pax_global_header00006660000000000000000000000064152023231310014502gustar00rootroot0000000000000052 comment=b9df04cc518b9cca5f1b0d007d4359b1c93e2118 chawan-v0.4.0/000077500000000000000000000000001520232313100131325ustar00rootroot00000000000000chawan-v0.4.0/.build.yml000066400000000000000000000012471520232313100150360ustar00rootroot00000000000000image: alpine/edge packages: - nim - brotli-dev - brotli-static - libssh2-dev - libssh2-static - openssl-dev - openssl-libs-static - zlib-dev - zlib-static - build-base - xz sources: - "https://git.sr.ht/~bptato/chawan" artifacts: - chawan/chawan-linux-amd64.tar.xz tasks: - linux-amd64: | cd chawan # Set flags sed -i '/^STATIC_LINK ?=/s/0/1/' Makefile export LDFLAGS="-lz" export CFLAGS="-ffile-prefix-map=$(pwd)/=" # Build make -j$(nproc) # Prepare archive dir=chawan-linux-amd64 mkdir "$dir" cp -rP target/ doc/ Makefile cha "$dir" # Create archive tar caf "$dir".tar "$dir" --owner=root --group=root xz "$dir".tar chawan-v0.4.0/.gitignore000066400000000000000000000000461520232313100151220ustar00rootroot00000000000000/a /cha /target/ /.obj/ /test/net/run chawan-v0.4.0/Makefile000066400000000000000000000303531520232313100145760ustar00rootroot00000000000000# Public variables. NIM ?= nim NIMC ?= $(NIM) c OBJDIR ?= .obj OUTDIR ?= target # These paths are quoted in recipes. PREFIX ?= /usr/local MANPREFIX ?= $(PREFIX)/share/man MANPREFIX1 ?= $(MANPREFIX)/man1 MANPREFIX5 ?= $(MANPREFIX)/man5 MANPREFIX7 ?= $(MANPREFIX)/man7 TARGET ?= release PANDOC ?= pandoc PKG_CONFIG ?= pkg-config # Note: this is not a real shell substitution. # The default setting is at {the binary's path}/../libexec/chawan. # You may override it with any path if your system does not have a libexec # directory. # (This way, `cha' can be directly executed without installation.) LIBEXECDIR ?= \$$CHA_BIN_DIR/../libexec/chawan # I won't take this from the environment for obvious reasons. Please override it # in the make command if you must, or (preferably) fix your environment so it's # not needed. DANGER_DISABLE_SANDBOX = 0 # Private variables. # If overridden, take libexecdir that was specified. # Otherwise, just install to libexec/chawan. ifeq ($(LIBEXECDIR),\$$CHA_BIN_DIR/../libexec/chawan) LIBEXECDIR_CHAWAN = "$(DESTDIR)$(PREFIX)/libexec/chawan" else LIBEXECDIR_CHAWAN = $(LIBEXECDIR) endif # Static linking. STATIC_LINK ?= 0 # These paths are quoted in recipes. OUTDIR_TARGET = $(OUTDIR)/$(TARGET) OUTDIR_BIN = $(OUTDIR_TARGET)/bin OUTDIR_LIBEXEC = $(OUTDIR_TARGET)/libexec/chawan OUTDIR_CGI_BIN = $(OUTDIR_LIBEXEC)/cgi-bin OUTDIR_MAN = $(OUTDIR_TARGET)/share/man # Force a poll implementation. 0 - do not force, 1 - poll, 2 - select. # This is an intentionally undocumented debugging flag; open a ticket if # you need it on a certain system, because it has subtle issues without # platform-specific adjustments. FORCE_POLL_MODE ?= 0 chac_flags = # Nim compiler flags ifeq ($(TARGET),debug) FLAGS += -d:debug --debugger:native CFLAGS += -DDUMP_LEAKS=1 else ifeq ($(TARGET),release) chac_flags = -s FLAGS += -d:release -d:strip -d:lto else ifeq ($(TARGET),release0) FLAGS += -d:release --stacktrace:on else ifeq ($(TARGET),release1) FLAGS += -d:release --debugger:native endif ssl_link = http gemini sftp tohtml_link = gopher2html md2html ansi2html gmi2html dirlist2html img2html protocols_bin = file ftp gopher finger man spartan chabookmark stbi jebp sixel \ canvas resize nanosvg ssl converters_bin = uri2html tohtml tools_bin = urlenc nc protocols = $(protocols_bin) $(ssl_link) converters = $(converters_bin) $(tohtml_link) tools = $(tools_bin) urldec scripts = init.jsb ifeq ($(STATIC_LINK),1) LDFLAGS += -static endif ifeq ($(FORCE_POLL_MODE),2) # for seccomp CFLAGS += -DCHA_FORCE_SELECT endif FLAGS += $(foreach flag,$(CFLAGS),-t:$(flag)) FLAGS += $(foreach flag,$(LDFLAGS),-l:$(flag)) FLAGS += -d:disableSandbox=$(DANGER_DISABLE_SANDBOX) FLAGS += -d:forcePollMode=$(FORCE_POLL_MODE) ssl_libs = libssl libcrypto libbrotlidec libbrotlicommon libssh2 ssl_flags = $(FLAGS) ssl_cflags := $(shell $(PKG_CONFIG) --cflags $(ssl_libs) || echo _cha_error) ifeq ($(ssl_cflags),_cha_error) $(error failed to find some dependencies) endif ssl_ldflags := $(shell $(PKG_CONFIG) --libs $(ssl_libs) || echo _cha_error) ifeq ($(ssl_ldflags),_cha_error) $(error failed to find some dependencies) endif ssl_flags += $(foreach flag,$(ssl_cflags),-t:$(flag)) ssl_flags += $(foreach flag,$(ssl_ldflags),-l:$(flag)) export CC CFLAGS LDFLAGS PANDOC binaries = $(OUTDIR_BIN)/cha $(OUTDIR_BIN)/mancha binaries += $(foreach bin,$(protocols),$(OUTDIR_CGI_BIN)/$(bin)) binaries += $(foreach bin,$(converters),$(OUTDIR_LIBEXEC)/$(bin)) binaries += $(foreach bin,$(tools),$(OUTDIR_LIBEXEC)/$(bin)) binaries += $(foreach bin,$(scripts),$(OUTDIR_LIBEXEC)/$(bin)) .PHONY: all all: $(binaries) ln -sf "$(OUTDIR)/$(TARGET)/bin/cha" cha ifeq ($(shell uname), Linux) chaseccomp = lib/chaseccomp/chaseccomp.o lib/chaseccomp/chaseccomp.o: .FORCE (cd lib/chaseccomp && $(MAKE)) .FORCE: endif twtstr = src/utils/twtstr.nim src/types/opt.nim dynstream = src/io/dynstream.nim chafile = src/io/chafile.nim $(dynstream) myposix = src/utils/myposix.nim connectionerror = src/server/connectionerror.nim lcgi = $(myposix) $(chafile) $(twtstr) $(sandbox) $(connectionerror) \ adapter/protocol/lcgi.nim lcgi_ssl = $(lcgi) adapter/protocol/lcgi_ssl.nim sandbox = src/utils/sandbox.nim $(chaseccomp) tinfl = adapter/protocol/tinfl.h # lib/*0 has a 0 so that it doesn't conflict with the old submodules. # git can't deal with this, it seems. $(OUTDIR_BIN)/cha: src/*.nim src/*/*.nim src/*/*.c res/* lib/chame0/chame/* \ lib/monoucha0/monoucha/* lib/monoucha0/monoucha/qjs/* $(chaseccomp) \ res/charwidth_gen.nim nim.cfg @mkdir -p "$(OUTDIR_BIN)" $(NIMC) --nimcache:"$(OBJDIR)/$(TARGET)/cha" -d:libexecPath=$(LIBEXECDIR) \ $(FLAGS) -o:"$(OUTDIR_BIN)/cha" src/main.nim $(OUTDIR_BIN)/mancha: adapter/tools/mancha @mkdir -p "$(OUTDIR_BIN)" install -m755 $< "$(OUTDIR_BIN)" unicode_version = 17.0.0 .PHONY: unicode_gen unicode_gen: @printf 'Download EastAsianWidth.txt from www.unicode.org? (y/n) ' @read res; if test "$$res" = "y"; then \ cha -d 'https://www.unicode.org/Public/$(unicode_version)/ucd/EastAsianWidth.txt' >res/EastAsianWidth.txt; \ fi $(NIMC) --nimcache:"$(OBJDIR)/charwidth_gen_cache" -d:danger -o:"$(OBJDIR)/gencharwidth" res/gencharwidth.nim $(OBJDIR)/gencharwidth > res/charwidth_gen.nim~ mv res/charwidth_gen.nim~ res/charwidth_gen.nim $(OUTDIR_CGI_BIN)/man: $(lcgi) src/utils/lrewrap.nim \ lib/monoucha0/monoucha/libregexp.nim \ lib/monoucha0/monoucha/qjs/libregexp.* \ lib/monoucha0/monoucha/qjs/libunicode.* \ lib/monoucha0/monoucha/qjs/cutils.* $(OUTDIR_CGI_BIN)/file: $(lcgi) $(OUTDIR_CGI_BIN)/ftp: $(lcgi) $(OUTDIR_CGI_BIN)/ssl: adapter/protocol/http.nim adapter/protocol/gemini.nim \ adapter/protocol/sftp.nim $(lcgi_ssl) $(sandbox) $(tinfl) $(OUTDIR_CGI_BIN)/stbi: adapter/img/stbi.nim adapter/img/stb_image.h \ adapter/img/stb_image_write.h $(lcgi) $(OUTDIR_CGI_BIN)/jebp: adapter/img/jebp.h $(lcgi) $(OUTDIR_CGI_BIN)/sixel: src/types/color.nim $(lcgi) $(OUTDIR_CGI_BIN)/canvas: src/types/canvastypes.nim src/types/path.nim \ src/io/packetreader.nim src/types/color.nim adapter/img/stb_image.h \ $(lcgi) $(OUTDIR_CGI_BIN)/resize: adapter/img/stb_image_resize.h $(lcgi) $(OUTDIR_CGI_BIN)/nanosvg: adapter/img/nanosvg.nim adapter/img/nanosvg.h \ adapter/img/nanosvgrast.h $(lcgi) $(OUTDIR_LIBEXEC)/urlenc: $(twtstr) $(chafile) $(OUTDIR_LIBEXEC)/nc: $(lcgi) $(OUTDIR_LIBEXEC)/tohtml: adapter/format/ansi2html.nim adapter/format/dirlist2html.nim \ adapter/format/gmi2html.nim adapter/format/gopher2html.nim \ adapter/format/md2html.nim adapter/format/img2html.nim \ $(twtstr) $(chafile) $(dynstream) src/types/color.nim $(foreach it,$(ssl_link),$(OUTDIR_CGI_BIN)/$(it)): $(OUTDIR_CGI_BIN)/ssl (cd "$(OUTDIR_CGI_BIN)" && ln -sf ssl $(notdir $@)) $(foreach it,$(tohtml_link),$(OUTDIR_LIBEXEC)/$(it)): $(OUTDIR_LIBEXEC)/tohtml (cd "$(OUTDIR_LIBEXEC)" && ln -sf tohtml $(notdir $@)) $(OUTDIR_CGI_BIN)/%: adapter/protocol/%.nim adapter/nim.cfg @mkdir -p "$(OUTDIR_CGI_BIN)" $(NIMC) $(FLAGS) --nimcache:"$(OBJDIR)/$(TARGET)/$(notdir $@)" -o:"$@" $< $(OUTDIR_CGI_BIN)/ssl: adapter/protocol/ssl.nim adapter/nim.cfg @mkdir -p "$(OUTDIR_CGI_BIN)" $(NIMC) $(ssl_flags) --nimcache:"$(OBJDIR)/$(TARGET)/$(notdir $@)" -o:"$@" $< $(OUTDIR_CGI_BIN)/%: adapter/protocol/% @mkdir -p "$(OUTDIR_CGI_BIN)" install -m755 $< "$(OUTDIR_CGI_BIN)" $(OUTDIR_LIBEXEC)/%: adapter/format/% @mkdir -p "$(OUTDIR_LIBEXEC)" install -m755 $< "$(OUTDIR_LIBEXEC)" $(OUTDIR_CGI_BIN)/%: adapter/img/%.nim adapter/nim.cfg @mkdir -p "$(OUTDIR_CGI_BIN)" rm -rf "$(OBJDIR)/$(TARGET)/$(notdir $@)" $(NIMC) $(FLAGS) --nimcache:"$(OBJDIR)/$(TARGET)/$(notdir $@)" -o:"$@" $< $(OUTDIR_LIBEXEC)/%: adapter/format/%.nim adapter/nim.cfg @mkdir -p "$(OUTDIR_LIBEXEC)" $(NIMC) $(FLAGS) --nimcache:"$(OBJDIR)/$(TARGET)/$(notdir $@)" -o:"$@" $< $(OUTDIR_LIBEXEC)/%: adapter/tools/%.nim adapter/nim.cfg @mkdir -p "$(OUTDIR_LIBEXEC)" $(NIMC) $(FLAGS) --nimcache:"$(OBJDIR)/$(TARGET)/$(notdir $@)" -o:"$@" $< $(OUTDIR_LIBEXEC)/urldec: $(OUTDIR_LIBEXEC)/urlenc (cd "$(OUTDIR_LIBEXEC)" && ln -sf urlenc urldec) # Do not add FLAGS here, because that breaks cross-compilation. $(OBJDIR)/chac: src/chac.nim lib/monoucha0/monoucha/* lib/monoucha0/monoucha/qjs/* $(NIMC) -o:$@ $< $(OUTDIR_LIBEXEC)/%.jsb: src/%.js $(OBJDIR)/chac $(OBJDIR)/chac $(chac_flags) $< $@ doc/%.1: doc/%.md md2man ./md2man $< > $@~ mv $@~ $@ doc/cha-%.5: doc/%.md md2man ./md2man $< > $@~ mv $@~ $@ doc/cha-%.7: doc/%.md md2man ./md2man $< > $@~ mv $@~ $@ .PHONY: clean clean: rm -rf "$(OBJDIR)/$(TARGET)" (cd lib/chaseccomp && $(MAKE) clean) .PHONY: distclean distclean: clean rm -rf "$(OUTDIR)" manpages1 = cha.1 mancha.1 manpages5 = cha-config.5 cha-mailcap.5 cha-mime.types.5 cha-cgi.5 \ cha-urimethodmap.5 manpages7 = cha-protocols.7 cha-api.7 cha-troubleshooting.7 cha-image.7 cha-css.7 cha-terminal.7 manpages = $(manpages1) $(manpages5) $(manpages7) .PHONY: manpage manpage: $(manpages:%=doc/%) .PHONY: install install: mkdir -p "$(DESTDIR)$(PREFIX)/bin" install -m755 "$(OUTDIR_BIN)/cha" "$(DESTDIR)$(PREFIX)/bin" install -m755 "$(OUTDIR_BIN)/mancha" "$(DESTDIR)$(PREFIX)/bin" # intentionally not quoted mkdir -p $(LIBEXECDIR_CHAWAN)/cgi-bin for f in $(protocols_bin); do \ install -m755 "$(OUTDIR_CGI_BIN)/$$f" $(LIBEXECDIR_CHAWAN)/cgi-bin; \ done for f in $(converters_bin) $(tools_bin) $(scripts); \ do install -m755 "$(OUTDIR_LIBEXEC)/$$f" $(LIBEXECDIR_CHAWAN); \ done (cd $(LIBEXECDIR_CHAWAN) && ln -sf urlenc urldec) for f in $(ssl_link); do (cd $(LIBEXECDIR_CHAWAN)/cgi-bin && ln -sf ssl "$$f"); done for f in $(tohtml_link); do (cd $(LIBEXECDIR_CHAWAN) && ln -sf tohtml "$$f"); done mkdir -p "$(DESTDIR)$(MANPREFIX1)" for f in $(manpages1); do install -m644 "doc/$$f" "$(DESTDIR)$(MANPREFIX1)"; done mkdir -p "$(DESTDIR)$(MANPREFIX5)" for f in $(manpages5); do install -m644 "doc/$$f" "$(DESTDIR)$(MANPREFIX5)"; done mkdir -p "$(DESTDIR)$(MANPREFIX7)" for f in $(manpages7); do install -m644 "doc/$$f" "$(DESTDIR)$(MANPREFIX7)"; done .PHONY: uninstall uninstall: rm -f "$(DESTDIR)$(PREFIX)/bin/cha" rm -f "$(DESTDIR)$(PREFIX)/bin/mancha" # intentionally not quoted for f in $(protocols); do rm -f $(LIBEXECDIR_CHAWAN)/cgi-bin/$$f; done for f in $(converters) $(tools) $(scripts); do rm -f $(LIBEXECDIR_CHAWAN)/$$f; done # We only want to uninstall binaries that the main distribution # includes or has ever included, but not those that the user might have # added. Some of these cannot be directly derived from our variables: # * png has been removed in favor of stbi # * data, about have been moved back into the main binary # * gmifetch has been replaced by gemini # * cha-finger has been renamed to finger rm -f $(LIBEXECDIR_CHAWAN)/cgi-bin/about rm -f $(LIBEXECDIR_CHAWAN)/cgi-bin/cha-finger rm -f $(LIBEXECDIR_CHAWAN)/cgi-bin/data rm -f $(LIBEXECDIR_CHAWAN)/cgi-bin/gmifetch rm -f $(LIBEXECDIR_CHAWAN)/cgi-bin/png rmdir $(LIBEXECDIR_CHAWAN)/cgi-bin || true rmdir $(LIBEXECDIR_CHAWAN) || true for f in $(manpages7); do rm -f "$(DESTDIR)$(MANPREFIX7)/$$f"; done for f in $(manpages5); do rm -f "$(DESTDIR)$(MANPREFIX5)/$$f"; done # moved to section 7 (and localcgi renamed to just cgi) for f in cha-protocols.5 cha-api.5 cha-troubleshooting.5 cha-image.5 cha-localcgi.5; do rm -f "$(DESTDIR)$(MANPREFIX5)/$$f"; done for f in $(manpages1); do rm -f "$(DESTDIR)$(MANPREFIX1)/$$f"; done test/net/run: test/net/run.nim $(NIMC) test/net/run.nim .PHONY: map map: $(NIM) $(FLAGS) r res/createmap.nim > src/encoding/charset_map.nim .PHONY: test_js test_js: (cd test/js && ./run.sh) .PHONY: test_layout test_layout: (cd test/layout && ./run.sh) .PHONY: test_md test_md: (cd test/md && ./run.sh) .PHONY: test_net test_net: test/net/run (cd test/net && ./run.sh) .PHONY: test_pager test_pager: test/pager/run.sh (cd test/pager && ./run.sh) $(OBJDIR)/chagashi_test: mkdir -p $(OBJDIR)/chagashi_test cp test/charset/data.tar.xz $(OBJDIR)/chagashi_test unxz $(OBJDIR)/chagashi_test/data.tar.xz tar xf $(OBJDIR)/chagashi_test/data.tar -C $(OBJDIR)/chagashi_test test_flags = --verbosity:0 .PHONY: test_charset test_charset: test/charset/run.sh $(OBJDIR)/chagashi_test (cd test/charset && ./run.sh) $(NIM) r $(test_flags) test/charset/basic.nim CGS_TESTDIR=$(OBJDIR)/chagashi_test $(NIM) r $(test_flags) test/charset/data.nim .PHONY: test_nim test_nim: test/nim/ttwtstr.nim (cd test/nim && $(NIM) r $(test_flags) ttwtstr.nim) .PHONY: test test: test_js test_layout test_net test_md test_pager test_charset test_nim chawan-v0.4.0/NEWS000066400000000000000000000155631520232313100136430ustar00rootroot000000000000000.4.0 (2026.05.17) * dupeBuffer/anchor navigation no longer forks buffer process * support VT420 * support DEC special graphics in ASCII mode * support all VP8L indexed color transforms * support pandoc-style definition list in markdown * support color, width, align, noshade properties on HR element * support Element#getAttributeNames * add status.format-mode (sets formatting of status bar) * add toggleLinkHintsAutoClick command (by Arthur Jacquin) * add saveScreen, editScreen commands; rename sourceEdit to editSource * add x-type, x-match, x-nc-match mailcap extensions (from w3mmee) * add mouse support to the line editor * improve keybinding format (mostly backwards-compatible; see cha-config(5)) * remove display.force-clear (shouldn't have ever been needed) * remove display.query-da1 (no longer needed) * remove deprecated special case in pager.load() with trailing newline * remove deprecated parentBuffer, prevSiblingBuffer, nextSiblingBuffer actions * remove MAILCAP_URL env var when executing mailcap entries (use %u instead) * make terminal querying asynchronous * work around FreeBSD vt(4) freezing on startup * work around a bug in URL standard that made us reject ed2k URLs * optimize out Sixel repaints when scrolling * drop excessive frames when the terminal/link cannot keep up * rework seccomp handling to support cross-compilation to incompatible archs * fix cached images not being cleared when a buffer is deleted * fix a NULL deref in jebp * fix y/n being truncated out of long ask() prompts * fix media queries not being re-evaluated on windowChange * fix load info not being set on cycling between buffers * fix color blending over body bgcolor * fix matching of nested subsequent sibling combinator * fix various CSS image sizing bugs * fix table row rendering order with multiple thead/tfoot children * fix absolutely positioned boxes not respecting min/max size constraints * fix percentage calc() output in color values * fix inline pre/nowrap not being flushed to the next line on overflow * fix bugs in our libregexp UTF-8 patch * fix various proxy authentication bugs * fix [attr|=value] and :lang() pseudo-class bugs * fix localStorage.key function * fix gotoLine malfunctioning in select menu * fix bug in negation of the minimum layout unit value * fix crash on Storage#key overflow on 32-bit targets * fix crash on calling status getter for unsent XHR * fix various charset decoder bugs * fix TypedArray handling * fix suspend() not suspending all processes * fix JS bindings having incorrect property descriptions * fix user/pass in Basic auth not being percent-decoded * fix decoding of data URLs that include a question mark 0.3.0 (2025.11.21) UI additions * wheel-scroll, side-wheel-scroll config options (by Tim Culverhouse) * new API functions Pager#traverse, Pager#navDirection, Pager#revDirection, Buffer#find * bracketed paste - pasting a URL now opens the URL bar automatically * "copy URL", "copy selection" now works over SSH when OSC 52 is supported * "hints mode" for jumping to specific links on the page (default keybinding is `f`, configurable using `input.link-hint-chars`) * added loaded stylesheet/image counters --- CSS additions * monochrome, color, color-index media queries * implement
    current URL, right click -> URL under cursor, middle click -> empty URL bar - double click + drag selects text * fixed flash of unstyled content and removed blank screen on page load * moved all commands in `cmd.pager` and `cmd.buffer` into `cmd` * binding keys no longer requires `cmd.` prefix for built-in commands * color contrast correction is no longer invoked on cells that do not use the terminal theme for foreground or background --- Misc changes * history, cookies, etc. are now saved in XDG_DATA_HOME for XDG basedir users (instead of XDG_CONFIG_HOME) - users that store their config in ~/.chawan are not affected * unify binaries that link to OpenSSL in dynamically linked builds, and unify markdown, gemini, etc. -> HTML converters * allow overriding pkg-config path in Makefile (using PKG_CONFIG) * better color approximation in "eight-bit" color mode (256 colors) * #L{n} (e.g. #L1) jumps to nth line in plain text files (idea from Dillo) * console buffer is now spawned on demand * switched from QJS-NG to QJS (with patches from NG) --- Removals * remove deprecated prepend-https, css and stylesheet config options (use prepend-scheme, user-style instead) * remove protocol.form-request config option (read the body in CGI instead) * remove buffer tree; buffers are now organized in lists, and buffer lists belong in tabs (note: the latter does not have a real UI yet) --- Optimizations * layout caching (makes a huge difference in memory usage and performance) * CSS parser is now single-pass (kind of) * cascade: eliminate several allocations, merge hash maps for separate origins * more compact DOM representation (uses doubly linked list instead of a vector) * insert style sheets incrementally instead of traversing DOM several times * async terminal handling (printing large Sixels no longer blocks the rest of the pager) --- Fixes * fix buffer cloning on musl * fix crash when saving cookies * fix possible crash in CanvasRenderingContext2D#closePath * fix mystery miscompilation bug on macOS * fix interactive mode when reading from stdin on macOS * fix referrer policy handling with referer-from=true * fix compilation on OpenBSD + ancient Nim * fix crash on hitting C-c on buffers waiting for connection * fix chaseccomp compilation with some ancient shells * fix lang() CSS selector * fix setTimeout needlessly spinning the CPU on macOS * fix selector dependency tracking for :not * fix double width char measurement in passwords * fix Content-Type header in multipart forms * fix crash on file upload * fix DOMParser#parseFromString replacing the entire document * fix specificity being applied incorrectly with multiple author sheets 0.2.0 (2025.06.15) Initial release. Thanks for patches applied prior to this release to: commodorian Alex hrdl chawan-v0.4.0/README.md000066400000000000000000000135361520232313100144210ustar00rootroot00000000000000[Chawan](https://chawan.net) is a TUI web (and (S)FTP, Gopher, Gemini, ...) browser with CSS, inline image and JavaScript support. It uses its own small browser engine developed from scratch, which can nevertheless display many websites in a manner similar to major graphical browsers. It can also be used as a terminal pager. ![Screenshot of Chawan displaying its SourceHut page](doc/showcase.png) ## Compiling A Unix-like operating system (Linux, \*BSD, Haiku, macOS, ...) is assumed. On Windows you have to use WSL. 1. Clone the Chawan repository: `git clone https://git.sr.ht/~bptato/chawan && cd chawan` 2. Install the Nim compiler: * Please use 2.0.0 or newer, ideally 2.2.10. (`nim -v` displays your Nim compiler's version.) The 1.6 branch from 1.6.14 upwards may still work, but it isn't recommended unless you have no other choice. * If you are using a 32-bit system, you probably need 2.2 or newer. 2.0 may still work if you `export CFLAGS=-fpermissive`. 3. Install the following dependencies: * [OpenSSL](https://www.openssl.org/) (or [LibreSSL](https://www.libressl.org/)) * [libssh2](https://libssh2.org/) * [brotli](https://github.com/google/brotli) * pkg-config * GNU make (gmake on non-GNU systems) * Quick copy-paste for Debian: `apt install libssh2-1-dev libssl-dev libbrotli-dev pkg-config make` 4. Run `make` (without arguments). 5. Install using `make install` (e.g. `sudo make install`). Then, try: ```bash $ cha -V # open in visual mode for a list of default keybindings $ cha example.org # open your favorite website directly from the shell $ mancha cha # read the cha(1) man page using `mancha' ``` ## Packages You can also install Chawan from packages maintained by volunteers. Known stable packages are: * Alpine Linux: * Arch Linux: * FreeBSD: * Homebrew: * NixOS: * Slackware (SBo): * Void Linux: Unstable packages (tip of the `master` branch): * AUR: * AppImage: * Homebrew (using `--HEAD`): Each [release](https://chawan.net/news/index.html) also comes with static binaries. However, their dependencies can quickly get out of date, so installing a package or compiling Chawan yourself is preferable. ## Features Currently implemented features are: * multi-processing, incremental loading of documents * HTML5 support with various encodings (UTF-8, Shift_JIS, GBK, ...), forms, cookies * [CSS](doc/css.md)-based layout engine: supports flow layout, table layout, flexbox layout, double-width characters (CJK) * user-programmable keybindings (defaults are vi(m)-like), mouse support * JavaScript support in documents (disabled by default) * inline image support with [Sixel](https://en.wikipedia.org/wiki/Sixel) or [Kitty protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/) (disabled by default; see [doc/image.md](doc/image.md) on how to enable) * supports several network [protocols](doc/protocols.md): HTTP(S), (S)FTP, Gopher, Gemini, Finger, Spartan * markdown viewer (`cha README.md`), man page viewer (`mancha`) * [user-defined protocols](doc/urimethodmap.md) and [file formats](doc/mailcap.md) * syscall filter based sandboxing on FreeBSD, OpenBSD and Linux (through capsicum, pledge and seccomp-bpf) * bookmarks, history ...with a lot more [planned](todo). ## Bugs, technical issues, etc. First, read the [troubleshooting](doc/troubleshooting.md) document. If it doesn't help, [open a ticket](https://todo.sr.ht/~bptato/chawan). When using the ticket tracker, please make sure your tickets are valid markdown, or they become unreadable on the web interface. If you want to send plain text e-mails not formatted as markdown, use the [mailing list](mailto:~bptato/chawan-devel@lists.sr.ht) instead. This is also where you can send patches. If you're having troubles accessing SourceHut, you can also use the [Codeberg mirror](https://codeberg.org/bptato/chawan). ## Documentation index Chawan's documentation is available as man pages (`man cha`) and as Markdown files. * build/compilation options: [doc/build.md](doc/build.md) * `cha` man page: [doc/cha.md](doc/cha.md) * `mancha` man page: [doc/mancha.md](doc/mancha.md) * configuration options: [doc/config.md](doc/config.md) * API description (for keybindings): [doc/api.md](doc/api.md) * mailcap: [doc/mailcap.md](doc/mailcap.md) * mime.types: [doc/mime.types.md](doc/mime.types.md) * urimethodmap: [doc/urimethodmap.md](doc/urimethodmap.md) * local CGI: [doc/cgi.md](doc/cgi.md) * protocols: [doc/protocols.md](doc/protocols.md) * inline images: [doc/image.md](doc/image.md) * CSS: [doc/css.md](doc/css.md) * terminal compatibility: [doc/terminal.md](doc/terminal.md) * troubleshooting: [doc/troubleshooting.md](doc/troubleshooting.md) If you're interested in modifying the code: * architecture: [doc/architecture.md](doc/architecture.md) * style guide, debugging tips, etc.: [doc/hacking.md](doc/hacking.md) ## Relatives [w3m](https://sr.ht/~rkta/w3m) has been the main inspiration for Chawan; although the two do not share code, the UI and feature set is similar. [Ferus](https://github.com/ferus-web/ferus) is a separate graphical browser engine written in Nim, which uses Chawan's HTML parser. ## License Chawan is dedicated to the public domain. See the UNLICENSE file for details. Chawan also includes and depends on several permissively licensed libraries. For further details, check the page in Chawan, or read the same document [here](res/license.md). chawan-v0.4.0/UNLICENSE000066400000000000000000000022731520232313100144060ustar00rootroot00000000000000This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to chawan-v0.4.0/adapter/000077500000000000000000000000001520232313100145525ustar00rootroot00000000000000chawan-v0.4.0/adapter/format/000077500000000000000000000000001520232313100160425ustar00rootroot00000000000000chawan-v0.4.0/adapter/format/ansi2html.nim000066400000000000000000000275601520232313100204620ustar00rootroot00000000000000{.push raises: [].} import std/os import std/posix import io/chafile import io/dynstream import types/color import types/opt import utils/twtstr type FormatFlag = enum ffBold = "bold" ffItalic = "italic" ffUnderline = "underline" ffReverse = "-cha-reverse" ffStrike = "line-through" ffOverline = "overline" ffBlink = "blink" Format = object fgcolor: CellColor bgcolor: CellColor flags: set[FormatFlag] AnsiCodeParseState = enum acpsDone, acpsStart, acpsParams, acpsInterm, acpsFinal, acpsBackspace, acpsInBackspaceTransition, acpsInBackspace, acpsOSC, acpsOSCEsc State = object os: PosixStream outbufIdx: int outbuf: array[4096, char] currentFmt: Format pendingFmt: Format ansiParams: string ansiState: AnsiCodeParseState backspaceDecay: int tmpFlags: set[FormatFlag] af: bool spanOpen: bool aOpen: bool hasPrintingBuf: bool proc getParam(state: State; i: var int; colon = false): string = result = "" while i < state.ansiParams.len: let c = state.ansiParams[i] if c == ';' or colon and c == ':': break result &= c inc i if i < state.ansiParams.len: inc i proc getParamU8(state: State; i: var int; colon = false): Opt[uint8] = if i >= state.ansiParams.len: return err() parseUInt8(state.getParam(i), allowSign = false) proc setColor(format: var Format; c: CellColor; isfg: bool) = if isfg: format.fgcolor = c else: format.bgcolor = c proc parseSGRDefColor(state: State; format: var Format; i: var int; isfg: bool): Opt[void] = let u = ?state.getParamU8(i, colon = true) if u == 2: let param0 = ?state.getParamU8(i, colon = true) if i < state.ansiParams.len: let r = param0 let g = ?state.getParamU8(i, colon = true) let b = ?state.getParamU8(i, colon = true) format.setColor(cellColor(rgb(r, g, b)), isfg) else: format.setColor(cellColor(gray(param0)), isfg) elif u == 5: let param0 = ?state.getParamU8(i, colon = true) format.setColor(ANSIColor(param0).cellColor(), isfg) else: return err() ok() proc parseSGRColor(state: State; format: var Format; i: var int; u: uint8): Opt[void] = if u in 30u8..37u8: format.fgcolor = cellColor(ANSIColor(u - 30)) elif u == 38: return state.parseSGRDefColor(format, i, isfg = true) elif u == 39: format.fgcolor = defaultColor elif u in 40u8..47u8: format.bgcolor = cellColor(ANSIColor(u - 40)) elif u == 48: return state.parseSGRDefColor(format, i, isfg = false) elif u == 49: format.bgcolor = defaultColor elif u in 90u8..97u8: format.fgcolor = cellColor(ANSIColor(u - 82)) elif u in 100u8..107u8: format.bgcolor = cellColor(ANSIColor(u - 92)) else: return err() ok() const FormatCodes: array[FormatFlag, tuple[s, e: uint8]] = [ ffBold: (1u8, 22u8), ffItalic: (3u8, 23u8), ffUnderline: (4u8, 24u8), ffReverse: (7u8, 27u8), ffStrike: (9u8, 29u8), ffOverline: (53u8, 55u8), ffBlink: (5u8, 25u8), ] proc parseSGRAspect(state: State; format: var Format; i: var int): Opt[void] = let u = ?state.getParamU8(i) for flag, (s, e) in FormatCodes: if u == s: format.flags.incl(flag) return ok() if u == e: format.flags.excl(flag) return ok() if u == 0: format = Format() return ok() else: return state.parseSGRColor(format, i, u) proc parseSGR(state: State; format: var Format) = if state.ansiParams.len == 0: format = Format() else: var i = 0 while i < state.ansiParams.len: if state.parseSGRAspect(format, i).isErr: break proc parseControlFunction(state: var State; format: var Format; f: char) = if f == 'm': state.parseSGR(format) else: discard # unknown proc flushOutbuf(state: var State) = if state.outbufIdx > 0: if state.os.writeLoop(state.outbuf.toOpenArray(0, state.outbufIdx - 1)).isErr: quit(1) state.outbufIdx = 0 proc putc(state: var State; c: char) {.inline.} = if state.outbufIdx + 4 >= state.outbuf.len: # max utf-8 char length state.flushOutbuf() state.outbuf[state.outbufIdx] = c inc state.outbufIdx proc puts(state: var State; s: openArray[char]) {.inline.} = #TODO this is slower than it should be for c in s: state.putc(c) proc flushFmt(state: var State) = if state.pendingFmt != state.currentFmt: if state.spanOpen: state.puts("") if state.pendingFmt == Format(): state.currentFmt = state.pendingFmt state.spanOpen = false return state.spanOpen = true state.puts(" 0 and buf[^1] == ';': buf.setLen(buf.high) buf &= "'>" state.puts(buf) state.currentFmt = fmt state.hasPrintingBuf = false proc parseOSC(state: var State) = let p1 = state.ansiParams.until(';') let n = parseIntP(p1).get(-1) if n == 8: # hyperlink let p2start = p1.len + 1 let p1 = state.ansiParams.until(';', p2start) let url = state.ansiParams.until(';', p2start + p1.len + 1) if state.aOpen: state.puts("") state.aOpen = false if url != "": state.puts("") state.aOpen = true type ParseAnsiCodeResult = enum pacrProcess, pacrSkip proc parseAnsiCode(state: var State; format: var Format; c: char): ParseAnsiCodeResult = case state.ansiState of acpsStart: if c in '@'..'_': case c of '[': state.ansiState = acpsParams of ']': state.ansiState = acpsOSC else: state.ansiState = acpsDone else: state.ansiState = acpsDone return pacrProcess of acpsParams: if c in '0'..'?': state.ansiParams &= c else: state.ansiState = acpsInterm return state.parseAnsiCode(format, c) of acpsInterm: if c in ' '..'/': discard else: state.ansiState = acpsFinal return state.parseAnsiCode(format, c) of acpsFinal: state.ansiState = acpsDone if c in '@'..'~': state.parseControlFunction(format, c) else: return pacrProcess of acpsDone: discard of acpsBackspace: # We used to emulate less here, but it seems to yield dubious benefits # considering that # a) the only place backspace-based formatting is used in is manpages # b) we have w3mman now, which is superior in all respects, so this is # pretty much never used # c) if we drop generality, the output can be parsed much more efficiently # (without having to buffer the entire line first) # # So we buffer only the last non-formatted UTF-8 char, and override it when # necessary. if not state.hasPrintingBuf: state.ansiState = acpsDone return pacrProcess var i = state.outbufIdx - 1 while true: if i < 0: state.ansiState = acpsDone return pacrProcess if (int(state.outbuf[i]) and 0xC0) != 0x80: break dec i if state.outbuf[i] == '_' or c == '_': # underline for underscore overstrike if ffUnderline notin state.pendingFmt.flags: state.tmpFlags.incl(ffUnderline) state.pendingFmt.flags.incl(ffUnderline) elif c == '_' and ffBold notin state.pendingFmt.flags: state.tmpFlags.incl(ffBold) state.pendingFmt.flags.incl(ffBold) else: # represent *any* non-underline overstrike with bold. # it is sloppy, but enough for our purposes. if ffBold notin state.pendingFmt.flags: state.tmpFlags.incl(ffBold) state.pendingFmt.flags.incl(ffBold) state.outbufIdx = i # move back output pointer state.ansiState = acpsInBackspaceTransition state.flushFmt() return pacrProcess of acpsInBackspaceTransition: if (int(c) and 0xC0) != 0x80: # backspace char end, next char begin state.ansiState = acpsInBackspace return pacrProcess of acpsInBackspace: if (int(c) and 0xC0) != 0x80: # second char after backspaced char begin if c == '\b': # got backspace again, overstriking previous char. here we don't have to # override anything state.ansiState = acpsBackspace return pacrProcess # welp. we have to fixup the previous char's formatting var i = state.outbufIdx - 1 while true: assert i >= 0 if (int(state.outbuf[i]) and 0xC0) != 0x80: break dec i let s = state.outbuf[i..': state.puts(">") of '\'': state.puts("'") of '"': state.puts(""") of '&': state.puts("&") of '\t': let obgcolor = state.currentFmt.bgcolor state.pendingFmt = state.currentFmt state.pendingFmt.bgcolor = defaultColor state.flushFmt() state.putc('\t') state.pendingFmt.bgcolor = obgcolor state.flushFmt() of '\e': state.ansiState = acpsStart state.ansiParams = "" of '\b': state.ansiState = acpsBackspace of '\0': state.puts("\uFFFD") # HTML eats NUL, so replace it here else: state.putc(c) proc usage() = let stderr = cast[ChaFile](stderr) discard stderr.writeLine("Usage: ansi2html [-s] [-t title]") quit(1) proc main*() = var state = State(os: newPosixStream(STDOUT_FILENO)) # parse args let H = paramCount() var i = 1 var standalone = false var title = "" while i <= H: let s = paramStr(i) if s == "": inc i if s[0] != '-': usage() for j in 1 ..< s.len: case s[j] of 's': standalone = true of 't': inc i if i > H: usage() title = paramStr(i).percentDecode() else: usage() inc i if standalone: state.puts("\n") if title != "": state.puts("" & title.htmlEscape() & "\n") if standalone: state.puts("\n") state.puts("
    \n")
      let ps = newPosixStream(STDIN_FILENO)
      var buffer {.noinit.}: array[4096, char]
      while true:
        state.flushOutbuf()
        let n = ps.read(buffer)
        if n <= 0:
          break
        state.processData(buffer.toOpenArray(0, n - 1))
      if standalone:
        state.puts("")
      state.flushOutbuf()
    
    {.pop.} # raises: []
    chawan-v0.4.0/adapter/format/dirlist2html.nim000066400000000000000000000104641520232313100211750ustar00rootroot00000000000000{.push raises: [].}
    
    import std/algorithm
    import std/os
    
    import io/chafile
    import types/opt
    import utils/twtstr
    
    type DirlistItemType = enum
      ditFile, ditLink, ditDir
    
    type DirlistItem = ref object
      name: string # real name
      dname: string # display name
      modified: string # date last modified
      case t: DirlistItemType
      of ditLink:
        linkto: string
      of ditFile:
        nsize: int64
      of ditDir:
        discard
    
    proc printDirlist(f: ChaFile; items: openArray[DirlistItem]): Opt[void] =
      ?f.writeLine("[Upper Directory]")
      for item in items:
        var path = percentEncode(item.name, PathPercentEncodeSet)
        if item.t == ditLink and item.linkto.len > 0 and item.linkto[^1] == '/':
          # If the target is a directory, treat it as a directory. (For FTP.)
          path &= '/'
        # this depends on a CSS hack in ua.css where for dirlist, hr gets a
        # proprietary border style and anchors are moved upwards by -1em.
        var line = ""
        line &= ""
        ?f.write(line)
      ok()
    
    proc usage() =
      let stderr = cast[ChaFile](stderr)
      discard stderr.writeLine("Usage: dirlist2html [-t title]")
      quit(1)
    
    proc addItem(items: var seq[DirlistItem]; item: DirlistItem) =
      if item.t == ditDir:
        item.name &= '/'
      item.dname = item.name
      if item.t == ditLink:
        item.dname &= '@'
      items.add(item)
    
    proc skipTillSpace(line: openArray[char]; i: int): int =
      var i = i
      while i < line.len and line[i] != ' ':
        inc i
      return i
    
    proc parseInput(f: ChaFile; items: var seq[DirlistItem]): Opt[void] =
      var line: string
      while ?f.readLine(line):
        if line.len == 0: continue
        var i = 10 # permission
        # link count
        i = line.skipBlanks(i)
        i = line.skipTillSpace(i)
        # owner
        i = line.skipBlanks(i)
        i = line.skipTillSpace(i)
        # group
        i = line.skipBlanks(i)
        i = line.skipTillSpace(i)
        # size
        i = line.skipBlanks(i)
        var sizes = ""
        while i < line.len and line[i] in AsciiDigit:
          sizes &= line[i]
          inc i
        let nsize = parseInt64(sizes).get(-1)
        # date
        i = line.skipBlanks(i)
        let datestarti = i
        i = line.skipTillSpace(i) # m
        i = line.skipBlanks(i)
        i = line.skipTillSpace(i) # d
        i = line.skipBlanks(i)
        i = line.skipTillSpace(i) # y
        let dates = line.substr(datestarti, i)
        inc i
        var j = line.len
        if line[^1] == '\r':
          dec j
        let name = line.substr(i, j - 1)
        if name == "." or name == "..":
          continue
        case line[0]
        of 'l': # link
          var linki = name.find(" -> ")
          if linki == -1:
            linki = name.len
          let linkfrom = name.substr(0, linki - 1)
          let linkto = name.substr(linki + 4) # you?
          items.addItem(DirlistItem(
            t: ditLink,
            name: linkfrom,
            modified: dates,
            linkto: linkto
          ))
        of 'd': # directory
          items.addItem(DirlistItem(
            t: ditDir,
            name: name,
            modified: dates
          ))
        else: # file
          items.addItem(DirlistItem(
            t: ditFile,
            name: name,
            modified: dates,
            nsize: nsize
          ))
      ok()
    
    proc parseArgs(title: var string) =
      let H = paramCount()
      var i = 1
      while i <= H:
        let s = paramStr(i)
        if s == "":
          inc i
        if s[0] != '-':
          usage()
        for j in 1 ..< s.len:
          case s[j]
          of 't':
            inc i
            if i > H: usage()
            title = paramStr(i)
          else:
            usage()
        inc i
    
    proc parse(): Opt[void] =
      var title = ""
      parseArgs(title)
      let stdout = cast[ChaFile](stdout)
      ?stdout.write("""
    """ & title.htmlEscape() & """

    """ & title.htmlEscape() & """

    """) var items: seq[DirlistItem] = @[] let stdin = cast[ChaFile](stdin) ?stdin.parseInput(items) items.sort(proc(a, b: DirlistItem): int = if a.t == ditDir and b.t != ditDir: return -1 if a.t != ditDir and b.t == ditDir: return 1 return cmp(a.dname, b.dname) ) ?stdout.printDirlist(items) ?stdout.write("
    ") ok() proc main*() = discard parse() {.pop.} # raises: [] chawan-v0.4.0/adapter/format/gmi2html.nim000066400000000000000000000047141520232313100203000ustar00rootroot00000000000000{.push raises: [].} import io/chafile import types/opt import utils/twtstr proc parse(): Opt[void] = # We use `display: block' for anchors because they are supposed to be # presented on separate lines per standard. # We use `white-space: pre-line' on the entire body so that we do not have # to emit a
    character for each paragraph. ("Why not p?" Because gemini # does not allow collapsing newlines, so we would have to use
    or empty #

    tags for them. Neither make a lot more sense semantically than the # simplest and most efficient solution, which is just using newlines.) let stdout = cast[ChaFile](stdout) let stdin = cast[ChaFile](stdin) ?stdout.write("") var inpre = false var inul = false var line = "" while ?stdin.readLine(line): if inpre and not line.startsWith("```"): ?stdout.write(line.htmlEscape() & '\n') continue if inul and not line.startsWith("* "): ?stdout.write("") inul = false if line.len == 0: ?stdout.write("\n") continue if line.startsWith("=>"): # link let i = line.skipBlanks(2) let url = line.until(AsciiWhitespace, i) let text = if i + url.len < line.len: let j = line.skipBlanks(i + url.len) line.toOpenArray(j, line.high).htmlEscape() else: url.htmlEscape() ?stdout.write("" & text & "") elif line.startsWith("```"): # preformatting toggle inpre = not inpre let title = line.toOpenArray(3, line.high).htmlEscape() if inpre: ?stdout.write("

    ")
          else:
            ?stdout.write("
    ") elif line.startsWith("#"): # heading line var i = 1 while i < line.len and i < 3 and line[i] == '#': inc i let h = "h" & $i i = line.skipBlanks(i) # ignore whitespace after # ?stdout.write("<" & h & ">" & line.toOpenArray(i, line.high).htmlEscape() & "") elif line.startsWith("* "): # unordered list item if not inul: inul = true ?stdout.write("
      ") ?stdout.write("
    • " & line.toOpenArray(2, line.high).htmlEscape() & "
    • ") elif line.startsWith(">"): # quote ?stdout.write("
      ") ?stdout.write(line.toOpenArray(1, line.high).htmlEscape()) ?stdout.write("
      ") else: ?stdout.write(line.htmlEscape() & '\n') ok() proc main*() = discard parse() {.pop.} # raises: [] chawan-v0.4.0/adapter/format/gopher2html.nim000066400000000000000000000032001520232313100207750ustar00rootroot00000000000000{.push raises: [].} import std/os import io/chafile import types/opt import utils/twtstr proc getField(line: string; i: var int): string = var s = line.until('\t', i) i += s.len if i < line.len and line[i] == '\t': inc i move(s) proc parse(): Opt[void] = let stdout = cast[ChaFile](stdout) let stdin = cast[ChaFile](stdin) if paramCount() != 2 or paramStr(1) != "-u": discard stdout.writeLine("Usage: gopher2html [-u URL]") quit(1) let url = htmlEscape(paramStr(2)) ?stdout.write(""" Index of """ & url & """

      Index of """ & url & """

      """) var ispre = false var line = "" while ?stdin.readLine(line): if line.len == 0: continue let t = line[0] if t == '.': break # end var i = 1 let name = line.getField(i) var file = line.getField(i) let host = line.getField(i) let port = line.until('\t', i) # ignore anything after port var outs = "" if t == 'i': if not ispre: outs &= "
      "
              ispre = true
            outs &= htmlEscape(name) & '\n'
          else:
            if ispre:
              outs &= "
      " ispre = false let ourls = if not file.startsWith("URL:"): if file.len == 0 or file[0] != '/': file = '/' & file let pefile = file.percentEncode(PathPercentEncodeSet) "gopher://" & host & ":" & port & "/" & t & pefile else: file.substr("URL:".len) outs &= "" & htmlEscape(name) & "
      \n" ?stdout.write(outs) ok() proc main*() = discard parse() {.pop.} # raises: [] chawan-v0.4.0/adapter/format/img2html.nim000066400000000000000000000013621520232313100202740ustar00rootroot00000000000000{.push raises: [].} import std/os import io/chafile import types/opt import utils/twtstr proc parse(): Opt[void] = let stdout = cast[ChaFile](stdout) let stdin = cast[ChaFile](stdin) let stderr = cast[ChaFile](stderr) if paramCount() != 2: discard stderr.writeLine("Usage: img2html [content-type] [title]") quit(1) ?stdout.write("" & paramStr(2).htmlEscape() & "") ok() proc main*() = discard parse() {.pop.} # raises: [] chawan-v0.4.0/adapter/format/md2html.nim000066400000000000000000001007411520232313100201210ustar00rootroot00000000000000{.push raises: [].} import std/tables import io/chafile import types/opt import utils/twtstr type BracketState = enum bsNone, bsInBracket BlockType = enum btNone, btPar, btParBlank, btTableHeader, btTableBody, btList, btPre, btTabPre, btSpacePre, btBlockquote, btHTML, btHTMLPre, btComment, btLinkDef, btDefinition, btDefinitionPar, btDefinitionIndent, btDefinitionBlank ListState = enum lsNormal, lsAfterBlank, lsLastLine ListType = enum ltOl, ltUl, ltNoMark ListItemDesc = object t: ListType start: int32 depth: int len: int List = object depth: int t: ListType par: bool LinkDefState = enum ldsLink, ldsTitle ParseState = object ofile: ChaFile blockData: string line: string # current line to be processed lists: seq[List] numBlockLines: int numTableCells: int numDLSpaces: int linkDefIdx: int linkDefName: string linkDefLink: string refMap: TableRef[string, tuple[link, title: string]] slurpBuf: string slurpIdx: int reprocess: bool hasp: bool skipp: bool listState: ListState blockType: BlockType linkDefState: LinkDefState # Forward declarations proc parse(state: var ParseState): Opt[void] proc write(state: ParseState; c: char): Opt[void] = if state.ofile != nil: return state.ofile.write(c) ok() proc write(state: ParseState; s: openArray[char]): Opt[void] = if state.ofile != nil: return state.ofile.write(s) ok() proc writeLine(state: ParseState): Opt[void] = if state.ofile != nil: return state.ofile.writeLine() ok() proc writeLine(state: ParseState; s: openArray[char]): Opt[void] = if state.ofile != nil: return state.ofile.writeLine(s) ok() proc slurp(state: var ParseState): Opt[void] = if state.slurpIdx != -1: return ok() var state2 = ParseState(slurpIdx: -2, ofile: nil, refMap: state.refMap) if state.reprocess: state2.reprocess = true state2.line = state.line ?state2.parse() else: ?state2.parse() state.slurpBuf = move(state2.slurpBuf) state.slurpIdx = 0 return ok() proc getId(line: openArray[char]): string = result = "" var i = 0 var bs = bsNone while i < line.len: case (let c = line[i]; c) of AsciiAlphaNumeric, '-', '_', '.': result &= c.toLowerAscii() of ' ': result &= '-' of '[': bs = bsInBracket of ']': if bs == bsInBracket: if i + 1 < line.len and line[i + 1] == '(': inc i while i < line.len: let c = line[i] if c == '\\': inc i elif c == ')': break inc i bs = bsNone else: discard inc i type InlineFlag = enum ifItalic, ifBold, ifDel proc startsWithScheme(s: string): bool = for i, c in s: if i > 0 and c == ':': return true if c notin AsciiAlphaNumeric: break false type ParseInlineContext = object i: int bracketChars: string bs: BracketState flags: set[InlineFlag] const PreTags = ["pre", "script", "style", "textarea", "head"] proc parseInTag(ctx: var ParseInlineContext; line: string; state: ParseState): Opt[void] = var buf = "" var i = ctx.i + 1 while i < line.len: let c = line[i] if c == '>': # done if buf.startsWithScheme(): # link ?state.write("" & buf & "") else: # tag let s = '<' & buf & '>' ?state.write(s) if PreTags.containsIgnoreCase(buf): let pi = i + 1 i = line.find(s, i) if i == -1: i = line.high else: i += s.len if pi <= i: ?state.write(line.toOpenArray(pi, i)) ctx.i = i return ok() elif c == '<': dec i break else: buf &= c inc i ?state.write("<") ?state.write(buf) ctx.i = i ok() proc append(ctx: var ParseInlineContext; s: string; state: ParseState): Opt[void] = if ctx.bs == bsInBracket: ctx.bracketChars &= s else: ?state.write(s) ok() proc append(ctx: var ParseInlineContext; c: char; state: ParseState): Opt[void] = if ctx.bs == bsInBracket: ctx.bracketChars &= c else: ?state.write(c) ok() type CommentState = enum csNone, csDash, csDashDash proc parseComment(ctx: var ParseInlineContext; line: openArray[char]; state: ParseState): Opt[void] = var i = ctx.i var cs = csNone var buf = "" while i < line.len: let c = line[i] if cs in {csNone, csDash} and c == '-': inc cs elif cs == csDashDash and c == '>': buf &= '>' break else: cs = csNone buf &= c inc i ?ctx.append(buf, state) ctx.i = i ok() proc parseCode(ctx: var ParseInlineContext; line: openArray[char]; state: ParseState): Opt[void] = let i = ctx.i + 1 let j = line.find('`', i) if j != -1: ?ctx.append("", state) ?ctx.append(line.toOpenArray(i, j - 1).htmlEscape(), state) ?ctx.append("", state) ctx.i = j else: ?ctx.append('`', state) ok() proc parseLinkDestination(link: var string; line: openArray[char]; i: int): int = var i = i var quote = false var parens = 0 let sc = line[i] if sc == '<': inc i while i < line.len: let c = line[i] if quote: quote = false elif sc == '<' and c == '>': break elif sc == '<' and c in {'<', '\n'} or sc != '<' and c in Controls: return -1 elif sc != '<' and c in AsciiWhitespace: i = line.skipBlanks(i) break elif c == '\\': quote = true elif c == '(': inc parens link &= c elif c == ')' and sc != '>': if parens == 0: break dec parens link &= c else: link &= c inc i if sc != '<' and parens != 0 or quote: return -1 return line.skipBlanks(i + int(sc == '<')) proc parseTitle(title: var string; line: openArray[char]; i: int): int = let ec = line[i] var i = i + 1 var quote = false while i < line.len: let c = line[i] if quote: quote = false elif c == '\\': quote = true elif c == ec: inc i break else: title &= c inc i return line.skipBlanks(i) proc parseLinkBail(ctx: var ParseInlineContext; i: int; state: ParseState): Opt[void] = ctx.i = i return state.write('[' & ctx.bracketChars & ']') proc parseLinkWrite(ctx: ParseInlineContext; url, title: string; state: ParseState): Opt[void] = ?state.write("" & ctx.bracketChars & "") proc parseLink(ctx: var ParseInlineContext; line: string; state: var ParseState): Opt[void] = var i = ctx.i + 1 if i >= line.len: return ctx.parseLinkBail(i, state) if (let c = line[i]; c != '('): ?state.slurp() if c == '[': let j = line.find(']', i + 1) if j == -1: return ctx.parseLinkBail(i - 1, state) let s = line.substr(i + 1, j - 1).toLowerAscii() if s != "": let (link, title) = state.refMap.getOrDefault(s) if link == "": return ctx.parseLinkBail(i - 1, state) ctx.i = j return ctx.parseLinkWrite(link, title, state) else: # [link][] i += 2 let s = ctx.bracketChars.toLowerAscii() let (link, title) = state.refMap.getOrDefault(s) if link == "": if c == '[': i -= 2 return ctx.parseLinkBail(i - 1, state) ctx.i = i - 1 return ctx.parseLinkWrite(link, title, state) let bi = i - 1 i = line.skipBlanks(i + 1) if i >= line.len: return ctx.parseLinkBail(bi, state) var url = "" var j = url.parseLinkDestination(line, i) var title = "" if j != -1 and j < line.len and line[j] in {'(', '"', '\''}: j = title.parseTitle(line, j) if j == -1 or j >= line.len or line[j] != ')': return ctx.parseLinkBail(bi, state) ctx.i = j return ctx.parseLinkWrite(url, title, state) proc parseImageAlt(text: var string; line: openArray[char]; i: int): int = var i = i var brackets = 0 while i < line.len: let c = line[i] if c == '\\': inc i elif c == '<': while i < line.len and line[i] != '>': text &= c inc i elif c == '[': inc brackets text &= c elif line[i] == ']': if brackets == 0: break dec brackets text &= c else: text &= c inc i return i proc parseImageWrite(ctx: var ParseInlineContext; link, title, alt: string; state: ParseState): Opt[void] = ?ctx.append("" & alt.htmlEscape(), state)
  return ctx.append("", state) proc parseImage(ctx: var ParseInlineContext; line: string; state: var ParseState): Opt[void] = var alt = "" var i = alt.parseImageAlt(line, ctx.i + 2) if i == -1 or i + 1 >= line.len or line[i] != ']': return ctx.append("!", state) inc i let c = line[i] if c == '[': ?state.slurp() let j = line.find(']', i + 1) if j == -1: return ctx.append("!", state) let s = line.substr(i + 1, j - 1).toLowerAscii() let (link, title) = state.refMap.getOrDefault(s) if link == "": return ctx.append("!", state) ctx.i = j return ctx.parseImageWrite(link, title, alt, state) if c != '(': return ctx.append("!", state) var link = "" var j = link.parseLinkDestination(line, line.skipBlanks(i + 1)) var title = "" if j != -1 and j < line.len and line[j] in {'(', '"', '\''}: j = title.parseTitle(line, j) if j == -1 or j >= line.len or line[j] != ')': return ctx.append("!", state) ctx.i = j return ctx.parseImageWrite(link, title, alt, state) proc appendToggle(ctx: var ParseInlineContext; f: InlineFlag; s, e: string; state: ParseState): Opt[void] = if f notin ctx.flags: ctx.flags.incl(f) ?ctx.append(s, state) else: ctx.flags.excl(f) ?ctx.append(e, state) ok() proc parseInline(state: var ParseState; line: string): Opt[void] = var ctx = ParseInlineContext() while ctx.i < line.len: let c = line[ctx.i] if c == '\\': inc ctx.i if ctx.i < line.len: let c = line[ctx.i] if c == '\n': ?ctx.append("
      ", state) else: ?ctx.append(c, state) elif (ctx.i > 0 and line[ctx.i - 1] notin AsciiWhitespace or ctx.i + 1 < line.len and line[ctx.i + 1] notin AsciiWhitespace) and (c == '*' or c == '_' and (ctx.i == 0 or line[ctx.i - 1] notin AsciiAlphaNumeric or ctx.i + 1 >= line.len or line[ctx.i + 1] notin AsciiAlphaNumeric + {'_'})): if ctx.i + 1 < line.len and line[ctx.i + 1] == c: ?ctx.appendToggle(ifBold, "", "", state) inc ctx.i else: ?ctx.appendToggle(ifItalic, "", "", state) elif c == '`': ?ctx.parseCode(line, state) elif c == '~' and ctx.i + 1 < line.len and line[ctx.i + 1] == '~': ?ctx.appendToggle(ifDel, "", "", state) inc ctx.i elif c == '!' and ctx.i + 1 < line.len and line[ctx.i + 1] == '[': ?ctx.parseImage(line, state) elif c == '[': if ctx.bs == bsInBracket: ?state.write('[' & ctx.bracketChars) ctx.bracketChars = "" ctx.bs = bsInBracket elif c == ']' and ctx.bs == bsInBracket: ?ctx.parseLink(line, state) ctx.bracketChars = "" ctx.bs = bsNone elif c == '<': ?ctx.parseInTag(line, state) elif ctx.i + 4 < line.len and line.toOpenArray(ctx.i, ctx.i + 3) == "") if i != -1: ?state.write(line.substr(0, i + 2)) state.blockType = btNone ?state.parseInline(line.substr(i + 3)) else: ?state.writeLine(line) ok() proc parseLinkDef(state: var ParseState; line: string): Opt[void] = let pi = state.linkDefIdx state.linkDefIdx = 0 var i = line.skipBlanks(pi) if i >= line.len: if pi == 0: if state.linkDefLink != "": discard state.refMap.mgetOrPut(state.linkDefName, (move(state.linkDefLink), "")) state.blockData = "" state.blockType = btNone else: state.blockType = btPar state.reprocess = true else: state.blockData &= line return ok() if state.linkDefLink == "": i = state.linkDefLink.parseLinkDestination(line, i) if i == -1: state.blockType = btPar state.reprocess = true return ok() if i < line.len: i = line.skipBlanks(i) state.linkDefState = ldsTitle if i >= line.len: # next line state.blockData &= line return ok() var title = "" if line[i] in {'"', '\''}: i = title.parseTitle(line, i) if i == -1 or i < line.len: if pi == 0: # not the first line. put & reprocess discard state.refMap.mgetOrPut(state.linkDefName, (move(state.linkDefLink), move(title))) state.blockType = btNone state.blockData = "" else: state.blockType = btPar state.reprocess = true return ok() discard state.refMap.mgetOrPut(state.linkDefName, (move(state.linkDefLink), move(title))) state.blockData = "" state.blockType = btNone ok() proc readLine(state: var ParseState; line: var string): Opt[bool] = let stdin = cast[ChaFile](stdin) let hadLine = line != "" or state.blockType in {btList, btDefinitionBlank, btParBlank} if state.slurpIdx < 0: if ?stdin.readLine(line): if state.slurpIdx == -2: state.slurpBuf &= line & '\n' return ok(true) else: if state.slurpIdx < state.slurpBuf.len: line = state.slurpBuf.until('\n', state.slurpIdx) state.slurpIdx += line.len + 1 return ok(true) line = "" state.listState = lsLastLine ok(hadLine) # add one last iteration with a blank after EOF proc parse(state: var ParseState): Opt[void] = while state.reprocess or ?state.readLine(state.line): state.reprocess = false case state.blockType of btNone: ?state.parseNone(state.line) of btPre: ?state.parsePre(state.line) of btTabPre: ?state.parseTabPre(state.line) of btSpacePre: ?state.parseSpacePre(state.line) of btBlockquote: ?state.parseBlockquote(state.line) of btList: ?state.parseList(state.line) of btPar: ?state.parsePar(state.line) of btParBlank: ?state.parseParBlank(state.line) of btDefinition, btDefinitionPar: ?state.parseDefinition(state.line) of btDefinitionIndent: ?state.parseDefinitionIndent(state.line) of btDefinitionBlank: ?state.parseDefinitionBlank(state.line) of btTableHeader: ?state.parseTableHeader(state.line) of btTableBody: ?state.parseTableBody(state.line) of btHTML: ?state.parseHTML(state.line) of btHTMLPre: ?state.parseHTMLPre(state.line) of btComment: ?state.parseComment(state.line) of btLinkDef: ?state.parseLinkDef(state.line) ok() proc main*() = var state = ParseState( slurpIdx: -1, ofile: cast[ChaFile](stdout), refMap: newTable[string, tuple[link, title: string]]() ) discard state.parse() {.pop.} # raises: [] chawan-v0.4.0/adapter/format/tohtml.nim000066400000000000000000000006201520232313100200540ustar00rootroot00000000000000import std/os import utils/twtstr import ansi2html import dirlist2html import gmi2html import gopher2html import img2html import md2html proc main() = case paramStr(0).afterLast('/') of "ansi2html": ansi2html.main() of "dirlist2html": dirlist2html.main() of "gmi2html": gmi2html.main() of "gopher2html": gopher2html.main() of "img2html": img2html.main() else: md2html.main() main() chawan-v0.4.0/adapter/format/uri2html000066400000000000000000000003061520232313100175320ustar00rootroot00000000000000#!/bin/sh echo "${1:+"$1

      $1


      "}
        " "$CHA_LIBEXEC_DIR"/urldec | \ sed '/^#/d;s//\</g;s/&/\&/g;s/"/\"/g;s@.*@
      1. &@' chawan-v0.4.0/adapter/img/000077500000000000000000000000001520232313100153265ustar00rootroot00000000000000chawan-v0.4.0/adapter/img/canvas.nim000066400000000000000000000252651520232313100173200ustar00rootroot00000000000000# Very simple canvas renderer. At the moment, it uses an undocumented binary # protocol for reading commands, and renders it whenever stdin is closed. # So for now, it can only really render a single frame. # # It uses unifont for rendering text - currently I just store it as PNG # and read it with stbi. (TODO: try switching to a more efficient format # like qemacs fbf.) {.push raises: [].} import std/algorithm import std/posix import io/dynstream import io/packetreader import types/canvastypes import types/color import types/path import ../protocol/lcgi {.passc: "-I" & currentSourcePath().untilLast('/').} {.push header: """ #define STBI_ONLY_PNG #define STBI_NO_STDIO #define STBI_NO_LINEAR #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" """.} proc stbi_load_from_memory(buffer: ptr uint8; len: cint; x, y, comp: ptr cint; req_comp: cint): ptr uint8 proc stbi_image_free(retval_from_stbi_load: pointer) {.pop.} type GlyphCacheItem = object u: uint32 bmp: Bitmap Bitmap = ref object px: seq[RGBAColorBE] width: int height: int proc newBitmap(width, height: int): Bitmap = return Bitmap( px: newSeq[RGBAColorBE](width * height), width: width, height: height ) proc setpx(bmp: Bitmap; x, y: int; color: RGBAColorBE) {.inline.} = bmp.px[bmp.width * y + x] = color proc setpx(bmp: Bitmap; x, y: int; color: ARGBColor) {.inline.} = bmp.px[bmp.width * y + x] = rgba_be(color.r, color.g, color.b, color.a) proc getpx(bmp: Bitmap; x, y: int): RGBAColorBE {.inline.} = return bmp.px[bmp.width * y + x] proc setpxb(bmp: Bitmap; x, y: int; c: RGBAColorBE) {.inline.} = if c.a == 255: bmp.setpx(x, y, c) else: bmp.setpx(x, y, bmp.getpx(x, y).argb.blend(c.argb)) proc setpxb(bmp: Bitmap; x, y: int; c: ARGBColor) {.inline.} = bmp.setpxb(x, y, rgba_be(c.r, c.g, c.b, c.a)) const unifont = staticRead"res/unifont_jp-15.0.05.png" proc loadUnifont(unifont: string): Bitmap = var width, height, comp: cint let p = stbi_load_from_memory(cast[ptr uint8](unsafeAddr unifont[0]), cint(unifont.len), addr width, addr height, addr comp, 4) let len = width * height let bitmap = Bitmap( px: cast[seq[RGBAColorBE]](newSeqUninit[uint32](len)), width: int(width), height: int(height) ) copyMem(addr bitmap.px[0], p, len) stbi_image_free(p) return bitmap # https://en.wikipedia.org/wiki/Bresenham's_line_algorithm#All_cases proc plotLineLow(bmp: Bitmap; x1, y1, x2, y2: int; color: ARGBColor) = var dx = x2 - x1 var dy = y2 - y1 var yi = 1 if dy < 0: yi = -1 dy = -dy var D = 2 * dy - dx; var y = y1; for x in x1 ..< x2: if x < 0 or y < 0 or x >= bmp.width or y >= bmp.height: break bmp.setpxb(x, y, color) if D > 0: y = y + yi; D = D - 2 * dx; D = D + 2 * dy; proc plotLineHigh(bmp: Bitmap; x1, y1, x2, y2: int; color: ARGBColor) = var dx = x2 - x1 var dy = y2 - y1 var xi = 1 if dx < 0: xi = -1 dx = -dx var D = 2 * dx - dy var x = x1 for y in y1 ..< y2: if x < 0 or y < 0 or x >= bmp.width or y >= bmp.height: break bmp.setpxb(x, y, color) if D > 0: x = x + xi D = D - 2 * dy D = D + 2 * dx proc plotLine(bmp: Bitmap; x1, y1, x2, y2: int; color: ARGBColor) = if abs(y2 - y1) < abs(x2 - x1): if x1 > x2: bmp.plotLineLow(x2, y2, x1, y1, color) else: bmp.plotLineLow(x1, y1, x2, y2, color) else: if y1 > y2: bmp.plotLineHigh(x2, y2, x1, y1, color) else: bmp.plotLineHigh(x1, y1, x2, y2, color) proc plotLine(bmp: Bitmap; a, b: Vector2D; color: ARGBColor) = bmp.plotLine(int(a.x), int(a.y), int(b.x), int(b.y), color) proc plotLine(bmp: Bitmap; line: Line; color: ARGBColor) = bmp.plotLine(line.p0, line.p1, color) proc strokePath(bmp: Bitmap; lines: seq[Line]; color: ARGBColor) = for line in lines: bmp.plotLine(line, color) proc isInside(windingNumber: int; fillRule: CanvasFillRule): bool = return case fillRule of cfrNonZero: windingNumber != 0 of cfrEvenOdd: windingNumber mod 2 == 0 # Algorithm originally from SerenityOS. proc fillPath(bmp: Bitmap; lines: PathLines; color: ARGBColor; fillRule: CanvasFillRule) = var i = 0 var ylines: seq[LineSegment] = @[] for y in int(lines.miny) .. int(lines.maxy): for k in countdown(ylines.high, 0): if ylines[k].maxy < float64(y): ylines.del(k) # we'll sort anyways, so del is fine for j in i ..< lines.len: if lines[j].miny > float64(y): break if lines[j].maxy > float64(y): ylines.add(lines[j]) inc i ylines.sort(cmpLineSegmentX) var w = if fillRule == cfrNonZero: 1 else: 0 for k in 0 ..< ylines.high: let a = ylines[k] let b = ylines[k + 1] let sx = int(a.minyx) let ex = int(b.minyx) if w.isInside(fillRule) and y > 0: for x in sx .. ex: if x > 0: bmp.setpxb(x, y, color) if int(a.p0.y) != y and int(a.p1.y) != y and int(b.p0.y) != y and int(b.p1.y) != y and sx != ex or a.islope * b.islope < 0: case fillRule of cfrEvenOdd: inc w of cfrNonZero: if a.p0.y < a.p1.y: inc w else: dec w ylines[k].minyx += ylines[k].islope if ylines.len > 0: ylines[^1].minyx += ylines[^1].islope proc fillRect(bmp: Bitmap; x1, y1, x2, y2: int; color: ARGBColor) = for y in y1 ..< y2: for x in x1 ..< x2: bmp.setpxb(x, y, color) proc strokeRect(bmp: Bitmap; x1, y1, x2, y2: int; color: ARGBColor) = for x in x1 ..< x2: bmp.setpxb(x, y1, color) bmp.setpxb(x, y2, color) for y in y1 ..< y2: bmp.setpxb(x1, y, color) bmp.setpxb(x2, y, color) var unifontBitmap: Bitmap = nil var glyphCache: seq[GlyphCacheItem] = @[] var glyphCacheI = 0 proc getCharBmp(u: uint32): Bitmap = # We only have the BMP. let u = if u <= 0xFFFF: u else: 0xFFFD for it in glyphCache: if it.u == u: return it.bmp # Unifont glyphs start at x: 32, y: 64, and are of 8x16/16x16 size let gx = int(32 + 16 * (u mod 0x100)) let gy = int(64 + 16 * (u div 0x100)) var fullwidth = false const white = rgba_be(255, 255, 255, 255) block loop: # hack to recognize full width characters for y in 0 ..< 16: for x in 8 ..< 16: if unifontBitmap.getpx(gx + x, gy + y) != white: fullwidth = true break loop let bmp = newBitmap(if fullwidth: 16 else: 8, 16) for y in 0 ..< bmp.height: for x in 0 ..< bmp.width: let c = unifontBitmap.getpx(gx + x, gy + y) if c != white: bmp.setpx(x, y, c) if glyphCache.len < 256: glyphCache.add(GlyphCacheItem(u: u, bmp: bmp)) else: glyphCache[glyphCacheI] = GlyphCacheItem(u: u, bmp: bmp) inc glyphCacheI if glyphCacheI >= glyphCache.len: glyphCacheI = 0 return bmp proc drawBitmap(a, b: Bitmap; p: Vector2D; color: ARGBColor) = for y in 0 ..< b.height: for x in 0 ..< b.width: let ax = int(p.x) + x let ay = int(p.y) + y if ax >= 0 and ay >= y and ax < a.width and ay < a.height and b.getpx(x, y).a != 0: a.setpxb(ax, ay, color) proc fillText(bmp: Bitmap; text: string; x, y: float64; color: ARGBColor; textAlign: CanvasTextAlign) = var w = 0f64 var glyphs: seq[Bitmap] = @[] for u in text.points: let glyph = getCharBmp(u) glyphs.add(glyph) w += float64(glyph.width) var x = x #TODO rtl case textAlign of ctaLeft, ctaStart: discard of ctaRight, ctaEnd: x -= w of ctaCenter: x -= w / 2 for glyph in glyphs: bmp.drawBitmap(glyph, Vector2D(x: x, y: y - 8), color) x += float64(glyph.width) proc strokeText(bmp: Bitmap; text: string; x, y: float64; color: ARGBColor; textAlign: CanvasTextAlign) = #TODO bmp.fillText(text, x, y, color, textAlign) proc main() = enterNetworkSandbox() let os = newPosixStream(STDOUT_FILENO) let ps = newPosixStream(STDIN_FILENO) if getEnvEmpty("MAPPED_URI_SCHEME") != "img-codec+x-cha-canvas": cgiDie(ceInternalError, "invalid scheme") case getEnvEmpty("MAPPED_URI_PATH") of "decode": let headers = getEnvEmpty("REQUEST_HEADERS") for hdr in headers.split('\n'): if hdr.strip() == "Cha-Image-Info-Only: 1": #TODO this is a hack... # basically, we eat & discard all data from the buffer so it gets saved # to a cache file. then, actually render when the pager asks us to # do so. # obviously this is highly sub-optimal; a better solution would be to # leave stdin open & pass down the stream id from the buffer. (but then # you have to save canvas output too, so it doesn't have to be # re-coded, and handle that case in encoders... or implement on-demand # multi-frame output.) discard os.write("\n") discard ps.readAll() quit(0) var cmd: PaintCommand var width: int var height: int ps.withPacketReader r: r.sread(cmd) if cmd != pcSetDimensions: cgiDie(ceInternalError, "wrong dimensions") r.sread(width) r.sread(height) do: quit(1) if os.writeLoop("Cha-Image-Dimensions: " & $width & "x" & $height & "\n\n").isErr: quit(1) let bmp = newBitmap(width, height) var alive = true while alive: ps.withPacketReader r: r.sread(cmd) case cmd of pcSetDimensions: alive = false of pcFillRect, pcStrokeRect: var x1, y1, x2, y2: int var color: ARGBColor r.sread(x1) r.sread(y1) r.sread(x2) r.sread(y2) r.sread(color) if cmd == pcFillRect: bmp.fillRect(x1, y1, x2, y2, color) else: bmp.strokeRect(x1, y1, x2, y2, color) of pcFillPath: var lines: PathLines var color: ARGBColor var fillRule: CanvasFillRule r.sread(lines) r.sread(color) r.sread(fillRule) bmp.fillPath(lines, color, fillRule) of pcStrokePath: var lines: seq[Line] var color: ARGBColor r.sread(lines) r.sread(color) bmp.strokePath(lines, color) of pcFillText, pcStrokeText: if unifontBitmap == nil: unifontBitmap = loadUnifont(unifont) var text: string var x, y: float64 var color: ARGBColor var align: CanvasTextAlign r.sread(text) r.sread(x) r.sread(y) r.sread(color) r.sread(align) if cmd == pcFillText: bmp.fillText(text, x, y, color, align) else: bmp.strokeText(text, x, y, color, align) do: alive = false discard os.writeLoop(addr bmp.px[0], bmp.px.len * sizeof(bmp.px[0])) else: cgiDie(ceInternalError, "not implemented") main() {.pop.} # raises: [] chawan-v0.4.0/adapter/img/jebp.h000066400000000000000000006011771520232313100164330ustar00rootroot00000000000000/** * JebP - Single header WebP decoder */ /** * LICENSE ** * MIT No Attribution * * Copyright 2022 Jasmine Minter * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ // Attribution is not required, but would be appreciated :) /** * DOCUMENTATION ** * First and foremost, this project uses some custom types: * `jebp_byte`/`jebp_ubyte` is a singular byte. * `jebp_short`/jebp_ushort` is an integer of atleast 16-bits. * `jebp_int`/`jebp_uint` is an integer of atleast 32-bits. * * This is a header only file. This means that it operates as a standard header * and to generate the source file you define `JEBP_IMPLEMENTATION` in ONE file * only. For example: * ```c * #define JEBP_IMPLEMENTATION * #include "jebp.h" * ``` * * The most basic API call in this library is: * ```c * err = jebp_decode(&image, size, data); * ``` * where: * `jebp_image_t *image` is a pointer to an image structure to receive the * decoded data. * `size_t size` is the size of the WebP-encoded data buffer. * `const void *data` is a pointer to the WebP encoded data buffer, `size` * bytes large. * `jebp_error_t err` is the result of the operation (OK or an error code). * * For reading from a provided file path, this API call can be used instead: * ```c * err = jebp_read(&image, path); * ``` * where: * `const char *path` is the path of the file to be read. * * It is currently not possible to read from a `FILE *` object. * If you only want to get the size of the image without a full read, these * functions can be used instead: * ```c * err = jebp_decode_size(&image, size, data); * err = jebp_read_size(&image, path); * ``` * * The `jebp_image_t` structure has the following properties: * `jebp_int width` is the width of the image. * `jebp_int height` is the height of the image. * `jebp_color_t *pixels` is a pointer to an array pixels. Each `jebp_color_t` * structure contains four `jebp_ubyte` values for `r`, * `g`, `b` and `a`. This allows the `pixels` pointer * to be cast to `jebp_ubyte *` to get an RGBA pixel * buffer. * The allocated data in the image can be free'd with: * ```c * jebp_free_image(&image); * ``` * This function will also clear the structure, notably width and height will be * set to 0. * * The `jebp_error_t` enumeration has the following values: * `JEBP_OK` means the operation completed successfully. * `JEBP_ERROR_INVAL` means one of the arguments provided is invalid, usually * this refers to a NULL pointer. * `JEBP_ERROR_INVDATA` means the WebP-encoded data is invalid or corrupted. * `JEBP_ERROR_INVDATA_HEADER` is a suberror of `INVDATA` that indicates that * the header bytes are invalid. This file is likely not a * WebP file. * `JEBP_ERROR_EOF` means the end of the file (or data buffer) was reached * before the operation could successfully complete. * `JEBP_ERROR_NOSUP` means there is a feature in the WebP stream that is not * currently supported (see below). This can also represent * new features, versions or RIFF-chunks that were not in * the specification when writing. * `JEBP_ERROR_NOSUP_CODEC` is a suberror of `NOSUP` that indicates that the * RIFF chunk that is most likely for the codec is not * recognized. This is usually returned when a specific * file format has been disabled (see `JEBP_NO_VP8`, * `JEBP_NO_VP8L`, `JEBP_NO_VP8X`). * `JEBP_ERROR_NOMEM` means that a memory allocation failed, indicating that * there is no more memory available. * `JEBP_ERROR_IO` represents any generic I/O error, usually from * file-reading. * `JEBP_ERROR_UNKNOWN` means any unknown error. Currently this is only used * when an unknown value is passed into * `jebp_error_string`. * To get a human-readable string of the error, the following function can be * used: * ```c * const char *error = jebp_error_string(err); * ``` * * This is not a feature-complete WebP decoder and has the following * limitations: * - Does not support animated VP8X images, or filtered VP8X alpha. * - Does not support VP8L images with more than 256 huffman groups. This is * an arbitrary limit to prevent bad images from using too much memory. In * theory, images requiring more groups should be very rare. This limit may * be increased in the future. * * Features that will probably never be supported due to complexity or API * constraints: * - Decoding color profiles. * - Decoding metadata. * * Along with `JEBP_IMPLEMENTATION` defined above, there are a few other macros * that can be defined to change how JebP operates: * `JEBP_NO_STDIO` will disable the file-reading API. `JEBP_NO_CALLBACKS` * disables the callback API as well. * `JEBP_NO_SIMD` will disable SIMD optimizations. These are currently * not-used but the detection is there ready for further work. * `JEBP_NO_VP8` will disable VP8 (lossy) decoding support. * `JEBP_NO_VP8L` will disable VP8L (lossless) decoding support. Note that * either VP8 or VP8L decoding support is required and it is an * error to disable both. * `JEBP_NO_VP8X` will disable VP8X (extended format) support. This is a * container for VP8 and VP8L, so disabling either of those * also disables VP8X containing the respective format. * `JEBP_ONLY_VP8` and `JEBP_ONLY_VP8L` will disable all other features except * the specified feature. * `JEBP_ALLOC` and `JEBP_FREE` can be defined to functions for a custom * allocator. They either both have to be defined or neither * defined. * * This single-header library requires C99 to be supported. Along with this it * requires the following headers from the system to successfully compile. Some * of these can be disabled with the above macros: * `stddef.h` is used for the definition of the `size_t` type. * `limits.h` is used for the `UINT_MAX` macro to check the size of `int`. If * `int` is not 32-bits, `long` will be used for `jebp_int` * instead. * `string.h` is used for `memset` to clear out memory. * `stdio.h` is used for I/O support and logging errors. If `JEBP_NO_STDIO` is * defined and `JEBP_LOG_ERRORS` is not defined, this will not be * included. * `stdlib.h` is used for the default implementations of `JEBP_ALLOC` * and `JEBP_FREE`, using `malloc` and `free` respectively. If * those macros are already defined to something else, this will * not be included. * `emmintrin.h` and `arm_neon.h` is used for SIMD intrinsice. If * `JEBP_NO_SIMD` is defined these will not be included. * * The following predefined macros are also used for compiler-feature, SIMD and * endianness detection. These can be changed or modified before import to * change JebP's detection logic: * `__STDC_VERSION__` is used to detect if the compiler supports C99 and also * checks for C11 support to use `_Noreturn`. * `__has_attribute` and `__has_builtin` are used to detect the `noreturn` and * `always_inline` attributes, along with the * `__builtin_bswap16` and `__builtin_bswap32` builtins. * Note that `__has_attribute` does not fallback to compiler * version checks since most compilers already support * `__has_attribute`. * `__GNUC__` and `__GNUC_MINOR__` are used to detect if the compiler is GCC * (or GCC compatible) and what version of GCC it is. This, in * turn, is used to polyfill `__has_builtin` on older compilers * that may not support it. * `__clang__` is used to detect the Clang compiler. This is only used to set * the detected GCC version higher since Clang still marks itself * as GCC 4.2 by default. No Clang version detection is done. * `_MSC_VER` is used to detect the MSVC compiler. This is used to check * support for `__declspec(noreturn)`, `__forceinline` and * `_byteswap_ulong`. No MSVC version detection is done. * `__LITTLE_ENDIAN__` is used to check if the architecture is little-endian. * Note that this is only checked either if the * architecture cannot be detected or, in special cases, * where there is not enough information from the * architecture or compiler to detect endianness. Also * note that big-endian and other more-obscure endian * types are not detected. Little-endian is the only * endianness detected and is used for optimization in a * few areas. If the architecture is not little-endian or * cannot be detected as such, a naive solution is used * instead. * `__i386`, `__i386__` and `_M_IX86` are used to detect if this is being * compiled for x86-32 (also known as x86, IA-32, or i386). If one of * these are defined, it is also assumed that the architecture is * little-endian. `_M_IX86` is usually present on MSVC, while * the other two are usually present on most other compilers. * `__SSE2__` and `_M_IX86_FP` are used to detect SSE2 support on x86-32. * `_M_IX86`, which is usually present on MSVC, must equal 2 to * indicate that the code is being compiled for a SSE2-compatible * floating-point unit. `__SSE2__` is usually present on most other * compilers. * `__x86_64`, `__x86_64__` and `_M_X64` are used to detect if this is being * compiled for x86-64 (also known as AMD64). If one of these are * defined, it is also assumed that the architecture is little-endian * and that SSE2 is supported (which is required for x86-64 support). * `_M_X64` is usually present on MSVC, while the other two are * usually present on most other compilers. * `__arm`, `__arm__` and `_M_ARM` are used to detect if this is being * compiled for AArch32 (also known as arm32 or armhf). If one of * these are defined on Windows, it is also assumed that Neon is * supported (which is required for Windows). `_M_ARM` is usually * present on MSVC while the other two are usually present on most * other compilers. * `__ARM_NEON` is used to detect Neon support on AArch32. MSVC doesn't seem * to support this and I can't find any info on detecting Neon * support for MSVC. I have found mentions of Windows requiring * Neon support but cannot find any concrete proof anywhere. * `__aarch64`, `__aarch64__` and `_M_ARM64` are used to detect if this is * being compiled for AArch64 (also known as arm64). If one of * these are defined, it is also assumed that Neon is supported * (which is required for AArch64 support). `_M_ARM64` is usually * present on MSVC, while the other two are usually present on * most other compilers. * `__ARM_BIG_ENDIAN` is used to detect, on AArch/ARM architectures, if it is * in big-endian mode. However, as mentioned above, there * is no special code for big-endian and it's worth noting * that this is just used to force-disable little-endian. * If this is not present, it falls back to using * `__LITTLE_ENDIAN__`. It is also worth noting that MSVC * does not seem to provide a way to detect endianness. It * may be that Windows requires little-endian but I can't * find any concrete sources on this so currently * little-endian detection is not supported on MSVC. */ /** * HEADER */ #ifndef JEBP__HEADER #define JEBP__HEADER #ifdef __cplusplus extern "C" { #endif // __cplusplus #include #include #if UINT_MAX >= 0xffffffff #define JEBP__INT int #else #define JEBP__INT long #endif typedef signed char jebp_byte; typedef unsigned char jebp_ubyte; typedef short jebp_short; typedef unsigned short jebp_ushort; typedef JEBP__INT jebp_int; typedef unsigned JEBP__INT jebp_uint; typedef enum jebp_error_t { JEBP_OK, JEBP_ERROR_INVAL, JEBP_ERROR_INVDATA, JEBP_ERROR_INVDATA_HEADER, JEBP_ERROR_EOF, JEBP_ERROR_NOSUP, JEBP_ERROR_NOSUP_CODEC, JEBP_ERROR_NOMEM, JEBP_ERROR_IO, JEBP_ERROR_UNKNOWN, JEBP_NB_ERRORS } jebp_error_t; typedef struct jebp_color_t { jebp_ubyte r; jebp_ubyte g; jebp_ubyte b; jebp_ubyte a; } jebp_color_t; typedef struct jebp_image_t { jebp_int width; jebp_int height; jebp_color_t *pixels; } jebp_image_t; const char *jebp_error_string(jebp_error_t err); void jebp_free_image(jebp_image_t *image); jebp_error_t jebp_decode_size(jebp_image_t *image, size_t size, const void *data); jebp_error_t jebp_decode(jebp_image_t *image, size_t size, const void *data); // Callbacks API #ifndef JEBP_NO_CALLBACKS typedef struct jebp_io_callbacks { /* fill "data" with 'n' bytes; return number of bytes read */ size_t (*read)(void *data, size_t n, void *user); /* return 1 if error, 0 if no error */ int (*check_error)(void *user); } jebp_io_callbacks; jebp_error_t jebp_read_from_callbacks(jebp_image_t *image, const jebp_io_callbacks *cb, void *user); jebp_error_t jebp_read_size_from_callbacks(jebp_image_t *image, const jebp_io_callbacks *cb, void *user); // I/O API #ifndef JEBP_NO_STDIO jebp_error_t jebp_read_size(jebp_image_t *image, const char *path); jebp_error_t jebp_read(jebp_image_t *image, const char *path); #endif // JEBP_NO_STDIO #endif // JEBP_NO_CALLBACKS #ifdef __cplusplus } #endif // __cplusplus #endif // JEBP__HEADER /** * IMPLEMENTATION */ #ifdef JEBP_IMPLEMENTATION #include #if !defined(JEBP_NO_STDIO) #include #endif #if !defined(JEBP_ALLOC) && !defined(JEBP_FREE) #include #define JEBP_ALLOC malloc #define JEBP_FREE free #elif !defined(JEBP_ALLOC) || !defined(JEBP_FREE) #error "Both JEBP_ALLOC and JEBP_FREE have to be defined" #endif #if defined(JEBP_ONLY_VP8) || defined(JEBP_ONLY_VP8L) #define JEBP_NO_VP8X #ifndef JEBP_ONLY_VP8 #define JEBP_NO_VP8L #endif // JEBP_ONLY_VP8 #ifndef JEBP_ONLY_VP8L #define JEBP_NO_VP8 #endif // JEBP_ONLY_VP8L #endif #if defined(JEBP_NO_VP8) && defined(JEBP_NO_VP8L) #error "Either VP8 or VP8L has to be enabled" #endif /** * Predefined macro detection */ #ifdef __STDC_VERSION__ #if __STDC_VERSION__ < 199901 #error "Standard C99 support is required" #endif #else // __STDC_VERSION__ #if defined(__GNUC__) #warning "C version cannot be checked, compilation may fail" #elif defined(_MSC_VER) #pragma message( \ "MSVC by default is C89 'with extensions', use /std:c11 to ensure there are no errors") #endif #endif // __STDC_VERSION__ #if defined(__clang__) // The default GNUC version provided by Clang is just short of what we need #define JEBP__GNU_VERSION 403 #elif defined(__GNUC__) #define JEBP__GNU_VERSION ((__GNUC__ * 100) + __GNUC_MINOR__) #else #define JEBP__GNU_VERSION 0 #endif // __GNUC__ #ifdef __has_attribute #define JEBP__HAS_ATTRIBUTE __has_attribute #else // __has_attribute // We don't add GCC version checks since, unlike __has_builtin, __has_attribute // has been out for so long that its more likely that the compiler supports it. #define JEBP__HAS_ATTRIBUTE(attr) 0 #endif // __has_attribute #if JEBP__HAS_ATTRIBUTE(always_inline) #define JEBP__ALWAYS_INLINE __attribute__((always_inline)) #elif defined(_MSC_VER) #define JEBP__ALWAYS_INLINE __forceinline #else #define JEBP__ALWAYS_INLINE #endif #define JEBP__INLINE static inline JEBP__ALWAYS_INLINE #if JEBP__HAS_ATTRIBUTE(aligned) #define JEBP__ALIGN_TYPE(type, align) type __attribute__((aligned(align))) #elif defined(_MSC_VER) #define JEBP__ALIGN_TYPE(type, aligned) __declspec(align(aligned)) type #else #define JEBP__ALIGN_TYPE(type, align) type #endif #ifdef __has_builtin #define JEBP__HAS_BUILTIN __has_builtin #else // __has_builtin #define JEBP__HAS_BUILTIN(builtin) \ JEBP__VERSION##builtin != 0 && JEBP__GNU_VERSION >= JEBP__VERSION##builtin // I believe this was added earlier but GCC 4.3 is the first time it was // mentioned in the changelog and manual. #define JEBP__VERSION__builtin_bswap16 403 #define JEBP__VERSION__builtin_bswap32 403 #endif // __has_builtin #if JEBP__HAS_BUILTIN(__builtin_bswap16) #define JEBP__SWAP16(value) __builtin_bswap16(value) #elif defined(_MSC_VER) #define JEBP__SWAP16(value) _byteswap_ushort(value) #endif #if JEBP__HAS_BUILTIN(__builtin_bswap32) #define JEBP__SWAP32(value) __builtin_bswap32(value) #elif defined(_MSC_VER) #define JEBP__SWAP32(value) _byteswap_ulong(value) #endif // We don't do any SIMD runtime detection since that causes alot of // heavily-documented issues that I won't go into here. Instead, if the compiler // supports it (and requests it) we will use it. It helps that both x86-64 and // AArch64 always support the SIMD from their 32-bit counterparts. #if defined(__i386) || defined(__i386__) || defined(_M_IX86) #define JEBP__ARCH_X86 #if defined(__SSE2__) || _M_IX86_FP == 2 #define JEBP__SIMD_SSE2 #endif #elif defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) #define JEBP__ARCH_X86 #define JEBP__SIMD_SSE2 #elif defined(__arm) || defined(__arm__) || defined(_M_ARM) #define JEBP__ARCH_ARM #if defined(__ARM_NEON) || defined(_MSC_VER) // According to the following article, MSVC requires Neon support // https://docs.microsoft.com/en-us/cpp/build/overview-of-arm-abi-conventions #define JEBP__SIMD_NEON #endif #elif defined(__aarch64) || defined(__aarch64__) || defined(_M_ARM64) #define JEBP__ARCH_ARM #define JEBP__SIMD_NEON #define JEBP__SIMD_NEON64 #endif #if defined(JEBP__ARCH_X86) // x86 is always little-endian #define JEBP__LITTLE_ENDIAN #elif defined(JEBP__ARCH_ARM) && defined(__ARM_BIG_ENDIAN) // The ACLE big-endian define overrules everything else, including the defualt // endianness detection #elif defined(JEBP__ARCH_ARM) && (defined(__ARM_ACLE) || defined(_MSC_VER)) // If ACLE is supported and big-endian is not defined, it must be little-endian // According to the article linked above, MSVC only supports little-endian #define JEBP__LITTLE_ENDIAN #elif defined(__LITTLE_ENDIAN__) || __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define JEBP__LITTLE_ENDIAN #endif #ifdef JEBP_NO_SIMD #undef JEBP__SIMD_SSE2 #undef JEBP__SIMD_NEON #endif // JEBP_NO_SIMD #ifdef JEBP__SIMD_SSE2 #include #define JEBP__SIMD_ALIGN 16 #endif // JEBP__SIMD_SSE2 #ifdef JEBP__SIMD_NEON #include #define JEBP__SIMD_ALIGN 16 #endif // JEBP__SIMD_NEON #ifndef JEBP__SIMD_ALIGN #define JEBP__SIMD_ALIGN 1 #endif // JEBP__SIMD_ALIGN /** * Common utilities */ // TODO: Maybe we should have a logging flag and add custom logs with more // information to each error (and maybe other stuff like allocations) #define JEBP__MIN(a, b) ((a) < (b) ? (a) : (b)) #define JEBP__MAX(a, b) ((a) > (b) ? (a) : (b)) #define JEBP__ABS(a) ((a) < 0 ? -(a) : (a)) #define JEBP__CLAMP(x, min, max) JEBP__MIN(JEBP__MAX(x, min), max) #define JEBP__CLAMP_UBYTE(x) JEBP__CLAMP(x, 0, 255) // F=floor, C=ceil, R=round #define JEBP__CSHIFT(a, b) (((a) + (1 << (b)) - 1) >> (b)) #define JEBP__RSHIFT(a, b) (((a) + (1 << ((b)-1))) >> (b)) #define JEBP__FAVG(a, b) (((a) + (b)) / 2) #define JEBP__RAVG(a, b) JEBP__RSHIFT((a) + (b), 1) #define JEBP__RAVG3(a, b, c) JEBP__RSHIFT((a) + (b) + (b) + (c), 2) #define JEBP__CALIGN(a, b) (((a) + (b)-1) & ~((b)-1)) #define JEBP__SET_MASK(x, m, v) ((x) = ((x) & ~(m)) | ((v) & (m))) #define JEBP__SET_BIT(x, b, v) JEBP__SET_MASK(x, b, (v) ? (b) : 0) #define JEBP__CLEAR(ptr, size) memset(ptr, 0, size) // A simple utility that updates an error pointer if it currently does not have // an error JEBP__INLINE jebp_error_t jebp__error(jebp_error_t *err, jebp_error_t error) { if (*err == JEBP_OK) { *err = error; } return *err; } static jebp_error_t jebp__alloc_image0(jebp_image_t *image, jebp_int width) { image->pixels = JEBP_ALLOC(width * image->height * sizeof(jebp_color_t)); if (image->pixels == NULL) { return JEBP_ERROR_NOMEM; } return JEBP_OK; } static jebp_error_t jebp__alloc_image(jebp_image_t *image) { return jebp__alloc_image0(image, image->width); } /** * Reader abstraction */ #define JEBP__BUFFER_SIZE 4096 typedef struct jebp__reader_t { size_t nb_bytes; const jebp_ubyte *bytes; #ifndef JEBP_NO_CALLBACKS void *buffer; void *user; jebp_io_callbacks cb; #endif // JEBP_NO_CALLBACKS } jebp__reader_t; static void jebp__init_memory(jebp__reader_t *reader, size_t size, const void *data) { reader->nb_bytes = size; reader->bytes = data; #ifndef JEBP_NO_CALLBACKS reader->user = NULL; JEBP__CLEAR(&reader->cb, sizeof(reader->cb)); #endif // JEBP_NO_CALLBACKS } #ifndef JEBP_NO_CALLBACKS static jebp_error_t jebp__init_callbacks(jebp__reader_t *reader, const jebp_io_callbacks *cb, void *user) { reader->nb_bytes = 0; reader->cb = *cb; reader->user = user; reader->buffer = JEBP_ALLOC(JEBP__BUFFER_SIZE); if (reader->buffer == NULL) { return JEBP_ERROR_NOMEM; } return JEBP_OK; } #endif // JEBP_NO_CALLBACKS static jebp_error_t jebp__buffer_bytes(jebp__reader_t *reader) { if (reader->nb_bytes > 0) { return JEBP_OK; } #ifndef JEBP_NO_CALLBACKS if (reader->cb.read != NULL) { reader->nb_bytes = reader->cb.read(reader->buffer, JEBP__BUFFER_SIZE, reader->user); reader->bytes = reader->buffer; if (reader->cb.check_error && reader->cb.check_error(reader->user)) { return JEBP_ERROR_IO; } } #endif // JEBP_NO_CALLBACKS if (reader->nb_bytes == 0) { return JEBP_ERROR_EOF; } return JEBP_OK; } // TODO: Most reads are only a few bytes so maybe I should optimize for that static jebp_error_t jebp__read_bytes(jebp__reader_t *reader, size_t size, void *data) { jebp_error_t err; jebp_ubyte *bytes = data; while (size > 0) { if ((err = jebp__buffer_bytes(reader)) != JEBP_OK) { return err; } size_t nb_bytes = JEBP__MIN(size, reader->nb_bytes); if (bytes != NULL) { memcpy(bytes, reader->bytes, nb_bytes); bytes += nb_bytes; } size -= nb_bytes; reader->nb_bytes -= nb_bytes; reader->bytes += nb_bytes; } return JEBP_OK; } // Reader mapping is only used by VP8 #ifndef JEBP_NO_VP8 static jebp_error_t jebp__map_reader(jebp__reader_t *reader, jebp__reader_t *map, size_t size) { jebp_error_t err; #ifndef JEBP_NO_CALLBACKS if (reader->cb.read != NULL) { void *data = JEBP_ALLOC(size); if (data == NULL) { return JEBP_ERROR_NOMEM; } if ((err = jebp__read_bytes(reader, size, data)) != JEBP_OK) { JEBP_FREE(data); return err; } jebp__init_memory(map, size, data); map->buffer = data; return JEBP_OK; } map->buffer = NULL; #endif // JEBP_NO_CALLBACKS const void *data = reader->bytes; if ((err = jebp__read_bytes(reader, size, NULL)) != JEBP_OK) { return err; } jebp__init_memory(map, size, data); return JEBP_OK; } static void jebp__unmap_reader(jebp__reader_t *map) { #ifndef JEBP_NO_CALLBACKS JEBP_FREE(map->buffer); #else // JEBP_NO_CALLBACKS (void)map; #endif // JEBP_NO_CALLBACKS } #endif // JEBP_NO_VP8 static jebp_ubyte jebp__read_uint8(jebp__reader_t *reader, jebp_error_t *err) { if (*err != JEBP_OK) { return 0; } if ((*err = jebp__buffer_bytes(reader)) != JEBP_OK) { return 0; } reader->nb_bytes -= 1; return *(reader->bytes++); } // 16-bit uint reading is only used by VP8 #ifndef JEBP_NO_VP8 static jebp_ushort jebp__read_uint16(jebp__reader_t *reader, jebp_error_t *err) { if (*err != JEBP_OK) { return 0; } #ifdef JEBP__LITTLE_ENDIAN jebp_ushort value = 0; *err = jebp__read_bytes(reader, 2, &value); return value; #else // JEBP__LITTLE_ENDIAN jebp_ubyte bytes[2]; *err = jebp__read_bytes(reader, 2, bytes); return bytes[0] | (bytes[1] << 8); #endif // JEBP__LITTLE_ENDIAN } #endif // JEBP_NO_VP8 // 24-bit uint reading is only used by VP8 and VP8X #if !defined(JEBP_NO_VP8) || !defined(JEBP_NO_VP8X) static jebp_int jebp__read_uint24(jebp__reader_t *reader, jebp_error_t *err) { if (*err != JEBP_OK) { return 0; } #ifdef JEBP__LITTLE_ENDIAN jebp_int value = 0; *err = jebp__read_bytes(reader, 3, &value); return value; #else // JEBP__LITTLE_ENDIAN jebp_ubyte bytes[3]; *err = jebp__read_bytes(reader, 3, bytes); return (jebp_int)bytes[0] | ((jebp_int)bytes[1] << 8) | ((jebp_int)bytes[2] << 16); #endif // JEBP__LITTLE_ENDIAN } #endif // !defined(JEBP_NO_VP8) || !defined(JEBP_NO_VP8X) static jebp_uint jebp__read_uint32(jebp__reader_t *reader, jebp_error_t *err) { if (*err != JEBP_OK) { return 0; } #ifdef JEBP__LITTLE_ENDIAN jebp_uint value = 0; *err = jebp__read_bytes(reader, 4, &value); return value; #else // JEBP__LITTLE_ENDIAN jebp_ubyte bytes[4]; *err = jebp__read_bytes(reader, 4, bytes); return (jebp_uint)bytes[0] | ((jebp_uint)bytes[1] << 8) | ((jebp_uint)bytes[2] << 16) | ((jebp_uint)bytes[3] << 24); #endif // JEBP__LITTLE_ENDIAN } /** * RIFF container */ #define JEBP__RIFF_TAG 0x46464952 #define JEBP__WEBP_TAG 0x50424557 typedef struct jebp__chunk_t { jebp_uint tag; jebp_uint size; } jebp__chunk_t; typedef struct jebp__riff_reader_t { jebp__reader_t *reader; jebp__chunk_t header; } jebp__riff_reader_t; static jebp_error_t jebp__read_chunk(jebp__riff_reader_t *riff, jebp__chunk_t *chunk) { jebp_error_t err = JEBP_OK; chunk->tag = jebp__read_uint32(riff->reader, &err); chunk->size = jebp__read_uint32(riff->reader, &err); chunk->size += chunk->size % 2; // round up to even return err; } static jebp_error_t jebp__read_riff_header(jebp__riff_reader_t *riff, jebp__reader_t *reader) { jebp_error_t err; riff->reader = reader; if ((err = jebp__read_chunk(riff, &riff->header)) != JEBP_OK) { return err; } if (riff->header.tag != JEBP__RIFF_TAG) { return JEBP_ERROR_INVDATA_HEADER; } if (jebp__read_uint32(reader, &err) != JEBP__WEBP_TAG) { return jebp__error(&err, JEBP_ERROR_INVDATA_HEADER); } return err; } static jebp_error_t jebp__read_riff_chunk(jebp__riff_reader_t *riff, jebp__chunk_t *chunk) { jebp_error_t err; if ((err = jebp__read_chunk(riff, chunk)) != JEBP_OK) { return err; } if (chunk->size > riff->header.size) { return JEBP_ERROR_INVDATA; } riff->header.size -= chunk->size; return JEBP_OK; } /** * YUV image */ #ifndef JEBP_NO_VP8 // R = 255 * ((Y-16)/219 + (Cr-128)/224 * 1.402) #define JEBP__CONVERT_R(y, v) \ JEBP__CLAMP_UBYTE(((y)*298 + (v)*409 - 57068) >> 8) // Eg = (Ey - Er*0.299 - Eb*0.114)/0.587 // = Ey/0.587 - (Ey+Ecr*1.402)*(0.299/0.587) - (Ey+Ecb*1.772)*(0.114/0.587) // = Ey - Ecr*(1.402*0.299/0.587) - Ecb*(1.772*0.114/0.587) // G = 255 * ((Y-16)/219 - (Cr-128)/224 * (1.402*0.299/0.587) - (Cb-128)/224 * // (1.772*0.114/0.587)) #define JEBP__CONVERT_G(y, u, v) \ JEBP__CLAMP_UBYTE(((y)*298 - (u)*208 - (v)*100 + 34707) >> 8) // B = 255 * ((Y-16)/219 + (Cb-128)/224 * 1.772) #define JEBP__CONVERT_B(y, u) \ JEBP__CLAMP_UBYTE(((y)*298 + (u)*516 - 70870) >> 8) typedef struct jebp__yuv_image_t { jebp_int width; jebp_int height; jebp_int stride; jebp_int uv_width; jebp_int uv_height; jebp_int uv_stride; jebp_ubyte *buffer; jebp_ubyte *y; jebp_ubyte *u; jebp_ubyte *v; } jebp__yuv_image_t; static void jebp__fill_yuv_edge(jebp_ubyte *pred, jebp_int stride, jebp_int height) { jebp_ubyte *top = &pred[-stride]; memset(top, 127, stride - JEBP__SIMD_ALIGN); top[-1] = 127; for (jebp_int y = 0; y < height; y += 1) { jebp_ubyte *row = &pred[y * stride]; row[-1] = 129; } } static jebp_error_t jebp__alloc_yuv_image(jebp__yuv_image_t *image) { // The only time this function is used, width/height are even image->uv_width = image->width / 2; image->uv_height = image->height / 2; // We have extra columns to the left for filling default prediction values, // aligned to the SIMD alignment image->stride = image->width + JEBP__SIMD_ALIGN; image->uv_stride = image->uv_width + JEBP__SIMD_ALIGN; // We also have one row above for the same reason size_t y_size = image->stride * (image->height + 1); size_t uv_size = image->uv_stride * (image->uv_height + 1); size_t uv_offset = image->uv_stride + JEBP__SIMD_ALIGN; image->buffer = JEBP_ALLOC(y_size + uv_size * 2 + uv_offset * 2 + JEBP__SIMD_ALIGN); if (image->buffer == NULL) { return JEBP_ERROR_NOMEM; } // Setup the actual pointers // TODO: maybe move this to a function and use native aligned alloc if // available image->y = (void *)JEBP__CALIGN((size_t)image->buffer, JEBP__SIMD_ALIGN); image->u = image->y + y_size; image->v = image->u + uv_size; image->y += image->stride + JEBP__SIMD_ALIGN; image->u += uv_offset; image->v += uv_offset; // Setup default values for edge prediction jebp__fill_yuv_edge(image->y, image->stride, image->height); jebp__fill_yuv_edge(image->u, image->uv_stride, image->uv_height); jebp__fill_yuv_edge(image->v, image->uv_stride, image->uv_height); return JEBP_OK; } static void jebp__free_yuv_image(jebp__yuv_image_t *image) { JEBP_FREE(image->buffer); } JEBP__INLINE void jebp__upscale_uv_row(jebp_ubyte *out, jebp_ubyte *in, jebp_int width) { jebp_int x = 0; for (; x < width - 1; x += 1) { out[x * 2] = in[x]; out[x * 2 + 1] = JEBP__RAVG(in[x], in[x + 1]); } if (x < width) { out[x * 2] = in[x]; out[x * 2 + 1] = in[x]; } } static jebp_error_t jebp__convert_yuv_image(jebp_image_t *out, jebp__yuv_image_t *in) { // Buffers to upscale UV rows into jebp_ubyte *uv_buffer = JEBP_ALLOC(in->width * 4); if (uv_buffer == NULL) { return JEBP_ERROR_NOMEM; } jebp_ubyte *u_prev = uv_buffer; jebp_ubyte *v_prev = u_prev + in->width; jebp_ubyte *u_next = v_prev + in->width; jebp_ubyte *v_next = u_next + in->width; jebp__upscale_uv_row(u_prev, in->u, in->uv_width); jebp__upscale_uv_row(v_prev, in->v, in->uv_width); for (jebp_int y = 0; y < out->height; y += 2) { // Rec. 601 doesn't specify the chroma location for 420, for now I'm // assuming it is top-left // Even rows jebp_color_t *row = &out->pixels[y * out->width]; jebp_ubyte *y_row = &in->y[y * in->stride]; for (jebp_int x = 0; x < out->width; x += 1) { row[x].r = JEBP__CONVERT_R(y_row[x], v_prev[x]); row[x].g = JEBP__CONVERT_G(y_row[x], u_prev[x], v_prev[x]); row[x].b = JEBP__CONVERT_B(y_row[x], u_prev[x]); row[x].a = 255; } if (y + 1 == out->height) { // If the image height is odd, end here break; } else if (y + 2 == in->height) { // If this is the final row, duplicate the UV rows u_next = u_prev; v_next = v_prev; } else { // Upscale next row jebp_int uv_next = (y / 2 + 1) * in->uv_stride; jebp__upscale_uv_row(u_next, &in->u[uv_next], in->uv_width); jebp__upscale_uv_row(v_next, &in->v[uv_next], in->uv_width); } // Odd rows row = &out->pixels[(y + 1) * out->width]; y_row = &in->y[(y + 1) * in->stride]; for (jebp_int x = 0; x < out->width; x += 1) { jebp_ubyte u_avg = JEBP__RAVG(u_prev[x], u_next[x]); jebp_ubyte v_avg = JEBP__RAVG(v_prev[x], v_next[x]); row[x].r = JEBP__CONVERT_R(y_row[x], v_avg); row[x].g = JEBP__CONVERT_G(y_row[x], u_avg, v_avg); row[x].b = JEBP__CONVERT_B(y_row[x], u_avg); row[x].a = 255; } // Swap buffers jebp_ubyte *tmp; tmp = u_prev; u_prev = u_next; u_next = tmp; tmp = v_prev; v_prev = v_next; v_next = tmp; } JEBP_FREE(uv_buffer); return JEBP_OK; } /** * Boolean entropy coding */ #define JEBP__NB_PROBS(nb) ((nb)-1) #define JEBP__NB_TREE(nb) (2 * JEBP__NB_PROBS(nb)) typedef struct jebp__bec_reader_t { jebp__reader_t *reader; size_t nb_bytes; jebp_int nb_bits; jebp_int value; jebp_int range; } jebp__bec_reader_t; static jebp_error_t jebp__init_bec_reader(jebp__bec_reader_t *bec, jebp__reader_t *reader, size_t size) { jebp_error_t err; if (size < 2) { return JEBP_ERROR_INVDATA; } bec->reader = reader; bec->nb_bytes = size - 2; bec->nb_bits = 8; #if defined(JEBP__LITTLE_ENDIAN) && defined(JEBP__SWAP16) jebp_ushort value = 0; err = jebp__read_bytes(reader, 2, &value); bec->value = JEBP__SWAP16(value); #else jebp_ubyte bytes[2]; err = jebp__read_bytes(reader, 2, bytes); bec->value = (bytes[0] << 8) | bytes[1]; #endif if (err != JEBP_OK) { return err; } bec->range = 255; return JEBP_OK; } // TODO: this code can definitely be improved, especially since its used alot // and probably needs to be very fast. Notable changes: // - instead of a while loop do all the shifts at once // - fetch 16 or 24-bits at a time from the reader (instead of // byte-by-byte) // - check bit size and fetch more if needed at the start of a new call // (instead of at the end of the previous call) // - optimize the prob = 128 variant, maybe optimize int reading with // multiple prob=128 bits // - it might be possible to simplify the split calculation by always // storing the range with -1 // - instead of shifting the value, use nb_bits as a shift offset of the // value static jebp_int jebp__read_bool(jebp__bec_reader_t *bec, jebp_ubyte prob, jebp_error_t *err) { if (*err != JEBP_OK) { return 0; } if (bec->nb_bytes == 0 && bec->nb_bits == 0) { jebp__error(err, JEBP_ERROR_INVDATA); return 0; } jebp_int split = 1 + (((bec->range - 1) * prob) >> 8); jebp_int split_high = split << 8; jebp_int boolval = bec->value >= split_high; if (boolval) { bec->value -= split_high; bec->range -= split; } else { bec->range = split; } while (bec->range < 128) { bec->value <<= 1; bec->range <<= 1; bec->nb_bits -= 1; if (bec->nb_bits == 0) { if (bec->nb_bytes == 0) { break; } bec->value |= jebp__read_uint8(bec->reader, err); bec->nb_bytes -= 1; bec->nb_bits = 8; } } return boolval; } JEBP__INLINE jebp_int jebp__read_flag(jebp__bec_reader_t *bec, jebp_error_t *err) { return jebp__read_bool(bec, 128, err); } static jebp_uint jebp__read_bec_uint(jebp__bec_reader_t *bec, jebp_int size, jebp_error_t *err) { if (*err != JEBP_OK) { return 0; } jebp_uint value = 0; for (jebp_int i = 0; i < size; i += 1) { value = (value << 1) | jebp__read_flag(bec, err); } return value; } static jebp_int jebp__read_bec_int(jebp__bec_reader_t *bec, jebp_int size, jebp_error_t *err) { if (*err != JEBP_OK) { return 0; } jebp_int value = jebp__read_bec_uint(bec, size, err); return jebp__read_flag(bec, err) ? -value : value; } static jebp_int jebp__read_tree(jebp__bec_reader_t *bec, const jebp_byte *tree, const jebp_ubyte *probs, jebp_error_t *err) { jebp_int index = 0; do { const jebp_byte *node = &tree[index]; index = node[jebp__read_bool(bec, probs[index / 2], err)]; } while (index > 0); return -index; } /** * Compressed B.E.C. header */ #define JEBP__NB_SEGMENTS 4 #define JEBP__NB_QUANT_INDEXES 128 #define JEBP__NB_COEFFS 16 #define JEBP__NB_COEFF_BANDS 8 #define JEBP__NB_TOKEN_COMPLEXITIES 3 #define JEBP__CLAMP_QUANT(q) JEBP__CLAMP(q, 0, JEBP__NB_QUANT_INDEXES - 1) typedef enum jebp__segment_type_t { JEBP__SEGMENT_NONE = -1, JEBP__SEGMENT_ZERO, JEBP__SEGMENT_ID } jebp__segment_type_t; typedef enum jebp__quant_type_t { JEBP__QUANT_Y_DC, JEBP__QUANT_Y_AC, JEBP__QUANT_Y2_DC, JEBP__QUANT_Y2_AC, JEBP__QUANT_UV_DC, JEBP__QUANT_UV_AC, JEBP__QUANT_NB } jebp__quant_type_t; typedef struct jebp__quants_t { jebp_short v[JEBP__QUANT_NB]; } jebp__quants_t; typedef struct jebp__segment_t { jebp__quants_t quants; jebp_short filter_strength; } jebp__segment_t; typedef enum jebp__block_type_t { JEBP__BLOCK_Y1, // Y beginning at 1 JEBP__BLOCK_Y2, // WHT block of DC values JEBP__BLOCK_UV, JEBP__BLOCK_Y0, // Y beginning at 0 JEBP__NB_BLOCK_TYPES } jebp__block_type_t; typedef enum jebp__token_t { JEBP__TOKEN_COEFF0, JEBP__TOKEN_COEFF1, JEBP__TOKEN_COEFF2, JEBP__TOKEN_COEFF3, JEBP__TOKEN_COEFF4, JEBP__TOKEN_EXTRA1, JEBP__TOKEN_EXTRA2, JEBP__TOKEN_EXTRA3, JEBP__TOKEN_EXTRA4, JEBP__TOKEN_EXTRA5, JEBP__TOKEN_EXTRA6, JEBP__TOKEN_EOB, JEBP__NB_TOKENS, JEBP__NB_EXTRA_TOKENS = JEBP__TOKEN_EOB - JEBP__TOKEN_EXTRA1 } jebp__token_t; typedef struct jebp__vp8_header_t { jebp_int bec_size; jebp__segment_type_t segment_type; jebp_int skip_prob; jebp_int abs_segments; jebp__segment_t segments[JEBP__NB_SEGMENTS]; jebp_ubyte segment_probs[JEBP__NB_PROBS(JEBP__NB_SEGMENTS)]; jebp_int simple_filter; jebp_short filter_strength; jebp_short filter_sharpness; jebp_ubyte token_probs[JEBP__NB_BLOCK_TYPES][JEBP__NB_COEFF_BANDS] [JEBP__NB_TOKEN_COMPLEXITIES] [JEBP__NB_PROBS(JEBP__NB_TOKENS)]; } jebp__vp8_header_t; static const jebp_short jebp__dc_quant_table[JEBP__NB_QUANT_INDEXES]; static const jebp_short jebp__ac_quant_table[JEBP__NB_QUANT_INDEXES]; static const jebp_ubyte jebp__default_token_probs[JEBP__NB_BLOCK_TYPES][JEBP__NB_COEFF_BANDS] [JEBP__NB_TOKEN_COMPLEXITIES] [JEBP__NB_PROBS(JEBP__NB_TOKENS)]; static const jebp_ubyte jebp__update_token_probs[JEBP__NB_BLOCK_TYPES][JEBP__NB_COEFF_BANDS] [JEBP__NB_TOKEN_COMPLEXITIES] [JEBP__NB_PROBS(JEBP__NB_TOKENS)]; static void jebp__init_vp8_header(jebp__vp8_header_t *hdr) { JEBP__CLEAR(hdr, sizeof(jebp__vp8_header_t)); hdr->segment_type = JEBP__SEGMENT_NONE; hdr->abs_segments = 1; memset(hdr->segment_probs, 255, sizeof(hdr->segment_probs)); memcpy(hdr->token_probs, jebp__default_token_probs, sizeof(hdr->token_probs)); } static jebp_error_t jebp__read_segment_header(jebp__vp8_header_t *hdr, jebp__bec_reader_t *bec) { jebp_error_t err = JEBP_OK; if (!jebp__read_flag(bec, &err)) { // no segments return err; } hdr->segment_type = jebp__read_flag(bec, &err); if (jebp__read_flag(bec, &err)) { // update segment data hdr->abs_segments = jebp__read_flag(bec, &err); for (jebp_int i = 0; i < JEBP__NB_SEGMENTS; i += 1) { if (jebp__read_flag(bec, &err)) { hdr->segments[i].quants.v[JEBP__QUANT_Y_AC] = jebp__read_bec_int(bec, 7, &err); } } for (jebp_int i = 0; i < JEBP__NB_SEGMENTS; i += 1) { if (jebp__read_flag(bec, &err)) { hdr->segments[i].filter_strength = jebp__read_bec_int(bec, 6, &err); } } } if (hdr->segment_type == JEBP__SEGMENT_ID) { for (jebp_int i = 0; i < JEBP__NB_PROBS(JEBP__NB_SEGMENTS); i += 1) { if (jebp__read_flag(bec, &err)) { hdr->segment_probs[i] = jebp__read_bec_uint(bec, 8, &err); } } } return err; } static jebp_error_t jebp__read_filter_header(jebp__vp8_header_t *hdr, jebp__bec_reader_t *bec) { jebp_error_t err = JEBP_OK; hdr->simple_filter = jebp__read_flag(bec, &err); hdr->filter_strength = jebp__read_bec_uint(bec, 6, &err); hdr->filter_sharpness = jebp__read_bec_uint(bec, 3, &err); if (jebp__read_flag(bec, &err)) { // TODO: support filter adjustments return jebp__error(&err, JEBP_ERROR_NOSUP); } return err; } static void jebp__update_quants(jebp__quants_t *quants, jebp__quants_t *deltas) { jebp_short dy_ac = deltas->v[JEBP__QUANT_Y_AC]; jebp_short dy_dc = deltas->v[JEBP__QUANT_Y_DC]; jebp_short dy2_dc = deltas->v[JEBP__QUANT_Y2_DC]; jebp_short dy2_ac = deltas->v[JEBP__QUANT_Y2_AC]; jebp_short duv_ac = deltas->v[JEBP__QUANT_UV_AC]; jebp_short duv_dc = deltas->v[JEBP__QUANT_UV_DC]; quants->v[JEBP__QUANT_Y_DC] = jebp__dc_quant_table[JEBP__CLAMP_QUANT(dy_ac + dy_dc)]; quants->v[JEBP__QUANT_Y_AC] = jebp__ac_quant_table[JEBP__CLAMP_QUANT(dy_ac)]; quants->v[JEBP__QUANT_Y2_DC] = jebp__dc_quant_table[JEBP__CLAMP_QUANT(dy_ac + dy2_dc)]; quants->v[JEBP__QUANT_Y2_DC] *= 2; quants->v[JEBP__QUANT_Y2_AC] = jebp__ac_quant_table[JEBP__CLAMP_QUANT(dy_ac + dy2_ac)]; quants->v[JEBP__QUANT_Y2_AC] = JEBP__MAX(quants->v[JEBP__QUANT_Y2_AC] * 155 / 100, 8); quants->v[JEBP__QUANT_UV_DC] = jebp__dc_quant_table[JEBP__CLAMP_QUANT(dy_ac + duv_dc)]; quants->v[JEBP__QUANT_UV_DC] = JEBP__MIN(quants->v[JEBP__QUANT_UV_DC], 132); quants->v[JEBP__QUANT_UV_AC] = jebp__ac_quant_table[JEBP__CLAMP_QUANT(dy_ac + duv_ac)]; } static jebp_error_t jebp__read_quant_header(jebp__vp8_header_t *hdr, jebp__bec_reader_t *bec) { jebp_error_t err = JEBP_OK; jebp__quants_t deltas; jebp_int y_ac = jebp__read_bec_uint(bec, 7, &err); deltas.v[JEBP__QUANT_Y_DC] = jebp__read_flag(bec, &err) ? jebp__read_bec_int(bec, 4, &err) : 0; deltas.v[JEBP__QUANT_Y2_DC] = jebp__read_flag(bec, &err) ? jebp__read_bec_int(bec, 4, &err) : 0; deltas.v[JEBP__QUANT_Y2_AC] = jebp__read_flag(bec, &err) ? jebp__read_bec_int(bec, 4, &err) : 0; deltas.v[JEBP__QUANT_UV_DC] = jebp__read_flag(bec, &err) ? jebp__read_bec_int(bec, 4, &err) : 0; deltas.v[JEBP__QUANT_UV_AC] = jebp__read_flag(bec, &err) ? jebp__read_bec_int(bec, 4, &err) : 0; if (hdr->segment_type == JEBP__SEGMENT_NONE) { deltas.v[JEBP__QUANT_Y_AC] = y_ac; jebp__update_quants(&hdr->segments->quants, &deltas); return err; } if (hdr->abs_segments) { y_ac = 0; } for (jebp_int i = 0; i < JEBP__NB_SEGMENTS; i += 1) { jebp__quants_t *quants = &hdr->segments[i].quants; deltas.v[JEBP__QUANT_Y_AC] = y_ac + quants->v[JEBP__QUANT_Y_AC]; jebp__update_quants(quants, &deltas); } return err; } static jebp_error_t jebp__read_token_header(jebp__vp8_header_t *hdr, jebp__bec_reader_t *bec) { jebp_error_t err = JEBP_OK; jebp_ubyte *probs = hdr->token_probs[0][0][0]; const jebp_ubyte *update_probs = jebp__update_token_probs[0][0][0]; for (size_t i = 0; i < sizeof(jebp__update_token_probs); i += 1) { if (jebp__read_bool(bec, update_probs[i], &err)) { probs[i] = jebp__read_bec_uint(bec, 8, &err); } } if (jebp__read_flag(bec, &err)) { hdr->skip_prob = jebp__read_bec_uint(bec, 8, &err); } else { hdr->skip_prob = -1; } return err; } static jebp_error_t jebp__read_bec_header(jebp__vp8_header_t *hdr, jebp__bec_reader_t *bec) { jebp_error_t err = JEBP_OK; if (jebp__read_flag(bec, &err)) { // pixel format must be YCbCr return jebp__error(&err, JEBP_ERROR_NOSUP); } jebp__read_flag(bec, &err); // we always clamp pixels if (err != JEBP_OK) { return err; } if ((err = jebp__read_segment_header(hdr, bec)) != JEBP_OK) { return err; } if ((err = jebp__read_filter_header(hdr, bec)) != JEBP_OK) { return err; } if (jebp__read_bec_uint(bec, 2, &err) > 0 || err != JEBP_OK) { // TODO: support data partitions return jebp__error(&err, JEBP_ERROR_NOSUP); } if ((err = jebp__read_quant_header(hdr, bec)) != JEBP_OK) { return err; } jebp__read_flag(bec, &err); // there is only one frame so probabilities are // never used for later frames if (err != JEBP_OK) { return err; } if ((err = jebp__read_token_header(hdr, bec)) != JEBP_OK) { return err; } return JEBP_OK; } /** * Macroblock header */ #define JEBP__BLOCK_BITS 2 #define JEBP__BLOCK_SIZE (1 << JEBP__BLOCK_BITS) // 4 #define JEBP__NB_BLOCK_COEFFS (JEBP__BLOCK_SIZE * JEBP__BLOCK_SIZE) // 16 #define JEBP__Y_BITS 2 #define JEBP__Y_SIZE (1 << JEBP__Y_BITS) // 4 #define JEBP__NB_Y_BLOCKS (JEBP__Y_SIZE * JEBP__Y_SIZE) // 16 #define JEBP__Y_PIXEL_BITS (JEBP__Y_BITS + JEBP__BLOCK_BITS) // 4 #define JEBP__Y_PIXEL_SIZE (1 << JEBP__Y_PIXEL_BITS) // 16 #define JEBP__UV_BITS 1 #define JEBP__UV_SIZE (1 << JEBP__UV_BITS) // 2 #define JEBP__NB_UV_BLOCKS (JEBP__UV_SIZE * JEBP__UV_SIZE) // 4 #define JEBP__UV_PIXEL_BITS (JEBP__UV_BITS + JEBP__BLOCK_BITS) // 3 #define JEBP__UV_PIXEL_SIZE (1 << JEBP__UV_PIXEL_BITS) // 8 typedef enum jebp__y_flags_t { JEBP__B_PRED_MASK = 0x7f, JEBP__Y_NONZERO = 0x80 } jebp__y_flags_t; typedef enum jebp__uv_flags_t { JEBP__U_NONZERO = 0x01, JEBP__V_NONZERO = 0x02 } jebp__uv_flags_t; typedef enum jebp__vp8_pred_type_t { JEBP__VP8_PRED_DC, // Predict DC only JEBP__VP8_PRED_TM, // "True-Motion" JEBP__VP8_PRED_V, // Vertical JEBP__VP8_PRED_H, // Horizontal JEBP__VP8_PRED_DC_L, // Left-only DC JEBP__VP8_PRED_DC_T, // Top-only DC JEBP__VP8_PRED_B, // Per-block prediction JEBP__NB_Y_PRED_TYPES, JEBP__NB_UV_PRED_TYPES = JEBP__VP8_PRED_B } jebp__vp8_pred_type_t; typedef enum jebp__b_pred_type_t { JEBP__B_PRED_DC, // Predict DC only JEBP__B_PRED_TM, // "True-motion" JEBP__B_PRED_VE, // Vertical (S) JEBP__B_PRED_HE, // Horizontal (E) JEBP__B_PRED_LD, // Left-down (SW) JEBP__B_PRED_RD, // Right-down (SE) JEBP__B_PRED_VR, // Vertical-right (SSE) JEBP__B_PRED_VL, // Vertical-left (SSW) JEBP__B_PRED_HD, // Horizontal-down (ESE) JEBP__B_PRED_HU, // Horizontal-up (ENE) JEBP__NB_B_PRED_TYPES } jebp__b_pred_type_t; typedef struct jebp__macro_state_t { jebp_ubyte y_flags[JEBP__Y_SIZE]; // jebp__y_flags_t | jebp__b_pred_type_t jebp_ubyte uv_flags[JEBP__UV_SIZE]; // jebp__uv_flags_t jebp_ubyte y2_flags; // jebp__y_flags_t } jebp__macro_state_t; typedef struct jebp__macro_state_pair_t { jebp__macro_state_t *top; jebp__macro_state_t *left; } jebp__macro_state_pair_t; typedef struct jebp__macro_header_t { jebp__vp8_header_t *vp8; jebp_int x; jebp_int y; jebp__segment_t *segment; jebp__vp8_pred_type_t y_pred; jebp__vp8_pred_type_t uv_pred; jebp_ubyte skip_flag; jebp__b_pred_type_t b_preds[JEBP__NB_Y_BLOCKS]; } jebp__macro_header_t; static const jebp_byte jebp__segment_tree[JEBP__NB_TREE(JEBP__NB_SEGMENTS)]; static const jebp_byte jebp__y_pred_tree[JEBP__NB_TREE(JEBP__NB_Y_PRED_TYPES)]; static const jebp_ubyte jebp__y_pred_probs[JEBP__NB_PROBS(JEBP__NB_Y_PRED_TYPES)]; static const jebp_byte jebp__b_pred_tree[JEBP__NB_TREE(JEBP__NB_B_PRED_TYPES)]; static const jebp_ubyte jebp__b_pred_probs[JEBP__NB_B_PRED_TYPES][JEBP__NB_B_PRED_TYPES] [JEBP__NB_PROBS(JEBP__NB_B_PRED_TYPES)]; static const jebp_byte jebp__uv_pred_tree[JEBP__NB_TREE(JEBP__NB_UV_PRED_TYPES)]; static const jebp_ubyte jebp__uv_pred_probs[JEBP__NB_PROBS(JEBP__NB_UV_PRED_TYPES)]; static jebp_error_t jebp__read_macro_header(jebp__macro_header_t *hdr, jebp__macro_state_pair_t state, jebp__bec_reader_t *bec) { jebp_error_t err = JEBP_OK; jebp_int segment = 0; if (hdr->vp8->segment_type == JEBP__SEGMENT_ID) { segment = jebp__read_tree(bec, jebp__segment_tree, hdr->vp8->segment_probs, &err); } if (hdr->vp8->skip_prob >= 0) { hdr->skip_flag = jebp__read_bool(bec, hdr->vp8->skip_prob, &err); } else { hdr->skip_flag = 0; } hdr->segment = &hdr->vp8->segments[segment]; hdr->y_pred = jebp__read_tree(bec, jebp__y_pred_tree, jebp__y_pred_probs, &err); jebp__b_pred_type_t b_top[JEBP__Y_SIZE]; jebp__b_pred_type_t b_left[JEBP__Y_SIZE]; for (jebp_int i = 0; i < JEBP__Y_SIZE; i += 1) { if (hdr->y_pred == JEBP__VP8_PRED_B) { // We read out the previous subblock predictions from the state now // to both make the code cleaner and to potentially improve // performance (rather than reading & writing the state for every // subblock) b_top[i] = state.top->y_flags[i] & JEBP__B_PRED_MASK; b_left[i] = state.left->y_flags[i] & JEBP__B_PRED_MASK; } else { // If we're not decoding B prediction subblocks we instead use this // iteration to copy over the fake subblock modes used for the // probabilities which will be written back to the state at the end b_top[i] = (jebp__b_pred_type_t)hdr->y_pred; b_left[i] = (jebp__b_pred_type_t)hdr->y_pred; } } if (hdr->y_pred == JEBP__VP8_PRED_B) { for (jebp_int y = 0; y < JEBP__Y_SIZE; y += 1) { for (jebp_int x = 0; x < JEBP__Y_SIZE; x += 1) { jebp_int i = y * JEBP__Y_SIZE + x; hdr->b_preds[i] = jebp__read_tree( bec, jebp__b_pred_tree, jebp__b_pred_probs[b_top[x]][b_left[y]], &err); b_top[x] = hdr->b_preds[i]; b_left[y] = hdr->b_preds[i]; } } } for (jebp_int i = 0; i < JEBP__Y_SIZE; i += 1) { JEBP__SET_MASK(state.top->y_flags[i], JEBP__B_PRED_MASK, b_top[i]); JEBP__SET_MASK(state.left->y_flags[i], JEBP__B_PRED_MASK, b_left[i]); } hdr->uv_pred = jebp__read_tree(bec, jebp__uv_pred_tree, jebp__uv_pred_probs, &err); return err; } /** * DCT and WHT inversions */ // Utility macros that does 16-bit fixed-point multiplications // Multiplies against cos(pi/8)*sqrt(2) #define JEBP__DCT_COS(x) ((x) + (((x)*20091) >> 16)) // Multiplies against sin(pi/8)*sqrt(2) #define JEBP__DCT_SIN(x) (((x)*35468) >> 16) #if defined(JEBP__SIMD_NEON) JEBP__INLINE int16x8_t jebp__neon_getlo_s16x8(int16x8_t v1, int16x8_t v2) { #ifdef JEBP__SIMD_NEON64 int64x2_t v_lo = vuzp1q_s64(vreinterpretq_s64_s16(v1), vreinterpretq_s64_s16(v2)); return vreinterpretq_s16_s64(v_lo); #else // JEBP__SIMD_NEON64 return vcombine_s16(vget_low_s16(v1), vget_low_s16(v2)); #endif // JEBP__SIMD_NEON64 } JEBP__INLINE int16x8_t jebp__neon_gethi_s16x8(int16x8_t v1, int16x8_t v2) { #ifdef JEBP__SIMD_NEON64 int64x2_t v_hi = vuzp2q_s64(vreinterpretq_s64_s16(v1), vreinterpretq_s64_s16(v2)); return vreinterpretq_s16_s64(v_hi); #else // JEBP__SIMD_NEON64 return vcombine_s16(vget_high_s16(v1), vget_high_s16(v2)); #endif // JEBP__SIMD_NEON64 } JEBP__INLINE int16x8_t jebp__neon_dctcos_s16x8(int16x8_t v_dct) { int16x8_t v_cos = vqdmulhq_n_s16(v_dct, 20091); return vsraq_n_s16(v_dct, v_cos, 1); } JEBP__INLINE int16x8_t jebp__neon_dctsin_s16x8(int16x8_t v_dct) { return vqdmulhq_n_s16(v_dct, 17734); } #endif static void jebp__invert_dct(jebp_short *dct) { #if defined(JEBP__SIMD_NEON) int16x8_t v_sign = vcombine_s16(vdup_n_s16(1), vdup_n_s16(-1)); int16x4x4_t v_dct4; #ifdef JEBP__SIMD_NEON64 int64x2x2_t v_dct64 = vld2q_s64((int64_t *)dct); int16x8_t v_dct0 = vreinterpretq_s16_s64(v_dct64.val[0]); int16x8_t v_dct1 = vreinterpretq_s16_s64(v_dct64.val[1]); #ifndef JEBP__LITTLE_ENDIAN v_dct0 = vrev64q_s16(v_dct0); v_dct1 = vrev64q_s16(v_dct1); #endif // JEBP__LITTLE_ENDIAN #else // JEBP__SIMD_NEON64 v_dct4 = vld1_s16_x4(dct); int16x8_t v_dct0 = vcombine_s16(v_dct4.val[0], v_dct4.val[2]); int16x8_t v_dct1 = vcombine_s16(v_dct4.val[1], v_dct4.val[3]); #endif // JEBP__SIMD_NEON64 // Vertical pass int16x8_t v_lo = jebp__neon_getlo_s16x8(v_dct0, v_dct0); int16x8_t v_hi = jebp__neon_gethi_s16x8(v_dct0, v_dct0); int16x8_t v_t01 = vmlaq_s16(v_lo, v_hi, v_sign); int16x8_t v_cos = jebp__neon_dctcos_s16x8(v_dct1); int16x8_t v_sin = jebp__neon_dctsin_s16x8(v_dct1); v_lo = jebp__neon_getlo_s16x8(v_cos, v_sin); v_hi = jebp__neon_gethi_s16x8(v_sin, v_cos); int16x8_t v_t32 = vmlaq_s16(v_lo, v_hi, v_sign); v_dct0 = vaddq_s16(v_t01, v_t32); v_dct1 = vsubq_s16(v_t01, v_t32); v_dct1 = vextq_s16(v_dct1, v_dct1, 4); // Horizontal pass int16x8x2_t v_dct = vuzpq_s16(v_dct0, v_dct1); int16x8x2_t v_evod = vuzpq_s16(v_dct.val[0], v_dct.val[0]); v_t01 = vmlaq_s16(v_evod.val[0], v_evod.val[1], v_sign); v_cos = jebp__neon_dctcos_s16x8(v_dct.val[1]); v_sin = jebp__neon_dctsin_s16x8(v_dct.val[1]); #ifdef JEBP__SIMD_NEON64 int16x8_t v_even = vuzp1q_s16(v_cos, v_sin); int16x8_t v_odd = vuzp2q_s16(v_sin, v_cos); #else // JEBP__SIMD_NEON64 v_evod = vuzpq_s16(v_cos, v_sin); int16x8_t v_even = v_evod.val[0]; int16x8_t v_odd = vextq_s16(v_evod.val[1], v_evod.val[1], 4); #endif // JEBP__SIMD_NEON64 v_t32 = vmlaq_s16(v_even, v_odd, v_sign); v_dct0 = vaddq_s16(v_t01, v_t32); v_dct1 = vsubq_s16(v_t01, v_t32); // Rounding and store v_dct0 = vrshrq_n_s16(v_dct0, 3); v_dct1 = vrshrq_n_s16(v_dct1, 3); v_dct4.val[0] = vget_low_s16(v_dct0); v_dct4.val[1] = vget_high_s16(v_dct0); // Saves a vext call by rotating it here v_dct4.val[2] = vget_high_s16(v_dct1); v_dct4.val[3] = vget_low_s16(v_dct1); vst4_s16(dct, v_dct4); #else for (jebp_int i = 0; i < JEBP__BLOCK_SIZE; i += 1) { jebp_short *col = &dct[i]; jebp_int t0 = col[0] + col[8]; jebp_int t1 = col[0] - col[8]; jebp_int t2 = JEBP__DCT_SIN(col[4]) - JEBP__DCT_COS(col[12]); jebp_int t3 = JEBP__DCT_COS(col[4]) + JEBP__DCT_SIN(col[12]); col[0] = t0 + t3; col[4] = t1 + t2; col[8] = t1 - t2; col[12] = t0 - t3; } for (jebp_int i = 0; i < JEBP__BLOCK_SIZE; i += 1) { jebp_short *row = &dct[i * JEBP__BLOCK_SIZE]; jebp_int t0 = row[0] + row[2]; jebp_int t1 = row[0] - row[2]; jebp_int t2 = JEBP__DCT_SIN(row[1]) - JEBP__DCT_COS(row[3]); jebp_int t3 = JEBP__DCT_COS(row[1]) + JEBP__DCT_SIN(row[3]); row[0] = JEBP__RSHIFT(t0 + t3, 3); row[1] = JEBP__RSHIFT(t1 + t2, 3); row[2] = JEBP__RSHIFT(t1 - t2, 3); row[3] = JEBP__RSHIFT(t0 - t3, 3); } #endif } static void jebp__invert_wht(jebp_short *wht) { #if defined(JEBP__SIMD_NEON) int16x8_t v_round = vdupq_n_s16(3); int16x8x2_t v_wht = vld1q_s16_x2(wht); // Vertical pass int16x8_t v_wht0 = v_wht.val[0]; int16x8_t v_wht1 = vextq_s16(v_wht.val[1], v_wht.val[1], 4); int16x8_t v_t01 = vaddq_s16(v_wht0, v_wht1); int16x8_t v_t32 = vsubq_s16(v_wht0, v_wht1); int16x8_t v_t03 = jebp__neon_getlo_s16x8(v_t01, v_t32); int16x8_t v_t12 = jebp__neon_gethi_s16x8(v_t01, v_t32); int32x4_t v_wht0_32 = vreinterpretq_s32_s16(vaddq_s16(v_t03, v_t12)); int32x4_t v_wht1_32 = vreinterpretq_s32_s16(vsubq_s16(v_t03, v_t12)); // Horizontal pass int32x4x2_t v_wht32 = vuzpq_s32(v_wht0_32, v_wht1_32); v_wht0 = vreinterpretq_s16_s32(v_wht32.val[0]); v_wht1 = vrev32q_s16(vreinterpretq_s16_s32(v_wht32.val[1])); v_t01 = vaddq_s16(v_wht0, v_wht1); v_t32 = vsubq_s16(v_wht0, v_wht1); int16x8x2_t v_tmp = vuzpq_s16(v_t01, v_t32); v_wht0 = vaddq_s16(v_tmp.val[0], v_tmp.val[1]); v_wht1 = vsubq_s16(v_tmp.val[0], v_tmp.val[1]); // Rounding and store v_wht0 = vaddq_s16(v_wht0, v_round); v_wht1 = vaddq_s16(v_wht1, v_round); v_wht0 = vshrq_n_s16(v_wht0, 3); v_wht1 = vshrq_n_s16(v_wht1, 3); int16x4x4_t v_wht4; v_wht4.val[0] = vget_low_s16(v_wht0); v_wht4.val[1] = vget_high_s16(v_wht0); v_wht4.val[2] = vget_low_s16(v_wht1); v_wht4.val[3] = vget_high_s16(v_wht1); vst4_s16(wht, v_wht4); #else for (jebp_int i = 0; i < JEBP__BLOCK_SIZE; i += 1) { jebp_short *col = &wht[i]; jebp_int t0 = col[0] + col[12]; jebp_int t1 = col[4] + col[8]; jebp_int t2 = col[4] - col[8]; jebp_int t3 = col[0] - col[12]; col[0] = t0 + t1; col[4] = t2 + t3; col[8] = t0 - t1; col[12] = t3 - t2; } for (jebp_int i = 0; i < JEBP__BLOCK_SIZE; i += 1) { jebp_short *row = &wht[i * JEBP__BLOCK_SIZE]; jebp_int t0 = row[0] + row[3]; jebp_int t1 = row[1] + row[2]; jebp_int t2 = row[1] - row[2]; jebp_int t3 = row[0] - row[3]; // These use a different rounding value and thus can't use RSHIFT row[0] = (t0 + t1 + 3) >> 3; row[1] = (t2 + t3 + 3) >> 3; row[2] = (t0 - t1 + 3) >> 3; row[3] = (t3 - t2 + 3) >> 3; } #endif } /** * VP8 predictions */ typedef void (*jebp__vp8_pred_t)(jebp_ubyte *pred, jebp_int stride); typedef void (*jebp__b_pred_t)(jebp_ubyte *pred, jebp_int stride, jebp_ubyte *tr); // UV predictions static void jebp__uv_pred_fill(jebp_ubyte *pred, jebp_int stride, jebp_ubyte value) { for (jebp_int y = 0; y < JEBP__UV_PIXEL_SIZE; y += 1) { jebp_ubyte *row = &pred[y * stride]; memset(row, value, JEBP__UV_PIXEL_SIZE); } } static jebp_int jebp__uv_pred_sum_l(jebp_ubyte *pred, jebp_int stride) { jebp_int sum = 0; for (jebp_int i = 0; i < JEBP__UV_PIXEL_SIZE; i += 1) { jebp_ubyte *row = &pred[i * stride]; sum += row[-1]; } return sum; } static jebp_int jebp__uv_pred_sum_t(jebp_ubyte *pred, jebp_int stride) { jebp_ubyte *top = &pred[-stride]; #if defined(JEBP__SIMD_NEON) uint8x8_t v_top = vld1_u8(top); #ifdef JEBP__SIMD_NEON64 return vaddlv_u8(v_top); #else // JEBP__SIMD_NEON64 uint16x4_t v_top4 = vpaddl_u8(v_top); uint16x4_t v_top2 = vpadd_u16(v_top4, v_top4); uint16x4_t v_top1 = vpadd_u16(v_top2, v_top2); return vget_lane_u16(v_top1, 0); #endif // JEBP__SIMD_NEON64 #else jebp_int sum = 0; for (jebp_int i = 0; i < JEBP__UV_PIXEL_SIZE; i += 1) { sum += top[i]; } return sum; #endif } static void jebp__uv_pred_dc(jebp_ubyte *pred, jebp_int stride) { jebp_int sum = jebp__uv_pred_sum_t(pred, stride) + jebp__uv_pred_sum_l(pred, stride); jebp_ubyte dc = JEBP__RSHIFT(sum, 4); jebp__uv_pred_fill(pred, stride, dc); } // For handling DC prediction on top and left macroblocks static void jebp__uv_pred_dc_l(jebp_ubyte *pred, jebp_int stride) { jebp_int sum = jebp__uv_pred_sum_l(pred, stride); jebp_ubyte dc = JEBP__RSHIFT(sum, 3); jebp__uv_pred_fill(pred, stride, dc); } static void jebp__uv_pred_dc_t(jebp_ubyte *pred, jebp_int stride) { jebp_int sum = jebp__uv_pred_sum_t(pred, stride); jebp_ubyte dc = JEBP__RSHIFT(sum, 3); jebp__uv_pred_fill(pred, stride, dc); } static void jebp__uv_pred_tm(jebp_ubyte *pred, jebp_int stride) { jebp_ubyte *top = &pred[-stride]; #if defined(JEBP__SIMD_NEON) uint8x8_t v_toplo = vld1_u8(top); uint8x16_t v_top = vcombine_u8(v_toplo, v_toplo); uint8x16_t v_tl = vld1q_dup_u8(&top[-1]); uint8x16_t v_diff = vabdq_u8(v_top, v_tl); uint8x16_t v_neg = vcltq_u8(v_top, v_tl); for (jebp_int y = 0; y < JEBP__UV_PIXEL_SIZE; y += 2) { jebp_ubyte *rowlo = &pred[(y + 0) * stride]; jebp_ubyte *rowhi = &pred[(y + 1) * stride]; uint8x16_t v_left = vcombine_u8(vld1_dup_u8(&rowlo[-1]), vld1_dup_u8(&rowhi[-1])); uint8x16_t v_add = vqaddq_u8(v_left, v_diff); uint8x16_t v_sub = vqsubq_u8(v_left, v_diff); uint8x16_t v_row = vbslq_u8(v_neg, v_sub, v_add); vst1_u8(rowlo, vget_low_u8(v_row)); vst1_u8(rowhi, vget_high_u8(v_row)); } #else for (jebp_int y = 0; y < JEBP__UV_PIXEL_SIZE; y += 1) { jebp_ubyte *row = &pred[y * stride]; jebp_int diff = row[-1] - top[-1]; for (jebp_int x = 0; x < JEBP__UV_PIXEL_SIZE; x += 1) { row[x] = JEBP__CLAMP_UBYTE(diff + top[x]); } } #endif } static void jebp__uv_pred_v(jebp_ubyte *pred, jebp_int stride) { // This might look dumb but on most compilers this prevents repetive loads // TODO: msvc compiling for ARM still struggles with this but eh jebp_ubyte top[JEBP__UV_PIXEL_SIZE]; memcpy(top, &pred[-stride], JEBP__UV_PIXEL_SIZE); for (jebp_int y = 0; y < JEBP__UV_PIXEL_SIZE; y += 1) { jebp_ubyte *row = &pred[y * stride]; memcpy(row, top, JEBP__UV_PIXEL_SIZE); } } static void jebp__uv_pred_h(jebp_ubyte *pred, jebp_int stride) { for (jebp_int y = 0; y < JEBP__UV_PIXEL_SIZE; y += 1) { jebp_ubyte *row = &pred[y * stride]; memset(row, row[-1], JEBP__UV_PIXEL_SIZE); } } // Y predictions static void jebp__y_pred_fill(jebp_ubyte *pred, jebp_int stride, jebp_ubyte value) { for (jebp_int y = 0; y < JEBP__Y_PIXEL_SIZE; y += 1) { jebp_ubyte *row = &pred[y * stride]; memset(row, value, JEBP__Y_PIXEL_SIZE); } } static jebp_int jebp__y_pred_sum_l(jebp_ubyte *pred, jebp_int stride) { jebp_int sum = 0; for (jebp_int i = 0; i < JEBP__Y_PIXEL_SIZE; i += 1) { jebp_ubyte *row = &pred[i * stride]; sum += row[-1]; } return sum; } static jebp_int jebp__y_pred_sum_t(jebp_ubyte *pred, jebp_int stride) { jebp_ubyte *top = &pred[-stride]; #if defined(JEBP__SIMD_NEON) uint8x16_t v_top = vld1q_u8(top); #ifdef JEBP__SIMD_NEON64 return vaddlvq_u8(v_top); #else // JEBP__SIMD_NEON64 uint16x8_t v_top8 = vaddl_u8(vget_low_u8(v_top), vget_high_u8(v_top)); uint16x4_t v_top4 = vadd_u16(vget_low_u16(v_top8), vget_high_u16(v_top8)); uint16x4_t v_top2 = vpadd_u16(v_top4, v_top4); uint16x4_t v_top1 = vpadd_u16(v_top2, v_top2); return vget_lane_u16(v_top1, 0); #endif // JEBP__SIMD_NEON64 #else jebp_int sum = 0; for (jebp_int i = 0; i < JEBP__Y_PIXEL_SIZE; i += 1) { sum += top[i]; } return sum; #endif } static void jebp__y_pred_dc(jebp_ubyte *pred, jebp_int stride) { jebp_int sum = jebp__y_pred_sum_t(pred, stride) + jebp__y_pred_sum_l(pred, stride); jebp_ubyte dc = JEBP__RSHIFT(sum, 5); jebp__y_pred_fill(pred, stride, dc); } static void jebp__y_pred_dc_l(jebp_ubyte *pred, jebp_int stride) { jebp_int sum = jebp__y_pred_sum_l(pred, stride); jebp_ubyte dc = JEBP__RSHIFT(sum, 4); jebp__y_pred_fill(pred, stride, dc); } static void jebp__y_pred_dc_t(jebp_ubyte *pred, jebp_int stride) { jebp_int sum = jebp__y_pred_sum_t(pred, stride); jebp_ubyte dc = JEBP__RSHIFT(sum, 4); jebp__y_pred_fill(pred, stride, dc); } static void jebp__y_pred_tm(jebp_ubyte *pred, jebp_int stride) { jebp_ubyte *top = &pred[-stride]; #if defined(JEBP__SIMD_NEON) uint8x16_t v_top = vld1q_u8(top); uint8x16_t v_tl = vld1q_dup_u8(&top[-1]); uint8x16_t v_diff = vabdq_u8(v_top, v_tl); uint8x16_t v_neg = vcltq_u8(v_top, v_tl); for (jebp_int y = 0; y < JEBP__Y_PIXEL_SIZE; y += 1) { jebp_ubyte *row = &pred[y * stride]; uint8x16_t v_left = vld1q_dup_u8(&row[-1]); uint8x16_t v_add = vqaddq_u8(v_left, v_diff); uint8x16_t v_sub = vqsubq_u8(v_left, v_diff); uint8x16_t v_row = vbslq_u8(v_neg, v_sub, v_add); vst1q_u8(row, v_row); } #else for (jebp_int y = 0; y < JEBP__Y_PIXEL_SIZE; y += 1) { jebp_ubyte *row = &pred[y * stride]; jebp_int diff = row[-1] - top[-1]; for (jebp_int x = 0; x < JEBP__Y_PIXEL_SIZE; x += 1) { row[x] = JEBP__CLAMP_UBYTE(diff + top[x]); } } #endif } static void jebp__y_pred_v(jebp_ubyte *pred, jebp_int stride) { jebp_ubyte top[JEBP__Y_PIXEL_SIZE]; memcpy(top, &pred[-stride], JEBP__Y_PIXEL_SIZE); for (jebp_int y = 0; y < JEBP__Y_PIXEL_SIZE; y += 1) { jebp_ubyte *row = &pred[y * stride]; memcpy(row, top, JEBP__Y_PIXEL_SIZE); } } static void jebp__y_pred_h(jebp_ubyte *pred, jebp_int stride) { for (jebp_int y = 0; y < JEBP__Y_PIXEL_SIZE; y += 1) { jebp_ubyte *row = &pred[y * stride]; memset(row, row[-1], JEBP__Y_PIXEL_SIZE); } } // B predictions static void jebp__b_pred_fill(jebp_ubyte *pred, jebp_int stride, jebp_ubyte value) { memset(&pred[0 * stride], value, JEBP__BLOCK_SIZE); memset(&pred[1 * stride], value, JEBP__BLOCK_SIZE); memset(&pred[2 * stride], value, JEBP__BLOCK_SIZE); memset(&pred[3 * stride], value, JEBP__BLOCK_SIZE); } static void jebp__b_pred_dc(jebp_ubyte *pred, jebp_int stride, jebp_ubyte *tr) { (void)tr; jebp_int sum = 0; jebp_ubyte *top = &pred[-stride]; sum += top[0] + top[1] + top[2] + top[3]; jebp_ubyte *left = &pred[-1]; sum += left[0 * stride] + left[1 * stride] + left[2 * stride] + left[3 * stride]; jebp_ubyte dc = JEBP__RSHIFT(sum, 3); jebp__b_pred_fill(pred, stride, dc); } static void jebp__b_pred_tm(jebp_ubyte *pred, jebp_int stride, jebp_ubyte *tr) { (void)tr; jebp_ubyte *top = &pred[-stride]; #if defined(JEBP__SIMD_NEON) uint8x16_t v_top = vreinterpretq_u8_u32(vld1q_dup_u32((uint32_t *)top)); uint8x16_t v_tl = vld1q_dup_u8(&top[-1]); uint8x16_t v_diff = vabdq_u8(v_top, v_tl); uint8x16_t v_neg = vcltq_u8(v_top, v_tl); uint8x16_t v_left = vdupq_n_u8(0); v_left = vld1q_lane_u8(&pred[0 * stride - 1], v_left, 0); v_left = vld1q_lane_u8(&pred[1 * stride - 1], v_left, 4); v_left = vld1q_lane_u8(&pred[2 * stride - 1], v_left, 8); v_left = vld1q_lane_u8(&pred[3 * stride - 1], v_left, 12); v_left = vreinterpretq_u8_u32( vmulq_n_u32(vreinterpretq_u32_u8(v_left), 0x01010101)); uint8x16_t v_add = vqaddq_u8(v_left, v_diff); uint8x16_t v_sub = vqsubq_u8(v_left, v_diff); uint32x4_t v_row = vreinterpretq_u32_u8(vbslq_u8(v_neg, v_sub, v_add)); vst1q_lane_u32((uint32_t *)&pred[0 * stride], v_row, 0); vst1q_lane_u32((uint32_t *)&pred[1 * stride], v_row, 1); vst1q_lane_u32((uint32_t *)&pred[2 * stride], v_row, 2); vst1q_lane_u32((uint32_t *)&pred[3 * stride], v_row, 3); #else for (jebp_int y = 0; y < JEBP__BLOCK_SIZE; y += 1) { jebp_ubyte *row = &pred[y * stride]; jebp_int diff = row[-1] - top[-1]; row[0] = JEBP__CLAMP_UBYTE(diff + top[0]); row[1] = JEBP__CLAMP_UBYTE(diff + top[1]); row[2] = JEBP__CLAMP_UBYTE(diff + top[2]); row[3] = JEBP__CLAMP_UBYTE(diff + top[3]); } #endif } static void jebp__b_pred_ve(jebp_ubyte *pred, jebp_int stride, jebp_ubyte *tr) { jebp_ubyte *top = &pred[-stride]; jebp_ubyte avg[4]; avg[0] = JEBP__RAVG3(top[-1], top[0], top[1]); avg[1] = JEBP__RAVG3(top[0], top[1], top[2]); avg[2] = JEBP__RAVG3(top[1], top[2], top[3]); avg[3] = JEBP__RAVG3(top[2], top[3], tr[0]); memcpy(&pred[0 * stride], avg, JEBP__BLOCK_SIZE); memcpy(&pred[1 * stride], avg, JEBP__BLOCK_SIZE); memcpy(&pred[2 * stride], avg, JEBP__BLOCK_SIZE); memcpy(&pred[3 * stride], avg, JEBP__BLOCK_SIZE); } static void jebp__b_pred_he(jebp_ubyte *pred, jebp_int stride, jebp_ubyte *tr) { (void)tr; jebp_ubyte *top = &pred[-stride]; jebp_ubyte *r0 = &pred[0 * stride]; jebp_ubyte *r1 = &pred[1 * stride]; jebp_ubyte *r2 = &pred[2 * stride]; jebp_ubyte *r3 = &pred[3 * stride]; memset(r0, JEBP__RAVG3(top[-1], r0[-1], r1[-1]), JEBP__BLOCK_SIZE); memset(r1, JEBP__RAVG3(r0[-1], r1[-1], r2[-1]), JEBP__BLOCK_SIZE); memset(r2, JEBP__RAVG3(r1[-1], r2[-1], r3[-1]), JEBP__BLOCK_SIZE); memset(r3, JEBP__RAVG3(r2[-1], r3[-1], r3[-1]), JEBP__BLOCK_SIZE); } static void jebp__b_pred_ld(jebp_ubyte *pred, jebp_int stride, jebp_ubyte *tr) { jebp_ubyte *top = &pred[-stride]; jebp_ubyte *r0 = &pred[0 * stride]; jebp_ubyte *r1 = &pred[1 * stride]; jebp_ubyte *r2 = &pred[2 * stride]; jebp_ubyte *r3 = &pred[3 * stride]; r0[0] = JEBP__RAVG3(top[0], top[1], top[2]); r0[1] = r1[0] = JEBP__RAVG3(top[1], top[2], top[3]); r0[2] = r1[1] = r2[0] = JEBP__RAVG3(top[2], top[3], tr[0]); r0[3] = r1[2] = r2[1] = r3[0] = JEBP__RAVG3(top[3], tr[0], tr[1]); r1[3] = r2[2] = r3[1] = JEBP__RAVG3(tr[0], tr[1], tr[2]); r2[3] = r3[2] = JEBP__RAVG3(tr[1], tr[2], tr[3]); r3[3] = JEBP__RAVG3(tr[2], tr[3], tr[3]); } static void jebp__b_pred_rd(jebp_ubyte *pred, jebp_int stride, jebp_ubyte *tr) { (void)tr; jebp_ubyte *top = &pred[-stride]; jebp_ubyte *r0 = &pred[0 * stride]; jebp_ubyte *r1 = &pred[1 * stride]; jebp_ubyte *r2 = &pred[2 * stride]; jebp_ubyte *r3 = &pred[3 * stride]; r3[0] = JEBP__RAVG3(r3[-1], r2[-1], r1[-1]); r2[0] = r3[1] = JEBP__RAVG3(r2[-1], r1[-1], r0[-1]); r1[0] = r2[1] = r3[2] = JEBP__RAVG3(r1[-1], r0[-1], top[-1]); r0[0] = r1[1] = r2[2] = r3[3] = JEBP__RAVG3(r0[-1], top[-1], top[0]); r0[1] = r1[2] = r2[3] = JEBP__RAVG3(top[-1], top[0], top[1]); r0[2] = r1[3] = JEBP__RAVG3(top[0], top[1], top[2]); r0[3] = JEBP__RAVG3(top[1], top[2], top[3]); } static void jebp__b_pred_vr(jebp_ubyte *pred, jebp_int stride, jebp_ubyte *tr) { (void)tr; jebp_ubyte *top = &pred[-stride]; jebp_ubyte *r0 = &pred[0 * stride]; jebp_ubyte *r1 = &pred[1 * stride]; jebp_ubyte *r2 = &pred[2 * stride]; jebp_ubyte *r3 = &pred[3 * stride]; r3[0] = JEBP__RAVG3(r2[-1], r1[-1], r0[-1]); r2[0] = JEBP__RAVG3(r1[-1], r0[-1], top[-1]); r1[0] = r3[1] = JEBP__RAVG3(r0[-1], top[-1], top[0]); r0[0] = r2[1] = JEBP__RAVG(top[-1], top[0]); r1[1] = r3[2] = JEBP__RAVG3(top[-1], top[0], top[1]); r0[1] = r2[2] = JEBP__RAVG(top[0], top[1]); r1[2] = r3[3] = JEBP__RAVG3(top[0], top[1], top[2]); r0[2] = r2[3] = JEBP__RAVG(top[1], top[2]); r1[3] = JEBP__RAVG3(top[1], top[2], top[3]); r0[3] = JEBP__RAVG(top[2], top[3]); } static void jebp__b_pred_vl(jebp_ubyte *pred, jebp_int stride, jebp_ubyte *tr) { jebp_ubyte *top = &pred[-stride]; jebp_ubyte *r0 = &pred[0 * stride]; jebp_ubyte *r1 = &pred[1 * stride]; jebp_ubyte *r2 = &pred[2 * stride]; jebp_ubyte *r3 = &pred[3 * stride]; r0[0] = JEBP__RAVG(top[0], top[1]); r1[0] = JEBP__RAVG3(top[0], top[1], top[2]); r0[1] = r2[0] = JEBP__RAVG(top[1], top[2]); r1[1] = r3[0] = JEBP__RAVG3(top[1], top[2], top[3]); r0[2] = r2[1] = JEBP__RAVG(top[2], top[3]); r1[2] = r3[1] = JEBP__RAVG3(top[2], top[3], tr[0]); r0[3] = r2[2] = JEBP__RAVG(top[3], tr[0]); r1[3] = r3[2] = JEBP__RAVG3(top[3], tr[0], tr[1]); // These last two do not follow the same pattern r2[3] = JEBP__RAVG3(tr[0], tr[1], tr[2]); r3[3] = JEBP__RAVG3(tr[1], tr[2], tr[3]); } static void jebp__b_pred_hd(jebp_ubyte *pred, jebp_int stride, jebp_ubyte *tr) { (void)tr; jebp_ubyte *top = &pred[-stride]; jebp_ubyte *r0 = &pred[0 * stride]; jebp_ubyte *r1 = &pred[1 * stride]; jebp_ubyte *r2 = &pred[2 * stride]; jebp_ubyte *r3 = &pred[3 * stride]; r3[0] = JEBP__RAVG(r3[-1], r2[-1]); r3[1] = JEBP__RAVG3(r3[-1], r2[-1], r1[-1]); r2[0] = r3[2] = JEBP__RAVG(r2[-1], r1[-1]); r2[1] = r3[3] = JEBP__RAVG3(r2[-1], r1[-1], r0[-1]); r1[0] = r2[2] = JEBP__RAVG(r1[-1], r0[-1]); r1[1] = r2[3] = JEBP__RAVG3(r1[-1], r0[-1], top[-1]); r0[0] = r1[2] = JEBP__RAVG(r0[-1], top[-1]); r0[1] = r1[3] = JEBP__RAVG3(r0[-1], top[-1], top[0]); r0[2] = JEBP__RAVG3(top[-1], top[0], top[1]); r0[3] = JEBP__RAVG3(top[0], top[1], top[2]); } static void jebp__b_pred_hu(jebp_ubyte *pred, jebp_int stride, jebp_ubyte *tr) { (void)tr; jebp_ubyte *r0 = &pred[0 * stride]; jebp_ubyte *r1 = &pred[1 * stride]; jebp_ubyte *r2 = &pred[2 * stride]; jebp_ubyte *r3 = &pred[3 * stride]; r0[0] = JEBP__RAVG(r0[-1], r1[-1]); r0[1] = JEBP__RAVG3(r0[-1], r1[-1], r2[-1]); r1[0] = r0[2] = JEBP__RAVG(r1[-1], r2[-1]); r1[1] = r0[3] = JEBP__RAVG3(r1[-1], r2[-1], r3[-1]); r2[0] = r1[2] = JEBP__RAVG(r2[-1], r3[-1]); r2[1] = r1[3] = JEBP__RAVG3(r2[-1], r3[-1], r3[-1]); // The rest cannot be predicted well r2[2] = r2[3] = r3[0] = r3[1] = r3[2] = r3[3] = r3[-1]; } static const jebp__vp8_pred_t jebp__uv_preds[JEBP__NB_UV_PRED_TYPES] = { jebp__uv_pred_dc, jebp__uv_pred_tm, jebp__uv_pred_v, jebp__uv_pred_h, jebp__uv_pred_dc_l, jebp__uv_pred_dc_t}; // Using 'nb. UV pred types' since we don't include B-pred in this list static const jebp__vp8_pred_t jebp__y_preds[JEBP__NB_UV_PRED_TYPES] = { jebp__y_pred_dc, jebp__y_pred_tm, jebp__y_pred_v, jebp__y_pred_h, jebp__y_pred_dc_l, jebp__y_pred_dc_t}; static const jebp__b_pred_t jebp__b_preds[JEBP__NB_B_PRED_TYPES] = { jebp__b_pred_dc, jebp__b_pred_tm, jebp__b_pred_ve, jebp__b_pred_he, jebp__b_pred_ld, jebp__b_pred_rd, jebp__b_pred_vr, jebp__b_pred_vl, jebp__b_pred_hd, jebp__b_pred_hu}; /** * Macroblock data */ #define JEBP__MAX_TOKEN_EXTRA 11 #define JEBP__GET_Y_NONZERO(state, index) \ (((state)->y_flags[index] & JEBP__Y_NONZERO) != 0) #define JEBP__GET_U_NONZERO(state, index) \ (((state)->uv_flags[index] & JEBP__U_NONZERO) != 0) #define JEBP__GET_V_NONZERO(state, index) \ (((state)->uv_flags[index] & JEBP__V_NONZERO) != 0) #define JEBP__GET_Y2_NONZERO(state) (((state)->y2_flags & JEBP__Y_NONZERO) != 0) typedef struct jebp__token_extra_t { jebp_byte offset; jebp_ubyte probs[JEBP__MAX_TOKEN_EXTRA + 1]; } jebp__token_extra_t; static const jebp_byte jebp__coeff_bands[JEBP__NB_BLOCK_COEFFS]; static const jebp_byte jebp__coeff_order[JEBP__NB_BLOCK_COEFFS]; static const jebp_byte jebp__token_tree[JEBP__NB_TREE(JEBP__NB_TOKENS - 1)]; static const jebp__token_extra_t jebp__token_extra[JEBP__NB_EXTRA_TOKENS]; static jebp__vp8_pred_type_t jebp__vp8_pred_type(jebp__macro_header_t *hdr, jebp__vp8_pred_type_t pred) { if (pred == JEBP__VP8_PRED_DC) { if (hdr->x > 0 && hdr->y == 0) { return JEBP__VP8_PRED_DC_L; } else if (hdr->x == 0 && hdr->y > 0) { return JEBP__VP8_PRED_DC_T; } } return pred; } JEBP__INLINE jebp_short jebp__read_token_extrabits(jebp__token_t token, jebp__bec_reader_t *bec, jebp_error_t *err) { if (*err != JEBP_OK) { return 0; } const jebp__token_extra_t *extra = &jebp__token_extra[token - JEBP__TOKEN_EXTRA1]; jebp_short value = 0; for (const jebp_ubyte *prob = extra->probs; *prob != 0; prob += 1) { value = (value << 1) | jebp__read_bool(bec, *prob, err); } return value + extra->offset; } // Returns non-zero if it contains atleast 1 non-zero token static jebp_int jebp__read_dct(jebp__macro_header_t *hdr, jebp_short *dct, jebp__block_type_t type, jebp_int complex, jebp__bec_reader_t *bec, jebp_error_t *err) { if (*err != JEBP_OK) { return 0; } if (hdr->skip_flag) { return 0; } jebp_int coeff = type == JEBP__BLOCK_Y1 ? 1 : 0; jebp__quants_t *quants = &hdr->segment->quants; jebp_short *dcac; switch (type) { case JEBP__BLOCK_Y2: dcac = &quants->v[JEBP__QUANT_Y2_DC]; break; case JEBP__BLOCK_UV: dcac = &quants->v[JEBP__QUANT_UV_DC]; break; default: dcac = &quants->v[JEBP__QUANT_Y_DC]; break; } // The initial quantizer is DC if starting at 0, or AC for Y1 blocks jebp_short quant = dcac[coeff]; jebp_ubyte(*token_probs)[JEBP__NB_TOKEN_COMPLEXITIES] [JEBP__NB_PROBS(JEBP__NB_TOKENS)] = hdr->vp8->token_probs[type]; jebp_ubyte *probs = token_probs[jebp__coeff_bands[coeff]][complex]; if (!jebp__read_bool(bec, probs[0], err)) { // First token is EOB, making sure not to clear the first one if the // type is Y1 JEBP__CLEAR(&dct[coeff], (JEBP__NB_BLOCK_COEFFS - coeff) * sizeof(jebp_short)); return 0; } for (;;) { jebp__token_t token = jebp__read_tree(bec, jebp__token_tree, &probs[1], err); if (token == JEBP__TOKEN_COEFF0) { // If the token is 0, there is no negative flag, the next complexity // is 0, and we skip the EOB reading. dct[jebp__coeff_order[coeff]] = 0; coeff += 1; if (coeff >= JEBP__NB_BLOCK_COEFFS) { break; } quant = dcac[1]; probs = token_probs[jebp__coeff_bands[coeff]][0]; } else { jebp_short value; complex = 2; if (token == JEBP__TOKEN_COEFF1) { // 1 has a complexity of 1 value = 1; complex = 1; } else if (token < JEBP__TOKEN_EXTRA1) { value = token - JEBP__TOKEN_COEFF0; } else { value = jebp__read_token_extrabits(token, bec, err); } if (jebp__read_flag(bec, err)) { // Negative value value = -value; } value *= quant; dct[jebp__coeff_order[coeff]] = value; coeff += 1; if (coeff >= JEBP__NB_BLOCK_COEFFS) { break; } quant = dcac[1]; probs = token_probs[jebp__coeff_bands[coeff]][complex]; if (!jebp__read_bool(bec, probs[0], err)) { // EOB token break; } } } // Fill the rest after an EOB with 0 for (; coeff < JEBP__NB_BLOCK_COEFFS; coeff += 1) { dct[jebp__coeff_order[coeff]] = 0; } return 1; } // TODO: invert and add DCT at the same time static void jebp__sum_pred_dct(jebp_ubyte *pred, jebp_int stride, jebp_short *dct) { #if defined(JEBP__SIMD_NEON) uint16x8x2_t v_dct = vld1q_u16_x2((uint16_t *)dct); uint32x2_t v_pred32 = vcreate_u32(0); for (jebp_int y = 0; y < JEBP__BLOCK_SIZE; y += 2) { uint32_t *rowlo = (uint32_t *)&pred[(y + 0) * stride]; uint32_t *rowhi = (uint32_t *)&pred[(y + 1) * stride]; v_pred32 = vld1_lane_u32(rowlo, v_pred32, 0); v_pred32 = vld1_lane_u32(rowhi, v_pred32, 1); uint16x8_t v_pred16 = vaddw_u8(v_dct.val[y / 2], vreinterpret_u8_u32(v_pred32)); uint8x8_t v_pred8 = vqmovun_s16(vreinterpretq_s16_u16(v_pred16)); v_pred32 = vreinterpret_u32_u8(v_pred8); vst1_lane_u32(rowlo, v_pred32, 0); vst1_lane_u32(rowhi, v_pred32, 1); } #else for (jebp_int i = 0; i < JEBP__BLOCK_SIZE; i += 1) { pred[0] = JEBP__CLAMP_UBYTE(pred[0] + dct[0]); pred[1] = JEBP__CLAMP_UBYTE(pred[1] + dct[1]); pred[2] = JEBP__CLAMP_UBYTE(pred[2] + dct[2]); pred[3] = JEBP__CLAMP_UBYTE(pred[3] + dct[3]); pred += stride; dct += JEBP__BLOCK_SIZE; } #endif } static jebp_error_t jebp__read_macro_data(jebp__macro_header_t *hdr, jebp__macro_state_pair_t state, jebp__yuv_image_t *image, jebp__bec_reader_t *bec) { jebp_error_t err = JEBP_OK; JEBP__ALIGN_TYPE(jebp_short dct[JEBP__NB_BLOCK_COEFFS], JEBP__SIMD_ALIGN); JEBP__ALIGN_TYPE(jebp_short wht[JEBP__NB_BLOCK_COEFFS], JEBP__SIMD_ALIGN); jebp__block_type_t y_type = JEBP__BLOCK_Y0; jebp_ubyte *image_y = &image->y[(hdr->y * image->stride + hdr->x) * JEBP__Y_PIXEL_SIZE]; // TODO: optimize 16x DCT inversion/add for non-B predictions if (hdr->y_pred != JEBP__VP8_PRED_B) { y_type = JEBP__BLOCK_Y1; jebp__y_preds[jebp__vp8_pred_type(hdr, hdr->y_pred)](image_y, image->stride); jebp_int complex = JEBP__GET_Y2_NONZERO(state.top) + JEBP__GET_Y2_NONZERO(state.left); jebp_int nonzero = jebp__read_dct(hdr, wht, JEBP__BLOCK_Y2, complex, bec, &err); JEBP__SET_BIT(state.top->y2_flags, JEBP__Y_NONZERO, nonzero); JEBP__SET_BIT(state.left->y2_flags, JEBP__Y_NONZERO, nonzero); jebp__invert_wht(wht); } jebp_int macro_width = image->width / JEBP__Y_PIXEL_SIZE; for (jebp_int y = 0; y < JEBP__Y_SIZE; y += 1) { jebp_int row = y * image->stride; for (jebp_int x = 0; x < JEBP__Y_SIZE; x += 1) { jebp_int i = y * JEBP__Y_SIZE + x; jebp_ubyte *pred = &image_y[(row + x) * JEBP__BLOCK_SIZE]; if (hdr->y_pred == JEBP__VP8_PRED_B) { jebp_ubyte *tr; jebp_ubyte tr_copy[JEBP__BLOCK_SIZE]; if (x < JEBP__Y_SIZE - 1) { // 0th, 1st and 2nd blocks can just reference the top-right // portion tr = &pred[JEBP__BLOCK_SIZE - image->stride]; } else if (hdr->x < macro_width - 1) { // Blocks on the right edge share TR with the top-right // block tr = &image_y[JEBP__Y_PIXEL_SIZE - image->stride]; } else { // Otherwise we duplicate the right-most pixel memset(tr_copy, image_y[JEBP__Y_PIXEL_SIZE - 1 - image->stride], JEBP__BLOCK_SIZE); tr = tr_copy; } jebp__b_preds[hdr->b_preds[i]](pred, image->stride, tr); } else { dct[0] = wht[i]; } jebp_int complex = JEBP__GET_Y_NONZERO(state.top, x) + JEBP__GET_Y_NONZERO(state.left, y); jebp_int nonzero = jebp__read_dct(hdr, dct, y_type, complex, bec, &err); JEBP__SET_BIT(state.top->y_flags[x], JEBP__Y_NONZERO, nonzero); JEBP__SET_BIT(state.left->y_flags[y], JEBP__Y_NONZERO, nonzero); jebp__invert_dct(dct); jebp__sum_pred_dct(pred, image->stride, dct); } } jebp__vp8_pred_t uv_pred = jebp__uv_preds[jebp__vp8_pred_type(hdr, hdr->uv_pred)]; jebp_int uv_offset = (hdr->y * image->uv_stride + hdr->x) * JEBP__UV_PIXEL_SIZE; jebp_ubyte *image_u = &image->u[uv_offset]; uv_pred(image_u, image->uv_stride); jebp_ubyte *image_v = &image->v[uv_offset]; uv_pred(image_v, image->uv_stride); // TODO: optimize 4x DCT inversion/add for UV predictions for (jebp_int y = 0; y < JEBP__UV_SIZE; y += 1) { jebp_int row = y * image->uv_stride; for (jebp_int x = 0; x < JEBP__UV_SIZE; x += 1) { jebp_ubyte *pred = &image_u[(row + x) * JEBP__BLOCK_SIZE]; jebp_int complex = JEBP__GET_U_NONZERO(state.top, x) + JEBP__GET_U_NONZERO(state.left, y); jebp_int nonzero = jebp__read_dct(hdr, dct, JEBP__BLOCK_UV, complex, bec, &err); JEBP__SET_BIT(state.top->uv_flags[x], JEBP__U_NONZERO, nonzero); JEBP__SET_BIT(state.left->uv_flags[y], JEBP__U_NONZERO, nonzero); jebp__invert_dct(dct); jebp__sum_pred_dct(pred, image->uv_stride, dct); } } for (jebp_int y = 0; y < JEBP__UV_SIZE; y += 1) { jebp_int row = y * image->uv_stride; for (jebp_int x = 0; x < JEBP__UV_SIZE; x += 1) { jebp_ubyte *pred = &image_v[(row + x) * JEBP__BLOCK_SIZE]; jebp_int complex = JEBP__GET_V_NONZERO(state.top, x) + JEBP__GET_V_NONZERO(state.left, y); jebp_int nonzero = jebp__read_dct(hdr, dct, JEBP__BLOCK_UV, complex, bec, &err); JEBP__SET_BIT(state.top->uv_flags[x], JEBP__V_NONZERO, nonzero); JEBP__SET_BIT(state.left->uv_flags[y], JEBP__V_NONZERO, nonzero); jebp__invert_dct(dct); jebp__sum_pred_dct(pred, image->uv_stride, dct); } } return err; } /** * VP8 lossy codec */ #define JEBP__VP8_TAG 0x20385056 #define JEBP__VP8_MAGIC 0x2a019d static jebp_error_t jebp__read_vp8_header(jebp__vp8_header_t *hdr, jebp_image_t *image, jebp__reader_t *reader, jebp__chunk_t *chunk) { jebp_error_t err = JEBP_OK; if (chunk->size < 10) { return JEBP_ERROR_INVDATA_HEADER; } chunk->size -= 10; jebp_int frame = jebp__read_uint24(reader, &err); if (jebp__read_uint24(reader, &err) != JEBP__VP8_MAGIC) { // check magic before everything else, despite being 3 bytes in return jebp__error(&err, JEBP_ERROR_INVDATA_HEADER); } if (frame & 0x1) { // frame must be a key-frame return jebp__error(&err, JEBP_ERROR_INVDATA); } if ((frame & 0xe) > 6) { // version must be 3 or less (shifted left by 1) return jebp__error(&err, JEBP_ERROR_NOSUP); } if (!(frame & 0x10)) { // frame must be displayed return jebp__error(&err, JEBP_ERROR_INVDATA); } hdr->bec_size = frame >> 5; if ((jebp_uint)hdr->bec_size > chunk->size) { return jebp__error(&err, JEBP_ERROR_INVDATA); } chunk->size -= hdr->bec_size; image->width = jebp__read_uint16(reader, &err); image->height = jebp__read_uint16(reader, &err); if ((image->width & 0xc000) || (image->height & 0xc000)) { // TODO: support frame upscaling return jebp__error(&err, JEBP_ERROR_NOSUP); } return err; } static jebp_error_t jebp__read_vp8_size(jebp_image_t *image, jebp__reader_t *reader, jebp__chunk_t *chunk) { jebp__vp8_header_t hdr; jebp__init_vp8_header(&hdr); return jebp__read_vp8_header(&hdr, image, reader, chunk); } static jebp_error_t jebp__read_vp8(jebp_image_t *image, jebp__reader_t *reader, jebp__chunk_t *chunk) { jebp_error_t err; jebp__vp8_header_t hdr; jebp__init_vp8_header(&hdr); if ((err = jebp__read_vp8_header(&hdr, image, reader, chunk)) != JEBP_OK) { return err; } jebp__reader_t map; jebp__bec_reader_t hdr_bec; if ((err = jebp__map_reader(reader, &map, hdr.bec_size)) != JEBP_OK) { return err; } if ((err = jebp__init_bec_reader(&hdr_bec, &map, hdr.bec_size)) != JEBP_OK) { jebp__unmap_reader(&map); return err; } if ((err = jebp__read_bec_header(&hdr, &hdr_bec)) != JEBP_OK) { jebp__unmap_reader(&map); return err; } jebp__bec_reader_t data_bec; if ((err = jebp__init_bec_reader(&data_bec, reader, chunk->size)) != JEBP_OK) { jebp__unmap_reader(&map); return err; } jebp_int macro_width = JEBP__CSHIFT(image->width, JEBP__Y_PIXEL_BITS); jebp_int macro_height = JEBP__CSHIFT(image->height, JEBP__Y_PIXEL_BITS); jebp__yuv_image_t yuv_image; yuv_image.width = macro_width * JEBP__Y_PIXEL_SIZE; yuv_image.height = macro_height * JEBP__Y_PIXEL_SIZE; if ((err = jebp__alloc_yuv_image(&yuv_image)) != JEBP_OK) { jebp__unmap_reader(&map); return err; } size_t top_size = macro_width * sizeof(jebp__macro_state_t); jebp__macro_state_t *top = JEBP_ALLOC(top_size); if (top == NULL) { jebp__free_yuv_image(&yuv_image); jebp__unmap_reader(&map); return JEBP_ERROR_NOMEM; } JEBP__CLEAR(top, top_size); jebp__macro_state_t left; jebp__macro_header_t macro_hdr; macro_hdr.vp8 = &hdr; for (jebp_int y = 0; y < macro_height; y += 1) { JEBP__CLEAR(&left, sizeof(jebp__macro_state_t)); for (jebp_int x = 0; x < macro_width; x += 1) { macro_hdr.x = x; macro_hdr.y = y; jebp__macro_state_pair_t state = {.top = &top[x], .left = &left}; if ((err = jebp__read_macro_header(¯o_hdr, state, &hdr_bec)) != JEBP_OK) { break; } if ((err = jebp__read_macro_data(¯o_hdr, state, &yuv_image, &data_bec)) != JEBP_OK) { break; } } if (err != JEBP_OK) { break; } } JEBP_FREE(top); jebp__unmap_reader(&map); if (err != JEBP_OK) { jebp__free_yuv_image(&yuv_image); return err; } if ((err = jebp__alloc_image(image)) != JEBP_OK) { jebp__free_yuv_image(&yuv_image); return err; } err = jebp__convert_yuv_image(image, &yuv_image); jebp__free_yuv_image(&yuv_image); if (err != JEBP_OK) { jebp_free_image(image); return err; } return JEBP_OK; } #endif // JEBP_NO_VP8 /** * Bit reader */ #ifndef JEBP_NO_VP8L typedef struct jebp__bit_reader_t { jebp__reader_t *reader; size_t nb_bytes; jebp_int nb_bits; jebp_uint bits; } jebp__bit_reader_t; static void jepb__init_bit_reader(jebp__bit_reader_t *bits, jebp__reader_t *reader, size_t size) { bits->reader = reader; bits->nb_bytes = size; bits->nb_bits = 0; bits->bits = 0; } // buffer/peek/skip should be used together to optimize bit-reading static jebp_error_t jebp__buffer_bits(jebp__bit_reader_t *bits, jebp_int size) { jebp_error_t err = JEBP_OK; while (bits->nb_bits < size && bits->nb_bytes > 0) { bits->bits |= jebp__read_uint8(bits->reader, &err) << bits->nb_bits; bits->nb_bits += 8; bits->nb_bytes -= 1; } return err; } JEBP__INLINE jebp_int jepb__peek_bits(jebp__bit_reader_t *bits, jebp_int size) { return bits->bits & ((1 << size) - 1); } JEBP__INLINE jebp_error_t jebp__skip_bits(jebp__bit_reader_t *bits, jebp_int size) { if (size > bits->nb_bits) { return JEBP_ERROR_INVDATA; } bits->nb_bits -= size; bits->bits >>= size; return JEBP_OK; } static jebp_uint jebp__read_bits(jebp__bit_reader_t *bits, jebp_int size, jebp_error_t *err) { if (*err != JEBP_OK) { return 0; } if ((*err = jebp__buffer_bits(bits, size)) != JEBP_OK) { return 0; } jebp_uint value = jepb__peek_bits(bits, size); if ((*err = jebp__skip_bits(bits, size)) != JEBP_OK) { return 0; } return value; } /** * Huffman coding */ #define JEBP__MAX_HUFFMAN_LENGTH 15 #define JEBP__MAX_PRIMARY_LENGTH 8 #define JEBP__MAX_SECONDARY_LENGTH \ (JEBP__MAX_HUFFMAN_LENGTH - JEBP__MAX_PRIMARY_LENGTH) #define JEBP__NB_PRIMARY_HUFFMANS (1 << JEBP__MAX_PRIMARY_LENGTH) #define JEBP__NO_HUFFMAN_SYMBOL 0xffff #define JEBP__NB_META_SYMBOLS 19 #define JEBP__NB_COLOR_SYMBOLS 256 #define JEBP__NB_LENGTH_SYMBOLS 24 #define JEBP__NB_DIST_SYMBOLS 40 #define JEBP__NB_MAIN_SYMBOLS (JEBP__NB_COLOR_SYMBOLS + JEBP__NB_LENGTH_SYMBOLS) // The huffman decoding is done in one or two steps, both using a lookup table. // These tables are called the "primary" table and "secondary" tables. First // 8-bits are peeked from the stream to index the primary table. If the symbol // is in this table (indicated by length <= 8) then the symbol from that is used // and the length is used to skip that many bits. Codes which are smaller than // 8-bits are represented by filling the table such that any index with a prefix // of the given code will have the same entry. If the symbol requires more bits // (indiciated by length > 8) then the symbol is used as an offset pointing to // the secondary table which has an index size of (length - 8) bits. typedef struct jebp__huffman_t { // <= 8: length is the number of bits actually used, and symbol is the // decoded symbol or `JEBP__NO_HUFFMAN_SYMBOL` for an invalid code. // > 8: length is the maximum number of bits for any code with this prefix, // and symbol is the offset in the array to the secondary table. jebp_short length; jebp_ushort symbol; } jebp__huffman_t; typedef struct jebp__huffman_group_t { jebp__huffman_t *main; jebp__huffman_t *red; jebp__huffman_t *blue; jebp__huffman_t *alpha; jebp__huffman_t *dist; } jebp__huffman_group_t; static const jebp_byte jebp__meta_length_order[JEBP__NB_META_SYMBOLS]; // Reverse increment, returns truthy on overflow JEBP__INLINE jebp_int jebp__increment_code(jebp_int *code, jebp_int length) { jebp_int inc = 1 << (length - 1); while (*code & inc) { inc >>= 1; } if (inc == 0) { return 1; } *code = (*code & (inc - 1)) + inc; return 0; } // This function is a bit confusing so I have attempted to document it well static jebp_error_t jebp__alloc_huffman(jebp__huffman_t **huffmans, jebp_int nb_lengths, const jebp_byte *lengths) { // Stack allocate the primary table and set it all to invalid values jebp__huffman_t primary[JEBP__NB_PRIMARY_HUFFMANS]; for (jebp_int i = 0; i < JEBP__NB_PRIMARY_HUFFMANS; i += 1) { primary[i].symbol = JEBP__NO_HUFFMAN_SYMBOL; } // Fill in the 8-bit codes in the primary table jebp_int len = 1; jebp_int code = 0; jebp_int overflow = 0; jebp_ushort symbol = JEBP__NO_HUFFMAN_SYMBOL; jebp_int nb_symbols = 0; for (; len <= JEBP__MAX_PRIMARY_LENGTH; len += 1) { for (jebp_int i = 0; i < nb_lengths; i += 1) { if (lengths[i] != len) { continue; } if (overflow) { // Fail now if the last increment overflowed return JEBP_ERROR_INVDATA; } for (jebp_int c = code; c < JEBP__NB_PRIMARY_HUFFMANS; c += 1 << len) { primary[c].length = len; primary[c].symbol = i; } overflow = jebp__increment_code(&code, len); symbol = i; nb_symbols += 1; } } // Fill in the secondary table lengths in the primary table jebp_int secondary_code = code; for (; len <= JEBP__MAX_HUFFMAN_LENGTH; len += 1) { for (jebp_int i = 0; i < nb_lengths; i += 1) { if (lengths[i] != len) { continue; } if (overflow) { return JEBP_ERROR_INVDATA; } jebp_int prefix = code & (JEBP__NB_PRIMARY_HUFFMANS - 1); primary[prefix].length = len; overflow = jebp__increment_code(&code, len); symbol = i; nb_symbols += 1; } } // Calculate the total no. of huffman entries and fill in the secondary // table offsets jebp_int nb_huffmans = JEBP__NB_PRIMARY_HUFFMANS; for (jebp_int i = 0; i < JEBP__NB_PRIMARY_HUFFMANS; i += 1) { if (nb_symbols <= 1) { // Special case: if there is only one symbol, use this iteration to // instead fill the primary table with 0-length // entries primary[i].length = 0; primary[i].symbol = symbol; continue; } jebp_int suffix_length = primary[i].length - JEBP__MAX_PRIMARY_LENGTH; if (suffix_length > 0) { primary[i].symbol = nb_huffmans; nb_huffmans += 1 << suffix_length; } } // Allocate, copy over the primary table, and assign the rest to invalid // values *huffmans = JEBP_ALLOC(nb_huffmans * sizeof(jebp__huffman_t)); if (*huffmans == NULL) { return JEBP_ERROR_NOMEM; } memcpy(*huffmans, primary, sizeof(primary)); if (nb_huffmans == JEBP__NB_PRIMARY_HUFFMANS) { // Special case: we can stop here if we don't have to fill any secondary // tables return JEBP_OK; } for (jebp_int i = JEBP__NB_PRIMARY_HUFFMANS; i < nb_huffmans; i += 1) { (*huffmans)[i].symbol = JEBP__NO_HUFFMAN_SYMBOL; } // Fill in the secondary tables len = JEBP__MAX_PRIMARY_LENGTH + 1; code = secondary_code; for (; len <= JEBP__MAX_HUFFMAN_LENGTH; len += 1) { for (jebp_int i = 0; i < nb_lengths; i += 1) { if (lengths[i] != len) { continue; } jebp_int prefix = code & (JEBP__NB_PRIMARY_HUFFMANS - 1); jebp_int nb_secondary_huffmans = 1 << primary[prefix].length; jebp__huffman_t *secondary = *huffmans + primary[prefix].symbol; for (jebp_int c = code; c < nb_secondary_huffmans; c += 1 << len) { secondary[c >> JEBP__MAX_PRIMARY_LENGTH].length = len; secondary[c >> JEBP__MAX_PRIMARY_LENGTH].symbol = i; } jebp__increment_code(&code, len); } } return JEBP_OK; } static jebp_int jebp__read_symbol(jebp__huffman_t *huffmans, jebp__bit_reader_t *bits, jebp_error_t *err) { if (*err != JEBP_OK) { return 0; } if ((*err = jebp__buffer_bits(bits, JEBP__MAX_HUFFMAN_LENGTH)) != JEBP_OK) { return 0; } jebp_int code = jepb__peek_bits(bits, JEBP__MAX_PRIMARY_LENGTH); if (huffmans[code].symbol == JEBP__NO_HUFFMAN_SYMBOL) { *err = JEBP_ERROR_INVDATA; return 0; } jebp_int length = huffmans[code].length; jebp_int skip = JEBP__MIN(length, JEBP__MAX_PRIMARY_LENGTH); if ((*err = jebp__skip_bits(bits, skip)) != JEBP_OK) { return 0; } if (skip == length) { return huffmans[code].symbol; } huffmans += huffmans[code].symbol; code = jepb__peek_bits(bits, length - skip); if (huffmans[code].symbol == JEBP__NO_HUFFMAN_SYMBOL) { *err = JEBP_ERROR_INVDATA; return 0; } if ((*err = jebp__skip_bits(bits, huffmans[code].length - skip)) != JEBP_OK) { return 0; } return huffmans[code].symbol; } static jebp_error_t jebp__read_huffman(jebp__huffman_t **huffmans, jebp__bit_reader_t *bits, jebp_int nb_lengths, jebp_byte *lengths) { // This part of the spec is INCREDIBLY wrong and partly missing jebp_error_t err = JEBP_OK; JEBP__CLEAR(lengths, nb_lengths); if (jebp__read_bits(bits, 1, &err)) { // simple length storage with only 1 (first) or 2 (second) symbols, both // with a length of 1 jebp_int has_second = jebp__read_bits(bits, 1, &err); jebp_int first_bits = jebp__read_bits(bits, 1, &err) ? 8 : 1; jebp_int first = jebp__read_bits(bits, first_bits, &err); if (first >= nb_lengths) { return jebp__error(&err, JEBP_ERROR_INVDATA); } lengths[first] = 1; if (has_second) { jebp_int second = jebp__read_bits(bits, 8, &err); if (second >= nb_lengths) { return jebp__error(&err, JEBP_ERROR_INVDATA); } lengths[second] = 1; } } else { jebp_byte meta_lengths[JEBP__NB_META_SYMBOLS] = {0}; jebp_int nb_meta_lengths = jebp__read_bits(bits, 4, &err) + 4; for (jebp_int i = 0; i < nb_meta_lengths; i += 1) { meta_lengths[jebp__meta_length_order[i]] = jebp__read_bits(bits, 3, &err); } if (err != JEBP_OK) { return err; } jebp__huffman_t *meta_huffmans; if ((err = jebp__alloc_huffman(&meta_huffmans, JEBP__NB_META_SYMBOLS, meta_lengths)) != JEBP_OK) { return err; } jebp_int nb_meta_symbols = nb_lengths; if (jebp__read_bits(bits, 1, &err)) { // limit codes jebp_int symbols_bits = jebp__read_bits(bits, 3, &err) * 2 + 2; nb_meta_symbols = jebp__read_bits(bits, symbols_bits, &err) + 2; } jebp_int prev_length = 8; for (jebp_int i = 0; i < nb_lengths && nb_meta_symbols > 0; nb_meta_symbols -= 1) { jebp_int symbol = jebp__read_symbol(meta_huffmans, bits, &err); jebp_int length; jebp_int repeat; switch (symbol) { case 16: length = prev_length; repeat = jebp__read_bits(bits, 2, &err) + 3; break; case 17: length = 0; repeat = jebp__read_bits(bits, 3, &err) + 3; break; case 18: length = 0; repeat = jebp__read_bits(bits, 7, &err) + 11; break; default: prev_length = symbol; /* fallthrough */ case 0: // We don't ever repeat 0 values. lengths[i++] = symbol; continue; } if (i + repeat > nb_lengths) { jebp__error(&err, JEBP_ERROR_INVDATA); break; } for (jebp_int j = 0; j < repeat; j += 1) { lengths[i++] = length; } } JEBP_FREE(meta_huffmans); } if (err != JEBP_OK) { return err; } return jebp__alloc_huffman(huffmans, nb_lengths, lengths); } static jebp_error_t jebp__read_huffman_group(jebp__huffman_group_t *group, jebp__bit_reader_t *bits, jebp_int nb_main_symbols, jebp_byte *lengths) { jebp_error_t err; if ((err = jebp__read_huffman(&group->main, bits, nb_main_symbols, lengths)) != JEBP_OK) { return err; } if ((err = jebp__read_huffman(&group->red, bits, JEBP__NB_COLOR_SYMBOLS, lengths)) != JEBP_OK) { return err; } if ((err = jebp__read_huffman(&group->blue, bits, JEBP__NB_COLOR_SYMBOLS, lengths)) != JEBP_OK) { return err; } if ((err = jebp__read_huffman(&group->alpha, bits, JEBP__NB_COLOR_SYMBOLS, lengths)) != JEBP_OK) { return err; } if ((err = jebp__read_huffman(&group->dist, bits, JEBP__NB_DIST_SYMBOLS, lengths)) != JEBP_OK) { return err; } return JEBP_OK; } static void jebp__free_huffman_group(jebp__huffman_group_t *group) { JEBP_FREE(group->main); JEBP_FREE(group->red); JEBP_FREE(group->blue); JEBP_FREE(group->alpha); JEBP_FREE(group->dist); } /** * Color cache */ typedef struct jebp__colcache_t { jebp_int bits; jebp_color_t *colors; } jebp__colcache_t; static jebp_error_t jebp__read_colcache(jebp__colcache_t *colcache, jebp__bit_reader_t *bits) { jebp_error_t err = JEBP_OK; if (!jebp__read_bits(bits, 1, &err)) { // no color cache colcache->bits = 0; return err; } colcache->bits = jebp__read_bits(bits, 4, &err); if (err != JEBP_OK || colcache->bits < 1 || colcache->bits > 11) { return jebp__error(&err, JEBP_ERROR_INVDATA); } size_t colcache_size = ((size_t)1 << colcache->bits) * sizeof(jebp_color_t); colcache->colors = JEBP_ALLOC(colcache_size); if (colcache->colors == NULL) { return JEBP_ERROR_NOMEM; } JEBP__CLEAR(colcache->colors, colcache_size); return JEBP_OK; } static void jebp__free_colcache(jebp__colcache_t *colcache) { if (colcache->bits > 0) { JEBP_FREE(colcache->colors); } } static void jebp__colcache_insert(jebp__colcache_t *colcache, jebp_color_t *color) { if (colcache->bits == 0) { return; } #if defined(JEBP__LITTLE_ENDIAN) && defined(JEBP__SWAP32) jebp_uint hash; memcpy(&hash, color, sizeof(jebp_color_t)); // ABGR due to little-endian hash = JEBP__SWAP32(hash); // RGBA hash = (hash >> 8) | (hash << 24); // ARGB #else jebp_uint hash = ((jebp_uint)color->a << 24) | ((jebp_uint)color->r << 16) | ((jebp_uint)color->g << 8) | (jebp_uint)color->b; #endif hash = (0x1e35a7bd * hash) >> (32 - colcache->bits); colcache->colors[hash] = *color; } /** * VP8L image */ #define JEBP__NB_VP8L_OFFSETS 120 typedef struct jebp__subimage_t { jebp_image_t s; jebp_int block_bits; } jebp__subimage_t; static const jebp_byte jebp__vp8l_offsets[JEBP__NB_VP8L_OFFSETS][2]; JEBP__INLINE jebp_int jebp__read_vp8l_extrabits(jebp__bit_reader_t *bits, jebp_int symbol, jebp_error_t *err) { if (*err != JEBP_OK) { return 1; } if (symbol < 4) { return symbol + 1; } jebp_int extrabits = symbol / 2 - 1; symbol = ((symbol % 2 + 2) << extrabits) + 1; return symbol + jebp__read_bits(bits, extrabits, err); } static jebp_error_t jebp__read_vp8l_image(jebp_image_t *image, jebp__bit_reader_t *bits, jebp__colcache_t *colcache, jebp__subimage_t *huffman_image, jebp_int real_width) { jebp_error_t err; jebp_int nb_groups = 1; jebp__huffman_group_t *groups = &(jebp__huffman_group_t){0}; if (huffman_image != NULL) { jebp_int size = huffman_image->s.width * huffman_image->s.height; for (jebp_int i = 0; i < size; i += 1) { jebp_color_t *huffman = &huffman_image->s.pixels[i]; if (huffman->r != 0) { // Currently only 256 huffman groups are supported return JEBP_ERROR_NOSUP; } nb_groups = JEBP__MAX(nb_groups, huffman->g + 1); huffman += 1; } if (nb_groups > 1) { groups = JEBP_ALLOC(nb_groups * sizeof(jebp__huffman_group_t)); if (groups == NULL) { return JEBP_ERROR_NOMEM; } } } jebp_int nb_main_symbols = JEBP__NB_MAIN_SYMBOLS; if (colcache->bits > 0) { nb_main_symbols += 1 << colcache->bits; } jebp_byte *lengths = JEBP_ALLOC(nb_main_symbols); if (lengths == NULL) { err = JEBP_ERROR_NOMEM; goto free_groups; } jebp_int nb_read_groups = 0; for (; nb_read_groups < nb_groups; nb_read_groups += 1) { if ((err = jebp__read_huffman_group(&groups[nb_read_groups], bits, nb_main_symbols, lengths)) != JEBP_OK) { break; } } JEBP_FREE(lengths); if (err != JEBP_OK) { goto free_read_groups; } if ((err = jebp__alloc_image0(image, real_width)) != JEBP_OK) { goto free_read_groups; } jebp_color_t *pixel = image->pixels; jebp_color_t *end = pixel + image->width * image->height; jebp_int x = 0; for (jebp_int y = 0; y < image->height;) { jebp_color_t *huffman_row = NULL; if (huffman_image != NULL) { huffman_row = &huffman_image->s.pixels[(y >> huffman_image->block_bits) * huffman_image->s.width]; } do { jebp__huffman_group_t *group; if (huffman_image == NULL) { group = groups; } else { jebp_color_t *huffman = &huffman_row[x >> huffman_image->block_bits]; group = &groups[huffman->g]; } jebp_int main = jebp__read_symbol(group->main, bits, &err); if (main < JEBP__NB_COLOR_SYMBOLS) { pixel->g = main; pixel->r = jebp__read_symbol(group->red, bits, &err); pixel->b = jebp__read_symbol(group->blue, bits, &err); pixel->a = jebp__read_symbol(group->alpha, bits, &err); jebp__colcache_insert(colcache, pixel++); x += 1; } else if (main >= JEBP__NB_MAIN_SYMBOLS) { *(pixel++) = colcache->colors[main - JEBP__NB_MAIN_SYMBOLS]; x += 1; } else { jebp_int length = jebp__read_vp8l_extrabits( bits, main - JEBP__NB_COLOR_SYMBOLS, &err); jebp_int dist = jebp__read_symbol(group->dist, bits, &err); dist = jebp__read_vp8l_extrabits(bits, dist, &err); if (dist > JEBP__NB_VP8L_OFFSETS) { dist -= JEBP__NB_VP8L_OFFSETS; } else { const jebp_byte *offset = jebp__vp8l_offsets[dist - 1]; dist = offset[1] * image->width + offset[0]; dist = JEBP__MAX(dist, 1); } jebp_color_t *repeat = pixel - dist; if (repeat < image->pixels || pixel + length > end) { jebp__error(&err, JEBP_ERROR_INVDATA); break; } for (jebp_int i = 0; i < length; i += 1) { jebp__colcache_insert(colcache, repeat); *(pixel++) = *(repeat++); } x += length; } } while (x < image->width); y += x / image->width; x %= image->width; } if (err != JEBP_OK) { jebp_free_image(image); } free_read_groups: for (nb_read_groups -= 1; nb_read_groups >= 0; nb_read_groups -= 1) { jebp__free_huffman_group(&groups[nb_read_groups]); } free_groups: if (nb_groups > 1) { JEBP_FREE(groups); } return err; } static jebp_error_t jebp__read_subimage(jebp__subimage_t *subimage, jebp__bit_reader_t *bits, jebp_image_t *image) { jebp_error_t err = JEBP_OK; subimage->block_bits = jebp__read_bits(bits, 3, &err) + 2; subimage->s.width = JEBP__CSHIFT(image->width, subimage->block_bits); subimage->s.height = JEBP__CSHIFT(image->height, subimage->block_bits); if (err != JEBP_OK) { return err; } jebp__colcache_t colcache; if ((err = jebp__read_colcache(&colcache, bits)) != JEBP_OK) { return err; } err = jebp__read_vp8l_image(&subimage->s, bits, &colcache, NULL, subimage->s.width); jebp__free_colcache(&colcache); return err; } static jebp_error_t jebp__read_palette(jebp__subimage_t *subimage, jebp__bit_reader_t *bits, jebp_image_t *image) { jebp_error_t err = JEBP_OK; jebp_uint len = jebp__read_bits(bits, 8, &err) + 1; jebp_uint i; jebp_color_t px0 = {0}; if (err != JEBP_OK) { return err; } subimage->block_bits = 0; subimage->s.width = len; subimage->s.height = 1; jebp__colcache_t colcache; if ((err = jebp__read_colcache(&colcache, bits)) != JEBP_OK) { return err; } if ((err = jebp__read_vp8l_image(&subimage->s, bits, &colcache, NULL, subimage->s.width)) != JEBP_OK) { goto free_colcache; } for (i = 0; i < len; i++) { jebp_color_t *px1 = &subimage->s.pixels[i]; px1->r += px0.r; px1->g += px0.g; px1->b += px0.b; px1->a = 255; px0 = *px1; } if (len <= 2) { image->width = JEBP__RSHIFT(image->width, 3); } else if (len <= 4) { image->width = JEBP__RSHIFT(image->width, 2); } else if (len <= 16) { image->width = JEBP__RSHIFT(image->width, 1); } free_colcache: jebp__free_colcache(&colcache); return err; } /** * VP8L predictions */ #define JEBP__NB_VP8L_PRED_TYPES 14 // I don't like the way it formats this // clang-format off #define JEBP__UNROLL4(var, body) \ { var = 0; body } \ { var = 1; body } \ { var = 2; body } \ { var = 3; body } // clang-format on typedef void (*jebp__vp8l_pred_t)(jebp_color_t *pixel, jebp_color_t *top, jebp_int width); #ifdef JEBP__SIMD_SSE2 typedef struct jebp__m128x4i { __m128i v[4]; } jebp__m128x4i; JEBP__INLINE __m128i jebp__sse_move_px1(__m128i v_dst, __m128i v_src) { __m128 v_dstf = _mm_castsi128_ps(v_dst); __m128 v_srcf = _mm_castsi128_ps(v_src); __m128 v_movf = _mm_move_ss(v_dstf, v_srcf); return _mm_castps_si128(v_movf); } JEBP__INLINE __m128i jebp__sse_avg_u8x16(__m128i v1, __m128i v2) { __m128i v_one = _mm_set1_epi8(1); __m128i v_avg = _mm_avg_epu8(v1, v2); // SSE2 `avg` rounds up, we have to check if a round-up occured (one of the // low bits was set but the other wasn't) and subtract 1 if so __m128i v_err = _mm_xor_si128(v1, v2); v_err = _mm_and_si128(v_err, v_one); return _mm_sub_epi8(v_avg, v_err); } JEBP__INLINE __m128i jebp__sse_avg2_u8x16(__m128i v1, __m128i v2, __m128i v3) { __m128i v_one = _mm_set1_epi8(1); // We can further optimise two avg calls but noting that the error will // propogate __m128i v_avg1 = _mm_avg_epu8(v1, v2); __m128i v_err1 = _mm_xor_si128(v1, v2); __m128i v_avg2 = _mm_avg_epu8(v_avg1, v3); __m128i v_err2 = _mm_xor_si128(v_avg1, v3); v_err2 = _mm_or_si128(v_err1, v_err2); v_err2 = _mm_and_si128(v_err2, v_one); return _mm_sub_epi8(v_avg2, v_err2); } JEBP__INLINE __m128i jebp__sse_flatten_px4(jebp__m128x4i v_pixel4) { __m128i v_pixello = jebp__sse_move_px1(v_pixel4.v[1], v_pixel4.v[0]); __m128i v_pixel3 = _mm_bsrli_si128(v_pixel4.v[3], 4); __m128i v_pixelhi = _mm_unpackhi_epi32(v_pixel4.v[2], v_pixel3); return _mm_unpacklo_epi64(v_pixello, v_pixelhi); } // Bit-select and accumulate, used by prediction filters 11-13 JEBP__INLINE __m128i jebp__sse_bsela_u8x16(__m128i v_acc, __m128i v_mask, __m128i v1, __m128i v0) { // This is faster than using and/andnot/or since SSE only supports two // operands so prefers chaining outputs __m128i v_sel = _mm_xor_si128(v0, v1); v_sel = _mm_and_si128(v_sel, v_mask); v_sel = _mm_xor_si128(v_sel, v0); return _mm_add_epi8(v_acc, v_sel); } #endif // JEBP__SIMD_SSE2 #ifdef JEBP__SIMD_NEON JEBP__INLINE uint8x16_t jebp__neon_load_px1(jebp_color_t *pixel) { uint8x16_t v_pixel = vreinterpretq_u8_u32(vld1q_dup_u32((uint32_t *)pixel)); #ifndef JEBP__LITTLE_ENDIAN v_pixel = vrev32q_u8(v_pixel); #endif // JEBP__LITTLE_ENDIAN return v_pixel; } JEBP__INLINE uint8x16_t jebp__neon_flatten_px4(uint8x16x4_t v_pixel4) { #ifdef JEBP__SIMD_NEON64 uint8x16_t v_table = vcombine_u8(vcreate_u8(0x1716151403020100), vcreate_u8(0x3f3e3d3c2b2a2928)); return vqtbl4q_u8(v_pixel4, v_table); #else // JEBP__SIMD_NEON64 uint8x16_t v_mask = vreinterpretq_u8_u64(vdupq_n_u64(0xffffffff)); uint8x16_t v_even = vcombine_u8(vget_low_u8(v_pixel4.val[0]), vget_high_u8(v_pixel4.val[2])); uint8x16_t v_odd = vcombine_u8(vget_low_u8(v_pixel4.val[1]), vget_high_u8(v_pixel4.val[3])); return vbslq_u8(v_mask, v_even, v_odd); #endif // JEBP__SIMD_NEON64 } JEBP__INLINE uint32x4_t jebp__neon_sad_px4(uint8x16_t v_pix1, uint8x16_t v_pix2) { uint8x16_t v_diff8 = vabdq_u8(v_pix1, v_pix2); uint16x8_t v_diff16 = vpaddlq_u8(v_diff8); return vpaddlq_u16(v_diff16); } #endif // JEBP__SIMD_NEON JEBP__INLINE void jebp__vp8l_pred_black(jebp_color_t *pixel, jebp_int width) { jebp_int x = 0; #if defined(JEBP__SIMD_SSE2) __m128i v_black = _mm_set1_epi32((int)0xff000000); for (; x + 4 <= width; x += 4) { __m128i v_pixel = _mm_loadu_si128((__m128i *)&pixel[x]); v_pixel = _mm_add_epi8(v_pixel, v_black); _mm_storeu_si128((__m128i *)&pixel[x], v_pixel); } #elif defined(JEBP__SIMD_NEON) uint8x8_t v_black = vdup_n_u8(0xff); for (; x + 8 <= width; x += 8) { uint8x8x4_t v_pixel = vld4_u8((uint8_t *)&pixel[x]); v_pixel.val[3] = vadd_u8(v_pixel.val[3], v_black); vst4_u8((uint8_t *)&pixel[x], v_pixel); } #endif for (; x < width; x += 1) { pixel[x].a += 0xff; } } static void jebp__vp8l_pred0(jebp_color_t *pixel, jebp_color_t *top, jebp_int width) { (void)top; jebp__vp8l_pred_black(pixel, width); } JEBP__INLINE void jebp__vp8l_pred_left(jebp_color_t *pixel, jebp_int width) { jebp_int x = 0; #if defined(JEBP__SIMD_SSE2) __m128i v_left; if (width >= 4) { int v_left_i; memcpy(&v_left_i, &pixel[-1], sizeof(int)); v_left = _mm_cvtsi32_si128(v_left_i); } for (; x + 4 <= width; x += 4) { __m128i v_pixel = _mm_loadu_si128((__m128i *)&pixel[x]); v_pixel = _mm_add_epi8(v_pixel, v_left); v_left = _mm_bslli_si128(v_pixel, 4); v_pixel = _mm_add_epi8(v_pixel, v_left); v_left = _mm_bslli_si128(v_pixel, 8); v_pixel = _mm_add_epi8(v_pixel, v_left); _mm_storeu_si128((__m128i *)&pixel[x], v_pixel); v_left = _mm_bsrli_si128(v_pixel, 12); } #elif defined(JEBP__SIMD_NEON) uint8x16_t v_zero = vdupq_n_u8(0); uint8x16_t v_left; if (width >= 4) { v_left = jebp__neon_load_px1(&pixel[-1]); v_left = vextq_u8(v_left, v_zero, 12); } for (; x + 4 <= width; x += 4) { uint8x16_t v_pixel = vld1q_u8((uint8_t *)&pixel[x]); v_pixel = vaddq_u8(v_pixel, v_left); v_left = vextq_u8(v_zero, v_pixel, 12); v_pixel = vaddq_u8(v_pixel, v_left); v_left = vextq_u8(v_zero, v_pixel, 8); v_pixel = vaddq_u8(v_pixel, v_left); vst1q_u8((uint8_t *)&pixel[x], v_pixel); v_left = vextq_u8(v_pixel, v_zero, 12); } #endif for (; x < width; x += 1) { pixel[x].r += pixel[x - 1].r; pixel[x].g += pixel[x - 1].g; pixel[x].b += pixel[x - 1].b; pixel[x].a += pixel[x - 1].a; } } static void jebp__vp8l_pred1(jebp_color_t *pixel, jebp_color_t *top, jebp_int width) { (void)top; jebp__vp8l_pred_left(pixel, width); } JEBP__INLINE void jebp__vp8l_pred_top(jebp_color_t *pixel, jebp_color_t *top, jebp_int width) { jebp_int x = 0; #if defined(JEBP__SIMD_SSE2) for (; x + 4 <= width; x += 4) { __m128i v_pixel = _mm_loadu_si128((__m128i *)&pixel[x]); __m128i v_top = _mm_loadu_si128((__m128i *)&top[x]); v_pixel = _mm_add_epi8(v_pixel, v_top); _mm_storeu_si128((__m128i *)&pixel[x], v_pixel); } #elif defined(JEBP__SIMD_NEON) for (; x + 4 <= width; x += 4) { uint8x16_t v_pixel = vld1q_u8((uint8_t *)&pixel[x]); uint8x16_t v_top = vld1q_u8((uint8_t *)&top[x]); v_pixel = vaddq_u8(v_pixel, v_top); vst1q_u8((uint8_t *)&pixel[x], v_pixel); } #endif for (; x < width; x += 1) { pixel[x].r += top[x].r; pixel[x].g += top[x].g; pixel[x].b += top[x].b; pixel[x].a += top[x].a; } } static void jebp__vp8l_pred2(jebp_color_t *pixel, jebp_color_t *top, jebp_int width) { jebp__vp8l_pred_top(pixel, top, width); } static void jebp__vp8l_pred3(jebp_color_t *pixel, jebp_color_t *top, jebp_int width) { jebp__vp8l_pred_top(pixel, &top[1], width); } static void jebp__vp8l_pred4(jebp_color_t *pixel, jebp_color_t *top, jebp_int width) { jebp__vp8l_pred_top(pixel, &top[-1], width); } static void jebp__vp8l_pred5(jebp_color_t *pixel, jebp_color_t *top, jebp_int width) { jebp_int x = 0; #if defined(JEBP__SIMD_SSE2) __m128i v_left; __m128i v_top; if (width >= 4) { int v_left_i; memcpy(&v_left_i, &pixel[-1], sizeof(int)); v_left = _mm_cvtsi32_si128(v_left_i); v_top = _mm_loadu_si128((__m128i *)top); } for (; x + 4 <= width; x += 4) { __m128i v_pixel = _mm_loadu_si128((__m128i *)&pixel[x]); __m128i v_next = _mm_loadu_si128((__m128i *)&top[x + 4]); __m128i v_tr = jebp__sse_move_px1(v_top, v_next); v_tr = _mm_shuffle_epi32(v_tr, _MM_SHUFFLE(0, 3, 2, 1)); jebp__m128x4i v_pixel4; JEBP__UNROLL4(jebp_int i, { __m128i v_avg = jebp__sse_avg2_u8x16(v_left, v_tr, v_top); v_pixel4.v[i] = _mm_add_epi8(v_pixel, v_avg); v_left = _mm_shuffle_epi32(v_pixel4.v[i], _MM_SHUFFLE(2, 1, 0, 3)); }) v_pixel = jebp__sse_flatten_px4(v_pixel4); _mm_storeu_si128((__m128i *)&pixel[x], v_pixel); v_top = v_next; } #elif defined(JEBP__SIMD_NEON) uint8x16_t v_left; uint8x16_t v_top; if (width >= 4) { v_left = jebp__neon_load_px1(&pixel[-1]); v_top = vld1q_u8((uint8_t *)top); } for (; x + 4 <= width; x += 4) { uint8x16_t v_pixel = vld1q_u8((uint8_t *)&pixel[x]); uint8x16_t v_next = vld1q_u8((uint8_t *)&top[x + 4]); uint8x16_t v_tr = vextq_u8(v_top, v_next, 4); uint8x16x4_t v_pixel4; JEBP__UNROLL4(jebp_int i, { uint8x16_t v_avg = vhaddq_u8(v_left, v_tr); v_avg = vhaddq_u8(v_avg, v_top); v_pixel4.val[i] = vaddq_u8(v_pixel, v_avg); v_left = vextq_u8(v_pixel4.val[i], v_pixel4.val[i], 12); }) v_pixel = jebp__neon_flatten_px4(v_pixel4); vst1q_u8((uint8_t *)&pixel[x], v_pixel); v_top = v_next; } #endif for (; x < width; x += 1) { pixel[x].r += JEBP__FAVG(JEBP__FAVG(pixel[x - 1].r, top[x + 1].r), top[x].r); pixel[x].g += JEBP__FAVG(JEBP__FAVG(pixel[x - 1].g, top[x + 1].g), top[x].g); pixel[x].b += JEBP__FAVG(JEBP__FAVG(pixel[x - 1].b, top[x + 1].b), top[x].b); pixel[x].a += JEBP__FAVG(JEBP__FAVG(pixel[x - 1].a, top[x + 1].a), top[x].a); } } JEBP__INLINE void jebp__vp8l_pred_avgtl(jebp_color_t *pixel, jebp_color_t *top, jebp_int width) { jebp_int x = 0; #if defined(JEBP__SIMD_SSE2) __m128i v_left; if (width >= 4) { int v_left_i; memcpy(&v_left_i, &pixel[-1], sizeof(int)); v_left = _mm_cvtsi32_si128(v_left_i); } for (; x + 4 <= width; x += 4) { __m128i v_pixel = _mm_loadu_si128((__m128i *)&pixel[x]); __m128i v_top = _mm_loadu_si128((__m128i *)&top[x]); jebp__m128x4i v_pixel4; JEBP__UNROLL4(jebp_int i, { __m128i v_avg = jebp__sse_avg_u8x16(v_left, v_top); v_pixel4.v[i] = _mm_add_epi8(v_pixel, v_avg); v_left = _mm_shuffle_epi32(v_pixel4.v[i], _MM_SHUFFLE(2, 1, 0, 3)); }) v_pixel = jebp__sse_flatten_px4(v_pixel4); _mm_storeu_si128((__m128i *)&pixel[x], v_pixel); } #elif defined(JEBP__SIMD_NEON) uint8x16_t v_left; if (width >= 4) { v_left = jebp__neon_load_px1(&pixel[-1]); } for (; x + 4 <= width; x += 4) { uint8x16_t v_pixel = vld1q_u8((uint8_t *)&pixel[x]); uint8x16_t v_top = vld1q_u8((uint8_t *)&top[x]); uint8x16x4_t v_pixel4; JEBP__UNROLL4(jebp_int i, { uint8x16_t v_avg = vhaddq_u8(v_left, v_top); v_pixel4.val[i] = vaddq_u8(v_pixel, v_avg); v_left = vextq_u8(v_pixel4.val[i], v_pixel4.val[i], 12); }) v_pixel = jebp__neon_flatten_px4(v_pixel4); vst1q_u8((uint8_t *)&pixel[x], v_pixel); } #endif for (; x < width; x += 1) { pixel[x].r += JEBP__FAVG(pixel[x - 1].r, top[x].r); pixel[x].g += JEBP__FAVG(pixel[x - 1].g, top[x].g); pixel[x].b += JEBP__FAVG(pixel[x - 1].b, top[x].b); pixel[x].a += JEBP__FAVG(pixel[x - 1].a, top[x].a); } } static void jebp__vp8l_pred6(jebp_color_t *pixel, jebp_color_t *top, jebp_int width) { jebp__vp8l_pred_avgtl(pixel, &top[-1], width); } static void jebp__vp8l_pred7(jebp_color_t *pixel, jebp_color_t *top, jebp_int width) { jebp__vp8l_pred_avgtl(pixel, top, width); } JEBP__INLINE void jebp__vp8l_pred_avgtr(jebp_color_t *pixel, jebp_color_t *top, jebp_int width) { jebp_int x = 0; #if defined(JEBP__SIMD_SSE2) __m128i v_top; if (width >= 4) { v_top = _mm_loadu_si128((__m128i *)top); } for (; x + 4 <= width; x += 4) { __m128i v_pixel = _mm_loadu_si128((__m128i *)&pixel[x]); __m128i v_next = _mm_loadu_si128((__m128i *)&top[x + 4]); __m128i v_tr = jebp__sse_move_px1(v_top, v_next); v_tr = _mm_shuffle_epi32(v_tr, _MM_SHUFFLE(0, 3, 2, 1)); v_tr = jebp__sse_avg_u8x16(v_top, v_tr); v_pixel = _mm_add_epi8(v_pixel, v_tr); _mm_storeu_si128((__m128i *)&pixel[x], v_pixel); v_top = v_next; } #elif defined(JEBP__SIMD_NEON) uint8x16_t v_top; if (width >= 4) { v_top = vld1q_u8((uint8_t *)top); } for (; x + 4 <= width; x += 4) { uint8x16_t v_pixel = vld1q_u8((uint8_t *)&pixel[x]); uint8x16_t v_next = vld1q_u8((uint8_t *)&top[x + 4]); uint8x16_t v_tr = vextq_u8(v_top, v_next, 4); v_tr = vhaddq_u8(v_top, v_tr); v_pixel = vaddq_u8(v_pixel, v_tr); vst1q_u8((uint8_t *)&pixel[x], v_pixel); v_top = v_next; } #endif for (; x < width; x += 1) { pixel[x].r += JEBP__FAVG(top[x].r, top[x + 1].r); pixel[x].g += JEBP__FAVG(top[x].g, top[x + 1].g); pixel[x].b += JEBP__FAVG(top[x].b, top[x + 1].b); pixel[x].a += JEBP__FAVG(top[x].a, top[x + 1].a); } } static void jebp__vp8l_pred8(jebp_color_t *pixel, jebp_color_t *top, jebp_int width) { jebp__vp8l_pred_avgtr(pixel, &top[-1], width); } static void jebp__vp8l_pred9(jebp_color_t *pixel, jebp_color_t *top, jebp_int width) { jebp__vp8l_pred_avgtr(pixel, top, width); } static void jebp__vp8l_pred10(jebp_color_t *pixel, jebp_color_t *top, jebp_int width) { jebp_int x = 0; #if defined(JEBP__SIMD_SSE2) __m128i v_left; __m128i v_tl; __m128i v_top; if (width >= 4) { int v_left_i, v_tl_i; memcpy(&v_left_i, &pixel[-1], sizeof(int)); memcpy(&v_tl_i, &top[-1], sizeof(int)); v_left = _mm_cvtsi32_si128(v_left_i); v_tl = _mm_cvtsi32_si128(v_tl_i); v_top = _mm_loadu_si128((__m128i *)top); } for (; x + 4 <= width; x += 4) { __m128i v_pixel = _mm_loadu_si128((__m128i *)&pixel[x]); __m128i v_next = _mm_loadu_si128((__m128i *)&top[x + 4]); __m128i v_rot = _mm_shuffle_epi32(v_top, _MM_SHUFFLE(2, 1, 0, 3)); v_tl = jebp__sse_move_px1(v_rot, v_tl); __m128i v_tr = jebp__sse_move_px1(v_top, v_next); v_tr = _mm_shuffle_epi32(v_tr, _MM_SHUFFLE(0, 3, 2, 1)); v_tr = jebp__sse_avg_u8x16(v_top, v_tr); jebp__m128x4i v_pixel4; JEBP__UNROLL4(jebp_int i, { __m128i v_avg = jebp__sse_avg2_u8x16(v_left, v_tl, v_tr); v_pixel4.v[i] = _mm_add_epi8(v_pixel, v_avg); v_left = _mm_shuffle_epi32(v_pixel4.v[i], _MM_SHUFFLE(2, 1, 0, 3)); }) v_pixel = jebp__sse_flatten_px4(v_pixel4); _mm_storeu_si128((__m128i *)&pixel[x], v_pixel); v_tl = v_rot; v_top = v_next; } #elif defined(JEBP__SIMD_NEON) uint8x16_t v_left; uint8x16_t v_tl; uint8x16_t v_top; if (width >= 4) { v_left = jebp__neon_load_px1(&pixel[-1]); v_tl = jebp__neon_load_px1(&top[-1]); v_top = vld1q_u8((uint8_t *)top); } for (; x + 4 <= width; x += 4) { uint8x16_t v_pixel = vld1q_u8((uint8_t *)&pixel[x]); uint8x16_t v_next = vld1q_u8((uint8_t *)&top[x + 4]); v_tl = vextq_u8(v_tl, v_top, 12); uint8x16_t v_tr = vextq_u8(v_top, v_next, 4); v_tr = vhaddq_u8(v_top, v_tr); uint8x16x4_t v_pixel4; JEBP__UNROLL4(jebp_int i, { uint8x16_t v_avg = vhaddq_u8(v_left, v_tl); v_avg = vhaddq_u8(v_avg, v_tr); v_pixel4.val[i] = vaddq_u8(v_pixel, v_avg); v_left = vextq_u8(v_pixel4.val[i], v_pixel4.val[i], 12); }) v_pixel = jebp__neon_flatten_px4(v_pixel4); vst1q_u8((uint8_t *)&pixel[x], v_pixel); v_tl = v_top; v_top = v_next; } #endif for (; x < width; x += 1) { pixel[x].r += JEBP__FAVG(JEBP__FAVG(pixel[x - 1].r, top[x - 1].r), JEBP__FAVG(top[x].r, top[x + 1].r)); pixel[x].g += JEBP__FAVG(JEBP__FAVG(pixel[x - 1].g, top[x - 1].g), JEBP__FAVG(top[x].g, top[x + 1].g)); pixel[x].b += JEBP__FAVG(JEBP__FAVG(pixel[x - 1].b, top[x - 1].b), JEBP__FAVG(top[x].b, top[x + 1].b)); pixel[x].a += JEBP__FAVG(JEBP__FAVG(pixel[x - 1].a, top[x - 1].a), JEBP__FAVG(top[x].a, top[x + 1].a)); } } JEBP__INLINE jebp_int jebp__vp8l_pred_dist(jebp_color_t *pix1, jebp_color_t *pix2) { return JEBP__ABS(pix1->r - pix2->r) + JEBP__ABS(pix1->g - pix2->g) + JEBP__ABS(pix1->b - pix2->b) + JEBP__ABS(pix1->a - pix2->a); } static void jebp__vp8l_pred11(jebp_color_t *pixel, jebp_color_t *top, jebp_int width) { jebp_int x = 0; #if defined(JEBP__SIMD_SSE2) __m128i v_left; __m128i v_tl; if (width >= 4) { int v_left_i, v_tl_i; memcpy(&v_left_i, &pixel[-1], sizeof(int)); memcpy(&v_tl_i, &top[-1], sizeof(int)); v_left = _mm_cvtsi32_si128(v_left_i); v_tl = _mm_cvtsi32_si128(v_tl_i); } for (; x + 4 <= width; x += 4) { __m128i v_ldist, v_tdist, v_cmp, v_pixello, v_pixelhi; __m128i v_pixel = _mm_loadu_si128((__m128i *)&pixel[x]); __m128i v_top = _mm_loadu_si128((__m128i *)&top[x]); __m128i v_rot = _mm_shuffle_epi32(v_top, _MM_SHUFFLE(2, 1, 0, 3)); v_tl = jebp__sse_move_px1(v_rot, v_tl); // Pixel 0 // This does double the SAD result but if both distances are doubled the // comparison should still be the same __m128i v_tllo = _mm_unpacklo_epi32(v_tl, v_tl); __m128i v_toplo = _mm_unpacklo_epi32(v_top, v_top); v_ldist = _mm_sad_epu8(v_tllo, v_toplo); v_tdist = _mm_unpacklo_epi32(v_left, v_left); v_tdist = _mm_sad_epu8(v_tllo, v_tdist); v_cmp = _mm_cmplt_epi32(v_ldist, v_tdist); v_pixello = jebp__sse_bsela_u8x16(v_pixel, v_cmp, v_left, v_top); v_left = _mm_bslli_si128(v_pixello, 4); // Pixel 1 v_tdist = _mm_unpacklo_epi32(v_left, v_left); v_tdist = _mm_sad_epu8(v_tllo, v_tdist); v_cmp = _mm_cmplt_epi32(v_ldist, v_tdist); v_cmp = _mm_bsrli_si128(v_cmp, 4); v_pixello = jebp__sse_bsela_u8x16(v_pixel, v_cmp, v_left, v_top); v_pixello = _mm_unpacklo_epi32(v_left, v_pixello); v_left = _mm_bsrli_si128(v_pixello, 4); // Pixel 2 __m128i v_tlhi = _mm_shuffle_epi32(v_tl, _MM_SHUFFLE(2, 2, 3, 3)); __m128i v_tophi = _mm_shuffle_epi32(v_top, _MM_SHUFFLE(2, 2, 3, 3)); v_ldist = _mm_sad_epu8(v_tlhi, v_tophi); v_tdist = _mm_shuffle_epi32(v_left, _MM_SHUFFLE(2, 2, 3, 3)); v_tdist = _mm_sad_epu8(v_tlhi, v_tdist); v_cmp = _mm_cmplt_epi32(v_ldist, v_tdist); v_pixelhi = jebp__sse_bsela_u8x16(v_pixel, v_cmp, v_left, v_top); v_left = _mm_bslli_si128(v_pixelhi, 4); // Pixel 3 v_tdist = _mm_shuffle_epi32(v_left, _MM_SHUFFLE(2, 2, 3, 3)); v_tdist = _mm_sad_epu8(v_tlhi, v_tdist); v_cmp = _mm_cmplt_epi32(v_ldist, v_tdist); v_cmp = _mm_bslli_si128(v_cmp, 12); v_pixelhi = jebp__sse_bsela_u8x16(v_pixel, v_cmp, v_left, v_top); v_pixelhi = _mm_unpackhi_epi32(v_left, v_pixelhi); v_left = _mm_bsrli_si128(v_pixelhi, 12); v_pixel = _mm_unpackhi_epi64(v_pixello, v_pixelhi); _mm_storeu_si128((__m128i *)&pixel[x], v_pixel); v_tl = v_rot; } #elif defined(JEBP__SIMD_NEON) uint8x16_t v_left; uint8x16_t v_tl; if (width >= 4) { v_left = jebp__neon_load_px1(&pixel[-1]); v_tl = jebp__neon_load_px1(&top[-1]); } for (; x + 4 <= width; x += 4) { uint8x16_t v_pixel = vld1q_u8((uint8_t *)&pixel[x]); uint8x16_t v_top = vld1q_u8((uint8_t *)&top[x]); v_tl = vextq_u8(v_tl, v_top, 12); uint32x4_t v_ldist = jebp__neon_sad_px4(v_tl, v_top); uint8x16x4_t v_pixel4; JEBP__UNROLL4(jebp_int i, { uint32x4_t v_tdist = jebp__neon_sad_px4(v_tl, v_left); uint32x4_t v_cmp = vcltq_u32(v_ldist, v_tdist); uint8x16_t v_pred = vbslq_u8((uint8x16_t)v_cmp, v_left, v_top); v_pixel4.val[i] = vaddq_u8(v_pixel, v_pred); v_left = vextq_u8(v_pixel4.val[i], v_pixel4.val[i], 12); }) v_pixel = jebp__neon_flatten_px4(v_pixel4); vst1q_u8((uint8_t *)&pixel[x], v_pixel); v_tl = v_top; } #endif for (; x < width; x += 1) { jebp_int ldist = jebp__vp8l_pred_dist(&top[x - 1], &top[x]); jebp_int tdist = jebp__vp8l_pred_dist(&top[x - 1], &pixel[x - 1]); if (ldist < tdist) { jebp__vp8l_pred_left(&pixel[x], 1); } else { jebp__vp8l_pred_top(&pixel[x], &top[x], 1); } } } static void jebp__vp8l_pred12(jebp_color_t *pixel, jebp_color_t *top, jebp_int width) { jebp_int x = 0; #if defined(JEBP__SIMD_SSE2) __m128i v_left; __m128i v_tl; if (width >= 4) { int v_left_i, v_tl_i; memcpy(&v_left_i, &pixel[-1], sizeof(int)); memcpy(&v_tl_i, &top[-1], sizeof(int)); v_left = _mm_cvtsi32_si128(v_left_i); v_tl = _mm_cvtsi32_si128(v_tl_i); } for (; x + 4 <= width; x += 4) { __m128i v_pixel = _mm_loadu_si128((__m128i *)&pixel[x]); __m128i v_top = _mm_loadu_si128((__m128i *)&top[x]); __m128i v_rot = _mm_shuffle_epi32(v_top, _MM_SHUFFLE(2, 1, 0, 3)); v_tl = jebp__sse_move_px1(v_rot, v_tl); __m128i v_max = _mm_max_epu8(v_top, v_tl); __m128i v_min = _mm_min_epu8(v_top, v_tl); __m128i v_diff = _mm_sub_epi8(v_max, v_min); __m128i v_pos = _mm_cmpeq_epi8(v_max, v_top); jebp__m128x4i v_pixel4; JEBP__UNROLL4(jebp_int i, { __m128i v_add = _mm_adds_epu8(v_left, v_diff); __m128i v_sub = _mm_subs_epu8(v_left, v_diff); v_pixel4.v[i] = jebp__sse_bsela_u8x16(v_pixel, v_pos, v_add, v_sub); v_left = _mm_shuffle_epi32(v_pixel4.v[i], _MM_SHUFFLE(2, 1, 0, 3)); }) v_pixel = jebp__sse_flatten_px4(v_pixel4); _mm_storeu_si128((__m128i *)&pixel[x], v_pixel); v_tl = v_rot; } #elif defined(JEBP__SIMD_NEON) uint8x16_t v_left; uint8x16_t v_tl; if (width >= 4) { v_left = jebp__neon_load_px1(&pixel[-1]); v_tl = jebp__neon_load_px1(&top[-1]); } for (; x + 4 <= width; x += 4) { uint8x16_t v_pixel = vld1q_u8((uint8_t *)&pixel[x]); uint8x16_t v_top = vld1q_u8((uint8_t *)&top[x]); v_tl = vextq_u8(v_tl, v_top, 12); uint8x16_t v_diff = vabdq_u8(v_top, v_tl); uint8x16_t v_neg = vcltq_u8(v_top, v_tl); uint8x16x4_t v_pixel4; JEBP__UNROLL4(jebp_int i, { uint8x16_t v_add = vqaddq_u8(v_left, v_diff); uint8x16_t v_sub = vqsubq_u8(v_left, v_diff); uint8x16_t v_pred = vbslq_u8(v_neg, v_sub, v_add); v_pixel4.val[i] = vaddq_u8(v_pixel, v_pred); v_left = vextq_u8(v_pixel4.val[i], v_pixel4.val[i], 12); }) v_pixel = jebp__neon_flatten_px4(v_pixel4); vst1q_u8((uint8_t *)&pixel[x], v_pixel); v_tl = v_top; } #endif for (; x < width; x += 1) { pixel[x].r += JEBP__CLAMP_UBYTE(pixel[x - 1].r + top[x].r - top[x - 1].r); pixel[x].g += JEBP__CLAMP_UBYTE(pixel[x - 1].g + top[x].g - top[x - 1].g); pixel[x].b += JEBP__CLAMP_UBYTE(pixel[x - 1].b + top[x].b - top[x - 1].b); pixel[x].a += JEBP__CLAMP_UBYTE(pixel[x - 1].a + top[x].a - top[x - 1].a); } } static void jebp__vp8l_pred13(jebp_color_t *pixel, jebp_color_t *top, jebp_int width) { jebp_int x = 0; #if defined(JEBP__SIMD_SSE2) __m128i v_mask = _mm_set1_epi8(0x7f); __m128i v_left; __m128i v_tl; if (width >= 4) { int v_left_i, v_tl_i; memcpy(&v_left_i, &pixel[-1], sizeof(int)); memcpy(&v_tl_i, &top[-1], sizeof(int)); v_left = _mm_cvtsi32_si128(v_left_i); v_tl = _mm_cvtsi32_si128(v_tl_i); } for (; x + 4 <= width; x += 4) { __m128i v_pixel = _mm_loadu_si128((__m128i *)&pixel[x]); __m128i v_top = _mm_loadu_si128((__m128i *)&top[x]); __m128i v_rot = _mm_shuffle_epi32(v_top, _MM_SHUFFLE(2, 1, 0, 3)); v_tl = jebp__sse_move_px1(v_rot, v_tl); jebp__m128x4i v_pixel4; JEBP__UNROLL4(jebp_int i, { __m128i v_avg = jebp__sse_avg_u8x16(v_left, v_top); __m128i v_max = _mm_max_epu8(v_avg, v_tl); __m128i v_min = _mm_min_epu8(v_avg, v_tl); __m128i v_diff = _mm_sub_epi8(v_max, v_min); v_diff = _mm_srli_epi16(v_diff, 1); v_diff = _mm_and_si128(v_diff, v_mask); __m128i v_pos = _mm_cmpeq_epi8(v_max, v_avg); __m128i v_add = _mm_adds_epu8(v_avg, v_diff); __m128i v_sub = _mm_subs_epu8(v_avg, v_diff); v_pixel4.v[i] = jebp__sse_bsela_u8x16(v_pixel, v_pos, v_add, v_sub); v_left = _mm_shuffle_epi32(v_pixel4.v[i], _MM_SHUFFLE(2, 1, 0, 3)); }) v_pixel = jebp__sse_flatten_px4(v_pixel4); _mm_storeu_si128((__m128i *)&pixel[x], v_pixel); v_tl = v_rot; } #elif defined(JEBP__SIMD_NEON) uint8x16_t v_left; uint8x16_t v_tl; if (width >= 4) { v_left = jebp__neon_load_px1(&pixel[-1]); v_tl = jebp__neon_load_px1(&top[-1]); } for (; x + 4 <= width; x += 4) { uint8x16_t v_pixel = vld1q_u8((uint8_t *)&pixel[x]); uint8x16_t v_top = vld1q_u8((uint8_t *)&top[x]); v_tl = vextq_u8(v_tl, v_top, 12); uint8x16x4_t v_pixel4; JEBP__UNROLL4(jebp_int i, { uint8x16_t v_avg = vhaddq_u8(v_left, v_top); uint8x16_t v_diff = vabdq_u8(v_avg, v_tl); v_diff = vshrq_n_u8(v_diff, 1); uint8x16_t v_neg = vcltq_u8(v_avg, v_tl); uint8x16_t v_add = vqaddq_u8(v_avg, v_diff); uint8x16_t v_sub = vqsubq_u8(v_avg, v_diff); uint8x16_t v_pred = vbslq_u8(v_neg, v_sub, v_add); v_pixel4.val[i] = vaddq_u8(v_pixel, v_pred); v_left = vextq_u8(v_pixel4.val[i], v_pixel4.val[i], 12); }) v_pixel = jebp__neon_flatten_px4(v_pixel4); vst1q_u8((uint8_t *)&pixel[x], v_pixel); v_tl = v_top; } #endif for (; x < width; x += 1) { jebp_color_t avg = {JEBP__FAVG(pixel[x - 1].r, top[x].r), JEBP__FAVG(pixel[x - 1].g, top[x].g), JEBP__FAVG(pixel[x - 1].b, top[x].b), JEBP__FAVG(pixel[x - 1].a, top[x].a)}; pixel[x].r += JEBP__CLAMP_UBYTE(avg.r + (avg.r - top[x - 1].r) / 2); pixel[x].g += JEBP__CLAMP_UBYTE(avg.g + (avg.g - top[x - 1].g) / 2); pixel[x].b += JEBP__CLAMP_UBYTE(avg.b + (avg.b - top[x - 1].b) / 2); pixel[x].a += JEBP__CLAMP_UBYTE(avg.a + (avg.a - top[x - 1].a) / 2); } } static const jebp__vp8l_pred_t jebp__vp8l_preds[JEBP__NB_VP8L_PRED_TYPES] = { jebp__vp8l_pred0, jebp__vp8l_pred1, jebp__vp8l_pred2, jebp__vp8l_pred3, jebp__vp8l_pred4, jebp__vp8l_pred5, jebp__vp8l_pred6, jebp__vp8l_pred7, jebp__vp8l_pred8, jebp__vp8l_pred9, jebp__vp8l_pred10, jebp__vp8l_pred11, jebp__vp8l_pred12, jebp__vp8l_pred13}; /** * VP8L transforms */ typedef enum jebp__transform_type_t { JEBP__TRANSFORM_PREDICT, JEBP__TRANSFORM_COLOR, JEBP__TRANSFORM_GREEN, JEBP__TRANSFORM_PALETTE, JEBP__NB_TRANSFORMS } jebp__transform_type_t; typedef struct jebp__transform_t { jebp__transform_type_t type; jebp__subimage_t image; } jebp__transform_t; static jebp_error_t jebp__read_transform(jebp__transform_t *transform, jebp__bit_reader_t *bits, jebp_image_t *image, jebp_int *types_seen) { jebp_error_t err = JEBP_OK; jebp_int type_bit; transform->type = jebp__read_bits(bits, 2, &err); if (err != JEBP_OK) { return err; } type_bit = 1 << transform->type; if ((*types_seen & type_bit) != 0) { return JEBP_ERROR_INVDATA; } *types_seen |= type_bit; if (transform->type == JEBP__TRANSFORM_PALETTE) { err = jebp__read_palette(&transform->image, bits, image); } else if (transform->type != JEBP__TRANSFORM_GREEN) { err = jebp__read_subimage(&transform->image, bits, image); } return err; } static void jebp__free_transform(jebp__transform_t *transform) { if (transform->type != JEBP__TRANSFORM_GREEN) { jebp_free_image(&transform->image.s); } } JEBP__INLINE jebp_error_t jebp__apply_predict_row(jebp_color_t *pixel, jebp_color_t *top, jebp_int width, jebp_color_t *predict_pixel) { if (predict_pixel->g >= JEBP__NB_VP8L_PRED_TYPES) { return JEBP_ERROR_INVDATA; } jebp__vp8l_preds[predict_pixel->g](pixel, top, width); return JEBP_OK; } JEBP__INLINE jebp_error_t jebp__apply_predict_transform( jebp_image_t *image, jebp__subimage_t *predict_image) { jebp_error_t err; jebp_color_t *pixel = image->pixels; jebp_color_t *top = pixel; jebp_int predict_width = predict_image->s.width - 1; jebp_int block_size = 1 << predict_image->block_bits; jebp_int end_size = image->width - (predict_width << predict_image->block_bits); if (predict_width == 0) { // Special case: if there is only one block the first block which is // shortened by one pixel (due to the left prediction) // needs to be `end_size` and the proper end block then // needs to be skipped. block_size = end_size; end_size = 0; } // Use opaque-black prediction for the top-left pixel jebp__vp8l_pred_black(pixel, 1); // Use left prediction for the top row jebp__vp8l_pred_left(pixel + 1, image->width - 1); pixel += image->width; for (jebp_int y = 1; y < image->height; y += 1) { jebp_color_t *predict_row = &predict_image->s.pixels[(y >> predict_image->block_bits) * predict_image->s.width]; // Use top prediction for the left column jebp__vp8l_pred_top(pixel, top, 1); // Finish the rest of the first block if ((err = jebp__apply_predict_row(pixel + 1, top + 1, block_size - 1, predict_row)) != JEBP_OK) { return err; } pixel += block_size; top += block_size; for (jebp_int x = 1; x < predict_width; x += 1) { if ((err = jebp__apply_predict_row(pixel, top, block_size, &predict_row[x])) != JEBP_OK) { return err; } pixel += block_size; top += block_size; } jebp__apply_predict_row(pixel, top, end_size, &predict_row[predict_width]); pixel += end_size; top += end_size; } return JEBP_OK; } JEBP__INLINE void jebp__apply_color_row(jebp_color_t *pixel, jebp_int width, jebp_color_t *color_pixel) { jebp_int x = 0; #if defined(JEBP__SIMD_SSE2) jebp_ushort color_r = ((jebp_short)(color_pixel->r << 8) >> 5); jebp_ushort color_g = ((jebp_short)(color_pixel->g << 8) >> 5); jebp_ushort color_b = ((jebp_short)(color_pixel->b << 8) >> 5); __m128i v_color_bg = _mm_set1_epi32(color_b | ((jebp_uint)color_g << 16)); __m128i v_color_r = _mm_set1_epi32(color_r); __m128i v_masklo = _mm_set1_epi16((short)0x00ff); __m128i v_maskhi = _mm_set1_epi16((short)0xff00); for (; x + 4 <= width; x += 4) { __m128i v_pixel = _mm_loadu_si128((__m128i *)&pixel[x]); __m128i v_green = _mm_and_si128(v_pixel, v_maskhi); v_green = _mm_shufflelo_epi16(v_green, _MM_SHUFFLE(2, 2, 0, 0)); v_green = _mm_shufflehi_epi16(v_green, _MM_SHUFFLE(2, 2, 0, 0)); __m128i v_bg = _mm_mulhi_epi16(v_green, v_color_bg); v_bg = _mm_and_si128(v_bg, v_masklo); v_pixel = _mm_add_epi8(v_pixel, v_bg); __m128i v_red = _mm_slli_epi16(v_pixel, 8); v_red = _mm_mulhi_epi16(v_red, v_color_r); v_red = _mm_and_si128(v_red, v_masklo); v_red = _mm_slli_epi32(v_red, 16); v_pixel = _mm_add_epi8(v_pixel, v_red); _mm_storeu_si128((__m128i *)&pixel[x], v_pixel); } #elif defined(JEBP__SIMD_NEON) int8x8x3_t v_color_pixel = vld3_dup_s8((jebp_byte *)color_pixel); for (; x + 8 <= width; x += 8) { int16x8_t v_mul; int8x8_t v_shr; int8x8x4_t v_pixel = vld4_s8((jebp_byte *)&pixel[x]); v_mul = vmull_s8(v_pixel.val[1], v_color_pixel.val[2]); v_shr = vshrn_n_s16(v_mul, 5); v_pixel.val[0] = vadd_s8(v_pixel.val[0], v_shr); v_mul = vmull_s8(v_pixel.val[1], v_color_pixel.val[1]); v_shr = vshrn_n_s16(v_mul, 5); v_pixel.val[2] = vadd_s8(v_pixel.val[2], v_shr); v_mul = vmull_s8(v_pixel.val[0], v_color_pixel.val[0]); v_shr = vshrn_n_s16(v_mul, 5); v_pixel.val[2] = vadd_s8(v_pixel.val[2], v_shr); vst4_s8((jebp_byte *)&pixel[x], v_pixel); } #endif for (; x < width; x += 1) { pixel[x].r += ((jebp_byte)pixel[x].g * (jebp_byte)color_pixel->b) >> 5; pixel[x].b += ((jebp_byte)pixel[x].g * (jebp_byte)color_pixel->g) >> 5; pixel[x].b += ((jebp_byte)pixel[x].r * (jebp_byte)color_pixel->r) >> 5; } } JEBP__INLINE jebp_error_t jebp__apply_color_transform( jebp_image_t *image, jebp__subimage_t *color_image) { jebp_color_t *pixel = image->pixels; jebp_int color_width = color_image->s.width - 1; jebp_int block_size = 1 << color_image->block_bits; jebp_int end_size = image->width - (color_width << color_image->block_bits); for (jebp_int y = 0; y < image->height; y += 1) { jebp_color_t *color_row = &color_image->s .pixels[(y >> color_image->block_bits) * color_image->s.width]; for (jebp_int x = 0; x < color_width; x += 1) { jebp__apply_color_row(pixel, block_size, &color_row[x]); pixel += block_size; } jebp__apply_color_row(pixel, end_size, &color_row[color_width]); pixel += end_size; } return JEBP_OK; } JEBP__INLINE jebp_error_t jebp__apply_green_transform(jebp_image_t *image) { jebp_int size = image->width * image->height; jebp_int i = 0; #if defined(JEBP__SIMD_SSE2) for (; i + 4 <= size; i += 4) { __m128i *pixel = (__m128i *)&image->pixels[i]; __m128i v_pixel = _mm_loadu_si128(pixel); __m128i v_green = _mm_srli_epi16(v_pixel, 8); v_green = _mm_shufflelo_epi16(v_green, _MM_SHUFFLE(2, 2, 0, 0)); v_green = _mm_shufflehi_epi16(v_green, _MM_SHUFFLE(2, 2, 0, 0)); v_pixel = _mm_add_epi8(v_pixel, v_green); _mm_storeu_si128(pixel, v_pixel); } #elif defined(JEBP__SIMD_NEON) for (; i + 16 <= size; i += 16) { jebp_ubyte *pixel = (jebp_ubyte *)&image->pixels[i]; uint8x16x4_t v_pixel = vld4q_u8(pixel); v_pixel.val[0] = vaddq_u8(v_pixel.val[0], v_pixel.val[1]); v_pixel.val[2] = vaddq_u8(v_pixel.val[2], v_pixel.val[1]); vst4q_u8(pixel, v_pixel); } #endif for (; i < size; i += 1) { jebp_color_t *pixel = &image->pixels[i]; pixel->r += pixel->g; pixel->b += pixel->g; } return JEBP_OK; } JEBP__INLINE jebp_error_t jebp__apply_palette_transform( jebp_image_t *image, jebp__subimage_t *palette_image, jebp_int real_width) { jebp_int palette_size = palette_image->s.width; if (palette_size > 16) { jebp_int i, size = image->width * image->height; for (i = 0; i < size; i++) { jebp_color_t *pixel = &image->pixels[i]; jebp_int idx = pixel->g; if (idx < palette_size) { *pixel = palette_image->s.pixels[idx]; } else { return JEBP_ERROR_INVDATA; } } } else { jebp_int x, y, width = image->width, height = image->height; jebp_int shift, shift_back, mask, mask_back; if (palette_size <= 2) { shift = 3; } else if (palette_size <= 4) { shift = 2; } else { shift = 1; } mask = (1 << shift) - 1; shift_back = 8 >> shift; mask_back = (1 << shift_back) - 1; for (y = height - 1; y >= 0; y--) { jebp_int real_row = y * real_width, row = y * width; for (x = real_width - 1; x >= 0; x--) { jebp_color_t *dst = &image->pixels[real_row + x]; jebp_color_t *src = &image->pixels[row + (x >> shift)]; jebp_int shift_x = (x & mask) * shift_back; jebp_int idx = (src->g & (mask_back << shift_x)) >> shift_x; if (idx < palette_size) { *dst = palette_image->s.pixels[idx]; } else { return JEBP_ERROR_INVDATA; } } } image->width = real_width; } return JEBP_OK; } static jebp_error_t jebp__apply_transform(jebp__transform_t *transform, jebp_image_t *image, jebp_int real_width) { switch (transform->type) { case JEBP__TRANSFORM_PREDICT: return jebp__apply_predict_transform(image, &transform->image); case JEBP__TRANSFORM_COLOR: return jebp__apply_color_transform(image, &transform->image); case JEBP__TRANSFORM_GREEN: return jebp__apply_green_transform(image); case JEBP__TRANSFORM_PALETTE: return jebp__apply_palette_transform(image, &transform->image, real_width); default: return JEBP_ERROR_NOSUP; } } /** * VP8L lossless codec */ #define JEBP__VP8L_TAG 0x4c385056 #define JEBP__VP8L_MAGIC 0x2f static jebp_error_t jebp__read_vp8l_header(jebp_image_t *image, jebp__reader_t *reader, jebp__bit_reader_t *bits, jebp__chunk_t *chunk) { jebp_error_t err = JEBP_OK; if (chunk->size < 5) { return JEBP_ERROR_INVDATA_HEADER; } if (jebp__read_uint8(reader, &err) != JEBP__VP8L_MAGIC) { return jebp__error(&err, JEBP_ERROR_INVDATA_HEADER); } jepb__init_bit_reader(bits, reader, chunk->size - 1); image->width = jebp__read_bits(bits, 14, &err) + 1; image->height = jebp__read_bits(bits, 14, &err) + 1; jebp__read_bits(bits, 1, &err); // alpha does not impact decoding if (jebp__read_bits(bits, 3, &err) != 0) { // version must be 0 return jebp__error(&err, JEBP_ERROR_NOSUP); } return err; } static jebp_error_t jebp__read_vp8l_size(jebp_image_t *image, jebp__reader_t *reader, jebp__chunk_t *chunk) { jebp__bit_reader_t bits; return jebp__read_vp8l_header(image, reader, &bits, chunk); } static jebp_error_t jebp__read_vp8l_nohead(jebp_image_t *image, jebp__bit_reader_t *bits) { jebp_error_t err = JEBP_OK; jebp__transform_t transforms[4]; jebp_int nb_transforms = 0; jebp_int real_width = image->width; jebp_int transforms_seen = 0; for (; nb_transforms <= JEBP__NB_TRANSFORMS; nb_transforms += 1) { if (!jebp__read_bits(bits, 1, &err)) { // no more transforms to read break; } if (err != JEBP_OK || nb_transforms == JEBP__NB_TRANSFORMS) { // too many transforms jebp__error(&err, JEBP_ERROR_INVDATA); goto free_transforms; } if ((err = jebp__read_transform(&transforms[nb_transforms], bits, image, &transforms_seen)) != JEBP_OK) { goto free_transforms; } } if (err != JEBP_OK) { goto free_transforms; } jebp__colcache_t colcache; if ((err = jebp__read_colcache(&colcache, bits)) != JEBP_OK) { goto free_transforms; } jebp__subimage_t *huffman_image = &(jebp__subimage_t){0}; if (!jebp__read_bits(bits, 1, &err)) { // there is no huffman image huffman_image = NULL; } if (err != JEBP_OK) { jebp__free_colcache(&colcache); goto free_transforms; } if (huffman_image != NULL) { if ((err = jebp__read_subimage(huffman_image, bits, image)) != JEBP_OK) { jebp__free_colcache(&colcache); goto free_transforms; } } err = jebp__read_vp8l_image(image, bits, &colcache, huffman_image, real_width); jebp__free_colcache(&colcache); jebp_free_image((jebp_image_t *)huffman_image); free_transforms: for (nb_transforms -= 1; nb_transforms >= 0; nb_transforms -= 1) { if (err == JEBP_OK) { err = jebp__apply_transform(&transforms[nb_transforms], image, real_width); } jebp__free_transform(&transforms[nb_transforms]); } return err; } static jebp_error_t jebp__read_vp8l(jebp_image_t *image, jebp__reader_t *reader, jebp__chunk_t *chunk) { jebp_error_t err; jebp__bit_reader_t bits; if ((err = jebp__read_vp8l_header(image, reader, &bits, chunk)) != JEBP_OK) { return err; } if ((err = jebp__read_vp8l_nohead(image, &bits)) != JEBP_OK) { return err; } return JEBP_OK; } #endif // JEBP_NO_VP8L /** * VP8X image */ #ifndef JEBP_NO_VP8X #define JEBP__VP8X_TAG 0x58385056 #define JEBP__ICCP_TAG 0x50434349 #define JEBP__ALPH_TAG 0x48504c41 #define JEBP__VP8X_FLAG_ANIM (1 << 1) #define JEBP__VP8X_FLAG_ALPH (1 << 4) #define JEBP__VP8X_FLAG_ICCP (1 << 5) typedef struct jebp__vp8x_header_t { jebp_uint flags; } jebp__vp8x_header_t; static void jebp__init_vp8x_header(jebp__vp8x_header_t *hdr) { JEBP__CLEAR(hdr, sizeof(jebp__vp8x_header_t)); } static jebp_error_t jebp__read_vp8x_header(jebp__vp8x_header_t *hdr, jebp_image_t *image, jebp__reader_t *reader, jebp__chunk_t *chunk) { jebp_error_t err = JEBP_OK; if (chunk->size != 10) { return jebp__error(&err, JEBP_ERROR_INVDATA_HEADER); } hdr->flags = jebp__read_uint32(reader, &err); if ((hdr->flags & JEBP__VP8X_FLAG_ANIM) != 0) { return jebp__error(&err, JEBP_ERROR_NOSUP); } image->width = jebp__read_uint24(reader, &err) + 1; image->height = jebp__read_uint24(reader, &err) + 1; if (image->width > 0xffffffffL / image->height) { return jebp__error(&err, JEBP_ERROR_INVDATA); } return err; } static jebp_error_t jebp__read_vp8x_size(jebp_image_t *image, jebp__reader_t *reader, jebp__chunk_t *chunk) { jebp__vp8x_header_t hdr; jebp__init_vp8x_header(&hdr); return jebp__read_vp8x_header(&hdr, image, reader, chunk); } static void jebp__skip_vp8x_iccp(jebp__riff_reader_t *riff, jebp_error_t *err, jebp_uint flags) { jebp__chunk_t chunk; jebp_uint i; if ((flags & JEBP__VP8X_FLAG_ICCP) == 0 || *err != JEBP_OK) { return; } if ((*err = jebp__read_riff_chunk(riff, &chunk)) != JEBP_OK) { return; } if (chunk.tag == JEBP__ICCP_TAG) { for (i = 0; i < chunk.size; i++) { jebp__read_uint8(riff->reader, err); } } else { *err = JEBP_ERROR_INVDATA; } } static jebp_ubyte *jebp__read_vp8x_alpha(jebp__riff_reader_t *riff, jebp_error_t *err, jebp_uint flags, jebp_image_t *canvas, jebp_int *osize, jebp_int *ostep) { jebp__chunk_t chunk; jebp_uint aflags, filter, compression; if ((flags & JEBP__VP8X_FLAG_ALPH) == 0 || *err != JEBP_OK) { return NULL; } if ((*err = jebp__read_riff_chunk(riff, &chunk)) != JEBP_OK) { return NULL; } if (chunk.tag != JEBP__ALPH_TAG || chunk.size < 2) { *err = JEBP_ERROR_INVDATA; return NULL; } aflags = jebp__read_uint8(riff->reader, err); compression = (aflags) & 3; filter = (aflags >> 2) & 3; if (compression > 1) { *err = JEBP_ERROR_NOSUP; return NULL; } if (filter) { *err = JEBP_ERROR_NOSUP; /* TODO */ return NULL; } if (compression) { #ifndef JEBP_NO_VP8L jebp__bit_reader_t bits; jebp_image_t uncompress = *canvas; uncompress.pixels = NULL; jepb__init_bit_reader(&bits, riff->reader, chunk.size - 1); if ((*err = jebp__read_vp8l_nohead(&uncompress, &bits)) != JEBP_OK) { return NULL; } *osize = uncompress.width * uncompress.height; *ostep = 4; return (jebp_ubyte *)uncompress.pixels; #else *err = JEBP_ERROR_NOSUP; return NULL; #endif // JEBP_NO_VP8L } jebp_ubyte *alpha; *osize = chunk.size - 1; *ostep = 1; if ((alpha = JEBP_ALLOC(*osize)) == NULL) { *err = JEBP_ERROR_NOMEM; return NULL; } if ((*err = jebp__read_bytes(riff->reader, *osize, alpha)) != JEBP_OK) { JEBP_FREE(alpha); return NULL; } return alpha; } static jebp_error_t jebp__read_vp8x(jebp_image_t *image, jebp__reader_t *reader, jebp__chunk_t *vp8x_chunk, jebp__riff_reader_t *riff) { jebp_error_t err; jebp__vp8x_header_t hdr; jebp_uint flags; jebp_ubyte *alpha; jebp__chunk_t chunk; jebp_int asize, astep; jebp__init_vp8x_header(&hdr); err = jebp__read_vp8x_header(&hdr, image, reader, vp8x_chunk); flags = hdr.flags; jebp__skip_vp8x_iccp(riff, &err, flags); if (err != JEBP_OK) { return err; } alpha = jebp__read_vp8x_alpha(riff, &err, flags, image, &asize, &astep); if (err != JEBP_OK) { return err; } if ((err = jebp__read_riff_chunk(riff, &chunk)) != JEBP_OK) { goto free_alpha; } switch (chunk.tag) { #ifndef JEBP_NO_VP8 case JEBP__VP8_TAG: err = jebp__read_vp8(image, reader, &chunk); if (err == JEBP_OK && alpha != NULL) { jebp_uint i, j, len; len = JEBP__MIN(image->width * image->height, asize); /* if astep is 4, start with offset 1 */ for (i = 0, j = astep == 4; i < len; i++, j += astep) { image->pixels[i].a = alpha[j]; } } break; #endif // JEBP_NO_VP8 #ifndef JEBP_NO_VP8L case JEBP__VP8L_TAG: err = jebp__read_vp8l(image, reader, &chunk); break; #endif // JEBP_NO_VP8L default: err = JEBP_ERROR_NOSUP_CODEC; } free_alpha: if (alpha != NULL) { JEBP_FREE(alpha); } return err; } #endif // JEBP_NO_VP8X /** * Public API */ static const char *const jebp__error_strings[JEBP_NB_ERRORS]; const char *jebp_error_string(jebp_error_t err) { if (err < 0 || err >= JEBP_NB_ERRORS) { err = JEBP_ERROR_UNKNOWN; } return jebp__error_strings[err]; } void jebp_free_image(jebp_image_t *image) { if (image != NULL) { JEBP_FREE(image->pixels); JEBP__CLEAR(image, sizeof(jebp_image_t)); } } static jebp_error_t jebp__read_size(jebp_image_t *image, jebp__reader_t *reader) { jebp_error_t err; jebp__riff_reader_t riff; JEBP__CLEAR(image, sizeof(jebp_image_t)); if ((err = jebp__read_riff_header(&riff, reader)) != JEBP_OK) { return err; } jebp__chunk_t chunk; if ((err = jebp__read_riff_chunk(&riff, &chunk)) != JEBP_OK) { return err; } switch (chunk.tag) { #ifndef JEBP_NO_VP8 case JEBP__VP8_TAG: return jebp__read_vp8_size(image, reader, &chunk); #endif // JEBP_NO_VP8 #ifndef JEBP_NO_VP8L case JEBP__VP8L_TAG: return jebp__read_vp8l_size(image, reader, &chunk); #endif // JEBP_NO_VP8L #ifndef JEBP_NO_VP8X case JEBP__VP8X_TAG: return jebp__read_vp8x_size(image, reader, &chunk); #endif // JEBP_NO_VP8X default: return JEBP_ERROR_NOSUP_CODEC; } } jebp_error_t jebp_decode_size(jebp_image_t *image, size_t size, const void *data) { if (image == NULL || data == NULL) { return JEBP_ERROR_INVAL; } jebp__reader_t reader; jebp__init_memory(&reader, size, data); return jebp__read_size(image, &reader); } static jebp_error_t jebp__read(jebp_image_t *image, jebp__reader_t *reader) { jebp_error_t err; jebp__riff_reader_t riff; JEBP__CLEAR(image, sizeof(jebp_image_t)); if ((err = jebp__read_riff_header(&riff, reader)) != JEBP_OK) { return err; } jebp__chunk_t chunk; if ((err = jebp__read_riff_chunk(&riff, &chunk)) != JEBP_OK) { return err; } switch (chunk.tag) { #ifndef JEBP_NO_VP8 case JEBP__VP8_TAG: return jebp__read_vp8(image, reader, &chunk); #endif // JEBP_NO_VP8 #ifndef JEBP_NO_VP8L case JEBP__VP8L_TAG: return jebp__read_vp8l(image, reader, &chunk); #endif // JEBP_NO_VP8L #ifndef JEBP_NO_VP8X case JEBP__VP8X_TAG: return jebp__read_vp8x(image, reader, &chunk, &riff); #endif // JEBP_NO_VP8X default: return JEBP_ERROR_NOSUP_CODEC; } } jebp_error_t jebp_decode(jebp_image_t *image, size_t size, const void *data) { if (image == NULL || data == NULL) { return JEBP_ERROR_INVAL; } jebp__reader_t reader; jebp__init_memory(&reader, size, data); return jebp__read(image, &reader); } #ifndef JEBP_NO_CALLBACKS jebp_error_t jebp_read_size_from_callbacks(jebp_image_t *image, const jebp_io_callbacks *cb, void *user) { jebp_error_t err; if (image == NULL || cb == NULL) { return JEBP_ERROR_INVAL; } jebp__reader_t reader; if ((err = jebp__init_callbacks(&reader, cb, user)) != JEBP_OK) { return err; } err = jebp__read_size(image, &reader); JEBP_FREE(reader.buffer); return err; } jebp_error_t jebp_read_from_callbacks(jebp_image_t *image, const jebp_io_callbacks *cb, void *user) { jebp_error_t err; if (image == NULL || cb == NULL) { return JEBP_ERROR_INVAL; } jebp__reader_t reader; if ((err = jebp__init_callbacks(&reader, cb, user)) != JEBP_OK) { return err; } err = jebp__read(image, &reader); JEBP_FREE(reader.buffer); return err; } #ifndef JEBP_NO_STDIO size_t jebp__stdio_read(void *data, size_t n, void *user) { return fread(data, 1, n, (FILE *)user); } int jebp__stdio_check_error(void *user) { return ferror((FILE *)user); } static const jebp_io_callbacks jebp__stdio_callbacks = { jebp__stdio_read, jebp__stdio_check_error }; jebp_error_t jebp_read_size(jebp_image_t *image, const char *path) { jebp_error_t err; if (image == NULL || path == NULL) { return JEBP_ERROR_INVAL; } FILE *file = fopen(path, "rb"); if (file == NULL) { return JEBP_ERROR_IO; } err = jebp_read_size_from_callbacks(image, &jebp__stdio_callbacks, file); fclose(file); return err; } jebp_error_t jebp_read(jebp_image_t *image, const char *path) { jebp_error_t err; if (image == NULL || path == NULL) { return JEBP_ERROR_INVAL; } FILE *file = fopen(path, "rb"); if (file == NULL) { return JEBP_ERROR_IO; } err = jebp_read_from_callbacks(image, &jebp__stdio_callbacks, file); fclose(file); return err; } #endif // JEBP_NO_STDIO #endif // JEBP_NO_CALLBACKS /** * Lookup tables */ // These are moved to the end of the file since some of them are very large and // putting them in the middle of the code would disrupt the flow of reading. // Especially since in most situations the values in these tables are // unimportant to the developer. #ifndef JEBP_NO_VP8 // Lookup table mapping quantizer indices to DC values static const jebp_short jebp__dc_quant_table[JEBP__NB_QUANT_INDEXES] = { 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 91, 93, 95, 96, 98, 100, 101, 102, 104, 106, 108, 110, 112, 114, 116, 118, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 143, 145, 148, 151, 154, 157}; // Lookup table mapping quantizer indices to AC values static const jebp_short jebp__ac_quant_table[JEBP__NB_QUANT_INDEXES] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 119, 122, 125, 128, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 161, 164, 167, 170, 173, 177, 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 234, 239, 245, 249, 254, 259, 264, 269, 274, 279, 284}; // Default token probabilities static const jebp_ubyte jebp__default_token_probs [JEBP__NB_BLOCK_TYPES][JEBP__NB_COEFF_BANDS][JEBP__NB_TOKEN_COMPLEXITIES] [JEBP__NB_PROBS(JEBP__NB_TOKENS)] = { {{{128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, {128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, {128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}}, {{253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128}, {189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128}, {106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128}}, {{1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128}, {181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128}, {78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128}}, {{1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128}, {184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128}, {77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128}}, {{1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128}, {170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128}, {37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128}}, {{1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128}, {207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128}, {102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128}}, {{1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128}, {177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128}, {80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128}}, {{1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, {246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, {255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}}}, {{{198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62}, {131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1}, {68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128}}, {{1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128}, {184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128}, {81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128}}, {{1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128}, {99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128}, {23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128}}, {{1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128}, {109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128}, {44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128}}, {{1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128}, {94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128}, {22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128}}, {{1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128}, {124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128}, {35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128}}, {{1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128}, {121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128}, {45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128}}, {{1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128}, {203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128}, {137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128}}}, {{{253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128}, {175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128}, {73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128}}, {{1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128}, {239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128}, {155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128}}, {{1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128}, {201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128}, {69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128}}, {{1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128}, {223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128}, {141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128}}, {{1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128}, {190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128}, {149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}}, {{1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128}, {247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128}, {240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128}}, {{1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128}, {213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128}, {55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128}}, {{128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, {128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, {128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}}}, {{{202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255}, {126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128}, {61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128}}, {{1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128}, {166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128}, {39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128}}, {{1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128}, {124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128}, {24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128}}, {{1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128}, {149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128}, {28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128}}, {{1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128}, {123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128}, {20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128}}, {{1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128}, {168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128}, {47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128}}, {{1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128}, {141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128}, {42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128}}, {{1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, {244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, {238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}}}}; // Probabilities to update specific token static const jebp_ubyte jebp__update_token_probs [JEBP__NB_BLOCK_TYPES][JEBP__NB_COEFF_BANDS][JEBP__NB_TOKEN_COMPLEXITIES] [JEBP__NB_PROBS(JEBP__NB_TOKENS)] = { {{{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}, {{176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255}, {249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255}, {234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255}, {250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255}, {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}}, {{{217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255}, {234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255}}, {{255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255}}, {{255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255}, {250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}}, {{{186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255}, {234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255}, {251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255}}, {{255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255}}, {{255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}}, {{{248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255}, {248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255}}, {{255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255}, {246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255}, {252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255}}, {{255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255}, {248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255}, {253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255}}, {{255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255}, {252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255}, {250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}, {{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}}}; // The decoding tree for the segment ID static const jebp_byte jebp__segment_tree[JEBP__NB_TREE(JEBP__NB_SEGMENTS)] = { 2, 4, -0, -1, -2, -3}; // The decoding tree for the Y prediction mode static const jebp_byte jebp__y_pred_tree[JEBP__NB_TREE(JEBP__NB_Y_PRED_TYPES)] = {-JEBP__VP8_PRED_B, 2, 4, 6, -JEBP__VP8_PRED_DC, -JEBP__VP8_PRED_V, -JEBP__VP8_PRED_H, -JEBP__VP8_PRED_TM}; // The fixed probabilities for the Y prediction mode static const jebp_ubyte jebp__y_pred_probs[JEBP__NB_PROBS( JEBP__NB_Y_PRED_TYPES)] = {145, 156, 163, 128}; // The decoding tree for the Y subblock modes (when the prediction mode is B) static const jebp_byte jebp__b_pred_tree[JEBP__NB_TREE(JEBP__NB_B_PRED_TYPES)] = {-JEBP__B_PRED_DC, 2, -JEBP__B_PRED_TM, 4, -JEBP__B_PRED_VE, 6, 8, 12, -JEBP__B_PRED_HE, 10, -JEBP__B_PRED_RD, -JEBP__B_PRED_VR, -JEBP__B_PRED_LD, 14, -JEBP__B_PRED_VL, 16, -JEBP__B_PRED_HD, -JEBP__B_PRED_HU}; // The fixed probabilities for the Y subblock modes based on nearby subblock // modes static const jebp_ubyte jebp__b_pred_probs[JEBP__NB_B_PRED_TYPES][JEBP__NB_B_PRED_TYPES] [JEBP__NB_PROBS(JEBP__NB_B_PRED_TYPES)] = { {{231, 120, 48, 89, 115, 113, 120, 152, 112}, {152, 179, 64, 126, 170, 118, 46, 70, 95}, {175, 69, 143, 80, 85, 82, 72, 155, 103}, {56, 58, 10, 171, 218, 189, 17, 13, 152}, {144, 71, 10, 38, 171, 213, 144, 34, 26}, {114, 26, 17, 163, 44, 195, 21, 10, 173}, {121, 24, 80, 195, 26, 62, 44, 64, 85}, {170, 46, 55, 19, 136, 160, 33, 206, 71}, {63, 20, 8, 114, 114, 208, 12, 9, 226}, {81, 40, 11, 96, 182, 84, 29, 16, 36}}, {{134, 183, 89, 137, 98, 101, 106, 165, 148}, {72, 187, 100, 130, 157, 111, 32, 75, 80}, {66, 102, 167, 99, 74, 62, 40, 234, 128}, {41, 53, 9, 178, 241, 141, 26, 8, 107}, {104, 79, 12, 27, 217, 255, 87, 17, 7}, {74, 43, 26, 146, 73, 166, 49, 23, 157}, {65, 38, 105, 160, 51, 52, 31, 115, 128}, {87, 68, 71, 44, 114, 51, 15, 186, 23}, {47, 41, 14, 110, 182, 183, 21, 17, 194}, {66, 45, 25, 102, 197, 189, 23, 18, 22}}, {{88, 88, 147, 150, 42, 46, 45, 196, 205}, {43, 97, 183, 117, 85, 38, 35, 179, 61}, {39, 53, 200, 87, 26, 21, 43, 232, 171}, {56, 34, 51, 104, 114, 102, 29, 93, 77}, {107, 54, 32, 26, 51, 1, 81, 43, 31}, {39, 28, 85, 171, 58, 165, 90, 98, 64}, {34, 22, 116, 206, 23, 34, 43, 166, 73}, {68, 25, 106, 22, 64, 171, 36, 225, 114}, {34, 19, 21, 102, 132, 188, 16, 76, 124}, {62, 18, 78, 95, 85, 57, 50, 48, 51}}, {{193, 101, 35, 159, 215, 111, 89, 46, 111}, {60, 148, 31, 172, 219, 228, 21, 18, 111}, {112, 113, 77, 85, 179, 255, 38, 120, 114}, {40, 42, 1, 196, 245, 209, 10, 25, 109}, {100, 80, 8, 43, 154, 1, 51, 26, 71}, {88, 43, 29, 140, 166, 213, 37, 43, 154}, {61, 63, 30, 155, 67, 45, 68, 1, 209}, {142, 78, 78, 16, 255, 128, 34, 197, 171}, {41, 40, 5, 102, 211, 183, 4, 1, 221}, {51, 50, 17, 168, 209, 192, 23, 25, 82}}, {{125, 98, 42, 88, 104, 85, 117, 175, 82}, {95, 84, 53, 89, 128, 100, 113, 101, 45}, {75, 79, 123, 47, 51, 128, 81, 171, 1}, {57, 17, 5, 71, 102, 57, 53, 41, 49}, {115, 21, 2, 10, 102, 255, 166, 23, 6}, {38, 33, 13, 121, 57, 73, 26, 1, 85}, {41, 10, 67, 138, 77, 110, 90, 47, 114}, {101, 29, 16, 10, 85, 128, 101, 196, 26}, {57, 18, 10, 102, 102, 213, 34, 20, 43}, {117, 20, 15, 36, 163, 128, 68, 1, 26}}, {{138, 31, 36, 171, 27, 166, 38, 44, 229}, {67, 87, 58, 169, 82, 115, 26, 59, 179}, {63, 59, 90, 180, 59, 166, 93, 73, 154}, {40, 40, 21, 116, 143, 209, 34, 39, 175}, {57, 46, 22, 24, 128, 1, 54, 17, 37}, {47, 15, 16, 183, 34, 223, 49, 45, 183}, {46, 17, 33, 183, 6, 98, 15, 32, 183}, {65, 32, 73, 115, 28, 128, 23, 128, 205}, {40, 3, 9, 115, 51, 192, 18, 6, 223}, {87, 37, 9, 115, 59, 77, 64, 21, 47}}, {{104, 55, 44, 218, 9, 54, 53, 130, 226}, {64, 90, 70, 205, 40, 41, 23, 26, 57}, {54, 57, 112, 184, 5, 41, 38, 166, 213}, {30, 34, 26, 133, 152, 116, 10, 32, 134}, {75, 32, 12, 51, 192, 255, 160, 43, 51}, {39, 19, 53, 221, 26, 114, 32, 73, 255}, {31, 9, 65, 234, 2, 15, 1, 118, 73}, {88, 31, 35, 67, 102, 85, 55, 186, 85}, {56, 21, 23, 111, 59, 205, 45, 37, 192}, {55, 38, 70, 124, 73, 102, 1, 34, 98}}, {{102, 61, 71, 37, 34, 53, 31, 243, 192}, {69, 60, 71, 38, 73, 119, 28, 222, 37}, {68, 45, 128, 34, 1, 47, 11, 245, 171}, {62, 17, 19, 70, 146, 85, 55, 62, 70}, {75, 15, 9, 9, 64, 255, 184, 119, 16}, {37, 43, 37, 154, 100, 163, 85, 160, 1}, {63, 9, 92, 136, 28, 64, 32, 201, 85}, {86, 6, 28, 5, 64, 255, 25, 248, 1}, {56, 8, 17, 132, 137, 255, 55, 116, 128}, {58, 15, 20, 82, 135, 57, 26, 121, 40}}, {{164, 50, 31, 137, 154, 133, 25, 35, 218}, {51, 103, 44, 131, 131, 123, 31, 6, 158}, {86, 40, 64, 135, 148, 224, 45, 183, 128}, {22, 26, 17, 131, 240, 154, 14, 1, 209}, {83, 12, 13, 54, 192, 255, 68, 47, 28}, {45, 16, 21, 91, 64, 222, 7, 1, 197}, {56, 21, 39, 155, 60, 138, 23, 102, 213}, {85, 26, 85, 85, 128, 128, 32, 146, 171}, {18, 11, 7, 63, 144, 171, 4, 4, 246}, {35, 27, 10, 146, 174, 171, 12, 26, 128}}, {{190, 80, 35, 99, 180, 80, 126, 54, 45}, {85, 126, 47, 87, 176, 51, 41, 20, 32}, {101, 75, 128, 139, 118, 146, 116, 128, 85}, {56, 41, 15, 176, 236, 85, 37, 9, 62}, {146, 36, 19, 30, 171, 255, 97, 27, 20}, {71, 30, 17, 119, 118, 255, 17, 18, 138}, {101, 38, 60, 138, 55, 70, 43, 26, 142}, {138, 45, 61, 62, 219, 1, 81, 188, 64}, {32, 41, 20, 117, 151, 142, 20, 21, 163}, {112, 19, 12, 61, 195, 128, 48, 4, 24}}}; // The decoding tree for the UV prediction mode static const jebp_byte jebp__uv_pred_tree[JEBP__NB_TREE(JEBP__NB_UV_PRED_TYPES)] = { -JEBP__VP8_PRED_DC, 2, -JEBP__VP8_PRED_V, 4, -JEBP__VP8_PRED_H, -JEBP__VP8_PRED_TM}; // The fixed probabilities for the UV prediction mode static const jebp_ubyte jebp__uv_pred_probs[JEBP__NB_PROBS( JEBP__NB_UV_PRED_TYPES)] = {142, 114, 183}; // Which bands each coefficient goes into for token complexities static const jebp_byte jebp__coeff_bands[JEBP__NB_BLOCK_COEFFS] = { 0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7}; // The zig-zag order of the coefficients // [0]= 0 [1]= 1 [5]= 2 [6]= 3 // [2]= 4 [4]= 5 [7]= 6 [12]= 7 // [3]= 8 [8]= 9 [11]=10 [13]=11 // [9]=12 [10]=13 [14]=14 [15]=15 static const jebp_byte jebp__coeff_order[JEBP__NB_BLOCK_COEFFS] = { 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15}; // The fixed tree for token decoding, using the probabilities defined in the // header. This doesn't include the EOB branch at the start since that may be // skipped. static const jebp_byte jebp__token_tree[JEBP__NB_TREE(JEBP__NB_TOKENS - 1)] = { -JEBP__TOKEN_COEFF0, 2, -JEBP__TOKEN_COEFF1, 4, 6, 10, -JEBP__TOKEN_COEFF2, 8, -JEBP__TOKEN_COEFF3, -JEBP__TOKEN_COEFF4, 12, 14, -JEBP__TOKEN_EXTRA1, -JEBP__TOKEN_EXTRA2, 16, 18, -JEBP__TOKEN_EXTRA3, -JEBP__TOKEN_EXTRA4, -JEBP__TOKEN_EXTRA5, -JEBP__TOKEN_EXTRA6}; static const jebp__token_extra_t jebp__token_extra[JEBP__NB_EXTRA_TOKENS] = { {5, {159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {7, {165, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {11, {173, 148, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, {19, {176, 155, 140, 135, 0, 0, 0, 0, 0, 0, 0, 0}}, {35, {180, 157, 141, 134, 130, 0, 0, 0, 0, 0, 0, 0}}, {67, {254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0}}, }; #endif // JEBP_NO_VP8 #ifndef JEBP_NO_VP8L // The order that meta lengths are read static const jebp_byte jebp__meta_length_order[JEBP__NB_META_SYMBOLS] = { 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; // {X, Y} offsets from the pixel when decoding short distance codes static const jebp_byte jebp__vp8l_offsets[JEBP__NB_VP8L_OFFSETS][2] = { {0, 1}, {1, 0}, {1, 1}, {-1, 1}, {0, 2}, {2, 0}, {1, 2}, {-1, 2}, {2, 1}, {-2, 1}, {2, 2}, {-2, 2}, {0, 3}, {3, 0}, {1, 3}, {-1, 3}, {3, 1}, {-3, 1}, {2, 3}, {-2, 3}, {3, 2}, {-3, 2}, {0, 4}, {4, 0}, {1, 4}, {-1, 4}, {4, 1}, {-4, 1}, {3, 3}, {-3, 3}, {2, 4}, {-2, 4}, {4, 2}, {-4, 2}, {0, 5}, {3, 4}, {-3, 4}, {4, 3}, {-4, 3}, {5, 0}, {1, 5}, {-1, 5}, {5, 1}, {-5, 1}, {2, 5}, {-2, 5}, {5, 2}, {-5, 2}, {4, 4}, {-4, 4}, {3, 5}, {-3, 5}, {5, 3}, {-5, 3}, {0, 6}, {6, 0}, {1, 6}, {-1, 6}, {6, 1}, {-6, 1}, {2, 6}, {-2, 6}, {6, 2}, {-6, 2}, {4, 5}, {-4, 5}, {5, 4}, {-5, 4}, {3, 6}, {-3, 6}, {6, 3}, {-6, 3}, {0, 7}, {7, 0}, {1, 7}, {-1, 7}, {5, 5}, {-5, 5}, {7, 1}, {-7, 1}, {4, 6}, {-4, 6}, {6, 4}, {-6, 4}, {2, 7}, {-2, 7}, {7, 2}, {-7, 2}, {3, 7}, {-3, 7}, {7, 3}, {-7, 3}, {5, 6}, {-5, 6}, {6, 5}, {-6, 5}, {8, 0}, {4, 7}, {-4, 7}, {7, 4}, {-7, 4}, {8, 1}, {8, 2}, {6, 6}, {-6, 6}, {8, 3}, {5, 7}, {-5, 7}, {7, 5}, {-7, 5}, {8, 4}, {6, 7}, {-6, 7}, {7, 6}, {-7, 6}, {8, 5}, {7, 7}, {-7, 7}, {8, 6}, {8, 7}}; #endif // JEBP_NO_VP8L // Error strings to return from jebp_error_string static const char *const jebp__error_strings[JEBP_NB_ERRORS] = { "Ok", "Invalid value or argument", "Invalid data or corrupted file", "Invalid WebP header or corrupted file", "End of file", "Feature not supported", "Codec not supported", "Not enough memory", "I/O error", "Unknown error"}; #endif // JEBP_IMPLEMENTATION chawan-v0.4.0/adapter/img/jebp.nim000066400000000000000000000055401520232313100167570ustar00rootroot00000000000000{.push raises: [].} import std/posix import ../protocol/lcgi when sizeof(cint) < 4: type jebp_int = clong else: type jebp_int = cint {.passc: "-I" & currentSourcePath().untilLast('/').} {.push header: """ #define JEBP_NO_STDIO #define JEBP_IMPLEMENTATION #include "jebp.h" """.} type jebp_io_callbacks {.importc.} = object read: proc(data: pointer; size: csize_t; user: pointer): csize_t {.cdecl.} check_error: proc(user: pointer): cint {.cdecl.} jebp_error_t {.importc.} = cint jebp_color_t {.importc.} = object r: uint8 g: uint8 b: uint8 a: uint8 jebp_image_t {.importc.} = object width: jebp_int height: jebp_int pixels: ptr jebp_color_t proc jebp_read_from_callbacks(image: ptr jebp_image_t; cb: ptr jebp_io_callbacks; user: pointer): jebp_error_t {.importc.} proc jebp_read_size_from_callbacks(image: ptr jebp_image_t; cb: ptr jebp_io_callbacks; user: pointer): jebp_error_t {.importc.} proc jebp_error_string(err: jebp_error_t): cstring {.importc.} proc jebp_free_image(image: ptr jebp_image_t) {.importc.} {.pop.} # jebp.h proc myRead(data: pointer; size: csize_t; user: pointer): csize_t {.cdecl.} = var n = csize_t(0) while n < size: let i = read(STDIN_FILENO, addr cast[ptr UncheckedArray[char]](data)[n], int(size - n)) if i <= 0: break n += csize_t(i) return n proc writeAll(data: pointer; size: int) = var n = 0 let data = cast[ptr UncheckedArray[uint8]](data) while n < size: let i = write(STDOUT_FILENO, addr data[n], size - n) assert i >= 0 n += i proc puts(s: string) = if s.len > 0: writeAll(unsafeAddr s[0], s.len) proc main() = enterNetworkSandbox() let scheme = getEnvEmpty("MAPPED_URI_SCHEME") let f = scheme.after('+') if getEnvEmpty("MAPPED_URI_PATH") == "decode": if f != "webp": cgiDie(ceInternalError, "unknown format " & f) let headers = getEnvEmpty("REQUEST_HEADERS") var infoOnly = false for hdr in headers.split('\n'): let v = hdr.after(':').strip() if hdr.until(':').equalsIgnoreCase("Cha-Image-Info-Only"): infoOnly = v == "1" var image = jebp_image_t() var cb = jebp_io_callbacks(read: myRead) if infoOnly: let res = jebp_read_size_from_callbacks(addr image, addr cb, nil) if res == 0: puts("Cha-Image-Dimensions: " & $image.width & "x" & $image.height & "\n\n") quit(0) else: cgiDie(ceInternalError, jebp_error_string(res)) let res = jebp_read_from_callbacks(addr image, addr cb, nil) if res != 0: cgiDie(ceInternalError, jebp_error_string(res)) else: puts("Cha-Image-Dimensions: " & $image.width & "x" & $image.height & "\n\n") writeAll(image.pixels, image.width * image.height * 4) jebp_free_image(addr image) else: cgiDie(ceInternalError, "not implemented") main() {.pop.} # raises: [] chawan-v0.4.0/adapter/img/nanosvg.h000066400000000000000000002425751520232313100171710ustar00rootroot00000000000000/* * Copyright (c) 2013-14 Mikko Mononen memon@inside.org * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * * The SVG parser is based on Anti-Grain Geometry 2.4 SVG example * Copyright (C) 2002-2004 Maxim Shemanarev (McSeem) (http://www.antigrain.com/) * * Arc calculation code based on canvg (https://code.google.com/p/canvg/) * * Bounding box calculation based on http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html * * * This file has been modified for use in the Chawan project. * */ #ifndef NANOSVG_H #define NANOSVG_H #ifndef NANOSVG_CPLUSPLUS #ifdef __cplusplus extern "C" { #endif #endif // NanoSVG is a simple stupid single-header-file SVG parse. The output of the parser is a list of cubic bezier shapes. // // The library suits well for anything from rendering scalable icons in your editor application to prototyping a game. // // NanoSVG supports a wide range of SVG features, but something may be missing, feel free to create a pull request! // // The shapes in the SVG images are transformed by the viewBox and converted to specified units. // That is, you should get the same looking data as your designed in your favorite app. // // NanoSVG can return the paths in few different units. For example if you want to render an image, you may choose // to get the paths in pixels, or if you are feeding the data into a CNC-cutter, you may want to use millimeters. // // The units passed to NanoSVG should be one of: 'px', 'pt', 'pc' 'mm', 'cm', or 'in'. // DPI (dots-per-inch) controls how the unit conversion is done. // // If you don't know or care about the units stuff, "px" and 96 should get you going. /* Example Usage: // Load SVG NSVGimage* image; image = nsvgParseFromFile("test.svg", "px", 96); printf("size: %f x %f\n", image->width, image->height); // Use... for (NSVGshape *shape = image->shapes; shape != NULL; shape = shape->next) { for (NSVGpath *path = shape->paths; path != NULL; path = path->next) { for (int i = 0; i < path->npts-1; i += 3) { float* p = &path->pts[i*2]; drawCubicBez(p[0],p[1], p[2],p[3], p[4],p[5], p[6],p[7]); } } } // Delete nsvgDelete(image); */ enum NSVGpaintType { NSVG_PAINT_UNDEF = -1, NSVG_PAINT_NONE = 0, NSVG_PAINT_COLOR = 1, NSVG_PAINT_LINEAR_GRADIENT = 2, NSVG_PAINT_RADIAL_GRADIENT = 3 }; enum NSVGspreadType { NSVG_SPREAD_PAD = 0, NSVG_SPREAD_REFLECT = 1, NSVG_SPREAD_REPEAT = 2 }; enum NSVGlineJoin { NSVG_JOIN_MITER = 0, NSVG_JOIN_ROUND = 1, NSVG_JOIN_BEVEL = 2 }; enum NSVGlineCap { NSVG_CAP_BUTT = 0, NSVG_CAP_ROUND = 1, NSVG_CAP_SQUARE = 2 }; enum NSVGfillRule { NSVG_FILLRULE_NONZERO = 0, NSVG_FILLRULE_EVENODD = 1 }; enum NSVGflags { NSVG_FLAGS_VISIBLE = 0x01 }; typedef struct NSVGgradientStop { unsigned int color; float offset; } NSVGgradientStop; typedef struct NSVGgradient { float xform[6]; char spread; float fx, fy; int nstops; NSVGgradientStop stops[1]; } NSVGgradient; typedef struct NSVGpaint { signed char type; union { unsigned int color; NSVGgradient* gradient; }; } NSVGpaint; typedef struct NSVGpath { float* pts; // Cubic bezier points: x0,y0, [cpx1,cpx1,cpx2,cpy2,x1,y1], ... int npts; // Total number of bezier points. char closed; // Flag indicating if shapes should be treated as closed. float bounds[4]; // Tight bounding box of the shape [minx,miny,maxx,maxy]. struct NSVGpath* next; // Pointer to next path, or NULL if last element. } NSVGpath; typedef struct NSVGshape { char id[64]; // Optional 'id' attr of the shape or its group NSVGpaint fill; // Fill paint NSVGpaint stroke; // Stroke paint float opacity; // Opacity of the shape. float strokeWidth; // Stroke width (scaled). float strokeDashOffset; // Stroke dash offset (scaled). float strokeDashArray[8]; // Stroke dash array (scaled). char strokeDashCount; // Number of dash values in dash array. char strokeLineJoin; // Stroke join type. char strokeLineCap; // Stroke cap type. float miterLimit; // Miter limit char fillRule; // Fill rule, see NSVGfillRule. unsigned char flags; // Logical or of NSVG_FLAGS_* flags float bounds[4]; // Tight bounding box of the shape [minx,miny,maxx,maxy]. char fillGradient[64]; // Optional 'id' of fill gradient char strokeGradient[64]; // Optional 'id' of stroke gradient float xform[6]; // Root transformation for fill/stroke gradient NSVGpath* paths; // Linked list of paths in the image. struct NSVGshape* next; // Pointer to next shape, or NULL if last element. } NSVGshape; typedef struct NSVGimage { float width; // Width of the image. float height; // Height of the image. NSVGshape* shapes; // Linked list of shapes in the image. } NSVGimage; // Parses SVG file from a file, returns SVG image as paths. NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi); // Parses SVG file from a null terminated string, returns SVG image as paths. // Important note: changes the string. NSVGimage* nsvgParse(char* input, const char* units, float dpi); // Duplicates a path. NSVGpath* nsvgDuplicatePath(NSVGpath* p); // Deletes an image. void nsvgDelete(NSVGimage* image); #ifndef NANOSVG_CPLUSPLUS #ifdef __cplusplus } #endif #endif #ifdef NANOSVG_IMPLEMENTATION #include #include #include #include #define NSVG_PI (3.14159265358979323846264338327f) #define NSVG_KAPPA90 (0.5522847493f) // Length proportional to radius of a cubic bezier handle for 90deg arcs. #define NSVG_ALIGN_MIN 0 #define NSVG_ALIGN_MID 1 #define NSVG_ALIGN_MAX 2 #define NSVG_ALIGN_NONE 0 #define NSVG_ALIGN_MEET 1 #define NSVG_ALIGN_SLICE 2 #define NSVG_NOTUSED(v) do { (void)(1 ? (void)0 : ( (void)(v) ) ); } while(0) #define NSVG_RGB(r, g, b) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16)) #ifdef _MSC_VER #pragma warning (disable: 4996) // Switch off security warnings #pragma warning (disable: 4100) // Switch off unreferenced formal parameter warnings #ifdef __cplusplus #define NSVG_INLINE inline #else #define NSVG_INLINE #endif #else #define NSVG_INLINE inline #endif static int nsvg__isspace(char c) { return strchr(" \t\n\v\f\r", c) != 0; } static int nsvg__isdigit(char c) { return c >= '0' && c <= '9'; } static NSVG_INLINE float nsvg__minf(float a, float b) { return a < b ? a : b; } static NSVG_INLINE float nsvg__maxf(float a, float b) { return a > b ? a : b; } // Simple XML parser #define NSVG_XML_TAG 1 #define NSVG_XML_CONTENT 2 #define NSVG_XML_MAX_ATTRIBS 256 static void nsvg__parseContent(char* s, void (*contentCb)(void* ud, const char* s), void* ud) { // Trim start white spaces while (*s && nsvg__isspace(*s)) s++; if (!*s) return; if (contentCb) (*contentCb)(ud, s); } static void nsvg__parseElement(char* s, void (*startelCb)(void* ud, const char* el, const char** attr), void (*endelCb)(void* ud, const char* el), void* ud) { const char* attr[NSVG_XML_MAX_ATTRIBS]; int nattr = 0; char* name; int start = 0; int end = 0; char quote; // Skip white space after the '<' while (*s && nsvg__isspace(*s)) s++; // Check if the tag is end tag if (*s == '/') { s++; end = 1; } else { start = 1; } // Skip comments, data and preprocessor stuff. if (!*s || *s == '?' || *s == '!') return; // Get tag name name = s; while (*s && !nsvg__isspace(*s)) s++; if (*s) { *s++ = '\0'; } // Get attribs while (!end && *s && nattr < NSVG_XML_MAX_ATTRIBS-3) { char* name = NULL; char* value = NULL; // Skip white space before the attrib name while (*s && nsvg__isspace(*s)) s++; if (!*s) break; if (*s == '/') { end = 1; break; } name = s; // Find end of the attrib name. while (*s && !nsvg__isspace(*s) && *s != '=') s++; if (*s) { *s++ = '\0'; } // Skip until the beginning of the value. while (*s && *s != '\"' && *s != '\'') s++; if (!*s) break; quote = *s; s++; // Store value and find the end of it. value = s; while (*s && *s != quote) s++; if (*s) { *s++ = '\0'; } // Store only well formed attributes if (name && value) { attr[nattr++] = name; attr[nattr++] = value; } } // List terminator attr[nattr++] = 0; attr[nattr++] = 0; // Call callbacks. if (start && startelCb) (*startelCb)(ud, name, attr); if (end && endelCb) (*endelCb)(ud, name); } int nsvg__parseXML(char* input, void (*startelCb)(void* ud, const char* el, const char** attr), void (*endelCb)(void* ud, const char* el), void (*contentCb)(void* ud, const char* s), void* ud) { char* s = input; char* mark = s; int state = NSVG_XML_CONTENT; while (*s) { if (*s == '<' && state == NSVG_XML_CONTENT) { // Start of a tag *s++ = '\0'; nsvg__parseContent(mark, contentCb, ud); mark = s; state = NSVG_XML_TAG; } else if (*s == '>' && state == NSVG_XML_TAG) { // Start of a content or new tag. *s++ = '\0'; nsvg__parseElement(mark, startelCb, endelCb, ud); mark = s; state = NSVG_XML_CONTENT; } else { s++; } } return 1; } /* Simple SVG parser. */ #define NSVG_MAX_ATTR 128 enum NSVGgradientUnits { NSVG_USER_SPACE = 0, NSVG_OBJECT_SPACE = 1 }; #define NSVG_MAX_DASHES 8 enum NSVGunits { NSVG_UNITS_USER, NSVG_UNITS_PX, NSVG_UNITS_PT, NSVG_UNITS_PC, NSVG_UNITS_MM, NSVG_UNITS_CM, NSVG_UNITS_IN, NSVG_UNITS_PERCENT, NSVG_UNITS_EM, NSVG_UNITS_EX }; typedef struct NSVGcoordinate { float value; int units; } NSVGcoordinate; typedef struct NSVGlinearData { NSVGcoordinate x1, y1, x2, y2; } NSVGlinearData; typedef struct NSVGradialData { NSVGcoordinate cx, cy, r, fx, fy; } NSVGradialData; typedef struct NSVGgradientData { char id[64]; char ref[64]; signed char type; union { NSVGlinearData linear; NSVGradialData radial; }; char spread; char units; float xform[6]; int nstops; NSVGgradientStop* stops; struct NSVGgradientData* next; } NSVGgradientData; typedef struct NSVGattrib { char id[64]; float xform[6]; unsigned int fillColor; unsigned int strokeColor; float opacity; float fillOpacity; float strokeOpacity; char fillGradient[64]; char strokeGradient[64]; float strokeWidth; float strokeDashOffset; float strokeDashArray[NSVG_MAX_DASHES]; int strokeDashCount; char strokeLineJoin; char strokeLineCap; float miterLimit; char fillRule; float fontSize; unsigned int stopColor; float stopOpacity; float stopOffset; char hasFill; char hasStroke; char visible; } NSVGattrib; typedef struct NSVGparser { NSVGattrib attr[NSVG_MAX_ATTR]; int attrHead; float* pts; int npts; int cpts; NSVGpath* plist; NSVGimage* image; NSVGgradientData* gradients; NSVGshape* shapesTail; float viewMinx, viewMiny, viewWidth, viewHeight; int alignX, alignY, alignType; float dpi; char pathFlag; char defsFlag; } NSVGparser; static void nsvg__xformIdentity(float* t) { t[0] = 1.0f; t[1] = 0.0f; t[2] = 0.0f; t[3] = 1.0f; t[4] = 0.0f; t[5] = 0.0f; } static void nsvg__xformSetTranslation(float* t, float tx, float ty) { t[0] = 1.0f; t[1] = 0.0f; t[2] = 0.0f; t[3] = 1.0f; t[4] = tx; t[5] = ty; } static void nsvg__xformSetScale(float* t, float sx, float sy) { t[0] = sx; t[1] = 0.0f; t[2] = 0.0f; t[3] = sy; t[4] = 0.0f; t[5] = 0.0f; } static void nsvg__xformSetSkewX(float* t, float a) { t[0] = 1.0f; t[1] = 0.0f; t[2] = tanf(a); t[3] = 1.0f; t[4] = 0.0f; t[5] = 0.0f; } static void nsvg__xformSetSkewY(float* t, float a) { t[0] = 1.0f; t[1] = tanf(a); t[2] = 0.0f; t[3] = 1.0f; t[4] = 0.0f; t[5] = 0.0f; } static void nsvg__xformSetRotation(float* t, float a) { float cs = cosf(a), sn = sinf(a); t[0] = cs; t[1] = sn; t[2] = -sn; t[3] = cs; t[4] = 0.0f; t[5] = 0.0f; } static void nsvg__xformMultiply(float* t, float* s) { float t0 = t[0] * s[0] + t[1] * s[2]; float t2 = t[2] * s[0] + t[3] * s[2]; float t4 = t[4] * s[0] + t[5] * s[2] + s[4]; t[1] = t[0] * s[1] + t[1] * s[3]; t[3] = t[2] * s[1] + t[3] * s[3]; t[5] = t[4] * s[1] + t[5] * s[3] + s[5]; t[0] = t0; t[2] = t2; t[4] = t4; } static void nsvg__xformInverse(float* inv, float* t) { double invdet, det = (double)t[0] * t[3] - (double)t[2] * t[1]; if (det > -1e-6 && det < 1e-6) { nsvg__xformIdentity(t); return; } invdet = 1.0 / det; inv[0] = (float)(t[3] * invdet); inv[2] = (float)(-t[2] * invdet); inv[4] = (float)(((double)t[2] * t[5] - (double)t[3] * t[4]) * invdet); inv[1] = (float)(-t[1] * invdet); inv[3] = (float)(t[0] * invdet); inv[5] = (float)(((double)t[1] * t[4] - (double)t[0] * t[5]) * invdet); } static void nsvg__xformPremultiply(float* t, float* s) { float s2[6]; memcpy(s2, s, sizeof(float)*6); nsvg__xformMultiply(s2, t); memcpy(t, s2, sizeof(float)*6); } static void nsvg__xformPoint(float* dx, float* dy, float x, float y, float* t) { *dx = x*t[0] + y*t[2] + t[4]; *dy = x*t[1] + y*t[3] + t[5]; } static void nsvg__xformVec(float* dx, float* dy, float x, float y, float* t) { *dx = x*t[0] + y*t[2]; *dy = x*t[1] + y*t[3]; } #define NSVG_EPSILON (1e-12) static int nsvg__ptInBounds(float* pt, float* bounds) { return pt[0] >= bounds[0] && pt[0] <= bounds[2] && pt[1] >= bounds[1] && pt[1] <= bounds[3]; } static double nsvg__evalBezier(double t, double p0, double p1, double p2, double p3) { double it = 1.0-t; return it*it*it*p0 + 3.0*it*it*t*p1 + 3.0*it*t*t*p2 + t*t*t*p3; } static void nsvg__curveBounds(float* bounds, float* curve) { int i, j, count; double roots[2], a, b, c, b2ac, t, v; float* v0 = &curve[0]; float* v1 = &curve[2]; float* v2 = &curve[4]; float* v3 = &curve[6]; // Start the bounding box by end points bounds[0] = nsvg__minf(v0[0], v3[0]); bounds[1] = nsvg__minf(v0[1], v3[1]); bounds[2] = nsvg__maxf(v0[0], v3[0]); bounds[3] = nsvg__maxf(v0[1], v3[1]); // Bezier curve fits inside the convex hull of it's control points. // If control points are inside the bounds, we're done. if (nsvg__ptInBounds(v1, bounds) && nsvg__ptInBounds(v2, bounds)) return; // Add bezier curve inflection points in X and Y. for (i = 0; i < 2; i++) { a = -3.0 * v0[i] + 9.0 * v1[i] - 9.0 * v2[i] + 3.0 * v3[i]; b = 6.0 * v0[i] - 12.0 * v1[i] + 6.0 * v2[i]; c = 3.0 * v1[i] - 3.0 * v0[i]; count = 0; if (fabs(a) < NSVG_EPSILON) { if (fabs(b) > NSVG_EPSILON) { t = -c / b; if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON) roots[count++] = t; } } else { b2ac = b*b - 4.0*c*a; if (b2ac > NSVG_EPSILON) { t = (-b + sqrt(b2ac)) / (2.0 * a); if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON) roots[count++] = t; t = (-b - sqrt(b2ac)) / (2.0 * a); if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON) roots[count++] = t; } } for (j = 0; j < count; j++) { v = nsvg__evalBezier(roots[j], v0[i], v1[i], v2[i], v3[i]); bounds[0+i] = nsvg__minf(bounds[0+i], (float)v); bounds[2+i] = nsvg__maxf(bounds[2+i], (float)v); } } } static NSVGparser* nsvg__createParser(void) { NSVGparser* p; p = (NSVGparser*)malloc(sizeof(NSVGparser)); if (p == NULL) goto error; memset(p, 0, sizeof(NSVGparser)); p->image = (NSVGimage*)malloc(sizeof(NSVGimage)); if (p->image == NULL) goto error; memset(p->image, 0, sizeof(NSVGimage)); // Init style nsvg__xformIdentity(p->attr[0].xform); memset(p->attr[0].id, 0, sizeof p->attr[0].id); p->attr[0].fillColor = NSVG_RGB(0,0,0); p->attr[0].strokeColor = NSVG_RGB(0,0,0); p->attr[0].opacity = 1; p->attr[0].fillOpacity = 1; p->attr[0].strokeOpacity = 1; p->attr[0].stopOpacity = 1; p->attr[0].strokeWidth = 1; p->attr[0].strokeLineJoin = NSVG_JOIN_MITER; p->attr[0].strokeLineCap = NSVG_CAP_BUTT; p->attr[0].miterLimit = 4; p->attr[0].fillRule = NSVG_FILLRULE_NONZERO; p->attr[0].hasFill = 1; p->attr[0].visible = 1; return p; error: if (p) { if (p->image) free(p->image); free(p); } return NULL; } static void nsvg__deletePaths(NSVGpath* path) { while (path) { NSVGpath *next = path->next; if (path->pts != NULL) free(path->pts); free(path); path = next; } } static void nsvg__deletePaint(NSVGpaint* paint) { if (paint->type == NSVG_PAINT_LINEAR_GRADIENT || paint->type == NSVG_PAINT_RADIAL_GRADIENT) free(paint->gradient); } static void nsvg__deleteGradientData(NSVGgradientData* grad) { NSVGgradientData* next; while (grad != NULL) { next = grad->next; free(grad->stops); free(grad); grad = next; } } static void nsvg__deleteParser(NSVGparser* p) { if (p != NULL) { nsvg__deletePaths(p->plist); nsvg__deleteGradientData(p->gradients); nsvgDelete(p->image); free(p->pts); free(p); } } static void nsvg__resetPath(NSVGparser* p) { p->npts = 0; } static void nsvg__addPoint(NSVGparser* p, float x, float y) { if (p->npts+1 > p->cpts) { p->cpts = p->cpts ? p->cpts*2 : 8; p->pts = (float*)realloc(p->pts, p->cpts*2*sizeof(float)); if (!p->pts) return; } p->pts[p->npts*2+0] = x; p->pts[p->npts*2+1] = y; p->npts++; } static void nsvg__moveTo(NSVGparser* p, float x, float y) { if (p->npts > 0) { p->pts[(p->npts-1)*2+0] = x; p->pts[(p->npts-1)*2+1] = y; } else { nsvg__addPoint(p, x, y); } } static void nsvg__lineTo(NSVGparser* p, float x, float y) { float px,py, dx,dy; if (p->npts > 0) { px = p->pts[(p->npts-1)*2+0]; py = p->pts[(p->npts-1)*2+1]; dx = x - px; dy = y - py; nsvg__addPoint(p, px + dx/3.0f, py + dy/3.0f); nsvg__addPoint(p, x - dx/3.0f, y - dy/3.0f); nsvg__addPoint(p, x, y); } } static void nsvg__cubicBezTo(NSVGparser* p, float cpx1, float cpy1, float cpx2, float cpy2, float x, float y) { if (p->npts > 0) { nsvg__addPoint(p, cpx1, cpy1); nsvg__addPoint(p, cpx2, cpy2); nsvg__addPoint(p, x, y); } } static NSVGattrib* nsvg__getAttr(NSVGparser* p) { return &p->attr[p->attrHead]; } static void nsvg__pushAttr(NSVGparser* p) { if (p->attrHead < NSVG_MAX_ATTR-1) { p->attrHead++; memcpy(&p->attr[p->attrHead], &p->attr[p->attrHead-1], sizeof(NSVGattrib)); } } static void nsvg__popAttr(NSVGparser* p) { if (p->attrHead > 0) p->attrHead--; } static float nsvg__actualOrigX(NSVGparser* p) { return p->viewMinx; } static float nsvg__actualOrigY(NSVGparser* p) { return p->viewMiny; } static float nsvg__actualWidth(NSVGparser* p) { return p->viewWidth; } static float nsvg__actualHeight(NSVGparser* p) { return p->viewHeight; } static float nsvg__actualLength(NSVGparser* p) { float w = nsvg__actualWidth(p), h = nsvg__actualHeight(p); return sqrtf(w*w + h*h) / sqrtf(2.0f); } static float nsvg__convertToPixels(NSVGparser* p, NSVGcoordinate c, float orig, float length) { NSVGattrib* attr = nsvg__getAttr(p); switch (c.units) { case NSVG_UNITS_USER: return c.value; case NSVG_UNITS_PX: return c.value; case NSVG_UNITS_PT: return c.value / 72.0f * p->dpi; case NSVG_UNITS_PC: return c.value / 6.0f * p->dpi; case NSVG_UNITS_MM: return c.value / 25.4f * p->dpi; case NSVG_UNITS_CM: return c.value / 2.54f * p->dpi; case NSVG_UNITS_IN: return c.value * p->dpi; case NSVG_UNITS_EM: return c.value * attr->fontSize; case NSVG_UNITS_EX: return c.value * attr->fontSize * 0.52f; // x-height of Helvetica. case NSVG_UNITS_PERCENT: return orig + c.value / 100.0f * length; default: return c.value; } return c.value; } static NSVGgradientData* nsvg__findGradientData(NSVGparser* p, const char* id) { NSVGgradientData* grad = p->gradients; if (id == NULL || *id == '\0') return NULL; while (grad != NULL) { if (strcmp(grad->id, id) == 0) return grad; grad = grad->next; } return NULL; } static NSVGgradient* nsvg__createGradient(NSVGparser* p, const char* id, const float* localBounds, float *xform, signed char* paintType) { NSVGgradientData* data = NULL; NSVGgradientData* ref = NULL; NSVGgradientStop* stops = NULL; NSVGgradient* grad; float ox, oy, sw, sh, sl; int nstops = 0; int refIter; data = nsvg__findGradientData(p, id); if (data == NULL) return NULL; // TODO: use ref to fill in all unset values too. ref = data; refIter = 0; while (ref != NULL) { NSVGgradientData* nextRef = NULL; if (stops == NULL && ref->stops != NULL) { stops = ref->stops; nstops = ref->nstops; break; } nextRef = nsvg__findGradientData(p, ref->ref); if (nextRef == ref) break; // prevent infite loops on malformed data ref = nextRef; refIter++; if (refIter > 32) break; // prevent infite loops on malformed data } if (stops == NULL) return NULL; grad = (NSVGgradient*)malloc(sizeof(NSVGgradient) + sizeof(NSVGgradientStop)*(nstops-1)); if (grad == NULL) return NULL; // The shape width and height. if (data->units == NSVG_OBJECT_SPACE) { ox = localBounds[0]; oy = localBounds[1]; sw = localBounds[2] - localBounds[0]; sh = localBounds[3] - localBounds[1]; } else { ox = nsvg__actualOrigX(p); oy = nsvg__actualOrigY(p); sw = nsvg__actualWidth(p); sh = nsvg__actualHeight(p); } sl = sqrtf(sw*sw + sh*sh) / sqrtf(2.0f); if (data->type == NSVG_PAINT_LINEAR_GRADIENT) { float x1, y1, x2, y2, dx, dy; x1 = nsvg__convertToPixels(p, data->linear.x1, ox, sw); y1 = nsvg__convertToPixels(p, data->linear.y1, oy, sh); x2 = nsvg__convertToPixels(p, data->linear.x2, ox, sw); y2 = nsvg__convertToPixels(p, data->linear.y2, oy, sh); // Calculate transform aligned to the line dx = x2 - x1; dy = y2 - y1; grad->xform[0] = dy; grad->xform[1] = -dx; grad->xform[2] = dx; grad->xform[3] = dy; grad->xform[4] = x1; grad->xform[5] = y1; } else { float cx, cy, fx, fy, r; cx = nsvg__convertToPixels(p, data->radial.cx, ox, sw); cy = nsvg__convertToPixels(p, data->radial.cy, oy, sh); fx = nsvg__convertToPixels(p, data->radial.fx, ox, sw); fy = nsvg__convertToPixels(p, data->radial.fy, oy, sh); r = nsvg__convertToPixels(p, data->radial.r, 0, sl); // Calculate transform aligned to the circle grad->xform[0] = r; grad->xform[1] = 0; grad->xform[2] = 0; grad->xform[3] = r; grad->xform[4] = cx; grad->xform[5] = cy; grad->fx = fx / r; grad->fy = fy / r; } nsvg__xformMultiply(grad->xform, data->xform); nsvg__xformMultiply(grad->xform, xform); grad->spread = data->spread; memcpy(grad->stops, stops, nstops*sizeof(NSVGgradientStop)); grad->nstops = nstops; *paintType = data->type; return grad; } static float nsvg__getAverageScale(float* t) { float sx = sqrtf(t[0]*t[0] + t[2]*t[2]); float sy = sqrtf(t[1]*t[1] + t[3]*t[3]); return (sx + sy) * 0.5f; } static void nsvg__getLocalBounds(float* bounds, NSVGshape *shape, float* xform) { NSVGpath* path; float curve[4*2], curveBounds[4]; int i, first = 1; for (path = shape->paths; path != NULL; path = path->next) { nsvg__xformPoint(&curve[0], &curve[1], path->pts[0], path->pts[1], xform); for (i = 0; i < path->npts-1; i += 3) { nsvg__xformPoint(&curve[2], &curve[3], path->pts[(i+1)*2], path->pts[(i+1)*2+1], xform); nsvg__xformPoint(&curve[4], &curve[5], path->pts[(i+2)*2], path->pts[(i+2)*2+1], xform); nsvg__xformPoint(&curve[6], &curve[7], path->pts[(i+3)*2], path->pts[(i+3)*2+1], xform); nsvg__curveBounds(curveBounds, curve); if (first) { bounds[0] = curveBounds[0]; bounds[1] = curveBounds[1]; bounds[2] = curveBounds[2]; bounds[3] = curveBounds[3]; first = 0; } else { bounds[0] = nsvg__minf(bounds[0], curveBounds[0]); bounds[1] = nsvg__minf(bounds[1], curveBounds[1]); bounds[2] = nsvg__maxf(bounds[2], curveBounds[2]); bounds[3] = nsvg__maxf(bounds[3], curveBounds[3]); } curve[0] = curve[6]; curve[1] = curve[7]; } } } static void nsvg__addShape(NSVGparser* p) { NSVGattrib* attr = nsvg__getAttr(p); float scale = 1.0f; NSVGshape* shape; NSVGpath* path; int i; if (p->plist == NULL) return; shape = (NSVGshape*)malloc(sizeof(NSVGshape)); if (shape == NULL) goto error; memset(shape, 0, sizeof(NSVGshape)); memcpy(shape->id, attr->id, sizeof shape->id); memcpy(shape->fillGradient, attr->fillGradient, sizeof shape->fillGradient); memcpy(shape->strokeGradient, attr->strokeGradient, sizeof shape->strokeGradient); memcpy(shape->xform, attr->xform, sizeof shape->xform); scale = nsvg__getAverageScale(attr->xform); shape->strokeWidth = attr->strokeWidth * scale; shape->strokeDashOffset = attr->strokeDashOffset * scale; shape->strokeDashCount = (char)attr->strokeDashCount; for (i = 0; i < attr->strokeDashCount; i++) shape->strokeDashArray[i] = attr->strokeDashArray[i] * scale; shape->strokeLineJoin = attr->strokeLineJoin; shape->strokeLineCap = attr->strokeLineCap; shape->miterLimit = attr->miterLimit; shape->fillRule = attr->fillRule; shape->opacity = attr->opacity; shape->paths = p->plist; p->plist = NULL; // Calculate shape bounds shape->bounds[0] = shape->paths->bounds[0]; shape->bounds[1] = shape->paths->bounds[1]; shape->bounds[2] = shape->paths->bounds[2]; shape->bounds[3] = shape->paths->bounds[3]; for (path = shape->paths->next; path != NULL; path = path->next) { shape->bounds[0] = nsvg__minf(shape->bounds[0], path->bounds[0]); shape->bounds[1] = nsvg__minf(shape->bounds[1], path->bounds[1]); shape->bounds[2] = nsvg__maxf(shape->bounds[2], path->bounds[2]); shape->bounds[3] = nsvg__maxf(shape->bounds[3], path->bounds[3]); } // Set fill if (attr->hasFill == 0) { shape->fill.type = NSVG_PAINT_NONE; } else if (attr->hasFill == 1) { shape->fill.type = NSVG_PAINT_COLOR; shape->fill.color = attr->fillColor; shape->fill.color |= (unsigned int)(attr->fillOpacity*255) << 24; } else if (attr->hasFill == 2) { shape->fill.type = NSVG_PAINT_UNDEF; } // Set stroke if (attr->hasStroke == 0) { shape->stroke.type = NSVG_PAINT_NONE; } else if (attr->hasStroke == 1) { shape->stroke.type = NSVG_PAINT_COLOR; shape->stroke.color = attr->strokeColor; shape->stroke.color |= (unsigned int)(attr->strokeOpacity*255) << 24; } else if (attr->hasStroke == 2) { shape->stroke.type = NSVG_PAINT_UNDEF; } // Set flags shape->flags = (attr->visible ? NSVG_FLAGS_VISIBLE : 0x00); // Add to tail if (p->image->shapes == NULL) p->image->shapes = shape; else p->shapesTail->next = shape; p->shapesTail = shape; return; error: if (shape) free(shape); } static void nsvg__addPath(NSVGparser* p, char closed) { NSVGattrib* attr = nsvg__getAttr(p); NSVGpath* path = NULL; float bounds[4]; float* curve; int i; if (p->npts < 4) return; if (closed) nsvg__lineTo(p, p->pts[0], p->pts[1]); // Expect 1 + N*3 points (N = number of cubic bezier segments). if ((p->npts % 3) != 1) return; path = (NSVGpath*)malloc(sizeof(NSVGpath)); if (path == NULL) goto error; memset(path, 0, sizeof(NSVGpath)); path->pts = (float*)malloc(p->npts*2*sizeof(float)); if (path->pts == NULL) goto error; path->closed = closed; path->npts = p->npts; // Transform path. for (i = 0; i < p->npts; ++i) nsvg__xformPoint(&path->pts[i*2], &path->pts[i*2+1], p->pts[i*2], p->pts[i*2+1], attr->xform); // Find bounds for (i = 0; i < path->npts-1; i += 3) { curve = &path->pts[i*2]; nsvg__curveBounds(bounds, curve); if (i == 0) { path->bounds[0] = bounds[0]; path->bounds[1] = bounds[1]; path->bounds[2] = bounds[2]; path->bounds[3] = bounds[3]; } else { path->bounds[0] = nsvg__minf(path->bounds[0], bounds[0]); path->bounds[1] = nsvg__minf(path->bounds[1], bounds[1]); path->bounds[2] = nsvg__maxf(path->bounds[2], bounds[2]); path->bounds[3] = nsvg__maxf(path->bounds[3], bounds[3]); } } path->next = p->plist; p->plist = path; return; error: if (path != NULL) { if (path->pts != NULL) free(path->pts); free(path); } } // We roll our own string to float because the std library one uses locale and messes things up. static double nsvg__atof(const char* s) { char* cur = (char*)s; char* end = NULL; double res = 0.0, sign = 1.0; long long intPart = 0, fracPart = 0; char hasIntPart = 0, hasFracPart = 0; // Parse optional sign if (*cur == '+') { cur++; } else if (*cur == '-') { sign = -1; cur++; } // Parse integer part if (nsvg__isdigit(*cur)) { // Parse digit sequence intPart = strtoll(cur, &end, 10); if (cur != end) { res = (double)intPart; hasIntPart = 1; cur = end; } } // Parse fractional part. if (*cur == '.') { cur++; // Skip '.' if (nsvg__isdigit(*cur)) { // Parse digit sequence fracPart = strtoll(cur, &end, 10); if (cur != end) { res += (double)fracPart / pow(10.0, (double)(end - cur)); hasFracPart = 1; cur = end; } } } // A valid number should have integer or fractional part. if (!hasIntPart && !hasFracPart) return 0.0; // Parse optional exponent if (*cur == 'e' || *cur == 'E') { long expPart = 0; cur++; // skip 'E' expPart = strtol(cur, &end, 10); // Parse digit sequence with sign if (cur != end) { res *= pow(10.0, (double)expPart); } } return res * sign; } static const char* nsvg__parseNumber(const char* s, char* it, const int size) { const int last = size-1; int i = 0; // sign if (*s == '-' || *s == '+') { if (i < last) it[i++] = *s; s++; } // integer part while (*s && nsvg__isdigit(*s)) { if (i < last) it[i++] = *s; s++; } if (*s == '.') { // decimal point if (i < last) it[i++] = *s; s++; // fraction part while (*s && nsvg__isdigit(*s)) { if (i < last) it[i++] = *s; s++; } } // exponent if ((*s == 'e' || *s == 'E') && (s[1] != 'm' && s[1] != 'x')) { if (i < last) it[i++] = *s; s++; if (*s == '-' || *s == '+') { if (i < last) it[i++] = *s; s++; } while (*s && nsvg__isdigit(*s)) { if (i < last) it[i++] = *s; s++; } } it[i] = '\0'; return s; } static const char* nsvg__getNextPathItemWhenArcFlag(const char* s, char* it) { it[0] = '\0'; while (*s && (nsvg__isspace(*s) || *s == ',')) s++; if (!*s) return s; if (*s == '0' || *s == '1') { it[0] = *s++; it[1] = '\0'; return s; } return s; } static const char* nsvg__getNextPathItem(const char* s, char* it) { it[0] = '\0'; // Skip white spaces and commas while (*s && (nsvg__isspace(*s) || *s == ',')) s++; if (!*s) return s; if (*s == '-' || *s == '+' || *s == '.' || nsvg__isdigit(*s)) { s = nsvg__parseNumber(s, it, 64); } else { // Parse command it[0] = *s++; it[1] = '\0'; return s; } return s; } static unsigned int nsvg__parseColorHex(const char* str) { unsigned int r=0, g=0, b=0; if (sscanf(str, "#%2x%2x%2x", &r, &g, &b) == 3 ) // 2 digit hex return NSVG_RGB(r, g, b); if (sscanf(str, "#%1x%1x%1x", &r, &g, &b) == 3 ) // 1 digit hex, e.g. #abc -> 0xccbbaa return NSVG_RGB(r*17, g*17, b*17); // same effect as (r<<4|r), (g<<4|g), .. return NSVG_RGB(128, 128, 128); } // Parse rgb color. The pointer 'str' must point at "rgb(" (4+ characters). // This function returns gray (rgb(128, 128, 128) == '#808080') on parse errors // for backwards compatibility. Note: other image viewers return black instead. static unsigned int nsvg__parseColorRGB(const char* str) { int i; unsigned int rgbi[3]; float rgbf[3]; // try decimal integers first if (sscanf(str, "rgb(%u, %u, %u)", &rgbi[0], &rgbi[1], &rgbi[2]) != 3) { // integers failed, try percent values (float, locale independent) const char delimiter[3] = {',', ',', ')'}; str += 4; // skip "rgb(" for (i = 0; i < 3; i++) { while (*str && (nsvg__isspace(*str))) str++; // skip leading spaces if (*str == '+') str++; // skip '+' (don't allow '-') if (!*str) break; rgbf[i] = nsvg__atof(str); // Note 1: it would be great if nsvg__atof() returned how many // bytes it consumed but it doesn't. We need to skip the number, // the '%' character, spaces, and the delimiter ',' or ')'. // Note 2: The following code does not allow values like "33.%", // i.e. a decimal point w/o fractional part, but this is consistent // with other image viewers, e.g. firefox, chrome, eog, gimp. while (*str && nsvg__isdigit(*str)) str++; // skip integer part if (*str == '.') { str++; if (!nsvg__isdigit(*str)) break; // error: no digit after '.' while (*str && nsvg__isdigit(*str)) str++; // skip fractional part } if (*str == '%') str++; else break; while (*str && nsvg__isspace(*str)) str++; if (*str == delimiter[i]) str++; else break; } if (i == 3) { rgbi[0] = roundf(rgbf[0] * 2.55f); rgbi[1] = roundf(rgbf[1] * 2.55f); rgbi[2] = roundf(rgbf[2] * 2.55f); } else { rgbi[0] = rgbi[1] = rgbi[2] = 128; } } // clip values as the CSS spec requires for (i = 0; i < 3; i++) { if (rgbi[i] > 255) rgbi[i] = 255; } return NSVG_RGB(rgbi[0], rgbi[1], rgbi[2]); } typedef struct NSVGNamedColor { const char* name; unsigned int color; } NSVGNamedColor; NSVGNamedColor nsvg__colors[] = { { "red", NSVG_RGB(255, 0, 0) }, { "green", NSVG_RGB( 0, 128, 0) }, { "blue", NSVG_RGB( 0, 0, 255) }, { "yellow", NSVG_RGB(255, 255, 0) }, { "cyan", NSVG_RGB( 0, 255, 255) }, { "magenta", NSVG_RGB(255, 0, 255) }, { "black", NSVG_RGB( 0, 0, 0) }, { "grey", NSVG_RGB(128, 128, 128) }, { "gray", NSVG_RGB(128, 128, 128) }, { "white", NSVG_RGB(255, 255, 255) }, #ifdef NANOSVG_ALL_COLOR_KEYWORDS { "aliceblue", NSVG_RGB(240, 248, 255) }, { "antiquewhite", NSVG_RGB(250, 235, 215) }, { "aqua", NSVG_RGB( 0, 255, 255) }, { "aquamarine", NSVG_RGB(127, 255, 212) }, { "azure", NSVG_RGB(240, 255, 255) }, { "beige", NSVG_RGB(245, 245, 220) }, { "bisque", NSVG_RGB(255, 228, 196) }, { "blanchedalmond", NSVG_RGB(255, 235, 205) }, { "blueviolet", NSVG_RGB(138, 43, 226) }, { "brown", NSVG_RGB(165, 42, 42) }, { "burlywood", NSVG_RGB(222, 184, 135) }, { "cadetblue", NSVG_RGB( 95, 158, 160) }, { "chartreuse", NSVG_RGB(127, 255, 0) }, { "chocolate", NSVG_RGB(210, 105, 30) }, { "coral", NSVG_RGB(255, 127, 80) }, { "cornflowerblue", NSVG_RGB(100, 149, 237) }, { "cornsilk", NSVG_RGB(255, 248, 220) }, { "crimson", NSVG_RGB(220, 20, 60) }, { "darkblue", NSVG_RGB( 0, 0, 139) }, { "darkcyan", NSVG_RGB( 0, 139, 139) }, { "darkgoldenrod", NSVG_RGB(184, 134, 11) }, { "darkgray", NSVG_RGB(169, 169, 169) }, { "darkgreen", NSVG_RGB( 0, 100, 0) }, { "darkgrey", NSVG_RGB(169, 169, 169) }, { "darkkhaki", NSVG_RGB(189, 183, 107) }, { "darkmagenta", NSVG_RGB(139, 0, 139) }, { "darkolivegreen", NSVG_RGB( 85, 107, 47) }, { "darkorange", NSVG_RGB(255, 140, 0) }, { "darkorchid", NSVG_RGB(153, 50, 204) }, { "darkred", NSVG_RGB(139, 0, 0) }, { "darksalmon", NSVG_RGB(233, 150, 122) }, { "darkseagreen", NSVG_RGB(143, 188, 143) }, { "darkslateblue", NSVG_RGB( 72, 61, 139) }, { "darkslategray", NSVG_RGB( 47, 79, 79) }, { "darkslategrey", NSVG_RGB( 47, 79, 79) }, { "darkturquoise", NSVG_RGB( 0, 206, 209) }, { "darkviolet", NSVG_RGB(148, 0, 211) }, { "deeppink", NSVG_RGB(255, 20, 147) }, { "deepskyblue", NSVG_RGB( 0, 191, 255) }, { "dimgray", NSVG_RGB(105, 105, 105) }, { "dimgrey", NSVG_RGB(105, 105, 105) }, { "dodgerblue", NSVG_RGB( 30, 144, 255) }, { "firebrick", NSVG_RGB(178, 34, 34) }, { "floralwhite", NSVG_RGB(255, 250, 240) }, { "forestgreen", NSVG_RGB( 34, 139, 34) }, { "fuchsia", NSVG_RGB(255, 0, 255) }, { "gainsboro", NSVG_RGB(220, 220, 220) }, { "ghostwhite", NSVG_RGB(248, 248, 255) }, { "gold", NSVG_RGB(255, 215, 0) }, { "goldenrod", NSVG_RGB(218, 165, 32) }, { "greenyellow", NSVG_RGB(173, 255, 47) }, { "honeydew", NSVG_RGB(240, 255, 240) }, { "hotpink", NSVG_RGB(255, 105, 180) }, { "indianred", NSVG_RGB(205, 92, 92) }, { "indigo", NSVG_RGB( 75, 0, 130) }, { "ivory", NSVG_RGB(255, 255, 240) }, { "khaki", NSVG_RGB(240, 230, 140) }, { "lavender", NSVG_RGB(230, 230, 250) }, { "lavenderblush", NSVG_RGB(255, 240, 245) }, { "lawngreen", NSVG_RGB(124, 252, 0) }, { "lemonchiffon", NSVG_RGB(255, 250, 205) }, { "lightblue", NSVG_RGB(173, 216, 230) }, { "lightcoral", NSVG_RGB(240, 128, 128) }, { "lightcyan", NSVG_RGB(224, 255, 255) }, { "lightgoldenrodyellow", NSVG_RGB(250, 250, 210) }, { "lightgray", NSVG_RGB(211, 211, 211) }, { "lightgreen", NSVG_RGB(144, 238, 144) }, { "lightgrey", NSVG_RGB(211, 211, 211) }, { "lightpink", NSVG_RGB(255, 182, 193) }, { "lightsalmon", NSVG_RGB(255, 160, 122) }, { "lightseagreen", NSVG_RGB( 32, 178, 170) }, { "lightskyblue", NSVG_RGB(135, 206, 250) }, { "lightslategray", NSVG_RGB(119, 136, 153) }, { "lightslategrey", NSVG_RGB(119, 136, 153) }, { "lightsteelblue", NSVG_RGB(176, 196, 222) }, { "lightyellow", NSVG_RGB(255, 255, 224) }, { "lime", NSVG_RGB( 0, 255, 0) }, { "limegreen", NSVG_RGB( 50, 205, 50) }, { "linen", NSVG_RGB(250, 240, 230) }, { "maroon", NSVG_RGB(128, 0, 0) }, { "mediumaquamarine", NSVG_RGB(102, 205, 170) }, { "mediumblue", NSVG_RGB( 0, 0, 205) }, { "mediumorchid", NSVG_RGB(186, 85, 211) }, { "mediumpurple", NSVG_RGB(147, 112, 219) }, { "mediumseagreen", NSVG_RGB( 60, 179, 113) }, { "mediumslateblue", NSVG_RGB(123, 104, 238) }, { "mediumspringgreen", NSVG_RGB( 0, 250, 154) }, { "mediumturquoise", NSVG_RGB( 72, 209, 204) }, { "mediumvioletred", NSVG_RGB(199, 21, 133) }, { "midnightblue", NSVG_RGB( 25, 25, 112) }, { "mintcream", NSVG_RGB(245, 255, 250) }, { "mistyrose", NSVG_RGB(255, 228, 225) }, { "moccasin", NSVG_RGB(255, 228, 181) }, { "navajowhite", NSVG_RGB(255, 222, 173) }, { "navy", NSVG_RGB( 0, 0, 128) }, { "oldlace", NSVG_RGB(253, 245, 230) }, { "olive", NSVG_RGB(128, 128, 0) }, { "olivedrab", NSVG_RGB(107, 142, 35) }, { "orange", NSVG_RGB(255, 165, 0) }, { "orangered", NSVG_RGB(255, 69, 0) }, { "orchid", NSVG_RGB(218, 112, 214) }, { "palegoldenrod", NSVG_RGB(238, 232, 170) }, { "palegreen", NSVG_RGB(152, 251, 152) }, { "paleturquoise", NSVG_RGB(175, 238, 238) }, { "palevioletred", NSVG_RGB(219, 112, 147) }, { "papayawhip", NSVG_RGB(255, 239, 213) }, { "peachpuff", NSVG_RGB(255, 218, 185) }, { "peru", NSVG_RGB(205, 133, 63) }, { "pink", NSVG_RGB(255, 192, 203) }, { "plum", NSVG_RGB(221, 160, 221) }, { "powderblue", NSVG_RGB(176, 224, 230) }, { "purple", NSVG_RGB(128, 0, 128) }, { "rosybrown", NSVG_RGB(188, 143, 143) }, { "royalblue", NSVG_RGB( 65, 105, 225) }, { "saddlebrown", NSVG_RGB(139, 69, 19) }, { "salmon", NSVG_RGB(250, 128, 114) }, { "sandybrown", NSVG_RGB(244, 164, 96) }, { "seagreen", NSVG_RGB( 46, 139, 87) }, { "seashell", NSVG_RGB(255, 245, 238) }, { "sienna", NSVG_RGB(160, 82, 45) }, { "silver", NSVG_RGB(192, 192, 192) }, { "skyblue", NSVG_RGB(135, 206, 235) }, { "slateblue", NSVG_RGB(106, 90, 205) }, { "slategray", NSVG_RGB(112, 128, 144) }, { "slategrey", NSVG_RGB(112, 128, 144) }, { "snow", NSVG_RGB(255, 250, 250) }, { "springgreen", NSVG_RGB( 0, 255, 127) }, { "steelblue", NSVG_RGB( 70, 130, 180) }, { "tan", NSVG_RGB(210, 180, 140) }, { "teal", NSVG_RGB( 0, 128, 128) }, { "thistle", NSVG_RGB(216, 191, 216) }, { "tomato", NSVG_RGB(255, 99, 71) }, { "turquoise", NSVG_RGB( 64, 224, 208) }, { "violet", NSVG_RGB(238, 130, 238) }, { "wheat", NSVG_RGB(245, 222, 179) }, { "whitesmoke", NSVG_RGB(245, 245, 245) }, { "yellowgreen", NSVG_RGB(154, 205, 50) }, #endif }; static unsigned int nsvg__parseColorName(const char* str) { int i, ncolors = sizeof(nsvg__colors) / sizeof(NSVGNamedColor); for (i = 0; i < ncolors; i++) { if (strcmp(nsvg__colors[i].name, str) == 0) { return nsvg__colors[i].color; } } return NSVG_RGB(128, 128, 128); } static unsigned int nsvg__parseColor(const char* str) { size_t len = 0; while(*str == ' ') ++str; len = strlen(str); if (len >= 1 && *str == '#') return nsvg__parseColorHex(str); else if (len >= 4 && str[0] == 'r' && str[1] == 'g' && str[2] == 'b' && str[3] == '(') return nsvg__parseColorRGB(str); return nsvg__parseColorName(str); } static float nsvg__parseOpacity(const char* str) { float val = nsvg__atof(str); if (val < 0.0f) val = 0.0f; if (val > 1.0f) val = 1.0f; return val; } static float nsvg__parseMiterLimit(const char* str) { float val = nsvg__atof(str); if (val < 0.0f) val = 0.0f; return val; } static int nsvg__parseUnits(const char* units) { if (units[0] == 'p' && units[1] == 'x') return NSVG_UNITS_PX; else if (units[0] == 'p' && units[1] == 't') return NSVG_UNITS_PT; else if (units[0] == 'p' && units[1] == 'c') return NSVG_UNITS_PC; else if (units[0] == 'm' && units[1] == 'm') return NSVG_UNITS_MM; else if (units[0] == 'c' && units[1] == 'm') return NSVG_UNITS_CM; else if (units[0] == 'i' && units[1] == 'n') return NSVG_UNITS_IN; else if (units[0] == '%') return NSVG_UNITS_PERCENT; else if (units[0] == 'e' && units[1] == 'm') return NSVG_UNITS_EM; else if (units[0] == 'e' && units[1] == 'x') return NSVG_UNITS_EX; return NSVG_UNITS_USER; } static int nsvg__isCoordinate(const char* s) { // optional sign if (*s == '-' || *s == '+') s++; // must have at least one digit, or start by a dot return (nsvg__isdigit(*s) || *s == '.'); } static NSVGcoordinate nsvg__parseCoordinateRaw(const char* str) { NSVGcoordinate coord = {0, NSVG_UNITS_USER}; char buf[64]; coord.units = nsvg__parseUnits(nsvg__parseNumber(str, buf, 64)); coord.value = nsvg__atof(buf); return coord; } static NSVGcoordinate nsvg__coord(float v, int units) { NSVGcoordinate coord = {v, units}; return coord; } static float nsvg__parseCoordinate(NSVGparser* p, const char* str, float orig, float length) { NSVGcoordinate coord = nsvg__parseCoordinateRaw(str); return nsvg__convertToPixels(p, coord, orig, length); } static int nsvg__parseTransformArgs(const char** str, float* args, int maxNa) { const char* end; const char* ptr = *str; char it[64]; int na; while (*ptr && *ptr != '(') ++ptr; if (*ptr == 0) { *str = ptr; return 0; } end = ptr; while (*end && *end != ')') ++end; if (*end == 0) { *str = ptr; return 0; } na = 0; while (ptr < end) { if (*ptr == '-' || *ptr == '+' || *ptr == '.' || nsvg__isdigit(*ptr)) { if (na >= maxNa) { *str = end; return 0; } ptr = nsvg__parseNumber(ptr, it, 64); args[na++] = (float)nsvg__atof(it); } else { ++ptr; } } *str = end; return na; } static int nsvg__parseMatrix(float* xform, const char** str) { float t[6]; int na; na = nsvg__parseTransformArgs(str, t, 6); if (na != 6) return 0; memcpy(xform, t, sizeof(float)*6); return 1; } static int nsvg__parseTranslate(float* xform, const char** str) { float args[2]; float t[6]; int na; na = nsvg__parseTransformArgs(str, args, 2); if (na == 0) return 0; if (na == 1) args[1] = 0.0; nsvg__xformSetTranslation(t, args[0], args[1]); memcpy(xform, t, sizeof(float)*6); return 1; } static int nsvg__parseScale(float* xform, const char** str) { float args[2]; int na; float t[6]; na = nsvg__parseTransformArgs(str, args, 2); if (na == 0) return 0; if (na == 1) args[1] = args[0]; nsvg__xformSetScale(t, args[0], args[1]); memcpy(xform, t, sizeof(float)*6); return 1; } static int nsvg__parseSkewX(float* xform, const char** str) { float args[1]; int na; float t[6]; na = nsvg__parseTransformArgs(str, args, 1); if (na == 0) return 0; nsvg__xformSetSkewX(t, args[0]/180.0f*NSVG_PI); memcpy(xform, t, sizeof(float)*6); return 1; } static int nsvg__parseSkewY(float* xform, const char** str) { float args[1]; int na; float t[6]; na = nsvg__parseTransformArgs(str, args, 1); if (na == 0) return 0; nsvg__xformSetSkewY(t, args[0]/180.0f*NSVG_PI); memcpy(xform, t, sizeof(float)*6); return 1; } static int nsvg__parseRotate(float* xform, const char** str) { float args[3]; int na; float m[6]; float t[6]; na = nsvg__parseTransformArgs(str, args, 3); if (na == 0) return 0; if (na == 1) args[1] = args[2] = 0.0f; nsvg__xformIdentity(m); if (na > 1) { nsvg__xformSetTranslation(t, -args[1], -args[2]); nsvg__xformMultiply(m, t); } nsvg__xformSetRotation(t, args[0]/180.0f*NSVG_PI); nsvg__xformMultiply(m, t); if (na > 1) { nsvg__xformSetTranslation(t, args[1], args[2]); nsvg__xformMultiply(m, t); } memcpy(xform, m, sizeof(float)*6); return 1; } static void nsvg__parseTransform(float* xform, const char* str) { float t[6]; int found; nsvg__xformIdentity(xform); while (*str) { if (strncmp(str, "matrix", 6) == 0) found = nsvg__parseMatrix(t, &str); else if (strncmp(str, "translate", 9) == 0) found = nsvg__parseTranslate(t, &str); else if (strncmp(str, "scale", 5) == 0) found = nsvg__parseScale(t, &str); else if (strncmp(str, "rotate", 6) == 0) found = nsvg__parseRotate(t, &str); else if (strncmp(str, "skewX", 5) == 0) found = nsvg__parseSkewX(t, &str); else if (strncmp(str, "skewY", 5) == 0) found = nsvg__parseSkewY(t, &str); else { ++str; continue; } if (found) nsvg__xformPremultiply(xform, t); } } static void nsvg__parseUrl(char* id, const char* str) { int i = 0; str += 4; // "url("; if (*str && *str == '#') str++; while (i < 63 && *str && *str != ')') { id[i] = *str++; i++; } id[i] = '\0'; } static char nsvg__parseLineCap(const char* str) { if (strcmp(str, "butt") == 0) return NSVG_CAP_BUTT; else if (strcmp(str, "round") == 0) return NSVG_CAP_ROUND; else if (strcmp(str, "square") == 0) return NSVG_CAP_SQUARE; // TODO: handle inherit. return NSVG_CAP_BUTT; } static char nsvg__parseLineJoin(const char* str) { if (strcmp(str, "miter") == 0) return NSVG_JOIN_MITER; else if (strcmp(str, "round") == 0) return NSVG_JOIN_ROUND; else if (strcmp(str, "bevel") == 0) return NSVG_JOIN_BEVEL; // TODO: handle inherit. return NSVG_JOIN_MITER; } static char nsvg__parseFillRule(const char* str) { if (strcmp(str, "nonzero") == 0) return NSVG_FILLRULE_NONZERO; else if (strcmp(str, "evenodd") == 0) return NSVG_FILLRULE_EVENODD; // TODO: handle inherit. return NSVG_FILLRULE_NONZERO; } static const char* nsvg__getNextDashItem(const char* s, char* it) { int n = 0; it[0] = '\0'; // Skip white spaces and commas while (*s && (nsvg__isspace(*s) || *s == ',')) s++; // Advance until whitespace, comma or end. while (*s && (!nsvg__isspace(*s) && *s != ',')) { if (n < 63) it[n++] = *s; s++; } it[n++] = '\0'; return s; } static int nsvg__parseStrokeDashArray(NSVGparser* p, const char* str, float* strokeDashArray) { char item[64]; int count = 0, i; float sum = 0.0f; // Handle "none" if (str[0] == 'n') return 0; // Parse dashes while (*str) { str = nsvg__getNextDashItem(str, item); if (!*item) break; if (count < NSVG_MAX_DASHES) strokeDashArray[count++] = fabsf(nsvg__parseCoordinate(p, item, 0.0f, nsvg__actualLength(p))); } for (i = 0; i < count; i++) sum += strokeDashArray[i]; if (sum <= 1e-6f) count = 0; return count; } static void nsvg__parseStyle(NSVGparser* p, const char* str); static int nsvg__parseAttr(NSVGparser* p, const char* name, const char* value) { float xform[6]; NSVGattrib* attr = nsvg__getAttr(p); if (!attr) return 0; if (strcmp(name, "style") == 0) { nsvg__parseStyle(p, value); } else if (strcmp(name, "display") == 0) { if (strcmp(value, "none") == 0) attr->visible = 0; // Don't reset ->visible on display:inline, one display:none hides the whole subtree } else if (strcmp(name, "fill") == 0) { if (strcmp(value, "none") == 0) { attr->hasFill = 0; } else if (strncmp(value, "url(", 4) == 0) { attr->hasFill = 2; nsvg__parseUrl(attr->fillGradient, value); } else { attr->hasFill = 1; attr->fillColor = nsvg__parseColor(value); } } else if (strcmp(name, "opacity") == 0) { attr->opacity = nsvg__parseOpacity(value); } else if (strcmp(name, "fill-opacity") == 0) { attr->fillOpacity = nsvg__parseOpacity(value); } else if (strcmp(name, "stroke") == 0) { if (strcmp(value, "none") == 0) { attr->hasStroke = 0; } else if (strncmp(value, "url(", 4) == 0) { attr->hasStroke = 2; nsvg__parseUrl(attr->strokeGradient, value); } else { attr->hasStroke = 1; attr->strokeColor = nsvg__parseColor(value); } } else if (strcmp(name, "stroke-width") == 0) { attr->strokeWidth = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); } else if (strcmp(name, "stroke-dasharray") == 0) { attr->strokeDashCount = nsvg__parseStrokeDashArray(p, value, attr->strokeDashArray); } else if (strcmp(name, "stroke-dashoffset") == 0) { attr->strokeDashOffset = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); } else if (strcmp(name, "stroke-opacity") == 0) { attr->strokeOpacity = nsvg__parseOpacity(value); } else if (strcmp(name, "stroke-linecap") == 0) { attr->strokeLineCap = nsvg__parseLineCap(value); } else if (strcmp(name, "stroke-linejoin") == 0) { attr->strokeLineJoin = nsvg__parseLineJoin(value); } else if (strcmp(name, "stroke-miterlimit") == 0) { attr->miterLimit = nsvg__parseMiterLimit(value); } else if (strcmp(name, "fill-rule") == 0) { attr->fillRule = nsvg__parseFillRule(value); } else if (strcmp(name, "font-size") == 0) { attr->fontSize = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); } else if (strcmp(name, "transform") == 0) { nsvg__parseTransform(xform, value); nsvg__xformPremultiply(attr->xform, xform); } else if (strcmp(name, "stop-color") == 0) { attr->stopColor = nsvg__parseColor(value); } else if (strcmp(name, "stop-opacity") == 0) { attr->stopOpacity = nsvg__parseOpacity(value); } else if (strcmp(name, "offset") == 0) { attr->stopOffset = nsvg__parseCoordinate(p, value, 0.0f, 1.0f); } else if (strcmp(name, "id") == 0) { strncpy(attr->id, value, 63); attr->id[63] = '\0'; } else { return 0; } return 1; } static int nsvg__parseNameValue(NSVGparser* p, const char* start, const char* end) { const char* str; const char* val; char name[512]; char value[512]; int n; str = start; while (str < end && *str != ':') ++str; val = str; // Right Trim while (str > start && (*str == ':' || nsvg__isspace(*str))) --str; ++str; n = (int)(str - start); if (n > 511) n = 511; if (n) memcpy(name, start, n); name[n] = 0; while (val < end && (*val == ':' || nsvg__isspace(*val))) ++val; n = (int)(end - val); if (n > 511) n = 511; if (n) memcpy(value, val, n); value[n] = 0; return nsvg__parseAttr(p, name, value); } static void nsvg__parseStyle(NSVGparser* p, const char* str) { const char* start; const char* end; while (*str) { // Left Trim while(*str && nsvg__isspace(*str)) ++str; start = str; while(*str && *str != ';') ++str; end = str; // Right Trim while (end > start && (*end == ';' || nsvg__isspace(*end))) --end; ++end; nsvg__parseNameValue(p, start, end); if (*str) ++str; } } static void nsvg__parseAttribs(NSVGparser* p, const char** attr) { int i; for (i = 0; attr[i]; i += 2) { if (strcmp(attr[i], "style") == 0) nsvg__parseStyle(p, attr[i + 1]); else nsvg__parseAttr(p, attr[i], attr[i + 1]); } } static int nsvg__getArgsPerElement(char cmd) { switch (cmd) { case 'v': case 'V': case 'h': case 'H': return 1; case 'm': case 'M': case 'l': case 'L': case 't': case 'T': return 2; case 'q': case 'Q': case 's': case 'S': return 4; case 'c': case 'C': return 6; case 'a': case 'A': return 7; case 'z': case 'Z': return 0; } return -1; } static void nsvg__pathMoveTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) { if (rel) { *cpx += args[0]; *cpy += args[1]; } else { *cpx = args[0]; *cpy = args[1]; } nsvg__moveTo(p, *cpx, *cpy); } static void nsvg__pathLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) { if (rel) { *cpx += args[0]; *cpy += args[1]; } else { *cpx = args[0]; *cpy = args[1]; } nsvg__lineTo(p, *cpx, *cpy); } static void nsvg__pathHLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) { if (rel) *cpx += args[0]; else *cpx = args[0]; nsvg__lineTo(p, *cpx, *cpy); } static void nsvg__pathVLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) { if (rel) *cpy += args[0]; else *cpy = args[0]; nsvg__lineTo(p, *cpx, *cpy); } static void nsvg__pathCubicBezTo(NSVGparser* p, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel) { float x2, y2, cx1, cy1, cx2, cy2; if (rel) { cx1 = *cpx + args[0]; cy1 = *cpy + args[1]; cx2 = *cpx + args[2]; cy2 = *cpy + args[3]; x2 = *cpx + args[4]; y2 = *cpy + args[5]; } else { cx1 = args[0]; cy1 = args[1]; cx2 = args[2]; cy2 = args[3]; x2 = args[4]; y2 = args[5]; } nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); *cpx2 = cx2; *cpy2 = cy2; *cpx = x2; *cpy = y2; } static void nsvg__pathCubicBezShortTo(NSVGparser* p, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel) { float x1, y1, x2, y2, cx1, cy1, cx2, cy2; x1 = *cpx; y1 = *cpy; if (rel) { cx2 = *cpx + args[0]; cy2 = *cpy + args[1]; x2 = *cpx + args[2]; y2 = *cpy + args[3]; } else { cx2 = args[0]; cy2 = args[1]; x2 = args[2]; y2 = args[3]; } cx1 = 2*x1 - *cpx2; cy1 = 2*y1 - *cpy2; nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); *cpx2 = cx2; *cpy2 = cy2; *cpx = x2; *cpy = y2; } static void nsvg__pathQuadBezTo(NSVGparser* p, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel) { float x1, y1, x2, y2, cx, cy; float cx1, cy1, cx2, cy2; x1 = *cpx; y1 = *cpy; if (rel) { cx = *cpx + args[0]; cy = *cpy + args[1]; x2 = *cpx + args[2]; y2 = *cpy + args[3]; } else { cx = args[0]; cy = args[1]; x2 = args[2]; y2 = args[3]; } // Convert to cubic bezier cx1 = x1 + 2.0f/3.0f*(cx - x1); cy1 = y1 + 2.0f/3.0f*(cy - y1); cx2 = x2 + 2.0f/3.0f*(cx - x2); cy2 = y2 + 2.0f/3.0f*(cy - y2); nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); *cpx2 = cx; *cpy2 = cy; *cpx = x2; *cpy = y2; } static void nsvg__pathQuadBezShortTo(NSVGparser* p, float* cpx, float* cpy, float* cpx2, float* cpy2, float* args, int rel) { float x1, y1, x2, y2, cx, cy; float cx1, cy1, cx2, cy2; x1 = *cpx; y1 = *cpy; if (rel) { x2 = *cpx + args[0]; y2 = *cpy + args[1]; } else { x2 = args[0]; y2 = args[1]; } cx = 2*x1 - *cpx2; cy = 2*y1 - *cpy2; // Convert to cubix bezier cx1 = x1 + 2.0f/3.0f*(cx - x1); cy1 = y1 + 2.0f/3.0f*(cy - y1); cx2 = x2 + 2.0f/3.0f*(cx - x2); cy2 = y2 + 2.0f/3.0f*(cy - y2); nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2); *cpx2 = cx; *cpy2 = cy; *cpx = x2; *cpy = y2; } static float nsvg__sqr(float x) { return x*x; } static float nsvg__vmag(float x, float y) { return sqrtf(x*x + y*y); } static float nsvg__vecrat(float ux, float uy, float vx, float vy) { return (ux*vx + uy*vy) / (nsvg__vmag(ux,uy) * nsvg__vmag(vx,vy)); } static float nsvg__vecang(float ux, float uy, float vx, float vy) { float r = nsvg__vecrat(ux,uy, vx,vy); if (r < -1.0f) r = -1.0f; if (r > 1.0f) r = 1.0f; return ((ux*vy < uy*vx) ? -1.0f : 1.0f) * acosf(r); } static void nsvg__pathArcTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel) { // Ported from canvg (https://code.google.com/p/canvg/) float rx, ry, rotx; float x1, y1, x2, y2, cx, cy, dx, dy, d; float x1p, y1p, cxp, cyp, s, sa, sb; float ux, uy, vx, vy, a1, da; float x, y, tanx, tany, a, px = 0, py = 0, ptanx = 0, ptany = 0, t[6]; float sinrx, cosrx; int fa, fs; int i, ndivs; float hda, kappa; rx = fabsf(args[0]); // y radius ry = fabsf(args[1]); // x radius rotx = args[2] / 180.0f * NSVG_PI; // x rotation angle fa = fabsf(args[3]) > 1e-6 ? 1 : 0; // Large arc fs = fabsf(args[4]) > 1e-6 ? 1 : 0; // Sweep direction x1 = *cpx; // start point y1 = *cpy; if (rel) { // end point x2 = *cpx + args[5]; y2 = *cpy + args[6]; } else { x2 = args[5]; y2 = args[6]; } dx = x1 - x2; dy = y1 - y2; d = sqrtf(dx*dx + dy*dy); if (d < 1e-6f || rx < 1e-6f || ry < 1e-6f) { // The arc degenerates to a line nsvg__lineTo(p, x2, y2); *cpx = x2; *cpy = y2; return; } sinrx = sinf(rotx); cosrx = cosf(rotx); // Convert to center point parameterization. // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes // 1) Compute x1', y1' x1p = cosrx * dx / 2.0f + sinrx * dy / 2.0f; y1p = -sinrx * dx / 2.0f + cosrx * dy / 2.0f; d = nsvg__sqr(x1p)/nsvg__sqr(rx) + nsvg__sqr(y1p)/nsvg__sqr(ry); if (d > 1) { d = sqrtf(d); rx *= d; ry *= d; } // 2) Compute cx', cy' s = 0.0f; sa = nsvg__sqr(rx)*nsvg__sqr(ry) - nsvg__sqr(rx)*nsvg__sqr(y1p) - nsvg__sqr(ry)*nsvg__sqr(x1p); sb = nsvg__sqr(rx)*nsvg__sqr(y1p) + nsvg__sqr(ry)*nsvg__sqr(x1p); if (sa < 0.0f) sa = 0.0f; if (sb > 0.0f) s = sqrtf(sa / sb); if (fa == fs) s = -s; cxp = s * rx * y1p / ry; cyp = s * -ry * x1p / rx; // 3) Compute cx,cy from cx',cy' cx = (x1 + x2)/2.0f + cosrx*cxp - sinrx*cyp; cy = (y1 + y2)/2.0f + sinrx*cxp + cosrx*cyp; // 4) Calculate theta1, and delta theta. ux = (x1p - cxp) / rx; uy = (y1p - cyp) / ry; vx = (-x1p - cxp) / rx; vy = (-y1p - cyp) / ry; a1 = nsvg__vecang(1.0f,0.0f, ux,uy); // Initial angle da = nsvg__vecang(ux,uy, vx,vy); // Delta angle // if (vecrat(ux,uy,vx,vy) <= -1.0f) da = NSVG_PI; // if (vecrat(ux,uy,vx,vy) >= 1.0f) da = 0; if (fs == 0 && da > 0) da -= 2 * NSVG_PI; else if (fs == 1 && da < 0) da += 2 * NSVG_PI; // Approximate the arc using cubic spline segments. t[0] = cosrx; t[1] = sinrx; t[2] = -sinrx; t[3] = cosrx; t[4] = cx; t[5] = cy; // Split arc into max 90 degree segments. // The loop assumes an iteration per end point (including start and end), this +1. ndivs = (int)(fabsf(da) / (NSVG_PI*0.5f) + 1.0f); hda = (da / (float)ndivs) / 2.0f; // Fix for ticket #179: division by 0: avoid cotangens around 0 (infinite) if ((hda < 1e-3f) && (hda > -1e-3f)) hda *= 0.5f; else hda = (1.0f - cosf(hda)) / sinf(hda); kappa = fabsf(4.0f / 3.0f * hda); if (da < 0.0f) kappa = -kappa; for (i = 0; i <= ndivs; i++) { a = a1 + da * ((float)i/(float)ndivs); dx = cosf(a); dy = sinf(a); nsvg__xformPoint(&x, &y, dx*rx, dy*ry, t); // position nsvg__xformVec(&tanx, &tany, -dy*rx * kappa, dx*ry * kappa, t); // tangent if (i > 0) nsvg__cubicBezTo(p, px+ptanx,py+ptany, x-tanx, y-tany, x, y); px = x; py = y; ptanx = tanx; ptany = tany; } *cpx = x2; *cpy = y2; } static void nsvg__parsePath(NSVGparser* p, const char** attr) { const char* s = NULL; char cmd = '\0'; float args[10]; int nargs; int rargs = 0; char initPoint; float cpx, cpy, cpx2, cpy2; const char* tmp[4]; char closedFlag; int i; char item[64]; for (i = 0; attr[i]; i += 2) { if (strcmp(attr[i], "d") == 0) { s = attr[i + 1]; } else { tmp[0] = attr[i]; tmp[1] = attr[i + 1]; tmp[2] = 0; tmp[3] = 0; nsvg__parseAttribs(p, tmp); } } if (s) { nsvg__resetPath(p); cpx = 0; cpy = 0; cpx2 = 0; cpy2 = 0; initPoint = 0; closedFlag = 0; nargs = 0; while (*s) { item[0] = '\0'; if ((cmd == 'A' || cmd == 'a') && (nargs == 3 || nargs == 4)) s = nsvg__getNextPathItemWhenArcFlag(s, item); if (!*item) s = nsvg__getNextPathItem(s, item); if (!*item) break; if (cmd != '\0' && nsvg__isCoordinate(item)) { if (nargs < 10) args[nargs++] = (float)nsvg__atof(item); if (nargs >= rargs) { switch (cmd) { case 'm': case 'M': nsvg__pathMoveTo(p, &cpx, &cpy, args, cmd == 'm' ? 1 : 0); // Moveto can be followed by multiple coordinate pairs, // which should be treated as linetos. cmd = (cmd == 'm') ? 'l' : 'L'; rargs = nsvg__getArgsPerElement(cmd); cpx2 = cpx; cpy2 = cpy; initPoint = 1; break; case 'l': case 'L': nsvg__pathLineTo(p, &cpx, &cpy, args, cmd == 'l' ? 1 : 0); cpx2 = cpx; cpy2 = cpy; break; case 'H': case 'h': nsvg__pathHLineTo(p, &cpx, &cpy, args, cmd == 'h' ? 1 : 0); cpx2 = cpx; cpy2 = cpy; break; case 'V': case 'v': nsvg__pathVLineTo(p, &cpx, &cpy, args, cmd == 'v' ? 1 : 0); cpx2 = cpx; cpy2 = cpy; break; case 'C': case 'c': nsvg__pathCubicBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'c' ? 1 : 0); break; case 'S': case 's': nsvg__pathCubicBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 's' ? 1 : 0); break; case 'Q': case 'q': nsvg__pathQuadBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'q' ? 1 : 0); break; case 'T': case 't': nsvg__pathQuadBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 't' ? 1 : 0); break; case 'A': case 'a': nsvg__pathArcTo(p, &cpx, &cpy, args, cmd == 'a' ? 1 : 0); cpx2 = cpx; cpy2 = cpy; break; default: if (nargs >= 2) { cpx = args[nargs-2]; cpy = args[nargs-1]; cpx2 = cpx; cpy2 = cpy; } break; } nargs = 0; } } else { cmd = item[0]; if (cmd == 'M' || cmd == 'm') { // Commit path. if (p->npts > 0) nsvg__addPath(p, closedFlag); // Start new subpath. nsvg__resetPath(p); closedFlag = 0; nargs = 0; } else if (initPoint == 0) { // Do not allow other commands until initial point has been set (moveTo called once). cmd = '\0'; } if (cmd == 'Z' || cmd == 'z') { closedFlag = 1; // Commit path. if (p->npts > 0) { // Move current point to first point cpx = p->pts[0]; cpy = p->pts[1]; cpx2 = cpx; cpy2 = cpy; nsvg__addPath(p, closedFlag); } // Start new subpath. nsvg__resetPath(p); nsvg__moveTo(p, cpx, cpy); closedFlag = 0; nargs = 0; } rargs = nsvg__getArgsPerElement(cmd); if (rargs == -1) { // Command not recognized cmd = '\0'; rargs = 0; } } } // Commit path. if (p->npts) nsvg__addPath(p, closedFlag); } nsvg__addShape(p); } static void nsvg__parseRect(NSVGparser* p, const char** attr) { float x = 0.0f; float y = 0.0f; float w = 0.0f; float h = 0.0f; float rx = -1.0f; // marks not set float ry = -1.0f; int i; for (i = 0; attr[i]; i += 2) { if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { if (strcmp(attr[i], "x") == 0) x = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); if (strcmp(attr[i], "y") == 0) y = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); if (strcmp(attr[i], "width") == 0) w = nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p)); if (strcmp(attr[i], "height") == 0) h = nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p)); if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p))); if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p))); } } if (rx < 0.0f && ry > 0.0f) rx = ry; if (ry < 0.0f && rx > 0.0f) ry = rx; if (rx < 0.0f) rx = 0.0f; if (ry < 0.0f) ry = 0.0f; if (rx > w/2.0f) rx = w/2.0f; if (ry > h/2.0f) ry = h/2.0f; if (w != 0.0f && h != 0.0f) { nsvg__resetPath(p); if (rx < 0.00001f || ry < 0.0001f) { nsvg__moveTo(p, x, y); nsvg__lineTo(p, x+w, y); nsvg__lineTo(p, x+w, y+h); nsvg__lineTo(p, x, y+h); } else { // Rounded rectangle nsvg__moveTo(p, x+rx, y); nsvg__lineTo(p, x+w-rx, y); nsvg__cubicBezTo(p, x+w-rx*(1-NSVG_KAPPA90), y, x+w, y+ry*(1-NSVG_KAPPA90), x+w, y+ry); nsvg__lineTo(p, x+w, y+h-ry); nsvg__cubicBezTo(p, x+w, y+h-ry*(1-NSVG_KAPPA90), x+w-rx*(1-NSVG_KAPPA90), y+h, x+w-rx, y+h); nsvg__lineTo(p, x+rx, y+h); nsvg__cubicBezTo(p, x+rx*(1-NSVG_KAPPA90), y+h, x, y+h-ry*(1-NSVG_KAPPA90), x, y+h-ry); nsvg__lineTo(p, x, y+ry); nsvg__cubicBezTo(p, x, y+ry*(1-NSVG_KAPPA90), x+rx*(1-NSVG_KAPPA90), y, x+rx, y); } nsvg__addPath(p, 1); nsvg__addShape(p); } } static void nsvg__parseCircle(NSVGparser* p, const char** attr) { float cx = 0.0f; float cy = 0.0f; float r = 0.0f; int i; for (i = 0; attr[i]; i += 2) { if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); if (strcmp(attr[i], "r") == 0) r = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualLength(p))); } } if (r > 0.0f) { nsvg__resetPath(p); nsvg__moveTo(p, cx+r, cy); nsvg__cubicBezTo(p, cx+r, cy+r*NSVG_KAPPA90, cx+r*NSVG_KAPPA90, cy+r, cx, cy+r); nsvg__cubicBezTo(p, cx-r*NSVG_KAPPA90, cy+r, cx-r, cy+r*NSVG_KAPPA90, cx-r, cy); nsvg__cubicBezTo(p, cx-r, cy-r*NSVG_KAPPA90, cx-r*NSVG_KAPPA90, cy-r, cx, cy-r); nsvg__cubicBezTo(p, cx+r*NSVG_KAPPA90, cy-r, cx+r, cy-r*NSVG_KAPPA90, cx+r, cy); nsvg__addPath(p, 1); nsvg__addShape(p); } } static void nsvg__parseEllipse(NSVGparser* p, const char** attr) { float cx = 0.0f; float cy = 0.0f; float rx = 0.0f; float ry = 0.0f; int i; for (i = 0; attr[i]; i += 2) { if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p))); if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p))); } } if (rx > 0.0f && ry > 0.0f) { nsvg__resetPath(p); nsvg__moveTo(p, cx+rx, cy); nsvg__cubicBezTo(p, cx+rx, cy+ry*NSVG_KAPPA90, cx+rx*NSVG_KAPPA90, cy+ry, cx, cy+ry); nsvg__cubicBezTo(p, cx-rx*NSVG_KAPPA90, cy+ry, cx-rx, cy+ry*NSVG_KAPPA90, cx-rx, cy); nsvg__cubicBezTo(p, cx-rx, cy-ry*NSVG_KAPPA90, cx-rx*NSVG_KAPPA90, cy-ry, cx, cy-ry); nsvg__cubicBezTo(p, cx+rx*NSVG_KAPPA90, cy-ry, cx+rx, cy-ry*NSVG_KAPPA90, cx+rx, cy); nsvg__addPath(p, 1); nsvg__addShape(p); } } static void nsvg__parseLine(NSVGparser* p, const char** attr) { float x1 = 0.0; float y1 = 0.0; float x2 = 0.0; float y2 = 0.0; int i; for (i = 0; attr[i]; i += 2) { if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { if (strcmp(attr[i], "x1") == 0) x1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); if (strcmp(attr[i], "y1") == 0) y1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); if (strcmp(attr[i], "x2") == 0) x2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p)); if (strcmp(attr[i], "y2") == 0) y2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p)); } } nsvg__resetPath(p); nsvg__moveTo(p, x1, y1); nsvg__lineTo(p, x2, y2); nsvg__addPath(p, 0); nsvg__addShape(p); } static void nsvg__parsePoly(NSVGparser* p, const char** attr, int closeFlag) { int i; const char* s; float args[2]; int nargs, npts = 0; char item[64]; nsvg__resetPath(p); for (i = 0; attr[i]; i += 2) { if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { if (strcmp(attr[i], "points") == 0) { s = attr[i + 1]; nargs = 0; while (*s) { s = nsvg__getNextPathItem(s, item); args[nargs++] = (float)nsvg__atof(item); if (nargs >= 2) { if (npts == 0) nsvg__moveTo(p, args[0], args[1]); else nsvg__lineTo(p, args[0], args[1]); nargs = 0; npts++; } } } } } nsvg__addPath(p, (char)closeFlag); nsvg__addShape(p); } static void nsvg__parseSVG(NSVGparser* p, const char** attr) { int i; for (i = 0; attr[i]; i += 2) { if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { if (strcmp(attr[i], "width") == 0) { p->image->width = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f); } else if (strcmp(attr[i], "height") == 0) { p->image->height = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f); } else if (strcmp(attr[i], "viewBox") == 0) { const char *s = attr[i + 1]; char buf[64]; s = nsvg__parseNumber(s, buf, 64); p->viewMinx = nsvg__atof(buf); while (*s && (nsvg__isspace(*s) || *s == '%' || *s == ',')) s++; if (!*s) return; s = nsvg__parseNumber(s, buf, 64); p->viewMiny = nsvg__atof(buf); while (*s && (nsvg__isspace(*s) || *s == '%' || *s == ',')) s++; if (!*s) return; s = nsvg__parseNumber(s, buf, 64); p->viewWidth = nsvg__atof(buf); while (*s && (nsvg__isspace(*s) || *s == '%' || *s == ',')) s++; if (!*s) return; s = nsvg__parseNumber(s, buf, 64); p->viewHeight = nsvg__atof(buf); } else if (strcmp(attr[i], "preserveAspectRatio") == 0) { if (strstr(attr[i + 1], "none") != 0) { // No uniform scaling p->alignType = NSVG_ALIGN_NONE; } else { // Parse X align if (strstr(attr[i + 1], "xMin") != 0) p->alignX = NSVG_ALIGN_MIN; else if (strstr(attr[i + 1], "xMid") != 0) p->alignX = NSVG_ALIGN_MID; else if (strstr(attr[i + 1], "xMax") != 0) p->alignX = NSVG_ALIGN_MAX; // Parse X align if (strstr(attr[i + 1], "YMin") != 0) p->alignY = NSVG_ALIGN_MIN; else if (strstr(attr[i + 1], "YMid") != 0) p->alignY = NSVG_ALIGN_MID; else if (strstr(attr[i + 1], "YMax") != 0) p->alignY = NSVG_ALIGN_MAX; // Parse meet/slice p->alignType = NSVG_ALIGN_MEET; if (strstr(attr[i + 1], "slice") != 0) p->alignType = NSVG_ALIGN_SLICE; } } } } } static void nsvg__parseGradient(NSVGparser* p, const char** attr, signed char type) { int i; NSVGgradientData* grad = (NSVGgradientData*)malloc(sizeof(NSVGgradientData)); if (grad == NULL) return; memset(grad, 0, sizeof(NSVGgradientData)); grad->units = NSVG_OBJECT_SPACE; grad->type = type; if (grad->type == NSVG_PAINT_LINEAR_GRADIENT) { grad->linear.x1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT); grad->linear.y1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT); grad->linear.x2 = nsvg__coord(100.0f, NSVG_UNITS_PERCENT); grad->linear.y2 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT); } else if (grad->type == NSVG_PAINT_RADIAL_GRADIENT) { grad->radial.cx = nsvg__coord(50.0f, NSVG_UNITS_PERCENT); grad->radial.cy = nsvg__coord(50.0f, NSVG_UNITS_PERCENT); grad->radial.r = nsvg__coord(50.0f, NSVG_UNITS_PERCENT); } nsvg__xformIdentity(grad->xform); for (i = 0; attr[i]; i += 2) { if (strcmp(attr[i], "id") == 0) { strncpy(grad->id, attr[i+1], 63); grad->id[63] = '\0'; } else if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) { if (strcmp(attr[i], "gradientUnits") == 0) { if (strcmp(attr[i+1], "objectBoundingBox") == 0) grad->units = NSVG_OBJECT_SPACE; else grad->units = NSVG_USER_SPACE; } else if (strcmp(attr[i], "gradientTransform") == 0) { nsvg__parseTransform(grad->xform, attr[i + 1]); } else if (strcmp(attr[i], "cx") == 0) { grad->radial.cx = nsvg__parseCoordinateRaw(attr[i + 1]); } else if (strcmp(attr[i], "cy") == 0) { grad->radial.cy = nsvg__parseCoordinateRaw(attr[i + 1]); } else if (strcmp(attr[i], "r") == 0) { grad->radial.r = nsvg__parseCoordinateRaw(attr[i + 1]); } else if (strcmp(attr[i], "fx") == 0) { grad->radial.fx = nsvg__parseCoordinateRaw(attr[i + 1]); } else if (strcmp(attr[i], "fy") == 0) { grad->radial.fy = nsvg__parseCoordinateRaw(attr[i + 1]); } else if (strcmp(attr[i], "x1") == 0) { grad->linear.x1 = nsvg__parseCoordinateRaw(attr[i + 1]); } else if (strcmp(attr[i], "y1") == 0) { grad->linear.y1 = nsvg__parseCoordinateRaw(attr[i + 1]); } else if (strcmp(attr[i], "x2") == 0) { grad->linear.x2 = nsvg__parseCoordinateRaw(attr[i + 1]); } else if (strcmp(attr[i], "y2") == 0) { grad->linear.y2 = nsvg__parseCoordinateRaw(attr[i + 1]); } else if (strcmp(attr[i], "spreadMethod") == 0) { if (strcmp(attr[i+1], "pad") == 0) grad->spread = NSVG_SPREAD_PAD; else if (strcmp(attr[i+1], "reflect") == 0) grad->spread = NSVG_SPREAD_REFLECT; else if (strcmp(attr[i+1], "repeat") == 0) grad->spread = NSVG_SPREAD_REPEAT; } else if (strcmp(attr[i], "xlink:href") == 0) { const char *href = attr[i+1]; strncpy(grad->ref, href+1, 62); grad->ref[62] = '\0'; } } } grad->next = p->gradients; p->gradients = grad; } static void nsvg__parseGradientStop(NSVGparser* p, const char** attr) { NSVGattrib* curAttr = nsvg__getAttr(p); NSVGgradientData* grad; NSVGgradientStop* stop; int i, idx; curAttr->stopOffset = 0; curAttr->stopColor = 0; curAttr->stopOpacity = 1.0f; for (i = 0; attr[i]; i += 2) { nsvg__parseAttr(p, attr[i], attr[i + 1]); } // Add stop to the last gradient. grad = p->gradients; if (grad == NULL) return; grad->nstops++; grad->stops = (NSVGgradientStop*)realloc(grad->stops, sizeof(NSVGgradientStop)*grad->nstops); if (grad->stops == NULL) return; // Insert idx = grad->nstops-1; for (i = 0; i < grad->nstops-1; i++) { if (curAttr->stopOffset < grad->stops[i].offset) { idx = i; break; } } if (idx != grad->nstops-1) { for (i = grad->nstops-1; i > idx; i--) grad->stops[i] = grad->stops[i-1]; } stop = &grad->stops[idx]; stop->color = curAttr->stopColor; stop->color |= (unsigned int)(curAttr->stopOpacity*255) << 24; stop->offset = curAttr->stopOffset; } static void nsvg__startElement(void* ud, const char* el, const char** attr) { NSVGparser* p = (NSVGparser*)ud; if (p->defsFlag) { // Skip everything but gradients in defs if (strcmp(el, "linearGradient") == 0) { nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT); } else if (strcmp(el, "radialGradient") == 0) { nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT); } else if (strcmp(el, "stop") == 0) { nsvg__parseGradientStop(p, attr); } return; } if (strcmp(el, "g") == 0) { nsvg__pushAttr(p); nsvg__parseAttribs(p, attr); } else if (strcmp(el, "path") == 0) { if (p->pathFlag) // Do not allow nested paths. return; nsvg__pushAttr(p); nsvg__parsePath(p, attr); nsvg__popAttr(p); } else if (strcmp(el, "rect") == 0) { nsvg__pushAttr(p); nsvg__parseRect(p, attr); nsvg__popAttr(p); } else if (strcmp(el, "circle") == 0) { nsvg__pushAttr(p); nsvg__parseCircle(p, attr); nsvg__popAttr(p); } else if (strcmp(el, "ellipse") == 0) { nsvg__pushAttr(p); nsvg__parseEllipse(p, attr); nsvg__popAttr(p); } else if (strcmp(el, "line") == 0) { nsvg__pushAttr(p); nsvg__parseLine(p, attr); nsvg__popAttr(p); } else if (strcmp(el, "polyline") == 0) { nsvg__pushAttr(p); nsvg__parsePoly(p, attr, 0); nsvg__popAttr(p); } else if (strcmp(el, "polygon") == 0) { nsvg__pushAttr(p); nsvg__parsePoly(p, attr, 1); nsvg__popAttr(p); } else if (strcmp(el, "linearGradient") == 0) { nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT); } else if (strcmp(el, "radialGradient") == 0) { nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT); } else if (strcmp(el, "stop") == 0) { nsvg__parseGradientStop(p, attr); } else if (strcmp(el, "defs") == 0) { p->defsFlag = 1; } else if (strcmp(el, "svg") == 0) { nsvg__parseSVG(p, attr); } } static void nsvg__endElement(void* ud, const char* el) { NSVGparser* p = (NSVGparser*)ud; if (strcmp(el, "g") == 0) { nsvg__popAttr(p); } else if (strcmp(el, "path") == 0) { p->pathFlag = 0; } else if (strcmp(el, "defs") == 0) { p->defsFlag = 0; } } static void nsvg__content(void* ud, const char* s) { NSVG_NOTUSED(ud); NSVG_NOTUSED(s); // empty } static void nsvg__imageBounds(NSVGparser* p, float* bounds) { NSVGshape* shape; shape = p->image->shapes; if (shape == NULL) { bounds[0] = bounds[1] = bounds[2] = bounds[3] = 0.0; return; } bounds[0] = shape->bounds[0]; bounds[1] = shape->bounds[1]; bounds[2] = shape->bounds[2]; bounds[3] = shape->bounds[3]; for (shape = shape->next; shape != NULL; shape = shape->next) { bounds[0] = nsvg__minf(bounds[0], shape->bounds[0]); bounds[1] = nsvg__minf(bounds[1], shape->bounds[1]); bounds[2] = nsvg__maxf(bounds[2], shape->bounds[2]); bounds[3] = nsvg__maxf(bounds[3], shape->bounds[3]); } } static float nsvg__viewAlign(float content, float container, int type) { if (type == NSVG_ALIGN_MIN) return 0; else if (type == NSVG_ALIGN_MAX) return container - content; // mid return (container - content) * 0.5f; } static void nsvg__scaleGradient(NSVGgradient* grad, float tx, float ty, float sx, float sy) { float t[6]; nsvg__xformSetTranslation(t, tx, ty); nsvg__xformMultiply (grad->xform, t); nsvg__xformSetScale(t, sx, sy); nsvg__xformMultiply (grad->xform, t); } static void nsvg__scaleToViewbox(NSVGparser* p, const char* units) { NSVGshape* shape; NSVGpath* path; float tx, ty, sx, sy, us, bounds[4], t[6], avgs; int i; float* pt; // Guess image size if not set completely. nsvg__imageBounds(p, bounds); if (p->viewWidth == 0) { if (p->image->width > 0) { p->viewWidth = p->image->width; } else { p->viewMinx = bounds[0]; p->viewWidth = bounds[2] - bounds[0]; } } if (p->viewHeight == 0) { if (p->image->height > 0) { p->viewHeight = p->image->height; } else { p->viewMiny = bounds[1]; p->viewHeight = bounds[3] - bounds[1]; } } if (p->image->width == 0) p->image->width = p->viewWidth; if (p->image->height == 0) p->image->height = p->viewHeight; tx = -p->viewMinx; ty = -p->viewMiny; sx = p->viewWidth > 0 ? p->image->width / p->viewWidth : 0; sy = p->viewHeight > 0 ? p->image->height / p->viewHeight : 0; // Unit scaling us = 1.0f / nsvg__convertToPixels(p, nsvg__coord(1.0f, nsvg__parseUnits(units)), 0.0f, 1.0f); // Fix aspect ratio if (p->alignType == NSVG_ALIGN_MEET) { // fit whole image into viewbox sx = sy = nsvg__minf(sx, sy); tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx; ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy; } else if (p->alignType == NSVG_ALIGN_SLICE) { // fill whole viewbox with image sx = sy = nsvg__maxf(sx, sy); tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx; ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy; } // Transform sx *= us; sy *= us; avgs = (sx+sy) / 2.0f; for (shape = p->image->shapes; shape != NULL; shape = shape->next) { shape->bounds[0] = (shape->bounds[0] + tx) * sx; shape->bounds[1] = (shape->bounds[1] + ty) * sy; shape->bounds[2] = (shape->bounds[2] + tx) * sx; shape->bounds[3] = (shape->bounds[3] + ty) * sy; for (path = shape->paths; path != NULL; path = path->next) { path->bounds[0] = (path->bounds[0] + tx) * sx; path->bounds[1] = (path->bounds[1] + ty) * sy; path->bounds[2] = (path->bounds[2] + tx) * sx; path->bounds[3] = (path->bounds[3] + ty) * sy; for (i =0; i < path->npts; i++) { pt = &path->pts[i*2]; pt[0] = (pt[0] + tx) * sx; pt[1] = (pt[1] + ty) * sy; } } if (shape->fill.type == NSVG_PAINT_LINEAR_GRADIENT || shape->fill.type == NSVG_PAINT_RADIAL_GRADIENT) { nsvg__scaleGradient(shape->fill.gradient, tx,ty, sx,sy); memcpy(t, shape->fill.gradient->xform, sizeof(float)*6); nsvg__xformInverse(shape->fill.gradient->xform, t); } if (shape->stroke.type == NSVG_PAINT_LINEAR_GRADIENT || shape->stroke.type == NSVG_PAINT_RADIAL_GRADIENT) { nsvg__scaleGradient(shape->stroke.gradient, tx,ty, sx,sy); memcpy(t, shape->stroke.gradient->xform, sizeof(float)*6); nsvg__xformInverse(shape->stroke.gradient->xform, t); } shape->strokeWidth *= avgs; shape->strokeDashOffset *= avgs; for (i = 0; i < shape->strokeDashCount; i++) shape->strokeDashArray[i] *= avgs; } } static void nsvg__createGradients(NSVGparser* p) { NSVGshape* shape; for (shape = p->image->shapes; shape != NULL; shape = shape->next) { if (shape->fill.type == NSVG_PAINT_UNDEF) { if (shape->fillGradient[0] != '\0') { float inv[6], localBounds[4]; nsvg__xformInverse(inv, shape->xform); nsvg__getLocalBounds(localBounds, shape, inv); shape->fill.gradient = nsvg__createGradient(p, shape->fillGradient, localBounds, shape->xform, &shape->fill.type); } if (shape->fill.type == NSVG_PAINT_UNDEF) { shape->fill.type = NSVG_PAINT_NONE; } } if (shape->stroke.type == NSVG_PAINT_UNDEF) { if (shape->strokeGradient[0] != '\0') { float inv[6], localBounds[4]; nsvg__xformInverse(inv, shape->xform); nsvg__getLocalBounds(localBounds, shape, inv); shape->stroke.gradient = nsvg__createGradient(p, shape->strokeGradient, localBounds, shape->xform, &shape->stroke.type); } if (shape->stroke.type == NSVG_PAINT_UNDEF) { shape->stroke.type = NSVG_PAINT_NONE; } } } } NSVGimage* nsvgParse(char* input, const char* units, float dpi) { NSVGparser* p; NSVGimage* ret = 0; p = nsvg__createParser(); if (p == NULL) { return NULL; } p->dpi = dpi; nsvg__parseXML(input, nsvg__startElement, nsvg__endElement, nsvg__content, p); // Create gradients after all definitions have been parsed nsvg__createGradients(p); // Scale to viewBox nsvg__scaleToViewbox(p, units); ret = p->image; p->image = NULL; nsvg__deleteParser(p); return ret; } NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi) { FILE* fp = NULL; size_t size; char* data = NULL; NSVGimage* image = NULL; fp = fopen(filename, "rb"); if (!fp) goto error; fseek(fp, 0, SEEK_END); size = ftell(fp); fseek(fp, 0, SEEK_SET); data = (char*)malloc(size+1); if (data == NULL) goto error; if (fread(data, 1, size, fp) != size) goto error; data[size] = '\0'; // Must be null terminated. fclose(fp); image = nsvgParse(data, units, dpi); free(data); return image; error: if (fp) fclose(fp); if (data) free(data); if (image) nsvgDelete(image); return NULL; } NSVGpath* nsvgDuplicatePath(NSVGpath* p) { NSVGpath* res = NULL; if (p == NULL) return NULL; res = (NSVGpath*)malloc(sizeof(NSVGpath)); if (res == NULL) goto error; memset(res, 0, sizeof(NSVGpath)); res->pts = (float*)malloc(p->npts*2*sizeof(float)); if (res->pts == NULL) goto error; memcpy(res->pts, p->pts, p->npts * sizeof(float) * 2); res->npts = p->npts; memcpy(res->bounds, p->bounds, sizeof(p->bounds)); res->closed = p->closed; return res; error: if (res != NULL) { free(res->pts); free(res); } return NULL; } void nsvgDelete(NSVGimage* image) { NSVGshape *snext, *shape; if (image == NULL) return; shape = image->shapes; while (shape != NULL) { snext = shape->next; nsvg__deletePaths(shape->paths); nsvg__deletePaint(&shape->fill); nsvg__deletePaint(&shape->stroke); free(shape); shape = snext; } free(image); } #endif // NANOSVG_IMPLEMENTATION #endif // NANOSVG_H chawan-v0.4.0/adapter/img/nanosvg.nim000066400000000000000000000043301520232313100175060ustar00rootroot00000000000000{.push raises: [].} import std/posix import ../protocol/lcgi {.passc: "-I" & currentSourcePath().untilLast('/').} {.push header: """ #define NANOSVG_IMPLEMENTATION #define NANOSVG_ALL_COLOR_KEYWORDS #include "nanosvg.h" """.} type NSVGimage {.importc.} = object width: cfloat height: cfloat shapes: ptr NSVGShape NSVGShape {.importc, incompleteStruct.} = object {.push importc, cdecl.} proc nsvgParse(input, units: cstring; dpi: cfloat): ptr NSVGimage proc nsvgDelete(image: ptr NSVGimage) {.pop.} {.pop.} # nanosvg.h {.push header: """ #define NANOSVGRAST_IMPLEMENTATION #include "nanosvgrast.h" """.} type NSVGrasterizer {.incompleteStruct, importc.} = object {.push importc, cdecl.} proc nsvgCreateRasterizer(): ptr NSVGrasterizer proc nsvgRasterize(r: ptr NSVGrasterizer; image: ptr NSVGimage; tx, ty, scale: cfloat; dst: ptr uint8; w, h, stride: cint) proc nsvgDeleteRasterizer(r: ptr NSVGrasterizer) {.pop.} {.pop.} # nanosvgrast.h proc main() = let os = newPosixStream(STDOUT_FILENO) enterNetworkSandbox() case getEnvEmpty("MAPPED_URI_PATH") of "decode": # Unfortunate as it is, I can't just mmap the string because nanosvg # wants to modify it. var ss = newPosixStream(STDIN_FILENO).readAll() let image = nsvgParse(cstring(ss), "px", 96) if image == nil or image.width < 0 or image.height < 0 or cdouble(image.width) >= cdouble(cint.high) or cdouble(image.height) >= cdouble(cint.high): cgiDie(ceInternalError, "decoding failed") let width = cint(image.width) let height = cint(image.height) discard os.writeLoop("Cha-Image-Dimensions: " & $width & 'x' & $height & "\n\n") for hdr in getEnvEmpty("REQUEST_HEADERS").split('\n'): let v = hdr.after(':').strip() if hdr.until(':') == "Cha-Image-Info-Only" and v == "1": return if width > 0 and height > 0: let r = nsvgCreateRasterizer() if r == nil: quit(1) var obuf = newSeqUninit[uint8](width * height * 4) r.nsvgRasterize(image, 0, 0, 1, addr obuf[0], width, height, width * 4) discard os.writeLoop(obuf) r.nsvgDeleteRasterizer() image.nsvgDelete() else: cgiDie(ceInternalError, "not supported") main() {.pop.} # raises: [] chawan-v0.4.0/adapter/img/nanosvgrast.h000066400000000000000000001133501520232313100200470ustar00rootroot00000000000000/* * Copyright (c) 2013-14 Mikko Mononen memon@inside.org * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * * The polygon rasterization is heavily based on stb_truetype rasterizer * by Sean Barrett - http://nothings.org/ * */ #ifndef NANOSVGRAST_H #define NANOSVGRAST_H #include "nanosvg.h" #ifndef NANOSVGRAST_CPLUSPLUS #ifdef __cplusplus extern "C" { #endif #endif typedef struct NSVGrasterizer NSVGrasterizer; /* Example Usage: // Load SVG NSVGimage* image; image = nsvgParseFromFile("test.svg", "px", 96); // Create rasterizer (can be used to render multiple images). struct NSVGrasterizer* rast = nsvgCreateRasterizer(); // Allocate memory for image unsigned char* img = malloc(w*h*4); // Rasterize nsvgRasterize(rast, image, 0,0,1, img, w, h, w*4); */ // Allocated rasterizer context. NSVGrasterizer* nsvgCreateRasterizer(void); // Rasterizes SVG image, returns RGBA image (non-premultiplied alpha) // r - pointer to rasterizer context // image - pointer to image to rasterize // tx,ty - image offset (applied after scaling) // scale - image scale // dst - pointer to destination image data, 4 bytes per pixel (RGBA) // w - width of the image to render // h - height of the image to render // stride - number of bytes per scaleline in the destination buffer void nsvgRasterize(NSVGrasterizer* r, NSVGimage* image, float tx, float ty, float scale, unsigned char* dst, int w, int h, int stride); // Deletes rasterizer context. void nsvgDeleteRasterizer(NSVGrasterizer*); #ifndef NANOSVGRAST_CPLUSPLUS #ifdef __cplusplus } #endif #endif #ifdef NANOSVGRAST_IMPLEMENTATION #include #include #include #define NSVG__SUBSAMPLES 5 #define NSVG__FIXSHIFT 10 #define NSVG__FIX (1 << NSVG__FIXSHIFT) #define NSVG__FIXMASK (NSVG__FIX-1) #define NSVG__MEMPAGE_SIZE 1024 typedef struct NSVGedge { float x0,y0, x1,y1; int dir; struct NSVGedge* next; } NSVGedge; typedef struct NSVGpoint { float x, y; float dx, dy; float len; float dmx, dmy; unsigned char flags; } NSVGpoint; typedef struct NSVGactiveEdge { int x,dx; float ey; int dir; struct NSVGactiveEdge *next; } NSVGactiveEdge; typedef struct NSVGmemPage { unsigned char mem[NSVG__MEMPAGE_SIZE]; int size; struct NSVGmemPage* next; } NSVGmemPage; typedef struct NSVGcachedPaint { signed char type; char spread; float xform[6]; unsigned int colors[256]; } NSVGcachedPaint; struct NSVGrasterizer { float px, py; float tessTol; float distTol; NSVGedge* edges; int nedges; int cedges; NSVGpoint* points; int npoints; int cpoints; NSVGpoint* points2; int npoints2; int cpoints2; NSVGactiveEdge* freelist; NSVGmemPage* pages; NSVGmemPage* curpage; unsigned char* scanline; int cscanline; unsigned char* bitmap; int width, height, stride; }; NSVGrasterizer* nsvgCreateRasterizer(void) { NSVGrasterizer* r = (NSVGrasterizer*)malloc(sizeof(NSVGrasterizer)); if (r == NULL) goto error; memset(r, 0, sizeof(NSVGrasterizer)); r->tessTol = 0.25f; r->distTol = 0.01f; return r; error: nsvgDeleteRasterizer(r); return NULL; } void nsvgDeleteRasterizer(NSVGrasterizer* r) { NSVGmemPage* p; if (r == NULL) return; p = r->pages; while (p != NULL) { NSVGmemPage* next = p->next; free(p); p = next; } if (r->edges) free(r->edges); if (r->points) free(r->points); if (r->points2) free(r->points2); if (r->scanline) free(r->scanline); free(r); } static NSVGmemPage* nsvg__nextPage(NSVGrasterizer* r, NSVGmemPage* cur) { NSVGmemPage *newp; // If using existing chain, return the next page in chain if (cur != NULL && cur->next != NULL) { return cur->next; } // Alloc new page newp = (NSVGmemPage*)malloc(sizeof(NSVGmemPage)); if (newp == NULL) return NULL; memset(newp, 0, sizeof(NSVGmemPage)); // Add to linked list if (cur != NULL) cur->next = newp; else r->pages = newp; return newp; } static void nsvg__resetPool(NSVGrasterizer* r) { NSVGmemPage* p = r->pages; while (p != NULL) { p->size = 0; p = p->next; } r->curpage = r->pages; } static unsigned char* nsvg__alloc(NSVGrasterizer* r, int size) { unsigned char* buf; if (size > NSVG__MEMPAGE_SIZE) return NULL; if (r->curpage == NULL || r->curpage->size+size > NSVG__MEMPAGE_SIZE) { r->curpage = nsvg__nextPage(r, r->curpage); } buf = &r->curpage->mem[r->curpage->size]; r->curpage->size += size; return buf; } static int nsvg__ptEquals(float x1, float y1, float x2, float y2, float tol) { float dx = x2 - x1; float dy = y2 - y1; return dx*dx + dy*dy < tol*tol; } static void nsvg__addPathPoint(NSVGrasterizer* r, float x, float y, int flags) { NSVGpoint* pt; if (r->npoints > 0) { pt = &r->points[r->npoints-1]; if (nsvg__ptEquals(pt->x,pt->y, x,y, r->distTol)) { pt->flags = (unsigned char)(pt->flags | flags); return; } } if (r->npoints+1 > r->cpoints) { r->cpoints = r->cpoints > 0 ? r->cpoints * 2 : 64; r->points = (NSVGpoint*)realloc(r->points, sizeof(NSVGpoint) * r->cpoints); if (r->points == NULL) return; } pt = &r->points[r->npoints]; pt->x = x; pt->y = y; pt->flags = (unsigned char)flags; r->npoints++; } static void nsvg__appendPathPoint(NSVGrasterizer* r, NSVGpoint pt) { if (r->npoints+1 > r->cpoints) { r->cpoints = r->cpoints > 0 ? r->cpoints * 2 : 64; r->points = (NSVGpoint*)realloc(r->points, sizeof(NSVGpoint) * r->cpoints); if (r->points == NULL) return; } r->points[r->npoints] = pt; r->npoints++; } static void nsvg__duplicatePoints(NSVGrasterizer* r) { if (r->npoints > r->cpoints2) { r->cpoints2 = r->npoints; r->points2 = (NSVGpoint*)realloc(r->points2, sizeof(NSVGpoint) * r->cpoints2); if (r->points2 == NULL) return; } memcpy(r->points2, r->points, sizeof(NSVGpoint) * r->npoints); r->npoints2 = r->npoints; } static void nsvg__addEdge(NSVGrasterizer* r, float x0, float y0, float x1, float y1) { NSVGedge* e; // Skip horizontal edges if (y0 == y1) return; if (r->nedges+1 > r->cedges) { r->cedges = r->cedges > 0 ? r->cedges * 2 : 64; r->edges = (NSVGedge*)realloc(r->edges, sizeof(NSVGedge) * r->cedges); if (r->edges == NULL) return; } e = &r->edges[r->nedges]; r->nedges++; if (y0 < y1) { e->x0 = x0; e->y0 = y0; e->x1 = x1; e->y1 = y1; e->dir = 1; } else { e->x0 = x1; e->y0 = y1; e->x1 = x0; e->y1 = y0; e->dir = -1; } } static float nsvg__normalize(float *x, float* y) { float d = sqrtf((*x)*(*x) + (*y)*(*y)); if (d > 1e-6f) { float id = 1.0f / d; *x *= id; *y *= id; } return d; } static float nsvg__absf(float x) { return x < 0 ? -x : x; } static float nsvg__roundf(float x) { return (x >= 0) ? floorf(x + 0.5) : ceilf(x - 0.5); } static void nsvg__flattenCubicBez(NSVGrasterizer* r, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, int level, int type) { float x12,y12,x23,y23,x34,y34,x123,y123,x234,y234,x1234,y1234; float dx,dy,d2,d3; if (level > 10) return; x12 = (x1+x2)*0.5f; y12 = (y1+y2)*0.5f; x23 = (x2+x3)*0.5f; y23 = (y2+y3)*0.5f; x34 = (x3+x4)*0.5f; y34 = (y3+y4)*0.5f; x123 = (x12+x23)*0.5f; y123 = (y12+y23)*0.5f; dx = x4 - x1; dy = y4 - y1; d2 = nsvg__absf((x2 - x4) * dy - (y2 - y4) * dx); d3 = nsvg__absf((x3 - x4) * dy - (y3 - y4) * dx); if ((d2 + d3)*(d2 + d3) < r->tessTol * (dx*dx + dy*dy)) { nsvg__addPathPoint(r, x4, y4, type); return; } x234 = (x23+x34)*0.5f; y234 = (y23+y34)*0.5f; x1234 = (x123+x234)*0.5f; y1234 = (y123+y234)*0.5f; nsvg__flattenCubicBez(r, x1,y1, x12,y12, x123,y123, x1234,y1234, level+1, 0); nsvg__flattenCubicBez(r, x1234,y1234, x234,y234, x34,y34, x4,y4, level+1, type); } static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float scale) { int i, j; NSVGpath* path; for (path = shape->paths; path != NULL; path = path->next) { r->npoints = 0; // Flatten path nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0); for (i = 0; i < path->npts-1; i += 3) { float* p = &path->pts[i*2]; nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, 0); } // Close path nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0); // Build edges for (i = 0, j = r->npoints-1; i < r->npoints; j = i++) nsvg__addEdge(r, r->points[j].x, r->points[j].y, r->points[i].x, r->points[i].y); } } enum NSVGpointFlags { NSVG_PT_CORNER = 0x01, NSVG_PT_BEVEL = 0x02, NSVG_PT_LEFT = 0x04 }; static void nsvg__initClosed(NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth) { float w = lineWidth * 0.5f; float dx = p1->x - p0->x; float dy = p1->y - p0->y; float len = nsvg__normalize(&dx, &dy); float px = p0->x + dx*len*0.5f, py = p0->y + dy*len*0.5f; float dlx = dy, dly = -dx; float lx = px - dlx*w, ly = py - dly*w; float rx = px + dlx*w, ry = py + dly*w; left->x = lx; left->y = ly; right->x = rx; right->y = ry; } static void nsvg__buttCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int connect) { float w = lineWidth * 0.5f; float px = p->x, py = p->y; float dlx = dy, dly = -dx; float lx = px - dlx*w, ly = py - dly*w; float rx = px + dlx*w, ry = py + dly*w; nsvg__addEdge(r, lx, ly, rx, ry); if (connect) { nsvg__addEdge(r, left->x, left->y, lx, ly); nsvg__addEdge(r, rx, ry, right->x, right->y); } left->x = lx; left->y = ly; right->x = rx; right->y = ry; } static void nsvg__squareCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int connect) { float w = lineWidth * 0.5f; float px = p->x - dx*w, py = p->y - dy*w; float dlx = dy, dly = -dx; float lx = px - dlx*w, ly = py - dly*w; float rx = px + dlx*w, ry = py + dly*w; nsvg__addEdge(r, lx, ly, rx, ry); if (connect) { nsvg__addEdge(r, left->x, left->y, lx, ly); nsvg__addEdge(r, rx, ry, right->x, right->y); } left->x = lx; left->y = ly; right->x = rx; right->y = ry; } #ifndef NSVG_PI #define NSVG_PI (3.14159265358979323846264338327f) #endif static void nsvg__roundCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int ncap, int connect) { int i; float w = lineWidth * 0.5f; float px = p->x, py = p->y; float dlx = dy, dly = -dx; float lx = 0, ly = 0, rx = 0, ry = 0, prevx = 0, prevy = 0; for (i = 0; i < ncap; i++) { float a = (float)i/(float)(ncap-1)*NSVG_PI; float ax = cosf(a) * w, ay = sinf(a) * w; float x = px - dlx*ax - dx*ay; float y = py - dly*ax - dy*ay; if (i > 0) nsvg__addEdge(r, prevx, prevy, x, y); prevx = x; prevy = y; if (i == 0) { lx = x; ly = y; } else if (i == ncap-1) { rx = x; ry = y; } } if (connect) { nsvg__addEdge(r, left->x, left->y, lx, ly); nsvg__addEdge(r, rx, ry, right->x, right->y); } left->x = lx; left->y = ly; right->x = rx; right->y = ry; } static void nsvg__bevelJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth) { float w = lineWidth * 0.5f; float dlx0 = p0->dy, dly0 = -p0->dx; float dlx1 = p1->dy, dly1 = -p1->dx; float lx0 = p1->x - (dlx0 * w), ly0 = p1->y - (dly0 * w); float rx0 = p1->x + (dlx0 * w), ry0 = p1->y + (dly0 * w); float lx1 = p1->x - (dlx1 * w), ly1 = p1->y - (dly1 * w); float rx1 = p1->x + (dlx1 * w), ry1 = p1->y + (dly1 * w); nsvg__addEdge(r, lx0, ly0, left->x, left->y); nsvg__addEdge(r, lx1, ly1, lx0, ly0); nsvg__addEdge(r, right->x, right->y, rx0, ry0); nsvg__addEdge(r, rx0, ry0, rx1, ry1); left->x = lx1; left->y = ly1; right->x = rx1; right->y = ry1; } static void nsvg__miterJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth) { float w = lineWidth * 0.5f; float dlx0 = p0->dy, dly0 = -p0->dx; float dlx1 = p1->dy, dly1 = -p1->dx; float lx0, rx0, lx1, rx1; float ly0, ry0, ly1, ry1; if (p1->flags & NSVG_PT_LEFT) { lx0 = lx1 = p1->x - p1->dmx * w; ly0 = ly1 = p1->y - p1->dmy * w; nsvg__addEdge(r, lx1, ly1, left->x, left->y); rx0 = p1->x + (dlx0 * w); ry0 = p1->y + (dly0 * w); rx1 = p1->x + (dlx1 * w); ry1 = p1->y + (dly1 * w); nsvg__addEdge(r, right->x, right->y, rx0, ry0); nsvg__addEdge(r, rx0, ry0, rx1, ry1); } else { lx0 = p1->x - (dlx0 * w); ly0 = p1->y - (dly0 * w); lx1 = p1->x - (dlx1 * w); ly1 = p1->y - (dly1 * w); nsvg__addEdge(r, lx0, ly0, left->x, left->y); nsvg__addEdge(r, lx1, ly1, lx0, ly0); rx0 = rx1 = p1->x + p1->dmx * w; ry0 = ry1 = p1->y + p1->dmy * w; nsvg__addEdge(r, right->x, right->y, rx1, ry1); } left->x = lx1; left->y = ly1; right->x = rx1; right->y = ry1; } static void nsvg__roundJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth, int ncap) { int i, n; float w = lineWidth * 0.5f; float dlx0 = p0->dy, dly0 = -p0->dx; float dlx1 = p1->dy, dly1 = -p1->dx; float a0 = atan2f(dly0, dlx0); float a1 = atan2f(dly1, dlx1); float da = a1 - a0; float lx, ly, rx, ry; if (da < NSVG_PI) da += NSVG_PI*2; if (da > NSVG_PI) da -= NSVG_PI*2; n = (int)ceilf((nsvg__absf(da) / NSVG_PI) * (float)ncap); if (n < 2) n = 2; if (n > ncap) n = ncap; lx = left->x; ly = left->y; rx = right->x; ry = right->y; for (i = 0; i < n; i++) { float u = (float)i/(float)(n-1); float a = a0 + u*da; float ax = cosf(a) * w, ay = sinf(a) * w; float lx1 = p1->x - ax, ly1 = p1->y - ay; float rx1 = p1->x + ax, ry1 = p1->y + ay; nsvg__addEdge(r, lx1, ly1, lx, ly); nsvg__addEdge(r, rx, ry, rx1, ry1); lx = lx1; ly = ly1; rx = rx1; ry = ry1; } left->x = lx; left->y = ly; right->x = rx; right->y = ry; } static void nsvg__straightJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p1, float lineWidth) { float w = lineWidth * 0.5f; float lx = p1->x - (p1->dmx * w), ly = p1->y - (p1->dmy * w); float rx = p1->x + (p1->dmx * w), ry = p1->y + (p1->dmy * w); nsvg__addEdge(r, lx, ly, left->x, left->y); nsvg__addEdge(r, right->x, right->y, rx, ry); left->x = lx; left->y = ly; right->x = rx; right->y = ry; } static int nsvg__curveDivs(float r, float arc, float tol) { float da = acosf(r / (r + tol)) * 2.0f; int divs = (int)ceilf(arc / da); if (divs < 2) divs = 2; return divs; } static void nsvg__expandStroke(NSVGrasterizer* r, NSVGpoint* points, int npoints, int closed, int lineJoin, int lineCap, float lineWidth) { int ncap = nsvg__curveDivs(lineWidth*0.5f, NSVG_PI, r->tessTol); // Calculate divisions per half circle. NSVGpoint left = {0,0,0,0,0,0,0,0}, right = {0,0,0,0,0,0,0,0}, firstLeft = {0,0,0,0,0,0,0,0}, firstRight = {0,0,0,0,0,0,0,0}; NSVGpoint* p0, *p1; int j, s, e; // Build stroke edges if (closed) { // Looping p0 = &points[npoints-1]; p1 = &points[0]; s = 0; e = npoints; } else { // Add cap p0 = &points[0]; p1 = &points[1]; s = 1; e = npoints-1; } if (closed) { nsvg__initClosed(&left, &right, p0, p1, lineWidth); firstLeft = left; firstRight = right; } else { // Add cap float dx = p1->x - p0->x; float dy = p1->y - p0->y; nsvg__normalize(&dx, &dy); if (lineCap == NSVG_CAP_BUTT) nsvg__buttCap(r, &left, &right, p0, dx, dy, lineWidth, 0); else if (lineCap == NSVG_CAP_SQUARE) nsvg__squareCap(r, &left, &right, p0, dx, dy, lineWidth, 0); else if (lineCap == NSVG_CAP_ROUND) nsvg__roundCap(r, &left, &right, p0, dx, dy, lineWidth, ncap, 0); } for (j = s; j < e; ++j) { if (p1->flags & NSVG_PT_CORNER) { if (lineJoin == NSVG_JOIN_ROUND) nsvg__roundJoin(r, &left, &right, p0, p1, lineWidth, ncap); else if (lineJoin == NSVG_JOIN_BEVEL || (p1->flags & NSVG_PT_BEVEL)) nsvg__bevelJoin(r, &left, &right, p0, p1, lineWidth); else nsvg__miterJoin(r, &left, &right, p0, p1, lineWidth); } else { nsvg__straightJoin(r, &left, &right, p1, lineWidth); } p0 = p1++; } if (closed) { // Loop it nsvg__addEdge(r, firstLeft.x, firstLeft.y, left.x, left.y); nsvg__addEdge(r, right.x, right.y, firstRight.x, firstRight.y); } else { // Add cap float dx = p1->x - p0->x; float dy = p1->y - p0->y; nsvg__normalize(&dx, &dy); if (lineCap == NSVG_CAP_BUTT) nsvg__buttCap(r, &right, &left, p1, -dx, -dy, lineWidth, 1); else if (lineCap == NSVG_CAP_SQUARE) nsvg__squareCap(r, &right, &left, p1, -dx, -dy, lineWidth, 1); else if (lineCap == NSVG_CAP_ROUND) nsvg__roundCap(r, &right, &left, p1, -dx, -dy, lineWidth, ncap, 1); } } static void nsvg__prepareStroke(NSVGrasterizer* r, float miterLimit, int lineJoin) { int i, j; NSVGpoint* p0, *p1; p0 = &r->points[r->npoints-1]; p1 = &r->points[0]; for (i = 0; i < r->npoints; i++) { // Calculate segment direction and length p0->dx = p1->x - p0->x; p0->dy = p1->y - p0->y; p0->len = nsvg__normalize(&p0->dx, &p0->dy); // Advance p0 = p1++; } // calculate joins p0 = &r->points[r->npoints-1]; p1 = &r->points[0]; for (j = 0; j < r->npoints; j++) { float dlx0, dly0, dlx1, dly1, dmr2, cross; dlx0 = p0->dy; dly0 = -p0->dx; dlx1 = p1->dy; dly1 = -p1->dx; // Calculate extrusions p1->dmx = (dlx0 + dlx1) * 0.5f; p1->dmy = (dly0 + dly1) * 0.5f; dmr2 = p1->dmx*p1->dmx + p1->dmy*p1->dmy; if (dmr2 > 0.000001f) { float s2 = 1.0f / dmr2; if (s2 > 600.0f) { s2 = 600.0f; } p1->dmx *= s2; p1->dmy *= s2; } // Clear flags, but keep the corner. p1->flags = (p1->flags & NSVG_PT_CORNER) ? NSVG_PT_CORNER : 0; // Keep track of left turns. cross = p1->dx * p0->dy - p0->dx * p1->dy; if (cross > 0.0f) p1->flags |= NSVG_PT_LEFT; // Check to see if the corner needs to be beveled. if (p1->flags & NSVG_PT_CORNER) { if ((dmr2 * miterLimit*miterLimit) < 1.0f || lineJoin == NSVG_JOIN_BEVEL || lineJoin == NSVG_JOIN_ROUND) { p1->flags |= NSVG_PT_BEVEL; } } p0 = p1++; } } static void nsvg__flattenShapeStroke(NSVGrasterizer* r, NSVGshape* shape, float scale) { int i, j, closed; NSVGpath* path; NSVGpoint* p0, *p1; float miterLimit = shape->miterLimit; int lineJoin = shape->strokeLineJoin; int lineCap = shape->strokeLineCap; float lineWidth = shape->strokeWidth * scale; for (path = shape->paths; path != NULL; path = path->next) { // Flatten path r->npoints = 0; nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, NSVG_PT_CORNER); for (i = 0; i < path->npts-1; i += 3) { float* p = &path->pts[i*2]; nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, NSVG_PT_CORNER); } if (r->npoints < 2) continue; closed = path->closed; // If the first and last points are the same, remove the last, mark as closed path. p0 = &r->points[r->npoints-1]; p1 = &r->points[0]; if (nsvg__ptEquals(p0->x,p0->y, p1->x,p1->y, r->distTol)) { r->npoints--; p0 = &r->points[r->npoints-1]; closed = 1; } if (shape->strokeDashCount > 0) { int idash = 0, dashState = 1; float totalDist = 0, dashLen, allDashLen, dashOffset; NSVGpoint cur; if (closed) nsvg__appendPathPoint(r, r->points[0]); // Duplicate points -> points2. nsvg__duplicatePoints(r); r->npoints = 0; cur = r->points2[0]; nsvg__appendPathPoint(r, cur); // Figure out dash offset. allDashLen = 0; for (j = 0; j < shape->strokeDashCount; j++) allDashLen += shape->strokeDashArray[j]; if (shape->strokeDashCount & 1) allDashLen *= 2.0f; // Find location inside pattern dashOffset = fmodf(shape->strokeDashOffset, allDashLen); if (dashOffset < 0.0f) dashOffset += allDashLen; while (dashOffset > shape->strokeDashArray[idash]) { dashOffset -= shape->strokeDashArray[idash]; idash = (idash + 1) % shape->strokeDashCount; } dashLen = (shape->strokeDashArray[idash] - dashOffset) * scale; for (j = 1; j < r->npoints2; ) { float dx = r->points2[j].x - cur.x; float dy = r->points2[j].y - cur.y; float dist = sqrtf(dx*dx + dy*dy); if ((totalDist + dist) > dashLen) { // Calculate intermediate point float d = (dashLen - totalDist) / dist; float x = cur.x + dx * d; float y = cur.y + dy * d; nsvg__addPathPoint(r, x, y, NSVG_PT_CORNER); // Stroke if (r->npoints > 1 && dashState) { nsvg__prepareStroke(r, miterLimit, lineJoin); nsvg__expandStroke(r, r->points, r->npoints, 0, lineJoin, lineCap, lineWidth); } // Advance dash pattern dashState = !dashState; idash = (idash+1) % shape->strokeDashCount; dashLen = shape->strokeDashArray[idash] * scale; // Restart cur.x = x; cur.y = y; cur.flags = NSVG_PT_CORNER; totalDist = 0.0f; r->npoints = 0; nsvg__appendPathPoint(r, cur); } else { totalDist += dist; cur = r->points2[j]; nsvg__appendPathPoint(r, cur); j++; } } // Stroke any leftover path if (r->npoints > 1 && dashState) { nsvg__prepareStroke(r, miterLimit, lineJoin); nsvg__expandStroke(r, r->points, r->npoints, 0, lineJoin, lineCap, lineWidth); } } else { nsvg__prepareStroke(r, miterLimit, lineJoin); nsvg__expandStroke(r, r->points, r->npoints, closed, lineJoin, lineCap, lineWidth); } } } static int nsvg__cmpEdge(const void *p, const void *q) { const NSVGedge* a = (const NSVGedge*)p; const NSVGedge* b = (const NSVGedge*)q; if (a->y0 < b->y0) return -1; if (a->y0 > b->y0) return 1; return 0; } static NSVGactiveEdge* nsvg__addActive(NSVGrasterizer* r, NSVGedge* e, float startPoint) { NSVGactiveEdge* z; if (r->freelist != NULL) { // Restore from freelist. z = r->freelist; r->freelist = z->next; } else { // Alloc new edge. z = (NSVGactiveEdge*)nsvg__alloc(r, sizeof(NSVGactiveEdge)); if (z == NULL) return NULL; } float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); // STBTT_assert(e->y0 <= start_point); // round dx down to avoid going too far if (dxdy < 0) z->dx = (int)(-nsvg__roundf(NSVG__FIX * -dxdy)); else z->dx = (int)nsvg__roundf(NSVG__FIX * dxdy); z->x = (int)nsvg__roundf(NSVG__FIX * (e->x0 + dxdy * (startPoint - e->y0))); // z->x -= off_x * FIX; z->ey = e->y1; z->next = 0; z->dir = e->dir; return z; } static void nsvg__freeActive(NSVGrasterizer* r, NSVGactiveEdge* z) { z->next = r->freelist; r->freelist = z; } static void nsvg__fillScanline(unsigned char* scanline, int len, int x0, int x1, int maxWeight, int* xmin, int* xmax) { int i = x0 >> NSVG__FIXSHIFT; int j = x1 >> NSVG__FIXSHIFT; if (i < *xmin) *xmin = i; if (j > *xmax) *xmax = j; if (i < len && j >= 0) { if (i == j) { // x0,x1 are the same pixel, so compute combined coverage scanline[i] = (unsigned char)(scanline[i] + ((x1 - x0) * maxWeight >> NSVG__FIXSHIFT)); } else { if (i >= 0) // add antialiasing for x0 scanline[i] = (unsigned char)(scanline[i] + (((NSVG__FIX - (x0 & NSVG__FIXMASK)) * maxWeight) >> NSVG__FIXSHIFT)); else i = -1; // clip if (j < len) // add antialiasing for x1 scanline[j] = (unsigned char)(scanline[j] + (((x1 & NSVG__FIXMASK) * maxWeight) >> NSVG__FIXSHIFT)); else j = len; // clip for (++i; i < j; ++i) // fill pixels between x0 and x1 scanline[i] = (unsigned char)(scanline[i] + maxWeight); } } } // note: this routine clips fills that extend off the edges... ideally this // wouldn't happen, but it could happen if the truetype glyph bounding boxes // are wrong, or if the user supplies a too-small bitmap static void nsvg__fillActiveEdges(unsigned char* scanline, int len, NSVGactiveEdge* e, int maxWeight, int* xmin, int* xmax, char fillRule) { // non-zero winding fill int x0 = 0, w = 0; if (fillRule == NSVG_FILLRULE_NONZERO) { // Non-zero while (e != NULL) { if (w == 0) { // if we're currently at zero, we need to record the edge start point x0 = e->x; w += e->dir; } else { int x1 = e->x; w += e->dir; // if we went to zero, we need to draw if (w == 0) nsvg__fillScanline(scanline, len, x0, x1, maxWeight, xmin, xmax); } e = e->next; } } else if (fillRule == NSVG_FILLRULE_EVENODD) { // Even-odd while (e != NULL) { if (w == 0) { // if we're currently at zero, we need to record the edge start point x0 = e->x; w = 1; } else { int x1 = e->x; w = 0; nsvg__fillScanline(scanline, len, x0, x1, maxWeight, xmin, xmax); } e = e->next; } } } static float nsvg__clampf(float a, float mn, float mx) { if (isnan(a)) return mn; return a < mn ? mn : (a > mx ? mx : a); } static unsigned int nsvg__RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) { return ((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16) | ((unsigned int)a << 24); } static unsigned int nsvg__lerpRGBA(unsigned int c0, unsigned int c1, float u) { int iu = (int)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f); int r = (((c0) & 0xff)*(256-iu) + (((c1) & 0xff)*iu)) >> 8; int g = (((c0>>8) & 0xff)*(256-iu) + (((c1>>8) & 0xff)*iu)) >> 8; int b = (((c0>>16) & 0xff)*(256-iu) + (((c1>>16) & 0xff)*iu)) >> 8; int a = (((c0>>24) & 0xff)*(256-iu) + (((c1>>24) & 0xff)*iu)) >> 8; return nsvg__RGBA((unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a); } static unsigned int nsvg__applyOpacity(unsigned int c, float u) { int iu = (int)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f); int r = (c) & 0xff; int g = (c>>8) & 0xff; int b = (c>>16) & 0xff; int a = (((c>>24) & 0xff)*iu) >> 8; return nsvg__RGBA((unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a); } static inline int nsvg__div255(int x) { return ((x+1) * 257) >> 16; } static void nsvg__scanlineSolid(unsigned char* dst, int count, unsigned char* cover, int x, int y, float tx, float ty, float scale, NSVGcachedPaint* cache) { if (cache->type == NSVG_PAINT_COLOR) { int i, cr, cg, cb, ca; cr = cache->colors[0] & 0xff; cg = (cache->colors[0] >> 8) & 0xff; cb = (cache->colors[0] >> 16) & 0xff; ca = (cache->colors[0] >> 24) & 0xff; for (i = 0; i < count; i++) { int r,g,b; int a = nsvg__div255((int)cover[0] * ca); int ia = 255 - a; // Premultiply r = nsvg__div255(cr * a); g = nsvg__div255(cg * a); b = nsvg__div255(cb * a); // Blend over r += nsvg__div255(ia * (int)dst[0]); g += nsvg__div255(ia * (int)dst[1]); b += nsvg__div255(ia * (int)dst[2]); a += nsvg__div255(ia * (int)dst[3]); dst[0] = (unsigned char)r; dst[1] = (unsigned char)g; dst[2] = (unsigned char)b; dst[3] = (unsigned char)a; cover++; dst += 4; } } else if (cache->type == NSVG_PAINT_LINEAR_GRADIENT) { // TODO: spread modes. // TODO: plenty of opportunities to optimize. float fx, fy, dx, gy; float* t = cache->xform; int i, cr, cg, cb, ca; unsigned int c; fx = ((float)x - tx) / scale; fy = ((float)y - ty) / scale; dx = 1.0f / scale; for (i = 0; i < count; i++) { int r,g,b,a,ia; gy = fx*t[1] + fy*t[3] + t[5]; c = cache->colors[(int)nsvg__clampf(gy*255.0f, 0, 255.0f)]; cr = (c) & 0xff; cg = (c >> 8) & 0xff; cb = (c >> 16) & 0xff; ca = (c >> 24) & 0xff; a = nsvg__div255((int)cover[0] * ca); ia = 255 - a; // Premultiply r = nsvg__div255(cr * a); g = nsvg__div255(cg * a); b = nsvg__div255(cb * a); // Blend over r += nsvg__div255(ia * (int)dst[0]); g += nsvg__div255(ia * (int)dst[1]); b += nsvg__div255(ia * (int)dst[2]); a += nsvg__div255(ia * (int)dst[3]); dst[0] = (unsigned char)r; dst[1] = (unsigned char)g; dst[2] = (unsigned char)b; dst[3] = (unsigned char)a; cover++; dst += 4; fx += dx; } } else if (cache->type == NSVG_PAINT_RADIAL_GRADIENT) { // TODO: spread modes. // TODO: plenty of opportunities to optimize. // TODO: focus (fx,fy) float fx, fy, dx, gx, gy, gd; float* t = cache->xform; int i, cr, cg, cb, ca; unsigned int c; fx = ((float)x - tx) / scale; fy = ((float)y - ty) / scale; dx = 1.0f / scale; for (i = 0; i < count; i++) { int r,g,b,a,ia; gx = fx*t[0] + fy*t[2] + t[4]; gy = fx*t[1] + fy*t[3] + t[5]; gd = sqrtf(gx*gx + gy*gy); c = cache->colors[(int)nsvg__clampf(gd*255.0f, 0, 255.0f)]; cr = (c) & 0xff; cg = (c >> 8) & 0xff; cb = (c >> 16) & 0xff; ca = (c >> 24) & 0xff; a = nsvg__div255((int)cover[0] * ca); ia = 255 - a; // Premultiply r = nsvg__div255(cr * a); g = nsvg__div255(cg * a); b = nsvg__div255(cb * a); // Blend over r += nsvg__div255(ia * (int)dst[0]); g += nsvg__div255(ia * (int)dst[1]); b += nsvg__div255(ia * (int)dst[2]); a += nsvg__div255(ia * (int)dst[3]); dst[0] = (unsigned char)r; dst[1] = (unsigned char)g; dst[2] = (unsigned char)b; dst[3] = (unsigned char)a; cover++; dst += 4; fx += dx; } } } static void nsvg__rasterizeSortedEdges(NSVGrasterizer *r, float tx, float ty, float scale, NSVGcachedPaint* cache, char fillRule) { NSVGactiveEdge *active = NULL; int y, s; int e = 0; int maxWeight = (255 / NSVG__SUBSAMPLES); // weight per vertical scanline int xmin, xmax; for (y = 0; y < r->height; y++) { memset(r->scanline, 0, r->width); xmin = r->width; xmax = 0; for (s = 0; s < NSVG__SUBSAMPLES; ++s) { // find center of pixel for this scanline float scany = (float)(y*NSVG__SUBSAMPLES + s) + 0.5f; NSVGactiveEdge **step = &active; // update all active edges; // remove all active edges that terminate before the center of this scanline while (*step) { NSVGactiveEdge *z = *step; if (z->ey <= scany) { *step = z->next; // delete from list // NSVG__assert(z->valid); nsvg__freeActive(r, z); } else { z->x += z->dx; // advance to position for current scanline step = &((*step)->next); // advance through list } } // resort the list if needed for (;;) { int changed = 0; step = &active; while (*step && (*step)->next) { if ((*step)->x > (*step)->next->x) { NSVGactiveEdge* t = *step; NSVGactiveEdge* q = t->next; t->next = q->next; q->next = t; *step = q; changed = 1; } step = &(*step)->next; } if (!changed) break; } // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline while (e < r->nedges && r->edges[e].y0 <= scany) { if (r->edges[e].y1 > scany) { NSVGactiveEdge* z = nsvg__addActive(r, &r->edges[e], scany); if (z == NULL) break; // find insertion point if (active == NULL) { active = z; } else if (z->x < active->x) { // insert at front z->next = active; active = z; } else { // find thing to insert AFTER NSVGactiveEdge* p = active; while (p->next && p->next->x < z->x) p = p->next; // at this point, p->next->x is NOT < z->x z->next = p->next; p->next = z; } } e++; } // now process all active edges in non-zero fashion if (active != NULL) nsvg__fillActiveEdges(r->scanline, r->width, active, maxWeight, &xmin, &xmax, fillRule); } // Blit if (xmin < 0) xmin = 0; if (xmax > r->width-1) xmax = r->width-1; if (xmin <= xmax) { nsvg__scanlineSolid(&r->bitmap[y * r->stride] + xmin*4, xmax-xmin+1, &r->scanline[xmin], xmin, y, tx,ty, scale, cache); } } } static void nsvg__unpremultiplyAlpha(unsigned char* image, int w, int h, int stride) { int x,y; // Unpremultiply for (y = 0; y < h; y++) { unsigned char *row = &image[y*stride]; for (x = 0; x < w; x++) { int r = row[0], g = row[1], b = row[2], a = row[3]; if (a != 0) { row[0] = (unsigned char)(r*255/a); row[1] = (unsigned char)(g*255/a); row[2] = (unsigned char)(b*255/a); } row += 4; } } // Defringe for (y = 0; y < h; y++) { unsigned char *row = &image[y*stride]; for (x = 0; x < w; x++) { int r = 0, g = 0, b = 0, a = row[3], n = 0; if (a == 0) { if (x-1 > 0 && row[-1] != 0) { r += row[-4]; g += row[-3]; b += row[-2]; n++; } if (x+1 < w && row[7] != 0) { r += row[4]; g += row[5]; b += row[6]; n++; } if (y-1 > 0 && row[-stride+3] != 0) { r += row[-stride]; g += row[-stride+1]; b += row[-stride+2]; n++; } if (y+1 < h && row[stride+3] != 0) { r += row[stride]; g += row[stride+1]; b += row[stride+2]; n++; } if (n > 0) { row[0] = (unsigned char)(r/n); row[1] = (unsigned char)(g/n); row[2] = (unsigned char)(b/n); } } row += 4; } } } static void nsvg__initPaint(NSVGcachedPaint* cache, NSVGpaint* paint, float opacity) { int i, j; NSVGgradient* grad; cache->type = paint->type; if (paint->type == NSVG_PAINT_COLOR) { cache->colors[0] = nsvg__applyOpacity(paint->color, opacity); return; } grad = paint->gradient; cache->spread = grad->spread; memcpy(cache->xform, grad->xform, sizeof(float)*6); if (grad->nstops == 0) { for (i = 0; i < 256; i++) cache->colors[i] = 0; } else if (grad->nstops == 1) { unsigned int color = nsvg__applyOpacity(grad->stops[0].color, opacity); for (i = 0; i < 256; i++) cache->colors[i] = color; } else { unsigned int ca, cb = 0; float ua, ub, du, u; int ia, ib, count; ca = nsvg__applyOpacity(grad->stops[0].color, opacity); ua = nsvg__clampf(grad->stops[0].offset, 0, 1); ub = nsvg__clampf(grad->stops[grad->nstops-1].offset, ua, 1); ia = (int)(ua * 255.0f); ib = (int)(ub * 255.0f); for (i = 0; i < ia; i++) { cache->colors[i] = ca; } for (i = 0; i < grad->nstops-1; i++) { ca = nsvg__applyOpacity(grad->stops[i].color, opacity); cb = nsvg__applyOpacity(grad->stops[i+1].color, opacity); ua = nsvg__clampf(grad->stops[i].offset, 0, 1); ub = nsvg__clampf(grad->stops[i+1].offset, 0, 1); ia = (int)(ua * 255.0f); ib = (int)(ub * 255.0f); count = ib - ia; if (count <= 0) continue; u = 0; du = 1.0f / (float)count; for (j = 0; j < count; j++) { cache->colors[ia+j] = nsvg__lerpRGBA(ca,cb,u); u += du; } } for (i = ib; i < 256; i++) cache->colors[i] = cb; } } /* static void dumpEdges(NSVGrasterizer* r, const char* name) { float xmin = 0, xmax = 0, ymin = 0, ymax = 0; NSVGedge *e = NULL; int i; if (r->nedges == 0) return; FILE* fp = fopen(name, "w"); if (fp == NULL) return; xmin = xmax = r->edges[0].x0; ymin = ymax = r->edges[0].y0; for (i = 0; i < r->nedges; i++) { e = &r->edges[i]; xmin = nsvg__minf(xmin, e->x0); xmin = nsvg__minf(xmin, e->x1); xmax = nsvg__maxf(xmax, e->x0); xmax = nsvg__maxf(xmax, e->x1); ymin = nsvg__minf(ymin, e->y0); ymin = nsvg__minf(ymin, e->y1); ymax = nsvg__maxf(ymax, e->y0); ymax = nsvg__maxf(ymax, e->y1); } fprintf(fp, "", xmin, ymin, (xmax - xmin), (ymax - ymin)); for (i = 0; i < r->nedges; i++) { e = &r->edges[i]; fprintf(fp ,"", e->x0,e->y0, e->x1,e->y1); } for (i = 0; i < r->npoints; i++) { if (i+1 < r->npoints) fprintf(fp ,"", r->points[i].x, r->points[i].y, r->points[i+1].x, r->points[i+1].y); fprintf(fp ,"", r->points[i].x, r->points[i].y, r->points[i].flags == 0 ? "#f00" : "#0f0"); } fprintf(fp, ""); fclose(fp); } */ void nsvgRasterize(NSVGrasterizer* r, NSVGimage* image, float tx, float ty, float scale, unsigned char* dst, int w, int h, int stride) { NSVGshape *shape = NULL; NSVGedge *e = NULL; NSVGcachedPaint cache; int i; r->bitmap = dst; r->width = w; r->height = h; r->stride = stride; if (w > r->cscanline) { r->cscanline = w; r->scanline = (unsigned char*)realloc(r->scanline, w); if (r->scanline == NULL) return; } for (i = 0; i < h; i++) memset(&dst[i*stride], 0, w*4); for (shape = image->shapes; shape != NULL; shape = shape->next) { if (!(shape->flags & NSVG_FLAGS_VISIBLE)) continue; if (shape->fill.type != NSVG_PAINT_NONE) { nsvg__resetPool(r); r->freelist = NULL; r->nedges = 0; nsvg__flattenShape(r, shape, scale); // Scale and translate edges for (i = 0; i < r->nedges; i++) { e = &r->edges[i]; e->x0 = tx + e->x0; e->y0 = (ty + e->y0) * NSVG__SUBSAMPLES; e->x1 = tx + e->x1; e->y1 = (ty + e->y1) * NSVG__SUBSAMPLES; } // Rasterize edges if (r->nedges != 0) qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge); // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule nsvg__initPaint(&cache, &shape->fill, shape->opacity); nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, shape->fillRule); } if (shape->stroke.type != NSVG_PAINT_NONE && (shape->strokeWidth * scale) > 0.01f) { nsvg__resetPool(r); r->freelist = NULL; r->nedges = 0; nsvg__flattenShapeStroke(r, shape, scale); // dumpEdges(r, "edge.svg"); // Scale and translate edges for (i = 0; i < r->nedges; i++) { e = &r->edges[i]; e->x0 = tx + e->x0; e->y0 = (ty + e->y0) * NSVG__SUBSAMPLES; e->x1 = tx + e->x1; e->y1 = (ty + e->y1) * NSVG__SUBSAMPLES; } // Rasterize edges if (r->nedges != 0) qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge); // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule nsvg__initPaint(&cache, &shape->stroke, shape->opacity); nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, NSVG_FILLRULE_NONZERO); } } nsvg__unpremultiplyAlpha(dst, w, h, stride); r->bitmap = NULL; r->width = 0; r->height = 0; r->stride = 0; } #endif // NANOSVGRAST_IMPLEMENTATION #endif // NANOSVGRAST_H chawan-v0.4.0/adapter/img/resize.nim000066400000000000000000000027221520232313100173370ustar00rootroot00000000000000{.push raises: [].} import std/posix import ../protocol/lcgi {.passc: "-I" & currentSourcePath().untilLast('/').} {.push header: """ #define STB_IMAGE_RESIZE_IMPLEMENTATION #include "stb_image_resize.h" """.} proc stbir_resize_uint8_srgb(input_pixels: ptr uint8; input_w, input_h, input_stride_in_bytes: cint; output_pixels: ptr uint8; output_w, output_h, output_stride_in_bytes, num_channels, alpha_channel, flags: cint): cint {.importc.} {.pop.} proc main() = var srcWidth = cint(-1) var srcHeight = cint(-1) var dstWidth = cint(-1) var dstHeight = cint(-1) for hdr in getEnvEmpty("REQUEST_HEADERS").split('\n'): let k = hdr.until(':') let v = hdr.after(':').strip() case k of "Cha-Image-Target-Dimensions": (dstWidth, dstHeight) = parseDimensionsC(v, allowZero = false) of "Cha-Image-Dimensions": (srcWidth, srcHeight) = parseDimensionsC(v, allowZero = false) let ps = newPosixStream(STDIN_FILENO) let os = newPosixStream(STDOUT_FILENO) let src = ps.readLoopOrMmap(int(srcWidth * srcHeight * 4)) let dst = os.maybeMmapForSend(int(dstWidth * dstHeight * 4 + 1)) if src == nil or dst == nil: cgiDie(ceInternalError, "failed to open i/o") dst.p[0] = uint8('\n') # for CGI enterNetworkSandbox() doAssert stbir_resize_uint8_srgb(addr src.p[0], srcWidth, srcHeight, 0, addr dst.p[1], dstWidth, dstHeight, 0, 4, 3, 0) != 0 discard os.writeLoop(dst) deallocMem(src) deallocMem(dst) main() {.pop.} # raises: [] chawan-v0.4.0/adapter/img/sixel.nim000066400000000000000000000374711520232313100171730ustar00rootroot00000000000000# Sixel codec. I'm lazy, so no decoder yet. # # "Regular" mode just encodes the image as a sixel image, with # Cha-Image-Sixel-Palette colors. If that isn't given, it's set # according to Cha-Image-Quality. # # The encoder also has a "half-dump" mode, where a binary lookup table # is appended to the file end to allow vertical cropping in ~constant # time. # # This table is an array of 32-bit big-endian integers indicating the # start index of every sixel, and finally a 32-bit big-endian integer # indicating the number of sixels in the image. # # Warning: we intentionally leak the final octree. Be careful if you # want to integrate this module into a larger program. Deallocation # would (currently) look like: # # * Free the leaves first, since they might have been inserted more # than once (iterate over "nodes" seq) # * Recurse to free the parent nodes (start from root, dealloc each # node where idx == -1) {.push raises: [].} import std/algorithm import std/posix import types/color import ../protocol/lcgi proc puts(os: PosixStream; s: string) = doAssert os.writeLoop(s).isOk const DCS = "\eP" const ST = "\e\\" proc putU32BE(s: var string; n: uint32) = s &= char((n shr 24) and 0xFF) s &= char((n shr 16) and 0xFF) s &= char((n shr 8) and 0xFF) s &= char(n and 0xFF) type Node = ptr NodeObj NodeObj = object idx: int # -1: parent, anything else: leaf u: NodeUnion NodeUnion {.union.} = object leaf: NodeLeaf children: NodeChildren NodeChildren = array[8, Node] NodeLeaf = object c: RGBColor n: uint32 r: uint32 g: uint32 b: uint32 proc getIdx(c: RGBColor; level: int): uint8 {.inline.} = let c = uint32(c) and (0x80808080u32 shr uint32(level)) return uint8((c shr (21 - level)) or (c shr (14 - level)) or (c shr (7 - level))) type TrimMap = array[7, seq[Node]] proc insert(root: var NodeChildren; c: RGBColor; trimMap: var TrimMap): uint = # max level is 7, because we only have ~6.5 bits (0..100, inclusive) # (it *is* 0-indexed, but one extra level is needed for the final leaves) var level = 0 var parent = addr root var split = false while true: assert level < 8 let idx = c.getIdx(level) let old = parent[idx] if old == nil: let node = cast[Node](alloc(sizeof(NodeObj))) node.idx = 0 node.u.leaf = NodeLeaf( c: c, n: 1, r: uint32(c.r), g: uint32(c.g), b: uint32(c.b) ) parent[idx] = node return 1 elif old.idx != -1: # split just once with identical colors if level == 7 or split and old.u.leaf.c == c: inc old.u.leaf.n old.u.leaf.r += uint32(c.r) old.u.leaf.g += uint32(c.g) old.u.leaf.b += uint32(c.b) break let oc = old.u.leaf.c let child = cast[Node](alloc(sizeof(NodeObj))) child.idx = 0 child.u.leaf = old.u.leaf old.idx = -1 zeroMem(addr old.u.children, sizeof(old.u.children)) old.u.children[oc.getIdx(level + 1)] = child trimMap[level].add(old) split = true inc level parent = addr old.u.children 0 proc trim(trimMap: var TrimMap; K: var uint) = var node: Node = nil for i in countdown(trimMap.high, 0): if trimMap[i].len > 0: node = trimMap[i].pop() break var r = 0u32 var g = 0u32 var b = 0u32 var n = 0u32 var k = K + 1 for child in node.u.children: if child != nil: r += child.u.leaf.r g += child.u.leaf.g b += child.u.leaf.b n += child.u.leaf.n dealloc(child) dec k node.idx = 0 node.u.leaf = NodeLeaf( c: rgb(uint8(r div n), uint8(g div n), uint8(b div n)), r: r, g: g, b: b, n: n ) K = k proc quantize(img: openArray[RGBAColorBE]; outk: var uint; outTransparent: var bool): NodeChildren = var root = NodeChildren.default if outk <= 2: # monochrome; not much we can do with an octree... root[0] = cast[Node](alloc0(sizeof(NodeObj))) root[0].u.leaf.c = rgb(0, 0, 0) root[7] = cast[Node](alloc0(sizeof(NodeObj))) root[7].u.leaf.c = rgb(100, 100, 100) outk = 2 # the point is to skip the first scan, so fall back to the option # that always works outTransparent = true return root # number of leaves let palette = outk var K = 0u # map of non-leaves for each level. # (note: somewhat confusingly, this actually starts at level 1.) var trimMap: array[7, seq[Node]] var transparent = false for c0 in img: let c0 = c0.argb().fastmul(100) transparent = transparent or c0.a != 100 let c = RGBColor(c0) K += root.insert(c, trimMap) while K > palette: trimMap.trim(K) outk = K outTransparent = transparent return root proc flatten(children: NodeChildren; cols: var seq[Node]) = for node in children: if node != nil: if node.idx != -1: cols.add(node) else: node.u.children.flatten(cols) proc flatten(root: NodeChildren; outs: var string; palette: uint): seq[Node] = var cols = newSeqOfCap[Node](palette) root.flatten(cols) # try to set the most common colors as the smallest numbers (so we write less) cols.sort(proc(a, b: Node): int = cmp(a.u.leaf.n, b.u.leaf.n), order = Descending) for n, it in cols: let c = it.u.leaf.c # 2 is RGB outs &= '#' & $n & ";2;" & $c.r & ';' & $c.g & ';' & $c.b it.idx = n return cols type DitherDiff = tuple[a, r, g, b: int32] Dither = object d1: seq[DitherDiff] d2: seq[DitherDiff] proc getColor(nodes: seq[Node]; c: ARGBColor; diff: var DitherDiff): Node = var child: Node = nil var minDist = uint32.high var mdiff = DitherDiff.default for node in nodes: let ic = node.u.leaf.c let ad = int32(c.a) - 100 let rd = int32(c.r) - int32(ic.r) let gd = int32(c.g) - int32(ic.g) let bd = int32(c.b) - int32(ic.b) let d = uint32(abs(rd)) + uint32(abs(gd)) + uint32(abs(bd)) if d < minDist: minDist = d child = node mdiff = (ad, rd, gd, bd) if ic == c.rgb(): break diff = mdiff return child proc getColor(root: var NodeChildren; c: ARGBColor; nodes: seq[Node]; diff: var DitherDiff): int = if nodes.len < 64: # Octree-based nearest neighbor search creates really ugly artifacts # with a low amount of colors, which is exactly the case where # linear search is still acceptable. # # 64 is the first power of 2 that gives OK results on my test images # with the octree. # # (In practice, I assume no sane terminal would pick a palette (> 2) # that isn't a multiple of 4, so really only 16 is relevant here. # Even that is quite rare, unless you misconfigure XTerm - or # have a hardware terminal, but those didn't have private color # registers in the first place. I do like the aesthetics, though; # would be a shame if it didn't work :P) return nodes.getColor(c, diff).idx # Find a matching color in the octree. # Not as accurate as a linear search, but good enough (and much # faster) for palettes that reach this path. var level = 0 var children = addr root while true: let idx = RGBColor(c).getIdx(level) let child = children[idx] if child == nil: let child = nodes.getColor(c, diff) # No child found in this corner of the octree. This is caused by # dithering. # Allocate at least 4 ancestors, so that other colors with the # same initial bits don't end up using something wildly different # than the dither intended. while level < 4: let idx = RGBColor(c).getIdx(level) let node = cast[Node](alloc0(sizeof(NodeObj))) node.idx = -1 children[idx] = node children = addr node.u.children inc level let idx = RGBColor(c).getIdx(level) children[idx] = child return child.idx if child.idx != -1: let ic = child.u.leaf.c let a = int32(c.a) - 100 let r = int32(c.r) - int32(ic.r) let g = int32(c.g) - int32(ic.g) let b = int32(c.b) - int32(ic.b) diff = (a, r, g, b) return child.idx inc level children = addr child.u.children -1 # unreachable proc correctDither(c: ARGBColor; x: int; dither: Dither): ARGBColor = let (ad, rd, gd, bd) = dither.d1[x + 1] let pa = (uint32(c) shr 20) and 0xFF0 let pr = (uint32(c) shr 12) and 0xFF0 let pg = (uint32(c) shr 4) and 0xFF0 let pb = (uint32(c) shl 4) and 0xFF0 {.push overflowChecks: off.} let a = uint8(uint32(clamp(int32(pa) + ad, 0, 1600)) shr 4) let r = uint8(uint32(clamp(int32(pr) + rd, 0, 1600)) shr 4) let g = uint8(uint32(clamp(int32(pg) + gd, 0, 1600)) shr 4) let b = uint8(uint32(clamp(int32(pb) + bd, 0, 1600)) shr 4) {.pop.} return rgba(r, g, b, a) proc fs(dither: var Dither; x: int; d: DitherDiff) = let x = x + 1 # skip first bounds check template at(p, mul: untyped) = var (ad, rd, gd, bd) = p p = (ad + d.a * mul, rd + d.r * mul, gd + d.g * mul, bd + d.b * mul) {.push overflowChecks: off.} at(dither.d1[x + 1], 7) at(dither.d2[x - 1], 3) at(dither.d2[x], 5) at(dither.d2[x + 1], 1) {.pop.} type SixelBand = object head: ptr SixelChunk tail: ptr SixelChunk SixelChunk = object x: int c: int nrow: uint # data is binary 0..63; compressSixel creates the final ASCII form data: seq[uint8] # linked list for chaining together bands # (yes, this *is* faster than a seq.) next: ptr SixelChunk proc compressSixel(outs: var string; band: SixelBand) = var x = 0 var chunk = band.head while chunk != nil: outs &= '#' & $chunk.c var n = chunk.x - x var c = '?' for u in chunk.data: let cc = char(u + 0x3F) if c != cc: if n > 3: outs &= '!' & $n & c else: for i in 0 ..< n: outs &= c c = cc n = 0 inc n if n > 3: outs &= '!' & $n & c else: for i in 0 ..< n: outs &= c x = chunk.x + chunk.data.len let next = chunk.next chunk.next = nil chunk = next proc createBands(bands: var seq[SixelBand]; activeChunks: seq[ptr SixelChunk]) = for chunk in activeChunks: var found = false for band in bands.mitems: if band.head.x > chunk.x + chunk.data.len: chunk.next = band.head band.head = chunk found = true break elif band.tail.x + band.tail.data.len <= chunk.x: band.tail.next = chunk band.tail = chunk found = true break if not found: bands.add(SixelBand(head: chunk, tail: chunk)) proc encode(os: PosixStream; img: openArray[RGBAColorBE]; width, height, offx, offy, cropw, palette: int; halfdump: bool) = var palette = uint(palette) var transparent = false var root = img.quantize(palette, transparent) # prelude var outs = "Cha-Image-Sixel-Transparent: " & $int(transparent) & "\n" outs &= "Cha-Image-Sixel-Prelude-Len: " const PreludePad = "666 666 666" let preludeLenPos = outs.len outs &= PreludePad & "\n\n" let dcsPos = outs.len outs &= DCS if transparent: outs &= "0;1" # P2=1 -> image has transparency outs &= 'q' # set raster attributes outs &= "\"1;1;" & $width & ';' & $height let nodes = root.flatten(outs, palette) # prepend prelude size var ps = $(outs.len - dcsPos) while ps.len < PreludePad.len: ps &= ' ' for i, c in ps: outs[preludeLenPos + i] = c let L = width * height let realw = cropw - offx var n = offy * width var ymap = "" var totalLen = 0u32 # add +2 so we don't have to bounds check var dither = Dither( d1: newSeq[DitherDiff](realw + 2), d2: newSeq[DitherDiff](realw + 2) ) var chunkMap = newSeq[SixelChunk](palette) var activeChunks: seq[ptr SixelChunk] = @[] var nrow = 1u # buffer to 64k, just because. const MaxBuffer = 65536 while true: if halfdump: ymap.putU32BE(totalLen) for i in 0 ..< 6: if n >= L: break let mask = 1u8 shl i var chunk: ptr SixelChunk = nil for j in 0 ..< realw: let m = n + offx + j let c0 = img[m].argb().fastmul(100).correctDither(j, dither) if c0.a < 50: # transparent let diff = (int32(c0.a), 0i32, 0i32, 0i32) dither.fs(j, diff) chunk = nil continue var diff: DitherDiff let c = root.getColor(c0, nodes, diff) dither.fs(j, diff) if chunk == nil or chunk.c != c: chunk = addr chunkMap[c] if chunk.nrow < nrow: chunk.c = c chunk.nrow = nrow chunk.x = j chunk.data.setLen(0) activeChunks.add(chunk) elif chunk.x > j: let diff = chunk.x - j chunk.x = j let olen = chunk.data.len chunk.data.setLen(olen + diff) moveMem(addr chunk.data[diff], addr chunk.data[0], olen) zeroMem(addr chunk.data[0], diff) elif chunk.data.len < j - chunk.x: let olen = chunk.data.len chunk.data.setLen(j - chunk.x) when NimMajor < 2: zeroMem(addr chunk.data[olen], j - chunk.x - olen) else: discard olen let k = j - chunk.x if k < chunk.data.len: chunk.data[k] = chunk.data[k] or mask else: chunk.data.add(mask) n += width var tmp = move(dither.d1) dither.d1 = move(dither.d2) dither.d2 = move(tmp) zeroMem(addr dither.d2[0], dither.d2.len * sizeof(dither.d2[0])) var bands: seq[SixelBand] = @[] bands.createBands(activeChunks) let olen = outs.len for i in 0 ..< bands.len: if i > 0: outs &= '$' outs.compressSixel(bands[i]) if n >= L: outs &= ST totalLen += uint32(outs.len - olen) break else: outs &= '-' totalLen += uint32(outs.len - olen) if outs.len >= MaxBuffer: os.puts(outs) outs.setLen(0) inc nrow activeChunks.setLen(0) if halfdump: ymap.putU32BE(totalLen) ymap.putU32BE(uint32(ymap.len)) outs &= ymap os.puts(outs) # Note: we leave octree deallocation to the OS. See the header for details. proc main() = let os = newPosixStream(STDOUT_FILENO) if getEnvEmpty("MAPPED_URI_PATH") == "encode": var width = 0 var height = 0 var offx = 0 var offy = 0 var halfdump = false var palette = -1 var cropw = -1 var quality = -1 for hdr in getEnvEmpty("REQUEST_HEADERS").split('\n'): let s = hdr.after(':').strip() case hdr.until(':') of "Cha-Image-Dimensions": (width, height) = parseDimensions(s, allowZero = false) of "Cha-Image-Offset": (offx, offy) = parseDimensions(s, allowZero = true) of "Cha-Image-Crop-Width": let q = parseUInt32(s, allowSign = false) if q.isErr: cgiDie(ceInternalError, "wrong crop width") cropw = int(q.get) of "Cha-Image-Sixel-Halfdump": halfdump = true of "Cha-Image-Sixel-Palette": let q = parseUInt16(s, allowSign = false) if q.isErr: cgiDie(ceInternalError, "wrong palette") palette = int(q.get) of "Cha-Image-Quality": let q = parseUInt16(s, allowSign = false) if q.isErr: cgiDie(ceInternalError, "wrong quality") quality = int(q.get) if cropw == -1: cropw = width if palette == -1: if quality < 30: palette = 16 elif quality < 70: palette = 256 else: palette = 1024 if width == 0 or height == 0: quit(0) # done... let n = width * height let L = n * 4 let ps = newPosixStream(STDIN_FILENO) let src = ps.readLoopOrMmap(L) if src == nil: cgiDie(ceInternalError, "failed to read input") enterNetworkSandbox() # don't swallow stat let p = cast[ptr UncheckedArray[RGBAColorBE]](src.p) os.encode(p.toOpenArray(0, n - 1), width, height, offx, offy, cropw, palette, halfdump) deallocMem(src) else: cgiDie(ceInternalError, "not implemented") main() {.pop.} # raises: [] chawan-v0.4.0/adapter/img/stb_image.h000066400000000000000000010560671520232313100174500ustar00rootroot00000000000000/* stb_image - v2.30 - public domain image loader - http://nothings.org/stb no warranty implied; use at your own risk Do this: #define STB_IMAGE_IMPLEMENTATION before you include this file in *one* C or C++ file to create the implementation. // i.e. it should look like this: #include ... #include ... #include ... #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" You can #define STBI_ASSERT(x) before the #include to avoid using assert.h. And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free QUICK NOTES: Primarily of interest to game developers and other people who can avoid problematic images and only need the trivial interface JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib) PNG 1/2/4/8/16-bit-per-channel TGA (not sure what subset, if a subset) BMP non-1bpp, non-RLE PSD (composited view only, no extra channels, 8/16 bit-per-channel) GIF (*comp always reports as 4-channel) HDR (radiance rgbE format) PIC (Softimage PIC) PNM (PPM and PGM binary only) Animated GIF still needs a proper API, but here's one way to do it: http://gist.github.com/urraka/685d9a6340b26b830d49 - decode from memory or through FILE (define STBI_NO_STDIO to remove code) - decode from arbitrary I/O callbacks - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON) Full documentation under "DOCUMENTATION" below. LICENSE See end of file for license information. RECENT REVISION HISTORY: 2.30 (2024-05-31) avoid erroneous gcc warning 2.29 (2023-05-xx) optimizations 2.28 (2023-01-29) many error fixes, security errors, just tons of stuff 2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes 2.26 (2020-07-13) many minor fixes 2.25 (2020-02-02) fix warnings 2.24 (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically 2.23 (2019-08-11) fix clang static analysis warning 2.22 (2019-03-04) gif fixes, fix warnings 2.21 (2019-02-25) fix typo in comment 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs 2.19 (2018-02-11) fix warning 2.18 (2018-01-30) fix warnings 2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings 2.16 (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes 2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs 2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64 RGB-format JPEG; remove white matting in PSD; allocate large structures on the stack; correct channel count for PNG & BMP 2.10 (2016-01-22) avoid warning introduced in 2.09 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED See end of file for full revision history. ============================ Contributors ========================= Image formats Extensions, features Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info) Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info) Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG) Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks) Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG) Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip) Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) github:urraka (animated gif) Junggon Kim (PNM comments) Christopher Forseth (animated gif) Daniel Gibson (16-bit TGA) socks-the-fox (16-bit PNG) Jeremy Sawicki (handle all ImageNet JPGs) Optimizations & bugfixes Mikhail Morozov (1-bit BMP) Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query) Arseny Kapoulkine Simon Breuss (16-bit PNM) John-Mark Allen Carmelo J Fdez-Aguera Bug & warning fixes Marc LeBlanc David Woo Guillaume George Martins Mozeiko Christpher Lloyd Jerry Jansson Joseph Thomson Blazej Dariusz Roszkowski Phil Jordan Henner Zeller Dave Moore Roy Eltham Hayaki Saito Nathan Reed Won Chun Thomas Bernard Luke Graham Johan Duparc Nick Verigakis the Horde3D community Thomas Ruf Ronny Chevalier github:rlyeh Janez Zemva John Bartholomew Michal Cichon github:romigrou Jonathan Blow Ken Hamada Tero Hanninen github:svdijk Eugene Golushkov Laurent Gomila Cort Stratton github:snagar Aruelien Pocheville Sergio Gonzalez Thibault Reuille github:Zelex Cass Everitt Ryamond Barbiero github:grim210 Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus Josh Tobin Nia Bickford Matthew Gregan github:poppolopoppo Julian Raschke Gregory Mullen Christian Floisand github:darealshinji Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007 Brad Weinberger Matvey Cherevko github:mosra Luca Sas Alexander Veselov Zack Middleton [reserved] Ryan C. Gordon [reserved] [reserved] DO NOT ADD YOUR NAME HERE Jacko Dirks To add your name to the credits, pick a random blank space in the middle and fill it. 80% of merge conflicts on stb PRs are due to people adding their name at the end of the credits. */ #ifndef STBI_INCLUDE_STB_IMAGE_H #define STBI_INCLUDE_STB_IMAGE_H // DOCUMENTATION // // Limitations: // - no 12-bit-per-channel JPEG // - no JPEGs with arithmetic coding // - GIF always returns *comp=4 // // Basic usage (see HDR discussion below for HDR usage): // int x,y,n; // unsigned char *data = stbi_load(filename, &x, &y, &n, 0); // // ... process data if not NULL ... // // ... x = width, y = height, n = # 8-bit components per pixel ... // // ... replace '0' with '1'..'4' to force that many components per pixel // // ... but 'n' will always be the number that it would have been if you said 0 // stbi_image_free(data); // // Standard parameters: // int *x -- outputs image width in pixels // int *y -- outputs image height in pixels // int *channels_in_file -- outputs # of image components in image file // int desired_channels -- if non-zero, # of image components requested in result // // The return value from an image loader is an 'unsigned char *' which points // to the pixel data, or NULL on an allocation failure or if the image is // corrupt or invalid. The pixel data consists of *y scanlines of *x pixels, // with each pixel consisting of N interleaved 8-bit components; the first // pixel pointed to is top-left-most in the image. There is no padding between // image scanlines or between pixels, regardless of format. The number of // components N is 'desired_channels' if desired_channels is non-zero, or // *channels_in_file otherwise. If desired_channels is non-zero, // *channels_in_file has the number of components that _would_ have been // output otherwise. E.g. if you set desired_channels to 4, you will always // get RGBA output, but you can check *channels_in_file to see if it's trivially // opaque because e.g. there were only 3 channels in the source image. // // An output image with N components has the following components interleaved // in this order in each pixel: // // N=#comp components // 1 grey // 2 grey, alpha // 3 red, green, blue // 4 red, green, blue, alpha // // If image loading fails for any reason, the return value will be NULL, // and *x, *y, *channels_in_file will be unchanged. The function // stbi_failure_reason() can be queried for an extremely brief, end-user // unfriendly explanation of why the load failed. Define STBI_NO_FAILURE_STRINGS // to avoid compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly // more user-friendly ones. // // Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. // // To query the width, height and component count of an image without having to // decode the full file, you can use the stbi_info family of functions: // // int x,y,n,ok; // ok = stbi_info(filename, &x, &y, &n); // // returns ok=1 and sets x, y, n if image is a supported format, // // 0 otherwise. // // Note that stb_image pervasively uses ints in its public API for sizes, // including sizes of memory buffers. This is now part of the API and thus // hard to change without causing breakage. As a result, the various image // loaders all have certain limits on image size; these differ somewhat // by format but generally boil down to either just under 2GB or just under // 1GB. When the decoded image would be larger than this, stb_image decoding // will fail. // // Additionally, stb_image will reject image files that have any of their // dimensions set to a larger value than the configurable STBI_MAX_DIMENSIONS, // which defaults to 2**24 = 16777216 pixels. Due to the above memory limit, // the only way to have an image with such dimensions load correctly // is for it to have a rather extreme aspect ratio. Either way, the // assumption here is that such larger images are likely to be malformed // or malicious. If you do need to load an image with individual dimensions // larger than that, and it still fits in the overall size limit, you can // #define STBI_MAX_DIMENSIONS on your own to be something larger. // // =========================================================================== // // UNICODE: // // If compiling for Windows and you wish to use Unicode filenames, compile // with // #define STBI_WINDOWS_UTF8 // and pass utf8-encoded filenames. Call stbi_convert_wchar_to_utf8 to convert // Windows wchar_t filenames to utf8. // // =========================================================================== // // Philosophy // // stb libraries are designed with the following priorities: // // 1. easy to use // 2. easy to maintain // 3. good performance // // Sometimes I let "good performance" creep up in priority over "easy to maintain", // and for best performance I may provide less-easy-to-use APIs that give higher // performance, in addition to the easy-to-use ones. Nevertheless, it's important // to keep in mind that from the standpoint of you, a client of this library, // all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all. // // Some secondary priorities arise directly from the first two, some of which // provide more explicit reasons why performance can't be emphasized. // // - Portable ("ease of use") // - Small source code footprint ("easy to maintain") // - No dependencies ("ease of use") // // =========================================================================== // // I/O callbacks // // I/O callbacks allow you to read from arbitrary sources, like packaged // files or some other source. Data read from callbacks are processed // through a small internal buffer (currently 128 bytes) to try to reduce // overhead. // // The three functions you must define are "read" (reads some bytes of data), // "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). // // =========================================================================== // // SIMD support // // The JPEG decoder will try to automatically use SIMD kernels on x86 when // supported by the compiler. For ARM Neon support, you must explicitly // request it. // // (The old do-it-yourself SIMD API is no longer supported in the current // code.) // // On x86, SSE2 will automatically be used when available based on a run-time // test; if not, the generic C versions are used as a fall-back. On ARM targets, // the typical path is to have separate builds for NEON and non-NEON devices // (at least this is true for iOS and Android). Therefore, the NEON support is // toggled by a build flag: define STBI_NEON to get NEON loops. // // If for some reason you do not want to use any of SIMD code, or if // you have issues compiling it, you can disable it entirely by // defining STBI_NO_SIMD. // // =========================================================================== // // HDR image support (disable by defining STBI_NO_HDR) // // stb_image supports loading HDR images in general, and currently the Radiance // .HDR file format specifically. You can still load any file through the existing // interface; if you attempt to load an HDR file, it will be automatically remapped // to LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; // both of these constants can be reconfigured through this interface: // // stbi_hdr_to_ldr_gamma(2.2f); // stbi_hdr_to_ldr_scale(1.0f); // // (note, do not use _inverse_ constants; stbi_image will invert them // appropriately). // // Additionally, there is a new, parallel interface for loading files as // (linear) floats to preserve the full dynamic range: // // float *data = stbi_loadf(filename, &x, &y, &n, 0); // // If you load LDR images through this interface, those images will // be promoted to floating point values, run through the inverse of // constants corresponding to the above: // // stbi_ldr_to_hdr_scale(1.0f); // stbi_ldr_to_hdr_gamma(2.2f); // // Finally, given a filename (or an open file or memory block--see header // file for details) containing image data, you can query for the "most // appropriate" interface to use (that is, whether the image is HDR or // not), using: // // stbi_is_hdr(char *filename); // // =========================================================================== // // iPhone PNG support: // // We optionally support converting iPhone-formatted PNGs (which store // premultiplied BGRA) back to RGB, even though they're internally encoded // differently. To enable this conversion, call // stbi_convert_iphone_png_to_rgb(1). // // Call stbi_set_unpremultiply_on_load(1) as well to force a divide per // pixel to remove any premultiplied alpha *only* if the image file explicitly // says there's premultiplied data (currently only happens in iPhone images, // and only if iPhone convert-to-rgb processing is on). // // =========================================================================== // // ADDITIONAL CONFIGURATION // // - You can suppress implementation of any of the decoders to reduce // your code footprint by #defining one or more of the following // symbols before creating the implementation. // // STBI_NO_JPEG // STBI_NO_PNG // STBI_NO_BMP // STBI_NO_PSD // STBI_NO_TGA // STBI_NO_GIF // STBI_NO_HDR // STBI_NO_PIC // STBI_NO_PNM (.ppm and .pgm) // // - You can request *only* certain decoders and suppress all other ones // (this will be more forward-compatible, as addition of new decoders // doesn't require you to disable them explicitly): // // STBI_ONLY_JPEG // STBI_ONLY_PNG // STBI_ONLY_BMP // STBI_ONLY_PSD // STBI_ONLY_TGA // STBI_ONLY_GIF // STBI_ONLY_HDR // STBI_ONLY_PIC // STBI_ONLY_PNM (.ppm and .pgm) // // - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still // want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB // // - If you define STBI_MAX_DIMENSIONS, stb_image will reject images greater // than that size (in either width or height) without further processing. // This is to let programs in the wild set an upper bound to prevent // denial-of-service attacks on untrusted data, as one could generate a // valid image of gigantic dimensions and force stb_image to allocate a // huge block of memory and spend disproportionate time decoding it. By // default this is set to (1 << 24), which is 16777216, but that's still // very big. #ifndef STBI_NO_STDIO #include #endif // STBI_NO_STDIO #define STBI_VERSION 1 #if defined(__has_attribute) # if __has_attribute(fallthrough) # define STBI_FALLTHROUGH __attribute__((fallthrough)); # endif #endif #if !defined(STBI_FALLTHROUGH) # define STBI_FALLTHROUGH #endif enum { STBI_default = 0, // only used for desired_channels STBI_grey = 1, STBI_grey_alpha = 2, STBI_rgb = 3, STBI_rgb_alpha = 4 }; #include typedef unsigned char stbi_uc; typedef unsigned short stbi_us; #ifdef __cplusplus extern "C" { #endif #ifndef STBIDEF #ifdef STB_IMAGE_STATIC #define STBIDEF static #else #define STBIDEF extern #endif #endif ////////////////////////////////////////////////////////////////////////////// // // PRIMARY API - works on images of any type // // // load image by filename, open file, or memory buffer // typedef struct { int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative int (*eof) (void *user); // returns nonzero if we are at end of file/data } stbi_io_callbacks; //////////////////////////////////// // // 8-bits-per-channel interface // STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels); STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels); #ifndef STBI_NO_STDIO STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); // for stbi_load_from_file, file pointer is left pointing immediately after image #endif #ifndef STBI_NO_GIF STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp); #endif #ifdef STBI_WINDOWS_UTF8 STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input); #endif //////////////////////////////////// // // 16-bits-per-channel interface // STBIDEF stbi_us *stbi_load_16_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); #ifndef STBI_NO_STDIO STBIDEF stbi_us *stbi_load_16 (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); #endif //////////////////////////////////// // // float-per-channel interface // #ifndef STBI_NO_LINEAR STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); #ifndef STBI_NO_STDIO STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); #endif #endif #ifndef STBI_NO_HDR STBIDEF void stbi_hdr_to_ldr_gamma(float gamma); STBIDEF void stbi_hdr_to_ldr_scale(float scale); #endif // STBI_NO_HDR #ifndef STBI_NO_LINEAR STBIDEF void stbi_ldr_to_hdr_gamma(float gamma); STBIDEF void stbi_ldr_to_hdr_scale(float scale); #endif // STBI_NO_LINEAR // stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); #ifndef STBI_NO_STDIO STBIDEF int stbi_is_hdr (char const *filename); STBIDEF int stbi_is_hdr_from_file(FILE *f); #endif // STBI_NO_STDIO // get a VERY brief reason for failure // on most compilers (and ALL modern mainstream compilers) this is threadsafe STBIDEF const char *stbi_failure_reason (void); // free the loaded image -- this is just free() STBIDEF void stbi_image_free (void *retval_from_stbi_load); // get image dimensions & components without fully decoding STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len); STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user); #ifndef STBI_NO_STDIO STBIDEF int stbi_info (char const *filename, int *x, int *y, int *comp); STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); STBIDEF int stbi_is_16_bit (char const *filename); STBIDEF int stbi_is_16_bit_from_file(FILE *f); #endif // for image formats that explicitly notate that they have premultiplied alpha, // we just return the colors as stored in the file. set this flag to force // unpremultiplication. results are undefined if the unpremultiply overflow. STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); // indicate whether we should process iphone images back to canonical format, // or just pass them through "as-is" STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); // flip the image vertically, so the first pixel in the output array is the bottom left STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); // as above, but only applies to images loaded on the thread that calls the function // this function is only available if your compiler supports thread-local variables; // calling it will fail to link if your compiler doesn't STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply); STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert); STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip); // ZLIB client - used by PNG, available for other purposes STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header); STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); #ifdef __cplusplus } #endif // // //// end header file ///////////////////////////////////////////////////// #endif // STBI_INCLUDE_STB_IMAGE_H #ifdef STB_IMAGE_IMPLEMENTATION #if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \ || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \ || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \ || defined(STBI_ONLY_ZLIB) #ifndef STBI_ONLY_JPEG #define STBI_NO_JPEG #endif #ifndef STBI_ONLY_PNG #define STBI_NO_PNG #endif #ifndef STBI_ONLY_BMP #define STBI_NO_BMP #endif #ifndef STBI_ONLY_PSD #define STBI_NO_PSD #endif #ifndef STBI_ONLY_TGA #define STBI_NO_TGA #endif #ifndef STBI_ONLY_GIF #define STBI_NO_GIF #endif #ifndef STBI_ONLY_HDR #define STBI_NO_HDR #endif #ifndef STBI_ONLY_PIC #define STBI_NO_PIC #endif #ifndef STBI_ONLY_PNM #define STBI_NO_PNM #endif #endif #if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB) #define STBI_NO_ZLIB #endif #include #include // ptrdiff_t on osx #include #include #include #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) #include // ldexp, pow #endif #ifndef STBI_NO_STDIO #include #endif #ifndef STBI_ASSERT #include #define STBI_ASSERT(x) assert(x) #endif #ifdef __cplusplus #define STBI_EXTERN extern "C" #else #define STBI_EXTERN extern #endif #ifndef _MSC_VER #ifdef __cplusplus #define stbi_inline inline #else #define stbi_inline #endif #else #define stbi_inline __forceinline #endif #ifndef STBI_NO_THREAD_LOCALS #if defined(__cplusplus) && __cplusplus >= 201103L #define STBI_THREAD_LOCAL thread_local #elif defined(__GNUC__) && __GNUC__ < 5 #define STBI_THREAD_LOCAL __thread #elif defined(_MSC_VER) #define STBI_THREAD_LOCAL __declspec(thread) #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__) #define STBI_THREAD_LOCAL _Thread_local #endif #ifndef STBI_THREAD_LOCAL #if defined(__GNUC__) #define STBI_THREAD_LOCAL __thread #endif #endif #endif #if defined(_MSC_VER) || defined(__SYMBIAN32__) typedef unsigned short stbi__uint16; typedef signed short stbi__int16; typedef unsigned int stbi__uint32; typedef signed int stbi__int32; #else #include typedef uint16_t stbi__uint16; typedef int16_t stbi__int16; typedef uint32_t stbi__uint32; typedef int32_t stbi__int32; #endif // should produce compiler error if size is wrong typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; #ifdef _MSC_VER #define STBI_NOTUSED(v) (void)(v) #else #define STBI_NOTUSED(v) (void)sizeof(v) #endif #ifdef _MSC_VER #define STBI_HAS_LROTL #endif #ifdef STBI_HAS_LROTL #define stbi_lrot(x,y) _lrotl(x,y) #else #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (-(y) & 31))) #endif #if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED)) // ok #elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED) // ok #else #error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)." #endif #ifndef STBI_MALLOC #define STBI_MALLOC(sz) malloc(sz) #define STBI_REALLOC(p,newsz) realloc(p,newsz) #define STBI_FREE(p) free(p) #endif #ifndef STBI_REALLOC_SIZED #define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz) #endif // x86/x64 detection #if defined(__x86_64__) || defined(_M_X64) #define STBI__X64_TARGET #elif defined(__i386) || defined(_M_IX86) #define STBI__X86_TARGET #endif #if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) // gcc doesn't support sse2 intrinsics unless you compile with -msse2, // which in turn means it gets to use SSE2 everywhere. This is unfortunate, // but previous attempts to provide the SSE2 functions with runtime // detection caused numerous issues. The way architecture extensions are // exposed in GCC/Clang is, sadly, not really suited for one-file libs. // New behavior: if compiled with -msse2, we use SSE2 without any // detection; if not, we don't use it at all. #define STBI_NO_SIMD #endif #if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD) // Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET // // 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the // Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant. // As a result, enabling SSE2 on 32-bit MinGW is dangerous when not // simultaneously enabling "-mstackrealign". // // See https://github.com/nothings/stb/issues/81 for more information. // // So default to no SSE2 on 32-bit MinGW. If you've read this far and added // -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2. #define STBI_NO_SIMD #endif #if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) #define STBI_SSE2 #include #ifdef _MSC_VER #if _MSC_VER >= 1400 // not VC6 #include // __cpuid static int stbi__cpuid3(void) { int info[4]; __cpuid(info,1); return info[3]; } #else static int stbi__cpuid3(void) { int res; __asm { mov eax,1 cpuid mov res,edx } return res; } #endif #define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name #if !defined(STBI_NO_JPEG) && defined(STBI_SSE2) static int stbi__sse2_available(void) { int info3 = stbi__cpuid3(); return ((info3 >> 26) & 1) != 0; } #endif #else // assume GCC-style if not VC++ #define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) #if !defined(STBI_NO_JPEG) && defined(STBI_SSE2) static int stbi__sse2_available(void) { // If we're even attempting to compile this on GCC/Clang, that means // -msse2 is on, which means the compiler is allowed to use SSE2 // instructions at will, and so are we. return 1; } #endif #endif #endif // ARM NEON #if defined(STBI_NO_SIMD) && defined(STBI_NEON) #undef STBI_NEON #endif #ifdef STBI_NEON #include #ifdef _MSC_VER #define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name #else #define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) #endif #endif #ifndef STBI_SIMD_ALIGN #define STBI_SIMD_ALIGN(type, name) type name #endif #ifndef STBI_MAX_DIMENSIONS #define STBI_MAX_DIMENSIONS (1 << 24) #endif /////////////////////////////////////////////// // // stbi__context struct and start_xxx functions // stbi__context structure is our basic context used by all images, so it // contains all the IO context, plus some basic image information typedef struct { stbi__uint32 img_x, img_y; int img_n, img_out_n; stbi_io_callbacks io; void *io_user_data; int read_from_callbacks; int buflen; stbi_uc buffer_start[128]; int callback_already_read; stbi_uc *img_buffer, *img_buffer_end; stbi_uc *img_buffer_original, *img_buffer_original_end; } stbi__context; static void stbi__refill_buffer(stbi__context *s); // initialize a memory-decode context static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len) { s->io.read = NULL; s->io.skip = NULL; s->io.eof = NULL; s->read_from_callbacks = 0; s->callback_already_read = 0; s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer; s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len; } // initialize a callback-based context static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *user) { s->io = *c; s->io_user_data = user; s->buflen = sizeof(s->buffer_start); s->read_from_callbacks = 1; s->callback_already_read = 0; s->img_buffer = s->img_buffer_original = s->buffer_start; stbi__refill_buffer(s); s->img_buffer_original_end = s->img_buffer_end; } #ifndef STBI_NO_STDIO static int stbi__stdio_read(void *user, char *data, int size) { return (int) fread(data,1,size,(FILE*) user); } static void stbi__stdio_skip(void *user, int n) { int ch; fseek((FILE*) user, n, SEEK_CUR); ch = fgetc((FILE*) user); /* have to read a byte to reset feof()'s flag */ if (ch != EOF) { ungetc(ch, (FILE *) user); /* push byte back onto stream if valid. */ } } static int stbi__stdio_eof(void *user) { return feof((FILE*) user) || ferror((FILE *) user); } static stbi_io_callbacks stbi__stdio_callbacks = { stbi__stdio_read, stbi__stdio_skip, stbi__stdio_eof, }; static void stbi__start_file(stbi__context *s, FILE *f) { stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f); } //static void stop_file(stbi__context *s) { } #endif // !STBI_NO_STDIO static void stbi__rewind(stbi__context *s) { // conceptually rewind SHOULD rewind to the beginning of the stream, // but we just rewind to the beginning of the initial buffer, because // we only use it after doing 'test', which only ever looks at at most 92 bytes s->img_buffer = s->img_buffer_original; s->img_buffer_end = s->img_buffer_original_end; } enum { STBI_ORDER_RGB, STBI_ORDER_BGR }; typedef struct { int bits_per_channel; int num_channels; int channel_order; } stbi__result_info; #ifndef STBI_NO_JPEG static int stbi__jpeg_test(stbi__context *s); static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_PNG static int stbi__png_test(stbi__context *s); static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp); static int stbi__png_is16(stbi__context *s); #endif #ifndef STBI_NO_BMP static int stbi__bmp_test(stbi__context *s); static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_TGA static int stbi__tga_test(stbi__context *s); static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_PSD static int stbi__psd_test(stbi__context *s); static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc); static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp); static int stbi__psd_is16(stbi__context *s); #endif #ifndef STBI_NO_HDR static int stbi__hdr_test(stbi__context *s); static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_PIC static int stbi__pic_test(stbi__context *s); static void *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_GIF static int stbi__gif_test(stbi__context *s); static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp); static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_PNM static int stbi__pnm_test(stbi__context *s); static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); static int stbi__pnm_is16(stbi__context *s); #endif static #ifdef STBI_THREAD_LOCAL STBI_THREAD_LOCAL #endif const char *stbi__g_failure_reason; STBIDEF const char *stbi_failure_reason(void) { return stbi__g_failure_reason; } #ifndef STBI_NO_FAILURE_STRINGS static int stbi__err(const char *str) { stbi__g_failure_reason = str; return 0; } #endif static void *stbi__malloc(size_t size) { return STBI_MALLOC(size); } // stb_image uses ints pervasively, including for offset calculations. // therefore the largest decoded image size we can support with the // current code, even on 64-bit targets, is INT_MAX. this is not a // significant limitation for the intended use case. // // we do, however, need to make sure our size calculations don't // overflow. hence a few helper functions for size calculations that // multiply integers together, making sure that they're non-negative // and no overflow occurs. // return 1 if the sum is valid, 0 on overflow. // negative terms are considered invalid. static int stbi__addsizes_valid(int a, int b) { if (b < 0) return 0; // now 0 <= b <= INT_MAX, hence also // 0 <= INT_MAX - b <= INTMAX. // And "a + b <= INT_MAX" (which might overflow) is the // same as a <= INT_MAX - b (no overflow) return a <= INT_MAX - b; } // returns 1 if the product is valid, 0 on overflow. // negative factors are considered invalid. static int stbi__mul2sizes_valid(int a, int b) { if (a < 0 || b < 0) return 0; if (b == 0) return 1; // mul-by-0 is always safe // portable way to check for no overflows in a*b return a <= INT_MAX/b; } #if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) // returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow static int stbi__mad2sizes_valid(int a, int b, int add) { return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add); } #endif // returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow static int stbi__mad3sizes_valid(int a, int b, int c, int add) { return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && stbi__addsizes_valid(a*b*c, add); } // returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM) || !defined(STBI_NO_PNG) || !defined(STBI_NO_PSD) static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) { return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && stbi__mul2sizes_valid(a*b*c, d) && stbi__addsizes_valid(a*b*c*d, add); } #endif #if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) // mallocs with size overflow checking static void *stbi__malloc_mad2(int a, int b, int add) { if (!stbi__mad2sizes_valid(a, b, add)) return NULL; return stbi__malloc(a*b + add); } #endif static void *stbi__malloc_mad3(int a, int b, int c, int add) { if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL; return stbi__malloc(a*b*c + add); } #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM) || !defined(STBI_NO_PNG) || !defined(STBI_NO_PSD) static void *stbi__malloc_mad4(int a, int b, int c, int d, int add) { if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; return stbi__malloc(a*b*c*d + add); } #endif // returns 1 if the sum of two signed ints is valid (between -2^31 and 2^31-1 inclusive), 0 on overflow. static int stbi__addints_valid(int a, int b) { if ((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow if (a < 0 && b < 0) return a >= INT_MIN - b; // same as a + b >= INT_MIN; INT_MIN - b cannot overflow since b < 0. return a <= INT_MAX - b; } // returns 1 if the product of two ints fits in a signed short, 0 on overflow. static int stbi__mul2shorts_valid(int a, int b) { if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX/b; // product is positive, so similar to mul2sizes_valid if (b < 0) return a <= SHRT_MIN / b; // same as a * b >= SHRT_MIN return a >= SHRT_MIN / b; } // stbi__err - error // stbi__errpf - error returning pointer to float // stbi__errpuc - error returning pointer to unsigned char #ifdef STBI_NO_FAILURE_STRINGS #define stbi__err(x,y) 0 #elif defined(STBI_FAILURE_USERMSG) #define stbi__err(x,y) stbi__err(y) #else #define stbi__err(x,y) stbi__err(x) #endif #define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL)) #define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL)) STBIDEF void stbi_image_free(void *retval_from_stbi_load) { STBI_FREE(retval_from_stbi_load); } #ifndef STBI_NO_LINEAR static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp); #endif #ifndef STBI_NO_HDR static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp); #endif static int stbi__vertically_flip_on_load_global = 0; STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) { stbi__vertically_flip_on_load_global = flag_true_if_should_flip; } #ifndef STBI_THREAD_LOCAL #define stbi__vertically_flip_on_load stbi__vertically_flip_on_load_global #else static STBI_THREAD_LOCAL int stbi__vertically_flip_on_load_local, stbi__vertically_flip_on_load_set; STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip) { stbi__vertically_flip_on_load_local = flag_true_if_should_flip; stbi__vertically_flip_on_load_set = 1; } #define stbi__vertically_flip_on_load (stbi__vertically_flip_on_load_set \ ? stbi__vertically_flip_on_load_local \ : stbi__vertically_flip_on_load_global) #endif // STBI_THREAD_LOCAL static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) { memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order ri->num_channels = 0; // test the formats with a very explicit header first (at least a FOURCC // or distinctive magic number first) #ifndef STBI_NO_PNG if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri); #endif #ifndef STBI_NO_BMP if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp, ri); #endif #ifndef STBI_NO_GIF if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp, ri); #endif #ifndef STBI_NO_PSD if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc); #else STBI_NOTUSED(bpc); #endif #ifndef STBI_NO_PIC if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri); #endif // then the formats that can end up attempting to load with just 1 or 2 // bytes matching expectations; these are prone to false positives, so // try them later #ifndef STBI_NO_JPEG if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri); #endif #ifndef STBI_NO_PNM if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri); #endif #ifndef STBI_NO_HDR if (stbi__hdr_test(s)) { float *hdr = stbi__hdr_load(s, x,y,comp,req_comp, ri); return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); } #endif #ifndef STBI_NO_TGA // test tga last because it's a crappy test! if (stbi__tga_test(s)) return stbi__tga_load(s,x,y,comp,req_comp, ri); #endif return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); } static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int channels) { int i; int img_len = w * h * channels; stbi_uc *reduced; reduced = (stbi_uc *) stbi__malloc(img_len); if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory"); for (i = 0; i < img_len; ++i) reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling STBI_FREE(orig); return reduced; } static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int channels) { int i; int img_len = w * h * channels; stbi__uint16 *enlarged; enlarged = (stbi__uint16 *) stbi__malloc(((size_t)img_len)*2); if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); for (i = 0; i < img_len; ++i) enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff STBI_FREE(orig); return enlarged; } static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel) { int row; size_t bytes_per_row = (size_t)w * bytes_per_pixel; stbi_uc temp[2048]; stbi_uc *bytes = (stbi_uc *)image; for (row = 0; row < (h>>1); row++) { stbi_uc *row0 = bytes + row*bytes_per_row; stbi_uc *row1 = bytes + (h - row - 1)*bytes_per_row; // swap row0 with row1 size_t bytes_left = bytes_per_row; while (bytes_left) { size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp); memcpy(temp, row0, bytes_copy); memcpy(row0, row1, bytes_copy); memcpy(row1, temp, bytes_copy); row0 += bytes_copy; row1 += bytes_copy; bytes_left -= bytes_copy; } } } #ifndef STBI_NO_GIF static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel) { int slice; int slice_size = w * h * bytes_per_pixel; stbi_uc *bytes = (stbi_uc *)image; for (slice = 0; slice < z; ++slice) { stbi__vertical_flip(bytes, w, h, bytes_per_pixel); bytes += slice_size; } } #endif static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) { stbi__result_info ri; void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8); if (result == NULL) return NULL; // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); if (ri.bits_per_channel != 8) { stbi_uc *converted = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp); if (converted == NULL) { STBI_FREE(result); return NULL; } result = converted; ri.bits_per_channel = 8; } // @TODO: move stbi__convert_format to here if (stbi__vertically_flip_on_load) { int channels = req_comp ? req_comp : *comp; stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc)); } return (unsigned char *) result; } static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) { stbi__result_info ri; void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16); if (result == NULL) return NULL; // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); if (ri.bits_per_channel != 16) { stbi__uint16 * converted = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp); if (converted == NULL) { STBI_FREE(result); return NULL; } result = converted; ri.bits_per_channel = 16; } // @TODO: move stbi__convert_format16 to here // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision if (stbi__vertically_flip_on_load) { int channels = req_comp ? req_comp : *comp; stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16)); } return (stbi__uint16 *) result; } #if !defined(STBI_NO_HDR) && !defined(STBI_NO_LINEAR) static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp) { if (stbi__vertically_flip_on_load && result != NULL) { int channels = req_comp ? req_comp : *comp; stbi__vertical_flip(result, *x, *y, channels * sizeof(float)); } } #endif #ifndef STBI_NO_STDIO #if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide); STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default); #endif #if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) { return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); } #endif static FILE *stbi__fopen(char const *filename, char const *mode) { FILE *f; #if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) wchar_t wMode[64]; wchar_t wFilename[1024]; if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename))) return 0; if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode))) return 0; #if defined(_MSC_VER) && _MSC_VER >= 1400 if (0 != _wfopen_s(&f, wFilename, wMode)) f = 0; #else f = _wfopen(wFilename, wMode); #endif #elif defined(_MSC_VER) && _MSC_VER >= 1400 if (0 != fopen_s(&f, filename, mode)) f=0; #else f = fopen(filename, mode); #endif return f; } STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) { FILE *f = stbi__fopen(filename, "rb"); unsigned char *result; if (!f) return stbi__errpuc("can't fopen", "Unable to open file"); result = stbi_load_from_file(f,x,y,comp,req_comp); fclose(f); return result; } STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) { unsigned char *result; stbi__context s; stbi__start_file(&s,f); result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); if (result) { // need to 'unget' all the characters in the IO buffer if (fseek(f, -(int)(s.img_buffer_end - s.img_buffer), SEEK_CUR) != 0) { // fseek() failed; we can no longer maintain the file cursor position // guarantee of this function, so return null. STBI_FREE(result); return stbi__errpuc("bad file", "fseek() failed; seek position unreliable"); } } return result; } STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp, int req_comp) { stbi__uint16 *result; stbi__context s; stbi__start_file(&s,f); result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp); if (result) { // need to 'unget' all the characters in the IO buffer if (fseek(f, -(int)(s.img_buffer_end - s.img_buffer), SEEK_CUR) != 0) { // fseek() failed; we can no longer maintain the file cursor position // guarantee of this function, so return null. STBI_FREE(result); return (stbi__uint16 *) stbi__errpuc("bad file", "fseek() failed; seek position unreliable"); } } return result; } STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, int req_comp) { FILE *f = stbi__fopen(filename, "rb"); stbi__uint16 *result; if (!f) return (stbi_us *) stbi__errpuc("can't fopen", "Unable to open file"); result = stbi_load_from_file_16(f,x,y,comp,req_comp); fclose(f); return result; } #endif //!STBI_NO_STDIO STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels) { stbi__context s; stbi__start_mem(&s,buffer,len); return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); } STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels) { stbi__context s; stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user); return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); } STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) { stbi__context s; stbi__start_mem(&s,buffer,len); return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); } STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) { stbi__context s; stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); } #ifndef STBI_NO_GIF STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp) { unsigned char *result; stbi__context s; stbi__start_mem(&s,buffer,len); result = (unsigned char*) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp); if (stbi__vertically_flip_on_load && result) { int channels = req_comp ? req_comp : *comp; stbi__vertical_flip_slices( result, *x, *y, *z, channels ); } return result; } #endif #ifndef STBI_NO_LINEAR static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) { unsigned char *data; #ifndef STBI_NO_HDR if (stbi__hdr_test(s)) { stbi__result_info ri; float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp, &ri); if (hdr_data) stbi__float_postprocess(hdr_data,x,y,comp,req_comp); return hdr_data; } #endif data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp); if (data) return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); return stbi__errpf("unknown image type", "Image not of any known type, or corrupt"); } STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) { stbi__context s; stbi__start_mem(&s,buffer,len); return stbi__loadf_main(&s,x,y,comp,req_comp); } STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) { stbi__context s; stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); return stbi__loadf_main(&s,x,y,comp,req_comp); } #ifndef STBI_NO_STDIO STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) { float *result; FILE *f = stbi__fopen(filename, "rb"); if (!f) return stbi__errpf("can't fopen", "Unable to open file"); result = stbi_loadf_from_file(f,x,y,comp,req_comp); fclose(f); return result; } STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) { stbi__context s; stbi__start_file(&s,f); return stbi__loadf_main(&s,x,y,comp,req_comp); } #endif // !STBI_NO_STDIO #endif // !STBI_NO_LINEAR // these is-hdr-or-not is defined independent of whether STBI_NO_LINEAR is // defined, for API simplicity; if STBI_NO_LINEAR is defined, it always // reports false! STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) { #ifndef STBI_NO_HDR stbi__context s; stbi__start_mem(&s,buffer,len); return stbi__hdr_test(&s); #else STBI_NOTUSED(buffer); STBI_NOTUSED(len); return 0; #endif } #ifndef STBI_NO_STDIO STBIDEF int stbi_is_hdr (char const *filename) { FILE *f = stbi__fopen(filename, "rb"); int result=0; if (f) { result = stbi_is_hdr_from_file(f); fclose(f); } return result; } STBIDEF int stbi_is_hdr_from_file(FILE *f) { #ifndef STBI_NO_HDR int res; long pos = ftell(f); if (pos < 0) return stbi__err("bad file", "ftell() failed"); stbi__context s; stbi__start_file(&s,f); res = stbi__hdr_test(&s); if (fseek(f, pos, SEEK_SET) != 0) return stbi__err("bad file", "fseek() failed"); return res; #else STBI_NOTUSED(f); return 0; #endif } #endif // !STBI_NO_STDIO STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) { #ifndef STBI_NO_HDR stbi__context s; stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); return stbi__hdr_test(&s); #else STBI_NOTUSED(clbk); STBI_NOTUSED(user); return 0; #endif } #ifndef STBI_NO_LINEAR static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f; STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; } STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; } #endif static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f; STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; } STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; } ////////////////////////////////////////////////////////////////////////////// // // Common code used by all image loaders // enum { STBI__SCAN_load=0, STBI__SCAN_type, STBI__SCAN_header }; static void stbi__refill_buffer(stbi__context *s) { int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); s->callback_already_read += (int) (s->img_buffer - s->img_buffer_original); if (n == 0) { // at end of file, treat same as if from memory, but need to handle case // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file s->read_from_callbacks = 0; s->img_buffer = s->buffer_start; s->img_buffer_end = s->buffer_start+1; *s->img_buffer = 0; } else { s->img_buffer = s->buffer_start; s->img_buffer_end = s->buffer_start + n; } } stbi_inline static stbi_uc stbi__get8(stbi__context *s) { if (s->img_buffer < s->img_buffer_end) return *s->img_buffer++; if (s->read_from_callbacks) { stbi__refill_buffer(s); return *s->img_buffer++; } return 0; } #if defined(STBI_NO_JPEG) && defined(STBI_NO_HDR) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) // nothing #else stbi_inline static int stbi__at_eof(stbi__context *s) { if (s->io.read) { if (!(s->io.eof)(s->io_user_data)) return 0; // if feof() is true, check if buffer = end // special case: we've only got the special 0 character at the end if (s->read_from_callbacks == 0) return 1; } return s->img_buffer >= s->img_buffer_end; } #endif #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) // nothing #else static void stbi__skip(stbi__context *s, int n) { if (n == 0) return; // already there! if (n < 0) { s->img_buffer = s->img_buffer_end; return; } if (s->io.read) { int blen = (int) (s->img_buffer_end - s->img_buffer); if (blen < n) { s->img_buffer = s->img_buffer_end; (s->io.skip)(s->io_user_data, n - blen); return; } } s->img_buffer += n; } #endif #if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) // nothing #else static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n) { if (s->io.read) { int blen = (int) (s->img_buffer_end - s->img_buffer); if (blen < n) { int res, count; memcpy(buffer, s->img_buffer, blen); count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); res = (count == (n-blen)); s->img_buffer = s->img_buffer_end; return res; } } if (s->img_buffer+n <= s->img_buffer_end) { memcpy(buffer, s->img_buffer, n); s->img_buffer += n; return 1; } else return 0; } #endif #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) // nothing #else static int stbi__get16be(stbi__context *s) { int z = stbi__get8(s); return (z << 8) + stbi__get8(s); } #endif #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) // nothing #else static stbi__uint32 stbi__get32be(stbi__context *s) { stbi__uint32 z = stbi__get16be(s); return (z << 16) + stbi__get16be(s); } #endif #if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) // nothing #else static int stbi__get16le(stbi__context *s) { int z = stbi__get8(s); return z + (stbi__get8(s) << 8); } #endif #ifndef STBI_NO_BMP static stbi__uint32 stbi__get32le(stbi__context *s) { stbi__uint32 z = stbi__get16le(s); z += (stbi__uint32)stbi__get16le(s) << 16; return z; } #endif #define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) // nothing #else ////////////////////////////////////////////////////////////////////////////// // // generic converter from built-in img_n to req_comp // individual types do this automatically as much as possible (e.g. jpeg // does all cases internally since it needs to colorspace convert anyway, // and it never has alpha, so very few cases ). png can automatically // interleave an alpha=255 channel, but falls back to this for other cases // // assume data buffer is malloced, so malloc a new one and free that one // only failure mode is malloc failing static stbi_uc stbi__compute_y(int r, int g, int b) { return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8); } #endif #if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) // nothing #else static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y) { int i,j; unsigned char *good; if (data == NULL) return data; if (req_comp == img_n) return data; STBI_ASSERT(req_comp >= 1 && req_comp <= 4); good = (unsigned char *) stbi__malloc_mad3(req_comp, x, y, 0); if (good == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } for (j=0; j < (int) y; ++j) { unsigned char *src = data + j * x * img_n ; unsigned char *dest = good + j * x * req_comp; #define STBI__COMBO(a,b) ((a)*8+(b)) #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) // convert source image with img_n components to one with req_comp components; // avoid switch per pixel, so use switch per scanline and massive macros switch (STBI__COMBO(img_n, req_comp)) { STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=255; } break; STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=255; } break; STBI__CASE(2,1) { dest[0]=src[0]; } break; STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break; STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=255; } break; STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = 255; } break; STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break; STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break; default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); } #undef STBI__CASE } STBI_FREE(data); return good; } #endif #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PNM) // nothing #else static stbi__uint16 stbi__compute_y_16(int r, int g, int b) { return (stbi__uint16) (((r*77) + (g*150) + (29*b)) >> 8); } #endif #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PNM) // nothing #else static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y) { int i,j; stbi__uint16 *good; if (req_comp == img_n) return data; STBI_ASSERT(req_comp >= 1 && req_comp <= 4); good = (stbi__uint16 *) stbi__malloc_mad4(req_comp, x, y, 2, 0); if (good == NULL) { STBI_FREE(data); return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); } for (j=0; j < (int) y; ++j) { stbi__uint16 *src = data + j * x * img_n ; stbi__uint16 *dest = good + j * x * req_comp; #define STBI__COMBO(a,b) ((a)*8+(b)) #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) // convert source image with img_n components to one with req_comp components; // avoid switch per pixel, so use switch per scanline and massive macros switch (STBI__COMBO(img_n, req_comp)) { STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=0xffff; } break; STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=0xffff; } break; STBI__CASE(2,1) { dest[0]=src[0]; } break; STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break; STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=0xffff; } break; STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = 0xffff; } break; STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break; STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break; default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*) stbi__errpuc("unsupported", "Unsupported format conversion"); } #undef STBI__CASE } STBI_FREE(data); return good; } #endif #ifndef STBI_NO_LINEAR static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) { int i,k,n; float *output; if (!data) return NULL; output = (float *) stbi__malloc_mad4(x, y, comp, sizeof(float), 0); if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } // compute number of non-alpha components if (comp & 1) n = comp; else n = comp-1; for (i=0; i < x*y; ++i) { for (k=0; k < n; ++k) { output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale); } } if (n < comp) { for (i=0; i < x*y; ++i) { output[i*comp + n] = data[i*comp + n]/255.0f; } } STBI_FREE(data); return output; } #endif #ifndef STBI_NO_HDR #define stbi__float2int(x) ((int) (x)) static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) { int i,k,n; stbi_uc *output; if (!data) return NULL; output = (stbi_uc *) stbi__malloc_mad3(x, y, comp, 0); if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } // compute number of non-alpha components if (comp & 1) n = comp; else n = comp-1; for (i=0; i < x*y; ++i) { for (k=0; k < n; ++k) { float z = (float) pow(data[i*comp+k]*stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; if (z < 0) z = 0; if (z > 255) z = 255; output[i*comp + k] = (stbi_uc) stbi__float2int(z); } if (k < comp) { float z = data[i*comp+k] * 255 + 0.5f; if (z < 0) z = 0; if (z > 255) z = 255; output[i*comp + k] = (stbi_uc) stbi__float2int(z); } } STBI_FREE(data); return output; } #endif ////////////////////////////////////////////////////////////////////////////// // // "baseline" JPEG/JFIF decoder // // simple implementation // - doesn't support delayed output of y-dimension // - simple interface (only one output format: 8-bit interleaved RGB) // - doesn't try to recover corrupt jpegs // - doesn't allow partial loading, loading multiple at once // - still fast on x86 (copying globals into locals doesn't help x86) // - allocates lots of intermediate memory (full size of all components) // - non-interleaved case requires this anyway // - allows good upsampling (see next) // high-quality // - upsampled channels are bilinearly interpolated, even across blocks // - quality integer IDCT derived from IJG's 'slow' // performance // - fast huffman; reasonable integer IDCT // - some SIMD kernels for common paths on targets with SSE2/NEON // - uses a lot of intermediate memory, could cache poorly #ifndef STBI_NO_JPEG // huffman decoding acceleration #define FAST_BITS 9 // larger handles more cases; smaller stomps less cache typedef struct { stbi_uc fast[1 << FAST_BITS]; // weirdly, repacking this into AoS is a 10% speed loss, instead of a win stbi__uint16 code[256]; stbi_uc values[256]; stbi_uc size[257]; unsigned int maxcode[18]; int delta[17]; // old 'firstsymbol' - old 'firstcode' } stbi__huffman; typedef struct { stbi__context *s; stbi__huffman huff_dc[4]; stbi__huffman huff_ac[4]; stbi__uint16 dequant[4][64]; stbi__int16 fast_ac[4][1 << FAST_BITS]; // sizes for components, interleaved MCUs int img_h_max, img_v_max; int img_mcu_x, img_mcu_y; int img_mcu_w, img_mcu_h; // definition of jpeg image component struct { int id; int h,v; int tq; int hd,ha; int dc_pred; int x,y,w2,h2; stbi_uc *data; void *raw_data, *raw_coeff; stbi_uc *linebuf; short *coeff; // progressive only int coeff_w, coeff_h; // number of 8x8 coefficient blocks } img_comp[4]; stbi__uint32 code_buffer; // jpeg entropy-coded buffer int code_bits; // number of valid bits unsigned char marker; // marker seen while filling entropy buffer int nomore; // flag if we saw a marker so must stop int progressive; int spec_start; int spec_end; int succ_high; int succ_low; int eob_run; int jfif; int app14_color_transform; // Adobe APP14 tag int rgb; int scan_n, order[4]; int restart_interval, todo; // kernels void (*idct_block_kernel)(stbi_uc *out, int out_stride, short data[64]); void (*YCbCr_to_RGB_kernel)(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step); stbi_uc *(*resample_row_hv_2_kernel)(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs); } stbi__jpeg; static int stbi__build_huffman(stbi__huffman *h, int *count) { int i,j,k=0; unsigned int code; // build size list for each symbol (from JPEG spec) for (i=0; i < 16; ++i) { for (j=0; j < count[i]; ++j) { h->size[k++] = (stbi_uc) (i+1); if(k >= 257) return stbi__err("bad size list","Corrupt JPEG"); } } h->size[k] = 0; // compute actual symbols (from jpeg spec) code = 0; k = 0; for(j=1; j <= 16; ++j) { // compute delta to add to code to compute symbol id h->delta[j] = k - code; if (h->size[k] == j) { while (h->size[k] == j) h->code[k++] = (stbi__uint16) (code++); if (code-1 >= (1u << j)) return stbi__err("bad code lengths","Corrupt JPEG"); } // compute largest code + 1 for this size, preshifted as needed later h->maxcode[j] = code << (16-j); code <<= 1; } h->maxcode[j] = 0xffffffff; // build non-spec acceleration table; 255 is flag for not-accelerated memset(h->fast, 255, 1 << FAST_BITS); for (i=0; i < k; ++i) { int s = h->size[i]; if (s <= FAST_BITS) { int c = h->code[i] << (FAST_BITS-s); int m = 1 << (FAST_BITS-s); for (j=0; j < m; ++j) { h->fast[c+j] = (stbi_uc) i; } } } return 1; } // build a table that decodes both magnitude and value of small ACs in // one go. static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h) { int i; for (i=0; i < (1 << FAST_BITS); ++i) { stbi_uc fast = h->fast[i]; fast_ac[i] = 0; if (fast < 255) { int rs = h->values[fast]; int run = (rs >> 4) & 15; int magbits = rs & 15; int len = h->size[fast]; if (magbits && len + magbits <= FAST_BITS) { // magnitude code followed by receive_extend code int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); int m = 1 << (magbits - 1); if (k < m) k += (~0U << magbits) + 1; // if the result is small enough, we can fit it in fast_ac table if (k >= -128 && k <= 127) fast_ac[i] = (stbi__int16) ((k * 256) + (run * 16) + (len + magbits)); } } } } static void stbi__grow_buffer_unsafe(stbi__jpeg *j) { do { unsigned int b = j->nomore ? 0 : stbi__get8(j->s); if (b == 0xff) { int c = stbi__get8(j->s); while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes if (c != 0) { j->marker = (unsigned char) c; j->nomore = 1; return; } } j->code_buffer |= b << (24 - j->code_bits); j->code_bits += 8; } while (j->code_bits <= 24); } // (1 << n) - 1 static const stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; // decode a jpeg huffman value from the bitstream stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h) { unsigned int temp; int c,k; if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); // look at the top FAST_BITS and determine what symbol ID it is, // if the code is <= FAST_BITS c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); k = h->fast[c]; if (k < 255) { int s = h->size[k]; if (s > j->code_bits) return -1; j->code_buffer <<= s; j->code_bits -= s; return h->values[k]; } // naive test is to shift the code_buffer down so k bits are // valid, then test against maxcode. To speed this up, we've // preshifted maxcode left so that it has (16-k) 0s at the // end; in other words, regardless of the number of bits, it // wants to be compared against something shifted to have 16; // that way we don't need to shift inside the loop. temp = j->code_buffer >> 16; for (k=FAST_BITS+1 ; ; ++k) if (temp < h->maxcode[k]) break; if (k == 17) { // error! code not found j->code_bits -= 16; return -1; } if (k > j->code_bits) return -1; // convert the huffman code to the symbol id c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; if(c < 0 || c >= 256) // symbol id out of bounds! return -1; STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); // convert the id to a symbol j->code_bits -= k; j->code_buffer <<= k; return h->values[c]; } // bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) k = stbi_lrot(j->code_buffer, n); j->code_buffer = k & ~stbi__bmask[n]; k &= stbi__bmask[n]; j->code_bits -= n; return k + (stbi__jbias[n] & (sgn - 1)); } // get some unsigned bits stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n) { unsigned int k; if (j->code_bits < n) stbi__grow_buffer_unsafe(j); if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing k = stbi_lrot(j->code_buffer, n); j->code_buffer = k & ~stbi__bmask[n]; k &= stbi__bmask[n]; j->code_bits -= n; return k; } stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j) { unsigned int k; if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing k = j->code_buffer; j->code_buffer <<= 1; --j->code_bits; return k & 0x80000000; } // given a value that's at position X in the zigzag stream, // where does it appear in the 8x8 matrix coded as row-major? static const stbi_uc stbi__jpeg_dezigzag[64+15] = { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, // let corrupt input sample past end 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 }; // decode one 64-entry block-- static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi__uint16 *dequant) { int diff,dc,k; int t; if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); t = stbi__jpeg_huff_decode(j, hdc); if (t < 0 || t > 15) return stbi__err("bad huffman code","Corrupt JPEG"); // 0 all the ac values now so we can do it 32-bits at a time memset(data,0,64*sizeof(data[0])); diff = t ? stbi__extend_receive(j, t) : 0; if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta","Corrupt JPEG"); dc = j->img_comp[b].dc_pred + diff; j->img_comp[b].dc_pred = dc; if ((dc > SHRT_MAX) || (dequant[0] > SHRT_MAX) || !stbi__mul2shorts_valid((short) dc, (short) dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); data[0] = (short) ((size_t)dc * dequant[0]); // decode AC components, see JPEG spec k = 1; do { unsigned int zig; int c,r,s; if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); r = fac[c]; if (r) { // fast-AC path k += (r >> 4) & 15; // run s = r & 15; // combined length if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); j->code_buffer <<= s; j->code_bits -= s; // decode into unzigzag'd location zig = stbi__jpeg_dezigzag[k++]; data[zig] = (short) ((r >> 8) * dequant[zig]); } else { int rs = stbi__jpeg_huff_decode(j, hac); if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); s = rs & 15; r = rs >> 4; if (s == 0) { if (rs != 0xf0) break; // end block k += 16; } else { k += r; // decode into unzigzag'd location zig = stbi__jpeg_dezigzag[k++]; data[zig] = (short) (stbi__extend_receive(j,s) * dequant[zig]); } } } while (k < 64); return 1; } static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__huffman *hdc, int b) { int diff,dc; int t; if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); if (j->succ_high == 0) { // first scan for DC coefficient, must be first memset(data,0,64*sizeof(data[0])); // 0 all the ac values now t = stbi__jpeg_huff_decode(j, hdc); if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); diff = t ? stbi__extend_receive(j, t) : 0; if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); dc = j->img_comp[b].dc_pred + diff; j->img_comp[b].dc_pred = dc; if ((dc > SHRT_MAX) || !stbi__mul2shorts_valid((short) dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); data[0] = (short) (dc * (1 << j->succ_low)); } else { // refinement scan for DC coefficient if (stbi__jpeg_get_bit(j)) data[0] += (short) (1 << j->succ_low); } return 1; } // @OPTIMIZE: store non-zigzagged during the decode passes, // and only de-zigzag when dequantizing static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__huffman *hac, stbi__int16 *fac) { int k; if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); if (j->succ_high == 0) { int shift = j->succ_low; if (j->eob_run) { --j->eob_run; return 1; } k = j->spec_start; do { unsigned int zig; int c,r,s; if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); r = fac[c]; if (r) { // fast-AC path k += (r >> 4) & 15; // run s = r & 15; // combined length if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); j->code_buffer <<= s; j->code_bits -= s; zig = stbi__jpeg_dezigzag[k++]; data[zig] = (short) ((r >> 8) * (1 << shift)); } else { int rs = stbi__jpeg_huff_decode(j, hac); if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); s = rs & 15; r = rs >> 4; if (s == 0) { if (r < 15) { j->eob_run = (1 << r); if (r) j->eob_run += stbi__jpeg_get_bits(j, r); --j->eob_run; break; } k += 16; } else { k += r; zig = stbi__jpeg_dezigzag[k++]; data[zig] = (short) (stbi__extend_receive(j,s) * (1 << shift)); } } } while (k <= j->spec_end); } else { // refinement scan for these AC coefficients short bit = (short) (1 << j->succ_low); if (j->eob_run) { --j->eob_run; for (k = j->spec_start; k <= j->spec_end; ++k) { short *p = &data[stbi__jpeg_dezigzag[k]]; if (*p != 0) if (stbi__jpeg_get_bit(j)) if ((*p & bit)==0) { if (*p > 0) *p += bit; else *p -= bit; } } } else { k = j->spec_start; do { int r,s; int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); s = rs & 15; r = rs >> 4; if (s == 0) { if (r < 15) { j->eob_run = (1 << r) - 1; if (r) j->eob_run += stbi__jpeg_get_bits(j, r); r = 64; // force end of block } else { // r=15 s=0 should write 16 0s, so we just do // a run of 15 0s and then write s (which is 0), // so we don't have to do anything special here } } else { if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); // sign bit if (stbi__jpeg_get_bit(j)) s = bit; else s = -bit; } // advance by r while (k <= j->spec_end) { short *p = &data[stbi__jpeg_dezigzag[k++]]; if (*p != 0) { if (stbi__jpeg_get_bit(j)) if ((*p & bit)==0) { if (*p > 0) *p += bit; else *p -= bit; } } else { if (r == 0) { *p = (short) s; break; } --r; } } } while (k <= j->spec_end); } } return 1; } // take a -128..127 value and stbi__clamp it and convert to 0..255 stbi_inline static stbi_uc stbi__clamp(int x) { // trick to use a single test to catch both cases if ((unsigned int) x > 255) { if (x < 0) return 0; if (x > 255) return 255; } return (stbi_uc) x; } #define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) #define stbi__fsh(x) ((x) * 4096) // derived from jidctint -- DCT_ISLOW #define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ p2 = s2; \ p3 = s6; \ p1 = (p2+p3) * stbi__f2f(0.5411961f); \ t2 = p1 + p3*stbi__f2f(-1.847759065f); \ t3 = p1 + p2*stbi__f2f( 0.765366865f); \ p2 = s0; \ p3 = s4; \ t0 = stbi__fsh(p2+p3); \ t1 = stbi__fsh(p2-p3); \ x0 = t0+t3; \ x3 = t0-t3; \ x1 = t1+t2; \ x2 = t1-t2; \ t0 = s7; \ t1 = s5; \ t2 = s3; \ t3 = s1; \ p3 = t0+t2; \ p4 = t1+t3; \ p1 = t0+t3; \ p2 = t1+t2; \ p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ t0 = t0*stbi__f2f( 0.298631336f); \ t1 = t1*stbi__f2f( 2.053119869f); \ t2 = t2*stbi__f2f( 3.072711026f); \ t3 = t3*stbi__f2f( 1.501321110f); \ p1 = p5 + p1*stbi__f2f(-0.899976223f); \ p2 = p5 + p2*stbi__f2f(-2.562915447f); \ p3 = p3*stbi__f2f(-1.961570560f); \ p4 = p4*stbi__f2f(-0.390180644f); \ t3 += p1+p4; \ t2 += p2+p3; \ t1 += p2+p4; \ t0 += p1+p3; static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64]) { int i,val[64],*v=val; stbi_uc *o; short *d = data; // columns for (i=0; i < 8; ++i,++d, ++v) { // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 && d[40]==0 && d[48]==0 && d[56]==0) { // no shortcut 0 seconds // (1|2|3|4|5|6|7)==0 0 seconds // all separate -0.047 seconds // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds int dcterm = d[0]*4; v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; } else { STBI__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[56]) // constants scaled things up by 1<<12; let's bring them back // down, but keep 2 extra bits of precision x0 += 512; x1 += 512; x2 += 512; x3 += 512; v[ 0] = (x0+t3) >> 10; v[56] = (x0-t3) >> 10; v[ 8] = (x1+t2) >> 10; v[48] = (x1-t2) >> 10; v[16] = (x2+t1) >> 10; v[40] = (x2-t1) >> 10; v[24] = (x3+t0) >> 10; v[32] = (x3-t0) >> 10; } } for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { // no fast case since the first 1D IDCT spread components out STBI__IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) // constants scaled things up by 1<<12, plus we had 1<<2 from first // loop, plus horizontal and vertical each scale by sqrt(8) so together // we've got an extra 1<<3, so 1<<17 total we need to remove. // so we want to round that, which means adding 0.5 * 1<<17, // aka 65536. Also, we'll end up with -128 to 127 that we want // to encode as 0..255 by adding 128, so we'll add that before the shift x0 += 65536 + (128<<17); x1 += 65536 + (128<<17); x2 += 65536 + (128<<17); x3 += 65536 + (128<<17); // tried computing the shifts into temps, or'ing the temps to see // if any were out of range, but that was slower o[0] = stbi__clamp((x0+t3) >> 17); o[7] = stbi__clamp((x0-t3) >> 17); o[1] = stbi__clamp((x1+t2) >> 17); o[6] = stbi__clamp((x1-t2) >> 17); o[2] = stbi__clamp((x2+t1) >> 17); o[5] = stbi__clamp((x2-t1) >> 17); o[3] = stbi__clamp((x3+t0) >> 17); o[4] = stbi__clamp((x3-t0) >> 17); } } #ifdef STBI_SSE2 // sse2 integer IDCT. not the fastest possible implementation but it // produces bit-identical results to the generic C version so it's // fully "transparent". static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) { // This is constructed to match our regular (generic) integer IDCT exactly. __m128i row0, row1, row2, row3, row4, row5, row6, row7; __m128i tmp; // dot product constant: even elems=x, odd elems=y #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) // out(1) = c1[even]*x + c1[odd]*y #define dct_rot(out0,out1, x,y,c0,c1) \ __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) // out = in << 12 (in 16-bit, out 32-bit) #define dct_widen(out, in) \ __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) // wide add #define dct_wadd(out, a, b) \ __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ __m128i out##_h = _mm_add_epi32(a##_h, b##_h) // wide sub #define dct_wsub(out, a, b) \ __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) // butterfly a/b, add bias, then shift by "s" and pack #define dct_bfly32o(out0, out1, a,b,bias,s) \ { \ __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ dct_wadd(sum, abiased, b); \ dct_wsub(dif, abiased, b); \ out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ } // 8-bit interleave step (for transposes) #define dct_interleave8(a, b) \ tmp = a; \ a = _mm_unpacklo_epi8(a, b); \ b = _mm_unpackhi_epi8(tmp, b) // 16-bit interleave step (for transposes) #define dct_interleave16(a, b) \ tmp = a; \ a = _mm_unpacklo_epi16(a, b); \ b = _mm_unpackhi_epi16(tmp, b) #define dct_pass(bias,shift) \ { \ /* even part */ \ dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ __m128i sum04 = _mm_add_epi16(row0, row4); \ __m128i dif04 = _mm_sub_epi16(row0, row4); \ dct_widen(t0e, sum04); \ dct_widen(t1e, dif04); \ dct_wadd(x0, t0e, t3e); \ dct_wsub(x3, t0e, t3e); \ dct_wadd(x1, t1e, t2e); \ dct_wsub(x2, t1e, t2e); \ /* odd part */ \ dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ __m128i sum17 = _mm_add_epi16(row1, row7); \ __m128i sum35 = _mm_add_epi16(row3, row5); \ dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ dct_wadd(x4, y0o, y4o); \ dct_wadd(x5, y1o, y5o); \ dct_wadd(x6, y2o, y5o); \ dct_wadd(x7, y3o, y4o); \ dct_bfly32o(row0,row7, x0,x7,bias,shift); \ dct_bfly32o(row1,row6, x1,x6,bias,shift); \ dct_bfly32o(row2,row5, x2,x5,bias,shift); \ dct_bfly32o(row3,row4, x3,x4,bias,shift); \ } __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f( 0.765366865f), stbi__f2f(0.5411961f)); __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f( 0.298631336f), stbi__f2f(-1.961570560f)); __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f( 3.072711026f)); __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f( 2.053119869f), stbi__f2f(-0.390180644f)); __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f( 1.501321110f)); // rounding biases in column/row passes, see stbi__idct_block for explanation. __m128i bias_0 = _mm_set1_epi32(512); __m128i bias_1 = _mm_set1_epi32(65536 + (128<<17)); // load row0 = _mm_load_si128((const __m128i *) (data + 0*8)); row1 = _mm_load_si128((const __m128i *) (data + 1*8)); row2 = _mm_load_si128((const __m128i *) (data + 2*8)); row3 = _mm_load_si128((const __m128i *) (data + 3*8)); row4 = _mm_load_si128((const __m128i *) (data + 4*8)); row5 = _mm_load_si128((const __m128i *) (data + 5*8)); row6 = _mm_load_si128((const __m128i *) (data + 6*8)); row7 = _mm_load_si128((const __m128i *) (data + 7*8)); // column pass dct_pass(bias_0, 10); { // 16bit 8x8 transpose pass 1 dct_interleave16(row0, row4); dct_interleave16(row1, row5); dct_interleave16(row2, row6); dct_interleave16(row3, row7); // transpose pass 2 dct_interleave16(row0, row2); dct_interleave16(row1, row3); dct_interleave16(row4, row6); dct_interleave16(row5, row7); // transpose pass 3 dct_interleave16(row0, row1); dct_interleave16(row2, row3); dct_interleave16(row4, row5); dct_interleave16(row6, row7); } // row pass dct_pass(bias_1, 17); { // pack __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 __m128i p1 = _mm_packus_epi16(row2, row3); __m128i p2 = _mm_packus_epi16(row4, row5); __m128i p3 = _mm_packus_epi16(row6, row7); // 8bit 8x8 transpose pass 1 dct_interleave8(p0, p2); // a0e0a1e1... dct_interleave8(p1, p3); // c0g0c1g1... // transpose pass 2 dct_interleave8(p0, p1); // a0c0e0g0... dct_interleave8(p2, p3); // b0d0f0h0... // transpose pass 3 dct_interleave8(p0, p2); // a0b0c0d0... dct_interleave8(p1, p3); // a4b4c4d4... // store _mm_storel_epi64((__m128i *) out, p0); out += out_stride; _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; _mm_storel_epi64((__m128i *) out, p2); out += out_stride; _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; _mm_storel_epi64((__m128i *) out, p1); out += out_stride; _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; _mm_storel_epi64((__m128i *) out, p3); out += out_stride; _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e)); } #undef dct_const #undef dct_rot #undef dct_widen #undef dct_wadd #undef dct_wsub #undef dct_bfly32o #undef dct_interleave8 #undef dct_interleave16 #undef dct_pass } #endif // STBI_SSE2 #ifdef STBI_NEON // NEON integer IDCT. should produce bit-identical // results to the generic C version. static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) { int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); int16x4_t rot0_2 = vdup_n_s16(stbi__f2f( 0.765366865f)); int16x4_t rot1_0 = vdup_n_s16(stbi__f2f( 1.175875602f)); int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); int16x4_t rot3_0 = vdup_n_s16(stbi__f2f( 0.298631336f)); int16x4_t rot3_1 = vdup_n_s16(stbi__f2f( 2.053119869f)); int16x4_t rot3_2 = vdup_n_s16(stbi__f2f( 3.072711026f)); int16x4_t rot3_3 = vdup_n_s16(stbi__f2f( 1.501321110f)); #define dct_long_mul(out, inq, coeff) \ int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) #define dct_long_mac(out, acc, inq, coeff) \ int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) #define dct_widen(out, inq) \ int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) // wide add #define dct_wadd(out, a, b) \ int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ int32x4_t out##_h = vaddq_s32(a##_h, b##_h) // wide sub #define dct_wsub(out, a, b) \ int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ int32x4_t out##_h = vsubq_s32(a##_h, b##_h) // butterfly a/b, then shift using "shiftop" by "s" and pack #define dct_bfly32o(out0,out1, a,b,shiftop,s) \ { \ dct_wadd(sum, a, b); \ dct_wsub(dif, a, b); \ out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ } #define dct_pass(shiftop, shift) \ { \ /* even part */ \ int16x8_t sum26 = vaddq_s16(row2, row6); \ dct_long_mul(p1e, sum26, rot0_0); \ dct_long_mac(t2e, p1e, row6, rot0_1); \ dct_long_mac(t3e, p1e, row2, rot0_2); \ int16x8_t sum04 = vaddq_s16(row0, row4); \ int16x8_t dif04 = vsubq_s16(row0, row4); \ dct_widen(t0e, sum04); \ dct_widen(t1e, dif04); \ dct_wadd(x0, t0e, t3e); \ dct_wsub(x3, t0e, t3e); \ dct_wadd(x1, t1e, t2e); \ dct_wsub(x2, t1e, t2e); \ /* odd part */ \ int16x8_t sum15 = vaddq_s16(row1, row5); \ int16x8_t sum17 = vaddq_s16(row1, row7); \ int16x8_t sum35 = vaddq_s16(row3, row5); \ int16x8_t sum37 = vaddq_s16(row3, row7); \ int16x8_t sumodd = vaddq_s16(sum17, sum35); \ dct_long_mul(p5o, sumodd, rot1_0); \ dct_long_mac(p1o, p5o, sum17, rot1_1); \ dct_long_mac(p2o, p5o, sum35, rot1_2); \ dct_long_mul(p3o, sum37, rot2_0); \ dct_long_mul(p4o, sum15, rot2_1); \ dct_wadd(sump13o, p1o, p3o); \ dct_wadd(sump24o, p2o, p4o); \ dct_wadd(sump23o, p2o, p3o); \ dct_wadd(sump14o, p1o, p4o); \ dct_long_mac(x4, sump13o, row7, rot3_0); \ dct_long_mac(x5, sump24o, row5, rot3_1); \ dct_long_mac(x6, sump23o, row3, rot3_2); \ dct_long_mac(x7, sump14o, row1, rot3_3); \ dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ } // load row0 = vld1q_s16(data + 0*8); row1 = vld1q_s16(data + 1*8); row2 = vld1q_s16(data + 2*8); row3 = vld1q_s16(data + 3*8); row4 = vld1q_s16(data + 4*8); row5 = vld1q_s16(data + 5*8); row6 = vld1q_s16(data + 6*8); row7 = vld1q_s16(data + 7*8); // add DC bias row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); // column pass dct_pass(vrshrn_n_s32, 10); // 16bit 8x8 transpose { // these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. // whether compilers actually get this is another story, sadly. #define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } #define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } #define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } // pass 1 dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 dct_trn16(row2, row3); dct_trn16(row4, row5); dct_trn16(row6, row7); // pass 2 dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 dct_trn32(row1, row3); dct_trn32(row4, row6); dct_trn32(row5, row7); // pass 3 dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 dct_trn64(row1, row5); dct_trn64(row2, row6); dct_trn64(row3, row7); #undef dct_trn16 #undef dct_trn32 #undef dct_trn64 } // row pass // vrshrn_n_s32 only supports shifts up to 16, we need // 17. so do a non-rounding shift of 16 first then follow // up with a rounding shift by 1. dct_pass(vshrn_n_s32, 16); { // pack and round uint8x8_t p0 = vqrshrun_n_s16(row0, 1); uint8x8_t p1 = vqrshrun_n_s16(row1, 1); uint8x8_t p2 = vqrshrun_n_s16(row2, 1); uint8x8_t p3 = vqrshrun_n_s16(row3, 1); uint8x8_t p4 = vqrshrun_n_s16(row4, 1); uint8x8_t p5 = vqrshrun_n_s16(row5, 1); uint8x8_t p6 = vqrshrun_n_s16(row6, 1); uint8x8_t p7 = vqrshrun_n_s16(row7, 1); // again, these can translate into one instruction, but often don't. #define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } #define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } #define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } // sadly can't use interleaved stores here since we only write // 8 bytes to each scan line! // 8x8 8-bit transpose pass 1 dct_trn8_8(p0, p1); dct_trn8_8(p2, p3); dct_trn8_8(p4, p5); dct_trn8_8(p6, p7); // pass 2 dct_trn8_16(p0, p2); dct_trn8_16(p1, p3); dct_trn8_16(p4, p6); dct_trn8_16(p5, p7); // pass 3 dct_trn8_32(p0, p4); dct_trn8_32(p1, p5); dct_trn8_32(p2, p6); dct_trn8_32(p3, p7); // store vst1_u8(out, p0); out += out_stride; vst1_u8(out, p1); out += out_stride; vst1_u8(out, p2); out += out_stride; vst1_u8(out, p3); out += out_stride; vst1_u8(out, p4); out += out_stride; vst1_u8(out, p5); out += out_stride; vst1_u8(out, p6); out += out_stride; vst1_u8(out, p7); #undef dct_trn8_8 #undef dct_trn8_16 #undef dct_trn8_32 } #undef dct_long_mul #undef dct_long_mac #undef dct_widen #undef dct_wadd #undef dct_wsub #undef dct_bfly32o #undef dct_pass } #endif // STBI_NEON #define STBI__MARKER_none 0xff // if there's a pending marker from the entropy stream, return that // otherwise, fetch from the stream and get a marker. if there's no // marker, return 0xff, which is never a valid marker value static stbi_uc stbi__get_marker(stbi__jpeg *j) { stbi_uc x; if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } x = stbi__get8(j->s); if (x != 0xff) return STBI__MARKER_none; while (x == 0xff) x = stbi__get8(j->s); // consume repeated 0xff fill bytes return x; } // in each scan, we'll have scan_n components, and the order // of the components is specified by order[] #define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) // after a restart interval, stbi__jpeg_reset the entropy decoder and // the dc prediction static void stbi__jpeg_reset(stbi__jpeg *j) { j->code_bits = 0; j->code_buffer = 0; j->nomore = 0; j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; j->marker = STBI__MARKER_none; j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; j->eob_run = 0; // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, // since we don't even allow 1<<30 pixels } static int stbi__parse_entropy_coded_data(stbi__jpeg *z) { stbi__jpeg_reset(z); if (!z->progressive) { if (z->scan_n == 1) { int i,j; STBI_SIMD_ALIGN(short, data[64]); int n = z->order[0]; // non-interleaved data, we just need to process one block at a time, // in trivial scanline order // number of blocks to do just depends on how many actual "pixels" this // component has, independent of interleaved MCU blocking and such int w = (z->img_comp[n].x+7) >> 3; int h = (z->img_comp[n].y+7) >> 3; for (j=0; j < h; ++j) { for (i=0; i < w; ++i) { int ha = z->img_comp[n].ha; if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); // every data block is an MCU, so countdown the restart interval if (--z->todo <= 0) { if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); // if it's NOT a restart, then just bail, so we get corrupt data // rather than no data if (!STBI__RESTART(z->marker)) return 1; stbi__jpeg_reset(z); } } } return 1; } else { // interleaved int i,j,k,x,y; STBI_SIMD_ALIGN(short, data[64]); for (j=0; j < z->img_mcu_y; ++j) { for (i=0; i < z->img_mcu_x; ++i) { // scan an interleaved mcu... process scan_n components in order for (k=0; k < z->scan_n; ++k) { int n = z->order[k]; // scan out an mcu's worth of this component; that's just determined // by the basic H and V specified for the component for (y=0; y < z->img_comp[n].v; ++y) { for (x=0; x < z->img_comp[n].h; ++x) { int x2 = (i*z->img_comp[n].h + x)*8; int y2 = (j*z->img_comp[n].v + y)*8; int ha = z->img_comp[n].ha; if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data); } } } // after all interleaved components, that's an interleaved MCU, // so now count down the restart interval if (--z->todo <= 0) { if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); if (!STBI__RESTART(z->marker)) return 1; stbi__jpeg_reset(z); } } } return 1; } } else { if (z->scan_n == 1) { int i,j; int n = z->order[0]; // non-interleaved data, we just need to process one block at a time, // in trivial scanline order // number of blocks to do just depends on how many actual "pixels" this // component has, independent of interleaved MCU blocking and such int w = (z->img_comp[n].x+7) >> 3; int h = (z->img_comp[n].y+7) >> 3; for (j=0; j < h; ++j) { for (i=0; i < w; ++i) { short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); if (z->spec_start == 0) { if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) return 0; } else { int ha = z->img_comp[n].ha; if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) return 0; } // every data block is an MCU, so countdown the restart interval if (--z->todo <= 0) { if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); if (!STBI__RESTART(z->marker)) return 1; stbi__jpeg_reset(z); } } } return 1; } else { // interleaved int i,j,k,x,y; for (j=0; j < z->img_mcu_y; ++j) { for (i=0; i < z->img_mcu_x; ++i) { // scan an interleaved mcu... process scan_n components in order for (k=0; k < z->scan_n; ++k) { int n = z->order[k]; // scan out an mcu's worth of this component; that's just determined // by the basic H and V specified for the component for (y=0; y < z->img_comp[n].v; ++y) { for (x=0; x < z->img_comp[n].h; ++x) { int x2 = (i*z->img_comp[n].h + x); int y2 = (j*z->img_comp[n].v + y); short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) return 0; } } } // after all interleaved components, that's an interleaved MCU, // so now count down the restart interval if (--z->todo <= 0) { if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); if (!STBI__RESTART(z->marker)) return 1; stbi__jpeg_reset(z); } } } return 1; } } } static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant) { int i; for (i=0; i < 64; ++i) data[i] *= dequant[i]; } static void stbi__jpeg_finish(stbi__jpeg *z) { if (z->progressive) { // dequantize and idct the data int i,j,n; for (n=0; n < z->s->img_n; ++n) { int w = (z->img_comp[n].x+7) >> 3; int h = (z->img_comp[n].y+7) >> 3; for (j=0; j < h; ++j) { for (i=0; i < w; ++i) { short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); } } } } } static int stbi__process_marker(stbi__jpeg *z, int m) { int L; switch (m) { case STBI__MARKER_none: // no marker found return stbi__err("expected marker","Corrupt JPEG"); case 0xDD: // DRI - specify restart interval if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len","Corrupt JPEG"); z->restart_interval = stbi__get16be(z->s); return 1; case 0xDB: // DQT - define quantization table L = stbi__get16be(z->s)-2; while (L > 0) { int q = stbi__get8(z->s); int p = q >> 4, sixteen = (p != 0); int t = q & 15,i; if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG"); if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG"); for (i=0; i < 64; ++i) z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); L -= (sixteen ? 129 : 65); } return L==0; case 0xC4: // DHT - define huffman table L = stbi__get16be(z->s)-2; while (L > 0) { stbi_uc *v; int sizes[16],i,n=0; int q = stbi__get8(z->s); int tc = q >> 4; int th = q & 15; if (tc > 1 || th > 3) return stbi__err("bad DHT header","Corrupt JPEG"); for (i=0; i < 16; ++i) { sizes[i] = stbi__get8(z->s); n += sizes[i]; } if(n > 256) return stbi__err("bad DHT header","Corrupt JPEG"); // Loop over i < n would write past end of values! L -= 17; if (tc == 0) { if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0; v = z->huff_dc[th].values; } else { if (!stbi__build_huffman(z->huff_ac+th, sizes)) return 0; v = z->huff_ac[th].values; } for (i=0; i < n; ++i) v[i] = stbi__get8(z->s); if (tc != 0) stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); L -= n; } return L==0; } // check for comment block or APP blocks if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { L = stbi__get16be(z->s); if (L < 2) { if (m == 0xFE) return stbi__err("bad COM len","Corrupt JPEG"); else return stbi__err("bad APP len","Corrupt JPEG"); } L -= 2; if (m == 0xE0 && L >= 5) { // JFIF APP0 segment static const unsigned char tag[5] = {'J','F','I','F','\0'}; int ok = 1; int i; for (i=0; i < 5; ++i) if (stbi__get8(z->s) != tag[i]) ok = 0; L -= 5; if (ok) z->jfif = 1; } else if (m == 0xEE && L >= 12) { // Adobe APP14 segment static const unsigned char tag[6] = {'A','d','o','b','e','\0'}; int ok = 1; int i; for (i=0; i < 6; ++i) if (stbi__get8(z->s) != tag[i]) ok = 0; L -= 6; if (ok) { stbi__get8(z->s); // version stbi__get16be(z->s); // flags0 stbi__get16be(z->s); // flags1 z->app14_color_transform = stbi__get8(z->s); // color transform L -= 6; } } stbi__skip(z->s, L); return 1; } return stbi__err("unknown marker","Corrupt JPEG"); } // after we see SOS static int stbi__process_scan_header(stbi__jpeg *z) { int i; int Ls = stbi__get16be(z->s); z->scan_n = stbi__get8(z->s); if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return stbi__err("bad SOS component count","Corrupt JPEG"); if (Ls != 6+2*z->scan_n) return stbi__err("bad SOS len","Corrupt JPEG"); for (i=0; i < z->scan_n; ++i) { int id = stbi__get8(z->s), which; int q = stbi__get8(z->s); for (which = 0; which < z->s->img_n; ++which) if (z->img_comp[which].id == id) break; if (which == z->s->img_n) return 0; // no match z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff","Corrupt JPEG"); z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff","Corrupt JPEG"); z->order[i] = which; } { int aa; z->spec_start = stbi__get8(z->s); z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 aa = stbi__get8(z->s); z->succ_high = (aa >> 4); z->succ_low = (aa & 15); if (z->progressive) { if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) return stbi__err("bad SOS", "Corrupt JPEG"); } else { if (z->spec_start != 0) return stbi__err("bad SOS","Corrupt JPEG"); if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS","Corrupt JPEG"); z->spec_end = 63; } } return 1; } static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why) { int i; for (i=0; i < ncomp; ++i) { if (z->img_comp[i].raw_data) { STBI_FREE(z->img_comp[i].raw_data); z->img_comp[i].raw_data = NULL; z->img_comp[i].data = NULL; } if (z->img_comp[i].raw_coeff) { STBI_FREE(z->img_comp[i].raw_coeff); z->img_comp[i].raw_coeff = 0; z->img_comp[i].coeff = 0; } if (z->img_comp[i].linebuf) { STBI_FREE(z->img_comp[i].linebuf); z->img_comp[i].linebuf = NULL; } } return why; } static int stbi__process_frame_header(stbi__jpeg *z, int scan) { stbi__context *s = z->s; int Lf,p,i,q, h_max=1,v_max=1,c; Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len","Corrupt JPEG"); // JPEG p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); c = stbi__get8(s); if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG"); s->img_n = c; for (i=0; i < c; ++i) { z->img_comp[i].data = NULL; z->img_comp[i].linebuf = NULL; } if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG"); z->rgb = 0; for (i=0; i < s->img_n; ++i) { static const unsigned char rgb[3] = { 'R', 'G', 'B' }; z->img_comp[i].id = stbi__get8(s); if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) ++z->rgb; q = stbi__get8(s); z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG"); z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG"); z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ","Corrupt JPEG"); } if (scan != STBI__SCAN_load) return 1; if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); for (i=0; i < s->img_n; ++i) { if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; } // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios // and I've never seen a non-corrupted JPEG file actually use them for (i=0; i < s->img_n; ++i) { if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H","Corrupt JPEG"); if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V","Corrupt JPEG"); } // compute interleaved mcu info z->img_h_max = h_max; z->img_v_max = v_max; z->img_mcu_w = h_max * 8; z->img_mcu_h = v_max * 8; // these sizes can't be more than 17 bits z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; for (i=0; i < s->img_n; ++i) { // number of effective pixels (e.g. for non-interleaved MCU) z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; // to simplify generation, we'll allocate enough memory to decode // the bogus oversized data from using interleaved MCUs and their // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't // discard the extra data until colorspace conversion // // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) // so these muls can't overflow with 32-bit ints (which we require) z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; z->img_comp[i].coeff = 0; z->img_comp[i].raw_coeff = 0; z->img_comp[i].linebuf = NULL; z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); if (z->img_comp[i].raw_data == NULL) return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); // align blocks for idct using mmx/sse z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); if (z->progressive) { // w2, h2 are multiples of 8 (see above) z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); if (z->img_comp[i].raw_coeff == NULL) return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15); } } return 1; } // use comparisons since in some cases we handle more than one case (e.g. SOF) #define stbi__DNL(x) ((x) == 0xdc) #define stbi__SOI(x) ((x) == 0xd8) #define stbi__EOI(x) ((x) == 0xd9) #define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) #define stbi__SOS(x) ((x) == 0xda) #define stbi__SOF_progressive(x) ((x) == 0xc2) static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) { int m; z->jfif = 0; z->app14_color_transform = -1; // valid values are 0,1,2 z->marker = STBI__MARKER_none; // initialize cached marker to empty m = stbi__get_marker(z); if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG"); if (scan == STBI__SCAN_type) return 1; m = stbi__get_marker(z); while (!stbi__SOF(m)) { if (!stbi__process_marker(z,m)) return 0; m = stbi__get_marker(z); while (m == STBI__MARKER_none) { // some files have extra padding after their blocks, so ok, we'll scan if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); m = stbi__get_marker(z); } } z->progressive = stbi__SOF_progressive(m); if (!stbi__process_frame_header(z, scan)) return 0; return 1; } static stbi_uc stbi__skip_jpeg_junk_at_end(stbi__jpeg *j) { // some JPEGs have junk at end, skip over it but if we find what looks // like a valid marker, resume there while (!stbi__at_eof(j->s)) { stbi_uc x = stbi__get8(j->s); while (x == 0xff) { // might be a marker if (stbi__at_eof(j->s)) return STBI__MARKER_none; x = stbi__get8(j->s); if (x != 0x00 && x != 0xff) { // not a stuffed zero or lead-in to another marker, looks // like an actual marker, return it return x; } // stuffed zero has x=0 now which ends the loop, meaning we go // back to regular scan loop. // repeated 0xff keeps trying to read the next byte of the marker. } } return STBI__MARKER_none; } // decode image to YCbCr format static int stbi__decode_jpeg_image(stbi__jpeg *j) { int m; for (m = 0; m < 4; m++) { j->img_comp[m].raw_data = NULL; j->img_comp[m].raw_coeff = NULL; } j->restart_interval = 0; if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; m = stbi__get_marker(j); while (!stbi__EOI(m)) { if (stbi__SOS(m)) { if (!stbi__process_scan_header(j)) return 0; if (!stbi__parse_entropy_coded_data(j)) return 0; if (j->marker == STBI__MARKER_none ) { j->marker = stbi__skip_jpeg_junk_at_end(j); // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 } m = stbi__get_marker(j); if (STBI__RESTART(m)) m = stbi__get_marker(j); } else if (stbi__DNL(m)) { int Ld = stbi__get16be(j->s); stbi__uint32 NL = stbi__get16be(j->s); if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); m = stbi__get_marker(j); } else { if (!stbi__process_marker(j, m)) return 1; m = stbi__get_marker(j); } } if (j->progressive) stbi__jpeg_finish(j); return 1; } // static jfif-centered resampling (across block boundaries) typedef stbi_uc *(*resample_row_func)(stbi_uc *out, stbi_uc *in0, stbi_uc *in1, int w, int hs); #define stbi__div4(x) ((stbi_uc) ((x) >> 2)) static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) { STBI_NOTUSED(out); STBI_NOTUSED(in_far); STBI_NOTUSED(w); STBI_NOTUSED(hs); return in_near; } static stbi_uc* stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) { // need to generate two samples vertically for every one in input int i; STBI_NOTUSED(hs); for (i=0; i < w; ++i) out[i] = stbi__div4(3*in_near[i] + in_far[i] + 2); return out; } static stbi_uc* stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) { // need to generate two samples horizontally for every one in input int i; stbi_uc *input = in_near; if (w == 1) { // if only one sample, can't do any interpolation out[0] = out[1] = input[0]; return out; } out[0] = input[0]; out[1] = stbi__div4(input[0]*3 + input[1] + 2); for (i=1; i < w-1; ++i) { int n = 3*input[i]+2; out[i*2+0] = stbi__div4(n+input[i-1]); out[i*2+1] = stbi__div4(n+input[i+1]); } out[i*2+0] = stbi__div4(input[w-2]*3 + input[w-1] + 2); out[i*2+1] = input[w-1]; STBI_NOTUSED(in_far); STBI_NOTUSED(hs); return out; } #define stbi__div16(x) ((stbi_uc) ((x) >> 4)) static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) { // need to generate 2x2 samples for every one in input int i,t0,t1; if (w == 1) { out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); return out; } t1 = 3*in_near[0] + in_far[0]; out[0] = stbi__div4(t1+2); for (i=1; i < w; ++i) { t0 = t1; t1 = 3*in_near[i]+in_far[i]; out[i*2-1] = stbi__div16(3*t0 + t1 + 8); out[i*2 ] = stbi__div16(3*t1 + t0 + 8); } out[w*2-1] = stbi__div4(t1+2); STBI_NOTUSED(hs); return out; } #if defined(STBI_SSE2) || defined(STBI_NEON) static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) { // need to generate 2x2 samples for every one in input int i=0,t0,t1; if (w == 1) { out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); return out; } t1 = 3*in_near[0] + in_far[0]; // process groups of 8 pixels for as long as we can. // note we can't handle the last pixel in a row in this loop // because we need to handle the filter boundary conditions. for (; i < ((w-1) & ~7); i += 8) { #if defined(STBI_SSE2) // load and perform the vertical filtering pass // this uses 3*x + y = 4*x + (y - x) __m128i zero = _mm_setzero_si128(); __m128i farb = _mm_loadl_epi64((__m128i *) (in_far + i)); __m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i)); __m128i farw = _mm_unpacklo_epi8(farb, zero); __m128i nearw = _mm_unpacklo_epi8(nearb, zero); __m128i diff = _mm_sub_epi16(farw, nearw); __m128i nears = _mm_slli_epi16(nearw, 2); __m128i curr = _mm_add_epi16(nears, diff); // current row // horizontal filter works the same based on shifted vers of current // row. "prev" is current row shifted right by 1 pixel; we need to // insert the previous pixel value (from t1). // "next" is current row shifted left by 1 pixel, with first pixel // of next block of 8 pixels added in. __m128i prv0 = _mm_slli_si128(curr, 2); __m128i nxt0 = _mm_srli_si128(curr, 2); __m128i prev = _mm_insert_epi16(prv0, t1, 0); __m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7); // horizontal filter, polyphase implementation since it's convenient: // even pixels = 3*cur + prev = cur*4 + (prev - cur) // odd pixels = 3*cur + next = cur*4 + (next - cur) // note the shared term. __m128i bias = _mm_set1_epi16(8); __m128i curs = _mm_slli_epi16(curr, 2); __m128i prvd = _mm_sub_epi16(prev, curr); __m128i nxtd = _mm_sub_epi16(next, curr); __m128i curb = _mm_add_epi16(curs, bias); __m128i even = _mm_add_epi16(prvd, curb); __m128i odd = _mm_add_epi16(nxtd, curb); // interleave even and odd pixels, then undo scaling. __m128i int0 = _mm_unpacklo_epi16(even, odd); __m128i int1 = _mm_unpackhi_epi16(even, odd); __m128i de0 = _mm_srli_epi16(int0, 4); __m128i de1 = _mm_srli_epi16(int1, 4); // pack and write output __m128i outv = _mm_packus_epi16(de0, de1); _mm_storeu_si128((__m128i *) (out + i*2), outv); #elif defined(STBI_NEON) // load and perform the vertical filtering pass // this uses 3*x + y = 4*x + (y - x) uint8x8_t farb = vld1_u8(in_far + i); uint8x8_t nearb = vld1_u8(in_near + i); int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); int16x8_t curr = vaddq_s16(nears, diff); // current row // horizontal filter works the same based on shifted vers of current // row. "prev" is current row shifted right by 1 pixel; we need to // insert the previous pixel value (from t1). // "next" is current row shifted left by 1 pixel, with first pixel // of next block of 8 pixels added in. int16x8_t prv0 = vextq_s16(curr, curr, 7); int16x8_t nxt0 = vextq_s16(curr, curr, 1); int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7); // horizontal filter, polyphase implementation since it's convenient: // even pixels = 3*cur + prev = cur*4 + (prev - cur) // odd pixels = 3*cur + next = cur*4 + (next - cur) // note the shared term. int16x8_t curs = vshlq_n_s16(curr, 2); int16x8_t prvd = vsubq_s16(prev, curr); int16x8_t nxtd = vsubq_s16(next, curr); int16x8_t even = vaddq_s16(curs, prvd); int16x8_t odd = vaddq_s16(curs, nxtd); // undo scaling and round, then store with even/odd phases interleaved uint8x8x2_t o; o.val[0] = vqrshrun_n_s16(even, 4); o.val[1] = vqrshrun_n_s16(odd, 4); vst2_u8(out + i*2, o); #endif // "previous" value for next iter t1 = 3*in_near[i+7] + in_far[i+7]; } t0 = t1; t1 = 3*in_near[i] + in_far[i]; out[i*2] = stbi__div16(3*t1 + t0 + 8); for (++i; i < w; ++i) { t0 = t1; t1 = 3*in_near[i]+in_far[i]; out[i*2-1] = stbi__div16(3*t0 + t1 + 8); out[i*2 ] = stbi__div16(3*t1 + t0 + 8); } out[w*2-1] = stbi__div4(t1+2); STBI_NOTUSED(hs); return out; } #endif static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) { // resample with nearest-neighbor int i,j; STBI_NOTUSED(in_far); for (i=0; i < w; ++i) for (j=0; j < hs; ++j) out[i*hs+j] = in_near[i]; return out; } // this is a reduced-precision calculation of YCbCr-to-RGB introduced // to make sure the code produces the same results in both SIMD and scalar #define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) { int i; for (i=0; i < count; ++i) { int y_fixed = (y[i] << 20) + (1<<19); // rounding int r,g,b; int cr = pcr[i] - 128; int cb = pcb[i] - 128; r = y_fixed + cr* stbi__float2fixed(1.40200f); g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); b = y_fixed + cb* stbi__float2fixed(1.77200f); r >>= 20; g >>= 20; b >>= 20; if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } out[0] = (stbi_uc)r; out[1] = (stbi_uc)g; out[2] = (stbi_uc)b; out[3] = 255; out += step; } } #if defined(STBI_SSE2) || defined(STBI_NEON) static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step) { int i = 0; #ifdef STBI_SSE2 // step == 3 is pretty ugly on the final interleave, and i'm not convinced // it's useful in practice (you wouldn't use it for textures, for example). // so just accelerate step == 4 case. if (step == 4) { // this is a fairly straightforward implementation and not super-optimized. __m128i signflip = _mm_set1_epi8(-0x80); __m128i cr_const0 = _mm_set1_epi16( (short) ( 1.40200f*4096.0f+0.5f)); __m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f)); __m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f)); __m128i cb_const1 = _mm_set1_epi16( (short) ( 1.77200f*4096.0f+0.5f)); __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128); __m128i xw = _mm_set1_epi16(255); // alpha channel for (; i+7 < count; i += 8) { // load __m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i)); __m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i)); __m128i cb_bytes = _mm_loadl_epi64((__m128i *) (pcb+i)); __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 // unpack to short (and left-shift cr, cb by 8) __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); // color transform __m128i yws = _mm_srli_epi16(yw, 4); __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); __m128i rws = _mm_add_epi16(cr0, yws); __m128i gwt = _mm_add_epi16(cb0, yws); __m128i bws = _mm_add_epi16(yws, cb1); __m128i gws = _mm_add_epi16(gwt, cr1); // descale __m128i rw = _mm_srai_epi16(rws, 4); __m128i bw = _mm_srai_epi16(bws, 4); __m128i gw = _mm_srai_epi16(gws, 4); // back to byte, set up for transpose __m128i brb = _mm_packus_epi16(rw, bw); __m128i gxb = _mm_packus_epi16(gw, xw); // transpose to interleave channels __m128i t0 = _mm_unpacklo_epi8(brb, gxb); __m128i t1 = _mm_unpackhi_epi8(brb, gxb); __m128i o0 = _mm_unpacklo_epi16(t0, t1); __m128i o1 = _mm_unpackhi_epi16(t0, t1); // store _mm_storeu_si128((__m128i *) (out + 0), o0); _mm_storeu_si128((__m128i *) (out + 16), o1); out += 32; } } #endif #ifdef STBI_NEON // in this version, step=3 support would be easy to add. but is there demand? if (step == 4) { // this is a fairly straightforward implementation and not super-optimized. uint8x8_t signflip = vdup_n_u8(0x80); int16x8_t cr_const0 = vdupq_n_s16( (short) ( 1.40200f*4096.0f+0.5f)); int16x8_t cr_const1 = vdupq_n_s16( - (short) ( 0.71414f*4096.0f+0.5f)); int16x8_t cb_const0 = vdupq_n_s16( - (short) ( 0.34414f*4096.0f+0.5f)); int16x8_t cb_const1 = vdupq_n_s16( (short) ( 1.77200f*4096.0f+0.5f)); for (; i+7 < count; i += 8) { // load uint8x8_t y_bytes = vld1_u8(y + i); uint8x8_t cr_bytes = vld1_u8(pcr + i); uint8x8_t cb_bytes = vld1_u8(pcb + i); int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); // expand to s16 int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); int16x8_t crw = vshll_n_s8(cr_biased, 7); int16x8_t cbw = vshll_n_s8(cb_biased, 7); // color transform int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); int16x8_t rws = vaddq_s16(yws, cr0); int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); int16x8_t bws = vaddq_s16(yws, cb1); // undo scaling, round, convert to byte uint8x8x4_t o; o.val[0] = vqrshrun_n_s16(rws, 4); o.val[1] = vqrshrun_n_s16(gws, 4); o.val[2] = vqrshrun_n_s16(bws, 4); o.val[3] = vdup_n_u8(255); // store, interleaving r/g/b/a vst4_u8(out, o); out += 8*4; } } #endif for (; i < count; ++i) { int y_fixed = (y[i] << 20) + (1<<19); // rounding int r,g,b; int cr = pcr[i] - 128; int cb = pcb[i] - 128; r = y_fixed + cr* stbi__float2fixed(1.40200f); g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); b = y_fixed + cb* stbi__float2fixed(1.77200f); r >>= 20; g >>= 20; b >>= 20; if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } out[0] = (stbi_uc)r; out[1] = (stbi_uc)g; out[2] = (stbi_uc)b; out[3] = 255; out += step; } } #endif // set up the kernels static void stbi__setup_jpeg(stbi__jpeg *j) { j->idct_block_kernel = stbi__idct_block; j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; #ifdef STBI_SSE2 if (stbi__sse2_available()) { j->idct_block_kernel = stbi__idct_simd; j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; } #endif #ifdef STBI_NEON j->idct_block_kernel = stbi__idct_simd; j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; #endif } // clean up the temporary component buffers static void stbi__cleanup_jpeg(stbi__jpeg *j) { stbi__free_jpeg_components(j, j->s->img_n, 0); } typedef struct { resample_row_func resample; stbi_uc *line0,*line1; int hs,vs; // expansion factor in each axis int w_lores; // horizontal pixels pre-expansion int ystep; // how far through vertical expansion we are int ypos; // which pre-expansion row we're on } stbi__resample; // fast 0..255 * 0..255 => 0..255 rounded multiplication static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) { unsigned int t = x*y + 128; return (stbi_uc) ((t + (t >>8)) >> 8); } static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) { int n, decode_n, is_rgb; z->s->img_n = 0; // make stbi__cleanup_jpeg safe // validate req_comp if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); // load a jpeg image from whichever source, but leave in YCbCr format if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } // determine actual number of components to generate n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); if (z->s->img_n == 3 && n < 3 && !is_rgb) decode_n = 1; else decode_n = z->s->img_n; // nothing to do if no components requested; check this now to avoid // accessing uninitialized coutput[0] later if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } // resample and color-convert { int k; unsigned int i,j; stbi_uc *output; stbi_uc *coutput[4] = { NULL, NULL, NULL, NULL }; stbi__resample res_comp[4]; for (k=0; k < decode_n; ++k) { stbi__resample *r = &res_comp[k]; // allocate line buffer big enough for upsampling off the edges // with upsample factor of 4 z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3); if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } r->hs = z->img_h_max / z->img_comp[k].h; r->vs = z->img_v_max / z->img_comp[k].v; r->ystep = r->vs >> 1; r->w_lores = (z->s->img_x + r->hs-1) / r->hs; r->ypos = 0; r->line0 = r->line1 = z->img_comp[k].data; if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; else r->resample = stbi__resample_row_generic; } // can't error after this so, this is safe output = (stbi_uc *) stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } // now go ahead and resample for (j=0; j < z->s->img_y; ++j) { stbi_uc *out = output + n * z->s->img_x * j; for (k=0; k < decode_n; ++k) { stbi__resample *r = &res_comp[k]; int y_bot = r->ystep >= (r->vs >> 1); coutput[k] = r->resample(z->img_comp[k].linebuf, y_bot ? r->line1 : r->line0, y_bot ? r->line0 : r->line1, r->w_lores, r->hs); if (++r->ystep >= r->vs) { r->ystep = 0; r->line0 = r->line1; if (++r->ypos < z->img_comp[k].y) r->line1 += z->img_comp[k].w2; } } if (n >= 3) { stbi_uc *y = coutput[0]; if (z->s->img_n == 3) { if (is_rgb) { for (i=0; i < z->s->img_x; ++i) { out[0] = y[i]; out[1] = coutput[1][i]; out[2] = coutput[2][i]; out[3] = 255; out += n; } } else { z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); } } else if (z->s->img_n == 4) { if (z->app14_color_transform == 0) { // CMYK for (i=0; i < z->s->img_x; ++i) { stbi_uc m = coutput[3][i]; out[0] = stbi__blinn_8x8(coutput[0][i], m); out[1] = stbi__blinn_8x8(coutput[1][i], m); out[2] = stbi__blinn_8x8(coutput[2][i], m); out[3] = 255; out += n; } } else if (z->app14_color_transform == 2) { // YCCK z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); for (i=0; i < z->s->img_x; ++i) { stbi_uc m = coutput[3][i]; out[0] = stbi__blinn_8x8(255 - out[0], m); out[1] = stbi__blinn_8x8(255 - out[1], m); out[2] = stbi__blinn_8x8(255 - out[2], m); out += n; } } else { // YCbCr + alpha? Ignore the fourth channel for now z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); } } else for (i=0; i < z->s->img_x; ++i) { out[0] = out[1] = out[2] = y[i]; out[3] = 255; // not used if n==3 out += n; } } else { if (is_rgb) { if (n == 1) for (i=0; i < z->s->img_x; ++i) *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); else { for (i=0; i < z->s->img_x; ++i, out += 2) { out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); out[1] = 255; } } } else if (z->s->img_n == 4 && z->app14_color_transform == 0) { for (i=0; i < z->s->img_x; ++i) { stbi_uc m = coutput[3][i]; stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); out[0] = stbi__compute_y(r, g, b); out[1] = 255; out += n; } } else if (z->s->img_n == 4 && z->app14_color_transform == 2) { for (i=0; i < z->s->img_x; ++i) { out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); out[1] = 255; out += n; } } else { stbi_uc *y = coutput[0]; if (n == 1) for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; else for (i=0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } } } } stbi__cleanup_jpeg(z); *out_x = z->s->img_x; *out_y = z->s->img_y; if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output return output; } } static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { unsigned char* result; stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg)); if (!j) return stbi__errpuc("outofmem", "Out of memory"); memset(j, 0, sizeof(stbi__jpeg)); STBI_NOTUSED(ri); j->s = s; stbi__setup_jpeg(j); result = load_jpeg_image(j, x,y,comp,req_comp); STBI_FREE(j); return result; } static int stbi__jpeg_test(stbi__context *s) { int r; stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); if (!j) return stbi__err("outofmem", "Out of memory"); memset(j, 0, sizeof(stbi__jpeg)); j->s = s; stbi__setup_jpeg(j); r = stbi__decode_jpeg_header(j, STBI__SCAN_type); stbi__rewind(s); STBI_FREE(j); return r; } static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp) { if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { stbi__rewind( j->s ); return 0; } if (x) *x = j->s->img_x; if (y) *y = j->s->img_y; if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; return 1; } static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp) { int result; stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg))); if (!j) return stbi__err("outofmem", "Out of memory"); memset(j, 0, sizeof(stbi__jpeg)); j->s = s; result = stbi__jpeg_info_raw(j, x, y, comp); STBI_FREE(j); return result; } #endif // public domain zlib decode v0.2 Sean Barrett 2006-11-18 // simple implementation // - all input must be provided in an upfront buffer // - all output is written to a single output buffer (can malloc/realloc) // performance // - fast huffman #ifndef STBI_NO_ZLIB // fast-way is faster to check than jpeg huffman, but slow way is slower #define STBI__ZFAST_BITS 9 // accelerate all cases in default tables #define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) #define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet // zlib-style huffman encoding // (jpegs packs from left, zlib from right, so can't share code) typedef struct { stbi__uint16 fast[1 << STBI__ZFAST_BITS]; stbi__uint16 firstcode[16]; int maxcode[17]; stbi__uint16 firstsymbol[16]; stbi_uc size[STBI__ZNSYMS]; stbi__uint16 value[STBI__ZNSYMS]; } stbi__zhuffman; stbi_inline static int stbi__bitreverse16(int n) { n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); return n; } stbi_inline static int stbi__bit_reverse(int v, int bits) { STBI_ASSERT(bits <= 16); // to bit reverse n bits, reverse 16 and shift // e.g. 11 bits, bit reverse and shift away 5 return stbi__bitreverse16(v) >> (16-bits); } static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num) { int i,k=0; int code, next_code[16], sizes[17]; // DEFLATE spec for generating codes memset(sizes, 0, sizeof(sizes)); memset(z->fast, 0, sizeof(z->fast)); for (i=0; i < num; ++i) ++sizes[sizelist[i]]; sizes[0] = 0; for (i=1; i < 16; ++i) if (sizes[i] > (1 << i)) return stbi__err("bad sizes", "Corrupt PNG"); code = 0; for (i=1; i < 16; ++i) { next_code[i] = code; z->firstcode[i] = (stbi__uint16) code; z->firstsymbol[i] = (stbi__uint16) k; code = (code + sizes[i]); if (sizes[i]) if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG"); z->maxcode[i] = code << (16-i); // preshift for inner loop code <<= 1; k += sizes[i]; } z->maxcode[16] = 0x10000; // sentinel for (i=0; i < num; ++i) { int s = sizelist[i]; if (s) { int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; stbi__uint16 fastv = (stbi__uint16) ((s << 9) | i); z->size [c] = (stbi_uc ) s; z->value[c] = (stbi__uint16) i; if (s <= STBI__ZFAST_BITS) { int j = stbi__bit_reverse(next_code[s],s); while (j < (1 << STBI__ZFAST_BITS)) { z->fast[j] = fastv; j += (1 << s); } } ++next_code[s]; } } return 1; } // zlib-from-memory implementation for PNG reading // because PNG allows splitting the zlib stream arbitrarily, // and it's annoying structurally to have PNG call ZLIB call PNG, // we require PNG read all the IDATs and combine them into a single // memory buffer typedef struct { stbi_uc *zbuffer, *zbuffer_end; int num_bits; int hit_zeof_once; stbi__uint32 code_buffer; char *zout; char *zout_start; char *zout_end; int z_expandable; stbi__zhuffman z_length, z_distance; } stbi__zbuf; stbi_inline static int stbi__zeof(stbi__zbuf *z) { return (z->zbuffer >= z->zbuffer_end); } stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z) { return stbi__zeof(z) ? 0 : *z->zbuffer++; } static void stbi__fill_bits(stbi__zbuf *z) { do { if (z->code_buffer >= (1U << z->num_bits)) { z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ return; } z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits; z->num_bits += 8; } while (z->num_bits <= 24); } stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n) { unsigned int k; if (z->num_bits < n) stbi__fill_bits(z); k = z->code_buffer & ((1 << n) - 1); z->code_buffer >>= n; z->num_bits -= n; return k; } static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) { int b,s,k; // not resolved by fast table, so compute it the slow way // use jpeg approach, which requires MSbits at top k = stbi__bit_reverse(a->code_buffer, 16); for (s=STBI__ZFAST_BITS+1; ; ++s) if (k < z->maxcode[s]) break; if (s >= 16) return -1; // invalid code! // code size is s, so: b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. a->code_buffer >>= s; a->num_bits -= s; return z->value[b]; } stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) { int b,s; if (a->num_bits < 16) { if (stbi__zeof(a)) { if (!a->hit_zeof_once) { // This is the first time we hit eof, insert 16 extra padding btis // to allow us to keep going; if we actually consume any of them // though, that is invalid data. This is caught later. a->hit_zeof_once = 1; a->num_bits += 16; // add 16 implicit zero bits } else { // We already inserted our extra 16 padding bits and are again // out, this stream is actually prematurely terminated. return -1; } } else { stbi__fill_bits(a); } } b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; if (b) { s = b >> 9; a->code_buffer >>= s; a->num_bits -= s; return b & 511; } return stbi__zhuffman_decode_slowpath(a, z); } static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes { char *q; unsigned int cur, limit, old_limit; z->zout = zout; if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG"); cur = (unsigned int) (z->zout - z->zout_start); limit = old_limit = (unsigned) (z->zout_end - z->zout_start); if (UINT_MAX - cur < (unsigned) n) return stbi__err("outofmem", "Out of memory"); while (cur + n > limit) { if(limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); limit *= 2; } q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); STBI_NOTUSED(old_limit); if (q == NULL) return stbi__err("outofmem", "Out of memory"); z->zout_start = q; z->zout = q + cur; z->zout_end = q + limit; return 1; } static const int stbi__zlength_base[31] = { 3,4,5,6,7,8,9,10,11,13, 15,17,19,23,27,31,35,43,51,59, 67,83,99,115,131,163,195,227,258,0,0 }; static const int stbi__zlength_extra[31]= { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; static const int stbi__zdist_extra[32] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; static int stbi__parse_huffman_block(stbi__zbuf *a) { char *zout = a->zout; for(;;) { int z = stbi__zhuffman_decode(a, &a->z_length); if (z < 256) { if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); // error in huffman codes if (zout >= a->zout_end) { if (!stbi__zexpand(a, zout, 1)) return 0; zout = a->zout; } *zout++ = (char) z; } else { stbi_uc *p; int len,dist; if (z == 256) { a->zout = zout; if (a->hit_zeof_once && a->num_bits < 16) { // The first time we hit zeof, we inserted 16 extra zero bits into our bit // buffer so the decoder can just do its speculative decoding. But if we // actually consumed any of those bits (which is the case when num_bits < 16), // the stream actually read past the end so it is malformed. return stbi__err("unexpected end","Corrupt PNG"); } return 1; } if (z >= 286) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data z -= 257; len = stbi__zlength_base[z]; if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); z = stbi__zhuffman_decode(a, &a->z_distance); if (z < 0 || z >= 30) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data dist = stbi__zdist_base[z]; if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG"); if (len > a->zout_end - zout) { if (!stbi__zexpand(a, zout, len)) return 0; zout = a->zout; } p = (stbi_uc *) (zout - dist); if (dist == 1) { // run of one byte; common in images. stbi_uc v = *p; if (len) { do *zout++ = v; while (--len); } } else { if (len) { do *zout++ = *p++; while (--len); } } } } } static int stbi__compute_huffman_codes(stbi__zbuf *a) { static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; stbi__zhuffman z_codelength; stbi_uc lencodes[286+32+137];//padding for maximum single op stbi_uc codelength_sizes[19]; int i,n; int hlit = stbi__zreceive(a,5) + 257; int hdist = stbi__zreceive(a,5) + 1; int hclen = stbi__zreceive(a,4) + 4; int ntot = hlit + hdist; memset(codelength_sizes, 0, sizeof(codelength_sizes)); for (i=0; i < hclen; ++i) { int s = stbi__zreceive(a,3); codelength_sizes[length_dezigzag[i]] = (stbi_uc) s; } if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; n = 0; while (n < ntot) { int c = stbi__zhuffman_decode(a, &z_codelength); if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); if (c < 16) lencodes[n++] = (stbi_uc) c; else { stbi_uc fill = 0; if (c == 16) { c = stbi__zreceive(a,2)+3; if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); fill = lencodes[n-1]; } else if (c == 17) { c = stbi__zreceive(a,3)+3; } else if (c == 18) { c = stbi__zreceive(a,7)+11; } else { return stbi__err("bad codelengths", "Corrupt PNG"); } if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); memset(lencodes+n, fill, c); n += c; } } if (n != ntot) return stbi__err("bad codelengths","Corrupt PNG"); if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; return 1; } static int stbi__parse_uncompressed_block(stbi__zbuf *a) { stbi_uc header[4]; int len,nlen,k; if (a->num_bits & 7) stbi__zreceive(a, a->num_bits & 7); // discard // drain the bit-packed data into header k = 0; while (a->num_bits > 0) { header[k++] = (stbi_uc) (a->code_buffer & 255); // suppress MSVC run-time check a->code_buffer >>= 8; a->num_bits -= 8; } if (a->num_bits < 0) return stbi__err("zlib corrupt","Corrupt PNG"); // now fill header the normal way while (k < 4) header[k++] = stbi__zget8(a); len = header[1] * 256 + header[0]; nlen = header[3] * 256 + header[2]; if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt","Corrupt PNG"); if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer","Corrupt PNG"); if (a->zout + len > a->zout_end) if (!stbi__zexpand(a, a->zout, len)) return 0; memcpy(a->zout, a->zbuffer, len); a->zbuffer += len; a->zout += len; return 1; } static int stbi__parse_zlib_header(stbi__zbuf *a) { int cmf = stbi__zget8(a); int cm = cmf & 15; /* int cinfo = cmf >> 4; */ int flg = stbi__zget8(a); if (stbi__zeof(a)) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png // window = 1 << (8 + cinfo)... but who cares, we fully buffer output return 1; } static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] = { 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 }; static const stbi_uc stbi__zdefault_distance[32] = { 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 }; /* Init algorithm: { int i; // use <= to match clearly with spec for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; } */ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) { int final, type; if (parse_header) if (!stbi__parse_zlib_header(a)) return 0; a->num_bits = 0; a->code_buffer = 0; a->hit_zeof_once = 0; do { final = stbi__zreceive(a,1); type = stbi__zreceive(a,2); if (type == 0) { if (!stbi__parse_uncompressed_block(a)) return 0; } else if (type == 3) { return 0; } else { if (type == 1) { // use fixed code lengths if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , STBI__ZNSYMS)) return 0; if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; } else { if (!stbi__compute_huffman_codes(a)) return 0; } if (!stbi__parse_huffman_block(a)) return 0; } } while (!final); return 1; } static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse_header) { a->zout_start = obuf; a->zout = obuf; a->zout_end = obuf + olen; a->z_expandable = exp; return stbi__parse_zlib(a, parse_header); } STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) { stbi__zbuf a; char *p = (char *) stbi__malloc(initial_size); if (p == NULL) return NULL; a.zbuffer = (stbi_uc *) buffer; a.zbuffer_end = (stbi_uc *) buffer + len; if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { if (outlen) *outlen = (int) (a.zout - a.zout_start); return a.zout_start; } else { STBI_FREE(a.zout_start); return NULL; } } STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) { return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); } STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) { stbi__zbuf a; char *p = (char *) stbi__malloc(initial_size); if (p == NULL) return NULL; a.zbuffer = (stbi_uc *) buffer; a.zbuffer_end = (stbi_uc *) buffer + len; if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { if (outlen) *outlen = (int) (a.zout - a.zout_start); return a.zout_start; } else { STBI_FREE(a.zout_start); return NULL; } } STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) { stbi__zbuf a; a.zbuffer = (stbi_uc *) ibuffer; a.zbuffer_end = (stbi_uc *) ibuffer + ilen; if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) return (int) (a.zout - a.zout_start); else return -1; } STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) { stbi__zbuf a; char *p = (char *) stbi__malloc(16384); if (p == NULL) return NULL; a.zbuffer = (stbi_uc *) buffer; a.zbuffer_end = (stbi_uc *) buffer+len; if (stbi__do_zlib(&a, p, 16384, 1, 0)) { if (outlen) *outlen = (int) (a.zout - a.zout_start); return a.zout_start; } else { STBI_FREE(a.zout_start); return NULL; } } STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) { stbi__zbuf a; a.zbuffer = (stbi_uc *) ibuffer; a.zbuffer_end = (stbi_uc *) ibuffer + ilen; if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) return (int) (a.zout - a.zout_start); else return -1; } #endif // public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 // simple implementation // - only 8-bit samples // - no CRC checking // - allocates lots of intermediate memory // - avoids problem of streaming data between subsystems // - avoids explicit window management // performance // - uses stb_zlib, a PD zlib implementation with fast huffman decoding #ifndef STBI_NO_PNG typedef struct { stbi__uint32 length; stbi__uint32 type; } stbi__pngchunk; static stbi__pngchunk stbi__get_chunk_header(stbi__context *s) { stbi__pngchunk c; c.length = stbi__get32be(s); c.type = stbi__get32be(s); return c; } static int stbi__check_png_header(stbi__context *s) { static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; int i; for (i=0; i < 8; ++i) if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG"); return 1; } typedef struct { stbi__context *s; stbi_uc *idata, *expanded, *out; int depth; } stbi__png; enum { STBI__F_none=0, STBI__F_sub=1, STBI__F_up=2, STBI__F_avg=3, STBI__F_paeth=4, // synthetic filter used for first scanline to avoid needing a dummy row of 0s STBI__F_avg_first }; static stbi_uc first_row_filter[5] = { STBI__F_none, STBI__F_sub, STBI__F_none, STBI__F_avg_first, STBI__F_sub // Paeth with b=c=0 turns out to be equivalent to sub }; static int stbi__paeth(int a, int b, int c) { // This formulation looks very different from the reference in the PNG spec, but is // actually equivalent and has favorable data dependencies and admits straightforward // generation of branch-free code, which helps performance significantly. int thresh = c*3 - (a + b); int lo = a < b ? a : b; int hi = a < b ? b : a; int t0 = (hi <= thresh) ? lo : c; int t1 = (thresh <= lo) ? hi : t0; return t1; } static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; // adds an extra all-255 alpha channel // dest == src is legal // img_n must be 1 or 3 static void stbi__create_png_alpha_expand8(stbi_uc *dest, stbi_uc *src, stbi__uint32 x, int img_n) { int i; // must process data backwards since we allow dest==src if (img_n == 1) { for (i=x-1; i >= 0; --i) { dest[i*2+1] = 255; dest[i*2+0] = src[i]; } } else { STBI_ASSERT(img_n == 3); for (i=x-1; i >= 0; --i) { dest[i*4+3] = 255; dest[i*4+2] = src[i*3+2]; dest[i*4+1] = src[i*3+1]; dest[i*4+0] = src[i*3+0]; } } } // create the png data from post-deflated data static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) { int bytes = (depth == 16 ? 2 : 1); stbi__context *s = a->s; stbi__uint32 i,j,stride = x*out_n*bytes; stbi__uint32 img_len, img_width_bytes; stbi_uc *filter_buf; int all_ok = 1; int k; int img_n = s->img_n; // copy it into a local for later int output_bytes = out_n*bytes; int filter_bytes = img_n*bytes; int width = x; STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1); a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into if (!a->out) return stbi__err("outofmem", "Out of memory"); // note: error exits here don't need to clean up a->out individually, // stbi__do_png always does on error. if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); img_width_bytes = (((img_n * x * depth) + 7) >> 3); if (!stbi__mad2sizes_valid(img_width_bytes, y, img_width_bytes)) return stbi__err("too large", "Corrupt PNG"); img_len = (img_width_bytes + 1) * y; // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), // so just check for raw_len < img_len always. if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG"); // Allocate two scan lines worth of filter workspace buffer. filter_buf = (stbi_uc *) stbi__malloc_mad2(img_width_bytes, 2, 0); if (!filter_buf) return stbi__err("outofmem", "Out of memory"); // Filtering for low-bit-depth images if (depth < 8) { filter_bytes = 1; width = img_width_bytes; } for (j=0; j < y; ++j) { // cur/prior filter buffers alternate stbi_uc *cur = filter_buf + (j & 1)*img_width_bytes; stbi_uc *prior = filter_buf + (~j & 1)*img_width_bytes; stbi_uc *dest = a->out + stride*j; int nk = width * filter_bytes; int filter = *raw++; // check filter type if (filter > 4) { all_ok = stbi__err("invalid filter","Corrupt PNG"); break; } // if first row, use special filter that doesn't sample previous row if (j == 0) filter = first_row_filter[filter]; // perform actual filtering switch (filter) { case STBI__F_none: memcpy(cur, raw, nk); break; case STBI__F_sub: memcpy(cur, raw, filter_bytes); for (k = filter_bytes; k < nk; ++k) cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); break; case STBI__F_up: for (k = 0; k < nk; ++k) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; case STBI__F_avg: for (k = 0; k < filter_bytes; ++k) cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); for (k = filter_bytes; k < nk; ++k) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); break; case STBI__F_paeth: for (k = 0; k < filter_bytes; ++k) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); // prior[k] == stbi__paeth(0,prior[k],0) for (k = filter_bytes; k < nk; ++k) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes], prior[k], prior[k-filter_bytes])); break; case STBI__F_avg_first: memcpy(cur, raw, filter_bytes); for (k = filter_bytes; k < nk; ++k) cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); break; } raw += nk; // expand decoded bits in cur to dest, also adding an extra alpha channel if desired if (depth < 8) { stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range stbi_uc *in = cur; stbi_uc *out = dest; stbi_uc inb = 0; stbi__uint32 nsmp = x*img_n; // expand bits to bytes first if (depth == 4) { for (i=0; i < nsmp; ++i) { if ((i & 1) == 0) inb = *in++; *out++ = scale * (inb >> 4); inb <<= 4; } } else if (depth == 2) { for (i=0; i < nsmp; ++i) { if ((i & 3) == 0) inb = *in++; *out++ = scale * (inb >> 6); inb <<= 2; } } else { STBI_ASSERT(depth == 1); for (i=0; i < nsmp; ++i) { if ((i & 7) == 0) inb = *in++; *out++ = scale * (inb >> 7); inb <<= 1; } } // insert alpha=255 values if desired if (img_n != out_n) stbi__create_png_alpha_expand8(dest, dest, x, img_n); } else if (depth == 8) { if (img_n == out_n) memcpy(dest, cur, x*img_n); else stbi__create_png_alpha_expand8(dest, cur, x, img_n); } else if (depth == 16) { // convert the image data from big-endian to platform-native stbi__uint16 *dest16 = (stbi__uint16*)dest; stbi__uint32 nsmp = x*img_n; if (img_n == out_n) { for (i = 0; i < nsmp; ++i, ++dest16, cur += 2) *dest16 = (cur[0] << 8) | cur[1]; } else { STBI_ASSERT(img_n+1 == out_n); if (img_n == 1) { for (i = 0; i < x; ++i, dest16 += 2, cur += 2) { dest16[0] = (cur[0] << 8) | cur[1]; dest16[1] = 0xffff; } } else { STBI_ASSERT(img_n == 3); for (i = 0; i < x; ++i, dest16 += 4, cur += 6) { dest16[0] = (cur[0] << 8) | cur[1]; dest16[1] = (cur[2] << 8) | cur[3]; dest16[2] = (cur[4] << 8) | cur[5]; dest16[3] = 0xffff; } } } } } STBI_FREE(filter_buf); if (!all_ok) return 0; return 1; } static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) { int bytes = (depth == 16 ? 2 : 1); int out_bytes = out_n * bytes; stbi_uc *final; int p; if (!interlaced) return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); // de-interlacing final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); if (!final) return stbi__err("outofmem", "Out of memory"); for (p=0; p < 7; ++p) { int xorig[] = { 0,4,0,2,0,1,0 }; int yorig[] = { 0,0,4,0,2,0,1 }; int xspc[] = { 8,8,4,4,2,2,1 }; int yspc[] = { 8,8,8,4,4,2,2 }; int i,j,x,y; // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p]; y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p]; if (x && y) { stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { STBI_FREE(final); return 0; } for (j=0; j < y; ++j) { for (i=0; i < x; ++i) { int out_y = j*yspc[p]+yorig[p]; int out_x = i*xspc[p]+xorig[p]; memcpy(final + out_y*a->s->img_x*out_bytes + out_x*out_bytes, a->out + (j*x+i)*out_bytes, out_bytes); } } STBI_FREE(a->out); image_data += img_len; image_data_len -= img_len; } } a->out = final; return 1; } static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n) { stbi__context *s = z->s; stbi__uint32 i, pixel_count = s->img_x * s->img_y; stbi_uc *p = z->out; // compute color-based transparency, assuming we've // already got 255 as the alpha value in the output STBI_ASSERT(out_n == 2 || out_n == 4); if (out_n == 2) { for (i=0; i < pixel_count; ++i) { p[1] = (p[0] == tc[0] ? 0 : 255); p += 2; } } else { for (i=0; i < pixel_count; ++i) { if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) p[3] = 0; p += 4; } } return 1; } static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n) { stbi__context *s = z->s; stbi__uint32 i, pixel_count = s->img_x * s->img_y; stbi__uint16 *p = (stbi__uint16*) z->out; // compute color-based transparency, assuming we've // already got 65535 as the alpha value in the output STBI_ASSERT(out_n == 2 || out_n == 4); if (out_n == 2) { for (i = 0; i < pixel_count; ++i) { p[1] = (p[0] == tc[0] ? 0 : 65535); p += 2; } } else { for (i = 0; i < pixel_count; ++i) { if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) p[3] = 0; p += 4; } } return 1; } static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n) { stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; stbi_uc *p, *temp_out, *orig = a->out; p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0); if (p == NULL) return stbi__err("outofmem", "Out of memory"); // between here and free(out) below, exitting would leak temp_out = p; if (pal_img_n == 3) { for (i=0; i < pixel_count; ++i) { int n = orig[i]*4; p[0] = palette[n ]; p[1] = palette[n+1]; p[2] = palette[n+2]; p += 3; } } else { for (i=0; i < pixel_count; ++i) { int n = orig[i]*4; p[0] = palette[n ]; p[1] = palette[n+1]; p[2] = palette[n+2]; p[3] = palette[n+3]; p += 4; } } STBI_FREE(a->out); a->out = temp_out; STBI_NOTUSED(len); return 1; } static int stbi__unpremultiply_on_load_global = 0; static int stbi__de_iphone_flag_global = 0; STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) { stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply; } STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) { stbi__de_iphone_flag_global = flag_true_if_should_convert; } #ifndef STBI_THREAD_LOCAL #define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global #define stbi__de_iphone_flag stbi__de_iphone_flag_global #else static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set; static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set; STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply) { stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply; stbi__unpremultiply_on_load_set = 1; } STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert) { stbi__de_iphone_flag_local = flag_true_if_should_convert; stbi__de_iphone_flag_set = 1; } #define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ ? stbi__unpremultiply_on_load_local \ : stbi__unpremultiply_on_load_global) #define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ ? stbi__de_iphone_flag_local \ : stbi__de_iphone_flag_global) #endif // STBI_THREAD_LOCAL static void stbi__de_iphone(stbi__png *z) { stbi__context *s = z->s; stbi__uint32 i, pixel_count = s->img_x * s->img_y; stbi_uc *p = z->out; if (s->img_out_n == 3) { // convert bgr to rgb for (i=0; i < pixel_count; ++i) { stbi_uc t = p[0]; p[0] = p[2]; p[2] = t; p += 3; } } else { STBI_ASSERT(s->img_out_n == 4); if (stbi__unpremultiply_on_load) { // convert bgr to rgb and unpremultiply for (i=0; i < pixel_count; ++i) { stbi_uc a = p[3]; stbi_uc t = p[0]; if (a) { stbi_uc half = a / 2; p[0] = (p[2] * 255 + half) / a; p[1] = (p[1] * 255 + half) / a; p[2] = ( t * 255 + half) / a; } else { p[0] = p[2]; p[2] = t; } p += 4; } } else { // convert bgr to rgb for (i=0; i < pixel_count; ++i) { stbi_uc t = p[0]; p[0] = p[2]; p[2] = t; p += 4; } } } } #define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) { stbi_uc palette[1024]={0}, pal_img_n=0; stbi_uc has_trans=0, tc[3]={0}; stbi__uint16 tc16[3]={0}; stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0; int first=1,k,interlace=0, color=0, is_iphone=0; stbi__context *s = z->s; z->expanded = NULL; z->idata = NULL; z->out = NULL; if (!stbi__check_png_header(s)) return 0; if (scan == STBI__SCAN_type) return 1; for (;;) { stbi__pngchunk c = stbi__get_chunk_header(s); switch (c.type) { case STBI__PNG_TYPE('C','g','B','I'): is_iphone = 1; stbi__skip(s, c.length); break; case STBI__PNG_TYPE('I','H','D','R'): { int comp,filter; if (!first) return stbi__err("multiple IHDR","Corrupt PNG"); first = 0; if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG"); s->img_x = stbi__get32be(s); s->img_y = stbi__get32be(s); if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only"); color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG"); if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG"); comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG"); filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG"); interlace = stbi__get8(s); if (interlace>1) return stbi__err("bad interlace method","Corrupt PNG"); if (!s->img_x || !s->img_y) return stbi__err("0-pixel image","Corrupt PNG"); if (!pal_img_n) { s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); } else { // if paletted, then pal_n is our final components, and // img_n is # components to decompress/filter. s->img_n = 1; if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG"); } // even with SCAN_header, have to scan to see if we have a tRNS break; } case STBI__PNG_TYPE('P','L','T','E'): { if (first) return stbi__err("first not IHDR", "Corrupt PNG"); if (c.length > 256*3) return stbi__err("invalid PLTE","Corrupt PNG"); pal_len = c.length / 3; if (pal_len * 3 != c.length) return stbi__err("invalid PLTE","Corrupt PNG"); for (i=0; i < pal_len; ++i) { palette[i*4+0] = stbi__get8(s); palette[i*4+1] = stbi__get8(s); palette[i*4+2] = stbi__get8(s); palette[i*4+3] = 255; } break; } case STBI__PNG_TYPE('t','R','N','S'): { if (first) return stbi__err("first not IHDR", "Corrupt PNG"); if (z->idata) return stbi__err("tRNS after IDAT","Corrupt PNG"); if (pal_img_n) { if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } if (pal_len == 0) return stbi__err("tRNS before PLTE","Corrupt PNG"); if (c.length > pal_len) return stbi__err("bad tRNS len","Corrupt PNG"); pal_img_n = 4; for (i=0; i < c.length; ++i) palette[i*4+3] = stbi__get8(s); } else { if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG"); if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG"); has_trans = 1; // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. if (scan == STBI__SCAN_header) { ++s->img_n; return 1; } if (z->depth == 16) { for (k = 0; k < s->img_n && k < 3; ++k) // extra loop test to suppress false GCC warning tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is } else { for (k = 0; k < s->img_n && k < 3; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger } } break; } case STBI__PNG_TYPE('I','D','A','T'): { if (first) return stbi__err("first not IHDR", "Corrupt PNG"); if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG"); if (scan == STBI__SCAN_header) { // header scan definitely stops at first IDAT if (pal_img_n) s->img_n = pal_img_n; return 1; } if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes"); if ((int)(ioff + c.length) < (int)ioff) return 0; if (ioff + c.length > idata_limit) { stbi__uint32 idata_limit_old = idata_limit; stbi_uc *p; if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; while (ioff + c.length > idata_limit) idata_limit *= 2; STBI_NOTUSED(idata_limit_old); p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); z->idata = p; } if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG"); ioff += c.length; break; } case STBI__PNG_TYPE('I','E','N','D'): { stbi__uint32 raw_len, bpl; if (first) return stbi__err("first not IHDR", "Corrupt PNG"); if (scan != STBI__SCAN_load) return 1; if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG"); // initial guess for decoded data size to avoid unnecessary reallocs bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone); if (z->expanded == NULL) return 0; // zlib should set error STBI_FREE(z->idata); z->idata = NULL; if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) s->img_out_n = s->img_n+1; else s->img_out_n = s->img_n; if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; if (has_trans) { if (z->depth == 16) { if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; } else { if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; } } if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) stbi__de_iphone(z); if (pal_img_n) { // pal_img_n == 3 or 4 s->img_n = pal_img_n; // record the actual colors we had s->img_out_n = pal_img_n; if (req_comp >= 3) s->img_out_n = req_comp; if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) return 0; } else if (has_trans) { // non-paletted image with tRNS -> source image has (constant) alpha ++s->img_n; } STBI_FREE(z->expanded); z->expanded = NULL; // end of PNG chunk, read and skip CRC stbi__get32be(s); if (s->io.skip && s->img_buffer_end > s->img_buffer) { // rewind the additional bytes that have been read to the buffer (s->io.skip)(s->io_user_data, (int)(s->img_buffer - s->img_buffer_end)); } return 1; } default: // if critical, fail if (first) return stbi__err("first not IHDR", "Corrupt PNG"); if ((c.type & (1 << 29)) == 0) { #ifndef STBI_NO_FAILURE_STRINGS // not threadsafe static char invalid_chunk[] = "XXXX PNG chunk not known"; invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); #endif return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); } stbi__skip(s, c.length); break; } // end of PNG chunk, read and skip CRC stbi__get32be(s); } } static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri) { void *result=NULL; if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { if (p->depth <= 8) ri->bits_per_channel = 8; else if (p->depth == 16) ri->bits_per_channel = 16; else return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); result = p->out; p->out = NULL; if (req_comp && req_comp != p->s->img_out_n) { if (ri->bits_per_channel == 8) result = stbi__convert_format((unsigned char *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); else result = stbi__convert_format16((stbi__uint16 *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); p->s->img_out_n = req_comp; if (result == NULL) return result; } *x = p->s->img_x; *y = p->s->img_y; if (n) *n = p->s->img_n; } STBI_FREE(p->out); p->out = NULL; STBI_FREE(p->expanded); p->expanded = NULL; STBI_FREE(p->idata); p->idata = NULL; return result; } static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { stbi__png p; p.s = s; return stbi__do_png(&p, x,y,comp,req_comp, ri); } static int stbi__png_test(stbi__context *s) { int r; r = stbi__check_png_header(s); stbi__rewind(s); return r; } static int stbi__png_info_raw(stbi__png *p, int *x, int *y, int *comp) { if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { stbi__rewind( p->s ); return 0; } if (x) *x = p->s->img_x; if (y) *y = p->s->img_y; if (comp) *comp = p->s->img_n; return 1; } static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp) { stbi__png p; p.s = s; return stbi__png_info_raw(&p, x, y, comp); } static int stbi__png_is16(stbi__context *s) { stbi__png p; p.s = s; if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) return 0; if (p.depth != 16) { stbi__rewind(p.s); return 0; } return 1; } #endif // Microsoft/Windows BMP image #ifndef STBI_NO_BMP static int stbi__bmp_test_raw(stbi__context *s) { int r; int sz; if (stbi__get8(s) != 'B') return 0; if (stbi__get8(s) != 'M') return 0; stbi__get32le(s); // discard filesize stbi__get16le(s); // discard reserved stbi__get16le(s); // discard reserved stbi__get32le(s); // discard data offset sz = stbi__get32le(s); r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); return r; } static int stbi__bmp_test(stbi__context *s) { int r = stbi__bmp_test_raw(s); stbi__rewind(s); return r; } // returns 0..31 for the highest set bit static int stbi__high_bit(unsigned int z) { int n=0; if (z == 0) return -1; if (z >= 0x10000) { n += 16; z >>= 16; } if (z >= 0x00100) { n += 8; z >>= 8; } if (z >= 0x00010) { n += 4; z >>= 4; } if (z >= 0x00004) { n += 2; z >>= 2; } if (z >= 0x00002) { n += 1;/* >>= 1;*/ } return n; } static int stbi__bitcount(unsigned int a) { a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits a = (a + (a >> 8)); // max 16 per 8 bits a = (a + (a >> 16)); // max 32 per 8 bits return a & 0xff; } // extract an arbitrarily-aligned N-bit value (N=bits) // from v, and then make it 8-bits long and fractionally // extend it to full full range. static int stbi__shiftsigned(unsigned int v, int shift, int bits) { static unsigned int mul_table[9] = { 0, 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, }; static unsigned int shift_table[9] = { 0, 0,0,1,0,2,4,6,0, }; if (shift < 0) v <<= -shift; else v >>= shift; STBI_ASSERT(v < 256); v >>= (8-bits); STBI_ASSERT(bits >= 0 && bits <= 8); return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits]; } typedef struct { int bpp, offset, hsz; unsigned int mr,mg,mb,ma, all_a; int extra_read; } stbi__bmp_data; static int stbi__bmp_set_mask_defaults(stbi__bmp_data *info, int compress) { // BI_BITFIELDS specifies masks explicitly, don't override if (compress == 3) return 1; if (compress == 0) { if (info->bpp == 16) { info->mr = 31u << 10; info->mg = 31u << 5; info->mb = 31u << 0; } else if (info->bpp == 32) { info->mr = 0xffu << 16; info->mg = 0xffu << 8; info->mb = 0xffu << 0; info->ma = 0xffu << 24; info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 } else { // otherwise, use defaults, which is all-0 info->mr = info->mg = info->mb = info->ma = 0; } return 1; } return 0; // error } static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) { int hsz; if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); stbi__get32le(s); // discard filesize stbi__get16le(s); // discard reserved stbi__get16le(s); // discard reserved info->offset = stbi__get32le(s); info->hsz = hsz = stbi__get32le(s); info->mr = info->mg = info->mb = info->ma = 0; info->extra_read = 14; if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); if (hsz == 12) { s->img_x = stbi__get16le(s); s->img_y = stbi__get16le(s); } else { s->img_x = stbi__get32le(s); s->img_y = stbi__get32le(s); } if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); info->bpp = stbi__get16le(s); if (hsz != 12) { int compress = stbi__get32le(s); if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel stbi__get32le(s); // discard sizeof stbi__get32le(s); // discard hres stbi__get32le(s); // discard vres stbi__get32le(s); // discard colorsused stbi__get32le(s); // discard max important if (hsz == 40 || hsz == 56) { if (hsz == 56) { stbi__get32le(s); stbi__get32le(s); stbi__get32le(s); stbi__get32le(s); } if (info->bpp == 16 || info->bpp == 32) { if (compress == 0) { stbi__bmp_set_mask_defaults(info, compress); } else if (compress == 3) { info->mr = stbi__get32le(s); info->mg = stbi__get32le(s); info->mb = stbi__get32le(s); info->extra_read += 12; // not documented, but generated by photoshop and handled by mspaint if (info->mr == info->mg && info->mg == info->mb) { // ?!?!? return stbi__errpuc("bad BMP", "bad BMP"); } } else return stbi__errpuc("bad BMP", "bad BMP"); } } else { // V4/V5 header int i; if (hsz != 108 && hsz != 124) return stbi__errpuc("bad BMP", "bad BMP"); info->mr = stbi__get32le(s); info->mg = stbi__get32le(s); info->mb = stbi__get32le(s); info->ma = stbi__get32le(s); if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs stbi__bmp_set_mask_defaults(info, compress); stbi__get32le(s); // discard color space for (i=0; i < 12; ++i) stbi__get32le(s); // discard color space parameters if (hsz == 124) { stbi__get32le(s); // discard rendering intent stbi__get32le(s); // discard offset of profile data stbi__get32le(s); // discard size of profile data stbi__get32le(s); // discard reserved } } } return (void *) 1; } static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { stbi_uc *out; unsigned int mr=0,mg=0,mb=0,ma=0, all_a; stbi_uc pal[256][4]; int psize=0,i,j,width; int flip_vertically, pad, target; stbi__bmp_data info; STBI_NOTUSED(ri); info.all_a = 255; if (stbi__bmp_parse_header(s, &info) == NULL) return NULL; // error code already set flip_vertically = ((int) s->img_y) > 0; s->img_y = abs((int) s->img_y); if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); mr = info.mr; mg = info.mg; mb = info.mb; ma = info.ma; all_a = info.all_a; if (info.hsz == 12) { if (info.bpp < 24) psize = (info.offset - info.extra_read - info.hsz) / 3; } else { if (info.bpp < 16) psize = (info.offset - info.extra_read - info.hsz) >> 2; } if (psize == 0) { // accept some number of extra bytes after the header, but if the offset points either to before // the header ends or implies a large amount of extra data, reject the file as malformed int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original); int header_limit = 1024; // max we actually read is below 256 bytes currently. int extra_data_limit = 256*4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) { return stbi__errpuc("bad header", "Corrupt BMP"); } // we established that bytes_read_so_far is positive and sensible. // the first half of this test rejects offsets that are either too small positives, or // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn // ensures the number computed in the second half of the test can't overflow. if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) { return stbi__errpuc("bad offset", "Corrupt BMP"); } else { stbi__skip(s, info.offset - bytes_read_so_far); } } if (info.bpp == 24 && ma == 0xff000000) s->img_n = 3; else s->img_n = ma ? 4 : 3; if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 target = req_comp; else target = s->img_n; // if they want monochrome, we'll post-convert // sanity-check size if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) return stbi__errpuc("too large", "Corrupt BMP"); out = (stbi_uc *) stbi__malloc_mad3(target, s->img_x, s->img_y, 0); if (!out) return stbi__errpuc("outofmem", "Out of memory"); if (info.bpp < 16) { int z=0; if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } for (i=0; i < psize; ++i) { pal[i][2] = stbi__get8(s); pal[i][1] = stbi__get8(s); pal[i][0] = stbi__get8(s); if (info.hsz != 12) stbi__get8(s); pal[i][3] = 255; } stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); if (info.bpp == 1) width = (s->img_x + 7) >> 3; else if (info.bpp == 4) width = (s->img_x + 1) >> 1; else if (info.bpp == 8) width = s->img_x; else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } pad = (-width)&3; if (info.bpp == 1) { for (j=0; j < (int) s->img_y; ++j) { int bit_offset = 7, v = stbi__get8(s); for (i=0; i < (int) s->img_x; ++i) { int color = (v>>bit_offset)&0x1; out[z++] = pal[color][0]; out[z++] = pal[color][1]; out[z++] = pal[color][2]; if (target == 4) out[z++] = 255; if (i+1 == (int) s->img_x) break; if((--bit_offset) < 0) { bit_offset = 7; v = stbi__get8(s); } } stbi__skip(s, pad); } } else { for (j=0; j < (int) s->img_y; ++j) { for (i=0; i < (int) s->img_x; i += 2) { int v=stbi__get8(s),v2=0; if (info.bpp == 4) { v2 = v & 15; v >>= 4; } out[z++] = pal[v][0]; out[z++] = pal[v][1]; out[z++] = pal[v][2]; if (target == 4) out[z++] = 255; if (i+1 == (int) s->img_x) break; v = (info.bpp == 8) ? stbi__get8(s) : v2; out[z++] = pal[v][0]; out[z++] = pal[v][1]; out[z++] = pal[v][2]; if (target == 4) out[z++] = 255; } stbi__skip(s, pad); } } } else { int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; int z = 0; int easy=0; stbi__skip(s, info.offset - info.extra_read - info.hsz); if (info.bpp == 24) width = 3 * s->img_x; else if (info.bpp == 16) width = 2*s->img_x; else /* bpp = 32 and pad = 0 */ width=0; pad = (-width) & 3; if (info.bpp == 24) { easy = 1; } else if (info.bpp == 32) { if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) easy = 2; } if (!easy) { if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } // right shift amt to put high bit in position #7 rshift = stbi__high_bit(mr)-7; rcount = stbi__bitcount(mr); gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg); bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb); ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma); if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } } for (j=0; j < (int) s->img_y; ++j) { if (easy) { for (i=0; i < (int) s->img_x; ++i) { unsigned char a; out[z+2] = stbi__get8(s); out[z+1] = stbi__get8(s); out[z+0] = stbi__get8(s); z += 3; a = (easy == 2 ? stbi__get8(s) : 255); all_a |= a; if (target == 4) out[z++] = a; } } else { int bpp = info.bpp; for (i=0; i < (int) s->img_x; ++i) { stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s)); unsigned int a; out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); all_a |= a; if (target == 4) out[z++] = STBI__BYTECAST(a); } } stbi__skip(s, pad); } } // if alpha channel is all 0s, replace with all 255s if (target == 4 && all_a == 0) for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4) out[i] = 255; if (flip_vertically) { stbi_uc t; for (j=0; j < (int) s->img_y>>1; ++j) { stbi_uc *p1 = out + j *s->img_x*target; stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; for (i=0; i < (int) s->img_x*target; ++i) { t = p1[i]; p1[i] = p2[i]; p2[i] = t; } } } if (req_comp && req_comp != target) { out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); if (out == NULL) return out; // stbi__convert_format frees input on failure } *x = s->img_x; *y = s->img_y; if (comp) *comp = s->img_n; return out; } #endif // Targa Truevision - TGA // by Jonathan Dummer #ifndef STBI_NO_TGA // returns STBI_rgb or whatever, 0 on error static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) { // only RGB or RGBA (incl. 16bit) or grey allowed if (is_rgb16) *is_rgb16 = 0; switch(bits_per_pixel) { case 8: return STBI_grey; case 16: if(is_grey) return STBI_grey_alpha; STBI_FALLTHROUGH; case 15: if(is_rgb16) *is_rgb16 = 1; return STBI_rgb; case 24: // fallthrough case 32: return bits_per_pixel/8; default: return 0; } } static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) { int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; int sz, tga_colormap_type; stbi__get8(s); // discard Offset tga_colormap_type = stbi__get8(s); // colormap type if( tga_colormap_type > 1 ) { stbi__rewind(s); return 0; // only RGB or indexed allowed } tga_image_type = stbi__get8(s); // image type if ( tga_colormap_type == 1 ) { // colormapped (paletted) image if (tga_image_type != 1 && tga_image_type != 9) { stbi__rewind(s); return 0; } stbi__skip(s,4); // skip index of first colormap entry and number of entries sz = stbi__get8(s); // check bits per palette color entry if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) { stbi__rewind(s); return 0; } stbi__skip(s,4); // skip image x and y origin tga_colormap_bpp = sz; } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) { stbi__rewind(s); return 0; // only RGB or grey allowed, +/- RLE } stbi__skip(s,9); // skip colormap specification and image x/y origin tga_colormap_bpp = 0; } tga_w = stbi__get16le(s); if( tga_w < 1 ) { stbi__rewind(s); return 0; // test width } tga_h = stbi__get16le(s); if( tga_h < 1 ) { stbi__rewind(s); return 0; // test height } tga_bits_per_pixel = stbi__get8(s); // bits per pixel stbi__get8(s); // ignore alpha bits if (tga_colormap_bpp != 0) { if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { // when using a colormap, tga_bits_per_pixel is the size of the indexes // I don't think anything but 8 or 16bit indexes makes sense stbi__rewind(s); return 0; } tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); } else { tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); } if(!tga_comp) { stbi__rewind(s); return 0; } if (x) *x = tga_w; if (y) *y = tga_h; if (comp) *comp = tga_comp; return 1; // seems to have passed everything } static int stbi__tga_test(stbi__context *s) { int res = 0; int sz, tga_color_type; stbi__get8(s); // discard Offset tga_color_type = stbi__get8(s); // color type if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed sz = stbi__get8(s); // image type if ( tga_color_type == 1 ) { // colormapped (paletted) image if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 stbi__skip(s,4); // skip index of first colormap entry and number of entries sz = stbi__get8(s); // check bits per palette color entry if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; stbi__skip(s,4); // skip image x and y origin } else { // "normal" image w/o colormap if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE stbi__skip(s,9); // skip colormap specification and image x/y origin } if ( stbi__get16le(s) < 1 ) goto errorEnd; // test width if ( stbi__get16le(s) < 1 ) goto errorEnd; // test height sz = stbi__get8(s); // bits per pixel if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; res = 1; // if we got this far, everything's good and we can return 1 instead of 0 errorEnd: stbi__rewind(s); return res; } // read 16bit value and convert to 24bit RGB static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) { stbi__uint16 px = (stbi__uint16)stbi__get16le(s); stbi__uint16 fiveBitMask = 31; // we have 3 channels with 5bits each int r = (px >> 10) & fiveBitMask; int g = (px >> 5) & fiveBitMask; int b = px & fiveBitMask; // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later out[0] = (stbi_uc)((r * 255)/31); out[1] = (stbi_uc)((g * 255)/31); out[2] = (stbi_uc)((b * 255)/31); // some people claim that the most significant bit might be used for alpha // (possibly if an alpha-bit is set in the "image descriptor byte") // but that only made 16bit test images completely translucent.. // so let's treat all 15 and 16bit TGAs as RGB with no alpha. } static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { // read in the TGA header stuff int tga_offset = stbi__get8(s); int tga_indexed = stbi__get8(s); int tga_image_type = stbi__get8(s); int tga_is_RLE = 0; int tga_palette_start = stbi__get16le(s); int tga_palette_len = stbi__get16le(s); int tga_palette_bits = stbi__get8(s); int tga_x_origin = stbi__get16le(s); int tga_y_origin = stbi__get16le(s); int tga_width = stbi__get16le(s); int tga_height = stbi__get16le(s); int tga_bits_per_pixel = stbi__get8(s); int tga_comp, tga_rgb16=0; int tga_inverted = stbi__get8(s); // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) // image data unsigned char *tga_data; unsigned char *tga_palette = NULL; int i, j; unsigned char raw_data[4] = {0}; int RLE_count = 0; int RLE_repeating = 0; int read_next_pixel = 1; STBI_NOTUSED(ri); STBI_NOTUSED(tga_x_origin); // @TODO STBI_NOTUSED(tga_y_origin); // @TODO if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); // do a tiny bit of precessing if ( tga_image_type >= 8 ) { tga_image_type -= 8; tga_is_RLE = 1; } tga_inverted = 1 - ((tga_inverted >> 5) & 1); // If I'm paletted, then I'll use the number of bits from the palette if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); // tga info *x = tga_width; *y = tga_height; if (comp) *comp = tga_comp; if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) return stbi__errpuc("too large", "Corrupt TGA"); tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); // skip to the data's starting position (offset usually = 0) stbi__skip(s, tga_offset ); if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) { for (i=0; i < tga_height; ++i) { int row = tga_inverted ? tga_height -i - 1 : i; stbi_uc *tga_row = tga_data + row*tga_width*tga_comp; if(!stbi__getn(s, tga_row, tga_width * tga_comp)) { STBI_FREE(tga_data); return stbi__errpuc("bad palette", "Corrupt TGA"); } } } else { // do I need to load a palette? if ( tga_indexed) { if (tga_palette_len == 0) { /* you have to have at least one entry! */ STBI_FREE(tga_data); return stbi__errpuc("bad palette", "Corrupt TGA"); } // any data to skip? (offset usually = 0) stbi__skip(s, tga_palette_start ); // load the palette tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); if (!tga_palette) { STBI_FREE(tga_data); return stbi__errpuc("outofmem", "Out of memory"); } if (tga_rgb16) { stbi_uc *pal_entry = tga_palette; STBI_ASSERT(tga_comp == STBI_rgb); for (i=0; i < tga_palette_len; ++i) { stbi__tga_read_rgb16(s, pal_entry); pal_entry += tga_comp; } } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { STBI_FREE(tga_data); STBI_FREE(tga_palette); return stbi__errpuc("bad palette", "Corrupt TGA"); } } // load the data for (i=0; i < tga_width * tga_height; ++i) { // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? if ( tga_is_RLE ) { if ( RLE_count == 0 ) { // yep, get the next byte as a RLE command int RLE_cmd = stbi__get8(s); RLE_count = 1 + (RLE_cmd & 127); RLE_repeating = RLE_cmd >> 7; read_next_pixel = 1; } else if ( !RLE_repeating ) { read_next_pixel = 1; } } else { read_next_pixel = 1; } // OK, if I need to read a pixel, do it now if ( read_next_pixel ) { // load however much data we did have if ( tga_indexed ) { // read in index, then perform the lookup int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); if ( pal_idx >= tga_palette_len ) { // invalid index pal_idx = 0; } pal_idx *= tga_comp; for (j = 0; j < tga_comp; ++j) { raw_data[j] = tga_palette[pal_idx+j]; } } else if(tga_rgb16) { STBI_ASSERT(tga_comp == STBI_rgb); stbi__tga_read_rgb16(s, raw_data); } else { // read in the data raw for (j = 0; j < tga_comp; ++j) { raw_data[j] = stbi__get8(s); } } // clear the reading flag for the next pixel read_next_pixel = 0; } // end of reading a pixel // copy data for (j = 0; j < tga_comp; ++j) tga_data[i*tga_comp+j] = raw_data[j]; // in case we're in RLE mode, keep counting down --RLE_count; } // do I need to invert the image? if ( tga_inverted ) { for (j = 0; j*2 < tga_height; ++j) { int index1 = j * tga_width * tga_comp; int index2 = (tga_height - 1 - j) * tga_width * tga_comp; for (i = tga_width * tga_comp; i > 0; --i) { unsigned char temp = tga_data[index1]; tga_data[index1] = tga_data[index2]; tga_data[index2] = temp; ++index1; ++index2; } } } // clear my palette, if I had one if ( tga_palette != NULL ) { STBI_FREE( tga_palette ); } } // swap RGB - if the source data was RGB16, it already is in the right order if (tga_comp >= 3 && !tga_rgb16) { unsigned char* tga_pixel = tga_data; for (i=0; i < tga_width * tga_height; ++i) { unsigned char temp = tga_pixel[0]; tga_pixel[0] = tga_pixel[2]; tga_pixel[2] = temp; tga_pixel += tga_comp; } } // convert to target component count if (req_comp && req_comp != tga_comp) tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); // the things I do to get rid of an error message, and yet keep // Microsoft's C compilers happy... [8^( tga_palette_start = tga_palette_len = tga_palette_bits = tga_x_origin = tga_y_origin = 0; STBI_NOTUSED(tga_palette_start); // OK, done return tga_data; } #endif // ************************************************************************************************* // Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB #ifndef STBI_NO_PSD static int stbi__psd_test(stbi__context *s) { int r = (stbi__get32be(s) == 0x38425053); stbi__rewind(s); return r; } static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount) { int count, nleft, len; count = 0; while ((nleft = pixelCount - count) > 0) { len = stbi__get8(s); if (len == 128) { // No-op. } else if (len < 128) { // Copy next len+1 bytes literally. len++; if (len > nleft) return 0; // corrupt data count += len; while (len) { *p = stbi__get8(s); p += 4; len--; } } else if (len > 128) { stbi_uc val; // Next -len+1 bytes in the dest are replicated from next source byte. // (Interpret len as a negative 8-bit int.) len = 257 - len; if (len > nleft) return 0; // corrupt data val = stbi__get8(s); count += len; while (len) { *p = val; p += 4; len--; } } } return 1; } static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) { int pixelCount; int channelCount, compression; int channel, i; int bitdepth; int w,h; stbi_uc *out; STBI_NOTUSED(ri); // Check identifier if (stbi__get32be(s) != 0x38425053) // "8BPS" return stbi__errpuc("not PSD", "Corrupt PSD image"); // Check file type version. if (stbi__get16be(s) != 1) return stbi__errpuc("wrong version", "Unsupported version of PSD image"); // Skip 6 reserved bytes. stbi__skip(s, 6 ); // Read the number of channels (R, G, B, A, etc). channelCount = stbi__get16be(s); if (channelCount < 0 || channelCount > 16) return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); // Read the rows and columns of the image. h = stbi__get32be(s); w = stbi__get32be(s); if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); // Make sure the depth is 8 bits. bitdepth = stbi__get16be(s); if (bitdepth != 8 && bitdepth != 16) return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); // Make sure the color mode is RGB. // Valid options are: // 0: Bitmap // 1: Grayscale // 2: Indexed color // 3: RGB color // 4: CMYK color // 7: Multichannel // 8: Duotone // 9: Lab color if (stbi__get16be(s) != 3) return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) stbi__skip(s,stbi__get32be(s) ); // Skip the image resources. (resolution, pen tool paths, etc) stbi__skip(s, stbi__get32be(s) ); // Skip the reserved data. stbi__skip(s, stbi__get32be(s) ); // Find out if the data is compressed. // Known values: // 0: no compression // 1: RLE compressed compression = stbi__get16be(s); if (compression > 1) return stbi__errpuc("bad compression", "PSD has an unknown compression format"); // Check size if (!stbi__mad3sizes_valid(4, w, h, 0)) return stbi__errpuc("too large", "Corrupt PSD"); // Create the destination image. if (!compression && bitdepth == 16 && bpc == 16) { out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0); ri->bits_per_channel = 16; } else out = (stbi_uc *) stbi__malloc(4 * w*h); if (!out) return stbi__errpuc("outofmem", "Out of memory"); pixelCount = w*h; // Initialize the data to zero. //memset( out, 0, pixelCount * 4 ); // Finally, the image data. if (compression) { // RLE as used by .PSD and .TIFF // Loop until you get the number of unpacked bytes you are expecting: // Read the next source byte into n. // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. // Else if n is 128, noop. // Endloop // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, // which we're going to just skip. stbi__skip(s, h * channelCount * 2 ); // Read the RLE data by channel. for (channel = 0; channel < 4; channel++) { stbi_uc *p; p = out+channel; if (channel >= channelCount) { // Fill this channel with default data. for (i = 0; i < pixelCount; i++, p += 4) *p = (channel == 3 ? 255 : 0); } else { // Read the RLE data. if (!stbi__psd_decode_rle(s, p, pixelCount)) { STBI_FREE(out); return stbi__errpuc("corrupt", "bad RLE data"); } } } } else { // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. // Read the data by channel. for (channel = 0; channel < 4; channel++) { if (channel >= channelCount) { // Fill this channel with default data. if (bitdepth == 16 && bpc == 16) { stbi__uint16 *q = ((stbi__uint16 *) out) + channel; stbi__uint16 val = channel == 3 ? 65535 : 0; for (i = 0; i < pixelCount; i++, q += 4) *q = val; } else { stbi_uc *p = out+channel; stbi_uc val = channel == 3 ? 255 : 0; for (i = 0; i < pixelCount; i++, p += 4) *p = val; } } else { if (ri->bits_per_channel == 16) { // output bpc stbi__uint16 *q = ((stbi__uint16 *) out) + channel; for (i = 0; i < pixelCount; i++, q += 4) *q = (stbi__uint16) stbi__get16be(s); } else { stbi_uc *p = out+channel; if (bitdepth == 16) { // input bpc for (i = 0; i < pixelCount; i++, p += 4) *p = (stbi_uc) (stbi__get16be(s) >> 8); } else { for (i = 0; i < pixelCount; i++, p += 4) *p = stbi__get8(s); } } } } } // remove weird white matte from PSD if (channelCount >= 4) { if (ri->bits_per_channel == 16) { for (i=0; i < w*h; ++i) { stbi__uint16 *pixel = (stbi__uint16 *) out + 4*i; if (pixel[3] != 0 && pixel[3] != 65535) { float a = pixel[3] / 65535.0f; float ra = 1.0f / a; float inv_a = 65535.0f * (1 - ra); pixel[0] = (stbi__uint16) (pixel[0]*ra + inv_a); pixel[1] = (stbi__uint16) (pixel[1]*ra + inv_a); pixel[2] = (stbi__uint16) (pixel[2]*ra + inv_a); } } } else { for (i=0; i < w*h; ++i) { unsigned char *pixel = out + 4*i; if (pixel[3] != 0 && pixel[3] != 255) { float a = pixel[3] / 255.0f; float ra = 1.0f / a; float inv_a = 255.0f * (1 - ra); pixel[0] = (unsigned char) (pixel[0]*ra + inv_a); pixel[1] = (unsigned char) (pixel[1]*ra + inv_a); pixel[2] = (unsigned char) (pixel[2]*ra + inv_a); } } } } // convert to desired output format if (req_comp && req_comp != 4) { if (ri->bits_per_channel == 16) out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, 4, req_comp, w, h); else out = stbi__convert_format(out, 4, req_comp, w, h); if (out == NULL) return out; // stbi__convert_format frees input on failure } if (comp) *comp = 4; *y = h; *x = w; return out; } #endif // ************************************************************************************************* // Softimage PIC loader // by Tom Seddon // // See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format // See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ #ifndef STBI_NO_PIC static int stbi__pic_is4(stbi__context *s,const char *str) { int i; for (i=0; i<4; ++i) if (stbi__get8(s) != (stbi_uc)str[i]) return 0; return 1; } static int stbi__pic_test_core(stbi__context *s) { int i; if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) return 0; for(i=0;i<84;++i) stbi__get8(s); if (!stbi__pic_is4(s,"PICT")) return 0; return 1; } typedef struct { stbi_uc size,type,channel; } stbi__pic_packet; static stbi_uc *stbi__readval(stbi__context *s, int channel, stbi_uc *dest) { int mask=0x80, i; for (i=0; i<4; ++i, mask>>=1) { if (channel & mask) { if (stbi__at_eof(s)) return stbi__errpuc("bad file","PIC file too short"); dest[i]=stbi__get8(s); } } return dest; } static void stbi__copyval(int channel,stbi_uc *dest,const stbi_uc *src) { int mask=0x80,i; for (i=0;i<4; ++i, mask>>=1) if (channel&mask) dest[i]=src[i]; } static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *comp, stbi_uc *result) { int act_comp=0,num_packets=0,y,chained; stbi__pic_packet packets[10]; // this will (should...) cater for even some bizarre stuff like having data // for the same channel in multiple packets. do { stbi__pic_packet *packet; if (num_packets==sizeof(packets)/sizeof(packets[0])) return stbi__errpuc("bad format","too many packets"); packet = &packets[num_packets++]; chained = stbi__get8(s); packet->size = stbi__get8(s); packet->type = stbi__get8(s); packet->channel = stbi__get8(s); act_comp |= packet->channel; if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (reading packets)"); if (packet->size != 8) return stbi__errpuc("bad format","packet isn't 8bpp"); } while (chained); *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? for(y=0; ytype) { default: return stbi__errpuc("bad format","packet has bad compression type"); case 0: {//uncompressed int x; for(x=0;xchannel,dest)) return 0; break; } case 1://Pure RLE { int left=width, i; while (left>0) { stbi_uc count,value[4]; count=stbi__get8(s); if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pure read count)"); if (count > left) count = (stbi_uc) left; if (!stbi__readval(s,packet->channel,value)) return 0; for(i=0; ichannel,dest,value); left -= count; } } break; case 2: {//Mixed RLE int left=width; while (left>0) { int count = stbi__get8(s), i; if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (mixed read count)"); if (count >= 128) { // Repeated stbi_uc value[4]; if (count==128) count = stbi__get16be(s); else count -= 127; if (count > left) return stbi__errpuc("bad file","scanline overrun"); if (!stbi__readval(s,packet->channel,value)) return 0; for(i=0;ichannel,dest,value); } else { // Raw ++count; if (count>left) return stbi__errpuc("bad file","scanline overrun"); for(i=0;ichannel,dest)) return 0; } left-=count; } break; } } } } return result; } static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri) { stbi_uc *result; int i, x,y, internal_comp; STBI_NOTUSED(ri); if (!comp) comp = &internal_comp; for (i=0; i<92; ++i) stbi__get8(s); x = stbi__get16be(s); y = stbi__get16be(s); if (y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); if (x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)"); if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); stbi__get32be(s); //skip `ratio' stbi__get16be(s); //skip `fields' stbi__get16be(s); //skip `pad' // intermediate buffer is RGBA result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0); if (!result) return stbi__errpuc("outofmem", "Out of memory"); memset(result, 0xff, x*y*4); if (!stbi__pic_load_core(s,x,y,comp, result)) { STBI_FREE(result); return 0; } *px = x; *py = y; if (req_comp == 0) req_comp = *comp; result=stbi__convert_format(result,4,req_comp,x,y); return result; } static int stbi__pic_test(stbi__context *s) { int r = stbi__pic_test_core(s); stbi__rewind(s); return r; } #endif // ************************************************************************************************* // GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb #ifndef STBI_NO_GIF typedef struct { stbi__int16 prefix; stbi_uc first; stbi_uc suffix; } stbi__gif_lzw; typedef struct { int w,h; stbi_uc *out; // output buffer (always 4 components) stbi_uc *background; // The current "background" as far as a gif is concerned stbi_uc *history; int flags, bgindex, ratio, transparent, eflags; stbi_uc pal[256][4]; stbi_uc lpal[256][4]; stbi__gif_lzw codes[8192]; stbi_uc *color_table; int parse, step; int lflags; int start_x, start_y; int max_x, max_y; int cur_x, cur_y; int line_size; int delay; } stbi__gif; static int stbi__gif_test_raw(stbi__context *s) { int sz; if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; sz = stbi__get8(s); if (sz != '9' && sz != '7') return 0; if (stbi__get8(s) != 'a') return 0; return 1; } static int stbi__gif_test(stbi__context *s) { int r = stbi__gif_test_raw(s); stbi__rewind(s); return r; } static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], int num_entries, int transp) { int i; for (i=0; i < num_entries; ++i) { pal[i][2] = stbi__get8(s); pal[i][1] = stbi__get8(s); pal[i][0] = stbi__get8(s); pal[i][3] = transp == i ? 0 : 255; } } static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info) { stbi_uc version; if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return stbi__err("not GIF", "Corrupt GIF"); version = stbi__get8(s); if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); stbi__g_failure_reason = ""; g->w = stbi__get16le(s); g->h = stbi__get16le(s); g->flags = stbi__get8(s); g->bgindex = stbi__get8(s); g->ratio = stbi__get8(s); g->transparent = -1; if (g->w > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); if (g->h > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments if (is_info) return 1; if (g->flags & 0x80) stbi__gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1); return 1; } static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp) { stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); if (!g) return stbi__err("outofmem", "Out of memory"); if (!stbi__gif_header(s, g, comp, 1)) { STBI_FREE(g); stbi__rewind( s ); return 0; } if (x) *x = g->w; if (y) *y = g->h; STBI_FREE(g); return 1; } static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code) { stbi_uc *p, *c; int idx; // recurse to decode the prefixes, since the linked-list is backwards, // and working backwards through an interleaved image would be nasty if (g->codes[code].prefix >= 0) stbi__out_gif_code(g, g->codes[code].prefix); if (g->cur_y >= g->max_y) return; idx = g->cur_x + g->cur_y; p = &g->out[idx]; g->history[idx / 4] = 1; c = &g->color_table[g->codes[code].suffix * 4]; if (c[3] > 128) { // don't render transparent pixels; p[0] = c[2]; p[1] = c[1]; p[2] = c[0]; p[3] = c[3]; } g->cur_x += 4; if (g->cur_x >= g->max_x) { g->cur_x = g->start_x; g->cur_y += g->step; while (g->cur_y >= g->max_y && g->parse > 0) { g->step = (1 << g->parse) * g->line_size; g->cur_y = g->start_y + (g->step >> 1); --g->parse; } } } static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) { stbi_uc lzw_cs; stbi__int32 len, init_code; stbi__uint32 first; stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; stbi__gif_lzw *p; lzw_cs = stbi__get8(s); if (lzw_cs > 12) return NULL; clear = 1 << lzw_cs; first = 1; codesize = lzw_cs + 1; codemask = (1 << codesize) - 1; bits = 0; valid_bits = 0; for (init_code = 0; init_code < clear; init_code++) { g->codes[init_code].prefix = -1; g->codes[init_code].first = (stbi_uc) init_code; g->codes[init_code].suffix = (stbi_uc) init_code; } // support no starting clear code avail = clear+2; oldcode = -1; len = 0; for(;;) { if (valid_bits < codesize) { if (len == 0) { len = stbi__get8(s); // start new block if (len == 0) return g->out; } --len; bits |= (stbi__int32) stbi__get8(s) << valid_bits; valid_bits += 8; } else { stbi__int32 code = bits & codemask; bits >>= codesize; valid_bits -= codesize; // @OPTIMIZE: is there some way we can accelerate the non-clear path? if (code == clear) { // clear code codesize = lzw_cs + 1; codemask = (1 << codesize) - 1; avail = clear + 2; oldcode = -1; first = 0; } else if (code == clear + 1) { // end of stream code stbi__skip(s, len); while ((len = stbi__get8(s)) > 0) stbi__skip(s,len); return g->out; } else if (code <= avail) { if (first) { return stbi__errpuc("no clear code", "Corrupt GIF"); } if (oldcode >= 0) { p = &g->codes[avail++]; if (avail > 8192) { return stbi__errpuc("too many codes", "Corrupt GIF"); } p->prefix = (stbi__int16) oldcode; p->first = g->codes[oldcode].first; p->suffix = (code == avail) ? p->first : g->codes[code].first; } else if (code == avail) return stbi__errpuc("illegal code in raster", "Corrupt GIF"); stbi__out_gif_code(g, (stbi__uint16) code); if ((avail & codemask) == 0 && avail <= 0x0FFF) { codesize++; codemask = (1 << codesize) - 1; } oldcode = code; } else { return stbi__errpuc("illegal code in raster", "Corrupt GIF"); } } } } // this function is designed to support animated gifs, although stb_image doesn't support it // two back is the image from two frames ago, used for a very specific disposal format static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp, stbi_uc *two_back) { int dispose; int first_frame; int pi; int pcount; STBI_NOTUSED(req_comp); // on first frame, any non-written pixels get the background colour (non-transparent) first_frame = 0; if (g->out == 0) { if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header if (!stbi__mad3sizes_valid(4, g->w, g->h, 0)) return stbi__errpuc("too large", "GIF image is too large"); pcount = g->w * g->h; g->out = (stbi_uc *) stbi__malloc(4 * pcount); g->background = (stbi_uc *) stbi__malloc(4 * pcount); g->history = (stbi_uc *) stbi__malloc(pcount); if (!g->out || !g->background || !g->history) return stbi__errpuc("outofmem", "Out of memory"); // image is treated as "transparent" at the start - ie, nothing overwrites the current background; // background colour is only used for pixels that are not rendered first frame, after that "background" // color refers to the color that was there the previous frame. memset(g->out, 0x00, 4 * pcount); memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent) memset(g->history, 0x00, pcount); // pixels that were affected previous frame first_frame = 1; } else { // second frame - how do we dispose of the previous one? dispose = (g->eflags & 0x1C) >> 2; pcount = g->w * g->h; if ((dispose == 3) && (two_back == 0)) { dispose = 2; // if I don't have an image to revert back to, default to the old background } if (dispose == 3) { // use previous graphic for (pi = 0; pi < pcount; ++pi) { if (g->history[pi]) { memcpy( &g->out[pi * 4], &two_back[pi * 4], 4 ); } } } else if (dispose == 2) { // restore what was changed last frame to background before that frame; for (pi = 0; pi < pcount; ++pi) { if (g->history[pi]) { memcpy( &g->out[pi * 4], &g->background[pi * 4], 4 ); } } } else { // This is a non-disposal case eithe way, so just // leave the pixels as is, and they will become the new background // 1: do not dispose // 0: not specified. } // background is what out is after the undoing of the previou frame; memcpy( g->background, g->out, 4 * g->w * g->h ); } // clear my history; memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame for (;;) { int tag = stbi__get8(s); switch (tag) { case 0x2C: /* Image Descriptor */ { stbi__int32 x, y, w, h; stbi_uc *o; x = stbi__get16le(s); y = stbi__get16le(s); w = stbi__get16le(s); h = stbi__get16le(s); if (((x + w) > (g->w)) || ((y + h) > (g->h))) return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); g->line_size = g->w * 4; g->start_x = x * 4; g->start_y = y * g->line_size; g->max_x = g->start_x + w * 4; g->max_y = g->start_y + h * g->line_size; g->cur_x = g->start_x; g->cur_y = g->start_y; // if the width of the specified rectangle is 0, that means // we may not see *any* pixels or the image is malformed; // to make sure this is caught, move the current y down to // max_y (which is what out_gif_code checks). if (w == 0) g->cur_y = g->max_y; g->lflags = stbi__get8(s); if (g->lflags & 0x40) { g->step = 8 * g->line_size; // first interlaced spacing g->parse = 3; } else { g->step = g->line_size; g->parse = 0; } if (g->lflags & 0x80) { stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); g->color_table = (stbi_uc *) g->lpal; } else if (g->flags & 0x80) { g->color_table = (stbi_uc *) g->pal; } else return stbi__errpuc("missing color table", "Corrupt GIF"); o = stbi__process_gif_raster(s, g); if (!o) return NULL; // if this was the first frame, pcount = g->w * g->h; if (first_frame && (g->bgindex > 0)) { // if first frame, any pixel not drawn to gets the background color for (pi = 0; pi < pcount; ++pi) { if (g->history[pi] == 0) { g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be; memcpy( &g->out[pi * 4], &g->pal[g->bgindex], 4 ); } } } return o; } case 0x21: // Comment Extension. { int len; int ext = stbi__get8(s); if (ext == 0xF9) { // Graphic Control Extension. len = stbi__get8(s); if (len == 4) { g->eflags = stbi__get8(s); g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths. // unset old transparent if (g->transparent >= 0) { g->pal[g->transparent][3] = 255; } if (g->eflags & 0x01) { g->transparent = stbi__get8(s); if (g->transparent >= 0) { g->pal[g->transparent][3] = 0; } } else { // don't need transparent stbi__skip(s, 1); g->transparent = -1; } } else { stbi__skip(s, len); break; } } while ((len = stbi__get8(s)) != 0) { stbi__skip(s, len); } break; } case 0x3B: // gif stream termination code return (stbi_uc *) s; // using '1' causes warning on some compilers default: return stbi__errpuc("unknown code", "Corrupt GIF"); } } } static void *stbi__load_gif_main_outofmem(stbi__gif *g, stbi_uc *out, int **delays) { STBI_FREE(g->out); STBI_FREE(g->history); STBI_FREE(g->background); if (out) STBI_FREE(out); if (delays && *delays) { STBI_FREE(*delays); *delays = NULL; } return stbi__errpuc("outofmem", "Out of memory"); } static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp) { if (stbi__gif_test(s)) { int layers = 0; stbi_uc *u = 0; stbi_uc *out = 0; stbi_uc *two_back = 0; stbi__gif g; int stride; int out_size = 0; int delays_size = 0; STBI_NOTUSED(out_size); STBI_NOTUSED(delays_size); memset(&g, 0, sizeof(g)); if (delays) { *delays = 0; } do { u = stbi__gif_load_next(s, &g, comp, req_comp, two_back); if (u == (stbi_uc *) s) u = 0; // end of animated gif marker if (u) { *x = g.w; *y = g.h; ++layers; stride = g.w * g.h * 4; if (out) { if (stride == 0) return stbi__load_gif_main_outofmem(&g, out, delays); if (!stbi__mul2sizes_valid(layers, stride)) return stbi__load_gif_main_outofmem(&g, out, delays); void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride ); if (!tmp) return stbi__load_gif_main_outofmem(&g, out, delays); else { out = (stbi_uc*) tmp; out_size = layers * stride; } if (delays) { int *new_delays = (int*) STBI_REALLOC_SIZED( *delays, delays_size, sizeof(int) * layers ); if (!new_delays) return stbi__load_gif_main_outofmem(&g, out, delays); *delays = new_delays; delays_size = layers * sizeof(int); } } else { if (!stbi__mul2sizes_valid(layers, stride)) return stbi__load_gif_main_outofmem(&g, out, delays); out = (stbi_uc*)stbi__malloc( layers * stride ); if (!out) return stbi__load_gif_main_outofmem(&g, out, delays); out_size = layers * stride; if (delays) { *delays = (int*) stbi__malloc( layers * sizeof(int) ); if (!*delays) return stbi__load_gif_main_outofmem(&g, out, delays); delays_size = layers * sizeof(int); } } memcpy( out + ((layers - 1) * stride), u, stride ); if (layers >= 2) { two_back = out + (layers - 2) * stride; } if (delays) { (*delays)[layers - 1U] = g.delay; } } } while (u != 0); // free temp buffer; STBI_FREE(g.out); STBI_FREE(g.history); STBI_FREE(g.background); // do the final conversion after loading everything; if (req_comp && req_comp != 4) out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h); *z = layers; return out; } else { return stbi__errpuc("not GIF", "Image was not as a gif type."); } } static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { stbi_uc *u = 0; stbi__gif g; memset(&g, 0, sizeof(g)); STBI_NOTUSED(ri); u = stbi__gif_load_next(s, &g, comp, req_comp, 0); if (u == (stbi_uc *) s) u = 0; // end of animated gif marker if (u) { *x = g.w; *y = g.h; // moved conversion to after successful load so that the same // can be done for multiple frames. if (req_comp && req_comp != 4) u = stbi__convert_format(u, 4, req_comp, g.w, g.h); } else if (g.out) { // if there was an error and we allocated an image buffer, free it! STBI_FREE(g.out); } // free buffers needed for multiple frame loading; STBI_FREE(g.history); STBI_FREE(g.background); return u; } static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp) { return stbi__gif_info_raw(s,x,y,comp); } #endif // ************************************************************************************************* // Radiance RGBE HDR loader // originally by Nicolas Schulz #ifndef STBI_NO_HDR static int stbi__hdr_test_core(stbi__context *s, const char *signature) { int i; for (i=0; signature[i]; ++i) if (stbi__get8(s) != signature[i]) return 0; stbi__rewind(s); return 1; } static int stbi__hdr_test(stbi__context* s) { int r = stbi__hdr_test_core(s, "#?RADIANCE\n"); stbi__rewind(s); if(!r) { r = stbi__hdr_test_core(s, "#?RGBE\n"); stbi__rewind(s); } return r; } #define STBI__HDR_BUFLEN 1024 static char *stbi__hdr_gettoken(stbi__context *z, char *buffer) { int len=0; char c = '\0'; c = (char) stbi__get8(z); while (!stbi__at_eof(z) && c != '\n') { buffer[len++] = c; if (len == STBI__HDR_BUFLEN-1) { // flush to end of line while (!stbi__at_eof(z) && stbi__get8(z) != '\n') ; break; } c = (char) stbi__get8(z); } buffer[len] = 0; return buffer; } static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp) { if ( input[3] != 0 ) { float f1; // Exponent f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); if (req_comp <= 2) output[0] = (input[0] + input[1] + input[2]) * f1 / 3; else { output[0] = input[0] * f1; output[1] = input[1] * f1; output[2] = input[2] * f1; } if (req_comp == 2) output[1] = 1; if (req_comp == 4) output[3] = 1; } else { switch (req_comp) { case 4: output[3] = 1; STBI_FALLTHROUGH; case 3: output[0] = output[1] = output[2] = 0; break; case 2: output[1] = 1; STBI_FALLTHROUGH; case 1: output[0] = 0; break; } } } static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { char buffer[STBI__HDR_BUFLEN]; char *token; int valid = 0; int width, height; stbi_uc *scanline; float *hdr_data; int len; unsigned char count, value; int i, j, k, c1,c2, z; const char *headerToken; STBI_NOTUSED(ri); // Check identifier headerToken = stbi__hdr_gettoken(s,buffer); if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0) return stbi__errpf("not HDR", "Corrupt HDR image"); // Parse header for(;;) { token = stbi__hdr_gettoken(s,buffer); if (token[0] == 0) break; if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; } if (!valid) return stbi__errpf("unsupported format", "Unsupported HDR format"); // Parse width and height // can't use sscanf() if we're not using stdio! token = stbi__hdr_gettoken(s,buffer); if (strncmp(token, "-Y ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); token += 3; height = (int) strtol(token, &token, 10); while (*token == ' ') ++token; if (strncmp(token, "+X ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); token += 3; width = (int) strtol(token, NULL, 10); if (height > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)"); if (width > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)"); *x = width; *y = height; if (comp) *comp = 3; if (req_comp == 0) req_comp = 3; if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0)) return stbi__errpf("too large", "HDR image is too large"); // Read data hdr_data = (float *) stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); if (!hdr_data) return stbi__errpf("outofmem", "Out of memory"); // Load image data // image data is stored as some number of sca if ( width < 8 || width >= 32768) { // Read flat data for (j=0; j < height; ++j) { for (i=0; i < width; ++i) { stbi_uc rgbe[4]; main_decode_loop: if (!stbi__getn(s, rgbe, 4)) { STBI_FREE(hdr_data); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); } } } else { // Read RLE-encoded data scanline = NULL; for (j = 0; j < height; ++j) { c1 = stbi__get8(s); c2 = stbi__get8(s); len = stbi__get8(s); if (c1 != 2 || c2 != 2 || (len & 0x80)) { // not run-length encoded, so we have to actually use THIS data as a decoded // pixel (note this can't be a valid pixel--one of RGB must be >= 128) stbi_uc rgbe[4]; rgbe[0] = (stbi_uc) c1; rgbe[1] = (stbi_uc) c2; rgbe[2] = (stbi_uc) len; rgbe[3] = (stbi_uc) stbi__get8(s); stbi__hdr_convert(hdr_data, rgbe, req_comp); i = 1; j = 0; STBI_FREE(scanline); goto main_decode_loop; // yes, this makes no sense } len <<= 8; len |= stbi__get8(s); if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } if (scanline == NULL) { scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0); if (!scanline) { STBI_FREE(hdr_data); return stbi__errpf("outofmem", "Out of memory"); } } for (k = 0; k < 4; ++k) { int nleft; i = 0; while ((nleft = width - i) > 0) { count = stbi__get8(s); if (count > 128) { // Run value = stbi__get8(s); count -= 128; if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } for (z = 0; z < count; ++z) scanline[i++ * 4 + k] = value; } else { // Dump if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } for (z = 0; z < count; ++z) scanline[i++ * 4 + k] = stbi__get8(s); } } } for (i=0; i < width; ++i) stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); } if (scanline) STBI_FREE(scanline); } return hdr_data; } static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp) { char buffer[STBI__HDR_BUFLEN]; char *token; int valid = 0; int dummy; if (!x) x = &dummy; if (!y) y = &dummy; if (!comp) comp = &dummy; if (stbi__hdr_test(s) == 0) { stbi__rewind( s ); return 0; } for(;;) { token = stbi__hdr_gettoken(s,buffer); if (token[0] == 0) break; if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; } if (!valid) { stbi__rewind( s ); return 0; } token = stbi__hdr_gettoken(s,buffer); if (strncmp(token, "-Y ", 3)) { stbi__rewind( s ); return 0; } token += 3; *y = (int) strtol(token, &token, 10); while (*token == ' ') ++token; if (strncmp(token, "+X ", 3)) { stbi__rewind( s ); return 0; } token += 3; *x = (int) strtol(token, NULL, 10); *comp = 3; return 1; } #endif // STBI_NO_HDR #ifndef STBI_NO_BMP static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) { void *p; stbi__bmp_data info; info.all_a = 255; p = stbi__bmp_parse_header(s, &info); if (p == NULL) { stbi__rewind( s ); return 0; } if (x) *x = s->img_x; if (y) *y = s->img_y; if (comp) { if (info.bpp == 24 && info.ma == 0xff000000) *comp = 3; else *comp = info.ma ? 4 : 3; } return 1; } #endif #ifndef STBI_NO_PSD static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) { int channelCount, dummy, depth; if (!x) x = &dummy; if (!y) y = &dummy; if (!comp) comp = &dummy; if (stbi__get32be(s) != 0x38425053) { stbi__rewind( s ); return 0; } if (stbi__get16be(s) != 1) { stbi__rewind( s ); return 0; } stbi__skip(s, 6); channelCount = stbi__get16be(s); if (channelCount < 0 || channelCount > 16) { stbi__rewind( s ); return 0; } *y = stbi__get32be(s); *x = stbi__get32be(s); depth = stbi__get16be(s); if (depth != 8 && depth != 16) { stbi__rewind( s ); return 0; } if (stbi__get16be(s) != 3) { stbi__rewind( s ); return 0; } *comp = 4; return 1; } static int stbi__psd_is16(stbi__context *s) { int channelCount, depth; if (stbi__get32be(s) != 0x38425053) { stbi__rewind( s ); return 0; } if (stbi__get16be(s) != 1) { stbi__rewind( s ); return 0; } stbi__skip(s, 6); channelCount = stbi__get16be(s); if (channelCount < 0 || channelCount > 16) { stbi__rewind( s ); return 0; } STBI_NOTUSED(stbi__get32be(s)); STBI_NOTUSED(stbi__get32be(s)); depth = stbi__get16be(s); if (depth != 16) { stbi__rewind( s ); return 0; } return 1; } #endif #ifndef STBI_NO_PIC static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) { int act_comp=0,num_packets=0,chained,dummy; stbi__pic_packet packets[10]; if (!x) x = &dummy; if (!y) y = &dummy; if (!comp) comp = &dummy; if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) { stbi__rewind(s); return 0; } stbi__skip(s, 88); *x = stbi__get16be(s); *y = stbi__get16be(s); if (stbi__at_eof(s)) { stbi__rewind( s); return 0; } if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) { stbi__rewind( s ); return 0; } stbi__skip(s, 8); do { stbi__pic_packet *packet; if (num_packets==sizeof(packets)/sizeof(packets[0])) return 0; packet = &packets[num_packets++]; chained = stbi__get8(s); packet->size = stbi__get8(s); packet->type = stbi__get8(s); packet->channel = stbi__get8(s); act_comp |= packet->channel; if (stbi__at_eof(s)) { stbi__rewind( s ); return 0; } if (packet->size != 8) { stbi__rewind( s ); return 0; } } while (chained); *comp = (act_comp & 0x10 ? 4 : 3); return 1; } #endif // ************************************************************************************************* // Portable Gray Map and Portable Pixel Map loader // by Ken Miller // // PGM: http://netpbm.sourceforge.net/doc/pgm.html // PPM: http://netpbm.sourceforge.net/doc/ppm.html // // Known limitations: // Does not support comments in the header section // Does not support ASCII image data (formats P2 and P3) #ifndef STBI_NO_PNM static int stbi__pnm_test(stbi__context *s) { char p, t; p = (char) stbi__get8(s); t = (char) stbi__get8(s); if (p != 'P' || (t != '5' && t != '6')) { stbi__rewind( s ); return 0; } return 1; } static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { stbi_uc *out; STBI_NOTUSED(ri); ri->bits_per_channel = stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n); if (ri->bits_per_channel == 0) return 0; if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); *x = s->img_x; *y = s->img_y; if (comp) *comp = s->img_n; if (!stbi__mad4sizes_valid(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0)) return stbi__errpuc("too large", "PNM too large"); out = (stbi_uc *) stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0); if (!out) return stbi__errpuc("outofmem", "Out of memory"); if (!stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8))) { STBI_FREE(out); return stbi__errpuc("bad PNM", "PNM file truncated"); } if (req_comp && req_comp != s->img_n) { if (ri->bits_per_channel == 16) { out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, s->img_n, req_comp, s->img_x, s->img_y); } else { out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); } if (out == NULL) return out; // stbi__convert_format frees input on failure } return out; } static int stbi__pnm_isspace(char c) { return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; } static void stbi__pnm_skip_whitespace(stbi__context *s, char *c) { for (;;) { while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) *c = (char) stbi__get8(s); if (stbi__at_eof(s) || *c != '#') break; while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' ) *c = (char) stbi__get8(s); } } static int stbi__pnm_isdigit(char c) { return c >= '0' && c <= '9'; } static int stbi__pnm_getinteger(stbi__context *s, char *c) { int value = 0; while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) { value = value*10 + (*c - '0'); *c = (char) stbi__get8(s); if((value > 214748364) || (value == 214748364 && *c > '7')) return stbi__err("integer parse overflow", "Parsing an integer in the PPM header overflowed a 32-bit int"); } return value; } static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) { int maxv, dummy; char c, p, t; if (!x) x = &dummy; if (!y) y = &dummy; if (!comp) comp = &dummy; stbi__rewind(s); // Get identifier p = (char) stbi__get8(s); t = (char) stbi__get8(s); if (p != 'P' || (t != '5' && t != '6')) { stbi__rewind(s); return 0; } *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm c = (char) stbi__get8(s); stbi__pnm_skip_whitespace(s, &c); *x = stbi__pnm_getinteger(s, &c); // read width if(*x == 0) return stbi__err("invalid width", "PPM image header had zero or overflowing width"); stbi__pnm_skip_whitespace(s, &c); *y = stbi__pnm_getinteger(s, &c); // read height if (*y == 0) return stbi__err("invalid width", "PPM image header had zero or overflowing width"); stbi__pnm_skip_whitespace(s, &c); maxv = stbi__pnm_getinteger(s, &c); // read max value if (maxv > 65535) return stbi__err("max value > 65535", "PPM image supports only 8-bit and 16-bit images"); else if (maxv > 255) return 16; else return 8; } static int stbi__pnm_is16(stbi__context *s) { if (stbi__pnm_info(s, NULL, NULL, NULL) == 16) return 1; return 0; } #endif static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp) { #ifndef STBI_NO_JPEG if (stbi__jpeg_info(s, x, y, comp)) return 1; #endif #ifndef STBI_NO_PNG if (stbi__png_info(s, x, y, comp)) return 1; #endif #ifndef STBI_NO_GIF if (stbi__gif_info(s, x, y, comp)) return 1; #endif #ifndef STBI_NO_BMP if (stbi__bmp_info(s, x, y, comp)) return 1; #endif #ifndef STBI_NO_PSD if (stbi__psd_info(s, x, y, comp)) return 1; #endif #ifndef STBI_NO_PIC if (stbi__pic_info(s, x, y, comp)) return 1; #endif #ifndef STBI_NO_PNM if (stbi__pnm_info(s, x, y, comp)) return 1; #endif #ifndef STBI_NO_HDR if (stbi__hdr_info(s, x, y, comp)) return 1; #endif // test tga last because it's a crappy test! #ifndef STBI_NO_TGA if (stbi__tga_info(s, x, y, comp)) return 1; #endif return stbi__err("unknown image type", "Image not of any known type, or corrupt"); } static int stbi__is_16_main(stbi__context *s) { #ifndef STBI_NO_PNG if (stbi__png_is16(s)) return 1; #endif #ifndef STBI_NO_PSD if (stbi__psd_is16(s)) return 1; #endif #ifndef STBI_NO_PNM if (stbi__pnm_is16(s)) return 1; #endif return 0; } #ifndef STBI_NO_STDIO STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp) { FILE *f = stbi__fopen(filename, "rb"); int result; if (!f) return stbi__err("can't fopen", "Unable to open file"); result = stbi_info_from_file(f, x, y, comp); fclose(f); return result; } STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) { int r; stbi__context s; long pos = ftell(f); if (pos < 0) return stbi__err("bad file", "ftell() failed"); stbi__start_file(&s, f); r = stbi__info_main(&s,x,y,comp); if (fseek(f, pos, SEEK_SET) != 0) return stbi__err("bad file", "fseek() failed"); return r; } STBIDEF int stbi_is_16_bit(char const *filename) { FILE *f = stbi__fopen(filename, "rb"); int result; if (!f) return stbi__err("can't fopen", "Unable to open file"); result = stbi_is_16_bit_from_file(f); fclose(f); return result; } STBIDEF int stbi_is_16_bit_from_file(FILE *f) { int r; stbi__context s; long pos = ftell(f); if (pos < 0) return stbi__err("bad file", "ftell() failed"); stbi__start_file(&s, f); r = stbi__is_16_main(&s); if (fseek(f, pos, SEEK_SET) != 0) return stbi__err("bad file", "fseek() failed"); return r; } #endif // !STBI_NO_STDIO STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) { stbi__context s; stbi__start_mem(&s,buffer,len); return stbi__info_main(&s,x,y,comp); } STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp) { stbi__context s; stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); return stbi__info_main(&s,x,y,comp); } STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len) { stbi__context s; stbi__start_mem(&s,buffer,len); return stbi__is_16_main(&s); } STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user) { stbi__context s; stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); return stbi__is_16_main(&s); } #endif // STB_IMAGE_IMPLEMENTATION /* revision history: 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs 2.19 (2018-02-11) fix warning 2.18 (2018-01-30) fix warnings 2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug 1-bit BMP *_is_16_bit api avoid warnings 2.16 (2017-07-23) all functions have 16-bit variants; STBI_NO_STDIO works again; compilation fixes; fix rounding in unpremultiply; optimize vertical flip; disable raw_len validation; documentation fixes 2.15 (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode; warning fixes; disable run-time SSE detection on gcc; uniform handling of optional "return" values; thread-safe initialization of zlib tables 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs 2.13 (2016-11-29) add 16-bit API, only supported for PNG right now 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes 2.11 (2016-04-02) allocate large structures on the stack remove white matting for transparent PSD fix reported channel count for PNG & BMP re-enable SSE2 in non-gcc 64-bit support RGB-formatted JPEG read 16-bit PNGs (only as 8-bit) 2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED 2.09 (2016-01-16) allow comments in PNM files 16-bit-per-pixel TGA (not bit-per-component) info() for TGA could break due to .hdr handling info() for BMP to shares code instead of sloppy parse can use STBI_REALLOC_SIZED if allocator doesn't support realloc code cleanup 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA 2.07 (2015-09-13) fix compiler warnings partial animated GIF support limited 16-bpc PSD support #ifdef unused functions bug with < 92 byte PIC,PNM,HDR,TGA 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit 2.03 (2015-04-12) extra corruption checking (mmozeiko) stbi_set_flip_vertically_on_load (nguillemot) fix NEON support; fix mingw support 2.02 (2015-01-19) fix incorrect assert, fix warning 2.01 (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG 2.00 (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg) progressive JPEG (stb) PGM/PPM support (Ken Miller) STBI_MALLOC,STBI_REALLOC,STBI_FREE GIF bugfix -- seemingly never worked STBI_NO_*, STBI_ONLY_* 1.48 (2014-12-14) fix incorrectly-named assert() 1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb) optimize PNG (ryg) fix bug in interlaced PNG with user-specified channel count (stb) 1.46 (2014-08-26) fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG 1.45 (2014-08-16) fix MSVC-ARM internal compiler error by wrapping malloc 1.44 (2014-08-07) various warning fixes from Ronny Chevalier 1.43 (2014-07-15) fix MSVC-only compiler problem in code changed in 1.42 1.42 (2014-07-09) don't define _CRT_SECURE_NO_WARNINGS (affects user code) fixes to stbi__cleanup_jpeg path added STBI_ASSERT to avoid requiring assert.h 1.41 (2014-06-25) fix search&replace from 1.36 that messed up comments/error messages 1.40 (2014-06-22) fix gcc struct-initialization warning 1.39 (2014-06-15) fix to TGA optimization when req_comp != number of components in TGA; fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite) add support for BMP version 5 (more ignored fields) 1.38 (2014-06-06) suppress MSVC warnings on integer casts truncating values fix accidental rename of 'skip' field of I/O 1.37 (2014-06-04) remove duplicate typedef 1.36 (2014-06-03) convert to header file single-file library if de-iphone isn't set, load iphone images color-swapped instead of returning NULL 1.35 (2014-05-27) various warnings fix broken STBI_SIMD path fix bug where stbi_load_from_file no longer left file pointer in correct place fix broken non-easy path for 32-bit BMP (possibly never used) TGA optimization by Arseny Kapoulkine 1.34 (unknown) use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case 1.33 (2011-07-14) make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements 1.32 (2011-07-13) support for "info" function for all supported filetypes (SpartanJ) 1.31 (2011-06-20) a few more leak fixes, bug in PNG handling (SpartanJ) 1.30 (2011-06-11) added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) removed deprecated format-specific test/load functions removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) fix inefficiency in decoding 32-bit BMP (David Woo) 1.29 (2010-08-16) various warning fixes from Aurelien Pocheville 1.28 (2010-08-01) fix bug in GIF palette transparency (SpartanJ) 1.27 (2010-08-01) cast-to-stbi_uc to fix warnings 1.26 (2010-07-24) fix bug in file buffering for PNG reported by SpartanJ 1.25 (2010-07-17) refix trans_data warning (Won Chun) 1.24 (2010-07-12) perf improvements reading from files on platforms with lock-heavy fgetc() minor perf improvements for jpeg deprecated type-specific functions so we'll get feedback if they're needed attempt to fix trans_data warning (Won Chun) 1.23 fixed bug in iPhone support 1.22 (2010-07-10) removed image *writing* support stbi_info support from Jetro Lauha GIF support from Jean-Marc Lienher iPhone PNG-extensions from James Brown warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva) 1.21 fix use of 'stbi_uc' in header (reported by jon blow) 1.20 added support for Softimage PIC, by Tom Seddon 1.19 bug in interlaced PNG corruption check (found by ryg) 1.18 (2008-08-02) fix a threading bug (local mutable static) 1.17 support interlaced PNG 1.16 major bugfix - stbi__convert_format converted one too many pixels 1.15 initialize some fields for thread safety 1.14 fix threadsafe conversion bug header-file-only version (#define STBI_HEADER_FILE_ONLY before including) 1.13 threadsafe 1.12 const qualifiers in the API 1.11 Support installable IDCT, colorspace conversion routines 1.10 Fixes for 64-bit (don't use "unsigned long") optimized upsampling by Fabian "ryg" Giesen 1.09 Fix format-conversion for PSD code (bad global variables!) 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz 1.07 attempt to fix C++ warning/errors again 1.06 attempt to fix C++ warning/errors again 1.05 fix TGA loading to return correct *comp and use good luminance calc 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR 1.02 support for (subset of) HDR files, float interface for preferred access to them 1.01 fix bug: possible bug in handling right-side up bmps... not sure fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all 1.00 interface to zlib that skips zlib header 0.99 correct handling of alpha in palette 0.98 TGA loader by lonesock; dynamically add loaders (untested) 0.97 jpeg errors on too large a file; also catch another malloc failure 0.96 fix detection of invalid v value - particleman@mollyrocket forum 0.95 during header scan, seek to markers in case of padding 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same 0.93 handle jpegtran output; verbose errors 0.92 read 4,8,16,24,32-bit BMP files of several formats 0.91 output 24-bit Windows 3.0 BMP files 0.90 fix a few more warnings; bump version number to approach 1.0 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd 0.60 fix compiling as c++ 0.59 fix warnings: merge Dave Moore's -Wall fixes 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available 0.56 fix bug: zlib uncompressed mode len vs. nlen 0.55 fix bug: restart_interval not initialized to 0 0.54 allow NULL for 'int *comp' 0.53 fix bug in png 3->4; speedup png decoding 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments 0.51 obey req_comp requests, 1-component jpegs return as 1-component, on 'test' only check type, not whether we support this variant 0.50 (2006-11-19) first released version */ /* ------------------------------------------------------------------------------ This software is available under 2 licenses -- choose whichever you prefer. ------------------------------------------------------------------------------ ALTERNATIVE A - MIT License Copyright (c) 2017 Sean Barrett Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ ALTERNATIVE B - Public Domain (www.unlicense.org) This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ */ chawan-v0.4.0/adapter/img/stb_image_resize.h000066400000000000000000003434441520232313100210260ustar00rootroot00000000000000/* stb_image_resize - v0.97 - public domain image resizing by Jorge L Rodriguez (@VinoBS) - 2014 http://github.com/nothings/stb Written with emphasis on usability, portability, and efficiency. (No SIMD or threads, so it be easily outperformed by libs that use those.) Only scaling and translation is supported, no rotations or shears. Easy API downsamples w/Mitchell filter, upsamples w/cubic interpolation. COMPILING & LINKING In one C/C++ file that #includes this file, do this: #define STB_IMAGE_RESIZE_IMPLEMENTATION before the #include. That will create the implementation in that file. QUICKSTART stbir_resize_uint8( input_pixels , in_w , in_h , 0, output_pixels, out_w, out_h, 0, num_channels) stbir_resize_float(...) stbir_resize_uint8_srgb( input_pixels , in_w , in_h , 0, output_pixels, out_w, out_h, 0, num_channels , alpha_chan , 0) stbir_resize_uint8_srgb_edgemode( input_pixels , in_w , in_h , 0, output_pixels, out_w, out_h, 0, num_channels , alpha_chan , 0, STBIR_EDGE_CLAMP) // WRAP/REFLECT/ZERO FULL API See the "header file" section of the source for API documentation. ADDITIONAL DOCUMENTATION SRGB & FLOATING POINT REPRESENTATION The sRGB functions presume IEEE floating point. If you do not have IEEE floating point, define STBIR_NON_IEEE_FLOAT. This will use a slower implementation. MEMORY ALLOCATION The resize functions here perform a single memory allocation using malloc. To control the memory allocation, before the #include that triggers the implementation, do: #define STBIR_MALLOC(size,context) ... #define STBIR_FREE(ptr,context) ... Each resize function makes exactly one call to malloc/free, so to use temp memory, store the temp memory in the context and return that. ASSERT Define STBIR_ASSERT(boolval) to override assert() and not use assert.h OPTIMIZATION Define STBIR_SATURATE_INT to compute clamp values in-range using integer operations instead of float operations. This may be faster on some platforms. DEFAULT FILTERS For functions which don't provide explicit control over what filters to use, you can change the compile-time defaults with #define STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_something #define STBIR_DEFAULT_FILTER_DOWNSAMPLE STBIR_FILTER_something See stbir_filter in the header-file section for the list of filters. NEW FILTERS A number of 1D filter kernels are used. For a list of supported filters see the stbir_filter enum. To add a new filter, write a filter function and add it to stbir__filter_info_table. PROGRESS For interactive use with slow resize operations, you can install a progress-report callback: #define STBIR_PROGRESS_REPORT(val) some_func(val) The parameter val is a float which goes from 0 to 1 as progress is made. For example: static void my_progress_report(float progress); #define STBIR_PROGRESS_REPORT(val) my_progress_report(val) #define STB_IMAGE_RESIZE_IMPLEMENTATION #include "stb_image_resize.h" static void my_progress_report(float progress) { printf("Progress: %f%%\n", progress*100); } MAX CHANNELS If your image has more than 64 channels, define STBIR_MAX_CHANNELS to the max you'll have. ALPHA CHANNEL Most of the resizing functions provide the ability to control how the alpha channel of an image is processed. The important things to know about this: 1. The best mathematically-behaved version of alpha to use is called "premultiplied alpha", in which the other color channels have had the alpha value multiplied in. If you use premultiplied alpha, linear filtering (such as image resampling done by this library, or performed in texture units on GPUs) does the "right thing". While premultiplied alpha is standard in the movie CGI industry, it is still uncommon in the videogame/real-time world. If you linearly filter non-premultiplied alpha, strange effects occur. (For example, the 50/50 average of 99% transparent bright green and 1% transparent black produces 50% transparent dark green when non-premultiplied, whereas premultiplied it produces 50% transparent near-black. The former introduces green energy that doesn't exist in the source image.) 2. Artists should not edit premultiplied-alpha images; artists want non-premultiplied alpha images. Thus, art tools generally output non-premultiplied alpha images. 3. You will get best results in most cases by converting images to premultiplied alpha before processing them mathematically. 4. If you pass the flag STBIR_FLAG_ALPHA_PREMULTIPLIED, the resizer does not do anything special for the alpha channel; it is resampled identically to other channels. This produces the correct results for premultiplied-alpha images, but produces less-than-ideal results for non-premultiplied-alpha images. 5. If you do not pass the flag STBIR_FLAG_ALPHA_PREMULTIPLIED, then the resizer weights the contribution of input pixels based on their alpha values, or, equivalently, it multiplies the alpha value into the color channels, resamples, then divides by the resultant alpha value. Input pixels which have alpha=0 do not contribute at all to output pixels unless _all_ of the input pixels affecting that output pixel have alpha=0, in which case the result for that pixel is the same as it would be without STBIR_FLAG_ALPHA_PREMULTIPLIED. However, this is only true for input images in integer formats. For input images in float format, input pixels with alpha=0 have no effect, and output pixels which have alpha=0 will be 0 in all channels. (For float images, you can manually achieve the same result by adding a tiny epsilon value to the alpha channel of every image, and then subtracting or clamping it at the end.) 6. You can suppress the behavior described in #5 and make all-0-alpha pixels have 0 in all channels by #defining STBIR_NO_ALPHA_EPSILON. 7. You can separately control whether the alpha channel is interpreted as linear or affected by the colorspace. By default it is linear; you almost never want to apply the colorspace. (For example, graphics hardware does not apply sRGB conversion to the alpha channel.) CONTRIBUTORS Jorge L Rodriguez: Implementation Sean Barrett: API design, optimizations Aras Pranckevicius: bugfix Nathan Reed: warning fixes REVISIONS 0.97 (2020-02-02) fixed warning 0.96 (2019-03-04) fixed warnings 0.95 (2017-07-23) fixed warnings 0.94 (2017-03-18) fixed warnings 0.93 (2017-03-03) fixed bug with certain combinations of heights 0.92 (2017-01-02) fix integer overflow on large (>2GB) images 0.91 (2016-04-02) fix warnings; fix handling of subpixel regions 0.90 (2014-09-17) first released version LICENSE See end of file for license information. TODO Don't decode all of the image data when only processing a partial tile Don't use full-width decode buffers when only processing a partial tile When processing wide images, break processing into tiles so data fits in L1 cache Installable filters? Resize that respects alpha test coverage (Reference code: FloatImage::alphaTestCoverage and FloatImage::scaleAlphaToCoverage: https://code.google.com/p/nvidia-texture-tools/source/browse/trunk/src/nvimage/FloatImage.cpp ) */ #ifndef STBIR_INCLUDE_STB_IMAGE_RESIZE_H #define STBIR_INCLUDE_STB_IMAGE_RESIZE_H #ifdef _MSC_VER typedef unsigned char stbir_uint8; typedef unsigned short stbir_uint16; typedef unsigned int stbir_uint32; #else #include typedef uint8_t stbir_uint8; typedef uint16_t stbir_uint16; typedef uint32_t stbir_uint32; #endif #ifndef STBIRDEF #ifdef STB_IMAGE_RESIZE_STATIC #define STBIRDEF static #else #ifdef __cplusplus #define STBIRDEF extern "C" #else #define STBIRDEF extern #endif #endif #endif ////////////////////////////////////////////////////////////////////////////// // // Easy-to-use API: // // * "input pixels" points to an array of image data with 'num_channels' channels (e.g. RGB=3, RGBA=4) // * input_w is input image width (x-axis), input_h is input image height (y-axis) // * stride is the offset between successive rows of image data in memory, in bytes. you can // specify 0 to mean packed continuously in memory // * alpha channel is treated identically to other channels. // * colorspace is linear or sRGB as specified by function name // * returned result is 1 for success or 0 in case of an error. // #define STBIR_ASSERT() to trigger an assert on parameter validation errors. // * Memory required grows approximately linearly with input and output size, but with // discontinuities at input_w == output_w and input_h == output_h. // * These functions use a "default" resampling filter defined at compile time. To change the filter, // you can change the compile-time defaults by #defining STBIR_DEFAULT_FILTER_UPSAMPLE // and STBIR_DEFAULT_FILTER_DOWNSAMPLE, or you can use the medium-complexity API. STBIRDEF int stbir_resize_uint8( const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, int num_channels); STBIRDEF int stbir_resize_float( const float *input_pixels , int input_w , int input_h , int input_stride_in_bytes, float *output_pixels, int output_w, int output_h, int output_stride_in_bytes, int num_channels); // The following functions interpret image data as gamma-corrected sRGB. // Specify STBIR_ALPHA_CHANNEL_NONE if you have no alpha channel, // or otherwise provide the index of the alpha channel. Flags value // of 0 will probably do the right thing if you're not sure what // the flags mean. #define STBIR_ALPHA_CHANNEL_NONE -1 // Set this flag if your texture has premultiplied alpha. Otherwise, stbir will // use alpha-weighted resampling (effectively premultiplying, resampling, // then unpremultiplying). #define STBIR_FLAG_ALPHA_PREMULTIPLIED (1 << 0) // The specified alpha channel should be handled as gamma-corrected value even // when doing sRGB operations. #define STBIR_FLAG_ALPHA_USES_COLORSPACE (1 << 1) STBIRDEF int stbir_resize_uint8_srgb(const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, int num_channels, int alpha_channel, int flags); typedef enum { STBIR_EDGE_CLAMP = 1, STBIR_EDGE_REFLECT = 2, STBIR_EDGE_WRAP = 3, STBIR_EDGE_ZERO = 4, } stbir_edge; // This function adds the ability to specify how requests to sample off the edge of the image are handled. STBIRDEF int stbir_resize_uint8_srgb_edgemode(const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, int num_channels, int alpha_channel, int flags, stbir_edge edge_wrap_mode); ////////////////////////////////////////////////////////////////////////////// // // Medium-complexity API // // This extends the easy-to-use API as follows: // // * Alpha-channel can be processed separately // * If alpha_channel is not STBIR_ALPHA_CHANNEL_NONE // * Alpha channel will not be gamma corrected (unless flags&STBIR_FLAG_GAMMA_CORRECT) // * Filters will be weighted by alpha channel (unless flags&STBIR_FLAG_ALPHA_PREMULTIPLIED) // * Filter can be selected explicitly // * uint16 image type // * sRGB colorspace available for all types // * context parameter for passing to STBIR_MALLOC typedef enum { STBIR_FILTER_DEFAULT = 0, // use same filter type that easy-to-use API chooses STBIR_FILTER_BOX = 1, // A trapezoid w/1-pixel wide ramps, same result as box for integer scale ratios STBIR_FILTER_TRIANGLE = 2, // On upsampling, produces same results as bilinear texture filtering STBIR_FILTER_CUBICBSPLINE = 3, // The cubic b-spline (aka Mitchell-Netrevalli with B=1,C=0), gaussian-esque STBIR_FILTER_CATMULLROM = 4, // An interpolating cubic spline STBIR_FILTER_MITCHELL = 5, // Mitchell-Netrevalli filter with B=1/3, C=1/3 } stbir_filter; typedef enum { STBIR_COLORSPACE_LINEAR, STBIR_COLORSPACE_SRGB, STBIR_MAX_COLORSPACES, } stbir_colorspace; // The following functions are all identical except for the type of the image data STBIRDEF int stbir_resize_uint8_generic( const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, int num_channels, int alpha_channel, int flags, stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, void *alloc_context); STBIRDEF int stbir_resize_uint16_generic(const stbir_uint16 *input_pixels , int input_w , int input_h , int input_stride_in_bytes, stbir_uint16 *output_pixels , int output_w, int output_h, int output_stride_in_bytes, int num_channels, int alpha_channel, int flags, stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, void *alloc_context); STBIRDEF int stbir_resize_float_generic( const float *input_pixels , int input_w , int input_h , int input_stride_in_bytes, float *output_pixels , int output_w, int output_h, int output_stride_in_bytes, int num_channels, int alpha_channel, int flags, stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, void *alloc_context); ////////////////////////////////////////////////////////////////////////////// // // Full-complexity API // // This extends the medium API as follows: // // * uint32 image type // * not typesafe // * separate filter types for each axis // * separate edge modes for each axis // * can specify scale explicitly for subpixel correctness // * can specify image source tile using texture coordinates typedef enum { STBIR_TYPE_UINT8 , STBIR_TYPE_UINT16, STBIR_TYPE_UINT32, STBIR_TYPE_FLOAT , STBIR_MAX_TYPES } stbir_datatype; STBIRDEF int stbir_resize( const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, stbir_datatype datatype, int num_channels, int alpha_channel, int flags, stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, stbir_filter filter_horizontal, stbir_filter filter_vertical, stbir_colorspace space, void *alloc_context); STBIRDEF int stbir_resize_subpixel(const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, stbir_datatype datatype, int num_channels, int alpha_channel, int flags, stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, stbir_filter filter_horizontal, stbir_filter filter_vertical, stbir_colorspace space, void *alloc_context, float x_scale, float y_scale, float x_offset, float y_offset); STBIRDEF int stbir_resize_region( const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, stbir_datatype datatype, int num_channels, int alpha_channel, int flags, stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, stbir_filter filter_horizontal, stbir_filter filter_vertical, stbir_colorspace space, void *alloc_context, float s0, float t0, float s1, float t1); // (s0, t0) & (s1, t1) are the top-left and bottom right corner (uv addressing style: [0, 1]x[0, 1]) of a region of the input image to use. // // //// end header file ///////////////////////////////////////////////////// #endif // STBIR_INCLUDE_STB_IMAGE_RESIZE_H #ifdef STB_IMAGE_RESIZE_IMPLEMENTATION #ifndef STBIR_ASSERT #include #define STBIR_ASSERT(x) assert(x) #endif // For memset #include #include #ifndef STBIR_MALLOC #include // use comma operator to evaluate c, to avoid "unused parameter" warnings #define STBIR_MALLOC(size,c) ((void)(c), malloc(size)) #define STBIR_FREE(ptr,c) ((void)(c), free(ptr)) #endif #ifndef _MSC_VER #ifdef __cplusplus #define stbir__inline inline #else #define stbir__inline #endif #else #define stbir__inline __forceinline #endif // should produce compiler error if size is wrong typedef unsigned char stbir__validate_uint32[sizeof(stbir_uint32) == 4 ? 1 : -1]; #ifdef _MSC_VER #define STBIR__NOTUSED(v) (void)(v) #else #define STBIR__NOTUSED(v) (void)sizeof(v) #endif #define STBIR__ARRAY_SIZE(a) (sizeof((a))/sizeof((a)[0])) #ifndef STBIR_DEFAULT_FILTER_UPSAMPLE #define STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_CATMULLROM #endif #ifndef STBIR_DEFAULT_FILTER_DOWNSAMPLE #define STBIR_DEFAULT_FILTER_DOWNSAMPLE STBIR_FILTER_MITCHELL #endif #ifndef STBIR_PROGRESS_REPORT #define STBIR_PROGRESS_REPORT(float_0_to_1) #endif #ifndef STBIR_MAX_CHANNELS #define STBIR_MAX_CHANNELS 64 #endif #if STBIR_MAX_CHANNELS > 65536 #error "Too many channels; STBIR_MAX_CHANNELS must be no more than 65536." // because we store the indices in 16-bit variables #endif // This value is added to alpha just before premultiplication to avoid // zeroing out color values. It is equivalent to 2^-80. If you don't want // that behavior (it may interfere if you have floating point images with // very small alpha values) then you can define STBIR_NO_ALPHA_EPSILON to // disable it. #ifndef STBIR_ALPHA_EPSILON #define STBIR_ALPHA_EPSILON ((float)1 / (1 << 20) / (1 << 20) / (1 << 20) / (1 << 20)) #endif #ifdef _MSC_VER #define STBIR__UNUSED_PARAM(v) (void)(v) #else #define STBIR__UNUSED_PARAM(v) (void)sizeof(v) #endif // must match stbir_datatype static unsigned char stbir__type_size[] = { 1, // STBIR_TYPE_UINT8 2, // STBIR_TYPE_UINT16 4, // STBIR_TYPE_UINT32 4, // STBIR_TYPE_FLOAT }; // Kernel function centered at 0 typedef float (stbir__kernel_fn)(float x, float scale); typedef float (stbir__support_fn)(float scale); typedef struct { stbir__kernel_fn* kernel; stbir__support_fn* support; } stbir__filter_info; // When upsampling, the contributors are which source pixels contribute. // When downsampling, the contributors are which destination pixels are contributed to. typedef struct { int n0; // First contributing pixel int n1; // Last contributing pixel } stbir__contributors; typedef struct { const void* input_data; int input_w; int input_h; int input_stride_bytes; void* output_data; int output_w; int output_h; int output_stride_bytes; float s0, t0, s1, t1; float horizontal_shift; // Units: output pixels float vertical_shift; // Units: output pixels float horizontal_scale; float vertical_scale; int channels; int alpha_channel; stbir_uint32 flags; stbir_datatype type; stbir_filter horizontal_filter; stbir_filter vertical_filter; stbir_edge edge_horizontal; stbir_edge edge_vertical; stbir_colorspace colorspace; stbir__contributors* horizontal_contributors; float* horizontal_coefficients; stbir__contributors* vertical_contributors; float* vertical_coefficients; int decode_buffer_pixels; float* decode_buffer; float* horizontal_buffer; // cache these because ceil/floor are inexplicably showing up in profile int horizontal_coefficient_width; int vertical_coefficient_width; int horizontal_filter_pixel_width; int vertical_filter_pixel_width; int horizontal_filter_pixel_margin; int vertical_filter_pixel_margin; int horizontal_num_contributors; int vertical_num_contributors; int ring_buffer_length_bytes; // The length of an individual entry in the ring buffer. The total number of ring buffers is stbir__get_filter_pixel_width(filter) int ring_buffer_num_entries; // Total number of entries in the ring buffer. int ring_buffer_first_scanline; int ring_buffer_last_scanline; int ring_buffer_begin_index; // first_scanline is at this index in the ring buffer float* ring_buffer; float* encode_buffer; // A temporary buffer to store floats so we don't lose precision while we do multiply-adds. int horizontal_contributors_size; int horizontal_coefficients_size; int vertical_contributors_size; int vertical_coefficients_size; int decode_buffer_size; int horizontal_buffer_size; int ring_buffer_size; int encode_buffer_size; } stbir__info; static const float stbir__max_uint8_as_float = 255.0f; static const float stbir__max_uint16_as_float = 65535.0f; static const double stbir__max_uint32_as_float = 4294967295.0; static stbir__inline int stbir__min(int a, int b) { return a < b ? a : b; } static stbir__inline float stbir__saturate(float x) { if (x < 0) return 0; if (x > 1) return 1; return x; } #ifdef STBIR_SATURATE_INT static stbir__inline stbir_uint8 stbir__saturate8(int x) { if ((unsigned int) x <= 255) return x; if (x < 0) return 0; return 255; } static stbir__inline stbir_uint16 stbir__saturate16(int x) { if ((unsigned int) x <= 65535) return x; if (x < 0) return 0; return 65535; } #endif static float stbir__srgb_uchar_to_linear_float[256] = { 0.000000f, 0.000304f, 0.000607f, 0.000911f, 0.001214f, 0.001518f, 0.001821f, 0.002125f, 0.002428f, 0.002732f, 0.003035f, 0.003347f, 0.003677f, 0.004025f, 0.004391f, 0.004777f, 0.005182f, 0.005605f, 0.006049f, 0.006512f, 0.006995f, 0.007499f, 0.008023f, 0.008568f, 0.009134f, 0.009721f, 0.010330f, 0.010960f, 0.011612f, 0.012286f, 0.012983f, 0.013702f, 0.014444f, 0.015209f, 0.015996f, 0.016807f, 0.017642f, 0.018500f, 0.019382f, 0.020289f, 0.021219f, 0.022174f, 0.023153f, 0.024158f, 0.025187f, 0.026241f, 0.027321f, 0.028426f, 0.029557f, 0.030713f, 0.031896f, 0.033105f, 0.034340f, 0.035601f, 0.036889f, 0.038204f, 0.039546f, 0.040915f, 0.042311f, 0.043735f, 0.045186f, 0.046665f, 0.048172f, 0.049707f, 0.051269f, 0.052861f, 0.054480f, 0.056128f, 0.057805f, 0.059511f, 0.061246f, 0.063010f, 0.064803f, 0.066626f, 0.068478f, 0.070360f, 0.072272f, 0.074214f, 0.076185f, 0.078187f, 0.080220f, 0.082283f, 0.084376f, 0.086500f, 0.088656f, 0.090842f, 0.093059f, 0.095307f, 0.097587f, 0.099899f, 0.102242f, 0.104616f, 0.107023f, 0.109462f, 0.111932f, 0.114435f, 0.116971f, 0.119538f, 0.122139f, 0.124772f, 0.127438f, 0.130136f, 0.132868f, 0.135633f, 0.138432f, 0.141263f, 0.144128f, 0.147027f, 0.149960f, 0.152926f, 0.155926f, 0.158961f, 0.162029f, 0.165132f, 0.168269f, 0.171441f, 0.174647f, 0.177888f, 0.181164f, 0.184475f, 0.187821f, 0.191202f, 0.194618f, 0.198069f, 0.201556f, 0.205079f, 0.208637f, 0.212231f, 0.215861f, 0.219526f, 0.223228f, 0.226966f, 0.230740f, 0.234551f, 0.238398f, 0.242281f, 0.246201f, 0.250158f, 0.254152f, 0.258183f, 0.262251f, 0.266356f, 0.270498f, 0.274677f, 0.278894f, 0.283149f, 0.287441f, 0.291771f, 0.296138f, 0.300544f, 0.304987f, 0.309469f, 0.313989f, 0.318547f, 0.323143f, 0.327778f, 0.332452f, 0.337164f, 0.341914f, 0.346704f, 0.351533f, 0.356400f, 0.361307f, 0.366253f, 0.371238f, 0.376262f, 0.381326f, 0.386430f, 0.391573f, 0.396755f, 0.401978f, 0.407240f, 0.412543f, 0.417885f, 0.423268f, 0.428691f, 0.434154f, 0.439657f, 0.445201f, 0.450786f, 0.456411f, 0.462077f, 0.467784f, 0.473532f, 0.479320f, 0.485150f, 0.491021f, 0.496933f, 0.502887f, 0.508881f, 0.514918f, 0.520996f, 0.527115f, 0.533276f, 0.539480f, 0.545725f, 0.552011f, 0.558340f, 0.564712f, 0.571125f, 0.577581f, 0.584078f, 0.590619f, 0.597202f, 0.603827f, 0.610496f, 0.617207f, 0.623960f, 0.630757f, 0.637597f, 0.644480f, 0.651406f, 0.658375f, 0.665387f, 0.672443f, 0.679543f, 0.686685f, 0.693872f, 0.701102f, 0.708376f, 0.715694f, 0.723055f, 0.730461f, 0.737911f, 0.745404f, 0.752942f, 0.760525f, 0.768151f, 0.775822f, 0.783538f, 0.791298f, 0.799103f, 0.806952f, 0.814847f, 0.822786f, 0.830770f, 0.838799f, 0.846873f, 0.854993f, 0.863157f, 0.871367f, 0.879622f, 0.887923f, 0.896269f, 0.904661f, 0.913099f, 0.921582f, 0.930111f, 0.938686f, 0.947307f, 0.955974f, 0.964686f, 0.973445f, 0.982251f, 0.991102f, 1.0f }; static float stbir__srgb_to_linear(float f) { if (f <= 0.04045f) return f / 12.92f; else return (float)pow((f + 0.055f) / 1.055f, 2.4f); } static float stbir__linear_to_srgb(float f) { if (f <= 0.0031308f) return f * 12.92f; else return 1.055f * (float)pow(f, 1 / 2.4f) - 0.055f; } #ifndef STBIR_NON_IEEE_FLOAT // From https://gist.github.com/rygorous/2203834 typedef union { stbir_uint32 u; float f; } stbir__FP32; static const stbir_uint32 fp32_to_srgb8_tab4[104] = { 0x0073000d, 0x007a000d, 0x0080000d, 0x0087000d, 0x008d000d, 0x0094000d, 0x009a000d, 0x00a1000d, 0x00a7001a, 0x00b4001a, 0x00c1001a, 0x00ce001a, 0x00da001a, 0x00e7001a, 0x00f4001a, 0x0101001a, 0x010e0033, 0x01280033, 0x01410033, 0x015b0033, 0x01750033, 0x018f0033, 0x01a80033, 0x01c20033, 0x01dc0067, 0x020f0067, 0x02430067, 0x02760067, 0x02aa0067, 0x02dd0067, 0x03110067, 0x03440067, 0x037800ce, 0x03df00ce, 0x044600ce, 0x04ad00ce, 0x051400ce, 0x057b00c5, 0x05dd00bc, 0x063b00b5, 0x06970158, 0x07420142, 0x07e30130, 0x087b0120, 0x090b0112, 0x09940106, 0x0a1700fc, 0x0a9500f2, 0x0b0f01cb, 0x0bf401ae, 0x0ccb0195, 0x0d950180, 0x0e56016e, 0x0f0d015e, 0x0fbc0150, 0x10630143, 0x11070264, 0x1238023e, 0x1357021d, 0x14660201, 0x156601e9, 0x165a01d3, 0x174401c0, 0x182401af, 0x18fe0331, 0x1a9602fe, 0x1c1502d2, 0x1d7e02ad, 0x1ed4028d, 0x201a0270, 0x21520256, 0x227d0240, 0x239f0443, 0x25c003fe, 0x27bf03c4, 0x29a10392, 0x2b6a0367, 0x2d1d0341, 0x2ebe031f, 0x304d0300, 0x31d105b0, 0x34a80555, 0x37520507, 0x39d504c5, 0x3c37048b, 0x3e7c0458, 0x40a8042a, 0x42bd0401, 0x44c20798, 0x488e071e, 0x4c1c06b6, 0x4f76065d, 0x52a50610, 0x55ac05cc, 0x5892058f, 0x5b590559, 0x5e0c0a23, 0x631c0980, 0x67db08f6, 0x6c55087f, 0x70940818, 0x74a007bd, 0x787d076c, 0x7c330723, }; static stbir_uint8 stbir__linear_to_srgb_uchar(float in) { static const stbir__FP32 almostone = { 0x3f7fffff }; // 1-eps static const stbir__FP32 minval = { (127-13) << 23 }; stbir_uint32 tab,bias,scale,t; stbir__FP32 f; // Clamp to [2^(-13), 1-eps]; these two values map to 0 and 1, respectively. // The tests are carefully written so that NaNs map to 0, same as in the reference // implementation. if (!(in > minval.f)) // written this way to catch NaNs in = minval.f; if (in > almostone.f) in = almostone.f; // Do the table lookup and unpack bias, scale f.f = in; tab = fp32_to_srgb8_tab4[(f.u - minval.u) >> 20]; bias = (tab >> 16) << 9; scale = tab & 0xffff; // Grab next-highest mantissa bits and perform linear interpolation t = (f.u >> 12) & 0xff; return (unsigned char) ((bias + scale*t) >> 16); } #else // sRGB transition values, scaled by 1<<28 static int stbir__srgb_offset_to_linear_scaled[256] = { 0, 40738, 122216, 203693, 285170, 366648, 448125, 529603, 611080, 692557, 774035, 855852, 942009, 1033024, 1128971, 1229926, 1335959, 1447142, 1563542, 1685229, 1812268, 1944725, 2082664, 2226148, 2375238, 2529996, 2690481, 2856753, 3028870, 3206888, 3390865, 3580856, 3776916, 3979100, 4187460, 4402049, 4622919, 4850123, 5083710, 5323731, 5570236, 5823273, 6082892, 6349140, 6622065, 6901714, 7188133, 7481369, 7781466, 8088471, 8402427, 8723380, 9051372, 9386448, 9728650, 10078021, 10434603, 10798439, 11169569, 11548036, 11933879, 12327139, 12727857, 13136073, 13551826, 13975156, 14406100, 14844697, 15290987, 15745007, 16206795, 16676389, 17153826, 17639142, 18132374, 18633560, 19142734, 19659934, 20185196, 20718552, 21260042, 21809696, 22367554, 22933648, 23508010, 24090680, 24681686, 25281066, 25888850, 26505076, 27129772, 27762974, 28404716, 29055026, 29713942, 30381490, 31057708, 31742624, 32436272, 33138682, 33849884, 34569912, 35298800, 36036568, 36783260, 37538896, 38303512, 39077136, 39859796, 40651528, 41452360, 42262316, 43081432, 43909732, 44747252, 45594016, 46450052, 47315392, 48190064, 49074096, 49967516, 50870356, 51782636, 52704392, 53635648, 54576432, 55526772, 56486700, 57456236, 58435408, 59424248, 60422780, 61431036, 62449032, 63476804, 64514376, 65561776, 66619028, 67686160, 68763192, 69850160, 70947088, 72053992, 73170912, 74297864, 75434880, 76581976, 77739184, 78906536, 80084040, 81271736, 82469648, 83677792, 84896192, 86124888, 87363888, 88613232, 89872928, 91143016, 92423512, 93714432, 95015816, 96327688, 97650056, 98982952, 100326408, 101680440, 103045072, 104420320, 105806224, 107202800, 108610064, 110028048, 111456776, 112896264, 114346544, 115807632, 117279552, 118762328, 120255976, 121760536, 123276016, 124802440, 126339832, 127888216, 129447616, 131018048, 132599544, 134192112, 135795792, 137410592, 139036528, 140673648, 142321952, 143981456, 145652208, 147334208, 149027488, 150732064, 152447968, 154175200, 155913792, 157663776, 159425168, 161197984, 162982240, 164777968, 166585184, 168403904, 170234160, 172075968, 173929344, 175794320, 177670896, 179559120, 181458992, 183370528, 185293776, 187228736, 189175424, 191133888, 193104112, 195086128, 197079968, 199085648, 201103184, 203132592, 205173888, 207227120, 209292272, 211369392, 213458480, 215559568, 217672656, 219797792, 221934976, 224084240, 226245600, 228419056, 230604656, 232802400, 235012320, 237234432, 239468736, 241715280, 243974080, 246245120, 248528464, 250824112, 253132064, 255452368, 257785040, 260130080, 262487520, 264857376, 267239664, }; static stbir_uint8 stbir__linear_to_srgb_uchar(float f) { int x = (int) (f * (1 << 28)); // has headroom so you don't need to clamp int v = 0; int i; // Refine the guess with a short binary search. i = v + 128; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; i = v + 64; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; i = v + 32; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; i = v + 16; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; i = v + 8; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; i = v + 4; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; i = v + 2; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; i = v + 1; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; return (stbir_uint8) v; } #endif static float stbir__filter_trapezoid(float x, float scale) { float halfscale = scale / 2; float t = 0.5f + halfscale; STBIR_ASSERT(scale <= 1); x = (float)fabs(x); if (x >= t) return 0; else { float r = 0.5f - halfscale; if (x <= r) return 1; else return (t - x) / scale; } } static float stbir__support_trapezoid(float scale) { STBIR_ASSERT(scale <= 1); return 0.5f + scale / 2; } static float stbir__filter_triangle(float x, float s) { STBIR__UNUSED_PARAM(s); x = (float)fabs(x); if (x <= 1.0f) return 1 - x; else return 0; } static float stbir__filter_cubic(float x, float s) { STBIR__UNUSED_PARAM(s); x = (float)fabs(x); if (x < 1.0f) return (4 + x*x*(3*x - 6))/6; else if (x < 2.0f) return (8 + x*(-12 + x*(6 - x)))/6; return (0.0f); } static float stbir__filter_catmullrom(float x, float s) { STBIR__UNUSED_PARAM(s); x = (float)fabs(x); if (x < 1.0f) return 1 - x*x*(2.5f - 1.5f*x); else if (x < 2.0f) return 2 - x*(4 + x*(0.5f*x - 2.5f)); return (0.0f); } static float stbir__filter_mitchell(float x, float s) { STBIR__UNUSED_PARAM(s); x = (float)fabs(x); if (x < 1.0f) return (16 + x*x*(21 * x - 36))/18; else if (x < 2.0f) return (32 + x*(-60 + x*(36 - 7*x)))/18; return (0.0f); } static float stbir__support_zero(float s) { STBIR__UNUSED_PARAM(s); return 0; } static float stbir__support_one(float s) { STBIR__UNUSED_PARAM(s); return 1; } static float stbir__support_two(float s) { STBIR__UNUSED_PARAM(s); return 2; } static stbir__filter_info stbir__filter_info_table[] = { { NULL, stbir__support_zero }, { stbir__filter_trapezoid, stbir__support_trapezoid }, { stbir__filter_triangle, stbir__support_one }, { stbir__filter_cubic, stbir__support_two }, { stbir__filter_catmullrom, stbir__support_two }, { stbir__filter_mitchell, stbir__support_two }, }; stbir__inline static int stbir__use_upsampling(float ratio) { return ratio > 1; } stbir__inline static int stbir__use_width_upsampling(stbir__info* stbir_info) { return stbir__use_upsampling(stbir_info->horizontal_scale); } stbir__inline static int stbir__use_height_upsampling(stbir__info* stbir_info) { return stbir__use_upsampling(stbir_info->vertical_scale); } // This is the maximum number of input samples that can affect an output sample // with the given filter static int stbir__get_filter_pixel_width(stbir_filter filter, float scale) { STBIR_ASSERT(filter != 0); STBIR_ASSERT(filter < STBIR__ARRAY_SIZE(stbir__filter_info_table)); if (stbir__use_upsampling(scale)) return (int)ceil(stbir__filter_info_table[filter].support(1/scale) * 2); else return (int)ceil(stbir__filter_info_table[filter].support(scale) * 2 / scale); } // This is how much to expand buffers to account for filters seeking outside // the image boundaries. static int stbir__get_filter_pixel_margin(stbir_filter filter, float scale) { return stbir__get_filter_pixel_width(filter, scale) / 2; } static int stbir__get_coefficient_width(stbir_filter filter, float scale) { if (stbir__use_upsampling(scale)) return (int)ceil(stbir__filter_info_table[filter].support(1 / scale) * 2); else return (int)ceil(stbir__filter_info_table[filter].support(scale) * 2); } static int stbir__get_contributors(float scale, stbir_filter filter, int input_size, int output_size) { if (stbir__use_upsampling(scale)) return output_size; else return (input_size + stbir__get_filter_pixel_margin(filter, scale) * 2); } static int stbir__get_total_horizontal_coefficients(stbir__info* info) { return info->horizontal_num_contributors * stbir__get_coefficient_width (info->horizontal_filter, info->horizontal_scale); } static int stbir__get_total_vertical_coefficients(stbir__info* info) { return info->vertical_num_contributors * stbir__get_coefficient_width (info->vertical_filter, info->vertical_scale); } static stbir__contributors* stbir__get_contributor(stbir__contributors* contributors, int n) { return &contributors[n]; } // For perf reasons this code is duplicated in stbir__resample_horizontal_upsample/downsample, // if you change it here change it there too. static float* stbir__get_coefficient(float* coefficients, stbir_filter filter, float scale, int n, int c) { int width = stbir__get_coefficient_width(filter, scale); return &coefficients[width*n + c]; } static int stbir__edge_wrap_slow(stbir_edge edge, int n, int max) { switch (edge) { case STBIR_EDGE_ZERO: return 0; // we'll decode the wrong pixel here, and then overwrite with 0s later case STBIR_EDGE_CLAMP: if (n < 0) return 0; if (n >= max) return max - 1; return n; // NOTREACHED case STBIR_EDGE_REFLECT: { if (n < 0) { if (n < max) return -n; else return max - 1; } if (n >= max) { int max2 = max * 2; if (n >= max2) return 0; else return max2 - n - 1; } return n; // NOTREACHED } case STBIR_EDGE_WRAP: if (n >= 0) return (n % max); else { int m = (-n) % max; if (m != 0) m = max - m; return (m); } // NOTREACHED default: STBIR_ASSERT(!"Unimplemented edge type"); return 0; } } stbir__inline static int stbir__edge_wrap(stbir_edge edge, int n, int max) { // avoid per-pixel switch if (n >= 0 && n < max) return n; return stbir__edge_wrap_slow(edge, n, max); } // What input pixels contribute to this output pixel? static void stbir__calculate_sample_range_upsample(int n, float out_filter_radius, float scale_ratio, float out_shift, int* in_first_pixel, int* in_last_pixel, float* in_center_of_out) { float out_pixel_center = (float)n + 0.5f; float out_pixel_influence_lowerbound = out_pixel_center - out_filter_radius; float out_pixel_influence_upperbound = out_pixel_center + out_filter_radius; float in_pixel_influence_lowerbound = (out_pixel_influence_lowerbound + out_shift) / scale_ratio; float in_pixel_influence_upperbound = (out_pixel_influence_upperbound + out_shift) / scale_ratio; *in_center_of_out = (out_pixel_center + out_shift) / scale_ratio; *in_first_pixel = (int)(floor(in_pixel_influence_lowerbound + 0.5)); *in_last_pixel = (int)(floor(in_pixel_influence_upperbound - 0.5)); } // What output pixels does this input pixel contribute to? static void stbir__calculate_sample_range_downsample(int n, float in_pixels_radius, float scale_ratio, float out_shift, int* out_first_pixel, int* out_last_pixel, float* out_center_of_in) { float in_pixel_center = (float)n + 0.5f; float in_pixel_influence_lowerbound = in_pixel_center - in_pixels_radius; float in_pixel_influence_upperbound = in_pixel_center + in_pixels_radius; float out_pixel_influence_lowerbound = in_pixel_influence_lowerbound * scale_ratio - out_shift; float out_pixel_influence_upperbound = in_pixel_influence_upperbound * scale_ratio - out_shift; *out_center_of_in = in_pixel_center * scale_ratio - out_shift; *out_first_pixel = (int)(floor(out_pixel_influence_lowerbound + 0.5)); *out_last_pixel = (int)(floor(out_pixel_influence_upperbound - 0.5)); } static void stbir__calculate_coefficients_upsample(stbir_filter filter, float scale, int in_first_pixel, int in_last_pixel, float in_center_of_out, stbir__contributors* contributor, float* coefficient_group) { int i; float total_filter = 0; float filter_scale; STBIR_ASSERT(in_last_pixel - in_first_pixel <= (int)ceil(stbir__filter_info_table[filter].support(1/scale) * 2)); // Taken directly from stbir__get_coefficient_width() which we can't call because we don't know if we're horizontal or vertical. contributor->n0 = in_first_pixel; contributor->n1 = in_last_pixel; STBIR_ASSERT(contributor->n1 >= contributor->n0); for (i = 0; i <= in_last_pixel - in_first_pixel; i++) { float in_pixel_center = (float)(i + in_first_pixel) + 0.5f; coefficient_group[i] = stbir__filter_info_table[filter].kernel(in_center_of_out - in_pixel_center, 1 / scale); // If the coefficient is zero, skip it. (Don't do the <0 check here, we want the influence of those outside pixels.) if (i == 0 && !coefficient_group[i]) { contributor->n0 = ++in_first_pixel; i--; continue; } total_filter += coefficient_group[i]; } // NOTE(fg): Not actually true in general, nor is there any reason to expect it should be. // It would be true in exact math but is at best approximately true in floating-point math, // and it would not make sense to try and put actual bounds on this here because it depends // on the image aspect ratio which can get pretty extreme. //STBIR_ASSERT(stbir__filter_info_table[filter].kernel((float)(in_last_pixel + 1) + 0.5f - in_center_of_out, 1/scale) == 0); STBIR_ASSERT(total_filter > 0.9); STBIR_ASSERT(total_filter < 1.1f); // Make sure it's not way off. // Make sure the sum of all coefficients is 1. filter_scale = 1 / total_filter; for (i = 0; i <= in_last_pixel - in_first_pixel; i++) coefficient_group[i] *= filter_scale; for (i = in_last_pixel - in_first_pixel; i >= 0; i--) { if (coefficient_group[i]) break; // This line has no weight. We can skip it. contributor->n1 = contributor->n0 + i - 1; } } static void stbir__calculate_coefficients_downsample(stbir_filter filter, float scale_ratio, int out_first_pixel, int out_last_pixel, float out_center_of_in, stbir__contributors* contributor, float* coefficient_group) { int i; STBIR_ASSERT(out_last_pixel - out_first_pixel <= (int)ceil(stbir__filter_info_table[filter].support(scale_ratio) * 2)); // Taken directly from stbir__get_coefficient_width() which we can't call because we don't know if we're horizontal or vertical. contributor->n0 = out_first_pixel; contributor->n1 = out_last_pixel; STBIR_ASSERT(contributor->n1 >= contributor->n0); for (i = 0; i <= out_last_pixel - out_first_pixel; i++) { float out_pixel_center = (float)(i + out_first_pixel) + 0.5f; float x = out_pixel_center - out_center_of_in; coefficient_group[i] = stbir__filter_info_table[filter].kernel(x, scale_ratio) * scale_ratio; } // NOTE(fg): Not actually true in general, nor is there any reason to expect it should be. // It would be true in exact math but is at best approximately true in floating-point math, // and it would not make sense to try and put actual bounds on this here because it depends // on the image aspect ratio which can get pretty extreme. //STBIR_ASSERT(stbir__filter_info_table[filter].kernel((float)(out_last_pixel + 1) + 0.5f - out_center_of_in, scale_ratio) == 0); for (i = out_last_pixel - out_first_pixel; i >= 0; i--) { if (coefficient_group[i]) break; // This line has no weight. We can skip it. contributor->n1 = contributor->n0 + i - 1; } } static void stbir__normalize_downsample_coefficients(stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, int input_size, int output_size) { int num_contributors = stbir__get_contributors(scale_ratio, filter, input_size, output_size); int num_coefficients = stbir__get_coefficient_width(filter, scale_ratio); int i, j; int skip; for (i = 0; i < output_size; i++) { float scale; float total = 0; for (j = 0; j < num_contributors; j++) { if (i >= contributors[j].n0 && i <= contributors[j].n1) { float coefficient = *stbir__get_coefficient(coefficients, filter, scale_ratio, j, i - contributors[j].n0); total += coefficient; } else if (i < contributors[j].n0) break; } STBIR_ASSERT(total > 0.9f); STBIR_ASSERT(total < 1.1f); scale = 1 / total; for (j = 0; j < num_contributors; j++) { if (i >= contributors[j].n0 && i <= contributors[j].n1) *stbir__get_coefficient(coefficients, filter, scale_ratio, j, i - contributors[j].n0) *= scale; else if (i < contributors[j].n0) break; } } // Optimize: Skip zero coefficients and contributions outside of image bounds. // Do this after normalizing because normalization depends on the n0/n1 values. for (j = 0; j < num_contributors; j++) { int range, max, width; skip = 0; while (*stbir__get_coefficient(coefficients, filter, scale_ratio, j, skip) == 0) skip++; contributors[j].n0 += skip; while (contributors[j].n0 < 0) { contributors[j].n0++; skip++; } range = contributors[j].n1 - contributors[j].n0 + 1; max = stbir__min(num_coefficients, range); width = stbir__get_coefficient_width(filter, scale_ratio); for (i = 0; i < max; i++) { if (i + skip >= width) break; *stbir__get_coefficient(coefficients, filter, scale_ratio, j, i) = *stbir__get_coefficient(coefficients, filter, scale_ratio, j, i + skip); } continue; } // Using min to avoid writing into invalid pixels. for (i = 0; i < num_contributors; i++) contributors[i].n1 = stbir__min(contributors[i].n1, output_size - 1); } // Each scan line uses the same kernel values so we should calculate the kernel // values once and then we can use them for every scan line. static void stbir__calculate_filters(stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, float shift, int input_size, int output_size) { int n; int total_contributors = stbir__get_contributors(scale_ratio, filter, input_size, output_size); if (stbir__use_upsampling(scale_ratio)) { float out_pixels_radius = stbir__filter_info_table[filter].support(1 / scale_ratio) * scale_ratio; // Looping through out pixels for (n = 0; n < total_contributors; n++) { float in_center_of_out; // Center of the current out pixel in the in pixel space int in_first_pixel, in_last_pixel; stbir__calculate_sample_range_upsample(n, out_pixels_radius, scale_ratio, shift, &in_first_pixel, &in_last_pixel, &in_center_of_out); stbir__calculate_coefficients_upsample(filter, scale_ratio, in_first_pixel, in_last_pixel, in_center_of_out, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0)); } } else { float in_pixels_radius = stbir__filter_info_table[filter].support(scale_ratio) / scale_ratio; // Looping through in pixels for (n = 0; n < total_contributors; n++) { float out_center_of_in; // Center of the current out pixel in the in pixel space int out_first_pixel, out_last_pixel; int n_adjusted = n - stbir__get_filter_pixel_margin(filter, scale_ratio); stbir__calculate_sample_range_downsample(n_adjusted, in_pixels_radius, scale_ratio, shift, &out_first_pixel, &out_last_pixel, &out_center_of_in); stbir__calculate_coefficients_downsample(filter, scale_ratio, out_first_pixel, out_last_pixel, out_center_of_in, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0)); } stbir__normalize_downsample_coefficients(contributors, coefficients, filter, scale_ratio, input_size, output_size); } } static float* stbir__get_decode_buffer(stbir__info* stbir_info) { // The 0 index of the decode buffer starts after the margin. This makes // it okay to use negative indexes on the decode buffer. return &stbir_info->decode_buffer[stbir_info->horizontal_filter_pixel_margin * stbir_info->channels]; } #define STBIR__DECODE(type, colorspace) ((int)(type) * (STBIR_MAX_COLORSPACES) + (int)(colorspace)) static void stbir__decode_scanline(stbir__info* stbir_info, int n) { int c; int channels = stbir_info->channels; int alpha_channel = stbir_info->alpha_channel; int type = stbir_info->type; int colorspace = stbir_info->colorspace; int input_w = stbir_info->input_w; size_t input_stride_bytes = stbir_info->input_stride_bytes; float* decode_buffer = stbir__get_decode_buffer(stbir_info); stbir_edge edge_horizontal = stbir_info->edge_horizontal; stbir_edge edge_vertical = stbir_info->edge_vertical; size_t in_buffer_row_offset = stbir__edge_wrap(edge_vertical, n, stbir_info->input_h) * input_stride_bytes; const void* input_data = (char *) stbir_info->input_data + in_buffer_row_offset; int max_x = input_w + stbir_info->horizontal_filter_pixel_margin; int decode = STBIR__DECODE(type, colorspace); int x = -stbir_info->horizontal_filter_pixel_margin; // special handling for STBIR_EDGE_ZERO because it needs to return an item that doesn't appear in the input, // and we want to avoid paying overhead on every pixel if not STBIR_EDGE_ZERO if (edge_vertical == STBIR_EDGE_ZERO && (n < 0 || n >= stbir_info->input_h)) { for (; x < max_x; x++) for (c = 0; c < channels; c++) decode_buffer[x*channels + c] = 0; return; } switch (decode) { case STBIR__DECODE(STBIR_TYPE_UINT8, STBIR_COLORSPACE_LINEAR): for (; x < max_x; x++) { int decode_pixel_index = x * channels; int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; for (c = 0; c < channels; c++) decode_buffer[decode_pixel_index + c] = ((float)((const unsigned char*)input_data)[input_pixel_index + c]) / stbir__max_uint8_as_float; } break; case STBIR__DECODE(STBIR_TYPE_UINT8, STBIR_COLORSPACE_SRGB): for (; x < max_x; x++) { int decode_pixel_index = x * channels; int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; for (c = 0; c < channels; c++) decode_buffer[decode_pixel_index + c] = stbir__srgb_uchar_to_linear_float[((const unsigned char*)input_data)[input_pixel_index + c]]; if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned char*)input_data)[input_pixel_index + alpha_channel]) / stbir__max_uint8_as_float; } break; case STBIR__DECODE(STBIR_TYPE_UINT16, STBIR_COLORSPACE_LINEAR): for (; x < max_x; x++) { int decode_pixel_index = x * channels; int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; for (c = 0; c < channels; c++) decode_buffer[decode_pixel_index + c] = ((float)((const unsigned short*)input_data)[input_pixel_index + c]) / stbir__max_uint16_as_float; } break; case STBIR__DECODE(STBIR_TYPE_UINT16, STBIR_COLORSPACE_SRGB): for (; x < max_x; x++) { int decode_pixel_index = x * channels; int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; for (c = 0; c < channels; c++) decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear(((float)((const unsigned short*)input_data)[input_pixel_index + c]) / stbir__max_uint16_as_float); if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned short*)input_data)[input_pixel_index + alpha_channel]) / stbir__max_uint16_as_float; } break; case STBIR__DECODE(STBIR_TYPE_UINT32, STBIR_COLORSPACE_LINEAR): for (; x < max_x; x++) { int decode_pixel_index = x * channels; int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; for (c = 0; c < channels; c++) decode_buffer[decode_pixel_index + c] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / stbir__max_uint32_as_float); } break; case STBIR__DECODE(STBIR_TYPE_UINT32, STBIR_COLORSPACE_SRGB): for (; x < max_x; x++) { int decode_pixel_index = x * channels; int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; for (c = 0; c < channels; c++) decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear((float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / stbir__max_uint32_as_float)); if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) decode_buffer[decode_pixel_index + alpha_channel] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + alpha_channel]) / stbir__max_uint32_as_float); } break; case STBIR__DECODE(STBIR_TYPE_FLOAT, STBIR_COLORSPACE_LINEAR): for (; x < max_x; x++) { int decode_pixel_index = x * channels; int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; for (c = 0; c < channels; c++) decode_buffer[decode_pixel_index + c] = ((const float*)input_data)[input_pixel_index + c]; } break; case STBIR__DECODE(STBIR_TYPE_FLOAT, STBIR_COLORSPACE_SRGB): for (; x < max_x; x++) { int decode_pixel_index = x * channels; int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; for (c = 0; c < channels; c++) decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear(((const float*)input_data)[input_pixel_index + c]); if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) decode_buffer[decode_pixel_index + alpha_channel] = ((const float*)input_data)[input_pixel_index + alpha_channel]; } break; default: STBIR_ASSERT(!"Unknown type/colorspace/channels combination."); break; } if (!(stbir_info->flags & STBIR_FLAG_ALPHA_PREMULTIPLIED)) { for (x = -stbir_info->horizontal_filter_pixel_margin; x < max_x; x++) { int decode_pixel_index = x * channels; // If the alpha value is 0 it will clobber the color values. Make sure it's not. float alpha = decode_buffer[decode_pixel_index + alpha_channel]; #ifndef STBIR_NO_ALPHA_EPSILON if (stbir_info->type != STBIR_TYPE_FLOAT) { alpha += STBIR_ALPHA_EPSILON; decode_buffer[decode_pixel_index + alpha_channel] = alpha; } #endif for (c = 0; c < channels; c++) { if (c == alpha_channel) continue; decode_buffer[decode_pixel_index + c] *= alpha; } } } if (edge_horizontal == STBIR_EDGE_ZERO) { for (x = -stbir_info->horizontal_filter_pixel_margin; x < 0; x++) { for (c = 0; c < channels; c++) decode_buffer[x*channels + c] = 0; } for (x = input_w; x < max_x; x++) { for (c = 0; c < channels; c++) decode_buffer[x*channels + c] = 0; } } } static float* stbir__get_ring_buffer_entry(float* ring_buffer, int index, int ring_buffer_length) { return &ring_buffer[index * ring_buffer_length]; } static float* stbir__add_empty_ring_buffer_entry(stbir__info* stbir_info, int n) { int ring_buffer_index; float* ring_buffer; stbir_info->ring_buffer_last_scanline = n; if (stbir_info->ring_buffer_begin_index < 0) { ring_buffer_index = stbir_info->ring_buffer_begin_index = 0; stbir_info->ring_buffer_first_scanline = n; } else { ring_buffer_index = (stbir_info->ring_buffer_begin_index + (stbir_info->ring_buffer_last_scanline - stbir_info->ring_buffer_first_scanline)) % stbir_info->ring_buffer_num_entries; STBIR_ASSERT(ring_buffer_index != stbir_info->ring_buffer_begin_index); } ring_buffer = stbir__get_ring_buffer_entry(stbir_info->ring_buffer, ring_buffer_index, stbir_info->ring_buffer_length_bytes / sizeof(float)); memset(ring_buffer, 0, stbir_info->ring_buffer_length_bytes); return ring_buffer; } static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, float* output_buffer) { int x, k; int output_w = stbir_info->output_w; int channels = stbir_info->channels; float* decode_buffer = stbir__get_decode_buffer(stbir_info); stbir__contributors* horizontal_contributors = stbir_info->horizontal_contributors; float* horizontal_coefficients = stbir_info->horizontal_coefficients; int coefficient_width = stbir_info->horizontal_coefficient_width; for (x = 0; x < output_w; x++) { int n0 = horizontal_contributors[x].n0; int n1 = horizontal_contributors[x].n1; int out_pixel_index = x * channels; int coefficient_group = coefficient_width * x; int coefficient_counter = 0; STBIR_ASSERT(n1 >= n0); STBIR_ASSERT(n0 >= -stbir_info->horizontal_filter_pixel_margin); STBIR_ASSERT(n1 >= -stbir_info->horizontal_filter_pixel_margin); STBIR_ASSERT(n0 < stbir_info->input_w + stbir_info->horizontal_filter_pixel_margin); STBIR_ASSERT(n1 < stbir_info->input_w + stbir_info->horizontal_filter_pixel_margin); switch (channels) { case 1: for (k = n0; k <= n1; k++) { int in_pixel_index = k * 1; float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++]; STBIR_ASSERT(coefficient != 0); output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; } break; case 2: for (k = n0; k <= n1; k++) { int in_pixel_index = k * 2; float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++]; STBIR_ASSERT(coefficient != 0); output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient; } break; case 3: for (k = n0; k <= n1; k++) { int in_pixel_index = k * 3; float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++]; STBIR_ASSERT(coefficient != 0); output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient; output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient; } break; case 4: for (k = n0; k <= n1; k++) { int in_pixel_index = k * 4; float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++]; STBIR_ASSERT(coefficient != 0); output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient; output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient; output_buffer[out_pixel_index + 3] += decode_buffer[in_pixel_index + 3] * coefficient; } break; default: for (k = n0; k <= n1; k++) { int in_pixel_index = k * channels; float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++]; int c; STBIR_ASSERT(coefficient != 0); for (c = 0; c < channels; c++) output_buffer[out_pixel_index + c] += decode_buffer[in_pixel_index + c] * coefficient; } break; } } } static void stbir__resample_horizontal_downsample(stbir__info* stbir_info, float* output_buffer) { int x, k; int input_w = stbir_info->input_w; int channels = stbir_info->channels; float* decode_buffer = stbir__get_decode_buffer(stbir_info); stbir__contributors* horizontal_contributors = stbir_info->horizontal_contributors; float* horizontal_coefficients = stbir_info->horizontal_coefficients; int coefficient_width = stbir_info->horizontal_coefficient_width; int filter_pixel_margin = stbir_info->horizontal_filter_pixel_margin; int max_x = input_w + filter_pixel_margin * 2; STBIR_ASSERT(!stbir__use_width_upsampling(stbir_info)); switch (channels) { case 1: for (x = 0; x < max_x; x++) { int n0 = horizontal_contributors[x].n0; int n1 = horizontal_contributors[x].n1; int in_x = x - filter_pixel_margin; int in_pixel_index = in_x * 1; int max_n = n1; int coefficient_group = coefficient_width * x; for (k = n0; k <= max_n; k++) { int out_pixel_index = k * 1; float coefficient = horizontal_coefficients[coefficient_group + k - n0]; output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; } } break; case 2: for (x = 0; x < max_x; x++) { int n0 = horizontal_contributors[x].n0; int n1 = horizontal_contributors[x].n1; int in_x = x - filter_pixel_margin; int in_pixel_index = in_x * 2; int max_n = n1; int coefficient_group = coefficient_width * x; for (k = n0; k <= max_n; k++) { int out_pixel_index = k * 2; float coefficient = horizontal_coefficients[coefficient_group + k - n0]; output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient; } } break; case 3: for (x = 0; x < max_x; x++) { int n0 = horizontal_contributors[x].n0; int n1 = horizontal_contributors[x].n1; int in_x = x - filter_pixel_margin; int in_pixel_index = in_x * 3; int max_n = n1; int coefficient_group = coefficient_width * x; for (k = n0; k <= max_n; k++) { int out_pixel_index = k * 3; float coefficient = horizontal_coefficients[coefficient_group + k - n0]; output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient; output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient; } } break; case 4: for (x = 0; x < max_x; x++) { int n0 = horizontal_contributors[x].n0; int n1 = horizontal_contributors[x].n1; int in_x = x - filter_pixel_margin; int in_pixel_index = in_x * 4; int max_n = n1; int coefficient_group = coefficient_width * x; for (k = n0; k <= max_n; k++) { int out_pixel_index = k * 4; float coefficient = horizontal_coefficients[coefficient_group + k - n0]; output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient; output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient; output_buffer[out_pixel_index + 3] += decode_buffer[in_pixel_index + 3] * coefficient; } } break; default: for (x = 0; x < max_x; x++) { int n0 = horizontal_contributors[x].n0; int n1 = horizontal_contributors[x].n1; int in_x = x - filter_pixel_margin; int in_pixel_index = in_x * channels; int max_n = n1; int coefficient_group = coefficient_width * x; for (k = n0; k <= max_n; k++) { int c; int out_pixel_index = k * channels; float coefficient = horizontal_coefficients[coefficient_group + k - n0]; for (c = 0; c < channels; c++) output_buffer[out_pixel_index + c] += decode_buffer[in_pixel_index + c] * coefficient; } } break; } } static void stbir__decode_and_resample_upsample(stbir__info* stbir_info, int n) { // Decode the nth scanline from the source image into the decode buffer. stbir__decode_scanline(stbir_info, n); // Now resample it into the ring buffer. if (stbir__use_width_upsampling(stbir_info)) stbir__resample_horizontal_upsample(stbir_info, stbir__add_empty_ring_buffer_entry(stbir_info, n)); else stbir__resample_horizontal_downsample(stbir_info, stbir__add_empty_ring_buffer_entry(stbir_info, n)); // Now it's sitting in the ring buffer ready to be used as source for the vertical sampling. } static void stbir__decode_and_resample_downsample(stbir__info* stbir_info, int n) { // Decode the nth scanline from the source image into the decode buffer. stbir__decode_scanline(stbir_info, n); memset(stbir_info->horizontal_buffer, 0, stbir_info->output_w * stbir_info->channels * sizeof(float)); // Now resample it into the horizontal buffer. if (stbir__use_width_upsampling(stbir_info)) stbir__resample_horizontal_upsample(stbir_info, stbir_info->horizontal_buffer); else stbir__resample_horizontal_downsample(stbir_info, stbir_info->horizontal_buffer); // Now it's sitting in the horizontal buffer ready to be distributed into the ring buffers. } // Get the specified scan line from the ring buffer. static float* stbir__get_ring_buffer_scanline(int get_scanline, float* ring_buffer, int begin_index, int first_scanline, int ring_buffer_num_entries, int ring_buffer_length) { int ring_buffer_index = (begin_index + (get_scanline - first_scanline)) % ring_buffer_num_entries; return stbir__get_ring_buffer_entry(ring_buffer, ring_buffer_index, ring_buffer_length); } static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void *output_buffer, float *encode_buffer, int channels, int alpha_channel, int decode) { int x; int n; int num_nonalpha; stbir_uint16 nonalpha[STBIR_MAX_CHANNELS]; if (!(stbir_info->flags&STBIR_FLAG_ALPHA_PREMULTIPLIED)) { for (x=0; x < num_pixels; ++x) { int pixel_index = x*channels; float alpha = encode_buffer[pixel_index + alpha_channel]; float reciprocal_alpha = alpha ? 1.0f / alpha : 0; // unrolling this produced a 1% slowdown upscaling a large RGBA linear-space image on my machine - stb for (n = 0; n < channels; n++) if (n != alpha_channel) encode_buffer[pixel_index + n] *= reciprocal_alpha; // We added in a small epsilon to prevent the color channel from being deleted with zero alpha. // Because we only add it for integer types, it will automatically be discarded on integer // conversion, so we don't need to subtract it back out (which would be problematic for // numeric precision reasons). } } // build a table of all channels that need colorspace correction, so // we don't perform colorspace correction on channels that don't need it. for (x = 0, num_nonalpha = 0; x < channels; ++x) { if (x != alpha_channel || (stbir_info->flags & STBIR_FLAG_ALPHA_USES_COLORSPACE)) { nonalpha[num_nonalpha++] = (stbir_uint16)x; } } #define STBIR__ROUND_INT(f) ((int) ((f)+0.5)) #define STBIR__ROUND_UINT(f) ((stbir_uint32) ((f)+0.5)) #ifdef STBIR__SATURATE_INT #define STBIR__ENCODE_LINEAR8(f) stbir__saturate8 (STBIR__ROUND_INT((f) * stbir__max_uint8_as_float )) #define STBIR__ENCODE_LINEAR16(f) stbir__saturate16(STBIR__ROUND_INT((f) * stbir__max_uint16_as_float)) #else #define STBIR__ENCODE_LINEAR8(f) (unsigned char ) STBIR__ROUND_INT(stbir__saturate(f) * stbir__max_uint8_as_float ) #define STBIR__ENCODE_LINEAR16(f) (unsigned short) STBIR__ROUND_INT(stbir__saturate(f) * stbir__max_uint16_as_float) #endif switch (decode) { case STBIR__DECODE(STBIR_TYPE_UINT8, STBIR_COLORSPACE_LINEAR): for (x=0; x < num_pixels; ++x) { int pixel_index = x*channels; for (n = 0; n < channels; n++) { int index = pixel_index + n; ((unsigned char*)output_buffer)[index] = STBIR__ENCODE_LINEAR8(encode_buffer[index]); } } break; case STBIR__DECODE(STBIR_TYPE_UINT8, STBIR_COLORSPACE_SRGB): for (x=0; x < num_pixels; ++x) { int pixel_index = x*channels; for (n = 0; n < num_nonalpha; n++) { int index = pixel_index + nonalpha[n]; ((unsigned char*)output_buffer)[index] = stbir__linear_to_srgb_uchar(encode_buffer[index]); } if (!(stbir_info->flags & STBIR_FLAG_ALPHA_USES_COLORSPACE)) ((unsigned char *)output_buffer)[pixel_index + alpha_channel] = STBIR__ENCODE_LINEAR8(encode_buffer[pixel_index+alpha_channel]); } break; case STBIR__DECODE(STBIR_TYPE_UINT16, STBIR_COLORSPACE_LINEAR): for (x=0; x < num_pixels; ++x) { int pixel_index = x*channels; for (n = 0; n < channels; n++) { int index = pixel_index + n; ((unsigned short*)output_buffer)[index] = STBIR__ENCODE_LINEAR16(encode_buffer[index]); } } break; case STBIR__DECODE(STBIR_TYPE_UINT16, STBIR_COLORSPACE_SRGB): for (x=0; x < num_pixels; ++x) { int pixel_index = x*channels; for (n = 0; n < num_nonalpha; n++) { int index = pixel_index + nonalpha[n]; ((unsigned short*)output_buffer)[index] = (unsigned short)STBIR__ROUND_INT(stbir__linear_to_srgb(stbir__saturate(encode_buffer[index])) * stbir__max_uint16_as_float); } if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) ((unsigned short*)output_buffer)[pixel_index + alpha_channel] = STBIR__ENCODE_LINEAR16(encode_buffer[pixel_index + alpha_channel]); } break; case STBIR__DECODE(STBIR_TYPE_UINT32, STBIR_COLORSPACE_LINEAR): for (x=0; x < num_pixels; ++x) { int pixel_index = x*channels; for (n = 0; n < channels; n++) { int index = pixel_index + n; ((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__saturate(encode_buffer[index])) * stbir__max_uint32_as_float); } } break; case STBIR__DECODE(STBIR_TYPE_UINT32, STBIR_COLORSPACE_SRGB): for (x=0; x < num_pixels; ++x) { int pixel_index = x*channels; for (n = 0; n < num_nonalpha; n++) { int index = pixel_index + nonalpha[n]; ((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__linear_to_srgb(stbir__saturate(encode_buffer[index]))) * stbir__max_uint32_as_float); } if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) ((unsigned int*)output_buffer)[pixel_index + alpha_channel] = (unsigned int)STBIR__ROUND_INT(((double)stbir__saturate(encode_buffer[pixel_index + alpha_channel])) * stbir__max_uint32_as_float); } break; case STBIR__DECODE(STBIR_TYPE_FLOAT, STBIR_COLORSPACE_LINEAR): for (x=0; x < num_pixels; ++x) { int pixel_index = x*channels; for (n = 0; n < channels; n++) { int index = pixel_index + n; ((float*)output_buffer)[index] = encode_buffer[index]; } } break; case STBIR__DECODE(STBIR_TYPE_FLOAT, STBIR_COLORSPACE_SRGB): for (x=0; x < num_pixels; ++x) { int pixel_index = x*channels; for (n = 0; n < num_nonalpha; n++) { int index = pixel_index + nonalpha[n]; ((float*)output_buffer)[index] = stbir__linear_to_srgb(encode_buffer[index]); } if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) ((float*)output_buffer)[pixel_index + alpha_channel] = encode_buffer[pixel_index + alpha_channel]; } break; default: STBIR_ASSERT(!"Unknown type/colorspace/channels combination."); break; } } static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n) { int x, k; int output_w = stbir_info->output_w; stbir__contributors* vertical_contributors = stbir_info->vertical_contributors; float* vertical_coefficients = stbir_info->vertical_coefficients; int channels = stbir_info->channels; int alpha_channel = stbir_info->alpha_channel; int type = stbir_info->type; int colorspace = stbir_info->colorspace; int ring_buffer_entries = stbir_info->ring_buffer_num_entries; void* output_data = stbir_info->output_data; float* encode_buffer = stbir_info->encode_buffer; int decode = STBIR__DECODE(type, colorspace); int coefficient_width = stbir_info->vertical_coefficient_width; int coefficient_counter; int contributor = n; float* ring_buffer = stbir_info->ring_buffer; int ring_buffer_begin_index = stbir_info->ring_buffer_begin_index; int ring_buffer_first_scanline = stbir_info->ring_buffer_first_scanline; int ring_buffer_length = stbir_info->ring_buffer_length_bytes/sizeof(float); int n0,n1, output_row_start; int coefficient_group = coefficient_width * contributor; n0 = vertical_contributors[contributor].n0; n1 = vertical_contributors[contributor].n1; output_row_start = n * stbir_info->output_stride_bytes; STBIR_ASSERT(stbir__use_height_upsampling(stbir_info)); memset(encode_buffer, 0, output_w * sizeof(float) * channels); // I tried reblocking this for better cache usage of encode_buffer // (using x_outer, k, x_inner), but it lost speed. -- stb coefficient_counter = 0; switch (channels) { case 1: for (k = n0; k <= n1; k++) { int coefficient_index = coefficient_counter++; float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length); float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; for (x = 0; x < output_w; ++x) { int in_pixel_index = x * 1; encode_buffer[in_pixel_index + 0] += ring_buffer_entry[in_pixel_index + 0] * coefficient; } } break; case 2: for (k = n0; k <= n1; k++) { int coefficient_index = coefficient_counter++; float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length); float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; for (x = 0; x < output_w; ++x) { int in_pixel_index = x * 2; encode_buffer[in_pixel_index + 0] += ring_buffer_entry[in_pixel_index + 0] * coefficient; encode_buffer[in_pixel_index + 1] += ring_buffer_entry[in_pixel_index + 1] * coefficient; } } break; case 3: for (k = n0; k <= n1; k++) { int coefficient_index = coefficient_counter++; float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length); float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; for (x = 0; x < output_w; ++x) { int in_pixel_index = x * 3; encode_buffer[in_pixel_index + 0] += ring_buffer_entry[in_pixel_index + 0] * coefficient; encode_buffer[in_pixel_index + 1] += ring_buffer_entry[in_pixel_index + 1] * coefficient; encode_buffer[in_pixel_index + 2] += ring_buffer_entry[in_pixel_index + 2] * coefficient; } } break; case 4: for (k = n0; k <= n1; k++) { int coefficient_index = coefficient_counter++; float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length); float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; for (x = 0; x < output_w; ++x) { int in_pixel_index = x * 4; encode_buffer[in_pixel_index + 0] += ring_buffer_entry[in_pixel_index + 0] * coefficient; encode_buffer[in_pixel_index + 1] += ring_buffer_entry[in_pixel_index + 1] * coefficient; encode_buffer[in_pixel_index + 2] += ring_buffer_entry[in_pixel_index + 2] * coefficient; encode_buffer[in_pixel_index + 3] += ring_buffer_entry[in_pixel_index + 3] * coefficient; } } break; default: for (k = n0; k <= n1; k++) { int coefficient_index = coefficient_counter++; float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length); float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; for (x = 0; x < output_w; ++x) { int in_pixel_index = x * channels; int c; for (c = 0; c < channels; c++) encode_buffer[in_pixel_index + c] += ring_buffer_entry[in_pixel_index + c] * coefficient; } } break; } stbir__encode_scanline(stbir_info, output_w, (char *) output_data + output_row_start, encode_buffer, channels, alpha_channel, decode); } static void stbir__resample_vertical_downsample(stbir__info* stbir_info, int n) { int x, k; int output_w = stbir_info->output_w; stbir__contributors* vertical_contributors = stbir_info->vertical_contributors; float* vertical_coefficients = stbir_info->vertical_coefficients; int channels = stbir_info->channels; int ring_buffer_entries = stbir_info->ring_buffer_num_entries; float* horizontal_buffer = stbir_info->horizontal_buffer; int coefficient_width = stbir_info->vertical_coefficient_width; int contributor = n + stbir_info->vertical_filter_pixel_margin; float* ring_buffer = stbir_info->ring_buffer; int ring_buffer_begin_index = stbir_info->ring_buffer_begin_index; int ring_buffer_first_scanline = stbir_info->ring_buffer_first_scanline; int ring_buffer_length = stbir_info->ring_buffer_length_bytes/sizeof(float); int n0,n1; n0 = vertical_contributors[contributor].n0; n1 = vertical_contributors[contributor].n1; STBIR_ASSERT(!stbir__use_height_upsampling(stbir_info)); for (k = n0; k <= n1; k++) { int coefficient_index = k - n0; int coefficient_group = coefficient_width * contributor; float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length); switch (channels) { case 1: for (x = 0; x < output_w; x++) { int in_pixel_index = x * 1; ring_buffer_entry[in_pixel_index + 0] += horizontal_buffer[in_pixel_index + 0] * coefficient; } break; case 2: for (x = 0; x < output_w; x++) { int in_pixel_index = x * 2; ring_buffer_entry[in_pixel_index + 0] += horizontal_buffer[in_pixel_index + 0] * coefficient; ring_buffer_entry[in_pixel_index + 1] += horizontal_buffer[in_pixel_index + 1] * coefficient; } break; case 3: for (x = 0; x < output_w; x++) { int in_pixel_index = x * 3; ring_buffer_entry[in_pixel_index + 0] += horizontal_buffer[in_pixel_index + 0] * coefficient; ring_buffer_entry[in_pixel_index + 1] += horizontal_buffer[in_pixel_index + 1] * coefficient; ring_buffer_entry[in_pixel_index + 2] += horizontal_buffer[in_pixel_index + 2] * coefficient; } break; case 4: for (x = 0; x < output_w; x++) { int in_pixel_index = x * 4; ring_buffer_entry[in_pixel_index + 0] += horizontal_buffer[in_pixel_index + 0] * coefficient; ring_buffer_entry[in_pixel_index + 1] += horizontal_buffer[in_pixel_index + 1] * coefficient; ring_buffer_entry[in_pixel_index + 2] += horizontal_buffer[in_pixel_index + 2] * coefficient; ring_buffer_entry[in_pixel_index + 3] += horizontal_buffer[in_pixel_index + 3] * coefficient; } break; default: for (x = 0; x < output_w; x++) { int in_pixel_index = x * channels; int c; for (c = 0; c < channels; c++) ring_buffer_entry[in_pixel_index + c] += horizontal_buffer[in_pixel_index + c] * coefficient; } break; } } } static void stbir__buffer_loop_upsample(stbir__info* stbir_info) { int y; float scale_ratio = stbir_info->vertical_scale; float out_scanlines_radius = stbir__filter_info_table[stbir_info->vertical_filter].support(1/scale_ratio) * scale_ratio; STBIR_ASSERT(stbir__use_height_upsampling(stbir_info)); for (y = 0; y < stbir_info->output_h; y++) { float in_center_of_out = 0; // Center of the current out scanline in the in scanline space int in_first_scanline = 0, in_last_scanline = 0; stbir__calculate_sample_range_upsample(y, out_scanlines_radius, scale_ratio, stbir_info->vertical_shift, &in_first_scanline, &in_last_scanline, &in_center_of_out); STBIR_ASSERT(in_last_scanline - in_first_scanline + 1 <= stbir_info->ring_buffer_num_entries); if (stbir_info->ring_buffer_begin_index >= 0) { // Get rid of whatever we don't need anymore. while (in_first_scanline > stbir_info->ring_buffer_first_scanline) { if (stbir_info->ring_buffer_first_scanline == stbir_info->ring_buffer_last_scanline) { // We just popped the last scanline off the ring buffer. // Reset it to the empty state. stbir_info->ring_buffer_begin_index = -1; stbir_info->ring_buffer_first_scanline = 0; stbir_info->ring_buffer_last_scanline = 0; break; } else { stbir_info->ring_buffer_first_scanline++; stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->ring_buffer_num_entries; } } } // Load in new ones. if (stbir_info->ring_buffer_begin_index < 0) stbir__decode_and_resample_upsample(stbir_info, in_first_scanline); while (in_last_scanline > stbir_info->ring_buffer_last_scanline) stbir__decode_and_resample_upsample(stbir_info, stbir_info->ring_buffer_last_scanline + 1); // Now all buffers should be ready to write a row of vertical sampling. stbir__resample_vertical_upsample(stbir_info, y); STBIR_PROGRESS_REPORT((float)y / stbir_info->output_h); } } static void stbir__empty_ring_buffer(stbir__info* stbir_info, int first_necessary_scanline) { int output_stride_bytes = stbir_info->output_stride_bytes; int channels = stbir_info->channels; int alpha_channel = stbir_info->alpha_channel; int type = stbir_info->type; int colorspace = stbir_info->colorspace; int output_w = stbir_info->output_w; void* output_data = stbir_info->output_data; int decode = STBIR__DECODE(type, colorspace); float* ring_buffer = stbir_info->ring_buffer; int ring_buffer_length = stbir_info->ring_buffer_length_bytes/sizeof(float); if (stbir_info->ring_buffer_begin_index >= 0) { // Get rid of whatever we don't need anymore. while (first_necessary_scanline > stbir_info->ring_buffer_first_scanline) { if (stbir_info->ring_buffer_first_scanline >= 0 && stbir_info->ring_buffer_first_scanline < stbir_info->output_h) { int output_row_start = stbir_info->ring_buffer_first_scanline * output_stride_bytes; float* ring_buffer_entry = stbir__get_ring_buffer_entry(ring_buffer, stbir_info->ring_buffer_begin_index, ring_buffer_length); stbir__encode_scanline(stbir_info, output_w, (char *) output_data + output_row_start, ring_buffer_entry, channels, alpha_channel, decode); STBIR_PROGRESS_REPORT((float)stbir_info->ring_buffer_first_scanline / stbir_info->output_h); } if (stbir_info->ring_buffer_first_scanline == stbir_info->ring_buffer_last_scanline) { // We just popped the last scanline off the ring buffer. // Reset it to the empty state. stbir_info->ring_buffer_begin_index = -1; stbir_info->ring_buffer_first_scanline = 0; stbir_info->ring_buffer_last_scanline = 0; break; } else { stbir_info->ring_buffer_first_scanline++; stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->ring_buffer_num_entries; } } } } static void stbir__buffer_loop_downsample(stbir__info* stbir_info) { int y; float scale_ratio = stbir_info->vertical_scale; int output_h = stbir_info->output_h; float in_pixels_radius = stbir__filter_info_table[stbir_info->vertical_filter].support(scale_ratio) / scale_ratio; int pixel_margin = stbir_info->vertical_filter_pixel_margin; int max_y = stbir_info->input_h + pixel_margin; STBIR_ASSERT(!stbir__use_height_upsampling(stbir_info)); for (y = -pixel_margin; y < max_y; y++) { float out_center_of_in; // Center of the current out scanline in the in scanline space int out_first_scanline, out_last_scanline; stbir__calculate_sample_range_downsample(y, in_pixels_radius, scale_ratio, stbir_info->vertical_shift, &out_first_scanline, &out_last_scanline, &out_center_of_in); STBIR_ASSERT(out_last_scanline - out_first_scanline + 1 <= stbir_info->ring_buffer_num_entries); if (out_last_scanline < 0 || out_first_scanline >= output_h) continue; stbir__empty_ring_buffer(stbir_info, out_first_scanline); stbir__decode_and_resample_downsample(stbir_info, y); // Load in new ones. if (stbir_info->ring_buffer_begin_index < 0) stbir__add_empty_ring_buffer_entry(stbir_info, out_first_scanline); while (out_last_scanline > stbir_info->ring_buffer_last_scanline) stbir__add_empty_ring_buffer_entry(stbir_info, stbir_info->ring_buffer_last_scanline + 1); // Now the horizontal buffer is ready to write to all ring buffer rows. stbir__resample_vertical_downsample(stbir_info, y); } stbir__empty_ring_buffer(stbir_info, stbir_info->output_h); } static void stbir__setup(stbir__info *info, int input_w, int input_h, int output_w, int output_h, int channels) { info->input_w = input_w; info->input_h = input_h; info->output_w = output_w; info->output_h = output_h; info->channels = channels; } static void stbir__calculate_transform(stbir__info *info, float s0, float t0, float s1, float t1, float *transform) { info->s0 = s0; info->t0 = t0; info->s1 = s1; info->t1 = t1; if (transform) { info->horizontal_scale = transform[0]; info->vertical_scale = transform[1]; info->horizontal_shift = transform[2]; info->vertical_shift = transform[3]; } else { info->horizontal_scale = ((float)info->output_w / info->input_w) / (s1 - s0); info->vertical_scale = ((float)info->output_h / info->input_h) / (t1 - t0); info->horizontal_shift = s0 * info->output_w / (s1 - s0); info->vertical_shift = t0 * info->output_h / (t1 - t0); } } static void stbir__choose_filter(stbir__info *info, stbir_filter h_filter, stbir_filter v_filter) { if (h_filter == 0) h_filter = stbir__use_upsampling(info->horizontal_scale) ? STBIR_DEFAULT_FILTER_UPSAMPLE : STBIR_DEFAULT_FILTER_DOWNSAMPLE; if (v_filter == 0) v_filter = stbir__use_upsampling(info->vertical_scale) ? STBIR_DEFAULT_FILTER_UPSAMPLE : STBIR_DEFAULT_FILTER_DOWNSAMPLE; info->horizontal_filter = h_filter; info->vertical_filter = v_filter; } static stbir_uint32 stbir__calculate_memory(stbir__info *info) { int pixel_margin = stbir__get_filter_pixel_margin(info->horizontal_filter, info->horizontal_scale); int filter_height = stbir__get_filter_pixel_width(info->vertical_filter, info->vertical_scale); info->horizontal_num_contributors = stbir__get_contributors(info->horizontal_scale, info->horizontal_filter, info->input_w, info->output_w); info->vertical_num_contributors = stbir__get_contributors(info->vertical_scale , info->vertical_filter , info->input_h, info->output_h); // One extra entry because floating point precision problems sometimes cause an extra to be necessary. info->ring_buffer_num_entries = filter_height + 1; info->horizontal_contributors_size = info->horizontal_num_contributors * sizeof(stbir__contributors); info->horizontal_coefficients_size = stbir__get_total_horizontal_coefficients(info) * sizeof(float); info->vertical_contributors_size = info->vertical_num_contributors * sizeof(stbir__contributors); info->vertical_coefficients_size = stbir__get_total_vertical_coefficients(info) * sizeof(float); info->decode_buffer_size = (info->input_w + pixel_margin * 2) * info->channels * sizeof(float); info->horizontal_buffer_size = info->output_w * info->channels * sizeof(float); info->ring_buffer_size = info->output_w * info->channels * info->ring_buffer_num_entries * sizeof(float); info->encode_buffer_size = info->output_w * info->channels * sizeof(float); STBIR_ASSERT(info->horizontal_filter != 0); STBIR_ASSERT(info->horizontal_filter < STBIR__ARRAY_SIZE(stbir__filter_info_table)); // this now happens too late STBIR_ASSERT(info->vertical_filter != 0); STBIR_ASSERT(info->vertical_filter < STBIR__ARRAY_SIZE(stbir__filter_info_table)); // this now happens too late if (stbir__use_height_upsampling(info)) // The horizontal buffer is for when we're downsampling the height and we // can't output the result of sampling the decode buffer directly into the // ring buffers. info->horizontal_buffer_size = 0; else // The encode buffer is to retain precision in the height upsampling method // and isn't used when height downsampling. info->encode_buffer_size = 0; return info->horizontal_contributors_size + info->horizontal_coefficients_size + info->vertical_contributors_size + info->vertical_coefficients_size + info->decode_buffer_size + info->horizontal_buffer_size + info->ring_buffer_size + info->encode_buffer_size; } static int stbir__resize_allocated(stbir__info *info, const void* input_data, int input_stride_in_bytes, void* output_data, int output_stride_in_bytes, int alpha_channel, stbir_uint32 flags, stbir_datatype type, stbir_edge edge_horizontal, stbir_edge edge_vertical, stbir_colorspace colorspace, void* tempmem, size_t tempmem_size_in_bytes) { size_t memory_required = stbir__calculate_memory(info); int width_stride_input = input_stride_in_bytes ? input_stride_in_bytes : info->channels * info->input_w * stbir__type_size[type]; int width_stride_output = output_stride_in_bytes ? output_stride_in_bytes : info->channels * info->output_w * stbir__type_size[type]; #ifdef STBIR_DEBUG_OVERWRITE_TEST #define OVERWRITE_ARRAY_SIZE 8 unsigned char overwrite_output_before_pre[OVERWRITE_ARRAY_SIZE]; unsigned char overwrite_tempmem_before_pre[OVERWRITE_ARRAY_SIZE]; unsigned char overwrite_output_after_pre[OVERWRITE_ARRAY_SIZE]; unsigned char overwrite_tempmem_after_pre[OVERWRITE_ARRAY_SIZE]; size_t begin_forbidden = width_stride_output * (info->output_h - 1) + info->output_w * info->channels * stbir__type_size[type]; memcpy(overwrite_output_before_pre, &((unsigned char*)output_data)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE); memcpy(overwrite_output_after_pre, &((unsigned char*)output_data)[begin_forbidden], OVERWRITE_ARRAY_SIZE); memcpy(overwrite_tempmem_before_pre, &((unsigned char*)tempmem)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE); memcpy(overwrite_tempmem_after_pre, &((unsigned char*)tempmem)[tempmem_size_in_bytes], OVERWRITE_ARRAY_SIZE); #endif STBIR_ASSERT(info->channels >= 0); STBIR_ASSERT(info->channels <= STBIR_MAX_CHANNELS); if (info->channels < 0 || info->channels > STBIR_MAX_CHANNELS) return 0; STBIR_ASSERT(info->horizontal_filter < STBIR__ARRAY_SIZE(stbir__filter_info_table)); STBIR_ASSERT(info->vertical_filter < STBIR__ARRAY_SIZE(stbir__filter_info_table)); if (info->horizontal_filter >= STBIR__ARRAY_SIZE(stbir__filter_info_table)) return 0; if (info->vertical_filter >= STBIR__ARRAY_SIZE(stbir__filter_info_table)) return 0; if (alpha_channel < 0) flags |= STBIR_FLAG_ALPHA_USES_COLORSPACE | STBIR_FLAG_ALPHA_PREMULTIPLIED; if (!(flags&STBIR_FLAG_ALPHA_USES_COLORSPACE) || !(flags&STBIR_FLAG_ALPHA_PREMULTIPLIED)) { STBIR_ASSERT(alpha_channel >= 0 && alpha_channel < info->channels); } if (alpha_channel >= info->channels) return 0; STBIR_ASSERT(tempmem); if (!tempmem) return 0; STBIR_ASSERT(tempmem_size_in_bytes >= memory_required); if (tempmem_size_in_bytes < memory_required) return 0; memset(tempmem, 0, tempmem_size_in_bytes); info->input_data = input_data; info->input_stride_bytes = width_stride_input; info->output_data = output_data; info->output_stride_bytes = width_stride_output; info->alpha_channel = alpha_channel; info->flags = flags; info->type = type; info->edge_horizontal = edge_horizontal; info->edge_vertical = edge_vertical; info->colorspace = colorspace; info->horizontal_coefficient_width = stbir__get_coefficient_width (info->horizontal_filter, info->horizontal_scale); info->vertical_coefficient_width = stbir__get_coefficient_width (info->vertical_filter , info->vertical_scale ); info->horizontal_filter_pixel_width = stbir__get_filter_pixel_width (info->horizontal_filter, info->horizontal_scale); info->vertical_filter_pixel_width = stbir__get_filter_pixel_width (info->vertical_filter , info->vertical_scale ); info->horizontal_filter_pixel_margin = stbir__get_filter_pixel_margin(info->horizontal_filter, info->horizontal_scale); info->vertical_filter_pixel_margin = stbir__get_filter_pixel_margin(info->vertical_filter , info->vertical_scale ); info->ring_buffer_length_bytes = info->output_w * info->channels * sizeof(float); info->decode_buffer_pixels = info->input_w + info->horizontal_filter_pixel_margin * 2; #define STBIR__NEXT_MEMPTR(current, newtype) (newtype*)(((unsigned char*)current) + current##_size) info->horizontal_contributors = (stbir__contributors *) tempmem; info->horizontal_coefficients = STBIR__NEXT_MEMPTR(info->horizontal_contributors, float); info->vertical_contributors = STBIR__NEXT_MEMPTR(info->horizontal_coefficients, stbir__contributors); info->vertical_coefficients = STBIR__NEXT_MEMPTR(info->vertical_contributors, float); info->decode_buffer = STBIR__NEXT_MEMPTR(info->vertical_coefficients, float); if (stbir__use_height_upsampling(info)) { info->horizontal_buffer = NULL; info->ring_buffer = STBIR__NEXT_MEMPTR(info->decode_buffer, float); info->encode_buffer = STBIR__NEXT_MEMPTR(info->ring_buffer, float); STBIR_ASSERT((size_t)STBIR__NEXT_MEMPTR(info->encode_buffer, unsigned char) == (size_t)tempmem + tempmem_size_in_bytes); } else { info->horizontal_buffer = STBIR__NEXT_MEMPTR(info->decode_buffer, float); info->ring_buffer = STBIR__NEXT_MEMPTR(info->horizontal_buffer, float); info->encode_buffer = NULL; STBIR_ASSERT((size_t)STBIR__NEXT_MEMPTR(info->ring_buffer, unsigned char) == (size_t)tempmem + tempmem_size_in_bytes); } #undef STBIR__NEXT_MEMPTR // This signals that the ring buffer is empty info->ring_buffer_begin_index = -1; stbir__calculate_filters(info->horizontal_contributors, info->horizontal_coefficients, info->horizontal_filter, info->horizontal_scale, info->horizontal_shift, info->input_w, info->output_w); stbir__calculate_filters(info->vertical_contributors, info->vertical_coefficients, info->vertical_filter, info->vertical_scale, info->vertical_shift, info->input_h, info->output_h); STBIR_PROGRESS_REPORT(0); if (stbir__use_height_upsampling(info)) stbir__buffer_loop_upsample(info); else stbir__buffer_loop_downsample(info); STBIR_PROGRESS_REPORT(1); #ifdef STBIR_DEBUG_OVERWRITE_TEST STBIR_ASSERT(memcmp(overwrite_output_before_pre, &((unsigned char*)output_data)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE) == 0); STBIR_ASSERT(memcmp(overwrite_output_after_pre, &((unsigned char*)output_data)[begin_forbidden], OVERWRITE_ARRAY_SIZE) == 0); STBIR_ASSERT(memcmp(overwrite_tempmem_before_pre, &((unsigned char*)tempmem)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE) == 0); STBIR_ASSERT(memcmp(overwrite_tempmem_after_pre, &((unsigned char*)tempmem)[tempmem_size_in_bytes], OVERWRITE_ARRAY_SIZE) == 0); #endif return 1; } static int stbir__resize_arbitrary( void *alloc_context, const void* input_data, int input_w, int input_h, int input_stride_in_bytes, void* output_data, int output_w, int output_h, int output_stride_in_bytes, float s0, float t0, float s1, float t1, float *transform, int channels, int alpha_channel, stbir_uint32 flags, stbir_datatype type, stbir_filter h_filter, stbir_filter v_filter, stbir_edge edge_horizontal, stbir_edge edge_vertical, stbir_colorspace colorspace) { stbir__info info; int result; size_t memory_required; void* extra_memory; stbir__setup(&info, input_w, input_h, output_w, output_h, channels); stbir__calculate_transform(&info, s0,t0,s1,t1,transform); stbir__choose_filter(&info, h_filter, v_filter); memory_required = stbir__calculate_memory(&info); extra_memory = STBIR_MALLOC(memory_required, alloc_context); if (!extra_memory) return 0; result = stbir__resize_allocated(&info, input_data, input_stride_in_bytes, output_data, output_stride_in_bytes, alpha_channel, flags, type, edge_horizontal, edge_vertical, colorspace, extra_memory, memory_required); STBIR_FREE(extra_memory, alloc_context); return result; } STBIRDEF int stbir_resize_uint8( const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, int num_channels) { return stbir__resize_arbitrary(NULL, input_pixels, input_w, input_h, input_stride_in_bytes, output_pixels, output_w, output_h, output_stride_in_bytes, 0,0,1,1,NULL,num_channels,-1,0, STBIR_TYPE_UINT8, STBIR_FILTER_DEFAULT, STBIR_FILTER_DEFAULT, STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_COLORSPACE_LINEAR); } STBIRDEF int stbir_resize_float( const float *input_pixels , int input_w , int input_h , int input_stride_in_bytes, float *output_pixels, int output_w, int output_h, int output_stride_in_bytes, int num_channels) { return stbir__resize_arbitrary(NULL, input_pixels, input_w, input_h, input_stride_in_bytes, output_pixels, output_w, output_h, output_stride_in_bytes, 0,0,1,1,NULL,num_channels,-1,0, STBIR_TYPE_FLOAT, STBIR_FILTER_DEFAULT, STBIR_FILTER_DEFAULT, STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_COLORSPACE_LINEAR); } STBIRDEF int stbir_resize_uint8_srgb(const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, int num_channels, int alpha_channel, int flags) { return stbir__resize_arbitrary(NULL, input_pixels, input_w, input_h, input_stride_in_bytes, output_pixels, output_w, output_h, output_stride_in_bytes, 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_UINT8, STBIR_FILTER_DEFAULT, STBIR_FILTER_DEFAULT, STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_COLORSPACE_SRGB); } STBIRDEF int stbir_resize_uint8_srgb_edgemode(const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, int num_channels, int alpha_channel, int flags, stbir_edge edge_wrap_mode) { return stbir__resize_arbitrary(NULL, input_pixels, input_w, input_h, input_stride_in_bytes, output_pixels, output_w, output_h, output_stride_in_bytes, 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_UINT8, STBIR_FILTER_DEFAULT, STBIR_FILTER_DEFAULT, edge_wrap_mode, edge_wrap_mode, STBIR_COLORSPACE_SRGB); } STBIRDEF int stbir_resize_uint8_generic( const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, int num_channels, int alpha_channel, int flags, stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, void *alloc_context) { return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes, output_pixels, output_w, output_h, output_stride_in_bytes, 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_UINT8, filter, filter, edge_wrap_mode, edge_wrap_mode, space); } STBIRDEF int stbir_resize_uint16_generic(const stbir_uint16 *input_pixels , int input_w , int input_h , int input_stride_in_bytes, stbir_uint16 *output_pixels , int output_w, int output_h, int output_stride_in_bytes, int num_channels, int alpha_channel, int flags, stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, void *alloc_context) { return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes, output_pixels, output_w, output_h, output_stride_in_bytes, 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_UINT16, filter, filter, edge_wrap_mode, edge_wrap_mode, space); } STBIRDEF int stbir_resize_float_generic( const float *input_pixels , int input_w , int input_h , int input_stride_in_bytes, float *output_pixels , int output_w, int output_h, int output_stride_in_bytes, int num_channels, int alpha_channel, int flags, stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, void *alloc_context) { return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes, output_pixels, output_w, output_h, output_stride_in_bytes, 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_FLOAT, filter, filter, edge_wrap_mode, edge_wrap_mode, space); } STBIRDEF int stbir_resize( const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, stbir_datatype datatype, int num_channels, int alpha_channel, int flags, stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, stbir_filter filter_horizontal, stbir_filter filter_vertical, stbir_colorspace space, void *alloc_context) { return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes, output_pixels, output_w, output_h, output_stride_in_bytes, 0,0,1,1,NULL,num_channels,alpha_channel,flags, datatype, filter_horizontal, filter_vertical, edge_mode_horizontal, edge_mode_vertical, space); } STBIRDEF int stbir_resize_subpixel(const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, stbir_datatype datatype, int num_channels, int alpha_channel, int flags, stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, stbir_filter filter_horizontal, stbir_filter filter_vertical, stbir_colorspace space, void *alloc_context, float x_scale, float y_scale, float x_offset, float y_offset) { float transform[4]; transform[0] = x_scale; transform[1] = y_scale; transform[2] = x_offset; transform[3] = y_offset; return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes, output_pixels, output_w, output_h, output_stride_in_bytes, 0,0,1,1,transform,num_channels,alpha_channel,flags, datatype, filter_horizontal, filter_vertical, edge_mode_horizontal, edge_mode_vertical, space); } STBIRDEF int stbir_resize_region( const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, stbir_datatype datatype, int num_channels, int alpha_channel, int flags, stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, stbir_filter filter_horizontal, stbir_filter filter_vertical, stbir_colorspace space, void *alloc_context, float s0, float t0, float s1, float t1) { return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes, output_pixels, output_w, output_h, output_stride_in_bytes, s0,t0,s1,t1,NULL,num_channels,alpha_channel,flags, datatype, filter_horizontal, filter_vertical, edge_mode_horizontal, edge_mode_vertical, space); } #endif // STB_IMAGE_RESIZE_IMPLEMENTATION /* ------------------------------------------------------------------------------ This software is available under 2 licenses -- choose whichever you prefer. ------------------------------------------------------------------------------ ALTERNATIVE A - MIT License Copyright (c) 2017 Sean Barrett Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ ALTERNATIVE B - Public Domain (www.unlicense.org) This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ */ chawan-v0.4.0/adapter/img/stb_image_write.h000066400000000000000000002134151520232313100206510ustar00rootroot00000000000000/* stb_image_write - v1.16 - public domain - http://nothings.org/stb writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015 no warranty implied; use at your own risk Before #including, #define STB_IMAGE_WRITE_IMPLEMENTATION in the file that you want to have the implementation. Will probably not work correctly with strict-aliasing optimizations. ABOUT: This header file is a library for writing images to C stdio or a callback. The PNG output is not optimal; it is 20-50% larger than the file written by a decent optimizing implementation; though providing a custom zlib compress function (see STBIW_ZLIB_COMPRESS) can mitigate that. This library is designed for source code compactness and simplicity, not optimal image file size or run-time performance. BUILDING: You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h. You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace malloc,realloc,free. You can #define STBIW_MEMMOVE() to replace memmove() You can #define STBIW_ZLIB_COMPRESS to use a custom zlib-style compress function for PNG compression (instead of the builtin one), it must have the following signature: unsigned char * my_compress(unsigned char *data, int data_len, int *out_len, int quality); The returned data will be freed with STBIW_FREE() (free() by default), so it must be heap allocated with STBIW_MALLOC() (malloc() by default), UNICODE: If compiling for Windows and you wish to use Unicode filenames, compile with #define STBIW_WINDOWS_UTF8 and pass utf8-encoded filenames. Call stbiw_convert_wchar_to_utf8 to convert Windows wchar_t filenames to utf8. USAGE: There are five functions, one for each image file format: int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); int stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality); int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); void stbi_flip_vertically_on_write(int flag); // flag is non-zero to flip data vertically There are also five equivalent functions that use an arbitrary write function. You are expected to open/close your file-equivalent before and after calling these: int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality); where the callback is: void stbi_write_func(void *context, void *data, int size); You can configure it with these global variables: int stbi_write_tga_with_rle; // defaults to true; set to 0 to disable RLE int stbi_write_png_compression_level; // defaults to 8; set to higher for more compression int stbi_write_force_png_filter; // defaults to -1; set to 0..5 to force a filter mode You can define STBI_WRITE_NO_STDIO to disable the file variant of these functions, so the library will not use stdio.h at all. However, this will also disable HDR writing, because it requires stdio for formatted output. Each function returns 0 on failure and non-0 on success. The functions create an image file defined by the parameters. The image is a rectangle of pixels stored from left-to-right, top-to-bottom. Each pixel contains 'comp' channels of data stored interleaved with 8-bits per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall. The *data pointer points to the first byte of the top-left-most pixel. For PNG, "stride_in_bytes" is the distance in bytes from the first byte of a row of pixels to the first byte of the next row of pixels. PNG creates output files with the same number of components as the input. The BMP format expands Y to RGB in the file format and does not output alpha. PNG supports writing rectangles of data even when the bytes storing rows of data are not consecutive in memory (e.g. sub-rectangles of a larger image), by supplying the stride between the beginning of adjacent rows. The other formats do not. (Thus you cannot write a native-format BMP through the BMP writer, both because it is in BGR order and because it may have padding at the end of the line.) PNG allows you to set the deflate compression level by setting the global variable 'stbi_write_png_compression_level' (it defaults to 8). HDR expects linear float data. Since the format is always 32-bit rgb(e) data, alpha (if provided) is discarded, and for monochrome data it is replicated across all three channels. TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed data, set the global variable 'stbi_write_tga_with_rle' to 0. JPEG does ignore alpha channels in input data; quality is between 1 and 100. Higher quality looks better but results in a bigger image. JPEG baseline (no JPEG progressive). CREDITS: Sean Barrett - PNG/BMP/TGA Baldur Karlsson - HDR Jean-Sebastien Guay - TGA monochrome Tim Kelsey - misc enhancements Alan Hickman - TGA RLE Emmanuel Julien - initial file IO callback implementation Jon Olick - original jo_jpeg.cpp code Daniel Gibson - integrate JPEG, allow external zlib Aarni Koskela - allow choosing PNG filter bugfixes: github:Chribba Guillaume Chereau github:jry2 github:romigrou Sergio Gonzalez Jonas Karlsson Filip Wasil Thatcher Ulrich github:poppolopoppo Patrick Boettcher github:xeekworx Cap Petschulat Simon Rodriguez Ivan Tikhonov github:ignotion Adam Schackart Andrew Kensler LICENSE See end of file for license information. */ #ifndef INCLUDE_STB_IMAGE_WRITE_H #define INCLUDE_STB_IMAGE_WRITE_H #include // if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline' #ifndef STBIWDEF #ifdef STB_IMAGE_WRITE_STATIC #define STBIWDEF static #else #ifdef __cplusplus #define STBIWDEF extern "C" #else #define STBIWDEF extern #endif #endif #endif #ifndef STB_IMAGE_WRITE_STATIC // C++ forbids static forward declarations STBIWDEF int stbi_write_tga_with_rle; STBIWDEF int stbi_write_png_compression_level; STBIWDEF int stbi_write_force_png_filter; #endif #ifndef STBI_WRITE_NO_STDIO STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality); #ifdef STBIW_WINDOWS_UTF8 STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input); #endif #endif typedef void stbi_write_func(void *context, void *data, int size); STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality); STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean); #endif//INCLUDE_STB_IMAGE_WRITE_H #ifdef STB_IMAGE_WRITE_IMPLEMENTATION #ifdef _WIN32 #ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #endif #ifndef _CRT_NONSTDC_NO_DEPRECATE #define _CRT_NONSTDC_NO_DEPRECATE #endif #endif #ifndef STBI_WRITE_NO_STDIO #include #endif // STBI_WRITE_NO_STDIO #include #include #include #include #if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED)) // ok #elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED) // ok #else #error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)." #endif #ifndef STBIW_MALLOC #define STBIW_MALLOC(sz) malloc(sz) #define STBIW_REALLOC(p,newsz) realloc(p,newsz) #define STBIW_FREE(p) free(p) #endif #ifndef STBIW_REALLOC_SIZED #define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz) #endif #ifndef STBIW_MEMMOVE #define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz) #endif #ifndef STBIW_ASSERT #include #define STBIW_ASSERT(x) assert(x) #endif #define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff) #ifdef STB_IMAGE_WRITE_STATIC static int stbi_write_png_compression_level = 8; static int stbi_write_tga_with_rle = 1; static int stbi_write_force_png_filter = -1; #else int stbi_write_png_compression_level = 8; int stbi_write_tga_with_rle = 1; int stbi_write_force_png_filter = -1; #endif static int stbi__flip_vertically_on_write = 0; STBIWDEF void stbi_flip_vertically_on_write(int flag) { stbi__flip_vertically_on_write = flag; } typedef struct { stbi_write_func *func; void *context; unsigned char buffer[64]; int buf_used; } stbi__write_context; // initialize a callback-based context static void stbi__start_write_callbacks(stbi__write_context *s, stbi_write_func *c, void *context) { s->func = c; s->context = context; } #ifndef STBI_WRITE_NO_STDIO static void stbi__stdio_write(void *context, void *data, int size) { fwrite(data,1,size,(FILE*) context); } #if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8) #ifdef __cplusplus #define STBIW_EXTERN extern "C" #else #define STBIW_EXTERN extern #endif STBIW_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide); STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default); STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) { return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); } #endif static FILE *stbiw__fopen(char const *filename, char const *mode) { FILE *f; #if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8) wchar_t wMode[64]; wchar_t wFilename[1024]; if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename))) return 0; if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode))) return 0; #if defined(_MSC_VER) && _MSC_VER >= 1400 if (0 != _wfopen_s(&f, wFilename, wMode)) f = 0; #else f = _wfopen(wFilename, wMode); #endif #elif defined(_MSC_VER) && _MSC_VER >= 1400 if (0 != fopen_s(&f, filename, mode)) f=0; #else f = fopen(filename, mode); #endif return f; } static int stbi__start_write_file(stbi__write_context *s, const char *filename) { FILE *f = stbiw__fopen(filename, "wb"); stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f); return f != NULL; } static void stbi__end_write_file(stbi__write_context *s) { fclose((FILE *)s->context); } #endif // !STBI_WRITE_NO_STDIO typedef unsigned int stbiw_uint32; typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1]; static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v) { while (*fmt) { switch (*fmt++) { case ' ': break; case '1': { unsigned char x = STBIW_UCHAR(va_arg(v, int)); s->func(s->context,&x,1); break; } case '2': { int x = va_arg(v,int); unsigned char b[2]; b[0] = STBIW_UCHAR(x); b[1] = STBIW_UCHAR(x>>8); s->func(s->context,b,2); break; } case '4': { stbiw_uint32 x = va_arg(v,int); unsigned char b[4]; b[0]=STBIW_UCHAR(x); b[1]=STBIW_UCHAR(x>>8); b[2]=STBIW_UCHAR(x>>16); b[3]=STBIW_UCHAR(x>>24); s->func(s->context,b,4); break; } default: STBIW_ASSERT(0); return; } } } static void stbiw__writef(stbi__write_context *s, const char *fmt, ...) { va_list v; va_start(v, fmt); stbiw__writefv(s, fmt, v); va_end(v); } static void stbiw__write_flush(stbi__write_context *s) { if (s->buf_used) { s->func(s->context, &s->buffer, s->buf_used); s->buf_used = 0; } } static void stbiw__putc(stbi__write_context *s, unsigned char c) { s->func(s->context, &c, 1); } static void stbiw__write1(stbi__write_context *s, unsigned char a) { if ((size_t)s->buf_used + 1 > sizeof(s->buffer)) stbiw__write_flush(s); s->buffer[s->buf_used++] = a; } static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c) { int n; if ((size_t)s->buf_used + 3 > sizeof(s->buffer)) stbiw__write_flush(s); n = s->buf_used; s->buf_used = n+3; s->buffer[n+0] = a; s->buffer[n+1] = b; s->buffer[n+2] = c; } static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d) { unsigned char bg[3] = { 255, 0, 255}, px[3]; int k; if (write_alpha < 0) stbiw__write1(s, d[comp - 1]); switch (comp) { case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case case 1: if (expand_mono) stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp else stbiw__write1(s, d[0]); // monochrome TGA break; case 4: if (!write_alpha) { // composite against pink background for (k = 0; k < 3; ++k) px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255; stbiw__write3(s, px[1 - rgb_dir], px[1], px[1 + rgb_dir]); break; } /* FALLTHROUGH */ case 3: stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]); break; } if (write_alpha > 0) stbiw__write1(s, d[comp - 1]); } static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono) { stbiw_uint32 zero = 0; int i,j, j_end; if (y <= 0) return; if (stbi__flip_vertically_on_write) vdir *= -1; if (vdir < 0) { j_end = -1; j = y-1; } else { j_end = y; j = 0; } for (; j != j_end; j += vdir) { for (i=0; i < x; ++i) { unsigned char *d = (unsigned char *) data + (j*x+i)*comp; stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d); } stbiw__write_flush(s); s->func(s->context, &zero, scanline_pad); } } static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, int expand_mono, void *data, int alpha, int pad, const char *fmt, ...) { if (y < 0 || x < 0) { return 0; } else { va_list v; va_start(v, fmt); stbiw__writefv(s, fmt, v); va_end(v); stbiw__write_pixels(s,rgb_dir,vdir,x,y,comp,data,alpha,pad, expand_mono); return 1; } } static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data) { if (comp != 4) { // write RGB bitmap int pad = (-x*3) & 3; return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad, "11 4 22 4" "4 44 22 444444", 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header } else { // RGBA bitmaps need a v4 header // use BI_BITFIELDS mode with 32bpp and alpha mask // (straight BI_RGB with alpha mask doesn't work in most readers) return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *)data,1,0, "11 4 22 4" "4 44 22 444444 4444 4 444 444 444 444", 'B', 'M', 14+108+x*y*4, 0, 0, 14+108, // file header 108, x,y, 1,32, 3,0,0,0,0,0, 0xff0000,0xff00,0xff,0xff000000u, 0, 0,0,0, 0,0,0, 0,0,0, 0,0,0); // bitmap V4 header } } STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) { stbi__write_context s = { 0 }; stbi__start_write_callbacks(&s, func, context); return stbi_write_bmp_core(&s, x, y, comp, data); } #ifndef STBI_WRITE_NO_STDIO STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data) { stbi__write_context s = { 0 }; if (stbi__start_write_file(&s,filename)) { int r = stbi_write_bmp_core(&s, x, y, comp, data); stbi__end_write_file(&s); return r; } else return 0; } #endif //!STBI_WRITE_NO_STDIO static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, void *data) { int has_alpha = (comp == 2 || comp == 4); int colorbytes = has_alpha ? comp-1 : comp; int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3 if (y < 0 || x < 0) return 0; if (!stbi_write_tga_with_rle) { return stbiw__outfile(s, -1, -1, x, y, comp, 0, (void *) data, has_alpha, 0, "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8); } else { int i,j,k; int jend, jdir; stbiw__writef(s, "111 221 2222 11", 0,0,format+8, 0,0,0, 0,0,x,y, (colorbytes + has_alpha) * 8, has_alpha * 8); if (stbi__flip_vertically_on_write) { j = 0; jend = y; jdir = 1; } else { j = y-1; jend = -1; jdir = -1; } for (; j != jend; j += jdir) { unsigned char *row = (unsigned char *) data + j * x * comp; int len; for (i = 0; i < x; i += len) { unsigned char *begin = row + i * comp; int diff = 1; len = 1; if (i < x - 1) { ++len; diff = memcmp(begin, row + (i + 1) * comp, comp); if (diff) { const unsigned char *prev = begin; for (k = i + 2; k < x && len < 128; ++k) { if (memcmp(prev, row + k * comp, comp)) { prev += comp; ++len; } else { --len; break; } } } else { for (k = i + 2; k < x && len < 128; ++k) { if (!memcmp(begin, row + k * comp, comp)) { ++len; } else { break; } } } } if (diff) { unsigned char header = STBIW_UCHAR(len - 1); stbiw__write1(s, header); for (k = 0; k < len; ++k) { stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp); } } else { unsigned char header = STBIW_UCHAR(len - 129); stbiw__write1(s, header); stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin); } } } stbiw__write_flush(s); } return 1; } STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) { stbi__write_context s = { 0 }; stbi__start_write_callbacks(&s, func, context); return stbi_write_tga_core(&s, x, y, comp, (void *) data); } #ifndef STBI_WRITE_NO_STDIO STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data) { stbi__write_context s = { 0 }; if (stbi__start_write_file(&s,filename)) { int r = stbi_write_tga_core(&s, x, y, comp, (void *) data); stbi__end_write_file(&s); return r; } else return 0; } #endif // ************************************************************************************************* // Radiance RGBE HDR writer // by Baldur Karlsson #define stbiw__max(a, b) ((a) > (b) ? (a) : (b)) #ifndef STBI_WRITE_NO_STDIO static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear) { int exponent; float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2])); if (maxcomp < 1e-32f) { rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0; } else { float normalize = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp; rgbe[0] = (unsigned char)(linear[0] * normalize); rgbe[1] = (unsigned char)(linear[1] * normalize); rgbe[2] = (unsigned char)(linear[2] * normalize); rgbe[3] = (unsigned char)(exponent + 128); } } static void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte) { unsigned char lengthbyte = STBIW_UCHAR(length+128); STBIW_ASSERT(length+128 <= 255); s->func(s->context, &lengthbyte, 1); s->func(s->context, &databyte, 1); } static void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data) { unsigned char lengthbyte = STBIW_UCHAR(length); STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code s->func(s->context, &lengthbyte, 1); s->func(s->context, data, length); } static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline) { unsigned char scanlineheader[4] = { 2, 2, 0, 0 }; unsigned char rgbe[4]; float linear[3]; int x; scanlineheader[2] = (width&0xff00)>>8; scanlineheader[3] = (width&0x00ff); /* skip RLE for images too small or large */ if (width < 8 || width >= 32768) { for (x=0; x < width; x++) { switch (ncomp) { case 4: /* fallthrough */ case 3: linear[2] = scanline[x*ncomp + 2]; linear[1] = scanline[x*ncomp + 1]; linear[0] = scanline[x*ncomp + 0]; break; default: linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0]; break; } stbiw__linear_to_rgbe(rgbe, linear); s->func(s->context, rgbe, 4); } } else { int c,r; /* encode into scratch buffer */ for (x=0; x < width; x++) { switch(ncomp) { case 4: /* fallthrough */ case 3: linear[2] = scanline[x*ncomp + 2]; linear[1] = scanline[x*ncomp + 1]; linear[0] = scanline[x*ncomp + 0]; break; default: linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0]; break; } stbiw__linear_to_rgbe(rgbe, linear); scratch[x + width*0] = rgbe[0]; scratch[x + width*1] = rgbe[1]; scratch[x + width*2] = rgbe[2]; scratch[x + width*3] = rgbe[3]; } s->func(s->context, scanlineheader, 4); /* RLE each component separately */ for (c=0; c < 4; c++) { unsigned char *comp = &scratch[width*c]; x = 0; while (x < width) { // find first run r = x; while (r+2 < width) { if (comp[r] == comp[r+1] && comp[r] == comp[r+2]) break; ++r; } if (r+2 >= width) r = width; // dump up to first run while (x < r) { int len = r-x; if (len > 128) len = 128; stbiw__write_dump_data(s, len, &comp[x]); x += len; } // if there's a run, output it if (r+2 < width) { // same test as what we break out of in search loop, so only true if we break'd // find next byte after run while (r < width && comp[r] == comp[x]) ++r; // output run up to r while (x < r) { int len = r-x; if (len > 127) len = 127; stbiw__write_run_data(s, len, comp[x]); x += len; } } } } } } static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, float *data) { if (y <= 0 || x <= 0 || data == NULL) return 0; else { // Each component is stored separately. Allocate scratch space for full output scanline. unsigned char *scratch = (unsigned char *) STBIW_MALLOC(x*4); if (NULL == scratch) return 0; int i, len; char buffer[128]; char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n"; s->func(s->context, header, sizeof(header)-1); #ifdef __STDC_LIB_EXT1__ len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L len = snprintf(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); #else len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); #endif s->func(s->context, buffer, len); for(i=0; i < y; i++) stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i)); STBIW_FREE(scratch); return 1; } } STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data) { stbi__write_context s = { 0 }; stbi__start_write_callbacks(&s, func, context); return stbi_write_hdr_core(&s, x, y, comp, (float *) data); } STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data) { stbi__write_context s = { 0 }; if (stbi__start_write_file(&s,filename)) { int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data); stbi__end_write_file(&s); return r; } else return 0; } #endif // STBI_WRITE_NO_STDIO ////////////////////////////////////////////////////////////////////////////// // // PNG writer // #ifndef STBIW_ZLIB_COMPRESS // stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size() #define stbiw__sbraw(a) ((int *) (void *) (a) - 2) #define stbiw__sbm(a) stbiw__sbraw(a)[0] #define stbiw__sbn(a) stbiw__sbraw(a)[1] #define stbiw__sbneedgrow(a,n) ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a)) #define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0) #define stbiw__sbgrow(a,n) stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a))) #define stbiw__sbpush(a, v) (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v)) #define stbiw__sbcount(a) ((a) ? stbiw__sbn(a) : 0) #define stbiw__sbfree(a) ((a) ? STBIW_FREE(stbiw__sbraw(a)),0 : 0) static void *stbiw__sbgrowf(void **arr, int increment, int itemsize) { int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1; void *p = STBIW_REALLOC_SIZED(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr)*itemsize + sizeof(int)*2) : 0, itemsize * m + sizeof(int)*2); STBIW_ASSERT(p); if (p) { if (!*arr) ((int *) p)[1] = 0; *arr = (void *) ((int *) p + 2); stbiw__sbm(*arr) = m; } return *arr; } static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount) { while (*bitcount >= 8) { stbiw__sbpush(data, STBIW_UCHAR(*bitbuffer)); *bitbuffer >>= 8; *bitcount -= 8; } return data; } static int stbiw__zlib_bitrev(int code, int codebits) { int res=0; while (codebits--) { res = (res << 1) | (code & 1); code >>= 1; } return res; } static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *b, int limit) { int i; for (i=0; i < limit && i < 258; ++i) if (a[i] != b[i]) break; return i; } static unsigned int stbiw__zhash(unsigned char *data) { stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16); hash ^= hash << 3; hash += hash >> 5; hash ^= hash << 4; hash += hash >> 17; hash ^= hash << 25; hash += hash >> 6; return hash; } #define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount)) #define stbiw__zlib_add(code,codebits) \ (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush()) #define stbiw__zlib_huffa(b,c) stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c) // default huffman tables #define stbiw__zlib_huff1(n) stbiw__zlib_huffa(0x30 + (n), 8) #define stbiw__zlib_huff2(n) stbiw__zlib_huffa(0x190 + (n)-144, 9) #define stbiw__zlib_huff3(n) stbiw__zlib_huffa(0 + (n)-256,7) #define stbiw__zlib_huff4(n) stbiw__zlib_huffa(0xc0 + (n)-280,8) #define stbiw__zlib_huff(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : (n) <= 255 ? stbiw__zlib_huff2(n) : (n) <= 279 ? stbiw__zlib_huff3(n) : stbiw__zlib_huff4(n)) #define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n)) #define stbiw__ZHASH 16384 #endif // STBIW_ZLIB_COMPRESS STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality) { #ifdef STBIW_ZLIB_COMPRESS // user provided a zlib compress implementation, use that return STBIW_ZLIB_COMPRESS(data, data_len, out_len, quality); #else // use builtin static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 }; static unsigned char lengtheb[]= { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 }; static unsigned short distc[] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 }; static unsigned char disteb[] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; unsigned int bitbuf=0; int i,j, bitcount=0; unsigned char *out = NULL; unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(unsigned char**)); if (hash_table == NULL) return NULL; if (quality < 5) quality = 5; stbiw__sbpush(out, 0x78); // DEFLATE 32K window stbiw__sbpush(out, 0x5e); // FLEVEL = 1 stbiw__zlib_add(1,1); // BFINAL = 1 stbiw__zlib_add(1,2); // BTYPE = 1 -- fixed huffman for (i=0; i < stbiw__ZHASH; ++i) hash_table[i] = NULL; i=0; while (i < data_len-3) { // hash next 3 bytes of data to be compressed int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3; unsigned char *bestloc = 0; unsigned char **hlist = hash_table[h]; int n = stbiw__sbcount(hlist); for (j=0; j < n; ++j) { if (hlist[j]-data > i-32768) { // if entry lies within window int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i); if (d >= best) { best=d; bestloc=hlist[j]; } } } // when hash table entry is too long, delete half the entries if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) { STBIW_MEMMOVE(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality); stbiw__sbn(hash_table[h]) = quality; } stbiw__sbpush(hash_table[h],data+i); if (bestloc) { // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1); hlist = hash_table[h]; n = stbiw__sbcount(hlist); for (j=0; j < n; ++j) { if (hlist[j]-data > i-32767) { int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1); if (e > best) { // if next match is better, bail on current match bestloc = NULL; break; } } } } if (bestloc) { int d = (int) (data+i - bestloc); // distance back STBIW_ASSERT(d <= 32767 && best <= 258); for (j=0; best > lengthc[j+1]-1; ++j); stbiw__zlib_huff(j+257); if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]); for (j=0; d > distc[j+1]-1; ++j); stbiw__zlib_add(stbiw__zlib_bitrev(j,5),5); if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]); i += best; } else { stbiw__zlib_huffb(data[i]); ++i; } } // write out final bytes for (;i < data_len; ++i) stbiw__zlib_huffb(data[i]); stbiw__zlib_huff(256); // end of block // pad with 0 bits to byte boundary while (bitcount) stbiw__zlib_add(0,1); for (i=0; i < stbiw__ZHASH; ++i) (void) stbiw__sbfree(hash_table[i]); STBIW_FREE(hash_table); // store uncompressed instead if compression was worse if (stbiw__sbn(out) > data_len + 2 + ((data_len+32766)/32767)*5) { stbiw__sbn(out) = 2; // truncate to DEFLATE 32K window and FLEVEL = 1 for (j = 0; j < data_len;) { int blocklen = data_len - j; if (blocklen > 32767) blocklen = 32767; stbiw__sbpush(out, data_len - j == blocklen); // BFINAL = ?, BTYPE = 0 -- no compression stbiw__sbpush(out, STBIW_UCHAR(blocklen)); // LEN stbiw__sbpush(out, STBIW_UCHAR(blocklen >> 8)); stbiw__sbpush(out, STBIW_UCHAR(~blocklen)); // NLEN stbiw__sbpush(out, STBIW_UCHAR(~blocklen >> 8)); memcpy(out+stbiw__sbn(out), data+j, blocklen); stbiw__sbn(out) += blocklen; j += blocklen; } } { // compute adler32 on input unsigned int s1=1, s2=0; int blocklen = (int) (data_len % 5552); j=0; while (j < data_len) { for (i=0; i < blocklen; ++i) { s1 += data[j+i]; s2 += s1; } s1 %= 65521; s2 %= 65521; j += blocklen; blocklen = 5552; } stbiw__sbpush(out, STBIW_UCHAR(s2 >> 8)); stbiw__sbpush(out, STBIW_UCHAR(s2)); stbiw__sbpush(out, STBIW_UCHAR(s1 >> 8)); stbiw__sbpush(out, STBIW_UCHAR(s1)); } *out_len = stbiw__sbn(out); // make returned pointer freeable STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len); return (unsigned char *) stbiw__sbraw(out); #endif // STBIW_ZLIB_COMPRESS } static unsigned int stbiw__crc32(unsigned char *buffer, int len) { #ifdef STBIW_CRC32 return STBIW_CRC32(buffer, len); #else static unsigned int crc_table[256] = { 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }; unsigned int crc = ~0u; int i; for (i=0; i < len; ++i) crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)]; return ~crc; #endif } #define stbiw__wpng4(o,a,b,c,d) ((o)[0]=STBIW_UCHAR(a),(o)[1]=STBIW_UCHAR(b),(o)[2]=STBIW_UCHAR(c),(o)[3]=STBIW_UCHAR(d),(o)+=4) #define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v)); #define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3]) static void stbiw__wpcrc(unsigned char **data, int len) { unsigned int crc = stbiw__crc32(*data - len - 4, len+4); stbiw__wp32(*data, crc); } static unsigned char stbiw__paeth(int a, int b, int c) { int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c); if (pa <= pb && pa <= pc) return STBIW_UCHAR(a); if (pb <= pc) return STBIW_UCHAR(b); return STBIW_UCHAR(c); } // @OPTIMIZE: provide an option that always forces left-predict or paeth predict static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int width, int height, int y, int n, int filter_type, signed char *line_buffer) { static int mapping[] = { 0,1,2,3,4 }; static int firstmap[] = { 0,1,0,5,6 }; int *mymap = (y != 0) ? mapping : firstmap; int i; int type = mymap[filter_type]; unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y); int signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes; if (type==0) { memcpy(line_buffer, z, width*n); return; } // first loop isn't optimized since it's just one pixel for (i = 0; i < n; ++i) { switch (type) { case 1: line_buffer[i] = z[i]; break; case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break; case 3: line_buffer[i] = z[i] - (z[i-signed_stride]>>1); break; case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-signed_stride],0)); break; case 5: line_buffer[i] = z[i]; break; case 6: line_buffer[i] = z[i]; break; } } switch (type) { case 1: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-n]; break; case 2: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-signed_stride]; break; case 3: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - ((z[i-n] + z[i-signed_stride])>>1); break; case 4: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-signed_stride], z[i-signed_stride-n]); break; case 5: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - (z[i-n]>>1); break; case 6: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break; } } STBIWDEF unsigned char *stbi_write_png_to_mem(const unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len) { int force_filter = stbi_write_force_png_filter; int ctype[5] = { -1, 0, 4, 2, 6 }; unsigned char sig[8] = { 137,80,78,71,13,10,26,10 }; unsigned char *out,*o, *filt, *zlib; signed char *line_buffer; int j,zlen; if (stride_bytes == 0) stride_bytes = x * n; if (force_filter >= 5) { force_filter = -1; } filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0; line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; } for (j=0; j < y; ++j) { int filter_type; if (force_filter > -1) { filter_type = force_filter; stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, force_filter, line_buffer); } else { // Estimate the best filter by running through all of them: int best_filter = 0, best_filter_val = 0x7fffffff, est, i; for (filter_type = 0; filter_type < 5; filter_type++) { stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, filter_type, line_buffer); // Estimate the entropy of the line using this filter; the less, the better. est = 0; for (i = 0; i < x*n; ++i) { est += abs((signed char) line_buffer[i]); } if (est < best_filter_val) { best_filter_val = est; best_filter = filter_type; } } if (filter_type != best_filter) { // If the last iteration already got us the best filter, don't redo it stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, best_filter, line_buffer); filter_type = best_filter; } } // when we get here, filter_type contains the filter type, and line_buffer contains the data filt[j*(x*n+1)] = (unsigned char) filter_type; STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n); } STBIW_FREE(line_buffer); zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, stbi_write_png_compression_level); STBIW_FREE(filt); if (!zlib) return 0; // each tag requires 12 bytes of overhead out = (unsigned char *) STBIW_MALLOC(8 + 12+13 + 12+zlen + 12); if (!out) return 0; *out_len = 8 + 12+13 + 12+zlen + 12; o=out; STBIW_MEMMOVE(o,sig,8); o+= 8; stbiw__wp32(o, 13); // header length stbiw__wptag(o, "IHDR"); stbiw__wp32(o, x); stbiw__wp32(o, y); *o++ = 8; *o++ = STBIW_UCHAR(ctype[n]); *o++ = 0; *o++ = 0; *o++ = 0; stbiw__wpcrc(&o,13); stbiw__wp32(o, zlen); stbiw__wptag(o, "IDAT"); STBIW_MEMMOVE(o, zlib, zlen); o += zlen; STBIW_FREE(zlib); stbiw__wpcrc(&o, zlen); stbiw__wp32(o,0); stbiw__wptag(o, "IEND"); stbiw__wpcrc(&o,0); STBIW_ASSERT(o == out + *out_len); return out; } #ifndef STBI_WRITE_NO_STDIO STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes) { FILE *f; int len; unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len); if (png == NULL) return 0; f = stbiw__fopen(filename, "wb"); if (!f) { STBIW_FREE(png); return 0; } fwrite(png, 1, len, f); fclose(f); STBIW_FREE(png); return 1; } #endif STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int stride_bytes) { int len; unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len); if (png == NULL) return 0; func(context, png, len); STBIW_FREE(png); return 1; } /* *************************************************************************** * * JPEG writer * * This is based on Jon Olick's jo_jpeg.cpp: * public domain Simple, Minimalistic JPEG writer - http://www.jonolick.com/code.html */ static const unsigned char stbiw__jpg_ZigZag[] = { 0,1,5,6,14,15,27,28,2,4,7,13,16,26,29,42,3,8,12,17,25,30,41,43,9,11,18, 24,31,40,44,53,10,19,23,32,39,45,52,54,20,22,33,38,46,51,55,60,21,34,37,47,50,56,59,61,35,36,48,49,57,58,62,63 }; static void stbiw__jpg_writeBits(stbi__write_context *s, int *bitBufP, int *bitCntP, const unsigned short *bs) { int bitBuf = *bitBufP, bitCnt = *bitCntP; bitCnt += bs[1]; bitBuf |= bs[0] << (24 - bitCnt); while(bitCnt >= 8) { unsigned char c = (bitBuf >> 16) & 255; stbiw__putc(s, c); if(c == 255) { stbiw__putc(s, 0); } bitBuf <<= 8; bitCnt -= 8; } *bitBufP = bitBuf; *bitCntP = bitCnt; } static void stbiw__jpg_DCT(float *d0p, float *d1p, float *d2p, float *d3p, float *d4p, float *d5p, float *d6p, float *d7p) { float d0 = *d0p, d1 = *d1p, d2 = *d2p, d3 = *d3p, d4 = *d4p, d5 = *d5p, d6 = *d6p, d7 = *d7p; float z1, z2, z3, z4, z5, z11, z13; float tmp0 = d0 + d7; float tmp7 = d0 - d7; float tmp1 = d1 + d6; float tmp6 = d1 - d6; float tmp2 = d2 + d5; float tmp5 = d2 - d5; float tmp3 = d3 + d4; float tmp4 = d3 - d4; // Even part float tmp10 = tmp0 + tmp3; // phase 2 float tmp13 = tmp0 - tmp3; float tmp11 = tmp1 + tmp2; float tmp12 = tmp1 - tmp2; d0 = tmp10 + tmp11; // phase 3 d4 = tmp10 - tmp11; z1 = (tmp12 + tmp13) * 0.707106781f; // c4 d2 = tmp13 + z1; // phase 5 d6 = tmp13 - z1; // Odd part tmp10 = tmp4 + tmp5; // phase 2 tmp11 = tmp5 + tmp6; tmp12 = tmp6 + tmp7; // The rotator is modified from fig 4-8 to avoid extra negations. z5 = (tmp10 - tmp12) * 0.382683433f; // c6 z2 = tmp10 * 0.541196100f + z5; // c2-c6 z4 = tmp12 * 1.306562965f + z5; // c2+c6 z3 = tmp11 * 0.707106781f; // c4 z11 = tmp7 + z3; // phase 5 z13 = tmp7 - z3; *d5p = z13 + z2; // phase 6 *d3p = z13 - z2; *d1p = z11 + z4; *d7p = z11 - z4; *d0p = d0; *d2p = d2; *d4p = d4; *d6p = d6; } static void stbiw__jpg_calcBits(int val, unsigned short bits[2]) { int tmp1 = val < 0 ? -val : val; val = val < 0 ? val-1 : val; bits[1] = 1; while(tmp1 >>= 1) { ++bits[1]; } bits[0] = val & ((1<0)&&(DU[end0pos]==0); --end0pos) { } // end0pos = first element in reverse order !=0 if(end0pos == 0) { stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB); return DU[0]; } for(i = 1; i <= end0pos; ++i) { int startpos = i; int nrzeroes; unsigned short bits[2]; for (; DU[i]==0 && i<=end0pos; ++i) { } nrzeroes = i-startpos; if ( nrzeroes >= 16 ) { int lng = nrzeroes>>4; int nrmarker; for (nrmarker=1; nrmarker <= lng; ++nrmarker) stbiw__jpg_writeBits(s, bitBuf, bitCnt, M16zeroes); nrzeroes &= 15; } stbiw__jpg_calcBits(DU[i], bits); stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTAC[(nrzeroes<<4)+bits[1]]); stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits); } if(end0pos != 63) { stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB); } return DU[0]; } static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, int comp, const void* data, int quality) { // Constants that don't pollute global namespace static const unsigned char std_dc_luminance_nrcodes[] = {0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0}; static const unsigned char std_dc_luminance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11}; static const unsigned char std_ac_luminance_nrcodes[] = {0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d}; static const unsigned char std_ac_luminance_values[] = { 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08, 0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28, 0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59, 0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89, 0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6, 0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2, 0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa }; static const unsigned char std_dc_chrominance_nrcodes[] = {0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0}; static const unsigned char std_dc_chrominance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11}; static const unsigned char std_ac_chrominance_nrcodes[] = {0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77}; static const unsigned char std_ac_chrominance_values[] = { 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91, 0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26, 0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58, 0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87, 0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4, 0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda, 0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa }; // Huffman tables static const unsigned short YDC_HT[256][2] = { {0,2},{2,3},{3,3},{4,3},{5,3},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9}}; static const unsigned short UVDC_HT[256][2] = { {0,2},{1,2},{2,2},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9},{1022,10},{2046,11}}; static const unsigned short YAC_HT[256][2] = { {10,4},{0,2},{1,2},{4,3},{11,4},{26,5},{120,7},{248,8},{1014,10},{65410,16},{65411,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {12,4},{27,5},{121,7},{502,9},{2038,11},{65412,16},{65413,16},{65414,16},{65415,16},{65416,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {28,5},{249,8},{1015,10},{4084,12},{65417,16},{65418,16},{65419,16},{65420,16},{65421,16},{65422,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {58,6},{503,9},{4085,12},{65423,16},{65424,16},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {59,6},{1016,10},{65430,16},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {122,7},{2039,11},{65438,16},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {123,7},{4086,12},{65446,16},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {250,8},{4087,12},{65454,16},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {504,9},{32704,15},{65462,16},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {505,9},{65470,16},{65471,16},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {506,9},{65479,16},{65480,16},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {1017,10},{65488,16},{65489,16},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {1018,10},{65497,16},{65498,16},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {2040,11},{65506,16},{65507,16},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {65515,16},{65516,16},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{0,0},{0,0},{0,0},{0,0},{0,0}, {2041,11},{65525,16},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0} }; static const unsigned short UVAC_HT[256][2] = { {0,2},{1,2},{4,3},{10,4},{24,5},{25,5},{56,6},{120,7},{500,9},{1014,10},{4084,12},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {11,4},{57,6},{246,8},{501,9},{2038,11},{4085,12},{65416,16},{65417,16},{65418,16},{65419,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {26,5},{247,8},{1015,10},{4086,12},{32706,15},{65420,16},{65421,16},{65422,16},{65423,16},{65424,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {27,5},{248,8},{1016,10},{4087,12},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{65430,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {58,6},{502,9},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{65438,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {59,6},{1017,10},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{65446,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {121,7},{2039,11},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{65454,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {122,7},{2040,11},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{65462,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {249,8},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{65470,16},{65471,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {503,9},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{65479,16},{65480,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {504,9},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{65488,16},{65489,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {505,9},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{65497,16},{65498,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {506,9},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{65506,16},{65507,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {2041,11},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{65515,16},{65516,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {16352,14},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{65525,16},{0,0},{0,0},{0,0},{0,0},{0,0}, {1018,10},{32707,15},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0} }; static const int YQT[] = {16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,18,22, 37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99}; static const int UVQT[] = {17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99, 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99}; static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f, 1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f }; int row, col, i, k, subsample; float fdtbl_Y[64], fdtbl_UV[64]; unsigned char YTable[64], UVTable[64]; if(!data || !width || !height || comp > 4 || comp < 1) { return 0; } quality = quality ? quality : 90; subsample = quality <= 90 ? 1 : 0; quality = quality < 1 ? 1 : quality > 100 ? 100 : quality; quality = quality < 50 ? 5000 / quality : 200 - quality * 2; for(i = 0; i < 64; ++i) { int uvti, yti = (YQT[i]*quality+50)/100; YTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (yti < 1 ? 1 : yti > 255 ? 255 : yti); uvti = (UVQT[i]*quality+50)/100; UVTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (uvti < 1 ? 1 : uvti > 255 ? 255 : uvti); } for(row = 0, k = 0; row < 8; ++row) { for(col = 0; col < 8; ++col, ++k) { fdtbl_Y[k] = 1 / (YTable [stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]); fdtbl_UV[k] = 1 / (UVTable[stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]); } } // Write Headers { static const unsigned char head0[] = { 0xFF,0xD8,0xFF,0xE0,0,0x10,'J','F','I','F',0,1,1,0,0,1,0,1,0,0,0xFF,0xDB,0,0x84,0 }; static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 }; const unsigned char head1[] = { 0xFF,0xC0,0,0x11,8,(unsigned char)(height>>8),STBIW_UCHAR(height),(unsigned char)(width>>8),STBIW_UCHAR(width), 3,1,(unsigned char)(subsample?0x22:0x11),0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 }; s->func(s->context, (void*)head0, sizeof(head0)); s->func(s->context, (void*)YTable, sizeof(YTable)); stbiw__putc(s, 1); s->func(s->context, UVTable, sizeof(UVTable)); s->func(s->context, (void*)head1, sizeof(head1)); s->func(s->context, (void*)(std_dc_luminance_nrcodes+1), sizeof(std_dc_luminance_nrcodes)-1); s->func(s->context, (void*)std_dc_luminance_values, sizeof(std_dc_luminance_values)); stbiw__putc(s, 0x10); // HTYACinfo s->func(s->context, (void*)(std_ac_luminance_nrcodes+1), sizeof(std_ac_luminance_nrcodes)-1); s->func(s->context, (void*)std_ac_luminance_values, sizeof(std_ac_luminance_values)); stbiw__putc(s, 1); // HTUDCinfo s->func(s->context, (void*)(std_dc_chrominance_nrcodes+1), sizeof(std_dc_chrominance_nrcodes)-1); s->func(s->context, (void*)std_dc_chrominance_values, sizeof(std_dc_chrominance_values)); stbiw__putc(s, 0x11); // HTUACinfo s->func(s->context, (void*)(std_ac_chrominance_nrcodes+1), sizeof(std_ac_chrominance_nrcodes)-1); s->func(s->context, (void*)std_ac_chrominance_values, sizeof(std_ac_chrominance_values)); s->func(s->context, (void*)head2, sizeof(head2)); } // Encode 8x8 macroblocks { static const unsigned short fillBits[] = {0x7F, 7}; int DCY=0, DCU=0, DCV=0; int bitBuf=0, bitCnt=0; // comp == 2 is grey+alpha (alpha is ignored) int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0; const unsigned char *dataR = (const unsigned char *)data; const unsigned char *dataG = dataR + ofsG; const unsigned char *dataB = dataR + ofsB; int x, y, pos; if(subsample) { for(y = 0; y < height; y += 16) { for(x = 0; x < width; x += 16) { float Y[256], U[256], V[256]; for(row = y, pos = 0; row < y+16; ++row) { // row >= height => use last input row int clamped_row = (row < height) ? row : height - 1; int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp; for(col = x; col < x+16; ++col, ++pos) { // if col >= width => use pixel from last input column int p = base_p + ((col < width) ? col : (width-1))*comp; float r = dataR[p], g = dataG[p], b = dataB[p]; Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128; U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b; V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b; } } DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+0, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+8, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+128, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+136, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); // subsample U,V { float subU[64], subV[64]; int yy, xx; for(yy = 0, pos = 0; yy < 8; ++yy) { for(xx = 0; xx < 8; ++xx, ++pos) { int j = yy*32+xx*2; subU[pos] = (U[j+0] + U[j+1] + U[j+16] + U[j+17]) * 0.25f; subV[pos] = (V[j+0] + V[j+1] + V[j+16] + V[j+17]) * 0.25f; } } DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subU, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subV, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); } } } } else { for(y = 0; y < height; y += 8) { for(x = 0; x < width; x += 8) { float Y[64], U[64], V[64]; for(row = y, pos = 0; row < y+8; ++row) { // row >= height => use last input row int clamped_row = (row < height) ? row : height - 1; int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp; for(col = x; col < x+8; ++col, ++pos) { // if col >= width => use pixel from last input column int p = base_p + ((col < width) ? col : (width-1))*comp; float r = dataR[p], g = dataG[p], b = dataB[p]; Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128; U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b; V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b; } } DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y, 8, fdtbl_Y, DCY, YDC_HT, YAC_HT); DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, U, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, V, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); } } } // Do the bit alignment of the EOI marker stbiw__jpg_writeBits(s, &bitBuf, &bitCnt, fillBits); } // EOI stbiw__putc(s, 0xFF); stbiw__putc(s, 0xD9); return 1; } STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality) { stbi__write_context s = { 0 }; stbi__start_write_callbacks(&s, func, context); return stbi_write_jpg_core(&s, x, y, comp, (void *) data, quality); } #ifndef STBI_WRITE_NO_STDIO STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality) { stbi__write_context s = { 0 }; if (stbi__start_write_file(&s,filename)) { int r = stbi_write_jpg_core(&s, x, y, comp, data, quality); stbi__end_write_file(&s); return r; } else return 0; } #endif #endif // STB_IMAGE_WRITE_IMPLEMENTATION /* Revision history 1.16 (2021-07-11) make Deflate code emit uncompressed blocks when it would otherwise expand support writing BMPs with alpha channel 1.15 (2020-07-13) unknown 1.14 (2020-02-02) updated JPEG writer to downsample chroma channels 1.13 1.12 1.11 (2019-08-11) 1.10 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs 1.09 (2018-02-11) fix typo in zlib quality API, improve STB_I_W_STATIC in C++ 1.08 (2018-01-29) add stbi__flip_vertically_on_write, external zlib, zlib quality, choose PNG filter 1.07 (2017-07-24) doc fix 1.06 (2017-07-23) writing JPEG (using Jon Olick's code) 1.05 ??? 1.04 (2017-03-03) monochrome BMP expansion 1.03 ??? 1.02 (2016-04-02) avoid allocating large structures on the stack 1.01 (2016-01-16) STBIW_REALLOC_SIZED: support allocators with no realloc support avoid race-condition in crc initialization minor compile issues 1.00 (2015-09-14) installable file IO function 0.99 (2015-09-13) warning fixes; TGA rle support 0.98 (2015-04-08) added STBIW_MALLOC, STBIW_ASSERT etc 0.97 (2015-01-18) fixed HDR asserts, rewrote HDR rle logic 0.96 (2015-01-17) add HDR output fix monochrome BMP 0.95 (2014-08-17) add monochrome TGA output 0.94 (2014-05-31) rename private functions to avoid conflicts with stb_image.h 0.93 (2014-05-27) warning fixes 0.92 (2010-08-01) casts to unsigned char to fix warnings 0.91 (2010-07-17) first public release 0.90 first internal release */ /* ------------------------------------------------------------------------------ This software is available under 2 licenses -- choose whichever you prefer. ------------------------------------------------------------------------------ ALTERNATIVE A - MIT License Copyright (c) 2017 Sean Barrett Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ ALTERNATIVE B - Public Domain (www.unlicense.org) This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ */ chawan-v0.4.0/adapter/img/stbi.nim000066400000000000000000000125201520232313100167740ustar00rootroot00000000000000{.push raises: [].} import std/posix import io/dynstream import types/opt import utils/sandbox import utils/twtstr import ../protocol/lcgi {.passc: "-fno-strict-aliasing".} {.passl: "-fno-strict-aliasing".} {.push header: """ #define STB_IMAGE_IMPLEMENTATION #define STBI_NO_LINEAR #define STBI_NO_STDIO /* #define STBI_NO_JPEG * #define STBI_NO_PNG * #define STBI_NO_BMP */ #define STBI_NO_PSD #define STBI_NO_TGA /* #define STBI_NO_GIF */ #define STBI_NO_HDR #define STBI_NO_PIC #define STBI_NO_PNM /* (.ppm and .pgm) */ #include "stb_image.h" """.} type stbi_io_callbacks {.importc.} = object read: proc(user: pointer; data: ptr char; size: cint): cint {.cdecl.} skip: proc(user: pointer; n: cint) {.cdecl.} eof: proc(user: pointer): cint {.cdecl.} proc stbi_load_from_callbacks(clbk: ptr stbi_io_callbacks; user: pointer; x, y, channels_in_file: var cint; desired_channels: cint): ptr uint8 {.importc.} proc stbi_info_from_callbacks(clbk: ptr stbi_io_callbacks; user: pointer; x, y, comp: var cint): cint {.importc.} proc stbi_failure_reason(): cstring {.importc.} proc stbi_image_free(retval_from_stbi_load: pointer) {.importc.} {.pop.} type StbiUser = object atEof: bool const STDIN_FILENO = 0 const STDOUT_FILENO = 1 proc myRead(user: pointer; data: ptr char; size: cint): cint {.cdecl.} = var n = cint(0) while n < size: let i = read(STDIN_FILENO, addr cast[ptr UncheckedArray[char]](data)[n], int(size - n)) if i == 0: cast[ptr StbiUser](user)[].atEof = true break n += cint(i) return n proc mySkip(user: pointer; size: cint) {.cdecl.} = var data: array[4096, uint8] var n = cint(0) while n < size: let i = read(STDIN_FILENO, addr data[0], min(int(size - n), data.len)) if i == 0: cast[ptr StbiUser](user)[].atEof = true break n += cint(i) proc myEof(user: pointer): cint {.cdecl.} = return cint(cast[ptr StbiUser](user)[].atEof) type stbi_write_func = proc(context, data: pointer; size: cint) {.cdecl.} {.push header: """ #define STB_IMAGE_WRITE_IMPLEMENTATION #define STIBW_NO_STDIO #include "stb_image_write.h" """.} proc stbi_write_png_to_func(fun: stbi_write_func; context: pointer; w, h, comp: cint; data: pointer; stride_in_bytes: cint) {.importc.} proc stbi_write_bmp_to_func(fun: stbi_write_func; context: pointer; w, h, comp: cint; data: pointer) {.importc.} proc stbi_write_jpg_to_func(fun: stbi_write_func; context: pointer; w, h, comp: cint; data: pointer; quality: cint) {.importc.} {.pop.} proc writeAll(data: pointer; size: int) = var n = 0 while n < size: let i = write(STDOUT_FILENO, addr cast[ptr UncheckedArray[uint8]](data)[n], int(size) - n) assert i >= 0 n += i proc myWriteFunc(context, data: pointer; size: cint) {.cdecl.} = writeAll(data, int(size)) proc puts(s: string) = if s.len > 0: writeAll(unsafeAddr s[0], s.len) proc main() = let f = getEnvEmpty("MAPPED_URI_SCHEME").after('+') case getEnvEmpty("MAPPED_URI_PATH") of "decode": if f notin ["jpeg", "gif", "bmp", "png", "x-unknown"]: cgiDie(ceInternalError, "unknown format " & f) enterNetworkSandbox() var user = StbiUser() var x: cint var y: cint var channels_in_file: cint var clbk = stbi_io_callbacks( read: myRead, skip: mySkip, eof: myEof ) var infoOnly = false for hdr in getEnvEmpty("REQUEST_HEADERS").split('\n'): let v = hdr.after(':').strip() if hdr.until(':') == "Cha-Image-Info-Only": infoOnly = v == "1" break if infoOnly: if stbi_info_from_callbacks(addr clbk, addr user, x, y, channels_in_file) == 1: puts("Cha-Image-Dimensions: " & $x & "x" & $y & "\n\n") quit(0) else: cgiDie(ceInternalError, stbi_failure_reason()) let p = stbi_load_from_callbacks(addr clbk, addr user, x, y, channels_in_file, 4) if p == nil: cgiDie(ceInternalError, stbi_failure_reason()) else: puts("Cha-Image-Dimensions: " & $x & "x" & $y & "\n\n") writeAll(p, x * y * 4) stbi_image_free(p) of "encode": if f notin ["png", "bmp", "jpeg"]: cgiDie(ceInternalError, "unknown format " & f) let headers = getEnvEmpty("REQUEST_HEADERS") var quality = cint(50) var width = cint(0) var height = cint(0) for hdr in headers.split('\n'): let s = hdr.after(':').strip() case hdr.until(':') of "Cha-Image-Dimensions": (width, height) = parseDimensionsC(s, allowZero = false) of "Cha-Image-Quality": let q = parseUInt32(s, allowSign = false).get(101) if q < 1 or 100 < q: cgiDie(ceInternalError, "wrong quality") quality = cint(q) let ps = newPosixStream(STDIN_FILENO) let src = ps.readLoopOrMmap(width * height * 4) if src == nil: cgiDie(ceInternalError, "failed to read input") enterNetworkSandbox() # don't swallow stat puts("Cha-Image-Dimensions: " & $width & 'x' & $height & "\n\n") let p = src.p case f of "png": stbi_write_png_to_func(myWriteFunc, nil, cint(width), cint(height), 4, p, 0) of "bmp": stbi_write_bmp_to_func(myWriteFunc, nil, cint(width), cint(height), 4, p) of "jpeg": stbi_write_jpg_to_func(myWriteFunc, nil, cint(width), cint(height), 4, p, quality) deallocMem(src) else: cgiDie(ceInternalError, "not implemented") main() {.pop.} # raises: [] chawan-v0.4.0/adapter/nim.cfg000066400000000000000000000000441520232313100160140ustar00rootroot00000000000000passc:"-fno-strict-aliasing" mm:arc chawan-v0.4.0/adapter/protocol/000077500000000000000000000000001520232313100164135ustar00rootroot00000000000000chawan-v0.4.0/adapter/protocol/chabookmark000077500000000000000000000133051520232313100206240ustar00rootroot00000000000000#!/bin/sh # # Simple bookmark script for Chawan. By default, M-b shows bookmarks, # and M-a opens the "add bookmark" screen. # # Also works in w3m; just add to keymap: # # bind M-a GOTO /cgi-bin/chabookmark # # The format is a subset of Markdown, so that it's easy to render. # You can also edit it manually and it will still work, as long as you # don't do anything weird. # # Sample: # # # Bookmarks # # # # # Bookmarks # # ## Section 1 # # * [Entry 1](https://a.example) # * [Entry 2](https://b.example) # # ## Section 2 # # * [Entry 3](https://c.example) # # (end of sample) # # TODO: # * sub-entries (or really, sub-sections) # * maybe tags? (but I don't know what they are good for...) # * think of a better structured bookmark format? # * rewrite in Nim? bookmark_file=${CHA_BOOKMARK:-"${CHA_DATA_DIR:-"$HOME/.chawan"}/bookmark.md"} # utils die() { echo "Cha-Control: ConnectionError $*" exit 1 } urldec() { printf '%s\n' "$1" | sed 's/+/ /g' | "${CHA_LIBEXEC_DIR:-/usr/local/libexec/chawan}"/urldec } urlenc() { printf '%s\n' "$1" | "$CHA_LIBEXEC_DIR"/urlenc } post_only() { test "$REQUEST_METHOD" = POST || die InvalidMethod } safe_printf() { printf "$@" || die "InternalError error writing file" } safe_println() { safe_printf '%s\n' "$1" } safe_rm() { rm -f "$1" || die "InternalError error removing temporary file" } list_sections() { # we don't care if there is a file or not sed -n '/^## /s/## //p' "$bookmark_file" 2>/dev/null } # endpoints ensure_bookmark() { if test -f "$bookmark_file"; then return 0; fi import_text= if test -f "${W3M_DIR:-"$HOME"/.w3m}"/bookmark.html then import_text="

        Or import bookmarks from w3m:

        " fi exec cat <No bookmark file

        No bookmark file

        No bookmark file found. Create a new one at $bookmark_file?
        $import_text EOF } new_ed() { ensure_bookmark new_ed_section=$(list_sections | sed 's/.*/


    " line &= "" & htmlEscape(item.dname) & "" line &= "
    " line &= htmlEscape(item.modified) if item.t == ditFile: line &= ' ' & convertSize(uint64(max(item.nsize, 0))) elif item.t == ditLink: line &= " -> " & htmlEscape(item.linkto) line &= "
    Section: " fi exec cat < Register to my bookmark

    Register to my bookmark

    $new_ed_section
    New Section:
    URL:
    Title:
    EOF } view() { ensure_bookmark printf 'Status: 301\nLocation: file:%s\n\n' "$bookmark_file" } new() { if test -z "$title" then printf '\nError: missing title\n' exit 1 fi if ! test -f "$bookmark_file"; then init || exit 1; fi if test -n "$new_section" then section=$new_section safe_printf '\n## %s\n' "$new_section" >>"$bookmark_file" elif test -z "$section" then die "InternalError section not specified" fi new_tmp="$bookmark_file~" new_found=0 safe_rm "$new_tmp" while read -r line do safe_println "$line" >>"$new_tmp" if test "$new_found" = 0 && test "$line" = "## $section" then if read -r line && test -n "$line" then die "InternalError malformed section $section" fi safe_println "$line" >>"$new_tmp" while read -r line do case $line in '#'*) die "InternalError malformed section $section";; '') new_found=1; break;; *) safe_println "$line" >>"$new_tmp";; esac done safe_println "* [$title]($url)" >>"$new_tmp" if test "$new_found" = 1 then safe_println '' >>"$new_tmp" else new_found=1 fi fi done <"$bookmark_file" mv "$new_tmp" "$bookmark_file" || die "InternalError could not move temp file" view } init_string=' Bookmarks # Bookmarks' init() { mkdir -p "$(dirname "$bookmark_file")" safe_println "$init_string" >>"$bookmark_file" } import_w3m() { if ! test -f "$w3m_path" then printf '\n\nFile not found: %s\n' "$w3m_path" exit 1 fi mkdir -p "$(dirname "$bookmark_file")" import_w3m_tmp="$bookmark_file~" safe_rm "$import_w3m_tmp" safe_println "$init_string" >>"$import_w3m_tmp" #TODO this isn't quite right. Specifically, if a URL has unmatched # parentheses/brackets in it, then you get a malformed markdown file. # But also, the user can just edit it manually, it's not that hard. sed -E \ -e 's@

    (.*)

    @## \1@g' \ -e 's@|@@g' \ -e '/^ # Chawan's command API As described in [**cha-config**](config.md)(5), users can bind keypress combinations to actions. Such an action can be either a JavaScript expression, or a command defined in the `[cmd]` section of config.toml. For example, the following works: ``` 'g p n' = 'n => pager.alert(n)' # e.g. 2gpn prints `2' to the status line ``` Note however, that JavaScript functions must be called with an appropriate `this` value. So e.g. the following does not work: ``` 'g p n' = 'pager.alert' # broken!!! ``` To work around this limitation, actions have to wrap the target function in a closure, as above. However, this has poor reusability; for more complex actions, you would have to copy and paste the entire function every time you re-bind it or call it from a different function. To fix this, it is possible to define a command in the `[cmd]` section: ```toml [cmd.my.namespace] showNumber = 'n => pager.alert(n)' ``` `my.namespace` can be anything you want; it is to avoid collisions when including multiple configs. The only restriction is that the first component (in this case, "my") must not contain an upper-case letter. Now you can call `cmd.my.namespace.showNumber()` from any other function, or include it in a keybinding (in that case, `cmd.` is optional): ```toml 'g p n' = 'my.namespace.showNumber' # same as 'g p n' = 'cmd.my.namespace.showNumber' ``` ## Interfaces Note that there are also many private functions not documented here. Such functions have no stability guarantee and may disappear at any time, so using them is not recommended. ### Client The global object (`globalThis`) implements the `Client` interface. Public functions of this are: `quit()` : Exit the browser. `suspend()` : Temporarily suspend the browser, by delivering the client process a SIGTSTP signal. Note: this suspends all processes, including buffers, the loader and CGI. `readFile(path)` : Read a file at `path`. Returns the file's content as a string, or null if the file does not exist. `writeFile(path, content)` : Write `content` to the file at `path`. Throws a TypeError if this failed for whatever reason. `getenv(name, fallback = null)` : Get an environment variable by `name`. Returns `fallback` if the variable does not exist. `setenv(name, value)` : Set an environment variable by `name`. Throws a `TypeError` if the operation failed (e.g. because the variable's size exceeded an OS-specified limit.) `pager` : The pager object. Implements `Pager`, as described below. `line` : The line editor. Implements `LineEdit`, as described below. `config` : The config object. A currently incomplete interface for retrieving and setting configuration options. In general, names are the same as in config.toml, except all `-` (ASCII hyphen) characters are stripped and the next character is upper-cased. e.g. `external.cgi-dir` can be queried as `config.external.cgiDir`, etc. Setting individual options sometimes works, but sometimes they do not get propagated as expected. Consider this an experimental API. Currently, `siteconf` and `omnirule` values are not exposed to JS. The configuration directory itself can be queried as `config.dir`. `Client` also implements various web standards normally available on the `Window` object on websites, e.g. fetch(). Note however that it does *not* give access to JS objects in buffers, so e.g. `globalThis.document` is not available. ### Pager `Pager` is a separate interface from `Client` that gives access to the pager (i.e. browser chrome). It is accessible as `globalThis.pager`, or simply `pager`. Note that there is a quirk of questionable value, where accessing properties that do not exist on the pager will dispatch those to the current buffer (`pager.buffer`). So if you see e.g. `pager.url`, that is actually equivalent to `pager.buffer.url`, because `Pager` has no `url` getter. Following properties (functions/getters) are defined by `Pager`: `load(url = pager.buffer.url)` : Put the specified address into the URL bar, and optionally load it. Note that this performs auto-expansion of URLs, so Chawan will expand any matching omni-rules (e.g. search), try to open schemeless URLs with the default scheme/local files, etc. Opens a prompt with the current URL when no parameters are specified; otherwise, the string passed is displayed in the prompt. `loadSubmit(url)` : Act as if `url` had been entered to the URL bar. `loadSubmit` differs from `gotoURL` in that it also evaluates omni-rules, tries to prepend a scheme, etc. `gotoURL(url, options = {replace: null, contentType: null, save: false, charset: null})` : Go to the specified URL immediately (without a prompt). This differs from `loadSubmit` in that it loads the exact URL as passed (no prepending https, etc.) When `replace` is set, the new buffer may replace the old one if it loads successfully. When `contentType` is set, the new buffer's content type is forcefully set to that string. When `save` is true, the user is prompted to save the resource instead of displaying it in a buffer. When `charset` is not null, the specified charset label is forced instead of regular charset detection. `traverse(dir)` : Switch to the next buffer in direction `dir`, interpreted as in `Buffer#find`. `nextBuffer()`, `prevBuffer()` : Same as `traverse("next")` and `traverse("prev")`. `dupeBuffer()` : Duplicate the current buffer by loading its source in a new buffer. `discardBuffer(buffer = pager.buffer, dir = pager.navDirection)` : Discard `buffer`, then move back to the buffer opposite to `dir` (interpreted as in `Buffer#find`). `discardTree()` : Discard all subsequent siblings of the current buffer. This function is deprecated, and may be removed in the future. `addTab(target)` : Open a new tab. If `target` is a buffer, it is removed from its current tab and added to the newly created tab. Otherwise, `target` is interpreted as a URL to open with `gotoURL`. `prevTab()`, `nextTab()` : Switch to the previous/next tab in the tab list. `discardTab()` : Discard the current tab. `reload()` : Open a new buffer with the current buffer's URL, replacing the current buffer. `reshape()` : Reshape the current buffer (=render the current page anew.) `redraw()` : Redraw screen contents. Useful if something messed up the display. `toggleSource()` : If viewing an HTML buffer, open a new buffer with its source. Otherwise, open the current buffer's contents as HTML. `lineInfo()` : Display information about the current line. `searchForward()`, `searchBackward()` : Search forward/backward for a string in the current buffer. `isearchForward()`, `isearchBackward()` : Incremental-search forward/backward for a string, highlighting the first result. `gotoLine(n?)` : Go to the line passed as the first argument. If no arguments were specified, an input window for entering a line is shown. `searchNext(n = 1)`, `searchPrev(n = 1)` : Jump to the nth next/previous search result. `peek()` : Display an alert message of the current URL. `peekCursor()` : Display an alert message of the URL or title under the cursor. Multiple calls allow cycling through the two. (i.e. by default, press u once -> title, press again -> URL) `showFullAlert()` : Show the last alert inside the line editor. `ask(prompt)` : Ask the user for confirmation. Returns a promise which resolves to a boolean value indicating whether the user responded with yes. Can be used to implement an exit prompt like this: ``` q = 'pager.ask("Do you want to exit Chawan?").then(x => x ? pager.quit() : void 0)' ``` `askChar(prompt)` : Ask the user for any character. Like `pager.ask`, but the return value is a character. `clipboardWrite(s)` : Write `s` to the clipboard (copy). By default, it tries using OSC 52; if that fails, it tries to run `external.copy-cmd` (defaults to `xsel`). Returns true if the copy succeeded, false otherwise. (There may be false positives in case OSC 52 is used and the terminal doesn't consume the text, although Chawan will try its best to avoid this.) `extern(cmd, options = {env: { ... }, suspend: true, wait: false})` : Run an external command `cmd`. By default, the `$CHA_URL` and `$CHA_CHARSET` variables are set; change this using the `env` option. `options.suspend` suspends the pager while the command is being executed, and `options.wait` makes it so the user must press a key before the pager is resumed. Returns true if the command exited successfully, false otherwise. `externCapture(cmd)` : Like `extern()`, but redirect the command's stdout string into the result. `null` is returned if the command wasn't executed successfully, or if the command returned a non-zero exit value. `externInto(cmd, ins)` : Like `extern()`, but redirect `ins` into the command's standard input stream. `true` is returned if the command exits successfully, `false` otherwise. `externFilterSource(cmd, buffer = null, contentType = null)` : Redirects the specified (or if `buffer` is null, the current) buffer's source into `cmd`. Then, it pipes the output into a new buffer, with the content type `contentType` (or, if `contentType` is null, the original buffer's content type). Returns `undefined`. (It should return a promise; TODO.) `openEditor(text)` : Open "text" in the command configured as `external.editor` (this is typically just `$EDITOR`.) If the editor signals an error (crash or non-zero exit code), `null` is returned. Otherwise, the user's input is returned as a string. `openMenu(x = pager.cursorx - pager.fromx, y = pager.cursory - pager.fromy)` : Opens the context menu at the specified x/y positions. `closeMenu()` : Closes the menu if it is opened. `buffer` : Getter for the currently displayed buffer. Returns a `Buffer` object; see below. `menu` : Getter for the currently displayed menu. Returns a `Select` object. `navDirection` : The direction the user last moved in the buffer list using `traverse`. Possible values are `prev`, `next`, `any`. `revDirection` : Equivalent to `Pager.oppositeDir(pager.navDirection)`. Also, the following static function is defined on `Pager` itself: `Pager.oppositeDir(dir)` : Return a string representing the direction opposite to `dir`. For "next", this is "prev"; for "prev", "next"; for "any", it's the same. ### Buffer Each buffer is exposed as an object that implements the `Buffer` interface. To get a reference to the currently displayed buffer, use `pager.buffer`. Note the quirk mentioned above where `Pager` dispatches unknown properties onto the current buffer. Following properties (functions/getters) are defined by `Buffer`: `cursorUp(n = 1)`, `cursorDown(n = 1)` : Move the cursor upwards/downwards by `n` lines, or if `n` is unspecified, by 1. `cursorLeft(n = 1)`, `cursorRight(n = 1)` : Move the cursor to the left/right by `n` cells, or if `n` is unspecified, by 1. Note: `n` right now represents cells, but really it should represent characters. (The difference is that numbered cursorLeft or cursorRight is currently broken for double-width chars.) `cursorLineBegin()`, `cursorLineEnd()` : Move the cursor to the first/last cell of the line. `cursorLineTextStart()` : Move the cursor to the first non-blank character of the line. `cursorNextWord()`, `cursorNextViWord()`, `cursorNextBigWord()` : Move the cursor to the beginning of the next [word](#word-types). `cursorPrevWord()`, `cursorPrevViWord()`, `cursorPrevBigWord()` : Move the cursor to the end of the previous [word](#word-types). `cursorWordEnd()`, `cursorViWordEnd()`, `cursorBigWordEnd()` : Move the cursor to the end of the current [word](#word-types), or if already there, to the end of the next word. `cursorWordBegin()`, `cursorViWordBegin()`, `cursorBigWordBegin()` : Move the cursor to the beginning of the current [word](#word-types), or if already there, to the end of the previous word. `async getCurrentWord(x = this.cursorx, y = this.cursory)` : Returns the word currently under the cursor as a string. `cursorNextLink()`, `cursorPrevLink()` : Move the cursor to the beginning of the next/previous clickable element. `cursorLinkNavDown(n = 1)`, `cursorLinkNavUp(n = 1)` : Move the cursor to the beginning of the `n`th next/previous clickable element. Buffer scrolls pagewise, wrap to beginning/end if content is less than one page length. `cursorNextParagraph(n = 1)`, `cursorPrevParagraph(n = 1)` : Move the cursor to the beginning/end of the nth next/previous paragraph. `cursorNthLink(n = 1)` : Move the cursor to the nth link of the document. `cursorRevNthLink(n = 1)` : Move the cursor to the nth link of the document, counting backwards from the document's last line. `pageUp(n = 1)`, `pageDown(n = 1)`, `pageLeft(n = 1)`, `pageRight(n = 1)` : Scroll up/down/left/right by n pages. `halfPageUp(n = 1)`, `halfPageDown(n = 1)`, `halfPageLeft(n = 1)`, `halfPageRight(n = 1)` : Scroll up/down/left/right by n half pages. `scrollUp(n = 1)`, `scrollDown(n = 1)`, `scrollLeft(n = 1)`, `scrollRight(n = 1)` : Scroll up/down/left/right by n lines. `click(n = 1)` : Click the HTML element currently under the cursor. `n` controls the number of clicks, e.g. `n = 2` is a double click. (The number of clicks is only relevant in JS apps.) `cursorFirstLine()`, `cursorLastLine()` : Move to the first/last line in the buffer. `cursorTop()`, `cursorMiddle()`, `cursorBottom()` : Move to the first/middle/bottom line on the screen. (Equivalent to H/M/L in vi.) `lowerPage(n = this.cursory)` : Move cursor to line n, then scroll up so that the cursor is on the top line on the screen. (`zt` in vim.) `lowerPageBegin(n = this.cursory)` : Move cursor to the first non-blank character of line n, then scroll up so that the cursor is on the top line on the screen. (`z` in vi.) `centerLine(n = this.cursory)` : Center screen around line n. (`zz` in vim.) `centerLineBegin(n = this.cursory)` : Center screen around line n, and move the cursor to the line's first non-blank character. (`z.` in vi.) `raisePage(n = this.cursory)` : Move cursor to line n, then scroll down so that the cursor is on the top line on the screen. (`zb` in vim.) `raisePageBegin(n = this.cursory)` : Move cursor to the first non-blank character of line n, then scroll up so that the cursor is on the last line on the screen. (`z^` in vi.) `nextPageBegin(n = this.cursory)` : If n was given, move to the screen before the nth line and raise the page. Otherwise, go to the previous screen's last line and raise the page. (`z+` in vi.) `cursorLeftEdge()`, `cursorMiddleColumn()`, `cursorRightEdge()` : Move to the first/middle/last column on the screen. `centerColumn()` : Center screen around the current column. `findPrevMatch(regex, x, y, wrap = false, n = 1)`, `findNextMatch(regex, x, y, wrap = false, n = 1)` : Find the previous/next match for a regex. `regex` is a RegExp object (e.g. from `/this syntax/`). `x` and `y` are the starting position in the buffer, `wrap` determines whether or not the search should wrap over the document, and `n` is the count of occurrences to be found. Returns an array of the elements `[x, y, w]` where `x` and `y` are the matched coordinates and `w` the width of the matched text. If no match is found, the result is `[-1, -1, 0]`. `findNextMark(x = this.cursorx, y = this.cursory)`, `findPrevMark(x = this.cursorx, y = this.cursory)` : Find the next/previous mark after/before `x`, `y`, if any; and return its id (or null if none were found.) `setMark(id, x = this.cursorx, y = this.cursory)` : Set a mark at (x, y) using the name `id`. Returns true if no other mark exists with `id`. If one already exists, it will be overridden and the function returns false. `clearMark(id)` : Clear the mark with the name `id`. Returns true if the mark existed, false otherwise. `gotoMark(id)` : If the mark `id` exists, jump to its position and return true. Otherwise, do nothing and return false. `gotoMarkY(id)` : If the mark `id` exists, jump to the beginning of the line at its Y position and return true. Otherwise, do nothing and return false. `getMarkPos(id)` : If the mark `id` exists, this returns its position as an array where the first element is the X position and the second element is the Y position. Otherwise it returns `null`. `cursorToggleSelection(n = 1, opts = {selectionType: "normal"})` : Start a vim-style visual selection. The cursor is moved to the right by `n` cells. selectionType may be "normal" (regular selection), "line" (line-based selection) and "column" (column-based selection). `getSelectionText()` : Get the currently selected text. Returns a promise, so consumers must `await` it to get the text. `markURL()` : Convert URL-like strings to anchors on the current page. `showLinkHints()` : Display link hints on the page. Mainly intended for the built-in toggleLinkHints command. Returns an array of objects with `x` representing the x position, `y` the y position of a link. `toggleImages()` : Toggle display of images in this buffer. `saveLink()` : Save URL pointed to by the cursor. `saveSource()` : Save the source of this buffer. `setCursorX(x)`, `setCursorY(y)`, `setCursorXY(x, y)`, `setCursorXCenter(x)`, `setCursorYCenter(y)`, `setCursorXYCenter(x, y)` : Set the cursor position to `x` and `y` respectively, scrolling the view if necessary. Variants that end with "Center" will also center the screen around the position if it is outside the screen. `setFromX(x)`, `setFromY(y)`, `setFromXY(x, y)` : Set the starting position of the displayed area on the screen. `find(dir)` : Find the next buffer in the list in a specific direction. Possible values of `dir` are "prev", "next", and "any". "next" and "prev" return the next/previous buffer respectively, while "any" returns either "prev", or if it's null, "next". `url` : Getter for the buffer's URL. Note: this returns a `URL` object, not a string. `hoverTitle`, `hoverLink`, `hoverImage` : Getter for the string representation of the element title/link/image currently under the cursor. Returns the empty string if no title is found. `cursorx`, `cursory` : The x/y position of the cursor inside the buffer. Note that while the status line display is 1-indexed, these values are 0-indexed (i.e. `cursory = 0` is the first line). `fromx`, `fromy` : The x/y position of the first line displayed on the screen. `numLines` : The number of lines currently loaded in the buffer. `width`, `height` : The width and height of the buffer's window (i.e. the visible part of the canvas). `process` : The process ID of the buffer. `title` : Text from the `title` element, or the buffer's URL if there is no title. `next` : Next buffer in the buffer list. May be `null`. `prev` : Previous buffer in the buffer list. May be `null`. `select` : Reference to the current `select` element's widget, or null if no `select` element is open. This object implements the `Select` interface, which is somewhat compatible with the `Buffer` interface with some exceptions. (TODO: elaborate)
    ### LineEdit The line editor at the bottom of the screen is exposed to the JavaScript context as `globalThis.line`, or simply `line`, and implements the `LineEdit` interface. Note that there is no single `LineEdit` object; a new one is created every time the line editor is opened, and when the line editor is closed, `globalThis.line` simply returns `null`. Following properties (functions/getters) are defined by `LineEdit`: `submit()` : Submit line. `cancel()` : Cancel operation. `backspace()` : Delete character before cursor. `delete()` : Delete character after cursor. `clear()` : Clear text before cursor. `kill()` : Clear text after cursor. `clearWord()` : Delete word before cursor. `killWord()` : Delete word after cursor. `backward()`, `forward()` : Move cursor backward/forward by one character. `nextWord()`, `prevWord()` : Move cursor to the next/previous word by one character. `begin()`, `end()` : Move cursor to the beginning/end of the line. `escape()` : Ignore keybindings for next character. `nextHist()`, `prevHist()` : Jump to the previous/next history entry. `text` : The currently entered text. ## See also [**cha**](cha.md)(1) [**cha-config**](config.md)(5) chawan-v0.4.0/doc/architecture.md000066400000000000000000000333511520232313100167100ustar00rootroot00000000000000# Architecture of Chawan This document describes some aspects of how Chawan works. **Table of contents** * [Module organization](#module-organization) * [Process model](#process-model) * [Main process](#main-process) * [Forkserver](#forkserver) * [Loader](#loader) * [Buffer](#buffer) * [Opening buffers](#opening-buffers) * [Parsing HTML](#parsing-html) * [JavaScript](#javascript) * [General](#general) * [JS in the pager](#js-in-the-pager) * [JS in the buffer](#js-in-the-buffer) * [CSS](#css) * [Parsing, cascading](#parsing-cascading) * [Layout](#layout) * [Rendering](#rendering) ## Module organization Explanation for the separate directories found in `src/`: * config: configuration-related code. Mainly parsers for config files. * css: CSS parsing, cascading, layout, rendering. * html: DOM building, the DOM itself, forms, misc. JS APIs, etc. (It does not include the [HTML parser](https://git.sr.ht/~bptato/chame).) * io: code for IPC, interaction with the file system, etc. * local: code for the main process (i.e. the pager). * server: code for processes other than the main process: buffer, forkserver, loader. * types: mainly definitions of data types and things I didn't know where to put. * utils: things I didn't know where to put part 2 Additionally, "adapters" of various protocols and file formats can be found in `adapter/`: * protocol: includes support for every protocol supported by Chawan. * format: HTML converters for various text-based file formats, e.g. Markdown. * img: image decoders and encoders. In general, these just read and output RGBA data through standard I/O (which may actually be a cache file; see the [image docs](image.md) for details). ## Process model Described as a tree: * cha (main process) - forkserver (forked immediately at startup) * loader * buffer(s) * local CGI scripts - mailcap processes (e.g. md2html, feh, ...) - editor (e.g. vi) ### Main process The main process runs code related to the pager. This includes processing user input, printing buffer contents to the screen, and managing buffers in general. The complete list of buffers is only known to the main process. Mailcap commands are executed by the main process. This depends on knowing the content type of the resource, so the main process also reads in all network headers of navigation responses before launching a buffer process. More on this in [Opening buffers](#opening-buffers). ### Forkserver For forking the loader process, buffer processes and CGI processes, a fork server process is launched at the very beginning of every 'cha' invocation. We use a fork server for two reasons: 1. It helps clean up child processes when the main process crashes. (We open a UNIX domain socket between the main process and the fork server, and kill all child processes from the fork server on EOF.) 2. It allows us to start new buffer processes without cloning the pager's entire address space. This reduces the impact of memory bugs somewhat, and also our memory usage. For convenience reasons, the fork server is not used for mailcap processes. ### Loader The loader process takes requests from the main process and the buffer processes. Then, depending on the scheme, it performs one of the following steps: * `cgi-bin:` Start a CGI script, and read out its stdout into the response body. In certain cases it also streams the response into the cache. This is also used for schemes like http/s, ftp, etc. by internally rewriting them into the appropriate `cgi-bin:` URL. * `stream:` Do the same thing as above, but read from a file descriptor passed to the loader beforehand. This is used when stdin is a file, e.g. `echo test | cha`. It is also used for mailcap entries with an x-htmloutput field. * `cache:` Read the file from the cache. This is used by the pager for the "view source" operation, and by buffers in the rare situation where their initial character encoding guess proves to be incorrect and they need to rewind the source. * `data:` Decode a data URL. This is done directly in the loader process because very long data URLs wouldn't fit into the environment. (Plus, obviously, it's more efficient this way.) The loader process distinguishes between clients (i.e processes) through their control stream (one end of a socketpair created by loader). This control stream is closed when the pager discards the buffer, so discarded buffers are unable to make further requests even if their process is still alive. ### Buffer Buffer processes parse HTML, optionally query external resources from loader, run styling, JS, and finally render the page to an internal canvas. Buffers are managed by the pager through Container objects. A UNIX domain socket is established between each buffer and the pager for IPC. ## Opening buffers Scenario: the user attempts to navigate to . 1. pager creates a new container for the target URL. 2. pager sends a request for "https://example.org" to the loader. Then, it registers the file descriptor in its selector, and does something else until poll() reports activity on the file descriptor. 3. loader rewrites "https://example.org" into "cgi-bin:http". It then runs the http CGI script with the appropriate environment variables set to parts of this URL and request headers. 4. The http CGI script opens a connection to example.org. When connected, it starts writing headers it receives to stdout. 5. loader parses these headers, and sends them to pager. 6. pager reads in the headers, and decides what to do based on the Content-Type: * If Content-Type is found in mailcap, then the response body is piped into the command in that mailcap entry. If the entry has x-htmloutput, then the command's stdout is taken instead of the response body, and Content-Type is set to text/html. Otherwise, the container is discarded. * If Content-Type is text/html, then a new buffer process is created, which then parses the response body as HTML. If it is any `text/*` subtype, then the response is simply inserted into a `` tag. * If Content-Type is not a `text/*` subtype, and no mailcap entry for it is found, then the user is prompted about where they wish to save the file. ## Cache Chawan's caching mechanism is largely inspired by that of w3m, which does not have a network cache. Instead, it simply saves source files to the disk before displaying them, and lets users view/edit the source without another network request. The only difference in Chawan is that it simultaneously streams files to the cache *and* buffers: 1. Client (pager or buffer) initiates request by sending a message to loader. 2. Loader starts CGI script, reads headers, sends a response, and waits. 3. Client now may send an "addCacheFile" message, which prompts loader to add a cache file for this request. 4. Client sends "resume", now loader will stream the response both to the client and the cache. Cached items may be shared between clients; this is how rewinding on wrong charset guess is implemented. They are also manually reference counted and are unlinked when their reference count drops to zero. The cache is used in the following ways: * For view source and edit source operations. * For rewinding buffers on incorrect charset guess. (In practice, this is almost never used, because the first chunk we read tends to determine the charset unambiguously.) * For reading images multiple times after download. (At least two reads are needed, because the first pass only parses the headers.) * As a memory buffer for image coding processes to mmap. (For details, see [image.md](image.md).) Crucially, the cache *does not* understand Cache-Control headers, and will never skip a download when requested by a user. Similarly, loading a "cache:" URL (e.g. view source) is guaranteed to never make a network request. Future directions: for non-JS buffers, we could kill idle processes and reload them on-demand from the cache. This could solve the problem of spawning too many processes that then do nothing. ## Parsing HTML The character decoder and the HTML parser are implementations of the WHATWG standards, and are available as [separate](https://git.sr.ht/~bptato/chagashi) [libraries](https://git.sr.ht/~bptato/chame). Buffer processes decode and parse HTML documents asynchronously. When bytes from the network are exhausted, the buffer will 1) partially render the current document as-is, 2) return it to the pager so that the user can interact with the document. Character encoding detection is rather primitive; the list specified in `encoding.document-charset` is enumerated until either no errors are produced by the decoder, or no more charsets exist. In some extremely rare edge cases, the document is re-downloaded from the cache, but this pretty much never happens. (The most common case is that the UTF-8 validator just runs through the entire document without reporting errors.) The HTML parser then consumes the decoded (or validated) input buffer. In some cases, a script calls document.write and then the parser is called recursively. (Debugging this is not very fun.) ## JavaScript QuickJS is used by both the pager as a scripting language, and by buffers for running on-page scripts when JavaScript is enabled. The core JS related functionality has been separated out into the [Monoucha](https://git.sr.ht/~bptato/monoucha) library, so it can be used outside of Chawan too. ### General To avoid having to type out all the type conversion & error handling code manually, we have JS pragmas to automagically turn Nim procedures into JavaScript functions. (For details on the specific pragmas, see the [manual](https://git.sr.ht/~bptato/monoucha/tree/master/doc/manual.md).) Still, sometimes we have to deal with JSValues manually; in this case, the fromJS and toJS functions are used. fromJS in particular returns an Opt[void], and uses a var parameter for overloading and efficient returns. ### JS in the pager Keybindings can be assigned JavaScript functions in the config, and then the pager executes those when the keybindings are pressed. Also, contents of the start.startup-script option are executed at startup. This is used when `cha` is called with the `-r` flag. There *is* an API, described at [api.md](api.md). Web APIs are exposed to pager too, but you cannot operate on the DOMs themselves from the pager, unless you create one yourself with DOMParser.parseFromString. [config.md](config.md) describes all commands that are used in the default config. ### JS in the buffer The DOM is implemented through the same wrappers as those in pager, except the pager modules are not exposed to buffer JS. Aside from document.write, it is mostly straightforward, and usually works OK, though too many things are missing to really make it useful. As for document.write: don't ask. It works as far as I can tell, but I wouldn't know why. ## CSS css/ contains CSS parsing, cascading, layout, and rendering. Note that CSS (at least 2.0 and onward) was designed for pixel-based displays, not for character-based ones, so we have to round a lot. The layout engine includes some heuristics around this so that the result is usually still acceptable. Also, some (now) commonly used features like CSS grid are not implemented yet, so websites using those look ugly. ### Parsing, cascading The parser is not very interesting, it's just an implementation of the CSS 3 parsing module. Overall it works fairly well. Cascading works OK. To speed up selector matching, various properties are hashed to filter out irrelevant CSS rules. However, no further style optimization exists yet (such as Bloom filters or style interning). Style calculation is incremental, and results are cached until an element's style is invalidated, so re-styles are quite fast. (The invalidation logic is primitive, but it's good enough in most cases.) ### Layout Layout runs whenever a page is loaded, or some action (e.g. hover, DOM change by JS, etc.) invalidates the page currently visible to the user. Our layout engine is a "simple" procedural implementation which consists of two passes: 1. css/csstree.nim: build a layout tree, possibly reusing the tree from the previous layout. Anonymous block and table boxes are generated here. After this pass, the tree is no longer mutated, only the `state` and `render` fields of the respective boxes. 2. css/layout.nim: position said boxes, always relative to their parent. This pass takes `input` and compares it with input previously taken; if they differ, it recurses through its children and then stores the box size and other output in `state`. But if `input` is the same as in the previous pass and `keepLayout` wasn't unset, it is assumed that layout for the subtree has not changed, and it is simply skipped (for the box itself as well as for all its children.) In practice, step 2 is often repeated for subsections of the tree to resolve cyclic dependencies in CSS layout (e.g. in table, flex). However, this rarely results in quadratic behavior thanks to the aforementioned caching mechanism. ### Rendering After layout is finished, the document is rendered onto a text-based canvas, which is represented as a sequence of strings associated with their formatting. (Right now, "formatting" also includes a reference to the respective DOM nodes; in the future, it won't.) Additionally, boxes are assigned an offset in the `render` field here, which is used when jumping to anchors. The entire document is rendered, which is a performance bottleneck in some cases. (Styling and layout are both slower, but those are cached. Rendering isn't, but all it really does is just copying around a bunch of strings and computers are very good at this.) The positive side of this design is that search is very simple (and fast), since we are just running regexes over a linear sequence of strings. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/build.md��������������������������������������������������������������������������0000664�0000000�0000000�00000013046�15202323131�0015324�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Building Chawan Chawan uses GNU make for builds. To build and install it, you'll typically want to run `make` and then `make install`. ## Variables Unless noted otherwise, variables can be passed either in the environment (e.g. `PREFIX=/usr make`) or as arguments to `make` (e.g. `make PREFIX=/usr`). It is recommended to pass the same variables to both the default target (`make`) and the install target (`make install`). The easiest way to accomplish this is to export the appropriate variables beforehand (e.g. `export PREFIX=/usr`). Following is a list of variables which may be set. * `TARGET`: the build target. - `debug`: Generate a debug build, with stack traces and debugging symbols enabled. Useful for debugging, but generates huge and slow executables. - `release`: The default target. Uses LTO and strips the final binaries. - `release0`: A release build with stack traces (**not** line traces) enabled. Useful when debugging a crash that needs a lot of processing to manifest. - `release1`: A release build with debugging symbols enabled. Useful for profiling with cachegrind, or debugging a release build with gdb. * `OUTDIR`: where to output the files. * `NIM`: path to the Nim compiler. * `PKG_CONFIG`: path to pkg-config. You can set it to pkgconf too. * `CFLAGS`, `LDFLAGS`: flags to pass to the C compiler at compile or link time. * `OBJDIR`: directory to output compilation artifacts. By default, it is `.obj`. * `PREFIX`: installation prefix, by default it is `/usr/local`. * `DESTDIR`: directory prepended to `$(PREFIX)`. e.g. you can set it to `/tmp`, so that `make install` installs the binary to the path `/tmp/usr/local/bin/cha`. * `MANPREFIX`, `MANPREFIX1`, `MANPREFIX5`: prefixes for the installation of man pages. The default setting expands to `/usr/local/share/man/man1`, etc. (Normally you shouldn't have to set `MANPREFIX1` or `MANPREFIX5` at all, as these are derived from `MANPREFIX`.) * `LIBEXECDIR`: Path to your libexec directory; by default, it is relative to wherever the binary is placed when it is executed. (i.e. after installation it would resolve to `/usr/local/libexec`.) * `STATIC_LINK`: Set it to 1 for static linking. * `DANGER_DISABLE_SANDBOX`: Set it to 1 to forcibly disable syscall filtering. Note that this is *not* taken from the environment variables, and you must use it like `make DANGER_DISABLE_SANDBOX=1`. As the name suggests, this is rarely an optimal solution to whatever problem you are facing. This list does not include the `CC` variable, because Nim only supports a limited set of C compilers. If you want to override the C compiler: 1. Set `CC` to the respective compiler anyways, because it is used by chaseccomp. 2. If your compiler is supported by Nim, then set e.g. `FLAGS=--cc:clang`. Check the list of supported compilers with `nim --cc:help`. 3. If your compiler is not supported by Nim, but emulates another compiler driver, then add e.g. `FLAGS=--gcc.path=/usr/local/musl/bin --gcc.exe=musl-gcc --gcc.linkerexe=musl-gcc` ## Phony targets * `all`: build all required executables * `clean`: remove OBJDIR (i.e. object files, but not the built executables) * `distclean`: remove OBJDIR and OUTDIR (i.e. both object files and executables) * `manpage`: rebuild man pages; note that this is not part of `all`. Manual pages are included in the repository, so this only needs to be called when you modify the documentation. **To packagers**: DO NOT use this in your packages. Our man pages depend on a bugfix that is only present in pandoc's development version, so a packaged version is guaranteed to make a mess of it. * `unicode_gen`: rebuild the EastAsianWidth mapping from the source. Like `manpage`, this is intended for development only. * `map`: rebuild all charset maps. See the previous point. * `install`: install the `cha` binary and man pages * `uninstall`: remove the `cha` binary and Chawan man pages * `test`: run tests. For now, these have no additional dependencies, but this may change in the future. Additionally, no guarantees are made about their reliability - I *think* they always work, but there have been counterexamples in the past. ## Cross-compiling [Apparently](https://todo.sr.ht/~bptato/chawan/37) it's possible. From user cutenice (with dependencies updated): > With the latest changes, I could simply run > `CFLAGS=-m32 LDFLAGS=-m32 FLAGS=--cpu:i386 make` to cross-compile! > > I don't know if I have any additional insight from today's > exploration.. On Arch I needed these things: > > - `nim-git` from the AUR > - the version available in the repos isn't quite new enough it > seems. I think it's related to #12 (at least i got similar looking > errors) > - enable the multilib repository in `/etc/pacman.conf` > - `pacman -S lib32-openssl lib32-libxcrypt lib32-libssh2` > - most of these packages pull packages like `lib32-gcc-libs` and > `lib32-glibc` which might be useful as well haha > - the rest can be eluded from the PKGBUILD in the > [AUR](https://aur.archlinux.org/packages/chawan-git) ## Static linking Tested with musl as follows: * Install musl to the default path (`/usr/local/musl`) * Add the following to `$HOME/nim.cfg`: ``` cc:gcc gcc.path = "/usr/local/musl/bin" gcc.exe = "musl-gcc" gcc.linkerexe = "musl-gcc" ``` * Compile and install OpenSSL, libssh2, libbrotlicommon and libbrotlidec to `/usr/local/musl`. * Compile Chawan: ```sh $ export PKG_CONFIG_PATH=/usr/local/musl/lib/pkgconfig:/usr/local/musl/lib64/pkgconfig $ export CC=musl-gcc STATIC_LINK=1 $ make distclean $ make ``` ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/cgi.md����������������������������������������������������������������������������0000664�0000000�0000000�00000024226�15202323131�0014771�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- CHA-CGI 5 --> # Local CGI support in Chawan Chawan supports the invocation of CGI scripts placed in a directory specified in the `external.cgi-dir` configuration option. By default, this is set to `$CHA_DIR/cgi-bin` (i.e. `~/.chawan/cgi-bin` or `~/.config/chawan/cgi-bin`, depending on `config.toml`'s location) and `/usr/local/libexec/chawan/cgi-bin`. A CGI script in one of these directories can be executed by visiting the URL `cgi-bin:script-name`. `$PATH_INFO` and `$QUERY_STRING` are set as normal, i.e. `cgi-bin:script-name/abcd?defgh=ijkl` will set `$PATH_INFO` to `/abcd`, and `$QUERY_STRING` to `defgh=ijkl`. Further notes on processing CGI paths: * The URL must be opaque, so you must not add a double slash after the scheme. e.g. `cgi-bin://script-name` will NOT work, only `cgi-bin:script-name`. * Paths beginning with `/cgi-bin/` or `/$LIB/` are stripped of this segment automatically. So e.g. `cgi-bin:/cgi-bin/script-name` becomes `cgi-bin:script-name`. * If `external.w3m-cgi-compat` is true, file: URLs are converted to `cgi-bin:` URLs if the path name starts with `/cgi-bin/`, `/$LIB/`, or the path of a local CGI script. Note: this is unsafe, please do not use it unless you must. * Absolute paths are accepted as e.g. `cgi-bin:/path/to/cgi/dir/script-name`. Note however, that this only works if `/path/to/cgi/dir` has already been specified as a CGI directory in `external.cgi-dir`. ## Headers Local CGI scripts may send some headers that Chawan will interpret specially (and thus will not pass forward to e.g. the fetch API, etc): * `Status`: interpreted as the HTTP status code. * `Cha-Control`: special header, see below. These headers **must** be sent before any regular headers. Headers received after a regular header or a `Cha-Control: ControlDone` header will be treated as regular headers. The `Cha-Control` header's value is parsed as follows: ``` Cha-Control-Value = Command *Parameter Command = ALPHA *ALPHA Parameter = SPACE *CHAR ``` In other words, it is `Command [Param1] [Param2] ...`. Currently available commands are: * `Connected`: Takes no parameters. Must be the first reported header; it means that connection to the server has been successfully established, but no data has been received yet. When any other header is sent first, Chawan will act as if a `Cha-Control: Connected` header had been implicitly sent before that. * `ConnectionError`: Must be the first reported header. Parameter 1 is the error code, see below. If any following parameters are given, they are concatenated to form a custom error message. Note: short but descriptive error messages are preferred, messages that do not fit on the screen are currently truncated. * `ControlDone`: Signals that no more special headers will be sent; this means that `Cha-Control` and `Status` headers sent after this must be interpreted as regular headers (and thus e.g. will be available for JS code calling the script using the fetch API). WARNING: this header must be sent before any non-hardcoded headers that take external input. For example, an HTTP client would have to send `Cha-Control: ControlDone` before returning the retrieved headers. Following is a list of error codes and their string counterparts. CGI scripts may use either (but not both) in a ConnectionError header. * `1 InternalError`: An internal error prevented the script from retrieving the requested resource. CGI scripts can also use this to signal that they have no information on what went wrong. * `2 InvalidMethod`: The client requested data using a method not supported by this protocol. * `3 InvalidURL`: The request URL could not be interpreted as a valid URL for this format. * `4 FileNotFound`: No file was found at the requested address, so the request is meaningless. Note: this should only be used by protocols that do not rely on a client-server architecture, e.g. local file access, local databases, or peer-to-peer file retrieval mechanisms. A server responding with "no file found" is NOT a connection error, and is better represented as a response with a 404 status code. * `5 ConnectionRefused`: The server refused to establish a connection. * `6 ProxyRefusedToConnect`: The proxy refused to establish a connection. * `7 FailedToResolveHost`: The hostname could not be resolved. * `8 FailedToResolveProxy`: The proxy could not be resolved. * `9 ProxyAuthFail`: The proxy refused the provided username/password. * `10 InvalidResponse`: The server's response deviates from the specification so badly that it cannot be meaningfully processed. * `11 ProxyInvalidResponse`: The proxy's response deviates from the specification so badly that it cannot be meaningfully processed. ## Environment variables Chawan sets the following environment variables: * `SERVER_SOFTWARE="Chawan"` * `SERVER_PROTOCOL="HTTP/1.0"` * `SERVER_NAME="localhost"` * `SERVER_PORT="80"` * `REMOTE_HOST="localhost"` * `REMOTE_ADDR="127.0.0.1"` * `GATEWAY_INTERFACE="CGI/1.1"` * `SCRIPT_NAME="/cgi-bin/script-name"` if called with a relative path, and `"/path/to/script/script-name"` if called with an absolute path. * `SCRIPT_FILENAME="/path/to/script/script-name"` * `QUERY_STRING=` the query string (i.e. `URL.search`). This variable is percent-encoded. * `PATH_INFO=` everything after the script's path name, e.g. for `cgi-bin:script-name/abcd/efgh` `"/abcd/efgh"`. This variable is NOT percent-encoded. * `REQUEST_URI="$SCRIPT_NAME/$PATH_INFO?$QUERY_STRING` * `REQUEST_METHOD=` HTTP method used for making the request, e.g. GET or POST * `REQUEST_HEADERS=` A newline-separated list of all headers for this request. * `CHA_LIBEXEC_DIR=` The libexec directory Chawan was configured to use at compile time. See the [tools](#tools) section below for details on why this is useful. * `CONTENT_TYPE=` for POST requests, the Content-Type header. Not set for other request types (e.g. GET). * `CONTENT_LENGTH=` the content length, if $CONTENT_TYPE has been set. * `ALL_PROXY=` if a proxy has been set, the proxy URL. WARNING: for security reasons, this **must** be respected when making external connections. If a CGI script does not support proxies, it must never make any external connections when the `ALL_PROXY` variable is set, but rather return an error message. * `HTTP_COOKIE=` if set, the Cookie header. * `HTTP_REFERER=` if set, the Referer header. * `CHA_TMP_DIR=` directory used for storing temporary files. * `CHA_DIR=` location of the config file. For requests originating from a urimethodmap rewrite, Chawan will also set the parsed URL's parts as environment variables. Use of these is highly encouraged, to avoid exploits originating from double-parsing of URLs. If `example://username:password@example.org:1234/path/name.html?example` is the original URL, then: * `MAPPED_URI_SCHEME=` the scheme of the original URL, in this case `example`. * `MAPPED_URI_USERNAME=` the username part, in this case `username`. If no username was specified, the variable is set to the empty string. * `MAPPED_URI_PASSWORD=` the password part, in this case `password`. If no password was specified, the variable is set to the empty string. * `MAPPED_URI_HOST=` the host part, in this case `host.org` If no host was specified, the variable is set to the empty string. (An example of a URL with no host: `about:blank`, here `blank` is the path name.) * `MAPPED_URI_PORT=` the port, in this case `1234`. If no port was specified, the variable is set to the empty string. (In this case, the CGI script is expected to use the default port for the scheme, if any.) * `MAPPED_URI_PATH=` the path name, in this case `/path/name.html?example`. If no path was specified, the variable is set to the empty string. The path name is percent-encoded. * `MAPPED_URI_QUERY=` the query string, in this case `example`. Unlike in JavaScript, no question mark is prepended to the string. The query string is percent-encoded as well. The fragment part is omitted intentionally. ## Request body If the request body is not empty, it is streamed into the program through the standard input. Note that this may be both an application/x-www-form-urlencoded or a multipart/form-data request; `CONTENT_TYPE` stores information about the request type, and in case of a multipart request, the boundary as well. ## Tools Chawan provides certain helper binaries that may be useful for CGI scripts. These can be portably accessed by executing `"$CHA_LIBEXEC_DIR"/[program]`. Currently, the following tools are available: * `urldec`: percent-decode strings passed on standard input. * `urlenc`: percent-encode strings passed on standard input, taking a percent-encode set as the first parameter. ## Troubleshooting Note that standard error is redirected to the browser console (by default, M-cM-c). This makes it easy to debug a misbehaving CGI script, but may also slow down the browser in case of excessive logging. If this is not the desired behavior, wrap your script into a shell script that redirects stderr to /dev/null. ### My script is returning a "Failed to execute script" error message. This means the `execl` call to the script failed. Make sure that your CGI script's executable bit is set, i.e. run `chmod +x /path/to/cgi/script`. ### My script is returning an "invalid CGI path" error message. Make sure that you did not include leading slashes. Reminder: `cgi-bin://script-name` does not work, use `cgi-bin:script-name`. ### My script is returning a "CGI file not found" error message. Double check that your CGI script is in the correct location. Also, make sure that you are not accidentally calling the script with an absolute path via `cgi-bin:/script-name` (instead of the correct `cgi-bin:script-name`). It is also possible that `external.cgi-dir` is not really set to the directory your script is in. Note that by default, this depends on the binary's path, so e.g. if your binary is in `~/src/chawan/target/release/bin/cha`, but you put your CGI script to `/usr/local/libexec/chawan/cgi-bin`, then it will not work. ### My script is returning a "failed to set up CGI script" error message. This means that either `pipe` or `fork` failed. Maybe you are running out of memory? ## See also [**cha**](cha.md)(1) [**cha-urimethodmap**](urimethodmap.md)(5) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/cha-api.7�������������������������������������������������������������������������0000664�0000000�0000000�00000056252�15202323131�0015303�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" Automatically generated by Pandoc 3.9.0.2 .\" .TH "CHA-API" "7" .SH Chawan\(cqs command API As described in \f[B]cha\-config\f[R](5), users can bind keypress combinations to actions. Such an action can be either a JavaScript expression, or a command defined in the \f[CR][cmd]\f[R] section of config.toml. .PP For example, the following works: .IP .EX \(aqg p n\(aq = \(aqn => pager.alert(n)\(aq # e.g. 2gpn prints \(ga2\(aq to the status line .EE .PP Note however, that JavaScript functions must be called with an appropriate \f[CR]this\f[R] value. So e.g.\ the following does not work: .IP .EX \(aqg p n\(aq = \(aqpager.alert\(aq # broken!!! .EE .PP To work around this limitation, actions have to wrap the target function in a closure, as above. However, this has poor reusability; for more complex actions, you would have to copy and paste the entire function every time you re\-bind it or call it from a different function. .PP To fix this, it is possible to define a command in the \f[CR][cmd]\f[R] section: .IP .EX \f[B][cmd.my.namespace]\f[R] showNumber = \(aqn => pager.alert(n)\(aq .EE .PP \f[CR]my.namespace\f[R] can be anything you want; it is to avoid collisions when including multiple configs. The only restriction is that the first component (in this case, \(lqmy\(rq) must not contain an upper\-case letter. .PP Now you can call \f[CR]cmd.my.namespace.showNumber()\f[R] from any other function, or include it in a keybinding (in that case, \f[CR]cmd.\f[R] is optional): .IP .EX \(aqg p n\(aq = \(aqmy.namespace.showNumber\(aq \f[I]# same as\f[R] \(aqg p n\(aq = \(aqcmd.my.namespace.showNumber\(aq .EE .SS Interfaces Note that there are also many private functions not documented here. Such functions have no stability guarantee and may disappear at any time, so using them is not recommended. .SS Client The global object (\f[CR]globalThis\f[R]) implements the \f[CR]Client\f[R] interface. Public functions of this are: .TP \f[CR]quit()\f[R] Exit the browser. .TP \f[CR]suspend()\f[R] Temporarily suspend the browser, by delivering the client process a SIGTSTP signal. .RS Note: this suspends all processes, including buffers, the loader and CGI. .RE .TP \f[CR]readFile(path)\f[R] Read a file at \f[CR]path\f[R]. .RS Returns the file\(cqs content as a string, or null if the file does not exist. .RE .TP \f[CR]writeFile(path, content)\f[R] Write \f[CR]content\f[R] to the file at \f[CR]path\f[R]. .RS Throws a TypeError if this failed for whatever reason. .RE .TP \f[CR]getenv(name, fallback = null)\f[R] Get an environment variable by \f[CR]name\f[R]. .RS Returns \f[CR]fallback\f[R] if the variable does not exist. .RE .TP \f[CR]setenv(name, value)\f[R] Set an environment variable by \f[CR]name\f[R]. .RS Throws a \f[CR]TypeError\f[R] if the operation failed (e.g.\ because the variable\(cqs size exceeded an OS\-specified limit.) .RE .TP \f[CR]pager\f[R] The pager object. Implements \f[CR]Pager\f[R], as described below. .TP \f[CR]line\f[R] The line editor. Implements \f[CR]LineEdit\f[R], as described below. .TP \f[CR]config\f[R] The config object. .RS A currently incomplete interface for retrieving and setting configuration options. In general, names are the same as in config.toml, except all \f[CR]\-\f[R] (ASCII hyphen) characters are stripped and the next character is upper\-cased. e.g.\ \f[CR]external.cgi\-dir\f[R] can be queried as \f[CR]config.external.cgiDir\f[R], etc. Setting individual options sometimes works, but sometimes they do not get propagated as expected. Consider this an experimental API. Currently, \f[CR]siteconf\f[R] and \f[CR]omnirule\f[R] values are not exposed to JS. The configuration directory itself can be queried as \f[CR]config.dir\f[R]. .RE .PP \f[CR]Client\f[R] also implements various web standards normally available on the \f[CR]Window\f[R] object on websites, e.g.\ fetch(). Note however that it does \f[I]not\f[R] give access to JS objects in buffers, so e.g.\ \f[CR]globalThis.document\f[R] is not available. .SS Pager \f[CR]Pager\f[R] is a separate interface from \f[CR]Client\f[R] that gives access to the pager (i.e.\ browser chrome). It is accessible as \f[CR]globalThis.pager\f[R], or simply \f[CR]pager\f[R]. .PP Note that there is a quirk of questionable value, where accessing properties that do not exist on the pager will dispatch those to the current buffer (\f[CR]pager.buffer\f[R]). So if you see e.g.\ \f[CR]pager.url\f[R], that is actually equivalent to \f[CR]pager.buffer.url\f[R], because \f[CR]Pager\f[R] has no \f[CR]url\f[R] getter. .PP Following properties (functions/getters) are defined by \f[CR]Pager\f[R]: .TP \f[CR]load(url = pager.buffer.url)\f[R] Put the specified address into the URL bar, and optionally load it. .RS Note that this performs auto\-expansion of URLs, so Chawan will expand any matching omni\-rules (e.g.\ search), try to open schemeless URLs with the default scheme/local files, etc. Opens a prompt with the current URL when no parameters are specified; otherwise, the string passed is displayed in the prompt. .RE .TP \f[CR]loadSubmit(url)\f[R] Act as if \f[CR]url\f[R] had been entered to the URL bar. \f[CR]loadSubmit\f[R] differs from \f[CR]gotoURL\f[R] in that it also evaluates omni\-rules, tries to prepend a scheme, etc. .TP \f[CR]gotoURL(url, options = {replace: null, contentType: null, save: false, charset: null})\f[R] Go to the specified URL immediately (without a prompt). This differs from \f[CR]loadSubmit\f[R] in that it loads the exact URL as passed (no prepending https, etc.) .RS When \f[CR]replace\f[R] is set, the new buffer may replace the old one if it loads successfully. When \f[CR]contentType\f[R] is set, the new buffer\(cqs content type is forcefully set to that string. When \f[CR]save\f[R] is true, the user is prompted to save the resource instead of displaying it in a buffer. When \f[CR]charset\f[R] is not null, the specified charset label is forced instead of regular charset detection. .RE .TP \f[CR]traverse(dir)\f[R] Switch to the next buffer in direction \f[CR]dir\f[R], interpreted as in \f[CR]Buffer#find\f[R]. .TP \f[CR]nextBuffer()\f[R], \f[CR]prevBuffer()\f[R] Same as \f[CR]traverse(\(dqnext\(dq)\f[R] and \f[CR]traverse(\(dqprev\(dq)\f[R]. .TP \f[CR]dupeBuffer()\f[R] Duplicate the current buffer by loading its source in a new buffer. .TP \f[CR]discardBuffer(buffer = pager.buffer, dir = pager.navDirection)\f[R] Discard \f[CR]buffer\f[R], then move back to the buffer opposite to \f[CR]dir\f[R] (interpreted as in \f[CR]Buffer#find\f[R]). .TP \f[CR]discardTree()\f[R] Discard all subsequent siblings of the current buffer. This function is deprecated, and may be removed in the future. .TP \f[CR]addTab(target)\f[R] Open a new tab. .RS If \f[CR]target\f[R] is a buffer, it is removed from its current tab and added to the newly created tab. Otherwise, \f[CR]target\f[R] is interpreted as a URL to open with \f[CR]gotoURL\f[R]. .RE .TP \f[CR]prevTab()\f[R], \f[CR]nextTab()\f[R] Switch to the previous/next tab in the tab list. .TP \f[CR]discardTab()\f[R] Discard the current tab. .TP \f[CR]reload()\f[R] Open a new buffer with the current buffer\(cqs URL, replacing the current buffer. .TP \f[CR]reshape()\f[R] Reshape the current buffer (=render the current page anew.) .TP \f[CR]redraw()\f[R] Redraw screen contents. Useful if something messed up the display. .TP \f[CR]toggleSource()\f[R] If viewing an HTML buffer, open a new buffer with its source. Otherwise, open the current buffer\(cqs contents as HTML. .TP \f[CR]lineInfo()\f[R] Display information about the current line. .TP \f[CR]searchForward()\f[R], \f[CR]searchBackward()\f[R] Search forward/backward for a string in the current buffer. .TP \f[CR]isearchForward()\f[R], \f[CR]isearchBackward()\f[R] Incremental\-search forward/backward for a string, highlighting the first result. .TP \f[CR]gotoLine(n?)\f[R] Go to the line passed as the first argument. .RS If no arguments were specified, an input window for entering a line is shown. .RE .TP \f[CR]searchNext(n = 1)\f[R], \f[CR]searchPrev(n = 1)\f[R] Jump to the nth next/previous search result. .TP \f[CR]peek()\f[R] Display an alert message of the current URL. .TP \f[CR]peekCursor()\f[R] Display an alert message of the URL or title under the cursor. Multiple calls allow cycling through the two. (i.e.\ by default, press u once \-> title, press again \-> URL) .TP \f[CR]showFullAlert()\f[R] Show the last alert inside the line editor. .TP \f[CR]ask(prompt)\f[R] Ask the user for confirmation. Returns a promise which resolves to a boolean value indicating whether the user responded with yes. .RS Can be used to implement an exit prompt like this: .IP .EX q = \(aqpager.ask(\(dqDo you want to exit Chawan?\(dq).then(x => x ? pager.quit() : void 0)\(aq .EE .RE .TP \f[CR]askChar(prompt)\f[R] Ask the user for any character. .RS Like \f[CR]pager.ask\f[R], but the return value is a character. .RE .TP \f[CR]clipboardWrite(s)\f[R] Write \f[CR]s\f[R] to the clipboard (copy). By default, it tries using OSC 52; if that fails, it tries to run \f[CR]external.copy\-cmd\f[R] (defaults to \f[CR]xsel\f[R]). .RS Returns true if the copy succeeded, false otherwise. (There may be false positives in case OSC 52 is used and the terminal doesn\(cqt consume the text, although Chawan will try its best to avoid this.) .RE .TP \f[CR]extern(cmd, options = {env: { ... }, suspend: true, wait: false})\f[R] Run an external command \f[CR]cmd\f[R]. .RS By default, the \f[CR]$CHA_URL\f[R] and \f[CR]$CHA_CHARSET\f[R] variables are set; change this using the \f[CR]env\f[R] option. \f[CR]options.suspend\f[R] suspends the pager while the command is being executed, and \f[CR]options.wait\f[R] makes it so the user must press a key before the pager is resumed. Returns true if the command exited successfully, false otherwise. .RE .TP \f[CR]externCapture(cmd)\f[R] Like \f[CR]extern()\f[R], but redirect the command\(cqs stdout string into the result. \f[CR]null\f[R] is returned if the command wasn\(cqt executed successfully, or if the command returned a non\-zero exit value. .TP \f[CR]externInto(cmd, ins)\f[R] Like \f[CR]extern()\f[R], but redirect \f[CR]ins\f[R] into the command\(cqs standard input stream. \f[CR]true\f[R] is returned if the command exits successfully, \f[CR]false\f[R] otherwise. .TP \f[CR]externFilterSource(cmd, buffer = null, contentType = null)\f[R] Redirects the specified (or if \f[CR]buffer\f[R] is null, the current) buffer\(cqs source into \f[CR]cmd\f[R]. .RS Then, it pipes the output into a new buffer, with the content type \f[CR]contentType\f[R] (or, if \f[CR]contentType\f[R] is null, the original buffer\(cqs content type). Returns \f[CR]undefined\f[R]. (It should return a promise; TODO.) .RE .TP \f[CR]openEditor(text)\f[R] Open \(lqtext\(rq in the command configured as \f[CR]external.editor\f[R] (this is typically just \f[CR]$EDITOR\f[R].) .RS If the editor signals an error (crash or non\-zero exit code), \f[CR]null\f[R] is returned. Otherwise, the user\(cqs input is returned as a string. .RE .TP \f[CR]openMenu(x = pager.cursorx \- pager.fromx, y = pager.cursory \- pager.fromy)\f[R] Opens the context menu at the specified x/y positions. .TP \f[CR]closeMenu()\f[R] Closes the menu if it is opened. .TP \f[CR]buffer\f[R] Getter for the currently displayed buffer. Returns a \f[CR]Buffer\f[R] object; see below. .TP \f[CR]menu\f[R] Getter for the currently displayed menu. Returns a \f[CR]Select\f[R] object. .TP \f[CR]navDirection\f[R] The direction the user last moved in the buffer list using \f[CR]traverse\f[R]. Possible values are \f[CR]prev\f[R], \f[CR]next\f[R], \f[CR]any\f[R]. .TP \f[CR]revDirection\f[R] Equivalent to \f[CR]Pager.oppositeDir(pager.navDirection)\f[R]. .PP Also, the following static function is defined on \f[CR]Pager\f[R] itself: .TP \f[CR]Pager.oppositeDir(dir)\f[R] Return a string representing the direction opposite to \f[CR]dir\f[R]. .RS For \(lqnext\(rq, this is \(lqprev\(rq; for \(lqprev\(rq, \(lqnext\(rq; for \(lqany\(rq, it\(cqs the same. .RE .SS Buffer Each buffer is exposed as an object that implements the \f[CR]Buffer\f[R] interface. To get a reference to the currently displayed buffer, use \f[CR]pager.buffer\f[R]. .PP Note the quirk mentioned above where \f[CR]Pager\f[R] dispatches unknown properties onto the current buffer. .PP Following properties (functions/getters) are defined by \f[CR]Buffer\f[R]: .TP \f[CR]cursorUp(n = 1)\f[R], \f[CR]cursorDown(n = 1)\f[R] Move the cursor upwards/downwards by \f[CR]n\f[R] lines, or if \f[CR]n\f[R] is unspecified, by 1. .TP \f[CR]cursorLeft(n = 1)\f[R], \f[CR]cursorRight(n = 1)\f[R] Move the cursor to the left/right by \f[CR]n\f[R] cells, or if \f[CR]n\f[R] is unspecified, by 1. .RS Note: \f[CR]n\f[R] right now represents cells, but really it should represent characters. (The difference is that numbered cursorLeft or cursorRight is currently broken for double\-width chars.) .RE .TP \f[CR]cursorLineBegin()\f[R], \f[CR]cursorLineEnd()\f[R] Move the cursor to the first/last cell of the line. .TP \f[CR]cursorLineTextStart()\f[R] Move the cursor to the first non\-blank character of the line. .TP \f[CR]cursorNextWord()\f[R], \f[CR]cursorNextViWord()\f[R], \f[CR]cursorNextBigWord()\f[R] Move the cursor to the beginning of the next word. .TP \f[CR]cursorPrevWord()\f[R], \f[CR]cursorPrevViWord()\f[R], \f[CR]cursorPrevBigWord()\f[R] Move the cursor to the end of the previous word. .TP \f[CR]cursorWordEnd()\f[R], \f[CR]cursorViWordEnd()\f[R], \f[CR]cursorBigWordEnd()\f[R] Move the cursor to the end of the current word, or if already there, to the end of the next word. .TP \f[CR]cursorWordBegin()\f[R], \f[CR]cursorViWordBegin()\f[R], \f[CR]cursorBigWordBegin()\f[R] Move the cursor to the beginning of the current word, or if already there, to the end of the previous word. .TP \f[CR]async getCurrentWord(x = this.cursorx, y = this.cursory)\f[R] Returns the word currently under the cursor as a string. .TP \f[CR]cursorNextLink()\f[R], \f[CR]cursorPrevLink()\f[R] Move the cursor to the beginning of the next/previous clickable element. .TP \f[CR]cursorLinkNavDown(n = 1)\f[R], \f[CR]cursorLinkNavUp(n = 1)\f[R] Move the cursor to the beginning of the \f[CR]n\f[R]th next/previous clickable element. Buffer scrolls pagewise, wrap to beginning/end if content is less than one page length. .TP \f[CR]cursorNextParagraph(n = 1)\f[R], \f[CR]cursorPrevParagraph(n = 1)\f[R] Move the cursor to the beginning/end of the nth next/previous paragraph. .TP \f[CR]cursorNthLink(n = 1)\f[R] Move the cursor to the nth link of the document. .TP \f[CR]cursorRevNthLink(n = 1)\f[R] Move the cursor to the nth link of the document, counting backwards from the document\(cqs last line. .TP \f[CR]pageUp(n = 1)\f[R], \f[CR]pageDown(n = 1)\f[R], \f[CR]pageLeft(n = 1)\f[R], \f[CR]pageRight(n = 1)\f[R] Scroll up/down/left/right by n pages. .TP \f[CR]halfPageUp(n = 1)\f[R], \f[CR]halfPageDown(n = 1)\f[R], \f[CR]halfPageLeft(n = 1)\f[R], \f[CR]halfPageRight(n = 1)\f[R] Scroll up/down/left/right by n half pages. .TP \f[CR]scrollUp(n = 1)\f[R], \f[CR]scrollDown(n = 1)\f[R], \f[CR]scrollLeft(n = 1)\f[R], \f[CR]scrollRight(n = 1)\f[R] Scroll up/down/left/right by n lines. .TP \f[CR]click(n = 1)\f[R] Click the HTML element currently under the cursor. \f[CR]n\f[R] controls the number of clicks, e.g.\ \f[CR]n = 2\f[R] is a double click. (The number of clicks is only relevant in JS apps.) .TP \f[CR]cursorFirstLine()\f[R], \f[CR]cursorLastLine()\f[R] Move to the first/last line in the buffer. .TP \f[CR]cursorTop()\f[R], \f[CR]cursorMiddle()\f[R], \f[CR]cursorBottom()\f[R] Move to the first/middle/bottom line on the screen. (Equivalent to H/M/L in vi.) .TP \f[CR]lowerPage(n = this.cursory)\f[R] Move cursor to line n, then scroll up so that the cursor is on the top line on the screen. (\f[CR]zt\f[R] in vim.) .TP \f[CR]lowerPageBegin(n = this.cursory)\f[R] Move cursor to the first non\-blank character of line n, then scroll up so that the cursor is on the top line on the screen. (\f[CR]z<CR>\f[R] in vi.) .TP \f[CR]centerLine(n = this.cursory)\f[R] Center screen around line n.\ (\f[CR]zz\f[R] in vim.) .TP \f[CR]centerLineBegin(n = this.cursory)\f[R] Center screen around line n, and move the cursor to the line\(cqs first non\-blank character. (\f[CR]z.\f[R] in vi.) .TP \f[CR]raisePage(n = this.cursory)\f[R] Move cursor to line n, then scroll down so that the cursor is on the top line on the screen. (\f[CR]zb\f[R] in vim.) .TP \f[CR]raisePageBegin(n = this.cursory)\f[R] Move cursor to the first non\-blank character of line n, then scroll up so that the cursor is on the last line on the screen. (\f[CR]z\(ha\f[R] in vi.) .TP \f[CR]nextPageBegin(n = this.cursory)\f[R] If n was given, move to the screen before the nth line and raise the page. Otherwise, go to the previous screen\(cqs last line and raise the page. (\f[CR]z+\f[R] in vi.) .TP \f[CR]cursorLeftEdge()\f[R], \f[CR]cursorMiddleColumn()\f[R], \f[CR]cursorRightEdge()\f[R] Move to the first/middle/last column on the screen. .TP \f[CR]centerColumn()\f[R] Center screen around the current column. .TP \f[CR]findPrevMatch(regex, x, y, wrap = false, n = 1)\f[R], \f[CR]findNextMatch(regex, x, y, wrap = false, n = 1)\f[R] Find the previous/next match for a regex. .RS \f[CR]regex\f[R] is a RegExp object (e.g.\ from \f[CR]/this syntax/\f[R]). \f[CR]x\f[R] and \f[CR]y\f[R] are the starting position in the buffer, \f[CR]wrap\f[R] determines whether or not the search should wrap over the document, and \f[CR]n\f[R] is the count of occurrences to be found. Returns an array of the elements \f[CR][x, y, w]\f[R] where \f[CR]x\f[R] and \f[CR]y\f[R] are the matched coordinates and \f[CR]w\f[R] the width of the matched text. If no match is found, the result is \f[CR][\-1, \-1, 0]\f[R]. .RE .TP \f[CR]findNextMark(x = this.cursorx, y = this.cursory)\f[R], \f[CR]findPrevMark(x = this.cursorx, y = this.cursory)\f[R] Find the next/previous mark after/before \f[CR]x\f[R], \f[CR]y\f[R], if any; and return its id (or null if none were found.) .TP \f[CR]setMark(id, x = this.cursorx, y = this.cursory)\f[R] Set a mark at (x, y) using the name \f[CR]id\f[R]. .RS Returns true if no other mark exists with \f[CR]id\f[R]. If one already exists, it will be overridden and the function returns false. .RE .TP \f[CR]clearMark(id)\f[R] Clear the mark with the name \f[CR]id\f[R]. Returns true if the mark existed, false otherwise. .TP \f[CR]gotoMark(id)\f[R] If the mark \f[CR]id\f[R] exists, jump to its position and return true. Otherwise, do nothing and return false. .TP \f[CR]gotoMarkY(id)\f[R] If the mark \f[CR]id\f[R] exists, jump to the beginning of the line at its Y position and return true. Otherwise, do nothing and return false. .TP \f[CR]getMarkPos(id)\f[R] If the mark \f[CR]id\f[R] exists, this returns its position as an array where the first element is the X position and the second element is the Y position. Otherwise it returns \f[CR]null\f[R]. .TP \f[CR]cursorToggleSelection(n = 1, opts = {selectionType: \(dqnormal\(dq})\f[R] Start a vim\-style visual selection. The cursor is moved to the right by \f[CR]n\f[R] cells. .RS selectionType may be \(lqnormal\(rq (regular selection), \(lqline\(rq (line\-based selection) and \(lqcolumn\(rq (column\-based selection). .RE .TP \f[CR]getSelectionText()\f[R] Get the currently selected text. .RS Returns a promise, so consumers must \f[CR]await\f[R] it to get the text. .RE .TP \f[CR]markURL()\f[R] Convert URL\-like strings to anchors on the current page. .TP \f[CR]showLinkHints()\f[R] Display link hints on the page. Mainly intended for the built\-in toggleLinkHints command. .RS Returns an array of objects with \f[CR]x\f[R] representing the x position, \f[CR]y\f[R] the y position of a link. .RE .TP \f[CR]toggleImages()\f[R] Toggle display of images in this buffer. .TP \f[CR]saveLink()\f[R] Save URL pointed to by the cursor. .TP \f[CR]saveSource()\f[R] Save the source of this buffer. .TP \f[CR]setCursorX(x)\f[R], \f[CR]setCursorY(y)\f[R], \f[CR]setCursorXY(x, y)\f[R], \f[CR]setCursorXCenter(x)\f[R], \f[CR]setCursorYCenter(y)\f[R], \f[CR]setCursorXYCenter(x, y)\f[R] Set the cursor position to \f[CR]x\f[R] and \f[CR]y\f[R] respectively, scrolling the view if necessary. .RS Variants that end with \(lqCenter\(rq will also center the screen around the position if it is outside the screen. .RE .TP \f[CR]setFromX(x)\f[R], \f[CR]setFromY(y)\f[R], \f[CR]setFromXY(x, y)\f[R] Set the starting position of the displayed area on the screen. .TP \f[CR]find(dir)\f[R] Find the next buffer in the list in a specific direction. .RS Possible values of \f[CR]dir\f[R] are \(lqprev\(rq, \(lqnext\(rq, and \(lqany\(rq. \(lqnext\(rq and \(lqprev\(rq return the next/previous buffer respectively, while \(lqany\(rq returns either \(lqprev\(rq, or if it\(cqs null, \(lqnext\(rq. .RE .TP \f[CR]url\f[R] Getter for the buffer\(cqs URL. Note: this returns a \f[CR]URL\f[R] object, not a string. .TP \f[CR]hoverTitle\f[R], \f[CR]hoverLink\f[R], \f[CR]hoverImage\f[R] Getter for the string representation of the element title/link/image currently under the cursor. Returns the empty string if no title is found. .TP \f[CR]cursorx\f[R], \f[CR]cursory\f[R] The x/y position of the cursor inside the buffer. .RS Note that while the status line display is 1\-indexed, these values are 0\-indexed (i.e.\ \f[CR]cursory = 0\f[R] is the first line). .RE .TP \f[CR]fromx\f[R], \f[CR]fromy\f[R] The x/y position of the first line displayed on the screen. .TP \f[CR]numLines\f[R] The number of lines currently loaded in the buffer. .TP \f[CR]width\f[R], \f[CR]height\f[R] The width and height of the buffer\(cqs window (i.e.\ the visible part of the canvas). .TP \f[CR]process\f[R] The process ID of the buffer. .TP \f[CR]title\f[R] Text from the \f[CR]title\f[R] element, or the buffer\(cqs URL if there is no title. .TP \f[CR]next\f[R] Next buffer in the buffer list. May be \f[CR]null\f[R]. .TP \f[CR]prev\f[R] Previous buffer in the buffer list. May be \f[CR]null\f[R]. .TP \f[CR]select\f[R] Reference to the current \f[CR]select\f[R] element\(cqs widget, or null if no \f[CR]select\f[R] element is open. .RS This object implements the \f[CR]Select\f[R] interface, which is somewhat compatible with the \f[CR]Buffer\f[R] interface with some exceptions. (TODO: elaborate) .RE .SS LineEdit The line editor at the bottom of the screen is exposed to the JavaScript context as \f[CR]globalThis.line\f[R], or simply \f[CR]line\f[R], and implements the \f[CR]LineEdit\f[R] interface. .PP Note that there is no single \f[CR]LineEdit\f[R] object; a new one is created every time the line editor is opened, and when the line editor is closed, \f[CR]globalThis.line\f[R] simply returns \f[CR]null\f[R]. .PP Following properties (functions/getters) are defined by \f[CR]LineEdit\f[R]: .TP \f[CR]submit()\f[R] Submit line. .TP \f[CR]cancel()\f[R] Cancel operation. .TP \f[CR]backspace()\f[R] Delete character before cursor. .TP \f[CR]delete()\f[R] Delete character after cursor. .TP \f[CR]clear()\f[R] Clear text before cursor. .TP \f[CR]kill()\f[R] Clear text after cursor. .TP \f[CR]clearWord()\f[R] Delete word before cursor. .TP \f[CR]killWord()\f[R] Delete word after cursor. .TP \f[CR]backward()\f[R], \f[CR]forward()\f[R] Move cursor backward/forward by one character. .TP \f[CR]nextWord()\f[R], \f[CR]prevWord()\f[R] Move cursor to the next/previous word by one character. .TP \f[CR]begin()\f[R], \f[CR]end()\f[R] Move cursor to the beginning/end of the line. .TP \f[CR]escape()\f[R] Ignore keybindings for next character. .TP \f[CR]nextHist()\f[R], \f[CR]prevHist()\f[R] Jump to the previous/next history entry. .TP \f[CR]text\f[R] The currently entered text. .SS See also \f[B]cha\f[R](1) \f[B]cha\-config\f[R](5) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/cha-cgi.5�������������������������������������������������������������������������0000664�0000000�0000000�00000027335�15202323131�0015272�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" Automatically generated by Pandoc 3.9.0.2 .\" .TH "CHA-CGI" "5" .SH Local CGI support in Chawan Chawan supports the invocation of CGI scripts placed in a directory specified in the \f[CR]external.cgi\-dir\f[R] configuration option. By default, this is set to \f[CR]$CHA_DIR/cgi\-bin\f[R] (i.e.\ \f[CR]\(ti/.chawan/cgi\-bin\f[R] or \f[CR]\(ti/.config/chawan/cgi\-bin\f[R], depending on \f[CR]config.toml\f[R]\(cqs location) and \f[CR]/usr/local/libexec/chawan/cgi\-bin\f[R]. .PP A CGI script in one of these directories can be executed by visiting the URL \f[CR]cgi\-bin:script\-name\f[R]. \f[CR]$PATH_INFO\f[R] and \f[CR]$QUERY_STRING\f[R] are set as normal, i.e.\ \f[CR]cgi\-bin:script\-name/abcd?defgh=ijkl\f[R] will set \f[CR]$PATH_INFO\f[R] to \f[CR]/abcd\f[R], and \f[CR]$QUERY_STRING\f[R] to \f[CR]defgh=ijkl\f[R]. .PP Further notes on processing CGI paths: .IP \(bu 2 The URL must be opaque, so you must not add a double slash after the scheme. e.g.\ \f[CR]cgi\-bin://script\-name\f[R] will NOT work, only \f[CR]cgi\-bin:script\-name\f[R]. .IP \(bu 2 Paths beginning with \f[CR]/cgi\-bin/\f[R] or \f[CR]/$LIB/\f[R] are stripped of this segment automatically. So e.g.\ \f[CR]cgi\-bin:/cgi\-bin/script\-name\f[R] becomes \f[CR]cgi\-bin:script\-name\f[R]. .IP \(bu 2 If \f[CR]external.w3m\-cgi\-compat\f[R] is true, file: URLs are converted to \f[CR]cgi\-bin:\f[R] URLs if the path name starts with \f[CR]/cgi\-bin/\f[R], \f[CR]/$LIB/\f[R], or the path of a local CGI script. Note: this is unsafe, please do not use it unless you must. .IP \(bu 2 Absolute paths are accepted as e.g.\ \f[CR]cgi\-bin:/path/to/cgi/dir/script\-name\f[R]. Note however, that this only works if \f[CR]/path/to/cgi/dir\f[R] has already been specified as a CGI directory in \f[CR]external.cgi\-dir\f[R]. .SS Headers Local CGI scripts may send some headers that Chawan will interpret specially (and thus will not pass forward to e.g.\ the fetch API, etc): .IP \(bu 2 \f[CR]Status\f[R]: interpreted as the HTTP status code. .IP \(bu 2 \f[CR]Cha\-Control\f[R]: special header, see below. .PP These headers \f[B]must\f[R] be sent before any regular headers. Headers received after a regular header or a \f[CR]Cha\-Control: ControlDone\f[R] header will be treated as regular headers. .PP The \f[CR]Cha\-Control\f[R] header\(cqs value is parsed as follows: .IP .EX Cha\-Control\-Value = Command *Parameter Command = ALPHA *ALPHA Parameter = SPACE *CHAR .EE .PP In other words, it is \f[CR]Command [Param1] [Param2] ...\f[R]. .PP Currently available commands are: .IP \(bu 2 \f[CR]Connected\f[R]: Takes no parameters. Must be the first reported header; it means that connection to the server has been successfully established, but no data has been received yet. When any other header is sent first, Chawan will act as if a \f[CR]Cha\-Control: Connected\f[R] header had been implicitly sent before that. .IP \(bu 2 \f[CR]ConnectionError\f[R]: Must be the first reported header. Parameter 1 is the error code, see below. If any following parameters are given, they are concatenated to form a custom error message. .RS 2 .PP Note: short but descriptive error messages are preferred, messages that do not fit on the screen are currently truncated. .RE .IP \(bu 2 \f[CR]ControlDone\f[R]: Signals that no more special headers will be sent; this means that \f[CR]Cha\-Control\f[R] and \f[CR]Status\f[R] headers sent after this must be interpreted as regular headers (and thus e.g.\ will be available for JS code calling the script using the fetch API). .RS 2 .PP WARNING: this header must be sent before any non\-hardcoded headers that take external input. For example, an HTTP client would have to send \f[CR]Cha\-Control: ControlDone\f[R] before returning the retrieved headers. .RE .PP Following is a list of error codes and their string counterparts. CGI scripts may use either (but not both) in a ConnectionError header. .IP \(bu 2 \f[CR]1 InternalError\f[R]: An internal error prevented the script from retrieving the requested resource. CGI scripts can also use this to signal that they have no information on what went wrong. .IP \(bu 2 \f[CR]2 InvalidMethod\f[R]: The client requested data using a method not supported by this protocol. .IP \(bu 2 \f[CR]3 InvalidURL\f[R]: The request URL could not be interpreted as a valid URL for this format. .IP \(bu 2 \f[CR]4 FileNotFound\f[R]: No file was found at the requested address, so the request is meaningless. Note: this should only be used by protocols that do not rely on a client\-server architecture, e.g.\ local file access, local databases, or peer\-to\-peer file retrieval mechanisms. A server responding with \(lqno file found\(rq is NOT a connection error, and is better represented as a response with a 404 status code. .IP \(bu 2 \f[CR]5 ConnectionRefused\f[R]: The server refused to establish a connection. .IP \(bu 2 \f[CR]6 ProxyRefusedToConnect\f[R]: The proxy refused to establish a connection. .IP \(bu 2 \f[CR]7 FailedToResolveHost\f[R]: The hostname could not be resolved. .IP \(bu 2 \f[CR]8 FailedToResolveProxy\f[R]: The proxy could not be resolved. .IP \(bu 2 \f[CR]9 ProxyAuthFail\f[R]: The proxy refused the provided username/password. .IP \(bu 2 \f[CR]10 InvalidResponse\f[R]: The server\(cqs response deviates from the specification so badly that it cannot be meaningfully processed. .IP \(bu 2 \f[CR]11 ProxyInvalidResponse\f[R]: The proxy\(cqs response deviates from the specification so badly that it cannot be meaningfully processed. .SS Environment variables Chawan sets the following environment variables: .IP \(bu 2 \f[CR]SERVER_SOFTWARE=\(dqChawan\(dq\f[R] .IP \(bu 2 \f[CR]SERVER_PROTOCOL=\(dqHTTP/1.0\(dq\f[R] .IP \(bu 2 \f[CR]SERVER_NAME=\(dqlocalhost\(dq\f[R] .IP \(bu 2 \f[CR]SERVER_PORT=\(dq80\(dq\f[R] .IP \(bu 2 \f[CR]REMOTE_HOST=\(dqlocalhost\(dq\f[R] .IP \(bu 2 \f[CR]REMOTE_ADDR=\(dq127.0.0.1\(dq\f[R] .IP \(bu 2 \f[CR]GATEWAY_INTERFACE=\(dqCGI/1.1\(dq\f[R] .IP \(bu 2 \f[CR]SCRIPT_NAME=\(dq/cgi\-bin/script\-name\(dq\f[R] if called with a relative path, and \f[CR]\(dq/path/to/script/script\-name\(dq\f[R] if called with an absolute path. .IP \(bu 2 \f[CR]SCRIPT_FILENAME=\(dq/path/to/script/script\-name\(dq\f[R] .IP \(bu 2 \f[CR]QUERY_STRING=\f[R] the query string (i.e.\ \f[CR]URL.search\f[R]). This variable is percent\-encoded. .IP \(bu 2 \f[CR]PATH_INFO=\f[R] everything after the script\(cqs path name, e.g.\ for \f[CR]cgi\-bin:script\-name/abcd/efgh\f[R] \f[CR]\(dq/abcd/efgh\(dq\f[R]. This variable is NOT percent\-encoded. .IP \(bu 2 \f[CR]REQUEST_URI=\(dq$SCRIPT_NAME/$PATH_INFO?$QUERY_STRING\f[R] .IP \(bu 2 \f[CR]REQUEST_METHOD=\f[R] HTTP method used for making the request, e.g.\ GET or POST .IP \(bu 2 \f[CR]REQUEST_HEADERS=\f[R] A newline\-separated list of all headers for this request. .IP \(bu 2 \f[CR]CHA_LIBEXEC_DIR=\f[R] The libexec directory Chawan was configured to use at compile time. See the tools section below for details on why this is useful. .IP \(bu 2 \f[CR]CONTENT_TYPE=\f[R] for POST requests, the Content\-Type header. Not set for other request types (e.g.\ GET). .IP \(bu 2 \f[CR]CONTENT_LENGTH=\f[R] the content length, if $CONTENT_TYPE has been set. .IP \(bu 2 \f[CR]ALL_PROXY=\f[R] if a proxy has been set, the proxy URL. WARNING: for security reasons, this \f[B]must\f[R] be respected when making external connections. If a CGI script does not support proxies, it must never make any external connections when the \f[CR]ALL_PROXY\f[R] variable is set, but rather return an error message. .IP \(bu 2 \f[CR]HTTP_COOKIE=\f[R] if set, the Cookie header. .IP \(bu 2 \f[CR]HTTP_REFERER=\f[R] if set, the Referer header. .IP \(bu 2 \f[CR]CHA_TMP_DIR=\f[R] directory used for storing temporary files. .IP \(bu 2 \f[CR]CHA_DIR=\f[R] location of the config file. .PP For requests originating from a urimethodmap rewrite, Chawan will also set the parsed URL\(cqs parts as environment variables. Use of these is highly encouraged, to avoid exploits originating from double\-parsing of URLs. .PP If \f[CR]example://username:password\(atexample.org:1234/path/name.html?example\f[R] is the original URL, then: .IP \(bu 2 \f[CR]MAPPED_URI_SCHEME=\f[R] the scheme of the original URL, in this case \f[CR]example\f[R]. .IP \(bu 2 \f[CR]MAPPED_URI_USERNAME=\f[R] the username part, in this case \f[CR]username\f[R]. If no username was specified, the variable is set to the empty string. .IP \(bu 2 \f[CR]MAPPED_URI_PASSWORD=\f[R] the password part, in this case \f[CR]password\f[R]. If no password was specified, the variable is set to the empty string. .IP \(bu 2 \f[CR]MAPPED_URI_HOST=\f[R] the host part, in this case \f[CR]host.org\f[R] If no host was specified, the variable is set to the empty string. (An example of a URL with no host: \f[CR]about:blank\f[R], here \f[CR]blank\f[R] is the path name.) .IP \(bu 2 \f[CR]MAPPED_URI_PORT=\f[R] the port, in this case \f[CR]1234\f[R]. If no port was specified, the variable is set to the empty string. (In this case, the CGI script is expected to use the default port for the scheme, if any.) .IP \(bu 2 \f[CR]MAPPED_URI_PATH=\f[R] the path name, in this case \f[CR]/path/name.html?example\f[R]. If no path was specified, the variable is set to the empty string. The path name is percent\-encoded. .IP \(bu 2 \f[CR]MAPPED_URI_QUERY=\f[R] the query string, in this case \f[CR]example\f[R]. Unlike in JavaScript, no question mark is prepended to the string. The query string is percent\-encoded as well. .PP The fragment part is omitted intentionally. .SS Request body If the request body is not empty, it is streamed into the program through the standard input. .PP Note that this may be both an application/x\-www\-form\-urlencoded or a multipart/form\-data request; \f[CR]CONTENT_TYPE\f[R] stores information about the request type, and in case of a multipart request, the boundary as well. .SS Tools Chawan provides certain helper binaries that may be useful for CGI scripts. These can be portably accessed by executing \f[CR]\(dq$CHA_LIBEXEC_DIR\(dq/[program]\f[R]. .PP Currently, the following tools are available: .IP \(bu 2 \f[CR]urldec\f[R]: percent\-decode strings passed on standard input. .IP \(bu 2 \f[CR]urlenc\f[R]: percent\-encode strings passed on standard input, taking a percent\-encode set as the first parameter. .SS Troubleshooting Note that standard error is redirected to the browser console (by default, M\-cM\-c). This makes it easy to debug a misbehaving CGI script, but may also slow down the browser in case of excessive logging. If this is not the desired behavior, wrap your script into a shell script that redirects stderr to /dev/null. .SS My script is returning a \(lqFailed to execute script\(rq error message. This means the \f[CR]execl\f[R] call to the script failed. Make sure that your CGI script\(cqs executable bit is set, i.e.\ run \f[CR]chmod +x /path/to/cgi/script\f[R]. .SS My script is returning an \(lqinvalid CGI path\(rq error message. Make sure that you did not include leading slashes. Reminder: \f[CR]cgi\-bin://script\-name\f[R] does not work, use \f[CR]cgi\-bin:script\-name\f[R]. .SS My script is returning a \(lqCGI file not found\(rq error message. Double check that your CGI script is in the correct location. Also, make sure that you are not accidentally calling the script with an absolute path via \f[CR]cgi\-bin:/script\-name\f[R] (instead of the correct \f[CR]cgi\-bin:script\-name\f[R]). .PP It is also possible that \f[CR]external.cgi\-dir\f[R] is not really set to the directory your script is in. Note that by default, this depends on the binary\(cqs path, so e.g.\ if your binary is in \f[CR]\(ti/src/chawan/target/release/bin/cha\f[R], but you put your CGI script to \f[CR]/usr/local/libexec/chawan/cgi\-bin\f[R], then it will not work. .SS My script is returning a \(lqfailed to set up CGI script\(rq error message. This means that either \f[CR]pipe\f[R] or \f[CR]fork\f[R] failed. Maybe you are running out of memory? .SS See also \f[B]cha\f[R](1) \f[B]cha\-urimethodmap\f[R](5) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/cha-config.5����������������������������������������������������������������������0000664�0000000�0000000�00000136071�15202323131�0015773�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" Automatically generated by Pandoc 3.9.0.2 .\" .TH "CHA-CONFIG" "5" .SH Configuration of Chawan Chawan supports configuration of various options like keybindings, user stylesheets, site preferences, etc. The configuration format is similar to toml, with the following exceptions: .IP \(bu 2 Regular tables (\f[CR][table]\f[R]) and inline tables (\f[CR]table = {}\f[R]) have different semantics. The first is additive, meaning default values are not removed. The second is destructive, and clears all default definitions in the table specified. .IP \(bu 2 \f[CR][[table\-array]]\f[R] is sugar for \f[CR][table\-array.n]\f[R], where \f[CR]n\f[R] is the number of declared table arrays. For example, you can declare anonymous siteconfs using the syntax \f[CR][[siteconf]]\f[R]. .PP The canonical configuration file path is \(ti/.chawan/config.toml, but the search path accommodates XDG basedirs as well: .IP "1." 3 config file specified through \-C switch \-> use that .IP "2." 3 \f[CR]$CHA_DIR\f[R] is set \-> use \f[CR]$CHA_DIR/config.toml\f[R] .IP "3." 3 \f[CR]${XDG_CONFIG_HOME:\-\(ti/.config}/chawan/config.toml\f[R] exists \-> use that .IP "4." 3 \f[CR]\(ti/.chawan/config.toml\f[R] exists \-> use that .PP See the \f[I]Path handling\f[R] section for details on how the config directory can be accessed. .PP For a configuration template, see bonus/config.toml in the source distribution. .SS Start Start\-up options are to be placed in the \f[CR][start]\f[R] section. .PP Following is a list of start\-up options: .TP visual\-home = \(lqabout:chawan\(rq \f[B]URL\f[R] .RS Page opened when Chawan is called with the \-V option and no other pages are passed as arguments. .RE .TP startup\-script = \(lq\(rq \f[B]JavaScript code\f[R] .RS Script Chawan runs on start\-up. Pages will not be loaded until this function exits. (Note however that asynchronous functions like setTimeout do not block loading.) .RE .TP headless = false \f[B]boolean\f[R] / \f[B]\(lqdump\(rq\f[R] .RS When set to true or \(lqdump\(rq, the browser does not take input; instead, it prints a rendered version of all buffers in order, then exits. The difference between \f[CR]true\f[R] and \(lqdump\(rq is that \f[CR]true\f[R] first waits for all scripts and network requests to run to completion, while \(lqdump\(rq does not. This means that \f[CR]true\f[R] may never exit when scripting is enabled (e.g.\ if a script sets \f[CR]setInterval\f[R].) Piping \f[CR]cha\f[R] to an external program or passing the \f[CR]\-d\f[R] switch has the same effect as setting this option to \(lqdump\(rq. .RE .TP console\-buffer = true \f[B]boolean\f[R] .RS Whether Chawan should open a console buffer in non\-headless mode. Warning: this is only useful for debugging. Disabling this option without manually redirecting standard error will result in error messages randomly appearing on your screen. .RE .SS Buffer Buffer options are to be placed in the \f[CR][buffer]\f[R] section. .PP These options are global to all buffers. For more granular filtering, use \f[CR][[siteconf]]\f[R]. .PP Example: .IP .EX \f[B][buffer]\f[R] \f[I]# show images on all websites\f[R] images = true \f[I]# disable website CSS\f[R] styling = false \f[I]# Specify user styles.\f[R] user\-style = \(aq\(aq\(aq /* you can import external UA styles like this: */ \(atimport \(aquser.css\(aq; /* or just insert the style inline as follows. */ /* enforce the default text\-decoration for links (i.e. underline). */ a[href] { text\-decoration: revert !important } \(atmedia (monochrome) { /* only in color\-mode \(dqmonochrome\(dq (or \-M) */ /* disable UA style of bold font (no need for important here) */ a[href]:hover { font\-weight: initial } /* ...and italicize the font on hover instead. * here we use important because we don\(aqt want websites to * override the value. */ a[href]:hover { font\-style: italic !important } } \(aq\(aq\(aq \f[I]# You *can* set scripting to true here, but I strongly recommend using\f[R] \f[I]# [[siteconf]] to enable it on a per\-site basis instead.\f[R] .EE .PP Following is a list of buffer options: .TP styling = true \f[B]boolean\f[R] .RS Enable/disable author style sheets. Note that disabling this does not affect user styles. .RE .TP scripting = false \f[B]boolean\f[R] / \f[B]\(lqapp\(rq\f[R] .RS Enable/disable JavaScript in \f[I]all\f[R] buffers. \f[CR]\(dqapp\(dq\f[R] also enables JavaScript APIs that can be used to fingerprint users (e.g.\ querying the window\(cqs size). This may achieve better compatibility with websites that behave like applications, at the cost of reduced privacy. For security and performance reasons, users are encouraged to selectively enable JavaScript with \f[CR][[siteconf]]\f[R] instead of using this setting. .RE .TP images = false \f[B]boolean\f[R] .RS Enable/disable inline image display. .RE .TP cookie = false \f[B]boolean\f[R] / \f[B]\(lqsave\(rq\f[R] .RS Enable/disable cookies on sites. If the string \(lqsave\(rq is specified, then cookies are also saved to \f[CR]external.cookie\-file\f[R]. \f[CR]true\f[R] still reads cookies.txt, but does not modify it. In Chawan, each website gets a separate cookie jar, so websites relying on cross\-site cookies may not work as expected. You may use the \f[CR][[siteconf]]\f[R] \f[CR]\(dqshare\-cookie\-jar\(dq\f[R] setting to adjust this behavior for specific sites. .RE .TP referer\-from = false \f[B]boolean\f[R] .RS Enable/disable the \(lqReferer\(rq header. Defaults to false. For privacy reasons, users are encouraged to leave this option disabled, only enabling it for specific sites in \f[CR][[siteconf]]\f[R]. .RE .TP autofocus = false \f[B]boolean\f[R] .RS When set to true, elements with an \(lqautofocus\(rq attribute are focused on automatically after the buffer is loaded. If scripting is enabled, this also allows scripts to focus on elements. .RE .TP meta\-refresh = \(lqask\(rq \f[B]\(lqnever\(rq\f[R] / \f[B]\(lqalways\(rq\f[R] / \f[B]\(lqask\(rq\f[R] .RS Whether or not \f[CR]http\-equiv=refresh\f[R] meta tags should be respected. \(lqnever\(rq completely disables them, \(lqalways\(rq automatically accepts all of them, \(lqask\(rq brings up a pop\-up menu. .RE .TP history = true \f[B]boolean\f[R] .RS Whether or not browsing history should be saved to the disk. .RE .TP mark\-links = false \f[B]boolean\f[R] .RS Add numeric markers before links. In headless/dump mode, this also prints a list of URLs after the page. .RE .TP user\-style = \(lq\(rq \f[B]CSS stylesheet\f[R] .RS A user stylesheet applied to all buffers. External stylesheets can be imported using the \f[CR]\(atimport \(aqfile.css\(aq;\f[R] syntax. Paths are relative to the configuration directory. Nested \f[CR]\(atimport\f[R] is not supported yet. .RE .SS Search Search options are to be placed in the \f[CR][search]\f[R] section. .PP Following is a list of search options: .TP wrap = true \f[B]boolean\f[R] .RS Whether on\-page searches should wrap around the document. .RE .TP ignore\-case = \(lqauto\(rq \f[B]\(lqauto\(rq\f[R] / \f[B]boolean\f[R] .RS When set to true, document\-wide searches are case\-insensitive by default. When set to \(lqauto\(rq, searches are only case\-sensitive when the search term includes a capital letter. Note: this can also be overridden inline in the search bar (vim\-style), with the escape sequences \f[CR]\(rsc\f[R] (ignore case) and \f[CR]\(rsC\f[R] (strict case). See search mode for details. .RE .SS Encoding Encoding options are to be placed in the \f[CR][encoding]\f[R] section. .PP Following is a list of encoding options: .TP document\-charset = [\(lqutf\-8\(rq, \(lqsjis\(rq, \(lqeuc\-jp\(rq, \(lqlatin2\(rq] \f[B]array of charset label strings\f[R] .RS List of character sets for loading documents. All listed character sets are enumerated until the document has been decoded without errors. In HTML, meta tags and the BOM may override this with a different charset, so long as the specified charset can decode the document correctly. .RE .TP display\-charset = \(lqauto\(rq \f[B]charset label string\f[R] / \f[B]\(lqauto\(rq\f[R] .RS Character set for keyboard input and displaying documents. Used in dump mode as well. (This means that e.g.\ \f[CR]cha \-I EUC\-JP \-O UTF\-8 a > b\f[R] is roughly equivalent to \f[CR]iconv \-f EUC\-JP \-t UTF\-8\f[R].) .RE .SS External External options are to be placed in the \f[CR][external]\f[R] section. .PP Following is a list of external options: .TP tmpdir = {usually \(lq/tmp/cha\-tmp\-user\(rq} \f[B]path\f[R] .RS Directory used to save temporary files. .RE .TP editor = \(lq${VISUAL:\-${EDITOR:\-vi}}\(rq \f[B]shell command\f[R] .RS External editor command. %s is substituted for the file name, %d for the line number. .RE .TP mailcap = [\(lq\(ti/.mailcap\(rq, \(lq/etc/mailcap\(rq, \(lq/usr/etc/mailcap\(rq, \(lq/usr/local/etc/mailcap\(rq] \f[B]array of paths\f[R] .RS Search path for mailcap files. See \f[B]cha\-mailcap\f[R](5) for details. Directories specified first have higher precedence. .RE .TP mime\-types = [\(lq\(ti/.mime.types\(rq, \(lq/etc/mime.types\(rq, \(lq/usr/etc/mime.types\(rq, \(lq/usr/local/etc/mime.types\(rq] \f[B]array of paths\f[R] .RS Search path for mime.types files. See \f[B]cha\-mime.types\f[R](5) for details. .RE .TP auto\-mailcap = \(lq$CHA_DIR/mailcap\(rq \f[B]path\f[R] .RS Mailcap file for entries that are automatically executed. The \(lqOpen as\(rq prompt also saves entries in this file. For backwards\-compatibility, if this is \(lqmailcap\(rq and the file does not exist, Chawan will also check \(lqauto.mailcap\(rq. .RE .TP cgi\-dir = [\(lq$CHA_DIR/cgi\-bin\(rq, \(lq$CHA_LIBEXEC_DIR/cgi\-bin\(rq] \f[B]array of paths\f[R] .RS Search path for local CGI scripts. See \f[B]cha\-cgi\f[R](5) for details. .RE .TP urimethodmap = [\(lq$CHA_DIR/urimethodmap\(rq, \(lq\(ti/.urimethodmap\(rq, \(lq/etc/urimethodmap\(rq] \f[B]array of paths\f[R] .RS Search path for urimethodmap files. See \f[B]cha\-urimethodmap\f[R](5) for details. .RE .TP w3m\-cgi\-compat = false \f[B]boolean\f[R] .RS Enable local CGI compatibility with w3m. In short, it redirects \f[CR]file:///cgi\-bin/*\f[R] and \f[CR]file:///$LIB/cgi\-bin/*\f[R] to \f[CR]cgi\-bin:*\f[R]. See \f[B]cha\-cgi\f[R](5) for details. .RE .TP download\-dir = \(lq${TMPDIR:\-/tmp}/\(rq \f[B]path\f[R] .RS Path to pre\-fill for \(lqSave to:\(rq prompts. .RE .TP show\-download\-panel = true \f[B]boolean\f[R] .RS Whether \f[CR]about:downloads\f[R] should be opened after starting a download. .RE .TP copy\-cmd = \(lqxsel \-bi\(rq \f[B]shell command\f[R] .RS Command to use for \(lqcopy to clipboard\(rq operations. When \f[CR]input.osc52\-copy\f[R] is set to \(lqauto\(rq (the default), \f[CR]copy\-cmd\f[R] is ignored if support for OSC 52 is detected. .RE .TP paste\-cmd = \(lqxsel \-bo\(rq \f[B]shell command\f[R] .RS Command to use for \(lqread from clipboard\(rq operations. .RE .TP bookmark = \(lq$CHA_DATA_DIR/bookmark.md\(rq \f[B]path\f[R] .RS Path to the bookmark.md file. (The file it points to should have a .md extension, so that its type can be correctly deduced.) .RE .TP history\-file = \(lq$CHA_DATA_DIR/history.uri\(rq \f[B]path\f[R] .RS Path to the history file. .RE .TP history\-size = 100 \f[B]number\f[R] .RS Maximum length of the history file. .RE .TP cookie\-file = \(lq$CHA_DATA_DIR/cookies.txt\(rq \f[B]path\f[R] .RS Path to the cookie file. The format is equivalent to curl\(cqs \(lqcookies.txt\(rq format, except that a \(lqjar\(at\(rq part is prepended for cookies that belong in a different jar than the domain. Cookies from this file are used if \(lqbuffer.cookie\(rq (or its equivalent siteconf override) is set to \f[CR]true\f[R] or \f[CR]\(dqsave\(dq\f[R]. This means that \f[CR]true\f[R] sets the cookie\-file to a \(lqread\-only\(rq mode. .RE .SS Input Input options are to be placed in the \f[CR][input]\f[R] section. .TP vi\-numeric\-prefix = true \f[B]boolean\f[R] .RS Whether vi\-style numeric prefixes to commands should be accepted. Only applies for keybindings defined in \f[CR][page]\f[R]. .RE .TP use\-mouse = \(lqauto\(rq \f[B]boolean\f[R] / \f[B]\(lqauto\(rq\f[R] .RS Whether Chawan is allowed to intercept mouse clicks. The current implementation imitates w3m. When set to \(lqauto\(rq (the default), Chawan tries to detect whether mouse support is available. .RE .TP osc52\-copy = \(lqauto\(rq \f[B]boolean\f[R] / \f[B]\(lqauto\(rq\f[R] .RS Whether Chawan should use the OSC 52 escape sequence for copying to the clipboard directly through the terminal. When available, OSC 52 overrides \f[CR]external.copy\-cmd\f[R]. When set to \(lqauto\(rq (the default), Chawan tries to detect whether OSC 52 is available on launch. .RE .TP osc52\-primary = \(lqauto\(rq \f[B]boolean\f[R] / \f[B]\(lqauto\(rq\f[R] .RS Whether Chawan should try to set the primary selection through OSC 52. This happens automatically on mouse selection, and also on all clipboard copies. When set to \(lqauto\(rq (the default), Chawan tries to detect whether the terminal is capable of setting the primary selection. Note that very few terminals actually implement OSC 52 correctly (to my knowledge, only XTerm and Kitty), and on other terminals this might even break copying to the clipboard selection. .RE .TP bracketed\-paste = \(lqauto\(rq \f[B]boolean\f[R] / \f[B]\(lqauto\(rq\f[R] .RS Whether Chawan should ask for bracketed paste. When true, the terminal will (hopefully) mark pasted text with escape sequences, which a) ensures that pasting a newline character into the line editor does not submit the editor, b) allows Chawan to intercept text pasted into the pager, automatically loading it into the browser\(cqs URL bar. When set to \(lqauto\(rq (the default), Chawan tries to only enable bracketed paste if the terminal is known not to misbehave when trying to do so. .RE .TP wheel\-scroll = 5 \f[B]number\f[R] .RS Number of lines to scroll for a mouse wheel event. .RE .TP side\-wheel\-scroll = 5 \f[B]number\f[R] .RS Number of columns to scroll for a mouse side\-wheel event. .RE .TP link\-hint\-chars = \(lqabcdefghijklmnoprstuvxyz\(rq \f[B]string\f[R] .RS A string of characters to use in \f[CR]toggleLinkHints\f[R]. Any Unicode codepoint is accepted, and they are ordered as specified in this option. .RE .PP Examples: .IP .EX [input] vi\-numeric\-prefix = true [page] # Here, the arrow function will be called with the vi numbered prefix if # one was input, and with no argument otherwise. # The numeric prefix can never be zero, so it is safe to test for undefined # using the ternary operator. G = \(aqn => n ? pager.gotoLine(n) : pager.cursorLastLine()\(aq .EE .SS Network Network options are to be placed in the \f[CR][network]\f[R] section. .TP max\-redirect = 10 \f[B]number\f[R] .RS Maximum number of redirections to follow. .RE .TP max\-net\-connections = 12 \f[B]number\f[R] .RS Maximum number of simultaneous network connections allowed in one buffer. Further connections are held back until the number returns below the threshold. .RE .TP prepend\-scheme = \(lqhttps://\(rq \f[B]string\f[R] .RS Prepend this to URLs passed to Chawan (or typed into the URL bar) without a scheme. Note that local files (\f[CR]file:\f[R] scheme) will always be checked first; only if this fails, Chawan will retry the request with \f[CR]prepend\-scheme\f[R] set as the scheme. .RE .TP proxy = \(lq\(rq \f[B]URL\f[R] .RS Specify a proxy for all network requests Chawan makes. Currently, the formats \f[CR]http://user:pass\(atdomain\f[R] and \f[CR]socks5://user:pass\(atdomain\f[R] are accepted. Unlike in curl, \f[CR]socks5h\f[R] is an alias of \f[CR]socks5\f[R], and DNS requests are always tunneled. Can be overridden by siteconf. .RE .TP default\-headers = {see bonus/config.toml} \f[B]table\f[R] .RS Specify a table of default headers for all HTTP(S) network requests. Can be overridden by siteconf. .RE .TP allow\-http\-from\-file = false \f[B]boolean\f[R] .RS \f[B]WARNING: think twice before enabling this.\f[R] Allows HTTP and HTTPS requests from the \f[CR]file:\f[R] and \f[CR]stream:\f[R] schemes. This is a bad idea in general, because it allows local files to ping remote servers (a functionality commonly abused by HTML e\-mails to track your mailbox activity). On the other hand, it allows loading images in HTML e\-mails if you don\(cqt care about the privacy implications. .RE .SS Display Display options are to be placed in the \f[CR][display]\f[R] section. .PP Following is a list of display options: .TP color\-mode = \(lqauto\(rq \f[B]\(lqmonochrome\(rq\f[R] / \f[B]\(lqansi\(rq\f[R] / \f[B]\(lqeight\-bit\(rq\f[R] / \f[B]\(lqtrue\-color\(rq\f[R] / \f[B]\(lqauto\(rq\f[R] .RS Set the color mode. \(lqauto\(rq for automatic detection, \(lqmonochrome\(rq for black on white, \(lqansi\(rq for eight ANSI plus eight aixterm colors, \(lqeight\-bit\(rq for 256\-color mode, and \(lqtrue\-color\(rq for 24\-bit colors. .RE .TP format\-mode = \(lqauto\(rq \f[B]\(lqauto\(rq\f[R] / \f[B][\(lqbold\(rq, \(lqitalic\(rq, \(lqunderline\(rq, \(lqreverse\(rq, \(lqstrike\(rq, \(lqoverline\(rq, \(lqblink\(rq]\f[R] .RS Specifies allowed output formatting modes. Accepts the string \(lqauto\(rq or an array of specific attributes. \(lqauto\(rq (the default) tries to detect supported formatting modes when launched visually, and omits all formatting modes in dump mode. An empty array (\f[CR][]\f[R]) disables formatting even in visual mode. .RE .TP no\-format\-mode = [\(lqoverline\(rq] \f[B][\(lqbold\(rq, \(lqitalic\(rq, \(lqunderline\(rq, \(lqreverse\(rq, \(lqstrike\(rq, \(lqoverline\(rq, \(lqblink\(rq]\f[R] .RS Disable specific formatting modes. .RE .TP image\-mode = \(lqauto\(rq \f[B]\(lqauto\(rq\f[R] / \f[B]\(lqnone\(rq\f[R] / \f[B]\(lqsixel\(rq\f[R] / \f[B]\(lqkitty\(rq\f[R] .RS Specifies the image output mode. \(lqsixel\(rq uses sixels for output, \(lqkitty\(rq uses the Kitty image display protocol, \(lqnone\(rq disables image display completely. \(lqauto\(rq (the default) detects sixel or kitty support automatically, and falls back to \(lqnone\(rq when neither are available. This is expected to work on all known terminals with functional image support. Note that \f[CR]buffer.images\f[R] must be enabled for images to load at all. .RE .TP sixel\-colors = \(lqauto\(rq \f[B]\(lqauto\(rq\f[R] / \f[B]2..65535\f[R] .RS Only applies when \f[CR]display.image\-mode=\(dqsixel\(dq\f[R]. Setting this to a number overrides the number of sixel color registers reported by the terminal. .RE .TP alt\-screen = \(lqauto\(rq \f[B]\(lqauto\(rq\f[R] / \f[B]boolean\f[R] .RS Enable/disable the alternative screen. \(lqauto\(rq (the default) tries to detect support for this feature. (However, since Chawan does not link to terminfo, you should not expect hacks which remove the respective terminfo description to work.) .RE .TP highlight\-color = \(lq\-cha\-ansi(bright\-cyan)\(rq \f[B]CSS color\f[R] .RS Set the highlight color for incremental search and marks. CSS color names, hex values, and color functions are all accepted. In monochrome mode, this setting is ignored; instead, reverse video is used. .RE .TP highlight\-marks = true \f[B]boolean\f[R] .RS Enable/disable highlighting of marks. .RE .TP double\-width\-ambiguous = false \f[B]boolean\f[R] .RS Assume the terminal displays characters in the East Asian Ambiguous category as double\-width characters. Useful when e.g.\ ○ occupies two cells. .RE .TP minimum\-contrast = 100 \f[B]0..235\f[R] .RS Specify the minimum difference between the luminance (Y) of the default terminal background and the foreground as represented in YUV. 0 disables this function (i.e.\ allows black letters on black background, etc). Note: in the past, this option used to apply to all colors, but since v0.3 Chawan only performs color contrast correction when either the foreground or background color is the terminal default. Also, the contrast correction algorithm is still not perfect, so future changes are to be expected. .RE .TP set\-title = true \f[B]boolean\f[R] .RS Set the terminal emulator\(cqs window title to that of the current page. .RE .TP default\-background\-color = \(lqauto\(rq \f[B]\(lqauto\(rq\f[R] / \f[B]RGB color\f[R] .RS Overrides the assumed background color of the terminal. \(lqauto\(rq leaves background color detection to Chawan. .RE .TP default\-foreground\-color = \(lqauto\(rq \f[B]\(lqauto\(rq\f[R] / \f[B]RGB color\f[R] .RS Sets the assumed foreground color of the terminal. \(lqauto\(rq leaves foreground color detection to Chawan. .RE .TP columns = 80, lines = 24, pixels\-per\-column = 9, pixels\-per\-line = 18 \f[B]number\f[R] .RS Fallback values for the number of columns, lines, pixels per column, and pixels per line for the cases where it cannot be determined automatically. (For example, these values are used in dump mode.) .RE .TP force\-columns = false, force\-lines = false, force\-pixels\-per\-column = false, force\-pixels\-per\-line = false \f[B]boolean\f[R] .RS Force\-set columns, lines, pixels per column, or pixels per line to the fallback values provided above. .RE .SS Status Options concerning the status bar (last line on the screen) are to be placed in the \f[CR][status]\f[R] section. .PP Following is a list of status options: .TP show\-cursor\-position = true \f[B]boolean\f[R] .RS Whether or not the current line number should be displayed. .RE .TP show\-hover\-link = true \f[B]boolean\f[R] .RS Whether or not the link under the cursor should be displayed. .RE .TP format\-mode = \(lqreverse\(rq \f[B]{see [display] section}\f[R] .RS Formatting of the status bar. .RE .SS Omnirule The omni\-bar (by default opened with C\-l) can be used to perform searches using omni\-rules. These are to be specified as sub\-keys to table \f[CR][omnirule]\f[R]. (The sub\-key itself is ignored; you can use anything as long it doesn\(cqt conflict with other keys.) .PP Examples: .IP .EX # Search using DuckDuckGo Lite. # (This rule is included in the default config, although C\-k invokes # Brave search.) [omnirule.ddg] match = \(aq\(haddg:\(aq substitute\-url = \(aq(x) => \(dqhttps://lite.duckduckgo.com/lite/?kp=\-1&kd=\-1&q=\(dq + encodeURIComponent(x.split(\(dq:\(dq).slice(1).join(\(dq:\(dq))\(aq # To use the above rule, open the URL bar with C\-k, clear it with # C\-u, and type ddg:keyword. # Alternatively, you can also redefine C\-k like: [page] \(aqC\-k\(aq = \(aq() => pager.load(\(dqddg:\(dq)\(aq # Search using Wikipedia, Firefox\-style. # The [[omnirule]] syntax introduces an anonymous omnirule; it is # equivalent to the named one. [[omnirule]] match = \(aq\(ha\(atwikipedia\(aq substitute\-url = \(aq(x) => \(dqhttps://en.wikipedia.org/wiki/Special:Search?search=\(dq + encodeURIComponent(x.replace(/\(atwikipedia/, \(dq\(dq))\(aq .EE .PP As noted above, the default config includes some built\-in rules, selected according to the maintainer\(cqs preference and the minimum criterion that they must work without cookies and JavaScript. Currently, these are: .IP \(bu 2 \f[CR]ddg:\f[R] \- DuckDuckGo Lite. .IP \(bu 2 \f[CR]br:\f[R] \- Brave Search. .IP \(bu 2 \f[CR]wk:\f[R] \- English Wikipedia. .IP \(bu 2 \f[CR]wd:\f[R] \- English Wikitionary. .IP \(bu 2 \f[CR]mo:\f[R] \- Mojeek. .PP Omnirule options: .TP match \f[B]regex\f[R] .RS Regular expression used to match the input string. Note that websites passed as arguments are matched as well. Note: regexes are handled according to the match mode regex handling rules. .RE .TP substitute\-url \f[B]JavaScript function\f[R] .RS A JavaScript function Chawan will pass the input string to. If a new string is returned, it will be parsed instead of the old one. .RE .SS Siteconf Configuration options can be specified for individual sites. Entries are to be specified as sub\-keys to table \f[CR][siteconf]\f[R]. (The sub\-key itself is ignored; you can use anything as long it doesn\(cqt conflict with other keys.) .PP Most siteconf options can also be specified globally; see the \(lqoverrides\(rq field. .PP Examples: .IP .EX # Enable cookies on the orange website for log\-in. [siteconf.hn] url = \(aqhttps://news\(rs.ycombinator\(rs.com/.*\(aq cookie = true # Redirect npr.org to text.npr.org. [siteconf.npr] host = \(aq(www\(rs.)?npr\(rs.org\(aq rewrite\-url = \(aq\(aq\(aq (x) => { x.host = \(dqtext.npr.org\(dq; const s = x.pathname.split(\(aq/\(aq); x.pathname = s.at(s.length > 2 ? \-2 : 1); /* No need to return; URL objects are passed by reference. */ } \(aq\(aq\(aq # Allow cookie sharing on *sr.ht domains. [siteconf.sr\-ht] host = \(aq(.*\(rs.)?sr\(rs.ht\(aq # either \(aqsomething.sr.ht\(aq or \(aqsr.ht\(aq cookie = true # enable cookies (read\-only; use \(dqsave\(dq to persist them) share\-cookie\-jar = \(aqsr.ht\(aq # use the cookie jar of \(aqsr.ht\(aq for all matched hosts # Use the \(dqvector\(dq skin on Wikipedia. # The [[siteconf]] syntax introduces an anonymous siteconf; it is # equivalent to the above ones. [[siteconf]] url = \(aq\(hahttps?://[a\-z]+\(rs.wikipedia\(rs.org/wiki/(?!.*useskin=.*)\(aq rewrite\-url = \(aqx => x.searchParams.append(\(dquseskin\(dq, \(dqvector\(dq)\(aq # Make imgur send us images. [siteconf.imgur] host = \(aq(i\(rs.)?imgur\(rs.com\(aq default\-headers = { User\-Agent = \(dqMozilla/5.0 chawan\(dq, Accept = \(dq*/*\(dq, Accept\-Encoding = \(dqgzip, deflate\(dq, Accept\-Language = \(dqen;q=1.0\(dq, Pragma = \(dqno\-cache\(dq, Cache\-Control = \(dqno\-cache\(dq } .EE .PP Siteconf options: .TP url \f[B]regex\f[R] .RS Regular expression used to match the URL. Either this or the \f[CR]host\f[R] option must be specified. Note: regexes are handled according to the match mode regex handling rules. .RE .TP host \f[B]regex\f[R] .RS Regular expression used to match the host part of the URL (i.e.\ domain name/ip address). Either this or the \f[CR]url\f[R] option (but not both) must be specified. Note: regexes are handled according to the match mode regex handling rules. .RE .TP rewrite\-url \f[B]JavaScript function\f[R] .RS A JavaScript function Chawan will pass the site\(cqs URL object to. If a new URL is returned, or the URL object is modified in any way, Chawan will transparently redirect the user to this new URL. .RE .TP cookie = buffer.cookie \f[B]boolean\f[R] / \f[B]\(lqsave\(rq\f[R] .RS Whether loading (with \(lqsave\(rq, also saving) cookies should be allowed for this URL. .RE .TP share\-cookie\-jar \f[B]host string\f[R] .RS Cookie jar to use for this domain. Useful for e.g.\ sharing cookies with subdomains. .RE .TP referer\-from = buffer.referer\-from \f[B]boolean\f[R] .RS Whether or not Chawan should send a Referer header when opening requests originating from this domain. Simplified example: if you click a link on a.com that refers to b.com, and referer\-from is true, b.com is sent \(lqa.com\(rq as the Referer header. .RE .TP scripting = buffer.scripting \f[B]boolean\f[R] / \f[B]\(lqapp\(rq\f[R] .RS Enable/disable JavaScript execution on this site. See \f[CR]buffer.scripting\f[R] for details. .RE .TP styling = buffer.styling \f[B]boolean\f[R] .RS Enable/disable author styles (CSS) on this site. .RE .TP images = buffer.images \f[B]boolean\f[R] .RS Enable/disable loading of images on this site. .RE .TP document\-charset = encoding.document\-charset \f[B]charset label string\f[R] .RS Specify the default encoding for this site. .RE .TP proxy = network.proxy \f[B]URL string\f[R] .RS Specify a proxy for network requests fetching contents of this buffer. .RE .TP default\-headers = network.default\-headers \f[B]table\f[R] .RS Specify a list of default headers for HTTP(S) network requests to this buffer. .RE .TP insecure\-ssl\-no\-verify = false \f[B]boolean\f[R] .RS When set to true, this disables peer and hostname verification for SSL keys on this site, like \f[CR]curl \-\-insecure\f[R] would. Please do not use this unless you are absolutely sure you know what you are doing. .RE .TP autofocus = buffer.autofocus \f[B]boolean\f[R] .RS When set to true, elements with an \(lqautofocus\(rq attribute are focused on automatically after the buffer is loaded. If scripting is enabled, this also allows scripts to focus on elements. .RE .TP meta\-refresh = buffer.meta\-refresh \f[B]\(lqnever\(rq\f[R] / \f[B]\(lqalways\(rq\f[R] / \f[B]\(lqask\(rq\f[R] .RS Whether or not \f[CR]http\-equiv=refresh\f[R] meta tags and headers should be respected. \(lqnever\(rq completely disables them, \(lqalways\(rq automatically accepts all of them, \(lqask\(rq brings up a pop\-up menu. .RE .TP history = buffer.history \f[B]boolean\f[R] .RS Whether or not browsing history should be saved to the disk for this URL. .RE .TP mark\-links = buffer.mark\-links \f[B]boolean\f[R] .RS Add numeric markers before links. .RE .TP user\-style = buffer.user\-style \f[B]string\f[R] .RS Specify a user style sheet specific to the site. Refer to \f[CR]buffer.user\-style\f[R] for details. .RE .SS Keybindings Keybindings are to be placed in these sections: .IP \(bu 2 for pager interaction: \f[CR][page]\f[R] .IP \(bu 2 for line editing: \f[CR][line]\f[R] .PP Keybindings are configured using the syntax .IP .EX \(aq<keybinding>\(aq = \(aq<action>\(aq .EE .PP Where \f[CR]<keybinding>\f[R] is a combination of unicode characters using the syntax described below. .PP \f[CR]<action>\f[R] is either a command defined in the \f[CR][cmd]\f[R] section, or a JavaScript expression. This document only describes the pre\-defined actions in the default config; for a description of the API, see \f[B]cha\-api\f[R](7). .PP Examples: .IP .EX \f[I]# show change URL when Control, Escape and j are pressed\f[R] \(aqC\-M\-j\(aq = \(aqload\(aq \f[I]# go to the first line of the page when g is pressed twice without a preceding\f[R] \f[I]# number, or to the line when a preceding number is given.\f[R] \(aqg g\(aq = \(aqgotoLineOrStart\(aq \f[I]# JS functions and expressions are accepted too. Following replaces the\f[R] \f[I]# default search engine with DuckDuckGo Lite.\f[R] \f[I]# (See api.md for a list of available functions, and a discussion on how\f[R] \f[I]# to add your own \(dqnamespaced\(dq commands like above.)\f[R] \(aqC\-k\(aq = \(aq() => pager.load(\(dqddg:\(dq)\(aq .EE .SS Keybinding format A keybinding is a space\-separated list of keys, optionally prefixed by modifiers \f[CR]S\-\f[R] (shift), \f[CR]C\-\f[R] (control), or \f[CR]M\-\f[R] (meta). .PP In general, ASCII/Unicode keys can be written as\-is. The exception is space, which is written as \f[CR]SPC\f[R]. .PP Other supported named keys are: \f[CR]TAB\f[R], \f[CR]ESC\f[R], \f[CR]RET\f[R] (return key), \f[CR]LF\f[R] (enter key/line feed), \f[CR]Left\f[R], \f[CR]Up\f[R], \f[CR]Down\f[R], \f[CR]Right\f[R] (cursor keys), \f[CR]PageUp\f[R], \f[CR]PageDown\f[R] (page up/down), \f[CR]Home\f[R], \f[CR]End\f[R], and function keys \f[CR]F1\f[R] through \f[CR]F20\f[R]. .PP For backwards\-compatibility, spaces can be omitted from key sequences that do not start with an upper\-case letter. For example, \f[CR]\(aqgg\(aq\f[R] and \f[CR]\(aqg g\(aq\f[R] are equivalent. However, components that start with an upper\-case letter (e.g.\ \f[CR]\(aqGg\(aq\f[R]) are reserved for key names, so those must be space\-separated (e.g.\ \f[CR]\(aqG g\(aq\f[R]) to avoid ambiguous parsing. .PP Also, for backwards\-compatibility, spaces at the beginning/end of the keybinding are translated to \f[CR]SPC\f[R]. .SS Pager actions Default keybindings are highlighted in \f[B]bold\f[R]. .TP quit \f[B]q\f[R] .RS Exit the browser. .RE .TP suspend \f[B]C\-z\f[R] .RS Temporarily suspend the browser Note: this also suspends e.g.\ buffer processes or CGI scripts. So if you are downloading something, that will be delayed until you restart the process. .RE .TP load \f[B]C\-l\f[R] .RS Open the current address in the URL bar. .RE .TP loadCursor \f[B]M\-l\f[R] .RS Open the address of the link or image being hovered in the URL bar. If no link/image is under the cursor, an empty URL bar is opened. .RE .TP loadEmpty Open an empty address bar. .TP webSearch \f[B]C\-k\f[R] .RS Open the URL bar with an arbitrary search engine. At the moment, this is Brave Search, but this may change in the future. .RE .TP dupeBuffer \f[B]M\-u\f[R] .RS Duplicate the current buffer. This is a shallow clone, so modifications to one buffer will affect the other. .RE .TP reloadBuffer \f[B]U\f[R] .RS Open a new buffer with the current buffer\(cqs URL, replacing the current buffer. .RE .TP lineInfo \f[B]C\-g\f[R] .RS Display information about the current line on the status line. .RE .TP toggleSource \f[B]\(rs\f[R] .RS If viewing an HTML buffer, open a new buffer with its source. Otherwise, open the current buffer\(cqs contents as HTML. .RE .TP saveScreen \f[B]s s\f[R] .RS Save the rendered buffer to a file. .RE .TP saveSource \f[B]s S\f[R] .RS Save the buffer\(cqs source to a file. .RE .TP editScreen \f[B]s e\f[R] .RS Open the rendered buffer in an editor. .RE .TP editSource \f[B]s E\f[R] .RS Open the buffer\(cqs source in an editor. .RE .TP discardBuffer \f[B]D\f[R] .RS Discard the current buffer, and move back to the previous/next buffer depending on what the previously viewed buffer was. .RE .TP discardBufferPrev, discardBufferNext \f[B]d ,\f[R], \f[B]d .\f[R] .RS Discard the current buffer, and move back to the previous/next buffer, or open the link under the cursor. .RE .TP discardTree \f[B]M\-d\f[R] .RS Discard all child buffers of the current buffer. .RE .TP nextBuffer, prevBuffer \f[B].\f[R], \f[B],\f[R] .RS Switch to the next or previous buffer respectively. .RE .TP enterCommand \f[B]M\-c\f[R] .RS Directly enter a JavaScript command. Note that this interacts with the pager, not the website being displayed. .RE .TP searchForward, searchBackward Search for a string in the current buffer, forwards or backwards. .TP isearchForward, searchBackward \f[B]/\f[R], \f[B]?\f[R] .RS Incremental\-search for a string, highlighting the first result, forwards or backwards. .RE .TP searchNext, searchPrev \f[B]n\f[R], \f[B]N\f[R] .RS Jump to the nth (or if unspecified, first) next/previous search result. .RE .TP peek Display a message of the current buffer\(cqs URL on the status line. .TP peekCursor \f[B]u\f[R] .RS Display a message of the URL or title under the cursor on the status line. Multiple calls allow cycling through the two. (i.e.\ by default, press u once \-> title, press again \-> URL) .RE .TP showFullAlert \f[B]s u\f[R] .RS Show the last alert inside the line editor. You can also view previous ones using C\-p or C\-n. .RE .TP copyURL \f[B]M\-y\f[R] .RS Copy the current buffer\(cqs URL to the system clipboard. .RE .TP copyCursorLink \f[B]y u\f[R] .RS Copy the link under the cursor to the system clipboard. .RE .TP copyCursorImage \f[B]y I\f[R] .RS Copy the URL of the image under the cursor to the system clipboard. .RE .TP gotoClipboardURL \f[B]M\-p\f[R] .RS Go to the URL currently on the clipboard. .RE .TP openBookmarks \f[B]M\-b\f[R] .RS Open the bookmark file. .RE .TP addBookmark \f[B]M\-a\f[R] .RS Add the current page to your bookmarks. .RE .TP toggleLinkHints \f[B]f\f[R] .RS Show hints before each link (or button). After typing a hint, the cursor is placed on the respective link. The hint character set may be customized with \f[CR]input.link\-hint\-chars\f[R]. .RE .TP toggleLinkHintsAutoClick Same as \f[CR]toggleLinkHints\f[R], but also click the selected link. .SS Buffer actions \f[CR]n\f[R] refers to a number preceding the action. e.g.\ in \f[CR]10gg\f[R], \f[CR]n\f[R] is 10. If no preceding number is input, then it is left unspecified. .PP Default keybindings are highlighted in \f[B]bold\f[R]. .TP cursorUp, cursorDown \f[B]j\f[R]/\f[B]C\-p\f[R]/\f[B]Up\f[R], \f[B]k\f[R]/\f[B]C\-n\f[R]/\f[B]Down\f[R] .RS Move the cursor upwards/downwards by \f[CR]n\f[R] lines, or if \f[CR]n\f[R] is unspecified, by 1. .RE .TP cursorLeft, cursorRight \f[B]h\f[R]/\f[B]Left\f[R], \f[B]l\f[R]/\f[B]Right\f[R] .RS Move the cursor to the left/right by \f[CR]n\f[R] cells, or if \f[CR]n\f[R] is unspecified, by 1. .RE .TP cursorLineBegin \f[B]0\f[R]/\f[B]Home\f[R] .RS Move the cursor to the first cell of the line. .RE .TP cursorLineTextStart \f[B]\(ha\f[R] .RS Move the cursor to the first non\-blank character of the line. .RE .TP cursorLineEnd \f[B]$\f[R]/\f[B]End\f[R] .RS Move the cursor to the last cell of the line. .RE .TP cursorNextWord, cursorNextViWord, cursorNextBigWord \f[B]w\f[R], \f[B]W\f[R] .RS Move the cursor to the beginning of the nth next word. .RE .TP cursorPrevWord, cursorPrevViWord, cursorPrevBigWord Move the cursor to the end of the nth previous word. .TP cursorWordEnd, cursorViWordEnd, cursorBigWordEnd \f[B]e\f[R], \f[B]E\f[R] .RS Move the cursor to the end of the current word, or if already there, to the end of the nth next word. .RE .TP cursorWordBegin, cursorViWordBegin, cursorBigWordBegin \f[B]b\f[R], \f[B]B\f[R] .RS Move the cursor to the beginning of the current word, or if already there, to the end of the nth previous word. .RE .TP cursorPrevLink, cursorNextLink \f[B][\f[R], \f[B]]\f[R] .RS Move the cursor to the end/beginning of the previous/next clickable element (e.g.\ link, input field, etc). .RE .TP cursorPrevParagraph, cursorNextParagraph \f[B]{\f[R], \f[B]}\f[R] .RS Move the cursor to the end/beginning of the nth previous/next paragraph. .RE .TP cursorRevNthLink Move the cursor to the nth link of the document, counting backwards from the document\(cqs last line. .TP cursorNthLink Move the cursor to the nth link of the document. .TP pageUp, pageDown, pageLeft, pageRight \f[B]C\-b\f[R]/\f[B]PageUp\f[R], \f[B]C\-f\f[R]/\f[B]PageDown\f[R], \f[B]z H\f[R], \f[B]z L\f[R] .RS Scroll up/down/left/right by \f[CR]n\f[R] pages, or if \f[CR]n\f[R] is unspecified, by one page. .RE .TP halfPageUp, halfPageDown, halfPageLeft, halfPageUp \f[B]C\-u\f[R], \f[B]C\-d\f[R] .RS Scroll up/down/left/right by \f[CR]n\f[R] half pages, or if \f[CR]n\f[R] is unspecified, by one page. .RE .TP scrollUp, scrollDown, scrollLeft, scrollRight \f[B]K\f[R]/\f[B]C\-y\f[R], \f[B]J\f[R]/\f[B]C\-e\f[R], \f[B]z h\f[R], \f[B]z l\f[R] .RS Scroll up/down/left/right by \f[CR]n\f[R] lines, or if \f[CR]n\f[R] is unspecified, by one line. .RE .TP click \f[B]RET\f[R]/\f[B]LF\f[R] .RS Click the HTML element currently under the cursor. \f[CR]n\f[R] specifies the number of clicks in JS events. .RE .TP rightClick \f[B]c\f[R] .RS Send a right click to the buffer. If it doesn\(cqt catch the event (i.e.\ no JS context menu is shown), toggle the menu instead. .RE .TP toggleMenu \f[B]C\f[R] .RS Toggle the menu. .RE .TP viewImage \f[B]I\f[R] .RS View the image currently under the cursor in an external viewer. .RE .TP reshape \f[B]R\f[R] .RS Reshape the current buffer (=render the current page anew). Useful if the layout is not updating even though it should have. .RE .TP redraw \f[B]r\f[R] .RS Redraw screen contents. Useful if something messed up the display. .RE .TP cursorFirstLine, cursorLastLine Move to the beginning/end in the buffer. .TP cursorTop, cursorMiddle, cursorBottom \f[B]H\f[R], \f[B]M\f[R], \f[B]L\f[R] .RS Move to the first line/line in the middle of/last line on the screen. (Equivalent to \f[CR]H\f[R], \f[CR]M\f[R], \f[CR]L\f[R] in vi.) .RE .TP raisePage, raisePageBegin, centerLine, centerLineBegin, lowerPage, lowerPageBegin \f[B]z t\f[R], \f[B]z RET\f[R], \f[B]z z\f[R], \f[B]z .\f[R], \f[B]z b\f[R], \f[B]z \-\f[R] .RS If \f[CR]n\f[R] is specified, move cursor to line \f[CR]n\f[R]. Then, .IP \(bu 2 \f[CR]raisePage\f[R] scrolls down so that the cursor is on the top line of the screen. (vi \f[CR]z RET\f[R], vim \f[CR]z t\f[R].) .IP \(bu 2 \f[CR]centerLine\f[R] shifts the screen so that the cursor is in the middle of the screen. (vi \f[CR]z .\f[R], vim \f[CR]z z\f[R].) .IP \(bu 2 \f[CR]lowerPage\f[R] scrolls up so that the cursor is on the bottom line of the screen. (vi \f[CR]z \-\f[R], vim \f[CR]z b\f[R].) The \-Begin variants also move the cursor to the line\(cqs first non\-blank character, as the original keybindings in vi do. .RE .TP nextPageBegin \f[B]z +\f[R] .RS If \f[CR]n\f[R] is specified, move to the screen before the nth line and raise the page. Otherwise, go to the next screen\(cqs first line and raise the page. .RE .TP previousPageBegin \f[B]z \(ha\f[R] .RS If \f[CR]n\f[R] is specified, move to the screen before the nth line and lower the page. Otherwise, go to the previous screen\(cqs last line and lower the page. .RE .TP cursorLeftEdge, cursorMiddleColumn, cursorRightEdge \f[B]g 0\f[R], \f[B]g c\f[R], \f[B]g $\f[R] .RS Move to the first/middle/last column on the screen. .RE .TP centerColumn Center screen around the current column. (w3m \f[CR]Z\f[R].) .TP gotoLineOrStart, gotoLineOrEnd \f[B]g g\f[R], \f[B]G\f[R] .RS If \f[CR]n\f[R] is specified, jump to line \f[CR]n\f[R]. Otherwise, jump to the first/last line of the buffer. .RE .TP gotoColumnOrBegin, gotoColumnOrEnd \f[B]|\f[R] .RS If \f[CR]n\f[R] is specified, jump to column \f[CR]n\f[R] of the current line. Otherwise, jump to the first/last column. .RE .TP mark \f[B]m\f[R] .RS Wait for a character \f[CR]x\f[R] and then set a mark with the ID \f[CR]x\f[R]. .RE .TP gotoMark, gotoMarkY \f[B]\(ga\f[R], \f[B]\(cq\f[R] .RS Wait for a character \f[CR]x\f[R] and then jump to the mark with the ID \f[CR]x\f[R] (if it exists on the page). \f[CR]gotoMark\f[R] sets both the X and Y positions; gotoMarkY only sets the Y position. .RE .TP markURL \f[B]:\f[R] .RS Convert URL\-like strings to anchors on the current page. .RE .TP saveLink \f[B]s RET\f[R] .RS Save resource from the URL pointed to by the cursor to the disk. .RE .TP saveSource \f[B]s S\f[R] .RS Save the source of the current buffer to the disk. .RE .TP saveImage \f[B]s I\f[R] .RS Save the image currently under the cursor. .RE .TP toggleImages \f[B]M\-i\f[R] .RS Toggle display of images in the current buffer. .RE .TP toggleScripting \f[B]M\-j\f[R] .RS Reload the current buffer with scripting enabled/disabled. .RE .TP toggleCookie \f[B]M\-k\f[R] .RS Reload the current buffer with cookies enabled/disabled. .RE .TP cursorSearchWordForward \f[B]C\-a\f[R], \f[B]*\f[R] .RS Search for the word currently under the cursor. .RE .TP cursorSearchWordBackward \f[B]#\f[R] .RS Search for the word currently under the cursor, backwards. .RE .SS Line\-editing actions .TP line.submit \f[B]RET\f[R], \f[B]LF\f[R] .RS Submit the currently entered text. .RE .TP line.cancel \f[B]C\-g\f[R] .RS Close the editor and cancel the operation it was opened for. .RE .TP line.copyOrCancel \f[B]C\-c\f[R] .RS If there is an active selection, copy it. Otherwise, it\(cqs the same as \f[CR]line.cancel\f[R]. .RE .TP line.backspace, line.delete \f[B]C\-h\f[R], \f[B]C\-d\f[R] .RS Delete character before (backspace)/after (delete) the cursor. .RE .TP line.clear, line.kill \f[B]C\-u\f[R]/\f[B]C\-x C\-?\f[R], \f[B]C\-k\f[R] .RS Delete text before (clear)/after (kill) the cursor. .RE .TP line.openEditor \f[B]C\-x C\-e\f[R] .RS Open the line editor\(cqs contents in $EDITOR. .RE .TP line.clearWord, line.killWord \f[B]C\-w\f[R], \f[B]M\-d\f[R] .RS Delete word before (clear)/after (kill) the cursor. .RE .TP line.backward, line.forward \f[B]C\-b\f[R], \f[B]C\-f\f[R] .RS Move cursor backward/forward by one character. .RE .TP line.prevWord, line.nextWord \f[B]M\-b\f[R], \f[B]M\-f\f[R] .RS Move cursor to the previous/next word by one character .RE .TP line.begin, line.end \f[B]C\-a\f[R]/\f[B]Home\f[R], \f[B]C\-e\f[R]/\f[B]End\f[R] .RS Move cursor to the beginning/end of the line. .RE .TP line.escape \f[B]C\-v\f[R] .RS Ignore keybindings for next character. .RE .TP line.prevHist, line.nextHist \f[B]C\-p\f[R], \f[B]C\-n\f[R] .RS Jump to the previous/next history entry .RE .PP Note: to facilitate URL editing, the line editor has a different definition of what a word is than the pager. For the line editor, a word is either a sequence of alphanumeric characters, or any single non\-alphanumeric character. (This means that e.g.\ \f[CR]https://\f[R] consists of four words: \f[CR]https\f[R], \f[CR]:\f[R], \f[CR]/\f[R] and \f[CR]/\f[R].) .IP .EX # Control+A moves the cursor to the beginning of the line. \(aqC\-a\(aq = \(aqline.begin\(aq # Escape+D deletes everything after the cursor until it reaches a word\-breaking # character. \(aqM\-d\(aq = \(aqline.killWord\(aq .EE .SS Appendix .SS Regex handling Regular expressions are currently handled using the libregexp library from QuickJS. This means that all regular expressions work as in JavaScript. .PP There are two different modes of regex preprocessing in Chawan: \(lqsearch\(rq mode and \(lqmatch\(rq mode. Match mode is used for configurations (meaning in all values in this document described as \(lqregex\(rq). Search mode is used for the on\-page search function (using searchForward/isearchForward etc.) .SS Match mode Regular expressions are assumed to be exact matches, except when they start with a caret (\(ha) sign or end with an unescaped dollar ($) sign. .PP In other words, the following transformations occur: .IP .EX \(haabcd \-> \(haabcd (no change, only beginning is matched) efgh$ \-> efgh$ (no change, only end is matched) \(haijkl$ \-> \(haijkl$ (no change, the entire line is matched) mnop \-> \(hamnop$ (changed to exact match, the entire line is matched) .EE .PP Match mode has no way to toggle JavaScript regex flags like \f[CR]i\f[R]. .SS Search mode For on\-page search, the above transformations do not apply; the search \f[CR]/abcd\f[R] searches for the string \f[CR]abcd\f[R] inside all lines. .PP Search mode also has some other convenience transformations (these do not work in match mode): .IP \(bu 2 The string \f[CR]\(rsc\f[R] (backslash + lower\-case c) inside a search\-mode regex enables case\-insensitive matching. .IP \(bu 2 Conversely, \f[CR]\(rsC\f[R] (backslash + capital C) disables case\-insensitive matching. (Useful if you have \f[CR]ignore\-case\f[R] set to true, which is the default.) .IP \(bu 2 \f[CR]\(rs<\f[R] and \f[CR]\(rs>\f[R] is converted to \f[CR]\(rsb\f[R] (as in vi, grep, etc.) .PP Like match mode, search mode operates on individual lines. This means that search patterns do not match text wrapped over multiple lines. .SS Path handling Rules for path handling are similar to how the shell handles strings. .IP \(bu 2 Tilde\-expansion is used to determine the user\(cqs home directory. So e.g.\ \f[CR]\(ti/whatever\f[R] works. .IP \(bu 2 Environment variables can be used like \f[CR]$ENV_VAR\f[R]. .IP \(bu 2 Relative paths are relative to the Chawan configuration directory (i.e.\ \f[CR]$CHA_DIR\f[R]). .PP Some environment variables are also exported by Chawan: .IP \(bu 2 \f[CR]$CHA_BIN_DIR\f[R]: the directory which the \f[CR]cha\f[R] binary resides in. Symbolic links are automatically resolved to determine this path. .IP \(bu 2 \f[CR]$CHA_LIBEXEC_DIR\f[R]: the directory for all executables Chawan uses for operation. By default, this is \f[CR]$CHA_BIN_DIR/../libexec/chawan\f[R]. .IP \(bu 2 \f[CR]$CHA_DIR\f[R]: the configuration directory. (This can also be set by the user; see the top section for details.) .IP \(bu 2 \f[CR]$CHA_DATA_DIR\f[R]: if the configuration file uses XDG base directories, this is \f[CR]${XDG_DATA_HOME:\-$HOME/.local/share}/chawan\f[R]. Otherwise, it is the same as \f[CR]$CHA_DIR\f[R]. .RS 2 .IP \(bu 2 Exception: if \f[CR]$CHA_DIR\f[R] is set before \f[CR]cha\f[R] is invoked, then \f[CR]$CHA_DATA_DIR\f[R] is also read. This is to make nested invocations work in configurations with XDG basedirs. .RE .SS Word types Word\-based pager commands can operate with different definitions of words. Currently, these are: .IP \(bu 2 w3m words .IP \(bu 2 vi words .IP \(bu 2 Big words .SS w3m word A w3m word is a sequence of alphanumeric characters. Symbols are treated in the same way as whitespace. .SS vi word A vi word is a sequence of characters in the same character category. Currently, character categories are alphanumeric characters, symbols, han letters, hiragana, katakana, and hangul. .PP vi words may be separated by whitespace; however, vi words from separate categories do not have to be whitespace\-separated. e.g.\ the following character sequence contains two words: .IP .EX hello[]+{}\(at\(ga! .EE .SS Big word A big word is a sequence of non\-whitespace characters. .PP It is essentially the same as a w3m word, but with symbols being defined as non\-whitespace. .SS See also \f[B]cha\f[R](1) \f[B]cha\-api\f[R](7) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/cha-css.7�������������������������������������������������������������������������0000664�0000000�0000000�00000027425�15202323131�0015322�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" Automatically generated by Pandoc 3.9.0.2 .\" .TH "CHA-CSS" "7" .SH CSS in Chawan This document describes CSS features supported by Chawan, as well as its proprietary extensions and deviations from standards. .PP If you discover a deviation that is not covered by this document, please open a ticket at \c .UR https://todo.sr.ht/~bptato/chawan .UE \c \&. .SS Standard properties A list of supported standard properties, with notes on unimplemented values: .IP \(bu 2 background\-color (see color) .IP \(bu 2 background\-image (displays placeholders only) .IP \(bu 2 border\-collapse .IP \(bu 2 border\-*\-style, border\-*\-color, border\-*\-width (but see borders) .IP \(bu 2 border\-spacing .IP \(bu 2 bottom .IP \(bu 2 box\-sizing .IP \(bu 2 caption\-side .IP \(bu 2 clear .IP \(bu 2 color (hex values and functions \f[CR]rgb\f[R], \f[CR]rgba\f[R], \f[CR]hsl\f[R], \f[CR]hsla\f[R]) .IP \(bu 2 content (string, (no\-)open/close\-quote, counter()) .IP \(bu 2 counter\-increment .IP \(bu 2 counter\-reset .IP \(bu 2 counter\-set .IP \(bu 2 display (\f[CR]block\f[R], \f[CR]inline\-block\f[R], \f[CR]list\-item\f[R], \f[CR]table\f[R], \f[CR]inline\-table\f[R], \f[CR]table\-*\f[R], \f[CR]flex\f[R], \f[CR]inline\-flex\f[R], \f[CR]flow\-root\f[R]) .IP \(bu 2 flex\-basis (but \f[CR]content\f[R] not supported) .IP \(bu 2 flex\-direction .IP \(bu 2 flex\-grow .IP \(bu 2 flex\-shrink .IP \(bu 2 flex\-wrap .IP \(bu 2 float .IP \(bu 2 font\-size (ignored; only for JS compatibility) .IP \(bu 2 font\-style (\f[CR]oblique\f[R] interpreted as \f[CR]italic\f[R]) .IP \(bu 2 font\-weight (numeric properties > 500 interpreted as bold, others as regular) .IP \(bu 2 height .IP \(bu 2 left .IP \(bu 2 list\-style\-position .IP \(bu 2 list\-style\-type (but no custom list styles) .IP \(bu 2 margin\-bottom .IP \(bu 2 margin\-left .IP \(bu 2 margin\-right .IP \(bu 2 margin\-top .IP \(bu 2 max\-height .IP \(bu 2 max\-width .IP \(bu 2 min\-height .IP \(bu 2 min\-width .IP \(bu 2 opacity (hacky; only works with \f[CR]opacity: 0\f[R]) .IP \(bu 2 overflow\-x (see below on scrollbars) .IP \(bu 2 overflow\-y (see below on scrollbars) .IP \(bu 2 padding\-bottom .IP \(bu 2 padding\-left .IP \(bu 2 padding\-right .IP \(bu 2 padding\-top .IP \(bu 2 position (see below for \f[CR]sticky\f[R] and \f[CR]fixed\f[R]) .IP \(bu 2 quotes .IP \(bu 2 right .IP \(bu 2 text\-align .IP \(bu 2 text\-decoration (\f[CR]none\f[R], \f[CR]underline\f[R], \f[CR]overline\f[R], \f[CR]line\-through\f[R]) .IP \(bu 2 text\-transform .IP \(bu 2 top .IP \(bu 2 vertical\-align .IP \(bu 2 visibility .IP \(bu 2 white\-space .IP \(bu 2 width .IP \(bu 2 word\-break .IP \(bu 2 z\-index .PP Shorthands: .IP \(bu 2 all .IP \(bu 2 margin .IP \(bu 2 padding .IP \(bu 2 border, border\-style, border\-color, border\-width (but see borders) .IP \(bu 2 background (only color and url; other components are skipped) .IP \(bu 2 list\-style (list\-style\-image is skipped) .IP \(bu 2 flex .IP \(bu 2 flex\-flow .IP \(bu 2 overflow .PP Variables (the \f[CR]var()\f[R] function) are fully supported. .PP Values of \f[CR]<length>\f[R] or \f[CR]<color>\f[R] types fully support \f[CR]calc()\f[R] expressions. .SS Selectors All selector types from CSS 2.1 are supported, except for namespaces. .PP Following standard pseudo\-classes are supported: \f[CR]:first\-child\f[R], \f[CR]:last\-child\f[R], \f[CR]:only\-child\f[R], \f[CR]:hover\f[R], \f[CR]:root\f[R], \f[CR]:nth\-child()\f[R], \f[CR]:nth\-last\-child()\f[R], \f[CR]:checked\f[R], \f[CR]:focus\f[R], \f[CR]:is()\f[R], \f[CR]:not()\f[R], \f[CR]:where()\f[R], \f[CR]:lang()\f[R], \f[CR]:link\f[R], \f[CR]:target\f[R], \f[CR]:disabled\f[R]. .PP \f[CR]:visited\f[R] is parsed, but for now it is not matched. .PP \f[CR]:defined\f[R], \f[CR]:host\f[R], and \f[CR]:host()\f[R] are matched for compatibility; however, custom elements and shadow DOM are not supported yet. .PP The standard pseudo\-elements \f[CR]::before\f[R], \f[CR]::after\f[R], and \f[CR]::marker\f[R] are supported. \f[CR]::backdrop\f[R] is parsed for compatibility, but is not supported yet. .SS At\-rules Following rules starting with an \f[CR]\(at\f[R] sign are supported. .SS \f[CR]\(atmedia\f[R] The \f[CR]grid\f[R], \f[CR]hover\f[R], \f[CR]prefers\-color\-scheme\f[R], \f[CR]scripting\f[R], \f[CR]width\f[R], and \f[CR]height\f[R] media features are fully supported. .PP The \f[CR]color\f[R], \f[CR]color\-index\f[R], and \f[CR]monochrome\f[R] features are supported, but only consider the number of supported text colors (which can differ from the number of colors in Sixel/Kitty images). .SS \f[CR]\(atimport\f[R] Importing to layers is supported. .PP \f[CR]\(atimport\f[R] combined with media queries is not yet supported. .SS \f[CR]\(atlayer\f[R] \f[CR]\(atlayer\f[R] is fully supported. (I think.) .SS Proprietary extensions .IP \(bu 2 \f[CR]text\-align\f[R] accepts the values \f[CR]\-cha\-center\f[R], \f[CR]\-cha\-left\f[R], and \f[CR]\-cha\-right\f[R] to support the HTML \f[CR]<center>\f[R], \f[CR]<div align=left>\f[R] and \f[CR]<div align=right>\f[R] elements. (Analogous to \f[CR]\-moz\-center\f[R] etc.) .IP \(bu 2 Properties with a \f[CR]<color>\f[R] value accept the function \f[CR]\-cha\-ansi()\f[R], mapping to terminal\-specific (\(lqANSI\(rq) colors. The function takes one of .RS 2 .IP \(bu 2 An 8\-bit integer, indicating a color value as set by XTerm\(cqs indexed color feature. .IP \(bu 2 One of the strings \(lqblack\(rq, \(lqred\(rq, \(lqgreen\(rq, \(lqyellow\(rq, \(lqblue\(rq, \(lqmagenta\(rq, \(lqcyan\(rq, \(lqwhite\(rq for an ANSI color, possibly prefixed by the string \(lqbright\-\(rq to indicate an aixterm 16\-color value. .RE .IP \(bu 2 \f[CR]text\-decoration\f[R] accepts the keyword \f[CR]\-cha\-reverse\f[R], which sets the \f[I]reverse video\f[R] parameter on the text. (This is used by the UA style sheet to highlight text in \f[CR]<code>\f[R] tags.) .IP \(bu 2 \f[CR]text\-transform\f[R] accepts the keyword \f[CR]\-cha\-half\-width\f[R], which has the opposite effect as \f[CR]full\-width\f[R]. .RS 2 .PP This can be used in user style sheets to compress distracting ruby text: \f[CR]rt{text\-transform: \-cha\-half\-width}\f[R]. Characters without half\-width counterparts are left intact, except hiragana is treated as katakana. .RE .IP \(bu 2 The \f[CR]\-cha\-colspan\f[R] and \f[CR]\-cha\-rowspan\f[R] properties have the same effect as the \f[CR]colspan\f[R] and \f[CR]rowspan\f[R] attributes on tables. .IP \(bu 2 The \f[CR]:\-cha\-first\-node\f[R] and \f[CR]:\-cha\-last\-node\f[R] pseudo\-classes apply to elements that have no preceding/subsequent sibling node that is either an element node or a text node with non\-whitespace contents. (Modeled after \f[CR]:\-moz\-first\-node\f[R] and \f[CR]:\-moz\-last\-node\f[R].) .IP \(bu 2 If \f[CR]buffer.mark\-links\f[R] is set, the \f[CR]::\-cha\-link\-marker\f[R] pseudo\-element will be generated on all anchor elements. .IP \(bu 2 In hints mode (by default, the \f[CR]f\f[R] key) the markers are implemented by generating \f[CR]::\-cha\-link\-hint\f[R] on all applicable elements. So you can change the marker background in your \f[CR]user\-style\f[R] (\f[CR][buffer]\f[R] section in \f[CR]config.toml\f[R]): .RS 2 .IP .EX \f[BI]::\-cha\-link\-hint\f[R] { \f[B]background\f[R]: gainsboro } .EE .RE .IP \(bu 2 The \f[CR]\-cha\-content\-type\f[R] media feature can be used to filter documents for their content type. For example, you can add .RS 2 .IP .EX \f[B]\(atmedia\f[R] (\-cha\-content\-type: \(dqtext/markdown\(dq) { body { \f[B]width\f[R]: 80ch } } .EE .PP to your \f[CR]user\-style\f[R] to set the body width of all markdown documents to 80 characters. (The string is matched case\-insensitively.) .RE .SS Rendering quirks These are willful violations of the standard, usually made to better fit the display model inherent to projecting the web to a cell\-based screen. .SS User agent style sheet The user agent style sheet is a combination of the styles suggested by the HTML standard and a CSS port of w3m\(cqs rendering. In general, faithfulness to w3m is preferred over the standard\(cqs suggestions, unless w3m\(cqs rendering breaks on existing websites. .PP Link colors differ depending on the terminal\(cqs color scheme. .SS Sizing and positioning Layout is performed on a finite canvas of coordinates represented by a 32\-bit fixed\-point number with 6 bits of precision. After layout, these positions are divided by the cell width and/or height, with the fractional part truncated. (This is subject to change.) .PP In case of Kitty images, the fractional part is preserved, and is used as an in\-cell offset. .PP The lengths \f[CR]1em\f[R] and \f[CR]1ch\f[R] compute to the cell height and cell width respectively. .PP In outer inline boxes (\f[CR]inline\-block\f[R], \f[CR]inline\-flex\f[R]) and \f[CR]list\-item\f[R] boxes, margins and padding that are smaller than one cell (on the respective axis) are ignored. This does not apply to blockified inline boxes. .PP When calculating clip boxes (\f[CR]overflow: hidden\f[R] or \f[CR]clip\f[R]), the clip box\(cqs offset is floored, and its size is ceiled to the nearest cell\(cqs boundaries. This means that \(lqwidth: 1px; overflow: hidden\(rq will still display the first character of a text box. .SS Scroll bars Chawan does not have scroll bars, as they would complicate on\-page navigation and would not work in dump mode. Instead, the \(lqoverflow\-x/y\(rq properties are handled as follows. .IP "1." 3 If \f[CR]overflow\f[R] is \f[CR]auto\f[R] or \f[CR]scroll\f[R], and the intrinsic minimum size of the box is greater than its specified size, then the former overrides the latter. .IP "2." 3 Content that spills out of a scroll container on the X axis is displayed, while content that spills out of a scroll container on the Y axis is clipped. .SS \f[CR]position: fixed\f[R], \f[CR]position: sticky\f[R] To keep the document model static, these do not change their position based on the viewport\(cqs scroll status. Instead: .IP \(bu 2 \f[CR]position: sticky\f[R] is treated as \f[CR]position: static\f[R], except it also behaves as an absolute position container. .IP \(bu 2 \f[CR]position: fixed\f[R] is placed at the bottom of the document. .PP Right now, \f[CR]position: fixed\f[R] is always positioned at the bottom of the root element\(cqs margin box. This breaks on pages that overflow it (e.g. by setting \f[CR]height: 100%\f[R] on the root element), so it will be moved to the bottom of its overflow box in the future. .SS Color correction Some authors only specify one of the foreground or the background color, assuming a black\-on\-white canvas. The \f[CR]display.minimum\-contrast\f[R] option adjusts the foreground color so that text remains readable even if the terminal background does not match this expectation. (The exact algorithm is unspecified and subject to change.) .PP To avoid breaking spoiler mechanisms that rely on \(lqblack on black\(rq text, color correction is not invoked on cells that have an RGB color (typically specified by the author.) .SS Borders CSS borders are difficult to accurately display on a cell\-based display. So while the functionality exists, it has some limitations: .IP \(bu 2 On tables, borders are always collapsed, even when \f[CR]border\-collapse\f[R] is set to \f[CR]separate\f[R]. .IP \(bu 2 With \f[CR]border\-collapse: separate\f[R], the spacing between cells is the largest of \f[CR]border\-spacing\f[R] times two and the cell width. .IP \(bu 2 \f[CR]border\-*\-width\f[R] is interpreted as a binary value: a width of 0 results in no border, while any other width results in a border of a single type. If the width is smaller than one cell (in the respective direction), the rest is subtracted from the margin (if there is any margin). .IP \(bu 2 \f[CR]box\-sizing: border\-box\f[R] actually sets the padding box size, so that borders rounded up to the cell size do not accidentally take all space from the actual content. (That in turn would cause problems if a child box set \f[CR]overflow: hidden\f[R], etc.) .SS See also \f[B]cha\f[R](1) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/cha-image.7�����������������������������������������������������������������������0000664�0000000�0000000�00000020627�15202323131�0015611�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" Automatically generated by Pandoc 3.9.0.2 .\" .TH "CHA-IMAGE" "7" .SH Inline images On terminals that support images, Chawan is capable of displaying various image formats inline. .SS Enabling images There are actually two switches for images in the config: .IP \(bu 2 buffer.images: this enables downloading images, \f[I]even if they cannot be displayed\f[R]. This is the switch you typically need. .IP \(bu 2 display.image\-mode: sets the inline image display method. Defaults to \(lqauto\(rq, but may also be set to \(lqnone\(rq, \(lqsixel\(rq, or \(lqkitty\(rq manually. This switch is rarely useful. .PP In general, you only have to set \f[CR]buffer.images\f[R] to true: .IP .EX \f[I]# in \(ti/.chawan/config.toml (or \(ti/.config/chawan/config.toml)\f[R] \f[B][buffer]\f[R] images = true .EE .PP The \f[CR]image\-mode\f[R] switch is mainly useful if you want images to be fetched, but not displayed (\(lqnone\(rq option). It may also help if \(lqauto\(rq fails to detect the terminal\(cqs image display capabilities; however, I am not aware of any terminal where this can happen. (If you find one, open a ticket.) .SS Output formats Supported output formats are: .IP \(bu 2 The DEC Sixel format .IP \(bu 2 The Kitty terminal graphics protocol .PP Support for other protocols (iTerm, MLTerm, etc.) is not planned. (To my knowledge, all image\-capable terminals support at least one of the above two anyways.) .PP Support for environment\-specific hacks such as w3mimgdisplay, ueberzug, etc. is not planned. .SS Sixel Sixel is the most widely supported image format. See \c .UR https://arewesixelyet.com .UE \c \ to find a terminal that supports it. .PP Known quirks and implementation details: .IP \(bu 2 XTerm needs extensive configuration for ideal sixel support. In particular, you will want to set the decGraphicsID, numColorRegisters, and maxGraphicSize attributes. See \f[B]xterm\f[R](1) for details. .IP \(bu 2 We assume private color registers are supported. On terminals where they aren\(cqt (e.g.\ SyncTERM or hardware terminals), colors will get messed up with multiple images on screen. .IP \(bu 2 Zellij advertises Sixel support, but the feature is completely broken in the current version, so Chawan specifically disables images in Zellij by default. In particular: .RS 2 .IP \(bu 2 Zellij itself does no Sixel detection, emitting Sixel data even on terminals that do not support it. (A fairly puzzling bug, given the developers seem to be aware of the DA1 feature.) .IP \(bu 2 On terminals that support Sixel, it fails to position images correctly, with the misplaced images completely messing up layout. .RE .IP \(bu 2 We send XTSMGRAPHICS for retrieving the number of color registers; on failure, we fall back to 256. You can override color register count using the \f[CR]display.sixel\-colors\f[R] configuration value. .IP \(bu 2 Normally, Sixel encoding runs in two passes. On slow computers, you can try setting \f[CR]display.sixel\-colors = 2\f[R], which will skip the first pass (but will also display everything in monochrome). .IP \(bu 2 Transparency \f[I]is\f[R] supported, but looks weird because we approximate an 8\-bit alpha channel with Sixel\(cqs 1\-bit alpha channel. Also, some terminals don\(cqt emulate it correctly \- when in doubt, try XTerm (which does). .IP \(bu 2 Terminal scroll (both with LF/RI and SU/SD) is used extensively to avoid sending images several times. Expect troubles on terminals that do not handle this correctly. (For example, tmux is known to destroy images on scroll, so we avoid using scroll there.) .SS Kitty On terminals that support it, Kitty\(cqs protocol is preferred over Sixel. Its main benefit is that images do not have to be sent again every time a new slice of the image moves into the screen. Support for full RGBA without quantization is another benefit. .PP Note: at the time of writing, tmux does not support the Kitty image protocol. While it is possible to hack Kitty images onto tmux nevertheless, this requires significant concessions in display capabilities compared to the regular Kitty protocol (or even Sixel). Therefore, support for this hack is not planned. .SS Input formats Currently, the supported input formats are: .IP \(bu 2 BMP, PNG, JPEG, GIF (through stb_image) .IP \(bu 2 WebP (through JebP) .IP \(bu 2 SVG (through NanoSVG) .PP More formats may be added in the future, provided there exists a reasonably small implementation, preferably in the public domain. (I do not want to depend on external image decoding libraries, but something like stbi is OK to vendor.) .SS Codec module system All image codec implementations are specified by the URL scheme \(lqimg\-codec+name:\(rq, where \(lqname\(rq is the MIME subtype. e.g.\ for image/png, it is \(lqimg\-codec+png:\(rq. (This indeed means that only \(lqimage\(rq MIME types can be used.) .PP Like all schemes, these are defined (and overridable) in the urimethodmap file, and are implemented as local CGI programs. These programs take an encoded image on stdin, and dump the decoded RGBA data to stdout \- when encoding, vice versa. .PP This means that it is possible for users to define image decoders for their preferred formats, or even override the built\-in ones. (If you actually end up doing this for some reason, please send me a mail so I can add it to the bonus directory.) .PP A codec can have one of, or both, \(lqdecode\(rq and \(lqencode\(rq instructions; these are set in the path name. So \(lqimg\-codec+png:decode\(rq is called for decoding PNGs, and \(lqimg\-codec+png:encode\(rq for encoding them. .PP Headers are used for transferring metadata (like image dimensions), both from the browser (input) and to the browser (output). Detailed description of the decoder & encoder interfaces follows. .SS decoding When the path equals \(lqdecode\(rq, a codec CGI script must take a binary stream of an encoded image on its standard input and print the equivalent binary stream of big\-endian 8\-bit (per component) RGBA values to stdout. .PP Input headers: .IP \(bu 2 Cha\-Image\-Info\-Only: 1 .PP This tells the image decoder to only send image metadata (i.e.\ size). Technically, the decoder is free to fully decode the image, but this is a waste of resources; the browser will ignore any output received after headers. .PP Output headers: .IP \(bu 2 Cha\-Image\-Dimensions: {width}x{height} .PP The size of the decoded image. e.g.\ for 123x456, 123 is width and 456 is height. .SS encoding When the path equals \(lqencode\(rq, a codec CGI script must take a binary stream of big\-endian 8\-bit (per component) RGBA values on its standard input and print the equivalent encoded image to its standard output. .PP Input headers: .IP \(bu 2 Cha\-Image\-Dimensions: {width}x{height} .PP Specifies the dimensions of the input RGBA image. This means that {width} * {height} * 4 == {size of data received on stdin}. .PP The format is the same as above; in fact, the design is such that you could directly pipe the output of decode to encode (and vice versa). .IP \(bu 2 Cha\-Image\-Quality: {number} .PP The requested encoding quality, ranging from 1 to 100 inclusive (i.e.\ 1..100). It is up to the encoder to interpret this number. .PP (The stb_image JPEG encoder uses this.) .PP Output headers: .PP Currently, no output headers are defined for encoders. .SS Skipping copies with mmap The naive implementation of the above system would have to copy the output at least twice when an image is resized. To skip these copies, stdin and/or stdout is (currently) a file in the tmp directory for: .IP \(bu 2 decode stdin, when the image is already downloaded .IP \(bu 2 decode stdout, always .IP \(bu 2 encode stdin, always .PP This makes it possible to mmap stdin/stdout instead of streaming through them with read and write. When doing this, mind the following: .IP \(bu 2 When reading, you must check your initial position in the file with lseek. .IP \(bu 2 When writing, your headers are part of the output. At the very least, you must place a newline at the file\(cqs beginning. .IP \(bu 2 mmapping for write is slower than streaming the data with \f[CR]write\f[R]. The only reason to mmap for write is to save memory when you can\(cqt stream the output. .IP \(bu 2 This \f[I]is\f[R] an implementation detail, and might change at any time in the future (e.g.\ if we add a \(lqno cache files\(rq mode). Always check for S_ISREG to ensure that you are actually dealing with a file. (Use io/dynstream.nim\(cqs readLoopOrMmap and maybeMmapForSend to deal with this automatically.) .SS See also \f[B]cha\f[R](1) \f[B]cha\-terminal\f[R](7) ���������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/cha-mailcap.5���������������������������������������������������������������������0000664�0000000�0000000�00000021314�15202323131�0016125�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" Automatically generated by Pandoc 3.9.0.2 .\" .TH "CHA-MAILCAP" "5" .SH Mailcap By default, Chawan\(cqs buffers only handle HTML and plain text. The \f[I]mailcap\f[R] file can be used to view other file formats using external commands, or to convert them to HTML/plain text before displaying them in Chawan. .PP Note that Chawan\(cqs default mime.types file only recognizes a few file extensions, which may result in your entries not being executed if your system lacks an /etc/mime.types file. Please consult \f[B]cha\-mime.types\f[R](5) for details. .PP For an exact description of the mailcap format, see \c .UR https://www.rfc-editor.org/rfc/rfc1524 RFC 1524 .UE \c \&. .SS Search path The search path for mailcap files is set by the configuration variable \f[CR]external.mailcap\f[R]. This matches the recommended path in the RFC: .IP .EX $HOME/.mailcap:/etc/mailcap:/usr/etc/mailcap:/usr/local/etc/mailcap .EE .PP By default, mailcap entries are only executed if the user types \f[CR]r\f[R] (run) after the prompt. Other options are to view the file with \f[CR]t\f[R] (text), or to save the file with \f[CR]s\f[R]. .PP If a capital letter is typed (e.g.\ shift + \f[CR]R\f[R]), then a corresponding entry is appended to \f[CR]external.auto\-mailcap\f[R] (default: \f[CR]\(ti/.chawan/mailcap\f[R], or \f[CR]\(ti/.config/chawan/mailcap\f[R] with XDG basedirs). \f[CR](T)ext\f[R] and \f[CR](S)ave\f[R] may also be used to append entries corresponding to the other display options. .PP Entries in auto\-mailcap are automatically executed, so it is recommended to add your Chawan\-specific entries there (or just set it to your personal mailcap file). .SS Format Chawan adheres to the format described in RFC 1524, with a few extensions. .PP \f[CR]text/html\f[R] and \f[CR]text/plain\f[R] entries are ignored. .SS Templating The command part of entries may include template strings which are substituted by the browser at execution. .PP Templates do not have to be quoted; Chawan quotes them automatically. (This works with $(command substitutions) as well.) However, other software may misbehave on such templates, so it may be better to assign them to a variable first, e.g. .IP .EX text/x\-example; s=%s cat \(dq$s\(dq; copiousoutput .EE .PP Following templates are supported: .IP \(bu 2 \f[CR]%s\f[R] expands to the path. Specifying \f[CR]%s\f[R] forces download of the external resource \f[I]before\f[R] the entry is executed. If \f[CR]%s\f[R] is not specified, the resource is instead piped to standard input. (In this case, \f[CR]needsterminal\f[R] does not apply.) .IP \(bu 2 \f[CR]%t\f[R] expands to the content type. Named content type fields can also be specified with the syntax \f[CR]%{charset}\f[R]. For example, in .RS 2 .IP .EX text/html; charset=utf\-8 .EE .PP \f[CR]%t\f[R] would expand to the above string, while \f[CR]%{charset}\f[R] would expand to \(lqutf\-8\(rq. .RE .IP \(bu 2 Non\-standard templates for the resource\(cqs original URL: \f[CR]%u\f[R] (from Netscape) expands to the original URL of the resource, \f[CR]%h\f[R] (from w3mmee) expands to the hostname without the port, \f[CR]%H\f[R] expands to the hostname including the port, and \f[CR]%?\f[R] (from w3mmee) expands to the query string including the question mark. .RS 2 .PP (w3mmee did not actually include the question mark in \f[CR]%?\f[R]. However, that design could not express the difference between the empty query string and the null query string, so it has been changed in Chawan.) .RE .SS Fields Following fields are recognized. .IP \(bu 2 When the \f[CR]test\f[R] named field is specified, the mailcap entry is only used if the test command returns 0. For example, you can restrict entries that require X11 as follows: .RS 2 .IP .EX image; feh \-; test=test \-n \(dq$DISPLAY\(dq .EE .PP Warning: \f[CR]%s\f[R] does not work with \f[CR]test\f[R]. \f[CR]test\f[R] named fields with a \f[CR]%s\f[R] template are skipped, and no data is piped into \f[CR]test\f[R] commands. .RE .IP \(bu 2 \f[CR]copiousoutput\f[R] makes Chawan redirect the output of the external command\(cqs output into a new buffer. If either \f[CR]x\-htmloutput\f[R] or \f[CR]x\-ansioutput\f[R] is defined too, then \f[CR]copiousoutput\f[R] is ignored. .IP \(bu 2 \f[CR]needsterminal\f[R] hands over control of the terminal to the command while it is running. It does nothing if one of \f[CR]copiousoutput\f[R], \f[CR]x\-ansioutput\f[R], \f[CR]x\-saveoutput\f[R] or \f[CR]x\-htmloutput\f[R] is specified. .IP \(bu 2 \f[CR]nametemplate\f[R] provides a specific template for the temporary file created when \f[CR]%s\f[R] is specified. See the RFC for details. .IP \(bu 2 \f[CR]x\-htmloutput\f[R] (from w3m) behaves the same as \f[CR]copiousoutput\f[R], but makes Chawan interpret the command\(cqs output as HTML. .IP \(bu 2 \f[CR]x\-ansioutput\f[R] pipes the output through the \(lqtext/x\-ansi\(rq content type handler, so that ANSI colors, formatting, etc. are displayed correctly. .IP \(bu 2 \f[CR]x\-saveoutput\f[R] prompts the user to save the entry\(cqs output in a file. .IP \(bu 2 \f[CR]x\-needsstyle\f[R] forces CSS to be processed for the specific type, even if styling is disabled in the config. Only useful when combined with \f[CR]x\-htmloutput\f[R]. (Also see the \f[CR]\-cha\-content\-type\f[R] media query in \f[B]cha\-css\f[R](7).) .IP \(bu 2 \f[CR]x\-needsimage\f[R] forces images to be displayed in \f[CR]x\-htmloutput\f[R], even if images are disabled. .IP \(bu 2 \f[CR]x\-type\f[R] (from w3mmee) specifies a MIME type substitution. The command part is interpreted as a MIME type (without template expansion) which is used instead of the original type. Such entries are only respected in \f[CR]external.auto\-mailcap\f[R]. .RS 2 .PP Entries with \f[CR]x\-type\f[R] also match text/plain and text/html documents (which are normally excluded from mailcap). However, \f[CR]x\-type\f[R] does not apply if the content type was forced (e.g.\ using the \f[CR]\-T\f[R] flag). .PP (Note: \f[CR]x\-type\f[R] is experimental. Future changes to its semantics are to be expected.) .RE .IP \(bu 2 \f[CR]x\-match\f[R] (from w3mmee) restricts the entry\(cqs URL to the specified regex. \f[CR]x\-nc\-match\f[R] is the same, but it is case\-insensitive. For example, \f[CR]x\-match=https?://example\(rs.org/.*\f[R] restricts the entry to example.org (note the backslash.) .RS 2 .PP When one of these fields is present together with \f[CR]test\f[R], the result is ANDed together. .RE .IP \(bu 2 \f[CR]x\-netpath\f[R] (from w3mmee) restricts the entry to URIs that match the \f[CR]net_path\f[R] production of RFC 2396. In other words, the URI must have an authority (hostname etc.), so e.g.\ \f[CR]example://blah/path\f[R] is matched, while \f[CR]example:/path\f[R] isn\(cqt. .RS 2 .PP For schemes other than \f[CR]file\f[R], two slashes after the colon signify a \f[CR]net_path\f[R]. \f[CR]file:///path\f[R] is a special case: it looks like a \f[CR]net_path\f[R], but it isn\(cqt one. (This is inherited from the WHATWG URL standard.) .RE .SS Examples To automatically execute these entries, place them in \f[CR]\(ti/.chawan/mailcap\f[R] (or \f[CR]\(ti/.config/chawan/mailcap\f[R] if you use XDG basedirs). Alternatively, if you already have a mailcap file to share with other programs, you can set \f[CR]external.auto\-mailcap\f[R] to \f[CR]\(ti/.mailcap\f[R]. .IP .EX # Note: these examples require an entry in mime.types that sets e.g. md as # the markdown content type. # Handle markdown files using pandoc. text/markdown; pandoc \- \-f markdown \-t html \-o \-; x\-htmloutput # Show syntax highlighting for JavaScript source files using bat. text/javascript; bat \-f \-l es6 \-\-file\-name %u \-; x\-ansioutput # Play music using mpv, and hand over control of the terminal until mpv exits. audio/*; mpv \-; needsterminal # Play videos using mpv in the background, redirecting its standard output # and standard error to /dev/null. video/*; mpv \- # Open docx files using LibreOffice Writer. application/vnd.openxmlformats\-officedocument.wordprocessingml.document; lowriter %s # Display manpages using pandoc. (Make sure the mime type matches the one # set in your mime.types file for extensions .1, .2, .3, ...) application/x\-troff\-man; pandoc \- \-f man \-t html \-o \-; x\-htmloutput # epub \-> HTML using pandoc. (Again, don\(aqt forget to adjust mime.types.) # We set http_proxy to keep it from downloading whatever through http/s. application/epub+zip; http_proxy=localhost:0 pandoc \- \-f epub \(rs \-\-embed\-resources \-\-standalone; x\-htmloutput # Hex viewer. Usage: alias chadump=\(aqcha \-Ttext/x\-hexdump\(aq # (Uses GNU\-specific flags, adjust as needed on other systems.) text/x\-hexdump; od \-w12 \-A x \-t x1z \-v; copiousoutput # Following entry will be ignored, as text/html is supported natively by Chawan. text/html; cha \-dT text/html \-I %{charset}; copiousoutput .EE .SS See also \f[B]cha\f[R](1) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/cha-mime.types.5������������������������������������������������������������������0000664�0000000�0000000�00000003201�15202323131�0016604�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" Automatically generated by Pandoc 3.9.0.2 .\" .TH "CHA-MIME.TYPES" "5" .SH mime.types Chawan uses the mime.types file to map file extensions to MIME types (also known as \f[CR]Content\-Type\f[R]). .PP MIME types in turn are used by mailcap to decide how to present a certain file to the user (display as text, use external viewer, save, etc.) See \f[B]cha\-mailcap\f[R](5) for details of how that works. .SS Search path Chawan parses all mime.types files defined in \f[CR]external.mime\-types\f[R]. When no mime.types file is found, the built\-in MIME type associations are used. .PP The default search path for mime.types files is: .IP .EX $HOME/.mime.types:/etc/mime.types:/usr/etc/mime.types:/usr/local/etc/mime.types .EE .SS Format The mime.types file is a list of whitespace\-separated columns. The first column represents the mime type, all following columns are file extensions. .PP Lines starting with a hash character (#) are recognized as comments, and are ignored. .PP Example: .IP .EX # comment application/x\-example exmpl ex .EE .PP This mime.types file would register the file extensions \(lqexmpl\(rq and \(lqex\(rq to be recognized as the mime type \f[CR]application/x\-example\f[R]. .SS Note Chawan only uses mime.types files for finding mailcap entries; buffers use an internal mime.types file for content type detection instead. .PP The default mime.types file only includes file formats that buffers can handle, which is rather limited (at the time of writing, 7 file formats). Therefore it is highly recommended to configure at least one external mime.types file if you use mailcap. .SS See also \f[B]cha\f[R](1) \f[B]cha\-mailcap\f[R](5) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/cha-protocols.7�������������������������������������������������������������������0000664�0000000�0000000�00000026037�15202323131�0016554�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" Automatically generated by Pandoc 3.9.0.2 .\" .TH "CHA-PROTOCOLS" "7" .SH Protocols Chawan supports downloading resources from various protocols: HTTP, FTP, SFTP, Gopher, Gemini, Spartan, and Finger. Details on these protocols, and information on how users can add support to their preferred protocols is outlined in this document. .PP You can find network adapters in the source distribution\(cqs \f[CR]adapter/protocol\f[R] directory. For protocol\-specific file formats (like gemtext or gopher directories) you will also find an appropriate HTML converter in \f[CR]adapter/format\f[R] \- note that these are ultimately compiled into a single \f[CR]tohtml\f[R] program that dispatches based on its \f[CR]argv[0]\f[R]. .SS OpenSSL\-based adapters The HTTP(S), SFTP, and Gemini modules all depend on OpenSSL. This is a huge library, and linking it separately with each adapter would result in enormous code bloat in static builds. .PP Therefore, these modules are compiled into a single binary. The entry point can be found at \f[CR]adapter/protocol/ssl.nim\f[R]. .SS HTTP The HTTP(S) adapter supports HTTP/1.1 with arbitrary headers and POST data, is able to use passed userinfo data (Basic authentication), and returns all headers and response body it receives without exception. .PP Deflate decompression with gzip and zlib headers is supported. (Accept\-Encoding: gzip, deflate.) This is based on a modified version of the public domain tinfl.h decompressor by Rich Geldreich. .PP Brotli decompression (Accept\-Encoding: br) is supported using the decoder provided by the reference implementation. .PP The \f[CR]bonus\f[R] directory contains two alternative HTTP clients: .IP \(bu 2 curlhttp; this is the old HTTP client based on libcurl. It can be built using curl\-impersonate; see README.md in the bonus/ directory for details. .IP \(bu 2 libfetch\-http: based on FreeBSD libfetch. It is mostly a proof of concept, as FreeBSD libfetch HTTP support is very limited; in particular, it does not support arbitrary HTTP headers, so e.g. cookies will not work. .SS SFTP The SFTP adapter wraps libssh2. It works for me, but YMMV. .PP A slight usability issue is that if an IdentityFile declaration is found in your ssh config, it will prompt for the identity file password, but there is no way to tell whether it is really asking for that (or just regular password auth). Also, settings covered by the Match field are ignored. .PP The adapter does not have a way to register new known hosts, so you have to first connect to new hosts with the regular \f[CR]sftp\f[R] command before opening them in Chawan. .SS Gemini Currently, the Gemini adapter does not support sites that require private key authentication. Otherwise, it should work OK. .PP gmi2html is its companion program to convert the \f[CR]text/gemini\f[R] file format to HTML. .SS FTP Chawan supports FTP passive mode browsing and downloads. .PP Directory listings return the \f[CR]text/x\-dirlist\f[R] content type, which is parsed by \f[CR]dirlist2html\f[R] (and also used by the \f[CR]file:\f[R] handler). This assumes UNIX output style, and will probably break horribly on receiving anything else. .SS Shell\-based adapters Following protocols are simple enough to have adapters implemented as shell scripts. As such, they are good starting points for understanding Chawan\(cqs protocol adapter system. .PP To open TCP connections in a portable manner, these scripts use a very limited \f[CR]nc\f[R] clone installed in \f[CR]$CHA_LIBEXEC_DIR\f[R]. .SS Gopher Support for the Gopher protocol is implemented as a shell script, using the \f[CR]nc\f[R] tool in the libexec directory (a very limited netcat clone). Gopher directories are returned with the \f[CR]text/gopher\f[R] type, and gopher2html takes care of converting this to HTML. .PP Gopher selector types are converted to MIME types when possible; however, this is very limited, as most of them (like \f[CR]s\f[R] sound, or \f[CR]I\f[R] image) cannot be unambiguously converted without some other sniffing method. Chawan will fall back to extension\-based detection in these cases, and in the worst case may end up with \f[CR]application/octet\-stream\f[R]. .SS Finger Finger is supported through the \f[CR]finger\f[R] shell script, using the same \f[CR]nc\f[R] clone as Gopher. It is probably the simplest protocol of all. .PP The URL scheme is a simplified imitation of the one accepted by Lynx. .SS Spartan Spartan is a protocol similar to Gemini, but without TLS. It is supported through the \f[CR]spartan\f[R] shell script, and like Finger, it uses Chawan\(cqs \f[CR]nc\f[R] to make requests. .PP Spartan has the very strange property of extending gemtext with a protocol\-specific line type. This is implemented as a sed filter for gemtext outputs in the CGI script (in other words, no modification to gmi2html was done to support this). .SS Local schemes: file:, man: While these are not necessarily \f[I]protocols\f[R], they are implemented similarly to the protocols listed above (and thus can also be replaced, if the user wishes; see below). .PP \f[CR]file:\f[R] loads a file from the local filesystem. In case of directories, it shows the directory listing using \f[CR]dirlist2html\f[R] like FTP. .PP \f[CR]man:\f[R], \f[CR]man\-k:\f[R] and \f[CR]man\-l:\f[R] are wrappers around the commands \f[CR]man\f[R], \f[CR]man \-k\f[R] and \f[CR]man \-l\f[R]. These look up man pages using \f[CR]/usr/bin/man\f[R] and turn on\-page references into links. A wrapper command \f[CR]mancha\f[R] also exists; this has an interface similar to \f[CR]man\f[R]. (This used to be based on w3mman2html.cgi, but it has been rewritten as a standalone Nim program.) .SS Internal schemes: cgi\-bin:, stream:, cache:, data:, about: Five internal protocols exist: \f[CR]cgi\-bin:\f[R], \f[CR]stream:\f[R], \f[CR]cache:\f[R], \f[CR]data:\f[R] and \f[CR]about:\f[R]. These are the basic building blocks for the implementation of every protocol mentioned above; for this reason, these can \f[I]not\f[R] be replaced, and are implemented in the main browser binary. .PP \f[CR]cgi\-bin:\f[R] executes a local CGI script. This scheme is used for the actual implementation of the non\-internal protocols mentioned above. Local CGI scripts can also be used to implement wrappers of other programs inside Chawan (e.g.\ dictionaries). .PP \f[CR]stream:\f[R] is used for streams returned by external programs. It differs from \f[CR]cgi\-bin:\f[R] in that it does not cooperate with the external process, and that the loader does not keep track of where the stream originally comes from. Therefore it is suitable for reading in the output of mailcap entries, or for turning stdin into a URL. .PP It is not possible to reload \f[CR]stream:\f[R] URLs. To support rewinding and \(lqview source\(rq, the output of \f[CR]stream:\f[R]\(cqs is stored in a cache file until the buffer is discarded. .PP \f[CR]cache:\f[R] is not something an end user would normally see; it\(cqs used for rewinding or re\-interpreting streams already downloaded. .PP Caching works differently than in most other browsers; files are deterministically loaded from the cache upon certain actions, and from the network upon others, but neither is used as a fallback to the other. .PP \f[CR]data:\f[R] decodes a data URL as defined in RFC 2397. This used to be a CGI module, but has been moved back into the loader process because these URLs can get so long that they no longer fit into the environment. .PP \f[CR]about:\f[R] is inside the loader to allow for an implementation of the download list panel. It should be turned into a CGI module once the loader gets RPC capabilities. .PP The following about pages are available: \f[CR]about:chawan\f[R], \f[CR]about:blank\f[R], \f[CR]about:license\f[R], \f[CR]about:downloads\f[R]. .SS Custom protocols The \f[CR]cha\f[R] binary itself does not know much about the protocols listed above; instead, it loads these through a combination of local CGI, urimethodmap, and if conversion to HTML or plain text is necessary, mailcap (using x\-htmloutput, x\-ansioutput and copiousoutput). .PP urimethodmap can also be used to override default handlers for the protocols listed above. This is similar to how w3m allows you to override the default directory listing display, but much more powerful; this way, any library or program that can retrieve and output text through a certain protocol can be combined with Chawan. .PP For example, consider the urimethodmap definition of \f[CR]finger\f[R]: .IP .EX finger: cgi\-bin:finger .EE .PP This commands Chawan to load the \f[CR]finger\f[R] CGI script, setting the \f[CR]$MAPPED_URI_*\f[R] variables to the target URL\(cqs parts in the process. .PP Then, finger uses these passed parts to construct an appropriate curl command that will retrieve the specified \f[CR]finger:\f[R] URL; it prints the header `Content\-Type: text/plain' to the output, then an empty line, then the body of the retrieved resource. If an error is encountered, it prints a \f[CR]Cha\-Control\f[R] header with an error code and a specific error message instead. .SS Adding a new protocol Here we will add a protocol called \(lqcowsay\(rq, so that the URL cowsay:text prints the output of \f[CR]cowsay text\f[R] after a second of waiting. .PP Note: following assumes you put your \f[CR]config.toml\f[R] in \f[CR]\(ti/.chawan\f[R]. If you are using XDG base directories (i.e.\ your \f[CR]config.toml\f[R] is in \f[CR]\(ti/.config/chawan\f[R]), substitute \f[CR]\(ti/.chawan/cgi\-bin\f[R] with \f[CR]\(ti/.config/chawan/cgi\-bin\f[R]. .PP \f[CR]mkdir \-p \(ti/.chawan/cgi\-bin\f[R], and create a CGI script in \f[CR]\(ti/.chawan/cgi\-bin/cowsay.cgi\f[R]: .IP .EX \f[I]#!/bin/sh\f[R] \f[I]# Signal to the browser that the connection has succeeded. After this,\f[R] \f[I]# Chawan will now \(dqDownloading\(dq instead of \(dqConnecting\(dq.\f[R] printf \(aqCha\-Control: Connected\(rsn\(aq sleep 1 \f[I]# simulate a delay\f[R] \f[I]# Status is a special header that signals the equivalent HTTP status code.\f[R] printf \(aqStatus: 200\(rsn\(aq \f[I]# HTTP OK\f[R] \f[I]# ControlDone is only useful if you want to send remotely received headers\f[R] \f[I]# (i.e. in an HTTP adapter). With ControlDone sent, subsequent Cha\-Control\f[R] \f[I]# headers are not interpreted specially.\f[R] printf \(aqCha\-Control: ControlDone\(rsn\(aq \f[I]# As in HTTP, send an empty line before the body.\f[R] printf \(aq\(rsn\(aq \f[I]# Print the body. We take the path passed to the URL, which urimethodmap\f[R] \f[I]# sets as MAPPED_URI_PATH. This is URI\-encoded, so we also run the urldec\f[R] \f[I]# utility on it.\f[R] printf \(aq%s\(rsn\(aq \(dq$MAPPED_URI_PATH\(dq \f[B]|\f[R] \(dq$CHA_LIBEXEC_DIR\(dq/urldec \f[B]|\f[R] cowsay .EE .PP Don\(cqt forget to set the executable bit, e.g. .IP .EX chmod +x \(ti/.config/chawan/cgi\-bin/cowsay.cgi .EE .PP Finally, create a \(lq.urimethodmap\(rq file in your \f[CR]$HOME\f[R] directory, with the following content: .IP .EX cowsay: /cgi\-bin/cowsay.cgi .EE .PP Now try \f[CR]cha cowsay:Hello,%20world.\f[R]. If you did everything correctly, it should wait one second, then print a cow saying \(lqHello, world.\(rq. .SS See also \f[B]cha\f[R](1), \f[B]cha\-cgi\f[R](5), \f[B]cha\-urimethodmap\f[R](5), \f[B]cha\-mailcap\f[R](5) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/cha-terminal.7��������������������������������������������������������������������0000664�0000000�0000000�00000013223�15202323131�0016334�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" Automatically generated by Pandoc 3.9.0.2 .\" .TH "CHA-TERMINAL" "7" .SH Chawan terminal compatibility Chawan does not use termcap, terminfo, or ncurses; it relies solely on built\-in terminal handling routines, mostly inspired by notcurses. .SS XTerm compatibility In general, Chawan assumes an XTerm\-compatible environment where XTerm means the current XTerm version as developed and maintained by Thomas E.\ Dickey. This means that Chawan is compatible with any given terminal if: .IP \(bu 2 the terminal is actually compatible with XTerm, OR .IP \(bu 2 the terminal isn\(cqt compatible with XTerm, but reports its capabilities via terminal queries correctly, OR .IP \(bu 2 the terminal isn\(cqt compatible with XTerm, but its \f[CR]TERM\f[R] value is hardcoded in Chawan. .PP Terminals pretending to be XTerm (\f[CR]TERM=xterm\f[R]) which are not actually XTerm might malfunction. .PP (In practice, I have tested dozens of terminal emulators and haven\(cqt encountered any major issues; in all likelihood, yours will work too. If it doesn\(cqt, please \c .UR https://todo.sr.ht/~bptato/chawan open a ticket .UE \c \&.) .SS Queries Queries are preferred to hardcoded terminal descriptions because they are forward\-compatible. On startup, Chawan queries: .IP \(bu 2 Whether the terminal has true color, with XTGETTCAP rgb. .IP \(bu 2 The default background, foreground, and 16 ANSI(\-ish) colors with \f[CR]OSC 10 ; ? ST\f[R], \f[CR]OSC 11 ; ? ST\f[R], and \f[CR]OSC 4 ; {0..15} ; ? ST\f[R]. .IP \(bu 2 \f[CR]OSC 60 ST\f[R] and \f[CR]OSC 61 allowWindowOps ST\f[R] for detecting OSC 52 support (see the \f[I]Clipboard\f[R] section). .IP \(bu 2 Whether the terminal can use the Kitty image protocol, by sending a 1x1 Kitty image and listening for a response. .IP \(bu 2 The number of Sixel color registers (\f[CR]CSI ? 1 ; 1 ; 0 $\f[R]). .IP \(bu 2 Primary device attributes (DA1). .IP \(bu 2 Text area and cell size using \f[CR]CSI 14 t\f[R] and \f[CR]CSI 16 t\f[R]. (Cell size beats text area size as it is more reliable.) .IP \(bu 2 Window size in cells by sending a CUP to 9999;9999 and then asking for CPR (the same trick is used by \f[B]resize\f[R](1)). .PP Chawan processes responses to the above query in the same state machine as user input, so it works reasonably well on all terminals that at least emulate the most basic VT100 function (CPR). This unified state machine also minimizes the chance of user input being mistaken for a query response (or vice versa). .PP Terminals that do not respond to CPR will freeze on quit \- in this case, you must type \f[CR]C\-c\f[R] to forcibly kill the state machine. In practice, FreeBSD\(cqs \f[B]vt\f[R](4) is the only one I\(cqve found that exhibits this behavior; to add insult to injury, it claims to be an \(lqxterm\(rq in TERM. Therefore we discriminate between \f[B]vt\f[R](4) and a real XTerm using an ioctl. (Idea shamelessly stolen from notcurses\(cq Linux console detection.) .PP Some terminals bleed the APC sequence used to recognize kitty image support, and this may result in strange artifacts when no alt screen is used. On terminals that set TERM correctly, the APC sequence is not sent. .SS Clipboard Some terminals support sequences to override the clipboard. Chawan differentiates between three tiers: .IP "1." 3 Supports clipboard \f[I]and\f[R] primary selection. The latter is what allows you on X11 to select some text with the mouse and then middle\-click paste it elsewhere. .RS 4 .PP This applies to all terminals that respond to OSC 60/61 (XTerm) as well as a hardcoded list of terminals that respond with 52 in DA1 and have been confirmed to support the primary selection (Kitty). .RE .IP "2." 3 Supports clipboard, but may choke on trying to set primary selection. .RS 4 .PP This applies to terminals that include the number 52 in DA1. This response guarantees nothing about support for the primary selection, and indeed, some terminals that return it (e.g.\ Contour) behave incorrectly when receiving primary. .RE .IP "3." 3 Does not support clipboard. In this case we shell out to \f[CR]external.copy\-cmd\f[R] (defaults to \f[B]xsel\f[R](1x)). .RS 4 .PP This applies to all other terminals. Notably, this includes terminals that support OSC 52 but do not have a reliable mechanism to detect whether it actually works, such as Alacritty. .RE .PP It is possible to manually adjust OSC 52 use with the \f[CR]input.osc52\-copy\f[R] and \f[CR]input.osc52\-primary\f[R] configuration options. .SS Ancient terminals Most pre\-ECMA\-48 (1979) terminals are not expected to work. .PP There is some degree of ADM\-3A support, tested in Kragen Javier Sitaker\(cqs \c .UR https://gitlab.com/kragen/bubbleos admu .UE \c \ emulator. .PP Some DEC terminals have also been tested in simulators of the original hardware running the actual ROM: .IP \(bu 2 The VT100 has been tested in Lars Brinkhoff\(cqs \c .UR https://github.com/larsbrinkhoff/terminal-simulator terminal\-simulator .UE \c \&. Note: use TERM=vt100\-nav if you don\(cqt have advanced video. .IP \(bu 2 The VT420 has been tested in Matt Mastracci\(cqs \c .UR https://github.com/mmastrac/blaze Blaze .UE \c \&. .PP Patches for other terminals (hardware or software alike) are welcome. .SS Ancient character encodings For ASCII\-only terminals, don\(cqt forget to \f[CR]export LC_ALL=C\f[R]. For terminals supporting other legacy encodings, you may also have some luck with \f[CR]language.charset\f[R], such as \f[CR]export LC_ALL=ja_JP.ISO\-2022\-JP\f[R]. .PP Note that Chawan uses its own encoding library instead of the notoriously broken C locale facility, and the two sets of supported charsets may not fully overlap. You can test whether a charset is supported using \f[CR]cha \-O {charset name} \-V\f[R]. .SS See also \f[B]cha\f[R](1) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/cha-troubleshooting.7�������������������������������������������������������������0000664�0000000�0000000�00000015536�15202323131�0017761�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" Automatically generated by Pandoc 3.9.0.2 .\" .TH "CHA-TROUBLESHOOTING" "7" .SH Troubleshooting Chawan This document lists common problems you may run into when using Chawan. .PP If you encounter a problem not described in this document, please open a ticket at \c .UR https://todo.sr.ht/~bptato/chawan .UE \c \&. .SS It doesn\(cqt compile? Please open a ticket. Don\(cqt forget to include the compilation error, and your operating system (and its version). .SS It crashes? Please open a ticket that describes how to reproduce the crash. Don\(cqt forget to include the error message you see after your buffer disappeared. .PP If you don\(cqt see an error message, try: \f[CR]cha example.org \-o start.console\-buffer=false 2>err.log\f[R]. Then check the contents of \f[CR]err.log\f[R] after the crash. .PP If you \f[I]still\f[R] don\(cqt see an error message, no problem, just report that you couldn\(cqt get an error message. .SS I can\(cqt select/copy text with my mouse? Right click \-> select text, then right click \-> copy selection. (You can also double click and drag the mouse to the left/right to select.) .PP If Chawan complains about xsel, either install it or edit \f[CR]external.copy\-cmd\f[R] and \f[CR]external.paste\-cmd\f[R] to your liking. .PP You can also disable mouse tracking temporarily by holding down shift, or permanently by setting in \f[CR]config.toml\f[R]: .IP .EX \f[B][input]\f[R] use\-mouse = false .EE .SS I was promised images but I see nothing? The most common reason is that you didn\(cqt add following to \f[CR]config.toml\f[R]: .IP .EX \f[B][buffer]\f[R] images = true .EE .PP The second most common reason is that your terminal supports neither Sixel nor Kitty images. .PP Other reasons are enumerated \f[B]cha\-image\f[R](7). .SS Why do I get strange/incorrect/ugly colors? By default, Chawan\(cqs display capabilities are limited to what your terminal reports. In particular: .IP \(bu 2 If the \f[CR]$COLORTERM\f[R] environment variable is not set, it may fall back to 8\-bit or ANSI colors. Make sure you export it as \f[CR]COLORTERM=truecolor\f[R]. .IP \(bu 2 If it does not respond to querying the background color, then Chawan\(cqs color contrast correction will likely malfunction. You can correct this using the \f[CR]display.default\-background\-color\f[R] and \f[CR]display.default\-foreground\-color\f[R] options. .PP See the \f[I]Display\f[R] section in \f[B]cha\-config\f[R](5) for details. .SS I set my \f[CR]$PAGER\f[R] to \f[CR]cha\f[R] and now man pages are unreadable. Most \f[CR]man\f[R] implementations print formatted manual pages by default, which Chawan \f[I]can\f[R] parse if they are passed through standard input. .PP Unfortunately, mandoc passes us the formatted document as a \f[I]file\f[R], which Chawan reasonably interprets as plain text without formatting. .PP At this point, you have two options: .IP \(bu 2 \f[CR]export PAGER=\(aqcha \-T text/x\-ansi\(aq\f[R] and see that man suddenly works as expected. .IP \(bu 2 \f[CR]alias man=mancha\f[R] and see that man suddenly works better than expected. .PP Ideally you should do both, to deal with cases like git help which shells out to man directly. .PP There is still one problem with this solution: some programs will try to call \f[CR]$PAGER\f[R] without shell expansion, breaking the \f[CR]\-T text/x\-ansi\f[R] trick. To fix this, put a script somewhere in your \f[CR]PATH\f[R]: .IP .EX \f[I]#!/bin/sh\f[R] exec cha \-T text/x\-ansi \(dq$\(at\(dq .EE .PP and \f[CR]export PAGER=pcha\f[R] (or whatever you named the script). .SS How do I view text files with wrapping? By default, Chawan does not automatically wrap text files, which makes viewing plain text files that were not wrapped by its authors uncomfortable. .PP A workaround is to add this to your config\(cqs \f[CR][page]\f[R] section: .IP .EX \(aqSPC f\(aq = \(dqpager.externFilterSource(\(aqfmt\(aq)\(dq .EE .PP and then type \f[CR]<space> f\f[R] to view a wrapped version of the current text file. (This assumes your system has an \f[CR]fmt\f[R] program \- if not, \f[CR]fold \-s\f[R] may be an alternative.) .PP To always automatically wrap, you can add this to your user style: .IP .EX plaintext { \f[B]white\-space\f[R]: pre\-wrap } .EE .PP To do the same for HTML and ANSI text, use \f[CR]plaintext, pre\f[R]. .SS Why does \f[CR]$WEBSITE\f[R] look awful? Usually, this is because it uses some CSS features that are not yet implemented in Chawan. The most common offender is grid. .PP There are three ways of dealing with this: .IP "1." 3 If the website\(cqs contents are mostly text, install \c .UR https://github.com/eafer/rdrview rdrview .UE \c \&. Then bind the following command to a key of your choice in the config (e.g.\ \f[CR]<space> r\f[R]): .RS 4 .PP \f[CR]\(aq r\(aq = \(dqpager.externFilterSource(\(aqrdrview \-Hu \(rs\(dq$CHA_URL\(rs\(dq\(aq)\(dq\f[R] .PP This does not fix the core problem, but will significantly improve your reading experience anyway. .RE .IP "2." 3 Complain \c .UR https://todo.sr.ht/~bptato/chawan here .UE \c , and wait until the problem goes away. It helps if you can reduce the issue to a minimal reproducible example (ideally a small HTML fragment.) .IP "3." 3 Write a patch to fix the problem, and send it \c .UR https://lists.sr.ht/~bptato/chawan-devel here .UE \c \&. .SS \f[CR]$WEBSITE\f[R]\(cqs interactive features don\(cqt work! Some potential fixes: .IP \(bu 2 Logging in to websites requires cookies. Some websites also require cookie sharing across domains. For security reasons, Chawan does not allow any of this by default, so you will have to fiddle with siteconf to fix it. See the \f[I]Siteconf\f[R] section in \f[B]cha\-config\f[R](5) for details. .IP \(bu 2 Set the \f[CR]referer\-from\f[R] siteconf value to true; this will cause Chawan to send a \f[CR]Referer\f[R] header when navigating to other URLs from the target URL. .IP \(bu 2 Enable JavaScript. If something broke, type M\-c M\-c to check the browser console, then follow step 3.\ of the previous answer. .SS Text areas discard my edits when I type C\-c in my editor! This is a bug in your shell: \c .UR https://people.freebsd.org/~cracauer/homepage-mirror/sigint.html .UE \c .PP When Chawan runs an external text editor, it simply passes the \f[CR]$EDITOR\f[R] command to the shell, and then examines its \f[I]wait status\f[R] to determine if your editor exited gracefully. This works if either the editor never receives a signal, or your shell implements WCE. .PP However, if the editor (e.g.\ nvi) catches SIGINT on C\-c, and the shell reports that the program was killed by a signal (WUE), then Chawan will discard your changes (as it believes that the program has crashed). .PP The easiest workaround is to remove the shell from the equation using \f[CR]exec\f[R]: .IP .EX [external] editor = \(aqexec vi +%d\(aq .EE .SS When I open Chawan from aerc, it prints garbage in the search field! This should be fixed in the latest aerc version. Please update aerc. .SS See also \f[B]cha\f[R](1) ������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/cha-urimethodmap.5����������������������������������������������������������������0000664�0000000�0000000�00000007405�15202323131�0017222�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" Automatically generated by Pandoc 3.9.0.2 .\" .TH "CHA-URIMETHODMAP" "5" .SH URI method map support in Chawan Chawan can be used to map unrecognized protocols to known protocols using the \f[I]urimethodmap\f[R] format. .PP The main use case for this is implementing handlers to protocols unknown to Chawan through a protocol that the browser does understand. .SS Search path The search path for urimethodmap files can be overridden using the configuration variable \f[CR]external.urimethodmap\f[R]. .PP The default search path for urimethodmap files is: .IP .EX $CHA_DIR/urimethodmap:$HOME/.urimethodmap:/etc/urimethodmap .EE .SS Format The urimethodmap format is taken 1:1 from w3m, with some modifications to the interpretation of templates. .PP A rough attempt at the formal description of this: .IP .EX URIMethodMap\-File = *URIMethodMap\-line URIMethodMap\-Line = Comment / URIMethodMap\-Entry URIMethodMap\-Entry = Protocol *WHITESPACE Template *WHITESPACE CR Protocol = 1*CHAR COLON Template = [see below] Comment = *WHITESPACE CR / \(dq#\(dq *CHAR CR .EE .PP Note that an ASCII colon sign (:) must be present after the protocol name. However, the whitespace may be omitted. .PP Examples: .IP .EX # This is ok: protocol: /cgi\-bin/interpret\-protocol?%s # This is ok too: protocol:/cgi\-bin/interpret\-protocol?%s # Spaces and tabs are both allowed, so this is also ok: protocol: /cgi\-bin/interpret\-protocol?%s # However, this is incorrect, because the colon sign is missing: protocol /cgi\-bin/interpret\-protocol?%s .EE .PP The redirection template is the target URL. If the string \f[CR]%s\f[R] is contained in the template, it will be replaced by the target URL. .PP For compatibility with w3m, templates starting with \f[CR]/cgi\-bin/\f[R] and \f[CR]file:/cgi\-bin/\f[R] are special\-cased and the starting string is replaced with \f[CR]cgi\-bin:\f[R]. So for example, the template \f[CR]/cgi\-bin/w3mdict.cgi\f[R] is the same as \f[CR]cgi\-bin:w3mdict.cgi\f[R] (and so is \f[CR]file:/cgi\-bin/w3mdict.cgi\f[R]). .PP Example: .IP .EX # The following are the same in Chawan protocol: /cgi\-bin/interpret\-protocol?%s protocol: file:/cgi\-bin/interpret\-protocol?%s # Note: this last entry does not work in w3m. protocol: cgi\-bin:interpret\-protocol?%s .EE .PP Note however that absolute paths to cgi scripts are NOT special cased, so e.g.\ \f[CR]file:///usr/local/libexec/w3m/cgi\-bin/w3mdict.cgi\f[R] will simply open w3mdict.cgi in the file viewer. (Unlike in w3m, where it could run \f[CR]w3mdict.cgi\f[R] depending on the user\(cqs configuration.) .SS Examples Following lines should be specified in \f[CR]$CHA_DIR/urimethodmap\f[R] (where \f[CR]$CHA_DIR\f[R] is either \(ti/.chawan or \(ti/.config/chawan depending on where your config.toml is). .SS magnet.cgi .IP .EX # Use the \(gamagnet.cgi\(ga CGI shell script to pass magnet links to Transmission. magnet: /cgi\-bin/magnet.cgi?%s .EE .PP \f[CR]magnet.cgi\f[R] can be found in the \f[CR]bonus/\f[R] directory. You can also write a local CGI wrapper to pass the links to your BitTorrent client of choice. .SS dict In w3m, urimethodmap is commonly (ab)used to define shorthands for CGI scripts. .PP This works in Chawan too; for an example, you could define a \f[CR]tl:\f[R] shorthand like this: .IP .EX # (trans.cgi is a script you can find and study in the bonus/ directory.) tl: /cgi\-bin/trans.cgi?%s .EE .PP Then, you could open the translation of any word using \f[CR]tl:word\f[R]. .PP Note however that Chawan has a more powerful facility for substitution shorthands like this in the form of omni\-rules. So if you want to redirect to an online dictionary site with tl:word instead of providing a local CGI interface, it is easier to just use omni\-rules instead of urimethodmap + local CGI redirection. .SS See also \f[B]cha\f[R](1) \f[B]cha\-cgi\f[R](5) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/cha.1�����������������������������������������������������������������������������0000664�0000000�0000000�00000013172�15202323131�0014520�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" Automatically generated by Pandoc 3.9.0.2 .\" .TH "CHA" "1" .SH NAME cha \- the Chawan text\-mode browser .SH SYNOPSIS \f[B]cha\f[R] [\f[B]options\f[R]] [\f[I]URL(s)\f[R] or \f[I]file(s)\f[R]\&...] .SH DESCRIPTION Chawan is a text\-mode browser. It can be used as a pager, or as a web/(S)FTP/gopher/gemini/file browser. It understands HTML and CSS, and when enabled by the user, can also execute JavaScript and display images (on terminals supporting Sixel or the Kitty image protocol.) .PP Chawan can also be used as a general text\-based document viewer as described in \f[B]cha\-mailcap\f[R](5), or as a hyperlinked man page viewer using \f[B]mancha\f[R](1). .PP This document describes the invocation of Chawan. For a list of default keybindings, type \f[I]cha about:chawan\f[R]. For a detailed description of the configuration format, see \f[B]cha\-config\f[R](5). .SH ARGUMENTS On invocation, Chawan attempts to open all URL/file arguments supplied. If no URLs could successfully be opened, Chawan exits automatically. .PP Chawan may also be started without specifying a file, if a file is provided through a pipe. In this case, you can specify the content type using the \f[B]\-T\f[R] switch. .SH OPTIONS All command line options have short forms (e.g.\ \f[B]\-d\f[R]) and long forms (e.g.\ \f[B]\-\-dump\f[R]). .PP Long forms must be introduced with two dashes; when only a single dash is provided, each letter is parsed as a separate short form. .PP In short form, it is also valid to provide values to arguments without a subsequent space. For example, \f[B]\-obuffer.images=true\f[R] is valid. .TP \f[B]\-c\f[R], \f[B]\-\-css\f[R] \f[I]stylesheet\f[R] Temporarily modify the user stylesheet. If a user stylesheet is already being used, the stylesheet given is appended to that. .TP \f[B]\-d\f[R], \f[B]\-\-dump\f[R] Start in headless mode, and sequentially print the opened files to stdout. This option is implicitly enabled if stdout is not a tty (e.g.\ when piping \f[I]cha\f[R] output). .TP \f[B]\-h\f[R], \f[B]\-\-help\f[R] Print a short version of this page, then exit. .TP \f[B]\-o\f[R], \f[B]\-\-opt\f[R] \f[I]config\f[R] Pass temporary configuration options. This accepts the configuration format described in \f[B]cha\-config\f[R](5), so the passed string must be valid TOML. .RS .PP To ease specifying string parameters, unrecognized bare keywords are converted to strings. So this works: .PP \f[B]\-\-opt\f[R] display.color\-mode=\f[I]eight\-bit\f[R]. .PP However, symbols and words starting with a number must still be quoted, i.e.\ you have to quote them twice to bypass shell quoting. .RE .TP \f[B]\-r\f[R], \f[B]\-\-run\f[R] \f[I]script\f[R]/\f[I]file\f[R] Execute the string provided as a JS script, or execute the supplied JS file. If the file ends in .mjs, it is executed as an ES module. .TP \f[B]\-v\f[R], \f[B]\-\-version\f[R] Print information about the browser\(cqs version, then exit. .TP \f[B]\-C\f[R], \f[B]\-\-config\f[R] \f[I]file\f[R] Override the default configuration search path. Both absolute and relative paths are allowed. .TP \f[B]\-I\f[R], \f[B]\-\-input\-charset\f[R] \f[I]charset\f[R] Override the character set of all input files. Useful when Chawan is incorrectly recognizing the input character set. .RS .PP (If this happens often, consider changing the default input charset recognition list \f[I]encoding.document\-charset\f[R] in the configuration.) .RE .TP \f[B]\-M\f[R], \f[B]\-\-monochrome\f[R] Force monochrome output. Formatting (bold/italic/etc.) is not affected. This is a shortcut for \f[B]\-o\f[R] display.color\-mode=\f[I]monochrome\f[R]. .TP \f[B]\-O\f[R], \f[B]\-\-output\-charset\f[R] \f[I]charset\f[R] Override the output character set. This is a shortcut for \f[B]\-o\f[R] encoding.display\-charset=\f[I]charset\f[R]. .TP \f[B]\-T\f[R], \f[B]\-\-type\f[R] \f[I]content\-type\f[R] Override the content type of all input files. Useful when the content type cannot be guessed from the file extension, or when reading a non\-plaintext file from stdin. .TP \f[B]\-V\f[R], \f[B]\-\-visual\f[R] When no files/URLs are passed, open the page specified in \f[I]start.visual\-home\f[R] instead of printing a help screen. .TP \f[B]\-\-\f[R] Interpret all following arguments as files. For example, you can open a file named \f[I]\-o\f[R], using \f[I]cha\f[R] \f[B]\-\-\f[R] \f[I]\-o\f[R]. .SH ENVIRONMENT Certain environment variables are read and used by Chawan. .TP \f[B]TMPDIR\f[R] When set, the default configuration stores temporary files inside this directory (and \f[I]/tmp/cha\-tmp\-user\f[R] otherwise.) .TP \f[B]HTTP_HOME\f[R], \f[B]WWW_HOME\f[R] When set, Chawan starts in visual mode by default and opens the page specified by one of these variables. \f[B]HTTP_HOME\f[R] takes precedence over \f[B]WWW_HOME\f[R]. .TP \f[B]CHA_DIR\f[R] When set, it switches the configuration directory to the path specified. .TP \f[B]COLORTERM\f[R] When set to \f[I]24bit\f[R] or \f[I]truecolor\f[R], and the \f[I]display.color\-mode\f[R] configuration option is set to \f[I]auto\f[R], Chawan sets the color mode to true color. .TP \f[B]TERM\f[R] Used by Chawan to adjust to terminal\-specific quirks. When not set, defaults to \f[I]xterm\f[R]. .TP \f[B]VISUAL\f[R], \f[B]EDITOR\f[R] Used to determine the editor to use when the \f[I]external.editor\f[R] configuration option is not set. .TP \f[B]LINES\f[R], \f[B]COLUMNS\f[R] Used as fallback values when window size detection fails. .SH SEE ALSO \f[B]mancha\f[R](1), \f[B]cha\-config\f[R](5), \f[B]cha\-mailcap\f[R](5), \f[B]cha\-mime.types\f[R](5), \f[B]cha\-cgi\f[R](5), \f[B]cha\-urimethodmap\f[R](5), \f[B]cha\-protocols\f[R](7), \f[B]cha\-image\f[R](7), \f[B]cha\-css\f[R](7), \f[B]cha\-troubleshooting\f[R](7), \f[B]cha\-terminal\f[R](7) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/cha.md����������������������������������������������������������������������������0000664�0000000�0000000�00000012263�15202323131�0014760�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- CHA 1 --> # NAME cha - the Chawan text-mode browser # SYNOPSIS **cha** [**options**] [*URL(s)* or *file(s)*...] # DESCRIPTION Chawan is a text-mode browser. It can be used as a pager, or as a web/(S)FTP/gopher/gemini/file browser. It understands HTML and CSS, and when enabled by the user, can also execute JavaScript and display images (on terminals supporting Sixel or the Kitty image protocol.) Chawan can also be used as a general text-based document viewer as described in **cha-mailcap**(5), or as a hyperlinked man page viewer using **mancha**(1). This document describes the invocation of Chawan. For a list of default keybindings, type *cha about:chawan*. For a detailed description of the configuration format, see **cha-config**(5). # ARGUMENTS On invocation, Chawan attempts to open all URL/file arguments supplied. If no URLs could successfully be opened, Chawan exits automatically. Chawan may also be started without specifying a file, if a file is provided through a pipe. In this case, you can specify the content type using the **\-T** switch. # OPTIONS All command line options have short forms (e.g. **\-d**) and long forms (e.g. **\-\-dump**). Long forms must be introduced with two dashes; when only a single dash is provided, each letter is parsed as a separate short form. In short form, it is also valid to provide values to arguments without a subsequent space. For example, **\-obuffer.images=true** is valid. **\-c**, **\-\-css** *stylesheet* : Temporarily modify the user stylesheet. If a user stylesheet is already being used, the stylesheet given is appended to that. **\-d**, **\-\-dump** : Start in headless mode, and sequentially print the opened files to stdout. This option is implicitly enabled if stdout is not a tty (e.g. when piping *cha* output). **\-h**, **\-\-help** : Print a short version of this page, then exit. **\-o**, **\-\-opt** *config* : Pass temporary configuration options. This accepts the configuration format described in **cha-config**(5), so the passed string must be valid TOML. To ease specifying string parameters, unrecognized bare keywords are converted to strings. So this works: **\-\-opt** display.color-mode=*eight-bit*. However, symbols and words starting with a number must still be quoted, i.e. you have to quote them twice to bypass shell quoting. **\-r**, **\-\-run** *script*/*file* : Execute the string provided as a JS script, or execute the supplied JS file. If the file ends in .mjs, it is executed as an ES module. **\-v**, **\-\-version** : Print information about the browser's version, then exit. **\-C**, **\-\-config** *file* : Override the default configuration search path. Both absolute and relative paths are allowed. **\-I**, **\-\-input-charset** *charset* : Override the character set of all input files. Useful when Chawan is incorrectly recognizing the input character set. (If this happens often, consider changing the default input charset recognition list *encoding.document-charset* in the configuration.) **\-M**, **\-\-monochrome** : Force monochrome output. Formatting (bold/italic/etc.) is not affected. This is a shortcut for **\-o** display.color\-mode=*monochrome*. **\-O**, **\-\-output-charset** *charset* : Override the output character set. This is a shortcut for **\-o** encoding.display\-charset=*charset*. **\-T**, **\-\-type** *content-type* : Override the content type of all input files. Useful when the content type cannot be guessed from the file extension, or when reading a non-plaintext file from stdin. **\-V**, **\-\-visual** : When no files/URLs are passed, open the page specified in *start.visual-home* instead of printing a help screen. **\-\-** : Interpret all following arguments as files. For example, you can open a file named *\-o*, using *cha* **\-\-** *\-o*. # ENVIRONMENT Certain environment variables are read and used by Chawan. **TMPDIR** : When set, the default configuration stores temporary files inside this directory (and */tmp/cha-tmp-user* otherwise.) **HTTP_HOME**, **WWW_HOME** : When set, Chawan starts in visual mode by default and opens the page specified by one of these variables. **HTTP_HOME** takes precedence over **WWW_HOME**. **CHA_DIR** : When set, it switches the configuration directory to the path specified. **COLORTERM** : When set to *24bit* or *truecolor*, and the *display.color-mode* configuration option is set to *auto*, Chawan sets the color mode to true color. **TERM** : Used by Chawan to adjust to terminal-specific quirks. When not set, defaults to *xterm*. **VISUAL**, **EDITOR** : Used to determine the editor to use when the *external.editor* configuration option is not set. **LINES**, **COLUMNS** : Used as fallback values when window size detection fails. # SEE ALSO [**mancha**](mancha.md)(1), [**cha\-config**](config.md)(5), [**cha\-mailcap**](mailcap.md)(5), [**cha\-mime.types**](mime.types.md)(5), [**cha\-cgi**](cgi.md)(5), [**cha\-urimethodmap**](urimethodmap.md)(5), [**cha\-protocols**](protocols.md)(7), [**cha\-image**](image.md)(7), [**cha\-css**](css.md)(7), [**cha\-troubleshooting**](troubleshooting.md)(7), [**cha\-terminal**](terminal.md)(7) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/config.md�������������������������������������������������������������������������0000664�0000000�0000000�00000124526�15202323131�0015500�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- CHA-CONFIG 5 --> # Configuration of Chawan Chawan supports configuration of various options like keybindings, user stylesheets, site preferences, etc. The configuration format is similar to toml, with the following exceptions: * Regular tables (`[table]`) and inline tables (`table = {}`) have different semantics. The first is additive, meaning default values are not removed. The second is destructive, and clears all default definitions in the table specified. * `[[table-array]]` is sugar for `[table-array.n]`, where `n` is the number of declared table arrays. For example, you can declare anonymous siteconfs using the syntax `[[siteconf]]`. The canonical configuration file path is ~/.chawan/config.toml, but the search path accommodates XDG basedirs as well: 1. config file specified through -C switch -> use that 2. `$CHA_DIR` is set -> use `$CHA_DIR/config.toml` 3. `${XDG_CONFIG_HOME:-~/.config}/chawan/config.toml` exists -> use that 4. `~/.chawan/config.toml` exists -> use that See the [*Path handling*](#path-handling) section for details on how the config directory can be accessed. For a configuration template, see bonus/config.toml in the source distribution. <!-- MANOFF --> **Table of contents** * [Start](#start) * [Search](#search) * [Buffer](#buffer) * [Encoding](#encoding) * [External](#external) * [Input](#input) * [Network](#network) * [Display](#display) * [Status](#status) * [Omnirule](#omnirule) * [Siteconf](#siteconf) * [Keybindings](#keybindings) * [Pager actions](#pager-actions) * [Buffer actions](#buffer-actions) * [Line-editing actions](#line-editing-actions) * [Appendix](#appendix) * [Regex handling](#regex-handling) * [Match mode](#match-mode) * [Search mode](#search-mode) * [Path handling](#path-handling) * [Word types](#word-types) * [w3m word](#w3m-word) * [vi word](#vi-word) * [Big word](#big-word) <!-- MANON --> ## Start Start-up options are to be placed in the `[start]` section. Following is a list of start-up options: visual-home = "about:chawan" : **URL** : Page opened when Chawan is called with the -V option and no other pages are passed as arguments. startup-script = "" : **JavaScript code** : Script Chawan runs on start-up. Pages will not be loaded until this function exits. (Note however that asynchronous functions like setTimeout do not block loading.) headless = false : **boolean** / **"dump"** : When set to true or "dump", the browser does not take input; instead, it prints a rendered version of all buffers in order, then exits. The difference between `true` and "dump" is that `true` first waits for all scripts and network requests to run to completion, while "dump" does not. This means that `true` may never exit when scripting is enabled (e.g. if a script sets `setInterval`.) Piping `cha` to an external program or passing the `-d` switch has the same effect as setting this option to "dump". console-buffer = true : **boolean** : Whether Chawan should open a console buffer in non-headless mode. Warning: this is only useful for debugging. Disabling this option without manually redirecting standard error will result in error messages randomly appearing on your screen. ## Buffer Buffer options are to be placed in the `[buffer]` section. These options are global to all buffers. For more granular filtering, use `[[siteconf]]`. Example: ```toml [buffer] # show images on all websites images = true # disable website CSS styling = false # Specify user styles. user-style = ''' /* you can import external UA styles like this: */ @import 'user.css'; /* or just insert the style inline as follows. */ /* enforce the default text-decoration for links (i.e. underline). */ a[href] { text-decoration: revert !important } @media (monochrome) { /* only in color-mode "monochrome" (or -M) */ /* disable UA style of bold font (no need for important here) */ a[href]:hover { font-weight: initial } /* ...and italicize the font on hover instead. * here we use important because we don't want websites to * override the value. */ a[href]:hover { font-style: italic !important } } ''' # You *can* set scripting to true here, but I strongly recommend using # [[siteconf]] to enable it on a per-site basis instead. ``` Following is a list of buffer options: styling = true : **boolean** : Enable/disable author style sheets. Note that disabling this does not affect user styles. scripting = false : **boolean** / **"app"** : Enable/disable JavaScript in *all* buffers. `"app"` also enables JavaScript APIs that can be used to fingerprint users (e.g. querying the window's size). This may achieve better compatibility with websites that behave like applications, at the cost of reduced privacy. For security and performance reasons, users are encouraged to selectively enable JavaScript with `[[siteconf]]` instead of using this setting. images = false : **boolean** : Enable/disable inline image display. cookie = false : **boolean** / **"save"** : Enable/disable cookies on sites. If the string "save" is specified, then cookies are also saved to `external.cookie-file`. `true` still reads cookies.txt, but does not modify it. In Chawan, each website gets a separate cookie jar, so websites relying on cross-site cookies may not work as expected. You may use the `[[siteconf]]` `"share-cookie-jar"` setting to adjust this behavior for specific sites. referer-from = false : **boolean** : Enable/disable the "Referer" header. Defaults to false. For privacy reasons, users are encouraged to leave this option disabled, only enabling it for specific sites in `[[siteconf]]`. autofocus = false : **boolean** : When set to true, elements with an "autofocus" attribute are focused on automatically after the buffer is loaded. If scripting is enabled, this also allows scripts to focus on elements. meta-refresh = "ask" : **"never"** / **"always"** / **"ask"** : Whether or not `http-equiv=refresh` meta tags should be respected. "never" completely disables them, "always" automatically accepts all of them, "ask" brings up a pop-up menu. history = true : **boolean** : Whether or not browsing history should be saved to the disk. mark-links = false : **boolean** : Add numeric markers before links. In headless/dump mode, this also prints a list of URLs after the page. user-style = "" : **CSS stylesheet** : A user stylesheet applied to all buffers. External stylesheets can be imported using the `@import 'file.css';` syntax. Paths are relative to the configuration directory. Nested `@import` is not supported yet. ## Search Search options are to be placed in the `[search]` section. Following is a list of search options: wrap = true : **boolean** : Whether on-page searches should wrap around the document. ignore-case = "auto" : **"auto"** / **boolean** : When set to true, document-wide searches are case-insensitive by default. When set to "auto", searches are only case-sensitive when the search term includes a capital letter. Note: this can also be overridden inline in the search bar (vim-style), with the escape sequences `\c` (ignore case) and `\C` (strict case). See [search mode](#search-mode) for details. ## Encoding Encoding options are to be placed in the `[encoding]` section. Following is a list of encoding options: document-charset = ["utf-8", "sjis", "euc-jp", "latin2"] : **array of charset label strings** : List of character sets for loading documents. All listed character sets are enumerated until the document has been decoded without errors. In HTML, meta tags and the BOM may override this with a different charset, so long as the specified charset can decode the document correctly. display-charset = "auto" : **charset label string** / **"auto"** : Character set for keyboard input and displaying documents. Used in dump mode as well. (This means that e.g. `cha -I EUC-JP -O UTF-8 a > b` is roughly equivalent to `iconv -f EUC-JP -t UTF-8`.) ## External External options are to be placed in the `[external]` section. Following is a list of external options: tmpdir = {usually "/tmp/cha-tmp-user"} : **path** : Directory used to save temporary files. editor = "\${VISUAL:-\${EDITOR:-vi}}" : **shell command** : External editor command. %s is substituted for the file name, %d for the line number. mailcap = ["~/.mailcap", "/etc/mailcap", "/usr/etc/mailcap", "/usr/local/etc/mailcap"] : **array of paths** : Search path for mailcap files. See [**cha-mailcap**](mailcap.md)(5) for details. Directories specified first have higher precedence. mime-types = ["~/.mime.types", "/etc/mime.types", "/usr/etc/mime.types", "/usr/local/etc/mime.types"] : **array of paths** : Search path for mime.types files. See [**cha-mime.types**](mime.types.md)(5) for details. auto-mailcap = "\$CHA_DIR/mailcap" : **path** : Mailcap file for entries that are automatically executed. The "Open as" prompt also saves entries in this file. For backwards-compatibility, if this is "mailcap" and the file does not exist, Chawan will also check "auto.mailcap". cgi-dir = ["\$CHA_DIR/cgi-bin", "\$CHA_LIBEXEC_DIR/cgi-bin"] : **array of paths** : Search path for local CGI scripts. See [**cha-cgi**](cgi.md)(5) for details. urimethodmap = ["\$CHA_DIR/urimethodmap", "~/.urimethodmap", "/etc/urimethodmap"] : **array of paths** : Search path for urimethodmap files. See [**cha-urimethodmap**](urimethodmap.md)(5) for details. w3m-cgi-compat = false : **boolean** : Enable local CGI compatibility with w3m. In short, it redirects `file:///cgi-bin/*` and `file:///$LIB/cgi-bin/*` to `cgi-bin:*`. See [**cha-cgi**](cgi.md)(5) for details. download-dir = "\${TMPDIR:-/tmp}/" : **path** : Path to pre-fill for "Save to:" prompts. show-download-panel = true : **boolean** : Whether `about:downloads` should be opened after starting a download. copy-cmd = "xsel -bi" : **shell command** : Command to use for "copy to clipboard" operations. When `input.osc52-copy` is set to "auto" (the default), `copy-cmd` is ignored if support for OSC 52 is detected. paste-cmd = "xsel -bo" : **shell command** : Command to use for "read from clipboard" operations. bookmark = "\$CHA_DATA_DIR/bookmark.md" : **path** : Path to the bookmark.md file. (The file it points to should have a .md extension, so that its type can be correctly deduced.) history-file = "\$CHA_DATA_DIR/history.uri" : **path** : Path to the history file. history-size = 100 : **number** : Maximum length of the history file. cookie-file = "\$CHA_DATA_DIR/cookies.txt" : **path** : Path to the cookie file. The format is equivalent to curl's "cookies.txt" format, except that a "jar@" part is prepended for cookies that belong in a different jar than the domain. Cookies from this file are used if "buffer.cookie" (or its equivalent siteconf override) is set to `true` or `"save"`. This means that `true` sets the cookie-file to a "read-only" mode. ## Input Input options are to be placed in the `[input]` section. vi-numeric-prefix = true : **boolean** : Whether vi-style numeric prefixes to commands should be accepted. Only applies for keybindings defined in `[page]`. use-mouse = "auto" : **boolean** / **"auto"** : Whether Chawan is allowed to intercept mouse clicks. The current implementation imitates w3m. When set to "auto" (the default), Chawan tries to detect whether mouse support is available. osc52-copy = "auto" : **boolean** / **"auto"** : Whether Chawan should use the OSC 52 escape sequence for copying to the clipboard directly through the terminal. When available, OSC 52 overrides `external.copy-cmd`. When set to "auto" (the default), Chawan tries to detect whether OSC 52 is available on launch. osc52-primary = "auto" : **boolean** / **"auto"** : Whether Chawan should try to set the primary selection through OSC 52. This happens automatically on mouse selection, and also on all clipboard copies. When set to "auto" (the default), Chawan tries to detect whether the terminal is capable of setting the primary selection. Note that very few terminals actually implement OSC 52 correctly (to my knowledge, only XTerm and Kitty), and on other terminals this might even break copying to the clipboard selection. bracketed-paste = "auto" : **boolean** / **"auto"** : Whether Chawan should ask for bracketed paste. When true, the terminal will (hopefully) mark pasted text with escape sequences, which a) ensures that pasting a newline character into the line editor does not submit the editor, b) allows Chawan to intercept text pasted into the pager, automatically loading it into the browser's URL bar. When set to "auto" (the default), Chawan tries to only enable bracketed paste if the terminal is known not to misbehave when trying to do so. wheel-scroll = 5 : **number** : Number of lines to scroll for a mouse wheel event. side-wheel-scroll = 5 : **number** : Number of columns to scroll for a mouse side-wheel event. link-hint-chars = "abcdefghijklmnoprstuvxyz" : **string** : A string of characters to use in `toggleLinkHints`. Any Unicode codepoint is accepted, and they are ordered as specified in this option. Examples: ``` [input] vi-numeric-prefix = true [page] # Here, the arrow function will be called with the vi numbered prefix if # one was input, and with no argument otherwise. # The numeric prefix can never be zero, so it is safe to test for undefined # using the ternary operator. G = 'n => n ? pager.gotoLine(n) : pager.cursorLastLine()' ``` ## Network Network options are to be placed in the `[network]` section. max-redirect = 10 : **number** : Maximum number of redirections to follow. max-net-connections = 12 : **number** : Maximum number of simultaneous network connections allowed in one buffer. Further connections are held back until the number returns below the threshold. prepend-scheme = "https://" : **string** : Prepend this to URLs passed to Chawan (or typed into the URL bar) without a scheme. Note that local files (`file:` scheme) will always be checked first; only if this fails, Chawan will retry the request with `prepend-scheme` set as the scheme. proxy = "" : **URL** : Specify a proxy for all network requests Chawan makes. Currently, the formats `http://user:pass@domain` and `socks5://user:pass@domain` are accepted. Unlike in curl, `socks5h` is an alias of `socks5`, and DNS requests are always tunneled. Can be overridden by siteconf. default-headers = {see bonus/config.toml} : **table** : Specify a table of default headers for all HTTP(S) network requests. Can be overridden by siteconf. allow-http-from-file = false : **boolean** : **WARNING: think twice before enabling this.** Allows HTTP and HTTPS requests from the `file:` and `stream:` schemes. This is a bad idea in general, because it allows local files to ping remote servers (a functionality commonly abused by HTML e-mails to track your mailbox activity). On the other hand, it allows loading images in HTML e-mails if you don't care about the privacy implications. ## Display Display options are to be placed in the `[display]` section. Following is a list of display options: color-mode = "auto" : **"monochrome"** / **"ansi"** / **"eight-bit"** / **"true-color"** / **"auto"** : Set the color mode. "auto" for automatic detection, "monochrome" for black on white, "ansi" for eight ANSI plus eight aixterm colors, "eight-bit" for 256-color mode, and "true-color" for 24-bit colors. format-mode = "auto" : **"auto"** / **["bold", "italic", "underline", "reverse", "strike", "overline", "blink"]** : Specifies allowed output formatting modes. Accepts the string "auto" or an array of specific attributes. "auto" (the default) tries to detect supported formatting modes when launched visually, and omits all formatting modes in dump mode. An empty array (`[]`) disables formatting even in visual mode. no-format-mode = ["overline"] : **["bold", "italic", "underline", "reverse", "strike", "overline", "blink"]** : Disable specific formatting modes. image-mode = "auto" : **"auto"** / **"none"** / **"sixel"** / **"kitty"** : Specifies the image output mode. "sixel" uses sixels for output, "kitty" uses the Kitty image display protocol, "none" disables image display completely. "auto" (the default) detects sixel or kitty support automatically, and falls back to "none" when neither are available. This is expected to work on all known terminals with functional image support. Note that `buffer.images` must be enabled for images to load at all. sixel-colors = "auto" : **"auto"** / **2..65535** : Only applies when `display.image-mode="sixel"`. Setting this to a number overrides the number of sixel color registers reported by the terminal. alt-screen = "auto" : **"auto"** / **boolean** : Enable/disable the alternative screen. "auto" (the default) tries to detect support for this feature. (However, since Chawan does not link to terminfo, you should not expect hacks which remove the respective terminfo description to work.) highlight-color = "-cha-ansi(bright-cyan)" : **CSS color** : Set the highlight color for incremental search and marks. CSS color names, hex values, and color functions are all accepted. In monochrome mode, this setting is ignored; instead, reverse video is used. highlight-marks = true : **boolean** : Enable/disable highlighting of marks. double-width-ambiguous = false : **boolean** : Assume the terminal displays characters in the East Asian Ambiguous category as double-width characters. Useful when e.g. ○ occupies two cells. minimum-contrast = 100 : **0..235** : Specify the minimum difference between the luminance (Y) of the default terminal background and the foreground as represented in YUV. 0 disables this function (i.e. allows black letters on black background, etc). Note: in the past, this option used to apply to all colors, but since v0.3 Chawan only performs color contrast correction when either the foreground or background color is the terminal default. Also, the contrast correction algorithm is still not perfect, so future changes are to be expected. set-title = true : **boolean** : Set the terminal emulator's window title to that of the current page. default-background-color = "auto" : **"auto"** / **RGB color** : Overrides the assumed background color of the terminal. "auto" leaves background color detection to Chawan. default-foreground-color = "auto" : **"auto"** / **RGB color** : Sets the assumed foreground color of the terminal. "auto" leaves foreground color detection to Chawan. columns = 80, lines = 24, pixels-per-column = 9, pixels-per-line = 18 : **number** : Fallback values for the number of columns, lines, pixels per column, and pixels per line for the cases where it cannot be determined automatically. (For example, these values are used in dump mode.) force-columns = false, force-lines = false, force-pixels-per-column = false, force-pixels-per-line = false : **boolean** : Force-set columns, lines, pixels per column, or pixels per line to the fallback values provided above. ## Status Options concerning the status bar (last line on the screen) are to be placed in the `[status]` section. Following is a list of status options: show-cursor-position = true : **boolean** : Whether or not the current line number should be displayed. show-hover-link = true : **boolean** : Whether or not the link under the cursor should be displayed. format-mode = "reverse" : **{see \[display\] section}** : Formatting of the status bar. ## Omnirule The omni-bar (by default opened with C-l) can be used to perform searches using omni-rules. These are to be specified as sub-keys to table `[omnirule]`. (The sub-key itself is ignored; you can use anything as long it doesn't conflict with other keys.) Examples: ``` # Search using DuckDuckGo Lite. # (This rule is included in the default config, although C-k invokes # Brave search.) [omnirule.ddg] match = '^ddg:' substitute-url = '(x) => "https://lite.duckduckgo.com/lite/?kp=-1&kd=-1&q=" + encodeURIComponent(x.split(":").slice(1).join(":"))' # To use the above rule, open the URL bar with C-k, clear it with # C-u, and type ddg:keyword. # Alternatively, you can also redefine C-k like: [page] 'C-k' = '() => pager.load("ddg:")' # Search using Wikipedia, Firefox-style. # The [[omnirule]] syntax introduces an anonymous omnirule; it is # equivalent to the named one. [[omnirule]] match = '^@wikipedia' substitute-url = '(x) => "https://en.wikipedia.org/wiki/Special:Search?search=" + encodeURIComponent(x.replace(/@wikipedia/, ""))' ``` As noted above, the default config includes some built-in rules, selected according to the maintainer's preference and the minimum criterion that they must work without cookies and JavaScript. Currently, these are: * `ddg:` - DuckDuckGo Lite. * `br:` - Brave Search. * `wk:` - English Wikipedia. * `wd:` - English Wikitionary. * `mo:` - Mojeek. Omnirule options: match : **regex** : Regular expression used to match the input string. Note that websites passed as arguments are matched as well. Note: regexes are handled according to the [match mode](#match-mode) regex handling rules. substitute-url : **JavaScript function** : A JavaScript function Chawan will pass the input string to. If a new string is returned, it will be parsed instead of the old one. ## Siteconf Configuration options can be specified for individual sites. Entries are to be specified as sub-keys to table `[siteconf]`. (The sub-key itself is ignored; you can use anything as long it doesn't conflict with other keys.) Most siteconf options can also be specified globally; see the "overrides" field. Examples: ``` # Enable cookies on the orange website for log-in. [siteconf.hn] url = 'https://news\.ycombinator\.com/.*' cookie = true # Redirect npr.org to text.npr.org. [siteconf.npr] host = '(www\.)?npr\.org' rewrite-url = ''' (x) => { x.host = "text.npr.org"; const s = x.pathname.split('/'); x.pathname = s.at(s.length > 2 ? -2 : 1); /* No need to return; URL objects are passed by reference. */ } ''' # Allow cookie sharing on *sr.ht domains. [siteconf.sr-ht] host = '(.*\.)?sr\.ht' # either 'something.sr.ht' or 'sr.ht' cookie = true # enable cookies (read-only; use "save" to persist them) share-cookie-jar = 'sr.ht' # use the cookie jar of 'sr.ht' for all matched hosts # Use the "vector" skin on Wikipedia. # The [[siteconf]] syntax introduces an anonymous siteconf; it is # equivalent to the above ones. [[siteconf]] url = '^https?://[a-z]+\.wikipedia\.org/wiki/(?!.*useskin=.*)' rewrite-url = 'x => x.searchParams.append("useskin", "vector")' # Make imgur send us images. [siteconf.imgur] host = '(i\.)?imgur\.com' default-headers = { User-Agent = "Mozilla/5.0 chawan", Accept = "*/*", Accept-Encoding = "gzip, deflate", Accept-Language = "en;q=1.0", Pragma = "no-cache", Cache-Control = "no-cache" } ``` Siteconf options: url : **regex** : Regular expression used to match the URL. Either this or the `host` option must be specified. Note: regexes are handled according to the [match mode](#match-mode) regex handling rules. host : **regex** : Regular expression used to match the host part of the URL (i.e. domain name/ip address). Either this or the `url` option (but not both) must be specified. Note: regexes are handled according to the [match mode](#match-mode) regex handling rules. rewrite-url : **JavaScript function** : A JavaScript function Chawan will pass the site's URL object to. If a new URL is returned, or the URL object is modified in any way, Chawan will transparently redirect the user to this new URL. cookie = buffer.cookie : **boolean** / **"save"** : Whether loading (with "save", also saving) cookies should be allowed for this URL. share-cookie-jar : **host string** : Cookie jar to use for this domain. Useful for e.g. sharing cookies with subdomains. referer-from = buffer.referer-from : **boolean** : Whether or not Chawan should send a Referer header when opening requests originating from this domain. Simplified example: if you click a link on a.com that refers to b.com, and referer-from is true, b.com is sent "a.com" as the Referer header. scripting = buffer.scripting : **boolean** / **"app"** : Enable/disable JavaScript execution on this site. See `buffer.scripting` for details. styling = buffer.styling : **boolean** : Enable/disable author styles (CSS) on this site. images = buffer.images : **boolean** : Enable/disable loading of images on this site. document-charset = encoding.document-charset : **charset label string** : Specify the default encoding for this site. proxy = network.proxy : **URL string** : Specify a proxy for network requests fetching contents of this buffer. default-headers = network.default-headers : **table** : Specify a list of default headers for HTTP(S) network requests to this buffer. insecure-ssl-no-verify = false : **boolean** : When set to true, this disables peer and hostname verification for SSL keys on this site, like `curl --insecure` would. Please do not use this unless you are absolutely sure you know what you are doing. autofocus = buffer.autofocus : **boolean** : When set to true, elements with an "autofocus" attribute are focused on automatically after the buffer is loaded. If scripting is enabled, this also allows scripts to focus on elements. meta-refresh = buffer.meta-refresh : **"never"** / **"always"** / **"ask"** : Whether or not `http-equiv=refresh` meta tags and headers should be respected. "never" completely disables them, "always" automatically accepts all of them, "ask" brings up a pop-up menu. history = buffer.history : **boolean** : Whether or not browsing history should be saved to the disk for this URL. mark-links = buffer.mark-links : **boolean** : Add numeric markers before links. user-style = buffer.user-style : **string** : Specify a user style sheet specific to the site. Refer to `buffer.user-style` for details. ## Keybindings Keybindings are to be placed in these sections: * for pager interaction: `[page]` * for line editing: `[line]` Keybindings are configured using the syntax ```toml '<keybinding>' = '<action>' ``` Where `<keybinding>` is a combination of unicode characters using the syntax described below. `<action>` is either a command defined in the `[cmd]` section, or a JavaScript expression. This document only describes the pre-defined actions in the default config; for a description of the API, see [**cha-api**](api.md)(7). Examples: ```toml # show change URL when Control, Escape and j are pressed 'C-M-j' = 'load' # go to the first line of the page when g is pressed twice without a preceding # number, or to the line when a preceding number is given. 'g g' = 'gotoLineOrStart' # JS functions and expressions are accepted too. Following replaces the # default search engine with DuckDuckGo Lite. # (See api.md for a list of available functions, and a discussion on how # to add your own "namespaced" commands like above.) 'C-k' = '() => pager.load("ddg:")' ``` ### Keybinding format A keybinding is a space-separated list of keys, optionally prefixed by modifiers `S-` (shift), `C-` (control), or `M-` (meta). In general, ASCII/Unicode keys can be written as-is. The exception is space, which is written as `SPC`. Other supported named keys are: `TAB`, `ESC`, `RET` (return key), `LF` (enter key/line feed), `Left`, `Up`, `Down`, `Right` (cursor keys), `PageUp`, `PageDown` (page up/down), `Home`, `End`, and function keys `F1` through `F20`. For backwards-compatibility, spaces can be omitted from key sequences that do not start with an upper-case letter. For example, `'gg'` and `'g g'` are equivalent. However, components that start with an upper-case letter (e.g. `'Gg'`) are reserved for key names, so those must be space-separated (e.g. `'G g'`) to avoid ambiguous parsing. Also, for backwards-compatibility, spaces at the beginning/end of the keybinding are translated to `SPC`. ### Pager actions Default keybindings are highlighted in **bold**. quit : **q** : Exit the browser. suspend : **C-z** : Temporarily suspend the browser Note: this also suspends e.g. buffer processes or CGI scripts. So if you are downloading something, that will be delayed until you restart the process. load : **C-l** : Open the current address in the URL bar. loadCursor : **M-l** : Open the address of the link or image being hovered in the URL bar. If no link/image is under the cursor, an empty URL bar is opened. loadEmpty : Open an empty address bar. webSearch : **C-k** : Open the URL bar with an arbitrary search engine. At the moment, this is Brave Search, but this may change in the future. dupeBuffer : **M-u** : Duplicate the current buffer. This is a shallow clone, so modifications to one buffer will affect the other. reloadBuffer : **U** : Open a new buffer with the current buffer's URL, replacing the current buffer. lineInfo : **C-g** : Display information about the current line on the status line. toggleSource : **&bsol;** : If viewing an HTML buffer, open a new buffer with its source. Otherwise, open the current buffer's contents as HTML. saveScreen : **s s** : Save the rendered buffer to a file. saveSource : **s S** : Save the buffer's source to a file. editScreen : **s e** : Open the rendered buffer in an editor. editSource : **s E** : Open the buffer's source in an editor. discardBuffer : **D** : Discard the current buffer, and move back to the previous/next buffer depending on what the previously viewed buffer was. discardBufferPrev, discardBufferNext : **d ,**, **d .** : Discard the current buffer, and move back to the previous/next buffer, or open the link under the cursor. discardTree : **M-d** : Discard all child buffers of the current buffer. nextBuffer, prevBuffer : **.**, **,** : Switch to the next or previous buffer respectively. enterCommand : **M-c** : Directly enter a JavaScript command. Note that this interacts with the pager, not the website being displayed. searchForward, searchBackward : Search for a string in the current buffer, forwards or backwards. isearchForward, searchBackward : **/**, **?** : Incremental-search for a string, highlighting the first result, forwards or backwards. searchNext, searchPrev : **n**, **N** : Jump to the nth (or if unspecified, first) next/previous search result. peek : Display a message of the current buffer's URL on the status line. peekCursor : **u** : Display a message of the URL or title under the cursor on the status line. Multiple calls allow cycling through the two. (i.e. by default, press u once -> title, press again -> URL) showFullAlert : **s u** : Show the last alert inside the line editor. You can also view previous ones using C-p or C-n. copyURL : **M-y** : Copy the current buffer's URL to the system clipboard. copyCursorLink : **y u** : Copy the link under the cursor to the system clipboard. copyCursorImage : **y I** : Copy the URL of the image under the cursor to the system clipboard. gotoClipboardURL : **M-p** : Go to the URL currently on the clipboard. openBookmarks : **M-b** : Open the bookmark file. addBookmark : **M-a** : Add the current page to your bookmarks. toggleLinkHints : **f** : Show hints before each link (or button). After typing a hint, the cursor is placed on the respective link. The hint character set may be customized with `input.link-hint-chars`. toggleLinkHintsAutoClick : Same as `toggleLinkHints`, but also click the selected link. ### Buffer actions `n` refers to a number preceding the action. e.g. in `10gg`, `n` is 10. If no preceding number is input, then it is left unspecified. Default keybindings are highlighted in **bold**. cursorUp, cursorDown : **j**/**C-p**/**Up**, **k**/**C-n**/**Down** : Move the cursor upwards/downwards by `n` lines, or if `n` is unspecified, by 1. cursorLeft, cursorRight : **h**/**Left**, **l**/**Right** : Move the cursor to the left/right by `n` cells, or if `n` is unspecified, by 1. cursorLineBegin : **0**/**Home** : Move the cursor to the first cell of the line. cursorLineTextStart : **^** : Move the cursor to the first non-blank character of the line. cursorLineEnd : **&dollar;**/**End** : Move the cursor to the last cell of the line. cursorNextWord, cursorNextViWord, cursorNextBigWord : **w**, **W** : Move the cursor to the beginning of the nth next [word](#word-types). cursorPrevWord, cursorPrevViWord, cursorPrevBigWord : Move the cursor to the end of the nth previous [word](#word-types). cursorWordEnd, cursorViWordEnd, cursorBigWordEnd : **e**, **E** : Move the cursor to the end of the current [word](#word-types), or if already there, to the end of the nth next word. cursorWordBegin, cursorViWordBegin, cursorBigWordBegin : **b**, **B** : Move the cursor to the beginning of the current [word](#word-types), or if already there, to the end of the nth previous word. cursorPrevLink, cursorNextLink : **[**, **]** : Move the cursor to the end/beginning of the previous/next clickable element (e.g. link, input field, etc). cursorPrevParagraph, cursorNextParagraph : **{**, **}** : Move the cursor to the end/beginning of the nth previous/next paragraph. cursorRevNthLink : Move the cursor to the nth link of the document, counting backwards from the document's last line. cursorNthLink : Move the cursor to the nth link of the document. pageUp, pageDown, pageLeft, pageRight : **C-b**/**PageUp**, **C-f**/**PageDown**, **z H**, **z L** : Scroll up/down/left/right by `n` pages, or if `n` is unspecified, by one page. halfPageUp, halfPageDown, halfPageLeft, halfPageUp : **C-u**, **C-d** : Scroll up/down/left/right by `n` half pages, or if `n` is unspecified, by one page. scrollUp, scrollDown, scrollLeft, scrollRight : **K**/**C-y**, **J**/**C-e**, **z h**, **z l** : Scroll up/down/left/right by `n` lines, or if `n` is unspecified, by one line. click : **RET**/**LF** : Click the HTML element currently under the cursor. `n` specifies the number of clicks in JS events. rightClick : **c** : Send a right click to the buffer. If it doesn't catch the event (i.e. no JS context menu is shown), toggle the menu instead. toggleMenu : **C** : Toggle the menu. viewImage : **I** : View the image currently under the cursor in an external viewer. reshape : **R** : Reshape the current buffer (=render the current page anew). Useful if the layout is not updating even though it should have. redraw : **r** : Redraw screen contents. Useful if something messed up the display. cursorFirstLine, cursorLastLine : Move to the beginning/end in the buffer. cursorTop, cursorMiddle, cursorBottom : **H**, **M**, **L** : Move to the first line/line in the middle of/last line on the screen. (Equivalent to `H`, `M`, `L` in vi.) raisePage, raisePageBegin, centerLine, centerLineBegin, lowerPage, lowerPageBegin : **z t**, **z RET**, **z z**, **z .**, **z b**, **z -** : If `n` is specified, move cursor to line `n`. Then, * `raisePage` scrolls down so that the cursor is on the top line of the screen. (vi `z RET`, vim `z t`.) * `centerLine` shifts the screen so that the cursor is in the middle of the screen. (vi `z .`, vim `z z`.) * `lowerPage` scrolls up so that the cursor is on the bottom line of the screen. (vi `z -`, vim `z b`.) The -Begin variants also move the cursor to the line's first non-blank character, as the original keybindings in vi do. nextPageBegin : **z +** : If `n` is specified, move to the screen before the nth line and raise the page. Otherwise, go to the next screen's first line and raise the page. previousPageBegin : **z ^** : If `n` is specified, move to the screen before the nth line and lower the page. Otherwise, go to the previous screen's last line and lower the page. cursorLeftEdge, cursorMiddleColumn, cursorRightEdge : **g 0**, **g c**, **g $** : Move to the first/middle/last column on the screen. centerColumn : Center screen around the current column. (w3m `Z`.) gotoLineOrStart, gotoLineOrEnd : **g g**, **G** : If `n` is specified, jump to line `n`. Otherwise, jump to the first/last line of the buffer. gotoColumnOrBegin, gotoColumnOrEnd : **&vert;** : If `n` is specified, jump to column `n` of the current line. Otherwise, jump to the first/last column. mark : **m** : Wait for a character `x` and then set a mark with the ID `x`. gotoMark, gotoMarkY : **&grave;**, **'** : Wait for a character `x` and then jump to the mark with the ID `x` (if it exists on the page). `gotoMark` sets both the X and Y positions; gotoMarkY only sets the Y position. markURL : **:** : Convert URL-like strings to anchors on the current page. saveLink : **s RET** : Save resource from the URL pointed to by the cursor to the disk. saveSource : **s S** : Save the source of the current buffer to the disk. saveImage : **s I** : Save the image currently under the cursor. toggleImages : **M-i** : Toggle display of images in the current buffer. toggleScripting : **M-j** : Reload the current buffer with scripting enabled/disabled. toggleCookie : **M-k** : Reload the current buffer with cookies enabled/disabled. cursorSearchWordForward : **C-a**, **\*** : Search for the word currently under the cursor. cursorSearchWordBackward : **#** : Search for the word currently under the cursor, backwards. ### Line-editing actions line.submit : **RET**, **LF** : Submit the currently entered text. line.cancel : **C-g** : Close the editor and cancel the operation it was opened for. line.copyOrCancel : **C-c** : If there is an active selection, copy it. Otherwise, it's the same as `line.cancel`. line.backspace, line.delete : **C-h**, **C-d** : Delete character before (backspace)/after (delete) the cursor. line.clear, line.kill : **C-u**/**C-x C-?**, **C-k** : Delete text before (clear)/after (kill) the cursor. line.openEditor : **C-x C-e** : Open the line editor's contents in $EDITOR. line.clearWord, line.killWord : **C-w**, **M-d** : Delete word before (clear)/after (kill) the cursor. line.backward, line.forward : **C-b**, **C-f** : Move cursor backward/forward by one character. line.prevWord, line.nextWord : **M-b**, **M-f** : Move cursor to the previous/next word by one character line.begin, line.end : **C-a**/**Home**, **C-e**/**End** : Move cursor to the beginning/end of the line. line.escape : **C-v** : Ignore keybindings for next character. line.prevHist, line.nextHist : **C-p**, **C-n** : Jump to the previous/next history entry Note: to facilitate URL editing, the line editor has a different definition of what a word is than the pager. For the line editor, a word is either a sequence of alphanumeric characters, or any single non-alphanumeric character. (This means that e.g. `https://` consists of four words: `https`, `:`, `/` and `/`.) ```Examples: # Control+A moves the cursor to the beginning of the line. 'C-a' = 'line.begin' # Escape+D deletes everything after the cursor until it reaches a word-breaking # character. 'M-d' = 'line.killWord' ``` ## Appendix ### Regex handling Regular expressions are currently handled using the libregexp library from QuickJS. This means that all regular expressions work as in JavaScript. There are two different modes of regex preprocessing in Chawan: "search" mode and "match" mode. Match mode is used for configurations (meaning in all values in this document described as "regex"). Search mode is used for the on-page search function (using searchForward/isearchForward etc.) #### Match mode Regular expressions are assumed to be exact matches, except when they start with a caret (^) sign or end with an unescaped dollar ($) sign. In other words, the following transformations occur: ``` ^abcd -> ^abcd (no change, only beginning is matched) efgh$ -> efgh$ (no change, only end is matched) ^ijkl$ -> ^ijkl$ (no change, the entire line is matched) mnop -> ^mnop$ (changed to exact match, the entire line is matched) ``` Match mode has no way to toggle JavaScript regex flags like `i`. #### Search mode For on-page search, the above transformations do not apply; the search `/abcd` searches for the string `abcd` inside all lines. Search mode also has some other convenience transformations (these do not work in match mode): * The string `\c` (backslash + lower-case c) inside a search-mode regex enables case-insensitive matching. * Conversely, `\C` (backslash + capital C) disables case-insensitive matching. (Useful if you have `ignore-case` set to true, which is the default.) * `\<` and `\>` is converted to `\b` (as in vi, grep, etc.) Like match mode, search mode operates on individual lines. This means that search patterns do not match text wrapped over multiple lines. ### Path handling Rules for path handling are similar to how the shell handles strings. * Tilde-expansion is used to determine the user's home directory. So e.g. `~/whatever` works. * Environment variables can be used like `$ENV_VAR`. * Relative paths are relative to the Chawan configuration directory (i.e. `$CHA_DIR`). Some environment variables are also exported by Chawan: * `$CHA_BIN_DIR`: the directory which the `cha` binary resides in. Symbolic links are automatically resolved to determine this path. * `$CHA_LIBEXEC_DIR`: the directory for all executables Chawan uses for operation. By default, this is `$CHA_BIN_DIR/../libexec/chawan`. * `$CHA_DIR`: the configuration directory. (This can also be set by the user; see the top section for details.) * `$CHA_DATA_DIR`: if the configuration file uses XDG base directories, this is `${XDG_DATA_HOME:-$HOME/.local/share}/chawan`. Otherwise, it is the same as `$CHA_DIR`. - Exception: if `$CHA_DIR` is set before `cha` is invoked, then `$CHA_DATA_DIR` is also read. This is to make nested invocations work in configurations with XDG basedirs. ### Word types Word-based pager commands can operate with different definitions of words. Currently, these are: * w3m words * vi words * Big words #### w3m word A w3m word is a sequence of alphanumeric characters. Symbols are treated in the same way as whitespace. #### vi word A vi word is a sequence of characters in the same character category. Currently, character categories are alphanumeric characters, symbols, han letters, hiragana, katakana, and hangul. vi words may be separated by whitespace; however, vi words from separate categories do not have to be whitespace-separated. e.g. the following character sequence contains two words: ``` hello[]+{}@`! ``` #### Big word A big word is a sequence of non-whitespace characters. It is essentially the same as a w3m word, but with symbols being defined as non-whitespace. ## See also [**cha**](cha.md)(1) [**cha-api**](api.md)(7) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/css.md����������������������������������������������������������������������������0000664�0000000�0000000�00000023213�15202323131�0015012�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- CHA-CSS 7 --> # CSS in Chawan This document describes CSS features supported by Chawan, as well as its proprietary extensions and deviations from standards. If you discover a deviation that is not covered by this document, please open a ticket at <https://todo.sr.ht/~bptato/chawan>. ## Standard properties A list of supported standard properties, with notes on unimplemented values: * background-color (see color) * background-image (displays placeholders only) * border-collapse * border-\*-style, border-\*-color, border-\*-width (but see [borders](#borders)) * border-spacing * bottom * box-sizing * caption-side * clear * color (hex values and functions `rgb`, `rgba`, `hsl`, `hsla`) * content (string, (no-)open/close-quote, counter()) * counter-increment * counter-reset * counter-set * display (`block`, `inline-block`, `list-item`, `table`, `inline-table`, `table-*`, `flex`, `inline-flex`, `flow-root`) * flex-basis (but `content` not supported) * flex-direction * flex-grow * flex-shrink * flex-wrap * float * font-size (ignored; only for JS compatibility) * font-style (`oblique` interpreted as `italic`) * font-weight (numeric properties > 500 interpreted as bold, others as regular) * height * left * list-style-position * list-style-type (but no custom list styles) * margin-bottom * margin-left * margin-right * margin-top * max-height * max-width * min-height * min-width * opacity (hacky; only works with `opacity: 0`) * overflow-x (see below on scrollbars) * overflow-y (see below on scrollbars) * padding-bottom * padding-left * padding-right * padding-top * position (see below for `sticky` and `fixed`) * quotes * right * text-align * text-decoration (`none`, `underline`, `overline`, `line-through`) * text-transform * top * vertical-align * visibility * white-space * width * word-break * z-index Shorthands: * all * margin * padding * border, border-style, border-color, border-width (but see [borders](#borders)) * background (only color and url; other components are skipped) * list-style (list-style-image is skipped) * flex * flex-flow * overflow Variables (the `var()` function) are fully supported. Values of `<length>` or `<color>` types fully support `calc()` expressions. ## Selectors All selector types from CSS 2.1 are supported, except for namespaces. Following standard pseudo-classes are supported: `:first-child`, `:last-child`, `:only-child`, `:hover`, `:root`, `:nth-child()`, `:nth-last-child()`, `:checked`, `:focus`, `:is()`, `:not()`, `:where()`, `:lang()`, `:link`, `:target`, `:disabled`. `:visited` is parsed, but for now it is not matched. `:defined`, `:host`, and `:host()` are matched for compatibility; however, custom elements and shadow DOM are not supported yet. The standard pseudo-elements `::before`, `::after`, and `::marker` are supported. `::backdrop` is parsed for compatibility, but is not supported yet. ## At-rules Following rules starting with an `@` sign are supported. ### `@media` The `grid`, `hover`, `prefers-color-scheme`, `scripting`, `width`, and `height` media features are fully supported. The `color`, `color-index`, and `monochrome` features are supported, but only consider the number of supported text colors (which can differ from the number of colors in Sixel/Kitty images). ### `@import` Importing to layers is supported. `@import` combined with media queries is not yet supported. ### `@layer` `@layer` is fully supported. (I think.) ## Proprietary extensions * `text-align` accepts the values `-cha-center`, `-cha-left`, and `-cha-right` to support the HTML `<center>`, `<div align=left>` and `<div align=right>` elements. (Analogous to `-moz-center` etc.) * Properties with a `<color>` value accept the function `-cha-ansi()`, mapping to terminal-specific ("ANSI") colors. The function takes one of - An 8-bit integer, indicating a color value as set by XTerm's indexed color feature. - One of the strings "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white" for an ANSI color, possibly prefixed by the string "bright-" to indicate an aixterm 16-color value. * `text-decoration` accepts the keyword `-cha-reverse`, which sets the *reverse video* parameter on the text. (This is used by the UA style sheet to highlight text in `<code>` tags.) * `text-transform` accepts the keyword `-cha-half-width`, which has the opposite effect as `full-width`. This can be used in user style sheets to compress distracting ruby text: `rt{text-transform: -cha-half-width}`. Characters without half-width counterparts are left intact, except hiragana is treated as katakana. * The `-cha-colspan` and `-cha-rowspan` properties have the same effect as the `colspan` and `rowspan` attributes on tables. * The `:-cha-first-node` and `:-cha-last-node` pseudo-classes apply to elements that have no preceding/subsequent sibling node that is either an element node or a text node with non-whitespace contents. (Modeled after `:-moz-first-node` and `:-moz-last-node`.) * If `buffer.mark-links` is set, the `::-cha-link-marker` pseudo-element will be generated on all anchor elements. * In hints mode (by default, the `f` key) the markers are implemented by generating `::-cha-link-hint` on all applicable elements. So you can change the marker background in your `user-style` (`[buffer]` section in `config.toml`): ```css ::-cha-link-hint { background: gainsboro } ``` * The `-cha-content-type` media feature can be used to filter documents for their content type. For example, you can add ```css @media (-cha-content-type: "text/markdown") { body { width: 80ch } } ``` to your `user-style` to set the body width of all markdown documents to 80 characters. (The string is matched case-insensitively.) ## Rendering quirks These are willful violations of the standard, usually made to better fit the display model inherent to projecting the web to a cell-based screen. ### User agent style sheet The user agent style sheet is a combination of the styles suggested by the HTML standard and a CSS port of w3m's rendering. In general, faithfulness to w3m is preferred over the standard's suggestions, unless w3m's rendering breaks on existing websites. Link colors differ depending on the terminal's color scheme. ### Sizing and positioning Layout is performed on a finite canvas of coordinates represented by a 32-bit fixed-point number with 6 bits of precision. After layout, these positions are divided by the cell width and/or height, with the fractional part truncated. (This is subject to change.) In case of Kitty images, the fractional part is preserved, and is used as an in-cell offset. The lengths `1em` and `1ch` compute to the cell height and cell width respectively. In outer inline boxes (`inline-block`, `inline-flex`) and `list-item` boxes, margins and padding that are smaller than one cell (on the respective axis) are ignored. This does not apply to blockified inline boxes. When calculating clip boxes (`overflow: hidden` or `clip`), the clip box's offset is floored, and its size is ceiled to the nearest cell's boundaries. This means that "width: 1px; overflow: hidden" will still display the first character of a text box. ### Scroll bars Chawan does not have scroll bars, as they would complicate on-page navigation and would not work in dump mode. Instead, the "overflow-x/y" properties are handled as follows. 1. If `overflow` is `auto` or `scroll`, and the intrinsic minimum size of the box is greater than its specified size, then the former overrides the latter. 2. Content that spills out of a scroll container on the X axis is displayed, while content that spills out of a scroll container on the Y axis is clipped. ### `position: fixed`, `position: sticky` To keep the document model static, these do not change their position based on the viewport's scroll status. Instead: * `position: sticky` is treated as `position: static`, except it also behaves as an absolute position container. * `position: fixed` is placed at the bottom of the document. Right now, `position: fixed` is always positioned at the bottom of the root element's margin box. This breaks on pages that overflow it (e.g. by setting `height: 100%` on the root element), so it will be moved to the bottom of its overflow box in the future. ### Color correction Some authors only specify one of the foreground or the background color, assuming a black-on-white canvas. The `display.minimum-contrast` option adjusts the foreground color so that text remains readable even if the terminal background does not match this expectation. (The exact algorithm is unspecified and subject to change.) To avoid breaking spoiler mechanisms that rely on "black on black" text, color correction is not invoked on cells that have an RGB color (typically specified by the author.) ### Borders CSS borders are difficult to accurately display on a cell-based display. So while the functionality exists, it has some limitations: * On tables, borders are always collapsed, even when `border-collapse` is set to `separate`. * With `border-collapse: separate`, the spacing between cells is the largest of `border-spacing` times two and the cell width. * `border-*-width` is interpreted as a binary value: a width of 0 results in no border, while any other width results in a border of a single type. If the width is smaller than one cell (in the respective direction), the rest is subtracted from the margin (if there is any margin). * `box-sizing: border-box` actually sets the padding box size, so that borders rounded up to the cell size do not accidentally take all space from the actual content. (That in turn would cause problems if a child box set `overflow: hidden`, etc.) ## See also [**cha**](cha.md)(1) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/hacking.md������������������������������������������������������������������������0000664�0000000�0000000�00000026021�15202323131�0015626�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Hacking Some notes on modifying Chawan's code. ## Style Refer to the [NEP1](https://nim-lang.org/docs/nep1.html) for the basics. Also, try to keep the style of existing code. In particular, style of vendored libraries should not be changed unless upstream is dead. ### Casing Everything is camelCase. Enums are camelCase too, but the first part is an abbreviation of the type name. e.g. members of `SomeEnum` start with `se`. Exceptions: * Types/constants use PascalCase. enums in cssvalues use PascalCase too, to avoid name collisions. * We keep style of external C libraries, which is often snake_case. * Chame is stuck with `SCREAMING_SNAKE_CASE` for its enums. This is unfortunate, but does not warrant an API breakage. Rationale: consistency. ### Wrapping 80 chars per line. Exceptions: URL comments. Rationale: makes it easier to edit in vi. ### Spacing No blank lines inside procedures (and other code blocks). A single blank line separates two procs, type defs, etc. If your proc doesn't fit on two 24-line screens, split it up into more procs instead of inserting blank lines. Exceptions: occasionally a proc will get larger than two screens, and that's ok, but try to avoid it. Rationale: makes it easier to edit in vi. ### Param separation Semicolons, not commas. e.g. ```nim # Good proc foo(p1: int; p2, p3: string; p4 = true) # Bad proc bar(p1: int, p2, p3: string, p4 = true) ``` Rationale: makes it easier to edit in vi. ### Naming Prefer short names. Don't copy verbose naming from the standard. Rationale: we aren't a fruit company. ### Comments Comment what is not obvious, don't comment what is obvious. Whether something is obvious or not is left to your judgment. Don't paste standard prose into the code unless you're making a point. If you do, abridge the prose. Rationale: common sense, copyright. ### C style Note that most C code included in this repository is from vendored external libraries like QuickJS; following points only apply to code we own, such as chaseccomp. * 80 spaces per line. Indent with 4 spaces (not mixed with tabs). * Local variable declarations come before their use (a la C89). The two sections have a blank line inbetween. * Braces go on the same line as the statement, except for functions where they go on the next line. * `if`, `for`, etc. must have braces unless each part fits on a single line. * Boolean operators (`||` etc.) belong on the same line as the left-hand expression. ### JavaScript style Similar to C style. * 80 spaces per line. Indent with 4 spaces (not mixed with tabs). * Prefer `const`/`let` to `var`. * Braces go on the same line as the statement or function. * `if`, `for`, etc. must have braces unless each part fits on a single line. * Boolean operators (`||` etc.) belong on the same line as the left-hand expression. Note: although QJS has an optimizer, compared to that of a static language it is very limited. Some ugliness is acceptable if it results in more efficient code. ## Features to avoid List of Nim features/patterns that sound like a good idea but aren't, for non-obvious reasons. ### Exceptions Avoid at all costs. If a standard library procedure throws, do not use it. Also avoid `try...finally` (even without `catch`). For own procs, use Result/Opt instead. For large objects this may result in excessive copying; to avoid inefficient code, either make them `ref` or use manual RVO: ```nim proc blah(input: int; output: var BigObject): Opt[void] = if input < 0: return err() output = BigObject(...) ok() ``` In new modules, always specify: ```nim # This is an example module. # After any header comments, but before imports: {.push raises: [].} import ... # At the end of the file: {.pop.} # raises: [] ``` ### Implicit initialization Avoid. The correct way to create an object: ```nim let myObj = MyObject( param1: x, param2: y # if there's e.g. a param3 too, it's OK to leave it out and let it be # default initialized. ) ``` For primitive types, just set them to 0, "", etc. As a special case, implicit initialization is allowed for arrays: ```nim var buf1: array[1234, char] # when you need 0-initialization var buf2 {.noinit.}: array[1234, char] # when you don't need 0-initialization ``` Note that the second example is unsafe and doesn't work with GC'ed types, so don't use it unless you know what you're doing. ### `out` parameters `out` parameters crash the 1.6.14 compiler. Use `var` instead. ### Copying operations `substr` and `x[n..m]` copies. Try to use `toOpenArray` instead, which is a non-copying slice. (Obviously, you should use `substr` if you *need* to copy.) Note that `=` usually copies. If you're copying a large object a lot, you may want to set its type to `ref`. For `seq`/`string` you can also try using `move`, but be sure to check the generated code because often times it doesn't work in `refc`. Beware of `pairs` on sequences of objects; it copies. Use `mypairs` if you don't need mutation, `mpairs` if you do: ```nim proc foo(objs: openArray[SomeObj]) = for i, obj in objs: # Bad. this copies. obj's type is "SomeObj". obj.bar(i) # import utils/twtstr to use mypairs. for i, obj in objs.mypairs: # OK, doesn't copy. obj's type is "lent "SomeObj". obj.bar(i) for i, obj in objs.mpairs: # OK, doesn't copy. obj's type is "var SomeObj". obj.i = i ``` ### `func`, `.noSideEffect` These introduce function coloring for little to no benefit. Just use `proc` without `.noSideEffect`. ### Closures A closure is an anonymous `proc` that uses ("captures") variables in its wrapper `proc`. These introduce implicit GC'ed environments which are often wasteful, and combined with JS they are an easy way to produce memory leaks. To enforce this rule, `proc` variables or members always have a `nimcall` (or `cdecl`) pragma. The environment can be passed explicitly, e.g.: ```nim type FooCallback = proc(foo: Foo; opaque: RootRef) {.nimcall, raises: [].} Foo = ref object callback: FooCallback opaque: RootRef # add an explicit environment like this if needed ``` ## Fixing cyclic imports In Nim, you can't have circular dependencies between modules. This gets unwieldy as the HTML/DOM/etc. specs are a huge cyclic OOP mess. The preferred workaround is global function pointer variables: ```nim # Forward declaration hack var forwardDeclImpl*: proc(window: Window; x, y: int) {.nimcall, raises: [].} # in the other module: forwardDeclImpl = proc(window: Window; x, y: int) = # [...] ``` Don't forget to make it `.nimcall`, and to comment "Forward declaration hack" above. (Hopefully we can remove these once Nim supports cyclic module dependencies.) ## Debugging Note: following text assumes you are compiling in debug mode, i.e. `make TARGET=debug`. ### The universal debugger "eprint x, y" prints x, y to stderr, space separated. Normally you can view what you printed through the M-c M-c (escape + c twice) console. Except when you're printing from the pager, then do `cha [...] 2>a` and check the "a" file. Sometimes, printing to the console triggers a self-feeding loop of printing to the console. To avoid this, disable the console buffer: `cha [...] -o start.console-buffer=false 2>a`. Then check the "a" file. You can also inspect open buffers from the console. Note that you must run these *before* switching to the console buffer (i.e. before the second M-c), or it will show info about the console buffer. * `pager.process`: the current buffer's PID. * `pager.cacheFile`: the current buffer's cache file. * `pager.cacheId`: the cache ID of said file. Open the `cache:id` URL to view the file. ### gdb gdb should work fine too. You can attach it to buffers by putting a long sleep call in runBuffer, then retrieving the PID as described above. Note that this will upset seccomp, so you should compile with `make TARGET=debug DANGER_DISABLE_SANDBOX=1`. ### Debugging layout bugs One possible workflow: * Save page from your favorite graphical browser. * Binary search the HTML by deleting half of the file at each step. Be careful to not remove any stylesheet LINK or STYLE tags. * Binary search the CSS using the same method. You can format it using the graphical browser's developer tools. The `-o start.console-buffer=false` trick (see above) is especially useful when debugging a flow layout path that the console buffer also needs. Don't forget to add a test case after the fix: ```sh $ ./test/layout/add test/layout/my-test-case.html ``` ### Sandbox violations You got a syscall number (assuming you're on Linux); look it up in the Linux syscall table for your architecture. To get more context on what happened, you can run `strace -f ./cha -o start.console-buffer=false [...] 2>a`, trigger the crash, then search for the last occurrence of "--- SIGSYS". Then search backwards on the PID to see the last syscalls. (*strace* also shows the syscall name, so it may be easier to check like that than looking it up in the syscall table.) ## Resources You may find these links useful. ### Chawan Of particular interest in the documentation are: * The [architecture](architecture.md) document. * The Monoucha [manual](../lib/monoucha0/doc/manual.md), for JS-related documentation. ### WHATWG * HTML: <https://html.spec.whatwg.org/multipage/>. Includes everything and then some more. * DOM: <https://dom.spec.whatwg.org/>. Includes events, basic node-related stuff, etc. * Encoding: <https://encoding.spec.whatwg.org/>. These algorithms are implemented in encoding. * URL: <https://url.spec.whatwg.org/>. For some incomprehensible reason, it's defined as an equally incomprehensible state machine. types/url implements this. * Fetch: <https://fetch.spec.whatwg.org/>. Networking stuff. Also see <https://xhr.spec.whatwg.org> for XMLHttpRequest. * Web IDL: <https://webidl.spec.whatwg.org/>. Relevant for Monoucha/JS bindings. Note that some of these are updated daily, such as the HTML standard. ### CSS standards * CSS 2.1: <https://www.w3.org/TR/CSS2/>. There's also an "Editor's Draft" 2.2 version: <https://drafts.csswg.org/css2/>, but so far I haven't encountered significant differences. Good news is that unlike WHATWG specs, this doesn't change daily. Bad news is that CSS 2.1 was the last real CSS version, and newer features are spread across a bunch of random documents with questionable status of stability: <https://www.w3.org/Style/CSS/specs.en.html>. ### Other standards It's unlikely that you will need these, but for completeness' sake: * TOML: <https://toml.io/en/v1.1.0>. config.toml's base language. * Mailcap: <https://www.rfc-editor.org/rfc/rfc1524>. * Cookies: <https://www.rfc-editor.org/rfc/rfc6265>. * EcmaScript: <https://tc39.es/ecma262/> is the latest draft. ### Nim docs * Manual: <https://nim-lang.org/docs/manual.html>. A detailed description of all language features. * Standard library docs: <https://nim-lang.org/docs/lib.html>. Everything found in the "std/" namespace. ### MDN <https://developer.mozilla.org/en-US/docs/Web> MDN is useful if you don't quite understand how a certain feature is supposed to work. It also has links to relevant standards in page footers. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/image.md��������������������������������������������������������������������������0000664�0000000�0000000�00000017760�15202323131�0015316�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- CHA-IMAGE 7 --> # Inline images On terminals that support images, Chawan is capable of displaying various image formats inline. ## Enabling images There are actually two switches for images in the config: * buffer.images: this enables downloading images, *even if they cannot be displayed*. This is the switch you typically need. * display.image-mode: sets the inline image display method. Defaults to "auto", but may also be set to "none", "sixel", or "kitty" manually. This switch is rarely useful. In general, you only have to set `buffer.images` to true: ```toml # in ~/.chawan/config.toml (or ~/.config/chawan/config.toml) [buffer] images = true ``` The `image-mode` switch is mainly useful if you want images to be fetched, but not displayed ("none" option). It may also help if "auto" fails to detect the terminal's image display capabilities; however, I am not aware of any terminal where this can happen. (If you find one, open a ticket.) ## Output formats Supported output formats are: * The DEC Sixel format * The Kitty terminal graphics protocol Support for other protocols (iTerm, MLTerm, etc.) is not planned. (To my knowledge, all image-capable terminals support at least one of the above two anyways.) Support for environment-specific hacks such as w3mimgdisplay, ueberzug, etc. is not planned. ### Sixel Sixel is the most widely supported image format. See <https://arewesixelyet.com> to find a terminal that supports it. Known quirks and implementation details: * XTerm needs extensive configuration for ideal sixel support. In particular, you will want to set the decGraphicsID, numColorRegisters, and maxGraphicSize attributes. See [**xterm**](man:xterm(1))(1) for details. * We assume private color registers are supported. On terminals where they aren't (e.g. SyncTERM or hardware terminals), colors will get messed up with multiple images on screen. * Zellij advertises Sixel support, but the feature is completely broken in the current version, so Chawan specifically disables images in Zellij by default. In particular: - Zellij itself does no Sixel detection, emitting Sixel data even on terminals that do not support it. (A fairly puzzling bug, given the developers seem to be aware of the DA1 feature.) - On terminals that support Sixel, it fails to position images correctly, with the misplaced images completely messing up layout. * We send XTSMGRAPHICS for retrieving the number of color registers; on failure, we fall back to 256. You can override color register count using the `display.sixel-colors` configuration value. * Normally, Sixel encoding runs in two passes. On slow computers, you can try setting `display.sixel-colors = 2`, which will skip the first pass (but will also display everything in monochrome). * Transparency *is* supported, but looks weird because we approximate an 8-bit alpha channel with Sixel's 1-bit alpha channel. Also, some terminals don't emulate it correctly - when in doubt, try XTerm (which does). * Terminal scroll (both with LF/RI and SU/SD) is used extensively to avoid sending images several times. Expect troubles on terminals that do not handle this correctly. (For example, tmux is known to destroy images on scroll, so we avoid using scroll there.) ### Kitty On terminals that support it, Kitty's protocol is preferred over Sixel. Its main benefit is that images do not have to be sent again every time a new slice of the image moves into the screen. Support for full RGBA without quantization is another benefit. Note: at the time of writing, tmux does not support the Kitty image protocol. While it is possible to hack Kitty images onto tmux nevertheless, this requires significant concessions in display capabilities compared to the regular Kitty protocol (or even Sixel). Therefore, support for this hack is not planned. ## Input formats Currently, the supported input formats are: * BMP, PNG, JPEG, GIF (through stb_image) * WebP (through JebP) * SVG (through NanoSVG) More formats may be added in the future, provided there exists a reasonably small implementation, preferably in the public domain. (I do not want to depend on external image decoding libraries, but something like stbi is OK to vendor.) ### Codec module system All image codec implementations are specified by the URL scheme "img-codec+name:", where "name" is the MIME subtype. e.g. for image/png, it is "img-codec+png:". (This indeed means that only "image" MIME types can be used.) Like all schemes, these are defined (and overridable) in the urimethodmap file, and are implemented as local CGI programs. These programs take an encoded image on stdin, and dump the decoded RGBA data to stdout - when encoding, vice versa. This means that it is possible for users to define image decoders for their preferred formats, or even override the built-in ones. (If you actually end up doing this for some reason, please send me a mail so I can add it to the bonus directory.) A codec can have one of, or both, "decode" and "encode" instructions; these are set in the path name. So "img-codec+png:decode" is called for decoding PNGs, and "img-codec+png:encode" for encoding them. Headers are used for transferring metadata (like image dimensions), both from the browser (input) and to the browser (output). Detailed description of the decoder & encoder interfaces follows. #### decoding When the path equals "decode", a codec CGI script must take a binary stream of an encoded image on its standard input and print the equivalent binary stream of big-endian 8-bit (per component) RGBA values to stdout. Input headers: * Cha-Image-Info-Only: 1 This tells the image decoder to only send image metadata (i.e. size). Technically, the decoder is free to fully decode the image, but this is a waste of resources; the browser will ignore any output received after headers. Output headers: * Cha-Image-Dimensions: {width}x{height} The size of the decoded image. e.g. for 123x456, 123 is width and 456 is height. #### encoding When the path equals "encode", a codec CGI script must take a binary stream of big-endian 8-bit (per component) RGBA values on its standard input and print the equivalent encoded image to its standard output. Input headers: * Cha-Image-Dimensions: {width}x{height} Specifies the dimensions of the input RGBA image. This means that {width} * {height} * 4 == {size of data received on stdin}. The format is the same as above; in fact, the design is such that you could directly pipe the output of decode to encode (and vice versa). * Cha-Image-Quality: {number} The requested encoding quality, ranging from 1 to 100 inclusive (i.e. 1..100). It is up to the encoder to interpret this number. (The stb_image JPEG encoder uses this.) Output headers: Currently, no output headers are defined for encoders. ### Skipping copies with mmap The naive implementation of the above system would have to copy the output at least twice when an image is resized. To skip these copies, stdin and/or stdout is (currently) a file in the tmp directory for: * decode stdin, when the image is already downloaded * decode stdout, always * encode stdin, always This makes it possible to [mmap](man:mmap(3)) stdin/stdout instead of streaming through them with [read](man:read(3)) and [write](man:write(3)). When doing this, mind the following: * When reading, you must check your initial position in the file with [lseek](man:lseek(3)). * When writing, your headers are part of the output. At the very least, you must place a newline at the file's beginning. * mmapping for write is slower than streaming the data with `write`. The only reason to mmap for write is to save memory when you can't stream the output. * This *is* an implementation detail, and might change at any time in the future (e.g. if we add a "no cache files" mode). Always check for S_ISREG to ensure that you are actually dealing with a file. (Use io/dynstream.nim's readLoopOrMmap and maybeMmapForSend to deal with this automatically.) ## See also [**cha**](cha.md)(1) [**cha-terminal**](terminal.md)(7) ����������������chawan-v0.4.0/doc/mailcap.md������������������������������������������������������������������������0000664�0000000�0000000�00000017367�15202323131�0015645�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- CHA-MAILCAP 5 --> # Mailcap By default, Chawan's buffers only handle HTML and plain text. The *mailcap* file can be used to view other file formats using external commands, or to convert them to HTML/plain text before displaying them in Chawan. Note that Chawan's default mime.types file only recognizes a few file extensions, which may result in your entries not being executed if your system lacks an /etc/mime.types file. Please consult [**cha-mime.types**](mime.types.md)(5) for details. For an exact description of the mailcap format, see [RFC 1524](https://www.rfc-editor.org/rfc/rfc1524). ## Search path The search path for mailcap files is set by the configuration variable `external.mailcap`. This matches the recommended path in the RFC: ``` $HOME/.mailcap:/etc/mailcap:/usr/etc/mailcap:/usr/local/etc/mailcap ``` By default, mailcap entries are only executed if the user types `r` (run) after the prompt. Other options are to view the file with `t` (text), or to save the file with `s`. If a capital letter is typed (e.g. shift + `R`), then a corresponding entry is appended to `external.auto-mailcap` (default: `~/.chawan/mailcap`, or `~/.config/chawan/mailcap` with XDG basedirs). `(T)ext` and `(S)ave` may also be used to append entries corresponding to the other display options. Entries in auto-mailcap are automatically executed, so it is recommended to add your Chawan-specific entries there (or just set it to your personal mailcap file). ## Format Chawan adheres to the format described in RFC 1524, with a few extensions. `text/html` and `text/plain` entries are ignored. ### Templating The command part of entries may include template strings which are substituted by the browser at execution. Templates do not have to be quoted; Chawan quotes them automatically. (This works with $(command substitutions) as well.) However, other software may misbehave on such templates, so it may be better to assign them to a variable first, e.g. ``` text/x-example; s=%s cat "$s"; copiousoutput ``` Following templates are supported: * `%s` expands to the path. Specifying `%s` forces download of the external resource *before* the entry is executed. If `%s` is not specified, the resource is instead piped to standard input. (In this case, `needsterminal` does not apply.) * `%t` expands to the content type. Named content type fields can also be specified with the syntax `%{charset}`. For example, in ``` text/html; charset=utf-8 ``` `%t` would expand to the above string, while `%{charset}` would expand to "utf-8". * Non-standard templates for the resource's original URL: `%u` (from Netscape) expands to the original URL of the resource, `%h` (from w3mmee) expands to the hostname without the port, `%H` expands to the hostname including the port, and `%?` (from w3mmee) expands to the query string including the question mark. (w3mmee did not actually include the question mark in `%?`. However, that design could not express the difference between the empty query string and the null query string, so it has been changed in Chawan.) ### Fields Following fields are recognized. * When the `test` named field is specified, the mailcap entry is only used if the test command returns 0. For example, you can restrict entries that require X11 as follows: ``` image; feh -; test=test -n "$DISPLAY" ``` Warning: `%s` does not work with `test`. `test` named fields with a `%s` template are skipped, and no data is piped into `test` commands. * `copiousoutput` makes Chawan redirect the output of the external command's output into a new buffer. If either `x-htmloutput` or `x-ansioutput` is defined too, then `copiousoutput` is ignored. * `needsterminal` hands over control of the terminal to the command while it is running. It does nothing if one of `copiousoutput`, `x-ansioutput`, `x-saveoutput` or `x-htmloutput` is specified. * `nametemplate` provides a specific template for the temporary file created when `%s` is specified. See the RFC for details. * `x-htmloutput` (from w3m) behaves the same as `copiousoutput`, but makes Chawan interpret the command's output as HTML. * `x-ansioutput` pipes the output through the "text/x-ansi" content type handler, so that ANSI colors, formatting, etc. are displayed correctly. * `x-saveoutput` prompts the user to save the entry's output in a file. * `x-needsstyle` forces CSS to be processed for the specific type, even if styling is disabled in the config. Only useful when combined with `x-htmloutput`. (Also see the `-cha-content-type` media query in [**cha-css**](css.md)(7).) * `x-needsimage` forces images to be displayed in `x-htmloutput`, even if images are disabled. * `x-type` (from w3mmee) specifies a MIME type substitution. The command part is interpreted as a MIME type (without template expansion) which is used instead of the original type. Such entries are only respected in `external.auto-mailcap`. Entries with `x-type` also match text/plain and text/html documents (which are normally excluded from mailcap). However, `x-type` does not apply if the content type was forced (e.g. using the `-T` flag). (Note: `x-type` is experimental. Future changes to its semantics are to be expected.) * `x-match` (from w3mmee) restricts the entry's URL to the specified regex. `x-nc-match` is the same, but it is case-insensitive. For example, `x-match=https?://example\.org/.*` restricts the entry to example.org (note the backslash.) When one of these fields is present together with `test`, the result is ANDed together. * `x-netpath` (from w3mmee) restricts the entry to URIs that match the `net_path` production of RFC 2396. In other words, the URI must have an authority (hostname etc.), so e.g. `example://blah/path` is matched, while `example:/path` isn't. For schemes other than `file`, two slashes after the colon signify a `net_path`. `file:///path` is a special case: it looks like a `net_path`, but it isn't one. (This is inherited from the WHATWG URL standard.) ## Examples To automatically execute these entries, place them in `~/.chawan/mailcap` (or `~/.config/chawan/mailcap` if you use XDG basedirs). Alternatively, if you already have a mailcap file to share with other programs, you can set `external.auto-mailcap` to `~/.mailcap`. ``` # Note: these examples require an entry in mime.types that sets e.g. md as # the markdown content type. # Handle markdown files using pandoc. text/markdown; pandoc - -f markdown -t html -o -; x-htmloutput # Show syntax highlighting for JavaScript source files using bat. text/javascript; bat -f -l es6 --file-name %u -; x-ansioutput # Play music using mpv, and hand over control of the terminal until mpv exits. audio/*; mpv -; needsterminal # Play videos using mpv in the background, redirecting its standard output # and standard error to /dev/null. video/*; mpv - # Open docx files using LibreOffice Writer. application/vnd.openxmlformats-officedocument.wordprocessingml.document; lowriter %s # Display manpages using pandoc. (Make sure the mime type matches the one # set in your mime.types file for extensions .1, .2, .3, ...) application/x-troff-man; pandoc - -f man -t html -o -; x-htmloutput # epub -> HTML using pandoc. (Again, don't forget to adjust mime.types.) # We set http_proxy to keep it from downloading whatever through http/s. application/epub+zip; http_proxy=localhost:0 pandoc - -f epub \ --embed-resources --standalone; x-htmloutput # Hex viewer. Usage: alias chadump='cha -Ttext/x-hexdump' # (Uses GNU-specific flags, adjust as needed on other systems.) text/x-hexdump; od -w12 -A x -t x1z -v; copiousoutput # Following entry will be ignored, as text/html is supported natively by Chawan. text/html; cha -dT text/html -I %{charset}; copiousoutput ``` ## See also [**cha**](cha.md)(1) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/mancha.1��������������������������������������������������������������������������0000664�0000000�0000000�00000004117�15202323131�0015213�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" Automatically generated by Pandoc 3.9.0.2 .\" .TH "MANCHA" "1" .SH NAME mancha \- view manual pages via cha(1) .SH SYNOPSIS \f[B]mancha\f[R] [\f[B]\-M\f[R] \f[I]path\f[R]] [\f[I]section\f[R]] \f[I]name\f[R] .PD 0 .P .PD \f[B]mancha\f[R] [\f[B]\-M\f[R] \f[I]path\f[R]] [\f[I]section\f[R]] \f[B]\-k\f[R] \f[I]keyword\f[R] .PD 0 .P .PD \f[B]mancha\f[R] \f[B]\-l\f[R] \f[I]file\f[R] .SH DESCRIPTION \f[B]mancha\f[R] enables viewing man pages using the Chawan browser. It is analogous to the \f[B]w3mman\f[R](1) utility. .PP \f[B]mancha\f[R] executes \f[B]cha\f[R](1) with the appropriate \f[I]man:\f[R], \f[I]man\-k:\f[R] or \f[I]man\-l:\f[R] URLs. The protocol adapter then opens the man page and injects markup into it, e.g.\ man page references are converted into \f[I]man:\f[R] links. .SH OPTIONS Command line options are: .TP \f[B]\-M\f[R] \f[I]path\f[R] Set \f[I]path\f[R] as the MANPATH environment variable. See \f[B]man\f[R](1) for details of how this is interpreted. .TP \f[B]\-k\f[R] \f[I]keyword\f[R] Use \f[I]keyword\f[R] for keyword\-based man page search. .TP \f[B]\-l\f[R] \f[I]file\f[R] Open the specified local \f[I]file\f[R] as a man page. .SH ENVIRONMENT Following environment variables are used: .TP \f[B]MANCHA_CHA\f[R] If set, the contents of the variable are used instead of \f[I]cha\f[R]. (Note that the \f[I]cha\f[R] command is called through \f[B]system\f[R](3), so you do not have to override it so long as \f[I]cha\f[R] is found in your \f[B]PATH\f[R].) .TP \f[B]MANCHA_MAN\f[R] If set, the contents of the variable are used instead of \f[I]/usr/bin/man\f[R]. .TP \f[B]MANCHA_APROPOS\f[R] If set, the contents of the variable are used instead of \f[I]/usr/bin/man\f[R]. .RS .PP (This is not a typo; normally (except on FreeBSD), \f[B]mancha\f[R] assumes that \f[B]man\f[R](1) is compatible with \f[B]apropos\f[R](1) and accepts the \f[I]\-s\f[R] parameter. Overriding \f[B]MANCHA_MAN\f[R] therefore also overrides the command used for \f[B]man\-k\f[R], so long as \f[B]MANCHA_APROPOS\f[R] is not set.) .RE .SH SEE ALSO \f[B]man\f[R](1), \f[B]cha\f[R](1), \f[B]cha\-cgi\f[R](5), \f[B]w3mman\f[R](1) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/mancha.md�������������������������������������������������������������������������0000664�0000000�0000000�00000003230�15202323131�0015446�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- MANCHA 1 --> # NAME mancha - view manual pages via cha(1) # SYNOPSIS **mancha** \[**-M** *path*\] \[*section*\] *name*\ **mancha** \[**-M** *path*\] \[*section*\] **-k** *keyword*\ **mancha** **-l** *file* # DESCRIPTION **mancha** enables viewing man pages using the Chawan browser. It is analogous to the **w3mman**(1) utility. **mancha** executes **cha**(1) with the appropriate *man:*, *man-k:* or *man-l:* URLs. The protocol adapter then opens the man page and injects markup into it, e.g. man page references are converted into *man:* links. # OPTIONS Command line options are: **-M** *path* : Set *path* as the MANPATH environment variable. See **man**(1) for details of how this is interpreted. **-k** *keyword* : Use *keyword* for keyword-based man page search. **-l** *file* : Open the specified local *file* as a man page. # ENVIRONMENT Following environment variables are used: **MANCHA_CHA** : If set, the contents of the variable are used instead of *cha*. (Note that the *cha* command is called through **system**(3), so you do not have to override it so long as *cha* is found in your **PATH**.) **MANCHA_MAN** : If set, the contents of the variable are used instead of */usr/bin/man*. **MANCHA_APROPOS** : If set, the contents of the variable are used instead of */usr/bin/man*. (This is not a typo; normally (except on FreeBSD), **mancha** assumes that **man**(1) is compatible with **apropos**(1) and accepts the *-s* parameter. Overriding **MANCHA_MAN** therefore also overrides the command used for **man-k**, so long as **MANCHA_APROPOS** is not set.) # SEE ALSO **man**(1), **cha**(1), **cha-cgi**(5), **w3mman**(1) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/mime.types.md���������������������������������������������������������������������0000664�0000000�0000000�00000003042�15202323131�0016312�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- CHA-MIME.TYPES 5 --> # mime.types Chawan uses the mime.types file to map file extensions to MIME types (also known as `Content-Type`). MIME types in turn are used by mailcap to decide how to present a certain file to the user (display as text, use external viewer, save, etc.) See [**cha-mailcap**](mailcap.md)(5) for details of how that works. ## Search path Chawan parses all mime.types files defined in `external.mime-types`. When no mime.types file is found, the built-in MIME type associations are used. The default search path for mime.types files is: ``` $HOME/.mime.types:/etc/mime.types:/usr/etc/mime.types:/usr/local/etc/mime.types ``` ## Format The mime.types file is a list of whitespace-separated columns. The first column represents the mime type, all following columns are file extensions. Lines starting with a hash character (#) are recognized as comments, and are ignored. Example: ``` # comment application/x-example exmpl ex ``` This mime.types file would register the file extensions "exmpl" and "ex" to be recognized as the mime type `application/x-example`. ## Note Chawan only uses mime.types files for finding mailcap entries; buffers use an internal mime.types file for content type detection instead. The default mime.types file only includes file formats that buffers can handle, which is rather limited (at the time of writing, 7 file formats). Therefore it is highly recommended to configure at least one external mime.types file if you use mailcap. ## See also [**cha**](cha.md)(1) [**cha-mailcap**](mailcap.md)(5) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/protocols.md����������������������������������������������������������������������0000664�0000000�0000000�00000025120�15202323131�0016245�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- CHA-PROTOCOLS 7 --> # Protocols Chawan supports downloading resources from various protocols: HTTP, FTP, SFTP, Gopher, Gemini, Spartan, and Finger. Details on these protocols, and information on how users can add support to their preferred protocols is outlined in this document. You can find network adapters in the source distribution's `adapter/protocol` directory. For protocol-specific file formats (like gemtext or gopher directories) you will also find an appropriate HTML converter in `adapter/format` - note that these are ultimately compiled into a single `tohtml` program that dispatches based on its `argv[0]`. <!-- MANOFF --> **Table of contents** * [OpenSSL-based adapters](#openssl-based-adapters) - [HTTP](#http) - [SFTP](#sftp) - [Gemini](#gemini) * [FTP](#ftp) * [Shell-based adapters](#shell-based-adapters) - [Gopher](#gopher) - [Finger](#finger) - [Spartan](#spartan) * [Local schemes: file:, man:](#local-schemes-file-man) * [Internal schemes: cgi-bin:, stream:, cache:, data:, about:](#internal-schemes-cgi-bin-stream-cache-data-about) * [Custom protocols](#custom-protocols) <!-- MANON --> ## OpenSSL-based adapters The HTTP(S), SFTP, and Gemini modules all depend on OpenSSL. This is a huge library, and linking it separately with each adapter would result in enormous code bloat in static builds. Therefore, these modules are compiled into a single binary. The entry point can be found at `adapter/protocol/ssl.nim`. ### HTTP The HTTP(S) adapter supports HTTP/1.1 with arbitrary headers and POST data, is able to use passed userinfo data (Basic authentication), and returns all headers and response body it receives without exception. Deflate decompression with gzip and zlib headers is supported. (Accept-Encoding: gzip, deflate.) This is based on a modified version of the public domain tinfl.h decompressor by Rich Geldreich. Brotli decompression (Accept-Encoding: br) is supported using the decoder provided by the reference implementation. The `bonus` directory contains two alternative HTTP clients: * curlhttp; this is the old HTTP client based on libcurl. It can be built using curl-impersonate; see [README.md](../bonus/README.md) in the bonus/ directory for details. * libfetch-http: based on FreeBSD libfetch. It is mostly a proof of concept, as FreeBSD libfetch HTTP support is very limited; in particular, it does not support arbitrary HTTP headers, so e.g. cookies will not work. ### SFTP The SFTP adapter wraps libssh2. It works for me, but YMMV. A slight usability issue is that if an IdentityFile declaration is found in your ssh config, it will prompt for the identity file password, but there is no way to tell whether it is really asking for that (or just regular password auth). Also, settings covered by the Match field are ignored. The adapter does not have a way to register new known hosts, so you have to first connect to new hosts with the regular `sftp` command before opening them in Chawan. ### Gemini Currently, the Gemini adapter does not support sites that require private key authentication. Otherwise, it should work OK. gmi2html is its companion program to convert the `text/gemini` file format to HTML. ## FTP Chawan supports FTP passive mode browsing and downloads. Directory listings return the `text/x-dirlist` content type, which is parsed by `dirlist2html` (and also used by the `file:` handler). This assumes UNIX output style, and will probably break horribly on receiving anything else. ## Shell-based adapters Following protocols are simple enough to have adapters implemented as shell scripts. As such, they are good starting points for understanding Chawan's protocol adapter system. To open TCP connections in a portable manner, these scripts use a very limited `nc` clone installed in `$CHA_LIBEXEC_DIR`. ### Gopher Support for the Gopher protocol is implemented as a shell script, using the `nc` tool in the libexec directory (a very limited netcat clone). Gopher directories are returned with the `text/gopher` type, and gopher2html takes care of converting this to HTML. Gopher selector types are converted to MIME types when possible; however, this is very limited, as most of them (like `s` sound, or `I` image) cannot be unambiguously converted without some other sniffing method. Chawan will fall back to extension-based detection in these cases, and in the worst case may end up with `application/octet-stream`. ### Finger Finger is supported through the `finger` shell script, using the same `nc` clone as Gopher. It is probably the simplest protocol of all. The URL scheme is a simplified imitation of the one accepted by Lynx. ### Spartan Spartan is a protocol similar to Gemini, but without TLS. It is supported through the `spartan` shell script, and like Finger, it uses Chawan's `nc` to make requests. Spartan has the very strange property of extending gemtext with a protocol-specific line type. This is implemented as a sed filter for gemtext outputs in the CGI script (in other words, no modification to gmi2html was done to support this). ## Local schemes: file:, man: While these are not necessarily *protocols*, they are implemented similarly to the protocols listed above (and thus can also be replaced, if the user wishes; see below). `file:` loads a file from the local filesystem. In case of directories, it shows the directory listing using `dirlist2html` like FTP. `man:`, `man-k:` and `man-l:` are wrappers around the commands `man`, `man -k` and `man -l`. These look up man pages using `/usr/bin/man` and turn on-page references into links. A wrapper command `mancha` also exists; this has an interface similar to `man`. (This used to be based on w3mman2html.cgi, but it has been rewritten as a standalone Nim program.) ## Internal schemes: cgi-bin:, stream:, cache:, data:, about: Five internal protocols exist: `cgi-bin:`, `stream:`, `cache:`, `data:` and `about:`. These are the basic building blocks for the implementation of every protocol mentioned above; for this reason, these can *not* be replaced, and are implemented in the main browser binary. `cgi-bin:` executes a local CGI script. This scheme is used for the actual implementation of the non-internal protocols mentioned above. Local CGI scripts can also be used to implement wrappers of other programs inside Chawan (e.g. dictionaries). `stream:` is used for streams returned by external programs. It differs from `cgi-bin:` in that it does not cooperate with the external process, and that the loader does not keep track of where the stream originally comes from. Therefore it is suitable for reading in the output of mailcap entries, or for turning stdin into a URL. It is not possible to reload `stream:` URLs. To support rewinding and "view source", the output of `stream:`'s is stored in a cache file until the buffer is discarded. `cache:` is not something an end user would normally see; it's used for rewinding or re-interpreting streams already downloaded. Caching works differently than in most other browsers; files are deterministically loaded from the cache upon certain actions, and from the network upon others, but neither is used as a fallback to the other. `data:` decodes a data URL as defined in RFC 2397. This used to be a CGI module, but has been moved back into the loader process because these URLs can get so long that they no longer fit into the environment. `about:` is inside the loader to allow for an implementation of the download list panel. It should be turned into a CGI module once the loader gets RPC capabilities. The following about pages are available: `about:chawan`, `about:blank`, `about:license`, `about:downloads`. ## Custom protocols The `cha` binary itself does not know much about the protocols listed above; instead, it loads these through a combination of [local CGI](cgi.md), [urimethodmap](urimethodmap.md), and if conversion to HTML or plain text is necessary, [mailcap](mailcap.md) (using x-htmloutput, x-ansioutput and copiousoutput). urimethodmap can also be used to override default handlers for the protocols listed above. This is similar to how w3m allows you to override the default directory listing display, but much more powerful; this way, any library or program that can retrieve and output text through a certain protocol can be combined with Chawan. For example, consider the urimethodmap definition of `finger`: ``` finger: cgi-bin:finger ``` This commands Chawan to load the `finger` CGI script, setting the `$MAPPED_URI_*` variables to the target URL's parts in the process. Then, finger uses these passed parts to construct an appropriate curl command that will retrieve the specified `finger:` URL; it prints the header 'Content-Type: text/plain' to the output, then an empty line, then the body of the retrieved resource. If an error is encountered, it prints a `Cha-Control` header with an error code and a specific error message instead. ### Adding a new protocol Here we will add a protocol called "cowsay", so that the URL cowsay:text prints the output of `cowsay text` after a second of waiting. Note: following assumes you put your `config.toml` in `~/.chawan`. If you are using XDG base directories (i.e. your `config.toml` is in `~/.config/chawan`), substitute `~/.chawan/cgi-bin` with `~/.config/chawan/cgi-bin`. `mkdir -p ~/.chawan/cgi-bin`, and create a CGI script in `~/.chawan/cgi-bin/cowsay.cgi`: ```sh #!/bin/sh # Signal to the browser that the connection has succeeded. After this, # Chawan will now "Downloading" instead of "Connecting". printf 'Cha-Control: Connected\n' sleep 1 # simulate a delay # Status is a special header that signals the equivalent HTTP status code. printf 'Status: 200\n' # HTTP OK # ControlDone is only useful if you want to send remotely received headers # (i.e. in an HTTP adapter). With ControlDone sent, subsequent Cha-Control # headers are not interpreted specially. printf 'Cha-Control: ControlDone\n' # As in HTTP, send an empty line before the body. printf '\n' # Print the body. We take the path passed to the URL, which urimethodmap # sets as MAPPED_URI_PATH. This is URI-encoded, so we also run the urldec # utility on it. printf '%s\n' "$MAPPED_URI_PATH" | "$CHA_LIBEXEC_DIR"/urldec | cowsay ``` Don't forget to set the executable bit, e.g. ```sh chmod +x ~/.config/chawan/cgi-bin/cowsay.cgi ``` Finally, create a ".urimethodmap" file in your `$HOME` directory, with the following content: ``` cowsay: /cgi-bin/cowsay.cgi ``` Now try `cha cowsay:Hello,%20world.`. If you did everything correctly, it should wait one second, then print a cow saying "Hello, world.". ## See also [**cha**](cha.md)(1), [**cha-cgi**](cgi.md)(5), [**cha-urimethodmap**](urimethodmap.md)(5), [**cha-mailcap**](mailcap.md)(5) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/showcase.png����������������������������������������������������������������������0000664�0000000�0000000�00000060717�15202323131�0016234�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR��{�������}iCCPicc��(}=H@_SE*"VuP.*XP VhIC(X:8* N.RB L5;bYF:1 Џ1JgS$<=||,sn%o2'ǘnXӛy8JB|N<n.ƹ3F&=G&m,1+*qDQ5.+8*kޓ0זNs ,`)QʰU#DAǟ"L 0ṛݚ 7):_lcmv?WZ_3ZZ.[\�OdH) }SVޚ8}�2U88F`{oi^r9G$��OPLTE���!%)NRU59<cfi=AD.14UY]CFJSVZ􋌍[^aqstikl135:=Az|}{~269%),bdejnqEJM*.1eiluy|mqtJNR~STV赸9<=֢BDF]adZ[]svy;zH-Li<~HD0Vy=G/Ss$/:I*CY)He>A5gEJLN"$&*,-^dhҦfkpnsxOTX6k'9J3b)>S':K2](2;7o!%GLQ>DHW\a6;@9tA@C9u#,3&5C!+j79$Q~!,680y.B!Js*;4L0|,n)a&\)^.s3$8)f9U7Q#Nz2 Bf0F!Fk%364#Hp/w(_%S=\&X?`2@b-p/y)1Y}.Po$) uz '6@^+h3n<3���bKGD�H��� pHYs����od���tIME('cJ��[iTXtXML:com.adobe.xmp�����<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 4.4.0-Exiv2"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:GIMP="http://www.gimp.org/xmp/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:tiff="http://ns.adobe.com/tiff/1.0/" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmpMM:DocumentID="gimp:docid:gimp:49834114-dcb8-41e2-b76e-d6b8fb09680e" xmpMM:InstanceID="xmp.iid:2351f40a-3c53-4507-a57e-eb2eee3ce6e5" xmpMM:OriginalDocumentID="xmp.did:87b156ef-d464-48d9-ab28-05557a24a2a3" GIMP:API="2.0" GIMP:Platform="Linux" GIMP:TimeStamp="1724794839562296" GIMP:Version="2.10.38" dc:Format="image/png" tiff:Orientation="1" xmp:CreatorTool="GIMP 2.10" xmp:MetadataDate="2024:08:27T23:40:39+02:00" xmp:ModifyDate="2024:08:27T23:40:39+02:00"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="saved" stEvt:changed="/" stEvt:instanceID="xmp.iid:eb0f2ce1-fdca-4ab4-8fb0-96ceb52c832b" stEvt:softwareAgent="Gimp 2.10 (Linux)" stEvt:when="2024-08-27T23:39:20+02:00"/> <rdf:li stEvt:action="saved" stEvt:changed="/" stEvt:instanceID="xmp.iid:06f75282-d810-4569-b7d3-3ec5dd22edf3" stEvt:softwareAgent="Gimp 2.10 (Linux)" stEvt:when="2024-08-27T23:40:39+02:00"/> </rdf:Seq> </xmpMM:History> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="w"?>/u��OIDATx흍CG<TyLl!Q 1¨CU|"&j~^M4Ga ZXx=m{,|~of<@@wm~fvvf^$k$(Z@@ÞT z%_t=,QcRkM#ܴY@S@ 2D˓Uig=C1DJ+}!9UT\d/Rkz XEt}^Y.2ͅvZNFKJK2Y_QjS+ٶ nQ I5u8BJF)yR_ˣ{mQ4<]mE*UUz|R}d2~ ֤h0Ǵ@n&PF|9%.JKG Ehꂱ@JfU*AF Ş$ 7a|܂mTFo$쵑Y1xO"isZ(A. )WT[ZVa_M8۴s6%7Z>$ M49{&{C rM=@J=¤,E쵈{a&S\ i@8{{fQ O@ #8dV.꾝oPTD̞s*ME)}14 +sJ0{תD-<H`@ -vF#<luak^Eob̵ q*:YEt?cj]gh97qMv^{ wjB %ȥ#"4ux)6<|@u]/9R)6jIU<D"#1= ֡+%5f^6…tR"M7^ J\nhJW'w_=*}^^ '@/G؃"�=@@ `@ { =@@ `@ { =C(h `{{?{[f'`oocpe۶xa,{ߚ?o�{ّ|!)xӂ&ĊM0{yo/ue[N4^${][wًvkߞuA:tx#!>6ȡ#J[L|RY3V:۫_gm2c2ߘ[yRe"rZJc[+k|XؘiWeCn(-yMjpg`:q=ןN־ \TܒzxxIў_{ 4Xc>?m2a$V$A {u{_%=wC^~z><wvǢ Ǿk6OW[Gk=:-U>hqfJBuT^!{]\"fOҚ#1GPe1 nJwGˇ֫"CznΕBV)O駧Q읨ǟc{ 59QX 򚰗ӕ6mFv ᴛL܄p1-7qQa[}r4%^أls/aG.b>a/ LNg%܁ƵNo}b&JLٍ!b%dȞE Q+Oa$%ab>e8>howq6mSܝA(VFm>roK`r9&a#Ʋ'ܲgSÉ{_%=jу~{t~1{dǾI;pH__QvBϖ4gZ)?rJw^wDl2bO\9c!ԖԊLe!*s9ޓq|i2(Q{Xww 'ԸMU#8u_5<Áacol;u u~W(1{ßq_b?U!f\ ʽ6Cz9EVtFB"6]9cz~%1.V9,Nwp|=ީx/lR5Dbc-ֵiw"MD),Gw1`Ƚ/x'{x&g g]丢,ud,',f E! dK%@dC'I^PҊ>I{rI?yN6F> X bޖGs4{'f/k,ϩPsRwwD.͵|0b[.qYʮ0{\HdeS*R)0s=:J0j ;JLztK)!{(?KCktNVO8Ds-'Oɩ(؉m+ZXq&*+2Uu {Ƣܡs͵4os6lB/E1l1>G\sABP>Ek W2s~Q0i:% Y{]f~>n6?*7]r;OzL6iwNً1Ԭtz8ւسj fDĽ"G #[i[9bE#^cO#K�{+/mf7gKXʾ)V mϞs)-=Iu{Є+ْV({ԉ3rh«*>'@%`@!`@ `57C!@bVғeMT3mP P앨TFJ勰P.0tʺ5Uo@ق@iUF{CbVu^Zרŭ3"JSgȇ!_o!ٽa@H'v>1űWٔ*#_T֊ci4{\F) 5f.āA `/.%z=G[]m쑟MQ=Qveoj!U 7Z39QӘm"#@^<{V붬E'%M̞U$~d_!Eȥj_+-n#ɿ;H` qciٔ=Q+MN7s-,{=1v'b(}bڈsۂtcޟXԘ" | |~>'ycf t=6wk hGe.jVWc?!fY^x)‰k1JԦ/AHQס*t=9okȠbض۹55b8sgt!*n6a>`Gf{ =@c`2@@ `@ { =@@ `@ { =!{w t@ `=c/4卯;A^B\SQdd.+(K$gU1XTiTZ\pfX%V:%?Mz [C#wr4|wcwսT'M);had%;ecO|dSd-y'- $EFJ񵜜oI~6Ra 떍]+N&72<xs `nލ>t эY`/ǝːt,{K'SwptH:{ɀЍI� ]FFGc?|w7߿!wh +/>,,2gcK 6O%hfXҋK~<v'liZHխ4n7¨ z}2-_#7܎`,d#r1to[Dd#6 :c,B*'r*S_am#՗HVtQۈTSTlI qU MT*/f.dCr#ƉD6{c7ׯ~ޅ?>uir4- #xgdp/o'TRVTI*@+i͑2*Qh>U_mb@+SDDLjͻ;ij@GQ[jI*69Vd[ȳX3!\==!?BtXٳ %d#.ҩWFYtѤUWBp0x b~7GDHG% %UPM©%kEBbY]rD̞P)J#cm|; >؍OܺG &qFY>iWN5)I Q+L=T4(iE%)D\UÅE>pW@oMĞ4.QEƱxD'XxUQ%d#=Qq鼍{TEM*Qq !_=Wm`l}E=DZ׆_&QU $k? ZKHH\"-E'ffK5cm׍bٿ4~'_({plf- ip#Z7O7r;E Yd[B6dz'G. Q'.(! O5FYtѤUǞ" >'/gQm#cKTɇR6QU ğo? ZKHH\,^̞P))!nQu$oc1 jk(79W㘙>g9^hH^8A^u8]9c؏r;aOnǑ<zxϏ]0W\T9r챇|6S_$;w*dޱy*%EuN^lK}oCQa#be؂{?l1>g8ֆUdXHzWH))P!"cv|N͆懏1x,.(!ًC|N]TE͎ɺC77m_+D%nIL"B">'*9k|XiXT)5ꎵIco߈ke|͵|32<IF<UHI[n01{r<\G͵ Q~))Ž>02.cYG ys#k!\ϱu  Bt2(DҩWv,h"s-\p ̵>yĎDm#c+RbkWZTp*$h B,ZX}W;R/A&^0ST (cm{݃cbԏ~x~:nG^c8fTڼf|5Ȼ7֛ubmV2k(!`o)Z(X/<lWEl ߲0 G1棳{ FH `ce1EMUPB08:GF &/#ǞTj/jm?ZB_>n+ �)nRBa2~ATqM"isV9$֕qiBNeC1K-`o5W쁖Ymz{ =@ `=b/:2PgKlppt ,f*K.e,wczll֊]DzmA-g=AO'?ԁ?F-g]/wj› ?CqzzQ?.ۈ|4~3;{lő}lL/oa~ ~=! >y3F)v< 3eO ɍGhưerC 6!Jf*)w(ފZ~dFؘac>h'_NGhRD#A-/G-߿{:44.(U읻=)q~Borgap=?55z<oEa2rZM>y7E[{>t7oLBg-VBmzh;lp&ldsQX߉l"RÊcjyk9}sh y=|gyje}lmOCIZYtC?@>VNY]-g-;3 }=9Óv"w`JJ0⼑Epc(J<{w/qH\D6JՊA-/G-/|cHG=46g.qƌ¹6]17SIC Kd+,;D6&K\u˧âZ6JՊJkZ^Z|!]h�x@frw?NBнg~ aW$ߡ$K}ї#IbMxDZ6Jl!yE1@-/}-/ Rx9^.b7JZ^Zӡ\tEo eU+ze r@{ { dc Te:ffy=IﶩWq˩gޫŞ)^޶33 U�{ye !ߦHԎ5'Zǹ-s֛5w""O8߼3սyK8}; 8p긇e&6|lEW~J.:5uvTrw 4f7P&Z\O|WpՑw WBZU#NFLjʫaSy%`g9h:%ן.%U)ԅ׬�T2׿@qM+bo37y|8NƻT&BǫMM۶tDvkWT"U\y:j1{'^ |6#F'jfm I}c{ֵ6�ulϴD\ u!boKr|N1=z){66)V DALNεDӺP;rGV{o)Y8\M' X:*uPG^]"ԩT咲O4$N^ j fQFSڍ} ZŻ_K*ZdqSyl'bOHAU.-{~vF*f˦{լMBhW{k ;7?OV3Ry]"<1:7uy=n>qM'ENy*\V4P5CP+\iY\aY[N`5r =@@ `@ { @{ { =@@ `{ ЫZN{ { {?^T#Gӷ뽐=j4~{�^zeQi}+}}tJ;|\9g/=ЊCuK{x̞e蹃[w_ݳ÷�{gKyqr>篗_ޏzg׾=/o߃[ѾGqQqtҏA@/neC.+_5 {8_)j\p�Vz?݇[ۉ}?.X4SW|~ܯS{ppЇGzw|/Dʅh ]#kCK[ G_`.E.ݮ/z͋\)GX}IC}}.ą`Y{9+gwvgC"Kԥ#c1w{=Eg_Xo/^w%a/= ceNsRY!Ǎ:�@+Ko9aO>G÷uxS.9w'9c`߯d+"�,](.lpQGݮgϝg'fxZW>xn/孱y{q䢗лc.hEh%l=̎^Gְ~H]죢|]!uo_8FȄQk =?ž瓯1PW{Ⱦ!=*׮s/Y@+tm;J{ =@@ee29BE(]2<?@E]"_UI V{ݯۭlfV_1MZ䓀n@1s|䯛+d嫇=;˙M@}x`r*iR[A[ߌ;n6ܭBYyEҡ,Euu$i Bn>_)*Oj>\xރ_ ٰ;ʺV6=c^)W}xư)=P{׻owヒ_VZNMAZl#PzU`+NFUo9FW̞2t Uv8 |:HpGO`Nc"{ 3hh'=P{ճnx�e[:{b&JLٍ!$ MJl;IjN>|]̞2f)r 'Q}C>|:q<{|6 âو؋O9. EO=Pyx/Gm>X6YNkuMD=z^%y hZpM̞25ykE(WOH:q<{|6t~--d<%m1{eb׻{ǹsϽ6Cz9EVtFBDm4Nt:q%`o]4{lP S:Z`8Z FM ً(kbbŲwuG_8j%n7 C90\( I^"t|m1(jap@kI=޵`F:$V9'.@bEȀUZOCEUrHRI !r}KSϬZֿbu2]!DՕ4B:)'YwF)K7צP.iNNC7p'><.9Ox2:JBaO0$Cծӿn#}~8V$o[�+ʷI=M7hEeryE#١`g2ݟ-(Pe�_J-lj=@@ `@ Вw(4mݾ$GJAEw܇_8 `Z${!ԗȣs_{ήo遽/= ^]ڷ:/bw߯,Bt؋f}}?֕Ow"O_'v6ṳ?&�=aBt؋f>'Y?-~ߥQOc/sw%߇8H@sON}R=t$x} w#}}p,Qb"A `O΅g9DZwS$vՏDE@^x/x,g"9wDzJH;)DTϵ\~eZ.o=(ks{?£ԕ]}>:L@^*04¹G5dE[c:xy{î]o=ʕ/veM!:쥩ҵܕpj9(m(S8{p[avʜý}:oU(lh!>'@ `{ =@@@ `{ =@@ `@ `{ = +3 @^R9 {9 e -@` ZL-ku 5P "أkL tFS 3bӀ*PVYJ,z(M`pU4iΗ١TAgPPtTZ0֭E] F}]@թ.G{iҵ*7u^ *pru^6Wج TK_qF:Fi\Z=RN+h^9AZiqwT<=U;ȮΆ_)TXXr^6`h0 -=FSc;v ;hhkT;S (̤)^NMڛ~+e&'ut0{y {RUj0g Mknˮ <*i.3֮</ZP!R'ïQ�Y T�|N(3D7 8a�Zv@ { =@@ `{ { hŰo\AE'[H,e@s]cBz]mʣ;dx~{%%??^{a[ ~-yy:ʑ[CU\kbTZ[vQUrqdګ#Is pzsEWncWu:2@Vw B9men'ܭfmB/29@uQ]#W;b)ttɢ*eM72@CT.w)G {&5sTpҢurZjUTfYqo9V uS[m:M9`0"qR{�G΋ek٘[VHYjፎn5!ei xUl v{Qy ^+`bwqZ!'#R>g#e4 2bw͎@A;ҮZe/@wlP `kiQةiuê6D{VSmRͱ)Lm2ѕ-I{]ZY).`0nU:i쁀=n&t:5ް+s:  O#. *5tTz eeJt^䖲z4MaVAZ45 ^)lv&.~].댋9 0_iRl1䦤P{%cB3FR =oA7@Ew\ c@jA8.wOW̍\Gh]zcvUruspء#Ǭ)U+%O̔JiJ>J;JUVr`UYA{.⮳[SW/^|뿩ozcj]R.mݵhhwد4WQ-eR|ae={@C^J^=H^:]ի[|W_| w{&g.c.P*\uMֹ=etZwe@H/P.n=ij#G)*ޮEͨsZnzu[n}T5S`E uT #4uE_twu0{vbC>&yṖ�ܴ&qMeR[Ղkq�{ |s-zAj;/=߿^s`}jŎ{e 2i TReu.hjT6\^#{c |ar~vnt,/|D8Ž[/݊O=ZY]Az4Fe7]ot(Z8C9M= =Wr/QZ;7wI4:2e~_9!Q ̣�R5J A J- mjRPL^ {tŷHj 9bb _p|Mfr,g\3Y3cBA' C]("P=q(a0Q͎ gҴ G—)xYOW){zuu5 ulj"]Y3!LjYW8ϊ4Y\c}/r:_YԚҎYZ6WrWNS zK*lYi%-&m <-fU.W1{�cjTcauzM"Ftم˝ņulBO>?`3 S=/<crJYp+c,Y3jynݬӋԩ+~fuWbV'{r9U9j^Fy{ ˞I+PE ͖4R қ[DM^u^ NBuS˴%[Or]v ,q8à줿u^v-\tR3H}@�B!lGB>vi!T^$K[L~f9{/k7J B.4 _&YcN.,!g/h̵,Tؑz)@ `@ }NQ:M@Ug x(*ӟ){ӧUlQ"v Pث?hz6L NZu}Ygtyn@֞ @YcOqͣgTt&'1{Z;ȫ|秵:z<@{3gtեhK {uTm#٣Fr:/A}vte=Ɓ{9?ݟ:\&m+!iê= e9So8{m`rTnO?Ae=ѪOJ;Ԋ;Ρs8Lnx{LxQ '>'@ `-/{ij&wGc)ѧI<;6/]P< J=9/d>}^ԃ4\ ?s/Ypl& JSd.N,@ `/55Vx.(ϻ<CؓwPӹUq'h3*aOU[K?: '՝ 4{j+hEbG ~[~&ž&3C9hs?=U;h4ai]@Y'JMu'4{gJ7(ֆ3E؛{{;Ni g@y {3aoÀJB4(ڣr@@gku5w=29bأ4=Ӿ>C@鱧 tk53T�g�S?ñp]E=b]p{1ugrᐽr9&]S}ŵɁU K}jzgzžU؃G8α %5nq7U*U ;=Ѡ}F<n!आjoN~F5|6cm)yA@w$a ryjA|( w}73.վnܛX":BXcW�;Ѳ(Mh#ZIA ВQDh=MM,)7T =k4=kr"}?yV^ק8rϜ9i)e+3;Lϙ r1{ӟ(o} G͵ky4S[[ - P|α Ŀ ^R33ڡ> jkϩѾo0{Ӎ,Q*^~}{;33 3Zb[i-lep73׬(3ok)7 gj8A{ƣiɝOs:TgN﫨IӟUFqs&{ Pأ QaÆ*y2J)@C6xh:<{ PأD^ci@l~hh%2,Zr1L8-f2 fo"`2wm QGG4"h5G*52r!dNu1^5vDi *z9&i1(C{&/W4%*^Bj/-F*˱r{KiR ttjlw\i !_Z1-#?I24VlqWibኑ ψJU҂=}|oC`I/[+zgZ5aO1;+(gAaS~4`+ki 䳕c3%B,Djhr:,j)-SD >-~n/W-}>廲FC7J*Y*w!jru:m])ʯKm2TL>o"7Q[D^lv}'siR߫x %bsbZCe2ss 4 =w]n)::{ViB[1iɩgRm?v;K;`>j#fi]V>{Ie0{91WVi=[ǜ@N28,+GꊠS[ufKjU9WhJ(tE2O~̸XK}`Lbˬ gτȊm*h+ss-ޢ: jpUP*i ?sW RTcfE- _rZf;WWkuxC?Q ,d+gRzf|W6{LGv_7B-�wA(erVʑQ[&XN  aIN5 Qcn#q{-LcهI2|O>_SZK}vKQdR>˸d K{yc9Ϸd|W?{K<K,wZW×<W"{!h~C=@@@ `{ =@ d/ @kX Jg^YAe㶗ОyUI !no@s2L7[an >JY 9B%%�y_8.[A+y_G(K%$gV+{wG~>')J7Ku`6^a![kd6oYYK󳅦`|0Ll;GFPN3gR7*4]/V]7zxzqo)f/#c WC(h||rgeS߳�!M`s ԕY:ʜłHWj:Tjt X+5&mG3[RYm舮P;_ZG::s\gs]{wt mK0Wb/{O};>{wd/w'M> =xۏGLǰԦB26L~?۪nթr9!rym҆"]m7UvXL1{*;(Ԗ{"sB.[q+q,IcEOf$ HYZW{y*4zxwN NW:>%91{zdqB [fe66I>sʰ{c |{,bE j?dT-Yn{z^YXR4T;VωiZSJ6l }Pf3ٚ9 ?LF O?A*9- ?4r?##ᡩq9=˲#b?c@2,>kesՕ5f]zuСnXsRպނ(!4+k;v*f3&ow5Pau&S(jnXl> D'_ѕVI{ *i$N-qL3*U8~1#fГBCOF~B=C_ {5K7*wpCnz)fOZAE~?R[W/G׃~[j y7Q~ZDU%̢~%P,ww&jsՅd1smrLLcr$n ܥ6tkM?uY~_1gChbt!= }58 3top|b+NgƒY) Ys j' 6˄YLSPYR97.Z5v-Jwdԍ4IR : R*�tپșO8a?0SqxJ?I_~ۓߏ<| yv{rzdIo?MN=izwrXLIAt5!y /Yw2)hqH`L8+ťMѡ!ʭr_ /p~a?ًmי9t0}&\Q|_|2Fy޽o |QObf{Q6ThɕaR. QMH)3 Ld3I줟, /?vLf.6yiֿҒL'~WAF@L>֓:SMͼ3ZrI?POEjdoHY*1ܝīSLQLLW'?b+3^]~`W:O!%<Iᄦ3Lo13N/V-{CPz?p*]1ݠA'~W%vLD(35=f`AӊQj40-ăL'}&xcϓŗߪemw982û wխs,|L,j n2bo'({{Qk=<׋G4*;nqbZI1w>LW26KhBΓ~ bbo~o^Oooc44yojn~wwb ݾw[aQia+(ThE҅٫$ϝ-p;vrtM5AdW:ޝ&WBnӧ#KWjݾ7^yx1&N 3? ~Lܛx&oM?l ݺ}ځ�j5U MUZ?1iϓ&mq)' S<0a@3_hƹ'=7>6tg|/B?|z]Ey҆Y dBU!m5R ҔYŨVXUe^96 {etO~}+?|G\̩{SOMLޞ~:>votjhѳg̳&kQG3X7 F3C3<wXKq^2~bOg[ M O=DOGOֳ;ì`8lFhCTek}\3X`TUߝ˗\;.[oS?ГǞ? ?$'ɕ'9}αp%<[޺;<>^L?G܅}[d6?eB6läjOgi'@i^7/v΅R>ڋ áчy L5qϏ[χyZYKUm)>g\3P.j , ViY?Qӑ+t{}; gltqWIOݾ; fpFpOLػ aӉon NNz2A܅nլ`nSr(ݹä5WK~+J[g*] =khrp ۧ7_IsUJT m@" rg}ZTf1*+b|wp_6v+l;pe<HVs= Mw9ֽLw 7߹cû{cU m߬6j7=f/uLpI.7QSLvOŗe{xw]F'vr M>03;ˤCTE9pW=&*u6U =4*5t+&,+0c}58u 31/|i #(q)09z4atSwo߽s |S4<>58Rd0P-2((TnHڷE} ؅c:8=_TFFB6s(ӓCӳɉ'=Г/^<xԹ] \^ [ (gy dؿSiBO T\oN<^yȕd\g=>7ykh-lgݓ鑡ۏݚ~24_ x Ձ֊ Y?BtG & b(4}.J^PU~pezッo}KAx|͊>"lZؐQW+[#a$X7hW.p>1I?͙)<2`.c# Y|EoUsًAޕ2Ӿr*4%+{+g>fwsWťoiD\mv{>{ {hAV+= hZ-@@=@.{> 8_ܮ֗HWz;\Sɷ"Z")C9S| <\#oH]ȫΔhV.jɚ֯Hl;b?T֬k=a\XYE)FJҠq7Ǣ^c0{qe0ZSZҲWd6[֘fe|6DÙӦdk9# ^ωx ׹CJ*HTe2IW{,kqS_ց=VfL+d YS.©YlSPeQkZr&_eSԮ)R3p5]g�#]c_[ùה؄,TpM^K7p{,73+KI$uD[ kxJK+Dp s'Ej\:˚|dcmnɅHp$8#q0ހ_o/cE9IR4-=5'զ%9sus|~$8?ҹn#u J`AC ׬alLl5(ź/k<m\qC.׬rJrJ$ I"*0mtNA@nJ.ˋ{kְ!k}}dm8?ĥ+#|͞V jm=q3K=%Ϲ9iR{0eaIJksmeHH&eh0ȱCJ$^r+jfm$8"B`ˤókЊ@d3H؛3p>@$6#bI)Y$nGxruQ8[c=^GqkLq|Ǝ }N̞B^E;BZ,{eHŞ])jrE:tр2:[U…(DtegIď?I4d,<{>'yc pq>Dg#7\%D!޸H*aZ({F)6s=Wp}�DIk 9d|m/awS--ѷ,q"){ a i ~3W_dعc1s-]6W3"zH~uEszNN8jyN"gv;%!$"8'uw As k�.e$ YcEK &m=ƫID!鰧/ ΕN6nm]bekܬɿY vac_^߸5H~6a> {EܷQ,([3E}N(mef-N_j.5A@@hIzlG u����IENDB`�������������������������������������������������chawan-v0.4.0/doc/terminal.md�����������������������������������������������������������������������0000664�0000000�0000000�00000012330�15202323131�0016033�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- CHA-TERMINAL 7 --> # Chawan terminal compatibility Chawan does not use termcap, terminfo, or ncurses; it relies solely on built-in terminal handling routines, mostly inspired by notcurses. ## XTerm compatibility In general, Chawan assumes an XTerm-compatible environment where XTerm means the current XTerm version as developed and maintained by Thomas E.\ Dickey. This means that Chawan is compatible with any given terminal if: * the terminal is actually compatible with XTerm, OR * the terminal isn't compatible with XTerm, but reports its capabilities via terminal queries correctly, OR * the terminal isn't compatible with XTerm, but its `TERM` value is hardcoded in Chawan. Terminals pretending to be XTerm (`TERM=xterm`) which are not actually XTerm might malfunction. (In practice, I have tested dozens of terminal emulators and haven't encountered any major issues; in all likelihood, yours will work too. If it doesn't, please [open a ticket](https://todo.sr.ht/~bptato/chawan).) ## Queries Queries are preferred to hardcoded terminal descriptions because they are forward-compatible. On startup, Chawan queries: * Whether the terminal has true color, with XTGETTCAP rgb. * The default background, foreground, and 16 ANSI(-ish) colors with `OSC 10 ; ? ST`, `OSC 11 ; ? ST`, and `OSC 4 ; {0..15} ; ? ST`. * `OSC 60 ST` and `OSC 61 allowWindowOps ST` for detecting OSC 52 support (see the *[Clipboard](#clipboard)* section). * Whether the terminal can use the Kitty image protocol, by sending a 1x1 Kitty image and listening for a response. * The number of Sixel color registers (`CSI ? 1 ; 1 ; 0 $`). * Primary device attributes (DA1). * Text area and cell size using `CSI 14 t` and `CSI 16 t`. (Cell size beats text area size as it is more reliable.) * Window size in cells by sending a CUP to 9999;9999 and then asking for CPR (the same trick is used by [**resize**](man:resize(1))(1)). Chawan processes responses to the above query in the same state machine as user input, so it works reasonably well on all terminals that at least emulate the most basic VT100 function (CPR). This unified state machine also minimizes the chance of user input being mistaken for a query response (or vice versa). Terminals that do not respond to CPR will freeze on quit - in this case, you must type `C-c` to forcibly kill the state machine. In practice, FreeBSD's **vt**(4) is the only one I've found that exhibits this behavior; to add insult to injury, it claims to be an "xterm" in TERM. Therefore we discriminate between **vt**(4) and a real XTerm using an ioctl. (Idea shamelessly stolen from notcurses' Linux console detection.) Some terminals bleed the APC sequence used to recognize kitty image support, and this may result in strange artifacts when no alt screen is used. On terminals that set TERM correctly, the APC sequence is not sent. ## Clipboard Some terminals support sequences to override the clipboard. Chawan differentiates between three tiers: 1. Supports clipboard *and* primary selection. The latter is what allows you on X11 to select some text with the mouse and then middle-click paste it elsewhere. This applies to all terminals that respond to OSC 60/61 (XTerm) as well as a hardcoded list of terminals that respond with 52 in DA1 and have been confirmed to support the primary selection (Kitty). 2. Supports clipboard, but may choke on trying to set primary selection. This applies to terminals that include the number 52 in DA1. This response guarantees nothing about support for the primary selection, and indeed, some terminals that return it (e.g. Contour) behave incorrectly when receiving primary. 3. Does not support clipboard. In this case we shell out to `external.copy-cmd` (defaults to [**xsel**](man:xsel(1x))(1x)). This applies to all other terminals. Notably, this includes terminals that support OSC 52 but do not have a reliable mechanism to detect whether it actually works, such as Alacritty. It is possible to manually adjust OSC 52 use with the `input.osc52-copy` and `input.osc52-primary` configuration options. ## Ancient terminals Most pre-ECMA-48 (1979) terminals are not expected to work. There is some degree of ADM-3A support, tested in Kragen Javier Sitaker's [admu](https://gitlab.com/kragen/bubbleos) emulator. Some DEC terminals have also been tested in simulators of the original hardware running the actual ROM: * The VT100 has been tested in Lars Brinkhoff's [terminal-simulator](https://github.com/larsbrinkhoff/terminal-simulator). Note: use TERM=vt100-nav if you don't have advanced video. * The VT420 has been tested in Matt Mastracci's [Blaze](https://github.com/mmastrac/blaze). Patches for other terminals (hardware or software alike) are welcome. ## Ancient character encodings For ASCII-only terminals, don't forget to `export LC_ALL=C`. For terminals supporting other legacy encodings, you may also have some luck with `language.charset`, such as `export LC_ALL=ja_JP.ISO-2022-JP`. Note that Chawan uses its own encoding library instead of the notoriously broken C locale facility, and the two sets of supported charsets may not fully overlap. You can test whether a charset is supported using `cha -O {charset name} -V`. ## See also [**cha**](cha.md)(1) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/troubleshooting.md����������������������������������������������������������������0000664�0000000�0000000�00000014405�15202323131�0017454�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- CHA-TROUBLESHOOTING 7 --> # Troubleshooting Chawan This document lists common problems you may run into when using Chawan. If you encounter a problem not described in this document, please open a ticket at <https://todo.sr.ht/~bptato/chawan>. ## It doesn't compile? Please open a ticket. Don't forget to include the compilation error, and your operating system (and its version). ## It crashes? Please open a ticket that describes how to reproduce the crash. Don't forget to include the error message you see after your buffer disappeared. If you don't see an error message, try: `cha example.org -o start.console-buffer=false 2>err.log`. Then check the contents of `err.log` after the crash. If you *still* don't see an error message, no problem, just report that you couldn't get an error message. ## I can't select/copy text with my mouse? Right click -> select text, then right click -> copy selection. (You can also double click and drag the mouse to the left/right to select.) If Chawan complains about xsel, either install it or edit `external.copy-cmd` and `external.paste-cmd` to your liking. You can also disable mouse tracking temporarily by holding down shift, or permanently by setting in `config.toml`: ```toml [input] use-mouse = false ``` ## I was promised images but I see nothing? The most common reason is that you didn't add following to `config.toml`: ```toml [buffer] images = true ``` The second most common reason is that your terminal supports neither Sixel nor Kitty images. Other reasons are enumerated [**cha-image**](image.md)(7). ## Why do I get strange/incorrect/ugly colors? By default, Chawan's display capabilities are limited to what your terminal reports. In particular: * If the `$COLORTERM` environment variable is not set, it may fall back to 8-bit or ANSI colors. Make sure you export it as `COLORTERM=truecolor`. * If it does not respond to querying the background color, then Chawan's color contrast correction will likely malfunction. You can correct this using the `display.default-background-color` and `display.default-foreground-color` options. See the *Display* section in [**cha-config**](config.md#display)(5) for details. ## I set my `$PAGER` to `cha` and now man pages are unreadable. Most `man` implementations print formatted manual pages by default, which Chawan *can* parse if they are passed through standard input. Unfortunately, mandoc passes us the formatted document as a *file*, which Chawan reasonably interprets as plain text without formatting. At this point, you have two options: * `export PAGER='cha -T text/x-ansi'` and see that man suddenly works as expected. * `alias man=mancha` and see that man suddenly works better than expected. Ideally you should do both, to deal with cases like git help which shells out to man directly. There is still one problem with this solution: some programs will try to call `$PAGER` without shell expansion, breaking the `-T text/x-ansi` trick. To fix this, put a script somewhere in your `PATH`: ```sh #!/bin/sh exec cha -T text/x-ansi "$@" ``` and `export PAGER=pcha` (or whatever you named the script). ## How do I view text files with wrapping? By default, Chawan does not automatically wrap text files, which makes viewing plain text files that were not wrapped by its authors uncomfortable. A workaround is to add this to your [config](config.md#keybindings)'s `[page]` section: ```toml 'SPC f' = "pager.externFilterSource('fmt')" ``` and then type `<space> f` to view a wrapped version of the current text file. (This assumes your system has an `fmt` program - if not, `fold -s` may be an alternative.) To always automatically wrap, you can add this to your [user style](config.md#buffer): ```css plaintext { white-space: pre-wrap } ``` To do the same for HTML and ANSI text, use `plaintext, pre`. ## Why does `$WEBSITE` look awful? Usually, this is because it uses some CSS features that are not yet implemented in Chawan. The most common offender is grid. There are three ways of dealing with this: 1. If the website's contents are mostly text, install [rdrview](https://github.com/eafer/rdrview). Then bind the following command to a key of your choice in the [config](config.md#keybindings) (e.g. `<space> r`): `' r' = "pager.externFilterSource('rdrview -Hu \"$CHA_URL\"')"` This does not fix the core problem, but will significantly improve your reading experience anyway. 2. Complain [here](https://todo.sr.ht/~bptato/chawan), and wait until the problem goes away. It helps if you can reduce the issue to a minimal reproducible example (ideally a small HTML fragment.) 3. Write a patch to fix the problem, and send it [here](https://lists.sr.ht/~bptato/chawan-devel). ## `$WEBSITE`'s interactive features don't work! Some potential fixes: * Logging in to websites requires cookies. Some websites also require cookie sharing across domains. For security reasons, Chawan does not allow any of this by default, so you will have to fiddle with siteconf to fix it. See the *Siteconf* section in [**cha-config**](config.md#siteconf)(5) for details. * Set the `referer-from` siteconf value to true; this will cause Chawan to send a `Referer` header when navigating to other URLs from the target URL. * Enable JavaScript. If something broke, type M-c M-c to check the browser console, then follow step 3.\ of the previous answer. ## Text areas discard my edits when I type C-c in my editor! This is a bug in your shell: <https://people.freebsd.org/~cracauer/homepage-mirror/sigint.html> When Chawan runs an external text editor, it simply passes the `$EDITOR` command to the shell, and then examines its *wait status* to determine if your editor exited gracefully. This works if either the editor never receives a signal, or your shell implements WCE. However, if the editor (e.g. nvi) catches SIGINT on C-c, and the shell reports that the program was killed by a signal (WUE), then Chawan will discard your changes (as it believes that the program has crashed). The easiest workaround is to remove the shell from the equation using `exec`: ```sh [external] editor = 'exec vi +%d' ``` ## When I open Chawan from aerc, it prints garbage in the search field! This should be fixed in the latest aerc version. Please update aerc. ## See also [**cha**](cha.md)(1) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/doc/urimethodmap.md�������������������������������������������������������������������0000664�0000000�0000000�00000006736�15202323131�0016733�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- CHA-URIMETHODMAP 5 --> # URI method map support in Chawan Chawan can be used to map unrecognized protocols to known protocols using the *urimethodmap* format. The main use case for this is implementing handlers to protocols unknown to Chawan through a protocol that the browser does understand. ## Search path The search path for urimethodmap files can be overridden using the configuration variable `external.urimethodmap`. The default search path for urimethodmap files is: ``` $CHA_DIR/urimethodmap:$HOME/.urimethodmap:/etc/urimethodmap ``` ## Format The urimethodmap format is taken 1:1 from w3m, with some modifications to the interpretation of templates. A rough attempt at the formal description of this: ``` URIMethodMap-File = *URIMethodMap-line URIMethodMap-Line = Comment / URIMethodMap-Entry URIMethodMap-Entry = Protocol *WHITESPACE Template *WHITESPACE CR Protocol = 1*CHAR COLON Template = [see below] Comment = *WHITESPACE CR / "#" *CHAR CR ``` Note that an ASCII colon sign (:) must be present after the protocol name. However, the whitespace may be omitted. Examples: ``` # This is ok: protocol: /cgi-bin/interpret-protocol?%s # This is ok too: protocol:/cgi-bin/interpret-protocol?%s # Spaces and tabs are both allowed, so this is also ok: protocol: /cgi-bin/interpret-protocol?%s # However, this is incorrect, because the colon sign is missing: protocol /cgi-bin/interpret-protocol?%s ``` The redirection template is the target URL. If the string `%s` is contained in the template, it will be replaced by the target URL. For compatibility with w3m, templates starting with `/cgi-bin/` and `file:/cgi-bin/` are special-cased and the starting string is replaced with `cgi-bin:`. So for example, the template `/cgi-bin/w3mdict.cgi` is the same as `cgi-bin:w3mdict.cgi` (and so is `file:/cgi-bin/w3mdict.cgi`). Example: ``` # The following are the same in Chawan protocol: /cgi-bin/interpret-protocol?%s protocol: file:/cgi-bin/interpret-protocol?%s # Note: this last entry does not work in w3m. protocol: cgi-bin:interpret-protocol?%s ``` Note however that absolute paths to cgi scripts are NOT special cased, so e.g. `file:///usr/local/libexec/w3m/cgi-bin/w3mdict.cgi` will simply open w3mdict.cgi in the file viewer. (Unlike in w3m, where it could run `w3mdict.cgi` depending on the user's configuration.) ## Examples Following lines should be specified in `$CHA_DIR/urimethodmap` (where `$CHA_DIR` is either ~/.chawan or ~/.config/chawan depending on where your config.toml is). ### magnet.cgi ``` # Use the `magnet.cgi` CGI shell script to pass magnet links to Transmission. magnet: /cgi-bin/magnet.cgi?%s ``` `magnet.cgi` can be found in the `bonus/` directory. You can also write a local CGI wrapper to pass the links to your BitTorrent client of choice. ### dict In w3m, urimethodmap is commonly (ab)used to define shorthands for CGI scripts. This works in Chawan too; for an example, you could define a `tl:` shorthand like this: ``` # (trans.cgi is a script you can find and study in the bonus/ directory.) tl: /cgi-bin/trans.cgi?%s ``` Then, you could open the translation of any word using `tl:word`. Note however that Chawan has a more powerful facility for substitution shorthands like this in the form of omni-rules. So if you want to redirect to an online dictionary site with tl:word instead of providing a local CGI interface, it is easier to just use omni-rules instead of urimethodmap + local CGI redirection. ## See also [**cha**](cha.md)(1) [**cha-cgi**](cgi.md)(5) ����������������������������������chawan-v0.4.0/lib/����������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0013700�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/���������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0015035�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/.gitignore�����������������������������������������������������������������0000664�0000000�0000000�00000000032�15202323131�0017020�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/test/* !/test/*.* /.obj/ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/Makefile�������������������������������������������������������������������0000664�0000000�0000000�00000000717�15202323131�0016502�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������NIM ?= nim FLAGS += -p:. -p:../chagashi0 .PHONY: all all: test .PHONY: test test: if ! test -d test/html5lib-tests; then cd test && git clone https://github.com/html5lib/html5lib-tests.git; fi $(NIM) r $(FLAGS) test/test1.nim $(NIM) r $(FLAGS) test/tree.nim $(NIM) r $(FLAGS) test/tokenizer.nim $(NIM) r $(FLAGS) test/tree_charset.nim $(NIM) r $(FLAGS) test/tree_misc.nim .PHONY: entity entity: cd chame/res && $(NIM) r genentity.nim >../entity_gen.nim �������������������������������������������������chawan-v0.4.0/lib/chame0/NEWS�����������������������������������������������������������������������0000664�0000000�0000000�00000011113�15202323131�0015531�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������1.0.5 (2025.09.09) * Unbreak compilation on 1.6.10 * Eliminate macro use (for faster compilation) * Update code style * Minor optimizations Note that this removes some exported symbols (in particular, the macros module) which weren't advertised in the public API. 1.0.4 (2025.05.23) * Fix bug in parsing invalid character references that start with #x10FFFF or its decimal counterpart * Minor optimizations * Removed submodules from repository 1.0.3 (2025.01.03) * Conform to strict defs 1.0.2 (2024.11.22) * Minor optimizations * Minor documentation updates 1.0.1 (2024.07.28) * Minor optimization * Add test directory to skipDirs 1.0.0 (2024.06.13) * Drop support for parse error handling * Switch from legacy character decoder library to Chagashi * Return PRES_SCRIPT for the SVG script element too First stable version. 0.14.5 (2024.04.09) * Fix broken parsing of HTML entities starting with a lower `z' * Fix nimble test execution on old Nim versions * Various refactorings: reduce duplicated code, get rid of some dead code, move some atom mappings to compile time 0.14.4 (2024.03.03) * Clean up tokenizeEOF so that it's compiled correctly on old Nim + ARM 0.14.3 (2024.02.21) * Fix another instance of the same bug 0.14.2 (2024.02.21) * Fix a character reference parsing bug: e.g. in `&g<a>', the < character was being flushed as text instead of being interpreted as markup. 0.14.1 (2024.02.08) * Fix associateWithFormImpl callback regression (it was not being called for input elements) * Misc refactorings 0.14.0 (2024.02.07) * The "bag of pointers" interface design has been dropped * Tag and attribute names are now treated as interned strings (a user-defined "Atom" type) * Support processing of embedded SVG/MathML elements * Chakasu has been made an optional dependency * std/streams no longer used by htmlparser; now it supports chunked parsing instead * All tokenizer + tree builder tests passed in html5lib-tests Rough migration guide from the previous API: Users of minidom * nodeType is no longer supported, use the of operator to distinguish between node types. * minidom now only supports UTF-8; if you need support for other charsets, use minidom_cs. * localName is now an MAtom; to get the stringified local name, use localNameStr. * attrs is now a seq of Attribute tuples. Linear search this seq to find specific attributes. * minidom now contains several MAtom fields; to convert these to strings, call document.atomToStr(atom). Users of htmlparser * The NodeType enum has been removed. Either copy-paste the enum definition from a previous version, or (more efficient) use the `of` operator to distinguish between types. * Use of an AtomFactory is now required for consumers of htmlparser. The easiest fix is to copy-paste the implementation found in minidom. * Your DOM builder should be generic over a Handle and an Atom. Example: `DOMBuilder[Node, MAtom]` * You no longer have to copy function pointers into your DOM builder. * It is recommended to add `include chame/htmlparseriface` to your DOM builder module. See the htmlparseriface documentation for details. Switching to the new interface: * Add `Impl` to the name of all your procedure implementations. * If you included chame/htmlparseriface, replace all parameters of your procedures containing `DOMBuilder[MyHandle]` with `MyDOMBuilder`. * setCharacterSet -> setEncodingImpl that takes a string label. * getLocalNameImpl now must return an Atom. getTagType is no longer used. * insertBeforeImpl must take an `Option[Handle]` * addAttrsIfMissingImpl is now mandatory, and must take a `Table[Atom, string]` * getNamespaceImpl is now mandatory. * getDocumentImpl must be implemented, and must return the Handle of the document. * tagTypeToAtomImpl, atomToTagTypeImpl, strToAtomImpl must all be implemented. * createHTMLElementImpl must be implemented, and must return the handle of a new `<html>` element. * createElement -> createElementForTokenImpl, the signature has changed significantly. localName is the 2-in-1 replacement for both tagType and localName. Also, you probably have to convert attributes from htmlAttrs & xmlAttrs to your own internal representation. * finish is no longer called at the end of parsing. Call it yourself. Event loop changes: * parseHTML is now split into three parts: initHTML5Parser, parseChunk, finish. * If you implement scripting and/or character sets other than UTF-8, see doc/manual.md for handling parseChunk's result. Otherwise, it is safe to discard it. * Do not forget to call finish after having parsed the entire document (first for the parser, then for your own DOM builder). �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/README.md������������������������������������������������������������������0000664�0000000�0000000�00000006311�15202323131�0016315�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Chame: an HTML5 parser library in Nim ## Usage Include Chame in your project using either Nimble or as a git submodule. ``` requires "chame" # optional, if you want support for charsets other than UTF-8 requires "chagashi" ``` Then, check the [documentation](https://chawan.net/doc/chame/) for a description of the API. Note: only Nim 1.6.10+ is supported. ## Features * Full compliance with the WHATWG HTML parsing standard * Passes all tokenizer and tree builder tests in html5lib-tests (except for ones requiring JS) * Includes a minimal DOM implementation * No mandatory dependencies other than the Nim standard library * Optional character encoding support (see [minidom_cs](chame/minidom_cs.nim)) * String interning support for tag and attribute names * Support for chunked parsing * document.write (no actual implementation here, but it's possible to implement it on top of Chame) ## Manual There is a manual available at [doc/manual.md](doc/manual.md). ## To-do At this point the library is complete. The only remaining tasks are optimization-related. Also, a small module for basic minidom utilities is planned. ## Bugs, feedback, etc. Feedback, complaints, etc. are accepted at [SourceHut](https://todo.sr.ht/~bptato/chawan) or the Nim forum [thread](https://forum.nim-lang.org/t/10963). ## FAQ ### Does Chame include a DOM, JavaScript, CSS, ...? Chame just parses HTML and calls the callbacks supplied to it. JavaScript, DOM manipulation, etc. are technically outside the scope of this project. However, Chame includes a minimal DOM interface (intuitively named minidom) for demonstration and testing purposes. This only implements the very basics needed for the parser to function (and for the tests to pass), and does not have any convenience functions (like querySelector, getElementById, etc.) Please refer to the [Chawan](https://sr.ht/~bptato/chawan/) web browser for an example of a complete DOM implementation that depends on Chame. Also see [CSS3Selectors](https://github.com/Niminem/CSS3Selectors/), a CSS selector library for Chame's minidom which allows you to run querySelector like you can in JS. If you implement a DOM library based on Chame, please notify me, so that I can redirect users to it in this section. ### I read the manual, but it's too complex, I don't understand anything, help Just call minidom.parseHTML on an std/stream.Stream object and forget about everything else. Chances are this is enough for whatever you want to do. ### How do I implement speculative parsing? No idea. Let me know if you figure something out. ### How do you pronounce Chame? It is an acronym of "**Cha**wan HT**M**L (aitch-tee-e**m-e**l)." Accordingly, it is pronounced as "cha-meh." ## Thanks [SerenityOS](https://serenityos.org/)'s HTML parser has been used as a reference when I found some parts of the specification unclear. Servo's HTML parser [html5ever](https://github.com/servo/html5ever) has been the main inspiration for Chame's API. Finally, thanks to the standard writers for writing a very detailed specification of the HTML5 parsing algorithm. The bulk of Chame is a direct translation of this algorithm into Nim. ## License Chame is dedicated to the public domain. See the UNLICENSE file for details. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/UNLICENSE������������������������������������������������������������������0000664�0000000�0000000�00000002273�15202323131�0016311�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to <http://unlicense.org/> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/chame.nimble���������������������������������������������������������������0000664�0000000�0000000�00000000306�15202323131�0017301�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Package version = "1.0.5" author = "bptato" description = "HTML5 parser for Chawan" license = "Unlicense" skipDirs = @["test"] # Dependencies requires "nim >= 1.6.10" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/chame/���������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0016112�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/chame/dombuilder.nim�������������������������������������������������������0000664�0000000�0000000�00000000465�15202323131�0020752�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import tags type SetEncodingResult* = enum SET_ENCODING_CONTINUE, SET_ENCODING_STOP ParsedAttr*[Atom] = tuple prefix: NamespacePrefix namespace: Namespace name: Atom value: string DOMBuilderBase* = ref object of RootObj DOMBuilder*[Handle, Atom] = ref object of DOMBuilderBase �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/chame/entity_gen.nim�������������������������������������������������������0000664�0000000�0000000�00000147055�15202323131�0021000�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������type Z = cstring const entityMap*: array[2231, Z] = [ Z "AElig:\xC3\x86","AElig;:\xC3\x86","AMP:&","AMP;:&","Aacute:\xC3\x81", "Aacute;:\xC3\x81","Abreve;:\xC4\x82","Acirc:\xC3\x82","Acirc;:\xC3\x82", "Acy;:\xD0\x90","Afr;:\xF0\x9D\x94\x84","Agrave:\xC3\x80","Agrave;:\xC3\x80", "Alpha;:\xCE\x91","Amacr;:\xC4\x80","And;:\xE2\xA9\x93","Aogon;:\xC4\x84", "Aopf;:\xF0\x9D\x94\xB8","ApplyFunction;:\xE2\x81\xA1","Aring:\xC3\x85", "Aring;:\xC3\x85","Ascr;:\xF0\x9D\x92\x9C","Assign;:\xE2\x89\x94", "Atilde:\xC3\x83","Atilde;:\xC3\x83","Auml:\xC3\x84","Auml;:\xC3\x84", "Backslash;:\xE2\x88\x96","Barv;:\xE2\xAB\xA7","Barwed;:\xE2\x8C\x86", "Bcy;:\xD0\x91","Because;:\xE2\x88\xB5","Bernoullis;:\xE2\x84\xAC", "Beta;:\xCE\x92","Bfr;:\xF0\x9D\x94\x85","Bopf;:\xF0\x9D\x94\xB9", "Breve;:\xCB\x98","Bscr;:\xE2\x84\xAC","Bumpeq;:\xE2\x89\x8E","CHcy;:\xD0\xA7", "COPY:\xC2\xA9","COPY;:\xC2\xA9","Cacute;:\xC4\x86","Cap;:\xE2\x8B\x92", "CapitalDifferentialD;:\xE2\x85\x85","Cayleys;:\xE2\x84\xAD","Ccaron;:\xC4\x8C", "Ccedil:\xC3\x87","Ccedil;:\xC3\x87","Ccirc;:\xC4\x88","Cconint;:\xE2\x88\xB0", "Cdot;:\xC4\x8A","Cedilla;:\xC2\xB8","CenterDot;:\xC2\xB7","Cfr;:\xE2\x84\xAD", "Chi;:\xCE\xA7","CircleDot;:\xE2\x8A\x99","CircleMinus;:\xE2\x8A\x96", "CirclePlus;:\xE2\x8A\x95","CircleTimes;:\xE2\x8A\x97", "ClockwiseContourIntegral;:\xE2\x88\xB2","CloseCurlyDoubleQuote;:\xE2\x80\x9D", "CloseCurlyQuote;:\xE2\x80\x99","Colon;:\xE2\x88\xB7","Colone;:\xE2\xA9\xB4", "Congruent;:\xE2\x89\xA1","Conint;:\xE2\x88\xAF", "ContourIntegral;:\xE2\x88\xAE","Copf;:\xE2\x84\x82","Coproduct;:\xE2\x88\x90", "CounterClockwiseContourIntegral;:\xE2\x88\xB3","Cross;:\xE2\xA8\xAF", "Cscr;:\xF0\x9D\x92\x9E","Cup;:\xE2\x8B\x93","CupCap;:\xE2\x89\x8D", "DD;:\xE2\x85\x85","DDotrahd;:\xE2\xA4\x91","DJcy;:\xD0\x82","DScy;:\xD0\x85", "DZcy;:\xD0\x8F","Dagger;:\xE2\x80\xA1","Darr;:\xE2\x86\xA1", "Dashv;:\xE2\xAB\xA4","Dcaron;:\xC4\x8E","Dcy;:\xD0\x94","Del;:\xE2\x88\x87", "Delta;:\xCE\x94","Dfr;:\xF0\x9D\x94\x87","DiacriticalAcute;:\xC2\xB4", "DiacriticalDot;:\xCB\x99","DiacriticalDoubleAcute;:\xCB\x9D", "DiacriticalGrave;:`","DiacriticalTilde;:\xCB\x9C","Diamond;:\xE2\x8B\x84", "DifferentialD;:\xE2\x85\x86","Dopf;:\xF0\x9D\x94\xBB","Dot;:\xC2\xA8", "DotDot;:\xE2\x83\x9C","DotEqual;:\xE2\x89\x90", "DoubleContourIntegral;:\xE2\x88\xAF","DoubleDot;:\xC2\xA8", "DoubleDownArrow;:\xE2\x87\x93","DoubleLeftArrow;:\xE2\x87\x90", "DoubleLeftRightArrow;:\xE2\x87\x94","DoubleLeftTee;:\xE2\xAB\xA4", "DoubleLongLeftArrow;:\xE2\x9F\xB8","DoubleLongLeftRightArrow;:\xE2\x9F\xBA", "DoubleLongRightArrow;:\xE2\x9F\xB9","DoubleRightArrow;:\xE2\x87\x92", "DoubleRightTee;:\xE2\x8A\xA8","DoubleUpArrow;:\xE2\x87\x91", "DoubleUpDownArrow;:\xE2\x87\x95","DoubleVerticalBar;:\xE2\x88\xA5", "DownArrow;:\xE2\x86\x93","DownArrowBar;:\xE2\xA4\x93", "DownArrowUpArrow;:\xE2\x87\xB5","DownBreve;:\xCC\x91", "DownLeftRightVector;:\xE2\xA5\x90","DownLeftTeeVector;:\xE2\xA5\x9E", "DownLeftVector;:\xE2\x86\xBD","DownLeftVectorBar;:\xE2\xA5\x96", "DownRightTeeVector;:\xE2\xA5\x9F","DownRightVector;:\xE2\x87\x81", "DownRightVectorBar;:\xE2\xA5\x97","DownTee;:\xE2\x8A\xA4", "DownTeeArrow;:\xE2\x86\xA7","Downarrow;:\xE2\x87\x93","Dscr;:\xF0\x9D\x92\x9F", "Dstrok;:\xC4\x90","ENG;:\xC5\x8A","ETH:\xC3\x90","ETH;:\xC3\x90", "Eacute:\xC3\x89","Eacute;:\xC3\x89","Ecaron;:\xC4\x9A","Ecirc:\xC3\x8A", "Ecirc;:\xC3\x8A","Ecy;:\xD0\xAD","Edot;:\xC4\x96","Efr;:\xF0\x9D\x94\x88", "Egrave:\xC3\x88","Egrave;:\xC3\x88","Element;:\xE2\x88\x88","Emacr;:\xC4\x92", "EmptySmallSquare;:\xE2\x97\xBB","EmptyVerySmallSquare;:\xE2\x96\xAB", "Eogon;:\xC4\x98","Eopf;:\xF0\x9D\x94\xBC","Epsilon;:\xCE\x95", "Equal;:\xE2\xA9\xB5","EqualTilde;:\xE2\x89\x82","Equilibrium;:\xE2\x87\x8C", "Escr;:\xE2\x84\xB0","Esim;:\xE2\xA9\xB3","Eta;:\xCE\x97","Euml:\xC3\x8B", "Euml;:\xC3\x8B","Exists;:\xE2\x88\x83","ExponentialE;:\xE2\x85\x87", "Fcy;:\xD0\xA4","Ffr;:\xF0\x9D\x94\x89","FilledSmallSquare;:\xE2\x97\xBC", "FilledVerySmallSquare;:\xE2\x96\xAA","Fopf;:\xF0\x9D\x94\xBD", "ForAll;:\xE2\x88\x80","Fouriertrf;:\xE2\x84\xB1","Fscr;:\xE2\x84\xB1", "GJcy;:\xD0\x83","GT:>","GT;:>","Gamma;:\xCE\x93","Gammad;:\xCF\x9C", "Gbreve;:\xC4\x9E","Gcedil;:\xC4\xA2","Gcirc;:\xC4\x9C","Gcy;:\xD0\x93", "Gdot;:\xC4\xA0","Gfr;:\xF0\x9D\x94\x8A","Gg;:\xE2\x8B\x99", "Gopf;:\xF0\x9D\x94\xBE","GreaterEqual;:\xE2\x89\xA5", "GreaterEqualLess;:\xE2\x8B\x9B","GreaterFullEqual;:\xE2\x89\xA7", "GreaterGreater;:\xE2\xAA\xA2","GreaterLess;:\xE2\x89\xB7", "GreaterSlantEqual;:\xE2\xA9\xBE","GreaterTilde;:\xE2\x89\xB3", "Gscr;:\xF0\x9D\x92\xA2","Gt;:\xE2\x89\xAB","HARDcy;:\xD0\xAA", "Hacek;:\xCB\x87","Hat;:^","Hcirc;:\xC4\xA4","Hfr;:\xE2\x84\x8C", "HilbertSpace;:\xE2\x84\x8B","Hopf;:\xE2\x84\x8D", "HorizontalLine;:\xE2\x94\x80","Hscr;:\xE2\x84\x8B","Hstrok;:\xC4\xA6", "HumpDownHump;:\xE2\x89\x8E","HumpEqual;:\xE2\x89\x8F","IEcy;:\xD0\x95", "IJlig;:\xC4\xB2","IOcy;:\xD0\x81","Iacute:\xC3\x8D","Iacute;:\xC3\x8D", "Icirc:\xC3\x8E","Icirc;:\xC3\x8E","Icy;:\xD0\x98","Idot;:\xC4\xB0", "Ifr;:\xE2\x84\x91","Igrave:\xC3\x8C","Igrave;:\xC3\x8C","Im;:\xE2\x84\x91", "Imacr;:\xC4\xAA","ImaginaryI;:\xE2\x85\x88","Implies;:\xE2\x87\x92", "Int;:\xE2\x88\xAC","Integral;:\xE2\x88\xAB","Intersection;:\xE2\x8B\x82", "InvisibleComma;:\xE2\x81\xA3","InvisibleTimes;:\xE2\x81\xA2","Iogon;:\xC4\xAE", "Iopf;:\xF0\x9D\x95\x80","Iota;:\xCE\x99","Iscr;:\xE2\x84\x90", "Itilde;:\xC4\xA8","Iukcy;:\xD0\x86","Iuml:\xC3\x8F","Iuml;:\xC3\x8F", "Jcirc;:\xC4\xB4","Jcy;:\xD0\x99","Jfr;:\xF0\x9D\x94\x8D", "Jopf;:\xF0\x9D\x95\x81","Jscr;:\xF0\x9D\x92\xA5","Jsercy;:\xD0\x88", "Jukcy;:\xD0\x84","KHcy;:\xD0\xA5","KJcy;:\xD0\x8C","Kappa;:\xCE\x9A", "Kcedil;:\xC4\xB6","Kcy;:\xD0\x9A","Kfr;:\xF0\x9D\x94\x8E", "Kopf;:\xF0\x9D\x95\x82","Kscr;:\xF0\x9D\x92\xA6","LJcy;:\xD0\x89","LT:<", "LT;:<","Lacute;:\xC4\xB9","Lambda;:\xCE\x9B","Lang;:\xE2\x9F\xAA", "Laplacetrf;:\xE2\x84\x92","Larr;:\xE2\x86\x9E","Lcaron;:\xC4\xBD", "Lcedil;:\xC4\xBB","Lcy;:\xD0\x9B","LeftAngleBracket;:\xE2\x9F\xA8", "LeftArrow;:\xE2\x86\x90","LeftArrowBar;:\xE2\x87\xA4", "LeftArrowRightArrow;:\xE2\x87\x86","LeftCeiling;:\xE2\x8C\x88", "LeftDoubleBracket;:\xE2\x9F\xA6","LeftDownTeeVector;:\xE2\xA5\xA1", "LeftDownVector;:\xE2\x87\x83","LeftDownVectorBar;:\xE2\xA5\x99", "LeftFloor;:\xE2\x8C\x8A","LeftRightArrow;:\xE2\x86\x94", "LeftRightVector;:\xE2\xA5\x8E","LeftTee;:\xE2\x8A\xA3", "LeftTeeArrow;:\xE2\x86\xA4","LeftTeeVector;:\xE2\xA5\x9A", "LeftTriangle;:\xE2\x8A\xB2","LeftTriangleBar;:\xE2\xA7\x8F", "LeftTriangleEqual;:\xE2\x8A\xB4","LeftUpDownVector;:\xE2\xA5\x91", "LeftUpTeeVector;:\xE2\xA5\xA0","LeftUpVector;:\xE2\x86\xBF", "LeftUpVectorBar;:\xE2\xA5\x98","LeftVector;:\xE2\x86\xBC", "LeftVectorBar;:\xE2\xA5\x92","Leftarrow;:\xE2\x87\x90", "Leftrightarrow;:\xE2\x87\x94","LessEqualGreater;:\xE2\x8B\x9A", "LessFullEqual;:\xE2\x89\xA6","LessGreater;:\xE2\x89\xB6", "LessLess;:\xE2\xAA\xA1","LessSlantEqual;:\xE2\xA9\xBD", "LessTilde;:\xE2\x89\xB2","Lfr;:\xF0\x9D\x94\x8F","Ll;:\xE2\x8B\x98", "Lleftarrow;:\xE2\x87\x9A","Lmidot;:\xC4\xBF","LongLeftArrow;:\xE2\x9F\xB5", "LongLeftRightArrow;:\xE2\x9F\xB7","LongRightArrow;:\xE2\x9F\xB6", "Longleftarrow;:\xE2\x9F\xB8","Longleftrightarrow;:\xE2\x9F\xBA", "Longrightarrow;:\xE2\x9F\xB9","Lopf;:\xF0\x9D\x95\x83", "LowerLeftArrow;:\xE2\x86\x99","LowerRightArrow;:\xE2\x86\x98", "Lscr;:\xE2\x84\x92","Lsh;:\xE2\x86\xB0","Lstrok;:\xC5\x81","Lt;:\xE2\x89\xAA", "Map;:\xE2\xA4\x85","Mcy;:\xD0\x9C","MediumSpace;:\xE2\x81\x9F", "Mellintrf;:\xE2\x84\xB3","Mfr;:\xF0\x9D\x94\x90","MinusPlus;:\xE2\x88\x93", "Mopf;:\xF0\x9D\x95\x84","Mscr;:\xE2\x84\xB3","Mu;:\xCE\x9C","NJcy;:\xD0\x8A", "Nacute;:\xC5\x83","Ncaron;:\xC5\x87","Ncedil;:\xC5\x85","Ncy;:\xD0\x9D", "NegativeMediumSpace;:\xE2\x80\x8B","NegativeThickSpace;:\xE2\x80\x8B", "NegativeThinSpace;:\xE2\x80\x8B","NegativeVeryThinSpace;:\xE2\x80\x8B", "NestedGreaterGreater;:\xE2\x89\xAB","NestedLessLess;:\xE2\x89\xAA", "NewLine;:\x0A","Nfr;:\xF0\x9D\x94\x91","NoBreak;:\xE2\x81\xA0", "NonBreakingSpace;:\xC2\xA0","Nopf;:\xE2\x84\x95","Not;:\xE2\xAB\xAC", "NotCongruent;:\xE2\x89\xA2","NotCupCap;:\xE2\x89\xAD", "NotDoubleVerticalBar;:\xE2\x88\xA6","NotElement;:\xE2\x88\x89", "NotEqual;:\xE2\x89\xA0","NotEqualTilde;:\xE2\x89\x82\xCC\xB8", "NotExists;:\xE2\x88\x84","NotGreater;:\xE2\x89\xAF", "NotGreaterEqual;:\xE2\x89\xB1","NotGreaterFullEqual;:\xE2\x89\xA7\xCC\xB8", "NotGreaterGreater;:\xE2\x89\xAB\xCC\xB8","NotGreaterLess;:\xE2\x89\xB9", "NotGreaterSlantEqual;:\xE2\xA9\xBE\xCC\xB8","NotGreaterTilde;:\xE2\x89\xB5", "NotHumpDownHump;:\xE2\x89\x8E\xCC\xB8","NotHumpEqual;:\xE2\x89\x8F\xCC\xB8", "NotLeftTriangle;:\xE2\x8B\xAA","NotLeftTriangleBar;:\xE2\xA7\x8F\xCC\xB8", "NotLeftTriangleEqual;:\xE2\x8B\xAC","NotLess;:\xE2\x89\xAE", "NotLessEqual;:\xE2\x89\xB0","NotLessGreater;:\xE2\x89\xB8", "NotLessLess;:\xE2\x89\xAA\xCC\xB8","NotLessSlantEqual;:\xE2\xA9\xBD\xCC\xB8", "NotLessTilde;:\xE2\x89\xB4","NotNestedGreaterGreater;:\xE2\xAA\xA2\xCC\xB8", "NotNestedLessLess;:\xE2\xAA\xA1\xCC\xB8","NotPrecedes;:\xE2\x8A\x80", "NotPrecedesEqual;:\xE2\xAA\xAF\xCC\xB8","NotPrecedesSlantEqual;:\xE2\x8B\xA0", "NotReverseElement;:\xE2\x88\x8C","NotRightTriangle;:\xE2\x8B\xAB", "NotRightTriangleBar;:\xE2\xA7\x90\xCC\xB8", "NotRightTriangleEqual;:\xE2\x8B\xAD","NotSquareSubset;:\xE2\x8A\x8F\xCC\xB8", "NotSquareSubsetEqual;:\xE2\x8B\xA2","NotSquareSuperset;:\xE2\x8A\x90\xCC\xB8", "NotSquareSupersetEqual;:\xE2\x8B\xA3","NotSubset;:\xE2\x8A\x82\xE2\x83\x92", "NotSubsetEqual;:\xE2\x8A\x88","NotSucceeds;:\xE2\x8A\x81", "NotSucceedsEqual;:\xE2\xAA\xB0\xCC\xB8","NotSucceedsSlantEqual;:\xE2\x8B\xA1", "NotSucceedsTilde;:\xE2\x89\xBF\xCC\xB8", "NotSuperset;:\xE2\x8A\x83\xE2\x83\x92","NotSupersetEqual;:\xE2\x8A\x89", "NotTilde;:\xE2\x89\x81","NotTildeEqual;:\xE2\x89\x84", "NotTildeFullEqual;:\xE2\x89\x87","NotTildeTilde;:\xE2\x89\x89", "NotVerticalBar;:\xE2\x88\xA4","Nscr;:\xF0\x9D\x92\xA9","Ntilde:\xC3\x91", "Ntilde;:\xC3\x91","Nu;:\xCE\x9D","OElig;:\xC5\x92","Oacute:\xC3\x93", "Oacute;:\xC3\x93","Ocirc:\xC3\x94","Ocirc;:\xC3\x94","Ocy;:\xD0\x9E", "Odblac;:\xC5\x90","Ofr;:\xF0\x9D\x94\x92","Ograve:\xC3\x92","Ograve;:\xC3\x92", "Omacr;:\xC5\x8C","Omega;:\xCE\xA9","Omicron;:\xCE\x9F", "Oopf;:\xF0\x9D\x95\x86","OpenCurlyDoubleQuote;:\xE2\x80\x9C", "OpenCurlyQuote;:\xE2\x80\x98","Or;:\xE2\xA9\x94","Oscr;:\xF0\x9D\x92\xAA", "Oslash:\xC3\x98","Oslash;:\xC3\x98","Otilde:\xC3\x95","Otilde;:\xC3\x95", "Otimes;:\xE2\xA8\xB7","Ouml:\xC3\x96","Ouml;:\xC3\x96","OverBar;:\xE2\x80\xBE", "OverBrace;:\xE2\x8F\x9E","OverBracket;:\xE2\x8E\xB4", "OverParenthesis;:\xE2\x8F\x9C","PartialD;:\xE2\x88\x82","Pcy;:\xD0\x9F", "Pfr;:\xF0\x9D\x94\x93","Phi;:\xCE\xA6","Pi;:\xCE\xA0","PlusMinus;:\xC2\xB1", "Poincareplane;:\xE2\x84\x8C","Popf;:\xE2\x84\x99","Pr;:\xE2\xAA\xBB", "Precedes;:\xE2\x89\xBA","PrecedesEqual;:\xE2\xAA\xAF", "PrecedesSlantEqual;:\xE2\x89\xBC","PrecedesTilde;:\xE2\x89\xBE", "Prime;:\xE2\x80\xB3","Product;:\xE2\x88\x8F","Proportion;:\xE2\x88\xB7", "Proportional;:\xE2\x88\x9D","Pscr;:\xF0\x9D\x92\xAB","Psi;:\xCE\xA8","QUOT:\"", "QUOT;:\"","Qfr;:\xF0\x9D\x94\x94","Qopf;:\xE2\x84\x9A", "Qscr;:\xF0\x9D\x92\xAC","RBarr;:\xE2\xA4\x90","REG:\xC2\xAE","REG;:\xC2\xAE", "Racute;:\xC5\x94","Rang;:\xE2\x9F\xAB","Rarr;:\xE2\x86\xA0", "Rarrtl;:\xE2\xA4\x96","Rcaron;:\xC5\x98","Rcedil;:\xC5\x96","Rcy;:\xD0\xA0", "Re;:\xE2\x84\x9C","ReverseElement;:\xE2\x88\x8B", "ReverseEquilibrium;:\xE2\x87\x8B","ReverseUpEquilibrium;:\xE2\xA5\xAF", "Rfr;:\xE2\x84\x9C","Rho;:\xCE\xA1","RightAngleBracket;:\xE2\x9F\xA9", "RightArrow;:\xE2\x86\x92","RightArrowBar;:\xE2\x87\xA5", "RightArrowLeftArrow;:\xE2\x87\x84","RightCeiling;:\xE2\x8C\x89", "RightDoubleBracket;:\xE2\x9F\xA7","RightDownTeeVector;:\xE2\xA5\x9D", "RightDownVector;:\xE2\x87\x82","RightDownVectorBar;:\xE2\xA5\x95", "RightFloor;:\xE2\x8C\x8B","RightTee;:\xE2\x8A\xA2", "RightTeeArrow;:\xE2\x86\xA6","RightTeeVector;:\xE2\xA5\x9B", "RightTriangle;:\xE2\x8A\xB3","RightTriangleBar;:\xE2\xA7\x90", "RightTriangleEqual;:\xE2\x8A\xB5","RightUpDownVector;:\xE2\xA5\x8F", "RightUpTeeVector;:\xE2\xA5\x9C","RightUpVector;:\xE2\x86\xBE", "RightUpVectorBar;:\xE2\xA5\x94","RightVector;:\xE2\x87\x80", "RightVectorBar;:\xE2\xA5\x93","Rightarrow;:\xE2\x87\x92","Ropf;:\xE2\x84\x9D", "RoundImplies;:\xE2\xA5\xB0","Rrightarrow;:\xE2\x87\x9B","Rscr;:\xE2\x84\x9B", "Rsh;:\xE2\x86\xB1","RuleDelayed;:\xE2\xA7\xB4","SHCHcy;:\xD0\xA9", "SHcy;:\xD0\xA8","SOFTcy;:\xD0\xAC","Sacute;:\xC5\x9A","Sc;:\xE2\xAA\xBC", "Scaron;:\xC5\xA0","Scedil;:\xC5\x9E","Scirc;:\xC5\x9C","Scy;:\xD0\xA1", "Sfr;:\xF0\x9D\x94\x96","ShortDownArrow;:\xE2\x86\x93", "ShortLeftArrow;:\xE2\x86\x90","ShortRightArrow;:\xE2\x86\x92", "ShortUpArrow;:\xE2\x86\x91","Sigma;:\xCE\xA3","SmallCircle;:\xE2\x88\x98", "Sopf;:\xF0\x9D\x95\x8A","Sqrt;:\xE2\x88\x9A","Square;:\xE2\x96\xA1", "SquareIntersection;:\xE2\x8A\x93","SquareSubset;:\xE2\x8A\x8F", "SquareSubsetEqual;:\xE2\x8A\x91","SquareSuperset;:\xE2\x8A\x90", "SquareSupersetEqual;:\xE2\x8A\x92","SquareUnion;:\xE2\x8A\x94", "Sscr;:\xF0\x9D\x92\xAE","Star;:\xE2\x8B\x86","Sub;:\xE2\x8B\x90", "Subset;:\xE2\x8B\x90","SubsetEqual;:\xE2\x8A\x86","Succeeds;:\xE2\x89\xBB", "SucceedsEqual;:\xE2\xAA\xB0","SucceedsSlantEqual;:\xE2\x89\xBD", "SucceedsTilde;:\xE2\x89\xBF","SuchThat;:\xE2\x88\x8B","Sum;:\xE2\x88\x91", "Sup;:\xE2\x8B\x91","Superset;:\xE2\x8A\x83","SupersetEqual;:\xE2\x8A\x87", "Supset;:\xE2\x8B\x91","THORN:\xC3\x9E","THORN;:\xC3\x9E","TRADE;:\xE2\x84\xA2", "TSHcy;:\xD0\x8B","TScy;:\xD0\xA6","Tab;:\x09","Tau;:\xCE\xA4", "Tcaron;:\xC5\xA4","Tcedil;:\xC5\xA2","Tcy;:\xD0\xA2","Tfr;:\xF0\x9D\x94\x97", "Therefore;:\xE2\x88\xB4","Theta;:\xCE\x98", "ThickSpace;:\xE2\x81\x9F\xE2\x80\x8A","ThinSpace;:\xE2\x80\x89", "Tilde;:\xE2\x88\xBC","TildeEqual;:\xE2\x89\x83","TildeFullEqual;:\xE2\x89\x85", "TildeTilde;:\xE2\x89\x88","Topf;:\xF0\x9D\x95\x8B","TripleDot;:\xE2\x83\x9B", "Tscr;:\xF0\x9D\x92\xAF","Tstrok;:\xC5\xA6","Uacute:\xC3\x9A", "Uacute;:\xC3\x9A","Uarr;:\xE2\x86\x9F","Uarrocir;:\xE2\xA5\x89", "Ubrcy;:\xD0\x8E","Ubreve;:\xC5\xAC","Ucirc:\xC3\x9B","Ucirc;:\xC3\x9B", "Ucy;:\xD0\xA3","Udblac;:\xC5\xB0","Ufr;:\xF0\x9D\x94\x98","Ugrave:\xC3\x99", "Ugrave;:\xC3\x99","Umacr;:\xC5\xAA","UnderBar;:_","UnderBrace;:\xE2\x8F\x9F", "UnderBracket;:\xE2\x8E\xB5","UnderParenthesis;:\xE2\x8F\x9D", "Union;:\xE2\x8B\x83","UnionPlus;:\xE2\x8A\x8E","Uogon;:\xC5\xB2", "Uopf;:\xF0\x9D\x95\x8C","UpArrow;:\xE2\x86\x91","UpArrowBar;:\xE2\xA4\x92", "UpArrowDownArrow;:\xE2\x87\x85","UpDownArrow;:\xE2\x86\x95", "UpEquilibrium;:\xE2\xA5\xAE","UpTee;:\xE2\x8A\xA5","UpTeeArrow;:\xE2\x86\xA5", "Uparrow;:\xE2\x87\x91","Updownarrow;:\xE2\x87\x95", "UpperLeftArrow;:\xE2\x86\x96","UpperRightArrow;:\xE2\x86\x97","Upsi;:\xCF\x92", "Upsilon;:\xCE\xA5","Uring;:\xC5\xAE","Uscr;:\xF0\x9D\x92\xB0", "Utilde;:\xC5\xA8","Uuml:\xC3\x9C","Uuml;:\xC3\x9C","VDash;:\xE2\x8A\xAB", "Vbar;:\xE2\xAB\xAB","Vcy;:\xD0\x92","Vdash;:\xE2\x8A\xA9", "Vdashl;:\xE2\xAB\xA6","Vee;:\xE2\x8B\x81","Verbar;:\xE2\x80\x96", "Vert;:\xE2\x80\x96","VerticalBar;:\xE2\x88\xA3","VerticalLine;:|", "VerticalSeparator;:\xE2\x9D\x98","VerticalTilde;:\xE2\x89\x80", "VeryThinSpace;:\xE2\x80\x8A","Vfr;:\xF0\x9D\x94\x99","Vopf;:\xF0\x9D\x95\x8D", "Vscr;:\xF0\x9D\x92\xB1","Vvdash;:\xE2\x8A\xAA","Wcirc;:\xC5\xB4", "Wedge;:\xE2\x8B\x80","Wfr;:\xF0\x9D\x94\x9A","Wopf;:\xF0\x9D\x95\x8E", "Wscr;:\xF0\x9D\x92\xB2","Xfr;:\xF0\x9D\x94\x9B","Xi;:\xCE\x9E", "Xopf;:\xF0\x9D\x95\x8F","Xscr;:\xF0\x9D\x92\xB3","YAcy;:\xD0\xAF", "YIcy;:\xD0\x87","YUcy;:\xD0\xAE","Yacute:\xC3\x9D","Yacute;:\xC3\x9D", "Ycirc;:\xC5\xB6","Ycy;:\xD0\xAB","Yfr;:\xF0\x9D\x94\x9C", "Yopf;:\xF0\x9D\x95\x90","Yscr;:\xF0\x9D\x92\xB4","Yuml;:\xC5\xB8", "ZHcy;:\xD0\x96","Zacute;:\xC5\xB9","Zcaron;:\xC5\xBD","Zcy;:\xD0\x97", "Zdot;:\xC5\xBB","ZeroWidthSpace;:\xE2\x80\x8B","Zeta;:\xCE\x96", "Zfr;:\xE2\x84\xA8","Zopf;:\xE2\x84\xA4","Zscr;:\xF0\x9D\x92\xB5", "aacute:\xC3\xA1","aacute;:\xC3\xA1","abreve;:\xC4\x83","ac;:\xE2\x88\xBE", "acE;:\xE2\x88\xBE\xCC\xB3","acd;:\xE2\x88\xBF","acirc:\xC3\xA2", "acirc;:\xC3\xA2","acute:\xC2\xB4","acute;:\xC2\xB4","acy;:\xD0\xB0", "aelig:\xC3\xA6","aelig;:\xC3\xA6","af;:\xE2\x81\xA1","afr;:\xF0\x9D\x94\x9E", "agrave:\xC3\xA0","agrave;:\xC3\xA0","alefsym;:\xE2\x84\xB5", "aleph;:\xE2\x84\xB5","alpha;:\xCE\xB1","amacr;:\xC4\x81","amalg;:\xE2\xA8\xBF", "amp:&","amp;:&","and;:\xE2\x88\xA7","andand;:\xE2\xA9\x95", "andd;:\xE2\xA9\x9C","andslope;:\xE2\xA9\x98","andv;:\xE2\xA9\x9A", "ang;:\xE2\x88\xA0","ange;:\xE2\xA6\xA4","angle;:\xE2\x88\xA0", "angmsd;:\xE2\x88\xA1","angmsdaa;:\xE2\xA6\xA8","angmsdab;:\xE2\xA6\xA9", "angmsdac;:\xE2\xA6\xAA","angmsdad;:\xE2\xA6\xAB","angmsdae;:\xE2\xA6\xAC", "angmsdaf;:\xE2\xA6\xAD","angmsdag;:\xE2\xA6\xAE","angmsdah;:\xE2\xA6\xAF", "angrt;:\xE2\x88\x9F","angrtvb;:\xE2\x8A\xBE","angrtvbd;:\xE2\xA6\x9D", "angsph;:\xE2\x88\xA2","angst;:\xC3\x85","angzarr;:\xE2\x8D\xBC", "aogon;:\xC4\x85","aopf;:\xF0\x9D\x95\x92","ap;:\xE2\x89\x88", "apE;:\xE2\xA9\xB0","apacir;:\xE2\xA9\xAF","ape;:\xE2\x89\x8A", "apid;:\xE2\x89\x8B","apos;:\'","approx;:\xE2\x89\x88","approxeq;:\xE2\x89\x8A", "aring:\xC3\xA5","aring;:\xC3\xA5","ascr;:\xF0\x9D\x92\xB6","ast;:*", "asymp;:\xE2\x89\x88","asympeq;:\xE2\x89\x8D","atilde:\xC3\xA3", "atilde;:\xC3\xA3","auml:\xC3\xA4","auml;:\xC3\xA4","awconint;:\xE2\x88\xB3", "awint;:\xE2\xA8\x91","bNot;:\xE2\xAB\xAD","backcong;:\xE2\x89\x8C", "backepsilon;:\xCF\xB6","backprime;:\xE2\x80\xB5","backsim;:\xE2\x88\xBD", "backsimeq;:\xE2\x8B\x8D","barvee;:\xE2\x8A\xBD","barwed;:\xE2\x8C\x85", "barwedge;:\xE2\x8C\x85","bbrk;:\xE2\x8E\xB5","bbrktbrk;:\xE2\x8E\xB6", "bcong;:\xE2\x89\x8C","bcy;:\xD0\xB1","bdquo;:\xE2\x80\x9E", "becaus;:\xE2\x88\xB5","because;:\xE2\x88\xB5","bemptyv;:\xE2\xA6\xB0", "bepsi;:\xCF\xB6","bernou;:\xE2\x84\xAC","beta;:\xCE\xB2","beth;:\xE2\x84\xB6", "between;:\xE2\x89\xAC","bfr;:\xF0\x9D\x94\x9F","bigcap;:\xE2\x8B\x82", "bigcirc;:\xE2\x97\xAF","bigcup;:\xE2\x8B\x83","bigodot;:\xE2\xA8\x80", "bigoplus;:\xE2\xA8\x81","bigotimes;:\xE2\xA8\x82","bigsqcup;:\xE2\xA8\x86", "bigstar;:\xE2\x98\x85","bigtriangledown;:\xE2\x96\xBD", "bigtriangleup;:\xE2\x96\xB3","biguplus;:\xE2\xA8\x84","bigvee;:\xE2\x8B\x81", "bigwedge;:\xE2\x8B\x80","bkarow;:\xE2\xA4\x8D","blacklozenge;:\xE2\xA7\xAB", "blacksquare;:\xE2\x96\xAA","blacktriangle;:\xE2\x96\xB4", "blacktriangledown;:\xE2\x96\xBE","blacktriangleleft;:\xE2\x97\x82", "blacktriangleright;:\xE2\x96\xB8","blank;:\xE2\x90\xA3","blk12;:\xE2\x96\x92", "blk14;:\xE2\x96\x91","blk34;:\xE2\x96\x93","block;:\xE2\x96\x88", "bne;:=\xE2\x83\xA5","bnequiv;:\xE2\x89\xA1\xE2\x83\xA5","bnot;:\xE2\x8C\x90", "bopf;:\xF0\x9D\x95\x93","bot;:\xE2\x8A\xA5","bottom;:\xE2\x8A\xA5", "bowtie;:\xE2\x8B\x88","boxDL;:\xE2\x95\x97","boxDR;:\xE2\x95\x94", "boxDl;:\xE2\x95\x96","boxDr;:\xE2\x95\x93","boxH;:\xE2\x95\x90", "boxHD;:\xE2\x95\xA6","boxHU;:\xE2\x95\xA9","boxHd;:\xE2\x95\xA4", "boxHu;:\xE2\x95\xA7","boxUL;:\xE2\x95\x9D","boxUR;:\xE2\x95\x9A", "boxUl;:\xE2\x95\x9C","boxUr;:\xE2\x95\x99","boxV;:\xE2\x95\x91", "boxVH;:\xE2\x95\xAC","boxVL;:\xE2\x95\xA3","boxVR;:\xE2\x95\xA0", "boxVh;:\xE2\x95\xAB","boxVl;:\xE2\x95\xA2","boxVr;:\xE2\x95\x9F", "boxbox;:\xE2\xA7\x89","boxdL;:\xE2\x95\x95","boxdR;:\xE2\x95\x92", "boxdl;:\xE2\x94\x90","boxdr;:\xE2\x94\x8C","boxh;:\xE2\x94\x80", "boxhD;:\xE2\x95\xA5","boxhU;:\xE2\x95\xA8","boxhd;:\xE2\x94\xAC", "boxhu;:\xE2\x94\xB4","boxminus;:\xE2\x8A\x9F","boxplus;:\xE2\x8A\x9E", "boxtimes;:\xE2\x8A\xA0","boxuL;:\xE2\x95\x9B","boxuR;:\xE2\x95\x98", "boxul;:\xE2\x94\x98","boxur;:\xE2\x94\x94","boxv;:\xE2\x94\x82", "boxvH;:\xE2\x95\xAA","boxvL;:\xE2\x95\xA1","boxvR;:\xE2\x95\x9E", "boxvh;:\xE2\x94\xBC","boxvl;:\xE2\x94\xA4","boxvr;:\xE2\x94\x9C", "bprime;:\xE2\x80\xB5","breve;:\xCB\x98","brvbar:\xC2\xA6","brvbar;:\xC2\xA6", "bscr;:\xF0\x9D\x92\xB7","bsemi;:\xE2\x81\x8F","bsim;:\xE2\x88\xBD", "bsime;:\xE2\x8B\x8D","bsol;:\\","bsolb;:\xE2\xA7\x85","bsolhsub;:\xE2\x9F\x88", "bull;:\xE2\x80\xA2","bullet;:\xE2\x80\xA2","bump;:\xE2\x89\x8E", "bumpE;:\xE2\xAA\xAE","bumpe;:\xE2\x89\x8F","bumpeq;:\xE2\x89\x8F", "cacute;:\xC4\x87","cap;:\xE2\x88\xA9","capand;:\xE2\xA9\x84", "capbrcup;:\xE2\xA9\x89","capcap;:\xE2\xA9\x8B","capcup;:\xE2\xA9\x87", "capdot;:\xE2\xA9\x80","caps;:\xE2\x88\xA9\xEF\xB8\x80","caret;:\xE2\x81\x81", "caron;:\xCB\x87","ccaps;:\xE2\xA9\x8D","ccaron;:\xC4\x8D","ccedil:\xC3\xA7", "ccedil;:\xC3\xA7","ccirc;:\xC4\x89","ccups;:\xE2\xA9\x8C", "ccupssm;:\xE2\xA9\x90","cdot;:\xC4\x8B","cedil:\xC2\xB8","cedil;:\xC2\xB8", "cemptyv;:\xE2\xA6\xB2","cent:\xC2\xA2","cent;:\xC2\xA2","centerdot;:\xC2\xB7", "cfr;:\xF0\x9D\x94\xA0","chcy;:\xD1\x87","check;:\xE2\x9C\x93", "checkmark;:\xE2\x9C\x93","chi;:\xCF\x87","cir;:\xE2\x97\x8B", "cirE;:\xE2\xA7\x83","circ;:\xCB\x86","circeq;:\xE2\x89\x97", "circlearrowleft;:\xE2\x86\xBA","circlearrowright;:\xE2\x86\xBB", "circledR;:\xC2\xAE","circledS;:\xE2\x93\x88","circledast;:\xE2\x8A\x9B", "circledcirc;:\xE2\x8A\x9A","circleddash;:\xE2\x8A\x9D","cire;:\xE2\x89\x97", "cirfnint;:\xE2\xA8\x90","cirmid;:\xE2\xAB\xAF","cirscir;:\xE2\xA7\x82", "clubs;:\xE2\x99\xA3","clubsuit;:\xE2\x99\xA3","colon;::", "colone;:\xE2\x89\x94","coloneq;:\xE2\x89\x94","comma;:,","commat;:@", "comp;:\xE2\x88\x81","compfn;:\xE2\x88\x98","complement;:\xE2\x88\x81", "complexes;:\xE2\x84\x82","cong;:\xE2\x89\x85","congdot;:\xE2\xA9\xAD", "conint;:\xE2\x88\xAE","copf;:\xF0\x9D\x95\x94","coprod;:\xE2\x88\x90", "copy:\xC2\xA9","copy;:\xC2\xA9","copysr;:\xE2\x84\x97","crarr;:\xE2\x86\xB5", "cross;:\xE2\x9C\x97","cscr;:\xF0\x9D\x92\xB8","csub;:\xE2\xAB\x8F", "csube;:\xE2\xAB\x91","csup;:\xE2\xAB\x90","csupe;:\xE2\xAB\x92", "ctdot;:\xE2\x8B\xAF","cudarrl;:\xE2\xA4\xB8","cudarrr;:\xE2\xA4\xB5", "cuepr;:\xE2\x8B\x9E","cuesc;:\xE2\x8B\x9F","cularr;:\xE2\x86\xB6", "cularrp;:\xE2\xA4\xBD","cup;:\xE2\x88\xAA","cupbrcap;:\xE2\xA9\x88", "cupcap;:\xE2\xA9\x86","cupcup;:\xE2\xA9\x8A","cupdot;:\xE2\x8A\x8D", "cupor;:\xE2\xA9\x85","cups;:\xE2\x88\xAA\xEF\xB8\x80","curarr;:\xE2\x86\xB7", "curarrm;:\xE2\xA4\xBC","curlyeqprec;:\xE2\x8B\x9E","curlyeqsucc;:\xE2\x8B\x9F", "curlyvee;:\xE2\x8B\x8E","curlywedge;:\xE2\x8B\x8F","curren:\xC2\xA4", "curren;:\xC2\xA4","curvearrowleft;:\xE2\x86\xB6", "curvearrowright;:\xE2\x86\xB7","cuvee;:\xE2\x8B\x8E","cuwed;:\xE2\x8B\x8F", "cwconint;:\xE2\x88\xB2","cwint;:\xE2\x88\xB1","cylcty;:\xE2\x8C\xAD", "dArr;:\xE2\x87\x93","dHar;:\xE2\xA5\xA5","dagger;:\xE2\x80\xA0", "daleth;:\xE2\x84\xB8","darr;:\xE2\x86\x93","dash;:\xE2\x80\x90", "dashv;:\xE2\x8A\xA3","dbkarow;:\xE2\xA4\x8F","dblac;:\xCB\x9D", "dcaron;:\xC4\x8F","dcy;:\xD0\xB4","dd;:\xE2\x85\x86","ddagger;:\xE2\x80\xA1", "ddarr;:\xE2\x87\x8A","ddotseq;:\xE2\xA9\xB7","deg:\xC2\xB0","deg;:\xC2\xB0", "delta;:\xCE\xB4","demptyv;:\xE2\xA6\xB1","dfisht;:\xE2\xA5\xBF", "dfr;:\xF0\x9D\x94\xA1","dharl;:\xE2\x87\x83","dharr;:\xE2\x87\x82", "diam;:\xE2\x8B\x84","diamond;:\xE2\x8B\x84","diamondsuit;:\xE2\x99\xA6", "diams;:\xE2\x99\xA6","die;:\xC2\xA8","digamma;:\xCF\x9D","disin;:\xE2\x8B\xB2", "div;:\xC3\xB7","divide:\xC3\xB7","divide;:\xC3\xB7", "divideontimes;:\xE2\x8B\x87","divonx;:\xE2\x8B\x87","djcy;:\xD1\x92", "dlcorn;:\xE2\x8C\x9E","dlcrop;:\xE2\x8C\x8D","dollar;:$", "dopf;:\xF0\x9D\x95\x95","dot;:\xCB\x99","doteq;:\xE2\x89\x90", "doteqdot;:\xE2\x89\x91","dotminus;:\xE2\x88\xB8","dotplus;:\xE2\x88\x94", "dotsquare;:\xE2\x8A\xA1","doublebarwedge;:\xE2\x8C\x86", "downarrow;:\xE2\x86\x93","downdownarrows;:\xE2\x87\x8A", "downharpoonleft;:\xE2\x87\x83","downharpoonright;:\xE2\x87\x82", "drbkarow;:\xE2\xA4\x90","drcorn;:\xE2\x8C\x9F","drcrop;:\xE2\x8C\x8C", "dscr;:\xF0\x9D\x92\xB9","dscy;:\xD1\x95","dsol;:\xE2\xA7\xB6", "dstrok;:\xC4\x91","dtdot;:\xE2\x8B\xB1","dtri;:\xE2\x96\xBF", "dtrif;:\xE2\x96\xBE","duarr;:\xE2\x87\xB5","duhar;:\xE2\xA5\xAF", "dwangle;:\xE2\xA6\xA6","dzcy;:\xD1\x9F","dzigrarr;:\xE2\x9F\xBF", "eDDot;:\xE2\xA9\xB7","eDot;:\xE2\x89\x91","eacute:\xC3\xA9","eacute;:\xC3\xA9", "easter;:\xE2\xA9\xAE","ecaron;:\xC4\x9B","ecir;:\xE2\x89\x96","ecirc:\xC3\xAA", "ecirc;:\xC3\xAA","ecolon;:\xE2\x89\x95","ecy;:\xD1\x8D","edot;:\xC4\x97", "ee;:\xE2\x85\x87","efDot;:\xE2\x89\x92","efr;:\xF0\x9D\x94\xA2", "eg;:\xE2\xAA\x9A","egrave:\xC3\xA8","egrave;:\xC3\xA8","egs;:\xE2\xAA\x96", "egsdot;:\xE2\xAA\x98","el;:\xE2\xAA\x99","elinters;:\xE2\x8F\xA7", "ell;:\xE2\x84\x93","els;:\xE2\xAA\x95","elsdot;:\xE2\xAA\x97", "emacr;:\xC4\x93","empty;:\xE2\x88\x85","emptyset;:\xE2\x88\x85", "emptyv;:\xE2\x88\x85","emsp13;:\xE2\x80\x84","emsp14;:\xE2\x80\x85", "emsp;:\xE2\x80\x83","eng;:\xC5\x8B","ensp;:\xE2\x80\x82","eogon;:\xC4\x99", "eopf;:\xF0\x9D\x95\x96","epar;:\xE2\x8B\x95","eparsl;:\xE2\xA7\xA3", "eplus;:\xE2\xA9\xB1","epsi;:\xCE\xB5","epsilon;:\xCE\xB5","epsiv;:\xCF\xB5", "eqcirc;:\xE2\x89\x96","eqcolon;:\xE2\x89\x95","eqsim;:\xE2\x89\x82", "eqslantgtr;:\xE2\xAA\x96","eqslantless;:\xE2\xAA\x95","equals;:=", "equest;:\xE2\x89\x9F","equiv;:\xE2\x89\xA1","equivDD;:\xE2\xA9\xB8", "eqvparsl;:\xE2\xA7\xA5","erDot;:\xE2\x89\x93","erarr;:\xE2\xA5\xB1", "escr;:\xE2\x84\xAF","esdot;:\xE2\x89\x90","esim;:\xE2\x89\x82","eta;:\xCE\xB7", "eth:\xC3\xB0","eth;:\xC3\xB0","euml:\xC3\xAB","euml;:\xC3\xAB", "euro;:\xE2\x82\xAC","excl;:!","exist;:\xE2\x88\x83", "expectation;:\xE2\x84\xB0","exponentiale;:\xE2\x85\x87", "fallingdotseq;:\xE2\x89\x92","fcy;:\xD1\x84","female;:\xE2\x99\x80", "ffilig;:\xEF\xAC\x83","fflig;:\xEF\xAC\x80","ffllig;:\xEF\xAC\x84", "ffr;:\xF0\x9D\x94\xA3","filig;:\xEF\xAC\x81","fjlig;:fj","flat;:\xE2\x99\xAD", "fllig;:\xEF\xAC\x82","fltns;:\xE2\x96\xB1","fnof;:\xC6\x92", "fopf;:\xF0\x9D\x95\x97","forall;:\xE2\x88\x80","fork;:\xE2\x8B\x94", "forkv;:\xE2\xAB\x99","fpartint;:\xE2\xA8\x8D","frac12:\xC2\xBD", "frac12;:\xC2\xBD","frac13;:\xE2\x85\x93","frac14:\xC2\xBC","frac14;:\xC2\xBC", "frac15;:\xE2\x85\x95","frac16;:\xE2\x85\x99","frac18;:\xE2\x85\x9B", "frac23;:\xE2\x85\x94","frac25;:\xE2\x85\x96","frac34:\xC2\xBE", "frac34;:\xC2\xBE","frac35;:\xE2\x85\x97","frac38;:\xE2\x85\x9C", "frac45;:\xE2\x85\x98","frac56;:\xE2\x85\x9A","frac58;:\xE2\x85\x9D", "frac78;:\xE2\x85\x9E","frasl;:\xE2\x81\x84","frown;:\xE2\x8C\xA2", "fscr;:\xF0\x9D\x92\xBB","gE;:\xE2\x89\xA7","gEl;:\xE2\xAA\x8C", "gacute;:\xC7\xB5","gamma;:\xCE\xB3","gammad;:\xCF\x9D","gap;:\xE2\xAA\x86", "gbreve;:\xC4\x9F","gcirc;:\xC4\x9D","gcy;:\xD0\xB3","gdot;:\xC4\xA1", "ge;:\xE2\x89\xA5","gel;:\xE2\x8B\x9B","geq;:\xE2\x89\xA5","geqq;:\xE2\x89\xA7", "geqslant;:\xE2\xA9\xBE","ges;:\xE2\xA9\xBE","gescc;:\xE2\xAA\xA9", "gesdot;:\xE2\xAA\x80","gesdoto;:\xE2\xAA\x82","gesdotol;:\xE2\xAA\x84", "gesl;:\xE2\x8B\x9B\xEF\xB8\x80","gesles;:\xE2\xAA\x94","gfr;:\xF0\x9D\x94\xA4", "gg;:\xE2\x89\xAB","ggg;:\xE2\x8B\x99","gimel;:\xE2\x84\xB7","gjcy;:\xD1\x93", "gl;:\xE2\x89\xB7","glE;:\xE2\xAA\x92","gla;:\xE2\xAA\xA5","glj;:\xE2\xAA\xA4", "gnE;:\xE2\x89\xA9","gnap;:\xE2\xAA\x8A","gnapprox;:\xE2\xAA\x8A", "gne;:\xE2\xAA\x88","gneq;:\xE2\xAA\x88","gneqq;:\xE2\x89\xA9", "gnsim;:\xE2\x8B\xA7","gopf;:\xF0\x9D\x95\x98","grave;:`","gscr;:\xE2\x84\x8A", "gsim;:\xE2\x89\xB3","gsime;:\xE2\xAA\x8E","gsiml;:\xE2\xAA\x90","gt:>","gt;:>", "gtcc;:\xE2\xAA\xA7","gtcir;:\xE2\xA9\xBA","gtdot;:\xE2\x8B\x97", "gtlPar;:\xE2\xA6\x95","gtquest;:\xE2\xA9\xBC","gtrapprox;:\xE2\xAA\x86", "gtrarr;:\xE2\xA5\xB8","gtrdot;:\xE2\x8B\x97","gtreqless;:\xE2\x8B\x9B", "gtreqqless;:\xE2\xAA\x8C","gtrless;:\xE2\x89\xB7","gtrsim;:\xE2\x89\xB3", "gvertneqq;:\xE2\x89\xA9\xEF\xB8\x80","gvnE;:\xE2\x89\xA9\xEF\xB8\x80", "hArr;:\xE2\x87\x94","hairsp;:\xE2\x80\x8A","half;:\xC2\xBD", "hamilt;:\xE2\x84\x8B","hardcy;:\xD1\x8A","harr;:\xE2\x86\x94", "harrcir;:\xE2\xA5\x88","harrw;:\xE2\x86\xAD","hbar;:\xE2\x84\x8F", "hcirc;:\xC4\xA5","hearts;:\xE2\x99\xA5","heartsuit;:\xE2\x99\xA5", "hellip;:\xE2\x80\xA6","hercon;:\xE2\x8A\xB9","hfr;:\xF0\x9D\x94\xA5", "hksearow;:\xE2\xA4\xA5","hkswarow;:\xE2\xA4\xA6","hoarr;:\xE2\x87\xBF", "homtht;:\xE2\x88\xBB","hookleftarrow;:\xE2\x86\xA9", "hookrightarrow;:\xE2\x86\xAA","hopf;:\xF0\x9D\x95\x99","horbar;:\xE2\x80\x95", "hscr;:\xF0\x9D\x92\xBD","hslash;:\xE2\x84\x8F","hstrok;:\xC4\xA7", "hybull;:\xE2\x81\x83","hyphen;:\xE2\x80\x90","iacute:\xC3\xAD", "iacute;:\xC3\xAD","ic;:\xE2\x81\xA3","icirc:\xC3\xAE","icirc;:\xC3\xAE", "icy;:\xD0\xB8","iecy;:\xD0\xB5","iexcl:\xC2\xA1","iexcl;:\xC2\xA1", "iff;:\xE2\x87\x94","ifr;:\xF0\x9D\x94\xA6","igrave:\xC3\xAC", "igrave;:\xC3\xAC","ii;:\xE2\x85\x88","iiiint;:\xE2\xA8\x8C", "iiint;:\xE2\x88\xAD","iinfin;:\xE2\xA7\x9C","iiota;:\xE2\x84\xA9", "ijlig;:\xC4\xB3","imacr;:\xC4\xAB","image;:\xE2\x84\x91", "imagline;:\xE2\x84\x90","imagpart;:\xE2\x84\x91","imath;:\xC4\xB1", "imof;:\xE2\x8A\xB7","imped;:\xC6\xB5","in;:\xE2\x88\x88", "incare;:\xE2\x84\x85","infin;:\xE2\x88\x9E","infintie;:\xE2\xA7\x9D", "inodot;:\xC4\xB1","int;:\xE2\x88\xAB","intcal;:\xE2\x8A\xBA", "integers;:\xE2\x84\xA4","intercal;:\xE2\x8A\xBA","intlarhk;:\xE2\xA8\x97", "intprod;:\xE2\xA8\xBC","iocy;:\xD1\x91","iogon;:\xC4\xAF", "iopf;:\xF0\x9D\x95\x9A","iota;:\xCE\xB9","iprod;:\xE2\xA8\xBC", "iquest:\xC2\xBF","iquest;:\xC2\xBF","iscr;:\xF0\x9D\x92\xBE", "isin;:\xE2\x88\x88","isinE;:\xE2\x8B\xB9","isindot;:\xE2\x8B\xB5", "isins;:\xE2\x8B\xB4","isinsv;:\xE2\x8B\xB3","isinv;:\xE2\x88\x88", "it;:\xE2\x81\xA2","itilde;:\xC4\xA9","iukcy;:\xD1\x96","iuml:\xC3\xAF", "iuml;:\xC3\xAF","jcirc;:\xC4\xB5","jcy;:\xD0\xB9","jfr;:\xF0\x9D\x94\xA7", "jmath;:\xC8\xB7","jopf;:\xF0\x9D\x95\x9B","jscr;:\xF0\x9D\x92\xBF", "jsercy;:\xD1\x98","jukcy;:\xD1\x94","kappa;:\xCE\xBA","kappav;:\xCF\xB0", "kcedil;:\xC4\xB7","kcy;:\xD0\xBA","kfr;:\xF0\x9D\x94\xA8","kgreen;:\xC4\xB8", "khcy;:\xD1\x85","kjcy;:\xD1\x9C","kopf;:\xF0\x9D\x95\x9C", "kscr;:\xF0\x9D\x93\x80","lAarr;:\xE2\x87\x9A","lArr;:\xE2\x87\x90", "lAtail;:\xE2\xA4\x9B","lBarr;:\xE2\xA4\x8E","lE;:\xE2\x89\xA6", "lEg;:\xE2\xAA\x8B","lHar;:\xE2\xA5\xA2","lacute;:\xC4\xBA", "laemptyv;:\xE2\xA6\xB4","lagran;:\xE2\x84\x92","lambda;:\xCE\xBB", "lang;:\xE2\x9F\xA8","langd;:\xE2\xA6\x91","langle;:\xE2\x9F\xA8", "lap;:\xE2\xAA\x85","laquo:\xC2\xAB","laquo;:\xC2\xAB","larr;:\xE2\x86\x90", "larrb;:\xE2\x87\xA4","larrbfs;:\xE2\xA4\x9F","larrfs;:\xE2\xA4\x9D", "larrhk;:\xE2\x86\xA9","larrlp;:\xE2\x86\xAB","larrpl;:\xE2\xA4\xB9", "larrsim;:\xE2\xA5\xB3","larrtl;:\xE2\x86\xA2","lat;:\xE2\xAA\xAB", "latail;:\xE2\xA4\x99","late;:\xE2\xAA\xAD","lates;:\xE2\xAA\xAD\xEF\xB8\x80", "lbarr;:\xE2\xA4\x8C","lbbrk;:\xE2\x9D\xB2","lbrace;:{","lbrack;:[", "lbrke;:\xE2\xA6\x8B","lbrksld;:\xE2\xA6\x8F","lbrkslu;:\xE2\xA6\x8D", "lcaron;:\xC4\xBE","lcedil;:\xC4\xBC","lceil;:\xE2\x8C\x88","lcub;:{", "lcy;:\xD0\xBB","ldca;:\xE2\xA4\xB6","ldquo;:\xE2\x80\x9C", "ldquor;:\xE2\x80\x9E","ldrdhar;:\xE2\xA5\xA7","ldrushar;:\xE2\xA5\x8B", "ldsh;:\xE2\x86\xB2","le;:\xE2\x89\xA4","leftarrow;:\xE2\x86\x90", "leftarrowtail;:\xE2\x86\xA2","leftharpoondown;:\xE2\x86\xBD", "leftharpoonup;:\xE2\x86\xBC","leftleftarrows;:\xE2\x87\x87", "leftrightarrow;:\xE2\x86\x94","leftrightarrows;:\xE2\x87\x86", "leftrightharpoons;:\xE2\x87\x8B","leftrightsquigarrow;:\xE2\x86\xAD", "leftthreetimes;:\xE2\x8B\x8B","leg;:\xE2\x8B\x9A","leq;:\xE2\x89\xA4", "leqq;:\xE2\x89\xA6","leqslant;:\xE2\xA9\xBD","les;:\xE2\xA9\xBD", "lescc;:\xE2\xAA\xA8","lesdot;:\xE2\xA9\xBF","lesdoto;:\xE2\xAA\x81", "lesdotor;:\xE2\xAA\x83","lesg;:\xE2\x8B\x9A\xEF\xB8\x80", "lesges;:\xE2\xAA\x93","lessapprox;:\xE2\xAA\x85","lessdot;:\xE2\x8B\x96", "lesseqgtr;:\xE2\x8B\x9A","lesseqqgtr;:\xE2\xAA\x8B","lessgtr;:\xE2\x89\xB6", "lesssim;:\xE2\x89\xB2","lfisht;:\xE2\xA5\xBC","lfloor;:\xE2\x8C\x8A", "lfr;:\xF0\x9D\x94\xA9","lg;:\xE2\x89\xB6","lgE;:\xE2\xAA\x91", "lhard;:\xE2\x86\xBD","lharu;:\xE2\x86\xBC","lharul;:\xE2\xA5\xAA", "lhblk;:\xE2\x96\x84","ljcy;:\xD1\x99","ll;:\xE2\x89\xAA","llarr;:\xE2\x87\x87", "llcorner;:\xE2\x8C\x9E","llhard;:\xE2\xA5\xAB","lltri;:\xE2\x97\xBA", "lmidot;:\xC5\x80","lmoust;:\xE2\x8E\xB0","lmoustache;:\xE2\x8E\xB0", "lnE;:\xE2\x89\xA8","lnap;:\xE2\xAA\x89","lnapprox;:\xE2\xAA\x89", "lne;:\xE2\xAA\x87","lneq;:\xE2\xAA\x87","lneqq;:\xE2\x89\xA8", "lnsim;:\xE2\x8B\xA6","loang;:\xE2\x9F\xAC","loarr;:\xE2\x87\xBD", "lobrk;:\xE2\x9F\xA6","longleftarrow;:\xE2\x9F\xB5", "longleftrightarrow;:\xE2\x9F\xB7","longmapsto;:\xE2\x9F\xBC", "longrightarrow;:\xE2\x9F\xB6","looparrowleft;:\xE2\x86\xAB", "looparrowright;:\xE2\x86\xAC","lopar;:\xE2\xA6\x85","lopf;:\xF0\x9D\x95\x9D", "loplus;:\xE2\xA8\xAD","lotimes;:\xE2\xA8\xB4","lowast;:\xE2\x88\x97", "lowbar;:_","loz;:\xE2\x97\x8A","lozenge;:\xE2\x97\x8A","lozf;:\xE2\xA7\xAB", "lpar;:(","lparlt;:\xE2\xA6\x93","lrarr;:\xE2\x87\x86","lrcorner;:\xE2\x8C\x9F", "lrhar;:\xE2\x87\x8B","lrhard;:\xE2\xA5\xAD","lrm;:\xE2\x80\x8E", "lrtri;:\xE2\x8A\xBF","lsaquo;:\xE2\x80\xB9","lscr;:\xF0\x9D\x93\x81", "lsh;:\xE2\x86\xB0","lsim;:\xE2\x89\xB2","lsime;:\xE2\xAA\x8D", "lsimg;:\xE2\xAA\x8F","lsqb;:[","lsquo;:\xE2\x80\x98","lsquor;:\xE2\x80\x9A", "lstrok;:\xC5\x82","lt:<","lt;:<","ltcc;:\xE2\xAA\xA6","ltcir;:\xE2\xA9\xB9", "ltdot;:\xE2\x8B\x96","lthree;:\xE2\x8B\x8B","ltimes;:\xE2\x8B\x89", "ltlarr;:\xE2\xA5\xB6","ltquest;:\xE2\xA9\xBB","ltrPar;:\xE2\xA6\x96", "ltri;:\xE2\x97\x83","ltrie;:\xE2\x8A\xB4","ltrif;:\xE2\x97\x82", "lurdshar;:\xE2\xA5\x8A","luruhar;:\xE2\xA5\xA6", "lvertneqq;:\xE2\x89\xA8\xEF\xB8\x80","lvnE;:\xE2\x89\xA8\xEF\xB8\x80", "mDDot;:\xE2\x88\xBA","macr:\xC2\xAF","macr;:\xC2\xAF","male;:\xE2\x99\x82", "malt;:\xE2\x9C\xA0","maltese;:\xE2\x9C\xA0","map;:\xE2\x86\xA6", "mapsto;:\xE2\x86\xA6","mapstodown;:\xE2\x86\xA7","mapstoleft;:\xE2\x86\xA4", "mapstoup;:\xE2\x86\xA5","marker;:\xE2\x96\xAE","mcomma;:\xE2\xA8\xA9", "mcy;:\xD0\xBC","mdash;:\xE2\x80\x94","measuredangle;:\xE2\x88\xA1", "mfr;:\xF0\x9D\x94\xAA","mho;:\xE2\x84\xA7","micro:\xC2\xB5","micro;:\xC2\xB5", "mid;:\xE2\x88\xA3","midast;:*","midcir;:\xE2\xAB\xB0","middot:\xC2\xB7", "middot;:\xC2\xB7","minus;:\xE2\x88\x92","minusb;:\xE2\x8A\x9F", "minusd;:\xE2\x88\xB8","minusdu;:\xE2\xA8\xAA","mlcp;:\xE2\xAB\x9B", "mldr;:\xE2\x80\xA6","mnplus;:\xE2\x88\x93","models;:\xE2\x8A\xA7", "mopf;:\xF0\x9D\x95\x9E","mp;:\xE2\x88\x93","mscr;:\xF0\x9D\x93\x82", "mstpos;:\xE2\x88\xBE","mu;:\xCE\xBC","multimap;:\xE2\x8A\xB8", "mumap;:\xE2\x8A\xB8","nGg;:\xE2\x8B\x99\xCC\xB8", "nGt;:\xE2\x89\xAB\xE2\x83\x92","nGtv;:\xE2\x89\xAB\xCC\xB8", "nLeftarrow;:\xE2\x87\x8D","nLeftrightarrow;:\xE2\x87\x8E", "nLl;:\xE2\x8B\x98\xCC\xB8","nLt;:\xE2\x89\xAA\xE2\x83\x92", "nLtv;:\xE2\x89\xAA\xCC\xB8","nRightarrow;:\xE2\x87\x8F","nVDash;:\xE2\x8A\xAF", "nVdash;:\xE2\x8A\xAE","nabla;:\xE2\x88\x87","nacute;:\xC5\x84", "nang;:\xE2\x88\xA0\xE2\x83\x92","nap;:\xE2\x89\x89", "napE;:\xE2\xA9\xB0\xCC\xB8","napid;:\xE2\x89\x8B\xCC\xB8","napos;:\xC5\x89", "napprox;:\xE2\x89\x89","natur;:\xE2\x99\xAE","natural;:\xE2\x99\xAE", "naturals;:\xE2\x84\x95","nbsp:\xC2\xA0","nbsp;:\xC2\xA0", "nbump;:\xE2\x89\x8E\xCC\xB8","nbumpe;:\xE2\x89\x8F\xCC\xB8", "ncap;:\xE2\xA9\x83","ncaron;:\xC5\x88","ncedil;:\xC5\x86", "ncong;:\xE2\x89\x87","ncongdot;:\xE2\xA9\xAD\xCC\xB8","ncup;:\xE2\xA9\x82", "ncy;:\xD0\xBD","ndash;:\xE2\x80\x93","ne;:\xE2\x89\xA0","neArr;:\xE2\x87\x97", "nearhk;:\xE2\xA4\xA4","nearr;:\xE2\x86\x97","nearrow;:\xE2\x86\x97", "nedot;:\xE2\x89\x90\xCC\xB8","nequiv;:\xE2\x89\xA2","nesear;:\xE2\xA4\xA8", "nesim;:\xE2\x89\x82\xCC\xB8","nexist;:\xE2\x88\x84","nexists;:\xE2\x88\x84", "nfr;:\xF0\x9D\x94\xAB","ngE;:\xE2\x89\xA7\xCC\xB8","nge;:\xE2\x89\xB1", "ngeq;:\xE2\x89\xB1","ngeqq;:\xE2\x89\xA7\xCC\xB8", "ngeqslant;:\xE2\xA9\xBE\xCC\xB8","nges;:\xE2\xA9\xBE\xCC\xB8", "ngsim;:\xE2\x89\xB5","ngt;:\xE2\x89\xAF","ngtr;:\xE2\x89\xAF", "nhArr;:\xE2\x87\x8E","nharr;:\xE2\x86\xAE","nhpar;:\xE2\xAB\xB2", "ni;:\xE2\x88\x8B","nis;:\xE2\x8B\xBC","nisd;:\xE2\x8B\xBA","niv;:\xE2\x88\x8B", "njcy;:\xD1\x9A","nlArr;:\xE2\x87\x8D","nlE;:\xE2\x89\xA6\xCC\xB8", "nlarr;:\xE2\x86\x9A","nldr;:\xE2\x80\xA5","nle;:\xE2\x89\xB0", "nleftarrow;:\xE2\x86\x9A","nleftrightarrow;:\xE2\x86\xAE","nleq;:\xE2\x89\xB0", "nleqq;:\xE2\x89\xA6\xCC\xB8","nleqslant;:\xE2\xA9\xBD\xCC\xB8", "nles;:\xE2\xA9\xBD\xCC\xB8","nless;:\xE2\x89\xAE","nlsim;:\xE2\x89\xB4", "nlt;:\xE2\x89\xAE","nltri;:\xE2\x8B\xAA","nltrie;:\xE2\x8B\xAC", "nmid;:\xE2\x88\xA4","nopf;:\xF0\x9D\x95\x9F","not:\xC2\xAC","not;:\xC2\xAC", "notin;:\xE2\x88\x89","notinE;:\xE2\x8B\xB9\xCC\xB8", "notindot;:\xE2\x8B\xB5\xCC\xB8","notinva;:\xE2\x88\x89", "notinvb;:\xE2\x8B\xB7","notinvc;:\xE2\x8B\xB6","notni;:\xE2\x88\x8C", "notniva;:\xE2\x88\x8C","notnivb;:\xE2\x8B\xBE","notnivc;:\xE2\x8B\xBD", "npar;:\xE2\x88\xA6","nparallel;:\xE2\x88\xA6", "nparsl;:\xE2\xAB\xBD\xE2\x83\xA5","npart;:\xE2\x88\x82\xCC\xB8", "npolint;:\xE2\xA8\x94","npr;:\xE2\x8A\x80","nprcue;:\xE2\x8B\xA0", "npre;:\xE2\xAA\xAF\xCC\xB8","nprec;:\xE2\x8A\x80", "npreceq;:\xE2\xAA\xAF\xCC\xB8","nrArr;:\xE2\x87\x8F","nrarr;:\xE2\x86\x9B", "nrarrc;:\xE2\xA4\xB3\xCC\xB8","nrarrw;:\xE2\x86\x9D\xCC\xB8", "nrightarrow;:\xE2\x86\x9B","nrtri;:\xE2\x8B\xAB","nrtrie;:\xE2\x8B\xAD", "nsc;:\xE2\x8A\x81","nsccue;:\xE2\x8B\xA1","nsce;:\xE2\xAA\xB0\xCC\xB8", "nscr;:\xF0\x9D\x93\x83","nshortmid;:\xE2\x88\xA4", "nshortparallel;:\xE2\x88\xA6","nsim;:\xE2\x89\x81","nsime;:\xE2\x89\x84", "nsimeq;:\xE2\x89\x84","nsmid;:\xE2\x88\xA4","nspar;:\xE2\x88\xA6", "nsqsube;:\xE2\x8B\xA2","nsqsupe;:\xE2\x8B\xA3","nsub;:\xE2\x8A\x84", "nsubE;:\xE2\xAB\x85\xCC\xB8","nsube;:\xE2\x8A\x88", "nsubset;:\xE2\x8A\x82\xE2\x83\x92","nsubseteq;:\xE2\x8A\x88", "nsubseteqq;:\xE2\xAB\x85\xCC\xB8","nsucc;:\xE2\x8A\x81", "nsucceq;:\xE2\xAA\xB0\xCC\xB8","nsup;:\xE2\x8A\x85", "nsupE;:\xE2\xAB\x86\xCC\xB8","nsupe;:\xE2\x8A\x89", "nsupset;:\xE2\x8A\x83\xE2\x83\x92","nsupseteq;:\xE2\x8A\x89", "nsupseteqq;:\xE2\xAB\x86\xCC\xB8","ntgl;:\xE2\x89\xB9","ntilde:\xC3\xB1", "ntilde;:\xC3\xB1","ntlg;:\xE2\x89\xB8","ntriangleleft;:\xE2\x8B\xAA", "ntrianglelefteq;:\xE2\x8B\xAC","ntriangleright;:\xE2\x8B\xAB", "ntrianglerighteq;:\xE2\x8B\xAD","nu;:\xCE\xBD","num;:#","numero;:\xE2\x84\x96", "numsp;:\xE2\x80\x87","nvDash;:\xE2\x8A\xAD","nvHarr;:\xE2\xA4\x84", "nvap;:\xE2\x89\x8D\xE2\x83\x92","nvdash;:\xE2\x8A\xAC", "nvge;:\xE2\x89\xA5\xE2\x83\x92","nvgt;:>\xE2\x83\x92","nvinfin;:\xE2\xA7\x9E", "nvlArr;:\xE2\xA4\x82","nvle;:\xE2\x89\xA4\xE2\x83\x92","nvlt;:<\xE2\x83\x92", "nvltrie;:\xE2\x8A\xB4\xE2\x83\x92","nvrArr;:\xE2\xA4\x83", "nvrtrie;:\xE2\x8A\xB5\xE2\x83\x92","nvsim;:\xE2\x88\xBC\xE2\x83\x92", "nwArr;:\xE2\x87\x96","nwarhk;:\xE2\xA4\xA3","nwarr;:\xE2\x86\x96", "nwarrow;:\xE2\x86\x96","nwnear;:\xE2\xA4\xA7","oS;:\xE2\x93\x88", "oacute:\xC3\xB3","oacute;:\xC3\xB3","oast;:\xE2\x8A\x9B","ocir;:\xE2\x8A\x9A", "ocirc:\xC3\xB4","ocirc;:\xC3\xB4","ocy;:\xD0\xBE","odash;:\xE2\x8A\x9D", "odblac;:\xC5\x91","odiv;:\xE2\xA8\xB8","odot;:\xE2\x8A\x99", "odsold;:\xE2\xA6\xBC","oelig;:\xC5\x93","ofcir;:\xE2\xA6\xBF", "ofr;:\xF0\x9D\x94\xAC","ogon;:\xCB\x9B","ograve:\xC3\xB2","ograve;:\xC3\xB2", "ogt;:\xE2\xA7\x81","ohbar;:\xE2\xA6\xB5","ohm;:\xCE\xA9","oint;:\xE2\x88\xAE", "olarr;:\xE2\x86\xBA","olcir;:\xE2\xA6\xBE","olcross;:\xE2\xA6\xBB", "oline;:\xE2\x80\xBE","olt;:\xE2\xA7\x80","omacr;:\xC5\x8D","omega;:\xCF\x89", "omicron;:\xCE\xBF","omid;:\xE2\xA6\xB6","ominus;:\xE2\x8A\x96", "oopf;:\xF0\x9D\x95\xA0","opar;:\xE2\xA6\xB7","operp;:\xE2\xA6\xB9", "oplus;:\xE2\x8A\x95","or;:\xE2\x88\xA8","orarr;:\xE2\x86\xBB", "ord;:\xE2\xA9\x9D","order;:\xE2\x84\xB4","orderof;:\xE2\x84\xB4", "ordf:\xC2\xAA","ordf;:\xC2\xAA","ordm:\xC2\xBA","ordm;:\xC2\xBA", "origof;:\xE2\x8A\xB6","oror;:\xE2\xA9\x96","orslope;:\xE2\xA9\x97", "orv;:\xE2\xA9\x9B","oscr;:\xE2\x84\xB4","oslash:\xC3\xB8","oslash;:\xC3\xB8", "osol;:\xE2\x8A\x98","otilde:\xC3\xB5","otilde;:\xC3\xB5", "otimes;:\xE2\x8A\x97","otimesas;:\xE2\xA8\xB6","ouml:\xC3\xB6", "ouml;:\xC3\xB6","ovbar;:\xE2\x8C\xBD","par;:\xE2\x88\xA5","para:\xC2\xB6", "para;:\xC2\xB6","parallel;:\xE2\x88\xA5","parsim;:\xE2\xAB\xB3", "parsl;:\xE2\xAB\xBD","part;:\xE2\x88\x82","pcy;:\xD0\xBF","percnt;:%", "period;:.","permil;:\xE2\x80\xB0","perp;:\xE2\x8A\xA5","pertenk;:\xE2\x80\xB1", "pfr;:\xF0\x9D\x94\xAD","phi;:\xCF\x86","phiv;:\xCF\x95","phmmat;:\xE2\x84\xB3", "phone;:\xE2\x98\x8E","pi;:\xCF\x80","pitchfork;:\xE2\x8B\x94","piv;:\xCF\x96", "planck;:\xE2\x84\x8F","planckh;:\xE2\x84\x8E","plankv;:\xE2\x84\x8F","plus;:+", "plusacir;:\xE2\xA8\xA3","plusb;:\xE2\x8A\x9E","pluscir;:\xE2\xA8\xA2", "plusdo;:\xE2\x88\x94","plusdu;:\xE2\xA8\xA5","pluse;:\xE2\xA9\xB2", "plusmn:\xC2\xB1","plusmn;:\xC2\xB1","plussim;:\xE2\xA8\xA6", "plustwo;:\xE2\xA8\xA7","pm;:\xC2\xB1","pointint;:\xE2\xA8\x95", "popf;:\xF0\x9D\x95\xA1","pound:\xC2\xA3","pound;:\xC2\xA3","pr;:\xE2\x89\xBA", "prE;:\xE2\xAA\xB3","prap;:\xE2\xAA\xB7","prcue;:\xE2\x89\xBC", "pre;:\xE2\xAA\xAF","prec;:\xE2\x89\xBA","precapprox;:\xE2\xAA\xB7", "preccurlyeq;:\xE2\x89\xBC","preceq;:\xE2\xAA\xAF","precnapprox;:\xE2\xAA\xB9", "precneqq;:\xE2\xAA\xB5","precnsim;:\xE2\x8B\xA8","precsim;:\xE2\x89\xBE", "prime;:\xE2\x80\xB2","primes;:\xE2\x84\x99","prnE;:\xE2\xAA\xB5", "prnap;:\xE2\xAA\xB9","prnsim;:\xE2\x8B\xA8","prod;:\xE2\x88\x8F", "profalar;:\xE2\x8C\xAE","profline;:\xE2\x8C\x92","profsurf;:\xE2\x8C\x93", "prop;:\xE2\x88\x9D","propto;:\xE2\x88\x9D","prsim;:\xE2\x89\xBE", "prurel;:\xE2\x8A\xB0","pscr;:\xF0\x9D\x93\x85","psi;:\xCF\x88", "puncsp;:\xE2\x80\x88","qfr;:\xF0\x9D\x94\xAE","qint;:\xE2\xA8\x8C", "qopf;:\xF0\x9D\x95\xA2","qprime;:\xE2\x81\x97","qscr;:\xF0\x9D\x93\x86", "quaternions;:\xE2\x84\x8D","quatint;:\xE2\xA8\x96","quest;:?", "questeq;:\xE2\x89\x9F","quot:\"","quot;:\"","rAarr;:\xE2\x87\x9B", "rArr;:\xE2\x87\x92","rAtail;:\xE2\xA4\x9C","rBarr;:\xE2\xA4\x8F", "rHar;:\xE2\xA5\xA4","race;:\xE2\x88\xBD\xCC\xB1","racute;:\xC5\x95", "radic;:\xE2\x88\x9A","raemptyv;:\xE2\xA6\xB3","rang;:\xE2\x9F\xA9", "rangd;:\xE2\xA6\x92","range;:\xE2\xA6\xA5","rangle;:\xE2\x9F\xA9", "raquo:\xC2\xBB","raquo;:\xC2\xBB","rarr;:\xE2\x86\x92","rarrap;:\xE2\xA5\xB5", "rarrb;:\xE2\x87\xA5","rarrbfs;:\xE2\xA4\xA0","rarrc;:\xE2\xA4\xB3", "rarrfs;:\xE2\xA4\x9E","rarrhk;:\xE2\x86\xAA","rarrlp;:\xE2\x86\xAC", "rarrpl;:\xE2\xA5\x85","rarrsim;:\xE2\xA5\xB4","rarrtl;:\xE2\x86\xA3", "rarrw;:\xE2\x86\x9D","ratail;:\xE2\xA4\x9A","ratio;:\xE2\x88\xB6", "rationals;:\xE2\x84\x9A","rbarr;:\xE2\xA4\x8D","rbbrk;:\xE2\x9D\xB3", "rbrace;:}","rbrack;:]","rbrke;:\xE2\xA6\x8C","rbrksld;:\xE2\xA6\x8E", "rbrkslu;:\xE2\xA6\x90","rcaron;:\xC5\x99","rcedil;:\xC5\x97", "rceil;:\xE2\x8C\x89","rcub;:}","rcy;:\xD1\x80","rdca;:\xE2\xA4\xB7", "rdldhar;:\xE2\xA5\xA9","rdquo;:\xE2\x80\x9D","rdquor;:\xE2\x80\x9D", "rdsh;:\xE2\x86\xB3","real;:\xE2\x84\x9C","realine;:\xE2\x84\x9B", "realpart;:\xE2\x84\x9C","reals;:\xE2\x84\x9D","rect;:\xE2\x96\xAD", "reg:\xC2\xAE","reg;:\xC2\xAE","rfisht;:\xE2\xA5\xBD","rfloor;:\xE2\x8C\x8B", "rfr;:\xF0\x9D\x94\xAF","rhard;:\xE2\x87\x81","rharu;:\xE2\x87\x80", "rharul;:\xE2\xA5\xAC","rho;:\xCF\x81","rhov;:\xCF\xB1", "rightarrow;:\xE2\x86\x92","rightarrowtail;:\xE2\x86\xA3", "rightharpoondown;:\xE2\x87\x81","rightharpoonup;:\xE2\x87\x80", "rightleftarrows;:\xE2\x87\x84","rightleftharpoons;:\xE2\x87\x8C", "rightrightarrows;:\xE2\x87\x89","rightsquigarrow;:\xE2\x86\x9D", "rightthreetimes;:\xE2\x8B\x8C","ring;:\xCB\x9A","risingdotseq;:\xE2\x89\x93", "rlarr;:\xE2\x87\x84","rlhar;:\xE2\x87\x8C","rlm;:\xE2\x80\x8F", "rmoust;:\xE2\x8E\xB1","rmoustache;:\xE2\x8E\xB1","rnmid;:\xE2\xAB\xAE", "roang;:\xE2\x9F\xAD","roarr;:\xE2\x87\xBE","robrk;:\xE2\x9F\xA7", "ropar;:\xE2\xA6\x86","ropf;:\xF0\x9D\x95\xA3","roplus;:\xE2\xA8\xAE", "rotimes;:\xE2\xA8\xB5","rpar;:)","rpargt;:\xE2\xA6\x94", "rppolint;:\xE2\xA8\x92","rrarr;:\xE2\x87\x89","rsaquo;:\xE2\x80\xBA", "rscr;:\xF0\x9D\x93\x87","rsh;:\xE2\x86\xB1","rsqb;:]","rsquo;:\xE2\x80\x99", "rsquor;:\xE2\x80\x99","rthree;:\xE2\x8B\x8C","rtimes;:\xE2\x8B\x8A", "rtri;:\xE2\x96\xB9","rtrie;:\xE2\x8A\xB5","rtrif;:\xE2\x96\xB8", "rtriltri;:\xE2\xA7\x8E","ruluhar;:\xE2\xA5\xA8","rx;:\xE2\x84\x9E", "sacute;:\xC5\x9B","sbquo;:\xE2\x80\x9A","sc;:\xE2\x89\xBB","scE;:\xE2\xAA\xB4", "scap;:\xE2\xAA\xB8","scaron;:\xC5\xA1","sccue;:\xE2\x89\xBD", "sce;:\xE2\xAA\xB0","scedil;:\xC5\x9F","scirc;:\xC5\x9D","scnE;:\xE2\xAA\xB6", "scnap;:\xE2\xAA\xBA","scnsim;:\xE2\x8B\xA9","scpolint;:\xE2\xA8\x93", "scsim;:\xE2\x89\xBF","scy;:\xD1\x81","sdot;:\xE2\x8B\x85", "sdotb;:\xE2\x8A\xA1","sdote;:\xE2\xA9\xA6","seArr;:\xE2\x87\x98", "searhk;:\xE2\xA4\xA5","searr;:\xE2\x86\x98","searrow;:\xE2\x86\x98", "sect:\xC2\xA7","sect;:\xC2\xA7","semi;:;","seswar;:\xE2\xA4\xA9", "setminus;:\xE2\x88\x96","setmn;:\xE2\x88\x96","sext;:\xE2\x9C\xB6", "sfr;:\xF0\x9D\x94\xB0","sfrown;:\xE2\x8C\xA2","sharp;:\xE2\x99\xAF", "shchcy;:\xD1\x89","shcy;:\xD1\x88","shortmid;:\xE2\x88\xA3", "shortparallel;:\xE2\x88\xA5","shy:\xC2\xAD","shy;:\xC2\xAD","sigma;:\xCF\x83", "sigmaf;:\xCF\x82","sigmav;:\xCF\x82","sim;:\xE2\x88\xBC", "simdot;:\xE2\xA9\xAA","sime;:\xE2\x89\x83","simeq;:\xE2\x89\x83", "simg;:\xE2\xAA\x9E","simgE;:\xE2\xAA\xA0","siml;:\xE2\xAA\x9D", "simlE;:\xE2\xAA\x9F","simne;:\xE2\x89\x86","simplus;:\xE2\xA8\xA4", "simrarr;:\xE2\xA5\xB2","slarr;:\xE2\x86\x90","smallsetminus;:\xE2\x88\x96", "smashp;:\xE2\xA8\xB3","smeparsl;:\xE2\xA7\xA4","smid;:\xE2\x88\xA3", "smile;:\xE2\x8C\xA3","smt;:\xE2\xAA\xAA","smte;:\xE2\xAA\xAC", "smtes;:\xE2\xAA\xAC\xEF\xB8\x80","softcy;:\xD1\x8C","sol;:/", "solb;:\xE2\xA7\x84","solbar;:\xE2\x8C\xBF","sopf;:\xF0\x9D\x95\xA4", "spades;:\xE2\x99\xA0","spadesuit;:\xE2\x99\xA0","spar;:\xE2\x88\xA5", "sqcap;:\xE2\x8A\x93","sqcaps;:\xE2\x8A\x93\xEF\xB8\x80","sqcup;:\xE2\x8A\x94", "sqcups;:\xE2\x8A\x94\xEF\xB8\x80","sqsub;:\xE2\x8A\x8F","sqsube;:\xE2\x8A\x91", "sqsubset;:\xE2\x8A\x8F","sqsubseteq;:\xE2\x8A\x91","sqsup;:\xE2\x8A\x90", "sqsupe;:\xE2\x8A\x92","sqsupset;:\xE2\x8A\x90","sqsupseteq;:\xE2\x8A\x92", "squ;:\xE2\x96\xA1","square;:\xE2\x96\xA1","squarf;:\xE2\x96\xAA", "squf;:\xE2\x96\xAA","srarr;:\xE2\x86\x92","sscr;:\xF0\x9D\x93\x88", "ssetmn;:\xE2\x88\x96","ssmile;:\xE2\x8C\xA3","sstarf;:\xE2\x8B\x86", "star;:\xE2\x98\x86","starf;:\xE2\x98\x85","straightepsilon;:\xCF\xB5", "straightphi;:\xCF\x95","strns;:\xC2\xAF","sub;:\xE2\x8A\x82", "subE;:\xE2\xAB\x85","subdot;:\xE2\xAA\xBD","sube;:\xE2\x8A\x86", "subedot;:\xE2\xAB\x83","submult;:\xE2\xAB\x81","subnE;:\xE2\xAB\x8B", "subne;:\xE2\x8A\x8A","subplus;:\xE2\xAA\xBF","subrarr;:\xE2\xA5\xB9", "subset;:\xE2\x8A\x82","subseteq;:\xE2\x8A\x86","subseteqq;:\xE2\xAB\x85", "subsetneq;:\xE2\x8A\x8A","subsetneqq;:\xE2\xAB\x8B","subsim;:\xE2\xAB\x87", "subsub;:\xE2\xAB\x95","subsup;:\xE2\xAB\x93","succ;:\xE2\x89\xBB", "succapprox;:\xE2\xAA\xB8","succcurlyeq;:\xE2\x89\xBD","succeq;:\xE2\xAA\xB0", "succnapprox;:\xE2\xAA\xBA","succneqq;:\xE2\xAA\xB6","succnsim;:\xE2\x8B\xA9", "succsim;:\xE2\x89\xBF","sum;:\xE2\x88\x91","sung;:\xE2\x99\xAA", "sup1:\xC2\xB9","sup1;:\xC2\xB9","sup2:\xC2\xB2","sup2;:\xC2\xB2", "sup3:\xC2\xB3","sup3;:\xC2\xB3","sup;:\xE2\x8A\x83","supE;:\xE2\xAB\x86", "supdot;:\xE2\xAA\xBE","supdsub;:\xE2\xAB\x98","supe;:\xE2\x8A\x87", "supedot;:\xE2\xAB\x84","suphsol;:\xE2\x9F\x89","suphsub;:\xE2\xAB\x97", "suplarr;:\xE2\xA5\xBB","supmult;:\xE2\xAB\x82","supnE;:\xE2\xAB\x8C", "supne;:\xE2\x8A\x8B","supplus;:\xE2\xAB\x80","supset;:\xE2\x8A\x83", "supseteq;:\xE2\x8A\x87","supseteqq;:\xE2\xAB\x86","supsetneq;:\xE2\x8A\x8B", "supsetneqq;:\xE2\xAB\x8C","supsim;:\xE2\xAB\x88","supsub;:\xE2\xAB\x94", "supsup;:\xE2\xAB\x96","swArr;:\xE2\x87\x99","swarhk;:\xE2\xA4\xA6", "swarr;:\xE2\x86\x99","swarrow;:\xE2\x86\x99","swnwar;:\xE2\xA4\xAA", "szlig:\xC3\x9F","szlig;:\xC3\x9F","target;:\xE2\x8C\x96","tau;:\xCF\x84", "tbrk;:\xE2\x8E\xB4","tcaron;:\xC5\xA5","tcedil;:\xC5\xA3","tcy;:\xD1\x82", "tdot;:\xE2\x83\x9B","telrec;:\xE2\x8C\x95","tfr;:\xF0\x9D\x94\xB1", "there4;:\xE2\x88\xB4","therefore;:\xE2\x88\xB4","theta;:\xCE\xB8", "thetasym;:\xCF\x91","thetav;:\xCF\x91","thickapprox;:\xE2\x89\x88", "thicksim;:\xE2\x88\xBC","thinsp;:\xE2\x80\x89","thkap;:\xE2\x89\x88", "thksim;:\xE2\x88\xBC","thorn:\xC3\xBE","thorn;:\xC3\xBE","tilde;:\xCB\x9C", "times:\xC3\x97","times;:\xC3\x97","timesb;:\xE2\x8A\xA0", "timesbar;:\xE2\xA8\xB1","timesd;:\xE2\xA8\xB0","tint;:\xE2\x88\xAD", "toea;:\xE2\xA4\xA8","top;:\xE2\x8A\xA4","topbot;:\xE2\x8C\xB6", "topcir;:\xE2\xAB\xB1","topf;:\xF0\x9D\x95\xA5","topfork;:\xE2\xAB\x9A", "tosa;:\xE2\xA4\xA9","tprime;:\xE2\x80\xB4","trade;:\xE2\x84\xA2", "triangle;:\xE2\x96\xB5","triangledown;:\xE2\x96\xBF", "triangleleft;:\xE2\x97\x83","trianglelefteq;:\xE2\x8A\xB4", "triangleq;:\xE2\x89\x9C","triangleright;:\xE2\x96\xB9", "trianglerighteq;:\xE2\x8A\xB5","tridot;:\xE2\x97\xAC","trie;:\xE2\x89\x9C", "triminus;:\xE2\xA8\xBA","triplus;:\xE2\xA8\xB9","trisb;:\xE2\xA7\x8D", "tritime;:\xE2\xA8\xBB","trpezium;:\xE2\x8F\xA2","tscr;:\xF0\x9D\x93\x89", "tscy;:\xD1\x86","tshcy;:\xD1\x9B","tstrok;:\xC5\xA7","twixt;:\xE2\x89\xAC", "twoheadleftarrow;:\xE2\x86\x9E","twoheadrightarrow;:\xE2\x86\xA0", "uArr;:\xE2\x87\x91","uHar;:\xE2\xA5\xA3","uacute:\xC3\xBA","uacute;:\xC3\xBA", "uarr;:\xE2\x86\x91","ubrcy;:\xD1\x9E","ubreve;:\xC5\xAD","ucirc:\xC3\xBB", "ucirc;:\xC3\xBB","ucy;:\xD1\x83","udarr;:\xE2\x87\x85","udblac;:\xC5\xB1", "udhar;:\xE2\xA5\xAE","ufisht;:\xE2\xA5\xBE","ufr;:\xF0\x9D\x94\xB2", "ugrave:\xC3\xB9","ugrave;:\xC3\xB9","uharl;:\xE2\x86\xBF", "uharr;:\xE2\x86\xBE","uhblk;:\xE2\x96\x80","ulcorn;:\xE2\x8C\x9C", "ulcorner;:\xE2\x8C\x9C","ulcrop;:\xE2\x8C\x8F","ultri;:\xE2\x97\xB8", "umacr;:\xC5\xAB","uml:\xC2\xA8","uml;:\xC2\xA8","uogon;:\xC5\xB3", "uopf;:\xF0\x9D\x95\xA6","uparrow;:\xE2\x86\x91","updownarrow;:\xE2\x86\x95", "upharpoonleft;:\xE2\x86\xBF","upharpoonright;:\xE2\x86\xBE", "uplus;:\xE2\x8A\x8E","upsi;:\xCF\x85","upsih;:\xCF\x92","upsilon;:\xCF\x85", "upuparrows;:\xE2\x87\x88","urcorn;:\xE2\x8C\x9D","urcorner;:\xE2\x8C\x9D", "urcrop;:\xE2\x8C\x8E","uring;:\xC5\xAF","urtri;:\xE2\x97\xB9", "uscr;:\xF0\x9D\x93\x8A","utdot;:\xE2\x8B\xB0","utilde;:\xC5\xA9", "utri;:\xE2\x96\xB5","utrif;:\xE2\x96\xB4","uuarr;:\xE2\x87\x88", "uuml:\xC3\xBC","uuml;:\xC3\xBC","uwangle;:\xE2\xA6\xA7","vArr;:\xE2\x87\x95", "vBar;:\xE2\xAB\xA8","vBarv;:\xE2\xAB\xA9","vDash;:\xE2\x8A\xA8", "vangrt;:\xE2\xA6\x9C","varepsilon;:\xCF\xB5","varkappa;:\xCF\xB0", "varnothing;:\xE2\x88\x85","varphi;:\xCF\x95","varpi;:\xCF\x96", "varpropto;:\xE2\x88\x9D","varr;:\xE2\x86\x95","varrho;:\xCF\xB1", "varsigma;:\xCF\x82","varsubsetneq;:\xE2\x8A\x8A\xEF\xB8\x80", "varsubsetneqq;:\xE2\xAB\x8B\xEF\xB8\x80", "varsupsetneq;:\xE2\x8A\x8B\xEF\xB8\x80", "varsupsetneqq;:\xE2\xAB\x8C\xEF\xB8\x80","vartheta;:\xCF\x91", "vartriangleleft;:\xE2\x8A\xB2","vartriangleright;:\xE2\x8A\xB3", "vcy;:\xD0\xB2","vdash;:\xE2\x8A\xA2","vee;:\xE2\x88\xA8", "veebar;:\xE2\x8A\xBB","veeeq;:\xE2\x89\x9A","vellip;:\xE2\x8B\xAE","verbar;:|", "vert;:|","vfr;:\xF0\x9D\x94\xB3","vltri;:\xE2\x8A\xB2", "vnsub;:\xE2\x8A\x82\xE2\x83\x92","vnsup;:\xE2\x8A\x83\xE2\x83\x92", "vopf;:\xF0\x9D\x95\xA7","vprop;:\xE2\x88\x9D","vrtri;:\xE2\x8A\xB3", "vscr;:\xF0\x9D\x93\x8B","vsubnE;:\xE2\xAB\x8B\xEF\xB8\x80", "vsubne;:\xE2\x8A\x8A\xEF\xB8\x80","vsupnE;:\xE2\xAB\x8C\xEF\xB8\x80", "vsupne;:\xE2\x8A\x8B\xEF\xB8\x80","vzigzag;:\xE2\xA6\x9A","wcirc;:\xC5\xB5", "wedbar;:\xE2\xA9\x9F","wedge;:\xE2\x88\xA7","wedgeq;:\xE2\x89\x99", "weierp;:\xE2\x84\x98","wfr;:\xF0\x9D\x94\xB4","wopf;:\xF0\x9D\x95\xA8", "wp;:\xE2\x84\x98","wr;:\xE2\x89\x80","wreath;:\xE2\x89\x80", "wscr;:\xF0\x9D\x93\x8C","xcap;:\xE2\x8B\x82","xcirc;:\xE2\x97\xAF", "xcup;:\xE2\x8B\x83","xdtri;:\xE2\x96\xBD","xfr;:\xF0\x9D\x94\xB5", "xhArr;:\xE2\x9F\xBA","xharr;:\xE2\x9F\xB7","xi;:\xCE\xBE", "xlArr;:\xE2\x9F\xB8","xlarr;:\xE2\x9F\xB5","xmap;:\xE2\x9F\xBC", "xnis;:\xE2\x8B\xBB","xodot;:\xE2\xA8\x80","xopf;:\xF0\x9D\x95\xA9", "xoplus;:\xE2\xA8\x81","xotime;:\xE2\xA8\x82","xrArr;:\xE2\x9F\xB9", "xrarr;:\xE2\x9F\xB6","xscr;:\xF0\x9D\x93\x8D","xsqcup;:\xE2\xA8\x86", "xuplus;:\xE2\xA8\x84","xutri;:\xE2\x96\xB3","xvee;:\xE2\x8B\x81", "xwedge;:\xE2\x8B\x80","yacute:\xC3\xBD","yacute;:\xC3\xBD","yacy;:\xD1\x8F", "ycirc;:\xC5\xB7","ycy;:\xD1\x8B","yen:\xC2\xA5","yen;:\xC2\xA5", "yfr;:\xF0\x9D\x94\xB6","yicy;:\xD1\x97","yopf;:\xF0\x9D\x95\xAA", "yscr;:\xF0\x9D\x93\x8E","yucy;:\xD1\x8E","yuml:\xC3\xBF","yuml;:\xC3\xBF", "zacute;:\xC5\xBA","zcaron;:\xC5\xBE","zcy;:\xD0\xB7","zdot;:\xC5\xBC", "zeetrf;:\xE2\x84\xA8","zeta;:\xCE\xB6","zfr;:\xF0\x9D\x94\xB7", "zhcy;:\xD0\xB6","zigrarr;:\xE2\x87\x9D","zopf;:\xF0\x9D\x95\xAB", "zscr;:\xF0\x9D\x93\x8F","zwj;:\xE2\x80\x8D","zwnj;:\xE2\x80\x8C", ] const charMap*: array[char, int] = [ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,26,38,74,128,158,166,188,200,229,236,244, 304,313,385,414,433,438,483,523,546,586,603,608,612,623,633,-1,-1,-1,-1,-1,-1, 702,818,917,983,1050,1089,1149,1177,1233,1241,1251,1405,1445,1613,1674,1743, 1754,1858,2016,2074,2126,2168,2179,2203,2217,2230,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, ] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/chame/htmlparser.nim�������������������������������������������������������0000664�0000000�0000000�00000257557�15202323131�0021025�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import std/options import std/tables import dombuilder import htmltokenizer import tags import tokstate # Export these so that htmlparseriface works seamlessly. export dombuilder export options export tags # Export tokstate too; it is needed for fragment parsing. export tokstate # Heavily inspired by html5ever's TreeSink design. type HTML5ParserOpts*[Handle, Atom] = object isIframeSrcdoc*: bool ## Is the document an iframe srcdoc? scripting*: bool ## Is scripting enabled for this document? pushInTemplate*: bool ## When set to true, the "in template" insertion mode is pushed to ## the stack of template insertion modes on parser start. initialTokenizerState*: TokenizerState ## The initial tokenizer state; by default, this is DATA. ctx*: Option[OpenElementInit[Handle, Atom]] ## Context element for fragment parsing. When set to some Handle, ## the fragment case is used while parsing. ## ## `token` must be a valid starting token for this element. openElementsInit*: seq[OpenElementInit[Handle, Atom]] ## Initial ## state of the stack of open elements. By default, the stack starts ## out empty. ## Note: if this is initialized to a non-empty sequence, the parser will ## start by resetting the insertion mode appropriately. formInit*: Option[Handle] ## Initial state of the parser's form pointer. OpenElement[Handle, Atom] = tuple element: Handle token: Token[Atom] ## the element's start tag token; must not be nil. OpenElementInit*[Handle, Atom] = tuple element: Handle startTagName: Atom ## the element's start tag token's name. type QualifiedName[Atom] = tuple prefix: NamespacePrefix namespace: Namespace localName: Atom HTML5Parser*[Handle, Atom] = object dombuilder: DOMBuilder[Handle, Atom] opts: HTML5ParserOpts[Handle, Atom] ctx: Option[OpenElement[Handle, Atom]] openElements: seq[OpenElement[Handle, Atom]] templateModes: seq[InsertionMode] head: Option[OpenElement[Handle, Atom]] tokenizer: Tokenizer[Handle, Atom] form: Option[Handle] quirksMode: QuirksMode insertionMode: InsertionMode oldInsertionMode: InsertionMode fosterParenting: bool framesetOk: bool ignoreLF: bool pendingTableCharsWhitespace: bool # Handle is an element. nil => marker activeFormatting: seq[(Option[Handle], Token[Atom])] pendingTableChars: string caseTable: Table[Atom, Atom] adjustedTable: Table[Atom, Atom] foreignTable: Table[Atom, QualifiedName[Atom]] InsertionLocation[Handle] = object inside: Handle before: Option[Handle] # 13.2.4.1 InsertionMode = enum imInitial, imBeforeHtml, imBeforeHead, imInHead, imInHeadNoscript, imAfterHead, imInBody, imInText, imInTable, imInTableInText, imInCaption, imInColumnGroup, imInTableBody, imInRow, imInCell, imInTemplate, imAfterBody, imInFrameset, imAfterFrameset, imAfterAfterBody, imAfterAfterFrameset type ParseResult* = enum ## Result of parsing the passed chunk. ## PRES_CONTINUE is returned when it is OK to continue parsing. ## ## PRES_STOP is returned when the parser has been stopped from ## setEncodingImpl. ## ## PRES_SCRIPT is returned when a script end tag is encountered. For ## implementations that do not support scripting, this can be treated ## equivalently to PRES_CONTINUE. ## ## Implementations that *do* support scripting and implement `document.write` ## can instead use PRES_SCRIPT to process string injected into the input ## stream by `document.write` before continuing with parsing from the ## network stream. In this case, script elements should be stored in e.g. the ## DOM builder from `elementPoppedImpl`, and processed accordingly after ## PRES_SCRIPT has been returned. PRES_CONTINUE PRES_STOP PRES_SCRIPT # DOMBuilder interface functions proc strToAtom[Handle, Atom](parser: HTML5Parser[Handle, Atom]; s: string): Atom = mixin strToAtomImpl return parser.dombuilder.strToAtomImpl(s) proc toAtom[Handle, Atom](parser: HTML5Parser[Handle, Atom]; tagType: TagType): Atom = mixin tagTypeToAtomImpl return parser.dombuilder.tagTypeToAtomImpl(tagType) proc toTagType[Handle, Atom](parser: HTML5Parser[Handle, Atom]; atom: Atom): TagType = mixin atomToTagTypeImpl return parser.dombuilder.atomToTagTypeImpl(atom) proc setQuirksMode[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; mode: QuirksMode) = mixin setQuirksModeImpl parser.quirksMode = mode when compiles(parser.dombuilder.setQuirksModeImpl(mode)): parser.dombuilder.setQuirksModeImpl(mode) proc setEncoding(parser: var HTML5Parser; cs: string): SetEncodingResult = mixin setEncodingImpl when compiles(parser.dombuilder.setEncodingImpl(cs)): return parser.dombuilder.setEncodingImpl(cs) else: return SET_ENCODING_CONTINUE proc getDocument[Handle, Atom](parser: HTML5Parser[Handle, Atom]): Handle = mixin getDocumentImpl return parser.dombuilder.getDocumentImpl() proc getParentNode[Handle, Atom](parser: HTML5Parser[Handle, Atom]; handle: Handle): Option[Handle] = mixin getParentNodeImpl return parser.dombuilder.getParentNodeImpl(handle) proc getLocalName[Handle, Atom](parser: HTML5Parser[Handle, Atom]; handle: Handle): Atom = mixin getLocalNameImpl return parser.dombuilder.getLocalNameImpl(handle) proc getNamespace[Handle, Atom](parser: HTML5Parser[Handle, Atom]; handle: Handle): Namespace = mixin getNamespaceImpl return parser.dombuilder.getNamespaceImpl(handle) proc getTemplateContent[Handle, Atom](parser: HTML5Parser[Handle, Atom]; handle: Handle): Handle = mixin getTemplateContentImpl return parser.dombuilder.getTemplateContentImpl(handle) proc getTagType[Handle, Atom](parser: HTML5Parser[Handle, Atom]; handle: Handle): TagType = if parser.getNamespace(handle) != Namespace.HTML: return TAG_UNKNOWN return parser.toTagType(parser.getLocalName(handle)) proc createHTMLElement[Handle, Atom](parser: HTML5Parser[Handle, Atom]): Handle = mixin createHTMLElementImpl return parser.dombuilder.createHTMLElementImpl() proc insertCommentImpl[Handle, Atom](parser: HTML5Parser[Handle, Atom]; parent: Handle; text: string; before: Option[Handle]) = mixin insertCommentImpl parser.dombuilder.insertCommentImpl(parent, text, before) proc appendDocumentType[Handle, Atom](parser: HTML5Parser[Handle, Atom]; name, publicId, systemId: string) = mixin appendDocumentTypeImpl parser.dombuilder.appendDocumentTypeImpl(name, publicId, systemId) proc insertBefore[Handle, Atom](parser: HTML5Parser[Handle, Atom]; parent, child: Handle; before: Option[Handle]) = mixin insertBeforeImpl parser.dombuilder.insertBeforeImpl(parent, child, before) proc insertText[Handle, Atom](parser: HTML5Parser[Handle, Atom]; parent: Handle; text: string; before: Option[Handle]) = mixin insertTextImpl parser.dombuilder.insertTextImpl(parent, text, before) proc remove[Handle, Atom](parser: HTML5Parser[Handle, Atom]; child: Handle) = mixin removeImpl parser.dombuilder.removeImpl(child) proc moveChildren[Handle, Atom](parser: HTML5Parser[Handle, Atom]; handleFrom, handleTo: Handle) = mixin moveChildrenImpl parser.dombuilder.moveChildrenImpl(handleFrom, handleTo) proc addAttrsIfMissing[Handle, Atom](parser: HTML5Parser[Handle, Atom]; element: Handle; attrs: Table[Atom, string]) = mixin addAttrsIfMissingImpl parser.dombuilder.addAttrsIfMissingImpl(element, attrs) proc setScriptAlreadyStarted[Handle, Atom](parser: HTML5Parser[Handle, Atom]; script: Handle) = mixin setScriptAlreadyStartedImpl when compiles(parser.dombuilder.setScriptAlreadyStartedImpl(script)): parser.dombuilder.setScriptAlreadyStartedImpl(script) proc associateWithForm[Handle, Atom](parser: HTML5Parser[Handle, Atom]; element, form, intendedParent: Handle) = mixin associateWithFormImpl when compiles(parser.dombuilder.associateWithFormImpl(element, form, intendedParent)): parser.dombuilder.associateWithFormImpl(element, form, intendedParent) # Parser iterator ropenElements[Handle, Atom](parser: HTML5Parser[Handle, Atom]): lent Handle = var i = uint(parser.openElements.len) while i > 0: dec i yield parser.openElements[i].element # https://html.spec.whatwg.org/multipage/parsing.html#reset-the-insertion-mode-appropriately proc resetInsertionMode0(parser: var HTML5Parser): InsertionMode = for i in countdown(parser.openElements.high, 0): var node = parser.openElements[i] let last = i == 0 if last and parser.ctx.isSome: node = parser.ctx.get let tagType = parser.getTagType(node.element) case tagType of TAG_TD, TAG_TH: if not last: return imInCell of TAG_TR: return imInRow of TAG_TBODY, TAG_THEAD, TAG_TFOOT: return imInTableBody of TAG_CAPTION: return imInCaption of TAG_COLGROUP: return imInColumnGroup of TAG_TABLE: return imInTable of TAG_TEMPLATE: return parser.templateModes[^1] of TAG_HEAD: if not last: return imInHead of TAG_BODY: return imInBody of TAG_FRAMESET: return imInFrameset of TAG_HTML: if parser.head.isNone: return imBeforeHead else: return imAfterHead else: discard return imInBody proc resetInsertionMode(parser: var HTML5Parser) = parser.insertionMode = parser.resetInsertionMode0() func currentNodeToken[Handle, Atom](parser: HTML5Parser[Handle, Atom]): OpenElement[Handle, Atom] = return parser.openElements[^1] func currentNode[Handle, Atom](parser: HTML5Parser[Handle, Atom]): Handle = return parser.currentNodeToken.element func currentToken[Handle, Atom](parser: HTML5Parser[Handle, Atom]): Token[Atom] = return parser.currentNodeToken.token func adjustedCurrentNodeToken[Handle, Atom](parser: HTML5Parser[Handle, Atom]): OpenElement[Handle, Atom] = if parser.ctx.isSome and parser.openElements.len == 1: return parser.ctx.get else: return parser.currentNodeToken func adjustedCurrentNode[Handle, Atom](parser: HTML5Parser[Handle, Atom]): Handle = return parser.adjustedCurrentNodeToken.element proc lastElementOfTag[Handle, Atom](parser: HTML5Parser[Handle, Atom]; tagType: TagType): tuple[element: Option[Handle], pos: int] = for i in countdown(parser.openElements.high, 0): let element = parser.openElements[i].element if parser.getTagType(element) == tagType: return (some(element), i) return (none(Handle), -1) func lastChildOf[Handle](n: Handle): InsertionLocation[Handle] = InsertionLocation[Handle](inside: n, before: none(Handle)) func lastChildOf[Handle, Atom](n: OpenElement[Handle, Atom]): InsertionLocation[Handle] = lastChildOf(n.element) # https://html.spec.whatwg.org/multipage/#appropriate-place-for-inserting-a-node proc appropriatePlaceForInsert[Handle, Atom](parser: HTML5Parser[Handle, Atom]; target: Handle): InsertionLocation[Handle] = assert parser.getTagType(parser.openElements[0].element) == TAG_HTML let targetTagType = parser.getTagType(target) const FosterTagTypes = {TAG_TABLE, TAG_TBODY, TAG_TFOOT, TAG_THEAD, TAG_TR} if parser.fosterParenting and targetTagType in FosterTagTypes: let lastTemplate = parser.lastElementOfTag(TAG_TEMPLATE) let lastTable = parser.lastElementOfTag(TAG_TABLE) if lastTemplate.element.isSome and (lastTable.element.isNone or lastTable.pos < lastTemplate.pos): let content = parser.getTemplateContent(lastTemplate.element.get) return lastChildOf(content) if lastTable.element.isNone: return lastChildOf(parser.openElements[0].element) let parentNode = parser.getParentNode(lastTable.element.get) if parentNode.isSome: return InsertionLocation[Handle]( inside: parentNode.get, before: lastTable.element ) let previousElement = parser.openElements[lastTable.pos - 1] result = lastChildOf(previousElement.element) else: result = lastChildOf(target) if parser.getTagType(result.inside) == TAG_TEMPLATE: result = lastChildOf(parser.getTemplateContent(result.inside)) proc appropriatePlaceForInsert[Handle, Atom](parser: HTML5Parser[Handle, Atom]): InsertionLocation[Handle] = parser.appropriatePlaceForInsert(parser.currentNode) proc hasElement[Handle, Atom](parser: HTML5Parser[Handle, Atom]; tag: TagType): bool = for it in parser.openElements: if parser.getTagType(it.element) == tag: return true return false const Scope = { TAG_APPLET, TAG_CAPTION, TAG_HTML, TAG_TABLE, TAG_TD, TAG_TH, TAG_MARQUEE, TAG_OBJECT, TAG_SELECT, TAG_TEMPLATE # (+ SVG, MathML) } proc hasElementInScopeWithXML[Handle, Atom](parser: HTML5Parser[Handle, Atom]; target: Handle; list: set[TagType]): bool = for element in parser.ropenElements: if element == target: return true let localName = parser.getLocalName(element) let tagType = parser.toTagType(localName) case parser.getNamespace(element) of Namespace.HTML: if tagType in list: return false of Namespace.MATHML: const elements = { TAG_MI, TAG_MO, TAG_MN, TAG_MS, TAG_MTEXT, TAG_ANNOTATION_XML } if tagType in elements: return false of Namespace.SVG: const elements = {TAG_FOREIGN_OBJECT, TAG_DESC, TAG_TITLE} if tagType in elements: return false else: discard return false proc hasElementInScopeWithXML[Handle, Atom](parser: HTML5Parser[Handle, Atom]; target: TagType; list: set[TagType]): bool = for element in parser.ropenElements: let tagType = parser.toTagType(parser.getLocalName(element)) case parser.getNamespace(element) of Namespace.HTML: if tagType == target or target == TAG_H1 and tagType in TAG_H2 .. TAG_H6: return true if tagType in list: return false of Namespace.MATHML: const elements = { TAG_MI, TAG_MO, TAG_MN, TAG_MS, TAG_MTEXT, TAG_ANNOTATION_XML } if tagType in elements: return false of Namespace.SVG: const elements = {TAG_FOREIGN_OBJECT, TAG_DESC, TAG_TITLE} if tagType in elements: return false else: discard return false proc hasElementInScope[Handle, Atom](parser: HTML5Parser[Handle, Atom]; target: Handle): bool = return parser.hasElementInScopeWithXML(target, Scope) proc hasElementInScope[Handle, Atom](parser: HTML5Parser[Handle, Atom]; target: TagType): bool = return parser.hasElementInScopeWithXML(target, Scope) proc hasElementInListItemScope[Handle, Atom](parser: HTML5Parser[Handle, Atom]; target: TagType): bool = const ListItemScope = Scope + {TAG_OL, TAG_UL} return parser.hasElementInScopeWithXML(target, ListItemScope) proc hasElementInButtonScope[Handle, Atom](parser: HTML5Parser[Handle, Atom]; target: TagType): bool = const ButtonScope = Scope + {TAG_BUTTON} return parser.hasElementInScopeWithXML(target, ButtonScope) proc hasElementInTableScope[Handle, Atom](parser: HTML5Parser[Handle, Atom]; target: set[TagType]): bool = for element in parser.ropenElements: let tagType = parser.getTagType(element) if tagType in target: return true if tagType in {TAG_HTML, TAG_TABLE, TAG_TEMPLATE}: break return false proc hasElementInTableScope[Handle, Atom](parser: HTML5Parser[Handle, Atom]; target: TagType): bool = return parser.hasElementInTableScope({target}) proc createElementForToken[Handle, Atom](parser: HTML5Parser[Handle, Atom]; localName: Atom; namespace: Namespace; intendedParent: Handle; htmlAttrs: Table[Atom, string]; xmlAttrs: seq[ParsedAttr[Atom]]): Handle = mixin createElementForTokenImpl let element = parser.dombuilder.createElementForTokenImpl( localName, namespace, intendedParent, htmlAttrs, xmlAttrs ) let tagType = parser.toTagType(localName) if namespace == Namespace.HTML and tagType in FormAssociatedElements and parser.form.isSome and not parser.hasElement(TAG_TEMPLATE) and (tagType notin ListedElements or parser.toAtom(TAG_FORM) notin htmlAttrs): parser.associateWithForm(element, parser.form.get, intendedParent) return element proc createElementForToken[Handle, Atom](parser: HTML5Parser[Handle, Atom]; token: Token; namespace: Namespace; intendedParent: Handle): Handle = # attrs not adjusted return parser.createElementForToken(token.tagname, namespace, intendedParent, token.attrs, @[]) proc createHTMLElementForToken[Handle, Atom](parser: HTML5Parser[Handle, Atom]; token: Token; intendedParent: Handle): Handle = # attrs not adjusted return parser.createElementForToken( token.tagname, Namespace.HTML, intendedParent, token.attrs, @[] ) proc pushElement[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; node: Handle; token: Token[Atom]) = parser.openElements.add((node, token)) let node = parser.adjustedCurrentNode() parser.tokenizer.hasnonhtml = parser.getNamespace(node) != Namespace.HTML proc popElement[Handle, Atom](parser: var HTML5Parser[Handle, Atom]): Handle = mixin elementPoppedImpl result = parser.openElements.pop().element when compiles(parser.dombuilder.elementPoppedImpl(result)): parser.dombuilder.elementPoppedImpl(result) if parser.openElements.len == 0: parser.tokenizer.hasnonhtml = false else: let node = parser.adjustedCurrentNode() parser.tokenizer.hasnonhtml = parser.getNamespace(node) != Namespace.HTML proc insert[Handle, Atom](parser: HTML5Parser[Handle, Atom]; location: InsertionLocation[Handle]; node: Handle) = parser.insertBefore(location.inside, node, location.before) proc append[Handle, Atom](parser: HTML5Parser[Handle, Atom]; parent, node: Handle) = parser.insertBefore(parent, node, none(Handle)) proc insertForeignElement[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; token: Token; localName: Atom; namespace: Namespace; stackOnly: bool; xmlAttrs: seq[ParsedAttr[Atom]]): Handle = let location = parser.appropriatePlaceForInsert() let parent = location.inside let element = parser.createElementForToken(localName, namespace, parent, token.attrs, xmlAttrs) if not stackOnly: parser.insert(location, element) parser.pushElement(element, token) return element proc insertForeignElement[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; token: Token; namespace: Namespace; stackOnly: bool): Handle = parser.insertForeignElement(token, token.tagname, namespace, stackOnly, @[]) proc insertHTMLElement[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; token: Token): Handle = return parser.insertForeignElement(token, Namespace.HTML, false) proc insertHTMLElementPop[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; token: Token) = discard parser.insertHTMLElement(token) discard parser.popElement() # Note: adjustMathMLAttributes and adjustSVGAttributes both include the "adjust # foreign attributes" step as well. proc adjustMathMLAttributes[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; htmlAttrs: var Table[Atom, string]; xmlAttrs: var seq[ParsedAttr[Atom]]) = var deleted: seq[Atom] = @[] for k, v in htmlAttrs.mpairs: parser.foreignTable.withValue(k, p): xmlAttrs.add((p[].prefix, p[].namespace, p[].localName, v)) deleted.add(k) var v: string = "" if htmlAttrs.pop(parser.toAtom(TAG_DEFINITION_URL), v): htmlAttrs[parser.strToAtom("definitionURL")] = v for k in deleted: htmlAttrs.del(k) proc adjustSVGAttributes[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; htmlAttrs: var Table[Atom, string]; xmlAttrs: var seq[ParsedAttr[Atom]]) = var deleted: seq[Atom] = @[] for k, v in htmlAttrs: parser.foreignTable.withValue(k, p): xmlAttrs.add((p[].prefix, p[].namespace, p[].localName, v)) deleted.add(k) for k, ak in parser.adjustedTable: var v: string = "" if htmlAttrs.pop(k, v): htmlAttrs[ak] = v for k in deleted: htmlAttrs.del(k) proc insertCharacter(parser: var HTML5Parser; data: string) = let location = parser.appropriatePlaceForInsert() if location.inside == parser.getDocument(): return parser.insertText(location.inside, data, location.before) proc insertComment[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; token: Token; position: InsertionLocation[Handle]) = parser.insertCommentImpl(position.inside, token.s, position.before) proc insertComment(parser: var HTML5Parser; token: Token) = let position = parser.appropriatePlaceForInsert() parser.insertComment(token, position) const PublicIdentifierEquals = [ "-//W3O//DTD W3 HTML Strict 3.0//EN//", "-/W3C/DTD HTML 4.0 Transitional/EN", "HTML" ] const PublicIdentifierStartsWith = [ "+//Silmaril//dtd html Pro v0r11 19970101//", "-//AS//DTD HTML 3.0 asWedit + extensions//", "-//AdvaSoft Ltd//DTD HTML 3.0 asWedit + extensions//", "-//IETF//DTD HTML 2.0 Level 1//", "-//IETF//DTD HTML 2.0 Level 2//", "-//IETF//DTD HTML 2.0 Strict Level 1//", "-//IETF//DTD HTML 2.0 Strict Level 2//", "-//IETF//DTD HTML 2.0 Strict//", "-//IETF//DTD HTML 2.0//", "-//IETF//DTD HTML 2.1E//", "-//IETF//DTD HTML 3.0//", "-//IETF//DTD HTML 3.2 Final//", "-//IETF//DTD HTML 3.2//", "-//IETF//DTD HTML 3//", "-//IETF//DTD HTML Level 0//", "-//IETF//DTD HTML Level 1//", "-//IETF//DTD HTML Level 2//", "-//IETF//DTD HTML Level 3//", "-//IETF//DTD HTML Strict Level 0//", "-//IETF//DTD HTML Strict Level 1//", "-//IETF//DTD HTML Strict Level 2//", "-//IETF//DTD HTML Strict Level 3//", "-//IETF//DTD HTML Strict//", "-//IETF//DTD HTML//", "-//Metrius//DTD Metrius Presentational//", "-//Microsoft//DTD Internet Explorer 2.0 HTML Strict//", "-//Microsoft//DTD Internet Explorer 2.0 HTML//", "-//Microsoft//DTD Internet Explorer 2.0 Tables//", "-//Microsoft//DTD Internet Explorer 3.0 HTML Strict//", "-//Microsoft//DTD Internet Explorer 3.0 HTML//", "-//Microsoft//DTD Internet Explorer 3.0 Tables//", "-//Netscape Comm. Corp.//DTD HTML//", "-//Netscape Comm. Corp.//DTD Strict HTML//", "-//O'Reilly and Associates//DTD HTML 2.0//", "-//O'Reilly and Associates//DTD HTML Extended 1.0//", "-//O'Reilly and Associates//DTD HTML Extended Relaxed 1.0//", "-//SQ//DTD HTML 2.0 HoTMetaL + extensions//", "-//SoftQuad Software//DTD HoTMetaL PRO 6.0::19990601::extensions to HTML 4.0//", "-//SoftQuad//DTD HoTMetaL PRO 4.0::19971010::extensions to HTML 4.0//", "-//Spyglass//DTD HTML 2.0 Extended//", "-//Sun Microsystems Corp.//DTD HotJava HTML//", "-//Sun Microsystems Corp.//DTD HotJava Strict HTML//", "-//W3C//DTD HTML 3 1995-03-24//", "-//W3C//DTD HTML 3.2 Draft//", "-//W3C//DTD HTML 3.2 Final//", "-//W3C//DTD HTML 3.2//", "-//W3C//DTD HTML 3.2S Draft//", "-//W3C//DTD HTML 4.0 Frameset//", "-//W3C//DTD HTML 4.0 Transitional//", "-//W3C//DTD HTML Experimental 19960712//", "-//W3C//DTD HTML Experimental 970421//", "-//W3C//DTD W3 HTML//", "-//W3O//DTD W3 HTML 3.0//", "-//WebTechs//DTD Mozilla HTML 2.0//", "-//WebTechs//DTD Mozilla HTML//", ] const SystemIdentifierMissingAndPublicIdentifierStartsWith = [ "-//W3C//DTD HTML 4.01 Frameset//", "-//W3C//DTD HTML 4.01 Transitional//" ] const PublicIdentifierStartsWithLimited = [ "-//W3C//DTD XHTML 1.0 Frameset//", "-//W3C//DTD XHTML 1.0 Transitional//" ] const SystemIdentifierNotMissingAndPublicIdentifierStartsWith = [ "-//W3C//DTD HTML 4.01 Frameset//", "-//W3C//DTD HTML 4.01 Transitional//" ] const AsciiUpperAlpha = {'A'..'Z'} proc toLowerAscii(c: char): char {.inline.} = if c in AsciiUpperAlpha: result = char(uint8(c) xor 0x20'u8) else: result = c func startsWithNoCase(str, prefix: string): bool = if str.len < prefix.len: return false # prefix.len is always lower var i = 0 while i != prefix.len: if str[i].toLowerAscii() != prefix[i].toLowerAscii(): return false inc i true func equalsIgnoreCase(s1, s2: string): bool = if s1.len != s2.len: return false var i = 0 while i < s1.len: if s1[i].toLowerAscii() != s2[i].toLowerAscii(): return false inc i true func quirksConditions(name, pubid, sysid: string; flags: set[TokenFlag]): bool = if tfQuirks in flags: return true if name != "html": return true if sysid == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd": return true if tfPubid in flags: for id in PublicIdentifierEquals: if pubid.equalsIgnoreCase(id): return true for id in PublicIdentifierStartsWith: if pubid.startsWithNoCase(id): return true if tfSysid notin flags: for id in SystemIdentifierMissingAndPublicIdentifierStartsWith: if pubid.startsWithNoCase(id): return true return false func limitedQuirksConditions(pubid: string; flags: set[TokenFlag]): bool = if tfPubid notin flags: return false for id in PublicIdentifierStartsWithLimited: if pubid.startsWithNoCase(id): return true if tfSysid notin flags: return false for id in SystemIdentifierNotMissingAndPublicIdentifierStartsWith: if pubid.startsWithNoCase(id): return true return false # 13.2.6.2 proc genericRawtextElementParsingAlgorithm(parser: var HTML5Parser; token: Token) = discard parser.insertHTMLElement(token) parser.tokenizer.state = RAWTEXT parser.oldInsertionMode = parser.insertionMode parser.insertionMode = imInText proc genericRCDATAElementParsingAlgorithm(parser: var HTML5Parser; token: Token) = discard parser.insertHTMLElement(token) parser.tokenizer.state = RCDATA parser.oldInsertionMode = parser.insertionMode parser.insertionMode = imInText # Pop all elements, including the specified tag. proc popElementsIncl(parser: var HTML5Parser; tag: TagType) = while parser.getTagType(parser.popElement()) != tag: discard # Pop all elements, including the specified element. proc popElementsIncl[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; handle: Handle) = while parser.popElement() != handle: discard # Pop all elements, excluding the specified tag. proc popElementsExcl(parser: var HTML5Parser; tags: set[TagType]) = while parser.getTagType(parser.currentNode) notin tags: discard parser.popElement() proc hasElementInScopePop[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; target: TagType): bool = if parser.hasElementInScope(target): parser.popElementsIncl(target) return true false # https://html.spec.whatwg.org/multipage/parsing.html#closing-elements-that-have-implied-end-tags proc generateImpliedEndTags(parser: var HTML5Parser) = const tags = { TAG_DD, TAG_DT, TAG_LI, TAG_OPTGROUP, TAG_OPTION, TAG_P, TAG_RB, TAG_RP, TAG_RT, TAG_RTC } while parser.getTagType(parser.currentNode) in tags: discard parser.popElement() proc generateImpliedEndTags(parser: var HTML5Parser; exclude: TagType) = let tags = { TAG_DD, TAG_DT, TAG_LI, TAG_OPTGROUP, TAG_OPTION, TAG_P, TAG_RB, TAG_RP, TAG_RT, TAG_RTC } - {exclude} while parser.getTagType(parser.currentNode) in tags: discard parser.popElement() proc generateImpliedEndTagsThoroughly(parser: var HTML5Parser) = const tags = { TAG_CAPTION, TAG_COLGROUP, TAG_DD, TAG_DT, TAG_LI, TAG_OPTGROUP, TAG_OPTION, TAG_P, TAG_RB, TAG_RP, TAG_RT, TAG_RTC, TAG_TBODY, TAG_TD, TAG_TFOOT, TAG_TH, TAG_THEAD, TAG_TR } while parser.getTagType(parser.currentNode) in tags: discard parser.popElement() # https://html.spec.whatwg.org/multipage/parsing.html#push-onto-the-list-of-active-formatting-elements proc pushActiveFormatting[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; element: Handle; token: Token[Atom]) = var count = 0 for i in countdown(parser.activeFormatting.high, 0): let it = parser.activeFormatting[i] if it[0].isNone: # marker break if it[1].tagname != token.tagname: continue if parser.getNamespace(it[0].get) != parser.getNamespace(element): continue if it[1].attrs != token.attrs: continue inc count if count == 3: parser.activeFormatting.delete(i) break parser.activeFormatting.add((some(element), token)) proc findOpenElement[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; element: Handle): int = for i, it in parser.openElements: if it.element == element: return i return -1 proc reconstructActiveFormatting[Handle, Atom]( parser: var HTML5Parser[Handle, Atom]) = type State = enum sRewind, sAdvance, sCreate if parser.activeFormatting.len == 0 or parser.activeFormatting[^1][0].isNone or parser.findOpenElement(parser.activeFormatting[^1][0].get) != -1: return var i = parser.activeFormatting.high var state = sRewind while true: case state of sRewind: if i == 0: state = sCreate continue dec i let entry = parser.activeFormatting[i][0] if entry.isSome and parser.findOpenElement(entry.get) == -1: continue state = sAdvance of sAdvance: inc i state = sCreate of sCreate: let element = parser.insertHTMLElement(parser.activeFormatting[i][1]) parser.activeFormatting[i] = ( some(element), parser.activeFormatting[i][1] ) if i != parser.activeFormatting.high: state = sAdvance continue break proc clearActiveFormattingTillMarker(parser: var HTML5Parser) = while parser.activeFormatting.len > 0 and parser.activeFormatting.pop()[0].isSome: discard proc isMathMLIntegrationPoint[Handle, Atom](parser: HTML5Parser[Handle, Atom]; element: Handle): bool = if parser.getNamespace(element) != Namespace.MATHML: return false let tagType = parser.toTagType(parser.getLocalName(element)) return tagType in {TAG_MI, TAG_MO, TAG_MN, TAG_MS, TAG_MTEXT} proc isHTMLIntegrationPoint[Handle, Atom](parser: HTML5Parser[Handle, Atom]; oe: OpenElement[Handle, Atom]): bool = let (element, token) = oe let localName = parser.getLocalName(element) let namespace = parser.getNamespace(element) let tagType = parser.toTagType(localName) if namespace == Namespace.MATHML: if tagType == TAG_ANNOTATION_XML: token.attrs.withValue(parser.toAtom(TAG_ENCODING), p): return p[].equalsIgnoreCase("text/html") or p[].equalsIgnoreCase("application/xhtml+xml") elif namespace == Namespace.SVG: return tagType in {TAG_FOREIGN_OBJECT, TAG_DESC, TAG_TITLE} return false const AsciiWhitespace = {' ', '\n', '\r', '\t', '\f'} func until(s: string; c1, c2: char; starti: int): string = result = "" for i in starti ..< s.len: let c = s[i] if c == c1 or c == c2: break result &= c func extractEncFromMeta(s: string): string = var i = 0 while true: # Loop: var j = 0 while i < s.len: let cc = s[i].toLowerAscii() template check(cc: char; c: static char) = if cc == c: inc j else: j = 0 case j of 0: check cc, 'c' of 1: check cc, 'h' of 2: check cc, 'a' of 3: check cc, 'r' of 4: check cc, 's' of 5: check cc, 'e' of 6: check cc, 't' of 7: inc j break else: discard inc i if j < 7: return "" while i < s.len and s[i] in AsciiWhitespace: inc i if i >= s.len or s[i] != '=': continue while i < s.len and s[i] in AsciiWhitespace: inc i break inc i if i >= s.len: return "" if s[i] in {'"', '\''}: let s2 = s.until('"', '\'', i + 1) if s2.len == 0 or s2[^1] != s[i]: return "" return s2 return s.until(';', ' ', i) # Find a node in the list of active formatting elements, or return -1. func findLastActiveFormatting[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; node: Handle): int = for i in countdown(parser.activeFormatting.high, 0): let it = parser.activeFormatting[i][0] if it.isSome and it.get == node: return i return -1 # > the last element in the list of active formatting elements that: # > is between the end of the list and the last marker in the list, if any, # > or the start of the list otherwise, and has the tag name subject. func findLastActiveFormattingAfterMarker(parser: var HTML5Parser, token: Token): int = for i in countdown(parser.activeFormatting.high, 0): let it = parser.activeFormatting[i][1] if it == nil: break # marker if it.tagname == token.tagname: return i return -1 proc findLastActiveFormattingAfterMarker(parser: var HTML5Parser; tagType: TagType): int = for i in countdown(parser.activeFormatting.high, 0): let it = parser.activeFormatting[i][0] if it.isNone: break if parser.getTagType(it.get) == tagType: return i return -1 #https://html.spec.whatwg.org/multipage/parsing.html#the-stack-of-open-elements const SpecialElements = { TAG_ADDRESS, TAG_APPLET, TAG_AREA, TAG_ARTICLE, TAG_ASIDE, TAG_BASE, TAG_BASEFONT, TAG_BGSOUND, TAG_BLOCKQUOTE, TAG_BODY, TAG_BR, TAG_BUTTON, TAG_CAPTION, TAG_CENTER, TAG_COL, TAG_COLGROUP, TAG_DD, TAG_DETAILS, TAG_DIR, TAG_DIV, TAG_DL, TAG_DT, TAG_EMBED, TAG_FIELDSET, TAG_FIGCAPTION, TAG_FIGURE, TAG_FOOTER, TAG_FORM, TAG_FRAME, TAG_FRAMESET, TAG_H1, TAG_H2, TAG_H3, TAG_H4, TAG_H5, TAG_H6, TAG_HEAD, TAG_HEADER, TAG_HGROUP, TAG_HR, TAG_HTML, TAG_IFRAME, TAG_IMG, TAG_INPUT, TAG_KEYGEN, TAG_LI, TAG_LINK, TAG_LISTING, TAG_MAIN, TAG_MARQUEE, TAG_MENU, TAG_META, TAG_NAV, TAG_NOEMBED, TAG_NOFRAMES, TAG_NOSCRIPT, TAG_OBJECT, TAG_OL, TAG_P, TAG_PARAM, TAG_PLAINTEXT, TAG_PRE, TAG_SCRIPT, TAG_SEARCH, TAG_SECTION, TAG_SELECT, TAG_SOURCE, TAG_STYLE, TAG_SUMMARY, TAG_TABLE, TAG_TBODY, TAG_TD, TAG_TEMPLATE, TAG_TEXTAREA, TAG_TFOOT, TAG_TH, TAG_THEAD, TAG_TITLE, TAG_TR, TAG_TRACK, TAG_UL, TAG_WBR, TAG_XMP } proc isSpecialElement[Handle, Atom](parser: HTML5Parser[Handle, Atom]; element: Handle): bool = let tagType = parser.toTagType(parser.getLocalName(element)) case parser.getNamespace(element) of Namespace.HTML: return tagType in SpecialElements of Namespace.MATHML: const elements = { TAG_MI, TAG_MO, TAG_MN, TAG_MS, TAG_MTEXT, TAG_ANNOTATION_XML } return tagType in elements of Namespace.SVG: return tagType in {TAG_FOREIGN_OBJECT, TAG_DESC, TAG_TITLE} else: return false # > Let furthestBlock be the topmost node in the stack of open elements that # > is lower in the stack than formattingElement, and is an element in the # > special category. There might not be one. proc findFurthestBlockAfter(parser: HTML5Parser; stackIndex: int): int = for i in stackIndex ..< parser.openElements.len: if parser.isSpecialElement(parser.openElements[i].element): return i return -1 proc findLastActiveFormatting[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; tagTypes: set[TagType]): int = for i in countdown(parser.activeFormatting.high, 0): let it = parser.activeFormatting[i][0] if it.isSome and parser.getTagType(it.get) in tagTypes: return i return -1 # If true is returned, call "any other end tag". proc adoptionAgencyAlgorithm[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; token: Token): bool = if parser.currentToken.tagname == token.tagname and parser.findLastActiveFormatting(parser.currentNode) == -1: discard parser.popElement() return false for i in 0 ..< 8: # outer loop var formattingIndex = parser.findLastActiveFormattingAfterMarker(token) if formattingIndex == -1: # no such element return true let formatting = parser.activeFormatting[formattingIndex][0].get let stackIndex = parser.findOpenElement(formatting) if stackIndex < 0: parser.activeFormatting.delete(formattingIndex) return false if not parser.hasElementInScope(formatting): return false var furthestBlockIndex = parser.findFurthestBlockAfter(stackIndex) if furthestBlockIndex == -1: parser.popElementsIncl(formatting) parser.activeFormatting.delete(formattingIndex) return false let furthestBlock = parser.openElements[furthestBlockIndex].element let commonAncestor = parser.openElements[stackIndex - 1].element var bookmark = formattingIndex var node = furthestBlock var aboveNode = parser.openElements[furthestBlockIndex - 1].element var lastNode = furthestBlock var j = 0 while true: inc j node = aboveNode if node == formatting: break let nodeStackIndex = parser.findOpenElement(node) var nodeFormattingIndex = parser.findLastActiveFormatting(node) if j > 3 and nodeFormattingIndex >= 0: parser.activeFormatting.delete(nodeFormattingIndex) if nodeFormattingIndex < bookmark: dec bookmark # a previous node got deleted, so decrement bookmark nodeFormattingIndex = -1 # deleted, so set to -1 if nodeFormattingIndex < 0: aboveNode = parser.openElements[nodeStackIndex - 1].element parser.openElements.delete(nodeStackIndex) if nodeStackIndex < furthestBlockIndex: dec furthestBlockIndex let element = parser.openElements[furthestBlockIndex].element assert furthestBlock == element continue let tok = parser.activeFormatting[nodeFormattingIndex][1] let element = parser.createHTMLElementForToken(tok, commonAncestor) parser.activeFormatting[nodeFormattingIndex] = (some(element), tok) parser.openElements[nodeStackIndex] = (element, tok) aboveNode = parser.openElements[nodeStackIndex - 1].element node = element if lastNode == furthestBlock: bookmark = nodeFormattingIndex + 1 parser.remove(lastNode) parser.append(node, lastNode) lastNode = node parser.remove(lastNode) let location = parser.appropriatePlaceForInsert(commonAncestor) parser.insert(location, lastNode) let token = parser.activeFormatting[formattingIndex][1] let element = parser.createHTMLElementForToken(token, furthestBlock) parser.moveChildren(furthestBlock, element) parser.append(furthestBlock, element) parser.activeFormatting.insert((some(element), token), bookmark) if formattingIndex >= bookmark: inc formattingIndex # increment because of insert parser.activeFormatting.delete(formattingIndex) parser.openElements.insert((element, token), furthestBlockIndex + 1) parser.openElements.delete(stackIndex) return false proc closeP(parser: var HTML5Parser; sure = false) = if sure or parser.hasElementInButtonScope(TAG_P): parser.popElementsIncl(TAG_P) proc newStartTagToken[Handle, Atom](parser: HTML5Parser[Handle, Atom]; t: TagType): Token[Atom] = return Token[Atom](t: ttStartTag, tagname: parser.toAtom(t)) proc otherBodyEndTag[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; tagname: Atom): ParseResult = for i in countdown(parser.openElements.high, 0): let (node, itToken) = parser.openElements[i] if itToken.tagname == tagname: parser.popElementsIncl(node) break elif parser.isSpecialElement(node): break return PRES_CONTINUE proc popTableContext[Handle, Atom](parser: var HTML5Parser[Handle, Atom]) = parser.popElementsExcl({TAG_TABLE, TAG_TEMPLATE, TAG_HTML}) proc popTableBodyContext[Handle, Atom](parser: var HTML5Parser[Handle, Atom]) = const tags = {TAG_TBODY, TAG_TFOOT, TAG_THEAD, TAG_TEMPLATE, TAG_HTML} parser.popElementsExcl(tags) proc popTableRowContext[Handle, Atom](parser: var HTML5Parser[Handle, Atom]) = parser.popElementsExcl({TAG_TR, TAG_TEMPLATE, TAG_HTML}) proc closeCell[Handle, Atom](parser: var HTML5Parser[Handle, Atom]) = while parser.getTagType(parser.popElement()) notin {TAG_TD, TAG_TH}: discard parser.clearActiveFormattingTillMarker() parser.insertionMode = imInRow proc processInHTML[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; token: Token; insertionMode: InsertionMode): ParseResult = template reprocess(tok: Token): ParseResult = parser.processInHTML(tok, parser.insertionMode) template reprocess(mode: InsertionMode): ParseResult = parser.processInHTML(token, mode) var anythingElse = false case insertionMode of imInitial: case token.t of ttWhitespace: discard of ttComment: parser.insertComment(token, lastChildOf(parser.getDocument())) of ttDoctype: parser.appendDocumentType(token.name, token.pubid, token.sysid) if not parser.opts.isIframeSrcdoc: if quirksConditions(token.name, token.pubid, token.sysid, token.flags): parser.setQuirksMode(QUIRKS) elif limitedQuirksConditions(token.pubid, token.flags): parser.setQuirksMode(LIMITED_QUIRKS) parser.insertionMode = imBeforeHtml else: parser.setQuirksMode(QUIRKS) parser.insertionMode = imBeforeHtml return reprocess token of imBeforeHtml: case token.t of ttDoctype, ttWhitespace: discard of ttComment: parser.insertComment(token, lastChildOf(parser.getDocument())) of ttStartTag: if parser.toTagType(token.tagname) == TAG_HTML: let intendedParent = parser.getDocument() let element = parser.createHTMLElementForToken(token, intendedParent) parser.append(parser.getDocument(), element) parser.pushElement(element, token) parser.insertionMode = imBeforeHead else: anythingElse = true of ttEndTag: anythingElse = parser.toTagType(token.tagname) in {TAG_HEAD, TAG_BODY, TAG_HTML, TAG_BR} else: anythingElse = true if anythingElse: let element = parser.createHTMLElement() parser.append(parser.getDocument(), element) let html = parser.newStartTagToken(TAG_HTML) parser.pushElement(element, html) parser.insertionMode = imBeforeHead return reprocess token of imBeforeHead: case token.t of ttWhitespace, ttDoctype: discard of ttComment: parser.insertComment(token) of ttStartTag: case parser.toTagType(token.tagname) of TAG_HTML: return reprocess imInBody of TAG_HEAD: parser.head = some((parser.insertHTMLElement(token), token)) parser.insertionMode = imInHead else: anythingElse = true of ttEndTag: anythingElse = parser.toTagType(token.tagname) in {TAG_HEAD, TAG_BODY, TAG_HTML, TAG_BR} else: anythingElse = true if anythingElse: let head = parser.newStartTagToken(TAG_HEAD) parser.head = some((parser.insertHTMLElement(head), head)) parser.insertionMode = imInHead return reprocess token of imInHead: case token.t of ttWhitespace: parser.insertCharacter(token.s) of ttComment: parser.insertComment(token) of ttDoctype: discard of ttStartTag: case parser.toTagType(token.tagname) of TAG_HTML: return reprocess imInBody of TAG_BASE, TAG_BASEFONT, TAG_BGSOUND, TAG_LINK: parser.insertHTMLElementPop(token) of TAG_META: parser.insertHTMLElementPop(token) token.attrs.withValue(parser.toAtom(TAG_CHARSET), p): case parser.setEncoding(p[]) of SET_ENCODING_CONTINUE: discard of SET_ENCODING_STOP: return PRES_STOP do: token.attrs.withValue(parser.toAtom(TAG_HTTP_EQUIV), p): if p[].equalsIgnoreCase("Content-Type"): token.attrs.withValue(parser.toAtom(TAG_CONTENT), p2): let cs = extractEncFromMeta(p2[]) if cs != "": case parser.setEncoding(cs) of SET_ENCODING_CONTINUE: discard of SET_ENCODING_STOP: return PRES_STOP of TAG_TITLE: parser.genericRCDATAElementParsingAlgorithm(token) of TAG_NOSCRIPT: if not parser.opts.scripting: discard parser.insertHTMLElement(token) parser.insertionMode = imInHeadNoscript else: parser.genericRawtextElementParsingAlgorithm(token) of TAG_NOFRAMES, TAG_STYLE: parser.genericRawtextElementParsingAlgorithm(token) of TAG_SCRIPT: let location = parser.appropriatePlaceForInsert() let element = parser.createElementForToken(token, Namespace.HTML, location.inside) if parser.ctx.isSome: parser.setScriptAlreadyStarted(element) parser.insert(location, element) parser.pushElement(element, token) parser.tokenizer.state = SCRIPT_DATA parser.oldInsertionMode = parser.insertionMode parser.insertionMode = imInText of TAG_TEMPLATE: discard parser.insertHTMLElement(token) parser.activeFormatting.add((none(Handle), nil)) parser.framesetOk = false parser.insertionMode = imInTemplate parser.templateModes.add(imInTemplate) of TAG_HEAD: discard else: anythingElse = true of ttEndTag: case parser.toTagType(token.tagname) of TAG_HEAD: discard parser.popElement() parser.insertionMode = imAfterHead of TAG_TEMPLATE: if parser.hasElement(TAG_TEMPLATE): parser.generateImpliedEndTagsThoroughly() parser.popElementsIncl(TAG_TEMPLATE) parser.clearActiveFormattingTillMarker() discard parser.templateModes.pop() parser.resetInsertionMode() of TAG_BODY, TAG_HTML, TAG_BR: anythingElse = true else: discard else: anythingElse = true if anythingElse: discard parser.popElement() parser.insertionMode = imAfterHead return reprocess token of imInHeadNoscript: case token.t of ttDoctype: discard of ttStartTag: case parser.toTagType(token.tagname) of TAG_HEAD, TAG_NOSCRIPT: discard of TAG_HTML: return reprocess imInBody of TAG_BASEFONT, TAG_BGSOUND, TAG_LINK, TAG_META, TAG_NOFRAMES, TAG_STYLE: return reprocess imInHead else: anythingElse = true of ttEndTag: case parser.toTagType(token.tagname) of TAG_BR: anythingElse = true of TAG_NOSCRIPT: discard parser.popElement() parser.insertionMode = imInHead else: discard of ttWhitespace, ttComment: return reprocess imInHead else: anythingElse = true if anythingElse: discard parser.popElement() parser.insertionMode = imInHead return reprocess token of imAfterHead: case token.t of ttWhitespace: parser.insertCharacter(token.s) of ttComment: parser.insertComment(token) of ttDoctype: discard of ttStartTag: case parser.toTagType(token.tagname) of TAG_HEAD: discard of TAG_HTML: return reprocess imInBody of TAG_BODY: discard parser.insertHTMLElement(token) parser.framesetOk = false parser.insertionMode = imInBody of TAG_FRAMESET: discard parser.insertHTMLElement(token) parser.insertionMode = imInFrameset of TAG_BASE, TAG_BASEFONT, TAG_BGSOUND, TAG_LINK, TAG_META, TAG_NOFRAMES, TAG_SCRIPT, TAG_STYLE, TAG_TEMPLATE, TAG_TITLE: let (head, headTok) = parser.head.get parser.pushElement(head, headTok) result = reprocess imInHead if (let i = parser.findOpenElement(head); i != -1): parser.openElements.delete(i) else: anythingElse = true of ttEndTag: case parser.toTagType(token.tagname) of TAG_TEMPLATE: return reprocess imInHead of TAG_BODY, TAG_HTML, TAG_BR: anythingElse = true else: discard else: anythingElse = true if anythingElse: discard parser.insertHTMLElement(parser.newStartTagToken(TAG_BODY)) parser.insertionMode = imInBody return reprocess token of imInBody: case token.t of ttWhitespace: parser.reconstructActiveFormatting() parser.insertCharacter(token.s) of ttNull, ttDoctype: discard of ttCharacter: parser.reconstructActiveFormatting() parser.insertCharacter(token.s) parser.framesetOk = false of ttComment: parser.insertComment(token) of ttStartTag: let tagType = parser.toTagType(token.tagname) case tagType of TAG_HTML: if not parser.hasElement(TAG_TEMPLATE): parser.addAttrsIfMissing(parser.openElements[0].element, token.attrs) of TAG_BASE, TAG_BASEFONT, TAG_BGSOUND, TAG_LINK, TAG_META, TAG_NOFRAMES, TAG_SCRIPT, TAG_STYLE, TAG_TEMPLATE, TAG_TITLE: return reprocess imInHead of TAG_BODY: if parser.openElements.len == 1 or parser.getTagType(parser.openElements[1].element) != TAG_BODY or parser.hasElement(TAG_TEMPLATE): discard else: parser.framesetOk = false parser.addAttrsIfMissing(parser.openElements[1].element, token.attrs) of TAG_FRAMESET: if parser.openElements.len == 1 or parser.getTagType(parser.openElements[1].element) != TAG_BODY or not parser.framesetOk: discard else: parser.remove(parser.openElements[1].element) while parser.openElements.len > 1: discard parser.popElement() discard parser.insertHTMLElement(token) parser.insertionMode = imInFrameset of TAG_ADDRESS, TAG_ARTICLE, TAG_ASIDE, TAG_BLOCKQUOTE, TAG_CENTER, TAG_DETAILS, TAG_DIALOG, TAG_DIR, TAG_DIV, TAG_DL, TAG_FIELDSET, TAG_FIGCAPTION, TAG_FIGURE, TAG_FOOTER, TAG_HEADER, TAG_HGROUP, TAG_MAIN, TAG_MENU, TAG_NAV, TAG_OL, TAG_P, TAG_SEARCH, TAG_SECTION, TAG_SUMMARY, TAG_UL: parser.closeP() discard parser.insertHTMLElement(token) of TAG_H1, TAG_H2, TAG_H3, TAG_H4, TAG_H5, TAG_H6: parser.closeP() if parser.getTagType(parser.currentNode) in HTagTypes: discard parser.popElement() discard parser.insertHTMLElement(token) of TAG_PRE, TAG_LISTING: parser.closeP() discard parser.insertHTMLElement(token) parser.ignoreLF = true parser.framesetOk = false of TAG_FORM: let hasTemplate = parser.hasElement(TAG_TEMPLATE) if parser.form.isNone or hasTemplate: parser.closeP() let element = parser.insertHTMLElement(token) if not hasTemplate: parser.form = some(element) of TAG_LI: parser.framesetOk = false for node in parser.ropenElements: let tagType = parser.getTagType(node) case tagType of TAG_LI: parser.popElementsIncl(TAG_LI) break of TAG_ADDRESS, TAG_DIV, TAG_P: discard elif parser.isSpecialElement(node): break else: discard parser.closeP() discard parser.insertHTMLElement(token) of TAG_DD, TAG_DT: parser.framesetOk = false for node in parser.ropenElements: let tagType = parser.getTagType(node) case tagType of TAG_DD: parser.popElementsIncl(TAG_DD) break of TAG_DT: parser.popElementsIncl(TAG_DT) break of TAG_ADDRESS, TAG_DIV, TAG_P: discard elif parser.isSpecialElement(node): break else: discard parser.closeP() discard parser.insertHTMLElement(token) of TAG_PLAINTEXT: parser.closeP() discard parser.insertHTMLElement(token) parser.tokenizer.state = PLAINTEXT of TAG_BUTTON: discard parser.hasElementInScopePop(TAG_BUTTON) parser.reconstructActiveFormatting() discard parser.insertHTMLElement(token) parser.framesetOk = false of TAG_A: let i = parser.findLastActiveFormattingAfterMarker(TAG_A) if i != -1: let anchor = parser.activeFormatting[i][0].get if parser.adoptionAgencyAlgorithm(token): return parser.otherBodyEndTag(token.tagname) let j = parser.findLastActiveFormatting(anchor) if j != -1: parser.activeFormatting.delete(j) let k = parser.findOpenElement(anchor) if k != -1: parser.openElements.delete(k) parser.reconstructActiveFormatting() let element = parser.insertHTMLElement(token) parser.pushActiveFormatting(element, token) of TAG_B, TAG_BIG, TAG_CODE, TAG_EM, TAG_FONT, TAG_I, TAG_S, TAG_SMALL, TAG_STRIKE, TAG_STRONG, TAG_TT, TAG_U: parser.reconstructActiveFormatting() let element = parser.insertHTMLElement(token) parser.pushActiveFormatting(element, token) of TAG_NOBR: parser.reconstructActiveFormatting() if parser.hasElementInScope(TAG_NOBR): if parser.adoptionAgencyAlgorithm(token): return parser.otherBodyEndTag(token.tagname) parser.reconstructActiveFormatting() let element = parser.insertHTMLElement(token) parser.pushActiveFormatting(element, token) of TAG_APPLET, TAG_MARQUEE, TAG_OBJECT: parser.reconstructActiveFormatting() discard parser.insertHTMLElement(token) parser.activeFormatting.add((none(Handle), nil)) parser.framesetOk = false of TAG_TABLE: if parser.quirksMode != QUIRKS: parser.closeP() discard parser.insertHTMLElement(token) parser.framesetOk = false parser.insertionMode = imInTable of TAG_AREA, TAG_BR, TAG_EMBED, TAG_IMG, TAG_KEYGEN, TAG_WBR: parser.reconstructActiveFormatting() parser.insertHTMLElementPop(token) parser.framesetOk = false of TAG_INPUT: if parser.ctx.isNone or parser.getTagType(parser.ctx.get.element) != TAG_SELECT: discard parser.hasElementInScopePop(TAG_SELECT) parser.reconstructActiveFormatting() parser.insertHTMLElementPop(token) token.attrs.withValue(parser.toAtom(TAG_TYP), p): if not p[].equalsIgnoreCase("hidden"): parser.framesetOk = false do: parser.framesetOk = false of TAG_PARAM, TAG_SOURCE, TAG_TRACK: parser.insertHTMLElementPop(token) of TAG_HR: parser.closeP() if parser.hasElementInScope(TAG_SELECT): parser.generateImpliedEndTags() parser.insertHTMLElementPop(token) parser.framesetOk = false of TAG_IMAGE: token.tagname = parser.toAtom(TAG_IMG) return reprocess token of TAG_TEXTAREA: discard parser.insertHTMLElement(token) parser.ignoreLF = true parser.tokenizer.state = RCDATA parser.oldInsertionMode = parser.insertionMode parser.framesetOk = false parser.insertionMode = imInText of TAG_XMP: parser.closeP() parser.reconstructActiveFormatting() parser.framesetOk = false parser.genericRawtextElementParsingAlgorithm(token) of TAG_IFRAME: parser.framesetOk = false parser.genericRawtextElementParsingAlgorithm(token) of TAG_NOEMBED: parser.genericRawtextElementParsingAlgorithm(token) of TAG_NOSCRIPT: if parser.opts.scripting: parser.genericRawtextElementParsingAlgorithm(token) else: parser.reconstructActiveFormatting() discard parser.insertHTMLElement(token) of TAG_SELECT: if parser.ctx.isSome and parser.getTagType(parser.ctx.get.element) == TAG_SELECT: discard elif not parser.hasElementInScopePop(TAG_SELECT): parser.reconstructActiveFormatting() discard parser.insertHTMLElement(token) parser.framesetOk = false of TAG_OPTION, TAG_OPTGROUP: if parser.hasElementInScope(TAG_SELECT): if tagType == TAG_OPTION: parser.generateImpliedEndTags(TAG_OPTGROUP) else: parser.generateImpliedEndTags() elif parser.getTagType(parser.currentNode) == TAG_OPTION: discard parser.popElement() parser.reconstructActiveFormatting() discard parser.insertHTMLElement(token) of TAG_RB, TAG_RTC: if parser.hasElementInScope(TAG_RUBY): parser.generateImpliedEndTags() discard parser.insertHTMLElement(token) of TAG_RP, TAG_RT: if parser.hasElementInScope(TAG_RUBY): parser.generateImpliedEndTags(TAG_RTC) discard parser.insertHTMLElement(token) of TAG_MATH: parser.reconstructActiveFormatting() var xmlAttrs: seq[ParsedAttr[Atom]] = @[] parser.adjustMathMLAttributes(token.attrs, xmlAttrs) discard parser.insertForeignElement(token, token.tagname, Namespace.MATHML, false, xmlAttrs) if tfSelfClosing in token.flags: discard parser.popElement() of TAG_SVG: parser.reconstructActiveFormatting() var xmlAttrs: seq[ParsedAttr[Atom]] = @[] parser.adjustSVGAttributes(token.attrs, xmlAttrs) discard parser.insertForeignElement(token, token.tagname, Namespace.SVG, false, xmlAttrs) if tfSelfClosing in token.flags: discard parser.popElement() of TAG_CAPTION, TAG_COL, TAG_COLGROUP, TAG_FRAME, TAG_HEAD, TAG_TBODY, TAG_TD, TAG_TFOOT, TAG_TH, TAG_THEAD, TAG_TR: discard else: parser.reconstructActiveFormatting() discard parser.insertHTMLElement(token) of ttEndTag: case (let tokTagType = parser.toTagType(token.tagname); tokTagType) of TAG_TEMPLATE: return reprocess imInHead of TAG_BODY: if parser.hasElementInScope(TAG_BODY): parser.insertionMode = imAfterBody of TAG_HTML: if parser.hasElementInScope(TAG_BODY): parser.insertionMode = imAfterBody return reprocess token of TAG_ADDRESS, TAG_ARTICLE, TAG_ASIDE, TAG_BLOCKQUOTE, TAG_BUTTON, TAG_CENTER, TAG_DETAILS, TAG_DIALOG, TAG_DIR, TAG_DIV, TAG_DL, TAG_FIELDSET, TAG_FIGCAPTION, TAG_FIGURE, TAG_FOOTER, TAG_HEADER, TAG_HGROUP, TAG_LISTING, TAG_MAIN, TAG_MENU, TAG_NAV, TAG_OL, TAG_PRE, TAG_SEARCH, TAG_SECTION, TAG_SELECT, TAG_SUMMARY, TAG_UL: discard parser.hasElementInScopePop(tokTagType) of TAG_FORM: if not parser.hasElement(TAG_TEMPLATE): let form = parser.form parser.form = none(Handle) if form.isNone or not parser.hasElementInScope(form.get): return let node = form.get parser.generateImpliedEndTags() let i = parser.findOpenElement(node) parser.openElements.delete(i) else: discard parser.hasElementInScopePop(TAG_FORM) of TAG_P: if not parser.hasElementInButtonScope(TAG_P): discard parser.insertHTMLElement(parser.newStartTagToken(TAG_P)) parser.closeP(sure = true) of TAG_LI: if parser.hasElementInListItemScope(TAG_LI): parser.popElementsIncl(TAG_LI) of TAG_DD, TAG_DT: discard parser.hasElementInScopePop(tokTagType) of TAG_H1, TAG_H2, TAG_H3, TAG_H4, TAG_H5, TAG_H6: if parser.hasElementInScope(TAG_H1): while parser.getTagType(parser.popElement()) notin TAG_H1..TAG_H6: discard of TAG_A, TAG_B, TAG_BIG, TAG_CODE, TAG_EM, TAG_FONT, TAG_I, TAG_NOBR, TAG_S, TAG_SMALL, TAG_STRIKE, TAG_STRONG, TAG_TT, TAG_U: if parser.adoptionAgencyAlgorithm(token): return parser.otherBodyEndTag(token.tagname) of TAG_APPLET, TAG_MARQUEE, TAG_OBJECT: if parser.hasElementInScopePop(tokTagType): parser.clearActiveFormattingTillMarker() of TAG_BR: return reprocess parser.newStartTagToken(TAG_BR) else: return parser.otherBodyEndTag(token.tagname) of imInText: case token.t of ttCharacter, ttWhitespace: parser.insertCharacter(token.s) of ttEndTag: discard parser.popElement() parser.insertionMode = parser.oldInsertionMode if parser.opts.scripting: if parser.toTagType(token.tagname) == TAG_SCRIPT: return PRES_SCRIPT else: assert false # unreachable of imInTable: case token.t of ttCharacter, ttWhitespace, ttNull: const CanHaveText = { TAG_TABLE, TAG_TBODY, TAG_TFOOT, TAG_THEAD, TAG_TR } if parser.getTagType(parser.currentNode) in CanHaveText: parser.pendingTableChars = "" parser.pendingTableCharsWhitespace = true parser.oldInsertionMode = parser.insertionMode parser.insertionMode = imInTableInText return reprocess token else: # anything else parser.fosterParenting = true result = reprocess imInBody parser.fosterParenting = false of ttComment: parser.insertComment(token) of ttDoctype: discard of ttStartTag: case parser.toTagType(token.tagname) of TAG_CAPTION: parser.popTableContext() parser.activeFormatting.add((none(Handle), nil)) discard parser.insertHTMLElement(token) parser.insertionMode = imInCaption of TAG_COLGROUP: parser.popTableContext() let colgroupTok = parser.newStartTagToken(TAG_COLGROUP) discard parser.insertHTMLElement(colgroupTok) parser.insertionMode = imInColumnGroup of TAG_COL: parser.popTableContext() let colgroupTok = parser.newStartTagToken(TAG_COLGROUP) discard parser.insertHTMLElement(colgroupTok) parser.insertionMode = imInColumnGroup return reprocess token of TAG_TBODY, TAG_TFOOT, TAG_THEAD: parser.popTableContext() discard parser.insertHTMLElement(token) parser.insertionMode = imInTableBody of TAG_TD, TAG_TH, TAG_TR: parser.popTableContext() discard parser.insertHTMLElement(parser.newStartTagToken(TAG_TBODY)) parser.insertionMode = imInTableBody return reprocess token of TAG_TABLE: if parser.hasElementInTableScope(TAG_TABLE): parser.popElementsIncl(TAG_TABLE) parser.resetInsertionMode() return reprocess token of TAG_INPUT: token.attrs.withValue(parser.toAtom(TAG_TYP), p): if not p[].equalsIgnoreCase("hidden"): # anything else parser.fosterParenting = true result = reprocess imInBody parser.fosterParenting = false else: parser.insertHTMLElementPop(token) do: anythingElse = true of TAG_STYLE, TAG_SCRIPT, TAG_TEMPLATE: return reprocess imInHead of TAG_FORM: if parser.form.isNone and not parser.hasElement(TAG_TEMPLATE): parser.form = some(parser.insertHTMLElement(token)) discard parser.popElement() else: anythingElse = true of ttEndTag: case parser.toTagType(token.tagname) of TAG_TABLE: if parser.hasElementInTableScope(TAG_TABLE): parser.popElementsIncl(TAG_TABLE) parser.resetInsertionMode() of TAG_BODY, TAG_CAPTION, TAG_COL, TAG_COLGROUP, TAG_HTML, TAG_TBODY, TAG_TD, TAG_TFOOT, TAG_TH, TAG_THEAD, TAG_TR: discard of TAG_TEMPLATE: return reprocess imInHead else: anythingElse = true if anythingElse: parser.fosterParenting = true result = reprocess imInBody parser.fosterParenting = false of imInTableInText: case token.t of ttNull: discard of ttWhitespace: parser.pendingTableChars &= token.s of ttCharacter: parser.pendingTableCharsWhitespace = false parser.pendingTableChars &= token.s else: if not parser.pendingTableCharsWhitespace: # I *think* this is effectively the same thing the specification # wants... parser.fosterParenting = true parser.reconstructActiveFormatting() parser.insertCharacter(parser.pendingTableChars) parser.framesetOk = false parser.fosterParenting = false else: parser.insertCharacter(parser.pendingTableChars) parser.insertionMode = parser.oldInsertionMode return reprocess token of imInCaption: case token.t of ttStartTag: case parser.toTagType(token.tagname) of TAG_CAPTION, TAG_COL, TAG_COLGROUP, TAG_TBODY, TAG_TD, TAG_TFOOT, TAG_TH, TAG_THEAD, TAG_TR: if parser.hasElementInTableScope(TAG_CAPTION): parser.popElementsIncl(TAG_CAPTION) parser.clearActiveFormattingTillMarker() parser.insertionMode = imInTable return reprocess token else: anythingElse = true of ttEndTag: case (let tokTagType = parser.toTagType(token.tagname); tokTagType) of TAG_CAPTION, TAG_TABLE: if parser.hasElementInTableScope(TAG_CAPTION): parser.popElementsIncl(TAG_CAPTION) parser.clearActiveFormattingTillMarker() parser.insertionMode = imInTable if tokTagType == TAG_TABLE: return reprocess token of TAG_BODY, TAG_COL, TAG_COLGROUP, TAG_HTML, TAG_TBODY, TAG_TD, TAG_TFOOT, TAG_TH, TAG_THEAD, TAG_TR: discard else: anythingElse = true else: anythingElse = true if anythingElse: return reprocess imInBody of imInColumnGroup: case token.t of ttWhitespace: parser.insertCharacter(token.s) of ttComment: parser.insertComment(token) of ttDoctype: discard of ttStartTag: case parser.toTagType(token.tagname) of TAG_HTML: return reprocess imInBody of TAG_COL: parser.insertHTMLElementPop(token) of TAG_TEMPLATE: return reprocess imInHead else: anythingElse = true of ttEndTag: case parser.toTagType(token.tagname) of TAG_COL: discard of TAG_COLGROUP: if parser.getTagType(parser.currentNode) == TAG_COLGROUP: discard parser.popElement() parser.insertionMode = imInTable of TAG_TEMPLATE: return reprocess imInHead else: anythingElse = true else: anythingElse = true if anythingElse: if parser.getTagType(parser.currentNode) == TAG_COLGROUP: discard parser.popElement() parser.insertionMode = imInTable return reprocess token of imInTableBody: case token.t of ttStartTag: case parser.toTagType(token.tagname) of TAG_TR: parser.popTableBodyContext() discard parser.insertHTMLElement(token) parser.insertionMode = imInRow of TAG_TH, TAG_TD: parser.popTableBodyContext() discard parser.insertHTMLElement(parser.newStartTagToken(TAG_TR)) parser.insertionMode = imInRow return reprocess token of TAG_CAPTION, TAG_COL, TAG_COLGROUP, TAG_TBODY, TAG_TFOOT, TAG_THEAD: if parser.hasElementInTableScope({TAG_TBODY, TAG_THEAD, TAG_TFOOT}): parser.popTableBodyContext() discard parser.popElement() parser.insertionMode = imInTable return reprocess token else: return reprocess imInTable of ttEndTag: case (let tokTagType = parser.toTagType(token.tagname); tokTagType) of TAG_TBODY, TAG_TFOOT, TAG_THEAD, TAG_TABLE: if parser.hasElementInTableScope(tokTagType): parser.popTableBodyContext() discard parser.popElement() parser.insertionMode = imInTable if tokTagType == TAG_TABLE: return reprocess token of TAG_BODY, TAG_CAPTION, TAG_COL, TAG_COLGROUP, TAG_HTML, TAG_TD, TAG_TH, TAG_TR: discard else: return reprocess imInTable else: return reprocess imInTable of imInRow: case token.t of ttStartTag: case parser.toTagType(token.tagname) of TAG_TH, TAG_TD: parser.popTableRowContext() discard parser.insertHTMLElement(token) parser.insertionMode = imInCell parser.activeFormatting.add((none(Handle), nil)) of TAG_CAPTION, TAG_COL, TAG_COLGROUP, TAG_TBODY, TAG_TFOOT, TAG_THEAD, TAG_TR: if parser.hasElementInTableScope(TAG_TR): parser.popTableRowContext() discard parser.popElement() parser.insertionMode = imInTableBody return reprocess token else: return reprocess imInTable of ttEndTag: case (let tokTagType = parser.toTagType(token.tagname); tokTagType) of TAG_TR: if parser.hasElementInTableScope(TAG_TR): parser.popTableRowContext() discard parser.popElement() parser.insertionMode = imInTableBody of TAG_TABLE: if parser.hasElementInTableScope(TAG_TR): parser.popTableRowContext() discard parser.popElement() parser.insertionMode = imInTableBody return reprocess token of TAG_TBODY, TAG_TFOOT, TAG_THEAD: if parser.hasElementInTableScope({tokTagType, TAG_TR}): parser.popTableRowContext() discard parser.popElement() parser.insertionMode = imInTableBody return reprocess token of TAG_BODY, TAG_CAPTION, TAG_COL, TAG_COLGROUP, TAG_HTML, TAG_TD, TAG_TH: discard else: return reprocess imInTable else: return reprocess imInTable of imInCell: case token.t of ttStartTag: case parser.toTagType(token.tagname) of TAG_CAPTION, TAG_COL, TAG_COLGROUP, TAG_TBODY, TAG_TD, TAG_TFOOT, TAG_TH, TAG_THEAD, TAG_TR: if parser.hasElementInTableScope({TAG_TD, TAG_TH}): parser.closeCell() return reprocess token else: return reprocess imInBody of ttEndTag: case (let tokTagType = parser.toTagType(token.tagname); tokTagType) of TAG_TD, TAG_TH: if parser.hasElementInTableScope(tokTagType): parser.popElementsIncl(tokTagType) parser.clearActiveFormattingTillMarker() parser.insertionMode = imInRow of TAG_BODY, TAG_CAPTION, TAG_COL, TAG_COLGROUP, TAG_HTML: discard of TAG_TABLE, TAG_TBODY, TAG_TFOOT, TAG_THEAD, TAG_TR: if parser.hasElementInTableScope(tokTagType): parser.closeCell() return reprocess token else: return reprocess imInBody else: return reprocess imInBody of imInTemplate: case token.t of ttCharacter, ttWhitespace, ttNull, ttDoctype, ttComment: return reprocess imInBody of ttStartTag: case parser.toTagType(token.tagname) of TAG_BASE, TAG_BASEFONT, TAG_BGSOUND, TAG_LINK, TAG_META, TAG_NOFRAMES, TAG_SCRIPT, TAG_STYLE, TAG_TEMPLATE, TAG_TITLE: return reprocess imInHead of TAG_CAPTION, TAG_COLGROUP, TAG_TBODY, TAG_TFOOT, TAG_THEAD: discard parser.templateModes.pop() parser.templateModes.add(imInTable) parser.insertionMode = imInTable return reprocess token of TAG_COL: discard parser.templateModes.pop() parser.templateModes.add(imInColumnGroup) parser.insertionMode = imInColumnGroup return reprocess token of TAG_TR: discard parser.templateModes.pop() parser.templateModes.add(imInTableBody) parser.insertionMode = imInTableBody return reprocess token of TAG_TD, TAG_TH: discard parser.templateModes.pop() parser.templateModes.add(imInRow) parser.insertionMode = imInRow return reprocess token else: discard parser.templateModes.pop() parser.templateModes.add(imInBody) parser.insertionMode = imInBody return reprocess token of ttEndTag: if parser.toTagType(token.tagname) == TAG_TEMPLATE: return reprocess imInHead of imAfterBody: case token.t of ttWhitespace: return reprocess imInBody of ttComment: parser.insertComment(token, lastChildOf(parser.openElements[0])) of ttDoctype: discard of ttStartTag: if parser.toTagType(token.tagname) == TAG_HTML: return reprocess imInBody parser.insertionMode = imInBody return reprocess token of ttEndTag: if parser.toTagType(token.tagname) == TAG_HTML: if parser.ctx.isNone: parser.insertionMode = imAfterAfterBody else: parser.insertionMode = imInBody return reprocess token else: parser.insertionMode = imInBody return reprocess token of imInFrameset: case token.t of ttWhitespace: parser.insertCharacter(token.s) of ttComment: parser.insertComment(token) of ttDoctype: discard of ttStartTag: case parser.toTagType(token.tagname) of TAG_HTML: return reprocess imInBody of TAG_FRAMESET: discard parser.insertHTMLElement(token) of TAG_FRAME: parser.insertHTMLElementPop(token) of TAG_NOFRAMES: return reprocess imInHead else: discard of ttEndTag: if parser.toTagType(token.tagname) == TAG_FRAMESET: if parser.getTagType(parser.currentNode) != TAG_HTML: discard parser.popElement() if parser.ctx.isNone and parser.getTagType(parser.currentNode) != TAG_FRAMESET: parser.insertionMode = imAfterFrameset else: discard of imAfterFrameset: case token.t of ttWhitespace: parser.insertCharacter(token.s) of ttComment: parser.insertComment(token) of ttStartTag: case parser.toTagType(token.tagname) of TAG_HTML: return reprocess imInBody of TAG_NOFRAMES: return reprocess imInHead else: discard of ttEndTag: if parser.toTagType(token.tagname) == TAG_HTML: parser.insertionMode = imAfterAfterFrameset else: discard of imAfterAfterBody: case token.t of ttComment: parser.insertComment(token, lastChildOf(parser.getDocument())) of ttDoctype, ttWhitespace: return reprocess imInBody of ttStartTag: if parser.toTagType(token.tagname) == TAG_HTML: return reprocess imInBody parser.insertionMode = imInBody return reprocess token else: parser.insertionMode = imInBody return reprocess token of imAfterAfterFrameset: case token.t of ttComment: parser.insertComment(token, lastChildOf(parser.getDocument())) of ttDoctype, ttWhitespace: return reprocess imInBody of ttStartTag: case parser.toTagType(token.tagname) of TAG_HTML: return reprocess imInBody of TAG_NOFRAMES: return reprocess imInHead else: discard else: discard return PRES_CONTINUE proc processEOF[Handle, Atom](parser: var HTML5Parser[Handle, Atom]) = var insertionMode = parser.insertionMode if insertionMode == imInitial: parser.setQuirksMode(QUIRKS) insertionMode = imBeforeHtml if insertionMode == imBeforeHtml: let element = parser.createHTMLElement() parser.append(parser.getDocument(), element) let html = parser.newStartTagToken(TAG_HTML) parser.pushElement(element, html) insertionMode = imBeforeHead if insertionMode == imBeforeHead: let head = parser.newStartTagToken(TAG_HEAD) parser.head = some((parser.insertHTMLElement(head), head)) insertionMode = imInHead if insertionMode == imInHeadNoscript: discard parser.popElement() insertionMode = imInHead if insertionMode == imInHead: discard parser.popElement() insertionMode = imAfterHead if insertionMode == imAfterHead: discard parser.insertHTMLElement(parser.newStartTagToken(TAG_BODY)) insertionMode = imInBody case insertionMode of imInBody, imInCaption, imInColumnGroup, imInCell, imInTable, imInTableBody, imInRow, imInTemplate: if parser.templateModes.len > 0 and parser.hasElement(TAG_TEMPLATE): parser.popElementsIncl(TAG_TEMPLATE) parser.clearActiveFormattingTillMarker() discard parser.templateModes.pop() parser.resetInsertionMode() parser.processEOF() of imInText: if parser.getTagType(parser.currentNode) == TAG_SCRIPT: parser.setScriptAlreadyStarted(parser.currentNode) discard parser.popElement() parser.insertionMode = parser.oldInsertionMode parser.processEOF() of imInTableInText: if not parser.pendingTableCharsWhitespace: # I *think* this is effectively the same thing the specification # wants... parser.fosterParenting = true parser.reconstructActiveFormatting() parser.insertCharacter(parser.pendingTableChars) parser.framesetOk = false parser.fosterParenting = false else: parser.insertCharacter(parser.pendingTableChars) parser.insertionMode = parser.oldInsertionMode parser.processEOF() else: discard proc processHTMLForeignTag[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; token: Token): ParseResult = while not parser.isMathMLIntegrationPoint(parser.currentNode) and not parser.isHTMLIntegrationPoint(parser.currentNodeToken) and parser.getNamespace(parser.currentNode) != Namespace.HTML: discard parser.popElement() return parser.processInHTML(token, parser.insertionMode) proc otherForeignStartTag[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; token: Token): ParseResult = let namespace = parser.getNamespace(parser.adjustedCurrentNode) var tagname = token.tagname var xmlAttrs: seq[ParsedAttr[Atom]] = @[] if namespace == Namespace.SVG: parser.caseTable.withValue(tagname, p): tagname = p[] parser.adjustSVGAttributes(token.attrs, xmlAttrs) elif namespace == Namespace.MATHML: parser.adjustMathMLAttributes(token.attrs, xmlAttrs) discard parser.insertForeignElement(token, tagname, namespace, false, xmlAttrs) if tfSelfClosing in token.flags: discard parser.popElement() if namespace == Namespace.SVG and parser.toTagType(tagname) == TAG_SCRIPT: return PRES_SCRIPT return PRES_CONTINUE proc otherForeignEndTag[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; token: Token): ParseResult = for i in countdown(parser.openElements.high, 0): # loop if i == 0: # fragment case assert parser.ctx.isSome break let (node, nodeToken) = parser.openElements[i] if i != parser.openElements.high and parser.getNamespace(node) == Namespace.HTML: return parser.processInHTML(token, parser.insertionMode) if nodeToken.tagname == token.tagname: # Compare the start tag token, since it is guaranteed to be lower case. # (The local name might have been adjusted to a non-lower-case string.) parser.popElementsIncl(node) break return PRES_CONTINUE proc processInForeign[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; token: Token): ParseResult = case token.t of ttNull: parser.insertCharacter("\uFFFD") of ttWhitespace: parser.insertCharacter(token.s) of ttCharacter: parser.insertCharacter(token.s) parser.framesetOk = false of ttComment: parser.insertComment(token) of ttDoctype: discard of ttStartTag: case parser.toTagType(token.tagname) of TAG_B, TAG_BIG, TAG_BLOCKQUOTE, TAG_BODY, TAG_BR, TAG_CENTER, TAG_CODE, TAG_DD, TAG_DIV, TAG_DL, TAG_DT, TAG_EM, TAG_EMBED, TAG_H1, TAG_H2, TAG_H3, TAG_H4, TAG_H5, TAG_H6, TAG_HEAD, TAG_HR, TAG_I, TAG_IMG, TAG_LI, TAG_LISTING, TAG_MENU, TAG_META, TAG_NOBR, TAG_OL, TAG_P, TAG_PRE, TAG_RUBY, TAG_S, TAG_SMALL, TAG_SPAN, TAG_STRONG, TAG_STRIKE, TAG_SUB, TAG_SUP, TAG_TABLE, TAG_TT, TAG_U, TAG_UL, TAG_VAR: return parser.processHTMLForeignTag(token) of TAG_FONT: let atColor = parser.toAtom(TAG_COLOR) let atFace = parser.toAtom(TAG_FACE) let atSize = parser.toAtom(TAG_SIZE) if atColor in token.attrs or atFace in token.attrs or atSize in token.attrs: return parser.processHTMLForeignTag(token) # fall through else: discard return parser.otherForeignStartTag(token) of ttEndTag: case parser.toTagType(token.tagname) of TAG_BR, TAG_P: return parser.processHTMLForeignTag(token) of TAG_SCRIPT: let namespace = parser.getNamespace(parser.currentNode) let localName = parser.currentToken.tagname # Any atom corresponding to the string "script" must have the same # value as TAG_SCRIPT, so this is correct. if namespace == Namespace.SVG and parser.toTagType(localName) == TAG_SCRIPT: discard parser.popElement() return PRES_SCRIPT # fall through else: discard return parser.otherForeignEndTag(token) return PRES_CONTINUE proc processToken[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; token: Token[Atom]): ParseResult = if parser.ignoreLF: parser.ignoreLF = false if token.t == ttWhitespace and token.s[0] == '\n': if token.s.len == 1: return PRES_CONTINUE else: for i in 1 ..< token.s.len: token.s[i - 1] = token.s[i] token.s.setLen(token.s.high) if parser.openElements.len == 0 or parser.getNamespace(parser.adjustedCurrentNode) == Namespace.HTML: return parser.processInHTML(token, parser.insertionMode) let oe = parser.adjustedCurrentNodeToken let oeTagType = parser.toTagType(oe.token.tagname) let namespace = parser.getNamespace(oe.element) const CharacterToken = {ttCharacter, ttWhitespace, ttNull} let mmlnoatoms = {TAG_MGLYPH, TAG_MALIGNMARK} let ismmlip = parser.isMathMLIntegrationPoint(oe.element) let ishtmlip = parser.isHTMLIntegrationPoint(oe) if token.t == ttStartTag and ( let tagType = parser.toTagType(token.tagname) ismmlip and tagType notin mmlnoatoms or ishtmlip or namespace == Namespace.MATHML and oeTagType == TAG_ANNOTATION_XML and tagType == TAG_SVG ) or token.t in CharacterToken and (ismmlip or ishtmlip): return parser.processInHTML(token, parser.insertionMode) return parser.processInForeign(token) const CaseTable = { "altglyph": "altGlyph", "altglyphdef": "altGlyphDef", "altglyphitem": "altGlyphItem", "animatecolor": "animateColor", "animatemotion": "animateMotion", "animatetransform": "animateTransform", "clippath": "clipPath", "feblend": "feBlend", "fecolormatrix": "feColorMatrix", "fecomponenttransfer": "feComponentTransfer", "fecomposite": "feComposite", "feconvolvematrix": "feConvolveMatrix", "fediffuselighting": "feDiffuseLighting", "fedisplacementmap": "feDisplacementMap", "fedistantlight": "feDistantLight", "fedropshadow": "feDropShadow", "feflood": "feFlood", "fefunca": "feFuncA", "fefuncb": "feFuncB", "fefuncg": "feFuncG", "fefuncr": "feFuncR", "fegaussianblur": "feGaussianBlur", "feimage": "feImage", "femerge": "feMerge", "femergenode": "feMergeNode", "femorphology": "feMorphology", "feoffset": "feOffset", "fepointlight": "fePointLight", "fespecularlighting": "feSpecularLighting", "fespotlight": "feSpotLight", "fetile": "feTile", "feturbulence": "feTurbulence", "foreignobject": "foreignObject", "glyphref": "glyphRef", "lineargradient": "linearGradient", "radialgradient": "radialGradient", "textpath": "textPath", } proc createCaseTable[Handle, Atom](parser: var HTML5Parser[Handle, Atom]) = for (k, v) in CaseTable: let ka = parser.strToAtom(k) let va = parser.strToAtom(v) parser.caseTable[ka] = va const AdjustedTable = { "attributename": "attributeName", "attributetype": "attributeType", "basefrequency": "baseFrequency", "baseprofile": "baseProfile", "calcmode": "calcMode", "clippathunits": "clipPathUnits", "diffuseconstant": "diffuseConstant", "edgemode": "edgeMode", "filterunits": "filterUnits", "glyphref": "glyphRef", "gradienttransform": "gradientTransform", "gradientunits": "gradientUnits", "kernelmatrix": "kernelMatrix", "kernelunitlength": "kernelUnitLength", "keypoints": "keyPoints", "keysplines": "keySplines", "keytimes": "keyTimes", "lengthadjust": "lengthAdjust", "limitingconeangle": "limitingConeAngle", "markerheight": "markerHeight", "markerunits": "markerUnits", "markerwidth": "markerWidth", "maskcontentunits": "maskContentUnits", "maskunits": "maskUnits", "numoctaves": "numOctaves", "pathlength": "pathLength", "patterncontentunits": "patternContentUnits", "patterntransform": "patternTransform", "patternunits": "patternUnits", "pointsatx": "pointsAtX", "pointsaty": "pointsAtY", "pointsatz": "pointsAtZ", "preservealpha": "preserveAlpha", "preserveaspectratio": "preserveAspectRatio", "primitiveunits": "primitiveUnits", "refx": "refX", "refy": "refY", "repeatcount": "repeatCount", "repeatdur": "repeatDur", "requiredextensions": "requiredExtensions", "requiredfeatures": "requiredFeatures", "specularconstant": "specularConstant", "specularexponent": "specularExponent", "spreadmethod": "spreadMethod", "startoffset": "startOffset", "stddeviation": "stdDeviation", "stitchtiles": "stitchTiles", "surfacescale": "surfaceScale", "systemlanguage": "systemLanguage", "tablevalues": "tableValues", "targetx": "targetX", "targety": "targetY", "textlength": "textLength", "viewbox": "viewBox", "viewtarget": "viewTarget", "xchannelselector": "xChannelSelector", "ychannelselector": "yChannelSelector", "zoomandpan": "zoomAndPan", } proc createAdjustedTable[Handle, Atom](parser: var HTML5Parser[Handle, Atom]) = for (k, v) in AdjustedTable: let ka = parser.strToAtom(k) let va = parser.strToAtom(v) parser.adjustedTable[ka] = va const ForeignTable = { "xlink:actuate": (PREFIX_XLINK, "actuate", Namespace.XLINK), "xlink:arcrole": (PREFIX_XLINK, "arcrole", Namespace.XLINK), "xlink:href": (PREFIX_XLINK, "href", Namespace.XLINK), "xlink:role": (PREFIX_XLINK, "role", Namespace.XLINK), "xlink:show": (PREFIX_XLINK, "show", Namespace.XLINK), "xlink:title": (PREFIX_XLINK, "title", Namespace.XLINK), "xlink:type": (PREFIX_XLINK, "type", Namespace.XLINK), "xml:lang": (PREFIX_XML, "lang", Namespace.XML), "xml:space": (PREFIX_XML, "space", Namespace.XML), "xmlns": (NO_PREFIX, "xmlns", Namespace.XMLNS), "xmlns:xlink": (PREFIX_XMLNS, "xlink", Namespace.XMLNS), } proc createForeignTable[Handle, Atom](parser: var HTML5Parser[Handle, Atom]) = for (oldName, qualName) in ForeignTable: let (prefix, newName, ns) = qualName let oldNameAtom = parser.strToAtom(oldName) let newNameAtom = parser.strToAtom(newName) parser.foreignTable[oldNameAtom] = (prefix, ns, newNameAtom) proc initHTML5Parser*[Handle, Atom](dombuilder: DOMBuilder[Handle, Atom]; opts: HTML5ParserOpts[Handle, Atom]): HTML5Parser[Handle, Atom] = ## Create and initialize a new HTML5Parser object from dombuilder `dombuilder` ## and parser options `opts`. ## ## The generic `Handle` must be the node handle type of the DOM builder. The ## generic `Atom` must be the interned string type of the DOM builder. var parser = HTML5Parser[Handle, Atom]( dombuilder: dombuilder, opts: opts, form: opts.formInit, framesetOk: true ) if opts.ctx.isSome: let ctxInit = opts.ctx.get let ctx: OpenElement[Handle, Atom] = (ctxInit.element, Token[Atom]( t: ttStartTag, tagname: ctxInit.startTagName )) parser.ctx = some(ctx) for (element, tagName) in opts.openElementsInit: let it = (element, Token[Atom](t: ttStartTag, tagname: tagName)) parser.openElements.add(it) parser.createCaseTable() parser.createAdjustedTable() parser.createForeignTable() if opts.pushInTemplate: parser.templateModes.add(imInTemplate) if opts.openElementsInit.len > 0: parser.resetInsertionMode() let tokstate = opts.initialTokenizerState parser.tokenizer = newTokenizer[Handle, Atom](dombuilder, tokstate) return parser proc parseChunk*[Handle, Atom](parser: var HTML5Parser[Handle, Atom]; inputBuf: openArray[char]): ParseResult = ## Parse a chunk of characters stored in `inputBuf` with `parser`. var running = true parser.tokenizer.inputBufIdx = 0 while running: running = parser.tokenizer.tokenize(inputBuf) != trDone for i, token in parser.tokenizer.tokqueue: let pres = parser.processToken(token) if pres != PRES_CONTINUE: assert pres != PRES_SCRIPT or i == parser.tokenizer.tokqueue.high return pres return PRES_CONTINUE func getInsertionPoint*(parser: HTML5Parser): int = return parser.tokenizer.inputBufIdx proc finish*[Handle, Atom](parser: var HTML5Parser[Handle, Atom]) = ## Finish parsing the document associated with `parser`. ## This will process an EOF token, and pop all elements from the stack of ## open elements one by one. var running = true while running: running = parser.tokenizer.finish() != trDone for token in parser.tokenizer.tokqueue: let pres = parser.processToken(token) assert pres == PRES_CONTINUE # pres == PRES_SCRIPT: this is unreachable. # * Tokenizer's tokenizeEOF() can not emit end tag tokens, ergo no # </script> will be processed here. # * In some cases, tokenize() is called before tokenizeEOF(), to flush # characters stuck in the internal peekBuf. This can happen if: # 1. eatStr returns esrRetry in a previous pass. Here, peekBuf can # contain any prefix of strings passed to eatStr/NoCase(), which # crucially is never a potential </script> tag (or indeed, # nothing that can start with </). # 2. The "named character reference" state is interrupted. In this # case, peekBuf is a prefix of at least one named character # reference; obviously these can not be </script> tags either, # since they all match the regex `&[a-zA-Z]+'. # pres == PRES_STOP: unreachable for reasons almost identical to those # outlined in PRES_SCRIPT. PRES_STOP can only be returned after a <meta> # tag is processed; just like with end tags, the tokenizer cannot emit # start tags in finish(). parser.processEOF() while parser.openElements.len > 0: discard parser.popElement() �������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/chame/htmlparseriface.nim��������������������������������������������������0000664�0000000�0000000�00000032540�15202323131�0021774�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������when defined(nimdocdummy): ## Interface definitions for htmlparser. ## ## This exists to make implementing the DOMBuilder interface less painful. Two ## categories of hooks exist: ## 1. Mandatory hooks: these must be implemented by all users, or Chame will ## not compile. ## 2. Optional hooks: these may be omitted if your DOM does not need ## them. (You do not have to do anything special for this, just don't ## implement them.) ## ## Usage: ## 1. Put a type clause with your generic types in your DOM builder interface: ## ```nim ## type ## DOMBuilderImpl = MyDOMBuilder ## AtomImpl = MyAtom ## HandleImpl = MyHandle ## ``` ## 2. **Include** (**not** import) this file: ## ```nim ## include chame/htmlparseriface ## ``` ## 3. Implement all `*Impl` functions until the compiler no longer complains. ## ## Then you can call `parseHTML` with your custom DOMBuilder. ## ## You can also just implement the required functions without including ## this interface, but then you will have to do the casting from ## `DOMBuilder[HandleImpl, AtomImpl]` -> `DOMBuilderImpl` manually and will ## get uglier error messages when a function is missing. ## ## Note that when using this interface you can't use procs with different side ## effects than declared, so e.g. `func getDocumentImpl(...` **will not work**. ## You must use `proc getDocumentImpl(...` instead. ## ## Also, make sure that parameter names match the ones defined here, ## otherwise you are likely to get strange compilation errors. ## ## ## Optional hooks ## Following procedures are optional hooks; implementations of this interface ## can choose to leave them out without getting compilation errors. ## ## ## ```nim ## proc setQuirksModeImpl(builder: DOMBuilderBase, quirksMode: QuirksMode) ## ``` ## ## Set quirks mode to either `QUIRKS` or `LIMITED_QUIRKS`. `NO_QUIRKS` is the ## default and is therefore never passed here. ## ## ## ```nim ## proc setEncodingImpl(builder: DOMBuilderBase, encoding: string): ## SetEncodingResult ## ``` ## ## Called whenever a <meta charset=... or a <meta http-equiv=... tag ## containing a non-empty character set is encountered. A SetEncodingResult ## return value is expected, which is either `SET_ENCODING_STOP`, stopping ## the parser, or `SET_ENCODING_CONTINUE`, allowing the parser to continue. ## ## Note that htmlparser no longer contains any encoding-related logic, not ## even UTF-8 validation. Implementing this is left to the caller. (For an ## example, see minidom_cs which implements decoding of all character sets ## in the WHATWG recommendation.) ## ## ## ```nim ## proc elementPoppedImpl(builder: DOMBuilderBase, handle: HandleImpl) ## ``` ## ## Called when an element is popped from the stack of open elements ## (i.e. when it has been closed.) ## ## ## ```nim ## proc setScriptAlreadyStartedImpl(builder: DOMBuilderBase, handle: HandleImpl) ## ``` ## ## Set the "already started" flag for the script element. ## ## Note: this flag is not togglable, so implementations of this callback ## should just set the flag to true. ## ## ## ```nim ## proc associateWithFormImpl(builder: DOMBuilderBase, element, form, ## intendedParent: HandleImpl) ## ``` ## ## Called after createElement. Attempts to set form for form-associated ## elements. ## ## Note: the DOM builder is responsible for checking whether the intended ## parent and the form element are in the same tree. # Dummy definitions import std/tables import htmlparser type HandleImpl = int AtomImpl = int DOMBuilderImpl = DOMBuilder[HandleImpl, AtomImpl] # DOMBuilder static: # DOMBuilderImpl must be an instance of DOMBuilder with the handle type # HandleImpl and atom type AtomImpl. doAssert DOMBuilderImpl is DOMBuilder[HandleImpl, AtomImpl] converter toDOMBuilderImpl(dombuilder: DOMBuilder[HandleImpl, AtomImpl]): DOMBuilderImpl = return DOMBuilderImpl(dombuilder) when defined(nimdocdummy): import std/macros macro doc(f: untyped) = f[0] = newNimNode(nnkPostfix).add(ident("*")).add(f[0]) f else: macro doc(f: untyped) = f proc strToAtomImpl(builder: DOMBuilderImpl; s: string): AtomImpl {.doc.} ## Turn a string `s` into an Atom. ## ## This must always convert *every* string with the same value into the ## same Atom. We recommend using a hash table-based approach for this ## (see e.g. MAtomFactory). proc tagTypeToAtomImpl(builder: DOMBuilderImpl; tagType: TagType): AtomImpl {.doc.} ## Turn a TagType `tagType` into an Atom. ## ## Every TagType `tagType` must always be converted into the same atom as ## that represented by its stringifier. An implementation could be: ## ```nim ## proc tagTypeToAtomImpl(builder: DOMBuilderImpl, tt: TagType): AtomImpl = ## assert tt != TAG_UNKNOWN # parser never calls this with TAG_UNKNOWN. ## return builder.strToAtomImpl($tt) ## ``` proc atomToTagTypeImpl(builder: DOMBuilderImpl; atom: AtomImpl): TagType {.doc.} ## Turn an Atom `atom` into a TagType. This is the inverse function of ## `tagTypeToAtomImpl`. proc getDocumentImpl(builder: DOMBuilderImpl): HandleImpl {.doc.} ## Get the root document node's handle. ## This must not return nil, not even in the fragment parsing case. proc getParentNodeImpl(builder: DOMBuilderImpl; handle: HandleImpl): Option[HandleImpl] {.doc.} ## Retrieve a handle to the parent node. ## May return none(Handle) if no parent node exists. proc createHTMLElementImpl(builder: DOMBuilderImpl): HandleImpl {.doc.} ## Create a new <html> element node. The tag type of the created element must ## be TAG_HTML, and its namespace must be Namespace.HTML. ## ## This should not be confused with the "create an element for a token" ## step, which is not executed here. proc createElementForTokenImpl(builder: DOMBuilderImpl; localName: AtomImpl; namespace: Namespace; intendedParent: HandleImpl; htmlAttrs: Table[AtomImpl, string]; xmlAttrs: seq[ParsedAttr[AtomImpl]]): HandleImpl {.doc.} ## Create a new element node. ## ## `localName` is an Atom representing the tag name of the start token. ## ## Note that the parser determines the TagType of an element by its namespace ## and localName; for non-HTML elements it is always considered TAG_UNKNOWN. ## ## (However, tokens have no namespace, so TAG_SVG and TAG_MATHML can still ## used on them.) ## ## `namespace` is the namespace of the new element. For HTML elements, ## it's HTML; for embedded SVG/MathML elements, it is Namespace.SVG or ## Namespace.MATHML. No other namespace is used currently. ## ## `htmlAttrs` is a seq of the new elements attributes. It only contains ## attributes with prefix NO_PREFIX and namespace NO_NAMESPACE; adjusted ## foreign of embedded SVG/MathML elements that *do* have namespaces are ## *not* included, these can be found in `xmlAttrs`. All attribute names in ## `htmlAttrs` are guaranteed to be unique, but the parser makes no guarantees ## about the order of the attributes. (TODO maybe attrs should be a hash ## table after all?) ## ## `xmlAttrs` is a list of (XML) adjusted attributes. They are only set ## for elements in the MathML or SVG namespace, for which there are ## pre-defined attributes in the standard with names whose casing, namespace, ## and namespace prefixes must be adjusted by the parser. ## ## `intendedParent` is the intended parent of the element, as passed to the ## "create an element for a token" step. This may be used for looking up ## custom element definitions. ## ## Implementers of this function are encouraged to consult the ## [create an element for a token](https://html.spec.whatwg.org/multipage/parsing.html#create-an-element-for-the-token) ## section of the standard. In particular, steps 3 (Let document be intended ## parent's node document.) to 13 (If element is a resettable element...) ## should be implemented. ## ## Note that step 14. (If element is a form-associated element...) should ## *not* be implemented here. In fact, it is impossible to do so without ## access to the parser internals, so for this step, the parser will call ## associateWithFormImpl if all conditions (except "the intended parent is ## in the same tree as the element pointed to by the form element pointer") ## are fulfilled. proc getLocalNameImpl(builder: DOMBuilderImpl; handle: HandleImpl): AtomImpl {.doc.} ## Retrieve the local name (also known as the tag name) of the element ## represented by `handle`. proc getNamespaceImpl(builder: DOMBuilderImpl; handle: HandleImpl): Namespace {.doc.} ## Retrieve the namespace of element. For HTML elements, this should be ## `Namespace.HTML`. For embedded SVG or MathML elements, it should be ## `Namespace.SVG` or `Namespace.MathML`, respectively. ## ## (In general, you should just return the namespace that was passed to ## `createElement`.) proc getTemplateContentImpl(builder: DOMBuilderImpl; handle: HandleImpl): HandleImpl {.doc.} ## Retrieve a handle to the template element's contents. Every element ## where `builder.atomToTagTypeImpl(element.localName)` equals TAG_TEMPLATE ## and `builder.getNamespaceImpl(element)` equals `Namespace.HTML` must have ## an associated "template contents" node which this function must return. proc addAttrsIfMissingImpl(builder: DOMBuilderImpl; handle: HandleImpl, attrs: Table[AtomImpl, string]) {.doc.} ## Add the attributes in `attrs` to the element node `element`. ## This is only called with the HTML and BODY tags, when more than one ## exists in a document. ## ## Pseudocode implementation: ## ```nim ## for attr in attrs: ## if attr.name notin element.attrs: ## element.attrs.add(attr) ## ``` proc insertCommentImpl(builder: DOMBuilderImpl; parent: HandleImpl; text: string; before: Option[HandleImpl]) {.doc.} ## Create a new comment node, and insert it into `parent` before the node ## `before`. ## `text` is a string representing the new comment node's character data. proc appendDocumentTypeImpl(builder: DOMBuilderImpl; name, publicId, systemId: string) {.doc.} ## Append a new document type node to the Document node. proc insertBeforeImpl(builder: DOMBuilderImpl; parent, child: HandleImpl; before: Option[HandleImpl]) {.doc.} ## Insert node `child` before the node called `before`. ## ## If `before` is `none(Handle)`, `child` is expected to be appended to ## `parent`'s node list. ## ## If `child` is a text, and its previous sibling after insertion is a ## text as well, then they should be merged. `before` is never a ## text node (and thus never has to be merged). ## ## Note: parent may be either an Element or a Document node. proc insertTextImpl(builder: DOMBuilderImpl; parent: HandleImpl; text: string; before: Option[HandleImpl]) {.doc.} ## Insert a text node at the specified location with contents `text`. If ## the specified location has a previous sibling that is a text node, no new ## text node should be created, but instead `text` should be appended to the ## previous sibling's character data (or if `before` is `none(Handle)`, ## to the last element). proc removeImpl(builder: DOMBuilderImpl; child: HandleImpl) {.doc.} ## If `child` does not have a parent node, do nothing. Otherwise, remove ## `child` from its parent node. proc moveChildrenImpl(builder: DOMBuilderImpl; fromNode, toNode: HandleImpl) {.doc.} ## Remove all children from the node `fromHandle`, then append them to ## `toHandle`. when defined(nimdocdummy): # Dummy definitions proc strToAtomImpl(builder: DOMBuilderImpl; s: string): AtomImpl = discard proc tagTypeToAtomImpl(builder: DOMBuilderImpl; tagType: TagType): AtomImpl = discard proc atomToTagTypeImpl(builder: DOMBuilderImpl; atom: AtomImpl): TagType = discard proc getDocumentImpl(builder: DOMBuilderImpl): HandleImpl = discard proc getParentNodeImpl(builder: DOMBuilderImpl; handle: HandleImpl): Option[HandleImpl] = discard proc createHTMLElementImpl(builder: DOMBuilderImpl): HandleImpl = discard proc createElementForTokenImpl(builder: DOMBuilderImpl; localName: AtomImpl; namespace: Namespace; intendedParent: HandleImpl; htmlAttrs: Table[AtomImpl, string]; xmlAttrs: seq[ParsedAttr[AtomImpl]]): HandleImpl = discard proc getLocalNameImpl(builder: DOMBuilderImpl; handle: HandleImpl): AtomImpl = discard proc getNamespaceImpl(builder: DOMBuilderImpl; handle: HandleImpl): Namespace = discard proc getTemplateContentImpl(builder: DOMBuilderImpl; handle: HandleImpl): HandleImpl = discard proc addAttrsIfMissingImpl(builder: DOMBuilderImpl; handle: HandleImpl, attrs: Table[AtomImpl, string]) = discard proc createCommentImpl(builder: DOMBuilderImpl; text: string): HandleImpl = discard proc createDocumentTypeImpl(builder: DOMBuilderImpl; name, publicId, systemId: string): HandleImpl = discard proc insertBeforeImpl(builder: DOMBuilderImpl; parent, child: HandleImpl; before: Option[HandleImpl]) = discard proc insertTextImpl(builder: DOMBuilderImpl; parent: HandleImpl; text: string; before: Option[HandleImpl]) = discard proc removeImpl(builder: DOMBuilderImpl; child: HandleImpl) = discard proc moveChildrenImpl(builder: DOMBuilderImpl; fromNode, toNode: HandleImpl) = discard ����������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/chame/htmltokenizer.nim����������������������������������������������������0000664�0000000�0000000�00000117676�15202323131�0021540�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.experimental: "overloadableEnums".} import std/tables import dombuilder import entity_gen import tokstate export tokstate type Tokenizer*[Handle, Atom] = object dombuilder: DOMBuilder[Handle, Atom] # temporary buffer (mentioned by the standard, but also used for attribute # names) tmp: string tok: Token[Atom] # current token to be emitted laststart*: Token[Atom] # last start tag token attrv: string # buffer for attribute values attrna: Atom # atom representing attrn after the attribute name is closed code: uint32 # codepoint of current numeric character reference state*: TokenizerState rstate: TokenizerState # return state attr: bool # is there already an attr in the previous values? hasnonhtml*: bool # does the stack of open elements have a non-HTML node? ignoreLF: bool # ignore the next consumed line feed (for CRLF normalization) isend: bool # if consume returns -1 and isend, we are at EOF isws: bool # is the current character token whitespace-only? quote: char # dedupe states that only differ in their quoting tokqueue*: seq[Token[Atom]] # queue of tokens to be emitted in this iteration charbuf: string # buffer for character tokens tagNameBuf: string # buffer for storing the tag name peekBuf: array[64, char] # a stack with the last element at peekBufLen - 1 peekBufLen: int inputBufIdx*: int # last character consumed in input buf TokenType* = enum ttDoctype, ttStartTag, ttEndTag, ttComment, ttCharacter, ttWhitespace, ttNull TokenFlag* = enum tfQuirks, tfPubid, tfSysid, tfSelfClosing Token*[Atom] = ref object flags*: set[TokenFlag] case t*: TokenType of ttDoctype: name*: string pubid*: string sysid*: string of ttStartTag, ttEndTag: tagname*: Atom attrs*: Table[Atom, string] of ttCharacter, ttWhitespace, ttComment: s*: string of ttNull: discard const AsciiUpperAlpha = {'A'..'Z'} const AsciiLowerAlpha = {'a'..'z'} const AsciiAlpha = (AsciiUpperAlpha + AsciiLowerAlpha) const AsciiDigit = {'0'..'9'} const AsciiAlphaNumeric = AsciiAlpha + AsciiDigit const AsciiWhitespace = {' ', '\n', '\r', '\t', '\f'} proc toLowerAscii(c: char): char {.inline.} = if c in AsciiUpperAlpha: result = char(uint8(c) xor 0x20'u8) else: result = c func `$`*(tok: Token): string = result = $tok.t case tok.t of ttDoctype: result &= ' ' & tok.name & ' ' & tok.pubid & ' ' & tok.sysid if tfQuirks in tok.flags: result &= " (quirks)" of ttStartTag, ttEndTag: result &= ' ' & tok.tagname & ' ' & $tok.attrs if tfSelfClosing in tok.flags: result &= " (self-closing)" of ttCharacter, ttWhitespace, ttComment: result &= ' ' & tok.s else: discard proc strToAtom[Handle, Atom](tokenizer: Tokenizer[Handle, Atom]; s: string): Atom = mixin strToAtomImpl return tokenizer.dombuilder.strToAtomImpl(s) proc newTokenizer*[Handle, Atom](dombuilder: DOMBuilder[Handle, Atom]; initialState = DATA): Tokenizer[Handle, Atom] = return Tokenizer[Handle, Atom](state: initialState, dombuilder: dombuilder) proc reconsume(tokenizer: var Tokenizer; s: openArray[char]) = for i in countdown(s.high, 0): tokenizer.peekBuf[tokenizer.peekBufLen] = s[i] inc tokenizer.peekBufLen proc reconsume(tokenizer: var Tokenizer; c: char) = tokenizer.peekBuf[tokenizer.peekBufLen] = c inc tokenizer.peekBufLen proc consume(tokenizer: var Tokenizer; ibuf: openArray[char]): int = if tokenizer.peekBufLen > 0: dec tokenizer.peekBufLen return int(tokenizer.peekBuf[tokenizer.peekBufLen]) if tokenizer.inputBufIdx >= ibuf.len: return -1 var c = ibuf[tokenizer.inputBufIdx] inc tokenizer.inputBufIdx if tokenizer.ignoreLF: if c == '\n': if tokenizer.inputBufIdx >= ibuf.len: return -1 c = ibuf[tokenizer.inputBufIdx] inc tokenizer.inputBufIdx tokenizer.ignoreLF = false if c == '\r': tokenizer.ignoreLF = true c = '\n' return int(c) proc flushChars[Handle, Atom](tokenizer: var Tokenizer[Handle, Atom]) = if tokenizer.charbuf.len > 0: if tokenizer.isws: tokenizer.tokqueue.add(Token[Atom]( t: ttWhitespace, s: move(tokenizer.charbuf) )) else: tokenizer.tokqueue.add(Token[Atom]( t: ttCharacter, s: move(tokenizer.charbuf) )) tokenizer.isws = false tokenizer.charbuf.setLen(0) const AttributeStates = { ATTRIBUTE_VALUE_QUOTED, ATTRIBUTE_VALUE_UNQUOTED } func consumedAsAttribute(tokenizer: Tokenizer): bool = return tokenizer.rstate in AttributeStates proc appendToAttrValue(tokenizer: var Tokenizer; s: openArray[char]) = if tokenizer.attr: for c in s: tokenizer.attrv &= c proc emit(tokenizer: var Tokenizer; c: char) = let isws = c in AsciiWhitespace if tokenizer.isws != isws: # Emit whitespace & non-whitespace separately. tokenizer.flushChars() tokenizer.isws = isws tokenizer.charbuf &= c type CharRefResult = tuple[i, ci: int, entry: cstring] proc findCharRef(tokenizer: var Tokenizer; c: char; ibuf: openArray[char]): CharRefResult = var i = charMap[c] if i == -1: return (0, 0, nil) tokenizer.tmp &= c var entry = entityMap[i] var ci = 1 let oc = c while entry != nil and entry[ci] != ':': let n = tokenizer.consume(ibuf) if n == -1 and not tokenizer.isend: # We must retry at the next iteration :/ #TODO it would be nice to save state in this case return (-1, 0, nil) if n != int(entry[ci]): entry = nil # i is not the right entry. while entry == nil: if i == 0: # See below; we avoid flushing the last character consumed by # decrementing `ci'. dec ci break dec i entry = entityMap[i] if oc != entry[0]: # Out of entries that start with the character `oc'; give up. # We must not flush the last character consumed as a character # reference, since it is not a prefix of any entry (and can indeed be # markup; e.g. in the case of `&g<'), so decrement `ci' here. dec ci entry = nil break var j = 1 while j < tokenizer.tmp.len - 1: if entry[j] == ':': # Full match: entry is a prefix of the previous entry we inspected. break if tokenizer.tmp[j + 1] != entry[j]: # Characters consumed until now are not a prefix of entry. # Try the next one instead. entry = nil break inc j if entry != nil: if entry[j] == ':': # Full match: make sure the outer loop exits. ci = j - 1 elif int(entry[j]) == n: # Partial match, *including c*. (This is never reached with n == -1) ci = j else: # Continue with the loop. # If entry is set to non-nil after this iteration, then ci will # also be set appropriately. # Otherwise, if entry remains nil, ci will point to the first # non-matching character in tmp; this will be reconsumed. entry = nil if n != -1: tokenizer.tmp &= cast[char](n) inc ci return (i, ci, entry) proc appendAttrOrEmit(tokenizer: var Tokenizer; s: openArray[char]) = if tokenizer.consumedAsAttribute(): tokenizer.appendToAttrValue(s) else: for c in s: tokenizer.emit(c) proc numericCharacterReferenceEndState(tokenizer: var Tokenizer) = const ControlMap = [ 0x20ACu16, 0, 0x201A, 0x192, 0x201E, 0x2026, 0x2020, 0x2021, 0x2C6, 0x2030, 0x160, 0x2039, 0x152, 0, 0x17D, 0, 0, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x2DC, 0x2122, 0x161, 0x203A, 0x153, 0, 0x17E, 0x178 ] var u = tokenizer.code let cc = u - 0x80 if cc < ControlMap.len and ControlMap[cc] != 0: u = ControlMap[cc] elif u == 0x00 or u > 0x10FFFF or u in 0xD800u32..0xDFFFu32: u = 0xFFFD var s = "" if u < 0x80: s = $char(u) elif u < 0x800: s = char(u shr 6 or 0xC0) & char(u and 0x3F or 0x80) elif u < 0x10000: s = char(u shr 12 or 0xE0) & char(u shr 6 and 0x3F or 0x80) & char(u and 0x3F or 0x80) else: s = char(u shr 18 or 0xF0) & char(u shr 12 and 0x3F or 0x80) & char(u shr 6 and 0x3F or 0x80) & char(u and 0x3F or 0x80) tokenizer.appendAttrOrEmit(s) proc flushAttr(tokenizer: var Tokenizer) = # This can also be called with tok.t == ttEndTag, in that case we do # not want to flush attributes. if tokenizer.tok.t == ttStartTag and tokenizer.attr: tokenizer.tok.attrs[tokenizer.attrna] = move(tokenizer.attrv) proc startNewAttribute(tokenizer: var Tokenizer) = tokenizer.flushAttr() tokenizer.tmp = "" tokenizer.attrv = "" tokenizer.attr = true type EatStrResult = enum esrFail, esrSuccess, esrRetry proc eatStr(tokenizer: var Tokenizer, c: char, s, ibuf: openArray[char]): EatStrResult = var cs = $c for c in s: let n = tokenizer.consume(ibuf) if n != -1: cs &= cast[char](n) if n != int(c): tokenizer.reconsume(cs) if n == -1 and not tokenizer.isend: return esrRetry return esrFail return esrSuccess proc eatStrNoCase(tokenizer: var Tokenizer; c: char; s, ibuf: openArray[char]): EatStrResult = var cs = $c for c in s: let n = tokenizer.consume(ibuf) if n != -1: cs &= cast[char](n) if n == -1 or cast[char](n).toLowerAscii() != c: tokenizer.reconsume(cs) if n == -1 and not tokenizer.isend: return esrRetry return esrFail return esrSuccess proc flushTagName(tokenizer: var Tokenizer) = tokenizer.tok.tagname = tokenizer.strToAtom(tokenizer.tagNameBuf) proc emitTmp(tokenizer: var Tokenizer) = if tokenizer.isws: tokenizer.flushChars() tokenizer.charbuf &= "</" tokenizer.charbuf &= tokenizer.tmp # if true, redo proc tokenizeEOF[Handle, Atom](tokenizer: var Tokenizer[Handle, Atom]): bool = tokenizer.tokqueue.setLen(0) if tokenizer.isws: tokenizer.flushChars() case tokenizer.state of TAG_OPEN, RCDATA_LESS_THAN_SIGN, RAWTEXT_LESS_THAN_SIGN, SCRIPT_DATA_LESS_THAN_SIGN, SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: tokenizer.charbuf &= '<' of END_TAG_OPEN, RCDATA_END_TAG_OPEN, RAWTEXT_END_TAG_OPEN, SCRIPT_DATA_END_TAG_OPEN, SCRIPT_DATA_ESCAPED_END_TAG_OPEN: tokenizer.charbuf &= "</" of RCDATA_END_TAG_NAME, RAWTEXT_END_TAG_NAME, SCRIPT_DATA_END_TAG_NAME, SCRIPT_DATA_ESCAPED_END_TAG_NAME: tokenizer.emitTmp() of BOGUS_COMMENT, BOGUS_DOCTYPE, COMMENT_END_DASH, COMMENT_END, COMMENT_END_BANG, COMMENT_LESS_THAN_SIGN_BANG_DASH, COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH, COMMENT_START_DASH, COMMENT, COMMENT_START, COMMENT_LESS_THAN_SIGN, COMMENT_LESS_THAN_SIGN_BANG: tokenizer.flushChars() tokenizer.tokqueue.add(tokenizer.tok) of MARKUP_DECLARATION_OPEN: tokenizer.flushChars() tokenizer.tokqueue.add(Token[Atom](t: ttComment)) of DOCTYPE, BEFORE_DOCTYPE_NAME: tokenizer.flushChars() tokenizer.tokqueue.add(Token[Atom](t: ttDoctype, flags: {tfQuirks})) of DOCTYPE_NAME, AFTER_DOCTYPE_NAME, AFTER_DOCTYPE_PUBLIC_KEYWORD, BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, DOCTYPE_PUBLIC_IDENTIFIER_QUOTED, AFTER_DOCTYPE_PUBLIC_IDENTIFIER, BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS, AFTER_DOCTYPE_SYSTEM_KEYWORD, BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, DOCTYPE_SYSTEM_IDENTIFIER_QUOTED, AFTER_DOCTYPE_SYSTEM_IDENTIFIER: tokenizer.tok.flags.incl(tfQuirks) tokenizer.flushChars() tokenizer.tokqueue.add(tokenizer.tok) of CDATA_SECTION_BRACKET: tokenizer.charbuf &= ']' of CDATA_SECTION_END: tokenizer.charbuf &= "]]" of CHARACTER_REFERENCE: tokenizer.appendAttrOrEmit("&") tokenizer.state = tokenizer.rstate return true of AMBIGUOUS_AMPERSAND_STATE: tokenizer.state = tokenizer.rstate return true of NAMED_CHARACTER_REFERENCE, HEXADECIMAL_CHARACTER_REFERENCE_START, NUMERIC_CHARACTER_REFERENCE: tokenizer.appendAttrOrEmit(tokenizer.tmp) tokenizer.state = tokenizer.rstate return true of HEXADECIMAL_CHARACTER_REFERENCE, DECIMAL_CHARACTER_REFERENCE: tokenizer.numericCharacterReferenceEndState() # we unnecessarily consumed once so reconsume tokenizer.state = tokenizer.rstate return true else: discard tokenizer.flushChars() false type TokenizeResult* = enum trDone, trEmit proc tokenize*[Handle, Atom](tokenizer: var Tokenizer[Handle, Atom]; ibuf: openArray[char]): TokenizeResult = template emit(s: static string) = if tokenizer.isws: tokenizer.flushChars() tokenizer.charbuf &= s template emit(ch: char) = tokenizer.emit(ch) template emit_null = tokenizer.flushChars() tokenizer.tokqueue.add(Token[Atom](t: ttNull)) template emit_tok = tokenizer.flushChars() tokenizer.tokqueue.add(tokenizer.tok) template emit_replacement = emit "\uFFFD" template switch_state(s: TokenizerState) = tokenizer.state = s template switch_state_return(s: TokenizerState) = tokenizer.rstate = tokenizer.state tokenizer.state = s template is_appropriate_end_tag_token(): bool = tokenizer.laststart != nil and tokenizer.laststart.tagname == tokenizer.tok.tagname template new_token(t: Token) = tokenizer.attr = false tokenizer.tok = t tokenizer.tokqueue.setLen(0) while true: if tokenizer.tokqueue.len > 0: return trEmit let n = tokenizer.consume(ibuf) if n == -1: break # trDone let c = cast[char](n) template reconsume_in(s: TokenizerState) = tokenizer.reconsume(c) switch_state s case tokenizer.state of DATA: case c of '&': switch_state_return CHARACTER_REFERENCE of '<': switch_state TAG_OPEN of '\0': emit_null else: emit c of RCDATA: case c of '&': switch_state_return CHARACTER_REFERENCE of '<': switch_state RCDATA_LESS_THAN_SIGN of '\0': emit_replacement else: emit c of RAWTEXT: case c of '<': switch_state RAWTEXT_LESS_THAN_SIGN of '\0': emit_replacement else: emit c of SCRIPT_DATA: case c of '<': switch_state SCRIPT_DATA_LESS_THAN_SIGN of '\0': emit_replacement else: emit c of PLAINTEXT: case c of '\0': emit_replacement else: emit c of TAG_OPEN: case c of '!': switch_state MARKUP_DECLARATION_OPEN of '/': switch_state END_TAG_OPEN of AsciiAlpha: new_token Token[Atom](t: ttStartTag) tokenizer.laststart = tokenizer.tok tokenizer.tagNameBuf = $c.toLowerAscii() # note: was reconsume switch_state TAG_NAME of '?': new_token Token[Atom](t: ttComment, s: "?") # note: was reconsume switch_state BOGUS_COMMENT else: emit '<' reconsume_in DATA of END_TAG_OPEN: case c of AsciiAlpha: new_token Token[Atom](t: ttEndTag) tokenizer.tagNameBuf = $c.toLowerAscii() # note: was reconsume switch_state TAG_NAME of '>': switch_state DATA else: new_token Token[Atom](t: ttComment) reconsume_in BOGUS_COMMENT of TAG_NAME: case c of AsciiWhitespace: tokenizer.flushTagName() switch_state BEFORE_ATTRIBUTE_NAME of '/': tokenizer.flushTagName() switch_state SELF_CLOSING_START_TAG of '>': switch_state DATA tokenizer.flushTagName() emit_tok of '\0': tokenizer.tagNameBuf &= "\uFFFD" else: tokenizer.tagNameBuf &= c.toLowerAscii() of RCDATA_LESS_THAN_SIGN: case c of '/': tokenizer.tmp = "" switch_state RCDATA_END_TAG_OPEN else: emit '<' reconsume_in RCDATA of RCDATA_END_TAG_OPEN: case c of AsciiAlpha: new_token Token[Atom](t: ttEndTag) tokenizer.tagNameBuf = $c.toLowerAscii() tokenizer.tmp &= c # note: was reconsume switch_state RCDATA_END_TAG_NAME else: emit "</" reconsume_in RCDATA of RCDATA_END_TAG_NAME: template anything_else = tokenizer.emitTmp() reconsume_in RCDATA case c of AsciiWhitespace: tokenizer.flushTagName() if is_appropriate_end_tag_token: switch_state BEFORE_ATTRIBUTE_NAME else: anything_else of '/': tokenizer.flushTagName() if is_appropriate_end_tag_token: switch_state SELF_CLOSING_START_TAG else: anything_else of '>': tokenizer.flushTagName() if is_appropriate_end_tag_token: switch_state DATA emit_tok else: anything_else of AsciiAlpha: # note: merged upper & lower tokenizer.tagNameBuf &= c.toLowerAscii() tokenizer.tmp &= c else: anything_else of RAWTEXT_LESS_THAN_SIGN: case c of '/': tokenizer.tmp = "" switch_state RAWTEXT_END_TAG_OPEN else: emit '<' reconsume_in RAWTEXT of RAWTEXT_END_TAG_OPEN: case c of AsciiAlpha: new_token Token[Atom](t: ttEndTag) tokenizer.tagNameBuf = $c.toLowerAscii() tokenizer.tmp &= c # note: was reconsume switch_state RAWTEXT_END_TAG_NAME else: emit "</" reconsume_in RAWTEXT of RAWTEXT_END_TAG_NAME: template anything_else = tokenizer.emitTmp() reconsume_in RAWTEXT case c of AsciiWhitespace: tokenizer.flushTagName() if is_appropriate_end_tag_token: switch_state BEFORE_ATTRIBUTE_NAME else: anything_else of '/': tokenizer.flushTagName() if is_appropriate_end_tag_token: switch_state SELF_CLOSING_START_TAG else: anything_else of '>': tokenizer.flushTagName() if is_appropriate_end_tag_token: switch_state DATA emit_tok else: anything_else of AsciiAlpha: # note: merged upper & lower tokenizer.tagNameBuf &= c.toLowerAscii() tokenizer.tmp &= c else: anything_else of SCRIPT_DATA_LESS_THAN_SIGN: case c of '/': tokenizer.tmp = "" switch_state SCRIPT_DATA_END_TAG_OPEN of '!': switch_state SCRIPT_DATA_ESCAPE_START emit "<!" else: emit '<' reconsume_in SCRIPT_DATA of SCRIPT_DATA_END_TAG_OPEN: case c of AsciiAlpha: new_token Token[Atom](t: ttEndTag) tokenizer.tagNameBuf = $c.toLowerAscii() tokenizer.tmp &= c # note: was reconsume switch_state SCRIPT_DATA_END_TAG_NAME else: emit "</" reconsume_in SCRIPT_DATA of SCRIPT_DATA_END_TAG_NAME: template anything_else = tokenizer.emitTmp() reconsume_in SCRIPT_DATA case c of AsciiWhitespace: tokenizer.flushTagName() if is_appropriate_end_tag_token: switch_state BEFORE_ATTRIBUTE_NAME else: anything_else of '/': tokenizer.flushTagName() if is_appropriate_end_tag_token: switch_state SELF_CLOSING_START_TAG else: anything_else of '>': tokenizer.flushTagName() if is_appropriate_end_tag_token: switch_state DATA emit_tok else: anything_else of AsciiAlpha: # note: merged upper & lower tokenizer.tagNameBuf &= c.toLowerAscii() tokenizer.tmp &= c else: anything_else of SCRIPT_DATA_ESCAPE_START: case c of '-': switch_state SCRIPT_DATA_ESCAPE_START_DASH emit '-' else: reconsume_in SCRIPT_DATA of SCRIPT_DATA_ESCAPE_START_DASH: case c of '-': switch_state SCRIPT_DATA_ESCAPED_DASH_DASH emit '-' else: reconsume_in SCRIPT_DATA of SCRIPT_DATA_ESCAPED: case c of '-': switch_state SCRIPT_DATA_ESCAPED_DASH emit '-' of '<': switch_state SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN of '\0': emit_replacement else: emit c of SCRIPT_DATA_ESCAPED_DASH: case c of '-': switch_state SCRIPT_DATA_ESCAPED_DASH_DASH emit '-' of '<': switch_state SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN of '\0': switch_state SCRIPT_DATA_ESCAPED emit_replacement else: switch_state SCRIPT_DATA_ESCAPED emit c of SCRIPT_DATA_ESCAPED_DASH_DASH: case c of '-': emit '-' of '<': switch_state SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN of '>': switch_state SCRIPT_DATA emit '>' of '\0': switch_state SCRIPT_DATA_ESCAPED emit_replacement else: switch_state SCRIPT_DATA_ESCAPED emit c of SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: case c of '/': tokenizer.tmp = "" switch_state SCRIPT_DATA_ESCAPED_END_TAG_OPEN of AsciiAlpha: tokenizer.tmp = $c.toLowerAscii() emit '<' emit c # note: was reconsume switch_state SCRIPT_DATA_DOUBLE_ESCAPE_START else: emit '<' reconsume_in SCRIPT_DATA_ESCAPED of SCRIPT_DATA_ESCAPED_END_TAG_OPEN: if c in AsciiAlpha: new_token Token[Atom](t: ttEndTag) tokenizer.tagNameBuf = $c.toLowerAscii() tokenizer.tmp &= c # note: was reconsume switch_state SCRIPT_DATA_ESCAPED_END_TAG_NAME else: emit "</" reconsume_in SCRIPT_DATA_ESCAPED of SCRIPT_DATA_ESCAPED_END_TAG_NAME: template anything_else = tokenizer.emitTmp() reconsume_in SCRIPT_DATA_ESCAPED case c of AsciiWhitespace: tokenizer.flushTagName() if is_appropriate_end_tag_token: switch_state BEFORE_ATTRIBUTE_NAME else: anything_else of '/': tokenizer.flushTagName() if is_appropriate_end_tag_token: switch_state SELF_CLOSING_START_TAG else: anything_else of '>': tokenizer.flushTagName() if is_appropriate_end_tag_token: switch_state DATA emit_tok else: anything_else of AsciiAlpha: tokenizer.tagNameBuf &= c.toLowerAscii() tokenizer.tmp &= c else: anything_else of SCRIPT_DATA_DOUBLE_ESCAPE_START: case c of AsciiWhitespace, '/', '>': if tokenizer.tmp == "script": switch_state SCRIPT_DATA_DOUBLE_ESCAPED else: switch_state SCRIPT_DATA_ESCAPED emit c of AsciiAlpha: # note: merged upper & lower tokenizer.tmp &= c.toLowerAscii() emit c else: reconsume_in SCRIPT_DATA_ESCAPED of SCRIPT_DATA_DOUBLE_ESCAPED: case c of '-': switch_state SCRIPT_DATA_DOUBLE_ESCAPED_DASH emit '-' of '<': switch_state SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN emit '<' of '\0': emit_replacement else: emit c of SCRIPT_DATA_DOUBLE_ESCAPED_DASH: case c of '-': switch_state SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH emit '-' of '<': switch_state SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN emit '<' of '\0': switch_state SCRIPT_DATA_DOUBLE_ESCAPED emit_replacement else: switch_state SCRIPT_DATA_DOUBLE_ESCAPED emit c of SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH: case c of '-': emit '-' of '<': switch_state SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN emit '<' of '>': switch_state SCRIPT_DATA emit '>' of '\0': switch_state SCRIPT_DATA_DOUBLE_ESCAPED emit_replacement else: switch_state SCRIPT_DATA_DOUBLE_ESCAPED emit c of SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN: case c of '/': tokenizer.tmp = "" switch_state SCRIPT_DATA_DOUBLE_ESCAPE_END emit '/' else: reconsume_in SCRIPT_DATA_DOUBLE_ESCAPED of SCRIPT_DATA_DOUBLE_ESCAPE_END: case c of AsciiWhitespace, '/', '>': if tokenizer.tmp == "script": switch_state SCRIPT_DATA_ESCAPED else: switch_state SCRIPT_DATA_DOUBLE_ESCAPED emit c of AsciiAlpha: # note: merged upper & lower tokenizer.tmp &= c.toLowerAscii() emit c else: reconsume_in SCRIPT_DATA_DOUBLE_ESCAPED of BEFORE_ATTRIBUTE_NAME: case c of AsciiWhitespace: discard of '/': switch_state SELF_CLOSING_START_TAG of '>': reconsume_in AFTER_ATTRIBUTE_NAME else: tokenizer.startNewAttribute() if c == '\0': tokenizer.tmp &= "\uFFFD" else: tokenizer.tmp &= c.toLowerAscii() switch_state ATTRIBUTE_NAME of ATTRIBUTE_NAME: template leave_attribute_name_state = tokenizer.attrna = tokenizer.strToAtom(tokenizer.tmp) if tokenizer.attrna in tokenizer.tok.attrs: tokenizer.attr = false case c of AsciiWhitespace, '/', '>': leave_attribute_name_state reconsume_in AFTER_ATTRIBUTE_NAME of '=': leave_attribute_name_state switch_state BEFORE_ATTRIBUTE_VALUE of '\0': tokenizer.tmp &= "\uFFFD" else: tokenizer.tmp &= c.toLowerAscii() of AFTER_ATTRIBUTE_NAME: case c of AsciiWhitespace: discard of '/': switch_state SELF_CLOSING_START_TAG of '=': switch_state BEFORE_ATTRIBUTE_VALUE of '>': switch_state DATA tokenizer.flushAttr() emit_tok else: tokenizer.startNewAttribute() if c == '\0': tokenizer.tmp &= "\uFFFD" else: tokenizer.tmp &= c.toLowerAscii() switch_state ATTRIBUTE_NAME of BEFORE_ATTRIBUTE_VALUE: case c of AsciiWhitespace: discard of '"', '\'': tokenizer.quote = c switch_state ATTRIBUTE_VALUE_QUOTED of '>': switch_state DATA tokenizer.flushAttr() emit_tok else: reconsume_in ATTRIBUTE_VALUE_UNQUOTED of ATTRIBUTE_VALUE_QUOTED: case c of '&': switch_state_return CHARACTER_REFERENCE of '\0': tokenizer.appendToAttrValue("\uFFFD") elif c == tokenizer.quote: switch_state AFTER_ATTRIBUTE_VALUE_QUOTED else: tokenizer.appendToAttrValue([c]) of ATTRIBUTE_VALUE_UNQUOTED: case c of AsciiWhitespace: switch_state BEFORE_ATTRIBUTE_NAME of '&': switch_state_return CHARACTER_REFERENCE of '>': switch_state DATA tokenizer.flushAttr() emit_tok of '\0': tokenizer.appendToAttrValue("\uFFFD") else: tokenizer.appendToAttrValue([c]) of AFTER_ATTRIBUTE_VALUE_QUOTED: case c of AsciiWhitespace: switch_state BEFORE_ATTRIBUTE_NAME of '/': switch_state SELF_CLOSING_START_TAG of '>': switch_state DATA tokenizer.flushAttr() emit_tok else: reconsume_in BEFORE_ATTRIBUTE_NAME of SELF_CLOSING_START_TAG: case c of '>': tokenizer.tok.flags.incl(tfSelfClosing) switch_state DATA tokenizer.flushAttr() emit_tok else: reconsume_in BEFORE_ATTRIBUTE_NAME of BOGUS_COMMENT: assert tokenizer.tok.t == ttComment case c of '>': switch_state DATA emit_tok of '\0': tokenizer.tok.s &= "\uFFFD" else: tokenizer.tok.s &= c of MARKUP_DECLARATION_OPEN: # note: rewritten to fit case model as we consume a char anyway template anything_else = new_token Token[Atom](t: ttComment) switch_state BOGUS_COMMENT case c of '-': case tokenizer.eatStr(c, "-", ibuf) of esrSuccess: new_token Token[Atom](t: ttComment) tokenizer.state = COMMENT_START of esrRetry: break of esrFail: anything_else of 'D', 'd': case tokenizer.eatStrNoCase(c, "octype", ibuf) of esrSuccess: switch_state DOCTYPE of esrRetry: break of esrFail: anything_else of '[': case tokenizer.eatStr(c, "CDATA[", ibuf) of esrSuccess: if tokenizer.hasnonhtml: switch_state CDATA_SECTION else: new_token Token[Atom](t: ttComment, s: "[CDATA[") switch_state BOGUS_COMMENT of esrRetry: break of esrFail: anything_else else: # eat didn't reconsume, do it ourselves tokenizer.reconsume(c) anything_else of COMMENT_START: case c of '-': switch_state COMMENT_START_DASH of '>': switch_state DATA emit_tok else: reconsume_in COMMENT of COMMENT_START_DASH: case c of '-': switch_state COMMENT_END of '>': switch_state DATA emit_tok else: tokenizer.tok.s &= '-' reconsume_in COMMENT of COMMENT: case c of '<': tokenizer.tok.s &= c switch_state COMMENT_LESS_THAN_SIGN of '-': switch_state COMMENT_END_DASH of '\0': tokenizer.tok.s &= "\uFFFD" else: tokenizer.tok.s &= c of COMMENT_LESS_THAN_SIGN: case c of '!': tokenizer.tok.s &= c switch_state COMMENT_LESS_THAN_SIGN_BANG of '<': tokenizer.tok.s &= c else: reconsume_in COMMENT of COMMENT_LESS_THAN_SIGN_BANG: case c of '-': switch_state COMMENT_LESS_THAN_SIGN_BANG_DASH else: reconsume_in COMMENT of COMMENT_LESS_THAN_SIGN_BANG_DASH: case c of '-': switch_state COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH else: reconsume_in COMMENT_END_DASH of COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH: case c of '>': # note: was reconsume (comment end) switch_state DATA emit_tok else: reconsume_in COMMENT_END of COMMENT_END_DASH: case c of '-': switch_state COMMENT_END else: tokenizer.tok.s &= '-' reconsume_in COMMENT of COMMENT_END: case c of '>': switch_state DATA emit_tok of '!': switch_state COMMENT_END_BANG of '-': tokenizer.tok.s &= '-' else: tokenizer.tok.s &= "--" reconsume_in COMMENT of COMMENT_END_BANG: if c == '>': switch_state DATA emit_tok else: tokenizer.tok.s &= "--!" if c == '-': switch_state COMMENT_END_DASH else: reconsume_in COMMENT of DOCTYPE: if c notin AsciiWhitespace: tokenizer.reconsume(c) switch_state BEFORE_DOCTYPE_NAME of BEFORE_DOCTYPE_NAME: case c of AsciiWhitespace: discard of '\0': new_token Token[Atom](t: ttDoctype, name: "\uFFFD") switch_state DOCTYPE_NAME of '>': new_token Token[Atom](t: ttDoctype, flags: {tfQuirks}) switch_state DATA emit_tok else: new_token Token[Atom](t: ttDoctype, name: $c.toLowerAscii()) switch_state DOCTYPE_NAME of DOCTYPE_NAME: case c of AsciiWhitespace: switch_state AFTER_DOCTYPE_NAME of '>': switch_state DATA emit_tok of '\0': tokenizer.tok.name &= "\uFFFD" else: tokenizer.tok.name &= c.toLowerAscii() of AFTER_DOCTYPE_NAME: # note: rewritten to fit case model as we consume a char anyway template anything_else = tokenizer.tok.flags.incl(tfQuirks) switch_state BOGUS_DOCTYPE case c of AsciiWhitespace: discard of '>': switch_state DATA emit_tok of 'p', 'P': case tokenizer.eatStrNoCase(c, "ublic", ibuf) of esrSuccess: switch_state AFTER_DOCTYPE_PUBLIC_KEYWORD of esrRetry: break of esrFail: anything_else of 's', 'S': case tokenizer.eatStrNoCase(c, "ystem", ibuf) of esrSuccess: switch_state AFTER_DOCTYPE_SYSTEM_KEYWORD of esrRetry: break of esrFail: anything_else else: # eat didn't reconsume, do it ourselves tokenizer.reconsume(c) anything_else of AFTER_DOCTYPE_PUBLIC_KEYWORD: case c of AsciiWhitespace: switch_state BEFORE_DOCTYPE_PUBLIC_IDENTIFIER of '"', '\'': tokenizer.tok.flags.incl(tfPubid) tokenizer.quote = c switch_state DOCTYPE_PUBLIC_IDENTIFIER_QUOTED of '>': tokenizer.tok.flags.incl(tfQuirks) switch_state DATA emit_tok else: tokenizer.tok.flags.incl(tfQuirks) reconsume_in BOGUS_DOCTYPE of BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: case c of AsciiWhitespace: discard of '"', '\'': tokenizer.tok.flags.incl(tfPubid) tokenizer.quote = c switch_state DOCTYPE_PUBLIC_IDENTIFIER_QUOTED of '>': tokenizer.tok.flags.incl(tfQuirks) switch_state DATA emit_tok else: tokenizer.tok.flags.incl(tfQuirks) reconsume_in BOGUS_DOCTYPE of DOCTYPE_PUBLIC_IDENTIFIER_QUOTED: case c of '\0': tokenizer.tok.pubid &= "\uFFFD" of '>': tokenizer.tok.flags.incl(tfQuirks) switch_state DATA emit_tok elif c == tokenizer.quote: switch_state AFTER_DOCTYPE_PUBLIC_IDENTIFIER else: tokenizer.tok.pubid &= c of AFTER_DOCTYPE_PUBLIC_IDENTIFIER: case c of AsciiWhitespace: switch_state BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS of '>': switch_state DATA emit_tok of '"', '\'': tokenizer.tok.flags.incl(tfSysid) tokenizer.quote = c switch_state DOCTYPE_SYSTEM_IDENTIFIER_QUOTED else: tokenizer.tok.flags.incl(tfQuirks) reconsume_in BOGUS_DOCTYPE of BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: case c of AsciiWhitespace: discard of '>': switch_state DATA emit_tok of '"', '\'': tokenizer.tok.flags.incl(tfSysid) tokenizer.quote = c switch_state DOCTYPE_SYSTEM_IDENTIFIER_QUOTED else: tokenizer.tok.flags.incl(tfQuirks) reconsume_in BOGUS_DOCTYPE of AFTER_DOCTYPE_SYSTEM_KEYWORD: case c of AsciiWhitespace: switch_state BEFORE_DOCTYPE_SYSTEM_IDENTIFIER of '"', '\'': tokenizer.tok.flags.incl(tfSysid) tokenizer.quote = c switch_state DOCTYPE_SYSTEM_IDENTIFIER_QUOTED of '>': tokenizer.tok.flags.incl(tfQuirks) switch_state DATA emit_tok else: tokenizer.tok.flags.incl(tfQuirks) reconsume_in BOGUS_DOCTYPE of BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: case c of AsciiWhitespace: discard of '"', '\'': tokenizer.tok.flags.incl(tfSysid) tokenizer.quote = c switch_state DOCTYPE_SYSTEM_IDENTIFIER_QUOTED of '>': tokenizer.tok.flags.incl(tfQuirks) switch_state DATA emit_tok else: tokenizer.tok.flags.incl(tfQuirks) reconsume_in BOGUS_DOCTYPE of DOCTYPE_SYSTEM_IDENTIFIER_QUOTED: case c of '\0': tokenizer.tok.sysid &= "\uFFFD" of '>': tokenizer.tok.flags.incl(tfQuirks) switch_state DATA emit_tok elif c == tokenizer.quote: switch_state AFTER_DOCTYPE_SYSTEM_IDENTIFIER else: tokenizer.tok.sysid &= c of AFTER_DOCTYPE_SYSTEM_IDENTIFIER: case c of AsciiWhitespace: discard of '>': switch_state DATA emit_tok else: switch_state BOGUS_DOCTYPE of BOGUS_DOCTYPE: if c == '>': emit_tok switch_state DATA of CDATA_SECTION: case c of ']': switch_state CDATA_SECTION_BRACKET of '\0': # "U+0000 NULL characters are handled in the tree construction stage, # as part of the in foreign content insertion mode, which is the only # place where CDATA sections can appear." emit_null else: emit c of CDATA_SECTION_BRACKET: if c == ']': switch_state CDATA_SECTION_END else: emit ']' reconsume_in CDATA_SECTION of CDATA_SECTION_END: case c of ']': emit ']' of '>': switch_state DATA else: emit "]]" reconsume_in CDATA_SECTION of CHARACTER_REFERENCE: case c of AsciiAlpha: tokenizer.tmp = "&" reconsume_in NAMED_CHARACTER_REFERENCE of '#': tokenizer.tmp = "&#" switch_state NUMERIC_CHARACTER_REFERENCE else: tokenizer.appendAttrOrEmit("&") reconsume_in tokenizer.rstate of NAMED_CHARACTER_REFERENCE: let (i, ci, entry) = tokenizer.findCharRef(c, ibuf) if entry == nil and i == -1: # -1 encountered without isend tokenizer.reconsume(tokenizer.tmp.toOpenArray(1, tokenizer.tmp.high)) tokenizer.tmp = "&" break # Move back the pointer & shorten the buffer to the last match. # (Add 1, because we do not store the starting & char in entityMap, # but tmp starts with an &.) tokenizer.reconsume(tokenizer.tmp.toOpenArray(ci + 1, tokenizer.tmp.high)) tokenizer.tmp.setLen(ci + 1) if entry != nil and entry[ci] == ':': let n = tokenizer.consume(ibuf) let sc = tokenizer.consumedAsAttribute() and tokenizer.tmp[^1] != ';' if sc and n != -1 and cast[char](n) in {'='} + AsciiAlphaNumeric: tokenizer.reconsume(cast[char](n)) tokenizer.appendAttrOrEmit(tokenizer.tmp) switch_state tokenizer.rstate elif sc and n == -1 and not tokenizer.isend: # We have to redo the above check. tokenizer.reconsume(tokenizer.tmp.toOpenArray(1, tokenizer.tmp.high)) tokenizer.tmp = "&" break else: if n != -1: tokenizer.reconsume(cast[char](n)) tokenizer.tmp = "" var ci = ci + 1 while (let c = entry[ci]; c != '\0'): tokenizer.tmp &= c inc ci tokenizer.appendAttrOrEmit(tokenizer.tmp) switch_state tokenizer.rstate else: tokenizer.appendAttrOrEmit(tokenizer.tmp) switch_state AMBIGUOUS_AMPERSAND_STATE of AMBIGUOUS_AMPERSAND_STATE: if c in AsciiAlpha: tokenizer.appendAttrOrEmit([c]) else: reconsume_in tokenizer.rstate of NUMERIC_CHARACTER_REFERENCE: tokenizer.code = 0 case c of 'x', 'X': tokenizer.tmp &= c switch_state HEXADECIMAL_CHARACTER_REFERENCE_START of AsciiDigit: tokenizer.code = uint32(c) - uint32('0') # note: was reconsume switch_state DECIMAL_CHARACTER_REFERENCE else: tokenizer.appendAttrOrEmit(tokenizer.tmp) reconsume_in tokenizer.rstate of HEXADECIMAL_CHARACTER_REFERENCE_START: let c2 = c.toLowerAscii() case c2 of AsciiDigit: tokenizer.code = uint32(c2) - uint32('0') # note: was reconsume switch_state HEXADECIMAL_CHARACTER_REFERENCE of 'a'..'f': tokenizer.code = uint32(c2) - uint32('a') + 10 # note: was reconsume switch_state HEXADECIMAL_CHARACTER_REFERENCE else: tokenizer.appendAttrOrEmit(tokenizer.tmp) reconsume_in tokenizer.rstate of HEXADECIMAL_CHARACTER_REFERENCE: let c2 = c.toLowerAscii() case c2 of AsciiDigit: if tokenizer.code <= 0x10FFFF: tokenizer.code *= 0x10 tokenizer.code += uint32(c2) - uint32('0') of 'a'..'f': if tokenizer.code <= 0x10FFFF: tokenizer.code *= 0x10 tokenizer.code += uint32(c2) - uint32('a') + 10 else: if c != ';': tokenizer.reconsume(c) tokenizer.numericCharacterReferenceEndState() switch_state tokenizer.rstate of DECIMAL_CHARACTER_REFERENCE: if c in AsciiDigit: if tokenizer.code <= 0x10FFFF: tokenizer.code *= 10 tokenizer.code += uint32(c) - uint32('0') else: if c != ';': tokenizer.reconsume(c) tokenizer.numericCharacterReferenceEndState() switch_state tokenizer.rstate return trDone proc finish*[Handle, Atom](tokenizer: var Tokenizer[Handle, Atom]): TokenizeResult = if tokenizer.peekBufLen > 0: tokenizer.isend = true if tokenizer.tokenize([]) != trDone: return trEmit if tokenizer.tokenizeEOF(): let r = tokenizer.tokenizeEOF() assert not r return trDone ������������������������������������������������������������������chawan-v0.4.0/lib/chame0/chame/minidom.nim����������������������������������������������������������0000664�0000000�0000000�00000044115�15202323131�0020260�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Minimal DOMBuilder example. Implements the absolute minimum required ## for htmlparser to work correctly. ## ## For an example of a complete implementation (with JS support and ## document.write), see Chawan's chadombuilder. ## ## Note: this only works with UTF-8 inputs. For a variant that can ## switch encodings when meta tags are encountered etc. see ## [chame/minidom_cs](minidom_cs.html). import std/algorithm import std/hashes import std/options import std/sets import std/streams import std/tables import htmlparser import tags export tags # Atom implementation #TODO maybe we should use a better hash map. const MAtomFactoryStrMapLength = 1024 # must be a power of 2 static: doAssert (MAtomFactoryStrMapLength and (MAtomFactoryStrMapLength - 1)) == 0 type MAtom* = distinct int MAtomFactory* = ref object of RootObj strMap: array[MAtomFactoryStrMapLength, seq[MAtom]] atomMap: seq[string] # Mandatory Atom functions func `==`*(a, b: MAtom): bool {.borrow.} func hash*(atom: MAtom): Hash {.borrow.} func strToAtom*(factory: MAtomFactory; s: string): MAtom proc newMAtomFactory*(): MAtomFactory = const minCap = int(TagType.high) + 1 let factory = MAtomFactory( atomMap: newSeqOfCap[string](minCap), ) factory.atomMap.add("") # skip TAG_UNKNOWN for tagType in TagType(int(TAG_UNKNOWN) + 1) .. TagType.high: discard factory.strToAtom($tagType) return factory func strToAtom*(factory: MAtomFactory; s: string): MAtom = let h = s.hash() let i = h and (factory.strMap.len - 1) for atom in factory.strMap[i]: if factory.atomMap[int(atom)] == s: # Found return atom # Not found let atom = MAtom(factory.atomMap.len) factory.atomMap.add(s) factory.strMap[i].add(atom) return atom func tagTypeToAtom*(factory: MAtomFactory; tagType: TagType): MAtom = assert tagType != TAG_UNKNOWN return MAtom(tagType) func atomToStr*(factory: MAtomFactory; atom: MAtom): string = return factory.atomMap[int(atom)] # Node types type Attribute* = ParsedAttr[MAtom] Node* = ref object of RootObj childList*: seq[Node] parentNode* {.cursor.}: Node CharacterData* = ref object of Node data*: string Comment* = ref object of CharacterData Document* = ref object of Node factory*: MAtomFactory Text* = ref object of CharacterData DocumentType* = ref object of Node name*: string publicId*: string systemId*: string Element* = ref object of Node localName*: MAtom namespace*: Namespace attrs*: seq[Attribute] document*: Document DocumentFragment* = ref object of Node HTMLTemplateElement* = ref object of Element content*: DocumentFragment type MiniDOMBuilder* = ref object of DOMBuilder[Node, MAtom] document*: Document factory*: MAtomFactory type DOMBuilderImpl = MiniDOMBuilder AtomImpl = MAtom HandleImpl = Node include htmlparseriface iterator ancestors*(node: Node): Node = var it = node.parentNode while it != nil: yield it it = it.parentNode iterator descendants*(node: Node): Node = var stack = newSeqOfCap[Node](node.childList.len) for i in countdown(node.childList.high, 0): stack.add(node.childList[i]) while stack.len > 0: let node = stack.pop() yield node for i in countdown(node.childList.high, 0): stack.add(node.childList[i]) proc findAttribute*(element: Element; name: string): int = if element.attrs.len == 0: return -1 let name = element.document.factory.strToAtom(name) for i, it in element.attrs.mpairs: if it.name == name: return i return -1 proc hasAttribute*(element: Element; name: string): bool = element.findAttribute(name) != -1 proc clone*(node: Node; deep: bool): Node = let copy = if node of Element: let element = Element(node) Node(Element( localName: element.localName, namespace: element.namespace, attrs: element.attrs, document: element.document )) elif node of Text: Node(Text(data: Text(node).data)) elif node of Comment: Node(Comment(data: Comment(node).data)) elif node of Document: Node(Document(factory: Document(node).factory)) elif node of DocumentType: let doctype = DocumentType(node) Node(DocumentType( name: doctype.name, publicId: doctype.publicId, systemId: doctype.systemId )) elif node of DocumentFragment: Node(DocumentFragment()) else: assert false Node(nil) if deep: for child in node.childList: copy.childList.add(child.clone(deep = true)) return copy func toTagType*(atom: MAtom): TagType {.inline.} = if int(atom) <= int(high(TagType)): return TagType(atom) return TAG_UNKNOWN func tagType*(element: Element): TagType = return element.localName.toTagType() func cmp*(a, b: MAtom): int {.inline.} = return cmp(int(a), int(b)) # We use this to validate input strings, since htmltokenizer/htmlparser does no # input validation. proc toValidUTF8(s: string): string = result = "" var i = 0 while i < s.len: if int(s[i]) < 0x80: result &= s[i] inc i elif int(s[i]) shr 5 == 0x6: if i + 1 < s.len and int(s[i + 1]) shr 6 == 2: result &= s[i] result &= s[i + 1] else: result &= "\uFFFD" i += 2 elif int(s[i]) shr 4 == 0xE: if i + 2 < s.len and int(s[i + 1]) shr 6 == 2 and int(s[i + 2]) shr 6 == 2: result &= s[i] result &= s[i + 1] result &= s[i + 2] else: result &= "\uFFFD" i += 3 elif int(s[i]) shr 3 == 0x1E: if i + 3 < s.len and int(s[i + 1]) shr 6 == 2 and int(s[i + 2]) shr 6 == 2 and int(s[i + 3]) shr 6 == 2: result &= s[i] result &= s[i + 1] result &= s[i + 2] result &= s[i + 3] else: result &= "\uFFFD" i += 4 else: result &= "\uFFFD" inc i proc localNameStr*(element: Element): string = return element.document.factory.atomToStr(element.localName) iterator attrsStr*(element: Element): tuple[name, value: string] = let factory = element.document.factory for attr in element.attrs: var name = "" if attr.prefix != NO_PREFIX: name &= $attr.prefix & ':' name &= factory.atomToStr(attr.name) yield (name, attr.value) # htmlparseriface implementation proc strToAtomImpl(builder: MiniDOMBuilder, s: string): MAtom = return builder.factory.strToAtom(s) proc tagTypeToAtomImpl(builder: MiniDOMBuilder; tagType: TagType): MAtom = return builder.factory.tagTypeToAtom(tagType) proc atomToTagTypeImpl(builder: MiniDOMBuilder; atom: MAtom): TagType = return atom.toTagType() proc getDocumentImpl(builder: MiniDOMBuilder): Node = return builder.document proc getParentNodeImpl(builder: MiniDOMBuilder; handle: Node): Option[Node] = return option(handle.parentNode) proc createElement(document: Document; localName: MAtom; namespace: Namespace): Element = let element = if localName.toTagType() == TAG_TEMPLATE and namespace == Namespace.HTML: HTMLTemplateElement( content: DocumentFragment() ) else: Element() element.localName = localName element.namespace = namespace element.document = document return element proc createHTMLElementImpl(builder: MiniDOMBuilder): Node = let localName = builder.factory.tagTypeToAtom(TAG_HTML) return builder.document.createElement(localName, Namespace.HTML) proc createElementForTokenImpl(builder: MiniDOMBuilder; localName: MAtom; namespace: Namespace; intendedParent: Node; htmlAttrs: Table[MAtom, string]; xmlAttrs: seq[Attribute]): Node = let element = builder.document.createElement(localName, namespace) element.attrs = xmlAttrs for k, v in htmlAttrs: element.attrs.add((NO_PREFIX, NO_NAMESPACE, k, v.toValidUTF8())) element.attrs.sort(func(a, b: Attribute): int = cmp(a.name, b.name)) return element proc getLocalNameImpl(builder: MiniDOMBuilder; handle: Node): MAtom = return Element(handle).localName proc getNamespaceImpl(builder: MiniDOMBuilder; handle: Node): Namespace = return Element(handle).namespace proc getTemplateContentImpl(builder: MiniDOMBuilder, handle: Node): Node = return HTMLTemplateElement(handle).content func countElementChildren(node: Node): int = result = 0 for child in node.childList: if child of Element: inc result func hasTextChild(node: Node): bool = for child in node.childList: if child of Text: return true return false func hasElementChild(node: Node): bool = for child in node.childList: if child of Element: return true return false func hasDocumentTypeChild(node: Node): bool = for child in node.childList: if child of DocumentType: return true return false func isHostIncludingInclusiveAncestor(a, b: Node): bool = var b = b while b != nil: if b == a: return true b = b.parentNode return false func hasPreviousElementSibling(node: Node): bool = for n in node.parentNode.childList: if n == node: break if n of Element: return true return false func hasNextDocumentTypeSibling(node: Node): bool = for i in countdown(node.parentNode.childList.len, 0): let n = node.parentNode.childList[i] if n == node: break if n of DocumentType: return true return false func isValidParent(node: Node): bool = return node of Element or node of Document or node of DocumentFragment func isValidChild(node: Node): bool = return node.isValidParent or node of DocumentType or node of CharacterData # WARNING the ordering of the arguments in the standard is whack so this # doesn't match that func preInsertionValidity*(parent, node, before: Node): bool = if not parent.isValidParent: return false if node.isHostIncludingInclusiveAncestor(parent): return false if before != nil and before.parentNode != parent: return false if not node.isValidChild: return false if node of Text and parent of Document: return false if node of DocumentType and not (parent of Document): return false if parent of Document: if node of DocumentFragment: let elems = node.countElementChildren() if elems > 1 or node.hasTextChild(): return false elif elems == 1 and (parent.hasElementChild() or before != nil and (before of DocumentType or before.hasNextDocumentTypeSibling())): return false elif node of Element: if parent.hasElementChild(): return false elif before != nil and (before of DocumentType or before.hasNextDocumentTypeSibling()): return false elif node of DocumentType: if parent.hasDocumentTypeChild() or before != nil and before.hasPreviousElementSibling() or before == nil and parent.hasElementChild(): return false return true # no exception reached proc insertBefore(parent, child: Node; before: Option[Node]) = let before = before.get(nil) if parent.preInsertionValidity(child, before): assert child.parentNode == nil if before == nil: parent.childList.add(child) else: let i = parent.childList.find(before) parent.childList.insert(child, i) child.parentNode = parent proc insertBeforeImpl(builder: MiniDOMBuilder; parent, child: Node; before: Option[Node]) = parent.insertBefore(child, before) proc insertCommentImpl(builder: MiniDOMBuilder; parent: Node; text: string; before: Option[Node]) = let comment = Comment(data: text.toValidUTF8()) parent.insertBefore(comment, before) proc appendDocumentTypeImpl(builder: MiniDOMBuilder, name, publicId, systemId: string) = let doctype = DocumentType( name: name.toValidUTF8(), publicId: publicId.toValidUTF8(), systemId: systemId.toValidUTF8() ) builder.document.insertBefore(doctype, none(Node)) proc insertTextImpl(builder: MiniDOMBuilder; parent: Node; text: string; before: Option[Node]) = let text = text.toValidUTF8() let before = before.get(nil) let prevSibling = if before != nil: let i = parent.childList.find(before) if i == 0: nil else: parent.childList[i - 1] elif parent.childList.len > 0: parent.childList[^1] else: nil if prevSibling != nil and prevSibling of Text: Text(prevSibling).data &= text else: let text = Text(data: text) parent.insertBefore(text, option(before)) proc removeImpl(builder: MiniDOMBuilder; child: Node) = if child.parentNode != nil: let i = child.parentNode.childList.find(child) child.parentNode.childList.delete(i) child.parentNode = nil proc moveChildrenImpl(builder: MiniDOMBuilder; fromNode, toNode: Node) = let tomove = @(fromNode.childList) fromNode.childList.setLen(0) for child in tomove: child.parentNode = nil toNode.insertBefore(child, none(Node)) proc elementPoppedImpl(builder: MiniDOMBuilder; node: Node) = let popped = Element(node) if popped.namespace != Namespace.HTML or popped.tagType != TAG_OPTION: return let selected = popped.hasAttribute("selected") for ancestor in popped.ancestors: if not (ancestor of Element): break let ancestor = Element(ancestor) if ancestor.namespace != Namespace.HTML or ancestor.tagType != TAG_SELECT: continue var found: Element = nil for child in ancestor.descendants: if not (child of Element): continue let child = Element(child) if child.namespace == Namespace.HTML: if child.tagType == TAG_OPTION and child != popped and not selected: # emulate selectedness by declaring the first option selected found = nil break if child.tagType == TAG_SELECTEDCONTENT: found = child if found != nil: for it in found.childList: it.parentNode = nil found.childList.setLen(0) for child in popped.childList: found.childList.add(child.clone(deep = true)) break proc addAttrsIfMissingImpl(builder: MiniDOMBuilder; handle: Node; attrs: Table[MAtom, string]) = let element = Element(handle) var oldNames = initHashSet[MAtom]() for attr in element.attrs: oldNames.incl(attr.name) for name, value in attrs: if name notin oldNames: element.attrs.add((NO_PREFIX, NO_NAMESPACE, name, value.toValidUTF8())) element.attrs.sort(func(a, b: Attribute): int = cmp(a.name, b.name)) method setEncodingImpl(builder: MiniDOMBuilder; encoding: string): SetEncodingResult {.base.} = # Provided as a method for minidom_cs to override. return SET_ENCODING_CONTINUE proc newMiniDOMBuilder*(factory: MAtomFactory): MiniDOMBuilder = let document = Document(factory: factory) let builder = MiniDOMBuilder( document: document, factory: factory ) return builder proc parseFromStream(parser: var HTML5Parser[Node, MAtom]; inputStream: Stream) = var buffer {.noinit.}: array[4096, char] while true: let n = inputStream.readData(addr buffer[0], buffer.len) if n == 0: break # res can be PRES_CONTINUE or PRES_SCRIPTING. PRES_STOP is only returned # on charset switching, and minidom does not support that. var res = parser.parseChunk(buffer.toOpenArray(0, n - 1)) # Important: we must repeat parseChunk with the same contents for the script # end tag result, with reprocess = true. # # (This is only relevant for calls where scripting = true; with scripting = # false, PRES_SCRIPT would never be returned.) var ip = 0 while res == PRES_SCRIPT and (ip += parser.getInsertionPoint(); ip != n): res = parser.parseChunk(buffer.toOpenArray(ip, n - 1)) parser.finish() proc parseHTML*(inputStream: Stream; opts = HTML5ParserOpts[Node, MAtom](); factory = newMAtomFactory()): Document = ## Read, parse and return an HTML document from `inputStream`, using ## parser options `opts` and MAtom factory `factory`. ## ## `inputStream` is not required to be seekable. ## ## For a description of `HTML5ParserOpts`, see the `htmlparser` module's ## documentation. let builder = newMiniDOMBuilder(factory) var parser = initHTML5Parser(builder, opts) parser.parseFromStream(inputStream) return builder.document proc parseHTMLFragment*(inputStream: Stream; element: Element; opts: HTML5ParserOpts[Node, MAtom]; factory = newMAtomFactory()): seq[Node] = ## Read, parse and return the children of an HTML fragment from `inputStream`, ## using context element `element` and parser options `opts`. ## ## For information on `opts` (an `HTML5ParserOpts` object), please consult ## the documentation of chame/htmlparser.nim. ## ## For details on the HTML fragment parsing algorithm, see ## https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments ## ## Note: the members `ctx`, `initialTokenizerState`, `openElementsInit` and ## `pushInTemplate` of `opts` are overridden (in accordance with the standard). let builder = newMiniDOMBuilder(factory) let document = builder.document let state = if element.namespace != Namespace.HTML: DATA else: case element.tagType of TAG_TITLE, TAG_TEXTAREA: RCDATA of TAG_STYLE, TAG_XMP, TAG_IFRAME, TAG_NOEMBED, TAG_NOFRAMES: RAWTEXT of TAG_SCRIPT: SCRIPT_DATA of TAG_NOSCRIPT: DATA # no scripting of TAG_PLAINTEXT: PLAINTEXT else: DATA let htmlAtom = builder.factory.tagTypeToAtom(TAG_HTML) let root = Element( localName: htmlAtom, namespace: HTML, document: document ) document.childList = @[Node(root)] var opts = opts opts.ctx = some((Node(element), element.localName)) opts.initialTokenizerState = state opts.openElementsInit = @[(Node(root), htmlAtom)] opts.pushInTemplate = element.tagType == TAG_TEMPLATE var parser = initHTML5Parser(builder, opts) parser.parseFromStream(inputStream) return root.childList proc parseHTMLFragment*(s: string; element: Element): seq[Node] = ## Convenience wrapper around parseHTMLFragment with opts. ## ## Read, parse and return the children of an HTML fragment from the string `s`, ## using context element `element`. ## ## For details on the HTML fragment parsing algorithm, see ## https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments let inputStream = newStringStream(s) let opts = HTML5ParserOpts[Node, MAtom]( isIframeSrcdoc: false, scripting: false, pushInTemplate: element.tagType == TAG_TEMPLATE ) return parseHTMLFragment(inputStream, element, opts) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/chame/minidom_cs.nim�������������������������������������������������������0000664�0000000�0000000�00000014015�15202323131�0020741�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## A demonstration of using the Chagashi encoding library in combination ## with the Chame HTML parser. ## ## For the most part, this is the same as minidom, except it supports ## decoding documents with arbitrary character sets. ## ## Note: this is not implemented for the fragment parsing algorithm, ## because that is only defined for UTF-8 in the standard. ## ## For a version without the encoding library dependency, see ## [minidom](minidom.html). import std/streams import minidom import htmlparser import tags import chagashi/charset import chagashi/decoder export minidom export tags type CharsetConfidence = enum ccTentative, ccCertain type CharsetMiniDOMBuilder = ref object of MiniDOMBuilder charset: Charset confidence: CharsetConfidence method setEncodingImpl(builder: CharsetMiniDOMBuilder; encoding: string): SetEncodingResult = let charset = getCharset(encoding) if charset == csUnknown: return SET_ENCODING_CONTINUE if builder.charset in {csUtf16le, csUtf16be}: builder.confidence = ccCertain return SET_ENCODING_CONTINUE builder.confidence = ccCertain if charset == builder.charset: return SET_ENCODING_CONTINUE if charset == csXUserDefined: builder.charset = csWindows1252 else: builder.charset = charset return SET_ENCODING_STOP proc newCharsetMiniDOMBuilder(factory: MAtomFactory): CharsetMiniDOMBuilder = let document = Document(factory: factory) let builder = CharsetMiniDOMBuilder(document: document, factory: factory) return builder #TODO this should be handled by decoderstream proc bomSniff(inputStream: Stream): Charset = let bom = inputStream.readStr(2) if bom == "\xFE\xFF": return csUtf16be if bom == "\xFF\xFE": return csUtf16le if bom == "\xEF\xBB": if inputStream.readChar() == '\xBF': return csUtf8 inputStream.setPosition(0) return csUnknown proc parseHTML*(inputStream: Stream; opts: HTML5ParserOpts[Node, MAtom]; charsets: seq[Charset]; seekable = true; factory = newMAtomFactory()): Document = ## Read, parse and return an HTML document from `inputStream`. ## ## `charsets` is a list of input character sets to try. If empty, it will be ## initialized to `@[csUtf8]`. ## ## The list of fallback charsets is used as follows: ## ## * A charset stack is initialized to `charsets`, reversed. This ## means that the first charset specified in `charsets` is on top of ## the stack. (e.g. say `charsets = @[csUtf16le, csUtf8]`, ## then utf-16-le is tried before utf-8.) ## * BOM sniffing is attempted. If successful, confidence is set to ## certain and the resulting charset is used (i.e. other character ## sets will not be tried for decoding this document.) ## * If the charset stack is empty, UTF-8 is pushed on top. ## * Attempt to parse the document with the first charset on top of ## the stack. ## * If BOM sniffing was unsuccessful, and a <meta charset=...> tag ## is encountered, parsing is restarted with the specified charset. ## No further attempts are made to detect the encoding, and decoder ## errors are signaled by U+FFFD replacement characters. ## * Otherwise, each charset on the charset stack is tried until either no ## decoding errors are encountered, or only one charset is left. For ## the last charset, decoder errors are signaled by U+FFFD replacement ## characters. ## ## `seekable` must be true only if `inputStream` is seekable; if set to true, ## `inputStream.setPosition(0)` must work. ## ## Note that `seekable = false` disables automatic character set detection; ## even `<meta charset=...` tags will be disregarded. ## (TODO: this should be improved in the future; theoretically we could still ## switch between ASCII-compatible charsets before non-ASCII is encountered.) let builder = newCharsetMiniDOMBuilder(factory) var charsetStack: seq[Charset] = @[] for i in countdown(charsets.high, 0): charsetStack.add(charsets[i]) var seekable = seekable var inputStream = inputStream if seekable: let scs = inputStream.bomSniff() if scs != csUnknown: charsetStack.add(scs) builder.confidence = ccCertain seekable = false if charsetStack.len == 0: charsetStack.add(DefaultCharset) # UTF-8 while true: builder.charset = charsetStack.pop() if seekable and charsetStack.len > 0: builder.confidence = ccTentative # used in the next iteration else: builder.confidence = ccCertain var parser = initHTML5Parser(builder, opts) var iq {.noinit.}: array[4096, char] let errorMode = [ ccTentative: demFatal, ccCertain: demReplacement ][builder.confidence] var ctx = initTextDecoderContext(builder.charset, errorMode) while true: let n = inputStream.readData(addr iq[0], iq.len) var finish = n < iq.len for chunk in ctx.decode(iq.toOpenArrayByte(0, n - 1), finish = finish): # res can be PRES_SCRIPT, PRES_STOP or PRES_CONTINUE. var res = parser.parseChunk(chunk.toOpenArray()) # For PRES_SCRIPT, we must re-feed the same chunk as in minidom, but # starting from the current insertion point. var ip = 0 while res == PRES_SCRIPT and (ip += parser.getInsertionPoint(); ip != chunk.len): res = parser.parseChunk(chunk.toOpenArray(ip, chunk.high)) # PRES_STOP is returned when we return SET_ENCODING_STOP from # setEncodingImpl. We immediately stop parsing in this case. if res == PRES_STOP: finish = true break if finish: break parser.finish() if builder.confidence == ccCertain and seekable: # A meta tag describing the charset has been found; force use of this # charset. inputStream.setPosition(0) builder.document = Document(factory: factory) charsetStack.add(builder.charset) seekable = false continue if ctx.failed and seekable: # Retry with another charset. inputStream.setPosition(0) builder.document = Document(factory: factory) continue break return builder.document �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/chame/res/�����������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0016703�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/chame/res/entity.json������������������������������������������������������0000664�0000000�0000000�00000434751�15202323131�0021130�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{ "&AElig": { "codepoints": [198], "characters": "\u00C6" }, "&AElig;": { "codepoints": [198], "characters": "\u00C6" }, "&AMP": { "codepoints": [38], "characters": "\u0026" }, "&AMP;": { "codepoints": [38], "characters": "\u0026" }, "&Aacute": { "codepoints": [193], "characters": "\u00C1" }, "&Aacute;": { "codepoints": [193], "characters": "\u00C1" }, "&Abreve;": { "codepoints": [258], "characters": "\u0102" }, "&Acirc": { "codepoints": [194], "characters": "\u00C2" }, "&Acirc;": { "codepoints": [194], "characters": "\u00C2" }, "&Acy;": { "codepoints": [1040], "characters": "\u0410" }, "&Afr;": { "codepoints": [120068], "characters": "\uD835\uDD04" }, "&Agrave": { "codepoints": [192], "characters": "\u00C0" }, "&Agrave;": { "codepoints": [192], "characters": "\u00C0" }, "&Alpha;": { "codepoints": [913], "characters": "\u0391" }, "&Amacr;": { "codepoints": [256], "characters": "\u0100" }, "&And;": { "codepoints": [10835], "characters": "\u2A53" }, "&Aogon;": { "codepoints": [260], "characters": "\u0104" }, "&Aopf;": { "codepoints": [120120], "characters": "\uD835\uDD38" }, "&ApplyFunction;": { "codepoints": [8289], "characters": "\u2061" }, "&Aring": { "codepoints": [197], "characters": "\u00C5" }, "&Aring;": { "codepoints": [197], "characters": "\u00C5" }, "&Ascr;": { "codepoints": [119964], "characters": "\uD835\uDC9C" }, "&Assign;": { "codepoints": [8788], "characters": "\u2254" }, "&Atilde": { "codepoints": [195], "characters": "\u00C3" }, "&Atilde;": { "codepoints": [195], "characters": "\u00C3" }, "&Auml": { "codepoints": [196], "characters": "\u00C4" }, "&Auml;": { "codepoints": [196], "characters": "\u00C4" }, "&Backslash;": { "codepoints": [8726], "characters": "\u2216" }, "&Barv;": { "codepoints": [10983], "characters": "\u2AE7" }, "&Barwed;": { "codepoints": [8966], "characters": "\u2306" }, "&Bcy;": { "codepoints": [1041], "characters": "\u0411" }, "&Because;": { "codepoints": [8757], "characters": "\u2235" }, "&Bernoullis;": { "codepoints": [8492], "characters": "\u212C" }, "&Beta;": { "codepoints": [914], "characters": "\u0392" }, "&Bfr;": { "codepoints": [120069], "characters": "\uD835\uDD05" }, "&Bopf;": { "codepoints": [120121], "characters": "\uD835\uDD39" }, "&Breve;": { "codepoints": [728], "characters": "\u02D8" }, "&Bscr;": { "codepoints": [8492], "characters": "\u212C" }, "&Bumpeq;": { "codepoints": [8782], "characters": "\u224E" }, "&CHcy;": { "codepoints": [1063], "characters": "\u0427" }, "&COPY": { "codepoints": [169], "characters": "\u00A9" }, "&COPY;": { "codepoints": [169], "characters": "\u00A9" }, "&Cacute;": { "codepoints": [262], "characters": "\u0106" }, "&Cap;": { "codepoints": [8914], "characters": "\u22D2" }, "&CapitalDifferentialD;": { "codepoints": [8517], "characters": "\u2145" }, "&Cayleys;": { "codepoints": [8493], "characters": "\u212D" }, "&Ccaron;": { "codepoints": [268], "characters": "\u010C" }, "&Ccedil": { "codepoints": [199], "characters": "\u00C7" }, "&Ccedil;": { "codepoints": [199], "characters": "\u00C7" }, "&Ccirc;": { "codepoints": [264], "characters": "\u0108" }, "&Cconint;": { "codepoints": [8752], "characters": "\u2230" }, "&Cdot;": { "codepoints": [266], "characters": "\u010A" }, "&Cedilla;": { "codepoints": [184], "characters": "\u00B8" }, "&CenterDot;": { "codepoints": [183], "characters": "\u00B7" }, "&Cfr;": { "codepoints": [8493], "characters": "\u212D" }, "&Chi;": { "codepoints": [935], "characters": "\u03A7" }, "&CircleDot;": { "codepoints": [8857], "characters": "\u2299" }, "&CircleMinus;": { "codepoints": [8854], "characters": "\u2296" }, "&CirclePlus;": { "codepoints": [8853], "characters": "\u2295" }, "&CircleTimes;": { "codepoints": [8855], "characters": "\u2297" }, "&ClockwiseContourIntegral;": { "codepoints": [8754], "characters": "\u2232" }, "&CloseCurlyDoubleQuote;": { "codepoints": [8221], "characters": "\u201D" }, "&CloseCurlyQuote;": { "codepoints": [8217], "characters": "\u2019" }, "&Colon;": { "codepoints": [8759], "characters": "\u2237" }, "&Colone;": { "codepoints": [10868], "characters": "\u2A74" }, "&Congruent;": { "codepoints": [8801], "characters": "\u2261" }, "&Conint;": { "codepoints": [8751], "characters": "\u222F" }, "&ContourIntegral;": { "codepoints": [8750], "characters": "\u222E" }, "&Copf;": { "codepoints": [8450], "characters": "\u2102" }, "&Coproduct;": { "codepoints": [8720], "characters": "\u2210" }, "&CounterClockwiseContourIntegral;": { "codepoints": [8755], "characters": "\u2233" }, "&Cross;": { "codepoints": [10799], "characters": "\u2A2F" }, "&Cscr;": { "codepoints": [119966], "characters": "\uD835\uDC9E" }, "&Cup;": { "codepoints": [8915], "characters": "\u22D3" }, "&CupCap;": { "codepoints": [8781], "characters": "\u224D" }, "&DD;": { "codepoints": [8517], "characters": "\u2145" }, "&DDotrahd;": { "codepoints": [10513], "characters": "\u2911" }, "&DJcy;": { "codepoints": [1026], "characters": "\u0402" }, "&DScy;": { "codepoints": [1029], "characters": "\u0405" }, "&DZcy;": { "codepoints": [1039], "characters": "\u040F" }, "&Dagger;": { "codepoints": [8225], "characters": "\u2021" }, "&Darr;": { "codepoints": [8609], "characters": "\u21A1" }, "&Dashv;": { "codepoints": [10980], "characters": "\u2AE4" }, "&Dcaron;": { "codepoints": [270], "characters": "\u010E" }, "&Dcy;": { "codepoints": [1044], "characters": "\u0414" }, "&Del;": { "codepoints": [8711], "characters": "\u2207" }, "&Delta;": { "codepoints": [916], "characters": "\u0394" }, "&Dfr;": { "codepoints": [120071], "characters": "\uD835\uDD07" }, "&DiacriticalAcute;": { "codepoints": [180], "characters": "\u00B4" }, "&DiacriticalDot;": { "codepoints": [729], "characters": "\u02D9" }, "&DiacriticalDoubleAcute;": { "codepoints": [733], "characters": "\u02DD" }, "&DiacriticalGrave;": { "codepoints": [96], "characters": "\u0060" }, "&DiacriticalTilde;": { "codepoints": [732], "characters": "\u02DC" }, "&Diamond;": { "codepoints": [8900], "characters": "\u22C4" }, "&DifferentialD;": { "codepoints": [8518], "characters": "\u2146" }, "&Dopf;": { "codepoints": [120123], "characters": "\uD835\uDD3B" }, "&Dot;": { "codepoints": [168], "characters": "\u00A8" }, "&DotDot;": { "codepoints": [8412], "characters": "\u20DC" }, "&DotEqual;": { "codepoints": [8784], "characters": "\u2250" }, "&DoubleContourIntegral;": { "codepoints": [8751], "characters": "\u222F" }, "&DoubleDot;": { "codepoints": [168], "characters": "\u00A8" }, "&DoubleDownArrow;": { "codepoints": [8659], "characters": "\u21D3" }, "&DoubleLeftArrow;": { "codepoints": [8656], "characters": "\u21D0" }, "&DoubleLeftRightArrow;": { "codepoints": [8660], "characters": "\u21D4" }, "&DoubleLeftTee;": { "codepoints": [10980], "characters": "\u2AE4" }, "&DoubleLongLeftArrow;": { "codepoints": [10232], "characters": "\u27F8" }, "&DoubleLongLeftRightArrow;": { "codepoints": [10234], "characters": "\u27FA" }, "&DoubleLongRightArrow;": { "codepoints": [10233], "characters": "\u27F9" }, "&DoubleRightArrow;": { "codepoints": [8658], "characters": "\u21D2" }, "&DoubleRightTee;": { "codepoints": [8872], "characters": "\u22A8" }, "&DoubleUpArrow;": { "codepoints": [8657], "characters": "\u21D1" }, "&DoubleUpDownArrow;": { "codepoints": [8661], "characters": "\u21D5" }, "&DoubleVerticalBar;": { "codepoints": [8741], "characters": "\u2225" }, "&DownArrow;": { "codepoints": [8595], "characters": "\u2193" }, "&DownArrowBar;": { "codepoints": [10515], "characters": "\u2913" }, "&DownArrowUpArrow;": { "codepoints": [8693], "characters": "\u21F5" }, "&DownBreve;": { "codepoints": [785], "characters": "\u0311" }, "&DownLeftRightVector;": { "codepoints": [10576], "characters": "\u2950" }, "&DownLeftTeeVector;": { "codepoints": [10590], "characters": "\u295E" }, "&DownLeftVector;": { "codepoints": [8637], "characters": "\u21BD" }, "&DownLeftVectorBar;": { "codepoints": [10582], "characters": "\u2956" }, "&DownRightTeeVector;": { "codepoints": [10591], "characters": "\u295F" }, "&DownRightVector;": { "codepoints": [8641], "characters": "\u21C1" }, "&DownRightVectorBar;": { "codepoints": [10583], "characters": "\u2957" }, "&DownTee;": { "codepoints": [8868], "characters": "\u22A4" }, "&DownTeeArrow;": { "codepoints": [8615], "characters": "\u21A7" }, "&Downarrow;": { "codepoints": [8659], "characters": "\u21D3" }, "&Dscr;": { "codepoints": [119967], "characters": "\uD835\uDC9F" }, "&Dstrok;": { "codepoints": [272], "characters": "\u0110" }, "&ENG;": { "codepoints": [330], "characters": "\u014A" }, "&ETH": { "codepoints": [208], "characters": "\u00D0" }, "&ETH;": { "codepoints": [208], "characters": "\u00D0" }, "&Eacute": { "codepoints": [201], "characters": "\u00C9" }, "&Eacute;": { "codepoints": [201], "characters": "\u00C9" }, "&Ecaron;": { "codepoints": [282], "characters": "\u011A" }, "&Ecirc": { "codepoints": [202], "characters": "\u00CA" }, "&Ecirc;": { "codepoints": [202], "characters": "\u00CA" }, "&Ecy;": { "codepoints": [1069], "characters": "\u042D" }, "&Edot;": { "codepoints": [278], "characters": "\u0116" }, "&Efr;": { "codepoints": [120072], "characters": "\uD835\uDD08" }, "&Egrave": { "codepoints": [200], "characters": "\u00C8" }, "&Egrave;": { "codepoints": [200], "characters": "\u00C8" }, "&Element;": { "codepoints": [8712], "characters": "\u2208" }, "&Emacr;": { "codepoints": [274], "characters": "\u0112" }, "&EmptySmallSquare;": { "codepoints": [9723], "characters": "\u25FB" }, "&EmptyVerySmallSquare;": { "codepoints": [9643], "characters": "\u25AB" }, "&Eogon;": { "codepoints": [280], "characters": "\u0118" }, "&Eopf;": { "codepoints": [120124], "characters": "\uD835\uDD3C" }, "&Epsilon;": { "codepoints": [917], "characters": "\u0395" }, "&Equal;": { "codepoints": [10869], "characters": "\u2A75" }, "&EqualTilde;": { "codepoints": [8770], "characters": "\u2242" }, "&Equilibrium;": { "codepoints": [8652], "characters": "\u21CC" }, "&Escr;": { "codepoints": [8496], "characters": "\u2130" }, "&Esim;": { "codepoints": [10867], "characters": "\u2A73" }, "&Eta;": { "codepoints": [919], "characters": "\u0397" }, "&Euml": { "codepoints": [203], "characters": "\u00CB" }, "&Euml;": { "codepoints": [203], "characters": "\u00CB" }, "&Exists;": { "codepoints": [8707], "characters": "\u2203" }, "&ExponentialE;": { "codepoints": [8519], "characters": "\u2147" }, "&Fcy;": { "codepoints": [1060], "characters": "\u0424" }, "&Ffr;": { "codepoints": [120073], "characters": "\uD835\uDD09" }, "&FilledSmallSquare;": { "codepoints": [9724], "characters": "\u25FC" }, "&FilledVerySmallSquare;": { "codepoints": [9642], "characters": "\u25AA" }, "&Fopf;": { "codepoints": [120125], "characters": "\uD835\uDD3D" }, "&ForAll;": { "codepoints": [8704], "characters": "\u2200" }, "&Fouriertrf;": { "codepoints": [8497], "characters": "\u2131" }, "&Fscr;": { "codepoints": [8497], "characters": "\u2131" }, "&GJcy;": { "codepoints": [1027], "characters": "\u0403" }, "&GT": { "codepoints": [62], "characters": "\u003E" }, "&GT;": { "codepoints": [62], "characters": "\u003E" }, "&Gamma;": { "codepoints": [915], "characters": "\u0393" }, "&Gammad;": { "codepoints": [988], "characters": "\u03DC" }, "&Gbreve;": { "codepoints": [286], "characters": "\u011E" }, "&Gcedil;": { "codepoints": [290], "characters": "\u0122" }, "&Gcirc;": { "codepoints": [284], "characters": "\u011C" }, "&Gcy;": { "codepoints": [1043], "characters": "\u0413" }, "&Gdot;": { "codepoints": [288], "characters": "\u0120" }, "&Gfr;": { "codepoints": [120074], "characters": "\uD835\uDD0A" }, "&Gg;": { "codepoints": [8921], "characters": "\u22D9" }, "&Gopf;": { "codepoints": [120126], "characters": "\uD835\uDD3E" }, "&GreaterEqual;": { "codepoints": [8805], "characters": "\u2265" }, "&GreaterEqualLess;": { "codepoints": [8923], "characters": "\u22DB" }, "&GreaterFullEqual;": { "codepoints": [8807], "characters": "\u2267" }, "&GreaterGreater;": { "codepoints": [10914], "characters": "\u2AA2" }, "&GreaterLess;": { "codepoints": [8823], "characters": "\u2277" }, "&GreaterSlantEqual;": { "codepoints": [10878], "characters": "\u2A7E" }, "&GreaterTilde;": { "codepoints": [8819], "characters": "\u2273" }, "&Gscr;": { "codepoints": [119970], "characters": "\uD835\uDCA2" }, "&Gt;": { "codepoints": [8811], "characters": "\u226B" }, "&HARDcy;": { "codepoints": [1066], "characters": "\u042A" }, "&Hacek;": { "codepoints": [711], "characters": "\u02C7" }, "&Hat;": { "codepoints": [94], "characters": "\u005E" }, "&Hcirc;": { "codepoints": [292], "characters": "\u0124" }, "&Hfr;": { "codepoints": [8460], "characters": "\u210C" }, "&HilbertSpace;": { "codepoints": [8459], "characters": "\u210B" }, "&Hopf;": { "codepoints": [8461], "characters": "\u210D" }, "&HorizontalLine;": { "codepoints": [9472], "characters": "\u2500" }, "&Hscr;": { "codepoints": [8459], "characters": "\u210B" }, "&Hstrok;": { "codepoints": [294], "characters": "\u0126" }, "&HumpDownHump;": { "codepoints": [8782], "characters": "\u224E" }, "&HumpEqual;": { "codepoints": [8783], "characters": "\u224F" }, "&IEcy;": { "codepoints": [1045], "characters": "\u0415" }, "&IJlig;": { "codepoints": [306], "characters": "\u0132" }, "&IOcy;": { "codepoints": [1025], "characters": "\u0401" }, "&Iacute": { "codepoints": [205], "characters": "\u00CD" }, "&Iacute;": { "codepoints": [205], "characters": "\u00CD" }, "&Icirc": { "codepoints": [206], "characters": "\u00CE" }, "&Icirc;": { "codepoints": [206], "characters": "\u00CE" }, "&Icy;": { "codepoints": [1048], "characters": "\u0418" }, "&Idot;": { "codepoints": [304], "characters": "\u0130" }, "&Ifr;": { "codepoints": [8465], "characters": "\u2111" }, "&Igrave": { "codepoints": [204], "characters": "\u00CC" }, "&Igrave;": { "codepoints": [204], "characters": "\u00CC" }, "&Im;": { "codepoints": [8465], "characters": "\u2111" }, "&Imacr;": { "codepoints": [298], "characters": "\u012A" }, "&ImaginaryI;": { "codepoints": [8520], "characters": "\u2148" }, "&Implies;": { "codepoints": [8658], "characters": "\u21D2" }, "&Int;": { "codepoints": [8748], "characters": "\u222C" }, "&Integral;": { "codepoints": [8747], "characters": "\u222B" }, "&Intersection;": { "codepoints": [8898], "characters": "\u22C2" }, "&InvisibleComma;": { "codepoints": [8291], "characters": "\u2063" }, "&InvisibleTimes;": { "codepoints": [8290], "characters": "\u2062" }, "&Iogon;": { "codepoints": [302], "characters": "\u012E" }, "&Iopf;": { "codepoints": [120128], "characters": "\uD835\uDD40" }, "&Iota;": { "codepoints": [921], "characters": "\u0399" }, "&Iscr;": { "codepoints": [8464], "characters": "\u2110" }, "&Itilde;": { "codepoints": [296], "characters": "\u0128" }, "&Iukcy;": { "codepoints": [1030], "characters": "\u0406" }, "&Iuml": { "codepoints": [207], "characters": "\u00CF" }, "&Iuml;": { "codepoints": [207], "characters": "\u00CF" }, "&Jcirc;": { "codepoints": [308], "characters": "\u0134" }, "&Jcy;": { "codepoints": [1049], "characters": "\u0419" }, "&Jfr;": { "codepoints": [120077], "characters": "\uD835\uDD0D" }, "&Jopf;": { "codepoints": [120129], "characters": "\uD835\uDD41" }, "&Jscr;": { "codepoints": [119973], "characters": "\uD835\uDCA5" }, "&Jsercy;": { "codepoints": [1032], "characters": "\u0408" }, "&Jukcy;": { "codepoints": [1028], "characters": "\u0404" }, "&KHcy;": { "codepoints": [1061], "characters": "\u0425" }, "&KJcy;": { "codepoints": [1036], "characters": "\u040C" }, "&Kappa;": { "codepoints": [922], "characters": "\u039A" }, "&Kcedil;": { "codepoints": [310], "characters": "\u0136" }, "&Kcy;": { "codepoints": [1050], "characters": "\u041A" }, "&Kfr;": { "codepoints": [120078], "characters": "\uD835\uDD0E" }, "&Kopf;": { "codepoints": [120130], "characters": "\uD835\uDD42" }, "&Kscr;": { "codepoints": [119974], "characters": "\uD835\uDCA6" }, "&LJcy;": { "codepoints": [1033], "characters": "\u0409" }, "&LT": { "codepoints": [60], "characters": "\u003C" }, "&LT;": { "codepoints": [60], "characters": "\u003C" }, "&Lacute;": { "codepoints": [313], "characters": "\u0139" }, "&Lambda;": { "codepoints": [923], "characters": "\u039B" }, "&Lang;": { "codepoints": [10218], "characters": "\u27EA" }, "&Laplacetrf;": { "codepoints": [8466], "characters": "\u2112" }, "&Larr;": { "codepoints": [8606], "characters": "\u219E" }, "&Lcaron;": { "codepoints": [317], "characters": "\u013D" }, "&Lcedil;": { "codepoints": [315], "characters": "\u013B" }, "&Lcy;": { "codepoints": [1051], "characters": "\u041B" }, "&LeftAngleBracket;": { "codepoints": [10216], "characters": "\u27E8" }, "&LeftArrow;": { "codepoints": [8592], "characters": "\u2190" }, "&LeftArrowBar;": { "codepoints": [8676], "characters": "\u21E4" }, "&LeftArrowRightArrow;": { "codepoints": [8646], "characters": "\u21C6" }, "&LeftCeiling;": { "codepoints": [8968], "characters": "\u2308" }, "&LeftDoubleBracket;": { "codepoints": [10214], "characters": "\u27E6" }, "&LeftDownTeeVector;": { "codepoints": [10593], "characters": "\u2961" }, "&LeftDownVector;": { "codepoints": [8643], "characters": "\u21C3" }, "&LeftDownVectorBar;": { "codepoints": [10585], "characters": "\u2959" }, "&LeftFloor;": { "codepoints": [8970], "characters": "\u230A" }, "&LeftRightArrow;": { "codepoints": [8596], "characters": "\u2194" }, "&LeftRightVector;": { "codepoints": [10574], "characters": "\u294E" }, "&LeftTee;": { "codepoints": [8867], "characters": "\u22A3" }, "&LeftTeeArrow;": { "codepoints": [8612], "characters": "\u21A4" }, "&LeftTeeVector;": { "codepoints": [10586], "characters": "\u295A" }, "&LeftTriangle;": { "codepoints": [8882], "characters": "\u22B2" }, "&LeftTriangleBar;": { "codepoints": [10703], "characters": "\u29CF" }, "&LeftTriangleEqual;": { "codepoints": [8884], "characters": "\u22B4" }, "&LeftUpDownVector;": { "codepoints": [10577], "characters": "\u2951" }, "&LeftUpTeeVector;": { "codepoints": [10592], "characters": "\u2960" }, "&LeftUpVector;": { "codepoints": [8639], "characters": "\u21BF" }, "&LeftUpVectorBar;": { "codepoints": [10584], "characters": "\u2958" }, "&LeftVector;": { "codepoints": [8636], "characters": "\u21BC" }, "&LeftVectorBar;": { "codepoints": [10578], "characters": "\u2952" }, "&Leftarrow;": { "codepoints": [8656], "characters": "\u21D0" }, "&Leftrightarrow;": { "codepoints": [8660], "characters": "\u21D4" }, "&LessEqualGreater;": { "codepoints": [8922], "characters": "\u22DA" }, "&LessFullEqual;": { "codepoints": [8806], "characters": "\u2266" }, "&LessGreater;": { "codepoints": [8822], "characters": "\u2276" }, "&LessLess;": { "codepoints": [10913], "characters": "\u2AA1" }, "&LessSlantEqual;": { "codepoints": [10877], "characters": "\u2A7D" }, "&LessTilde;": { "codepoints": [8818], "characters": "\u2272" }, "&Lfr;": { "codepoints": [120079], "characters": "\uD835\uDD0F" }, "&Ll;": { "codepoints": [8920], "characters": "\u22D8" }, "&Lleftarrow;": { "codepoints": [8666], "characters": "\u21DA" }, "&Lmidot;": { "codepoints": [319], "characters": "\u013F" }, "&LongLeftArrow;": { "codepoints": [10229], "characters": "\u27F5" }, "&LongLeftRightArrow;": { "codepoints": [10231], "characters": "\u27F7" }, "&LongRightArrow;": { "codepoints": [10230], "characters": "\u27F6" }, "&Longleftarrow;": { "codepoints": [10232], "characters": "\u27F8" }, "&Longleftrightarrow;": { "codepoints": [10234], "characters": "\u27FA" }, "&Longrightarrow;": { "codepoints": [10233], "characters": "\u27F9" }, "&Lopf;": { "codepoints": [120131], "characters": "\uD835\uDD43" }, "&LowerLeftArrow;": { "codepoints": [8601], "characters": "\u2199" }, "&LowerRightArrow;": { "codepoints": [8600], "characters": "\u2198" }, "&Lscr;": { "codepoints": [8466], "characters": "\u2112" }, "&Lsh;": { "codepoints": [8624], "characters": "\u21B0" }, "&Lstrok;": { "codepoints": [321], "characters": "\u0141" }, "&Lt;": { "codepoints": [8810], "characters": "\u226A" }, "&Map;": { "codepoints": [10501], "characters": "\u2905" }, "&Mcy;": { "codepoints": [1052], "characters": "\u041C" }, "&MediumSpace;": { "codepoints": [8287], "characters": "\u205F" }, "&Mellintrf;": { "codepoints": [8499], "characters": "\u2133" }, "&Mfr;": { "codepoints": [120080], "characters": "\uD835\uDD10" }, "&MinusPlus;": { "codepoints": [8723], "characters": "\u2213" }, "&Mopf;": { "codepoints": [120132], "characters": "\uD835\uDD44" }, "&Mscr;": { "codepoints": [8499], "characters": "\u2133" }, "&Mu;": { "codepoints": [924], "characters": "\u039C" }, "&NJcy;": { "codepoints": [1034], "characters": "\u040A" }, "&Nacute;": { "codepoints": [323], "characters": "\u0143" }, "&Ncaron;": { "codepoints": [327], "characters": "\u0147" }, "&Ncedil;": { "codepoints": [325], "characters": "\u0145" }, "&Ncy;": { "codepoints": [1053], "characters": "\u041D" }, "&NegativeMediumSpace;": { "codepoints": [8203], "characters": "\u200B" }, "&NegativeThickSpace;": { "codepoints": [8203], "characters": "\u200B" }, "&NegativeThinSpace;": { "codepoints": [8203], "characters": "\u200B" }, "&NegativeVeryThinSpace;": { "codepoints": [8203], "characters": "\u200B" }, "&NestedGreaterGreater;": { "codepoints": [8811], "characters": "\u226B" }, "&NestedLessLess;": { "codepoints": [8810], "characters": "\u226A" }, "&NewLine;": { "codepoints": [10], "characters": "\u000A" }, "&Nfr;": { "codepoints": [120081], "characters": "\uD835\uDD11" }, "&NoBreak;": { "codepoints": [8288], "characters": "\u2060" }, "&NonBreakingSpace;": { "codepoints": [160], "characters": "\u00A0" }, "&Nopf;": { "codepoints": [8469], "characters": "\u2115" }, "&Not;": { "codepoints": [10988], "characters": "\u2AEC" }, "&NotCongruent;": { "codepoints": [8802], "characters": "\u2262" }, "&NotCupCap;": { "codepoints": [8813], "characters": "\u226D" }, "&NotDoubleVerticalBar;": { "codepoints": [8742], "characters": "\u2226" }, "&NotElement;": { "codepoints": [8713], "characters": "\u2209" }, "&NotEqual;": { "codepoints": [8800], "characters": "\u2260" }, "&NotEqualTilde;": { "codepoints": [8770, 824], "characters": "\u2242\u0338" }, "&NotExists;": { "codepoints": [8708], "characters": "\u2204" }, "&NotGreater;": { "codepoints": [8815], "characters": "\u226F" }, "&NotGreaterEqual;": { "codepoints": [8817], "characters": "\u2271" }, "&NotGreaterFullEqual;": { "codepoints": [8807, 824], "characters": "\u2267\u0338" }, "&NotGreaterGreater;": { "codepoints": [8811, 824], "characters": "\u226B\u0338" }, "&NotGreaterLess;": { "codepoints": [8825], "characters": "\u2279" }, "&NotGreaterSlantEqual;": { "codepoints": [10878, 824], "characters": "\u2A7E\u0338" }, "&NotGreaterTilde;": { "codepoints": [8821], "characters": "\u2275" }, "&NotHumpDownHump;": { "codepoints": [8782, 824], "characters": "\u224E\u0338" }, "&NotHumpEqual;": { "codepoints": [8783, 824], "characters": "\u224F\u0338" }, "&NotLeftTriangle;": { "codepoints": [8938], "characters": "\u22EA" }, "&NotLeftTriangleBar;": { "codepoints": [10703, 824], "characters": "\u29CF\u0338" }, "&NotLeftTriangleEqual;": { "codepoints": [8940], "characters": "\u22EC" }, "&NotLess;": { "codepoints": [8814], "characters": "\u226E" }, "&NotLessEqual;": { "codepoints": [8816], "characters": "\u2270" }, "&NotLessGreater;": { "codepoints": [8824], "characters": "\u2278" }, "&NotLessLess;": { "codepoints": [8810, 824], "characters": "\u226A\u0338" }, "&NotLessSlantEqual;": { "codepoints": [10877, 824], "characters": "\u2A7D\u0338" }, "&NotLessTilde;": { "codepoints": [8820], "characters": "\u2274" }, "&NotNestedGreaterGreater;": { "codepoints": [10914, 824], "characters": "\u2AA2\u0338" }, "&NotNestedLessLess;": { "codepoints": [10913, 824], "characters": "\u2AA1\u0338" }, "&NotPrecedes;": { "codepoints": [8832], "characters": "\u2280" }, "&NotPrecedesEqual;": { "codepoints": [10927, 824], "characters": "\u2AAF\u0338" }, "&NotPrecedesSlantEqual;": { "codepoints": [8928], "characters": "\u22E0" }, "&NotReverseElement;": { "codepoints": [8716], "characters": "\u220C" }, "&NotRightTriangle;": { "codepoints": [8939], "characters": "\u22EB" }, "&NotRightTriangleBar;": { "codepoints": [10704, 824], "characters": "\u29D0\u0338" }, "&NotRightTriangleEqual;": { "codepoints": [8941], "characters": "\u22ED" }, "&NotSquareSubset;": { "codepoints": [8847, 824], "characters": "\u228F\u0338" }, "&NotSquareSubsetEqual;": { "codepoints": [8930], "characters": "\u22E2" }, "&NotSquareSuperset;": { "codepoints": [8848, 824], "characters": "\u2290\u0338" }, "&NotSquareSupersetEqual;": { "codepoints": [8931], "characters": "\u22E3" }, "&NotSubset;": { "codepoints": [8834, 8402], "characters": "\u2282\u20D2" }, "&NotSubsetEqual;": { "codepoints": [8840], "characters": "\u2288" }, "&NotSucceeds;": { "codepoints": [8833], "characters": "\u2281" }, "&NotSucceedsEqual;": { "codepoints": [10928, 824], "characters": "\u2AB0\u0338" }, "&NotSucceedsSlantEqual;": { "codepoints": [8929], "characters": "\u22E1" }, "&NotSucceedsTilde;": { "codepoints": [8831, 824], "characters": "\u227F\u0338" }, "&NotSuperset;": { "codepoints": [8835, 8402], "characters": "\u2283\u20D2" }, "&NotSupersetEqual;": { "codepoints": [8841], "characters": "\u2289" }, "&NotTilde;": { "codepoints": [8769], "characters": "\u2241" }, "&NotTildeEqual;": { "codepoints": [8772], "characters": "\u2244" }, "&NotTildeFullEqual;": { "codepoints": [8775], "characters": "\u2247" }, "&NotTildeTilde;": { "codepoints": [8777], "characters": "\u2249" }, "&NotVerticalBar;": { "codepoints": [8740], "characters": "\u2224" }, "&Nscr;": { "codepoints": [119977], "characters": "\uD835\uDCA9" }, "&Ntilde": { "codepoints": [209], "characters": "\u00D1" }, "&Ntilde;": { "codepoints": [209], "characters": "\u00D1" }, "&Nu;": { "codepoints": [925], "characters": "\u039D" }, "&OElig;": { "codepoints": [338], "characters": "\u0152" }, "&Oacute": { "codepoints": [211], "characters": "\u00D3" }, "&Oacute;": { "codepoints": [211], "characters": "\u00D3" }, "&Ocirc": { "codepoints": [212], "characters": "\u00D4" }, "&Ocirc;": { "codepoints": [212], "characters": "\u00D4" }, "&Ocy;": { "codepoints": [1054], "characters": "\u041E" }, "&Odblac;": { "codepoints": [336], "characters": "\u0150" }, "&Ofr;": { "codepoints": [120082], "characters": "\uD835\uDD12" }, "&Ograve": { "codepoints": [210], "characters": "\u00D2" }, "&Ograve;": { "codepoints": [210], "characters": "\u00D2" }, "&Omacr;": { "codepoints": [332], "characters": "\u014C" }, "&Omega;": { "codepoints": [937], "characters": "\u03A9" }, "&Omicron;": { "codepoints": [927], "characters": "\u039F" }, "&Oopf;": { "codepoints": [120134], "characters": "\uD835\uDD46" }, "&OpenCurlyDoubleQuote;": { "codepoints": [8220], "characters": "\u201C" }, "&OpenCurlyQuote;": { "codepoints": [8216], "characters": "\u2018" }, "&Or;": { "codepoints": [10836], "characters": "\u2A54" }, "&Oscr;": { "codepoints": [119978], "characters": "\uD835\uDCAA" }, "&Oslash": { "codepoints": [216], "characters": "\u00D8" }, "&Oslash;": { "codepoints": [216], "characters": "\u00D8" }, "&Otilde": { "codepoints": [213], "characters": "\u00D5" }, "&Otilde;": { "codepoints": [213], "characters": "\u00D5" }, "&Otimes;": { "codepoints": [10807], "characters": "\u2A37" }, "&Ouml": { "codepoints": [214], "characters": "\u00D6" }, "&Ouml;": { "codepoints": [214], "characters": "\u00D6" }, "&OverBar;": { "codepoints": [8254], "characters": "\u203E" }, "&OverBrace;": { "codepoints": [9182], "characters": "\u23DE" }, "&OverBracket;": { "codepoints": [9140], "characters": "\u23B4" }, "&OverParenthesis;": { "codepoints": [9180], "characters": "\u23DC" }, "&PartialD;": { "codepoints": [8706], "characters": "\u2202" }, "&Pcy;": { "codepoints": [1055], "characters": "\u041F" }, "&Pfr;": { "codepoints": [120083], "characters": "\uD835\uDD13" }, "&Phi;": { "codepoints": [934], "characters": "\u03A6" }, "&Pi;": { "codepoints": [928], "characters": "\u03A0" }, "&PlusMinus;": { "codepoints": [177], "characters": "\u00B1" }, "&Poincareplane;": { "codepoints": [8460], "characters": "\u210C" }, "&Popf;": { "codepoints": [8473], "characters": "\u2119" }, "&Pr;": { "codepoints": [10939], "characters": "\u2ABB" }, "&Precedes;": { "codepoints": [8826], "characters": "\u227A" }, "&PrecedesEqual;": { "codepoints": [10927], "characters": "\u2AAF" }, "&PrecedesSlantEqual;": { "codepoints": [8828], "characters": "\u227C" }, "&PrecedesTilde;": { "codepoints": [8830], "characters": "\u227E" }, "&Prime;": { "codepoints": [8243], "characters": "\u2033" }, "&Product;": { "codepoints": [8719], "characters": "\u220F" }, "&Proportion;": { "codepoints": [8759], "characters": "\u2237" }, "&Proportional;": { "codepoints": [8733], "characters": "\u221D" }, "&Pscr;": { "codepoints": [119979], "characters": "\uD835\uDCAB" }, "&Psi;": { "codepoints": [936], "characters": "\u03A8" }, "&QUOT": { "codepoints": [34], "characters": "\u0022" }, "&QUOT;": { "codepoints": [34], "characters": "\u0022" }, "&Qfr;": { "codepoints": [120084], "characters": "\uD835\uDD14" }, "&Qopf;": { "codepoints": [8474], "characters": "\u211A" }, "&Qscr;": { "codepoints": [119980], "characters": "\uD835\uDCAC" }, "&RBarr;": { "codepoints": [10512], "characters": "\u2910" }, "&REG": { "codepoints": [174], "characters": "\u00AE" }, "&REG;": { "codepoints": [174], "characters": "\u00AE" }, "&Racute;": { "codepoints": [340], "characters": "\u0154" }, "&Rang;": { "codepoints": [10219], "characters": "\u27EB" }, "&Rarr;": { "codepoints": [8608], "characters": "\u21A0" }, "&Rarrtl;": { "codepoints": [10518], "characters": "\u2916" }, "&Rcaron;": { "codepoints": [344], "characters": "\u0158" }, "&Rcedil;": { "codepoints": [342], "characters": "\u0156" }, "&Rcy;": { "codepoints": [1056], "characters": "\u0420" }, "&Re;": { "codepoints": [8476], "characters": "\u211C" }, "&ReverseElement;": { "codepoints": [8715], "characters": "\u220B" }, "&ReverseEquilibrium;": { "codepoints": [8651], "characters": "\u21CB" }, "&ReverseUpEquilibrium;": { "codepoints": [10607], "characters": "\u296F" }, "&Rfr;": { "codepoints": [8476], "characters": "\u211C" }, "&Rho;": { "codepoints": [929], "characters": "\u03A1" }, "&RightAngleBracket;": { "codepoints": [10217], "characters": "\u27E9" }, "&RightArrow;": { "codepoints": [8594], "characters": "\u2192" }, "&RightArrowBar;": { "codepoints": [8677], "characters": "\u21E5" }, "&RightArrowLeftArrow;": { "codepoints": [8644], "characters": "\u21C4" }, "&RightCeiling;": { "codepoints": [8969], "characters": "\u2309" }, "&RightDoubleBracket;": { "codepoints": [10215], "characters": "\u27E7" }, "&RightDownTeeVector;": { "codepoints": [10589], "characters": "\u295D" }, "&RightDownVector;": { "codepoints": [8642], "characters": "\u21C2" }, "&RightDownVectorBar;": { "codepoints": [10581], "characters": "\u2955" }, "&RightFloor;": { "codepoints": [8971], "characters": "\u230B" }, "&RightTee;": { "codepoints": [8866], "characters": "\u22A2" }, "&RightTeeArrow;": { "codepoints": [8614], "characters": "\u21A6" }, "&RightTeeVector;": { "codepoints": [10587], "characters": "\u295B" }, "&RightTriangle;": { "codepoints": [8883], "characters": "\u22B3" }, "&RightTriangleBar;": { "codepoints": [10704], "characters": "\u29D0" }, "&RightTriangleEqual;": { "codepoints": [8885], "characters": "\u22B5" }, "&RightUpDownVector;": { "codepoints": [10575], "characters": "\u294F" }, "&RightUpTeeVector;": { "codepoints": [10588], "characters": "\u295C" }, "&RightUpVector;": { "codepoints": [8638], "characters": "\u21BE" }, "&RightUpVectorBar;": { "codepoints": [10580], "characters": "\u2954" }, "&RightVector;": { "codepoints": [8640], "characters": "\u21C0" }, "&RightVectorBar;": { "codepoints": [10579], "characters": "\u2953" }, "&Rightarrow;": { "codepoints": [8658], "characters": "\u21D2" }, "&Ropf;": { "codepoints": [8477], "characters": "\u211D" }, "&RoundImplies;": { "codepoints": [10608], "characters": "\u2970" }, "&Rrightarrow;": { "codepoints": [8667], "characters": "\u21DB" }, "&Rscr;": { "codepoints": [8475], "characters": "\u211B" }, "&Rsh;": { "codepoints": [8625], "characters": "\u21B1" }, "&RuleDelayed;": { "codepoints": [10740], "characters": "\u29F4" }, "&SHCHcy;": { "codepoints": [1065], "characters": "\u0429" }, "&SHcy;": { "codepoints": [1064], "characters": "\u0428" }, "&SOFTcy;": { "codepoints": [1068], "characters": "\u042C" }, "&Sacute;": { "codepoints": [346], "characters": "\u015A" }, "&Sc;": { "codepoints": [10940], "characters": "\u2ABC" }, "&Scaron;": { "codepoints": [352], "characters": "\u0160" }, "&Scedil;": { "codepoints": [350], "characters": "\u015E" }, "&Scirc;": { "codepoints": [348], "characters": "\u015C" }, "&Scy;": { "codepoints": [1057], "characters": "\u0421" }, "&Sfr;": { "codepoints": [120086], "characters": "\uD835\uDD16" }, "&ShortDownArrow;": { "codepoints": [8595], "characters": "\u2193" }, "&ShortLeftArrow;": { "codepoints": [8592], "characters": "\u2190" }, "&ShortRightArrow;": { "codepoints": [8594], "characters": "\u2192" }, "&ShortUpArrow;": { "codepoints": [8593], "characters": "\u2191" }, "&Sigma;": { "codepoints": [931], "characters": "\u03A3" }, "&SmallCircle;": { "codepoints": [8728], "characters": "\u2218" }, "&Sopf;": { "codepoints": [120138], "characters": "\uD835\uDD4A" }, "&Sqrt;": { "codepoints": [8730], "characters": "\u221A" }, "&Square;": { "codepoints": [9633], "characters": "\u25A1" }, "&SquareIntersection;": { "codepoints": [8851], "characters": "\u2293" }, "&SquareSubset;": { "codepoints": [8847], "characters": "\u228F" }, "&SquareSubsetEqual;": { "codepoints": [8849], "characters": "\u2291" }, "&SquareSuperset;": { "codepoints": [8848], "characters": "\u2290" }, "&SquareSupersetEqual;": { "codepoints": [8850], "characters": "\u2292" }, "&SquareUnion;": { "codepoints": [8852], "characters": "\u2294" }, "&Sscr;": { "codepoints": [119982], "characters": "\uD835\uDCAE" }, "&Star;": { "codepoints": [8902], "characters": "\u22C6" }, "&Sub;": { "codepoints": [8912], "characters": "\u22D0" }, "&Subset;": { "codepoints": [8912], "characters": "\u22D0" }, "&SubsetEqual;": { "codepoints": [8838], "characters": "\u2286" }, "&Succeeds;": { "codepoints": [8827], "characters": "\u227B" }, "&SucceedsEqual;": { "codepoints": [10928], "characters": "\u2AB0" }, "&SucceedsSlantEqual;": { "codepoints": [8829], "characters": "\u227D" }, "&SucceedsTilde;": { "codepoints": [8831], "characters": "\u227F" }, "&SuchThat;": { "codepoints": [8715], "characters": "\u220B" }, "&Sum;": { "codepoints": [8721], "characters": "\u2211" }, "&Sup;": { "codepoints": [8913], "characters": "\u22D1" }, "&Superset;": { "codepoints": [8835], "characters": "\u2283" }, "&SupersetEqual;": { "codepoints": [8839], "characters": "\u2287" }, "&Supset;": { "codepoints": [8913], "characters": "\u22D1" }, "&THORN": { "codepoints": [222], "characters": "\u00DE" }, "&THORN;": { "codepoints": [222], "characters": "\u00DE" }, "&TRADE;": { "codepoints": [8482], "characters": "\u2122" }, "&TSHcy;": { "codepoints": [1035], "characters": "\u040B" }, "&TScy;": { "codepoints": [1062], "characters": "\u0426" }, "&Tab;": { "codepoints": [9], "characters": "\u0009" }, "&Tau;": { "codepoints": [932], "characters": "\u03A4" }, "&Tcaron;": { "codepoints": [356], "characters": "\u0164" }, "&Tcedil;": { "codepoints": [354], "characters": "\u0162" }, "&Tcy;": { "codepoints": [1058], "characters": "\u0422" }, "&Tfr;": { "codepoints": [120087], "characters": "\uD835\uDD17" }, "&Therefore;": { "codepoints": [8756], "characters": "\u2234" }, "&Theta;": { "codepoints": [920], "characters": "\u0398" }, "&ThickSpace;": { "codepoints": [8287, 8202], "characters": "\u205F\u200A" }, "&ThinSpace;": { "codepoints": [8201], "characters": "\u2009" }, "&Tilde;": { "codepoints": [8764], "characters": "\u223C" }, "&TildeEqual;": { "codepoints": [8771], "characters": "\u2243" }, "&TildeFullEqual;": { "codepoints": [8773], "characters": "\u2245" }, "&TildeTilde;": { "codepoints": [8776], "characters": "\u2248" }, "&Topf;": { "codepoints": [120139], "characters": "\uD835\uDD4B" }, "&TripleDot;": { "codepoints": [8411], "characters": "\u20DB" }, "&Tscr;": { "codepoints": [119983], "characters": "\uD835\uDCAF" }, "&Tstrok;": { "codepoints": [358], "characters": "\u0166" }, "&Uacute": { "codepoints": [218], "characters": "\u00DA" }, "&Uacute;": { "codepoints": [218], "characters": "\u00DA" }, "&Uarr;": { "codepoints": [8607], "characters": "\u219F" }, "&Uarrocir;": { "codepoints": [10569], "characters": "\u2949" }, "&Ubrcy;": { "codepoints": [1038], "characters": "\u040E" }, "&Ubreve;": { "codepoints": [364], "characters": "\u016C" }, "&Ucirc": { "codepoints": [219], "characters": "\u00DB" }, "&Ucirc;": { "codepoints": [219], "characters": "\u00DB" }, "&Ucy;": { "codepoints": [1059], "characters": "\u0423" }, "&Udblac;": { "codepoints": [368], "characters": "\u0170" }, "&Ufr;": { "codepoints": [120088], "characters": "\uD835\uDD18" }, "&Ugrave": { "codepoints": [217], "characters": "\u00D9" }, "&Ugrave;": { "codepoints": [217], "characters": "\u00D9" }, "&Umacr;": { "codepoints": [362], "characters": "\u016A" }, "&UnderBar;": { "codepoints": [95], "characters": "\u005F" }, "&UnderBrace;": { "codepoints": [9183], "characters": "\u23DF" }, "&UnderBracket;": { "codepoints": [9141], "characters": "\u23B5" }, "&UnderParenthesis;": { "codepoints": [9181], "characters": "\u23DD" }, "&Union;": { "codepoints": [8899], "characters": "\u22C3" }, "&UnionPlus;": { "codepoints": [8846], "characters": "\u228E" }, "&Uogon;": { "codepoints": [370], "characters": "\u0172" }, "&Uopf;": { "codepoints": [120140], "characters": "\uD835\uDD4C" }, "&UpArrow;": { "codepoints": [8593], "characters": "\u2191" }, "&UpArrowBar;": { "codepoints": [10514], "characters": "\u2912" }, "&UpArrowDownArrow;": { "codepoints": [8645], "characters": "\u21C5" }, "&UpDownArrow;": { "codepoints": [8597], "characters": "\u2195" }, "&UpEquilibrium;": { "codepoints": [10606], "characters": "\u296E" }, "&UpTee;": { "codepoints": [8869], "characters": "\u22A5" }, "&UpTeeArrow;": { "codepoints": [8613], "characters": "\u21A5" }, "&Uparrow;": { "codepoints": [8657], "characters": "\u21D1" }, "&Updownarrow;": { "codepoints": [8661], "characters": "\u21D5" }, "&UpperLeftArrow;": { "codepoints": [8598], "characters": "\u2196" }, "&UpperRightArrow;": { "codepoints": [8599], "characters": "\u2197" }, "&Upsi;": { "codepoints": [978], "characters": "\u03D2" }, "&Upsilon;": { "codepoints": [933], "characters": "\u03A5" }, "&Uring;": { "codepoints": [366], "characters": "\u016E" }, "&Uscr;": { "codepoints": [119984], "characters": "\uD835\uDCB0" }, "&Utilde;": { "codepoints": [360], "characters": "\u0168" }, "&Uuml": { "codepoints": [220], "characters": "\u00DC" }, "&Uuml;": { "codepoints": [220], "characters": "\u00DC" }, "&VDash;": { "codepoints": [8875], "characters": "\u22AB" }, "&Vbar;": { "codepoints": [10987], "characters": "\u2AEB" }, "&Vcy;": { "codepoints": [1042], "characters": "\u0412" }, "&Vdash;": { "codepoints": [8873], "characters": "\u22A9" }, "&Vdashl;": { "codepoints": [10982], "characters": "\u2AE6" }, "&Vee;": { "codepoints": [8897], "characters": "\u22C1" }, "&Verbar;": { "codepoints": [8214], "characters": "\u2016" }, "&Vert;": { "codepoints": [8214], "characters": "\u2016" }, "&VerticalBar;": { "codepoints": [8739], "characters": "\u2223" }, "&VerticalLine;": { "codepoints": [124], "characters": "\u007C" }, "&VerticalSeparator;": { "codepoints": [10072], "characters": "\u2758" }, "&VerticalTilde;": { "codepoints": [8768], "characters": "\u2240" }, "&VeryThinSpace;": { "codepoints": [8202], "characters": "\u200A" }, "&Vfr;": { "codepoints": [120089], "characters": "\uD835\uDD19" }, "&Vopf;": { "codepoints": [120141], "characters": "\uD835\uDD4D" }, "&Vscr;": { "codepoints": [119985], "characters": "\uD835\uDCB1" }, "&Vvdash;": { "codepoints": [8874], "characters": "\u22AA" }, "&Wcirc;": { "codepoints": [372], "characters": "\u0174" }, "&Wedge;": { "codepoints": [8896], "characters": "\u22C0" }, "&Wfr;": { "codepoints": [120090], "characters": "\uD835\uDD1A" }, "&Wopf;": { "codepoints": [120142], "characters": "\uD835\uDD4E" }, "&Wscr;": { "codepoints": [119986], "characters": "\uD835\uDCB2" }, "&Xfr;": { "codepoints": [120091], "characters": "\uD835\uDD1B" }, "&Xi;": { "codepoints": [926], "characters": "\u039E" }, "&Xopf;": { "codepoints": [120143], "characters": "\uD835\uDD4F" }, "&Xscr;": { "codepoints": [119987], "characters": "\uD835\uDCB3" }, "&YAcy;": { "codepoints": [1071], "characters": "\u042F" }, "&YIcy;": { "codepoints": [1031], "characters": "\u0407" }, "&YUcy;": { "codepoints": [1070], "characters": "\u042E" }, "&Yacute": { "codepoints": [221], "characters": "\u00DD" }, "&Yacute;": { "codepoints": [221], "characters": "\u00DD" }, "&Ycirc;": { "codepoints": [374], "characters": "\u0176" }, "&Ycy;": { "codepoints": [1067], "characters": "\u042B" }, "&Yfr;": { "codepoints": [120092], "characters": "\uD835\uDD1C" }, "&Yopf;": { "codepoints": [120144], "characters": "\uD835\uDD50" }, "&Yscr;": { "codepoints": [119988], "characters": "\uD835\uDCB4" }, "&Yuml;": { "codepoints": [376], "characters": "\u0178" }, "&ZHcy;": { "codepoints": [1046], "characters": "\u0416" }, "&Zacute;": { "codepoints": [377], "characters": "\u0179" }, "&Zcaron;": { "codepoints": [381], "characters": "\u017D" }, "&Zcy;": { "codepoints": [1047], "characters": "\u0417" }, "&Zdot;": { "codepoints": [379], "characters": "\u017B" }, "&ZeroWidthSpace;": { "codepoints": [8203], "characters": "\u200B" }, "&Zeta;": { "codepoints": [918], "characters": "\u0396" }, "&Zfr;": { "codepoints": [8488], "characters": "\u2128" }, "&Zopf;": { "codepoints": [8484], "characters": "\u2124" }, "&Zscr;": { "codepoints": [119989], "characters": "\uD835\uDCB5" }, "&aacute": { "codepoints": [225], "characters": "\u00E1" }, "&aacute;": { "codepoints": [225], "characters": "\u00E1" }, "&abreve;": { "codepoints": [259], "characters": "\u0103" }, "&ac;": { "codepoints": [8766], "characters": "\u223E" }, "&acE;": { "codepoints": [8766, 819], "characters": "\u223E\u0333" }, "&acd;": { "codepoints": [8767], "characters": "\u223F" }, "&acirc": { "codepoints": [226], "characters": "\u00E2" }, "&acirc;": { "codepoints": [226], "characters": "\u00E2" }, "&acute": { "codepoints": [180], "characters": "\u00B4" }, "&acute;": { "codepoints": [180], "characters": "\u00B4" }, "&acy;": { "codepoints": [1072], "characters": "\u0430" }, "&aelig": { "codepoints": [230], "characters": "\u00E6" }, "&aelig;": { "codepoints": [230], "characters": "\u00E6" }, "&af;": { "codepoints": [8289], "characters": "\u2061" }, "&afr;": { "codepoints": [120094], "characters": "\uD835\uDD1E" }, "&agrave": { "codepoints": [224], "characters": "\u00E0" }, "&agrave;": { "codepoints": [224], "characters": "\u00E0" }, "&alefsym;": { "codepoints": [8501], "characters": "\u2135" }, "&aleph;": { "codepoints": [8501], "characters": "\u2135" }, "&alpha;": { "codepoints": [945], "characters": "\u03B1" }, "&amacr;": { "codepoints": [257], "characters": "\u0101" }, "&amalg;": { "codepoints": [10815], "characters": "\u2A3F" }, "&amp": { "codepoints": [38], "characters": "\u0026" }, "&amp;": { "codepoints": [38], "characters": "\u0026" }, "&and;": { "codepoints": [8743], "characters": "\u2227" }, "&andand;": { "codepoints": [10837], "characters": "\u2A55" }, "&andd;": { "codepoints": [10844], "characters": "\u2A5C" }, "&andslope;": { "codepoints": [10840], "characters": "\u2A58" }, "&andv;": { "codepoints": [10842], "characters": "\u2A5A" }, "&ang;": { "codepoints": [8736], "characters": "\u2220" }, "&ange;": { "codepoints": [10660], "characters": "\u29A4" }, "&angle;": { "codepoints": [8736], "characters": "\u2220" }, "&angmsd;": { "codepoints": [8737], "characters": "\u2221" }, "&angmsdaa;": { "codepoints": [10664], "characters": "\u29A8" }, "&angmsdab;": { "codepoints": [10665], "characters": "\u29A9" }, "&angmsdac;": { "codepoints": [10666], "characters": "\u29AA" }, "&angmsdad;": { "codepoints": [10667], "characters": "\u29AB" }, "&angmsdae;": { "codepoints": [10668], "characters": "\u29AC" }, "&angmsdaf;": { "codepoints": [10669], "characters": "\u29AD" }, "&angmsdag;": { "codepoints": [10670], "characters": "\u29AE" }, "&angmsdah;": { "codepoints": [10671], "characters": "\u29AF" }, "&angrt;": { "codepoints": [8735], "characters": "\u221F" }, "&angrtvb;": { "codepoints": [8894], "characters": "\u22BE" }, "&angrtvbd;": { "codepoints": [10653], "characters": "\u299D" }, "&angsph;": { "codepoints": [8738], "characters": "\u2222" }, "&angst;": { "codepoints": [197], "characters": "\u00C5" }, "&angzarr;": { "codepoints": [9084], "characters": "\u237C" }, "&aogon;": { "codepoints": [261], "characters": "\u0105" }, "&aopf;": { "codepoints": [120146], "characters": "\uD835\uDD52" }, "&ap;": { "codepoints": [8776], "characters": "\u2248" }, "&apE;": { "codepoints": [10864], "characters": "\u2A70" }, "&apacir;": { "codepoints": [10863], "characters": "\u2A6F" }, "&ape;": { "codepoints": [8778], "characters": "\u224A" }, "&apid;": { "codepoints": [8779], "characters": "\u224B" }, "&apos;": { "codepoints": [39], "characters": "\u0027" }, "&approx;": { "codepoints": [8776], "characters": "\u2248" }, "&approxeq;": { "codepoints": [8778], "characters": "\u224A" }, "&aring": { "codepoints": [229], "characters": "\u00E5" }, "&aring;": { "codepoints": [229], "characters": "\u00E5" }, "&ascr;": { "codepoints": [119990], "characters": "\uD835\uDCB6" }, "&ast;": { "codepoints": [42], "characters": "\u002A" }, "&asymp;": { "codepoints": [8776], "characters": "\u2248" }, "&asympeq;": { "codepoints": [8781], "characters": "\u224D" }, "&atilde": { "codepoints": [227], "characters": "\u00E3" }, "&atilde;": { "codepoints": [227], "characters": "\u00E3" }, "&auml": { "codepoints": [228], "characters": "\u00E4" }, "&auml;": { "codepoints": [228], "characters": "\u00E4" }, "&awconint;": { "codepoints": [8755], "characters": "\u2233" }, "&awint;": { "codepoints": [10769], "characters": "\u2A11" }, "&bNot;": { "codepoints": [10989], "characters": "\u2AED" }, "&backcong;": { "codepoints": [8780], "characters": "\u224C" }, "&backepsilon;": { "codepoints": [1014], "characters": "\u03F6" }, "&backprime;": { "codepoints": [8245], "characters": "\u2035" }, "&backsim;": { "codepoints": [8765], "characters": "\u223D" }, "&backsimeq;": { "codepoints": [8909], "characters": "\u22CD" }, "&barvee;": { "codepoints": [8893], "characters": "\u22BD" }, "&barwed;": { "codepoints": [8965], "characters": "\u2305" }, "&barwedge;": { "codepoints": [8965], "characters": "\u2305" }, "&bbrk;": { "codepoints": [9141], "characters": "\u23B5" }, "&bbrktbrk;": { "codepoints": [9142], "characters": "\u23B6" }, "&bcong;": { "codepoints": [8780], "characters": "\u224C" }, "&bcy;": { "codepoints": [1073], "characters": "\u0431" }, "&bdquo;": { "codepoints": [8222], "characters": "\u201E" }, "&becaus;": { "codepoints": [8757], "characters": "\u2235" }, "&because;": { "codepoints": [8757], "characters": "\u2235" }, "&bemptyv;": { "codepoints": [10672], "characters": "\u29B0" }, "&bepsi;": { "codepoints": [1014], "characters": "\u03F6" }, "&bernou;": { "codepoints": [8492], "characters": "\u212C" }, "&beta;": { "codepoints": [946], "characters": "\u03B2" }, "&beth;": { "codepoints": [8502], "characters": "\u2136" }, "&between;": { "codepoints": [8812], "characters": "\u226C" }, "&bfr;": { "codepoints": [120095], "characters": "\uD835\uDD1F" }, "&bigcap;": { "codepoints": [8898], "characters": "\u22C2" }, "&bigcirc;": { "codepoints": [9711], "characters": "\u25EF" }, "&bigcup;": { "codepoints": [8899], "characters": "\u22C3" }, "&bigodot;": { "codepoints": [10752], "characters": "\u2A00" }, "&bigoplus;": { "codepoints": [10753], "characters": "\u2A01" }, "&bigotimes;": { "codepoints": [10754], "characters": "\u2A02" }, "&bigsqcup;": { "codepoints": [10758], "characters": "\u2A06" }, "&bigstar;": { "codepoints": [9733], "characters": "\u2605" }, "&bigtriangledown;": { "codepoints": [9661], "characters": "\u25BD" }, "&bigtriangleup;": { "codepoints": [9651], "characters": "\u25B3" }, "&biguplus;": { "codepoints": [10756], "characters": "\u2A04" }, "&bigvee;": { "codepoints": [8897], "characters": "\u22C1" }, "&bigwedge;": { "codepoints": [8896], "characters": "\u22C0" }, "&bkarow;": { "codepoints": [10509], "characters": "\u290D" }, "&blacklozenge;": { "codepoints": [10731], "characters": "\u29EB" }, "&blacksquare;": { "codepoints": [9642], "characters": "\u25AA" }, "&blacktriangle;": { "codepoints": [9652], "characters": "\u25B4" }, "&blacktriangledown;": { "codepoints": [9662], "characters": "\u25BE" }, "&blacktriangleleft;": { "codepoints": [9666], "characters": "\u25C2" }, "&blacktriangleright;": { "codepoints": [9656], "characters": "\u25B8" }, "&blank;": { "codepoints": [9251], "characters": "\u2423" }, "&blk12;": { "codepoints": [9618], "characters": "\u2592" }, "&blk14;": { "codepoints": [9617], "characters": "\u2591" }, "&blk34;": { "codepoints": [9619], "characters": "\u2593" }, "&block;": { "codepoints": [9608], "characters": "\u2588" }, "&bne;": { "codepoints": [61, 8421], "characters": "\u003D\u20E5" }, "&bnequiv;": { "codepoints": [8801, 8421], "characters": "\u2261\u20E5" }, "&bnot;": { "codepoints": [8976], "characters": "\u2310" }, "&bopf;": { "codepoints": [120147], "characters": "\uD835\uDD53" }, "&bot;": { "codepoints": [8869], "characters": "\u22A5" }, "&bottom;": { "codepoints": [8869], "characters": "\u22A5" }, "&bowtie;": { "codepoints": [8904], "characters": "\u22C8" }, "&boxDL;": { "codepoints": [9559], "characters": "\u2557" }, "&boxDR;": { "codepoints": [9556], "characters": "\u2554" }, "&boxDl;": { "codepoints": [9558], "characters": "\u2556" }, "&boxDr;": { "codepoints": [9555], "characters": "\u2553" }, "&boxH;": { "codepoints": [9552], "characters": "\u2550" }, "&boxHD;": { "codepoints": [9574], "characters": "\u2566" }, "&boxHU;": { "codepoints": [9577], "characters": "\u2569" }, "&boxHd;": { "codepoints": [9572], "characters": "\u2564" }, "&boxHu;": { "codepoints": [9575], "characters": "\u2567" }, "&boxUL;": { "codepoints": [9565], "characters": "\u255D" }, "&boxUR;": { "codepoints": [9562], "characters": "\u255A" }, "&boxUl;": { "codepoints": [9564], "characters": "\u255C" }, "&boxUr;": { "codepoints": [9561], "characters": "\u2559" }, "&boxV;": { "codepoints": [9553], "characters": "\u2551" }, "&boxVH;": { "codepoints": [9580], "characters": "\u256C" }, "&boxVL;": { "codepoints": [9571], "characters": "\u2563" }, "&boxVR;": { "codepoints": [9568], "characters": "\u2560" }, "&boxVh;": { "codepoints": [9579], "characters": "\u256B" }, "&boxVl;": { "codepoints": [9570], "characters": "\u2562" }, "&boxVr;": { "codepoints": [9567], "characters": "\u255F" }, "&boxbox;": { "codepoints": [10697], "characters": "\u29C9" }, "&boxdL;": { "codepoints": [9557], "characters": "\u2555" }, "&boxdR;": { "codepoints": [9554], "characters": "\u2552" }, "&boxdl;": { "codepoints": [9488], "characters": "\u2510" }, "&boxdr;": { "codepoints": [9484], "characters": "\u250C" }, "&boxh;": { "codepoints": [9472], "characters": "\u2500" }, "&boxhD;": { "codepoints": [9573], "characters": "\u2565" }, "&boxhU;": { "codepoints": [9576], "characters": "\u2568" }, "&boxhd;": { "codepoints": [9516], "characters": "\u252C" }, "&boxhu;": { "codepoints": [9524], "characters": "\u2534" }, "&boxminus;": { "codepoints": [8863], "characters": "\u229F" }, "&boxplus;": { "codepoints": [8862], "characters": "\u229E" }, "&boxtimes;": { "codepoints": [8864], "characters": "\u22A0" }, "&boxuL;": { "codepoints": [9563], "characters": "\u255B" }, "&boxuR;": { "codepoints": [9560], "characters": "\u2558" }, "&boxul;": { "codepoints": [9496], "characters": "\u2518" }, "&boxur;": { "codepoints": [9492], "characters": "\u2514" }, "&boxv;": { "codepoints": [9474], "characters": "\u2502" }, "&boxvH;": { "codepoints": [9578], "characters": "\u256A" }, "&boxvL;": { "codepoints": [9569], "characters": "\u2561" }, "&boxvR;": { "codepoints": [9566], "characters": "\u255E" }, "&boxvh;": { "codepoints": [9532], "characters": "\u253C" }, "&boxvl;": { "codepoints": [9508], "characters": "\u2524" }, "&boxvr;": { "codepoints": [9500], "characters": "\u251C" }, "&bprime;": { "codepoints": [8245], "characters": "\u2035" }, "&breve;": { "codepoints": [728], "characters": "\u02D8" }, "&brvbar": { "codepoints": [166], "characters": "\u00A6" }, "&brvbar;": { "codepoints": [166], "characters": "\u00A6" }, "&bscr;": { "codepoints": [119991], "characters": "\uD835\uDCB7" }, "&bsemi;": { "codepoints": [8271], "characters": "\u204F" }, "&bsim;": { "codepoints": [8765], "characters": "\u223D" }, "&bsime;": { "codepoints": [8909], "characters": "\u22CD" }, "&bsol;": { "codepoints": [92], "characters": "\u005C" }, "&bsolb;": { "codepoints": [10693], "characters": "\u29C5" }, "&bsolhsub;": { "codepoints": [10184], "characters": "\u27C8" }, "&bull;": { "codepoints": [8226], "characters": "\u2022" }, "&bullet;": { "codepoints": [8226], "characters": "\u2022" }, "&bump;": { "codepoints": [8782], "characters": "\u224E" }, "&bumpE;": { "codepoints": [10926], "characters": "\u2AAE" }, "&bumpe;": { "codepoints": [8783], "characters": "\u224F" }, "&bumpeq;": { "codepoints": [8783], "characters": "\u224F" }, "&cacute;": { "codepoints": [263], "characters": "\u0107" }, "&cap;": { "codepoints": [8745], "characters": "\u2229" }, "&capand;": { "codepoints": [10820], "characters": "\u2A44" }, "&capbrcup;": { "codepoints": [10825], "characters": "\u2A49" }, "&capcap;": { "codepoints": [10827], "characters": "\u2A4B" }, "&capcup;": { "codepoints": [10823], "characters": "\u2A47" }, "&capdot;": { "codepoints": [10816], "characters": "\u2A40" }, "&caps;": { "codepoints": [8745, 65024], "characters": "\u2229\uFE00" }, "&caret;": { "codepoints": [8257], "characters": "\u2041" }, "&caron;": { "codepoints": [711], "characters": "\u02C7" }, "&ccaps;": { "codepoints": [10829], "characters": "\u2A4D" }, "&ccaron;": { "codepoints": [269], "characters": "\u010D" }, "&ccedil": { "codepoints": [231], "characters": "\u00E7" }, "&ccedil;": { "codepoints": [231], "characters": "\u00E7" }, "&ccirc;": { "codepoints": [265], "characters": "\u0109" }, "&ccups;": { "codepoints": [10828], "characters": "\u2A4C" }, "&ccupssm;": { "codepoints": [10832], "characters": "\u2A50" }, "&cdot;": { "codepoints": [267], "characters": "\u010B" }, "&cedil": { "codepoints": [184], "characters": "\u00B8" }, "&cedil;": { "codepoints": [184], "characters": "\u00B8" }, "&cemptyv;": { "codepoints": [10674], "characters": "\u29B2" }, "&cent": { "codepoints": [162], "characters": "\u00A2" }, "&cent;": { "codepoints": [162], "characters": "\u00A2" }, "&centerdot;": { "codepoints": [183], "characters": "\u00B7" }, "&cfr;": { "codepoints": [120096], "characters": "\uD835\uDD20" }, "&chcy;": { "codepoints": [1095], "characters": "\u0447" }, "&check;": { "codepoints": [10003], "characters": "\u2713" }, "&checkmark;": { "codepoints": [10003], "characters": "\u2713" }, "&chi;": { "codepoints": [967], "characters": "\u03C7" }, "&cir;": { "codepoints": [9675], "characters": "\u25CB" }, "&cirE;": { "codepoints": [10691], "characters": "\u29C3" }, "&circ;": { "codepoints": [710], "characters": "\u02C6" }, "&circeq;": { "codepoints": [8791], "characters": "\u2257" }, "&circlearrowleft;": { "codepoints": [8634], "characters": "\u21BA" }, "&circlearrowright;": { "codepoints": [8635], "characters": "\u21BB" }, "&circledR;": { "codepoints": [174], "characters": "\u00AE" }, "&circledS;": { "codepoints": [9416], "characters": "\u24C8" }, "&circledast;": { "codepoints": [8859], "characters": "\u229B" }, "&circledcirc;": { "codepoints": [8858], "characters": "\u229A" }, "&circleddash;": { "codepoints": [8861], "characters": "\u229D" }, "&cire;": { "codepoints": [8791], "characters": "\u2257" }, "&cirfnint;": { "codepoints": [10768], "characters": "\u2A10" }, "&cirmid;": { "codepoints": [10991], "characters": "\u2AEF" }, "&cirscir;": { "codepoints": [10690], "characters": "\u29C2" }, "&clubs;": { "codepoints": [9827], "characters": "\u2663" }, "&clubsuit;": { "codepoints": [9827], "characters": "\u2663" }, "&colon;": { "codepoints": [58], "characters": "\u003A" }, "&colone;": { "codepoints": [8788], "characters": "\u2254" }, "&coloneq;": { "codepoints": [8788], "characters": "\u2254" }, "&comma;": { "codepoints": [44], "characters": "\u002C" }, "&commat;": { "codepoints": [64], "characters": "\u0040" }, "&comp;": { "codepoints": [8705], "characters": "\u2201" }, "&compfn;": { "codepoints": [8728], "characters": "\u2218" }, "&complement;": { "codepoints": [8705], "characters": "\u2201" }, "&complexes;": { "codepoints": [8450], "characters": "\u2102" }, "&cong;": { "codepoints": [8773], "characters": "\u2245" }, "&congdot;": { "codepoints": [10861], "characters": "\u2A6D" }, "&conint;": { "codepoints": [8750], "characters": "\u222E" }, "&copf;": { "codepoints": [120148], "characters": "\uD835\uDD54" }, "&coprod;": { "codepoints": [8720], "characters": "\u2210" }, "&copy": { "codepoints": [169], "characters": "\u00A9" }, "&copy;": { "codepoints": [169], "characters": "\u00A9" }, "&copysr;": { "codepoints": [8471], "characters": "\u2117" }, "&crarr;": { "codepoints": [8629], "characters": "\u21B5" }, "&cross;": { "codepoints": [10007], "characters": "\u2717" }, "&cscr;": { "codepoints": [119992], "characters": "\uD835\uDCB8" }, "&csub;": { "codepoints": [10959], "characters": "\u2ACF" }, "&csube;": { "codepoints": [10961], "characters": "\u2AD1" }, "&csup;": { "codepoints": [10960], "characters": "\u2AD0" }, "&csupe;": { "codepoints": [10962], "characters": "\u2AD2" }, "&ctdot;": { "codepoints": [8943], "characters": "\u22EF" }, "&cudarrl;": { "codepoints": [10552], "characters": "\u2938" }, "&cudarrr;": { "codepoints": [10549], "characters": "\u2935" }, "&cuepr;": { "codepoints": [8926], "characters": "\u22DE" }, "&cuesc;": { "codepoints": [8927], "characters": "\u22DF" }, "&cularr;": { "codepoints": [8630], "characters": "\u21B6" }, "&cularrp;": { "codepoints": [10557], "characters": "\u293D" }, "&cup;": { "codepoints": [8746], "characters": "\u222A" }, "&cupbrcap;": { "codepoints": [10824], "characters": "\u2A48" }, "&cupcap;": { "codepoints": [10822], "characters": "\u2A46" }, "&cupcup;": { "codepoints": [10826], "characters": "\u2A4A" }, "&cupdot;": { "codepoints": [8845], "characters": "\u228D" }, "&cupor;": { "codepoints": [10821], "characters": "\u2A45" }, "&cups;": { "codepoints": [8746, 65024], "characters": "\u222A\uFE00" }, "&curarr;": { "codepoints": [8631], "characters": "\u21B7" }, "&curarrm;": { "codepoints": [10556], "characters": "\u293C" }, "&curlyeqprec;": { "codepoints": [8926], "characters": "\u22DE" }, "&curlyeqsucc;": { "codepoints": [8927], "characters": "\u22DF" }, "&curlyvee;": { "codepoints": [8910], "characters": "\u22CE" }, "&curlywedge;": { "codepoints": [8911], "characters": "\u22CF" }, "&curren": { "codepoints": [164], "characters": "\u00A4" }, "&curren;": { "codepoints": [164], "characters": "\u00A4" }, "&curvearrowleft;": { "codepoints": [8630], "characters": "\u21B6" }, "&curvearrowright;": { "codepoints": [8631], "characters": "\u21B7" }, "&cuvee;": { "codepoints": [8910], "characters": "\u22CE" }, "&cuwed;": { "codepoints": [8911], "characters": "\u22CF" }, "&cwconint;": { "codepoints": [8754], "characters": "\u2232" }, "&cwint;": { "codepoints": [8753], "characters": "\u2231" }, "&cylcty;": { "codepoints": [9005], "characters": "\u232D" }, "&dArr;": { "codepoints": [8659], "characters": "\u21D3" }, "&dHar;": { "codepoints": [10597], "characters": "\u2965" }, "&dagger;": { "codepoints": [8224], "characters": "\u2020" }, "&daleth;": { "codepoints": [8504], "characters": "\u2138" }, "&darr;": { "codepoints": [8595], "characters": "\u2193" }, "&dash;": { "codepoints": [8208], "characters": "\u2010" }, "&dashv;": { "codepoints": [8867], "characters": "\u22A3" }, "&dbkarow;": { "codepoints": [10511], "characters": "\u290F" }, "&dblac;": { "codepoints": [733], "characters": "\u02DD" }, "&dcaron;": { "codepoints": [271], "characters": "\u010F" }, "&dcy;": { "codepoints": [1076], "characters": "\u0434" }, "&dd;": { "codepoints": [8518], "characters": "\u2146" }, "&ddagger;": { "codepoints": [8225], "characters": "\u2021" }, "&ddarr;": { "codepoints": [8650], "characters": "\u21CA" }, "&ddotseq;": { "codepoints": [10871], "characters": "\u2A77" }, "&deg": { "codepoints": [176], "characters": "\u00B0" }, "&deg;": { "codepoints": [176], "characters": "\u00B0" }, "&delta;": { "codepoints": [948], "characters": "\u03B4" }, "&demptyv;": { "codepoints": [10673], "characters": "\u29B1" }, "&dfisht;": { "codepoints": [10623], "characters": "\u297F" }, "&dfr;": { "codepoints": [120097], "characters": "\uD835\uDD21" }, "&dharl;": { "codepoints": [8643], "characters": "\u21C3" }, "&dharr;": { "codepoints": [8642], "characters": "\u21C2" }, "&diam;": { "codepoints": [8900], "characters": "\u22C4" }, "&diamond;": { "codepoints": [8900], "characters": "\u22C4" }, "&diamondsuit;": { "codepoints": [9830], "characters": "\u2666" }, "&diams;": { "codepoints": [9830], "characters": "\u2666" }, "&die;": { "codepoints": [168], "characters": "\u00A8" }, "&digamma;": { "codepoints": [989], "characters": "\u03DD" }, "&disin;": { "codepoints": [8946], "characters": "\u22F2" }, "&div;": { "codepoints": [247], "characters": "\u00F7" }, "&divide": { "codepoints": [247], "characters": "\u00F7" }, "&divide;": { "codepoints": [247], "characters": "\u00F7" }, "&divideontimes;": { "codepoints": [8903], "characters": "\u22C7" }, "&divonx;": { "codepoints": [8903], "characters": "\u22C7" }, "&djcy;": { "codepoints": [1106], "characters": "\u0452" }, "&dlcorn;": { "codepoints": [8990], "characters": "\u231E" }, "&dlcrop;": { "codepoints": [8973], "characters": "\u230D" }, "&dollar;": { "codepoints": [36], "characters": "\u0024" }, "&dopf;": { "codepoints": [120149], "characters": "\uD835\uDD55" }, "&dot;": { "codepoints": [729], "characters": "\u02D9" }, "&doteq;": { "codepoints": [8784], "characters": "\u2250" }, "&doteqdot;": { "codepoints": [8785], "characters": "\u2251" }, "&dotminus;": { "codepoints": [8760], "characters": "\u2238" }, "&dotplus;": { "codepoints": [8724], "characters": "\u2214" }, "&dotsquare;": { "codepoints": [8865], "characters": "\u22A1" }, "&doublebarwedge;": { "codepoints": [8966], "characters": "\u2306" }, "&downarrow;": { "codepoints": [8595], "characters": "\u2193" }, "&downdownarrows;": { "codepoints": [8650], "characters": "\u21CA" }, "&downharpoonleft;": { "codepoints": [8643], "characters": "\u21C3" }, "&downharpoonright;": { "codepoints": [8642], "characters": "\u21C2" }, "&drbkarow;": { "codepoints": [10512], "characters": "\u2910" }, "&drcorn;": { "codepoints": [8991], "characters": "\u231F" }, "&drcrop;": { "codepoints": [8972], "characters": "\u230C" }, "&dscr;": { "codepoints": [119993], "characters": "\uD835\uDCB9" }, "&dscy;": { "codepoints": [1109], "characters": "\u0455" }, "&dsol;": { "codepoints": [10742], "characters": "\u29F6" }, "&dstrok;": { "codepoints": [273], "characters": "\u0111" }, "&dtdot;": { "codepoints": [8945], "characters": "\u22F1" }, "&dtri;": { "codepoints": [9663], "characters": "\u25BF" }, "&dtrif;": { "codepoints": [9662], "characters": "\u25BE" }, "&duarr;": { "codepoints": [8693], "characters": "\u21F5" }, "&duhar;": { "codepoints": [10607], "characters": "\u296F" }, "&dwangle;": { "codepoints": [10662], "characters": "\u29A6" }, "&dzcy;": { "codepoints": [1119], "characters": "\u045F" }, "&dzigrarr;": { "codepoints": [10239], "characters": "\u27FF" }, "&eDDot;": { "codepoints": [10871], "characters": "\u2A77" }, "&eDot;": { "codepoints": [8785], "characters": "\u2251" }, "&eacute": { "codepoints": [233], "characters": "\u00E9" }, "&eacute;": { "codepoints": [233], "characters": "\u00E9" }, "&easter;": { "codepoints": [10862], "characters": "\u2A6E" }, "&ecaron;": { "codepoints": [283], "characters": "\u011B" }, "&ecir;": { "codepoints": [8790], "characters": "\u2256" }, "&ecirc": { "codepoints": [234], "characters": "\u00EA" }, "&ecirc;": { "codepoints": [234], "characters": "\u00EA" }, "&ecolon;": { "codepoints": [8789], "characters": "\u2255" }, "&ecy;": { "codepoints": [1101], "characters": "\u044D" }, "&edot;": { "codepoints": [279], "characters": "\u0117" }, "&ee;": { "codepoints": [8519], "characters": "\u2147" }, "&efDot;": { "codepoints": [8786], "characters": "\u2252" }, "&efr;": { "codepoints": [120098], "characters": "\uD835\uDD22" }, "&eg;": { "codepoints": [10906], "characters": "\u2A9A" }, "&egrave": { "codepoints": [232], "characters": "\u00E8" }, "&egrave;": { "codepoints": [232], "characters": "\u00E8" }, "&egs;": { "codepoints": [10902], "characters": "\u2A96" }, "&egsdot;": { "codepoints": [10904], "characters": "\u2A98" }, "&el;": { "codepoints": [10905], "characters": "\u2A99" }, "&elinters;": { "codepoints": [9191], "characters": "\u23E7" }, "&ell;": { "codepoints": [8467], "characters": "\u2113" }, "&els;": { "codepoints": [10901], "characters": "\u2A95" }, "&elsdot;": { "codepoints": [10903], "characters": "\u2A97" }, "&emacr;": { "codepoints": [275], "characters": "\u0113" }, "&empty;": { "codepoints": [8709], "characters": "\u2205" }, "&emptyset;": { "codepoints": [8709], "characters": "\u2205" }, "&emptyv;": { "codepoints": [8709], "characters": "\u2205" }, "&emsp13;": { "codepoints": [8196], "characters": "\u2004" }, "&emsp14;": { "codepoints": [8197], "characters": "\u2005" }, "&emsp;": { "codepoints": [8195], "characters": "\u2003" }, "&eng;": { "codepoints": [331], "characters": "\u014B" }, "&ensp;": { "codepoints": [8194], "characters": "\u2002" }, "&eogon;": { "codepoints": [281], "characters": "\u0119" }, "&eopf;": { "codepoints": [120150], "characters": "\uD835\uDD56" }, "&epar;": { "codepoints": [8917], "characters": "\u22D5" }, "&eparsl;": { "codepoints": [10723], "characters": "\u29E3" }, "&eplus;": { "codepoints": [10865], "characters": "\u2A71" }, "&epsi;": { "codepoints": [949], "characters": "\u03B5" }, "&epsilon;": { "codepoints": [949], "characters": "\u03B5" }, "&epsiv;": { "codepoints": [1013], "characters": "\u03F5" }, "&eqcirc;": { "codepoints": [8790], "characters": "\u2256" }, "&eqcolon;": { "codepoints": [8789], "characters": "\u2255" }, "&eqsim;": { "codepoints": [8770], "characters": "\u2242" }, "&eqslantgtr;": { "codepoints": [10902], "characters": "\u2A96" }, "&eqslantless;": { "codepoints": [10901], "characters": "\u2A95" }, "&equals;": { "codepoints": [61], "characters": "\u003D" }, "&equest;": { "codepoints": [8799], "characters": "\u225F" }, "&equiv;": { "codepoints": [8801], "characters": "\u2261" }, "&equivDD;": { "codepoints": [10872], "characters": "\u2A78" }, "&eqvparsl;": { "codepoints": [10725], "characters": "\u29E5" }, "&erDot;": { "codepoints": [8787], "characters": "\u2253" }, "&erarr;": { "codepoints": [10609], "characters": "\u2971" }, "&escr;": { "codepoints": [8495], "characters": "\u212F" }, "&esdot;": { "codepoints": [8784], "characters": "\u2250" }, "&esim;": { "codepoints": [8770], "characters": "\u2242" }, "&eta;": { "codepoints": [951], "characters": "\u03B7" }, "&eth": { "codepoints": [240], "characters": "\u00F0" }, "&eth;": { "codepoints": [240], "characters": "\u00F0" }, "&euml": { "codepoints": [235], "characters": "\u00EB" }, "&euml;": { "codepoints": [235], "characters": "\u00EB" }, "&euro;": { "codepoints": [8364], "characters": "\u20AC" }, "&excl;": { "codepoints": [33], "characters": "\u0021" }, "&exist;": { "codepoints": [8707], "characters": "\u2203" }, "&expectation;": { "codepoints": [8496], "characters": "\u2130" }, "&exponentiale;": { "codepoints": [8519], "characters": "\u2147" }, "&fallingdotseq;": { "codepoints": [8786], "characters": "\u2252" }, "&fcy;": { "codepoints": [1092], "characters": "\u0444" }, "&female;": { "codepoints": [9792], "characters": "\u2640" }, "&ffilig;": { "codepoints": [64259], "characters": "\uFB03" }, "&fflig;": { "codepoints": [64256], "characters": "\uFB00" }, "&ffllig;": { "codepoints": [64260], "characters": "\uFB04" }, "&ffr;": { "codepoints": [120099], "characters": "\uD835\uDD23" }, "&filig;": { "codepoints": [64257], "characters": "\uFB01" }, "&fjlig;": { "codepoints": [102, 106], "characters": "\u0066\u006A" }, "&flat;": { "codepoints": [9837], "characters": "\u266D" }, "&fllig;": { "codepoints": [64258], "characters": "\uFB02" }, "&fltns;": { "codepoints": [9649], "characters": "\u25B1" }, "&fnof;": { "codepoints": [402], "characters": "\u0192" }, "&fopf;": { "codepoints": [120151], "characters": "\uD835\uDD57" }, "&forall;": { "codepoints": [8704], "characters": "\u2200" }, "&fork;": { "codepoints": [8916], "characters": "\u22D4" }, "&forkv;": { "codepoints": [10969], "characters": "\u2AD9" }, "&fpartint;": { "codepoints": [10765], "characters": "\u2A0D" }, "&frac12": { "codepoints": [189], "characters": "\u00BD" }, "&frac12;": { "codepoints": [189], "characters": "\u00BD" }, "&frac13;": { "codepoints": [8531], "characters": "\u2153" }, "&frac14": { "codepoints": [188], "characters": "\u00BC" }, "&frac14;": { "codepoints": [188], "characters": "\u00BC" }, "&frac15;": { "codepoints": [8533], "characters": "\u2155" }, "&frac16;": { "codepoints": [8537], "characters": "\u2159" }, "&frac18;": { "codepoints": [8539], "characters": "\u215B" }, "&frac23;": { "codepoints": [8532], "characters": "\u2154" }, "&frac25;": { "codepoints": [8534], "characters": "\u2156" }, "&frac34": { "codepoints": [190], "characters": "\u00BE" }, "&frac34;": { "codepoints": [190], "characters": "\u00BE" }, "&frac35;": { "codepoints": [8535], "characters": "\u2157" }, "&frac38;": { "codepoints": [8540], "characters": "\u215C" }, "&frac45;": { "codepoints": [8536], "characters": "\u2158" }, "&frac56;": { "codepoints": [8538], "characters": "\u215A" }, "&frac58;": { "codepoints": [8541], "characters": "\u215D" }, "&frac78;": { "codepoints": [8542], "characters": "\u215E" }, "&frasl;": { "codepoints": [8260], "characters": "\u2044" }, "&frown;": { "codepoints": [8994], "characters": "\u2322" }, "&fscr;": { "codepoints": [119995], "characters": "\uD835\uDCBB" }, "&gE;": { "codepoints": [8807], "characters": "\u2267" }, "&gEl;": { "codepoints": [10892], "characters": "\u2A8C" }, "&gacute;": { "codepoints": [501], "characters": "\u01F5" }, "&gamma;": { "codepoints": [947], "characters": "\u03B3" }, "&gammad;": { "codepoints": [989], "characters": "\u03DD" }, "&gap;": { "codepoints": [10886], "characters": "\u2A86" }, "&gbreve;": { "codepoints": [287], "characters": "\u011F" }, "&gcirc;": { "codepoints": [285], "characters": "\u011D" }, "&gcy;": { "codepoints": [1075], "characters": "\u0433" }, "&gdot;": { "codepoints": [289], "characters": "\u0121" }, "&ge;": { "codepoints": [8805], "characters": "\u2265" }, "&gel;": { "codepoints": [8923], "characters": "\u22DB" }, "&geq;": { "codepoints": [8805], "characters": "\u2265" }, "&geqq;": { "codepoints": [8807], "characters": "\u2267" }, "&geqslant;": { "codepoints": [10878], "characters": "\u2A7E" }, "&ges;": { "codepoints": [10878], "characters": "\u2A7E" }, "&gescc;": { "codepoints": [10921], "characters": "\u2AA9" }, "&gesdot;": { "codepoints": [10880], "characters": "\u2A80" }, "&gesdoto;": { "codepoints": [10882], "characters": "\u2A82" }, "&gesdotol;": { "codepoints": [10884], "characters": "\u2A84" }, "&gesl;": { "codepoints": [8923, 65024], "characters": "\u22DB\uFE00" }, "&gesles;": { "codepoints": [10900], "characters": "\u2A94" }, "&gfr;": { "codepoints": [120100], "characters": "\uD835\uDD24" }, "&gg;": { "codepoints": [8811], "characters": "\u226B" }, "&ggg;": { "codepoints": [8921], "characters": "\u22D9" }, "&gimel;": { "codepoints": [8503], "characters": "\u2137" }, "&gjcy;": { "codepoints": [1107], "characters": "\u0453" }, "&gl;": { "codepoints": [8823], "characters": "\u2277" }, "&glE;": { "codepoints": [10898], "characters": "\u2A92" }, "&gla;": { "codepoints": [10917], "characters": "\u2AA5" }, "&glj;": { "codepoints": [10916], "characters": "\u2AA4" }, "&gnE;": { "codepoints": [8809], "characters": "\u2269" }, "&gnap;": { "codepoints": [10890], "characters": "\u2A8A" }, "&gnapprox;": { "codepoints": [10890], "characters": "\u2A8A" }, "&gne;": { "codepoints": [10888], "characters": "\u2A88" }, "&gneq;": { "codepoints": [10888], "characters": "\u2A88" }, "&gneqq;": { "codepoints": [8809], "characters": "\u2269" }, "&gnsim;": { "codepoints": [8935], "characters": "\u22E7" }, "&gopf;": { "codepoints": [120152], "characters": "\uD835\uDD58" }, "&grave;": { "codepoints": [96], "characters": "\u0060" }, "&gscr;": { "codepoints": [8458], "characters": "\u210A" }, "&gsim;": { "codepoints": [8819], "characters": "\u2273" }, "&gsime;": { "codepoints": [10894], "characters": "\u2A8E" }, "&gsiml;": { "codepoints": [10896], "characters": "\u2A90" }, "&gt": { "codepoints": [62], "characters": "\u003E" }, "&gt;": { "codepoints": [62], "characters": "\u003E" }, "&gtcc;": { "codepoints": [10919], "characters": "\u2AA7" }, "&gtcir;": { "codepoints": [10874], "characters": "\u2A7A" }, "&gtdot;": { "codepoints": [8919], "characters": "\u22D7" }, "&gtlPar;": { "codepoints": [10645], "characters": "\u2995" }, "&gtquest;": { "codepoints": [10876], "characters": "\u2A7C" }, "&gtrapprox;": { "codepoints": [10886], "characters": "\u2A86" }, "&gtrarr;": { "codepoints": [10616], "characters": "\u2978" }, "&gtrdot;": { "codepoints": [8919], "characters": "\u22D7" }, "&gtreqless;": { "codepoints": [8923], "characters": "\u22DB" }, "&gtreqqless;": { "codepoints": [10892], "characters": "\u2A8C" }, "&gtrless;": { "codepoints": [8823], "characters": "\u2277" }, "&gtrsim;": { "codepoints": [8819], "characters": "\u2273" }, "&gvertneqq;": { "codepoints": [8809, 65024], "characters": "\u2269\uFE00" }, "&gvnE;": { "codepoints": [8809, 65024], "characters": "\u2269\uFE00" }, "&hArr;": { "codepoints": [8660], "characters": "\u21D4" }, "&hairsp;": { "codepoints": [8202], "characters": "\u200A" }, "&half;": { "codepoints": [189], "characters": "\u00BD" }, "&hamilt;": { "codepoints": [8459], "characters": "\u210B" }, "&hardcy;": { "codepoints": [1098], "characters": "\u044A" }, "&harr;": { "codepoints": [8596], "characters": "\u2194" }, "&harrcir;": { "codepoints": [10568], "characters": "\u2948" }, "&harrw;": { "codepoints": [8621], "characters": "\u21AD" }, "&hbar;": { "codepoints": [8463], "characters": "\u210F" }, "&hcirc;": { "codepoints": [293], "characters": "\u0125" }, "&hearts;": { "codepoints": [9829], "characters": "\u2665" }, "&heartsuit;": { "codepoints": [9829], "characters": "\u2665" }, "&hellip;": { "codepoints": [8230], "characters": "\u2026" }, "&hercon;": { "codepoints": [8889], "characters": "\u22B9" }, "&hfr;": { "codepoints": [120101], "characters": "\uD835\uDD25" }, "&hksearow;": { "codepoints": [10533], "characters": "\u2925" }, "&hkswarow;": { "codepoints": [10534], "characters": "\u2926" }, "&hoarr;": { "codepoints": [8703], "characters": "\u21FF" }, "&homtht;": { "codepoints": [8763], "characters": "\u223B" }, "&hookleftarrow;": { "codepoints": [8617], "characters": "\u21A9" }, "&hookrightarrow;": { "codepoints": [8618], "characters": "\u21AA" }, "&hopf;": { "codepoints": [120153], "characters": "\uD835\uDD59" }, "&horbar;": { "codepoints": [8213], "characters": "\u2015" }, "&hscr;": { "codepoints": [119997], "characters": "\uD835\uDCBD" }, "&hslash;": { "codepoints": [8463], "characters": "\u210F" }, "&hstrok;": { "codepoints": [295], "characters": "\u0127" }, "&hybull;": { "codepoints": [8259], "characters": "\u2043" }, "&hyphen;": { "codepoints": [8208], "characters": "\u2010" }, "&iacute": { "codepoints": [237], "characters": "\u00ED" }, "&iacute;": { "codepoints": [237], "characters": "\u00ED" }, "&ic;": { "codepoints": [8291], "characters": "\u2063" }, "&icirc": { "codepoints": [238], "characters": "\u00EE" }, "&icirc;": { "codepoints": [238], "characters": "\u00EE" }, "&icy;": { "codepoints": [1080], "characters": "\u0438" }, "&iecy;": { "codepoints": [1077], "characters": "\u0435" }, "&iexcl": { "codepoints": [161], "characters": "\u00A1" }, "&iexcl;": { "codepoints": [161], "characters": "\u00A1" }, "&iff;": { "codepoints": [8660], "characters": "\u21D4" }, "&ifr;": { "codepoints": [120102], "characters": "\uD835\uDD26" }, "&igrave": { "codepoints": [236], "characters": "\u00EC" }, "&igrave;": { "codepoints": [236], "characters": "\u00EC" }, "&ii;": { "codepoints": [8520], "characters": "\u2148" }, "&iiiint;": { "codepoints": [10764], "characters": "\u2A0C" }, "&iiint;": { "codepoints": [8749], "characters": "\u222D" }, "&iinfin;": { "codepoints": [10716], "characters": "\u29DC" }, "&iiota;": { "codepoints": [8489], "characters": "\u2129" }, "&ijlig;": { "codepoints": [307], "characters": "\u0133" }, "&imacr;": { "codepoints": [299], "characters": "\u012B" }, "&image;": { "codepoints": [8465], "characters": "\u2111" }, "&imagline;": { "codepoints": [8464], "characters": "\u2110" }, "&imagpart;": { "codepoints": [8465], "characters": "\u2111" }, "&imath;": { "codepoints": [305], "characters": "\u0131" }, "&imof;": { "codepoints": [8887], "characters": "\u22B7" }, "&imped;": { "codepoints": [437], "characters": "\u01B5" }, "&in;": { "codepoints": [8712], "characters": "\u2208" }, "&incare;": { "codepoints": [8453], "characters": "\u2105" }, "&infin;": { "codepoints": [8734], "characters": "\u221E" }, "&infintie;": { "codepoints": [10717], "characters": "\u29DD" }, "&inodot;": { "codepoints": [305], "characters": "\u0131" }, "&int;": { "codepoints": [8747], "characters": "\u222B" }, "&intcal;": { "codepoints": [8890], "characters": "\u22BA" }, "&integers;": { "codepoints": [8484], "characters": "\u2124" }, "&intercal;": { "codepoints": [8890], "characters": "\u22BA" }, "&intlarhk;": { "codepoints": [10775], "characters": "\u2A17" }, "&intprod;": { "codepoints": [10812], "characters": "\u2A3C" }, "&iocy;": { "codepoints": [1105], "characters": "\u0451" }, "&iogon;": { "codepoints": [303], "characters": "\u012F" }, "&iopf;": { "codepoints": [120154], "characters": "\uD835\uDD5A" }, "&iota;": { "codepoints": [953], "characters": "\u03B9" }, "&iprod;": { "codepoints": [10812], "characters": "\u2A3C" }, "&iquest": { "codepoints": [191], "characters": "\u00BF" }, "&iquest;": { "codepoints": [191], "characters": "\u00BF" }, "&iscr;": { "codepoints": [119998], "characters": "\uD835\uDCBE" }, "&isin;": { "codepoints": [8712], "characters": "\u2208" }, "&isinE;": { "codepoints": [8953], "characters": "\u22F9" }, "&isindot;": { "codepoints": [8949], "characters": "\u22F5" }, "&isins;": { "codepoints": [8948], "characters": "\u22F4" }, "&isinsv;": { "codepoints": [8947], "characters": "\u22F3" }, "&isinv;": { "codepoints": [8712], "characters": "\u2208" }, "&it;": { "codepoints": [8290], "characters": "\u2062" }, "&itilde;": { "codepoints": [297], "characters": "\u0129" }, "&iukcy;": { "codepoints": [1110], "characters": "\u0456" }, "&iuml": { "codepoints": [239], "characters": "\u00EF" }, "&iuml;": { "codepoints": [239], "characters": "\u00EF" }, "&jcirc;": { "codepoints": [309], "characters": "\u0135" }, "&jcy;": { "codepoints": [1081], "characters": "\u0439" }, "&jfr;": { "codepoints": [120103], "characters": "\uD835\uDD27" }, "&jmath;": { "codepoints": [567], "characters": "\u0237" }, "&jopf;": { "codepoints": [120155], "characters": "\uD835\uDD5B" }, "&jscr;": { "codepoints": [119999], "characters": "\uD835\uDCBF" }, "&jsercy;": { "codepoints": [1112], "characters": "\u0458" }, "&jukcy;": { "codepoints": [1108], "characters": "\u0454" }, "&kappa;": { "codepoints": [954], "characters": "\u03BA" }, "&kappav;": { "codepoints": [1008], "characters": "\u03F0" }, "&kcedil;": { "codepoints": [311], "characters": "\u0137" }, "&kcy;": { "codepoints": [1082], "characters": "\u043A" }, "&kfr;": { "codepoints": [120104], "characters": "\uD835\uDD28" }, "&kgreen;": { "codepoints": [312], "characters": "\u0138" }, "&khcy;": { "codepoints": [1093], "characters": "\u0445" }, "&kjcy;": { "codepoints": [1116], "characters": "\u045C" }, "&kopf;": { "codepoints": [120156], "characters": "\uD835\uDD5C" }, "&kscr;": { "codepoints": [120000], "characters": "\uD835\uDCC0" }, "&lAarr;": { "codepoints": [8666], "characters": "\u21DA" }, "&lArr;": { "codepoints": [8656], "characters": "\u21D0" }, "&lAtail;": { "codepoints": [10523], "characters": "\u291B" }, "&lBarr;": { "codepoints": [10510], "characters": "\u290E" }, "&lE;": { "codepoints": [8806], "characters": "\u2266" }, "&lEg;": { "codepoints": [10891], "characters": "\u2A8B" }, "&lHar;": { "codepoints": [10594], "characters": "\u2962" }, "&lacute;": { "codepoints": [314], "characters": "\u013A" }, "&laemptyv;": { "codepoints": [10676], "characters": "\u29B4" }, "&lagran;": { "codepoints": [8466], "characters": "\u2112" }, "&lambda;": { "codepoints": [955], "characters": "\u03BB" }, "&lang;": { "codepoints": [10216], "characters": "\u27E8" }, "&langd;": { "codepoints": [10641], "characters": "\u2991" }, "&langle;": { "codepoints": [10216], "characters": "\u27E8" }, "&lap;": { "codepoints": [10885], "characters": "\u2A85" }, "&laquo": { "codepoints": [171], "characters": "\u00AB" }, "&laquo;": { "codepoints": [171], "characters": "\u00AB" }, "&larr;": { "codepoints": [8592], "characters": "\u2190" }, "&larrb;": { "codepoints": [8676], "characters": "\u21E4" }, "&larrbfs;": { "codepoints": [10527], "characters": "\u291F" }, "&larrfs;": { "codepoints": [10525], "characters": "\u291D" }, "&larrhk;": { "codepoints": [8617], "characters": "\u21A9" }, "&larrlp;": { "codepoints": [8619], "characters": "\u21AB" }, "&larrpl;": { "codepoints": [10553], "characters": "\u2939" }, "&larrsim;": { "codepoints": [10611], "characters": "\u2973" }, "&larrtl;": { "codepoints": [8610], "characters": "\u21A2" }, "&lat;": { "codepoints": [10923], "characters": "\u2AAB" }, "&latail;": { "codepoints": [10521], "characters": "\u2919" }, "&late;": { "codepoints": [10925], "characters": "\u2AAD" }, "&lates;": { "codepoints": [10925, 65024], "characters": "\u2AAD\uFE00" }, "&lbarr;": { "codepoints": [10508], "characters": "\u290C" }, "&lbbrk;": { "codepoints": [10098], "characters": "\u2772" }, "&lbrace;": { "codepoints": [123], "characters": "\u007B" }, "&lbrack;": { "codepoints": [91], "characters": "\u005B" }, "&lbrke;": { "codepoints": [10635], "characters": "\u298B" }, "&lbrksld;": { "codepoints": [10639], "characters": "\u298F" }, "&lbrkslu;": { "codepoints": [10637], "characters": "\u298D" }, "&lcaron;": { "codepoints": [318], "characters": "\u013E" }, "&lcedil;": { "codepoints": [316], "characters": "\u013C" }, "&lceil;": { "codepoints": [8968], "characters": "\u2308" }, "&lcub;": { "codepoints": [123], "characters": "\u007B" }, "&lcy;": { "codepoints": [1083], "characters": "\u043B" }, "&ldca;": { "codepoints": [10550], "characters": "\u2936" }, "&ldquo;": { "codepoints": [8220], "characters": "\u201C" }, "&ldquor;": { "codepoints": [8222], "characters": "\u201E" }, "&ldrdhar;": { "codepoints": [10599], "characters": "\u2967" }, "&ldrushar;": { "codepoints": [10571], "characters": "\u294B" }, "&ldsh;": { "codepoints": [8626], "characters": "\u21B2" }, "&le;": { "codepoints": [8804], "characters": "\u2264" }, "&leftarrow;": { "codepoints": [8592], "characters": "\u2190" }, "&leftarrowtail;": { "codepoints": [8610], "characters": "\u21A2" }, "&leftharpoondown;": { "codepoints": [8637], "characters": "\u21BD" }, "&leftharpoonup;": { "codepoints": [8636], "characters": "\u21BC" }, "&leftleftarrows;": { "codepoints": [8647], "characters": "\u21C7" }, "&leftrightarrow;": { "codepoints": [8596], "characters": "\u2194" }, "&leftrightarrows;": { "codepoints": [8646], "characters": "\u21C6" }, "&leftrightharpoons;": { "codepoints": [8651], "characters": "\u21CB" }, "&leftrightsquigarrow;": { "codepoints": [8621], "characters": "\u21AD" }, "&leftthreetimes;": { "codepoints": [8907], "characters": "\u22CB" }, "&leg;": { "codepoints": [8922], "characters": "\u22DA" }, "&leq;": { "codepoints": [8804], "characters": "\u2264" }, "&leqq;": { "codepoints": [8806], "characters": "\u2266" }, "&leqslant;": { "codepoints": [10877], "characters": "\u2A7D" }, "&les;": { "codepoints": [10877], "characters": "\u2A7D" }, "&lescc;": { "codepoints": [10920], "characters": "\u2AA8" }, "&lesdot;": { "codepoints": [10879], "characters": "\u2A7F" }, "&lesdoto;": { "codepoints": [10881], "characters": "\u2A81" }, "&lesdotor;": { "codepoints": [10883], "characters": "\u2A83" }, "&lesg;": { "codepoints": [8922, 65024], "characters": "\u22DA\uFE00" }, "&lesges;": { "codepoints": [10899], "characters": "\u2A93" }, "&lessapprox;": { "codepoints": [10885], "characters": "\u2A85" }, "&lessdot;": { "codepoints": [8918], "characters": "\u22D6" }, "&lesseqgtr;": { "codepoints": [8922], "characters": "\u22DA" }, "&lesseqqgtr;": { "codepoints": [10891], "characters": "\u2A8B" }, "&lessgtr;": { "codepoints": [8822], "characters": "\u2276" }, "&lesssim;": { "codepoints": [8818], "characters": "\u2272" }, "&lfisht;": { "codepoints": [10620], "characters": "\u297C" }, "&lfloor;": { "codepoints": [8970], "characters": "\u230A" }, "&lfr;": { "codepoints": [120105], "characters": "\uD835\uDD29" }, "&lg;": { "codepoints": [8822], "characters": "\u2276" }, "&lgE;": { "codepoints": [10897], "characters": "\u2A91" }, "&lhard;": { "codepoints": [8637], "characters": "\u21BD" }, "&lharu;": { "codepoints": [8636], "characters": "\u21BC" }, "&lharul;": { "codepoints": [10602], "characters": "\u296A" }, "&lhblk;": { "codepoints": [9604], "characters": "\u2584" }, "&ljcy;": { "codepoints": [1113], "characters": "\u0459" }, "&ll;": { "codepoints": [8810], "characters": "\u226A" }, "&llarr;": { "codepoints": [8647], "characters": "\u21C7" }, "&llcorner;": { "codepoints": [8990], "characters": "\u231E" }, "&llhard;": { "codepoints": [10603], "characters": "\u296B" }, "&lltri;": { "codepoints": [9722], "characters": "\u25FA" }, "&lmidot;": { "codepoints": [320], "characters": "\u0140" }, "&lmoust;": { "codepoints": [9136], "characters": "\u23B0" }, "&lmoustache;": { "codepoints": [9136], "characters": "\u23B0" }, "&lnE;": { "codepoints": [8808], "characters": "\u2268" }, "&lnap;": { "codepoints": [10889], "characters": "\u2A89" }, "&lnapprox;": { "codepoints": [10889], "characters": "\u2A89" }, "&lne;": { "codepoints": [10887], "characters": "\u2A87" }, "&lneq;": { "codepoints": [10887], "characters": "\u2A87" }, "&lneqq;": { "codepoints": [8808], "characters": "\u2268" }, "&lnsim;": { "codepoints": [8934], "characters": "\u22E6" }, "&loang;": { "codepoints": [10220], "characters": "\u27EC" }, "&loarr;": { "codepoints": [8701], "characters": "\u21FD" }, "&lobrk;": { "codepoints": [10214], "characters": "\u27E6" }, "&longleftarrow;": { "codepoints": [10229], "characters": "\u27F5" }, "&longleftrightarrow;": { "codepoints": [10231], "characters": "\u27F7" }, "&longmapsto;": { "codepoints": [10236], "characters": "\u27FC" }, "&longrightarrow;": { "codepoints": [10230], "characters": "\u27F6" }, "&looparrowleft;": { "codepoints": [8619], "characters": "\u21AB" }, "&looparrowright;": { "codepoints": [8620], "characters": "\u21AC" }, "&lopar;": { "codepoints": [10629], "characters": "\u2985" }, "&lopf;": { "codepoints": [120157], "characters": "\uD835\uDD5D" }, "&loplus;": { "codepoints": [10797], "characters": "\u2A2D" }, "&lotimes;": { "codepoints": [10804], "characters": "\u2A34" }, "&lowast;": { "codepoints": [8727], "characters": "\u2217" }, "&lowbar;": { "codepoints": [95], "characters": "\u005F" }, "&loz;": { "codepoints": [9674], "characters": "\u25CA" }, "&lozenge;": { "codepoints": [9674], "characters": "\u25CA" }, "&lozf;": { "codepoints": [10731], "characters": "\u29EB" }, "&lpar;": { "codepoints": [40], "characters": "\u0028" }, "&lparlt;": { "codepoints": [10643], "characters": "\u2993" }, "&lrarr;": { "codepoints": [8646], "characters": "\u21C6" }, "&lrcorner;": { "codepoints": [8991], "characters": "\u231F" }, "&lrhar;": { "codepoints": [8651], "characters": "\u21CB" }, "&lrhard;": { "codepoints": [10605], "characters": "\u296D" }, "&lrm;": { "codepoints": [8206], "characters": "\u200E" }, "&lrtri;": { "codepoints": [8895], "characters": "\u22BF" }, "&lsaquo;": { "codepoints": [8249], "characters": "\u2039" }, "&lscr;": { "codepoints": [120001], "characters": "\uD835\uDCC1" }, "&lsh;": { "codepoints": [8624], "characters": "\u21B0" }, "&lsim;": { "codepoints": [8818], "characters": "\u2272" }, "&lsime;": { "codepoints": [10893], "characters": "\u2A8D" }, "&lsimg;": { "codepoints": [10895], "characters": "\u2A8F" }, "&lsqb;": { "codepoints": [91], "characters": "\u005B" }, "&lsquo;": { "codepoints": [8216], "characters": "\u2018" }, "&lsquor;": { "codepoints": [8218], "characters": "\u201A" }, "&lstrok;": { "codepoints": [322], "characters": "\u0142" }, "&lt": { "codepoints": [60], "characters": "\u003C" }, "&lt;": { "codepoints": [60], "characters": "\u003C" }, "&ltcc;": { "codepoints": [10918], "characters": "\u2AA6" }, "&ltcir;": { "codepoints": [10873], "characters": "\u2A79" }, "&ltdot;": { "codepoints": [8918], "characters": "\u22D6" }, "&lthree;": { "codepoints": [8907], "characters": "\u22CB" }, "&ltimes;": { "codepoints": [8905], "characters": "\u22C9" }, "&ltlarr;": { "codepoints": [10614], "characters": "\u2976" }, "&ltquest;": { "codepoints": [10875], "characters": "\u2A7B" }, "&ltrPar;": { "codepoints": [10646], "characters": "\u2996" }, "&ltri;": { "codepoints": [9667], "characters": "\u25C3" }, "&ltrie;": { "codepoints": [8884], "characters": "\u22B4" }, "&ltrif;": { "codepoints": [9666], "characters": "\u25C2" }, "&lurdshar;": { "codepoints": [10570], "characters": "\u294A" }, "&luruhar;": { "codepoints": [10598], "characters": "\u2966" }, "&lvertneqq;": { "codepoints": [8808, 65024], "characters": "\u2268\uFE00" }, "&lvnE;": { "codepoints": [8808, 65024], "characters": "\u2268\uFE00" }, "&mDDot;": { "codepoints": [8762], "characters": "\u223A" }, "&macr": { "codepoints": [175], "characters": "\u00AF" }, "&macr;": { "codepoints": [175], "characters": "\u00AF" }, "&male;": { "codepoints": [9794], "characters": "\u2642" }, "&malt;": { "codepoints": [10016], "characters": "\u2720" }, "&maltese;": { "codepoints": [10016], "characters": "\u2720" }, "&map;": { "codepoints": [8614], "characters": "\u21A6" }, "&mapsto;": { "codepoints": [8614], "characters": "\u21A6" }, "&mapstodown;": { "codepoints": [8615], "characters": "\u21A7" }, "&mapstoleft;": { "codepoints": [8612], "characters": "\u21A4" }, "&mapstoup;": { "codepoints": [8613], "characters": "\u21A5" }, "&marker;": { "codepoints": [9646], "characters": "\u25AE" }, "&mcomma;": { "codepoints": [10793], "characters": "\u2A29" }, "&mcy;": { "codepoints": [1084], "characters": "\u043C" }, "&mdash;": { "codepoints": [8212], "characters": "\u2014" }, "&measuredangle;": { "codepoints": [8737], "characters": "\u2221" }, "&mfr;": { "codepoints": [120106], "characters": "\uD835\uDD2A" }, "&mho;": { "codepoints": [8487], "characters": "\u2127" }, "&micro": { "codepoints": [181], "characters": "\u00B5" }, "&micro;": { "codepoints": [181], "characters": "\u00B5" }, "&mid;": { "codepoints": [8739], "characters": "\u2223" }, "&midast;": { "codepoints": [42], "characters": "\u002A" }, "&midcir;": { "codepoints": [10992], "characters": "\u2AF0" }, "&middot": { "codepoints": [183], "characters": "\u00B7" }, "&middot;": { "codepoints": [183], "characters": "\u00B7" }, "&minus;": { "codepoints": [8722], "characters": "\u2212" }, "&minusb;": { "codepoints": [8863], "characters": "\u229F" }, "&minusd;": { "codepoints": [8760], "characters": "\u2238" }, "&minusdu;": { "codepoints": [10794], "characters": "\u2A2A" }, "&mlcp;": { "codepoints": [10971], "characters": "\u2ADB" }, "&mldr;": { "codepoints": [8230], "characters": "\u2026" }, "&mnplus;": { "codepoints": [8723], "characters": "\u2213" }, "&models;": { "codepoints": [8871], "characters": "\u22A7" }, "&mopf;": { "codepoints": [120158], "characters": "\uD835\uDD5E" }, "&mp;": { "codepoints": [8723], "characters": "\u2213" }, "&mscr;": { "codepoints": [120002], "characters": "\uD835\uDCC2" }, "&mstpos;": { "codepoints": [8766], "characters": "\u223E" }, "&mu;": { "codepoints": [956], "characters": "\u03BC" }, "&multimap;": { "codepoints": [8888], "characters": "\u22B8" }, "&mumap;": { "codepoints": [8888], "characters": "\u22B8" }, "&nGg;": { "codepoints": [8921, 824], "characters": "\u22D9\u0338" }, "&nGt;": { "codepoints": [8811, 8402], "characters": "\u226B\u20D2" }, "&nGtv;": { "codepoints": [8811, 824], "characters": "\u226B\u0338" }, "&nLeftarrow;": { "codepoints": [8653], "characters": "\u21CD" }, "&nLeftrightarrow;": { "codepoints": [8654], "characters": "\u21CE" }, "&nLl;": { "codepoints": [8920, 824], "characters": "\u22D8\u0338" }, "&nLt;": { "codepoints": [8810, 8402], "characters": "\u226A\u20D2" }, "&nLtv;": { "codepoints": [8810, 824], "characters": "\u226A\u0338" }, "&nRightarrow;": { "codepoints": [8655], "characters": "\u21CF" }, "&nVDash;": { "codepoints": [8879], "characters": "\u22AF" }, "&nVdash;": { "codepoints": [8878], "characters": "\u22AE" }, "&nabla;": { "codepoints": [8711], "characters": "\u2207" }, "&nacute;": { "codepoints": [324], "characters": "\u0144" }, "&nang;": { "codepoints": [8736, 8402], "characters": "\u2220\u20D2" }, "&nap;": { "codepoints": [8777], "characters": "\u2249" }, "&napE;": { "codepoints": [10864, 824], "characters": "\u2A70\u0338" }, "&napid;": { "codepoints": [8779, 824], "characters": "\u224B\u0338" }, "&napos;": { "codepoints": [329], "characters": "\u0149" }, "&napprox;": { "codepoints": [8777], "characters": "\u2249" }, "&natur;": { "codepoints": [9838], "characters": "\u266E" }, "&natural;": { "codepoints": [9838], "characters": "\u266E" }, "&naturals;": { "codepoints": [8469], "characters": "\u2115" }, "&nbsp": { "codepoints": [160], "characters": "\u00A0" }, "&nbsp;": { "codepoints": [160], "characters": "\u00A0" }, "&nbump;": { "codepoints": [8782, 824], "characters": "\u224E\u0338" }, "&nbumpe;": { "codepoints": [8783, 824], "characters": "\u224F\u0338" }, "&ncap;": { "codepoints": [10819], "characters": "\u2A43" }, "&ncaron;": { "codepoints": [328], "characters": "\u0148" }, "&ncedil;": { "codepoints": [326], "characters": "\u0146" }, "&ncong;": { "codepoints": [8775], "characters": "\u2247" }, "&ncongdot;": { "codepoints": [10861, 824], "characters": "\u2A6D\u0338" }, "&ncup;": { "codepoints": [10818], "characters": "\u2A42" }, "&ncy;": { "codepoints": [1085], "characters": "\u043D" }, "&ndash;": { "codepoints": [8211], "characters": "\u2013" }, "&ne;": { "codepoints": [8800], "characters": "\u2260" }, "&neArr;": { "codepoints": [8663], "characters": "\u21D7" }, "&nearhk;": { "codepoints": [10532], "characters": "\u2924" }, "&nearr;": { "codepoints": [8599], "characters": "\u2197" }, "&nearrow;": { "codepoints": [8599], "characters": "\u2197" }, "&nedot;": { "codepoints": [8784, 824], "characters": "\u2250\u0338" }, "&nequiv;": { "codepoints": [8802], "characters": "\u2262" }, "&nesear;": { "codepoints": [10536], "characters": "\u2928" }, "&nesim;": { "codepoints": [8770, 824], "characters": "\u2242\u0338" }, "&nexist;": { "codepoints": [8708], "characters": "\u2204" }, "&nexists;": { "codepoints": [8708], "characters": "\u2204" }, "&nfr;": { "codepoints": [120107], "characters": "\uD835\uDD2B" }, "&ngE;": { "codepoints": [8807, 824], "characters": "\u2267\u0338" }, "&nge;": { "codepoints": [8817], "characters": "\u2271" }, "&ngeq;": { "codepoints": [8817], "characters": "\u2271" }, "&ngeqq;": { "codepoints": [8807, 824], "characters": "\u2267\u0338" }, "&ngeqslant;": { "codepoints": [10878, 824], "characters": "\u2A7E\u0338" }, "&nges;": { "codepoints": [10878, 824], "characters": "\u2A7E\u0338" }, "&ngsim;": { "codepoints": [8821], "characters": "\u2275" }, "&ngt;": { "codepoints": [8815], "characters": "\u226F" }, "&ngtr;": { "codepoints": [8815], "characters": "\u226F" }, "&nhArr;": { "codepoints": [8654], "characters": "\u21CE" }, "&nharr;": { "codepoints": [8622], "characters": "\u21AE" }, "&nhpar;": { "codepoints": [10994], "characters": "\u2AF2" }, "&ni;": { "codepoints": [8715], "characters": "\u220B" }, "&nis;": { "codepoints": [8956], "characters": "\u22FC" }, "&nisd;": { "codepoints": [8954], "characters": "\u22FA" }, "&niv;": { "codepoints": [8715], "characters": "\u220B" }, "&njcy;": { "codepoints": [1114], "characters": "\u045A" }, "&nlArr;": { "codepoints": [8653], "characters": "\u21CD" }, "&nlE;": { "codepoints": [8806, 824], "characters": "\u2266\u0338" }, "&nlarr;": { "codepoints": [8602], "characters": "\u219A" }, "&nldr;": { "codepoints": [8229], "characters": "\u2025" }, "&nle;": { "codepoints": [8816], "characters": "\u2270" }, "&nleftarrow;": { "codepoints": [8602], "characters": "\u219A" }, "&nleftrightarrow;": { "codepoints": [8622], "characters": "\u21AE" }, "&nleq;": { "codepoints": [8816], "characters": "\u2270" }, "&nleqq;": { "codepoints": [8806, 824], "characters": "\u2266\u0338" }, "&nleqslant;": { "codepoints": [10877, 824], "characters": "\u2A7D\u0338" }, "&nles;": { "codepoints": [10877, 824], "characters": "\u2A7D\u0338" }, "&nless;": { "codepoints": [8814], "characters": "\u226E" }, "&nlsim;": { "codepoints": [8820], "characters": "\u2274" }, "&nlt;": { "codepoints": [8814], "characters": "\u226E" }, "&nltri;": { "codepoints": [8938], "characters": "\u22EA" }, "&nltrie;": { "codepoints": [8940], "characters": "\u22EC" }, "&nmid;": { "codepoints": [8740], "characters": "\u2224" }, "&nopf;": { "codepoints": [120159], "characters": "\uD835\uDD5F" }, "&not": { "codepoints": [172], "characters": "\u00AC" }, "&not;": { "codepoints": [172], "characters": "\u00AC" }, "&notin;": { "codepoints": [8713], "characters": "\u2209" }, "&notinE;": { "codepoints": [8953, 824], "characters": "\u22F9\u0338" }, "&notindot;": { "codepoints": [8949, 824], "characters": "\u22F5\u0338" }, "&notinva;": { "codepoints": [8713], "characters": "\u2209" }, "&notinvb;": { "codepoints": [8951], "characters": "\u22F7" }, "&notinvc;": { "codepoints": [8950], "characters": "\u22F6" }, "&notni;": { "codepoints": [8716], "characters": "\u220C" }, "&notniva;": { "codepoints": [8716], "characters": "\u220C" }, "&notnivb;": { "codepoints": [8958], "characters": "\u22FE" }, "&notnivc;": { "codepoints": [8957], "characters": "\u22FD" }, "&npar;": { "codepoints": [8742], "characters": "\u2226" }, "&nparallel;": { "codepoints": [8742], "characters": "\u2226" }, "&nparsl;": { "codepoints": [11005, 8421], "characters": "\u2AFD\u20E5" }, "&npart;": { "codepoints": [8706, 824], "characters": "\u2202\u0338" }, "&npolint;": { "codepoints": [10772], "characters": "\u2A14" }, "&npr;": { "codepoints": [8832], "characters": "\u2280" }, "&nprcue;": { "codepoints": [8928], "characters": "\u22E0" }, "&npre;": { "codepoints": [10927, 824], "characters": "\u2AAF\u0338" }, "&nprec;": { "codepoints": [8832], "characters": "\u2280" }, "&npreceq;": { "codepoints": [10927, 824], "characters": "\u2AAF\u0338" }, "&nrArr;": { "codepoints": [8655], "characters": "\u21CF" }, "&nrarr;": { "codepoints": [8603], "characters": "\u219B" }, "&nrarrc;": { "codepoints": [10547, 824], "characters": "\u2933\u0338" }, "&nrarrw;": { "codepoints": [8605, 824], "characters": "\u219D\u0338" }, "&nrightarrow;": { "codepoints": [8603], "characters": "\u219B" }, "&nrtri;": { "codepoints": [8939], "characters": "\u22EB" }, "&nrtrie;": { "codepoints": [8941], "characters": "\u22ED" }, "&nsc;": { "codepoints": [8833], "characters": "\u2281" }, "&nsccue;": { "codepoints": [8929], "characters": "\u22E1" }, "&nsce;": { "codepoints": [10928, 824], "characters": "\u2AB0\u0338" }, "&nscr;": { "codepoints": [120003], "characters": "\uD835\uDCC3" }, "&nshortmid;": { "codepoints": [8740], "characters": "\u2224" }, "&nshortparallel;": { "codepoints": [8742], "characters": "\u2226" }, "&nsim;": { "codepoints": [8769], "characters": "\u2241" }, "&nsime;": { "codepoints": [8772], "characters": "\u2244" }, "&nsimeq;": { "codepoints": [8772], "characters": "\u2244" }, "&nsmid;": { "codepoints": [8740], "characters": "\u2224" }, "&nspar;": { "codepoints": [8742], "characters": "\u2226" }, "&nsqsube;": { "codepoints": [8930], "characters": "\u22E2" }, "&nsqsupe;": { "codepoints": [8931], "characters": "\u22E3" }, "&nsub;": { "codepoints": [8836], "characters": "\u2284" }, "&nsubE;": { "codepoints": [10949, 824], "characters": "\u2AC5\u0338" }, "&nsube;": { "codepoints": [8840], "characters": "\u2288" }, "&nsubset;": { "codepoints": [8834, 8402], "characters": "\u2282\u20D2" }, "&nsubseteq;": { "codepoints": [8840], "characters": "\u2288" }, "&nsubseteqq;": { "codepoints": [10949, 824], "characters": "\u2AC5\u0338" }, "&nsucc;": { "codepoints": [8833], "characters": "\u2281" }, "&nsucceq;": { "codepoints": [10928, 824], "characters": "\u2AB0\u0338" }, "&nsup;": { "codepoints": [8837], "characters": "\u2285" }, "&nsupE;": { "codepoints": [10950, 824], "characters": "\u2AC6\u0338" }, "&nsupe;": { "codepoints": [8841], "characters": "\u2289" }, "&nsupset;": { "codepoints": [8835, 8402], "characters": "\u2283\u20D2" }, "&nsupseteq;": { "codepoints": [8841], "characters": "\u2289" }, "&nsupseteqq;": { "codepoints": [10950, 824], "characters": "\u2AC6\u0338" }, "&ntgl;": { "codepoints": [8825], "characters": "\u2279" }, "&ntilde": { "codepoints": [241], "characters": "\u00F1" }, "&ntilde;": { "codepoints": [241], "characters": "\u00F1" }, "&ntlg;": { "codepoints": [8824], "characters": "\u2278" }, "&ntriangleleft;": { "codepoints": [8938], "characters": "\u22EA" }, "&ntrianglelefteq;": { "codepoints": [8940], "characters": "\u22EC" }, "&ntriangleright;": { "codepoints": [8939], "characters": "\u22EB" }, "&ntrianglerighteq;": { "codepoints": [8941], "characters": "\u22ED" }, "&nu;": { "codepoints": [957], "characters": "\u03BD" }, "&num;": { "codepoints": [35], "characters": "\u0023" }, "&numero;": { "codepoints": [8470], "characters": "\u2116" }, "&numsp;": { "codepoints": [8199], "characters": "\u2007" }, "&nvDash;": { "codepoints": [8877], "characters": "\u22AD" }, "&nvHarr;": { "codepoints": [10500], "characters": "\u2904" }, "&nvap;": { "codepoints": [8781, 8402], "characters": "\u224D\u20D2" }, "&nvdash;": { "codepoints": [8876], "characters": "\u22AC" }, "&nvge;": { "codepoints": [8805, 8402], "characters": "\u2265\u20D2" }, "&nvgt;": { "codepoints": [62, 8402], "characters": "\u003E\u20D2" }, "&nvinfin;": { "codepoints": [10718], "characters": "\u29DE" }, "&nvlArr;": { "codepoints": [10498], "characters": "\u2902" }, "&nvle;": { "codepoints": [8804, 8402], "characters": "\u2264\u20D2" }, "&nvlt;": { "codepoints": [60, 8402], "characters": "\u003C\u20D2" }, "&nvltrie;": { "codepoints": [8884, 8402], "characters": "\u22B4\u20D2" }, "&nvrArr;": { "codepoints": [10499], "characters": "\u2903" }, "&nvrtrie;": { "codepoints": [8885, 8402], "characters": "\u22B5\u20D2" }, "&nvsim;": { "codepoints": [8764, 8402], "characters": "\u223C\u20D2" }, "&nwArr;": { "codepoints": [8662], "characters": "\u21D6" }, "&nwarhk;": { "codepoints": [10531], "characters": "\u2923" }, "&nwarr;": { "codepoints": [8598], "characters": "\u2196" }, "&nwarrow;": { "codepoints": [8598], "characters": "\u2196" }, "&nwnear;": { "codepoints": [10535], "characters": "\u2927" }, "&oS;": { "codepoints": [9416], "characters": "\u24C8" }, "&oacute": { "codepoints": [243], "characters": "\u00F3" }, "&oacute;": { "codepoints": [243], "characters": "\u00F3" }, "&oast;": { "codepoints": [8859], "characters": "\u229B" }, "&ocir;": { "codepoints": [8858], "characters": "\u229A" }, "&ocirc": { "codepoints": [244], "characters": "\u00F4" }, "&ocirc;": { "codepoints": [244], "characters": "\u00F4" }, "&ocy;": { "codepoints": [1086], "characters": "\u043E" }, "&odash;": { "codepoints": [8861], "characters": "\u229D" }, "&odblac;": { "codepoints": [337], "characters": "\u0151" }, "&odiv;": { "codepoints": [10808], "characters": "\u2A38" }, "&odot;": { "codepoints": [8857], "characters": "\u2299" }, "&odsold;": { "codepoints": [10684], "characters": "\u29BC" }, "&oelig;": { "codepoints": [339], "characters": "\u0153" }, "&ofcir;": { "codepoints": [10687], "characters": "\u29BF" }, "&ofr;": { "codepoints": [120108], "characters": "\uD835\uDD2C" }, "&ogon;": { "codepoints": [731], "characters": "\u02DB" }, "&ograve": { "codepoints": [242], "characters": "\u00F2" }, "&ograve;": { "codepoints": [242], "characters": "\u00F2" }, "&ogt;": { "codepoints": [10689], "characters": "\u29C1" }, "&ohbar;": { "codepoints": [10677], "characters": "\u29B5" }, "&ohm;": { "codepoints": [937], "characters": "\u03A9" }, "&oint;": { "codepoints": [8750], "characters": "\u222E" }, "&olarr;": { "codepoints": [8634], "characters": "\u21BA" }, "&olcir;": { "codepoints": [10686], "characters": "\u29BE" }, "&olcross;": { "codepoints": [10683], "characters": "\u29BB" }, "&oline;": { "codepoints": [8254], "characters": "\u203E" }, "&olt;": { "codepoints": [10688], "characters": "\u29C0" }, "&omacr;": { "codepoints": [333], "characters": "\u014D" }, "&omega;": { "codepoints": [969], "characters": "\u03C9" }, "&omicron;": { "codepoints": [959], "characters": "\u03BF" }, "&omid;": { "codepoints": [10678], "characters": "\u29B6" }, "&ominus;": { "codepoints": [8854], "characters": "\u2296" }, "&oopf;": { "codepoints": [120160], "characters": "\uD835\uDD60" }, "&opar;": { "codepoints": [10679], "characters": "\u29B7" }, "&operp;": { "codepoints": [10681], "characters": "\u29B9" }, "&oplus;": { "codepoints": [8853], "characters": "\u2295" }, "&or;": { "codepoints": [8744], "characters": "\u2228" }, "&orarr;": { "codepoints": [8635], "characters": "\u21BB" }, "&ord;": { "codepoints": [10845], "characters": "\u2A5D" }, "&order;": { "codepoints": [8500], "characters": "\u2134" }, "&orderof;": { "codepoints": [8500], "characters": "\u2134" }, "&ordf": { "codepoints": [170], "characters": "\u00AA" }, "&ordf;": { "codepoints": [170], "characters": "\u00AA" }, "&ordm": { "codepoints": [186], "characters": "\u00BA" }, "&ordm;": { "codepoints": [186], "characters": "\u00BA" }, "&origof;": { "codepoints": [8886], "characters": "\u22B6" }, "&oror;": { "codepoints": [10838], "characters": "\u2A56" }, "&orslope;": { "codepoints": [10839], "characters": "\u2A57" }, "&orv;": { "codepoints": [10843], "characters": "\u2A5B" }, "&oscr;": { "codepoints": [8500], "characters": "\u2134" }, "&oslash": { "codepoints": [248], "characters": "\u00F8" }, "&oslash;": { "codepoints": [248], "characters": "\u00F8" }, "&osol;": { "codepoints": [8856], "characters": "\u2298" }, "&otilde": { "codepoints": [245], "characters": "\u00F5" }, "&otilde;": { "codepoints": [245], "characters": "\u00F5" }, "&otimes;": { "codepoints": [8855], "characters": "\u2297" }, "&otimesas;": { "codepoints": [10806], "characters": "\u2A36" }, "&ouml": { "codepoints": [246], "characters": "\u00F6" }, "&ouml;": { "codepoints": [246], "characters": "\u00F6" }, "&ovbar;": { "codepoints": [9021], "characters": "\u233D" }, "&par;": { "codepoints": [8741], "characters": "\u2225" }, "&para": { "codepoints": [182], "characters": "\u00B6" }, "&para;": { "codepoints": [182], "characters": "\u00B6" }, "&parallel;": { "codepoints": [8741], "characters": "\u2225" }, "&parsim;": { "codepoints": [10995], "characters": "\u2AF3" }, "&parsl;": { "codepoints": [11005], "characters": "\u2AFD" }, "&part;": { "codepoints": [8706], "characters": "\u2202" }, "&pcy;": { "codepoints": [1087], "characters": "\u043F" }, "&percnt;": { "codepoints": [37], "characters": "\u0025" }, "&period;": { "codepoints": [46], "characters": "\u002E" }, "&permil;": { "codepoints": [8240], "characters": "\u2030" }, "&perp;": { "codepoints": [8869], "characters": "\u22A5" }, "&pertenk;": { "codepoints": [8241], "characters": "\u2031" }, "&pfr;": { "codepoints": [120109], "characters": "\uD835\uDD2D" }, "&phi;": { "codepoints": [966], "characters": "\u03C6" }, "&phiv;": { "codepoints": [981], "characters": "\u03D5" }, "&phmmat;": { "codepoints": [8499], "characters": "\u2133" }, "&phone;": { "codepoints": [9742], "characters": "\u260E" }, "&pi;": { "codepoints": [960], "characters": "\u03C0" }, "&pitchfork;": { "codepoints": [8916], "characters": "\u22D4" }, "&piv;": { "codepoints": [982], "characters": "\u03D6" }, "&planck;": { "codepoints": [8463], "characters": "\u210F" }, "&planckh;": { "codepoints": [8462], "characters": "\u210E" }, "&plankv;": { "codepoints": [8463], "characters": "\u210F" }, "&plus;": { "codepoints": [43], "characters": "\u002B" }, "&plusacir;": { "codepoints": [10787], "characters": "\u2A23" }, "&plusb;": { "codepoints": [8862], "characters": "\u229E" }, "&pluscir;": { "codepoints": [10786], "characters": "\u2A22" }, "&plusdo;": { "codepoints": [8724], "characters": "\u2214" }, "&plusdu;": { "codepoints": [10789], "characters": "\u2A25" }, "&pluse;": { "codepoints": [10866], "characters": "\u2A72" }, "&plusmn": { "codepoints": [177], "characters": "\u00B1" }, "&plusmn;": { "codepoints": [177], "characters": "\u00B1" }, "&plussim;": { "codepoints": [10790], "characters": "\u2A26" }, "&plustwo;": { "codepoints": [10791], "characters": "\u2A27" }, "&pm;": { "codepoints": [177], "characters": "\u00B1" }, "&pointint;": { "codepoints": [10773], "characters": "\u2A15" }, "&popf;": { "codepoints": [120161], "characters": "\uD835\uDD61" }, "&pound": { "codepoints": [163], "characters": "\u00A3" }, "&pound;": { "codepoints": [163], "characters": "\u00A3" }, "&pr;": { "codepoints": [8826], "characters": "\u227A" }, "&prE;": { "codepoints": [10931], "characters": "\u2AB3" }, "&prap;": { "codepoints": [10935], "characters": "\u2AB7" }, "&prcue;": { "codepoints": [8828], "characters": "\u227C" }, "&pre;": { "codepoints": [10927], "characters": "\u2AAF" }, "&prec;": { "codepoints": [8826], "characters": "\u227A" }, "&precapprox;": { "codepoints": [10935], "characters": "\u2AB7" }, "&preccurlyeq;": { "codepoints": [8828], "characters": "\u227C" }, "&preceq;": { "codepoints": [10927], "characters": "\u2AAF" }, "&precnapprox;": { "codepoints": [10937], "characters": "\u2AB9" }, "&precneqq;": { "codepoints": [10933], "characters": "\u2AB5" }, "&precnsim;": { "codepoints": [8936], "characters": "\u22E8" }, "&precsim;": { "codepoints": [8830], "characters": "\u227E" }, "&prime;": { "codepoints": [8242], "characters": "\u2032" }, "&primes;": { "codepoints": [8473], "characters": "\u2119" }, "&prnE;": { "codepoints": [10933], "characters": "\u2AB5" }, "&prnap;": { "codepoints": [10937], "characters": "\u2AB9" }, "&prnsim;": { "codepoints": [8936], "characters": "\u22E8" }, "&prod;": { "codepoints": [8719], "characters": "\u220F" }, "&profalar;": { "codepoints": [9006], "characters": "\u232E" }, "&profline;": { "codepoints": [8978], "characters": "\u2312" }, "&profsurf;": { "codepoints": [8979], "characters": "\u2313" }, "&prop;": { "codepoints": [8733], "characters": "\u221D" }, "&propto;": { "codepoints": [8733], "characters": "\u221D" }, "&prsim;": { "codepoints": [8830], "characters": "\u227E" }, "&prurel;": { "codepoints": [8880], "characters": "\u22B0" }, "&pscr;": { "codepoints": [120005], "characters": "\uD835\uDCC5" }, "&psi;": { "codepoints": [968], "characters": "\u03C8" }, "&puncsp;": { "codepoints": [8200], "characters": "\u2008" }, "&qfr;": { "codepoints": [120110], "characters": "\uD835\uDD2E" }, "&qint;": { "codepoints": [10764], "characters": "\u2A0C" }, "&qopf;": { "codepoints": [120162], "characters": "\uD835\uDD62" }, "&qprime;": { "codepoints": [8279], "characters": "\u2057" }, "&qscr;": { "codepoints": [120006], "characters": "\uD835\uDCC6" }, "&quaternions;": { "codepoints": [8461], "characters": "\u210D" }, "&quatint;": { "codepoints": [10774], "characters": "\u2A16" }, "&quest;": { "codepoints": [63], "characters": "\u003F" }, "&questeq;": { "codepoints": [8799], "characters": "\u225F" }, "&quot": { "codepoints": [34], "characters": "\u0022" }, "&quot;": { "codepoints": [34], "characters": "\u0022" }, "&rAarr;": { "codepoints": [8667], "characters": "\u21DB" }, "&rArr;": { "codepoints": [8658], "characters": "\u21D2" }, "&rAtail;": { "codepoints": [10524], "characters": "\u291C" }, "&rBarr;": { "codepoints": [10511], "characters": "\u290F" }, "&rHar;": { "codepoints": [10596], "characters": "\u2964" }, "&race;": { "codepoints": [8765, 817], "characters": "\u223D\u0331" }, "&racute;": { "codepoints": [341], "characters": "\u0155" }, "&radic;": { "codepoints": [8730], "characters": "\u221A" }, "&raemptyv;": { "codepoints": [10675], "characters": "\u29B3" }, "&rang;": { "codepoints": [10217], "characters": "\u27E9" }, "&rangd;": { "codepoints": [10642], "characters": "\u2992" }, "&range;": { "codepoints": [10661], "characters": "\u29A5" }, "&rangle;": { "codepoints": [10217], "characters": "\u27E9" }, "&raquo": { "codepoints": [187], "characters": "\u00BB" }, "&raquo;": { "codepoints": [187], "characters": "\u00BB" }, "&rarr;": { "codepoints": [8594], "characters": "\u2192" }, "&rarrap;": { "codepoints": [10613], "characters": "\u2975" }, "&rarrb;": { "codepoints": [8677], "characters": "\u21E5" }, "&rarrbfs;": { "codepoints": [10528], "characters": "\u2920" }, "&rarrc;": { "codepoints": [10547], "characters": "\u2933" }, "&rarrfs;": { "codepoints": [10526], "characters": "\u291E" }, "&rarrhk;": { "codepoints": [8618], "characters": "\u21AA" }, "&rarrlp;": { "codepoints": [8620], "characters": "\u21AC" }, "&rarrpl;": { "codepoints": [10565], "characters": "\u2945" }, "&rarrsim;": { "codepoints": [10612], "characters": "\u2974" }, "&rarrtl;": { "codepoints": [8611], "characters": "\u21A3" }, "&rarrw;": { "codepoints": [8605], "characters": "\u219D" }, "&ratail;": { "codepoints": [10522], "characters": "\u291A" }, "&ratio;": { "codepoints": [8758], "characters": "\u2236" }, "&rationals;": { "codepoints": [8474], "characters": "\u211A" }, "&rbarr;": { "codepoints": [10509], "characters": "\u290D" }, "&rbbrk;": { "codepoints": [10099], "characters": "\u2773" }, "&rbrace;": { "codepoints": [125], "characters": "\u007D" }, "&rbrack;": { "codepoints": [93], "characters": "\u005D" }, "&rbrke;": { "codepoints": [10636], "characters": "\u298C" }, "&rbrksld;": { "codepoints": [10638], "characters": "\u298E" }, "&rbrkslu;": { "codepoints": [10640], "characters": "\u2990" }, "&rcaron;": { "codepoints": [345], "characters": "\u0159" }, "&rcedil;": { "codepoints": [343], "characters": "\u0157" }, "&rceil;": { "codepoints": [8969], "characters": "\u2309" }, "&rcub;": { "codepoints": [125], "characters": "\u007D" }, "&rcy;": { "codepoints": [1088], "characters": "\u0440" }, "&rdca;": { "codepoints": [10551], "characters": "\u2937" }, "&rdldhar;": { "codepoints": [10601], "characters": "\u2969" }, "&rdquo;": { "codepoints": [8221], "characters": "\u201D" }, "&rdquor;": { "codepoints": [8221], "characters": "\u201D" }, "&rdsh;": { "codepoints": [8627], "characters": "\u21B3" }, "&real;": { "codepoints": [8476], "characters": "\u211C" }, "&realine;": { "codepoints": [8475], "characters": "\u211B" }, "&realpart;": { "codepoints": [8476], "characters": "\u211C" }, "&reals;": { "codepoints": [8477], "characters": "\u211D" }, "&rect;": { "codepoints": [9645], "characters": "\u25AD" }, "&reg": { "codepoints": [174], "characters": "\u00AE" }, "&reg;": { "codepoints": [174], "characters": "\u00AE" }, "&rfisht;": { "codepoints": [10621], "characters": "\u297D" }, "&rfloor;": { "codepoints": [8971], "characters": "\u230B" }, "&rfr;": { "codepoints": [120111], "characters": "\uD835\uDD2F" }, "&rhard;": { "codepoints": [8641], "characters": "\u21C1" }, "&rharu;": { "codepoints": [8640], "characters": "\u21C0" }, "&rharul;": { "codepoints": [10604], "characters": "\u296C" }, "&rho;": { "codepoints": [961], "characters": "\u03C1" }, "&rhov;": { "codepoints": [1009], "characters": "\u03F1" }, "&rightarrow;": { "codepoints": [8594], "characters": "\u2192" }, "&rightarrowtail;": { "codepoints": [8611], "characters": "\u21A3" }, "&rightharpoondown;": { "codepoints": [8641], "characters": "\u21C1" }, "&rightharpoonup;": { "codepoints": [8640], "characters": "\u21C0" }, "&rightleftarrows;": { "codepoints": [8644], "characters": "\u21C4" }, "&rightleftharpoons;": { "codepoints": [8652], "characters": "\u21CC" }, "&rightrightarrows;": { "codepoints": [8649], "characters": "\u21C9" }, "&rightsquigarrow;": { "codepoints": [8605], "characters": "\u219D" }, "&rightthreetimes;": { "codepoints": [8908], "characters": "\u22CC" }, "&ring;": { "codepoints": [730], "characters": "\u02DA" }, "&risingdotseq;": { "codepoints": [8787], "characters": "\u2253" }, "&rlarr;": { "codepoints": [8644], "characters": "\u21C4" }, "&rlhar;": { "codepoints": [8652], "characters": "\u21CC" }, "&rlm;": { "codepoints": [8207], "characters": "\u200F" }, "&rmoust;": { "codepoints": [9137], "characters": "\u23B1" }, "&rmoustache;": { "codepoints": [9137], "characters": "\u23B1" }, "&rnmid;": { "codepoints": [10990], "characters": "\u2AEE" }, "&roang;": { "codepoints": [10221], "characters": "\u27ED" }, "&roarr;": { "codepoints": [8702], "characters": "\u21FE" }, "&robrk;": { "codepoints": [10215], "characters": "\u27E7" }, "&ropar;": { "codepoints": [10630], "characters": "\u2986" }, "&ropf;": { "codepoints": [120163], "characters": "\uD835\uDD63" }, "&roplus;": { "codepoints": [10798], "characters": "\u2A2E" }, "&rotimes;": { "codepoints": [10805], "characters": "\u2A35" }, "&rpar;": { "codepoints": [41], "characters": "\u0029" }, "&rpargt;": { "codepoints": [10644], "characters": "\u2994" }, "&rppolint;": { "codepoints": [10770], "characters": "\u2A12" }, "&rrarr;": { "codepoints": [8649], "characters": "\u21C9" }, "&rsaquo;": { "codepoints": [8250], "characters": "\u203A" }, "&rscr;": { "codepoints": [120007], "characters": "\uD835\uDCC7" }, "&rsh;": { "codepoints": [8625], "characters": "\u21B1" }, "&rsqb;": { "codepoints": [93], "characters": "\u005D" }, "&rsquo;": { "codepoints": [8217], "characters": "\u2019" }, "&rsquor;": { "codepoints": [8217], "characters": "\u2019" }, "&rthree;": { "codepoints": [8908], "characters": "\u22CC" }, "&rtimes;": { "codepoints": [8906], "characters": "\u22CA" }, "&rtri;": { "codepoints": [9657], "characters": "\u25B9" }, "&rtrie;": { "codepoints": [8885], "characters": "\u22B5" }, "&rtrif;": { "codepoints": [9656], "characters": "\u25B8" }, "&rtriltri;": { "codepoints": [10702], "characters": "\u29CE" }, "&ruluhar;": { "codepoints": [10600], "characters": "\u2968" }, "&rx;": { "codepoints": [8478], "characters": "\u211E" }, "&sacute;": { "codepoints": [347], "characters": "\u015B" }, "&sbquo;": { "codepoints": [8218], "characters": "\u201A" }, "&sc;": { "codepoints": [8827], "characters": "\u227B" }, "&scE;": { "codepoints": [10932], "characters": "\u2AB4" }, "&scap;": { "codepoints": [10936], "characters": "\u2AB8" }, "&scaron;": { "codepoints": [353], "characters": "\u0161" }, "&sccue;": { "codepoints": [8829], "characters": "\u227D" }, "&sce;": { "codepoints": [10928], "characters": "\u2AB0" }, "&scedil;": { "codepoints": [351], "characters": "\u015F" }, "&scirc;": { "codepoints": [349], "characters": "\u015D" }, "&scnE;": { "codepoints": [10934], "characters": "\u2AB6" }, "&scnap;": { "codepoints": [10938], "characters": "\u2ABA" }, "&scnsim;": { "codepoints": [8937], "characters": "\u22E9" }, "&scpolint;": { "codepoints": [10771], "characters": "\u2A13" }, "&scsim;": { "codepoints": [8831], "characters": "\u227F" }, "&scy;": { "codepoints": [1089], "characters": "\u0441" }, "&sdot;": { "codepoints": [8901], "characters": "\u22C5" }, "&sdotb;": { "codepoints": [8865], "characters": "\u22A1" }, "&sdote;": { "codepoints": [10854], "characters": "\u2A66" }, "&seArr;": { "codepoints": [8664], "characters": "\u21D8" }, "&searhk;": { "codepoints": [10533], "characters": "\u2925" }, "&searr;": { "codepoints": [8600], "characters": "\u2198" }, "&searrow;": { "codepoints": [8600], "characters": "\u2198" }, "&sect": { "codepoints": [167], "characters": "\u00A7" }, "&sect;": { "codepoints": [167], "characters": "\u00A7" }, "&semi;": { "codepoints": [59], "characters": "\u003B" }, "&seswar;": { "codepoints": [10537], "characters": "\u2929" }, "&setminus;": { "codepoints": [8726], "characters": "\u2216" }, "&setmn;": { "codepoints": [8726], "characters": "\u2216" }, "&sext;": { "codepoints": [10038], "characters": "\u2736" }, "&sfr;": { "codepoints": [120112], "characters": "\uD835\uDD30" }, "&sfrown;": { "codepoints": [8994], "characters": "\u2322" }, "&sharp;": { "codepoints": [9839], "characters": "\u266F" }, "&shchcy;": { "codepoints": [1097], "characters": "\u0449" }, "&shcy;": { "codepoints": [1096], "characters": "\u0448" }, "&shortmid;": { "codepoints": [8739], "characters": "\u2223" }, "&shortparallel;": { "codepoints": [8741], "characters": "\u2225" }, "&shy": { "codepoints": [173], "characters": "\u00AD" }, "&shy;": { "codepoints": [173], "characters": "\u00AD" }, "&sigma;": { "codepoints": [963], "characters": "\u03C3" }, "&sigmaf;": { "codepoints": [962], "characters": "\u03C2" }, "&sigmav;": { "codepoints": [962], "characters": "\u03C2" }, "&sim;": { "codepoints": [8764], "characters": "\u223C" }, "&simdot;": { "codepoints": [10858], "characters": "\u2A6A" }, "&sime;": { "codepoints": [8771], "characters": "\u2243" }, "&simeq;": { "codepoints": [8771], "characters": "\u2243" }, "&simg;": { "codepoints": [10910], "characters": "\u2A9E" }, "&simgE;": { "codepoints": [10912], "characters": "\u2AA0" }, "&siml;": { "codepoints": [10909], "characters": "\u2A9D" }, "&simlE;": { "codepoints": [10911], "characters": "\u2A9F" }, "&simne;": { "codepoints": [8774], "characters": "\u2246" }, "&simplus;": { "codepoints": [10788], "characters": "\u2A24" }, "&simrarr;": { "codepoints": [10610], "characters": "\u2972" }, "&slarr;": { "codepoints": [8592], "characters": "\u2190" }, "&smallsetminus;": { "codepoints": [8726], "characters": "\u2216" }, "&smashp;": { "codepoints": [10803], "characters": "\u2A33" }, "&smeparsl;": { "codepoints": [10724], "characters": "\u29E4" }, "&smid;": { "codepoints": [8739], "characters": "\u2223" }, "&smile;": { "codepoints": [8995], "characters": "\u2323" }, "&smt;": { "codepoints": [10922], "characters": "\u2AAA" }, "&smte;": { "codepoints": [10924], "characters": "\u2AAC" }, "&smtes;": { "codepoints": [10924, 65024], "characters": "\u2AAC\uFE00" }, "&softcy;": { "codepoints": [1100], "characters": "\u044C" }, "&sol;": { "codepoints": [47], "characters": "\u002F" }, "&solb;": { "codepoints": [10692], "characters": "\u29C4" }, "&solbar;": { "codepoints": [9023], "characters": "\u233F" }, "&sopf;": { "codepoints": [120164], "characters": "\uD835\uDD64" }, "&spades;": { "codepoints": [9824], "characters": "\u2660" }, "&spadesuit;": { "codepoints": [9824], "characters": "\u2660" }, "&spar;": { "codepoints": [8741], "characters": "\u2225" }, "&sqcap;": { "codepoints": [8851], "characters": "\u2293" }, "&sqcaps;": { "codepoints": [8851, 65024], "characters": "\u2293\uFE00" }, "&sqcup;": { "codepoints": [8852], "characters": "\u2294" }, "&sqcups;": { "codepoints": [8852, 65024], "characters": "\u2294\uFE00" }, "&sqsub;": { "codepoints": [8847], "characters": "\u228F" }, "&sqsube;": { "codepoints": [8849], "characters": "\u2291" }, "&sqsubset;": { "codepoints": [8847], "characters": "\u228F" }, "&sqsubseteq;": { "codepoints": [8849], "characters": "\u2291" }, "&sqsup;": { "codepoints": [8848], "characters": "\u2290" }, "&sqsupe;": { "codepoints": [8850], "characters": "\u2292" }, "&sqsupset;": { "codepoints": [8848], "characters": "\u2290" }, "&sqsupseteq;": { "codepoints": [8850], "characters": "\u2292" }, "&squ;": { "codepoints": [9633], "characters": "\u25A1" }, "&square;": { "codepoints": [9633], "characters": "\u25A1" }, "&squarf;": { "codepoints": [9642], "characters": "\u25AA" }, "&squf;": { "codepoints": [9642], "characters": "\u25AA" }, "&srarr;": { "codepoints": [8594], "characters": "\u2192" }, "&sscr;": { "codepoints": [120008], "characters": "\uD835\uDCC8" }, "&ssetmn;": { "codepoints": [8726], "characters": "\u2216" }, "&ssmile;": { "codepoints": [8995], "characters": "\u2323" }, "&sstarf;": { "codepoints": [8902], "characters": "\u22C6" }, "&star;": { "codepoints": [9734], "characters": "\u2606" }, "&starf;": { "codepoints": [9733], "characters": "\u2605" }, "&straightepsilon;": { "codepoints": [1013], "characters": "\u03F5" }, "&straightphi;": { "codepoints": [981], "characters": "\u03D5" }, "&strns;": { "codepoints": [175], "characters": "\u00AF" }, "&sub;": { "codepoints": [8834], "characters": "\u2282" }, "&subE;": { "codepoints": [10949], "characters": "\u2AC5" }, "&subdot;": { "codepoints": [10941], "characters": "\u2ABD" }, "&sube;": { "codepoints": [8838], "characters": "\u2286" }, "&subedot;": { "codepoints": [10947], "characters": "\u2AC3" }, "&submult;": { "codepoints": [10945], "characters": "\u2AC1" }, "&subnE;": { "codepoints": [10955], "characters": "\u2ACB" }, "&subne;": { "codepoints": [8842], "characters": "\u228A" }, "&subplus;": { "codepoints": [10943], "characters": "\u2ABF" }, "&subrarr;": { "codepoints": [10617], "characters": "\u2979" }, "&subset;": { "codepoints": [8834], "characters": "\u2282" }, "&subseteq;": { "codepoints": [8838], "characters": "\u2286" }, "&subseteqq;": { "codepoints": [10949], "characters": "\u2AC5" }, "&subsetneq;": { "codepoints": [8842], "characters": "\u228A" }, "&subsetneqq;": { "codepoints": [10955], "characters": "\u2ACB" }, "&subsim;": { "codepoints": [10951], "characters": "\u2AC7" }, "&subsub;": { "codepoints": [10965], "characters": "\u2AD5" }, "&subsup;": { "codepoints": [10963], "characters": "\u2AD3" }, "&succ;": { "codepoints": [8827], "characters": "\u227B" }, "&succapprox;": { "codepoints": [10936], "characters": "\u2AB8" }, "&succcurlyeq;": { "codepoints": [8829], "characters": "\u227D" }, "&succeq;": { "codepoints": [10928], "characters": "\u2AB0" }, "&succnapprox;": { "codepoints": [10938], "characters": "\u2ABA" }, "&succneqq;": { "codepoints": [10934], "characters": "\u2AB6" }, "&succnsim;": { "codepoints": [8937], "characters": "\u22E9" }, "&succsim;": { "codepoints": [8831], "characters": "\u227F" }, "&sum;": { "codepoints": [8721], "characters": "\u2211" }, "&sung;": { "codepoints": [9834], "characters": "\u266A" }, "&sup1": { "codepoints": [185], "characters": "\u00B9" }, "&sup1;": { "codepoints": [185], "characters": "\u00B9" }, "&sup2": { "codepoints": [178], "characters": "\u00B2" }, "&sup2;": { "codepoints": [178], "characters": "\u00B2" }, "&sup3": { "codepoints": [179], "characters": "\u00B3" }, "&sup3;": { "codepoints": [179], "characters": "\u00B3" }, "&sup;": { "codepoints": [8835], "characters": "\u2283" }, "&supE;": { "codepoints": [10950], "characters": "\u2AC6" }, "&supdot;": { "codepoints": [10942], "characters": "\u2ABE" }, "&supdsub;": { "codepoints": [10968], "characters": "\u2AD8" }, "&supe;": { "codepoints": [8839], "characters": "\u2287" }, "&supedot;": { "codepoints": [10948], "characters": "\u2AC4" }, "&suphsol;": { "codepoints": [10185], "characters": "\u27C9" }, "&suphsub;": { "codepoints": [10967], "characters": "\u2AD7" }, "&suplarr;": { "codepoints": [10619], "characters": "\u297B" }, "&supmult;": { "codepoints": [10946], "characters": "\u2AC2" }, "&supnE;": { "codepoints": [10956], "characters": "\u2ACC" }, "&supne;": { "codepoints": [8843], "characters": "\u228B" }, "&supplus;": { "codepoints": [10944], "characters": "\u2AC0" }, "&supset;": { "codepoints": [8835], "characters": "\u2283" }, "&supseteq;": { "codepoints": [8839], "characters": "\u2287" }, "&supseteqq;": { "codepoints": [10950], "characters": "\u2AC6" }, "&supsetneq;": { "codepoints": [8843], "characters": "\u228B" }, "&supsetneqq;": { "codepoints": [10956], "characters": "\u2ACC" }, "&supsim;": { "codepoints": [10952], "characters": "\u2AC8" }, "&supsub;": { "codepoints": [10964], "characters": "\u2AD4" }, "&supsup;": { "codepoints": [10966], "characters": "\u2AD6" }, "&swArr;": { "codepoints": [8665], "characters": "\u21D9" }, "&swarhk;": { "codepoints": [10534], "characters": "\u2926" }, "&swarr;": { "codepoints": [8601], "characters": "\u2199" }, "&swarrow;": { "codepoints": [8601], "characters": "\u2199" }, "&swnwar;": { "codepoints": [10538], "characters": "\u292A" }, "&szlig": { "codepoints": [223], "characters": "\u00DF" }, "&szlig;": { "codepoints": [223], "characters": "\u00DF" }, "&target;": { "codepoints": [8982], "characters": "\u2316" }, "&tau;": { "codepoints": [964], "characters": "\u03C4" }, "&tbrk;": { "codepoints": [9140], "characters": "\u23B4" }, "&tcaron;": { "codepoints": [357], "characters": "\u0165" }, "&tcedil;": { "codepoints": [355], "characters": "\u0163" }, "&tcy;": { "codepoints": [1090], "characters": "\u0442" }, "&tdot;": { "codepoints": [8411], "characters": "\u20DB" }, "&telrec;": { "codepoints": [8981], "characters": "\u2315" }, "&tfr;": { "codepoints": [120113], "characters": "\uD835\uDD31" }, "&there4;": { "codepoints": [8756], "characters": "\u2234" }, "&therefore;": { "codepoints": [8756], "characters": "\u2234" }, "&theta;": { "codepoints": [952], "characters": "\u03B8" }, "&thetasym;": { "codepoints": [977], "characters": "\u03D1" }, "&thetav;": { "codepoints": [977], "characters": "\u03D1" }, "&thickapprox;": { "codepoints": [8776], "characters": "\u2248" }, "&thicksim;": { "codepoints": [8764], "characters": "\u223C" }, "&thinsp;": { "codepoints": [8201], "characters": "\u2009" }, "&thkap;": { "codepoints": [8776], "characters": "\u2248" }, "&thksim;": { "codepoints": [8764], "characters": "\u223C" }, "&thorn": { "codepoints": [254], "characters": "\u00FE" }, "&thorn;": { "codepoints": [254], "characters": "\u00FE" }, "&tilde;": { "codepoints": [732], "characters": "\u02DC" }, "&times": { "codepoints": [215], "characters": "\u00D7" }, "&times;": { "codepoints": [215], "characters": "\u00D7" }, "&timesb;": { "codepoints": [8864], "characters": "\u22A0" }, "&timesbar;": { "codepoints": [10801], "characters": "\u2A31" }, "&timesd;": { "codepoints": [10800], "characters": "\u2A30" }, "&tint;": { "codepoints": [8749], "characters": "\u222D" }, "&toea;": { "codepoints": [10536], "characters": "\u2928" }, "&top;": { "codepoints": [8868], "characters": "\u22A4" }, "&topbot;": { "codepoints": [9014], "characters": "\u2336" }, "&topcir;": { "codepoints": [10993], "characters": "\u2AF1" }, "&topf;": { "codepoints": [120165], "characters": "\uD835\uDD65" }, "&topfork;": { "codepoints": [10970], "characters": "\u2ADA" }, "&tosa;": { "codepoints": [10537], "characters": "\u2929" }, "&tprime;": { "codepoints": [8244], "characters": "\u2034" }, "&trade;": { "codepoints": [8482], "characters": "\u2122" }, "&triangle;": { "codepoints": [9653], "characters": "\u25B5" }, "&triangledown;": { "codepoints": [9663], "characters": "\u25BF" }, "&triangleleft;": { "codepoints": [9667], "characters": "\u25C3" }, "&trianglelefteq;": { "codepoints": [8884], "characters": "\u22B4" }, "&triangleq;": { "codepoints": [8796], "characters": "\u225C" }, "&triangleright;": { "codepoints": [9657], "characters": "\u25B9" }, "&trianglerighteq;": { "codepoints": [8885], "characters": "\u22B5" }, "&tridot;": { "codepoints": [9708], "characters": "\u25EC" }, "&trie;": { "codepoints": [8796], "characters": "\u225C" }, "&triminus;": { "codepoints": [10810], "characters": "\u2A3A" }, "&triplus;": { "codepoints": [10809], "characters": "\u2A39" }, "&trisb;": { "codepoints": [10701], "characters": "\u29CD" }, "&tritime;": { "codepoints": [10811], "characters": "\u2A3B" }, "&trpezium;": { "codepoints": [9186], "characters": "\u23E2" }, "&tscr;": { "codepoints": [120009], "characters": "\uD835\uDCC9" }, "&tscy;": { "codepoints": [1094], "characters": "\u0446" }, "&tshcy;": { "codepoints": [1115], "characters": "\u045B" }, "&tstrok;": { "codepoints": [359], "characters": "\u0167" }, "&twixt;": { "codepoints": [8812], "characters": "\u226C" }, "&twoheadleftarrow;": { "codepoints": [8606], "characters": "\u219E" }, "&twoheadrightarrow;": { "codepoints": [8608], "characters": "\u21A0" }, "&uArr;": { "codepoints": [8657], "characters": "\u21D1" }, "&uHar;": { "codepoints": [10595], "characters": "\u2963" }, "&uacute": { "codepoints": [250], "characters": "\u00FA" }, "&uacute;": { "codepoints": [250], "characters": "\u00FA" }, "&uarr;": { "codepoints": [8593], "characters": "\u2191" }, "&ubrcy;": { "codepoints": [1118], "characters": "\u045E" }, "&ubreve;": { "codepoints": [365], "characters": "\u016D" }, "&ucirc": { "codepoints": [251], "characters": "\u00FB" }, "&ucirc;": { "codepoints": [251], "characters": "\u00FB" }, "&ucy;": { "codepoints": [1091], "characters": "\u0443" }, "&udarr;": { "codepoints": [8645], "characters": "\u21C5" }, "&udblac;": { "codepoints": [369], "characters": "\u0171" }, "&udhar;": { "codepoints": [10606], "characters": "\u296E" }, "&ufisht;": { "codepoints": [10622], "characters": "\u297E" }, "&ufr;": { "codepoints": [120114], "characters": "\uD835\uDD32" }, "&ugrave": { "codepoints": [249], "characters": "\u00F9" }, "&ugrave;": { "codepoints": [249], "characters": "\u00F9" }, "&uharl;": { "codepoints": [8639], "characters": "\u21BF" }, "&uharr;": { "codepoints": [8638], "characters": "\u21BE" }, "&uhblk;": { "codepoints": [9600], "characters": "\u2580" }, "&ulcorn;": { "codepoints": [8988], "characters": "\u231C" }, "&ulcorner;": { "codepoints": [8988], "characters": "\u231C" }, "&ulcrop;": { "codepoints": [8975], "characters": "\u230F" }, "&ultri;": { "codepoints": [9720], "characters": "\u25F8" }, "&umacr;": { "codepoints": [363], "characters": "\u016B" }, "&uml": { "codepoints": [168], "characters": "\u00A8" }, "&uml;": { "codepoints": [168], "characters": "\u00A8" }, "&uogon;": { "codepoints": [371], "characters": "\u0173" }, "&uopf;": { "codepoints": [120166], "characters": "\uD835\uDD66" }, "&uparrow;": { "codepoints": [8593], "characters": "\u2191" }, "&updownarrow;": { "codepoints": [8597], "characters": "\u2195" }, "&upharpoonleft;": { "codepoints": [8639], "characters": "\u21BF" }, "&upharpoonright;": { "codepoints": [8638], "characters": "\u21BE" }, "&uplus;": { "codepoints": [8846], "characters": "\u228E" }, "&upsi;": { "codepoints": [965], "characters": "\u03C5" }, "&upsih;": { "codepoints": [978], "characters": "\u03D2" }, "&upsilon;": { "codepoints": [965], "characters": "\u03C5" }, "&upuparrows;": { "codepoints": [8648], "characters": "\u21C8" }, "&urcorn;": { "codepoints": [8989], "characters": "\u231D" }, "&urcorner;": { "codepoints": [8989], "characters": "\u231D" }, "&urcrop;": { "codepoints": [8974], "characters": "\u230E" }, "&uring;": { "codepoints": [367], "characters": "\u016F" }, "&urtri;": { "codepoints": [9721], "characters": "\u25F9" }, "&uscr;": { "codepoints": [120010], "characters": "\uD835\uDCCA" }, "&utdot;": { "codepoints": [8944], "characters": "\u22F0" }, "&utilde;": { "codepoints": [361], "characters": "\u0169" }, "&utri;": { "codepoints": [9653], "characters": "\u25B5" }, "&utrif;": { "codepoints": [9652], "characters": "\u25B4" }, "&uuarr;": { "codepoints": [8648], "characters": "\u21C8" }, "&uuml": { "codepoints": [252], "characters": "\u00FC" }, "&uuml;": { "codepoints": [252], "characters": "\u00FC" }, "&uwangle;": { "codepoints": [10663], "characters": "\u29A7" }, "&vArr;": { "codepoints": [8661], "characters": "\u21D5" }, "&vBar;": { "codepoints": [10984], "characters": "\u2AE8" }, "&vBarv;": { "codepoints": [10985], "characters": "\u2AE9" }, "&vDash;": { "codepoints": [8872], "characters": "\u22A8" }, "&vangrt;": { "codepoints": [10652], "characters": "\u299C" }, "&varepsilon;": { "codepoints": [1013], "characters": "\u03F5" }, "&varkappa;": { "codepoints": [1008], "characters": "\u03F0" }, "&varnothing;": { "codepoints": [8709], "characters": "\u2205" }, "&varphi;": { "codepoints": [981], "characters": "\u03D5" }, "&varpi;": { "codepoints": [982], "characters": "\u03D6" }, "&varpropto;": { "codepoints": [8733], "characters": "\u221D" }, "&varr;": { "codepoints": [8597], "characters": "\u2195" }, "&varrho;": { "codepoints": [1009], "characters": "\u03F1" }, "&varsigma;": { "codepoints": [962], "characters": "\u03C2" }, "&varsubsetneq;": { "codepoints": [8842, 65024], "characters": "\u228A\uFE00" }, "&varsubsetneqq;": { "codepoints": [10955, 65024], "characters": "\u2ACB\uFE00" }, "&varsupsetneq;": { "codepoints": [8843, 65024], "characters": "\u228B\uFE00" }, "&varsupsetneqq;": { "codepoints": [10956, 65024], "characters": "\u2ACC\uFE00" }, "&vartheta;": { "codepoints": [977], "characters": "\u03D1" }, "&vartriangleleft;": { "codepoints": [8882], "characters": "\u22B2" }, "&vartriangleright;": { "codepoints": [8883], "characters": "\u22B3" }, "&vcy;": { "codepoints": [1074], "characters": "\u0432" }, "&vdash;": { "codepoints": [8866], "characters": "\u22A2" }, "&vee;": { "codepoints": [8744], "characters": "\u2228" }, "&veebar;": { "codepoints": [8891], "characters": "\u22BB" }, "&veeeq;": { "codepoints": [8794], "characters": "\u225A" }, "&vellip;": { "codepoints": [8942], "characters": "\u22EE" }, "&verbar;": { "codepoints": [124], "characters": "\u007C" }, "&vert;": { "codepoints": [124], "characters": "\u007C" }, "&vfr;": { "codepoints": [120115], "characters": "\uD835\uDD33" }, "&vltri;": { "codepoints": [8882], "characters": "\u22B2" }, "&vnsub;": { "codepoints": [8834, 8402], "characters": "\u2282\u20D2" }, "&vnsup;": { "codepoints": [8835, 8402], "characters": "\u2283\u20D2" }, "&vopf;": { "codepoints": [120167], "characters": "\uD835\uDD67" }, "&vprop;": { "codepoints": [8733], "characters": "\u221D" }, "&vrtri;": { "codepoints": [8883], "characters": "\u22B3" }, "&vscr;": { "codepoints": [120011], "characters": "\uD835\uDCCB" }, "&vsubnE;": { "codepoints": [10955, 65024], "characters": "\u2ACB\uFE00" }, "&vsubne;": { "codepoints": [8842, 65024], "characters": "\u228A\uFE00" }, "&vsupnE;": { "codepoints": [10956, 65024], "characters": "\u2ACC\uFE00" }, "&vsupne;": { "codepoints": [8843, 65024], "characters": "\u228B\uFE00" }, "&vzigzag;": { "codepoints": [10650], "characters": "\u299A" }, "&wcirc;": { "codepoints": [373], "characters": "\u0175" }, "&wedbar;": { "codepoints": [10847], "characters": "\u2A5F" }, "&wedge;": { "codepoints": [8743], "characters": "\u2227" }, "&wedgeq;": { "codepoints": [8793], "characters": "\u2259" }, "&weierp;": { "codepoints": [8472], "characters": "\u2118" }, "&wfr;": { "codepoints": [120116], "characters": "\uD835\uDD34" }, "&wopf;": { "codepoints": [120168], "characters": "\uD835\uDD68" }, "&wp;": { "codepoints": [8472], "characters": "\u2118" }, "&wr;": { "codepoints": [8768], "characters": "\u2240" }, "&wreath;": { "codepoints": [8768], "characters": "\u2240" }, "&wscr;": { "codepoints": [120012], "characters": "\uD835\uDCCC" }, "&xcap;": { "codepoints": [8898], "characters": "\u22C2" }, "&xcirc;": { "codepoints": [9711], "characters": "\u25EF" }, "&xcup;": { "codepoints": [8899], "characters": "\u22C3" }, "&xdtri;": { "codepoints": [9661], "characters": "\u25BD" }, "&xfr;": { "codepoints": [120117], "characters": "\uD835\uDD35" }, "&xhArr;": { "codepoints": [10234], "characters": "\u27FA" }, "&xharr;": { "codepoints": [10231], "characters": "\u27F7" }, "&xi;": { "codepoints": [958], "characters": "\u03BE" }, "&xlArr;": { "codepoints": [10232], "characters": "\u27F8" }, "&xlarr;": { "codepoints": [10229], "characters": "\u27F5" }, "&xmap;": { "codepoints": [10236], "characters": "\u27FC" }, "&xnis;": { "codepoints": [8955], "characters": "\u22FB" }, "&xodot;": { "codepoints": [10752], "characters": "\u2A00" }, "&xopf;": { "codepoints": [120169], "characters": "\uD835\uDD69" }, "&xoplus;": { "codepoints": [10753], "characters": "\u2A01" }, "&xotime;": { "codepoints": [10754], "characters": "\u2A02" }, "&xrArr;": { "codepoints": [10233], "characters": "\u27F9" }, "&xrarr;": { "codepoints": [10230], "characters": "\u27F6" }, "&xscr;": { "codepoints": [120013], "characters": "\uD835\uDCCD" }, "&xsqcup;": { "codepoints": [10758], "characters": "\u2A06" }, "&xuplus;": { "codepoints": [10756], "characters": "\u2A04" }, "&xutri;": { "codepoints": [9651], "characters": "\u25B3" }, "&xvee;": { "codepoints": [8897], "characters": "\u22C1" }, "&xwedge;": { "codepoints": [8896], "characters": "\u22C0" }, "&yacute": { "codepoints": [253], "characters": "\u00FD" }, "&yacute;": { "codepoints": [253], "characters": "\u00FD" }, "&yacy;": { "codepoints": [1103], "characters": "\u044F" }, "&ycirc;": { "codepoints": [375], "characters": "\u0177" }, "&ycy;": { "codepoints": [1099], "characters": "\u044B" }, "&yen": { "codepoints": [165], "characters": "\u00A5" }, "&yen;": { "codepoints": [165], "characters": "\u00A5" }, "&yfr;": { "codepoints": [120118], "characters": "\uD835\uDD36" }, "&yicy;": { "codepoints": [1111], "characters": "\u0457" }, "&yopf;": { "codepoints": [120170], "characters": "\uD835\uDD6A" }, "&yscr;": { "codepoints": [120014], "characters": "\uD835\uDCCE" }, "&yucy;": { "codepoints": [1102], "characters": "\u044E" }, "&yuml": { "codepoints": [255], "characters": "\u00FF" }, "&yuml;": { "codepoints": [255], "characters": "\u00FF" }, "&zacute;": { "codepoints": [378], "characters": "\u017A" }, "&zcaron;": { "codepoints": [382], "characters": "\u017E" }, "&zcy;": { "codepoints": [1079], "characters": "\u0437" }, "&zdot;": { "codepoints": [380], "characters": "\u017C" }, "&zeetrf;": { "codepoints": [8488], "characters": "\u2128" }, "&zeta;": { "codepoints": [950], "characters": "\u03B6" }, "&zfr;": { "codepoints": [120119], "characters": "\uD835\uDD37" }, "&zhcy;": { "codepoints": [1078], "characters": "\u0436" }, "&zigrarr;": { "codepoints": [8669], "characters": "\u21DD" }, "&zopf;": { "codepoints": [120171], "characters": "\uD835\uDD6B" }, "&zscr;": { "codepoints": [120015], "characters": "\uD835\uDCCF" }, "&zwj;": { "codepoints": [8205], "characters": "\u200D" }, "&zwnj;": { "codepoints": [8204], "characters": "\u200C" } } �����������������������chawan-v0.4.0/lib/chame0/chame/res/genentity.nim����������������������������������������������������0000664�0000000�0000000�00000002267�15202323131�0021425�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import std/json import std/streams import std/strutils type LineWriter = object s: Stream line: string proc write(writer: var LineWriter, s: string) = if s.len + writer.line.len > 80: writer.s.writeLine(writer.line) writer.line = "" writer.line &= s proc flush(writer: var LineWriter) = writer.s.writeLine(writer.line) writer.line = "" proc main() = let entityJson = parseJson(readFile("entity.json")) echo "type Z = cstring" var writer = LineWriter(s: newFileStream(stdout)) var cc: char var charMap: array[char, int] for i in charMap.mitems: i = -1 var entityMap: seq[tuple[name, value: string]] for k, v in entityJson: entityMap.add((k.substr(1), v{"characters"}.getStr())) let n = entityMap.len echo "const entityMap*: array[" & $n & ", Z] = [" writer.write("Z ") var i = 0 for (k, v) in entityMap: if k[0] != cc: charMap[cc] = i - 1 cc = k[0] writer.write((k & ":" & v).escape() & ",") inc i assert cc == 'z' charMap[cc] = i - 1 writer.flush() echo "]" echo "" echo "const charMap*: array[char, int] = [" for c in char.low..char.high: writer.write($charMap[c] & ",") writer.flush() echo "]" main() �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/chame/tags.nim�������������������������������������������������������������0000664�0000000�0000000�00000011231�15202323131�0017553�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������type TagType* = enum TAG_UNKNOWN = "" TAG_APPLET = "applet" TAG_BIG = "big" TAG_HTML = "html" TAG_BASE = "base" TAG_BASEFONT = "basefont" TAG_BGSOUND = "bgsound" TAG_HEAD = "head" TAG_LINK = "link" TAG_LISTING = "listing" TAG_META = "meta" TAG_STYLE = "style" TAG_TITLE = "title" TAG_BODY = "body" TAG_ADDRESS = "address" TAG_ARTICLE = "article" TAG_ASIDE = "aside" TAG_FOOTER = "footer" TAG_HEADER = "header" TAG_H1 = "h1" TAG_H2 = "h2" TAG_H3 = "h3" TAG_H4 = "h4" TAG_H5 = "h5" TAG_H6 = "h6" TAG_HGROUP = "hgroup" TAG_MAIN = "main" TAG_NAV = "nav" TAG_SEARCH = "search" TAG_SECTION = "section" TAG_BLOCKQUOTE = "blockquote" TAG_DD = "dd" TAG_DIV = "div" TAG_DL = "dl" TAG_DT = "dt" TAG_FIGCAPTION = "figcaption" TAG_FIGURE = "figure" TAG_HR = "hr" TAG_LI = "li" TAG_OL = "ol" TAG_P = "p" TAG_PRE = "pre" TAG_UL = "ul" TAG_A = "a" TAG_ABBR = "abbr" TAG_B = "b" TAG_BDI = "bdi" TAG_BDO = "bdo" TAG_BR = "br" TAG_NOBR = "nobr" TAG_CITE = "cite" TAG_CODE = "code" TAG_DATA = "data" TAG_DFN = "dfn" TAG_EM = "em" TAG_EMBED = "embed" TAG_I = "i" TAG_KBD = "kbd" TAG_MARK = "mark" TAG_MARQUEE = "marquee" TAG_Q = "q" TAG_RB = "rb" TAG_RP = "rp" TAG_RT = "rt" TAG_RTC = "rtc" TAG_RUBY = "ruby" TAG_S = "s" TAG_SAMP = "samp" TAG_SMALL = "small" TAG_SPAN = "span" TAG_STRONG = "strong" TAG_SUB = "sub" TAG_SUP = "sup" TAG_TIME = "time" TAG_U = "u" TAG_VAR = "var" TAG_WBR = "wbr" TAG_AREA = "area" TAG_AUDIO = "audio" TAG_IMG = "img" TAG_IMAGE = "image" TAG_MAP = "map" TAG_TRACK = "track" TAG_VIDEO = "video" TAG_IFRAME = "iframe" TAG_OBJECT = "object" TAG_PARAM = "param" TAG_PICTURE = "picture" TAG_PORTAL = "portal" TAG_SOURCE = "source" TAG_CANVAS = "canvas" TAG_NOSCRIPT = "noscript" TAG_NOEMBED = "noembed" TAG_PLAINTEXT = "plaintext" TAG_XMP = "xmp" TAG_SCRIPT = "script" TAG_SLOT = "slot" TAG_DEL = "del" TAG_INS = "ins" TAG_CAPTION = "caption" TAG_COL = "col" TAG_COLGROUP = "colgroup" TAG_TABLE = "table" TAG_TBODY = "tbody" TAG_TD = "td" TAG_TFOOT = "tfoot" TAG_TH = "th" TAG_THEAD = "thead" TAG_TR = "tr" TAG_BUTTON = "button" TAG_DATALIST = "datalist" TAG_FIELDSET = "fieldset" TAG_FORM = "form" TAG_INPUT = "input" TAG_KEYGEN = "keygen" TAG_LABEL = "label" TAG_LEGEND = "legend" TAG_METER = "meter" TAG_OPTGROUP = "optgroup" TAG_OPTION = "option" TAG_OUTPUT = "output" TAG_PROGRESS = "progress" TAG_SELECT = "select" TAG_SELECTEDCONTENT = "selectedcontent" TAG_TEXTAREA = "textarea" TAG_DETAILS = "details" TAG_DIALOG = "dialog" TAG_MENU = "menu" TAG_SUMMARY = "summary" TAG_BLINK = "blink" TAG_CENTER = "center" TAG_CONTENT = "content" TAG_DIR = "dir" TAG_FONT = "font" TAG_FRAME = "frame" TAG_NOFRAMES = "noframes" TAG_FRAMESET = "frameset" TAG_STRIKE = "strike" TAG_TT = "tt" TAG_TEMPLATE = "template" TAG_SARCASM = "sarcasm" TAG_MATH = "math" TAG_SVG = "svg" TAG_CHARSET = "charset" TAG_HTTP_EQUIV = "http-equiv" TAG_TYP = "type" TAG_DEFINITION_URL = "definitionurl" TAG_ANNOTATION_XML = "annotation-xml" TAG_FOREIGN_OBJECT = "foreignObject" TAG_DESC = "desc" TAG_ENCODING = "encoding" TAG_MI = "mi" TAG_MO = "mo" TAG_MN = "mn" TAG_MS = "ms" TAG_MTEXT = "mtext" TAG_MGLYPH = "mglyph" TAG_MALIGNMARK = "malignmark" TAG_COLOR = "color" TAG_FACE = "face" TAG_SIZE = "size" QuirksMode* = enum NO_QUIRKS, QUIRKS, LIMITED_QUIRKS Namespace* = enum NO_NAMESPACE = "", HTML = "http://www.w3.org/1999/xhtml", MATHML = "http://www.w3.org/1998/Math/MathML", SVG = "http://www.w3.org/2000/svg", XLINK = "http://www.w3.org/1999/xlink", XML = "http://www.w3.org/XML/1998/namespace", XMLNS = "http://www.w3.org/2000/xmlns/" NAMESPACE_UNKNOWN = "" NamespacePrefix* = enum NO_PREFIX = "" PREFIX_XLINK = "xlink" PREFIX_XML = "xml" PREFIX_XMLNS = "xmlns" PREFIX_UNKNOWN = "" const AllTagTypes* = {TagType.low..TagType.high} const HTagTypes* = { TAG_H1, TAG_H2, TAG_H3, TAG_H4, TAG_H5, TAG_H6 } # 4.10.2 Categories const FormAssociatedElements* = { TAG_BUTTON, TAG_FIELDSET, TAG_INPUT, TAG_OBJECT, TAG_OUTPUT, TAG_SELECT, TAG_TEXTAREA, TAG_IMG } const ListedElements* = { TAG_FIELDSET, TAG_INPUT, TAG_OBJECT, TAG_OUTPUT, TAG_SELECT, TAG_TEXTAREA } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/chame/tokstate.nim���������������������������������������������������������0000664�0000000�0000000�00000003602�15202323131�0020456�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������type TokenizerState* = enum DATA, CHARACTER_REFERENCE, TAG_OPEN, RCDATA, RCDATA_LESS_THAN_SIGN, RAWTEXT, RAWTEXT_LESS_THAN_SIGN, SCRIPT_DATA, SCRIPT_DATA_LESS_THAN_SIGN, PLAINTEXT, MARKUP_DECLARATION_OPEN, END_TAG_OPEN, BOGUS_COMMENT, TAG_NAME, BEFORE_ATTRIBUTE_NAME, RCDATA_END_TAG_OPEN, RCDATA_END_TAG_NAME, RAWTEXT_END_TAG_OPEN, RAWTEXT_END_TAG_NAME, SELF_CLOSING_START_TAG, SCRIPT_DATA_END_TAG_OPEN, SCRIPT_DATA_ESCAPE_START, SCRIPT_DATA_END_TAG_NAME, SCRIPT_DATA_ESCAPE_START_DASH, SCRIPT_DATA_ESCAPED_DASH_DASH, SCRIPT_DATA_ESCAPED, SCRIPT_DATA_ESCAPED_DASH, SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN, SCRIPT_DATA_ESCAPED_END_TAG_OPEN, SCRIPT_DATA_DOUBLE_ESCAPE_START, SCRIPT_DATA_ESCAPED_END_TAG_NAME, SCRIPT_DATA_DOUBLE_ESCAPED, SCRIPT_DATA_DOUBLE_ESCAPED_DASH, SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN, SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH, SCRIPT_DATA_DOUBLE_ESCAPE_END, AFTER_ATTRIBUTE_NAME, ATTRIBUTE_NAME, BEFORE_ATTRIBUTE_VALUE, ATTRIBUTE_VALUE_QUOTED, ATTRIBUTE_VALUE_UNQUOTED, AFTER_ATTRIBUTE_VALUE_QUOTED, COMMENT_START, CDATA_SECTION, COMMENT_START_DASH, COMMENT, COMMENT_END, COMMENT_LESS_THAN_SIGN, COMMENT_END_DASH, COMMENT_LESS_THAN_SIGN_BANG, COMMENT_LESS_THAN_SIGN_BANG_DASH, COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH, COMMENT_END_BANG, DOCTYPE, BEFORE_DOCTYPE_NAME, DOCTYPE_NAME, AFTER_DOCTYPE_NAME, AFTER_DOCTYPE_PUBLIC_KEYWORD, AFTER_DOCTYPE_SYSTEM_KEYWORD, BOGUS_DOCTYPE, BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, DOCTYPE_PUBLIC_IDENTIFIER_QUOTED, AFTER_DOCTYPE_PUBLIC_IDENTIFIER, BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS, DOCTYPE_SYSTEM_IDENTIFIER_QUOTED, BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, AFTER_DOCTYPE_SYSTEM_IDENTIFIER, CDATA_SECTION_BRACKET, CDATA_SECTION_END, NAMED_CHARACTER_REFERENCE, NUMERIC_CHARACTER_REFERENCE, AMBIGUOUS_AMPERSAND_STATE, HEXADECIMAL_CHARACTER_REFERENCE_START, HEXADECIMAL_CHARACTER_REFERENCE, DECIMAL_CHARACTER_REFERENCE ������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/chame/version.nim����������������������������������������������������������0000664�0000000�0000000�00000000063�15202323131�0020303�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������const Major* = 1 const Minor* = 0 const Patch* = 5 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/doc/�����������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0015602�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/doc/.index.md��������������������������������������������������������������0000664�0000000�0000000�00000001327�15202323131�0017314�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Documentation of Chame, an HTML5 parsing library written in Nim. To get started, please read the [readme](https://git.sr.ht/~bptato/chame). Index of the (stable) public API: * [minidom](minidom.html): minimal DOM module and a high-level interface to the HTML parser. * [minidom_cs](minidom_cs.html): minidom with support for non-UTF-8 character sets. * [htmlparser](htmlparser.html): low-level interface to the HTML parser. * [htmlparseriface](htmlparseriface.html): forward declarations for the HTML parser * [tags](tags.html): enum definitions for Chame (tags, namespaces, etc.) * [tokstate](tokstate.html): tokenizer states for the fragment parsing algorithm Also of interest: the Chame [manual](manual.html). ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/doc/manual.md��������������������������������������������������������������0000664�0000000�0000000�00000026373�15202323131�0017414�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Using Chame Chame is divided into two parts: a low-level API ([htmlparser](htmlparser.html)) and a high-level API ([minidom](minidom.html), [minidom_cs](minidom_cs.html)). The high-level APIs build on top of htmlparser, and are easier to use. However, they give consumers less control than htmlparser. Here we describe both APIs. ## Table of Contents * [Basic concepts](#basic-concepts) - [Standards](#standards) - [String interning](#string-interning) - [String validation](#string-validation) * [High-level API (minidom, minidom_cs)](#high-level-api-minidom-minidom_cs) * [Low-level API (htmlparser)](#low-level-api-htmlparser) - [Functions and procedures](#functions-and-procedures) * [initHTML5Parser](#inithtml5parser) * [parseChunk](#parsechunk) * [finish](#finish) - [Generic parameters](#generic-parameters) * [Example](#example) ## Basic concepts ### Standards Chame implements HTML5 parsing as described in the [Parsing HTML documents](https://html.spec.whatwg.org/multipage/parsing.html) section of WHATWG's living standard. Note that this document may change at any time, and newer additions might take some time to implement in Chame. Users of the low-level API are encouraged to consult the appropriate sections of the standard while implementing hooks provided by htmlparser. ### String interning To achieve O(1) comparisons of tag and attribute names and a lower memory footprint, Chame uses [string interning](https://en.wikipedia.org/wiki/String_interning). While minidom users can simply call the appropriate conversion functions on Document.factory, consumers of htmlparser must implement string interning themselves, be that through MAtomFactory or a custom solution. ### String validation Note that (as per standard) the tokenization stage strips out all NUL characters, so strings from the parser can be safely converted to cstrings. htmlparser itself does no UTF-8 validation; it is up to the DOM builder to validate the input. Non-ASCII characters are treated as opaque characters, so parsing of ASCII-compatible character sets should just work with the caveat that the strings from htmlparser will not necessarily be valid UTF-8. This is not a problem in minidom, since it abstracts over this difficulty. ## High-level API (minidom, minidom_cs) minidom has two main entry points: `parseHTML` and `parseHTMLFragment`. For parsing documents, `parseHTML` should be used; `parseHTMLFragment` is for parsing incomplete document fragments. e.g. in a browser, the `innerHTML` setter would use `parseHTMLFragment`, while `DOMParser.parseFromString` would use `parseHTML`. The input stream must be passed as a `Stream` object from `std/streams`. Both `parseHTML` and `parseHTMLFragment` return only when the input stream has been completely consumed from the stream. For chunked parsing, you must use the low-level htmlparser API instead. minidom (and minidom_cs) implements string interning using `MAtomFactory`, and interned strings in minidom are represented using `MAtom`s. Every `MAtom` is guaranteed to point to a valid UTF-8 string. To convert a Nim string into an `MAtom`, use the `MAtomFactory.strToAtom` function. To convert an `MAtom` into a Nim string, use the `MAtomFactory.atomToStr` function. Note: it is always more efficient to convert strings to atoms (i.e. to use `strToAtom`) than to do it the other way. `MAtom`s are just integers, so storing, copying, and comparing them is a lot cheaper than the same operations with strings. The output is a DOM tree, with the root node being a `Document`. The root Document node also contains a `MAtomFactory` instance, which can be used to convert `MAtom`s back to strings (through `atomToStr`). Strings returned from minidom are guaranteed to be valid UTF-8. Note however that minidom only understands UTF-8 documents. For parsing documents with character sets other than UTF-8, minidom_cs must be used. The `parseHTML` function of minidom_cs is also able to BOM sniff, interpret meta charset tags, and optionally retry parsing with a predefined list of character sets (using the companion character decoding library Chagashi). ## Low-level API (htmlparser) ### Functions and procedures htmlparser has three defined procedures: `initHTML5Parser`, `parseChunk`, and `finish`. A `getInsertionPoint` function is available as well. #### initHTML5Parser ```nim # Signature proc initHTML5Parser[Handle, Atom](dombuilder: DOMBuilder[Handle, Atom], opts: HTML5ParserOpts[Handle, Atom]): HTML5Parser[Handle, Atom] ``` The `initHTML5Parser` procedure requires a user-defined DOMBuilder object derived from the `DOMBuilder[Handle, Atom]` generic object reference. To implement all interfaces necessary for htmlparser, please include [htmlparseriface](htmlparseriface.html) in your DOM builder module; it contains forward-declarations for all procedures that `HTML5Parser` depends on. Feel free to study/copy [minidom](minidom.html)'s implementations. The return value is an `HTML5Parser[Handle, Atom]` object. Note that this is a rather large object that is passed by value; if possible, avoid copying it at all. #### parseChunk ```nim # Signature proc parseChunk[Handle, Atom](parser: var HTML5Parser[Handle, Atom], inputBuf: openArray[char], reprocess = false): ParseResult ``` `parseChunk` consumes all data passed in `inputBuf`. During this, the appropriate functions (`createElementImpl`, etc.) will be called by the parser. `parseChunk` returns a `ParseResult`, which is one of the following values: * `PRES_CONTINUE`: the caller should continue with parsing the next chunk of data when it is available. (It's also fine to do delay processing the next call by processing something different first.) * `PRES_STOP`: parsing was stopped by your setEncodingImpl implementation. The caller is expected to restart parsing from the beginning using a **new** `HTML5Parser` object. WARNING: do *not* re-use the current HTML5Parser for this. * `PRES_SCRIPT`: a `</script>` end tag has been encountered, which immediately suspended parsing. In the next `parseChunk` call, the caller is expected to pass the **same** buffer (`inputBuf`) as in the current one. For details, see below. Special care is required when implementing programs with scripting support. The HTML5 standard requires the parser to be re-entrant for supporting the `document.write` JavaScript function; therefore the parser suspends itself upon encountering a `</script>` end tag, returning a `PRES_SCRIPT` `ParseResult`. At this point, implementations have two options. ##### Option 1: Continue parsing the current buffer If either: * your implementation does not support `document.write`, or * no `document.write` call has been issued by the script, or * parsing of all buffers passed by `document.write` calls has finished, then you can simply resume parsing the current buffer by calling `parseChunk` again with an openArray that uses the same backing buffer, except starting from `parser.getInsertionPoint()`. `minidom`, which pretends to support scripting in test cases, but does not actually execute scripts, has an example of this: ```nim var buffer: array[4096, char] while true: let n = inputStream.readData(addr buffer[0], buffer.len) if n == 0: break # res can be PRES_CONTINUE or PRES_SCRIPTING. PRES_STOP is only returned # on charset switching, and minidom does not support that. var res = parser.parseChunk(buffer.toOpenArray(0, n - 1)) # Important: we must repeat parseChunk with the same contents for the script # end tag result, with reprocess = true. # # (This is only relevant for calls where scripting = true; with scripting = # false, PRES_SCRIPT would never be returned.) var ip = 0 while res == PRES_SCRIPT and (ip += parser.getInsertionPoint(); ip != n): res = parser.parseChunk(buffer.toOpenArray(ip, n - 1)) parser.finish() ``` Note the while loop; `parseChunk` will return `PRES_SCRIPT` multiple times for a single chunk if it contains several scripts. Also note that `minidom` does not handle `PRES_STOP`, since it does not support legacy encodings. For an implementation that *does* handle `PRES_STOP`, see `minidom_cs`. ##### Option 2: Parse buffers passed by `document.write` Per standard, it is possible to insert buffers into the stream from scripts using the `document.write` function. It is possible to implement this, but it is somewhat too involved to give a detailed explanation of it here. Please refer to Chawan's implementation in html/chadombuilder and html/dom. (Good luck.) #### finish After having parsed all chunks of your document with `parseChunk`, you **must** call the `finish` function. This is necessary because the parser may still have some non-flushed characters in an internal buffer. e.g. when the parser receives the string `&gt`, it is not clear whether the character reference refers to a "greater than" sign, or a longer character reference like `&gtrsim;`; `finish` confirms that the reference is indeed a `&gt` sign. Also, the parser has to execute certain actions on encountering the `EOF` token, which only `finish` can produce. `finish` must never be called twice, and any `parseChunk` call after `finish` is invalid. ### Generic parameters `initHTML5Parser` takes two generic parameters: `Handle` and `Atom`. `Handle` is conceptually a unique pointer to a node in the document. A naive single-threaded implementation (like minidom) may simply implement this as a Nim `ref` to an object. However, this is not mandatory; since `Handle` is a generic parameter, any type is accepted. For example, multi-processing implementations that use message passing might instead prefer to use an integer ID that refers to an object owned by a different thread. Similarly, `Atom` is a unique pointer to a string. This means that `DOMBuilder.strToAtom` must always return the same Atom for every string whose contents are equivalent. Additionally, `atomToTagType` and `tagTypeToAtom` must operate as if `TagType` values were equivalent to the contents of its stringifier. (i.e. `tagTypeToAtom(tagType) == strToAtom($tagType)` for all tag types except `TAG_UNKNOWN`, which is never passed to `tagTypeToAtom`.) Note that htmlparser does not *require* an `atomToStr` procedure, so it is not even necessary to store interned strings in a format compatible with the Nim string type. (Obviously, some way to stringify atoms is required for most use cases, but it need not be exposed to Chame.) ## Example A simple example with minidom: dumps all text on a page. ```Nim # Compile with nim c -d:ssl # List text found between HTML tags on the target website. import std/httpclient import std/os import std/strutils import chame/minidom if paramCount() != 1: echo "Usage: " & paramStr(0) & " [URL]" quit(1) let client = newHttpClient() let res = client.get(paramStr(1)) let document = parseHTML(res.bodyStream) var stack = @[Node(document)] while stack.len > 0: let node = stack.pop() if node of Text: let s = Text(node).data.strip() if s != "": echo s for i in countdown(node.childList.high, 0): stack.add(node.childList[i]) ``` For more advanced usage of minidom, please study tests/tree.nim and tests/shared/tree_common.nim which together constitute a test runner of html5lib-tests. For an example implementation of [htmlparseriface](htmlparseriface.html), please check the source code of [minidom](minidom.html) (and if you need legacy charset support, [minidom_cs](minidom_cs.html)). ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/gendoc.sh������������������������������������������������������������������0000775�0000000�0000000�00000001261�15202323131�0016633�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh mkdir -p .obj/doc for f in chame/*.nim do if test "$f" = "chame/htmlparseriface.nim" then nim doc -d:nimdocdummy --outdir:.obj/doc "$f" else nim doc -p:test/chagashi/ --outdir:.obj/doc "$f" fi sed -i \ -e '/<\!-- Google fonts -->/,+2d' \ -e 's/theindex.html/index.html/g' \ ".obj/doc/$(basename "$f" .nim).html" done makehtml() { printf '<!DOCTYPE html> <head> <meta name=viewport content="width=device-width, initial-scale=1"> <title>%s</title> </head> <body> ' "$2" cat "$1" | pandoc printf '</body>\n' } makehtml doc/manual.md "Chame manual" > .obj/doc/manual.html makehtml doc/.index.md "Chame documentation" > .obj/doc/index.html �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/test/����������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0016014�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/test/.gitignore������������������������������������������������������������0000664�0000000�0000000�00000000033�15202323131�0020000�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������./chagashi ./htmllib-tests �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/test/config.nims�����������������������������������������������������������0000664�0000000�0000000�00000000045�15202323131�0020150�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������switch("path", "$projectDir/../src") �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/test/custom.dat������������������������������������������������������������0000664�0000000�0000000�00000000541�15202323131�0020020�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#data <!DOCTYPE html> <plaintext> ͂ɂقւ ʂ킩 悽ꂻ‚˂ ނ̂ ܂ӂ ߂݂ Ђ #document | <html> | <head> | <body> | <plaintext> | " いろはにほへと ちりぬるをわか よたれそつねな らむうゐのおく やまけふこえて あさきゆめみし ゑひもせす" ���������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/test/eprint.nim������������������������������������������������������������0000664�0000000�0000000�00000000751�15202323131�0020025�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.used.} template eprint0(s: varargs[string]) = {.cast(noSideEffect), cast(tags: []), cast(raises: []).}: var o = "" for i in 0 ..< s.len: if i != 0: o &= ' ' o &= s[i] when not declared(stderr): echo o else: o &= '\n' stderr.write(o) when defined(release): func eprint*(s: varargs[string, `$`]) {.deprecated: "eprint is for debugging only".} = eprint0(s) else: func eprint*(s: varargs[string, `$`]) = eprint0(s) �����������������������chawan-v0.4.0/lib/chame0/test/gtrsim.dat������������������������������������������������������������0000664�0000000�0000000�00000000751�15202323131�0020016�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#data &gtrsim #errors #document | <html> | <head> | <body> | ">rsim" #data &gt #errors #document | <html> | <head> | <body> | ">" #data <h2>&g</h2> #errors #document | <html> | <head> | <body> | <h2> | "&g" #data <H2>Q&A</H2> #errors #document | <html> | <head> | <body> | <h2> | "Q&A" #data &zacute; #errors #document | <html> | <head> | <body> | "ź" #data &#x10FFFF1; #errors #document | <html> | <head> | <body> | "�" �����������������������chawan-v0.4.0/lib/chame0/test/latin1.dat������������������������������������������������������������0000664�0000000�0000000�00000000212�15202323131�0017671�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#data <meta charset=latin1> #errors #document | <html> | <head> | <meta> | charset="latin1" | " " | <body> | "ß" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/test/shared/���������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0017262�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/test/shared/tree_common.nim������������������������������������������������0000664�0000000�0000000�00000021561�15202323131�0022303�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import std/algorithm import std/options import std/strutils import std/tables import std/unittest import test1 import chame/htmlparser import chame/minidom type TCError = object s: string FragmentType = enum FT_HTML, FT_SVG, FT_MATHML TCFragment = object fragmentType: FragmentType ctx: Element ScriptMode = enum SCRIPT_BOTH, SCRIPT_OFF, SCRIPT_ON TCTest = object data: string errors: seq[TCError] newerrors: seq[TCError] fragment: Option[TCFragment] script: ScriptMode document: Document TCTestParser = object s: string i: int pi: int factory: MAtomFactory linei: int func has(ctx: TCTestParser): bool = return ctx.i < ctx.s.len proc reconsumeLine(ctx: var TCTestParser) = ctx.i = ctx.pi dec ctx.linei proc consumeLine(ctx: var TCTestParser): string = result = "" ctx.pi = ctx.i inc ctx.linei while ctx.has: if ctx.s[ctx.i] == '\n': inc ctx.i break result &= ctx.s[ctx.i] inc ctx.i proc parseTestData(ctx: var TCTestParser): string = result = "" while ctx.has: let line = ctx.consumeLine() if line == "#errors": return if result.len > 0: result &= '\n' result &= line doAssert false, "errors expected" proc parseTestNewErrors(ctx: var TCTestParser): seq[TCError] = result = @[] while ctx.has: let line = ctx.consumeLine() case line of "#document-fragment", "#script-off", "#script-on", "#document": ctx.reconsumeLine() return result.add(TCError(s: line)) proc parseTestErrors(ctx: var TCTestParser): seq[TCError] = result = @[] while ctx.has: let line = ctx.consumeLine() case line of "#new-errors": ctx.reconsumeLine() result.add(ctx.parseTestNewErrors()) return of "#document-fragment", "#script-off", "#script-on", "#document": ctx.reconsumeLine() return result.add(TCError(s: line)) proc parseTestFragment(ctx: var TCTestParser): TCFragment = var line = ctx.consumeLine() var fragmentType = FT_HTML if line.startsWith("svg "): fragmentType = FT_SVG line = line.substr("svg ".len) elif line.startsWith("math "): fragmentType = FT_MATHML line = line.substr("math ".len) let namespace = case fragmentType of FT_SVG: Namespace.SVG of FT_MATHML: Namespace.MATHML of FT_HTML: Namespace.HTML let element = Element( namespace: namespace, localName: ctx.factory.strToAtom(line) ) return TCFragment( fragmentType: fragmentType, ctx: element ) proc parseDoctype(ctx: TCTestParser, s: string): DocumentType = let doctype = DocumentType() var i = "<!DOCTYPE ".len while i < s.len and s[i] != ' ' and s[i] != '>': doctype.name &= s[i] inc i while s[i] == ' ': inc i if s[i] == '>': return doctype assert s[i] == '"' inc i while i < s.len and s[i] != '"': doctype.publicId &= s[i] inc i assert s[i] == '"' inc i assert s[i] == ' ' inc i assert s[i] == '"' inc i while i < s.len and s[i] != '"': doctype.systemId &= s[i] inc i while i + 1 < s.len and s[i + 1] == '"': doctype.systemId &= s[i] inc i assert s[i] == '"' inc i assert s[i] == '>' return doctype func until(s: string, c: set[char]): string = result = "" var i = 0 while i < s.len: if s[i] in c: break result.add(s[i]) inc i func until(s: string, c: char): string = s.until({c}) func after(s: string, c: set[char]): string = var i = 0 while i < s.len: if s[i] in c: return s.substr(i + 1) inc i return "" func after(s: string, c: char): string = s.after({c}) proc parseTestDocument(ctx: var TCTestParser): Document = result = Document(factory: ctx.factory) var stack = @[Node(result)] template top: auto = stack[^1] var thistext: Text = nil var thiscomment: Comment = nil var indent = 1 template pop_node = let node = stack.pop() if node of Element: Element(node).attrs.sort(proc(a, b: Attribute): int = cmp(a.name, b.name)) indent -= 2 while ctx.has: let line = ctx.consumeLine() if thistext != nil: if line.endsWith("\""): thistext.data &= line.substr(0, line.high - 1) thistext = nil else: thistext.data &= line & "\n" continue if thiscomment != nil: if line.endsWith(" -->"): thiscomment.data &= line.substr(0, line.high - " -->".len) thiscomment = nil else: thiscomment.data &= line & "\n" continue if line == "": break assert line[0] == '|' and line[1] == ' ' while indent >= line.len or not line.startsWith('|' & ' '.repeat(indent)): let node = stack.pop() if node of Element: Element(node).attrs.sort(proc(a, b: Attribute): int = cmp(a.name, b.name)) indent -= 2 let str = line.substr(indent + 1) if str.startsWith("<!DOCTYPE "): let doctype = ctx.parseDoctype(str) top.childList.add(doctype) elif str.startsWith("<!-- "): let comment = minidom.Comment() top.childList.add(comment) if not str.endsWith(" -->"): comment.data = str.substr("<!-- ".len) & "\n" thiscomment = comment else: comment.data = str.substr("<!-- ".len, str.high - " -->".len) elif str.startsWith("<?"): assert false, "todo" elif str.startsWith("<") and str.endsWith(">"): var nameStr = str.substr(1, str.high - 1) var namespace = Namespace.HTML if nameStr.startsWith("svg "): nameStr = nameStr.substr("svg ".len) namespace = Namespace.SVG elif nameStr.startsWith("math "): nameStr = nameStr.substr("math ".len) namespace = Namespace.MATHML let element = if nameStr == "template": HTMLTemplateElement() else: Element() element.localName = ctx.factory.strToAtom(nameStr) element.namespace = namespace element.document = result top.childList.add(element) stack.add(element) indent += 2 elif str == "content": let fragment = DocumentFragment() HTMLTemplateElement(top).content = fragment stack.add(fragment) indent += 2 elif str[0] == '"': let text = Text() top.childList.add(text) if str[^1] != '"' or str.len == 1: text.data = str.substr(1) & "\n" thistext = text else: text.data = str.substr(1, str.high - 1) else: assert '=' in str var name = str.until('=') var prefix = NO_PREFIX var ns = NO_NAMESPACE if name.startsWith("xml "): ns = Namespace.XML prefix = PREFIX_XML name = name.substr("xml ".len) elif name.startsWith("xmlns "): ns = Namespace.XMLNS prefix = PREFIX_XMLNS name = name.substr("xmlns ".len) elif name.startsWith("xlink "): ns = Namespace.XLINK prefix = PREFIX_XLINK name = name.substr("xlink ".len) let na = ctx.factory.strToAtom(name) let value = str.after('=')[1..^2] Element(top).attrs.add((prefix, ns, na, value)) while indent > 1: pop_node proc parseTest(ctx: var TCTestParser): TCTest = doAssert ctx.consumeLine() == "#data" var t = TCTest() t.data = ctx.parseTestData() t.errors = ctx.parseTestErrors() while ctx.has: let line = ctx.consumeLine() case line of "#document-fragment": t.fragment = some(ctx.parseTestFragment()) of "#script-off": t.script = SCRIPT_OFF of "#script-on": t.script = SCRIPT_ON of "#document": assert t.document == nil t.document = ctx.parseTestDocument() break of "": break return t proc parseTests*(s: string, factory: MAtomFactory): seq[TCTest] = result = @[] var parser = TCTestParser(s: s, factory: factory) while parser.i < s.len: let test = parser.parseTest() result.add(test) var s = "" for x in test.document.childList: s &= $x & '\n' proc checkTest(nodein, nodep: Node) = check nodein.childList.len == nodep.childList.len if nodein.childList.len != nodep.childList.len: echo nodein echo nodep if nodein of Element: check nodep of Element let nodein = Element(nodein) let nodep = Element(nodep) check nodein.localName == nodep.localName check nodein.namespace == nodep.namespace if nodein.attrs != nodep.attrs: echo "NODEIN", $nodein echo "NODEP", $nodep check nodein.attrs == nodep.attrs elif nodein of DocumentFragment: assert false elif nodein of CharacterData: check nodep of CharacterData check CharacterData(nodein).data == CharacterData(nodep).data elif nodein of DocumentType: check nodep of DocumentType let nodein = DocumentType(nodein) let nodep = DocumentType(nodep) check nodein.name == nodep.name check nodein.publicId == nodep.publicId check nodein.systemId == nodep.systemId if nodein.childList.len == nodep.childList.len: for i in 0 ..< nodein.childList.len: checkTest(nodein.childList[i], nodep.childList[i]) �����������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/test/sjis.dat��������������������������������������������������������������0000664�0000000�0000000�00000000531�15202323131�0017455�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#data <plaintext> ͂ɂقւ ʂ킩 悽ꂻ‚˂ ނ̂ ܂ӂ ߂݂ Ђ #errors #document | <html> | <head> | <body> | <plaintext> | " いろはにほへと ちりぬるをわか よたれそつねな らむうゐのおく やまけふこえて あさくゆめみし ゑひもせす" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/test/test1.nim�������������������������������������������������������������0000664�0000000�0000000�00000004047�15202323131�0017566�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# "simple" test to check if it compiles # (actually, I just copy-pasted a throwaway test project here) import std/unittest import std/streams import chame/tags import chame/minidom func escapeText(s: string, attributeMode = false): string = result = "" var nbspMode = false var nbspPrev = '\0' for c in s: if nbspMode: if c == char(0xA0): result &= "&nbsp;" else: result &= nbspPrev & c nbspMode = false elif c == '&': result &= "&amp;" elif c == char(0xC2): nbspMode = true nbspPrev = c elif attributeMode and c == '"': result &= "&quot;" elif not attributeMode and c == '<': result &= "&lt;" elif not attributeMode and c == '>': result &= "&gt;" else: result &= c func `$`*(node: Node): string = result = "" if node of Element: let element = Element(node) var x = "" if element.namespace == Namespace.SVG: x = "svg " elif element.namespace == Namespace.MATHML: x = "math " result = "<" & x & element.localNameStr for k, v in element.attrsStr: result &= ' ' & k & "=\"" & v.escapeText(true) & "\"" result &= ">" for node in element.childList: result &= $node result &= "</" & x & element.localNameStr & ">" elif node of Text: let text = Text(node) result = text.data.escapeText() elif node of Comment: result = "<!-- " & Comment(node).data & "-->" elif node of DocumentType: result = "<!DOCTYPE" & ' ' & DocumentType(node).name & ">" elif node of Document: result = "Node of Document" else: assert false # This is, in fact, standards-compliant behavior. # Don't ask. test "simple html serialization test": const inhtml = """ <!DOCTYPE html> <html> <head> </head> <body> <main> Hello, world! </main> </body> </html>""" const outhtml = """ <!DOCTYPE html> <html><head> </head> <body> <main> Hello, world! </main> </body></html> """ let document = parseHTML(newStringStream(inhtml)) var s = "" for x in document.childList: s &= $x & '\n' check s == outhtml �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/test/tokenizer.nim���������������������������������������������������������0000664�0000000�0000000�00000016132�15202323131�0020536�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import std/json import std/options import std/tables import std/unicode import std/unittest import chame/htmltokenizer import chame/minidom proc hexValue*(c: char): int = if c in '0'..'9': return int(uint8(c) - uint8('0')) if c in 'a'..'f': return int(uint8(c) - uint8('a') + 0xA) if c in 'A'..'F': return int(uint8(c) - uint8('A') + 0xA) return -1 func doubleEscape(input: string): string = var s = "" var esc = 0 var u: uint32 = 0 for c in input: if esc == 0: if c == '\\': inc esc else: s &= c elif esc == 1: if c == 'u': inc esc else: s &= '\\' dec esc s &= c elif esc < 6: # 2 + 4 inc esc if esc == 3: u = 0x00 let n = hexValue(c) doAssert n != -1 u *= 0x10 u += uint32(n) if esc == 6: s &= $cast[Rune](u) esc = 0 return s proc getAttrs(factory: MAtomFactory, o: JsonNode, esc: bool): Table[MAtom, string] = result = Table[MAtom, string]() for k, v in o: let k = factory.strToAtom(k) if esc: result[k] = v.getStr().doubleEscape() else: result[k] = v.getStr() proc getToken(factory: MAtomFactory, a: seq[JsonNode], esc: bool): Token[MAtom] = case a[0].getStr() of "StartTag": return Token[MAtom]( t: ttStartTag, tagname: factory.strToAtom(a[1].getStr()), attrs: getAttrs(factory, a[2], esc), flags: if a.len > 3 and a[3].getBool(): {tfSelfClosing} else: {} ) of "EndTag": return Token[MAtom]( t: ttEndTag, tagname: factory.strToAtom(a[1].getStr()) ) of "Character": let s = if esc: doubleEscape(a[1].getStr()) else: a[1].getStr() return Token[MAtom]( t: ttCharacter, s: s ) of "DOCTYPE": var flags: set[TokenFlag] = {} if a[2].kind != JNull: flags.incl(tfPubid) if a[3].kind != JNull: flags.incl(tfSysid) if not a[4].getBool(): # yes, this is reversed. don't ask flags.incl(tfQuirks) return Token[MAtom]( t: ttDoctype, name: if a[1].kind == JNull: "" else: a[1].getStr(), pubid: if a[2].kind == JNull: "" else: a[2].getStr(), sysid: if a[3].kind == JNull: "" else: a[3].getStr(), flags: flags ) of "Comment": let s = if esc: doubleEscape(a[1].getStr()) else: a[1].getStr() return Token[MAtom](t: ttComment, s: s) else: return nil proc checkEquals(factory: MAtomFactory, tok, otok: Token, desc: string) = doAssert otok.t == tok.t, desc & " (tok t: " & $tok.t & " otok t: " & $otok.t & ")" case tok.t of ttDoctype: doAssert tok.name == otok.name, desc & " (" & "tok name: " & $tok.name & " otok name: " & $otok.name & ")" doAssert tok.pubid == otok.pubid, desc & " (" & "tok pubid: " & $tok.pubid & " otok pubid: " & $otok.pubid & ")" doAssert tok.sysid == otok.sysid, desc doAssert tok.flags == otok.flags, desc of ttStartTag, ttEndTag: doAssert tok.tagname == otok.tagname, desc & " (tok tagname: " & factory.atomToStr(tok.tagname) & " otok tagname " & factory.atomToStr(otok.tagname) & ")" if tok.t == ttStartTag: # otherwise a test incorrectly fails doAssert tok.flags == otok.flags, desc var attrs = "" var i = 0 for name, value in tok.attrs: if i > 0: attrs &= " " attrs &= factory.atomToStr(name) attrs &= "=" attrs &= "'" & value & "'" inc i var oattrs = "" i = 0 for name, value in otok.attrs: if i > 0: oattrs &= " " oattrs &= factory.atomToStr(name) oattrs &= "=" oattrs &= "'" & value & "'" inc i doAssert tok.attrs == otok.attrs, desc & " (tok attrs: " & attrs & " otok attrs (" & oattrs & ")" of ttCharacter, ttWhitespace, ttComment: doAssert tok.s == otok.s, desc & " (tok s: " & tok.s & " otok s: " & otok.s & ")" of ttNull: discard proc runTest(builder: MiniDOMBuilder, desc: string, output: seq[JsonNode], laststart: MAtom, esc: bool, input: string, state = TokenizerState.DATA) = let factory = builder.factory var tokenizer = newTokenizer(builder, state) tokenizer.laststart = Token[MAtom](t: ttStartTag, tagname: laststart) var i = 0 var chartok: Token[MAtom] = nil var toks = newSeq[Token[MAtom]]() while true: let res = tokenizer.tokenize(input.toOpenArray(0, input.high)) toks.add(tokenizer.tokqueue) if res == trDone: break while true: let res = tokenizer.finish() toks.add(tokenizer.tokqueue) if res == trDone: break for tok in toks: check tok != nil if chartok != nil and tok.t notin {ttCharacter, ttWhitespace, ttNull}: let otok = getToken(factory, output[i].getElems(), esc) checkEquals(factory, chartok, otok, desc) inc i chartok = nil if tok.t in {ttCharacter, ttWhitespace}: if chartok == nil: chartok = Token[MAtom](t: ttCharacter) chartok.s &= tok.s elif tok.t == ttNull: if chartok == nil: chartok = Token[MAtom](t: ttCharacter) chartok.s &= char(0) else: let otok = getToken(factory, output[i].getElems(), esc) checkEquals(factory, tok, otok, desc) inc i func getState(s: string): TokenizerState = case s of "Data state": return DATA of "PLAINTEXT state": return PLAINTEXT of "RCDATA state": return RCDATA of "RAWTEXT state": return RAWTEXT of "Script data state": return SCRIPT_DATA of "CDATA section state": return CDATA_SECTION else: doAssert false, "Unknown state: " & s quit(1) const rootpath = "test/html5lib-tests/tokenizer/" proc runTests(filename: string) = let tests = parseFile(rootpath & filename){"tests"} for t in tests: let desc = t{"description"}.getStr() var input = t{"input"}.getStr() let esc = "doubleEscaped" in t and t{"doubleEscaped"}.getBool() if esc: input = doubleEscape(input) let output = t{"output"}.getElems() let laststart0 = if "lastStartTag" in t: t{"lastStartTag"}.getStr() else: "" let factory = newMAtomFactory() let builder = newMiniDOMBuilder(factory) let laststart = builder.factory.strToAtom(laststart0) if "initialStates" notin t: runTest(builder, desc, output, laststart, esc, input) else: for state in t{"initialStates"}: let state = getState(state.getStr()) runTest(builder, desc, output, laststart, esc, input, state) test "contentModelFlags": runTests("contentModelFlags.test") test "domjs": runTests("domjs.test") test "entities": runTests("entities.test") test "escapeFlag": runTests("escapeFlag.test") test "namedEntities": runTests("namedEntities.test") test "numericEntities": runTests("numericEntities.test") #test "pendingSpecChanges": # runTests("pendingSpecChanges.test") test "test1": runTests("test1.test") test "test2": runTests("test2.test") test "test3": runTests("test3.test") test "test4": runTests("test4.test") test "unicodeChars": runTests("unicodeChars.test") test "unicodeCharsProblematic": runTests("unicodeCharsProblematic.test") #test "xmlViolation": # runTests("xmlViolation.test") ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/test/tree.nim��������������������������������������������������������������0000664�0000000�0000000�00000010452�15202323131�0017462�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������include shared/tree_common import std/streams proc runTest(test: TCTest, factory: MAtomFactory, scripting, print: bool) = let ss = newStringStream(test.data) let opts = HTML5ParserOpts[Node, MAtom]( scripting: scripting ) let pdoc = if test.fragment.isNone: parseHTML(ss, opts, factory) else: let ctx = Element() ctx[] = test.fragment.get.ctx[] let childList = parseHTMLFragment(ss, ctx, opts, factory) for child in childList: if ctx.preInsertionValidity(child, nil): ctx.childList.add(child) Document(childList: ctx.childList) if print: var ins = "" for x in test.document.childList: ins &= $x & '\n' var ps = "" for x in pdoc.childList: ps &= $x & '\n' echo "data ", test.data echo "indoc ", $ins echo "psdoc ", $ps checkTest(test.document, pdoc) const rootpath = "test/html5lib-tests/tree-construction/" proc runTests(filename: string, print = false) = let factory = newMAtomFactory() let tests = parseTests(readFile(rootpath & filename), factory) for test in tests: case test.script of SCRIPT_OFF: test.runTest(factory, scripting = false, print = print) of SCRIPT_ON: test.runTest(factory, scripting = true, print = print) of SCRIPT_BOTH: test.runTest(factory, scripting = false, print = print) test.runTest(factory, scripting = true, print = print) test "tests1.dat": runTests("tests1.dat") test "tests2.dat": runTests("tests2.dat") test "tests3.dat": runTests("tests3.dat") test "tests4.dat": runTests("tests4.dat") test "tests5.dat": runTests("tests5.dat") test "tests6.dat": runTests("tests6.dat") test "tests7.dat": runTests("tests7.dat") test "tests8.dat": runTests("tests8.dat") test "tests9.dat": runTests("tests9.dat") test "tests10.dat": runTests("tests10.dat") test "tests11.dat": runTests("tests11.dat") test "tests12.dat": runTests("tests12.dat") # no tests13 in html5lib-tests :) test "tests14.dat": runTests("tests14.dat") test "tests15.dat": runTests("tests15.dat") test "tests16.dat": runTests("tests16.dat") test "tests17.dat": runTests("tests17.dat") test "tests18.dat": runTests("tests18.dat") test "tests19.dat": runTests("tests19.dat") test "tests20.dat": runTests("tests20.dat") test "tests21.dat": runTests("tests21.dat") test "tests22.dat": runTests("tests22.dat") test "tests23.dat": runTests("tests23.dat") test "tests24.dat": runTests("tests24.dat") test "tests25.dat": runTests("tests25.dat") test "tests26.dat": runTests("tests26.dat") test "adoption01.dat": runTests("adoption01.dat") test "adoption02.dat": runTests("adoption02.dat") test "blocks.dat": runTests("blocks.dat") test "comments01.dat": runTests("comments01.dat") test "doctype01.dat": runTests("doctype01.dat") test "domjs-unsafe.dat": runTests("domjs-unsafe.dat") test "entities01.dat": runTests("entities01.dat") test "entities02.dat": runTests("entities02.dat") test "foreign-fragment.dat": runTests("foreign-fragment.dat") test "html5test-com.dat": runTests("html5test-com.dat") test "inbody01.dat": runTests("inbody01.dat") test "isindex.dat": runTests("isindex.dat") test "main-element.dat": runTests("main-element.dat") test "math.dat": runTests("math.dat") test "menuitem-element.dat": runTests("menuitem-element.dat") test "namespace-sensitivity.dat": runTests("namespace-sensitivity.dat") test "noscript01.dat": runTests("noscript01.dat") test "pending-spec-changes.dat": runTests("pending-spec-changes.dat") test "pending-spec-changes-plain-text-unsafe.dat": runTests("pending-spec-changes-plain-text-unsafe.dat") test "plain-text-unsafe.dat": runTests("plain-text-unsafe.dat") test "quirks01.dat": runTests("quirks01.dat") test "ruby.dat": runTests("ruby.dat") test "scriptdata01.dat": runTests("scriptdata01.dat") test "search-element.dat": runTests("search-element.dat") test "svg.dat": runTests("svg.dat") test "tables01.dat": runTests("tables01.dat") test "template.dat": runTests("template.dat") # Sigh. # (This has a test case which doesn't match the spec.) #test "tests_innerHTML_1.dat": # runTests("tests_innerHTML_1.dat") test "tricky01.dat": runTests("tricky01.dat") test "webkit01.dat": runTests("webkit01.dat") test "webkit02.dat": runTests("webkit02.dat") ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/test/tree_charset.nim������������������������������������������������������0000664�0000000�0000000�00000002560�15202323131�0021174�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������include shared/tree_common import std/streams import chame/minidom_cs import chagashi/charset proc runTest(test: TCTest, factory: MAtomFactory, scripting: bool, labels: openArray[string]) = let ss = newStringStream(test.data) let opts = HTML5ParserOpts[Node, MAtom](scripting: scripting) assert test.fragment.isNone var charsets: seq[Charset] = @[] for s in labels: let cs = getCharset(s) assert cs != csUnknown charsets.add(cs) let pdoc = parseHTML(ss, opts, charsets, factory = factory) #[ var ins = "" for x in test.document.childList: ins &= $x & '\n' var ps = "" for x in pdoc.childList: ps &= $x & '\n' echo "data ", test.data echo "indoc ", $ins echo "psdoc ", $ps ]# checkTest(test.document, pdoc) const rootpath = "test/" proc runTests(filename: string, labels: openArray[string]) = let factory = newMAtomFactory() let tests = parseTests(readFile(rootpath & filename), factory) for test in tests: case test.script of SCRIPT_OFF: test.runTest(factory, scripting = false, labels) of SCRIPT_ON: test.runTest(factory, scripting = true, labels) of SCRIPT_BOTH: test.runTest(factory, scripting = false, labels) test.runTest(factory, scripting = true, labels) test "sjis.dat": runTests("sjis.dat", ["utf8", "sjis", "latin1"]) test "latin1.dat": runTests("latin1.dat", ["utf8"]) ������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/test/tree_misc.nim���������������������������������������������������������0000664�0000000�0000000�00000002014�15202323131�0020470�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������include shared/tree_common import std/streams proc runTest(test: TCTest, factory: MAtomFactory, scripting: bool) = let ss = newStringStream(test.data) let opts = HTML5ParserOpts[Node, MAtom](scripting: scripting) assert test.fragment.isNone let pdoc = parseHTML(ss, opts, factory = factory) #[ var ins = "" for x in test.document.childList: ins &= $x & '\n' var ps = "" for x in pdoc.childList: ps &= $x & '\n' echo "data ", test.data echo "indoc ", $ins echo "psdoc ", $ps ]# checkTest(test.document, pdoc) const rootpath = "test/" proc runTests(filename: string) = let factory = newMAtomFactory() let tests = parseTests(readFile(rootpath & filename), factory) for test in tests: case test.script of SCRIPT_OFF: test.runTest(factory, scripting = false) of SCRIPT_ON: test.runTest(factory, scripting = true) of SCRIPT_BOTH: test.runTest(factory, scripting = false) test.runTest(factory, scripting = true) test "gtrsim.dat": runTests("gtrsim.dat") ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chame0/todo�����������������������������������������������������������������������0000664�0000000�0000000�00000000750�15202323131�0015727�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������v2: * use non-deduped seq for attrs; leave foreign attr adjustment to impl (I think caseTable can be removed too) * createComment -> insertComment (so Handle can be set to ParentNode) * zero-copy insertCharacter (maybe attr values too? but that needs a more elaborate CoW scheme) * non-ref Token * sink/lent in iface * standardize identifier names * omit openElementsInit, just add HTML based on ctx? * allow custom seq? etc: * add getElementById and some more basic stuff to minidom ������������������������chawan-v0.4.0/lib/chame0/updver���������������������������������������������������������������������0000775�0000000�0000000�00000001766�15202323131�0016302�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh die() { echo "$*" 2>&1 exit 1 } test "$1" || die "Usage: updver [version]" vv=$(printf '%s\n' "$1" | sed 's/v//') major=$(printf '%s\n' "$vv" | sed 's/\..*//') minor=$(printf '%s\n' "$vv" | sed 's/[^.]*\.\([^.]*\)\..*/\1/') patch=$(printf '%s\n' "$vv" | sed 's/.*\.//') vs="$major.$minor.$patch" oldhdr=$(head -1 NEWS) msgfile=$(mktemp) printf '%s (%s)\n\n' "$vs" "$(date +'%Y.%m.%d')" > "$msgfile" cat NEWS >> "$msgfile" test -n "$EDITOR" || die 'missing $EDITOR env var' $EDITOR "$msgfile" printf 'Ok? (y/n) ' read -r ok case "$ok" in y|Y) ;; *) die "Aborted. (File is $msgfile.)" ;; esac cp "$msgfile" NEWS echo "/version/c version = \"$vs\" . p wq" | ed -s chame.nimble echo "/Major/s/[0-9]*$/$major/ /Minor/s/[0-9]*$/$minor/ /Patch/s/[0-9]*$/$patch/ g/.*/p wq" | ed -s chame/version.nim git add . git commit -m "Version $vs" tmp2=$(mktemp) while read line do if test "$line" = "$oldhdr"; then break; fi printf '%s\n' "$line" done <NEWS >"$tmp2" git tag -faeF "$tmp2" "v$vs" ����������chawan-v0.4.0/lib/chaseccomp/�����������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0016005�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chaseccomp/.gitignore�������������������������������������������������������������0000664�0000000�0000000�00000000135�15202323131�0017774�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/chasc_*.h /chasc_*.c /chasc_defs_* /*.expanded /chaseccomp /*.o /*.d /*~ /dummy /audit_nr.h �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chaseccomp/Makefile���������������������������������������������������������������0000664�0000000�0000000�00000001073�15202323131�0017446�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������CFLAGS += -Wall -Wextra all: chaseccomp.o dummy: dummy.c audit_nr.h: dummy read_nr ./read_nr dummy > $@~ mv $@~ $@ chasc_defs_buffer.c: common.chasc.expanded chasc_defs_network.c: common.chasc.expanded chasc_defs_%.c: %.chasc gen_defs chaseccomp.h audit_nr.h ./gen_defs <$< >$@~ mv $@~ $@ %.chasc.expanded: chasc_defs_%.c $(CC) $(CFLAGS) $(LDFLAGS) -E -P $< -o $@ chasc_%.h: %.chasc.expanded gen_syscalls ./gen_syscalls $< $@ chaseccomp.o: chaseccomp.h chasc_network.h chasc_buffer.h clean: rm -f *.d *.o rm -f *.chasc.expanded chasc_*.h chasc_*.c dummy ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chaseccomp/README.md��������������������������������������������������������������0000664�0000000�0000000�00000002460�15202323131�0017266�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# chaseccomp chaseccomp is a simple BPF assembler for interfacing with seccomp. Input files look something like: ``` # load syscall number load nr # check if it's exit_group ifeq SYS_exit_group allow # if not, die ret kill : allow # else, allow ret allow ``` It has labels, conditional jumps, and support for C identifiers. In fact, C identifiers are just passed on to the C compiler. It also has an "ifeqdef" statement, which wraps each "ifeq" in an ifdef. This lets us use the same filters for all platforms - if it doesn't support a syscall, its "allow" rule just doesn't get compiled in. Ideally, the filter should be constructed by sorting the syscalls in order of usage frequency and then checking each syscall with ifeqdef. The assembler runs in four steps: * audit_nr.h is generated by compiling a dummy program and parsing its ELF header. This is included from common.chasc, which checks the audit arch number at the top of the filter. * gen_defs generates a chasc file with C preprocessor directives from `$<.chasc`. * The C preprocessor reads the chasc file, disabling filters for syscalls that do not apply to this platform. The output is in `$<.chasc.expanded`. * gen_syscalls takes `$<.chasc.expanded` and outputs `chasc_$<.h`. This is the final header file we include in the actual program. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chaseccomp/buffer.chasc�����������������������������������������������������������0000664�0000000�0000000�00000001301�15202323131�0020254�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������include "common.chasc.expanded" # signal handling ifeqdef SYS_rt_sigreturn allow # newer kernels have this instead of sigreturn ifeqdef SYS_sigreturn allow # called by signal trampoline # serializing blob requires dup #TODO sending blob to buffer is not the best idea in the first place ifeqdef SYS_dup allow # network; note that we don't call send/recv in buffer ifeqdef SYS_recvmsg allow ifeqdef SYS_sendmsg allow ifdef SYS_socketcall ifne SYS_socketcall not_socketcall load args[0] ifeq 13 allow # shutdown ifeq 16 allow # sendmsg ifeq 17 allow # recvmsg : not_socketcall endif # warning: nr is no longer loaded here : deny ret trap : kill ret kill : eperm ret errno EPERM : allow ret allow �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chaseccomp/chaseccomp.c�����������������������������������������������������������0000664�0000000�0000000�00000004435�15202323131�0020264�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * ref. seccomp(2) * also bpf(4), except I can't find it on Linux... check a BSD. */ #define _GNU_SOURCE #include <sched.h> #include <stdlib.h> #include <stddef.h> #include <sys/prctl.h> #include <sys/syscall.h> #include <unistd.h> #include <string.h> #include <stdio.h> #include <sys/mman.h> #include <errno.h> #include <sys/socket.h> #include <sys/un.h> #include <fcntl.h> #include <stdint.h> #include <signal.h> #include <assert.h> #include "audit_nr.h" #include "chaseccomp.h" static void sigsys_handler_buffer(int sig, siginfo_t *info, void *ucontext) { (void)sig; (void)ucontext; fprintf(stderr, "Sandbox violation in buffer: syscall #%d\n", info->si_syscall); abort(); } int cha_enter_buffer_sandbox(void) { struct sock_filter filter[] = { #include "chasc_buffer.h" }; #ifndef EXPECTED_COUNT #error "buffer sandbox not built" #endif struct sock_fprog prog = { .len = COUNTOF(filter), .filter = filter }; struct sigaction act = { .sa_flags = SA_SIGINFO, .sa_sigaction = sigsys_handler_buffer, }; static_assert(EXPECTED_COUNT == COUNTOF(filter), "wrong buffer filter count"); if (sigaction(SIGSYS, &act, NULL) < 0) return 0; if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) return 0; if (syscall(SYS_seccomp, SECCOMP_SET_MODE_FILTER, 0, &prog)) return 0; return 1; } static void sigsys_handler_network(int sig, siginfo_t *info, void *ucontext) { (void)sig; (void)ucontext; fprintf(stderr, "Sandbox violation in network: syscall #%d\n", info->si_syscall); abort(); } int cha_enter_network_sandbox(void) { #undef EXPECTED_COUNT struct sock_filter filter[] = { #include "chasc_network.h" }; #ifndef EXPECTED_COUNT #error "network sandbox not built" #endif struct sock_fprog prog = { .len = COUNTOF(filter), .filter = filter }; struct sigaction act = { .sa_flags = SA_SIGINFO, .sa_sigaction = sigsys_handler_network, }; static_assert(EXPECTED_COUNT == COUNTOF(filter), "wrong network filter count"); if (sigaction(SIGSYS, &act, NULL) < 0) return 0; if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) return 0; if (syscall(SYS_seccomp, SECCOMP_SET_MODE_FILTER, 0, &prog)) return 0; return 1; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chaseccomp/chaseccomp.h�����������������������������������������������������������0000664�0000000�0000000�00000002575�15202323131�0020274�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include <stdint.h> /* * seccomp */ #define SECCOMP_SET_MODE_FILTER 1 #define SECCOMP_RET_KILL_PROCESS 0x80000000u #define SECCOMP_RET_ALLOW 0x7FFF0000u #define SECCOMP_RET_TRAP 0x00030000u #define SECCOMP_RET_ERRNO 0x00050000u #define SECCOMP_RET_DATA 0x0000FFFFu struct seccomp_data { int nr; uint32_t arch; uint64_t instruction_pointer; uint64_t args[6]; }; /* * BPF */ /* instruction classes */ #define BPF_LD 0x00 #define BPF_JMP 0x05 #define BPF_RET 0x06 /* ld/ldx fields */ #define BPF_ABS 0x20 #define BPF_W 0x00 /* alu/jmp fields */ #define BPF_JEQ 0x10 #define BPF_JGT 0x20 #define BPF_K 0x00 struct sock_filter { uint16_t code; uint8_t jt; uint8_t jf; uint32_t k; }; struct sock_fprog { unsigned short len; struct sock_filter *filter; }; #define BPF_STMT(code, k) { (unsigned short)(code), 0, 0, k } #define BPF_JUMP(code, k, jt, jf) { (unsigned short)(code), jt, jf, k } /* * chaseccomp stuff */ #define COUNTOF(x) (sizeof(x) / sizeof(*(x))) #define CHA_BPF_LOAD(field) \ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, \ (offsetof(struct seccomp_data, field))) #define CHA_BPF_RET(val) BPF_STMT(BPF_RET | BPF_K, val) #define CHA_BPF_JE(data, n) BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, data, n, 0) #define CHA_BPF_JNE(data, m) BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, data, 0, m) #define CHA_BPF_JLE(data, m) BPF_JUMP(BPF_JMP | BPF_JGT | BPF_K, data, 0, m) �����������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chaseccomp/common.chasc�����������������������������������������������������������0000664�0000000�0000000�00000005207�15202323131�0020304�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������: start include "audit_nr.h" # check if we are using the expected calling convention load arch ifne CHA_AUDIT_NR deny # load syscall nr load nr # socket/file i/o ifeqdef SYS_read allow ifeqdef SYS_write allow # polling ifeqdef SYS_poll allow ifeqdef SYS_ppoll allow # poll is sometimes implemented as ppoll, e.g. musl ifdef CHA_FORCE_SELECT ifeqdef SYS_select allow ifeqdef SYS_pselect6 allow endif # memory allocation ifeqdef SYS_mmap allow ifeqdef SYS_mmap2 allow ifeqdef SYS_mremap allow ifeqdef SYS_munmap allow ifeqdef SYS_brk allow # less common socket/file i/o ifeqdef SYS_writev allow ifeqdef SYS_readv allow ifeqdef SYS_lseek allow ifeqdef SYS_close allow ifeqdef SYS_shutdown allow # prevent glibc from getting our process murdered ifeqdef SYS_fstat eperm ifeqdef SYS_fstat64 eperm ifeqdef SYS_fstatat64 eperm ifeqdef SYS_newfstatat eperm ifeqdef SYS_statx eperm # accept fcntl(2), but only with F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_SETFL. # (F_SETFL is 4, others are 0..3) ifeqdef SYS_fcntl64 is_fcntl64 ifne SYS_fcntl not_fcntl # additional test for fcntl64 on 32-bit systems : is_fcntl64 load args[1] ifle F_SETFL allow load nr : not_fcntl # following syscalls are rarely called ifeqdef SYS_futex allow # bionic libc & WSL both need it ifeqdef SYS_exit allow # for quit ifeqdef SYS_exit_group allow # for quit ifeqdef SYS_restart_syscall allow # for resuming poll on SIGCONT ifeqdef SYS_getrandom allow # glibc calls it when initializing its malloc # so we don't trap on crash ifeqdef SYS_sigaction eperm ifeqdef SYS_rt_sigaction eperm ifeqdef SYS_rt_sigprocmask eperm ifeqdef SYS_gettid eperm ifeqdef SYS_tgkill kill # these are used both by QJS in buffer and by *something* in network # (I could never reproduce it; might have been libcurl, might have been OpenSSL) ifeqdef SYS_clock_gettime allow # used by QuickJS in atomics and cpuTime() ifeqdef SYS_clock_gettime64 allow # same but 32-bit ifeqdef SYS_gettimeofday allow # used by QuickJS in Date.now() # network: used indirectly by OpenSSL EVP_RAND_CTX_new (through drbg) # buffer: apparently used in SIGSEGV handler ifeqdef SYS_getpid allow # bionic-specific stuff ifdef __BIONIC__ ifeqdef SYS_rt_sigprocmap allow ifeqdef SYS_madvise allow #TODO can we make this less broad? # bionic uses prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME) for its pages. ifne SYS_prctl not_prctl load args[0] ifne PR_SET_VMA deny load args[1] ifeq PR_SET_VMA_ANON_NAME allow load nr : not_prctl # bionic also calls mprotect(2) with PROT_READ and PROT_WRITE flags. # Crucially, we don't want to allow PROT_EXEC. ifne SYS_mprotect not_mprotect load args[2] ifle PROT_READ|PROT_WRITE allow load nr : not_mprotect endif /* __BIONIC__ */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chaseccomp/dummy.c����������������������������������������������������������������0000664�0000000�0000000�00000000147�15202323131�0017306�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include <stdio.h> #include <stdlib.h> int main(void) { printf("Hello, world!\n"); exit(0); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chaseccomp/gen_defs���������������������������������������������������������������0000775�0000000�0000000�00000000446�15202323131�0017511�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh LC_ALL=C echo "#include <sys/syscall.h>" sed -E -e 's/#.*//;s/^[[:space:]]*//;s/[[:space:]]*$//;/^$/d' \ -e 's/^ifdef/#&/;s/^endif/#&/;s/^include/#&/' \ -e 's/^(if..)def ([^ ]+) ([^ ]+)$/#ifdef \2\ \1 cha_\2 \3\ #endif/' \ -e 's/^(if..) ([a-zA-Z_]+) ([a-zA-Z_]+)/\1 cha_\2 \3/' ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chaseccomp/gen_syscalls�����������������������������������������������������������0000775�0000000�0000000�00000003042�15202323131�0020420�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh die() { echo "$*" >&2 exit 1 } test "$1" || die "usage: gen_syscalls [input] [output]" find_label() { line=$(printf '%s\n' "$labels" | grep -e "$1 " | head -n 1) if test "$line"; then printf '%d\n' "${line#* }"; fi } line_cut_next() { next=${line%% *} oline=$line line=${line#* } if test "$line" = "$oline"; then line= ; fi } put_cmp() { line_cut_next val=${next#cha_} line_cut_next label=$(find_label "$next") test "$label" || die "missing label $next" label=$(($label - 1 - $ip)) printf '\t%s(%s, %d),\n' "$1" "$val" "$label" } put_load() { line_cut_next printf '\tCHA_BPF_LOAD(%s),\n' "$next" } put_ret() { line_cut_next case $next in allow) val=SECCOMP_RET_ALLOW ;; trap) val=SECCOMP_RET_TRAP ;; kill) val=SECCOMP_RET_KILL_PROCESS ;; errno) val="SECCOMP_RET_ERRNO | ($line & SECCOMP_RET_DATA)" ;; *) die "wrong retval $line" ;; esac printf '\tCHA_BPF_RET(%s),\n' "$val" } sed -ne '/^: start$/,$p' "$1" >"$2~" ip=0 while IFS= read -r line do line=${line%%#*} case $line in ': '*) line_cut_next if test -n "$labels" then labels="$labels $line $ip" else labels="$line $ip" fi ;; '') ;; *) ip=$((ip + 1));; esac done < "$2~" ip=0 while IFS= read -r line do line_cut_next case $next in :) continue ;; ret) put_ret ;; ifeq) put_cmp CHA_BPF_JE;; ifne) put_cmp CHA_BPF_JNE;; ifle) put_cmp CHA_BPF_JLE;; load) put_load;; '') continue;; *) die "unexpected instruction $next" ;; esac ip=$(($ip + 1)) done < "$2~" >"$2~~" mv "$2~~" "$2~" printf '#define EXPECTED_COUNT %d\n' "$ip" >>"$2~" mv "$2~" "$2" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chaseccomp/network.chasc����������������������������������������������������������0000664�0000000�0000000�00000001216�15202323131�0020501�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������include "common.chasc.expanded" # syscall nr is loaded in common.chasc # network ifeqdef SYS_send allow ifeqdef SYS_recv allow ifeqdef SYS_recvfrom allow # required at least by libssh2 ifeqdef SYS_sendto allow # ditto ifeqdef SYS_recvmsg allow ifeqdef SYS_sendmsg allow ifdef SYS_socketcall ifne SYS_socketcall not_socketcall load args[0] ifeq 9 allow # send ifeq 10 allow # recv ifeq 11 allow # sendto ifeq 12 allow # recvfrom ifeq 13 allow # shutdown ifeq 16 allow # sendmsg ifeq 17 allow # recvmsg : not_socketcall endif # warning: nr is no longer loaded here : deny ret trap : kill ret kill : eperm ret errno EPERM : allow ret allow ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/chaseccomp/read_nr����������������������������������������������������������������0000775�0000000�0000000�00000001764�15202323131�0017355�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh # Audit arch numbers are derived from the ELF machine number, so for the # most part we can reconstruct them ourselves by just reading a dummy ELF # binary. # (We could also just run a dummy C program and trigger a SIGSYS, but that # prevents cross-compilation to incompatible architectures.) file=$1 die() { echo "$*" exit 1 } test -n "$file" || die "usage: read_nr [file]" get_bytes() { od -v -t d"$2" -A n -N 1 -j "$1" "$file" | sed 's/ //g' } nr=$(get_bytes 18 2) b=$(get_bytes 4 1) case $b in 1) ;; # 32-bit 2) nr="$nr|0x80000000";; # 64-bit *) die "unexpected byte $b" esac b=$(get_bytes 5 1) case $b in 1) nr="$nr|0x40000000";; # little-endian 2) ;; # big-endian *) die "unexpected byte $b" esac echo "#if defined(__x86_64__) && defined(__ILP32__) /* x86_32 calling convention (not i386!) */ #define CHA_AUDIT_NR 0xC000003E #elif defined(__LP64__) && defined(__mips_n32) /* MIPS n32 calling convention */ #define CHA_AUDIT_NR ($nr|0x20000000) #else #define CHA_AUDIT_NR ($nr) #endif" ������������chawan-v0.4.0/lib/monoucha0/������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0015571�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/.gitignore��������������������������������������������������������������0000664�0000000�0000000�00000000021�15202323131�0017552�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test/* !test/*.* ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/Makefile����������������������������������������������������������������0000664�0000000�0000000�00000001310�15202323131�0017224�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������NIM ?= nim TESTDIR ?= /tmp/chagashi_test FLAGS += --debugger:native .PHONY: all all: test .PHONY: test_basic test_basic: $(NIM) $(FLAGS) r --mm:refc -p:. test/basic.nim $(NIM) $(FLAGS) r --mm:orc -p:. test/basic.nim .PHONY: test_regexonly test_regexonly: $(NIM) $(FLAGS) r --mm:refc -d:lreOnly=1 -p:. test/regexonly.nim $(NIM) $(FLAGS) r --mm:orc -d:lreOnly=1 -p:. test/regexonly.nim .PHONY: test_manual test_manual: $(NIM) $(FLAGS) r --mm:refc -p:. test/manual.nim $(NIM) $(FLAGS) r --mm:orc -p:. test/manual.nim .PHONY: test_etc test_etc: $(NIM) $(FLAGS) r --mm:refc -p:. test/etc.nim $(NIM) $(FLAGS) r --mm:orc -p:. test/etc.nim .PHONY: test test: test_basic test_regexonly test_manual test_etc ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/NEWS��������������������������������������������������������������������0000664�0000000�0000000�00000012052�15202323131�0016270�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0.11.0 (2026.02.07) * switch back to upstream QuickJS * add .jsmark * add many useful procedures to jsutils * fix compilation on 1.6.14 * best-effort ORC support * make nim-results optional * make .jsfin inherited (breaking) * refactor API (very breaking) * remove support for value-only objects * remove jsregex (libregexp bindings remain) * remove extraGetSet QuickJS-NG has plenty of bugs that upstream has fixed in the meantime, as well as other problems (slower, less portable), so I've switched back. ORC "works" if you're prepared to fight the compiler. fromJS has changed a lot, now it returns an "error code" instead of results. This is the last public release of this library. 0.10.0 (2025.03.28) * implement [Replaceable] property as .jsrget, .jsrfget * allow sink parameters * fix .jsget pragma on JSValue properties * fix a bug in transfer of ownership with reference types * derive constructor functions from their parent * always call finalizers on objects, even if they aren't attached to a JSRuntime (in that case they receive nil) * remove getClass, hasClass; use the returned class ID from registerType instead * generate gc_mark functions on registered objects including JSValues * remove ishtmldda from registerType; use the QJS API instead * update QuickJS-NG to 0.9.0 * re-add JSValueConst as a distinct type (it gets auto-converted to JSValue) * various refactoring and optimization This version is mainly focused on fixing bugs and further reducing runtime and compile time overhead. The main breaking change from 0.9 is the introduction of JSValueConst, which makes ownership and borrowing more explicit and eliminates the potential for a class of refcounting bugs. See the manual for details. 0.9.1 (2025.01.16) * add type information to JSArrayBufferView * add some more bindings 0.9.0 (2025.01.13) * drop support for pre-2.0.0 Nim versions * drop support for generics and non-JSValue varargs * drop undocumented $ -> toString renaming * always set fromJS "out" param (set to default on failure) * do not accept JS_NULL for ref object * replace jsgetprop with jsgetrealprop * type erase dfin This version brings a significant reduction in the feature set, and changes in various APIs. Wrappers with implementations deemed inefficient or overly complex have been removed. The JS_NULL change is intended to allow for non-nullable parameters. In particular, it means that procedures with nullable parameters now *must* wrap these in an Option to have the same effect as before. However, ref object return values still convert `nil` to JS_NULL. Also, this release includes an optimization that is expected to break ORC less subtly than before. As always, please make sure to use --mm:refc. 0.8.0 (2024.12.26) * update QuickJS-NG to 0.8.0 0.7.2 (2024.11.25) * fix some deinitialization bugs on JSRuntime.free The test suite was being run for ORC only, so it failed to catch bugs with refc deinitialization. 0.7.1 (2024.11.22) * fix wrong allocation sizes in jspropenum module This could lead to memory corruption. 0.7.0 (2024.11.18) * clean up and complete exotic pragmas Now the Monoucha API can express all exotics that QJS provides. 0.6.0 (2024.11.16) * update QuickJS-NG to 0.7.0 * misc optimizations 0.5.5 (2024.11.09) * fix fromJS with seq * fix JS_FreePropertyEnum binding 0.5.4 (2024.11.08) * fix some C warnings * do not link to pthread with --threads:off 0.5.3 (2024.10.28) * fix assertion on creating 0-length property enum list 0.5.2 (2024.10.12) * fix a bug in our libregexp patch 0.5.1 (2024.10.02) * fix build with --threads:off 0.5.0 (2024.09.29) * switch to QuickJS-NG QuickJS-NG is a better maintained QuickJS fork. It has some useful features like support for recent standards and column tracking for errors. We import their latest release, which is 0.6.1. I plan to update this for every new QJS-NG release. 0.4.3 (2024.09.17) * fix broken enum conversion 0.4.2 (2024.09.17) * throw on trying to call bound functions on prototypes * fix inherited jsgetprop 0.4.1 (2024.08.22) * fix compilation on Nim 2.0.4 0.4.0 (2024.08.15) * remove toJS(Rune) * remove setInteruptHandler wrapper * properly convert to pointer-sized int depending on pointer size * fix incorrect varargs slicing * misc refactoring 0.3.0, 0.3.1 (2024.08.09) * redesign fromJS API to reduce copying - fromJS now returns an Opt[void] to signal errors, and fills the third `res` parameter if it succeeded - JSDict now supports .jsdefault to init values, and throws on missing non-jsdefault values - JSDict JSValue members are now automatically freed This is a breaking change. * allow eval without file name * sync with upstream * fix NUL handling in toJS(string) 0.2.3 (2024.07.28) * fix and optimize varargs[JSValue] jsfunc params 0.2.2 (2024.07.18) * fix wrong header used in libunicode binding 0.2.1 (2024.07.17) * fix a memory corruption bug * add JSValueConst to bindings (for documentation purposes) * update manual 0.2.0 (2024.06.22) * include missing QuickJS bindings * add missing err...Error templates * update manual 0.1.1 (2024.06.03) libunicode wrapper fixes 0.1.0 (2024.06.03) Initial release ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/README.md���������������������������������������������������������������0000664�0000000�0000000�00000005421�15202323131�0017052�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Monoucha: seamless Nim-QuickJS integration Monoucha is a wrapper library to simplify the process of embedding the [QuickJS](https://bellard.org/quickjs/) JavaScript engine into Nim programs. ## Quick start Include Monoucha in your project using either Nimble or as a git submodule. ``` requires "monoucha" ``` Then, * There is a [manual](doc/manual.md). Please read the manual. * [Examples](test/manual.nim) from the manual, organized as unit tests. ## Warning Monoucha works with ORC, but it also depends on `=destroy` hooks with ref objects, which [may leak](https://github.com/nim-lang/Nim/issues/24161) memory in ORC (the interaction between the two features is "undefined".) Therefore, for best results you should put the following in your nim.cfg: ``` --mm:refc ``` ## Dependencies Monoucha has no hard dependencies other than QuickJS and the standard library (in particular, the `tables` module.) QuickJS in turn has no dependencies other than libc. There is an optional `jserror` module which enables error handling that is generic to Nim and QuickJS using the [nim-results](https://github.com/arnetheduck/nim-results) library. QuickJS is already included in this repository; you do not have to install it separately. ## Q&A * Cool, so how do I use this thing? There is a [manual](doc/manual.md). Please read the manual. * I'm getting memory leaks? See the [Warning](#warning) section. (If you are also experiencing issues with refc, please open a ticket [here](https://todo.sr.ht/~bptato/chawan/) and I'll look into it.) * I already have QuickJS, why are you not linking to my system library? Monoucha does not actually use stock QuickJS, but a fork that tracks upstream. This fork includes some GC modifications necessary for the synchronization of the Nim and QuickJS runtimes. * Can I compile Nim to JS and execute Nim from Nim? Possibilities are endless, but [this](https://peterme.net/using-nimscript-as-a-configuration-language-embedding-nimscript-pt-1.html) looks like a better solution. * Can I use Monoucha with `[insert JS engine]` instead of QuickJS? No. Feel free to fork and adapt it to whatever engine you want, but here we only support QuickJS. * What *is* a monoucha? A kind of tea, from the town once called Monou. You pronounce it as mo-no-u-cha. Yes, it's a [pun](https://en.wikipedia.org/w/index.php?title=SpiderMonkey&oldid=1214134789#History). ## License QuickJS was written by Fabrice Bellard and Charlie Gordon. Some patches from QuickJS-NG (maintained by Ben Noordhuis and Saúl Ibarra Corretgé) are also included. QuickJS is distributed in this repository under the terms of the MIT license. See the [monoucha/qjs/LICENSE](monoucha/qjs/LICENSE) file for details. Monoucha is released into the public domain. See the [UNLICENSE](UNLICENSE) file for details. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/UNLICENSE���������������������������������������������������������������0000664�0000000�0000000�00000002273�15202323131�0017045�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to <http://unlicense.org/> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/doc/��������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0016336�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/doc/manual.md�����������������������������������������������������������0000664�0000000�0000000�00000056477�15202323131�0020160�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Monoucha manual **Warning**: currently, Monoucha only works correctly with refc. Using Monoucha with ORC may result in memory leaks. See the [readme](../README.md) for details. ## Table of Contents * [Introduction](#introduction) - [Hello, world](#hello-world) - [Error handling](#error-handling) * [Registering objects](#registering-objects) - [registerType: registering type interfaces](#registertype-registering-type-interfaces) * [Global objects](#global-objects) * [Inheritance](#inheritance) * [Misc registerType parameters](#misc-registertype-parameters) - [jsget, jsset: basic property reflectors](#jsget-jsset-basic-property-reflection) * [Function pragmas](#function-pragmas) - [jsfunc: regular functions](#jsfunc-regular-functions) - [jsctor: constructors](#jsctor-constructors) - [jsfget, jsfset: custom property reflectors](#jsfget-jsfset-custom-property-reflectors) - [jsstfunc: static functions](#jsstfunc-static-functions) - [jsuffunc, jsufget, jsuffget: the LegacyUnforgeable property](#jsuffunc-jsufget-jsuffget-the-legacyunforgeable-property) - [jsgetownprop, jsgetprop, jssetprop, jsdelprop, jshasprop, jspropnames: magic functions](#jsgetownprop-jsgetprop-jssetprop-jsdelprop-jshasprop-jspropnames-magic-functions) - [jsfin: object finalizers](#jsfin-object-finalizers) * [toJS, fromJS](#tojs-fromjs) - [Option vs Opt](#option-vs-opt) - [Using raw JSValues](#using-raw-jsvalues) - [Using toJS](#using-tojs) - [Using fromJS](#using-fromjs) - [Custom type converters](#custom-type-converters) ## Introduction Monoucha is a high-level wrapper to QuickJS, created for the [Chawan](https://sr.ht/~bptato/chawan) browser with the primary aim of automatically generating bindings to JS APIs. Monoucha is high-level, but it does not try to completely abstract away the low-level details. You will in many cases have to use QuickJS APIs directly to achieve something; Monoucha only provides abstractions to APIs where doing something manually would be tedious and/or error-prone. ### Hello, world ```nim import monoucha/javascript let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() const code = "'Hello from JS!'" let val = ctx.eval(code) var res: string assert ctx.fromJS(val, res).isOk # no error echo res # Hello from JS! JS_FreeValue(ctx, val) ctx.free() rt.free() ``` eval() takes two parameters, one for code and one for the file name (used for exception formatting). Note that you have to free the context and runtime handles manually. The `res` variable then holds a QuickJS JSValue. In this case, we convert it to a string before freeing it. You can skip conversion if you don't care about the script's return value, but you *must* free the value. ### Error handling Following code produces a ReferenceError: ```nim const code = "abcd" let val = ctx.eval(code) ``` If you try to convert this into a string, you will get an err() result. This means you should print the exception message *somewhere*, but neither QJS nor Monoucha really cares *where* you print it, or if you print it at all. A simple error handling code may look like: ```nim if JS_IsException(res): stderr.writeLine(ctx.getExceptionMsg()) ``` Usually you'll want to wrap `eval` in a function that deals with exceptions in a way appropriate for your application. ### More convenient error handling with nim-results There is a convenience wrapper for error handling which uses nim-results, which allows writing procedures that throw exceptions but are still generic to JS and Nim. It also includes an `evalConvert` which is like `eval` but returns a `Result` of the desired value or an exception. This is *not* zero-cost, it requires more allocations than just using the QJS APIs. But it does allow for prettier code. ## Registering objects In JavaScript, all objects are passed *by reference*. Monoucha allows you to transparently use Nim object references in JS, provided you register their type interface first. ### registerType: registering type interfaces To register object types as a JavaScript interface, you must call the `registerType` macro on the JS context with a type of your choice. ```nim macro registerType*(ctx: JSContext; t: typed; parent: JSClassID = 0; asglobal: static bool = false; name: static string = ""; namespace = JS_NULL): JSClassID ``` Typically, you would do this using Nim reference types. Non-reference types work too, but have some restrictions covered later. Following code registers a JS interface for the Nim ref object `Moon`: ```nim type Moon = ref object jsDestructor(Moon) # [...] ctx.registerType(Moon) const code = "Moon" let val = ctx.eval(code) var res: string assert ctx.fromJS(val, res).isOk # no error echo res # function Moon() [...] JS_FreeValue(ctx, val) ``` i.e. just call `registerType`. Pay attention to the jsDestructor template: you must call jsDestructor immediately after your type declaration *before* any other functions. (This is necessary so that we can generate a `=destroy` hook for the object.) #### Global objects `registerType` also allows you to change the global object's type. This is quite important, as it is the only way to create global functions (discounting object constructors). To register a global type, set `asglobal = true` in `registerType`: ```nim type Earth = ref object # [...] let earth = Earth() ctx.registerType(Earth, asglobal = true) ctx.setGlobal(earth) const code = "assert(globalThis instanceof Earth)" let val = ctx.eval(code) assert not JS_IsException(val) JS_FreeValue(ctx, val) ``` Notes: * We call `setGlobal` with an instance of Earth. This is needed to register some object as the backing Nim object; this same instance of Earth will be passed to bound functions. * This time, we do not call jsDestructor, because the global object is special-cased; its reference is kept until the JS context gets freed. Therefore it does not need a `=destroy` hook. #### Inheritance `registerType` also allows you to specify inheritance chains by setting the `parent` parameter: ```nim type Planet = ref object of RootObj Earth = ref object of Planet Moon = ref object of Planet # [...] let planetCID = ctx.registerType(Planet) ctx.registerType(Earth, parent = planetCID, asglobal = true) ctx.registerType(Moon, parent = planetCID) ctx.setGlobal(Earth()) # make sure to set a global so global functions work const code = "assert(globalThis instanceof Planet)" let val = ctx.eval(code) assert not JS_IsException(val) JS_FreeValue(ctx, val) ``` In this model, the inheritance tree looks like: * Planet - Earth - Moon There is no strict requirement to actually model the Nim inheritance chain. e.g. if we set "Rock" as the parent of Planet, then we could use Rock as the direct ancestor of Earth without even registering Planet at all. However, this is a two-edged blade, as it also allows specifying invalid models which result in undefined behavior. For example, setting Earth as the `parent` of Moon compiles, but is invalid, and will result in "Moon" Nim objects being cast to Earth references. #### Misc registerType parameters Following parameters also exist: * `name`: set a different JS name than the Nim name * `namespace`: instead of defining the constructor on the global object, define it on the passed JS object. You must use QuickJS APIs to create this object. `namespace` is not consumed (i.e. you must free it yourself). ### jsget, jsset: basic property reflectors The `jsget` and `jsset` pragmas can be set on fields of registered object types to directly expose them to JS: ```nim type Moon = ref object Earth = ref object moon {.jsget.}: Moon name {.jsgetset.}: string population {.jsset.}: int64 jsDestructor(Moon) # [...] let earth = Earth(moon: Moon(), population: 1, name: "Earth") ctx.registerType(Earth, asglobal = true) ctx.registerType(Moon) ctx.setGlobal(earth) const code = """ globalThis.population = 8e9; "name: " + globalThis.name + ", moon: " + globalThis.moon; """ let val = ctx.eval(code) var res: string assert ctx.fromJS(val, res).isOk # no error echo res # name: Earth, moon: [object Moon] echo earth.population # 8e9 JS_FreeValue(ctx, val) ``` In the above example, we expose an Earth instance as the global object, and modify/inspect it. By default, object fields are not exposed to JS; `{.jsget.}` gives JS read-only access, `{.jsset.}` write-only, and `jsgetset` expands to `{.jsget, jsset.}` (both read and write). ## Function pragmas The main feature of Monoucha is that it can automatically wrap functions and expose them to JavaScript by associating them with types exposed through [registerType](#registertype-registering-type-interfaces). All you have to do is to stick pragmas to function definitions. Here we enumerate over all currently available pragmas. ### jsfunc: regular functions The simplest pragma is `.jsfunc`. This marks the function as a member of the JS interface associated with the first parameter's type. Example: ```nim type Window = ref object console {.jsget.}: Console Console = ref object jsDestructor(Console) proc log(console: Console; s: string) {.jsfunc.} = echo s # [...] let window = Window(console: Console()) ctx.registerType(Window, asglobal = true) ctx.registerType(Console) ctx.setGlobal(window) const code = "console.log('Hello, world!')" JS_FreeValue(ctx, ctx.eval(code)) ``` As you can see, `log` has been exposed as a member of the JS interface `Console`. It is possible to use a different name for the JS function than for the Nim procedure. e.g. the following will also expose a `log` function: ```nim proc jsLog(console: Console; s: string) {.jsfunc: "log".} = # [...] ``` In general, you can use any combination of parameters in `.jsfunc` procs. These are converted on a best-effort basis: e.g. in the above example, `console.log(1)` would pass the string "1", not an exception. Monoucha tries to adhere to the WebIDL standard in this regard - the main exception is that `float64` is mapped to `unrestricted double`, not just `double`. The first parameter must be a reference type that has been registered using `registerType`. ```nim type Console2 = object # not ref! proc log(console: var Console2; s: string) {.jsfunc.} = # [...] ``` It is also possible to insert a "zeroeth" parameter to get a reference to the current JS context. This is useful if you want to access state global to the JS context without storing a backreference to the global object: ```nim proc log(ctx: JSContext; console: Console; s: string) {.jsfunc.} = # This assumes you have already setGlobal a Window instance. let global = JS_GetGlobalObject(ctx) var window: Window assert ctx.fromJS(global, window).isOk # no error JS_FreeValue(ctx, global) # Now you can do something with the window, e.g. window.outFile.writeLine(s) ``` It is also possible to use `varargs` in `.jsfunc` functions: ```nim proc log(ctx: JSContext; console: Console; ss: varargs[JSValueConst]) {.jsfunc.} = discard # can be called like `console.log("a", "b", "c", "d")` ``` Only `JSValueConst` varargs are supported. For further information about individual type conversions, see the [toJS, fromJS](#tojs-fromjs) section. ### jsctor: constructors The `.jsctor` pragma is used to define a constructor for a specific type: ```nim type JSFile = ref object path {.jsget.}: string jsDestructor(JSFile) proc newJSFile(path: string): JSFile {.jsctor.} = return JSFile(path: path) # [...] # Use different name in JS through `name': File in JS is mapped to JSFile # in Nim. ctx.registerType(JSFile, name = "File") const code = "console.log(new File('/path/to/file'))" JS_FreeValue(ctx, ctx.eval(code)) # [object File] ``` `.jsctor`, like other pragmas, supports the same "zeroeth" JSContext parameter as [jsfunc](#jsfunc-regular-functions), which is useful when the global object is needed for resource allocation. ### jsfget, jsfset: custom property reflectors The `.jsfget` and `.jsfset` pragmas can be used to define custom getter/setter functions. Like `.jsget` and `.jsset`, they appear as regular getters and setters in JS. However, instead of automatically reflecting a property, `.jsfget` and `.jsfset` allows you to write custom code to handle property accesses. Example: ```nim # [...] (see above for constructor) func name(file: JSFile): string {.jsfget.} = return file.path.substr(file.path.rfind('/') + 1) proc setName(file: JSFile; s: string) {.jsfset: "name".} = let i = file.path.rfind('/') file.path = file.path.substr(0, i) & s # [...] const code = """ const file = new JSFile("/path/to/file"); console.log(file.path); /* /path/to/file */ console.log(file.name); /* file */ file.name = "new-name"; console.log(file.path); /* /path/to/new-name */ """ JS_FreeValue(ctx, ctx.eval(code)) ``` ### jsstfunc: static functions `.jsstfunc` defines a static function on a given interface. Unlike with `.jsfunc`, you must provide at least a single parameter for these functions, with the syntax `Interface#functionName`. Note that `Interface` must be an interface registered through `registerType`. If the interface was renamed, the Nim name (*not* the JS name) must be used. Example: ```nim # [...] (see above for constructor) proc jsExists(path: string): bool {.jsstfunc: "JSFile#exists".} = return fileExists(path) # [...] const code = """ console.log(File.exists("doc/manual.md")); /* true */ """ JS_FreeValue(ctx, ctx.eval(code)) ``` ### jsuffunc, jsufget, jsuffget: the LegacyUnforgeable property The pragmas `.jsuffunc`, `.jsufget` and `.jsuffget` correspond to the WebIDL [`[LegacyUnforgeable]`](https://webidl.spec.whatwg.org/#LegacyUnforgeable) property. Concretely, this means that the function (or getter) is defined on instances of the interface, not on the interface (i.e. object prototype) as a non-configurable property. Even more concretely, this means that the function (or getter) cannot be changed by JavaScript code. ```nim # this will always return the result of the fstat call. proc owner(file: JSFile): int {.jsuffget.} = let fd = open(cstring(file.path), O_RDONLY, 0) if fd == -1: return -1 var stats = Stat.default if fstat(fd, stats) == -1: discard close(fd) return -1 return int(stats.st_uid) proc getOwner(file: JSFile): int {.jsuffget.} = return file.owner # [...] const code = """ const file = new File("doc/manual.md"); const oldGetOwner = file.getOwner; file.getOwner = () => -2; /* doesn't work */ assert(oldGetOwner == file.getOwner); Object.defineProperty(file, "owner", { value: -2 }); /* throws */ """ JS_FreeValue(ctx, ctx.eval(code)) ``` ### jsgetownprop, jsgetprop, jssetprop, jsdelprop, jshasprop, jspropnames: magic functions `.jsgetownprop`, `.jsgetprop`, `.jssetprop`, `.jsdelprop`, `.jshasprop` and `.jspropnames` generate bindings for magic functions. These are mainly useful for collections, where you want to provide custom behavior for property accesses. (TODO elaborate...) ### jsfin: object finalizers The `.jsfin` pragma can be used to clean up resources used by objects at the end of their lifetime. In principle, this is just like the Nim `=destroy` property, except it also tracks the lifetime of possible JS objects which the Nim object may back. (In other words, it's a cross-GC finalizer.) The first parameter must be a reference to the object in question. Only one `.jsfin` procedure per reference type is allowed, but parent `.jsfin` finalizers are inherited. (This used to work differently in previous versions.) `.jsfin` also supports a "zeroeth" parameter, but here it must be a `JSRuntime`, *not* `JSContext`. Example: ```nim type JSFile = ref object path: string buffer: pointer # some internal buffer handled as managed memory jsDestructor(JSFile) proc newJSFile(path: string): JSFile {.jsctor.} = return JSFile( path: path, buffer: alloc(4096) ) var unrefd {.global.} = 0 proc finalize(file: JSFile) {.jsfin.} = if file.buffer != nil: dealloc(file.buffer) # Note: it is not necessary to nil out the pointer; it's just me being # paranoid :P file.buffer = nil inc unrefd # [...] const code = """ { /* following call is in a separate code, so QJS can unref it * immediately. */ const file = new File("doc/manual.md"); } /* in contrast, following file will not be deallocated until the runtime is * gone. */ const file = new File("doc/manual.md"); """ JS_FreeValue(ctx, ctx.eval(code)) GC_fullCollect() # ensure refc runs assert unrefd == 1 # first file is already deallocated ctx.free() GC_fullCollect() # ensure refc runs assert unrefd == 1 # the second file is still available rt.free() assert unrefd == 2 # runtime is freed, so the second file gets deallocated too ``` ## toJS, fromJS This section covers the handling and conversion of JSValue types. While in many cases it is possible to avoid using JSValues, Monoucha does not go out of its way to completely eliminate them. In particular, handling JSValues is unavoidable when: * You want to do something with `eval()`'s result. * You need to call a QuickJS API not wrapped by Monoucha. (e.g. JS function calls) * You want a dynamically typed variable, e.g. for "union" types. ### Option vs Opt In converters, the conventional way to represent null values is to `import std/options`, `import monoucha/jsnull`, and use `Option[T]`. This applies to e.g. strings (which are not nilable in Nim), but also to refs in fromJS so that a registered ref object parameter of a `.jsfunc` is not nullable unless you wrap it in an `Option`. `Opt[T]` in contrast is used for representing errors - to use this, make sure to add: ```nim import monoucha/jserror ``` Typically, it is returned from fromJS as `Opt[void]`; you can use the nim-results functions to handle these. It is also possible to return a `Result[T, JSError]` from a bound procedure, making it easy to return error conditions from procs used both in Nim and JS. (However, returning a JSValue is more efficient.) Monoucha does not use Nim exceptions, and throwing an exception across bound function boundaries will result in undefined behavior. (`--exceptions:setjmp` will mess up the interpreter's internal state; with `--exceptions:goto` it probably just swallows the exception.) ### Using raw JSValues When passing around raw JSValues, it is important to make sure you reference/unreference appropriately. For this, use the `JS_DupValue` and `JS_FreeValue` functions from QuickJS. (When you only have access to a `JSRuntime`, use the `JS_FreeValueRT` and `JS_DupValueRT` variants instead.) Note the presence of JSValueConst; this is a distinct subtype of JSValue that indicates that the value is borrowed. It is analogous to the `lent` keyword in Nim (which is implicit in procedure parameters). In contrast, procedures that take a non-const JSValue are expected to take ownership of said JSValue and eventually free it. This behavior is anologous to the `sink` keyword in Nim. To get raw JSValues in `.jsfunc` (or similar) bound functions, you can simply set the desired parameter's type to `JSValueConst`. This way, you get a "borrowed" JSValue; to keep a reference to these after the function exits, reference them with `JS_DupValue` first. (Analogously, you do not have to free such JSValues as long as you don't call `JS_DupValue` on them, either.) Since JSValues need a JSContext to do anything useful, you may want to set the first parameter of such functions to a `JSContext` type; this passes the current JSContext on to the bound function. (For details, see [above](#jsfunc-regular-functions).) ### Using toJS ```nim proc toJS[T](ctx: JSContext; val: T): JSValue ``` Monoucha internally uses the overloaded `toJS` function to convert bound function return values to JS values. This is available to user code too; simply import the `monoucha/tojs` module. `JSValue`s you get from toJS are owned by you, so you should call `JS_FreeValue` on these when you no longer need them. The `tojs` module also includes some other convenience functions: * `defineProperty`, `definePropertyC`, `definePropertyE`, `definePropertyCW`, `definePropertyCWE`: simple wrappers around `JS_DefineProperty*` functions from the QuickJS API. Unlike the QuickJS versions, they panic on errors, so only use these if you are 100% sure that they always succeed.<br> The `C`, `E`, `CW`, `CWE` represent the "configurable", "enumerable", and "writable" flags of the property.<br> Warning: like in QuickJS, these functions *consume* a JSValue; that is, if you pass a JSValue, then the function will call `JS_FreeValue` on it. * `newFunction`: creates a new JavaScript function. `args` is a list of parameter names, `body` is the JavaScript function body. ### Using fromJS ```nim proc fromJS[T](ctx: JSContext; val: JSValueConst; res: var T): FromJSResult ``` `fromJS` converts QJS `JSValue`s into Nim values. The default converters reside in `monoucha/fromjs`. On success, `fromJS` fills `res` and returns `fjOk`. On failure, `res` is set to an unspecified value, a QuickJS exception is thrown (typically a `TypeError`), and `fjErr` is returned. **Warning**: JSDict in general is somewhat finnicky: you must make sure that their destructors run before deinitializing the runtime. In practice, this means a) you must not use JSDict in the same procedure where you free the JSRuntime, b) you must call GC_fullCollect before freeing the runtime if you use JSDict. (TODO: this all seems very broken. Why isn't JSDict itself just a ref object?) Passing `JS_EXCEPTION` to `fromJS` is valid, and results in no new exception being thrown. ### Custom type converters In Monoucha, object reference types are automatically converted to JS reference types. However, value types are different: trying to pass any other type to/from JS errors out at compilation time. To work around this limitation, you can override `toJS` and `fromJS` for such types. In both cases, it is enough to add an overload for the respective function and expose it to the module where the converter is needed (i.e. where you call `registerType`). ### Implementation details As mentioned before, ref types registered with the registerType macro can be freely passed to JS, and the function-defining macros set functions on their JS prototypes. When a ref type is passed to JS, a shim JS object is associated with the Nim object, and will remain in memory until neither Nim nor JS has references to it. There is a complication in this system: QuickJS has a reference-counting GC, and so does Nim. Associating two objects managed by two separate GCs is problematic: even if you can freely manage the references on both objects, you now have a cycle that only a cycle collector can break up. A cross-GC cycle collector is out of question; then it would be easier to just replace the entire GC in one of the runtimes. (That is probably how a future ARC-based version will work.) So instead, we patch a hook into the QuickJS cycle collector. Every time a JS companion object of a Nim object would be freed, we first check if the Nim object still has references from Nim, and if yes, prevent the JS object from being freed by "moving" a reference to the JS object (i.e. unref Nim, ref JS). Then, if we want to pass the object to JS again, we add no references to the JS object, only to the Nim object. By this, we "moved" the reference back to JS. This way, the Nim cycle collector can destroy the object without problems if no more references to it exist. Once you set some properties on the JS companion object, it will remain even if no more references exist to it in JS for some time, only in Nim. So this works: ```js document.querySelector("html").canary = "chirp"; console.log(document.querySelector("html").canary); /* chirp */ ``` �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha.nimble���������������������������������������������������������0000664�0000000�0000000�00000000355�15202323131�0020575�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Package version = "0.11.0" author = "bptato" description = "Seamless Nim-QuickJS integration" license = "Unlicense" skipDirs = @["test"] # Dependencies requires "nim >= 1.6.14" requires "results >= 0.4.0" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/���������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0017402�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/constcharp.nim�������������������������������������������������0000664�0000000�0000000�00000000645�15202323131�0022260�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} type cstringConstImpl {.importc: "const char*".} = cstring cstringConst* = distinct cstringConstImpl proc `[]`*(s: cstringConst; i: int): char = cstring(s)[i] proc `$`*(s: cstringConst): string {.borrow.} converter toCstring*(s: cstringConst): cstring {.inline.} = return cstring(s) converter toCstringConst*(s: cstring): cstringConst {.inline.} = return cstringConst(s) {.pop.} # raises �������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/cutils.nim�����������������������������������������������������0000664�0000000�0000000�00000000452�15202323131�0021413�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.used.} when not compileOption("threads"): const CFLAGS = "-fwrapv -DCHA_NO_THREADS" else: const CFLAGS = "-fwrapv" {.compile("qjs/cutils.c", CFLAGS).} type JS_BOOL* = distinct cint converter toBool*(x: JS_BOOL): bool = cast[bool](x) converter toJSBool*(x: bool): JS_BOOL = JS_BOOL(x) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/dtoa.nim�������������������������������������������������������0000664�0000000�0000000�00000004707�15202323131�0021046�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} from std/os import parentDir import cutils import constcharp export constcharp {.used.} when not compileOption("threads"): const CFLAGS = "-fwrapv -DCHA_NO_THREADS" else: const CFLAGS = "-fwrapv" {.compile("qjs/dtoa.c", CFLAGS).} {.passc: "-I" & currentSourcePath().parentDir().} {.push header: "qjs/dtoa.h", importc.} # maximum number of digits for fixed and frac formats const JS_DTOA_MAX_DIGITS* = 101 # radix != 10 is only supported with flags = JS_DTOA_FORMAT_FREE # use as many digits as necessary const JS_DTOA_FORMAT_FREE* = (0 shl 0) # use n_digits significant digits (1 <= n_digits <= JS_DTOA_MAX_DIGITS) const JS_DTOA_FORMAT_FIXED* = (1 shl 0) # force fractional format: [-]dd.dd with n_digits fractional digits. # 0 <= n_digits <= JS_DTOA_MAX_DIGITS const JS_DTOA_FORMAT_FRAC* = (2 shl 0) const JS_DTOA_FORMAT_MASK* = (3 shl 0) # select exponential notation either in fixed or free format const JS_DTOA_EXP_AUTO* = (0 shl 2) const JS_DTOA_EXP_ENABLED* = (1 shl 2) const JS_DTOA_EXP_DISABLED* = (2 shl 2) const JS_DTOA_EXP_MASK* = (3 shl 2) const JS_DTOA_MINUS_ZERO* = (1 shl 4) # show the minus sign for -0 # only accepts integers (no dot, no exponent) const JS_ATOD_INT_ONLY* = (1 shl 0) # accept Oo and Ob prefixes in addition to 0x prefix if radix = 0 const JS_ATOD_ACCEPT_BIN_OCT* = (1 shl 1) # accept O prefix as octal if radix == 0 and properly formed (Annex B) const JS_ATOD_ACCEPT_LEGACY_OCTAL* = (1 shl 2) # accept _ between digits as a digit separator const JS_ATOD_ACCEPT_UNDERSCORES* = (1 shl 3) type JSDTOATempMem* {.importc, header: "qjs/dtoa.h".} = object mem*: array[37, uint64] JSATODTempMem* {.importc, header: "qjs/dtoa.h".} = object mem*: array[27, uint64] # return a maximum bound of the string length proc js_dtoa_max_len*(d: cdouble; radix, n_digits, flags: cint): cint # return the string length proc js_dtoa*(buf: cstring; d: cdouble; radix, n_digits, flags: cint; tmp_mem: var JSDTOATempMem): cint proc js_atod*(str: cstringConst; pnext: ptr cstringConst; radix, flags: cint; tmp_mem: var JSATODTempMem): cdouble # additional exported functions proc u32toa*(buf: cstring; n: uint32): csize_t proc i32toa*(buf: cstring; n: int32): csize_t proc u64toa*(buf: cstring; n: uint64): csize_t proc i64toa*(buf: cstring; n: int64): csize_t proc u64toa_radix*(buf: cstring; n: uint64; radix: cuint): csize_t proc i64toa_radix*(buf: cstring; n: int64; radix: cuint): csize_t {.pop.} # header, importc {.pop.} # raises ���������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/fromjs.nim�����������������������������������������������������0000664�0000000�0000000�00000040546�15202323131�0021420�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/algorithm import std/macros import std/tables import jsopaque import jstypes import quickjs import tojs type FromJSResult* = enum fjErr, fjOk proc fromJS*(ctx: JSContext; val: JSValueConst; res: var string): FromJSResult proc fromJS*(ctx: JSContext; val: JSValueConst; res: var int16): FromJSResult proc fromJS*(ctx: JSContext; val: JSValueConst; res: var int32): FromJSResult proc fromJS*(ctx: JSContext; val: JSValueConst; res: var int64): FromJSResult proc fromJS*(ctx: JSContext; val: JSValueConst; res: var uint16): FromJSResult proc fromJS*(ctx: JSContext; val: JSValueConst; res: var uint32): FromJSResult proc fromJS*(ctx: JSContext; val: JSValueConst; res: var int): FromJSResult proc fromJS*(ctx: JSContext; val: JSValueConst; res: var float64): FromJSResult proc fromJS*[T: tuple](ctx: JSContext; val: JSValueConst; res: var T): FromJSResult proc fromJS*[T](ctx: JSContext; val: JSValueConst; res: var seq[T]): FromJSResult proc fromJS*[T](ctx: JSContext; val: JSValueConst; res: var set[T]): FromJSResult proc fromJS*[A, B](ctx: JSContext; val: JSValueConst; res: var JSKeyValuePair[A, B]): FromJSResult proc fromJS*(ctx: JSContext; val: JSValueConst; res: var bool): FromJSResult proc fromJS*[T: enum](ctx: JSContext; val: JSValueConst; res: var T): FromJSResult proc fromJS*[T](ctx: JSContext; val: JSValueConst; res: var ptr T): FromJSResult proc fromJS*[T: ref object](ctx: JSContext; val: JSValueConst; res: var T): FromJSResult proc fromJS*[T: JSDict](ctx: JSContext; val: JSValueConst; res: var T): FromJSResult proc fromJS*(ctx: JSContext; val: JSValueConst; res: var JSArrayBuffer): FromJSResult proc fromJS*(ctx: JSContext; val: JSValueConst; res: var JSArrayBufferView): FromJSResult proc fromJS*(ctx: JSContext; val: JSValueConst; res: var JSValueConst): FromJSResult proc fromJS*(ctx: JSContext; val: JSValueConst; res: var JSValue): FromJSResult template isOk*(res: FromJSResult): bool = res == fjOk template isErr*(res: FromJSResult): bool = res == fjErr template `?`(res: FromJSResult) = if res == fjErr: return fjErr proc isInstanceOf(ctx: JSContext; classid, tclassid: JSClassID): bool = let rtOpaque = JS_GetRuntime(ctx).getOpaque() var classid = classid var found = false while true: if classid == tclassid: found = true break if int(classid) < rtOpaque.classes.len: classid = rtOpaque.classes[int(classid)].parent else: classid = 0 # not defined by us; assume parent is Object. if classid == 0: break return found proc isSequence*(ctx: JSContext; o: JSValueConst): bool = if not JS_IsObject(o): return false let prop = JS_GetProperty(ctx, o, ctx.getOpaque().symRefs[jsyIterator]) # prop can't be exception (throws_ref_error is 0 and tag is object) result = not JS_IsUndefined(prop) JS_FreeValue(ctx, prop) proc fromJSFree*[T](ctx: JSContext; val: JSValue; res: var T): FromJSResult = result = ctx.fromJS(val, res) JS_FreeValue(ctx, val) proc fromJS*(ctx: JSContext; val: JSValueConst; res: var string): FromJSResult = var plen {.noinit.}: csize_t let outp = JS_ToCStringLen(ctx, plen, val) # cstring if outp == nil: return fjErr res = newString(plen) if plen != 0: copyMem(addr res[0], cstring(outp), plen) JS_FreeCString(ctx, outp) fjOk proc fromJS*(ctx: JSContext; val: JSValueConst; res: var int16): FromJSResult = var n {.noinit.}: int32 if JS_ToInt32(ctx, n, val) < 0: return fjErr res = cast[int16](n) fjOk proc fromJS*(ctx: JSContext; val: JSValueConst; res: var int32): FromJSResult = var n {.noinit.}: int32 if JS_ToInt32(ctx, n, val) < 0: return fjErr res = n fjOk proc fromJS*(ctx: JSContext; val: JSValueConst; res: var int64): FromJSResult = var n {.noinit.}: int64 if JS_ToInt64(ctx, n, val) < 0: return fjErr res = n fjOk proc fromJS*(ctx: JSContext; val: JSValueConst; res: var uint16): FromJSResult = var n {.noinit.}: uint32 if JS_ToUint32(ctx, n, val) < 0: return fjErr res = uint16(n) fjOk proc fromJS*(ctx: JSContext; val: JSValueConst; res: var uint32): FromJSResult = var n {.noinit.}: uint32 if JS_ToUint32(ctx, n, val) < 0: return fjErr res = n fjOk proc fromJS*(ctx: JSContext; val: JSValueConst; res: var int): FromJSResult = when sizeof(int) > 4: var x: int64 else: var x: int32 ?ctx.fromJS(val, x) res = int(x) fjOk proc fromJS*(ctx: JSContext; val: JSValueConst; res: var float64): FromJSResult = var n {.noinit.}: float64 if JS_ToFloat64(ctx, n, val) < 0: return fjErr res = n fjOk proc readTupleDone(ctx: JSContext; it, nextMethod: JSValueConst): FromJSResult = let next = JS_Call(ctx, nextMethod, it, 0, nil) let ctxOpaque = ctx.getOpaque() let doneVal = JS_GetProperty(ctx, next, ctxOpaque.strRefs[jstDone]) var done = false if ctx.fromJSFree(doneVal, done).isErr or done: JS_FreeValue(ctx, next) if not done: return fjErr return fjOk while true: let next = JS_Call(ctx, nextMethod, it, 0, nil) let doneVal = JS_GetProperty(ctx, next, ctxOpaque.strRefs[jstDone]) var done = false if ctx.fromJSFree(doneVal, done).isErr or done: JS_FreeValue(ctx, next) if done: JS_ThrowTypeError(ctx, "too many tuple members") return fjErr JS_FreeValue(ctx, JS_GetProperty(ctx, next, ctxOpaque.strRefs[jstValue])) JS_FreeValue(ctx, next) fjOk proc fromJSTupleBody[T](ctx: JSContext; it, nextMethod: JSValueConst; res: var T): FromJSResult = for f in res.fields: let next = JS_Call(ctx, nextMethod, it, 0, nil) let doneVal = JS_GetProperty(ctx, next, ctx.getOpaque().strRefs[jstDone]) var done = false if ctx.fromJSFree(doneVal, done).isErr or done: if done: JS_ThrowTypeError(ctx, "too few arguments in sequence") JS_FreeValue(ctx, next) return fjErr let valueVal = JS_GetProperty(ctx, next, ctx.getOpaque().strRefs[jstValue]) JS_FreeValue(ctx, next) ?ctx.fromJSFree(valueVal, f) ctx.readTupleDone(it, nextMethod) proc fromJS*[T: tuple](ctx: JSContext; val: JSValueConst; res: var T): FromJSResult = let it = JS_Invoke(ctx, val, ctx.getOpaque().symRefs[jsyIterator], 0, nil) let nextMethod = JS_GetProperty(ctx, it, ctx.getOpaque().strRefs[jstNext]) if JS_IsException(nextMethod): JS_FreeValue(ctx, it) return fjErr result = ctx.fromJSTupleBody(it, nextMethod, res) JS_FreeValue(ctx, it) JS_FreeValue(ctx, nextMethod) type SeqItResult = enum sirDone, sirContinue, sirException proc fromJSSeqIt(ctx: JSContext; it, nextMethod: JSValueConst; res: var JSValue): SeqItResult = let next = JS_Call(ctx, nextMethod, it, 0, nil) let doneVal = JS_GetProperty(ctx, next, ctx.getOpaque().strRefs[jstDone]) var done = false if ctx.fromJSFree(doneVal, done).isOk and not done: res = JS_GetProperty(ctx, next, ctx.getOpaque().strRefs[jstValue]) JS_FreeValue(ctx, next) return sirContinue JS_FreeValue(ctx, next) if not done: return sirException # conversion error sirDone # actually done proc fromJS*[T](ctx: JSContext; val: JSValueConst; res: var seq[T]): FromJSResult = let it = JS_Invoke(ctx, val, ctx.getOpaque().symRefs[jsyIterator], 0, nil) let nextMethod = JS_GetProperty(ctx, it, ctx.getOpaque().strRefs[jstNext]) if JS_IsException(nextMethod): JS_FreeValue(ctx, it) return fjErr var status = fjOk var tmp = newSeq[T]() while status.isOk: var val: JSValue case ctx.fromJSSeqIt(it, nextMethod, val) of sirException: status = fjErr break of sirDone: res = move(tmp) break of sirContinue: tmp.add(default(T)) status = ctx.fromJSFree(val, tmp[^1]) JS_FreeValue(ctx, it) JS_FreeValue(ctx, nextMethod) status proc fromJS*[T](ctx: JSContext; val: JSValueConst; res: var set[T]): FromJSResult = let it = JS_Invoke(ctx, val, ctx.getOpaque().symRefs[jsyIterator], 0, nil) let nextMethod = JS_GetProperty(ctx, it, ctx.getOpaque().strRefs[jstNext]) if JS_IsException(nextMethod): JS_FreeValue(ctx, it) return fjErr var status = fjOk var tmp: set[T] = {} while status.isOk: var val: JSValue case ctx.fromJSSeqIt(it, nextMethod, val) of sirException: status = fjErr break of sirDone: res = tmp break of sirContinue: var x: T status = ctx.fromJSFree(val, x) tmp.incl(x) JS_FreeValue(ctx, it) JS_FreeValue(ctx, nextMethod) status proc fromJS*[A, B](ctx: JSContext; val: JSValueConst; res: var JSKeyValuePair[A, B]): FromJSResult = if JS_IsException(val): return fjErr var ptab: ptr UncheckedArray[JSPropertyEnum] var plen: uint32 let flags = JS_GPN_STRING_MASK if JS_GetOwnPropertyNames(ctx, addr ptab, addr plen, val, flags) == -1: # exception return fjErr var tmp = newSeqOfCap[tuple[name: A, value: B]](plen) for i in 0 ..< plen: let atom = ptab[i].atom let k = JS_AtomToValue(ctx, atom) var kn: A if ctx.fromJSFree(k, kn).isErr: JS_FreePropertyEnum(ctx, ptab, plen) return fjErr let v = JS_GetProperty(ctx, val, atom) var vn: B if ctx.fromJSFree(v, vn).isErr: JS_FreePropertyEnum(ctx, ptab, plen) return fjErr tmp.add((move(kn), move(vn))) JS_FreePropertyEnum(ctx, ptab, plen) res = JSKeyValuePair[A, B](s: move(tmp)) fjOk proc fromJS*(ctx: JSContext; val: JSValueConst; res: var bool): FromJSResult = let ret = JS_ToBool(ctx, val) if ret == -1: # exception return fjErr res = ret != 0 fjOk proc cmpItem(x: EnumMapItem; y: JSAtom): int = cmp(uint32(x.atom), uint32(y)) proc fromJSEnumBody(ctx: JSContext; val: JSValueConst; enumId: int; enums: openArray[string]; tname: cstring): int32 = if not ctx.putEnums(enumId, enums): return -1 let atom = JS_ValueToAtom(ctx, val) if atom == JS_ATOM_NULL: return -1 let rtOpaque = JS_GetRuntime(ctx).getOpaque() let i = rtOpaque.enumMap[enumId].enums.binarySearch(atom, cmpItem) JS_FreeAtom(ctx, atom) if i == -1: JS_ThrowTypeError(ctx, "invalid value for enumeration %s", tname) return -1 return rtOpaque.enumMap[enumId].enums[i].n proc getEnumMap[T: enum](t: typedesc[T]): array[T, string] = result = array[T, string].default for e, s in result.mpairs: s = $e proc fromJS*[T: enum](ctx: JSContext; val: JSValueConst; res: var T): FromJSResult = const tname = cstring($T) const enumId = getJSEnumId(T) const enums = getEnumMap(T) let n = ctx.fromJSEnumBody(val, enumId, enums, tname) if n == -1: return fjErr {.push rangeChecks: off.} res = T(n) {.pop.} fjOk proc fromJS(ctx: JSContext; val: JSValueConst; nimt: pointer; res: var pointer): FromJSResult = if not JS_IsObject(val): if not JS_IsException(val): JS_ThrowTypeError(ctx, "value is not an object") return fjErr let ctxOpaque = ctx.getOpaque() var classid: JSClassID var p: pointer if JS_VALUE_GET_PTR(ctxOpaque.global) != JS_VALUE_GET_PTR(val): p = JS_GetAnyOpaque(val, classid) else: classid = ctxOpaque.gclass p = ctxOpaque.globalObj let rtOpaque = JS_GetRuntime(ctx).getOpaque() let tclassid = rtOpaque.typemap.getOrDefault(nimt, 0) if p == nil or not ctx.isInstanceOf(classid, tclassid): # dumb way to invoke JS_ThrowTypeErrorInvalidClass discard JS_GetOpaque2(ctx, JS_UNDEFINED, tclassid) return fjErr res = p fjOk proc fromJS*[T](ctx: JSContext; val: JSValueConst; res: var ptr T): FromJSResult = let nimt = getTypePtr(T) var x: pointer ?ctx.fromJS(val, nimt, x) res = cast[ptr T](x) fjOk proc fromJS*[T: ref object](ctx: JSContext; val: JSValueConst; res: var T): FromJSResult = let nimt = getTypePtr(T) var x: pointer ?ctx.fromJS(val, nimt, x) res = cast[T](x) fjOk proc fromJSThis*[T: ref object](ctx: JSContext; val: JSValueConst; res: var T): FromJSResult = # translate undefined -> global if JS_IsUndefined(val): return ctx.fromJS(ctx.getOpaque().global, res) return ctx.fromJS(val, res) macro fromJSDictBody(ctx: JSContext; val: JSValueConst; res, t: typed) = let impl = t.getTypeInst()[1].getImpl() let convertStmts = newStmtList() let success = ident("success") var isOptional = true var identDefsStack = @[impl[2]] let jsDictType = JSDict.getType() var undefInit = newStmtList() while identDefsStack.len > 0: let def = identDefsStack.pop() case def.kind of nnkRecList, nnkObjectTy: for child in def.children: if child.kind != nnkEmpty: identDefsStack.add(child) of nnkOfInherit: let other = def[0].getType() if not other.sameType(jsDictType) and not jsDictType.sameType(other): identDefsStack.add(other.getTypeInst().getImpl()[2][2]) else: assert def.kind == nnkIdentDefs var fallback: NimNode = nil var name = def[0] if name.kind == nnkPragmaExpr: for varPragma in name[1]: if varPragma.kind == nnkExprColonExpr: if varPragma[0].strVal == "jsdefault": fallback = varPragma[1] elif varPragma.kind == nnkSym: if varPragma.strVal == "jsdefault": let typ = def[1] fallback = quote do: `typ`.default name = name[0] if name.kind == nnkPostfix: # This is a public field. We are skipping the postfix * name = name[1] if $name == "toFree": continue if fallback != nil: undefInit.add(quote do: `res`.`name` = `fallback`) else: isOptional = false let nameStr = newStrLitNode($name) let it = if fallback != nil: quote do: let prop = JS_GetPropertyStr(`ctx`, `val`, `nameStr`) if not JS_IsUndefined(prop): res.toFree.vals.add(prop) if `ctx`.fromJS(prop, `res`.`name`) == fjErr: return fjErr else: quote do: missing = `nameStr` let prop = JS_GetPropertyStr(`ctx`, `val`, missing) if JS_IsUndefined(prop): break `success` res.toFree.vals.add(prop) if `ctx`.fromJS(prop, `res`.`name`) == fjErr: return fjErr convertStmts.add(it) let undefCheck = if isOptional: quote do: if JS_IsUndefined(val) or JS_IsNull(val): return fjOk else: newStmtList() result = quote do: `undefInit` `undefCheck` if not JS_IsObject(val): JS_ThrowTypeError(ctx, "dictionary is not an object") return fjErr res.toFree = JSDictToFreeAux() var missing {.inject.}: cstring = nil block `success`: `convertStmts` return fjOk JS_ThrowTypeError(ctx, "missing field %s", missing) return fjErr # For some reason, the compiler can't deal with this. proc fromJS*[T: JSDict](ctx: JSContext; val: JSValueConst; res: var T): FromJSResult = fromJSDictBody(ctx, val, res, T) proc fromJS*(ctx: JSContext; val: JSValueConst; res: var JSArrayBuffer): FromJSResult = var len {.noinit.}: csize_t let p = JS_GetArrayBuffer(ctx, len, val) if p == nil: return fjErr res = JSArrayBuffer(len: len, p: cast[ptr UncheckedArray[uint8]](p)) fjOk proc fromJS*(ctx: JSContext; val: JSValueConst; res: var JSArrayBufferView): FromJSResult = var offset {.noinit.}: csize_t var len {.noinit.}: csize_t var bytesPerItem {.noinit.}: csize_t let jsbuf = JS_GetTypedArrayBuffer(ctx, val, offset, len, bytesPerItem) if JS_IsException(jsbuf): return fjErr if uint64(offset) + uint64(len) > uint64(int32.high): JS_FreeValue(ctx, jsbuf) JS_ThrowRangeError(ctx, "array buffer view too large") return fjErr var abuf: JSArrayBuffer ?ctx.fromJSFree(jsbuf, abuf) res = JSArrayBufferView( abuf: abuf, offset: cast[int](offset), len: cast[int](len), bytesPerItem: uint8(bytesPerItem), t: JSTypedArrayEnum(JS_GetTypedArrayType(val)) ) fjOk proc fromJS*(ctx: JSContext; val: JSValueConst; res: var JSValueConst): FromJSResult = res = val fjOk proc fromJS*(ctx: JSContext; val: JSValueConst; res: var JSValue): FromJSResult = res = JS_DupValue(ctx, val) fjOk proc fromJS*(ctx: JSContext; atom: JSAtom; res: var JSAtom): FromJSResult = res = atom fjOk proc fromJS*(ctx: JSContext; atom: JSAtom; res: var string): FromJSResult = var len: csize_t let cs = JS_AtomToCStringLen(ctx, addr len, atom) if cs == nil: return fjErr if len > csize_t(int.high): JS_FreeCString(ctx, cs) JS_ThrowRangeError(ctx, "string length out of bounds") return fjErr res = newString(int(len)) if len > 0: copyMem(addr res[0], cast[pointer](cs), len) JS_FreeCString(ctx, cs) fjOk {.pop.} # raises: [] ����������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/javascript.nim�������������������������������������������������0000664�0000000�0000000�00000000157�15202323131�0022260�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import jsbind, jstypes, jsutils, tojs, fromjs, quickjs export jsbind, jstypes, jsutils, tojs, fromjs, quickjs �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/jsbind.nim�����������������������������������������������������0000664�0000000�0000000�00000142557�15202323131�0021376�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Macro-based JavaScript binding generator. Values are converted from JS to ## Nim and vice versa using generic overloaded functions; users can also ## define their own converters. See the `tojs` and `fromjs` modules for ## details. ## ## Pragmas: ## ## {.jsctor.} for constructors. These have no `this' value, and are bound ## as regular constructors in JS. They must return a ref object, which ## will have a JS counterpart too. (Other functions can return ref ## objects too, which will either use the existing JS counterpart, if ## exists, or create a new one.) ## ## {.jsfctor.} is like {.jsctor.}, but can also be called as a regular ## function. ## ## {.jsfunc.} is used for binding normal functions. Needs a `this' ## value, as all following pragmas. Generics are not supported, but ## JSValue is. ## ## By default, the Nim function name is bound; if this is not desired, ## you can rename the function like this: {.jsfunc: "preferredName".} ## This also works for all other pragmas that define named functions ## in JS. ## ## {.jsstfunc.} binds static functions. Unlike .jsfunc, it does not ## have a `this' value. A class name must be specified, e.g. ## {.jsstfunc: "URL".} to define on the URL class. To rename a static ## function, use the syntax "ClassName#funcName", e.g. "Response#error". ## ## {.jsget.}, {.jsfget.} must be specified on object fields; these ## generate regular getter & setter functions. ## ## {.jsufget, jsuffget, jsuffunc.} For fields with the ## [LegacyUnforgeable] WebIDL property. ## ## This makes it so a non-configurable/writable, but enumerable ## property is defined on the object when the *constructor* is called ## (i.e. NOT on the prototype.) ## ## {.jsrget.}, {.jsrfget.}: For fields with the [Replaceable] WebIDL ## property. ## ## {.jsfget.} and {.jsfset.} for getters/setters. Note the `f'; bare ## jsget/jsset can only be used on object fields. (I initially wanted ## to use the same keyword, unfortunately that didn't work out.) ## ## {.jsgetownprop.} Called when GetOwnProperty would return nothing. The ## key must be either a JSAtom, uint32 or string. (Note that the string ## variant copies.) ## ## {.jsgetprop.} for property getters. Called on GetProperty. (This can be ## emulated using get_own_property, but this might still be faster.) ## ## {.jssetprop.} for property setters. Called on SetProperty - this is the ## set() method of Proxy, except it always returns true. Same rules as ## jsgetprop for keys. ## ## {.jsdelprop.} for property deletion. It is like the deleteProperty() ## method of Proxy. Must return true if deleted, false if not deleted. ## ## {.jshasprop.} for overriding has_property. Must return a boolean, ## or the integer 1 for true, 0 for false, or -1 for exception. ## ## {.jspropnames.} overrides get_own_property_names. Must return a ## JSPropertyEnumList object. {.push raises: [].} import std/macros import std/sets import std/tables import fromjs import jsopaque import jsutils import quickjs import tojs when sizeof(int) < sizeof(int64): export quickjs.`==` type JSFunctionList = openArray[JSCFunctionListEntry] BoundFunctionType = enum bfFunction = "js_func" bfConstructor = "js_ctor" bfConstructorFunction = "js_fctor" bfGetter = "js_get" bfSetter = "js_set" bfPropertyGetOwn = "js_prop_get_own" bfPropertyGet = "js_prop_get" bfPropertySet = "js_prop_set" bfPropertyDel = "js_prop_del" bfPropertyHas = "js_prop_has" bfPropertyNames = "js_prop_names" bfFinalizer = "js_fin" bfMark = "js_mark" BoundFunctionFlag = enum bffNone, bffUnforgeable, bffStatic, bffReplaceable BoundFunction = object t: BoundFunctionType flag: BoundFunctionFlag magic: uint16 name: string id: NimNode JSIterableType* = enum jitNone, jitValue, jitPair proc bindMalloc(s: JSMallocStateP; size: csize_t): pointer {.cdecl.} = return alloc(size) proc bindFree(s: JSMallocStateP; p: pointer) {.cdecl.} = if p != nil: dealloc(p) proc bindRealloc(s: JSMallocStateP; p: pointer; size: csize_t): pointer {.cdecl.} = return realloc(p, size) proc newJSRuntime*(): JSRuntime = ## Instantiate a Monoucha `JSRuntime`. var mf {.global.} = JSMallocFunctions( js_malloc: bindMalloc, js_free: bindFree, js_realloc: bindRealloc, js_malloc_usable_size: nil ) return JS_NewRuntime2(addr mf, nil) proc setGlobalRuntime*(rt: JSRuntime) = let opaque = JSRuntimeOpaque() GC_ref(opaque) JS_SetRuntimeOpaque(rt, cast[pointer](opaque)) # Must be added after opaque is set, or there is a chance of # nimFinalizeForJS dereferencing it (at the new call). globalRuntime = rt proc newGlobalJSRuntime*(): JSRuntime = let rt = newJSRuntime() if rt != nil: setGlobalRuntime(rt) return rt proc newJSContext*(rt: JSRuntime): JSContext = ## Instantiate a Monoucha `JSContext`. ## It is only valid to call Monoucha procedures on contexts initialized with ## `newJSContext`, as it does extra initialization over `JS_NewContext`. let ctx = JS_NewContext(rt) let opaque = newJSContextOpaque(ctx) GC_ref(opaque) JS_SetContextOpaque(ctx, cast[pointer](opaque)) return ctx proc free*(ctx: JSContext) = ## Free the JSContext and associated resources. ## Note: this is not an alias of `JS_FreeContext`; `free` also frees various ## JSValues stored on context startup by `newJSContext`. let opaque = ctx.getOpaque() if opaque != nil: for a in opaque.symRefs: JS_FreeAtom(ctx, a) for a in opaque.strRefs: JS_FreeAtom(ctx, a) for v in opaque.valRefs: JS_FreeValue(ctx, v) for ctor in opaque.ctors: JS_FreeValue(ctx, ctor) if opaque.globalObj != nil: let rt = JS_GetRuntime(ctx) let rtOpaque = rt.getOpaque() for fin in rtOpaque.finalizers(opaque.gclass): fin(rt, cast[pointer](opaque.globalObj)) when defined(gcDestructors): rtOpaque.classes[opaque.gclass].dtor(opaque.globalObj) else: GC_unref(cast[RootRef](opaque.globalObj)) rtOpaque.plist.del(opaque.globalObj) JS_FreeValue(ctx, opaque.global) GC_unref(opaque) JS_FreeContext(ctx) proc free*(rt: JSRuntime) = ## Free the `JSRuntime` rt and remove it from the global JSRuntime pool. # # We must prepare space for opaque refs & pointers here, so that we # can avoid allocations during cleanup. Otherwise we risk triggering a # GC cycle and that would break cleanup too... # # (But we must *not* collect them yet; wait until the cycles are collected # once.) let rtOpaque = rt.getOpaque() for map in rtOpaque.enumMap: for atom in map.atoms: JS_FreeAtomRT(rt, atom) for it in map.enums: JS_FreeAtomRT(rt, it.atom) rtOpaque.tmplist.setLen(rtOpaque.plist.len) GC_unref(rtOpaque) # For refc: ensure there are no ghost Nim objects holding onto JS # values. try: GC_fullCollect() except Exception: quit(1) JS_RunGC(rt) assert rtOpaque.destroying == nil # Now comes a very elaborate dance to ensure that ordering # dependencies are satisfied: # * plist must be cleared before finalizers run. # * Individual finalizers rely on their opaques being set. # * Bound JSValues must not drop to a refcount of 0 before their # opaque is cleared, lest they try to mark related JSValues and/or # claw back their refcount in can_destroy. # * Allocations must not occur during deinitialization. # # For this we need three passes over the object map. Theoretically, two # passes would be enough if move worked reliably across Nim versions. var np = 0 for nimp, jsp in rtOpaque.plist: discard JS_DupValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, jsp)) rtOpaque.tmplist[np] = (nimp, jsp) inc np rtOpaque.plist.clear() for it in rtOpaque.tmplist.toOpenArray(0, np - 1): let val = JS_MKPTR(JS_TAG_OBJECT, it.jsp) let classid = JS_GetClassID(val) let opaque = JS_GetOpaque(val, classid) for fin in rtOpaque.finalizers(classid): fin(rt, it.nimp) if opaque != nil: # JS held a ref to the Nim object. JS_SetOpaque(val, nil) assert opaque == it.nimp when defined(gcDestructors): rtOpaque.classes[int(classid)].dtor(opaque) else: GC_unref(cast[RootRef](opaque)) else: # Nim held a ref to the JS object. JS_FreeValueRT(rt, val) assert cast[ptr cint](it.jsp)[] >= 0 # Opaques are unset, and finalizers have run. Now we can actually # release the JS objects. for it in rtOpaque.tmplist.toOpenArray(0, np - 1): JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, it.jsp)) # GC will run again now (in QJS code). JS_FreeRuntime(rt) globalRuntime = nil proc setGlobal*[T](ctx: JSContext; obj: T) = ## Set the global variable to the reference `obj`. ## Note: you must call `ctx.registerType(T, asglobal = true)` for this to ## work, `T` being the type of `obj`. # Add JSValue reference. let rt = JS_GetRuntime(ctx) let rtOpaque = rt.getOpaque() let ctxOpaque = ctx.getOpaque() let opaque = cast[pointer](obj) rtOpaque.plist[opaque] = JS_VALUE_GET_PTR(ctxOpaque.global) GC_ref(obj) ctxOpaque.globalObj = opaque # Add all LegacyUnforgeable functions defined on the prototype chain to # the opaque. # Since every prototype has a list of all its ancestor's LegacyUnforgeable # functions, it is sufficient to simply merge the new list of new classes # with their parent's list to achieve this. # We handle finalizers similarly. # Returns true on success, false on exception. proc addClassUnforgeableAndFinalizer(ctx: JSContext; proto: JSValueConst; classid, parent: JSClassID; ourUnforgeable: JSFunctionList; finalizer: JSFinalizerFunction): bool = let rtOpaque = JS_GetRuntime(ctx).getOpaque() var merged = @ourUnforgeable if int(parent) < rtOpaque.classes.len: merged.add(rtOpaque.classes[int(parent)].unforgeable) if merged.len > 0: rtOpaque.classes[int(classid)].unforgeable = move(merged) var fins: seq[JSFinalizerFunction] = @[] if finalizer != nil: fins.add(finalizer) if int(parent) < rtOpaque.classes.len: fins.add(rtOpaque.classes[int(parent)].fins) if fins.len > 0: rtOpaque.classes[classid].fins = move(fins) true proc newProtoFromParentClass(ctx: JSContext; parent: JSClassID): JSValue = if parent != 0: let parentProto = JS_GetClassProto(ctx, parent) let proto = JS_NewObjectProtoClass(ctx, parentProto, parent) JS_FreeValue(ctx, parentProto) return proto return JS_NewObject(ctx) proc newCtorFunFromParentClass(ctx: JSContext; ctor: JSCFunction; className: cstring; parent: JSClassID; ctorType: JSCFunctionEnum): JSValue = if parent != 0: return JS_NewCFunction3(ctx, ctor, className, 0, ctorType, 0, ctx.getOpaque().ctors[int(parent)], 0) return JS_NewCFunction2(ctx, ctor, className, 0, ctorType, 0) proc defineIterableProps(ctx: JSContext; iterable: JSIterableType; proto: JSValueConst): DefinePropertyResult = let ctxOpaque = ctx.getOpaque() case iterable of jitNone: discard of jitValue: let values = JS_DupValue(ctx, ctxOpaque.valRefs[jsvArrayPrototypeValues]) let itSym = ctxOpaque.symRefs[jsyIterator] if ctx.definePropertyCW(proto, itSym, values) == dprException: return dprException const map = { jstEntries: jsvArrayPrototypeEntries, jstForEach: jsvArrayPrototypeForEach, jstKeys: jsvArrayPrototypeKeys, jstValues: jsvArrayPrototypeValues } for (n, v) in map: let val = JS_DupValue(ctx, ctxOpaque.valRefs[v]) let name = ctxOpaque.strRefs[n] if ctx.definePropertyCWE(proto, name, val) == dprException: return dprException of jitPair: #TODO this isn't really compliant let values = JS_DupValue(ctx, ctxOpaque.valRefs[jsvArrayPrototypeValues]) let itSym = ctxOpaque.symRefs[jsyIterator] if ctx.definePropertyCWE(proto, itSym, values) == dprException: return dprException dprSuccess # On exception, this returns JS_INVALID_CLASS_ID, but doesn't undo changes # to the global object. proc newJSClass*(ctx: JSContext; cdef: JSClassDefConst; nimt: pointer; ctor: JSCFunction; funcs: JSFunctionList; parent: JSClassID; asglobal: bool; iterable: JSIterableType; ctorType: JSCFunctionEnum; finalizer: JSFinalizerFunction; namespace: JSValueConst; unforgeable, staticfuns: JSFunctionList; dtor: BoundRefDestructor): JSClassID {.discardable.} = let rt = JS_GetRuntime(ctx) var res: uint32 discard JS_NewClassID(res) let ctxOpaque = ctx.getOpaque() let rtOpaque = rt.getOpaque() if JS_NewClass(rt, res, cdef) != 0: return JS_INVALID_CLASS_ID rtOpaque.typemap[nimt] = res if rtOpaque.classes.len <= int(res): rtOpaque.classes.setLen(int(res) + 1) rtOpaque.classes[res].parent = parent let proto = ctx.newProtoFromParentClass(parent) if ctx.defineIterableProps(iterable, proto) == dprException: JS_FreeValue(ctx, proto) return JS_INVALID_CLASS_ID JS_SetClassProto(ctx, res, proto) if not ctx.addClassUnforgeableAndFinalizer(proto, res, parent, unforgeable, finalizer): return JS_INVALID_CLASS_ID let name = JS_NewString(ctx, cdef.class_name) let strSym = ctxOpaque.symRefs[jsyToStringTag] if asglobal: let global = ctxOpaque.global assert ctxOpaque.gclass == 0 ctxOpaque.gclass = res # Global already exists, so set unforgeable functions here if ctx.definePropertyC(global, strSym, name) == dprException or JS_SetPrototype(ctx, global, proto) != 1 or not ctx.setPropertyFunctionList(global, funcs) or not ctx.setUnforgeable(global, res): return JS_INVALID_CLASS_ID else: if ctx.definePropertyC(proto, strSym, name) == dprException or not ctx.setPropertyFunctionList(proto, funcs): return JS_INVALID_CLASS_ID let jctor = ctx.newCtorFunFromParentClass(ctor, cdef.class_name, parent, ctorType) if not ctx.setPropertyFunctionList(jctor, staticfuns): JS_FreeValue(ctx, jctor) return JS_INVALID_CLASS_ID JS_SetConstructor(ctx, jctor, proto) if ctxOpaque.ctors.len <= int(res): ctxOpaque.ctors.setLen(int(res) + 1) let target = if JS_IsNull(namespace): JSValueConst(ctxOpaque.global) else: namespace if JS_DefinePropertyValueStr(ctx, target, cdef.class_name, JS_DupValue(ctx, jctor), JS_PROP_CONFIGURABLE or JS_PROP_WRITABLE) == -1: return JS_INVALID_CLASS_ID ctxOpaque.ctors[res] = jctor when defined(gcDestructors): rtOpaque.classes[res].dtor = dtor return res type FuncParam = tuple t: NimNode val: NimNode # may be nil JSFuncGenerator = object t: BoundFunctionType hasThis: bool flag: BoundFunctionFlag funcName: string funcParams: seq[FuncParam] thisType: string thisTypeNode: NimNode returnType: NimNode # may be nil newName: NimNode dielabel: NimNode # die: jump to exception return code (JS_EXCEPTION or -1) jsFunCallList: NimNode jsFunCall: NimNode jsCallAndRet: NimNode minArgs: cint actualMinArgs: cint # minArgs without JSContext i: cint # nim parameters accounted for RegistryInfo = ref object t: NimNode # NimNode of type name: string # JS name, if this is the empty string then it equals tname tabFuns: NimNode # array of function table tabUnforgeable: NimNode # array of unforgeable function table tabStatic: NimNode # array of static function table ctorFun: NimNode # constructor ident ctorType: JSCFunctionEnum # JS_CFUNC_constructor or [...]constructor_or_func getset: Table[string, (NimNode, NimNode, BoundFunctionFlag)] # name -> value propGetOwnFun: NimNode # custom own get function ident propGetFun: NimNode # custom get function ident propSetFun: NimNode # custom set function ident propDelFun: NimNode # custom del function ident propHasFun: NimNode # custom has function ident propNamesFun: NimNode # custom property names function ident finFun: NimNode # finalizer wrapper ident dfin: NimNode # CheckDestroy finalizer ident replaceableSetFun: NimNode # replaceable setter function ident tabReplaceableNames: NimNode # replaceable names array markFun: NimNode # gc_mark for class var BoundFunctions {.compileTime.}: Table[string, RegistryInfo] proc newRegistryInfo(t: NimNode): RegistryInfo = return RegistryInfo( t: t, name: t.strVal, tabFuns: newNimNode(nnkBracket), tabUnforgeable: newNimNode(nnkBracket), tabStatic: newNimNode(nnkBracket), tabReplaceableNames: newNimNode(nnkBracket), ctorType: JS_CFUNC_constructor, finFun: newNilLit(), propGetOwnFun: newNilLit(), propGetFun: newNilLit(), propSetFun: newNilLit(), propDelFun: newNilLit(), propHasFun: newNilLit(), propNamesFun: newNilLit(), markFun: newNilLit() ) proc readParams(gen: var JSFuncGenerator; fun: NimNode) = let formalParams = fun.params if formalParams[0].kind != nnkEmpty: gen.returnType = formalParams[0] var minArgsSeen = false for i in 1 ..< formalParams.len: let it = formalParams[i] var val = it[^1] if val.kind == nnkEmpty: val = nil var t = it[^2] case t.kind of nnkEmpty: if val.kind == nnkEmpty: error("?? " & treeRepr(val)) t = quote do: typeof(`val`) of nnkVarTy: t = newNimNode(nnkPtrTy).add(t[0]) of nnkCommand, nnkCall: if t.len == 2 and t[0].eqIdent("sink"): t = t[1] of nnkBracketExpr: if t[0].eqIdent("varargs"): if i != formalParams.len - 1: error("varargs must be the last parameter") minArgsSeen = true else: discard for i in 0 ..< it.len - 2: gen.funcParams.add((t, val)) if val != nil: minArgsSeen = true elif not minArgsSeen: gen.minArgs = cint(gen.funcParams.len) gen.actualMinArgs = gen.minArgs if gen.hasThis and gen.flag != bffStatic: dec gen.actualMinArgs if gen.funcParams.len > gen.i: if gen.funcParams[gen.i].t.eqIdent("JSContext"): dec gen.actualMinArgs gen.jsFunCall.add(ident("ctx")) inc gen.i elif gen.funcParams[gen.i].t.eqIdent("JSRuntime"): inc gen.i # special case for finalizers that have a JSRuntime param assert gen.actualMinArgs >= 0 template getJSParams(): untyped = [ (quote do: JSValue), newIdentDefs(ident("ctx"), quote do: JSContext), newIdentDefs(ident("this"), quote do: JSValueConst), newIdentDefs(ident("argc"), quote do: cint), newIdentDefs(ident("argv"), quote do: JSValueConstArray) ] template getJSGetterParams(): untyped = [ (quote do: JSValue), newIdentDefs(ident("ctx"), quote do: JSContext), newIdentDefs(ident("this"), quote do: JSValueConst), ] template getJSMagicGetterParams(): untyped = [ (quote do: JSValue), newIdentDefs(ident("ctx"), quote do: JSContext), newIdentDefs(ident("this"), quote do: JSValueConst), newIdentDefs(ident("magic"), quote do: cint) ] template getJSGetOwnPropParams(): untyped = [ (quote do: cint), newIdentDefs(ident("ctx"), quote do: JSContext), newIdentDefs(ident("desc"), quote do: ptr JSPropertyDescriptor), newIdentDefs(ident("this"), quote do: JSValueConst), newIdentDefs(ident("prop"), quote do: JSAtom), ] template getJSGetPropParams(): untyped = [ (quote do: JSValue), newIdentDefs(ident("ctx"), quote do: JSContext), newIdentDefs(ident("this"), quote do: JSValueConst), newIdentDefs(ident("prop"), quote do: JSAtom), newIdentDefs(ident("receiver"), quote do: JSValueConst), ] template getJSSetPropParams(): untyped = [ (quote do: cint), newIdentDefs(ident("ctx"), quote do: JSContext), newIdentDefs(ident("this"), quote do: JSValueConst), newIdentDefs(ident("atom"), quote do: JSAtom), newIdentDefs(ident("value"), quote do: JSValueConst), newIdentDefs(ident("receiver"), quote do: JSValueConst), newIdentDefs(ident("flags"), quote do: cint), ] template getJSDelPropParams(): untyped = [ (quote do: cint), newIdentDefs(ident("ctx"), quote do: JSContext), newIdentDefs(ident("this"), quote do: JSValueConst), newIdentDefs(ident("prop"), quote do: JSAtom), ] template getJSHasPropParams(): untyped = [ (quote do: cint), newIdentDefs(ident("ctx"), quote do: JSContext), newIdentDefs(ident("this"), quote do: JSValueConst), newIdentDefs(ident("atom"), quote do: JSAtom), ] template getJSSetterParams(): untyped = [ (quote do: JSValue), newIdentDefs(ident("ctx"), quote do: JSContext), newIdentDefs(ident("this"), quote do: JSValueConst), newIdentDefs(ident("val"), quote do: JSValueConst), ] template getJSPropNamesParams(): untyped = [ (quote do: cint), newIdentDefs(ident("ctx"), quote do: JSContext), newIdentDefs(ident("ptab"), quote do: ptr JSPropertyEnumArray), newIdentDefs(ident("plen"), quote do: ptr uint32), newIdentDefs(ident("this"), quote do: JSValueConst) ] proc addThisParam(gen: var JSFuncGenerator; thisName = "this") = var s = ident("arg_" & $gen.i) let t = gen.funcParams[gen.i].t let id = ident(thisName) let dl = gen.dielabel gen.jsFunCallList.add(quote do: var `s`: `t` if ctx.fromJSThis(`id`, `s`) == fjErr: break `dl` ) if gen.funcParams[gen.i].t.kind == nnkPtrTy: s = quote do: `s`[] gen.jsFunCall.add(s) inc gen.i proc addFixParam(gen: var JSFuncGenerator; id: NimNode) = var s = ident("arg_" & $gen.i) let t = gen.funcParams[gen.i].t let dl = gen.dielabel gen.jsFunCallList.add(quote do: var `s`: `t` if ctx.fromJS(`id`, `s`) == fjErr: break `dl` ) if gen.funcParams[gen.i].t.kind == nnkPtrTy: s = quote do: `s`[] gen.jsFunCall.add(s) inc gen.i proc addArgv(gen: var JSFuncGenerator) = var j = 0 while gen.i < gen.minArgs: gen.addFixParam(quote do: argv[`j`]) inc j while gen.i < gen.funcParams.len: var s = ident("arg_" & $gen.i) let t = gen.funcParams[gen.i].t if t.kind == nnkBracketExpr and t[0].eqIdent("varargs"): s = quote do: argv.toOpenArray(`j`, argc - 1) else: let fallback = gen.funcParams[gen.i].val if fallback == nil: error("No fallback value. Maybe a non-optional parameter follows an " & "optional parameter?") if t.typeKind == ntyGenericParam: error("Union parameters are not supported. Use JSValue instead.") let dl = gen.dielabel gen.jsFunCallList.add(quote do: var `s`: `t` if `j` < argc and not JS_IsUndefined(argv[`j`]): if ctx.fromJS(argv[`j`], `s`) == fjErr: break `dl` else: `s` = `fallback` ) if t.kind == nnkPtrTy: s = quote do: `s`[] gen.jsFunCall.add(s) inc j inc gen.i proc finishFunCallList(gen: var JSFuncGenerator) = gen.jsFunCallList.add(gen.jsFunCall) var jsDtors {.compileTime.}: HashSet[string] proc registerFunction(info: RegistryInfo; fun: BoundFunction) = let name = fun.name let id = fun.id case fun.t of bfFunction: case fun.flag of bffNone: info.tabFuns.add(quote do: JS_CFUNC_DEF(`name`, 0, `id`, JS_PROP_C_W_E)) of bffUnforgeable: info.tabUnforgeable.add(quote do: JS_CFUNC_DEF(`name`, 0, `id`, JS_PROP_ENUMERABLE)) of bffStatic: info.tabStatic.add(quote do: JS_CFUNC_DEF(`name`, 0, `id`, JS_PROP_C_W_E)) of bffReplaceable: assert false #TODO of bfConstructor, bfConstructorFunction: if info.ctorFun != nil: error("Class " & info.name & " has 2+ constructors.") info.ctorFun = id if fun.t == bfConstructorFunction: info.ctorType = JS_CFUNC_constructor_or_func of bfGetter: info.getset.withValue(name, exv): exv[0] = id exv[2] = fun.flag do: info.getset[name] = (id, newNilLit(), fun.flag) if fun.flag == bffReplaceable: info.tabReplaceableNames.add(newCall("cstring", newStrLitNode(name))) of bfSetter: info.getset.withValue(name, exv): exv[1] = id do: info.getset[name] = (newNilLit(), id, bffNone) of bfPropertyGetOwn: if info.propGetFun.kind != nnkNilLit: error("Class " & info.name & " has 2+ own property getters.") info.propGetOwnFun = id of bfPropertyGet: if info.propGetFun.kind != nnkNilLit: error("Class " & info.name & " has 2+ property getters.") info.propGetFun = id of bfPropertySet: if info.propSetFun.kind != nnkNilLit: error("Class " & info.name & " has 2+ property setters.") info.propSetFun = id of bfPropertyDel: if info.propDelFun.kind != nnkNilLit: error("Class " & info.name & " has 2+ property deleters.") info.propDelFun = id of bfPropertyHas: if info.propHasFun.kind != nnkNilLit: error("Class " & info.name & " has 2+ hasprop getters.") info.propHasFun = id of bfPropertyNames: if info.propNamesFun.kind != nnkNilLit: error("Class " & info.name & " has 2+ propnames getters.") info.propNamesFun = id of bfFinalizer: if info.finFun.kind != nnkNilLit: error("Class " & info.name & " has 2+ finalizers.") info.finFun = id of bfMark: if info.markFun.kind != nnkNilLit: error("Class " & info.name & " has 2+ mark functions.") info.markFun = id proc registerFunction(typ: string; fun: BoundFunction) = var info = BoundFunctions.getOrDefault(typ) if info == nil: info = newRegistryInfo(ident(typ)) BoundFunctions[typ] = info info.registerFunction(fun) proc registerFunction(gen: JSFuncGenerator) = registerFunction(gen.thisType, BoundFunction( t: gen.t, name: gen.funcName, id: gen.newName, flag: gen.flag )) proc jsCheckNumArgs*(ctx: JSContext; argc, minargs: cint): bool = if argc < minargs: JS_ThrowTypeError(ctx, "At least %d arguments required, but only %d passed", minargs, argc) return false true proc newJSProc(gen: var JSFuncGenerator; params: openArray[NimNode]; isva = true): NimNode = let ma = gen.actualMinArgs let jsBody = newStmtList() if isva and ma > 0: jsBody.add(quote do: if not ctx.jsCheckNumArgs(argc, `ma`): return JS_EXCEPTION ) jsBody.add(gen.jsCallAndRet) let jsPragmas = newNimNode(nnkPragma) .add(ident("cdecl")) .add(newTree(nnkExprColonExpr, ident("raises"), newNimNode(nnkBracket))) return newProc(gen.newName, params, jsBody, pragmas = jsPragmas) proc getFuncName(fun: NimNode; jsname, staticName: string): string = if jsname != "": return jsname if staticName != "": let i = staticName.find('#') if i != -1: return staticName.substr(i + 1) return $fun.name proc addThisName(gen: var JSFuncGenerator; hasThis: bool) = if hasThis: var t = gen.funcParams[gen.i].t if t.kind in {nnkPtrTy, nnkRefTy}: t = t[0] gen.thisTypeNode = t gen.thisType = $t gen.newName = ident($gen.t & "_" & gen.thisType & "_" & gen.funcName) else: let rt = gen.returnType if rt.kind in {nnkRefTy, nnkPtrTy}: gen.thisTypeNode = rt[0] gen.thisType = rt[0].strVal else: if rt.kind == nnkBracketExpr: gen.thisTypeNode = rt[1] gen.thisType = rt[1].strVal else: gen.thisTypeNode = rt gen.thisType = rt.strVal gen.newName = ident($gen.t & "_" & gen.funcName) proc initGenerator(fun: NimNode; t: BoundFunctionType; hasThis: bool; jsname = ""; flag = bffNone; staticName = ""): JSFuncGenerator = var funCallName = fun[0] if funCallName.kind == nnkPostfix: funCallName = funCallName[1] result = JSFuncGenerator( t: t, funcName: getFuncName(fun, jsname, staticName), hasThis: hasThis, dielabel: ident("ondie"), jsFunCallList: newStmtList(), jsFunCall: newCall(funCallName), flag: flag ) result.readParams(fun) if staticName == "": result.addThisName(hasThis) else: result.thisType = staticName if (let i = result.thisType.find('#'); i != -1): result.thisType.setLen(i) result.newName = ident($result.t & "_" & result.funcName) proc makeJSCallAndRet(gen: var JSFuncGenerator; okstmt, errstmt: NimNode) = let jfcl = gen.jsFunCallList let dl = gen.dielabel gen.jsCallAndRet = if gen.returnType != nil: quote do: block `dl`: return ctx.toJS(`jfcl`) `errstmt` else: quote do: block `dl`: `jfcl` `okstmt` `errstmt` macro jsctor0*(fun: untyped; t: static BoundFunctionType) = var gen = initGenerator(fun, t, hasThis = false) gen.addArgv() gen.finishFunCallList() let jfcl = gen.jsFunCallList let dl = gen.dielabel gen.jsCallAndRet = quote do: block `dl`: return ctx.toJSNew(`jfcl`, this) return JS_EXCEPTION let jsProc = gen.newJSProc(getJSParams()) gen.registerFunction() return newStmtList(fun, jsProc) template jsctor*(fun: untyped) = jsctor0(fun, bfConstructor) template jsfctor*(fun: untyped) = jsctor0(fun, bfConstructorFunction) macro jshasprop*(fun: untyped) = var gen = initGenerator(fun, bfPropertyHas, hasThis = true) gen.addThisParam() gen.addFixParam(ident"atom") gen.finishFunCallList() let jfcl = gen.jsFunCallList let dl = gen.dielabel gen.jsCallAndRet = quote do: block `dl`: let retv = `jfcl` return cint(retv) return cint(-1) let jsProc = gen.newJSProc(getJSHasPropParams(), false) gen.registerFunction() return newStmtList(fun, jsProc) macro jsgetownprop*(fun: untyped) = var gen = initGenerator(fun, bfPropertyGetOwn, hasThis = true) gen.addThisParam() gen.addFixParam(ident"prop") var handleRetv: NimNode if gen.i < gen.funcParams.len: handleRetv = quote do: discard gen.jsFunCall.add(ident("desc")) else: handleRetv = quote do: if desc != nil: # From quickjs.h: # > If 1 is returned, the property descriptor 'desc' is filled # > if != NULL. # So desc may be nil. desc[].setter = JS_UNDEFINED desc[].getter = JS_UNDEFINED desc[].value = retv desc[].flags = 0 else: JS_FreeValue(ctx, retv) gen.finishFunCallList() let jfcl = gen.jsFunCallList let dl = gen.dielabel gen.jsCallAndRet = quote do: block `dl`: if JS_GetOpaque(this, JS_GetClassID(this)) == nil: return cint(0) let retv {.inject.} = ctx.toJS(`jfcl`) if JS_IsException(retv): return cint(-1) if JS_IsUninitialized(retv): return cint(0) `handleRetv` return cint(1) return cint(-1) let jsProc = gen.newJSProc(getJSGetOwnPropParams(), false) gen.registerFunction() return newStmtList(fun, jsProc) macro jsgetprop*(fun: untyped) = var gen = initGenerator(fun, bfPropertyGet, hasThis = true) gen.addThisParam("receiver") gen.addFixParam(ident"prop") if gen.i < gen.funcParams.len: gen.addFixParam(ident"this") gen.finishFunCallList() let jfcl = gen.jsFunCallList let dl = gen.dielabel gen.jsCallAndRet = quote do: block `dl`: return ctx.toJS(`jfcl`) return JS_EXCEPTION let jsProc = gen.newJSProc(getJSGetPropParams(), false) gen.registerFunction() return newStmtList(fun, jsProc) macro jssetprop*(fun: untyped) = var gen = initGenerator(fun, bfPropertySet, hasThis = true) gen.addThisParam("receiver") gen.addFixParam(ident"atom") gen.addFixParam(ident"value") if gen.i < gen.funcParams.len: gen.addFixParam(ident"this") gen.finishFunCallList() let jfcl = gen.jsFunCallList let dl = gen.dielabel gen.jsCallAndRet = if gen.returnType != nil: quote do: block `dl`: let v = toJS(ctx, `jfcl`) if not JS_IsException(v): return cint(1) if JS_IsUninitialized(v): return cint(0) return cint(-1) else: quote do: block `dl`: `jfcl` return cint(1) return cint(-1) let jsProc = gen.newJSProc(getJSSetPropParams(), false) gen.registerFunction() return newStmtList(fun, jsProc) macro jsdelprop*(fun: untyped) = var gen = initGenerator(fun, bfPropertyDel, hasThis = true) gen.addThisParam() gen.addFixParam(ident"prop") gen.finishFunCallList() let jfcl = gen.jsFunCallList let dl = gen.dielabel gen.jsCallAndRet = quote do: block `dl`: let retv = `jfcl` return cint(retv) return cint(-1) let jsProc = gen.newJSProc(getJSDelPropParams(), false) gen.registerFunction() return newStmtList(fun, jsProc) macro jspropnames*(fun: untyped) = var gen = initGenerator(fun, bfPropertyNames, hasThis = true) gen.addThisParam() gen.finishFunCallList() let jfcl = gen.jsFunCallList let dl = gen.dielabel gen.jsCallAndRet = quote do: block `dl`: let retv = `jfcl` ptab[] = retv.buffer plen[] = retv.len return cint(0) return cint(-1) let jsProc = gen.newJSProc(getJSPropNamesParams(), false) gen.registerFunction() return newStmtList(fun, jsProc) macro jsfgetn(jsname: static string; flag: static BoundFunctionFlag; fun: untyped) = var gen = initGenerator(fun, bfGetter, hasThis = true, jsname, flag) if gen.actualMinArgs != 0 or gen.funcParams.len != gen.minArgs: error("jsfget functions must only accept one parameter.") if gen.returnType == nil: error("jsfget functions must have a return type.") gen.addThisParam() gen.finishFunCallList() gen.makeJSCallAndRet(nil, quote do: discard) let jsProc = if flag != bffReplaceable: gen.newJSProc(getJSGetterParams(), false) else: gen.newJSProc(getJSMagicGetterParams(), false) gen.registerFunction() return newStmtList(fun, jsProc) # "Why?" So the compiler doesn't cry. # Warning: make these typed and you will cry instead. template jsfget*(fun: untyped) = jsfgetn("", bffNone, fun) template jsuffget*(fun: untyped) = jsfgetn("", bffUnforgeable, fun) template jsrfget*(fun: untyped) = jsfgetn("", bffReplaceable, fun) template jsfget*(jsname, fun: untyped) = jsfgetn(jsname, bffNone, fun) template jsuffget*(jsname, fun: untyped) = jsfgetn(jsname, bffUnforgeable, fun) template jsrfget*(jsname, fun: untyped) = jsfgetn(jsname, bffReplaceable, fun) # Ideally we could simulate JS setters using nim setters, but nim setters # won't accept types that don't match their reflected field's type. macro jsfsetn(jsname: static string; fun: untyped) = var gen = initGenerator(fun, bfSetter, hasThis = true, jsname = jsname) if gen.actualMinArgs != 1 or gen.funcParams.len != gen.minArgs: error("jsfset functions must accept two parameters") gen.addThisParam() gen.addFixParam(ident"val") gen.finishFunCallList() # return param anyway let okstmt = quote do: discard let errstmt = quote do: return JS_DupValue(ctx, val) gen.makeJSCallAndRet(okstmt, errstmt) let jsProc = gen.newJSProc(getJSSetterParams(), false) gen.registerFunction() return newStmtList(fun, jsProc) template jsfset*(fun: untyped) = jsfsetn("", fun) template jsfset*(jsname, fun: untyped) = jsfsetn(jsname, fun) macro jsfuncn*(jsname: static string; flag: static BoundFunctionFlag; staticName: static string; fun: untyped) = var gen = initGenerator(fun, bfFunction, hasThis = true, jsname = jsname, flag = flag, staticName = staticName) if gen.minArgs == 0 and gen.flag != bffStatic: error("Zero-parameter functions are not supported. (Maybe pass Window?)") if gen.flag != bffStatic: gen.addThisParam() gen.addArgv() gen.finishFunCallList() let okstmt = quote do: return JS_UNDEFINED let errstmt = quote do: return JS_EXCEPTION gen.makeJSCallAndRet(okstmt, errstmt) let jsProc = gen.newJSProc(getJSParams()) gen.registerFunction() return newStmtList(fun, jsProc) template jsfunc*(fun: untyped) = jsfuncn("", bffNone, "", fun) template jsuffunc*(fun: untyped) = jsfuncn("", bffUnforgeable, "", fun) template jsfunc*(jsname, fun: untyped) = jsfuncn(jsname, bffNone, "", fun) template jsuffunc*(jsname, fun: untyped) = jsfuncn(jsname, bffUnforgeable, "", fun) template jsstfunc*(name, fun: untyped) = jsfuncn("", bffStatic, name, fun) macro jsfin*(fun: untyped) = var gen = initGenerator(fun, bfFinalizer, hasThis = true) let finName = gen.newName let finFun = ident(gen.funcName) let t = gen.thisTypeNode var finStmt: NimNode = nil # warning: won't compile on 2.0.4 with let if gen.minArgs == 1: finStmt = quote do: `finFun`(cast[`t`](opaque)) elif gen.minArgs == 2: finStmt = quote do: `finFun`(rt, cast[`t`](opaque)) else: error("Expected one or two parameters") let jsProc = quote do: proc `finName`(rt {.inject.}: JSRuntime; opaque {.inject.}: pointer) = `finStmt` gen.registerFunction() return newStmtList(fun, jsProc) macro jsmark*(fun: untyped) = var gen = initGenerator(fun, bfMark, hasThis = true) let markName = gen.newName let markFun = ident(gen.funcName) let t = gen.thisTypeNode let jsProc = quote do: proc `markName`(rt {.inject.}: JSRuntime; val: JSValueConst; markFunc {.inject.}: JS_MarkFunc) {.cdecl.} = let opaque = JS_GetOpaque(val, JS_GetClassID(val)) if opaque != nil: `markFun`(rt, cast[`t`](opaque), markFunc) gen.registerFunction() return newStmtList(fun, jsProc) # Having the same names for these and the macros leads to weird bugs, so the # macros get an additional f. template jsget*() {.pragma.} template jsget*(name: string) {.pragma.} template jsset*() {.pragma.} template jsset*(name: string) {.pragma.} template jsgetset*() {.pragma.} template jsgetset*(name: string) {.pragma.} template jsufget*() {.pragma.} template jsufget*(name: string) {.pragma.} template jsrget*() {.pragma.} template jsrget*(name: string) {.pragma.} proc js_illegal_ctor*(ctx: JSContext; this: JSValueConst; argc: cint; argv: JSValueConstArray): JSValue {.cdecl.} = return JS_ThrowTypeError(ctx, "Illegal constructor") type JSObjectPragma = object name: string varsym: NimNode flag: BoundFunctionFlag proc getPragmaName(varPragma: NimNode): string = if varPragma.kind == nnkExprColonExpr: return $varPragma[0] return $varPragma proc getStringFromPragma(varPragma, fallback: NimNode): string = if varPragma.kind == nnkExprColonExpr: if not varPragma.len == 1 and varPragma[1].kind == nnkStrLit: error("Expected string as pragma argument") return $varPragma[1] return $fallback proc tname(info: RegistryInfo): string = return info.t.strVal # Differs from tname if the Nim object's name differs from the JS object's # name. proc jsname(info: RegistryInfo): string = if info.name != "": return info.name return info.tname proc registerGetter(stmts: NimNode; info: RegistryInfo; op: JSObjectPragma) = let t = info.t let tname = info.tname let node = op.varsym let fn = op.name let id = ident($bfGetter & "_" & tname & "_" & fn) stmts.add(quote do: proc `id`(ctx: JSContext; this: JSValueConst): JSValue {.cdecl.} = var arg_0: `t` if ctx.fromJSThis(this, arg_0) == fjErr: return JS_EXCEPTION when arg0.`node` is JSValue: return JS_DupValue(ctx, arg0.`node`) else: return ctx.toJS(arg_0.`node`) ) info.registerFunction(BoundFunction( t: bfGetter, name: fn, id: id, flag: op.flag )) proc registerSetter(stmts: NimNode; info: RegistryInfo; op: JSObjectPragma) = let t = info.t let tname = info.tname let node = op.varsym let fn = op.name let id = ident($bfSetter & "_" & tname & "_" & fn) stmts.add(quote do: proc `id`(ctx: JSContext; this, val: JSValueConst): JSValue {.cdecl.} = var arg_0: `t` if ctx.fromJSThis(this, arg_0) == fjErr: return JS_EXCEPTION # We can't just set arg_0.`node` directly, or fromJS may damage it. var nodeVal: typeof(arg_0.`node`) when nodeVal is JSValue: static: error(".jsset is not supported on JSValue; use jsfset") else: if ctx.fromJS(val, nodeVal) == fjErr: return JS_EXCEPTION arg_0.`node` = move(nodeVal) return JS_DupValue(ctx, val) ) info.registerFunction(BoundFunction(t: bfSetter, name: fn, id: id)) proc registerPragmas(stmts: NimNode; info: RegistryInfo; t: NimNode) = let typ = t.getTypeInst()[1] # The type, as declared. var impl = typ.getTypeImpl() # ref t if impl.kind in {nnkRefTy, nnkPtrTy}: impl = impl[0].getImpl() else: impl = typ.getImpl() # stolen from std's macros.customPragmaNode var identDefsStack = newSeq[NimNode](impl[2].len) for i, it in identDefsStack.mpairs: it = impl[2][i] while identDefsStack.len > 0: let identDefs = identDefsStack.pop() case identDefs.kind of nnkRecList: for child in identDefs.children: identDefsStack.add(child) of nnkRecCase: discard # case objects are not supported else: for i in 0 ..< identDefs.len - 2: var varNode = identDefs[i] if varNode.kind == nnkPragmaExpr: let varPragmas = varNode[1] varNode = varNode[0] if varNode.kind == nnkPostfix: varNode = varNode[1] for varPragma in varPragmas: let pragmaName = getPragmaName(varPragma) var op = JSObjectPragma( name: getStringFromPragma(varPragma, varNode), varsym: varNode ) case pragmaName of "jsget": stmts.registerGetter(info, op) of "jsset": stmts.registerSetter(info, op) of "jsufget": # LegacyUnforgeable op.flag = bffUnforgeable stmts.registerGetter(info, op) of "jsrget": # Replaceable op.flag = bffReplaceable stmts.registerGetter(info, op) of "jsgetset": stmts.registerGetter(info, op) stmts.registerSetter(info, op) elif varNode.kind == nnkPostfix: varNode = varNode[1] let typ = identDefs[^2] if typ.getTypeInst().sameType(JSValue.getType()) or JSValue.getType().sameType(typ): if info.markFun.kind == nnkNilLit: warning(info.tname & " misses .jsmark for member " & varNode.strVal & ". This will cause memory leaks.") if info.finFun.kind == nnkNilLit: warning(info.tname & " misses .jsfin for member " & varNode.strVal & ". This will cause memory leaks.") proc nimFinalizeForJS*(obj, typeptr: pointer) = let rt = globalRuntime if rt != nil: let rtOpaque = rt.getOpaque() rtOpaque.plist.withValue(obj, pp): let val = JS_MKPTR(JS_TAG_OBJECT, pp[]) for fin in rtOpaque.finalizers(JS_GetClassID(val)): fin(rt, obj) JS_SetOpaque(val, nil) rtOpaque.plist.del(obj) if rtOpaque.destroying == obj: # Allow QJS to collect the JSValue through checkDestroy. rtOpaque.destroying = nil else: JS_FreeValueRT(rt, val) do: # No JSValue exists for the object, but it likely still expects us to # free it. let classid = rtOpaque.typemap.getOrDefault(typeptr) for fin in rtOpaque.finalizers(classid): fin(rt, obj) template jsDestructor*[U](T: typedesc[ref U]) = static: jsDtors.incl($T) proc `=destroy`(obj: var U) = nimFinalizeForJS(addr obj, getTypePtr(obj)) proc bindConstructor(stmts: NimNode; info: var RegistryInfo): NimNode = if info.ctorFun != nil: return info.ctorFun return ident("js_illegal_ctor") proc bindReplaceableSet(stmts: NimNode; info: var RegistryInfo) = let rsf = ident("js_replaceable_set") let t = info.t info.replaceableSetFun = rsf let trns = info.tabReplaceableNames stmts.add(quote do: const replaceableNames = `trns` proc `rsf`(ctx: JSContext; this, val: JSValueConst; magic: cint): JSValue {.cdecl.} = var dummy: `t` if ctx.fromJSThis(this, dummy) == fjErr: return JS_EXCEPTION let name = replaceableNames[int(magic)] let dval = JS_DupValue(ctx, val) if JS_DefinePropertyValueStr(ctx, this, name, dval, JS_PROP_C_W_E) < 0: return JS_EXCEPTION return JS_DupValue(ctx, val) ) proc bindGetSet(stmts: NimNode; info: RegistryInfo) = var replaceableId = 0u16 for k, (get, set, flag) in info.getset: case flag of bffNone: info.tabFuns.add(quote do: JS_CGETSET_DEF(`k`, `get`, `set`, JS_PROP_CONFIGURABLE or JS_PROP_ENUMERABLE) ) of bffUnforgeable: info.tabUnforgeable.add(quote do: JS_CGETSET_DEF(`k`, `get`, `set`, JS_PROP_ENUMERABLE) ) of bffReplaceable: if set != nil: error("Replaceable properties must not have a setter.") let orid = replaceableId inc replaceableId if orid > replaceableId: error("Too many replaceable functions defined.") let magic = cast[int16](orid) info.tabFuns.add(quote do: JS_CGETSET_MAGIC_DEF(`k`, `get`, js_replaceable_set, `magic`, JS_PROP_CONFIGURABLE or JS_PROP_ENUMERABLE) ) else: error("Static getters and setters are not supported.") proc jsCheckDestroy*(rt: JSRuntime; val: JSValueConst): JS_BOOL {.cdecl.} = let classId = JS_GetClassID(val) let opaque = JS_GetOpaque(val, classId) if opaque != nil: # Before this function is called, the ownership model is # JSObject -> Nim object. # Here we change it to Nim object -> JSObject. # As a result, Nim object's reference count can now reach zero (it is # no longer "referenced" by the JS object). # nimFinalizeForJS will be invoked by the Nim GC when the Nim # refcount reaches zero. Then, the JS object's opaque will be set # to nil, and its refcount decreased again, so next time this # function will return true. # # Actually, we need another hack to ensure correct # operation. GC_unref may call the destructor of this object, and # in this case we cannot ask QJS to keep the JSValue alive. So we set # the "destroying" pointer to the current opaque, and return true if # the opaque was collected. let rtOpaque = rt.getOpaque() rtOpaque.destroying = opaque # We can lie about the type in refc, as it type erases the reference. # In ARC, we must do an indirect call. when defined(gcDestructors): rtOpaque.classes[classId].dtor(opaque) else: GC_unref(cast[RootRef](opaque)) if rtOpaque.destroying == nil: # Looks like GC_unref called nimFinalizeForJS for this pointer. # This means we can allow QJS to collect this JSValue. return true rtOpaque.destroying = nil # Returning false from this function signals to the QJS GC that it # should not be collected yet. Accordingly, the JSObject's refcount # (and that of its children) will be set to one again, and later its # opaque to NULL. return false return true proc bindEndStmts(endstmts: NimNode; info: RegistryInfo) = let jsname = info.jsname let dfin = info.dfin let markFun = info.markFun if info.propGetOwnFun.kind != nnkNilLit or info.propGetFun.kind != nnkNilLit or info.propSetFun.kind != nnkNilLit or info.propDelFun.kind != nnkNilLit or info.propHasFun.kind != nnkNilLit or info.propNamesFun.kind != nnkNilLit: let propGetOwnFun = info.propGetOwnFun let propGetFun = info.propGetFun let propSetFun = info.propSetFun let propDelFun = info.propDelFun let propHasFun = info.propHasFun let propNamesFun = info.propNamesFun endstmts.add(quote do: var exotic {.global.} = JSClassExoticMethods( get_own_property: `propGetOwnFun`, get_own_property_names: `propNamesFun`, has_property: `propHasFun`, get_property: `propGetFun`, set_property: `propSetFun`, delete_property: `propDelFun` ) var cd {.global.} = JSClassDef( class_name: `jsname`, can_destroy: `dfin`, gc_mark: `markFun`, exotic: JSClassExoticMethodsConst(addr exotic) ) let classDef {.inject.} = JSClassDefConst(addr cd) ) else: endstmts.add(quote do: var cd {.global.} = JSClassDef( class_name: `jsname`, can_destroy: `dfin`, gc_mark: `markFun` ) let classDef {.inject.} = JSClassDefConst(addr cd) ) when defined(gcDestructors): proc rootRefDtor(x: pointer) = GC_unref(cast[RootRef](x)) template mncGetDtor*(T: untyped): BoundRefDestructor = when T is RootRef: rootRefDtor else: proc dtor(x: pointer) {.nimcall.} = GC_unref(cast[T](x)) dtor else: template mncGetDtor*(T: untyped): BoundRefDestructor = nil macro registerType*(ctx: JSContext; t: typed; parent: JSClassID = 0; asglobal: static bool = false; name: static string = ""; namespace = JS_NULL; iterable: static JSIterableType = jitNone): JSClassID = var stmts = newStmtList() var info = BoundFunctions.getOrDefault(t.strVal) if info == nil: info = newRegistryInfo(t) if name != "": info.name = name if name != "": info.name = name if not asglobal: info.dfin = quote do: jsCheckDestroy if info.tname notin jsDtors: warning("No destructor has been defined for type " & info.tname) else: info.dfin = newNilLit() if info.tname in jsDtors: error("Global object " & info.tname & " must not have a destructor.") stmts.registerPragmas(info, t) if info.tabReplaceableNames.len > 0: stmts.bindReplaceableSet(info) stmts.bindGetSet(info) let sctr = stmts.bindConstructor(info) let endstmts = newStmtList() endstmts.bindEndStmts(info) let finFun = info.finFun let flist0 = info.tabFuns let flen = flist0.len let sflist0 = info.tabStatic let sflen = sflist0.len let uflist0 = info.tabUnforgeable let uflen = uflist0.len let ctorType = info.ctorType endstmts.add(quote do: let flist {.global, inject.}: array[`flen`, JSCFunctionListEntry] = `flist0` let sflist {.global, inject.}: array[`sflen`, JSCFunctionListEntry] = `sflist0` let uflist {.global, inject.}: array[`uflen`, JSCFunctionListEntry] = `uflist0` `ctx`.newJSClass(classDef, getTypePtr(`t`), `sctr`, flist, `parent`, cast[bool](`asglobal`), cast[JSIterableType](`iterable`), cast[JSCFunctionEnum](`ctorType`), `finFun`, `namespace`, uflist, sflist, mncGetDtor(`t`)) ) stmts.add(newBlockStmt(endstmts)) return stmts {.pop.} # raises �������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/jserror.nim����������������������������������������������������0000664�0000000�0000000�00000010410�15202323131�0021571�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## JS Error compatibility using nim-results. It uses Opt/Result for passing ## down exceptions received up in the chain. ## ## `Opt[T].err()` translates to JS_EXCEPTION, which signals to QJS that ## you have already thrown an exception (say, using `JS_ThrowTypeError`). ## `Result[T, JSError]` also translates to JS_EXCEPTION if error is nil, or ## throws the respective exception otherwise. For example, you can ## `return err(newTypeError("wrong type"))` from such a proc instantiates ## a TypeError with the message "wrong type". ## ## There are also wrapper templates that are just shorthands for ## `err(new...Error("blah"))`. ## ## This API is strictly less efficient than its QJS counterpart, as it ## relies on additional heap allocation. It only exists to make it ## easier to write interfaces that can be used both in Nim and QJS. ## ## An alternative with better performance is to set your proc's the return ## value to `JSValue`, take `JSContext` as the first parameter, and return ## e.g. `JS_ThrowTypeError` on exception or `ctx.toJS(val)` for your values. ## (You'll also want to `import monoucha/tojs` for the latter to work.) ## ## If you want to return `null` instead of an exception, check the `jsnull` ## module. {.push raises: [].} import fromjs import quickjs import results import tojs type JSError* = ref object e*: JSErrorEnum message*: string JSErrorEnum* = enum # QuickJS internal errors jeRangeError = "RangeError" jeReferenceError = "ReferenceError" jeSyntaxError = "SyntaxError" jeTypeError = "TypeError" jeInternalError = "InternalError" JSResult*[T] = Result[T, JSError] proc toJS*[T, E](ctx: JSContext; opt: Result[T, E]): JSValue proc toJS*(ctx: JSContext; err: JSError): JSValue proc toJSNew*[T, E](ctx: JSContext; opt: Result[T, E]; ctor: JSValueConst): JSValue proc newRangeError*(message: sink string): JSError = return JSError(e: jeRangeError, message: message) proc newReferenceError*(message: sink string): JSError = return JSError(e: jeReferenceError, message: message) proc newSyntaxError*(message: sink string): JSError = return JSError(e: jeSyntaxError, message: message) proc newTypeError*(message: sink string): JSError = return JSError(e: jeTypeError, message: message) proc newInternalError*(message: sink string): JSError = return JSError(e: jeInternalError, message: message) template errRangeError*(message: sink string): untyped = err(newRangeError(message)) template errReferenceError*(message: sink string): untyped = err(newReferenceError(message)) template errSyntaxError*(message: sink string): untyped = err(newSyntaxError(message)) template errTypeError*(message: sink string): untyped = err(newTypeError(message)) template errInternalError*(message: sink string): untyped = err(newInternalError(message)) proc toJS*(ctx: JSContext; err: JSError): JSValue = if err == nil: return JS_NULL case err.e of jeRangeError: JS_ThrowRangeError(ctx, "%s", cstring(err.message)) of jeReferenceError: JS_ThrowReferenceError(ctx, "%s", cstring(err.message)) of jeSyntaxError: JS_ThrowSyntaxError(ctx, "%s", cstring(err.message)) of jeTypeError: JS_ThrowTypeError(ctx, "%s", cstring(err.message)) of jeInternalError: JS_ThrowInternalError(ctx, "%s", cstring(err.message)) return JS_GetException(ctx) proc toJS*[T, E](ctx: JSContext; opt: Result[T, E]): JSValue = if opt.isOk: when not (T is void): return ctx.toJS(opt.get) else: return JS_UNDEFINED else: when not (E is void): if opt.error != nil: return JS_Throw(ctx, ctx.toJS(opt.error)) return JS_EXCEPTION proc toJSNew*[T, E](ctx: JSContext; opt: Result[T, E]; ctor: JSValueConst): JSValue = if opt.isOk: when not (T is void): return ctx.toJSNew(opt.get, ctor) else: return JS_UNDEFINED else: when not (E is void): if opt.error != nil: return JS_Throw(ctx, ctx.toJS(opt.error)) return JS_EXCEPTION proc evalConvert*[T](ctx: JSContext; code: string; file = "<input>"; flags = JS_EVAL_TYPE_GLOBAL): Result[T, string] = let val = ctx.eval(code, file, flags) var res: T if ctx.fromJSFree(val, res).isErr: # Exception when converting the value. return err(ctx.getExceptionMsg()) # All ok; return the converted object. ok(res) {.pop.} # raises ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/jsnull.nim�����������������������������������������������������0000664�0000000�0000000�00000001412�15202323131�0021414�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Converts `Option` from `std/options` into nullable JS types. ## Use this if you want to return either a string or take a ref object ## parameter that can be nil. ## ## If you want to return a value or an exception, see the `jserror` module ## instead. {.push raises: [].} import std/options import fromjs import quickjs import tojs proc toJS*(ctx: JSContext; opt: Option): JSValue = if opt.isSome: return ctx.toJS(opt.get) return JS_NULL proc fromJS*[T](ctx: JSContext; val: JSValueConst; res: var Option[T]): FromJSResult proc fromJS*[T](ctx: JSContext; val: JSValueConst; res: var Option[T]): FromJSResult = if JS_IsNull(val): res = none(T) else: var x: T if ctx.fromJS(val, x).isErr: return fjErr res = option(move(x)) fjOk ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/jsopaque.nim���������������������������������������������������0000664�0000000�0000000�00000011477�15202323131�0021750�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/algorithm import std/tables import quickjs type JSSymbolRef* = enum jsyIterator = "iterator" jsyToStringTag = "toStringTag" JSStrRef* = enum jstDone = "done" jstValue = "value" jstNext = "next" jstThen = "then" jstCatch = "catch" jstSet = "set" jstGet = "get" jstEntries = "entries" jstForEach = "forEach" jstKeys = "keys" jstValues = "values" JSValueRef* = enum jsvArrayPrototypeForEach = "Array.prototype.forEach" jsvArrayPrototypeEntries = "Array.prototype.entries" jsvArrayPrototypeKeys = "Array.prototype.keys" jsvArrayPrototypeValues = "Array.prototype.values" jsvObjectPrototypeValueOf = "Object.prototype.valueOf" jsvSet = "Set" jsvFunction = "Function" BoundRefDestructor* = proc(x: pointer) {.nimcall, raises: [].} JSClassData* = object parent*: JSClassID # Parent unforgeables are merged on class creation. # (i.e. to set all unforgeables on the prototype chain, it is enough to set) # `unforgeable[classid]'.) unforgeable*: seq[JSCFunctionListEntry] fins*: seq[JSFinalizerFunction] when defined(gcDestructors): dtor*: BoundRefDestructor JSContextOpaque* = ref object gclass*: JSClassID # class ID of the global object ctors*: seq[JSValue] # class ID -> constructor global*: JSValue symRefs*: array[JSSymbolRef, JSAtom] strRefs*: array[JSStrRef, JSAtom] valRefs*: array[JSValueRef, JSValue] globalObj*: pointer JSFinalizerFunction* = proc(rt: JSRuntime; opaque: pointer) {.nimcall, raises: [].} EnumMapItem* = object atom*: JSAtom n*: int32 EnumMapEntry* = object atoms*: seq[JSAtom] # enum number -> atom enums*: seq[EnumMapItem] # atom number -> enum JSRuntimeOpaque* = ref object classes*: seq[JSClassData] # JSClassID -> data typemap*: Table[pointer, JSClassID] # getTypePtr -> JSClassID enumMap*: seq[EnumMapEntry] plist*: Table[pointer, pointer] # Nim -> JS destroying*: pointer # temp list for uninit tmplist*: seq[tuple[nimp, jsp: pointer]] var globalRuntime* {.global.}: JSRuntime iterator finalizers*(rtOpaque: JSRuntimeOpaque; classid: JSClassID): JSFinalizerFunction = let classid = int(classid) if classid < rtOpaque.classes.len: for fin in rtOpaque.classes[classid].fins: yield fin proc newJSContextOpaque*(ctx: JSContext): JSContextOpaque = let opaque = JSContextOpaque(global: JS_GetGlobalObject(ctx)) let sym = JS_GetPropertyStr(ctx, opaque.global, "Symbol") for s in JSSymbolRef: let name = $s let val = JS_GetPropertyStr(ctx, sym, cstring(name)) assert JS_IsSymbol(val) opaque.symRefs[s] = JS_ValueToAtom(ctx, val) JS_FreeValue(ctx, val) JS_FreeValue(ctx, sym) for s in JSStrRef: let ss = $s opaque.strRefs[s] = JS_NewAtomLen(ctx, cstring(ss), csize_t(ss.len)) for s in JSValueRef: let ss = $s let ret = JS_Eval(ctx, cstring(ss), csize_t(ss.len), "<init>", 0) assert JS_IsFunction(ctx, ret) opaque.valRefs[s] = ret return opaque proc getOpaque*(ctx: JSContext): JSContextOpaque = return cast[JSContextOpaque](JS_GetContextOpaque(ctx)) proc getOpaque*(rt: JSRuntime): JSRuntimeOpaque = return cast[JSRuntimeOpaque](JS_GetRuntimeOpaque(rt)) proc getOpaque*(val: JSValue): pointer = if JS_VALUE_GET_TAG(val) == JS_TAG_OBJECT: return JS_GetOpaque(val, JS_GetClassID(val)) return nil proc setUnforgeable*(ctx: JSContext; val: JSValueConst; class: JSClassID): bool = let rtOpaque = JS_GetRuntime(ctx).getOpaque() let iclass = int(class) if iclass < rtOpaque.classes.len and rtOpaque.classes[iclass].unforgeable.len > 0: let ufp0 = addr rtOpaque.classes[iclass].unforgeable[0] let ufp = cast[JSCFunctionListP](ufp0) if JS_SetPropertyFunctionList(ctx, val, ufp, cint(rtOpaque.classes[iclass].unforgeable.len)) == -1: return false true proc putEnums0(ctx: JSContext; entry: var EnumMapEntry; atoms: openArray[string]): bool = entry.enums = newSeqOfCap[EnumMapItem](atoms.len) if entry.atoms.len < atoms.len: entry.atoms.setLen(atoms.len) for i in 0'i32 ..< int32(atoms.len): let atom = JS_NewAtomLen(ctx, cstringConst(atoms[i]), csize_t(atoms[i].len)) if atom == JS_ATOM_NULL: return false if entry.atoms[i] == JS_ATOM_NULL: entry.atoms[i] = JS_DupAtom(ctx, atom) entry.enums.add(EnumMapItem(n: i, atom: atom)) entry.enums.sort(proc(x, y: EnumMapItem): int {.nimcall.} = cmp(uint32(x.atom), uint32(y.atom)) ) true proc putEnums*(ctx: JSContext; enumId: int; atoms: openArray[string]): bool = let rtOpaque = JS_GetRuntime(ctx).getOpaque() if enumId >= rtOpaque.enumMap.len: rtOpaque.enumMap.setLen(enumId + 1) if rtOpaque.enumMap[enumId].enums.len == atoms.len: return true ctx.putEnums0(rtOpaque.enumMap[enumId], atoms) {.pop.} # raises �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/jspropenumlist.nim���������������������������������������������0000664�0000000�0000000�00000002233�15202323131�0023205�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import quickjs type JSPropertyEnumArray* = ptr UncheckedArray[JSPropertyEnum] JSPropertyEnumList* = object buffer*: JSPropertyEnumArray size: uint32 len*: uint32 ctx: JSContext proc newJSPropertyEnumList*(ctx: JSContext; size: uint32): JSPropertyEnumList = let p = if size != 0: js_malloc(ctx, csize_t(sizeof(JSPropertyEnum)) * csize_t(size)) else: nil return JSPropertyEnumList( ctx: ctx, buffer: cast[JSPropertyEnumArray](p), size: size ) proc grow(this: var JSPropertyEnumList) = if this.size == 0: this.size = 1 this.size *= 2 let p = js_realloc(this.ctx, this.buffer, csize_t(sizeof(JSPropertyEnum)) * csize_t(this.size)) this.buffer = cast[JSPropertyEnumArray](p) proc add*(this: var JSPropertyEnumList; val: uint32) = let i = this.len inc this.len if this.size < this.len: this.grow() this.buffer[i].atom = JS_NewAtomUInt32(this.ctx, val) proc add*(this: var JSPropertyEnumList; val: string) = let i = this.len inc this.len if this.size < this.len: this.grow() this.buffer[i].atom = JS_NewAtomLen(this.ctx, cstring(val), csize_t(val.len)) {.pop.} # raises ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/jstypes.nim����������������������������������������������������0000664�0000000�0000000�00000003314�15202323131�0021611�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import jsopaque import quickjs # This is the WebIDL dictionary type. # We only use it for type inference in generics. type # JSDictToFreeAux is a hack to ensure JSValues are freed only # when the JSDict goes out of scope. Ugly and sub-optimal, but it does # the job. JSDictToFreeAux* = ref JSDictToFreeAuxObj JSDictToFreeAuxObj = object vals*: seq[JSValue] JSDict* {.pure, inheritable.} = object toFree*: JSDictToFreeAux proc `=destroy`*(x: var JSDictToFreeAuxObj) = for val in x.vals: JS_FreeValueRT(globalRuntime, val) # Example usage: # # type MyOptions = object of JSDict # x {.jsdefault: 1.}: int # y {.jsdefault.}: bool # # For the above JSDict, no exception will be thrown if `x` is missing; instead, # it gets set to `1'. template jsdefault*(x: untyped) {.pragma.} template jsdefault*() {.pragma.} # Container compatible with the internal representation of narrow strings in # QuickJS (Latin-1). type NarrowString* = distinct string # Various containers for array buffer types. # Converting these only requires copying the metadata; buffers are never copied. type JSArrayBuffer* = object p*: ptr UncheckedArray[uint8] len*: csize_t dealloc*: JSFreeArrayBufferDataFunc JSArrayBufferView* = object abuf*: JSArrayBuffer offset*: int # offset into the buffer len*: int # number of members bytesPerItem*: uint8 # ignored in toJS t*: JSTypedArrayEnum # type template toOpenArray*(view: JSArrayBufferView): openArray[uint8] = view.abuf.p.toOpenArray(view.offset, view.offset + view.len - 1) # A key-value pair: in WebIDL terms, this is a record. type JSKeyValuePair*[K, T] = object s*: seq[tuple[name: string; value: T]] {.pop.} # raises ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/jsutils.nim����������������������������������������������������0000664�0000000�0000000�00000032000�15202323131�0021577�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Miscellaneous wrappers around QJS functions. {.push raises: [].} import dtoa import jsopaque import quickjs template toJSValueArray*(a: openArray[JSValue]): JSValueArray = if a.len > 0: cast[ptr UncheckedArray[JSValue]](unsafeAddr a[0]) else: nil template toJSValueConstArray*(a: openArray[JSValue]): JSValueConstArray = cast[JSValueConstArray](a.toJSValueArray()) template toJSValueConstArray*(a: openArray[JSValueConst]): JSValueConstArray = if a.len > 0: cast[ptr UncheckedArray[JSValueConst]](unsafeAddr a[0]) else: nil template toJSValueConstOpenArray*(a: openArray[JSValue]): openArray[JSValueConst] = a.toJSValueConstArray().toOpenArray(0, a.high) # This must be a template, because we're taking the address of the passed # value, and Nim is pass-by-value. template toJSValueArray*(a: JSValue): JSValueArray = cast[JSValueArray](unsafeAddr a) template toJSValueConstArray*(a: JSValueConst): JSValueConstArray = cast[JSValueConstArray](unsafeAddr a) proc JS_CallFree*(ctx: JSContext; funcObj: JSValue; this: JSValueConst; argc: cint; argv: JSValueConstArray): JSValue = result = JS_Call(ctx, funcObj, this, argc, argv) JS_FreeValue(ctx, funcObj) proc freeValues*(rt: JSRuntime; vals: varargs[JSValue]) = ## Free each individual value in `vals`. for val in vals: JS_FreeValueRT(rt, val) proc freeValues*(ctx: JSContext; vals: varargs[JSValue]) = ## Free each individual value in `vals`. for val in vals: JS_FreeValue(ctx, val) proc call*(ctx: JSContext; funcObj, this: JSValueConst; argv: varargs[JSValueConst]): JSValue = ## Call `funcObj` with the this value `this` and parameters `argv`. JS_Call(ctx, funcObj, this, cast[cint](argv.len), argv.toJSValueConstArray()) proc callFree*(ctx: JSContext; funcObj: JSValue; this: JSValueConst; argv: varargs[JSValueConst]): JSValue = ## Call `funcObj` with the this value `this` and parameters `argv`, then ## free `funcObj`. JS_CallFree(ctx, funcObj, this, cast[cint](argv.len), argv.toJSValueConstArray()) proc callSink*(ctx: JSContext; funcObj, this: JSValueConst; argv: varargs[JSValue]): JSValue = ## Call `funcObj` with the this value `this` and parameters `argv`, then ## free each element of `argv`. let res = JS_Call(ctx, funcObj, this, cast[cint](argv.len), argv.toJSValueConstArray()) ctx.freeValues(argv) res proc callSinkThis*(ctx: JSContext; funcObj: JSValueConst; this: JSValue; argv: varargs[JSValue]): JSValue = ## Call `funcObj` with the this value `this` and parameters `argv`, then ## free each element of `argv` as well as `this`. let res = ctx.callSink(funcObj, this, argv) JS_FreeValue(ctx, this) res proc callSinkFree*(ctx: JSContext; funcObj: JSValue; this: JSValueConst; argv: varargs[JSValue]): JSValue = ## Call `funcObj` with the this value `this` and parameters `argv`, then ## free each element of `argv` and `funcObj`. let res = ctx.callSink(funcObj, this, argv) JS_FreeValue(ctx, funcObj) res proc callSinkThisFree*(ctx: JSContext; funcObj, this: JSValue; argv: varargs[JSValue]): JSValue = ## Call `funcObj` with the this value `this` and parameters `argv`, then ## free each element of `argv` and `funcObj`. let res = ctx.callSinkThis(funcObj, this, argv) JS_FreeValue(ctx, funcObj) res proc invoke*(ctx: JSContext; val: JSValueConst; atom: JSAtom; argv: varargs[JSValueConst]): JSValue = ## Invoke the function named `atom` on `val`. JS_Invoke(ctx, val, atom, cast[cint](argv.len), argv.toJSValueConstArray()) proc invokeSink*(ctx: JSContext; val: JSValueConst; atom: JSAtom; argv: varargs[JSValue]): JSValue = ## Invoke the function named `atom` on `val`, then free each element of ## `argv`. let res = JS_Invoke(ctx, val, atom, cast[cint](argv.len), argv.toJSValueArray()) for arg in argv: JS_FreeValue(ctx, arg) res proc toUndefined*(ctx: JSContext; val: JSValue): JSValue = ## Free JSValue, and return JS_EXCEPTION if it's an exception (or ## undefined otherwise). if JS_IsException(val): return JS_EXCEPTION JS_FreeValue(ctx, val) return JS_UNDEFINED proc newArrayFrom*(ctx: JSContext; vals: varargs[JSValue]): JSValue = ## Create a new array consisting of `vals`. ## ## Frees/consumes each individual value in `vals`. if int64(vals.len) > int64(uint32.high): ctx.freeValues(vals) return JS_ThrowRangeError(ctx, "sequence too large") var obj = JS_NewArray(ctx) if JS_IsException(obj): return obj var u = 0u32 let L = uint32(vals.len) while u < L: let res = JS_SetPropertyUint32(ctx, obj, u, vals[u]) inc u if res < 0: JS_FreeValue(ctx, obj) obj = JS_EXCEPTION break while u < L: JS_FreeValue(ctx, vals[u]) inc u return obj proc newPromiseCapability*(ctx: JSContext; funs: array[2, JSValue]): JSValue = return JS_NewPromiseCapability(ctx, funs.toJSValueArray()) proc enqueueJob*(ctx: JSContext; fun: JSJobFunc; argv: varargs[JSValueConst]): cint = return JS_EnqueueJob(ctx, fun, cint(argv.len), argv.toJSValueConstArray()) proc rejectJob(ctx: JSContext; argc: cint; argv: JSValueConstArray): JSValue {.cdecl.} = return ctx.call(argv[0], JS_UNDEFINED, argv[1]) proc enqueueRejection*(ctx: JSContext; reject: JSValue): cint = ## Usage: throw an exception, then call queueRejection with the reject fun. ## reject is freed. let ex = JS_GetException(ctx) let code = ctx.enqueueJob(rejectJob, reject, ex) JS_FreeValue(ctx, reject) JS_FreeValue(ctx, ex) return code type DefinePropertyResult* = enum dprException, dprSuccess, dprFail proc defineProperty*(ctx: JSContext; this: JSValueConst; name: JSAtom; prop: JSValue; flags = cint(0)): DefinePropertyResult = ## Frees/consumes `prop'. return case JS_DefinePropertyValue(ctx, this, name, prop, flags) of 0: dprFail of 1: dprSuccess else: dprException proc definePropertyC*(ctx: JSContext; this: JSValueConst; name: JSAtom; prop: JSValue): DefinePropertyResult = ## Define a configurable property on `this`. ## ## Frees `prop'. ctx.defineProperty(this, name, prop, JS_PROP_CONFIGURABLE) proc defineProperty*(ctx: JSContext; this: JSValueConst; name: cstring; prop: JSValue; flags = cint(0)): DefinePropertyResult = ## Define an immutable property on `this`. ## ## Frees `prop'. return case JS_DefinePropertyValueStr(ctx, this, name, prop, flags) of 0: dprFail of 1: dprSuccess else: dprException proc definePropertyC*(ctx: JSContext; this: JSValueConst; name: string; prop: JSValue): DefinePropertyResult = ## Define a configurable property on `this`. ## ## Frees `prop'. ctx.defineProperty(this, name, prop, JS_PROP_CONFIGURABLE) proc definePropertyE*(ctx: JSContext; this: JSValueConst; name: string; prop: JSValue): DefinePropertyResult = ## Define an enumerable property on `this`. ## ## Frees `prop'. ctx.defineProperty(this, name, prop, JS_PROP_ENUMERABLE) proc definePropertyCW*(ctx: JSContext; this: JSValueConst; name: JSAtom; prop: JSValue): DefinePropertyResult = ## Frees `prop'. ctx.defineProperty(this, name, prop, JS_PROP_CONFIGURABLE or JS_PROP_WRITABLE) proc definePropertyCW*(ctx: JSContext; this: JSValueConst; name: string; prop: JSValue): DefinePropertyResult = ## Frees `prop'. ctx.defineProperty(this, name, prop, JS_PROP_CONFIGURABLE or JS_PROP_WRITABLE) proc definePropertyCWE*(ctx: JSContext; this: JSValueConst; name: JSAtom; prop: JSValue): DefinePropertyResult = ## Frees `prop'. ctx.defineProperty(this, name, prop, JS_PROP_C_W_E) proc definePropertyCWE*(ctx: JSContext; this: JSValueConst; name: string; prop: JSValue): DefinePropertyResult = ## Frees `prop'. ctx.defineProperty(this, name, prop, JS_PROP_C_W_E) proc strictEquals*(ctx: JSContext; a, b: JSValueConst): bool = ## Returns true if `a === b', false otherwise. return JS_StrictEq(ctx, a, b) proc addRow(s: var string; title: string; count, size, sz2, cnt2: int64; name: string) = let d = cdouble(sz2) / cdouble(cnt2) let dn = js_dtoa_max_len(d, 10, 1, JS_DTOA_FORMAT_FIXED) var buf = newString(dn) var tmp: JSDTOATempMem let len = js_dtoa(cstring(buf), d, 10, 1, JS_DTOA_FORMAT_FIXED, tmp) buf.setLen(int(len)) s &= title & ": " & $count & " " & $size & " (" & buf & ")" & name & "\n" proc addRow(s: var string; title: string; count, size, sz2: int64; name: string) = s.addRow(title, count, size, sz2, count, name) proc addRow(s: var string; title: string; count, size: int64; name: string) = s.addRow(title, count, size, size, name) proc getMemoryUsage*(rt: JSRuntime): string = ## Prints a formatted message of the current memory usage. ## This wraps `JS_ComputeMemoryUsage`. var m: JSMemoryUsage JS_ComputeMemoryUsage(rt, m) var s = "" if m.malloc_count != 0: s.addRow("memory allocated", m.malloc_count, m.malloc_size, "/block") s.addRow("memory used", m.memory_used_count, m.memory_used_size, m.malloc_size - m.memory_used_size, " average slack") if m.atom_count != 0: s.addRow("atoms", m.atom_count, m.atom_size, "/atom") if m.str_count != 0: s.addRow("strings", m.str_count, m.str_size, "/string") if m.obj_count != 0: s.addRow("objects", m.obj_count, m.obj_size, "/object") s.addRow("properties", m.prop_count, m.prop_size, m.prop_size, m.obj_count, "/object") s.addRow("shapes", m.shape_count, m.shape_size, "/shape") if m.js_func_count != 0: s.addRow("js functions", m.js_func_count, m.js_func_size, "/function") if m.c_func_count != 0: s &= "native functions: " & $m.c_func_count & "\n" if m.array_count != 0: s &= "arrays: " & $m.array_count & "\n" & "fast arrays: " & $m.fast_array_count & "\n" s.addRow("fast array elements", m.fast_array_elements, m.fast_array_elements * sizeof(JSValue), m.fast_array_elements, m.fast_array_count, "") if m.binary_object_count != 0: s &= "binary objects: " & $m.binary_object_count & " " & $m.binary_object_size move(s) proc eval*(ctx: JSContext; s: string; file = "<input>"; evalFlags = JS_EVAL_TYPE_GLOBAL): JSValue = ## Wrapper around JS_Eval. return JS_Eval(ctx, cstring(s), csize_t(s.len), cstring(file), evalFlags) proc compileScript*(ctx: JSContext; s: string; file = "<input>"): JSValue = ## Compiles `s` into bytecode. ## You can evaluate the result using `evalFunction`. return ctx.eval(s, file, JS_EVAL_FLAG_COMPILE_ONLY) proc compileModule*(ctx: JSContext; s: string; file = "<input>"): JSValue = ## Compiles `s` into a module. ## ## I forgot how to use this, check quickjs-libc.c in the original ## distribution if you're interested. return ctx.eval(s, file, JS_EVAL_TYPE_MODULE or JS_EVAL_FLAG_COMPILE_ONLY) proc evalFunction*(ctx: JSContext; val: JSValue): JSValue = ## Evaluates a bytecode function or a module. This wraps `JS_EvalFunction`. return JS_EvalFunction(ctx, val) proc defineConsts*(ctx: JSContext; classid: JSClassID; consts: typedesc[enum]): DefinePropertyResult = ## Define a list of constants expressed as a Nim enum on a class. let proto = JS_GetClassProto(ctx, classid) let ctor = ctx.getOpaque().ctors[int(classid)] var res = dprSuccess for e in consts: let s = $e res = ctx.definePropertyE(proto, s, JS_NewUint32(ctx, uint32(e))) if res != dprSuccess: break res = ctx.definePropertyE(ctor, s, JS_NewUint32(ctx, uint32(e))) if res != dprSuccess: break JS_FreeValue(ctx, proto) res proc setPropertyFunctionList*(ctx: JSContext; val: JSValueConst; funcs: openArray[JSCFunctionListEntry]): bool = if funcs.len == 0: return true let fp = cast[JSCFunctionListP](unsafeAddr funcs[0]) return JS_SetPropertyFunctionList(ctx, val, fp, cint(funcs.len)) != -1 proc identity(ctx: JSContext; this_val: JSValueConst; argc: cint; argv: JSValueConstArray; magic: cint; func_data: JSValueConstArray): JSValue {.cdecl.} = return JS_DupValue(ctx, func_data[0]) proc identityFunction*(ctx: JSContext; val: JSValueConst): JSValue = ## Returns a function that always returns `val`. return JS_NewCFunctionData(ctx, identity, 0, 0, 1, val.toJSValueConstArray()) proc getExceptionMsg*(ctx: JSContext): string = ## Converts the current exception to a string. result = "" let ex = JS_GetException(ctx) var plen: csize_t let outp = JS_ToCStringLen(ctx, plen, ex) # cstring if outp != nil: if plen > 0: result.setLen(plen) copyMem(addr result[0], cstring(outp), plen) JS_FreeCString(ctx, outp) result &= '\n' let stack = JS_GetPropertyStr(ctx, ex, cstring("stack")) JS_FreeValue(ctx, ex) if not JS_IsUndefined(stack): let outp = JS_ToCStringLen(ctx, plen, stack) # cstring if outp != nil: if plen > 0: let olen = result.len result.setLen(csize_t(olen) + plen) copyMem(addr result[olen], cstring(outp), plen) JS_FreeCString(ctx, outp) JS_FreeValue(ctx, stack) proc runJSJobs*(rt: JSRuntime): JSContext = ## Returns the first JSContext that threw an exception, or nil if no ## exception was thrown. while JS_IsJobPending(rt): var ctx: JSContext let r = JS_ExecutePendingJob(rt, ctx) if r == -1: return ctx nil {.pop.} # raises chawan-v0.4.0/lib/monoucha0/monoucha/libregexp.nim��������������������������������������������������0000664�0000000�0000000�00000004061�15202323131�0022071�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} from std/os import parentDir {.used.} # used so that we can import it from quickjs.nim import libunicode export libunicode.JS_BOOL when not compileOption("threads"): const CFLAGS = "-fwrapv -DCHA_NO_THREADS" else: const CFLAGS = "-fwrapv" {.compile("qjs/libregexp.c", CFLAGS).} # this is hardcoded into quickjs, so we must override it here. proc lre_realloc(opaque, p: pointer; size: csize_t): pointer {.exportc.} = if size == 0: if p != nil: dealloc(p) return nil return realloc(p, size) # Hack: quickjs provides a lre_check_stack_overflow, but that basically # depends on the entire QuickJS runtime. So to avoid pulling that in as # a necessary dependency, we must provide one ourselves, but *only* if # quickjs has not been imported. # So we define NOT_LRE_ONLY in quickjs.nim, and check it in the "second # compilation pass" (i.e. in C). {.emit: """ #ifndef NOT_LRE_ONLY int lre_check_timeout(void *opaque) { return 0; } int lre_check_stack_overflow(void *opaque, size_t alloca_size) { return 0; } #endif """.} type LREFlag* {.size: sizeof(cint).} = enum LRE_FLAG_GLOBAL = "g" LRE_FLAG_IGNORECASE = "i" LRE_FLAG_MULTILINE = "m" LRE_FLAG_DOTALL = "s" LRE_FLAG_UNICODE = "u" LRE_FLAG_STICKY = "y" LREFlags* = set[LREFlag] proc toCInt*(flags: LREFlags): cint = cint(cast[uint8](flags)) proc toLREFlags*(flags: cint): LREFlags = cast[LREFlags](flags) {.passc: "-I" & currentSourcePath().parentDir().} {.push header: "qjs/libregexp.h", importc.} proc lre_compile*(plen: var cint; error_msg: cstring; error_msg_size: cint; buf: cstring; buf_len: csize_t; re_flags: cint; opaque: pointer): ptr uint8 proc lre_exec*(capture: ptr ptr uint8; bc_buf, cbuf: ptr uint8; cindex, clen, cbuf_type: cint; opaque: pointer): cint proc lre_get_alloc_count*(bc_buf: ptr uint8): cint proc lre_get_capture_count*(bc_buf: ptr uint8): cint proc lre_get_flags*(bc_buf: ptr uint8): cint proc lre_is_space_non_ascii*(c: uint32): JS_BOOL proc lre_is_space*(c: uint32): JS_BOOL {.pop.} # header, importc {.pop.} # raises �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/libunicode.nim�������������������������������������������������0000664�0000000�0000000�00000002777�15202323131�0022241�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} from std/os import parentDir import cutils export cutils.JS_BOOL {.used.} {.compile("qjs/libunicode.c", "-fwrapv").} const luheader = """ #include "qjs/cutils.h" #include "qjs/libunicode.h" """ type DynBufReallocFunc = proc(opaque, p: pointer; size: csize_t): pointer {.cdecl.} CharRange* {.importc, header: luheader.} = object len*: cint # in points, always even size*: cint points*: ptr uint32 # points sorted by increasing value mem_opaque*: pointer realloc_func*: DynBufReallocFunc UnicodeNormalizationEnum* {.size: sizeof(cint).} = enum UNICODE_NFC, UNICODE_NFD, UNICODE_NFKC, UNICODE_NFKD {.passc: "-I" & currentSourcePath().parentDir().} {.push header: luheader, importc.} proc cr_init*(cr: ptr CharRange; mem_opaque: pointer; realloc_func: DynBufReallocFunc) proc cr_free*(cr: ptr CharRange) # conv_type: # 0 = to upper # 1 = to lower # 2 = case folding # res must be an array of LRE_CC_RES_LEN_MAX const LRE_CC_RES_LEN_MAX* = 3 proc lre_case_conv*(res: ptr UncheckedArray[uint32]; c: uint32; conv_type: cint): cint proc unicode_normalize*(pdst: ptr ptr uint32; src: ptr uint32; src_len: cint; n_type: UnicodeNormalizationEnum; opaque: pointer; realloc_func: DynBufReallocFunc): cint proc unicode_script*(cr: ptr CharRange; script_name: cstring; is_ext: JS_BOOL): cint proc unicode_prop*(cr: ptr CharRange; prop_name: cstring): cint proc unicode_general_category*(cr: ptr CharRange; gc_name: cstring): cint {.pop.} # header, importc {.pop.} # raises �chawan-v0.4.0/lib/monoucha0/monoucha/qjs/�����������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0020177�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/qjs/LICENSE����������������������������������������������������0000664�0000000�0000000�00000002152�15202323131�0021204�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������QuickJS Javascript Engine Copyright (c) 2017-2021 Fabrice Bellard Copyright (c) 2017-2021 Charlie Gordon Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/qjs/cutils.c���������������������������������������������������0000664�0000000�0000000�00000042606�15202323131�0021656�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * C utilities * * Copyright (c) 2017 Fabrice Bellard * Copyright (c) 2018 Charlie Gordon * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include <stdlib.h> #include <stdio.h> #include <stdarg.h> #include <string.h> #include "cutils.h" void pstrcpy(char *buf, int buf_size, const char *str) { int c; char *q = buf; if (buf_size <= 0) return; for(;;) { c = *str++; if (c == 0 || q >= buf + buf_size - 1) break; *q++ = c; } *q = '\0'; } /* strcat and truncate. */ char *pstrcat(char *buf, int buf_size, const char *s) { int len; len = strlen(buf); if (len < buf_size) pstrcpy(buf + len, buf_size - len, s); return buf; } int strstart(const char *str, const char *val, const char **ptr) { const char *p, *q; p = str; q = val; while (*q != '\0') { if (*p != *q) return 0; p++; q++; } if (ptr) *ptr = p; return 1; } int has_suffix(const char *str, const char *suffix) { size_t len = strlen(str); size_t slen = strlen(suffix); return (len >= slen && !memcmp(str + len - slen, suffix, slen)); } /* Dynamic buffer package */ static void *dbuf_default_realloc(void *opaque, void *ptr, size_t size) { return realloc(ptr, size); } void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func) { memset(s, 0, sizeof(*s)); if (!realloc_func) realloc_func = dbuf_default_realloc; s->opaque = opaque; s->realloc_func = realloc_func; } void dbuf_init(DynBuf *s) { dbuf_init2(s, NULL, NULL); } /* Try to allocate 'len' more bytes. return < 0 if error */ int dbuf_claim(DynBuf *s, size_t len) { size_t new_size, size; uint8_t *new_buf; new_size = s->size + len; if (new_size < len) return -1; /* overflow case */ if (new_size > s->allocated_size) { if (s->error) return -1; size = s->allocated_size + (s->allocated_size / 2); if (size < s->allocated_size) return -1; /* overflow case */ if (size > new_size) new_size = size; new_buf = s->realloc_func(s->opaque, s->buf, new_size); if (!new_buf) { s->error = TRUE; return -1; } s->buf = new_buf; s->allocated_size = new_size; } return 0; } int dbuf_put(DynBuf *s, const uint8_t *data, size_t len) { if (unlikely((s->allocated_size - s->size) < len)) { if (dbuf_claim(s, len)) return -1; } memcpy_no_ub(s->buf + s->size, data, len); s->size += len; return 0; } int dbuf_put_self(DynBuf *s, size_t offset, size_t len) { if (unlikely((s->allocated_size - s->size) < len)) { if (dbuf_claim(s, len)) return -1; } memcpy(s->buf + s->size, s->buf + offset, len); s->size += len; return 0; } int __dbuf_putc(DynBuf *s, uint8_t c) { return dbuf_put(s, &c, 1); } int __dbuf_put_u16(DynBuf *s, uint16_t val) { return dbuf_put(s, (uint8_t *)&val, 2); } int __dbuf_put_u32(DynBuf *s, uint32_t val) { return dbuf_put(s, (uint8_t *)&val, 4); } int __dbuf_put_u64(DynBuf *s, uint64_t val) { return dbuf_put(s, (uint8_t *)&val, 8); } int dbuf_putstr(DynBuf *s, const char *str) { return dbuf_put(s, (const uint8_t *)str, strlen(str)); } int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s, const char *fmt, ...) { va_list ap; char buf[128]; int len; va_start(ap, fmt); len = vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); if (len < 0) return -1; if (len < sizeof(buf)) { /* fast case */ return dbuf_put(s, (uint8_t *)buf, len); } else { if (dbuf_claim(s, len + 1)) return -1; va_start(ap, fmt); vsnprintf((char *)(s->buf + s->size), s->allocated_size - s->size, fmt, ap); va_end(ap); s->size += len; } return 0; } void dbuf_free(DynBuf *s) { /* we test s->buf as a fail safe to avoid crashing if dbuf_free() is called twice */ if (s->buf) { s->realloc_func(s->opaque, s->buf, 0); } memset(s, 0, sizeof(*s)); } /* Note: at most 31 bits are encoded. At most UTF8_CHAR_LEN_MAX bytes are output. */ int unicode_to_utf8(uint8_t *buf, unsigned int c) { uint8_t *q = buf; if (c < 0x80) { *q++ = c; } else { if (c < 0x800) { *q++ = (c >> 6) | 0xc0; } else { if (c < 0x10000) { *q++ = (c >> 12) | 0xe0; } else { if (c < 0x00200000) { *q++ = (c >> 18) | 0xf0; } else { if (c < 0x04000000) { *q++ = (c >> 24) | 0xf8; } else if (c < 0x80000000) { *q++ = (c >> 30) | 0xfc; *q++ = ((c >> 24) & 0x3f) | 0x80; } else { return 0; } *q++ = ((c >> 18) & 0x3f) | 0x80; } *q++ = ((c >> 12) & 0x3f) | 0x80; } *q++ = ((c >> 6) & 0x3f) | 0x80; } *q++ = (c & 0x3f) | 0x80; } return q - buf; } static const unsigned int utf8_min_code[5] = { 0x80, 0x800, 0x10000, 0x00200000, 0x04000000, }; static const unsigned char utf8_first_code_mask[5] = { 0x1f, 0xf, 0x7, 0x3, 0x1, }; /* return -1 if error. *pp is not updated in this case. max_len must be >= 1. The maximum length for a UTF8 byte sequence is 6 bytes. */ int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp) { int l, c, b, i; c = *p++; if (c < 0x80) { *pp = p; return c; } switch(c) { case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: l = 1; break; case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: l = 2; break; case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: l = 3; break; case 0xf8: case 0xf9: case 0xfa: case 0xfb: l = 4; break; case 0xfc: case 0xfd: l = 5; break; default: return -1; } /* check that we have enough characters */ if (l > (max_len - 1)) return -1; c &= utf8_first_code_mask[l - 1]; for(i = 0; i < l; i++) { b = *p++; if (b < 0x80 || b >= 0xc0) return -1; c = (c << 6) | (b & 0x3f); } if (c < utf8_min_code[l - 1]) return -1; *pp = p; return c; } #if 0 #if defined(__EMSCRIPTEN__) || defined(__ANDROID__) static void *rqsort_arg; static int (*rqsort_cmp)(const void *, const void *, void *); static int rqsort_cmp2(const void *p1, const void *p2) { return rqsort_cmp(p1, p2, rqsort_arg); } /* not reentrant, but not needed with emscripten */ void rqsort(void *base, size_t nmemb, size_t size, int (*cmp)(const void *, const void *, void *), void *arg) { rqsort_arg = arg; rqsort_cmp = cmp; qsort(base, nmemb, size, rqsort_cmp2); } #endif #else typedef void (*exchange_f)(void *a, void *b, size_t size); typedef int (*cmp_f)(const void *, const void *, void *opaque); static void exchange_bytes(void *a, void *b, size_t size) { uint8_t *ap = (uint8_t *)a; uint8_t *bp = (uint8_t *)b; while (size-- != 0) { uint8_t t = *ap; *ap++ = *bp; *bp++ = t; } } static void exchange_one_byte(void *a, void *b, size_t size) { uint8_t *ap = (uint8_t *)a; uint8_t *bp = (uint8_t *)b; uint8_t t = *ap; *ap = *bp; *bp = t; } static void exchange_int16s(void *a, void *b, size_t size) { uint16_t *ap = (uint16_t *)a; uint16_t *bp = (uint16_t *)b; for (size /= sizeof(uint16_t); size-- != 0;) { uint16_t t = *ap; *ap++ = *bp; *bp++ = t; } } static void exchange_one_int16(void *a, void *b, size_t size) { uint16_t *ap = (uint16_t *)a; uint16_t *bp = (uint16_t *)b; uint16_t t = *ap; *ap = *bp; *bp = t; } static void exchange_int32s(void *a, void *b, size_t size) { uint32_t *ap = (uint32_t *)a; uint32_t *bp = (uint32_t *)b; for (size /= sizeof(uint32_t); size-- != 0;) { uint32_t t = *ap; *ap++ = *bp; *bp++ = t; } } static void exchange_one_int32(void *a, void *b, size_t size) { uint32_t *ap = (uint32_t *)a; uint32_t *bp = (uint32_t *)b; uint32_t t = *ap; *ap = *bp; *bp = t; } static void exchange_int64s(void *a, void *b, size_t size) { uint64_t *ap = (uint64_t *)a; uint64_t *bp = (uint64_t *)b; for (size /= sizeof(uint64_t); size-- != 0;) { uint64_t t = *ap; *ap++ = *bp; *bp++ = t; } } static void exchange_one_int64(void *a, void *b, size_t size) { uint64_t *ap = (uint64_t *)a; uint64_t *bp = (uint64_t *)b; uint64_t t = *ap; *ap = *bp; *bp = t; } static void exchange_int128s(void *a, void *b, size_t size) { uint64_t *ap = (uint64_t *)a; uint64_t *bp = (uint64_t *)b; for (size /= sizeof(uint64_t) * 2; size-- != 0; ap += 2, bp += 2) { uint64_t t = ap[0]; uint64_t u = ap[1]; ap[0] = bp[0]; ap[1] = bp[1]; bp[0] = t; bp[1] = u; } } static void exchange_one_int128(void *a, void *b, size_t size) { uint64_t *ap = (uint64_t *)a; uint64_t *bp = (uint64_t *)b; uint64_t t = ap[0]; uint64_t u = ap[1]; ap[0] = bp[0]; ap[1] = bp[1]; bp[0] = t; bp[1] = u; } static inline exchange_f exchange_func(const void *base, size_t size) { switch (((uintptr_t)base | (uintptr_t)size) & 15) { case 0: if (size == sizeof(uint64_t) * 2) return exchange_one_int128; else return exchange_int128s; case 8: if (size == sizeof(uint64_t)) return exchange_one_int64; else return exchange_int64s; case 4: case 12: if (size == sizeof(uint32_t)) return exchange_one_int32; else return exchange_int32s; case 2: case 6: case 10: case 14: if (size == sizeof(uint16_t)) return exchange_one_int16; else return exchange_int16s; default: if (size == 1) return exchange_one_byte; else return exchange_bytes; } } static void heapsortx(void *base, size_t nmemb, size_t size, cmp_f cmp, void *opaque) { uint8_t *basep = (uint8_t *)base; size_t i, n, c, r; exchange_f swap = exchange_func(base, size); if (nmemb > 1) { i = (nmemb / 2) * size; n = nmemb * size; while (i > 0) { i -= size; for (r = i; (c = r * 2 + size) < n; r = c) { if (c < n - size && cmp(basep + c, basep + c + size, opaque) <= 0) c += size; if (cmp(basep + r, basep + c, opaque) > 0) break; swap(basep + r, basep + c, size); } } for (i = n - size; i > 0; i -= size) { swap(basep, basep + i, size); for (r = 0; (c = r * 2 + size) < i; r = c) { if (c < i - size && cmp(basep + c, basep + c + size, opaque) <= 0) c += size; if (cmp(basep + r, basep + c, opaque) > 0) break; swap(basep + r, basep + c, size); } } } } static inline void *med3(void *a, void *b, void *c, cmp_f cmp, void *opaque) { return cmp(a, b, opaque) < 0 ? (cmp(b, c, opaque) < 0 ? b : (cmp(a, c, opaque) < 0 ? c : a )) : (cmp(b, c, opaque) > 0 ? b : (cmp(a, c, opaque) < 0 ? a : c )); } /* pointer based version with local stack and insertion sort threshhold */ void rqsort(void *base, size_t nmemb, size_t size, cmp_f cmp, void *opaque) { struct { uint8_t *base; size_t count; int depth; } stack[50], *sp = stack; uint8_t *ptr, *pi, *pj, *plt, *pgt, *top, *m; size_t m4, i, lt, gt, span, span2; int c, depth; exchange_f swap = exchange_func(base, size); exchange_f swap_block = exchange_func(base, size | 128); if (nmemb < 2 || size <= 0) return; sp->base = (uint8_t *)base; sp->count = nmemb; sp->depth = 0; sp++; while (sp > stack) { sp--; ptr = sp->base; nmemb = sp->count; depth = sp->depth; while (nmemb > 6) { if (++depth > 50) { /* depth check to ensure worst case logarithmic time */ heapsortx(ptr, nmemb, size, cmp, opaque); nmemb = 0; break; } /* select median of 3 from 1/4, 1/2, 3/4 positions */ /* should use median of 5 or 9? */ m4 = (nmemb >> 2) * size; m = med3(ptr + m4, ptr + 2 * m4, ptr + 3 * m4, cmp, opaque); swap(ptr, m, size); /* move the pivot to the start or the array */ i = lt = 1; pi = plt = ptr + size; gt = nmemb; pj = pgt = top = ptr + nmemb * size; for (;;) { while (pi < pj && (c = cmp(ptr, pi, opaque)) >= 0) { if (c == 0) { swap(plt, pi, size); lt++; plt += size; } i++; pi += size; } while (pi < (pj -= size) && (c = cmp(ptr, pj, opaque)) <= 0) { if (c == 0) { gt--; pgt -= size; swap(pgt, pj, size); } } if (pi >= pj) break; swap(pi, pj, size); i++; pi += size; } /* array has 4 parts: * from 0 to lt excluded: elements identical to pivot * from lt to pi excluded: elements smaller than pivot * from pi to gt excluded: elements greater than pivot * from gt to n excluded: elements identical to pivot */ /* move elements identical to pivot in the middle of the array: */ /* swap values in ranges [0..lt[ and [i-lt..i[ swapping the smallest span between lt and i-lt is sufficient */ span = plt - ptr; span2 = pi - plt; lt = i - lt; if (span > span2) span = span2; swap_block(ptr, pi - span, span); /* swap values in ranges [gt..top[ and [i..top-(top-gt)[ swapping the smallest span between top-gt and gt-i is sufficient */ span = top - pgt; span2 = pgt - pi; pgt = top - span2; gt = nmemb - (gt - i); if (span > span2) span = span2; swap_block(pi, top - span, span); /* now array has 3 parts: * from 0 to lt excluded: elements smaller than pivot * from lt to gt excluded: elements identical to pivot * from gt to n excluded: elements greater than pivot */ /* stack the larger segment and keep processing the smaller one to minimize stack use for pathological distributions */ if (lt > nmemb - gt) { sp->base = ptr; sp->count = lt; sp->depth = depth; sp++; ptr = pgt; nmemb -= gt; } else { sp->base = pgt; sp->count = nmemb - gt; sp->depth = depth; sp++; nmemb = lt; } } /* Use insertion sort for small fragments */ for (pi = ptr + size, top = ptr + nmemb * size; pi < top; pi += size) { for (pj = pi; pj > ptr && cmp(pj - size, pj, opaque) > 0; pj -= size) swap(pj, pj - size, size); } } } #endif ��������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/qjs/cutils.h���������������������������������������������������0000664�0000000�0000000�00000025632�15202323131�0021663�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * C utilities * * Copyright (c) 2017 Fabrice Bellard * Copyright (c) 2018 Charlie Gordon * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #ifndef CUTILS_H #define CUTILS_H #include <stdlib.h> #include <string.h> #include <inttypes.h> #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) #define force_inline inline __attribute__((always_inline)) #define no_inline __attribute__((noinline)) #define __maybe_unused __attribute__((unused)) #define xglue(x, y) x ## y #define glue(x, y) xglue(x, y) #define stringify(s) tostring(s) #define tostring(s) #s #ifndef offsetof #define offsetof(type, field) ((size_t) &((type *)0)->field) #endif #ifndef countof #define countof(x) (sizeof(x) / sizeof((x)[0])) #endif #ifndef container_of /* return the pointer of type 'type *' containing 'ptr' as field 'member' */ #define container_of(ptr, type, member) ((type *)((uint8_t *)(ptr) - offsetof(type, member))) #endif #if !defined(_MSC_VER) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define minimum_length(n) static n #else #define minimum_length(n) n #endif typedef int BOOL; #ifndef FALSE enum { FALSE = 0, TRUE = 1, }; #endif void pstrcpy(char *buf, int buf_size, const char *str); char *pstrcat(char *buf, int buf_size, const char *s); int strstart(const char *str, const char *val, const char **ptr); int has_suffix(const char *str, const char *suffix); /* Prevent UB when n == 0 and (src == NULL or dest == NULL) */ static inline void memcpy_no_ub(void *dest, const void *src, size_t n) { if (n) memcpy(dest, src, n); } static inline int max_int(int a, int b) { if (a > b) return a; else return b; } static inline int min_int(int a, int b) { if (a < b) return a; else return b; } static inline uint32_t max_uint32(uint32_t a, uint32_t b) { if (a > b) return a; else return b; } static inline uint32_t min_uint32(uint32_t a, uint32_t b) { if (a < b) return a; else return b; } static inline int64_t max_int64(int64_t a, int64_t b) { if (a > b) return a; else return b; } static inline int64_t min_int64(int64_t a, int64_t b) { if (a < b) return a; else return b; } /* WARNING: undefined if a = 0 */ static inline int clz32(unsigned int a) { return __builtin_clz(a); } /* WARNING: undefined if a = 0 */ static inline int clz64(uint64_t a) { return __builtin_clzll(a); } /* WARNING: undefined if a = 0 */ static inline int ctz32(unsigned int a) { return __builtin_ctz(a); } /* WARNING: undefined if a = 0 */ static inline int ctz64(uint64_t a) { return __builtin_ctzll(a); } struct __attribute__((packed)) packed_u64 { uint64_t v; }; struct __attribute__((packed)) packed_u32 { uint32_t v; }; struct __attribute__((packed)) packed_u16 { uint16_t v; }; static inline uint64_t get_u64(const uint8_t *tab) { return ((const struct packed_u64 *)tab)->v; } static inline int64_t get_i64(const uint8_t *tab) { return (int64_t)((const struct packed_u64 *)tab)->v; } static inline void put_u64(uint8_t *tab, uint64_t val) { ((struct packed_u64 *)tab)->v = val; } static inline uint32_t get_u32(const uint8_t *tab) { return ((const struct packed_u32 *)tab)->v; } static inline int32_t get_i32(const uint8_t *tab) { return (int32_t)((const struct packed_u32 *)tab)->v; } static inline void put_u32(uint8_t *tab, uint32_t val) { ((struct packed_u32 *)tab)->v = val; } static inline uint32_t get_u16(const uint8_t *tab) { return ((const struct packed_u16 *)tab)->v; } static inline int32_t get_i16(const uint8_t *tab) { return (int16_t)((const struct packed_u16 *)tab)->v; } static inline void put_u16(uint8_t *tab, uint16_t val) { ((struct packed_u16 *)tab)->v = val; } static inline uint32_t get_u8(const uint8_t *tab) { return *tab; } static inline int32_t get_i8(const uint8_t *tab) { return (int8_t)*tab; } static inline void put_u8(uint8_t *tab, uint8_t val) { *tab = val; } #ifndef bswap16 static inline uint16_t bswap16(uint16_t x) { return (x >> 8) | (x << 8); } #endif #ifndef bswap32 static inline uint32_t bswap32(uint32_t v) { return ((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >> 8) | ((v & 0x0000ff00) << 8) | ((v & 0x000000ff) << 24); } #endif #ifndef bswap64 static inline uint64_t bswap64(uint64_t v) { return ((v & ((uint64_t)0xff << (7 * 8))) >> (7 * 8)) | ((v & ((uint64_t)0xff << (6 * 8))) >> (5 * 8)) | ((v & ((uint64_t)0xff << (5 * 8))) >> (3 * 8)) | ((v & ((uint64_t)0xff << (4 * 8))) >> (1 * 8)) | ((v & ((uint64_t)0xff << (3 * 8))) << (1 * 8)) | ((v & ((uint64_t)0xff << (2 * 8))) << (3 * 8)) | ((v & ((uint64_t)0xff << (1 * 8))) << (5 * 8)) | ((v & ((uint64_t)0xff << (0 * 8))) << (7 * 8)); } #endif /* XXX: should take an extra argument to pass slack information to the caller */ typedef void *DynBufReallocFunc(void *opaque, void *ptr, size_t size); typedef struct DynBuf { uint8_t *buf; size_t size; size_t allocated_size; BOOL error; /* true if a memory allocation error occurred */ DynBufReallocFunc *realloc_func; void *opaque; /* for realloc_func */ } DynBuf; void dbuf_init(DynBuf *s); void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func); int dbuf_claim(DynBuf *s, size_t len); int dbuf_put(DynBuf *s, const uint8_t *data, size_t len); int dbuf_put_self(DynBuf *s, size_t offset, size_t len); int dbuf_putstr(DynBuf *s, const char *str); int __dbuf_putc(DynBuf *s, uint8_t c); int __dbuf_put_u16(DynBuf *s, uint16_t val); int __dbuf_put_u32(DynBuf *s, uint32_t val); int __dbuf_put_u64(DynBuf *s, uint64_t val); static inline int dbuf_putc(DynBuf *s, uint8_t val) { if (unlikely((s->allocated_size - s->size) < 1)) { return __dbuf_putc(s, val); } else { s->buf[s->size++] = val; return 0; } } static inline int dbuf_put_u16(DynBuf *s, uint16_t val) { if (unlikely((s->allocated_size - s->size) < 2)) { return __dbuf_put_u16(s, val); } else { put_u16(s->buf + s->size, val); s->size += 2; return 0; } } static inline int dbuf_put_u32(DynBuf *s, uint32_t val) { if (unlikely((s->allocated_size - s->size) < 4)) { return __dbuf_put_u32(s, val); } else { put_u32(s->buf + s->size, val); s->size += 4; return 0; } } static inline int dbuf_put_u64(DynBuf *s, uint64_t val) { if (unlikely((s->allocated_size - s->size) < 8)) { return __dbuf_put_u64(s, val); } else { put_u64(s->buf + s->size, val); s->size += 8; return 0; } } int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s, const char *fmt, ...); void dbuf_free(DynBuf *s); static inline BOOL dbuf_error(DynBuf *s) { return s->error; } static inline void dbuf_set_error(DynBuf *s) { s->error = TRUE; } #define UTF8_CHAR_LEN_MAX 6 int unicode_to_utf8(uint8_t *buf, unsigned int c); int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp); static inline BOOL is_surrogate(uint32_t c) { return (c >> 11) == (0xD800 >> 11); // 0xD800-0xDFFF } static inline BOOL is_hi_surrogate(uint32_t c) { return (c >> 10) == (0xD800 >> 10); // 0xD800-0xDBFF } static inline BOOL is_lo_surrogate(uint32_t c) { return (c >> 10) == (0xDC00 >> 10); // 0xDC00-0xDFFF } static inline uint32_t get_hi_surrogate(uint32_t c) { return (c >> 10) - (0x10000 >> 10) + 0xD800; } static inline uint32_t get_lo_surrogate(uint32_t c) { return (c & 0x3FF) | 0xDC00; } static inline uint32_t from_surrogate(uint32_t hi, uint32_t lo) { return 0x10000 + 0x400 * (hi - 0xD800) + (lo - 0xDC00); } static inline int from_hex(int c) { if (c >= '0' && c <= '9') return c - '0'; else if (c >= 'A' && c <= 'F') return c - 'A' + 10; else if (c >= 'a' && c <= 'f') return c - 'a' + 10; else return -1; } void rqsort(void *base, size_t nmemb, size_t size, int (*cmp)(const void *, const void *, void *), void *arg); static inline uint64_t float64_as_uint64(double d) { union { double d; uint64_t u64; } u; u.d = d; return u.u64; } static inline double uint64_as_float64(uint64_t u64) { union { double d; uint64_t u64; } u; u.u64 = u64; return u.d; } static inline double fromfp16(uint16_t v) { double d; uint32_t v1; v1 = v & 0x7fff; if (unlikely(v1 >= 0x7c00)) v1 += 0x1f8000; /* NaN or infinity */ d = uint64_as_float64(((uint64_t)(v >> 15) << 63) | ((uint64_t)v1 << (52 - 10))); return d * 0x1p1008; } static inline uint16_t tofp16(double d) { uint64_t a, addend; uint32_t v, sgn; int shift; a = float64_as_uint64(d); sgn = a >> 63; a = a & 0x7fffffffffffffff; if (unlikely(a > 0x7ff0000000000000)) { /* nan */ v = 0x7c01; } else if (a < 0x3f10000000000000) { /* 0x1p-14 */ /* subnormal f16 number or zero */ if (a <= 0x3e60000000000000) { /* 0x1p-25 */ v = 0x0000; /* zero */ } else { shift = 1051 - (a >> 52); a = ((uint64_t)1 << 52) | (a & (((uint64_t)1 << 52) - 1)); addend = ((a >> shift) & 1) + (((uint64_t)1 << (shift - 1)) - 1); v = (a + addend) >> shift; } } else { /* normal number or infinity */ a -= 0x3f00000000000000; /* adjust the exponent */ /* round */ addend = ((a >> (52 - 10)) & 1) + (((uint64_t)1 << (52 - 11)) - 1); v = (a + addend) >> (52 - 10); /* overflow ? */ if (unlikely(v > 0x7c00)) v = 0x7c00; } return v | (sgn << 15); } static inline int isfp16nan(uint16_t v) { return (v & 0x7FFF) > 0x7C00; } static inline int isfp16zero(uint16_t v) { return (v & 0x7FFF) == 0; } #endif /* CUTILS_H */ ������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/qjs/dtoa.c�����������������������������������������������������0000664�0000000�0000000�00000127524�15202323131�0021305�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Tiny float64 printing and parsing library * * Copyright (c) 2024 Fabrice Bellard * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include <stdlib.h> #include <stdio.h> #include <stdarg.h> #include <inttypes.h> #include <string.h> #include <assert.h> #include <ctype.h> #include <math.h> #include "cutils.h" #include "dtoa.h" /* TODO: - test n_digits=101 instead of 100 - simplify subnormal handling - reduce max memory usage - free format: could add shortcut if exact result - use 64 bit limb_t when possible - use another algorithm for free format dtoa in base 10 (ryu ?) */ #define USE_POW5_TABLE /* use fast path to print small integers in free format */ #define USE_FAST_INT #define LIMB_LOG2_BITS 5 #define LIMB_BITS (1 << LIMB_LOG2_BITS) typedef int32_t slimb_t; typedef uint32_t limb_t; typedef uint64_t dlimb_t; #define LIMB_DIGITS 9 #define JS_RADIX_MAX 36 #define DBIGNUM_LEN_MAX 52 /* ~ 2^(1072+53)*36^100 (dtoa) */ #define MANT_LEN_MAX 18 /* < 36^100 */ typedef intptr_t mp_size_t; /* the represented number is sum(i, tab[i]*2^(LIMB_BITS * i)) */ typedef struct { int len; /* >= 1 */ limb_t tab[]; } mpb_t; static limb_t mp_add_ui(limb_t *tab, limb_t b, size_t n) { size_t i; limb_t k, a; k=b; for(i=0;i<n;i++) { if (k == 0) break; a = tab[i] + k; k = (a < k); tab[i] = a; } return k; } /* tabr[] = taba[] * b + l. Return the high carry */ static limb_t mp_mul1(limb_t *tabr, const limb_t *taba, limb_t n, limb_t b, limb_t l) { limb_t i; dlimb_t t; for(i = 0; i < n; i++) { t = (dlimb_t)taba[i] * (dlimb_t)b + l; tabr[i] = t; l = t >> LIMB_BITS; } return l; } /* WARNING: d must be >= 2^(LIMB_BITS-1) */ static inline limb_t udiv1norm_init(limb_t d) { limb_t a0, a1; a1 = -d - 1; a0 = -1; return (((dlimb_t)a1 << LIMB_BITS) | a0) / d; } /* return the quotient and the remainder in '*pr'of 'a1*2^LIMB_BITS+a0 / d' with 0 <= a1 < d. */ static inline limb_t udiv1norm(limb_t *pr, limb_t a1, limb_t a0, limb_t d, limb_t d_inv) { limb_t n1m, n_adj, q, r, ah; dlimb_t a; n1m = ((slimb_t)a0 >> (LIMB_BITS - 1)); n_adj = a0 + (n1m & d); a = (dlimb_t)d_inv * (a1 - n1m) + n_adj; q = (a >> LIMB_BITS) + a1; /* compute a - q * r and update q so that the remainder is between 0 and d - 1 */ a = ((dlimb_t)a1 << LIMB_BITS) | a0; a = a - (dlimb_t)q * d - d; ah = a >> LIMB_BITS; q += 1 + ah; r = (limb_t)a + (ah & d); *pr = r; return q; } static limb_t mp_div1(limb_t *tabr, const limb_t *taba, limb_t n, limb_t b, limb_t r) { slimb_t i; dlimb_t a1; for(i = n - 1; i >= 0; i--) { a1 = ((dlimb_t)r << LIMB_BITS) | taba[i]; tabr[i] = a1 / b; r = a1 % b; } return r; } /* r = (a + high*B^n) >> shift. Return the remainder r (0 <= r < 2^shift). 1 <= shift <= LIMB_BITS - 1 */ static limb_t mp_shr(limb_t *tab_r, const limb_t *tab, mp_size_t n, int shift, limb_t high) { mp_size_t i; limb_t l, a; assert(shift >= 1 && shift < LIMB_BITS); l = high; for(i = n - 1; i >= 0; i--) { a = tab[i]; tab_r[i] = (a >> shift) | (l << (LIMB_BITS - shift)); l = a; } return l & (((limb_t)1 << shift) - 1); } /* r = (a << shift) + low. 1 <= shift <= LIMB_BITS - 1, 0 <= low < 2^shift. */ static limb_t mp_shl(limb_t *tab_r, const limb_t *tab, mp_size_t n, int shift, limb_t low) { mp_size_t i; limb_t l, a; assert(shift >= 1 && shift < LIMB_BITS); l = low; for(i = 0; i < n; i++) { a = tab[i]; tab_r[i] = (a << shift) | l; l = (a >> (LIMB_BITS - shift)); } return l; } static no_inline limb_t mp_div1norm(limb_t *tabr, const limb_t *taba, limb_t n, limb_t b, limb_t r, limb_t b_inv, int shift) { slimb_t i; if (shift != 0) { r = (r << shift) | mp_shl(tabr, taba, n, shift, 0); } for(i = n - 1; i >= 0; i--) { tabr[i] = udiv1norm(&r, r, taba[i], b, b_inv); } r >>= shift; return r; } static __maybe_unused void mpb_dump(const char *str, const mpb_t *a) { int i; printf("%s= 0x", str); for(i = a->len - 1; i >= 0; i--) { printf("%08x", a->tab[i]); if (i != 0) printf("_"); } printf("\n"); } static void mpb_renorm(mpb_t *r) { while (r->len > 1 && r->tab[r->len - 1] == 0) r->len--; } #ifdef USE_POW5_TABLE static const uint32_t pow5_table[17] = { 0x00000005, 0x00000019, 0x0000007d, 0x00000271, 0x00000c35, 0x00003d09, 0x0001312d, 0x0005f5e1, 0x001dcd65, 0x009502f9, 0x02e90edd, 0x0e8d4a51, 0x48c27395, 0x6bcc41e9, 0x1afd498d, 0x86f26fc1, 0xa2bc2ec5, }; static const uint8_t pow5h_table[4] = { 0x00000001, 0x00000007, 0x00000023, 0x000000b1, }; static const uint32_t pow5_inv_table[13] = { 0x99999999, 0x47ae147a, 0x0624dd2f, 0xa36e2eb1, 0x4f8b588e, 0x0c6f7a0b, 0xad7f29ab, 0x5798ee23, 0x12e0be82, 0xb7cdfd9d, 0x5fd7fe17, 0x19799812, 0xc25c2684, }; #endif /* return a^b */ static uint64_t pow_ui(uint32_t a, uint32_t b) { int i, n_bits; uint64_t r; if (b == 0) return 1; if (b == 1) return a; #ifdef USE_POW5_TABLE if ((a == 5 || a == 10) && b <= 17) { r = pow5_table[b - 1]; if (b >= 14) { r |= (uint64_t)pow5h_table[b - 14] << 32; } if (a == 10) r <<= b; return r; } #endif r = a; n_bits = 32 - clz32(b); for(i = n_bits - 2; i >= 0; i--) { r *= r; if ((b >> i) & 1) r *= a; } return r; } static uint32_t pow_ui_inv(uint32_t *pr_inv, int *pshift, uint32_t a, uint32_t b) { uint32_t r_inv, r; int shift; #ifdef USE_POW5_TABLE if (a == 5 && b >= 1 && b <= 13) { r = pow5_table[b - 1]; shift = clz32(r); r <<= shift; r_inv = pow5_inv_table[b - 1]; } else #endif { r = pow_ui(a, b); shift = clz32(r); r <<= shift; r_inv = udiv1norm_init(r); } *pshift = shift; *pr_inv = r_inv; return r; } enum { JS_RNDN, /* round to nearest, ties to even */ JS_RNDNA, /* round to nearest, ties away from zero */ JS_RNDZ, }; static int mpb_get_bit(const mpb_t *r, int k) { int l; l = (unsigned)k / LIMB_BITS; k = k & (LIMB_BITS - 1); if (l >= r->len) return 0; else return (r->tab[l] >> k) & 1; } /* compute round(r / 2^shift). 'shift' can be negative */ static void mpb_shr_round(mpb_t *r, int shift, int rnd_mode) { int l, i; if (shift == 0) return; if (shift < 0) { shift = -shift; l = (unsigned)shift / LIMB_BITS; shift = shift & (LIMB_BITS - 1); if (shift != 0) { r->tab[r->len] = mp_shl(r->tab, r->tab, r->len, shift, 0); r->len++; mpb_renorm(r); } if (l > 0) { for(i = r->len - 1; i >= 0; i--) r->tab[i + l] = r->tab[i]; for(i = 0; i < l; i++) r->tab[i] = 0; r->len += l; } } else { limb_t bit1, bit2; int k, add_one; switch(rnd_mode) { default: case JS_RNDZ: add_one = 0; break; case JS_RNDN: case JS_RNDNA: bit1 = mpb_get_bit(r, shift - 1); if (bit1) { if (rnd_mode == JS_RNDNA) { bit2 = 1; } else { /* bit2 = oring of all the bits after bit1 */ bit2 = 0; if (shift >= 2) { k = shift - 1; l = (unsigned)k / LIMB_BITS; k = k & (LIMB_BITS - 1); for(i = 0; i < min_int(l, r->len); i++) bit2 |= r->tab[i]; if (l < r->len) bit2 |= r->tab[l] & (((limb_t)1 << k) - 1); } } if (bit2) { add_one = 1; } else { /* round to even */ add_one = mpb_get_bit(r, shift); } } else { add_one = 0; } break; } l = (unsigned)shift / LIMB_BITS; shift = shift & (LIMB_BITS - 1); if (l >= r->len) { r->len = 1; r->tab[0] = add_one; } else { if (l > 0) { r->len -= l; for(i = 0; i < r->len; i++) r->tab[i] = r->tab[i + l]; } if (shift != 0) { mp_shr(r->tab, r->tab, r->len, shift, 0); mpb_renorm(r); } if (add_one) { limb_t a; a = mp_add_ui(r->tab, 1, r->len); if (a) r->tab[r->len++] = a; } } } } /* return -1, 0 or 1 */ static int mpb_cmp(const mpb_t *a, const mpb_t *b) { mp_size_t i; if (a->len < b->len) return -1; else if (a->len > b->len) return 1; for(i = a->len - 1; i >= 0; i--) { if (a->tab[i] != b->tab[i]) { if (a->tab[i] < b->tab[i]) return -1; else return 1; } } return 0; } static void mpb_set_u64(mpb_t *r, uint64_t m) { #if LIMB_BITS == 64 r->tab[0] = m; r->len = 1; #else r->tab[0] = m; r->tab[1] = m >> LIMB_BITS; if (r->tab[1] == 0) r->len = 1; else r->len = 2; #endif } static uint64_t mpb_get_u64(mpb_t *r) { #if LIMB_BITS == 64 return r->tab[0]; #else if (r->len == 1) { return r->tab[0]; } else { return r->tab[0] | ((uint64_t)r->tab[1] << LIMB_BITS); } #endif } /* floor_log2() = position of the first non zero bit or -1 if zero. */ static int mpb_floor_log2(mpb_t *a) { limb_t v; v = a->tab[a->len - 1]; if (v == 0) return -1; else return a->len * LIMB_BITS - 1 - clz32(v); } #define MUL_LOG2_RADIX_BASE_LOG2 24 /* round((1 << MUL_LOG2_RADIX_BASE_LOG2)/log2(i + 2)) */ static const uint32_t mul_log2_radix_table[JS_RADIX_MAX - 1] = { 0x000000, 0xa1849d, 0x000000, 0x6e40d2, 0x6308c9, 0x5b3065, 0x000000, 0x50c24e, 0x4d104d, 0x4a0027, 0x4768ce, 0x452e54, 0x433d00, 0x418677, 0x000000, 0x3ea16b, 0x3d645a, 0x3c43c2, 0x3b3b9a, 0x3a4899, 0x39680b, 0x3897b3, 0x37d5af, 0x372069, 0x367686, 0x35d6df, 0x354072, 0x34b261, 0x342bea, 0x33ac62, 0x000000, 0x32bfd9, 0x3251dd, 0x31e8d6, 0x318465, }; /* return floor(a / log2(radix)) for -2048 <= a <= 2047 */ static int mul_log2_radix(int a, int radix) { int radix_bits, mult; if ((radix & (radix - 1)) == 0) { /* if the radix is a power of two better to do it exactly */ radix_bits = 31 - clz32(radix); if (a < 0) a -= radix_bits - 1; return a / radix_bits; } else { mult = mul_log2_radix_table[radix - 2]; return ((int64_t)a * mult) >> MUL_LOG2_RADIX_BASE_LOG2; } } #if 0 static void build_mul_log2_radix_table(void) { int base, radix, mult, col, base_log2; base_log2 = 24; base = 1 << base_log2; col = 0; for(radix = 2; radix <= 36; radix++) { if ((radix & (radix - 1)) == 0) mult = 0; else mult = lrint((double)base / log2(radix)); printf("0x%06x, ", mult); if (++col == 4) { printf("\n"); col = 0; } } printf("\n"); } static void mul_log2_radix_test(void) { int radix, i, ref, r; for(radix = 2; radix <= 36; radix++) { for(i = -2048; i <= 2047; i++) { ref = (int)floor((double)i / log2(radix)); r = mul_log2_radix(i, radix); if (ref != r) { printf("ERROR: radix=%d i=%d r=%d ref=%d\n", radix, i, r, ref); exit(1); } } } if (0) build_mul_log2_radix_table(); } #endif static void u32toa_len(char *buf, uint32_t n, size_t len) { int digit, i; for(i = len - 1; i >= 0; i--) { digit = n % 10; n = n / 10; buf[i] = digit + '0'; } } /* for power of 2 radixes. len >= 1 */ static void u64toa_bin_len(char *buf, uint64_t n, unsigned int radix_bits, int len) { int digit, i; unsigned int mask; mask = (1 << radix_bits) - 1; for(i = len - 1; i >= 0; i--) { digit = n & mask; n >>= radix_bits; if (digit < 10) digit += '0'; else digit += 'a' - 10; buf[i] = digit; } } /* len >= 1. 2 <= radix <= 36 */ static void limb_to_a(char *buf, limb_t n, unsigned int radix, int len) { int digit, i; if (radix == 10) { /* specific case with constant divisor */ #if LIMB_BITS == 32 u32toa_len(buf, n, len); #else /* XXX: optimize */ for(i = len - 1; i >= 0; i--) { digit = (limb_t)n % 10; n = (limb_t)n / 10; buf[i] = digit + '0'; } #endif } else { for(i = len - 1; i >= 0; i--) { digit = (limb_t)n % radix; n = (limb_t)n / radix; if (digit < 10) digit += '0'; else digit += 'a' - 10; buf[i] = digit; } } } size_t u32toa(char *buf, uint32_t n) { char buf1[10], *q; size_t len; q = buf1 + sizeof(buf1); do { *--q = n % 10 + '0'; n /= 10; } while (n != 0); len = buf1 + sizeof(buf1) - q; memcpy(buf, q, len); return len; } size_t i32toa(char *buf, int32_t n) { if (n >= 0) { return u32toa(buf, n); } else { buf[0] = '-'; return u32toa(buf + 1, -(uint32_t)n) + 1; } } #ifdef USE_FAST_INT size_t u64toa(char *buf, uint64_t n) { if (n < 0x100000000) { return u32toa(buf, n); } else { uint64_t n1; char *q = buf; uint32_t n2; n1 = n / 1000000000; n %= 1000000000; if (n1 >= 0x100000000) { n2 = n1 / 1000000000; n1 = n1 % 1000000000; /* at most two digits */ if (n2 >= 10) { *q++ = n2 / 10 + '0'; n2 %= 10; } *q++ = n2 + '0'; u32toa_len(q, n1, 9); q += 9; } else { q += u32toa(q, n1); } u32toa_len(q, n, 9); q += 9; return q - buf; } } size_t i64toa(char *buf, int64_t n) { if (n >= 0) { return u64toa(buf, n); } else { buf[0] = '-'; return u64toa(buf + 1, -(uint64_t)n) + 1; } } /* XXX: only tested for 1 <= n < 2^53 */ size_t u64toa_radix(char *buf, uint64_t n, unsigned int radix) { int radix_bits, l; if (likely(radix == 10)) return u64toa(buf, n); if ((radix & (radix - 1)) == 0) { radix_bits = 31 - clz32(radix); if (n == 0) l = 1; else l = (64 - clz64(n) + radix_bits - 1) / radix_bits; u64toa_bin_len(buf, n, radix_bits, l); return l; } else { char buf1[41], *q; /* maximum length for radix = 3 */ size_t len; int digit; q = buf1 + sizeof(buf1); do { digit = n % radix; n /= radix; if (digit < 10) digit += '0'; else digit += 'a' - 10; *--q = digit; } while (n != 0); len = buf1 + sizeof(buf1) - q; memcpy(buf, q, len); return len; } } size_t i64toa_radix(char *buf, int64_t n, unsigned int radix) { if (n >= 0) { return u64toa_radix(buf, n, radix); } else { buf[0] = '-'; return u64toa_radix(buf + 1, -(uint64_t)n, radix) + 1; } } #endif /* USE_FAST_INT */ static const uint8_t digits_per_limb_table[JS_RADIX_MAX - 1] = { #if LIMB_BITS == 32 32,20,16,13,12,11,10,10, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, #else 64,40,32,27,24,22,21,20,19,18,17,17,16,16,16,15,15,15,14,14,14,14,13,13,13,13,13,13,13,12,12,12,12,12,12, #endif }; static const uint32_t radix_base_table[JS_RADIX_MAX - 1] = { 0x00000000, 0xcfd41b91, 0x00000000, 0x48c27395, 0x81bf1000, 0x75db9c97, 0x40000000, 0xcfd41b91, 0x3b9aca00, 0x8c8b6d2b, 0x19a10000, 0x309f1021, 0x57f6c100, 0x98c29b81, 0x00000000, 0x18754571, 0x247dbc80, 0x3547667b, 0x4c4b4000, 0x6b5a6e1d, 0x94ace180, 0xcaf18367, 0x0b640000, 0x0e8d4a51, 0x1269ae40, 0x17179149, 0x1cb91000, 0x23744899, 0x2b73a840, 0x34e63b41, 0x40000000, 0x4cfa3cc1, 0x5c13d840, 0x6d91b519, 0x81bf1000, }; /* XXX: remove the table ? */ static uint8_t dtoa_max_digits_table[JS_RADIX_MAX - 1] = { 54, 35, 28, 24, 22, 20, 19, 18, 17, 17, 16, 16, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, }; /* we limit the maximum number of significant digits for atod to about 128 bits of precision for non power of two bases. The only requirement for Javascript is at least 20 digits in base 10. For power of two bases, we do an exact rounding in all the cases. */ static uint8_t atod_max_digits_table[JS_RADIX_MAX - 1] = { 64, 80, 32, 55, 49, 45, 21, 40, 38, 37, 35, 34, 33, 32, 16, 31, 30, 30, 29, 29, 28, 28, 27, 27, 27, 26, 26, 26, 26, 25, 12, 25, 25, 24, 24, }; /* if abs(d) >= B^max_exponent, it is an overflow */ static const int16_t max_exponent[JS_RADIX_MAX - 1] = { 1024, 647, 512, 442, 397, 365, 342, 324, 309, 297, 286, 277, 269, 263, 256, 251, 246, 242, 237, 234, 230, 227, 224, 221, 218, 216, 214, 211, 209, 207, 205, 203, 202, 200, 199, }; /* if abs(d) <= B^min_exponent, it is an underflow */ static const int16_t min_exponent[JS_RADIX_MAX - 1] = { -1075, -679, -538, -463, -416, -383, -359, -340, -324, -311, -300, -291, -283, -276, -269, -263, -258, -254, -249, -245, -242, -238, -235, -232, -229, -227, -224, -222, -220, -217, -215, -214, -212, -210, -208, }; #if 0 void build_tables(void) { int r, j, radix, n, col, i; /* radix_base_table */ for(radix = 2; radix <= 36; radix++) { r = 1; for(j = 0; j < digits_per_limb_table[radix - 2]; j++) { r *= radix; } printf(" 0x%08x,", r); if ((radix % 4) == 1) printf("\n"); } printf("\n"); /* dtoa_max_digits_table */ for(radix = 2; radix <= 36; radix++) { /* Note: over estimated when the radix is a power of two */ printf(" %d,", 1 + (int)ceil(53.0 / log2(radix))); } printf("\n"); /* atod_max_digits_table */ for(radix = 2; radix <= 36; radix++) { if ((radix & (radix - 1)) == 0) { /* 64 bits is more than enough */ n = (int)floor(64.0 / log2(radix)); } else { n = (int)floor(128.0 / log2(radix)); } printf(" %d,", n); } printf("\n"); printf("static const int16_t max_exponent[JS_RADIX_MAX - 1] = {\n"); col = 0; for(radix = 2; radix <= 36; radix++) { printf("%5d, ", (int)ceil(1024 / log2(radix))); if (++col == 8) { col = 0; printf("\n"); } } printf("\n};\n\n"); printf("static const int16_t min_exponent[JS_RADIX_MAX - 1] = {\n"); col = 0; for(radix = 2; radix <= 36; radix++) { printf("%5d, ", (int)floor(-1075 / log2(radix))); if (++col == 8) { col = 0; printf("\n"); } } printf("\n};\n\n"); printf("static const uint32_t pow5_table[16] = {\n"); col = 0; for(i = 2; i <= 17; i++) { r = 1; for(j = 0; j < i; j++) { r *= 5; } printf("0x%08x, ", r); if (++col == 4) { col = 0; printf("\n"); } } printf("\n};\n\n"); /* high part */ printf("static const uint8_t pow5h_table[4] = {\n"); col = 0; for(i = 14; i <= 17; i++) { uint64_t r1; r1 = 1; for(j = 0; j < i; j++) { r1 *= 5; } printf("0x%08x, ", (uint32_t)(r1 >> 32)); if (++col == 4) { col = 0; printf("\n"); } } printf("\n};\n\n"); } #endif /* n_digits >= 1. 0 <= dot_pos <= n_digits. If dot_pos == n_digits, the dot is not displayed. 'a' is modified. */ static int output_digits(char *buf, mpb_t *a, int radix, int n_digits1, int dot_pos) { int n_digits, digits_per_limb, radix_bits, n, len; n_digits = n_digits1; if ((radix & (radix - 1)) == 0) { /* radix = 2^radix_bits */ radix_bits = 31 - clz32(radix); } else { radix_bits = 0; } digits_per_limb = digits_per_limb_table[radix - 2]; if (radix_bits != 0) { for(;;) { n = min_int(n_digits, digits_per_limb); n_digits -= n; u64toa_bin_len(buf + n_digits, a->tab[0], radix_bits, n); if (n_digits == 0) break; mpb_shr_round(a, digits_per_limb * radix_bits, JS_RNDZ); } } else { limb_t r; while (n_digits != 0) { n = min_int(n_digits, digits_per_limb); n_digits -= n; r = mp_div1(a->tab, a->tab, a->len, radix_base_table[radix - 2], 0); mpb_renorm(a); limb_to_a(buf + n_digits, r, radix, n); } } /* add the dot */ len = n_digits1; if (dot_pos != n_digits1) { memmove(buf + dot_pos + 1, buf + dot_pos, n_digits1 - dot_pos); buf[dot_pos] = '.'; len++; } return len; } /* return (a, e_offset) such that a = a * (radix1*2^radix_shift)^f * 2^-e_offset. 'f' can be negative. */ static int mul_pow(mpb_t *a, int radix1, int radix_shift, int f, BOOL is_int, int e) { int e_offset, d, n, n0; e_offset = -f * radix_shift; if (radix1 != 1) { d = digits_per_limb_table[radix1 - 2]; if (f >= 0) { limb_t h, b; b = 0; n0 = 0; while (f != 0) { n = min_int(f, d); if (n != n0) { b = pow_ui(radix1, n); n0 = n; } h = mp_mul1(a->tab, a->tab, a->len, b, 0); if (h != 0) { a->tab[a->len++] = h; } f -= n; } } else { int extra_bits, l, shift; limb_t r, rem, b, b_inv; f = -f; l = (f + d - 1) / d; /* high bound for the number of limbs (XXX: make it better) */ e_offset += l * LIMB_BITS; if (!is_int) { /* at least 'e' bits are needed in the final result for rounding */ extra_bits = max_int(e - mpb_floor_log2(a), 0); } else { /* at least two extra bits are needed in the final result for rounding */ extra_bits = max_int(2 + e - e_offset, 0); } e_offset += extra_bits; mpb_shr_round(a, -(l * LIMB_BITS + extra_bits), JS_RNDZ); b = 0; b_inv = 0; shift = 0; n0 = 0; rem = 0; while (f != 0) { n = min_int(f, d); if (n != n0) { b = pow_ui_inv(&b_inv, &shift, radix1, n); n0 = n; } r = mp_div1norm(a->tab, a->tab, a->len, b, 0, b_inv, shift); rem |= r; mpb_renorm(a); f -= n; } /* if the remainder is non zero, use it for rounding */ a->tab[0] |= (rem != 0); } } return e_offset; } /* tmp1 = round(m*2^e*radix^f). 'tmp0' is a temporary storage */ static void mul_pow_round(mpb_t *tmp1, uint64_t m, int e, int radix1, int radix_shift, int f, int rnd_mode) { int e_offset; mpb_set_u64(tmp1, m); e_offset = mul_pow(tmp1, radix1, radix_shift, f, TRUE, e); mpb_shr_round(tmp1, -e + e_offset, rnd_mode); } /* return round(a*2^e_offset) rounded as a float64. 'a' is modified */ static uint64_t round_to_d(int *pe, mpb_t *a, int e_offset, int rnd_mode) { int e; uint64_t m; if (a->tab[0] == 0 && a->len == 1) { /* zero result */ m = 0; e = 0; /* don't care */ } else { int prec, prec1, e_min; e = mpb_floor_log2(a) + 1 - e_offset; prec1 = 53; e_min = -1021; if (e < e_min) { /* subnormal result or zero */ prec = prec1 - (e_min - e); } else { prec = prec1; } mpb_shr_round(a, e + e_offset - prec, rnd_mode); m = mpb_get_u64(a); m <<= (53 - prec); /* mantissa overflow due to rounding */ if (m >= (uint64_t)1 << 53) { m >>= 1; e++; } } *pe = e; return m; } /* return (m, e) such that m*2^(e-53) = round(a * radix^f) with 2^52 <= m < 2^53 or m = 0. 'a' is modified. */ static uint64_t mul_pow_round_to_d(int *pe, mpb_t *a, int radix1, int radix_shift, int f, int rnd_mode) { int e_offset; e_offset = mul_pow(a, radix1, radix_shift, f, FALSE, 55); return round_to_d(pe, a, e_offset, rnd_mode); } #ifdef JS_DTOA_DUMP_STATS static int out_len_count[17]; void js_dtoa_dump_stats(void) { int i, sum; sum = 0; for(i = 0; i < 17; i++) sum += out_len_count[i]; for(i = 0; i < 17; i++) { printf("%2d %8d %5.2f%%\n", i + 1, out_len_count[i], (double)out_len_count[i] / sum * 100); } } #endif /* return a maximum bound of the string length. The bound depends on 'd' only if format = JS_DTOA_FORMAT_FRAC or if JS_DTOA_EXP_DISABLED is enabled. */ int js_dtoa_max_len(double d, int radix, int n_digits, int flags) { int fmt = flags & JS_DTOA_FORMAT_MASK; int n, e; uint64_t a; if (fmt != JS_DTOA_FORMAT_FRAC) { if (fmt == JS_DTOA_FORMAT_FREE) { n = dtoa_max_digits_table[radix - 2]; } else { n = n_digits; } if ((flags & JS_DTOA_EXP_MASK) == JS_DTOA_EXP_DISABLED) { /* no exponential */ a = float64_as_uint64(d); e = (a >> 52) & 0x7ff; if (e == 0x7ff) { /* NaN, Infinity */ n = 0; } else { e -= 1023; /* XXX: adjust */ n += 10 + abs(mul_log2_radix(e - 1, radix)); } } else { /* extra: sign, 1 dot and exponent "e-1000" */ n += 1 + 1 + 6; } } else { a = float64_as_uint64(d); e = (a >> 52) & 0x7ff; if (e == 0x7ff) { /* NaN, Infinity */ n = 0; } else { /* high bound for the integer part */ e -= 1023; /* x < 2^(e + 1) */ if (e < 0) { n = 1; } else { n = 2 + mul_log2_radix(e - 1, radix); } /* sign, extra digit, 1 dot */ n += 1 + 1 + 1 + n_digits; } } return max_int(n, 9); /* also include NaN and [-]Infinity */ } #if defined(__SANITIZE_ADDRESS__) && 0 static void *dtoa_malloc(uint64_t **pptr, size_t size) { return malloc(size); } static void dtoa_free(void *ptr) { free(ptr); } #else static void *dtoa_malloc(uint64_t **pptr, size_t size) { void *ret; ret = *pptr; *pptr += (size + 7) / 8; return ret; } static void dtoa_free(void *ptr) { } #endif /* return the length */ int js_dtoa(char *buf, double d, int radix, int n_digits, int flags, JSDTOATempMem *tmp_mem) { uint64_t a, m, *mptr = tmp_mem->mem; int e, sgn, l, E, P, i, E_max, radix1, radix_shift; char *q; mpb_t *tmp1, *mant_max; int fmt = flags & JS_DTOA_FORMAT_MASK; tmp1 = dtoa_malloc(&mptr, sizeof(mpb_t) + sizeof(limb_t) * DBIGNUM_LEN_MAX); mant_max = dtoa_malloc(&mptr, sizeof(mpb_t) + sizeof(limb_t) * MANT_LEN_MAX); assert((mptr - tmp_mem->mem) <= sizeof(JSDTOATempMem) / sizeof(mptr[0])); radix_shift = ctz32(radix); radix1 = radix >> radix_shift; a = float64_as_uint64(d); sgn = a >> 63; e = (a >> 52) & 0x7ff; m = a & (((uint64_t)1 << 52) - 1); q = buf; if (e == 0x7ff) { if (m == 0) { if (sgn) *q++ = '-'; memcpy(q, "Infinity", 8); q += 8; } else { memcpy(q, "NaN", 3); q += 3; } goto done; } else if (e == 0) { if (m == 0) { tmp1->len = 1; tmp1->tab[0] = 0; E = 1; if (fmt == JS_DTOA_FORMAT_FREE) P = 1; else if (fmt == JS_DTOA_FORMAT_FRAC) P = n_digits + 1; else P = n_digits; /* "-0" is displayed as "0" if JS_DTOA_MINUS_ZERO is not present */ if (sgn && (flags & JS_DTOA_MINUS_ZERO)) *q++ = '-'; goto output; } /* denormal number: convert to a normal number */ l = clz64(m) - 11; e -= l - 1; m <<= l; } else { m |= (uint64_t)1 << 52; } if (sgn) *q++ = '-'; /* remove the bias */ e -= 1022; /* d = 2^(e-53)*m */ // printf("m=0x%016" PRIx64 " e=%d\n", m, e); #ifdef USE_FAST_INT if (fmt == JS_DTOA_FORMAT_FREE && e >= 1 && e <= 53 && (m & (((uint64_t)1 << (53 - e)) - 1)) == 0 && (flags & JS_DTOA_EXP_MASK) != JS_DTOA_EXP_ENABLED) { m >>= 53 - e; /* 'm' is never zero */ q += u64toa_radix(q, m, radix); goto done; } #endif /* this choice of E implies F=round(x*B^(P-E) is such as: B^(P-1) <= F < 2.B^P. */ E = 1 + mul_log2_radix(e - 1, radix); if (fmt == JS_DTOA_FORMAT_FREE) { int P_max, E0, e1, E_found, P_found; uint64_t m1, mant_found, mant, mant_max1; /* P_max is guarranteed to work by construction */ P_max = dtoa_max_digits_table[radix - 2]; E0 = E; E_found = 0; P_found = 0; mant_found = 0; /* find the minimum number of digits by successive tries */ P = P_max; /* P_max is guarateed to work */ for(;;) { /* mant_max always fits on 64 bits */ mant_max1 = pow_ui(radix, P); /* compute the mantissa in base B */ E = E0; for(;;) { /* XXX: add inexact flag */ mul_pow_round(tmp1, m, e - 53, radix1, radix_shift, P - E, JS_RNDN); mant = mpb_get_u64(tmp1); if (mant < mant_max1) break; E++; /* at most one iteration is possible */ } /* remove useless trailing zero digits */ while ((mant % radix) == 0) { mant /= radix; P--; } /* garanteed to work for P = P_max */ if (P_found == 0) goto prec_found; /* convert back to base 2 */ mpb_set_u64(tmp1, mant); m1 = mul_pow_round_to_d(&e1, tmp1, radix1, radix_shift, E - P, JS_RNDN); // printf("P=%2d: m=0x%016" PRIx64 " e=%d m1=0x%016" PRIx64 " e1=%d\n", P, m, e, m1, e1); /* Note: (m, e) is never zero here, so the exponent for m1 = 0 does not matter */ if (m1 == m && e1 == e) { prec_found: P_found = P; E_found = E; mant_found = mant; if (P == 1) break; P--; /* try lower exponent */ } else { break; } } P = P_found; E = E_found; mpb_set_u64(tmp1, mant_found); #ifdef JS_DTOA_DUMP_STATS if (radix == 10) { out_len_count[P - 1]++; } #endif } else if (fmt == JS_DTOA_FORMAT_FRAC) { int len; assert(n_digits >= 0 && n_digits <= JS_DTOA_MAX_DIGITS); /* P = max_int(E, 1) + n_digits; */ /* frac is rounded using RNDNA */ mul_pow_round(tmp1, m, e - 53, radix1, radix_shift, n_digits, JS_RNDNA); /* we add one extra digit on the left and remove it if needed to avoid testing if the result is < radix^P */ len = output_digits(q, tmp1, radix, max_int(E + 1, 1) + n_digits, max_int(E + 1, 1)); if (q[0] == '0' && len >= 2 && q[1] != '.') { len--; memmove(q, q + 1, len); } q += len; goto done; } else { int pow_shift; assert(n_digits >= 1 && n_digits <= JS_DTOA_MAX_DIGITS); P = n_digits; /* mant_max = radix^P */ mant_max->len = 1; mant_max->tab[0] = 1; pow_shift = mul_pow(mant_max, radix1, radix_shift, P, FALSE, 0); mpb_shr_round(mant_max, pow_shift, JS_RNDZ); for(;;) { /* fixed and frac are rounded using RNDNA */ mul_pow_round(tmp1, m, e - 53, radix1, radix_shift, P - E, JS_RNDNA); if (mpb_cmp(tmp1, mant_max) < 0) break; E++; /* at most one iteration is possible */ } } output: if (fmt == JS_DTOA_FORMAT_FIXED) E_max = n_digits; else E_max = dtoa_max_digits_table[radix - 2] + 4; if ((flags & JS_DTOA_EXP_MASK) == JS_DTOA_EXP_ENABLED || ((flags & JS_DTOA_EXP_MASK) == JS_DTOA_EXP_AUTO && (E <= -6 || E > E_max))) { q += output_digits(q, tmp1, radix, P, 1); E--; if (radix == 10) { *q++ = 'e'; } else if (radix1 == 1 && radix_shift <= 4) { E *= radix_shift; *q++ = 'p'; } else { *q++ = '@'; } if (E < 0) { *q++ = '-'; E = -E; } else { *q++ = '+'; } q += u32toa(q, E); } else if (E <= 0) { *q++ = '0'; *q++ = '.'; for(i = 0; i < -E; i++) *q++ = '0'; q += output_digits(q, tmp1, radix, P, P); } else { q += output_digits(q, tmp1, radix, P, min_int(P, E)); for(i = 0; i < E - P; i++) *q++ = '0'; } done: *q = '\0'; dtoa_free(mant_max); dtoa_free(tmp1); return q - buf; } static inline int to_digit(int c) { if (c >= '0' && c <= '9') return c - '0'; else if (c >= 'A' && c <= 'Z') return c - 'A' + 10; else if (c >= 'a' && c <= 'z') return c - 'a' + 10; else return 36; } /* r = r * radix_base + a. radix_base = 0 means radix_base = 2^32 */ static void mpb_mul1_base(mpb_t *r, limb_t radix_base, limb_t a) { int i; if (r->tab[0] == 0 && r->len == 1) { r->tab[0] = a; } else { if (radix_base == 0) { for(i = r->len; i >= 0; i--) { r->tab[i + 1] = r->tab[i]; } r->tab[0] = a; } else { r->tab[r->len] = mp_mul1(r->tab, r->tab, r->len, radix_base, a); } r->len++; mpb_renorm(r); } } /* XXX: add fast path for small integers */ double js_atod(const char *str, const char **pnext, int radix, int flags, JSATODTempMem *tmp_mem) { uint64_t *mptr = tmp_mem->mem; const char *p, *p_start; limb_t cur_limb, radix_base, extra_digits; int is_neg, digit_count, limb_digit_count, digits_per_limb, sep, radix1, radix_shift; int radix_bits, expn, e, max_digits, expn_offset, dot_pos, sig_pos, pos; mpb_t *tmp0; double dval; BOOL is_bin_exp, is_zero, expn_overflow; uint64_t m, a; tmp0 = dtoa_malloc(&mptr, sizeof(mpb_t) + sizeof(limb_t) * DBIGNUM_LEN_MAX); assert((mptr - tmp_mem->mem) <= sizeof(JSATODTempMem) / sizeof(mptr[0])); /* optional separator between digits */ sep = (flags & JS_ATOD_ACCEPT_UNDERSCORES) ? '_' : 256; p = str; is_neg = 0; if (p[0] == '+') { p++; p_start = p; } else if (p[0] == '-') { is_neg = 1; p++; p_start = p; } else { p_start = p; } if (p[0] == '0') { if ((p[1] == 'x' || p[1] == 'X') && (radix == 0 || radix == 16)) { p += 2; radix = 16; } else if ((p[1] == 'o' || p[1] == 'O') && radix == 0 && (flags & JS_ATOD_ACCEPT_BIN_OCT)) { p += 2; radix = 8; } else if ((p[1] == 'b' || p[1] == 'B') && radix == 0 && (flags & JS_ATOD_ACCEPT_BIN_OCT)) { p += 2; radix = 2; } else if ((p[1] >= '0' && p[1] <= '9') && radix == 0 && (flags & JS_ATOD_ACCEPT_LEGACY_OCTAL)) { int i; sep = 256; for (i = 1; (p[i] >= '0' && p[i] <= '7'); i++) continue; if (p[i] == '8' || p[i] == '9') goto no_prefix; p += 1; radix = 8; } else { goto no_prefix; } /* there must be a digit after the prefix */ if (to_digit((uint8_t)*p) >= radix) goto fail; no_prefix: ; } else { if (!(flags & JS_ATOD_INT_ONLY) && strstart(p, "Infinity", &p)) goto overflow; } if (radix == 0) radix = 10; cur_limb = 0; expn_offset = 0; digit_count = 0; limb_digit_count = 0; max_digits = atod_max_digits_table[radix - 2]; digits_per_limb = digits_per_limb_table[radix - 2]; radix_base = radix_base_table[radix - 2]; radix_shift = ctz32(radix); radix1 = radix >> radix_shift; if (radix1 == 1) { /* radix = 2^radix_bits */ radix_bits = radix_shift; } else { radix_bits = 0; } tmp0->len = 1; tmp0->tab[0] = 0; extra_digits = 0; pos = 0; dot_pos = -1; /* skip leading zeros */ for(;;) { if (*p == '.' && (p > p_start || to_digit(p[1]) < radix) && !(flags & JS_ATOD_INT_ONLY)) { if (*p == sep) goto fail; if (dot_pos >= 0) break; dot_pos = pos; p++; } if (*p == sep && p > p_start && p[1] == '0') p++; if (*p != '0') break; p++; pos++; } sig_pos = pos; for(;;) { limb_t c; if (*p == '.' && (p > p_start || to_digit(p[1]) < radix) && !(flags & JS_ATOD_INT_ONLY)) { if (*p == sep) goto fail; if (dot_pos >= 0) break; dot_pos = pos; p++; } if (*p == sep && p > p_start && to_digit(p[1]) < radix) p++; c = to_digit(*p); if (c >= radix) break; p++; pos++; if (digit_count < max_digits) { /* XXX: could be faster when radix_bits != 0 */ cur_limb = cur_limb * radix + c; limb_digit_count++; if (limb_digit_count == digits_per_limb) { mpb_mul1_base(tmp0, radix_base, cur_limb); cur_limb = 0; limb_digit_count = 0; } digit_count++; } else { extra_digits |= c; } } if (limb_digit_count != 0) { mpb_mul1_base(tmp0, pow_ui(radix, limb_digit_count), cur_limb); } if (digit_count == 0) { is_zero = TRUE; expn_offset = 0; } else { is_zero = FALSE; if (dot_pos < 0) dot_pos = pos; expn_offset = sig_pos + digit_count - dot_pos; } /* Use the extra digits for rounding if the base is a power of two. Otherwise they are just truncated. */ if (radix_bits != 0 && extra_digits != 0) { tmp0->tab[0] |= 1; } /* parse the exponent, if any */ expn = 0; expn_overflow = FALSE; is_bin_exp = FALSE; if (!(flags & JS_ATOD_INT_ONLY) && ((radix == 10 && (*p == 'e' || *p == 'E')) || (radix != 10 && (*p == '@' || (radix_bits >= 1 && radix_bits <= 4 && (*p == 'p' || *p == 'P'))))) && p > p_start) { BOOL exp_is_neg; int c; const char *exp_start = p; is_bin_exp = (*p == 'p' || *p == 'P'); p++; exp_is_neg = 0; if (*p == '+') { p++; } else if (*p == '-') { exp_is_neg = 1; p++; } c = to_digit(*p); if (c >= 10) { p = exp_start; goto exp_backtrack; } expn = c; p++; for(;;) { if (*p == sep && to_digit(p[1]) < 10) p++; c = to_digit(*p); if (c >= 10) break; if (!expn_overflow) { if (unlikely(expn > ((INT32_MAX - 2 - 9) / 10))) { expn_overflow = TRUE; } else { expn = expn * 10 + c; } } p++; } if (exp_is_neg) expn = -expn; /* if zero result, the exponent can be arbitrarily large */ if (!is_zero && expn_overflow) { if (exp_is_neg) a = 0; else a = (uint64_t)0x7ff << 52; /* infinity */ goto done; } } exp_backtrack: if (p == p_start) goto fail; if (is_zero) { a = 0; } else { int expn1; if (radix_bits != 0) { if (!is_bin_exp) expn *= radix_bits; expn -= expn_offset * radix_bits; expn1 = expn + digit_count * radix_bits; if (expn1 >= 1024 + radix_bits) goto overflow; else if (expn1 <= -1075) goto underflow; m = round_to_d(&e, tmp0, -expn, JS_RNDN); } else { expn -= expn_offset; expn1 = expn + digit_count; if (expn1 >= max_exponent[radix - 2] + 1) goto overflow; else if (expn1 <= min_exponent[radix - 2]) goto underflow; m = mul_pow_round_to_d(&e, tmp0, radix1, radix_shift, expn, JS_RNDN); } if (m == 0) { underflow: a = 0; } else if (e > 1024) { overflow: /* overflow */ a = (uint64_t)0x7ff << 52; } else if (e < -1073) { /* underflow */ /* XXX: check rounding */ a = 0; } else if (e < -1021) { /* subnormal */ a = m >> (-e - 1021); } else { a = ((uint64_t)(e + 1022) << 52) | (m & (((uint64_t)1 << 52) - 1)); } } done: a |= (uint64_t)is_neg << 63; dval = uint64_as_float64(a); done1: if (pnext) *pnext = p; dtoa_free(tmp0); return dval; fail: dval = NAN; goto done1; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/qjs/dtoa.h�����������������������������������������������������0000664�0000000�0000000�00000006352�15202323131�0021305�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Tiny float64 printing and parsing library * * Copyright (c) 2024 Fabrice Bellard * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ //#define JS_DTOA_DUMP_STATS /* maximum number of digits for fixed and frac formats */ #define JS_DTOA_MAX_DIGITS 101 /* radix != 10 is only supported with flags = JS_DTOA_FORMAT_FREE */ /* use as many digits as necessary */ #define JS_DTOA_FORMAT_FREE (0 << 0) /* use n_digits significant digits (1 <= n_digits <= JS_DTOA_MAX_DIGITS) */ #define JS_DTOA_FORMAT_FIXED (1 << 0) /* force fractional format: [-]dd.dd with n_digits fractional digits. 0 <= n_digits <= JS_DTOA_MAX_DIGITS */ #define JS_DTOA_FORMAT_FRAC (2 << 0) #define JS_DTOA_FORMAT_MASK (3 << 0) /* select exponential notation either in fixed or free format */ #define JS_DTOA_EXP_AUTO (0 << 2) #define JS_DTOA_EXP_ENABLED (1 << 2) #define JS_DTOA_EXP_DISABLED (2 << 2) #define JS_DTOA_EXP_MASK (3 << 2) #define JS_DTOA_MINUS_ZERO (1 << 4) /* show the minus sign for -0 */ /* only accepts integers (no dot, no exponent) */ #define JS_ATOD_INT_ONLY (1 << 0) /* accept Oo and Ob prefixes in addition to 0x prefix if radix = 0 */ #define JS_ATOD_ACCEPT_BIN_OCT (1 << 1) /* accept O prefix as octal if radix == 0 and properly formed (Annex B) */ #define JS_ATOD_ACCEPT_LEGACY_OCTAL (1 << 2) /* accept _ between digits as a digit separator */ #define JS_ATOD_ACCEPT_UNDERSCORES (1 << 3) typedef struct { uint64_t mem[37]; } JSDTOATempMem; typedef struct { uint64_t mem[27]; } JSATODTempMem; /* return a maximum bound of the string length */ int js_dtoa_max_len(double d, int radix, int n_digits, int flags); /* return the string length */ int js_dtoa(char *buf, double d, int radix, int n_digits, int flags, JSDTOATempMem *tmp_mem); double js_atod(const char *str, const char **pnext, int radix, int flags, JSATODTempMem *tmp_mem); #ifdef JS_DTOA_DUMP_STATS void js_dtoa_dump_stats(void); #endif /* additional exported functions */ size_t u32toa(char *buf, uint32_t n); size_t i32toa(char *buf, int32_t n); size_t u64toa(char *buf, uint64_t n); size_t i64toa(char *buf, int64_t n); size_t u64toa_radix(char *buf, uint64_t n, unsigned int radix); size_t i64toa_radix(char *buf, int64_t n, unsigned int radix); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/qjs/libregexp-opcode.h�����������������������������������������0000664�0000000�0000000�00000005507�15202323131�0023607�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Regular Expression Engine * * Copyright (c) 2017-2018 Fabrice Bellard * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #ifdef DEF DEF(invalid, 1) /* never used */ DEF(char, 3) DEF(char_i, 3) DEF(char32, 5) DEF(char32_i, 5) DEF(dot, 1) DEF(any, 1) /* same as dot but match any character including line terminator */ DEF(space, 1) DEF(not_space, 1) /* must come after */ DEF(line_start, 1) DEF(line_start_m, 1) DEF(line_end, 1) DEF(line_end_m, 1) DEF(goto, 5) DEF(split_goto_first, 5) DEF(split_next_first, 5) DEF(match, 1) DEF(lookahead_match, 1) DEF(negative_lookahead_match, 1) /* must come after */ DEF(save_start, 2) /* save start position */ DEF(save_end, 2) /* save end position, must come after saved_start */ DEF(save_reset, 3) /* reset save positions */ DEF(loop, 6) /* decrement the top the stack and goto if != 0 */ DEF(loop_split_goto_first, 10) /* loop and then split */ DEF(loop_split_next_first, 10) DEF(loop_check_adv_split_goto_first, 10) /* loop and then check advance and split */ DEF(loop_check_adv_split_next_first, 10) DEF(set_i32, 6) /* store the immediate value to a register */ DEF(word_boundary, 1) DEF(word_boundary_i, 1) DEF(not_word_boundary, 1) DEF(not_word_boundary_i, 1) DEF(back_reference, 2) /* variable length */ DEF(back_reference_i, 2) /* must come after */ DEF(backward_back_reference, 2) /* must come after */ DEF(backward_back_reference_i, 2) /* must come after */ DEF(range, 3) /* variable length */ DEF(range_i, 3) /* variable length */ DEF(range32, 3) /* variable length */ DEF(range32_i, 3) /* variable length */ DEF(lookahead, 5) DEF(negative_lookahead, 5) /* must come after */ DEF(set_char_pos, 2) /* store the character position to a register */ DEF(check_advance, 2) /* check that the register is different from the character position */ DEF(prev, 1) /* go to the previous char */ #endif /* DEF */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/qjs/libregexp.c������������������������������������������������0000664�0000000�0000000�00000337743�15202323131�0022345�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Regular Expression Engine * * Copyright (c) 2017-2018 Fabrice Bellard * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include <stdlib.h> #include <stdio.h> #include <stdarg.h> #include <inttypes.h> #include <string.h> #include <assert.h> #include "cutils.h" #include "libregexp.h" #include "libunicode.h" /* TODO: - remove REOP_char_i and REOP_range_i by precomputing the case folding. - add specific opcodes for simple unicode property tests so that the generated bytecode is smaller. - Add a lock step execution mode (=linear time execution guaranteed) when the regular expression is "simple" i.e. no backreference nor complicated lookahead. The opcodes are designed for this execution model. */ #if defined(TEST) #define DUMP_REOP #endif //#define DUMP_REOP //#define DUMP_EXEC typedef enum { #define DEF(id, size) REOP_ ## id, #include "libregexp-opcode.h" #undef DEF REOP_COUNT, } REOPCodeEnum; #define CAPTURE_COUNT_MAX 255 #define REGISTER_COUNT_MAX 255 /* must be large enough to have a negligible runtime cost and small enough to call the interrupt callback often. */ #define INTERRUPT_COUNTER_INIT 10000 /* unicode code points */ #define CP_LS 0x2028 #define CP_PS 0x2029 #define TMP_BUF_SIZE 128 typedef struct { DynBuf byte_code; const uint8_t *buf_ptr; const uint8_t *buf_end; const uint8_t *buf_start; int re_flags; BOOL is_unicode; BOOL unicode_sets; /* if set, is_unicode is also set */ BOOL ignore_case; BOOL multi_line; BOOL dotall; uint8_t group_name_scope; int capture_count; int total_capture_count; /* -1 = not computed yet */ int has_named_captures; /* -1 = don't know, 0 = no, 1 = yes */ void *opaque; DynBuf group_names; union { char error_msg[TMP_BUF_SIZE]; char tmp_buf[TMP_BUF_SIZE]; } u; } REParseState; typedef struct { #ifdef DUMP_REOP const char *name; #endif uint8_t size; } REOpCode; static const REOpCode reopcode_info[REOP_COUNT] = { #ifdef DUMP_REOP #define DEF(id, size) { #id, size }, #else #define DEF(id, size) { size }, #endif #include "libregexp-opcode.h" #undef DEF }; #define RE_HEADER_FLAGS 0 #define RE_HEADER_CAPTURE_COUNT 2 #define RE_HEADER_REGISTER_COUNT 3 #define RE_HEADER_BYTECODE_LEN 4 #define RE_HEADER_LEN 8 static inline int is_digit(int c) { return c >= '0' && c <= '9'; } /* insert 'len' bytes at position 'pos'. Return < 0 if error. */ static int dbuf_insert(DynBuf *s, int pos, int len) { if (dbuf_claim(s, len)) return -1; memmove(s->buf + pos + len, s->buf + pos, s->size - pos); s->size += len; return 0; } typedef struct REString { struct REString *next; uint32_t hash; uint32_t len; uint32_t buf[]; } REString; typedef struct { /* the string list is the union of 'char_range' and of the strings in hash_table[]. The strings in hash_table[] have a length != 1. */ CharRange cr; uint32_t n_strings; uint32_t hash_size; int hash_bits; REString **hash_table; } REStringList; static uint32_t re_string_hash(int len, const uint32_t *buf) { int i; uint32_t h; h = 1; for(i = 0; i < len; i++) h = h * 263 + buf[i]; return h * 0x61C88647; } static void re_string_list_init(REParseState *s1, REStringList *s) { cr_init(&s->cr, s1->opaque, lre_realloc); s->n_strings = 0; s->hash_size = 0; s->hash_bits = 0; s->hash_table = NULL; } static void re_string_list_free(REStringList *s) { REString *p, *p_next; int i; for(i = 0; i < s->hash_size; i++) { for(p = s->hash_table[i]; p != NULL; p = p_next) { p_next = p->next; lre_realloc(s->cr.mem_opaque, p, 0); } } lre_realloc(s->cr.mem_opaque, s->hash_table, 0); cr_free(&s->cr); } static void lre_print_char(int c, BOOL is_range) { if (c == '\'' || c == '\\' || (is_range && (c == '-' || c == ']'))) { printf("\\%c", c); } else if (c >= ' ' && c <= 126) { printf("%c", c); } else { printf("\\u{%04x}", c); } } static __maybe_unused void re_string_list_dump(const char *str, const REStringList *s) { REString *p; const CharRange *cr; int i, j, k; printf("%s:\n", str); printf(" ranges: ["); cr = &s->cr; for(i = 0; i < cr->len; i += 2) { lre_print_char(cr->points[i], TRUE); if (cr->points[i] != cr->points[i + 1] - 1) { printf("-"); lre_print_char(cr->points[i + 1] - 1, TRUE); } } printf("]\n"); j = 0; for(i = 0; i < s->hash_size; i++) { for(p = s->hash_table[i]; p != NULL; p = p->next) { printf(" %d/%d: '", j, s->n_strings); for(k = 0; k < p->len; k++) { lre_print_char(p->buf[k], FALSE); } printf("'\n"); j++; } } } static int re_string_find2(REStringList *s, int len, const uint32_t *buf, uint32_t h0, BOOL add_flag) { uint32_t h = 0; /* avoid warning */ REString *p; if (s->n_strings != 0) { h = h0 >> (32 - s->hash_bits); for(p = s->hash_table[h]; p != NULL; p = p->next) { if (p->hash == h0 && p->len == len && !memcmp(p->buf, buf, len * sizeof(buf[0]))) { return 1; } } } /* not found */ if (!add_flag) return 0; /* increase the size of the hash table if needed */ if (unlikely((s->n_strings + 1) > s->hash_size)) { REString **new_hash_table, *p_next; int new_hash_bits, i; uint32_t new_hash_size; new_hash_bits = max_int(s->hash_bits + 1, 4); new_hash_size = 1 << new_hash_bits; new_hash_table = lre_realloc(s->cr.mem_opaque, NULL, sizeof(new_hash_table[0]) * new_hash_size); if (!new_hash_table) return -1; memset(new_hash_table, 0, sizeof(new_hash_table[0]) * new_hash_size); for(i = 0; i < s->hash_size; i++) { for(p = s->hash_table[i]; p != NULL; p = p_next) { p_next = p->next; h = p->hash >> (32 - new_hash_bits); p->next = new_hash_table[h]; new_hash_table[h] = p; } } lre_realloc(s->cr.mem_opaque, s->hash_table, 0); s->hash_bits = new_hash_bits; s->hash_size = new_hash_size; s->hash_table = new_hash_table; h = h0 >> (32 - s->hash_bits); } p = lre_realloc(s->cr.mem_opaque, NULL, sizeof(REString) + len * sizeof(buf[0])); if (!p) return -1; p->next = s->hash_table[h]; s->hash_table[h] = p; s->n_strings++; p->hash = h0; p->len = len; memcpy(p->buf, buf, sizeof(buf[0]) * len); return 1; } static int re_string_find(REStringList *s, int len, const uint32_t *buf, BOOL add_flag) { uint32_t h0; h0 = re_string_hash(len, buf); return re_string_find2(s, len, buf, h0, add_flag); } /* return -1 if memory error, 0 if OK */ static int re_string_add(REStringList *s, int len, const uint32_t *buf) { if (len == 1) { return cr_union_interval(&s->cr, buf[0], buf[0]); } if (re_string_find(s, len, buf, TRUE) < 0) return -1; return 0; } /* a = a op b */ static int re_string_list_op(REStringList *a, REStringList *b, int op) { int i, ret; REString *p, **pp; if (cr_op1(&a->cr, b->cr.points, b->cr.len, op)) return -1; switch(op) { case CR_OP_UNION: if (b->n_strings != 0) { for(i = 0; i < b->hash_size; i++) { for(p = b->hash_table[i]; p != NULL; p = p->next) { if (re_string_find2(a, p->len, p->buf, p->hash, TRUE) < 0) return -1; } } } break; case CR_OP_INTER: case CR_OP_SUB: for(i = 0; i < a->hash_size; i++) { pp = &a->hash_table[i]; for(;;) { p = *pp; if (p == NULL) break; ret = re_string_find2(b, p->len, p->buf, p->hash, FALSE); if (op == CR_OP_SUB) ret = !ret; if (!ret) { /* remove it */ *pp = p->next; a->n_strings--; lre_realloc(a->cr.mem_opaque, p, 0); } else { /* keep it */ pp = &p->next; } } } break; default: abort(); } return 0; } static int re_string_list_canonicalize(REParseState *s1, REStringList *s, BOOL is_unicode) { if (cr_regexp_canonicalize(&s->cr, is_unicode)) return -1; if (s->n_strings != 0) { REStringList a_s, *a = &a_s; int i, j; REString *p; /* XXX: simplify */ re_string_list_init(s1, a); a->n_strings = s->n_strings; a->hash_size = s->hash_size; a->hash_bits = s->hash_bits; a->hash_table = s->hash_table; s->n_strings = 0; s->hash_size = 0; s->hash_bits = 0; s->hash_table = NULL; for(i = 0; i < a->hash_size; i++) { for(p = a->hash_table[i]; p != NULL; p = p->next) { for(j = 0; j < p->len; j++) { p->buf[j] = lre_canonicalize(p->buf[j], is_unicode); } if (re_string_add(s, p->len, p->buf)) { re_string_list_free(a); return -1; } } } re_string_list_free(a); } return 0; } static const uint16_t char_range_d[] = { 1, 0x0030, 0x0039 + 1, }; /* code point ranges for Zs,Zl or Zp property */ static const uint16_t char_range_s[] = { 10, 0x0009, 0x000D + 1, 0x0020, 0x0020 + 1, 0x00A0, 0x00A0 + 1, 0x1680, 0x1680 + 1, 0x2000, 0x200A + 1, /* 2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;; */ /* 2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;; */ 0x2028, 0x2029 + 1, 0x202F, 0x202F + 1, 0x205F, 0x205F + 1, 0x3000, 0x3000 + 1, /* FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;; */ 0xFEFF, 0xFEFF + 1, }; static const uint16_t char_range_w[] = { 4, 0x0030, 0x0039 + 1, 0x0041, 0x005A + 1, 0x005F, 0x005F + 1, 0x0061, 0x007A + 1, }; #define CLASS_RANGE_BASE 0x40000000 typedef enum { CHAR_RANGE_d, CHAR_RANGE_D, CHAR_RANGE_s, CHAR_RANGE_S, CHAR_RANGE_w, CHAR_RANGE_W, } CharRangeEnum; static const uint16_t * const char_range_table[] = { char_range_d, char_range_s, char_range_w, }; static int cr_init_char_range(REParseState *s, REStringList *cr, uint32_t c) { BOOL invert; const uint16_t *c_pt; int len, i; invert = c & 1; c_pt = char_range_table[c >> 1]; len = *c_pt++; re_string_list_init(s, cr); for(i = 0; i < len * 2; i++) { if (cr_add_point(&cr->cr, c_pt[i])) goto fail; } if (invert) { if (cr_invert(&cr->cr)) goto fail; } return 0; fail: re_string_list_free(cr); return -1; } #ifdef DUMP_REOP static __maybe_unused void lre_dump_bytecode(const uint8_t *buf, int buf_len) { int pos, len, opcode, bc_len, re_flags, i; uint32_t val, val2; assert(buf_len >= RE_HEADER_LEN); re_flags = lre_get_flags(buf); bc_len = get_u32(buf + RE_HEADER_BYTECODE_LEN); assert(bc_len + RE_HEADER_LEN <= buf_len); printf("flags: 0x%x capture_count=%d reg_count=%d\n", re_flags, buf[RE_HEADER_CAPTURE_COUNT], buf[RE_HEADER_REGISTER_COUNT]); if (re_flags & LRE_FLAG_NAMED_GROUPS) { const char *p; p = (char *)buf + RE_HEADER_LEN + bc_len; printf("named groups: "); for(i = 1; i < buf[RE_HEADER_CAPTURE_COUNT]; i++) { if (i != 1) printf(","); printf("<%s>", p); p += strlen(p) + LRE_GROUP_NAME_TRAILER_LEN; } printf("\n"); assert(p == (char *)(buf + buf_len)); } printf("bytecode_len=%d\n", bc_len); buf += RE_HEADER_LEN; pos = 0; while (pos < bc_len) { printf("%5u: ", pos); opcode = buf[pos]; len = reopcode_info[opcode].size; if (opcode >= REOP_COUNT) { printf(" invalid opcode=0x%02x\n", opcode); break; } if ((pos + len) > bc_len) { printf(" buffer overflow (opcode=0x%02x)\n", opcode); break; } printf("%s", reopcode_info[opcode].name); switch(opcode) { case REOP_char: case REOP_char_i: val = get_u16(buf + pos + 1); if (val >= ' ' && val <= 126) printf(" '%c'", val); else printf(" 0x%04x", val); break; case REOP_char32: case REOP_char32_i: val = get_u32(buf + pos + 1); if (val >= ' ' && val <= 126) printf(" '%c'", val); else printf(" 0x%08x", val); break; case REOP_goto: case REOP_split_goto_first: case REOP_split_next_first: case REOP_lookahead: case REOP_negative_lookahead: val = get_u32(buf + pos + 1); val += (pos + 5); printf(" %u", val); break; case REOP_loop: val2 = buf[pos + 1]; val = get_u32(buf + pos + 2); val += (pos + 6); printf(" r%u, %u", val2, val); break; case REOP_loop_split_goto_first: case REOP_loop_split_next_first: case REOP_loop_check_adv_split_goto_first: case REOP_loop_check_adv_split_next_first: { uint32_t limit; val2 = buf[pos + 1]; limit = get_u32(buf + pos + 2); val = get_u32(buf + pos + 6); val += (pos + 10); printf(" r%u, %u, %u", val2, limit, val); } break; case REOP_save_start: case REOP_save_end: printf(" %u", buf[pos + 1]); break; case REOP_back_reference: case REOP_back_reference_i: case REOP_backward_back_reference: case REOP_backward_back_reference_i: { int n, i; n = buf[pos + 1]; len += n; for(i = 0; i < n; i++) { if (i != 0) printf(","); printf(" %u", buf[pos + 2 + i]); } } break; case REOP_save_reset: printf(" %u %u", buf[pos + 1], buf[pos + 2]); break; case REOP_set_i32: val = buf[pos + 1]; val2 = get_u32(buf + pos + 2); printf(" r%u, %d", val, val2); break; case REOP_set_char_pos: case REOP_check_advance: val = buf[pos + 1]; printf(" r%u", val); break; case REOP_range: case REOP_range_i: { int n, i; n = get_u16(buf + pos + 1); len += n * 4; for(i = 0; i < n * 2; i++) { val = get_u16(buf + pos + 3 + i * 2); printf(" 0x%04x", val); } } break; case REOP_range32: case REOP_range32_i: { int n, i; n = get_u16(buf + pos + 1); len += n * 8; for(i = 0; i < n * 2; i++) { val = get_u32(buf + pos + 3 + i * 4); printf(" 0x%08x", val); } } break; default: break; } printf("\n"); pos += len; } } #endif static void re_emit_op(REParseState *s, int op) { dbuf_putc(&s->byte_code, op); } /* return the offset of the u32 value */ static int re_emit_op_u32(REParseState *s, int op, uint32_t val) { int pos; dbuf_putc(&s->byte_code, op); pos = s->byte_code.size; dbuf_put_u32(&s->byte_code, val); return pos; } static int re_emit_goto(REParseState *s, int op, uint32_t val) { int pos; dbuf_putc(&s->byte_code, op); pos = s->byte_code.size; dbuf_put_u32(&s->byte_code, val - (pos + 4)); return pos; } static int re_emit_goto_u8(REParseState *s, int op, uint32_t arg, uint32_t val) { int pos; dbuf_putc(&s->byte_code, op); dbuf_putc(&s->byte_code, arg); pos = s->byte_code.size; dbuf_put_u32(&s->byte_code, val - (pos + 4)); return pos; } static int re_emit_goto_u8_u32(REParseState *s, int op, uint32_t arg0, uint32_t arg1, uint32_t val) { int pos; dbuf_putc(&s->byte_code, op); dbuf_putc(&s->byte_code, arg0); dbuf_put_u32(&s->byte_code, arg1); pos = s->byte_code.size; dbuf_put_u32(&s->byte_code, val - (pos + 4)); return pos; } static void re_emit_op_u8(REParseState *s, int op, uint32_t val) { dbuf_putc(&s->byte_code, op); dbuf_putc(&s->byte_code, val); } static void re_emit_op_u16(REParseState *s, int op, uint32_t val) { dbuf_putc(&s->byte_code, op); dbuf_put_u16(&s->byte_code, val); } static int __attribute__((format(printf, 2, 3))) re_parse_error(REParseState *s, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vsnprintf(s->u.error_msg, sizeof(s->u.error_msg), fmt, ap); va_end(ap); return -1; } static int re_parse_out_of_memory(REParseState *s) { return re_parse_error(s, "out of memory"); } /* If allow_overflow is false, return -1 in case of overflow. Otherwise return INT32_MAX. */ static int parse_digits(const uint8_t **pp, BOOL allow_overflow) { const uint8_t *p; uint64_t v; int c; p = *pp; v = 0; for(;;) { c = *p; if (c < '0' || c > '9') break; v = v * 10 + c - '0'; if (v >= INT32_MAX) { if (allow_overflow) v = INT32_MAX; else return -1; } p++; } *pp = p; return v; } static int re_parse_expect(REParseState *s, const uint8_t **pp, int c) { const uint8_t *p; p = *pp; if (*p != c) return re_parse_error(s, "expecting '%c'", c); p++; *pp = p; return 0; } /* Parse an escape sequence, *pp points after the '\': allow_utf16 value: 0 : no UTF-16 escapes allowed 1 : UTF-16 escapes allowed 2 : UTF-16 escapes allowed and escapes of surrogate pairs are converted to a unicode character (unicode regexp case). Return the unicode char and update *pp if recognized, return -1 if malformed escape, return -2 otherwise. */ int lre_parse_escape(const uint8_t **pp, int allow_utf16) { const uint8_t *p; uint32_t c; p = *pp; c = *p++; switch(c) { case 'b': c = '\b'; break; case 'f': c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'v': c = '\v'; break; case 'x': { int h0, h1; h0 = from_hex(*p++); if (h0 < 0) return -1; h1 = from_hex(*p++); if (h1 < 0) return -1; c = (h0 << 4) | h1; } break; case 'u': { int h, i; uint32_t c1; if (*p == '{' && allow_utf16) { p++; c = 0; for(;;) { h = from_hex(*p++); if (h < 0) return -1; c = (c << 4) | h; if (c > 0x10FFFF) return -1; if (*p == '}') break; } p++; } else { c = 0; for(i = 0; i < 4; i++) { h = from_hex(*p++); if (h < 0) { return -1; } c = (c << 4) | h; } if (is_hi_surrogate(c) && allow_utf16 == 2 && p[0] == '\\' && p[1] == 'u') { /* convert an escaped surrogate pair into a unicode char */ c1 = 0; for(i = 0; i < 4; i++) { h = from_hex(p[2 + i]); if (h < 0) break; c1 = (c1 << 4) | h; } if (i == 4 && is_lo_surrogate(c1)) { p += 6; c = from_surrogate(c, c1); } } } } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': c -= '0'; if (allow_utf16 == 2) { /* only accept \0 not followed by digit */ if (c != 0 || is_digit(*p)) return -1; } else { /* parse a legacy octal sequence */ uint32_t v; v = *p - '0'; if (v > 7) break; c = (c << 3) | v; p++; if (c >= 32) break; v = *p - '0'; if (v > 7) break; c = (c << 3) | v; p++; } break; default: return -2; } *pp = p; return c; } #ifdef CONFIG_ALL_UNICODE /* XXX: we use the same chars for name and value */ static BOOL is_unicode_char(int c) { return ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c == '_')); } /* XXX: memory error test */ static void seq_prop_cb(void *opaque, const uint32_t *seq, int seq_len) { REStringList *sl = opaque; re_string_add(sl, seq_len, seq); } static int parse_unicode_property(REParseState *s, REStringList *cr, const uint8_t **pp, BOOL is_inv, BOOL allow_sequence_prop) { const uint8_t *p; char name[64], value[64]; char *q; BOOL script_ext; int ret; p = *pp; if (*p != '{') return re_parse_error(s, "expecting '{' after \\p"); p++; q = name; while (is_unicode_char(*p)) { if ((q - name) >= sizeof(name) - 1) goto unknown_property_name; *q++ = *p++; } *q = '\0'; q = value; if (*p == '=') { p++; while (is_unicode_char(*p)) { if ((q - value) >= sizeof(value) - 1) return re_parse_error(s, "unknown unicode property value"); *q++ = *p++; } } *q = '\0'; if (*p != '}') return re_parse_error(s, "expecting '}'"); p++; // printf("name=%s value=%s\n", name, value); if (!strcmp(name, "Script") || !strcmp(name, "sc")) { script_ext = FALSE; goto do_script; } else if (!strcmp(name, "Script_Extensions") || !strcmp(name, "scx")) { script_ext = TRUE; do_script: re_string_list_init(s, cr); ret = unicode_script(&cr->cr, value, script_ext); if (ret) { re_string_list_free(cr); if (ret == -2) return re_parse_error(s, "unknown unicode script"); else goto out_of_memory; } } else if (!strcmp(name, "General_Category") || !strcmp(name, "gc")) { re_string_list_init(s, cr); ret = unicode_general_category(&cr->cr, value); if (ret) { re_string_list_free(cr); if (ret == -2) return re_parse_error(s, "unknown unicode general category"); else goto out_of_memory; } } else if (value[0] == '\0') { re_string_list_init(s, cr); ret = unicode_general_category(&cr->cr, name); if (ret == -1) { re_string_list_free(cr); goto out_of_memory; } if (ret < 0) { ret = unicode_prop(&cr->cr, name); if (ret == -1) { re_string_list_free(cr); goto out_of_memory; } } if (ret < 0 && !is_inv && allow_sequence_prop) { CharRange cr_tmp; cr_init(&cr_tmp, s->opaque, lre_realloc); ret = unicode_sequence_prop(name, seq_prop_cb, cr, &cr_tmp); cr_free(&cr_tmp); if (ret == -1) { re_string_list_free(cr); goto out_of_memory; } } if (ret < 0) goto unknown_property_name; } else { unknown_property_name: return re_parse_error(s, "unknown unicode property name"); } /* the ordering of case folding and inversion differs with unicode_sets. 'unicode_sets' ordering is more consistent */ /* XXX: the spec seems incorrect, we do it as the other engines seem to do it. */ if (s->ignore_case && s->unicode_sets) { if (re_string_list_canonicalize(s, cr, s->is_unicode)) { re_string_list_free(cr); goto out_of_memory; } } if (is_inv) { if (cr_invert(&cr->cr)) { re_string_list_free(cr); goto out_of_memory; } } if (s->ignore_case && !s->unicode_sets) { if (re_string_list_canonicalize(s, cr, s->is_unicode)) { re_string_list_free(cr); goto out_of_memory; } } *pp = p; return 0; out_of_memory: return re_parse_out_of_memory(s); } #endif /* CONFIG_ALL_UNICODE */ static int get_class_atom(REParseState *s, REStringList *cr, const uint8_t **pp, BOOL inclass); static int parse_class_string_disjunction(REParseState *s, REStringList *cr, const uint8_t **pp) { const uint8_t *p; DynBuf str; int c; p = *pp; if (*p != '{') return re_parse_error(s, "expecting '{' after \\q"); dbuf_init2(&str, s->opaque, lre_realloc); re_string_list_init(s, cr); p++; for(;;) { str.size = 0; while (*p != '}' && *p != '|') { c = get_class_atom(s, NULL, &p, FALSE); if (c < 0) goto fail; if (dbuf_put_u32(&str, c)) { re_parse_out_of_memory(s); goto fail; } } if (re_string_add(cr, str.size / 4, (uint32_t *)str.buf)) { re_parse_out_of_memory(s); goto fail; } if (*p == '}') break; p++; } if (s->ignore_case) { if (re_string_list_canonicalize(s, cr, TRUE)) goto fail; } p++; /* skip the '}' */ dbuf_free(&str); *pp = p; return 0; fail: dbuf_free(&str); re_string_list_free(cr); return -1; } /* return -1 if error otherwise the character or a class range (CLASS_RANGE_BASE) if cr != NULL. In case of class range, 'cr' is initialized. Otherwise, it is ignored. */ static int get_class_atom(REParseState *s, REStringList *cr, const uint8_t **pp, BOOL inclass) { const uint8_t *p; uint32_t c; int ret; p = *pp; c = *p; switch(c) { case '\\': p++; if (p >= s->buf_end) goto unexpected_end; c = *p++; switch(c) { case 'd': c = CHAR_RANGE_d; goto class_range; case 'D': c = CHAR_RANGE_D; goto class_range; case 's': c = CHAR_RANGE_s; goto class_range; case 'S': c = CHAR_RANGE_S; goto class_range; case 'w': c = CHAR_RANGE_w; goto class_range; case 'W': c = CHAR_RANGE_W; class_range: if (!cr) goto default_escape; if (cr_init_char_range(s, cr, c)) return -1; c += CLASS_RANGE_BASE; break; case 'c': c = *p; if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (((c >= '0' && c <= '9') || c == '_') && inclass && !s->is_unicode)) { /* Annex B.1.4 */ c &= 0x1f; p++; } else if (s->is_unicode) { goto invalid_escape; } else { /* otherwise return '\' and 'c' */ p--; c = '\\'; } break; case '-': if (!inclass && s->is_unicode) goto invalid_escape; break; case '^': case '$': case '\\': case '.': case '*': case '+': case '?': case '(': case ')': case '[': case ']': case '{': case '}': case '|': case '/': /* always valid to escape these characters */ break; #ifdef CONFIG_ALL_UNICODE case 'p': case 'P': if (s->is_unicode && cr) { if (parse_unicode_property(s, cr, &p, (c == 'P'), s->unicode_sets)) return -1; c = CLASS_RANGE_BASE; break; } goto default_escape; #endif case 'q': if (s->unicode_sets && cr && inclass) { if (parse_class_string_disjunction(s, cr, &p)) return -1; c = CLASS_RANGE_BASE; break; } goto default_escape; default: default_escape: p--; ret = lre_parse_escape(&p, s->is_unicode * 2); if (ret >= 0) { c = ret; } else { if (s->is_unicode) { invalid_escape: return re_parse_error(s, "invalid escape sequence in regular expression"); } else { /* just ignore the '\' */ goto normal_char; } } break; } break; case '\0': if (p >= s->buf_end) { unexpected_end: return re_parse_error(s, "unexpected end"); } /* fall thru */ goto normal_char; case '&': case '!': case '#': case '$': case '%': case '*': case '+': case ',': case '.': case ':': case ';': case '<': case '=': case '>': case '?': case '@': case '^': case '`': case '~': if (s->unicode_sets && p[1] == c) { /* forbidden double characters */ return re_parse_error(s, "invalid class set operation in regular expression"); } goto normal_char; case '(': case ')': case '[': case ']': case '{': case '}': case '/': case '-': case '|': if (s->unicode_sets) { /* invalid characters in unicode sets */ return re_parse_error(s, "invalid character in class in regular expression"); } goto normal_char; default: normal_char: /* normal char */ if (c >= 128) { c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); if ((unsigned)c > 0xffff && !s->is_unicode) { /* XXX: should handle non BMP-1 code points */ return re_parse_error(s, "malformed unicode char"); } } else { p++; } break; } *pp = p; return c; } static int re_emit_range(REParseState *s, const CharRange *cr) { int len, i; uint32_t high; len = (unsigned)cr->len / 2; if (len >= 65535) return re_parse_error(s, "too many ranges"); if (len == 0) { re_emit_op_u32(s, REOP_char32, -1); } else { high = cr->points[cr->len - 1]; if (high == UINT32_MAX) high = cr->points[cr->len - 2]; if (high <= 0xffff) { /* can use 16 bit ranges with the conversion that 0xffff = infinity */ re_emit_op_u16(s, s->ignore_case ? REOP_range_i : REOP_range, len); for(i = 0; i < cr->len; i += 2) { dbuf_put_u16(&s->byte_code, cr->points[i]); high = cr->points[i + 1] - 1; if (high == UINT32_MAX - 1) high = 0xffff; dbuf_put_u16(&s->byte_code, high); } } else { re_emit_op_u16(s, s->ignore_case ? REOP_range32_i : REOP_range32, len); for(i = 0; i < cr->len; i += 2) { dbuf_put_u32(&s->byte_code, cr->points[i]); dbuf_put_u32(&s->byte_code, cr->points[i + 1] - 1); } } } return 0; } static int re_string_cmp_len(const void *a, const void *b, void *arg) { REString *p1 = *(REString **)a; REString *p2 = *(REString **)b; return (p1->len < p2->len) - (p1->len > p2->len); } static void re_emit_char(REParseState *s, int c) { if (c <= 0xffff) re_emit_op_u16(s, s->ignore_case ? REOP_char_i : REOP_char, c); else re_emit_op_u32(s, s->ignore_case ? REOP_char32_i : REOP_char32, c); } static int re_emit_string_list(REParseState *s, const REStringList *sl) { REString **tab, *p; int i, j, split_pos, last_match_pos, n; BOOL has_empty_string, is_last; // re_string_list_dump("sl", sl); if (sl->n_strings == 0) { /* simple case: only characters */ if (re_emit_range(s, &sl->cr)) return -1; } else { /* at least one string list is present : match the longest ones first */ /* XXX: add a new op_switch opcode to compile as a trie */ tab = lre_realloc(s->opaque, NULL, sizeof(tab[0]) * sl->n_strings); if (!tab) { re_parse_out_of_memory(s); return -1; } has_empty_string = FALSE; n = 0; for(i = 0; i < sl->hash_size; i++) { for(p = sl->hash_table[i]; p != NULL; p = p->next) { if (p->len == 0) { has_empty_string = TRUE; } else { tab[n++] = p; } } } assert(n <= sl->n_strings); rqsort(tab, n, sizeof(tab[0]), re_string_cmp_len, NULL); last_match_pos = -1; for(i = 0; i < n; i++) { p = tab[i]; is_last = !has_empty_string && sl->cr.len == 0 && i == (n - 1); if (!is_last) split_pos = re_emit_op_u32(s, REOP_split_next_first, 0); else split_pos = 0; for(j = 0; j < p->len; j++) { re_emit_char(s, p->buf[j]); } if (!is_last) { last_match_pos = re_emit_op_u32(s, REOP_goto, last_match_pos); put_u32(s->byte_code.buf + split_pos, s->byte_code.size - (split_pos + 4)); } } if (sl->cr.len != 0) { /* char range */ is_last = !has_empty_string; if (!is_last) split_pos = re_emit_op_u32(s, REOP_split_next_first, 0); else split_pos = 0; /* not used */ if (re_emit_range(s, &sl->cr)) { lre_realloc(s->opaque, tab, 0); return -1; } if (!is_last) put_u32(s->byte_code.buf + split_pos, s->byte_code.size - (split_pos + 4)); } /* patch the 'goto match' */ while (last_match_pos != -1) { int next_pos = get_u32(s->byte_code.buf + last_match_pos); put_u32(s->byte_code.buf + last_match_pos, s->byte_code.size - (last_match_pos + 4)); last_match_pos = next_pos; } lre_realloc(s->opaque, tab, 0); } return 0; } static int re_parse_nested_class(REParseState *s, REStringList *cr, const uint8_t **pp); static int re_parse_class_set_operand(REParseState *s, REStringList *cr, const uint8_t **pp) { int c1; const uint8_t *p = *pp; if (*p == '[') { if (re_parse_nested_class(s, cr, pp)) return -1; } else { c1 = get_class_atom(s, cr, pp, TRUE); if (c1 < 0) return -1; if (c1 < CLASS_RANGE_BASE) { /* create a range with a single character */ re_string_list_init(s, cr); if (s->ignore_case) c1 = lre_canonicalize(c1, s->is_unicode); if (cr_union_interval(&cr->cr, c1, c1)) { re_string_list_free(cr); return -1; } } } return 0; } static int re_parse_nested_class(REParseState *s, REStringList *cr, const uint8_t **pp) { const uint8_t *p; uint32_t c1, c2; int ret; REStringList cr1_s, *cr1 = &cr1_s; BOOL invert, is_first; if (lre_check_stack_overflow(s->opaque, 0)) return re_parse_error(s, "stack overflow"); re_string_list_init(s, cr); p = *pp; p++; /* skip '[' */ invert = FALSE; if (*p == '^') { p++; invert = TRUE; } /* handle unions */ is_first = TRUE; for(;;) { if (*p == ']') break; if (*p == '[' && s->unicode_sets) { if (re_parse_nested_class(s, cr1, &p)) goto fail; goto class_union; } else { c1 = get_class_atom(s, cr1, &p, TRUE); if ((int)c1 < 0) goto fail; if (*p == '-' && p[1] != ']') { const uint8_t *p0 = p + 1; if (p[1] == '-' && s->unicode_sets && is_first) goto class_atom; /* first character class followed by '--' */ if (c1 >= CLASS_RANGE_BASE) { if (s->is_unicode) { re_string_list_free(cr1); goto invalid_class_range; } /* Annex B: match '-' character */ goto class_atom; } c2 = get_class_atom(s, cr1, &p0, TRUE); if ((int)c2 < 0) goto fail; if (c2 >= CLASS_RANGE_BASE) { re_string_list_free(cr1); if (s->is_unicode) { goto invalid_class_range; } /* Annex B: match '-' character */ goto class_atom; } p = p0; if (c2 < c1) { invalid_class_range: re_parse_error(s, "invalid class range"); goto fail; } if (s->ignore_case) { CharRange cr2_s, *cr2 = &cr2_s; cr_init(cr2, s->opaque, lre_realloc); if (cr_add_interval(cr2, c1, c2 + 1) || cr_regexp_canonicalize(cr2, s->is_unicode) || cr_op1(&cr->cr, cr2->points, cr2->len, CR_OP_UNION)) { cr_free(cr2); goto memory_error; } cr_free(cr2); } else { if (cr_union_interval(&cr->cr, c1, c2)) goto memory_error; } is_first = FALSE; /* union operation */ } else { class_atom: if (c1 >= CLASS_RANGE_BASE) { class_union: ret = re_string_list_op(cr, cr1, CR_OP_UNION); re_string_list_free(cr1); if (ret) goto memory_error; } else { if (s->ignore_case) c1 = lre_canonicalize(c1, s->is_unicode); if (cr_union_interval(&cr->cr, c1, c1)) goto memory_error; } } } if (s->unicode_sets && is_first) { if (*p == '&' && p[1] == '&' && p[2] != '&') { /* handle '&&' */ for(;;) { if (*p == ']') { break; } else if (*p == '&' && p[1] == '&' && p[2] != '&') { p += 2; } else { goto invalid_operation; } if (re_parse_class_set_operand(s, cr1, &p)) goto fail; ret = re_string_list_op(cr, cr1, CR_OP_INTER); re_string_list_free(cr1); if (ret) goto memory_error; } } else if (*p == '-' && p[1] == '-') { /* handle '--' */ for(;;) { if (*p == ']') { break; } else if (*p == '-' && p[1] == '-') { p += 2; } else { invalid_operation: re_parse_error(s, "invalid operation in regular expression"); goto fail; } if (re_parse_class_set_operand(s, cr1, &p)) goto fail; ret = re_string_list_op(cr, cr1, CR_OP_SUB); re_string_list_free(cr1); if (ret) goto memory_error; } } } is_first = FALSE; } p++; /* skip ']' */ *pp = p; if (invert) { /* XXX: add may_contain_string syntax check to be fully compliant. The test here accepts more input than the spec. */ if (cr->n_strings != 0) { re_parse_error(s, "negated character class with strings in regular expression debugger eval code"); goto fail; } if (cr_invert(&cr->cr)) goto memory_error; } return 0; memory_error: re_parse_out_of_memory(s); fail: re_string_list_free(cr); return -1; } static int re_parse_char_class(REParseState *s, const uint8_t **pp) { REStringList cr_s, *cr = &cr_s; if (re_parse_nested_class(s, cr, pp)) return -1; if (re_emit_string_list(s, cr)) goto fail; re_string_list_free(cr); return 0; fail: re_string_list_free(cr); return -1; } /* need_check_adv: false if the opcodes always advance the char pointer need_capture_init: true if all the captures in the atom are not set */ static BOOL re_need_check_adv_and_capture_init(BOOL *pneed_capture_init, const uint8_t *bc_buf, int bc_buf_len) { int pos, opcode, len; uint32_t val; BOOL need_check_adv, need_capture_init; need_check_adv = TRUE; need_capture_init = FALSE; pos = 0; while (pos < bc_buf_len) { opcode = bc_buf[pos]; len = reopcode_info[opcode].size; switch(opcode) { case REOP_range: case REOP_range_i: val = get_u16(bc_buf + pos + 1); len += val * 4; need_check_adv = FALSE; break; case REOP_range32: case REOP_range32_i: val = get_u16(bc_buf + pos + 1); len += val * 8; need_check_adv = FALSE; break; case REOP_char: case REOP_char_i: case REOP_char32: case REOP_char32_i: case REOP_dot: case REOP_any: case REOP_space: case REOP_not_space: need_check_adv = FALSE; break; case REOP_line_start: case REOP_line_start_m: case REOP_line_end: case REOP_line_end_m: case REOP_set_i32: case REOP_set_char_pos: case REOP_word_boundary: case REOP_word_boundary_i: case REOP_not_word_boundary: case REOP_not_word_boundary_i: case REOP_prev: /* no effect */ break; case REOP_save_start: case REOP_save_end: case REOP_save_reset: break; case REOP_back_reference: case REOP_back_reference_i: case REOP_backward_back_reference: case REOP_backward_back_reference_i: val = bc_buf[pos + 1]; len += val; need_capture_init = TRUE; break; default: /* safe behavior: we cannot predict the outcome */ need_capture_init = TRUE; goto done; } pos += len; } done: *pneed_capture_init = need_capture_init; return need_check_adv; } /* '*pp' is the first char after '<' */ static int re_parse_group_name(char *buf, int buf_size, const uint8_t **pp) { const uint8_t *p, *p1; uint32_t c, d; char *q; p = *pp; q = buf; for(;;) { c = *p; if (c == '\\') { p++; if (*p != 'u') return -1; c = lre_parse_escape(&p, 2); // accept surrogate pairs } else if (c == '>') { break; } else if (c >= 128) { c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); if (is_hi_surrogate(c)) { d = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p1); if (is_lo_surrogate(d)) { c = from_surrogate(c, d); p = p1; } } } else { p++; } if (c > 0x10FFFF) return -1; if (q == buf) { if (!lre_js_is_ident_first(c)) return -1; } else { if (!lre_js_is_ident_next(c)) return -1; } if ((q - buf + UTF8_CHAR_LEN_MAX + 1) > buf_size) return -1; if (c < 128) { *q++ = c; } else { q += unicode_to_utf8((uint8_t*)q, c); } } if (q == buf) return -1; *q = '\0'; p++; *pp = p; return 0; } /* if capture_name = NULL: return the number of captures + 1. Otherwise, return the number of matching capture groups */ static int re_parse_captures(REParseState *s, int *phas_named_captures, const char *capture_name, BOOL emit_group_index) { const uint8_t *p; int capture_index, n; char name[TMP_BUF_SIZE]; capture_index = 1; n = 0; *phas_named_captures = 0; for (p = s->buf_start; p < s->buf_end; p++) { switch (*p) { case '(': if (p[1] == '?') { if (p[2] == '<' && p[3] != '=' && p[3] != '!') { *phas_named_captures = 1; /* potential named capture */ if (capture_name) { p += 3; if (re_parse_group_name(name, sizeof(name), &p) == 0) { if (!strcmp(name, capture_name)) { if (emit_group_index) dbuf_putc(&s->byte_code, capture_index); n++; } } } capture_index++; if (capture_index >= CAPTURE_COUNT_MAX) goto done; } } else { capture_index++; if (capture_index >= CAPTURE_COUNT_MAX) goto done; } break; case '\\': p++; break; case '[': for (p += 1 + (*p == ']'); p < s->buf_end && *p != ']'; p++) { if (*p == '\\') p++; } break; } } done: if (capture_name) { return n; } else { return capture_index; } } static int re_count_captures(REParseState *s) { if (s->total_capture_count < 0) { s->total_capture_count = re_parse_captures(s, &s->has_named_captures, NULL, FALSE); } return s->total_capture_count; } static BOOL re_has_named_captures(REParseState *s) { if (s->has_named_captures < 0) re_count_captures(s); return s->has_named_captures; } static int find_group_name(REParseState *s, const char *name, BOOL emit_group_index) { const char *p, *buf_end; size_t len, name_len; int capture_index, n; p = (char *)s->group_names.buf; if (!p) return 0; buf_end = (char *)s->group_names.buf + s->group_names.size; name_len = strlen(name); capture_index = 1; n = 0; while (p < buf_end) { len = strlen(p); if (len == name_len && memcmp(name, p, name_len) == 0) { if (emit_group_index) dbuf_putc(&s->byte_code, capture_index); n++; } p += len + LRE_GROUP_NAME_TRAILER_LEN; capture_index++; } return n; } static BOOL is_duplicate_group_name(REParseState *s, const char *name, int scope) { const char *p, *buf_end; size_t len, name_len; int scope1; p = (char *)s->group_names.buf; if (!p) return 0; buf_end = (char *)s->group_names.buf + s->group_names.size; name_len = strlen(name); while (p < buf_end) { len = strlen(p); if (len == name_len && memcmp(name, p, name_len) == 0) { scope1 = (uint8_t)p[len + 1]; if (scope == scope1) return TRUE; } p += len + LRE_GROUP_NAME_TRAILER_LEN; } return FALSE; } static int re_parse_disjunction(REParseState *s, BOOL is_backward_dir); static int re_parse_modifiers(REParseState *s, const uint8_t **pp) { const uint8_t *p = *pp; int mask = 0; int val; for(;;) { if (*p == 'i') { val = LRE_FLAG_IGNORECASE; } else if (*p == 'm') { val = LRE_FLAG_MULTILINE; } else if (*p == 's') { val = LRE_FLAG_DOTALL; } else { break; } if (mask & val) return re_parse_error(s, "duplicate modifier: '%c'", *p); mask |= val; p++; } *pp = p; return mask; } static BOOL update_modifier(BOOL val, int add_mask, int remove_mask, int mask) { if (add_mask & mask) val = TRUE; if (remove_mask & mask) val = FALSE; return val; } static int re_parse_term(REParseState *s, BOOL is_backward_dir) { const uint8_t *p; int c, last_atom_start, quant_min, quant_max, last_capture_count; BOOL greedy, is_neg, is_backward_lookahead; REStringList cr_s, *cr = &cr_s; last_atom_start = -1; last_capture_count = 0; p = s->buf_ptr; c = *p; switch(c) { case '^': p++; re_emit_op(s, s->multi_line ? REOP_line_start_m : REOP_line_start); break; case '$': p++; re_emit_op(s, s->multi_line ? REOP_line_end_m : REOP_line_end); break; case '.': p++; last_atom_start = s->byte_code.size; last_capture_count = s->capture_count; if (is_backward_dir) re_emit_op(s, REOP_prev); re_emit_op(s, s->dotall ? REOP_any : REOP_dot); if (is_backward_dir) re_emit_op(s, REOP_prev); break; case '{': if (s->is_unicode) { return re_parse_error(s, "syntax error"); } else if (!is_digit(p[1])) { /* Annex B: we accept '{' not followed by digits as a normal atom */ goto parse_class_atom; } else { const uint8_t *p1 = p + 1; /* Annex B: error if it is like a repetition count */ parse_digits(&p1, TRUE); if (*p1 == ',') { p1++; if (is_digit(*p1)) { parse_digits(&p1, TRUE); } } if (*p1 != '}') { goto parse_class_atom; } } /* fall thru */ case '*': case '+': case '?': return re_parse_error(s, "nothing to repeat"); case '(': if (p[1] == '?') { if (p[2] == ':') { p += 3; last_atom_start = s->byte_code.size; last_capture_count = s->capture_count; s->buf_ptr = p; if (re_parse_disjunction(s, is_backward_dir)) return -1; p = s->buf_ptr; if (re_parse_expect(s, &p, ')')) return -1; } else if (p[2] == 'i' || p[2] == 'm' || p[2] == 's' || p[2] == '-') { BOOL saved_ignore_case, saved_multi_line, saved_dotall; int add_mask, remove_mask; p += 2; remove_mask = 0; add_mask = re_parse_modifiers(s, &p); if (add_mask < 0) return -1; if (*p == '-') { p++; remove_mask = re_parse_modifiers(s, &p); if (remove_mask < 0) return -1; } if ((add_mask == 0 && remove_mask == 0) || (add_mask & remove_mask) != 0) { return re_parse_error(s, "invalid modifiers"); } if (re_parse_expect(s, &p, ':')) return -1; saved_ignore_case = s->ignore_case; saved_multi_line = s->multi_line; saved_dotall = s->dotall; s->ignore_case = update_modifier(s->ignore_case, add_mask, remove_mask, LRE_FLAG_IGNORECASE); s->multi_line = update_modifier(s->multi_line, add_mask, remove_mask, LRE_FLAG_MULTILINE); s->dotall = update_modifier(s->dotall, add_mask, remove_mask, LRE_FLAG_DOTALL); last_atom_start = s->byte_code.size; last_capture_count = s->capture_count; s->buf_ptr = p; if (re_parse_disjunction(s, is_backward_dir)) return -1; p = s->buf_ptr; if (re_parse_expect(s, &p, ')')) return -1; s->ignore_case = saved_ignore_case; s->multi_line = saved_multi_line; s->dotall = saved_dotall; } else if ((p[2] == '=' || p[2] == '!')) { is_neg = (p[2] == '!'); is_backward_lookahead = FALSE; p += 3; goto lookahead; } else if (p[2] == '<' && (p[3] == '=' || p[3] == '!')) { int pos; is_neg = (p[3] == '!'); is_backward_lookahead = TRUE; p += 4; /* lookahead */ lookahead: /* Annex B allows lookahead to be used as an atom for the quantifiers */ if (!s->is_unicode && !is_backward_lookahead) { last_atom_start = s->byte_code.size; last_capture_count = s->capture_count; } pos = re_emit_op_u32(s, REOP_lookahead + is_neg, 0); s->buf_ptr = p; if (re_parse_disjunction(s, is_backward_lookahead)) return -1; p = s->buf_ptr; if (re_parse_expect(s, &p, ')')) return -1; re_emit_op(s, REOP_lookahead_match + is_neg); /* jump after the 'match' after the lookahead is successful */ if (dbuf_error(&s->byte_code)) return -1; put_u32(s->byte_code.buf + pos, s->byte_code.size - (pos + 4)); } else if (p[2] == '<') { p += 3; if (re_parse_group_name(s->u.tmp_buf, sizeof(s->u.tmp_buf), &p)) { return re_parse_error(s, "invalid group name"); } /* poor's man method to test duplicate group names. */ /* XXX: this method does not catch all the errors*/ if (is_duplicate_group_name(s, s->u.tmp_buf, s->group_name_scope)) { return re_parse_error(s, "duplicate group name"); } /* group name with a trailing zero */ dbuf_put(&s->group_names, (uint8_t *)s->u.tmp_buf, strlen(s->u.tmp_buf) + 1); dbuf_putc(&s->group_names, s->group_name_scope); s->has_named_captures = 1; goto parse_capture; } else { return re_parse_error(s, "invalid group"); } } else { int capture_index; p++; /* capture without group name */ dbuf_putc(&s->group_names, 0); dbuf_putc(&s->group_names, 0); parse_capture: if (s->capture_count >= CAPTURE_COUNT_MAX) return re_parse_error(s, "too many captures"); last_atom_start = s->byte_code.size; last_capture_count = s->capture_count; capture_index = s->capture_count++; re_emit_op_u8(s, REOP_save_start + is_backward_dir, capture_index); s->buf_ptr = p; if (re_parse_disjunction(s, is_backward_dir)) return -1; p = s->buf_ptr; re_emit_op_u8(s, REOP_save_start + 1 - is_backward_dir, capture_index); if (re_parse_expect(s, &p, ')')) return -1; } break; case '\\': switch(p[1]) { case 'b': case 'B': if (p[1] != 'b') { re_emit_op(s, s->ignore_case && s->is_unicode ? REOP_not_word_boundary_i : REOP_not_word_boundary); } else { re_emit_op(s, s->ignore_case && s->is_unicode ? REOP_word_boundary_i : REOP_word_boundary); } p += 2; break; case 'k': { const uint8_t *p1; int dummy_res, n; BOOL is_forward; p1 = p; if (p1[2] != '<') { /* annex B: we tolerate invalid group names in non unicode mode if there is no named capture definition */ if (s->is_unicode || re_has_named_captures(s)) return re_parse_error(s, "expecting group name"); else goto parse_class_atom; } p1 += 3; if (re_parse_group_name(s->u.tmp_buf, sizeof(s->u.tmp_buf), &p1)) { if (s->is_unicode || re_has_named_captures(s)) return re_parse_error(s, "invalid group name"); else goto parse_class_atom; } is_forward = FALSE; n = find_group_name(s, s->u.tmp_buf, FALSE); if (n == 0) { /* no capture name parsed before, try to look after (inefficient, but hopefully not common */ n = re_parse_captures(s, &dummy_res, s->u.tmp_buf, FALSE); if (n == 0) { if (s->is_unicode || re_has_named_captures(s)) return re_parse_error(s, "group name not defined"); else goto parse_class_atom; } is_forward = TRUE; } last_atom_start = s->byte_code.size; last_capture_count = s->capture_count; /* emit back references to all the captures indexes matching the group name */ re_emit_op_u8(s, REOP_back_reference + 2 * is_backward_dir + s->ignore_case, n); if (is_forward) { re_parse_captures(s, &dummy_res, s->u.tmp_buf, TRUE); } else { find_group_name(s, s->u.tmp_buf, TRUE); } p = p1; } break; case '0': p += 2; c = 0; if (s->is_unicode) { if (is_digit(*p)) { return re_parse_error(s, "invalid decimal escape in regular expression"); } } else { /* Annex B.1.4: accept legacy octal */ if (*p >= '0' && *p <= '7') { c = *p++ - '0'; if (*p >= '0' && *p <= '7') { c = (c << 3) + *p++ - '0'; } } } goto normal_char; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { const uint8_t *q = ++p; c = parse_digits(&p, FALSE); if (c < 0 || (c >= s->capture_count && c >= re_count_captures(s))) { if (!s->is_unicode) { /* Annex B.1.4: accept legacy octal */ p = q; if (*p <= '7') { c = 0; if (*p <= '3') c = *p++ - '0'; if (*p >= '0' && *p <= '7') { c = (c << 3) + *p++ - '0'; if (*p >= '0' && *p <= '7') { c = (c << 3) + *p++ - '0'; } } } else { c = *p++; } goto normal_char; } return re_parse_error(s, "back reference out of range in regular expression"); } last_atom_start = s->byte_code.size; last_capture_count = s->capture_count; re_emit_op_u8(s, REOP_back_reference + 2 * is_backward_dir + s->ignore_case, 1); dbuf_putc(&s->byte_code, c); } break; default: goto parse_class_atom; } break; case '[': last_atom_start = s->byte_code.size; last_capture_count = s->capture_count; if (is_backward_dir) re_emit_op(s, REOP_prev); if (re_parse_char_class(s, &p)) return -1; if (is_backward_dir) re_emit_op(s, REOP_prev); break; case ']': case '}': if (s->is_unicode) return re_parse_error(s, "syntax error"); goto parse_class_atom; default: parse_class_atom: c = get_class_atom(s, cr, &p, FALSE); if ((int)c < 0) return -1; normal_char: last_atom_start = s->byte_code.size; last_capture_count = s->capture_count; if (is_backward_dir) re_emit_op(s, REOP_prev); if (c >= CLASS_RANGE_BASE) { int ret = 0; /* optimize the common 'space' tests */ if (c == (CLASS_RANGE_BASE + CHAR_RANGE_s)) { re_emit_op(s, REOP_space); } else if (c == (CLASS_RANGE_BASE + CHAR_RANGE_S)) { re_emit_op(s, REOP_not_space); } else { ret = re_emit_string_list(s, cr); } re_string_list_free(cr); if (ret) return -1; } else { if (s->ignore_case) c = lre_canonicalize(c, s->is_unicode); re_emit_char(s, c); } if (is_backward_dir) re_emit_op(s, REOP_prev); break; } /* quantifier */ if (last_atom_start >= 0) { c = *p; switch(c) { case '*': p++; quant_min = 0; quant_max = INT32_MAX; goto quantifier; case '+': p++; quant_min = 1; quant_max = INT32_MAX; goto quantifier; case '?': p++; quant_min = 0; quant_max = 1; goto quantifier; case '{': { const uint8_t *p1 = p; /* As an extension (see ES6 annex B), we accept '{' not followed by digits as a normal atom */ if (!is_digit(p[1])) { if (s->is_unicode) goto invalid_quant_count; break; } p++; quant_min = parse_digits(&p, TRUE); quant_max = quant_min; if (*p == ',') { p++; if (is_digit(*p)) { quant_max = parse_digits(&p, TRUE); if (quant_max < quant_min) { invalid_quant_count: return re_parse_error(s, "invalid repetition count"); } } else { quant_max = INT32_MAX; /* infinity */ } } if (*p != '}' && !s->is_unicode) { /* Annex B: normal atom if invalid '{' syntax */ p = p1; break; } if (re_parse_expect(s, &p, '}')) return -1; } quantifier: greedy = TRUE; if (*p == '?') { p++; greedy = FALSE; } if (last_atom_start < 0) { return re_parse_error(s, "nothing to repeat"); } { BOOL need_capture_init, add_zero_advance_check; int len, pos; /* the spec tells that if there is no advance when running the atom after the first quant_min times, then there is no match. We remove this test when we are sure the atom always advances the position. */ add_zero_advance_check = re_need_check_adv_and_capture_init(&need_capture_init, s->byte_code.buf + last_atom_start, s->byte_code.size - last_atom_start); /* general case: need to reset the capture at each iteration. We don't do it if there are no captures in the atom or if we are sure all captures are initialized in the atom. If quant_min = 0, we still need to reset once the captures in case the atom does not match. */ if (need_capture_init && last_capture_count != s->capture_count) { if (dbuf_insert(&s->byte_code, last_atom_start, 3)) goto out_of_memory; int pos = last_atom_start; s->byte_code.buf[pos++] = REOP_save_reset; s->byte_code.buf[pos++] = last_capture_count; s->byte_code.buf[pos++] = s->capture_count - 1; } len = s->byte_code.size - last_atom_start; if (quant_min == 0) { /* need to reset the capture in case the atom is not executed */ if (!need_capture_init && last_capture_count != s->capture_count) { if (dbuf_insert(&s->byte_code, last_atom_start, 3)) goto out_of_memory; s->byte_code.buf[last_atom_start++] = REOP_save_reset; s->byte_code.buf[last_atom_start++] = last_capture_count; s->byte_code.buf[last_atom_start++] = s->capture_count - 1; } if (quant_max == 0) { s->byte_code.size = last_atom_start; } else if (quant_max == 1 || quant_max == INT32_MAX) { BOOL has_goto = (quant_max == INT32_MAX); if (dbuf_insert(&s->byte_code, last_atom_start, 5 + add_zero_advance_check * 2)) goto out_of_memory; s->byte_code.buf[last_atom_start] = REOP_split_goto_first + greedy; put_u32(s->byte_code.buf + last_atom_start + 1, len + 5 * has_goto + add_zero_advance_check * 2 * 2); if (add_zero_advance_check) { s->byte_code.buf[last_atom_start + 1 + 4] = REOP_set_char_pos; s->byte_code.buf[last_atom_start + 1 + 4 + 1] = 0; re_emit_op_u8(s, REOP_check_advance, 0); } if (has_goto) re_emit_goto(s, REOP_goto, last_atom_start); } else { if (dbuf_insert(&s->byte_code, last_atom_start, 11 + add_zero_advance_check * 2)) goto out_of_memory; pos = last_atom_start; s->byte_code.buf[pos++] = REOP_split_goto_first + greedy; put_u32(s->byte_code.buf + pos, 6 + add_zero_advance_check * 2 + len + 10); pos += 4; s->byte_code.buf[pos++] = REOP_set_i32; s->byte_code.buf[pos++] = 0; put_u32(s->byte_code.buf + pos, quant_max); pos += 4; last_atom_start = pos; if (add_zero_advance_check) { s->byte_code.buf[pos++] = REOP_set_char_pos; s->byte_code.buf[pos++] = 0; } re_emit_goto_u8_u32(s, (add_zero_advance_check ? REOP_loop_check_adv_split_next_first : REOP_loop_split_next_first) - greedy, 0, quant_max, last_atom_start); } } else if (quant_min == 1 && quant_max == INT32_MAX && !add_zero_advance_check) { re_emit_goto(s, REOP_split_next_first - greedy, last_atom_start); } else { if (quant_min == quant_max) add_zero_advance_check = FALSE; if (dbuf_insert(&s->byte_code, last_atom_start, 6 + add_zero_advance_check * 2)) goto out_of_memory; /* Note: we assume the string length is < INT32_MAX */ pos = last_atom_start; s->byte_code.buf[pos++] = REOP_set_i32; s->byte_code.buf[pos++] = 0; put_u32(s->byte_code.buf + pos, quant_max); pos += 4; last_atom_start = pos; if (add_zero_advance_check) { s->byte_code.buf[pos++] = REOP_set_char_pos; s->byte_code.buf[pos++] = 0; } if (quant_min == quant_max) { /* a simple loop is enough */ re_emit_goto_u8(s, REOP_loop, 0, last_atom_start); } else { re_emit_goto_u8_u32(s, (add_zero_advance_check ? REOP_loop_check_adv_split_next_first : REOP_loop_split_next_first) - greedy, 0, quant_max - quant_min, last_atom_start); } } last_atom_start = -1; } break; default: break; } } s->buf_ptr = p; return 0; out_of_memory: return re_parse_out_of_memory(s); } static int re_parse_alternative(REParseState *s, BOOL is_backward_dir) { const uint8_t *p; int ret; size_t start, term_start, end, term_size; start = s->byte_code.size; for(;;) { p = s->buf_ptr; if (p >= s->buf_end) break; if (*p == '|' || *p == ')') break; term_start = s->byte_code.size; ret = re_parse_term(s, is_backward_dir); if (ret) return ret; if (is_backward_dir) { /* reverse the order of the terms (XXX: inefficient, but speed is not really critical here) */ end = s->byte_code.size; term_size = end - term_start; if (dbuf_claim(&s->byte_code, term_size)) return -1; memmove(s->byte_code.buf + start + term_size, s->byte_code.buf + start, end - start); memcpy(s->byte_code.buf + start, s->byte_code.buf + end, term_size); } } return 0; } static int re_parse_disjunction(REParseState *s, BOOL is_backward_dir) { int start, len, pos; if (lre_check_stack_overflow(s->opaque, 0)) return re_parse_error(s, "stack overflow"); start = s->byte_code.size; if (re_parse_alternative(s, is_backward_dir)) return -1; while (*s->buf_ptr == '|') { s->buf_ptr++; len = s->byte_code.size - start; /* insert a split before the first alternative */ if (dbuf_insert(&s->byte_code, start, 5)) { return re_parse_out_of_memory(s); } s->byte_code.buf[start] = REOP_split_next_first; put_u32(s->byte_code.buf + start + 1, len + 5); pos = re_emit_op_u32(s, REOP_goto, 0); s->group_name_scope++; if (re_parse_alternative(s, is_backward_dir)) return -1; /* patch the goto */ len = s->byte_code.size - (pos + 4); put_u32(s->byte_code.buf + pos, len); } return 0; } /* Allocate the registers as a stack. The control flow is recursive so the analysis can be linear. */ static int compute_register_count(uint8_t *bc_buf, int bc_buf_len) { int stack_size, stack_size_max, pos, opcode, len; uint32_t val; stack_size = 0; stack_size_max = 0; bc_buf += RE_HEADER_LEN; bc_buf_len -= RE_HEADER_LEN; pos = 0; while (pos < bc_buf_len) { opcode = bc_buf[pos]; len = reopcode_info[opcode].size; assert(opcode < REOP_COUNT); assert((pos + len) <= bc_buf_len); switch(opcode) { case REOP_set_i32: case REOP_set_char_pos: bc_buf[pos + 1] = stack_size; stack_size++; if (stack_size > stack_size_max) { if (stack_size > REGISTER_COUNT_MAX) return -1; stack_size_max = stack_size; } break; case REOP_check_advance: case REOP_loop: case REOP_loop_split_goto_first: case REOP_loop_split_next_first: assert(stack_size > 0); stack_size--; bc_buf[pos + 1] = stack_size; break; case REOP_loop_check_adv_split_goto_first: case REOP_loop_check_adv_split_next_first: assert(stack_size >= 2); stack_size -= 2; bc_buf[pos + 1] = stack_size; break; case REOP_range: case REOP_range_i: val = get_u16(bc_buf + pos + 1); len += val * 4; break; case REOP_range32: case REOP_range32_i: val = get_u16(bc_buf + pos + 1); len += val * 8; break; case REOP_back_reference: case REOP_back_reference_i: case REOP_backward_back_reference: case REOP_backward_back_reference_i: val = bc_buf[pos + 1]; len += val; break; } pos += len; } return stack_size_max; } static void *lre_bytecode_realloc(void *opaque, void *ptr, size_t size) { if (size > (INT32_MAX / 2)) { /* the bytecode cannot be larger than 2G. Leave some slack to avoid some overflows. */ return NULL; } else { return lre_realloc(opaque, ptr, size); } } /* 'buf' must be a zero terminated UTF-8 string of length buf_len. Return NULL if error and allocate an error message in *perror_msg, otherwise the compiled bytecode and its length in plen. */ uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size, const char *buf, size_t buf_len, int re_flags, void *opaque) { REParseState s_s, *s = &s_s; int register_count; BOOL is_sticky; memset(s, 0, sizeof(*s)); s->opaque = opaque; s->buf_ptr = (const uint8_t *)buf; s->buf_end = s->buf_ptr + buf_len; s->buf_start = s->buf_ptr; s->re_flags = re_flags; s->is_unicode = ((re_flags & (LRE_FLAG_UNICODE | LRE_FLAG_UNICODE_SETS)) != 0); is_sticky = ((re_flags & LRE_FLAG_STICKY) != 0); s->ignore_case = ((re_flags & LRE_FLAG_IGNORECASE) != 0); s->multi_line = ((re_flags & LRE_FLAG_MULTILINE) != 0); s->dotall = ((re_flags & LRE_FLAG_DOTALL) != 0); s->unicode_sets = ((re_flags & LRE_FLAG_UNICODE_SETS) != 0); s->capture_count = 1; s->total_capture_count = -1; s->has_named_captures = -1; dbuf_init2(&s->byte_code, opaque, lre_bytecode_realloc); dbuf_init2(&s->group_names, opaque, lre_realloc); dbuf_put_u16(&s->byte_code, re_flags); /* first element is the flags */ dbuf_putc(&s->byte_code, 0); /* second element is the number of captures */ dbuf_putc(&s->byte_code, 0); /* stack size */ dbuf_put_u32(&s->byte_code, 0); /* bytecode length */ if (!is_sticky) { /* iterate thru all positions (about the same as .*?( ... ) ) . We do it without an explicit loop so that lock step thread execution will be possible in an optimized implementation */ re_emit_op_u32(s, REOP_split_goto_first, 1 + 5); re_emit_op(s, REOP_any); re_emit_op_u32(s, REOP_goto, -(5 + 1 + 5)); } re_emit_op_u8(s, REOP_save_start, 0); if (re_parse_disjunction(s, FALSE)) { error: dbuf_free(&s->byte_code); dbuf_free(&s->group_names); pstrcpy(error_msg, error_msg_size, s->u.error_msg); *plen = 0; return NULL; } re_emit_op_u8(s, REOP_save_end, 0); re_emit_op(s, REOP_match); if (*s->buf_ptr != '\0') { re_parse_error(s, "extraneous characters at the end"); goto error; } if (dbuf_error(&s->byte_code)) { re_parse_out_of_memory(s); goto error; } register_count = compute_register_count(s->byte_code.buf, s->byte_code.size); if (register_count < 0) { re_parse_error(s, "too many imbricated quantifiers"); goto error; } s->byte_code.buf[RE_HEADER_CAPTURE_COUNT] = s->capture_count; s->byte_code.buf[RE_HEADER_REGISTER_COUNT] = register_count; put_u32(s->byte_code.buf + RE_HEADER_BYTECODE_LEN, s->byte_code.size - RE_HEADER_LEN); /* add the named groups if needed */ if (s->group_names.size > (s->capture_count - 1) * LRE_GROUP_NAME_TRAILER_LEN) { dbuf_put(&s->byte_code, s->group_names.buf, s->group_names.size); put_u16(s->byte_code.buf + RE_HEADER_FLAGS, lre_get_flags(s->byte_code.buf) | LRE_FLAG_NAMED_GROUPS); } dbuf_free(&s->group_names); #ifdef DUMP_REOP lre_dump_bytecode(s->byte_code.buf, s->byte_code.size); #endif error_msg[0] = '\0'; *plen = s->byte_code.size; return s->byte_code.buf; } static BOOL is_line_terminator(uint32_t c) { return (c == '\n' || c == '\r' || c == CP_LS || c == CP_PS); } #define GET_CHAR(c, cptr, cbuf_end, cbuf_type) \ do { \ if (cbuf_type == 0) { \ c = *cptr++; \ } else if (cbuf_type < 3) { \ const uint16_t *_p = (const uint16_t *)cptr; \ const uint16_t *_end = (const uint16_t *)cbuf_end; \ c = *_p++; \ if (is_hi_surrogate(c) && cbuf_type == 2) { \ if (_p < _end && is_lo_surrogate(*_p)) { \ c = from_surrogate(c, *_p++); \ } \ } \ cptr = (const void *)_p; \ } else { \ c = unicode_from_utf8(cptr, cbuf_end - cptr, &cptr); \ } \ } while (0) #define PEEK_CHAR(c, cptr, cbuf_end, cbuf_type) \ do { \ if (cbuf_type == 0) { \ c = cptr[0]; \ } else if (cbuf_type < 3) { \ const uint16_t *_p = (const uint16_t *)cptr; \ const uint16_t *_end = (const uint16_t *)cbuf_end; \ c = *_p++; \ if (is_hi_surrogate(c) && cbuf_type == 2) { \ if (_p < _end && is_lo_surrogate(*_p)) { \ c = from_surrogate(c, *_p); \ } \ } \ } else { \ const uint8_t *__cpt2; \ c = unicode_from_utf8(cptr, cbuf_end - cptr, &__cpt2); \ } \ } while (0) #define PEEK_PREV_CHAR(c, cptr, cbuf_start, cbuf_type) \ do { \ if (cbuf_type == 0) { \ c = cptr[-1]; \ } else if (cbuf_type < 3) { \ const uint16_t *_p = (const uint16_t *)cptr - 1; \ const uint16_t *_start = (const uint16_t *)cbuf_start; \ c = *_p; \ if (is_lo_surrogate(c) && cbuf_type == 2) { \ if (_p > _start && is_hi_surrogate(_p[-1])) { \ c = from_surrogate(*--_p, c); \ } \ } \ } else { \ const uint8_t *__cpt2 = cptr; \ while (__cpt2 > cbuf_start && ((*(--__cpt2) >> 6) == 2)) \ ; \ c = unicode_from_utf8(__cpt2, cptr - __cpt2, &__cpt2); \ } \ } while (0) #define GET_PREV_CHAR(c, cptr, cbuf_start, cbuf_type) \ do { \ if (cbuf_type == 0) { \ cptr--; \ c = cptr[0]; \ } else if (cbuf_type < 3) { \ const uint16_t *_p = (const uint16_t *)cptr - 1; \ const uint16_t *_start = (const uint16_t *)cbuf_start; \ c = *_p; \ if (is_lo_surrogate(c) && cbuf_type == 2) { \ if (_p > _start && is_hi_surrogate(_p[-1])) { \ c = from_surrogate(*--_p, c); \ } \ } \ cptr = (const void *)_p; \ } else { \ const uint8_t *__cpt2 = cptr; \ while (cptr > cbuf_start && ((*(--cptr) >> 6) == 2)) \ ; \ c = unicode_from_utf8(cptr, __cpt2 - cptr, &__cpt2); \ } \ } while (0) #define PREV_CHAR(cptr, cbuf_start, cbuf_type) \ do { \ if (cbuf_type == 0) { \ cptr--; \ } else if (cbuf_type < 3) { \ const uint16_t *_p = (const uint16_t *)cptr - 1; \ const uint16_t *_start = (const uint16_t *)cbuf_start; \ if (is_lo_surrogate(*_p) && cbuf_type == 2) { \ if (_p > _start && is_hi_surrogate(_p[-1])) { \ --_p; \ } \ } \ cptr = (const void *)_p; \ } else { \ while (cptr > cbuf_start && (*(--cptr) >> 6) == 2) \ ; \ } \ } while (0) typedef enum { RE_EXEC_STATE_SPLIT, RE_EXEC_STATE_LOOKAHEAD, RE_EXEC_STATE_NEGATIVE_LOOKAHEAD, } REExecStateEnum; #if INTPTR_MAX >= INT64_MAX #define BP_TYPE_BITS 3 #else #define BP_TYPE_BITS 2 #endif typedef union { uint8_t *ptr; intptr_t val; /* for bp, the low BP_SHIFT bits store REExecStateEnum */ struct { uintptr_t val : sizeof(uintptr_t) * 8 - BP_TYPE_BITS; uintptr_t type : BP_TYPE_BITS; } bp; } StackElem; typedef struct { const uint8_t *cbuf; const uint8_t *cbuf_end; /* 0 = 8 bit chars, 1 = 16 bit chars, 2 = 16 bit chars, UTF-16, 3 = 8 bit chars, UTF-8 */ int cbuf_type; int capture_count; BOOL is_unicode; int interrupt_counter; void *opaque; /* used for stack overflow check */ StackElem *stack_buf; size_t stack_size; StackElem static_stack_buf[32]; /* static stack to avoid allocation in most cases */ } REExecContext; static int lre_poll_timeout(REExecContext *s) { if (unlikely(--s->interrupt_counter <= 0)) { s->interrupt_counter = INTERRUPT_COUNTER_INIT; if (lre_check_timeout(s->opaque)) return LRE_RET_TIMEOUT; } return 0; } static no_inline int stack_realloc(REExecContext *s, size_t n) { StackElem *new_stack; size_t new_size; new_size = s->stack_size * 3 / 2; if (new_size < n) new_size = n; if (s->stack_buf == s->static_stack_buf) { new_stack = lre_realloc(s->opaque, NULL, new_size * sizeof(StackElem)); if (!new_stack) return -1; /* XXX: could use correct size */ memcpy(new_stack, s->stack_buf, s->stack_size * sizeof(StackElem)); } else { new_stack = lre_realloc(s->opaque, s->stack_buf, new_size * sizeof(StackElem)); if (!new_stack) return -1; } s->stack_size = new_size; s->stack_buf = new_stack; return 0; } /* return 1 if match, 0 if not match or < 0 if error. */ static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture, const uint8_t *pc, const uint8_t *cptr) { int opcode; int cbuf_type; uint32_t val, c, idx; const uint8_t *cbuf_end; StackElem *sp, *bp, *stack_end; #ifdef DUMP_EXEC const uint8_t *pc_start = pc; /* TEST */ #endif cbuf_type = s->cbuf_type; cbuf_end = s->cbuf_end; sp = s->stack_buf; bp = s->stack_buf; stack_end = s->stack_buf + s->stack_size; #define CHECK_STACK_SPACE(n) \ if (unlikely((stack_end - sp) < (n))) { \ size_t saved_sp = sp - s->stack_buf; \ size_t saved_bp = bp - s->stack_buf; \ if (stack_realloc(s, sp - s->stack_buf + (n))) \ return LRE_RET_MEMORY_ERROR; \ stack_end = s->stack_buf + s->stack_size; \ sp = s->stack_buf + saved_sp; \ bp = s->stack_buf + saved_bp; \ } /* XXX: could test if the value was saved to reduce the stack size but slower */ #define SAVE_CAPTURE(idx, value) \ { \ CHECK_STACK_SPACE(2); \ sp[0].val = idx; \ sp[1].ptr = capture[idx]; \ sp += 2; \ capture[idx] = (value); \ } /* avoid saving the previous value if already saved */ #define SAVE_CAPTURE_CHECK(idx, value) \ { \ StackElem *sp1; \ sp1 = sp; \ for(;;) { \ if (sp1 > bp) { \ if (sp1[-2].val == idx) \ break; \ sp1 -= 2; \ } else { \ CHECK_STACK_SPACE(2); \ sp[0].val = idx; \ sp[1].ptr = capture[idx]; \ sp += 2; \ break; \ } \ } \ capture[idx] = (value); \ } #ifdef DUMP_EXEC printf("%5s %5s %5s %5s %s\n", "PC", "CP", "BP", "SP", "OPCODE"); #endif for(;;) { opcode = *pc++; #ifdef DUMP_EXEC printf("%5ld %5ld %5ld %5ld %s\n", pc - 1 - pc_start, cbuf_type == 0 ? cptr - s->cbuf : (cptr - s->cbuf) / 2, bp - s->stack_buf, sp - s->stack_buf, reopcode_info[opcode].name); #endif switch(opcode) { case REOP_match: return 1; no_match: for(;;) { REExecStateEnum type; if (bp == s->stack_buf) return 0; /* undo the modifications to capture[] */ while (sp > bp) { capture[sp[-2].val] = sp[-1].ptr; sp -= 2; } pc = sp[-3].ptr; cptr = sp[-2].ptr; type = sp[-1].bp.type; bp = s->stack_buf + sp[-1].bp.val; sp -= 3; if (type != RE_EXEC_STATE_LOOKAHEAD) break; } if (lre_poll_timeout(s)) return LRE_RET_TIMEOUT; break; case REOP_lookahead_match: /* pop all the saved states until reaching the start of the lookahead and keep the updated captures and variables and the corresponding undo info. */ { StackElem *sp1, *sp_top, *next_sp; REExecStateEnum type; sp_top = sp; for(;;) { sp1 = sp; sp = bp; pc = sp[-3].ptr; cptr = sp[-2].ptr; type = sp[-1].bp.type; bp = s->stack_buf + sp[-1].bp.val; sp[-1].ptr = (void *)sp1; /* save the next value for the copy step */ sp -= 3; if (type == RE_EXEC_STATE_LOOKAHEAD) break; } if (sp != s->stack_buf) { /* keep the undo info if there is a saved state */ sp1 = sp; while (sp1 < sp_top) { next_sp = (void *)sp1[2].ptr; sp1 += 3; while (sp1 < next_sp) *sp++ = *sp1++; } } } break; case REOP_negative_lookahead_match: /* pop all the saved states until reaching start of the negative lookahead */ for(;;) { REExecStateEnum type; type = bp[-1].bp.type; /* undo the modifications to capture[] */ while (sp > bp) { capture[sp[-2].val] = sp[-1].ptr; sp -= 2; } pc = sp[-3].ptr; cptr = sp[-2].ptr; type = sp[-1].bp.type; bp = s->stack_buf + sp[-1].bp.val; sp -= 3; if (type == RE_EXEC_STATE_NEGATIVE_LOOKAHEAD) break; } goto no_match; case REOP_char32: case REOP_char32_i: val = get_u32(pc); pc += 4; goto test_char; case REOP_char: case REOP_char_i: val = get_u16(pc); pc += 2; test_char: if (cptr >= cbuf_end) goto no_match; GET_CHAR(c, cptr, cbuf_end, cbuf_type); if (opcode == REOP_char_i || opcode == REOP_char32_i) { c = lre_canonicalize(c, s->is_unicode); } if (val != c) goto no_match; break; case REOP_split_goto_first: case REOP_split_next_first: { const uint8_t *pc1; val = get_u32(pc); pc += 4; if (opcode == REOP_split_next_first) { pc1 = pc + (int)val; } else { pc1 = pc; pc = pc + (int)val; } CHECK_STACK_SPACE(3); sp[0].ptr = (uint8_t *)pc1; sp[1].ptr = (uint8_t *)cptr; sp[2].bp.val = bp - s->stack_buf; sp[2].bp.type = RE_EXEC_STATE_SPLIT; sp += 3; bp = sp; } break; case REOP_lookahead: case REOP_negative_lookahead: val = get_u32(pc); pc += 4; CHECK_STACK_SPACE(3); sp[0].ptr = (uint8_t *)(pc + (int)val); sp[1].ptr = (uint8_t *)cptr; sp[2].bp.val = bp - s->stack_buf; sp[2].bp.type = RE_EXEC_STATE_LOOKAHEAD + opcode - REOP_lookahead; sp += 3; bp = sp; break; case REOP_goto: val = get_u32(pc); pc += 4 + (int)val; if (lre_poll_timeout(s)) return LRE_RET_TIMEOUT; break; case REOP_line_start: case REOP_line_start_m: if (cptr == s->cbuf) break; if (opcode == REOP_line_start) goto no_match; PEEK_PREV_CHAR(c, cptr, s->cbuf, cbuf_type); if (!is_line_terminator(c)) goto no_match; break; case REOP_line_end: case REOP_line_end_m: if (cptr == cbuf_end) break; if (opcode == REOP_line_end) goto no_match; PEEK_CHAR(c, cptr, cbuf_end, cbuf_type); if (!is_line_terminator(c)) goto no_match; break; case REOP_dot: if (cptr == cbuf_end) goto no_match; GET_CHAR(c, cptr, cbuf_end, cbuf_type); if (is_line_terminator(c)) goto no_match; break; case REOP_any: if (cptr == cbuf_end) goto no_match; GET_CHAR(c, cptr, cbuf_end, cbuf_type); break; case REOP_space: if (cptr == cbuf_end) goto no_match; GET_CHAR(c, cptr, cbuf_end, cbuf_type); if (!lre_is_space(c)) goto no_match; break; case REOP_not_space: if (cptr == cbuf_end) goto no_match; GET_CHAR(c, cptr, cbuf_end, cbuf_type); if (lre_is_space(c)) goto no_match; break; case REOP_save_start: case REOP_save_end: val = *pc++; assert(val < s->capture_count); idx = 2 * val + opcode - REOP_save_start; SAVE_CAPTURE(idx, (uint8_t *)cptr); break; case REOP_save_reset: { uint32_t val2; val = pc[0]; val2 = pc[1]; pc += 2; assert(val2 < s->capture_count); CHECK_STACK_SPACE(2 * (val2 - val + 1)); while (val <= val2) { idx = 2 * val; SAVE_CAPTURE(idx, NULL); idx = 2 * val + 1; SAVE_CAPTURE(idx, NULL); val++; } } break; case REOP_set_i32: idx = 2 * s->capture_count + pc[0]; val = get_u32(pc + 1); pc += 5; SAVE_CAPTURE_CHECK(idx, (void *)(uintptr_t)val); break; case REOP_loop: { uint32_t val2; idx = 2 * s->capture_count + pc[0]; val = get_u32(pc + 1); pc += 5; val2 = (uintptr_t)capture[idx] - 1; SAVE_CAPTURE_CHECK(idx, (void *)(uintptr_t)val2); if (val2 != 0) { pc += (int)val; if (lre_poll_timeout(s)) return LRE_RET_TIMEOUT; } } break; case REOP_loop_split_goto_first: case REOP_loop_split_next_first: case REOP_loop_check_adv_split_goto_first: case REOP_loop_check_adv_split_next_first: { const uint8_t *pc1; uint32_t val2, limit; idx = 2 * s->capture_count + pc[0]; limit = get_u32(pc + 1); val = get_u32(pc + 5); pc += 9; /* decrement the counter */ val2 = (uintptr_t)capture[idx] - 1; SAVE_CAPTURE_CHECK(idx, (void *)(uintptr_t)val2); if (val2 > limit) { /* normal loop if counter > limit */ pc += (int)val; if (lre_poll_timeout(s)) return LRE_RET_TIMEOUT; } else { /* check advance */ if ((opcode == REOP_loop_check_adv_split_goto_first || opcode == REOP_loop_check_adv_split_next_first) && capture[idx + 1] == cptr && val2 != limit) { goto no_match; } /* otherwise conditional split */ if (val2 != 0) { if (opcode == REOP_loop_split_next_first || opcode == REOP_loop_check_adv_split_next_first) { pc1 = pc + (int)val; } else { pc1 = pc; pc = pc + (int)val; } CHECK_STACK_SPACE(3); sp[0].ptr = (uint8_t *)pc1; sp[1].ptr = (uint8_t *)cptr; sp[2].bp.val = bp - s->stack_buf; sp[2].bp.type = RE_EXEC_STATE_SPLIT; sp += 3; bp = sp; } } } break; case REOP_set_char_pos: idx = 2 * s->capture_count + pc[0]; pc++; SAVE_CAPTURE_CHECK(idx, (uint8_t *)cptr); break; case REOP_check_advance: idx = 2 * s->capture_count + pc[0]; pc++; if (capture[idx] == cptr) goto no_match; break; case REOP_word_boundary: case REOP_word_boundary_i: case REOP_not_word_boundary: case REOP_not_word_boundary_i: { BOOL v1, v2; int ignore_case = (opcode == REOP_word_boundary_i || opcode == REOP_not_word_boundary_i); BOOL is_boundary = (opcode == REOP_word_boundary || opcode == REOP_word_boundary_i); /* char before */ if (cptr == s->cbuf) { v1 = FALSE; } else { PEEK_PREV_CHAR(c, cptr, s->cbuf, cbuf_type); if (c < 256) { v1 = (lre_is_word_byte(c) != 0); } else { v1 = ignore_case && (c == 0x017f || c == 0x212a); } } /* current char */ if (cptr >= cbuf_end) { v2 = FALSE; } else { PEEK_CHAR(c, cptr, cbuf_end, cbuf_type); if (c < 256) { v2 = (lre_is_word_byte(c) != 0); } else { v2 = ignore_case && (c == 0x017f || c == 0x212a); } } if (v1 ^ v2 ^ is_boundary) goto no_match; } break; case REOP_back_reference: case REOP_back_reference_i: case REOP_backward_back_reference: case REOP_backward_back_reference_i: { const uint8_t *cptr1, *cptr1_end, *cptr1_start; const uint8_t *pc1; uint32_t c1, c2; int i, n; n = *pc++; pc1 = pc; pc += n; for(i = 0; i < n; i++) { val = pc1[i]; if (val >= s->capture_count) goto no_match; cptr1_start = capture[2 * val]; cptr1_end = capture[2 * val + 1]; /* test the first not empty capture */ if (cptr1_start && cptr1_end) { if (opcode == REOP_back_reference || opcode == REOP_back_reference_i) { cptr1 = cptr1_start; while (cptr1 < cptr1_end) { if (cptr >= cbuf_end) goto no_match; GET_CHAR(c1, cptr1, cptr1_end, cbuf_type); GET_CHAR(c2, cptr, cbuf_end, cbuf_type); if (opcode == REOP_back_reference_i) { c1 = lre_canonicalize(c1, s->is_unicode); c2 = lre_canonicalize(c2, s->is_unicode); } if (c1 != c2) goto no_match; } } else { cptr1 = cptr1_end; while (cptr1 > cptr1_start) { if (cptr == s->cbuf) goto no_match; GET_PREV_CHAR(c1, cptr1, cptr1_start, cbuf_type); GET_PREV_CHAR(c2, cptr, s->cbuf, cbuf_type); if (opcode == REOP_backward_back_reference_i) { c1 = lre_canonicalize(c1, s->is_unicode); c2 = lre_canonicalize(c2, s->is_unicode); } if (c1 != c2) goto no_match; } } break; } } } break; case REOP_range: case REOP_range_i: { int n; uint32_t low, high, idx_min, idx_max, idx; n = get_u16(pc); /* n must be >= 1 */ pc += 2; if (cptr >= cbuf_end) goto no_match; GET_CHAR(c, cptr, cbuf_end, cbuf_type); if (opcode == REOP_range_i) { c = lre_canonicalize(c, s->is_unicode); } idx_min = 0; low = get_u16(pc + 0 * 4); if (c < low) goto no_match; idx_max = n - 1; high = get_u16(pc + idx_max * 4 + 2); /* 0xffff in for last value means +infinity */ if (unlikely(c >= 0xffff) && high == 0xffff) goto range_match; if (c > high) goto no_match; while (idx_min <= idx_max) { idx = (idx_min + idx_max) / 2; low = get_u16(pc + idx * 4); high = get_u16(pc + idx * 4 + 2); if (c < low) idx_max = idx - 1; else if (c > high) idx_min = idx + 1; else goto range_match; } goto no_match; range_match: pc += 4 * n; } break; case REOP_range32: case REOP_range32_i: { int n; uint32_t low, high, idx_min, idx_max, idx; n = get_u16(pc); /* n must be >= 1 */ pc += 2; if (cptr >= cbuf_end) goto no_match; GET_CHAR(c, cptr, cbuf_end, cbuf_type); if (opcode == REOP_range32_i) { c = lre_canonicalize(c, s->is_unicode); } idx_min = 0; low = get_u32(pc + 0 * 8); if (c < low) goto no_match; idx_max = n - 1; high = get_u32(pc + idx_max * 8 + 4); if (c > high) goto no_match; while (idx_min <= idx_max) { idx = (idx_min + idx_max) / 2; low = get_u32(pc + idx * 8); high = get_u32(pc + idx * 8 + 4); if (c < low) idx_max = idx - 1; else if (c > high) idx_min = idx + 1; else goto range32_match; } goto no_match; range32_match: pc += 8 * n; } break; case REOP_prev: /* go to the previous char */ if (cptr == s->cbuf) goto no_match; PREV_CHAR(cptr, s->cbuf, cbuf_type); break; default: #ifdef DUMP_EXEC printf("unknown opcode pc=%ld\n", pc - 1 - pc_start); #endif abort(); } } } /* Return 1 if match, 0 if not match or < 0 if error (see LRE_RET_x). cindex is the starting position of the match and must be such as 0 <= cindex <= clen. */ int lre_exec(uint8_t **capture, const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen, int cbuf_type, void *opaque) { REExecContext s_s, *s = &s_s; int re_flags, i, ret, cbuf_width = cbuf_type; const uint8_t *cptr; if (cbuf_width == 3) /* UTF-8 */ cbuf_width = 0; re_flags = lre_get_flags(bc_buf); s->is_unicode = (re_flags & (LRE_FLAG_UNICODE | LRE_FLAG_UNICODE_SETS)) != 0; s->capture_count = bc_buf[RE_HEADER_CAPTURE_COUNT]; s->cbuf = cbuf; s->cbuf_end = cbuf + (clen << cbuf_width); s->cbuf_type = cbuf_type; if (s->cbuf_type == 1 && s->is_unicode) s->cbuf_type = 2; s->interrupt_counter = INTERRUPT_COUNTER_INIT; s->opaque = opaque; s->stack_buf = s->static_stack_buf; s->stack_size = countof(s->static_stack_buf); for(i = 0; i < s->capture_count * 2; i++) capture[i] = NULL; cptr = cbuf + (cindex << cbuf_width); if (0 < cindex && cindex < clen && s->cbuf_type == 2) { const uint16_t *p = (const uint16_t *)cptr; if (is_lo_surrogate(*p) && is_hi_surrogate(p[-1])) { cptr = (const uint8_t *)(p - 1); } } ret = lre_exec_backtrack(s, capture, bc_buf + RE_HEADER_LEN, cptr); if (s->stack_buf != s->static_stack_buf) lre_realloc(s->opaque, s->stack_buf, 0); return ret; } int lre_get_alloc_count(const uint8_t *bc_buf) { return bc_buf[RE_HEADER_CAPTURE_COUNT] * 2 + bc_buf[RE_HEADER_REGISTER_COUNT]; } int lre_get_capture_count(const uint8_t *bc_buf) { return bc_buf[RE_HEADER_CAPTURE_COUNT]; } int lre_get_flags(const uint8_t *bc_buf) { return get_u16(bc_buf + RE_HEADER_FLAGS); } /* Return NULL if no group names. Otherwise, return a pointer to 'capture_count - 1' zero terminated UTF-8 strings. */ const char *lre_get_groupnames(const uint8_t *bc_buf) { uint32_t re_bytecode_len; if ((lre_get_flags(bc_buf) & LRE_FLAG_NAMED_GROUPS) == 0) return NULL; re_bytecode_len = get_u32(bc_buf + RE_HEADER_BYTECODE_LEN); return (const char *)(bc_buf + RE_HEADER_LEN + re_bytecode_len); } #ifdef TEST BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size) { return FALSE; } void *lre_realloc(void *opaque, void *ptr, size_t size) { return realloc(ptr, size); } int main(int argc, char **argv) { int len, flags, ret, i; uint8_t *bc; char error_msg[64]; uint8_t *capture; const char *input; int input_len, capture_count; if (argc < 4) { printf("usage: %s regexp flags input\n", argv[0]); return 1; } flags = atoi(argv[2]); bc = lre_compile(&len, error_msg, sizeof(error_msg), argv[1], strlen(argv[1]), flags, NULL); if (!bc) { fprintf(stderr, "error: %s\n", error_msg); exit(1); } input = argv[3]; input_len = strlen(input); capture = malloc(sizeof(capture[0]) * lre_get_alloc_count(bc)); ret = lre_exec(capture, bc, (uint8_t *)input, 0, input_len, 0, NULL); printf("ret=%d\n", ret); if (ret == 1) { capture_count = lre_get_capture_count(bc); for(i = 0; i < 2 * capture_count; i++) { uint8_t *ptr; ptr = capture[i]; printf("%d: ", i); if (!ptr) printf("<nil>"); else printf("%u", (int)(ptr - (uint8_t *)input)); printf("\n"); } } free(capture); return 0; } #endif �����������������������������chawan-v0.4.0/lib/monoucha0/monoucha/qjs/libregexp.h������������������������������������������������0000664�0000000�0000000�00000005261�15202323131�0022335�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Regular Expression Engine * * Copyright (c) 2017-2018 Fabrice Bellard * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #ifndef LIBREGEXP_H #define LIBREGEXP_H #include <stddef.h> #include <stdint.h> #define LRE_FLAG_GLOBAL (1 << 0) #define LRE_FLAG_IGNORECASE (1 << 1) #define LRE_FLAG_MULTILINE (1 << 2) #define LRE_FLAG_DOTALL (1 << 3) #define LRE_FLAG_UNICODE (1 << 4) #define LRE_FLAG_STICKY (1 << 5) #define LRE_FLAG_INDICES (1 << 6) /* Unused by libregexp, just recorded. */ #define LRE_FLAG_NAMED_GROUPS (1 << 7) /* named groups are present in the regexp */ #define LRE_FLAG_UNICODE_SETS (1 << 8) #define LRE_RET_MEMORY_ERROR (-1) #define LRE_RET_TIMEOUT (-2) /* trailer length after the group name including the trailing '\0' */ #define LRE_GROUP_NAME_TRAILER_LEN 2 uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size, const char *buf, size_t buf_len, int re_flags, void *opaque); int lre_get_alloc_count(const uint8_t *bc_buf); int lre_get_capture_count(const uint8_t *bc_buf); int lre_get_flags(const uint8_t *bc_buf); const char *lre_get_groupnames(const uint8_t *bc_buf); int lre_exec(uint8_t **capture, const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen, int cbuf_type, void *opaque); int lre_parse_escape(const uint8_t **pp, int allow_utf16); /* must be provided by the user, return non zero if overflow */ int lre_check_stack_overflow(void *opaque, size_t alloca_size); /* must be provided by the user, return non zero if time out */ int lre_check_timeout(void *opaque); void *lre_realloc(void *opaque, void *ptr, size_t size); #endif /* LIBREGEXP_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/qjs/libunicode-table.h�����������������������������������������0000664�0000000�0000000�00000755114�15202323131�0023567�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Compressed unicode tables */ /* Automatically generated file - do not edit */ #include <stdint.h> static const uint32_t case_conv_table1[378] = { 0x00209a30, 0x00309a00, 0x005a8173, 0x00601730, 0x006c0730, 0x006f81b3, 0x00701700, 0x007c0700, 0x007f8100, 0x00803040, 0x009801c3, 0x00988190, 0x00990640, 0x009c9040, 0x00a481b4, 0x00a52e40, 0x00bc0130, 0x00bc8640, 0x00bf8170, 0x00c00100, 0x00c08130, 0x00c10440, 0x00c30130, 0x00c38240, 0x00c48230, 0x00c58240, 0x00c70130, 0x00c78130, 0x00c80130, 0x00c88240, 0x00c98130, 0x00ca0130, 0x00ca8100, 0x00cb0130, 0x00cb8130, 0x00cc0240, 0x00cd0100, 0x00cd8101, 0x00ce0130, 0x00ce8130, 0x00cf0100, 0x00cf8130, 0x00d00640, 0x00d30130, 0x00d38240, 0x00d48130, 0x00d60240, 0x00d70130, 0x00d78240, 0x00d88230, 0x00d98440, 0x00db8130, 0x00dc0240, 0x00de0240, 0x00df8100, 0x00e20350, 0x00e38350, 0x00e50350, 0x00e69040, 0x00ee8100, 0x00ef1240, 0x00f801b4, 0x00f88350, 0x00fa0240, 0x00fb0130, 0x00fb8130, 0x00fc2840, 0x01100130, 0x01111240, 0x011d0131, 0x011d8240, 0x011e8130, 0x011f0131, 0x011f8201, 0x01208240, 0x01218130, 0x01220130, 0x01228130, 0x01230a40, 0x01280101, 0x01288101, 0x01290101, 0x01298100, 0x012a0100, 0x012b0200, 0x012c8100, 0x012d8100, 0x012e0101, 0x01300100, 0x01308101, 0x01318100, 0x01320101, 0x01328101, 0x01330101, 0x01340100, 0x01348100, 0x01350101, 0x01358101, 0x01360101, 0x01378100, 0x01388101, 0x01390100, 0x013a8100, 0x013e8101, 0x01400100, 0x01410101, 0x01418100, 0x01438101, 0x01440100, 0x01448100, 0x01450200, 0x01460100, 0x01490100, 0x014e8101, 0x014f0101, 0x01a28173, 0x01b80440, 0x01bb0240, 0x01bd8300, 0x01bf8130, 0x01c30130, 0x01c40330, 0x01c60130, 0x01c70230, 0x01c801d0, 0x01c89130, 0x01d18930, 0x01d60100, 0x01d68300, 0x01d801d3, 0x01d89100, 0x01e10173, 0x01e18900, 0x01e60100, 0x01e68200, 0x01e78130, 0x01e80173, 0x01e88173, 0x01ea8173, 0x01eb0173, 0x01eb8100, 0x01ec1840, 0x01f80173, 0x01f88173, 0x01f90100, 0x01f98100, 0x01fa01a0, 0x01fa8173, 0x01fb8240, 0x01fc8130, 0x01fd0240, 0x01fe8330, 0x02001030, 0x02082030, 0x02182000, 0x02281000, 0x02302240, 0x02453640, 0x02600130, 0x02608e40, 0x02678100, 0x02686040, 0x0298a630, 0x02b0a600, 0x02c381b5, 0x08502631, 0x08638131, 0x08668131, 0x08682b00, 0x087e8300, 0x09d05011, 0x09f80610, 0x09fc0620, 0x0e400174, 0x0e408174, 0x0e410174, 0x0e418174, 0x0e420174, 0x0e428174, 0x0e430174, 0x0e438180, 0x0e440180, 0x0e448240, 0x0e482b30, 0x0e5e8330, 0x0ebc8101, 0x0ebe8101, 0x0ec70101, 0x0f007e40, 0x0f3f1840, 0x0f4b01b5, 0x0f4b81b6, 0x0f4c01b6, 0x0f4c81b6, 0x0f4d01b7, 0x0f4d8180, 0x0f4f0130, 0x0f506040, 0x0f800800, 0x0f840830, 0x0f880600, 0x0f8c0630, 0x0f900800, 0x0f940830, 0x0f980800, 0x0f9c0830, 0x0fa00600, 0x0fa40630, 0x0fa801b0, 0x0fa88100, 0x0fa901d3, 0x0fa98100, 0x0faa01d3, 0x0faa8100, 0x0fab01d3, 0x0fab8100, 0x0fac8130, 0x0fad8130, 0x0fae8130, 0x0faf8130, 0x0fb00800, 0x0fb40830, 0x0fb80200, 0x0fb90400, 0x0fbb0201, 0x0fbc0201, 0x0fbd0201, 0x0fbe0201, 0x0fc008b7, 0x0fc40867, 0x0fc808b8, 0x0fcc0868, 0x0fd008b8, 0x0fd40868, 0x0fd80200, 0x0fd901b9, 0x0fd981b1, 0x0fda01b9, 0x0fdb01b1, 0x0fdb81d7, 0x0fdc0230, 0x0fdd0230, 0x0fde0161, 0x0fdf0173, 0x0fe101b9, 0x0fe181b2, 0x0fe201ba, 0x0fe301b2, 0x0fe381d8, 0x0fe40430, 0x0fe60162, 0x0fe80201, 0x0fe901d0, 0x0fe981d0, 0x0feb01b0, 0x0feb81d0, 0x0fec0230, 0x0fed0230, 0x0ff00201, 0x0ff101d3, 0x0ff181d3, 0x0ff201ba, 0x0ff28101, 0x0ff301b0, 0x0ff381d3, 0x0ff40231, 0x0ff50230, 0x0ff60131, 0x0ff901ba, 0x0ff981b2, 0x0ffa01bb, 0x0ffb01b2, 0x0ffb81d9, 0x0ffc0230, 0x0ffd0230, 0x0ffe0162, 0x109301a0, 0x109501a0, 0x109581a0, 0x10990131, 0x10a70101, 0x10b01031, 0x10b81001, 0x10c18240, 0x125b1a31, 0x12681a01, 0x16003031, 0x16183001, 0x16300240, 0x16310130, 0x16318130, 0x16320130, 0x16328100, 0x16330100, 0x16338640, 0x16368130, 0x16370130, 0x16378130, 0x16380130, 0x16390240, 0x163a8240, 0x163f0230, 0x16406440, 0x16758440, 0x16790240, 0x16802600, 0x16938100, 0x16968100, 0x53202e40, 0x53401c40, 0x53910e40, 0x53993e40, 0x53bc8440, 0x53be8130, 0x53bf0a40, 0x53c58240, 0x53c68130, 0x53c80440, 0x53ca0101, 0x53cb1440, 0x53d50130, 0x53d58130, 0x53d60130, 0x53d68130, 0x53d70130, 0x53d80130, 0x53d88130, 0x53d90130, 0x53d98131, 0x53da1040, 0x53e20131, 0x53e28130, 0x53e30130, 0x53e38440, 0x53e58130, 0x53e61040, 0x53ee0130, 0x53fa8240, 0x55a98101, 0x55b85020, 0x7d8001b2, 0x7d8081b2, 0x7d8101b2, 0x7d8181da, 0x7d8201da, 0x7d8281b3, 0x7d8301b3, 0x7d8981bb, 0x7d8a01bb, 0x7d8a81bb, 0x7d8b01bc, 0x7d8b81bb, 0x7f909a31, 0x7fa09a01, 0x82002831, 0x82142801, 0x82582431, 0x826c2401, 0x82b80b31, 0x82be0f31, 0x82c60731, 0x82ca0231, 0x82cb8b01, 0x82d18f01, 0x82d98701, 0x82dd8201, 0x86403331, 0x86603301, 0x86a81631, 0x86b81601, 0x8c502031, 0x8c602001, 0xb7202031, 0xb7302001, 0xb7501931, 0xb75d9901, 0xf4802231, 0xf4912201, }; static const uint8_t case_conv_table2[378] = { 0x01, 0x00, 0x9c, 0x06, 0x07, 0x4d, 0x03, 0x04, 0x10, 0x00, 0x8f, 0x0b, 0x00, 0x00, 0x11, 0x00, 0x08, 0x00, 0x53, 0x4b, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x3b, 0x55, 0x56, 0x00, 0x58, 0x5a, 0x40, 0x5f, 0x5e, 0x00, 0x47, 0x50, 0x63, 0x65, 0x43, 0x66, 0x00, 0x68, 0x00, 0x6a, 0x00, 0x6c, 0x00, 0x6e, 0x00, 0x70, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x93, 0x00, 0x00, 0x20, 0x36, 0x00, 0x28, 0x00, 0x24, 0x00, 0x24, 0x25, 0x2d, 0x00, 0x13, 0x6d, 0x6f, 0x00, 0x29, 0x27, 0x2a, 0x14, 0x16, 0x18, 0x1b, 0x1c, 0x41, 0x1e, 0x42, 0x1f, 0x4e, 0x3c, 0x40, 0x22, 0x21, 0x44, 0x21, 0x43, 0x26, 0x28, 0x27, 0x29, 0x23, 0x2b, 0x4b, 0x2d, 0x46, 0x2f, 0x4c, 0x31, 0x4d, 0x33, 0x47, 0x45, 0x99, 0x00, 0x00, 0x97, 0x91, 0x7f, 0x80, 0x85, 0x86, 0x12, 0x82, 0x84, 0x78, 0x79, 0x12, 0x7d, 0xa3, 0x7e, 0x7a, 0x7b, 0x8c, 0x92, 0x98, 0xa6, 0xa0, 0x87, 0x00, 0x9a, 0xa1, 0x95, 0x77, 0x33, 0x95, 0x00, 0x90, 0x00, 0x76, 0x9b, 0x9a, 0x99, 0x98, 0x00, 0x00, 0xa0, 0x00, 0x9e, 0x00, 0xa3, 0xa2, 0x15, 0x31, 0x32, 0x33, 0xb7, 0xb8, 0x53, 0xac, 0xab, 0x12, 0x14, 0x1e, 0x21, 0x22, 0x22, 0x2a, 0x34, 0x35, 0x00, 0xa8, 0xa9, 0x39, 0x22, 0x4c, 0x00, 0x00, 0x97, 0x01, 0x5a, 0xda, 0x1d, 0x36, 0x05, 0x00, 0xc7, 0xc6, 0xc9, 0xc8, 0xcb, 0xca, 0xcd, 0xcc, 0xcf, 0xce, 0xc4, 0xd8, 0x45, 0xd9, 0x42, 0xda, 0x46, 0xdb, 0xd1, 0xd3, 0xd5, 0xd7, 0xdd, 0xdc, 0xf1, 0xf9, 0x01, 0x11, 0x0a, 0x12, 0x80, 0x9f, 0x00, 0x21, 0x80, 0xa3, 0xf0, 0x00, 0xc0, 0x40, 0xc6, 0x60, 0xea, 0xde, 0xe6, 0x99, 0xc0, 0x00, 0x00, 0x06, 0x60, 0xdf, 0x29, 0x00, 0x15, 0x12, 0x06, 0x16, 0xfb, 0xe0, 0x09, 0x15, 0x12, 0x84, 0x0b, 0xc6, 0x16, 0x02, 0xe2, 0x06, 0xc0, 0x40, 0x00, 0x46, 0x60, 0xe1, 0xe3, 0x6d, 0x37, 0x38, 0x39, 0x18, 0x17, 0x1a, 0x19, 0x00, 0x1d, 0x1c, 0x1f, 0x1e, 0x00, 0x61, 0xba, 0x67, 0x45, 0x48, 0x00, 0x50, 0x64, 0x4f, 0x51, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0xa5, 0xa6, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x5c, 0x00, 0x4a, 0x00, 0x5d, 0x57, 0x59, 0x62, 0x60, 0x72, 0x6b, 0x71, 0x52, 0x00, 0x3e, 0x69, 0xbb, 0x00, 0x5b, 0x00, 0x25, 0x00, 0x48, 0xaa, 0x8a, 0x8b, 0x8c, 0xab, 0xac, 0x58, 0x58, 0xaf, 0x94, 0xb0, 0x6f, 0xb2, 0x61, 0x60, 0x63, 0x62, 0x65, 0x64, 0x6a, 0x6b, 0x6c, 0x6d, 0x66, 0x67, 0x68, 0x69, 0x6f, 0x6e, 0x71, 0x70, 0x73, 0x72, 0x75, 0x74, 0x77, 0x76, 0x79, 0x78, }; static const uint16_t case_conv_ext[58] = { 0x0399, 0x0308, 0x0301, 0x03a5, 0x0313, 0x0300, 0x0342, 0x0391, 0x0397, 0x03a9, 0x0046, 0x0049, 0x004c, 0x0053, 0x0069, 0x0307, 0x02bc, 0x004e, 0x004a, 0x030c, 0x0535, 0x0552, 0x0048, 0x0331, 0x0054, 0x0057, 0x030a, 0x0059, 0x0041, 0x02be, 0x1f08, 0x1f80, 0x1f28, 0x1f90, 0x1f68, 0x1fa0, 0x1fba, 0x0386, 0x1fb3, 0x1fca, 0x0389, 0x1fc3, 0x03a1, 0x1ffa, 0x038f, 0x1ff3, 0x0544, 0x0546, 0x053b, 0x054e, 0x053d, 0x03b8, 0x0462, 0xa64a, 0x1e60, 0x03c9, 0x006b, 0x00e5, }; static const uint8_t unicode_prop_Cased1_table[190] = { 0x40, 0xa9, 0x80, 0x8e, 0x80, 0xfc, 0x80, 0xd3, 0x80, 0x9b, 0x81, 0x8d, 0x02, 0x80, 0xe1, 0x80, 0x91, 0x85, 0x9a, 0x01, 0x00, 0x01, 0x11, 0x03, 0x04, 0x08, 0x01, 0x08, 0x30, 0x08, 0x01, 0x15, 0x20, 0x01, 0x31, 0x99, 0x31, 0x9d, 0x84, 0x40, 0x94, 0x80, 0xd6, 0x82, 0xa6, 0x80, 0x41, 0x62, 0x80, 0xa6, 0x80, 0x4b, 0x72, 0x80, 0x4c, 0x02, 0xf8, 0x02, 0x80, 0x8f, 0x80, 0xb0, 0x40, 0xdb, 0x08, 0x80, 0x41, 0xd0, 0x80, 0x8c, 0x80, 0x8f, 0x8c, 0xe4, 0x03, 0x01, 0x89, 0x00, 0x14, 0x28, 0x10, 0x11, 0x02, 0x01, 0x18, 0x0b, 0x24, 0x4b, 0x26, 0x01, 0x01, 0x86, 0xe5, 0x80, 0x60, 0x79, 0xb6, 0x81, 0x40, 0x91, 0x81, 0xbd, 0x88, 0x94, 0x05, 0x80, 0x98, 0x80, 0xc0, 0x1a, 0x82, 0x43, 0x34, 0xa2, 0x06, 0x80, 0x8d, 0x60, 0x5c, 0x15, 0x01, 0x10, 0xa9, 0x80, 0x88, 0x60, 0xcc, 0x44, 0xd4, 0x80, 0xc6, 0x01, 0x08, 0x09, 0x0b, 0x80, 0x8b, 0x00, 0x06, 0x80, 0xc0, 0x03, 0x0f, 0x06, 0x80, 0x9b, 0x03, 0x04, 0x00, 0x16, 0x80, 0x41, 0x53, 0x81, 0x98, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x07, 0x47, 0x33, 0x89, 0x80, 0x93, 0x2d, 0x41, 0x04, 0xbd, 0x50, 0xc1, 0x99, 0x85, 0x99, 0x85, 0x99, }; static const uint8_t unicode_prop_Cased1_index[18] = { 0xb9, 0x02, 0x80, // 002B9 at 36 0xa0, 0x1e, 0x40, // 01EA0 at 66 0x9e, 0xa6, 0x40, // 0A69E at 98 0x55, 0xd4, 0x21, // 1D455 at 129 0x15, 0xd7, 0x21, // 1D715 at 161 0x8a, 0xf1, 0x01, // 1F18A at 192 (upper bound) }; static const uint8_t unicode_prop_Case_Ignorable_table[785] = { 0xa6, 0x05, 0x80, 0x8a, 0x80, 0xa2, 0x00, 0x80, 0xc6, 0x03, 0x00, 0x03, 0x01, 0x81, 0x41, 0xf6, 0x40, 0xbf, 0x19, 0x18, 0x88, 0x08, 0x80, 0x40, 0xfa, 0x86, 0x40, 0xce, 0x04, 0x80, 0xb0, 0xac, 0x00, 0x01, 0x01, 0x00, 0xab, 0x80, 0x8a, 0x85, 0x89, 0x8a, 0x00, 0xa2, 0x80, 0x89, 0x94, 0x8f, 0x80, 0xe4, 0x38, 0x89, 0x03, 0xa0, 0x00, 0x80, 0x9d, 0x9a, 0xda, 0x8a, 0xb9, 0x8a, 0x18, 0x08, 0x97, 0x97, 0xaa, 0x82, 0xab, 0x06, 0x0c, 0x88, 0xa8, 0xb9, 0xb6, 0x00, 0x03, 0x3b, 0x02, 0x86, 0x89, 0x81, 0x8c, 0x80, 0x8e, 0x80, 0xb9, 0x03, 0x1f, 0x80, 0x93, 0x81, 0x99, 0x01, 0x81, 0xb8, 0x03, 0x0b, 0x09, 0x12, 0x80, 0x9d, 0x0a, 0x80, 0x8a, 0x81, 0xb8, 0x03, 0x20, 0x0b, 0x80, 0x93, 0x81, 0x95, 0x28, 0x80, 0xb9, 0x01, 0x00, 0x1f, 0x06, 0x81, 0x8a, 0x81, 0x9d, 0x80, 0xbc, 0x80, 0x8b, 0x80, 0xb1, 0x02, 0x80, 0xb6, 0x00, 0x14, 0x10, 0x1e, 0x81, 0x8a, 0x81, 0x9c, 0x80, 0xb9, 0x01, 0x05, 0x04, 0x81, 0x93, 0x81, 0x9b, 0x81, 0xb8, 0x0b, 0x1f, 0x80, 0x93, 0x81, 0x9c, 0x80, 0xc7, 0x06, 0x10, 0x80, 0xd9, 0x01, 0x86, 0x8a, 0x88, 0xe1, 0x01, 0x88, 0x88, 0x00, 0x86, 0xc8, 0x81, 0x9a, 0x00, 0x00, 0x80, 0xb6, 0x8d, 0x04, 0x01, 0x84, 0x8a, 0x80, 0xa3, 0x88, 0x80, 0xe5, 0x18, 0x28, 0x09, 0x81, 0x98, 0x0b, 0x82, 0x8f, 0x83, 0x8c, 0x01, 0x0d, 0x80, 0x8e, 0x80, 0xdd, 0x80, 0x42, 0x5f, 0x82, 0x43, 0xb1, 0x82, 0x9c, 0x81, 0x9d, 0x81, 0x9d, 0x81, 0xbf, 0x08, 0x37, 0x01, 0x8a, 0x10, 0x20, 0xac, 0x84, 0xb2, 0x80, 0xc0, 0x81, 0xa1, 0x80, 0xf5, 0x13, 0x81, 0x88, 0x05, 0x82, 0x40, 0xda, 0x09, 0x80, 0xb9, 0x00, 0x30, 0x00, 0x01, 0x3d, 0x89, 0x08, 0xa6, 0x07, 0xad, 0x81, 0x8b, 0x93, 0x83, 0xaf, 0x00, 0x20, 0x04, 0x80, 0xa7, 0x88, 0x8b, 0x81, 0x9f, 0x19, 0x08, 0x82, 0xb7, 0x00, 0x0a, 0x00, 0x82, 0xb9, 0x39, 0x81, 0xbf, 0x85, 0xd1, 0x10, 0x8c, 0x06, 0x18, 0x28, 0x11, 0xb1, 0xbe, 0x8c, 0x80, 0xa1, 0xe4, 0x41, 0xbc, 0x00, 0x82, 0x8a, 0x82, 0x8c, 0x82, 0x8c, 0x82, 0x8c, 0x81, 0x8b, 0x27, 0x81, 0x89, 0x01, 0x01, 0x84, 0xb0, 0x20, 0x89, 0x00, 0x8c, 0x80, 0x8f, 0x8c, 0xb2, 0xa0, 0x4b, 0x8a, 0x81, 0xf0, 0x82, 0xfc, 0x80, 0x8e, 0x80, 0xdf, 0x9f, 0xae, 0x80, 0x41, 0xd4, 0x80, 0xa3, 0x1a, 0x24, 0x80, 0xdc, 0x85, 0xdc, 0x82, 0x60, 0x6f, 0x15, 0x80, 0x44, 0xe1, 0x85, 0x41, 0x0d, 0x80, 0xe1, 0x18, 0x89, 0x00, 0x9b, 0x83, 0xcf, 0x81, 0x8d, 0xa1, 0xcd, 0x80, 0x96, 0x82, 0xe5, 0x1a, 0x0f, 0x02, 0x03, 0x80, 0x98, 0x0c, 0x80, 0x40, 0x96, 0x81, 0x99, 0x91, 0x8c, 0x80, 0xa5, 0x87, 0x98, 0x8a, 0xad, 0x82, 0xaf, 0x01, 0x19, 0x81, 0x90, 0x80, 0x94, 0x81, 0xc1, 0x29, 0x09, 0x81, 0x8b, 0x07, 0x80, 0xa2, 0x80, 0x8a, 0x80, 0xb2, 0x00, 0x11, 0x0c, 0x08, 0x80, 0x9a, 0x80, 0x8d, 0x0c, 0x08, 0x80, 0xe3, 0x84, 0x88, 0x82, 0xf8, 0x01, 0x03, 0x80, 0x60, 0x4f, 0x2f, 0x80, 0x40, 0x92, 0x90, 0x42, 0x3c, 0x8f, 0x10, 0x8b, 0x8f, 0xa1, 0x01, 0x80, 0x40, 0xa8, 0x06, 0x05, 0x80, 0x8a, 0x80, 0xa2, 0x00, 0x80, 0xae, 0x80, 0xac, 0x81, 0xc2, 0x80, 0x94, 0x82, 0x42, 0x00, 0x80, 0x40, 0xe1, 0x80, 0x40, 0x94, 0x84, 0x44, 0x04, 0x28, 0xa9, 0x80, 0x88, 0x42, 0x45, 0x10, 0x0c, 0x83, 0xa7, 0x13, 0x80, 0x40, 0xa4, 0x81, 0x42, 0x3c, 0x83, 0xa5, 0x80, 0x99, 0x20, 0x80, 0x41, 0x3a, 0x81, 0x97, 0x80, 0xb3, 0x85, 0xc5, 0x8a, 0xb0, 0x83, 0xfa, 0x80, 0xb5, 0x8e, 0xa8, 0x01, 0x81, 0x89, 0x82, 0xb0, 0x19, 0x09, 0x03, 0x80, 0x89, 0x80, 0xb1, 0x82, 0xa3, 0x20, 0x87, 0xbd, 0x80, 0x8b, 0x81, 0xb3, 0x88, 0x89, 0x19, 0x80, 0xde, 0x11, 0x00, 0x0d, 0x01, 0x80, 0x40, 0x9c, 0x02, 0x87, 0x94, 0x81, 0xb8, 0x0a, 0x80, 0xa4, 0x32, 0x84, 0xc5, 0x85, 0x8c, 0x00, 0x00, 0x80, 0x8d, 0x81, 0xd4, 0x39, 0x10, 0x80, 0x96, 0x80, 0xd3, 0x28, 0x03, 0x08, 0x81, 0x40, 0xed, 0x1d, 0x08, 0x81, 0x9a, 0x81, 0xd4, 0x39, 0x00, 0x81, 0xe9, 0x00, 0x01, 0x28, 0x80, 0xe4, 0x00, 0x01, 0x18, 0x84, 0x41, 0x02, 0x88, 0x01, 0x40, 0xff, 0x08, 0x03, 0x80, 0x40, 0x8f, 0x19, 0x0b, 0x80, 0x9f, 0x89, 0xa7, 0x29, 0x1f, 0x80, 0x88, 0x29, 0x82, 0xad, 0x8c, 0x01, 0x40, 0xc5, 0x00, 0x10, 0x80, 0x40, 0xc8, 0x30, 0x28, 0x80, 0xd1, 0x95, 0x0e, 0x01, 0x01, 0xf9, 0x2a, 0x00, 0x08, 0x30, 0x80, 0xc7, 0x0a, 0x00, 0x80, 0xc0, 0x80, 0x41, 0x18, 0x81, 0x8a, 0x81, 0xb3, 0x24, 0x00, 0x80, 0x96, 0x80, 0x54, 0xd4, 0x90, 0x85, 0x8e, 0x60, 0x2c, 0xc7, 0x8b, 0x12, 0x49, 0xbf, 0x84, 0xba, 0x86, 0x88, 0x83, 0x41, 0xfb, 0x82, 0xa7, 0x81, 0x41, 0xe1, 0x80, 0xbe, 0x90, 0xbf, 0x08, 0x81, 0x8c, 0x81, 0x60, 0x3f, 0xfb, 0x18, 0x30, 0x81, 0x4c, 0x9d, 0x08, 0x83, 0x52, 0x5b, 0xad, 0x81, 0x96, 0x42, 0x1f, 0x82, 0x88, 0x8f, 0x0e, 0x9d, 0x83, 0x40, 0x93, 0x82, 0x47, 0xba, 0xb6, 0x83, 0xb1, 0x38, 0x8d, 0x80, 0x95, 0x20, 0x8e, 0x45, 0x4f, 0x30, 0x90, 0x0e, 0x01, 0x04, 0x84, 0xbd, 0xa0, 0x80, 0x40, 0x9f, 0x8d, 0x41, 0x6f, 0x80, 0xbc, 0x83, 0x41, 0xfa, 0x84, 0x40, 0xfd, 0x81, 0x40, 0xf2, 0x01, 0x06, 0x0c, 0x80, 0x88, 0x80, 0x41, 0xcf, 0x86, 0xec, 0x87, 0x4a, 0xae, 0x84, 0x6c, 0x0c, 0x00, 0x80, 0x9d, 0xdf, 0xff, 0x40, 0xef, }; static const uint8_t unicode_prop_Case_Ignorable_index[75] = { 0xbe, 0x05, 0x00, // 005BE at 32 0xfe, 0x07, 0x00, // 007FE at 64 0x52, 0x0a, 0xa0, // 00A52 at 101 0xc1, 0x0b, 0x00, // 00BC1 at 128 0x82, 0x0d, 0x00, // 00D82 at 160 0x3f, 0x10, 0x80, // 0103F at 196 0xd4, 0x17, 0x40, // 017D4 at 226 0xde, 0x1a, 0x20, // 01ADE at 257 0xe9, 0x1c, 0x00, // 01CE9 at 288 0x72, 0x20, 0x00, // 02072 at 320 0x16, 0xa0, 0x40, // 0A016 at 354 0xc6, 0xa8, 0x40, // 0A8C6 at 386 0xc2, 0xaa, 0xa0, // 0AAC2 at 421 0x30, 0xfe, 0x00, // 0FE30 at 448 0xb1, 0x07, 0x41, // 107B1 at 482 0x51, 0x0f, 0x01, // 10F51 at 512 0xd0, 0x11, 0x01, // 111D0 at 544 0x5f, 0x14, 0x01, // 1145F at 576 0x44, 0x19, 0x61, // 11944 at 611 0xa8, 0x1c, 0x01, // 11CA8 at 640 0x2a, 0x61, 0x61, // 1612A at 675 0xff, 0xaf, 0x01, // 1AFFF at 704 0x19, 0xe0, 0x61, // 1E019 at 739 0x00, 0xe7, 0x01, // 1E700 at 768 0xf0, 0x01, 0x0e, // E01F0 at 800 (upper bound) }; static const uint8_t unicode_prop_ID_Start_table[1146] = { 0xc0, 0x99, 0x85, 0x99, 0xae, 0x80, 0x89, 0x03, 0x04, 0x96, 0x80, 0x9e, 0x80, 0x41, 0xc9, 0x83, 0x8b, 0x8d, 0x26, 0x00, 0x80, 0x40, 0x80, 0x20, 0x09, 0x18, 0x05, 0x00, 0x10, 0x00, 0x93, 0x80, 0xd2, 0x80, 0x40, 0x8a, 0x87, 0x40, 0xa5, 0x80, 0xa5, 0x08, 0x85, 0xa8, 0xc6, 0x9a, 0x1b, 0xac, 0xaa, 0xa2, 0x08, 0xe2, 0x00, 0x8e, 0x0e, 0x81, 0x89, 0x11, 0x80, 0x8f, 0x00, 0x9d, 0x9c, 0xd8, 0x8a, 0x80, 0x97, 0xa0, 0x88, 0x0b, 0x04, 0x95, 0x18, 0x88, 0x02, 0x80, 0x96, 0x98, 0x86, 0x8a, 0x84, 0x97, 0x06, 0x8f, 0xa9, 0xb9, 0xb5, 0x10, 0x91, 0x06, 0x89, 0x8e, 0x8f, 0x1f, 0x09, 0x81, 0x95, 0x06, 0x00, 0x13, 0x10, 0x8f, 0x80, 0x8c, 0x08, 0x82, 0x8d, 0x81, 0x89, 0x07, 0x2b, 0x09, 0x95, 0x06, 0x01, 0x01, 0x01, 0x9e, 0x18, 0x80, 0x92, 0x82, 0x8f, 0x88, 0x02, 0x80, 0x95, 0x06, 0x01, 0x04, 0x10, 0x91, 0x80, 0x8e, 0x81, 0x96, 0x80, 0x8a, 0x39, 0x09, 0x95, 0x06, 0x01, 0x04, 0x10, 0x9d, 0x08, 0x82, 0x8e, 0x80, 0x90, 0x00, 0x2a, 0x10, 0x1a, 0x08, 0x00, 0x0a, 0x0a, 0x12, 0x8b, 0x95, 0x80, 0xb3, 0x38, 0x10, 0x96, 0x80, 0x8f, 0x10, 0x99, 0x10, 0x09, 0x81, 0x9d, 0x03, 0x38, 0x10, 0x96, 0x80, 0x89, 0x04, 0x10, 0x9d, 0x10, 0x81, 0x8e, 0x81, 0x90, 0x88, 0x02, 0x80, 0xa8, 0x08, 0x8f, 0x04, 0x17, 0x82, 0x97, 0x2c, 0x91, 0x82, 0x97, 0x80, 0x88, 0x00, 0x0e, 0xb9, 0xaf, 0x01, 0x8b, 0x86, 0xb9, 0x08, 0x00, 0x20, 0x97, 0x00, 0x80, 0x89, 0x01, 0x88, 0x01, 0x20, 0x80, 0x94, 0x83, 0x9f, 0x80, 0xbe, 0x38, 0xa3, 0x9a, 0x84, 0xf2, 0xaa, 0x93, 0x80, 0x8f, 0x2b, 0x1a, 0x02, 0x0e, 0x13, 0x8c, 0x8b, 0x80, 0x90, 0xa5, 0x00, 0x20, 0x81, 0xaa, 0x80, 0x41, 0x4c, 0x03, 0x0e, 0x00, 0x03, 0x81, 0xa8, 0x03, 0x81, 0xa0, 0x03, 0x0e, 0x00, 0x03, 0x81, 0x8e, 0x80, 0xb8, 0x03, 0x81, 0xc2, 0xa4, 0x8f, 0x8f, 0xd5, 0x0d, 0x82, 0x42, 0x6b, 0x81, 0x90, 0x80, 0x99, 0x84, 0xca, 0x82, 0x8a, 0x86, 0x91, 0x8c, 0x92, 0x8d, 0x91, 0x8d, 0x8c, 0x02, 0x8e, 0xb3, 0xa2, 0x03, 0x80, 0xc2, 0xd8, 0x86, 0xa8, 0x00, 0x84, 0xc5, 0x89, 0x9e, 0xb0, 0x9d, 0x0c, 0x8a, 0xab, 0x83, 0x99, 0xb5, 0x96, 0x88, 0xb4, 0xd1, 0x80, 0xdc, 0xae, 0x90, 0x87, 0xb5, 0x9d, 0x8c, 0x81, 0x89, 0xab, 0x99, 0xa3, 0xa8, 0x82, 0x89, 0xa3, 0x81, 0x8a, 0x84, 0xaa, 0x0a, 0xa8, 0x18, 0x28, 0x0a, 0x04, 0x40, 0xbf, 0xbf, 0x41, 0x15, 0x0d, 0x81, 0xa5, 0x0d, 0x0f, 0x00, 0x00, 0x00, 0x80, 0x9e, 0x81, 0xb4, 0x06, 0x00, 0x12, 0x06, 0x13, 0x0d, 0x83, 0x8c, 0x22, 0x06, 0xf3, 0x80, 0x8c, 0x80, 0x8f, 0x8c, 0xe4, 0x03, 0x01, 0x89, 0x00, 0x0d, 0x28, 0x00, 0x00, 0x80, 0x8f, 0x0b, 0x24, 0x18, 0x90, 0xa8, 0x4a, 0x76, 0x40, 0xe4, 0x2b, 0x11, 0x8b, 0xa5, 0x00, 0x20, 0x81, 0xb7, 0x30, 0x8f, 0x96, 0x88, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x86, 0x42, 0x25, 0x82, 0x98, 0x88, 0x34, 0x0c, 0x83, 0xd5, 0x1c, 0x80, 0xd9, 0x03, 0x84, 0xaa, 0x80, 0xdd, 0x90, 0x9f, 0xaf, 0x8f, 0x41, 0xff, 0x59, 0xbf, 0xbf, 0x60, 0x56, 0x8c, 0xc2, 0xad, 0x81, 0x41, 0x0c, 0x82, 0x8f, 0x89, 0x81, 0x93, 0xae, 0x8f, 0x9e, 0x81, 0xcf, 0xa6, 0x88, 0x81, 0xe6, 0x81, 0xd1, 0x93, 0x90, 0x02, 0x03, 0x80, 0x96, 0x9c, 0xb3, 0x8d, 0xb1, 0xbd, 0x2a, 0x00, 0x81, 0x8a, 0x9b, 0x89, 0x96, 0x98, 0x9c, 0x86, 0xae, 0x9b, 0x80, 0x8f, 0x20, 0x89, 0x89, 0x20, 0xa8, 0x96, 0x10, 0x87, 0x93, 0x96, 0x10, 0x82, 0xb1, 0x00, 0x11, 0x0c, 0x08, 0x00, 0x97, 0x11, 0x8a, 0x32, 0x8b, 0x29, 0x29, 0x85, 0x88, 0x30, 0x30, 0xaa, 0x80, 0x8d, 0x85, 0xf2, 0x9c, 0x60, 0x2b, 0xa3, 0x8b, 0x96, 0x83, 0xb0, 0x60, 0x21, 0x03, 0x41, 0x6d, 0x81, 0xe9, 0xa5, 0x86, 0x8b, 0x24, 0x00, 0x89, 0x80, 0x8c, 0x04, 0x00, 0x01, 0x01, 0x80, 0xeb, 0xa0, 0x41, 0x6a, 0x91, 0xbf, 0x81, 0xb5, 0xa7, 0x8b, 0xf3, 0x20, 0x40, 0x86, 0xa3, 0x99, 0x85, 0x99, 0x8a, 0xd8, 0x15, 0x0d, 0x0d, 0x0a, 0xa2, 0x8b, 0x80, 0x99, 0x80, 0x92, 0x01, 0x80, 0x8e, 0x81, 0x8d, 0xa1, 0xfa, 0xc4, 0xb4, 0x41, 0x0a, 0x9c, 0x82, 0xb0, 0xae, 0x9f, 0x8c, 0x9d, 0x84, 0xa5, 0x89, 0x9d, 0x81, 0xa3, 0x1f, 0x04, 0xa9, 0x40, 0x9d, 0x91, 0xa3, 0x83, 0xa3, 0x83, 0xa7, 0x87, 0xb3, 0x8b, 0x8a, 0x80, 0x8e, 0x06, 0x01, 0x80, 0x8a, 0x80, 0x8e, 0x06, 0x01, 0x82, 0xb3, 0x8b, 0x41, 0x36, 0x88, 0x95, 0x89, 0x87, 0x97, 0x28, 0xa9, 0x80, 0x88, 0xc4, 0x29, 0x00, 0xab, 0x01, 0x10, 0x81, 0x96, 0x89, 0x96, 0x88, 0x9e, 0xc0, 0x92, 0x01, 0x89, 0x95, 0x89, 0x99, 0x85, 0x99, 0xa5, 0xb7, 0x29, 0xbf, 0x80, 0x8e, 0x18, 0x10, 0x9c, 0xa9, 0x9c, 0x82, 0x9c, 0xa2, 0x38, 0x9b, 0x9a, 0xb5, 0x89, 0x95, 0x89, 0x92, 0x8c, 0x91, 0xed, 0xc8, 0xb6, 0xb2, 0x8c, 0xb2, 0x8c, 0xa3, 0xa5, 0x9b, 0x88, 0x96, 0x40, 0xf9, 0xa9, 0x29, 0x8f, 0x85, 0xb7, 0x9c, 0x89, 0x07, 0x95, 0xa9, 0x91, 0xad, 0x94, 0x9a, 0x96, 0x8b, 0xb4, 0xb8, 0x09, 0x80, 0x8c, 0xac, 0x9f, 0x98, 0x99, 0xa3, 0x9c, 0x01, 0x07, 0xa2, 0x10, 0x8b, 0xaf, 0x8d, 0x83, 0x94, 0x00, 0x80, 0xa2, 0x91, 0x80, 0x98, 0x92, 0x81, 0xbe, 0x30, 0x00, 0x18, 0x8e, 0x80, 0x89, 0x86, 0xae, 0xa5, 0x39, 0x09, 0x95, 0x06, 0x01, 0x04, 0x10, 0x91, 0x80, 0x8b, 0x84, 0x9d, 0x89, 0x00, 0x08, 0x80, 0xa5, 0x00, 0x98, 0x00, 0x80, 0xab, 0xb4, 0x91, 0x83, 0x93, 0x82, 0x9d, 0xaf, 0x93, 0x08, 0x80, 0x40, 0xb7, 0xae, 0xa8, 0x83, 0xa3, 0xaf, 0x93, 0x80, 0xba, 0xaa, 0x8c, 0x80, 0xc6, 0x9a, 0xa4, 0x86, 0x40, 0xb8, 0xab, 0xf3, 0xbf, 0x9e, 0x39, 0x01, 0x38, 0x08, 0x97, 0x8e, 0x00, 0x80, 0xdd, 0x39, 0xa6, 0x8f, 0x00, 0x80, 0x9b, 0x80, 0x89, 0xa7, 0x30, 0x94, 0x80, 0x8a, 0xad, 0x92, 0x80, 0x91, 0xc8, 0x40, 0xc6, 0xa0, 0x9e, 0x88, 0x80, 0xa4, 0x90, 0x80, 0xb0, 0x9d, 0xef, 0x30, 0x08, 0xa5, 0x94, 0x80, 0x98, 0x28, 0x08, 0x9f, 0x8d, 0x80, 0x96, 0xab, 0x41, 0x03, 0x92, 0x8e, 0x00, 0x8c, 0x80, 0xa1, 0xfb, 0x80, 0xce, 0x43, 0x99, 0xe5, 0xee, 0x90, 0x40, 0xc3, 0x4a, 0x4b, 0xe0, 0x8e, 0x44, 0x2f, 0x90, 0x85, 0x98, 0x4f, 0x9a, 0x84, 0x42, 0x46, 0x5a, 0xb8, 0x9d, 0x46, 0xe1, 0x42, 0x38, 0x86, 0x9e, 0x90, 0xce, 0x90, 0x9d, 0x91, 0xaf, 0x8f, 0x83, 0x9e, 0x94, 0x84, 0x92, 0x41, 0xaf, 0xac, 0x40, 0xd2, 0xbf, 0x9f, 0x98, 0x81, 0x98, 0xab, 0xca, 0x20, 0xc1, 0x8c, 0xbf, 0x08, 0x80, 0x8d, 0x84, 0x88, 0x5c, 0xd5, 0xa8, 0x9f, 0xe0, 0xf2, 0x60, 0x21, 0xfc, 0x18, 0x30, 0x08, 0x41, 0x22, 0x8e, 0x80, 0x9c, 0x11, 0x80, 0x8d, 0x1f, 0x41, 0x8b, 0x49, 0x03, 0xea, 0x84, 0x8c, 0x82, 0x88, 0x86, 0x89, 0x57, 0x65, 0xd4, 0x80, 0xc6, 0x01, 0x08, 0x09, 0x0b, 0x80, 0x8b, 0x00, 0x06, 0x80, 0xc0, 0x03, 0x0f, 0x06, 0x80, 0x9b, 0x03, 0x04, 0x00, 0x16, 0x80, 0x41, 0x53, 0x81, 0x98, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x07, 0x47, 0x33, 0x9e, 0x2d, 0x41, 0x04, 0xbd, 0x40, 0x91, 0xac, 0x89, 0x86, 0x8f, 0x80, 0x41, 0x40, 0x9d, 0x91, 0xab, 0x41, 0xe3, 0x9b, 0x40, 0xe3, 0x9d, 0x08, 0x40, 0xce, 0x9e, 0x02, 0x01, 0x06, 0x0c, 0x88, 0x81, 0x40, 0xdf, 0x30, 0x18, 0x08, 0x8e, 0x80, 0x40, 0xc4, 0xba, 0xc3, 0x30, 0x44, 0xb3, 0x18, 0x9a, 0x01, 0x00, 0x08, 0x80, 0x89, 0x03, 0x00, 0x00, 0x28, 0x18, 0x00, 0x00, 0x02, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0b, 0x06, 0x03, 0x03, 0x00, 0x80, 0x89, 0x80, 0x90, 0x22, 0x04, 0x80, 0x90, 0x51, 0x43, 0x60, 0xa6, 0xdf, 0x9f, 0x51, 0x1d, 0x81, 0x56, 0x8d, 0x81, 0x5d, 0x30, 0x8e, 0x42, 0x6d, 0x49, 0xa1, 0x42, 0x1d, 0x45, 0xe1, 0x53, 0x4a, 0x84, 0x60, 0x21, 0x29, }; static const uint8_t unicode_prop_ID_Start_index[108] = { 0xf6, 0x03, 0x20, // 003F6 at 33 0xa6, 0x07, 0x00, // 007A6 at 64 0xa9, 0x09, 0x20, // 009A9 at 97 0xb1, 0x0a, 0x00, // 00AB1 at 128 0xba, 0x0b, 0x20, // 00BBA at 161 0x3b, 0x0d, 0x20, // 00D3B at 193 0xc7, 0x0e, 0x20, // 00EC7 at 225 0x49, 0x12, 0x00, // 01249 at 256 0x9b, 0x16, 0x00, // 0169B at 288 0xac, 0x19, 0x00, // 019AC at 320 0xc0, 0x1d, 0x80, // 01DC0 at 356 0x80, 0x20, 0x20, // 02080 at 385 0x70, 0x2d, 0x00, // 02D70 at 416 0x00, 0x32, 0x00, // 03200 at 448 0x06, 0xa8, 0x00, // 0A806 at 480 0x77, 0xaa, 0x00, // 0AA77 at 512 0xfc, 0xd7, 0x00, // 0D7FC at 544 0xfd, 0xfe, 0x40, // 0FEFD at 578 0xd1, 0x02, 0x01, // 102D1 at 608 0xb2, 0x05, 0x21, // 105B2 at 641 0xf6, 0x08, 0x01, // 108F6 at 672 0x49, 0x0c, 0x01, // 10C49 at 704 0x76, 0x10, 0x01, // 11076 at 736 0xdf, 0x12, 0x21, // 112DF at 769 0xc8, 0x14, 0x41, // 114C8 at 802 0x42, 0x19, 0x21, // 11942 at 833 0x31, 0x1d, 0x61, // 11D31 at 867 0xf1, 0x2f, 0x41, // 12FF1 at 898 0x78, 0x6b, 0x01, // 16B78 at 928 0x23, 0xb1, 0xa1, // 1B123 at 965 0xad, 0xd4, 0x01, // 1D4AD at 992 0x6f, 0xd7, 0x01, // 1D76F at 1024 0xee, 0xe5, 0x01, // 1E5EE at 1056 0x38, 0xee, 0x01, // 1EE38 at 1088 0xe0, 0xa6, 0x42, // 2A6E0 at 1122 0x7a, 0x34, 0x03, // 3347A at 1152 (upper bound) }; static const uint8_t unicode_prop_ID_Continue1_table[708] = { 0xaf, 0x89, 0xa4, 0x80, 0xd6, 0x80, 0x42, 0x47, 0xef, 0x96, 0x80, 0x40, 0xfa, 0x84, 0x41, 0x08, 0xac, 0x00, 0x01, 0x01, 0x00, 0xc7, 0x8a, 0xaf, 0x9e, 0x28, 0xe4, 0x31, 0x29, 0x08, 0x19, 0x89, 0x96, 0x80, 0x9d, 0x9a, 0xda, 0x8a, 0x8e, 0x89, 0xa0, 0x88, 0x88, 0x80, 0x97, 0x18, 0x88, 0x02, 0x04, 0xaa, 0x82, 0xba, 0x88, 0xa9, 0x97, 0x80, 0xa0, 0xb5, 0x10, 0x91, 0x06, 0x89, 0x09, 0x89, 0x90, 0x82, 0xb7, 0x00, 0x31, 0x09, 0x82, 0x88, 0x80, 0x89, 0x09, 0x89, 0x8d, 0x01, 0x82, 0xb7, 0x00, 0x23, 0x09, 0x12, 0x80, 0x93, 0x8b, 0x10, 0x8a, 0x82, 0xb7, 0x00, 0x38, 0x10, 0x82, 0x93, 0x09, 0x89, 0x89, 0x28, 0x82, 0xb7, 0x00, 0x31, 0x09, 0x16, 0x82, 0x89, 0x09, 0x89, 0x91, 0x80, 0xba, 0x22, 0x10, 0x83, 0x88, 0x80, 0x8d, 0x89, 0x8f, 0x84, 0xb6, 0x00, 0x30, 0x10, 0x1e, 0x81, 0x8a, 0x09, 0x89, 0x90, 0x82, 0xb7, 0x00, 0x30, 0x10, 0x1e, 0x81, 0x8a, 0x09, 0x89, 0x10, 0x8b, 0x83, 0xb6, 0x08, 0x30, 0x10, 0x83, 0x88, 0x80, 0x89, 0x09, 0x89, 0x90, 0x82, 0xc5, 0x03, 0x28, 0x00, 0x3d, 0x89, 0x09, 0xbc, 0x01, 0x86, 0x8b, 0x38, 0x89, 0xd6, 0x01, 0x88, 0x8a, 0x30, 0x89, 0xbd, 0x0d, 0x89, 0x8a, 0x00, 0x00, 0x03, 0x81, 0xb0, 0x93, 0x01, 0x84, 0x8a, 0x80, 0xa3, 0x88, 0x80, 0xe3, 0x93, 0x80, 0x89, 0x8b, 0x1b, 0x10, 0x11, 0x32, 0x83, 0x8c, 0x8b, 0x80, 0x8e, 0x42, 0xbe, 0x82, 0x88, 0x88, 0x43, 0x9f, 0x83, 0x9b, 0x82, 0x9c, 0x81, 0x9d, 0x81, 0xbf, 0x9f, 0x88, 0x01, 0x89, 0xa0, 0x10, 0x8a, 0x40, 0x8e, 0x80, 0xf5, 0x8b, 0x83, 0x8b, 0x89, 0x89, 0xff, 0x8a, 0xbb, 0x84, 0xb8, 0x89, 0x80, 0x9c, 0x81, 0x8a, 0x85, 0x89, 0x95, 0x8d, 0x80, 0x9e, 0x81, 0x8b, 0x93, 0x84, 0xae, 0x90, 0x8a, 0x89, 0x90, 0x88, 0x8b, 0x82, 0x9d, 0x8c, 0x81, 0x89, 0xab, 0x8d, 0xaf, 0x93, 0x87, 0x89, 0x85, 0x89, 0xf5, 0x10, 0x94, 0x18, 0x28, 0x0a, 0x40, 0xc5, 0xbf, 0x42, 0x0b, 0x81, 0xb0, 0x81, 0x92, 0x80, 0xfa, 0x8c, 0x18, 0x82, 0x8b, 0x4b, 0xfd, 0x82, 0x40, 0x8c, 0x80, 0xdf, 0x9f, 0x42, 0x29, 0x85, 0xe8, 0x81, 0xdf, 0x80, 0x60, 0x75, 0x23, 0x89, 0xc4, 0x03, 0x89, 0x9f, 0x81, 0xcf, 0x81, 0x41, 0x0f, 0x02, 0x03, 0x80, 0x96, 0x23, 0x80, 0xd2, 0x81, 0xb1, 0x91, 0x89, 0x89, 0x85, 0x91, 0x8c, 0x8a, 0x9b, 0x87, 0x98, 0x8c, 0xab, 0x83, 0xae, 0x8d, 0x8e, 0x89, 0x8a, 0x80, 0x89, 0x89, 0xae, 0x8d, 0x8b, 0x07, 0x09, 0x89, 0xa0, 0x82, 0xb1, 0x00, 0x11, 0x0c, 0x08, 0x80, 0xa8, 0x24, 0x81, 0x40, 0xeb, 0x38, 0x09, 0x89, 0x60, 0x4f, 0x23, 0x80, 0x42, 0xe0, 0x8f, 0x8f, 0x8f, 0x11, 0x97, 0x82, 0x40, 0xbf, 0x89, 0xa4, 0x80, 0xa4, 0x80, 0x42, 0x96, 0x80, 0x40, 0xe1, 0x80, 0x40, 0x94, 0x84, 0x41, 0x24, 0x89, 0x45, 0x56, 0x10, 0x0c, 0x83, 0xa7, 0x13, 0x80, 0x40, 0xa4, 0x81, 0x42, 0x3c, 0x1f, 0x89, 0x85, 0x89, 0x9e, 0x84, 0x41, 0x3c, 0x81, 0xcc, 0x85, 0xc5, 0x8a, 0xb0, 0x83, 0xf9, 0x82, 0xb4, 0x8e, 0x9e, 0x8a, 0x09, 0x89, 0x83, 0xac, 0x8a, 0x30, 0xac, 0x89, 0x2a, 0xa3, 0x8d, 0x80, 0x89, 0x21, 0xab, 0x80, 0x8b, 0x82, 0xaf, 0x8d, 0x3b, 0x80, 0x8b, 0xd1, 0x8b, 0x28, 0x08, 0x40, 0x9c, 0x8b, 0x84, 0x89, 0x2b, 0xb6, 0x08, 0x31, 0x09, 0x82, 0x88, 0x80, 0x89, 0x09, 0x32, 0x84, 0xc2, 0x88, 0x00, 0x08, 0x03, 0x04, 0x00, 0x8d, 0x81, 0xd1, 0x91, 0x88, 0x89, 0x18, 0xd0, 0x93, 0x8b, 0x89, 0x40, 0xd4, 0x31, 0x88, 0x9a, 0x81, 0xd1, 0x90, 0x8e, 0x89, 0xd0, 0x8c, 0x87, 0x89, 0x85, 0x93, 0xb8, 0x8e, 0x83, 0x89, 0x40, 0xf1, 0x8e, 0x40, 0xa4, 0x89, 0xc5, 0x28, 0x09, 0x18, 0x00, 0x81, 0x8b, 0x89, 0xf6, 0x31, 0x32, 0x80, 0x9b, 0x89, 0xa7, 0x30, 0x1f, 0x80, 0x88, 0x8a, 0xad, 0x8f, 0x40, 0xc5, 0x87, 0x40, 0x87, 0x89, 0xb4, 0x38, 0x87, 0x8f, 0x89, 0xb7, 0x95, 0x80, 0x8d, 0xf9, 0x2a, 0x00, 0x08, 0x30, 0x07, 0x89, 0xaf, 0x20, 0x08, 0x27, 0x89, 0xb5, 0x89, 0x41, 0x08, 0x83, 0x88, 0x08, 0x80, 0xaf, 0x32, 0x84, 0x8c, 0x8a, 0x54, 0xe4, 0x05, 0x8e, 0x60, 0x2c, 0xc7, 0x9b, 0x49, 0x25, 0x89, 0xd5, 0x89, 0xa5, 0x84, 0xba, 0x86, 0x98, 0x89, 0x42, 0x15, 0x89, 0x41, 0xd4, 0x00, 0xb6, 0x33, 0xd0, 0x80, 0x8a, 0x81, 0x60, 0x4c, 0xaa, 0x81, 0x50, 0x50, 0x89, 0x42, 0x05, 0xad, 0x81, 0x96, 0x42, 0x1d, 0x22, 0x2f, 0x39, 0x86, 0x9d, 0x83, 0x40, 0x93, 0x82, 0x45, 0x88, 0xb1, 0x41, 0xff, 0xb6, 0x83, 0xb1, 0x38, 0x8d, 0x80, 0x95, 0x20, 0x8e, 0x45, 0x4f, 0x30, 0x90, 0x0e, 0x01, 0x04, 0xe3, 0x80, 0x40, 0x9f, 0x86, 0x88, 0x89, 0x41, 0x63, 0x80, 0xbc, 0x8d, 0x41, 0xf1, 0x8d, 0x40, 0xf3, 0x08, 0x89, 0x40, 0xe7, 0x01, 0x06, 0x0c, 0x80, 0x41, 0xd9, 0x86, 0xec, 0x34, 0x89, 0x52, 0x95, 0x89, 0x6c, 0x05, 0x05, 0x40, 0xef, }; static const uint8_t unicode_prop_ID_Continue1_index[66] = { 0xfa, 0x06, 0x00, // 006FA at 32 0x70, 0x09, 0x00, // 00970 at 64 0xf0, 0x0a, 0x40, // 00AF0 at 98 0x57, 0x0c, 0x00, // 00C57 at 128 0xf0, 0x0d, 0x60, // 00DF0 at 163 0xc7, 0x0f, 0x20, // 00FC7 at 193 0xea, 0x17, 0x40, // 017EA at 226 0xec, 0x1a, 0x00, // 01AEC at 256 0x0e, 0x20, 0x40, // 0200E at 290 0x7e, 0xa6, 0x20, // 0A67E at 321 0xda, 0xa9, 0x20, // 0A9DA at 353 0x10, 0xfe, 0x40, // 0FE10 at 386 0x40, 0x0a, 0x41, // 10A40 at 418 0xbb, 0x10, 0x21, // 110BB at 449 0x4e, 0x13, 0x41, // 1134E at 482 0xde, 0x15, 0x01, // 115DE at 512 0xe5, 0x19, 0x01, // 119E5 at 544 0x5a, 0x1d, 0x01, // 11D5A at 576 0xf5, 0x6a, 0x21, // 16AF5 at 609 0x8c, 0xd1, 0x61, // 1D18C at 643 0x37, 0xe1, 0x41, // 1E137 at 674 0xf0, 0x01, 0x0e, // E01F0 at 704 (upper bound) }; #ifdef CONFIG_ALL_UNICODE static const uint8_t unicode_cc_table[937] = { 0xb2, 0xcf, 0xd4, 0x00, 0xe8, 0x03, 0xdc, 0x00, 0xe8, 0x00, 0xd8, 0x04, 0xdc, 0x01, 0xca, 0x03, 0xdc, 0x01, 0xca, 0x0a, 0xdc, 0x04, 0x01, 0x03, 0xdc, 0xc7, 0x00, 0xf0, 0xc0, 0x02, 0xdc, 0xc2, 0x01, 0xdc, 0x80, 0xc2, 0x03, 0xdc, 0xc0, 0x00, 0xe8, 0x01, 0xdc, 0xc0, 0x41, 0xe9, 0x00, 0xea, 0x41, 0xe9, 0x00, 0xea, 0x00, 0xe9, 0xcc, 0xb0, 0xe2, 0xc4, 0xb0, 0xd8, 0x00, 0xdc, 0xc3, 0x00, 0xdc, 0xc2, 0x00, 0xde, 0x00, 0xdc, 0xc5, 0x05, 0xdc, 0xc1, 0x00, 0xdc, 0xc1, 0x00, 0xde, 0x00, 0xe4, 0xc0, 0x49, 0x0a, 0x43, 0x13, 0x80, 0x00, 0x17, 0x80, 0x41, 0x18, 0x80, 0xc0, 0x00, 0xdc, 0x80, 0x00, 0x12, 0xb0, 0x17, 0xc7, 0x42, 0x1e, 0xaf, 0x47, 0x1b, 0xc1, 0x01, 0xdc, 0xc4, 0x00, 0xdc, 0xc1, 0x00, 0xdc, 0x8f, 0x00, 0x23, 0xb0, 0x34, 0xc6, 0x81, 0xc3, 0x00, 0xdc, 0xc0, 0x81, 0xc1, 0x80, 0x00, 0xdc, 0xc1, 0x00, 0xdc, 0xa2, 0x00, 0x24, 0x9d, 0xc0, 0x00, 0xdc, 0xc1, 0x00, 0xdc, 0xc1, 0x02, 0xdc, 0xc0, 0x01, 0xdc, 0xc0, 0x00, 0xdc, 0xc2, 0x00, 0xdc, 0xc0, 0x00, 0xdc, 0xc0, 0x00, 0xdc, 0xc0, 0x00, 0xdc, 0xc1, 0xb0, 0x6f, 0xc6, 0x00, 0xdc, 0xc0, 0x88, 0x00, 0xdc, 0x97, 0xc3, 0x80, 0xc8, 0x80, 0xc2, 0x80, 0xc4, 0xaa, 0x02, 0xdc, 0xb0, 0x0a, 0xc1, 0x02, 0xdc, 0xc3, 0xa9, 0xc4, 0x04, 0xdc, 0xcd, 0x80, 0x00, 0xdc, 0xc1, 0x00, 0xdc, 0xc1, 0x00, 0xdc, 0xc2, 0x02, 0xdc, 0x42, 0x1b, 0xc2, 0x00, 0xdc, 0xc1, 0x01, 0xdc, 0xc4, 0xb0, 0x0b, 0x00, 0x07, 0x8f, 0x00, 0x09, 0x82, 0xc0, 0x00, 0xdc, 0xc1, 0xb0, 0x36, 0x00, 0x07, 0x8f, 0x00, 0x09, 0xaf, 0xc0, 0xb0, 0x0c, 0x00, 0x07, 0x8f, 0x00, 0x09, 0xb0, 0x3d, 0x00, 0x07, 0x8f, 0x00, 0x09, 0xb0, 0x3d, 0x00, 0x07, 0x8f, 0x00, 0x09, 0xb0, 0x4e, 0x00, 0x09, 0xb0, 0x3d, 0x00, 0x07, 0x8f, 0x00, 0x09, 0x86, 0x00, 0x54, 0x00, 0x5b, 0xb0, 0x34, 0x00, 0x07, 0x8f, 0x00, 0x09, 0xb0, 0x3c, 0x01, 0x09, 0x8f, 0x00, 0x09, 0xb0, 0x4b, 0x00, 0x09, 0xb0, 0x3c, 0x01, 0x67, 0x00, 0x09, 0x8c, 0x03, 0x6b, 0xb0, 0x3b, 0x01, 0x76, 0x00, 0x09, 0x8c, 0x03, 0x7a, 0xb0, 0x1b, 0x01, 0xdc, 0x9a, 0x00, 0xdc, 0x80, 0x00, 0xdc, 0x80, 0x00, 0xd8, 0xb0, 0x06, 0x41, 0x81, 0x80, 0x00, 0x84, 0x84, 0x03, 0x82, 0x81, 0x00, 0x82, 0x80, 0xc1, 0x00, 0x09, 0x80, 0xc1, 0xb0, 0x0d, 0x00, 0xdc, 0xb0, 0x3f, 0x00, 0x07, 0x80, 0x01, 0x09, 0xb0, 0x21, 0x00, 0xdc, 0xb2, 0x9e, 0xc2, 0xb3, 0x83, 0x01, 0x09, 0x9d, 0x00, 0x09, 0xb0, 0x6c, 0x00, 0x09, 0x89, 0xc0, 0xb0, 0x9a, 0x00, 0xe4, 0xb0, 0x5e, 0x00, 0xde, 0xc0, 0x00, 0xdc, 0xb0, 0xaa, 0xc0, 0x00, 0xdc, 0xb0, 0x16, 0x00, 0x09, 0x93, 0xc7, 0x81, 0x00, 0xdc, 0xaf, 0xc4, 0x05, 0xdc, 0xc1, 0x00, 0xdc, 0x80, 0x01, 0xdc, 0xc1, 0x01, 0xdc, 0xc4, 0x00, 0xdc, 0xd1, 0x00, 0xdc, 0x81, 0xc5, 0x00, 0xdc, 0xc3, 0x00, 0xea, 0xb0, 0x17, 0x00, 0x07, 0x8e, 0x00, 0x09, 0xa5, 0xc0, 0x00, 0xdc, 0xc6, 0xb0, 0x05, 0x01, 0x09, 0xb0, 0x09, 0x00, 0x07, 0x8a, 0x01, 0x09, 0xb0, 0x12, 0x00, 0x07, 0xb0, 0x67, 0xc2, 0x41, 0x00, 0x04, 0xdc, 0xc1, 0x03, 0xdc, 0xc0, 0x41, 0x00, 0x05, 0x01, 0x83, 0x00, 0xdc, 0x85, 0xc0, 0x82, 0xc1, 0xb0, 0x95, 0xc1, 0x00, 0xdc, 0xc6, 0x00, 0xdc, 0xc1, 0x00, 0xea, 0x00, 0xd6, 0x00, 0xdc, 0x00, 0xca, 0xe4, 0x00, 0xe8, 0x01, 0xe4, 0x00, 0xdc, 0x00, 0xda, 0xc0, 0x00, 0xe9, 0x00, 0xdc, 0xc0, 0x00, 0xdc, 0xb2, 0x9f, 0xc1, 0x01, 0x01, 0xc3, 0x02, 0x01, 0xc1, 0x83, 0xc0, 0x82, 0x01, 0x01, 0xc0, 0x00, 0xdc, 0xc0, 0x01, 0x01, 0x03, 0xdc, 0xc0, 0xb8, 0x03, 0xcd, 0xc2, 0xb0, 0x5c, 0x00, 0x09, 0xb0, 0x2f, 0xdf, 0xb1, 0xf9, 0x00, 0xda, 0x00, 0xe4, 0x00, 0xe8, 0x00, 0xde, 0x01, 0xe0, 0xb0, 0x38, 0x01, 0x08, 0xb8, 0x6d, 0xa3, 0xc0, 0x83, 0xc9, 0x9f, 0xc1, 0xb0, 0x1f, 0xc1, 0xb0, 0xe3, 0x00, 0x09, 0xa4, 0x00, 0x09, 0xb0, 0x66, 0x00, 0x09, 0x9a, 0xd1, 0xb0, 0x08, 0x02, 0xdc, 0xa4, 0x00, 0x09, 0xb0, 0x2e, 0x00, 0x07, 0x8b, 0x00, 0x09, 0xb0, 0xbe, 0xc0, 0x80, 0xc1, 0x00, 0xdc, 0x81, 0xc1, 0x84, 0xc1, 0x80, 0xc0, 0xb0, 0x03, 0x00, 0x09, 0xb0, 0xc5, 0x00, 0x09, 0xb8, 0x46, 0xff, 0x00, 0x1a, 0xb2, 0xd0, 0xc6, 0x06, 0xdc, 0xc1, 0xb3, 0x9c, 0x00, 0xdc, 0xb0, 0xb1, 0x00, 0xdc, 0xb0, 0x64, 0xc4, 0xb6, 0x61, 0x00, 0xdc, 0x80, 0xc0, 0xa7, 0xc0, 0x00, 0x01, 0x00, 0xdc, 0x83, 0x00, 0x09, 0xb0, 0x74, 0xc0, 0x00, 0xdc, 0xb2, 0x0c, 0xc3, 0xb0, 0x10, 0xc4, 0xb1, 0x0c, 0xc1, 0xb0, 0x1c, 0x01, 0xdc, 0x80, 0x02, 0xdc, 0xb0, 0x15, 0x01, 0xdc, 0xc2, 0x00, 0xdc, 0xc0, 0x03, 0xdc, 0xb0, 0x00, 0xc0, 0x00, 0xdc, 0xc0, 0x00, 0xdc, 0xb0, 0x8f, 0x00, 0x09, 0xa8, 0x00, 0x09, 0x8d, 0x00, 0x09, 0xb0, 0x08, 0x00, 0x09, 0x00, 0x07, 0xb0, 0x14, 0xc2, 0xaf, 0x01, 0x09, 0xb0, 0x0d, 0x00, 0x07, 0xb0, 0x1b, 0x00, 0x09, 0x88, 0x00, 0x07, 0xb0, 0x39, 0x00, 0x09, 0x00, 0x07, 0xb0, 0x81, 0x00, 0x07, 0x00, 0x09, 0xb0, 0x1f, 0x01, 0x07, 0x8f, 0x00, 0x09, 0x97, 0xc6, 0x82, 0xc4, 0xb0, 0x28, 0x02, 0x09, 0xb0, 0x40, 0x00, 0x09, 0x82, 0x00, 0x07, 0x96, 0xc0, 0xb0, 0x32, 0x00, 0x09, 0x00, 0x07, 0xb0, 0xca, 0x00, 0x09, 0x00, 0x07, 0xb0, 0x4d, 0x00, 0x09, 0xb0, 0x45, 0x00, 0x09, 0x00, 0x07, 0xb0, 0x42, 0x00, 0x09, 0xb0, 0xdc, 0x00, 0x09, 0x00, 0x07, 0xb0, 0xd1, 0x01, 0x09, 0x83, 0x00, 0x07, 0xb0, 0x6b, 0x00, 0x09, 0xb0, 0x22, 0x00, 0x09, 0x91, 0x00, 0x09, 0xb0, 0x20, 0x00, 0x09, 0xb1, 0x74, 0x00, 0x09, 0xb0, 0xd1, 0x00, 0x07, 0x80, 0x01, 0x09, 0xb0, 0x20, 0x00, 0x09, 0xb1, 0x78, 0x01, 0x09, 0xb8, 0x39, 0xbb, 0x00, 0x09, 0xb8, 0x01, 0x8f, 0x04, 0x01, 0xb0, 0x0a, 0xc6, 0xb4, 0x88, 0x01, 0x06, 0xb8, 0x44, 0x7b, 0x00, 0x01, 0xb8, 0x0c, 0x95, 0x01, 0xd8, 0x02, 0x01, 0x82, 0x00, 0xe2, 0x04, 0xd8, 0x87, 0x07, 0xdc, 0x81, 0xc4, 0x01, 0xdc, 0x9d, 0xc3, 0xb0, 0x63, 0xc2, 0xb8, 0x05, 0x8a, 0xc6, 0x80, 0xd0, 0x81, 0xc6, 0x80, 0xc1, 0x80, 0xc4, 0xb0, 0x33, 0xc0, 0xb0, 0x6f, 0xc6, 0xb1, 0x46, 0xc0, 0xb0, 0x0c, 0xc3, 0xb1, 0xcb, 0x01, 0xe8, 0x00, 0xdc, 0xc0, 0xb0, 0xcd, 0xc0, 0x00, 0xdc, 0xb0, 0xc2, 0xc0, 0x81, 0xc0, 0x86, 0xc1, 0x84, 0xc0, 0xb1, 0xa9, 0x06, 0xdc, 0xb0, 0x3c, 0xc5, 0x00, 0x07, }; static const uint8_t unicode_cc_index[90] = { 0x4d, 0x03, 0x00, // 0034D at 32 0x97, 0x05, 0x20, // 00597 at 65 0xc6, 0x05, 0x00, // 005C6 at 96 0xe7, 0x06, 0x00, // 006E7 at 128 0x45, 0x07, 0x00, // 00745 at 160 0x9c, 0x08, 0x00, // 0089C at 192 0x4d, 0x09, 0x00, // 0094D at 224 0x3c, 0x0b, 0x00, // 00B3C at 256 0x3d, 0x0d, 0x00, // 00D3D at 288 0x36, 0x0f, 0x00, // 00F36 at 320 0x38, 0x10, 0x20, // 01038 at 353 0x3a, 0x19, 0x00, // 0193A at 384 0xcb, 0x1a, 0x20, // 01ACB at 417 0xf2, 0x1b, 0x00, // 01BF2 at 448 0xc3, 0x1d, 0x20, // 01DC3 at 481 0xd0, 0x20, 0x00, // 020D0 at 512 0x00, 0x2e, 0x00, // 02E00 at 544 0x2c, 0xa8, 0x00, // 0A82C at 576 0xbe, 0xaa, 0x00, // 0AABE at 608 0x76, 0x03, 0x01, // 10376 at 640 0xfa, 0x0e, 0x01, // 10EFA at 672 0x80, 0x10, 0x21, // 11080 at 705 0xe9, 0x12, 0x01, // 112E9 at 736 0xc3, 0x14, 0x01, // 114C3 at 768 0x3f, 0x19, 0x01, // 1193F at 800 0x98, 0x1d, 0x21, // 11D98 at 833 0x67, 0xd1, 0x01, // 1D167 at 864 0x8f, 0xe0, 0x21, // 1E08F at 897 0xf6, 0xe6, 0x01, // 1E6F6 at 928 0x4b, 0xe9, 0x01, // 1E94B at 960 (upper bound) }; static const uint32_t unicode_decomp_table1[709] = { 0x00280081, 0x002a0097, 0x002a8081, 0x002bc097, 0x002c8115, 0x002d0097, 0x002d4081, 0x002e0097, 0x002e4115, 0x002f0199, 0x00302016, 0x00400842, 0x00448a42, 0x004a0442, 0x004c0096, 0x004c8117, 0x004d0242, 0x004e4342, 0x004fc12f, 0x0050c342, 0x005240bf, 0x00530342, 0x00550942, 0x005a0842, 0x005e0096, 0x005e4342, 0x005fc081, 0x00680142, 0x006bc142, 0x00710185, 0x0071c317, 0x00734844, 0x00778344, 0x00798342, 0x007b02be, 0x007c4197, 0x007d0142, 0x007e0444, 0x00800e42, 0x00878142, 0x00898744, 0x00ac0483, 0x00b60317, 0x00b80283, 0x00d00214, 0x00d10096, 0x00dd0080, 0x00de8097, 0x00df8080, 0x00e10097, 0x00e1413e, 0x00e1c080, 0x00e204be, 0x00ea83ae, 0x00f282ae, 0x00f401ad, 0x00f4c12e, 0x00f54103, 0x00fc0303, 0x00fe4081, 0x0100023e, 0x0101c0be, 0x010301be, 0x010640be, 0x010e40be, 0x0114023e, 0x0115c0be, 0x011701be, 0x011d8144, 0x01304144, 0x01340244, 0x01358144, 0x01368344, 0x01388344, 0x013a8644, 0x013e0144, 0x0161c085, 0x018882ae, 0x019d422f, 0x01b00184, 0x01b4c084, 0x024a4084, 0x024c4084, 0x024d0084, 0x0256042e, 0x0272c12e, 0x02770120, 0x0277c084, 0x028cc084, 0x028d8084, 0x029641ae, 0x02978084, 0x02d20084, 0x02d2c12e, 0x02d70120, 0x02e50084, 0x02f281ae, 0x03120084, 0x03300084, 0x0331c122, 0x0332812e, 0x035281ae, 0x03768084, 0x037701ae, 0x038cc085, 0x03acc085, 0x03b7012f, 0x03c30081, 0x03d0c084, 0x03d34084, 0x03d48084, 0x03d5c084, 0x03d70084, 0x03da4084, 0x03dcc084, 0x03dd412e, 0x03ddc085, 0x03de0084, 0x03de4085, 0x03e04084, 0x03e4c084, 0x03e74084, 0x03e88084, 0x03e9c084, 0x03eb0084, 0x03ee4084, 0x04098084, 0x043f0081, 0x06c18484, 0x06c48084, 0x06cec184, 0x06d00120, 0x06d0c084, 0x074b0383, 0x074cc41f, 0x074f1783, 0x075e0081, 0x0766d283, 0x07801d44, 0x078e8942, 0x07931844, 0x079f0d42, 0x07a58216, 0x07a68085, 0x07a6c0be, 0x07a80d44, 0x07aea044, 0x07c00122, 0x07c08344, 0x07c20122, 0x07c28344, 0x07c40122, 0x07c48244, 0x07c60122, 0x07c68244, 0x07c8113e, 0x07d08244, 0x07d20122, 0x07d28244, 0x07d40122, 0x07d48344, 0x07d64c3e, 0x07dc4080, 0x07dc80be, 0x07dcc080, 0x07dd00be, 0x07dd4080, 0x07dd80be, 0x07ddc080, 0x07de00be, 0x07de4080, 0x07de80be, 0x07dec080, 0x07df00be, 0x07df4080, 0x07e00820, 0x07e40820, 0x07e80820, 0x07ec05be, 0x07eec080, 0x07ef00be, 0x07ef4097, 0x07ef8080, 0x07efc117, 0x07f0443e, 0x07f24080, 0x07f280be, 0x07f2c080, 0x07f303be, 0x07f4c080, 0x07f582ae, 0x07f6c080, 0x07f7433e, 0x07f8c080, 0x07f903ae, 0x07fac080, 0x07fb013e, 0x07fb8102, 0x07fc83be, 0x07fe4080, 0x07fe80be, 0x07fec080, 0x07ff00be, 0x07ff4080, 0x07ff8097, 0x0800011e, 0x08008495, 0x08044081, 0x0805c097, 0x08090081, 0x08094097, 0x08098099, 0x080bc081, 0x080cc085, 0x080d00b1, 0x080d8085, 0x080dc0b1, 0x080f0197, 0x0811c197, 0x0815c0b3, 0x0817c081, 0x081c0595, 0x081ec081, 0x081f0215, 0x0820051f, 0x08228583, 0x08254415, 0x082a0097, 0x08400119, 0x08408081, 0x0840c0bf, 0x08414119, 0x0841c081, 0x084240bf, 0x0842852d, 0x08454081, 0x08458097, 0x08464295, 0x08480097, 0x08484099, 0x08488097, 0x08490081, 0x08498080, 0x084a0081, 0x084a8102, 0x084b0495, 0x084d421f, 0x084e4081, 0x084ec099, 0x084f0283, 0x08514295, 0x08540119, 0x0854809b, 0x0854c619, 0x0857c097, 0x08580081, 0x08584097, 0x08588099, 0x0858c097, 0x08590081, 0x08594097, 0x08598099, 0x0859c09b, 0x085a0097, 0x085a4081, 0x085a8097, 0x085ac099, 0x085b0295, 0x085c4097, 0x085c8099, 0x085cc097, 0x085d0081, 0x085d4097, 0x085d8099, 0x085dc09b, 0x085e0097, 0x085e4081, 0x085e8097, 0x085ec099, 0x085f0215, 0x08624099, 0x0866813e, 0x086b80be, 0x087341be, 0x088100be, 0x088240be, 0x088300be, 0x088901be, 0x088b0085, 0x088b40b1, 0x088bc085, 0x088c00b1, 0x089040be, 0x089100be, 0x0891c1be, 0x089801be, 0x089b42be, 0x089d0144, 0x089e0144, 0x08a00144, 0x08a10144, 0x08a20144, 0x08ab023e, 0x08b80244, 0x08ba8220, 0x08ca411e, 0x0918049f, 0x091a4523, 0x091cc097, 0x091d04a5, 0x091f452b, 0x0921c09b, 0x092204a1, 0x09244525, 0x0926c099, 0x09270d25, 0x092d8d1f, 0x09340d1f, 0x093a8081, 0x0a8300b3, 0x0a9d0099, 0x0a9d4097, 0x0a9d8099, 0x0ab700be, 0x0b1f0115, 0x0b5bc081, 0x0ba7c081, 0x0bbcc081, 0x0bc004ad, 0x0bc244ad, 0x0bc484ad, 0x0bc6f383, 0x0be0852d, 0x0be31d03, 0x0bf1882d, 0x0c000081, 0x0c0d8283, 0x0c130b84, 0x0c194284, 0x0c1c0122, 0x0c1cc122, 0x0c1d8122, 0x0c1e4122, 0x0c1f0122, 0x0c250084, 0x0c26c123, 0x0c278084, 0x0c27c085, 0x0c2b0b84, 0x0c314284, 0x0c340122, 0x0c34c122, 0x0c358122, 0x0c364122, 0x0c370122, 0x0c3d0084, 0x0c3dc220, 0x0c3f8084, 0x0c3fc085, 0x0c4c4a2d, 0x0c51451f, 0x0c53ca9f, 0x0c5915ad, 0x0c648703, 0x0c800741, 0x0c838089, 0x0c83c129, 0x0c8441a9, 0x0c850089, 0x0c854129, 0x0c85c2a9, 0x0c870089, 0x0c87408f, 0x0c87808d, 0x0c881241, 0x0c910203, 0x0c940099, 0x0c9444a3, 0x0c968323, 0x0c98072d, 0x0c9b84af, 0x0c9dc2a1, 0x0c9f00b5, 0x0c9f40b3, 0x0c9f8085, 0x0ca01883, 0x0cac4223, 0x0cad4523, 0x0cafc097, 0x0cb004a1, 0x0cb241a5, 0x0cb30097, 0x0cb34099, 0x0cb38097, 0x0cb3c099, 0x0cb417ad, 0x0cbfc085, 0x0cc001b3, 0x0cc0c0b1, 0x0cc100b3, 0x0cc14131, 0x0cc1c0b5, 0x0cc200b3, 0x0cc241b1, 0x0cc30133, 0x0cc38131, 0x0cc40085, 0x0cc440b1, 0x0cc48133, 0x0cc50085, 0x0cc540b5, 0x0cc580b7, 0x0cc5c0b5, 0x0cc600b1, 0x0cc64135, 0x0cc6c0b3, 0x0cc701b1, 0x0cc7c0b3, 0x0cc800b5, 0x0cc840b3, 0x0cc881b1, 0x0cc9422f, 0x0cca4131, 0x0ccac0b5, 0x0ccb00b1, 0x0ccb40b3, 0x0ccb80b5, 0x0ccbc0b1, 0x0ccc012f, 0x0ccc80b5, 0x0cccc0b3, 0x0ccd00b5, 0x0ccd40b1, 0x0ccd80b5, 0x0ccdc085, 0x0cce02b1, 0x0ccf40b3, 0x0ccf80b1, 0x0ccfc085, 0x0cd001b1, 0x0cd0c0b3, 0x0cd101b1, 0x0cd1c0b5, 0x0cd200b3, 0x0cd24085, 0x0cd280b5, 0x0cd2c085, 0x0cd30133, 0x0cd381b1, 0x0cd440b3, 0x0cd48085, 0x0cd4c0b1, 0x0cd500b3, 0x0cd54085, 0x0cd580b5, 0x0cd5c0b1, 0x0cd60521, 0x0cd88525, 0x0cdb02a5, 0x0cdc4099, 0x0cdc8117, 0x0cdd0099, 0x0cdd4197, 0x0cde0127, 0x0cde8285, 0x0cdfc089, 0x0ce0043f, 0x0ce20099, 0x0ce2409b, 0x0ce283bf, 0x0ce44219, 0x0ce54205, 0x0ce6433f, 0x0ce7c131, 0x0ce84085, 0x0ce881b1, 0x0ce94085, 0x0ce98107, 0x0cea0089, 0x0cea4097, 0x0cea8219, 0x0ceb809d, 0x0cebc08d, 0x0cec083f, 0x0cf00105, 0x0cf0809b, 0x0cf0c197, 0x0cf1809b, 0x0cf1c099, 0x0cf20517, 0x0cf48099, 0x0cf4c117, 0x0cf54119, 0x0cf5c097, 0x0cf6009b, 0x0cf64099, 0x0cf68217, 0x0cf78119, 0x0cf804a1, 0x0cfa4525, 0x0cfcc525, 0x0cff4125, 0x0cffc099, 0x29a70103, 0x29dc0081, 0x29fc4215, 0x29fe0103, 0x2ad70203, 0x2ada4081, 0x3e401482, 0x3e4a7f82, 0x3e6a3f82, 0x3e8aa102, 0x3e9b0110, 0x3e9c2f82, 0x3eb3c590, 0x3ec00197, 0x3ec0c119, 0x3ec1413f, 0x3ec4c2af, 0x3ec74184, 0x3ec804ad, 0x3eca4081, 0x3eca8304, 0x3ecc03a0, 0x3ece02a0, 0x3ecf8084, 0x3ed00120, 0x3ed0c120, 0x3ed184ae, 0x3ed3c085, 0x3ed4312d, 0x3ef4cbad, 0x3efa892f, 0x3eff022d, 0x3f002f2f, 0x3f1782a5, 0x3f18c0b1, 0x3f1907af, 0x3f1cffaf, 0x3f3c81a5, 0x3f3d64af, 0x3f542031, 0x3f649b31, 0x3f7c0131, 0x3f7c83b3, 0x3f7e40b1, 0x3f7e80bd, 0x3f7ec0bb, 0x3f7f00b3, 0x3f840503, 0x3f8c01ad, 0x3f8cc315, 0x3f8e462d, 0x3f91cc03, 0x3f97c695, 0x3f9c01af, 0x3f9d0085, 0x3f9d852f, 0x3fa03aad, 0x3fbd442f, 0x3fc06f1f, 0x3fd7c11f, 0x3fd85fad, 0x3fe80081, 0x3fe84f1f, 0x3ff0831f, 0x3ff2831f, 0x3ff4831f, 0x3ff6819f, 0x3ff80783, 0x41724092, 0x41790092, 0x41e04d83, 0x41e70f91, 0x44268192, 0x442ac092, 0x444b8112, 0x44d2c112, 0x44e0c192, 0x44e38092, 0x44e44092, 0x44f14212, 0x452ec212, 0x456e8112, 0x464e0092, 0x58484412, 0x5b5a0192, 0x73358d1f, 0x733c051f, 0x74578392, 0x746ec312, 0x75000d1f, 0x75068d1f, 0x750d0d1f, 0x7513839f, 0x7515891f, 0x751a0d1f, 0x75208d1f, 0x75271015, 0x752f439f, 0x7531459f, 0x75340d1f, 0x753a8d1f, 0x75410395, 0x7543441f, 0x7545839f, 0x75478d1f, 0x754e0795, 0x7552839f, 0x75548d1f, 0x755b0d1f, 0x75618d1f, 0x75680d1f, 0x756e8d1f, 0x75750d1f, 0x757b8d1f, 0x75820d1f, 0x75888d1f, 0x758f0d1f, 0x75958d1f, 0x759c0d1f, 0x75a28d1f, 0x75a90103, 0x75aa089f, 0x75ae4081, 0x75ae839f, 0x75b04081, 0x75b08c9f, 0x75b6c081, 0x75b7032d, 0x75b8889f, 0x75bcc081, 0x75bd039f, 0x75bec081, 0x75bf0c9f, 0x75c54081, 0x75c5832d, 0x75c7089f, 0x75cb4081, 0x75cb839f, 0x75cd4081, 0x75cd8c9f, 0x75d3c081, 0x75d4032d, 0x75d5889f, 0x75d9c081, 0x75da039f, 0x75dbc081, 0x75dc0c9f, 0x75e24081, 0x75e2832d, 0x75e4089f, 0x75e84081, 0x75e8839f, 0x75ea4081, 0x75ea8c9f, 0x75f0c081, 0x75f1042d, 0x75f3851f, 0x75f6051f, 0x75f8851f, 0x75fb051f, 0x75fd851f, 0x780c049f, 0x780e419f, 0x780f059f, 0x7811c203, 0x7812d0ad, 0x781b0103, 0x7b80022d, 0x7b814dad, 0x7b884203, 0x7b89c081, 0x7b8a452d, 0x7b8d0403, 0x7b908081, 0x7b91dc03, 0x7ba0052d, 0x7ba2c8ad, 0x7ba84483, 0x7baac8ad, 0x7c400097, 0x7c404521, 0x7c440d25, 0x7c4a8087, 0x7c4ac115, 0x7c4b4117, 0x7c4c0d1f, 0x7c528217, 0x7c538099, 0x7c53c097, 0x7c5a8197, 0x7c640097, 0x7c80012f, 0x7c808081, 0x7c841603, 0x7c9004c1, 0x7c940103, 0x7efc051f, 0xbe0001ac, 0xbe00d110, 0xbe0947ac, 0xbe0d3910, 0xbe29872c, 0xbe2d022c, 0xbe2e3790, 0xbe49ff90, 0xbe69bc10, }; static const uint16_t unicode_decomp_table2[709] = { 0x0020, 0x0000, 0x0061, 0x0002, 0x0004, 0x0006, 0x03bc, 0x0008, 0x000a, 0x000c, 0x0015, 0x0095, 0x00a5, 0x00b9, 0x00c1, 0x00c3, 0x00c7, 0x00cb, 0x00d1, 0x00d7, 0x00dd, 0x00e0, 0x00e6, 0x00f8, 0x0108, 0x010a, 0x0073, 0x0110, 0x0112, 0x0114, 0x0120, 0x012c, 0x0144, 0x014d, 0x0153, 0x0162, 0x0168, 0x016a, 0x0176, 0x0192, 0x0194, 0x01a9, 0x01bb, 0x01c7, 0x01d1, 0x01d5, 0x02b9, 0x01d7, 0x003b, 0x01d9, 0x01db, 0x00b7, 0x01e1, 0x01fc, 0x020c, 0x0218, 0x021d, 0x0223, 0x0227, 0x03a3, 0x0233, 0x023f, 0x0242, 0x024b, 0x024e, 0x0251, 0x025d, 0x0260, 0x0269, 0x026c, 0x026f, 0x0275, 0x0278, 0x0281, 0x028a, 0x029c, 0x029f, 0x02a3, 0x02af, 0x02b9, 0x02c5, 0x02c9, 0x02cd, 0x02d1, 0x02d5, 0x02e7, 0x02ed, 0x02f1, 0x02f5, 0x02f9, 0x02fd, 0x0305, 0x0309, 0x030d, 0x0313, 0x0317, 0x031b, 0x0323, 0x0327, 0x032b, 0x032f, 0x0335, 0x033d, 0x0341, 0x0349, 0x034d, 0x0351, 0x0f0b, 0x0357, 0x035b, 0x035f, 0x0363, 0x0367, 0x036b, 0x036f, 0x0373, 0x0379, 0x037d, 0x0381, 0x0385, 0x0389, 0x038d, 0x0391, 0x0395, 0x0399, 0x039d, 0x03a1, 0x10dc, 0x03a5, 0x03c9, 0x03cd, 0x03d9, 0x03dd, 0x03e1, 0x03ef, 0x03f1, 0x043d, 0x044f, 0x0499, 0x04f0, 0x0502, 0x054a, 0x0564, 0x056c, 0x0570, 0x0573, 0x059a, 0x05fa, 0x05fe, 0x0607, 0x060b, 0x0614, 0x0618, 0x061e, 0x0622, 0x0628, 0x068e, 0x0694, 0x0698, 0x069e, 0x06a2, 0x06ab, 0x03ac, 0x06f3, 0x03ad, 0x06f6, 0x03ae, 0x06f9, 0x03af, 0x06fc, 0x03cc, 0x06ff, 0x03cd, 0x0702, 0x03ce, 0x0705, 0x0709, 0x070d, 0x0711, 0x0386, 0x0732, 0x0735, 0x03b9, 0x0737, 0x073b, 0x0388, 0x0753, 0x0389, 0x0756, 0x0390, 0x076b, 0x038a, 0x0777, 0x03b0, 0x0789, 0x038e, 0x0799, 0x079f, 0x07a3, 0x038c, 0x07b8, 0x038f, 0x07bb, 0x00b4, 0x07be, 0x07c0, 0x07c2, 0x2010, 0x07cb, 0x002e, 0x07cd, 0x07cf, 0x0020, 0x07d2, 0x07d6, 0x07db, 0x07df, 0x07e4, 0x07ea, 0x07f0, 0x0020, 0x07f6, 0x2212, 0x0801, 0x0805, 0x0807, 0x081d, 0x0825, 0x0827, 0x0043, 0x082d, 0x0830, 0x0190, 0x0836, 0x0839, 0x004e, 0x0845, 0x0847, 0x084c, 0x084e, 0x0851, 0x005a, 0x03a9, 0x005a, 0x0853, 0x0857, 0x0860, 0x0069, 0x0862, 0x0865, 0x086f, 0x0874, 0x087a, 0x087e, 0x08a2, 0x0049, 0x08a4, 0x08a6, 0x08a9, 0x0056, 0x08ab, 0x08ad, 0x08b0, 0x08b4, 0x0058, 0x08b6, 0x08b8, 0x08bb, 0x08c0, 0x08c2, 0x08c5, 0x0076, 0x08c7, 0x08c9, 0x08cc, 0x08d0, 0x0078, 0x08d2, 0x08d4, 0x08d7, 0x08db, 0x08de, 0x08e4, 0x08e7, 0x08f0, 0x08f3, 0x08f6, 0x08f9, 0x0902, 0x0906, 0x090b, 0x090f, 0x0914, 0x0917, 0x091a, 0x0923, 0x092c, 0x093b, 0x093e, 0x0941, 0x0944, 0x0947, 0x094a, 0x0956, 0x095c, 0x0960, 0x0962, 0x0964, 0x0968, 0x096a, 0x0970, 0x0978, 0x097c, 0x0980, 0x0986, 0x0989, 0x098f, 0x0991, 0x0030, 0x0993, 0x0999, 0x099c, 0x099e, 0x09a1, 0x09a4, 0x2d61, 0x6bcd, 0x9f9f, 0x09a6, 0x09b1, 0x09bc, 0x09c7, 0x0a95, 0x0aa1, 0x0b15, 0x0020, 0x0b27, 0x0b31, 0x0b8d, 0x0ba1, 0x0ba5, 0x0ba9, 0x0bad, 0x0bb1, 0x0bb5, 0x0bb9, 0x0bbd, 0x0bc1, 0x0bc5, 0x0c21, 0x0c35, 0x0c39, 0x0c3d, 0x0c41, 0x0c45, 0x0c49, 0x0c4d, 0x0c51, 0x0c55, 0x0c59, 0x0c6f, 0x0c71, 0x0c73, 0x0ca0, 0x0cbc, 0x0cdc, 0x0ce4, 0x0cec, 0x0cf4, 0x0cfc, 0x0d04, 0x0d0c, 0x0d14, 0x0d22, 0x0d2e, 0x0d7a, 0x0d82, 0x0d85, 0x0d89, 0x0d8d, 0x0d9d, 0x0db1, 0x0db5, 0x0dbc, 0x0dc2, 0x0dc6, 0x0e28, 0x0e2c, 0x0e30, 0x0e32, 0x0e36, 0x0e3c, 0x0e3e, 0x0e41, 0x0e43, 0x0e46, 0x0e77, 0x0e7b, 0x0e89, 0x0e8e, 0x0e94, 0x0e9c, 0x0ea3, 0x0ea9, 0x0eb4, 0x0ebe, 0x0ec6, 0x0eca, 0x0ecf, 0x0ed9, 0x0edd, 0x0ee4, 0x0eec, 0x0ef3, 0x0ef8, 0x0f04, 0x0f0a, 0x0f15, 0x0f1b, 0x0f22, 0x0f28, 0x0f33, 0x0f3d, 0x0f45, 0x0f4c, 0x0f51, 0x0f57, 0x0f5e, 0x0f63, 0x0f69, 0x0f70, 0x0f76, 0x0f7d, 0x0f82, 0x0f89, 0x0f8d, 0x0f9e, 0x0fa4, 0x0fa9, 0x0fad, 0x0fb8, 0x0fbe, 0x0fc9, 0x0fd0, 0x0fd6, 0x0fda, 0x0fe1, 0x0fe5, 0x0fef, 0x0ffa, 0x1000, 0x1004, 0x1009, 0x100f, 0x1013, 0x101a, 0x101f, 0x1023, 0x1029, 0x102f, 0x1032, 0x1036, 0x1039, 0x103f, 0x1045, 0x1059, 0x1061, 0x1079, 0x107c, 0x1080, 0x1095, 0x10a1, 0x10b1, 0x10c3, 0x10cb, 0x10cf, 0x10da, 0x10de, 0x10ea, 0x10f2, 0x10f4, 0x1100, 0x1105, 0x1111, 0x1141, 0x1149, 0x114d, 0x1153, 0x1157, 0x115a, 0x116e, 0x1171, 0x1175, 0x117b, 0x117d, 0x1181, 0x1184, 0x118c, 0x1192, 0x1196, 0x119c, 0x11a2, 0x11a8, 0x11ab, 0xa76f, 0x11af, 0x11b3, 0x11b7, 0x028d, 0x11bf, 0x1211, 0x130f, 0x140d, 0x1491, 0x1496, 0x1554, 0x156d, 0x1573, 0x1579, 0x157f, 0x158b, 0x1597, 0x002b, 0x15a2, 0x15ba, 0x15be, 0x15c2, 0x15c6, 0x15ca, 0x15ce, 0x15e2, 0x15e6, 0x164a, 0x1663, 0x1689, 0x168f, 0x174d, 0x1753, 0x1758, 0x1778, 0x1878, 0x187e, 0x1912, 0x19d4, 0x1a78, 0x1a80, 0x1a9e, 0x1aa3, 0x1ab7, 0x1ac1, 0x1ac7, 0x1adb, 0x1ae0, 0x1ae6, 0x1af4, 0x1b24, 0x1b31, 0x1b39, 0x1b3d, 0x1b53, 0x1bca, 0x1bdc, 0x1bde, 0x1be0, 0x3164, 0x1c21, 0x1c23, 0x1c25, 0x1c27, 0x1c29, 0x1c2b, 0x1c49, 0x1c4e, 0x1c53, 0x1c89, 0x1ccf, 0x1cdd, 0x1ce2, 0x1ceb, 0x1cf4, 0x1d02, 0x1d07, 0x1d0c, 0x1d1e, 0x1d30, 0x1d39, 0x1d3e, 0x1d62, 0x1d70, 0x1d72, 0x1d74, 0x1d94, 0x1daf, 0x1db1, 0x1db3, 0x1db5, 0x1db7, 0x1db9, 0x1dbb, 0x1dbd, 0x1ddd, 0x1ddf, 0x1de1, 0x1de3, 0x1de5, 0x1dec, 0x1dee, 0x1df0, 0x1df2, 0x1e01, 0x1e03, 0x1e05, 0x1e07, 0x1e09, 0x1e0b, 0x1e0d, 0x1e0f, 0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19, 0x1e1b, 0x1e1d, 0x1e21, 0x03f4, 0x1e23, 0x2207, 0x1e25, 0x2202, 0x1e27, 0x1e2f, 0x03f4, 0x1e31, 0x2207, 0x1e33, 0x2202, 0x1e35, 0x1e3d, 0x03f4, 0x1e3f, 0x2207, 0x1e41, 0x2202, 0x1e43, 0x1e4b, 0x03f4, 0x1e4d, 0x2207, 0x1e4f, 0x2202, 0x1e51, 0x1e59, 0x03f4, 0x1e5b, 0x2207, 0x1e5d, 0x2202, 0x1e5f, 0x1e69, 0x1e6b, 0x1e6d, 0x1e6f, 0x1e71, 0x1e73, 0x1e75, 0x1e77, 0x1e79, 0x1e81, 0x1ea4, 0x1ea8, 0x1eae, 0x1ecb, 0x062d, 0x1ed3, 0x1edf, 0x062c, 0x1eef, 0x1f5f, 0x1f6b, 0x1f7e, 0x1f90, 0x1fa3, 0x1fa5, 0x1fa9, 0x1faf, 0x1fb5, 0x1fb7, 0x1fbb, 0x1fbd, 0x1fc5, 0x1fc8, 0x1fca, 0x1fd0, 0x1fd2, 0x30b5, 0x1fd8, 0x2030, 0x2046, 0x204a, 0x204c, 0x2051, 0x209e, 0x20af, 0x21b0, 0x21c0, 0x21c6, 0x22c0, 0x23de, }; static const uint8_t unicode_decomp_data[9452] = { 0x20, 0x88, 0x20, 0x84, 0x32, 0x33, 0x20, 0x81, 0x20, 0xa7, 0x31, 0x6f, 0x31, 0xd0, 0x34, 0x31, 0xd0, 0x32, 0x33, 0xd0, 0x34, 0x41, 0x80, 0x41, 0x81, 0x41, 0x82, 0x41, 0x83, 0x41, 0x88, 0x41, 0x8a, 0x00, 0x00, 0x43, 0xa7, 0x45, 0x80, 0x45, 0x81, 0x45, 0x82, 0x45, 0x88, 0x49, 0x80, 0x49, 0x81, 0x49, 0x82, 0x49, 0x88, 0x00, 0x00, 0x4e, 0x83, 0x4f, 0x80, 0x4f, 0x81, 0x4f, 0x82, 0x4f, 0x83, 0x4f, 0x88, 0x00, 0x00, 0x00, 0x00, 0x55, 0x80, 0x55, 0x81, 0x55, 0x82, 0x55, 0x88, 0x59, 0x81, 0x00, 0x00, 0x00, 0x00, 0x61, 0x80, 0x61, 0x81, 0x61, 0x82, 0x61, 0x83, 0x61, 0x88, 0x61, 0x8a, 0x00, 0x00, 0x63, 0xa7, 0x65, 0x80, 0x65, 0x81, 0x65, 0x82, 0x65, 0x88, 0x69, 0x80, 0x69, 0x81, 0x69, 0x82, 0x69, 0x88, 0x00, 0x00, 0x6e, 0x83, 0x6f, 0x80, 0x6f, 0x81, 0x6f, 0x82, 0x6f, 0x83, 0x6f, 0x88, 0x00, 0x00, 0x00, 0x00, 0x75, 0x80, 0x75, 0x81, 0x75, 0x82, 0x75, 0x88, 0x79, 0x81, 0x00, 0x00, 0x79, 0x88, 0x41, 0x84, 0x41, 0x86, 0x41, 0xa8, 0x43, 0x81, 0x43, 0x82, 0x43, 0x87, 0x43, 0x8c, 0x44, 0x8c, 0x45, 0x84, 0x45, 0x86, 0x45, 0x87, 0x45, 0xa8, 0x45, 0x8c, 0x47, 0x82, 0x47, 0x86, 0x47, 0x87, 0x47, 0xa7, 0x48, 0x82, 0x49, 0x83, 0x49, 0x84, 0x49, 0x86, 0x49, 0xa8, 0x49, 0x87, 0x49, 0x4a, 0x69, 0x6a, 0x4a, 0x82, 0x4b, 0xa7, 0x4c, 0x81, 0x4c, 0xa7, 0x4c, 0x8c, 0x4c, 0x00, 0x00, 0x6b, 0x20, 0x6b, 0x4e, 0x81, 0x4e, 0xa7, 0x4e, 0x8c, 0xbc, 0x02, 0x6e, 0x4f, 0x84, 0x4f, 0x86, 0x4f, 0x8b, 0x52, 0x81, 0x52, 0xa7, 0x52, 0x8c, 0x53, 0x81, 0x53, 0x82, 0x53, 0xa7, 0x53, 0x8c, 0x54, 0xa7, 0x54, 0x8c, 0x55, 0x83, 0x55, 0x84, 0x55, 0x86, 0x55, 0x8a, 0x55, 0x8b, 0x55, 0xa8, 0x57, 0x82, 0x59, 0x82, 0x59, 0x88, 0x5a, 0x81, 0x5a, 0x87, 0x5a, 0x8c, 0x4f, 0x9b, 0x55, 0x9b, 0x44, 0x00, 0x7d, 0x01, 0x44, 0x00, 0x7e, 0x01, 0x64, 0x00, 0x7e, 0x01, 0x4c, 0x4a, 0x4c, 0x6a, 0x6c, 0x6a, 0x4e, 0x4a, 0x4e, 0x6a, 0x6e, 0x6a, 0x41, 0x00, 0x8c, 0x49, 0x00, 0x8c, 0x4f, 0x00, 0x8c, 0x55, 0x00, 0x8c, 0xdc, 0x00, 0x84, 0xdc, 0x00, 0x81, 0xdc, 0x00, 0x8c, 0xdc, 0x00, 0x80, 0xc4, 0x00, 0x84, 0x26, 0x02, 0x84, 0xc6, 0x00, 0x84, 0x47, 0x8c, 0x4b, 0x8c, 0x4f, 0xa8, 0xea, 0x01, 0x84, 0xeb, 0x01, 0x84, 0xb7, 0x01, 0x8c, 0x92, 0x02, 0x8c, 0x6a, 0x00, 0x8c, 0x44, 0x5a, 0x44, 0x7a, 0x64, 0x7a, 0x47, 0x81, 0x4e, 0x00, 0x80, 0xc5, 0x00, 0x81, 0xc6, 0x00, 0x81, 0xd8, 0x00, 0x81, 0x41, 0x8f, 0x41, 0x91, 0x45, 0x8f, 0x45, 0x91, 0x49, 0x8f, 0x49, 0x91, 0x4f, 0x8f, 0x4f, 0x91, 0x52, 0x8f, 0x52, 0x91, 0x55, 0x8f, 0x55, 0x91, 0x53, 0xa6, 0x54, 0xa6, 0x48, 0x8c, 0x41, 0x00, 0x87, 0x45, 0x00, 0xa7, 0xd6, 0x00, 0x84, 0xd5, 0x00, 0x84, 0x4f, 0x00, 0x87, 0x2e, 0x02, 0x84, 0x59, 0x00, 0x84, 0x68, 0x00, 0x66, 0x02, 0x6a, 0x00, 0x72, 0x00, 0x79, 0x02, 0x7b, 0x02, 0x81, 0x02, 0x77, 0x00, 0x79, 0x00, 0x20, 0x86, 0x20, 0x87, 0x20, 0x8a, 0x20, 0xa8, 0x20, 0x83, 0x20, 0x8b, 0x63, 0x02, 0x6c, 0x00, 0x73, 0x00, 0x78, 0x00, 0x95, 0x02, 0x80, 0x81, 0x00, 0x93, 0x88, 0x81, 0x20, 0xc5, 0x20, 0x81, 0xa8, 0x00, 0x81, 0x91, 0x03, 0x81, 0x95, 0x03, 0x81, 0x97, 0x03, 0x81, 0x99, 0x03, 0x81, 0x00, 0x00, 0x00, 0x9f, 0x03, 0x81, 0x00, 0x00, 0x00, 0xa5, 0x03, 0x81, 0xa9, 0x03, 0x81, 0xca, 0x03, 0x81, 0x01, 0x03, 0x98, 0x07, 0xa4, 0x07, 0xb0, 0x00, 0xb4, 0x00, 0xb6, 0x00, 0xb8, 0x00, 0xca, 0x00, 0x01, 0x03, 0xb8, 0x07, 0xc4, 0x07, 0xbe, 0x00, 0xc4, 0x00, 0xc8, 0x00, 0xa5, 0x03, 0x0d, 0x13, 0x00, 0x01, 0x03, 0xd1, 0x00, 0xd1, 0x07, 0xc6, 0x03, 0xc0, 0x03, 0xba, 0x03, 0xc1, 0x03, 0xc2, 0x03, 0x00, 0x00, 0x98, 0x03, 0xb5, 0x03, 0x15, 0x04, 0x80, 0x15, 0x04, 0x88, 0x00, 0x00, 0x00, 0x13, 0x04, 0x81, 0x06, 0x04, 0x88, 0x1a, 0x04, 0x81, 0x18, 0x04, 0x80, 0x23, 0x04, 0x86, 0x18, 0x04, 0x86, 0x38, 0x04, 0x86, 0x35, 0x04, 0x80, 0x35, 0x04, 0x88, 0x00, 0x00, 0x00, 0x33, 0x04, 0x81, 0x56, 0x04, 0x88, 0x3a, 0x04, 0x81, 0x38, 0x04, 0x80, 0x43, 0x04, 0x86, 0x74, 0x04, 0x8f, 0x16, 0x04, 0x86, 0x10, 0x04, 0x86, 0x10, 0x04, 0x88, 0x15, 0x04, 0x86, 0xd8, 0x04, 0x88, 0x16, 0x04, 0x88, 0x17, 0x04, 0x88, 0x18, 0x04, 0x84, 0x18, 0x04, 0x88, 0x1e, 0x04, 0x88, 0xe8, 0x04, 0x88, 0x2d, 0x04, 0x88, 0x23, 0x04, 0x84, 0x23, 0x04, 0x88, 0x23, 0x04, 0x8b, 0x27, 0x04, 0x88, 0x2b, 0x04, 0x88, 0x65, 0x05, 0x82, 0x05, 0x27, 0x06, 0x00, 0x2c, 0x00, 0x2d, 0x21, 0x2d, 0x00, 0x2e, 0x23, 0x2d, 0x27, 0x06, 0x00, 0x4d, 0x21, 0x4d, 0xa0, 0x4d, 0x23, 0x4d, 0xd5, 0x06, 0x54, 0x06, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x06, 0x54, 0x06, 0xd2, 0x06, 0x54, 0x06, 0x28, 0x09, 0x3c, 0x09, 0x30, 0x09, 0x3c, 0x09, 0x33, 0x09, 0x3c, 0x09, 0x15, 0x09, 0x00, 0x27, 0x01, 0x27, 0x02, 0x27, 0x07, 0x27, 0x0c, 0x27, 0x0d, 0x27, 0x16, 0x27, 0x1a, 0x27, 0xbe, 0x09, 0x09, 0x00, 0x09, 0x19, 0xa1, 0x09, 0xbc, 0x09, 0xaf, 0x09, 0xbc, 0x09, 0x32, 0x0a, 0x3c, 0x0a, 0x38, 0x0a, 0x3c, 0x0a, 0x16, 0x0a, 0x00, 0x26, 0x01, 0x26, 0x06, 0x26, 0x2b, 0x0a, 0x3c, 0x0a, 0x47, 0x0b, 0x56, 0x0b, 0x3e, 0x0b, 0x09, 0x00, 0x09, 0x19, 0x21, 0x0b, 0x3c, 0x0b, 0x92, 0x0b, 0xd7, 0x0b, 0xbe, 0x0b, 0x08, 0x00, 0x09, 0x00, 0x08, 0x19, 0x46, 0x0c, 0x56, 0x0c, 0xbf, 0x0c, 0xd5, 0x0c, 0xc6, 0x0c, 0xd5, 0x0c, 0xc2, 0x0c, 0x04, 0x00, 0x08, 0x13, 0x3e, 0x0d, 0x08, 0x00, 0x09, 0x00, 0x08, 0x19, 0xd9, 0x0d, 0xca, 0x0d, 0xca, 0x0d, 0x0f, 0x05, 0x12, 0x00, 0x0f, 0x15, 0x4d, 0x0e, 0x32, 0x0e, 0xcd, 0x0e, 0xb2, 0x0e, 0x99, 0x0e, 0x12, 0x00, 0x12, 0x08, 0x42, 0x0f, 0xb7, 0x0f, 0x4c, 0x0f, 0xb7, 0x0f, 0x51, 0x0f, 0xb7, 0x0f, 0x56, 0x0f, 0xb7, 0x0f, 0x5b, 0x0f, 0xb7, 0x0f, 0x40, 0x0f, 0xb5, 0x0f, 0x71, 0x0f, 0x72, 0x0f, 0x71, 0x0f, 0x00, 0x03, 0x41, 0x0f, 0xb2, 0x0f, 0x81, 0x0f, 0xb3, 0x0f, 0x80, 0x0f, 0xb3, 0x0f, 0x81, 0x0f, 0x71, 0x0f, 0x80, 0x0f, 0x92, 0x0f, 0xb7, 0x0f, 0x9c, 0x0f, 0xb7, 0x0f, 0xa1, 0x0f, 0xb7, 0x0f, 0xa6, 0x0f, 0xb7, 0x0f, 0xab, 0x0f, 0xb7, 0x0f, 0x90, 0x0f, 0xb5, 0x0f, 0x25, 0x10, 0x2e, 0x10, 0x05, 0x1b, 0x35, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1b, 0x35, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x09, 0x1b, 0x35, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0x35, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x1b, 0x35, 0x1b, 0x11, 0x1b, 0x35, 0x1b, 0x3a, 0x1b, 0x35, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x1b, 0x35, 0x1b, 0x3e, 0x1b, 0x35, 0x1b, 0x42, 0x1b, 0x35, 0x1b, 0x41, 0x00, 0xc6, 0x00, 0x42, 0x00, 0x00, 0x00, 0x44, 0x00, 0x45, 0x00, 0x8e, 0x01, 0x47, 0x00, 0x4f, 0x00, 0x22, 0x02, 0x50, 0x00, 0x52, 0x00, 0x54, 0x00, 0x55, 0x00, 0x57, 0x00, 0x61, 0x00, 0x50, 0x02, 0x51, 0x02, 0x02, 0x1d, 0x62, 0x00, 0x64, 0x00, 0x65, 0x00, 0x59, 0x02, 0x5b, 0x02, 0x5c, 0x02, 0x67, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x6d, 0x00, 0x4b, 0x01, 0x6f, 0x00, 0x54, 0x02, 0x16, 0x1d, 0x17, 0x1d, 0x70, 0x00, 0x74, 0x00, 0x75, 0x00, 0x1d, 0x1d, 0x6f, 0x02, 0x76, 0x00, 0x25, 0x1d, 0xb2, 0x03, 0xb3, 0x03, 0xb4, 0x03, 0xc6, 0x03, 0xc7, 0x03, 0x69, 0x00, 0x72, 0x00, 0x75, 0x00, 0x76, 0x00, 0xb2, 0x03, 0xb3, 0x03, 0xc1, 0x03, 0xc6, 0x03, 0xc7, 0x03, 0x52, 0x02, 0x63, 0x00, 0x55, 0x02, 0xf0, 0x00, 0x5c, 0x02, 0x66, 0x00, 0x5f, 0x02, 0x61, 0x02, 0x65, 0x02, 0x68, 0x02, 0x69, 0x02, 0x6a, 0x02, 0x7b, 0x1d, 0x9d, 0x02, 0x6d, 0x02, 0x85, 0x1d, 0x9f, 0x02, 0x71, 0x02, 0x70, 0x02, 0x72, 0x02, 0x73, 0x02, 0x74, 0x02, 0x75, 0x02, 0x78, 0x02, 0x82, 0x02, 0x83, 0x02, 0xab, 0x01, 0x89, 0x02, 0x8a, 0x02, 0x1c, 0x1d, 0x8b, 0x02, 0x8c, 0x02, 0x7a, 0x00, 0x90, 0x02, 0x91, 0x02, 0x92, 0x02, 0xb8, 0x03, 0x41, 0x00, 0xa5, 0x42, 0x00, 0x87, 0x42, 0x00, 0xa3, 0x42, 0x00, 0xb1, 0xc7, 0x00, 0x81, 0x44, 0x00, 0x87, 0x44, 0x00, 0xa3, 0x44, 0x00, 0xb1, 0x44, 0x00, 0xa7, 0x44, 0x00, 0xad, 0x12, 0x01, 0x80, 0x12, 0x01, 0x81, 0x45, 0x00, 0xad, 0x45, 0x00, 0xb0, 0x28, 0x02, 0x86, 0x46, 0x00, 0x87, 0x47, 0x00, 0x84, 0x48, 0x00, 0x87, 0x48, 0x00, 0xa3, 0x48, 0x00, 0x88, 0x48, 0x00, 0xa7, 0x48, 0x00, 0xae, 0x49, 0x00, 0xb0, 0xcf, 0x00, 0x81, 0x4b, 0x00, 0x81, 0x4b, 0x00, 0xa3, 0x4b, 0x00, 0xb1, 0x4c, 0x00, 0xa3, 0x36, 0x1e, 0x84, 0x4c, 0xb1, 0x4c, 0xad, 0x4d, 0x81, 0x4d, 0x87, 0x4d, 0xa3, 0x4e, 0x87, 0x4e, 0xa3, 0x4e, 0xb1, 0x4e, 0xad, 0xd5, 0x00, 0x81, 0xd5, 0x00, 0x88, 0x4c, 0x01, 0x80, 0x4c, 0x01, 0x81, 0x50, 0x00, 0x81, 0x50, 0x00, 0x87, 0x52, 0x00, 0x87, 0x52, 0x00, 0xa3, 0x5a, 0x1e, 0x84, 0x52, 0x00, 0xb1, 0x53, 0x00, 0x87, 0x53, 0x00, 0xa3, 0x5a, 0x01, 0x87, 0x60, 0x01, 0x87, 0x62, 0x1e, 0x87, 0x54, 0x00, 0x87, 0x54, 0x00, 0xa3, 0x54, 0x00, 0xb1, 0x54, 0x00, 0xad, 0x55, 0x00, 0xa4, 0x55, 0x00, 0xb0, 0x55, 0x00, 0xad, 0x68, 0x01, 0x81, 0x6a, 0x01, 0x88, 0x56, 0x83, 0x56, 0xa3, 0x57, 0x80, 0x57, 0x81, 0x57, 0x88, 0x57, 0x87, 0x57, 0xa3, 0x58, 0x87, 0x58, 0x88, 0x59, 0x87, 0x5a, 0x82, 0x5a, 0xa3, 0x5a, 0xb1, 0x68, 0xb1, 0x74, 0x88, 0x77, 0x8a, 0x79, 0x8a, 0x61, 0x00, 0xbe, 0x02, 0x7f, 0x01, 0x87, 0x41, 0x00, 0xa3, 0x41, 0x00, 0x89, 0xc2, 0x00, 0x81, 0xc2, 0x00, 0x80, 0xc2, 0x00, 0x89, 0xc2, 0x00, 0x83, 0xa0, 0x1e, 0x82, 0x02, 0x01, 0x81, 0x02, 0x01, 0x80, 0x02, 0x01, 0x89, 0x02, 0x01, 0x83, 0xa0, 0x1e, 0x86, 0x45, 0x00, 0xa3, 0x45, 0x00, 0x89, 0x45, 0x00, 0x83, 0xca, 0x00, 0x81, 0xca, 0x00, 0x80, 0xca, 0x00, 0x89, 0xca, 0x00, 0x83, 0xb8, 0x1e, 0x82, 0x49, 0x00, 0x89, 0x49, 0x00, 0xa3, 0x4f, 0x00, 0xa3, 0x4f, 0x00, 0x89, 0xd4, 0x00, 0x81, 0xd4, 0x00, 0x80, 0xd4, 0x00, 0x89, 0xd4, 0x00, 0x83, 0xcc, 0x1e, 0x82, 0xa0, 0x01, 0x81, 0xa0, 0x01, 0x80, 0xa0, 0x01, 0x89, 0xa0, 0x01, 0x83, 0xa0, 0x01, 0xa3, 0x55, 0x00, 0xa3, 0x55, 0x00, 0x89, 0xaf, 0x01, 0x81, 0xaf, 0x01, 0x80, 0xaf, 0x01, 0x89, 0xaf, 0x01, 0x83, 0xaf, 0x01, 0xa3, 0x59, 0x00, 0x80, 0x59, 0x00, 0xa3, 0x59, 0x00, 0x89, 0x59, 0x00, 0x83, 0xb1, 0x03, 0x13, 0x03, 0x00, 0x1f, 0x80, 0x00, 0x1f, 0x81, 0x00, 0x1f, 0xc2, 0x91, 0x03, 0x13, 0x03, 0x08, 0x1f, 0x80, 0x08, 0x1f, 0x81, 0x08, 0x1f, 0xc2, 0xb5, 0x03, 0x13, 0x03, 0x10, 0x1f, 0x80, 0x10, 0x1f, 0x81, 0x95, 0x03, 0x13, 0x03, 0x18, 0x1f, 0x80, 0x18, 0x1f, 0x81, 0xb7, 0x03, 0x93, 0xb7, 0x03, 0x94, 0x20, 0x1f, 0x80, 0x21, 0x1f, 0x80, 0x20, 0x1f, 0x81, 0x21, 0x1f, 0x81, 0x20, 0x1f, 0xc2, 0x21, 0x1f, 0xc2, 0x97, 0x03, 0x93, 0x97, 0x03, 0x94, 0x28, 0x1f, 0x80, 0x29, 0x1f, 0x80, 0x28, 0x1f, 0x81, 0x29, 0x1f, 0x81, 0x28, 0x1f, 0xc2, 0x29, 0x1f, 0xc2, 0xb9, 0x03, 0x93, 0xb9, 0x03, 0x94, 0x30, 0x1f, 0x80, 0x31, 0x1f, 0x80, 0x30, 0x1f, 0x81, 0x31, 0x1f, 0x81, 0x30, 0x1f, 0xc2, 0x31, 0x1f, 0xc2, 0x99, 0x03, 0x93, 0x99, 0x03, 0x94, 0x38, 0x1f, 0x80, 0x39, 0x1f, 0x80, 0x38, 0x1f, 0x81, 0x39, 0x1f, 0x81, 0x38, 0x1f, 0xc2, 0x39, 0x1f, 0xc2, 0xbf, 0x03, 0x93, 0xbf, 0x03, 0x94, 0x40, 0x1f, 0x80, 0x40, 0x1f, 0x81, 0x9f, 0x03, 0x13, 0x03, 0x48, 0x1f, 0x80, 0x48, 0x1f, 0x81, 0xc5, 0x03, 0x13, 0x03, 0x50, 0x1f, 0x80, 0x50, 0x1f, 0x81, 0x50, 0x1f, 0xc2, 0xa5, 0x03, 0x94, 0x00, 0x00, 0x00, 0x59, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x59, 0x1f, 0x81, 0x00, 0x00, 0x00, 0x59, 0x1f, 0xc2, 0xc9, 0x03, 0x93, 0xc9, 0x03, 0x94, 0x60, 0x1f, 0x80, 0x61, 0x1f, 0x80, 0x60, 0x1f, 0x81, 0x61, 0x1f, 0x81, 0x60, 0x1f, 0xc2, 0x61, 0x1f, 0xc2, 0xa9, 0x03, 0x93, 0xa9, 0x03, 0x94, 0x68, 0x1f, 0x80, 0x69, 0x1f, 0x80, 0x68, 0x1f, 0x81, 0x69, 0x1f, 0x81, 0x68, 0x1f, 0xc2, 0x69, 0x1f, 0xc2, 0xb1, 0x03, 0x80, 0xb5, 0x03, 0x80, 0xb7, 0x03, 0x80, 0xb9, 0x03, 0x80, 0xbf, 0x03, 0x80, 0xc5, 0x03, 0x80, 0xc9, 0x03, 0x80, 0x00, 0x1f, 0x45, 0x03, 0x20, 0x1f, 0x45, 0x03, 0x60, 0x1f, 0x45, 0x03, 0xb1, 0x03, 0x86, 0xb1, 0x03, 0x84, 0x70, 0x1f, 0xc5, 0xb1, 0x03, 0xc5, 0xac, 0x03, 0xc5, 0x00, 0x00, 0x00, 0xb1, 0x03, 0xc2, 0xb6, 0x1f, 0xc5, 0x91, 0x03, 0x86, 0x91, 0x03, 0x84, 0x91, 0x03, 0x80, 0x91, 0x03, 0xc5, 0x20, 0x93, 0x20, 0x93, 0x20, 0xc2, 0xa8, 0x00, 0xc2, 0x74, 0x1f, 0xc5, 0xb7, 0x03, 0xc5, 0xae, 0x03, 0xc5, 0x00, 0x00, 0x00, 0xb7, 0x03, 0xc2, 0xc6, 0x1f, 0xc5, 0x95, 0x03, 0x80, 0x97, 0x03, 0x80, 0x97, 0x03, 0xc5, 0xbf, 0x1f, 0x80, 0xbf, 0x1f, 0x81, 0xbf, 0x1f, 0xc2, 0xb9, 0x03, 0x86, 0xb9, 0x03, 0x84, 0xca, 0x03, 0x80, 0x00, 0x03, 0xb9, 0x42, 0xca, 0x42, 0x99, 0x06, 0x99, 0x04, 0x99, 0x00, 0xfe, 0x1f, 0x80, 0xfe, 0x1f, 0x81, 0xfe, 0x1f, 0xc2, 0xc5, 0x03, 0x86, 0xc5, 0x03, 0x84, 0xcb, 0x03, 0x80, 0x00, 0x03, 0xc1, 0x13, 0xc1, 0x14, 0xc5, 0x42, 0xcb, 0x42, 0xa5, 0x06, 0xa5, 0x04, 0xa5, 0x00, 0xa1, 0x03, 0x94, 0xa8, 0x00, 0x80, 0x85, 0x03, 0x60, 0x00, 0x7c, 0x1f, 0xc5, 0xc9, 0x03, 0xc5, 0xce, 0x03, 0xc5, 0x00, 0x00, 0x00, 0xc9, 0x03, 0xc2, 0xf6, 0x1f, 0xc5, 0x9f, 0x03, 0x80, 0xa9, 0x03, 0x80, 0xa9, 0x03, 0xc5, 0x20, 0x94, 0x02, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xb3, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x32, 0x20, 0x32, 0x20, 0x32, 0x20, 0x00, 0x00, 0x00, 0x35, 0x20, 0x35, 0x20, 0x35, 0x20, 0x00, 0x00, 0x00, 0x21, 0x21, 0x00, 0x00, 0x20, 0x85, 0x3f, 0x3f, 0x3f, 0x21, 0x21, 0x3f, 0x32, 0x20, 0x00, 0x00, 0x00, 0x00, 0x30, 0x69, 0x00, 0x00, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2b, 0x3d, 0x28, 0x29, 0x6e, 0x30, 0x00, 0x2b, 0x00, 0x12, 0x22, 0x3d, 0x00, 0x28, 0x00, 0x29, 0x00, 0x00, 0x00, 0x61, 0x00, 0x65, 0x00, 0x6f, 0x00, 0x78, 0x00, 0x59, 0x02, 0x68, 0x6b, 0x6c, 0x6d, 0x6e, 0x70, 0x73, 0x74, 0x52, 0x73, 0x61, 0x2f, 0x63, 0x61, 0x2f, 0x73, 0xb0, 0x00, 0x43, 0x63, 0x2f, 0x6f, 0x63, 0x2f, 0x75, 0xb0, 0x00, 0x46, 0x48, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x20, 0xdf, 0x01, 0x01, 0x04, 0x24, 0x4e, 0x6f, 0x50, 0x51, 0x52, 0x52, 0x52, 0x53, 0x4d, 0x54, 0x45, 0x4c, 0x54, 0x4d, 0x4b, 0x00, 0xc5, 0x00, 0x42, 0x43, 0x00, 0x65, 0x45, 0x46, 0x00, 0x4d, 0x6f, 0xd0, 0x05, 0x46, 0x41, 0x58, 0xc0, 0x03, 0xb3, 0x03, 0x93, 0x03, 0xa0, 0x03, 0x11, 0x22, 0x44, 0x64, 0x65, 0x69, 0x6a, 0x31, 0xd0, 0x37, 0x31, 0xd0, 0x39, 0x31, 0xd0, 0x31, 0x30, 0x31, 0xd0, 0x33, 0x32, 0xd0, 0x33, 0x31, 0xd0, 0x35, 0x32, 0xd0, 0x35, 0x33, 0xd0, 0x35, 0x34, 0xd0, 0x35, 0x31, 0xd0, 0x36, 0x35, 0xd0, 0x36, 0x31, 0xd0, 0x38, 0x33, 0xd0, 0x38, 0x35, 0xd0, 0x38, 0x37, 0xd0, 0x38, 0x31, 0xd0, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x56, 0x56, 0x49, 0x56, 0x49, 0x49, 0x56, 0x49, 0x49, 0x49, 0x49, 0x58, 0x58, 0x49, 0x58, 0x49, 0x49, 0x4c, 0x43, 0x44, 0x4d, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x76, 0x76, 0x69, 0x76, 0x69, 0x69, 0x76, 0x69, 0x69, 0x69, 0x69, 0x78, 0x78, 0x69, 0x78, 0x69, 0x69, 0x6c, 0x63, 0x64, 0x6d, 0x30, 0xd0, 0x33, 0x90, 0x21, 0xb8, 0x92, 0x21, 0xb8, 0x94, 0x21, 0xb8, 0xd0, 0x21, 0xb8, 0xd4, 0x21, 0xb8, 0xd2, 0x21, 0xb8, 0x03, 0x22, 0xb8, 0x08, 0x22, 0xb8, 0x0b, 0x22, 0xb8, 0x23, 0x22, 0xb8, 0x00, 0x00, 0x00, 0x25, 0x22, 0xb8, 0x2b, 0x22, 0x2b, 0x22, 0x2b, 0x22, 0x00, 0x00, 0x00, 0x2e, 0x22, 0x2e, 0x22, 0x2e, 0x22, 0x00, 0x00, 0x00, 0x3c, 0x22, 0xb8, 0x43, 0x22, 0xb8, 0x45, 0x22, 0xb8, 0x00, 0x00, 0x00, 0x48, 0x22, 0xb8, 0x3d, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x61, 0x22, 0xb8, 0x4d, 0x22, 0xb8, 0x3c, 0x00, 0xb8, 0x3e, 0x00, 0xb8, 0x64, 0x22, 0xb8, 0x65, 0x22, 0xb8, 0x72, 0x22, 0xb8, 0x76, 0x22, 0xb8, 0x7a, 0x22, 0xb8, 0x82, 0x22, 0xb8, 0x86, 0x22, 0xb8, 0xa2, 0x22, 0xb8, 0xa8, 0x22, 0xb8, 0xa9, 0x22, 0xb8, 0xab, 0x22, 0xb8, 0x7c, 0x22, 0xb8, 0x91, 0x22, 0xb8, 0xb2, 0x22, 0x38, 0x03, 0x08, 0x30, 0x31, 0x00, 0x31, 0x00, 0x30, 0x00, 0x32, 0x30, 0x28, 0x00, 0x31, 0x00, 0x29, 0x00, 0x28, 0x00, 0x31, 0x00, 0x30, 0x00, 0x29, 0x00, 0x28, 0x32, 0x30, 0x29, 0x31, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x32, 0x30, 0x2e, 0x28, 0x00, 0x61, 0x00, 0x29, 0x00, 0x41, 0x00, 0x61, 0x00, 0x2b, 0x22, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x3a, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0xdd, 0x2a, 0xb8, 0x6a, 0x56, 0x00, 0x4e, 0x00, 0x28, 0x36, 0x3f, 0x59, 0x85, 0x8c, 0xa0, 0xba, 0x3f, 0x51, 0x00, 0x26, 0x2c, 0x43, 0x57, 0x6c, 0xa1, 0xb6, 0xc1, 0x9b, 0x52, 0x00, 0x5e, 0x7a, 0x7f, 0x9d, 0xa6, 0xc1, 0xce, 0xe7, 0xb6, 0x53, 0xc8, 0x53, 0xe3, 0x53, 0xd7, 0x56, 0x1f, 0x57, 0xeb, 0x58, 0x02, 0x59, 0x0a, 0x59, 0x15, 0x59, 0x27, 0x59, 0x73, 0x59, 0x50, 0x5b, 0x80, 0x5b, 0xf8, 0x5b, 0x0f, 0x5c, 0x22, 0x5c, 0x38, 0x5c, 0x6e, 0x5c, 0x71, 0x5c, 0xdb, 0x5d, 0xe5, 0x5d, 0xf1, 0x5d, 0xfe, 0x5d, 0x72, 0x5e, 0x7a, 0x5e, 0x7f, 0x5e, 0xf4, 0x5e, 0xfe, 0x5e, 0x0b, 0x5f, 0x13, 0x5f, 0x50, 0x5f, 0x61, 0x5f, 0x73, 0x5f, 0xc3, 0x5f, 0x08, 0x62, 0x36, 0x62, 0x4b, 0x62, 0x2f, 0x65, 0x34, 0x65, 0x87, 0x65, 0x97, 0x65, 0xa4, 0x65, 0xb9, 0x65, 0xe0, 0x65, 0xe5, 0x65, 0xf0, 0x66, 0x08, 0x67, 0x28, 0x67, 0x20, 0x6b, 0x62, 0x6b, 0x79, 0x6b, 0xb3, 0x6b, 0xcb, 0x6b, 0xd4, 0x6b, 0xdb, 0x6b, 0x0f, 0x6c, 0x14, 0x6c, 0x34, 0x6c, 0x6b, 0x70, 0x2a, 0x72, 0x36, 0x72, 0x3b, 0x72, 0x3f, 0x72, 0x47, 0x72, 0x59, 0x72, 0x5b, 0x72, 0xac, 0x72, 0x84, 0x73, 0x89, 0x73, 0xdc, 0x74, 0xe6, 0x74, 0x18, 0x75, 0x1f, 0x75, 0x28, 0x75, 0x30, 0x75, 0x8b, 0x75, 0x92, 0x75, 0x76, 0x76, 0x7d, 0x76, 0xae, 0x76, 0xbf, 0x76, 0xee, 0x76, 0xdb, 0x77, 0xe2, 0x77, 0xf3, 0x77, 0x3a, 0x79, 0xb8, 0x79, 0xbe, 0x79, 0x74, 0x7a, 0xcb, 0x7a, 0xf9, 0x7a, 0x73, 0x7c, 0xf8, 0x7c, 0x36, 0x7f, 0x51, 0x7f, 0x8a, 0x7f, 0xbd, 0x7f, 0x01, 0x80, 0x0c, 0x80, 0x12, 0x80, 0x33, 0x80, 0x7f, 0x80, 0x89, 0x80, 0xe3, 0x81, 0x00, 0x07, 0x10, 0x19, 0x29, 0x38, 0x3c, 0x8b, 0x8f, 0x95, 0x4d, 0x86, 0x6b, 0x86, 0x40, 0x88, 0x4c, 0x88, 0x63, 0x88, 0x7e, 0x89, 0x8b, 0x89, 0xd2, 0x89, 0x00, 0x8a, 0x37, 0x8c, 0x46, 0x8c, 0x55, 0x8c, 0x78, 0x8c, 0x9d, 0x8c, 0x64, 0x8d, 0x70, 0x8d, 0xb3, 0x8d, 0xab, 0x8e, 0xca, 0x8e, 0x9b, 0x8f, 0xb0, 0x8f, 0xb5, 0x8f, 0x91, 0x90, 0x49, 0x91, 0xc6, 0x91, 0xcc, 0x91, 0xd1, 0x91, 0x77, 0x95, 0x80, 0x95, 0x1c, 0x96, 0xb6, 0x96, 0xb9, 0x96, 0xe8, 0x96, 0x51, 0x97, 0x5e, 0x97, 0x62, 0x97, 0x69, 0x97, 0xcb, 0x97, 0xed, 0x97, 0xf3, 0x97, 0x01, 0x98, 0xa8, 0x98, 0xdb, 0x98, 0xdf, 0x98, 0x96, 0x99, 0x99, 0x99, 0xac, 0x99, 0xa8, 0x9a, 0xd8, 0x9a, 0xdf, 0x9a, 0x25, 0x9b, 0x2f, 0x9b, 0x32, 0x9b, 0x3c, 0x9b, 0x5a, 0x9b, 0xe5, 0x9c, 0x75, 0x9e, 0x7f, 0x9e, 0xa5, 0x9e, 0x00, 0x16, 0x1e, 0x28, 0x2c, 0x54, 0x58, 0x69, 0x6e, 0x7b, 0x96, 0xa5, 0xad, 0xe8, 0xf7, 0xfb, 0x12, 0x30, 0x00, 0x00, 0x41, 0x53, 0x44, 0x53, 0x45, 0x53, 0x4b, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0x51, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0x53, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0x55, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0x57, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0x59, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0x61, 0x30, 0x99, 0x30, 0x64, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0x66, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0x68, 0x30, 0x99, 0x30, 0x6f, 0x30, 0x99, 0x30, 0x72, 0x30, 0x99, 0x30, 0x75, 0x30, 0x99, 0x30, 0x78, 0x30, 0x99, 0x30, 0x7b, 0x30, 0x99, 0x30, 0x46, 0x30, 0x99, 0x30, 0x20, 0x00, 0x99, 0x30, 0x9d, 0x30, 0x99, 0x30, 0x88, 0x30, 0x8a, 0x30, 0xab, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0xad, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0xaf, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0xb3, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x30, 0x99, 0x30, 0xc4, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x30, 0x99, 0x30, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x30, 0x99, 0x30, 0xcf, 0x30, 0x99, 0x30, 0xd2, 0x30, 0x99, 0x30, 0xd5, 0x30, 0x99, 0x30, 0xd8, 0x30, 0x99, 0x30, 0xdb, 0x30, 0x99, 0x30, 0xa6, 0x30, 0x99, 0x30, 0xef, 0x30, 0x99, 0x30, 0xfd, 0x30, 0x99, 0x30, 0xb3, 0x30, 0xc8, 0x30, 0x00, 0x11, 0x00, 0x01, 0xaa, 0x02, 0xac, 0xad, 0x03, 0x04, 0x05, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0x1a, 0x06, 0x07, 0x08, 0x21, 0x09, 0x11, 0x61, 0x11, 0x14, 0x11, 0x4c, 0x00, 0x01, 0xb3, 0xb4, 0xb8, 0xba, 0xbf, 0xc3, 0xc5, 0x08, 0xc9, 0xcb, 0x09, 0x0a, 0x0c, 0x0e, 0x0f, 0x13, 0x15, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1e, 0x22, 0x2c, 0x33, 0x38, 0xdd, 0xde, 0x43, 0x44, 0x45, 0x70, 0x71, 0x74, 0x7d, 0x7e, 0x80, 0x8a, 0x8d, 0x00, 0x4e, 0x8c, 0x4e, 0x09, 0x4e, 0xdb, 0x56, 0x0a, 0x4e, 0x2d, 0x4e, 0x0b, 0x4e, 0x32, 0x75, 0x59, 0x4e, 0x19, 0x4e, 0x01, 0x4e, 0x29, 0x59, 0x30, 0x57, 0xba, 0x4e, 0x28, 0x00, 0x29, 0x00, 0x00, 0x11, 0x02, 0x11, 0x03, 0x11, 0x05, 0x11, 0x06, 0x11, 0x07, 0x11, 0x09, 0x11, 0x0b, 0x11, 0x0c, 0x11, 0x0e, 0x11, 0x0f, 0x11, 0x10, 0x11, 0x11, 0x11, 0x12, 0x11, 0x28, 0x00, 0x00, 0x11, 0x61, 0x11, 0x29, 0x00, 0x28, 0x00, 0x02, 0x11, 0x61, 0x11, 0x29, 0x00, 0x28, 0x00, 0x05, 0x11, 0x61, 0x11, 0x29, 0x00, 0x28, 0x00, 0x09, 0x11, 0x61, 0x11, 0x29, 0x00, 0x28, 0x00, 0x0b, 0x11, 0x61, 0x11, 0x29, 0x00, 0x28, 0x00, 0x0e, 0x11, 0x61, 0x11, 0x29, 0x00, 0x28, 0x00, 0x0c, 0x11, 0x6e, 0x11, 0x29, 0x00, 0x28, 0x00, 0x0b, 0x11, 0x69, 0x11, 0x0c, 0x11, 0x65, 0x11, 0xab, 0x11, 0x29, 0x00, 0x28, 0x00, 0x0b, 0x11, 0x69, 0x11, 0x12, 0x11, 0x6e, 0x11, 0x29, 0x00, 0x28, 0x00, 0x29, 0x00, 0x00, 0x4e, 0x8c, 0x4e, 0x09, 0x4e, 0xdb, 0x56, 0x94, 0x4e, 0x6d, 0x51, 0x03, 0x4e, 0x6b, 0x51, 0x5d, 0x4e, 0x41, 0x53, 0x08, 0x67, 0x6b, 0x70, 0x34, 0x6c, 0x28, 0x67, 0xd1, 0x91, 0x1f, 0x57, 0xe5, 0x65, 0x2a, 0x68, 0x09, 0x67, 0x3e, 0x79, 0x0d, 0x54, 0x79, 0x72, 0xa1, 0x8c, 0x5d, 0x79, 0xb4, 0x52, 0xe3, 0x4e, 0x7c, 0x54, 0x66, 0x5b, 0xe3, 0x76, 0x01, 0x4f, 0xc7, 0x8c, 0x54, 0x53, 0x6d, 0x79, 0x11, 0x4f, 0xea, 0x81, 0xf3, 0x81, 0x4f, 0x55, 0x7c, 0x5e, 0x87, 0x65, 0x8f, 0x7b, 0x50, 0x54, 0x45, 0x32, 0x00, 0x31, 0x00, 0x33, 0x00, 0x30, 0x00, 0x00, 0x11, 0x00, 0x02, 0x03, 0x05, 0x06, 0x07, 0x09, 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x00, 0x11, 0x00, 0x61, 0x02, 0x61, 0x03, 0x61, 0x05, 0x61, 0x06, 0x61, 0x07, 0x61, 0x09, 0x61, 0x0b, 0x61, 0x0c, 0x61, 0x0e, 0x11, 0x61, 0x11, 0x00, 0x11, 0x0e, 0x61, 0xb7, 0x00, 0x69, 0x0b, 0x11, 0x01, 0x63, 0x00, 0x69, 0x0b, 0x11, 0x6e, 0x11, 0x00, 0x4e, 0x8c, 0x4e, 0x09, 0x4e, 0xdb, 0x56, 0x94, 0x4e, 0x6d, 0x51, 0x03, 0x4e, 0x6b, 0x51, 0x5d, 0x4e, 0x41, 0x53, 0x08, 0x67, 0x6b, 0x70, 0x34, 0x6c, 0x28, 0x67, 0xd1, 0x91, 0x1f, 0x57, 0xe5, 0x65, 0x2a, 0x68, 0x09, 0x67, 0x3e, 0x79, 0x0d, 0x54, 0x79, 0x72, 0xa1, 0x8c, 0x5d, 0x79, 0xb4, 0x52, 0xd8, 0x79, 0x37, 0x75, 0x73, 0x59, 0x69, 0x90, 0x2a, 0x51, 0x70, 0x53, 0xe8, 0x6c, 0x05, 0x98, 0x11, 0x4f, 0x99, 0x51, 0x63, 0x6b, 0x0a, 0x4e, 0x2d, 0x4e, 0x0b, 0x4e, 0xe6, 0x5d, 0xf3, 0x53, 0x3b, 0x53, 0x97, 0x5b, 0x66, 0x5b, 0xe3, 0x76, 0x01, 0x4f, 0xc7, 0x8c, 0x54, 0x53, 0x1c, 0x59, 0x33, 0x00, 0x36, 0x00, 0x34, 0x00, 0x30, 0x00, 0x35, 0x30, 0x31, 0x00, 0x08, 0x67, 0x31, 0x00, 0x30, 0x00, 0x08, 0x67, 0x48, 0x67, 0x65, 0x72, 0x67, 0x65, 0x56, 0x4c, 0x54, 0x44, 0xa2, 0x30, 0x00, 0x02, 0x04, 0x06, 0x08, 0x09, 0x0b, 0x0d, 0x0f, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f, 0x22, 0x24, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x30, 0x33, 0x36, 0x39, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x42, 0x44, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4d, 0x4e, 0x4f, 0x50, 0xe4, 0x4e, 0x8c, 0x54, 0xa1, 0x30, 0x01, 0x30, 0x5b, 0x27, 0x01, 0x4a, 0x34, 0x00, 0x01, 0x52, 0x39, 0x01, 0xa2, 0x30, 0x00, 0x5a, 0x49, 0xa4, 0x30, 0x00, 0x27, 0x4f, 0x0c, 0xa4, 0x30, 0x00, 0x4f, 0x1d, 0x02, 0x05, 0x4f, 0xa8, 0x30, 0x00, 0x11, 0x07, 0x54, 0x21, 0xa8, 0x30, 0x00, 0x54, 0x03, 0x54, 0xa4, 0x30, 0x06, 0x4f, 0x15, 0x06, 0x58, 0x3c, 0x07, 0x00, 0x46, 0xab, 0x30, 0x00, 0x3e, 0x18, 0x1d, 0x00, 0x42, 0x3f, 0x51, 0xac, 0x30, 0x00, 0x41, 0x47, 0x00, 0x47, 0x32, 0xae, 0x30, 0xac, 0x30, 0xae, 0x30, 0x00, 0x1d, 0x4e, 0xad, 0x30, 0x00, 0x38, 0x3d, 0x4f, 0x01, 0x3e, 0x13, 0x4f, 0xad, 0x30, 0xed, 0x30, 0xad, 0x30, 0x00, 0x40, 0x03, 0x3c, 0x33, 0xad, 0x30, 0x00, 0x40, 0x34, 0x4f, 0x1b, 0x3e, 0xad, 0x30, 0x00, 0x40, 0x42, 0x16, 0x1b, 0xb0, 0x30, 0x00, 0x39, 0x30, 0xa4, 0x30, 0x0c, 0x45, 0x3c, 0x24, 0x4f, 0x0b, 0x47, 0x18, 0x00, 0x49, 0xaf, 0x30, 0x00, 0x3e, 0x4d, 0x1e, 0xb1, 0x30, 0x00, 0x4b, 0x08, 0x02, 0x3a, 0x19, 0x02, 0x4b, 0x2c, 0xa4, 0x30, 0x11, 0x00, 0x0b, 0x47, 0xb5, 0x30, 0x00, 0x3e, 0x0c, 0x47, 0x2b, 0xb0, 0x30, 0x07, 0x3a, 0x43, 0x00, 0xb9, 0x30, 0x02, 0x3a, 0x08, 0x02, 0x3a, 0x0f, 0x07, 0x43, 0x00, 0xb7, 0x30, 0x10, 0x00, 0x12, 0x34, 0x11, 0x3c, 0x13, 0x17, 0xa4, 0x30, 0x2a, 0x1f, 0x24, 0x2b, 0x00, 0x20, 0xbb, 0x30, 0x16, 0x41, 0x00, 0x38, 0x0d, 0xc4, 0x30, 0x0d, 0x38, 0x00, 0xd0, 0x30, 0x00, 0x2c, 0x1c, 0x1b, 0xa2, 0x30, 0x32, 0x00, 0x17, 0x26, 0x49, 0xaf, 0x30, 0x25, 0x00, 0x3c, 0xb3, 0x30, 0x21, 0x00, 0x20, 0x38, 0xa1, 0x30, 0x34, 0x00, 0x48, 0x22, 0x28, 0xa3, 0x30, 0x32, 0x00, 0x59, 0x25, 0xa7, 0x30, 0x2f, 0x1c, 0x10, 0x00, 0x44, 0xd5, 0x30, 0x00, 0x14, 0x1e, 0xaf, 0x30, 0x29, 0x00, 0x10, 0x4d, 0x3c, 0xda, 0x30, 0xbd, 0x30, 0xb8, 0x30, 0x22, 0x13, 0x1a, 0x20, 0x33, 0x0c, 0x22, 0x3b, 0x01, 0x22, 0x44, 0x00, 0x21, 0x44, 0x07, 0xa4, 0x30, 0x39, 0x00, 0x4f, 0x24, 0xc8, 0x30, 0x14, 0x23, 0x00, 0xdb, 0x30, 0xf3, 0x30, 0xc9, 0x30, 0x14, 0x2a, 0x00, 0x12, 0x33, 0x22, 0x12, 0x33, 0x2a, 0xa4, 0x30, 0x3a, 0x00, 0x0b, 0x49, 0xa4, 0x30, 0x3a, 0x00, 0x47, 0x3a, 0x1f, 0x2b, 0x3a, 0x47, 0x0b, 0xb7, 0x30, 0x27, 0x3c, 0x00, 0x30, 0x3c, 0xaf, 0x30, 0x30, 0x00, 0x3e, 0x44, 0xdf, 0x30, 0xea, 0x30, 0xd0, 0x30, 0x0f, 0x1a, 0x00, 0x2c, 0x1b, 0xe1, 0x30, 0xac, 0x30, 0xac, 0x30, 0x35, 0x00, 0x1c, 0x47, 0x35, 0x50, 0x1c, 0x3f, 0xa2, 0x30, 0x42, 0x5a, 0x27, 0x42, 0x5a, 0x49, 0x44, 0x00, 0x51, 0xc3, 0x30, 0x27, 0x00, 0x05, 0x28, 0xea, 0x30, 0xe9, 0x30, 0xd4, 0x30, 0x17, 0x00, 0x28, 0xd6, 0x30, 0x15, 0x26, 0x00, 0x15, 0xec, 0x30, 0xe0, 0x30, 0xb2, 0x30, 0x3a, 0x41, 0x16, 0x00, 0x41, 0xc3, 0x30, 0x2c, 0x00, 0x05, 0x30, 0x00, 0xb9, 0x70, 0x31, 0x00, 0x30, 0x00, 0xb9, 0x70, 0x32, 0x00, 0x30, 0x00, 0xb9, 0x70, 0x68, 0x50, 0x61, 0x64, 0x61, 0x41, 0x55, 0x62, 0x61, 0x72, 0x6f, 0x56, 0x70, 0x63, 0x64, 0x6d, 0x64, 0x00, 0x6d, 0x00, 0xb2, 0x00, 0x49, 0x00, 0x55, 0x00, 0x73, 0x5e, 0x10, 0x62, 0x2d, 0x66, 0x8c, 0x54, 0x27, 0x59, 0x63, 0x6b, 0x0e, 0x66, 0xbb, 0x6c, 0x2a, 0x68, 0x0f, 0x5f, 0x1a, 0x4f, 0x3e, 0x79, 0x70, 0x00, 0x41, 0x6e, 0x00, 0x41, 0xbc, 0x03, 0x41, 0x6d, 0x00, 0x41, 0x6b, 0x00, 0x41, 0x4b, 0x00, 0x42, 0x4d, 0x00, 0x42, 0x47, 0x00, 0x42, 0x63, 0x61, 0x6c, 0x6b, 0x63, 0x61, 0x6c, 0x70, 0x00, 0x46, 0x6e, 0x00, 0x46, 0xbc, 0x03, 0x46, 0xbc, 0x03, 0x67, 0x6d, 0x00, 0x67, 0x6b, 0x00, 0x67, 0x48, 0x00, 0x7a, 0x6b, 0x48, 0x7a, 0x4d, 0x48, 0x7a, 0x47, 0x48, 0x7a, 0x54, 0x48, 0x7a, 0xbc, 0x03, 0x13, 0x21, 0x6d, 0x00, 0x13, 0x21, 0x64, 0x00, 0x13, 0x21, 0x6b, 0x00, 0x13, 0x21, 0x66, 0x00, 0x6d, 0x6e, 0x00, 0x6d, 0xbc, 0x03, 0x6d, 0x6d, 0x00, 0x6d, 0x63, 0x00, 0x6d, 0x6b, 0x00, 0x6d, 0x63, 0x00, 0x0a, 0x0a, 0x4f, 0x00, 0x0a, 0x4f, 0x6d, 0x00, 0xb2, 0x00, 0x63, 0x00, 0x08, 0x0a, 0x4f, 0x0a, 0x0a, 0x50, 0x00, 0x0a, 0x50, 0x6d, 0x00, 0xb3, 0x00, 0x6b, 0x00, 0x6d, 0x00, 0xb3, 0x00, 0x6d, 0x00, 0x15, 0x22, 0x73, 0x00, 0x6d, 0x00, 0x15, 0x22, 0x73, 0x00, 0xb2, 0x00, 0x50, 0x61, 0x6b, 0x50, 0x61, 0x4d, 0x50, 0x61, 0x47, 0x50, 0x61, 0x72, 0x61, 0x64, 0x72, 0x61, 0x64, 0xd1, 0x73, 0x72, 0x00, 0x61, 0x00, 0x64, 0x00, 0x15, 0x22, 0x73, 0x00, 0xb2, 0x00, 0x70, 0x00, 0x73, 0x6e, 0x00, 0x73, 0xbc, 0x03, 0x73, 0x6d, 0x00, 0x73, 0x70, 0x00, 0x56, 0x6e, 0x00, 0x56, 0xbc, 0x03, 0x56, 0x6d, 0x00, 0x56, 0x6b, 0x00, 0x56, 0x4d, 0x00, 0x56, 0x70, 0x00, 0x57, 0x6e, 0x00, 0x57, 0xbc, 0x03, 0x57, 0x6d, 0x00, 0x57, 0x6b, 0x00, 0x57, 0x4d, 0x00, 0x57, 0x6b, 0x00, 0xa9, 0x03, 0x4d, 0x00, 0xa9, 0x03, 0x61, 0x2e, 0x6d, 0x2e, 0x42, 0x71, 0x63, 0x63, 0x63, 0x64, 0x43, 0xd1, 0x6b, 0x67, 0x43, 0x6f, 0x2e, 0x64, 0x42, 0x47, 0x79, 0x68, 0x61, 0x48, 0x50, 0x69, 0x6e, 0x4b, 0x4b, 0x4b, 0x4d, 0x6b, 0x74, 0x6c, 0x6d, 0x6c, 0x6e, 0x6c, 0x6f, 0x67, 0x6c, 0x78, 0x6d, 0x62, 0x6d, 0x69, 0x6c, 0x6d, 0x6f, 0x6c, 0x50, 0x48, 0x70, 0x2e, 0x6d, 0x2e, 0x50, 0x50, 0x4d, 0x50, 0x52, 0x73, 0x72, 0x53, 0x76, 0x57, 0x62, 0x56, 0xd1, 0x6d, 0x41, 0xd1, 0x6d, 0x31, 0x00, 0xe5, 0x65, 0x31, 0x00, 0x30, 0x00, 0xe5, 0x65, 0x32, 0x00, 0x30, 0x00, 0xe5, 0x65, 0x33, 0x00, 0x30, 0x00, 0xe5, 0x65, 0x67, 0x61, 0x6c, 0x4a, 0x04, 0x4c, 0x04, 0x53, 0x43, 0x46, 0x51, 0x26, 0x01, 0x53, 0x01, 0x27, 0xa7, 0x37, 0xab, 0x6b, 0x02, 0x52, 0xab, 0x48, 0x8c, 0xf4, 0x66, 0xca, 0x8e, 0xc8, 0x8c, 0xd1, 0x6e, 0x32, 0x4e, 0xe5, 0x53, 0x9c, 0x9f, 0x9c, 0x9f, 0x51, 0x59, 0xd1, 0x91, 0x87, 0x55, 0x48, 0x59, 0xf6, 0x61, 0x69, 0x76, 0x85, 0x7f, 0x3f, 0x86, 0xba, 0x87, 0xf8, 0x88, 0x8f, 0x90, 0x02, 0x6a, 0x1b, 0x6d, 0xd9, 0x70, 0xde, 0x73, 0x3d, 0x84, 0x6a, 0x91, 0xf1, 0x99, 0x82, 0x4e, 0x75, 0x53, 0x04, 0x6b, 0x1b, 0x72, 0x2d, 0x86, 0x1e, 0x9e, 0x50, 0x5d, 0xeb, 0x6f, 0xcd, 0x85, 0x64, 0x89, 0xc9, 0x62, 0xd8, 0x81, 0x1f, 0x88, 0xca, 0x5e, 0x17, 0x67, 0x6a, 0x6d, 0xfc, 0x72, 0xce, 0x90, 0x86, 0x4f, 0xb7, 0x51, 0xde, 0x52, 0xc4, 0x64, 0xd3, 0x6a, 0x10, 0x72, 0xe7, 0x76, 0x01, 0x80, 0x06, 0x86, 0x5c, 0x86, 0xef, 0x8d, 0x32, 0x97, 0x6f, 0x9b, 0xfa, 0x9d, 0x8c, 0x78, 0x7f, 0x79, 0xa0, 0x7d, 0xc9, 0x83, 0x04, 0x93, 0x7f, 0x9e, 0xd6, 0x8a, 0xdf, 0x58, 0x04, 0x5f, 0x60, 0x7c, 0x7e, 0x80, 0x62, 0x72, 0xca, 0x78, 0xc2, 0x8c, 0xf7, 0x96, 0xd8, 0x58, 0x62, 0x5c, 0x13, 0x6a, 0xda, 0x6d, 0x0f, 0x6f, 0x2f, 0x7d, 0x37, 0x7e, 0x4b, 0x96, 0xd2, 0x52, 0x8b, 0x80, 0xdc, 0x51, 0xcc, 0x51, 0x1c, 0x7a, 0xbe, 0x7d, 0xf1, 0x83, 0x75, 0x96, 0x80, 0x8b, 0xcf, 0x62, 0x02, 0x6a, 0xfe, 0x8a, 0x39, 0x4e, 0xe7, 0x5b, 0x12, 0x60, 0x87, 0x73, 0x70, 0x75, 0x17, 0x53, 0xfb, 0x78, 0xbf, 0x4f, 0xa9, 0x5f, 0x0d, 0x4e, 0xcc, 0x6c, 0x78, 0x65, 0x22, 0x7d, 0xc3, 0x53, 0x5e, 0x58, 0x01, 0x77, 0x49, 0x84, 0xaa, 0x8a, 0xba, 0x6b, 0xb0, 0x8f, 0x88, 0x6c, 0xfe, 0x62, 0xe5, 0x82, 0xa0, 0x63, 0x65, 0x75, 0xae, 0x4e, 0x69, 0x51, 0xc9, 0x51, 0x81, 0x68, 0xe7, 0x7c, 0x6f, 0x82, 0xd2, 0x8a, 0xcf, 0x91, 0xf5, 0x52, 0x42, 0x54, 0x73, 0x59, 0xec, 0x5e, 0xc5, 0x65, 0xfe, 0x6f, 0x2a, 0x79, 0xad, 0x95, 0x6a, 0x9a, 0x97, 0x9e, 0xce, 0x9e, 0x9b, 0x52, 0xc6, 0x66, 0x77, 0x6b, 0x62, 0x8f, 0x74, 0x5e, 0x90, 0x61, 0x00, 0x62, 0x9a, 0x64, 0x23, 0x6f, 0x49, 0x71, 0x89, 0x74, 0xca, 0x79, 0xf4, 0x7d, 0x6f, 0x80, 0x26, 0x8f, 0xee, 0x84, 0x23, 0x90, 0x4a, 0x93, 0x17, 0x52, 0xa3, 0x52, 0xbd, 0x54, 0xc8, 0x70, 0xc2, 0x88, 0xaa, 0x8a, 0xc9, 0x5e, 0xf5, 0x5f, 0x7b, 0x63, 0xae, 0x6b, 0x3e, 0x7c, 0x75, 0x73, 0xe4, 0x4e, 0xf9, 0x56, 0xe7, 0x5b, 0xba, 0x5d, 0x1c, 0x60, 0xb2, 0x73, 0x69, 0x74, 0x9a, 0x7f, 0x46, 0x80, 0x34, 0x92, 0xf6, 0x96, 0x48, 0x97, 0x18, 0x98, 0x8b, 0x4f, 0xae, 0x79, 0xb4, 0x91, 0xb8, 0x96, 0xe1, 0x60, 0x86, 0x4e, 0xda, 0x50, 0xee, 0x5b, 0x3f, 0x5c, 0x99, 0x65, 0x02, 0x6a, 0xce, 0x71, 0x42, 0x76, 0xfc, 0x84, 0x7c, 0x90, 0x8d, 0x9f, 0x88, 0x66, 0x2e, 0x96, 0x89, 0x52, 0x7b, 0x67, 0xf3, 0x67, 0x41, 0x6d, 0x9c, 0x6e, 0x09, 0x74, 0x59, 0x75, 0x6b, 0x78, 0x10, 0x7d, 0x5e, 0x98, 0x6d, 0x51, 0x2e, 0x62, 0x78, 0x96, 0x2b, 0x50, 0x19, 0x5d, 0xea, 0x6d, 0x2a, 0x8f, 0x8b, 0x5f, 0x44, 0x61, 0x17, 0x68, 0x87, 0x73, 0x86, 0x96, 0x29, 0x52, 0x0f, 0x54, 0x65, 0x5c, 0x13, 0x66, 0x4e, 0x67, 0xa8, 0x68, 0xe5, 0x6c, 0x06, 0x74, 0xe2, 0x75, 0x79, 0x7f, 0xcf, 0x88, 0xe1, 0x88, 0xcc, 0x91, 0xe2, 0x96, 0x3f, 0x53, 0xba, 0x6e, 0x1d, 0x54, 0xd0, 0x71, 0x98, 0x74, 0xfa, 0x85, 0xa3, 0x96, 0x57, 0x9c, 0x9f, 0x9e, 0x97, 0x67, 0xcb, 0x6d, 0xe8, 0x81, 0xcb, 0x7a, 0x20, 0x7b, 0x92, 0x7c, 0xc0, 0x72, 0x99, 0x70, 0x58, 0x8b, 0xc0, 0x4e, 0x36, 0x83, 0x3a, 0x52, 0x07, 0x52, 0xa6, 0x5e, 0xd3, 0x62, 0xd6, 0x7c, 0x85, 0x5b, 0x1e, 0x6d, 0xb4, 0x66, 0x3b, 0x8f, 0x4c, 0x88, 0x4d, 0x96, 0x8b, 0x89, 0xd3, 0x5e, 0x40, 0x51, 0xc0, 0x55, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x58, 0x00, 0x00, 0x74, 0x66, 0x00, 0x00, 0x00, 0x00, 0xde, 0x51, 0x2a, 0x73, 0xca, 0x76, 0x3c, 0x79, 0x5e, 0x79, 0x65, 0x79, 0x8f, 0x79, 0x56, 0x97, 0xbe, 0x7c, 0xbd, 0x7f, 0x00, 0x00, 0x12, 0x86, 0x00, 0x00, 0xf8, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x38, 0x90, 0xfd, 0x90, 0xef, 0x98, 0xfc, 0x98, 0x28, 0x99, 0xb4, 0x9d, 0xde, 0x90, 0xb7, 0x96, 0xae, 0x4f, 0xe7, 0x50, 0x4d, 0x51, 0xc9, 0x52, 0xe4, 0x52, 0x51, 0x53, 0x9d, 0x55, 0x06, 0x56, 0x68, 0x56, 0x40, 0x58, 0xa8, 0x58, 0x64, 0x5c, 0x6e, 0x5c, 0x94, 0x60, 0x68, 0x61, 0x8e, 0x61, 0xf2, 0x61, 0x4f, 0x65, 0xe2, 0x65, 0x91, 0x66, 0x85, 0x68, 0x77, 0x6d, 0x1a, 0x6e, 0x22, 0x6f, 0x6e, 0x71, 0x2b, 0x72, 0x22, 0x74, 0x91, 0x78, 0x3e, 0x79, 0x49, 0x79, 0x48, 0x79, 0x50, 0x79, 0x56, 0x79, 0x5d, 0x79, 0x8d, 0x79, 0x8e, 0x79, 0x40, 0x7a, 0x81, 0x7a, 0xc0, 0x7b, 0xf4, 0x7d, 0x09, 0x7e, 0x41, 0x7e, 0x72, 0x7f, 0x05, 0x80, 0xed, 0x81, 0x79, 0x82, 0x79, 0x82, 0x57, 0x84, 0x10, 0x89, 0x96, 0x89, 0x01, 0x8b, 0x39, 0x8b, 0xd3, 0x8c, 0x08, 0x8d, 0xb6, 0x8f, 0x38, 0x90, 0xe3, 0x96, 0xff, 0x97, 0x3b, 0x98, 0x75, 0x60, 0xee, 0x42, 0x18, 0x82, 0x02, 0x26, 0x4e, 0xb5, 0x51, 0x68, 0x51, 0x80, 0x4f, 0x45, 0x51, 0x80, 0x51, 0xc7, 0x52, 0xfa, 0x52, 0x9d, 0x55, 0x55, 0x55, 0x99, 0x55, 0xe2, 0x55, 0x5a, 0x58, 0xb3, 0x58, 0x44, 0x59, 0x54, 0x59, 0x62, 0x5a, 0x28, 0x5b, 0xd2, 0x5e, 0xd9, 0x5e, 0x69, 0x5f, 0xad, 0x5f, 0xd8, 0x60, 0x4e, 0x61, 0x08, 0x61, 0x8e, 0x61, 0x60, 0x61, 0xf2, 0x61, 0x34, 0x62, 0xc4, 0x63, 0x1c, 0x64, 0x52, 0x64, 0x56, 0x65, 0x74, 0x66, 0x17, 0x67, 0x1b, 0x67, 0x56, 0x67, 0x79, 0x6b, 0xba, 0x6b, 0x41, 0x6d, 0xdb, 0x6e, 0xcb, 0x6e, 0x22, 0x6f, 0x1e, 0x70, 0x6e, 0x71, 0xa7, 0x77, 0x35, 0x72, 0xaf, 0x72, 0x2a, 0x73, 0x71, 0x74, 0x06, 0x75, 0x3b, 0x75, 0x1d, 0x76, 0x1f, 0x76, 0xca, 0x76, 0xdb, 0x76, 0xf4, 0x76, 0x4a, 0x77, 0x40, 0x77, 0xcc, 0x78, 0xb1, 0x7a, 0xc0, 0x7b, 0x7b, 0x7c, 0x5b, 0x7d, 0xf4, 0x7d, 0x3e, 0x7f, 0x05, 0x80, 0x52, 0x83, 0xef, 0x83, 0x79, 0x87, 0x41, 0x89, 0x86, 0x89, 0x96, 0x89, 0xbf, 0x8a, 0xf8, 0x8a, 0xcb, 0x8a, 0x01, 0x8b, 0xfe, 0x8a, 0xed, 0x8a, 0x39, 0x8b, 0x8a, 0x8b, 0x08, 0x8d, 0x38, 0x8f, 0x72, 0x90, 0x99, 0x91, 0x76, 0x92, 0x7c, 0x96, 0xe3, 0x96, 0x56, 0x97, 0xdb, 0x97, 0xff, 0x97, 0x0b, 0x98, 0x3b, 0x98, 0x12, 0x9b, 0x9c, 0x9f, 0x4a, 0x28, 0x44, 0x28, 0xd5, 0x33, 0x9d, 0x3b, 0x18, 0x40, 0x39, 0x40, 0x49, 0x52, 0xd0, 0x5c, 0xd3, 0x7e, 0x43, 0x9f, 0x8e, 0x9f, 0x2a, 0xa0, 0x02, 0x66, 0x66, 0x66, 0x69, 0x66, 0x6c, 0x66, 0x66, 0x69, 0x66, 0x66, 0x6c, 0x7f, 0x01, 0x74, 0x73, 0x00, 0x74, 0x65, 0x05, 0x0f, 0x11, 0x0f, 0x00, 0x0f, 0x06, 0x19, 0x11, 0x0f, 0x08, 0xd9, 0x05, 0xb4, 0x05, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x05, 0xb7, 0x05, 0xd0, 0x05, 0x12, 0x00, 0x03, 0x04, 0x0b, 0x0c, 0x0d, 0x18, 0x1a, 0xe9, 0x05, 0xc1, 0x05, 0xe9, 0x05, 0xc2, 0x05, 0x49, 0xfb, 0xc1, 0x05, 0x49, 0xfb, 0xc2, 0x05, 0xd0, 0x05, 0xb7, 0x05, 0xd0, 0x05, 0xb8, 0x05, 0xd0, 0x05, 0xbc, 0x05, 0xd8, 0x05, 0xbc, 0x05, 0xde, 0x05, 0xbc, 0x05, 0xe0, 0x05, 0xbc, 0x05, 0xe3, 0x05, 0xbc, 0x05, 0xb9, 0x05, 0x2d, 0x03, 0x2e, 0x03, 0x2f, 0x03, 0x30, 0x03, 0x31, 0x03, 0x1c, 0x00, 0x18, 0x06, 0x22, 0x06, 0x2b, 0x06, 0xd0, 0x05, 0xdc, 0x05, 0x71, 0x06, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0d, 0x0d, 0x0d, 0x0d, 0x0f, 0x0f, 0x0f, 0x0f, 0x09, 0x09, 0x09, 0x09, 0x0e, 0x0e, 0x0e, 0x0e, 0x08, 0x08, 0x08, 0x08, 0x33, 0x33, 0x33, 0x33, 0x35, 0x35, 0x35, 0x35, 0x13, 0x13, 0x13, 0x13, 0x12, 0x12, 0x12, 0x12, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x1c, 0x1c, 0x1b, 0x1b, 0x1d, 0x1d, 0x17, 0x17, 0x27, 0x27, 0x20, 0x20, 0x38, 0x38, 0x38, 0x38, 0x3e, 0x3e, 0x3e, 0x3e, 0x42, 0x42, 0x42, 0x42, 0x40, 0x40, 0x40, 0x40, 0x49, 0x49, 0x4a, 0x4a, 0x4a, 0x4a, 0x4f, 0x4f, 0x50, 0x50, 0x50, 0x50, 0x4d, 0x4d, 0x4d, 0x4d, 0x61, 0x61, 0x62, 0x62, 0x49, 0x06, 0x64, 0x64, 0x64, 0x64, 0x7e, 0x7e, 0x7d, 0x7d, 0x7f, 0x7f, 0x2e, 0x82, 0x82, 0x7c, 0x7c, 0x80, 0x80, 0x87, 0x87, 0x87, 0x87, 0x00, 0x00, 0x26, 0x06, 0x00, 0x01, 0x00, 0x01, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0x22, 0x00, 0x22, 0x00, 0xa1, 0x00, 0xa1, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa2, 0x00, 0xa2, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0x23, 0x00, 0x23, 0x00, 0x23, 0xcc, 0x06, 0x00, 0x00, 0x00, 0x00, 0x26, 0x06, 0x00, 0x06, 0x00, 0x07, 0x00, 0x1f, 0x00, 0x23, 0x00, 0x24, 0x02, 0x06, 0x02, 0x07, 0x02, 0x08, 0x02, 0x1f, 0x02, 0x23, 0x02, 0x24, 0x04, 0x06, 0x04, 0x07, 0x04, 0x08, 0x04, 0x1f, 0x04, 0x23, 0x04, 0x24, 0x05, 0x06, 0x05, 0x1f, 0x05, 0x23, 0x05, 0x24, 0x06, 0x07, 0x06, 0x1f, 0x07, 0x06, 0x07, 0x1f, 0x08, 0x06, 0x08, 0x07, 0x08, 0x1f, 0x0d, 0x06, 0x0d, 0x07, 0x0d, 0x08, 0x0d, 0x1f, 0x0f, 0x07, 0x0f, 0x1f, 0x10, 0x06, 0x10, 0x07, 0x10, 0x08, 0x10, 0x1f, 0x11, 0x07, 0x11, 0x1f, 0x12, 0x1f, 0x13, 0x06, 0x13, 0x1f, 0x14, 0x06, 0x14, 0x1f, 0x1b, 0x06, 0x1b, 0x07, 0x1b, 0x08, 0x1b, 0x1f, 0x1b, 0x23, 0x1b, 0x24, 0x1c, 0x07, 0x1c, 0x1f, 0x1c, 0x23, 0x1c, 0x24, 0x1d, 0x01, 0x1d, 0x06, 0x1d, 0x07, 0x1d, 0x08, 0x1d, 0x1e, 0x1d, 0x1f, 0x1d, 0x23, 0x1d, 0x24, 0x1e, 0x06, 0x1e, 0x07, 0x1e, 0x08, 0x1e, 0x1f, 0x1e, 0x23, 0x1e, 0x24, 0x1f, 0x06, 0x1f, 0x07, 0x1f, 0x08, 0x1f, 0x1f, 0x1f, 0x23, 0x1f, 0x24, 0x20, 0x06, 0x20, 0x07, 0x20, 0x08, 0x20, 0x1f, 0x20, 0x23, 0x20, 0x24, 0x21, 0x06, 0x21, 0x1f, 0x21, 0x23, 0x21, 0x24, 0x24, 0x06, 0x24, 0x07, 0x24, 0x08, 0x24, 0x1f, 0x24, 0x23, 0x24, 0x24, 0x0a, 0x4a, 0x0b, 0x4a, 0x23, 0x4a, 0x20, 0x00, 0x4c, 0x06, 0x51, 0x06, 0x51, 0x06, 0xff, 0x00, 0x1f, 0x26, 0x06, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x1f, 0x00, 0x20, 0x00, 0x23, 0x00, 0x24, 0x02, 0x0b, 0x02, 0x0c, 0x02, 0x1f, 0x02, 0x20, 0x02, 0x23, 0x02, 0x24, 0x04, 0x0b, 0x04, 0x0c, 0x04, 0x1f, 0x26, 0x06, 0x04, 0x20, 0x04, 0x23, 0x04, 0x24, 0x05, 0x0b, 0x05, 0x0c, 0x05, 0x1f, 0x05, 0x20, 0x05, 0x23, 0x05, 0x24, 0x1b, 0x23, 0x1b, 0x24, 0x1c, 0x23, 0x1c, 0x24, 0x1d, 0x01, 0x1d, 0x1e, 0x1d, 0x1f, 0x1d, 0x23, 0x1d, 0x24, 0x1e, 0x1f, 0x1e, 0x23, 0x1e, 0x24, 0x1f, 0x01, 0x1f, 0x1f, 0x20, 0x0b, 0x20, 0x0c, 0x20, 0x1f, 0x20, 0x20, 0x20, 0x23, 0x20, 0x24, 0x23, 0x4a, 0x24, 0x0b, 0x24, 0x0c, 0x24, 0x1f, 0x24, 0x20, 0x24, 0x23, 0x24, 0x24, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x1f, 0x00, 0x21, 0x02, 0x06, 0x02, 0x07, 0x02, 0x08, 0x02, 0x1f, 0x02, 0x21, 0x04, 0x06, 0x04, 0x07, 0x04, 0x08, 0x04, 0x1f, 0x04, 0x21, 0x05, 0x1f, 0x06, 0x07, 0x06, 0x1f, 0x07, 0x06, 0x07, 0x1f, 0x08, 0x06, 0x08, 0x1f, 0x0d, 0x06, 0x0d, 0x07, 0x0d, 0x08, 0x0d, 0x1f, 0x0f, 0x07, 0x0f, 0x08, 0x0f, 0x1f, 0x10, 0x06, 0x10, 0x07, 0x10, 0x08, 0x10, 0x1f, 0x11, 0x07, 0x12, 0x1f, 0x13, 0x06, 0x13, 0x1f, 0x14, 0x06, 0x14, 0x1f, 0x1b, 0x06, 0x1b, 0x07, 0x1b, 0x08, 0x1b, 0x1f, 0x1c, 0x07, 0x1c, 0x1f, 0x1d, 0x06, 0x1d, 0x07, 0x1d, 0x08, 0x1d, 0x1e, 0x1d, 0x1f, 0x1e, 0x06, 0x1e, 0x07, 0x1e, 0x08, 0x1e, 0x1f, 0x1e, 0x21, 0x1f, 0x06, 0x1f, 0x07, 0x1f, 0x08, 0x1f, 0x1f, 0x20, 0x06, 0x20, 0x07, 0x20, 0x08, 0x20, 0x1f, 0x20, 0x21, 0x21, 0x06, 0x21, 0x1f, 0x21, 0x4a, 0x24, 0x06, 0x24, 0x07, 0x24, 0x08, 0x24, 0x1f, 0x24, 0x21, 0x00, 0x1f, 0x00, 0x21, 0x02, 0x1f, 0x02, 0x21, 0x04, 0x1f, 0x04, 0x21, 0x05, 0x1f, 0x05, 0x21, 0x0d, 0x1f, 0x0d, 0x21, 0x0e, 0x1f, 0x0e, 0x21, 0x1d, 0x1e, 0x1d, 0x1f, 0x1e, 0x1f, 0x20, 0x1f, 0x20, 0x21, 0x24, 0x1f, 0x24, 0x21, 0x40, 0x06, 0x4e, 0x06, 0x51, 0x06, 0x27, 0x06, 0x10, 0x22, 0x10, 0x23, 0x12, 0x22, 0x12, 0x23, 0x13, 0x22, 0x13, 0x23, 0x0c, 0x22, 0x0c, 0x23, 0x0d, 0x22, 0x0d, 0x23, 0x06, 0x22, 0x06, 0x23, 0x05, 0x22, 0x05, 0x23, 0x07, 0x22, 0x07, 0x23, 0x0e, 0x22, 0x0e, 0x23, 0x0f, 0x22, 0x0f, 0x23, 0x0d, 0x05, 0x0d, 0x06, 0x0d, 0x07, 0x0d, 0x1e, 0x0d, 0x0a, 0x0c, 0x0a, 0x0e, 0x0a, 0x0f, 0x0a, 0x10, 0x22, 0x10, 0x23, 0x12, 0x22, 0x12, 0x23, 0x13, 0x22, 0x13, 0x23, 0x0c, 0x22, 0x0c, 0x23, 0x0d, 0x22, 0x0d, 0x23, 0x06, 0x22, 0x06, 0x23, 0x05, 0x22, 0x05, 0x23, 0x07, 0x22, 0x07, 0x23, 0x0e, 0x22, 0x0e, 0x23, 0x0f, 0x22, 0x0f, 0x23, 0x0d, 0x05, 0x0d, 0x06, 0x0d, 0x07, 0x0d, 0x1e, 0x0d, 0x0a, 0x0c, 0x0a, 0x0e, 0x0a, 0x0f, 0x0a, 0x0d, 0x05, 0x0d, 0x06, 0x0d, 0x07, 0x0d, 0x1e, 0x0c, 0x20, 0x0d, 0x20, 0x10, 0x1e, 0x0c, 0x05, 0x0c, 0x06, 0x0c, 0x07, 0x0d, 0x05, 0x0d, 0x06, 0x0d, 0x07, 0x10, 0x1e, 0x11, 0x1e, 0x00, 0x24, 0x00, 0x24, 0x2a, 0x06, 0x00, 0x02, 0x1b, 0x00, 0x03, 0x02, 0x00, 0x03, 0x02, 0x00, 0x03, 0x1b, 0x00, 0x04, 0x1b, 0x00, 0x1b, 0x02, 0x00, 0x1b, 0x03, 0x00, 0x1b, 0x04, 0x02, 0x1b, 0x03, 0x02, 0x1b, 0x03, 0x03, 0x1b, 0x20, 0x03, 0x1b, 0x1f, 0x09, 0x03, 0x02, 0x09, 0x02, 0x03, 0x09, 0x02, 0x1f, 0x09, 0x1b, 0x03, 0x09, 0x1b, 0x03, 0x09, 0x1b, 0x02, 0x09, 0x1b, 0x1b, 0x09, 0x1b, 0x1b, 0x0b, 0x03, 0x03, 0x0b, 0x03, 0x03, 0x0b, 0x1b, 0x1b, 0x0a, 0x03, 0x1b, 0x0a, 0x03, 0x1b, 0x0a, 0x02, 0x20, 0x0a, 0x1b, 0x04, 0x0a, 0x1b, 0x04, 0x0a, 0x1b, 0x1b, 0x0a, 0x1b, 0x1b, 0x0c, 0x03, 0x1f, 0x0c, 0x04, 0x1b, 0x0c, 0x04, 0x1b, 0x0d, 0x1b, 0x03, 0x0d, 0x1b, 0x03, 0x0d, 0x1b, 0x1b, 0x0d, 0x1b, 0x20, 0x0f, 0x02, 0x1b, 0x0f, 0x1b, 0x1b, 0x0f, 0x1b, 0x1b, 0x0f, 0x1b, 0x1f, 0x10, 0x1b, 0x1b, 0x10, 0x1b, 0x20, 0x10, 0x1b, 0x1f, 0x17, 0x04, 0x1b, 0x17, 0x04, 0x1b, 0x18, 0x1b, 0x03, 0x18, 0x1b, 0x1b, 0x1a, 0x03, 0x1b, 0x1a, 0x03, 0x20, 0x1a, 0x03, 0x1f, 0x1a, 0x02, 0x02, 0x1a, 0x02, 0x02, 0x1a, 0x04, 0x1b, 0x1a, 0x04, 0x1b, 0x1a, 0x1b, 0x03, 0x1a, 0x1b, 0x03, 0x1b, 0x03, 0x02, 0x1b, 0x03, 0x1b, 0x1b, 0x03, 0x20, 0x1b, 0x02, 0x03, 0x1b, 0x02, 0x1b, 0x1b, 0x04, 0x02, 0x1b, 0x04, 0x1b, 0x28, 0x06, 0x1d, 0x04, 0x06, 0x1f, 0x1d, 0x04, 0x1f, 0x1d, 0x1d, 0x1e, 0x05, 0x1d, 0x1e, 0x05, 0x21, 0x1e, 0x04, 0x1d, 0x1e, 0x04, 0x1d, 0x1e, 0x04, 0x21, 0x1e, 0x1d, 0x22, 0x1e, 0x1d, 0x21, 0x22, 0x1d, 0x1d, 0x22, 0x1d, 0x1d, 0x00, 0x06, 0x22, 0x02, 0x04, 0x22, 0x02, 0x04, 0x21, 0x02, 0x06, 0x22, 0x02, 0x06, 0x21, 0x02, 0x1d, 0x22, 0x02, 0x1d, 0x21, 0x04, 0x1d, 0x22, 0x04, 0x05, 0x21, 0x04, 0x1d, 0x21, 0x0b, 0x06, 0x21, 0x0d, 0x05, 0x22, 0x0c, 0x05, 0x22, 0x0e, 0x05, 0x22, 0x1c, 0x04, 0x22, 0x1c, 0x1d, 0x22, 0x22, 0x05, 0x22, 0x22, 0x04, 0x22, 0x22, 0x1d, 0x22, 0x1d, 0x1d, 0x22, 0x1a, 0x1d, 0x22, 0x1e, 0x05, 0x22, 0x1a, 0x1d, 0x05, 0x1c, 0x05, 0x1d, 0x11, 0x1d, 0x22, 0x1b, 0x1d, 0x22, 0x1e, 0x04, 0x05, 0x1d, 0x06, 0x22, 0x1c, 0x04, 0x1d, 0x1b, 0x1d, 0x1d, 0x1c, 0x04, 0x1d, 0x1e, 0x04, 0x05, 0x04, 0x05, 0x22, 0x05, 0x04, 0x22, 0x1d, 0x04, 0x22, 0x19, 0x1d, 0x22, 0x00, 0x05, 0x22, 0x1b, 0x1d, 0x1d, 0x11, 0x04, 0x1d, 0x0d, 0x1d, 0x1d, 0x0b, 0x06, 0x22, 0x1e, 0x04, 0x22, 0x35, 0x06, 0x00, 0x0f, 0x9d, 0x0d, 0x0f, 0x9d, 0x27, 0x06, 0x00, 0x1d, 0x1d, 0x20, 0x00, 0x1c, 0x01, 0x0a, 0x1e, 0x06, 0x1e, 0x08, 0x0e, 0x1d, 0x12, 0x1e, 0x0a, 0x0c, 0x21, 0x1d, 0x12, 0x1d, 0x23, 0x20, 0x21, 0x0c, 0x1d, 0x1e, 0x35, 0x06, 0x00, 0x0f, 0x14, 0x27, 0x06, 0x0e, 0x1d, 0x22, 0xff, 0x00, 0x1d, 0x1d, 0x20, 0xff, 0x12, 0x1d, 0x23, 0x20, 0xff, 0x21, 0x0c, 0x1d, 0x1e, 0x27, 0x06, 0x05, 0x1d, 0xff, 0x05, 0x1d, 0x00, 0x1d, 0x20, 0x27, 0x06, 0x0a, 0xa5, 0x00, 0x1d, 0x2c, 0x00, 0x01, 0x30, 0x02, 0x30, 0x3a, 0x00, 0x3b, 0x00, 0x21, 0x00, 0x3f, 0x00, 0x16, 0x30, 0x17, 0x30, 0x26, 0x20, 0x13, 0x20, 0x12, 0x01, 0x00, 0x5f, 0x5f, 0x28, 0x29, 0x7b, 0x7d, 0x08, 0x30, 0x0c, 0x0d, 0x08, 0x09, 0x02, 0x03, 0x00, 0x01, 0x04, 0x05, 0x06, 0x07, 0x5b, 0x00, 0x5d, 0x00, 0x3e, 0x20, 0x3e, 0x20, 0x3e, 0x20, 0x3e, 0x20, 0x5f, 0x00, 0x5f, 0x00, 0x5f, 0x00, 0x2c, 0x00, 0x01, 0x30, 0x2e, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x3a, 0x00, 0x3f, 0x00, 0x21, 0x00, 0x14, 0x20, 0x28, 0x00, 0x29, 0x00, 0x7b, 0x00, 0x7d, 0x00, 0x14, 0x30, 0x15, 0x30, 0x23, 0x26, 0x2a, 0x2b, 0x2d, 0x3c, 0x3e, 0x3d, 0x00, 0x5c, 0x24, 0x25, 0x40, 0x40, 0x06, 0xff, 0x0b, 0x00, 0x0b, 0xff, 0x0c, 0x20, 0x00, 0x4d, 0x06, 0x40, 0x06, 0xff, 0x0e, 0x00, 0x0e, 0xff, 0x0f, 0x00, 0x0f, 0xff, 0x10, 0x00, 0x10, 0xff, 0x11, 0x00, 0x11, 0xff, 0x12, 0x00, 0x12, 0x21, 0x06, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25, 0x25, 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29, 0x22, 0x06, 0x22, 0x00, 0x22, 0x00, 0x22, 0x01, 0x22, 0x01, 0x22, 0x03, 0x22, 0x03, 0x22, 0x05, 0x22, 0x05, 0x21, 0x00, 0x85, 0x29, 0x01, 0x30, 0x01, 0x0b, 0x0c, 0x00, 0xfa, 0xf1, 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xe2, 0xe4, 0xe6, 0xc2, 0xfb, 0xa1, 0xa3, 0xa5, 0xa7, 0xa9, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, 0xc0, 0xc3, 0xc5, 0xc7, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xd1, 0xd4, 0xd7, 0xda, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe3, 0xe5, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xee, 0xf2, 0x98, 0x99, 0x31, 0x31, 0x4f, 0x31, 0x55, 0x31, 0x5b, 0x31, 0x61, 0x31, 0xa2, 0x00, 0xa3, 0x00, 0xac, 0x00, 0xaf, 0x00, 0xa6, 0x00, 0xa5, 0x00, 0xa9, 0x20, 0x00, 0x00, 0x02, 0x25, 0x90, 0x21, 0x91, 0x21, 0x92, 0x21, 0x93, 0x21, 0xa0, 0x25, 0xcb, 0x25, 0xd2, 0x05, 0x07, 0x03, 0x01, 0xda, 0x05, 0x07, 0x03, 0x01, 0xd0, 0x02, 0xd1, 0x02, 0xe6, 0x00, 0x99, 0x02, 0x53, 0x02, 0x00, 0x00, 0xa3, 0x02, 0x66, 0xab, 0xa5, 0x02, 0xa4, 0x02, 0x56, 0x02, 0x57, 0x02, 0x91, 0x1d, 0x58, 0x02, 0x5e, 0x02, 0xa9, 0x02, 0x64, 0x02, 0x62, 0x02, 0x60, 0x02, 0x9b, 0x02, 0x27, 0x01, 0x9c, 0x02, 0x67, 0x02, 0x84, 0x02, 0xaa, 0x02, 0xab, 0x02, 0x6c, 0x02, 0x04, 0xdf, 0x8e, 0xa7, 0x6e, 0x02, 0x05, 0xdf, 0x8e, 0x02, 0x06, 0xdf, 0xf8, 0x00, 0x76, 0x02, 0x77, 0x02, 0x71, 0x00, 0x7a, 0x02, 0x08, 0xdf, 0x7d, 0x02, 0x7e, 0x02, 0x80, 0x02, 0xa8, 0x02, 0xa6, 0x02, 0x67, 0xab, 0xa7, 0x02, 0x88, 0x02, 0x71, 0x2c, 0x00, 0x00, 0x8f, 0x02, 0xa1, 0x02, 0xa2, 0x02, 0x98, 0x02, 0xc0, 0x01, 0xc1, 0x01, 0xc2, 0x01, 0x0a, 0xdf, 0x1e, 0xdf, 0x41, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x14, 0x99, 0x10, 0xba, 0x10, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x10, 0xba, 0x10, 0x05, 0x05, 0xa5, 0x10, 0xba, 0x10, 0x05, 0x31, 0x11, 0x27, 0x11, 0x32, 0x11, 0x27, 0x11, 0x55, 0x47, 0x13, 0x3e, 0x13, 0x47, 0x13, 0x57, 0x13, 0x55, 0x82, 0x13, 0xc9, 0x13, 0x00, 0x00, 0x00, 0x00, 0x84, 0x13, 0xbb, 0x13, 0x05, 0x05, 0x8b, 0x13, 0xc2, 0x13, 0x05, 0x90, 0x13, 0xc9, 0x13, 0x05, 0xc2, 0x13, 0xc2, 0x13, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x13, 0xb8, 0x13, 0xc2, 0x13, 0xc9, 0x13, 0x05, 0x55, 0xb9, 0x14, 0xba, 0x14, 0xb9, 0x14, 0xb0, 0x14, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x14, 0xbd, 0x14, 0x55, 0x50, 0xb8, 0x15, 0xaf, 0x15, 0xb9, 0x15, 0xaf, 0x15, 0x55, 0x35, 0x19, 0x30, 0x19, 0x05, 0x1e, 0x61, 0x1e, 0x61, 0x1e, 0x61, 0x29, 0x61, 0x1e, 0x61, 0x1f, 0x61, 0x29, 0x61, 0x1f, 0x61, 0x1e, 0x61, 0x20, 0x61, 0x21, 0x61, 0x1f, 0x61, 0x22, 0x61, 0x1f, 0x61, 0x21, 0x61, 0x20, 0x61, 0x55, 0x55, 0x55, 0x55, 0x67, 0x6d, 0x67, 0x6d, 0x63, 0x6d, 0x67, 0x6d, 0x69, 0x6d, 0x67, 0x6d, 0x55, 0x05, 0x41, 0x00, 0x30, 0x00, 0x57, 0xd1, 0x65, 0xd1, 0x58, 0xd1, 0x65, 0xd1, 0x5f, 0xd1, 0x6e, 0xd1, 0x5f, 0xd1, 0x6f, 0xd1, 0x5f, 0xd1, 0x70, 0xd1, 0x5f, 0xd1, 0x71, 0xd1, 0x5f, 0xd1, 0x72, 0xd1, 0x55, 0x55, 0x55, 0x05, 0xb9, 0xd1, 0x65, 0xd1, 0xba, 0xd1, 0x65, 0xd1, 0xbb, 0xd1, 0x6e, 0xd1, 0xbc, 0xd1, 0x6e, 0xd1, 0xbb, 0xd1, 0x6f, 0xd1, 0xbc, 0xd1, 0x6f, 0xd1, 0x55, 0x55, 0x55, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x69, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, 0x43, 0x44, 0x00, 0x00, 0x47, 0x00, 0x00, 0x4a, 0x4b, 0x00, 0x00, 0x4e, 0x4f, 0x50, 0x51, 0x00, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x00, 0x66, 0x68, 0x00, 0x70, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x42, 0x00, 0x44, 0x45, 0x46, 0x47, 0x4a, 0x00, 0x53, 0x00, 0x61, 0x00, 0x41, 0x42, 0x00, 0x44, 0x45, 0x46, 0x47, 0x00, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x00, 0x4f, 0x53, 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x31, 0x01, 0x37, 0x02, 0x91, 0x03, 0xa3, 0x03, 0xb1, 0x03, 0xd1, 0x03, 0x24, 0x00, 0x1f, 0x04, 0x20, 0x05, 0x91, 0x03, 0xa3, 0x03, 0xb1, 0x03, 0xd1, 0x03, 0x24, 0x00, 0x1f, 0x04, 0x20, 0x05, 0x91, 0x03, 0xa3, 0x03, 0xb1, 0x03, 0xd1, 0x03, 0x24, 0x00, 0x1f, 0x04, 0x20, 0x05, 0x91, 0x03, 0xa3, 0x03, 0xb1, 0x03, 0xd1, 0x03, 0x24, 0x00, 0x1f, 0x04, 0x20, 0x05, 0x91, 0x03, 0xa3, 0x03, 0xb1, 0x03, 0xd1, 0x03, 0x24, 0x00, 0x1f, 0x04, 0x20, 0x05, 0x0b, 0x0c, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x04, 0x3a, 0x04, 0x3e, 0x04, 0x4b, 0x04, 0x4d, 0x04, 0x4e, 0x04, 0x89, 0xa6, 0x30, 0x04, 0xa9, 0x26, 0x28, 0xb9, 0x7f, 0x9f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0e, 0x0f, 0x11, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x1a, 0x1b, 0x61, 0x26, 0x25, 0x2f, 0x7b, 0x51, 0xa6, 0xb1, 0x04, 0x27, 0x06, 0x00, 0x01, 0x05, 0x08, 0x2a, 0x06, 0x1e, 0x08, 0x03, 0x0d, 0x20, 0x19, 0x1a, 0x1b, 0x1c, 0x09, 0x0f, 0x17, 0x0b, 0x18, 0x07, 0x0a, 0x00, 0x01, 0x04, 0x06, 0x0c, 0x0e, 0x10, 0x44, 0x90, 0x77, 0x45, 0x28, 0x06, 0x2c, 0x06, 0x00, 0x00, 0x47, 0x06, 0x33, 0x06, 0x17, 0x10, 0x11, 0x12, 0x13, 0x00, 0x06, 0x0e, 0x02, 0x0f, 0x34, 0x06, 0x2a, 0x06, 0x2b, 0x06, 0x2e, 0x06, 0x00, 0x00, 0x36, 0x06, 0x00, 0x00, 0x3a, 0x06, 0x2d, 0x06, 0x00, 0x00, 0x4a, 0x06, 0x00, 0x00, 0x44, 0x06, 0x00, 0x00, 0x46, 0x06, 0x33, 0x06, 0x39, 0x06, 0x00, 0x00, 0x35, 0x06, 0x42, 0x06, 0x00, 0x00, 0x34, 0x06, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x06, 0x00, 0x00, 0x36, 0x06, 0x00, 0x00, 0x3a, 0x06, 0x00, 0x00, 0xba, 0x06, 0x00, 0x00, 0x6f, 0x06, 0x00, 0x00, 0x28, 0x06, 0x2c, 0x06, 0x00, 0x00, 0x47, 0x06, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x06, 0x37, 0x06, 0x4a, 0x06, 0x43, 0x06, 0x00, 0x00, 0x45, 0x06, 0x46, 0x06, 0x33, 0x06, 0x39, 0x06, 0x41, 0x06, 0x35, 0x06, 0x42, 0x06, 0x00, 0x00, 0x34, 0x06, 0x2a, 0x06, 0x2b, 0x06, 0x2e, 0x06, 0x00, 0x00, 0x36, 0x06, 0x38, 0x06, 0x3a, 0x06, 0x6e, 0x06, 0x00, 0x00, 0xa1, 0x06, 0x27, 0x06, 0x00, 0x01, 0x05, 0x08, 0x20, 0x21, 0x0b, 0x06, 0x10, 0x23, 0x2a, 0x06, 0x1a, 0x1b, 0x1c, 0x09, 0x0f, 0x17, 0x0b, 0x18, 0x07, 0x0a, 0x00, 0x01, 0x04, 0x06, 0x0c, 0x0e, 0x10, 0x28, 0x06, 0x2c, 0x06, 0x2f, 0x06, 0x00, 0x00, 0x48, 0x06, 0x32, 0x06, 0x2d, 0x06, 0x37, 0x06, 0x4a, 0x06, 0x2a, 0x06, 0x1a, 0x1b, 0x1c, 0x09, 0x0f, 0x17, 0x0b, 0x18, 0x07, 0x0a, 0x00, 0x01, 0x04, 0x06, 0x0c, 0x0e, 0x10, 0x30, 0x2e, 0x30, 0x00, 0x2c, 0x00, 0x28, 0x00, 0x41, 0x00, 0x29, 0x00, 0x14, 0x30, 0x53, 0x00, 0x15, 0x30, 0x43, 0x52, 0x43, 0x44, 0x57, 0x5a, 0x41, 0x00, 0x48, 0x56, 0x4d, 0x56, 0x53, 0x44, 0x53, 0x53, 0x50, 0x50, 0x56, 0x57, 0x43, 0x4d, 0x43, 0x4d, 0x44, 0x4d, 0x52, 0x44, 0x4a, 0x4b, 0x30, 0x30, 0x00, 0x68, 0x68, 0x4b, 0x62, 0x57, 0x5b, 0xcc, 0x53, 0xc7, 0x30, 0x8c, 0x4e, 0x1a, 0x59, 0xe3, 0x89, 0x29, 0x59, 0xa4, 0x4e, 0x20, 0x66, 0x21, 0x71, 0x99, 0x65, 0x4d, 0x52, 0x8c, 0x5f, 0x8d, 0x51, 0xb0, 0x65, 0x1d, 0x52, 0x42, 0x7d, 0x1f, 0x75, 0xa9, 0x8c, 0xf0, 0x58, 0x39, 0x54, 0x14, 0x6f, 0x95, 0x62, 0x55, 0x63, 0x00, 0x4e, 0x09, 0x4e, 0x4a, 0x90, 0xe6, 0x5d, 0x2d, 0x4e, 0xf3, 0x53, 0x07, 0x63, 0x70, 0x8d, 0x53, 0x62, 0x81, 0x79, 0x7a, 0x7a, 0x08, 0x54, 0x80, 0x6e, 0x09, 0x67, 0x08, 0x67, 0x33, 0x75, 0x72, 0x52, 0xb6, 0x55, 0x4d, 0x91, 0x14, 0x30, 0x15, 0x30, 0x2c, 0x67, 0x09, 0x4e, 0x8c, 0x4e, 0x89, 0x5b, 0xb9, 0x70, 0x53, 0x62, 0xd7, 0x76, 0xdd, 0x52, 0x57, 0x65, 0x97, 0x5f, 0xef, 0x53, 0x30, 0x00, 0x38, 0x4e, 0x05, 0x00, 0x09, 0x22, 0x01, 0x60, 0x4f, 0xae, 0x4f, 0xbb, 0x4f, 0x02, 0x50, 0x7a, 0x50, 0x99, 0x50, 0xe7, 0x50, 0xcf, 0x50, 0x9e, 0x34, 0x3a, 0x06, 0x4d, 0x51, 0x54, 0x51, 0x64, 0x51, 0x77, 0x51, 0x1c, 0x05, 0xb9, 0x34, 0x67, 0x51, 0x8d, 0x51, 0x4b, 0x05, 0x97, 0x51, 0xa4, 0x51, 0xcc, 0x4e, 0xac, 0x51, 0xb5, 0x51, 0xdf, 0x91, 0xf5, 0x51, 0x03, 0x52, 0xdf, 0x34, 0x3b, 0x52, 0x46, 0x52, 0x72, 0x52, 0x77, 0x52, 0x15, 0x35, 0x02, 0x00, 0x20, 0x80, 0x80, 0x00, 0x08, 0x00, 0x00, 0xc7, 0x52, 0x00, 0x02, 0x1d, 0x33, 0x3e, 0x3f, 0x50, 0x82, 0x8a, 0x93, 0xac, 0xb6, 0xb8, 0xb8, 0xb8, 0x2c, 0x0a, 0x70, 0x70, 0xca, 0x53, 0xdf, 0x53, 0x63, 0x0b, 0xeb, 0x53, 0xf1, 0x53, 0x06, 0x54, 0x9e, 0x54, 0x38, 0x54, 0x48, 0x54, 0x68, 0x54, 0xa2, 0x54, 0xf6, 0x54, 0x10, 0x55, 0x53, 0x55, 0x63, 0x55, 0x84, 0x55, 0x84, 0x55, 0x99, 0x55, 0xab, 0x55, 0xb3, 0x55, 0xc2, 0x55, 0x16, 0x57, 0x06, 0x56, 0x17, 0x57, 0x51, 0x56, 0x74, 0x56, 0x07, 0x52, 0xee, 0x58, 0xce, 0x57, 0xf4, 0x57, 0x0d, 0x58, 0x8b, 0x57, 0x32, 0x58, 0x31, 0x58, 0xac, 0x58, 0xe4, 0x14, 0xf2, 0x58, 0xf7, 0x58, 0x06, 0x59, 0x1a, 0x59, 0x22, 0x59, 0x62, 0x59, 0xa8, 0x16, 0xea, 0x16, 0xec, 0x59, 0x1b, 0x5a, 0x27, 0x5a, 0xd8, 0x59, 0x66, 0x5a, 0xee, 0x36, 0xfc, 0x36, 0x08, 0x5b, 0x3e, 0x5b, 0x3e, 0x5b, 0xc8, 0x19, 0xc3, 0x5b, 0xd8, 0x5b, 0xe7, 0x5b, 0xf3, 0x5b, 0x18, 0x1b, 0xff, 0x5b, 0x06, 0x5c, 0x53, 0x5f, 0x22, 0x5c, 0x81, 0x37, 0x60, 0x5c, 0x6e, 0x5c, 0xc0, 0x5c, 0x8d, 0x5c, 0xe4, 0x1d, 0x43, 0x5d, 0xe6, 0x1d, 0x6e, 0x5d, 0x6b, 0x5d, 0x7c, 0x5d, 0xe1, 0x5d, 0xe2, 0x5d, 0x2f, 0x38, 0xfd, 0x5d, 0x28, 0x5e, 0x3d, 0x5e, 0x69, 0x5e, 0x62, 0x38, 0x83, 0x21, 0x7c, 0x38, 0xb0, 0x5e, 0xb3, 0x5e, 0xb6, 0x5e, 0xca, 0x5e, 0x92, 0xa3, 0xfe, 0x5e, 0x31, 0x23, 0x31, 0x23, 0x01, 0x82, 0x22, 0x5f, 0x22, 0x5f, 0xc7, 0x38, 0xb8, 0x32, 0xda, 0x61, 0x62, 0x5f, 0x6b, 0x5f, 0xe3, 0x38, 0x9a, 0x5f, 0xcd, 0x5f, 0xd7, 0x5f, 0xf9, 0x5f, 0x81, 0x60, 0x3a, 0x39, 0x1c, 0x39, 0x94, 0x60, 0xd4, 0x26, 0xc7, 0x60, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00, 0x02, 0x08, 0x00, 0x80, 0x08, 0x00, 0x00, 0x08, 0x80, 0x28, 0x80, 0x02, 0x00, 0x00, 0x02, 0x48, 0x61, 0x00, 0x04, 0x06, 0x04, 0x32, 0x46, 0x6a, 0x5c, 0x67, 0x96, 0xaa, 0xae, 0xc8, 0xd3, 0x5d, 0x62, 0x00, 0x54, 0x77, 0xf3, 0x0c, 0x2b, 0x3d, 0x63, 0xfc, 0x62, 0x68, 0x63, 0x83, 0x63, 0xe4, 0x63, 0xf1, 0x2b, 0x22, 0x64, 0xc5, 0x63, 0xa9, 0x63, 0x2e, 0x3a, 0x69, 0x64, 0x7e, 0x64, 0x9d, 0x64, 0x77, 0x64, 0x6c, 0x3a, 0x4f, 0x65, 0x6c, 0x65, 0x0a, 0x30, 0xe3, 0x65, 0xf8, 0x66, 0x49, 0x66, 0x19, 0x3b, 0x91, 0x66, 0x08, 0x3b, 0xe4, 0x3a, 0x92, 0x51, 0x95, 0x51, 0x00, 0x67, 0x9c, 0x66, 0xad, 0x80, 0xd9, 0x43, 0x17, 0x67, 0x1b, 0x67, 0x21, 0x67, 0x5e, 0x67, 0x53, 0x67, 0xc3, 0x33, 0x49, 0x3b, 0xfa, 0x67, 0x85, 0x67, 0x52, 0x68, 0x85, 0x68, 0x6d, 0x34, 0x8e, 0x68, 0x1f, 0x68, 0x14, 0x69, 0x9d, 0x3b, 0x42, 0x69, 0xa3, 0x69, 0xea, 0x69, 0xa8, 0x6a, 0xa3, 0x36, 0xdb, 0x6a, 0x18, 0x3c, 0x21, 0x6b, 0xa7, 0x38, 0x54, 0x6b, 0x4e, 0x3c, 0x72, 0x6b, 0x9f, 0x6b, 0xba, 0x6b, 0xbb, 0x6b, 0x8d, 0x3a, 0x0b, 0x1d, 0xfa, 0x3a, 0x4e, 0x6c, 0xbc, 0x3c, 0xbf, 0x6c, 0xcd, 0x6c, 0x67, 0x6c, 0x16, 0x6d, 0x3e, 0x6d, 0x77, 0x6d, 0x41, 0x6d, 0x69, 0x6d, 0x78, 0x6d, 0x85, 0x6d, 0x1e, 0x3d, 0x34, 0x6d, 0x2f, 0x6e, 0x6e, 0x6e, 0x33, 0x3d, 0xcb, 0x6e, 0xc7, 0x6e, 0xd1, 0x3e, 0xf9, 0x6d, 0x6e, 0x6f, 0x5e, 0x3f, 0x8e, 0x3f, 0xc6, 0x6f, 0x39, 0x70, 0x1e, 0x70, 0x1b, 0x70, 0x96, 0x3d, 0x4a, 0x70, 0x7d, 0x70, 0x77, 0x70, 0xad, 0x70, 0x25, 0x05, 0x45, 0x71, 0x63, 0x42, 0x9c, 0x71, 0xab, 0x43, 0x28, 0x72, 0x35, 0x72, 0x50, 0x72, 0x08, 0x46, 0x80, 0x72, 0x95, 0x72, 0x35, 0x47, 0x02, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x02, 0x02, 0x80, 0x8a, 0x00, 0x00, 0x20, 0x00, 0x08, 0x0a, 0x00, 0x80, 0x88, 0x80, 0x20, 0x14, 0x48, 0x7a, 0x73, 0x8b, 0x73, 0xac, 0x3e, 0xa5, 0x73, 0xb8, 0x3e, 0xb8, 0x3e, 0x47, 0x74, 0x5c, 0x74, 0x71, 0x74, 0x85, 0x74, 0xca, 0x74, 0x1b, 0x3f, 0x24, 0x75, 0x36, 0x4c, 0x3e, 0x75, 0x92, 0x4c, 0x70, 0x75, 0x9f, 0x21, 0x10, 0x76, 0xa1, 0x4f, 0xb8, 0x4f, 0x44, 0x50, 0xfc, 0x3f, 0x08, 0x40, 0xf4, 0x76, 0xf3, 0x50, 0xf2, 0x50, 0x19, 0x51, 0x33, 0x51, 0x1e, 0x77, 0x1f, 0x77, 0x1f, 0x77, 0x4a, 0x77, 0x39, 0x40, 0x8b, 0x77, 0x46, 0x40, 0x96, 0x40, 0x1d, 0x54, 0x4e, 0x78, 0x8c, 0x78, 0xcc, 0x78, 0xe3, 0x40, 0x26, 0x56, 0x56, 0x79, 0x9a, 0x56, 0xc5, 0x56, 0x8f, 0x79, 0xeb, 0x79, 0x2f, 0x41, 0x40, 0x7a, 0x4a, 0x7a, 0x4f, 0x7a, 0x7c, 0x59, 0xa7, 0x5a, 0xa7, 0x5a, 0xee, 0x7a, 0x02, 0x42, 0xab, 0x5b, 0xc6, 0x7b, 0xc9, 0x7b, 0x27, 0x42, 0x80, 0x5c, 0xd2, 0x7c, 0xa0, 0x42, 0xe8, 0x7c, 0xe3, 0x7c, 0x00, 0x7d, 0x86, 0x5f, 0x63, 0x7d, 0x01, 0x43, 0xc7, 0x7d, 0x02, 0x7e, 0x45, 0x7e, 0x34, 0x43, 0x28, 0x62, 0x47, 0x62, 0x59, 0x43, 0xd9, 0x62, 0x7a, 0x7f, 0x3e, 0x63, 0x95, 0x7f, 0xfa, 0x7f, 0x05, 0x80, 0xda, 0x64, 0x23, 0x65, 0x60, 0x80, 0xa8, 0x65, 0x70, 0x80, 0x5f, 0x33, 0xd5, 0x43, 0xb2, 0x80, 0x03, 0x81, 0x0b, 0x44, 0x3e, 0x81, 0xb5, 0x5a, 0xa7, 0x67, 0xb5, 0x67, 0x93, 0x33, 0x9c, 0x33, 0x01, 0x82, 0x04, 0x82, 0x9e, 0x8f, 0x6b, 0x44, 0x91, 0x82, 0x8b, 0x82, 0x9d, 0x82, 0xb3, 0x52, 0xb1, 0x82, 0xb3, 0x82, 0xbd, 0x82, 0xe6, 0x82, 0x3c, 0x6b, 0xe5, 0x82, 0x1d, 0x83, 0x63, 0x83, 0xad, 0x83, 0x23, 0x83, 0xbd, 0x83, 0xe7, 0x83, 0x57, 0x84, 0x53, 0x83, 0xca, 0x83, 0xcc, 0x83, 0xdc, 0x83, 0x36, 0x6c, 0x6b, 0x6d, 0x02, 0x00, 0x00, 0x20, 0x22, 0x2a, 0xa0, 0x0a, 0x00, 0x20, 0x80, 0x28, 0x00, 0xa8, 0x20, 0x20, 0x00, 0x02, 0x80, 0x22, 0x02, 0x8a, 0x08, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x28, 0xd5, 0x6c, 0x2b, 0x45, 0xf1, 0x84, 0xf3, 0x84, 0x16, 0x85, 0xca, 0x73, 0x64, 0x85, 0x2c, 0x6f, 0x5d, 0x45, 0x61, 0x45, 0xb1, 0x6f, 0xd2, 0x70, 0x6b, 0x45, 0x50, 0x86, 0x5c, 0x86, 0x67, 0x86, 0x69, 0x86, 0xa9, 0x86, 0x88, 0x86, 0x0e, 0x87, 0xe2, 0x86, 0x79, 0x87, 0x28, 0x87, 0x6b, 0x87, 0x86, 0x87, 0xd7, 0x45, 0xe1, 0x87, 0x01, 0x88, 0xf9, 0x45, 0x60, 0x88, 0x63, 0x88, 0x67, 0x76, 0xd7, 0x88, 0xde, 0x88, 0x35, 0x46, 0xfa, 0x88, 0xbb, 0x34, 0xae, 0x78, 0x66, 0x79, 0xbe, 0x46, 0xc7, 0x46, 0xa0, 0x8a, 0xed, 0x8a, 0x8a, 0x8b, 0x55, 0x8c, 0xa8, 0x7c, 0xab, 0x8c, 0xc1, 0x8c, 0x1b, 0x8d, 0x77, 0x8d, 0x2f, 0x7f, 0x04, 0x08, 0xcb, 0x8d, 0xbc, 0x8d, 0xf0, 0x8d, 0xde, 0x08, 0xd4, 0x8e, 0x38, 0x8f, 0xd2, 0x85, 0xed, 0x85, 0x94, 0x90, 0xf1, 0x90, 0x11, 0x91, 0x2e, 0x87, 0x1b, 0x91, 0x38, 0x92, 0xd7, 0x92, 0xd8, 0x92, 0x7c, 0x92, 0xf9, 0x93, 0x15, 0x94, 0xfa, 0x8b, 0x8b, 0x95, 0x95, 0x49, 0xb7, 0x95, 0x77, 0x8d, 0xe6, 0x49, 0xc3, 0x96, 0xb2, 0x5d, 0x23, 0x97, 0x45, 0x91, 0x1a, 0x92, 0x6e, 0x4a, 0x76, 0x4a, 0xe0, 0x97, 0x0a, 0x94, 0xb2, 0x4a, 0x96, 0x94, 0x0b, 0x98, 0x0b, 0x98, 0x29, 0x98, 0xb6, 0x95, 0xe2, 0x98, 0x33, 0x4b, 0x29, 0x99, 0xa7, 0x99, 0xc2, 0x99, 0xfe, 0x99, 0xce, 0x4b, 0x30, 0x9b, 0x12, 0x9b, 0x40, 0x9c, 0xfd, 0x9c, 0xce, 0x4c, 0xed, 0x4c, 0x67, 0x9d, 0xce, 0xa0, 0xf8, 0x4c, 0x05, 0xa1, 0x0e, 0xa2, 0x91, 0xa2, 0xbb, 0x9e, 0x56, 0x4d, 0xf9, 0x9e, 0xfe, 0x9e, 0x05, 0x9f, 0x0f, 0x9f, 0x16, 0x9f, 0x3b, 0x9f, 0x00, 0xa6, 0x02, 0x88, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x28, 0x00, 0x08, 0xa0, 0x80, 0xa0, 0x80, 0x00, 0x80, 0x80, 0x00, 0x0a, 0x88, 0x80, 0x00, 0x80, 0x00, 0x20, 0x2a, 0x00, 0x80, }; static const uint16_t unicode_comp_table[965] = { 0x4a01, 0x49c0, 0x4a02, 0x0280, 0x0281, 0x0282, 0x0283, 0x02c0, 0x02c2, 0x0a00, 0x0284, 0x2442, 0x0285, 0x07c0, 0x0980, 0x0982, 0x2440, 0x2280, 0x02c4, 0x2282, 0x2284, 0x2286, 0x02c6, 0x02c8, 0x02ca, 0x02cc, 0x0287, 0x228a, 0x02ce, 0x228c, 0x2290, 0x2292, 0x228e, 0x0288, 0x0289, 0x028a, 0x2482, 0x0300, 0x0302, 0x0304, 0x028b, 0x2480, 0x0308, 0x0984, 0x0986, 0x2458, 0x0a02, 0x0306, 0x2298, 0x229a, 0x229e, 0x0900, 0x030a, 0x22a0, 0x030c, 0x030e, 0x0840, 0x0310, 0x0312, 0x22a2, 0x22a6, 0x09c0, 0x22a4, 0x22a8, 0x22aa, 0x028c, 0x028d, 0x028e, 0x0340, 0x0342, 0x0344, 0x0380, 0x028f, 0x248e, 0x07c2, 0x0988, 0x098a, 0x2490, 0x0346, 0x22ac, 0x0400, 0x22b0, 0x0842, 0x22b2, 0x0402, 0x22b4, 0x0440, 0x0444, 0x22b6, 0x0442, 0x22c2, 0x22c0, 0x22c4, 0x22c6, 0x22c8, 0x0940, 0x04c0, 0x0291, 0x22ca, 0x04c4, 0x22cc, 0x04c2, 0x22d0, 0x22ce, 0x0292, 0x0293, 0x0294, 0x0295, 0x0540, 0x0542, 0x0a08, 0x0296, 0x2494, 0x0544, 0x07c4, 0x098c, 0x098e, 0x06c0, 0x2492, 0x0844, 0x2308, 0x230a, 0x0580, 0x230c, 0x0584, 0x0990, 0x0992, 0x230e, 0x0582, 0x2312, 0x0586, 0x0588, 0x2314, 0x058c, 0x2316, 0x0998, 0x058a, 0x231e, 0x0590, 0x2320, 0x099a, 0x058e, 0x2324, 0x2322, 0x0299, 0x029a, 0x029b, 0x05c0, 0x05c2, 0x05c4, 0x029c, 0x24ac, 0x05c6, 0x05c8, 0x07c6, 0x0994, 0x0996, 0x0700, 0x24aa, 0x2326, 0x05ca, 0x232a, 0x2328, 0x2340, 0x2342, 0x2344, 0x2346, 0x05cc, 0x234a, 0x2348, 0x234c, 0x234e, 0x2350, 0x24b8, 0x029d, 0x05ce, 0x24be, 0x0a0c, 0x2352, 0x0600, 0x24bc, 0x24ba, 0x0640, 0x2354, 0x0642, 0x0644, 0x2356, 0x2358, 0x02a0, 0x02a1, 0x02a2, 0x02a3, 0x02c1, 0x02c3, 0x0a01, 0x02a4, 0x2443, 0x02a5, 0x07c1, 0x0981, 0x0983, 0x2441, 0x2281, 0x02c5, 0x2283, 0x2285, 0x2287, 0x02c7, 0x02c9, 0x02cb, 0x02cd, 0x02a7, 0x228b, 0x02cf, 0x228d, 0x2291, 0x2293, 0x228f, 0x02a8, 0x02a9, 0x02aa, 0x2483, 0x0301, 0x0303, 0x0305, 0x02ab, 0x2481, 0x0309, 0x0985, 0x0987, 0x2459, 0x0a03, 0x0307, 0x2299, 0x229b, 0x229f, 0x0901, 0x030b, 0x22a1, 0x030d, 0x030f, 0x0841, 0x0311, 0x0313, 0x22a3, 0x22a7, 0x09c1, 0x22a5, 0x22a9, 0x22ab, 0x2380, 0x02ac, 0x02ad, 0x02ae, 0x0341, 0x0343, 0x0345, 0x02af, 0x248f, 0x07c3, 0x0989, 0x098b, 0x2491, 0x0347, 0x22ad, 0x0401, 0x0884, 0x22b1, 0x0843, 0x22b3, 0x0403, 0x22b5, 0x0441, 0x0445, 0x22b7, 0x0443, 0x22c3, 0x22c1, 0x22c5, 0x22c7, 0x22c9, 0x0941, 0x04c1, 0x02b1, 0x22cb, 0x04c5, 0x22cd, 0x04c3, 0x22d1, 0x22cf, 0x02b2, 0x02b3, 0x02b4, 0x02b5, 0x0541, 0x0543, 0x0a09, 0x02b6, 0x2495, 0x0545, 0x07c5, 0x098d, 0x098f, 0x06c1, 0x2493, 0x0845, 0x2309, 0x230b, 0x0581, 0x230d, 0x0585, 0x0991, 0x0993, 0x230f, 0x0583, 0x2313, 0x0587, 0x0589, 0x2315, 0x058d, 0x2317, 0x0999, 0x058b, 0x231f, 0x2381, 0x0591, 0x2321, 0x099b, 0x058f, 0x2325, 0x2323, 0x02b9, 0x02ba, 0x02bb, 0x05c1, 0x05c3, 0x05c5, 0x02bc, 0x24ad, 0x05c7, 0x05c9, 0x07c7, 0x0995, 0x0997, 0x0701, 0x24ab, 0x2327, 0x05cb, 0x232b, 0x2329, 0x2341, 0x2343, 0x2345, 0x2347, 0x05cd, 0x234b, 0x2349, 0x2382, 0x234d, 0x234f, 0x2351, 0x24b9, 0x02bd, 0x05cf, 0x24bf, 0x0a0d, 0x2353, 0x02bf, 0x24bd, 0x2383, 0x24bb, 0x0641, 0x2355, 0x0643, 0x0645, 0x2357, 0x2359, 0x3101, 0x0c80, 0x2e00, 0x2446, 0x2444, 0x244a, 0x2448, 0x0800, 0x0942, 0x0944, 0x0804, 0x2288, 0x2486, 0x2484, 0x248a, 0x2488, 0x22ae, 0x2498, 0x2496, 0x249c, 0x249a, 0x2300, 0x0a06, 0x2302, 0x0a04, 0x0946, 0x07ce, 0x07ca, 0x07c8, 0x07cc, 0x2447, 0x2445, 0x244b, 0x2449, 0x0801, 0x0943, 0x0945, 0x0805, 0x2289, 0x2487, 0x2485, 0x248b, 0x2489, 0x22af, 0x2499, 0x2497, 0x249d, 0x249b, 0x2301, 0x0a07, 0x2303, 0x0a05, 0x0947, 0x07cf, 0x07cb, 0x07c9, 0x07cd, 0x2450, 0x244e, 0x2454, 0x2452, 0x2451, 0x244f, 0x2455, 0x2453, 0x2294, 0x2296, 0x2295, 0x2297, 0x2304, 0x2306, 0x2305, 0x2307, 0x2318, 0x2319, 0x231a, 0x231b, 0x232c, 0x232d, 0x232e, 0x232f, 0x2400, 0x24a2, 0x24a0, 0x24a6, 0x24a4, 0x24a8, 0x24a3, 0x24a1, 0x24a7, 0x24a5, 0x24a9, 0x24b0, 0x24ae, 0x24b4, 0x24b2, 0x24b6, 0x24b1, 0x24af, 0x24b5, 0x24b3, 0x24b7, 0x0882, 0x0880, 0x0881, 0x0802, 0x0803, 0x229c, 0x229d, 0x0a0a, 0x0a0b, 0x0883, 0x0b40, 0x2c8a, 0x0c81, 0x2c89, 0x2c88, 0x2540, 0x2541, 0x2d00, 0x2e07, 0x0d00, 0x2640, 0x2641, 0x2e80, 0x0d01, 0x26c8, 0x26c9, 0x2f00, 0x2f84, 0x0d02, 0x2f83, 0x2f82, 0x0d40, 0x26d8, 0x26d9, 0x3186, 0x0d04, 0x2740, 0x2741, 0x3100, 0x3086, 0x0d06, 0x3085, 0x3084, 0x0d41, 0x2840, 0x3200, 0x0d07, 0x284f, 0x2850, 0x3280, 0x2c84, 0x2e03, 0x2857, 0x0d42, 0x2c81, 0x2c80, 0x24c0, 0x24c1, 0x2c86, 0x2c83, 0x28c0, 0x0d43, 0x25c0, 0x25c1, 0x2940, 0x0d44, 0x26c0, 0x26c1, 0x2e05, 0x2e02, 0x29c0, 0x0d45, 0x2f05, 0x2f04, 0x0d80, 0x26d0, 0x26d1, 0x2f80, 0x2a40, 0x0d82, 0x26e0, 0x26e1, 0x3080, 0x3081, 0x2ac0, 0x0d83, 0x3004, 0x3003, 0x0d81, 0x27c0, 0x27c1, 0x3082, 0x2b40, 0x0d84, 0x2847, 0x2848, 0x3184, 0x3181, 0x2f06, 0x0d08, 0x2f81, 0x3005, 0x0d46, 0x3083, 0x3182, 0x0e00, 0x0e01, 0x0f40, 0x1180, 0x1182, 0x0f03, 0x0f00, 0x11c0, 0x0f01, 0x1140, 0x1202, 0x1204, 0x0f81, 0x1240, 0x0fc0, 0x1242, 0x0f80, 0x1244, 0x1284, 0x0f82, 0x1286, 0x1288, 0x128a, 0x12c0, 0x1282, 0x1181, 0x1183, 0x1043, 0x1040, 0x11c1, 0x1041, 0x1141, 0x1203, 0x1205, 0x10c1, 0x1241, 0x1000, 0x1243, 0x10c0, 0x1245, 0x1285, 0x10c2, 0x1287, 0x1289, 0x128b, 0x12c1, 0x1283, 0x1080, 0x1100, 0x1101, 0x1200, 0x1201, 0x1280, 0x1281, 0x1340, 0x1341, 0x1343, 0x1342, 0x1344, 0x13c2, 0x1400, 0x13c0, 0x1440, 0x1480, 0x14c0, 0x1540, 0x1541, 0x1740, 0x1700, 0x1741, 0x17c0, 0x1800, 0x1802, 0x1801, 0x1840, 0x1880, 0x1900, 0x18c0, 0x18c1, 0x1901, 0x1940, 0x1942, 0x1941, 0x1980, 0x19c0, 0x19c2, 0x19c1, 0x1c80, 0x1cc0, 0x1dc0, 0x1f80, 0x2000, 0x2002, 0x2004, 0x2006, 0x2008, 0x2040, 0x2080, 0x2082, 0x20c0, 0x20c1, 0x2100, 0x22b8, 0x22b9, 0x2310, 0x2311, 0x231c, 0x231d, 0x244c, 0x2456, 0x244d, 0x2457, 0x248c, 0x248d, 0x249e, 0x249f, 0x2500, 0x2502, 0x2504, 0x2bc0, 0x2501, 0x2503, 0x2505, 0x2bc1, 0x2bc2, 0x2bc3, 0x2bc4, 0x2bc5, 0x2bc6, 0x2bc7, 0x2580, 0x2582, 0x2584, 0x2bc8, 0x2581, 0x2583, 0x2585, 0x2bc9, 0x2bca, 0x2bcb, 0x2bcc, 0x2bcd, 0x2bce, 0x2bcf, 0x2600, 0x2602, 0x2601, 0x2603, 0x2680, 0x2682, 0x2681, 0x2683, 0x26c2, 0x26c4, 0x26c6, 0x2c00, 0x26c3, 0x26c5, 0x26c7, 0x2c01, 0x2c02, 0x2c03, 0x2c04, 0x2c05, 0x2c06, 0x2c07, 0x26ca, 0x26cc, 0x26ce, 0x2c08, 0x26cb, 0x26cd, 0x26cf, 0x2c09, 0x2c0a, 0x2c0b, 0x2c0c, 0x2c0d, 0x2c0e, 0x2c0f, 0x26d2, 0x26d4, 0x26d6, 0x26d3, 0x26d5, 0x26d7, 0x26da, 0x26dc, 0x26de, 0x26db, 0x26dd, 0x26df, 0x2700, 0x2702, 0x2701, 0x2703, 0x2780, 0x2782, 0x2781, 0x2783, 0x2800, 0x2802, 0x2804, 0x2801, 0x2803, 0x2805, 0x2842, 0x2844, 0x2846, 0x2849, 0x284b, 0x284d, 0x2c40, 0x284a, 0x284c, 0x284e, 0x2c41, 0x2c42, 0x2c43, 0x2c44, 0x2c45, 0x2c46, 0x2c47, 0x2851, 0x2853, 0x2855, 0x2c48, 0x2852, 0x2854, 0x2856, 0x2c49, 0x2c4a, 0x2c4b, 0x2c4c, 0x2c4d, 0x2c4e, 0x2c4f, 0x2c82, 0x2e01, 0x3180, 0x2c87, 0x2f01, 0x2f02, 0x2f03, 0x2e06, 0x3185, 0x3000, 0x3001, 0x3002, 0x4640, 0x4641, 0x4680, 0x46c0, 0x46c2, 0x46c1, 0x4700, 0x4740, 0x4780, 0x47c0, 0x47c2, 0x4900, 0x4940, 0x4980, 0x4982, 0x4a00, 0x49c2, 0x4a03, 0x4a04, 0x4a40, 0x4a41, 0x4a80, 0x4a81, 0x4ac0, 0x4ac1, 0x4bc0, 0x4bc1, 0x4b00, 0x4b01, 0x4b40, 0x4b41, 0x4bc2, 0x4bc3, 0x4b80, 0x4b81, 0x4b82, 0x4b83, 0x4c00, 0x4c01, 0x4c02, 0x4c03, 0x5600, 0x5440, 0x5442, 0x5444, 0x5446, 0x5448, 0x544a, 0x544c, 0x544e, 0x5450, 0x5452, 0x5454, 0x5456, 0x5480, 0x5482, 0x5484, 0x54c0, 0x54c1, 0x5500, 0x5501, 0x5540, 0x5541, 0x5580, 0x5581, 0x55c0, 0x55c1, 0x5680, 0x58c0, 0x5700, 0x5702, 0x5704, 0x5706, 0x5708, 0x570a, 0x570c, 0x570e, 0x5710, 0x5712, 0x5714, 0x5716, 0x5740, 0x5742, 0x5744, 0x5780, 0x5781, 0x57c0, 0x57c1, 0x5800, 0x5801, 0x5840, 0x5841, 0x5880, 0x5881, 0x5900, 0x5901, 0x5902, 0x5903, 0x5940, 0x8ec0, 0x8f00, 0x8fc0, 0x8fc2, 0x9000, 0x9040, 0x9041, 0x9080, 0x9081, 0x90c0, 0x90c2, 0x9100, 0x9140, 0x9182, 0x9180, 0x9183, 0x91c1, 0x91c0, 0x91c3, 0x9200, 0x9201, 0x9240, 0x9280, 0x9282, 0x9284, 0x9281, 0x9285, 0x9287, 0x9286, 0x9283, 0x92c1, 0x92c0, 0x92c2, }; typedef enum { UNICODE_GC_Cn, UNICODE_GC_Lu, UNICODE_GC_Ll, UNICODE_GC_Lt, UNICODE_GC_Lm, UNICODE_GC_Lo, UNICODE_GC_Mn, UNICODE_GC_Mc, UNICODE_GC_Me, UNICODE_GC_Nd, UNICODE_GC_Nl, UNICODE_GC_No, UNICODE_GC_Sm, UNICODE_GC_Sc, UNICODE_GC_Sk, UNICODE_GC_So, UNICODE_GC_Pc, UNICODE_GC_Pd, UNICODE_GC_Ps, UNICODE_GC_Pe, UNICODE_GC_Pi, UNICODE_GC_Pf, UNICODE_GC_Po, UNICODE_GC_Zs, UNICODE_GC_Zl, UNICODE_GC_Zp, UNICODE_GC_Cc, UNICODE_GC_Cf, UNICODE_GC_Cs, UNICODE_GC_Co, UNICODE_GC_LC, UNICODE_GC_L, UNICODE_GC_M, UNICODE_GC_N, UNICODE_GC_S, UNICODE_GC_P, UNICODE_GC_Z, UNICODE_GC_C, UNICODE_GC_COUNT, } UnicodeGCEnum; static const char unicode_gc_name_table[] = "Cn,Unassigned" "\0" "Lu,Uppercase_Letter" "\0" "Ll,Lowercase_Letter" "\0" "Lt,Titlecase_Letter" "\0" "Lm,Modifier_Letter" "\0" "Lo,Other_Letter" "\0" "Mn,Nonspacing_Mark" "\0" "Mc,Spacing_Mark" "\0" "Me,Enclosing_Mark" "\0" "Nd,Decimal_Number,digit" "\0" "Nl,Letter_Number" "\0" "No,Other_Number" "\0" "Sm,Math_Symbol" "\0" "Sc,Currency_Symbol" "\0" "Sk,Modifier_Symbol" "\0" "So,Other_Symbol" "\0" "Pc,Connector_Punctuation" "\0" "Pd,Dash_Punctuation" "\0" "Ps,Open_Punctuation" "\0" "Pe,Close_Punctuation" "\0" "Pi,Initial_Punctuation" "\0" "Pf,Final_Punctuation" "\0" "Po,Other_Punctuation" "\0" "Zs,Space_Separator" "\0" "Zl,Line_Separator" "\0" "Zp,Paragraph_Separator" "\0" "Cc,Control,cntrl" "\0" "Cf,Format" "\0" "Cs,Surrogate" "\0" "Co,Private_Use" "\0" "LC,Cased_Letter" "\0" "L,Letter" "\0" "M,Mark,Combining_Mark" "\0" "N,Number" "\0" "S,Symbol" "\0" "P,Punctuation,punct" "\0" "Z,Separator" "\0" "C,Other" "\0" ; static const uint8_t unicode_gc_table[4122] = { 0xfa, 0x18, 0x17, 0x56, 0x0d, 0x56, 0x12, 0x13, 0x16, 0x0c, 0x16, 0x11, 0x36, 0xe9, 0x02, 0x36, 0x4c, 0x36, 0xe1, 0x12, 0x12, 0x16, 0x13, 0x0e, 0x10, 0x0e, 0xe2, 0x12, 0x12, 0x0c, 0x13, 0x0c, 0xfa, 0x19, 0x17, 0x16, 0x6d, 0x0f, 0x16, 0x0e, 0x0f, 0x05, 0x14, 0x0c, 0x1b, 0x0f, 0x0e, 0x0f, 0x0c, 0x2b, 0x0e, 0x02, 0x36, 0x0e, 0x0b, 0x05, 0x15, 0x4b, 0x16, 0xe1, 0x0f, 0x0c, 0xc1, 0xe2, 0x10, 0x0c, 0xe2, 0x00, 0xff, 0x30, 0x02, 0xff, 0x08, 0x02, 0xff, 0x27, 0xbf, 0x22, 0x21, 0x02, 0x5f, 0x5f, 0x21, 0x22, 0x61, 0x02, 0x21, 0x02, 0x41, 0x42, 0x21, 0x02, 0x21, 0x02, 0x9f, 0x7f, 0x02, 0x5f, 0x5f, 0x21, 0x02, 0x5f, 0x3f, 0x02, 0x05, 0x3f, 0x22, 0x65, 0x01, 0x03, 0x02, 0x01, 0x03, 0x02, 0x01, 0x03, 0x02, 0xff, 0x08, 0x02, 0xff, 0x0a, 0x02, 0x01, 0x03, 0x02, 0x5f, 0x21, 0x02, 0xff, 0x32, 0xa2, 0x21, 0x02, 0x21, 0x22, 0x5f, 0x41, 0x02, 0xff, 0x00, 0xe2, 0x3c, 0x25, 0xe2, 0x12, 0xe4, 0x0a, 0x6e, 0xe4, 0x04, 0xee, 0x06, 0x84, 0xce, 0x04, 0x0e, 0x04, 0xee, 0x09, 0xe6, 0x68, 0x7f, 0x04, 0x0e, 0x3f, 0x20, 0x04, 0x42, 0x16, 0x01, 0x60, 0x2e, 0x01, 0x16, 0x41, 0x00, 0x01, 0x00, 0x21, 0x02, 0xe1, 0x09, 0x00, 0xe1, 0x01, 0xe2, 0x1b, 0x3f, 0x02, 0x41, 0x42, 0xff, 0x10, 0x62, 0x3f, 0x0c, 0x5f, 0x3f, 0x02, 0xe1, 0x2b, 0xe2, 0x28, 0xff, 0x1a, 0x0f, 0x86, 0x28, 0xff, 0x2f, 0xff, 0x06, 0x02, 0xff, 0x58, 0x00, 0xe1, 0x1e, 0x20, 0x04, 0xb6, 0xe2, 0x21, 0x16, 0x11, 0x20, 0x2f, 0x0d, 0x00, 0xe6, 0x25, 0x11, 0x06, 0x16, 0x26, 0x16, 0x26, 0x16, 0x06, 0xe0, 0x00, 0xe5, 0x13, 0x60, 0x65, 0x36, 0xe0, 0x03, 0xbb, 0x4c, 0x36, 0x0d, 0x36, 0x2f, 0xe6, 0x03, 0x16, 0x1b, 0x56, 0xe5, 0x18, 0x04, 0xe5, 0x02, 0xe6, 0x0d, 0xe9, 0x02, 0x76, 0x25, 0x06, 0xe5, 0x5b, 0x16, 0x05, 0xc6, 0x1b, 0x0f, 0xa6, 0x24, 0x26, 0x0f, 0x66, 0x25, 0xe9, 0x02, 0x45, 0x2f, 0x05, 0xf6, 0x06, 0x00, 0x1b, 0x05, 0x06, 0xe5, 0x16, 0xe6, 0x13, 0x20, 0xe5, 0x51, 0xe6, 0x03, 0x05, 0xe0, 0x06, 0xe9, 0x02, 0xe5, 0x19, 0xe6, 0x01, 0x24, 0x0f, 0x56, 0x04, 0x20, 0x06, 0x2d, 0xe5, 0x0e, 0x66, 0x04, 0xe6, 0x01, 0x04, 0x46, 0x04, 0x86, 0x20, 0xf6, 0x07, 0x00, 0xe5, 0x11, 0x46, 0x20, 0x16, 0x00, 0xe5, 0x03, 0x80, 0xe5, 0x10, 0x0e, 0xc5, 0x3b, 0x80, 0xe6, 0x01, 0xe5, 0x21, 0x04, 0xe6, 0x10, 0x1b, 0xe6, 0x18, 0x07, 0xe5, 0x2e, 0x06, 0x07, 0x06, 0x05, 0x47, 0xe6, 0x00, 0x67, 0x06, 0x27, 0x05, 0xc6, 0xe5, 0x02, 0x26, 0x36, 0xe9, 0x02, 0x16, 0x04, 0xe5, 0x07, 0x06, 0x27, 0x00, 0xe5, 0x00, 0x20, 0x25, 0x20, 0xe5, 0x0e, 0x00, 0xc5, 0x00, 0x05, 0x40, 0x65, 0x20, 0x06, 0x05, 0x47, 0x66, 0x20, 0x27, 0x20, 0x27, 0x06, 0x05, 0xe0, 0x00, 0x07, 0x60, 0x25, 0x00, 0x45, 0x26, 0x20, 0xe9, 0x02, 0x25, 0x2d, 0xab, 0x0f, 0x0d, 0x05, 0x16, 0x06, 0x20, 0x26, 0x07, 0x00, 0xa5, 0x60, 0x25, 0x20, 0xe5, 0x0e, 0x00, 0xc5, 0x00, 0x25, 0x00, 0x25, 0x00, 0x25, 0x20, 0x06, 0x00, 0x47, 0x26, 0x60, 0x26, 0x20, 0x46, 0x40, 0x06, 0xc0, 0x65, 0x00, 0x05, 0xc0, 0xe9, 0x02, 0x26, 0x45, 0x06, 0x16, 0xe0, 0x02, 0x26, 0x07, 0x00, 0xe5, 0x01, 0x00, 0x45, 0x00, 0xe5, 0x0e, 0x00, 0xc5, 0x00, 0x25, 0x00, 0x85, 0x20, 0x06, 0x05, 0x47, 0x86, 0x00, 0x26, 0x07, 0x00, 0x27, 0x06, 0x20, 0x05, 0xe0, 0x07, 0x25, 0x26, 0x20, 0xe9, 0x02, 0x16, 0x0d, 0xc0, 0x05, 0xa6, 0x00, 0x06, 0x27, 0x00, 0xe5, 0x00, 0x20, 0x25, 0x20, 0xe5, 0x0e, 0x00, 0xc5, 0x00, 0x25, 0x00, 0x85, 0x20, 0x06, 0x05, 0x07, 0x06, 0x07, 0x66, 0x20, 0x27, 0x20, 0x27, 0x06, 0xc0, 0x26, 0x07, 0x60, 0x25, 0x00, 0x45, 0x26, 0x20, 0xe9, 0x02, 0x0f, 0x05, 0xab, 0xe0, 0x02, 0x06, 0x05, 0x00, 0xa5, 0x40, 0x45, 0x00, 0x65, 0x40, 0x25, 0x00, 0x05, 0x00, 0x25, 0x40, 0x25, 0x40, 0x45, 0x40, 0xe5, 0x04, 0x60, 0x27, 0x06, 0x27, 0x40, 0x47, 0x00, 0x47, 0x06, 0x20, 0x05, 0xa0, 0x07, 0xe0, 0x06, 0xe9, 0x02, 0x4b, 0xaf, 0x0d, 0x0f, 0x80, 0x06, 0x47, 0x06, 0xe5, 0x00, 0x00, 0x45, 0x00, 0xe5, 0x0f, 0x00, 0xe5, 0x08, 0x20, 0x06, 0x05, 0x46, 0x67, 0x00, 0x46, 0x00, 0x66, 0xc0, 0x26, 0x00, 0x45, 0x00, 0x25, 0x20, 0x25, 0x26, 0x20, 0xe9, 0x02, 0xc0, 0x16, 0xcb, 0x0f, 0x05, 0x06, 0x27, 0x16, 0xe5, 0x00, 0x00, 0x45, 0x00, 0xe5, 0x0f, 0x00, 0xe5, 0x02, 0x00, 0x85, 0x20, 0x06, 0x05, 0x07, 0x06, 0x87, 0x00, 0x06, 0x27, 0x00, 0x27, 0x26, 0xc0, 0x27, 0x80, 0x45, 0x00, 0x25, 0x26, 0x20, 0xe9, 0x02, 0x00, 0x25, 0x07, 0xe0, 0x04, 0x26, 0x27, 0xe5, 0x01, 0x00, 0x45, 0x00, 0xe5, 0x21, 0x26, 0x05, 0x47, 0x66, 0x00, 0x47, 0x00, 0x47, 0x06, 0x05, 0x0f, 0x60, 0x45, 0x07, 0xcb, 0x45, 0x26, 0x20, 0xe9, 0x02, 0xeb, 0x01, 0x0f, 0xa5, 0x00, 0x06, 0x27, 0x00, 0xe5, 0x0a, 0x40, 0xe5, 0x10, 0x00, 0xe5, 0x01, 0x00, 0x05, 0x20, 0xc5, 0x40, 0x06, 0x60, 0x47, 0x46, 0x00, 0x06, 0x00, 0xe7, 0x00, 0xa0, 0xe9, 0x02, 0x20, 0x27, 0x16, 0xe0, 0x04, 0xe5, 0x28, 0x06, 0x25, 0xc6, 0x60, 0x0d, 0xa5, 0x04, 0xe6, 0x00, 0x16, 0xe9, 0x02, 0x36, 0xe0, 0x1d, 0x25, 0x00, 0x05, 0x00, 0x85, 0x00, 0xe5, 0x10, 0x00, 0x05, 0x00, 0xe5, 0x02, 0x06, 0x25, 0xe6, 0x01, 0x05, 0x20, 0x85, 0x00, 0x04, 0x00, 0xc6, 0x00, 0xe9, 0x02, 0x20, 0x65, 0xe0, 0x18, 0x05, 0x4f, 0xf6, 0x07, 0x0f, 0x16, 0x4f, 0x26, 0xaf, 0xe9, 0x02, 0xeb, 0x02, 0x0f, 0x06, 0x0f, 0x06, 0x0f, 0x06, 0x12, 0x13, 0x12, 0x13, 0x27, 0xe5, 0x00, 0x00, 0xe5, 0x1c, 0x60, 0xe6, 0x06, 0x07, 0x86, 0x16, 0x26, 0x85, 0xe6, 0x03, 0x00, 0xe6, 0x1c, 0x00, 0xef, 0x00, 0x06, 0xaf, 0x00, 0x2f, 0x96, 0x6f, 0x36, 0xe0, 0x1d, 0xe5, 0x23, 0x27, 0x66, 0x07, 0xa6, 0x07, 0x26, 0x27, 0x26, 0x05, 0xe9, 0x02, 0xb6, 0xa5, 0x27, 0x26, 0x65, 0x46, 0x05, 0x47, 0x25, 0xc7, 0x45, 0x66, 0xe5, 0x05, 0x06, 0x27, 0x26, 0xa7, 0x06, 0x05, 0x07, 0xe9, 0x02, 0x47, 0x06, 0x2f, 0xe1, 0x1e, 0x00, 0x01, 0x80, 0x01, 0x20, 0xe2, 0x23, 0x16, 0x04, 0x42, 0xe5, 0x80, 0xc1, 0x00, 0x65, 0x20, 0xc5, 0x00, 0x05, 0x00, 0x65, 0x20, 0xe5, 0x21, 0x00, 0x65, 0x20, 0xe5, 0x19, 0x00, 0x65, 0x20, 0xc5, 0x00, 0x05, 0x00, 0x65, 0x20, 0xe5, 0x07, 0x00, 0xe5, 0x31, 0x00, 0x65, 0x20, 0xe5, 0x3b, 0x20, 0x46, 0xf6, 0x01, 0xeb, 0x0c, 0x40, 0xe5, 0x08, 0xef, 0x02, 0xa0, 0xe1, 0x4e, 0x20, 0xa2, 0x20, 0x11, 0xe5, 0x81, 0xe4, 0x0f, 0x16, 0xe5, 0x09, 0x17, 0xe5, 0x12, 0x12, 0x13, 0x40, 0xe5, 0x43, 0x56, 0x4a, 0xe5, 0x00, 0xc0, 0xe5, 0x0a, 0x46, 0x07, 0xe0, 0x01, 0xe5, 0x0b, 0x26, 0x07, 0x36, 0xe0, 0x01, 0xe5, 0x0a, 0x26, 0xe0, 0x04, 0xe5, 0x05, 0x00, 0x45, 0x00, 0x26, 0xe0, 0x04, 0xe5, 0x2c, 0x26, 0x07, 0xc6, 0xe7, 0x00, 0x06, 0x27, 0xe6, 0x03, 0x56, 0x04, 0x56, 0x0d, 0x05, 0x06, 0x20, 0xe9, 0x02, 0xa0, 0xeb, 0x02, 0xa0, 0xb6, 0x11, 0x76, 0x46, 0x1b, 0x06, 0xe9, 0x02, 0xa0, 0xe5, 0x1b, 0x04, 0xe5, 0x2d, 0xc0, 0x85, 0x26, 0xe5, 0x1a, 0x06, 0x05, 0x80, 0xe5, 0x3e, 0xe0, 0x02, 0xe5, 0x17, 0x00, 0x46, 0x67, 0x26, 0x47, 0x60, 0x27, 0x06, 0xa7, 0x46, 0x60, 0x0f, 0x40, 0x36, 0xe9, 0x02, 0xe5, 0x16, 0x20, 0x85, 0xe0, 0x03, 0xe5, 0x24, 0x60, 0xe5, 0x12, 0xa0, 0xe9, 0x02, 0x0b, 0x40, 0xef, 0x1a, 0xe5, 0x0f, 0x26, 0x27, 0x06, 0x20, 0x36, 0xe5, 0x2d, 0x07, 0x06, 0x07, 0xc6, 0x00, 0x06, 0x07, 0x06, 0x27, 0xe6, 0x00, 0xa7, 0xe6, 0x02, 0x20, 0x06, 0xe9, 0x02, 0xa0, 0xe9, 0x02, 0xa0, 0xd6, 0x04, 0xb6, 0x20, 0xe6, 0x06, 0x08, 0xe6, 0x17, 0x20, 0xe6, 0x04, 0xe0, 0x0c, 0x66, 0x07, 0xe5, 0x27, 0x06, 0x07, 0x86, 0x07, 0x06, 0x87, 0x06, 0x27, 0xe5, 0x00, 0x00, 0x36, 0xe9, 0x02, 0xd6, 0xef, 0x02, 0xe6, 0x01, 0xef, 0x01, 0x56, 0x26, 0x07, 0xe5, 0x16, 0x07, 0x66, 0x27, 0x26, 0x07, 0x46, 0x25, 0xe9, 0x02, 0xe5, 0x24, 0x06, 0x07, 0x26, 0x47, 0x06, 0x07, 0x46, 0x27, 0xe0, 0x00, 0x76, 0xe5, 0x1c, 0xe7, 0x00, 0xe6, 0x00, 0x27, 0x26, 0x40, 0x96, 0xe9, 0x02, 0x40, 0x45, 0xe9, 0x02, 0xe5, 0x16, 0xa4, 0x36, 0xe2, 0x01, 0x3f, 0x80, 0xe1, 0x23, 0x20, 0x41, 0xf6, 0x00, 0xe0, 0x00, 0x46, 0x16, 0xe6, 0x05, 0x07, 0xc6, 0x65, 0x06, 0xa5, 0x06, 0x25, 0x07, 0x26, 0x05, 0x80, 0xe2, 0x24, 0xe4, 0x37, 0xe2, 0x05, 0x04, 0xe2, 0x1a, 0xe4, 0x1d, 0xe6, 0x38, 0xff, 0x80, 0x0e, 0xe2, 0x00, 0xff, 0x5a, 0xe2, 0x00, 0xe1, 0x00, 0xa2, 0x20, 0xa1, 0x20, 0xe2, 0x00, 0xe1, 0x00, 0xe2, 0x00, 0xe1, 0x00, 0xa2, 0x20, 0xa1, 0x20, 0xe2, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x3f, 0xc2, 0xe1, 0x00, 0xe2, 0x06, 0x20, 0xe2, 0x00, 0xe3, 0x00, 0xe2, 0x00, 0xe3, 0x00, 0xe2, 0x00, 0xe3, 0x00, 0x82, 0x00, 0x22, 0x61, 0x03, 0x0e, 0x02, 0x4e, 0x42, 0x00, 0x22, 0x61, 0x03, 0x4e, 0x62, 0x20, 0x22, 0x61, 0x00, 0x4e, 0xe2, 0x00, 0x81, 0x4e, 0x20, 0x42, 0x00, 0x22, 0x61, 0x03, 0x2e, 0x00, 0xf7, 0x03, 0x9b, 0xb1, 0x36, 0x14, 0x15, 0x12, 0x34, 0x15, 0x12, 0x14, 0xf6, 0x00, 0x18, 0x19, 0x9b, 0x17, 0xf6, 0x01, 0x14, 0x15, 0x76, 0x30, 0x56, 0x0c, 0x12, 0x13, 0xf6, 0x03, 0x0c, 0x16, 0x10, 0xf6, 0x02, 0x17, 0x9b, 0x00, 0xfb, 0x02, 0x0b, 0x04, 0x20, 0xab, 0x4c, 0x12, 0x13, 0x04, 0xeb, 0x02, 0x4c, 0x12, 0x13, 0x00, 0xe4, 0x05, 0x40, 0xed, 0x1a, 0xe0, 0x06, 0xe6, 0x05, 0x68, 0x06, 0x48, 0xe6, 0x04, 0xe0, 0x07, 0x2f, 0x01, 0x6f, 0x01, 0x2f, 0x02, 0x41, 0x22, 0x41, 0x02, 0x0f, 0x01, 0x2f, 0x0c, 0x81, 0xaf, 0x01, 0x0f, 0x01, 0x0f, 0x01, 0x0f, 0x61, 0x0f, 0x02, 0x61, 0x02, 0x65, 0x02, 0x2f, 0x22, 0x21, 0x8c, 0x3f, 0x42, 0x0f, 0x0c, 0x2f, 0x02, 0x0f, 0xeb, 0x08, 0xea, 0x1b, 0x3f, 0x6a, 0x0b, 0x2f, 0x60, 0x8c, 0x8f, 0x2c, 0x6f, 0x0c, 0x2f, 0x0c, 0x2f, 0x0c, 0xcf, 0x0c, 0xef, 0x17, 0x2c, 0x2f, 0x0c, 0x0f, 0x0c, 0xef, 0x17, 0xec, 0x80, 0x84, 0xef, 0x00, 0x12, 0x13, 0x12, 0x13, 0xef, 0x0c, 0x2c, 0xcf, 0x12, 0x13, 0xef, 0x49, 0x0c, 0xef, 0x16, 0xec, 0x11, 0xef, 0x20, 0xac, 0xef, 0x40, 0xe0, 0x0e, 0xef, 0x03, 0xe0, 0x0d, 0xeb, 0x34, 0xef, 0x46, 0xeb, 0x0e, 0xef, 0x80, 0x2f, 0x0c, 0xef, 0x01, 0x0c, 0xef, 0x2e, 0xec, 0x00, 0xef, 0x67, 0x0c, 0xef, 0x80, 0x70, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0xeb, 0x16, 0xef, 0x24, 0x8c, 0x12, 0x13, 0xec, 0x17, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0xec, 0x08, 0xef, 0x80, 0x78, 0xec, 0x7b, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0xec, 0x37, 0x12, 0x13, 0x12, 0x13, 0xec, 0x18, 0x12, 0x13, 0xec, 0x80, 0x7a, 0xef, 0x28, 0xec, 0x0d, 0x2f, 0xac, 0xef, 0x1f, 0x20, 0xef, 0x80, 0x02, 0xe1, 0x28, 0xe2, 0x28, 0x5f, 0x21, 0x22, 0xdf, 0x41, 0x02, 0x3f, 0x02, 0x3f, 0x82, 0x24, 0x41, 0x02, 0xff, 0x5a, 0x02, 0xaf, 0x7f, 0x46, 0x3f, 0x80, 0x76, 0x0b, 0x36, 0xe2, 0x1e, 0x00, 0x02, 0x80, 0x02, 0x20, 0xe5, 0x30, 0xc0, 0x04, 0x16, 0xe0, 0x06, 0x06, 0xe5, 0x0f, 0xe0, 0x01, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xe6, 0x18, 0x36, 0x14, 0x15, 0x14, 0x15, 0x56, 0x14, 0x15, 0x16, 0x14, 0x15, 0xf6, 0x01, 0x11, 0x36, 0x11, 0x16, 0x14, 0x15, 0x36, 0x14, 0x15, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x96, 0x04, 0xf6, 0x02, 0x31, 0x76, 0x11, 0x16, 0x12, 0xf6, 0x05, 0x2f, 0x56, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x11, 0xe0, 0x1a, 0xef, 0x12, 0x00, 0xef, 0x51, 0xe0, 0x04, 0xef, 0x80, 0x4e, 0xe0, 0x12, 0xef, 0x08, 0x17, 0x56, 0x0f, 0x04, 0x05, 0x0a, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x2f, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x11, 0x12, 0x33, 0x0f, 0xea, 0x01, 0x66, 0x27, 0x11, 0x84, 0x2f, 0x4a, 0x04, 0x05, 0x16, 0x2f, 0x00, 0xe5, 0x4e, 0x20, 0x26, 0x2e, 0x24, 0x05, 0x11, 0xe5, 0x52, 0x16, 0x44, 0x05, 0x80, 0xe5, 0x23, 0x00, 0xe5, 0x56, 0x00, 0x2f, 0x6b, 0xef, 0x02, 0xe5, 0x18, 0xef, 0x1e, 0xe0, 0x01, 0x0f, 0xe5, 0x08, 0xef, 0x17, 0x00, 0xeb, 0x02, 0xef, 0x16, 0xeb, 0x00, 0x0f, 0xeb, 0x07, 0xef, 0x18, 0xeb, 0x02, 0xef, 0x1f, 0xeb, 0x07, 0xef, 0x80, 0xb8, 0xe5, 0x99, 0x38, 0xef, 0x38, 0xe5, 0xc0, 0x11, 0x8d, 0x04, 0xe5, 0x83, 0xef, 0x40, 0xef, 0x2f, 0xe0, 0x01, 0xe5, 0x20, 0xa4, 0x36, 0xe5, 0x80, 0x84, 0x04, 0x56, 0xe5, 0x08, 0xe9, 0x02, 0x25, 0xe0, 0x0c, 0xff, 0x26, 0x05, 0x06, 0x48, 0x16, 0xe6, 0x02, 0x16, 0x04, 0xff, 0x14, 0x24, 0x26, 0xe5, 0x3e, 0xea, 0x02, 0x26, 0xb6, 0xe0, 0x00, 0xee, 0x0f, 0xe4, 0x01, 0x2e, 0xff, 0x06, 0x22, 0xff, 0x36, 0x04, 0xe2, 0x00, 0x9f, 0xff, 0x02, 0x04, 0x2e, 0x7f, 0x05, 0x7f, 0x22, 0xff, 0x0d, 0x61, 0x02, 0x81, 0x02, 0xff, 0x07, 0x41, 0x02, 0x5f, 0xff, 0x09, 0xe0, 0x0c, 0x64, 0x3f, 0x05, 0x24, 0x02, 0xc5, 0x06, 0x45, 0x06, 0x65, 0x06, 0xe5, 0x0f, 0x27, 0x26, 0x07, 0x6f, 0x06, 0x40, 0xab, 0x2f, 0x0d, 0x0f, 0xa0, 0xe5, 0x2c, 0x76, 0xe0, 0x00, 0x27, 0xe5, 0x2a, 0xe7, 0x08, 0x26, 0xe0, 0x00, 0x36, 0xe9, 0x02, 0xa0, 0xe6, 0x0a, 0xa5, 0x56, 0x05, 0x16, 0x25, 0x06, 0xe9, 0x02, 0xe5, 0x14, 0xe6, 0x00, 0x36, 0xe5, 0x0f, 0xe6, 0x03, 0x27, 0xe0, 0x03, 0x16, 0xe5, 0x15, 0x40, 0x46, 0x07, 0xe5, 0x27, 0x06, 0x27, 0x66, 0x27, 0x26, 0x47, 0xf6, 0x05, 0x00, 0x04, 0xe9, 0x02, 0x60, 0x36, 0x85, 0x06, 0x04, 0xe5, 0x01, 0xe9, 0x02, 0x85, 0x00, 0xe5, 0x21, 0xa6, 0x27, 0x26, 0x27, 0x26, 0xe0, 0x01, 0x45, 0x06, 0xe5, 0x00, 0x06, 0x07, 0x20, 0xe9, 0x02, 0x20, 0x76, 0xe5, 0x08, 0x04, 0xa5, 0x4f, 0x05, 0x07, 0x06, 0x07, 0xe5, 0x2a, 0x06, 0x05, 0x46, 0x25, 0x26, 0x85, 0x26, 0x05, 0x06, 0x05, 0xe0, 0x10, 0x25, 0x04, 0x36, 0xe5, 0x03, 0x07, 0x26, 0x27, 0x36, 0x05, 0x24, 0x07, 0x06, 0xe0, 0x02, 0xa5, 0x20, 0xa5, 0x20, 0xa5, 0xe0, 0x01, 0xc5, 0x00, 0xc5, 0x00, 0xe2, 0x23, 0x0e, 0x64, 0xe2, 0x01, 0x04, 0x2e, 0x60, 0xe2, 0x48, 0xe5, 0x1b, 0x27, 0x06, 0x27, 0x06, 0x27, 0x16, 0x07, 0x06, 0x20, 0xe9, 0x02, 0xa0, 0xe5, 0xab, 0x1c, 0xe0, 0x04, 0xe5, 0x0f, 0x60, 0xe5, 0x29, 0x60, 0xfc, 0x87, 0x78, 0xfd, 0x98, 0x78, 0xe5, 0x80, 0xe6, 0x20, 0xe5, 0x62, 0xe0, 0x1e, 0xc2, 0xe0, 0x04, 0x82, 0x80, 0x05, 0x06, 0xe5, 0x02, 0x0c, 0xe5, 0x05, 0x00, 0x85, 0x00, 0x05, 0x00, 0x25, 0x00, 0x25, 0x00, 0xe5, 0x64, 0xee, 0x09, 0xef, 0x08, 0xe5, 0x80, 0xe3, 0x13, 0x12, 0xef, 0x08, 0xe5, 0x38, 0x2f, 0xe5, 0x2e, 0xef, 0x00, 0xe0, 0x18, 0xe5, 0x04, 0x0d, 0x4f, 0xe6, 0x08, 0xd6, 0x12, 0x13, 0x16, 0xa0, 0xe6, 0x08, 0x16, 0x31, 0x30, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x36, 0x12, 0x13, 0x76, 0x50, 0x56, 0x00, 0x76, 0x11, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x56, 0x0c, 0x11, 0x4c, 0x00, 0x16, 0x0d, 0x36, 0x60, 0x85, 0x00, 0xe5, 0x7f, 0x20, 0x1b, 0x00, 0x56, 0x0d, 0x56, 0x12, 0x13, 0x16, 0x0c, 0x16, 0x11, 0x36, 0xe9, 0x02, 0x36, 0x4c, 0x36, 0xe1, 0x12, 0x12, 0x16, 0x13, 0x0e, 0x10, 0x0e, 0xe2, 0x12, 0x12, 0x0c, 0x13, 0x0c, 0x12, 0x13, 0x16, 0x12, 0x13, 0x36, 0xe5, 0x02, 0x04, 0xe5, 0x25, 0x24, 0xe5, 0x17, 0x40, 0xa5, 0x20, 0xa5, 0x20, 0xa5, 0x20, 0x45, 0x40, 0x2d, 0x0c, 0x0e, 0x0f, 0x2d, 0x00, 0x0f, 0x6c, 0x2f, 0xe0, 0x02, 0x5b, 0x2f, 0x20, 0xe5, 0x04, 0x00, 0xe5, 0x12, 0x00, 0xe5, 0x0b, 0x00, 0x25, 0x00, 0xe5, 0x07, 0x20, 0xe5, 0x06, 0xe0, 0x1a, 0xe5, 0x73, 0x80, 0x56, 0x60, 0xeb, 0x25, 0x40, 0xef, 0x01, 0xea, 0x2d, 0x6b, 0xef, 0x09, 0x2b, 0x4f, 0x00, 0xef, 0x05, 0x40, 0x0f, 0xe0, 0x27, 0xef, 0x25, 0x06, 0xe0, 0x7a, 0xe5, 0x15, 0x40, 0xe5, 0x29, 0xe0, 0x07, 0x06, 0xeb, 0x13, 0x60, 0xe5, 0x18, 0x6b, 0xe0, 0x01, 0xe5, 0x0c, 0x0a, 0xe5, 0x00, 0x0a, 0x80, 0xe5, 0x1e, 0x86, 0x80, 0xe5, 0x16, 0x00, 0x16, 0xe5, 0x1c, 0x60, 0xe5, 0x00, 0x16, 0x8a, 0xe0, 0x22, 0xe1, 0x20, 0xe2, 0x20, 0xe5, 0x46, 0x20, 0xe9, 0x02, 0xa0, 0xe1, 0x1c, 0x60, 0xe2, 0x1c, 0x60, 0xe5, 0x20, 0xe0, 0x00, 0xe5, 0x2c, 0xe0, 0x03, 0x16, 0xe1, 0x03, 0x00, 0xe1, 0x07, 0x00, 0xc1, 0x00, 0x21, 0x00, 0xe2, 0x03, 0x00, 0xe2, 0x07, 0x00, 0xc2, 0x00, 0x22, 0x40, 0xe5, 0x2c, 0xe0, 0x04, 0xe5, 0x80, 0xaf, 0xe0, 0x01, 0xe5, 0x0e, 0xe0, 0x02, 0xe5, 0x00, 0xe0, 0x10, 0xa4, 0x00, 0xe4, 0x22, 0x00, 0xe4, 0x01, 0xe0, 0x3d, 0xa5, 0x20, 0x05, 0x00, 0xe5, 0x24, 0x00, 0x25, 0x40, 0x05, 0x20, 0xe5, 0x0f, 0x00, 0x16, 0xeb, 0x00, 0xe5, 0x0f, 0x2f, 0xcb, 0xe5, 0x17, 0xe0, 0x00, 0xeb, 0x01, 0xe0, 0x28, 0xe5, 0x0b, 0x00, 0x25, 0x80, 0x8b, 0xe5, 0x0e, 0xab, 0x40, 0x16, 0xe5, 0x12, 0x80, 0x16, 0xe5, 0x12, 0xe0, 0x1e, 0xe5, 0x30, 0x60, 0x2b, 0x25, 0xeb, 0x08, 0x20, 0xeb, 0x26, 0x05, 0x46, 0x00, 0x26, 0x80, 0x66, 0x65, 0x00, 0x45, 0x00, 0xe5, 0x15, 0x20, 0x46, 0x60, 0x06, 0xeb, 0x01, 0xc0, 0xf6, 0x01, 0xc0, 0xe5, 0x15, 0x2b, 0x16, 0xe5, 0x15, 0x4b, 0xe0, 0x18, 0xe5, 0x00, 0x0f, 0xe5, 0x14, 0x26, 0x60, 0x8b, 0xd6, 0xe0, 0x01, 0xe5, 0x2e, 0x40, 0xd6, 0xe5, 0x0e, 0x20, 0xeb, 0x00, 0xe5, 0x0b, 0x80, 0xeb, 0x00, 0xe5, 0x0a, 0xc0, 0x76, 0xe0, 0x04, 0xcb, 0xe0, 0x48, 0xe5, 0x41, 0xe0, 0x2f, 0xe1, 0x2b, 0xe0, 0x05, 0xe2, 0x2b, 0xc0, 0xab, 0xe5, 0x1c, 0x66, 0xe0, 0x00, 0xe9, 0x02, 0xa0, 0xe9, 0x02, 0x65, 0x04, 0x05, 0xe1, 0x0e, 0x40, 0x86, 0x11, 0x04, 0xe2, 0x0e, 0xe0, 0x00, 0x2c, 0xe0, 0x80, 0x48, 0xeb, 0x17, 0x00, 0xe5, 0x22, 0x00, 0x26, 0x11, 0x20, 0x25, 0xe0, 0x08, 0x45, 0x04, 0x25, 0xe0, 0x00, 0x16, 0xef, 0x00, 0xe0, 0x19, 0xa6, 0xe5, 0x15, 0xeb, 0x02, 0x05, 0xe0, 0x00, 0xe5, 0x0e, 0xe6, 0x03, 0x6b, 0x96, 0xe0, 0x0e, 0xe5, 0x0a, 0x66, 0x76, 0xe0, 0x1e, 0xe5, 0x0d, 0xcb, 0xe0, 0x0c, 0xe5, 0x0f, 0xe0, 0x01, 0x07, 0x06, 0x07, 0xe5, 0x2d, 0xe6, 0x07, 0xd6, 0x60, 0xeb, 0x0c, 0xe9, 0x02, 0x06, 0x25, 0x26, 0x05, 0xe0, 0x01, 0x46, 0x07, 0xe5, 0x25, 0x47, 0x66, 0x27, 0x26, 0x36, 0x1b, 0x76, 0x06, 0xe0, 0x02, 0x1b, 0x20, 0xe5, 0x11, 0xc0, 0xe9, 0x02, 0xa0, 0x46, 0xe5, 0x1c, 0x86, 0x07, 0xe6, 0x00, 0x00, 0xe9, 0x02, 0x76, 0x05, 0x27, 0x05, 0xe0, 0x00, 0xe5, 0x1b, 0x06, 0x36, 0x05, 0xe0, 0x01, 0x26, 0x07, 0xe5, 0x28, 0x47, 0xe6, 0x01, 0x27, 0x65, 0x76, 0x66, 0x16, 0x07, 0x06, 0xe9, 0x02, 0x05, 0x16, 0x05, 0x56, 0x00, 0xeb, 0x0c, 0xe0, 0x03, 0xe5, 0x0a, 0x00, 0xe5, 0x11, 0x47, 0x46, 0x27, 0x06, 0x07, 0x26, 0xb6, 0x06, 0x25, 0x06, 0xe0, 0x36, 0xc5, 0x00, 0x05, 0x00, 0x65, 0x00, 0xe5, 0x07, 0x00, 0xe5, 0x02, 0x16, 0xa0, 0xe5, 0x27, 0x06, 0x47, 0xe6, 0x00, 0x80, 0xe9, 0x02, 0xa0, 0x26, 0x27, 0x00, 0xe5, 0x00, 0x20, 0x25, 0x20, 0xe5, 0x0e, 0x00, 0xc5, 0x00, 0x25, 0x00, 0x85, 0x00, 0x26, 0x05, 0x27, 0x06, 0x67, 0x20, 0x27, 0x20, 0x47, 0x20, 0x05, 0xa0, 0x07, 0x80, 0x85, 0x27, 0x20, 0xc6, 0x40, 0x86, 0xe0, 0x03, 0xe5, 0x02, 0x00, 0x05, 0x20, 0x05, 0x00, 0xe5, 0x1e, 0x00, 0x05, 0x47, 0xa6, 0x00, 0x07, 0x20, 0x07, 0x00, 0x67, 0x00, 0x27, 0x06, 0x07, 0x06, 0x05, 0x06, 0x05, 0x36, 0x00, 0x36, 0xe0, 0x00, 0x26, 0xe0, 0x15, 0xe5, 0x2d, 0x47, 0xe6, 0x00, 0x27, 0x46, 0x07, 0x06, 0x65, 0x96, 0xe9, 0x02, 0x36, 0x00, 0x16, 0x06, 0x45, 0xe0, 0x16, 0xe5, 0x28, 0x47, 0xa6, 0x07, 0x06, 0x67, 0x26, 0x07, 0x26, 0x25, 0x16, 0x05, 0xe0, 0x00, 0xe9, 0x02, 0xe0, 0x80, 0x1e, 0xe5, 0x27, 0x47, 0x66, 0x20, 0x67, 0x26, 0x07, 0x26, 0xf6, 0x0f, 0x65, 0x26, 0xe0, 0x1a, 0xe5, 0x28, 0x47, 0xe6, 0x00, 0x27, 0x06, 0x07, 0x26, 0x56, 0x05, 0xe0, 0x03, 0xe9, 0x02, 0xa0, 0xf6, 0x05, 0xe0, 0x0b, 0xe5, 0x23, 0x06, 0x07, 0x06, 0x27, 0xa6, 0x07, 0x06, 0x05, 0x16, 0xa0, 0xe9, 0x02, 0xa0, 0xe9, 0x0c, 0xe0, 0x14, 0xe5, 0x13, 0x20, 0x06, 0x07, 0x06, 0x27, 0x66, 0x07, 0x86, 0x60, 0xe9, 0x02, 0x2b, 0x56, 0x0f, 0xc5, 0xe0, 0x80, 0x31, 0xe5, 0x24, 0x47, 0xe6, 0x01, 0x07, 0x26, 0x16, 0xe0, 0x5c, 0xe1, 0x18, 0xe2, 0x18, 0xe9, 0x02, 0xeb, 0x01, 0xe0, 0x04, 0xe5, 0x00, 0x20, 0x05, 0x20, 0xe5, 0x00, 0x00, 0x25, 0x00, 0xe5, 0x10, 0xa7, 0x00, 0x27, 0x20, 0x26, 0x07, 0x06, 0x05, 0x07, 0x05, 0x07, 0x06, 0x56, 0xe0, 0x01, 0xe9, 0x02, 0xe0, 0x3e, 0xe5, 0x00, 0x20, 0xe5, 0x1f, 0x47, 0x66, 0x20, 0x26, 0x67, 0x06, 0x05, 0x16, 0x05, 0x07, 0xe0, 0x13, 0x05, 0xe6, 0x02, 0xe5, 0x20, 0xa6, 0x07, 0x05, 0x66, 0xf6, 0x00, 0x06, 0xe0, 0x00, 0x05, 0xa6, 0x27, 0x46, 0xe5, 0x26, 0xe6, 0x05, 0x07, 0x26, 0x56, 0x05, 0x96, 0xe0, 0x05, 0xe5, 0x41, 0xc0, 0xf6, 0x02, 0xe0, 0x4e, 0x06, 0x07, 0x46, 0x07, 0x06, 0x07, 0xe0, 0x50, 0xe5, 0x19, 0x16, 0xe0, 0x06, 0xe9, 0x02, 0xa0, 0xe5, 0x01, 0x00, 0xe5, 0x1d, 0x07, 0xc6, 0x00, 0xa6, 0x07, 0x06, 0x05, 0x96, 0xe0, 0x02, 0xe9, 0x02, 0xeb, 0x0b, 0x40, 0x36, 0xe5, 0x16, 0x20, 0xe6, 0x0e, 0x00, 0x07, 0xc6, 0x07, 0x26, 0x07, 0x26, 0xe0, 0x41, 0xc5, 0x00, 0x25, 0x00, 0xe5, 0x1e, 0xa6, 0x40, 0x06, 0x00, 0x26, 0x00, 0xc6, 0x05, 0x06, 0xe0, 0x00, 0xe9, 0x02, 0xa0, 0xa5, 0x00, 0x25, 0x00, 0xe5, 0x18, 0x87, 0x00, 0x26, 0x00, 0x27, 0x06, 0x07, 0x06, 0x05, 0xc0, 0xe9, 0x02, 0xa0, 0xe5, 0x21, 0x04, 0x25, 0x60, 0xe9, 0x02, 0xe0, 0x80, 0x6e, 0xe5, 0x0b, 0x26, 0x27, 0x36, 0xc0, 0x26, 0x05, 0x07, 0xe5, 0x05, 0x00, 0xe5, 0x1a, 0x27, 0x86, 0x40, 0x27, 0x06, 0x07, 0x06, 0xf6, 0x05, 0xe9, 0x02, 0x06, 0xe0, 0x4d, 0x05, 0xe0, 0x07, 0xeb, 0x0d, 0xef, 0x00, 0x6d, 0xef, 0x09, 0xe0, 0x05, 0x16, 0xe5, 0x83, 0x12, 0xe0, 0x5e, 0xea, 0x67, 0x00, 0x96, 0xe0, 0x03, 0xe5, 0x80, 0x3c, 0xe0, 0x89, 0xc4, 0xe5, 0x59, 0x36, 0xe0, 0x05, 0xe5, 0x83, 0xa8, 0xfb, 0x08, 0x06, 0xa5, 0xe6, 0x07, 0xe0, 0x02, 0xe5, 0x8f, 0x13, 0x80, 0xe5, 0x81, 0xbf, 0xe0, 0x9a, 0x31, 0xe5, 0x16, 0xe6, 0x04, 0x47, 0x46, 0xe9, 0x02, 0xe0, 0x86, 0x3e, 0xe5, 0x81, 0xb1, 0xc0, 0xe5, 0x17, 0x00, 0xe9, 0x02, 0x60, 0x36, 0xe5, 0x47, 0x00, 0xe9, 0x02, 0xa0, 0xe5, 0x16, 0x20, 0x86, 0x16, 0xe0, 0x02, 0xe5, 0x28, 0xc6, 0x96, 0x6f, 0x64, 0x16, 0x0f, 0xe0, 0x02, 0xe9, 0x02, 0x00, 0xcb, 0x00, 0xe5, 0x0d, 0x80, 0xe5, 0x0b, 0xe0, 0x81, 0x28, 0x44, 0xe5, 0x20, 0x24, 0x56, 0xe9, 0x02, 0xe0, 0x80, 0x3e, 0xe1, 0x18, 0xe2, 0x18, 0xeb, 0x0f, 0x76, 0x80, 0xe1, 0x11, 0x20, 0xe2, 0x11, 0xe0, 0x24, 0xe5, 0x43, 0x60, 0x06, 0x05, 0xe7, 0x2f, 0xc0, 0x66, 0xe4, 0x05, 0xe0, 0x38, 0x24, 0x16, 0x04, 0x06, 0xe0, 0x03, 0x27, 0x24, 0x4a, 0xe0, 0x01, 0xe5, 0x9c, 0x4e, 0xe0, 0x21, 0xe5, 0x18, 0xe0, 0x59, 0xe5, 0x6b, 0xe0, 0xa1, 0x75, 0x64, 0x00, 0xc4, 0x00, 0x24, 0x00, 0xe5, 0x80, 0x9b, 0xe0, 0x07, 0x05, 0xe0, 0x15, 0x45, 0x20, 0x05, 0xe0, 0x06, 0x65, 0xe0, 0x00, 0xe5, 0x81, 0x04, 0xe0, 0x88, 0x7c, 0xe5, 0x63, 0x80, 0xe5, 0x05, 0x40, 0xe5, 0x01, 0xc0, 0xe5, 0x02, 0x20, 0x0f, 0x26, 0x16, 0x7b, 0xe0, 0x8e, 0xd4, 0xef, 0x80, 0x68, 0xe9, 0x02, 0x4f, 0x40, 0xef, 0x81, 0x2c, 0xa0, 0xef, 0x0f, 0xe0, 0x07, 0xef, 0x08, 0x0c, 0xe0, 0x07, 0xe6, 0x26, 0x20, 0xe6, 0x0f, 0xe0, 0x01, 0xef, 0x6c, 0xe0, 0x34, 0xef, 0x80, 0x6e, 0xe0, 0x02, 0xef, 0x1f, 0x20, 0xef, 0x34, 0x27, 0x46, 0x4f, 0xa7, 0xfb, 0x00, 0xe6, 0x00, 0x2f, 0xc6, 0xef, 0x16, 0x66, 0xef, 0x35, 0xe0, 0x0d, 0xef, 0x3a, 0x46, 0x0f, 0xe0, 0x72, 0xeb, 0x0c, 0xe0, 0x04, 0xeb, 0x0c, 0xe0, 0x04, 0xef, 0x4f, 0xe0, 0x01, 0xeb, 0x11, 0xe0, 0x7f, 0xe1, 0x12, 0xe2, 0x12, 0xe1, 0x12, 0xc2, 0x00, 0xe2, 0x0a, 0xe1, 0x12, 0xe2, 0x12, 0x01, 0x00, 0x21, 0x20, 0x01, 0x20, 0x21, 0x20, 0x61, 0x00, 0xe1, 0x00, 0x62, 0x00, 0x02, 0x00, 0xc2, 0x00, 0xe2, 0x03, 0xe1, 0x12, 0xe2, 0x12, 0x21, 0x00, 0x61, 0x20, 0xe1, 0x00, 0x00, 0xc1, 0x00, 0xe2, 0x12, 0x21, 0x00, 0x61, 0x00, 0x81, 0x00, 0x01, 0x40, 0xc1, 0x00, 0xe2, 0x12, 0xe1, 0x12, 0xe2, 0x12, 0xe1, 0x12, 0xe2, 0x12, 0xe1, 0x12, 0xe2, 0x12, 0xe1, 0x12, 0xe2, 0x12, 0xe1, 0x12, 0xe2, 0x12, 0xe1, 0x12, 0xe2, 0x14, 0x20, 0xe1, 0x11, 0x0c, 0xe2, 0x11, 0x0c, 0xa2, 0xe1, 0x11, 0x0c, 0xe2, 0x11, 0x0c, 0xa2, 0xe1, 0x11, 0x0c, 0xe2, 0x11, 0x0c, 0xa2, 0xe1, 0x11, 0x0c, 0xe2, 0x11, 0x0c, 0xa2, 0xe1, 0x11, 0x0c, 0xe2, 0x11, 0x0c, 0xa2, 0x3f, 0x20, 0xe9, 0x2a, 0xef, 0x81, 0x78, 0xe6, 0x2f, 0x6f, 0xe6, 0x2a, 0xef, 0x00, 0x06, 0xef, 0x06, 0x06, 0x2f, 0x96, 0xe0, 0x07, 0x86, 0x00, 0xe6, 0x07, 0xe0, 0x83, 0xc8, 0xe2, 0x02, 0x05, 0xe2, 0x0c, 0xa0, 0xa2, 0xe0, 0x80, 0x4d, 0xc6, 0x00, 0xe6, 0x09, 0x20, 0xc6, 0x00, 0x26, 0x00, 0x86, 0x80, 0xe4, 0x36, 0xe0, 0x19, 0x06, 0xe0, 0x68, 0xe5, 0x25, 0x40, 0xc6, 0xc4, 0x20, 0xe9, 0x02, 0x60, 0x05, 0x0f, 0xe0, 0x80, 0xb8, 0xe5, 0x16, 0x06, 0xe0, 0x09, 0xe5, 0x24, 0x66, 0xe9, 0x02, 0x80, 0x0d, 0xe0, 0x81, 0x48, 0xe5, 0x13, 0x04, 0x66, 0xe9, 0x02, 0xe0, 0x80, 0x4e, 0xe5, 0x16, 0x26, 0x05, 0xe9, 0x02, 0x60, 0x16, 0xe0, 0x80, 0x38, 0xe5, 0x17, 0x00, 0x45, 0x06, 0x25, 0x06, 0xc5, 0x26, 0x85, 0x06, 0xe0, 0x00, 0x05, 0x04, 0xe0, 0x80, 0x58, 0xc5, 0x00, 0x65, 0x00, 0x25, 0x00, 0xe5, 0x07, 0x00, 0xe5, 0x80, 0x3d, 0x20, 0xeb, 0x01, 0xc6, 0xe0, 0x21, 0xe1, 0x1a, 0xe2, 0x1a, 0xc6, 0x04, 0x60, 0xe9, 0x02, 0x60, 0x36, 0xe0, 0x82, 0x89, 0xeb, 0x33, 0x0f, 0x4b, 0x0d, 0x6b, 0xe0, 0x44, 0xeb, 0x25, 0x0f, 0xeb, 0x07, 0xe0, 0x80, 0x3a, 0x65, 0x00, 0xe5, 0x13, 0x00, 0x25, 0x00, 0x05, 0x20, 0x05, 0x00, 0xe5, 0x02, 0x00, 0x65, 0x00, 0x05, 0x00, 0x05, 0xa0, 0x05, 0x60, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x45, 0x00, 0x25, 0x00, 0x05, 0x20, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x25, 0x00, 0x05, 0x20, 0x65, 0x00, 0xc5, 0x00, 0x65, 0x00, 0x65, 0x00, 0x05, 0x00, 0xe5, 0x02, 0x00, 0xe5, 0x09, 0x80, 0x45, 0x00, 0x85, 0x00, 0xe5, 0x09, 0xe0, 0x2c, 0x2c, 0xe0, 0x80, 0x86, 0xef, 0x24, 0x60, 0xef, 0x5c, 0xe0, 0x04, 0xef, 0x07, 0x20, 0xef, 0x07, 0x00, 0xef, 0x07, 0x00, 0xef, 0x1d, 0xe0, 0x02, 0xeb, 0x05, 0xef, 0x80, 0x19, 0xe0, 0x30, 0xef, 0x15, 0xe0, 0x05, 0xef, 0x24, 0x60, 0xef, 0x01, 0xc0, 0x2f, 0xe0, 0x06, 0xaf, 0xe0, 0x80, 0x12, 0xef, 0x80, 0x73, 0x8e, 0xef, 0x82, 0x51, 0x40, 0xef, 0x09, 0x40, 0xef, 0x05, 0x40, 0xef, 0x80, 0x52, 0xa0, 0xef, 0x04, 0x60, 0x0f, 0xe0, 0x07, 0xef, 0x04, 0x60, 0xef, 0x30, 0xe0, 0x00, 0xef, 0x02, 0xa0, 0xef, 0x20, 0xe0, 0x00, 0xef, 0x16, 0x20, 0xef, 0x04, 0x60, 0x2f, 0xe0, 0x06, 0xec, 0x01, 0xe0, 0x1f, 0xef, 0x80, 0xd0, 0xe0, 0x00, 0xef, 0x06, 0x20, 0xef, 0x05, 0x40, 0xef, 0x03, 0x40, 0xef, 0x31, 0x00, 0x0f, 0x60, 0xef, 0x08, 0x20, 0xef, 0x04, 0x60, 0xef, 0x02, 0xc0, 0xef, 0x80, 0x0b, 0x00, 0xef, 0x54, 0xe9, 0x02, 0x0f, 0xe0, 0x83, 0x7d, 0xe5, 0xc0, 0x66, 0x58, 0xe0, 0x18, 0xe5, 0x90, 0x96, 0x20, 0xe5, 0x96, 0x06, 0x20, 0xe5, 0x9c, 0xa9, 0xe0, 0x07, 0xe5, 0x81, 0xe6, 0xe0, 0x89, 0x1a, 0xe5, 0x81, 0x96, 0xe0, 0x85, 0x5a, 0xe5, 0x92, 0xc3, 0x80, 0xe5, 0xa0, 0xa2, 0xe0, 0xca, 0x8a, 0xff, 0x1b, 0xe0, 0x16, 0xfb, 0x58, 0xe0, 0x78, 0xe6, 0x80, 0x68, 0xe0, 0xc0, 0xbd, 0x88, 0xfd, 0xc0, 0xbf, 0x76, 0x20, 0xfd, 0xc0, 0xbf, 0x76, 0x20, }; typedef enum { UNICODE_SCRIPT_Unknown, UNICODE_SCRIPT_Adlam, UNICODE_SCRIPT_Ahom, UNICODE_SCRIPT_Anatolian_Hieroglyphs, UNICODE_SCRIPT_Arabic, UNICODE_SCRIPT_Armenian, UNICODE_SCRIPT_Avestan, UNICODE_SCRIPT_Balinese, UNICODE_SCRIPT_Bamum, UNICODE_SCRIPT_Bassa_Vah, UNICODE_SCRIPT_Batak, UNICODE_SCRIPT_Beria_Erfe, UNICODE_SCRIPT_Bengali, UNICODE_SCRIPT_Bhaiksuki, UNICODE_SCRIPT_Bopomofo, UNICODE_SCRIPT_Brahmi, UNICODE_SCRIPT_Braille, UNICODE_SCRIPT_Buginese, UNICODE_SCRIPT_Buhid, UNICODE_SCRIPT_Canadian_Aboriginal, UNICODE_SCRIPT_Carian, UNICODE_SCRIPT_Caucasian_Albanian, UNICODE_SCRIPT_Chakma, UNICODE_SCRIPT_Cham, UNICODE_SCRIPT_Cherokee, UNICODE_SCRIPT_Chorasmian, UNICODE_SCRIPT_Common, UNICODE_SCRIPT_Coptic, UNICODE_SCRIPT_Cuneiform, UNICODE_SCRIPT_Cypriot, UNICODE_SCRIPT_Cyrillic, UNICODE_SCRIPT_Cypro_Minoan, UNICODE_SCRIPT_Deseret, UNICODE_SCRIPT_Devanagari, UNICODE_SCRIPT_Dives_Akuru, UNICODE_SCRIPT_Dogra, UNICODE_SCRIPT_Duployan, UNICODE_SCRIPT_Egyptian_Hieroglyphs, UNICODE_SCRIPT_Elbasan, UNICODE_SCRIPT_Elymaic, UNICODE_SCRIPT_Ethiopic, UNICODE_SCRIPT_Garay, UNICODE_SCRIPT_Georgian, UNICODE_SCRIPT_Glagolitic, UNICODE_SCRIPT_Gothic, UNICODE_SCRIPT_Grantha, UNICODE_SCRIPT_Greek, UNICODE_SCRIPT_Gujarati, UNICODE_SCRIPT_Gunjala_Gondi, UNICODE_SCRIPT_Gurmukhi, UNICODE_SCRIPT_Gurung_Khema, UNICODE_SCRIPT_Han, UNICODE_SCRIPT_Hangul, UNICODE_SCRIPT_Hanifi_Rohingya, UNICODE_SCRIPT_Hanunoo, UNICODE_SCRIPT_Hatran, UNICODE_SCRIPT_Hebrew, UNICODE_SCRIPT_Hiragana, UNICODE_SCRIPT_Imperial_Aramaic, UNICODE_SCRIPT_Inherited, UNICODE_SCRIPT_Inscriptional_Pahlavi, UNICODE_SCRIPT_Inscriptional_Parthian, UNICODE_SCRIPT_Javanese, UNICODE_SCRIPT_Kaithi, UNICODE_SCRIPT_Kannada, UNICODE_SCRIPT_Katakana, UNICODE_SCRIPT_Katakana_Or_Hiragana, UNICODE_SCRIPT_Kawi, UNICODE_SCRIPT_Kayah_Li, UNICODE_SCRIPT_Kharoshthi, UNICODE_SCRIPT_Khmer, UNICODE_SCRIPT_Khojki, UNICODE_SCRIPT_Khitan_Small_Script, UNICODE_SCRIPT_Khudawadi, UNICODE_SCRIPT_Kirat_Rai, UNICODE_SCRIPT_Lao, UNICODE_SCRIPT_Latin, UNICODE_SCRIPT_Lepcha, UNICODE_SCRIPT_Limbu, UNICODE_SCRIPT_Linear_A, UNICODE_SCRIPT_Linear_B, UNICODE_SCRIPT_Lisu, UNICODE_SCRIPT_Lycian, UNICODE_SCRIPT_Lydian, UNICODE_SCRIPT_Makasar, UNICODE_SCRIPT_Mahajani, UNICODE_SCRIPT_Malayalam, UNICODE_SCRIPT_Mandaic, UNICODE_SCRIPT_Manichaean, UNICODE_SCRIPT_Marchen, UNICODE_SCRIPT_Masaram_Gondi, UNICODE_SCRIPT_Medefaidrin, UNICODE_SCRIPT_Meetei_Mayek, UNICODE_SCRIPT_Mende_Kikakui, UNICODE_SCRIPT_Meroitic_Cursive, UNICODE_SCRIPT_Meroitic_Hieroglyphs, UNICODE_SCRIPT_Miao, UNICODE_SCRIPT_Modi, UNICODE_SCRIPT_Mongolian, UNICODE_SCRIPT_Mro, UNICODE_SCRIPT_Multani, UNICODE_SCRIPT_Myanmar, UNICODE_SCRIPT_Nabataean, UNICODE_SCRIPT_Nag_Mundari, UNICODE_SCRIPT_Nandinagari, UNICODE_SCRIPT_New_Tai_Lue, UNICODE_SCRIPT_Newa, UNICODE_SCRIPT_Nko, UNICODE_SCRIPT_Nushu, UNICODE_SCRIPT_Nyiakeng_Puachue_Hmong, UNICODE_SCRIPT_Ogham, UNICODE_SCRIPT_Ol_Chiki, UNICODE_SCRIPT_Ol_Onal, UNICODE_SCRIPT_Old_Hungarian, UNICODE_SCRIPT_Old_Italic, UNICODE_SCRIPT_Old_North_Arabian, UNICODE_SCRIPT_Old_Permic, UNICODE_SCRIPT_Old_Persian, UNICODE_SCRIPT_Old_Sogdian, UNICODE_SCRIPT_Old_South_Arabian, UNICODE_SCRIPT_Old_Turkic, UNICODE_SCRIPT_Old_Uyghur, UNICODE_SCRIPT_Oriya, UNICODE_SCRIPT_Osage, UNICODE_SCRIPT_Osmanya, UNICODE_SCRIPT_Pahawh_Hmong, UNICODE_SCRIPT_Palmyrene, UNICODE_SCRIPT_Pau_Cin_Hau, UNICODE_SCRIPT_Phags_Pa, UNICODE_SCRIPT_Phoenician, UNICODE_SCRIPT_Psalter_Pahlavi, UNICODE_SCRIPT_Rejang, UNICODE_SCRIPT_Runic, UNICODE_SCRIPT_Samaritan, UNICODE_SCRIPT_Saurashtra, UNICODE_SCRIPT_Sharada, UNICODE_SCRIPT_Shavian, UNICODE_SCRIPT_Siddham, UNICODE_SCRIPT_Sidetic, UNICODE_SCRIPT_SignWriting, UNICODE_SCRIPT_Sinhala, UNICODE_SCRIPT_Sogdian, UNICODE_SCRIPT_Sora_Sompeng, UNICODE_SCRIPT_Soyombo, UNICODE_SCRIPT_Sundanese, UNICODE_SCRIPT_Sunuwar, UNICODE_SCRIPT_Syloti_Nagri, UNICODE_SCRIPT_Syriac, UNICODE_SCRIPT_Tagalog, UNICODE_SCRIPT_Tagbanwa, UNICODE_SCRIPT_Tai_Le, UNICODE_SCRIPT_Tai_Tham, UNICODE_SCRIPT_Tai_Viet, UNICODE_SCRIPT_Tai_Yo, UNICODE_SCRIPT_Takri, UNICODE_SCRIPT_Tamil, UNICODE_SCRIPT_Tangut, UNICODE_SCRIPT_Telugu, UNICODE_SCRIPT_Thaana, UNICODE_SCRIPT_Thai, UNICODE_SCRIPT_Tibetan, UNICODE_SCRIPT_Tifinagh, UNICODE_SCRIPT_Tirhuta, UNICODE_SCRIPT_Tangsa, UNICODE_SCRIPT_Todhri, UNICODE_SCRIPT_Tolong_Siki, UNICODE_SCRIPT_Toto, UNICODE_SCRIPT_Tulu_Tigalari, UNICODE_SCRIPT_Ugaritic, UNICODE_SCRIPT_Vai, UNICODE_SCRIPT_Vithkuqi, UNICODE_SCRIPT_Wancho, UNICODE_SCRIPT_Warang_Citi, UNICODE_SCRIPT_Yezidi, UNICODE_SCRIPT_Yi, UNICODE_SCRIPT_Zanabazar_Square, UNICODE_SCRIPT_COUNT, } UnicodeScriptEnum; static const char unicode_script_name_table[] = "Unknown,Zzzz" "\0" "Adlam,Adlm" "\0" "Ahom,Ahom" "\0" "Anatolian_Hieroglyphs,Hluw" "\0" "Arabic,Arab" "\0" "Armenian,Armn" "\0" "Avestan,Avst" "\0" "Balinese,Bali" "\0" "Bamum,Bamu" "\0" "Bassa_Vah,Bass" "\0" "Batak,Batk" "\0" "Beria_Erfe,Berf" "\0" "Bengali,Beng" "\0" "Bhaiksuki,Bhks" "\0" "Bopomofo,Bopo" "\0" "Brahmi,Brah" "\0" "Braille,Brai" "\0" "Buginese,Bugi" "\0" "Buhid,Buhd" "\0" "Canadian_Aboriginal,Cans" "\0" "Carian,Cari" "\0" "Caucasian_Albanian,Aghb" "\0" "Chakma,Cakm" "\0" "Cham,Cham" "\0" "Cherokee,Cher" "\0" "Chorasmian,Chrs" "\0" "Common,Zyyy" "\0" "Coptic,Copt,Qaac" "\0" "Cuneiform,Xsux" "\0" "Cypriot,Cprt" "\0" "Cyrillic,Cyrl" "\0" "Cypro_Minoan,Cpmn" "\0" "Deseret,Dsrt" "\0" "Devanagari,Deva" "\0" "Dives_Akuru,Diak" "\0" "Dogra,Dogr" "\0" "Duployan,Dupl" "\0" "Egyptian_Hieroglyphs,Egyp" "\0" "Elbasan,Elba" "\0" "Elymaic,Elym" "\0" "Ethiopic,Ethi" "\0" "Garay,Gara" "\0" "Georgian,Geor" "\0" "Glagolitic,Glag" "\0" "Gothic,Goth" "\0" "Grantha,Gran" "\0" "Greek,Grek" "\0" "Gujarati,Gujr" "\0" "Gunjala_Gondi,Gong" "\0" "Gurmukhi,Guru" "\0" "Gurung_Khema,Gukh" "\0" "Han,Hani" "\0" "Hangul,Hang" "\0" "Hanifi_Rohingya,Rohg" "\0" "Hanunoo,Hano" "\0" "Hatran,Hatr" "\0" "Hebrew,Hebr" "\0" "Hiragana,Hira" "\0" "Imperial_Aramaic,Armi" "\0" "Inherited,Zinh,Qaai" "\0" "Inscriptional_Pahlavi,Phli" "\0" "Inscriptional_Parthian,Prti" "\0" "Javanese,Java" "\0" "Kaithi,Kthi" "\0" "Kannada,Knda" "\0" "Katakana,Kana" "\0" "Katakana_Or_Hiragana,Hrkt" "\0" "Kawi,Kawi" "\0" "Kayah_Li,Kali" "\0" "Kharoshthi,Khar" "\0" "Khmer,Khmr" "\0" "Khojki,Khoj" "\0" "Khitan_Small_Script,Kits" "\0" "Khudawadi,Sind" "\0" "Kirat_Rai,Krai" "\0" "Lao,Laoo" "\0" "Latin,Latn" "\0" "Lepcha,Lepc" "\0" "Limbu,Limb" "\0" "Linear_A,Lina" "\0" "Linear_B,Linb" "\0" "Lisu,Lisu" "\0" "Lycian,Lyci" "\0" "Lydian,Lydi" "\0" "Makasar,Maka" "\0" "Mahajani,Mahj" "\0" "Malayalam,Mlym" "\0" "Mandaic,Mand" "\0" "Manichaean,Mani" "\0" "Marchen,Marc" "\0" "Masaram_Gondi,Gonm" "\0" "Medefaidrin,Medf" "\0" "Meetei_Mayek,Mtei" "\0" "Mende_Kikakui,Mend" "\0" "Meroitic_Cursive,Merc" "\0" "Meroitic_Hieroglyphs,Mero" "\0" "Miao,Plrd" "\0" "Modi,Modi" "\0" "Mongolian,Mong" "\0" "Mro,Mroo" "\0" "Multani,Mult" "\0" "Myanmar,Mymr" "\0" "Nabataean,Nbat" "\0" "Nag_Mundari,Nagm" "\0" "Nandinagari,Nand" "\0" "New_Tai_Lue,Talu" "\0" "Newa,Newa" "\0" "Nko,Nkoo" "\0" "Nushu,Nshu" "\0" "Nyiakeng_Puachue_Hmong,Hmnp" "\0" "Ogham,Ogam" "\0" "Ol_Chiki,Olck" "\0" "Ol_Onal,Onao" "\0" "Old_Hungarian,Hung" "\0" "Old_Italic,Ital" "\0" "Old_North_Arabian,Narb" "\0" "Old_Permic,Perm" "\0" "Old_Persian,Xpeo" "\0" "Old_Sogdian,Sogo" "\0" "Old_South_Arabian,Sarb" "\0" "Old_Turkic,Orkh" "\0" "Old_Uyghur,Ougr" "\0" "Oriya,Orya" "\0" "Osage,Osge" "\0" "Osmanya,Osma" "\0" "Pahawh_Hmong,Hmng" "\0" "Palmyrene,Palm" "\0" "Pau_Cin_Hau,Pauc" "\0" "Phags_Pa,Phag" "\0" "Phoenician,Phnx" "\0" "Psalter_Pahlavi,Phlp" "\0" "Rejang,Rjng" "\0" "Runic,Runr" "\0" "Samaritan,Samr" "\0" "Saurashtra,Saur" "\0" "Sharada,Shrd" "\0" "Shavian,Shaw" "\0" "Siddham,Sidd" "\0" "Sidetic,Sidt" "\0" "SignWriting,Sgnw" "\0" "Sinhala,Sinh" "\0" "Sogdian,Sogd" "\0" "Sora_Sompeng,Sora" "\0" "Soyombo,Soyo" "\0" "Sundanese,Sund" "\0" "Sunuwar,Sunu" "\0" "Syloti_Nagri,Sylo" "\0" "Syriac,Syrc" "\0" "Tagalog,Tglg" "\0" "Tagbanwa,Tagb" "\0" "Tai_Le,Tale" "\0" "Tai_Tham,Lana" "\0" "Tai_Viet,Tavt" "\0" "Tai_Yo,Tayo" "\0" "Takri,Takr" "\0" "Tamil,Taml" "\0" "Tangut,Tang" "\0" "Telugu,Telu" "\0" "Thaana,Thaa" "\0" "Thai,Thai" "\0" "Tibetan,Tibt" "\0" "Tifinagh,Tfng" "\0" "Tirhuta,Tirh" "\0" "Tangsa,Tnsa" "\0" "Todhri,Todr" "\0" "Tolong_Siki,Tols" "\0" "Toto,Toto" "\0" "Tulu_Tigalari,Tutg" "\0" "Ugaritic,Ugar" "\0" "Vai,Vaii" "\0" "Vithkuqi,Vith" "\0" "Wancho,Wcho" "\0" "Warang_Citi,Wara" "\0" "Yezidi,Yezi" "\0" "Yi,Yiii" "\0" "Zanabazar_Square,Zanb" "\0" ; static const uint8_t unicode_script_table[2818] = { 0xc0, 0x1a, 0x99, 0x4c, 0x85, 0x1a, 0x99, 0x4c, 0xae, 0x1a, 0x80, 0x4c, 0x8e, 0x1a, 0x80, 0x4c, 0x84, 0x1a, 0x96, 0x4c, 0x80, 0x1a, 0x9e, 0x4c, 0x80, 0x1a, 0xe1, 0x60, 0x4c, 0xa6, 0x1a, 0x84, 0x4c, 0x84, 0x1a, 0x81, 0x0e, 0x93, 0x1a, 0xe0, 0x0f, 0x3b, 0x83, 0x2e, 0x80, 0x1a, 0x82, 0x2e, 0x01, 0x83, 0x2e, 0x80, 0x1a, 0x80, 0x2e, 0x03, 0x80, 0x2e, 0x80, 0x1a, 0x80, 0x2e, 0x80, 0x1a, 0x82, 0x2e, 0x00, 0x80, 0x2e, 0x00, 0x93, 0x2e, 0x00, 0xbe, 0x2e, 0x8d, 0x1b, 0x8f, 0x2e, 0xe0, 0x24, 0x1e, 0x81, 0x3b, 0xe0, 0x48, 0x1e, 0x00, 0xa5, 0x05, 0x01, 0xb1, 0x05, 0x01, 0x82, 0x05, 0x00, 0xb6, 0x38, 0x07, 0x9a, 0x38, 0x03, 0x85, 0x38, 0x0a, 0x84, 0x04, 0x80, 0x1a, 0x85, 0x04, 0x80, 0x1a, 0x8d, 0x04, 0x80, 0x1a, 0x82, 0x04, 0x80, 0x1a, 0x9f, 0x04, 0x80, 0x1a, 0x89, 0x04, 0x8a, 0x3b, 0x99, 0x04, 0x80, 0x3b, 0xe0, 0x0b, 0x04, 0x80, 0x1a, 0xa1, 0x04, 0x8d, 0x93, 0x00, 0xbb, 0x93, 0x01, 0x82, 0x93, 0xaf, 0x04, 0xb1, 0x9e, 0x0d, 0xba, 0x6b, 0x01, 0x82, 0x6b, 0xad, 0x85, 0x01, 0x8e, 0x85, 0x00, 0x9b, 0x57, 0x01, 0x80, 0x57, 0x00, 0x8a, 0x93, 0x04, 0xa1, 0x04, 0x04, 0xca, 0x04, 0x80, 0x1a, 0x9c, 0x04, 0xd0, 0x21, 0x83, 0x3b, 0x8e, 0x21, 0x81, 0x1a, 0x99, 0x21, 0x83, 0x0c, 0x00, 0x87, 0x0c, 0x01, 0x81, 0x0c, 0x01, 0x95, 0x0c, 0x00, 0x86, 0x0c, 0x00, 0x80, 0x0c, 0x02, 0x83, 0x0c, 0x01, 0x88, 0x0c, 0x01, 0x81, 0x0c, 0x01, 0x83, 0x0c, 0x07, 0x80, 0x0c, 0x03, 0x81, 0x0c, 0x00, 0x84, 0x0c, 0x01, 0x98, 0x0c, 0x01, 0x82, 0x31, 0x00, 0x85, 0x31, 0x03, 0x81, 0x31, 0x01, 0x95, 0x31, 0x00, 0x86, 0x31, 0x00, 0x81, 0x31, 0x00, 0x81, 0x31, 0x00, 0x81, 0x31, 0x01, 0x80, 0x31, 0x00, 0x84, 0x31, 0x03, 0x81, 0x31, 0x01, 0x82, 0x31, 0x02, 0x80, 0x31, 0x06, 0x83, 0x31, 0x00, 0x80, 0x31, 0x06, 0x90, 0x31, 0x09, 0x82, 0x2f, 0x00, 0x88, 0x2f, 0x00, 0x82, 0x2f, 0x00, 0x95, 0x2f, 0x00, 0x86, 0x2f, 0x00, 0x81, 0x2f, 0x00, 0x84, 0x2f, 0x01, 0x89, 0x2f, 0x00, 0x82, 0x2f, 0x00, 0x82, 0x2f, 0x01, 0x80, 0x2f, 0x0e, 0x83, 0x2f, 0x01, 0x8b, 0x2f, 0x06, 0x86, 0x2f, 0x00, 0x82, 0x7a, 0x00, 0x87, 0x7a, 0x01, 0x81, 0x7a, 0x01, 0x95, 0x7a, 0x00, 0x86, 0x7a, 0x00, 0x81, 0x7a, 0x00, 0x84, 0x7a, 0x01, 0x88, 0x7a, 0x01, 0x81, 0x7a, 0x01, 0x82, 0x7a, 0x06, 0x82, 0x7a, 0x03, 0x81, 0x7a, 0x00, 0x84, 0x7a, 0x01, 0x91, 0x7a, 0x09, 0x81, 0x9b, 0x00, 0x85, 0x9b, 0x02, 0x82, 0x9b, 0x00, 0x83, 0x9b, 0x02, 0x81, 0x9b, 0x00, 0x80, 0x9b, 0x00, 0x81, 0x9b, 0x02, 0x81, 0x9b, 0x02, 0x82, 0x9b, 0x02, 0x8b, 0x9b, 0x03, 0x84, 0x9b, 0x02, 0x82, 0x9b, 0x00, 0x83, 0x9b, 0x01, 0x80, 0x9b, 0x05, 0x80, 0x9b, 0x0d, 0x94, 0x9b, 0x04, 0x8c, 0x9d, 0x00, 0x82, 0x9d, 0x00, 0x96, 0x9d, 0x00, 0x8f, 0x9d, 0x01, 0x88, 0x9d, 0x00, 0x82, 0x9d, 0x00, 0x83, 0x9d, 0x06, 0x81, 0x9d, 0x00, 0x82, 0x9d, 0x00, 0x81, 0x9d, 0x01, 0x83, 0x9d, 0x01, 0x89, 0x9d, 0x06, 0x88, 0x9d, 0x8c, 0x40, 0x00, 0x82, 0x40, 0x00, 0x96, 0x40, 0x00, 0x89, 0x40, 0x00, 0x84, 0x40, 0x01, 0x88, 0x40, 0x00, 0x82, 0x40, 0x00, 0x83, 0x40, 0x06, 0x81, 0x40, 0x04, 0x82, 0x40, 0x00, 0x83, 0x40, 0x01, 0x89, 0x40, 0x00, 0x82, 0x40, 0x0b, 0x8c, 0x56, 0x00, 0x82, 0x56, 0x00, 0xb2, 0x56, 0x00, 0x82, 0x56, 0x00, 0x85, 0x56, 0x03, 0x8f, 0x56, 0x01, 0x99, 0x56, 0x00, 0x82, 0x8c, 0x00, 0x91, 0x8c, 0x02, 0x97, 0x8c, 0x00, 0x88, 0x8c, 0x00, 0x80, 0x8c, 0x01, 0x86, 0x8c, 0x02, 0x80, 0x8c, 0x03, 0x85, 0x8c, 0x00, 0x80, 0x8c, 0x00, 0x87, 0x8c, 0x05, 0x89, 0x8c, 0x01, 0x82, 0x8c, 0x0b, 0xb9, 0x9f, 0x03, 0x80, 0x1a, 0x9b, 0x9f, 0x24, 0x81, 0x4b, 0x00, 0x80, 0x4b, 0x00, 0x84, 0x4b, 0x00, 0x97, 0x4b, 0x00, 0x80, 0x4b, 0x00, 0x96, 0x4b, 0x01, 0x84, 0x4b, 0x00, 0x80, 0x4b, 0x00, 0x86, 0x4b, 0x00, 0x89, 0x4b, 0x01, 0x83, 0x4b, 0x1f, 0xc7, 0xa0, 0x00, 0xa3, 0xa0, 0x03, 0xa6, 0xa0, 0x00, 0xa3, 0xa0, 0x00, 0x8e, 0xa0, 0x00, 0x86, 0xa0, 0x83, 0x1a, 0x81, 0xa0, 0x24, 0xe0, 0x3f, 0x65, 0xa5, 0x2a, 0x00, 0x80, 0x2a, 0x04, 0x80, 0x2a, 0x01, 0xaa, 0x2a, 0x80, 0x1a, 0x83, 0x2a, 0xe0, 0x9f, 0x34, 0xc8, 0x28, 0x00, 0x83, 0x28, 0x01, 0x86, 0x28, 0x00, 0x80, 0x28, 0x00, 0x83, 0x28, 0x01, 0xa8, 0x28, 0x00, 0x83, 0x28, 0x01, 0xa0, 0x28, 0x00, 0x83, 0x28, 0x01, 0x86, 0x28, 0x00, 0x80, 0x28, 0x00, 0x83, 0x28, 0x01, 0x8e, 0x28, 0x00, 0xb8, 0x28, 0x00, 0x83, 0x28, 0x01, 0xc2, 0x28, 0x01, 0x9f, 0x28, 0x02, 0x99, 0x28, 0x05, 0xd5, 0x18, 0x01, 0x85, 0x18, 0x01, 0xe2, 0x1f, 0x13, 0x9c, 0x6e, 0x02, 0xca, 0x84, 0x82, 0x1a, 0x8a, 0x84, 0x06, 0x95, 0x94, 0x08, 0x80, 0x94, 0x94, 0x36, 0x81, 0x1a, 0x08, 0x93, 0x12, 0x0b, 0x8c, 0x95, 0x00, 0x82, 0x95, 0x00, 0x81, 0x95, 0x0b, 0xdd, 0x46, 0x01, 0x89, 0x46, 0x05, 0x89, 0x46, 0x05, 0x81, 0x62, 0x81, 0x1a, 0x80, 0x62, 0x80, 0x1a, 0x93, 0x62, 0x05, 0xd8, 0x62, 0x06, 0xaa, 0x62, 0x04, 0xc5, 0x13, 0x09, 0x9e, 0x4e, 0x00, 0x8b, 0x4e, 0x03, 0x8b, 0x4e, 0x03, 0x80, 0x4e, 0x02, 0x8b, 0x4e, 0x9d, 0x96, 0x01, 0x84, 0x96, 0x0a, 0xab, 0x69, 0x03, 0x99, 0x69, 0x05, 0x8a, 0x69, 0x02, 0x81, 0x69, 0x9f, 0x46, 0x9b, 0x11, 0x01, 0x81, 0x11, 0xbe, 0x97, 0x00, 0x9c, 0x97, 0x01, 0x8a, 0x97, 0x05, 0x89, 0x97, 0x05, 0x8d, 0x97, 0x01, 0xad, 0x3b, 0x01, 0x8b, 0x3b, 0x13, 0xcc, 0x07, 0x00, 0xb1, 0x07, 0xbf, 0x90, 0xb3, 0x0a, 0x07, 0x83, 0x0a, 0xb7, 0x4d, 0x02, 0x8e, 0x4d, 0x02, 0x82, 0x4d, 0xaf, 0x6f, 0x8a, 0x1e, 0x04, 0xaa, 0x2a, 0x01, 0x82, 0x2a, 0x87, 0x90, 0x07, 0x82, 0x3b, 0x80, 0x1a, 0x8c, 0x3b, 0x80, 0x1a, 0x86, 0x3b, 0x83, 0x1a, 0x80, 0x3b, 0x85, 0x1a, 0x80, 0x3b, 0x82, 0x1a, 0x81, 0x3b, 0x80, 0x1a, 0x04, 0xa5, 0x4c, 0x84, 0x2e, 0x80, 0x1e, 0xb0, 0x4c, 0x84, 0x2e, 0x83, 0x4c, 0x84, 0x2e, 0x8c, 0x4c, 0x80, 0x1e, 0xc5, 0x4c, 0x80, 0x2e, 0xbf, 0x3b, 0xe0, 0x9f, 0x4c, 0x95, 0x2e, 0x01, 0x85, 0x2e, 0x01, 0xa5, 0x2e, 0x01, 0x85, 0x2e, 0x01, 0x87, 0x2e, 0x00, 0x80, 0x2e, 0x00, 0x80, 0x2e, 0x00, 0x80, 0x2e, 0x00, 0x9e, 0x2e, 0x01, 0xb4, 0x2e, 0x00, 0x8e, 0x2e, 0x00, 0x8d, 0x2e, 0x01, 0x85, 0x2e, 0x00, 0x92, 0x2e, 0x01, 0x82, 0x2e, 0x00, 0x88, 0x2e, 0x00, 0x8b, 0x1a, 0x81, 0x3b, 0xd6, 0x1a, 0x00, 0x8a, 0x1a, 0x80, 0x4c, 0x01, 0x8a, 0x1a, 0x80, 0x4c, 0x8e, 0x1a, 0x00, 0x8c, 0x4c, 0x02, 0xa1, 0x1a, 0x0d, 0xa0, 0x3b, 0x0e, 0xa5, 0x1a, 0x80, 0x2e, 0x82, 0x1a, 0x81, 0x4c, 0x85, 0x1a, 0x80, 0x4c, 0x9a, 0x1a, 0x80, 0x4c, 0x90, 0x1a, 0xa8, 0x4c, 0x82, 0x1a, 0x03, 0xe2, 0x39, 0x1a, 0x15, 0x8a, 0x1a, 0x14, 0xe3, 0x3f, 0x1a, 0xe0, 0x9f, 0x10, 0xe2, 0x13, 0x1a, 0x01, 0xe0, 0x29, 0x1a, 0xdf, 0x2b, 0x9f, 0x4c, 0xe0, 0x13, 0x1b, 0x04, 0x86, 0x1b, 0xa5, 0x2a, 0x00, 0x80, 0x2a, 0x04, 0x80, 0x2a, 0x01, 0xb7, 0xa1, 0x06, 0x81, 0xa1, 0x0d, 0x80, 0xa1, 0x96, 0x28, 0x08, 0x86, 0x28, 0x00, 0x86, 0x28, 0x00, 0x86, 0x28, 0x00, 0x86, 0x28, 0x00, 0x86, 0x28, 0x00, 0x86, 0x28, 0x00, 0x86, 0x28, 0x00, 0x86, 0x28, 0x00, 0x9f, 0x1e, 0xdd, 0x1a, 0x21, 0x99, 0x33, 0x00, 0xd8, 0x33, 0x0b, 0xe0, 0x75, 0x33, 0x19, 0x94, 0x1a, 0x80, 0x33, 0x80, 0x1a, 0x80, 0x33, 0x98, 0x1a, 0x88, 0x33, 0x83, 0x3b, 0x81, 0x34, 0x87, 0x1a, 0x83, 0x33, 0x83, 0x1a, 0x00, 0xd5, 0x39, 0x01, 0x81, 0x3b, 0x81, 0x1a, 0x82, 0x39, 0x80, 0x1a, 0xd9, 0x41, 0x81, 0x1a, 0x82, 0x41, 0x04, 0xaa, 0x0e, 0x00, 0xdd, 0x34, 0x00, 0x8f, 0x1a, 0x9f, 0x0e, 0xa5, 0x1a, 0x08, 0x80, 0x1a, 0x8f, 0x41, 0x9e, 0x34, 0x00, 0xbf, 0x1a, 0x9e, 0x34, 0xd0, 0x1a, 0xae, 0x41, 0x80, 0x1a, 0xd7, 0x41, 0xe0, 0x47, 0x1a, 0xf0, 0x09, 0x5f, 0x33, 0xbf, 0x1a, 0xf0, 0x41, 0x9f, 0x33, 0xe4, 0x2c, 0xae, 0x02, 0xb6, 0xae, 0x08, 0xaf, 0x51, 0xe0, 0xcb, 0xa9, 0x13, 0xdf, 0x1e, 0xd7, 0x08, 0x07, 0xa1, 0x1a, 0xe0, 0x05, 0x4c, 0x82, 0x1a, 0xd1, 0x4c, 0x13, 0x8e, 0x4c, 0xac, 0x92, 0x02, 0x89, 0x1a, 0x05, 0xb7, 0x80, 0x07, 0xc5, 0x86, 0x07, 0x8b, 0x86, 0x05, 0x9f, 0x21, 0xad, 0x44, 0x80, 0x1a, 0x80, 0x44, 0xa3, 0x83, 0x0a, 0x80, 0x83, 0x9c, 0x34, 0x02, 0xcd, 0x3e, 0x00, 0x80, 0x1a, 0x89, 0x3e, 0x03, 0x81, 0x3e, 0x9e, 0x65, 0x00, 0xb6, 0x17, 0x08, 0x8d, 0x17, 0x01, 0x89, 0x17, 0x01, 0x83, 0x17, 0x9f, 0x65, 0xc2, 0x98, 0x17, 0x84, 0x98, 0x96, 0x5c, 0x09, 0x85, 0x28, 0x01, 0x85, 0x28, 0x01, 0x85, 0x28, 0x08, 0x86, 0x28, 0x00, 0x86, 0x28, 0x00, 0xaa, 0x4c, 0x80, 0x1a, 0x88, 0x4c, 0x80, 0x2e, 0x83, 0x4c, 0x81, 0x1a, 0x03, 0xcf, 0x18, 0xad, 0x5c, 0x01, 0x89, 0x5c, 0x05, 0xf0, 0x1b, 0x43, 0x34, 0x0b, 0x96, 0x34, 0x03, 0xb0, 0x34, 0x70, 0x10, 0xa3, 0xe1, 0x0d, 0x33, 0x01, 0xe0, 0x09, 0x33, 0x25, 0x86, 0x4c, 0x0b, 0x84, 0x05, 0x04, 0x99, 0x38, 0x00, 0x84, 0x38, 0x00, 0x80, 0x38, 0x00, 0x81, 0x38, 0x00, 0x81, 0x38, 0x00, 0x89, 0x38, 0xe1, 0x8d, 0x04, 0x81, 0x1a, 0xe0, 0x2f, 0x04, 0x1f, 0x8f, 0x04, 0x8f, 0x3b, 0x89, 0x1a, 0x05, 0x8d, 0x3b, 0x81, 0x1e, 0xa2, 0x1a, 0x00, 0x92, 0x1a, 0x00, 0x83, 0x1a, 0x03, 0x84, 0x04, 0x00, 0xe0, 0x26, 0x04, 0x01, 0x80, 0x1a, 0x00, 0x9f, 0x1a, 0x99, 0x4c, 0x85, 0x1a, 0x99, 0x4c, 0x8a, 0x1a, 0x89, 0x41, 0x80, 0x1a, 0xac, 0x41, 0x81, 0x1a, 0x9e, 0x34, 0x02, 0x85, 0x34, 0x01, 0x85, 0x34, 0x01, 0x85, 0x34, 0x01, 0x82, 0x34, 0x02, 0x86, 0x1a, 0x00, 0x86, 0x1a, 0x09, 0x84, 0x1a, 0x01, 0x8b, 0x50, 0x00, 0x99, 0x50, 0x00, 0x92, 0x50, 0x00, 0x81, 0x50, 0x00, 0x8e, 0x50, 0x01, 0x8d, 0x50, 0x21, 0xe0, 0x1a, 0x50, 0x04, 0x82, 0x1a, 0x03, 0xac, 0x1a, 0x02, 0x88, 0x1a, 0xce, 0x2e, 0x00, 0x8c, 0x1a, 0x02, 0x80, 0x2e, 0x2e, 0xac, 0x1a, 0x80, 0x3b, 0x60, 0x21, 0x9c, 0x52, 0x02, 0xb0, 0x14, 0x0e, 0x80, 0x3b, 0x9a, 0x1a, 0x03, 0xa3, 0x72, 0x08, 0x82, 0x72, 0x9a, 0x2c, 0x04, 0xaa, 0x74, 0x04, 0x9d, 0xa8, 0x00, 0x80, 0xa8, 0xa3, 0x75, 0x03, 0x8d, 0x75, 0x29, 0xcf, 0x20, 0xaf, 0x88, 0x9d, 0x7c, 0x01, 0x89, 0x7c, 0x05, 0xa3, 0x7b, 0x03, 0xa3, 0x7b, 0x03, 0xa7, 0x26, 0x07, 0xb3, 0x15, 0x0a, 0x80, 0x15, 0x8a, 0xaa, 0x00, 0x8e, 0xaa, 0x00, 0x86, 0xaa, 0x00, 0x81, 0xaa, 0x00, 0x8a, 0xaa, 0x00, 0x8e, 0xaa, 0x00, 0x86, 0xaa, 0x00, 0x81, 0xaa, 0x02, 0xb3, 0xa4, 0x0b, 0xe0, 0xd6, 0x4f, 0x08, 0x95, 0x4f, 0x09, 0x87, 0x4f, 0x17, 0x85, 0x4c, 0x00, 0xa9, 0x4c, 0x00, 0x88, 0x4c, 0x44, 0x85, 0x1d, 0x01, 0x80, 0x1d, 0x00, 0xab, 0x1d, 0x00, 0x81, 0x1d, 0x02, 0x80, 0x1d, 0x01, 0x80, 0x1d, 0x95, 0x3a, 0x00, 0x88, 0x3a, 0x9f, 0x7e, 0x9e, 0x66, 0x07, 0x88, 0x66, 0x2f, 0x92, 0x37, 0x00, 0x81, 0x37, 0x04, 0x84, 0x37, 0x9b, 0x81, 0x02, 0x80, 0x81, 0x99, 0x53, 0x04, 0x80, 0x53, 0x99, 0x8a, 0x25, 0x9f, 0x5f, 0x97, 0x5e, 0x03, 0x93, 0x5e, 0x01, 0xad, 0x5e, 0x83, 0x45, 0x00, 0x81, 0x45, 0x04, 0x87, 0x45, 0x00, 0x82, 0x45, 0x00, 0x9c, 0x45, 0x01, 0x82, 0x45, 0x03, 0x89, 0x45, 0x06, 0x88, 0x45, 0x06, 0x9f, 0x77, 0x9f, 0x73, 0x1f, 0xa6, 0x58, 0x03, 0x8b, 0x58, 0x08, 0xb5, 0x06, 0x02, 0x86, 0x06, 0x95, 0x3d, 0x01, 0x87, 0x3d, 0x92, 0x3c, 0x04, 0x87, 0x3c, 0x91, 0x82, 0x06, 0x83, 0x82, 0x0b, 0x86, 0x82, 0x4f, 0xc8, 0x78, 0x36, 0xb2, 0x71, 0x0c, 0xb2, 0x71, 0x06, 0x85, 0x71, 0xa7, 0x35, 0x07, 0x89, 0x35, 0x05, 0xa5, 0x29, 0x02, 0x9c, 0x29, 0x07, 0x81, 0x29, 0x60, 0x6f, 0x9e, 0x04, 0x00, 0xa9, 0xad, 0x00, 0x82, 0xad, 0x01, 0x81, 0xad, 0x0f, 0x85, 0x04, 0x07, 0x88, 0x04, 0x20, 0x85, 0x04, 0xa7, 0x76, 0x07, 0xa9, 0x8d, 0x15, 0x99, 0x79, 0x25, 0x9b, 0x19, 0x13, 0x96, 0x27, 0x08, 0xcd, 0x0f, 0x03, 0xa3, 0x0f, 0x08, 0x80, 0x0f, 0xc2, 0x3f, 0x09, 0x80, 0x3f, 0x01, 0x98, 0x8e, 0x06, 0x89, 0x8e, 0x05, 0xb4, 0x16, 0x00, 0x91, 0x16, 0x07, 0xa6, 0x55, 0x08, 0xdf, 0x87, 0x00, 0x93, 0x8c, 0x0a, 0x91, 0x47, 0x00, 0xae, 0x47, 0x3d, 0x86, 0x64, 0x00, 0x80, 0x64, 0x00, 0x83, 0x64, 0x00, 0x8e, 0x64, 0x00, 0x8a, 0x64, 0x05, 0xba, 0x49, 0x04, 0x89, 0x49, 0x05, 0x83, 0x2d, 0x00, 0x87, 0x2d, 0x01, 0x81, 0x2d, 0x01, 0x95, 0x2d, 0x00, 0x86, 0x2d, 0x00, 0x81, 0x2d, 0x00, 0x84, 0x2d, 0x00, 0x80, 0x3b, 0x88, 0x2d, 0x01, 0x81, 0x2d, 0x01, 0x82, 0x2d, 0x01, 0x80, 0x2d, 0x05, 0x80, 0x2d, 0x04, 0x86, 0x2d, 0x01, 0x86, 0x2d, 0x02, 0x84, 0x2d, 0x0a, 0x89, 0xa7, 0x00, 0x80, 0xa7, 0x01, 0x80, 0xa7, 0x00, 0xa5, 0xa7, 0x00, 0x89, 0xa7, 0x00, 0x80, 0xa7, 0x01, 0x80, 0xa7, 0x00, 0x83, 0xa7, 0x00, 0x89, 0xa7, 0x00, 0x81, 0xa7, 0x07, 0x81, 0xa7, 0x1c, 0xdb, 0x6a, 0x00, 0x84, 0x6a, 0x1d, 0xc7, 0xa2, 0x07, 0x89, 0xa2, 0x60, 0x45, 0xb5, 0x89, 0x01, 0xa5, 0x89, 0x21, 0xc4, 0x61, 0x0a, 0x89, 0x61, 0x05, 0x8c, 0x62, 0x12, 0xb9, 0x9a, 0x05, 0x89, 0x9a, 0x05, 0x93, 0x65, 0x1b, 0x9a, 0x02, 0x01, 0x8e, 0x02, 0x03, 0x96, 0x02, 0x60, 0x58, 0xbb, 0x23, 0x60, 0x03, 0xd2, 0xac, 0x0b, 0x80, 0xac, 0x86, 0x22, 0x01, 0x80, 0x22, 0x01, 0x87, 0x22, 0x00, 0x81, 0x22, 0x00, 0x9d, 0x22, 0x00, 0x81, 0x22, 0x01, 0x8b, 0x22, 0x08, 0x89, 0x22, 0x45, 0x87, 0x68, 0x01, 0xad, 0x68, 0x01, 0x8a, 0x68, 0x1a, 0xc7, 0xaf, 0x07, 0xd2, 0x8f, 0x0c, 0x8f, 0x13, 0xb8, 0x7f, 0x06, 0x89, 0x21, 0x55, 0x87, 0x87, 0x57, 0xa1, 0x91, 0x0d, 0x89, 0x91, 0x05, 0x88, 0x0d, 0x00, 0xac, 0x0d, 0x00, 0x8d, 0x0d, 0x09, 0x9c, 0x0d, 0x02, 0x9f, 0x59, 0x01, 0x95, 0x59, 0x00, 0x8d, 0x59, 0x48, 0x86, 0x5a, 0x00, 0x81, 0x5a, 0x00, 0xab, 0x5a, 0x02, 0x80, 0x5a, 0x00, 0x81, 0x5a, 0x00, 0x88, 0x5a, 0x07, 0x89, 0x5a, 0x05, 0x85, 0x30, 0x00, 0x81, 0x30, 0x00, 0xa4, 0x30, 0x00, 0x81, 0x30, 0x00, 0x85, 0x30, 0x06, 0x89, 0x30, 0x05, 0xab, 0xa5, 0x03, 0x89, 0xa5, 0x60, 0x95, 0x98, 0x54, 0x06, 0x90, 0x43, 0x00, 0xa8, 0x43, 0x02, 0x9c, 0x43, 0x54, 0x80, 0x51, 0x0e, 0xb1, 0x9b, 0x0c, 0x80, 0x9b, 0xe3, 0x39, 0x1c, 0x60, 0x05, 0xe0, 0x0e, 0x1c, 0x00, 0x84, 0x1c, 0x0a, 0xe0, 0x63, 0x1c, 0x69, 0xeb, 0xe0, 0x02, 0x1f, 0x0c, 0xe3, 0xf5, 0x25, 0x09, 0xef, 0x3a, 0x25, 0x04, 0xe1, 0xe6, 0x03, 0x70, 0x0a, 0x58, 0xb9, 0x32, 0x66, 0x65, 0xe1, 0xd8, 0x08, 0x06, 0x9e, 0x63, 0x00, 0x89, 0x63, 0x03, 0x81, 0x63, 0xce, 0xa3, 0x00, 0x89, 0xa3, 0x05, 0x9d, 0x09, 0x01, 0x85, 0x09, 0x09, 0xc5, 0x7d, 0x09, 0x89, 0x7d, 0x00, 0x86, 0x7d, 0x00, 0x94, 0x7d, 0x04, 0x92, 0x7d, 0x61, 0x4f, 0xb9, 0x4a, 0x60, 0x65, 0xda, 0x5b, 0x04, 0x98, 0x0b, 0x01, 0x98, 0x0b, 0x2b, 0xca, 0x60, 0x03, 0xb8, 0x60, 0x06, 0x90, 0x60, 0x3f, 0x80, 0x9c, 0x80, 0x6c, 0x81, 0x33, 0x80, 0x48, 0x0a, 0x86, 0x33, 0x08, 0xf0, 0x0a, 0x9f, 0x9c, 0xe1, 0x75, 0x48, 0x28, 0x80, 0x48, 0x9e, 0x9c, 0x60, 0x00, 0xe0, 0x12, 0x9c, 0x70, 0x11, 0x9c, 0x83, 0x41, 0x00, 0x86, 0x41, 0x00, 0x81, 0x41, 0x00, 0x80, 0x41, 0xe0, 0xbe, 0x39, 0x82, 0x41, 0x0e, 0x80, 0x39, 0x1c, 0x82, 0x39, 0x01, 0x80, 0x41, 0x0d, 0x83, 0x41, 0x07, 0xe1, 0x2b, 0x6c, 0x68, 0xa3, 0xe0, 0x0a, 0x24, 0x04, 0x8c, 0x24, 0x02, 0x88, 0x24, 0x06, 0x89, 0x24, 0x01, 0x83, 0x24, 0x83, 0x1a, 0x6e, 0xfb, 0xe0, 0x9c, 0x1a, 0x02, 0xe1, 0x53, 0x1a, 0x05, 0x96, 0x1a, 0x0e, 0x90, 0x1a, 0x0e, 0xad, 0x3b, 0x01, 0x96, 0x3b, 0x08, 0xe0, 0x13, 0x1a, 0x3b, 0xe0, 0x95, 0x1a, 0x09, 0xa6, 0x1a, 0x01, 0xbd, 0x1a, 0x82, 0x3b, 0x90, 0x1a, 0x87, 0x3b, 0x81, 0x1a, 0x86, 0x3b, 0x9d, 0x1a, 0x83, 0x3b, 0xbc, 0x1a, 0x14, 0xc5, 0x2e, 0x60, 0x19, 0x93, 0x1a, 0x0b, 0x93, 0x1a, 0x0b, 0xd6, 0x1a, 0x08, 0x98, 0x1a, 0x60, 0x26, 0xd4, 0x1a, 0x00, 0xc6, 0x1a, 0x00, 0x81, 0x1a, 0x01, 0x80, 0x1a, 0x01, 0x81, 0x1a, 0x01, 0x83, 0x1a, 0x00, 0x8b, 0x1a, 0x00, 0x80, 0x1a, 0x00, 0x86, 0x1a, 0x00, 0xc0, 0x1a, 0x00, 0x83, 0x1a, 0x01, 0x87, 0x1a, 0x00, 0x86, 0x1a, 0x00, 0x9b, 0x1a, 0x00, 0x83, 0x1a, 0x00, 0x84, 0x1a, 0x00, 0x80, 0x1a, 0x02, 0x86, 0x1a, 0x00, 0xe0, 0xf3, 0x1a, 0x01, 0xe0, 0xc3, 0x1a, 0x01, 0xb1, 0x1a, 0xe2, 0x2b, 0x8b, 0x0e, 0x84, 0x8b, 0x00, 0x8e, 0x8b, 0x63, 0xef, 0x9e, 0x4c, 0x05, 0x85, 0x4c, 0x60, 0x74, 0x86, 0x2b, 0x00, 0x90, 0x2b, 0x01, 0x86, 0x2b, 0x00, 0x81, 0x2b, 0x00, 0x84, 0x2b, 0x04, 0xbd, 0x1e, 0x20, 0x80, 0x1e, 0x60, 0x0f, 0xac, 0x6d, 0x02, 0x8d, 0x6d, 0x01, 0x89, 0x6d, 0x03, 0x81, 0x6d, 0x60, 0xdf, 0x9e, 0xa6, 0x10, 0xb9, 0xab, 0x04, 0x80, 0xab, 0x61, 0x6f, 0xa9, 0x67, 0x60, 0x75, 0xaa, 0x70, 0x03, 0x80, 0x70, 0x60, 0x5f, 0x9e, 0x99, 0x00, 0x95, 0x99, 0x07, 0x81, 0x99, 0x60, 0x7f, 0x86, 0x28, 0x00, 0x83, 0x28, 0x00, 0x81, 0x28, 0x00, 0x8e, 0x28, 0x00, 0xe0, 0x64, 0x5d, 0x01, 0x8f, 0x5d, 0x28, 0xcb, 0x01, 0x03, 0x89, 0x01, 0x03, 0x81, 0x01, 0x62, 0xb0, 0xc3, 0x1a, 0x4b, 0xbc, 0x1a, 0x60, 0x61, 0x83, 0x04, 0x00, 0x9a, 0x04, 0x00, 0x81, 0x04, 0x00, 0x80, 0x04, 0x01, 0x80, 0x04, 0x00, 0x89, 0x04, 0x00, 0x83, 0x04, 0x00, 0x80, 0x04, 0x00, 0x80, 0x04, 0x05, 0x80, 0x04, 0x03, 0x80, 0x04, 0x00, 0x80, 0x04, 0x00, 0x80, 0x04, 0x00, 0x82, 0x04, 0x00, 0x81, 0x04, 0x00, 0x80, 0x04, 0x01, 0x80, 0x04, 0x00, 0x80, 0x04, 0x00, 0x80, 0x04, 0x00, 0x80, 0x04, 0x00, 0x80, 0x04, 0x00, 0x81, 0x04, 0x00, 0x80, 0x04, 0x01, 0x83, 0x04, 0x00, 0x86, 0x04, 0x00, 0x83, 0x04, 0x00, 0x83, 0x04, 0x00, 0x80, 0x04, 0x00, 0x89, 0x04, 0x00, 0x90, 0x04, 0x04, 0x82, 0x04, 0x00, 0x84, 0x04, 0x00, 0x90, 0x04, 0x33, 0x81, 0x04, 0x60, 0xad, 0xab, 0x1a, 0x03, 0xe0, 0x03, 0x1a, 0x0b, 0x8e, 0x1a, 0x01, 0x8e, 0x1a, 0x00, 0x8e, 0x1a, 0x00, 0xa4, 0x1a, 0x09, 0xe0, 0x4d, 0x1a, 0x37, 0x99, 0x1a, 0x80, 0x39, 0x81, 0x1a, 0x0c, 0xab, 0x1a, 0x03, 0x88, 0x1a, 0x06, 0x81, 0x1a, 0x0d, 0x85, 0x1a, 0x60, 0x39, 0xe3, 0x78, 0x1a, 0x02, 0x90, 0x1a, 0x02, 0x8c, 0x1a, 0x02, 0xe0, 0x79, 0x1a, 0x05, 0x8b, 0x1a, 0x03, 0x80, 0x1a, 0x0e, 0x8b, 0x1a, 0x03, 0xb7, 0x1a, 0x07, 0x89, 0x1a, 0x05, 0xa7, 0x1a, 0x07, 0x9d, 0x1a, 0x01, 0x8b, 0x1a, 0x03, 0x81, 0x1a, 0x0d, 0x88, 0x1a, 0x26, 0xe0, 0xf7, 0x1a, 0x07, 0x8d, 0x1a, 0x01, 0x8c, 0x1a, 0x02, 0x8a, 0x1a, 0x02, 0xb8, 0x1a, 0x00, 0x80, 0x1a, 0x03, 0x8f, 0x1a, 0x01, 0x8b, 0x1a, 0x03, 0x89, 0x1a, 0x06, 0xe0, 0x32, 0x1a, 0x00, 0xe0, 0x06, 0x1a, 0x63, 0xa4, 0xf0, 0x96, 0x7f, 0x33, 0x1f, 0xf0, 0x00, 0xbd, 0x33, 0x01, 0xf0, 0x06, 0x2d, 0x33, 0x01, 0xf0, 0x0c, 0xd0, 0x33, 0x0e, 0xe2, 0x0d, 0x33, 0x69, 0x41, 0xe1, 0xbd, 0x33, 0x65, 0x81, 0xf0, 0x02, 0xea, 0x33, 0x04, 0xf0, 0x10, 0xc9, 0x33, 0x7a, 0xbb, 0x26, 0x80, 0x1a, 0x1d, 0xdf, 0x1a, 0x60, 0x1f, 0xe0, 0x8f, 0x3b, }; static const uint8_t unicode_script_ext_table[1278] = { 0x80, 0x36, 0x00, 0x00, 0x10, 0x06, 0x14, 0x1b, 0x24, 0x26, 0x2a, 0x2b, 0x30, 0x2c, 0x2e, 0x33, 0x4c, 0x53, 0x55, 0x74, 0x88, 0x81, 0x83, 0x00, 0x00, 0x07, 0x0c, 0x1e, 0x21, 0x4c, 0x51, 0x9f, 0xa6, 0x09, 0x00, 0x00, 0x02, 0x0e, 0x4c, 0x00, 0x00, 0x02, 0x02, 0x0e, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x4c, 0x51, 0x08, 0x00, 0x00, 0x02, 0x4c, 0x9f, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x4c, 0x25, 0x00, 0x00, 0x08, 0x18, 0x1b, 0x1e, 0x2e, 0x4c, 0x74, 0x91, 0x96, 0x00, 0x08, 0x18, 0x1e, 0x2e, 0x4c, 0x7b, 0x91, 0x96, 0xa4, 0x00, 0x04, 0x18, 0x1e, 0x4c, 0xa1, 0x00, 0x05, 0x2b, 0x4c, 0x91, 0x93, 0x9f, 0x00, 0x0b, 0x15, 0x18, 0x1b, 0x1e, 0x2c, 0x2e, 0x4c, 0x7b, 0x93, 0xa1, 0xa4, 0x00, 0x06, 0x1b, 0x26, 0x2b, 0x2c, 0x41, 0x4c, 0x00, 0x05, 0x1e, 0x2e, 0x4c, 0x74, 0xa1, 0x00, 0x09, 0x1b, 0x24, 0x38, 0x4c, 0x74, 0x93, 0x96, 0xa1, 0xa4, 0x00, 0x0b, 0x05, 0x1e, 0x24, 0x2c, 0x2e, 0x38, 0x4c, 0x74, 0x93, 0x96, 0xa1, 0x00, 0x02, 0x4c, 0xa1, 0x00, 0x03, 0x24, 0x4c, 0x93, 0x00, 0x04, 0x18, 0x1e, 0x4c, 0x7b, 0x00, 0x03, 0x18, 0x4c, 0x96, 0x00, 0x02, 0x4c, 0x91, 0x00, 0x02, 0x28, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x4c, 0x91, 0x00, 0x03, 0x1e, 0x4c, 0xa4, 0x00, 0x00, 0x00, 0x04, 0x2e, 0x4c, 0x74, 0xa4, 0x0e, 0x00, 0x00, 0x06, 0x18, 0x24, 0x41, 0x4c, 0x93, 0xa1, 0x00, 0x04, 0x18, 0x24, 0x4c, 0x93, 0x00, 0x02, 0x4c, 0x93, 0x06, 0x00, 0x00, 0x03, 0x4c, 0x91, 0x93, 0x00, 0x02, 0x4c, 0x93, 0x00, 0x00, 0x00, 0x03, 0x18, 0x4c, 0x93, 0x00, 0x07, 0x15, 0x18, 0x2c, 0x4c, 0x91, 0x93, 0x9f, 0x0f, 0x00, 0x00, 0x01, 0x2e, 0x01, 0x00, 0x00, 0x01, 0x2e, 0x11, 0x00, 0x00, 0x02, 0x4c, 0x7b, 0x04, 0x00, 0x00, 0x03, 0x15, 0x4c, 0xa4, 0x03, 0x00, 0x0c, 0x01, 0x4c, 0x03, 0x00, 0x01, 0x02, 0x1b, 0x2e, 0x80, 0x8c, 0x00, 0x00, 0x02, 0x1e, 0x74, 0x00, 0x02, 0x1e, 0x2b, 0x01, 0x02, 0x1e, 0x4c, 0x00, 0x02, 0x1e, 0x2b, 0x80, 0x80, 0x00, 0x00, 0x03, 0x05, 0x2a, 0x2b, 0x80, 0x01, 0x00, 0x00, 0x07, 0x04, 0x29, 0x6b, 0x35, 0x93, 0x9e, 0xad, 0x0d, 0x00, 0x00, 0x07, 0x04, 0x29, 0x6b, 0x35, 0x93, 0x9e, 0xad, 0x00, 0x03, 0x04, 0x93, 0x9e, 0x01, 0x00, 0x00, 0x08, 0x01, 0x04, 0x29, 0x6b, 0x35, 0x93, 0x9e, 0xad, 0x1f, 0x00, 0x00, 0x09, 0x01, 0x04, 0x57, 0x58, 0x79, 0x82, 0x35, 0x8d, 0x93, 0x09, 0x00, 0x0a, 0x02, 0x04, 0x93, 0x09, 0x00, 0x09, 0x03, 0x04, 0x9e, 0xad, 0x05, 0x00, 0x00, 0x02, 0x04, 0x93, 0x62, 0x00, 0x00, 0x02, 0x04, 0x35, 0x81, 0xfb, 0x00, 0x00, 0x0f, 0x0c, 0x21, 0x2d, 0x2f, 0x31, 0x40, 0x4c, 0x56, 0x68, 0x6a, 0x7a, 0x87, 0x9b, 0x9d, 0xa2, 0x00, 0x0d, 0x0c, 0x21, 0x2d, 0x2f, 0x31, 0x40, 0x4c, 0x56, 0x6a, 0x7a, 0x9b, 0x9d, 0xa2, 0x10, 0x00, 0x00, 0x15, 0x0c, 0x21, 0x23, 0x30, 0x5a, 0x2d, 0x2f, 0x31, 0x40, 0x55, 0x56, 0x68, 0x70, 0x7a, 0x49, 0x8c, 0x92, 0x9a, 0x9b, 0x9d, 0xa2, 0x00, 0x17, 0x0c, 0x21, 0x23, 0x30, 0x5a, 0x2d, 0x2f, 0x32, 0x31, 0x40, 0x4e, 0x55, 0x56, 0x68, 0x70, 0x7a, 0x49, 0x8c, 0x92, 0x9a, 0x9b, 0x9d, 0xa2, 0x09, 0x04, 0x21, 0x23, 0x3f, 0x55, 0x75, 0x00, 0x09, 0x03, 0x0c, 0x16, 0x92, 0x75, 0x00, 0x09, 0x02, 0x31, 0x64, 0x75, 0x00, 0x09, 0x02, 0x2f, 0x47, 0x80, 0x75, 0x00, 0x0d, 0x02, 0x2d, 0x9b, 0x80, 0x71, 0x00, 0x09, 0x03, 0x40, 0x68, 0xa7, 0x82, 0xcf, 0x00, 0x09, 0x03, 0x16, 0x65, 0x96, 0x80, 0x30, 0x00, 0x00, 0x03, 0x2a, 0x2b, 0x4c, 0x85, 0x6e, 0x00, 0x02, 0x01, 0x84, 0x46, 0x00, 0x01, 0x04, 0x12, 0x36, 0x95, 0x94, 0x80, 0x4a, 0x00, 0x01, 0x02, 0x62, 0x80, 0x00, 0x00, 0x00, 0x02, 0x62, 0x80, 0x84, 0x49, 0x00, 0x00, 0x04, 0x0c, 0x21, 0x2d, 0x40, 0x00, 0x01, 0x21, 0x00, 0x04, 0x0c, 0x21, 0x2d, 0x40, 0x00, 0x03, 0x21, 0x2d, 0x40, 0x00, 0x01, 0x21, 0x00, 0x05, 0x0c, 0x21, 0x6a, 0x9d, 0xa2, 0x00, 0x03, 0x0c, 0x21, 0x9d, 0x00, 0x03, 0x21, 0x6a, 0x87, 0x00, 0x04, 0x0c, 0x21, 0x6a, 0x9d, 0x00, 0x02, 0x21, 0x87, 0x00, 0x06, 0x21, 0x40, 0x56, 0x7a, 0x9b, 0x9d, 0x00, 0x01, 0x21, 0x01, 0x02, 0x21, 0x87, 0x01, 0x01, 0x21, 0x00, 0x02, 0x21, 0x87, 0x00, 0x02, 0x0c, 0x21, 0x00, 0x03, 0x21, 0x6a, 0xa2, 0x05, 0x01, 0x21, 0x00, 0x03, 0x21, 0x68, 0x6a, 0x00, 0x03, 0x0c, 0x21, 0x87, 0x00, 0x02, 0x21, 0x6a, 0x00, 0x01, 0x21, 0x00, 0x04, 0x0c, 0x21, 0x6a, 0x87, 0x03, 0x01, 0x21, 0x00, 0x0b, 0x0c, 0x21, 0x2d, 0x40, 0x56, 0x68, 0x7a, 0x8c, 0x9d, 0xa2, 0xa7, 0x00, 0x02, 0x21, 0x2d, 0x00, 0x04, 0x21, 0x2d, 0x40, 0xa7, 0x01, 0x02, 0x0c, 0x21, 0x00, 0x01, 0x0c, 0x01, 0x02, 0x21, 0x2d, 0x00, 0x01, 0x68, 0x80, 0x44, 0x00, 0x01, 0x01, 0x2e, 0x35, 0x00, 0x00, 0x03, 0x1e, 0x4c, 0x93, 0x00, 0x00, 0x00, 0x01, 0x93, 0x81, 0xb3, 0x00, 0x00, 0x03, 0x4c, 0x62, 0x80, 0x1e, 0x00, 0x00, 0x02, 0x01, 0x04, 0x09, 0x00, 0x00, 0x06, 0x14, 0x2a, 0x2b, 0x71, 0x52, 0x78, 0x01, 0x00, 0x00, 0x04, 0x14, 0x2e, 0x71, 0x5f, 0x80, 0x11, 0x00, 0x00, 0x03, 0x21, 0x2d, 0x4c, 0x8c, 0xa5, 0x00, 0x00, 0x02, 0x1b, 0x4c, 0x17, 0x00, 0x00, 0x02, 0x06, 0x78, 0x00, 0x07, 0x06, 0x14, 0x2a, 0x71, 0x3f, 0x53, 0x85, 0x09, 0x00, 0x00, 0x01, 0x24, 0x03, 0x00, 0x00, 0x03, 0x01, 0x04, 0x71, 0x00, 0x00, 0x00, 0x02, 0x1e, 0x2b, 0x81, 0x2b, 0x00, 0x0f, 0x02, 0x33, 0x9c, 0x00, 0x00, 0x00, 0x07, 0x0e, 0x34, 0x33, 0x39, 0x41, 0x62, 0xae, 0x00, 0x08, 0x0e, 0x34, 0x33, 0x39, 0x41, 0x62, 0x80, 0xae, 0x00, 0x05, 0x0e, 0x34, 0x33, 0x39, 0x41, 0x01, 0x00, 0x00, 0x01, 0x33, 0x00, 0x00, 0x01, 0x08, 0x0e, 0x34, 0x33, 0x39, 0x41, 0x62, 0xa0, 0xae, 0x01, 0x09, 0x0e, 0x34, 0x33, 0x39, 0x41, 0x51, 0x62, 0xa0, 0xae, 0x05, 0x06, 0x0e, 0x34, 0x33, 0x39, 0x41, 0xae, 0x00, 0x00, 0x00, 0x05, 0x0e, 0x34, 0x33, 0x39, 0x41, 0x07, 0x06, 0x0e, 0x34, 0x33, 0x39, 0x41, 0xae, 0x03, 0x05, 0x0e, 0x34, 0x33, 0x39, 0x41, 0x09, 0x00, 0x03, 0x02, 0x0e, 0x33, 0x01, 0x00, 0x00, 0x05, 0x0e, 0x34, 0x33, 0x39, 0x41, 0x04, 0x02, 0x39, 0x41, 0x00, 0x00, 0x00, 0x05, 0x0e, 0x34, 0x33, 0x39, 0x41, 0x03, 0x00, 0x01, 0x03, 0x33, 0x39, 0x41, 0x01, 0x01, 0x33, 0x58, 0x00, 0x03, 0x02, 0x39, 0x41, 0x02, 0x00, 0x00, 0x02, 0x39, 0x41, 0x59, 0x00, 0x00, 0x06, 0x0e, 0x34, 0x33, 0x39, 0x41, 0xae, 0x00, 0x02, 0x39, 0x41, 0x80, 0x12, 0x00, 0x0f, 0x01, 0x33, 0x1f, 0x00, 0x25, 0x01, 0x33, 0x08, 0x00, 0x00, 0x02, 0x33, 0x9c, 0x2f, 0x00, 0x27, 0x01, 0x33, 0x37, 0x00, 0x30, 0x01, 0x33, 0x0e, 0x00, 0x0b, 0x01, 0x33, 0x32, 0x00, 0x00, 0x01, 0x33, 0x57, 0x00, 0x18, 0x01, 0x33, 0x09, 0x00, 0x04, 0x01, 0x33, 0x5f, 0x00, 0x1e, 0x01, 0x33, 0xc0, 0x31, 0xef, 0x00, 0x00, 0x02, 0x1e, 0x2b, 0x80, 0x0f, 0x00, 0x07, 0x02, 0x33, 0x4c, 0x80, 0xa7, 0x00, 0x02, 0x10, 0x21, 0x23, 0x2f, 0x31, 0x47, 0x40, 0x3f, 0x55, 0x56, 0x61, 0x68, 0x87, 0x49, 0x9a, 0xa2, 0xa7, 0x02, 0x0f, 0x21, 0x23, 0x2f, 0x31, 0x47, 0x40, 0x3f, 0x55, 0x61, 0x68, 0x87, 0x49, 0x9a, 0xa2, 0xa7, 0x01, 0x0b, 0x21, 0x23, 0x2f, 0x31, 0x47, 0x3f, 0x55, 0x61, 0x49, 0x9a, 0xa2, 0x00, 0x0c, 0x21, 0x23, 0x2f, 0x31, 0x47, 0x3f, 0x55, 0x61, 0x87, 0x49, 0x9a, 0xa2, 0x00, 0x0b, 0x21, 0x23, 0x2f, 0x31, 0x47, 0x3f, 0x55, 0x61, 0x49, 0x9a, 0xa2, 0x80, 0x36, 0x00, 0x00, 0x03, 0x0c, 0x21, 0xa7, 0x00, 0x00, 0x00, 0x02, 0x21, 0x9b, 0x39, 0x00, 0x00, 0x03, 0x44, 0x4c, 0x65, 0x80, 0x1f, 0x00, 0x00, 0x02, 0x11, 0x3e, 0xc0, 0x12, 0xed, 0x00, 0x01, 0x02, 0x04, 0x6b, 0x80, 0x31, 0x00, 0x00, 0x02, 0x04, 0x9e, 0x09, 0x00, 0x00, 0x02, 0x04, 0x9e, 0x46, 0x00, 0x01, 0x05, 0x0e, 0x34, 0x33, 0x39, 0x41, 0x80, 0x99, 0x00, 0x04, 0x06, 0x0e, 0x34, 0x33, 0x39, 0x41, 0xae, 0x09, 0x00, 0x00, 0x02, 0x39, 0x41, 0x2c, 0x00, 0x01, 0x02, 0x39, 0x41, 0x80, 0xdf, 0x00, 0x01, 0x03, 0x1f, 0x1d, 0x50, 0x00, 0x02, 0x1d, 0x50, 0x03, 0x00, 0x2c, 0x03, 0x1d, 0x4f, 0x50, 0x02, 0x00, 0x08, 0x02, 0x1d, 0x50, 0x81, 0x1f, 0x00, 0x1b, 0x02, 0x04, 0x1b, 0x87, 0x75, 0x00, 0x00, 0x02, 0x58, 0x79, 0x87, 0x8d, 0x00, 0x00, 0x02, 0x2d, 0x9b, 0x00, 0x00, 0x00, 0x02, 0x2d, 0x9b, 0x36, 0x00, 0x01, 0x02, 0x2d, 0x9b, 0x8c, 0x12, 0x00, 0x01, 0x02, 0x2d, 0x9b, 0x00, 0x00, 0x00, 0x02, 0x2d, 0x9b, 0xc0, 0x5c, 0x4b, 0x00, 0x03, 0x01, 0x24, 0x96, 0x3b, 0x00, 0x11, 0x01, 0x33, 0x9e, 0x5d, 0x00, 0x01, 0x01, 0x33, 0xce, 0xcd, 0x2d, 0x00, }; static const uint8_t unicode_prop_Hyphen_table[28] = { 0xac, 0x80, 0xfe, 0x80, 0x44, 0xdb, 0x80, 0x52, 0x7a, 0x80, 0x48, 0x08, 0x81, 0x4e, 0x04, 0x80, 0x42, 0xe2, 0x80, 0x60, 0xcd, 0x66, 0x80, 0x40, 0xa8, 0x80, 0xd6, 0x80, }; static const uint8_t unicode_prop_Other_Math_table[200] = { 0xdd, 0x80, 0x43, 0x70, 0x11, 0x80, 0x99, 0x09, 0x81, 0x5c, 0x1f, 0x80, 0x9a, 0x82, 0x8a, 0x80, 0x9f, 0x83, 0x97, 0x81, 0x8d, 0x81, 0xc0, 0x8c, 0x18, 0x11, 0x1c, 0x91, 0x03, 0x01, 0x89, 0x00, 0x14, 0x28, 0x11, 0x09, 0x02, 0x05, 0x13, 0x24, 0xca, 0x21, 0x18, 0x08, 0x08, 0x00, 0x21, 0x0b, 0x0b, 0x91, 0x09, 0x00, 0x06, 0x00, 0x29, 0x41, 0x21, 0x83, 0x40, 0xa7, 0x08, 0x80, 0x97, 0x80, 0x90, 0x80, 0x41, 0xbc, 0x81, 0x8b, 0x88, 0x24, 0x21, 0x09, 0x14, 0x8d, 0x00, 0x01, 0x85, 0x97, 0x81, 0xb8, 0x00, 0x80, 0x9c, 0x83, 0x88, 0x81, 0x41, 0x55, 0x81, 0x9e, 0x89, 0x41, 0x92, 0x95, 0xbe, 0x83, 0x9f, 0x81, 0x60, 0xd4, 0x62, 0x00, 0x03, 0x80, 0x40, 0xd2, 0x00, 0x80, 0x60, 0xd4, 0xc0, 0xd4, 0x80, 0xc6, 0x01, 0x08, 0x09, 0x0b, 0x80, 0x8b, 0x00, 0x06, 0x80, 0xc0, 0x03, 0x0f, 0x06, 0x80, 0x9b, 0x03, 0x04, 0x00, 0x16, 0x80, 0x41, 0x53, 0x81, 0x98, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x07, 0x81, 0xb1, 0x55, 0xff, 0x18, 0x9a, 0x01, 0x00, 0x08, 0x80, 0x89, 0x03, 0x00, 0x00, 0x28, 0x18, 0x00, 0x00, 0x02, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0b, 0x06, 0x03, 0x03, 0x00, 0x80, 0x89, 0x80, 0x90, 0x22, 0x04, 0x80, 0x90, }; static const uint8_t unicode_prop_Other_Alphabetic_table[452] = { 0x43, 0x44, 0x80, 0x9c, 0x8c, 0x42, 0x3f, 0x8d, 0x00, 0x01, 0x01, 0x00, 0xc7, 0x8a, 0xaf, 0x8c, 0x06, 0x8f, 0x80, 0xe4, 0x33, 0x19, 0x0b, 0x80, 0xa2, 0x80, 0x9d, 0x8f, 0xe5, 0x8a, 0xe4, 0x0a, 0x88, 0x02, 0x03, 0xe9, 0x80, 0xbb, 0x8b, 0x16, 0x85, 0x93, 0xb5, 0x09, 0x8e, 0x01, 0x22, 0x89, 0x81, 0x9c, 0x82, 0xb9, 0x31, 0x09, 0x81, 0x89, 0x80, 0x89, 0x81, 0x9c, 0x82, 0xb9, 0x23, 0x09, 0x0b, 0x80, 0x9d, 0x0a, 0x80, 0x8a, 0x82, 0xb9, 0x38, 0x10, 0x81, 0x94, 0x81, 0x95, 0x13, 0x82, 0xb9, 0x31, 0x09, 0x81, 0x88, 0x81, 0x89, 0x81, 0x9d, 0x80, 0xba, 0x22, 0x10, 0x82, 0x89, 0x80, 0xa7, 0x84, 0xb8, 0x30, 0x10, 0x17, 0x81, 0x8a, 0x81, 0x9c, 0x82, 0xb9, 0x30, 0x10, 0x17, 0x81, 0x8a, 0x81, 0x8e, 0x80, 0x8b, 0x83, 0xb9, 0x30, 0x10, 0x82, 0x89, 0x80, 0x89, 0x81, 0x9c, 0x82, 0xca, 0x28, 0x00, 0x87, 0x91, 0x81, 0xbc, 0x01, 0x86, 0x91, 0x80, 0xe2, 0x01, 0x28, 0x81, 0x8f, 0x80, 0x40, 0xa2, 0x92, 0x88, 0x8a, 0x80, 0xa3, 0xed, 0x8b, 0x00, 0x0b, 0x96, 0x1b, 0x10, 0x11, 0x32, 0x83, 0x8c, 0x8b, 0x00, 0x89, 0x83, 0x46, 0x73, 0x81, 0x9d, 0x81, 0x9d, 0x81, 0x9d, 0x81, 0xc1, 0x92, 0x40, 0xbb, 0x81, 0xa1, 0x80, 0xf5, 0x8b, 0x83, 0x88, 0x40, 0xdd, 0x84, 0xb8, 0x89, 0x81, 0x93, 0xc9, 0x81, 0x8a, 0x82, 0xb0, 0x84, 0xaf, 0x8e, 0xbb, 0x82, 0x9d, 0x88, 0x09, 0xb8, 0x8a, 0xb1, 0x92, 0x41, 0x9b, 0xa1, 0x46, 0xc0, 0xb3, 0x48, 0xf5, 0x9f, 0x60, 0x78, 0x73, 0x87, 0xa1, 0x81, 0x41, 0x61, 0x07, 0x80, 0x96, 0x84, 0xd7, 0x81, 0xb1, 0x8f, 0x00, 0xb8, 0x80, 0xa5, 0x84, 0x9b, 0x8b, 0xac, 0x83, 0xaf, 0x8b, 0xa4, 0x80, 0xc2, 0x8d, 0x8b, 0x07, 0x81, 0xac, 0x82, 0xb1, 0x00, 0x11, 0x0c, 0x80, 0xab, 0x24, 0x80, 0x40, 0xec, 0x87, 0x60, 0x4f, 0x32, 0x80, 0x48, 0x56, 0x84, 0x46, 0x85, 0x10, 0x0c, 0x83, 0x43, 0x13, 0x83, 0xc0, 0x80, 0x41, 0x40, 0x81, 0xcc, 0x82, 0x41, 0x02, 0x82, 0xb4, 0x8d, 0xac, 0x81, 0x8a, 0x82, 0xac, 0x88, 0x88, 0x80, 0xbc, 0x82, 0xa3, 0x8b, 0x91, 0x81, 0xb8, 0x82, 0xaf, 0x8c, 0x8d, 0x81, 0xdb, 0x88, 0x08, 0x28, 0x08, 0x40, 0x9c, 0x89, 0x96, 0x83, 0xb9, 0x31, 0x09, 0x81, 0x89, 0x80, 0x89, 0x81, 0xd3, 0x88, 0x00, 0x08, 0x03, 0x01, 0xe6, 0x8c, 0x02, 0xe9, 0x91, 0x40, 0xec, 0x31, 0x86, 0x9c, 0x81, 0xd1, 0x8e, 0x00, 0xe9, 0x8a, 0xe6, 0x8d, 0x41, 0x00, 0x8c, 0x40, 0xf6, 0x28, 0x09, 0x0a, 0x00, 0x80, 0x40, 0x8d, 0x31, 0x2b, 0x80, 0x9b, 0x89, 0xa9, 0x20, 0x83, 0x91, 0x8a, 0xad, 0x8d, 0x40, 0xc7, 0x87, 0x40, 0xc6, 0x38, 0x86, 0xd2, 0x95, 0x80, 0x8d, 0xf9, 0x2a, 0x00, 0x08, 0x10, 0x02, 0x80, 0xc1, 0x20, 0x08, 0x83, 0x41, 0x5b, 0x83, 0x88, 0x08, 0x80, 0xaf, 0x32, 0x82, 0x60, 0x41, 0xdc, 0x90, 0x4e, 0x1f, 0x00, 0xb6, 0x33, 0xdc, 0x81, 0x60, 0x4c, 0xab, 0x80, 0x60, 0x23, 0x60, 0x30, 0x90, 0x0e, 0x01, 0x04, 0xe3, 0x80, 0x46, 0x52, 0x01, 0x06, 0x0c, 0x80, 0x42, 0x50, 0x80, 0x47, 0xe7, 0x99, 0x85, 0x99, 0x85, 0x99, }; static const uint8_t unicode_prop_Other_Lowercase_table[68] = { 0x40, 0xa9, 0x80, 0x8e, 0x80, 0x41, 0xf4, 0x88, 0x31, 0x9d, 0x84, 0xdf, 0x80, 0xb3, 0x80, 0x4d, 0x80, 0x80, 0x4c, 0x2e, 0xbe, 0x8c, 0x80, 0xa1, 0xa4, 0x42, 0xb0, 0x80, 0x8c, 0x80, 0x8f, 0x8c, 0x40, 0xd2, 0x8f, 0x43, 0x4f, 0x99, 0x47, 0x91, 0x81, 0x60, 0x7a, 0x1d, 0x81, 0x40, 0xd1, 0x80, 0xff, 0x1a, 0x81, 0x43, 0x61, 0x83, 0x88, 0x80, 0x60, 0x5c, 0x15, 0x01, 0x10, 0xa9, 0x80, 0x88, 0x60, 0xd8, 0x74, 0xbd, }; static const uint8_t unicode_prop_Other_Uppercase_table[15] = { 0x60, 0x21, 0x5f, 0x8f, 0x43, 0x45, 0x99, 0x61, 0xcc, 0x5f, 0x99, 0x85, 0x99, 0x85, 0x99, }; static const uint8_t unicode_prop_Other_Grapheme_Extend_table[112] = { 0x49, 0xbd, 0x80, 0x97, 0x80, 0x41, 0x65, 0x80, 0x97, 0x80, 0xe5, 0x80, 0x97, 0x80, 0x40, 0xe7, 0x00, 0x03, 0x08, 0x81, 0x88, 0x81, 0xe6, 0x80, 0x97, 0x80, 0xf6, 0x80, 0x8e, 0x80, 0x49, 0x34, 0x80, 0x9d, 0x80, 0x43, 0xff, 0x04, 0x00, 0x04, 0x81, 0xe4, 0x80, 0xc6, 0x81, 0x44, 0x17, 0x80, 0x50, 0x20, 0x81, 0x60, 0x79, 0x22, 0x80, 0xeb, 0x80, 0x60, 0x55, 0xdc, 0x81, 0x52, 0x1f, 0x80, 0xf3, 0x80, 0x41, 0x07, 0x80, 0x8d, 0x80, 0x88, 0x80, 0xdf, 0x80, 0x88, 0x01, 0x00, 0x14, 0x80, 0x40, 0xdf, 0x80, 0x8b, 0x80, 0x40, 0xf0, 0x80, 0x41, 0x05, 0x80, 0x42, 0x78, 0x80, 0x8b, 0x80, 0x46, 0x02, 0x80, 0x60, 0x50, 0xad, 0x81, 0x60, 0x61, 0x72, 0x0d, 0x85, 0x6c, 0x2e, 0xac, 0xdf, }; static const uint8_t unicode_prop_Other_Default_Ignorable_Code_Point_table[32] = { 0x43, 0x4e, 0x80, 0x4e, 0x0e, 0x81, 0x46, 0x52, 0x81, 0x48, 0xae, 0x80, 0x50, 0xfd, 0x80, 0x60, 0xce, 0x3a, 0x80, 0xce, 0x88, 0x6d, 0x00, 0x06, 0x00, 0x9d, 0xdf, 0xff, 0x40, 0xef, 0x4e, 0x0f, }; static const uint8_t unicode_prop_Other_ID_Start_table[11] = { 0x58, 0x84, 0x81, 0x48, 0x90, 0x80, 0x94, 0x80, 0x4f, 0x6b, 0x81, }; static const uint8_t unicode_prop_Other_ID_Continue_table[22] = { 0x40, 0xb6, 0x80, 0x42, 0xce, 0x80, 0x4f, 0xe0, 0x88, 0x46, 0x67, 0x80, 0x46, 0x30, 0x81, 0x50, 0xec, 0x80, 0x60, 0xce, 0x68, 0x80, }; static const uint8_t unicode_prop_Prepended_Concatenation_Mark_table[19] = { 0x45, 0xff, 0x85, 0x40, 0xd6, 0x80, 0xb0, 0x80, 0x41, 0x7f, 0x81, 0xcf, 0x80, 0x61, 0x07, 0xd9, 0x80, 0x8e, 0x80, }; static const uint8_t unicode_prop_XID_Start1_table[31] = { 0x43, 0x79, 0x80, 0x4a, 0xb7, 0x80, 0xfe, 0x80, 0x60, 0x21, 0xe6, 0x81, 0x60, 0xcb, 0xc0, 0x85, 0x41, 0x95, 0x81, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41, 0x1e, 0x81, }; static const uint8_t unicode_prop_XID_Continue1_table[23] = { 0x43, 0x79, 0x80, 0x60, 0x2d, 0x1f, 0x81, 0x60, 0xcb, 0xc0, 0x85, 0x41, 0x95, 0x81, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, }; static const uint8_t unicode_prop_Changes_When_Titlecased1_table[22] = { 0x41, 0xc3, 0x08, 0x08, 0x81, 0xa4, 0x81, 0x4e, 0xdc, 0xaa, 0x0a, 0x4e, 0x87, 0x3f, 0x3f, 0x87, 0x8b, 0x80, 0x8e, 0x80, 0xae, 0x80, }; static const uint8_t unicode_prop_Changes_When_Casefolded1_table[29] = { 0x41, 0xef, 0x80, 0x41, 0x9e, 0x80, 0x9e, 0x80, 0x5a, 0xe4, 0x83, 0x40, 0xb5, 0x00, 0x00, 0x00, 0x80, 0xde, 0x06, 0x06, 0x80, 0x8a, 0x09, 0x81, 0x89, 0x10, 0x81, 0x8d, 0x80, }; static const uint8_t unicode_prop_Changes_When_NFKC_Casefolded1_table[449] = { 0x40, 0x9f, 0x06, 0x00, 0x01, 0x00, 0x01, 0x12, 0x10, 0x82, 0xf3, 0x80, 0x8b, 0x80, 0x40, 0x84, 0x01, 0x01, 0x80, 0xa2, 0x01, 0x80, 0x40, 0xbb, 0x88, 0x9e, 0x29, 0x84, 0xda, 0x08, 0x81, 0x89, 0x80, 0xa3, 0x04, 0x02, 0x04, 0x08, 0x07, 0x80, 0x9e, 0x80, 0xa0, 0x82, 0x9c, 0x80, 0x42, 0x28, 0x80, 0xd7, 0x83, 0x42, 0xde, 0x87, 0xfb, 0x08, 0x80, 0xd2, 0x01, 0x80, 0xa1, 0x11, 0x80, 0x40, 0xfc, 0x81, 0x42, 0xd4, 0x80, 0xfe, 0x80, 0xa7, 0x81, 0xad, 0x80, 0xb5, 0x80, 0x88, 0x03, 0x03, 0x03, 0x80, 0x8b, 0x80, 0x88, 0x00, 0x26, 0x80, 0x90, 0x80, 0x88, 0x03, 0x03, 0x03, 0x80, 0x8b, 0x80, 0x41, 0x41, 0x80, 0xe1, 0x81, 0x46, 0x52, 0x81, 0xd4, 0x84, 0x45, 0x1b, 0x10, 0x8a, 0x80, 0x91, 0x80, 0x9b, 0x8c, 0x80, 0xa1, 0xa4, 0x40, 0xd5, 0x83, 0x40, 0xb5, 0x00, 0x00, 0x00, 0x80, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xb7, 0x05, 0x00, 0x13, 0x05, 0x11, 0x02, 0x0c, 0x11, 0x00, 0x00, 0x0c, 0x15, 0x05, 0x08, 0x8f, 0x00, 0x20, 0x8b, 0x12, 0x2a, 0x08, 0x0b, 0x00, 0x07, 0x82, 0x8c, 0x06, 0x92, 0x81, 0x9a, 0x80, 0x8c, 0x8a, 0x80, 0xd6, 0x18, 0x10, 0x8a, 0x01, 0x0c, 0x0a, 0x00, 0x10, 0x11, 0x02, 0x06, 0x05, 0x1c, 0x85, 0x8f, 0x8f, 0x8f, 0x88, 0x80, 0x40, 0xa1, 0x08, 0x81, 0x40, 0xf7, 0x81, 0x41, 0x34, 0xd5, 0x99, 0x9a, 0x45, 0x20, 0x80, 0xe6, 0x82, 0xe4, 0x80, 0x41, 0x9e, 0x81, 0x40, 0xf0, 0x80, 0x41, 0x2e, 0x80, 0xd2, 0x80, 0x8b, 0x40, 0xd5, 0xa9, 0x80, 0xb4, 0x00, 0x82, 0xdf, 0x09, 0x80, 0xde, 0x80, 0xb0, 0xdd, 0x82, 0x8d, 0xdf, 0x9e, 0x80, 0xa7, 0x87, 0xae, 0x80, 0x41, 0x7f, 0x60, 0x72, 0x9b, 0x81, 0x40, 0xd1, 0x80, 0xff, 0x1a, 0x81, 0x43, 0x61, 0x83, 0x88, 0x80, 0x60, 0x4d, 0x95, 0x41, 0x0d, 0x08, 0x00, 0x81, 0x89, 0x00, 0x00, 0x09, 0x82, 0xc3, 0x81, 0xe9, 0xc2, 0x00, 0x97, 0x04, 0x00, 0x01, 0x01, 0x80, 0xeb, 0xa0, 0x41, 0x6a, 0x91, 0xbf, 0x81, 0xb5, 0xa7, 0x8c, 0x82, 0x99, 0x95, 0x94, 0x81, 0x8b, 0x80, 0x92, 0x03, 0x1a, 0x00, 0x80, 0x40, 0x86, 0x08, 0x80, 0x9f, 0x99, 0x40, 0x83, 0x15, 0x0d, 0x0d, 0x0a, 0x16, 0x06, 0x80, 0x88, 0x47, 0x87, 0x20, 0xa9, 0x80, 0x88, 0x60, 0xb4, 0xe4, 0x83, 0x50, 0x31, 0xa3, 0x44, 0x63, 0x86, 0x8d, 0x87, 0xbf, 0x85, 0x42, 0x3e, 0xd4, 0x80, 0xc6, 0x01, 0x08, 0x09, 0x0b, 0x80, 0x8b, 0x00, 0x06, 0x80, 0xc0, 0x03, 0x0f, 0x06, 0x80, 0x9b, 0x03, 0x04, 0x00, 0x16, 0x80, 0x41, 0x53, 0x81, 0x41, 0x23, 0x81, 0xb1, 0x48, 0x2f, 0xbd, 0x4d, 0x91, 0x18, 0x9a, 0x01, 0x00, 0x08, 0x80, 0x89, 0x03, 0x00, 0x00, 0x28, 0x18, 0x00, 0x00, 0x02, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0b, 0x06, 0x03, 0x03, 0x00, 0x80, 0x89, 0x80, 0x90, 0x22, 0x04, 0x80, 0x90, 0x42, 0x43, 0x8a, 0x84, 0x9e, 0x80, 0x9f, 0x99, 0x82, 0xa2, 0x80, 0xee, 0x82, 0x8c, 0xab, 0x83, 0x88, 0x31, 0x49, 0x9d, 0x89, 0x60, 0xfc, 0x05, 0x42, 0x1d, 0x6b, 0x05, 0xe1, 0x4f, 0xff, }; static const uint8_t unicode_prop_Basic_Emoji1_table[144] = { 0x60, 0x23, 0x19, 0x81, 0x40, 0xcc, 0x1a, 0x01, 0x80, 0x42, 0x08, 0x81, 0x94, 0x81, 0xb1, 0x8b, 0xaa, 0x80, 0x92, 0x80, 0x8c, 0x07, 0x81, 0x90, 0x0c, 0x0f, 0x04, 0x80, 0x94, 0x06, 0x08, 0x03, 0x01, 0x06, 0x03, 0x81, 0x9b, 0x80, 0xa2, 0x00, 0x03, 0x10, 0x80, 0xbc, 0x82, 0x97, 0x80, 0x8d, 0x80, 0x43, 0x5a, 0x81, 0xb2, 0x03, 0x80, 0x61, 0xc4, 0xad, 0x80, 0x40, 0xc9, 0x80, 0x40, 0xbd, 0x01, 0x89, 0xe5, 0x80, 0x97, 0x80, 0x93, 0x01, 0x20, 0x82, 0x94, 0x81, 0x40, 0xad, 0xa0, 0x8b, 0x88, 0x80, 0xc5, 0x80, 0x95, 0x8b, 0xaa, 0x1c, 0x8b, 0x90, 0x10, 0x82, 0xc6, 0x00, 0x80, 0x40, 0xba, 0x81, 0xbe, 0x8c, 0x18, 0x97, 0x91, 0x80, 0x99, 0x81, 0x8c, 0x80, 0xd5, 0xd4, 0xaf, 0xc5, 0x28, 0x12, 0x0b, 0x13, 0x8a, 0x0e, 0x88, 0x40, 0xe2, 0x8b, 0x18, 0x41, 0x1a, 0xae, 0x80, 0x89, 0x80, 0x40, 0xb8, 0xef, 0x8c, 0x82, 0x8a, 0x82, 0xb8, 0x00, 0x83, 0x8f, 0x81, 0x8b, 0x83, 0x89, }; static const uint8_t unicode_prop_Basic_Emoji2_table[183] = { 0x40, 0xa8, 0x03, 0x80, 0x5f, 0x8c, 0x80, 0x8b, 0x80, 0x40, 0xd7, 0x80, 0x95, 0x80, 0xd9, 0x85, 0x8e, 0x81, 0x41, 0x7c, 0x80, 0x40, 0xa5, 0x80, 0x9c, 0x10, 0x0c, 0x82, 0x40, 0xc6, 0x80, 0x40, 0xe6, 0x81, 0x89, 0x80, 0x88, 0x80, 0xb9, 0x0a, 0x84, 0x88, 0x01, 0x05, 0x03, 0x01, 0x00, 0x09, 0x02, 0x02, 0x0f, 0x14, 0x00, 0x80, 0x9b, 0x09, 0x00, 0x08, 0x80, 0x91, 0x01, 0x80, 0x92, 0x00, 0x18, 0x00, 0x0a, 0x05, 0x07, 0x81, 0x95, 0x05, 0x00, 0x00, 0x80, 0x94, 0x05, 0x09, 0x01, 0x17, 0x04, 0x09, 0x08, 0x01, 0x00, 0x00, 0x05, 0x02, 0x80, 0x90, 0x81, 0x8e, 0x01, 0x80, 0x9a, 0x81, 0xbb, 0x80, 0x41, 0x91, 0x81, 0x41, 0xce, 0x82, 0x45, 0x27, 0x80, 0x8b, 0x80, 0x42, 0x58, 0x00, 0x80, 0x61, 0xbe, 0xd5, 0x81, 0x8b, 0x81, 0x40, 0x81, 0x80, 0xb3, 0x80, 0x40, 0xe8, 0x01, 0x88, 0x88, 0x80, 0xc5, 0x80, 0x97, 0x08, 0x11, 0x81, 0xaa, 0x1c, 0x8b, 0x92, 0x00, 0x00, 0x80, 0xc6, 0x00, 0x80, 0x40, 0xba, 0x80, 0xca, 0x81, 0xa3, 0x09, 0x86, 0x8c, 0x01, 0x19, 0x80, 0x93, 0x01, 0x07, 0x81, 0x88, 0x04, 0x82, 0x8b, 0x17, 0x11, 0x00, 0x03, 0x05, 0x02, 0x05, 0x80, 0x40, 0xcf, 0x00, 0x82, 0x8f, 0x2a, 0x05, 0x01, 0x80, }; static const uint8_t unicode_prop_RGI_Emoji_Modifier_Sequence_table[72] = { 0x60, 0x26, 0x1c, 0x80, 0x40, 0xda, 0x80, 0x8f, 0x83, 0x61, 0xcc, 0x76, 0x80, 0xbb, 0x11, 0x01, 0x82, 0xf4, 0x09, 0x8a, 0x94, 0x18, 0x8d, 0x10, 0x1a, 0x02, 0x30, 0x00, 0x97, 0x80, 0x40, 0xc8, 0x0b, 0x80, 0x94, 0x03, 0x81, 0x40, 0xad, 0x12, 0x84, 0xd2, 0x80, 0x8f, 0x82, 0x88, 0x80, 0x8a, 0x80, 0x42, 0x3e, 0x01, 0x07, 0x3d, 0x80, 0x88, 0x89, 0x0a, 0xb7, 0x80, 0xbc, 0x08, 0x08, 0x80, 0x90, 0x10, 0x8c, 0x40, 0xe4, 0x82, 0xa9, 0x88, }; static const uint8_t unicode_prop_RGI_Emoji_Flag_Sequence_table[128] = { 0x0c, 0x00, 0x09, 0x00, 0x04, 0x01, 0x02, 0x06, 0x03, 0x03, 0x01, 0x02, 0x01, 0x03, 0x07, 0x0d, 0x18, 0x00, 0x09, 0x00, 0x00, 0x89, 0x08, 0x00, 0x00, 0x81, 0x88, 0x83, 0x8c, 0x10, 0x00, 0x01, 0x07, 0x08, 0x29, 0x10, 0x28, 0x00, 0x80, 0x8a, 0x00, 0x0a, 0x00, 0x0e, 0x15, 0x18, 0x83, 0x89, 0x06, 0x00, 0x81, 0x8d, 0x00, 0x12, 0x08, 0x00, 0x03, 0x00, 0x24, 0x00, 0x05, 0x21, 0x00, 0x00, 0x29, 0x90, 0x00, 0x02, 0x00, 0x08, 0x09, 0x00, 0x08, 0x18, 0x8b, 0x80, 0x8c, 0x02, 0x19, 0x1a, 0x11, 0x00, 0x00, 0x80, 0x9c, 0x80, 0x88, 0x02, 0x00, 0x00, 0x02, 0x20, 0x88, 0x0a, 0x00, 0x03, 0x01, 0x02, 0x05, 0x08, 0x00, 0x01, 0x09, 0x20, 0x21, 0x18, 0x22, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x89, 0x80, 0x8b, 0x80, 0x90, 0x80, 0x92, 0x80, 0x8d, 0x05, 0x80, 0x8a, 0x80, 0x88, 0x80, }; static const uint8_t unicode_prop_Emoji_Keycap_Sequence_table[4] = { 0xa2, 0x05, 0x04, 0x89, }; static const uint8_t unicode_prop_ASCII_Hex_Digit_table[5] = { 0xaf, 0x89, 0x35, 0x99, 0x85, }; static const uint8_t unicode_prop_Bidi_Control_table[10] = { 0x46, 0x1b, 0x80, 0x59, 0xf0, 0x81, 0x99, 0x84, 0xb6, 0x83, }; static const uint8_t unicode_prop_Dash_table[58] = { 0xac, 0x80, 0x45, 0x5b, 0x80, 0xb2, 0x80, 0x4e, 0x40, 0x80, 0x44, 0x04, 0x80, 0x48, 0x08, 0x85, 0xbc, 0x80, 0xa6, 0x80, 0x8e, 0x80, 0x41, 0x85, 0x80, 0x4c, 0x03, 0x01, 0x80, 0x9e, 0x0b, 0x80, 0x9b, 0x80, 0x41, 0xbd, 0x80, 0x92, 0x80, 0xee, 0x80, 0x60, 0xcd, 0x8f, 0x81, 0xa4, 0x80, 0x89, 0x80, 0x40, 0xa8, 0x80, 0x4e, 0x5f, 0x80, 0x41, 0x3d, 0x80, }; static const uint8_t unicode_prop_Deprecated_table[23] = { 0x41, 0x48, 0x80, 0x45, 0x28, 0x80, 0x49, 0x02, 0x00, 0x80, 0x48, 0x28, 0x81, 0x48, 0xc4, 0x85, 0x42, 0xb8, 0x81, 0x6d, 0xdc, 0xd5, 0x80, }; static const uint8_t unicode_prop_Diacritic_table[447] = { 0xdd, 0x00, 0x80, 0xc6, 0x05, 0x03, 0x01, 0x81, 0x41, 0xf6, 0x40, 0x9e, 0x07, 0x25, 0x90, 0x0b, 0x80, 0x88, 0x81, 0x40, 0xfc, 0x84, 0x40, 0xd0, 0x80, 0xb6, 0xac, 0x00, 0x01, 0x01, 0x00, 0x40, 0x82, 0x3b, 0x81, 0x40, 0x85, 0x0b, 0x0a, 0x82, 0xc2, 0x9a, 0xda, 0x8a, 0xb9, 0x8a, 0xa1, 0x81, 0xfd, 0x87, 0xa8, 0x89, 0x8f, 0x9b, 0xbc, 0x80, 0x8f, 0x02, 0x83, 0x9b, 0x80, 0xc9, 0x80, 0x8f, 0x80, 0xed, 0x80, 0x8f, 0x80, 0xed, 0x80, 0x8f, 0x80, 0xae, 0x82, 0xbb, 0x80, 0x8f, 0x06, 0x80, 0xf6, 0x80, 0xed, 0x80, 0x8f, 0x80, 0xed, 0x80, 0x8f, 0x80, 0xec, 0x81, 0x8f, 0x80, 0xfb, 0x80, 0xee, 0x80, 0x8b, 0x28, 0x80, 0xea, 0x80, 0x8c, 0x84, 0xca, 0x81, 0x9a, 0x00, 0x00, 0x03, 0x81, 0xc1, 0x10, 0x81, 0xbd, 0x80, 0xef, 0x00, 0x81, 0xa7, 0x0b, 0x84, 0x98, 0x30, 0x80, 0x89, 0x81, 0x42, 0xc0, 0x82, 0x43, 0xb3, 0x81, 0x9d, 0x80, 0x40, 0x93, 0x8a, 0x88, 0x80, 0x41, 0x5a, 0x82, 0x41, 0x23, 0x80, 0x93, 0x39, 0x80, 0xaf, 0x8e, 0x81, 0x8a, 0x82, 0x8e, 0x81, 0x8b, 0xc7, 0x80, 0x8e, 0x80, 0xa5, 0x88, 0xb5, 0x81, 0xb9, 0x80, 0x8a, 0x81, 0xc1, 0x81, 0xbf, 0x85, 0xd1, 0x98, 0x18, 0x28, 0x0a, 0xb1, 0xbe, 0xaf, 0xa3, 0x84, 0x8b, 0xa4, 0x8a, 0x41, 0xbc, 0x00, 0x82, 0x8a, 0x82, 0x8c, 0x82, 0x8c, 0x82, 0x8c, 0x81, 0x4c, 0xef, 0x82, 0x41, 0x3c, 0x80, 0x41, 0xf9, 0x85, 0xe8, 0x83, 0xde, 0x80, 0x60, 0x75, 0x71, 0x80, 0x8b, 0x08, 0x80, 0x9b, 0x81, 0xd1, 0x81, 0x8d, 0xa1, 0xe5, 0x82, 0xe5, 0x05, 0x81, 0x8b, 0x80, 0xa4, 0x80, 0x40, 0x96, 0x80, 0x9a, 0x91, 0xb8, 0x83, 0xa3, 0x80, 0xde, 0x80, 0x8b, 0x80, 0xa3, 0x80, 0x40, 0x94, 0x82, 0xc0, 0x83, 0xb2, 0x80, 0xe3, 0x84, 0x88, 0x82, 0xff, 0x81, 0x60, 0x4f, 0x2f, 0x80, 0x43, 0x00, 0x8f, 0x41, 0x0d, 0x00, 0x80, 0xae, 0x80, 0xac, 0x81, 0xc2, 0x80, 0x42, 0xfb, 0x80, 0x44, 0x9e, 0x28, 0xa9, 0x80, 0x88, 0x42, 0x7c, 0x13, 0x80, 0x40, 0xa4, 0x81, 0x42, 0x3a, 0x85, 0xa5, 0x80, 0x99, 0x84, 0x41, 0x8b, 0x01, 0x82, 0xc5, 0x8a, 0xb0, 0x83, 0x40, 0xbf, 0x80, 0xa8, 0x80, 0xc7, 0x81, 0xf7, 0x81, 0xbd, 0x80, 0xcb, 0x80, 0x88, 0x82, 0xe7, 0x81, 0x40, 0xb1, 0x81, 0xcf, 0x81, 0x8f, 0x80, 0x97, 0x32, 0x84, 0xd8, 0x10, 0x81, 0x8c, 0x81, 0xde, 0x02, 0x80, 0xfa, 0x81, 0x40, 0xfa, 0x81, 0xfd, 0x80, 0xf5, 0x81, 0xf2, 0x80, 0x41, 0x0c, 0x81, 0x41, 0x01, 0x0b, 0x80, 0x40, 0x9b, 0x80, 0xd2, 0x80, 0x91, 0x80, 0xd0, 0x80, 0x41, 0xa4, 0x80, 0x41, 0x01, 0x00, 0x81, 0xd0, 0x80, 0xc0, 0x80, 0x41, 0x66, 0x81, 0x96, 0x80, 0x54, 0xeb, 0x8e, 0x60, 0x2c, 0xd8, 0x80, 0x49, 0xbf, 0x84, 0xba, 0x86, 0x42, 0x33, 0x81, 0x42, 0x21, 0x90, 0xcf, 0x81, 0x60, 0x3f, 0xfd, 0x18, 0x30, 0x81, 0x5f, 0x00, 0xad, 0x81, 0x96, 0x42, 0x1f, 0x12, 0x2f, 0x39, 0x86, 0x9d, 0x83, 0x4e, 0x81, 0xbd, 0x40, 0xc1, 0x86, 0x41, 0x76, 0x80, 0xbc, 0x83, 0x42, 0xfd, 0x81, 0x42, 0xdf, 0x86, 0xec, 0x10, 0x82, }; static const uint8_t unicode_prop_Extender_table[116] = { 0x40, 0xb6, 0x80, 0x42, 0x17, 0x81, 0x43, 0x6d, 0x80, 0x41, 0xb8, 0x80, 0x42, 0x75, 0x80, 0x40, 0x88, 0x80, 0xd8, 0x80, 0x42, 0xef, 0x80, 0xfe, 0x80, 0x49, 0x42, 0x80, 0xb7, 0x80, 0x42, 0x62, 0x80, 0x41, 0x8d, 0x80, 0xc3, 0x80, 0x53, 0x88, 0x80, 0xaa, 0x84, 0xe6, 0x81, 0xdc, 0x82, 0x60, 0x6f, 0x15, 0x80, 0x45, 0xf5, 0x80, 0x43, 0xc1, 0x80, 0x95, 0x80, 0x40, 0x88, 0x80, 0xeb, 0x80, 0x94, 0x81, 0x60, 0x54, 0x7a, 0x80, 0x48, 0x0f, 0x81, 0x45, 0xca, 0x80, 0x9a, 0x03, 0x80, 0x44, 0xc6, 0x80, 0x41, 0x24, 0x80, 0xf3, 0x81, 0x41, 0xf1, 0x82, 0x44, 0xce, 0x80, 0x43, 0x3f, 0x80, 0x60, 0x4d, 0x67, 0x81, 0x44, 0x9b, 0x08, 0x80, 0x8d, 0x81, 0x60, 0x71, 0x47, 0x81, 0x44, 0xb0, 0x80, 0x43, 0x53, 0x82, }; static const uint8_t unicode_prop_Hex_Digit_table[12] = { 0xaf, 0x89, 0x35, 0x99, 0x85, 0x60, 0xfe, 0xa8, 0x89, 0x35, 0x99, 0x85, }; static const uint8_t unicode_prop_IDS_Unary_Operator_table[4] = { 0x60, 0x2f, 0xfd, 0x81, }; static const uint8_t unicode_prop_IDS_Binary_Operator_table[8] = { 0x60, 0x2f, 0xef, 0x09, 0x89, 0x41, 0xf0, 0x80, }; static const uint8_t unicode_prop_IDS_Trinary_Operator_table[4] = { 0x60, 0x2f, 0xf1, 0x81, }; static const uint8_t unicode_prop_Ideographic_table[71] = { 0x60, 0x30, 0x05, 0x81, 0x98, 0x88, 0x8d, 0x82, 0x43, 0xc4, 0x59, 0xbf, 0xbf, 0x60, 0x51, 0xff, 0x60, 0x58, 0xff, 0x41, 0x6d, 0x81, 0xe9, 0x60, 0x75, 0x09, 0x80, 0x8c, 0x84, 0x88, 0x5c, 0xd5, 0xa8, 0x9f, 0xe0, 0xf2, 0x60, 0x23, 0x7c, 0x41, 0x8b, 0x60, 0x4d, 0x03, 0x60, 0xa6, 0xdf, 0x9f, 0x51, 0x1d, 0x81, 0x56, 0x8d, 0x81, 0x5d, 0x30, 0x8e, 0x42, 0x6d, 0x49, 0xa1, 0x42, 0x1d, 0x45, 0xe1, 0x53, 0x4a, 0x84, 0x60, 0x21, 0x29, }; static const uint8_t unicode_prop_Join_Control_table[4] = { 0x60, 0x20, 0x0b, 0x81, }; static const uint8_t unicode_prop_Logical_Order_Exception_table[15] = { 0x4e, 0x3f, 0x84, 0xfa, 0x84, 0x4a, 0xef, 0x11, 0x80, 0x60, 0x90, 0xf9, 0x09, 0x00, 0x81, }; static const uint8_t unicode_prop_Modifier_Combining_Mark_table[16] = { 0x46, 0x53, 0x09, 0x80, 0x40, 0x82, 0x05, 0x02, 0x81, 0x41, 0xe0, 0x08, 0x12, 0x80, 0x9e, 0x80, }; static const uint8_t unicode_prop_Noncharacter_Code_Point_table[71] = { 0x60, 0xfd, 0xcf, 0x9f, 0x42, 0x0d, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, 0x60, 0xff, 0xfd, 0x81, }; static const uint8_t unicode_prop_Pattern_Syntax_table[58] = { 0xa0, 0x8e, 0x89, 0x86, 0x99, 0x18, 0x80, 0x99, 0x83, 0xa1, 0x30, 0x00, 0x08, 0x00, 0x0b, 0x03, 0x02, 0x80, 0x96, 0x80, 0x9e, 0x80, 0x5f, 0x17, 0x97, 0x87, 0x8e, 0x81, 0x92, 0x80, 0x89, 0x41, 0x30, 0x42, 0xcf, 0x40, 0x9f, 0x42, 0x75, 0x9d, 0x44, 0x6b, 0x41, 0xff, 0xff, 0x41, 0x80, 0x13, 0x98, 0x8e, 0x80, 0x60, 0xcd, 0x0c, 0x81, 0x41, 0x04, 0x81, }; static const uint8_t unicode_prop_Pattern_White_Space_table[11] = { 0x88, 0x84, 0x91, 0x80, 0xe3, 0x80, 0x5f, 0x87, 0x81, 0x97, 0x81, }; static const uint8_t unicode_prop_Quotation_Mark_table[31] = { 0xa1, 0x03, 0x80, 0x40, 0x82, 0x80, 0x8e, 0x80, 0x5f, 0x5b, 0x87, 0x98, 0x81, 0x4e, 0x06, 0x80, 0x41, 0xc8, 0x83, 0x8c, 0x82, 0x60, 0xce, 0x20, 0x83, 0x40, 0xbc, 0x03, 0x80, 0xd9, 0x81, }; static const uint8_t unicode_prop_Radical_table[9] = { 0x60, 0x2e, 0x7f, 0x99, 0x80, 0xd8, 0x8b, 0x40, 0xd5, }; static const uint8_t unicode_prop_Regional_Indicator_table[4] = { 0x61, 0xf1, 0xe5, 0x99, }; static const uint8_t unicode_prop_Sentence_Terminal_table[213] = { 0xa0, 0x80, 0x8b, 0x80, 0x8f, 0x80, 0x45, 0x48, 0x80, 0x40, 0x92, 0x82, 0x40, 0xb3, 0x80, 0xaa, 0x82, 0x40, 0xf5, 0x80, 0xbc, 0x00, 0x02, 0x81, 0x41, 0x24, 0x81, 0x46, 0xe3, 0x81, 0x43, 0x15, 0x03, 0x81, 0x43, 0x04, 0x80, 0x40, 0xc5, 0x81, 0x40, 0x9c, 0x81, 0xac, 0x04, 0x80, 0x41, 0x39, 0x81, 0x41, 0x61, 0x83, 0x40, 0xa1, 0x81, 0x89, 0x09, 0x81, 0x9c, 0x82, 0x40, 0xba, 0x81, 0xc0, 0x81, 0x43, 0xa3, 0x80, 0x96, 0x81, 0x88, 0x82, 0x4c, 0xae, 0x82, 0x41, 0x31, 0x80, 0x8c, 0x80, 0x95, 0x81, 0x41, 0xac, 0x80, 0x60, 0x74, 0xfb, 0x80, 0x41, 0x0d, 0x81, 0x40, 0xe2, 0x02, 0x80, 0x41, 0x7d, 0x81, 0xd5, 0x81, 0xde, 0x80, 0x40, 0x97, 0x81, 0x40, 0x92, 0x82, 0x40, 0x8f, 0x81, 0x40, 0xf8, 0x80, 0x60, 0x52, 0x25, 0x01, 0x81, 0xba, 0x02, 0x81, 0x40, 0xa8, 0x80, 0x8b, 0x80, 0x8f, 0x80, 0xc0, 0x80, 0x4a, 0xf3, 0x81, 0x44, 0xfc, 0x84, 0xab, 0x83, 0x40, 0xbc, 0x81, 0xf4, 0x83, 0xfe, 0x82, 0x40, 0x80, 0x0d, 0x80, 0x8f, 0x81, 0xd7, 0x08, 0x81, 0xeb, 0x80, 0x41, 0x29, 0x81, 0xf4, 0x81, 0x41, 0x74, 0x0c, 0x8e, 0xe8, 0x81, 0x40, 0xf8, 0x82, 0x42, 0x04, 0x00, 0x80, 0x40, 0xfa, 0x81, 0xd6, 0x81, 0x41, 0xa3, 0x81, 0x42, 0xb3, 0x81, 0xc9, 0x81, 0x60, 0x4b, 0x28, 0x81, 0x40, 0x84, 0x80, 0xc0, 0x81, 0x8a, 0x80, 0x42, 0x28, 0x81, 0x41, 0x27, 0x80, 0x60, 0x4e, 0x05, 0x80, 0x5d, 0xe7, 0x80, }; static const uint8_t unicode_prop_Soft_Dotted_table[79] = { 0xe8, 0x81, 0x40, 0xc3, 0x80, 0x41, 0x18, 0x80, 0x9d, 0x80, 0xb3, 0x80, 0x93, 0x80, 0x41, 0x3f, 0x80, 0xe1, 0x00, 0x80, 0x59, 0x08, 0x80, 0xb2, 0x80, 0x8c, 0x02, 0x80, 0x40, 0x83, 0x80, 0x40, 0x9c, 0x80, 0x41, 0xa4, 0x80, 0x40, 0xd5, 0x81, 0x4b, 0x31, 0x80, 0x61, 0xa7, 0xa4, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0x48, 0x85, 0x80, 0x41, 0x30, 0x81, 0x99, 0x80, }; static const uint8_t unicode_prop_Terminal_Punctuation_table[264] = { 0xa0, 0x80, 0x89, 0x00, 0x80, 0x8a, 0x0a, 0x80, 0x43, 0x3d, 0x07, 0x80, 0x42, 0x00, 0x80, 0xb8, 0x80, 0xc7, 0x80, 0x8d, 0x00, 0x82, 0x40, 0xb3, 0x80, 0xaa, 0x8a, 0x00, 0x40, 0xea, 0x81, 0xb5, 0x28, 0x87, 0x9e, 0x80, 0x41, 0x04, 0x81, 0x44, 0xf3, 0x81, 0x40, 0xab, 0x03, 0x85, 0x41, 0x36, 0x81, 0x43, 0x14, 0x87, 0x43, 0x04, 0x80, 0xfb, 0x82, 0xc6, 0x81, 0x40, 0x9c, 0x12, 0x80, 0xa6, 0x19, 0x81, 0x41, 0x39, 0x81, 0x41, 0x61, 0x83, 0x40, 0xa1, 0x81, 0x89, 0x08, 0x82, 0x9c, 0x82, 0x40, 0xba, 0x84, 0xbd, 0x81, 0x43, 0xa3, 0x80, 0x96, 0x81, 0x88, 0x82, 0x4c, 0xae, 0x82, 0x41, 0x31, 0x80, 0x8c, 0x03, 0x80, 0x89, 0x00, 0x0a, 0x81, 0x41, 0xab, 0x81, 0x60, 0x74, 0xfa, 0x81, 0x41, 0x0c, 0x82, 0x40, 0xe2, 0x84, 0x41, 0x7d, 0x81, 0xd5, 0x81, 0xde, 0x80, 0x40, 0x96, 0x82, 0x40, 0x92, 0x82, 0xfe, 0x80, 0x8f, 0x81, 0x40, 0xf8, 0x80, 0x60, 0x52, 0x25, 0x01, 0x81, 0xb8, 0x10, 0x83, 0x40, 0xa8, 0x80, 0x89, 0x00, 0x80, 0x8a, 0x0a, 0x80, 0xc0, 0x01, 0x80, 0x44, 0x39, 0x80, 0xaf, 0x80, 0x44, 0x85, 0x80, 0x40, 0xc6, 0x80, 0x41, 0x35, 0x81, 0x40, 0x97, 0x85, 0xc3, 0x85, 0xd8, 0x83, 0x43, 0xb7, 0x84, 0xab, 0x83, 0x40, 0xbc, 0x86, 0xef, 0x83, 0xfe, 0x82, 0x40, 0x80, 0x0d, 0x80, 0x8f, 0x81, 0xd7, 0x84, 0xeb, 0x80, 0x41, 0x29, 0x81, 0xf4, 0x82, 0x8b, 0x81, 0x41, 0x65, 0x1a, 0x8e, 0xe8, 0x81, 0x40, 0xf8, 0x82, 0x42, 0x04, 0x00, 0x80, 0x40, 0xfa, 0x81, 0xd6, 0x0b, 0x81, 0x41, 0x9d, 0x82, 0xac, 0x80, 0x42, 0x84, 0x81, 0xc9, 0x81, 0x45, 0x2a, 0x84, 0x60, 0x45, 0xf8, 0x81, 0x40, 0x84, 0x80, 0xc0, 0x82, 0x89, 0x80, 0x42, 0x28, 0x81, 0x41, 0x26, 0x81, 0x60, 0x4e, 0x05, 0x80, 0x5d, 0xe6, 0x83, }; static const uint8_t unicode_prop_Unified_Ideograph_table[46] = { 0x60, 0x33, 0xff, 0x59, 0xbf, 0xbf, 0x60, 0x51, 0xff, 0x60, 0x5a, 0x0d, 0x08, 0x00, 0x81, 0x89, 0x00, 0x00, 0x09, 0x82, 0x61, 0x05, 0xd5, 0x60, 0xa6, 0xdf, 0x9f, 0x51, 0x1d, 0x81, 0x56, 0x8d, 0x81, 0x5d, 0x30, 0x8e, 0x42, 0x6d, 0x51, 0xa1, 0x53, 0x4a, 0x84, 0x60, 0x21, 0x29, }; static const uint8_t unicode_prop_Variation_Selector_table[13] = { 0x58, 0x0a, 0x10, 0x80, 0x60, 0xe5, 0xef, 0x8f, 0x6d, 0x02, 0xef, 0x40, 0xef, }; static const uint8_t unicode_prop_White_Space_table[22] = { 0x88, 0x84, 0x91, 0x80, 0xe3, 0x80, 0x99, 0x80, 0x55, 0xde, 0x80, 0x49, 0x7e, 0x8a, 0x9c, 0x0c, 0x80, 0xae, 0x80, 0x4f, 0x9f, 0x80, }; static const uint8_t unicode_prop_Bidi_Mirrored_table[173] = { 0xa7, 0x81, 0x91, 0x00, 0x80, 0x9b, 0x00, 0x80, 0x9c, 0x00, 0x80, 0xac, 0x80, 0x8e, 0x80, 0x4e, 0x7d, 0x83, 0x47, 0x5c, 0x81, 0x49, 0x9b, 0x81, 0x89, 0x81, 0xb5, 0x81, 0x8d, 0x81, 0x40, 0xb0, 0x80, 0x40, 0xbf, 0x1a, 0x2a, 0x02, 0x0a, 0x18, 0x18, 0x00, 0x03, 0x88, 0x20, 0x80, 0x91, 0x23, 0x88, 0x08, 0x00, 0x38, 0x9f, 0x0b, 0x20, 0x88, 0x09, 0x92, 0x21, 0x88, 0x21, 0x0b, 0x97, 0x81, 0x8f, 0x3b, 0x93, 0x0e, 0x81, 0x44, 0x3c, 0x8d, 0xc9, 0x01, 0x18, 0x08, 0x14, 0x1c, 0x12, 0x8d, 0x41, 0x92, 0x95, 0x0d, 0x80, 0x8d, 0x38, 0x35, 0x10, 0x1c, 0x01, 0x0c, 0x18, 0x02, 0x09, 0x89, 0x29, 0x81, 0x8b, 0x92, 0x03, 0x08, 0x00, 0x08, 0x03, 0x21, 0x2a, 0x97, 0x81, 0x8a, 0x0b, 0x18, 0x09, 0x0b, 0xaa, 0x0f, 0x80, 0xa7, 0x20, 0x00, 0x14, 0x22, 0x18, 0x14, 0x00, 0x40, 0xff, 0x80, 0x42, 0x02, 0x1a, 0x08, 0x81, 0x8d, 0x09, 0x89, 0xaa, 0x87, 0x41, 0xaa, 0x89, 0x0f, 0x60, 0xce, 0x3c, 0x2c, 0x81, 0x40, 0xa1, 0x81, 0x91, 0x00, 0x80, 0x9b, 0x00, 0x80, 0x9c, 0x00, 0x00, 0x08, 0x81, 0x60, 0xd7, 0x76, 0x80, 0xb8, 0x80, 0xb8, 0x80, 0xb8, 0x80, 0xb8, 0x80, }; static const uint8_t unicode_prop_Emoji_table[239] = { 0xa2, 0x05, 0x04, 0x89, 0xee, 0x03, 0x80, 0x5f, 0x8c, 0x80, 0x8b, 0x80, 0x40, 0xd7, 0x80, 0x95, 0x80, 0xd9, 0x85, 0x8e, 0x81, 0x41, 0x6e, 0x81, 0x8b, 0x80, 0x40, 0xa5, 0x80, 0x98, 0x8a, 0x1a, 0x40, 0xc6, 0x80, 0x40, 0xe6, 0x81, 0x89, 0x80, 0x88, 0x80, 0xb9, 0x18, 0x84, 0x88, 0x01, 0x01, 0x09, 0x03, 0x01, 0x00, 0x09, 0x02, 0x02, 0x0f, 0x14, 0x00, 0x04, 0x8b, 0x8a, 0x09, 0x00, 0x08, 0x80, 0x91, 0x01, 0x81, 0x91, 0x28, 0x00, 0x0a, 0x0c, 0x01, 0x0b, 0x81, 0x8a, 0x0c, 0x09, 0x04, 0x08, 0x00, 0x81, 0x93, 0x0c, 0x28, 0x19, 0x03, 0x01, 0x01, 0x28, 0x01, 0x00, 0x00, 0x05, 0x02, 0x05, 0x80, 0x89, 0x81, 0x8e, 0x01, 0x03, 0x00, 0x03, 0x10, 0x80, 0x8a, 0x81, 0xaf, 0x82, 0x88, 0x80, 0x8d, 0x80, 0x8d, 0x80, 0x41, 0x73, 0x81, 0x41, 0xce, 0x82, 0x92, 0x81, 0xb2, 0x03, 0x80, 0x44, 0xd9, 0x80, 0x8b, 0x80, 0x42, 0x58, 0x00, 0x80, 0x61, 0xbd, 0x69, 0x80, 0x40, 0xc9, 0x80, 0x40, 0x9f, 0x81, 0x8b, 0x81, 0x8d, 0x01, 0x89, 0xca, 0x99, 0x01, 0x96, 0x80, 0x93, 0x01, 0x88, 0x94, 0x81, 0x40, 0xad, 0xa1, 0x81, 0xef, 0x09, 0x02, 0x81, 0xd2, 0x0a, 0x80, 0x41, 0x06, 0x80, 0xbe, 0x8a, 0x28, 0x97, 0x31, 0x0f, 0x8b, 0x01, 0x19, 0x03, 0x81, 0x8c, 0x09, 0x07, 0x81, 0x88, 0x04, 0x82, 0x8b, 0x17, 0x11, 0x00, 0x03, 0x05, 0x02, 0x05, 0xd5, 0xaf, 0xc5, 0x27, 0x0b, 0x82, 0x89, 0x10, 0x01, 0x10, 0x81, 0x89, 0x40, 0xe2, 0x8b, 0x18, 0x41, 0x1a, 0xae, 0x80, 0x89, 0x80, 0x40, 0xb8, 0xef, 0x8c, 0x82, 0x8a, 0x82, 0xb8, 0x00, 0x83, 0x8f, 0x81, 0x8b, 0x83, 0x89, }; static const uint8_t unicode_prop_Emoji_Component_table[28] = { 0xa2, 0x05, 0x04, 0x89, 0x5f, 0xd2, 0x80, 0x40, 0xd4, 0x80, 0x60, 0xdd, 0x2a, 0x80, 0x60, 0xf3, 0xd5, 0x99, 0x41, 0xfa, 0x84, 0x45, 0xaf, 0x83, 0x6c, 0x06, 0x6b, 0xdf, }; static const uint8_t unicode_prop_Emoji_Modifier_table[4] = { 0x61, 0xf3, 0xfa, 0x84, }; static const uint8_t unicode_prop_Emoji_Modifier_Base_table[71] = { 0x60, 0x26, 0x1c, 0x80, 0x40, 0xda, 0x80, 0x8f, 0x83, 0x61, 0xcc, 0x76, 0x80, 0xbb, 0x11, 0x01, 0x82, 0xf4, 0x09, 0x8a, 0x94, 0x92, 0x10, 0x1a, 0x02, 0x30, 0x00, 0x97, 0x80, 0x40, 0xc8, 0x0b, 0x80, 0x94, 0x03, 0x81, 0x40, 0xad, 0x12, 0x84, 0xd2, 0x80, 0x8f, 0x82, 0x88, 0x80, 0x8a, 0x80, 0x42, 0x3e, 0x01, 0x07, 0x3d, 0x80, 0x88, 0x89, 0x0a, 0xb7, 0x80, 0xbc, 0x08, 0x08, 0x80, 0x90, 0x10, 0x8c, 0x40, 0xe4, 0x82, 0xa9, 0x88, }; static const uint8_t unicode_prop_Emoji_Presentation_table[145] = { 0x60, 0x23, 0x19, 0x81, 0x40, 0xcc, 0x1a, 0x01, 0x80, 0x42, 0x08, 0x81, 0x94, 0x81, 0xb1, 0x8b, 0xaa, 0x80, 0x92, 0x80, 0x8c, 0x07, 0x81, 0x90, 0x0c, 0x0f, 0x04, 0x80, 0x94, 0x06, 0x08, 0x03, 0x01, 0x06, 0x03, 0x81, 0x9b, 0x80, 0xa2, 0x00, 0x03, 0x10, 0x80, 0xbc, 0x82, 0x97, 0x80, 0x8d, 0x80, 0x43, 0x5a, 0x81, 0xb2, 0x03, 0x80, 0x61, 0xc4, 0xad, 0x80, 0x40, 0xc9, 0x80, 0x40, 0xbd, 0x01, 0x89, 0xca, 0x99, 0x00, 0x97, 0x80, 0x93, 0x01, 0x20, 0x82, 0x94, 0x81, 0x40, 0xad, 0xa0, 0x8b, 0x88, 0x80, 0xc5, 0x80, 0x95, 0x8b, 0xaa, 0x1c, 0x8b, 0x90, 0x10, 0x82, 0xc6, 0x00, 0x80, 0x40, 0xba, 0x81, 0xbe, 0x8c, 0x18, 0x97, 0x91, 0x80, 0x99, 0x81, 0x8c, 0x80, 0xd5, 0xd4, 0xaf, 0xc5, 0x28, 0x12, 0x0b, 0x13, 0x8a, 0x0e, 0x88, 0x40, 0xe2, 0x8b, 0x18, 0x41, 0x1a, 0xae, 0x80, 0x89, 0x80, 0x40, 0xb8, 0xef, 0x8c, 0x82, 0x8a, 0x82, 0xb8, 0x00, 0x83, 0x8f, 0x81, 0x8b, 0x83, 0x89, }; static const uint8_t unicode_prop_Extended_Pictographic_table[254] = { 0x40, 0xa8, 0x03, 0x80, 0x5f, 0x8c, 0x80, 0x8b, 0x80, 0x40, 0xd7, 0x80, 0x95, 0x80, 0xd9, 0x85, 0x8e, 0x81, 0x41, 0x6e, 0x81, 0x8b, 0x80, 0x40, 0xa5, 0x80, 0x98, 0x8a, 0x1a, 0x40, 0xc6, 0x80, 0x40, 0xe6, 0x81, 0x89, 0x80, 0x88, 0x80, 0xb9, 0x18, 0x84, 0x88, 0x01, 0x01, 0x09, 0x03, 0x01, 0x00, 0x09, 0x02, 0x02, 0x0f, 0x14, 0x00, 0x04, 0x8b, 0x8a, 0x09, 0x00, 0x08, 0x80, 0x91, 0x01, 0x81, 0x91, 0x28, 0x00, 0x0a, 0x0c, 0x01, 0x0b, 0x81, 0x8a, 0x0c, 0x09, 0x04, 0x08, 0x00, 0x81, 0x93, 0x0c, 0x28, 0x19, 0x03, 0x01, 0x01, 0x28, 0x01, 0x00, 0x00, 0x05, 0x02, 0x05, 0x80, 0x89, 0x81, 0x8e, 0x01, 0x03, 0x00, 0x03, 0x10, 0x80, 0x8a, 0x81, 0xaf, 0x82, 0x88, 0x80, 0x8d, 0x80, 0x8d, 0x80, 0x41, 0x73, 0x81, 0x41, 0xce, 0x82, 0x92, 0x81, 0xb2, 0x03, 0x80, 0x44, 0xd9, 0x80, 0x8b, 0x80, 0x42, 0x58, 0x00, 0x80, 0x61, 0xbd, 0x69, 0x80, 0xa6, 0x83, 0xe3, 0x8b, 0x8e, 0x81, 0x8e, 0x80, 0x8d, 0x81, 0xa4, 0x89, 0xef, 0x81, 0x8b, 0x81, 0x8d, 0x01, 0x89, 0x92, 0xb7, 0x9a, 0x8e, 0x89, 0x80, 0x93, 0x01, 0x88, 0x03, 0x88, 0x96, 0x85, 0x40, 0xbb, 0x81, 0xef, 0x09, 0x02, 0x81, 0xd2, 0x0a, 0x03, 0x84, 0x40, 0xfd, 0x80, 0xbe, 0x8a, 0x28, 0x97, 0x31, 0x0f, 0x8b, 0x01, 0x19, 0x03, 0x81, 0x8c, 0x09, 0x07, 0x81, 0x88, 0x04, 0x82, 0x8b, 0x17, 0x11, 0x00, 0x03, 0x05, 0x02, 0x05, 0xd5, 0xaf, 0xc5, 0x27, 0x81, 0x90, 0x10, 0x05, 0x81, 0x8c, 0x40, 0xd9, 0xa5, 0x8b, 0x83, 0xb7, 0x87, 0x89, 0x85, 0xa7, 0x87, 0x9d, 0x81, 0x8b, 0x19, 0x8d, 0x88, 0xa6, 0x8b, 0xae, 0x80, 0x89, 0x80, 0x40, 0xb8, 0xd7, 0x87, 0x8d, 0x40, 0x91, 0x40, 0xff, 0x43, 0xfd, }; static const uint8_t unicode_prop_Default_Ignorable_Code_Point_table[51] = { 0x40, 0xac, 0x80, 0x42, 0xa0, 0x80, 0x42, 0xcb, 0x80, 0x4b, 0x41, 0x81, 0x46, 0x52, 0x81, 0xd4, 0x84, 0x47, 0xfa, 0x84, 0x99, 0x84, 0xb0, 0x8f, 0x50, 0xf3, 0x80, 0x60, 0xcc, 0x9a, 0x8f, 0x40, 0xee, 0x80, 0x40, 0x9f, 0x80, 0xce, 0x88, 0x60, 0xbc, 0xa6, 0x83, 0x54, 0xce, 0x87, 0x6c, 0x2e, 0x84, 0x4f, 0xff, }; typedef enum { UNICODE_PROP_Hyphen, UNICODE_PROP_Other_Math, UNICODE_PROP_Other_Alphabetic, UNICODE_PROP_Other_Lowercase, UNICODE_PROP_Other_Uppercase, UNICODE_PROP_Other_Grapheme_Extend, UNICODE_PROP_Other_Default_Ignorable_Code_Point, UNICODE_PROP_Other_ID_Start, UNICODE_PROP_Other_ID_Continue, UNICODE_PROP_Prepended_Concatenation_Mark, UNICODE_PROP_ID_Continue1, UNICODE_PROP_XID_Start1, UNICODE_PROP_XID_Continue1, UNICODE_PROP_Changes_When_Titlecased1, UNICODE_PROP_Changes_When_Casefolded1, UNICODE_PROP_Changes_When_NFKC_Casefolded1, UNICODE_PROP_Basic_Emoji1, UNICODE_PROP_Basic_Emoji2, UNICODE_PROP_RGI_Emoji_Modifier_Sequence, UNICODE_PROP_RGI_Emoji_Flag_Sequence, UNICODE_PROP_Emoji_Keycap_Sequence, UNICODE_PROP_ASCII_Hex_Digit, UNICODE_PROP_Bidi_Control, UNICODE_PROP_Dash, UNICODE_PROP_Deprecated, UNICODE_PROP_Diacritic, UNICODE_PROP_Extender, UNICODE_PROP_Hex_Digit, UNICODE_PROP_IDS_Unary_Operator, UNICODE_PROP_IDS_Binary_Operator, UNICODE_PROP_IDS_Trinary_Operator, UNICODE_PROP_Ideographic, UNICODE_PROP_Join_Control, UNICODE_PROP_Logical_Order_Exception, UNICODE_PROP_Modifier_Combining_Mark, UNICODE_PROP_Noncharacter_Code_Point, UNICODE_PROP_Pattern_Syntax, UNICODE_PROP_Pattern_White_Space, UNICODE_PROP_Quotation_Mark, UNICODE_PROP_Radical, UNICODE_PROP_Regional_Indicator, UNICODE_PROP_Sentence_Terminal, UNICODE_PROP_Soft_Dotted, UNICODE_PROP_Terminal_Punctuation, UNICODE_PROP_Unified_Ideograph, UNICODE_PROP_Variation_Selector, UNICODE_PROP_White_Space, UNICODE_PROP_Bidi_Mirrored, UNICODE_PROP_Emoji, UNICODE_PROP_Emoji_Component, UNICODE_PROP_Emoji_Modifier, UNICODE_PROP_Emoji_Modifier_Base, UNICODE_PROP_Emoji_Presentation, UNICODE_PROP_Extended_Pictographic, UNICODE_PROP_Default_Ignorable_Code_Point, UNICODE_PROP_ID_Start, UNICODE_PROP_Case_Ignorable, UNICODE_PROP_ASCII, UNICODE_PROP_Alphabetic, UNICODE_PROP_Any, UNICODE_PROP_Assigned, UNICODE_PROP_Cased, UNICODE_PROP_Changes_When_Casefolded, UNICODE_PROP_Changes_When_Casemapped, UNICODE_PROP_Changes_When_Lowercased, UNICODE_PROP_Changes_When_NFKC_Casefolded, UNICODE_PROP_Changes_When_Titlecased, UNICODE_PROP_Changes_When_Uppercased, UNICODE_PROP_Grapheme_Base, UNICODE_PROP_Grapheme_Extend, UNICODE_PROP_ID_Continue, UNICODE_PROP_ID_Compat_Math_Start, UNICODE_PROP_ID_Compat_Math_Continue, UNICODE_PROP_InCB, UNICODE_PROP_Lowercase, UNICODE_PROP_Math, UNICODE_PROP_Uppercase, UNICODE_PROP_XID_Continue, UNICODE_PROP_XID_Start, UNICODE_PROP_Cased1, UNICODE_PROP_COUNT, } UnicodePropertyEnum; static const char unicode_prop_name_table[] = "ASCII_Hex_Digit,AHex" "\0" "Bidi_Control,Bidi_C" "\0" "Dash" "\0" "Deprecated,Dep" "\0" "Diacritic,Dia" "\0" "Extender,Ext" "\0" "Hex_Digit,Hex" "\0" "IDS_Unary_Operator,IDSU" "\0" "IDS_Binary_Operator,IDSB" "\0" "IDS_Trinary_Operator,IDST" "\0" "Ideographic,Ideo" "\0" "Join_Control,Join_C" "\0" "Logical_Order_Exception,LOE" "\0" "Modifier_Combining_Mark,MCM" "\0" "Noncharacter_Code_Point,NChar" "\0" "Pattern_Syntax,Pat_Syn" "\0" "Pattern_White_Space,Pat_WS" "\0" "Quotation_Mark,QMark" "\0" "Radical" "\0" "Regional_Indicator,RI" "\0" "Sentence_Terminal,STerm" "\0" "Soft_Dotted,SD" "\0" "Terminal_Punctuation,Term" "\0" "Unified_Ideograph,UIdeo" "\0" "Variation_Selector,VS" "\0" "White_Space,space" "\0" "Bidi_Mirrored,Bidi_M" "\0" "Emoji" "\0" "Emoji_Component,EComp" "\0" "Emoji_Modifier,EMod" "\0" "Emoji_Modifier_Base,EBase" "\0" "Emoji_Presentation,EPres" "\0" "Extended_Pictographic,ExtPict" "\0" "Default_Ignorable_Code_Point,DI" "\0" "ID_Start,IDS" "\0" "Case_Ignorable,CI" "\0" "ASCII" "\0" "Alphabetic,Alpha" "\0" "Any" "\0" "Assigned" "\0" "Cased" "\0" "Changes_When_Casefolded,CWCF" "\0" "Changes_When_Casemapped,CWCM" "\0" "Changes_When_Lowercased,CWL" "\0" "Changes_When_NFKC_Casefolded,CWKCF" "\0" "Changes_When_Titlecased,CWT" "\0" "Changes_When_Uppercased,CWU" "\0" "Grapheme_Base,Gr_Base" "\0" "Grapheme_Extend,Gr_Ext" "\0" "ID_Continue,IDC" "\0" "ID_Compat_Math_Start" "\0" "ID_Compat_Math_Continue" "\0" "InCB" "\0" "Lowercase,Lower" "\0" "Math" "\0" "Uppercase,Upper" "\0" "XID_Continue,XIDC" "\0" "XID_Start,XIDS" "\0" ; static const uint8_t * const unicode_prop_table[] = { unicode_prop_Hyphen_table, unicode_prop_Other_Math_table, unicode_prop_Other_Alphabetic_table, unicode_prop_Other_Lowercase_table, unicode_prop_Other_Uppercase_table, unicode_prop_Other_Grapheme_Extend_table, unicode_prop_Other_Default_Ignorable_Code_Point_table, unicode_prop_Other_ID_Start_table, unicode_prop_Other_ID_Continue_table, unicode_prop_Prepended_Concatenation_Mark_table, unicode_prop_ID_Continue1_table, unicode_prop_XID_Start1_table, unicode_prop_XID_Continue1_table, unicode_prop_Changes_When_Titlecased1_table, unicode_prop_Changes_When_Casefolded1_table, unicode_prop_Changes_When_NFKC_Casefolded1_table, unicode_prop_Basic_Emoji1_table, unicode_prop_Basic_Emoji2_table, unicode_prop_RGI_Emoji_Modifier_Sequence_table, unicode_prop_RGI_Emoji_Flag_Sequence_table, unicode_prop_Emoji_Keycap_Sequence_table, unicode_prop_ASCII_Hex_Digit_table, unicode_prop_Bidi_Control_table, unicode_prop_Dash_table, unicode_prop_Deprecated_table, unicode_prop_Diacritic_table, unicode_prop_Extender_table, unicode_prop_Hex_Digit_table, unicode_prop_IDS_Unary_Operator_table, unicode_prop_IDS_Binary_Operator_table, unicode_prop_IDS_Trinary_Operator_table, unicode_prop_Ideographic_table, unicode_prop_Join_Control_table, unicode_prop_Logical_Order_Exception_table, unicode_prop_Modifier_Combining_Mark_table, unicode_prop_Noncharacter_Code_Point_table, unicode_prop_Pattern_Syntax_table, unicode_prop_Pattern_White_Space_table, unicode_prop_Quotation_Mark_table, unicode_prop_Radical_table, unicode_prop_Regional_Indicator_table, unicode_prop_Sentence_Terminal_table, unicode_prop_Soft_Dotted_table, unicode_prop_Terminal_Punctuation_table, unicode_prop_Unified_Ideograph_table, unicode_prop_Variation_Selector_table, unicode_prop_White_Space_table, unicode_prop_Bidi_Mirrored_table, unicode_prop_Emoji_table, unicode_prop_Emoji_Component_table, unicode_prop_Emoji_Modifier_table, unicode_prop_Emoji_Modifier_Base_table, unicode_prop_Emoji_Presentation_table, unicode_prop_Extended_Pictographic_table, unicode_prop_Default_Ignorable_Code_Point_table, unicode_prop_ID_Start_table, unicode_prop_Case_Ignorable_table, }; static const uint16_t unicode_prop_len_table[] = { countof(unicode_prop_Hyphen_table), countof(unicode_prop_Other_Math_table), countof(unicode_prop_Other_Alphabetic_table), countof(unicode_prop_Other_Lowercase_table), countof(unicode_prop_Other_Uppercase_table), countof(unicode_prop_Other_Grapheme_Extend_table), countof(unicode_prop_Other_Default_Ignorable_Code_Point_table), countof(unicode_prop_Other_ID_Start_table), countof(unicode_prop_Other_ID_Continue_table), countof(unicode_prop_Prepended_Concatenation_Mark_table), countof(unicode_prop_ID_Continue1_table), countof(unicode_prop_XID_Start1_table), countof(unicode_prop_XID_Continue1_table), countof(unicode_prop_Changes_When_Titlecased1_table), countof(unicode_prop_Changes_When_Casefolded1_table), countof(unicode_prop_Changes_When_NFKC_Casefolded1_table), countof(unicode_prop_Basic_Emoji1_table), countof(unicode_prop_Basic_Emoji2_table), countof(unicode_prop_RGI_Emoji_Modifier_Sequence_table), countof(unicode_prop_RGI_Emoji_Flag_Sequence_table), countof(unicode_prop_Emoji_Keycap_Sequence_table), countof(unicode_prop_ASCII_Hex_Digit_table), countof(unicode_prop_Bidi_Control_table), countof(unicode_prop_Dash_table), countof(unicode_prop_Deprecated_table), countof(unicode_prop_Diacritic_table), countof(unicode_prop_Extender_table), countof(unicode_prop_Hex_Digit_table), countof(unicode_prop_IDS_Unary_Operator_table), countof(unicode_prop_IDS_Binary_Operator_table), countof(unicode_prop_IDS_Trinary_Operator_table), countof(unicode_prop_Ideographic_table), countof(unicode_prop_Join_Control_table), countof(unicode_prop_Logical_Order_Exception_table), countof(unicode_prop_Modifier_Combining_Mark_table), countof(unicode_prop_Noncharacter_Code_Point_table), countof(unicode_prop_Pattern_Syntax_table), countof(unicode_prop_Pattern_White_Space_table), countof(unicode_prop_Quotation_Mark_table), countof(unicode_prop_Radical_table), countof(unicode_prop_Regional_Indicator_table), countof(unicode_prop_Sentence_Terminal_table), countof(unicode_prop_Soft_Dotted_table), countof(unicode_prop_Terminal_Punctuation_table), countof(unicode_prop_Unified_Ideograph_table), countof(unicode_prop_Variation_Selector_table), countof(unicode_prop_White_Space_table), countof(unicode_prop_Bidi_Mirrored_table), countof(unicode_prop_Emoji_table), countof(unicode_prop_Emoji_Component_table), countof(unicode_prop_Emoji_Modifier_table), countof(unicode_prop_Emoji_Modifier_Base_table), countof(unicode_prop_Emoji_Presentation_table), countof(unicode_prop_Extended_Pictographic_table), countof(unicode_prop_Default_Ignorable_Code_Point_table), countof(unicode_prop_ID_Start_table), countof(unicode_prop_Case_Ignorable_table), }; typedef enum { UNICODE_SEQUENCE_PROP_Basic_Emoji, UNICODE_SEQUENCE_PROP_Emoji_Keycap_Sequence, UNICODE_SEQUENCE_PROP_RGI_Emoji_Modifier_Sequence, UNICODE_SEQUENCE_PROP_RGI_Emoji_Flag_Sequence, UNICODE_SEQUENCE_PROP_RGI_Emoji_Tag_Sequence, UNICODE_SEQUENCE_PROP_RGI_Emoji_ZWJ_Sequence, UNICODE_SEQUENCE_PROP_RGI_Emoji, UNICODE_SEQUENCE_PROP_COUNT, } UnicodeSequencePropertyEnum; static const char unicode_sequence_prop_name_table[] = "Basic_Emoji" "\0" "Emoji_Keycap_Sequence" "\0" "RGI_Emoji_Modifier_Sequence" "\0" "RGI_Emoji_Flag_Sequence" "\0" "RGI_Emoji_Tag_Sequence" "\0" "RGI_Emoji_ZWJ_Sequence" "\0" "RGI_Emoji" "\0" ; static const uint8_t unicode_rgi_emoji_tag_sequence[18] = { 0x67, 0x62, 0x65, 0x6e, 0x67, 0x00, 0x67, 0x62, 0x73, 0x63, 0x74, 0x00, 0x67, 0x62, 0x77, 0x6c, 0x73, 0x00, }; static const uint8_t unicode_rgi_emoji_zwj_sequence[2392] = { 0x02, 0xb8, 0x19, 0x40, 0x86, 0x02, 0xd1, 0x39, 0xb0, 0x19, 0x02, 0x26, 0x39, 0x42, 0x86, 0x02, 0xb4, 0x36, 0x42, 0x86, 0x03, 0x68, 0x54, 0x64, 0x87, 0x68, 0x54, 0x02, 0xdc, 0x39, 0x42, 0x86, 0x02, 0xd1, 0x39, 0x73, 0x13, 0x02, 0x39, 0x39, 0x40, 0x86, 0x02, 0x69, 0x34, 0xbd, 0x19, 0x03, 0xb6, 0x36, 0x40, 0x86, 0xa1, 0x87, 0x03, 0x68, 0x74, 0x1d, 0x19, 0x68, 0x74, 0x03, 0x68, 0x34, 0xbd, 0x19, 0xa1, 0x87, 0x02, 0xf1, 0x7a, 0xf2, 0x7a, 0x02, 0xca, 0x33, 0x42, 0x86, 0x02, 0x69, 0x34, 0xb0, 0x19, 0x04, 0x68, 0x14, 0x68, 0x14, 0x67, 0x14, 0x66, 0x14, 0x02, 0xf9, 0x26, 0x42, 0x86, 0x03, 0x69, 0x74, 0x1d, 0x19, 0x69, 0x74, 0x03, 0xd1, 0x19, 0xbc, 0x19, 0xa1, 0x87, 0x02, 0x3c, 0x19, 0x40, 0x86, 0x02, 0x68, 0x34, 0xeb, 0x13, 0x02, 0xc3, 0x33, 0xa1, 0x87, 0x02, 0x70, 0x34, 0x40, 0x86, 0x02, 0xd4, 0x39, 0x42, 0x86, 0x02, 0xcf, 0x39, 0x42, 0x86, 0x03, 0xd1, 0x79, 0xef, 0x1a, 0xd1, 0x79, 0x03, 0x68, 0x74, 0xef, 0x1a, 0x68, 0x74, 0x03, 0x69, 0x74, 0xef, 0x1a, 0x69, 0x74, 0x02, 0x47, 0x36, 0x40, 0x86, 0x03, 0x68, 0x74, 0x30, 0x14, 0x68, 0x74, 0x02, 0x39, 0x39, 0x42, 0x86, 0x04, 0xd1, 0x79, 0x64, 0x87, 0x8b, 0x14, 0xd1, 0x79, 0x03, 0x69, 0x74, 0x30, 0x14, 0x69, 0x74, 0x02, 0xd1, 0x39, 0x95, 0x86, 0x02, 0x68, 0x34, 0x93, 0x13, 0x02, 0x69, 0x34, 0xed, 0x13, 0x02, 0xda, 0x39, 0x40, 0x86, 0x03, 0x69, 0x34, 0xaf, 0x19, 0xa1, 0x87, 0x02, 0xd1, 0x39, 0x93, 0x13, 0x03, 0xce, 0x39, 0x42, 0x86, 0xa1, 0x87, 0x03, 0xd1, 0x79, 0x64, 0x87, 0xd1, 0x79, 0x03, 0xc3, 0x33, 0x42, 0x86, 0xa1, 0x87, 0x03, 0x69, 0x74, 0x1d, 0x19, 0x68, 0x74, 0x02, 0x69, 0x34, 0x92, 0x16, 0x02, 0xd1, 0x39, 0x96, 0x86, 0x04, 0x69, 0x14, 0x64, 0x87, 0x8b, 0x14, 0x68, 0x14, 0x02, 0x47, 0x36, 0x42, 0x86, 0x02, 0x68, 0x34, 0x7c, 0x13, 0x02, 0x86, 0x34, 0x42, 0x86, 0x02, 0xd1, 0x39, 0x7c, 0x13, 0x02, 0x69, 0x14, 0xa4, 0x13, 0x02, 0xda, 0x39, 0x42, 0x86, 0x02, 0x37, 0x39, 0x40, 0x86, 0x02, 0xd1, 0x39, 0x08, 0x87, 0x04, 0x68, 0x54, 0x64, 0x87, 0x8b, 0x14, 0x68, 0x54, 0x02, 0x4d, 0x36, 0x40, 0x86, 0x02, 0x68, 0x34, 0x2c, 0x15, 0x02, 0x69, 0x34, 0xaf, 0x19, 0x02, 0x6e, 0x34, 0x40, 0x86, 0x02, 0xcd, 0x39, 0x42, 0x86, 0x02, 0xd1, 0x39, 0x2c, 0x15, 0x02, 0x6f, 0x14, 0x40, 0x86, 0x03, 0xd1, 0x39, 0xbc, 0x19, 0xa1, 0x87, 0x02, 0x68, 0x34, 0xa8, 0x13, 0x02, 0x69, 0x34, 0x73, 0x13, 0x04, 0x69, 0x54, 0x64, 0x87, 0x8b, 0x14, 0x68, 0x54, 0x02, 0x71, 0x34, 0x42, 0x86, 0x02, 0x45, 0x36, 0x40, 0x86, 0x02, 0xd1, 0x39, 0xa8, 0x13, 0x03, 0x69, 0x54, 0x64, 0x87, 0x68, 0x54, 0x03, 0x69, 0x54, 0x64, 0x87, 0x69, 0x54, 0x03, 0xce, 0x39, 0x40, 0x86, 0xa1, 0x87, 0x02, 0xd8, 0x39, 0x40, 0x86, 0x03, 0xc3, 0x33, 0x40, 0x86, 0xa1, 0x87, 0x02, 0x4d, 0x36, 0x42, 0x86, 0x02, 0xd1, 0x19, 0x92, 0x16, 0x02, 0xd1, 0x39, 0xeb, 0x13, 0x02, 0x68, 0x34, 0xbc, 0x14, 0x02, 0xd1, 0x39, 0xbc, 0x14, 0x02, 0x3d, 0x39, 0x40, 0x86, 0x02, 0xb8, 0x39, 0x42, 0x86, 0x02, 0xa3, 0x36, 0x40, 0x86, 0x02, 0x75, 0x35, 0x40, 0x86, 0x02, 0xd8, 0x39, 0x42, 0x86, 0x02, 0x69, 0x34, 0x93, 0x13, 0x02, 0x35, 0x39, 0x40, 0x86, 0x02, 0x4b, 0x36, 0x40, 0x86, 0x02, 0x3d, 0x39, 0x42, 0x86, 0x02, 0x38, 0x39, 0x42, 0x86, 0x02, 0xa3, 0x36, 0x42, 0x86, 0x03, 0x69, 0x14, 0x67, 0x14, 0x67, 0x14, 0x02, 0xb6, 0x36, 0x40, 0x86, 0x02, 0x69, 0x34, 0x7c, 0x13, 0x02, 0x75, 0x35, 0x42, 0x86, 0x02, 0xcc, 0x93, 0x40, 0x86, 0x02, 0x6f, 0x34, 0x42, 0x86, 0x02, 0xcc, 0x33, 0x40, 0x86, 0x03, 0xd1, 0x39, 0xbd, 0x19, 0xa1, 0x87, 0x02, 0x87, 0x34, 0x40, 0x86, 0x02, 0x82, 0x34, 0x40, 0x86, 0x02, 0x69, 0x14, 0x3e, 0x13, 0x02, 0xd6, 0x39, 0x40, 0x86, 0x02, 0x68, 0x14, 0xbd, 0x19, 0x02, 0x4b, 0x36, 0x42, 0x86, 0x02, 0x46, 0x36, 0x42, 0x86, 0x02, 0x69, 0x34, 0x2c, 0x15, 0x03, 0xb6, 0x36, 0x42, 0x86, 0xa1, 0x87, 0x02, 0xc4, 0x33, 0x40, 0x86, 0x02, 0x26, 0x19, 0x40, 0x86, 0x02, 0x69, 0x14, 0xb0, 0x19, 0x02, 0xde, 0x19, 0x42, 0x86, 0x02, 0x69, 0x34, 0xa8, 0x13, 0x02, 0xcc, 0x33, 0x42, 0x86, 0x02, 0x82, 0x34, 0x42, 0x86, 0x02, 0xd1, 0x19, 0x93, 0x13, 0x02, 0x81, 0x14, 0x42, 0x86, 0x03, 0xd1, 0x79, 0x30, 0x14, 0xd1, 0x79, 0x02, 0x68, 0x34, 0xbb, 0x14, 0x02, 0x69, 0x34, 0x95, 0x86, 0x02, 0xd1, 0x39, 0xbb, 0x14, 0x02, 0x69, 0x34, 0xeb, 0x13, 0x02, 0xd1, 0x39, 0x84, 0x13, 0x02, 0x69, 0x34, 0xbc, 0x14, 0x04, 0x69, 0x54, 0x64, 0x87, 0x8b, 0x14, 0x69, 0x54, 0x02, 0x26, 0x39, 0x40, 0x86, 0x02, 0xb4, 0x36, 0x40, 0x86, 0x02, 0x47, 0x16, 0x42, 0x86, 0x02, 0xdc, 0x39, 0x40, 0x86, 0x02, 0xca, 0x33, 0x40, 0x86, 0x02, 0xf9, 0x26, 0x40, 0x86, 0x02, 0x69, 0x34, 0x08, 0x87, 0x03, 0x69, 0x14, 0x69, 0x14, 0x66, 0x14, 0x03, 0xd1, 0x59, 0x1d, 0x19, 0xd1, 0x59, 0x02, 0xd4, 0x39, 0x40, 0x86, 0x02, 0xcf, 0x39, 0x40, 0x86, 0x02, 0x68, 0x34, 0xa4, 0x13, 0x02, 0xd1, 0x39, 0xa4, 0x13, 0x02, 0xd1, 0x19, 0xa8, 0x13, 0x02, 0xd7, 0x39, 0x42, 0x86, 0x03, 0x69, 0x34, 0xbc, 0x19, 0xa1, 0x87, 0x02, 0x68, 0x14, 0xb0, 0x19, 0x02, 0x3c, 0x39, 0x42, 0x86, 0x02, 0x68, 0x14, 0x73, 0x13, 0x04, 0x69, 0x14, 0x69, 0x14, 0x66, 0x14, 0x66, 0x14, 0x03, 0x68, 0x34, 0xaf, 0x19, 0xa1, 0x87, 0x02, 0x68, 0x34, 0x80, 0x16, 0x02, 0x73, 0x34, 0x42, 0x86, 0x02, 0xd1, 0x39, 0x80, 0x16, 0x02, 0x68, 0x34, 0xb0, 0x19, 0x02, 0x86, 0x34, 0x40, 0x86, 0x02, 0x38, 0x19, 0x42, 0x86, 0x02, 0x69, 0x34, 0xbb, 0x14, 0x02, 0xb5, 0x36, 0x42, 0x86, 0x02, 0xcd, 0x39, 0x40, 0x86, 0x02, 0x68, 0x34, 0x27, 0x15, 0x02, 0x68, 0x34, 0x95, 0x86, 0x03, 0x68, 0x14, 0x68, 0x14, 0x66, 0x14, 0x02, 0x71, 0x34, 0x40, 0x86, 0x02, 0xd1, 0x39, 0x27, 0x15, 0x02, 0x2e, 0x16, 0xa8, 0x14, 0x02, 0xc3, 0x33, 0x42, 0x86, 0x02, 0x69, 0x14, 0x66, 0x14, 0x02, 0x68, 0x34, 0x96, 0x86, 0x02, 0xd1, 0x39, 0x70, 0x1a, 0x03, 0x69, 0x14, 0x64, 0x87, 0x68, 0x14, 0x02, 0x69, 0x34, 0xa4, 0x13, 0x02, 0xb8, 0x39, 0x40, 0x86, 0x02, 0x68, 0x34, 0x3e, 0x13, 0x03, 0xd1, 0x19, 0xaf, 0x19, 0xa1, 0x87, 0x02, 0xd1, 0x39, 0x3e, 0x13, 0x02, 0x68, 0x34, 0xbd, 0x19, 0x02, 0xd1, 0x19, 0xbb, 0x14, 0x02, 0xd1, 0x19, 0x95, 0x86, 0x02, 0xdb, 0x39, 0x42, 0x86, 0x02, 0x38, 0x39, 0x40, 0x86, 0x02, 0x69, 0x34, 0x80, 0x16, 0x02, 0x69, 0x14, 0xeb, 0x13, 0x04, 0x68, 0x14, 0x69, 0x14, 0x67, 0x14, 0x67, 0x14, 0x02, 0x6f, 0x34, 0x40, 0x86, 0x02, 0x77, 0x34, 0x42, 0x86, 0x02, 0x46, 0x36, 0x40, 0x86, 0x02, 0x68, 0x34, 0x92, 0x16, 0x02, 0x4e, 0x36, 0x42, 0x86, 0x03, 0x69, 0x14, 0xbd, 0x19, 0xa1, 0x87, 0x02, 0xde, 0x19, 0x40, 0x86, 0x02, 0x69, 0x34, 0x27, 0x15, 0x03, 0xc3, 0x13, 0x40, 0x86, 0xa1, 0x87, 0x02, 0x81, 0x14, 0x40, 0x86, 0x03, 0xd1, 0x39, 0xaf, 0x19, 0xa1, 0x87, 0x02, 0x68, 0x34, 0xbc, 0x19, 0x02, 0xd1, 0x19, 0x80, 0x16, 0x02, 0xd9, 0x39, 0x42, 0x86, 0x02, 0xd1, 0x39, 0xbc, 0x19, 0x02, 0xdc, 0x19, 0x42, 0x86, 0x02, 0x68, 0x34, 0x73, 0x13, 0x02, 0x69, 0x34, 0x3e, 0x13, 0x02, 0x47, 0x16, 0x40, 0x86, 0x02, 0xd1, 0x39, 0xbd, 0x19, 0x02, 0x3e, 0x39, 0x42, 0x86, 0x02, 0x69, 0x14, 0x95, 0x86, 0x02, 0x68, 0x14, 0x96, 0x86, 0x03, 0x69, 0x34, 0xbd, 0x19, 0xa1, 0x87, 0x02, 0xd7, 0x39, 0x40, 0x86, 0x02, 0x45, 0x16, 0x42, 0x86, 0x02, 0x68, 0x34, 0xed, 0x13, 0x03, 0x68, 0x34, 0xbc, 0x19, 0xa1, 0x87, 0x02, 0xd1, 0x39, 0xed, 0x13, 0x02, 0x3c, 0x39, 0x40, 0x86, 0x02, 0xd1, 0x19, 0x70, 0x1a, 0x02, 0xd1, 0x39, 0x92, 0x16, 0x02, 0x73, 0x34, 0x40, 0x86, 0x02, 0x38, 0x19, 0x40, 0x86, 0x02, 0xb5, 0x36, 0x40, 0x86, 0x02, 0x68, 0x34, 0xaf, 0x19, 0x02, 0xd1, 0x39, 0xaf, 0x19, 0x02, 0x69, 0x34, 0xbc, 0x19, 0x02, 0xb6, 0x16, 0x42, 0x86, 0x02, 0x26, 0x14, 0x25, 0x15, 0x02, 0xc3, 0x33, 0x40, 0x86, 0x02, 0xdd, 0x39, 0x42, 0x86, 0x02, 0xcb, 0x93, 0x42, 0x86, 0x02, 0xcb, 0x33, 0x42, 0x86, 0x02, 0x81, 0x34, 0x42, 0x86, 0x02, 0xce, 0x39, 0xa1, 0x87, 0x02, 0xdb, 0x39, 0x40, 0x86, 0x02, 0x68, 0x34, 0x08, 0x87, 0x02, 0xd1, 0x19, 0xb0, 0x19, 0x02, 0x77, 0x34, 0x40, 0x86, 0x02, 0x4e, 0x36, 0x40, 0x86, 0x02, 0xce, 0x39, 0x42, 0x86, 0x02, 0x4e, 0x16, 0x42, 0x86, 0x02, 0xd9, 0x39, 0x40, 0x86, 0x02, 0xdc, 0x19, 0x40, 0x86, 0x02, 0x3e, 0x39, 0x40, 0x86, 0x02, 0xb9, 0x39, 0x42, 0x86, 0x02, 0xda, 0x19, 0x42, 0x86, 0x02, 0x42, 0x16, 0x94, 0x81, 0x02, 0x45, 0x16, 0x40, 0x86, 0x02, 0x69, 0x14, 0xbd, 0x19, 0x02, 0x70, 0x34, 0x42, 0x86, 0x02, 0xce, 0x19, 0xa1, 0x87, 0x02, 0xc3, 0x13, 0x42, 0x86, 0x02, 0x68, 0x14, 0x08, 0x87, 0x02, 0xd1, 0x19, 0x7c, 0x13, 0x02, 0x68, 0x14, 0x92, 0x16, 0x02, 0xb6, 0x16, 0x40, 0x86, 0x02, 0x37, 0x39, 0x42, 0x86, 0x03, 0xce, 0x19, 0x42, 0x86, 0xa1, 0x87, 0x03, 0x68, 0x14, 0x67, 0x14, 0x67, 0x14, 0x02, 0xdd, 0x39, 0x40, 0x86, 0x02, 0xcf, 0x19, 0x42, 0x86, 0x02, 0xd1, 0x19, 0x2c, 0x15, 0x02, 0x4b, 0x13, 0xe9, 0x17, 0x02, 0x68, 0x14, 0x67, 0x14, 0x02, 0xcb, 0x93, 0x40, 0x86, 0x02, 0x6e, 0x34, 0x42, 0x86, 0x02, 0xcb, 0x33, 0x40, 0x86, 0x02, 0x81, 0x34, 0x40, 0x86, 0x02, 0xb6, 0x36, 0xa1, 0x87, 0x02, 0x45, 0x36, 0x42, 0x86, 0x02, 0xb4, 0x16, 0x42, 0x86, 0x02, 0x69, 0x14, 0x73, 0x13, 0x04, 0x69, 0x14, 0x69, 0x14, 0x67, 0x14, 0x66, 0x14, 0x02, 0x35, 0x39, 0x42, 0x86, 0x02, 0x68, 0x14, 0x93, 0x13, 0x02, 0xb6, 0x36, 0x42, 0x86, 0x03, 0x68, 0x14, 0x69, 0x14, 0x66, 0x14, 0x02, 0xce, 0x39, 0x40, 0x86, 0x02, 0x4e, 0x16, 0x40, 0x86, 0x02, 0x87, 0x34, 0x42, 0x86, 0x02, 0x86, 0x14, 0x42, 0x86, 0x02, 0xd6, 0x39, 0x42, 0x86, 0x02, 0xc4, 0x33, 0x42, 0x86, 0x02, 0x69, 0x34, 0x96, 0x86, 0x02, 0xb9, 0x39, 0x40, 0x86, 0x02, 0x68, 0x14, 0xa8, 0x13, 0x02, 0xd1, 0x19, 0x84, 0x13, 0x02, 0xda, 0x19, 0x40, 0x86, 0x02, 0xd8, 0x19, 0x42, 0x86, 0x02, 0xc3, 0x13, 0x40, 0x86, 0x02, 0xb9, 0x19, 0x42, 0x86, 0x02, 0x3d, 0x19, 0x42, 0x86, 0x02, 0xcf, 0x19, 0x40, 0x86, 0x04, 0x68, 0x14, 0x68, 0x14, 0x67, 0x14, 0x67, 0x14, 0x03, 0xd1, 0x19, 0xd1, 0x19, 0xd2, 0x19, 0x02, 0x68, 0x14, 0xbb, 0x14, 0x02, 0x3b, 0x14, 0x44, 0x87, 0x02, 0xd1, 0x19, 0x27, 0x15, 0x02, 0xb4, 0x16, 0x40, 0x86, 0x02, 0xcd, 0x19, 0x42, 0x86, 0x02, 0xd3, 0x86, 0xa5, 0x14, 0x02, 0x70, 0x14, 0x42, 0x86, 0x03, 0xb6, 0x16, 0x42, 0x86, 0xa1, 0x87, 0x04, 0x69, 0x14, 0x64, 0x87, 0x8b, 0x14, 0x69, 0x14, 0x02, 0x36, 0x16, 0x2b, 0x93, 0x02, 0x68, 0x14, 0x80, 0x16, 0x02, 0x86, 0x14, 0x40, 0x86, 0x02, 0x08, 0x14, 0x1b, 0x0b, 0x02, 0xd1, 0x19, 0xbc, 0x19, 0x02, 0xca, 0x13, 0x42, 0x86, 0x02, 0x41, 0x94, 0xe8, 0x95, 0x02, 0xd8, 0x19, 0x40, 0x86, 0x02, 0xb9, 0x19, 0x40, 0x86, 0x02, 0xd1, 0x19, 0xed, 0x13, 0x02, 0xf9, 0x86, 0x42, 0x86, 0x03, 0xd1, 0x19, 0xbd, 0x19, 0xa1, 0x87, 0x02, 0x3d, 0x19, 0x40, 0x86, 0x02, 0xd6, 0x19, 0x42, 0x86, 0x03, 0x69, 0x14, 0x66, 0x14, 0x66, 0x14, 0x02, 0xd1, 0x19, 0xaf, 0x19, 0x03, 0x69, 0x14, 0x69, 0x14, 0x67, 0x14, 0x02, 0xcd, 0x19, 0x40, 0x86, 0x02, 0x70, 0x14, 0x40, 0x86, 0x03, 0x68, 0x14, 0xbc, 0x19, 0xa1, 0x87, 0x02, 0x6e, 0x14, 0x42, 0x86, 0x02, 0x69, 0x14, 0x92, 0x16, 0x03, 0x68, 0x14, 0x68, 0x14, 0x67, 0x14, 0x02, 0x69, 0x14, 0x67, 0x14, 0x02, 0x75, 0x95, 0x42, 0x86, 0x03, 0x69, 0x14, 0x64, 0x87, 0x69, 0x14, 0x02, 0xd1, 0x19, 0xbc, 0x14, 0x02, 0xdf, 0x19, 0x42, 0x86, 0x02, 0xca, 0x13, 0x40, 0x86, 0x02, 0x82, 0x14, 0x42, 0x86, 0x02, 0x69, 0x14, 0x93, 0x13, 0x02, 0x68, 0x14, 0x7c, 0x13, 0x02, 0xf9, 0x86, 0x40, 0x86, 0x02, 0xd6, 0x19, 0x40, 0x86, 0x02, 0x68, 0x14, 0x2c, 0x15, 0x02, 0x69, 0x14, 0xa8, 0x13, 0x02, 0xd4, 0x19, 0x42, 0x86, 0x04, 0x68, 0x14, 0x69, 0x14, 0x66, 0x14, 0x66, 0x14, 0x02, 0x77, 0x14, 0x42, 0x86, 0x02, 0x39, 0x19, 0x42, 0x86, 0x02, 0xd1, 0x19, 0xa4, 0x13, 0x02, 0x6e, 0x14, 0x40, 0x86, 0x03, 0xd1, 0x19, 0xd2, 0x19, 0xd2, 0x19, 0x02, 0x69, 0x14, 0xbb, 0x14, 0x02, 0xd1, 0x19, 0x96, 0x86, 0x02, 0x75, 0x95, 0x40, 0x86, 0x04, 0x68, 0x14, 0x64, 0x87, 0x8b, 0x14, 0x68, 0x14, 0x02, 0xd1, 0x19, 0x3e, 0x13, 0x02, 0xdf, 0x19, 0x40, 0x86, 0x02, 0x82, 0x14, 0x40, 0x86, 0x02, 0x44, 0x13, 0xeb, 0x17, 0x02, 0xdd, 0x19, 0x42, 0x86, 0x03, 0x68, 0x14, 0xaf, 0x19, 0xa1, 0x87, 0x02, 0x69, 0x14, 0x80, 0x16, 0x02, 0xa3, 0x16, 0x42, 0x86, 0x02, 0x69, 0x14, 0x96, 0x86, 0x02, 0x46, 0x16, 0x42, 0x86, 0x02, 0xb6, 0x16, 0xa1, 0x87, 0x02, 0x68, 0x14, 0x27, 0x15, 0x02, 0x26, 0x14, 0x1b, 0x0b, 0x02, 0xd4, 0x19, 0x40, 0x86, 0x02, 0x77, 0x14, 0x40, 0x86, 0x02, 0x39, 0x19, 0x40, 0x86, 0x02, 0x37, 0x19, 0x42, 0x86, 0x03, 0x69, 0x14, 0x67, 0x14, 0x66, 0x14, 0x03, 0xc3, 0x13, 0x42, 0x86, 0xa1, 0x87, 0x02, 0x68, 0x14, 0xbc, 0x19, 0x02, 0xd1, 0x19, 0xeb, 0x13, 0x04, 0x69, 0x14, 0x69, 0x14, 0x67, 0x14, 0x67, 0x14, 0x02, 0xd1, 0x19, 0x08, 0x87, 0x02, 0x68, 0x14, 0xed, 0x13, 0x03, 0x69, 0x14, 0xbc, 0x19, 0xa1, 0x87, 0x02, 0xdd, 0x19, 0x40, 0x86, 0x02, 0xc3, 0x13, 0xa1, 0x87, 0x03, 0x68, 0x14, 0x66, 0x14, 0x66, 0x14, 0x03, 0x68, 0x14, 0x69, 0x14, 0x67, 0x14, 0x02, 0xa3, 0x16, 0x40, 0x86, 0x02, 0xdb, 0x19, 0x42, 0x86, 0x02, 0x68, 0x14, 0xaf, 0x19, 0x02, 0x46, 0x16, 0x40, 0x86, 0x02, 0x35, 0x16, 0xab, 0x14, 0x02, 0x68, 0x14, 0x95, 0x86, 0x02, 0x42, 0x16, 0x95, 0x81, 0x02, 0xc4, 0x13, 0x42, 0x86, 0x02, 0x15, 0x14, 0xba, 0x19, 0x03, 0xd1, 0x19, 0x1d, 0x19, 0xd1, 0x19, 0x02, 0x69, 0x14, 0x08, 0x87, 0x02, 0x69, 0x14, 0x7c, 0x13, 0x02, 0x37, 0x19, 0x40, 0x86, 0x02, 0x73, 0x14, 0x42, 0x86, 0x02, 0x69, 0x14, 0x2c, 0x15, 0x02, 0xb5, 0x16, 0x42, 0x86, 0x02, 0x35, 0x19, 0x42, 0x86, 0x04, 0x68, 0x14, 0x69, 0x14, 0x67, 0x14, 0x66, 0x14, 0x02, 0x64, 0x87, 0x25, 0x15, 0x02, 0x64, 0x87, 0x79, 0x1a, 0x02, 0x68, 0x14, 0xbc, 0x14, 0x03, 0xce, 0x19, 0x40, 0x86, 0xa1, 0x87, 0x02, 0x87, 0x14, 0x42, 0x86, 0x02, 0x4d, 0x16, 0x42, 0x86, 0x04, 0x68, 0x14, 0x68, 0x14, 0x66, 0x14, 0x66, 0x14, 0x02, 0xdb, 0x19, 0x40, 0x86, 0x02, 0xd9, 0x19, 0x42, 0x86, 0x02, 0xc4, 0x13, 0x40, 0x86, 0x02, 0xd1, 0x19, 0xbd, 0x19, 0x02, 0x68, 0x14, 0xa4, 0x13, 0x02, 0x3e, 0x19, 0x42, 0x86, 0x02, 0xf3, 0x93, 0xa7, 0x86, 0x03, 0x69, 0x14, 0xaf, 0x19, 0xa1, 0x87, 0x02, 0xf3, 0x93, 0x08, 0x13, 0x02, 0xd1, 0x19, 0xd2, 0x19, 0x02, 0x73, 0x14, 0x40, 0x86, 0x02, 0xb5, 0x16, 0x40, 0x86, 0x02, 0x35, 0x19, 0x40, 0x86, 0x02, 0x69, 0x14, 0x27, 0x15, 0x02, 0xce, 0x19, 0x42, 0x86, 0x02, 0x71, 0x14, 0x42, 0x86, 0x02, 0xd1, 0x19, 0x73, 0x13, 0x02, 0x68, 0x14, 0x3e, 0x13, 0x02, 0xf4, 0x13, 0x20, 0x86, 0x02, 0x87, 0x14, 0x40, 0x86, 0x03, 0xb6, 0x16, 0x40, 0x86, 0xa1, 0x87, 0x02, 0x4d, 0x16, 0x40, 0x86, 0x02, 0x69, 0x14, 0xbc, 0x19, 0x02, 0x4b, 0x16, 0x42, 0x86, 0x02, 0xd9, 0x19, 0x40, 0x86, 0x02, 0x3e, 0x19, 0x40, 0x86, 0x02, 0x69, 0x14, 0xed, 0x13, 0x02, 0xd7, 0x19, 0x42, 0x86, 0x02, 0xb8, 0x19, 0x42, 0x86, 0x03, 0x68, 0x14, 0x67, 0x14, 0x66, 0x14, 0x02, 0x3c, 0x19, 0x42, 0x86, 0x02, 0x68, 0x14, 0x66, 0x14, 0x03, 0x68, 0x14, 0x64, 0x87, 0x68, 0x14, 0x02, 0x69, 0x14, 0xaf, 0x19, 0x02, 0xce, 0x19, 0x40, 0x86, 0x02, 0x71, 0x14, 0x40, 0x86, 0x02, 0x68, 0x14, 0xeb, 0x13, 0x03, 0x68, 0x14, 0xbd, 0x19, 0xa1, 0x87, 0x02, 0x6f, 0x14, 0x42, 0x86, 0x04, 0xd1, 0x19, 0xd1, 0x19, 0xd2, 0x19, 0xd2, 0x19, 0x02, 0x69, 0x14, 0xbc, 0x14, 0x02, 0xcc, 0x93, 0x42, 0x86, 0x02, 0x4b, 0x16, 0x40, 0x86, 0x02, 0x26, 0x19, 0x42, 0x86, 0x02, 0xd7, 0x19, 0x40, 0x86, }; #endif /* CONFIG_ALL_UNICODE */ /* 71 tables / 36659 bytes, 5 index / 357 bytes */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/qjs/libunicode.c�����������������������������������������������0000664�0000000�0000000�00000174201�15202323131�0022465�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Unicode utilities * * Copyright (c) 2017-2018 Fabrice Bellard * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include <stdlib.h> #include <stdio.h> #include <stdarg.h> #include <string.h> #include <assert.h> #include "cutils.h" #include "libunicode.h" #include "libunicode-table.h" enum { RUN_TYPE_U, RUN_TYPE_L, RUN_TYPE_UF, RUN_TYPE_LF, RUN_TYPE_UL, RUN_TYPE_LSU, RUN_TYPE_U2L_399_EXT2, RUN_TYPE_UF_D20, RUN_TYPE_UF_D1_EXT, RUN_TYPE_U_EXT, RUN_TYPE_LF_EXT, RUN_TYPE_UF_EXT2, RUN_TYPE_LF_EXT2, RUN_TYPE_UF_EXT3, }; static int lre_case_conv1(uint32_t c, int conv_type) { uint32_t res[LRE_CC_RES_LEN_MAX]; lre_case_conv(res, c, conv_type); return res[0]; } /* case conversion using the table entry 'idx' with value 'v' */ static int lre_case_conv_entry(uint32_t *res, uint32_t c, int conv_type, uint32_t idx, uint32_t v) { uint32_t code, data, type, a, is_lower; is_lower = (conv_type != 0); type = (v >> (32 - 17 - 7 - 4)) & 0xf; data = ((v & 0xf) << 8) | case_conv_table2[idx]; code = v >> (32 - 17); switch(type) { case RUN_TYPE_U: case RUN_TYPE_L: case RUN_TYPE_UF: case RUN_TYPE_LF: if (conv_type == (type & 1) || (type >= RUN_TYPE_UF && conv_type == 2)) { c = c - code + (case_conv_table1[data] >> (32 - 17)); } break; case RUN_TYPE_UL: a = c - code; if ((a & 1) != (1 - is_lower)) break; c = (a ^ 1) + code; break; case RUN_TYPE_LSU: a = c - code; if (a == 1) { c += 2 * is_lower - 1; } else if (a == (1 - is_lower) * 2) { c += (2 * is_lower - 1) * 2; } break; case RUN_TYPE_U2L_399_EXT2: if (!is_lower) { res[0] = c - code + case_conv_ext[data >> 6]; res[1] = 0x399; return 2; } else { c = c - code + case_conv_ext[data & 0x3f]; } break; case RUN_TYPE_UF_D20: if (conv_type == 1) break; c = data + (conv_type == 2) * 0x20; break; case RUN_TYPE_UF_D1_EXT: if (conv_type == 1) break; c = case_conv_ext[data] + (conv_type == 2); break; case RUN_TYPE_U_EXT: case RUN_TYPE_LF_EXT: if (is_lower != (type - RUN_TYPE_U_EXT)) break; c = case_conv_ext[data]; break; case RUN_TYPE_LF_EXT2: if (!is_lower) break; res[0] = c - code + case_conv_ext[data >> 6]; res[1] = case_conv_ext[data & 0x3f]; return 2; case RUN_TYPE_UF_EXT2: if (conv_type == 1) break; res[0] = c - code + case_conv_ext[data >> 6]; res[1] = case_conv_ext[data & 0x3f]; if (conv_type == 2) { /* convert to lower */ res[0] = lre_case_conv1(res[0], 1); res[1] = lre_case_conv1(res[1], 1); } return 2; default: case RUN_TYPE_UF_EXT3: if (conv_type == 1) break; res[0] = case_conv_ext[data >> 8]; res[1] = case_conv_ext[(data >> 4) & 0xf]; res[2] = case_conv_ext[data & 0xf]; if (conv_type == 2) { /* convert to lower */ res[0] = lre_case_conv1(res[0], 1); res[1] = lre_case_conv1(res[1], 1); res[2] = lre_case_conv1(res[2], 1); } return 3; } res[0] = c; return 1; } /* conv_type: 0 = to upper 1 = to lower 2 = case folding (= to lower with modifications) */ int lre_case_conv(uint32_t *res, uint32_t c, int conv_type) { if (c < 128) { if (conv_type) { if (c >= 'A' && c <= 'Z') { c = c - 'A' + 'a'; } } else { if (c >= 'a' && c <= 'z') { c = c - 'a' + 'A'; } } } else { uint32_t v, code, len; int idx, idx_min, idx_max; idx_min = 0; idx_max = countof(case_conv_table1) - 1; while (idx_min <= idx_max) { idx = (unsigned)(idx_max + idx_min) / 2; v = case_conv_table1[idx]; code = v >> (32 - 17); len = (v >> (32 - 17 - 7)) & 0x7f; if (c < code) { idx_max = idx - 1; } else if (c >= code + len) { idx_min = idx + 1; } else { return lre_case_conv_entry(res, c, conv_type, idx, v); } } } res[0] = c; return 1; } static int lre_case_folding_entry(uint32_t c, uint32_t idx, uint32_t v, BOOL is_unicode) { uint32_t res[LRE_CC_RES_LEN_MAX]; int len; if (is_unicode) { len = lre_case_conv_entry(res, c, 2, idx, v); if (len == 1) { c = res[0]; } else { /* handle the few specific multi-character cases (see unicode_gen.c:dump_case_folding_special_cases()) */ if (c == 0xfb06) { c = 0xfb05; } else if (c == 0x01fd3) { c = 0x390; } else if (c == 0x01fe3) { c = 0x3b0; } } } else { if (likely(c < 128)) { if (c >= 'a' && c <= 'z') c = c - 'a' + 'A'; } else { /* legacy regexp: to upper case if single char >= 128 */ len = lre_case_conv_entry(res, c, FALSE, idx, v); if (len == 1 && res[0] >= 128) c = res[0]; } } return c; } /* JS regexp specific rules for case folding */ int lre_canonicalize(uint32_t c, BOOL is_unicode) { if (c < 128) { /* fast case */ if (is_unicode) { if (c >= 'A' && c <= 'Z') { c = c - 'A' + 'a'; } } else { if (c >= 'a' && c <= 'z') { c = c - 'a' + 'A'; } } } else { uint32_t v, code, len; int idx, idx_min, idx_max; idx_min = 0; idx_max = countof(case_conv_table1) - 1; while (idx_min <= idx_max) { idx = (unsigned)(idx_max + idx_min) / 2; v = case_conv_table1[idx]; code = v >> (32 - 17); len = (v >> (32 - 17 - 7)) & 0x7f; if (c < code) { idx_max = idx - 1; } else if (c >= code + len) { idx_min = idx + 1; } else { return lre_case_folding_entry(c, idx, v, is_unicode); } } } return c; } static uint32_t get_le24(const uint8_t *ptr) { return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16); } #define UNICODE_INDEX_BLOCK_LEN 32 /* return -1 if not in table, otherwise the offset in the block */ static int get_index_pos(uint32_t *pcode, uint32_t c, const uint8_t *index_table, int index_table_len) { uint32_t code, v; int idx_min, idx_max, idx; idx_min = 0; v = get_le24(index_table); code = v & ((1 << 21) - 1); if (c < code) { *pcode = 0; return 0; } idx_max = index_table_len - 1; code = get_le24(index_table + idx_max * 3); if (c >= code) return -1; /* invariant: tab[idx_min] <= c < tab2[idx_max] */ while ((idx_max - idx_min) > 1) { idx = (idx_max + idx_min) / 2; v = get_le24(index_table + idx * 3); code = v & ((1 << 21) - 1); if (c < code) { idx_max = idx; } else { idx_min = idx; } } v = get_le24(index_table + idx_min * 3); *pcode = v & ((1 << 21) - 1); return (idx_min + 1) * UNICODE_INDEX_BLOCK_LEN + (v >> 21); } static BOOL lre_is_in_table(uint32_t c, const uint8_t *table, const uint8_t *index_table, int index_table_len) { uint32_t code, b, bit; int pos; const uint8_t *p; pos = get_index_pos(&code, c, index_table, index_table_len); if (pos < 0) return FALSE; /* outside the table */ p = table + pos; bit = 0; /* Compressed run length encoding: 00..3F: 2 packed lengths: 3-bit + 3-bit 40..5F: 5-bits plus extra byte for length 60..7F: 5-bits plus 2 extra bytes for length 80..FF: 7-bit length lengths must be incremented to get character count Ranges alternate between false and true return value. */ for(;;) { b = *p++; if (b < 64) { code += (b >> 3) + 1; if (c < code) return bit; bit ^= 1; code += (b & 7) + 1; } else if (b >= 0x80) { code += b - 0x80 + 1; } else if (b < 0x60) { code += (((b - 0x40) << 8) | p[0]) + 1; p++; } else { code += (((b - 0x60) << 16) | (p[0] << 8) | p[1]) + 1; p += 2; } if (c < code) return bit; bit ^= 1; } } BOOL lre_is_cased(uint32_t c) { uint32_t v, code, len; int idx, idx_min, idx_max; idx_min = 0; idx_max = countof(case_conv_table1) - 1; while (idx_min <= idx_max) { idx = (unsigned)(idx_max + idx_min) / 2; v = case_conv_table1[idx]; code = v >> (32 - 17); len = (v >> (32 - 17 - 7)) & 0x7f; if (c < code) { idx_max = idx - 1; } else if (c >= code + len) { idx_min = idx + 1; } else { return TRUE; } } return lre_is_in_table(c, unicode_prop_Cased1_table, unicode_prop_Cased1_index, sizeof(unicode_prop_Cased1_index) / 3); } BOOL lre_is_case_ignorable(uint32_t c) { return lre_is_in_table(c, unicode_prop_Case_Ignorable_table, unicode_prop_Case_Ignorable_index, sizeof(unicode_prop_Case_Ignorable_index) / 3); } /* character range */ static __maybe_unused void cr_dump(CharRange *cr) { int i; for(i = 0; i < cr->len; i++) printf("%d: 0x%04x\n", i, cr->points[i]); } static void *cr_default_realloc(void *opaque, void *ptr, size_t size) { return realloc(ptr, size); } void cr_init(CharRange *cr, void *mem_opaque, DynBufReallocFunc *realloc_func) { cr->len = cr->size = 0; cr->points = NULL; cr->mem_opaque = mem_opaque; cr->realloc_func = realloc_func ? realloc_func : cr_default_realloc; } void cr_free(CharRange *cr) { cr->realloc_func(cr->mem_opaque, cr->points, 0); } int cr_realloc(CharRange *cr, int size) { int new_size; uint32_t *new_buf; if (size > cr->size) { new_size = max_int(size, cr->size * 3 / 2); new_buf = cr->realloc_func(cr->mem_opaque, cr->points, new_size * sizeof(cr->points[0])); if (!new_buf) return -1; cr->points = new_buf; cr->size = new_size; } return 0; } int cr_copy(CharRange *cr, const CharRange *cr1) { if (cr_realloc(cr, cr1->len)) return -1; memcpy(cr->points, cr1->points, sizeof(cr->points[0]) * cr1->len); cr->len = cr1->len; return 0; } /* merge consecutive intervals and remove empty intervals */ static void cr_compress(CharRange *cr) { int i, j, k, len; uint32_t *pt; pt = cr->points; len = cr->len; i = 0; j = 0; k = 0; while ((i + 1) < len) { if (pt[i] == pt[i + 1]) { /* empty interval */ i += 2; } else { j = i; while ((j + 3) < len && pt[j + 1] == pt[j + 2]) j += 2; /* just copy */ pt[k] = pt[i]; pt[k + 1] = pt[j + 1]; k += 2; i = j + 2; } } cr->len = k; } /* union or intersection */ int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len, const uint32_t *b_pt, int b_len, int op) { int a_idx, b_idx, is_in; uint32_t v; a_idx = 0; b_idx = 0; for(;;) { /* get one more point from a or b in increasing order */ if (a_idx < a_len && b_idx < b_len) { if (a_pt[a_idx] < b_pt[b_idx]) { goto a_add; } else if (a_pt[a_idx] == b_pt[b_idx]) { v = a_pt[a_idx]; a_idx++; b_idx++; } else { goto b_add; } } else if (a_idx < a_len) { a_add: v = a_pt[a_idx++]; } else if (b_idx < b_len) { b_add: v = b_pt[b_idx++]; } else { break; } /* add the point if the in/out status changes */ switch(op) { case CR_OP_UNION: is_in = (a_idx & 1) | (b_idx & 1); break; case CR_OP_INTER: is_in = (a_idx & 1) & (b_idx & 1); break; case CR_OP_XOR: is_in = (a_idx & 1) ^ (b_idx & 1); break; case CR_OP_SUB: is_in = (a_idx & 1) & ((b_idx & 1) ^ 1); break; default: abort(); } if (is_in != (cr->len & 1)) { if (cr_add_point(cr, v)) return -1; } } cr_compress(cr); return 0; } int cr_op1(CharRange *cr, const uint32_t *b_pt, int b_len, int op) { CharRange a = *cr; int ret; cr->len = 0; cr->size = 0; cr->points = NULL; ret = cr_op(cr, a.points, a.len, b_pt, b_len, op); cr_free(&a); return ret; } int cr_invert(CharRange *cr) { int len; len = cr->len; if (cr_realloc(cr, len + 2)) return -1; memmove(cr->points + 1, cr->points, len * sizeof(cr->points[0])); cr->points[0] = 0; cr->points[len + 1] = UINT32_MAX; cr->len = len + 2; cr_compress(cr); return 0; } #define CASE_U (1 << 0) #define CASE_L (1 << 1) #define CASE_F (1 << 2) /* use the case conversion table to generate range of characters. CASE_U: set char if modified by uppercasing, CASE_L: set char if modified by lowercasing, CASE_F: set char if modified by case folding, */ static int unicode_case1(CharRange *cr, int case_mask) { #define MR(x) (1 << RUN_TYPE_ ## x) const uint32_t tab_run_mask[3] = { MR(U) | MR(UF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(UF_D20) | MR(UF_D1_EXT) | MR(U_EXT) | MR(UF_EXT2) | MR(UF_EXT3), MR(L) | MR(LF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(LF_EXT) | MR(LF_EXT2), MR(UF) | MR(LF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(LF_EXT) | MR(LF_EXT2) | MR(UF_D20) | MR(UF_D1_EXT) | MR(LF_EXT) | MR(UF_EXT2) | MR(UF_EXT3), }; #undef MR uint32_t mask, v, code, type, len, i, idx; if (case_mask == 0) return 0; mask = 0; for(i = 0; i < 3; i++) { if ((case_mask >> i) & 1) mask |= tab_run_mask[i]; } for(idx = 0; idx < countof(case_conv_table1); idx++) { v = case_conv_table1[idx]; type = (v >> (32 - 17 - 7 - 4)) & 0xf; code = v >> (32 - 17); len = (v >> (32 - 17 - 7)) & 0x7f; if ((mask >> type) & 1) { // printf("%d: type=%d %04x %04x\n", idx, type, code, code + len - 1); switch(type) { case RUN_TYPE_UL: if ((case_mask & CASE_U) && (case_mask & (CASE_L | CASE_F))) goto def_case; code += ((case_mask & CASE_U) != 0); for(i = 0; i < len; i += 2) { if (cr_add_interval(cr, code + i, code + i + 1)) return -1; } break; case RUN_TYPE_LSU: if ((case_mask & CASE_U) && (case_mask & (CASE_L | CASE_F))) goto def_case; if (!(case_mask & CASE_U)) { if (cr_add_interval(cr, code, code + 1)) return -1; } if (cr_add_interval(cr, code + 1, code + 2)) return -1; if (case_mask & CASE_U) { if (cr_add_interval(cr, code + 2, code + 3)) return -1; } break; default: def_case: if (cr_add_interval(cr, code, code + len)) return -1; break; } } } return 0; } static int point_cmp(const void *p1, const void *p2, void *arg) { uint32_t v1 = *(uint32_t *)p1; uint32_t v2 = *(uint32_t *)p2; return (v1 > v2) - (v1 < v2); } static void cr_sort_and_remove_overlap(CharRange *cr) { uint32_t start, end, start1, end1, i, j; /* the resulting ranges are not necessarily sorted and may overlap */ rqsort(cr->points, cr->len / 2, sizeof(cr->points[0]) * 2, point_cmp, NULL); j = 0; for(i = 0; i < cr->len; ) { start = cr->points[i]; end = cr->points[i + 1]; i += 2; while (i < cr->len) { start1 = cr->points[i]; end1 = cr->points[i + 1]; if (start1 > end) { /* |------| * |-------| */ break; } else if (end1 <= end) { /* |------| * |--| */ i += 2; } else { /* |------| * |-------| */ end = end1; i += 2; } } cr->points[j] = start; cr->points[j + 1] = end; j += 2; } cr->len = j; } /* canonicalize a character set using the JS regex case folding rules (see lre_canonicalize()) */ int cr_regexp_canonicalize(CharRange *cr, BOOL is_unicode) { CharRange cr_inter, cr_mask, cr_result, cr_sub; uint32_t v, code, len, i, idx, start, end, c, d_start, d_end, d; cr_init(&cr_mask, cr->mem_opaque, cr->realloc_func); cr_init(&cr_inter, cr->mem_opaque, cr->realloc_func); cr_init(&cr_result, cr->mem_opaque, cr->realloc_func); cr_init(&cr_sub, cr->mem_opaque, cr->realloc_func); if (unicode_case1(&cr_mask, is_unicode ? CASE_F : CASE_U)) goto fail; if (cr_op(&cr_inter, cr_mask.points, cr_mask.len, cr->points, cr->len, CR_OP_INTER)) goto fail; if (cr_invert(&cr_mask)) goto fail; if (cr_op(&cr_sub, cr_mask.points, cr_mask.len, cr->points, cr->len, CR_OP_INTER)) goto fail; /* cr_inter = cr & cr_mask */ /* cr_sub = cr & ~cr_mask */ /* use the case conversion table to compute the result */ d_start = -1; d_end = -1; idx = 0; v = case_conv_table1[idx]; code = v >> (32 - 17); len = (v >> (32 - 17 - 7)) & 0x7f; for(i = 0; i < cr_inter.len; i += 2) { start = cr_inter.points[i]; end = cr_inter.points[i + 1]; for(c = start; c < end; c++) { for(;;) { if (c >= code && c < code + len) break; idx++; assert(idx < countof(case_conv_table1)); v = case_conv_table1[idx]; code = v >> (32 - 17); len = (v >> (32 - 17 - 7)) & 0x7f; } d = lre_case_folding_entry(c, idx, v, is_unicode); /* try to merge with the current interval */ if (d_start == -1) { d_start = d; d_end = d + 1; } else if (d_end == d) { d_end++; } else { cr_add_interval(&cr_result, d_start, d_end); d_start = d; d_end = d + 1; } } } if (d_start != -1) { if (cr_add_interval(&cr_result, d_start, d_end)) goto fail; } /* the resulting ranges are not necessarily sorted and may overlap */ cr_sort_and_remove_overlap(&cr_result); /* or with the character not affected by the case folding */ cr->len = 0; if (cr_op(cr, cr_result.points, cr_result.len, cr_sub.points, cr_sub.len, CR_OP_UNION)) goto fail; cr_free(&cr_inter); cr_free(&cr_mask); cr_free(&cr_result); cr_free(&cr_sub); return 0; fail: cr_free(&cr_inter); cr_free(&cr_mask); cr_free(&cr_result); cr_free(&cr_sub); return -1; } #ifdef CONFIG_ALL_UNICODE BOOL lre_is_id_start(uint32_t c) { return lre_is_in_table(c, unicode_prop_ID_Start_table, unicode_prop_ID_Start_index, sizeof(unicode_prop_ID_Start_index) / 3); } BOOL lre_is_id_continue(uint32_t c) { return lre_is_id_start(c) || lre_is_in_table(c, unicode_prop_ID_Continue1_table, unicode_prop_ID_Continue1_index, sizeof(unicode_prop_ID_Continue1_index) / 3); } #define UNICODE_DECOMP_LEN_MAX 18 typedef enum { DECOMP_TYPE_C1, /* 16 bit char */ DECOMP_TYPE_L1, /* 16 bit char table */ DECOMP_TYPE_L2, DECOMP_TYPE_L3, DECOMP_TYPE_L4, DECOMP_TYPE_L5, /* XXX: not used */ DECOMP_TYPE_L6, /* XXX: could remove */ DECOMP_TYPE_L7, /* XXX: could remove */ DECOMP_TYPE_LL1, /* 18 bit char table */ DECOMP_TYPE_LL2, DECOMP_TYPE_S1, /* 8 bit char table */ DECOMP_TYPE_S2, DECOMP_TYPE_S3, DECOMP_TYPE_S4, DECOMP_TYPE_S5, DECOMP_TYPE_I1, /* increment 16 bit char value */ DECOMP_TYPE_I2_0, DECOMP_TYPE_I2_1, DECOMP_TYPE_I3_1, DECOMP_TYPE_I3_2, DECOMP_TYPE_I4_1, DECOMP_TYPE_I4_2, DECOMP_TYPE_B1, /* 16 bit base + 8 bit offset */ DECOMP_TYPE_B2, DECOMP_TYPE_B3, DECOMP_TYPE_B4, DECOMP_TYPE_B5, DECOMP_TYPE_B6, DECOMP_TYPE_B7, DECOMP_TYPE_B8, DECOMP_TYPE_B18, DECOMP_TYPE_LS2, DECOMP_TYPE_PAT3, DECOMP_TYPE_S2_UL, DECOMP_TYPE_LS2_UL, } DecompTypeEnum; static uint32_t unicode_get_short_code(uint32_t c) { static const uint16_t unicode_short_table[2] = { 0x2044, 0x2215 }; if (c < 0x80) return c; else if (c < 0x80 + 0x50) return c - 0x80 + 0x300; else return unicode_short_table[c - 0x80 - 0x50]; } static uint32_t unicode_get_lower_simple(uint32_t c) { if (c < 0x100 || (c >= 0x410 && c <= 0x42f)) c += 0x20; else c++; return c; } static uint16_t unicode_get16(const uint8_t *p) { return p[0] | (p[1] << 8); } static int unicode_decomp_entry(uint32_t *res, uint32_t c, int idx, uint32_t code, uint32_t len, uint32_t type) { uint32_t c1; int l, i, p; const uint8_t *d; if (type == DECOMP_TYPE_C1) { res[0] = unicode_decomp_table2[idx]; return 1; } else { d = unicode_decomp_data + unicode_decomp_table2[idx]; switch(type) { case DECOMP_TYPE_L1: case DECOMP_TYPE_L2: case DECOMP_TYPE_L3: case DECOMP_TYPE_L4: case DECOMP_TYPE_L5: case DECOMP_TYPE_L6: case DECOMP_TYPE_L7: l = type - DECOMP_TYPE_L1 + 1; d += (c - code) * l * 2; for(i = 0; i < l; i++) { if ((res[i] = unicode_get16(d + 2 * i)) == 0) return 0; } return l; case DECOMP_TYPE_LL1: case DECOMP_TYPE_LL2: { uint32_t k, p; l = type - DECOMP_TYPE_LL1 + 1; k = (c - code) * l; p = len * l * 2; for(i = 0; i < l; i++) { c1 = unicode_get16(d + 2 * k) | (((d[p + (k / 4)] >> ((k % 4) * 2)) & 3) << 16); if (!c1) return 0; res[i] = c1; k++; } } return l; case DECOMP_TYPE_S1: case DECOMP_TYPE_S2: case DECOMP_TYPE_S3: case DECOMP_TYPE_S4: case DECOMP_TYPE_S5: l = type - DECOMP_TYPE_S1 + 1; d += (c - code) * l; for(i = 0; i < l; i++) { if ((res[i] = unicode_get_short_code(d[i])) == 0) return 0; } return l; case DECOMP_TYPE_I1: l = 1; p = 0; goto decomp_type_i; case DECOMP_TYPE_I2_0: case DECOMP_TYPE_I2_1: case DECOMP_TYPE_I3_1: case DECOMP_TYPE_I3_2: case DECOMP_TYPE_I4_1: case DECOMP_TYPE_I4_2: l = 2 + ((type - DECOMP_TYPE_I2_0) >> 1); p = ((type - DECOMP_TYPE_I2_0) & 1) + (l > 2); decomp_type_i: for(i = 0; i < l; i++) { c1 = unicode_get16(d + 2 * i); if (i == p) c1 += c - code; res[i] = c1; } return l; case DECOMP_TYPE_B18: l = 18; goto decomp_type_b; case DECOMP_TYPE_B1: case DECOMP_TYPE_B2: case DECOMP_TYPE_B3: case DECOMP_TYPE_B4: case DECOMP_TYPE_B5: case DECOMP_TYPE_B6: case DECOMP_TYPE_B7: case DECOMP_TYPE_B8: l = type - DECOMP_TYPE_B1 + 1; decomp_type_b: { uint32_t c_min; c_min = unicode_get16(d); d += 2 + (c - code) * l; for(i = 0; i < l; i++) { c1 = d[i]; if (c1 == 0xff) c1 = 0x20; else c1 += c_min; res[i] = c1; } } return l; case DECOMP_TYPE_LS2: d += (c - code) * 3; if (!(res[0] = unicode_get16(d))) return 0; res[1] = unicode_get_short_code(d[2]); return 2; case DECOMP_TYPE_PAT3: res[0] = unicode_get16(d); res[2] = unicode_get16(d + 2); d += 4 + (c - code) * 2; res[1] = unicode_get16(d); return 3; case DECOMP_TYPE_S2_UL: case DECOMP_TYPE_LS2_UL: c1 = c - code; if (type == DECOMP_TYPE_S2_UL) { d += c1 & ~1; c = unicode_get_short_code(*d); d++; } else { d += (c1 >> 1) * 3; c = unicode_get16(d); d += 2; } if (c1 & 1) c = unicode_get_lower_simple(c); res[0] = c; res[1] = unicode_get_short_code(*d); return 2; } } return 0; } /* return the length of the decomposition (length <= UNICODE_DECOMP_LEN_MAX) or 0 if no decomposition */ static int unicode_decomp_char(uint32_t *res, uint32_t c, BOOL is_compat1) { uint32_t v, type, is_compat, code, len; int idx_min, idx_max, idx; idx_min = 0; idx_max = countof(unicode_decomp_table1) - 1; while (idx_min <= idx_max) { idx = (idx_max + idx_min) / 2; v = unicode_decomp_table1[idx]; code = v >> (32 - 18); len = (v >> (32 - 18 - 7)) & 0x7f; // printf("idx=%d code=%05x len=%d\n", idx, code, len); if (c < code) { idx_max = idx - 1; } else if (c >= code + len) { idx_min = idx + 1; } else { is_compat = v & 1; if (is_compat1 < is_compat) break; type = (v >> (32 - 18 - 7 - 6)) & 0x3f; return unicode_decomp_entry(res, c, idx, code, len, type); } } return 0; } /* return 0 if no pair found */ static int unicode_compose_pair(uint32_t c0, uint32_t c1) { uint32_t code, len, type, v, idx1, d_idx, d_offset, ch; int idx_min, idx_max, idx, d; uint32_t pair[2]; idx_min = 0; idx_max = countof(unicode_comp_table) - 1; while (idx_min <= idx_max) { idx = (idx_max + idx_min) / 2; idx1 = unicode_comp_table[idx]; /* idx1 represent an entry of the decomposition table */ d_idx = idx1 >> 6; d_offset = idx1 & 0x3f; v = unicode_decomp_table1[d_idx]; code = v >> (32 - 18); len = (v >> (32 - 18 - 7)) & 0x7f; type = (v >> (32 - 18 - 7 - 6)) & 0x3f; ch = code + d_offset; unicode_decomp_entry(pair, ch, d_idx, code, len, type); d = c0 - pair[0]; if (d == 0) d = c1 - pair[1]; if (d < 0) { idx_max = idx - 1; } else if (d > 0) { idx_min = idx + 1; } else { return ch; } } return 0; } /* return the combining class of character c (between 0 and 255) */ static int unicode_get_cc(uint32_t c) { uint32_t code, n, type, cc, c1, b; int pos; const uint8_t *p; pos = get_index_pos(&code, c, unicode_cc_index, sizeof(unicode_cc_index) / 3); if (pos < 0) return 0; p = unicode_cc_table + pos; /* Compressed run length encoding: - 2 high order bits are combining class type - 0:0, 1:230, 2:extra byte linear progression, 3:extra byte - 00..2F: range length (add 1) - 30..37: 3-bit range-length + 1 extra byte - 38..3F: 3-bit range-length + 2 extra byte */ for(;;) { b = *p++; type = b >> 6; n = b & 0x3f; if (n < 48) { } else if (n < 56) { n = (n - 48) << 8; n |= *p++; n += 48; } else { n = (n - 56) << 8; n |= *p++ << 8; n |= *p++; n += 48 + (1 << 11); } if (type <= 1) p++; c1 = code + n + 1; if (c < c1) { switch(type) { case 0: cc = p[-1]; break; case 1: cc = p[-1] + c - code; break; case 2: cc = 0; break; default: case 3: cc = 230; break; } return cc; } code = c1; } } static void sort_cc(int *buf, int len) { int i, j, k, cc, cc1, start, ch1; for(i = 0; i < len; i++) { cc = unicode_get_cc(buf[i]); if (cc != 0) { start = i; j = i + 1; while (j < len) { ch1 = buf[j]; cc1 = unicode_get_cc(ch1); if (cc1 == 0) break; k = j - 1; while (k >= start) { if (unicode_get_cc(buf[k]) <= cc1) break; buf[k + 1] = buf[k]; k--; } buf[k + 1] = ch1; j++; } #if 0 printf("cc:"); for(k = start; k < j; k++) { printf(" %3d", unicode_get_cc(buf[k])); } printf("\n"); #endif i = j; } } } static void to_nfd_rec(DynBuf *dbuf, const int *src, int src_len, int is_compat) { uint32_t c, v; int i, l; uint32_t res[UNICODE_DECOMP_LEN_MAX]; for(i = 0; i < src_len; i++) { c = src[i]; if (c >= 0xac00 && c < 0xd7a4) { /* Hangul decomposition */ c -= 0xac00; dbuf_put_u32(dbuf, 0x1100 + c / 588); dbuf_put_u32(dbuf, 0x1161 + (c % 588) / 28); v = c % 28; if (v != 0) dbuf_put_u32(dbuf, 0x11a7 + v); } else { l = unicode_decomp_char(res, c, is_compat); if (l) { to_nfd_rec(dbuf, (int *)res, l, is_compat); } else { dbuf_put_u32(dbuf, c); } } } } /* return 0 if not found */ static int compose_pair(uint32_t c0, uint32_t c1) { /* Hangul composition */ if (c0 >= 0x1100 && c0 < 0x1100 + 19 && c1 >= 0x1161 && c1 < 0x1161 + 21) { return 0xac00 + (c0 - 0x1100) * 588 + (c1 - 0x1161) * 28; } else if (c0 >= 0xac00 && c0 < 0xac00 + 11172 && (c0 - 0xac00) % 28 == 0 && c1 >= 0x11a7 && c1 < 0x11a7 + 28) { return c0 + c1 - 0x11a7; } else { return unicode_compose_pair(c0, c1); } } int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len, UnicodeNormalizationEnum n_type, void *opaque, DynBufReallocFunc *realloc_func) { int *buf, buf_len, i, p, starter_pos, cc, last_cc, out_len; BOOL is_compat; DynBuf dbuf_s, *dbuf = &dbuf_s; is_compat = n_type >> 1; dbuf_init2(dbuf, opaque, realloc_func); if (dbuf_claim(dbuf, sizeof(int) * src_len)) goto fail; /* common case: latin1 is unaffected by NFC */ if (n_type == UNICODE_NFC) { for(i = 0; i < src_len; i++) { if (src[i] >= 0x100) goto not_latin1; } buf = (int *)dbuf->buf; if (src_len != 0) memcpy(buf, src, src_len * sizeof(int)); *pdst = (uint32_t *)buf; return src_len; not_latin1: ; } to_nfd_rec(dbuf, (const int *)src, src_len, is_compat); if (dbuf_error(dbuf)) { fail: *pdst = NULL; return -1; } buf = (int *)dbuf->buf; buf_len = dbuf->size / sizeof(int); sort_cc(buf, buf_len); if (buf_len <= 1 || (n_type & 1) != 0) { /* NFD / NFKD */ *pdst = (uint32_t *)buf; return buf_len; } i = 1; out_len = 1; while (i < buf_len) { /* find the starter character and test if it is blocked from the character at 'i' */ last_cc = unicode_get_cc(buf[i]); starter_pos = out_len - 1; while (starter_pos >= 0) { cc = unicode_get_cc(buf[starter_pos]); if (cc == 0) break; if (cc >= last_cc) goto next; last_cc = 256; starter_pos--; } if (starter_pos >= 0 && (p = compose_pair(buf[starter_pos], buf[i])) != 0) { buf[starter_pos] = p; i++; } else { next: buf[out_len++] = buf[i++]; } } *pdst = (uint32_t *)buf; return out_len; } /* char ranges for various unicode properties */ static int unicode_find_name(const char *name_table, const char *name) { const char *p, *r; int pos; size_t name_len, len; p = name_table; pos = 0; name_len = strlen(name); while (*p) { for(;;) { r = strchr(p, ','); if (!r) len = strlen(p); else len = r - p; if (len == name_len && !memcmp(p, name, name_len)) return pos; p += len + 1; if (!r) break; } pos++; } return -1; } /* 'cr' must be initialized and empty. Return 0 if OK, -1 if error, -2 if not found */ int unicode_script(CharRange *cr, const char *script_name, BOOL is_ext) { int script_idx; const uint8_t *p, *p_end; uint32_t c, c1, b, n, v, v_len, i, type; CharRange cr1_s, *cr1; CharRange cr2_s, *cr2 = &cr2_s; BOOL is_common; script_idx = unicode_find_name(unicode_script_name_table, script_name); if (script_idx < 0) return -2; is_common = (script_idx == UNICODE_SCRIPT_Common || script_idx == UNICODE_SCRIPT_Inherited); if (is_ext) { cr1 = &cr1_s; cr_init(cr1, cr->mem_opaque, cr->realloc_func); cr_init(cr2, cr->mem_opaque, cr->realloc_func); } else { cr1 = cr; } p = unicode_script_table; p_end = unicode_script_table + countof(unicode_script_table); c = 0; while (p < p_end) { b = *p++; type = b >> 7; n = b & 0x7f; if (n < 96) { } else if (n < 112) { n = (n - 96) << 8; n |= *p++; n += 96; } else { n = (n - 112) << 16; n |= *p++ << 8; n |= *p++; n += 96 + (1 << 12); } c1 = c + n + 1; if (type != 0) { v = *p++; if (v == script_idx || script_idx == UNICODE_SCRIPT_Unknown) { if (cr_add_interval(cr1, c, c1)) goto fail; } } c = c1; } if (script_idx == UNICODE_SCRIPT_Unknown) { /* Unknown is all the characters outside scripts */ if (cr_invert(cr1)) goto fail; } if (is_ext) { /* add the script extensions */ p = unicode_script_ext_table; p_end = unicode_script_ext_table + countof(unicode_script_ext_table); c = 0; while (p < p_end) { b = *p++; if (b < 128) { n = b; } else if (b < 128 + 64) { n = (b - 128) << 8; n |= *p++; n += 128; } else { n = (b - 128 - 64) << 16; n |= *p++ << 8; n |= *p++; n += 128 + (1 << 14); } c1 = c + n + 1; v_len = *p++; if (is_common) { if (v_len != 0) { if (cr_add_interval(cr2, c, c1)) goto fail; } } else { for(i = 0; i < v_len; i++) { if (p[i] == script_idx) { if (cr_add_interval(cr2, c, c1)) goto fail; break; } } } p += v_len; c = c1; } if (is_common) { /* remove all the characters with script extensions */ if (cr_invert(cr2)) goto fail; if (cr_op(cr, cr1->points, cr1->len, cr2->points, cr2->len, CR_OP_INTER)) goto fail; } else { if (cr_op(cr, cr1->points, cr1->len, cr2->points, cr2->len, CR_OP_UNION)) goto fail; } cr_free(cr1); cr_free(cr2); } return 0; fail: if (is_ext) { cr_free(cr1); cr_free(cr2); } goto fail; } #define M(id) (1U << UNICODE_GC_ ## id) static int unicode_general_category1(CharRange *cr, uint32_t gc_mask) { const uint8_t *p, *p_end; uint32_t c, c0, b, n, v; p = unicode_gc_table; p_end = unicode_gc_table + countof(unicode_gc_table); c = 0; /* Compressed range encoding: initial byte: bits 0..4: category number (special case 31) bits 5..7: range length (add 1) special case bits 5..7 == 7: read an extra byte - 00..7F: range length (add 7 + 1) - 80..BF: 6-bits plus extra byte for range length (add 7 + 128) - C0..FF: 6-bits plus 2 extra bytes for range length (add 7 + 128 + 16384) */ while (p < p_end) { b = *p++; n = b >> 5; v = b & 0x1f; if (n == 7) { n = *p++; if (n < 128) { n += 7; } else if (n < 128 + 64) { n = (n - 128) << 8; n |= *p++; n += 7 + 128; } else { n = (n - 128 - 64) << 16; n |= *p++ << 8; n |= *p++; n += 7 + 128 + (1 << 14); } } c0 = c; c += n + 1; if (v == 31) { /* run of Lu / Ll */ b = gc_mask & (M(Lu) | M(Ll)); if (b != 0) { if (b == (M(Lu) | M(Ll))) { goto add_range; } else { c0 += ((gc_mask & M(Ll)) != 0); for(; c0 < c; c0 += 2) { if (cr_add_interval(cr, c0, c0 + 1)) return -1; } } } } else if ((gc_mask >> v) & 1) { add_range: if (cr_add_interval(cr, c0, c)) return -1; } } return 0; } static int unicode_prop1(CharRange *cr, int prop_idx) { const uint8_t *p, *p_end; uint32_t c, c0, b, bit; p = unicode_prop_table[prop_idx]; p_end = p + unicode_prop_len_table[prop_idx]; c = 0; bit = 0; /* Compressed range encoding: 00..3F: 2 packed lengths: 3-bit + 3-bit 40..5F: 5-bits plus extra byte for length 60..7F: 5-bits plus 2 extra bytes for length 80..FF: 7-bit length lengths must be incremented to get character count Ranges alternate between false and true return value. */ while (p < p_end) { c0 = c; b = *p++; if (b < 64) { c += (b >> 3) + 1; if (bit) { if (cr_add_interval(cr, c0, c)) return -1; } bit ^= 1; c0 = c; c += (b & 7) + 1; } else if (b >= 0x80) { c += b - 0x80 + 1; } else if (b < 0x60) { c += (((b - 0x40) << 8) | p[0]) + 1; p++; } else { c += (((b - 0x60) << 16) | (p[0] << 8) | p[1]) + 1; p += 2; } if (bit) { if (cr_add_interval(cr, c0, c)) return -1; } bit ^= 1; } return 0; } typedef enum { POP_GC, POP_PROP, POP_CASE, POP_UNION, POP_INTER, POP_XOR, POP_INVERT, POP_END, } PropOPEnum; #define POP_STACK_LEN_MAX 4 static int unicode_prop_ops(CharRange *cr, ...) { va_list ap; CharRange stack[POP_STACK_LEN_MAX]; int stack_len, op, ret, i; uint32_t a; va_start(ap, cr); stack_len = 0; for(;;) { op = va_arg(ap, int); switch(op) { case POP_GC: assert(stack_len < POP_STACK_LEN_MAX); a = va_arg(ap, int); cr_init(&stack[stack_len++], cr->mem_opaque, cr->realloc_func); if (unicode_general_category1(&stack[stack_len - 1], a)) goto fail; break; case POP_PROP: assert(stack_len < POP_STACK_LEN_MAX); a = va_arg(ap, int); cr_init(&stack[stack_len++], cr->mem_opaque, cr->realloc_func); if (unicode_prop1(&stack[stack_len - 1], a)) goto fail; break; case POP_CASE: assert(stack_len < POP_STACK_LEN_MAX); a = va_arg(ap, int); cr_init(&stack[stack_len++], cr->mem_opaque, cr->realloc_func); if (unicode_case1(&stack[stack_len - 1], a)) goto fail; break; case POP_UNION: case POP_INTER: case POP_XOR: { CharRange *cr1, *cr2, *cr3; assert(stack_len >= 2); assert(stack_len < POP_STACK_LEN_MAX); cr1 = &stack[stack_len - 2]; cr2 = &stack[stack_len - 1]; cr3 = &stack[stack_len++]; cr_init(cr3, cr->mem_opaque, cr->realloc_func); /* CR_OP_XOR may be used here */ if (cr_op(cr3, cr1->points, cr1->len, cr2->points, cr2->len, op - POP_UNION + CR_OP_UNION)) goto fail; cr_free(cr1); cr_free(cr2); *cr1 = *cr3; stack_len -= 2; } break; case POP_INVERT: assert(stack_len >= 1); if (cr_invert(&stack[stack_len - 1])) goto fail; break; case POP_END: goto done; default: abort(); } } done: assert(stack_len == 1); ret = cr_copy(cr, &stack[0]); cr_free(&stack[0]); return ret; fail: for(i = 0; i < stack_len; i++) cr_free(&stack[i]); return -1; } static const uint32_t unicode_gc_mask_table[] = { M(Lu) | M(Ll) | M(Lt), /* LC */ M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo), /* L */ M(Mn) | M(Mc) | M(Me), /* M */ M(Nd) | M(Nl) | M(No), /* N */ M(Sm) | M(Sc) | M(Sk) | M(So), /* S */ M(Pc) | M(Pd) | M(Ps) | M(Pe) | M(Pi) | M(Pf) | M(Po), /* P */ M(Zs) | M(Zl) | M(Zp), /* Z */ M(Cc) | M(Cf) | M(Cs) | M(Co) | M(Cn), /* C */ }; /* 'cr' must be initialized and empty. Return 0 if OK, -1 if error, -2 if not found */ int unicode_general_category(CharRange *cr, const char *gc_name) { int gc_idx; uint32_t gc_mask; gc_idx = unicode_find_name(unicode_gc_name_table, gc_name); if (gc_idx < 0) return -2; if (gc_idx <= UNICODE_GC_Co) { gc_mask = (uint64_t)1 << gc_idx; } else { gc_mask = unicode_gc_mask_table[gc_idx - UNICODE_GC_LC]; } return unicode_general_category1(cr, gc_mask); } /* 'cr' must be initialized and empty. Return 0 if OK, -1 if error, -2 if not found */ int unicode_prop(CharRange *cr, const char *prop_name) { int prop_idx, ret; prop_idx = unicode_find_name(unicode_prop_name_table, prop_name); if (prop_idx < 0) return -2; prop_idx += UNICODE_PROP_ASCII_Hex_Digit; ret = 0; switch(prop_idx) { case UNICODE_PROP_ASCII: if (cr_add_interval(cr, 0x00, 0x7f + 1)) return -1; break; case UNICODE_PROP_Any: if (cr_add_interval(cr, 0x00000, 0x10ffff + 1)) return -1; break; case UNICODE_PROP_Assigned: ret = unicode_prop_ops(cr, POP_GC, M(Cn), POP_INVERT, POP_END); break; case UNICODE_PROP_Math: ret = unicode_prop_ops(cr, POP_GC, M(Sm), POP_PROP, UNICODE_PROP_Other_Math, POP_UNION, POP_END); break; case UNICODE_PROP_Lowercase: ret = unicode_prop_ops(cr, POP_GC, M(Ll), POP_PROP, UNICODE_PROP_Other_Lowercase, POP_UNION, POP_END); break; case UNICODE_PROP_Uppercase: ret = unicode_prop_ops(cr, POP_GC, M(Lu), POP_PROP, UNICODE_PROP_Other_Uppercase, POP_UNION, POP_END); break; case UNICODE_PROP_Cased: ret = unicode_prop_ops(cr, POP_GC, M(Lu) | M(Ll) | M(Lt), POP_PROP, UNICODE_PROP_Other_Uppercase, POP_UNION, POP_PROP, UNICODE_PROP_Other_Lowercase, POP_UNION, POP_END); break; case UNICODE_PROP_Alphabetic: ret = unicode_prop_ops(cr, POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl), POP_PROP, UNICODE_PROP_Other_Uppercase, POP_UNION, POP_PROP, UNICODE_PROP_Other_Lowercase, POP_UNION, POP_PROP, UNICODE_PROP_Other_Alphabetic, POP_UNION, POP_END); break; case UNICODE_PROP_Grapheme_Base: ret = unicode_prop_ops(cr, POP_GC, M(Cc) | M(Cf) | M(Cs) | M(Co) | M(Cn) | M(Zl) | M(Zp) | M(Me) | M(Mn), POP_PROP, UNICODE_PROP_Other_Grapheme_Extend, POP_UNION, POP_INVERT, POP_END); break; case UNICODE_PROP_Grapheme_Extend: ret = unicode_prop_ops(cr, POP_GC, M(Me) | M(Mn), POP_PROP, UNICODE_PROP_Other_Grapheme_Extend, POP_UNION, POP_END); break; case UNICODE_PROP_XID_Start: ret = unicode_prop_ops(cr, POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl), POP_PROP, UNICODE_PROP_Other_ID_Start, POP_UNION, POP_PROP, UNICODE_PROP_Pattern_Syntax, POP_PROP, UNICODE_PROP_Pattern_White_Space, POP_UNION, POP_PROP, UNICODE_PROP_XID_Start1, POP_UNION, POP_INVERT, POP_INTER, POP_END); break; case UNICODE_PROP_XID_Continue: ret = unicode_prop_ops(cr, POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl) | M(Mn) | M(Mc) | M(Nd) | M(Pc), POP_PROP, UNICODE_PROP_Other_ID_Start, POP_UNION, POP_PROP, UNICODE_PROP_Other_ID_Continue, POP_UNION, POP_PROP, UNICODE_PROP_Pattern_Syntax, POP_PROP, UNICODE_PROP_Pattern_White_Space, POP_UNION, POP_PROP, UNICODE_PROP_XID_Continue1, POP_UNION, POP_INVERT, POP_INTER, POP_END); break; case UNICODE_PROP_Changes_When_Uppercased: ret = unicode_case1(cr, CASE_U); break; case UNICODE_PROP_Changes_When_Lowercased: ret = unicode_case1(cr, CASE_L); break; case UNICODE_PROP_Changes_When_Casemapped: ret = unicode_case1(cr, CASE_U | CASE_L | CASE_F); break; case UNICODE_PROP_Changes_When_Titlecased: ret = unicode_prop_ops(cr, POP_CASE, CASE_U, POP_PROP, UNICODE_PROP_Changes_When_Titlecased1, POP_XOR, POP_END); break; case UNICODE_PROP_Changes_When_Casefolded: ret = unicode_prop_ops(cr, POP_CASE, CASE_F, POP_PROP, UNICODE_PROP_Changes_When_Casefolded1, POP_XOR, POP_END); break; case UNICODE_PROP_Changes_When_NFKC_Casefolded: ret = unicode_prop_ops(cr, POP_CASE, CASE_F, POP_PROP, UNICODE_PROP_Changes_When_NFKC_Casefolded1, POP_XOR, POP_END); break; #if 0 case UNICODE_PROP_ID_Start: ret = unicode_prop_ops(cr, POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl), POP_PROP, UNICODE_PROP_Other_ID_Start, POP_UNION, POP_PROP, UNICODE_PROP_Pattern_Syntax, POP_PROP, UNICODE_PROP_Pattern_White_Space, POP_UNION, POP_INVERT, POP_INTER, POP_END); break; case UNICODE_PROP_ID_Continue: ret = unicode_prop_ops(cr, POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl) | M(Mn) | M(Mc) | M(Nd) | M(Pc), POP_PROP, UNICODE_PROP_Other_ID_Start, POP_UNION, POP_PROP, UNICODE_PROP_Other_ID_Continue, POP_UNION, POP_PROP, UNICODE_PROP_Pattern_Syntax, POP_PROP, UNICODE_PROP_Pattern_White_Space, POP_UNION, POP_INVERT, POP_INTER, POP_END); break; case UNICODE_PROP_Case_Ignorable: ret = unicode_prop_ops(cr, POP_GC, M(Mn) | M(Cf) | M(Lm) | M(Sk), POP_PROP, UNICODE_PROP_Case_Ignorable1, POP_XOR, POP_END); break; #else /* we use the existing tables */ case UNICODE_PROP_ID_Continue: ret = unicode_prop_ops(cr, POP_PROP, UNICODE_PROP_ID_Start, POP_PROP, UNICODE_PROP_ID_Continue1, POP_XOR, POP_END); break; #endif default: if (prop_idx >= countof(unicode_prop_table)) return -2; ret = unicode_prop1(cr, prop_idx); break; } return ret; } #endif /* CONFIG_ALL_UNICODE */ /*---- lre codepoint categorizing functions ----*/ #define S UNICODE_C_SPACE #define D UNICODE_C_DIGIT #define X UNICODE_C_XDIGIT #define U UNICODE_C_UPPER #define L UNICODE_C_LOWER #define _ UNICODE_C_UNDER #define d UNICODE_C_DOLLAR uint8_t const lre_ctype_bits[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, S, S, S, S, S, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, S, 0, 0, 0, d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X|D, X|D, X|D, X|D, X|D, X|D, X|D, X|D, X|D, X|D, 0, 0, 0, 0, 0, 0, 0, X|U, X|U, X|U, X|U, X|U, X|U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, 0, 0, 0, 0, _, 0, X|L, X|L, X|L, X|L, X|L, X|L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, S, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; #undef S #undef D #undef X #undef U #undef L #undef _ #undef d /* code point ranges for Zs,Zl or Zp property */ static const uint16_t char_range_s[] = { 10, 0x0009, 0x000D + 1, 0x0020, 0x0020 + 1, 0x00A0, 0x00A0 + 1, 0x1680, 0x1680 + 1, 0x2000, 0x200A + 1, /* 2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;; */ /* 2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;; */ 0x2028, 0x2029 + 1, 0x202F, 0x202F + 1, 0x205F, 0x205F + 1, 0x3000, 0x3000 + 1, /* FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;; */ 0xFEFF, 0xFEFF + 1, }; BOOL lre_is_space_non_ascii(uint32_t c) { size_t i, n; n = countof(char_range_s); for(i = 5; i < n; i += 2) { uint32_t low = char_range_s[i]; uint32_t high = char_range_s[i + 1]; if (c < low) return FALSE; if (c < high) return TRUE; } return FALSE; } #define SEQ_MAX_LEN 16 static int unicode_sequence_prop1(int seq_prop_idx, UnicodeSequencePropCB *cb, void *opaque, CharRange *cr) { int i, c, j; uint32_t seq[SEQ_MAX_LEN]; switch(seq_prop_idx) { case UNICODE_SEQUENCE_PROP_Basic_Emoji: if (unicode_prop1(cr, UNICODE_PROP_Basic_Emoji1) < 0) return -1; for(i = 0; i < cr->len; i += 2) { for(c = cr->points[i]; c < cr->points[i + 1]; c++) { seq[0] = c; cb(opaque, seq, 1); } } cr->len = 0; if (unicode_prop1(cr, UNICODE_PROP_Basic_Emoji2) < 0) return -1; for(i = 0; i < cr->len; i += 2) { for(c = cr->points[i]; c < cr->points[i + 1]; c++) { seq[0] = c; seq[1] = 0xfe0f; cb(opaque, seq, 2); } } break; case UNICODE_SEQUENCE_PROP_RGI_Emoji_Modifier_Sequence: if (unicode_prop1(cr, UNICODE_PROP_Emoji_Modifier_Base) < 0) return -1; for(i = 0; i < cr->len; i += 2) { for(c = cr->points[i]; c < cr->points[i + 1]; c++) { for(j = 0; j < 5; j++) { seq[0] = c; seq[1] = 0x1f3fb + j; cb(opaque, seq, 2); } } } break; case UNICODE_SEQUENCE_PROP_RGI_Emoji_Flag_Sequence: if (unicode_prop1(cr, UNICODE_PROP_RGI_Emoji_Flag_Sequence) < 0) return -1; for(i = 0; i < cr->len; i += 2) { for(c = cr->points[i]; c < cr->points[i + 1]; c++) { int c0, c1; c0 = c / 26; c1 = c % 26; seq[0] = 0x1F1E6 + c0; seq[1] = 0x1F1E6 + c1; cb(opaque, seq, 2); } } break; case UNICODE_SEQUENCE_PROP_RGI_Emoji_ZWJ_Sequence: { int len, code, pres, k, mod, mod_count, mod_pos[2], hc_pos, n_mod, n_hc, mod1; int mod_idx, hc_idx, i0, i1; const uint8_t *tab = unicode_rgi_emoji_zwj_sequence; for(i = 0; i < countof(unicode_rgi_emoji_zwj_sequence);) { len = tab[i++]; k = 0; mod = 0; mod_count = 0; hc_pos = -1; for(j = 0; j < len; j++) { code = tab[i++]; code |= tab[i++] << 8; pres = code >> 15; mod1 = (code >> 13) & 3; code &= 0x1fff; if (code < 0x1000) { c = code + 0x2000; } else { c = 0x1f000 + (code - 0x1000); } if (c == 0x1f9b0) hc_pos = k; seq[k++] = c; if (mod1 != 0) { assert(mod_count < 2); mod = mod1; mod_pos[mod_count++] = k; seq[k++] = 0; /* will be filled later */ } if (pres) { seq[k++] = 0xfe0f; } if (j < len - 1) { seq[k++] = 0x200d; } } /* genrate all the variants */ switch(mod) { case 1: n_mod = 5; break; case 2: n_mod = 25; break; case 3: n_mod = 20; break; default: n_mod = 1; break; } if (hc_pos >= 0) n_hc = 4; else n_hc = 1; for(hc_idx = 0; hc_idx < n_hc; hc_idx++) { for(mod_idx = 0; mod_idx < n_mod; mod_idx++) { if (hc_pos >= 0) seq[hc_pos] = 0x1f9b0 + hc_idx; switch(mod) { case 1: seq[mod_pos[0]] = 0x1f3fb + mod_idx; break; case 2: case 3: i0 = mod_idx / 5; i1 = mod_idx % 5; /* avoid identical values */ if (mod == 3 && i0 >= i1) i0++; seq[mod_pos[0]] = 0x1f3fb + i0; seq[mod_pos[1]] = 0x1f3fb + i1; break; default: break; } #if 0 for(j = 0; j < k; j++) printf(" %04x", seq[j]); printf("\n"); #endif cb(opaque, seq, k); } } } } break; case UNICODE_SEQUENCE_PROP_RGI_Emoji_Tag_Sequence: { for(i = 0; i < countof(unicode_rgi_emoji_tag_sequence);) { j = 0; seq[j++] = 0x1F3F4; for(;;) { c = unicode_rgi_emoji_tag_sequence[i++]; if (c == 0x00) break; seq[j++] = 0xe0000 + c; } seq[j++] = 0xe007f; cb(opaque, seq, j); } } break; case UNICODE_SEQUENCE_PROP_Emoji_Keycap_Sequence: if (unicode_prop1(cr, UNICODE_PROP_Emoji_Keycap_Sequence) < 0) return -1; for(i = 0; i < cr->len; i += 2) { for(c = cr->points[i]; c < cr->points[i + 1]; c++) { seq[0] = c; seq[1] = 0xfe0f; seq[2] = 0x20e3; cb(opaque, seq, 3); } } break; case UNICODE_SEQUENCE_PROP_RGI_Emoji: /* all prevous sequences */ for(i = UNICODE_SEQUENCE_PROP_Basic_Emoji; i <= UNICODE_SEQUENCE_PROP_RGI_Emoji_ZWJ_Sequence; i++) { int ret; ret = unicode_sequence_prop1(i, cb, opaque, cr); if (ret < 0) return ret; cr->len = 0; } break; default: return -2; } return 0; } /* build a unicode sequence property */ /* return -2 if not found, -1 if other error. 'cr' is used as temporary memory. */ int unicode_sequence_prop(const char *prop_name, UnicodeSequencePropCB *cb, void *opaque, CharRange *cr) { int seq_prop_idx; seq_prop_idx = unicode_find_name(unicode_sequence_prop_name_table, prop_name); if (seq_prop_idx < 0) return -2; return unicode_sequence_prop1(seq_prop_idx, cb, opaque, cr); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/qjs/libunicode.h�����������������������������������������������0000664�0000000�0000000�00000013533�15202323131�0022472�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Unicode utilities * * Copyright (c) 2017-2018 Fabrice Bellard * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #ifndef LIBUNICODE_H #define LIBUNICODE_H #include <stdint.h> /* unicode standard version */ #define LIBUNICODE_UNICODE_VERSION_MAJOR 17 #define LIBUNICODE_UNICODE_VERSION_MINOR 0 #define LIBUNICODE_UNICODE_VERSION_PATCH 0 /* define it to include all the unicode tables (40KB larger) */ #define CONFIG_ALL_UNICODE #define LRE_CC_RES_LEN_MAX 3 /* char ranges */ typedef struct { int len; /* in points, always even */ int size; uint32_t *points; /* points sorted by increasing value */ void *mem_opaque; void *(*realloc_func)(void *opaque, void *ptr, size_t size); } CharRange; typedef enum { CR_OP_UNION, CR_OP_INTER, CR_OP_XOR, CR_OP_SUB, } CharRangeOpEnum; void cr_init(CharRange *cr, void *mem_opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size)); void cr_free(CharRange *cr); int cr_realloc(CharRange *cr, int size); int cr_copy(CharRange *cr, const CharRange *cr1); static inline int cr_add_point(CharRange *cr, uint32_t v) { if (cr->len >= cr->size) { if (cr_realloc(cr, cr->len + 1)) return -1; } cr->points[cr->len++] = v; return 0; } static inline int cr_add_interval(CharRange *cr, uint32_t c1, uint32_t c2) { if ((cr->len + 2) > cr->size) { if (cr_realloc(cr, cr->len + 2)) return -1; } cr->points[cr->len++] = c1; cr->points[cr->len++] = c2; return 0; } int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len, const uint32_t *b_pt, int b_len, int op); int cr_op1(CharRange *cr, const uint32_t *b_pt, int b_len, int op); static inline int cr_union_interval(CharRange *cr, uint32_t c1, uint32_t c2) { uint32_t b_pt[2]; b_pt[0] = c1; b_pt[1] = c2 + 1; return cr_op1(cr, b_pt, 2, CR_OP_UNION); } int cr_invert(CharRange *cr); int cr_regexp_canonicalize(CharRange *cr, int is_unicode); typedef enum { UNICODE_NFC, UNICODE_NFD, UNICODE_NFKC, UNICODE_NFKD, } UnicodeNormalizationEnum; int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len, UnicodeNormalizationEnum n_type, void *opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size)); /* Unicode character range functions */ int unicode_script(CharRange *cr, const char *script_name, int is_ext); int unicode_general_category(CharRange *cr, const char *gc_name); int unicode_prop(CharRange *cr, const char *prop_name); typedef void UnicodeSequencePropCB(void *opaque, const uint32_t *buf, int len); int unicode_sequence_prop(const char *prop_name, UnicodeSequencePropCB *cb, void *opaque, CharRange *cr); int lre_case_conv(uint32_t *res, uint32_t c, int conv_type); int lre_canonicalize(uint32_t c, int is_unicode); /* Code point type categories */ enum { UNICODE_C_SPACE = (1 << 0), UNICODE_C_DIGIT = (1 << 1), UNICODE_C_UPPER = (1 << 2), UNICODE_C_LOWER = (1 << 3), UNICODE_C_UNDER = (1 << 4), UNICODE_C_DOLLAR = (1 << 5), UNICODE_C_XDIGIT = (1 << 6), }; extern uint8_t const lre_ctype_bits[256]; /* zero or non-zero return value */ int lre_is_cased(uint32_t c); int lre_is_case_ignorable(uint32_t c); int lre_is_id_start(uint32_t c); int lre_is_id_continue(uint32_t c); static inline int lre_is_space_byte(uint8_t c) { return lre_ctype_bits[c] & UNICODE_C_SPACE; } static inline int lre_is_id_start_byte(uint8_t c) { return lre_ctype_bits[c] & (UNICODE_C_UPPER | UNICODE_C_LOWER | UNICODE_C_UNDER | UNICODE_C_DOLLAR); } static inline int lre_is_id_continue_byte(uint8_t c) { return lre_ctype_bits[c] & (UNICODE_C_UPPER | UNICODE_C_LOWER | UNICODE_C_UNDER | UNICODE_C_DOLLAR | UNICODE_C_DIGIT); } static inline int lre_is_word_byte(uint8_t c) { return lre_ctype_bits[c] & (UNICODE_C_UPPER | UNICODE_C_LOWER | UNICODE_C_UNDER | UNICODE_C_DIGIT); } int lre_is_space_non_ascii(uint32_t c); static inline int lre_is_space(uint32_t c) { if (c < 256) return lre_is_space_byte(c); else return lre_is_space_non_ascii(c); } static inline int lre_js_is_ident_first(uint32_t c) { if (c < 128) { return lre_is_id_start_byte(c); } else { #ifdef CONFIG_ALL_UNICODE return lre_is_id_start(c); #else return !lre_is_space_non_ascii(c); #endif } } static inline int lre_js_is_ident_next(uint32_t c) { if (c < 128) { return lre_is_id_continue_byte(c); } else { /* ZWNJ and ZWJ are accepted in identifiers */ if (c >= 0x200C && c <= 0x200D) return TRUE; #ifdef CONFIG_ALL_UNICODE return lre_is_id_continue(c); #else return !lre_is_space_non_ascii(c); #endif } } #endif /* LIBUNICODE_H */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/qjs/list.h�����������������������������������������������������0000664�0000000�0000000�00000006021�15202323131�0021322�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Linux klist like system * * Copyright (c) 2016-2017 Fabrice Bellard * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #ifndef LIST_H #define LIST_H #ifndef NULL #include <stddef.h> #endif struct list_head { struct list_head *prev; struct list_head *next; }; #define LIST_HEAD_INIT(el) { &(el), &(el) } /* return the pointer of type 'type *' containing 'el' as field 'member' */ #define list_entry(el, type, member) container_of(el, type, member) static inline void init_list_head(struct list_head *head) { head->prev = head; head->next = head; } /* insert 'el' between 'prev' and 'next' */ static inline void __list_add(struct list_head *el, struct list_head *prev, struct list_head *next) { prev->next = el; el->prev = prev; el->next = next; next->prev = el; } /* add 'el' at the head of the list 'head' (= after element head) */ static inline void list_add(struct list_head *el, struct list_head *head) { __list_add(el, head, head->next); } /* add 'el' at the end of the list 'head' (= before element head) */ static inline void list_add_tail(struct list_head *el, struct list_head *head) { __list_add(el, head->prev, head); } static inline void list_del(struct list_head *el) { struct list_head *prev, *next; prev = el->prev; next = el->next; prev->next = next; next->prev = prev; el->prev = NULL; /* fail safe */ el->next = NULL; /* fail safe */ } static inline int list_empty(struct list_head *el) { return el->next == el; } #define list_for_each(el, head) \ for(el = (head)->next; el != (head); el = el->next) #define list_for_each_safe(el, el1, head) \ for(el = (head)->next, el1 = el->next; el != (head); \ el = el1, el1 = el->next) #define list_for_each_prev(el, head) \ for(el = (head)->prev; el != (head); el = el->prev) #define list_for_each_prev_safe(el, el1, head) \ for(el = (head)->prev, el1 = el->prev; el != (head); \ el = el1, el1 = el->prev) #endif /* LIST_H */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/qjs/quickjs-atom.h���������������������������������������������0000664�0000000�0000000�00000020001�15202323131�0022750�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * QuickJS atom definitions * * Copyright (c) 2017-2018 Fabrice Bellard * Copyright (c) 2017-2018 Charlie Gordon * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #ifdef DEF /* Note: first atoms are considered as keywords in the parser */ DEF(null, "null") /* must be first */ DEF(false, "false") DEF(true, "true") DEF(if, "if") DEF(else, "else") DEF(return, "return") DEF(var, "var") DEF(this, "this") DEF(delete, "delete") DEF(void, "void") DEF(typeof, "typeof") DEF(new, "new") DEF(in, "in") DEF(instanceof, "instanceof") DEF(do, "do") DEF(while, "while") DEF(for, "for") DEF(break, "break") DEF(continue, "continue") DEF(switch, "switch") DEF(case, "case") DEF(default, "default") DEF(throw, "throw") DEF(try, "try") DEF(catch, "catch") DEF(finally, "finally") DEF(function, "function") DEF(debugger, "debugger") DEF(with, "with") /* FutureReservedWord */ DEF(class, "class") DEF(const, "const") DEF(enum, "enum") DEF(export, "export") DEF(extends, "extends") DEF(import, "import") DEF(super, "super") /* FutureReservedWords when parsing strict mode code */ DEF(implements, "implements") DEF(interface, "interface") DEF(let, "let") DEF(package, "package") DEF(private, "private") DEF(protected, "protected") DEF(public, "public") DEF(static, "static") DEF(yield, "yield") DEF(await, "await") /* empty string */ DEF(empty_string, "") /* identifiers */ DEF(keys, "keys") DEF(size, "size") DEF(length, "length") DEF(fileName, "fileName") DEF(lineNumber, "lineNumber") DEF(columnNumber, "columnNumber") DEF(message, "message") DEF(cause, "cause") DEF(errors, "errors") DEF(stack, "stack") DEF(name, "name") DEF(toString, "toString") DEF(toLocaleString, "toLocaleString") DEF(valueOf, "valueOf") DEF(eval, "eval") DEF(prototype, "prototype") DEF(constructor, "constructor") DEF(configurable, "configurable") DEF(writable, "writable") DEF(enumerable, "enumerable") DEF(value, "value") DEF(get, "get") DEF(set, "set") DEF(of, "of") DEF(__proto__, "__proto__") DEF(undefined, "undefined") DEF(number, "number") DEF(boolean, "boolean") DEF(string, "string") DEF(object, "object") DEF(symbol, "symbol") DEF(integer, "integer") DEF(unknown, "unknown") DEF(arguments, "arguments") DEF(callee, "callee") DEF(caller, "caller") DEF(_eval_, "<eval>") DEF(_ret_, "<ret>") DEF(_var_, "<var>") DEF(_arg_var_, "<arg_var>") DEF(_with_, "<with>") DEF(lastIndex, "lastIndex") DEF(target, "target") DEF(index, "index") DEF(input, "input") DEF(defineProperties, "defineProperties") DEF(apply, "apply") DEF(join, "join") DEF(concat, "concat") DEF(split, "split") DEF(construct, "construct") DEF(getPrototypeOf, "getPrototypeOf") DEF(setPrototypeOf, "setPrototypeOf") DEF(isExtensible, "isExtensible") DEF(preventExtensions, "preventExtensions") DEF(has, "has") DEF(deleteProperty, "deleteProperty") DEF(defineProperty, "defineProperty") DEF(getOwnPropertyDescriptor, "getOwnPropertyDescriptor") DEF(ownKeys, "ownKeys") DEF(add, "add") DEF(done, "done") DEF(next, "next") DEF(values, "values") DEF(source, "source") DEF(flags, "flags") DEF(global, "global") DEF(unicode, "unicode") DEF(raw, "raw") DEF(rawJSON, "rawJSON") DEF(new_target, "new.target") DEF(this_active_func, "this.active_func") DEF(home_object, "<home_object>") DEF(computed_field, "<computed_field>") DEF(static_computed_field, "<static_computed_field>") /* must come after computed_fields */ DEF(class_fields_init, "<class_fields_init>") DEF(brand, "<brand>") DEF(hash_constructor, "#constructor") DEF(as, "as") DEF(from, "from") DEF(meta, "meta") DEF(_default_, "*default*") DEF(_star_, "*") DEF(Module, "Module") DEF(then, "then") DEF(resolve, "resolve") DEF(reject, "reject") DEF(promise, "promise") DEF(proxy, "proxy") DEF(revoke, "revoke") DEF(async, "async") DEF(exec, "exec") DEF(groups, "groups") DEF(indices, "indices") DEF(status, "status") DEF(reason, "reason") DEF(globalThis, "globalThis") DEF(bigint, "bigint") DEF(minus_zero, "-0") DEF(Infinity, "Infinity") DEF(minus_Infinity, "-Infinity") DEF(NaN, "NaN") DEF(hasIndices, "hasIndices") DEF(ignoreCase, "ignoreCase") DEF(multiline, "multiline") DEF(dotAll, "dotAll") DEF(sticky, "sticky") DEF(unicodeSets, "unicodeSets") /* the following 3 atoms are only used with CONFIG_ATOMICS */ DEF(not_equal, "not-equal") DEF(timed_out, "timed-out") DEF(ok, "ok") DEF(toISOString, "toISOString") /* */ DEF(toJSON, "toJSON") DEF(maxByteLength, "maxByteLength") /* class names */ DEF(Object, "Object") DEF(Array, "Array") DEF(Error, "Error") DEF(Number, "Number") DEF(String, "String") DEF(Boolean, "Boolean") DEF(Symbol, "Symbol") DEF(Arguments, "Arguments") DEF(Math, "Math") DEF(JSON, "JSON") DEF(Date, "Date") DEF(Function, "Function") DEF(GeneratorFunction, "GeneratorFunction") DEF(ForInIterator, "ForInIterator") DEF(RegExp, "RegExp") DEF(ArrayBuffer, "ArrayBuffer") DEF(SharedArrayBuffer, "SharedArrayBuffer") /* must keep same order as class IDs for typed arrays */ DEF(Uint8ClampedArray, "Uint8ClampedArray") DEF(Int8Array, "Int8Array") DEF(Uint8Array, "Uint8Array") DEF(Int16Array, "Int16Array") DEF(Uint16Array, "Uint16Array") DEF(Int32Array, "Int32Array") DEF(Uint32Array, "Uint32Array") DEF(BigInt64Array, "BigInt64Array") DEF(BigUint64Array, "BigUint64Array") DEF(Float16Array, "Float16Array") DEF(Float32Array, "Float32Array") DEF(Float64Array, "Float64Array") DEF(DataView, "DataView") DEF(BigInt, "BigInt") DEF(WeakRef, "WeakRef") DEF(FinalizationRegistry, "FinalizationRegistry") DEF(Map, "Map") DEF(Set, "Set") /* Map + 1 */ DEF(WeakMap, "WeakMap") /* Map + 2 */ DEF(WeakSet, "WeakSet") /* Map + 3 */ DEF(Iterator, "Iterator") DEF(IteratorHelper, "Iterator Helper") DEF(IteratorConcat, "Iterator Concat") DEF(IteratorWrap, "Iterator Wrap") DEF(Map_Iterator, "Map Iterator") DEF(Set_Iterator, "Set Iterator") DEF(Array_Iterator, "Array Iterator") DEF(String_Iterator, "String Iterator") DEF(RegExp_String_Iterator, "RegExp String Iterator") DEF(Generator, "Generator") DEF(Proxy, "Proxy") DEF(Promise, "Promise") DEF(PromiseResolveFunction, "PromiseResolveFunction") DEF(PromiseRejectFunction, "PromiseRejectFunction") DEF(AsyncFunction, "AsyncFunction") DEF(AsyncFunctionResolve, "AsyncFunctionResolve") DEF(AsyncFunctionReject, "AsyncFunctionReject") DEF(AsyncGeneratorFunction, "AsyncGeneratorFunction") DEF(AsyncGenerator, "AsyncGenerator") DEF(EvalError, "EvalError") DEF(RangeError, "RangeError") DEF(ReferenceError, "ReferenceError") DEF(SyntaxError, "SyntaxError") DEF(TypeError, "TypeError") DEF(URIError, "URIError") DEF(InternalError, "InternalError") DEF(AggregateError, "AggregateError") /* private symbols */ DEF(Private_brand, "<brand>") /* symbols */ DEF(Symbol_toPrimitive, "Symbol.toPrimitive") DEF(Symbol_iterator, "Symbol.iterator") DEF(Symbol_match, "Symbol.match") DEF(Symbol_matchAll, "Symbol.matchAll") DEF(Symbol_replace, "Symbol.replace") DEF(Symbol_search, "Symbol.search") DEF(Symbol_split, "Symbol.split") DEF(Symbol_toStringTag, "Symbol.toStringTag") DEF(Symbol_isConcatSpreadable, "Symbol.isConcatSpreadable") DEF(Symbol_hasInstance, "Symbol.hasInstance") DEF(Symbol_species, "Symbol.species") DEF(Symbol_unscopables, "Symbol.unscopables") DEF(Symbol_asyncIterator, "Symbol.asyncIterator") #endif /* DEF */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/qjs/quickjs-opcode.h�������������������������������������������0000664�0000000�0000000�00000036671�15202323131�0023305�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * QuickJS opcode definitions * * Copyright (c) 2017-2018 Fabrice Bellard * Copyright (c) 2017-2018 Charlie Gordon * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #ifdef FMT FMT(none) FMT(none_int) FMT(none_loc) FMT(none_arg) FMT(none_var_ref) FMT(u8) FMT(i8) FMT(loc8) FMT(const8) FMT(label8) FMT(u16) FMT(i16) FMT(label16) FMT(npop) FMT(npopx) FMT(npop_u16) FMT(loc) FMT(arg) FMT(var_ref) FMT(u32) FMT(i32) FMT(const) FMT(label) FMT(atom) FMT(atom_u8) FMT(atom_u16) FMT(atom_label_u8) FMT(atom_label_u16) FMT(label_u16) #undef FMT #endif /* FMT */ #ifdef DEF #ifndef def #define def(id, size, n_pop, n_push, f) DEF(id, size, n_pop, n_push, f) #endif DEF(invalid, 1, 0, 0, none) /* never emitted */ /* push values */ DEF( push_i32, 5, 0, 1, i32) DEF( push_const, 5, 0, 1, const) DEF( fclosure, 5, 0, 1, const) /* must follow push_const */ DEF(push_atom_value, 5, 0, 1, atom) DEF( private_symbol, 5, 0, 1, atom) DEF( undefined, 1, 0, 1, none) DEF( null, 1, 0, 1, none) DEF( push_this, 1, 0, 1, none) /* only used at the start of a function */ DEF( push_false, 1, 0, 1, none) DEF( push_true, 1, 0, 1, none) DEF( object, 1, 0, 1, none) DEF( special_object, 2, 0, 1, u8) /* only used at the start of a function */ DEF( rest, 3, 0, 1, u16) /* only used at the start of a function */ DEF( drop, 1, 1, 0, none) /* a -> */ DEF( nip, 1, 2, 1, none) /* a b -> b */ DEF( nip1, 1, 3, 2, none) /* a b c -> b c */ DEF( dup, 1, 1, 2, none) /* a -> a a */ DEF( dup1, 1, 2, 3, none) /* a b -> a a b */ DEF( dup2, 1, 2, 4, none) /* a b -> a b a b */ DEF( dup3, 1, 3, 6, none) /* a b c -> a b c a b c */ DEF( insert2, 1, 2, 3, none) /* obj a -> a obj a (dup_x1) */ DEF( insert3, 1, 3, 4, none) /* obj prop a -> a obj prop a (dup_x2) */ DEF( insert4, 1, 4, 5, none) /* this obj prop a -> a this obj prop a */ DEF( perm3, 1, 3, 3, none) /* obj a b -> a obj b */ DEF( perm4, 1, 4, 4, none) /* obj prop a b -> a obj prop b */ DEF( perm5, 1, 5, 5, none) /* this obj prop a b -> a this obj prop b */ DEF( swap, 1, 2, 2, none) /* a b -> b a */ DEF( swap2, 1, 4, 4, none) /* a b c d -> c d a b */ DEF( rot3l, 1, 3, 3, none) /* x a b -> a b x */ DEF( rot3r, 1, 3, 3, none) /* a b x -> x a b */ DEF( rot4l, 1, 4, 4, none) /* x a b c -> a b c x */ DEF( rot5l, 1, 5, 5, none) /* x a b c d -> a b c d x */ DEF(call_constructor, 3, 2, 1, npop) /* func new.target args -> ret. arguments are not counted in n_pop */ DEF( call, 3, 1, 1, npop) /* arguments are not counted in n_pop */ DEF( tail_call, 3, 1, 0, npop) /* arguments are not counted in n_pop */ DEF( call_method, 3, 2, 1, npop) /* arguments are not counted in n_pop */ DEF(tail_call_method, 3, 2, 0, npop) /* arguments are not counted in n_pop */ DEF( array_from, 3, 0, 1, npop) /* arguments are not counted in n_pop */ DEF( apply, 3, 3, 1, u16) DEF( return, 1, 1, 0, none) DEF( return_undef, 1, 0, 0, none) DEF(check_ctor_return, 1, 1, 2, none) DEF( check_ctor, 1, 0, 0, none) DEF( init_ctor, 1, 0, 1, none) DEF( check_brand, 1, 2, 2, none) /* this_obj func -> this_obj func */ DEF( add_brand, 1, 2, 0, none) /* this_obj home_obj -> */ DEF( return_async, 1, 1, 0, none) DEF( throw, 1, 1, 0, none) DEF( throw_error, 6, 0, 0, atom_u8) DEF( eval, 5, 1, 1, npop_u16) /* func args... -> ret_val */ DEF( apply_eval, 3, 2, 1, u16) /* func array -> ret_eval */ DEF( regexp, 1, 2, 1, none) /* create a RegExp object from the pattern and a bytecode string */ DEF( get_super, 1, 1, 1, none) DEF( import, 1, 2, 1, none) /* dynamic module import */ DEF( get_var_undef, 3, 0, 1, var_ref) /* push undefined if the variable does not exist */ DEF( get_var, 3, 0, 1, var_ref) /* throw an exception if the variable does not exist */ DEF( put_var, 3, 1, 0, var_ref) /* must come after get_var */ DEF( put_var_init, 3, 1, 0, var_ref) /* must come after put_var. Used to initialize a global lexical variable */ DEF( get_ref_value, 1, 2, 3, none) DEF( put_ref_value, 1, 3, 0, none) DEF( get_field, 5, 1, 1, atom) DEF( get_field2, 5, 1, 2, atom) DEF( put_field, 5, 2, 0, atom) DEF( get_private_field, 1, 2, 1, none) /* obj prop -> value */ DEF( put_private_field, 1, 3, 0, none) /* obj value prop -> */ DEF(define_private_field, 1, 3, 1, none) /* obj prop value -> obj */ DEF( get_array_el, 1, 2, 1, none) DEF( get_array_el2, 1, 2, 2, none) /* obj prop -> obj value */ DEF( get_array_el3, 1, 2, 3, none) /* obj prop -> obj prop1 value */ DEF( put_array_el, 1, 3, 0, none) DEF(get_super_value, 1, 3, 1, none) /* this obj prop -> value */ DEF(put_super_value, 1, 4, 0, none) /* this obj prop value -> */ DEF( define_field, 5, 2, 1, atom) DEF( set_name, 5, 1, 1, atom) DEF(set_name_computed, 1, 2, 2, none) DEF( set_proto, 1, 2, 1, none) DEF(set_home_object, 1, 2, 2, none) DEF(define_array_el, 1, 3, 2, none) DEF( append, 1, 3, 2, none) /* append enumerated object, update length */ DEF(copy_data_properties, 2, 3, 3, u8) DEF( define_method, 6, 2, 1, atom_u8) DEF(define_method_computed, 2, 3, 1, u8) /* must come after define_method */ DEF( define_class, 6, 2, 2, atom_u8) /* parent ctor -> ctor proto */ DEF( define_class_computed, 6, 3, 3, atom_u8) /* field_name parent ctor -> field_name ctor proto (class with computed name) */ DEF( get_loc, 3, 0, 1, loc) DEF( put_loc, 3, 1, 0, loc) /* must come after get_loc */ DEF( set_loc, 3, 1, 1, loc) /* must come after put_loc */ DEF( get_arg, 3, 0, 1, arg) DEF( put_arg, 3, 1, 0, arg) /* must come after get_arg */ DEF( set_arg, 3, 1, 1, arg) /* must come after put_arg */ DEF( get_var_ref, 3, 0, 1, var_ref) DEF( put_var_ref, 3, 1, 0, var_ref) /* must come after get_var_ref */ DEF( set_var_ref, 3, 1, 1, var_ref) /* must come after put_var_ref */ DEF(set_loc_uninitialized, 3, 0, 0, loc) DEF( get_loc_check, 3, 0, 1, loc) DEF( put_loc_check, 3, 1, 0, loc) /* must come after get_loc_check */ DEF( set_loc_check, 3, 1, 1, loc) /* must come after put_loc_check */ DEF( put_loc_check_init, 3, 1, 0, loc) DEF(get_loc_checkthis, 3, 0, 1, loc) DEF(get_var_ref_check, 3, 0, 1, var_ref) DEF(put_var_ref_check, 3, 1, 0, var_ref) /* must come after get_var_ref_check */ DEF(put_var_ref_check_init, 3, 1, 0, var_ref) DEF( close_loc, 3, 0, 0, loc) DEF( if_false, 5, 1, 0, label) DEF( if_true, 5, 1, 0, label) /* must come after if_false */ DEF( goto, 5, 0, 0, label) /* must come after if_true */ DEF( catch, 5, 0, 1, label) DEF( gosub, 5, 0, 0, label) /* used to execute the finally block */ DEF( ret, 1, 1, 0, none) /* used to return from the finally block */ DEF( nip_catch, 1, 2, 1, none) /* catch ... a -> a */ DEF( to_object, 1, 1, 1, none) //DEF( to_string, 1, 1, 1, none) DEF( to_propkey, 1, 1, 1, none) DEF( with_get_var, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */ DEF( with_put_var, 10, 2, 1, atom_label_u8) /* must be in the same order as scope_xxx */ DEF(with_delete_var, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */ DEF( with_make_ref, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */ DEF( with_get_ref, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */ DEF( make_loc_ref, 7, 0, 2, atom_u16) DEF( make_arg_ref, 7, 0, 2, atom_u16) DEF(make_var_ref_ref, 7, 0, 2, atom_u16) DEF( make_var_ref, 5, 0, 2, atom) DEF( for_in_start, 1, 1, 1, none) DEF( for_of_start, 1, 1, 3, none) DEF(for_await_of_start, 1, 1, 3, none) DEF( for_in_next, 1, 1, 3, none) DEF( for_of_next, 2, 3, 5, u8) DEF(for_await_of_next, 1, 3, 4, none) /* iter next catch_offset -> iter next catch_offset obj */ DEF(iterator_check_object, 1, 1, 1, none) DEF(iterator_get_value_done, 1, 2, 3, none) /* catch_offset obj -> catch_offset value done */ DEF( iterator_close, 1, 3, 0, none) DEF( iterator_next, 1, 4, 4, none) DEF( iterator_call, 2, 4, 5, u8) DEF( initial_yield, 1, 0, 0, none) DEF( yield, 1, 1, 2, none) DEF( yield_star, 1, 1, 2, none) DEF(async_yield_star, 1, 1, 2, none) DEF( await, 1, 1, 1, none) /* arithmetic/logic operations */ DEF( neg, 1, 1, 1, none) DEF( plus, 1, 1, 1, none) DEF( dec, 1, 1, 1, none) DEF( inc, 1, 1, 1, none) DEF( post_dec, 1, 1, 2, none) DEF( post_inc, 1, 1, 2, none) DEF( dec_loc, 2, 0, 0, loc8) DEF( inc_loc, 2, 0, 0, loc8) DEF( add_loc, 2, 1, 0, loc8) DEF( not, 1, 1, 1, none) DEF( lnot, 1, 1, 1, none) DEF( typeof, 1, 1, 1, none) DEF( delete, 1, 2, 1, none) DEF( delete_var, 5, 0, 1, atom) DEF( mul, 1, 2, 1, none) DEF( div, 1, 2, 1, none) DEF( mod, 1, 2, 1, none) DEF( add, 1, 2, 1, none) DEF( sub, 1, 2, 1, none) DEF( pow, 1, 2, 1, none) DEF( shl, 1, 2, 1, none) DEF( sar, 1, 2, 1, none) DEF( shr, 1, 2, 1, none) DEF( lt, 1, 2, 1, none) DEF( lte, 1, 2, 1, none) DEF( gt, 1, 2, 1, none) DEF( gte, 1, 2, 1, none) DEF( instanceof, 1, 2, 1, none) DEF( in, 1, 2, 1, none) DEF( eq, 1, 2, 1, none) DEF( neq, 1, 2, 1, none) DEF( strict_eq, 1, 2, 1, none) DEF( strict_neq, 1, 2, 1, none) DEF( and, 1, 2, 1, none) DEF( xor, 1, 2, 1, none) DEF( or, 1, 2, 1, none) DEF(is_undefined_or_null, 1, 1, 1, none) DEF( private_in, 1, 2, 1, none) DEF(push_bigint_i32, 5, 0, 1, i32) /* must be the last non short and non temporary opcode */ DEF( nop, 1, 0, 0, none) /* temporary opcodes: never emitted in the final bytecode */ def( enter_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */ def( leave_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */ def( label, 5, 0, 0, label) /* emitted in phase 1, removed in phase 3 */ /* the following opcodes must be in the same order as the 'with_x' and get_var_undef, get_var and put_var opcodes */ def(scope_get_var_undef, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ def( scope_get_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ def( scope_put_var, 7, 1, 0, atom_u16) /* emitted in phase 1, removed in phase 2 */ def(scope_delete_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ def( scope_make_ref, 11, 0, 2, atom_label_u16) /* emitted in phase 1, removed in phase 2 */ def( scope_get_ref, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */ def(scope_put_var_init, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */ def(scope_get_var_checkthis, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2, only used to return 'this' in derived class constructors */ def(scope_get_private_field, 7, 1, 1, atom_u16) /* obj -> value, emitted in phase 1, removed in phase 2 */ def(scope_get_private_field2, 7, 1, 2, atom_u16) /* obj -> obj value, emitted in phase 1, removed in phase 2 */ def(scope_put_private_field, 7, 2, 0, atom_u16) /* obj value ->, emitted in phase 1, removed in phase 2 */ def(scope_in_private_field, 7, 1, 1, atom_u16) /* obj -> res emitted in phase 1, removed in phase 2 */ def(get_field_opt_chain, 5, 1, 1, atom) /* emitted in phase 1, removed in phase 2 */ def(get_array_el_opt_chain, 1, 2, 1, none) /* emitted in phase 1, removed in phase 2 */ def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */ def( line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */ #if SHORT_OPCODES DEF( push_minus1, 1, 0, 1, none_int) DEF( push_0, 1, 0, 1, none_int) DEF( push_1, 1, 0, 1, none_int) DEF( push_2, 1, 0, 1, none_int) DEF( push_3, 1, 0, 1, none_int) DEF( push_4, 1, 0, 1, none_int) DEF( push_5, 1, 0, 1, none_int) DEF( push_6, 1, 0, 1, none_int) DEF( push_7, 1, 0, 1, none_int) DEF( push_i8, 2, 0, 1, i8) DEF( push_i16, 3, 0, 1, i16) DEF( push_const8, 2, 0, 1, const8) DEF( fclosure8, 2, 0, 1, const8) /* must follow push_const8 */ DEF(push_empty_string, 1, 0, 1, none) DEF( get_loc8, 2, 0, 1, loc8) DEF( put_loc8, 2, 1, 0, loc8) DEF( set_loc8, 2, 1, 1, loc8) DEF( get_loc0, 1, 0, 1, none_loc) DEF( get_loc1, 1, 0, 1, none_loc) DEF( get_loc2, 1, 0, 1, none_loc) DEF( get_loc3, 1, 0, 1, none_loc) DEF( put_loc0, 1, 1, 0, none_loc) DEF( put_loc1, 1, 1, 0, none_loc) DEF( put_loc2, 1, 1, 0, none_loc) DEF( put_loc3, 1, 1, 0, none_loc) DEF( set_loc0, 1, 1, 1, none_loc) DEF( set_loc1, 1, 1, 1, none_loc) DEF( set_loc2, 1, 1, 1, none_loc) DEF( set_loc3, 1, 1, 1, none_loc) DEF( get_arg0, 1, 0, 1, none_arg) DEF( get_arg1, 1, 0, 1, none_arg) DEF( get_arg2, 1, 0, 1, none_arg) DEF( get_arg3, 1, 0, 1, none_arg) DEF( put_arg0, 1, 1, 0, none_arg) DEF( put_arg1, 1, 1, 0, none_arg) DEF( put_arg2, 1, 1, 0, none_arg) DEF( put_arg3, 1, 1, 0, none_arg) DEF( set_arg0, 1, 1, 1, none_arg) DEF( set_arg1, 1, 1, 1, none_arg) DEF( set_arg2, 1, 1, 1, none_arg) DEF( set_arg3, 1, 1, 1, none_arg) DEF( get_var_ref0, 1, 0, 1, none_var_ref) DEF( get_var_ref1, 1, 0, 1, none_var_ref) DEF( get_var_ref2, 1, 0, 1, none_var_ref) DEF( get_var_ref3, 1, 0, 1, none_var_ref) DEF( put_var_ref0, 1, 1, 0, none_var_ref) DEF( put_var_ref1, 1, 1, 0, none_var_ref) DEF( put_var_ref2, 1, 1, 0, none_var_ref) DEF( put_var_ref3, 1, 1, 0, none_var_ref) DEF( set_var_ref0, 1, 1, 1, none_var_ref) DEF( set_var_ref1, 1, 1, 1, none_var_ref) DEF( set_var_ref2, 1, 1, 1, none_var_ref) DEF( set_var_ref3, 1, 1, 1, none_var_ref) DEF( get_length, 1, 1, 1, none) DEF( if_false8, 2, 1, 0, label8) DEF( if_true8, 2, 1, 0, label8) /* must come after if_false8 */ DEF( goto8, 2, 0, 0, label8) /* must come after if_true8 */ DEF( goto16, 3, 0, 0, label16) DEF( call0, 1, 1, 1, npopx) DEF( call1, 1, 1, 1, npopx) DEF( call2, 1, 1, 1, npopx) DEF( call3, 1, 1, 1, npopx) DEF( is_undefined, 1, 1, 1, none) DEF( is_null, 1, 1, 1, none) DEF(typeof_is_undefined, 1, 1, 1, none) DEF( typeof_is_function, 1, 1, 1, none) #endif #undef DEF #undef def #endif /* DEF */ �����������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/qjs/quickjs.c��������������������������������������������������0000664�0000000�0000000�00007434546�15202323131�0022043�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * QuickJS Javascript Engine * * Copyright (c) 2017-2025 Fabrice Bellard * Copyright (c) 2017-2025 Charlie Gordon * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include <stdlib.h> #include <stdio.h> #include <stdarg.h> #include <inttypes.h> #include <string.h> #include <assert.h> #include <sys/time.h> #include <time.h> #include <fenv.h> #include <math.h> #if defined(__APPLE__) #include <malloc/malloc.h> #elif defined(__linux__) || defined(__GLIBC__) #include <malloc.h> #elif defined(__FreeBSD__) #include <malloc_np.h> #endif #include "cutils.h" #include "list.h" #include "quickjs.h" #include "libregexp.h" #include "libunicode.h" #include "dtoa.h" #define OPTIMIZE 1 #define SHORT_OPCODES 1 #if defined(__EMSCRIPTEN__) #define DIRECT_DISPATCH 0 #else #define DIRECT_DISPATCH 1 #endif #if defined(__APPLE__) #define MALLOC_OVERHEAD 0 #else #define MALLOC_OVERHEAD 8 #endif #if !defined(_WIN32) /* define it if printf uses the RNDN rounding mode instead of RNDNA */ #define CONFIG_PRINTF_RNDN #endif /* define to include Atomics.* operations which depend on the OS threads */ #if !defined(__EMSCRIPTEN__) && !defined(CHA_NO_THREADS) #define CONFIG_ATOMICS #endif #if !defined(__EMSCRIPTEN__) /* enable stack limitation */ #define CONFIG_STACK_CHECK #endif /* dump object free */ //#define DUMP_FREE //#define DUMP_CLOSURE /* dump the bytecode of the compiled functions: combination of bits 1: dump pass 3 final byte code 2: dump pass 2 code 4: dump pass 1 code 8: dump stdlib functions 16: dump bytecode in hex 32: dump line number table 64: dump compute_stack_size */ //#define DUMP_BYTECODE (1) /* dump the occurence of the automatic GC */ //#define DUMP_GC /* dump objects freed by the garbage collector */ //#define DUMP_GC_FREE /* dump objects leaking when freeing the runtime */ //#define DUMP_LEAKS 1 /* dump memory usage before running the garbage collector */ //#define DUMP_MEM //#define DUMP_OBJECTS /* dump objects in JS_FreeContext */ //#define DUMP_ATOMS /* dump atoms in JS_FreeContext */ //#define DUMP_SHAPES /* dump shapes in JS_FreeContext */ //#define DUMP_MODULE_RESOLVE //#define DUMP_MODULE_EXEC //#define DUMP_PROMISE //#define DUMP_READ_OBJECT //#define DUMP_ROPE_REBALANCE /* test the GC by forcing it before each object allocation */ //#define FORCE_GC_AT_MALLOC #ifdef CONFIG_ATOMICS #include <pthread.h> #include <stdatomic.h> #include <errno.h> #endif enum { /* classid tag */ /* union usage | properties */ JS_CLASS_OBJECT = 1, /* must be first */ JS_CLASS_ARRAY, /* u.array | length */ JS_CLASS_ERROR, JS_CLASS_NUMBER, /* u.object_data */ JS_CLASS_STRING, /* u.object_data */ JS_CLASS_BOOLEAN, /* u.object_data */ JS_CLASS_SYMBOL, /* u.object_data */ JS_CLASS_ARGUMENTS, /* u.array | length */ JS_CLASS_MAPPED_ARGUMENTS, /* u.array | length */ JS_CLASS_DATE, /* u.object_data */ JS_CLASS_MODULE_NS, JS_CLASS_C_FUNCTION, /* u.cfunc */ JS_CLASS_BYTECODE_FUNCTION, /* u.func */ JS_CLASS_BOUND_FUNCTION, /* u.bound_function */ JS_CLASS_C_FUNCTION_DATA, /* u.c_function_data_record */ JS_CLASS_GENERATOR_FUNCTION, /* u.func */ JS_CLASS_FOR_IN_ITERATOR, /* u.for_in_iterator */ JS_CLASS_REGEXP, /* u.regexp */ JS_CLASS_ARRAY_BUFFER, /* u.array_buffer */ JS_CLASS_SHARED_ARRAY_BUFFER, /* u.array_buffer */ JS_CLASS_UINT8C_ARRAY, /* u.array (typed_array) */ JS_CLASS_INT8_ARRAY, /* u.array (typed_array) */ JS_CLASS_UINT8_ARRAY, /* u.array (typed_array) */ JS_CLASS_INT16_ARRAY, /* u.array (typed_array) */ JS_CLASS_UINT16_ARRAY, /* u.array (typed_array) */ JS_CLASS_INT32_ARRAY, /* u.array (typed_array) */ JS_CLASS_UINT32_ARRAY, /* u.array (typed_array) */ JS_CLASS_BIG_INT64_ARRAY, /* u.array (typed_array) */ JS_CLASS_BIG_UINT64_ARRAY, /* u.array (typed_array) */ JS_CLASS_FLOAT16_ARRAY, /* u.array (typed_array) */ JS_CLASS_FLOAT32_ARRAY, /* u.array (typed_array) */ JS_CLASS_FLOAT64_ARRAY, /* u.array (typed_array) */ JS_CLASS_DATAVIEW, /* u.typed_array */ JS_CLASS_BIG_INT, /* u.object_data */ JS_CLASS_MAP, /* u.map_state */ JS_CLASS_SET, /* u.map_state */ JS_CLASS_WEAKMAP, /* u.map_state */ JS_CLASS_WEAKSET, /* u.map_state */ JS_CLASS_ITERATOR, /* u.map_iterator_data */ JS_CLASS_ITERATOR_CONCAT, /* u.iterator_concat_data */ JS_CLASS_ITERATOR_HELPER, /* u.iterator_helper_data */ JS_CLASS_ITERATOR_WRAP, /* u.iterator_wrap_data */ JS_CLASS_MAP_ITERATOR, /* u.map_iterator_data */ JS_CLASS_SET_ITERATOR, /* u.map_iterator_data */ JS_CLASS_ARRAY_ITERATOR, /* u.array_iterator_data */ JS_CLASS_STRING_ITERATOR, /* u.array_iterator_data */ JS_CLASS_REGEXP_STRING_ITERATOR, /* u.regexp_string_iterator_data */ JS_CLASS_GENERATOR, /* u.generator_data */ JS_CLASS_GLOBAL_OBJECT, /* u.global_object */ JS_CLASS_RAWJSON, JS_CLASS_PROXY, /* u.proxy_data */ JS_CLASS_PROMISE, /* u.promise_data */ JS_CLASS_PROMISE_RESOLVE_FUNCTION, /* u.promise_function_data */ JS_CLASS_PROMISE_REJECT_FUNCTION, /* u.promise_function_data */ JS_CLASS_ASYNC_FUNCTION, /* u.func */ JS_CLASS_ASYNC_FUNCTION_RESOLVE, /* u.async_function_data */ JS_CLASS_ASYNC_FUNCTION_REJECT, /* u.async_function_data */ JS_CLASS_ASYNC_FROM_SYNC_ITERATOR, /* u.async_from_sync_iterator_data */ JS_CLASS_ASYNC_GENERATOR_FUNCTION, /* u.func */ JS_CLASS_ASYNC_GENERATOR, /* u.async_generator_data */ JS_CLASS_WEAK_REF, JS_CLASS_FINALIZATION_REGISTRY, JS_CLASS_INIT_COUNT, /* last entry for predefined classes */ }; /* number of typed array types */ #define JS_TYPED_ARRAY_COUNT (JS_CLASS_FLOAT64_ARRAY - JS_CLASS_UINT8C_ARRAY + 1) static uint8_t const typed_array_size_log2[JS_TYPED_ARRAY_COUNT]; #define typed_array_size_log2(classid) (typed_array_size_log2[(classid)- JS_CLASS_UINT8C_ARRAY]) typedef enum JSErrorEnum { JS_EVAL_ERROR, JS_RANGE_ERROR, JS_REFERENCE_ERROR, JS_SYNTAX_ERROR, JS_TYPE_ERROR, JS_URI_ERROR, JS_INTERNAL_ERROR, JS_AGGREGATE_ERROR, JS_NATIVE_ERROR_COUNT, /* number of different NativeError objects */ } JSErrorEnum; /* the variable and scope indexes must fit on 16 bits. The (-1) and ARG_SCOPE_END values are reserved. */ #define JS_MAX_LOCAL_VARS 65534 #define JS_STACK_SIZE_MAX 65534 #define JS_STRING_LEN_MAX ((1 << 30) - 1) /* strings <= this length are not concatenated using ropes. if too small, the rope memory overhead becomes high. */ #define JS_STRING_ROPE_SHORT_LEN 512 /* specific threshold for initial rope use */ #define JS_STRING_ROPE_SHORT2_LEN 8192 /* rope depth at which we rebalance */ #define JS_STRING_ROPE_MAX_DEPTH 60 #define __exception __attribute__((warn_unused_result)) typedef struct JSShape JSShape; typedef struct JSString JSString; typedef struct JSString JSAtomStruct; typedef struct JSObject JSObject; #define JS_VALUE_GET_OBJ(v) ((JSObject *)JS_VALUE_GET_PTR(v)) #define JS_VALUE_GET_STRING(v) ((JSString *)JS_VALUE_GET_PTR(v)) #define JS_VALUE_GET_STRING_ROPE(v) ((JSStringRope *)JS_VALUE_GET_PTR(v)) typedef enum { JS_GC_PHASE_NONE, JS_GC_PHASE_DECREF, JS_GC_PHASE_REMOVE_CYCLES, } JSGCPhaseEnum; typedef enum OPCodeEnum OPCodeEnum; struct JSRuntime { JSMallocFunctions mf; JSMallocState malloc_state; const char *rt_info; int atom_hash_size; /* power of two */ int atom_count; int atom_size; int atom_count_resize; /* resize hash table at this count */ uint32_t *atom_hash; JSAtomStruct **atom_array; int atom_free_index; /* 0 = none */ int class_count; /* size of class_array */ JSClass *class_array; struct list_head context_list; /* list of JSContext.link */ /* list of JSGCObjectHeader.link. List of allocated GC objects (used by the garbage collector) */ struct list_head gc_obj_list; /* list of JSGCObjectHeader.link. Used during JS_FreeValueRT() */ struct list_head gc_zero_ref_count_list; struct list_head tmp_obj_list; /* used during GC */ /* used during GC (for keeping track of objects with a can_destroy hook) */ struct list_head tmp_hook_obj_list; JSGCPhaseEnum gc_phase : 8; size_t malloc_gc_threshold; struct list_head weakref_list; /* list of JSWeakRefHeader.link */ #ifdef DUMP_LEAKS struct list_head string_list; /* list of JSString.link */ #endif /* stack limitation */ uintptr_t stack_size; /* in bytes, 0 if no limit */ uintptr_t stack_top; uintptr_t stack_limit; /* lower stack limit */ JSValue current_exception; /* true if the current exception cannot be catched */ BOOL current_exception_is_uncatchable : 8; /* true if inside an out of memory error, to avoid recursing */ BOOL in_out_of_memory : 8; struct JSStackFrame *current_stack_frame; JSInterruptHandler *interrupt_handler; void *interrupt_opaque; JSHostPromiseRejectionTracker *host_promise_rejection_tracker; void *host_promise_rejection_tracker_opaque; struct list_head job_list; /* list of JSJobEntry.link */ JSModuleNormalizeFunc *module_normalize_func; BOOL module_loader_has_attr; union { JSModuleLoaderFunc *module_loader_func; JSModuleLoaderFunc2 *module_loader_func2; } u; JSModuleCheckSupportedImportAttributes *module_check_attrs; void *module_loader_opaque; /* timestamp for internal use in module evaluation */ int64_t module_async_evaluation_next_timestamp; BOOL can_block : 8; /* TRUE if Atomics.wait can block */ /* used to allocate, free and clone SharedArrayBuffers */ JSSharedArrayBufferFunctions sab_funcs; /* see JS_SetStripInfo() */ uint8_t strip_flags; /* Shape hash table */ int shape_hash_bits; int shape_hash_size; int shape_hash_count; /* number of hashed shapes */ JSShape **shape_hash; void *user_opaque; }; struct JSClass { uint32_t class_id; /* 0 means free entry */ JSAtom class_name; JSClassFinalizer *finalizer; JSClassGCMark *gc_mark; JSClassCall *call; /* pointers for exotic behavior, can be NULL if none are present */ const JSClassExoticMethods *exotic; /* called before object would be destroyed */ JSClassCanDestroy *can_destroy; }; #define JS_MODE_STRICT (1 << 0) #define JS_MODE_ASYNC (1 << 2) /* async function */ #define JS_MODE_BACKTRACE_BARRIER (1 << 3) /* stop backtrace before this frame */ typedef struct JSStackFrame { struct JSStackFrame *prev_frame; /* NULL if first stack frame */ JSValue cur_func; /* current function, JS_UNDEFINED if the frame is detached */ JSValue *arg_buf; /* arguments */ JSValue *var_buf; /* variables */ struct JSVarRef **var_refs; /* references to arguments or local variables */ const uint8_t *cur_pc; /* only used in bytecode functions : PC of the instruction after the call */ int arg_count; int js_mode; /* not supported for C functions */ /* only used in generators. Current stack pointer value. NULL if the function is running. */ JSValue *cur_sp; } JSStackFrame; typedef enum { JS_GC_OBJ_TYPE_JS_OBJECT, JS_GC_OBJ_TYPE_FUNCTION_BYTECODE, JS_GC_OBJ_TYPE_SHAPE, JS_GC_OBJ_TYPE_VAR_REF, JS_GC_OBJ_TYPE_ASYNC_FUNCTION, JS_GC_OBJ_TYPE_JS_CONTEXT, JS_GC_OBJ_TYPE_MODULE, } JSGCObjectTypeEnum; /* header for GC objects. GC objects are C data structures with a reference count that can reference other GC objects. JS Objects are a particular type of GC object. */ struct JSGCObjectHeader { int ref_count; /* must come first, 32-bit */ JSGCObjectTypeEnum gc_obj_type : 4; uint8_t mark : 1; /* used by the GC */ uint8_t dummy0: 3; uint8_t dummy1; /* not used by the GC */ uint16_t dummy2; /* not used by the GC */ struct list_head link; }; typedef enum { JS_WEAKREF_TYPE_MAP, JS_WEAKREF_TYPE_WEAKREF, JS_WEAKREF_TYPE_FINREC, } JSWeakRefHeaderTypeEnum; typedef struct { struct list_head link; JSWeakRefHeaderTypeEnum weakref_type; } JSWeakRefHeader; typedef struct JSVarRef { union { JSGCObjectHeader header; /* must come first */ struct { int __gc_ref_count; /* corresponds to header.ref_count */ uint8_t __gc_mark; /* corresponds to header.mark/gc_obj_type */ uint8_t is_detached; uint8_t is_lexical; /* only used with global variables */ uint8_t is_const; /* only used with global variables */ }; }; JSValue *pvalue; /* pointer to the value, either on the stack or to 'value' */ union { JSValue value; /* used when is_detached = TRUE */ struct { uint16_t var_ref_idx; /* index in JSStackFrame.var_refs[] */ JSStackFrame *stack_frame; }; /* used when is_detached = FALSE */ }; } JSVarRef; /* bigint */ #if JS_LIMB_BITS == 32 typedef int32_t js_slimb_t; typedef uint32_t js_limb_t; typedef int64_t js_sdlimb_t; typedef uint64_t js_dlimb_t; #define JS_LIMB_DIGITS 9 #else typedef __int128 int128_t; typedef unsigned __int128 uint128_t; typedef int64_t js_slimb_t; typedef uint64_t js_limb_t; typedef int128_t js_sdlimb_t; typedef uint128_t js_dlimb_t; #define JS_LIMB_DIGITS 19 #endif typedef struct JSBigInt { JSRefCountHeader header; /* must come first, 32-bit */ uint32_t len; /* number of limbs, >= 1 */ js_limb_t tab[]; /* two's complement representation, always normalized so that 'len' is the minimum possible length >= 1 */ } JSBigInt; /* this bigint structure can hold a 64 bit integer */ typedef struct { js_limb_t big_int_buf[sizeof(JSBigInt) / sizeof(js_limb_t)]; /* for JSBigInt */ /* must come just after */ js_limb_t tab[(64 + JS_LIMB_BITS - 1) / JS_LIMB_BITS]; } JSBigIntBuf; typedef enum { JS_AUTOINIT_ID_PROTOTYPE, JS_AUTOINIT_ID_MODULE_NS, JS_AUTOINIT_ID_PROP, } JSAutoInitIDEnum; /* must be large enough to have a negligible runtime cost and small enough to call the interrupt callback often. */ #define JS_INTERRUPT_COUNTER_INIT 10000 struct JSContext { JSGCObjectHeader header; /* must come first */ JSRuntime *rt; struct list_head link; uint16_t binary_object_count; int binary_object_size; JSShape *array_shape; /* initial shape for Array objects */ JSShape *arguments_shape; /* shape for arguments objects */ JSShape *mapped_arguments_shape; /* shape for mapped arguments objects */ JSShape *regexp_shape; /* shape for regexp objects */ JSShape *regexp_result_shape; /* shape for regexp result objects */ JSValue *class_proto; JSValue function_proto; JSValue function_ctor; JSValue array_ctor; JSValue regexp_ctor; JSValue promise_ctor; JSValue native_error_proto[JS_NATIVE_ERROR_COUNT]; JSValue iterator_ctor; JSValue async_iterator_proto; JSValue array_proto_values; JSValue throw_type_error; JSValue eval_obj; JSValue global_obj; /* global object */ JSValue global_var_obj; /* contains the global let/const definitions */ uint64_t random_state; /* when the counter reaches zero, JSRutime.interrupt_handler is called */ int interrupt_counter; struct list_head loaded_modules; /* list of JSModuleDef.link */ /* if NULL, RegExp compilation is not supported */ JSValue (*compile_regexp)(JSContext *ctx, JSValueConst pattern, JSValueConst flags); /* if NULL, eval is not supported */ JSValue (*eval_internal)(JSContext *ctx, JSValueConst this_obj, const char *input, size_t input_len, const char *filename, int flags, int scope_idx); void *user_opaque; }; typedef union JSFloat64Union { double d; uint64_t u64; uint32_t u32[2]; } JSFloat64Union; enum { JS_ATOM_TYPE_STRING = 1, JS_ATOM_TYPE_GLOBAL_SYMBOL, JS_ATOM_TYPE_SYMBOL, JS_ATOM_TYPE_PRIVATE, }; typedef enum { JS_ATOM_KIND_STRING, JS_ATOM_KIND_SYMBOL, JS_ATOM_KIND_PRIVATE, } JSAtomKindEnum; #define JS_ATOM_HASH_MASK ((1 << 30) - 1) #define JS_ATOM_HASH_PRIVATE JS_ATOM_HASH_MASK struct JSString { JSRefCountHeader header; /* must come first, 32-bit */ uint32_t len : 31; uint8_t is_wide_char : 1; /* 0 = 8 bits, 1 = 16 bits characters */ /* for JS_ATOM_TYPE_SYMBOL: hash = weakref_count, atom_type = 3, for JS_ATOM_TYPE_PRIVATE: hash = JS_ATOM_HASH_PRIVATE, atom_type = 3 XXX: could change encoding to have one more bit in hash */ uint32_t hash : 30; uint8_t atom_type : 2; /* != 0 if atom, JS_ATOM_TYPE_x */ uint32_t hash_next; /* atom_index for JS_ATOM_TYPE_SYMBOL */ #ifdef DUMP_LEAKS struct list_head link; /* string list */ #endif union { uint8_t str8[0]; /* 8 bit strings will get an extra null terminator */ uint16_t str16[0]; } u; }; typedef struct JSStringRope { JSRefCountHeader header; /* must come first, 32-bit */ uint32_t len; uint8_t is_wide_char; /* 0 = 8 bits, 1 = 16 bits characters */ uint8_t depth; /* max depth of the rope tree */ /* XXX: could reduce memory usage by using a direct pointer with bit 0 to select rope or string */ JSValue left; JSValue right; /* might be the empty string */ } JSStringRope; typedef enum { JS_CLOSURE_LOCAL, /* 'var_idx' is the index of a local variable in the parent function */ JS_CLOSURE_ARG, /* 'var_idx' is the index of a argument variable in the parent function */ JS_CLOSURE_REF, /* 'var_idx' is the index of a closure variable in the parent function */ JS_CLOSURE_GLOBAL_REF, /* 'var_idx' in the index of a closure variable in the parent function referencing a global variable */ JS_CLOSURE_GLOBAL_DECL, /* global variable declaration (eval code only) */ JS_CLOSURE_GLOBAL, /* global variable (eval code only) */ JS_CLOSURE_MODULE_DECL, /* definition of a module variable (eval code only) */ JS_CLOSURE_MODULE_IMPORT, /* definition of a module import (eval code only) */ } JSClosureTypeEnum; typedef struct JSClosureVar { JSClosureTypeEnum closure_type : 3; uint8_t is_lexical : 1; /* lexical variable */ uint8_t is_const : 1; /* const variable (is_lexical = 1 if is_const = 1 */ uint8_t var_kind : 4; /* see JSVarKindEnum */ uint16_t var_idx; /* is_local = TRUE: index to a normal variable of the parent function. otherwise: index to a closure variable of the parent function */ JSAtom var_name; } JSClosureVar; #define ARG_SCOPE_INDEX 1 #define ARG_SCOPE_END (-2) typedef enum { /* XXX: add more variable kinds here instead of using bit fields */ JS_VAR_NORMAL, JS_VAR_FUNCTION_DECL, /* lexical var with function declaration */ JS_VAR_NEW_FUNCTION_DECL, /* lexical var with async/generator function declaration */ JS_VAR_CATCH, JS_VAR_FUNCTION_NAME, /* function expression name */ JS_VAR_PRIVATE_FIELD, JS_VAR_PRIVATE_METHOD, JS_VAR_PRIVATE_GETTER, JS_VAR_PRIVATE_SETTER, /* must come after JS_VAR_PRIVATE_GETTER */ JS_VAR_PRIVATE_GETTER_SETTER, /* must come after JS_VAR_PRIVATE_SETTER */ JS_VAR_GLOBAL_FUNCTION_DECL, /* global function definition, only in JSVarDef */ } JSVarKindEnum; typedef struct JSBytecodeVarDef { JSAtom var_name; /* index into JSFunctionBytecode.vars of the next variable in the same or enclosing lexical scope */ int scope_next; /* XXX: store on 16 bits */ uint8_t is_const : 1; uint8_t is_lexical : 1; uint8_t is_captured : 1; /* XXX: could remove and use a var_ref_idx value */ uint8_t has_scope: 1; /* true if JSVarDef.scope_level != 0 */ uint8_t var_kind : 4; /* see JSVarKindEnum */ /* If is_captured = TRUE, provides, the index of the corresponding JSVarRef on stack. It would be more compact to have a separate table with the corresponding inverted table but it requires more modifications in the code. */ uint16_t var_ref_idx; } JSBytecodeVarDef; /* for the encoding of the pc2line table */ #define PC2LINE_BASE (-1) #define PC2LINE_RANGE 5 #define PC2LINE_OP_FIRST 1 #define PC2LINE_DIFF_PC_MAX ((255 - PC2LINE_OP_FIRST) / PC2LINE_RANGE) typedef enum JSFunctionKindEnum { JS_FUNC_NORMAL = 0, JS_FUNC_GENERATOR = (1 << 0), JS_FUNC_ASYNC = (1 << 1), JS_FUNC_ASYNC_GENERATOR = (JS_FUNC_GENERATOR | JS_FUNC_ASYNC), } JSFunctionKindEnum; typedef struct JSFunctionBytecode { JSGCObjectHeader header; /* must come first */ uint8_t js_mode; uint8_t has_prototype : 1; /* true if a prototype field is necessary */ uint8_t has_simple_parameter_list : 1; uint8_t is_derived_class_constructor : 1; /* true if home_object needs to be initialized */ uint8_t need_home_object : 1; uint8_t func_kind : 2; uint8_t new_target_allowed : 1; uint8_t super_call_allowed : 1; uint8_t super_allowed : 1; uint8_t arguments_allowed : 1; uint8_t has_debug : 1; uint8_t read_only_bytecode : 1; uint8_t is_direct_or_indirect_eval : 1; /* used by JS_GetScriptOrModuleName() */ /* XXX: 10 bits available */ uint8_t *byte_code_buf; /* (self pointer) */ int byte_code_len; JSAtom func_name; JSBytecodeVarDef *vardefs; /* arguments + local variables (arg_count + var_count) (self pointer) */ JSClosureVar *closure_var; /* list of variables in the closure (self pointer) */ uint16_t arg_count; uint16_t var_count; uint16_t defined_arg_count; /* for length function property */ uint16_t stack_size; /* maximum stack size */ uint16_t var_ref_count; /* number of local variable references */ JSContext *realm; /* function realm */ JSValue *cpool; /* constant pool (self pointer) */ int cpool_count; int closure_var_count; struct { /* debug info, move to separate structure to save memory? */ JSAtom filename; int source_len; int pc2line_len; uint8_t *pc2line_buf; char *source; } debug; } JSFunctionBytecode; typedef struct JSBoundFunction { JSValue func_obj; JSValue this_val; int argc; JSValue argv[0]; } JSBoundFunction; typedef enum JSIteratorKindEnum { JS_ITERATOR_KIND_KEY, JS_ITERATOR_KIND_VALUE, JS_ITERATOR_KIND_KEY_AND_VALUE, } JSIteratorKindEnum; typedef struct JSForInIterator { JSValue obj; uint32_t idx; uint32_t atom_count; uint8_t in_prototype_chain; uint8_t is_array; JSPropertyEnum *tab_atom; /* is_array = FALSE */ } JSForInIterator; typedef struct JSRegExp { JSString *pattern; JSString *bytecode; /* also contains the flags */ } JSRegExp; typedef struct JSProxyData { JSValue target; JSValue handler; uint8_t is_func; uint8_t is_revoked; } JSProxyData; typedef struct JSArrayBuffer { int byte_length; /* 0 if detached */ int max_byte_length; /* -1 if not resizable; >= byte_length otherwise */ uint8_t detached; uint8_t shared; /* if shared, the array buffer cannot be detached */ uint8_t *data; /* NULL if detached */ struct list_head array_list; void *opaque; JSFreeArrayBufferDataFunc *free_func; } JSArrayBuffer; typedef struct JSTypedArray { struct list_head link; /* link to arraybuffer */ JSObject *obj; /* back pointer to the TypedArray/DataView object */ JSObject *buffer; /* based array buffer */ uint32_t offset; /* byte offset in the array buffer */ uint32_t length; /* byte length in the array buffer */ BOOL track_rab; /* auto-track length of backing array buffer */ } JSTypedArray; typedef struct JSGlobalObject { JSValue uninitialized_vars; /* hidden object containing the list of uninitialized variables */ } JSGlobalObject; typedef struct JSAsyncFunctionState { JSGCObjectHeader header; JSValue this_val; /* 'this' argument */ int argc; /* number of function arguments */ BOOL throw_flag; /* used to throw an exception in JS_CallInternal() */ BOOL is_completed; /* TRUE if the function has returned. The stack frame is no longer valid */ JSValue resolving_funcs[2]; /* only used in JS async functions */ JSStackFrame frame; /* arg_buf, var_buf, stack_buf and var_refs follow */ } JSAsyncFunctionState; typedef enum { /* binary operators */ JS_OVOP_ADD, JS_OVOP_SUB, JS_OVOP_MUL, JS_OVOP_DIV, JS_OVOP_MOD, JS_OVOP_POW, JS_OVOP_OR, JS_OVOP_AND, JS_OVOP_XOR, JS_OVOP_SHL, JS_OVOP_SAR, JS_OVOP_SHR, JS_OVOP_EQ, JS_OVOP_LESS, JS_OVOP_BINARY_COUNT, /* unary operators */ JS_OVOP_POS = JS_OVOP_BINARY_COUNT, JS_OVOP_NEG, JS_OVOP_INC, JS_OVOP_DEC, JS_OVOP_NOT, JS_OVOP_COUNT, } JSOverloadableOperatorEnum; typedef struct { uint32_t operator_index; JSObject *ops[JS_OVOP_BINARY_COUNT]; /* self operators */ } JSBinaryOperatorDefEntry; typedef struct { int count; JSBinaryOperatorDefEntry *tab; } JSBinaryOperatorDef; typedef struct { uint32_t operator_counter; BOOL is_primitive; /* OperatorSet for a primitive type */ /* NULL if no operator is defined */ JSObject *self_ops[JS_OVOP_COUNT]; /* self operators */ JSBinaryOperatorDef left; JSBinaryOperatorDef right; } JSOperatorSetData; typedef struct JSReqModuleEntry { JSAtom module_name; JSModuleDef *module; /* used using resolution */ JSValue attributes; /* JS_UNDEFINED or an object contains the attributes as key/value */ } JSReqModuleEntry; typedef enum JSExportTypeEnum { JS_EXPORT_TYPE_LOCAL, JS_EXPORT_TYPE_INDIRECT, } JSExportTypeEnum; typedef struct JSExportEntry { union { struct { int var_idx; /* closure variable index */ JSVarRef *var_ref; /* if != NULL, reference to the variable */ } local; /* for local export */ int req_module_idx; /* module for indirect export */ } u; JSExportTypeEnum export_type; JSAtom local_name; /* '*' if export ns from. not used for local export after compilation */ JSAtom export_name; /* exported variable name */ } JSExportEntry; typedef struct JSStarExportEntry { int req_module_idx; /* in req_module_entries */ } JSStarExportEntry; typedef struct JSImportEntry { int var_idx; /* closure variable index */ BOOL is_star; /* import_name = '*' is a valid import name, so need a flag */ JSAtom import_name; int req_module_idx; /* in req_module_entries */ } JSImportEntry; typedef enum { JS_MODULE_STATUS_UNLINKED, JS_MODULE_STATUS_LINKING, JS_MODULE_STATUS_LINKED, JS_MODULE_STATUS_EVALUATING, JS_MODULE_STATUS_EVALUATING_ASYNC, JS_MODULE_STATUS_EVALUATED, } JSModuleStatus; struct JSModuleDef { JSGCObjectHeader header; /* must come first */ JSAtom module_name; struct list_head link; JSReqModuleEntry *req_module_entries; int req_module_entries_count; int req_module_entries_size; JSExportEntry *export_entries; int export_entries_count; int export_entries_size; JSStarExportEntry *star_export_entries; int star_export_entries_count; int star_export_entries_size; JSImportEntry *import_entries; int import_entries_count; int import_entries_size; JSValue module_ns; JSValue func_obj; /* only used for JS modules */ JSModuleInitFunc *init_func; /* only used for C modules */ BOOL has_tla : 8; /* true if func_obj contains await */ BOOL resolved : 8; BOOL func_created : 8; JSModuleStatus status : 8; /* temp use during js_module_link() & js_module_evaluate() */ int dfs_index, dfs_ancestor_index; JSModuleDef *stack_prev; /* temp use during js_module_evaluate() */ JSModuleDef **async_parent_modules; int async_parent_modules_count; int async_parent_modules_size; int pending_async_dependencies; BOOL async_evaluation; /* true: async_evaluation_timestamp corresponds to [[AsyncEvaluationOrder]] false: [[AsyncEvaluationOrder]] is UNSET or DONE */ int64_t async_evaluation_timestamp; JSModuleDef *cycle_root; JSValue promise; /* corresponds to spec field: capability */ JSValue resolving_funcs[2]; /* corresponds to spec field: capability */ /* true if evaluation yielded an exception. It is saved in eval_exception */ BOOL eval_has_exception : 8; JSValue eval_exception; JSValue meta_obj; /* for import.meta */ JSValue private_value; /* private value for C modules */ }; typedef struct JSJobEntry { struct list_head link; JSContext *realm; JSJobFunc *job_func; int argc; JSValue argv[0]; } JSJobEntry; typedef struct JSProperty { union { JSValue value; /* JS_PROP_NORMAL */ struct { /* JS_PROP_GETSET */ JSObject *getter; /* NULL if undefined */ JSObject *setter; /* NULL if undefined */ } getset; JSVarRef *var_ref; /* JS_PROP_VARREF */ struct { /* JS_PROP_AUTOINIT */ /* in order to use only 2 pointers, we compress the realm and the init function pointer */ uintptr_t realm_and_id; /* realm and init_id (JS_AUTOINIT_ID_x) in the 2 low bits */ void *opaque; } init; } u; } JSProperty; #define JS_PROP_INITIAL_SIZE 2 #define JS_PROP_INITIAL_HASH_SIZE 4 /* must be a power of two */ typedef struct JSShapeProperty { uint32_t hash_next : 26; /* 0 if last in list */ uint32_t flags : 6; /* JS_PROP_XXX */ JSAtom atom; /* JS_ATOM_NULL = free property entry */ } JSShapeProperty; struct JSShape { /* hash table of size hash_mask + 1 before the start of the structure (see prop_hash_end()). */ JSGCObjectHeader header; /* true if the shape is inserted in the shape hash table. If not, JSShape.hash is not valid */ uint8_t is_hashed; uint32_t hash; /* current hash value */ uint32_t prop_hash_mask; int prop_size; /* allocated properties */ int prop_count; /* include deleted properties */ int deleted_prop_count; JSShape *shape_hash_next; /* in JSRuntime.shape_hash[h] list */ JSObject *proto; JSShapeProperty prop[0]; /* prop_size elements */ }; struct JSObject { union { JSGCObjectHeader header; struct { int __gc_ref_count; /* corresponds to header.ref_count */ uint8_t __gc_mark : 7; /* corresponds to header.mark/gc_obj_type */ /* TRUE if the array prototype is "normal": - no small index properties which are get/set or non writable - its prototype is Object.prototype - Object.prototype has no small index properties which are get/set or non writable - the prototype of Object.prototype is null (always true as it is immutable) */ uint8_t is_std_array_prototype : 1; uint8_t extensible : 1; uint8_t free_mark : 1; /* only used when freeing objects with cycles */ uint8_t is_exotic : 1; /* TRUE if object has exotic property handlers */ uint8_t fast_array : 1; /* TRUE if u.array is used for get/put (for JS_CLASS_ARRAY, JS_CLASS_ARGUMENTS, JS_CLASS_MAPPED_ARGUMENTS and typed arrays) */ uint8_t is_constructor : 1; /* TRUE if object is a constructor function */ uint8_t has_immutable_prototype : 1; /* cannot modify the prototype */ uint8_t tmp_mark : 1; /* used in JS_WriteObjectRec() */ uint8_t is_HTMLDDA : 1; /* specific annex B IsHtmlDDA behavior */ uint16_t class_id; /* see JS_CLASS_x */ }; }; /* count the number of weak references to this object. The object structure is freed only if header.ref_count = 0 and weakref_count = 0 */ uint32_t weakref_count; JSShape *shape; /* prototype and property names + flag */ JSProperty *prop; /* array of properties */ union { void *opaque; struct JSBoundFunction *bound_function; /* JS_CLASS_BOUND_FUNCTION */ struct JSCFunctionDataRecord *c_function_data_record; /* JS_CLASS_C_FUNCTION_DATA */ struct JSForInIterator *for_in_iterator; /* JS_CLASS_FOR_IN_ITERATOR */ struct JSArrayBuffer *array_buffer; /* JS_CLASS_ARRAY_BUFFER, JS_CLASS_SHARED_ARRAY_BUFFER */ struct JSTypedArray *typed_array; /* JS_CLASS_UINT8C_ARRAY..JS_CLASS_DATAVIEW */ struct JSMapState *map_state; /* JS_CLASS_MAP..JS_CLASS_WEAKSET */ struct JSMapIteratorData *map_iterator_data; /* JS_CLASS_MAP_ITERATOR, JS_CLASS_SET_ITERATOR */ struct JSArrayIteratorData *array_iterator_data; /* JS_CLASS_ARRAY_ITERATOR, JS_CLASS_STRING_ITERATOR */ struct JSRegExpStringIteratorData *regexp_string_iterator_data; /* JS_CLASS_REGEXP_STRING_ITERATOR */ struct JSGeneratorData *generator_data; /* JS_CLASS_GENERATOR */ struct JSIteratorConcatData *iterator_concat_data; /* JS_CLASS_ITERATOR_CONCAT */ struct JSIteratorHelperData *iterator_helper_data; /* JS_CLASS_ITERATOR_HELPER */ struct JSIteratorWrapData *iterator_wrap_data; /* JS_CLASS_ITERATOR_WRAP */ struct JSProxyData *proxy_data; /* JS_CLASS_PROXY */ struct JSPromiseData *promise_data; /* JS_CLASS_PROMISE */ struct JSPromiseFunctionData *promise_function_data; /* JS_CLASS_PROMISE_RESOLVE_FUNCTION, JS_CLASS_PROMISE_REJECT_FUNCTION */ struct JSAsyncFunctionState *async_function_data; /* JS_CLASS_ASYNC_FUNCTION_RESOLVE, JS_CLASS_ASYNC_FUNCTION_REJECT */ struct JSAsyncFromSyncIteratorData *async_from_sync_iterator_data; /* JS_CLASS_ASYNC_FROM_SYNC_ITERATOR */ struct JSAsyncGeneratorData *async_generator_data; /* JS_CLASS_ASYNC_GENERATOR */ struct { /* JS_CLASS_BYTECODE_FUNCTION: 12/24 bytes */ /* also used by JS_CLASS_GENERATOR_FUNCTION, JS_CLASS_ASYNC_FUNCTION and JS_CLASS_ASYNC_GENERATOR_FUNCTION */ struct JSFunctionBytecode *function_bytecode; JSVarRef **var_refs; JSObject *home_object; /* for 'super' access */ } func; struct { /* JS_CLASS_C_FUNCTION: 12/20 bytes */ JSContext *realm; JSCFunctionType c_function; uint8_t length; uint8_t cproto; int16_t magic; } cfunc; /* array part for fast arrays and typed arrays */ struct { /* JS_CLASS_ARRAY, JS_CLASS_ARGUMENTS, JS_CLASS_MAPPED_ARGUMENTS, JS_CLASS_UINT8C_ARRAY..JS_CLASS_FLOAT64_ARRAY */ union { uint32_t size; /* JS_CLASS_ARRAY */ struct JSTypedArray *typed_array; /* JS_CLASS_UINT8C_ARRAY..JS_CLASS_FLOAT64_ARRAY */ } u1; union { JSValue *values; /* JS_CLASS_ARRAY, JS_CLASS_ARGUMENTS */ JSVarRef **var_refs; /* JS_CLASS_MAPPED_ARGUMENTS */ void *ptr; /* JS_CLASS_UINT8C_ARRAY..JS_CLASS_FLOAT64_ARRAY */ int8_t *int8_ptr; /* JS_CLASS_INT8_ARRAY */ uint8_t *uint8_ptr; /* JS_CLASS_UINT8_ARRAY, JS_CLASS_UINT8C_ARRAY */ int16_t *int16_ptr; /* JS_CLASS_INT16_ARRAY */ uint16_t *uint16_ptr; /* JS_CLASS_UINT16_ARRAY */ int32_t *int32_ptr; /* JS_CLASS_INT32_ARRAY */ uint32_t *uint32_ptr; /* JS_CLASS_UINT32_ARRAY */ int64_t *int64_ptr; /* JS_CLASS_INT64_ARRAY */ uint64_t *uint64_ptr; /* JS_CLASS_UINT64_ARRAY */ uint16_t *fp16_ptr; /* JS_CLASS_FLOAT16_ARRAY */ float *float_ptr; /* JS_CLASS_FLOAT32_ARRAY */ double *double_ptr; /* JS_CLASS_FLOAT64_ARRAY */ } u; uint32_t count; /* <= 2^31-1. 0 for a detached typed array */ } array; /* 12/20 bytes */ JSRegExp regexp; /* JS_CLASS_REGEXP: 8/16 bytes */ JSValue object_data; /* for JS_SetObjectData(): 8/16/16 bytes */ JSGlobalObject global_object; } u; }; typedef struct JSMapRecord { int ref_count; /* used during enumeration to avoid freeing the record */ BOOL empty : 8; /* TRUE if the record is deleted */ struct list_head link; struct JSMapRecord *hash_next; JSValue key; JSValue value; } JSMapRecord; typedef struct JSMapState { BOOL is_weak; /* TRUE if WeakSet/WeakMap */ struct list_head records; /* list of JSMapRecord.link */ uint32_t record_count; JSMapRecord **hash_table; int hash_bits; uint32_t hash_size; /* = 2 ^ hash_bits */ uint32_t record_count_threshold; /* count at which a hash table resize is needed */ JSWeakRefHeader weakref_header; /* only used if is_weak = TRUE */ } JSMapState; enum { __JS_ATOM_NULL = JS_ATOM_NULL, #define DEF(name, str) JS_ATOM_ ## name, #include "quickjs-atom.h" #undef DEF JS_ATOM_END, }; #define JS_ATOM_LAST_KEYWORD JS_ATOM_super #define JS_ATOM_LAST_STRICT_KEYWORD JS_ATOM_yield static const char js_atom_init[] = #define DEF(name, str) str "\0" #include "quickjs-atom.h" #undef DEF ; typedef enum OPCodeFormat { #define FMT(f) OP_FMT_ ## f, #define DEF(id, size, n_pop, n_push, f) #include "quickjs-opcode.h" #undef DEF #undef FMT } OPCodeFormat; enum OPCodeEnum { #define FMT(f) #define DEF(id, size, n_pop, n_push, f) OP_ ## id, #define def(id, size, n_pop, n_push, f) #include "quickjs-opcode.h" #undef def #undef DEF #undef FMT OP_COUNT, /* excluding temporary opcodes */ /* temporary opcodes : overlap with the short opcodes */ OP_TEMP_START = OP_nop + 1, OP___dummy = OP_TEMP_START - 1, #define FMT(f) #define DEF(id, size, n_pop, n_push, f) #define def(id, size, n_pop, n_push, f) OP_ ## id, #include "quickjs-opcode.h" #undef def #undef DEF #undef FMT OP_TEMP_END, }; static int JS_InitAtoms(JSRuntime *rt); static JSAtom __JS_NewAtomInit(JSRuntime *rt, const char *str, int len, int atom_type); static void JS_FreeAtomStruct(JSRuntime *rt, JSAtomStruct *p); static void free_function_bytecode(JSRuntime *rt, JSFunctionBytecode *b); static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, int argc, JSValueConst *argv, int flags); static JSValue js_call_bound_function(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, int argc, JSValueConst *argv, int flags); static JSValue JS_CallInternal(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, JSValueConst new_target, int argc, JSValue *argv, int flags); static JSValue JS_CallConstructorInternal(JSContext *ctx, JSValueConst func_obj, JSValueConst new_target, int argc, JSValue *argv, int flags); static JSValue JS_CallFree(JSContext *ctx, JSValue func_obj, JSValueConst this_obj, int argc, JSValueConst *argv); static JSValue JS_InvokeFree(JSContext *ctx, JSValue this_val, JSAtom atom, int argc, JSValueConst *argv); static __exception int JS_ToArrayLengthFree(JSContext *ctx, uint32_t *plen, JSValue val, BOOL is_array_ctor); static JSValue JS_EvalObject(JSContext *ctx, JSValueConst this_obj, JSValueConst val, int flags, int scope_idx); JSValue __attribute__((format(printf, 2, 3))) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...); static __maybe_unused void JS_DumpAtoms(JSRuntime *rt); static __maybe_unused void JS_DumpString(JSRuntime *rt, const JSString *p); static __maybe_unused void JS_DumpObjectHeader(JSRuntime *rt); static __maybe_unused void JS_DumpObject(JSRuntime *rt, JSObject *p); static __maybe_unused void JS_DumpGCObject(JSRuntime *rt, JSGCObjectHeader *p); static __maybe_unused void JS_DumpAtom(JSContext *ctx, const char *str, JSAtom atom); static __maybe_unused void JS_DumpValueRT(JSRuntime *rt, const char *str, JSValueConst val); static __maybe_unused void JS_DumpValue(JSContext *ctx, const char *str, JSValueConst val); static __maybe_unused void JS_DumpShapes(JSRuntime *rt); static void js_dump_value_write(void *opaque, const char *buf, size_t len); static JSValue js_function_apply(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic); static void js_array_finalizer(JSRuntime *rt, JSValue val); static void js_array_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_mapped_arguments_finalizer(JSRuntime *rt, JSValue val); static void js_mapped_arguments_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_object_data_finalizer(JSRuntime *rt, JSValue val); static void js_object_data_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_c_function_finalizer(JSRuntime *rt, JSValue val); static void js_c_function_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_bytecode_function_finalizer(JSRuntime *rt, JSValue val); static void js_bytecode_function_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_bound_function_finalizer(JSRuntime *rt, JSValue val); static void js_bound_function_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_for_in_iterator_finalizer(JSRuntime *rt, JSValue val); static void js_for_in_iterator_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_regexp_finalizer(JSRuntime *rt, JSValue val); static void js_array_buffer_finalizer(JSRuntime *rt, JSValue val); static void js_typed_array_finalizer(JSRuntime *rt, JSValue val); static void js_typed_array_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_proxy_finalizer(JSRuntime *rt, JSValue val); static void js_proxy_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_map_finalizer(JSRuntime *rt, JSValue val); static void js_map_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_map_iterator_finalizer(JSRuntime *rt, JSValue val); static void js_map_iterator_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_array_iterator_finalizer(JSRuntime *rt, JSValue val); static void js_array_iterator_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_iterator_concat_finalizer(JSRuntime *rt, JSValue val); static void js_iterator_concat_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_iterator_helper_finalizer(JSRuntime *rt, JSValue val); static void js_iterator_helper_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_iterator_wrap_finalizer(JSRuntime *rt, JSValue val); static void js_iterator_wrap_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_regexp_string_iterator_finalizer(JSRuntime *rt, JSValue val); static void js_regexp_string_iterator_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_generator_finalizer(JSRuntime *rt, JSValue obj); static void js_generator_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_global_object_finalizer(JSRuntime *rt, JSValue obj); static void js_global_object_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_promise_finalizer(JSRuntime *rt, JSValue val); static void js_promise_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static void js_promise_resolve_function_finalizer(JSRuntime *rt, JSValue val); static void js_promise_resolve_function_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); #define HINT_STRING 0 #define HINT_NUMBER 1 #define HINT_NONE 2 #define HINT_FORCE_ORDINARY (1 << 4) // don't try Symbol.toPrimitive static JSValue JS_ToPrimitiveFree(JSContext *ctx, JSValue val, int hint); static JSValue JS_ToStringFree(JSContext *ctx, JSValue val); static int JS_ToBoolFree(JSContext *ctx, JSValue val); static int JS_ToInt32Free(JSContext *ctx, int32_t *pres, JSValue val); static int JS_ToFloat64Free(JSContext *ctx, double *pres, JSValue val); static int JS_ToUint8ClampFree(JSContext *ctx, int32_t *pres, JSValue val); static JSValue js_new_string8_len(JSContext *ctx, const char *buf, int len); static JSValue js_compile_regexp(JSContext *ctx, JSValueConst pattern, JSValueConst flags); static JSValue JS_NewRegexp(JSContext *ctx, JSValue pattern, JSValue bc); static void gc_decref(JSRuntime *rt); static int JS_NewClass1(JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def, JSAtom name); typedef enum JSStrictEqModeEnum { JS_EQ_STRICT, JS_EQ_SAME_VALUE, JS_EQ_SAME_VALUE_ZERO, } JSStrictEqModeEnum; static BOOL js_strict_eq2(JSContext *ctx, JSValue op1, JSValue op2, JSStrictEqModeEnum eq_mode); static BOOL js_strict_eq(JSContext *ctx, JSValueConst op1, JSValueConst op2); static BOOL js_same_value(JSContext *ctx, JSValueConst op1, JSValueConst op2); static BOOL js_same_value_zero(JSContext *ctx, JSValueConst op1, JSValueConst op2); static JSValue JS_ToObject(JSContext *ctx, JSValueConst val); static JSValue JS_ToObjectFree(JSContext *ctx, JSValue val); static JSProperty *add_property(JSContext *ctx, JSObject *p, JSAtom prop, int prop_flags); static void free_property(JSRuntime *rt, JSProperty *pr, int prop_flags); static int JS_ToBigInt64Free(JSContext *ctx, int64_t *pres, JSValue val); JSValue JS_ThrowOutOfMemory(JSContext *ctx); static JSValue JS_ThrowTypeErrorRevokedProxy(JSContext *ctx); static int js_resolve_proxy(JSContext *ctx, JSValueConst *pval, int throw_exception); static int JS_CreateProperty(JSContext *ctx, JSObject *p, JSAtom prop, JSValueConst val, JSValueConst getter, JSValueConst setter, int flags); static int js_string_memcmp(const JSString *p1, int pos1, const JSString *p2, int pos2, int len); static JSValue js_array_buffer_constructor3(JSContext *ctx, JSValueConst new_target, uint64_t len, uint64_t *max_len, JSClassID class_id, uint8_t *buf, JSFreeArrayBufferDataFunc *free_func, void *opaque, BOOL alloc_flag); static void js_array_buffer_free(JSRuntime *rt, void *opaque, void *ptr); static JSArrayBuffer *js_get_array_buffer(JSContext *ctx, JSValueConst obj); static BOOL array_buffer_is_resizable(const JSArrayBuffer *abuf); static JSValue js_typed_array_constructor(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int classid); static JSValue js_typed_array_constructor_ta(JSContext *ctx, JSValueConst new_target, JSValueConst src_obj, int classid, uint32_t len); static BOOL typed_array_is_oob(JSObject *p); static int js_typed_array_get_length_unsafe(JSContext *ctx, JSValueConst obj); static JSValue JS_ThrowTypeErrorDetachedArrayBuffer(JSContext *ctx); static JSValue JS_ThrowTypeErrorArrayBufferOOB(JSContext *ctx); static JSVarRef *js_create_var_ref(JSContext *ctx, BOOL is_lexical); static JSVarRef *get_var_ref(JSContext *ctx, JSStackFrame *sf, int var_idx, BOOL is_arg); static void __async_func_free(JSRuntime *rt, JSAsyncFunctionState *s); static void async_func_free(JSRuntime *rt, JSAsyncFunctionState *s); static JSValue js_generator_function_call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, int argc, JSValueConst *argv, int flags); static void js_async_function_resolve_finalizer(JSRuntime *rt, JSValue val); static void js_async_function_resolve_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static JSValue JS_EvalInternal(JSContext *ctx, JSValueConst this_obj, const char *input, size_t input_len, const char *filename, int flags, int scope_idx); static void js_free_module_def(JSRuntime *rt, JSModuleDef *m); static void js_mark_module_def(JSRuntime *rt, JSModuleDef *m, JS_MarkFunc *mark_func); static JSValue js_import_meta(JSContext *ctx); static JSValue js_dynamic_import(JSContext *ctx, JSValueConst specifier, JSValueConst options); static void free_var_ref(JSRuntime *rt, JSVarRef *var_ref); static JSValue js_new_promise_capability(JSContext *ctx, JSValue *resolving_funcs, JSValueConst ctor); static __exception int perform_promise_then(JSContext *ctx, JSValueConst promise, JSValueConst *resolve_reject, JSValueConst *cap_resolving_funcs); static JSValue js_promise_resolve(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic); static JSValue js_promise_then(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv); static BOOL js_string_eq(JSContext *ctx, const JSString *p1, const JSString *p2); static int js_string_compare(JSContext *ctx, const JSString *p1, const JSString *p2); static JSValue JS_ToNumber(JSContext *ctx, JSValueConst val); static int JS_SetPropertyValue(JSContext *ctx, JSValueConst this_obj, JSValue prop, JSValue val, int flags); static int JS_NumberIsInteger(JSContext *ctx, JSValueConst val); static BOOL JS_NumberIsNegativeOrMinusZero(JSContext *ctx, JSValueConst val); static JSValue JS_ToNumberFree(JSContext *ctx, JSValue val); static int JS_GetOwnPropertyInternal(JSContext *ctx, JSPropertyDescriptor *desc, JSObject *p, JSAtom prop); static void js_free_desc(JSContext *ctx, JSPropertyDescriptor *desc); static int JS_AddIntrinsicBasicObjects(JSContext *ctx); static void js_free_shape(JSRuntime *rt, JSShape *sh); static void js_free_shape_null(JSRuntime *rt, JSShape *sh); static int js_shape_prepare_update(JSContext *ctx, JSObject *p, JSShapeProperty **pprs); static int init_shape_hash(JSRuntime *rt); static __exception int js_get_length32(JSContext *ctx, uint32_t *pres, JSValueConst obj); static __exception int js_get_length64(JSContext *ctx, int64_t *pres, JSValueConst obj); static void free_arg_list(JSContext *ctx, JSValue *tab, uint32_t len); static JSValue *build_arg_list(JSContext *ctx, uint32_t *plen, JSValueConst array_arg); static BOOL js_get_fast_array(JSContext *ctx, JSValueConst obj, JSValue **arrpp, uint32_t *countp); static JSValue JS_CreateAsyncFromSyncIterator(JSContext *ctx, JSValueConst sync_iter); static void js_c_function_data_finalizer(JSRuntime *rt, JSValue val); static void js_c_function_data_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); static JSValue js_c_function_data_call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_val, int argc, JSValueConst *argv, int flags); static JSAtom js_symbol_to_atom(JSContext *ctx, JSValue val); static void add_gc_object(JSRuntime *rt, JSGCObjectHeader *h, JSGCObjectTypeEnum type); static void remove_gc_object(JSGCObjectHeader *h); static JSValue js_instantiate_prototype(JSContext *ctx, JSObject *p, JSAtom atom, void *opaque); static JSValue js_module_ns_autoinit(JSContext *ctx, JSObject *p, JSAtom atom, void *opaque); static JSValue JS_InstantiateFunctionListItem2(JSContext *ctx, JSObject *p, JSAtom atom, void *opaque); static JSValue js_object_groupBy(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int is_map); static void map_delete_weakrefs(JSRuntime *rt, JSWeakRefHeader *wh); static void weakref_delete_weakref(JSRuntime *rt, JSWeakRefHeader *wh); static void finrec_delete_weakref(JSRuntime *rt, JSWeakRefHeader *wh); static void JS_RunGCInternal(JSRuntime *rt, BOOL remove_weak_objects); static JSValue js_array_from_iterator(JSContext *ctx, uint32_t *plen, JSValueConst obj, JSValueConst method); static int js_string_find_invalid_codepoint(JSString *p); static JSValue js_regexp_toString(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv); static JSValue get_date_string(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic); static JSValue js_error_toString(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv); static JSVarRef *js_global_object_find_uninitialized_var(JSContext *ctx, JSObject *p, JSAtom atom, BOOL is_lexical); static const JSClassExoticMethods js_arguments_exotic_methods; static const JSClassExoticMethods js_string_exotic_methods; static const JSClassExoticMethods js_proxy_exotic_methods; static const JSClassExoticMethods js_module_ns_exotic_methods; static JSClassID js_class_id_alloc = JS_CLASS_INIT_COUNT; static void js_trigger_gc(JSRuntime *rt, size_t size) { BOOL force_gc; #ifdef FORCE_GC_AT_MALLOC force_gc = TRUE; #else force_gc = ((rt->malloc_state.malloc_size + size) > rt->malloc_gc_threshold); #endif if (force_gc) { #ifdef DUMP_GC printf("GC: size=%" PRIu64 "\n", (uint64_t)rt->malloc_state.malloc_size); #endif JS_RunGC(rt); rt->malloc_gc_threshold = rt->malloc_state.malloc_size + (rt->malloc_state.malloc_size >> 1); } } static size_t js_malloc_usable_size_unknown(const void *ptr) { return 0; } void *js_malloc_rt(JSRuntime *rt, size_t size) { return rt->mf.js_malloc(&rt->malloc_state, size); } void js_free_rt(JSRuntime *rt, void *ptr) { rt->mf.js_free(&rt->malloc_state, ptr); } void *js_realloc_rt(JSRuntime *rt, void *ptr, size_t size) { return rt->mf.js_realloc(&rt->malloc_state, ptr, size); } size_t js_malloc_usable_size_rt(JSRuntime *rt, const void *ptr) { return rt->mf.js_malloc_usable_size(ptr); } void *js_mallocz_rt(JSRuntime *rt, size_t size) { void *ptr; ptr = js_malloc_rt(rt, size); if (!ptr) return NULL; return memset(ptr, 0, size); } /* Throw out of memory in case of error */ void *js_malloc(JSContext *ctx, size_t size) { void *ptr; ptr = js_malloc_rt(ctx->rt, size); if (unlikely(!ptr)) { JS_ThrowOutOfMemory(ctx); return NULL; } return ptr; } /* Throw out of memory in case of error */ void *js_mallocz(JSContext *ctx, size_t size) { void *ptr; ptr = js_mallocz_rt(ctx->rt, size); if (unlikely(!ptr)) { JS_ThrowOutOfMemory(ctx); return NULL; } return ptr; } void js_free(JSContext *ctx, void *ptr) { js_free_rt(ctx->rt, ptr); } /* Throw out of memory in case of error */ void *js_realloc(JSContext *ctx, void *ptr, size_t size) { void *ret; ret = js_realloc_rt(ctx->rt, ptr, size); if (unlikely(!ret && size != 0)) { JS_ThrowOutOfMemory(ctx); return NULL; } return ret; } /* store extra allocated size in *pslack if successful */ void *js_realloc2(JSContext *ctx, void *ptr, size_t size, size_t *pslack) { void *ret; ret = js_realloc_rt(ctx->rt, ptr, size); if (unlikely(!ret && size != 0)) { JS_ThrowOutOfMemory(ctx); return NULL; } if (pslack) { size_t new_size = js_malloc_usable_size_rt(ctx->rt, ret); *pslack = (new_size > size) ? new_size - size : 0; } return ret; } size_t js_malloc_usable_size(JSContext *ctx, const void *ptr) { return js_malloc_usable_size_rt(ctx->rt, ptr); } /* Throw out of memory exception in case of error */ char *js_strndup(JSContext *ctx, const char *s, size_t n) { char *ptr; ptr = js_malloc(ctx, n + 1); if (ptr) { memcpy(ptr, s, n); ptr[n] = '\0'; } return ptr; } char *js_strdup(JSContext *ctx, const char *str) { return js_strndup(ctx, str, strlen(str)); } static no_inline int js_realloc_array(JSContext *ctx, void **parray, int elem_size, int *psize, int req_size) { int new_size; size_t slack; void *new_array; /* XXX: potential arithmetic overflow */ new_size = max_int(req_size, *psize * 3 / 2); new_array = js_realloc2(ctx, *parray, new_size * elem_size, &slack); if (!new_array) return -1; new_size += slack / elem_size; *psize = new_size; *parray = new_array; return 0; } /* resize the array and update its size if req_size > *psize */ static inline int js_resize_array(JSContext *ctx, void **parray, int elem_size, int *psize, int req_size) { if (unlikely(req_size > *psize)) return js_realloc_array(ctx, parray, elem_size, psize, req_size); else return 0; } static inline void js_dbuf_init(JSContext *ctx, DynBuf *s) { dbuf_init2(s, ctx->rt, (DynBufReallocFunc *)js_realloc_rt); } static void *js_realloc_bytecode_rt(void *opaque, void *ptr, size_t size) { JSRuntime *rt = opaque; if (size > (INT32_MAX / 2)) { /* the bytecode cannot be larger than 2G. Leave some slack to avoid some overflows. */ return NULL; } else { return rt->mf.js_realloc(&rt->malloc_state, ptr, size); } } static inline void js_dbuf_bytecode_init(JSContext *ctx, DynBuf *s) { dbuf_init2(s, ctx->rt, js_realloc_bytecode_rt); } static inline int is_digit(int c) { return c >= '0' && c <= '9'; } static inline int string_get(const JSString *p, int idx) { return p->is_wide_char ? p->u.str16[idx] : p->u.str8[idx]; } typedef struct JSClassShortDef { JSAtom class_name; JSClassFinalizer *finalizer; JSClassGCMark *gc_mark; } JSClassShortDef; static JSClassShortDef const js_std_class_def[] = { { JS_ATOM_Object, NULL, NULL }, /* JS_CLASS_OBJECT */ { JS_ATOM_Array, js_array_finalizer, js_array_mark }, /* JS_CLASS_ARRAY */ { JS_ATOM_Error, NULL, NULL }, /* JS_CLASS_ERROR */ { JS_ATOM_Number, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_NUMBER */ { JS_ATOM_String, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_STRING */ { JS_ATOM_Boolean, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_BOOLEAN */ { JS_ATOM_Symbol, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_SYMBOL */ { JS_ATOM_Arguments, js_array_finalizer, js_array_mark }, /* JS_CLASS_ARGUMENTS */ { JS_ATOM_Arguments, js_mapped_arguments_finalizer, js_mapped_arguments_mark }, /* JS_CLASS_MAPPED_ARGUMENTS */ { JS_ATOM_Date, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_DATE */ { JS_ATOM_Object, NULL, NULL }, /* JS_CLASS_MODULE_NS */ { JS_ATOM_Function, js_c_function_finalizer, js_c_function_mark }, /* JS_CLASS_C_FUNCTION */ { JS_ATOM_Function, js_bytecode_function_finalizer, js_bytecode_function_mark }, /* JS_CLASS_BYTECODE_FUNCTION */ { JS_ATOM_Function, js_bound_function_finalizer, js_bound_function_mark }, /* JS_CLASS_BOUND_FUNCTION */ { JS_ATOM_Function, js_c_function_data_finalizer, js_c_function_data_mark }, /* JS_CLASS_C_FUNCTION_DATA */ { JS_ATOM_GeneratorFunction, js_bytecode_function_finalizer, js_bytecode_function_mark }, /* JS_CLASS_GENERATOR_FUNCTION */ { JS_ATOM_ForInIterator, js_for_in_iterator_finalizer, js_for_in_iterator_mark }, /* JS_CLASS_FOR_IN_ITERATOR */ { JS_ATOM_RegExp, js_regexp_finalizer, NULL }, /* JS_CLASS_REGEXP */ { JS_ATOM_ArrayBuffer, js_array_buffer_finalizer, NULL }, /* JS_CLASS_ARRAY_BUFFER */ { JS_ATOM_SharedArrayBuffer, js_array_buffer_finalizer, NULL }, /* JS_CLASS_SHARED_ARRAY_BUFFER */ { JS_ATOM_Uint8ClampedArray, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_UINT8C_ARRAY */ { JS_ATOM_Int8Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_INT8_ARRAY */ { JS_ATOM_Uint8Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_UINT8_ARRAY */ { JS_ATOM_Int16Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_INT16_ARRAY */ { JS_ATOM_Uint16Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_UINT16_ARRAY */ { JS_ATOM_Int32Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_INT32_ARRAY */ { JS_ATOM_Uint32Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_UINT32_ARRAY */ { JS_ATOM_BigInt64Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_BIG_INT64_ARRAY */ { JS_ATOM_BigUint64Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_BIG_UINT64_ARRAY */ { JS_ATOM_Float16Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_FLOAT16_ARRAY */ { JS_ATOM_Float32Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_FLOAT32_ARRAY */ { JS_ATOM_Float64Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_FLOAT64_ARRAY */ { JS_ATOM_DataView, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_DATAVIEW */ { JS_ATOM_BigInt, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_BIG_INT */ { JS_ATOM_Map, js_map_finalizer, js_map_mark }, /* JS_CLASS_MAP */ { JS_ATOM_Set, js_map_finalizer, js_map_mark }, /* JS_CLASS_SET */ { JS_ATOM_WeakMap, js_map_finalizer, js_map_mark }, /* JS_CLASS_WEAKMAP */ { JS_ATOM_WeakSet, js_map_finalizer, js_map_mark }, /* JS_CLASS_WEAKSET */ { JS_ATOM_Iterator, NULL, NULL }, /* JS_CLASS_ITERATOR */ { JS_ATOM_IteratorConcat, js_iterator_concat_finalizer, js_iterator_concat_mark }, /* JS_CLASS_ITERATOR_CONCAT */ { JS_ATOM_IteratorHelper, js_iterator_helper_finalizer, js_iterator_helper_mark }, /* JS_CLASS_ITERATOR_HELPER */ { JS_ATOM_IteratorWrap, js_iterator_wrap_finalizer, js_iterator_wrap_mark }, /* JS_CLASS_ITERATOR_WRAP */ { JS_ATOM_Map_Iterator, js_map_iterator_finalizer, js_map_iterator_mark }, /* JS_CLASS_MAP_ITERATOR */ { JS_ATOM_Set_Iterator, js_map_iterator_finalizer, js_map_iterator_mark }, /* JS_CLASS_SET_ITERATOR */ { JS_ATOM_Array_Iterator, js_array_iterator_finalizer, js_array_iterator_mark }, /* JS_CLASS_ARRAY_ITERATOR */ { JS_ATOM_String_Iterator, js_array_iterator_finalizer, js_array_iterator_mark }, /* JS_CLASS_STRING_ITERATOR */ { JS_ATOM_RegExp_String_Iterator, js_regexp_string_iterator_finalizer, js_regexp_string_iterator_mark }, /* JS_CLASS_REGEXP_STRING_ITERATOR */ { JS_ATOM_Generator, js_generator_finalizer, js_generator_mark }, /* JS_CLASS_GENERATOR */ { JS_ATOM_Object, js_global_object_finalizer, js_global_object_mark }, /* JS_CLASS_GLOBAL_OBJECT */ { JS_ATOM_Object, NULL, NULL }, /* JS_CLASS_RAWJSON */ }; static int init_class_range(JSRuntime *rt, JSClassShortDef const *tab, int start, int count) { JSClassDef cm_s, *cm = &cm_s; int i, class_id; for(i = 0; i < count; i++) { class_id = i + start; memset(cm, 0, sizeof(*cm)); cm->finalizer = tab[i].finalizer; cm->gc_mark = tab[i].gc_mark; if (JS_NewClass1(rt, class_id, cm, tab[i].class_name) < 0) return -1; } return 0; } #if !defined(CONFIG_STACK_CHECK) /* no stack limitation */ static inline uintptr_t js_get_stack_pointer(void) { return 0; } static inline BOOL js_check_stack_overflow(JSRuntime *rt, size_t alloca_size) { return FALSE; } #else /* Note: OS and CPU dependent */ static inline uintptr_t js_get_stack_pointer(void) { return (uintptr_t)__builtin_frame_address(0); } static inline BOOL js_check_stack_overflow(JSRuntime *rt, size_t alloca_size) { uintptr_t sp; sp = js_get_stack_pointer() - alloca_size; return unlikely(sp < rt->stack_limit); } #endif JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque) { JSRuntime *rt; JSMallocState ms; memset(&ms, 0, sizeof(ms)); ms.opaque = opaque; ms.malloc_limit = -1; rt = mf->js_malloc(&ms, sizeof(JSRuntime)); if (!rt) return NULL; memset(rt, 0, sizeof(*rt)); rt->mf = *mf; if (!rt->mf.js_malloc_usable_size) { /* use dummy function if none provided */ rt->mf.js_malloc_usable_size = js_malloc_usable_size_unknown; } rt->malloc_state = ms; rt->malloc_gc_threshold = 256 * 1024; init_list_head(&rt->context_list); init_list_head(&rt->gc_obj_list); init_list_head(&rt->gc_zero_ref_count_list); rt->gc_phase = JS_GC_PHASE_NONE; init_list_head(&rt->weakref_list); #ifdef DUMP_LEAKS init_list_head(&rt->string_list); #endif init_list_head(&rt->job_list); if (JS_InitAtoms(rt)) goto fail; /* create the object, array and function classes */ if (init_class_range(rt, js_std_class_def, JS_CLASS_OBJECT, countof(js_std_class_def)) < 0) goto fail; rt->class_array[JS_CLASS_ARGUMENTS].exotic = &js_arguments_exotic_methods; rt->class_array[JS_CLASS_MAPPED_ARGUMENTS].exotic = &js_arguments_exotic_methods; rt->class_array[JS_CLASS_STRING].exotic = &js_string_exotic_methods; rt->class_array[JS_CLASS_MODULE_NS].exotic = &js_module_ns_exotic_methods; rt->class_array[JS_CLASS_C_FUNCTION].call = js_call_c_function; rt->class_array[JS_CLASS_C_FUNCTION_DATA].call = js_c_function_data_call; rt->class_array[JS_CLASS_BOUND_FUNCTION].call = js_call_bound_function; rt->class_array[JS_CLASS_GENERATOR_FUNCTION].call = js_generator_function_call; if (init_shape_hash(rt)) goto fail; rt->stack_size = JS_DEFAULT_STACK_SIZE; JS_UpdateStackTop(rt); rt->current_exception = JS_UNINITIALIZED; return rt; fail: JS_FreeRuntime(rt); return NULL; } void *JS_GetRuntimeOpaque(JSRuntime *rt) { return rt->user_opaque; } void JS_SetRuntimeOpaque(JSRuntime *rt, void *opaque) { rt->user_opaque = opaque; } /* default memory allocation functions with memory limitation */ static size_t js_def_malloc_usable_size(const void *ptr) { #if 0 #if defined(__APPLE__) return malloc_size(ptr); #elif defined(_WIN32) return _msize((void *)ptr); #elif defined(__EMSCRIPTEN__) return 0; #elif defined(__linux__) || defined(__GLIBC__) return malloc_usable_size((void *)ptr); #else /* change this to `return 0;` if compilation fails */ return malloc_usable_size((void *)ptr); #endif #endif /* 0 */ return 0; } static void *js_def_malloc(JSMallocState *s, size_t size) { void *ptr; /* Do not allocate zero bytes: behavior is platform dependent */ assert(size != 0); if (unlikely(s->malloc_size + size > s->malloc_limit)) return NULL; ptr = malloc(size); if (!ptr) return NULL; s->malloc_count++; s->malloc_size += js_def_malloc_usable_size(ptr) + MALLOC_OVERHEAD; return ptr; } static void js_def_free(JSMallocState *s, void *ptr) { if (!ptr) return; s->malloc_count--; s->malloc_size -= js_def_malloc_usable_size(ptr) + MALLOC_OVERHEAD; free(ptr); } static void *js_def_realloc(JSMallocState *s, void *ptr, size_t size) { size_t old_size; if (!ptr) { if (size == 0) return NULL; return js_def_malloc(s, size); } old_size = js_def_malloc_usable_size(ptr); if (size == 0) { s->malloc_count--; s->malloc_size -= old_size + MALLOC_OVERHEAD; free(ptr); return NULL; } if (s->malloc_size + size - old_size > s->malloc_limit) return NULL; ptr = realloc(ptr, size); if (!ptr) return NULL; s->malloc_size += js_def_malloc_usable_size(ptr) - old_size; return ptr; } static const JSMallocFunctions def_malloc_funcs = { js_def_malloc, js_def_free, js_def_realloc, js_def_malloc_usable_size, }; JSRuntime *JS_NewRuntime(void) { return JS_NewRuntime2(&def_malloc_funcs, NULL); } void JS_SetMemoryLimit(JSRuntime *rt, size_t limit) { rt->malloc_state.malloc_limit = limit; } /* use -1 to disable automatic GC */ void JS_SetGCThreshold(JSRuntime *rt, size_t gc_threshold) { rt->malloc_gc_threshold = gc_threshold; } #define malloc(s) malloc_is_forbidden(s) #define free(p) free_is_forbidden(p) #define realloc(p,s) realloc_is_forbidden(p,s) void JS_SetInterruptHandler(JSRuntime *rt, JSInterruptHandler *cb, void *opaque) { rt->interrupt_handler = cb; rt->interrupt_opaque = opaque; } void JS_SetCanBlock(JSRuntime *rt, BOOL can_block) { rt->can_block = can_block; } void JS_SetSharedArrayBufferFunctions(JSRuntime *rt, const JSSharedArrayBufferFunctions *sf) { rt->sab_funcs = *sf; } void JS_SetStripInfo(JSRuntime *rt, int flags) { rt->strip_flags = flags; } int JS_GetStripInfo(JSRuntime *rt) { return rt->strip_flags; } static int JS_EnqueueJob2(JSContext *ctx, JSJobFunc *job_func, int argc, JSValueConst *argv, BOOL no_exception) { JSRuntime *rt = ctx->rt; JSJobEntry *e; int i; if (no_exception) e = js_malloc_rt(ctx->rt, sizeof(*e) + argc * sizeof(JSValue)); else e = js_malloc(ctx, sizeof(*e) + argc * sizeof(JSValue)); if (!e) return -1; e->realm = JS_DupContext(ctx); e->job_func = job_func; e->argc = argc; for(i = 0; i < argc; i++) { e->argv[i] = JS_DupValue(ctx, argv[i]); } list_add_tail(&e->link, &rt->job_list); return 0; } /* return 0 if OK, < 0 if exception */ int JS_EnqueueJob(JSContext *ctx, JSJobFunc *job_func, int argc, JSValueConst *argv) { return JS_EnqueueJob2(ctx, job_func, argc, argv, FALSE); } BOOL JS_IsJobPending(JSRuntime *rt) { return !list_empty(&rt->job_list); } /* return < 0 if exception, 0 if no job pending, 1 if a job was executed successfully. The context of the job is stored in '*pctx' if pctx != NULL. It may be NULL if the context was already destroyed or if no job was pending. The 'pctx' parameter is now absolete. */ int JS_ExecutePendingJob(JSRuntime *rt, JSContext **pctx) { JSContext *ctx; JSJobEntry *e; JSValue res; int i, ret; if (list_empty(&rt->job_list)) { if (pctx) *pctx = NULL; return 0; } /* get the first pending job and execute it */ e = list_entry(rt->job_list.next, JSJobEntry, link); list_del(&e->link); ctx = e->realm; res = e->job_func(ctx, e->argc, (JSValueConst *)e->argv); for(i = 0; i < e->argc; i++) JS_FreeValue(ctx, e->argv[i]); if (JS_IsException(res)) ret = -1; else ret = 1; JS_FreeValue(ctx, res); js_free(ctx, e); if (pctx) { if (ctx->header.ref_count > 1) *pctx = ctx; else *pctx = NULL; } JS_FreeContext(ctx); return ret; } static inline uint32_t atom_get_free(const JSAtomStruct *p) { return (uintptr_t)p >> 1; } static inline BOOL atom_is_free(const JSAtomStruct *p) { return (uintptr_t)p & 1; } static inline JSAtomStruct *atom_set_free(uint32_t v) { return (JSAtomStruct *)(((uintptr_t)v << 1) | 1); } /* Note: the string contents are uninitialized */ static JSString *js_alloc_string_rt(JSRuntime *rt, int max_len, int is_wide_char) { JSString *str; str = js_malloc_rt(rt, sizeof(JSString) + (max_len << is_wide_char) + 1 - is_wide_char); if (unlikely(!str)) return NULL; str->header.ref_count = 1; str->is_wide_char = is_wide_char; str->len = max_len; str->atom_type = 0; str->hash = 0; /* optional but costless */ str->hash_next = 0; /* optional */ #ifdef DUMP_LEAKS list_add_tail(&str->link, &rt->string_list); #endif return str; } static JSString *js_alloc_string(JSContext *ctx, int max_len, int is_wide_char) { JSString *p; p = js_alloc_string_rt(ctx->rt, max_len, is_wide_char); if (unlikely(!p)) { JS_ThrowOutOfMemory(ctx); return NULL; } return p; } /* same as JS_FreeValueRT() but faster */ static inline void js_free_string(JSRuntime *rt, JSString *str) { if (--str->header.ref_count <= 0) { if (str->atom_type) { JS_FreeAtomStruct(rt, str); } else { #ifdef DUMP_LEAKS list_del(&str->link); #endif js_free_rt(rt, str); } } } void JS_SetRuntimeInfo(JSRuntime *rt, const char *s) { if (rt) rt->rt_info = s; } void JS_FreeRuntime(JSRuntime *rt) { struct list_head *el, *el1; int i; JS_FreeValueRT(rt, rt->current_exception); list_for_each_safe(el, el1, &rt->job_list) { JSJobEntry *e = list_entry(el, JSJobEntry, link); for(i = 0; i < e->argc; i++) JS_FreeValueRT(rt, e->argv[i]); JS_FreeContext(e->realm); js_free_rt(rt, e); } init_list_head(&rt->job_list); /* don't remove the weak objects to avoid create new jobs with FinalizationRegistry */ JS_RunGCInternal(rt, FALSE); #ifdef DUMP_LEAKS /* leaking objects */ { BOOL header_done; JSGCObjectHeader *p; int count; /* remove the internal refcounts to display only the object referenced externally */ list_for_each(el, &rt->gc_obj_list) { p = list_entry(el, JSGCObjectHeader, link); p->mark = 0; } gc_decref(rt); header_done = FALSE; list_for_each(el, &rt->gc_obj_list) { p = list_entry(el, JSGCObjectHeader, link); if (p->ref_count != 0) { if (!header_done) { printf("Object leaks:\n"); JS_DumpObjectHeader(rt); header_done = TRUE; } JS_DumpGCObject(rt, p); } } count = 0; list_for_each(el, &rt->gc_obj_list) { p = list_entry(el, JSGCObjectHeader, link); if (p->ref_count == 0) { count++; } } if (count != 0) printf("Secondary object leaks: %d\n", count); } #endif assert(list_empty(&rt->gc_obj_list)); assert(list_empty(&rt->weakref_list)); /* free the classes */ for(i = 0; i < rt->class_count; i++) { JSClass *cl = &rt->class_array[i]; if (cl->class_id != 0) { JS_FreeAtomRT(rt, cl->class_name); } } js_free_rt(rt, rt->class_array); #ifdef DUMP_LEAKS /* only the atoms defined in JS_InitAtoms() should be left */ { BOOL header_done = FALSE; for(i = 0; i < rt->atom_size; i++) { JSAtomStruct *p = rt->atom_array[i]; if (!atom_is_free(p) /* && p->str*/) { if (i >= JS_ATOM_END || p->header.ref_count != 1) { if (!header_done) { header_done = TRUE; if (rt->rt_info) { printf("%s:1: atom leakage:", rt->rt_info); } else { printf("Atom leaks:\n" " %6s %6s %s\n", "ID", "REFCNT", "NAME"); } } if (rt->rt_info) { printf(" "); } else { printf(" %6u %6u ", i, p->header.ref_count); } switch (p->atom_type) { case JS_ATOM_TYPE_STRING: JS_DumpString(rt, p); break; case JS_ATOM_TYPE_GLOBAL_SYMBOL: printf("Symbol.for("); JS_DumpString(rt, p); printf(")"); break; case JS_ATOM_TYPE_SYMBOL: if (p->hash != JS_ATOM_HASH_PRIVATE) { printf("Symbol("); JS_DumpString(rt, p); printf(")"); } else { printf("Private("); JS_DumpString(rt, p); printf(")"); } break; } if (rt->rt_info) { printf(":%u", p->header.ref_count); } else { printf("\n"); } } } } if (rt->rt_info && header_done) printf("\n"); } #endif /* free the atoms */ for(i = 0; i < rt->atom_size; i++) { JSAtomStruct *p = rt->atom_array[i]; if (!atom_is_free(p)) { #ifdef DUMP_LEAKS list_del(&p->link); #endif js_free_rt(rt, p); } } js_free_rt(rt, rt->atom_array); js_free_rt(rt, rt->atom_hash); js_free_rt(rt, rt->shape_hash); #ifdef DUMP_LEAKS if (!list_empty(&rt->string_list)) { if (rt->rt_info) { printf("%s:1: string leakage:", rt->rt_info); } else { printf("String leaks:\n" " %6s %s\n", "REFCNT", "VALUE"); } list_for_each_safe(el, el1, &rt->string_list) { JSString *str = list_entry(el, JSString, link); if (rt->rt_info) { printf(" "); } else { printf(" %6u ", str->header.ref_count); } JS_DumpString(rt, str); if (rt->rt_info) { printf(":%u", str->header.ref_count); } else { printf("\n"); } list_del(&str->link); js_free_rt(rt, str); } if (rt->rt_info) printf("\n"); } { JSMallocState *s = &rt->malloc_state; if (s->malloc_count > 1) { if (rt->rt_info) printf("%s:1: ", rt->rt_info); printf("Memory leak: %"PRIu64" bytes lost in %"PRIu64" block%s\n", (uint64_t)(s->malloc_size - sizeof(JSRuntime)), (uint64_t)(s->malloc_count - 1), &"s"[s->malloc_count == 2]); } } #endif { JSMallocState ms = rt->malloc_state; rt->mf.js_free(&ms, rt); } } JSContext *JS_NewContextRaw(JSRuntime *rt) { JSContext *ctx; int i; ctx = js_mallocz_rt(rt, sizeof(JSContext)); if (!ctx) return NULL; ctx->header.ref_count = 1; add_gc_object(rt, &ctx->header, JS_GC_OBJ_TYPE_JS_CONTEXT); ctx->class_proto = js_malloc_rt(rt, sizeof(ctx->class_proto[0]) * rt->class_count); if (!ctx->class_proto) { js_free_rt(rt, ctx); return NULL; } ctx->rt = rt; list_add_tail(&ctx->link, &rt->context_list); for(i = 0; i < rt->class_count; i++) ctx->class_proto[i] = JS_NULL; ctx->array_ctor = JS_NULL; ctx->iterator_ctor = JS_NULL; ctx->regexp_ctor = JS_NULL; ctx->promise_ctor = JS_NULL; init_list_head(&ctx->loaded_modules); if (JS_AddIntrinsicBasicObjects(ctx)) { JS_FreeContext(ctx); return NULL; } return ctx; } JSContext *JS_NewContext(JSRuntime *rt) { JSContext *ctx; ctx = JS_NewContextRaw(rt); if (!ctx) return NULL; if (JS_AddIntrinsicBaseObjects(ctx) || JS_AddIntrinsicDate(ctx) || JS_AddIntrinsicEval(ctx) || JS_AddIntrinsicStringNormalize(ctx) || JS_AddIntrinsicRegExp(ctx) || JS_AddIntrinsicJSON(ctx) || JS_AddIntrinsicProxy(ctx) || JS_AddIntrinsicMapSet(ctx) || JS_AddIntrinsicTypedArrays(ctx) || JS_AddIntrinsicPromise(ctx) || JS_AddIntrinsicWeakRef(ctx)) { JS_FreeContext(ctx); return NULL; } return ctx; } void *JS_GetContextOpaque(JSContext *ctx) { return ctx->user_opaque; } void JS_SetContextOpaque(JSContext *ctx, void *opaque) { ctx->user_opaque = opaque; } /* set the new value and free the old value after (freeing the value can reallocate the object data) */ static inline void set_value(JSContext *ctx, JSValue *pval, JSValue new_val) { JSValue old_val; old_val = *pval; *pval = new_val; JS_FreeValue(ctx, old_val); } void JS_SetClassProto(JSContext *ctx, JSClassID class_id, JSValue obj) { JSRuntime *rt = ctx->rt; assert(class_id < rt->class_count); set_value(ctx, &ctx->class_proto[class_id], obj); } JSValue JS_GetClassProto(JSContext *ctx, JSClassID class_id) { JSRuntime *rt = ctx->rt; assert(class_id < rt->class_count); return JS_DupValue(ctx, ctx->class_proto[class_id]); } typedef enum JSFreeModuleEnum { JS_FREE_MODULE_ALL, JS_FREE_MODULE_NOT_RESOLVED, } JSFreeModuleEnum; /* XXX: would be more efficient with separate module lists */ static void js_free_modules(JSContext *ctx, JSFreeModuleEnum flag) { struct list_head *el, *el1; list_for_each_safe(el, el1, &ctx->loaded_modules) { JSModuleDef *m = list_entry(el, JSModuleDef, link); if (flag == JS_FREE_MODULE_ALL || (flag == JS_FREE_MODULE_NOT_RESOLVED && !m->resolved)) { /* warning: the module may be referenced elsewhere. It could be simpler to use an array instead of a list for 'ctx->loaded_modules' */ list_del(&m->link); m->link.prev = NULL; m->link.next = NULL; JS_FreeValue(ctx, JS_MKPTR(JS_TAG_MODULE, m)); } } } JSContext *JS_DupContext(JSContext *ctx) { ctx->header.ref_count++; return ctx; } /* used by the GC */ static void JS_MarkContext(JSRuntime *rt, JSContext *ctx, JS_MarkFunc *mark_func) { int i; struct list_head *el; list_for_each(el, &ctx->loaded_modules) { JSModuleDef *m = list_entry(el, JSModuleDef, link); JS_MarkValue(rt, JS_MKPTR(JS_TAG_MODULE, m), mark_func); } JS_MarkValue(rt, ctx->global_obj, mark_func); JS_MarkValue(rt, ctx->global_var_obj, mark_func); JS_MarkValue(rt, ctx->throw_type_error, mark_func); JS_MarkValue(rt, ctx->eval_obj, mark_func); JS_MarkValue(rt, ctx->array_proto_values, mark_func); for(i = 0; i < JS_NATIVE_ERROR_COUNT; i++) { JS_MarkValue(rt, ctx->native_error_proto[i], mark_func); } for(i = 0; i < rt->class_count; i++) { JS_MarkValue(rt, ctx->class_proto[i], mark_func); } JS_MarkValue(rt, ctx->iterator_ctor, mark_func); JS_MarkValue(rt, ctx->async_iterator_proto, mark_func); JS_MarkValue(rt, ctx->promise_ctor, mark_func); JS_MarkValue(rt, ctx->array_ctor, mark_func); JS_MarkValue(rt, ctx->regexp_ctor, mark_func); JS_MarkValue(rt, ctx->function_ctor, mark_func); JS_MarkValue(rt, ctx->function_proto, mark_func); if (ctx->array_shape) mark_func(rt, &ctx->array_shape->header); if (ctx->arguments_shape) mark_func(rt, &ctx->arguments_shape->header); if (ctx->mapped_arguments_shape) mark_func(rt, &ctx->mapped_arguments_shape->header); if (ctx->regexp_shape) mark_func(rt, &ctx->regexp_shape->header); if (ctx->regexp_result_shape) mark_func(rt, &ctx->regexp_result_shape->header); } void JS_FreeContext(JSContext *ctx) { JSRuntime *rt = ctx->rt; int i; if (--ctx->header.ref_count > 0) return; assert(ctx->header.ref_count == 0); #ifdef DUMP_ATOMS JS_DumpAtoms(ctx->rt); #endif #ifdef DUMP_SHAPES JS_DumpShapes(ctx->rt); #endif #ifdef DUMP_OBJECTS { struct list_head *el; JSGCObjectHeader *p; printf("JSObjects: {\n"); JS_DumpObjectHeader(ctx->rt); list_for_each(el, &rt->gc_obj_list) { p = list_entry(el, JSGCObjectHeader, link); JS_DumpGCObject(rt, p); } printf("}\n"); } #endif #ifdef DUMP_MEM { JSMemoryUsage stats; JS_ComputeMemoryUsage(rt, &stats); JS_DumpMemoryUsage(stdout, &stats, rt); } #endif js_free_modules(ctx, JS_FREE_MODULE_ALL); JS_FreeValue(ctx, ctx->global_obj); JS_FreeValue(ctx, ctx->global_var_obj); JS_FreeValue(ctx, ctx->throw_type_error); JS_FreeValue(ctx, ctx->eval_obj); JS_FreeValue(ctx, ctx->array_proto_values); for(i = 0; i < JS_NATIVE_ERROR_COUNT; i++) { JS_FreeValue(ctx, ctx->native_error_proto[i]); } for(i = 0; i < rt->class_count; i++) { JS_FreeValue(ctx, ctx->class_proto[i]); } js_free_rt(rt, ctx->class_proto); JS_FreeValue(ctx, ctx->iterator_ctor); JS_FreeValue(ctx, ctx->async_iterator_proto); JS_FreeValue(ctx, ctx->promise_ctor); JS_FreeValue(ctx, ctx->array_ctor); JS_FreeValue(ctx, ctx->regexp_ctor); JS_FreeValue(ctx, ctx->function_ctor); JS_FreeValue(ctx, ctx->function_proto); js_free_shape_null(ctx->rt, ctx->array_shape); js_free_shape_null(ctx->rt, ctx->arguments_shape); js_free_shape_null(ctx->rt, ctx->mapped_arguments_shape); js_free_shape_null(ctx->rt, ctx->regexp_shape); js_free_shape_null(ctx->rt, ctx->regexp_result_shape); list_del(&ctx->link); remove_gc_object(&ctx->header); js_free_rt(ctx->rt, ctx); } JSRuntime *JS_GetRuntime(JSContext *ctx) { return ctx->rt; } static void update_stack_limit(JSRuntime *rt) { if (rt->stack_size == 0) { rt->stack_limit = 0; /* no limit */ } else { rt->stack_limit = rt->stack_top - rt->stack_size; } } void JS_SetMaxStackSize(JSRuntime *rt, size_t stack_size) { rt->stack_size = stack_size; update_stack_limit(rt); } void JS_UpdateStackTop(JSRuntime *rt) { rt->stack_top = js_get_stack_pointer(); update_stack_limit(rt); } static inline BOOL is_strict_mode(JSContext *ctx) { JSStackFrame *sf = ctx->rt->current_stack_frame; return (sf && (sf->js_mode & JS_MODE_STRICT)); } /* JSAtom support */ #define JS_ATOM_TAG_INT (1U << 31) #define JS_ATOM_MAX_INT (JS_ATOM_TAG_INT - 1) #define JS_ATOM_MAX ((1U << 30) - 1) /* return the max count from the hash size */ #define JS_ATOM_COUNT_RESIZE(n) ((n) * 2) static inline BOOL __JS_AtomIsConst(JSAtom v) { #if defined(DUMP_LEAKS) && DUMP_LEAKS > 1 return (int32_t)v <= 0; #else return (int32_t)v < JS_ATOM_END; #endif } static inline BOOL __JS_AtomIsTaggedInt(JSAtom v) { return (v & JS_ATOM_TAG_INT) != 0; } static inline JSAtom __JS_AtomFromUInt32(uint32_t v) { return v | JS_ATOM_TAG_INT; } static inline uint32_t __JS_AtomToUInt32(JSAtom atom) { return atom & ~JS_ATOM_TAG_INT; } static inline int is_num(int c) { return c >= '0' && c <= '9'; } /* return TRUE if the string is a number n with 0 <= n <= 2^32-1 */ static inline BOOL is_num_string(uint32_t *pval, const JSString *p) { uint32_t n; uint64_t n64; int c, i, len; len = p->len; if (len == 0 || len > 10) return FALSE; c = string_get(p, 0); if (is_num(c)) { if (c == '0') { if (len != 1) return FALSE; n = 0; } else { n = c - '0'; for(i = 1; i < len; i++) { c = string_get(p, i); if (!is_num(c)) return FALSE; n64 = (uint64_t)n * 10 + (c - '0'); if ((n64 >> 32) != 0) return FALSE; n = n64; } } *pval = n; return TRUE; } else { return FALSE; } } /* XXX: could use faster version ? */ static inline uint32_t hash_string8(const uint8_t *str, size_t len, uint32_t h) { size_t i; for(i = 0; i < len; i++) h = h * 263 + str[i]; return h; } static inline uint32_t hash_string16(const uint16_t *str, size_t len, uint32_t h) { size_t i; for(i = 0; i < len; i++) h = h * 263 + str[i]; return h; } static uint32_t hash_string(const JSString *str, uint32_t h) { if (str->is_wide_char) h = hash_string16(str->u.str16, str->len, h); else h = hash_string8(str->u.str8, str->len, h); return h; } static uint32_t hash_string_rope(JSValueConst val, uint32_t h) { if (JS_VALUE_GET_TAG(val) == JS_TAG_STRING) { return hash_string(JS_VALUE_GET_STRING(val), h); } else { JSStringRope *r = JS_VALUE_GET_STRING_ROPE(val); h = hash_string_rope(r->left, h); return hash_string_rope(r->right, h); } } static __maybe_unused void JS_DumpChar(FILE *fo, int c, int sep) { if (c == sep || c == '\\') { fputc('\\', fo); fputc(c, fo); } else if (c >= ' ' && c <= 126) { fputc(c, fo); } else if (c == '\n') { fputc('\\', fo); fputc('n', fo); } else { fprintf(fo, "\\u%04x", c); } } static __maybe_unused void JS_DumpString(JSRuntime *rt, const JSString *p) { int i, sep; if (p == NULL) { printf("<null>"); return; } printf("%d", p->header.ref_count); sep = (p->header.ref_count == 1) ? '\"' : '\''; putchar(sep); for(i = 0; i < p->len; i++) { JS_DumpChar(stdout, string_get(p, i), sep); } putchar(sep); } static __maybe_unused void JS_DumpAtoms(JSRuntime *rt) { JSAtomStruct *p; int h, i; /* This only dumps hashed atoms, not JS_ATOM_TYPE_SYMBOL atoms */ printf("JSAtom count=%d size=%d hash_size=%d:\n", rt->atom_count, rt->atom_size, rt->atom_hash_size); printf("JSAtom hash table: {\n"); for(i = 0; i < rt->atom_hash_size; i++) { h = rt->atom_hash[i]; if (h) { printf(" %d:", i); while (h) { p = rt->atom_array[h]; printf(" "); JS_DumpString(rt, p); h = p->hash_next; } printf("\n"); } } printf("}\n"); printf("JSAtom table: {\n"); for(i = 0; i < rt->atom_size; i++) { p = rt->atom_array[i]; if (!atom_is_free(p)) { printf(" %d: { %d %08x ", i, p->atom_type, p->hash); if (!(p->len == 0 && p->is_wide_char != 0)) JS_DumpString(rt, p); printf(" %d }\n", p->hash_next); } } printf("}\n"); } static int JS_ResizeAtomHash(JSRuntime *rt, int new_hash_size) { JSAtomStruct *p; uint32_t new_hash_mask, h, i, hash_next1, j, *new_hash; assert((new_hash_size & (new_hash_size - 1)) == 0); /* power of two */ new_hash_mask = new_hash_size - 1; new_hash = js_mallocz_rt(rt, sizeof(rt->atom_hash[0]) * new_hash_size); if (!new_hash) return -1; for(i = 0; i < rt->atom_hash_size; i++) { h = rt->atom_hash[i]; while (h != 0) { p = rt->atom_array[h]; hash_next1 = p->hash_next; /* add in new hash table */ j = p->hash & new_hash_mask; p->hash_next = new_hash[j]; new_hash[j] = h; h = hash_next1; } } js_free_rt(rt, rt->atom_hash); rt->atom_hash = new_hash; rt->atom_hash_size = new_hash_size; rt->atom_count_resize = JS_ATOM_COUNT_RESIZE(new_hash_size); // JS_DumpAtoms(rt); return 0; } static int JS_InitAtoms(JSRuntime *rt) { int i, len, atom_type; const char *p; rt->atom_hash_size = 0; rt->atom_hash = NULL; rt->atom_count = 0; rt->atom_size = 0; rt->atom_free_index = 0; if (JS_ResizeAtomHash(rt, 512)) /* there are at least 504 predefined atoms */ return -1; p = js_atom_init; for(i = 1; i < JS_ATOM_END; i++) { if (i == JS_ATOM_Private_brand) atom_type = JS_ATOM_TYPE_PRIVATE; else if (i >= JS_ATOM_Symbol_toPrimitive) atom_type = JS_ATOM_TYPE_SYMBOL; else atom_type = JS_ATOM_TYPE_STRING; len = strlen(p); if (__JS_NewAtomInit(rt, p, len, atom_type) == JS_ATOM_NULL) return -1; p = p + len + 1; } return 0; } static JSAtom JS_DupAtomRT(JSRuntime *rt, JSAtom v) { JSAtomStruct *p; if (!__JS_AtomIsConst(v)) { p = rt->atom_array[v]; p->header.ref_count++; } return v; } JSAtom JS_DupAtom(JSContext *ctx, JSAtom v) { JSRuntime *rt; JSAtomStruct *p; if (!__JS_AtomIsConst(v)) { rt = ctx->rt; p = rt->atom_array[v]; p->header.ref_count++; } return v; } static JSAtomKindEnum JS_AtomGetKind(JSContext *ctx, JSAtom v) { JSRuntime *rt; JSAtomStruct *p; rt = ctx->rt; if (__JS_AtomIsTaggedInt(v)) return JS_ATOM_KIND_STRING; p = rt->atom_array[v]; switch(p->atom_type) { case JS_ATOM_TYPE_STRING: return JS_ATOM_KIND_STRING; case JS_ATOM_TYPE_GLOBAL_SYMBOL: return JS_ATOM_KIND_SYMBOL; case JS_ATOM_TYPE_SYMBOL: if (p->hash == JS_ATOM_HASH_PRIVATE) return JS_ATOM_KIND_PRIVATE; else return JS_ATOM_KIND_SYMBOL; default: abort(); } } static BOOL JS_AtomIsString(JSContext *ctx, JSAtom v) { return JS_AtomGetKind(ctx, v) == JS_ATOM_KIND_STRING; } static JSAtom js_get_atom_index(JSRuntime *rt, JSAtomStruct *p) { uint32_t i = p->hash_next; /* atom_index */ if (p->atom_type != JS_ATOM_TYPE_SYMBOL) { JSAtomStruct *p1; i = rt->atom_hash[p->hash & (rt->atom_hash_size - 1)]; p1 = rt->atom_array[i]; while (p1 != p) { assert(i != 0); i = p1->hash_next; p1 = rt->atom_array[i]; } } return i; } /* string case (internal). Return JS_ATOM_NULL if error. 'str' is freed. */ static JSAtom __JS_NewAtom(JSRuntime *rt, JSString *str, int atom_type) { uint32_t h, h1, i; JSAtomStruct *p; int len; #if 0 printf("__JS_NewAtom: "); JS_DumpString(rt, str); printf("\n"); #endif if (atom_type < JS_ATOM_TYPE_SYMBOL) { /* str is not NULL */ if (str->atom_type == atom_type) { /* str is the atom, return its index */ i = js_get_atom_index(rt, str); /* reduce string refcount and increase atom's unless constant */ if (__JS_AtomIsConst(i)) str->header.ref_count--; return i; } /* try and locate an already registered atom */ len = str->len; h = hash_string(str, atom_type); h &= JS_ATOM_HASH_MASK; h1 = h & (rt->atom_hash_size - 1); i = rt->atom_hash[h1]; while (i != 0) { p = rt->atom_array[i]; if (p->hash == h && p->atom_type == atom_type && p->len == len && js_string_memcmp(p, 0, str, 0, len) == 0) { if (!__JS_AtomIsConst(i)) p->header.ref_count++; goto done; } i = p->hash_next; } } else { h1 = 0; /* avoid warning */ if (atom_type == JS_ATOM_TYPE_SYMBOL) { h = 0; } else { h = JS_ATOM_HASH_PRIVATE; atom_type = JS_ATOM_TYPE_SYMBOL; } } if (rt->atom_free_index == 0) { /* allow new atom entries */ uint32_t new_size, start; JSAtomStruct **new_array; /* alloc new with size progression 3/2: 4 6 9 13 19 28 42 63 94 141 211 316 474 711 1066 1599 2398 3597 5395 8092 preallocating space for predefined atoms (at least 504). */ new_size = max_int(711, rt->atom_size * 3 / 2); if (new_size > JS_ATOM_MAX) goto fail; /* XXX: should use realloc2 to use slack space */ new_array = js_realloc_rt(rt, rt->atom_array, sizeof(*new_array) * new_size); if (!new_array) goto fail; /* Note: the atom 0 is not used */ start = rt->atom_size; if (start == 0) { /* JS_ATOM_NULL entry */ p = js_mallocz_rt(rt, sizeof(JSAtomStruct)); if (!p) { js_free_rt(rt, new_array); goto fail; } p->header.ref_count = 1; /* not refcounted */ p->atom_type = JS_ATOM_TYPE_SYMBOL; #ifdef DUMP_LEAKS list_add_tail(&p->link, &rt->string_list); #endif new_array[0] = p; rt->atom_count++; start = 1; } rt->atom_size = new_size; rt->atom_array = new_array; rt->atom_free_index = start; for(i = start; i < new_size; i++) { uint32_t next; if (i == (new_size - 1)) next = 0; else next = i + 1; rt->atom_array[i] = atom_set_free(next); } } if (str) { if (str->atom_type == 0) { p = str; p->atom_type = atom_type; } else { p = js_malloc_rt(rt, sizeof(JSString) + (str->len << str->is_wide_char) + 1 - str->is_wide_char); if (unlikely(!p)) goto fail; p->header.ref_count = 1; p->is_wide_char = str->is_wide_char; p->len = str->len; #ifdef DUMP_LEAKS list_add_tail(&p->link, &rt->string_list); #endif memcpy(p->u.str8, str->u.str8, (str->len << str->is_wide_char) + 1 - str->is_wide_char); js_free_string(rt, str); } } else { p = js_malloc_rt(rt, sizeof(JSAtomStruct)); /* empty wide string */ if (!p) return JS_ATOM_NULL; p->header.ref_count = 1; p->is_wide_char = 1; /* Hack to represent NULL as a JSString */ p->len = 0; #ifdef DUMP_LEAKS list_add_tail(&p->link, &rt->string_list); #endif } /* use an already free entry */ i = rt->atom_free_index; rt->atom_free_index = atom_get_free(rt->atom_array[i]); rt->atom_array[i] = p; p->hash = h; p->hash_next = i; /* atom_index */ p->atom_type = atom_type; rt->atom_count++; if (atom_type != JS_ATOM_TYPE_SYMBOL) { p->hash_next = rt->atom_hash[h1]; rt->atom_hash[h1] = i; if (unlikely(rt->atom_count >= rt->atom_count_resize)) JS_ResizeAtomHash(rt, rt->atom_hash_size * 2); } // JS_DumpAtoms(rt); return i; fail: i = JS_ATOM_NULL; done: if (str) js_free_string(rt, str); return i; } /* only works with zero terminated 8 bit strings */ static JSAtom __JS_NewAtomInit(JSRuntime *rt, const char *str, int len, int atom_type) { JSString *p; p = js_alloc_string_rt(rt, len, 0); if (!p) return JS_ATOM_NULL; memcpy(p->u.str8, str, len); p->u.str8[len] = '\0'; return __JS_NewAtom(rt, p, atom_type); } /* Warning: str must be ASCII only */ static JSAtom __JS_FindAtom(JSRuntime *rt, const char *str, size_t len, int atom_type) { uint32_t h, h1, i; JSAtomStruct *p; h = hash_string8((const uint8_t *)str, len, JS_ATOM_TYPE_STRING); h &= JS_ATOM_HASH_MASK; h1 = h & (rt->atom_hash_size - 1); i = rt->atom_hash[h1]; while (i != 0) { p = rt->atom_array[i]; if (p->hash == h && p->atom_type == JS_ATOM_TYPE_STRING && p->len == len && p->is_wide_char == 0 && memcmp(p->u.str8, str, len) == 0) { if (!__JS_AtomIsConst(i)) p->header.ref_count++; return i; } i = p->hash_next; } return JS_ATOM_NULL; } static void JS_FreeAtomStruct(JSRuntime *rt, JSAtomStruct *p) { #if 0 /* JS_ATOM_NULL is not refcounted: __JS_AtomIsConst() includes 0 */ if (unlikely(i == JS_ATOM_NULL)) { p->header.ref_count = INT32_MAX / 2; return; } #endif uint32_t i = p->hash_next; /* atom_index */ if (p->atom_type != JS_ATOM_TYPE_SYMBOL) { JSAtomStruct *p0, *p1; uint32_t h0; h0 = p->hash & (rt->atom_hash_size - 1); i = rt->atom_hash[h0]; p1 = rt->atom_array[i]; if (p1 == p) { rt->atom_hash[h0] = p1->hash_next; } else { for(;;) { assert(i != 0); p0 = p1; i = p1->hash_next; p1 = rt->atom_array[i]; if (p1 == p) { p0->hash_next = p1->hash_next; break; } } } } /* insert in free atom list */ rt->atom_array[i] = atom_set_free(rt->atom_free_index); rt->atom_free_index = i; /* free the string structure */ #ifdef DUMP_LEAKS list_del(&p->link); #endif if (p->atom_type == JS_ATOM_TYPE_SYMBOL && p->hash != JS_ATOM_HASH_PRIVATE && p->hash != 0) { /* live weak references are still present on this object: keep it */ } else { js_free_rt(rt, p); } rt->atom_count--; assert(rt->atom_count >= 0); } static void __JS_FreeAtom(JSRuntime *rt, uint32_t i) { JSAtomStruct *p; p = rt->atom_array[i]; if (--p->header.ref_count > 0) return; JS_FreeAtomStruct(rt, p); } /* Warning: 'p' is freed */ static JSAtom JS_NewAtomStr(JSContext *ctx, JSString *p) { JSRuntime *rt = ctx->rt; uint32_t n; if (is_num_string(&n, p)) { if (n <= JS_ATOM_MAX_INT) { js_free_string(rt, p); return __JS_AtomFromUInt32(n); } } /* XXX: should generate an exception */ return __JS_NewAtom(rt, p, JS_ATOM_TYPE_STRING); } /* XXX: optimize */ static size_t count_ascii(const uint8_t *buf, size_t len) { const uint8_t *p, *p_end; p = buf; p_end = buf + len; while (p < p_end && *p < 128) p++; return p - buf; } /* str is UTF-8 encoded */ JSAtom JS_NewAtomLen(JSContext *ctx, const char *str, size_t len) { JSValue val; if (len == 0 || (!is_digit(*str) && count_ascii((const uint8_t *)str, len) == len)) { JSAtom atom = __JS_FindAtom(ctx->rt, str, len, JS_ATOM_TYPE_STRING); if (atom) return atom; } val = JS_NewStringLen(ctx, str, len); if (JS_IsException(val)) return JS_ATOM_NULL; return JS_NewAtomStr(ctx, JS_VALUE_GET_STRING(val)); } JSAtom JS_NewAtom(JSContext *ctx, const char *str) { return JS_NewAtomLen(ctx, str, strlen(str)); } JSAtom JS_NewAtomUInt32(JSContext *ctx, uint32_t n) { if (n <= JS_ATOM_MAX_INT) { return __JS_AtomFromUInt32(n); } else { char buf[11]; JSValue val; size_t len; len = u32toa(buf, n); val = js_new_string8_len(ctx, buf, len); if (JS_IsException(val)) return JS_ATOM_NULL; return __JS_NewAtom(ctx->rt, JS_VALUE_GET_STRING(val), JS_ATOM_TYPE_STRING); } } static JSAtom JS_NewAtomInt64(JSContext *ctx, int64_t n) { if ((uint64_t)n <= JS_ATOM_MAX_INT) { return __JS_AtomFromUInt32((uint32_t)n); } else { char buf[24]; JSValue val; size_t len; len = i64toa(buf, n); val = js_new_string8_len(ctx, buf, len); if (JS_IsException(val)) return JS_ATOM_NULL; return __JS_NewAtom(ctx->rt, JS_VALUE_GET_STRING(val), JS_ATOM_TYPE_STRING); } } /* 'p' is freed */ static JSValue JS_NewSymbol(JSContext *ctx, JSString *p, int atom_type) { JSRuntime *rt = ctx->rt; JSAtom atom; atom = __JS_NewAtom(rt, p, atom_type); if (atom == JS_ATOM_NULL) return JS_ThrowOutOfMemory(ctx); return JS_MKPTR(JS_TAG_SYMBOL, rt->atom_array[atom]); } /* descr must be a non-numeric string atom */ static JSValue JS_NewSymbolFromAtom(JSContext *ctx, JSAtom descr, int atom_type) { JSRuntime *rt = ctx->rt; JSString *p; assert(!__JS_AtomIsTaggedInt(descr)); assert(descr < rt->atom_size); p = rt->atom_array[descr]; JS_DupValue(ctx, JS_MKPTR(JS_TAG_STRING, p)); return JS_NewSymbol(ctx, p, atom_type); } #define ATOM_GET_STR_BUF_SIZE 64 /* Should only be used for debug. */ static const char *JS_AtomGetStrRT(JSRuntime *rt, char *buf, int buf_size, JSAtom atom) { if (__JS_AtomIsTaggedInt(atom)) { snprintf(buf, buf_size, "%u", __JS_AtomToUInt32(atom)); } else { JSAtomStruct *p; assert(atom < rt->atom_size); if (atom == JS_ATOM_NULL) { snprintf(buf, buf_size, "<null>"); } else { int i, c; char *q; JSString *str; q = buf; p = rt->atom_array[atom]; assert(!atom_is_free(p)); str = p; if (str) { if (!str->is_wide_char) { /* special case ASCII strings */ c = 0; for(i = 0; i < str->len; i++) { c |= str->u.str8[i]; } if (c < 0x80) return (const char *)str->u.str8; } for(i = 0; i < str->len; i++) { c = string_get(str, i); if ((q - buf) >= buf_size - UTF8_CHAR_LEN_MAX) break; if (c < 128) { *q++ = c; } else { q += unicode_to_utf8((uint8_t *)q, c); } } } *q = '\0'; } } return buf; } static const char *JS_AtomGetStr(JSContext *ctx, char *buf, int buf_size, JSAtom atom) { return JS_AtomGetStrRT(ctx->rt, buf, buf_size, atom); } static JSValue __JS_AtomToValue(JSContext *ctx, JSAtom atom, BOOL force_string) { char buf[ATOM_GET_STR_BUF_SIZE]; if (__JS_AtomIsTaggedInt(atom)) { size_t len = u32toa(buf, __JS_AtomToUInt32(atom)); return js_new_string8_len(ctx, buf, len); } else { JSRuntime *rt = ctx->rt; JSAtomStruct *p; assert(atom < rt->atom_size); p = rt->atom_array[atom]; if (p->atom_type == JS_ATOM_TYPE_STRING) { goto ret_string; } else if (force_string) { if (p->len == 0 && p->is_wide_char != 0) { /* no description string */ p = rt->atom_array[JS_ATOM_empty_string]; } ret_string: return JS_DupValue(ctx, JS_MKPTR(JS_TAG_STRING, p)); } else { return JS_DupValue(ctx, JS_MKPTR(JS_TAG_SYMBOL, p)); } } } JSValue JS_AtomToValue(JSContext *ctx, JSAtom atom) { return __JS_AtomToValue(ctx, atom, FALSE); } JSValue JS_AtomToString(JSContext *ctx, JSAtom atom) { return __JS_AtomToValue(ctx, atom, TRUE); } /* return TRUE if the atom is an array index (i.e. 0 <= index <= 2^32-2 and return its value */ static BOOL JS_AtomIsArrayIndex(JSContext *ctx, uint32_t *pval, JSAtom atom) { if (__JS_AtomIsTaggedInt(atom)) { *pval = __JS_AtomToUInt32(atom); return TRUE; } else { JSRuntime *rt = ctx->rt; JSAtomStruct *p; uint32_t val; assert(atom < rt->atom_size); p = rt->atom_array[atom]; if (p->atom_type == JS_ATOM_TYPE_STRING && is_num_string(&val, p) && val != -1) { *pval = val; return TRUE; } else { *pval = 0; return FALSE; } } } /* This test must be fast if atom is not a numeric index (e.g. a method name). Return JS_UNDEFINED if not a numeric index. JS_EXCEPTION can also be returned. */ JSValue JS_AtomIsNumericIndex1(JSContext *ctx, JSAtom atom) { JSRuntime *rt = ctx->rt; JSAtomStruct *p1; JSString *p; int c, ret; JSValue num, str; if (__JS_AtomIsTaggedInt(atom)) return JS_NewInt32(ctx, __JS_AtomToUInt32(atom)); assert(atom < rt->atom_size); p1 = rt->atom_array[atom]; if (p1->atom_type != JS_ATOM_TYPE_STRING) return JS_UNDEFINED; switch(atom) { case JS_ATOM_minus_zero: return __JS_NewFloat64(ctx, -0.0); case JS_ATOM_Infinity: return __JS_NewFloat64(ctx, INFINITY); case JS_ATOM_minus_Infinity: return __JS_NewFloat64(ctx, -INFINITY); case JS_ATOM_NaN: return __JS_NewFloat64(ctx, NAN); default: break; } p = p1; if (p->len == 0) return JS_UNDEFINED; c = string_get(p, 0); if (!is_num(c) && c != '-') return JS_UNDEFINED; /* this is ECMA CanonicalNumericIndexString primitive */ num = JS_ToNumber(ctx, JS_MKPTR(JS_TAG_STRING, p)); if (JS_IsException(num)) return num; str = JS_ToString(ctx, num); if (JS_IsException(str)) { JS_FreeValue(ctx, num); return str; } ret = js_string_eq(ctx, p, JS_VALUE_GET_STRING(str)); JS_FreeValue(ctx, str); if (ret) { return num; } else { JS_FreeValue(ctx, num); return JS_UNDEFINED; } } /* return -1 if exception or TRUE/FALSE */ static int JS_AtomIsNumericIndex(JSContext *ctx, JSAtom atom) { JSValue num; num = JS_AtomIsNumericIndex1(ctx, atom); if (likely(JS_IsUndefined(num))) return FALSE; if (JS_IsException(num)) return -1; JS_FreeValue(ctx, num); return TRUE; } void JS_FreeAtom(JSContext *ctx, JSAtom v) { if (!__JS_AtomIsConst(v)) __JS_FreeAtom(ctx->rt, v); } void JS_FreeAtomRT(JSRuntime *rt, JSAtom v) { if (!__JS_AtomIsConst(v)) __JS_FreeAtom(rt, v); } /* return TRUE if 'v' is a symbol with a string description */ static BOOL JS_AtomSymbolHasDescription(JSContext *ctx, JSAtom v) { JSRuntime *rt; JSAtomStruct *p; rt = ctx->rt; if (__JS_AtomIsTaggedInt(v)) return FALSE; p = rt->atom_array[v]; return (((p->atom_type == JS_ATOM_TYPE_SYMBOL && p->hash != JS_ATOM_HASH_PRIVATE) || p->atom_type == JS_ATOM_TYPE_GLOBAL_SYMBOL) && !(p->len == 0 && p->is_wide_char != 0)); } /* free with JS_FreeCString() */ const char *JS_AtomToCStringLen(JSContext *ctx, size_t *plen, JSAtom atom) { JSValue str; const char *cstr; str = JS_AtomToString(ctx, atom); if (JS_IsException(str)) { if (plen) *plen = 0; return NULL; } cstr = JS_ToCStringLen(ctx, plen, str); JS_FreeValue(ctx, str); return cstr; } /* return a string atom containing name concatenated with str1 */ static JSAtom js_atom_concat_str(JSContext *ctx, JSAtom name, const char *str1) { JSValue str; JSAtom atom; const char *cstr; char *cstr2; size_t len, len1; str = JS_AtomToString(ctx, name); if (JS_IsException(str)) return JS_ATOM_NULL; cstr = JS_ToCStringLen(ctx, &len, str); if (!cstr) goto fail; len1 = strlen(str1); cstr2 = js_malloc(ctx, len + len1 + 1); if (!cstr2) goto fail; memcpy(cstr2, cstr, len); memcpy(cstr2 + len, str1, len1); cstr2[len + len1] = '\0'; atom = JS_NewAtomLen(ctx, cstr2, len + len1); js_free(ctx, cstr2); JS_FreeCString(ctx, cstr); JS_FreeValue(ctx, str); return atom; fail: JS_FreeCString(ctx, cstr); JS_FreeValue(ctx, str); return JS_ATOM_NULL; } static JSAtom js_atom_concat_num(JSContext *ctx, JSAtom name, uint32_t n) { char buf[16]; size_t len; len = u32toa(buf, n); buf[len] = '\0'; return js_atom_concat_str(ctx, name, buf); } static inline BOOL JS_IsEmptyString(JSValueConst v) { return JS_VALUE_GET_TAG(v) == JS_TAG_STRING && JS_VALUE_GET_STRING(v)->len == 0; } /* JSClass support */ #ifdef CONFIG_ATOMICS static pthread_mutex_t js_class_id_mutex = PTHREAD_MUTEX_INITIALIZER; #endif /* a new class ID is allocated if *pclass_id != 0 */ JSClassID JS_NewClassID(JSClassID *pclass_id) { JSClassID class_id; #ifdef CONFIG_ATOMICS pthread_mutex_lock(&js_class_id_mutex); #endif class_id = *pclass_id; if (class_id == 0) { class_id = js_class_id_alloc++; *pclass_id = class_id; } #ifdef CONFIG_ATOMICS pthread_mutex_unlock(&js_class_id_mutex); #endif return class_id; } JSClassID JS_GetClassID(JSValue v) { JSObject *p; if (JS_VALUE_GET_TAG(v) != JS_TAG_OBJECT) return JS_INVALID_CLASS_ID; p = JS_VALUE_GET_OBJ(v); return p->class_id; } BOOL JS_IsRegisteredClass(JSRuntime *rt, JSClassID class_id) { return (class_id < rt->class_count && rt->class_array[class_id].class_id != 0); } /* create a new object internal class. Return -1 if error, 0 if OK. The finalizer can be NULL if none is needed. */ static int JS_NewClass1(JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def, JSAtom name) { int new_size, i; JSClass *cl, *new_class_array; struct list_head *el; if (class_id >= (1 << 16)) return -1; if (class_id < rt->class_count && rt->class_array[class_id].class_id != 0) return -1; if (class_id >= rt->class_count) { new_size = max_int(JS_CLASS_INIT_COUNT, max_int(class_id + 1, rt->class_count * 3 / 2)); /* reallocate the context class prototype array, if any */ list_for_each(el, &rt->context_list) { JSContext *ctx = list_entry(el, JSContext, link); JSValue *new_tab; new_tab = js_realloc_rt(rt, ctx->class_proto, sizeof(ctx->class_proto[0]) * new_size); if (!new_tab) return -1; for(i = rt->class_count; i < new_size; i++) new_tab[i] = JS_NULL; ctx->class_proto = new_tab; } /* reallocate the class array */ new_class_array = js_realloc_rt(rt, rt->class_array, sizeof(JSClass) * new_size); if (!new_class_array) return -1; memset(new_class_array + rt->class_count, 0, (new_size - rt->class_count) * sizeof(JSClass)); rt->class_array = new_class_array; rt->class_count = new_size; } cl = &rt->class_array[class_id]; cl->class_id = class_id; cl->class_name = JS_DupAtomRT(rt, name); cl->finalizer = class_def->finalizer; cl->gc_mark = class_def->gc_mark; cl->call = class_def->call; cl->exotic = class_def->exotic; cl->can_destroy = class_def->can_destroy; return 0; } int JS_NewClass(JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def) { int ret, len; JSAtom name; len = strlen(class_def->class_name); name = __JS_FindAtom(rt, class_def->class_name, len, JS_ATOM_TYPE_STRING); if (name == JS_ATOM_NULL) { name = __JS_NewAtomInit(rt, class_def->class_name, len, JS_ATOM_TYPE_STRING); if (name == JS_ATOM_NULL) return -1; } ret = JS_NewClass1(rt, class_id, class_def, name); JS_FreeAtomRT(rt, name); return ret; } static JSValue js_new_string8_len(JSContext *ctx, const char *buf, int len) { JSString *str; if (len <= 0) { return JS_AtomToString(ctx, JS_ATOM_empty_string); } str = js_alloc_string(ctx, len, 0); if (!str) return JS_EXCEPTION; memcpy(str->u.str8, buf, len); str->u.str8[len] = '\0'; return JS_MKPTR(JS_TAG_STRING, str); } static JSValue js_new_string8(JSContext *ctx, const char *buf) { return js_new_string8_len(ctx, buf, strlen(buf)); } static JSValue js_new_string16_len(JSContext *ctx, const uint16_t *buf, int len) { JSString *str; str = js_alloc_string(ctx, len, 1); if (!str) return JS_EXCEPTION; memcpy(str->u.str16, buf, len * 2); return JS_MKPTR(JS_TAG_STRING, str); } static JSValue js_new_string_char(JSContext *ctx, uint16_t c) { if (c < 0x100) { uint8_t ch8 = c; return js_new_string8_len(ctx, (const char *)&ch8, 1); } else { uint16_t ch16 = c; return js_new_string16_len(ctx, &ch16, 1); } } static JSValue js_sub_string(JSContext *ctx, JSString *p, int start, int end) { int len = end - start; if (start == 0 && end == p->len) { return JS_DupValue(ctx, JS_MKPTR(JS_TAG_STRING, p)); } if (p->is_wide_char && len > 0) { JSString *str; int i; uint16_t c = 0; for (i = start; i < end; i++) { c |= p->u.str16[i]; } if (c > 0xFF) return js_new_string16_len(ctx, p->u.str16 + start, len); str = js_alloc_string(ctx, len, 0); if (!str) return JS_EXCEPTION; for (i = 0; i < len; i++) { str->u.str8[i] = p->u.str16[start + i]; } str->u.str8[len] = '\0'; return JS_MKPTR(JS_TAG_STRING, str); } else { return js_new_string8_len(ctx, (const char *)(p->u.str8 + start), len); } } typedef struct StringBuffer { JSContext *ctx; JSString *str; int len; int size; int is_wide_char; int error_status; } StringBuffer; /* It is valid to call string_buffer_end() and all string_buffer functions even if string_buffer_init() or another string_buffer function returns an error. If the error_status is set, string_buffer_end() returns JS_EXCEPTION. */ static int string_buffer_init2(JSContext *ctx, StringBuffer *s, int size, int is_wide) { s->ctx = ctx; s->size = size; s->len = 0; s->is_wide_char = is_wide; s->error_status = 0; s->str = js_alloc_string(ctx, size, is_wide); if (unlikely(!s->str)) { s->size = 0; return s->error_status = -1; } #ifdef DUMP_LEAKS /* the StringBuffer may reallocate the JSString, only link it at the end */ list_del(&s->str->link); #endif return 0; } static inline int string_buffer_init(JSContext *ctx, StringBuffer *s, int size) { return string_buffer_init2(ctx, s, size, 0); } static void string_buffer_free(StringBuffer *s) { js_free(s->ctx, s->str); s->str = NULL; } static int string_buffer_set_error(StringBuffer *s) { js_free(s->ctx, s->str); s->str = NULL; s->size = 0; s->len = 0; return s->error_status = -1; } static no_inline int string_buffer_widen(StringBuffer *s, int size) { JSString *str; size_t slack; int i; if (s->error_status) return -1; str = js_realloc2(s->ctx, s->str, sizeof(JSString) + (size << 1), &slack); if (!str) return string_buffer_set_error(s); size += slack >> 1; for(i = s->len; i-- > 0;) { str->u.str16[i] = str->u.str8[i]; } s->is_wide_char = 1; s->size = size; s->str = str; return 0; } static no_inline int string_buffer_realloc(StringBuffer *s, int new_len, int c) { JSString *new_str; int new_size; size_t new_size_bytes, slack; if (s->error_status) return -1; if (new_len > JS_STRING_LEN_MAX) { JS_ThrowInternalError(s->ctx, "string too long"); return string_buffer_set_error(s); } new_size = min_int(max_int(new_len, s->size * 3 / 2), JS_STRING_LEN_MAX); if (!s->is_wide_char && c >= 0x100) { return string_buffer_widen(s, new_size); } new_size_bytes = sizeof(JSString) + (new_size << s->is_wide_char) + 1 - s->is_wide_char; new_str = js_realloc2(s->ctx, s->str, new_size_bytes, &slack); if (!new_str) return string_buffer_set_error(s); new_size = min_int(new_size + (slack >> s->is_wide_char), JS_STRING_LEN_MAX); s->size = new_size; s->str = new_str; return 0; } static no_inline int string_buffer_putc16_slow(StringBuffer *s, uint32_t c) { if (unlikely(s->len >= s->size)) { if (string_buffer_realloc(s, s->len + 1, c)) return -1; } if (s->is_wide_char) { s->str->u.str16[s->len++] = c; } else if (c < 0x100) { s->str->u.str8[s->len++] = c; } else { if (string_buffer_widen(s, s->size)) return -1; s->str->u.str16[s->len++] = c; } return 0; } /* 0 <= c <= 0xff */ static int string_buffer_putc8(StringBuffer *s, uint32_t c) { if (unlikely(s->len >= s->size)) { if (string_buffer_realloc(s, s->len + 1, c)) return -1; } if (s->is_wide_char) { s->str->u.str16[s->len++] = c; } else { s->str->u.str8[s->len++] = c; } return 0; } /* 0 <= c <= 0xffff */ static int string_buffer_putc16(StringBuffer *s, uint32_t c) { if (likely(s->len < s->size)) { if (s->is_wide_char) { s->str->u.str16[s->len++] = c; return 0; } else if (c < 0x100) { s->str->u.str8[s->len++] = c; return 0; } } return string_buffer_putc16_slow(s, c); } static int string_buffer_putc_slow(StringBuffer *s, uint32_t c) { if (unlikely(c >= 0x10000)) { /* surrogate pair */ if (string_buffer_putc16(s, get_hi_surrogate(c))) return -1; c = get_lo_surrogate(c); } return string_buffer_putc16(s, c); } /* 0 <= c <= 0x10ffff */ static inline int string_buffer_putc(StringBuffer *s, uint32_t c) { if (likely(s->len < s->size)) { if (s->is_wide_char) { if (c < 0x10000) { s->str->u.str16[s->len++] = c; return 0; } else if (likely((s->len + 1) < s->size)) { s->str->u.str16[s->len++] = get_hi_surrogate(c); s->str->u.str16[s->len++] = get_lo_surrogate(c); return 0; } } else if (c < 0x100) { s->str->u.str8[s->len++] = c; return 0; } } return string_buffer_putc_slow(s, c); } static int string_getc(const JSString *p, int *pidx) { int idx, c, c1; idx = *pidx; if (p->is_wide_char) { c = p->u.str16[idx++]; if (is_hi_surrogate(c) && idx < p->len) { c1 = p->u.str16[idx]; if (is_lo_surrogate(c1)) { c = from_surrogate(c, c1); idx++; } } } else { c = p->u.str8[idx++]; } *pidx = idx; return c; } static int string_buffer_write8(StringBuffer *s, const uint8_t *p, int len) { int i; if (s->len + len > s->size) { if (string_buffer_realloc(s, s->len + len, 0)) return -1; } if (s->is_wide_char) { for (i = 0; i < len; i++) { s->str->u.str16[s->len + i] = p[i]; } s->len += len; } else { memcpy(&s->str->u.str8[s->len], p, len); s->len += len; } return 0; } static int string_buffer_write16(StringBuffer *s, const uint16_t *p, int len) { int c = 0, i; for (i = 0; i < len; i++) { c |= p[i]; } if (s->len + len > s->size) { if (string_buffer_realloc(s, s->len + len, c)) return -1; } else if (!s->is_wide_char && c >= 0x100) { if (string_buffer_widen(s, s->size)) return -1; } if (s->is_wide_char) { memcpy(&s->str->u.str16[s->len], p, len << 1); s->len += len; } else { for (i = 0; i < len; i++) { s->str->u.str8[s->len + i] = p[i]; } s->len += len; } return 0; } /* appending an ASCII string */ static int string_buffer_puts8(StringBuffer *s, const char *str) { return string_buffer_write8(s, (const uint8_t *)str, strlen(str)); } static int string_buffer_concat(StringBuffer *s, const JSString *p, uint32_t from, uint32_t to) { if (to <= from) return 0; if (p->is_wide_char) return string_buffer_write16(s, p->u.str16 + from, to - from); else return string_buffer_write8(s, p->u.str8 + from, to - from); } static int string_buffer_concat_value(StringBuffer *s, JSValueConst v) { JSString *p; JSValue v1; int res; if (s->error_status) { /* prevent exception overload */ return -1; } if (unlikely(JS_VALUE_GET_TAG(v) != JS_TAG_STRING)) { if (JS_VALUE_GET_TAG(v) == JS_TAG_STRING_ROPE) { JSStringRope *r = JS_VALUE_GET_STRING_ROPE(v); /* recursion is acceptable because the rope depth is bounded */ if (string_buffer_concat_value(s, r->left)) return -1; return string_buffer_concat_value(s, r->right); } else { v1 = JS_ToString(s->ctx, v); if (JS_IsException(v1)) return string_buffer_set_error(s); p = JS_VALUE_GET_STRING(v1); res = string_buffer_concat(s, p, 0, p->len); JS_FreeValue(s->ctx, v1); return res; } } p = JS_VALUE_GET_STRING(v); return string_buffer_concat(s, p, 0, p->len); } static int string_buffer_concat_value_free(StringBuffer *s, JSValue v) { JSString *p; int res; if (s->error_status) { /* prevent exception overload */ JS_FreeValue(s->ctx, v); return -1; } if (unlikely(JS_VALUE_GET_TAG(v) != JS_TAG_STRING)) { v = JS_ToStringFree(s->ctx, v); if (JS_IsException(v)) return string_buffer_set_error(s); } p = JS_VALUE_GET_STRING(v); res = string_buffer_concat(s, p, 0, p->len); JS_FreeValue(s->ctx, v); return res; } static int string_buffer_fill(StringBuffer *s, int c, int count) { /* XXX: optimize */ if (s->len + count > s->size) { if (string_buffer_realloc(s, s->len + count, c)) return -1; } while (count-- > 0) { if (string_buffer_putc16(s, c)) return -1; } return 0; } static JSValue string_buffer_end(StringBuffer *s) { JSString *str; str = s->str; if (s->error_status) return JS_EXCEPTION; if (s->len == 0) { js_free(s->ctx, str); s->str = NULL; return JS_AtomToString(s->ctx, JS_ATOM_empty_string); } if (s->len < s->size) { /* smaller size so js_realloc should not fail, but OK if it does */ /* XXX: should add some slack to avoid unnecessary calls */ /* XXX: might need to use malloc+free to ensure smaller size */ str = js_realloc_rt(s->ctx->rt, str, sizeof(JSString) + (s->len << s->is_wide_char) + 1 - s->is_wide_char); if (str == NULL) str = s->str; s->str = str; } if (!s->is_wide_char) str->u.str8[s->len] = 0; #ifdef DUMP_LEAKS list_add_tail(&str->link, &s->ctx->rt->string_list); #endif str->is_wide_char = s->is_wide_char; str->len = s->len; s->str = NULL; return JS_MKPTR(JS_TAG_STRING, str); } /* create a string from a UTF-8 buffer */ JSValue JS_NewStringLen(JSContext *ctx, const char *buf, size_t buf_len) { const uint8_t *p, *p_end, *p_start, *p_next; uint32_t c; StringBuffer b_s, *b = &b_s; size_t len1; p_start = (const uint8_t *)buf; p_end = p_start + buf_len; len1 = count_ascii(p_start, buf_len); p = p_start + len1; if (len1 > JS_STRING_LEN_MAX) return JS_ThrowInternalError(ctx, "string too long"); if (p == p_end) { /* ASCII string */ return js_new_string8_len(ctx, buf, buf_len); } else { if (string_buffer_init(ctx, b, buf_len)) goto fail; string_buffer_write8(b, p_start, len1); while (p < p_end) { if (*p < 128) { string_buffer_putc8(b, *p++); } else { /* parse utf-8 sequence, return 0xFFFFFFFF for error */ c = unicode_from_utf8(p, p_end - p, &p_next); if (c < 0x10000) { p = p_next; } else if (c <= 0x10FFFF) { p = p_next; /* surrogate pair */ string_buffer_putc16(b, get_hi_surrogate(c)); c = get_lo_surrogate(c); } else { /* invalid char */ c = 0xfffd; /* skip the invalid chars */ /* XXX: seems incorrect. Why not just use c = *p++; ? */ while (p < p_end && (*p >= 0x80 && *p < 0xc0)) p++; if (p < p_end) { p++; while (p < p_end && (*p >= 0x80 && *p < 0xc0)) p++; } } string_buffer_putc16(b, c); } } } return string_buffer_end(b); fail: string_buffer_free(b); return JS_EXCEPTION; } static JSValue JS_ConcatString3(JSContext *ctx, const char *str1, JSValue str2, const char *str3) { StringBuffer b_s, *b = &b_s; int len1, len3; JSString *p; if (unlikely(JS_VALUE_GET_TAG(str2) != JS_TAG_STRING)) { str2 = JS_ToStringFree(ctx, str2); if (JS_IsException(str2)) goto fail; } p = JS_VALUE_GET_STRING(str2); len1 = strlen(str1); len3 = strlen(str3); if (string_buffer_init2(ctx, b, len1 + p->len + len3, p->is_wide_char)) goto fail; string_buffer_write8(b, (const uint8_t *)str1, len1); string_buffer_concat(b, p, 0, p->len); string_buffer_write8(b, (const uint8_t *)str3, len3); JS_FreeValue(ctx, str2); return string_buffer_end(b); fail: JS_FreeValue(ctx, str2); return JS_EXCEPTION; } JSValue JS_NewAtomString(JSContext *ctx, const char *str) { JSAtom atom = JS_NewAtom(ctx, str); if (atom == JS_ATOM_NULL) return JS_EXCEPTION; JSValue val = JS_AtomToString(ctx, atom); JS_FreeAtom(ctx, atom); return val; } /* return (NULL, 0) if exception. */ /* return pointer into a JSString with a live ref_count */ /* cesu8 determines if non-BMP1 codepoints are encoded as 1 or 2 utf-8 sequences */ const char *JS_ToCStringLen2(JSContext *ctx, size_t *plen, JSValueConst val1, BOOL cesu8) { JSValue val; JSString *str, *str_new; int pos, len, c, c1; uint8_t *q; if (JS_VALUE_GET_TAG(val1) != JS_TAG_STRING) { val = JS_ToString(ctx, val1); if (JS_IsException(val)) goto fail; } else { val = JS_DupValue(ctx, val1); } str = JS_VALUE_GET_STRING(val); len = str->len; if (!str->is_wide_char) { const uint8_t *src = str->u.str8; int count; /* count the number of non-ASCII characters */ /* Scanning the whole string is required for ASCII strings, and computing the number of non-ASCII bytes is less expensive than testing each byte, hence this method is faster for ASCII strings, which is the most common case. */ count = 0; for (pos = 0; pos < len; pos++) { count += src[pos] >> 7; } if (count == 0) { if (plen) *plen = len; return (const char *)src; } str_new = js_alloc_string(ctx, len + count, 0); if (!str_new) goto fail; q = str_new->u.str8; for (pos = 0; pos < len; pos++) { c = src[pos]; if (c < 0x80) { *q++ = c; } else { *q++ = (c >> 6) | 0xc0; *q++ = (c & 0x3f) | 0x80; } } } else { const uint16_t *src = str->u.str16; /* Allocate 3 bytes per 16 bit code point. Surrogate pairs may produce 4 bytes but use 2 code points. */ str_new = js_alloc_string(ctx, len * 3, 0); if (!str_new) goto fail; q = str_new->u.str8; pos = 0; while (pos < len) { c = src[pos++]; if (c < 0x80) { *q++ = c; } else { if (is_hi_surrogate(c)) { if (pos < len && !cesu8) { c1 = src[pos]; if (is_lo_surrogate(c1)) { pos++; c = from_surrogate(c, c1); } else { /* Keep unmatched surrogate code points */ /* c = 0xfffd; */ /* error */ } } else { /* Keep unmatched surrogate code points */ /* c = 0xfffd; */ /* error */ } } q += unicode_to_utf8(q, c); } } } *q = '\0'; str_new->len = q - str_new->u.str8; JS_FreeValue(ctx, val); if (plen) *plen = str_new->len; return (const char *)str_new->u.str8; fail: if (plen) *plen = 0; return NULL; } void JS_FreeCString(JSContext *ctx, const char *ptr) { JSString *p; if (!ptr) return; /* purposely removing constness */ p = container_of(ptr, JSString, u); JS_FreeValue(ctx, JS_MKPTR(JS_TAG_STRING, p)); } /* create a string from a narrow Unicode (latin-1) buffer */ JSValue JS_NewNarrowStringLen(JSContext *ctx, const char *buf, size_t buf_len) { if (buf_len > JS_STRING_LEN_MAX) return JS_ThrowInternalError(ctx, "string too long"); return js_new_string8_len(ctx, buf, buf_len); } uint8_t *JS_GetNarrowStringBuffer(JSValueConst value) { if (JS_VALUE_GET_TAG(value) != JS_TAG_STRING || JS_VALUE_GET_STRING(value)->is_wide_char) return NULL; return JS_VALUE_GET_STRING(value)->u.str8; } uint32_t JS_GetStringLength(JSValueConst value) { if (unlikely(JS_VALUE_GET_TAG(value) != JS_TAG_STRING)) return 0; return JS_VALUE_GET_STRING(value)->len; } static int memcmp16_8(const uint16_t *src1, const uint8_t *src2, int len) { int c, i; for(i = 0; i < len; i++) { c = src1[i] - src2[i]; if (c != 0) return c; } return 0; } static int memcmp16(const uint16_t *src1, const uint16_t *src2, int len) { int c, i; for(i = 0; i < len; i++) { c = src1[i] - src2[i]; if (c != 0) return c; } return 0; } static int js_string_memcmp(const JSString *p1, int pos1, const JSString *p2, int pos2, int len) { int res; if (likely(!p1->is_wide_char)) { if (likely(!p2->is_wide_char)) res = memcmp(p1->u.str8 + pos1, p2->u.str8 + pos2, len); else res = -memcmp16_8(p2->u.str16 + pos2, p1->u.str8 + pos1, len); } else { if (!p2->is_wide_char) res = memcmp16_8(p1->u.str16 + pos1, p2->u.str8 + pos2, len); else res = memcmp16(p1->u.str16 + pos1, p2->u.str16 + pos2, len); } return res; } static BOOL js_string_eq(JSContext *ctx, const JSString *p1, const JSString *p2) { if (p1->len != p2->len) return FALSE; if (p1 == p2) return TRUE; return js_string_memcmp(p1, 0, p2, 0, p1->len) == 0; } /* return < 0, 0 or > 0 */ static int js_string_compare(JSContext *ctx, const JSString *p1, const JSString *p2) { int res, len; len = min_int(p1->len, p2->len); res = js_string_memcmp(p1, 0, p2, 0, len); if (res == 0) { if (p1->len == p2->len) res = 0; else if (p1->len < p2->len) res = -1; else res = 1; } return res; } static void copy_str16(uint16_t *dst, const JSString *p, int offset, int len) { if (p->is_wide_char) { memcpy(dst, p->u.str16 + offset, len * 2); } else { const uint8_t *src1 = p->u.str8 + offset; int i; for(i = 0; i < len; i++) dst[i] = src1[i]; } } static JSValue JS_ConcatString1(JSContext *ctx, const JSString *p1, const JSString *p2) { JSString *p; uint32_t len; int is_wide_char; len = p1->len + p2->len; if (len > JS_STRING_LEN_MAX) return JS_ThrowInternalError(ctx, "string too long"); is_wide_char = p1->is_wide_char | p2->is_wide_char; p = js_alloc_string(ctx, len, is_wide_char); if (!p) return JS_EXCEPTION; if (!is_wide_char) { memcpy(p->u.str8, p1->u.str8, p1->len); memcpy(p->u.str8 + p1->len, p2->u.str8, p2->len); p->u.str8[len] = '\0'; } else { copy_str16(p->u.str16, p1, 0, p1->len); copy_str16(p->u.str16 + p1->len, p2, 0, p2->len); } return JS_MKPTR(JS_TAG_STRING, p); } static BOOL JS_ConcatStringInPlace(JSContext *ctx, JSString *p1, JSValueConst op2) { if (JS_VALUE_GET_TAG(op2) == JS_TAG_STRING) { JSString *p2 = JS_VALUE_GET_STRING(op2); size_t size1; if (p2->len == 0) return TRUE; if (p1->header.ref_count != 1) return FALSE; size1 = js_malloc_usable_size(ctx, p1); if (p1->is_wide_char) { if (size1 >= sizeof(*p1) + ((p1->len + p2->len) << 1)) { if (p2->is_wide_char) { memcpy(p1->u.str16 + p1->len, p2->u.str16, p2->len << 1); p1->len += p2->len; return TRUE; } else { size_t i; for (i = 0; i < p2->len; i++) { p1->u.str16[p1->len++] = p2->u.str8[i]; } return TRUE; } } } else if (!p2->is_wide_char) { if (size1 >= sizeof(*p1) + p1->len + p2->len + 1) { memcpy(p1->u.str8 + p1->len, p2->u.str8, p2->len); p1->len += p2->len; p1->u.str8[p1->len] = '\0'; return TRUE; } } } return FALSE; } static JSValue JS_ConcatString2(JSContext *ctx, JSValue op1, JSValue op2) { JSValue ret; JSString *p1, *p2; p1 = JS_VALUE_GET_STRING(op1); if (JS_ConcatStringInPlace(ctx, p1, op2)) { JS_FreeValue(ctx, op2); return op1; } p2 = JS_VALUE_GET_STRING(op2); ret = JS_ConcatString1(ctx, p1, p2); JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); return ret; } /* Return the character at position 'idx'. 'val' must be a string or rope */ static int string_rope_get(JSValueConst val, uint32_t idx) { if (JS_VALUE_GET_TAG(val) == JS_TAG_STRING) { return string_get(JS_VALUE_GET_STRING(val), idx); } else { JSStringRope *r = JS_VALUE_GET_STRING_ROPE(val); uint32_t len; if (JS_VALUE_GET_TAG(r->left) == JS_TAG_STRING) len = JS_VALUE_GET_STRING(r->left)->len; else len = JS_VALUE_GET_STRING_ROPE(r->left)->len; if (idx < len) return string_rope_get(r->left, idx); else return string_rope_get(r->right, idx - len); } } typedef struct { JSValueConst stack[JS_STRING_ROPE_MAX_DEPTH]; int stack_len; } JSStringRopeIter; static void string_rope_iter_init(JSStringRopeIter *s, JSValueConst val) { s->stack_len = 0; s->stack[s->stack_len++] = val; } /* iterate thru a rope and return the strings in order */ static JSString *string_rope_iter_next(JSStringRopeIter *s) { JSValueConst val; JSStringRope *r; if (s->stack_len == 0) return NULL; val = s->stack[--s->stack_len]; for(;;) { if (JS_VALUE_GET_TAG(val) == JS_TAG_STRING) return JS_VALUE_GET_STRING(val); r = JS_VALUE_GET_STRING_ROPE(val); assert(s->stack_len < JS_STRING_ROPE_MAX_DEPTH); s->stack[s->stack_len++] = r->right; val = r->left; } } static uint32_t string_rope_get_len(JSValueConst val) { if (JS_VALUE_GET_TAG(val) == JS_TAG_STRING) return JS_VALUE_GET_STRING(val)->len; else return JS_VALUE_GET_STRING_ROPE(val)->len; } static int js_string_rope_compare(JSContext *ctx, JSValueConst op1, JSValueConst op2, BOOL eq_only) { uint32_t len1, len2, len, pos1, pos2, l; int res; JSStringRopeIter it1, it2; JSString *p1, *p2; len1 = string_rope_get_len(op1); len2 = string_rope_get_len(op2); /* no need to go further for equality test if different length */ if (eq_only && len1 != len2) return 1; len = min_uint32(len1, len2); string_rope_iter_init(&it1, op1); string_rope_iter_init(&it2, op2); p1 = string_rope_iter_next(&it1); p2 = string_rope_iter_next(&it2); pos1 = 0; pos2 = 0; while (len != 0) { l = min_uint32(p1->len - pos1, p2->len - pos2); l = min_uint32(l, len); res = js_string_memcmp(p1, pos1, p2, pos2, l); if (res != 0) return res; len -= l; pos1 += l; if (pos1 >= p1->len) { p1 = string_rope_iter_next(&it1); pos1 = 0; } pos2 += l; if (pos2 >= p2->len) { p2 = string_rope_iter_next(&it2); pos2 = 0; } } if (len1 == len2) res = 0; else if (len1 < len2) res = -1; else res = 1; return res; } /* 'rope' must be a rope. return a string and modify the rope so that it won't need to be linearized again. */ static JSValue js_linearize_string_rope(JSContext *ctx, JSValue rope) { StringBuffer b_s, *b = &b_s; JSStringRope *r; JSValue ret; r = JS_VALUE_GET_STRING_ROPE(rope); /* check whether it is already linearized */ if (JS_VALUE_GET_TAG(r->right) == JS_TAG_STRING && JS_VALUE_GET_STRING(r->right)->len == 0) { ret = JS_DupValue(ctx, r->left); JS_FreeValue(ctx, rope); return ret; } if (string_buffer_init2(ctx, b, r->len, r->is_wide_char)) goto fail; if (string_buffer_concat_value(b, rope)) goto fail; ret = string_buffer_end(b); if (r->header.ref_count > 1) { /* update the rope so that it won't need to be linearized again */ JS_FreeValue(ctx, r->left); JS_FreeValue(ctx, r->right); r->left = JS_DupValue(ctx, ret); r->right = JS_AtomToString(ctx, JS_ATOM_empty_string); } JS_FreeValue(ctx, rope); return ret; fail: JS_FreeValue(ctx, rope); return JS_EXCEPTION; } static JSValue js_rebalancee_string_rope(JSContext *ctx, JSValueConst rope); /* op1 and op2 must be strings or string ropes */ static JSValue js_new_string_rope(JSContext *ctx, JSValue op1, JSValue op2) { uint32_t len; int is_wide_char, depth; JSStringRope *r; JSValue res; if (JS_VALUE_GET_TAG(op1) == JS_TAG_STRING) { JSString *p1 = JS_VALUE_GET_STRING(op1); len = p1->len; is_wide_char = p1->is_wide_char; depth = 0; } else { JSStringRope *r1 = JS_VALUE_GET_STRING_ROPE(op1); len = r1->len; is_wide_char = r1->is_wide_char; depth = r1->depth; } if (JS_VALUE_GET_TAG(op2) == JS_TAG_STRING) { JSString *p2 = JS_VALUE_GET_STRING(op2); len += p2->len; is_wide_char |= p2->is_wide_char; } else { JSStringRope *r2 = JS_VALUE_GET_STRING_ROPE(op2); len += r2->len; is_wide_char |= r2->is_wide_char; depth = max_int(depth, r2->depth); } if (len > JS_STRING_LEN_MAX) { JS_ThrowInternalError(ctx, "string too long"); goto fail; } r = js_malloc(ctx, sizeof(*r)); if (!r) goto fail; r->header.ref_count = 1; r->len = len; r->is_wide_char = is_wide_char; r->depth = depth + 1; r->left = op1; r->right = op2; res = JS_MKPTR(JS_TAG_STRING_ROPE, r); if (r->depth > JS_STRING_ROPE_MAX_DEPTH) { JSValue res2; #ifdef DUMP_ROPE_REBALANCE printf("rebalance: initial depth=%d\n", r->depth); #endif res2 = js_rebalancee_string_rope(ctx, res); #ifdef DUMP_ROPE_REBALANCE if (JS_VALUE_GET_TAG(res2) == JS_TAG_STRING_ROPE) printf("rebalance: final depth=%d\n", JS_VALUE_GET_STRING_ROPE(res2)->depth); #endif JS_FreeValue(ctx, res); return res2; } else { return res; } fail: JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); return JS_EXCEPTION; } #define ROPE_N_BUCKETS 44 /* Fibonacii numbers starting from F_2 */ static const uint32_t rope_bucket_len[ROPE_N_BUCKETS] = { 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433494437, 701408733, 1134903170, /* > JS_STRING_LEN_MAX */ }; static int js_rebalancee_string_rope_rec(JSContext *ctx, JSValue *buckets, JSValueConst val) { if (JS_VALUE_GET_TAG(val) == JS_TAG_STRING) { JSString *p = JS_VALUE_GET_STRING(val); uint32_t len, i; JSValue a, b; len = p->len; if (len == 0) return 0; /* nothing to do */ /* find the bucket i so that rope_bucket_len[i] <= len < rope_bucket_len[i + 1] and concatenate the ropes in the buckets before */ a = JS_NULL; i = 0; while (len >= rope_bucket_len[i + 1]) { b = buckets[i]; if (!JS_IsNull(b)) { buckets[i] = JS_NULL; if (JS_IsNull(a)) { a = b; } else { a = js_new_string_rope(ctx, b, a); if (JS_IsException(a)) return -1; } } i++; } if (!JS_IsNull(a)) { a = js_new_string_rope(ctx, a, JS_DupValue(ctx, val)); if (JS_IsException(a)) return -1; } else { a = JS_DupValue(ctx, val); } while (!JS_IsNull(buckets[i])) { a = js_new_string_rope(ctx, buckets[i], a); buckets[i] = JS_NULL; if (JS_IsException(a)) return -1; i++; } buckets[i] = a; } else { JSStringRope *r = JS_VALUE_GET_STRING_ROPE(val); js_rebalancee_string_rope_rec(ctx, buckets, r->left); js_rebalancee_string_rope_rec(ctx, buckets, r->right); } return 0; } /* Return a new rope which is balanced. Algorithm from "Ropes: an Alternative to Strings", Hans-J. Boehm, Russ Atkinson and Michael Plass. */ static JSValue js_rebalancee_string_rope(JSContext *ctx, JSValueConst rope) { JSValue buckets[ROPE_N_BUCKETS], a, b; int i; for(i = 0; i < ROPE_N_BUCKETS; i++) buckets[i] = JS_NULL; if (js_rebalancee_string_rope_rec(ctx, buckets, rope)) goto fail; a = JS_NULL; for(i = 0; i < ROPE_N_BUCKETS; i++) { b = buckets[i]; if (!JS_IsNull(b)) { buckets[i] = JS_NULL; if (JS_IsNull(a)) { a = b; } else { a = js_new_string_rope(ctx, b, a); if (JS_IsException(a)) goto fail; } } } /* fail safe */ if (JS_IsNull(a)) return JS_AtomToString(ctx, JS_ATOM_empty_string); else return a; fail: for(i = 0; i < ROPE_N_BUCKETS; i++) { JS_FreeValue(ctx, buckets[i]); } return JS_EXCEPTION; } /* op1 and op2 are converted to strings. For convenience, op1 or op2 = JS_EXCEPTION are accepted and return JS_EXCEPTION. */ static JSValue JS_ConcatString(JSContext *ctx, JSValue op1, JSValue op2) { JSString *p1, *p2; if (unlikely(JS_VALUE_GET_TAG(op1) != JS_TAG_STRING && JS_VALUE_GET_TAG(op1) != JS_TAG_STRING_ROPE)) { op1 = JS_ToStringFree(ctx, op1); if (JS_IsException(op1)) { JS_FreeValue(ctx, op2); return JS_EXCEPTION; } } if (unlikely(JS_VALUE_GET_TAG(op2) != JS_TAG_STRING && JS_VALUE_GET_TAG(op2) != JS_TAG_STRING_ROPE)) { op2 = JS_ToStringFree(ctx, op2); if (JS_IsException(op2)) { JS_FreeValue(ctx, op1); return JS_EXCEPTION; } } /* normal concatenation for short strings */ if (JS_VALUE_GET_TAG(op2) == JS_TAG_STRING) { p2 = JS_VALUE_GET_STRING(op2); if (p2->len == 0) { JS_FreeValue(ctx, op2); return op1; } if (p2->len <= JS_STRING_ROPE_SHORT_LEN) { if (JS_VALUE_GET_TAG(op1) == JS_TAG_STRING) { p1 = JS_VALUE_GET_STRING(op1); if (p1->len <= JS_STRING_ROPE_SHORT2_LEN) { return JS_ConcatString2(ctx, op1, op2); } else { return js_new_string_rope(ctx, op1, op2); } } else { JSStringRope *r1; r1 = JS_VALUE_GET_STRING_ROPE(op1); if (JS_VALUE_GET_TAG(r1->right) == JS_TAG_STRING && JS_VALUE_GET_STRING(r1->right)->len <= JS_STRING_ROPE_SHORT_LEN) { JSValue val, ret; val = JS_ConcatString2(ctx, JS_DupValue(ctx, r1->right), op2); if (JS_IsException(val)) { JS_FreeValue(ctx, op1); return JS_EXCEPTION; } ret = js_new_string_rope(ctx, JS_DupValue(ctx, r1->left), val); JS_FreeValue(ctx, op1); return ret; } } } } else if (JS_VALUE_GET_TAG(op1) == JS_TAG_STRING) { JSStringRope *r2; p1 = JS_VALUE_GET_STRING(op1); if (p1->len == 0) { JS_FreeValue(ctx, op1); return op2; } r2 = JS_VALUE_GET_STRING_ROPE(op2); if (JS_VALUE_GET_TAG(r2->left) == JS_TAG_STRING && JS_VALUE_GET_STRING(r2->left)->len <= JS_STRING_ROPE_SHORT_LEN) { JSValue val, ret; val = JS_ConcatString2(ctx, op1, JS_DupValue(ctx, r2->left)); if (JS_IsException(val)) { JS_FreeValue(ctx, op2); return JS_EXCEPTION; } ret = js_new_string_rope(ctx, val, JS_DupValue(ctx, r2->right)); JS_FreeValue(ctx, op2); return ret; } } return js_new_string_rope(ctx, op1, op2); } /* Shape support */ static inline size_t get_shape_size(size_t hash_size, size_t prop_size) { return hash_size * sizeof(uint32_t) + sizeof(JSShape) + prop_size * sizeof(JSShapeProperty); } static inline JSShape *get_shape_from_alloc(void *sh_alloc, size_t hash_size) { return (JSShape *)(void *)((uint32_t *)sh_alloc + hash_size); } static inline uint32_t *prop_hash_end(JSShape *sh) { return (uint32_t *)sh; } static inline void *get_alloc_from_shape(JSShape *sh) { return prop_hash_end(sh) - ((intptr_t)sh->prop_hash_mask + 1); } static inline JSShapeProperty *get_shape_prop(JSShape *sh) { return sh->prop; } static int init_shape_hash(JSRuntime *rt) { rt->shape_hash_bits = 4; /* 16 shapes */ rt->shape_hash_size = 1 << rt->shape_hash_bits; rt->shape_hash_count = 0; rt->shape_hash = js_mallocz_rt(rt, sizeof(rt->shape_hash[0]) * rt->shape_hash_size); if (!rt->shape_hash) return -1; return 0; } /* same magic hash multiplier as the Linux kernel */ static uint32_t shape_hash(uint32_t h, uint32_t val) { return (h + val) * 0x9e370001; } /* truncate the shape hash to 'hash_bits' bits */ static uint32_t get_shape_hash(uint32_t h, int hash_bits) { return h >> (32 - hash_bits); } static uint32_t shape_initial_hash(JSObject *proto) { uint32_t h; h = shape_hash(1, (uintptr_t)proto); if (sizeof(proto) > 4) h = shape_hash(h, (uint64_t)(uintptr_t)proto >> 32); return h; } static int resize_shape_hash(JSRuntime *rt, int new_shape_hash_bits) { int new_shape_hash_size, i; uint32_t h; JSShape **new_shape_hash, *sh, *sh_next; new_shape_hash_size = 1 << new_shape_hash_bits; new_shape_hash = js_mallocz_rt(rt, sizeof(rt->shape_hash[0]) * new_shape_hash_size); if (!new_shape_hash) return -1; for(i = 0; i < rt->shape_hash_size; i++) { for(sh = rt->shape_hash[i]; sh != NULL; sh = sh_next) { sh_next = sh->shape_hash_next; h = get_shape_hash(sh->hash, new_shape_hash_bits); sh->shape_hash_next = new_shape_hash[h]; new_shape_hash[h] = sh; } } js_free_rt(rt, rt->shape_hash); rt->shape_hash_bits = new_shape_hash_bits; rt->shape_hash_size = new_shape_hash_size; rt->shape_hash = new_shape_hash; return 0; } static void js_shape_hash_link(JSRuntime *rt, JSShape *sh) { uint32_t h; h = get_shape_hash(sh->hash, rt->shape_hash_bits); sh->shape_hash_next = rt->shape_hash[h]; rt->shape_hash[h] = sh; rt->shape_hash_count++; } static void js_shape_hash_unlink(JSRuntime *rt, JSShape *sh) { uint32_t h; JSShape **psh; h = get_shape_hash(sh->hash, rt->shape_hash_bits); psh = &rt->shape_hash[h]; while (*psh != sh) psh = &(*psh)->shape_hash_next; *psh = sh->shape_hash_next; rt->shape_hash_count--; } /* create a new empty shape with prototype 'proto'. It is not hashed */ static inline JSShape *js_new_shape_nohash(JSContext *ctx, JSObject *proto, int hash_size, int prop_size) { JSRuntime *rt = ctx->rt; void *sh_alloc; JSShape *sh; sh_alloc = js_malloc(ctx, get_shape_size(hash_size, prop_size)); if (!sh_alloc) return NULL; sh = get_shape_from_alloc(sh_alloc, hash_size); sh->header.ref_count = 1; add_gc_object(rt, &sh->header, JS_GC_OBJ_TYPE_SHAPE); if (proto) JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, proto)); sh->proto = proto; memset(prop_hash_end(sh) - hash_size, 0, sizeof(prop_hash_end(sh)[0]) * hash_size); sh->prop_hash_mask = hash_size - 1; sh->prop_size = prop_size; sh->prop_count = 0; sh->deleted_prop_count = 0; sh->is_hashed = FALSE; return sh; } /* create a new empty shape with prototype 'proto' */ static no_inline JSShape *js_new_shape2(JSContext *ctx, JSObject *proto, int hash_size, int prop_size) { JSRuntime *rt = ctx->rt; JSShape *sh; /* resize the shape hash table if necessary */ if (2 * (rt->shape_hash_count + 1) > rt->shape_hash_size) { resize_shape_hash(rt, rt->shape_hash_bits + 1); } sh = js_new_shape_nohash(ctx, proto, hash_size, prop_size); if (!sh) return NULL; /* insert in the hash table */ sh->hash = shape_initial_hash(proto); sh->is_hashed = TRUE; js_shape_hash_link(ctx->rt, sh); return sh; } static JSShape *js_new_shape(JSContext *ctx, JSObject *proto) { return js_new_shape2(ctx, proto, JS_PROP_INITIAL_HASH_SIZE, JS_PROP_INITIAL_SIZE); } /* The shape is cloned. The new shape is not inserted in the shape hash table */ static JSShape *js_clone_shape(JSContext *ctx, JSShape *sh1) { JSShape *sh; void *sh_alloc, *sh_alloc1; size_t size; JSShapeProperty *pr; uint32_t i, hash_size; hash_size = sh1->prop_hash_mask + 1; size = get_shape_size(hash_size, sh1->prop_size); sh_alloc = js_malloc(ctx, size); if (!sh_alloc) return NULL; sh_alloc1 = get_alloc_from_shape(sh1); memcpy(sh_alloc, sh_alloc1, size); sh = get_shape_from_alloc(sh_alloc, hash_size); sh->header.ref_count = 1; add_gc_object(ctx->rt, &sh->header, JS_GC_OBJ_TYPE_SHAPE); sh->is_hashed = FALSE; if (sh->proto) { JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, sh->proto)); } for(i = 0, pr = get_shape_prop(sh); i < sh->prop_count; i++, pr++) { JS_DupAtom(ctx, pr->atom); } return sh; } static JSShape *js_dup_shape(JSShape *sh) { sh->header.ref_count++; return sh; } static void js_free_shape0(JSRuntime *rt, JSShape *sh) { uint32_t i; JSShapeProperty *pr; assert(sh->header.ref_count == 0); if (sh->is_hashed) js_shape_hash_unlink(rt, sh); if (sh->proto != NULL) { JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, sh->proto)); } pr = get_shape_prop(sh); for(i = 0; i < sh->prop_count; i++) { JS_FreeAtomRT(rt, pr->atom); pr++; } remove_gc_object(&sh->header); js_free_rt(rt, get_alloc_from_shape(sh)); } static void js_free_shape(JSRuntime *rt, JSShape *sh) { if (unlikely(--sh->header.ref_count <= 0)) { js_free_shape0(rt, sh); } } static void js_free_shape_null(JSRuntime *rt, JSShape *sh) { if (sh) js_free_shape(rt, sh); } /* make space to hold at least 'count' properties */ static no_inline int resize_properties(JSContext *ctx, JSShape **psh, JSObject *p, uint32_t count) { JSShape *sh; uint32_t new_size, new_hash_size, new_hash_mask, i; JSShapeProperty *pr; void *sh_alloc; intptr_t h; JSShape *old_sh; sh = *psh; new_size = max_int(count, sh->prop_size * 3 / 2); /* Reallocate prop array first to avoid crash or size inconsistency in case of memory allocation failure */ if (p) { JSProperty *new_prop; new_prop = js_realloc(ctx, p->prop, sizeof(new_prop[0]) * new_size); if (unlikely(!new_prop)) return -1; p->prop = new_prop; } new_hash_size = sh->prop_hash_mask + 1; while (new_hash_size < new_size) new_hash_size = 2 * new_hash_size; /* resize the property shapes. Using js_realloc() is not possible in case the GC runs during the allocation */ old_sh = sh; sh_alloc = js_malloc(ctx, get_shape_size(new_hash_size, new_size)); if (!sh_alloc) return -1; sh = get_shape_from_alloc(sh_alloc, new_hash_size); list_del(&old_sh->header.link); /* copy all the shape properties */ memcpy(sh, old_sh, sizeof(JSShape) + sizeof(sh->prop[0]) * old_sh->prop_count); list_add_tail(&sh->header.link, &ctx->rt->gc_obj_list); if (new_hash_size != (sh->prop_hash_mask + 1)) { /* resize the hash table and the properties */ new_hash_mask = new_hash_size - 1; sh->prop_hash_mask = new_hash_mask; memset(prop_hash_end(sh) - new_hash_size, 0, sizeof(prop_hash_end(sh)[0]) * new_hash_size); for(i = 0, pr = sh->prop; i < sh->prop_count; i++, pr++) { if (pr->atom != JS_ATOM_NULL) { h = ((uintptr_t)pr->atom & new_hash_mask); pr->hash_next = prop_hash_end(sh)[-h - 1]; prop_hash_end(sh)[-h - 1] = i + 1; } } } else { /* just copy the previous hash table */ memcpy(prop_hash_end(sh) - new_hash_size, prop_hash_end(old_sh) - new_hash_size, sizeof(prop_hash_end(sh)[0]) * new_hash_size); } js_free(ctx, get_alloc_from_shape(old_sh)); *psh = sh; sh->prop_size = new_size; return 0; } /* remove the deleted properties. */ static int compact_properties(JSContext *ctx, JSObject *p) { JSShape *sh, *old_sh; void *sh_alloc; intptr_t h; uint32_t new_hash_size, i, j, new_hash_mask, new_size; JSShapeProperty *old_pr, *pr; JSProperty *prop, *new_prop; sh = p->shape; assert(!sh->is_hashed); new_size = max_int(JS_PROP_INITIAL_SIZE, sh->prop_count - sh->deleted_prop_count); assert(new_size <= sh->prop_size); new_hash_size = sh->prop_hash_mask + 1; while ((new_hash_size / 2) >= new_size) new_hash_size = new_hash_size / 2; new_hash_mask = new_hash_size - 1; /* resize the hash table and the properties */ old_sh = sh; sh_alloc = js_malloc(ctx, get_shape_size(new_hash_size, new_size)); if (!sh_alloc) return -1; sh = get_shape_from_alloc(sh_alloc, new_hash_size); list_del(&old_sh->header.link); memcpy(sh, old_sh, sizeof(JSShape)); list_add_tail(&sh->header.link, &ctx->rt->gc_obj_list); memset(prop_hash_end(sh) - new_hash_size, 0, sizeof(prop_hash_end(sh)[0]) * new_hash_size); j = 0; old_pr = old_sh->prop; pr = sh->prop; prop = p->prop; for(i = 0; i < sh->prop_count; i++) { if (old_pr->atom != JS_ATOM_NULL) { pr->atom = old_pr->atom; pr->flags = old_pr->flags; h = ((uintptr_t)old_pr->atom & new_hash_mask); pr->hash_next = prop_hash_end(sh)[-h - 1]; prop_hash_end(sh)[-h - 1] = j + 1; prop[j] = prop[i]; j++; pr++; } old_pr++; } assert(j == (sh->prop_count - sh->deleted_prop_count)); sh->prop_hash_mask = new_hash_mask; sh->prop_size = new_size; sh->deleted_prop_count = 0; sh->prop_count = j; p->shape = sh; js_free(ctx, get_alloc_from_shape(old_sh)); /* reduce the size of the object properties */ new_prop = js_realloc(ctx, p->prop, sizeof(new_prop[0]) * new_size); if (new_prop) p->prop = new_prop; return 0; } static int add_shape_property(JSContext *ctx, JSShape **psh, JSObject *p, JSAtom atom, int prop_flags) { JSRuntime *rt = ctx->rt; JSShape *sh = *psh; JSShapeProperty *pr, *prop; uint32_t hash_mask, new_shape_hash = 0; intptr_t h; /* update the shape hash */ if (sh->is_hashed) { js_shape_hash_unlink(rt, sh); new_shape_hash = shape_hash(shape_hash(sh->hash, atom), prop_flags); } if (unlikely(sh->prop_count >= sh->prop_size)) { if (resize_properties(ctx, psh, p, sh->prop_count + 1)) { /* in case of error, reinsert in the hash table. sh is still valid if resize_properties() failed */ if (sh->is_hashed) js_shape_hash_link(rt, sh); return -1; } sh = *psh; } if (sh->is_hashed) { sh->hash = new_shape_hash; js_shape_hash_link(rt, sh); } /* Initialize the new shape property. The object property at p->prop[sh->prop_count] is uninitialized */ prop = get_shape_prop(sh); pr = &prop[sh->prop_count++]; pr->atom = JS_DupAtom(ctx, atom); pr->flags = prop_flags; /* add in hash table */ hash_mask = sh->prop_hash_mask; h = atom & hash_mask; pr->hash_next = prop_hash_end(sh)[-h - 1]; prop_hash_end(sh)[-h - 1] = sh->prop_count; return 0; } /* find a hashed empty shape matching the prototype. Return NULL if not found */ static JSShape *find_hashed_shape_proto(JSRuntime *rt, JSObject *proto) { JSShape *sh1; uint32_t h, h1; h = shape_initial_hash(proto); h1 = get_shape_hash(h, rt->shape_hash_bits); for(sh1 = rt->shape_hash[h1]; sh1 != NULL; sh1 = sh1->shape_hash_next) { if (sh1->hash == h && sh1->proto == proto && sh1->prop_count == 0) { return sh1; } } return NULL; } /* find a hashed shape matching sh + (prop, prop_flags). Return NULL if not found */ static JSShape *find_hashed_shape_prop(JSRuntime *rt, JSShape *sh, JSAtom atom, int prop_flags) { JSShape *sh1; uint32_t h, h1, i, n; h = sh->hash; h = shape_hash(h, atom); h = shape_hash(h, prop_flags); h1 = get_shape_hash(h, rt->shape_hash_bits); for(sh1 = rt->shape_hash[h1]; sh1 != NULL; sh1 = sh1->shape_hash_next) { /* we test the hash first so that the rest is done only if the shapes really match */ if (sh1->hash == h && sh1->proto == sh->proto && sh1->prop_count == ((n = sh->prop_count) + 1)) { for(i = 0; i < n; i++) { if (unlikely(sh1->prop[i].atom != sh->prop[i].atom) || unlikely(sh1->prop[i].flags != sh->prop[i].flags)) goto next; } if (unlikely(sh1->prop[n].atom != atom) || unlikely(sh1->prop[n].flags != prop_flags)) goto next; return sh1; } next: ; } return NULL; } static __maybe_unused void JS_DumpShape(JSRuntime *rt, int i, JSShape *sh) { char atom_buf[ATOM_GET_STR_BUF_SIZE]; int j; /* XXX: should output readable class prototype */ printf("%5d %3d%c %14p %5d %5d", i, sh->header.ref_count, " *"[sh->is_hashed], (void *)sh->proto, sh->prop_size, sh->prop_count); for(j = 0; j < sh->prop_count; j++) { printf(" %s", JS_AtomGetStrRT(rt, atom_buf, sizeof(atom_buf), sh->prop[j].atom)); } printf("\n"); } static __maybe_unused void JS_DumpShapes(JSRuntime *rt) { int i; JSShape *sh; struct list_head *el; JSObject *p; JSGCObjectHeader *gp; printf("JSShapes: {\n"); printf("%5s %4s %14s %5s %5s %s\n", "SLOT", "REFS", "PROTO", "SIZE", "COUNT", "PROPS"); for(i = 0; i < rt->shape_hash_size; i++) { for(sh = rt->shape_hash[i]; sh != NULL; sh = sh->shape_hash_next) { JS_DumpShape(rt, i, sh); assert(sh->is_hashed); } } /* dump non-hashed shapes */ list_for_each(el, &rt->gc_obj_list) { gp = list_entry(el, JSGCObjectHeader, link); if (gp->gc_obj_type == JS_GC_OBJ_TYPE_JS_OBJECT) { p = (JSObject *)gp; if (!p->shape->is_hashed) { JS_DumpShape(rt, -1, p->shape); } } } printf("}\n"); } /* 'props[]' is used to initialized the object properties. The number of elements depends on the shape. */ static JSValue JS_NewObjectFromShape(JSContext *ctx, JSShape *sh, JSClassID class_id, JSProperty *props) { JSObject *p; int i; js_trigger_gc(ctx->rt, sizeof(JSObject)); p = js_malloc(ctx, sizeof(JSObject)); if (unlikely(!p)) goto fail; p->class_id = class_id; p->is_std_array_prototype = 0; p->extensible = TRUE; p->free_mark = 0; p->is_exotic = 0; p->fast_array = 0; p->is_constructor = 0; p->has_immutable_prototype = 0; p->tmp_mark = 0; p->is_HTMLDDA = 0; p->weakref_count = 0; p->u.opaque = NULL; p->shape = sh; p->prop = js_malloc(ctx, sizeof(JSProperty) * sh->prop_size); if (unlikely(!p->prop)) { js_free(ctx, p); fail: if (props) { JSShapeProperty *prs = get_shape_prop(sh); for(i = 0; i < sh->prop_count; i++) { free_property(ctx->rt, &props[i], prs->flags); prs++; } } js_free_shape(ctx->rt, sh); return JS_EXCEPTION; } switch(class_id) { case JS_CLASS_OBJECT: break; case JS_CLASS_ARRAY: { JSProperty *pr; p->is_exotic = 1; p->fast_array = 1; p->u.array.u.values = NULL; p->u.array.count = 0; p->u.array.u1.size = 0; if (!props) { /* XXX: remove */ /* the length property is always the first one */ if (likely(sh == ctx->array_shape)) { pr = &p->prop[0]; } else { /* only used for the first array */ /* cannot fail */ pr = add_property(ctx, p, JS_ATOM_length, JS_PROP_WRITABLE | JS_PROP_LENGTH); } pr->u.value = JS_NewInt32(ctx, 0); } } break; case JS_CLASS_C_FUNCTION: p->prop[0].u.value = JS_UNDEFINED; break; case JS_CLASS_ARGUMENTS: case JS_CLASS_MAPPED_ARGUMENTS: case JS_CLASS_UINT8C_ARRAY: case JS_CLASS_INT8_ARRAY: case JS_CLASS_UINT8_ARRAY: case JS_CLASS_INT16_ARRAY: case JS_CLASS_UINT16_ARRAY: case JS_CLASS_INT32_ARRAY: case JS_CLASS_UINT32_ARRAY: case JS_CLASS_BIG_INT64_ARRAY: case JS_CLASS_BIG_UINT64_ARRAY: case JS_CLASS_FLOAT16_ARRAY: case JS_CLASS_FLOAT32_ARRAY: case JS_CLASS_FLOAT64_ARRAY: p->is_exotic = 1; p->fast_array = 1; p->u.array.u.ptr = NULL; p->u.array.count = 0; break; case JS_CLASS_DATAVIEW: p->u.array.u.ptr = NULL; p->u.array.count = 0; break; case JS_CLASS_NUMBER: case JS_CLASS_STRING: case JS_CLASS_BOOLEAN: case JS_CLASS_SYMBOL: case JS_CLASS_DATE: case JS_CLASS_BIG_INT: p->u.object_data = JS_UNDEFINED; goto set_exotic; case JS_CLASS_REGEXP: p->u.regexp.pattern = NULL; p->u.regexp.bytecode = NULL; break; case JS_CLASS_GLOBAL_OBJECT: p->u.global_object.uninitialized_vars = JS_UNDEFINED; break; default: set_exotic: if (ctx->rt->class_array[class_id].exotic) { p->is_exotic = 1; } break; } p->header.ref_count = 1; add_gc_object(ctx->rt, &p->header, JS_GC_OBJ_TYPE_JS_OBJECT); if (props) { for(i = 0; i < sh->prop_count; i++) p->prop[i] = props[i]; } return JS_MKPTR(JS_TAG_OBJECT, p); } static JSObject *get_proto_obj(JSValueConst proto_val) { if (JS_VALUE_GET_TAG(proto_val) != JS_TAG_OBJECT) return NULL; else return JS_VALUE_GET_OBJ(proto_val); } /* WARNING: proto must be an object or JS_NULL */ JSValue JS_NewObjectProtoClass(JSContext *ctx, JSValueConst proto_val, JSClassID class_id) { JSShape *sh; JSObject *proto; proto = get_proto_obj(proto_val); sh = find_hashed_shape_proto(ctx->rt, proto); if (likely(sh)) { sh = js_dup_shape(sh); } else { sh = js_new_shape(ctx, proto); if (!sh) return JS_EXCEPTION; } return JS_NewObjectFromShape(ctx, sh, class_id, NULL); } /* WARNING: the shape is not hashed. It is used for objects where factorizing the shape is not relevant (prototypes, constructors) */ static JSValue JS_NewObjectProtoClassAlloc(JSContext *ctx, JSValueConst proto_val, JSClassID class_id, int n_alloc_props) { JSShape *sh; JSObject *proto; int hash_size, hash_bits; if (n_alloc_props <= JS_PROP_INITIAL_SIZE) { n_alloc_props = JS_PROP_INITIAL_SIZE; hash_size = JS_PROP_INITIAL_HASH_SIZE; } else { hash_bits = 32 - clz32(n_alloc_props - 1); /* ceil(log2(radix)) */ hash_size = 1 << hash_bits; } proto = get_proto_obj(proto_val); sh = js_new_shape_nohash(ctx, proto, hash_size, n_alloc_props); if (!sh) return JS_EXCEPTION; return JS_NewObjectFromShape(ctx, sh, class_id, NULL); } #if 0 static JSValue JS_GetObjectData(JSContext *ctx, JSValueConst obj) { JSObject *p; if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { p = JS_VALUE_GET_OBJ(obj); switch(p->class_id) { case JS_CLASS_NUMBER: case JS_CLASS_STRING: case JS_CLASS_BOOLEAN: case JS_CLASS_SYMBOL: case JS_CLASS_DATE: case JS_CLASS_BIG_INT: return JS_DupValue(ctx, p->u.object_data); } } return JS_UNDEFINED; } #endif static int JS_SetObjectData(JSContext *ctx, JSValueConst obj, JSValue val) { JSObject *p; if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { p = JS_VALUE_GET_OBJ(obj); switch(p->class_id) { case JS_CLASS_NUMBER: case JS_CLASS_STRING: case JS_CLASS_BOOLEAN: case JS_CLASS_SYMBOL: case JS_CLASS_DATE: case JS_CLASS_BIG_INT: JS_FreeValue(ctx, p->u.object_data); p->u.object_data = val; /* for JS_CLASS_STRING, 'val' must be JS_TAG_STRING (and not a rope) */ return 0; } } JS_FreeValue(ctx, val); if (!JS_IsException(obj)) JS_ThrowTypeError(ctx, "invalid object type"); return -1; } JSValue JS_NewObjectClass(JSContext *ctx, int class_id) { return JS_NewObjectProtoClass(ctx, ctx->class_proto[class_id], class_id); } JSValue JS_NewObjectProto(JSContext *ctx, JSValueConst proto) { return JS_NewObjectProtoClass(ctx, proto, JS_CLASS_OBJECT); } JSValue JS_NewArray(JSContext *ctx) { return JS_NewObjectFromShape(ctx, js_dup_shape(ctx->array_shape), JS_CLASS_ARRAY, NULL); } JSValue JS_NewObject(JSContext *ctx) { /* inline JS_NewObjectClass(ctx, JS_CLASS_OBJECT); */ return JS_NewObjectProtoClass(ctx, ctx->class_proto[JS_CLASS_OBJECT], JS_CLASS_OBJECT); } static void js_function_set_properties(JSContext *ctx, JSValueConst func_obj, JSAtom name, int len) { /* ES6 feature non compatible with ES5.1: length is configurable */ JS_DefinePropertyValue(ctx, func_obj, JS_ATOM_length, JS_NewInt32(ctx, len), JS_PROP_CONFIGURABLE); JS_DefinePropertyValue(ctx, func_obj, JS_ATOM_name, JS_AtomToString(ctx, name), JS_PROP_CONFIGURABLE); } static BOOL js_class_has_bytecode(JSClassID class_id) { return (class_id == JS_CLASS_BYTECODE_FUNCTION || class_id == JS_CLASS_GENERATOR_FUNCTION || class_id == JS_CLASS_ASYNC_FUNCTION || class_id == JS_CLASS_ASYNC_GENERATOR_FUNCTION); } /* return NULL without exception if not a function or no bytecode */ static JSFunctionBytecode *JS_GetFunctionBytecode(JSValueConst val) { JSObject *p; if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) return NULL; p = JS_VALUE_GET_OBJ(val); if (!js_class_has_bytecode(p->class_id)) return NULL; return p->u.func.function_bytecode; } static void js_method_set_home_object(JSContext *ctx, JSValueConst func_obj, JSValueConst home_obj) { JSObject *p, *p1; JSFunctionBytecode *b; if (JS_VALUE_GET_TAG(func_obj) != JS_TAG_OBJECT) return; p = JS_VALUE_GET_OBJ(func_obj); if (!js_class_has_bytecode(p->class_id)) return; b = p->u.func.function_bytecode; if (b->need_home_object) { p1 = p->u.func.home_object; if (p1) { JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p1)); } if (JS_VALUE_GET_TAG(home_obj) == JS_TAG_OBJECT) p1 = JS_VALUE_GET_OBJ(JS_DupValue(ctx, home_obj)); else p1 = NULL; p->u.func.home_object = p1; } } static JSValue js_get_function_name(JSContext *ctx, JSAtom name) { JSValue name_str; name_str = JS_AtomToString(ctx, name); if (JS_AtomSymbolHasDescription(ctx, name)) { name_str = JS_ConcatString3(ctx, "[", name_str, "]"); } return name_str; } /* Modify the name of a method according to the atom and 'flags'. 'flags' is a bitmask of JS_PROP_HAS_GET and JS_PROP_HAS_SET. Also set the home object of the method. Return < 0 if exception. */ static int js_method_set_properties(JSContext *ctx, JSValueConst func_obj, JSAtom name, int flags, JSValueConst home_obj) { JSValue name_str; name_str = js_get_function_name(ctx, name); if (flags & JS_PROP_HAS_GET) { name_str = JS_ConcatString3(ctx, "get ", name_str, ""); } else if (flags & JS_PROP_HAS_SET) { name_str = JS_ConcatString3(ctx, "set ", name_str, ""); } if (JS_IsException(name_str)) return -1; if (JS_DefinePropertyValue(ctx, func_obj, JS_ATOM_name, name_str, JS_PROP_CONFIGURABLE) < 0) return -1; js_method_set_home_object(ctx, func_obj, home_obj); return 0; } /* Note: at least 'length' arguments will be readable in 'argv' */ JSValue JS_NewCFunction3(JSContext *ctx, JSCFunction *func, const char *name, int length, JSCFunctionEnum cproto, int magic, JSValueConst proto_val, int n_fields) { JSValue func_obj; JSObject *p; JSAtom name_atom; if (n_fields > 0) { func_obj = JS_NewObjectProtoClassAlloc(ctx, proto_val, JS_CLASS_C_FUNCTION, n_fields); } else { func_obj = JS_NewObjectProtoClass(ctx, proto_val, JS_CLASS_C_FUNCTION); } if (JS_IsException(func_obj)) return func_obj; p = JS_VALUE_GET_OBJ(func_obj); p->u.cfunc.realm = JS_DupContext(ctx); p->u.cfunc.c_function.generic = func; p->u.cfunc.length = length; p->u.cfunc.cproto = cproto; p->u.cfunc.magic = magic; p->is_constructor = (cproto == JS_CFUNC_constructor || cproto == JS_CFUNC_constructor_magic || cproto == JS_CFUNC_constructor_or_func || cproto == JS_CFUNC_constructor_or_func_magic); if (!name) name = ""; name_atom = JS_NewAtom(ctx, name); if (name_atom == JS_ATOM_NULL) { JS_FreeValue(ctx, func_obj); return JS_EXCEPTION; } js_function_set_properties(ctx, func_obj, name_atom, length); JS_FreeAtom(ctx, name_atom); return func_obj; } /* Note: at least 'length' arguments will be readable in 'argv' */ JSValue JS_NewCFunction2(JSContext *ctx, JSCFunction *func, const char *name, int length, JSCFunctionEnum cproto, int magic) { return JS_NewCFunction3(ctx, func, name, length, cproto, magic, ctx->function_proto, 0); } typedef struct JSCFunctionDataRecord { JSCFunctionData *func; uint8_t length; uint8_t data_len; uint16_t magic; JSValue data[0]; } JSCFunctionDataRecord; static void js_c_function_data_finalizer(JSRuntime *rt, JSValue val) { JSCFunctionDataRecord *s = JS_GetOpaque(val, JS_CLASS_C_FUNCTION_DATA); int i; if (s) { for(i = 0; i < s->data_len; i++) { JS_FreeValueRT(rt, s->data[i]); } js_free_rt(rt, s); } } static void js_c_function_data_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSCFunctionDataRecord *s = JS_GetOpaque(val, JS_CLASS_C_FUNCTION_DATA); int i; if (s) { for(i = 0; i < s->data_len; i++) { JS_MarkValue(rt, s->data[i], mark_func); } } } static JSValue js_c_function_data_call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_val, int argc, JSValueConst *argv, int flags) { JSCFunctionDataRecord *s = JS_GetOpaque(func_obj, JS_CLASS_C_FUNCTION_DATA); JSValueConst *arg_buf; int i; /* XXX: could add the function on the stack for debug */ if (unlikely(argc < s->length)) { arg_buf = alloca(sizeof(arg_buf[0]) * s->length); for(i = 0; i < argc; i++) arg_buf[i] = argv[i]; for(i = argc; i < s->length; i++) arg_buf[i] = JS_UNDEFINED; } else { arg_buf = argv; } return s->func(ctx, this_val, argc, arg_buf, s->magic, s->data); } JSValue JS_NewCFunctionData(JSContext *ctx, JSCFunctionData *func, int length, int magic, int data_len, JSValueConst *data) { JSCFunctionDataRecord *s; JSValue func_obj; int i; func_obj = JS_NewObjectProtoClass(ctx, ctx->function_proto, JS_CLASS_C_FUNCTION_DATA); if (JS_IsException(func_obj)) return func_obj; s = js_malloc(ctx, sizeof(*s) + data_len * sizeof(JSValue)); if (!s) { JS_FreeValue(ctx, func_obj); return JS_EXCEPTION; } s->func = func; s->length = length; s->data_len = data_len; s->magic = magic; for(i = 0; i < data_len; i++) s->data[i] = JS_DupValue(ctx, data[i]); JS_SetOpaque(func_obj, s); js_function_set_properties(ctx, func_obj, JS_ATOM_empty_string, length); return func_obj; } static JSContext *js_autoinit_get_realm(JSProperty *pr) { return (JSContext *)(pr->u.init.realm_and_id & ~3); } static JSAutoInitIDEnum js_autoinit_get_id(JSProperty *pr) { return pr->u.init.realm_and_id & 3; } static void js_autoinit_free(JSRuntime *rt, JSProperty *pr) { JS_FreeContext(js_autoinit_get_realm(pr)); } static void js_autoinit_mark(JSRuntime *rt, JSProperty *pr, JS_MarkFunc *mark_func) { mark_func(rt, &js_autoinit_get_realm(pr)->header); } static void free_property(JSRuntime *rt, JSProperty *pr, int prop_flags) { if (unlikely(prop_flags & JS_PROP_TMASK)) { if ((prop_flags & JS_PROP_TMASK) == JS_PROP_GETSET) { if (pr->u.getset.getter) JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.getter)); if (pr->u.getset.setter) JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.setter)); } else if ((prop_flags & JS_PROP_TMASK) == JS_PROP_VARREF) { free_var_ref(rt, pr->u.var_ref); } else if ((prop_flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { js_autoinit_free(rt, pr); } } else { JS_FreeValueRT(rt, pr->u.value); } } static force_inline JSShapeProperty *find_own_property1(JSObject *p, JSAtom atom) { JSShape *sh; JSShapeProperty *pr, *prop; intptr_t h; sh = p->shape; h = (uintptr_t)atom & sh->prop_hash_mask; h = prop_hash_end(sh)[-h - 1]; prop = get_shape_prop(sh); while (h) { pr = &prop[h - 1]; if (likely(pr->atom == atom)) { return pr; } h = pr->hash_next; } return NULL; } static force_inline JSShapeProperty *find_own_property(JSProperty **ppr, JSObject *p, JSAtom atom) { JSShape *sh; JSShapeProperty *pr, *prop; intptr_t h; sh = p->shape; h = (uintptr_t)atom & sh->prop_hash_mask; h = prop_hash_end(sh)[-h - 1]; prop = get_shape_prop(sh); while (h) { pr = &prop[h - 1]; if (likely(pr->atom == atom)) { *ppr = &p->prop[h - 1]; /* the compiler should be able to assume that pr != NULL here */ return pr; } h = pr->hash_next; } *ppr = NULL; return NULL; } /* indicate that the object may be part of a function prototype cycle */ static void set_cycle_flag(JSContext *ctx, JSValueConst obj) { } static void free_var_ref(JSRuntime *rt, JSVarRef *var_ref) { if (var_ref) { assert(var_ref->header.ref_count > 0); if (--var_ref->header.ref_count == 0) { if (var_ref->is_detached) { JS_FreeValueRT(rt, var_ref->value); } else { JSStackFrame *sf = var_ref->stack_frame; assert(sf->var_refs[var_ref->var_ref_idx] == var_ref); sf->var_refs[var_ref->var_ref_idx] = NULL; if (sf->js_mode & JS_MODE_ASYNC) { JSAsyncFunctionState *async_func = container_of(sf, JSAsyncFunctionState, frame); async_func_free(rt, async_func); } } remove_gc_object(&var_ref->header); js_free_rt(rt, var_ref); } } } static void js_array_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); int i; for(i = 0; i < p->u.array.count; i++) { JS_FreeValueRT(rt, p->u.array.u.values[i]); } js_free_rt(rt, p->u.array.u.values); } static void js_array_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); int i; for(i = 0; i < p->u.array.count; i++) { JS_MarkValue(rt, p->u.array.u.values[i], mark_func); } } static void js_object_data_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); JS_FreeValueRT(rt, p->u.object_data); p->u.object_data = JS_UNDEFINED; } static void js_object_data_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); JS_MarkValue(rt, p->u.object_data, mark_func); } static void js_c_function_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); if (p->u.cfunc.realm) JS_FreeContext(p->u.cfunc.realm); } static void js_c_function_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); if (p->u.cfunc.realm) mark_func(rt, &p->u.cfunc.realm->header); } static void js_bytecode_function_finalizer(JSRuntime *rt, JSValue val) { JSObject *p1, *p = JS_VALUE_GET_OBJ(val); JSFunctionBytecode *b; JSVarRef **var_refs; int i; p1 = p->u.func.home_object; if (p1) { JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, p1)); } b = p->u.func.function_bytecode; if (b) { var_refs = p->u.func.var_refs; if (var_refs) { for(i = 0; i < b->closure_var_count; i++) free_var_ref(rt, var_refs[i]); js_free_rt(rt, var_refs); } JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_FUNCTION_BYTECODE, b)); } } static void js_bytecode_function_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); JSVarRef **var_refs = p->u.func.var_refs; JSFunctionBytecode *b = p->u.func.function_bytecode; int i; if (p->u.func.home_object) { JS_MarkValue(rt, JS_MKPTR(JS_TAG_OBJECT, p->u.func.home_object), mark_func); } if (b) { if (var_refs) { for(i = 0; i < b->closure_var_count; i++) { JSVarRef *var_ref = var_refs[i]; if (var_ref) { mark_func(rt, &var_ref->header); } } } /* must mark the function bytecode because template objects may be part of a cycle */ JS_MarkValue(rt, JS_MKPTR(JS_TAG_FUNCTION_BYTECODE, b), mark_func); } } static void js_bound_function_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); JSBoundFunction *bf = p->u.bound_function; int i; JS_FreeValueRT(rt, bf->func_obj); JS_FreeValueRT(rt, bf->this_val); for(i = 0; i < bf->argc; i++) { JS_FreeValueRT(rt, bf->argv[i]); } js_free_rt(rt, bf); } static void js_bound_function_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); JSBoundFunction *bf = p->u.bound_function; int i; JS_MarkValue(rt, bf->func_obj, mark_func); JS_MarkValue(rt, bf->this_val, mark_func); for(i = 0; i < bf->argc; i++) JS_MarkValue(rt, bf->argv[i], mark_func); } static void js_for_in_iterator_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); JSForInIterator *it = p->u.for_in_iterator; int i; JS_FreeValueRT(rt, it->obj); if (!it->is_array) { for(i = 0; i < it->atom_count; i++) { JS_FreeAtomRT(rt, it->tab_atom[i].atom); } js_free_rt(rt, it->tab_atom); } js_free_rt(rt, it); } static void js_for_in_iterator_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); JSForInIterator *it = p->u.for_in_iterator; JS_MarkValue(rt, it->obj, mark_func); } static void free_object(JSRuntime *rt, JSObject *p) { int i; JSClassFinalizer *finalizer; JSShape *sh; JSShapeProperty *pr; p->free_mark = 1; /* used to tell the object is invalid when freeing cycles */ /* free all the fields */ sh = p->shape; pr = get_shape_prop(sh); for(i = 0; i < sh->prop_count; i++) { free_property(rt, &p->prop[i], pr->flags); pr++; } js_free_rt(rt, p->prop); /* as an optimization we destroy the shape immediately without putting it in gc_zero_ref_count_list */ js_free_shape(rt, sh); /* fail safe */ p->shape = NULL; p->prop = NULL; finalizer = rt->class_array[p->class_id].finalizer; if (finalizer) (*finalizer)(rt, JS_MKPTR(JS_TAG_OBJECT, p)); /* fail safe */ p->class_id = 0; p->u.opaque = NULL; p->u.func.var_refs = NULL; p->u.func.home_object = NULL; remove_gc_object(&p->header); if (rt->gc_phase == JS_GC_PHASE_REMOVE_CYCLES) { if (p->header.ref_count == 0 && p->weakref_count == 0) { js_free_rt(rt, p); } else { /* keep the object structure because there are may be references to it */ list_add_tail(&p->header.link, &rt->gc_zero_ref_count_list); } } else { /* keep the object structure in case there are weak references to it */ if (p->weakref_count == 0) { js_free_rt(rt, p); } else { p->header.mark = 0; /* reset the mark so that the weakref can be freed */ } } } static void free_gc_object(JSRuntime *rt, JSGCObjectHeader *gp) { switch(gp->gc_obj_type) { case JS_GC_OBJ_TYPE_JS_OBJECT: free_object(rt, (JSObject *)gp); break; case JS_GC_OBJ_TYPE_FUNCTION_BYTECODE: free_function_bytecode(rt, (JSFunctionBytecode *)gp); break; case JS_GC_OBJ_TYPE_ASYNC_FUNCTION: __async_func_free(rt, (JSAsyncFunctionState *)gp); break; case JS_GC_OBJ_TYPE_MODULE: js_free_module_def(rt, (JSModuleDef *)gp); break; default: abort(); } } /* Check if object has a can_destroy hook. */ static int gc_has_can_destroy_hook(JSRuntime *rt, JSGCObjectHeader *p) { JSObject *obj; if (p->gc_obj_type != JS_GC_OBJ_TYPE_JS_OBJECT) return 0; obj = (JSObject *)p; return rt->class_array[obj->class_id].can_destroy != NULL; } /* User-defined override for object destruction. */ static int gc_can_destroy(JSRuntime *rt, JSGCObjectHeader *p) { JSClassCanDestroy *can_destroy; JSObject *obj; obj = (JSObject *)p; can_destroy = rt->class_array[obj->class_id].can_destroy; if (!((*can_destroy)(rt, JS_MKPTR(JS_TAG_OBJECT, obj)))) return 0; return 1; } static void free_zero_refcount(JSRuntime *rt) { struct list_head *el; JSGCObjectHeader *p; rt->gc_phase = JS_GC_PHASE_DECREF; for(;;) { el = rt->gc_zero_ref_count_list.next; if (el == &rt->gc_zero_ref_count_list) break; p = list_entry(el, JSGCObjectHeader, link); assert(p->ref_count == 0); free_gc_object(rt, p); } rt->gc_phase = JS_GC_PHASE_NONE; } /* called with the ref_count of 'v' reaches zero. */ void __JS_FreeValueRT(JSRuntime *rt, JSValue v) { uint32_t tag = JS_VALUE_GET_TAG(v); #ifdef DUMP_FREE { printf("Freeing "); if (tag == JS_TAG_OBJECT) { JS_DumpObject(rt, JS_VALUE_GET_OBJ(v)); } else { JS_DumpValueShort(rt, v); printf("\n"); } } #endif switch(tag) { case JS_TAG_STRING: { JSString *p = JS_VALUE_GET_STRING(v); if (p->atom_type) { JS_FreeAtomStruct(rt, p); } else { #ifdef DUMP_LEAKS list_del(&p->link); #endif js_free_rt(rt, p); } } break; case JS_TAG_STRING_ROPE: /* Note: recursion is acceptable because the rope depth is bounded */ { JSStringRope *p = JS_VALUE_GET_STRING_ROPE(v); JS_FreeValueRT(rt, p->left); JS_FreeValueRT(rt, p->right); js_free_rt(rt, p); } break; case JS_TAG_OBJECT: case JS_TAG_FUNCTION_BYTECODE: case JS_TAG_MODULE: { JSGCObjectHeader *p = JS_VALUE_GET_PTR(v); if (rt->gc_phase != JS_GC_PHASE_REMOVE_CYCLES) { if (gc_has_can_destroy_hook(rt, p) && !gc_can_destroy(rt, p)) { p->ref_count++; JS_SetOpaque(JS_MKPTR(JS_TAG_OBJECT, p), NULL); break; } list_del(&p->link); list_add(&p->link, &rt->gc_zero_ref_count_list); p->mark = 1; /* indicate that the object is about to be freed */ if (rt->gc_phase == JS_GC_PHASE_NONE) { free_zero_refcount(rt); } } } break; case JS_TAG_BIG_INT: { JSBigInt *p = JS_VALUE_GET_PTR(v); js_free_rt(rt, p); } break; case JS_TAG_SYMBOL: { JSAtomStruct *p = JS_VALUE_GET_PTR(v); JS_FreeAtomStruct(rt, p); } break; default: abort(); } } void __JS_FreeValue(JSContext *ctx, JSValue v) { __JS_FreeValueRT(ctx->rt, v); } /* garbage collection */ static void gc_remove_weak_objects(JSRuntime *rt) { struct list_head *el; /* add the freed objects to rt->gc_zero_ref_count_list so that rt->weakref_list is not modified while we traverse it */ rt->gc_phase = JS_GC_PHASE_DECREF; list_for_each(el, &rt->weakref_list) { JSWeakRefHeader *wh = list_entry(el, JSWeakRefHeader, link); switch(wh->weakref_type) { case JS_WEAKREF_TYPE_MAP: map_delete_weakrefs(rt, wh); break; case JS_WEAKREF_TYPE_WEAKREF: weakref_delete_weakref(rt, wh); break; case JS_WEAKREF_TYPE_FINREC: finrec_delete_weakref(rt, wh); break; default: abort(); } } rt->gc_phase = JS_GC_PHASE_NONE; /* free the freed objects here. */ free_zero_refcount(rt); } static void add_gc_object(JSRuntime *rt, JSGCObjectHeader *h, JSGCObjectTypeEnum type) { h->mark = 0; h->gc_obj_type = type; list_add_tail(&h->link, &rt->gc_obj_list); } static void remove_gc_object(JSGCObjectHeader *h) { list_del(&h->link); } void JS_MarkValue(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { if (JS_VALUE_HAS_REF_COUNT(val)) { switch(JS_VALUE_GET_TAG(val)) { case JS_TAG_OBJECT: case JS_TAG_FUNCTION_BYTECODE: case JS_TAG_MODULE: mark_func(rt, JS_VALUE_GET_PTR(val)); break; default: break; } } } static void mark_children(JSRuntime *rt, JSGCObjectHeader *gp, JS_MarkFunc *mark_func) { switch(gp->gc_obj_type) { case JS_GC_OBJ_TYPE_JS_OBJECT: { JSObject *p = (JSObject *)gp; JSShapeProperty *prs; JSShape *sh; int i; sh = p->shape; mark_func(rt, &sh->header); /* mark all the fields */ prs = get_shape_prop(sh); for(i = 0; i < sh->prop_count; i++) { JSProperty *pr = &p->prop[i]; if (prs->atom != JS_ATOM_NULL) { if (prs->flags & JS_PROP_TMASK) { if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) { if (pr->u.getset.getter) mark_func(rt, &pr->u.getset.getter->header); if (pr->u.getset.setter) mark_func(rt, &pr->u.getset.setter->header); } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { /* Note: the tag does not matter provided it is a GC object */ mark_func(rt, &pr->u.var_ref->header); } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { js_autoinit_mark(rt, pr, mark_func); } } else { JS_MarkValue(rt, pr->u.value, mark_func); } } prs++; } if (p->class_id != JS_CLASS_OBJECT) { JSClassGCMark *gc_mark; gc_mark = rt->class_array[p->class_id].gc_mark; if (gc_mark) gc_mark(rt, JS_MKPTR(JS_TAG_OBJECT, p), mark_func); } } break; case JS_GC_OBJ_TYPE_FUNCTION_BYTECODE: /* the template objects can be part of a cycle */ { JSFunctionBytecode *b = (JSFunctionBytecode *)gp; int i; for(i = 0; i < b->cpool_count; i++) { JS_MarkValue(rt, b->cpool[i], mark_func); } if (b->realm) mark_func(rt, &b->realm->header); } break; case JS_GC_OBJ_TYPE_VAR_REF: { JSVarRef *var_ref = (JSVarRef *)gp; if (var_ref->is_detached) { JS_MarkValue(rt, *var_ref->pvalue, mark_func); } else { JSStackFrame *sf = var_ref->stack_frame; if (sf->js_mode & JS_MODE_ASYNC) { JSAsyncFunctionState *async_func = container_of(sf, JSAsyncFunctionState, frame); mark_func(rt, &async_func->header); } } } break; case JS_GC_OBJ_TYPE_ASYNC_FUNCTION: { JSAsyncFunctionState *s = (JSAsyncFunctionState *)gp; JSStackFrame *sf = &s->frame; JSValue *sp; if (!s->is_completed) { JS_MarkValue(rt, sf->cur_func, mark_func); JS_MarkValue(rt, s->this_val, mark_func); /* sf->cur_sp = NULL if the function is running */ if (sf->cur_sp) { /* if the function is running, cur_sp is not known so we cannot mark the stack. Marking the variables is not needed because a running function cannot be part of a removable cycle */ for(sp = sf->arg_buf; sp < sf->cur_sp; sp++) JS_MarkValue(rt, *sp, mark_func); } } JS_MarkValue(rt, s->resolving_funcs[0], mark_func); JS_MarkValue(rt, s->resolving_funcs[1], mark_func); } break; case JS_GC_OBJ_TYPE_SHAPE: { JSShape *sh = (JSShape *)gp; if (sh->proto != NULL) { mark_func(rt, &sh->proto->header); } } break; case JS_GC_OBJ_TYPE_JS_CONTEXT: { JSContext *ctx = (JSContext *)gp; JS_MarkContext(rt, ctx, mark_func); } break; case JS_GC_OBJ_TYPE_MODULE: { JSModuleDef *m = (JSModuleDef *)gp; js_mark_module_def(rt, m, mark_func); } break; default: abort(); } } static void gc_decref_child(JSRuntime *rt, JSGCObjectHeader *p) { assert(p->ref_count > 0); p->ref_count--; if (p->ref_count == 0 && p->mark == 1) { list_del(&p->link); if (gc_has_can_destroy_hook(rt, p)) list_add_tail(&p->link, &rt->tmp_hook_obj_list); else list_add_tail(&p->link, &rt->tmp_obj_list); } } static void gc_decref(JSRuntime *rt) { struct list_head *el, *el1; JSGCObjectHeader *p; init_list_head(&rt->tmp_obj_list); init_list_head(&rt->tmp_hook_obj_list); /* decrement the refcount of all the children of all the GC objects and move the GC objects with zero refcount to tmp_obj_list */ list_for_each_safe(el, el1, &rt->gc_obj_list) { p = list_entry(el, JSGCObjectHeader, link); assert(p->mark == 0); mark_children(rt, p, gc_decref_child); p->mark = 1; if (p->ref_count == 0) { list_del(&p->link); if (gc_has_can_destroy_hook(rt, p)) list_add_tail(&p->link, &rt->tmp_hook_obj_list); else list_add_tail(&p->link, &rt->tmp_obj_list); } } } static void gc_scan_incref_child(JSRuntime *rt, JSGCObjectHeader *p) { p->ref_count++; if (p->ref_count == 1) { /* ref_count was 0: remove from tmp_obj_list and add at the end of gc_obj_list */ list_del(&p->link); list_add_tail(&p->link, &rt->gc_obj_list); p->mark = 0; /* reset the mark for the next GC call */ } } static void gc_scan_incref_child2(JSRuntime *rt, JSGCObjectHeader *p) { p->ref_count++; } static void gc_scan(JSRuntime *rt) { struct list_head *el, *el1, *gc_tail; JSGCObjectHeader *p, *p2; /* keep the objects with a refcount > 0 and their children. */ list_for_each(el, &rt->gc_obj_list) { p = list_entry(el, JSGCObjectHeader, link); assert(p->ref_count > 0); p->mark = 0; /* reset the mark for the next GC call */ mark_children(rt, p, gc_scan_incref_child); } /* restore objects whose can_destroy hook returns 0 and their children. */ for (;;) { /* save previous tail position of gc_obj_list */ gc_tail = rt->gc_obj_list.prev; p2 = NULL; list_for_each_safe(el, el1, &rt->tmp_hook_obj_list) { p = list_entry(el, JSGCObjectHeader, link); list_del(&p->link); /* gc_has_can_destroy_hook is the condition for objects to be placed in tmp_hook_obj_list, so it is true here. */ if (gc_can_destroy(rt, p)) { /* object can be destroyed; move to tmp_obj_list. */ list_add_tail(&p->link, &rt->tmp_obj_list); } else { /* hook says we cannot destroy yet; move back to gc_obj_list. */ p->ref_count++; list_add_tail(&p->link, &rt->gc_obj_list); p2 = p; break; } } /* if redo, restore object and all its descendants. Note: we must do this outside the previous loop, because el/el1 might get moved into gc_obj_list here. */ for (el = gc_tail->next; el != &rt->gc_obj_list; el = el->next) { p = list_entry(el, JSGCObjectHeader, link); assert(p->ref_count > 0); p->mark = 0; /* reset the mark for the next GC call */ mark_children(rt, p, gc_scan_incref_child); } if (!p2) break; /* unset the opaque to signal to the other side that we are no longer referencing them. */ JS_SetOpaque(JS_MKPTR(JS_TAG_OBJECT, p2), NULL); } /* restore the refcount of the objects to be deleted. */ list_for_each(el, &rt->tmp_obj_list) { p = list_entry(el, JSGCObjectHeader, link); mark_children(rt, p, gc_scan_incref_child2); } } static void gc_free_cycles(JSRuntime *rt) { struct list_head *el, *el1; JSGCObjectHeader *p; #ifdef DUMP_GC_FREE BOOL header_done = FALSE; #endif rt->gc_phase = JS_GC_PHASE_REMOVE_CYCLES; for(;;) { el = rt->tmp_obj_list.next; if (el == &rt->tmp_obj_list) break; p = list_entry(el, JSGCObjectHeader, link); /* Only need to free the GC object associated with JS values or async functions. The rest will be automatically removed because they must be referenced by them. */ switch(p->gc_obj_type) { case JS_GC_OBJ_TYPE_JS_OBJECT: case JS_GC_OBJ_TYPE_FUNCTION_BYTECODE: case JS_GC_OBJ_TYPE_ASYNC_FUNCTION: case JS_GC_OBJ_TYPE_MODULE: #ifdef DUMP_GC_FREE if (!header_done) { printf("Freeing cycles:\n"); JS_DumpObjectHeader(rt); header_done = TRUE; } JS_DumpGCObject(rt, p); #endif free_gc_object(rt, p); break; default: list_del(&p->link); list_add_tail(&p->link, &rt->gc_zero_ref_count_list); break; } } rt->gc_phase = JS_GC_PHASE_NONE; list_for_each_safe(el, el1, &rt->gc_zero_ref_count_list) { p = list_entry(el, JSGCObjectHeader, link); assert(p->gc_obj_type == JS_GC_OBJ_TYPE_JS_OBJECT || p->gc_obj_type == JS_GC_OBJ_TYPE_FUNCTION_BYTECODE || p->gc_obj_type == JS_GC_OBJ_TYPE_ASYNC_FUNCTION || p->gc_obj_type == JS_GC_OBJ_TYPE_MODULE); if (p->gc_obj_type == JS_GC_OBJ_TYPE_JS_OBJECT && ((JSObject *)p)->weakref_count != 0) { /* keep the object because there are weak references to it */ p->mark = 0; } else { js_free_rt(rt, p); } } init_list_head(&rt->gc_zero_ref_count_list); } static void JS_RunGCInternal(JSRuntime *rt, BOOL remove_weak_objects) { if (remove_weak_objects) { /* free the weakly referenced object or symbol structures, delete the associated Map/Set entries and queue the finalization registry callbacks. */ gc_remove_weak_objects(rt); } /* decrement the reference of the children of each object. mark = 1 after this pass. */ gc_decref(rt); /* keep the GC objects with a non zero refcount and their childs */ gc_scan(rt); /* free the GC objects in a cycle */ gc_free_cycles(rt); } void JS_RunGC(JSRuntime *rt) { JS_RunGCInternal(rt, TRUE); } /* Return false if not an object or if the object has already been freed (zombie objects are visible in finalizers when freeing cycles). */ BOOL JS_IsLiveObject(JSRuntime *rt, JSValueConst obj) { JSObject *p; if (!JS_IsObject(obj)) return FALSE; p = JS_VALUE_GET_OBJ(obj); return !p->free_mark; } /* Compute memory used by various object types */ /* XXX: poor man's approach to handling multiply referenced objects */ typedef struct JSMemoryUsage_helper { double memory_used_count; double str_count; double str_size; int64_t js_func_count; double js_func_size; int64_t js_func_code_size; int64_t js_func_pc2line_count; int64_t js_func_pc2line_size; } JSMemoryUsage_helper; static void compute_value_size(JSValueConst val, JSMemoryUsage_helper *hp); static void compute_jsstring_size(JSString *str, JSMemoryUsage_helper *hp) { if (!str->atom_type) { /* atoms are handled separately */ double s_ref_count = str->header.ref_count; hp->str_count += 1 / s_ref_count; hp->str_size += ((sizeof(*str) + (str->len << str->is_wide_char) + 1 - str->is_wide_char) / s_ref_count); } } static void compute_bytecode_size(JSFunctionBytecode *b, JSMemoryUsage_helper *hp) { int memory_used_count, js_func_size, i; memory_used_count = 0; js_func_size = offsetof(JSFunctionBytecode, debug); if (b->vardefs) { js_func_size += (b->arg_count + b->var_count) * sizeof(*b->vardefs); } if (b->cpool) { js_func_size += b->cpool_count * sizeof(*b->cpool); for (i = 0; i < b->cpool_count; i++) { JSValueConst val = b->cpool[i]; compute_value_size(val, hp); } } if (b->closure_var) { js_func_size += b->closure_var_count * sizeof(*b->closure_var); } if (!b->read_only_bytecode && b->byte_code_buf) { hp->js_func_code_size += b->byte_code_len; } if (b->has_debug) { js_func_size += sizeof(*b) - offsetof(JSFunctionBytecode, debug); if (b->debug.source) { memory_used_count++; js_func_size += b->debug.source_len + 1; } if (b->debug.pc2line_len) { memory_used_count++; hp->js_func_pc2line_count += 1; hp->js_func_pc2line_size += b->debug.pc2line_len; } } hp->js_func_size += js_func_size; hp->js_func_count += 1; hp->memory_used_count += memory_used_count; } static void compute_value_size(JSValueConst val, JSMemoryUsage_helper *hp) { switch(JS_VALUE_GET_TAG(val)) { case JS_TAG_STRING: compute_jsstring_size(JS_VALUE_GET_STRING(val), hp); break; case JS_TAG_BIG_INT: /* should track JSBigInt usage */ break; } } void JS_ComputeMemoryUsage(JSRuntime *rt, JSMemoryUsage *s) { struct list_head *el, *el1; int i; JSMemoryUsage_helper mem = { 0 }, *hp = &mem; memset(s, 0, sizeof(*s)); s->malloc_count = rt->malloc_state.malloc_count; s->malloc_size = rt->malloc_state.malloc_size; s->malloc_limit = rt->malloc_state.malloc_limit; s->memory_used_count = 2; /* rt + rt->class_array */ s->memory_used_size = sizeof(JSRuntime) + sizeof(JSValue) * rt->class_count; list_for_each(el, &rt->context_list) { JSContext *ctx = list_entry(el, JSContext, link); JSShape *sh = ctx->array_shape; s->memory_used_count += 2; /* ctx + ctx->class_proto */ s->memory_used_size += sizeof(JSContext) + sizeof(JSValue) * rt->class_count; s->binary_object_count += ctx->binary_object_count; s->binary_object_size += ctx->binary_object_size; /* the hashed shapes are counted separately */ if (sh && !sh->is_hashed) { int hash_size = sh->prop_hash_mask + 1; s->shape_count++; s->shape_size += get_shape_size(hash_size, sh->prop_size); } list_for_each(el1, &ctx->loaded_modules) { JSModuleDef *m = list_entry(el1, JSModuleDef, link); s->memory_used_count += 1; s->memory_used_size += sizeof(*m); if (m->req_module_entries) { s->memory_used_count += 1; s->memory_used_size += m->req_module_entries_count * sizeof(*m->req_module_entries); } if (m->export_entries) { s->memory_used_count += 1; s->memory_used_size += m->export_entries_count * sizeof(*m->export_entries); for (i = 0; i < m->export_entries_count; i++) { JSExportEntry *me = &m->export_entries[i]; if (me->export_type == JS_EXPORT_TYPE_LOCAL && me->u.local.var_ref) { /* potential multiple count */ s->memory_used_count += 1; compute_value_size(me->u.local.var_ref->value, hp); } } } if (m->star_export_entries) { s->memory_used_count += 1; s->memory_used_size += m->star_export_entries_count * sizeof(*m->star_export_entries); } if (m->import_entries) { s->memory_used_count += 1; s->memory_used_size += m->import_entries_count * sizeof(*m->import_entries); } compute_value_size(m->module_ns, hp); compute_value_size(m->func_obj, hp); } } list_for_each(el, &rt->gc_obj_list) { JSGCObjectHeader *gp = list_entry(el, JSGCObjectHeader, link); JSObject *p; JSShape *sh; JSShapeProperty *prs; /* XXX: could count the other GC object types too */ if (gp->gc_obj_type == JS_GC_OBJ_TYPE_FUNCTION_BYTECODE) { compute_bytecode_size((JSFunctionBytecode *)gp, hp); continue; } else if (gp->gc_obj_type != JS_GC_OBJ_TYPE_JS_OBJECT) { continue; } p = (JSObject *)gp; sh = p->shape; s->obj_count++; if (p->prop) { s->memory_used_count++; s->prop_size += sh->prop_size * sizeof(*p->prop); s->prop_count += sh->prop_count; prs = get_shape_prop(sh); for(i = 0; i < sh->prop_count; i++) { JSProperty *pr = &p->prop[i]; if (prs->atom != JS_ATOM_NULL && !(prs->flags & JS_PROP_TMASK)) { compute_value_size(pr->u.value, hp); } prs++; } } /* the hashed shapes are counted separately */ if (!sh->is_hashed) { int hash_size = sh->prop_hash_mask + 1; s->shape_count++; s->shape_size += get_shape_size(hash_size, sh->prop_size); } switch(p->class_id) { case JS_CLASS_ARRAY: /* u.array | length */ case JS_CLASS_ARGUMENTS: /* u.array | length */ s->array_count++; if (p->fast_array) { s->fast_array_count++; if (p->u.array.u.values) { s->memory_used_count++; s->memory_used_size += p->u.array.count * sizeof(*p->u.array.u.values); s->fast_array_elements += p->u.array.count; for (i = 0; i < p->u.array.count; i++) { compute_value_size(p->u.array.u.values[i], hp); } } } break; case JS_CLASS_MAPPED_ARGUMENTS: /* u.array | length */ if (p->fast_array) { s->fast_array_count++; if (p->u.array.u.values) { s->memory_used_count++; s->memory_used_size += p->u.array.count * sizeof(*p->u.array.u.var_refs); s->fast_array_elements += p->u.array.count; for (i = 0; i < p->u.array.count; i++) { compute_value_size(*p->u.array.u.var_refs[i]->pvalue, hp); } } } break; case JS_CLASS_NUMBER: /* u.object_data */ case JS_CLASS_STRING: /* u.object_data */ case JS_CLASS_BOOLEAN: /* u.object_data */ case JS_CLASS_SYMBOL: /* u.object_data */ case JS_CLASS_DATE: /* u.object_data */ case JS_CLASS_BIG_INT: /* u.object_data */ compute_value_size(p->u.object_data, hp); break; case JS_CLASS_C_FUNCTION: /* u.cfunc */ s->c_func_count++; break; case JS_CLASS_BYTECODE_FUNCTION: /* u.func */ { JSFunctionBytecode *b = p->u.func.function_bytecode; JSVarRef **var_refs = p->u.func.var_refs; /* home_object: object will be accounted for in list scan */ if (var_refs) { s->memory_used_count++; s->js_func_size += b->closure_var_count * sizeof(*var_refs); for (i = 0; i < b->closure_var_count; i++) { if (var_refs[i]) { double ref_count = var_refs[i]->header.ref_count; s->memory_used_count += 1 / ref_count; s->js_func_size += sizeof(*var_refs[i]) / ref_count; /* handle non object closed values */ if (var_refs[i]->pvalue == &var_refs[i]->value) { /* potential multiple count */ compute_value_size(var_refs[i]->value, hp); } } } } } break; case JS_CLASS_BOUND_FUNCTION: /* u.bound_function */ { JSBoundFunction *bf = p->u.bound_function; /* func_obj and this_val are objects */ for (i = 0; i < bf->argc; i++) { compute_value_size(bf->argv[i], hp); } s->memory_used_count += 1; s->memory_used_size += sizeof(*bf) + bf->argc * sizeof(*bf->argv); } break; case JS_CLASS_C_FUNCTION_DATA: /* u.c_function_data_record */ { JSCFunctionDataRecord *fd = p->u.c_function_data_record; if (fd) { for (i = 0; i < fd->data_len; i++) { compute_value_size(fd->data[i], hp); } s->memory_used_count += 1; s->memory_used_size += sizeof(*fd) + fd->data_len * sizeof(*fd->data); } } break; case JS_CLASS_REGEXP: /* u.regexp */ compute_jsstring_size(p->u.regexp.pattern, hp); compute_jsstring_size(p->u.regexp.bytecode, hp); break; case JS_CLASS_FOR_IN_ITERATOR: /* u.for_in_iterator */ { JSForInIterator *it = p->u.for_in_iterator; if (it) { compute_value_size(it->obj, hp); s->memory_used_count += 1; s->memory_used_size += sizeof(*it); } } break; case JS_CLASS_ARRAY_BUFFER: /* u.array_buffer */ case JS_CLASS_SHARED_ARRAY_BUFFER: /* u.array_buffer */ { JSArrayBuffer *abuf = p->u.array_buffer; if (abuf) { s->memory_used_count += 1; s->memory_used_size += sizeof(*abuf); if (abuf->data) { s->memory_used_count += 1; s->memory_used_size += abuf->byte_length; } } } break; case JS_CLASS_GENERATOR: /* u.generator_data */ case JS_CLASS_UINT8C_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_INT8_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_UINT8_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_INT16_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_UINT16_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_INT32_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_UINT32_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_BIG_INT64_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_BIG_UINT64_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_FLOAT16_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_FLOAT32_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_FLOAT64_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_DATAVIEW: /* u.typed_array */ case JS_CLASS_MAP: /* u.map_state */ case JS_CLASS_SET: /* u.map_state */ case JS_CLASS_WEAKMAP: /* u.map_state */ case JS_CLASS_WEAKSET: /* u.map_state */ case JS_CLASS_MAP_ITERATOR: /* u.map_iterator_data */ case JS_CLASS_SET_ITERATOR: /* u.map_iterator_data */ case JS_CLASS_ARRAY_ITERATOR: /* u.array_iterator_data */ case JS_CLASS_STRING_ITERATOR: /* u.array_iterator_data */ case JS_CLASS_PROXY: /* u.proxy_data */ case JS_CLASS_PROMISE: /* u.promise_data */ case JS_CLASS_PROMISE_RESOLVE_FUNCTION: /* u.promise_function_data */ case JS_CLASS_PROMISE_REJECT_FUNCTION: /* u.promise_function_data */ case JS_CLASS_ASYNC_FUNCTION_RESOLVE: /* u.async_function_data */ case JS_CLASS_ASYNC_FUNCTION_REJECT: /* u.async_function_data */ case JS_CLASS_ASYNC_FROM_SYNC_ITERATOR: /* u.async_from_sync_iterator_data */ case JS_CLASS_ASYNC_GENERATOR: /* u.async_generator_data */ /* TODO */ default: /* XXX: class definition should have an opaque block size */ if (p->u.opaque) { s->memory_used_count += 1; } break; } } s->obj_size += s->obj_count * sizeof(JSObject); /* hashed shapes */ s->memory_used_count++; /* rt->shape_hash */ s->memory_used_size += sizeof(rt->shape_hash[0]) * rt->shape_hash_size; for(i = 0; i < rt->shape_hash_size; i++) { JSShape *sh; for(sh = rt->shape_hash[i]; sh != NULL; sh = sh->shape_hash_next) { int hash_size = sh->prop_hash_mask + 1; s->shape_count++; s->shape_size += get_shape_size(hash_size, sh->prop_size); } } /* atoms */ s->memory_used_count += 2; /* rt->atom_array, rt->atom_hash */ s->atom_count = rt->atom_count; s->atom_size = sizeof(rt->atom_array[0]) * rt->atom_size + sizeof(rt->atom_hash[0]) * rt->atom_hash_size; for(i = 0; i < rt->atom_size; i++) { JSAtomStruct *p = rt->atom_array[i]; if (!atom_is_free(p)) { s->atom_size += (sizeof(*p) + (p->len << p->is_wide_char) + 1 - p->is_wide_char); } } s->str_count = round(mem.str_count); s->str_size = round(mem.str_size); s->js_func_count = mem.js_func_count; s->js_func_size = round(mem.js_func_size); s->js_func_code_size = mem.js_func_code_size; s->js_func_pc2line_count = mem.js_func_pc2line_count; s->js_func_pc2line_size = mem.js_func_pc2line_size; s->memory_used_count += round(mem.memory_used_count) + s->atom_count + s->str_count + s->obj_count + s->shape_count + s->js_func_count + s->js_func_pc2line_count; s->memory_used_size += s->atom_size + s->str_size + s->obj_size + s->prop_size + s->shape_size + s->js_func_size + s->js_func_code_size + s->js_func_pc2line_size; } void JS_DumpMemoryUsage(FILE *fp, const JSMemoryUsage *s, JSRuntime *rt) { fprintf(fp, "QuickJS memory usage -- " CONFIG_VERSION " version, %d-bit, malloc limit: %"PRId64"\n\n", (int)sizeof(void *) * 8, s->malloc_limit); #if 1 if (rt) { static const struct { const char *name; size_t size; } object_types[] = { { "JSRuntime", sizeof(JSRuntime) }, { "JSContext", sizeof(JSContext) }, { "JSObject", sizeof(JSObject) }, { "JSString", sizeof(JSString) }, { "JSFunctionBytecode", sizeof(JSFunctionBytecode) }, }; int i, usage_size_ok = 0; for(i = 0; i < countof(object_types); i++) { unsigned int size = object_types[i].size; void *p = js_malloc_rt(rt, size); if (p) { unsigned int size1 = js_malloc_usable_size_rt(rt, p); if (size1 >= size) { usage_size_ok = 1; fprintf(fp, " %3u + %-2u %s\n", size, size1 - size, object_types[i].name); } js_free_rt(rt, p); } } if (!usage_size_ok) { fprintf(fp, " malloc_usable_size unavailable\n"); } { int obj_classes[JS_CLASS_INIT_COUNT + 1] = { 0 }; int class_id; struct list_head *el; list_for_each(el, &rt->gc_obj_list) { JSGCObjectHeader *gp = list_entry(el, JSGCObjectHeader, link); JSObject *p; if (gp->gc_obj_type == JS_GC_OBJ_TYPE_JS_OBJECT) { p = (JSObject *)gp; obj_classes[min_uint32(p->class_id, JS_CLASS_INIT_COUNT)]++; } } fprintf(fp, "\n" "JSObject classes\n"); if (obj_classes[0]) fprintf(fp, " %5d %2.0d %s\n", obj_classes[0], 0, "none"); for (class_id = 1; class_id < JS_CLASS_INIT_COUNT; class_id++) { if (obj_classes[class_id] && class_id < rt->class_count) { char buf[ATOM_GET_STR_BUF_SIZE]; fprintf(fp, " %5d %2.0d %s\n", obj_classes[class_id], class_id, JS_AtomGetStrRT(rt, buf, sizeof(buf), rt->class_array[class_id].class_name)); } } if (obj_classes[JS_CLASS_INIT_COUNT]) fprintf(fp, " %5d %2.0d %s\n", obj_classes[JS_CLASS_INIT_COUNT], 0, "other"); } fprintf(fp, "\n"); } #endif fprintf(fp, "%-20s %8s %8s\n", "NAME", "COUNT", "SIZE"); if (s->malloc_count) { fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%0.1f per block)\n", "memory allocated", s->malloc_count, s->malloc_size, (double)s->malloc_size / s->malloc_count); fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%d overhead, %0.1f average slack)\n", "memory used", s->memory_used_count, s->memory_used_size, MALLOC_OVERHEAD, ((double)(s->malloc_size - s->memory_used_size) / s->memory_used_count)); } if (s->atom_count) { fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%0.1f per atom)\n", "atoms", s->atom_count, s->atom_size, (double)s->atom_size / s->atom_count); } if (s->str_count) { fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%0.1f per string)\n", "strings", s->str_count, s->str_size, (double)s->str_size / s->str_count); } if (s->obj_count) { fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%0.1f per object)\n", "objects", s->obj_count, s->obj_size, (double)s->obj_size / s->obj_count); fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%0.1f per object)\n", " properties", s->prop_count, s->prop_size, (double)s->prop_count / s->obj_count); fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%0.1f per shape)\n", " shapes", s->shape_count, s->shape_size, (double)s->shape_size / s->shape_count); } if (s->js_func_count) { fprintf(fp, "%-20s %8"PRId64" %8"PRId64"\n", "bytecode functions", s->js_func_count, s->js_func_size); fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%0.1f per function)\n", " bytecode", s->js_func_count, s->js_func_code_size, (double)s->js_func_code_size / s->js_func_count); if (s->js_func_pc2line_count) { fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%0.1f per function)\n", " pc2line", s->js_func_pc2line_count, s->js_func_pc2line_size, (double)s->js_func_pc2line_size / s->js_func_pc2line_count); } } if (s->c_func_count) { fprintf(fp, "%-20s %8"PRId64"\n", "C functions", s->c_func_count); } if (s->array_count) { fprintf(fp, "%-20s %8"PRId64"\n", "arrays", s->array_count); if (s->fast_array_count) { fprintf(fp, "%-20s %8"PRId64"\n", " fast arrays", s->fast_array_count); fprintf(fp, "%-20s %8"PRId64" %8"PRId64" (%0.1f per fast array)\n", " elements", s->fast_array_elements, s->fast_array_elements * (int)sizeof(JSValue), (double)s->fast_array_elements / s->fast_array_count); } } if (s->binary_object_count) { fprintf(fp, "%-20s %8"PRId64" %8"PRId64"\n", "binary objects", s->binary_object_count, s->binary_object_size); } } JSValue JS_GetGlobalObject(JSContext *ctx) { return JS_DupValue(ctx, ctx->global_obj); } /* WARNING: obj is freed */ JSValue JS_Throw(JSContext *ctx, JSValue obj) { JSRuntime *rt = ctx->rt; JS_FreeValue(ctx, rt->current_exception); rt->current_exception = obj; rt->current_exception_is_uncatchable = FALSE; return JS_EXCEPTION; } /* return the pending exception (cannot be called twice). */ JSValue JS_GetException(JSContext *ctx) { JSValue val; JSRuntime *rt = ctx->rt; val = rt->current_exception; rt->current_exception = JS_UNINITIALIZED; return val; } JS_BOOL JS_HasException(JSContext *ctx) { return !JS_IsUninitialized(ctx->rt->current_exception); } static void dbuf_put_leb128(DynBuf *s, uint32_t v) { uint32_t a; for(;;) { a = v & 0x7f; v >>= 7; if (v != 0) { dbuf_putc(s, a | 0x80); } else { dbuf_putc(s, a); break; } } } static void dbuf_put_sleb128(DynBuf *s, int32_t v1) { uint32_t v = v1; dbuf_put_leb128(s, (2 * v) ^ -(v >> 31)); } static int get_leb128(uint32_t *pval, const uint8_t *buf, const uint8_t *buf_end) { const uint8_t *ptr = buf; uint32_t v, a, i; v = 0; for(i = 0; i < 5; i++) { if (unlikely(ptr >= buf_end)) break; a = *ptr++; v |= (a & 0x7f) << (i * 7); if (!(a & 0x80)) { *pval = v; return ptr - buf; } } *pval = 0; return -1; } static int get_sleb128(int32_t *pval, const uint8_t *buf, const uint8_t *buf_end) { int ret; uint32_t val; ret = get_leb128(&val, buf, buf_end); if (ret < 0) { *pval = 0; return -1; } *pval = (val >> 1) ^ -(val & 1); return ret; } /* use pc_value = -1 to get the position of the function definition */ static int find_line_num(JSContext *ctx, JSFunctionBytecode *b, uint32_t pc_value, int *pcol_num) { const uint8_t *p_end, *p; int new_line_num, line_num, pc, v, ret, new_col_num, col_num; uint32_t val; unsigned int op; if (!b->has_debug || !b->debug.pc2line_buf) goto fail; /* function was stripped */ p = b->debug.pc2line_buf; p_end = p + b->debug.pc2line_len; /* get the function line and column numbers */ ret = get_leb128(&val, p, p_end); if (ret < 0) goto fail; p += ret; line_num = val + 1; ret = get_leb128(&val, p, p_end); if (ret < 0) goto fail; p += ret; col_num = val + 1; if (pc_value != -1) { pc = 0; while (p < p_end) { op = *p++; if (op == 0) { ret = get_leb128(&val, p, p_end); if (ret < 0) goto fail; pc += val; p += ret; ret = get_sleb128(&v, p, p_end); if (ret < 0) goto fail; p += ret; new_line_num = line_num + v; } else { op -= PC2LINE_OP_FIRST; pc += (op / PC2LINE_RANGE); new_line_num = line_num + (op % PC2LINE_RANGE) + PC2LINE_BASE; } ret = get_sleb128(&v, p, p_end); if (ret < 0) goto fail; p += ret; new_col_num = col_num + v; if (pc_value < pc) goto done; line_num = new_line_num; col_num = new_col_num; } } done: *pcol_num = col_num; return line_num; fail: *pcol_num = 0; return 0; } /* return a string property without executing arbitrary JS code (used when dumping the stack trace or in debug print). */ static const char *get_prop_string(JSContext *ctx, JSValueConst obj, JSAtom prop) { JSObject *p; JSProperty *pr; JSShapeProperty *prs; JSValueConst val; if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) return NULL; p = JS_VALUE_GET_OBJ(obj); prs = find_own_property(&pr, p, prop); if (!prs) { /* we look at one level in the prototype to handle the 'name' field of the Error objects */ p = p->shape->proto; if (!p) return NULL; prs = find_own_property(&pr, p, prop); if (!prs) return NULL; } if ((prs->flags & JS_PROP_TMASK) != JS_PROP_NORMAL) return NULL; val = pr->u.value; if (JS_VALUE_GET_TAG(val) != JS_TAG_STRING) return NULL; return JS_ToCString(ctx, val); } #define JS_BACKTRACE_FLAG_SKIP_FIRST_LEVEL (1 << 0) /* if filename != NULL, an additional level is added with the filename and line number information (used for parse error). */ static void build_backtrace(JSContext *ctx, JSValueConst error_obj, JSValueConst filter_func, const char *filename, int line_num, int col_num, int backtrace_flags) { JSStackFrame *sf; JSValue str; DynBuf dbuf; const char *func_name_str; const char *str1; JSObject *p; if (!JS_IsObject(error_obj)) return; /* protection in the out of memory case */ js_dbuf_init(ctx, &dbuf); if (filename) { dbuf_printf(&dbuf, " at %s", filename); if (line_num != -1) dbuf_printf(&dbuf, ":%d:%d", line_num, col_num); dbuf_putc(&dbuf, '\n'); str = JS_NewString(ctx, filename); if (JS_IsException(str)) return; /* Note: SpiderMonkey does that, could update once there is a standard */ if (JS_DefinePropertyValue(ctx, error_obj, JS_ATOM_fileName, str, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE) < 0 || JS_DefinePropertyValue(ctx, error_obj, JS_ATOM_lineNumber, JS_NewInt32(ctx, line_num), JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE) < 0 || JS_DefinePropertyValue(ctx, error_obj, JS_ATOM_columnNumber, JS_NewInt32(ctx, col_num), JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE) < 0) { return; } } sf = ctx->rt->current_stack_frame; if (!JS_IsUndefined(filter_func)) { for (; sf != NULL; sf = sf->prev_frame) { if (js_same_value(ctx, sf->cur_func, filter_func)) goto found; } sf = ctx->rt->current_stack_frame; found: } for(; sf != NULL; sf = sf->prev_frame) { if (sf->js_mode & JS_MODE_BACKTRACE_BARRIER) break; if (backtrace_flags & JS_BACKTRACE_FLAG_SKIP_FIRST_LEVEL) { backtrace_flags &= ~JS_BACKTRACE_FLAG_SKIP_FIRST_LEVEL; continue; } func_name_str = get_prop_string(ctx, sf->cur_func, JS_ATOM_name); if (!func_name_str || func_name_str[0] == '\0') str1 = "<anonymous>"; else str1 = func_name_str; dbuf_printf(&dbuf, " at %s", str1); JS_FreeCString(ctx, func_name_str); p = JS_VALUE_GET_OBJ(sf->cur_func); if (js_class_has_bytecode(p->class_id)) { JSFunctionBytecode *b; const char *atom_str; int line_num1, col_num1; b = p->u.func.function_bytecode; if (b->has_debug) { line_num1 = find_line_num(ctx, b, sf->cur_pc - b->byte_code_buf - 1, &col_num1); atom_str = JS_AtomToCString(ctx, b->debug.filename); dbuf_printf(&dbuf, " (%s", atom_str ? atom_str : "<null>"); JS_FreeCString(ctx, atom_str); if (line_num1 != 0) dbuf_printf(&dbuf, ":%d:%d", line_num1, col_num1); dbuf_putc(&dbuf, ')'); } } else { dbuf_printf(&dbuf, " (native)"); } dbuf_putc(&dbuf, '\n'); } dbuf_putc(&dbuf, '\0'); if (dbuf_error(&dbuf)) str = JS_NULL; else str = JS_NewString(ctx, (char *)dbuf.buf); dbuf_free(&dbuf); JS_DefinePropertyValue(ctx, error_obj, JS_ATOM_stack, str, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); } /* Note: it is important that no exception is returned by this function */ static BOOL is_backtrace_needed(JSContext *ctx, JSValueConst obj) { JSObject *p; if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) return FALSE; p = JS_VALUE_GET_OBJ(obj); if (p->class_id != JS_CLASS_ERROR) return FALSE; if (find_own_property1(p, JS_ATOM_stack)) return FALSE; return TRUE; } void JS_BuildBacktrace(JSContext *ctx, JSValueConst obj, int skip_first_level) { build_backtrace(ctx, obj, JS_UNDEFINED, NULL, 0, 0, skip_first_level); } JSValue JS_NewError(JSContext *ctx) { return JS_NewObjectClass(ctx, JS_CLASS_ERROR); } static JSValue JS_ThrowError2(JSContext *ctx, JSErrorEnum error_num, const char *fmt, va_list ap, BOOL add_backtrace) { char buf[256]; JSValue obj, ret; vsnprintf(buf, sizeof(buf), fmt, ap); obj = JS_NewObjectProtoClass(ctx, ctx->native_error_proto[error_num], JS_CLASS_ERROR); if (unlikely(JS_IsException(obj))) { /* out of memory: throw JS_NULL to avoid recursing */ obj = JS_NULL; } else { JS_DefinePropertyValue(ctx, obj, JS_ATOM_message, JS_NewString(ctx, buf), JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); if (add_backtrace) { build_backtrace(ctx, obj, JS_UNDEFINED, NULL, 0, 0, 0); } } ret = JS_Throw(ctx, obj); return ret; } static JSValue JS_ThrowError(JSContext *ctx, JSErrorEnum error_num, const char *fmt, va_list ap) { JSRuntime *rt = ctx->rt; JSStackFrame *sf; BOOL add_backtrace; /* the backtrace is added later if called from a bytecode function */ sf = rt->current_stack_frame; add_backtrace = !rt->in_out_of_memory && (!sf || (JS_GetFunctionBytecode(sf->cur_func) == NULL)); return JS_ThrowError2(ctx, error_num, fmt, ap, add_backtrace); } JSValue __attribute__((format(printf, 2, 3))) JS_ThrowSyntaxError(JSContext *ctx, const char *fmt, ...) { JSValue val; va_list ap; va_start(ap, fmt); val = JS_ThrowError(ctx, JS_SYNTAX_ERROR, fmt, ap); va_end(ap); return val; } JSValue __attribute__((format(printf, 2, 3))) JS_ThrowTypeError(JSContext *ctx, const char *fmt, ...) { JSValue val; va_list ap; va_start(ap, fmt); val = JS_ThrowError(ctx, JS_TYPE_ERROR, fmt, ap); va_end(ap); return val; } static int __attribute__((format(printf, 3, 4))) JS_ThrowTypeErrorOrFalse(JSContext *ctx, int flags, const char *fmt, ...) { va_list ap; if ((flags & JS_PROP_THROW) || ((flags & JS_PROP_THROW_STRICT) && is_strict_mode(ctx))) { va_start(ap, fmt); JS_ThrowError(ctx, JS_TYPE_ERROR, fmt, ap); va_end(ap); return -1; } else { return FALSE; } } /* never use it directly */ static JSValue __attribute__((format(printf, 3, 4))) __JS_ThrowTypeErrorAtom(JSContext *ctx, JSAtom atom, const char *fmt, ...) { char buf[ATOM_GET_STR_BUF_SIZE]; return JS_ThrowTypeError(ctx, fmt, JS_AtomGetStr(ctx, buf, sizeof(buf), atom)); } /* never use it directly */ static JSValue __attribute__((format(printf, 3, 4))) __JS_ThrowSyntaxErrorAtom(JSContext *ctx, JSAtom atom, const char *fmt, ...) { char buf[ATOM_GET_STR_BUF_SIZE]; return JS_ThrowSyntaxError(ctx, fmt, JS_AtomGetStr(ctx, buf, sizeof(buf), atom)); } /* %s is replaced by 'atom'. The macro is used so that gcc can check the format string. */ #define JS_ThrowTypeErrorAtom(ctx, fmt, atom) __JS_ThrowTypeErrorAtom(ctx, atom, fmt, "") #define JS_ThrowSyntaxErrorAtom(ctx, fmt, atom) __JS_ThrowSyntaxErrorAtom(ctx, atom, fmt, "") static int JS_ThrowTypeErrorReadOnly(JSContext *ctx, int flags, JSAtom atom) { if ((flags & JS_PROP_THROW) || ((flags & JS_PROP_THROW_STRICT) && is_strict_mode(ctx))) { JS_ThrowTypeErrorAtom(ctx, "'%s' is read-only", atom); return -1; } else { return FALSE; } } JSValue __attribute__((format(printf, 2, 3))) JS_ThrowReferenceError(JSContext *ctx, const char *fmt, ...) { JSValue val; va_list ap; va_start(ap, fmt); val = JS_ThrowError(ctx, JS_REFERENCE_ERROR, fmt, ap); va_end(ap); return val; } JSValue __attribute__((format(printf, 2, 3))) JS_ThrowRangeError(JSContext *ctx, const char *fmt, ...) { JSValue val; va_list ap; va_start(ap, fmt); val = JS_ThrowError(ctx, JS_RANGE_ERROR, fmt, ap); va_end(ap); return val; } JSValue __attribute__((format(printf, 2, 3))) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...) { JSValue val; va_list ap; va_start(ap, fmt); val = JS_ThrowError(ctx, JS_INTERNAL_ERROR, fmt, ap); va_end(ap); return val; } JSValue JS_ThrowOutOfMemory(JSContext *ctx) { JSRuntime *rt = ctx->rt; if (!rt->in_out_of_memory) { rt->in_out_of_memory = TRUE; JS_ThrowInternalError(ctx, "out of memory"); rt->in_out_of_memory = FALSE; } return JS_EXCEPTION; } static JSValue JS_ThrowStackOverflow(JSContext *ctx) { return JS_ThrowInternalError(ctx, "stack overflow"); } static JSValue JS_ThrowTypeErrorNotAnObject(JSContext *ctx) { return JS_ThrowTypeError(ctx, "not an object"); } static JSValue JS_ThrowTypeErrorNotAConstructor(JSContext *ctx, JSValueConst func_obj) { const char *name; if (!JS_IsFunction(ctx, func_obj)) goto fail; name = get_prop_string(ctx, func_obj, JS_ATOM_name); if (!name) { fail: return JS_ThrowTypeError(ctx, "not a constructor"); } JS_ThrowTypeError(ctx, "%s is not a constructor", name); JS_FreeCString(ctx, name); return JS_EXCEPTION; } static JSValue JS_ThrowTypeErrorNotASymbol(JSContext *ctx) { return JS_ThrowTypeError(ctx, "not a symbol"); } static JSValue JS_ThrowReferenceErrorNotDefined(JSContext *ctx, JSAtom name) { char buf[ATOM_GET_STR_BUF_SIZE]; return JS_ThrowReferenceError(ctx, "'%s' is not defined", JS_AtomGetStr(ctx, buf, sizeof(buf), name)); } static JSValue JS_ThrowReferenceErrorUninitialized(JSContext *ctx, JSAtom name) { char buf[ATOM_GET_STR_BUF_SIZE]; return JS_ThrowReferenceError(ctx, "%s is not initialized", name == JS_ATOM_NULL ? "lexical variable" : JS_AtomGetStr(ctx, buf, sizeof(buf), name)); } static JSValue JS_ThrowReferenceErrorUninitialized2(JSContext *ctx, JSFunctionBytecode *b, int idx, BOOL is_ref) { JSAtom atom = JS_ATOM_NULL; if (is_ref) { atom = b->closure_var[idx].var_name; } else { /* not present if the function is stripped and contains no eval() */ if (b->vardefs) atom = b->vardefs[b->arg_count + idx].var_name; } return JS_ThrowReferenceErrorUninitialized(ctx, atom); } static JSValue JS_ThrowTypeErrorInvalidClass(JSContext *ctx, int class_id) { JSRuntime *rt = ctx->rt; JSAtom name; name = rt->class_array[class_id].class_name; return JS_ThrowTypeErrorAtom(ctx, "%s object expected", name); } static void JS_ThrowInterrupted(JSContext *ctx) { JS_ThrowInternalError(ctx, "interrupted"); JS_SetUncatchableException(ctx, TRUE); } static no_inline __exception int __js_poll_interrupts(JSContext *ctx) { JSRuntime *rt = ctx->rt; ctx->interrupt_counter = JS_INTERRUPT_COUNTER_INIT; if (rt->interrupt_handler) { if (rt->interrupt_handler(rt, rt->interrupt_opaque)) { JS_ThrowInterrupted(ctx); return -1; } } return 0; } static inline __exception int js_poll_interrupts(JSContext *ctx) { if (unlikely(--ctx->interrupt_counter <= 0)) { return __js_poll_interrupts(ctx); } else { return 0; } } static void JS_SetImmutablePrototype(JSContext *ctx, JSValueConst obj) { JSObject *p; if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) return; p = JS_VALUE_GET_OBJ(obj); p->has_immutable_prototype = TRUE; } /* Return -1 (exception) or TRUE/FALSE. 'throw_flag' = FALSE indicates that it is called from Reflect.setPrototypeOf(). */ static int JS_SetPrototypeInternal(JSContext *ctx, JSValueConst obj, JSValueConst proto_val, BOOL throw_flag) { JSObject *proto, *p, *p1; JSShape *sh; if (throw_flag) { if (JS_VALUE_GET_TAG(obj) == JS_TAG_NULL || JS_VALUE_GET_TAG(obj) == JS_TAG_UNDEFINED) goto not_obj; } else { if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) goto not_obj; } p = JS_VALUE_GET_OBJ(obj); if (JS_VALUE_GET_TAG(proto_val) != JS_TAG_OBJECT) { if (JS_VALUE_GET_TAG(proto_val) != JS_TAG_NULL) { not_obj: JS_ThrowTypeErrorNotAnObject(ctx); return -1; } proto = NULL; } else { proto = JS_VALUE_GET_OBJ(proto_val); } if (throw_flag && JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) return TRUE; if (unlikely(p->is_exotic)) { const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; int ret; if (em && em->set_prototype) { ret = em->set_prototype(ctx, obj, proto_val); if (ret == 0 && throw_flag) { JS_ThrowTypeError(ctx, "proxy: bad prototype"); return -1; } else { return ret; } } } sh = p->shape; if (sh->proto == proto) return TRUE; if (unlikely(p->has_immutable_prototype)) { if (throw_flag) { JS_ThrowTypeError(ctx, "prototype is immutable"); return -1; } else { return FALSE; } } if (unlikely(!p->extensible)) { if (throw_flag) { JS_ThrowTypeError(ctx, "object is not extensible"); return -1; } else { return FALSE; } } if (proto) { /* check if there is a cycle */ p1 = proto; do { if (p1 == p) { if (throw_flag) { JS_ThrowTypeError(ctx, "circular prototype chain"); return -1; } else { return FALSE; } } /* Note: for Proxy objects, proto is NULL */ p1 = p1->shape->proto; } while (p1 != NULL); JS_DupValue(ctx, proto_val); } if (js_shape_prepare_update(ctx, p, NULL)) return -1; sh = p->shape; if (sh->proto) JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, sh->proto)); sh->proto = proto; p->is_std_array_prototype = FALSE; return TRUE; } /* return -1 (exception) or TRUE/FALSE */ int JS_SetPrototype(JSContext *ctx, JSValueConst obj, JSValueConst proto_val) { return JS_SetPrototypeInternal(ctx, obj, proto_val, TRUE); } /* Only works for primitive types, otherwise return JS_NULL. */ static JSValueConst JS_GetPrototypePrimitive(JSContext *ctx, JSValueConst val) { switch(JS_VALUE_GET_NORM_TAG(val)) { case JS_TAG_SHORT_BIG_INT: case JS_TAG_BIG_INT: val = ctx->class_proto[JS_CLASS_BIG_INT]; break; case JS_TAG_INT: case JS_TAG_FLOAT64: val = ctx->class_proto[JS_CLASS_NUMBER]; break; case JS_TAG_BOOL: val = ctx->class_proto[JS_CLASS_BOOLEAN]; break; case JS_TAG_STRING: case JS_TAG_STRING_ROPE: val = ctx->class_proto[JS_CLASS_STRING]; break; case JS_TAG_SYMBOL: val = ctx->class_proto[JS_CLASS_SYMBOL]; break; case JS_TAG_OBJECT: case JS_TAG_NULL: case JS_TAG_UNDEFINED: default: val = JS_NULL; break; } return val; } /* Return an Object, JS_NULL or JS_EXCEPTION in case of exotic object. */ JSValue JS_GetPrototype(JSContext *ctx, JSValueConst obj) { JSValue val; if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { JSObject *p; p = JS_VALUE_GET_OBJ(obj); if (unlikely(p->is_exotic)) { const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; if (em && em->get_prototype) { return em->get_prototype(ctx, obj); } } p = p->shape->proto; if (!p) val = JS_NULL; else val = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p)); } else { val = JS_DupValue(ctx, JS_GetPrototypePrimitive(ctx, obj)); } return val; } static JSValue JS_GetPrototypeFree(JSContext *ctx, JSValue obj) { JSValue obj1; obj1 = JS_GetPrototype(ctx, obj); JS_FreeValue(ctx, obj); return obj1; } /* return TRUE, FALSE or (-1) in case of exception */ static int JS_OrdinaryIsInstanceOf(JSContext *ctx, JSValueConst val, JSValueConst obj) { JSValue obj_proto; JSObject *proto; const JSObject *p, *proto1; BOOL ret; if (!JS_IsFunction(ctx, obj)) return FALSE; p = JS_VALUE_GET_OBJ(obj); if (p->class_id == JS_CLASS_BOUND_FUNCTION) { JSBoundFunction *s = p->u.bound_function; return JS_IsInstanceOf(ctx, val, s->func_obj); } /* Only explicitly boxed values are instances of constructors */ if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) return FALSE; obj_proto = JS_GetProperty(ctx, obj, JS_ATOM_prototype); if (JS_VALUE_GET_TAG(obj_proto) != JS_TAG_OBJECT) { if (!JS_IsException(obj_proto)) JS_ThrowTypeError(ctx, "operand 'prototype' property is not an object"); ret = -1; goto done; } proto = JS_VALUE_GET_OBJ(obj_proto); p = JS_VALUE_GET_OBJ(val); for(;;) { proto1 = p->shape->proto; if (!proto1) { /* slow case if exotic object in the prototype chain */ if (unlikely(p->is_exotic && !p->fast_array)) { JSValue obj1; obj1 = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, (JSObject *)p)); for(;;) { obj1 = JS_GetPrototypeFree(ctx, obj1); if (JS_IsException(obj1)) { ret = -1; break; } if (JS_IsNull(obj1)) { ret = FALSE; break; } if (proto == JS_VALUE_GET_OBJ(obj1)) { JS_FreeValue(ctx, obj1); ret = TRUE; break; } /* must check for timeout to avoid infinite loop */ if (js_poll_interrupts(ctx)) { JS_FreeValue(ctx, obj1); ret = -1; break; } } } else { ret = FALSE; } break; } p = proto1; if (proto == p) { ret = TRUE; break; } } done: JS_FreeValue(ctx, obj_proto); return ret; } /* return TRUE, FALSE or (-1) in case of exception */ int JS_IsInstanceOf(JSContext *ctx, JSValueConst val, JSValueConst obj) { JSValue method; if (!JS_IsObject(obj)) goto fail; method = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_hasInstance); if (JS_IsException(method)) return -1; if (!JS_IsNull(method) && !JS_IsUndefined(method)) { JSValue ret; ret = JS_CallFree(ctx, method, obj, 1, &val); return JS_ToBoolFree(ctx, ret); } /* legacy case */ if (!JS_IsFunction(ctx, obj)) { fail: JS_ThrowTypeError(ctx, "invalid 'instanceof' right operand"); return -1; } return JS_OrdinaryIsInstanceOf(ctx, val, obj); } /* return the value associated to the autoinit property or an exception */ typedef JSValue JSAutoInitFunc(JSContext *ctx, JSObject *p, JSAtom atom, void *opaque); static JSAutoInitFunc *js_autoinit_func_table[] = { js_instantiate_prototype, /* JS_AUTOINIT_ID_PROTOTYPE */ js_module_ns_autoinit, /* JS_AUTOINIT_ID_MODULE_NS */ JS_InstantiateFunctionListItem2, /* JS_AUTOINIT_ID_PROP */ }; /* warning: 'prs' is reallocated after it */ static int JS_AutoInitProperty(JSContext *ctx, JSObject *p, JSAtom prop, JSProperty *pr, JSShapeProperty *prs) { JSValue val; JSContext *realm; JSAutoInitFunc *func; JSAutoInitIDEnum id; if (js_shape_prepare_update(ctx, p, &prs)) return -1; realm = js_autoinit_get_realm(pr); id = js_autoinit_get_id(pr); func = js_autoinit_func_table[id]; /* 'func' shall not modify the object properties 'pr' */ val = func(realm, p, prop, pr->u.init.opaque); js_autoinit_free(ctx->rt, pr); prs->flags &= ~JS_PROP_TMASK; pr->u.value = JS_UNDEFINED; if (JS_IsException(val)) return -1; if (id == JS_AUTOINIT_ID_MODULE_NS && JS_VALUE_GET_TAG(val) == JS_TAG_STRING) { /* WARNING: a varref is returned as a string ! */ prs->flags |= JS_PROP_VARREF; pr->u.var_ref = JS_VALUE_GET_PTR(val); pr->u.var_ref->header.ref_count++; } else if (p->class_id == JS_CLASS_GLOBAL_OBJECT) { JSVarRef *var_ref; /* in the global object we use references */ var_ref = js_create_var_ref(ctx, FALSE); if (!var_ref) return -1; prs->flags |= JS_PROP_VARREF; pr->u.var_ref = var_ref; var_ref->value = val; var_ref->is_const = !(prs->flags & JS_PROP_WRITABLE); } else { pr->u.value = val; } return 0; } JSValue JS_GetPropertyInternal(JSContext *ctx, JSValueConst obj, JSAtom prop, JSValueConst this_obj, BOOL throw_ref_error) { JSObject *p; JSProperty *pr; JSShapeProperty *prs; uint32_t tag; tag = JS_VALUE_GET_TAG(obj); if (unlikely(tag != JS_TAG_OBJECT)) { switch(tag) { case JS_TAG_NULL: return JS_ThrowTypeErrorAtom(ctx, "cannot read property '%s' of null", prop); case JS_TAG_UNDEFINED: return JS_ThrowTypeErrorAtom(ctx, "cannot read property '%s' of undefined", prop); case JS_TAG_EXCEPTION: return JS_EXCEPTION; case JS_TAG_STRING: { JSString *p1 = JS_VALUE_GET_STRING(obj); if (__JS_AtomIsTaggedInt(prop)) { uint32_t idx; idx = __JS_AtomToUInt32(prop); if (idx < p1->len) { return js_new_string_char(ctx, string_get(p1, idx)); } } else if (prop == JS_ATOM_length) { return JS_NewInt32(ctx, p1->len); } } break; case JS_TAG_STRING_ROPE: { JSStringRope *p1 = JS_VALUE_GET_STRING_ROPE(obj); if (__JS_AtomIsTaggedInt(prop)) { uint32_t idx; idx = __JS_AtomToUInt32(prop); if (idx < p1->len) { return js_new_string_char(ctx, string_rope_get(obj, idx)); } } else if (prop == JS_ATOM_length) { return JS_NewInt32(ctx, p1->len); } } break; default: break; } /* cannot raise an exception */ p = JS_VALUE_GET_OBJ(JS_GetPrototypePrimitive(ctx, obj)); if (!p) return JS_UNDEFINED; } else { p = JS_VALUE_GET_OBJ(obj); } for(;;) { prs = find_own_property(&pr, p, prop); if (prs) { /* found */ if (unlikely(prs->flags & JS_PROP_TMASK)) { if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) { if (unlikely(!pr->u.getset.getter)) { return JS_UNDEFINED; } else { JSValue func = JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.getter); /* Note: the field could be removed in the getter */ func = JS_DupValue(ctx, func); return JS_CallFree(ctx, func, this_obj, 0, NULL); } } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { JSValue val = *pr->u.var_ref->pvalue; if (unlikely(JS_IsUninitialized(val))) return JS_ThrowReferenceErrorUninitialized(ctx, prs->atom); return JS_DupValue(ctx, val); } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { /* Instantiate property and retry */ if (JS_AutoInitProperty(ctx, p, prop, pr, prs)) return JS_EXCEPTION; continue; } } else { return JS_DupValue(ctx, pr->u.value); } } if (unlikely(p->is_exotic)) { /* exotic behaviors */ if (p->fast_array) { if (__JS_AtomIsTaggedInt(prop)) { uint32_t idx = __JS_AtomToUInt32(prop); if (idx < p->u.array.count) { /* we avoid duplicating the code */ return JS_GetPropertyUint32(ctx, JS_MKPTR(JS_TAG_OBJECT, p), idx); } else if (p->class_id >= JS_CLASS_UINT8C_ARRAY && p->class_id <= JS_CLASS_FLOAT64_ARRAY) { return JS_UNDEFINED; } } else if (p->class_id >= JS_CLASS_UINT8C_ARRAY && p->class_id <= JS_CLASS_FLOAT64_ARRAY) { int ret; ret = JS_AtomIsNumericIndex(ctx, prop); if (ret != 0) { if (ret < 0) return JS_EXCEPTION; return JS_UNDEFINED; } } } else { const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; if (em) { if (em->get_property) { JSValue obj1, retval; /* XXX: should pass throw_ref_error */ /* Note: if 'p' is a prototype, it can be freed in the called function */ obj1 = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p)); retval = em->get_property(ctx, obj1, prop, this_obj); JS_FreeValue(ctx, obj1); return retval; } if (em->get_own_property) { JSPropertyDescriptor desc; int ret; JSValue obj1; /* Note: if 'p' is a prototype, it can be freed in the called function */ obj1 = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p)); ret = em->get_own_property(ctx, &desc, obj1, prop); JS_FreeValue(ctx, obj1); if (ret < 0) return JS_EXCEPTION; if (ret) { if (desc.flags & JS_PROP_GETSET) { JS_FreeValue(ctx, desc.setter); return JS_CallFree(ctx, desc.getter, this_obj, 0, NULL); } else { return desc.value; } } } } } } p = p->shape->proto; if (!p) break; } if (unlikely(throw_ref_error)) { return JS_ThrowReferenceErrorNotDefined(ctx, prop); } else { return JS_UNDEFINED; } } static JSValue JS_ThrowTypeErrorPrivateNotFound(JSContext *ctx, JSAtom atom) { return JS_ThrowTypeErrorAtom(ctx, "private class field '%s' does not exist", atom); } /* Private fields can be added even on non extensible objects or Proxies */ static int JS_DefinePrivateField(JSContext *ctx, JSValueConst obj, JSValueConst name, JSValue val) { JSObject *p; JSShapeProperty *prs; JSProperty *pr; JSAtom prop; if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) { JS_ThrowTypeErrorNotAnObject(ctx); goto fail; } /* safety check */ if (unlikely(JS_VALUE_GET_TAG(name) != JS_TAG_SYMBOL)) { JS_ThrowTypeErrorNotASymbol(ctx); goto fail; } prop = js_symbol_to_atom(ctx, (JSValue)name); p = JS_VALUE_GET_OBJ(obj); prs = find_own_property(&pr, p, prop); if (prs) { JS_ThrowTypeErrorAtom(ctx, "private class field '%s' already exists", prop); goto fail; } pr = add_property(ctx, p, prop, JS_PROP_C_W_E); if (unlikely(!pr)) { fail: JS_FreeValue(ctx, val); return -1; } pr->u.value = val; return 0; } static JSValue JS_GetPrivateField(JSContext *ctx, JSValueConst obj, JSValueConst name) { JSObject *p; JSShapeProperty *prs; JSProperty *pr; JSAtom prop; if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) return JS_ThrowTypeErrorNotAnObject(ctx); /* safety check */ if (unlikely(JS_VALUE_GET_TAG(name) != JS_TAG_SYMBOL)) return JS_ThrowTypeErrorNotASymbol(ctx); prop = js_symbol_to_atom(ctx, (JSValue)name); p = JS_VALUE_GET_OBJ(obj); prs = find_own_property(&pr, p, prop); if (!prs) { JS_ThrowTypeErrorPrivateNotFound(ctx, prop); return JS_EXCEPTION; } return JS_DupValue(ctx, pr->u.value); } static int JS_SetPrivateField(JSContext *ctx, JSValueConst obj, JSValueConst name, JSValue val) { JSObject *p; JSShapeProperty *prs; JSProperty *pr; JSAtom prop; if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) { JS_ThrowTypeErrorNotAnObject(ctx); goto fail; } /* safety check */ if (unlikely(JS_VALUE_GET_TAG(name) != JS_TAG_SYMBOL)) { JS_ThrowTypeErrorNotASymbol(ctx); goto fail; } prop = js_symbol_to_atom(ctx, (JSValue)name); p = JS_VALUE_GET_OBJ(obj); prs = find_own_property(&pr, p, prop); if (!prs) { JS_ThrowTypeErrorPrivateNotFound(ctx, prop); fail: JS_FreeValue(ctx, val); return -1; } set_value(ctx, &pr->u.value, val); return 0; } /* add a private brand field to 'home_obj' if not already present and if obj is != null add a private brand to it */ static int JS_AddBrand(JSContext *ctx, JSValueConst obj, JSValueConst home_obj) { JSObject *p, *p1; JSShapeProperty *prs; JSProperty *pr; JSValue brand; JSAtom brand_atom; if (unlikely(JS_VALUE_GET_TAG(home_obj) != JS_TAG_OBJECT)) { JS_ThrowTypeErrorNotAnObject(ctx); return -1; } p = JS_VALUE_GET_OBJ(home_obj); prs = find_own_property(&pr, p, JS_ATOM_Private_brand); if (!prs) { /* if the brand is not present, add it */ brand = JS_NewSymbolFromAtom(ctx, JS_ATOM_brand, JS_ATOM_TYPE_PRIVATE); if (JS_IsException(brand)) return -1; pr = add_property(ctx, p, JS_ATOM_Private_brand, JS_PROP_C_W_E); if (!pr) { JS_FreeValue(ctx, brand); return -1; } pr->u.value = JS_DupValue(ctx, brand); } else { brand = JS_DupValue(ctx, pr->u.value); } brand_atom = js_symbol_to_atom(ctx, brand); if (JS_IsObject(obj)) { p1 = JS_VALUE_GET_OBJ(obj); prs = find_own_property(&pr, p1, brand_atom); if (unlikely(prs)) { JS_FreeAtom(ctx, brand_atom); JS_ThrowTypeError(ctx, "private method is already present"); return -1; } pr = add_property(ctx, p1, brand_atom, JS_PROP_C_W_E); JS_FreeAtom(ctx, brand_atom); if (!pr) return -1; pr->u.value = JS_UNDEFINED; } else { JS_FreeAtom(ctx, brand_atom); } return 0; } /* return a boolean telling if the brand of the home object of 'func' is present on 'obj' or -1 in case of exception */ static int JS_CheckBrand(JSContext *ctx, JSValueConst obj, JSValueConst func) { JSObject *p, *p1, *home_obj; JSShapeProperty *prs; JSProperty *pr; JSValueConst brand; /* get the home object of 'func' */ if (unlikely(JS_VALUE_GET_TAG(func) != JS_TAG_OBJECT)) goto not_obj; p1 = JS_VALUE_GET_OBJ(func); if (!js_class_has_bytecode(p1->class_id)) goto not_obj; home_obj = p1->u.func.home_object; if (!home_obj) goto not_obj; prs = find_own_property(&pr, home_obj, JS_ATOM_Private_brand); if (!prs) { JS_ThrowTypeError(ctx, "expecting <brand> private field"); return -1; } brand = pr->u.value; /* safety check */ if (unlikely(JS_VALUE_GET_TAG(brand) != JS_TAG_SYMBOL)) goto not_obj; /* get the brand array of 'obj' */ if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) { not_obj: JS_ThrowTypeErrorNotAnObject(ctx); return -1; } p = JS_VALUE_GET_OBJ(obj); prs = find_own_property(&pr, p, js_symbol_to_atom(ctx, (JSValue)brand)); return (prs != NULL); } static uint32_t js_string_obj_get_length(JSContext *ctx, JSValueConst obj) { JSObject *p; uint32_t len = 0; /* This is a class exotic method: obj class_id is JS_CLASS_STRING */ p = JS_VALUE_GET_OBJ(obj); if (JS_VALUE_GET_TAG(p->u.object_data) == JS_TAG_STRING) { JSString *p1 = JS_VALUE_GET_STRING(p->u.object_data); len = p1->len; } return len; } static int num_keys_cmp(const void *p1, const void *p2, void *opaque) { JSContext *ctx = opaque; JSAtom atom1 = ((const JSPropertyEnum *)p1)->atom; JSAtom atom2 = ((const JSPropertyEnum *)p2)->atom; uint32_t v1, v2; BOOL atom1_is_integer, atom2_is_integer; atom1_is_integer = JS_AtomIsArrayIndex(ctx, &v1, atom1); atom2_is_integer = JS_AtomIsArrayIndex(ctx, &v2, atom2); assert(atom1_is_integer && atom2_is_integer); if (v1 < v2) return -1; else if (v1 == v2) return 0; else return 1; } void JS_FreePropertyEnum(JSContext *ctx, JSPropertyEnum *tab, uint32_t len) { uint32_t i; if (tab) { for(i = 0; i < len; i++) JS_FreeAtom(ctx, tab[i].atom); js_free(ctx, tab); } } /* return < 0 in case if exception, 0 if OK. ptab and its atoms must be freed by the user. */ static int __exception JS_GetOwnPropertyNamesInternal(JSContext *ctx, JSPropertyEnum **ptab, uint32_t *plen, JSObject *p, int flags) { int i, j; JSShape *sh; JSShapeProperty *prs; JSPropertyEnum *tab_atom, *tab_exotic; JSAtom atom; uint32_t num_keys_count, str_keys_count, sym_keys_count, atom_count; uint32_t num_index, str_index, sym_index, exotic_count, exotic_keys_count; BOOL is_enumerable, num_sorted; uint32_t num_key; JSAtomKindEnum kind; /* clear pointer for consistency in case of failure */ *ptab = NULL; *plen = 0; /* compute the number of returned properties */ num_keys_count = 0; str_keys_count = 0; sym_keys_count = 0; exotic_keys_count = 0; exotic_count = 0; tab_exotic = NULL; sh = p->shape; for(i = 0, prs = get_shape_prop(sh); i < sh->prop_count; i++, prs++) { atom = prs->atom; if (atom != JS_ATOM_NULL) { is_enumerable = ((prs->flags & JS_PROP_ENUMERABLE) != 0); kind = JS_AtomGetKind(ctx, atom); if ((!(flags & JS_GPN_ENUM_ONLY) || is_enumerable) && ((flags >> kind) & 1) != 0) { /* need to raise an exception in case of the module name space (implicit GetOwnProperty) */ if (unlikely((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) && (flags & (JS_GPN_SET_ENUM | JS_GPN_ENUM_ONLY))) { JSVarRef *var_ref = p->prop[i].u.var_ref; if (unlikely(JS_IsUninitialized(*var_ref->pvalue))) { JS_ThrowReferenceErrorUninitialized(ctx, prs->atom); return -1; } } if (JS_AtomIsArrayIndex(ctx, &num_key, atom)) { num_keys_count++; } else if (kind == JS_ATOM_KIND_STRING) { str_keys_count++; } else { sym_keys_count++; } } } } if (p->is_exotic) { if (p->fast_array) { if (flags & JS_GPN_STRING_MASK) { num_keys_count += p->u.array.count; } } else if (p->class_id == JS_CLASS_STRING) { if (flags & JS_GPN_STRING_MASK) { num_keys_count += js_string_obj_get_length(ctx, JS_MKPTR(JS_TAG_OBJECT, p)); } } else { const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; if (em && em->get_own_property_names) { if (em->get_own_property_names(ctx, &tab_exotic, &exotic_count, JS_MKPTR(JS_TAG_OBJECT, p))) return -1; for(i = 0; i < exotic_count; i++) { atom = tab_exotic[i].atom; kind = JS_AtomGetKind(ctx, atom); if (((flags >> kind) & 1) != 0) { is_enumerable = FALSE; if (flags & (JS_GPN_SET_ENUM | JS_GPN_ENUM_ONLY)) { JSPropertyDescriptor desc; int res; /* set the "is_enumerable" field if necessary */ res = JS_GetOwnPropertyInternal(ctx, &desc, p, atom); if (res < 0) { JS_FreePropertyEnum(ctx, tab_exotic, exotic_count); return -1; } if (res) { is_enumerable = ((desc.flags & JS_PROP_ENUMERABLE) != 0); js_free_desc(ctx, &desc); } tab_exotic[i].is_enumerable = is_enumerable; } if (!(flags & JS_GPN_ENUM_ONLY) || is_enumerable) { exotic_keys_count++; } } } } } } /* fill them */ atom_count = num_keys_count + str_keys_count; if (atom_count < str_keys_count) goto add_overflow; atom_count += sym_keys_count; if (atom_count < sym_keys_count) goto add_overflow; atom_count += exotic_keys_count; if (atom_count < exotic_keys_count || atom_count > INT32_MAX) { add_overflow: JS_ThrowOutOfMemory(ctx); JS_FreePropertyEnum(ctx, tab_exotic, exotic_count); return -1; } /* XXX: need generic way to test for js_malloc(ctx, a * b) overflow */ /* avoid allocating 0 bytes */ tab_atom = js_malloc(ctx, sizeof(tab_atom[0]) * max_int(atom_count, 1)); if (!tab_atom) { JS_FreePropertyEnum(ctx, tab_exotic, exotic_count); return -1; } num_index = 0; str_index = num_keys_count; sym_index = str_index + str_keys_count; num_sorted = TRUE; sh = p->shape; for(i = 0, prs = get_shape_prop(sh); i < sh->prop_count; i++, prs++) { atom = prs->atom; if (atom != JS_ATOM_NULL) { is_enumerable = ((prs->flags & JS_PROP_ENUMERABLE) != 0); kind = JS_AtomGetKind(ctx, atom); if ((!(flags & JS_GPN_ENUM_ONLY) || is_enumerable) && ((flags >> kind) & 1) != 0) { if (JS_AtomIsArrayIndex(ctx, &num_key, atom)) { j = num_index++; num_sorted = FALSE; } else if (kind == JS_ATOM_KIND_STRING) { j = str_index++; } else { j = sym_index++; } tab_atom[j].atom = JS_DupAtom(ctx, atom); tab_atom[j].is_enumerable = is_enumerable; } } } if (p->is_exotic) { int len; if (p->fast_array) { if (flags & JS_GPN_STRING_MASK) { len = p->u.array.count; goto add_array_keys; } } else if (p->class_id == JS_CLASS_STRING) { if (flags & JS_GPN_STRING_MASK) { len = js_string_obj_get_length(ctx, JS_MKPTR(JS_TAG_OBJECT, p)); add_array_keys: for(i = 0; i < len; i++) { tab_atom[num_index].atom = __JS_AtomFromUInt32(i); if (tab_atom[num_index].atom == JS_ATOM_NULL) { JS_FreePropertyEnum(ctx, tab_atom, num_index); return -1; } tab_atom[num_index].is_enumerable = TRUE; num_index++; } } } else { /* Note: exotic keys are not reordered and comes after the object own properties. */ for(i = 0; i < exotic_count; i++) { atom = tab_exotic[i].atom; is_enumerable = tab_exotic[i].is_enumerable; kind = JS_AtomGetKind(ctx, atom); if ((!(flags & JS_GPN_ENUM_ONLY) || is_enumerable) && ((flags >> kind) & 1) != 0) { tab_atom[sym_index].atom = atom; tab_atom[sym_index].is_enumerable = is_enumerable; sym_index++; } else { JS_FreeAtom(ctx, atom); } } js_free(ctx, tab_exotic); } } assert(num_index == num_keys_count); assert(str_index == num_keys_count + str_keys_count); assert(sym_index == atom_count); if (num_keys_count != 0 && !num_sorted) { rqsort(tab_atom, num_keys_count, sizeof(tab_atom[0]), num_keys_cmp, ctx); } *ptab = tab_atom; *plen = atom_count; return 0; } int JS_GetOwnPropertyNames(JSContext *ctx, JSPropertyEnum **ptab, uint32_t *plen, JSValueConst obj, int flags) { if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) { JS_ThrowTypeErrorNotAnObject(ctx); return -1; } return JS_GetOwnPropertyNamesInternal(ctx, ptab, plen, JS_VALUE_GET_OBJ(obj), flags); } /* Return -1 if exception, FALSE if the property does not exist, TRUE if it exists. If TRUE is returned, the property descriptor 'desc' is filled present. */ static int JS_GetOwnPropertyInternal(JSContext *ctx, JSPropertyDescriptor *desc, JSObject *p, JSAtom prop) { JSShapeProperty *prs; JSProperty *pr; retry: prs = find_own_property(&pr, p, prop); if (prs) { if (desc) { desc->flags = prs->flags & JS_PROP_C_W_E; desc->getter = JS_UNDEFINED; desc->setter = JS_UNDEFINED; desc->value = JS_UNDEFINED; if (unlikely(prs->flags & JS_PROP_TMASK)) { if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) { desc->flags |= JS_PROP_GETSET; if (pr->u.getset.getter) desc->getter = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.getter)); if (pr->u.getset.setter) desc->setter = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.setter)); } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { JSValue val = *pr->u.var_ref->pvalue; if (unlikely(JS_IsUninitialized(val))) { JS_ThrowReferenceErrorUninitialized(ctx, prs->atom); return -1; } desc->value = JS_DupValue(ctx, val); } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { /* Instantiate property and retry */ if (JS_AutoInitProperty(ctx, p, prop, pr, prs)) return -1; goto retry; } } else { desc->value = JS_DupValue(ctx, pr->u.value); } } else { /* for consistency, send the exception even if desc is NULL */ if (unlikely((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF)) { if (unlikely(JS_IsUninitialized(*pr->u.var_ref->pvalue))) { JS_ThrowReferenceErrorUninitialized(ctx, prs->atom); return -1; } } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { /* nothing to do: delay instantiation until actual value and/or attributes are read */ } } return TRUE; } if (p->is_exotic) { if (p->fast_array) { /* specific case for fast arrays */ if (__JS_AtomIsTaggedInt(prop)) { uint32_t idx; idx = __JS_AtomToUInt32(prop); if (idx < p->u.array.count) { if (desc) { desc->flags = JS_PROP_WRITABLE | JS_PROP_ENUMERABLE | JS_PROP_CONFIGURABLE; desc->getter = JS_UNDEFINED; desc->setter = JS_UNDEFINED; desc->value = JS_GetPropertyUint32(ctx, JS_MKPTR(JS_TAG_OBJECT, p), idx); } return TRUE; } } } else { const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; if (em && em->get_own_property) { return em->get_own_property(ctx, desc, JS_MKPTR(JS_TAG_OBJECT, p), prop); } } } return FALSE; } int JS_GetOwnProperty(JSContext *ctx, JSPropertyDescriptor *desc, JSValueConst obj, JSAtom prop) { if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) { JS_ThrowTypeErrorNotAnObject(ctx); return -1; } return JS_GetOwnPropertyInternal(ctx, desc, JS_VALUE_GET_OBJ(obj), prop); } /* return -1 if exception (exotic object only) or TRUE/FALSE */ int JS_IsExtensible(JSContext *ctx, JSValueConst obj) { JSObject *p; if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) return FALSE; p = JS_VALUE_GET_OBJ(obj); if (unlikely(p->is_exotic)) { const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; if (em && em->is_extensible) { return em->is_extensible(ctx, obj); } } return p->extensible; } /* return -1 if exception (exotic object only) or TRUE/FALSE */ int JS_PreventExtensions(JSContext *ctx, JSValueConst obj) { JSObject *p; if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) return FALSE; p = JS_VALUE_GET_OBJ(obj); if (unlikely(p->is_exotic)) { if (p->class_id >= JS_CLASS_UINT8C_ARRAY && p->class_id <= JS_CLASS_FLOAT64_ARRAY) { JSTypedArray *ta; JSArrayBuffer *abuf; /* resizable type arrays return FALSE */ ta = p->u.typed_array; abuf = ta->buffer->u.array_buffer; if (ta->track_rab || (array_buffer_is_resizable(abuf) && !abuf->shared)) return FALSE; } else { const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; if (em && em->prevent_extensions) { return em->prevent_extensions(ctx, obj); } } } p->extensible = FALSE; return TRUE; } /* return -1 if exception otherwise TRUE or FALSE */ int JS_HasProperty(JSContext *ctx, JSValueConst obj, JSAtom prop) { JSObject *p; int ret; JSValue obj1; if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) return FALSE; p = JS_VALUE_GET_OBJ(obj); for(;;) { if (p->is_exotic) { const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; if (em && em->has_property) { /* has_property can free the prototype */ obj1 = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p)); ret = em->has_property(ctx, obj1, prop); JS_FreeValue(ctx, obj1); return ret; } } /* JS_GetOwnPropertyInternal can free the prototype */ JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p)); ret = JS_GetOwnPropertyInternal(ctx, NULL, p, prop); JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p)); if (ret != 0) return ret; if (p->class_id >= JS_CLASS_UINT8C_ARRAY && p->class_id <= JS_CLASS_FLOAT64_ARRAY) { ret = JS_AtomIsNumericIndex(ctx, prop); if (ret != 0) { if (ret < 0) return -1; return FALSE; } } p = p->shape->proto; if (!p) break; } return FALSE; } /* val must be a symbol */ static JSAtom js_symbol_to_atom(JSContext *ctx, JSValue val) { JSAtomStruct *p = JS_VALUE_GET_PTR(val); return js_get_atom_index(ctx->rt, p); } /* return JS_ATOM_NULL in case of exception */ JSAtom JS_ValueToAtom(JSContext *ctx, JSValueConst val) { JSAtom atom; uint32_t tag; tag = JS_VALUE_GET_TAG(val); if (tag == JS_TAG_INT && (uint32_t)JS_VALUE_GET_INT(val) <= JS_ATOM_MAX_INT) { /* fast path for integer values */ atom = __JS_AtomFromUInt32(JS_VALUE_GET_INT(val)); } else if (tag == JS_TAG_SYMBOL) { JSAtomStruct *p = JS_VALUE_GET_PTR(val); atom = JS_DupAtom(ctx, js_get_atom_index(ctx->rt, p)); } else { JSValue str; str = JS_ToPropertyKey(ctx, val); if (JS_IsException(str)) return JS_ATOM_NULL; if (JS_VALUE_GET_TAG(str) == JS_TAG_SYMBOL) { atom = js_symbol_to_atom(ctx, str); } else { atom = JS_NewAtomStr(ctx, JS_VALUE_GET_STRING(str)); } } return atom; } static JSValue JS_GetPropertyValue(JSContext *ctx, JSValueConst this_obj, JSValue prop) { JSAtom atom; JSValue ret; if (likely(JS_VALUE_GET_TAG(this_obj) == JS_TAG_OBJECT && JS_VALUE_GET_TAG(prop) == JS_TAG_INT)) { JSObject *p; uint32_t idx; /* fast path for array access */ p = JS_VALUE_GET_OBJ(this_obj); idx = JS_VALUE_GET_INT(prop); switch(p->class_id) { case JS_CLASS_ARRAY: case JS_CLASS_ARGUMENTS: if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_DupValue(ctx, p->u.array.u.values[idx]); case JS_CLASS_MAPPED_ARGUMENTS: if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_DupValue(ctx, *p->u.array.u.var_refs[idx]->pvalue); case JS_CLASS_INT8_ARRAY: if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_NewInt32(ctx, p->u.array.u.int8_ptr[idx]); case JS_CLASS_UINT8C_ARRAY: case JS_CLASS_UINT8_ARRAY: if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_NewInt32(ctx, p->u.array.u.uint8_ptr[idx]); case JS_CLASS_INT16_ARRAY: if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_NewInt32(ctx, p->u.array.u.int16_ptr[idx]); case JS_CLASS_UINT16_ARRAY: if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_NewInt32(ctx, p->u.array.u.uint16_ptr[idx]); case JS_CLASS_INT32_ARRAY: if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_NewInt32(ctx, p->u.array.u.int32_ptr[idx]); case JS_CLASS_UINT32_ARRAY: if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_NewUint32(ctx, p->u.array.u.uint32_ptr[idx]); case JS_CLASS_BIG_INT64_ARRAY: if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_NewBigInt64(ctx, p->u.array.u.int64_ptr[idx]); case JS_CLASS_BIG_UINT64_ARRAY: if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_NewBigUint64(ctx, p->u.array.u.uint64_ptr[idx]); case JS_CLASS_FLOAT16_ARRAY: if (unlikely(idx >= p->u.array.count)) goto slow_path; return __JS_NewFloat64(ctx, fromfp16(p->u.array.u.fp16_ptr[idx])); case JS_CLASS_FLOAT32_ARRAY: if (unlikely(idx >= p->u.array.count)) goto slow_path; return __JS_NewFloat64(ctx, p->u.array.u.float_ptr[idx]); case JS_CLASS_FLOAT64_ARRAY: if (unlikely(idx >= p->u.array.count)) goto slow_path; return __JS_NewFloat64(ctx, p->u.array.u.double_ptr[idx]); default: goto slow_path; } } else { slow_path: /* ToObject() must be done before ToPropertyKey() */ if (JS_IsNull(this_obj) || JS_IsUndefined(this_obj)) { JS_FreeValue(ctx, prop); return JS_ThrowTypeError(ctx, "cannot read property of %s", JS_IsNull(this_obj) ? "null" : "undefined"); } atom = JS_ValueToAtom(ctx, prop); JS_FreeValue(ctx, prop); if (unlikely(atom == JS_ATOM_NULL)) return JS_EXCEPTION; ret = JS_GetProperty(ctx, this_obj, atom); JS_FreeAtom(ctx, atom); return ret; } } JSValue JS_GetPropertyUint32(JSContext *ctx, JSValueConst this_obj, uint32_t idx) { return JS_GetPropertyValue(ctx, this_obj, JS_NewUint32(ctx, idx)); } /* Check if an object has a generalized numeric property. Return value: -1 for exception, TRUE if property exists, stored into *pval, FALSE if proprty does not exist. */ static int JS_TryGetPropertyInt64(JSContext *ctx, JSValueConst obj, int64_t idx, JSValue *pval) { JSValue val = JS_UNDEFINED; JSAtom prop; int present; if (likely((uint64_t)idx <= JS_ATOM_MAX_INT)) { /* fast path */ present = JS_HasProperty(ctx, obj, __JS_AtomFromUInt32(idx)); if (present > 0) { val = JS_GetPropertyValue(ctx, obj, JS_NewInt32(ctx, idx)); if (unlikely(JS_IsException(val))) present = -1; } } else { prop = JS_NewAtomInt64(ctx, idx); present = -1; if (likely(prop != JS_ATOM_NULL)) { present = JS_HasProperty(ctx, obj, prop); if (present > 0) { val = JS_GetProperty(ctx, obj, prop); if (unlikely(JS_IsException(val))) present = -1; } JS_FreeAtom(ctx, prop); } } *pval = val; return present; } static JSValue JS_GetPropertyInt64(JSContext *ctx, JSValueConst obj, int64_t idx) { JSAtom prop; JSValue val; if ((uint64_t)idx <= INT32_MAX) { /* fast path for fast arrays */ return JS_GetPropertyValue(ctx, obj, JS_NewInt32(ctx, idx)); } prop = JS_NewAtomInt64(ctx, idx); if (prop == JS_ATOM_NULL) return JS_EXCEPTION; val = JS_GetProperty(ctx, obj, prop); JS_FreeAtom(ctx, prop); return val; } JSValue JS_GetPropertyStr(JSContext *ctx, JSValueConst this_obj, const char *prop) { JSAtom atom; JSValue ret; atom = JS_NewAtom(ctx, prop); if (atom == JS_ATOM_NULL) return JS_EXCEPTION; ret = JS_GetProperty(ctx, this_obj, atom); JS_FreeAtom(ctx, atom); return ret; } /* Note: the property value is not initialized. Return NULL if memory error. */ static JSProperty *add_property(JSContext *ctx, JSObject *p, JSAtom prop, int prop_flags) { JSShape *sh, *new_sh; if (unlikely(__JS_AtomIsTaggedInt(prop))) { /* update is_std_array_prototype */ if (unlikely(p->is_std_array_prototype)) { p->is_std_array_prototype = FALSE; } else if (unlikely(p->has_immutable_prototype)) { struct list_head *el; /* modifying Object.prototype : reset the corresponding is_std_array_prototype */ list_for_each(el, &ctx->rt->context_list) { JSContext *ctx1 = list_entry(el, JSContext, link); if (JS_IsObject(ctx1->class_proto[JS_CLASS_OBJECT]) && JS_VALUE_GET_OBJ(ctx1->class_proto[JS_CLASS_OBJECT]) == p) { if (JS_IsObject(ctx1->class_proto[JS_CLASS_ARRAY])) { JSObject *p1 = JS_VALUE_GET_OBJ(ctx1->class_proto[JS_CLASS_ARRAY]); p1->is_std_array_prototype = FALSE; } break; } } } } sh = p->shape; if (sh->is_hashed) { /* try to find an existing shape */ new_sh = find_hashed_shape_prop(ctx->rt, sh, prop, prop_flags); if (new_sh) { /* matching shape found: use it */ /* the property array may need to be resized */ if (new_sh->prop_size != sh->prop_size) { JSProperty *new_prop; new_prop = js_realloc(ctx, p->prop, sizeof(p->prop[0]) * new_sh->prop_size); if (!new_prop) return NULL; p->prop = new_prop; } p->shape = js_dup_shape(new_sh); js_free_shape(ctx->rt, sh); return &p->prop[new_sh->prop_count - 1]; } else if (sh->header.ref_count != 1) { /* if the shape is shared, clone it */ new_sh = js_clone_shape(ctx, sh); if (!new_sh) return NULL; /* hash the cloned shape */ new_sh->is_hashed = TRUE; js_shape_hash_link(ctx->rt, new_sh); js_free_shape(ctx->rt, p->shape); p->shape = new_sh; } } assert(p->shape->header.ref_count == 1); if (add_shape_property(ctx, &p->shape, p, prop, prop_flags)) return NULL; return &p->prop[p->shape->prop_count - 1]; } /* can be called on JS_CLASS_ARRAY, JS_CLASS_ARGUMENTS or JS_CLASS_MAPPED_ARGUMENTS objects. return < 0 if memory alloc error. */ static no_inline __exception int convert_fast_array_to_array(JSContext *ctx, JSObject *p) { JSProperty *pr; JSShape *sh; uint32_t i, len, new_count; if (js_shape_prepare_update(ctx, p, NULL)) return -1; len = p->u.array.count; /* resize the properties once to simplify the error handling */ sh = p->shape; new_count = sh->prop_count + len; if (new_count > sh->prop_size) { if (resize_properties(ctx, &p->shape, p, new_count)) return -1; } if (p->class_id == JS_CLASS_MAPPED_ARGUMENTS) { JSVarRef **tab = p->u.array.u.var_refs; for(i = 0; i < len; i++) { /* add_property cannot fail here but __JS_AtomFromUInt32(i) fails for i > INT32_MAX */ pr = add_property(ctx, p, __JS_AtomFromUInt32(i), JS_PROP_C_W_E | JS_PROP_VARREF); pr->u.var_ref = *tab++; } } else { JSValue *tab = p->u.array.u.values; for(i = 0; i < len; i++) { /* add_property cannot fail here but __JS_AtomFromUInt32(i) fails for i > INT32_MAX */ pr = add_property(ctx, p, __JS_AtomFromUInt32(i), JS_PROP_C_W_E); pr->u.value = *tab++; } } js_free(ctx, p->u.array.u.values); p->u.array.count = 0; p->u.array.u.values = NULL; /* fail safe */ p->u.array.u1.size = 0; p->fast_array = 0; p->is_std_array_prototype = FALSE; return 0; } static int remove_global_object_property(JSContext *ctx, JSObject *p, JSShapeProperty *prs, JSProperty *pr) { JSVarRef *var_ref; JSObject *p1; JSProperty *pr1; var_ref = pr->u.var_ref; if (var_ref->header.ref_count == 1) return 0; p1 = JS_VALUE_GET_OBJ(p->u.global_object.uninitialized_vars); pr1 = add_property(ctx, p1, prs->atom, JS_PROP_C_W_E | JS_PROP_VARREF); if (!pr1) return -1; pr1->u.var_ref = var_ref; var_ref->header.ref_count++; JS_FreeValue(ctx, var_ref->value); var_ref->is_lexical = FALSE; var_ref->is_const = FALSE; var_ref->value = JS_UNINITIALIZED; return 0; } static int delete_property(JSContext *ctx, JSObject *p, JSAtom atom) { JSShape *sh; JSShapeProperty *pr, *lpr, *prop; JSProperty *pr1; uint32_t lpr_idx; intptr_t h, h1; redo: sh = p->shape; h1 = atom & sh->prop_hash_mask; h = prop_hash_end(sh)[-h1 - 1]; prop = get_shape_prop(sh); lpr = NULL; lpr_idx = 0; /* prevent warning */ while (h != 0) { pr = &prop[h - 1]; if (likely(pr->atom == atom)) { /* found ! */ if (!(pr->flags & JS_PROP_CONFIGURABLE)) return FALSE; /* realloc the shape if needed */ if (lpr) lpr_idx = lpr - get_shape_prop(sh); if (js_shape_prepare_update(ctx, p, &pr)) return -1; sh = p->shape; /* remove property */ if (lpr) { lpr = get_shape_prop(sh) + lpr_idx; lpr->hash_next = pr->hash_next; } else { prop_hash_end(sh)[-h1 - 1] = pr->hash_next; } sh->deleted_prop_count++; /* free the entry */ pr1 = &p->prop[h - 1]; if (unlikely(p->class_id == JS_CLASS_GLOBAL_OBJECT)) { if ((pr->flags & JS_PROP_TMASK) == JS_PROP_VARREF) if (remove_global_object_property(ctx, p, pr, pr1)) return -1; } free_property(ctx->rt, pr1, pr->flags); JS_FreeAtom(ctx, pr->atom); /* put default values */ pr->flags = 0; pr->atom = JS_ATOM_NULL; pr1->u.value = JS_UNDEFINED; /* compact the properties if too many deleted properties */ if (sh->deleted_prop_count >= 8 && sh->deleted_prop_count >= ((unsigned)sh->prop_count / 2)) { compact_properties(ctx, p); } return TRUE; } lpr = pr; h = pr->hash_next; } if (p->is_exotic) { if (p->fast_array) { uint32_t idx; if (JS_AtomIsArrayIndex(ctx, &idx, atom) && idx < p->u.array.count) { if (p->class_id == JS_CLASS_ARRAY || p->class_id == JS_CLASS_ARGUMENTS || p->class_id == JS_CLASS_MAPPED_ARGUMENTS) { /* Special case deleting the last element of a fast Array */ if (idx == p->u.array.count - 1) { if (p->class_id == JS_CLASS_MAPPED_ARGUMENTS) { free_var_ref(ctx->rt, p->u.array.u.var_refs[idx]); } else { JS_FreeValue(ctx, p->u.array.u.values[idx]); } p->u.array.count = idx; return TRUE; } if (convert_fast_array_to_array(ctx, p)) return -1; goto redo; } else { return FALSE; } } } else { const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; if (em && em->delete_property) { return em->delete_property(ctx, JS_MKPTR(JS_TAG_OBJECT, p), atom); } } } /* not found */ return TRUE; } static int call_setter(JSContext *ctx, JSObject *setter, JSValueConst this_obj, JSValue val, int flags) { JSValue ret, func; if (likely(setter)) { func = JS_MKPTR(JS_TAG_OBJECT, setter); /* Note: the field could be removed in the setter */ func = JS_DupValue(ctx, func); ret = JS_CallFree(ctx, func, this_obj, 1, (JSValueConst *)&val); JS_FreeValue(ctx, val); if (JS_IsException(ret)) return -1; JS_FreeValue(ctx, ret); return TRUE; } else { JS_FreeValue(ctx, val); if ((flags & JS_PROP_THROW) || ((flags & JS_PROP_THROW_STRICT) && is_strict_mode(ctx))) { JS_ThrowTypeError(ctx, "no setter for property"); return -1; } return FALSE; } } /* set the array length and remove the array elements if necessary. */ static int set_array_length(JSContext *ctx, JSObject *p, JSValue val, int flags) { uint32_t len, idx, cur_len; int i, ret; /* Note: this call can reallocate the properties of 'p' */ ret = JS_ToArrayLengthFree(ctx, &len, val, FALSE); if (ret) return -1; /* JS_ToArrayLengthFree() must be done before the read-only test */ if (unlikely(!(p->shape->prop[0].flags & JS_PROP_WRITABLE))) return JS_ThrowTypeErrorReadOnly(ctx, flags, JS_ATOM_length); if (likely(p->fast_array)) { uint32_t old_len = p->u.array.count; if (len < old_len) { for(i = len; i < old_len; i++) { JS_FreeValue(ctx, p->u.array.u.values[i]); } p->u.array.count = len; } p->prop[0].u.value = JS_NewUint32(ctx, len); } else { /* Note: length is always a uint32 because the object is an array */ JS_ToUint32(ctx, &cur_len, p->prop[0].u.value); if (len < cur_len) { uint32_t d; JSShape *sh; JSShapeProperty *pr; d = cur_len - len; sh = p->shape; if (d <= sh->prop_count) { JSAtom atom; /* faster to iterate */ while (cur_len > len) { atom = JS_NewAtomUInt32(ctx, cur_len - 1); ret = delete_property(ctx, p, atom); JS_FreeAtom(ctx, atom); if (unlikely(!ret)) { /* unlikely case: property is not configurable */ break; } cur_len--; } } else { /* faster to iterate thru all the properties. Need two passes in case one of the property is not configurable */ cur_len = len; for(i = 0, pr = get_shape_prop(sh); i < sh->prop_count; i++, pr++) { if (pr->atom != JS_ATOM_NULL && JS_AtomIsArrayIndex(ctx, &idx, pr->atom)) { if (idx >= cur_len && !(pr->flags & JS_PROP_CONFIGURABLE)) { cur_len = idx + 1; } } } for(i = 0, pr = get_shape_prop(sh); i < sh->prop_count; i++, pr++) { if (pr->atom != JS_ATOM_NULL && JS_AtomIsArrayIndex(ctx, &idx, pr->atom)) { if (idx >= cur_len) { /* remove the property */ delete_property(ctx, p, pr->atom); /* WARNING: the shape may have been modified */ sh = p->shape; pr = get_shape_prop(sh) + i; } } } } } else { cur_len = len; } set_value(ctx, &p->prop[0].u.value, JS_NewUint32(ctx, cur_len)); if (unlikely(cur_len > len)) { return JS_ThrowTypeErrorOrFalse(ctx, flags, "not configurable"); } } return TRUE; } /* return -1 if exception */ static int expand_fast_array(JSContext *ctx, JSObject *p, uint32_t new_len) { uint32_t new_size; size_t slack; JSValue *new_array_prop; /* XXX: potential arithmetic overflow */ new_size = max_int(new_len, p->u.array.u1.size * 3 / 2); new_array_prop = js_realloc2(ctx, p->u.array.u.values, sizeof(JSValue) * new_size, &slack); if (!new_array_prop) return -1; new_size += slack / sizeof(*new_array_prop); p->u.array.u.values = new_array_prop; p->u.array.u1.size = new_size; return 0; } /* Preconditions: 'p' must be of class JS_CLASS_ARRAY, p->fast_array = TRUE and p->extensible = TRUE */ static inline int add_fast_array_element(JSContext *ctx, JSObject *p, JSValue val, int flags) { uint32_t new_len, array_len; /* extend the array by one */ /* XXX: convert to slow array if new_len > 2^31-1 elements */ new_len = p->u.array.count + 1; /* update the length if necessary. We assume that if the length is not an integer, then if it >= 2^31. */ if (likely(JS_VALUE_GET_TAG(p->prop[0].u.value) == JS_TAG_INT)) { array_len = JS_VALUE_GET_INT(p->prop[0].u.value); if (new_len > array_len) { if (unlikely(!(get_shape_prop(p->shape)->flags & JS_PROP_WRITABLE))) { JS_FreeValue(ctx, val); return JS_ThrowTypeErrorReadOnly(ctx, flags, JS_ATOM_length); } p->prop[0].u.value = JS_NewInt32(ctx, new_len); } } if (unlikely(new_len > p->u.array.u1.size)) { if (expand_fast_array(ctx, p, new_len)) { JS_FreeValue(ctx, val); return -1; } } p->u.array.u.values[new_len - 1] = val; p->u.array.count = new_len; return TRUE; } /* Allocate a new fast array initialized to JS_UNDEFINED. Its maximum size is 2^31-1 elements. For convenience, 'len' is a 64 bit integer. */ static JSValue js_allocate_fast_array(JSContext *ctx, int64_t len) { JSValue arr; JSObject *p; int i; if (len > INT32_MAX) return JS_ThrowRangeError(ctx, "invalid array length"); arr = JS_NewArray(ctx); if (JS_IsException(arr)) return arr; if (len > 0) { p = JS_VALUE_GET_OBJ(arr); if (expand_fast_array(ctx, p, len) < 0) { JS_FreeValue(ctx, arr); return JS_EXCEPTION; } p->u.array.count = len; for(i = 0; i < len; i++) p->u.array.u.values[i] = JS_UNDEFINED; /* update the 'length' field */ set_value(ctx, &p->prop[0].u.value, JS_NewInt32(ctx, len)); } return arr; } static JSValue js_create_array(JSContext *ctx, int len, JSValueConst *tab) { JSValue obj; JSObject *p; int i; obj = JS_NewArray(ctx); if (JS_IsException(obj)) return JS_EXCEPTION; if (len > 0) { p = JS_VALUE_GET_OBJ(obj); if (expand_fast_array(ctx, p, len) < 0) { JS_FreeValue(ctx, obj); return JS_EXCEPTION; } p->u.array.count = len; for(i = 0; i < len; i++) p->u.array.u.values[i] = JS_DupValue(ctx, tab[i]); /* update the 'length' field */ set_value(ctx, &p->prop[0].u.value, JS_NewInt32(ctx, len)); } return obj; } static JSValue js_create_array_free(JSContext *ctx, int len, JSValue *tab) { JSValue obj; JSObject *p; int i; obj = JS_NewArray(ctx); if (JS_IsException(obj)) goto fail; if (len > 0) { p = JS_VALUE_GET_OBJ(obj); if (expand_fast_array(ctx, p, len) < 0) { JS_FreeValue(ctx, obj); fail: for(i = 0; i < len; i++) JS_FreeValue(ctx, tab[i]); return JS_EXCEPTION; } p->u.array.count = len; for(i = 0; i < len; i++) p->u.array.u.values[i] = tab[i]; /* update the 'length' field */ set_value(ctx, &p->prop[0].u.value, JS_NewInt32(ctx, len)); } return obj; } static void js_free_desc(JSContext *ctx, JSPropertyDescriptor *desc) { JS_FreeValue(ctx, desc->getter); JS_FreeValue(ctx, desc->setter); JS_FreeValue(ctx, desc->value); } /* return -1 in case of exception or TRUE or FALSE. Warning: 'val' is freed by the function. 'flags' is a bitmask of JS_PROP_THROW and JS_PROP_THROW_STRICT. 'this_obj' is the receiver. If obj != this_obj, then obj must be an object (Reflect.set case). */ int JS_SetPropertyInternal(JSContext *ctx, JSValueConst obj, JSAtom prop, JSValue val, JSValueConst this_obj, int flags) { JSObject *p, *p1; JSShapeProperty *prs; JSProperty *pr; uint32_t tag; JSPropertyDescriptor desc; int ret; #if 0 printf("JS_SetPropertyInternal: "); print_atom(ctx, prop); printf("\n"); #endif tag = JS_VALUE_GET_TAG(this_obj); if (unlikely(tag != JS_TAG_OBJECT)) { if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { p = NULL; p1 = JS_VALUE_GET_OBJ(obj); goto prototype_lookup; } else { switch(tag) { case JS_TAG_NULL: JS_FreeValue(ctx, val); JS_ThrowTypeErrorAtom(ctx, "cannot set property '%s' of null", prop); return -1; case JS_TAG_UNDEFINED: JS_FreeValue(ctx, val); JS_ThrowTypeErrorAtom(ctx, "cannot set property '%s' of undefined", prop); return -1; default: /* even on a primitive type we can have setters on the prototype */ p = NULL; p1 = JS_VALUE_GET_OBJ(JS_GetPrototypePrimitive(ctx, obj)); goto prototype_lookup; } } } else { p = JS_VALUE_GET_OBJ(this_obj); p1 = JS_VALUE_GET_OBJ(obj); if (unlikely(p != p1)) goto retry2; } /* fast path if obj == this_obj */ retry: prs = find_own_property(&pr, p1, prop); if (prs) { if (likely((prs->flags & (JS_PROP_TMASK | JS_PROP_WRITABLE | JS_PROP_LENGTH)) == JS_PROP_WRITABLE)) { /* fast case */ set_value(ctx, &pr->u.value, val); return TRUE; } else if (prs->flags & JS_PROP_LENGTH) { assert(p->class_id == JS_CLASS_ARRAY); assert(prop == JS_ATOM_length); return set_array_length(ctx, p, val, flags); } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) { return call_setter(ctx, pr->u.getset.setter, this_obj, val, flags); } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { /* XXX: already use var_ref->is_const. Cannot simplify use the writable flag for JS_CLASS_MODULE_NS. */ if (p->class_id == JS_CLASS_MODULE_NS || pr->u.var_ref->is_const) goto read_only_prop; set_value(ctx, pr->u.var_ref->pvalue, val); return TRUE; } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { /* Instantiate property and retry (potentially useless) */ if (JS_AutoInitProperty(ctx, p, prop, pr, prs)) { JS_FreeValue(ctx, val); return -1; } goto retry; } else { goto read_only_prop; } } for(;;) { if (p1->is_exotic) { if (p1->fast_array) { if (__JS_AtomIsTaggedInt(prop)) { uint32_t idx = __JS_AtomToUInt32(prop); if (idx < p1->u.array.count) { if (unlikely(p == p1)) return JS_SetPropertyValue(ctx, this_obj, JS_NewInt32(ctx, idx), val, flags); else break; } else if (p1->class_id >= JS_CLASS_UINT8C_ARRAY && p1->class_id <= JS_CLASS_FLOAT64_ARRAY) { goto typed_array_oob; } } else if (p1->class_id >= JS_CLASS_UINT8C_ARRAY && p1->class_id <= JS_CLASS_FLOAT64_ARRAY) { ret = JS_AtomIsNumericIndex(ctx, prop); if (ret != 0) { if (ret < 0) { JS_FreeValue(ctx, val); return -1; } typed_array_oob: if (p == p1) { /* must convert the argument even if out of bound access */ if (p1->class_id == JS_CLASS_BIG_INT64_ARRAY || p1->class_id == JS_CLASS_BIG_UINT64_ARRAY) { int64_t v; if (JS_ToBigInt64Free(ctx, &v, val)) return -1; } else { val = JS_ToNumberFree(ctx, val); JS_FreeValue(ctx, val); if (JS_IsException(val)) return -1; } } else { JS_FreeValue(ctx, val); } return TRUE; } } } else { const JSClassExoticMethods *em = ctx->rt->class_array[p1->class_id].exotic; if (em) { JSValue obj1; if (em->set_property) { /* set_property can free the prototype */ obj1 = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p1)); ret = em->set_property(ctx, obj1, prop, val, this_obj, flags); JS_FreeValue(ctx, obj1); JS_FreeValue(ctx, val); return ret; } if (em->get_own_property) { /* get_own_property can free the prototype */ obj1 = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p1)); ret = em->get_own_property(ctx, &desc, obj1, prop); JS_FreeValue(ctx, obj1); if (ret < 0) { JS_FreeValue(ctx, val); return ret; } if (ret) { if (desc.flags & JS_PROP_GETSET) { JSObject *setter; if (JS_IsUndefined(desc.setter)) setter = NULL; else setter = JS_VALUE_GET_OBJ(desc.setter); ret = call_setter(ctx, setter, this_obj, val, flags); JS_FreeValue(ctx, desc.getter); JS_FreeValue(ctx, desc.setter); return ret; } else { JS_FreeValue(ctx, desc.value); if (!(desc.flags & JS_PROP_WRITABLE)) goto read_only_prop; if (likely(p == p1)) { ret = JS_DefineProperty(ctx, this_obj, prop, val, JS_UNDEFINED, JS_UNDEFINED, JS_PROP_HAS_VALUE); JS_FreeValue(ctx, val); return ret; } else { break; } } } } } } } p1 = p1->shape->proto; prototype_lookup: if (!p1) break; retry2: prs = find_own_property(&pr, p1, prop); if (prs) { if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) { return call_setter(ctx, pr->u.getset.setter, this_obj, val, flags); } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { /* Instantiate property and retry (potentially useless) */ if (JS_AutoInitProperty(ctx, p1, prop, pr, prs)) return -1; goto retry2; } else if (!(prs->flags & JS_PROP_WRITABLE)) { goto read_only_prop; } else { break; } } } if (unlikely(!p)) { JS_FreeValue(ctx, val); return JS_ThrowTypeErrorOrFalse(ctx, flags, "not an object"); } if (unlikely(!p->extensible)) { JS_FreeValue(ctx, val); return JS_ThrowTypeErrorOrFalse(ctx, flags, "object is not extensible"); } if (likely(p == JS_VALUE_GET_OBJ(obj))) { if (p->is_exotic) { if (p->class_id == JS_CLASS_ARRAY && p->fast_array && __JS_AtomIsTaggedInt(prop)) { uint32_t idx = __JS_AtomToUInt32(prop); if (idx == p->u.array.count) { /* fast case */ return add_fast_array_element(ctx, p, val, flags); } else { goto generic_create_prop; } } else { goto generic_create_prop; } } else { if (unlikely(p->class_id == JS_CLASS_GLOBAL_OBJECT)) goto generic_create_prop; pr = add_property(ctx, p, prop, JS_PROP_C_W_E); if (unlikely(!pr)) { JS_FreeValue(ctx, val); return -1; } pr->u.value = val; return TRUE; } } else { /* generic case: modify the property in this_obj if it already exists */ ret = JS_GetOwnPropertyInternal(ctx, &desc, p, prop); if (ret < 0) { JS_FreeValue(ctx, val); return ret; } if (ret) { if (desc.flags & JS_PROP_GETSET) { JS_FreeValue(ctx, desc.getter); JS_FreeValue(ctx, desc.setter); JS_FreeValue(ctx, val); return JS_ThrowTypeErrorOrFalse(ctx, flags, "setter is forbidden"); } else { JS_FreeValue(ctx, desc.value); if (!(desc.flags & JS_PROP_WRITABLE) || p->class_id == JS_CLASS_MODULE_NS) { read_only_prop: JS_FreeValue(ctx, val); return JS_ThrowTypeErrorReadOnly(ctx, flags, prop); } } ret = JS_DefineProperty(ctx, this_obj, prop, val, JS_UNDEFINED, JS_UNDEFINED, JS_PROP_HAS_VALUE); JS_FreeValue(ctx, val); return ret; } else { generic_create_prop: ret = JS_CreateProperty(ctx, p, prop, val, JS_UNDEFINED, JS_UNDEFINED, flags | JS_PROP_HAS_VALUE | JS_PROP_HAS_ENUMERABLE | JS_PROP_HAS_WRITABLE | JS_PROP_HAS_CONFIGURABLE | JS_PROP_C_W_E); JS_FreeValue(ctx, val); return ret; } } } /* return true if an element can be added to a fast array without further tests */ static force_inline BOOL can_extend_fast_array(JSObject *p) { JSObject *proto; if (!p->extensible) return FALSE; proto = p->shape->proto; if (!proto) return TRUE; return proto->is_std_array_prototype; } /* flags can be JS_PROP_THROW or JS_PROP_THROW_STRICT */ static int JS_SetPropertyValue(JSContext *ctx, JSValueConst this_obj, JSValue prop, JSValue val, int flags) { if (likely(JS_VALUE_GET_TAG(this_obj) == JS_TAG_OBJECT && JS_VALUE_GET_TAG(prop) == JS_TAG_INT)) { JSObject *p; uint32_t idx; double d; int32_t v; /* fast path for array access */ p = JS_VALUE_GET_OBJ(this_obj); idx = JS_VALUE_GET_INT(prop); switch(p->class_id) { case JS_CLASS_ARRAY: if (unlikely(idx >= (uint32_t)p->u.array.count)) { /* fast path to add an element to the array */ if (unlikely(idx != (uint32_t)p->u.array.count || !p->fast_array || !can_extend_fast_array(p))) { goto slow_path; } /* add element */ return add_fast_array_element(ctx, p, val, flags); } set_value(ctx, &p->u.array.u.values[idx], val); break; case JS_CLASS_ARGUMENTS: if (unlikely(idx >= (uint32_t)p->u.array.count)) goto slow_path; set_value(ctx, &p->u.array.u.values[idx], val); break; case JS_CLASS_MAPPED_ARGUMENTS: if (unlikely(idx >= (uint32_t)p->u.array.count)) goto slow_path; set_value(ctx, p->u.array.u.var_refs[idx]->pvalue, val); break; case JS_CLASS_UINT8C_ARRAY: if (JS_ToUint8ClampFree(ctx, &v, val)) return -1; /* Note: the conversion can detach the typed array, so the array bound check must be done after */ if (unlikely(idx >= (uint32_t)p->u.array.count)) goto ta_out_of_bound; p->u.array.u.uint8_ptr[idx] = v; break; case JS_CLASS_INT8_ARRAY: case JS_CLASS_UINT8_ARRAY: if (JS_ToInt32Free(ctx, &v, val)) return -1; if (unlikely(idx >= (uint32_t)p->u.array.count)) goto ta_out_of_bound; p->u.array.u.uint8_ptr[idx] = v; break; case JS_CLASS_INT16_ARRAY: case JS_CLASS_UINT16_ARRAY: if (JS_ToInt32Free(ctx, &v, val)) return -1; if (unlikely(idx >= (uint32_t)p->u.array.count)) goto ta_out_of_bound; p->u.array.u.uint16_ptr[idx] = v; break; case JS_CLASS_INT32_ARRAY: case JS_CLASS_UINT32_ARRAY: if (JS_ToInt32Free(ctx, &v, val)) return -1; if (unlikely(idx >= (uint32_t)p->u.array.count)) goto ta_out_of_bound; p->u.array.u.uint32_ptr[idx] = v; break; case JS_CLASS_BIG_INT64_ARRAY: case JS_CLASS_BIG_UINT64_ARRAY: /* XXX: need specific conversion function */ { int64_t v; if (JS_ToBigInt64Free(ctx, &v, val)) return -1; if (unlikely(idx >= (uint32_t)p->u.array.count)) goto ta_out_of_bound; p->u.array.u.uint64_ptr[idx] = v; } break; case JS_CLASS_FLOAT16_ARRAY: if (JS_ToFloat64Free(ctx, &d, val)) return -1; if (unlikely(idx >= (uint32_t)p->u.array.count)) goto ta_out_of_bound; p->u.array.u.fp16_ptr[idx] = tofp16(d); break; case JS_CLASS_FLOAT32_ARRAY: if (JS_ToFloat64Free(ctx, &d, val)) return -1; if (unlikely(idx >= (uint32_t)p->u.array.count)) goto ta_out_of_bound; p->u.array.u.float_ptr[idx] = d; break; case JS_CLASS_FLOAT64_ARRAY: if (JS_ToFloat64Free(ctx, &d, val)) return -1; if (unlikely(idx >= (uint32_t)p->u.array.count)) { ta_out_of_bound: return TRUE; } p->u.array.u.double_ptr[idx] = d; break; default: goto slow_path; } return TRUE; } else { JSAtom atom; int ret; slow_path: atom = JS_ValueToAtom(ctx, prop); JS_FreeValue(ctx, prop); if (unlikely(atom == JS_ATOM_NULL)) { JS_FreeValue(ctx, val); return -1; } ret = JS_SetPropertyInternal(ctx, this_obj, atom, val, this_obj, flags); JS_FreeAtom(ctx, atom); return ret; } } int JS_SetPropertyUint32(JSContext *ctx, JSValueConst this_obj, uint32_t idx, JSValue val) { return JS_SetPropertyValue(ctx, this_obj, JS_NewUint32(ctx, idx), val, JS_PROP_THROW); } int JS_SetPropertyInt64(JSContext *ctx, JSValueConst this_obj, int64_t idx, JSValue val) { JSAtom prop; int res; if ((uint64_t)idx <= INT32_MAX) { /* fast path for fast arrays */ return JS_SetPropertyValue(ctx, this_obj, JS_NewInt32(ctx, idx), val, JS_PROP_THROW); } prop = JS_NewAtomInt64(ctx, idx); if (prop == JS_ATOM_NULL) { JS_FreeValue(ctx, val); return -1; } res = JS_SetProperty(ctx, this_obj, prop, val); JS_FreeAtom(ctx, prop); return res; } int JS_SetPropertyStr(JSContext *ctx, JSValueConst this_obj, const char *prop, JSValue val) { JSAtom atom; int ret; atom = JS_NewAtom(ctx, prop); if (atom == JS_ATOM_NULL) { JS_FreeValue(ctx, val); return -1; } ret = JS_SetPropertyInternal(ctx, this_obj, atom, val, this_obj, JS_PROP_THROW); JS_FreeAtom(ctx, atom); return ret; } /* compute the property flags. For each flag: (JS_PROP_HAS_x forces it, otherwise def_flags is used) Note: makes assumption about the bit pattern of the flags */ static int get_prop_flags(int flags, int def_flags) { int mask; mask = (flags >> JS_PROP_HAS_SHIFT) & JS_PROP_C_W_E; return (flags & mask) | (def_flags & ~mask); } static int JS_CreateProperty(JSContext *ctx, JSObject *p, JSAtom prop, JSValueConst val, JSValueConst getter, JSValueConst setter, int flags) { JSProperty *pr; int ret, prop_flags; JSVarRef *var_ref; JSObject *delete_obj; /* add a new property or modify an existing exotic one */ if (p->is_exotic) { if (p->class_id == JS_CLASS_ARRAY) { uint32_t idx, len; if (p->fast_array) { if (__JS_AtomIsTaggedInt(prop)) { idx = __JS_AtomToUInt32(prop); if (idx == p->u.array.count) { if (!p->extensible) goto not_extensible; if (flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) goto convert_to_array; prop_flags = get_prop_flags(flags, 0); if (prop_flags != JS_PROP_C_W_E) goto convert_to_array; return add_fast_array_element(ctx, p, JS_DupValue(ctx, val), flags); } else { goto convert_to_array; } } else if (JS_AtomIsArrayIndex(ctx, &idx, prop)) { /* convert the fast array to normal array */ convert_to_array: if (convert_fast_array_to_array(ctx, p)) return -1; goto generic_array; } } else if (JS_AtomIsArrayIndex(ctx, &idx, prop)) { JSProperty *plen; JSShapeProperty *pslen; generic_array: /* update the length field */ plen = &p->prop[0]; JS_ToUint32(ctx, &len, plen->u.value); if ((idx + 1) > len) { pslen = get_shape_prop(p->shape); if (unlikely(!(pslen->flags & JS_PROP_WRITABLE))) return JS_ThrowTypeErrorReadOnly(ctx, flags, JS_ATOM_length); /* XXX: should update the length after defining the property */ len = idx + 1; set_value(ctx, &plen->u.value, JS_NewUint32(ctx, len)); } } } else if (p->class_id >= JS_CLASS_UINT8C_ARRAY && p->class_id <= JS_CLASS_FLOAT64_ARRAY) { ret = JS_AtomIsNumericIndex(ctx, prop); if (ret != 0) { if (ret < 0) return -1; return JS_ThrowTypeErrorOrFalse(ctx, flags, "cannot create numeric index in typed array"); } } else if (!(flags & JS_PROP_NO_EXOTIC)) { const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; if (em) { if (em->define_own_property) { return em->define_own_property(ctx, JS_MKPTR(JS_TAG_OBJECT, p), prop, val, getter, setter, flags); } ret = JS_IsExtensible(ctx, JS_MKPTR(JS_TAG_OBJECT, p)); if (ret < 0) return -1; if (!ret) goto not_extensible; } } } if (!p->extensible) { not_extensible: return JS_ThrowTypeErrorOrFalse(ctx, flags, "object is not extensible"); } var_ref = NULL; delete_obj = NULL; if (flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) { prop_flags = (flags & (JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE)) | JS_PROP_GETSET; } else { prop_flags = flags & JS_PROP_C_W_E; if (p->class_id == JS_CLASS_GLOBAL_OBJECT) { JSObject *p1 = JS_VALUE_GET_OBJ(p->u.global_object.uninitialized_vars); JSShapeProperty *prs1; JSProperty *pr1; prs1 = find_own_property(&pr1, p1, prop); if (prs1) { delete_obj = p1; var_ref = pr1->u.var_ref; var_ref->header.ref_count++; } else { var_ref = js_create_var_ref(ctx, FALSE); if (!var_ref) return -1; } var_ref->is_const = !(prop_flags & JS_PROP_WRITABLE); prop_flags |= JS_PROP_VARREF; } } pr = add_property(ctx, p, prop, prop_flags); if (unlikely(!pr)) { if (var_ref) free_var_ref(ctx->rt, var_ref); return -1; } if (flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) { pr->u.getset.getter = NULL; if ((flags & JS_PROP_HAS_GET) && JS_IsFunction(ctx, getter)) { pr->u.getset.getter = JS_VALUE_GET_OBJ(JS_DupValue(ctx, getter)); } pr->u.getset.setter = NULL; if ((flags & JS_PROP_HAS_SET) && JS_IsFunction(ctx, setter)) { pr->u.getset.setter = JS_VALUE_GET_OBJ(JS_DupValue(ctx, setter)); } } else if (p->class_id == JS_CLASS_GLOBAL_OBJECT) { if (delete_obj) delete_property(ctx, delete_obj, prop); pr->u.var_ref = var_ref; if (flags & JS_PROP_HAS_VALUE) { *var_ref->pvalue = JS_DupValue(ctx, val); } else { *var_ref->pvalue = JS_UNDEFINED; } } else { if (flags & JS_PROP_HAS_VALUE) { pr->u.value = JS_DupValue(ctx, val); } else { pr->u.value = JS_UNDEFINED; } } return TRUE; } /* return FALSE if not OK */ static BOOL check_define_prop_flags(int prop_flags, int flags) { BOOL has_accessor, is_getset; if (!(prop_flags & JS_PROP_CONFIGURABLE)) { if ((flags & (JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE)) == (JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE)) { return FALSE; } if ((flags & JS_PROP_HAS_ENUMERABLE) && (flags & JS_PROP_ENUMERABLE) != (prop_flags & JS_PROP_ENUMERABLE)) return FALSE; if (flags & (JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE | JS_PROP_HAS_GET | JS_PROP_HAS_SET)) { has_accessor = ((flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) != 0); is_getset = ((prop_flags & JS_PROP_TMASK) == JS_PROP_GETSET); if (has_accessor != is_getset) return FALSE; if (!is_getset && !(prop_flags & JS_PROP_WRITABLE)) { /* not writable: cannot set the writable bit */ if ((flags & (JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE)) == (JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE)) return FALSE; } } } return TRUE; } /* ensure that the shape can be safely modified */ static int js_shape_prepare_update(JSContext *ctx, JSObject *p, JSShapeProperty **pprs) { JSShape *sh; uint32_t idx = 0; /* prevent warning */ sh = p->shape; if (sh->is_hashed) { if (sh->header.ref_count != 1) { if (pprs) idx = *pprs - get_shape_prop(sh); /* clone the shape (the resulting one is no longer hashed) */ sh = js_clone_shape(ctx, sh); if (!sh) return -1; js_free_shape(ctx->rt, p->shape); p->shape = sh; if (pprs) *pprs = get_shape_prop(sh) + idx; } else { js_shape_hash_unlink(ctx->rt, sh); sh->is_hashed = FALSE; } } return 0; } static int js_update_property_flags(JSContext *ctx, JSObject *p, JSShapeProperty **pprs, int flags) { if (flags != (*pprs)->flags) { if (js_shape_prepare_update(ctx, p, pprs)) return -1; (*pprs)->flags = flags; } return 0; } /* allowed flags: JS_PROP_CONFIGURABLE, JS_PROP_WRITABLE, JS_PROP_ENUMERABLE JS_PROP_HAS_GET, JS_PROP_HAS_SET, JS_PROP_HAS_VALUE, JS_PROP_HAS_CONFIGURABLE, JS_PROP_HAS_WRITABLE, JS_PROP_HAS_ENUMERABLE, JS_PROP_THROW, JS_PROP_NO_EXOTIC. If JS_PROP_THROW is set, return an exception instead of FALSE. if JS_PROP_NO_EXOTIC is set, do not call the exotic define_own_property callback. return -1 (exception), FALSE or TRUE. */ int JS_DefineProperty(JSContext *ctx, JSValueConst this_obj, JSAtom prop, JSValueConst val, JSValueConst getter, JSValueConst setter, int flags) { JSObject *p; JSShapeProperty *prs; JSProperty *pr; int mask, res; if (JS_VALUE_GET_TAG(this_obj) != JS_TAG_OBJECT) { JS_ThrowTypeErrorNotAnObject(ctx); return -1; } p = JS_VALUE_GET_OBJ(this_obj); redo_prop_update: prs = find_own_property(&pr, p, prop); if (prs) { /* the range of the Array length property is always tested before */ if ((prs->flags & JS_PROP_LENGTH) && (flags & JS_PROP_HAS_VALUE)) { uint32_t array_length; if (JS_ToArrayLengthFree(ctx, &array_length, JS_DupValue(ctx, val), FALSE)) { return -1; } /* this code relies on the fact that Uint32 are never allocated */ val = (JSValueConst)JS_NewUint32(ctx, array_length); /* prs may have been modified */ prs = find_own_property(&pr, p, prop); assert(prs != NULL); } /* property already exists */ if (!check_define_prop_flags(prs->flags, flags)) { not_configurable: return JS_ThrowTypeErrorOrFalse(ctx, flags, "property is not configurable"); } if ((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { /* Instantiate property and retry */ if (JS_AutoInitProperty(ctx, p, prop, pr, prs)) return -1; goto redo_prop_update; } if (flags & (JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE | JS_PROP_HAS_GET | JS_PROP_HAS_SET)) { if (flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) { JSObject *new_getter, *new_setter; if (JS_IsFunction(ctx, getter)) { new_getter = JS_VALUE_GET_OBJ(getter); } else { new_getter = NULL; } if (JS_IsFunction(ctx, setter)) { new_setter = JS_VALUE_GET_OBJ(setter); } else { new_setter = NULL; } if ((prs->flags & JS_PROP_TMASK) != JS_PROP_GETSET) { if (js_shape_prepare_update(ctx, p, &prs)) return -1; /* convert to getset */ if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { if (unlikely(p->class_id == JS_CLASS_GLOBAL_OBJECT)) { if (remove_global_object_property(ctx, p, prs, pr)) return -1; } free_var_ref(ctx->rt, pr->u.var_ref); } else { JS_FreeValue(ctx, pr->u.value); } prs->flags = (prs->flags & (JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE)) | JS_PROP_GETSET; pr->u.getset.getter = NULL; pr->u.getset.setter = NULL; } else { if (!(prs->flags & JS_PROP_CONFIGURABLE)) { if ((flags & JS_PROP_HAS_GET) && new_getter != pr->u.getset.getter) { goto not_configurable; } if ((flags & JS_PROP_HAS_SET) && new_setter != pr->u.getset.setter) { goto not_configurable; } } } if (flags & JS_PROP_HAS_GET) { if (pr->u.getset.getter) JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.getter)); if (new_getter) JS_DupValue(ctx, getter); pr->u.getset.getter = new_getter; } if (flags & JS_PROP_HAS_SET) { if (pr->u.getset.setter) JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.setter)); if (new_setter) JS_DupValue(ctx, setter); pr->u.getset.setter = new_setter; } } else { if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) { /* convert to data descriptor */ JSVarRef *var_ref; if (unlikely(p->class_id == JS_CLASS_GLOBAL_OBJECT)) { var_ref = js_global_object_find_uninitialized_var(ctx, p, prop, FALSE); if (!var_ref) return -1; } else { var_ref = NULL; } if (js_shape_prepare_update(ctx, p, &prs)) { if (var_ref) free_var_ref(ctx->rt, var_ref); return -1; } if (pr->u.getset.getter) JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.getter)); if (pr->u.getset.setter) JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.setter)); if (var_ref) { prs->flags = (prs->flags & ~JS_PROP_TMASK) | JS_PROP_VARREF | JS_PROP_WRITABLE; pr->u.var_ref = var_ref; } else { prs->flags &= ~(JS_PROP_TMASK | JS_PROP_WRITABLE); pr->u.value = JS_UNDEFINED; } } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { /* Note: JS_PROP_VARREF is always writable */ } else { if ((prs->flags & (JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE)) == 0 && (flags & JS_PROP_HAS_VALUE)) { if (!js_same_value(ctx, val, pr->u.value)) { goto not_configurable; } else { return TRUE; } } } if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { if (flags & JS_PROP_HAS_VALUE) { if (p->class_id == JS_CLASS_MODULE_NS) { /* JS_PROP_WRITABLE is always true for variable references, but they are write protected in module name spaces. */ if (!js_same_value(ctx, val, *pr->u.var_ref->pvalue)) goto not_configurable; } else { /* update the reference */ set_value(ctx, pr->u.var_ref->pvalue, JS_DupValue(ctx, val)); } } if ((flags & (JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE)) == JS_PROP_HAS_WRITABLE) { JSValue val1; if (p->class_id == JS_CLASS_MODULE_NS) { return JS_ThrowTypeErrorOrFalse(ctx, flags, "module namespace properties have writable = false"); } if (js_shape_prepare_update(ctx, p, &prs)) return -1; if (p->class_id == JS_CLASS_GLOBAL_OBJECT) { pr->u.var_ref->is_const = TRUE; /* mark as read-only */ prs->flags &= ~JS_PROP_WRITABLE; } else { /* if writable is set to false, no longer a reference (for mapped arguments) */ val1 = JS_DupValue(ctx, *pr->u.var_ref->pvalue); free_var_ref(ctx->rt, pr->u.var_ref); pr->u.value = val1; prs->flags &= ~(JS_PROP_TMASK | JS_PROP_WRITABLE); } } } else if (prs->flags & JS_PROP_LENGTH) { if (flags & JS_PROP_HAS_VALUE) { /* Note: no JS code is executable because 'val' is guaranted to be a Uint32 */ res = set_array_length(ctx, p, JS_DupValue(ctx, val), flags); } else { res = TRUE; } /* still need to reset the writable flag if needed. The JS_PROP_LENGTH is kept because the Uint32 test is still done if the length property is read-only. */ if ((flags & (JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE)) == JS_PROP_HAS_WRITABLE) { prs = get_shape_prop(p->shape); if (js_update_property_flags(ctx, p, &prs, prs->flags & ~JS_PROP_WRITABLE)) return -1; } return res; } else { if (flags & JS_PROP_HAS_VALUE) { JS_FreeValue(ctx, pr->u.value); pr->u.value = JS_DupValue(ctx, val); } if (flags & JS_PROP_HAS_WRITABLE) { if (js_update_property_flags(ctx, p, &prs, (prs->flags & ~JS_PROP_WRITABLE) | (flags & JS_PROP_WRITABLE))) return -1; } } } } mask = 0; if (flags & JS_PROP_HAS_CONFIGURABLE) mask |= JS_PROP_CONFIGURABLE; if (flags & JS_PROP_HAS_ENUMERABLE) mask |= JS_PROP_ENUMERABLE; if (js_update_property_flags(ctx, p, &prs, (prs->flags & ~mask) | (flags & mask))) return -1; return TRUE; } /* handle modification of fast array elements */ if (p->fast_array) { uint32_t idx; uint32_t prop_flags; if (p->class_id == JS_CLASS_ARRAY) { if (__JS_AtomIsTaggedInt(prop)) { idx = __JS_AtomToUInt32(prop); if (idx < p->u.array.count) { prop_flags = get_prop_flags(flags, JS_PROP_C_W_E); if (prop_flags != JS_PROP_C_W_E) goto convert_to_slow_array; if (flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) { convert_to_slow_array: if (convert_fast_array_to_array(ctx, p)) return -1; else goto redo_prop_update; } if (flags & JS_PROP_HAS_VALUE) { set_value(ctx, &p->u.array.u.values[idx], JS_DupValue(ctx, val)); } return TRUE; } } } else if (p->class_id >= JS_CLASS_UINT8C_ARRAY && p->class_id <= JS_CLASS_FLOAT64_ARRAY) { JSValue num; int ret; if (!__JS_AtomIsTaggedInt(prop)) { /* slow path with to handle all numeric indexes */ num = JS_AtomIsNumericIndex1(ctx, prop); if (JS_IsUndefined(num)) goto typed_array_done; if (JS_IsException(num)) return -1; ret = JS_NumberIsInteger(ctx, num); if (ret < 0) { JS_FreeValue(ctx, num); return -1; } if (!ret) { JS_FreeValue(ctx, num); return JS_ThrowTypeErrorOrFalse(ctx, flags, "non integer index in typed array"); } ret = JS_NumberIsNegativeOrMinusZero(ctx, num); JS_FreeValue(ctx, num); if (ret) { return JS_ThrowTypeErrorOrFalse(ctx, flags, "negative index in typed array"); } if (!__JS_AtomIsTaggedInt(prop)) goto typed_array_oob; } idx = __JS_AtomToUInt32(prop); /* if the typed array is detached, p->u.array.count = 0 */ if (idx >= p->u.array.count) { typed_array_oob: return JS_ThrowTypeErrorOrFalse(ctx, flags, "out-of-bound index in typed array"); } prop_flags = get_prop_flags(flags, JS_PROP_ENUMERABLE | JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); if (flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET) || prop_flags != (JS_PROP_ENUMERABLE | JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE)) { return JS_ThrowTypeErrorOrFalse(ctx, flags, "invalid descriptor flags"); } if (flags & JS_PROP_HAS_VALUE) { return JS_SetPropertyValue(ctx, this_obj, JS_NewInt32(ctx, idx), JS_DupValue(ctx, val), flags); } return TRUE; typed_array_done: ; } } return JS_CreateProperty(ctx, p, prop, val, getter, setter, flags); } static int JS_DefineAutoInitProperty(JSContext *ctx, JSValueConst this_obj, JSAtom prop, JSAutoInitIDEnum id, void *opaque, int flags) { JSObject *p; JSProperty *pr; if (JS_VALUE_GET_TAG(this_obj) != JS_TAG_OBJECT) return FALSE; p = JS_VALUE_GET_OBJ(this_obj); if (find_own_property(&pr, p, prop)) { /* property already exists */ abort(); return FALSE; } /* Specialized CreateProperty */ pr = add_property(ctx, p, prop, (flags & JS_PROP_C_W_E) | JS_PROP_AUTOINIT); if (unlikely(!pr)) return -1; pr->u.init.realm_and_id = (uintptr_t)JS_DupContext(ctx); assert((pr->u.init.realm_and_id & 3) == 0); assert(id <= 3); pr->u.init.realm_and_id |= id; pr->u.init.opaque = opaque; return TRUE; } /* shortcut to add or redefine a new property value */ int JS_DefinePropertyValue(JSContext *ctx, JSValueConst this_obj, JSAtom prop, JSValue val, int flags) { int ret; ret = JS_DefineProperty(ctx, this_obj, prop, val, JS_UNDEFINED, JS_UNDEFINED, flags | JS_PROP_HAS_VALUE | JS_PROP_HAS_CONFIGURABLE | JS_PROP_HAS_WRITABLE | JS_PROP_HAS_ENUMERABLE); JS_FreeValue(ctx, val); return ret; } int JS_DefinePropertyValueValue(JSContext *ctx, JSValueConst this_obj, JSValue prop, JSValue val, int flags) { JSAtom atom; int ret; atom = JS_ValueToAtom(ctx, prop); JS_FreeValue(ctx, prop); if (unlikely(atom == JS_ATOM_NULL)) { JS_FreeValue(ctx, val); return -1; } ret = JS_DefinePropertyValue(ctx, this_obj, atom, val, flags); JS_FreeAtom(ctx, atom); return ret; } int JS_DefinePropertyValueUint32(JSContext *ctx, JSValueConst this_obj, uint32_t idx, JSValue val, int flags) { return JS_DefinePropertyValueValue(ctx, this_obj, JS_NewUint32(ctx, idx), val, flags); } int JS_DefinePropertyValueInt64(JSContext *ctx, JSValueConst this_obj, int64_t idx, JSValue val, int flags) { return JS_DefinePropertyValueValue(ctx, this_obj, JS_NewInt64(ctx, idx), val, flags); } int JS_DefinePropertyValueStr(JSContext *ctx, JSValueConst this_obj, const char *prop, JSValue val, int flags) { JSAtom atom; int ret; atom = JS_NewAtom(ctx, prop); if (atom == JS_ATOM_NULL) { JS_FreeValue(ctx, val); return -1; } ret = JS_DefinePropertyValue(ctx, this_obj, atom, val, flags); JS_FreeAtom(ctx, atom); return ret; } /* shortcut to add getter & setter */ int JS_DefinePropertyGetSet(JSContext *ctx, JSValueConst this_obj, JSAtom prop, JSValue getter, JSValue setter, int flags) { int ret; ret = JS_DefineProperty(ctx, this_obj, prop, JS_UNDEFINED, getter, setter, flags | JS_PROP_HAS_GET | JS_PROP_HAS_SET | JS_PROP_HAS_CONFIGURABLE | JS_PROP_HAS_ENUMERABLE); JS_FreeValue(ctx, getter); JS_FreeValue(ctx, setter); return ret; } static int JS_CreateDataPropertyUint32(JSContext *ctx, JSValueConst this_obj, int64_t idx, JSValue val, int flags) { return JS_DefinePropertyValueValue(ctx, this_obj, JS_NewInt64(ctx, idx), val, flags | JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE | JS_PROP_WRITABLE); } /* return TRUE if 'obj' has a non empty 'name' string */ static BOOL js_object_has_name(JSContext *ctx, JSValueConst obj) { JSProperty *pr; JSShapeProperty *prs; JSValueConst val; JSString *p; prs = find_own_property(&pr, JS_VALUE_GET_OBJ(obj), JS_ATOM_name); if (!prs) return FALSE; if ((prs->flags & JS_PROP_TMASK) != JS_PROP_NORMAL) return TRUE; val = pr->u.value; if (JS_VALUE_GET_TAG(val) != JS_TAG_STRING) return TRUE; p = JS_VALUE_GET_STRING(val); return (p->len != 0); } static int JS_DefineObjectName(JSContext *ctx, JSValueConst obj, JSAtom name, int flags) { if (name != JS_ATOM_NULL && JS_IsObject(obj) && !js_object_has_name(ctx, obj) && JS_DefinePropertyValue(ctx, obj, JS_ATOM_name, JS_AtomToString(ctx, name), flags) < 0) { return -1; } return 0; } static int JS_DefineObjectNameComputed(JSContext *ctx, JSValueConst obj, JSValueConst str, int flags) { if (JS_IsObject(obj) && !js_object_has_name(ctx, obj)) { JSAtom prop; JSValue name_str; prop = JS_ValueToAtom(ctx, str); if (prop == JS_ATOM_NULL) return -1; name_str = js_get_function_name(ctx, prop); JS_FreeAtom(ctx, prop); if (JS_IsException(name_str)) return -1; if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_name, name_str, flags) < 0) return -1; } return 0; } #define DEFINE_GLOBAL_LEX_VAR (1 << 7) #define DEFINE_GLOBAL_FUNC_VAR (1 << 6) static JSValue JS_ThrowSyntaxErrorVarRedeclaration(JSContext *ctx, JSAtom prop) { return JS_ThrowSyntaxErrorAtom(ctx, "redeclaration of '%s'", prop); } /* flags is 0, DEFINE_GLOBAL_LEX_VAR or DEFINE_GLOBAL_FUNC_VAR */ /* XXX: could support exotic global object. */ static int JS_CheckDefineGlobalVar(JSContext *ctx, JSAtom prop, int flags) { JSObject *p; JSShapeProperty *prs; p = JS_VALUE_GET_OBJ(ctx->global_obj); prs = find_own_property1(p, prop); /* XXX: should handle JS_PROP_AUTOINIT */ if (flags & DEFINE_GLOBAL_LEX_VAR) { if (prs && !(prs->flags & JS_PROP_CONFIGURABLE)) goto fail_redeclaration; } else { if (!prs && !p->extensible) goto define_error; if (flags & DEFINE_GLOBAL_FUNC_VAR) { if (prs) { if (!(prs->flags & JS_PROP_CONFIGURABLE) && ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET || ((prs->flags & (JS_PROP_WRITABLE | JS_PROP_ENUMERABLE)) != (JS_PROP_WRITABLE | JS_PROP_ENUMERABLE)))) { define_error: JS_ThrowTypeErrorAtom(ctx, "cannot define variable '%s'", prop); return -1; } } } } /* check if there already is a lexical declaration */ p = JS_VALUE_GET_OBJ(ctx->global_var_obj); prs = find_own_property1(p, prop); if (prs) { fail_redeclaration: JS_ThrowSyntaxErrorVarRedeclaration(ctx, prop); return -1; } return 0; } /* construct a reference to a global variable */ static int JS_GetGlobalVarRef(JSContext *ctx, JSAtom prop, JSValue *sp) { JSObject *p; JSShapeProperty *prs; JSProperty *pr; /* no exotic behavior is possible in global_var_obj */ p = JS_VALUE_GET_OBJ(ctx->global_var_obj); prs = find_own_property(&pr, p, prop); if (prs) { /* XXX: conformance: do these tests in OP_put_var_ref/OP_get_var_ref ? */ if (unlikely(JS_IsUninitialized(*pr->u.var_ref->pvalue))) { JS_ThrowReferenceErrorUninitialized(ctx, prs->atom); return -1; } if (unlikely(!(prs->flags & JS_PROP_WRITABLE))) { return JS_ThrowTypeErrorReadOnly(ctx, JS_PROP_THROW, prop); } sp[0] = JS_DupValue(ctx, ctx->global_var_obj); } else { int ret; ret = JS_HasProperty(ctx, ctx->global_obj, prop); if (ret < 0) return -1; if (ret) { sp[0] = JS_DupValue(ctx, ctx->global_obj); } else { sp[0] = JS_UNDEFINED; } } sp[1] = JS_AtomToValue(ctx, prop); return 0; } /* return -1, FALSE or TRUE */ static int JS_DeleteGlobalVar(JSContext *ctx, JSAtom prop) { JSObject *p; JSShapeProperty *prs; JSProperty *pr; int ret; /* 9.1.1.4.7 DeleteBinding ( N ) */ p = JS_VALUE_GET_OBJ(ctx->global_var_obj); prs = find_own_property(&pr, p, prop); if (prs) return FALSE; /* lexical variables cannot be deleted */ ret = JS_HasProperty(ctx, ctx->global_obj, prop); if (ret < 0) return -1; if (ret) { return JS_DeleteProperty(ctx, ctx->global_obj, prop, 0); } else { return TRUE; } } /* return -1, FALSE or TRUE. return FALSE if not configurable or invalid object. return -1 in case of exception. flags can be 0, JS_PROP_THROW or JS_PROP_THROW_STRICT */ int JS_DeleteProperty(JSContext *ctx, JSValueConst obj, JSAtom prop, int flags) { JSValue obj1; JSObject *p; int res; obj1 = JS_ToObject(ctx, obj); if (JS_IsException(obj1)) return -1; p = JS_VALUE_GET_OBJ(obj1); res = delete_property(ctx, p, prop); JS_FreeValue(ctx, obj1); if (res != FALSE) return res; if ((flags & JS_PROP_THROW) || ((flags & JS_PROP_THROW_STRICT) && is_strict_mode(ctx))) { JS_ThrowTypeError(ctx, "could not delete property"); return -1; } return FALSE; } int JS_DeletePropertyInt64(JSContext *ctx, JSValueConst obj, int64_t idx, int flags) { JSAtom prop; int res; if ((uint64_t)idx <= JS_ATOM_MAX_INT) { /* fast path for fast arrays */ return JS_DeleteProperty(ctx, obj, __JS_AtomFromUInt32(idx), flags); } prop = JS_NewAtomInt64(ctx, idx); if (prop == JS_ATOM_NULL) return -1; res = JS_DeleteProperty(ctx, obj, prop, flags); JS_FreeAtom(ctx, prop); return res; } BOOL JS_IsFunction(JSContext *ctx, JSValueConst val) { JSObject *p; if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) return FALSE; p = JS_VALUE_GET_OBJ(val); switch(p->class_id) { case JS_CLASS_BYTECODE_FUNCTION: return TRUE; case JS_CLASS_PROXY: return p->u.proxy_data->is_func; default: return (ctx->rt->class_array[p->class_id].call != NULL); } } BOOL JS_IsCFunction(JSContext *ctx, JSValueConst val, JSCFunction *func, int magic) { JSObject *p; if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) return FALSE; p = JS_VALUE_GET_OBJ(val); if (p->class_id == JS_CLASS_C_FUNCTION) return (p->u.cfunc.c_function.generic == func && p->u.cfunc.magic == magic); else return FALSE; } BOOL JS_IsConstructor(JSContext *ctx, JSValueConst val) { JSObject *p; if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) return FALSE; p = JS_VALUE_GET_OBJ(val); return p->is_constructor; } BOOL JS_SetConstructorBit(JSContext *ctx, JSValueConst func_obj, BOOL val) { JSObject *p; if (JS_VALUE_GET_TAG(func_obj) != JS_TAG_OBJECT) return FALSE; p = JS_VALUE_GET_OBJ(func_obj); p->is_constructor = val; return TRUE; } BOOL JS_IsError(JSContext *ctx, JSValueConst val) { JSObject *p; if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) return FALSE; p = JS_VALUE_GET_OBJ(val); return (p->class_id == JS_CLASS_ERROR); } /* must be called after JS_Throw() */ void JS_SetUncatchableException(JSContext *ctx, BOOL flag) { ctx->rt->current_exception_is_uncatchable = flag; } void JS_SetOpaque(JSValue obj, void *opaque) { JSObject *p; if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { p = JS_VALUE_GET_OBJ(obj); p->u.opaque = opaque; } } /* return NULL if not an object of class class_id */ void *JS_GetOpaque(JSValueConst obj, JSClassID class_id) { JSObject *p; if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) return NULL; p = JS_VALUE_GET_OBJ(obj); if (p->class_id != class_id) return NULL; return p->u.opaque; } void *JS_GetOpaque2(JSContext *ctx, JSValueConst obj, JSClassID class_id) { void *p = JS_GetOpaque(obj, class_id); if (unlikely(!p)) { JS_ThrowTypeErrorInvalidClass(ctx, class_id); } return p; } void *JS_GetAnyOpaque(JSValueConst obj, JSClassID *class_id) { JSObject *p; if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) { *class_id = 0; return NULL; } p = JS_VALUE_GET_OBJ(obj); *class_id = p->class_id; return p->u.opaque; } static JSValue JS_ToPrimitiveFree(JSContext *ctx, JSValue val, int hint) { int i; BOOL force_ordinary; JSAtom method_name; JSValue method, ret; if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) return val; force_ordinary = hint & HINT_FORCE_ORDINARY; hint &= ~HINT_FORCE_ORDINARY; if (!force_ordinary) { method = JS_GetProperty(ctx, val, JS_ATOM_Symbol_toPrimitive); if (JS_IsException(method)) goto exception; /* ECMA says *If exoticToPrim is not undefined* but tests in test262 use null as a non callable converter */ if (!JS_IsUndefined(method) && !JS_IsNull(method)) { JSAtom atom; JSValue arg; switch(hint) { case HINT_STRING: atom = JS_ATOM_string; break; case HINT_NUMBER: atom = JS_ATOM_number; break; default: case HINT_NONE: atom = JS_ATOM_default; break; } arg = JS_AtomToString(ctx, atom); ret = JS_CallFree(ctx, method, val, 1, (JSValueConst *)&arg); JS_FreeValue(ctx, arg); if (JS_IsException(ret)) goto exception; JS_FreeValue(ctx, val); if (JS_VALUE_GET_TAG(ret) != JS_TAG_OBJECT) return ret; JS_FreeValue(ctx, ret); return JS_ThrowTypeError(ctx, "toPrimitive"); } } if (hint != HINT_STRING) hint = HINT_NUMBER; for(i = 0; i < 2; i++) { if ((i ^ hint) == 0) { method_name = JS_ATOM_toString; } else { method_name = JS_ATOM_valueOf; } method = JS_GetProperty(ctx, val, method_name); if (JS_IsException(method)) goto exception; if (JS_IsFunction(ctx, method)) { ret = JS_CallFree(ctx, method, val, 0, NULL); if (JS_IsException(ret)) goto exception; if (JS_VALUE_GET_TAG(ret) != JS_TAG_OBJECT) { JS_FreeValue(ctx, val); return ret; } JS_FreeValue(ctx, ret); } else { JS_FreeValue(ctx, method); } } JS_ThrowTypeError(ctx, "toPrimitive"); exception: JS_FreeValue(ctx, val); return JS_EXCEPTION; } static JSValue JS_ToPrimitive(JSContext *ctx, JSValueConst val, int hint) { return JS_ToPrimitiveFree(ctx, JS_DupValue(ctx, val), hint); } void JS_SetIsHTMLDDA(JSContext *ctx, JSValueConst obj) { JSObject *p; if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) return; p = JS_VALUE_GET_OBJ(obj); p->is_HTMLDDA = TRUE; } static inline BOOL JS_IsHTMLDDA(JSContext *ctx, JSValueConst obj) { JSObject *p; if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) return FALSE; p = JS_VALUE_GET_OBJ(obj); return p->is_HTMLDDA; } static int JS_ToBoolFree(JSContext *ctx, JSValue val) { uint32_t tag = JS_VALUE_GET_TAG(val); switch(tag) { case JS_TAG_INT: return JS_VALUE_GET_INT(val) != 0; case JS_TAG_BOOL: case JS_TAG_NULL: case JS_TAG_UNDEFINED: return JS_VALUE_GET_INT(val); case JS_TAG_EXCEPTION: return -1; case JS_TAG_STRING: { BOOL ret = JS_VALUE_GET_STRING(val)->len != 0; JS_FreeValue(ctx, val); return ret; } case JS_TAG_STRING_ROPE: { BOOL ret = JS_VALUE_GET_STRING_ROPE(val)->len != 0; JS_FreeValue(ctx, val); return ret; } case JS_TAG_SHORT_BIG_INT: return JS_VALUE_GET_SHORT_BIG_INT(val) != 0; case JS_TAG_BIG_INT: { JSBigInt *p = JS_VALUE_GET_PTR(val); BOOL ret; int i; /* fail safe: we assume it is not necessarily normalized. Beginning from the MSB ensures that the test is fast. */ ret = FALSE; for(i = p->len - 1; i >= 0; i--) { if (p->tab[i] != 0) { ret = TRUE; break; } } JS_FreeValue(ctx, val); return ret; } case JS_TAG_OBJECT: { JSObject *p = JS_VALUE_GET_OBJ(val); BOOL ret; ret = !p->is_HTMLDDA; JS_FreeValue(ctx, val); return ret; } break; default: if (JS_TAG_IS_FLOAT64(tag)) { double d = JS_VALUE_GET_FLOAT64(val); return !isnan(d) && d != 0; } else { JS_FreeValue(ctx, val); return TRUE; } } } int JS_ToBool(JSContext *ctx, JSValueConst val) { return JS_ToBoolFree(ctx, JS_DupValue(ctx, val)); } static int skip_spaces(const char *pc) { const uint8_t *p, *p_next, *p_start; uint32_t c; p = p_start = (const uint8_t *)pc; for (;;) { c = *p; if (c < 128) { if (!((c >= 0x09 && c <= 0x0d) || (c == 0x20))) break; p++; } else { c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p_next); if (!lre_is_space(c)) break; p = p_next; } } return p - p_start; } static inline int to_digit(int c) { if (c >= '0' && c <= '9') return c - '0'; else if (c >= 'A' && c <= 'Z') return c - 'A' + 10; else if (c >= 'a' && c <= 'z') return c - 'a' + 10; else return 36; } /* bigint support */ #define JS_BIGINT_MAX_SIZE ((1024 * 1024) / JS_LIMB_BITS) /* in limbs */ /* it is currently assumed that JS_SHORT_BIG_INT_BITS = JS_LIMB_BITS */ #if JS_SHORT_BIG_INT_BITS == 32 #define JS_SHORT_BIG_INT_MIN INT32_MIN #define JS_SHORT_BIG_INT_MAX INT32_MAX #elif JS_SHORT_BIG_INT_BITS == 64 #define JS_SHORT_BIG_INT_MIN INT64_MIN #define JS_SHORT_BIG_INT_MAX INT64_MAX #else #error unsupported #endif #define ADDC(res, carry_out, op1, op2, carry_in) \ do { \ js_limb_t __v, __a, __k, __k1; \ __v = (op1); \ __a = __v + (op2); \ __k1 = __a < __v; \ __k = (carry_in); \ __a = __a + __k; \ carry_out = (__a < __k) | __k1; \ res = __a; \ } while (0) #if JS_LIMB_BITS == 32 /* a != 0 */ static inline js_limb_t js_limb_clz(js_limb_t a) { return clz32(a); } #else static inline js_limb_t js_limb_clz(js_limb_t a) { return clz64(a); } #endif /* handle a = 0 too */ static inline js_limb_t js_limb_safe_clz(js_limb_t a) { if (a == 0) return JS_LIMB_BITS; else return js_limb_clz(a); } static js_limb_t mp_add(js_limb_t *res, const js_limb_t *op1, const js_limb_t *op2, js_limb_t n, js_limb_t carry) { int i; for(i = 0;i < n; i++) { ADDC(res[i], carry, op1[i], op2[i], carry); } return carry; } static js_limb_t mp_sub(js_limb_t *res, const js_limb_t *op1, const js_limb_t *op2, int n, js_limb_t carry) { int i; js_limb_t k, a, v, k1; k = carry; for(i=0;i<n;i++) { v = op1[i]; a = v - op2[i]; k1 = a > v; v = a - k; k = (v > a) | k1; res[i] = v; } return k; } /* compute 0 - op2. carry = 0 or 1. */ static js_limb_t mp_neg(js_limb_t *res, const js_limb_t *op2, int n) { int i; js_limb_t v, carry; carry = 1; for(i=0;i<n;i++) { v = ~op2[i] + carry; carry = v < carry; res[i] = v; } return carry; } /* tabr[] = taba[] * b + l. Return the high carry */ static js_limb_t mp_mul1(js_limb_t *tabr, const js_limb_t *taba, js_limb_t n, js_limb_t b, js_limb_t l) { js_limb_t i; js_dlimb_t t; for(i = 0; i < n; i++) { t = (js_dlimb_t)taba[i] * (js_dlimb_t)b + l; tabr[i] = t; l = t >> JS_LIMB_BITS; } return l; } static js_limb_t mp_div1(js_limb_t *tabr, const js_limb_t *taba, js_limb_t n, js_limb_t b, js_limb_t r) { js_slimb_t i; js_dlimb_t a1; for(i = n - 1; i >= 0; i--) { a1 = ((js_dlimb_t)r << JS_LIMB_BITS) | taba[i]; tabr[i] = a1 / b; r = a1 % b; } return r; } /* tabr[] += taba[] * b, return the high word. */ static js_limb_t mp_add_mul1(js_limb_t *tabr, const js_limb_t *taba, js_limb_t n, js_limb_t b) { js_limb_t i, l; js_dlimb_t t; l = 0; for(i = 0; i < n; i++) { t = (js_dlimb_t)taba[i] * (js_dlimb_t)b + l + tabr[i]; tabr[i] = t; l = t >> JS_LIMB_BITS; } return l; } /* size of the result : op1_size + op2_size. */ static void mp_mul_basecase(js_limb_t *result, const js_limb_t *op1, js_limb_t op1_size, const js_limb_t *op2, js_limb_t op2_size) { int i; js_limb_t r; result[op1_size] = mp_mul1(result, op1, op1_size, op2[0], 0); for(i=1;i<op2_size;i++) { r = mp_add_mul1(result + i, op1, op1_size, op2[i]); result[i + op1_size] = r; } } /* tabr[] -= taba[] * b. Return the value to substract to the high word. */ static js_limb_t mp_sub_mul1(js_limb_t *tabr, const js_limb_t *taba, js_limb_t n, js_limb_t b) { js_limb_t i, l; js_dlimb_t t; l = 0; for(i = 0; i < n; i++) { t = tabr[i] - (js_dlimb_t)taba[i] * (js_dlimb_t)b - l; tabr[i] = t; l = -(t >> JS_LIMB_BITS); } return l; } /* WARNING: d must be >= 2^(JS_LIMB_BITS-1) */ static inline js_limb_t udiv1norm_init(js_limb_t d) { js_limb_t a0, a1; a1 = -d - 1; a0 = -1; return (((js_dlimb_t)a1 << JS_LIMB_BITS) | a0) / d; } /* return the quotient and the remainder in '*pr'of 'a1*2^JS_LIMB_BITS+a0 / d' with 0 <= a1 < d. */ static inline js_limb_t udiv1norm(js_limb_t *pr, js_limb_t a1, js_limb_t a0, js_limb_t d, js_limb_t d_inv) { js_limb_t n1m, n_adj, q, r, ah; js_dlimb_t a; n1m = ((js_slimb_t)a0 >> (JS_LIMB_BITS - 1)); n_adj = a0 + (n1m & d); a = (js_dlimb_t)d_inv * (a1 - n1m) + n_adj; q = (a >> JS_LIMB_BITS) + a1; /* compute a - q * r and update q so that the remainder is\ between 0 and d - 1 */ a = ((js_dlimb_t)a1 << JS_LIMB_BITS) | a0; a = a - (js_dlimb_t)q * d - d; ah = a >> JS_LIMB_BITS; q += 1 + ah; r = (js_limb_t)a + (ah & d); *pr = r; return q; } #define UDIV1NORM_THRESHOLD 3 /* b must be >= 1 << (JS_LIMB_BITS - 1) */ static js_limb_t mp_div1norm(js_limb_t *tabr, const js_limb_t *taba, js_limb_t n, js_limb_t b, js_limb_t r) { js_slimb_t i; if (n >= UDIV1NORM_THRESHOLD) { js_limb_t b_inv; b_inv = udiv1norm_init(b); for(i = n - 1; i >= 0; i--) { tabr[i] = udiv1norm(&r, r, taba[i], b, b_inv); } } else { js_dlimb_t a1; for(i = n - 1; i >= 0; i--) { a1 = ((js_dlimb_t)r << JS_LIMB_BITS) | taba[i]; tabr[i] = a1 / b; r = a1 % b; } } return r; } /* base case division: divides taba[0..na-1] by tabb[0..nb-1]. tabb[nb - 1] must be >= 1 << (JS_LIMB_BITS - 1). na - nb must be >= 0. 'taba' is modified and contains the remainder (nb limbs). tabq[0..na-nb] contains the quotient with tabq[na - nb] <= 1. */ static void mp_divnorm(js_limb_t *tabq, js_limb_t *taba, js_limb_t na, const js_limb_t *tabb, js_limb_t nb) { js_limb_t r, a, c, q, v, b1, b1_inv, n, dummy_r; int i, j; b1 = tabb[nb - 1]; if (nb == 1) { taba[0] = mp_div1norm(tabq, taba, na, b1, 0); return; } n = na - nb; if (n >= UDIV1NORM_THRESHOLD) b1_inv = udiv1norm_init(b1); else b1_inv = 0; /* first iteration: the quotient is only 0 or 1 */ q = 1; for(j = nb - 1; j >= 0; j--) { if (taba[n + j] != tabb[j]) { if (taba[n + j] < tabb[j]) q = 0; break; } } tabq[n] = q; if (q) { mp_sub(taba + n, taba + n, tabb, nb, 0); } for(i = n - 1; i >= 0; i--) { if (unlikely(taba[i + nb] >= b1)) { q = -1; } else if (b1_inv) { q = udiv1norm(&dummy_r, taba[i + nb], taba[i + nb - 1], b1, b1_inv); } else { js_dlimb_t al; al = ((js_dlimb_t)taba[i + nb] << JS_LIMB_BITS) | taba[i + nb - 1]; q = al / b1; r = al % b1; } r = mp_sub_mul1(taba + i, tabb, nb, q); v = taba[i + nb]; a = v - r; c = (a > v); taba[i + nb] = a; if (c != 0) { /* negative result */ for(;;) { q--; c = mp_add(taba + i, taba + i, tabb, nb, 0); /* propagate carry and test if positive result */ if (c != 0) { if (++taba[i + nb] == 0) { break; } } } } tabq[i] = q; } } /* 1 <= shift <= JS_LIMB_BITS - 1 */ static js_limb_t mp_shl(js_limb_t *tabr, const js_limb_t *taba, int n, int shift) { int i; js_limb_t l, v; l = 0; for(i = 0; i < n; i++) { v = taba[i]; tabr[i] = (v << shift) | l; l = v >> (JS_LIMB_BITS - shift); } return l; } /* r = (a + high*B^n) >> shift. Return the remainder r (0 <= r < 2^shift). 1 <= shift <= LIMB_BITS - 1 */ static js_limb_t mp_shr(js_limb_t *tab_r, const js_limb_t *tab, int n, int shift, js_limb_t high) { int i; js_limb_t l, a; l = high; for(i = n - 1; i >= 0; i--) { a = tab[i]; tab_r[i] = (a >> shift) | (l << (JS_LIMB_BITS - shift)); l = a; } return l & (((js_limb_t)1 << shift) - 1); } static JSBigInt *js_bigint_new(JSContext *ctx, int len) { JSBigInt *r; if (len > JS_BIGINT_MAX_SIZE) { JS_ThrowRangeError(ctx, "BigInt is too large to allocate"); return NULL; } r = js_malloc(ctx, sizeof(JSBigInt) + len * sizeof(js_limb_t)); if (!r) return NULL; r->header.ref_count = 1; r->len = len; return r; } static JSBigInt *js_bigint_set_si(JSBigIntBuf *buf, js_slimb_t a) { JSBigInt *r = (JSBigInt *)buf->big_int_buf; r->header.ref_count = 0; /* fail safe */ r->len = 1; r->tab[0] = a; return r; } static JSBigInt *js_bigint_set_si64(JSBigIntBuf *buf, int64_t a) { #if JS_LIMB_BITS == 64 return js_bigint_set_si(buf, a); #else JSBigInt *r = (JSBigInt *)buf->big_int_buf; r->header.ref_count = 0; /* fail safe */ if (a >= INT32_MIN && a <= INT32_MAX) { r->len = 1; r->tab[0] = a; } else { r->len = 2; r->tab[0] = a; r->tab[1] = a >> JS_LIMB_BITS; } return r; #endif } /* val must be a short big int */ static JSBigInt *js_bigint_set_short(JSBigIntBuf *buf, JSValueConst val) { return js_bigint_set_si(buf, JS_VALUE_GET_SHORT_BIG_INT(val)); } static __maybe_unused void js_bigint_dump1(JSContext *ctx, const char *str, const js_limb_t *tab, int len) { int i; printf("%s: ", str); for(i = len - 1; i >= 0; i--) { #if JS_LIMB_BITS == 32 printf(" %08x", tab[i]); #else printf(" %016" PRIx64, tab[i]); #endif } printf("\n"); } static __maybe_unused void js_bigint_dump(JSContext *ctx, const char *str, const JSBigInt *p) { js_bigint_dump1(ctx, str, p->tab, p->len); } static JSBigInt *js_bigint_new_si(JSContext *ctx, js_slimb_t a) { JSBigInt *r; r = js_bigint_new(ctx, 1); if (!r) return NULL; r->tab[0] = a; return r; } static JSBigInt *js_bigint_new_si64(JSContext *ctx, int64_t a) { #if JS_LIMB_BITS == 64 return js_bigint_new_si(ctx, a); #else if (a >= INT32_MIN && a <= INT32_MAX) { return js_bigint_new_si(ctx, a); } else { JSBigInt *r; r = js_bigint_new(ctx, 2); if (!r) return NULL; r->tab[0] = a; r->tab[1] = a >> 32; return r; } #endif } static JSBigInt *js_bigint_new_ui64(JSContext *ctx, uint64_t a) { if (a <= INT64_MAX) { return js_bigint_new_si64(ctx, a); } else { JSBigInt *r; r = js_bigint_new(ctx, (65 + JS_LIMB_BITS - 1) / JS_LIMB_BITS); if (!r) return NULL; #if JS_LIMB_BITS == 64 r->tab[0] = a; r->tab[1] = 0; #else r->tab[0] = a; r->tab[1] = a >> 32; r->tab[2] = 0; #endif return r; } } static JSBigInt *js_bigint_new_di(JSContext *ctx, js_sdlimb_t a) { JSBigInt *r; if (a == (js_slimb_t)a) { r = js_bigint_new(ctx, 1); if (!r) return NULL; r->tab[0] = a; } else { r = js_bigint_new(ctx, 2); if (!r) return NULL; r->tab[0] = a; r->tab[1] = a >> JS_LIMB_BITS; } return r; } /* Remove redundant high order limbs. Warning: 'a' may be reallocated. Can never fail. */ static JSBigInt *js_bigint_normalize1(JSContext *ctx, JSBigInt *a, int l) { js_limb_t v; assert(a->header.ref_count == 1); while (l > 1) { v = a->tab[l - 1]; if ((v != 0 && v != -1) || (v & 1) != (a->tab[l - 2] >> (JS_LIMB_BITS - 1))) { break; } l--; } if (l != a->len) { JSBigInt *a1; /* realloc to reduce the size */ a->len = l; a1 = js_realloc(ctx, a, sizeof(JSBigInt) + l * sizeof(js_limb_t)); if (a1) a = a1; } return a; } static JSBigInt *js_bigint_normalize(JSContext *ctx, JSBigInt *a) { return js_bigint_normalize1(ctx, a, a->len); } /* return 0 or 1 depending on the sign */ static inline int js_bigint_sign(const JSBigInt *a) { return a->tab[a->len - 1] >> (JS_LIMB_BITS - 1); } static js_slimb_t js_bigint_get_si_sat(const JSBigInt *a) { if (a->len == 1) { return a->tab[0]; } else { #if JS_LIMB_BITS == 32 if (js_bigint_sign(a)) return INT32_MIN; else return INT32_MAX; #else if (js_bigint_sign(a)) return INT64_MIN; else return INT64_MAX; #endif } } /* add the op1 limb */ static JSBigInt *js_bigint_extend(JSContext *ctx, JSBigInt *r, js_limb_t op1) { int n2 = r->len; if ((op1 != 0 && op1 != -1) || (op1 & 1) != r->tab[n2 - 1] >> (JS_LIMB_BITS - 1)) { JSBigInt *r1; r1 = js_realloc(ctx, r, sizeof(JSBigInt) + (n2 + 1) * sizeof(js_limb_t)); if (!r1) { js_free(ctx, r); return NULL; } r = r1; r->len = n2 + 1; r->tab[n2] = op1; } else { /* otherwise still need to normalize the result */ r = js_bigint_normalize(ctx, r); } return r; } /* return NULL in case of error. Compute a + b (b_neg = 0) or a - b (b_neg = 1) */ /* XXX: optimize */ static JSBigInt *js_bigint_add(JSContext *ctx, const JSBigInt *a, const JSBigInt *b, int b_neg) { JSBigInt *r; int n1, n2, i; js_limb_t carry, op1, op2, a_sign, b_sign; n2 = max_int(a->len, b->len); n1 = min_int(a->len, b->len); r = js_bigint_new(ctx, n2); if (!r) return NULL; /* XXX: optimize */ /* common part */ carry = b_neg; for(i = 0; i < n1; i++) { op1 = a->tab[i]; op2 = b->tab[i] ^ (-b_neg); ADDC(r->tab[i], carry, op1, op2, carry); } a_sign = -js_bigint_sign(a); b_sign = (-js_bigint_sign(b)) ^ (-b_neg); /* part with sign extension of one operand */ if (a->len > b->len) { for(i = n1; i < n2; i++) { op1 = a->tab[i]; ADDC(r->tab[i], carry, op1, b_sign, carry); } } else if (a->len < b->len) { for(i = n1; i < n2; i++) { op2 = b->tab[i] ^ (-b_neg); ADDC(r->tab[i], carry, a_sign, op2, carry); } } /* part with sign extension for both operands. Extend the result if necessary */ return js_bigint_extend(ctx, r, a_sign + b_sign + carry); } /* XXX: optimize */ static JSBigInt *js_bigint_neg(JSContext *ctx, const JSBigInt *a) { JSBigIntBuf buf; JSBigInt *b; b = js_bigint_set_si(&buf, 0); return js_bigint_add(ctx, b, a, 1); } static JSBigInt *js_bigint_mul(JSContext *ctx, const JSBigInt *a, const JSBigInt *b) { JSBigInt *r; r = js_bigint_new(ctx, a->len + b->len); if (!r) return NULL; mp_mul_basecase(r->tab, a->tab, a->len, b->tab, b->len); /* correct the result if negative operands (no overflow is possible) */ if (js_bigint_sign(a)) mp_sub(r->tab + a->len, r->tab + a->len, b->tab, b->len, 0); if (js_bigint_sign(b)) mp_sub(r->tab + b->len, r->tab + b->len, a->tab, a->len, 0); return js_bigint_normalize(ctx, r); } /* return the division or the remainder. 'b' must be != 0. return NULL in case of exception (division by zero or memory error) */ static JSBigInt *js_bigint_divrem(JSContext *ctx, const JSBigInt *a, const JSBigInt *b, BOOL is_rem) { JSBigInt *r, *q; js_limb_t *tabb, h; int na, nb, a_sign, b_sign, shift; if (b->len == 1 && b->tab[0] == 0) { JS_ThrowRangeError(ctx, "BigInt division by zero"); return NULL; } a_sign = js_bigint_sign(a); b_sign = js_bigint_sign(b); na = a->len; nb = b->len; r = js_bigint_new(ctx, na + 2); if (!r) return NULL; if (a_sign) { mp_neg(r->tab, a->tab, na); } else { memcpy(r->tab, a->tab, na * sizeof(a->tab[0])); } /* normalize */ while (na > 1 && r->tab[na - 1] == 0) na--; tabb = js_malloc(ctx, nb * sizeof(tabb[0])); if (!tabb) { js_free(ctx, r); return NULL; } if (b_sign) { mp_neg(tabb, b->tab, nb); } else { memcpy(tabb, b->tab, nb * sizeof(tabb[0])); } /* normalize */ while (nb > 1 && tabb[nb - 1] == 0) nb--; /* trivial case if 'a' is small */ if (na < nb) { js_free(ctx, r); js_free(ctx, tabb); if (is_rem) { /* r = a */ r = js_bigint_new(ctx, a->len); if (!r) return NULL; memcpy(r->tab, a->tab, a->len * sizeof(a->tab[0])); return r; } else { /* q = 0 */ return js_bigint_new_si(ctx, 0); } } /* normalize 'b' */ shift = js_limb_clz(tabb[nb - 1]); if (shift != 0) { mp_shl(tabb, tabb, nb, shift); h = mp_shl(r->tab, r->tab, na, shift); if (h != 0) r->tab[na++] = h; } q = js_bigint_new(ctx, na - nb + 2); /* one more limb for the sign */ if (!q) { js_free(ctx, r); js_free(ctx, tabb); return NULL; } // js_bigint_dump1(ctx, "a", r->tab, na); // js_bigint_dump1(ctx, "b", tabb, nb); mp_divnorm(q->tab, r->tab, na, tabb, nb); js_free(ctx, tabb); if (is_rem) { js_free(ctx, q); if (shift != 0) mp_shr(r->tab, r->tab, nb, shift, 0); r->tab[nb++] = 0; if (a_sign) mp_neg(r->tab, r->tab, nb); r = js_bigint_normalize1(ctx, r, nb); return r; } else { js_free(ctx, r); q->tab[na - nb + 1] = 0; if (a_sign ^ b_sign) { mp_neg(q->tab, q->tab, q->len); } q = js_bigint_normalize(ctx, q); return q; } } /* and, or, xor */ static JSBigInt *js_bigint_logic(JSContext *ctx, const JSBigInt *a, const JSBigInt *b, OPCodeEnum op) { JSBigInt *r; js_limb_t b_sign; int a_len, b_len, i; if (a->len < b->len) { const JSBigInt *tmp; tmp = a; a = b; b = tmp; } /* a_len >= b_len */ a_len = a->len; b_len = b->len; b_sign = -js_bigint_sign(b); r = js_bigint_new(ctx, a_len); if (!r) return NULL; switch(op) { case OP_or: for(i = 0; i < b_len; i++) { r->tab[i] = a->tab[i] | b->tab[i]; } for(i = b_len; i < a_len; i++) { r->tab[i] = a->tab[i] | b_sign; } break; case OP_and: for(i = 0; i < b_len; i++) { r->tab[i] = a->tab[i] & b->tab[i]; } for(i = b_len; i < a_len; i++) { r->tab[i] = a->tab[i] & b_sign; } break; case OP_xor: for(i = 0; i < b_len; i++) { r->tab[i] = a->tab[i] ^ b->tab[i]; } for(i = b_len; i < a_len; i++) { r->tab[i] = a->tab[i] ^ b_sign; } break; default: abort(); } return js_bigint_normalize(ctx, r); } static JSBigInt *js_bigint_not(JSContext *ctx, const JSBigInt *a) { JSBigInt *r; int i; r = js_bigint_new(ctx, a->len); if (!r) return NULL; for(i = 0; i < a->len; i++) { r->tab[i] = ~a->tab[i]; } /* no normalization is needed */ return r; } static JSBigInt *js_bigint_shl(JSContext *ctx, const JSBigInt *a, unsigned int shift1) { int d, i, shift; JSBigInt *r; js_limb_t l; if (a->len == 1 && a->tab[0] == 0) return js_bigint_new_si(ctx, 0); /* zero case */ d = shift1 / JS_LIMB_BITS; shift = shift1 % JS_LIMB_BITS; r = js_bigint_new(ctx, a->len + d); if (!r) return NULL; for(i = 0; i < d; i++) r->tab[i] = 0; if (shift == 0) { for(i = 0; i < a->len; i++) { r->tab[i + d] = a->tab[i]; } } else { l = mp_shl(r->tab + d, a->tab, a->len, shift); if (js_bigint_sign(a)) l |= (js_limb_t)(-1) << shift; r = js_bigint_extend(ctx, r, l); } return r; } static JSBigInt *js_bigint_shr(JSContext *ctx, const JSBigInt *a, unsigned int shift1) { int d, i, shift, a_sign, n1; JSBigInt *r; d = shift1 / JS_LIMB_BITS; shift = shift1 % JS_LIMB_BITS; a_sign = js_bigint_sign(a); if (d >= a->len) return js_bigint_new_si(ctx, -a_sign); n1 = a->len - d; r = js_bigint_new(ctx, n1); if (!r) return NULL; if (shift == 0) { for(i = 0; i < n1; i++) { r->tab[i] = a->tab[i + d]; } /* no normalization is needed */ } else { mp_shr(r->tab, a->tab + d, n1, shift, -a_sign); r = js_bigint_normalize(ctx, r); } return r; } static JSBigInt *js_bigint_pow(JSContext *ctx, const JSBigInt *a, JSBigInt *b) { uint32_t e; int n_bits, i; JSBigInt *r, *r1; /* b must be >= 0 */ if (js_bigint_sign(b)) { JS_ThrowRangeError(ctx, "BigInt negative exponent"); return NULL; } if (b->len == 1 && b->tab[0] == 0) { /* a^0 = 1 */ return js_bigint_new_si(ctx, 1); } else if (a->len == 1) { js_limb_t v; BOOL is_neg; v = a->tab[0]; if (v <= 1) return js_bigint_new_si(ctx, v); else if (v == -1) return js_bigint_new_si(ctx, 1 - 2 * (b->tab[0] & 1)); is_neg = (js_slimb_t)v < 0; if (is_neg) v = -v; if ((v & (v - 1)) == 0) { uint64_t e1; int n; /* v = 2^n */ n = JS_LIMB_BITS - 1 - js_limb_clz(v); if (b->len > 1) goto overflow; if (b->tab[0] > INT32_MAX) goto overflow; e = b->tab[0]; e1 = (uint64_t)e * n; if (e1 > JS_BIGINT_MAX_SIZE * JS_LIMB_BITS) goto overflow; e = e1; if (is_neg) is_neg = b->tab[0] & 1; r = js_bigint_new(ctx, (e + JS_LIMB_BITS + 1 - is_neg) / JS_LIMB_BITS); if (!r) return NULL; memset(r->tab, 0, sizeof(r->tab[0]) * r->len); r->tab[e / JS_LIMB_BITS] = (js_limb_t)(1 - 2 * is_neg) << (e % JS_LIMB_BITS); return r; } } if (b->len > 1) goto overflow; if (b->tab[0] > INT32_MAX) goto overflow; e = b->tab[0]; n_bits = 32 - clz32(e); r = js_bigint_new(ctx, a->len); if (!r) return NULL; memcpy(r->tab, a->tab, a->len * sizeof(a->tab[0])); for(i = n_bits - 2; i >= 0; i--) { r1 = js_bigint_mul(ctx, r, r); if (!r1) return NULL; js_free(ctx, r); r = r1; if ((e >> i) & 1) { r1 = js_bigint_mul(ctx, r, a); if (!r1) return NULL; js_free(ctx, r); r = r1; } } return r; overflow: JS_ThrowRangeError(ctx, "BigInt is too large"); return NULL; } /* return (mant, exp) so that abs(a) ~ mant*2^(exp - (limb_bits - 1). a must be != 0. */ static uint64_t js_bigint_get_mant_exp(JSContext *ctx, int *pexp, const JSBigInt *a) { js_limb_t t[4 - JS_LIMB_BITS / 32], carry, v, low_bits; int n1, n2, sgn, shift, i, j, e; uint64_t a1, a0; n2 = 4 - JS_LIMB_BITS / 32; n1 = a->len - n2; sgn = js_bigint_sign(a); /* low_bits != 0 if there are a non zero low bit in abs(a) */ low_bits = 0; carry = sgn; for(i = 0; i < n1; i++) { v = (a->tab[i] ^ (-sgn)) + carry; carry = v < carry; low_bits |= v; } /* get the n2 high limbs of abs(a) */ for(j = 0; j < n2; j++) { i = j + n1; if (i < 0) { v = 0; } else { v = (a->tab[i] ^ (-sgn)) + carry; carry = v < carry; } t[j] = v; } #if JS_LIMB_BITS == 32 a1 = ((uint64_t)t[2] << 32) | t[1]; a0 = (uint64_t)t[0] << 32; #else a1 = t[1]; a0 = t[0]; #endif a0 |= (low_bits != 0); /* normalize */ if (a1 == 0) { /* JS_LIMB_BITS = 64 bit only */ shift = 64; a1 = a0; a0 = 0; } else { shift = clz64(a1); if (shift != 0) { a1 = (a1 << shift) | (a0 >> (64 - shift)); a0 <<= shift; } } a1 |= (a0 != 0); /* keep the bits for the final rounding */ /* compute the exponent */ e = a->len * JS_LIMB_BITS - shift - 1; *pexp = e; return a1; } /* shift left with round to nearest, ties to even. n >= 1 */ static uint64_t shr_rndn(uint64_t a, int n) { uint64_t addend = ((a >> n) & 1) + ((1 << (n - 1)) - 1); return (a + addend) >> n; } /* convert to float64 with round to nearest, ties to even. Return +/-infinity if too large. */ static double js_bigint_to_float64(JSContext *ctx, const JSBigInt *a) { int sgn, e; uint64_t mant; if (a->len == 1) { /* fast case, including zero */ return (double)(js_slimb_t)a->tab[0]; } sgn = js_bigint_sign(a); mant = js_bigint_get_mant_exp(ctx, &e, a); if (e > 1023) { /* overflow: return infinity */ mant = 0; e = 1024; } else { mant = (mant >> 1) | (mant & 1); /* avoid overflow in rounding */ mant = shr_rndn(mant, 10); /* rounding can cause an overflow */ if (mant >= ((uint64_t)1 << 53)) { mant >>= 1; e++; } mant &= (((uint64_t)1 << 52) - 1); } return uint64_as_float64(((uint64_t)sgn << 63) | ((uint64_t)(e + 1023) << 52) | mant); } /* return (1, NULL) if not an integer, (2, NULL) if NaN or Infinity, (0, n) if an integer, (0, NULL) in case of memory error */ static JSBigInt *js_bigint_from_float64(JSContext *ctx, int *pres, double a1) { uint64_t a = float64_as_uint64(a1); int sgn, e, shift; uint64_t mant; JSBigIntBuf buf; JSBigInt *r; sgn = a >> 63; e = (a >> 52) & ((1 << 11) - 1); mant = a & (((uint64_t)1 << 52) - 1); if (e == 2047) { /* NaN, Infinity */ *pres = 2; return NULL; } if (e == 0 && mant == 0) { /* zero */ *pres = 0; return js_bigint_new_si(ctx, 0); } e -= 1023; /* 0 < a < 1 : not an integer */ if (e < 0) goto not_an_integer; mant |= (uint64_t)1 << 52; if (e < 52) { shift = 52 - e; /* check that there is no fractional part */ if (mant & (((uint64_t)1 << shift) - 1)) { not_an_integer: *pres = 1; return NULL; } mant >>= shift; e = 0; } else { e -= 52; } if (sgn) mant = -mant; /* the integer is mant*2^e */ r = js_bigint_set_si64(&buf, (int64_t)mant); *pres = 0; return js_bigint_shl(ctx, r, e); } /* return -1, 0, 1 or (2) (unordered) */ static int js_bigint_float64_cmp(JSContext *ctx, const JSBigInt *a, double b) { int b_sign, a_sign, e, f; uint64_t mant, b1, a_mant; b1 = float64_as_uint64(b); b_sign = b1 >> 63; e = (b1 >> 52) & ((1 << 11) - 1); mant = b1 & (((uint64_t)1 << 52) - 1); a_sign = js_bigint_sign(a); if (e == 2047) { if (mant != 0) { /* NaN */ return 2; } else { /* +/- infinity */ return 2 * b_sign - 1; } } else if (e == 0 && mant == 0) { /* b = +/-0 */ if (a->len == 1 && a->tab[0] == 0) return 0; else return 1 - 2 * a_sign; } else if (a->len == 1 && a->tab[0] == 0) { /* a = 0, b != 0 */ return 2 * b_sign - 1; } else if (a_sign != b_sign) { return 1 - 2 * a_sign; } else { e -= 1023; /* Note: handling denormals is not necessary because we compare to integers hence f >= 0 */ /* compute f so that 2^f <= abs(a) < 2^(f+1) */ a_mant = js_bigint_get_mant_exp(ctx, &f, a); if (f != e) { if (f < e) return -1; else return 1; } else { mant = (mant | ((uint64_t)1 << 52)) << 11; /* align to a_mant */ if (a_mant < mant) return 2 * a_sign - 1; else if (a_mant > mant) return 1 - 2 * a_sign; else return 0; } } } /* return -1, 0 or 1 */ static int js_bigint_cmp(JSContext *ctx, const JSBigInt *a, const JSBigInt *b) { int a_sign, b_sign, res, i; a_sign = js_bigint_sign(a); b_sign = js_bigint_sign(b); if (a_sign != b_sign) { res = 1 - 2 * a_sign; } else { /* we assume the numbers are normalized */ if (a->len != b->len) { if (a->len < b->len) res = 2 * a_sign - 1; else res = 1 - 2 * a_sign; } else { res = 0; for(i = a->len -1; i >= 0; i--) { if (a->tab[i] != b->tab[i]) { if (a->tab[i] < b->tab[i]) res = -1; else res = 1; break; } } } } return res; } /* contains 10^i */ static const js_limb_t js_pow_dec[JS_LIMB_DIGITS + 1] = { 1U, 10U, 100U, 1000U, 10000U, 100000U, 1000000U, 10000000U, 100000000U, 1000000000U, #if JS_LIMB_BITS == 64 10000000000U, 100000000000U, 1000000000000U, 10000000000000U, 100000000000000U, 1000000000000000U, 10000000000000000U, 100000000000000000U, 1000000000000000000U, 10000000000000000000U, #endif }; /* syntax: [-]digits in base radix. Return NULL if memory error. radix = 10, 2, 8 or 16. */ static JSBigInt *js_bigint_from_string(JSContext *ctx, const char *str, int radix) { const char *p = str; size_t n_digits1; int is_neg, n_digits, n_limbs, len, log2_radix, n_bits, i; JSBigInt *r; js_limb_t v, c, h; is_neg = 0; if (*p == '-') { is_neg = 1; p++; } while (*p == '0') p++; n_digits1 = strlen(p); /* the real check for overflox is done js_bigint_new(). Here we just avoid integer overflow */ if (n_digits1 > JS_BIGINT_MAX_SIZE * JS_LIMB_BITS) { JS_ThrowRangeError(ctx, "BigInt is too large to allocate"); return NULL; } n_digits = n_digits1; log2_radix = 32 - clz32(radix - 1); /* ceil(log2(radix)) */ /* compute the maximum number of limbs */ if (radix == 10) { n_bits = (n_digits * 27 + 7) / 8; /* >= ceil(n_digits * log2(10)) */ } else { n_bits = n_digits * log2_radix; } /* we add one extra bit for the sign */ n_limbs = max_int(1, n_bits / JS_LIMB_BITS + 1); r = js_bigint_new(ctx, n_limbs); if (!r) return NULL; if (radix == 10) { int digits_per_limb = JS_LIMB_DIGITS; len = 1; r->tab[0] = 0; for(;;) { /* XXX: slow */ v = 0; for(i = 0; i < digits_per_limb; i++) { c = to_digit(*p); if (c >= radix) break; p++; v = v * 10 + c; } if (i == 0) break; if (len == 1 && r->tab[0] == 0) { r->tab[0] = v; } else { h = mp_mul1(r->tab, r->tab, len, js_pow_dec[i], v); if (h != 0) { r->tab[len++] = h; } } } /* add one extra limb to have the correct sign*/ if ((r->tab[len - 1] >> (JS_LIMB_BITS - 1)) != 0) r->tab[len++] = 0; r->len = len; } else { unsigned int bit_pos, shift, pos; /* power of two base: no multiplication is needed */ r->len = n_limbs; memset(r->tab, 0, sizeof(r->tab[0]) * n_limbs); for(i = 0; i < n_digits; i++) { c = to_digit(p[n_digits - 1 - i]); assert(c < radix); bit_pos = i * log2_radix; shift = bit_pos & (JS_LIMB_BITS - 1); pos = bit_pos / JS_LIMB_BITS; r->tab[pos] |= c << shift; /* if log2_radix does not divide JS_LIMB_BITS, needed an additional op */ if (shift + log2_radix > JS_LIMB_BITS) { r->tab[pos + 1] |= c >> (JS_LIMB_BITS - shift); } } } r = js_bigint_normalize(ctx, r); /* XXX: could do it in place */ if (is_neg) { JSBigInt *r1; r1 = js_bigint_neg(ctx, r); js_free(ctx, r); r = r1; } return r; } /* 2 <= base <= 36 */ static char const digits[36] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; /* special version going backwards */ /* XXX: use dtoa.c */ static char *js_u64toa(char *q, int64_t n, unsigned int base) { int digit; if (base == 10) { /* division by known base uses multiplication */ do { digit = (uint64_t)n % 10; n = (uint64_t)n / 10; *--q = '0' + digit; } while (n != 0); } else { do { digit = (uint64_t)n % base; n = (uint64_t)n / base; *--q = digits[digit]; } while (n != 0); } return q; } /* len >= 1. 2 <= radix <= 36 */ static char *limb_to_a(char *q, js_limb_t n, unsigned int radix, int len) { int digit, i; if (radix == 10) { /* specific case with constant divisor */ /* XXX: optimize */ for(i = 0; i < len; i++) { digit = (js_limb_t)n % 10; n = (js_limb_t)n / 10; *--q = digit + '0'; } } else { for(i = 0; i < len; i++) { digit = (js_limb_t)n % radix; n = (js_limb_t)n / radix; *--q = digits[digit]; } } return q; } #define JS_RADIX_MAX 36 static const uint8_t digits_per_limb_table[JS_RADIX_MAX - 1] = { #if JS_LIMB_BITS == 32 32,20,16,13,12,11,10,10, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, #else 64,40,32,27,24,22,21,20,19,18,17,17,16,16,16,15,15,15,14,14,14,14,13,13,13,13,13,13,13,12,12,12,12,12,12, #endif }; static const js_limb_t radix_base_table[JS_RADIX_MAX - 1] = { #if JS_LIMB_BITS == 32 0x00000000, 0xcfd41b91, 0x00000000, 0x48c27395, 0x81bf1000, 0x75db9c97, 0x40000000, 0xcfd41b91, 0x3b9aca00, 0x8c8b6d2b, 0x19a10000, 0x309f1021, 0x57f6c100, 0x98c29b81, 0x00000000, 0x18754571, 0x247dbc80, 0x3547667b, 0x4c4b4000, 0x6b5a6e1d, 0x94ace180, 0xcaf18367, 0x0b640000, 0x0e8d4a51, 0x1269ae40, 0x17179149, 0x1cb91000, 0x23744899, 0x2b73a840, 0x34e63b41, 0x40000000, 0x4cfa3cc1, 0x5c13d840, 0x6d91b519, 0x81bf1000, #else 0x0000000000000000, 0xa8b8b452291fe821, 0x0000000000000000, 0x6765c793fa10079d, 0x41c21cb8e1000000, 0x3642798750226111, 0x8000000000000000, 0xa8b8b452291fe821, 0x8ac7230489e80000, 0x4d28cb56c33fa539, 0x1eca170c00000000, 0x780c7372621bd74d, 0x1e39a5057d810000, 0x5b27ac993df97701, 0x0000000000000000, 0x27b95e997e21d9f1, 0x5da0e1e53c5c8000, 0xd2ae3299c1c4aedb, 0x16bcc41e90000000, 0x2d04b7fdd9c0ef49, 0x5658597bcaa24000, 0xa0e2073737609371, 0x0c29e98000000000, 0x14adf4b7320334b9, 0x226ed36478bfa000, 0x383d9170b85ff80b, 0x5a3c23e39c000000, 0x8e65137388122bcd, 0xdd41bb36d259e000, 0x0aee5720ee830681, 0x1000000000000000, 0x172588ad4f5f0981, 0x211e44f7d02c1000, 0x2ee56725f06e5c71, 0x41c21cb8e1000000, #endif }; static JSValue js_bigint_to_string1(JSContext *ctx, JSValueConst val, int radix) { if (JS_VALUE_GET_TAG(val) == JS_TAG_SHORT_BIG_INT) { char buf[66]; int len; len = i64toa_radix(buf, JS_VALUE_GET_SHORT_BIG_INT(val), radix); return js_new_string8_len(ctx, buf, len); } else { JSBigInt *r, *tmp = NULL; char *buf, *q, *buf_end; int is_neg, n_bits, log2_radix, n_digits; BOOL is_binary_radix; JSValue res; assert(JS_VALUE_GET_TAG(val) == JS_TAG_BIG_INT); r = JS_VALUE_GET_PTR(val); if (r->len == 1 && r->tab[0] == 0) { /* '0' case */ return js_new_string8_len(ctx, "0", 1); } is_binary_radix = ((radix & (radix - 1)) == 0); is_neg = js_bigint_sign(r); if (is_neg) { tmp = js_bigint_neg(ctx, r); if (!tmp) return JS_EXCEPTION; r = tmp; } else if (!is_binary_radix) { /* need to modify 'r' */ tmp = js_bigint_new(ctx, r->len); if (!tmp) return JS_EXCEPTION; memcpy(tmp->tab, r->tab, r->len * sizeof(r->tab[0])); r = tmp; } log2_radix = 31 - clz32(radix); /* floor(log2(radix)) */ n_bits = r->len * JS_LIMB_BITS - js_limb_safe_clz(r->tab[r->len - 1]); /* n_digits is exact only if radix is a power of two. Otherwise it is >= the exact number of digits */ n_digits = (n_bits + log2_radix - 1) / log2_radix; /* XXX: could directly build the JSString */ buf = js_malloc(ctx, n_digits + is_neg + 1); if (!buf) { js_free(ctx, tmp); return JS_EXCEPTION; } q = buf + n_digits + is_neg + 1; *--q = '\0'; buf_end = q; if (!is_binary_radix) { int len; js_limb_t radix_base, v; radix_base = radix_base_table[radix - 2]; len = r->len; for(;;) { /* remove leading zero limbs */ while (len > 1 && r->tab[len - 1] == 0) len--; if (len == 1 && r->tab[0] < radix_base) { v = r->tab[0]; if (v != 0) { q = js_u64toa(q, v, radix); } break; } else { v = mp_div1(r->tab, r->tab, len, radix_base, 0); q = limb_to_a(q, v, radix, digits_per_limb_table[radix - 2]); } } } else { int i, shift; unsigned int bit_pos, pos, c; /* radix is a power of two */ for(i = 0; i < n_digits; i++) { bit_pos = i * log2_radix; pos = bit_pos / JS_LIMB_BITS; shift = bit_pos % JS_LIMB_BITS; c = r->tab[pos] >> shift; if ((shift + log2_radix) > JS_LIMB_BITS && (pos + 1) < r->len) { c |= r->tab[pos + 1] << (JS_LIMB_BITS - shift); } c &= (radix - 1); *--q = digits[c]; } } if (is_neg) *--q = '-'; js_free(ctx, tmp); res = js_new_string8_len(ctx, q, buf_end - q); js_free(ctx, buf); return res; } } /* if possible transform a BigInt to short big and free it, otherwise return a normal bigint */ static JSValue JS_CompactBigInt(JSContext *ctx, JSBigInt *p) { JSValue res; if (p->len == 1) { res = __JS_NewShortBigInt(ctx, (js_slimb_t)p->tab[0]); js_free(ctx, p); return res; } else { return JS_MKPTR(JS_TAG_BIG_INT, p); } } #define ATOD_INT_ONLY (1 << 0) /* accept Oo and Ob prefixes in addition to 0x prefix if radix = 0 */ #define ATOD_ACCEPT_BIN_OCT (1 << 2) /* accept O prefix as octal if radix == 0 and properly formed (Annex B) */ #define ATOD_ACCEPT_LEGACY_OCTAL (1 << 4) /* accept _ between digits as a digit separator */ #define ATOD_ACCEPT_UNDERSCORES (1 << 5) /* allow a suffix to override the type */ #define ATOD_ACCEPT_SUFFIX (1 << 6) /* default type */ #define ATOD_TYPE_MASK (3 << 7) #define ATOD_TYPE_FLOAT64 (0 << 7) #define ATOD_TYPE_BIG_INT (1 << 7) /* accept -0x1 */ #define ATOD_ACCEPT_PREFIX_AFTER_SIGN (1 << 10) /* return an exception in case of memory error. Return JS_NAN if invalid syntax */ /* XXX: directly use js_atod() */ static JSValue js_atof(JSContext *ctx, const char *str, const char **pp, int radix, int flags) { const char *p, *p_start; int sep, is_neg; BOOL is_float, has_legacy_octal; int atod_type = flags & ATOD_TYPE_MASK; char buf1[64], *buf; int i, j, len; BOOL buf_allocated = FALSE; JSValue val; JSATODTempMem atod_mem; /* optional separator between digits */ sep = (flags & ATOD_ACCEPT_UNDERSCORES) ? '_' : 256; has_legacy_octal = FALSE; p = str; p_start = p; is_neg = 0; if (p[0] == '+') { p++; p_start++; if (!(flags & ATOD_ACCEPT_PREFIX_AFTER_SIGN)) goto no_radix_prefix; } else if (p[0] == '-') { p++; p_start++; is_neg = 1; if (!(flags & ATOD_ACCEPT_PREFIX_AFTER_SIGN)) goto no_radix_prefix; } if (p[0] == '0') { if ((p[1] == 'x' || p[1] == 'X') && (radix == 0 || radix == 16)) { p += 2; radix = 16; } else if ((p[1] == 'o' || p[1] == 'O') && radix == 0 && (flags & ATOD_ACCEPT_BIN_OCT)) { p += 2; radix = 8; } else if ((p[1] == 'b' || p[1] == 'B') && radix == 0 && (flags & ATOD_ACCEPT_BIN_OCT)) { p += 2; radix = 2; } else if ((p[1] >= '0' && p[1] <= '9') && radix == 0 && (flags & ATOD_ACCEPT_LEGACY_OCTAL)) { int i; has_legacy_octal = TRUE; sep = 256; for (i = 1; (p[i] >= '0' && p[i] <= '7'); i++) continue; if (p[i] == '8' || p[i] == '9') goto no_prefix; p += 1; radix = 8; } else { goto no_prefix; } /* there must be a digit after the prefix */ if (to_digit((uint8_t)*p) >= radix) goto fail; no_prefix: ; } else { no_radix_prefix: if (!(flags & ATOD_INT_ONLY) && (atod_type == ATOD_TYPE_FLOAT64) && strstart(p, "Infinity", &p)) { double d = 1.0 / 0.0; if (is_neg) d = -d; val = JS_NewFloat64(ctx, d); goto done; } } if (radix == 0) radix = 10; is_float = FALSE; p_start = p; while (to_digit((uint8_t)*p) < radix || (*p == sep && (radix != 10 || p != p_start + 1 || p[-1] != '0') && to_digit((uint8_t)p[1]) < radix)) { p++; } if (!(flags & ATOD_INT_ONLY) && radix == 10) { if (*p == '.' && (p > p_start || to_digit((uint8_t)p[1]) < radix)) { is_float = TRUE; p++; if (*p == sep) goto fail; while (to_digit((uint8_t)*p) < radix || (*p == sep && to_digit((uint8_t)p[1]) < radix)) p++; } if (p > p_start && (*p == 'e' || *p == 'E')) { const char *p1 = p + 1; is_float = TRUE; if (*p1 == '+') { p1++; } else if (*p1 == '-') { p1++; } if (is_digit((uint8_t)*p1)) { p = p1 + 1; while (is_digit((uint8_t)*p) || (*p == sep && is_digit((uint8_t)p[1]))) p++; } } } if (p == p_start) goto fail; buf = buf1; buf_allocated = FALSE; len = p - p_start; if (unlikely((len + 2) > sizeof(buf1))) { buf = js_malloc_rt(ctx->rt, len + 2); /* no exception raised */ if (!buf) goto mem_error; buf_allocated = TRUE; } /* remove the separators and the radix prefixes */ j = 0; if (is_neg) buf[j++] = '-'; for (i = 0; i < len; i++) { if (p_start[i] != '_') buf[j++] = p_start[i]; } buf[j] = '\0'; if ((flags & ATOD_ACCEPT_SUFFIX) && *p == 'n') { p++; atod_type = ATOD_TYPE_BIG_INT; } switch(atod_type) { case ATOD_TYPE_FLOAT64: { double d; d = js_atod(buf, NULL, radix, is_float ? 0 : JS_ATOD_INT_ONLY, &atod_mem); /* return int or float64 */ val = JS_NewFloat64(ctx, d); } break; case ATOD_TYPE_BIG_INT: { JSBigInt *r; if (has_legacy_octal || is_float) goto fail; r = js_bigint_from_string(ctx, buf, radix); if (!r) { val = JS_EXCEPTION; goto done; } val = JS_CompactBigInt(ctx, r); } break; default: abort(); } done: if (buf_allocated) js_free_rt(ctx->rt, buf); if (pp) *pp = p; return val; fail: val = JS_NAN; goto done; mem_error: val = JS_ThrowOutOfMemory(ctx); goto done; } typedef enum JSToNumberHintEnum { TON_FLAG_NUMBER, TON_FLAG_NUMERIC, } JSToNumberHintEnum; static JSValue JS_ToNumberHintFree(JSContext *ctx, JSValue val, JSToNumberHintEnum flag) { uint32_t tag; JSValue ret; redo: tag = JS_VALUE_GET_NORM_TAG(val); switch(tag) { case JS_TAG_BIG_INT: case JS_TAG_SHORT_BIG_INT: if (flag != TON_FLAG_NUMERIC) { JS_FreeValue(ctx, val); return JS_ThrowTypeError(ctx, "cannot convert bigint to number"); } ret = val; break; case JS_TAG_FLOAT64: case JS_TAG_INT: case JS_TAG_EXCEPTION: ret = val; break; case JS_TAG_BOOL: case JS_TAG_NULL: ret = JS_NewInt32(ctx, JS_VALUE_GET_INT(val)); break; case JS_TAG_UNDEFINED: ret = JS_NAN; break; case JS_TAG_OBJECT: val = JS_ToPrimitiveFree(ctx, val, HINT_NUMBER); if (JS_IsException(val)) return JS_EXCEPTION; goto redo; case JS_TAG_STRING: case JS_TAG_STRING_ROPE: { const char *str; const char *p; size_t len; str = JS_ToCStringLen(ctx, &len, val); JS_FreeValue(ctx, val); if (!str) return JS_EXCEPTION; p = str; p += skip_spaces(p); if ((p - str) == len) { ret = JS_NewInt32(ctx, 0); } else { int flags = ATOD_ACCEPT_BIN_OCT; ret = js_atof(ctx, p, &p, 0, flags); if (!JS_IsException(ret)) { p += skip_spaces(p); if ((p - str) != len) { JS_FreeValue(ctx, ret); ret = JS_NAN; } } } JS_FreeCString(ctx, str); } break; case JS_TAG_SYMBOL: JS_FreeValue(ctx, val); return JS_ThrowTypeError(ctx, "cannot convert symbol to number"); default: JS_FreeValue(ctx, val); ret = JS_NAN; break; } return ret; } static JSValue JS_ToNumberFree(JSContext *ctx, JSValue val) { return JS_ToNumberHintFree(ctx, val, TON_FLAG_NUMBER); } static JSValue JS_ToNumericFree(JSContext *ctx, JSValue val) { return JS_ToNumberHintFree(ctx, val, TON_FLAG_NUMERIC); } static JSValue JS_ToNumeric(JSContext *ctx, JSValueConst val) { return JS_ToNumericFree(ctx, JS_DupValue(ctx, val)); } static __exception int __JS_ToFloat64Free(JSContext *ctx, double *pres, JSValue val) { double d; uint32_t tag; val = JS_ToNumberFree(ctx, val); if (JS_IsException(val)) goto fail; tag = JS_VALUE_GET_NORM_TAG(val); switch(tag) { case JS_TAG_INT: d = JS_VALUE_GET_INT(val); break; case JS_TAG_FLOAT64: d = JS_VALUE_GET_FLOAT64(val); break; default: abort(); } *pres = d; return 0; fail: *pres = JS_FLOAT64_NAN; return -1; } static inline int JS_ToFloat64Free(JSContext *ctx, double *pres, JSValue val) { uint32_t tag; tag = JS_VALUE_GET_TAG(val); if (tag <= JS_TAG_NULL) { *pres = JS_VALUE_GET_INT(val); return 0; } else if (JS_TAG_IS_FLOAT64(tag)) { *pres = JS_VALUE_GET_FLOAT64(val); return 0; } else { return __JS_ToFloat64Free(ctx, pres, val); } } int JS_ToFloat64(JSContext *ctx, double *pres, JSValueConst val) { return JS_ToFloat64Free(ctx, pres, JS_DupValue(ctx, val)); } static JSValue JS_ToNumber(JSContext *ctx, JSValueConst val) { return JS_ToNumberFree(ctx, JS_DupValue(ctx, val)); } /* same as JS_ToNumber() but return 0 in case of NaN/Undefined */ static __maybe_unused JSValue JS_ToIntegerFree(JSContext *ctx, JSValue val) { uint32_t tag; JSValue ret; redo: tag = JS_VALUE_GET_NORM_TAG(val); switch(tag) { case JS_TAG_INT: case JS_TAG_BOOL: case JS_TAG_NULL: case JS_TAG_UNDEFINED: ret = JS_NewInt32(ctx, JS_VALUE_GET_INT(val)); break; case JS_TAG_FLOAT64: { double d = JS_VALUE_GET_FLOAT64(val); if (isnan(d)) { ret = JS_NewInt32(ctx, 0); } else { /* convert -0 to +0 */ d = trunc(d) + 0.0; ret = JS_NewFloat64(ctx, d); } } break; default: val = JS_ToNumberFree(ctx, val); if (JS_IsException(val)) return val; goto redo; } return ret; } /* Note: the integer value is satured to 32 bits */ static int JS_ToInt32SatFree(JSContext *ctx, int *pres, JSValue val) { uint32_t tag; int ret; redo: tag = JS_VALUE_GET_NORM_TAG(val); switch(tag) { case JS_TAG_INT: case JS_TAG_BOOL: case JS_TAG_NULL: case JS_TAG_UNDEFINED: ret = JS_VALUE_GET_INT(val); break; case JS_TAG_EXCEPTION: *pres = 0; return -1; case JS_TAG_FLOAT64: { double d = JS_VALUE_GET_FLOAT64(val); if (isnan(d)) { ret = 0; } else { if (d < INT32_MIN) ret = INT32_MIN; else if (d > INT32_MAX) ret = INT32_MAX; else ret = (int)d; } } break; default: val = JS_ToNumberFree(ctx, val); if (JS_IsException(val)) { *pres = 0; return -1; } goto redo; } *pres = ret; return 0; } int JS_ToInt32Sat(JSContext *ctx, int *pres, JSValueConst val) { return JS_ToInt32SatFree(ctx, pres, JS_DupValue(ctx, val)); } int JS_ToInt32Clamp(JSContext *ctx, int *pres, JSValueConst val, int min, int max, int min_offset) { int res = JS_ToInt32SatFree(ctx, pres, JS_DupValue(ctx, val)); if (res == 0) { if (*pres < min) { *pres += min_offset; if (*pres < min) *pres = min; } else { if (*pres > max) *pres = max; } } return res; } static int JS_ToInt64SatFree(JSContext *ctx, int64_t *pres, JSValue val) { uint32_t tag; redo: tag = JS_VALUE_GET_NORM_TAG(val); switch(tag) { case JS_TAG_INT: case JS_TAG_BOOL: case JS_TAG_NULL: case JS_TAG_UNDEFINED: *pres = JS_VALUE_GET_INT(val); return 0; case JS_TAG_EXCEPTION: *pres = 0; return -1; case JS_TAG_FLOAT64: { double d = JS_VALUE_GET_FLOAT64(val); if (isnan(d)) { *pres = 0; } else { if (d < INT64_MIN) *pres = INT64_MIN; else if (d >= 0x1p63) /* must use INT64_MAX + 1 because INT64_MAX cannot be exactly represented as a double */ *pres = INT64_MAX; else *pres = (int64_t)d; } } return 0; default: val = JS_ToNumberFree(ctx, val); if (JS_IsException(val)) { *pres = 0; return -1; } goto redo; } } int JS_ToInt64Sat(JSContext *ctx, int64_t *pres, JSValueConst val) { return JS_ToInt64SatFree(ctx, pres, JS_DupValue(ctx, val)); } int JS_ToInt64Clamp(JSContext *ctx, int64_t *pres, JSValueConst val, int64_t min, int64_t max, int64_t neg_offset) { int res = JS_ToInt64SatFree(ctx, pres, JS_DupValue(ctx, val)); if (res == 0) { if (*pres < 0) *pres += neg_offset; if (*pres < min) *pres = min; else if (*pres > max) *pres = max; } return res; } /* Same as JS_ToInt32Free() but with a 64 bit result. Return (<0, 0) in case of exception */ static int JS_ToInt64Free(JSContext *ctx, int64_t *pres, JSValue val) { uint32_t tag; int64_t ret; redo: tag = JS_VALUE_GET_NORM_TAG(val); switch(tag) { case JS_TAG_INT: case JS_TAG_BOOL: case JS_TAG_NULL: case JS_TAG_UNDEFINED: ret = JS_VALUE_GET_INT(val); break; case JS_TAG_FLOAT64: { JSFloat64Union u; double d; int e; d = JS_VALUE_GET_FLOAT64(val); u.d = d; /* we avoid doing fmod(x, 2^64) */ e = (u.u64 >> 52) & 0x7ff; if (likely(e <= (1023 + 62))) { /* fast case */ ret = (int64_t)d; } else if (e <= (1023 + 62 + 53)) { uint64_t v; /* remainder modulo 2^64 */ v = (u.u64 & (((uint64_t)1 << 52) - 1)) | ((uint64_t)1 << 52); ret = v << ((e - 1023) - 52); /* take the sign into account */ if (u.u64 >> 63) ret = -ret; } else { ret = 0; /* also handles NaN and +inf */ } } break; default: val = JS_ToNumberFree(ctx, val); if (JS_IsException(val)) { *pres = 0; return -1; } goto redo; } *pres = ret; return 0; } int JS_ToInt64(JSContext *ctx, int64_t *pres, JSValueConst val) { return JS_ToInt64Free(ctx, pres, JS_DupValue(ctx, val)); } int JS_ToInt64Ext(JSContext *ctx, int64_t *pres, JSValueConst val) { if (JS_IsBigInt(ctx, val)) return JS_ToBigInt64(ctx, pres, val); else return JS_ToInt64(ctx, pres, val); } /* return (<0, 0) in case of exception */ static int JS_ToInt32Free(JSContext *ctx, int32_t *pres, JSValue val) { uint32_t tag; int32_t ret; redo: tag = JS_VALUE_GET_NORM_TAG(val); switch(tag) { case JS_TAG_INT: case JS_TAG_BOOL: case JS_TAG_NULL: case JS_TAG_UNDEFINED: ret = JS_VALUE_GET_INT(val); break; case JS_TAG_FLOAT64: { JSFloat64Union u; double d; int e; d = JS_VALUE_GET_FLOAT64(val); u.d = d; /* we avoid doing fmod(x, 2^32) */ e = (u.u64 >> 52) & 0x7ff; if (likely(e <= (1023 + 30))) { /* fast case */ ret = (int32_t)d; } else if (e <= (1023 + 30 + 53)) { uint64_t v; /* remainder modulo 2^32 */ v = (u.u64 & (((uint64_t)1 << 52) - 1)) | ((uint64_t)1 << 52); v = v << ((e - 1023) - 52 + 32); ret = v >> 32; /* take the sign into account */ if (u.u64 >> 63) ret = -ret; } else { ret = 0; /* also handles NaN and +inf */ } } break; default: val = JS_ToNumberFree(ctx, val); if (JS_IsException(val)) { *pres = 0; return -1; } goto redo; } *pres = ret; return 0; } int JS_ToInt32(JSContext *ctx, int32_t *pres, JSValueConst val) { return JS_ToInt32Free(ctx, pres, JS_DupValue(ctx, val)); } static inline int JS_ToUint32Free(JSContext *ctx, uint32_t *pres, JSValue val) { return JS_ToInt32Free(ctx, (int32_t *)pres, val); } static int JS_ToUint8ClampFree(JSContext *ctx, int32_t *pres, JSValue val) { uint32_t tag; int res; redo: tag = JS_VALUE_GET_NORM_TAG(val); switch(tag) { case JS_TAG_INT: case JS_TAG_BOOL: case JS_TAG_NULL: case JS_TAG_UNDEFINED: res = JS_VALUE_GET_INT(val); res = max_int(0, min_int(255, res)); break; case JS_TAG_FLOAT64: { double d = JS_VALUE_GET_FLOAT64(val); if (isnan(d)) { res = 0; } else { if (d < 0) res = 0; else if (d > 255) res = 255; else res = lrint(d); } } break; default: val = JS_ToNumberFree(ctx, val); if (JS_IsException(val)) { *pres = 0; return -1; } goto redo; } *pres = res; return 0; } static __exception int JS_ToArrayLengthFree(JSContext *ctx, uint32_t *plen, JSValue val, BOOL is_array_ctor) { uint32_t tag, len; tag = JS_VALUE_GET_TAG(val); switch(tag) { case JS_TAG_INT: case JS_TAG_BOOL: case JS_TAG_NULL: { int v; v = JS_VALUE_GET_INT(val); if (v < 0) goto fail; len = v; } break; default: if (JS_TAG_IS_FLOAT64(tag)) { double d; d = JS_VALUE_GET_FLOAT64(val); if (!(d >= 0 && d <= UINT32_MAX)) goto fail; len = (uint32_t)d; if (len != d) goto fail; } else { uint32_t len1; if (is_array_ctor) { val = JS_ToNumberFree(ctx, val); if (JS_IsException(val)) return -1; /* cannot recurse because val is a number */ if (JS_ToArrayLengthFree(ctx, &len, val, TRUE)) return -1; } else { /* legacy behavior: must do the conversion twice and compare */ if (JS_ToUint32(ctx, &len, val)) { JS_FreeValue(ctx, val); return -1; } val = JS_ToNumberFree(ctx, val); if (JS_IsException(val)) return -1; /* cannot recurse because val is a number */ if (JS_ToArrayLengthFree(ctx, &len1, val, FALSE)) return -1; if (len1 != len) { fail: JS_ThrowRangeError(ctx, "invalid array length"); return -1; } } } break; } *plen = len; return 0; } #define MAX_SAFE_INTEGER (((int64_t)1 << 53) - 1) static BOOL is_safe_integer(double d) { return isfinite(d) && floor(d) == d && fabs(d) <= (double)MAX_SAFE_INTEGER; } int JS_ToIndex(JSContext *ctx, uint64_t *plen, JSValueConst val) { int64_t v; if (JS_ToInt64Sat(ctx, &v, val)) return -1; if (v < 0 || v > MAX_SAFE_INTEGER) { JS_ThrowRangeError(ctx, "invalid array index"); *plen = 0; return -1; } *plen = v; return 0; } /* convert a value to a length between 0 and MAX_SAFE_INTEGER. return -1 for exception */ static __exception int JS_ToLengthFree(JSContext *ctx, int64_t *plen, JSValue val) { int res = JS_ToInt64Clamp(ctx, plen, val, 0, MAX_SAFE_INTEGER, 0); JS_FreeValue(ctx, val); return res; } /* Note: can return an exception */ static int JS_NumberIsInteger(JSContext *ctx, JSValueConst val) { double d; if (!JS_IsNumber(val)) return FALSE; if (unlikely(JS_ToFloat64(ctx, &d, val))) return -1; return isfinite(d) && floor(d) == d; } static BOOL JS_NumberIsNegativeOrMinusZero(JSContext *ctx, JSValueConst val) { uint32_t tag; tag = JS_VALUE_GET_NORM_TAG(val); switch(tag) { case JS_TAG_INT: { int v; v = JS_VALUE_GET_INT(val); return (v < 0); } case JS_TAG_FLOAT64: { JSFloat64Union u; u.d = JS_VALUE_GET_FLOAT64(val); return (u.u64 >> 63); } case JS_TAG_SHORT_BIG_INT: return (JS_VALUE_GET_SHORT_BIG_INT(val) < 0); case JS_TAG_BIG_INT: { JSBigInt *p = JS_VALUE_GET_PTR(val); return js_bigint_sign(p); } default: return FALSE; } } static JSValue js_bigint_to_string(JSContext *ctx, JSValueConst val) { return js_bigint_to_string1(ctx, val, 10); } static JSValue js_dtoa2(JSContext *ctx, double d, int radix, int n_digits, int flags) { char static_buf[128], *buf, *tmp_buf; int len, len_max; JSValue res; JSDTOATempMem dtoa_mem; len_max = js_dtoa_max_len(d, radix, n_digits, flags); /* longer buffer may be used if radix != 10 */ if (len_max > sizeof(static_buf) - 1) { tmp_buf = js_malloc(ctx, len_max + 1); if (!tmp_buf) return JS_EXCEPTION; buf = tmp_buf; } else { tmp_buf = NULL; buf = static_buf; } len = js_dtoa(buf, d, radix, n_digits, flags, &dtoa_mem); res = js_new_string8_len(ctx, buf, len); js_free(ctx, tmp_buf); return res; } static JSValue JS_ToStringInternal(JSContext *ctx, JSValueConst val, BOOL is_ToPropertyKey) { uint32_t tag; char buf[32]; tag = JS_VALUE_GET_NORM_TAG(val); switch(tag) { case JS_TAG_STRING: return JS_DupValue(ctx, val); case JS_TAG_STRING_ROPE: return js_linearize_string_rope(ctx, JS_DupValue(ctx, val)); case JS_TAG_INT: { size_t len; len = i32toa(buf, JS_VALUE_GET_INT(val)); return js_new_string8_len(ctx, buf, len); } break; case JS_TAG_BOOL: return JS_AtomToString(ctx, JS_VALUE_GET_BOOL(val) ? JS_ATOM_true : JS_ATOM_false); case JS_TAG_NULL: return JS_AtomToString(ctx, JS_ATOM_null); case JS_TAG_UNDEFINED: return JS_AtomToString(ctx, JS_ATOM_undefined); case JS_TAG_EXCEPTION: return JS_EXCEPTION; case JS_TAG_OBJECT: { JSValue val1, ret; val1 = JS_ToPrimitive(ctx, val, HINT_STRING); if (JS_IsException(val1)) return val1; ret = JS_ToStringInternal(ctx, val1, is_ToPropertyKey); JS_FreeValue(ctx, val1); return ret; } break; case JS_TAG_FUNCTION_BYTECODE: return js_new_string8(ctx, "[function bytecode]"); case JS_TAG_SYMBOL: if (is_ToPropertyKey) { return JS_DupValue(ctx, val); } else { return JS_ThrowTypeError(ctx, "cannot convert symbol to string"); } case JS_TAG_FLOAT64: return js_dtoa2(ctx, JS_VALUE_GET_FLOAT64(val), 10, 0, JS_DTOA_FORMAT_FREE); case JS_TAG_SHORT_BIG_INT: case JS_TAG_BIG_INT: return js_bigint_to_string(ctx, val); default: return js_new_string8(ctx, "[unsupported type]"); } } JSValue JS_ToString(JSContext *ctx, JSValueConst val) { return JS_ToStringInternal(ctx, val, FALSE); } static JSValue JS_ToStringFree(JSContext *ctx, JSValue val) { JSValue ret; ret = JS_ToString(ctx, val); JS_FreeValue(ctx, val); return ret; } static JSValue JS_ToLocaleStringFree(JSContext *ctx, JSValue val) { if (JS_IsUndefined(val) || JS_IsNull(val)) return JS_ToStringFree(ctx, val); return JS_InvokeFree(ctx, val, JS_ATOM_toLocaleString, 0, NULL); } JSValue JS_ToPropertyKey(JSContext *ctx, JSValueConst val) { return JS_ToStringInternal(ctx, val, TRUE); } static JSValue JS_ToStringCheckObject(JSContext *ctx, JSValueConst val) { uint32_t tag = JS_VALUE_GET_TAG(val); if (tag == JS_TAG_NULL || tag == JS_TAG_UNDEFINED) return JS_ThrowTypeError(ctx, "null or undefined are forbidden"); return JS_ToString(ctx, val); } #define JS_PRINT_MAX_DEPTH 8 typedef struct { JSRuntime *rt; JSContext *ctx; /* may be NULL */ JSPrintValueOptions options; JSPrintValueWrite *write_func; void *write_opaque; int level; JSObject *print_stack[JS_PRINT_MAX_DEPTH]; /* level values */ } JSPrintValueState; static void js_print_value(JSPrintValueState *s, JSValueConst val); static void js_putc(JSPrintValueState *s, char c) { s->write_func(s->write_opaque, &c, 1); } static void js_puts(JSPrintValueState *s, const char *str) { s->write_func(s->write_opaque, str, strlen(str)); } static void __attribute__((format(printf, 2, 3))) js_printf(JSPrintValueState *s, const char *fmt, ...) { va_list ap; char buf[256]; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); s->write_func(s->write_opaque, buf, strlen(buf)); } static void js_print_float64(JSPrintValueState *s, double d) { JSDTOATempMem dtoa_mem; char buf[32]; int len; len = js_dtoa(buf, d, 10, 0, JS_DTOA_FORMAT_FREE | JS_DTOA_MINUS_ZERO, &dtoa_mem); s->write_func(s->write_opaque, buf, len); } static uint32_t js_string_get_length(JSValueConst val) { if (JS_VALUE_GET_TAG(val) == JS_TAG_STRING) { JSString *p = JS_VALUE_GET_STRING(val); return p->len; } else if (JS_VALUE_GET_TAG(val) == JS_TAG_STRING_ROPE) { JSStringRope *r = JS_VALUE_GET_PTR(val); return r->len; } else { return 0; } } /* pretty print the first 'len' characters of 'p' */ static void js_print_string1(JSPrintValueState *s, JSString *p, int len, int sep) { uint8_t buf[UTF8_CHAR_LEN_MAX]; int l, i, c, c1; for(i = 0; i < len; i++) { c = string_get(p, i); switch(c) { case '\t': c = 't'; goto quote; case '\r': c = 'r'; goto quote; case '\n': c = 'n'; goto quote; case '\b': c = 'b'; goto quote; case '\f': c = 'f'; goto quote; case '\\': quote: js_putc(s, '\\'); js_putc(s, c); break; default: if (c == sep) goto quote; if (c >= 32 && c <= 126) { js_putc(s, c); } else if (c < 32 || (c >= 0x7f && c <= 0x9f)) { escape: js_printf(s, "\\u%04x", c); } else { if (is_hi_surrogate(c)) { if ((i + 1) >= len) goto escape; c1 = string_get(p, i + 1); if (!is_lo_surrogate(c1)) goto escape; i++; c = from_surrogate(c, c1); } else if (is_lo_surrogate(c)) { goto escape; } l = unicode_to_utf8(buf, c); s->write_func(s->write_opaque, (char *)buf, l); } break; } } } static void js_print_string_rec(JSPrintValueState *s, JSValueConst val, int sep, uint32_t pos) { if (JS_VALUE_GET_TAG(val) == JS_TAG_STRING) { JSString *p = JS_VALUE_GET_STRING(val); uint32_t len; if (pos < s->options.max_string_length) { len = min_uint32(p->len, s->options.max_string_length - pos); js_print_string1(s, p, len, sep); } } else if (JS_VALUE_GET_TAG(val) == JS_TAG_STRING_ROPE) { JSStringRope *r = JS_VALUE_GET_PTR(val); js_print_string_rec(s, r->left, sep, pos); js_print_string_rec(s, r->right, sep, pos + js_string_get_length(r->left)); } else { js_printf(s, "<invalid string tag %d>", (int)JS_VALUE_GET_TAG(val)); } } static void js_print_string(JSPrintValueState *s, JSValueConst val) { int sep; if (s->options.raw_dump && JS_VALUE_GET_TAG(val) == JS_TAG_STRING) { JSString *p = JS_VALUE_GET_STRING(val); js_printf(s, "%d", p->header.ref_count); sep = (p->header.ref_count == 1) ? '\"' : '\''; } else { sep = '\"'; } js_putc(s, sep); js_print_string_rec(s, val, sep, 0); js_putc(s, sep); if (js_string_get_length(val) > s->options.max_string_length) { uint32_t n = js_string_get_length(val) - s->options.max_string_length; js_printf(s, "... %u more character%s", n, n > 1 ? "s" : ""); } } static void js_print_raw_string(JSPrintValueState *s, JSValueConst val) { const char *cstr; size_t len; cstr = JS_ToCStringLen(s->ctx, &len, val); if (cstr) { s->write_func(s->write_opaque, cstr, len); JS_FreeCString(s->ctx, cstr); } } static BOOL is_ascii_ident(const JSString *p) { int i, c; if (p->len == 0) return FALSE; for(i = 0; i < p->len; i++) { c = string_get(p, i); if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_' || c == '$') || (c >= '0' && c <= '9' && i > 0))) return FALSE; } return TRUE; } static void js_print_atom(JSPrintValueState *s, JSAtom atom) { int i; if (__JS_AtomIsTaggedInt(atom)) { js_printf(s, "%u", __JS_AtomToUInt32(atom)); } else if (atom == JS_ATOM_NULL) { js_puts(s, "<null>"); } else { assert(atom < s->rt->atom_size); JSString *p; p = s->rt->atom_array[atom]; if (is_ascii_ident(p)) { for(i = 0; i < p->len; i++) { js_putc(s, string_get(p, i)); } } else { js_putc(s, '"'); js_print_string1(s, p, p->len, '\"'); js_putc(s, '"'); } } } /* return 0 if invalid length */ static uint32_t js_print_array_get_length(JSObject *p) { JSProperty *pr; JSShapeProperty *prs; JSValueConst val; prs = find_own_property(&pr, p, JS_ATOM_length); if (!prs) return 0; if ((prs->flags & JS_PROP_TMASK) != JS_PROP_NORMAL) return 0; val = pr->u.value; switch(JS_VALUE_GET_NORM_TAG(val)) { case JS_TAG_INT: return JS_VALUE_GET_INT(val); case JS_TAG_FLOAT64: return (uint32_t)JS_VALUE_GET_FLOAT64(val); default: return 0; } } static void js_print_comma(JSPrintValueState *s, int *pcomma_state) { switch(*pcomma_state) { case 0: break; case 1: js_printf(s, ", "); break; case 2: js_printf(s, " { "); break; } *pcomma_state = 1; } static void js_print_more_items(JSPrintValueState *s, int *pcomma_state, uint32_t n) { js_print_comma(s, pcomma_state); js_printf(s, "... %u more item%s", n, n > 1 ? "s" : ""); } /* similar to js_regexp_toString() but without side effect */ static void js_print_regexp(JSPrintValueState *s, JSObject *p1) { JSRegExp *re = &p1->u.regexp; JSString *p; int i, n, c, c2, bra, flags; static const char regexp_flags[] = { 'g', 'i', 'm', 's', 'u', 'y', 'd', 'v' }; if (!re->pattern || !re->bytecode) { /* the regexp fields are zeroed at init */ js_puts(s, "[uninitialized_regexp]"); return; } p = re->pattern; js_putc(s, '/'); if (p->len == 0) { js_puts(s, "(?:)"); } else { bra = 0; for (i = 0, n = p->len; i < n;) { c2 = -1; switch (c = string_get(p, i++)) { case '\\': if (i < n) c2 = string_get(p, i++); break; case ']': bra = 0; break; case '[': if (!bra) { if (i < n && string_get(p, i) == ']') c2 = string_get(p, i++); bra = 1; } break; case '\n': c = '\\'; c2 = 'n'; break; case '\r': c = '\\'; c2 = 'r'; break; case '/': if (!bra) { c = '\\'; c2 = '/'; } break; } js_putc(s, c); if (c2 >= 0) js_putc(s, c2); } } js_putc(s, '/'); flags = lre_get_flags(re->bytecode->u.str8); for(i = 0; i < countof(regexp_flags); i++) { if ((flags >> i) & 1) { js_putc(s, regexp_flags[i]); } } } /* similar to js_error_toString() but without side effect */ static void js_print_error(JSPrintValueState *s, JSObject *p) { const char *str; size_t len; str = get_prop_string(s->ctx, JS_MKPTR(JS_TAG_OBJECT, p), JS_ATOM_name); if (!str) { js_puts(s, "Error"); } else { js_puts(s, str); JS_FreeCString(s->ctx, str); } str = get_prop_string(s->ctx, JS_MKPTR(JS_TAG_OBJECT, p), JS_ATOM_message); if (str && str[0] != '\0') { js_puts(s, ": "); js_puts(s, str); } JS_FreeCString(s->ctx, str); /* dump the stack if present */ str = get_prop_string(s->ctx, JS_MKPTR(JS_TAG_OBJECT, p), JS_ATOM_stack); if (str) { js_putc(s, '\n'); /* XXX: should remove the last '\n' in stack as v8. SpiderMonkey does not do it */ len = strlen(str); if (len > 0 && str[len - 1] == '\n') len--; s->write_func(s->write_opaque, str, len); JS_FreeCString(s->ctx, str); } } static void js_print_object(JSPrintValueState *s, JSObject *p) { JSRuntime *rt = s->rt; JSShape *sh; JSShapeProperty *prs; JSProperty *pr; int comma_state; BOOL is_array; uint32_t i; comma_state = 0; is_array = FALSE; if (p->class_id == JS_CLASS_ARRAY) { is_array = TRUE; js_printf(s, "[ "); /* XXX: print array like properties even if not fast array */ if (p->fast_array) { uint32_t len, n, len1; len = js_print_array_get_length(p); len1 = min_uint32(p->u.array.count, s->options.max_item_count); for(i = 0; i < len1; i++) { js_print_comma(s, &comma_state); js_print_value(s, p->u.array.u.values[i]); } if (len1 < p->u.array.count) js_print_more_items(s, &comma_state, p->u.array.count - len1); if (p->u.array.count < len) { n = len - p->u.array.count; js_print_comma(s, &comma_state); js_printf(s, "<%u empty item%s>", n, n > 1 ? "s" : ""); } } } else if (p->class_id >= JS_CLASS_UINT8C_ARRAY && p->class_id <= JS_CLASS_FLOAT64_ARRAY) { uint32_t size = 1 << typed_array_size_log2(p->class_id); uint32_t len1; int64_t v; js_print_atom(s, rt->class_array[p->class_id].class_name); js_printf(s, "(%u) [ ", p->u.array.count); is_array = TRUE; len1 = min_uint32(p->u.array.count, s->options.max_item_count); for(i = 0; i < len1; i++) { const uint8_t *ptr = p->u.array.u.uint8_ptr + i * size; js_print_comma(s, &comma_state); switch(p->class_id) { case JS_CLASS_UINT8C_ARRAY: case JS_CLASS_UINT8_ARRAY: v = *ptr; goto ta_int64; case JS_CLASS_INT8_ARRAY: v = *(int8_t *)ptr; goto ta_int64; case JS_CLASS_INT16_ARRAY: v = *(int16_t *)ptr; goto ta_int64; case JS_CLASS_UINT16_ARRAY: v = *(uint16_t *)ptr; goto ta_int64; case JS_CLASS_INT32_ARRAY: v = *(int32_t *)ptr; goto ta_int64; case JS_CLASS_UINT32_ARRAY: v = *(uint32_t *)ptr; goto ta_int64; case JS_CLASS_BIG_INT64_ARRAY: v = *(int64_t *)ptr; ta_int64: js_printf(s, "%" PRId64, v); break; case JS_CLASS_BIG_UINT64_ARRAY: js_printf(s, "%" PRIu64, *(uint64_t *)ptr); break; case JS_CLASS_FLOAT16_ARRAY: js_print_float64(s, fromfp16(*(uint16_t *)ptr)); break; case JS_CLASS_FLOAT32_ARRAY: js_print_float64(s, *(float *)ptr); break; case JS_CLASS_FLOAT64_ARRAY: js_print_float64(s, *(double *)ptr); break; } } if (len1 < p->u.array.count) js_print_more_items(s, &comma_state, p->u.array.count - len1); } else if (p->class_id == JS_CLASS_BYTECODE_FUNCTION || (rt->class_array[p->class_id].call != NULL && p->class_id != JS_CLASS_PROXY)) { js_printf(s, "[Function"); /* XXX: allow dump without ctx */ if (!s->options.raw_dump && s->ctx) { const char *func_name_str; js_putc(s, ' '); func_name_str = get_prop_string(s->ctx, JS_MKPTR(JS_TAG_OBJECT, p), JS_ATOM_name); if (!func_name_str || func_name_str[0] == '\0') js_puts(s, "(anonymous)"); else js_puts(s, func_name_str); JS_FreeCString(s->ctx, func_name_str); } js_printf(s, "]"); comma_state = 2; } else if (p->class_id == JS_CLASS_MAP || p->class_id == JS_CLASS_SET) { JSMapState *ms = p->u.opaque; struct list_head *el; if (!ms) goto default_obj; js_print_atom(s, rt->class_array[p->class_id].class_name); js_printf(s, "(%u) { ", ms->record_count); i = 0; list_for_each(el, &ms->records) { JSMapRecord *mr = list_entry(el, JSMapRecord, link); js_print_comma(s, &comma_state); if (mr->empty) continue; js_print_value(s, mr->key); if (p->class_id == JS_CLASS_MAP) { js_printf(s, " => "); js_print_value(s, mr->value); } i++; if (i >= s->options.max_item_count) break; } if (i < ms->record_count) js_print_more_items(s, &comma_state, ms->record_count - i); } else if (p->class_id == JS_CLASS_REGEXP && s->ctx) { js_print_regexp(s, p); comma_state = 2; } else if (p->class_id == JS_CLASS_DATE && s->ctx) { /* get_date_string() has no side effect */ JSValue str = get_date_string(s->ctx, JS_MKPTR(JS_TAG_OBJECT, p), 0, NULL, 0x23); /* toISOString() */ if (JS_IsException(str)) goto default_obj; js_print_raw_string(s, str); JS_FreeValueRT(s->rt, str); comma_state = 2; } else if (p->class_id == JS_CLASS_ERROR && s->ctx) { js_print_error(s, p); comma_state = 2; } else { default_obj: if (p->class_id != JS_CLASS_OBJECT) { js_print_atom(s, rt->class_array[p->class_id].class_name); js_printf(s, " "); } js_printf(s, "{ "); } sh = p->shape; /* the shape can be NULL while freeing an object */ if (sh) { uint32_t j; j = 0; for(i = 0, prs = get_shape_prop(sh); i < sh->prop_count; i++, prs++) { if (prs->atom != JS_ATOM_NULL) { if (!(prs->flags & JS_PROP_ENUMERABLE) && !s->options.show_hidden) { continue; } if (j < s->options.max_item_count) { pr = &p->prop[i]; js_print_comma(s, &comma_state); js_print_atom(s, prs->atom); js_printf(s, ": "); /* XXX: autoinit property */ if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) { if (s->options.raw_dump) { js_printf(s, "[Getter %p Setter %p]", pr->u.getset.getter, pr->u.getset.setter); } else { if (pr->u.getset.getter && pr->u.getset.setter) { js_printf(s, "[Getter/Setter]"); } else if (pr->u.getset.setter) { js_printf(s, "[Setter]"); } else { js_printf(s, "[Getter]"); } } } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { if (s->options.raw_dump) { js_printf(s, "[varref %p]", (void *)pr->u.var_ref); } else { js_print_value(s, *pr->u.var_ref->pvalue); } } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { if (s->options.raw_dump) { js_printf(s, "[autoinit %p %d %p]", (void *)js_autoinit_get_realm(pr), js_autoinit_get_id(pr), (void *)pr->u.init.opaque); } else { /* XXX: could autoinit but need to restart the iteration */ js_printf(s, "[autoinit]"); } } else { js_print_value(s, pr->u.value); } } j++; } } if (j > s->options.max_item_count) js_print_more_items(s, &comma_state, j - s->options.max_item_count); } if (s->options.raw_dump && js_class_has_bytecode(p->class_id)) { JSFunctionBytecode *b = p->u.func.function_bytecode; if (b->closure_var_count) { JSVarRef **var_refs; var_refs = p->u.func.var_refs; js_print_comma(s, &comma_state); js_printf(s, "[[Closure]]: ["); for(i = 0; i < b->closure_var_count; i++) { if (i != 0) js_printf(s, ", "); js_print_value(s, var_refs[i]->value); } js_printf(s, " ]"); } if (p->u.func.home_object) { js_print_comma(s, &comma_state); js_printf(s, "[[HomeObject]]: "); js_print_value(s, JS_MKPTR(JS_TAG_OBJECT, p->u.func.home_object)); } } if (!is_array) { if (comma_state != 2) { js_printf(s, " }"); } } else { js_printf(s, " ]"); } } static int js_print_stack_index(JSPrintValueState *s, JSObject *p) { int i; for(i = 0; i < s->level; i++) if (s->print_stack[i] == p) return i; return -1; } static void js_print_value(JSPrintValueState *s, JSValueConst val) { uint32_t tag = JS_VALUE_GET_NORM_TAG(val); const char *str; switch(tag) { case JS_TAG_INT: js_printf(s, "%d", JS_VALUE_GET_INT(val)); break; case JS_TAG_BOOL: if (JS_VALUE_GET_BOOL(val)) str = "true"; else str = "false"; goto print_str; case JS_TAG_NULL: str = "null"; goto print_str; case JS_TAG_EXCEPTION: str = "exception"; goto print_str; case JS_TAG_UNINITIALIZED: str = "uninitialized"; goto print_str; case JS_TAG_UNDEFINED: str = "undefined"; print_str: js_puts(s, str); break; case JS_TAG_FLOAT64: js_print_float64(s, JS_VALUE_GET_FLOAT64(val)); break; case JS_TAG_SHORT_BIG_INT: js_printf(s, "%" PRId64 "n", (int64_t)JS_VALUE_GET_SHORT_BIG_INT(val)); break; case JS_TAG_BIG_INT: if (!s->options.raw_dump && s->ctx) { JSValue str = js_bigint_to_string(s->ctx, val); if (JS_IsException(str)) goto raw_bigint; js_print_raw_string(s, str); js_putc(s, 'n'); JS_FreeValueRT(s->rt, str); } else { JSBigInt *p; int sgn, i; raw_bigint: p = JS_VALUE_GET_PTR(val); /* In order to avoid allocations we just dump the limbs */ sgn = js_bigint_sign(p); if (sgn) js_printf(s, "BigInt.asIntN(%d,", p->len * JS_LIMB_BITS); js_printf(s, "0x"); for(i = p->len - 1; i >= 0; i--) { if (i != p->len - 1) js_putc(s, '_'); #if JS_LIMB_BITS == 32 js_printf(s, "%08x", p->tab[i]); #else js_printf(s, "%016" PRIx64, p->tab[i]); #endif } js_putc(s, 'n'); if (sgn) js_putc(s, ')'); } break; case JS_TAG_STRING: case JS_TAG_STRING_ROPE: if (s->options.raw_dump && tag == JS_TAG_STRING_ROPE) { JSStringRope *r = JS_VALUE_GET_STRING_ROPE(val); js_printf(s, "[rope len=%d depth=%d]", r->len, r->depth); } else { js_print_string(s, val); } break; case JS_TAG_FUNCTION_BYTECODE: { JSFunctionBytecode *b = JS_VALUE_GET_PTR(val); js_puts(s, "[bytecode "); js_print_atom(s, b->func_name); js_putc(s, ']'); } break; case JS_TAG_OBJECT: { JSObject *p = JS_VALUE_GET_OBJ(val); int idx; idx = js_print_stack_index(s, p); if (idx >= 0) { js_printf(s, "[circular %d]", idx); } else if (s->level < s->options.max_depth) { s->print_stack[s->level++] = p; js_print_object(s, JS_VALUE_GET_OBJ(val)); s->level--; } else { JSAtom atom = s->rt->class_array[p->class_id].class_name; js_putc(s, '['); js_print_atom(s, atom); if (s->options.raw_dump) { js_printf(s, " %p", (void *)p); } js_putc(s, ']'); } } break; case JS_TAG_SYMBOL: { JSAtomStruct *p = JS_VALUE_GET_PTR(val); js_puts(s, "Symbol("); js_print_atom(s, js_get_atom_index(s->rt, p)); js_putc(s, ')'); } break; case JS_TAG_MODULE: js_puts(s, "[module]"); break; default: js_printf(s, "[unknown tag %d]", tag); break; } } void JS_PrintValueSetDefaultOptions(JSPrintValueOptions *options) { memset(options, 0, sizeof(*options)); options->max_depth = 2; options->max_string_length = 1000; options->max_item_count = 100; } static void JS_PrintValueInternal(JSRuntime *rt, JSContext *ctx, JSPrintValueWrite *write_func, void *write_opaque, JSValueConst val, const JSPrintValueOptions *options) { JSPrintValueState ss, *s = &ss; if (options) s->options = *options; else JS_PrintValueSetDefaultOptions(&s->options); if (s->options.max_depth <= 0) s->options.max_depth = JS_PRINT_MAX_DEPTH; else s->options.max_depth = min_int(s->options.max_depth, JS_PRINT_MAX_DEPTH); if (s->options.max_string_length == 0) s->options.max_string_length = UINT32_MAX; if (s->options.max_item_count == 0) s->options.max_item_count = UINT32_MAX; s->rt = rt; s->ctx = ctx; s->write_func = write_func; s->write_opaque = write_opaque; s->level = 0; js_print_value(s, val); } void JS_PrintValueRT(JSRuntime *rt, JSPrintValueWrite *write_func, void *write_opaque, JSValueConst val, const JSPrintValueOptions *options) { JS_PrintValueInternal(rt, NULL, write_func, write_opaque, val, options); } void JS_PrintValue(JSContext *ctx, JSPrintValueWrite *write_func, void *write_opaque, JSValueConst val, const JSPrintValueOptions *options) { JS_PrintValueInternal(ctx->rt, ctx, write_func, write_opaque, val, options); } static void js_dump_value_write(void *opaque, const char *buf, size_t len) { FILE *fo = opaque; fwrite(buf, 1, len, fo); } static __maybe_unused void print_atom(JSContext *ctx, JSAtom atom) { JSPrintValueState ss, *s = &ss; memset(s, 0, sizeof(*s)); s->rt = ctx->rt; s->ctx = ctx; s->write_func = js_dump_value_write; s->write_opaque = stdout; js_print_atom(s, atom); } static __maybe_unused void JS_DumpAtom(JSContext *ctx, const char *str, JSAtom atom) { printf("%s=", str); print_atom(ctx, atom); printf("\n"); } static __maybe_unused void JS_DumpValue(JSContext *ctx, const char *str, JSValueConst val) { printf("%s=", str); JS_PrintValue(ctx, js_dump_value_write, stdout, val, NULL); printf("\n"); } static __maybe_unused void JS_DumpValueRT(JSRuntime *rt, const char *str, JSValueConst val) { printf("%s=", str); JS_PrintValueRT(rt, js_dump_value_write, stdout, val, NULL); printf("\n"); } static __maybe_unused void JS_DumpObjectHeader(JSRuntime *rt) { printf("%14s %4s %4s %14s %s\n", "ADDRESS", "REFS", "SHRF", "PROTO", "CONTENT"); } /* for debug only: dump an object without side effect */ static __maybe_unused void JS_DumpObject(JSRuntime *rt, JSObject *p) { JSShape *sh; JSPrintValueOptions options; /* XXX: should encode atoms with special characters */ sh = p->shape; /* the shape can be NULL while freeing an object */ printf("%14p %4d ", (void *)p, p->header.ref_count); if (sh) { printf("%3d%c %14p ", sh->header.ref_count, " *"[sh->is_hashed], (void *)sh->proto); } else { printf("%3s %14s ", "-", "-"); } JS_PrintValueSetDefaultOptions(&options); options.max_depth = 1; options.show_hidden = TRUE; options.raw_dump = TRUE; JS_PrintValueRT(rt, js_dump_value_write, stdout, JS_MKPTR(JS_TAG_OBJECT, p), &options); printf("\n"); } static __maybe_unused void JS_DumpGCObject(JSRuntime *rt, JSGCObjectHeader *p) { if (p->gc_obj_type == JS_GC_OBJ_TYPE_JS_OBJECT) { JS_DumpObject(rt, (JSObject *)p); } else { printf("%14p %4d ", (void *)p, p->ref_count); switch(p->gc_obj_type) { case JS_GC_OBJ_TYPE_FUNCTION_BYTECODE: printf("[function bytecode]"); break; case JS_GC_OBJ_TYPE_SHAPE: printf("[shape]"); break; case JS_GC_OBJ_TYPE_VAR_REF: printf("[var_ref]"); break; case JS_GC_OBJ_TYPE_ASYNC_FUNCTION: printf("[async_function]"); break; case JS_GC_OBJ_TYPE_JS_CONTEXT: printf("[js_context]"); break; case JS_GC_OBJ_TYPE_MODULE: printf("[module]"); break; default: printf("[unknown %d]", p->gc_obj_type); break; } printf("\n"); } } /* return -1 if exception (proxy case) or TRUE/FALSE */ // TODO: should take flags to make proxy resolution and exceptions optional int JS_IsArray(JSContext *ctx, JSValueConst val) { if (js_resolve_proxy(ctx, &val, TRUE)) return -1; if (JS_VALUE_GET_TAG(val) == JS_TAG_OBJECT) { JSObject *p = JS_VALUE_GET_OBJ(val); return p->class_id == JS_CLASS_ARRAY; } else { return FALSE; } } static double js_pow(double a, double b) { if (unlikely(!isfinite(b)) && fabs(a) == 1) { /* not compatible with IEEE 754 */ return JS_FLOAT64_NAN; } else { return pow(a, b); } } JSValue JS_NewBigInt64(JSContext *ctx, int64_t v) { #if JS_SHORT_BIG_INT_BITS == 64 return __JS_NewShortBigInt(ctx, v); #else if (v >= JS_SHORT_BIG_INT_MIN && v <= JS_SHORT_BIG_INT_MAX) { return __JS_NewShortBigInt(ctx, v); } else { JSBigInt *p; p = js_bigint_new_si64(ctx, v); if (!p) return JS_EXCEPTION; return JS_MKPTR(JS_TAG_BIG_INT, p); } #endif } JSValue JS_NewBigUint64(JSContext *ctx, uint64_t v) { if (v <= JS_SHORT_BIG_INT_MAX) { return __JS_NewShortBigInt(ctx, v); } else { JSBigInt *p; p = js_bigint_new_ui64(ctx, v); if (!p) return JS_EXCEPTION; return JS_MKPTR(JS_TAG_BIG_INT, p); } } /* return NaN if bad bigint literal */ static JSValue JS_StringToBigInt(JSContext *ctx, JSValue val) { const char *str, *p; size_t len; int flags; str = JS_ToCStringLen(ctx, &len, val); JS_FreeValue(ctx, val); if (!str) return JS_EXCEPTION; p = str; p += skip_spaces(p); if ((p - str) == len) { val = JS_NewBigInt64(ctx, 0); } else { flags = ATOD_INT_ONLY | ATOD_ACCEPT_BIN_OCT | ATOD_TYPE_BIG_INT; val = js_atof(ctx, p, &p, 0, flags); p += skip_spaces(p); if (!JS_IsException(val)) { if ((p - str) != len) { JS_FreeValue(ctx, val); val = JS_NAN; } } } JS_FreeCString(ctx, str); return val; } static JSValue JS_StringToBigIntErr(JSContext *ctx, JSValue val) { val = JS_StringToBigInt(ctx, val); if (JS_VALUE_IS_NAN(val)) return JS_ThrowSyntaxError(ctx, "invalid bigint literal"); return val; } /* JS Numbers are not allowed */ static JSValue JS_ToBigIntFree(JSContext *ctx, JSValue val) { uint32_t tag; redo: tag = JS_VALUE_GET_NORM_TAG(val); switch(tag) { case JS_TAG_SHORT_BIG_INT: case JS_TAG_BIG_INT: break; case JS_TAG_INT: case JS_TAG_NULL: case JS_TAG_UNDEFINED: case JS_TAG_FLOAT64: goto fail; case JS_TAG_BOOL: val = __JS_NewShortBigInt(ctx, JS_VALUE_GET_INT(val)); break; case JS_TAG_STRING: case JS_TAG_STRING_ROPE: val = JS_StringToBigIntErr(ctx, val); if (JS_IsException(val)) return val; goto redo; case JS_TAG_OBJECT: val = JS_ToPrimitiveFree(ctx, val, HINT_NUMBER); if (JS_IsException(val)) return val; goto redo; default: fail: JS_FreeValue(ctx, val); return JS_ThrowTypeError(ctx, "cannot convert to bigint"); } return val; } static JSValue JS_ToBigInt(JSContext *ctx, JSValueConst val) { return JS_ToBigIntFree(ctx, JS_DupValue(ctx, val)); } /* XXX: merge with JS_ToInt64Free with a specific flag ? */ static int JS_ToBigInt64Free(JSContext *ctx, int64_t *pres, JSValue val) { uint64_t res; val = JS_ToBigIntFree(ctx, val); if (JS_IsException(val)) { *pres = 0; return -1; } if (JS_VALUE_GET_TAG(val) == JS_TAG_SHORT_BIG_INT) { res = JS_VALUE_GET_SHORT_BIG_INT(val); } else { JSBigInt *p = JS_VALUE_GET_PTR(val); /* return the value mod 2^64 */ res = p->tab[0]; #if JS_LIMB_BITS == 32 if (p->len >= 2) res |= (uint64_t)p->tab[1] << 32; #endif JS_FreeValue(ctx, val); } *pres = res; return 0; } int JS_ToBigInt64(JSContext *ctx, int64_t *pres, JSValueConst val) { return JS_ToBigInt64Free(ctx, pres, JS_DupValue(ctx, val)); } static no_inline __exception int js_unary_arith_slow(JSContext *ctx, JSValue *sp, OPCodeEnum op) { JSValue op1; int v; uint32_t tag; JSBigIntBuf buf1; JSBigInt *p1; op1 = sp[-1]; /* fast path for float64 */ if (JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(op1))) goto handle_float64; op1 = JS_ToNumericFree(ctx, op1); if (JS_IsException(op1)) goto exception; tag = JS_VALUE_GET_TAG(op1); switch(tag) { case JS_TAG_INT: { int64_t v64; v64 = JS_VALUE_GET_INT(op1); switch(op) { case OP_inc: case OP_dec: v = 2 * (op - OP_dec) - 1; v64 += v; break; case OP_plus: break; case OP_neg: if (v64 == 0) { sp[-1] = __JS_NewFloat64(ctx, -0.0); return 0; } else { v64 = -v64; } break; default: abort(); } sp[-1] = JS_NewInt64(ctx, v64); } break; case JS_TAG_SHORT_BIG_INT: { int64_t v; v = JS_VALUE_GET_SHORT_BIG_INT(op1); switch(op) { case OP_plus: JS_ThrowTypeError(ctx, "bigint argument with unary +"); goto exception; case OP_inc: if (v == JS_SHORT_BIG_INT_MAX) goto bigint_slow_case; sp[-1] = __JS_NewShortBigInt(ctx, v + 1); break; case OP_dec: if (v == JS_SHORT_BIG_INT_MIN) goto bigint_slow_case; sp[-1] = __JS_NewShortBigInt(ctx, v - 1); break; case OP_neg: v = JS_VALUE_GET_SHORT_BIG_INT(op1); if (v == JS_SHORT_BIG_INT_MIN) { bigint_slow_case: p1 = js_bigint_set_short(&buf1, op1); goto bigint_slow_case1; } sp[-1] = __JS_NewShortBigInt(ctx, -v); break; default: abort(); } } break; case JS_TAG_BIG_INT: { JSBigInt *r; p1 = JS_VALUE_GET_PTR(op1); bigint_slow_case1: switch(op) { case OP_plus: JS_ThrowTypeError(ctx, "bigint argument with unary +"); JS_FreeValue(ctx, op1); goto exception; case OP_inc: case OP_dec: { JSBigIntBuf buf2; JSBigInt *p2; p2 = js_bigint_set_si(&buf2, 2 * (op - OP_dec) - 1); r = js_bigint_add(ctx, p1, p2, 0); } break; case OP_neg: r = js_bigint_neg(ctx, p1); break; case OP_not: r = js_bigint_not(ctx, p1); break; default: abort(); } JS_FreeValue(ctx, op1); if (!r) goto exception; sp[-1] = JS_CompactBigInt(ctx, r); } break; default: handle_float64: { double d; d = JS_VALUE_GET_FLOAT64(op1); switch(op) { case OP_inc: case OP_dec: v = 2 * (op - OP_dec) - 1; d += v; break; case OP_plus: break; case OP_neg: d = -d; break; default: abort(); } sp[-1] = __JS_NewFloat64(ctx, d); } break; } return 0; exception: sp[-1] = JS_UNDEFINED; return -1; } static __exception int js_post_inc_slow(JSContext *ctx, JSValue *sp, OPCodeEnum op) { JSValue op1; /* XXX: allow custom operators */ op1 = sp[-1]; op1 = JS_ToNumericFree(ctx, op1); if (JS_IsException(op1)) { sp[-1] = JS_UNDEFINED; return -1; } sp[-1] = op1; sp[0] = JS_DupValue(ctx, op1); return js_unary_arith_slow(ctx, sp + 1, op - OP_post_dec + OP_dec); } static no_inline int js_not_slow(JSContext *ctx, JSValue *sp) { JSValue op1; op1 = sp[-1]; op1 = JS_ToNumericFree(ctx, op1); if (JS_IsException(op1)) goto exception; if (JS_VALUE_GET_TAG(op1) == JS_TAG_SHORT_BIG_INT) { sp[-1] = __JS_NewShortBigInt(ctx, ~JS_VALUE_GET_SHORT_BIG_INT(op1)); } else if (JS_VALUE_GET_TAG(op1) == JS_TAG_BIG_INT) { JSBigInt *r; r = js_bigint_not(ctx, JS_VALUE_GET_PTR(op1)); JS_FreeValue(ctx, op1); if (!r) goto exception; sp[-1] = JS_CompactBigInt(ctx, r); } else { int32_t v1; if (unlikely(JS_ToInt32Free(ctx, &v1, op1))) goto exception; sp[-1] = JS_NewInt32(ctx, ~v1); } return 0; exception: sp[-1] = JS_UNDEFINED; return -1; } static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *sp, OPCodeEnum op) { JSValue op1, op2; uint32_t tag1, tag2; double d1, d2; op1 = sp[-2]; op2 = sp[-1]; tag1 = JS_VALUE_GET_NORM_TAG(op1); tag2 = JS_VALUE_GET_NORM_TAG(op2); /* fast path for float operations */ if (tag1 == JS_TAG_FLOAT64 && tag2 == JS_TAG_FLOAT64) { d1 = JS_VALUE_GET_FLOAT64(op1); d2 = JS_VALUE_GET_FLOAT64(op2); goto handle_float64; } /* fast path for short big int operations */ if (tag1 == JS_TAG_SHORT_BIG_INT && tag2 == JS_TAG_SHORT_BIG_INT) { js_slimb_t v1, v2; js_sdlimb_t v; v1 = JS_VALUE_GET_SHORT_BIG_INT(op1); v2 = JS_VALUE_GET_SHORT_BIG_INT(op2); switch(op) { case OP_sub: v = (js_sdlimb_t)v1 - (js_sdlimb_t)v2; break; case OP_mul: v = (js_sdlimb_t)v1 * (js_sdlimb_t)v2; break; case OP_div: if (v2 == 0 || ((js_limb_t)v1 == (js_limb_t)1 << (JS_LIMB_BITS - 1) && v2 == -1)) { goto slow_big_int; } sp[-2] = __JS_NewShortBigInt(ctx, v1 / v2); return 0; case OP_mod: if (v2 == 0 || ((js_limb_t)v1 == (js_limb_t)1 << (JS_LIMB_BITS - 1) && v2 == -1)) { goto slow_big_int; } sp[-2] = __JS_NewShortBigInt(ctx, v1 % v2); return 0; case OP_pow: goto slow_big_int; default: abort(); } if (likely(v >= JS_SHORT_BIG_INT_MIN && v <= JS_SHORT_BIG_INT_MAX)) { sp[-2] = __JS_NewShortBigInt(ctx, v); } else { JSBigInt *r = js_bigint_new_di(ctx, v); if (!r) goto exception; sp[-2] = JS_MKPTR(JS_TAG_BIG_INT, r); } return 0; } op1 = JS_ToNumericFree(ctx, op1); if (JS_IsException(op1)) { JS_FreeValue(ctx, op2); goto exception; } op2 = JS_ToNumericFree(ctx, op2); if (JS_IsException(op2)) { JS_FreeValue(ctx, op1); goto exception; } tag1 = JS_VALUE_GET_NORM_TAG(op1); tag2 = JS_VALUE_GET_NORM_TAG(op2); if (tag1 == JS_TAG_INT && tag2 == JS_TAG_INT) { int32_t v1, v2; int64_t v; v1 = JS_VALUE_GET_INT(op1); v2 = JS_VALUE_GET_INT(op2); switch(op) { case OP_sub: v = (int64_t)v1 - (int64_t)v2; break; case OP_mul: v = (int64_t)v1 * (int64_t)v2; if (v == 0 && (v1 | v2) < 0) { sp[-2] = __JS_NewFloat64(ctx, -0.0); return 0; } break; case OP_div: sp[-2] = JS_NewFloat64(ctx, (double)v1 / (double)v2); return 0; case OP_mod: if (v1 < 0 || v2 <= 0) { sp[-2] = JS_NewFloat64(ctx, fmod(v1, v2)); return 0; } else { v = (int64_t)v1 % (int64_t)v2; } break; case OP_pow: sp[-2] = JS_NewFloat64(ctx, js_pow(v1, v2)); return 0; default: abort(); } sp[-2] = JS_NewInt64(ctx, v); } else if ((tag1 == JS_TAG_SHORT_BIG_INT || tag1 == JS_TAG_BIG_INT) && (tag2 == JS_TAG_SHORT_BIG_INT || tag2 == JS_TAG_BIG_INT)) { JSBigInt *p1, *p2, *r; JSBigIntBuf buf1, buf2; slow_big_int: /* bigint result */ if (JS_VALUE_GET_TAG(op1) == JS_TAG_SHORT_BIG_INT) p1 = js_bigint_set_short(&buf1, op1); else p1 = JS_VALUE_GET_PTR(op1); if (JS_VALUE_GET_TAG(op2) == JS_TAG_SHORT_BIG_INT) p2 = js_bigint_set_short(&buf2, op2); else p2 = JS_VALUE_GET_PTR(op2); switch(op) { case OP_add: r = js_bigint_add(ctx, p1, p2, 0); break; case OP_sub: r = js_bigint_add(ctx, p1, p2, 1); break; case OP_mul: r = js_bigint_mul(ctx, p1, p2); break; case OP_div: r = js_bigint_divrem(ctx, p1, p2, FALSE); break; case OP_mod: r = js_bigint_divrem(ctx, p1, p2, TRUE); break; case OP_pow: r = js_bigint_pow(ctx, p1, p2); break; default: abort(); } JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); if (!r) goto exception; sp[-2] = JS_CompactBigInt(ctx, r); } else { double dr; /* float64 result */ if (JS_ToFloat64Free(ctx, &d1, op1)) { JS_FreeValue(ctx, op2); goto exception; } if (JS_ToFloat64Free(ctx, &d2, op2)) goto exception; handle_float64: switch(op) { case OP_sub: dr = d1 - d2; break; case OP_mul: dr = d1 * d2; break; case OP_div: dr = d1 / d2; break; case OP_mod: dr = fmod(d1, d2); break; case OP_pow: dr = js_pow(d1, d2); break; default: abort(); } sp[-2] = __JS_NewFloat64(ctx, dr); } return 0; exception: sp[-2] = JS_UNDEFINED; sp[-1] = JS_UNDEFINED; return -1; } static inline BOOL tag_is_string(uint32_t tag) { return tag == JS_TAG_STRING || tag == JS_TAG_STRING_ROPE; } static no_inline __exception int js_add_slow(JSContext *ctx, JSValue *sp) { JSValue op1, op2; uint32_t tag1, tag2; op1 = sp[-2]; op2 = sp[-1]; tag1 = JS_VALUE_GET_NORM_TAG(op1); tag2 = JS_VALUE_GET_NORM_TAG(op2); /* fast path for float64 */ if (tag1 == JS_TAG_FLOAT64 && tag2 == JS_TAG_FLOAT64) { double d1, d2; d1 = JS_VALUE_GET_FLOAT64(op1); d2 = JS_VALUE_GET_FLOAT64(op2); sp[-2] = __JS_NewFloat64(ctx, d1 + d2); return 0; } /* fast path for short bigint */ if (tag1 == JS_TAG_SHORT_BIG_INT && tag2 == JS_TAG_SHORT_BIG_INT) { js_slimb_t v1, v2; js_sdlimb_t v; v1 = JS_VALUE_GET_SHORT_BIG_INT(op1); v2 = JS_VALUE_GET_SHORT_BIG_INT(op2); v = (js_sdlimb_t)v1 + (js_sdlimb_t)v2; if (likely(v >= JS_SHORT_BIG_INT_MIN && v <= JS_SHORT_BIG_INT_MAX)) { sp[-2] = __JS_NewShortBigInt(ctx, v); } else { JSBigInt *r = js_bigint_new_di(ctx, v); if (!r) goto exception; sp[-2] = JS_MKPTR(JS_TAG_BIG_INT, r); } return 0; } if (tag1 == JS_TAG_OBJECT || tag2 == JS_TAG_OBJECT) { op1 = JS_ToPrimitiveFree(ctx, op1, HINT_NONE); if (JS_IsException(op1)) { JS_FreeValue(ctx, op2); goto exception; } op2 = JS_ToPrimitiveFree(ctx, op2, HINT_NONE); if (JS_IsException(op2)) { JS_FreeValue(ctx, op1); goto exception; } tag1 = JS_VALUE_GET_NORM_TAG(op1); tag2 = JS_VALUE_GET_NORM_TAG(op2); } if (tag_is_string(tag1) || tag_is_string(tag2)) { sp[-2] = JS_ConcatString(ctx, op1, op2); if (JS_IsException(sp[-2])) goto exception; return 0; } op1 = JS_ToNumericFree(ctx, op1); if (JS_IsException(op1)) { JS_FreeValue(ctx, op2); goto exception; } op2 = JS_ToNumericFree(ctx, op2); if (JS_IsException(op2)) { JS_FreeValue(ctx, op1); goto exception; } tag1 = JS_VALUE_GET_NORM_TAG(op1); tag2 = JS_VALUE_GET_NORM_TAG(op2); if (tag1 == JS_TAG_INT && tag2 == JS_TAG_INT) { int32_t v1, v2; int64_t v; v1 = JS_VALUE_GET_INT(op1); v2 = JS_VALUE_GET_INT(op2); v = (int64_t)v1 + (int64_t)v2; sp[-2] = JS_NewInt64(ctx, v); } else if ((tag1 == JS_TAG_BIG_INT || tag1 == JS_TAG_SHORT_BIG_INT) && (tag2 == JS_TAG_BIG_INT || tag2 == JS_TAG_SHORT_BIG_INT)) { JSBigInt *p1, *p2, *r; JSBigIntBuf buf1, buf2; /* bigint result */ if (JS_VALUE_GET_TAG(op1) == JS_TAG_SHORT_BIG_INT) p1 = js_bigint_set_short(&buf1, op1); else p1 = JS_VALUE_GET_PTR(op1); if (JS_VALUE_GET_TAG(op2) == JS_TAG_SHORT_BIG_INT) p2 = js_bigint_set_short(&buf2, op2); else p2 = JS_VALUE_GET_PTR(op2); r = js_bigint_add(ctx, p1, p2, 0); JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); if (!r) goto exception; sp[-2] = JS_CompactBigInt(ctx, r); } else { double d1, d2; /* float64 result */ if (JS_ToFloat64Free(ctx, &d1, op1)) { JS_FreeValue(ctx, op2); goto exception; } if (JS_ToFloat64Free(ctx, &d2, op2)) goto exception; sp[-2] = __JS_NewFloat64(ctx, d1 + d2); } return 0; exception: sp[-2] = JS_UNDEFINED; sp[-1] = JS_UNDEFINED; return -1; } static no_inline __exception int js_binary_logic_slow(JSContext *ctx, JSValue *sp, OPCodeEnum op) { JSValue op1, op2; uint32_t tag1, tag2; uint32_t v1, v2, r; op1 = sp[-2]; op2 = sp[-1]; tag1 = JS_VALUE_GET_NORM_TAG(op1); tag2 = JS_VALUE_GET_NORM_TAG(op2); if (tag1 == JS_TAG_SHORT_BIG_INT && tag2 == JS_TAG_SHORT_BIG_INT) { js_slimb_t v1, v2, v; js_sdlimb_t vd; v1 = JS_VALUE_GET_SHORT_BIG_INT(op1); v2 = JS_VALUE_GET_SHORT_BIG_INT(op2); /* bigint fast path */ switch(op) { case OP_and: v = v1 & v2; break; case OP_or: v = v1 | v2; break; case OP_xor: v = v1 ^ v2; break; case OP_sar: if (v2 > (JS_LIMB_BITS - 1)) { goto slow_big_int; } else if (v2 < 0) { if (v2 < -(JS_LIMB_BITS - 1)) goto slow_big_int; v2 = -v2; goto bigint_shl; } bigint_sar: v = v1 >> v2; break; case OP_shl: if (v2 > (JS_LIMB_BITS - 1)) { goto slow_big_int; } else if (v2 < 0) { if (v2 < -(JS_LIMB_BITS - 1)) goto slow_big_int; v2 = -v2; goto bigint_sar; } bigint_shl: vd = (js_dlimb_t)v1 << v2; if (likely(vd >= JS_SHORT_BIG_INT_MIN && vd <= JS_SHORT_BIG_INT_MAX)) { v = vd; } else { JSBigInt *r = js_bigint_new_di(ctx, vd); if (!r) goto exception; sp[-2] = JS_MKPTR(JS_TAG_BIG_INT, r); return 0; } break; default: abort(); } sp[-2] = __JS_NewShortBigInt(ctx, v); return 0; } op1 = JS_ToNumericFree(ctx, op1); if (JS_IsException(op1)) { JS_FreeValue(ctx, op2); goto exception; } op2 = JS_ToNumericFree(ctx, op2); if (JS_IsException(op2)) { JS_FreeValue(ctx, op1); goto exception; } tag1 = JS_VALUE_GET_TAG(op1); tag2 = JS_VALUE_GET_TAG(op2); if ((tag1 == JS_TAG_BIG_INT || tag1 == JS_TAG_SHORT_BIG_INT) && (tag2 == JS_TAG_BIG_INT || tag2 == JS_TAG_SHORT_BIG_INT)) { JSBigInt *p1, *p2, *r; JSBigIntBuf buf1, buf2; slow_big_int: if (JS_VALUE_GET_TAG(op1) == JS_TAG_SHORT_BIG_INT) p1 = js_bigint_set_short(&buf1, op1); else p1 = JS_VALUE_GET_PTR(op1); if (JS_VALUE_GET_TAG(op2) == JS_TAG_SHORT_BIG_INT) p2 = js_bigint_set_short(&buf2, op2); else p2 = JS_VALUE_GET_PTR(op2); switch(op) { case OP_and: case OP_or: case OP_xor: r = js_bigint_logic(ctx, p1, p2, op); break; case OP_shl: case OP_sar: { js_slimb_t shift; shift = js_bigint_get_si_sat(p2); if (shift > INT32_MAX) shift = INT32_MAX; else if (shift < -INT32_MAX) shift = -INT32_MAX; if (op == OP_sar) shift = -shift; if (shift >= 0) r = js_bigint_shl(ctx, p1, shift); else r = js_bigint_shr(ctx, p1, -shift); } break; default: abort(); } JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); if (!r) goto exception; sp[-2] = JS_CompactBigInt(ctx, r); } else { if (unlikely(JS_ToInt32Free(ctx, (int32_t *)&v1, op1))) { JS_FreeValue(ctx, op2); goto exception; } if (unlikely(JS_ToInt32Free(ctx, (int32_t *)&v2, op2))) goto exception; switch(op) { case OP_shl: r = v1 << (v2 & 0x1f); break; case OP_sar: r = (int)v1 >> (v2 & 0x1f); break; case OP_and: r = v1 & v2; break; case OP_or: r = v1 | v2; break; case OP_xor: r = v1 ^ v2; break; default: abort(); } sp[-2] = JS_NewInt32(ctx, r); } return 0; exception: sp[-2] = JS_UNDEFINED; sp[-1] = JS_UNDEFINED; return -1; } /* op1 must be a bigint or int. */ static JSBigInt *JS_ToBigIntBuf(JSContext *ctx, JSBigIntBuf *buf1, JSValue op1) { JSBigInt *p1; switch(JS_VALUE_GET_TAG(op1)) { case JS_TAG_INT: p1 = js_bigint_set_si(buf1, JS_VALUE_GET_INT(op1)); break; case JS_TAG_SHORT_BIG_INT: p1 = js_bigint_set_short(buf1, op1); break; case JS_TAG_BIG_INT: p1 = JS_VALUE_GET_PTR(op1); break; default: abort(); } return p1; } /* op1 and op2 must be numeric types and at least one must be a bigint. No exception is generated. */ static int js_compare_bigint(JSContext *ctx, OPCodeEnum op, JSValue op1, JSValue op2) { int res, val, tag1, tag2; JSBigIntBuf buf1, buf2; JSBigInt *p1, *p2; tag1 = JS_VALUE_GET_NORM_TAG(op1); tag2 = JS_VALUE_GET_NORM_TAG(op2); if ((tag1 == JS_TAG_SHORT_BIG_INT || tag1 == JS_TAG_INT) && (tag2 == JS_TAG_SHORT_BIG_INT || tag2 == JS_TAG_INT)) { /* fast path */ js_slimb_t v1, v2; if (tag1 == JS_TAG_INT) v1 = JS_VALUE_GET_INT(op1); else v1 = JS_VALUE_GET_SHORT_BIG_INT(op1); if (tag2 == JS_TAG_INT) v2 = JS_VALUE_GET_INT(op2); else v2 = JS_VALUE_GET_SHORT_BIG_INT(op2); val = (v1 > v2) - (v1 < v2); } else { if (tag1 == JS_TAG_FLOAT64) { p2 = JS_ToBigIntBuf(ctx, &buf2, op2); val = js_bigint_float64_cmp(ctx, p2, JS_VALUE_GET_FLOAT64(op1)); if (val == 2) goto unordered; val = -val; } else if (tag2 == JS_TAG_FLOAT64) { p1 = JS_ToBigIntBuf(ctx, &buf1, op1); val = js_bigint_float64_cmp(ctx, p1, JS_VALUE_GET_FLOAT64(op2)); if (val == 2) { unordered: JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); return FALSE; } } else { p1 = JS_ToBigIntBuf(ctx, &buf1, op1); p2 = JS_ToBigIntBuf(ctx, &buf2, op2); val = js_bigint_cmp(ctx, p1, p2); } JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); } switch(op) { case OP_lt: res = val < 0; break; case OP_lte: res = val <= 0; break; case OP_gt: res = val > 0; break; case OP_gte: res = val >= 0; break; case OP_eq: res = val == 0; break; default: abort(); } return res; } static no_inline int js_relational_slow(JSContext *ctx, JSValue *sp, OPCodeEnum op) { JSValue op1, op2; int res; uint32_t tag1, tag2; op1 = sp[-2]; op2 = sp[-1]; tag1 = JS_VALUE_GET_NORM_TAG(op1); tag2 = JS_VALUE_GET_NORM_TAG(op2); op1 = JS_ToPrimitiveFree(ctx, op1, HINT_NUMBER); if (JS_IsException(op1)) { JS_FreeValue(ctx, op2); goto exception; } op2 = JS_ToPrimitiveFree(ctx, op2, HINT_NUMBER); if (JS_IsException(op2)) { JS_FreeValue(ctx, op1); goto exception; } tag1 = JS_VALUE_GET_NORM_TAG(op1); tag2 = JS_VALUE_GET_NORM_TAG(op2); if (tag_is_string(tag1) && tag_is_string(tag2)) { if (tag1 == JS_TAG_STRING && tag2 == JS_TAG_STRING) { res = js_string_compare(ctx, JS_VALUE_GET_STRING(op1), JS_VALUE_GET_STRING(op2)); } else { res = js_string_rope_compare(ctx, op1, op2, FALSE); } switch(op) { case OP_lt: res = (res < 0); break; case OP_lte: res = (res <= 0); break; case OP_gt: res = (res > 0); break; default: case OP_gte: res = (res >= 0); break; } JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); } else if ((tag1 <= JS_TAG_NULL || tag1 == JS_TAG_FLOAT64) && (tag2 <= JS_TAG_NULL || tag2 == JS_TAG_FLOAT64)) { /* fast path for float64/int */ goto float64_compare; } else { if ((((tag1 == JS_TAG_BIG_INT || tag1 == JS_TAG_SHORT_BIG_INT) && tag_is_string(tag2)) || ((tag2 == JS_TAG_BIG_INT || tag2 == JS_TAG_SHORT_BIG_INT) && tag_is_string(tag1)))) { if (tag_is_string(tag1)) { op1 = JS_StringToBigInt(ctx, op1); if (JS_VALUE_GET_TAG(op1) != JS_TAG_BIG_INT && JS_VALUE_GET_TAG(op1) != JS_TAG_SHORT_BIG_INT) goto invalid_bigint_string; } if (tag_is_string(tag2)) { op2 = JS_StringToBigInt(ctx, op2); if (JS_VALUE_GET_TAG(op2) != JS_TAG_BIG_INT && JS_VALUE_GET_TAG(op2) != JS_TAG_SHORT_BIG_INT) { invalid_bigint_string: JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); res = FALSE; goto done; } } } else { op1 = JS_ToNumericFree(ctx, op1); if (JS_IsException(op1)) { JS_FreeValue(ctx, op2); goto exception; } op2 = JS_ToNumericFree(ctx, op2); if (JS_IsException(op2)) { JS_FreeValue(ctx, op1); goto exception; } } tag1 = JS_VALUE_GET_NORM_TAG(op1); tag2 = JS_VALUE_GET_NORM_TAG(op2); if (tag1 == JS_TAG_BIG_INT || tag1 == JS_TAG_SHORT_BIG_INT || tag2 == JS_TAG_BIG_INT || tag2 == JS_TAG_SHORT_BIG_INT) { res = js_compare_bigint(ctx, op, op1, op2); } else { double d1, d2; float64_compare: /* can use floating point comparison */ if (tag1 == JS_TAG_FLOAT64) { d1 = JS_VALUE_GET_FLOAT64(op1); } else { d1 = JS_VALUE_GET_INT(op1); } if (tag2 == JS_TAG_FLOAT64) { d2 = JS_VALUE_GET_FLOAT64(op2); } else { d2 = JS_VALUE_GET_INT(op2); } switch(op) { case OP_lt: res = (d1 < d2); /* if NaN return false */ break; case OP_lte: res = (d1 <= d2); /* if NaN return false */ break; case OP_gt: res = (d1 > d2); /* if NaN return false */ break; default: case OP_gte: res = (d1 >= d2); /* if NaN return false */ break; } } } done: sp[-2] = JS_NewBool(ctx, res); return 0; exception: sp[-2] = JS_UNDEFINED; sp[-1] = JS_UNDEFINED; return -1; } static BOOL tag_is_number(uint32_t tag) { return (tag == JS_TAG_INT || tag == JS_TAG_FLOAT64 || tag == JS_TAG_BIG_INT || tag == JS_TAG_SHORT_BIG_INT); } static no_inline __exception int js_eq_slow(JSContext *ctx, JSValue *sp, BOOL is_neq) { JSValue op1, op2; int res; uint32_t tag1, tag2; op1 = sp[-2]; op2 = sp[-1]; redo: tag1 = JS_VALUE_GET_NORM_TAG(op1); tag2 = JS_VALUE_GET_NORM_TAG(op2); if (tag_is_number(tag1) && tag_is_number(tag2)) { if (tag1 == JS_TAG_INT && tag2 == JS_TAG_INT) { res = JS_VALUE_GET_INT(op1) == JS_VALUE_GET_INT(op2); } else if ((tag1 == JS_TAG_FLOAT64 && (tag2 == JS_TAG_INT || tag2 == JS_TAG_FLOAT64)) || (tag2 == JS_TAG_FLOAT64 && (tag1 == JS_TAG_INT || tag1 == JS_TAG_FLOAT64))) { double d1, d2; if (tag1 == JS_TAG_FLOAT64) { d1 = JS_VALUE_GET_FLOAT64(op1); } else { d1 = JS_VALUE_GET_INT(op1); } if (tag2 == JS_TAG_FLOAT64) { d2 = JS_VALUE_GET_FLOAT64(op2); } else { d2 = JS_VALUE_GET_INT(op2); } res = (d1 == d2); } else { res = js_compare_bigint(ctx, OP_eq, op1, op2); } } else if (tag1 == tag2) { res = js_strict_eq2(ctx, op1, op2, JS_EQ_STRICT); } else if ((tag1 == JS_TAG_NULL && tag2 == JS_TAG_UNDEFINED) || (tag2 == JS_TAG_NULL && tag1 == JS_TAG_UNDEFINED)) { res = TRUE; } else if (tag_is_string(tag1) && tag_is_string(tag2)) { /* needed when comparing strings and ropes */ res = js_strict_eq2(ctx, op1, op2, JS_EQ_STRICT); } else if ((tag_is_string(tag1) && tag_is_number(tag2)) || (tag_is_string(tag2) && tag_is_number(tag1))) { if (tag1 == JS_TAG_BIG_INT || tag1 == JS_TAG_SHORT_BIG_INT || tag2 == JS_TAG_BIG_INT || tag2 == JS_TAG_SHORT_BIG_INT) { if (tag_is_string(tag1)) { op1 = JS_StringToBigInt(ctx, op1); if (JS_VALUE_GET_TAG(op1) != JS_TAG_BIG_INT && JS_VALUE_GET_TAG(op1) != JS_TAG_SHORT_BIG_INT) goto invalid_bigint_string; } if (tag_is_string(tag2)) { op2 = JS_StringToBigInt(ctx, op2); if (JS_VALUE_GET_TAG(op2) != JS_TAG_BIG_INT && JS_VALUE_GET_TAG(op2) != JS_TAG_SHORT_BIG_INT ) { invalid_bigint_string: JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); res = FALSE; goto done; } } } else { op1 = JS_ToNumericFree(ctx, op1); if (JS_IsException(op1)) { JS_FreeValue(ctx, op2); goto exception; } op2 = JS_ToNumericFree(ctx, op2); if (JS_IsException(op2)) { JS_FreeValue(ctx, op1); goto exception; } } res = js_strict_eq2(ctx, op1, op2, JS_EQ_STRICT); } else if (tag1 == JS_TAG_BOOL) { op1 = JS_NewInt32(ctx, JS_VALUE_GET_INT(op1)); goto redo; } else if (tag2 == JS_TAG_BOOL) { op2 = JS_NewInt32(ctx, JS_VALUE_GET_INT(op2)); goto redo; } else if ((tag1 == JS_TAG_OBJECT && (tag_is_number(tag2) || tag_is_string(tag2) || tag2 == JS_TAG_SYMBOL)) || (tag2 == JS_TAG_OBJECT && (tag_is_number(tag1) || tag_is_string(tag1) || tag1 == JS_TAG_SYMBOL))) { op1 = JS_ToPrimitiveFree(ctx, op1, HINT_NONE); if (JS_IsException(op1)) { JS_FreeValue(ctx, op2); goto exception; } op2 = JS_ToPrimitiveFree(ctx, op2, HINT_NONE); if (JS_IsException(op2)) { JS_FreeValue(ctx, op1); goto exception; } goto redo; } else { /* IsHTMLDDA object is equivalent to undefined for '==' and '!=' */ if ((JS_IsHTMLDDA(ctx, op1) && (tag2 == JS_TAG_NULL || tag2 == JS_TAG_UNDEFINED)) || (JS_IsHTMLDDA(ctx, op2) && (tag1 == JS_TAG_NULL || tag1 == JS_TAG_UNDEFINED))) { res = TRUE; } else { res = FALSE; } JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); } done: sp[-2] = JS_NewBool(ctx, res ^ is_neq); return 0; exception: sp[-2] = JS_UNDEFINED; sp[-1] = JS_UNDEFINED; return -1; } static no_inline int js_shr_slow(JSContext *ctx, JSValue *sp) { JSValue op1, op2; uint32_t v1, v2, r; op1 = sp[-2]; op2 = sp[-1]; op1 = JS_ToNumericFree(ctx, op1); if (JS_IsException(op1)) { JS_FreeValue(ctx, op2); goto exception; } op2 = JS_ToNumericFree(ctx, op2); if (JS_IsException(op2)) { JS_FreeValue(ctx, op1); goto exception; } if (JS_VALUE_GET_TAG(op1) == JS_TAG_BIG_INT || JS_VALUE_GET_TAG(op1) == JS_TAG_SHORT_BIG_INT || JS_VALUE_GET_TAG(op2) == JS_TAG_BIG_INT || JS_VALUE_GET_TAG(op2) == JS_TAG_SHORT_BIG_INT) { JS_ThrowTypeError(ctx, "bigint operands are forbidden for >>>"); JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); goto exception; } /* cannot give an exception */ JS_ToUint32Free(ctx, &v1, op1); JS_ToUint32Free(ctx, &v2, op2); r = v1 >> (v2 & 0x1f); sp[-2] = JS_NewUint32(ctx, r); return 0; exception: sp[-2] = JS_UNDEFINED; sp[-1] = JS_UNDEFINED; return -1; } /* XXX: Should take JSValueConst arguments */ static BOOL js_strict_eq2(JSContext *ctx, JSValue op1, JSValue op2, JSStrictEqModeEnum eq_mode) { BOOL res; int tag1, tag2; double d1, d2; tag1 = JS_VALUE_GET_NORM_TAG(op1); tag2 = JS_VALUE_GET_NORM_TAG(op2); switch(tag1) { case JS_TAG_BOOL: if (tag1 != tag2) { res = FALSE; } else { res = JS_VALUE_GET_INT(op1) == JS_VALUE_GET_INT(op2); goto done_no_free; } break; case JS_TAG_NULL: case JS_TAG_UNDEFINED: res = (tag1 == tag2); break; case JS_TAG_STRING: case JS_TAG_STRING_ROPE: { if (!tag_is_string(tag2)) { res = FALSE; } else if (tag1 == JS_TAG_STRING && tag2 == JS_TAG_STRING) { res = js_string_eq(ctx, JS_VALUE_GET_STRING(op1), JS_VALUE_GET_STRING(op2)); } else { res = (js_string_rope_compare(ctx, op1, op2, TRUE) == 0); } } break; case JS_TAG_SYMBOL: { JSAtomStruct *p1, *p2; if (tag1 != tag2) { res = FALSE; } else { p1 = JS_VALUE_GET_PTR(op1); p2 = JS_VALUE_GET_PTR(op2); res = (p1 == p2); } } break; case JS_TAG_OBJECT: if (tag1 != tag2) res = FALSE; else res = JS_VALUE_GET_OBJ(op1) == JS_VALUE_GET_OBJ(op2); break; case JS_TAG_INT: d1 = JS_VALUE_GET_INT(op1); if (tag2 == JS_TAG_INT) { d2 = JS_VALUE_GET_INT(op2); goto number_test; } else if (tag2 == JS_TAG_FLOAT64) { d2 = JS_VALUE_GET_FLOAT64(op2); goto number_test; } else { res = FALSE; } break; case JS_TAG_FLOAT64: d1 = JS_VALUE_GET_FLOAT64(op1); if (tag2 == JS_TAG_FLOAT64) { d2 = JS_VALUE_GET_FLOAT64(op2); } else if (tag2 == JS_TAG_INT) { d2 = JS_VALUE_GET_INT(op2); } else { res = FALSE; break; } number_test: if (unlikely(eq_mode >= JS_EQ_SAME_VALUE)) { JSFloat64Union u1, u2; /* NaN is not always normalized, so this test is necessary */ if (isnan(d1) || isnan(d2)) { res = isnan(d1) == isnan(d2); } else if (eq_mode == JS_EQ_SAME_VALUE_ZERO) { res = (d1 == d2); /* +0 == -0 */ } else { u1.d = d1; u2.d = d2; res = (u1.u64 == u2.u64); /* +0 != -0 */ } } else { res = (d1 == d2); /* if NaN return false and +0 == -0 */ } goto done_no_free; case JS_TAG_SHORT_BIG_INT: case JS_TAG_BIG_INT: { JSBigIntBuf buf1, buf2; JSBigInt *p1, *p2; if (tag2 != JS_TAG_SHORT_BIG_INT && tag2 != JS_TAG_BIG_INT) { res = FALSE; break; } if (JS_VALUE_GET_TAG(op1) == JS_TAG_SHORT_BIG_INT) p1 = js_bigint_set_short(&buf1, op1); else p1 = JS_VALUE_GET_PTR(op1); if (JS_VALUE_GET_TAG(op2) == JS_TAG_SHORT_BIG_INT) p2 = js_bigint_set_short(&buf2, op2); else p2 = JS_VALUE_GET_PTR(op2); res = (js_bigint_cmp(ctx, p1, p2) == 0); } break; default: res = FALSE; break; } JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); done_no_free: return res; } static BOOL js_strict_eq(JSContext *ctx, JSValueConst op1, JSValueConst op2) { return js_strict_eq2(ctx, JS_DupValue(ctx, op1), JS_DupValue(ctx, op2), JS_EQ_STRICT); } BOOL JS_StrictEq(JSContext *ctx, JSValueConst op1, JSValueConst op2) { return js_strict_eq(ctx, op1, op2); } static BOOL js_same_value(JSContext *ctx, JSValueConst op1, JSValueConst op2) { return js_strict_eq2(ctx, JS_DupValue(ctx, op1), JS_DupValue(ctx, op2), JS_EQ_SAME_VALUE); } BOOL JS_SameValue(JSContext *ctx, JSValueConst op1, JSValueConst op2) { return js_same_value(ctx, op1, op2); } static BOOL js_same_value_zero(JSContext *ctx, JSValueConst op1, JSValueConst op2) { return js_strict_eq2(ctx, JS_DupValue(ctx, op1), JS_DupValue(ctx, op2), JS_EQ_SAME_VALUE_ZERO); } BOOL JS_SameValueZero(JSContext *ctx, JSValueConst op1, JSValueConst op2) { return js_same_value_zero(ctx, op1, op2); } static no_inline int js_strict_eq_slow(JSContext *ctx, JSValue *sp, BOOL is_neq) { BOOL res; res = js_strict_eq2(ctx, sp[-2], sp[-1], JS_EQ_STRICT); sp[-2] = JS_NewBool(ctx, res ^ is_neq); return 0; } static __exception int js_operator_in(JSContext *ctx, JSValue *sp) { JSValue op1, op2; JSAtom atom; int ret; op1 = sp[-2]; op2 = sp[-1]; if (JS_VALUE_GET_TAG(op2) != JS_TAG_OBJECT) { JS_ThrowTypeError(ctx, "invalid 'in' operand"); return -1; } atom = JS_ValueToAtom(ctx, op1); if (unlikely(atom == JS_ATOM_NULL)) return -1; ret = JS_HasProperty(ctx, op2, atom); JS_FreeAtom(ctx, atom); if (ret < 0) return -1; JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); sp[-2] = JS_NewBool(ctx, ret); return 0; } static __exception int js_operator_private_in(JSContext *ctx, JSValue *sp) { JSValue op1, op2; int ret; op1 = sp[-2]; /* object */ op2 = sp[-1]; /* field name or method function */ if (JS_VALUE_GET_TAG(op1) != JS_TAG_OBJECT) { JS_ThrowTypeError(ctx, "invalid 'in' operand"); return -1; } if (JS_IsObject(op2)) { /* method: use the brand */ ret = JS_CheckBrand(ctx, op1, op2); if (ret < 0) return -1; } else { JSAtom atom; JSObject *p; JSShapeProperty *prs; JSProperty *pr; /* field */ atom = JS_ValueToAtom(ctx, op2); if (unlikely(atom == JS_ATOM_NULL)) return -1; p = JS_VALUE_GET_OBJ(op1); prs = find_own_property(&pr, p, atom); JS_FreeAtom(ctx, atom); ret = (prs != NULL); } JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); sp[-2] = JS_NewBool(ctx, ret); return 0; } static __exception int js_has_unscopable(JSContext *ctx, JSValueConst obj, JSAtom atom) { JSValue arr, val; int ret; arr = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_unscopables); if (JS_IsException(arr)) return -1; ret = 0; if (JS_IsObject(arr)) { val = JS_GetProperty(ctx, arr, atom); ret = JS_ToBoolFree(ctx, val); } JS_FreeValue(ctx, arr); return ret; } static __exception int js_operator_instanceof(JSContext *ctx, JSValue *sp) { JSValue op1, op2; BOOL ret; op1 = sp[-2]; op2 = sp[-1]; ret = JS_IsInstanceOf(ctx, op1, op2); if (ret < 0) return ret; JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); sp[-2] = JS_NewBool(ctx, ret); return 0; } static __exception int js_operator_typeof(JSContext *ctx, JSValueConst op1) { JSAtom atom; uint32_t tag; tag = JS_VALUE_GET_NORM_TAG(op1); switch(tag) { case JS_TAG_SHORT_BIG_INT: case JS_TAG_BIG_INT: atom = JS_ATOM_bigint; break; case JS_TAG_INT: case JS_TAG_FLOAT64: atom = JS_ATOM_number; break; case JS_TAG_UNDEFINED: atom = JS_ATOM_undefined; break; case JS_TAG_BOOL: atom = JS_ATOM_boolean; break; case JS_TAG_STRING: case JS_TAG_STRING_ROPE: atom = JS_ATOM_string; break; case JS_TAG_OBJECT: { JSObject *p; p = JS_VALUE_GET_OBJ(op1); if (unlikely(p->is_HTMLDDA)) atom = JS_ATOM_undefined; else if (JS_IsFunction(ctx, op1)) atom = JS_ATOM_function; else goto obj_type; } break; case JS_TAG_NULL: obj_type: atom = JS_ATOM_object; break; case JS_TAG_SYMBOL: atom = JS_ATOM_symbol; break; default: atom = JS_ATOM_unknown; break; } return atom; } static __exception int js_operator_delete(JSContext *ctx, JSValue *sp) { JSValue op1, op2; JSAtom atom; int ret; op1 = sp[-2]; op2 = sp[-1]; atom = JS_ValueToAtom(ctx, op2); if (unlikely(atom == JS_ATOM_NULL)) return -1; ret = JS_DeleteProperty(ctx, op1, atom, JS_PROP_THROW_STRICT); JS_FreeAtom(ctx, atom); if (unlikely(ret < 0)) return -1; JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); sp[-2] = JS_NewBool(ctx, ret); return 0; } /* XXX: not 100% compatible, but mozilla seems to use a similar implementation to ensure that caller in non strict mode does not throw (ES5 compatibility) */ static JSValue js_throw_type_error(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSFunctionBytecode *b = JS_GetFunctionBytecode(this_val); if (!b || (b->js_mode & JS_MODE_STRICT) || !b->has_prototype || argc >= 1) { return JS_ThrowTypeError(ctx, "invalid property access"); } return JS_UNDEFINED; } static JSValue js_function_proto_fileName(JSContext *ctx, JSValueConst this_val) { JSFunctionBytecode *b = JS_GetFunctionBytecode(this_val); if (b && b->has_debug) { return JS_AtomToString(ctx, b->debug.filename); } return JS_UNDEFINED; } static JSValue js_function_proto_lineNumber(JSContext *ctx, JSValueConst this_val, int is_col) { JSFunctionBytecode *b = JS_GetFunctionBytecode(this_val); if (b && b->has_debug) { int line_num, col_num; line_num = find_line_num(ctx, b, -1, &col_num); if (is_col) return JS_NewInt32(ctx, col_num); else return JS_NewInt32(ctx, line_num); } return JS_UNDEFINED; } static int js_arguments_define_own_property(JSContext *ctx, JSValueConst this_obj, JSAtom prop, JSValueConst val, JSValueConst getter, JSValueConst setter, int flags) { JSObject *p; uint32_t idx; p = JS_VALUE_GET_OBJ(this_obj); /* convert to normal array when redefining an existing numeric field */ if (p->fast_array && JS_AtomIsArrayIndex(ctx, &idx, prop) && idx < p->u.array.count) { if (convert_fast_array_to_array(ctx, p)) return -1; } /* run the default define own property */ return JS_DefineProperty(ctx, this_obj, prop, val, getter, setter, flags | JS_PROP_NO_EXOTIC); } static const JSClassExoticMethods js_arguments_exotic_methods = { .define_own_property = js_arguments_define_own_property, }; static JSValue js_build_arguments(JSContext *ctx, int argc, JSValueConst *argv) { JSValue val, *tab; JSProperty props[3]; JSObject *p; int i; props[0].u.value = JS_NewInt32(ctx, argc); /* length */ props[1].u.value = JS_DupValue(ctx, ctx->array_proto_values); /* Symbol.iterator */ props[2].u.getset.getter = JS_VALUE_GET_OBJ(JS_DupValue(ctx, ctx->throw_type_error)); /* callee */ props[2].u.getset.setter = JS_VALUE_GET_OBJ(JS_DupValue(ctx, ctx->throw_type_error)); /* callee */ val = JS_NewObjectFromShape(ctx, js_dup_shape(ctx->arguments_shape), JS_CLASS_ARGUMENTS, props); if (JS_IsException(val)) return val; p = JS_VALUE_GET_OBJ(val); /* initialize the fast array part */ tab = NULL; if (argc > 0) { tab = js_malloc(ctx, sizeof(tab[0]) * argc); if (!tab) goto fail; for(i = 0; i < argc; i++) { tab[i] = JS_DupValue(ctx, argv[i]); } } p->u.array.u.values = tab; p->u.array.count = argc; return val; fail: JS_FreeValue(ctx, val); return JS_EXCEPTION; } #define GLOBAL_VAR_OFFSET 0x40000000 #define ARGUMENT_VAR_OFFSET 0x20000000 static void js_mapped_arguments_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); JSVarRef **var_refs = p->u.array.u.var_refs; int i; for(i = 0; i < p->u.array.count; i++) free_var_ref(rt, var_refs[i]); js_free_rt(rt, var_refs); } static void js_mapped_arguments_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); JSVarRef **var_refs = p->u.array.u.var_refs; int i; for(i = 0; i < p->u.array.count; i++) mark_func(rt, &var_refs[i]->header); } /* legacy arguments object: add references to the function arguments */ static JSValue js_build_mapped_arguments(JSContext *ctx, int argc, JSValueConst *argv, JSStackFrame *sf, int arg_count) { JSValue val; JSProperty props[3]; JSVarRef **tab, *var_ref; JSObject *p; int i, j; props[0].u.value = JS_NewInt32(ctx, argc); /* length */ props[1].u.value = JS_DupValue(ctx, ctx->array_proto_values); /* Symbol.iterator */ props[2].u.value = JS_DupValue(ctx, ctx->rt->current_stack_frame->cur_func); /* callee */ val = JS_NewObjectFromShape(ctx, js_dup_shape(ctx->mapped_arguments_shape), JS_CLASS_MAPPED_ARGUMENTS, props); if (JS_IsException(val)) return val; p = JS_VALUE_GET_OBJ(val); /* initialize the fast array part */ tab = NULL; if (argc > 0) { tab = js_malloc(ctx, sizeof(tab[0]) * argc); if (!tab) goto fail; for(i = 0; i < arg_count; i++) { var_ref = get_var_ref(ctx, sf, i, TRUE); if (!var_ref) goto fail1; tab[i] = var_ref; } for(i = arg_count; i < argc; i++) { var_ref = js_create_var_ref(ctx, FALSE); if (!var_ref) { fail1: for(j = 0; j < i; j++) free_var_ref(ctx->rt, tab[j]); js_free(ctx, tab); goto fail; } var_ref->value = JS_DupValue(ctx, argv[i]); tab[i] = var_ref; } } p->u.array.u.var_refs = tab; p->u.array.count = argc; return val; fail: JS_FreeValue(ctx, val); return JS_EXCEPTION; } static JSValue build_for_in_iterator(JSContext *ctx, JSValue obj) { JSObject *p, *p1; JSPropertyEnum *tab_atom; int i; JSValue enum_obj; JSForInIterator *it; uint32_t tag, tab_atom_count; tag = JS_VALUE_GET_TAG(obj); if (tag != JS_TAG_OBJECT && tag != JS_TAG_NULL && tag != JS_TAG_UNDEFINED) { obj = JS_ToObjectFree(ctx, obj); } it = js_malloc(ctx, sizeof(*it)); if (!it) { JS_FreeValue(ctx, obj); return JS_EXCEPTION; } enum_obj = JS_NewObjectProtoClass(ctx, JS_NULL, JS_CLASS_FOR_IN_ITERATOR); if (JS_IsException(enum_obj)) { js_free(ctx, it); JS_FreeValue(ctx, obj); return JS_EXCEPTION; } it->is_array = FALSE; it->obj = obj; it->idx = 0; it->tab_atom = NULL; it->atom_count = 0; it->in_prototype_chain = FALSE; p1 = JS_VALUE_GET_OBJ(enum_obj); p1->u.for_in_iterator = it; if (tag == JS_TAG_NULL || tag == JS_TAG_UNDEFINED) return enum_obj; p = JS_VALUE_GET_OBJ(obj); if (p->fast_array) { JSShape *sh; JSShapeProperty *prs; /* check that there are no enumerable normal fields */ sh = p->shape; for(i = 0, prs = get_shape_prop(sh); i < sh->prop_count; i++, prs++) { if (prs->flags & JS_PROP_ENUMERABLE) goto normal_case; } /* for fast arrays, we only store the number of elements */ it->is_array = TRUE; it->atom_count = p->u.array.count; } else { normal_case: if (JS_GetOwnPropertyNamesInternal(ctx, &tab_atom, &tab_atom_count, p, JS_GPN_STRING_MASK | JS_GPN_SET_ENUM)) { JS_FreeValue(ctx, enum_obj); return JS_EXCEPTION; } it->tab_atom = tab_atom; it->atom_count = tab_atom_count; } return enum_obj; } /* obj -> enum_obj */ static __exception int js_for_in_start(JSContext *ctx, JSValue *sp) { sp[-1] = build_for_in_iterator(ctx, sp[-1]); if (JS_IsException(sp[-1])) return -1; return 0; } /* return -1 if exception, 0 if slow case, 1 if the enumeration is finished */ static __exception int js_for_in_prepare_prototype_chain_enum(JSContext *ctx, JSValueConst enum_obj) { JSObject *p; JSForInIterator *it; JSPropertyEnum *tab_atom; uint32_t tab_atom_count, i; JSValue obj1; p = JS_VALUE_GET_OBJ(enum_obj); it = p->u.for_in_iterator; /* check if there are enumerable properties in the prototype chain (fast path) */ obj1 = JS_DupValue(ctx, it->obj); for(;;) { obj1 = JS_GetPrototypeFree(ctx, obj1); if (JS_IsNull(obj1)) break; if (JS_IsException(obj1)) goto fail; if (JS_GetOwnPropertyNamesInternal(ctx, &tab_atom, &tab_atom_count, JS_VALUE_GET_OBJ(obj1), JS_GPN_STRING_MASK | JS_GPN_ENUM_ONLY)) { JS_FreeValue(ctx, obj1); goto fail; } JS_FreePropertyEnum(ctx, tab_atom, tab_atom_count); if (tab_atom_count != 0) { JS_FreeValue(ctx, obj1); goto slow_path; } /* must check for timeout to avoid infinite loop */ if (js_poll_interrupts(ctx)) { JS_FreeValue(ctx, obj1); goto fail; } } JS_FreeValue(ctx, obj1); return 1; slow_path: /* add the visited properties, even if they are not enumerable */ if (it->is_array) { if (JS_GetOwnPropertyNamesInternal(ctx, &tab_atom, &tab_atom_count, JS_VALUE_GET_OBJ(it->obj), JS_GPN_STRING_MASK | JS_GPN_SET_ENUM)) { goto fail; } it->is_array = FALSE; it->tab_atom = tab_atom; it->atom_count = tab_atom_count; } for(i = 0; i < it->atom_count; i++) { if (JS_DefinePropertyValue(ctx, enum_obj, it->tab_atom[i].atom, JS_NULL, JS_PROP_ENUMERABLE) < 0) goto fail; } return 0; fail: return -1; } /* enum_obj -> enum_obj value done */ static __exception int js_for_in_next(JSContext *ctx, JSValue *sp) { JSValueConst enum_obj; JSObject *p; JSAtom prop; JSForInIterator *it; JSPropertyEnum *tab_atom; uint32_t tab_atom_count; int ret; enum_obj = sp[-1]; /* fail safe */ if (JS_VALUE_GET_TAG(enum_obj) != JS_TAG_OBJECT) goto done; p = JS_VALUE_GET_OBJ(enum_obj); if (p->class_id != JS_CLASS_FOR_IN_ITERATOR) goto done; it = p->u.for_in_iterator; for(;;) { if (it->idx >= it->atom_count) { if (JS_IsNull(it->obj) || JS_IsUndefined(it->obj)) goto done; /* not an object */ /* no more property in the current object: look in the prototype */ if (!it->in_prototype_chain) { ret = js_for_in_prepare_prototype_chain_enum(ctx, enum_obj); if (ret < 0) return -1; if (ret) goto done; it->in_prototype_chain = TRUE; } it->obj = JS_GetPrototypeFree(ctx, it->obj); if (JS_IsException(it->obj)) return -1; if (JS_IsNull(it->obj)) goto done; /* no more prototype */ /* must check for timeout to avoid infinite loop */ if (js_poll_interrupts(ctx)) return -1; if (JS_GetOwnPropertyNamesInternal(ctx, &tab_atom, &tab_atom_count, JS_VALUE_GET_OBJ(it->obj), JS_GPN_STRING_MASK | JS_GPN_SET_ENUM)) { return -1; } JS_FreePropertyEnum(ctx, it->tab_atom, it->atom_count); it->tab_atom = tab_atom; it->atom_count = tab_atom_count; it->idx = 0; } else { if (it->is_array) { prop = __JS_AtomFromUInt32(it->idx); it->idx++; } else { BOOL is_enumerable; prop = it->tab_atom[it->idx].atom; is_enumerable = it->tab_atom[it->idx].is_enumerable; it->idx++; if (it->in_prototype_chain) { /* slow case: we are in the prototype chain */ ret = JS_GetOwnPropertyInternal(ctx, NULL, JS_VALUE_GET_OBJ(enum_obj), prop); if (ret < 0) return ret; if (ret) continue; /* already visited */ /* add to the visited property list */ if (JS_DefinePropertyValue(ctx, enum_obj, prop, JS_NULL, JS_PROP_ENUMERABLE) < 0) return -1; } if (!is_enumerable) continue; } /* check if the property was deleted */ ret = JS_GetOwnPropertyInternal(ctx, NULL, JS_VALUE_GET_OBJ(it->obj), prop); if (ret < 0) return ret; if (ret) break; } } /* return the property */ sp[0] = JS_AtomToValue(ctx, prop); sp[1] = JS_FALSE; return 0; done: /* return the end */ sp[0] = JS_UNDEFINED; sp[1] = JS_TRUE; return 0; } static JSValue JS_GetIterator2(JSContext *ctx, JSValueConst obj, JSValueConst method) { JSValue enum_obj; enum_obj = JS_Call(ctx, method, obj, 0, NULL); if (JS_IsException(enum_obj)) return enum_obj; if (!JS_IsObject(enum_obj)) { JS_FreeValue(ctx, enum_obj); return JS_ThrowTypeErrorNotAnObject(ctx); } return enum_obj; } static JSValue JS_GetIterator(JSContext *ctx, JSValueConst obj, BOOL is_async) { JSValue method, ret, sync_iter; if (is_async) { method = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_asyncIterator); if (JS_IsException(method)) return method; if (JS_IsUndefined(method) || JS_IsNull(method)) { method = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_iterator); if (JS_IsException(method)) return method; sync_iter = JS_GetIterator2(ctx, obj, method); JS_FreeValue(ctx, method); if (JS_IsException(sync_iter)) return sync_iter; ret = JS_CreateAsyncFromSyncIterator(ctx, sync_iter); JS_FreeValue(ctx, sync_iter); return ret; } } else { method = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_iterator); if (JS_IsException(method)) return method; } if (!JS_IsFunction(ctx, method)) { JS_FreeValue(ctx, method); return JS_ThrowTypeError(ctx, "value is not iterable"); } ret = JS_GetIterator2(ctx, obj, method); JS_FreeValue(ctx, method); return ret; } /* return *pdone = 2 if the iterator object is not parsed */ static JSValue JS_IteratorNext2(JSContext *ctx, JSValueConst enum_obj, JSValueConst method, int argc, JSValueConst *argv, int *pdone) { JSValue obj; /* fast path for the built-in iterators (avoid creating the intermediate result object) */ if (JS_IsObject(method)) { JSObject *p = JS_VALUE_GET_OBJ(method); if (p->class_id == JS_CLASS_C_FUNCTION && p->u.cfunc.cproto == JS_CFUNC_iterator_next) { JSCFunctionType func; JSValueConst args[1]; /* in case the function expects one argument */ if (argc == 0) { args[0] = JS_UNDEFINED; argv = args; } func = p->u.cfunc.c_function; return func.iterator_next(ctx, enum_obj, argc, argv, pdone, p->u.cfunc.magic); } } obj = JS_Call(ctx, method, enum_obj, argc, argv); if (JS_IsException(obj)) goto fail; if (!JS_IsObject(obj)) { JS_FreeValue(ctx, obj); JS_ThrowTypeError(ctx, "iterator must return an object"); goto fail; } *pdone = 2; return obj; fail: *pdone = FALSE; return JS_EXCEPTION; } /* Note: always return JS_UNDEFINED when *pdone = TRUE. */ static JSValue JS_IteratorNext(JSContext *ctx, JSValueConst enum_obj, JSValueConst method, int argc, JSValueConst *argv, BOOL *pdone) { JSValue obj, value, done_val; int done; obj = JS_IteratorNext2(ctx, enum_obj, method, argc, argv, &done); if (JS_IsException(obj)) goto fail; if (likely(done == 0)) { *pdone = FALSE; return obj; } else if (done != 2) { JS_FreeValue(ctx, obj); *pdone = TRUE; return JS_UNDEFINED; } else { done_val = JS_GetProperty(ctx, obj, JS_ATOM_done); if (JS_IsException(done_val)) goto fail; *pdone = JS_ToBoolFree(ctx, done_val); value = JS_UNDEFINED; if (!*pdone) { value = JS_GetProperty(ctx, obj, JS_ATOM_value); } JS_FreeValue(ctx, obj); return value; } fail: JS_FreeValue(ctx, obj); *pdone = FALSE; return JS_EXCEPTION; } /* return < 0 in case of exception */ static int JS_IteratorClose(JSContext *ctx, JSValueConst enum_obj, BOOL is_exception_pending) { JSValue method, ret, ex_obj; int res; if (is_exception_pending) { ex_obj = ctx->rt->current_exception; ctx->rt->current_exception = JS_UNINITIALIZED; res = -1; } else { ex_obj = JS_UNDEFINED; res = 0; } method = JS_GetProperty(ctx, enum_obj, JS_ATOM_return); if (JS_IsException(method)) { res = -1; goto done; } if (JS_IsUndefined(method) || JS_IsNull(method)) { goto done; } ret = JS_CallFree(ctx, method, enum_obj, 0, NULL); if (!is_exception_pending) { if (JS_IsException(ret)) { res = -1; } else if (!JS_IsObject(ret)) { JS_ThrowTypeErrorNotAnObject(ctx); res = -1; } } JS_FreeValue(ctx, ret); done: if (is_exception_pending) { JS_Throw(ctx, ex_obj); } return res; } /* obj -> enum_rec (3 slots) */ static __exception int js_for_of_start(JSContext *ctx, JSValue *sp, BOOL is_async) { JSValue op1, obj, method; op1 = sp[-1]; obj = JS_GetIterator(ctx, op1, is_async); if (JS_IsException(obj)) return -1; JS_FreeValue(ctx, op1); sp[-1] = obj; method = JS_GetProperty(ctx, obj, JS_ATOM_next); if (JS_IsException(method)) return -1; sp[0] = method; return 0; } /* enum_rec [objs] -> enum_rec [objs] value done. There are 'offset' objs. If 'done' is true or in case of exception, 'enum_rec' is set to undefined. If 'done' is true, 'value' is always set to undefined. */ static __exception int js_for_of_next(JSContext *ctx, JSValue *sp, int offset) { JSValue value = JS_UNDEFINED; int done = 1; if (likely(!JS_IsUndefined(sp[offset]))) { value = JS_IteratorNext(ctx, sp[offset], sp[offset + 1], 0, NULL, &done); if (JS_IsException(value)) done = -1; if (done) { /* value is JS_UNDEFINED or JS_EXCEPTION */ /* replace the iteration object with undefined */ JS_FreeValue(ctx, sp[offset]); sp[offset] = JS_UNDEFINED; if (done < 0) { return -1; } else { JS_FreeValue(ctx, value); value = JS_UNDEFINED; } } } sp[0] = value; sp[1] = JS_NewBool(ctx, done); return 0; } static __exception int js_for_await_of_next(JSContext *ctx, JSValue *sp) { JSValue obj, iter, next; sp[-1] = JS_UNDEFINED; /* disable the catch offset so that exceptions do not close the iterator */ iter = sp[-3]; next = sp[-2]; obj = JS_Call(ctx, next, iter, 0, NULL); if (JS_IsException(obj)) return -1; sp[0] = obj; return 0; } static JSValue JS_IteratorGetCompleteValue(JSContext *ctx, JSValueConst obj, BOOL *pdone) { JSValue done_val, value; BOOL done; done_val = JS_GetProperty(ctx, obj, JS_ATOM_done); if (JS_IsException(done_val)) goto fail; done = JS_ToBoolFree(ctx, done_val); value = JS_GetProperty(ctx, obj, JS_ATOM_value); if (JS_IsException(value)) goto fail; *pdone = done; return value; fail: *pdone = FALSE; return JS_EXCEPTION; } static __exception int js_iterator_get_value_done(JSContext *ctx, JSValue *sp) { JSValue obj, value; BOOL done; obj = sp[-1]; if (!JS_IsObject(obj)) { JS_ThrowTypeError(ctx, "iterator must return an object"); return -1; } value = JS_IteratorGetCompleteValue(ctx, obj, &done); if (JS_IsException(value)) return -1; JS_FreeValue(ctx, obj); /* put again the catch offset so that exceptions close the iterator */ sp[-2] = JS_NewCatchOffset(ctx, 0); sp[-1] = value; sp[0] = JS_NewBool(ctx, done); return 0; } static JSValue js_create_iterator_result(JSContext *ctx, JSValue val, BOOL done) { JSValue obj; obj = JS_NewObject(ctx); if (JS_IsException(obj)) { JS_FreeValue(ctx, val); return obj; } if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_value, val, JS_PROP_C_W_E) < 0) { goto fail; } if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_done, JS_NewBool(ctx, done), JS_PROP_C_W_E) < 0) { fail: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } return obj; } static JSValue js_array_iterator_next(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, BOOL *pdone, int magic); static JSValue js_create_array_iterator(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic); static BOOL js_is_fast_array(JSContext *ctx, JSValueConst obj) { /* Try and handle fast arrays explicitly */ if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { JSObject *p = JS_VALUE_GET_OBJ(obj); if (p->class_id == JS_CLASS_ARRAY && p->fast_array) { return TRUE; } } return FALSE; } /* Access an Array's internal JSValue array if available */ static BOOL js_get_fast_array(JSContext *ctx, JSValueConst obj, JSValue **arrpp, uint32_t *countp) { /* Try and handle fast arrays explicitly */ if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { JSObject *p = JS_VALUE_GET_OBJ(obj); if (p->class_id == JS_CLASS_ARRAY && p->fast_array) { *countp = p->u.array.count; *arrpp = p->u.array.u.values; return TRUE; } } return FALSE; } static __exception int js_append_enumerate(JSContext *ctx, JSValue *sp) { JSValue iterator, enumobj, method, value; int is_array_iterator; JSValue *arrp; uint32_t i, count32, pos; JSCFunctionType ft; if (JS_VALUE_GET_TAG(sp[-2]) != JS_TAG_INT) { JS_ThrowInternalError(ctx, "invalid index for append"); return -1; } pos = JS_VALUE_GET_INT(sp[-2]); /* XXX: further optimisations: - use ctx->array_proto_values? - check if array_iterator_prototype next method is built-in and avoid constructing actual iterator object? - build this into js_for_of_start and use in all `for (x of o)` loops */ iterator = JS_GetProperty(ctx, sp[-1], JS_ATOM_Symbol_iterator); if (JS_IsException(iterator)) return -1; ft.generic_magic = js_create_array_iterator; is_array_iterator = JS_IsCFunction(ctx, iterator, ft.generic, JS_ITERATOR_KIND_VALUE); JS_FreeValue(ctx, iterator); enumobj = JS_GetIterator(ctx, sp[-1], FALSE); if (JS_IsException(enumobj)) return -1; method = JS_GetProperty(ctx, enumobj, JS_ATOM_next); if (JS_IsException(method)) { JS_FreeValue(ctx, enumobj); return -1; } ft.iterator_next = js_array_iterator_next; if (is_array_iterator && JS_IsCFunction(ctx, method, ft.generic, 0) && js_get_fast_array(ctx, sp[-1], &arrp, &count32)) { uint32_t len; if (js_get_length32(ctx, &len, sp[-1])) goto exception; /* if len > count32, the elements >= count32 might be read in the prototypes and might have side effects */ if (len != count32) goto general_case; /* Handle fast arrays explicitly */ for (i = 0; i < count32; i++) { if (JS_DefinePropertyValueUint32(ctx, sp[-3], pos++, JS_DupValue(ctx, arrp[i]), JS_PROP_C_W_E) < 0) goto exception; } } else { general_case: for (;;) { BOOL done; value = JS_IteratorNext(ctx, enumobj, method, 0, NULL, &done); if (JS_IsException(value)) goto exception; if (done) { /* value is JS_UNDEFINED */ break; } if (JS_DefinePropertyValueUint32(ctx, sp[-3], pos++, value, JS_PROP_C_W_E) < 0) goto exception; } } /* Note: could raise an error if too many elements */ sp[-2] = JS_NewInt32(ctx, pos); JS_FreeValue(ctx, enumobj); JS_FreeValue(ctx, method); return 0; exception: JS_IteratorClose(ctx, enumobj, TRUE); JS_FreeValue(ctx, enumobj); JS_FreeValue(ctx, method); return -1; } static __exception int JS_CopyDataProperties(JSContext *ctx, JSValueConst target, JSValueConst source, JSValueConst excluded, BOOL setprop) { JSPropertyEnum *tab_atom; JSValue val; uint32_t i, tab_atom_count; JSObject *p; JSObject *pexcl = NULL; int ret, gpn_flags; JSPropertyDescriptor desc; BOOL is_enumerable; if (JS_VALUE_GET_TAG(source) != JS_TAG_OBJECT) return 0; if (JS_VALUE_GET_TAG(excluded) == JS_TAG_OBJECT) pexcl = JS_VALUE_GET_OBJ(excluded); p = JS_VALUE_GET_OBJ(source); gpn_flags = JS_GPN_STRING_MASK | JS_GPN_SYMBOL_MASK | JS_GPN_ENUM_ONLY; if (p->is_exotic) { const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; /* cannot use JS_GPN_ENUM_ONLY with e.g. proxies because it introduces a visible change */ if (em && em->get_own_property_names) { gpn_flags &= ~JS_GPN_ENUM_ONLY; } } if (JS_GetOwnPropertyNamesInternal(ctx, &tab_atom, &tab_atom_count, p, gpn_flags)) return -1; for (i = 0; i < tab_atom_count; i++) { if (pexcl) { ret = JS_GetOwnPropertyInternal(ctx, NULL, pexcl, tab_atom[i].atom); if (ret) { if (ret < 0) goto exception; continue; } } if (!(gpn_flags & JS_GPN_ENUM_ONLY)) { /* test if the property is enumerable */ ret = JS_GetOwnPropertyInternal(ctx, &desc, p, tab_atom[i].atom); if (ret < 0) goto exception; if (!ret) continue; is_enumerable = (desc.flags & JS_PROP_ENUMERABLE) != 0; js_free_desc(ctx, &desc); if (!is_enumerable) continue; } val = JS_GetProperty(ctx, source, tab_atom[i].atom); if (JS_IsException(val)) goto exception; if (setprop) ret = JS_SetProperty(ctx, target, tab_atom[i].atom, val); else ret = JS_DefinePropertyValue(ctx, target, tab_atom[i].atom, val, JS_PROP_C_W_E); if (ret < 0) goto exception; } JS_FreePropertyEnum(ctx, tab_atom, tab_atom_count); return 0; exception: JS_FreePropertyEnum(ctx, tab_atom, tab_atom_count); return -1; } /* only valid inside C functions */ static JSValueConst JS_GetActiveFunction(JSContext *ctx) { return ctx->rt->current_stack_frame->cur_func; } static JSVarRef *js_create_var_ref(JSContext *ctx, BOOL is_lexical) { JSVarRef *var_ref; var_ref = js_malloc(ctx, sizeof(JSVarRef)); if (!var_ref) return NULL; var_ref->header.ref_count = 1; if (is_lexical) var_ref->value = JS_UNINITIALIZED; else var_ref->value = JS_UNDEFINED; var_ref->pvalue = &var_ref->value; var_ref->is_detached = TRUE; var_ref->is_lexical = FALSE; var_ref->is_const = FALSE; add_gc_object(ctx->rt, &var_ref->header, JS_GC_OBJ_TYPE_VAR_REF); return var_ref; } static JSVarRef *get_var_ref(JSContext *ctx, JSStackFrame *sf, int var_idx, BOOL is_arg) { JSObject *p; JSFunctionBytecode *b; JSVarRef *var_ref; JSValue *pvalue; int var_ref_idx; JSBytecodeVarDef *vd; p = JS_VALUE_GET_OBJ(sf->cur_func); b = p->u.func.function_bytecode; if (is_arg) { vd = &b->vardefs[var_idx]; pvalue = &sf->arg_buf[var_idx]; } else { vd = &b->vardefs[b->arg_count + var_idx]; pvalue = &sf->var_buf[var_idx]; } assert(vd->is_captured); var_ref_idx = vd->var_ref_idx; assert(var_ref_idx < b->var_ref_count); var_ref = sf->var_refs[var_ref_idx]; if (var_ref) { /* reference to the already created local variable */ assert(var_ref->pvalue == pvalue); var_ref->header.ref_count++; return var_ref; } /* create a new one */ var_ref = js_malloc(ctx, sizeof(JSVarRef)); if (!var_ref) return NULL; var_ref->header.ref_count = 1; add_gc_object(ctx->rt, &var_ref->header, JS_GC_OBJ_TYPE_VAR_REF); var_ref->is_detached = FALSE; var_ref->is_lexical = FALSE; var_ref->is_const = FALSE; var_ref->var_ref_idx = var_ref_idx; var_ref->stack_frame = sf; sf->var_refs[var_ref_idx] = var_ref; if (sf->js_mode & JS_MODE_ASYNC) { JSAsyncFunctionState *async_func = container_of(sf, JSAsyncFunctionState, frame); /* The stack frame is detached and may be destroyed at any time so its reference count must be increased. Calling close_var_refs() when destroying the stack frame is not possible because it would change the graph between the GC objects. Another solution could be to temporarily detach the JSVarRef of async functions during the GC. It would have the advantage of allowing the release of unused stack frames in a cycle. */ async_func->header.ref_count++; } var_ref->pvalue = pvalue; return var_ref; } static void js_global_object_finalizer(JSRuntime *rt, JSValue obj) { JSObject *p = JS_VALUE_GET_OBJ(obj); JS_FreeValueRT(rt, p->u.global_object.uninitialized_vars); } static void js_global_object_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); JS_MarkValue(rt, p->u.global_object.uninitialized_vars, mark_func); } static JSVarRef *js_global_object_get_uninitialized_var(JSContext *ctx, JSObject *p1, JSAtom atom) { JSObject *p = JS_VALUE_GET_OBJ(p1->u.global_object.uninitialized_vars); JSShapeProperty *prs; JSProperty *pr; JSVarRef *var_ref; prs = find_own_property(&pr, p, atom); if (prs) { assert((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF); var_ref = pr->u.var_ref; var_ref->header.ref_count++; return var_ref; } var_ref = js_create_var_ref(ctx, TRUE); if (!var_ref) return NULL; pr = add_property(ctx, p, atom, JS_PROP_C_W_E | JS_PROP_VARREF); if (unlikely(!pr)) { free_var_ref(ctx->rt, var_ref); return NULL; } pr->u.var_ref = var_ref; var_ref->header.ref_count++; return var_ref; } /* return a new variable reference. Get it from the uninitialized variables if it is present. Return NULL in case of memory error. */ static JSVarRef *js_global_object_find_uninitialized_var(JSContext *ctx, JSObject *p, JSAtom atom, BOOL is_lexical) { JSObject *p1; JSShapeProperty *prs; JSProperty *pr; JSVarRef *var_ref; p1 = JS_VALUE_GET_OBJ(p->u.global_object.uninitialized_vars); prs = find_own_property(&pr, p1, atom); if (prs) { assert((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF); var_ref = pr->u.var_ref; var_ref->header.ref_count++; delete_property(ctx, p1, atom); if (!is_lexical) var_ref->value = JS_UNDEFINED; } else { var_ref = js_create_var_ref(ctx, is_lexical); if (!var_ref) return NULL; } return var_ref; } static JSVarRef *js_closure_define_global_var(JSContext *ctx, JSClosureVar *cv, BOOL is_direct_or_indirect_eval) { JSObject *p, *p1; JSShapeProperty *prs; int flags; JSProperty *pr; JSVarRef *var_ref; if (cv->is_lexical) { p = JS_VALUE_GET_OBJ(ctx->global_var_obj); flags = JS_PROP_ENUMERABLE | JS_PROP_CONFIGURABLE; if (!cv->is_const) flags |= JS_PROP_WRITABLE; prs = find_own_property(&pr, p, cv->var_name); if (prs) { assert((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF); var_ref = pr->u.var_ref; var_ref->header.ref_count++; return var_ref; } /* if there is a corresponding global variable, reuse its reference and create a new one for the global variable */ p1 = JS_VALUE_GET_OBJ(ctx->global_obj); prs = find_own_property(&pr, p1, cv->var_name); if (prs && (prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { JSVarRef *var_ref1; var_ref1 = js_create_var_ref(ctx, FALSE); if (!var_ref1) return NULL; var_ref = pr->u.var_ref; var_ref1->value = var_ref->value; var_ref->value = JS_UNINITIALIZED; pr->u.var_ref = var_ref1; goto add_var_ref; } } else { p = JS_VALUE_GET_OBJ(ctx->global_obj); flags = JS_PROP_ENUMERABLE | JS_PROP_WRITABLE; if (is_direct_or_indirect_eval) flags |= JS_PROP_CONFIGURABLE; retry: prs = find_own_property(&pr, p, cv->var_name); if (prs) { if (unlikely((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT)) { if (JS_AutoInitProperty(ctx, p, cv->var_name, pr, prs)) return NULL; goto retry; } else if ((prs->flags & JS_PROP_TMASK) != JS_PROP_VARREF) { var_ref = js_global_object_get_uninitialized_var(ctx, p, cv->var_name); if (!var_ref) return NULL; } else { var_ref = pr->u.var_ref; var_ref->header.ref_count++; } if (cv->var_kind == JS_VAR_GLOBAL_FUNCTION_DECL && (prs->flags & JS_PROP_CONFIGURABLE)) { /* update the property flags if possible when declaring a global function */ if ((prs->flags & JS_PROP_TMASK) == JS_PROP_GETSET) { free_property(ctx->rt, pr, prs->flags); prs->flags = flags | JS_PROP_VARREF; pr->u.var_ref = var_ref; var_ref->header.ref_count++; } else { assert((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF); prs->flags = (prs->flags & ~JS_PROP_C_W_E) | flags; } var_ref->is_const = FALSE; } return var_ref; } if (!p->extensible) { return js_global_object_get_uninitialized_var(ctx, p, cv->var_name); } } /* if there is a corresponding uninitialized variable, use it */ p1 = JS_VALUE_GET_OBJ(ctx->global_obj); var_ref = js_global_object_find_uninitialized_var(ctx, p1, cv->var_name, cv->is_lexical); if (!var_ref) return NULL; add_var_ref: if (cv->is_lexical) { var_ref->is_lexical = TRUE; var_ref->is_const = cv->is_const; } pr = add_property(ctx, p, cv->var_name, flags | JS_PROP_VARREF); if (unlikely(!pr)) { free_var_ref(ctx->rt, var_ref); return NULL; } pr->u.var_ref = var_ref; var_ref->header.ref_count++; return var_ref; } static JSVarRef *js_closure_global_var(JSContext *ctx, JSClosureVar *cv) { JSObject *p; JSShapeProperty *prs; JSProperty *pr; JSVarRef *var_ref; p = JS_VALUE_GET_OBJ(ctx->global_var_obj); prs = find_own_property(&pr, p, cv->var_name); if (prs) { assert((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF); var_ref = pr->u.var_ref; var_ref->header.ref_count++; return var_ref; } p = JS_VALUE_GET_OBJ(ctx->global_obj); redo: prs = find_own_property(&pr, p, cv->var_name); if (prs) { if (unlikely((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT)) { /* Instantiate property and retry */ if (JS_AutoInitProperty(ctx, p, cv->var_name, pr, prs)) return NULL; goto redo; } if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { var_ref = pr->u.var_ref; var_ref->header.ref_count++; return var_ref; } } return js_global_object_get_uninitialized_var(ctx, p, cv->var_name); } static JSValue js_closure2(JSContext *ctx, JSValue func_obj, JSFunctionBytecode *b, JSVarRef **cur_var_refs, JSStackFrame *sf, BOOL is_eval, JSModuleDef *m) { JSObject *p; JSVarRef **var_refs; int i; p = JS_VALUE_GET_OBJ(func_obj); p->u.func.function_bytecode = b; p->u.func.home_object = NULL; p->u.func.var_refs = NULL; if (b->closure_var_count) { var_refs = js_mallocz(ctx, sizeof(var_refs[0]) * b->closure_var_count); if (!var_refs) goto fail; p->u.func.var_refs = var_refs; if (is_eval) { /* first pass to check the global variable definitions */ for(i = 0; i < b->closure_var_count; i++) { JSClosureVar *cv = &b->closure_var[i]; if (cv->closure_type == JS_CLOSURE_GLOBAL_DECL) { int flags; flags = 0; if (cv->is_lexical) flags |= DEFINE_GLOBAL_LEX_VAR; if (cv->var_kind == JS_VAR_GLOBAL_FUNCTION_DECL) flags |= DEFINE_GLOBAL_FUNC_VAR; if (JS_CheckDefineGlobalVar(ctx, cv->var_name, flags)) goto fail; } } } for(i = 0; i < b->closure_var_count; i++) { JSClosureVar *cv = &b->closure_var[i]; JSVarRef *var_ref; switch(cv->closure_type) { case JS_CLOSURE_MODULE_IMPORT: /* imported from other modules */ continue; case JS_CLOSURE_MODULE_DECL: var_ref = js_create_var_ref(ctx, cv->is_lexical); break; case JS_CLOSURE_GLOBAL_DECL: var_ref = js_closure_define_global_var(ctx, cv, b->is_direct_or_indirect_eval); break; case JS_CLOSURE_GLOBAL: var_ref = js_closure_global_var(ctx, cv); break; case JS_CLOSURE_LOCAL: /* reuse the existing variable reference if it already exists */ var_ref = get_var_ref(ctx, sf, cv->var_idx, FALSE); break; case JS_CLOSURE_ARG: /* reuse the existing variable reference if it already exists */ var_ref = get_var_ref(ctx, sf, cv->var_idx, TRUE); break; case JS_CLOSURE_REF: case JS_CLOSURE_GLOBAL_REF: var_ref = cur_var_refs[cv->var_idx]; var_ref->header.ref_count++; break; default: abort(); } if (!var_ref) goto fail; var_refs[i] = var_ref; } } return func_obj; fail: /* bfunc is freed when func_obj is freed */ JS_FreeValue(ctx, func_obj); return JS_EXCEPTION; } static JSValue js_instantiate_prototype(JSContext *ctx, JSObject *p, JSAtom atom, void *opaque) { JSValue obj, this_val; int ret; this_val = JS_MKPTR(JS_TAG_OBJECT, p); obj = JS_NewObject(ctx); if (JS_IsException(obj)) return JS_EXCEPTION; set_cycle_flag(ctx, obj); set_cycle_flag(ctx, this_val); ret = JS_DefinePropertyValue(ctx, obj, JS_ATOM_constructor, JS_DupValue(ctx, this_val), JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); if (ret < 0) { JS_FreeValue(ctx, obj); return JS_EXCEPTION; } return obj; } static const uint16_t func_kind_to_class_id[] = { [JS_FUNC_NORMAL] = JS_CLASS_BYTECODE_FUNCTION, [JS_FUNC_GENERATOR] = JS_CLASS_GENERATOR_FUNCTION, [JS_FUNC_ASYNC] = JS_CLASS_ASYNC_FUNCTION, [JS_FUNC_ASYNC_GENERATOR] = JS_CLASS_ASYNC_GENERATOR_FUNCTION, }; static JSValue js_closure(JSContext *ctx, JSValue bfunc, JSVarRef **cur_var_refs, JSStackFrame *sf, BOOL is_eval) { JSFunctionBytecode *b; JSValue func_obj; JSAtom name_atom; b = JS_VALUE_GET_PTR(bfunc); func_obj = JS_NewObjectClass(ctx, func_kind_to_class_id[b->func_kind]); if (JS_IsException(func_obj)) { JS_FreeValue(ctx, bfunc); return JS_EXCEPTION; } func_obj = js_closure2(ctx, func_obj, b, cur_var_refs, sf, is_eval, NULL); if (JS_IsException(func_obj)) { /* bfunc has been freed */ goto fail; } name_atom = b->func_name; if (name_atom == JS_ATOM_NULL) name_atom = JS_ATOM_empty_string; js_function_set_properties(ctx, func_obj, name_atom, b->defined_arg_count); if (b->func_kind & JS_FUNC_GENERATOR) { JSValue proto; int proto_class_id; /* generators have a prototype field which is used as prototype for the generator object */ if (b->func_kind == JS_FUNC_ASYNC_GENERATOR) proto_class_id = JS_CLASS_ASYNC_GENERATOR; else proto_class_id = JS_CLASS_GENERATOR; proto = JS_NewObjectProto(ctx, ctx->class_proto[proto_class_id]); if (JS_IsException(proto)) goto fail; JS_DefinePropertyValue(ctx, func_obj, JS_ATOM_prototype, proto, JS_PROP_WRITABLE); } else if (b->has_prototype) { /* add the 'prototype' property: delay instantiation to avoid creating cycles for every javascript function. The prototype object is created on the fly when first accessed */ JS_SetConstructorBit(ctx, func_obj, TRUE); JS_DefineAutoInitProperty(ctx, func_obj, JS_ATOM_prototype, JS_AUTOINIT_ID_PROTOTYPE, NULL, JS_PROP_WRITABLE); } return func_obj; fail: /* bfunc is freed when func_obj is freed */ JS_FreeValue(ctx, func_obj); return JS_EXCEPTION; } #define JS_DEFINE_CLASS_HAS_HERITAGE (1 << 0) static int js_op_define_class(JSContext *ctx, JSValue *sp, JSAtom class_name, int class_flags, JSVarRef **cur_var_refs, JSStackFrame *sf, BOOL is_computed_name) { JSValue bfunc, parent_class, proto = JS_UNDEFINED; JSValue ctor = JS_UNDEFINED, parent_proto = JS_UNDEFINED; JSFunctionBytecode *b; parent_class = sp[-2]; bfunc = sp[-1]; if (class_flags & JS_DEFINE_CLASS_HAS_HERITAGE) { if (JS_IsNull(parent_class)) { parent_proto = JS_NULL; parent_class = JS_DupValue(ctx, ctx->function_proto); } else { if (!JS_IsConstructor(ctx, parent_class)) { JS_ThrowTypeError(ctx, "parent class must be constructor"); goto fail; } parent_proto = JS_GetProperty(ctx, parent_class, JS_ATOM_prototype); if (JS_IsException(parent_proto)) goto fail; if (!JS_IsNull(parent_proto) && !JS_IsObject(parent_proto)) { JS_ThrowTypeError(ctx, "parent prototype must be an object or null"); goto fail; } } } else { /* parent_class is JS_UNDEFINED in this case */ parent_proto = JS_DupValue(ctx, ctx->class_proto[JS_CLASS_OBJECT]); parent_class = JS_DupValue(ctx, ctx->function_proto); } proto = JS_NewObjectProto(ctx, parent_proto); if (JS_IsException(proto)) goto fail; b = JS_VALUE_GET_PTR(bfunc); assert(b->func_kind == JS_FUNC_NORMAL); ctor = JS_NewObjectProtoClass(ctx, parent_class, JS_CLASS_BYTECODE_FUNCTION); if (JS_IsException(ctor)) goto fail; ctor = js_closure2(ctx, ctor, b, cur_var_refs, sf, FALSE, NULL); bfunc = JS_UNDEFINED; if (JS_IsException(ctor)) goto fail; js_method_set_home_object(ctx, ctor, proto); JS_SetConstructorBit(ctx, ctor, TRUE); JS_DefinePropertyValue(ctx, ctor, JS_ATOM_length, JS_NewInt32(ctx, b->defined_arg_count), JS_PROP_CONFIGURABLE); if (is_computed_name) { if (JS_DefineObjectNameComputed(ctx, ctor, sp[-3], JS_PROP_CONFIGURABLE) < 0) goto fail; } else { if (JS_DefineObjectName(ctx, ctor, class_name, JS_PROP_CONFIGURABLE) < 0) goto fail; } /* the constructor property must be first. It can be overriden by computed property names */ if (JS_DefinePropertyValue(ctx, proto, JS_ATOM_constructor, JS_DupValue(ctx, ctor), JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE | JS_PROP_THROW) < 0) goto fail; /* set the prototype property */ if (JS_DefinePropertyValue(ctx, ctor, JS_ATOM_prototype, JS_DupValue(ctx, proto), JS_PROP_THROW) < 0) goto fail; set_cycle_flag(ctx, ctor); set_cycle_flag(ctx, proto); JS_FreeValue(ctx, parent_proto); JS_FreeValue(ctx, parent_class); sp[-2] = ctor; sp[-1] = proto; return 0; fail: JS_FreeValue(ctx, parent_class); JS_FreeValue(ctx, parent_proto); JS_FreeValue(ctx, bfunc); JS_FreeValue(ctx, proto); JS_FreeValue(ctx, ctor); sp[-2] = JS_UNDEFINED; sp[-1] = JS_UNDEFINED; return -1; } static void close_var_ref(JSRuntime *rt, JSStackFrame *sf, JSVarRef *var_ref) { if (sf->js_mode & JS_MODE_ASYNC) { JSAsyncFunctionState *async_func = container_of(sf, JSAsyncFunctionState, frame); async_func_free(rt, async_func); } var_ref->value = JS_DupValueRT(rt, *var_ref->pvalue); var_ref->pvalue = &var_ref->value; /* the reference is no longer to a local variable */ var_ref->is_detached = TRUE; } static void close_var_refs(JSRuntime *rt, JSFunctionBytecode *b, JSStackFrame *sf) { JSVarRef *var_ref; int i; for(i = 0; i < b->var_ref_count; i++) { var_ref = sf->var_refs[i]; if (var_ref) close_var_ref(rt, sf, var_ref); } } static void close_lexical_var(JSContext *ctx, JSFunctionBytecode *b, JSStackFrame *sf, int var_idx) { JSVarRef *var_ref; int var_ref_idx; var_ref_idx = b->vardefs[b->arg_count + var_idx].var_ref_idx; var_ref = sf->var_refs[var_ref_idx]; if (var_ref) { close_var_ref(ctx->rt, sf, var_ref); sf->var_refs[var_ref_idx] = NULL; } } #define JS_CALL_FLAG_COPY_ARGV (1 << 1) #define JS_CALL_FLAG_GENERATOR (1 << 2) static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, int argc, JSValueConst *argv, int flags) { JSRuntime *rt = ctx->rt; JSCFunctionType func; JSObject *p; JSStackFrame sf_s, *sf = &sf_s, *prev_sf; JSValue ret_val; JSValueConst *arg_buf; int arg_count, i; JSCFunctionEnum cproto; p = JS_VALUE_GET_OBJ(func_obj); cproto = p->u.cfunc.cproto; arg_count = p->u.cfunc.length; /* better to always check stack overflow */ if (js_check_stack_overflow(rt, sizeof(arg_buf[0]) * arg_count)) return JS_ThrowStackOverflow(ctx); prev_sf = rt->current_stack_frame; sf->prev_frame = prev_sf; rt->current_stack_frame = sf; ctx = p->u.cfunc.realm; /* change the current realm */ sf->js_mode = 0; sf->cur_func = (JSValue)func_obj; sf->arg_count = argc; arg_buf = argv; if (unlikely(argc < arg_count)) { /* ensure that at least argc_count arguments are readable */ arg_buf = alloca(sizeof(arg_buf[0]) * arg_count); for(i = 0; i < argc; i++) arg_buf[i] = argv[i]; for(i = argc; i < arg_count; i++) arg_buf[i] = JS_UNDEFINED; sf->arg_count = arg_count; } sf->arg_buf = (JSValue*)arg_buf; func = p->u.cfunc.c_function; switch(cproto) { case JS_CFUNC_constructor: case JS_CFUNC_constructor_or_func: if (!(flags & JS_CALL_FLAG_CONSTRUCTOR)) { if (cproto == JS_CFUNC_constructor) { not_a_constructor: ret_val = JS_ThrowTypeError(ctx, "must be called with new"); break; } else { this_obj = JS_UNDEFINED; } } /* here this_obj is new_target */ /* fall thru */ case JS_CFUNC_generic: ret_val = func.generic(ctx, this_obj, argc, arg_buf); break; case JS_CFUNC_constructor_magic: case JS_CFUNC_constructor_or_func_magic: if (!(flags & JS_CALL_FLAG_CONSTRUCTOR)) { if (cproto == JS_CFUNC_constructor_magic) { goto not_a_constructor; } else { this_obj = JS_UNDEFINED; } } /* fall thru */ case JS_CFUNC_generic_magic: ret_val = func.generic_magic(ctx, this_obj, argc, arg_buf, p->u.cfunc.magic); break; case JS_CFUNC_getter: ret_val = func.getter(ctx, this_obj); break; case JS_CFUNC_setter: ret_val = func.setter(ctx, this_obj, arg_buf[0]); break; case JS_CFUNC_getter_magic: ret_val = func.getter_magic(ctx, this_obj, p->u.cfunc.magic); break; case JS_CFUNC_setter_magic: ret_val = func.setter_magic(ctx, this_obj, arg_buf[0], p->u.cfunc.magic); break; case JS_CFUNC_f_f: { double d1; if (unlikely(JS_ToFloat64(ctx, &d1, arg_buf[0]))) { ret_val = JS_EXCEPTION; break; } ret_val = JS_NewFloat64(ctx, func.f_f(d1)); } break; case JS_CFUNC_f_f_f: { double d1, d2; if (unlikely(JS_ToFloat64(ctx, &d1, arg_buf[0]))) { ret_val = JS_EXCEPTION; break; } if (unlikely(JS_ToFloat64(ctx, &d2, arg_buf[1]))) { ret_val = JS_EXCEPTION; break; } ret_val = JS_NewFloat64(ctx, func.f_f_f(d1, d2)); } break; case JS_CFUNC_iterator_next: { int done; ret_val = func.iterator_next(ctx, this_obj, argc, arg_buf, &done, p->u.cfunc.magic); if (!JS_IsException(ret_val) && done != 2) { ret_val = js_create_iterator_result(ctx, ret_val, done); } } break; default: abort(); } rt->current_stack_frame = sf->prev_frame; return ret_val; } static JSValue js_call_bound_function(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, int argc, JSValueConst *argv, int flags) { JSObject *p; JSBoundFunction *bf; JSValueConst *arg_buf, new_target; int arg_count, i; p = JS_VALUE_GET_OBJ(func_obj); bf = p->u.bound_function; arg_count = bf->argc + argc; if (js_check_stack_overflow(ctx->rt, sizeof(JSValue) * arg_count)) return JS_ThrowStackOverflow(ctx); arg_buf = alloca(sizeof(JSValue) * arg_count); for(i = 0; i < bf->argc; i++) { arg_buf[i] = bf->argv[i]; } for(i = 0; i < argc; i++) { arg_buf[bf->argc + i] = argv[i]; } if (flags & JS_CALL_FLAG_CONSTRUCTOR) { new_target = this_obj; if (js_same_value(ctx, func_obj, new_target)) new_target = bf->func_obj; return JS_CallConstructor2(ctx, bf->func_obj, new_target, arg_count, arg_buf); } else { return JS_Call(ctx, bf->func_obj, bf->this_val, arg_count, arg_buf); } } /* argument of OP_special_object */ typedef enum { OP_SPECIAL_OBJECT_ARGUMENTS, OP_SPECIAL_OBJECT_MAPPED_ARGUMENTS, OP_SPECIAL_OBJECT_THIS_FUNC, OP_SPECIAL_OBJECT_NEW_TARGET, OP_SPECIAL_OBJECT_HOME_OBJECT, OP_SPECIAL_OBJECT_VAR_OBJECT, OP_SPECIAL_OBJECT_IMPORT_META, } OPSpecialObjectEnum; #define FUNC_RET_AWAIT 0 #define FUNC_RET_YIELD 1 #define FUNC_RET_YIELD_STAR 2 #define FUNC_RET_INITIAL_YIELD 3 /* argv[] is modified if (flags & JS_CALL_FLAG_COPY_ARGV) = 0. */ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, JSValueConst this_obj, JSValueConst new_target, int argc, JSValue *argv, int flags) { JSRuntime *rt = caller_ctx->rt; JSContext *ctx; JSObject *p; JSFunctionBytecode *b; JSStackFrame sf_s, *sf = &sf_s; const uint8_t *pc; int opcode, arg_allocated_size, i; JSValue *local_buf, *stack_buf, *var_buf, *arg_buf, *sp, ret_val, *pval; JSVarRef **var_refs; size_t alloca_size; #if !DIRECT_DISPATCH #define SWITCH(pc) switch (opcode = *pc++) #define CASE(op) case op #define DEFAULT default #define BREAK break #else static const void * const dispatch_table[256] = { #define DEF(id, size, n_pop, n_push, f) && case_OP_ ## id, #if SHORT_OPCODES #define def(id, size, n_pop, n_push, f) #else #define def(id, size, n_pop, n_push, f) && case_default, #endif #include "quickjs-opcode.h" [ OP_COUNT ... 255 ] = &&case_default }; #define SWITCH(pc) goto *dispatch_table[opcode = *pc++]; #define CASE(op) case_ ## op #define DEFAULT case_default #define BREAK SWITCH(pc) #endif if (js_poll_interrupts(caller_ctx)) return JS_EXCEPTION; if (unlikely(JS_VALUE_GET_TAG(func_obj) != JS_TAG_OBJECT)) { if (flags & JS_CALL_FLAG_GENERATOR) { JSAsyncFunctionState *s = JS_VALUE_GET_PTR(func_obj); /* func_obj get contains a pointer to JSFuncAsyncState */ /* the stack frame is already allocated */ sf = &s->frame; p = JS_VALUE_GET_OBJ(sf->cur_func); b = p->u.func.function_bytecode; ctx = b->realm; var_refs = p->u.func.var_refs; local_buf = arg_buf = sf->arg_buf; var_buf = sf->var_buf; stack_buf = sf->var_buf + b->var_count; sp = sf->cur_sp; sf->cur_sp = NULL; /* cur_sp is NULL if the function is running */ pc = sf->cur_pc; sf->prev_frame = rt->current_stack_frame; rt->current_stack_frame = sf; if (s->throw_flag) goto exception; else goto restart; } else { goto not_a_function; } } p = JS_VALUE_GET_OBJ(func_obj); if (unlikely(p->class_id != JS_CLASS_BYTECODE_FUNCTION)) { JSClassCall *call_func; call_func = rt->class_array[p->class_id].call; if (!call_func) { not_a_function: return JS_ThrowTypeError(caller_ctx, "not a function"); } return call_func(caller_ctx, func_obj, this_obj, argc, (JSValueConst *)argv, flags); } b = p->u.func.function_bytecode; if (unlikely(argc < b->arg_count || (flags & JS_CALL_FLAG_COPY_ARGV))) { arg_allocated_size = b->arg_count; } else { arg_allocated_size = 0; } alloca_size = sizeof(JSValue) * (arg_allocated_size + b->var_count + b->stack_size) + sizeof(JSVarRef *) * b->var_ref_count; if (js_check_stack_overflow(rt, alloca_size)) return JS_ThrowStackOverflow(caller_ctx); sf->js_mode = b->js_mode; arg_buf = argv; sf->arg_count = argc; sf->cur_func = (JSValue)func_obj; var_refs = p->u.func.var_refs; local_buf = alloca(alloca_size); if (unlikely(arg_allocated_size)) { int n = min_int(argc, b->arg_count); arg_buf = local_buf; for(i = 0; i < n; i++) arg_buf[i] = JS_DupValue(caller_ctx, argv[i]); for(; i < b->arg_count; i++) arg_buf[i] = JS_UNDEFINED; sf->arg_count = b->arg_count; } var_buf = local_buf + arg_allocated_size; sf->var_buf = var_buf; sf->arg_buf = arg_buf; for(i = 0; i < b->var_count; i++) var_buf[i] = JS_UNDEFINED; stack_buf = var_buf + b->var_count; sf->var_refs = (JSVarRef **)(stack_buf + b->stack_size); for(i = 0; i < b->var_ref_count; i++) sf->var_refs[i] = NULL; sp = stack_buf; pc = b->byte_code_buf; sf->prev_frame = rt->current_stack_frame; rt->current_stack_frame = sf; ctx = b->realm; /* set the current realm */ restart: for(;;) { int call_argc; JSValue *call_argv; SWITCH(pc) { CASE(OP_push_i32): *sp++ = JS_NewInt32(ctx, get_u32(pc)); pc += 4; BREAK; CASE(OP_push_bigint_i32): *sp++ = __JS_NewShortBigInt(ctx, (int)get_u32(pc)); pc += 4; BREAK; CASE(OP_push_const): *sp++ = JS_DupValue(ctx, b->cpool[get_u32(pc)]); pc += 4; BREAK; #if SHORT_OPCODES CASE(OP_push_minus1): CASE(OP_push_0): CASE(OP_push_1): CASE(OP_push_2): CASE(OP_push_3): CASE(OP_push_4): CASE(OP_push_5): CASE(OP_push_6): CASE(OP_push_7): *sp++ = JS_NewInt32(ctx, opcode - OP_push_0); BREAK; CASE(OP_push_i8): *sp++ = JS_NewInt32(ctx, get_i8(pc)); pc += 1; BREAK; CASE(OP_push_i16): *sp++ = JS_NewInt32(ctx, get_i16(pc)); pc += 2; BREAK; CASE(OP_push_const8): *sp++ = JS_DupValue(ctx, b->cpool[*pc++]); BREAK; CASE(OP_fclosure8): *sp++ = js_closure(ctx, JS_DupValue(ctx, b->cpool[*pc++]), var_refs, sf, FALSE); if (unlikely(JS_IsException(sp[-1]))) goto exception; BREAK; CASE(OP_push_empty_string): *sp++ = JS_AtomToString(ctx, JS_ATOM_empty_string); BREAK; #endif CASE(OP_push_atom_value): *sp++ = JS_AtomToValue(ctx, get_u32(pc)); pc += 4; BREAK; CASE(OP_undefined): *sp++ = JS_UNDEFINED; BREAK; CASE(OP_null): *sp++ = JS_NULL; BREAK; CASE(OP_push_this): /* OP_push_this is only called at the start of a function */ { JSValue val; if (!(b->js_mode & JS_MODE_STRICT)) { uint32_t tag = JS_VALUE_GET_TAG(this_obj); if (likely(tag == JS_TAG_OBJECT)) goto normal_this; if (tag == JS_TAG_NULL || tag == JS_TAG_UNDEFINED) { val = JS_DupValue(ctx, ctx->global_obj); } else { val = JS_ToObject(ctx, this_obj); if (JS_IsException(val)) goto exception; } } else { normal_this: val = JS_DupValue(ctx, this_obj); } *sp++ = val; } BREAK; CASE(OP_push_false): *sp++ = JS_FALSE; BREAK; CASE(OP_push_true): *sp++ = JS_TRUE; BREAK; CASE(OP_object): *sp++ = JS_NewObject(ctx); if (unlikely(JS_IsException(sp[-1]))) goto exception; BREAK; CASE(OP_special_object): { int arg = *pc++; switch(arg) { case OP_SPECIAL_OBJECT_ARGUMENTS: *sp++ = js_build_arguments(ctx, argc, (JSValueConst *)argv); if (unlikely(JS_IsException(sp[-1]))) goto exception; break; case OP_SPECIAL_OBJECT_MAPPED_ARGUMENTS: *sp++ = js_build_mapped_arguments(ctx, argc, (JSValueConst *)argv, sf, min_int(argc, b->arg_count)); if (unlikely(JS_IsException(sp[-1]))) goto exception; break; case OP_SPECIAL_OBJECT_THIS_FUNC: *sp++ = JS_DupValue(ctx, sf->cur_func); break; case OP_SPECIAL_OBJECT_NEW_TARGET: *sp++ = JS_DupValue(ctx, new_target); break; case OP_SPECIAL_OBJECT_HOME_OBJECT: { JSObject *p1; p1 = p->u.func.home_object; if (unlikely(!p1)) *sp++ = JS_UNDEFINED; else *sp++ = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p1)); } break; case OP_SPECIAL_OBJECT_VAR_OBJECT: *sp++ = JS_NewObjectProto(ctx, JS_NULL); if (unlikely(JS_IsException(sp[-1]))) goto exception; break; case OP_SPECIAL_OBJECT_IMPORT_META: *sp++ = js_import_meta(ctx); if (unlikely(JS_IsException(sp[-1]))) goto exception; break; default: abort(); } } BREAK; CASE(OP_rest): { int first = get_u16(pc); pc += 2; first = min_int(first, argc); *sp++ = js_create_array(ctx, argc - first, (JSValueConst *)(argv + first)); if (unlikely(JS_IsException(sp[-1]))) goto exception; } BREAK; CASE(OP_drop): JS_FreeValue(ctx, sp[-1]); sp--; BREAK; CASE(OP_nip): JS_FreeValue(ctx, sp[-2]); sp[-2] = sp[-1]; sp--; BREAK; CASE(OP_nip1): /* a b c -> b c */ JS_FreeValue(ctx, sp[-3]); sp[-3] = sp[-2]; sp[-2] = sp[-1]; sp--; BREAK; CASE(OP_dup): sp[0] = JS_DupValue(ctx, sp[-1]); sp++; BREAK; CASE(OP_dup2): /* a b -> a b a b */ sp[0] = JS_DupValue(ctx, sp[-2]); sp[1] = JS_DupValue(ctx, sp[-1]); sp += 2; BREAK; CASE(OP_dup3): /* a b c -> a b c a b c */ sp[0] = JS_DupValue(ctx, sp[-3]); sp[1] = JS_DupValue(ctx, sp[-2]); sp[2] = JS_DupValue(ctx, sp[-1]); sp += 3; BREAK; CASE(OP_dup1): /* a b -> a a b */ sp[0] = sp[-1]; sp[-1] = JS_DupValue(ctx, sp[-2]); sp++; BREAK; CASE(OP_insert2): /* obj a -> a obj a (dup_x1) */ sp[0] = sp[-1]; sp[-1] = sp[-2]; sp[-2] = JS_DupValue(ctx, sp[0]); sp++; BREAK; CASE(OP_insert3): /* obj prop a -> a obj prop a (dup_x2) */ sp[0] = sp[-1]; sp[-1] = sp[-2]; sp[-2] = sp[-3]; sp[-3] = JS_DupValue(ctx, sp[0]); sp++; BREAK; CASE(OP_insert4): /* this obj prop a -> a this obj prop a */ sp[0] = sp[-1]; sp[-1] = sp[-2]; sp[-2] = sp[-3]; sp[-3] = sp[-4]; sp[-4] = JS_DupValue(ctx, sp[0]); sp++; BREAK; CASE(OP_perm3): /* obj a b -> a obj b (213) */ { JSValue tmp; tmp = sp[-2]; sp[-2] = sp[-3]; sp[-3] = tmp; } BREAK; CASE(OP_rot3l): /* x a b -> a b x (231) */ { JSValue tmp; tmp = sp[-3]; sp[-3] = sp[-2]; sp[-2] = sp[-1]; sp[-1] = tmp; } BREAK; CASE(OP_rot4l): /* x a b c -> a b c x */ { JSValue tmp; tmp = sp[-4]; sp[-4] = sp[-3]; sp[-3] = sp[-2]; sp[-2] = sp[-1]; sp[-1] = tmp; } BREAK; CASE(OP_rot5l): /* x a b c d -> a b c d x */ { JSValue tmp; tmp = sp[-5]; sp[-5] = sp[-4]; sp[-4] = sp[-3]; sp[-3] = sp[-2]; sp[-2] = sp[-1]; sp[-1] = tmp; } BREAK; CASE(OP_rot3r): /* a b x -> x a b (312) */ { JSValue tmp; tmp = sp[-1]; sp[-1] = sp[-2]; sp[-2] = sp[-3]; sp[-3] = tmp; } BREAK; CASE(OP_perm4): /* obj prop a b -> a obj prop b */ { JSValue tmp; tmp = sp[-2]; sp[-2] = sp[-3]; sp[-3] = sp[-4]; sp[-4] = tmp; } BREAK; CASE(OP_perm5): /* this obj prop a b -> a this obj prop b */ { JSValue tmp; tmp = sp[-2]; sp[-2] = sp[-3]; sp[-3] = sp[-4]; sp[-4] = sp[-5]; sp[-5] = tmp; } BREAK; CASE(OP_swap): /* a b -> b a */ { JSValue tmp; tmp = sp[-2]; sp[-2] = sp[-1]; sp[-1] = tmp; } BREAK; CASE(OP_swap2): /* a b c d -> c d a b */ { JSValue tmp1, tmp2; tmp1 = sp[-4]; tmp2 = sp[-3]; sp[-4] = sp[-2]; sp[-3] = sp[-1]; sp[-2] = tmp1; sp[-1] = tmp2; } BREAK; CASE(OP_fclosure): { JSValue bfunc = JS_DupValue(ctx, b->cpool[get_u32(pc)]); pc += 4; *sp++ = js_closure(ctx, bfunc, var_refs, sf, FALSE); if (unlikely(JS_IsException(sp[-1]))) goto exception; } BREAK; #if SHORT_OPCODES CASE(OP_call0): CASE(OP_call1): CASE(OP_call2): CASE(OP_call3): call_argc = opcode - OP_call0; goto has_call_argc; #endif CASE(OP_call): CASE(OP_tail_call): { call_argc = get_u16(pc); pc += 2; goto has_call_argc; has_call_argc: call_argv = sp - call_argc; sf->cur_pc = pc; ret_val = JS_CallInternal(ctx, call_argv[-1], JS_UNDEFINED, JS_UNDEFINED, call_argc, call_argv, 0); if (unlikely(JS_IsException(ret_val))) goto exception; if (opcode == OP_tail_call) goto done; for(i = -1; i < call_argc; i++) JS_FreeValue(ctx, call_argv[i]); sp -= call_argc + 1; *sp++ = ret_val; } BREAK; CASE(OP_call_constructor): { call_argc = get_u16(pc); pc += 2; call_argv = sp - call_argc; sf->cur_pc = pc; ret_val = JS_CallConstructorInternal(ctx, call_argv[-2], call_argv[-1], call_argc, call_argv, 0); if (unlikely(JS_IsException(ret_val))) goto exception; for(i = -2; i < call_argc; i++) JS_FreeValue(ctx, call_argv[i]); sp -= call_argc + 2; *sp++ = ret_val; } BREAK; CASE(OP_call_method): CASE(OP_tail_call_method): { call_argc = get_u16(pc); pc += 2; call_argv = sp - call_argc; sf->cur_pc = pc; ret_val = JS_CallInternal(ctx, call_argv[-1], call_argv[-2], JS_UNDEFINED, call_argc, call_argv, 0); if (unlikely(JS_IsException(ret_val))) goto exception; if (opcode == OP_tail_call_method) goto done; for(i = -2; i < call_argc; i++) JS_FreeValue(ctx, call_argv[i]); sp -= call_argc + 2; *sp++ = ret_val; } BREAK; CASE(OP_array_from): call_argc = get_u16(pc); pc += 2; ret_val = js_create_array_free(ctx, call_argc, sp - call_argc); sp -= call_argc; if (unlikely(JS_IsException(ret_val))) goto exception; *sp++ = ret_val; BREAK; CASE(OP_apply): { int magic; magic = get_u16(pc); pc += 2; sf->cur_pc = pc; ret_val = js_function_apply(ctx, sp[-3], 2, (JSValueConst *)&sp[-2], magic); if (unlikely(JS_IsException(ret_val))) goto exception; JS_FreeValue(ctx, sp[-3]); JS_FreeValue(ctx, sp[-2]); JS_FreeValue(ctx, sp[-1]); sp -= 3; *sp++ = ret_val; } BREAK; CASE(OP_return): ret_val = *--sp; goto done; CASE(OP_return_undef): ret_val = JS_UNDEFINED; goto done; CASE(OP_check_ctor_return): /* return TRUE if 'this' should be returned */ if (!JS_IsObject(sp[-1])) { if (!JS_IsUndefined(sp[-1])) { JS_ThrowTypeError(caller_ctx, "derived class constructor must return an object or undefined"); goto exception; } sp[0] = JS_TRUE; } else { sp[0] = JS_FALSE; } sp++; BREAK; CASE(OP_check_ctor): if (JS_IsUndefined(new_target)) { non_ctor_call: JS_ThrowTypeError(ctx, "class constructors must be invoked with 'new'"); goto exception; } BREAK; CASE(OP_init_ctor): { JSValue super, ret; sf->cur_pc = pc; if (JS_IsUndefined(new_target)) goto non_ctor_call; super = JS_GetPrototype(ctx, func_obj); if (JS_IsException(super)) goto exception; ret = JS_CallConstructor2(ctx, super, new_target, argc, (JSValueConst *)argv); JS_FreeValue(ctx, super); if (JS_IsException(ret)) goto exception; *sp++ = ret; } BREAK; CASE(OP_check_brand): { int ret = JS_CheckBrand(ctx, sp[-2], sp[-1]); if (ret < 0) goto exception; if (!ret) { JS_ThrowTypeError(ctx, "invalid brand on object"); goto exception; } } BREAK; CASE(OP_add_brand): if (JS_AddBrand(ctx, sp[-2], sp[-1]) < 0) goto exception; JS_FreeValue(ctx, sp[-2]); JS_FreeValue(ctx, sp[-1]); sp -= 2; BREAK; CASE(OP_throw): JS_Throw(ctx, *--sp); goto exception; CASE(OP_throw_error): #define JS_THROW_VAR_RO 0 #define JS_THROW_VAR_REDECL 1 #define JS_THROW_VAR_UNINITIALIZED 2 #define JS_THROW_ERROR_DELETE_SUPER 3 #define JS_THROW_ERROR_ITERATOR_THROW 4 { JSAtom atom; int type; atom = get_u32(pc); type = pc[4]; pc += 5; if (type == JS_THROW_VAR_RO) JS_ThrowTypeErrorReadOnly(ctx, JS_PROP_THROW, atom); else if (type == JS_THROW_VAR_REDECL) JS_ThrowSyntaxErrorVarRedeclaration(ctx, atom); else if (type == JS_THROW_VAR_UNINITIALIZED) JS_ThrowReferenceErrorUninitialized(ctx, atom); else if (type == JS_THROW_ERROR_DELETE_SUPER) JS_ThrowReferenceError(ctx, "unsupported reference to 'super'"); else if (type == JS_THROW_ERROR_ITERATOR_THROW) JS_ThrowTypeError(ctx, "iterator does not have a throw method"); else JS_ThrowInternalError(ctx, "invalid throw var type %d", type); } goto exception; CASE(OP_eval): { JSValueConst obj; int scope_idx; call_argc = get_u16(pc); scope_idx = get_u16(pc + 2) + ARG_SCOPE_END; pc += 4; call_argv = sp - call_argc; sf->cur_pc = pc; if (js_same_value(ctx, call_argv[-1], ctx->eval_obj)) { if (call_argc >= 1) obj = call_argv[0]; else obj = JS_UNDEFINED; ret_val = JS_EvalObject(ctx, JS_UNDEFINED, obj, JS_EVAL_TYPE_DIRECT, scope_idx); } else { ret_val = JS_CallInternal(ctx, call_argv[-1], JS_UNDEFINED, JS_UNDEFINED, call_argc, call_argv, 0); } if (unlikely(JS_IsException(ret_val))) goto exception; for(i = -1; i < call_argc; i++) JS_FreeValue(ctx, call_argv[i]); sp -= call_argc + 1; *sp++ = ret_val; } BREAK; /* could merge with OP_apply */ CASE(OP_apply_eval): { int scope_idx; uint32_t len; JSValue *tab; JSValueConst obj; scope_idx = get_u16(pc) + ARG_SCOPE_END; pc += 2; sf->cur_pc = pc; tab = build_arg_list(ctx, &len, sp[-1]); if (!tab) goto exception; if (js_same_value(ctx, sp[-2], ctx->eval_obj)) { if (len >= 1) obj = tab[0]; else obj = JS_UNDEFINED; ret_val = JS_EvalObject(ctx, JS_UNDEFINED, obj, JS_EVAL_TYPE_DIRECT, scope_idx); } else { ret_val = JS_Call(ctx, sp[-2], JS_UNDEFINED, len, (JSValueConst *)tab); } free_arg_list(ctx, tab, len); if (unlikely(JS_IsException(ret_val))) goto exception; JS_FreeValue(ctx, sp[-2]); JS_FreeValue(ctx, sp[-1]); sp -= 2; *sp++ = ret_val; } BREAK; CASE(OP_regexp): { sp[-2] = JS_NewRegexp(ctx, sp[-2], sp[-1]); sp--; if (JS_IsException(sp[-1])) goto exception; } BREAK; CASE(OP_get_super): { JSValue proto; sf->cur_pc = pc; proto = JS_GetPrototype(ctx, sp[-1]); if (JS_IsException(proto)) goto exception; JS_FreeValue(ctx, sp[-1]); sp[-1] = proto; } BREAK; CASE(OP_import): { JSValue val; sf->cur_pc = pc; val = js_dynamic_import(ctx, sp[-2], sp[-1]); if (JS_IsException(val)) goto exception; JS_FreeValue(ctx, sp[-2]); JS_FreeValue(ctx, sp[-1]); sp--; sp[-1] = val; } BREAK; CASE(OP_get_var_undef): CASE(OP_get_var): { int idx; JSValue val; idx = get_u16(pc); pc += 2; val = *var_refs[idx]->pvalue; if (unlikely(JS_IsUninitialized(val))) { JSClosureVar *cv = &b->closure_var[idx]; if (cv->is_lexical) { JS_ThrowReferenceErrorUninitialized(ctx, cv->var_name); goto exception; } else { sf->cur_pc = pc; sp[0] = JS_GetPropertyInternal(ctx, ctx->global_obj, cv->var_name, ctx->global_obj, opcode - OP_get_var_undef); if (JS_IsException(sp[0])) goto exception; } } else { sp[0] = JS_DupValue(ctx, val); } sp++; } BREAK; CASE(OP_put_var): CASE(OP_put_var_init): { int idx, ret; JSVarRef *var_ref; idx = get_u16(pc); pc += 2; var_ref = var_refs[idx]; if (unlikely(JS_IsUninitialized(*var_ref->pvalue) || var_ref->is_const)) { JSClosureVar *cv = &b->closure_var[idx]; if (var_ref->is_lexical) { if (opcode == OP_put_var_init) goto put_var_ok; if (JS_IsUninitialized(*var_ref->pvalue)) JS_ThrowReferenceErrorUninitialized(ctx, cv->var_name); else JS_ThrowTypeErrorReadOnly(ctx, JS_PROP_THROW, cv->var_name); goto exception; } else { sf->cur_pc = pc; ret = JS_HasProperty(ctx, ctx->global_obj, cv->var_name); if (ret < 0) goto exception; if (ret == 0 && is_strict_mode(ctx)) { JS_ThrowReferenceErrorNotDefined(ctx, cv->var_name); goto exception; } ret = JS_SetPropertyInternal(ctx, ctx->global_obj, cv->var_name, sp[-1], ctx->global_obj, JS_PROP_THROW_STRICT); sp--; if (ret < 0) goto exception; } } else { put_var_ok: set_value(ctx, var_ref->pvalue, sp[-1]); sp--; } } BREAK; CASE(OP_get_loc): { int idx; idx = get_u16(pc); pc += 2; sp[0] = JS_DupValue(ctx, var_buf[idx]); sp++; } BREAK; CASE(OP_put_loc): { int idx; idx = get_u16(pc); pc += 2; set_value(ctx, &var_buf[idx], sp[-1]); sp--; } BREAK; CASE(OP_set_loc): { int idx; idx = get_u16(pc); pc += 2; set_value(ctx, &var_buf[idx], JS_DupValue(ctx, sp[-1])); } BREAK; CASE(OP_get_arg): { int idx; idx = get_u16(pc); pc += 2; sp[0] = JS_DupValue(ctx, arg_buf[idx]); sp++; } BREAK; CASE(OP_put_arg): { int idx; idx = get_u16(pc); pc += 2; set_value(ctx, &arg_buf[idx], sp[-1]); sp--; } BREAK; CASE(OP_set_arg): { int idx; idx = get_u16(pc); pc += 2; set_value(ctx, &arg_buf[idx], JS_DupValue(ctx, sp[-1])); } BREAK; #if SHORT_OPCODES CASE(OP_get_loc8): *sp++ = JS_DupValue(ctx, var_buf[*pc++]); BREAK; CASE(OP_put_loc8): set_value(ctx, &var_buf[*pc++], *--sp); BREAK; CASE(OP_set_loc8): set_value(ctx, &var_buf[*pc++], JS_DupValue(ctx, sp[-1])); BREAK; CASE(OP_get_loc0): *sp++ = JS_DupValue(ctx, var_buf[0]); BREAK; CASE(OP_get_loc1): *sp++ = JS_DupValue(ctx, var_buf[1]); BREAK; CASE(OP_get_loc2): *sp++ = JS_DupValue(ctx, var_buf[2]); BREAK; CASE(OP_get_loc3): *sp++ = JS_DupValue(ctx, var_buf[3]); BREAK; CASE(OP_put_loc0): set_value(ctx, &var_buf[0], *--sp); BREAK; CASE(OP_put_loc1): set_value(ctx, &var_buf[1], *--sp); BREAK; CASE(OP_put_loc2): set_value(ctx, &var_buf[2], *--sp); BREAK; CASE(OP_put_loc3): set_value(ctx, &var_buf[3], *--sp); BREAK; CASE(OP_set_loc0): set_value(ctx, &var_buf[0], JS_DupValue(ctx, sp[-1])); BREAK; CASE(OP_set_loc1): set_value(ctx, &var_buf[1], JS_DupValue(ctx, sp[-1])); BREAK; CASE(OP_set_loc2): set_value(ctx, &var_buf[2], JS_DupValue(ctx, sp[-1])); BREAK; CASE(OP_set_loc3): set_value(ctx, &var_buf[3], JS_DupValue(ctx, sp[-1])); BREAK; CASE(OP_get_arg0): *sp++ = JS_DupValue(ctx, arg_buf[0]); BREAK; CASE(OP_get_arg1): *sp++ = JS_DupValue(ctx, arg_buf[1]); BREAK; CASE(OP_get_arg2): *sp++ = JS_DupValue(ctx, arg_buf[2]); BREAK; CASE(OP_get_arg3): *sp++ = JS_DupValue(ctx, arg_buf[3]); BREAK; CASE(OP_put_arg0): set_value(ctx, &arg_buf[0], *--sp); BREAK; CASE(OP_put_arg1): set_value(ctx, &arg_buf[1], *--sp); BREAK; CASE(OP_put_arg2): set_value(ctx, &arg_buf[2], *--sp); BREAK; CASE(OP_put_arg3): set_value(ctx, &arg_buf[3], *--sp); BREAK; CASE(OP_set_arg0): set_value(ctx, &arg_buf[0], JS_DupValue(ctx, sp[-1])); BREAK; CASE(OP_set_arg1): set_value(ctx, &arg_buf[1], JS_DupValue(ctx, sp[-1])); BREAK; CASE(OP_set_arg2): set_value(ctx, &arg_buf[2], JS_DupValue(ctx, sp[-1])); BREAK; CASE(OP_set_arg3): set_value(ctx, &arg_buf[3], JS_DupValue(ctx, sp[-1])); BREAK; CASE(OP_get_var_ref0): *sp++ = JS_DupValue(ctx, *var_refs[0]->pvalue); BREAK; CASE(OP_get_var_ref1): *sp++ = JS_DupValue(ctx, *var_refs[1]->pvalue); BREAK; CASE(OP_get_var_ref2): *sp++ = JS_DupValue(ctx, *var_refs[2]->pvalue); BREAK; CASE(OP_get_var_ref3): *sp++ = JS_DupValue(ctx, *var_refs[3]->pvalue); BREAK; CASE(OP_put_var_ref0): set_value(ctx, var_refs[0]->pvalue, *--sp); BREAK; CASE(OP_put_var_ref1): set_value(ctx, var_refs[1]->pvalue, *--sp); BREAK; CASE(OP_put_var_ref2): set_value(ctx, var_refs[2]->pvalue, *--sp); BREAK; CASE(OP_put_var_ref3): set_value(ctx, var_refs[3]->pvalue, *--sp); BREAK; CASE(OP_set_var_ref0): set_value(ctx, var_refs[0]->pvalue, JS_DupValue(ctx, sp[-1])); BREAK; CASE(OP_set_var_ref1): set_value(ctx, var_refs[1]->pvalue, JS_DupValue(ctx, sp[-1])); BREAK; CASE(OP_set_var_ref2): set_value(ctx, var_refs[2]->pvalue, JS_DupValue(ctx, sp[-1])); BREAK; CASE(OP_set_var_ref3): set_value(ctx, var_refs[3]->pvalue, JS_DupValue(ctx, sp[-1])); BREAK; #endif CASE(OP_get_var_ref): { int idx; JSValue val; idx = get_u16(pc); pc += 2; val = *var_refs[idx]->pvalue; sp[0] = JS_DupValue(ctx, val); sp++; } BREAK; CASE(OP_put_var_ref): { int idx; idx = get_u16(pc); pc += 2; set_value(ctx, var_refs[idx]->pvalue, sp[-1]); sp--; } BREAK; CASE(OP_set_var_ref): { int idx; idx = get_u16(pc); pc += 2; set_value(ctx, var_refs[idx]->pvalue, JS_DupValue(ctx, sp[-1])); } BREAK; CASE(OP_get_var_ref_check): { int idx; JSValue val; idx = get_u16(pc); pc += 2; val = *var_refs[idx]->pvalue; if (unlikely(JS_IsUninitialized(val))) { JS_ThrowReferenceErrorUninitialized2(ctx, b, idx, TRUE); goto exception; } sp[0] = JS_DupValue(ctx, val); sp++; } BREAK; CASE(OP_put_var_ref_check): { int idx; idx = get_u16(pc); pc += 2; if (unlikely(JS_IsUninitialized(*var_refs[idx]->pvalue))) { JS_ThrowReferenceErrorUninitialized2(ctx, b, idx, TRUE); goto exception; } set_value(ctx, var_refs[idx]->pvalue, sp[-1]); sp--; } BREAK; CASE(OP_put_var_ref_check_init): { int idx; idx = get_u16(pc); pc += 2; if (unlikely(!JS_IsUninitialized(*var_refs[idx]->pvalue))) { JS_ThrowReferenceErrorUninitialized2(ctx, b, idx, TRUE); goto exception; } set_value(ctx, var_refs[idx]->pvalue, sp[-1]); sp--; } BREAK; CASE(OP_set_loc_uninitialized): { int idx; idx = get_u16(pc); pc += 2; set_value(ctx, &var_buf[idx], JS_UNINITIALIZED); } BREAK; CASE(OP_get_loc_check): { int idx; idx = get_u16(pc); pc += 2; if (unlikely(JS_IsUninitialized(var_buf[idx]))) { JS_ThrowReferenceErrorUninitialized2(ctx, b, idx, FALSE); goto exception; } sp[0] = JS_DupValue(ctx, var_buf[idx]); sp++; } BREAK; CASE(OP_get_loc_checkthis): { int idx; idx = get_u16(pc); pc += 2; if (unlikely(JS_IsUninitialized(var_buf[idx]))) { JS_ThrowReferenceErrorUninitialized2(caller_ctx, b, idx, FALSE); goto exception; } sp[0] = JS_DupValue(ctx, var_buf[idx]); sp++; } BREAK; CASE(OP_put_loc_check): { int idx; idx = get_u16(pc); pc += 2; if (unlikely(JS_IsUninitialized(var_buf[idx]))) { JS_ThrowReferenceErrorUninitialized2(ctx, b, idx, FALSE); goto exception; } set_value(ctx, &var_buf[idx], sp[-1]); sp--; } BREAK; CASE(OP_set_loc_check): { int idx; idx = get_u16(pc); pc += 2; if (unlikely(JS_IsUninitialized(var_buf[idx]))) { JS_ThrowReferenceErrorUninitialized2(ctx, b, idx, FALSE); goto exception; } set_value(ctx, &var_buf[idx], JS_DupValue(ctx, sp[-1])); } BREAK; CASE(OP_put_loc_check_init): { int idx; idx = get_u16(pc); pc += 2; if (unlikely(!JS_IsUninitialized(var_buf[idx]))) { JS_ThrowReferenceError(ctx, "'this' can be initialized only once"); goto exception; } set_value(ctx, &var_buf[idx], sp[-1]); sp--; } BREAK; CASE(OP_close_loc): { int idx; idx = get_u16(pc); pc += 2; close_lexical_var(ctx, b, sf, idx); } BREAK; CASE(OP_make_loc_ref): CASE(OP_make_arg_ref): CASE(OP_make_var_ref_ref): { JSVarRef *var_ref; JSProperty *pr; JSAtom atom; int idx; atom = get_u32(pc); idx = get_u16(pc + 4); pc += 6; *sp++ = JS_NewObjectProto(ctx, JS_NULL); if (unlikely(JS_IsException(sp[-1]))) goto exception; if (opcode == OP_make_var_ref_ref) { var_ref = var_refs[idx]; var_ref->header.ref_count++; } else { var_ref = get_var_ref(ctx, sf, idx, opcode == OP_make_arg_ref); if (!var_ref) goto exception; } pr = add_property(ctx, JS_VALUE_GET_OBJ(sp[-1]), atom, JS_PROP_WRITABLE | JS_PROP_VARREF); if (!pr) { free_var_ref(rt, var_ref); goto exception; } pr->u.var_ref = var_ref; *sp++ = JS_AtomToValue(ctx, atom); } BREAK; CASE(OP_make_var_ref): { JSAtom atom; atom = get_u32(pc); pc += 4; sf->cur_pc = pc; if (JS_GetGlobalVarRef(ctx, atom, sp)) goto exception; sp += 2; } BREAK; CASE(OP_goto): pc += (int32_t)get_u32(pc); if (unlikely(js_poll_interrupts(ctx))) goto exception; BREAK; #if SHORT_OPCODES CASE(OP_goto16): pc += (int16_t)get_u16(pc); if (unlikely(js_poll_interrupts(ctx))) goto exception; BREAK; CASE(OP_goto8): pc += (int8_t)pc[0]; if (unlikely(js_poll_interrupts(ctx))) goto exception; BREAK; #endif CASE(OP_if_true): { int res; JSValue op1; op1 = sp[-1]; pc += 4; if ((uint32_t)JS_VALUE_GET_TAG(op1) <= JS_TAG_UNDEFINED) { res = JS_VALUE_GET_INT(op1); } else { res = JS_ToBoolFree(ctx, op1); } sp--; if (res) { pc += (int32_t)get_u32(pc - 4) - 4; } if (unlikely(js_poll_interrupts(ctx))) goto exception; } BREAK; CASE(OP_if_false): { int res; JSValue op1; op1 = sp[-1]; pc += 4; /* quick and dirty test for JS_TAG_INT, JS_TAG_BOOL, JS_TAG_NULL and JS_TAG_UNDEFINED */ if ((uint32_t)JS_VALUE_GET_TAG(op1) <= JS_TAG_UNDEFINED) { res = JS_VALUE_GET_INT(op1); } else { res = JS_ToBoolFree(ctx, op1); } sp--; if (!res) { pc += (int32_t)get_u32(pc - 4) - 4; } if (unlikely(js_poll_interrupts(ctx))) goto exception; } BREAK; #if SHORT_OPCODES CASE(OP_if_true8): { int res; JSValue op1; op1 = sp[-1]; pc += 1; if ((uint32_t)JS_VALUE_GET_TAG(op1) <= JS_TAG_UNDEFINED) { res = JS_VALUE_GET_INT(op1); } else { res = JS_ToBoolFree(ctx, op1); } sp--; if (res) { pc += (int8_t)pc[-1] - 1; } if (unlikely(js_poll_interrupts(ctx))) goto exception; } BREAK; CASE(OP_if_false8): { int res; JSValue op1; op1 = sp[-1]; pc += 1; if ((uint32_t)JS_VALUE_GET_TAG(op1) <= JS_TAG_UNDEFINED) { res = JS_VALUE_GET_INT(op1); } else { res = JS_ToBoolFree(ctx, op1); } sp--; if (!res) { pc += (int8_t)pc[-1] - 1; } if (unlikely(js_poll_interrupts(ctx))) goto exception; } BREAK; #endif CASE(OP_catch): { int32_t diff; diff = get_u32(pc); sp[0] = JS_NewCatchOffset(ctx, pc + diff - b->byte_code_buf); sp++; pc += 4; } BREAK; CASE(OP_gosub): { int32_t diff; diff = get_u32(pc); /* XXX: should have a different tag to avoid security flaw */ sp[0] = JS_NewInt32(ctx, pc + 4 - b->byte_code_buf); sp++; pc += diff; } BREAK; CASE(OP_ret): { JSValue op1; uint32_t pos; op1 = sp[-1]; if (unlikely(JS_VALUE_GET_TAG(op1) != JS_TAG_INT)) goto ret_fail; pos = JS_VALUE_GET_INT(op1); if (unlikely(pos >= b->byte_code_len)) { ret_fail: JS_ThrowInternalError(ctx, "invalid ret value"); goto exception; } sp--; pc = b->byte_code_buf + pos; } BREAK; CASE(OP_for_in_start): sf->cur_pc = pc; if (js_for_in_start(ctx, sp)) goto exception; BREAK; CASE(OP_for_in_next): sf->cur_pc = pc; if (js_for_in_next(ctx, sp)) goto exception; sp += 2; BREAK; CASE(OP_for_of_start): sf->cur_pc = pc; if (js_for_of_start(ctx, sp, FALSE)) goto exception; sp += 1; *sp++ = JS_NewCatchOffset(ctx, 0); BREAK; CASE(OP_for_of_next): { int offset = -3 - pc[0]; pc += 1; sf->cur_pc = pc; if (js_for_of_next(ctx, sp, offset)) goto exception; sp += 2; } BREAK; CASE(OP_for_await_of_next): sf->cur_pc = pc; if (js_for_await_of_next(ctx, sp)) goto exception; sp++; BREAK; CASE(OP_for_await_of_start): sf->cur_pc = pc; if (js_for_of_start(ctx, sp, TRUE)) goto exception; sp += 1; *sp++ = JS_NewCatchOffset(ctx, 0); BREAK; CASE(OP_iterator_get_value_done): sf->cur_pc = pc; if (js_iterator_get_value_done(ctx, sp)) goto exception; sp += 1; BREAK; CASE(OP_iterator_check_object): if (unlikely(!JS_IsObject(sp[-1]))) { JS_ThrowTypeError(ctx, "iterator must return an object"); goto exception; } BREAK; CASE(OP_iterator_close): /* iter_obj next catch_offset -> */ sp--; /* drop the catch offset to avoid getting caught by exception */ JS_FreeValue(ctx, sp[-1]); /* drop the next method */ sp--; if (!JS_IsUndefined(sp[-1])) { sf->cur_pc = pc; if (JS_IteratorClose(ctx, sp[-1], FALSE)) goto exception; JS_FreeValue(ctx, sp[-1]); } sp--; BREAK; CASE(OP_nip_catch): { JSValue ret_val; /* catch_offset ... ret_val -> ret_eval */ ret_val = *--sp; while (sp > stack_buf && JS_VALUE_GET_TAG(sp[-1]) != JS_TAG_CATCH_OFFSET) { JS_FreeValue(ctx, *--sp); } if (unlikely(sp == stack_buf)) { JS_ThrowInternalError(ctx, "nip_catch"); JS_FreeValue(ctx, ret_val); goto exception; } sp[-1] = ret_val; } BREAK; CASE(OP_iterator_next): /* stack: iter_obj next catch_offset val */ { JSValue ret; sf->cur_pc = pc; ret = JS_Call(ctx, sp[-3], sp[-4], 1, (JSValueConst *)(sp - 1)); if (JS_IsException(ret)) goto exception; JS_FreeValue(ctx, sp[-1]); sp[-1] = ret; } BREAK; CASE(OP_iterator_call): /* stack: iter_obj next catch_offset val */ { JSValue method, ret; BOOL ret_flag; int flags; flags = *pc++; sf->cur_pc = pc; method = JS_GetProperty(ctx, sp[-4], (flags & 1) ? JS_ATOM_throw : JS_ATOM_return); if (JS_IsException(method)) goto exception; if (JS_IsUndefined(method) || JS_IsNull(method)) { ret_flag = TRUE; } else { if (flags & 2) { /* no argument */ ret = JS_CallFree(ctx, method, sp[-4], 0, NULL); } else { ret = JS_CallFree(ctx, method, sp[-4], 1, (JSValueConst *)(sp - 1)); } if (JS_IsException(ret)) goto exception; JS_FreeValue(ctx, sp[-1]); sp[-1] = ret; ret_flag = FALSE; } sp[0] = JS_NewBool(ctx, ret_flag); sp += 1; } BREAK; CASE(OP_lnot): { int res; JSValue op1; op1 = sp[-1]; if ((uint32_t)JS_VALUE_GET_TAG(op1) <= JS_TAG_UNDEFINED) { res = JS_VALUE_GET_INT(op1) != 0; } else { res = JS_ToBoolFree(ctx, op1); } sp[-1] = JS_NewBool(ctx, !res); } BREAK; #define GET_FIELD_INLINE(name, keep, is_length) \ { \ JSValue val, obj; \ JSAtom atom; \ JSObject *p; \ JSProperty *pr; \ JSShapeProperty *prs; \ \ if (is_length) { \ atom = JS_ATOM_length; \ } else { \ atom = get_u32(pc); \ pc += 4; \ } \ \ obj = sp[-1]; \ if (likely(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT)) { \ p = JS_VALUE_GET_OBJ(obj); \ for(;;) { \ prs = find_own_property(&pr, p, atom); \ if (prs) { \ /* found */ \ if (unlikely(prs->flags & JS_PROP_TMASK)) \ goto name ## _slow_path; \ val = JS_DupValue(ctx, pr->u.value); \ break; \ } \ if (unlikely(p->is_exotic)) { \ /* XXX: should avoid the slow path for arrays \ and typed arrays by ensuring that 'prop' is \ not numeric */ \ obj = JS_MKPTR(JS_TAG_OBJECT, p); \ goto name ## _slow_path; \ } \ p = p->shape->proto; \ if (!p) { \ val = JS_UNDEFINED; \ break; \ } \ } \ } else { \ name ## _slow_path: \ sf->cur_pc = pc; \ val = JS_GetPropertyInternal(ctx, obj, atom, sp[-1], 0); \ if (unlikely(JS_IsException(val))) \ goto exception; \ } \ if (keep) { \ *sp++ = val; \ } else { \ JS_FreeValue(ctx, sp[-1]); \ sp[-1] = val; \ } \ } CASE(OP_get_field): GET_FIELD_INLINE(get_field, 0, 0); BREAK; CASE(OP_get_field2): GET_FIELD_INLINE(get_field2, 1, 0); BREAK; #if SHORT_OPCODES CASE(OP_get_length): GET_FIELD_INLINE(get_length, 0, 1); BREAK; #endif CASE(OP_put_field): { int ret; JSValue obj; JSAtom atom; JSObject *p; JSProperty *pr; JSShapeProperty *prs; atom = get_u32(pc); pc += 4; obj = sp[-2]; if (likely(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT)) { p = JS_VALUE_GET_OBJ(obj); prs = find_own_property(&pr, p, atom); if (!prs) goto put_field_slow_path; if (likely((prs->flags & (JS_PROP_TMASK | JS_PROP_WRITABLE | JS_PROP_LENGTH)) == JS_PROP_WRITABLE)) { /* fast path */ set_value(ctx, &pr->u.value, sp[-1]); } else { goto put_field_slow_path; } JS_FreeValue(ctx, obj); sp -= 2; } else { put_field_slow_path: sf->cur_pc = pc; ret = JS_SetPropertyInternal(ctx, obj, atom, sp[-1], obj, JS_PROP_THROW_STRICT); JS_FreeValue(ctx, obj); sp -= 2; if (unlikely(ret < 0)) goto exception; } } BREAK; CASE(OP_private_symbol): { JSAtom atom; JSValue val; atom = get_u32(pc); pc += 4; val = JS_NewSymbolFromAtom(ctx, atom, JS_ATOM_TYPE_PRIVATE); if (JS_IsException(val)) goto exception; *sp++ = val; } BREAK; CASE(OP_get_private_field): { JSValue val; val = JS_GetPrivateField(ctx, sp[-2], sp[-1]); JS_FreeValue(ctx, sp[-1]); JS_FreeValue(ctx, sp[-2]); sp[-2] = val; sp--; if (unlikely(JS_IsException(val))) goto exception; } BREAK; CASE(OP_put_private_field): { int ret; ret = JS_SetPrivateField(ctx, sp[-3], sp[-1], sp[-2]); JS_FreeValue(ctx, sp[-3]); JS_FreeValue(ctx, sp[-1]); sp -= 3; if (unlikely(ret < 0)) goto exception; } BREAK; CASE(OP_define_private_field): { int ret; ret = JS_DefinePrivateField(ctx, sp[-3], sp[-2], sp[-1]); JS_FreeValue(ctx, sp[-2]); sp -= 2; if (unlikely(ret < 0)) goto exception; } BREAK; CASE(OP_define_field): { int ret; JSAtom atom; atom = get_u32(pc); pc += 4; ret = JS_DefinePropertyValue(ctx, sp[-2], atom, sp[-1], JS_PROP_C_W_E | JS_PROP_THROW); sp--; if (unlikely(ret < 0)) goto exception; } BREAK; CASE(OP_set_name): { int ret; JSAtom atom; atom = get_u32(pc); pc += 4; ret = JS_DefineObjectName(ctx, sp[-1], atom, JS_PROP_CONFIGURABLE); if (unlikely(ret < 0)) goto exception; } BREAK; CASE(OP_set_name_computed): { int ret; ret = JS_DefineObjectNameComputed(ctx, sp[-1], sp[-2], JS_PROP_CONFIGURABLE); if (unlikely(ret < 0)) goto exception; } BREAK; CASE(OP_set_proto): { JSValue proto; sf->cur_pc = pc; proto = sp[-1]; if (JS_IsObject(proto) || JS_IsNull(proto)) { if (JS_SetPrototypeInternal(ctx, sp[-2], proto, TRUE) < 0) goto exception; } JS_FreeValue(ctx, proto); sp--; } BREAK; CASE(OP_set_home_object): js_method_set_home_object(ctx, sp[-1], sp[-2]); BREAK; CASE(OP_define_method): CASE(OP_define_method_computed): { JSValue getter, setter, value; JSValueConst obj; JSAtom atom; int flags, ret, op_flags; BOOL is_computed; #define OP_DEFINE_METHOD_METHOD 0 #define OP_DEFINE_METHOD_GETTER 1 #define OP_DEFINE_METHOD_SETTER 2 #define OP_DEFINE_METHOD_ENUMERABLE 4 is_computed = (opcode == OP_define_method_computed); if (is_computed) { atom = JS_ValueToAtom(ctx, sp[-2]); if (unlikely(atom == JS_ATOM_NULL)) goto exception; opcode += OP_define_method - OP_define_method_computed; } else { atom = get_u32(pc); pc += 4; } op_flags = *pc++; obj = sp[-2 - is_computed]; flags = JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE | JS_PROP_HAS_ENUMERABLE | JS_PROP_THROW; if (op_flags & OP_DEFINE_METHOD_ENUMERABLE) flags |= JS_PROP_ENUMERABLE; op_flags &= 3; value = JS_UNDEFINED; getter = JS_UNDEFINED; setter = JS_UNDEFINED; if (op_flags == OP_DEFINE_METHOD_METHOD) { value = sp[-1]; flags |= JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE; } else if (op_flags == OP_DEFINE_METHOD_GETTER) { getter = sp[-1]; flags |= JS_PROP_HAS_GET; } else { setter = sp[-1]; flags |= JS_PROP_HAS_SET; } ret = js_method_set_properties(ctx, sp[-1], atom, flags, obj); if (ret >= 0) { ret = JS_DefineProperty(ctx, obj, atom, value, getter, setter, flags); } JS_FreeValue(ctx, sp[-1]); if (is_computed) { JS_FreeAtom(ctx, atom); JS_FreeValue(ctx, sp[-2]); } sp -= 1 + is_computed; if (unlikely(ret < 0)) goto exception; } BREAK; CASE(OP_define_class): CASE(OP_define_class_computed): { int class_flags; JSAtom atom; atom = get_u32(pc); class_flags = pc[4]; pc += 5; if (js_op_define_class(ctx, sp, atom, class_flags, var_refs, sf, (opcode == OP_define_class_computed)) < 0) goto exception; } BREAK; #define GET_ARRAY_EL_INLINE(name, keep) \ { \ JSValue val, obj, prop; \ JSObject *p; \ uint32_t idx; \ \ obj = sp[-2]; \ prop = sp[-1]; \ if (likely(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT && \ JS_VALUE_GET_TAG(prop) == JS_TAG_INT)) { \ p = JS_VALUE_GET_OBJ(obj); \ idx = JS_VALUE_GET_INT(prop); \ if (unlikely(p->class_id != JS_CLASS_ARRAY)) \ goto name ## _slow_path; \ if (unlikely(idx >= p->u.array.count)) \ goto name ## _slow_path; \ val = JS_DupValue(ctx, p->u.array.u.values[idx]); \ } else { \ name ## _slow_path: \ sf->cur_pc = pc; \ val = JS_GetPropertyValue(ctx, obj, prop); \ if (unlikely(JS_IsException(val))) { \ if (keep) \ sp[-1] = JS_UNDEFINED; \ else \ sp--; \ goto exception; \ } \ } \ if (keep) { \ sp[-1] = val; \ } else { \ JS_FreeValue(ctx, obj); \ sp[-2] = val; \ sp--; \ } \ } CASE(OP_get_array_el): GET_ARRAY_EL_INLINE(get_array_el, 0); BREAK; CASE(OP_get_array_el2): GET_ARRAY_EL_INLINE(get_array_el2, 1); BREAK; CASE(OP_get_array_el3): { JSValue val; JSObject *p; uint32_t idx; if (likely(JS_VALUE_GET_TAG(sp[-2]) == JS_TAG_OBJECT && JS_VALUE_GET_TAG(sp[-1]) == JS_TAG_INT)) { p = JS_VALUE_GET_OBJ(sp[-2]); idx = JS_VALUE_GET_INT(sp[-1]); if (unlikely(p->class_id != JS_CLASS_ARRAY)) goto get_array_el3_slow_path; if (unlikely(idx >= p->u.array.count)) goto get_array_el3_slow_path; val = JS_DupValue(ctx, p->u.array.u.values[idx]); } else { get_array_el3_slow_path: switch (JS_VALUE_GET_TAG(sp[-1])) { case JS_TAG_INT: case JS_TAG_STRING: case JS_TAG_SYMBOL: /* undefined and null are tested in JS_GetPropertyValue() */ break; default: /* must be tested before JS_ToPropertyKey */ if (unlikely(JS_IsUndefined(sp[-2]) || JS_IsNull(sp[-2]))) { JS_ThrowTypeError(ctx, "value has no property"); goto exception; } sf->cur_pc = pc; ret_val = JS_ToPropertyKey(ctx, sp[-1]); if (JS_IsException(ret_val)) goto exception; JS_FreeValue(ctx, sp[-1]); sp[-1] = ret_val; break; } sf->cur_pc = pc; val = JS_GetPropertyValue(ctx, sp[-2], JS_DupValue(ctx, sp[-1])); if (unlikely(JS_IsException(val))) goto exception; } *sp++ = val; } BREAK; CASE(OP_get_ref_value): { JSValue val; JSAtom atom; int ret; sf->cur_pc = pc; atom = JS_ValueToAtom(ctx, sp[-1]); if (atom == JS_ATOM_NULL) goto exception; if (unlikely(JS_IsUndefined(sp[-2]))) { JS_ThrowReferenceErrorNotDefined(ctx, atom); JS_FreeAtom(ctx, atom); goto exception; } ret = JS_HasProperty(ctx, sp[-2], atom); if (unlikely(ret <= 0)) { if (ret < 0) { JS_FreeAtom(ctx, atom); goto exception; } if (is_strict_mode(ctx)) { JS_ThrowReferenceErrorNotDefined(ctx, atom); JS_FreeAtom(ctx, atom); goto exception; } val = JS_UNDEFINED; } else { val = JS_GetProperty(ctx, sp[-2], atom); } JS_FreeAtom(ctx, atom); if (unlikely(JS_IsException(val))) goto exception; sp[0] = val; sp++; } BREAK; CASE(OP_get_super_value): { JSValue val; JSAtom atom; sf->cur_pc = pc; atom = JS_ValueToAtom(ctx, sp[-1]); if (unlikely(atom == JS_ATOM_NULL)) goto exception; val = JS_GetPropertyInternal(ctx, sp[-2], atom, sp[-3], FALSE); JS_FreeAtom(ctx, atom); if (unlikely(JS_IsException(val))) goto exception; JS_FreeValue(ctx, sp[-1]); JS_FreeValue(ctx, sp[-2]); JS_FreeValue(ctx, sp[-3]); sp[-3] = val; sp -= 2; } BREAK; CASE(OP_put_array_el): { int ret; JSObject *p; uint32_t idx; if (likely(JS_VALUE_GET_TAG(sp[-3]) == JS_TAG_OBJECT && JS_VALUE_GET_TAG(sp[-2]) == JS_TAG_INT)) { p = JS_VALUE_GET_OBJ(sp[-3]); idx = JS_VALUE_GET_INT(sp[-2]); if (unlikely(p->class_id != JS_CLASS_ARRAY)) goto put_array_el_slow_path; if (unlikely(idx >= (uint32_t)p->u.array.count)) { uint32_t new_len, array_len; if (unlikely(idx != (uint32_t)p->u.array.count || !p->fast_array || !can_extend_fast_array(p))) { goto put_array_el_slow_path; } if (likely(JS_VALUE_GET_TAG(p->prop[0].u.value) != JS_TAG_INT)) goto put_array_el_slow_path; /* cannot overflow otherwise the length would not be an integer */ new_len = idx + 1; if (unlikely(new_len > p->u.array.u1.size)) goto put_array_el_slow_path; array_len = JS_VALUE_GET_INT(p->prop[0].u.value); if (new_len > array_len) { if (unlikely(!(get_shape_prop(p->shape)->flags & JS_PROP_WRITABLE))) goto put_array_el_slow_path; p->prop[0].u.value = JS_NewInt32(ctx, new_len); } p->u.array.count = new_len; p->u.array.u.values[idx] = sp[-1]; } else { set_value(ctx, &p->u.array.u.values[idx], sp[-1]); } JS_FreeValue(ctx, sp[-3]); sp -= 3; } else { put_array_el_slow_path: sf->cur_pc = pc; ret = JS_SetPropertyValue(ctx, sp[-3], sp[-2], sp[-1], JS_PROP_THROW_STRICT); JS_FreeValue(ctx, sp[-3]); sp -= 3; if (unlikely(ret < 0)) goto exception; } } BREAK; CASE(OP_put_ref_value): { int ret; JSAtom atom; sf->cur_pc = pc; atom = JS_ValueToAtom(ctx, sp[-2]); if (unlikely(atom == JS_ATOM_NULL)) goto exception; if (unlikely(JS_IsUndefined(sp[-3]))) { if (is_strict_mode(ctx)) { JS_ThrowReferenceErrorNotDefined(ctx, atom); JS_FreeAtom(ctx, atom); goto exception; } else { sp[-3] = JS_DupValue(ctx, ctx->global_obj); } } ret = JS_HasProperty(ctx, sp[-3], atom); if (unlikely(ret <= 0)) { if (unlikely(ret < 0)) { JS_FreeAtom(ctx, atom); goto exception; } if (is_strict_mode(ctx)) { JS_ThrowReferenceErrorNotDefined(ctx, atom); JS_FreeAtom(ctx, atom); goto exception; } } ret = JS_SetPropertyInternal(ctx, sp[-3], atom, sp[-1], sp[-3], JS_PROP_THROW_STRICT); JS_FreeAtom(ctx, atom); JS_FreeValue(ctx, sp[-2]); JS_FreeValue(ctx, sp[-3]); sp -= 3; if (unlikely(ret < 0)) goto exception; } BREAK; CASE(OP_put_super_value): { int ret; JSAtom atom; sf->cur_pc = pc; if (JS_VALUE_GET_TAG(sp[-3]) != JS_TAG_OBJECT) { JS_ThrowTypeErrorNotAnObject(ctx); goto exception; } atom = JS_ValueToAtom(ctx, sp[-2]); if (unlikely(atom == JS_ATOM_NULL)) goto exception; ret = JS_SetPropertyInternal(ctx, sp[-3], atom, sp[-1], sp[-4], JS_PROP_THROW_STRICT); JS_FreeAtom(ctx, atom); JS_FreeValue(ctx, sp[-4]); JS_FreeValue(ctx, sp[-3]); JS_FreeValue(ctx, sp[-2]); sp -= 4; if (ret < 0) goto exception; } BREAK; CASE(OP_define_array_el): { int ret; ret = JS_DefinePropertyValueValue(ctx, sp[-3], JS_DupValue(ctx, sp[-2]), sp[-1], JS_PROP_C_W_E | JS_PROP_THROW); sp -= 1; if (unlikely(ret < 0)) goto exception; } BREAK; CASE(OP_append): /* array pos enumobj -- array pos */ { sf->cur_pc = pc; if (js_append_enumerate(ctx, sp)) goto exception; JS_FreeValue(ctx, *--sp); } BREAK; CASE(OP_copy_data_properties): /* target source excludeList */ { /* stack offsets (-1 based): 2 bits for target, 3 bits for source, 2 bits for exclusionList */ int mask; mask = *pc++; sf->cur_pc = pc; if (JS_CopyDataProperties(ctx, sp[-1 - (mask & 3)], sp[-1 - ((mask >> 2) & 7)], sp[-1 - ((mask >> 5) & 7)], 0)) goto exception; } BREAK; CASE(OP_add): { JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { int64_t r; r = (int64_t)JS_VALUE_GET_INT(op1) + JS_VALUE_GET_INT(op2); if (unlikely((int)r != r)) { sp[-2] = __JS_NewFloat64(ctx, (double)r); } else { sp[-2] = JS_NewInt32(ctx, r); } sp--; } else if (JS_VALUE_IS_BOTH_FLOAT(op1, op2)) { sp[-2] = __JS_NewFloat64(ctx, JS_VALUE_GET_FLOAT64(op1) + JS_VALUE_GET_FLOAT64(op2)); sp--; } else if (JS_IsString(op1) && JS_IsString(op2)) { sp[-2] = JS_ConcatString(ctx, op1, op2); sp--; if (JS_IsException(sp[-1])) goto exception; } else { sf->cur_pc = pc; if (js_add_slow(ctx, sp)) goto exception; sp--; } } BREAK; CASE(OP_add_loc): { JSValue op2; JSValue *pv; int idx; idx = *pc; pc += 1; op2 = sp[-1]; pv = &var_buf[idx]; if (likely(JS_VALUE_IS_BOTH_INT(*pv, op2))) { int64_t r; r = (int64_t)JS_VALUE_GET_INT(*pv) + JS_VALUE_GET_INT(op2); if (unlikely((int)r != r)) { *pv = __JS_NewFloat64(ctx, (double)r); } else { *pv = JS_NewInt32(ctx, r); } sp--; } else if (JS_VALUE_IS_BOTH_FLOAT(*pv, op2)) { *pv = __JS_NewFloat64(ctx, JS_VALUE_GET_FLOAT64(*pv) + JS_VALUE_GET_FLOAT64(op2)); sp--; } else if (JS_VALUE_GET_TAG(*pv) == JS_TAG_STRING && JS_VALUE_GET_TAG(op2) == JS_TAG_STRING) { sp--; sf->cur_pc = pc; if (JS_ConcatStringInPlace(ctx, JS_VALUE_GET_STRING(*pv), op2)) { JS_FreeValue(ctx, op2); } else { op2 = JS_ConcatString(ctx, JS_DupValue(ctx, *pv), op2); if (JS_IsException(op2)) goto exception; set_value(ctx, pv, op2); } } else { JSValue ops[2]; /* In case of exception, js_add_slow frees ops[0] and ops[1], so we must duplicate *pv */ sf->cur_pc = pc; ops[0] = JS_DupValue(ctx, *pv); ops[1] = op2; sp--; if (js_add_slow(ctx, ops + 2)) goto exception; set_value(ctx, pv, ops[0]); } } BREAK; CASE(OP_sub): { JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { int64_t r; r = (int64_t)JS_VALUE_GET_INT(op1) - JS_VALUE_GET_INT(op2); if (unlikely((int)r != r)) { sp[-2] = __JS_NewFloat64(ctx, (double)r); } else { sp[-2] = JS_NewInt32(ctx, r); } sp--; } else if (JS_VALUE_IS_BOTH_FLOAT(op1, op2)) { sp[-2] = __JS_NewFloat64(ctx, JS_VALUE_GET_FLOAT64(op1) - JS_VALUE_GET_FLOAT64(op2)); sp--; } else { goto binary_arith_slow; } } BREAK; CASE(OP_mul): { JSValue op1, op2; double d; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { int32_t v1, v2; int64_t r; v1 = JS_VALUE_GET_INT(op1); v2 = JS_VALUE_GET_INT(op2); r = (int64_t)v1 * v2; if (unlikely((int)r != r)) { d = (double)r; goto mul_fp_res; } /* need to test zero case for -0 result */ if (unlikely(r == 0 && (v1 | v2) < 0)) { d = -0.0; goto mul_fp_res; } sp[-2] = JS_NewInt32(ctx, r); sp--; } else if (JS_VALUE_IS_BOTH_FLOAT(op1, op2)) { d = JS_VALUE_GET_FLOAT64(op1) * JS_VALUE_GET_FLOAT64(op2); mul_fp_res: sp[-2] = __JS_NewFloat64(ctx, d); sp--; } else { goto binary_arith_slow; } } BREAK; CASE(OP_div): { JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { int v1, v2; v1 = JS_VALUE_GET_INT(op1); v2 = JS_VALUE_GET_INT(op2); sp[-2] = JS_NewFloat64(ctx, (double)v1 / (double)v2); sp--; } else { goto binary_arith_slow; } } BREAK; CASE(OP_mod): { JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { int v1, v2, r; v1 = JS_VALUE_GET_INT(op1); v2 = JS_VALUE_GET_INT(op2); /* We must avoid v2 = 0, v1 = INT32_MIN and v2 = -1 and the cases where the result is -0. */ if (unlikely(v1 < 0 || v2 <= 0)) goto binary_arith_slow; r = v1 % v2; sp[-2] = JS_NewInt32(ctx, r); sp--; } else { goto binary_arith_slow; } } BREAK; CASE(OP_pow): binary_arith_slow: sf->cur_pc = pc; if (js_binary_arith_slow(ctx, sp, opcode)) goto exception; sp--; BREAK; CASE(OP_plus): { JSValue op1; uint32_t tag; op1 = sp[-1]; tag = JS_VALUE_GET_TAG(op1); if (tag == JS_TAG_INT || JS_TAG_IS_FLOAT64(tag)) { } else if (tag == JS_TAG_NULL || tag == JS_TAG_BOOL) { sp[-1] = JS_NewInt32(ctx, JS_VALUE_GET_INT(op1)); } else { sf->cur_pc = pc; if (js_unary_arith_slow(ctx, sp, opcode)) goto exception; } } BREAK; CASE(OP_neg): { JSValue op1; uint32_t tag; int val; double d; op1 = sp[-1]; tag = JS_VALUE_GET_TAG(op1); if (tag == JS_TAG_INT || tag == JS_TAG_BOOL || tag == JS_TAG_NULL) { val = JS_VALUE_GET_INT(op1); /* Note: -0 cannot be expressed as integer */ if (unlikely(val == 0)) { d = -0.0; goto neg_fp_res; } if (unlikely(val == INT32_MIN)) { d = -(double)val; goto neg_fp_res; } sp[-1] = JS_NewInt32(ctx, -val); } else if (JS_TAG_IS_FLOAT64(tag)) { d = -JS_VALUE_GET_FLOAT64(op1); neg_fp_res: sp[-1] = __JS_NewFloat64(ctx, d); } else { sf->cur_pc = pc; if (js_unary_arith_slow(ctx, sp, opcode)) goto exception; } } BREAK; CASE(OP_inc): { JSValue op1; int val; op1 = sp[-1]; if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { val = JS_VALUE_GET_INT(op1); if (unlikely(val == INT32_MAX)) goto inc_slow; sp[-1] = JS_NewInt32(ctx, val + 1); } else { inc_slow: sf->cur_pc = pc; if (js_unary_arith_slow(ctx, sp, opcode)) goto exception; } } BREAK; CASE(OP_dec): { JSValue op1; int val; op1 = sp[-1]; if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { val = JS_VALUE_GET_INT(op1); if (unlikely(val == INT32_MIN)) goto dec_slow; sp[-1] = JS_NewInt32(ctx, val - 1); } else { dec_slow: sf->cur_pc = pc; if (js_unary_arith_slow(ctx, sp, opcode)) goto exception; } } BREAK; CASE(OP_post_inc): { JSValue op1; int val; op1 = sp[-1]; if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { val = JS_VALUE_GET_INT(op1); if (unlikely(val == INT32_MAX)) goto post_inc_slow; sp[0] = JS_NewInt32(ctx, val + 1); } else { post_inc_slow: sf->cur_pc = pc; if (js_post_inc_slow(ctx, sp, opcode)) goto exception; } sp++; } BREAK; CASE(OP_post_dec): { JSValue op1; int val; op1 = sp[-1]; if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { val = JS_VALUE_GET_INT(op1); if (unlikely(val == INT32_MIN)) goto post_dec_slow; sp[0] = JS_NewInt32(ctx, val - 1); } else { post_dec_slow: sf->cur_pc = pc; if (js_post_inc_slow(ctx, sp, opcode)) goto exception; } sp++; } BREAK; CASE(OP_inc_loc): { JSValue op1; int val; int idx; idx = *pc; pc += 1; op1 = var_buf[idx]; if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { val = JS_VALUE_GET_INT(op1); if (unlikely(val == INT32_MAX)) goto inc_loc_slow; var_buf[idx] = JS_NewInt32(ctx, val + 1); } else { inc_loc_slow: sf->cur_pc = pc; /* must duplicate otherwise the variable value may be destroyed before JS code accesses it */ op1 = JS_DupValue(ctx, op1); if (js_unary_arith_slow(ctx, &op1 + 1, OP_inc)) goto exception; set_value(ctx, &var_buf[idx], op1); } } BREAK; CASE(OP_dec_loc): { JSValue op1; int val; int idx; idx = *pc; pc += 1; op1 = var_buf[idx]; if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { val = JS_VALUE_GET_INT(op1); if (unlikely(val == INT32_MIN)) goto dec_loc_slow; var_buf[idx] = JS_NewInt32(ctx, val - 1); } else { dec_loc_slow: sf->cur_pc = pc; /* must duplicate otherwise the variable value may be destroyed before JS code accesses it */ op1 = JS_DupValue(ctx, op1); if (js_unary_arith_slow(ctx, &op1 + 1, OP_dec)) goto exception; set_value(ctx, &var_buf[idx], op1); } } BREAK; CASE(OP_not): { JSValue op1; op1 = sp[-1]; if (JS_VALUE_GET_TAG(op1) == JS_TAG_INT) { sp[-1] = JS_NewInt32(ctx, ~JS_VALUE_GET_INT(op1)); } else { sf->cur_pc = pc; if (js_not_slow(ctx, sp)) goto exception; } } BREAK; CASE(OP_shl): { JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { uint32_t v1, v2; v1 = JS_VALUE_GET_INT(op1); v2 = JS_VALUE_GET_INT(op2); v2 &= 0x1f; sp[-2] = JS_NewInt32(ctx, v1 << v2); sp--; } else { sf->cur_pc = pc; if (js_binary_logic_slow(ctx, sp, opcode)) goto exception; sp--; } } BREAK; CASE(OP_shr): { JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { uint32_t v2; v2 = JS_VALUE_GET_INT(op2); v2 &= 0x1f; sp[-2] = JS_NewUint32(ctx, (uint32_t)JS_VALUE_GET_INT(op1) >> v2); sp--; } else { sf->cur_pc = pc; if (js_shr_slow(ctx, sp)) goto exception; sp--; } } BREAK; CASE(OP_sar): { JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { uint32_t v2; v2 = JS_VALUE_GET_INT(op2); v2 &= 0x1f; sp[-2] = JS_NewInt32(ctx, (int)JS_VALUE_GET_INT(op1) >> v2); sp--; } else { sf->cur_pc = pc; if (js_binary_logic_slow(ctx, sp, opcode)) goto exception; sp--; } } BREAK; CASE(OP_and): { JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { sp[-2] = JS_NewInt32(ctx, JS_VALUE_GET_INT(op1) & JS_VALUE_GET_INT(op2)); sp--; } else { sf->cur_pc = pc; if (js_binary_logic_slow(ctx, sp, opcode)) goto exception; sp--; } } BREAK; CASE(OP_or): { JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { sp[-2] = JS_NewInt32(ctx, JS_VALUE_GET_INT(op1) | JS_VALUE_GET_INT(op2)); sp--; } else { sf->cur_pc = pc; if (js_binary_logic_slow(ctx, sp, opcode)) goto exception; sp--; } } BREAK; CASE(OP_xor): { JSValue op1, op2; op1 = sp[-2]; op2 = sp[-1]; if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { sp[-2] = JS_NewInt32(ctx, JS_VALUE_GET_INT(op1) ^ JS_VALUE_GET_INT(op2)); sp--; } else { sf->cur_pc = pc; if (js_binary_logic_slow(ctx, sp, opcode)) goto exception; sp--; } } BREAK; #define OP_CMP(opcode, binary_op, slow_call) \ CASE(opcode): \ { \ JSValue op1, op2; \ op1 = sp[-2]; \ op2 = sp[-1]; \ if (likely(JS_VALUE_IS_BOTH_INT(op1, op2))) { \ sp[-2] = JS_NewBool(ctx, JS_VALUE_GET_INT(op1) binary_op JS_VALUE_GET_INT(op2)); \ sp--; \ } else { \ sf->cur_pc = pc; \ if (slow_call) \ goto exception; \ sp--; \ } \ } \ BREAK OP_CMP(OP_lt, <, js_relational_slow(ctx, sp, opcode)); OP_CMP(OP_lte, <=, js_relational_slow(ctx, sp, opcode)); OP_CMP(OP_gt, >, js_relational_slow(ctx, sp, opcode)); OP_CMP(OP_gte, >=, js_relational_slow(ctx, sp, opcode)); OP_CMP(OP_eq, ==, js_eq_slow(ctx, sp, 0)); OP_CMP(OP_neq, !=, js_eq_slow(ctx, sp, 1)); OP_CMP(OP_strict_eq, ==, js_strict_eq_slow(ctx, sp, 0)); OP_CMP(OP_strict_neq, !=, js_strict_eq_slow(ctx, sp, 1)); CASE(OP_in): sf->cur_pc = pc; if (js_operator_in(ctx, sp)) goto exception; sp--; BREAK; CASE(OP_private_in): sf->cur_pc = pc; if (js_operator_private_in(ctx, sp)) goto exception; sp--; BREAK; CASE(OP_instanceof): sf->cur_pc = pc; if (js_operator_instanceof(ctx, sp)) goto exception; sp--; BREAK; CASE(OP_typeof): { JSValue op1; JSAtom atom; op1 = sp[-1]; atom = js_operator_typeof(ctx, op1); JS_FreeValue(ctx, op1); sp[-1] = JS_AtomToString(ctx, atom); } BREAK; CASE(OP_delete): sf->cur_pc = pc; if (js_operator_delete(ctx, sp)) goto exception; sp--; BREAK; CASE(OP_delete_var): { JSAtom atom; int ret; atom = get_u32(pc); pc += 4; sf->cur_pc = pc; ret = JS_DeleteGlobalVar(ctx, atom); if (unlikely(ret < 0)) goto exception; *sp++ = JS_NewBool(ctx, ret); } BREAK; CASE(OP_to_object): if (JS_VALUE_GET_TAG(sp[-1]) != JS_TAG_OBJECT) { sf->cur_pc = pc; ret_val = JS_ToObject(ctx, sp[-1]); if (JS_IsException(ret_val)) goto exception; JS_FreeValue(ctx, sp[-1]); sp[-1] = ret_val; } BREAK; CASE(OP_to_propkey): switch (JS_VALUE_GET_TAG(sp[-1])) { case JS_TAG_INT: case JS_TAG_STRING: case JS_TAG_SYMBOL: break; default: sf->cur_pc = pc; ret_val = JS_ToPropertyKey(ctx, sp[-1]); if (JS_IsException(ret_val)) goto exception; JS_FreeValue(ctx, sp[-1]); sp[-1] = ret_val; break; } BREAK; #if 0 CASE(OP_to_string): if (JS_VALUE_GET_TAG(sp[-1]) != JS_TAG_STRING) { ret_val = JS_ToString(ctx, sp[-1]); if (JS_IsException(ret_val)) goto exception; JS_FreeValue(ctx, sp[-1]); sp[-1] = ret_val; } BREAK; #endif CASE(OP_with_get_var): CASE(OP_with_put_var): CASE(OP_with_delete_var): CASE(OP_with_make_ref): CASE(OP_with_get_ref): { JSAtom atom; int32_t diff; JSValue obj, val; int ret, is_with; atom = get_u32(pc); diff = get_u32(pc + 4); is_with = pc[8]; pc += 9; sf->cur_pc = pc; obj = sp[-1]; ret = JS_HasProperty(ctx, obj, atom); if (unlikely(ret < 0)) goto exception; if (ret) { if (is_with) { ret = js_has_unscopable(ctx, obj, atom); if (unlikely(ret < 0)) goto exception; if (ret) goto no_with; } switch (opcode) { case OP_with_get_var: /* in Object Environment Records, GetBindingValue() calls HasProperty() */ ret = JS_HasProperty(ctx, obj, atom); if (unlikely(ret <= 0)) { if (ret < 0) goto exception; if (is_strict_mode(ctx)) { JS_ThrowReferenceErrorNotDefined(ctx, atom); goto exception; } val = JS_UNDEFINED; } else { val = JS_GetProperty(ctx, obj, atom); if (unlikely(JS_IsException(val))) goto exception; } set_value(ctx, &sp[-1], val); break; case OP_with_put_var: /* used e.g. in for in/of */ /* in Object Environment Records, SetMutableBinding() calls HasProperty() */ ret = JS_HasProperty(ctx, obj, atom); if (unlikely(ret <= 0)) { if (ret < 0) goto exception; if (is_strict_mode(ctx)) { JS_ThrowReferenceErrorNotDefined(ctx, atom); goto exception; } } ret = JS_SetPropertyInternal(ctx, obj, atom, sp[-2], obj, JS_PROP_THROW_STRICT); JS_FreeValue(ctx, sp[-1]); sp -= 2; if (unlikely(ret < 0)) goto exception; break; case OP_with_delete_var: ret = JS_DeleteProperty(ctx, obj, atom, 0); if (unlikely(ret < 0)) goto exception; JS_FreeValue(ctx, sp[-1]); sp[-1] = JS_NewBool(ctx, ret); break; case OP_with_make_ref: /* produce a pair object/propname on the stack */ *sp++ = JS_AtomToValue(ctx, atom); break; case OP_with_get_ref: /* produce a pair object/method on the stack */ /* in Object Environment Records, GetBindingValue() calls HasProperty() */ ret = JS_HasProperty(ctx, obj, atom); if (unlikely(ret < 0)) goto exception; if (!ret) { val = JS_UNDEFINED; } else { val = JS_GetProperty(ctx, obj, atom); if (unlikely(JS_IsException(val))) goto exception; } *sp++ = val; break; } pc += diff - 5; } else { no_with: /* if not jumping, drop the object argument */ JS_FreeValue(ctx, sp[-1]); sp--; } } BREAK; CASE(OP_await): ret_val = JS_NewInt32(ctx, FUNC_RET_AWAIT); goto done_generator; CASE(OP_yield): ret_val = JS_NewInt32(ctx, FUNC_RET_YIELD); goto done_generator; CASE(OP_yield_star): CASE(OP_async_yield_star): ret_val = JS_NewInt32(ctx, FUNC_RET_YIELD_STAR); goto done_generator; CASE(OP_return_async): ret_val = JS_UNDEFINED; goto done_generator; CASE(OP_initial_yield): ret_val = JS_NewInt32(ctx, FUNC_RET_INITIAL_YIELD); goto done_generator; CASE(OP_nop): BREAK; CASE(OP_is_undefined_or_null): if (JS_VALUE_GET_TAG(sp[-1]) == JS_TAG_UNDEFINED || JS_VALUE_GET_TAG(sp[-1]) == JS_TAG_NULL) { goto set_true; } else { goto free_and_set_false; } #if SHORT_OPCODES CASE(OP_is_undefined): if (JS_VALUE_GET_TAG(sp[-1]) == JS_TAG_UNDEFINED) { goto set_true; } else { goto free_and_set_false; } CASE(OP_is_null): if (JS_VALUE_GET_TAG(sp[-1]) == JS_TAG_NULL) { goto set_true; } else { goto free_and_set_false; } /* XXX: could merge to a single opcode */ CASE(OP_typeof_is_undefined): /* different from OP_is_undefined because of isHTMLDDA */ if (js_operator_typeof(ctx, sp[-1]) == JS_ATOM_undefined) { goto free_and_set_true; } else { goto free_and_set_false; } CASE(OP_typeof_is_function): if (js_operator_typeof(ctx, sp[-1]) == JS_ATOM_function) { goto free_and_set_true; } else { goto free_and_set_false; } free_and_set_true: JS_FreeValue(ctx, sp[-1]); #endif set_true: sp[-1] = JS_TRUE; BREAK; free_and_set_false: JS_FreeValue(ctx, sp[-1]); sp[-1] = JS_FALSE; BREAK; CASE(OP_invalid): DEFAULT: JS_ThrowInternalError(ctx, "invalid opcode: pc=%u opcode=0x%02x", (int)(pc - b->byte_code_buf - 1), opcode); goto exception; } } exception: if (is_backtrace_needed(ctx, rt->current_exception)) { /* add the backtrace information now (it is not done before if the exception happens in a bytecode operation */ sf->cur_pc = pc; build_backtrace(ctx, rt->current_exception, JS_UNDEFINED, NULL, 0, 0, 0); } if (!rt->current_exception_is_uncatchable) { while (sp > stack_buf) { JSValue val = *--sp; JS_FreeValue(ctx, val); if (JS_VALUE_GET_TAG(val) == JS_TAG_CATCH_OFFSET) { int pos = JS_VALUE_GET_INT(val); if (pos == 0) { /* enumerator: close it with a throw */ JS_FreeValue(ctx, sp[-1]); /* drop the next method */ sp--; JS_IteratorClose(ctx, sp[-1], TRUE); } else { *sp++ = rt->current_exception; rt->current_exception = JS_UNINITIALIZED; pc = b->byte_code_buf + pos; goto restart; } } } } ret_val = JS_EXCEPTION; /* the local variables are freed by the caller in the generator case. Hence the label 'done' should never be reached in a generator function. */ if (b->func_kind != JS_FUNC_NORMAL) { done_generator: sf->cur_pc = pc; sf->cur_sp = sp; } else { done: if (unlikely(b->var_ref_count != 0)) { /* variable references reference the stack: must close them */ close_var_refs(rt, b, sf); } /* free the local variables and stack */ for(pval = local_buf; pval < sp; pval++) { JS_FreeValue(ctx, *pval); } } rt->current_stack_frame = sf->prev_frame; return ret_val; } JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, int argc, JSValueConst *argv) { return JS_CallInternal(ctx, func_obj, this_obj, JS_UNDEFINED, argc, (JSValue *)argv, JS_CALL_FLAG_COPY_ARGV); } static JSValue JS_CallFree(JSContext *ctx, JSValue func_obj, JSValueConst this_obj, int argc, JSValueConst *argv) { JSValue res = JS_CallInternal(ctx, func_obj, this_obj, JS_UNDEFINED, argc, (JSValue *)argv, JS_CALL_FLAG_COPY_ARGV); JS_FreeValue(ctx, func_obj); return res; } /* warning: the refcount of the context is not incremented. Return NULL in case of exception (case of revoked proxy only) */ static JSContext *JS_GetFunctionRealm(JSContext *ctx, JSValueConst func_obj) { JSObject *p; JSContext *realm; if (JS_VALUE_GET_TAG(func_obj) != JS_TAG_OBJECT) return ctx; p = JS_VALUE_GET_OBJ(func_obj); switch(p->class_id) { case JS_CLASS_C_FUNCTION: realm = p->u.cfunc.realm; break; case JS_CLASS_BYTECODE_FUNCTION: case JS_CLASS_GENERATOR_FUNCTION: case JS_CLASS_ASYNC_FUNCTION: case JS_CLASS_ASYNC_GENERATOR_FUNCTION: { JSFunctionBytecode *b; b = p->u.func.function_bytecode; realm = b->realm; } break; case JS_CLASS_PROXY: { JSProxyData *s = p->u.opaque; if (!s) return ctx; if (s->is_revoked) { JS_ThrowTypeErrorRevokedProxy(ctx); return NULL; } else { realm = JS_GetFunctionRealm(ctx, s->target); } } break; case JS_CLASS_BOUND_FUNCTION: { JSBoundFunction *bf = p->u.bound_function; realm = JS_GetFunctionRealm(ctx, bf->func_obj); } break; default: realm = ctx; break; } return realm; } static JSValue js_create_from_ctor(JSContext *ctx, JSValueConst ctor, int class_id) { JSValue proto, obj; JSContext *realm; if (JS_IsUndefined(ctor)) { proto = JS_DupValue(ctx, ctx->class_proto[class_id]); } else { proto = JS_GetProperty(ctx, ctor, JS_ATOM_prototype); if (JS_IsException(proto)) return proto; if (!JS_IsObject(proto)) { JS_FreeValue(ctx, proto); realm = JS_GetFunctionRealm(ctx, ctor); if (!realm) return JS_EXCEPTION; proto = JS_DupValue(ctx, realm->class_proto[class_id]); } } obj = JS_NewObjectProtoClass(ctx, proto, class_id); JS_FreeValue(ctx, proto); return obj; } JSValue JS_NewObjectFromCtor(JSContext *ctx, JSValueConst ctor, JSClassID class_id) { return js_create_from_ctor(ctx, ctor, class_id); } /* argv[] is modified if (flags & JS_CALL_FLAG_COPY_ARGV) = 0. */ static JSValue JS_CallConstructorInternal(JSContext *ctx, JSValueConst func_obj, JSValueConst new_target, int argc, JSValue *argv, int flags) { JSObject *p; JSFunctionBytecode *b; if (js_poll_interrupts(ctx)) return JS_EXCEPTION; flags |= JS_CALL_FLAG_CONSTRUCTOR; if (unlikely(JS_VALUE_GET_TAG(func_obj) != JS_TAG_OBJECT)) goto not_a_function; p = JS_VALUE_GET_OBJ(func_obj); if (unlikely(!p->is_constructor)) return JS_ThrowTypeErrorNotAConstructor(ctx, func_obj); if (unlikely(p->class_id != JS_CLASS_BYTECODE_FUNCTION)) { JSClassCall *call_func; call_func = ctx->rt->class_array[p->class_id].call; if (!call_func) { not_a_function: return JS_ThrowTypeError(ctx, "not a function"); } return call_func(ctx, func_obj, new_target, argc, (JSValueConst *)argv, flags); } b = p->u.func.function_bytecode; if (b->is_derived_class_constructor) { return JS_CallInternal(ctx, func_obj, JS_UNDEFINED, new_target, argc, argv, flags); } else { JSValue obj, ret; /* legacy constructor behavior */ obj = js_create_from_ctor(ctx, new_target, JS_CLASS_OBJECT); if (JS_IsException(obj)) return JS_EXCEPTION; ret = JS_CallInternal(ctx, func_obj, obj, new_target, argc, argv, flags); if (JS_VALUE_GET_TAG(ret) == JS_TAG_OBJECT || JS_IsException(ret)) { JS_FreeValue(ctx, obj); return ret; } else { JS_FreeValue(ctx, ret); return obj; } } } JSValue JS_CallConstructor2(JSContext *ctx, JSValueConst func_obj, JSValueConst new_target, int argc, JSValueConst *argv) { return JS_CallConstructorInternal(ctx, func_obj, new_target, argc, (JSValue *)argv, JS_CALL_FLAG_COPY_ARGV); } JSValue JS_CallConstructor(JSContext *ctx, JSValueConst func_obj, int argc, JSValueConst *argv) { return JS_CallConstructorInternal(ctx, func_obj, func_obj, argc, (JSValue *)argv, JS_CALL_FLAG_COPY_ARGV); } JSValue JS_Invoke(JSContext *ctx, JSValueConst this_val, JSAtom atom, int argc, JSValueConst *argv) { JSValue func_obj; func_obj = JS_GetProperty(ctx, this_val, atom); if (JS_IsException(func_obj)) return func_obj; return JS_CallFree(ctx, func_obj, this_val, argc, argv); } static JSValue JS_InvokeFree(JSContext *ctx, JSValue this_val, JSAtom atom, int argc, JSValueConst *argv) { JSValue res = JS_Invoke(ctx, this_val, atom, argc, argv); JS_FreeValue(ctx, this_val); return res; } /* JSAsyncFunctionState (used by generator and async functions) */ static JSAsyncFunctionState *async_func_init(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, int argc, JSValueConst *argv) { JSAsyncFunctionState *s; JSObject *p; JSFunctionBytecode *b; JSStackFrame *sf; int i, arg_buf_len, n; p = JS_VALUE_GET_OBJ(func_obj); b = p->u.func.function_bytecode; arg_buf_len = max_int(b->arg_count, argc); s = js_malloc(ctx, sizeof(*s) + sizeof(JSValue) * (arg_buf_len + b->var_count + b->stack_size) + sizeof(JSVarRef *) * b->var_ref_count); if (!s) return NULL; memset(s, 0, sizeof(*s)); s->header.ref_count = 1; add_gc_object(ctx->rt, &s->header, JS_GC_OBJ_TYPE_ASYNC_FUNCTION); sf = &s->frame; sf->js_mode = b->js_mode | JS_MODE_ASYNC; sf->cur_pc = b->byte_code_buf; sf->arg_buf = (JSValue *)(s + 1); sf->cur_func = JS_DupValue(ctx, func_obj); s->this_val = JS_DupValue(ctx, this_obj); s->argc = argc; sf->arg_count = arg_buf_len; sf->var_buf = sf->arg_buf + arg_buf_len; sf->cur_sp = sf->var_buf + b->var_count; sf->var_refs = (JSVarRef **)(sf->cur_sp + b->stack_size); for(i = 0; i < b->var_ref_count; i++) sf->var_refs[i] = NULL; for(i = 0; i < argc; i++) sf->arg_buf[i] = JS_DupValue(ctx, argv[i]); n = arg_buf_len + b->var_count; for(i = argc; i < n; i++) sf->arg_buf[i] = JS_UNDEFINED; s->resolving_funcs[0] = JS_UNDEFINED; s->resolving_funcs[1] = JS_UNDEFINED; s->is_completed = FALSE; return s; } static void async_func_free_frame(JSRuntime *rt, JSAsyncFunctionState *s) { JSStackFrame *sf = &s->frame; JSValue *sp; /* cannot free the function if it is running */ assert(sf->cur_sp != NULL); for(sp = sf->arg_buf; sp < sf->cur_sp; sp++) { JS_FreeValueRT(rt, *sp); } JS_FreeValueRT(rt, sf->cur_func); JS_FreeValueRT(rt, s->this_val); } static JSValue async_func_resume(JSContext *ctx, JSAsyncFunctionState *s) { JSRuntime *rt = ctx->rt; JSStackFrame *sf = &s->frame; JSValue func_obj, ret; assert(!s->is_completed); if (js_check_stack_overflow(ctx->rt, 0)) { ret = JS_ThrowStackOverflow(ctx); } else { /* the tag does not matter provided it is not an object */ func_obj = JS_MKPTR(JS_TAG_INT, s); ret = JS_CallInternal(ctx, func_obj, s->this_val, JS_UNDEFINED, s->argc, sf->arg_buf, JS_CALL_FLAG_GENERATOR); } if (JS_IsException(ret) || JS_IsUndefined(ret)) { JSObject *p; JSFunctionBytecode *b; p = JS_VALUE_GET_OBJ(sf->cur_func); b = p->u.func.function_bytecode; if (JS_IsUndefined(ret)) { ret = sf->cur_sp[-1]; sf->cur_sp[-1] = JS_UNDEFINED; } /* end of execution */ s->is_completed = TRUE; /* close the closure variables. */ close_var_refs(rt, b, sf); async_func_free_frame(rt, s); } return ret; } static void __async_func_free(JSRuntime *rt, JSAsyncFunctionState *s) { /* cannot close the closure variables here because it would potentially modify the object graph */ if (!s->is_completed) { async_func_free_frame(rt, s); } JS_FreeValueRT(rt, s->resolving_funcs[0]); JS_FreeValueRT(rt, s->resolving_funcs[1]); remove_gc_object(&s->header); if (rt->gc_phase == JS_GC_PHASE_REMOVE_CYCLES && s->header.ref_count != 0) { list_add_tail(&s->header.link, &rt->gc_zero_ref_count_list); } else { js_free_rt(rt, s); } } static void async_func_free(JSRuntime *rt, JSAsyncFunctionState *s) { if (--s->header.ref_count == 0) { if (rt->gc_phase != JS_GC_PHASE_REMOVE_CYCLES) { list_del(&s->header.link); list_add(&s->header.link, &rt->gc_zero_ref_count_list); if (rt->gc_phase == JS_GC_PHASE_NONE) { free_zero_refcount(rt); } } } } /* Generators */ typedef enum JSGeneratorStateEnum { JS_GENERATOR_STATE_SUSPENDED_START, JS_GENERATOR_STATE_SUSPENDED_YIELD, JS_GENERATOR_STATE_SUSPENDED_YIELD_STAR, JS_GENERATOR_STATE_EXECUTING, JS_GENERATOR_STATE_COMPLETED, } JSGeneratorStateEnum; typedef struct JSGeneratorData { JSGeneratorStateEnum state; JSAsyncFunctionState *func_state; } JSGeneratorData; static void free_generator_stack_rt(JSRuntime *rt, JSGeneratorData *s) { if (s->state == JS_GENERATOR_STATE_COMPLETED) return; if (s->func_state) { async_func_free(rt, s->func_state); s->func_state = NULL; } s->state = JS_GENERATOR_STATE_COMPLETED; } static void js_generator_finalizer(JSRuntime *rt, JSValue obj) { JSGeneratorData *s = JS_GetOpaque(obj, JS_CLASS_GENERATOR); if (s) { free_generator_stack_rt(rt, s); js_free_rt(rt, s); } } static void free_generator_stack(JSContext *ctx, JSGeneratorData *s) { free_generator_stack_rt(ctx->rt, s); } static void js_generator_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); JSGeneratorData *s = p->u.generator_data; if (!s || !s->func_state) return; mark_func(rt, &s->func_state->header); } /* XXX: use enum */ #define GEN_MAGIC_NEXT 0 #define GEN_MAGIC_RETURN 1 #define GEN_MAGIC_THROW 2 static JSValue js_generator_next(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, BOOL *pdone, int magic) { JSGeneratorData *s = JS_GetOpaque(this_val, JS_CLASS_GENERATOR); JSStackFrame *sf; JSValue ret, func_ret; *pdone = TRUE; if (!s) return JS_ThrowTypeError(ctx, "not a generator"); switch(s->state) { default: case JS_GENERATOR_STATE_SUSPENDED_START: sf = &s->func_state->frame; if (magic == GEN_MAGIC_NEXT) { goto exec_no_arg; } else { free_generator_stack(ctx, s); goto done; } break; case JS_GENERATOR_STATE_SUSPENDED_YIELD_STAR: case JS_GENERATOR_STATE_SUSPENDED_YIELD: sf = &s->func_state->frame; /* cur_sp[-1] was set to JS_UNDEFINED in the previous call */ ret = JS_DupValue(ctx, argv[0]); if (magic == GEN_MAGIC_THROW && s->state == JS_GENERATOR_STATE_SUSPENDED_YIELD) { JS_Throw(ctx, ret); s->func_state->throw_flag = TRUE; } else { sf->cur_sp[-1] = ret; sf->cur_sp[0] = JS_NewInt32(ctx, magic); sf->cur_sp++; exec_no_arg: s->func_state->throw_flag = FALSE; } s->state = JS_GENERATOR_STATE_EXECUTING; func_ret = async_func_resume(ctx, s->func_state); s->state = JS_GENERATOR_STATE_SUSPENDED_YIELD; if (s->func_state->is_completed) { /* finalize the execution in case of exception or normal return */ free_generator_stack(ctx, s); return func_ret; } else { assert(JS_VALUE_GET_TAG(func_ret) == JS_TAG_INT); /* get the returned yield value at the top of the stack */ ret = sf->cur_sp[-1]; sf->cur_sp[-1] = JS_UNDEFINED; if (JS_VALUE_GET_INT(func_ret) == FUNC_RET_YIELD_STAR) { s->state = JS_GENERATOR_STATE_SUSPENDED_YIELD_STAR; /* return (value, done) object */ *pdone = 2; } else { *pdone = FALSE; } } break; case JS_GENERATOR_STATE_COMPLETED: done: /* execution is finished */ switch(magic) { default: case GEN_MAGIC_NEXT: ret = JS_UNDEFINED; break; case GEN_MAGIC_RETURN: ret = JS_DupValue(ctx, argv[0]); break; case GEN_MAGIC_THROW: ret = JS_Throw(ctx, JS_DupValue(ctx, argv[0])); break; } break; case JS_GENERATOR_STATE_EXECUTING: ret = JS_ThrowTypeError(ctx, "cannot invoke a running generator"); break; } return ret; } static JSValue js_generator_function_call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, int argc, JSValueConst *argv, int flags) { JSValue obj, func_ret; JSGeneratorData *s; s = js_mallocz(ctx, sizeof(*s)); if (!s) return JS_EXCEPTION; s->state = JS_GENERATOR_STATE_SUSPENDED_START; s->func_state = async_func_init(ctx, func_obj, this_obj, argc, argv); if (!s->func_state) { s->state = JS_GENERATOR_STATE_COMPLETED; goto fail; } /* execute the function up to 'OP_initial_yield' */ func_ret = async_func_resume(ctx, s->func_state); if (JS_IsException(func_ret)) goto fail; JS_FreeValue(ctx, func_ret); obj = js_create_from_ctor(ctx, func_obj, JS_CLASS_GENERATOR); if (JS_IsException(obj)) goto fail; JS_SetOpaque(obj, s); return obj; fail: free_generator_stack_rt(ctx->rt, s); js_free(ctx, s); return JS_EXCEPTION; } /* AsyncFunction */ static void js_async_function_resolve_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); JSAsyncFunctionState *s = p->u.async_function_data; if (s) { async_func_free(rt, s); } } static void js_async_function_resolve_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); JSAsyncFunctionState *s = p->u.async_function_data; if (s) { mark_func(rt, &s->header); } } static int js_async_function_resolve_create(JSContext *ctx, JSAsyncFunctionState *s, JSValue *resolving_funcs) { int i; JSObject *p; for(i = 0; i < 2; i++) { resolving_funcs[i] = JS_NewObjectProtoClass(ctx, ctx->function_proto, JS_CLASS_ASYNC_FUNCTION_RESOLVE + i); if (JS_IsException(resolving_funcs[i])) { if (i == 1) JS_FreeValue(ctx, resolving_funcs[0]); return -1; } p = JS_VALUE_GET_OBJ(resolving_funcs[i]); s->header.ref_count++; p->u.async_function_data = s; } return 0; } static void js_async_function_resume(JSContext *ctx, JSAsyncFunctionState *s) { JSValue func_ret, ret2; func_ret = async_func_resume(ctx, s); if (s->is_completed) { if (JS_IsException(func_ret)) { JSValue error; fail: error = JS_GetException(ctx); ret2 = JS_Call(ctx, s->resolving_funcs[1], JS_UNDEFINED, 1, (JSValueConst *)&error); JS_FreeValue(ctx, error); JS_FreeValue(ctx, ret2); /* XXX: what to do if exception ? */ } else { /* normal return */ ret2 = JS_Call(ctx, s->resolving_funcs[0], JS_UNDEFINED, 1, (JSValueConst *)&func_ret); JS_FreeValue(ctx, func_ret); JS_FreeValue(ctx, ret2); /* XXX: what to do if exception ? */ } } else { JSValue value, promise, resolving_funcs[2], resolving_funcs1[2]; int i, res; value = s->frame.cur_sp[-1]; s->frame.cur_sp[-1] = JS_UNDEFINED; /* await */ JS_FreeValue(ctx, func_ret); /* not used */ promise = js_promise_resolve(ctx, ctx->promise_ctor, 1, (JSValueConst *)&value, 0); JS_FreeValue(ctx, value); if (JS_IsException(promise)) goto fail; if (js_async_function_resolve_create(ctx, s, resolving_funcs)) { JS_FreeValue(ctx, promise); goto fail; } /* Note: no need to create 'thrownawayCapability' as in the spec */ for(i = 0; i < 2; i++) resolving_funcs1[i] = JS_UNDEFINED; res = perform_promise_then(ctx, promise, (JSValueConst *)resolving_funcs, (JSValueConst *)resolving_funcs1); JS_FreeValue(ctx, promise); for(i = 0; i < 2; i++) JS_FreeValue(ctx, resolving_funcs[i]); if (res) goto fail; } } static JSValue js_async_function_resolve_call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, int argc, JSValueConst *argv, int flags) { JSObject *p = JS_VALUE_GET_OBJ(func_obj); JSAsyncFunctionState *s = p->u.async_function_data; BOOL is_reject = p->class_id - JS_CLASS_ASYNC_FUNCTION_RESOLVE; JSValueConst arg; if (argc > 0) arg = argv[0]; else arg = JS_UNDEFINED; s->throw_flag = is_reject; if (is_reject) { JS_Throw(ctx, JS_DupValue(ctx, arg)); } else { /* return value of await */ s->frame.cur_sp[-1] = JS_DupValue(ctx, arg); } js_async_function_resume(ctx, s); return JS_UNDEFINED; } static JSValue js_async_function_call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, int argc, JSValueConst *argv, int flags) { JSValue promise; JSAsyncFunctionState *s; s = async_func_init(ctx, func_obj, this_obj, argc, argv); if (!s) return JS_EXCEPTION; promise = JS_NewPromiseCapability(ctx, s->resolving_funcs); if (JS_IsException(promise)) { async_func_free(ctx->rt, s); return JS_EXCEPTION; } js_async_function_resume(ctx, s); async_func_free(ctx->rt, s); return promise; } /* AsyncGenerator */ typedef enum JSAsyncGeneratorStateEnum { JS_ASYNC_GENERATOR_STATE_SUSPENDED_START, JS_ASYNC_GENERATOR_STATE_SUSPENDED_YIELD, JS_ASYNC_GENERATOR_STATE_SUSPENDED_YIELD_STAR, JS_ASYNC_GENERATOR_STATE_EXECUTING, JS_ASYNC_GENERATOR_STATE_AWAITING_RETURN, JS_ASYNC_GENERATOR_STATE_COMPLETED, } JSAsyncGeneratorStateEnum; typedef struct JSAsyncGeneratorRequest { struct list_head link; /* completion */ int completion_type; /* GEN_MAGIC_x */ JSValue result; /* promise capability */ JSValue promise; JSValue resolving_funcs[2]; } JSAsyncGeneratorRequest; typedef struct JSAsyncGeneratorData { JSObject *generator; /* back pointer to the object (const) */ JSAsyncGeneratorStateEnum state; /* func_state is NULL is state AWAITING_RETURN and COMPLETED */ JSAsyncFunctionState *func_state; struct list_head queue; /* list of JSAsyncGeneratorRequest.link */ } JSAsyncGeneratorData; static void js_async_generator_free(JSRuntime *rt, JSAsyncGeneratorData *s) { struct list_head *el, *el1; JSAsyncGeneratorRequest *req; list_for_each_safe(el, el1, &s->queue) { req = list_entry(el, JSAsyncGeneratorRequest, link); JS_FreeValueRT(rt, req->result); JS_FreeValueRT(rt, req->promise); JS_FreeValueRT(rt, req->resolving_funcs[0]); JS_FreeValueRT(rt, req->resolving_funcs[1]); js_free_rt(rt, req); } if (s->func_state) async_func_free(rt, s->func_state); js_free_rt(rt, s); } static void js_async_generator_finalizer(JSRuntime *rt, JSValue obj) { JSAsyncGeneratorData *s = JS_GetOpaque(obj, JS_CLASS_ASYNC_GENERATOR); if (s) { js_async_generator_free(rt, s); } } static void js_async_generator_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSAsyncGeneratorData *s = JS_GetOpaque(val, JS_CLASS_ASYNC_GENERATOR); struct list_head *el; JSAsyncGeneratorRequest *req; if (s) { list_for_each(el, &s->queue) { req = list_entry(el, JSAsyncGeneratorRequest, link); JS_MarkValue(rt, req->result, mark_func); JS_MarkValue(rt, req->promise, mark_func); JS_MarkValue(rt, req->resolving_funcs[0], mark_func); JS_MarkValue(rt, req->resolving_funcs[1], mark_func); } if (s->func_state) { mark_func(rt, &s->func_state->header); } } } static JSValue js_async_generator_resolve_function(JSContext *ctx, JSValueConst this_obj, int argc, JSValueConst *argv, int magic, JSValue *func_data); static int js_async_generator_resolve_function_create(JSContext *ctx, JSValueConst generator, JSValue *resolving_funcs, BOOL is_resume_next) { int i; JSValue func; for(i = 0; i < 2; i++) { func = JS_NewCFunctionData(ctx, js_async_generator_resolve_function, 1, i + is_resume_next * 2, 1, &generator); if (JS_IsException(func)) { if (i == 1) JS_FreeValue(ctx, resolving_funcs[0]); return -1; } resolving_funcs[i] = func; } return 0; } static int js_async_generator_await(JSContext *ctx, JSAsyncGeneratorData *s, JSValueConst value) { JSValue promise, resolving_funcs[2], resolving_funcs1[2]; int i, res; promise = js_promise_resolve(ctx, ctx->promise_ctor, 1, &value, 0); if (JS_IsException(promise)) goto fail; if (js_async_generator_resolve_function_create(ctx, JS_MKPTR(JS_TAG_OBJECT, s->generator), resolving_funcs, FALSE)) { JS_FreeValue(ctx, promise); goto fail; } /* Note: no need to create 'thrownawayCapability' as in the spec */ for(i = 0; i < 2; i++) resolving_funcs1[i] = JS_UNDEFINED; res = perform_promise_then(ctx, promise, (JSValueConst *)resolving_funcs, (JSValueConst *)resolving_funcs1); JS_FreeValue(ctx, promise); for(i = 0; i < 2; i++) JS_FreeValue(ctx, resolving_funcs[i]); if (res) goto fail; return 0; fail: return -1; } static void js_async_generator_resolve_or_reject(JSContext *ctx, JSAsyncGeneratorData *s, JSValueConst result, int is_reject) { JSAsyncGeneratorRequest *next; JSValue ret; next = list_entry(s->queue.next, JSAsyncGeneratorRequest, link); list_del(&next->link); ret = JS_Call(ctx, next->resolving_funcs[is_reject], JS_UNDEFINED, 1, &result); JS_FreeValue(ctx, ret); JS_FreeValue(ctx, next->result); JS_FreeValue(ctx, next->promise); JS_FreeValue(ctx, next->resolving_funcs[0]); JS_FreeValue(ctx, next->resolving_funcs[1]); js_free(ctx, next); } static void js_async_generator_resolve(JSContext *ctx, JSAsyncGeneratorData *s, JSValueConst value, BOOL done) { JSValue result; result = js_create_iterator_result(ctx, JS_DupValue(ctx, value), done); /* XXX: better exception handling ? */ js_async_generator_resolve_or_reject(ctx, s, result, 0); JS_FreeValue(ctx, result); } static void js_async_generator_reject(JSContext *ctx, JSAsyncGeneratorData *s, JSValueConst exception) { js_async_generator_resolve_or_reject(ctx, s, exception, 1); } static void js_async_generator_complete(JSContext *ctx, JSAsyncGeneratorData *s) { if (s->state != JS_ASYNC_GENERATOR_STATE_COMPLETED) { s->state = JS_ASYNC_GENERATOR_STATE_COMPLETED; async_func_free(ctx->rt, s->func_state); s->func_state = NULL; } } static int js_async_generator_completed_return(JSContext *ctx, JSAsyncGeneratorData *s, JSValueConst value) { JSValue promise, resolving_funcs[2], resolving_funcs1[2]; int res; // Can fail looking up JS_ATOM_constructor when is_reject==0. promise = js_promise_resolve(ctx, ctx->promise_ctor, 1, &value, /*is_reject*/0); // A poisoned .constructor property is observable and the resulting // exception should be delivered to the catch handler. if (JS_IsException(promise)) { JSValue err = JS_GetException(ctx); promise = js_promise_resolve(ctx, ctx->promise_ctor, 1, (JSValueConst *)&err, /*is_reject*/1); JS_FreeValue(ctx, err); if (JS_IsException(promise)) return -1; } if (js_async_generator_resolve_function_create(ctx, JS_MKPTR(JS_TAG_OBJECT, s->generator), resolving_funcs1, TRUE)) { JS_FreeValue(ctx, promise); return -1; } resolving_funcs[0] = JS_UNDEFINED; resolving_funcs[1] = JS_UNDEFINED; res = perform_promise_then(ctx, promise, (JSValueConst *)resolving_funcs1, (JSValueConst *)resolving_funcs); JS_FreeValue(ctx, resolving_funcs1[0]); JS_FreeValue(ctx, resolving_funcs1[1]); JS_FreeValue(ctx, promise); return res; } static void js_async_generator_resume_next(JSContext *ctx, JSAsyncGeneratorData *s) { JSAsyncGeneratorRequest *next; JSValue func_ret, value; for(;;) { if (list_empty(&s->queue)) break; next = list_entry(s->queue.next, JSAsyncGeneratorRequest, link); switch(s->state) { case JS_ASYNC_GENERATOR_STATE_EXECUTING: /* only happens when restarting execution after await() */ goto resume_exec; case JS_ASYNC_GENERATOR_STATE_AWAITING_RETURN: goto done; case JS_ASYNC_GENERATOR_STATE_SUSPENDED_START: if (next->completion_type == GEN_MAGIC_NEXT) { goto exec_no_arg; } else { js_async_generator_complete(ctx, s); } break; case JS_ASYNC_GENERATOR_STATE_COMPLETED: if (next->completion_type == GEN_MAGIC_NEXT) { js_async_generator_resolve(ctx, s, JS_UNDEFINED, TRUE); } else if (next->completion_type == GEN_MAGIC_RETURN) { s->state = JS_ASYNC_GENERATOR_STATE_AWAITING_RETURN; js_async_generator_completed_return(ctx, s, next->result); } else { js_async_generator_reject(ctx, s, next->result); } goto done; case JS_ASYNC_GENERATOR_STATE_SUSPENDED_YIELD: case JS_ASYNC_GENERATOR_STATE_SUSPENDED_YIELD_STAR: value = JS_DupValue(ctx, next->result); if (next->completion_type == GEN_MAGIC_THROW && s->state == JS_ASYNC_GENERATOR_STATE_SUSPENDED_YIELD) { JS_Throw(ctx, value); s->func_state->throw_flag = TRUE; } else { /* 'yield' returns a value. 'yield *' also returns a value in case the 'throw' method is called */ s->func_state->frame.cur_sp[-1] = value; s->func_state->frame.cur_sp[0] = JS_NewInt32(ctx, next->completion_type); s->func_state->frame.cur_sp++; exec_no_arg: s->func_state->throw_flag = FALSE; } s->state = JS_ASYNC_GENERATOR_STATE_EXECUTING; resume_exec: func_ret = async_func_resume(ctx, s->func_state); if (s->func_state->is_completed) { if (JS_IsException(func_ret)) { value = JS_GetException(ctx); js_async_generator_complete(ctx, s); js_async_generator_reject(ctx, s, value); JS_FreeValue(ctx, value); } else { /* end of function */ js_async_generator_complete(ctx, s); js_async_generator_resolve(ctx, s, func_ret, TRUE); JS_FreeValue(ctx, func_ret); } } else { int func_ret_code, ret; assert(JS_VALUE_GET_TAG(func_ret) == JS_TAG_INT); func_ret_code = JS_VALUE_GET_INT(func_ret); value = s->func_state->frame.cur_sp[-1]; s->func_state->frame.cur_sp[-1] = JS_UNDEFINED; switch(func_ret_code) { case FUNC_RET_YIELD: case FUNC_RET_YIELD_STAR: if (func_ret_code == FUNC_RET_YIELD_STAR) s->state = JS_ASYNC_GENERATOR_STATE_SUSPENDED_YIELD_STAR; else s->state = JS_ASYNC_GENERATOR_STATE_SUSPENDED_YIELD; js_async_generator_resolve(ctx, s, value, FALSE); JS_FreeValue(ctx, value); break; case FUNC_RET_AWAIT: ret = js_async_generator_await(ctx, s, value); JS_FreeValue(ctx, value); if (ret < 0) { /* exception: throw it */ s->func_state->throw_flag = TRUE; goto resume_exec; } goto done; default: abort(); } } break; default: abort(); } } done: ; } static JSValue js_async_generator_resolve_function(JSContext *ctx, JSValueConst this_obj, int argc, JSValueConst *argv, int magic, JSValue *func_data) { BOOL is_reject = magic & 1; JSAsyncGeneratorData *s = JS_GetOpaque(func_data[0], JS_CLASS_ASYNC_GENERATOR); JSValueConst arg = argv[0]; /* XXX: what if s == NULL */ if (magic >= 2) { /* resume next case in AWAITING_RETURN state */ assert(s->state == JS_ASYNC_GENERATOR_STATE_AWAITING_RETURN || s->state == JS_ASYNC_GENERATOR_STATE_COMPLETED); s->state = JS_ASYNC_GENERATOR_STATE_COMPLETED; if (is_reject) { js_async_generator_reject(ctx, s, arg); } else { js_async_generator_resolve(ctx, s, arg, TRUE); } } else if (s->state == JS_ASYNC_GENERATOR_STATE_EXECUTING) { /* restart function execution after await() */ s->func_state->throw_flag = is_reject; if (is_reject) { JS_Throw(ctx, JS_DupValue(ctx, arg)); } else { /* return value of await */ s->func_state->frame.cur_sp[-1] = JS_DupValue(ctx, arg); } js_async_generator_resume_next(ctx, s); } return JS_UNDEFINED; } /* magic = GEN_MAGIC_x */ static JSValue js_async_generator_next(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSAsyncGeneratorData *s = JS_GetOpaque(this_val, JS_CLASS_ASYNC_GENERATOR); JSValue promise, resolving_funcs[2]; JSAsyncGeneratorRequest *req; promise = JS_NewPromiseCapability(ctx, resolving_funcs); if (JS_IsException(promise)) return JS_EXCEPTION; if (!s) { JSValue err, res2; JS_ThrowTypeError(ctx, "not an AsyncGenerator object"); err = JS_GetException(ctx); res2 = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, 1, (JSValueConst *)&err); JS_FreeValue(ctx, err); JS_FreeValue(ctx, res2); JS_FreeValue(ctx, resolving_funcs[0]); JS_FreeValue(ctx, resolving_funcs[1]); return promise; } req = js_mallocz(ctx, sizeof(*req)); if (!req) goto fail; req->completion_type = magic; req->result = JS_DupValue(ctx, argv[0]); req->promise = JS_DupValue(ctx, promise); req->resolving_funcs[0] = resolving_funcs[0]; req->resolving_funcs[1] = resolving_funcs[1]; list_add_tail(&req->link, &s->queue); if (s->state != JS_ASYNC_GENERATOR_STATE_EXECUTING) { js_async_generator_resume_next(ctx, s); } return promise; fail: JS_FreeValue(ctx, resolving_funcs[0]); JS_FreeValue(ctx, resolving_funcs[1]); JS_FreeValue(ctx, promise); return JS_EXCEPTION; } static JSValue js_async_generator_function_call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, int argc, JSValueConst *argv, int flags) { JSValue obj, func_ret; JSAsyncGeneratorData *s; s = js_mallocz(ctx, sizeof(*s)); if (!s) return JS_EXCEPTION; s->state = JS_ASYNC_GENERATOR_STATE_SUSPENDED_START; init_list_head(&s->queue); s->func_state = async_func_init(ctx, func_obj, this_obj, argc, argv); if (!s->func_state) goto fail; /* execute the function up to 'OP_initial_yield' (no yield nor await are possible) */ func_ret = async_func_resume(ctx, s->func_state); if (JS_IsException(func_ret)) goto fail; JS_FreeValue(ctx, func_ret); obj = js_create_from_ctor(ctx, func_obj, JS_CLASS_ASYNC_GENERATOR); if (JS_IsException(obj)) goto fail; s->generator = JS_VALUE_GET_OBJ(obj); JS_SetOpaque(obj, s); return obj; fail: js_async_generator_free(ctx->rt, s); return JS_EXCEPTION; } /* JS parser */ enum { TOK_NUMBER = -128, TOK_STRING, TOK_TEMPLATE, TOK_IDENT, TOK_REGEXP, /* warning: order matters (see js_parse_assign_expr) */ TOK_MUL_ASSIGN, TOK_DIV_ASSIGN, TOK_MOD_ASSIGN, TOK_PLUS_ASSIGN, TOK_MINUS_ASSIGN, TOK_SHL_ASSIGN, TOK_SAR_ASSIGN, TOK_SHR_ASSIGN, TOK_AND_ASSIGN, TOK_XOR_ASSIGN, TOK_OR_ASSIGN, TOK_POW_ASSIGN, TOK_LAND_ASSIGN, TOK_LOR_ASSIGN, TOK_DOUBLE_QUESTION_MARK_ASSIGN, TOK_DEC, TOK_INC, TOK_SHL, TOK_SAR, TOK_SHR, TOK_LT, TOK_LTE, TOK_GT, TOK_GTE, TOK_EQ, TOK_STRICT_EQ, TOK_NEQ, TOK_STRICT_NEQ, TOK_LAND, TOK_LOR, TOK_POW, TOK_ARROW, TOK_ELLIPSIS, TOK_DOUBLE_QUESTION_MARK, TOK_QUESTION_MARK_DOT, TOK_ERROR, TOK_PRIVATE_NAME, TOK_EOF, /* keywords: WARNING: same order as atoms */ TOK_NULL, /* must be first */ TOK_FALSE, TOK_TRUE, TOK_IF, TOK_ELSE, TOK_RETURN, TOK_VAR, TOK_THIS, TOK_DELETE, TOK_VOID, TOK_TYPEOF, TOK_NEW, TOK_IN, TOK_INSTANCEOF, TOK_DO, TOK_WHILE, TOK_FOR, TOK_BREAK, TOK_CONTINUE, TOK_SWITCH, TOK_CASE, TOK_DEFAULT, TOK_THROW, TOK_TRY, TOK_CATCH, TOK_FINALLY, TOK_FUNCTION, TOK_DEBUGGER, TOK_WITH, /* FutureReservedWord */ TOK_CLASS, TOK_CONST, TOK_ENUM, TOK_EXPORT, TOK_EXTENDS, TOK_IMPORT, TOK_SUPER, /* FutureReservedWords when parsing strict mode code */ TOK_IMPLEMENTS, TOK_INTERFACE, TOK_LET, TOK_PACKAGE, TOK_PRIVATE, TOK_PROTECTED, TOK_PUBLIC, TOK_STATIC, TOK_YIELD, TOK_AWAIT, /* must be last */ TOK_OF, /* only used for js_parse_skip_parens_token() */ }; #define TOK_FIRST_KEYWORD TOK_NULL #define TOK_LAST_KEYWORD TOK_AWAIT /* unicode code points */ #define CP_NBSP 0x00a0 #define CP_BOM 0xfeff #define CP_LS 0x2028 #define CP_PS 0x2029 typedef struct BlockEnv { struct BlockEnv *prev; JSAtom label_name; /* JS_ATOM_NULL if none */ int label_break; /* -1 if none */ int label_cont; /* -1 if none */ int drop_count; /* number of stack elements to drop */ int label_finally; /* -1 if none */ int scope_level; uint8_t has_iterator : 1; uint8_t is_regular_stmt : 1; /* i.e. not a loop statement */ } BlockEnv; typedef struct JSGlobalVar { int cpool_idx; /* if >= 0, index in the constant pool for hoisted function defintion*/ uint8_t force_init : 1; /* force initialization to undefined */ uint8_t is_lexical : 1; /* global let/const definition */ uint8_t is_const : 1; /* const definition */ int scope_level; /* scope of definition */ JSAtom var_name; /* variable name */ } JSGlobalVar; typedef struct RelocEntry { struct RelocEntry *next; uint32_t addr; /* address to patch */ int size; /* address size: 1, 2 or 4 bytes */ } RelocEntry; typedef struct JumpSlot { int op; int size; int pos; int label; } JumpSlot; typedef struct LabelSlot { int ref_count; int pos; /* phase 1 address, -1 means not resolved yet */ int pos2; /* phase 2 address, -1 means not resolved yet */ int addr; /* phase 3 address, -1 means not resolved yet */ RelocEntry *first_reloc; } LabelSlot; typedef struct LineNumberSlot { uint32_t pc; uint32_t source_pos; } LineNumberSlot; typedef struct { /* last source position */ const uint8_t *ptr; int line_num; int col_num; const uint8_t *buf_start; } GetLineColCache; typedef enum JSParseFunctionEnum { JS_PARSE_FUNC_STATEMENT, JS_PARSE_FUNC_VAR, JS_PARSE_FUNC_EXPR, JS_PARSE_FUNC_ARROW, JS_PARSE_FUNC_GETTER, JS_PARSE_FUNC_SETTER, JS_PARSE_FUNC_METHOD, JS_PARSE_FUNC_CLASS_STATIC_INIT, JS_PARSE_FUNC_CLASS_CONSTRUCTOR, JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR, } JSParseFunctionEnum; typedef enum JSParseExportEnum { JS_PARSE_EXPORT_NONE, JS_PARSE_EXPORT_NAMED, JS_PARSE_EXPORT_DEFAULT, } JSParseExportEnum; typedef struct JSVarScope { int parent; /* index into fd->scopes of the enclosing scope */ int first; /* index into fd->vars of the last variable in this scope */ } JSVarScope; typedef struct JSVarDef { JSAtom var_name; /* index into fd->scopes of this variable lexical scope */ int scope_level; /* - if scope_level = 0: scope in which the variable is defined - if scope_level != 0: index into fd->vars of the next variable in the same or enclosing lexical scope */ int scope_next; uint8_t is_const : 1; uint8_t is_lexical : 1; uint8_t is_captured : 1; /* XXX: could remove and use a var_ref_idx value */ uint8_t is_static_private : 1; /* only used during private class field parsing */ uint8_t var_kind : 4; /* see JSVarKindEnum */ /* if is_captured = TRUE, provides, the index of the corresponding JSVarRef on stack */ uint16_t var_ref_idx; /* function pool index for lexical variables with var_kind = JS_VAR_FUNCTION_DECL/JS_VAR_NEW_FUNCTION_DECL or scope level of the definition of the 'var' variables (they have scope_level = 0) */ int func_pool_idx; } JSVarDef; typedef struct JSFunctionDef { JSContext *ctx; struct JSFunctionDef *parent; int parent_cpool_idx; /* index in the constant pool of the parent or -1 if none */ int parent_scope_level; /* scope level in parent at point of definition */ struct list_head child_list; /* list of JSFunctionDef.link */ struct list_head link; BOOL is_eval; /* TRUE if eval code */ int eval_type; /* only valid if is_eval = TRUE */ BOOL is_global_var; /* TRUE if variables are not defined locally: eval global, eval module or non strict eval */ BOOL is_func_expr; /* TRUE if function expression */ BOOL has_home_object; /* TRUE if the home object is available */ BOOL has_prototype; /* true if a prototype field is necessary */ BOOL has_simple_parameter_list; BOOL has_parameter_expressions; /* if true, an argument scope is created */ BOOL has_use_strict; /* to reject directive in special cases */ BOOL has_eval_call; /* true if the function contains a call to eval() */ BOOL has_arguments_binding; /* true if the 'arguments' binding is available in the function */ BOOL has_this_binding; /* true if the 'this' and new.target binding are available in the function */ BOOL new_target_allowed; /* true if the 'new.target' does not throw a syntax error */ BOOL super_call_allowed; /* true if super() is allowed */ BOOL super_allowed; /* true if super. or super[] is allowed */ BOOL arguments_allowed; /* true if the 'arguments' identifier is allowed */ BOOL is_derived_class_constructor; BOOL in_function_body; JSFunctionKindEnum func_kind : 8; JSParseFunctionEnum func_type : 8; uint8_t js_mode; /* bitmap of JS_MODE_x */ JSAtom func_name; /* JS_ATOM_NULL if no name */ JSVarDef *vars; int var_size; /* allocated size for vars[] */ int var_count; JSVarDef *args; int arg_size; /* allocated size for args[] */ int arg_count; /* number of arguments */ int defined_arg_count; int var_ref_count; /* number of local/arg variable references */ int var_object_idx; /* -1 if none */ int arg_var_object_idx; /* -1 if none (var object for the argument scope) */ int arguments_var_idx; /* -1 if none */ int arguments_arg_idx; /* argument variable definition in argument scope, -1 if none */ int func_var_idx; /* variable containing the current function (-1 if none, only used if is_func_expr is true) */ int eval_ret_idx; /* variable containing the return value of the eval, -1 if none */ int this_var_idx; /* variable containg the 'this' value, -1 if none */ int new_target_var_idx; /* variable containg the 'new.target' value, -1 if none */ int this_active_func_var_idx; /* variable containg the 'this.active_func' value, -1 if none */ int home_object_var_idx; BOOL need_home_object; int scope_level; /* index into fd->scopes if the current lexical scope */ int scope_first; /* index into vd->vars of first lexically scoped variable */ int scope_size; /* allocated size of fd->scopes array */ int scope_count; /* number of entries used in the fd->scopes array */ JSVarScope *scopes; JSVarScope def_scope_array[4]; int body_scope; /* scope of the body of the function or eval */ int global_var_count; int global_var_size; JSGlobalVar *global_vars; DynBuf byte_code; int last_opcode_pos; /* -1 if no last opcode */ const uint8_t *last_opcode_source_ptr; BOOL use_short_opcodes; /* true if short opcodes are used in byte_code */ LabelSlot *label_slots; int label_size; /* allocated size for label_slots[] */ int label_count; BlockEnv *top_break; /* break/continue label stack */ /* constant pool (strings, functions, numbers) */ JSValue *cpool; int cpool_count; int cpool_size; /* list of variables in the closure */ int closure_var_count; int closure_var_size; JSClosureVar *closure_var; JumpSlot *jump_slots; int jump_size; int jump_count; LineNumberSlot *line_number_slots; int line_number_size; int line_number_count; int line_number_last; int line_number_last_pc; /* pc2line table */ BOOL strip_debug : 1; /* strip all debug info (implies strip_source = TRUE) */ BOOL strip_source : 1; /* strip only source code */ JSAtom filename; uint32_t source_pos; /* pointer in the eval() source */ GetLineColCache *get_line_col_cache; /* XXX: could remove to save memory */ DynBuf pc2line; char *source; /* raw source, utf-8 encoded */ int source_len; JSModuleDef *module; /* != NULL when parsing a module */ BOOL has_await; /* TRUE if await is used (used in module eval) */ } JSFunctionDef; typedef struct JSToken { int val; const uint8_t *ptr; /* position in the source */ union { struct { JSValue str; int sep; } str; struct { JSValue val; } num; struct { JSAtom atom; BOOL has_escape; BOOL is_reserved; } ident; struct { JSValue body; JSValue flags; } regexp; } u; } JSToken; typedef struct JSParseState { JSContext *ctx; const char *filename; JSToken token; BOOL got_lf; /* true if got line feed before the current token */ const uint8_t *last_ptr; const uint8_t *buf_start; const uint8_t *buf_ptr; const uint8_t *buf_end; /* current function code */ JSFunctionDef *cur_func; BOOL is_module; /* parsing a module */ BOOL allow_html_comments; BOOL ext_json; /* JSON parsing: true if accepting JSON superset */ GetLineColCache get_line_col_cache; } JSParseState; typedef struct JSOpCode { #ifdef DUMP_BYTECODE const char *name; #endif uint8_t size; /* in bytes */ /* the opcodes remove n_pop items from the top of the stack, then pushes n_push items */ uint8_t n_pop; uint8_t n_push; uint8_t fmt; } JSOpCode; static const JSOpCode opcode_info[OP_COUNT + (OP_TEMP_END - OP_TEMP_START)] = { #define FMT(f) #ifdef DUMP_BYTECODE #define DEF(id, size, n_pop, n_push, f) { #id, size, n_pop, n_push, OP_FMT_ ## f }, #else #define DEF(id, size, n_pop, n_push, f) { size, n_pop, n_push, OP_FMT_ ## f }, #endif #include "quickjs-opcode.h" #undef DEF #undef FMT }; #if SHORT_OPCODES /* After the final compilation pass, short opcodes are used. Their opcodes overlap with the temporary opcodes which cannot appear in the final bytecode. Their description is after the temporary opcodes in opcode_info[]. */ #define short_opcode_info(op) \ opcode_info[(op) >= OP_TEMP_START ? \ (op) + (OP_TEMP_END - OP_TEMP_START) : (op)] #else #define short_opcode_info(op) opcode_info[op] #endif static __exception int next_token(JSParseState *s); static void free_token(JSParseState *s, JSToken *token) { switch(token->val) { case TOK_NUMBER: JS_FreeValue(s->ctx, token->u.num.val); break; case TOK_STRING: case TOK_TEMPLATE: JS_FreeValue(s->ctx, token->u.str.str); break; case TOK_REGEXP: JS_FreeValue(s->ctx, token->u.regexp.body); JS_FreeValue(s->ctx, token->u.regexp.flags); break; case TOK_IDENT: case TOK_PRIVATE_NAME: JS_FreeAtom(s->ctx, token->u.ident.atom); break; default: if (token->val >= TOK_FIRST_KEYWORD && token->val <= TOK_LAST_KEYWORD) { JS_FreeAtom(s->ctx, token->u.ident.atom); } break; } } static void __attribute((unused)) dump_token(JSParseState *s, const JSToken *token) { switch(token->val) { case TOK_NUMBER: { double d; JS_ToFloat64(s->ctx, &d, token->u.num.val); /* no exception possible */ printf("number: %.14g\n", d); } break; case TOK_IDENT: dump_atom: { char buf[ATOM_GET_STR_BUF_SIZE]; printf("ident: '%s'\n", JS_AtomGetStr(s->ctx, buf, sizeof(buf), token->u.ident.atom)); } break; case TOK_STRING: { const char *str; /* XXX: quote the string */ str = JS_ToCString(s->ctx, token->u.str.str); printf("string: '%s'\n", str); JS_FreeCString(s->ctx, str); } break; case TOK_TEMPLATE: { const char *str; str = JS_ToCString(s->ctx, token->u.str.str); printf("template: `%s`\n", str); JS_FreeCString(s->ctx, str); } break; case TOK_REGEXP: { const char *str, *str2; str = JS_ToCString(s->ctx, token->u.regexp.body); str2 = JS_ToCString(s->ctx, token->u.regexp.flags); printf("regexp: '%s' '%s'\n", str, str2); JS_FreeCString(s->ctx, str); JS_FreeCString(s->ctx, str2); } break; case TOK_EOF: printf("eof\n"); break; default: if (s->token.val >= TOK_NULL && s->token.val <= TOK_LAST_KEYWORD) { goto dump_atom; } else if (s->token.val >= 256) { printf("token: %d\n", token->val); } else { printf("token: '%c'\n", token->val); } break; } } /* return the zero based line and column number in the source. */ /* Note: we no longer support '\r' as line terminator */ static int get_line_col(int *pcol_num, const uint8_t *buf, size_t len) { int line_num, col_num, c; size_t i; line_num = 0; col_num = 0; for(i = 0; i < len; i++) { c = buf[i]; if (c == '\n') { line_num++; col_num = 0; } else if (c < 0x80 || c >= 0xc0) { col_num++; } } *pcol_num = col_num; return line_num; } static int get_line_col_cached(GetLineColCache *s, int *pcol_num, const uint8_t *ptr) { int line_num, col_num; if (ptr >= s->ptr) { line_num = get_line_col(&col_num, s->ptr, ptr - s->ptr); if (line_num == 0) { s->col_num += col_num; } else { s->line_num += line_num; s->col_num = col_num; } } else { line_num = get_line_col(&col_num, ptr, s->ptr - ptr); if (line_num == 0) { s->col_num -= col_num; } else { const uint8_t *p; s->line_num -= line_num; /* find the absolute column position */ col_num = 0; for(p = ptr - 1; p >= s->buf_start; p--) { if (*p == '\n') { break; } else if (*p < 0x80 || *p >= 0xc0) { col_num++; } } s->col_num = col_num; } } s->ptr = ptr; *pcol_num = s->col_num; return s->line_num; } /* 'ptr' is the position of the error in the source */ static int js_parse_error_v(JSParseState *s, const uint8_t *ptr, const char *fmt, va_list ap) { JSContext *ctx = s->ctx; int line_num, col_num; line_num = get_line_col(&col_num, s->buf_start, ptr - s->buf_start); JS_ThrowError2(ctx, JS_SYNTAX_ERROR, fmt, ap, FALSE); build_backtrace(ctx, ctx->rt->current_exception, JS_UNDEFINED, s->filename, line_num + 1, col_num + 1, 0); return -1; } static __attribute__((format(printf, 3, 4))) int js_parse_error_pos(JSParseState *s, const uint8_t *ptr, const char *fmt, ...) { va_list ap; int ret; va_start(ap, fmt); ret = js_parse_error_v(s, ptr, fmt, ap); va_end(ap); return ret; } static __attribute__((format(printf, 2, 3))) int js_parse_error(JSParseState *s, const char *fmt, ...) { va_list ap; int ret; va_start(ap, fmt); ret = js_parse_error_v(s, s->token.ptr, fmt, ap); va_end(ap); return ret; } static int js_parse_expect(JSParseState *s, int tok) { if (s->token.val != tok) { /* XXX: dump token correctly in all cases */ return js_parse_error(s, "expecting '%c'", tok); } return next_token(s); } static int js_parse_expect_semi(JSParseState *s) { if (s->token.val != ';') { /* automatic insertion of ';' */ if (s->token.val == TOK_EOF || s->token.val == '}' || s->got_lf) { return 0; } return js_parse_error(s, "expecting '%c'", ';'); } return next_token(s); } static int js_parse_error_reserved_identifier(JSParseState *s) { char buf1[ATOM_GET_STR_BUF_SIZE]; return js_parse_error(s, "'%s' is a reserved identifier", JS_AtomGetStr(s->ctx, buf1, sizeof(buf1), s->token.u.ident.atom)); } static __exception int js_parse_template_part(JSParseState *s, const uint8_t *p) { uint32_t c; StringBuffer b_s, *b = &b_s; JSValue str; /* p points to the first byte of the template part */ if (string_buffer_init(s->ctx, b, 32)) goto fail; for(;;) { if (p >= s->buf_end) goto unexpected_eof; c = *p++; if (c == '`') { /* template end part */ break; } if (c == '$' && *p == '{') { /* template start or middle part */ p++; break; } if (c == '\\') { if (string_buffer_putc8(b, c)) goto fail; if (p >= s->buf_end) goto unexpected_eof; c = *p++; } /* newline sequences are normalized as single '\n' bytes */ if (c == '\r') { if (*p == '\n') p++; c = '\n'; } if (c >= 0x80) { const uint8_t *p_next; c = unicode_from_utf8(p - 1, UTF8_CHAR_LEN_MAX, &p_next); if (c > 0x10FFFF) { js_parse_error_pos(s, p - 1, "invalid UTF-8 sequence"); goto fail; } p = p_next; } if (string_buffer_putc(b, c)) goto fail; } str = string_buffer_end(b); if (JS_IsException(str)) return -1; s->token.val = TOK_TEMPLATE; s->token.u.str.sep = c; s->token.u.str.str = str; s->buf_ptr = p; return 0; unexpected_eof: js_parse_error(s, "unexpected end of string"); fail: string_buffer_free(b); return -1; } static __exception int js_parse_string(JSParseState *s, int sep, BOOL do_throw, const uint8_t *p, JSToken *token, const uint8_t **pp) { int ret; uint32_t c; StringBuffer b_s, *b = &b_s; const uint8_t *p_escape; JSValue str; /* string */ if (string_buffer_init(s->ctx, b, 32)) goto fail; for(;;) { if (p >= s->buf_end) goto invalid_char; c = *p; if (c < 0x20) { if (sep == '`') { if (c == '\r') { if (p[1] == '\n') p++; c = '\n'; } /* do not update s->line_num */ } else if (c == '\n' || c == '\r') goto invalid_char; } p++; if (c == sep) break; if (c == '$' && *p == '{' && sep == '`') { /* template start or middle part */ p++; break; } if (c == '\\') { p_escape = p - 1; c = *p; /* XXX: need a specific JSON case to avoid accepting invalid escapes */ switch(c) { case '\0': if (p >= s->buf_end) goto invalid_char; p++; break; case '\'': case '\"': case '\\': p++; break; case '\r': /* accept DOS and MAC newline sequences */ if (p[1] == '\n') { p++; } /* fall thru */ case '\n': /* ignore escaped newline sequence */ p++; continue; default: if (c >= '0' && c <= '9') { if (!(s->cur_func->js_mode & JS_MODE_STRICT) && sep != '`') goto parse_escape; if (c == '0' && !(p[1] >= '0' && p[1] <= '9')) { p++; c = '\0'; } else { if (c >= '8' || sep == '`') { /* Note: according to ES2021, \8 and \9 are not accepted in strict mode or in templates. */ goto invalid_escape; } else { if (do_throw) js_parse_error_pos(s, p_escape, "octal escape sequences are not allowed in strict mode"); } goto fail; } } else if (c >= 0x80) { const uint8_t *p_next; c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p_next); if (c > 0x10FFFF) { goto invalid_utf8; } p = p_next; /* LS or PS are skipped */ if (c == CP_LS || c == CP_PS) continue; } else { parse_escape: ret = lre_parse_escape(&p, TRUE); if (ret == -1) { invalid_escape: if (do_throw) js_parse_error_pos(s, p_escape, "malformed escape sequence in string literal"); goto fail; } else if (ret < 0) { /* ignore the '\' (could output a warning) */ p++; } else { c = ret; } } break; } } else if (c >= 0x80) { const uint8_t *p_next; c = unicode_from_utf8(p - 1, UTF8_CHAR_LEN_MAX, &p_next); if (c > 0x10FFFF) goto invalid_utf8; p = p_next; } if (string_buffer_putc(b, c)) goto fail; } str = string_buffer_end(b); if (JS_IsException(str)) return -1; token->val = TOK_STRING; token->u.str.sep = c; token->u.str.str = str; *pp = p; return 0; invalid_utf8: if (do_throw) js_parse_error(s, "invalid UTF-8 sequence"); goto fail; invalid_char: if (do_throw) js_parse_error(s, "unexpected end of string"); fail: string_buffer_free(b); return -1; } static inline BOOL token_is_pseudo_keyword(JSParseState *s, JSAtom atom) { return s->token.val == TOK_IDENT && s->token.u.ident.atom == atom && !s->token.u.ident.has_escape; } static __exception int js_parse_regexp(JSParseState *s) { const uint8_t *p; BOOL in_class; StringBuffer b_s, *b = &b_s; StringBuffer b2_s, *b2 = &b2_s; uint32_t c; JSValue body_str, flags_str; p = s->buf_ptr; p++; in_class = FALSE; if (string_buffer_init(s->ctx, b, 32)) return -1; if (string_buffer_init(s->ctx, b2, 1)) goto fail; for(;;) { if (p >= s->buf_end) { eof_error: js_parse_error(s, "unexpected end of regexp"); goto fail; } c = *p++; if (c == '\n' || c == '\r') { goto eol_error; } else if (c == '/') { if (!in_class) break; } else if (c == '[') { in_class = TRUE; } else if (c == ']') { /* XXX: incorrect as the first character in a class */ in_class = FALSE; } else if (c == '\\') { if (string_buffer_putc8(b, c)) goto fail; c = *p++; if (c == '\n' || c == '\r') goto eol_error; else if (c == '\0' && p >= s->buf_end) goto eof_error; else if (c >= 0x80) { const uint8_t *p_next; c = unicode_from_utf8(p - 1, UTF8_CHAR_LEN_MAX, &p_next); if (c > 0x10FFFF) { goto invalid_utf8; } p = p_next; if (c == CP_LS || c == CP_PS) goto eol_error; } } else if (c >= 0x80) { const uint8_t *p_next; c = unicode_from_utf8(p - 1, UTF8_CHAR_LEN_MAX, &p_next); if (c > 0x10FFFF) { invalid_utf8: js_parse_error_pos(s, p - 1, "invalid UTF-8 sequence"); goto fail; } /* LS or PS are considered as line terminator */ if (c == CP_LS || c == CP_PS) { eol_error: js_parse_error_pos(s, p - 1, "unexpected line terminator in regexp"); goto fail; } p = p_next; } if (string_buffer_putc(b, c)) goto fail; } /* flags */ for(;;) { const uint8_t *p_next = p; c = *p_next++; if (c >= 0x80) { c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p_next); if (c > 0x10FFFF) { p++; goto invalid_utf8; } } if (!lre_js_is_ident_next(c)) break; if (string_buffer_putc(b2, c)) goto fail; p = p_next; } body_str = string_buffer_end(b); flags_str = string_buffer_end(b2); if (JS_IsException(body_str) || JS_IsException(flags_str)) { JS_FreeValue(s->ctx, body_str); JS_FreeValue(s->ctx, flags_str); return -1; } s->token.val = TOK_REGEXP; s->token.u.regexp.body = body_str; s->token.u.regexp.flags = flags_str; s->buf_ptr = p; return 0; fail: string_buffer_free(b); string_buffer_free(b2); return -1; } static __exception int ident_realloc(JSContext *ctx, char **pbuf, size_t *psize, char *static_buf) { char *buf, *new_buf; size_t size, new_size; buf = *pbuf; size = *psize; if (size >= (SIZE_MAX / 3) * 2) new_size = SIZE_MAX; else new_size = size + (size >> 1); if (buf == static_buf) { new_buf = js_malloc(ctx, new_size); if (!new_buf) return -1; memcpy(new_buf, buf, size); } else { new_buf = js_realloc(ctx, buf, new_size); if (!new_buf) return -1; } *pbuf = new_buf; *psize = new_size; return 0; } /* convert a TOK_IDENT to a keyword when needed */ static void update_token_ident(JSParseState *s) { if (s->token.u.ident.atom <= JS_ATOM_LAST_KEYWORD || (s->token.u.ident.atom <= JS_ATOM_LAST_STRICT_KEYWORD && (s->cur_func->js_mode & JS_MODE_STRICT)) || (s->token.u.ident.atom == JS_ATOM_yield && ((s->cur_func->func_kind & JS_FUNC_GENERATOR) || (s->cur_func->func_type == JS_PARSE_FUNC_ARROW && !s->cur_func->in_function_body && s->cur_func->parent && (s->cur_func->parent->func_kind & JS_FUNC_GENERATOR)))) || (s->token.u.ident.atom == JS_ATOM_await && (s->is_module || (s->cur_func->func_kind & JS_FUNC_ASYNC) || s->cur_func->func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT || (s->cur_func->func_type == JS_PARSE_FUNC_ARROW && !s->cur_func->in_function_body && s->cur_func->parent && ((s->cur_func->parent->func_kind & JS_FUNC_ASYNC) || s->cur_func->parent->func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT))))) { if (s->token.u.ident.has_escape) { s->token.u.ident.is_reserved = TRUE; s->token.val = TOK_IDENT; } else { /* The keywords atoms are pre allocated */ s->token.val = s->token.u.ident.atom - 1 + TOK_FIRST_KEYWORD; } } } /* if the current token is an identifier or keyword, reparse it according to the current function type */ static void reparse_ident_token(JSParseState *s) { if (s->token.val == TOK_IDENT || (s->token.val >= TOK_FIRST_KEYWORD && s->token.val <= TOK_LAST_KEYWORD)) { s->token.val = TOK_IDENT; s->token.u.ident.is_reserved = FALSE; update_token_ident(s); } } /* 'c' is the first character. Return JS_ATOM_NULL in case of error */ static JSAtom parse_ident(JSParseState *s, const uint8_t **pp, BOOL *pident_has_escape, int c, BOOL is_private) { const uint8_t *p, *p1; char ident_buf[128], *buf; size_t ident_size, ident_pos; JSAtom atom; p = *pp; buf = ident_buf; ident_size = sizeof(ident_buf); ident_pos = 0; if (is_private) buf[ident_pos++] = '#'; for(;;) { p1 = p; if (c < 128) { buf[ident_pos++] = c; } else { ident_pos += unicode_to_utf8((uint8_t*)buf + ident_pos, c); } c = *p1++; if (c == '\\' && *p1 == 'u') { c = lre_parse_escape(&p1, TRUE); *pident_has_escape = TRUE; } else if (c >= 128) { c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p1); } if (!lre_js_is_ident_next(c)) break; p = p1; if (unlikely(ident_pos >= ident_size - UTF8_CHAR_LEN_MAX)) { if (ident_realloc(s->ctx, &buf, &ident_size, ident_buf)) { atom = JS_ATOM_NULL; goto done; } } } atom = JS_NewAtomLen(s->ctx, buf, ident_pos); done: if (unlikely(buf != ident_buf)) js_free(s->ctx, buf); *pp = p; return atom; } static __exception int next_token(JSParseState *s) { const uint8_t *p; int c; BOOL ident_has_escape; JSAtom atom; if (js_check_stack_overflow(s->ctx->rt, 0)) { return js_parse_error(s, "stack overflow"); } free_token(s, &s->token); p = s->last_ptr = s->buf_ptr; s->got_lf = FALSE; redo: s->token.ptr = p; c = *p; switch(c) { case 0: if (p >= s->buf_end) { s->token.val = TOK_EOF; } else { goto def_token; } break; case '`': if (js_parse_template_part(s, p + 1)) goto fail; p = s->buf_ptr; break; case '\'': case '\"': if (js_parse_string(s, c, TRUE, p + 1, &s->token, &p)) goto fail; break; case '\r': /* accept DOS and MAC newline sequences */ if (p[1] == '\n') { p++; } /* fall thru */ case '\n': p++; line_terminator: s->got_lf = TRUE; goto redo; case '\f': case '\v': case ' ': case '\t': p++; goto redo; case '/': if (p[1] == '*') { /* comment */ p += 2; for(;;) { if (*p == '\0' && p >= s->buf_end) { js_parse_error(s, "unexpected end of comment"); goto fail; } if (p[0] == '*' && p[1] == '/') { p += 2; break; } if (*p == '\n' || *p == '\r') { s->got_lf = TRUE; /* considered as LF for ASI */ p++; } else if (*p >= 0x80) { c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); if (c == CP_LS || c == CP_PS) { s->got_lf = TRUE; /* considered as LF for ASI */ } else if (c == -1) { p++; /* skip invalid UTF-8 */ } } else { p++; } } goto redo; } else if (p[1] == '/') { /* line comment */ p += 2; skip_line_comment: for(;;) { if (*p == '\0' && p >= s->buf_end) break; if (*p == '\r' || *p == '\n') break; if (*p >= 0x80) { c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); /* LS or PS are considered as line terminator */ if (c == CP_LS || c == CP_PS) { break; } else if (c == -1) { p++; /* skip invalid UTF-8 */ } } else { p++; } } goto redo; } else if (p[1] == '=') { p += 2; s->token.val = TOK_DIV_ASSIGN; } else { p++; s->token.val = c; } break; case '\\': if (p[1] == 'u') { const uint8_t *p1 = p + 1; int c1 = lre_parse_escape(&p1, TRUE); if (c1 >= 0 && lre_js_is_ident_first(c1)) { c = c1; p = p1; ident_has_escape = TRUE; goto has_ident; } else { /* XXX: syntax error? */ } } goto def_token; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '_': case '$': /* identifier */ p++; ident_has_escape = FALSE; has_ident: atom = parse_ident(s, &p, &ident_has_escape, c, FALSE); if (atom == JS_ATOM_NULL) goto fail; s->token.u.ident.atom = atom; s->token.u.ident.has_escape = ident_has_escape; s->token.u.ident.is_reserved = FALSE; s->token.val = TOK_IDENT; update_token_ident(s); break; case '#': /* private name */ { const uint8_t *p1; p++; p1 = p; c = *p1++; if (c == '\\' && *p1 == 'u') { c = lre_parse_escape(&p1, TRUE); } else if (c >= 128) { c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p1); } if (!lre_js_is_ident_first(c)) { js_parse_error(s, "invalid first character of private name"); goto fail; } p = p1; ident_has_escape = FALSE; /* not used */ atom = parse_ident(s, &p, &ident_has_escape, c, TRUE); if (atom == JS_ATOM_NULL) goto fail; s->token.u.ident.atom = atom; s->token.val = TOK_PRIVATE_NAME; } break; case '.': if (p[1] == '.' && p[2] == '.') { p += 3; s->token.val = TOK_ELLIPSIS; break; } if (p[1] >= '0' && p[1] <= '9') { goto parse_number; } else { goto def_token; } break; case '0': /* in strict mode, octal literals are not accepted */ if (is_digit(p[1]) && (s->cur_func->js_mode & JS_MODE_STRICT)) { js_parse_error(s, "octal literals are deprecated in strict mode"); goto fail; } goto parse_number; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* number */ parse_number: { JSValue ret; const uint8_t *p1; int flags; flags = ATOD_ACCEPT_BIN_OCT | ATOD_ACCEPT_LEGACY_OCTAL | ATOD_ACCEPT_UNDERSCORES | ATOD_ACCEPT_SUFFIX; ret = js_atof(s->ctx, (const char *)p, (const char **)&p, 0, flags); if (JS_IsException(ret)) goto fail; /* reject `10instanceof Number` */ if (JS_VALUE_IS_NAN(ret) || lre_js_is_ident_next(unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p1))) { JS_FreeValue(s->ctx, ret); js_parse_error(s, "invalid number literal"); goto fail; } s->token.val = TOK_NUMBER; s->token.u.num.val = ret; } break; case '*': if (p[1] == '=') { p += 2; s->token.val = TOK_MUL_ASSIGN; } else if (p[1] == '*') { if (p[2] == '=') { p += 3; s->token.val = TOK_POW_ASSIGN; } else { p += 2; s->token.val = TOK_POW; } } else { goto def_token; } break; case '%': if (p[1] == '=') { p += 2; s->token.val = TOK_MOD_ASSIGN; } else { goto def_token; } break; case '+': if (p[1] == '=') { p += 2; s->token.val = TOK_PLUS_ASSIGN; } else if (p[1] == '+') { p += 2; s->token.val = TOK_INC; } else { goto def_token; } break; case '-': if (p[1] == '=') { p += 2; s->token.val = TOK_MINUS_ASSIGN; } else if (p[1] == '-') { if (s->allow_html_comments && p[2] == '>' && (s->got_lf || s->last_ptr == s->buf_start)) { /* Annex B: `-->` at beginning of line is an html comment end. It extends to the end of the line. */ goto skip_line_comment; } p += 2; s->token.val = TOK_DEC; } else { goto def_token; } break; case '<': if (p[1] == '=') { p += 2; s->token.val = TOK_LTE; } else if (p[1] == '<') { if (p[2] == '=') { p += 3; s->token.val = TOK_SHL_ASSIGN; } else { p += 2; s->token.val = TOK_SHL; } } else if (s->allow_html_comments && p[1] == '!' && p[2] == '-' && p[3] == '-') { /* Annex B: handle `<!--` single line html comments */ goto skip_line_comment; } else { goto def_token; } break; case '>': if (p[1] == '=') { p += 2; s->token.val = TOK_GTE; } else if (p[1] == '>') { if (p[2] == '>') { if (p[3] == '=') { p += 4; s->token.val = TOK_SHR_ASSIGN; } else { p += 3; s->token.val = TOK_SHR; } } else if (p[2] == '=') { p += 3; s->token.val = TOK_SAR_ASSIGN; } else { p += 2; s->token.val = TOK_SAR; } } else { goto def_token; } break; case '=': if (p[1] == '=') { if (p[2] == '=') { p += 3; s->token.val = TOK_STRICT_EQ; } else { p += 2; s->token.val = TOK_EQ; } } else if (p[1] == '>') { p += 2; s->token.val = TOK_ARROW; } else { goto def_token; } break; case '!': if (p[1] == '=') { if (p[2] == '=') { p += 3; s->token.val = TOK_STRICT_NEQ; } else { p += 2; s->token.val = TOK_NEQ; } } else { goto def_token; } break; case '&': if (p[1] == '=') { p += 2; s->token.val = TOK_AND_ASSIGN; } else if (p[1] == '&') { if (p[2] == '=') { p += 3; s->token.val = TOK_LAND_ASSIGN; } else { p += 2; s->token.val = TOK_LAND; } } else { goto def_token; } break; case '^': if (p[1] == '=') { p += 2; s->token.val = TOK_XOR_ASSIGN; } else { goto def_token; } break; case '|': if (p[1] == '=') { p += 2; s->token.val = TOK_OR_ASSIGN; } else if (p[1] == '|') { if (p[2] == '=') { p += 3; s->token.val = TOK_LOR_ASSIGN; } else { p += 2; s->token.val = TOK_LOR; } } else { goto def_token; } break; case '?': if (p[1] == '?') { if (p[2] == '=') { p += 3; s->token.val = TOK_DOUBLE_QUESTION_MARK_ASSIGN; } else { p += 2; s->token.val = TOK_DOUBLE_QUESTION_MARK; } } else if (p[1] == '.' && !(p[2] >= '0' && p[2] <= '9')) { p += 2; s->token.val = TOK_QUESTION_MARK_DOT; } else { goto def_token; } break; default: if (c >= 128) { /* unicode value */ c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); switch(c) { case CP_PS: case CP_LS: /* XXX: should avoid incrementing line_number, but needed to handle HTML comments */ goto line_terminator; default: if (lre_is_space(c)) { goto redo; } else if (lre_js_is_ident_first(c)) { ident_has_escape = FALSE; goto has_ident; } else { js_parse_error(s, "unexpected character"); goto fail; } } } def_token: s->token.val = c; p++; break; } s->buf_ptr = p; // dump_token(s, &s->token); return 0; fail: s->token.val = TOK_ERROR; return -1; } /* 'c' is the first character. Return JS_ATOM_NULL in case of error */ /* XXX: accept unicode identifiers as JSON5 ? */ static JSAtom json_parse_ident(JSParseState *s, const uint8_t **pp, int c) { const uint8_t *p; char ident_buf[128], *buf; size_t ident_size, ident_pos; JSAtom atom; p = *pp; buf = ident_buf; ident_size = sizeof(ident_buf); ident_pos = 0; for(;;) { buf[ident_pos++] = c; c = *p; if (c >= 128 || !lre_is_id_continue_byte(c)) break; p++; if (unlikely(ident_pos >= ident_size - UTF8_CHAR_LEN_MAX)) { if (ident_realloc(s->ctx, &buf, &ident_size, ident_buf)) { atom = JS_ATOM_NULL; goto done; } } } atom = JS_NewAtomLen(s->ctx, buf, ident_pos); done: if (unlikely(buf != ident_buf)) js_free(s->ctx, buf); *pp = p; return atom; } static int json_parse_string(JSParseState *s, const uint8_t **pp, int sep) { const uint8_t *p, *p_next; int i; uint32_t c; StringBuffer b_s, *b = &b_s; if (string_buffer_init(s->ctx, b, 32)) goto fail; p = *pp; for(;;) { if (p >= s->buf_end) { goto end_of_input; } c = *p++; if (c == sep) break; if (c < 0x20) { js_parse_error_pos(s, p - 1, "Bad control character in string literal"); goto fail; } if (c == '\\') { c = *p++; switch(c) { case 'b': c = '\b'; break; case 'f': c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case '\\': break; case '/': break; case 'u': c = 0; for(i = 0; i < 4; i++) { int h = from_hex(*p++); if (h < 0) { js_parse_error_pos(s, p - 1, "Bad Unicode escape"); goto fail; } c = (c << 4) | h; } break; case '\n': if (s->ext_json) continue; goto bad_escape; case 'v': if (s->ext_json) { c = '\v'; break; } goto bad_escape; default: if (c == sep) break; if (p > s->buf_end) goto end_of_input; bad_escape: js_parse_error_pos(s, p - 1, "Bad escaped character"); goto fail; } } else if (c >= 0x80) { c = unicode_from_utf8(p - 1, UTF8_CHAR_LEN_MAX, &p_next); if (c > 0x10FFFF) { js_parse_error_pos(s, p - 1, "Bad UTF-8 sequence"); goto fail; } p = p_next; } if (string_buffer_putc(b, c)) goto fail; } s->token.val = TOK_STRING; s->token.u.str.sep = sep; s->token.u.str.str = string_buffer_end(b); *pp = p; return 0; end_of_input: js_parse_error(s, "Unexpected end of JSON input"); fail: string_buffer_free(b); return -1; } static int json_parse_number(JSParseState *s, const uint8_t **pp) { const uint8_t *p = *pp; const uint8_t *p_start = p; int radix; double d; JSATODTempMem atod_mem; if (*p == '+' || *p == '-') p++; if (!is_digit(*p)) { if (s->ext_json) { if (strstart((const char *)p, "Infinity", (const char **)&p)) { d = 1.0 / 0.0; if (*p_start == '-') d = -d; goto done; } else if (strstart((const char *)p, "NaN", (const char **)&p)) { d = NAN; goto done; } else if (*p != '.') { goto unexpected_token; } } else { goto unexpected_token; } } if (p[0] == '0') { if (s->ext_json) { /* also accepts base 16, 8 and 2 prefix for integers */ radix = 10; if (p[1] == 'x' || p[1] == 'X') { p += 2; radix = 16; } else if ((p[1] == 'o' || p[1] == 'O')) { p += 2; radix = 8; } else if ((p[1] == 'b' || p[1] == 'B')) { p += 2; radix = 2; } if (radix != 10) { /* prefix is present */ if (to_digit(*p) >= radix) { unexpected_token: return js_parse_error_pos(s, p, "Unexpected token '%c'", *p); } d = js_atod((const char *)p_start, (const char **)&p, 0, JS_ATOD_INT_ONLY | JS_ATOD_ACCEPT_BIN_OCT, &atod_mem); goto done; } } if (is_digit(p[1])) return js_parse_error_pos(s, p, "Unexpected number"); } while (is_digit(*p)) p++; if (*p == '.') { p++; if (!is_digit(*p)) return js_parse_error_pos(s, p, "Unterminated fractional number"); while (is_digit(*p)) p++; } if (*p == 'e' || *p == 'E') { p++; if (*p == '+' || *p == '-') p++; if (!is_digit(*p)) return js_parse_error_pos(s, p, "Exponent part is missing a number"); while (is_digit(*p)) p++; } d = js_atod((const char *)p_start, NULL, 10, 0, &atod_mem); done: s->token.val = TOK_NUMBER; s->token.u.num.val = JS_NewFloat64(s->ctx, d); *pp = p; return 0; } static __exception int json_next_token(JSParseState *s) { const uint8_t *p; int c; JSAtom atom; if (js_check_stack_overflow(s->ctx->rt, 0)) { return js_parse_error(s, "stack overflow"); } free_token(s, &s->token); p = s->last_ptr = s->buf_ptr; redo: s->token.ptr = p; c = *p; switch(c) { case 0: if (p >= s->buf_end) { s->token.val = TOK_EOF; } else { goto def_token; } break; case '\'': if (!s->ext_json) { /* JSON does not accept single quoted strings */ goto def_token; } /* fall through */ case '\"': p++; if (json_parse_string(s, &p, c)) goto fail; break; case '\r': /* accept DOS and MAC newline sequences */ if (p[1] == '\n') { p++; } /* fall thru */ case '\n': p++; goto redo; case '\f': case '\v': if (!s->ext_json) { /* JSONWhitespace does not match <VT>, nor <FF> */ goto def_token; } /* fall through */ case ' ': case '\t': p++; goto redo; case '/': if (!s->ext_json) { /* JSON does not accept comments */ goto def_token; } if (p[1] == '*') { /* comment */ p += 2; for(;;) { if (*p == '\0' && p >= s->buf_end) { js_parse_error(s, "unexpected end of comment"); goto fail; } if (p[0] == '*' && p[1] == '/') { p += 2; break; } if (*p >= 0x80) { c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); if (c == -1) { p++; /* skip invalid UTF-8 */ } } else { p++; } } goto redo; } else if (p[1] == '/') { /* line comment */ p += 2; for(;;) { if (*p == '\0' && p >= s->buf_end) break; if (*p == '\r' || *p == '\n') break; if (*p >= 0x80) { c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); /* LS or PS are considered as line terminator */ if (c == CP_LS || c == CP_PS) { break; } else if (c == -1) { p++; /* skip invalid UTF-8 */ } } else { p++; } } goto redo; } else { goto def_token; } break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '_': case '$': p++; atom = json_parse_ident(s, &p, c); if (atom == JS_ATOM_NULL) goto fail; s->token.u.ident.atom = atom; s->token.u.ident.has_escape = FALSE; s->token.u.ident.is_reserved = FALSE; s->token.val = TOK_IDENT; break; case '+': if (!s->ext_json) goto def_token; goto parse_number; case '.': if (s->ext_json && is_digit(p[1])) goto parse_number; else goto def_token; case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* number */ parse_number: if (json_parse_number(s, &p)) goto fail; break; default: if (c >= 128) { js_parse_error(s, "unexpected character"); goto fail; } def_token: s->token.val = c; p++; break; } s->buf_ptr = p; // dump_token(s, &s->token); return 0; fail: s->token.val = TOK_ERROR; return -1; } static int match_identifier(const uint8_t *p, const char *s) { uint32_t c; while (*s) { if ((uint8_t)*s++ != *p++) return 0; } c = *p; if (c >= 128) c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); return !lre_js_is_ident_next(c); } /* simple_next_token() is used to check for the next token in simple cases. It is only used for ':' and '=>', 'let' or 'function' look-ahead. (*pp) is only set if TOK_IMPORT is returned for JS_DetectModule() Whitespace and comments are skipped correctly. Then the next token is analyzed, only for specific words. Return values: - '\n' if !no_line_terminator - TOK_ARROW, TOK_IN, TOK_IMPORT, TOK_OF, TOK_EXPORT, TOK_FUNCTION - TOK_IDENT is returned for other identifiers and keywords - otherwise the next character or unicode codepoint is returned. */ static int simple_next_token(const uint8_t **pp, BOOL no_line_terminator) { const uint8_t *p; uint32_t c; /* skip spaces and comments */ p = *pp; for (;;) { switch(c = *p++) { case '\r': case '\n': if (no_line_terminator) return '\n'; continue; case ' ': case '\t': case '\v': case '\f': continue; case '/': if (*p == '/') { if (no_line_terminator) return '\n'; while (*p && *p != '\r' && *p != '\n') p++; continue; } if (*p == '*') { while (*++p) { if ((*p == '\r' || *p == '\n') && no_line_terminator) return '\n'; if (*p == '*' && p[1] == '/') { p += 2; break; } } continue; } break; case '=': if (*p == '>') return TOK_ARROW; break; case 'i': if (match_identifier(p, "n")) return TOK_IN; if (match_identifier(p, "mport")) { *pp = p + 5; return TOK_IMPORT; } return TOK_IDENT; case 'o': if (match_identifier(p, "f")) return TOK_OF; return TOK_IDENT; case 'e': if (match_identifier(p, "xport")) return TOK_EXPORT; return TOK_IDENT; case 'f': if (match_identifier(p, "unction")) return TOK_FUNCTION; return TOK_IDENT; case '\\': if (*p == 'u') { if (lre_js_is_ident_first(lre_parse_escape(&p, TRUE))) return TOK_IDENT; } break; default: if (c >= 128) { c = unicode_from_utf8(p - 1, UTF8_CHAR_LEN_MAX, &p); if (no_line_terminator && (c == CP_PS || c == CP_LS)) return '\n'; } if (lre_is_space(c)) continue; if (lre_js_is_ident_first(c)) return TOK_IDENT; break; } return c; } } static int peek_token(JSParseState *s, BOOL no_line_terminator) { const uint8_t *p = s->buf_ptr; return simple_next_token(&p, no_line_terminator); } static void skip_shebang(const uint8_t **pp, const uint8_t *buf_end) { const uint8_t *p = *pp; int c; if (p[0] == '#' && p[1] == '!') { p += 2; while (p < buf_end) { if (*p == '\n' || *p == '\r') { break; } else if (*p >= 0x80) { c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); if (c == CP_LS || c == CP_PS) { break; } else if (c == -1) { p++; /* skip invalid UTF-8 */ } } else { p++; } } *pp = p; } } /* return true if 'input' contains the source of a module (heuristic). 'input' must be a zero terminated. Heuristic: skip comments and expect 'import' keyword not followed by '(' or '.' or export keyword. */ BOOL JS_DetectModule(const char *input, size_t input_len) { const uint8_t *p = (const uint8_t *)input; int tok; skip_shebang(&p, p + input_len); switch(simple_next_token(&p, FALSE)) { case TOK_IMPORT: tok = simple_next_token(&p, FALSE); return (tok != '.' && tok != '('); case TOK_EXPORT: return TRUE; default: return FALSE; } } static inline int get_prev_opcode(JSFunctionDef *fd) { if (fd->last_opcode_pos < 0 || dbuf_error(&fd->byte_code)) return OP_invalid; else return fd->byte_code.buf[fd->last_opcode_pos]; } static BOOL js_is_live_code(JSParseState *s) { switch (get_prev_opcode(s->cur_func)) { case OP_tail_call: case OP_tail_call_method: case OP_return: case OP_return_undef: case OP_return_async: case OP_throw: case OP_throw_error: case OP_goto: #if SHORT_OPCODES case OP_goto8: case OP_goto16: #endif case OP_ret: return FALSE; default: return TRUE; } } static void emit_u8(JSParseState *s, uint8_t val) { dbuf_putc(&s->cur_func->byte_code, val); } static void emit_u16(JSParseState *s, uint16_t val) { dbuf_put_u16(&s->cur_func->byte_code, val); } static void emit_u32(JSParseState *s, uint32_t val) { dbuf_put_u32(&s->cur_func->byte_code, val); } static void emit_source_pos(JSParseState *s, const uint8_t *source_ptr) { JSFunctionDef *fd = s->cur_func; DynBuf *bc = &fd->byte_code; if (unlikely(fd->last_opcode_source_ptr != source_ptr)) { dbuf_putc(bc, OP_line_num); dbuf_put_u32(bc, source_ptr - s->buf_start); fd->last_opcode_source_ptr = source_ptr; } } static void emit_op(JSParseState *s, uint8_t val) { JSFunctionDef *fd = s->cur_func; DynBuf *bc = &fd->byte_code; fd->last_opcode_pos = bc->size; dbuf_putc(bc, val); } static void emit_atom(JSParseState *s, JSAtom name) { DynBuf *bc = &s->cur_func->byte_code; if (dbuf_claim(bc, 4)) return; /* not enough memory : don't duplicate the atom */ put_u32(bc->buf + bc->size, JS_DupAtom(s->ctx, name)); bc->size += 4; } static int update_label(JSFunctionDef *s, int label, int delta) { LabelSlot *ls; assert(label >= 0 && label < s->label_count); ls = &s->label_slots[label]; ls->ref_count += delta; assert(ls->ref_count >= 0); return ls->ref_count; } static int new_label_fd(JSFunctionDef *fd) { int label; LabelSlot *ls; if (js_resize_array(fd->ctx, (void *)&fd->label_slots, sizeof(fd->label_slots[0]), &fd->label_size, fd->label_count + 1)) return -1; label = fd->label_count++; ls = &fd->label_slots[label]; ls->ref_count = 0; ls->pos = -1; ls->pos2 = -1; ls->addr = -1; ls->first_reloc = NULL; return label; } static int new_label(JSParseState *s) { int label; label = new_label_fd(s->cur_func); if (unlikely(label < 0)) { dbuf_set_error(&s->cur_func->byte_code); } return label; } /* don't update the last opcode and don't emit line number info */ static void emit_label_raw(JSParseState *s, int label) { emit_u8(s, OP_label); emit_u32(s, label); s->cur_func->label_slots[label].pos = s->cur_func->byte_code.size; } /* return the label ID offset */ static int emit_label(JSParseState *s, int label) { if (label >= 0) { emit_op(s, OP_label); emit_u32(s, label); s->cur_func->label_slots[label].pos = s->cur_func->byte_code.size; return s->cur_func->byte_code.size - 4; } else { return -1; } } /* return label or -1 if dead code */ static int emit_goto(JSParseState *s, int opcode, int label) { if (js_is_live_code(s)) { if (label < 0) { label = new_label(s); if (label < 0) return -1; } emit_op(s, opcode); emit_u32(s, label); s->cur_func->label_slots[label].ref_count++; return label; } return -1; } /* return the constant pool index. 'val' is not duplicated. */ static int cpool_add(JSParseState *s, JSValue val) { JSFunctionDef *fd = s->cur_func; if (js_resize_array(s->ctx, (void *)&fd->cpool, sizeof(fd->cpool[0]), &fd->cpool_size, fd->cpool_count + 1)) { JS_FreeValue(s->ctx, val); return -1; } fd->cpool[fd->cpool_count++] = val; return fd->cpool_count - 1; } static __exception int emit_push_const(JSParseState *s, JSValueConst val, BOOL as_atom) { int idx; if (JS_VALUE_GET_TAG(val) == JS_TAG_STRING && as_atom) { JSAtom atom; /* warning: JS_NewAtomStr frees the string value */ JS_DupValue(s->ctx, val); atom = JS_NewAtomStr(s->ctx, JS_VALUE_GET_STRING(val)); if (atom != JS_ATOM_NULL && !__JS_AtomIsTaggedInt(atom)) { emit_op(s, OP_push_atom_value); emit_u32(s, atom); return 0; } } idx = cpool_add(s, JS_DupValue(s->ctx, val)); if (idx < 0) return -1; emit_op(s, OP_push_const); emit_u32(s, idx); return 0; } /* return the variable index or -1 if not found, add ARGUMENT_VAR_OFFSET for argument variables */ static int find_arg(JSContext *ctx, JSFunctionDef *fd, JSAtom name) { int i; for(i = fd->arg_count; i-- > 0;) { if (fd->args[i].var_name == name) return i | ARGUMENT_VAR_OFFSET; } return -1; } static int find_var(JSContext *ctx, JSFunctionDef *fd, JSAtom name) { int i; for(i = fd->var_count; i-- > 0;) { if (fd->vars[i].var_name == name && fd->vars[i].scope_level == 0) return i; } return find_arg(ctx, fd, name); } /* find a variable declaration in a given scope */ static int find_var_in_scope(JSContext *ctx, JSFunctionDef *fd, JSAtom name, int scope_level) { int scope_idx; for(scope_idx = fd->scopes[scope_level].first; scope_idx >= 0; scope_idx = fd->vars[scope_idx].scope_next) { if (fd->vars[scope_idx].scope_level != scope_level) break; if (fd->vars[scope_idx].var_name == name) return scope_idx; } return -1; } /* return true if scope == parent_scope or if scope is a child of parent_scope */ static BOOL is_child_scope(JSContext *ctx, JSFunctionDef *fd, int scope, int parent_scope) { while (scope >= 0) { if (scope == parent_scope) return TRUE; scope = fd->scopes[scope].parent; } return FALSE; } /* find a 'var' declaration in the same scope or a child scope */ static int find_var_in_child_scope(JSContext *ctx, JSFunctionDef *fd, JSAtom name, int scope_level) { int i; for(i = 0; i < fd->var_count; i++) { JSVarDef *vd = &fd->vars[i]; if (vd->var_name == name && vd->scope_level == 0) { if (is_child_scope(ctx, fd, vd->scope_next, scope_level)) return i; } } return -1; } static JSGlobalVar *find_global_var(JSFunctionDef *fd, JSAtom name) { int i; for(i = 0; i < fd->global_var_count; i++) { JSGlobalVar *hf = &fd->global_vars[i]; if (hf->var_name == name) return hf; } return NULL; } static JSGlobalVar *find_lexical_global_var(JSFunctionDef *fd, JSAtom name) { JSGlobalVar *hf = find_global_var(fd, name); if (hf && hf->is_lexical) return hf; else return NULL; } static int find_lexical_decl(JSContext *ctx, JSFunctionDef *fd, JSAtom name, int scope_idx, BOOL check_catch_var) { while (scope_idx >= 0) { JSVarDef *vd = &fd->vars[scope_idx]; if (vd->var_name == name && (vd->is_lexical || (vd->var_kind == JS_VAR_CATCH && check_catch_var))) return scope_idx; scope_idx = vd->scope_next; } if (fd->is_eval && fd->eval_type == JS_EVAL_TYPE_GLOBAL) { if (find_lexical_global_var(fd, name)) return GLOBAL_VAR_OFFSET; } return -1; } static int push_scope(JSParseState *s) { if (s->cur_func) { JSFunctionDef *fd = s->cur_func; int scope = fd->scope_count; /* XXX: should check for scope overflow */ if ((fd->scope_count + 1) > fd->scope_size) { int new_size; size_t slack; JSVarScope *new_buf; /* XXX: potential arithmetic overflow */ new_size = max_int(fd->scope_count + 1, fd->scope_size * 3 / 2); if (fd->scopes == fd->def_scope_array) { new_buf = js_realloc2(s->ctx, NULL, new_size * sizeof(*fd->scopes), &slack); if (!new_buf) return -1; memcpy(new_buf, fd->scopes, fd->scope_count * sizeof(*fd->scopes)); } else { new_buf = js_realloc2(s->ctx, fd->scopes, new_size * sizeof(*fd->scopes), &slack); if (!new_buf) return -1; } new_size += slack / sizeof(*new_buf); fd->scopes = new_buf; fd->scope_size = new_size; } fd->scope_count++; fd->scopes[scope].parent = fd->scope_level; fd->scopes[scope].first = fd->scope_first; emit_op(s, OP_enter_scope); emit_u16(s, scope); return fd->scope_level = scope; } return 0; } static int get_first_lexical_var(JSFunctionDef *fd, int scope) { while (scope >= 0) { int scope_idx = fd->scopes[scope].first; if (scope_idx >= 0) return scope_idx; scope = fd->scopes[scope].parent; } return -1; } static void pop_scope(JSParseState *s) { if (s->cur_func) { /* disable scoped variables */ JSFunctionDef *fd = s->cur_func; int scope = fd->scope_level; emit_op(s, OP_leave_scope); emit_u16(s, scope); fd->scope_level = fd->scopes[scope].parent; fd->scope_first = get_first_lexical_var(fd, fd->scope_level); } } static void close_scopes(JSParseState *s, int scope, int scope_stop) { while (scope > scope_stop) { emit_op(s, OP_leave_scope); emit_u16(s, scope); scope = s->cur_func->scopes[scope].parent; } } /* return the variable index or -1 if error */ static int add_var(JSContext *ctx, JSFunctionDef *fd, JSAtom name) { JSVarDef *vd; /* the local variable indexes are currently stored on 16 bits */ if (fd->var_count >= JS_MAX_LOCAL_VARS) { JS_ThrowInternalError(ctx, "too many local variables"); return -1; } if (js_resize_array(ctx, (void **)&fd->vars, sizeof(fd->vars[0]), &fd->var_size, fd->var_count + 1)) return -1; vd = &fd->vars[fd->var_count++]; memset(vd, 0, sizeof(*vd)); vd->var_name = JS_DupAtom(ctx, name); vd->func_pool_idx = -1; return fd->var_count - 1; } static int add_scope_var(JSContext *ctx, JSFunctionDef *fd, JSAtom name, JSVarKindEnum var_kind) { int idx = add_var(ctx, fd, name); if (idx >= 0) { JSVarDef *vd = &fd->vars[idx]; vd->var_kind = var_kind; vd->scope_level = fd->scope_level; vd->scope_next = fd->scope_first; fd->scopes[fd->scope_level].first = idx; fd->scope_first = idx; } return idx; } static int add_func_var(JSContext *ctx, JSFunctionDef *fd, JSAtom name) { int idx = fd->func_var_idx; if (idx < 0 && (idx = add_var(ctx, fd, name)) >= 0) { fd->func_var_idx = idx; fd->vars[idx].var_kind = JS_VAR_FUNCTION_NAME; if (fd->js_mode & JS_MODE_STRICT) fd->vars[idx].is_const = TRUE; } return idx; } static int add_arguments_var(JSContext *ctx, JSFunctionDef *fd) { int idx = fd->arguments_var_idx; if (idx < 0 && (idx = add_var(ctx, fd, JS_ATOM_arguments)) >= 0) { fd->arguments_var_idx = idx; } return idx; } /* add an argument definition in the argument scope. Only needed when "eval()" may be called in the argument scope. Return 0 if OK. */ static int add_arguments_arg(JSContext *ctx, JSFunctionDef *fd) { int idx; if (fd->arguments_arg_idx < 0) { idx = find_var_in_scope(ctx, fd, JS_ATOM_arguments, ARG_SCOPE_INDEX); if (idx < 0) { /* XXX: the scope links are not fully updated. May be an issue if there are child scopes of the argument scope */ idx = add_var(ctx, fd, JS_ATOM_arguments); if (idx < 0) return -1; fd->vars[idx].scope_next = fd->scopes[ARG_SCOPE_INDEX].first; fd->scopes[ARG_SCOPE_INDEX].first = idx; fd->vars[idx].scope_level = ARG_SCOPE_INDEX; fd->vars[idx].is_lexical = TRUE; fd->arguments_arg_idx = idx; } } return 0; } static int add_arg(JSContext *ctx, JSFunctionDef *fd, JSAtom name) { JSVarDef *vd; /* the local variable indexes are currently stored on 16 bits */ if (fd->arg_count >= JS_MAX_LOCAL_VARS) { JS_ThrowInternalError(ctx, "too many arguments"); return -1; } if (js_resize_array(ctx, (void **)&fd->args, sizeof(fd->args[0]), &fd->arg_size, fd->arg_count + 1)) return -1; vd = &fd->args[fd->arg_count++]; memset(vd, 0, sizeof(*vd)); vd->var_name = JS_DupAtom(ctx, name); vd->func_pool_idx = -1; return fd->arg_count - 1; } /* add a global variable definition */ static JSGlobalVar *add_global_var(JSContext *ctx, JSFunctionDef *s, JSAtom name) { JSGlobalVar *hf; if (js_resize_array(ctx, (void **)&s->global_vars, sizeof(s->global_vars[0]), &s->global_var_size, s->global_var_count + 1)) return NULL; hf = &s->global_vars[s->global_var_count++]; hf->cpool_idx = -1; hf->force_init = FALSE; hf->is_lexical = FALSE; hf->is_const = FALSE; hf->scope_level = s->scope_level; hf->var_name = JS_DupAtom(ctx, name); return hf; } typedef enum { JS_VAR_DEF_WITH, JS_VAR_DEF_LET, JS_VAR_DEF_CONST, JS_VAR_DEF_FUNCTION_DECL, /* function declaration */ JS_VAR_DEF_NEW_FUNCTION_DECL, /* async/generator function declaration */ JS_VAR_DEF_CATCH, JS_VAR_DEF_VAR, } JSVarDefEnum; static int define_var(JSParseState *s, JSFunctionDef *fd, JSAtom name, JSVarDefEnum var_def_type) { JSContext *ctx = s->ctx; JSVarDef *vd; int idx; switch (var_def_type) { case JS_VAR_DEF_WITH: idx = add_scope_var(ctx, fd, name, JS_VAR_NORMAL); break; case JS_VAR_DEF_LET: case JS_VAR_DEF_CONST: case JS_VAR_DEF_FUNCTION_DECL: case JS_VAR_DEF_NEW_FUNCTION_DECL: idx = find_lexical_decl(ctx, fd, name, fd->scope_first, TRUE); if (idx >= 0) { if (idx < GLOBAL_VAR_OFFSET) { if (fd->vars[idx].scope_level == fd->scope_level) { /* same scope: in non strict mode, functions can be redefined (annex B.3.3.4). */ if (!(!(fd->js_mode & JS_MODE_STRICT) && var_def_type == JS_VAR_DEF_FUNCTION_DECL && fd->vars[idx].var_kind == JS_VAR_FUNCTION_DECL)) { goto redef_lex_error; } } else if (fd->vars[idx].var_kind == JS_VAR_CATCH && (fd->vars[idx].scope_level + 2) == fd->scope_level) { goto redef_lex_error; } } else { if (fd->scope_level == fd->body_scope) { redef_lex_error: /* redefining a scoped var in the same scope: error */ return js_parse_error(s, "invalid redefinition of lexical identifier"); } } } if (var_def_type != JS_VAR_DEF_FUNCTION_DECL && var_def_type != JS_VAR_DEF_NEW_FUNCTION_DECL && fd->scope_level == fd->body_scope && find_arg(ctx, fd, name) >= 0) { /* lexical variable redefines a parameter name */ return js_parse_error(s, "invalid redefinition of parameter name"); } if (find_var_in_child_scope(ctx, fd, name, fd->scope_level) >= 0) { return js_parse_error(s, "invalid redefinition of a variable"); } if (fd->is_global_var) { JSGlobalVar *hf; hf = find_global_var(fd, name); if (hf && is_child_scope(ctx, fd, hf->scope_level, fd->scope_level)) { return js_parse_error(s, "invalid redefinition of global identifier"); } } if (fd->is_eval && (fd->eval_type == JS_EVAL_TYPE_GLOBAL || fd->eval_type == JS_EVAL_TYPE_MODULE) && fd->scope_level == fd->body_scope) { JSGlobalVar *hf; hf = add_global_var(s->ctx, fd, name); if (!hf) return -1; hf->is_lexical = TRUE; hf->is_const = (var_def_type == JS_VAR_DEF_CONST); idx = GLOBAL_VAR_OFFSET; } else { JSVarKindEnum var_kind; if (var_def_type == JS_VAR_DEF_FUNCTION_DECL) var_kind = JS_VAR_FUNCTION_DECL; else if (var_def_type == JS_VAR_DEF_NEW_FUNCTION_DECL) var_kind = JS_VAR_NEW_FUNCTION_DECL; else var_kind = JS_VAR_NORMAL; idx = add_scope_var(ctx, fd, name, var_kind); if (idx >= 0) { vd = &fd->vars[idx]; vd->is_lexical = 1; vd->is_const = (var_def_type == JS_VAR_DEF_CONST); } } break; case JS_VAR_DEF_CATCH: idx = add_scope_var(ctx, fd, name, JS_VAR_CATCH); break; case JS_VAR_DEF_VAR: if (find_lexical_decl(ctx, fd, name, fd->scope_first, FALSE) >= 0) { invalid_lexical_redefinition: /* error to redefine a var that inside a lexical scope */ return js_parse_error(s, "invalid redefinition of lexical identifier"); } if (fd->is_global_var) { JSGlobalVar *hf; hf = find_global_var(fd, name); if (hf && hf->is_lexical && hf->scope_level == fd->scope_level && fd->eval_type == JS_EVAL_TYPE_MODULE) { goto invalid_lexical_redefinition; } hf = add_global_var(s->ctx, fd, name); if (!hf) return -1; idx = GLOBAL_VAR_OFFSET; } else { /* if the variable already exists, don't add it again */ idx = find_var(ctx, fd, name); if (idx >= 0) break; idx = add_var(ctx, fd, name); if (idx >= 0) { if (name == JS_ATOM_arguments && fd->has_arguments_binding) fd->arguments_var_idx = idx; fd->vars[idx].scope_next = fd->scope_level; } } break; default: abort(); } return idx; } /* add a private field variable in the current scope */ static int add_private_class_field(JSParseState *s, JSFunctionDef *fd, JSAtom name, JSVarKindEnum var_kind, BOOL is_static) { JSContext *ctx = s->ctx; JSVarDef *vd; int idx; idx = add_scope_var(ctx, fd, name, var_kind); if (idx < 0) return idx; vd = &fd->vars[idx]; vd->is_lexical = 1; vd->is_const = 1; vd->is_static_private = is_static; return idx; } static __exception int js_parse_expr(JSParseState *s); static __exception int js_parse_function_decl(JSParseState *s, JSParseFunctionEnum func_type, JSFunctionKindEnum func_kind, JSAtom func_name, const uint8_t *ptr); static JSFunctionDef *js_parse_function_class_fields_init(JSParseState *s); static __exception int js_parse_function_decl2(JSParseState *s, JSParseFunctionEnum func_type, JSFunctionKindEnum func_kind, JSAtom func_name, const uint8_t *ptr, JSParseExportEnum export_flag, JSFunctionDef **pfd); static __exception int js_parse_assign_expr2(JSParseState *s, int parse_flags); static __exception int js_parse_assign_expr(JSParseState *s); static __exception int js_parse_unary(JSParseState *s, int parse_flags); static void push_break_entry(JSFunctionDef *fd, BlockEnv *be, JSAtom label_name, int label_break, int label_cont, int drop_count); static void pop_break_entry(JSFunctionDef *fd); static JSExportEntry *add_export_entry(JSParseState *s, JSModuleDef *m, JSAtom local_name, JSAtom export_name, JSExportTypeEnum export_type); /* Note: all the fields are already sealed except length */ static int seal_template_obj(JSContext *ctx, JSValueConst obj) { JSObject *p; JSShapeProperty *prs; p = JS_VALUE_GET_OBJ(obj); prs = find_own_property1(p, JS_ATOM_length); if (prs) { if (js_update_property_flags(ctx, p, &prs, prs->flags & ~(JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE))) return -1; } p->extensible = FALSE; return 0; } static __exception int js_parse_template(JSParseState *s, int call, int *argc) { JSContext *ctx = s->ctx; JSValue raw_array, template_object; JSToken cooked; int depth, ret; raw_array = JS_UNDEFINED; /* avoid warning */ template_object = JS_UNDEFINED; /* avoid warning */ if (call) { /* Create a template object: an array of cooked strings */ /* Create an array of raw strings and store it to the raw property */ template_object = JS_NewArray(ctx); if (JS_IsException(template_object)) return -1; // pool_idx = s->cur_func->cpool_count; ret = emit_push_const(s, template_object, 0); JS_FreeValue(ctx, template_object); if (ret) return -1; raw_array = JS_NewArray(ctx); if (JS_IsException(raw_array)) return -1; if (JS_DefinePropertyValue(ctx, template_object, JS_ATOM_raw, raw_array, JS_PROP_THROW) < 0) { return -1; } } depth = 0; while (s->token.val == TOK_TEMPLATE) { const uint8_t *p = s->token.ptr + 1; cooked = s->token; if (call) { if (JS_DefinePropertyValueUint32(ctx, raw_array, depth, JS_DupValue(ctx, s->token.u.str.str), JS_PROP_ENUMERABLE | JS_PROP_THROW) < 0) { return -1; } /* re-parse the string with escape sequences but do not throw a syntax error if it contains invalid sequences */ if (js_parse_string(s, '`', FALSE, p, &cooked, &p)) { cooked.u.str.str = JS_UNDEFINED; } if (JS_DefinePropertyValueUint32(ctx, template_object, depth, cooked.u.str.str, JS_PROP_ENUMERABLE | JS_PROP_THROW) < 0) { return -1; } } else { JSString *str; /* re-parse the string with escape sequences and throw a syntax error if it contains invalid sequences */ JS_FreeValue(ctx, s->token.u.str.str); s->token.u.str.str = JS_UNDEFINED; if (js_parse_string(s, '`', TRUE, p, &cooked, &p)) return -1; str = JS_VALUE_GET_STRING(cooked.u.str.str); if (str->len != 0 || depth == 0) { ret = emit_push_const(s, cooked.u.str.str, 1); JS_FreeValue(s->ctx, cooked.u.str.str); if (ret) return -1; if (depth == 0) { if (s->token.u.str.sep == '`') goto done1; emit_op(s, OP_get_field2); emit_atom(s, JS_ATOM_concat); } depth++; } else { JS_FreeValue(s->ctx, cooked.u.str.str); } } if (s->token.u.str.sep == '`') goto done; if (next_token(s)) return -1; if (js_parse_expr(s)) return -1; depth++; if (s->token.val != '}') { return js_parse_error(s, "expected '}' after template expression"); } /* XXX: should convert to string at this stage? */ free_token(s, &s->token); /* Resume TOK_TEMPLATE parsing (s->token.line_num and * s->token.ptr are OK) */ s->got_lf = FALSE; if (js_parse_template_part(s, s->buf_ptr)) return -1; } return js_parse_expect(s, TOK_TEMPLATE); done: if (call) { /* Seal the objects */ seal_template_obj(ctx, raw_array); seal_template_obj(ctx, template_object); *argc = depth + 1; } else { emit_op(s, OP_call_method); emit_u16(s, depth - 1); } done1: return next_token(s); } #define PROP_TYPE_IDENT 0 #define PROP_TYPE_VAR 1 #define PROP_TYPE_GET 2 #define PROP_TYPE_SET 3 #define PROP_TYPE_STAR 4 #define PROP_TYPE_ASYNC 5 #define PROP_TYPE_ASYNC_STAR 6 #define PROP_TYPE_PRIVATE (1 << 4) static BOOL token_is_ident(int tok) { /* Accept keywords and reserved words as property names */ return (tok == TOK_IDENT || (tok >= TOK_FIRST_KEYWORD && tok <= TOK_LAST_KEYWORD)); } /* if the property is an expression, name = JS_ATOM_NULL */ static int __exception js_parse_property_name(JSParseState *s, JSAtom *pname, BOOL allow_method, BOOL allow_var, BOOL allow_private) { int is_private = 0; BOOL is_non_reserved_ident; JSAtom name; int prop_type; prop_type = PROP_TYPE_IDENT; if (allow_method) { /* if allow_private is true (for class field parsing) and get/set is following by ';' (or LF with ASI), then it is a field name */ if ((token_is_pseudo_keyword(s, JS_ATOM_get) || token_is_pseudo_keyword(s, JS_ATOM_set)) && (!allow_private || peek_token(s, TRUE) != '\n')) { /* get x(), set x() */ name = JS_DupAtom(s->ctx, s->token.u.ident.atom); if (next_token(s)) goto fail1; if (s->token.val == ':' || s->token.val == ',' || s->token.val == '}' || s->token.val == '(' || s->token.val == '=' || (s->token.val == ';' && allow_private)) { is_non_reserved_ident = TRUE; goto ident_found; } prop_type = PROP_TYPE_GET + (name == JS_ATOM_set); JS_FreeAtom(s->ctx, name); } else if (s->token.val == '*') { if (next_token(s)) goto fail; prop_type = PROP_TYPE_STAR; } else if (token_is_pseudo_keyword(s, JS_ATOM_async) && peek_token(s, TRUE) != '\n') { name = JS_DupAtom(s->ctx, s->token.u.ident.atom); if (next_token(s)) goto fail1; if (s->token.val == ':' || s->token.val == ',' || s->token.val == '}' || s->token.val == '(' || s->token.val == '=') { is_non_reserved_ident = TRUE; goto ident_found; } JS_FreeAtom(s->ctx, name); if (s->token.val == '*') { if (next_token(s)) goto fail; prop_type = PROP_TYPE_ASYNC_STAR; } else { prop_type = PROP_TYPE_ASYNC; } } } if (token_is_ident(s->token.val)) { /* variable can only be a non-reserved identifier */ is_non_reserved_ident = (s->token.val == TOK_IDENT && !s->token.u.ident.is_reserved); /* keywords and reserved words have a valid atom */ name = JS_DupAtom(s->ctx, s->token.u.ident.atom); if (next_token(s)) goto fail1; ident_found: if (is_non_reserved_ident && prop_type == PROP_TYPE_IDENT && allow_var) { if (!(s->token.val == ':' || (s->token.val == '(' && allow_method))) { prop_type = PROP_TYPE_VAR; } } } else if (s->token.val == TOK_STRING) { name = JS_ValueToAtom(s->ctx, s->token.u.str.str); if (name == JS_ATOM_NULL) goto fail; if (next_token(s)) goto fail1; } else if (s->token.val == TOK_NUMBER) { JSValue val; val = s->token.u.num.val; name = JS_ValueToAtom(s->ctx, val); if (name == JS_ATOM_NULL) goto fail; if (next_token(s)) goto fail1; } else if (s->token.val == '[') { if (next_token(s)) goto fail; if (js_parse_assign_expr(s)) goto fail; if (js_parse_expect(s, ']')) goto fail; name = JS_ATOM_NULL; } else if (s->token.val == TOK_PRIVATE_NAME && allow_private) { name = JS_DupAtom(s->ctx, s->token.u.ident.atom); if (next_token(s)) goto fail1; is_private = PROP_TYPE_PRIVATE; } else { goto invalid_prop; } if (prop_type != PROP_TYPE_IDENT && prop_type != PROP_TYPE_VAR && s->token.val != '(') { JS_FreeAtom(s->ctx, name); invalid_prop: js_parse_error(s, "invalid property name"); goto fail; } *pname = name; return prop_type | is_private; fail1: JS_FreeAtom(s->ctx, name); fail: *pname = JS_ATOM_NULL; return -1; } typedef struct JSParsePos { BOOL got_lf; const uint8_t *ptr; } JSParsePos; static int js_parse_get_pos(JSParseState *s, JSParsePos *sp) { sp->ptr = s->token.ptr; sp->got_lf = s->got_lf; return 0; } static __exception int js_parse_seek_token(JSParseState *s, const JSParsePos *sp) { s->buf_ptr = sp->ptr; s->got_lf = sp->got_lf; return next_token(s); } /* return TRUE if a regexp literal is allowed after this token */ static BOOL is_regexp_allowed(int tok) { switch (tok) { case TOK_NUMBER: case TOK_STRING: case TOK_REGEXP: case TOK_DEC: case TOK_INC: case TOK_NULL: case TOK_FALSE: case TOK_TRUE: case TOK_THIS: case ')': case ']': case '}': /* XXX: regexp may occur after */ case TOK_IDENT: return FALSE; default: return TRUE; } } #define SKIP_HAS_SEMI (1 << 0) #define SKIP_HAS_ELLIPSIS (1 << 1) #define SKIP_HAS_ASSIGNMENT (1 << 2) static BOOL has_lf_in_range(const uint8_t *p1, const uint8_t *p2) { const uint8_t *tmp; if (p1 > p2) { tmp = p1; p1 = p2; p2 = tmp; } return (memchr(p1, '\n', p2 - p1) != NULL); } /* XXX: improve speed with early bailout */ /* XXX: no longer works if regexps are present. Could use previous regexp parsing heuristics to handle most cases */ static int js_parse_skip_parens_token(JSParseState *s, int *pbits, BOOL no_line_terminator) { char state[256]; size_t level = 0; JSParsePos pos; int last_tok, tok = TOK_EOF; int c, tok_len, bits = 0; const uint8_t *last_token_ptr; /* protect from underflow */ state[level++] = 0; js_parse_get_pos(s, &pos); last_tok = 0; for (;;) { switch(s->token.val) { case '(': case '[': case '{': if (level >= sizeof(state)) goto done; state[level++] = s->token.val; break; case ')': if (state[--level] != '(') goto done; break; case ']': if (state[--level] != '[') goto done; break; case '}': c = state[--level]; if (c == '`') { /* continue the parsing of the template */ free_token(s, &s->token); /* Resume TOK_TEMPLATE parsing (s->token.line_num and * s->token.ptr are OK) */ s->got_lf = FALSE; if (js_parse_template_part(s, s->buf_ptr)) goto done; goto handle_template; } else if (c != '{') { goto done; } break; case TOK_TEMPLATE: handle_template: if (s->token.u.str.sep != '`') { /* '${' inside the template : closing '}' and continue parsing the template */ if (level >= sizeof(state)) goto done; state[level++] = '`'; } break; case TOK_EOF: goto done; case ';': if (level == 2) { bits |= SKIP_HAS_SEMI; } break; case TOK_ELLIPSIS: if (level == 2) { bits |= SKIP_HAS_ELLIPSIS; } break; case '=': bits |= SKIP_HAS_ASSIGNMENT; break; case TOK_DIV_ASSIGN: tok_len = 2; goto parse_regexp; case '/': tok_len = 1; parse_regexp: if (is_regexp_allowed(last_tok)) { s->buf_ptr -= tok_len; if (js_parse_regexp(s)) { /* XXX: should clear the exception */ goto done; } } break; } /* last_tok is only used to recognize regexps */ if (s->token.val == TOK_IDENT && (token_is_pseudo_keyword(s, JS_ATOM_of) || token_is_pseudo_keyword(s, JS_ATOM_yield))) { last_tok = TOK_OF; } else { last_tok = s->token.val; } last_token_ptr = s->token.ptr; if (next_token(s)) { /* XXX: should clear the exception generated by next_token() */ break; } if (level <= 1) { tok = s->token.val; if (token_is_pseudo_keyword(s, JS_ATOM_of)) tok = TOK_OF; if (no_line_terminator && has_lf_in_range(last_token_ptr, s->token.ptr)) tok = '\n'; break; } } done: if (pbits) { *pbits = bits; } if (js_parse_seek_token(s, &pos)) return -1; return tok; } static void set_object_name(JSParseState *s, JSAtom name) { JSFunctionDef *fd = s->cur_func; int opcode; opcode = get_prev_opcode(fd); if (opcode == OP_set_name) { /* XXX: should free atom after OP_set_name? */ fd->byte_code.size = fd->last_opcode_pos; fd->last_opcode_pos = -1; emit_op(s, OP_set_name); emit_atom(s, name); } else if (opcode == OP_set_class_name) { int define_class_pos; JSAtom atom; define_class_pos = fd->last_opcode_pos + 1 - get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1); assert(fd->byte_code.buf[define_class_pos] == OP_define_class); /* for consistency we free the previous atom which is JS_ATOM_empty_string */ atom = get_u32(fd->byte_code.buf + define_class_pos + 1); JS_FreeAtom(s->ctx, atom); put_u32(fd->byte_code.buf + define_class_pos + 1, JS_DupAtom(s->ctx, name)); fd->last_opcode_pos = -1; } } static void set_object_name_computed(JSParseState *s) { JSFunctionDef *fd = s->cur_func; int opcode; opcode = get_prev_opcode(fd); if (opcode == OP_set_name) { /* XXX: should free atom after OP_set_name? */ fd->byte_code.size = fd->last_opcode_pos; fd->last_opcode_pos = -1; emit_op(s, OP_set_name_computed); } else if (opcode == OP_set_class_name) { int define_class_pos; define_class_pos = fd->last_opcode_pos + 1 - get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1); assert(fd->byte_code.buf[define_class_pos] == OP_define_class); fd->byte_code.buf[define_class_pos] = OP_define_class_computed; fd->last_opcode_pos = -1; } } static __exception int js_parse_object_literal(JSParseState *s) { JSAtom name = JS_ATOM_NULL; const uint8_t *start_ptr; int prop_type; BOOL has_proto; if (next_token(s)) goto fail; /* XXX: add an initial length that will be patched back */ emit_op(s, OP_object); has_proto = FALSE; while (s->token.val != '}') { /* specific case for getter/setter */ start_ptr = s->token.ptr; if (s->token.val == TOK_ELLIPSIS) { if (next_token(s)) return -1; if (js_parse_assign_expr(s)) return -1; emit_op(s, OP_null); /* dummy excludeList */ emit_op(s, OP_copy_data_properties); emit_u8(s, 2 | (1 << 2) | (0 << 5)); emit_op(s, OP_drop); /* pop excludeList */ emit_op(s, OP_drop); /* pop src object */ goto next; } prop_type = js_parse_property_name(s, &name, TRUE, TRUE, FALSE); if (prop_type < 0) goto fail; if (prop_type == PROP_TYPE_VAR) { /* shortcut for x: x */ emit_op(s, OP_scope_get_var); emit_atom(s, name); emit_u16(s, s->cur_func->scope_level); emit_op(s, OP_define_field); emit_atom(s, name); } else if (s->token.val == '(') { BOOL is_getset = (prop_type == PROP_TYPE_GET || prop_type == PROP_TYPE_SET); JSParseFunctionEnum func_type; JSFunctionKindEnum func_kind; int op_flags; func_kind = JS_FUNC_NORMAL; if (is_getset) { func_type = JS_PARSE_FUNC_GETTER + prop_type - PROP_TYPE_GET; } else { func_type = JS_PARSE_FUNC_METHOD; if (prop_type == PROP_TYPE_STAR) func_kind = JS_FUNC_GENERATOR; else if (prop_type == PROP_TYPE_ASYNC) func_kind = JS_FUNC_ASYNC; else if (prop_type == PROP_TYPE_ASYNC_STAR) func_kind = JS_FUNC_ASYNC_GENERATOR; } if (js_parse_function_decl(s, func_type, func_kind, JS_ATOM_NULL, start_ptr)) goto fail; if (name == JS_ATOM_NULL) { emit_op(s, OP_define_method_computed); } else { emit_op(s, OP_define_method); emit_atom(s, name); } if (is_getset) { op_flags = OP_DEFINE_METHOD_GETTER + prop_type - PROP_TYPE_GET; } else { op_flags = OP_DEFINE_METHOD_METHOD; } emit_u8(s, op_flags | OP_DEFINE_METHOD_ENUMERABLE); } else { if (name == JS_ATOM_NULL) { /* must be done before evaluating expr */ emit_op(s, OP_to_propkey); } if (js_parse_expect(s, ':')) goto fail; if (js_parse_assign_expr(s)) goto fail; if (name == JS_ATOM_NULL) { set_object_name_computed(s); emit_op(s, OP_define_array_el); emit_op(s, OP_drop); } else if (name == JS_ATOM___proto__) { if (has_proto) { js_parse_error(s, "duplicate __proto__ property name"); goto fail; } emit_op(s, OP_set_proto); has_proto = TRUE; } else { set_object_name(s, name); emit_op(s, OP_define_field); emit_atom(s, name); } } JS_FreeAtom(s->ctx, name); next: name = JS_ATOM_NULL; if (s->token.val != ',') break; if (next_token(s)) goto fail; } if (js_parse_expect(s, '}')) goto fail; return 0; fail: JS_FreeAtom(s->ctx, name); return -1; } /* allow the 'in' binary operator */ #define PF_IN_ACCEPTED (1 << 0) /* allow function calls parsing in js_parse_postfix_expr() */ #define PF_POSTFIX_CALL (1 << 1) /* allow the exponentiation operator in js_parse_unary() */ #define PF_POW_ALLOWED (1 << 2) /* forbid the exponentiation operator in js_parse_unary() */ #define PF_POW_FORBIDDEN (1 << 3) static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags); static void emit_class_field_init(JSParseState *s); static JSFunctionDef *js_new_function_def(JSContext *ctx, JSFunctionDef *parent, BOOL is_eval, BOOL is_func_expr, const char *filename, const uint8_t *source_ptr, GetLineColCache *get_line_col_cache); static void emit_return(JSParseState *s, BOOL hasval); static __exception int js_parse_left_hand_side_expr(JSParseState *s) { return js_parse_postfix_expr(s, PF_POSTFIX_CALL); } static __exception int js_parse_class_default_ctor(JSParseState *s, BOOL has_super, JSFunctionDef **pfd) { JSParseFunctionEnum func_type; JSFunctionDef *fd = s->cur_func; int idx; fd = js_new_function_def(s->ctx, fd, FALSE, FALSE, s->filename, s->token.ptr, &s->get_line_col_cache); if (!fd) return -1; s->cur_func = fd; fd->has_home_object = TRUE; fd->super_allowed = TRUE; fd->has_prototype = FALSE; fd->has_this_binding = TRUE; fd->new_target_allowed = TRUE; push_scope(s); /* enter body scope */ fd->body_scope = fd->scope_level; if (has_super) { fd->is_derived_class_constructor = TRUE; fd->super_call_allowed = TRUE; fd->arguments_allowed = TRUE; fd->has_arguments_binding = TRUE; func_type = JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR; emit_op(s, OP_init_ctor); // TODO(bnoordhuis) roll into OP_init_ctor emit_op(s, OP_scope_put_var_init); emit_atom(s, JS_ATOM_this); emit_u16(s, 0); emit_class_field_init(s); } else { func_type = JS_PARSE_FUNC_CLASS_CONSTRUCTOR; /* error if not invoked as a constructor */ emit_op(s, OP_check_ctor); emit_class_field_init(s); } fd->func_kind = JS_FUNC_NORMAL; fd->func_type = func_type; emit_return(s, FALSE); s->cur_func = fd->parent; if (pfd) *pfd = fd; /* the real object will be set at the end of the compilation */ idx = cpool_add(s, JS_NULL); fd->parent_cpool_idx = idx; return 0; } /* find field in the current scope */ static int find_private_class_field(JSContext *ctx, JSFunctionDef *fd, JSAtom name, int scope_level) { int idx; idx = fd->scopes[scope_level].first; while (idx != -1) { if (fd->vars[idx].scope_level != scope_level) break; if (fd->vars[idx].var_name == name) return idx; idx = fd->vars[idx].scope_next; } return -1; } /* initialize the class fields, called by the constructor. Note: super() can be called in an arrow function, so <this> and <class_fields_init> can be variable references */ static void emit_class_field_init(JSParseState *s) { int label_next; emit_op(s, OP_scope_get_var); emit_atom(s, JS_ATOM_class_fields_init); emit_u16(s, s->cur_func->scope_level); /* no need to call the class field initializer if not defined */ emit_op(s, OP_dup); label_next = emit_goto(s, OP_if_false, -1); emit_op(s, OP_scope_get_var); emit_atom(s, JS_ATOM_this); emit_u16(s, 0); emit_op(s, OP_swap); emit_op(s, OP_call_method); emit_u16(s, 0); emit_label(s, label_next); emit_op(s, OP_drop); } /* build a private setter function name from the private getter name */ static JSAtom get_private_setter_name(JSContext *ctx, JSAtom name) { return js_atom_concat_str(ctx, name, "<set>"); } typedef struct { JSFunctionDef *fields_init_fd; int computed_fields_count; BOOL need_brand; int brand_push_pos; BOOL is_static; } ClassFieldsDef; static __exception int emit_class_init_start(JSParseState *s, ClassFieldsDef *cf) { int label_add_brand; cf->fields_init_fd = js_parse_function_class_fields_init(s); if (!cf->fields_init_fd) return -1; s->cur_func = cf->fields_init_fd; if (!cf->is_static) { /* add the brand to the newly created instance */ /* XXX: would be better to add the code only if needed, maybe in a later pass */ emit_op(s, OP_push_false); /* will be patched later */ cf->brand_push_pos = cf->fields_init_fd->last_opcode_pos; label_add_brand = emit_goto(s, OP_if_false, -1); emit_op(s, OP_scope_get_var); emit_atom(s, JS_ATOM_this); emit_u16(s, 0); emit_op(s, OP_scope_get_var); emit_atom(s, JS_ATOM_home_object); emit_u16(s, 0); emit_op(s, OP_add_brand); emit_label(s, label_add_brand); } s->cur_func = s->cur_func->parent; return 0; } static void emit_class_init_end(JSParseState *s, ClassFieldsDef *cf) { int cpool_idx; s->cur_func = cf->fields_init_fd; emit_op(s, OP_return_undef); s->cur_func = s->cur_func->parent; cpool_idx = cpool_add(s, JS_NULL); cf->fields_init_fd->parent_cpool_idx = cpool_idx; emit_op(s, OP_fclosure); emit_u32(s, cpool_idx); emit_op(s, OP_set_home_object); } static __exception int js_parse_class(JSParseState *s, BOOL is_class_expr, JSParseExportEnum export_flag) { JSContext *ctx = s->ctx; JSFunctionDef *fd = s->cur_func; JSAtom name = JS_ATOM_NULL, class_name = JS_ATOM_NULL, class_name1; JSAtom class_var_name = JS_ATOM_NULL; JSFunctionDef *method_fd, *ctor_fd; int saved_js_mode, class_name_var_idx, prop_type, ctor_cpool_offset; int class_flags = 0, i, define_class_offset; BOOL is_static, is_private; const uint8_t *class_start_ptr = s->token.ptr; const uint8_t *start_ptr; ClassFieldsDef class_fields[2]; /* classes are parsed and executed in strict mode */ saved_js_mode = fd->js_mode; fd->js_mode |= JS_MODE_STRICT; if (next_token(s)) goto fail; if (s->token.val == TOK_IDENT) { if (s->token.u.ident.is_reserved) { js_parse_error_reserved_identifier(s); goto fail; } class_name = JS_DupAtom(ctx, s->token.u.ident.atom); if (next_token(s)) goto fail; } else if (!is_class_expr && export_flag != JS_PARSE_EXPORT_DEFAULT) { js_parse_error(s, "class statement requires a name"); goto fail; } if (!is_class_expr) { if (class_name == JS_ATOM_NULL) class_var_name = JS_ATOM__default_; /* export default */ else class_var_name = class_name; class_var_name = JS_DupAtom(ctx, class_var_name); } push_scope(s); if (s->token.val == TOK_EXTENDS) { class_flags = JS_DEFINE_CLASS_HAS_HERITAGE; if (next_token(s)) goto fail; if (js_parse_left_hand_side_expr(s)) goto fail; } else { emit_op(s, OP_undefined); } /* add a 'const' definition for the class name */ if (class_name != JS_ATOM_NULL) { class_name_var_idx = define_var(s, fd, class_name, JS_VAR_DEF_CONST); if (class_name_var_idx < 0) goto fail; } if (js_parse_expect(s, '{')) goto fail; /* this scope contains the private fields */ push_scope(s); emit_op(s, OP_push_const); ctor_cpool_offset = fd->byte_code.size; emit_u32(s, 0); /* will be patched at the end of the class parsing */ if (class_name == JS_ATOM_NULL) { if (class_var_name != JS_ATOM_NULL) class_name1 = JS_ATOM_default; else class_name1 = JS_ATOM_empty_string; } else { class_name1 = class_name; } emit_op(s, OP_define_class); emit_atom(s, class_name1); emit_u8(s, class_flags); define_class_offset = fd->last_opcode_pos; for(i = 0; i < 2; i++) { ClassFieldsDef *cf = &class_fields[i]; cf->fields_init_fd = NULL; cf->computed_fields_count = 0; cf->need_brand = FALSE; cf->is_static = i; } ctor_fd = NULL; while (s->token.val != '}') { if (s->token.val == ';') { if (next_token(s)) goto fail; continue; } is_static = FALSE; if (s->token.val == TOK_STATIC) { int next = peek_token(s, TRUE); if (!(next == ';' || next == '}' || next == '(' || next == '=')) is_static = TRUE; } prop_type = -1; if (is_static) { if (next_token(s)) goto fail; if (s->token.val == '{') { ClassFieldsDef *cf = &class_fields[is_static]; JSFunctionDef *init; if (!cf->fields_init_fd) { if (emit_class_init_start(s, cf)) goto fail; } s->cur_func = cf->fields_init_fd; /* XXX: could try to avoid creating a new function and reuse 'fields_init_fd' with a specific 'var' scope */ // stack is now: <empty> if (js_parse_function_decl2(s, JS_PARSE_FUNC_CLASS_STATIC_INIT, JS_FUNC_NORMAL, JS_ATOM_NULL, s->token.ptr, JS_PARSE_EXPORT_NONE, &init) < 0) { goto fail; } // stack is now: fclosure push_scope(s); emit_op(s, OP_scope_get_var); emit_atom(s, JS_ATOM_this); emit_u16(s, 0); // stack is now: fclosure this emit_op(s, OP_swap); // stack is now: this fclosure emit_op(s, OP_call_method); emit_u16(s, 0); // stack is now: returnvalue emit_op(s, OP_drop); // stack is now: <empty> pop_scope(s); s->cur_func = s->cur_func->parent; continue; } /* allow "static" field name */ if (s->token.val == ';' || s->token.val == '=') { is_static = FALSE; name = JS_DupAtom(ctx, JS_ATOM_static); prop_type = PROP_TYPE_IDENT; } } if (is_static) emit_op(s, OP_swap); start_ptr = s->token.ptr; if (prop_type < 0) { prop_type = js_parse_property_name(s, &name, TRUE, FALSE, TRUE); if (prop_type < 0) goto fail; } is_private = prop_type & PROP_TYPE_PRIVATE; prop_type &= ~PROP_TYPE_PRIVATE; if ((name == JS_ATOM_constructor && !is_static && prop_type != PROP_TYPE_IDENT) || (name == JS_ATOM_prototype && is_static) || name == JS_ATOM_hash_constructor) { js_parse_error(s, "invalid method name"); goto fail; } if (prop_type == PROP_TYPE_GET || prop_type == PROP_TYPE_SET) { BOOL is_set = prop_type - PROP_TYPE_GET; JSFunctionDef *method_fd; if (is_private) { int idx, var_kind, is_static1; idx = find_private_class_field(ctx, fd, name, fd->scope_level); if (idx >= 0) { var_kind = fd->vars[idx].var_kind; is_static1 = fd->vars[idx].is_static_private; if (var_kind == JS_VAR_PRIVATE_FIELD || var_kind == JS_VAR_PRIVATE_METHOD || var_kind == JS_VAR_PRIVATE_GETTER_SETTER || var_kind == (JS_VAR_PRIVATE_GETTER + is_set) || (var_kind == (JS_VAR_PRIVATE_GETTER + 1 - is_set) && is_static != is_static1)) { goto private_field_already_defined; } fd->vars[idx].var_kind = JS_VAR_PRIVATE_GETTER_SETTER; } else { if (add_private_class_field(s, fd, name, JS_VAR_PRIVATE_GETTER + is_set, is_static) < 0) goto fail; } class_fields[is_static].need_brand = TRUE; } if (js_parse_function_decl2(s, JS_PARSE_FUNC_GETTER + is_set, JS_FUNC_NORMAL, JS_ATOM_NULL, start_ptr, JS_PARSE_EXPORT_NONE, &method_fd)) goto fail; if (is_private) { method_fd->need_home_object = TRUE; /* needed for brand check */ emit_op(s, OP_set_home_object); /* XXX: missing function name */ emit_op(s, OP_scope_put_var_init); if (is_set) { JSAtom setter_name; int ret; setter_name = get_private_setter_name(ctx, name); if (setter_name == JS_ATOM_NULL) goto fail; emit_atom(s, setter_name); ret = add_private_class_field(s, fd, setter_name, JS_VAR_PRIVATE_SETTER, is_static); JS_FreeAtom(ctx, setter_name); if (ret < 0) goto fail; } else { emit_atom(s, name); } emit_u16(s, s->cur_func->scope_level); } else { if (name == JS_ATOM_NULL) { emit_op(s, OP_define_method_computed); } else { emit_op(s, OP_define_method); emit_atom(s, name); } emit_u8(s, OP_DEFINE_METHOD_GETTER + is_set); } } else if (prop_type == PROP_TYPE_IDENT && s->token.val != '(') { ClassFieldsDef *cf = &class_fields[is_static]; JSAtom field_var_name = JS_ATOM_NULL; /* class field */ /* XXX: spec: not consistent with method name checks */ if (name == JS_ATOM_constructor || name == JS_ATOM_prototype) { js_parse_error(s, "invalid field name"); goto fail; } if (is_private) { if (find_private_class_field(ctx, fd, name, fd->scope_level) >= 0) { goto private_field_already_defined; } if (add_private_class_field(s, fd, name, JS_VAR_PRIVATE_FIELD, is_static) < 0) goto fail; emit_op(s, OP_private_symbol); emit_atom(s, name); emit_op(s, OP_scope_put_var_init); emit_atom(s, name); emit_u16(s, s->cur_func->scope_level); } if (!cf->fields_init_fd) { if (emit_class_init_start(s, cf)) goto fail; } if (name == JS_ATOM_NULL ) { /* save the computed field name into a variable */ field_var_name = js_atom_concat_num(ctx, JS_ATOM_computed_field + is_static, cf->computed_fields_count); if (field_var_name == JS_ATOM_NULL) goto fail; if (define_var(s, fd, field_var_name, JS_VAR_DEF_CONST) < 0) { JS_FreeAtom(ctx, field_var_name); goto fail; } emit_op(s, OP_to_propkey); emit_op(s, OP_scope_put_var_init); emit_atom(s, field_var_name); emit_u16(s, s->cur_func->scope_level); } s->cur_func = cf->fields_init_fd; emit_op(s, OP_scope_get_var); emit_atom(s, JS_ATOM_this); emit_u16(s, 0); if (name == JS_ATOM_NULL) { emit_op(s, OP_scope_get_var); emit_atom(s, field_var_name); emit_u16(s, s->cur_func->scope_level); cf->computed_fields_count++; JS_FreeAtom(ctx, field_var_name); } else if (is_private) { emit_op(s, OP_scope_get_var); emit_atom(s, name); emit_u16(s, s->cur_func->scope_level); } if (s->token.val == '=') { if (next_token(s)) goto fail; if (js_parse_assign_expr(s)) goto fail; } else { emit_op(s, OP_undefined); } if (is_private) { set_object_name_computed(s); emit_op(s, OP_define_private_field); } else if (name == JS_ATOM_NULL) { set_object_name_computed(s); emit_op(s, OP_define_array_el); emit_op(s, OP_drop); } else { set_object_name(s, name); emit_op(s, OP_define_field); emit_atom(s, name); } s->cur_func = s->cur_func->parent; if (js_parse_expect_semi(s)) goto fail; } else { JSParseFunctionEnum func_type; JSFunctionKindEnum func_kind; func_type = JS_PARSE_FUNC_METHOD; func_kind = JS_FUNC_NORMAL; if (prop_type == PROP_TYPE_STAR) { func_kind = JS_FUNC_GENERATOR; } else if (prop_type == PROP_TYPE_ASYNC) { func_kind = JS_FUNC_ASYNC; } else if (prop_type == PROP_TYPE_ASYNC_STAR) { func_kind = JS_FUNC_ASYNC_GENERATOR; } else if (name == JS_ATOM_constructor && !is_static) { if (ctor_fd) { js_parse_error(s, "property constructor appears more than once"); goto fail; } if (class_flags & JS_DEFINE_CLASS_HAS_HERITAGE) func_type = JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR; else func_type = JS_PARSE_FUNC_CLASS_CONSTRUCTOR; } if (is_private) { class_fields[is_static].need_brand = TRUE; } if (js_parse_function_decl2(s, func_type, func_kind, JS_ATOM_NULL, start_ptr, JS_PARSE_EXPORT_NONE, &method_fd)) goto fail; if (func_type == JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR || func_type == JS_PARSE_FUNC_CLASS_CONSTRUCTOR) { ctor_fd = method_fd; } else if (is_private) { method_fd->need_home_object = TRUE; /* needed for brand check */ if (find_private_class_field(ctx, fd, name, fd->scope_level) >= 0) { private_field_already_defined: js_parse_error(s, "private class field is already defined"); goto fail; } if (add_private_class_field(s, fd, name, JS_VAR_PRIVATE_METHOD, is_static) < 0) goto fail; emit_op(s, OP_set_home_object); emit_op(s, OP_set_name); emit_atom(s, name); emit_op(s, OP_scope_put_var_init); emit_atom(s, name); emit_u16(s, s->cur_func->scope_level); } else { if (name == JS_ATOM_NULL) { emit_op(s, OP_define_method_computed); } else { emit_op(s, OP_define_method); emit_atom(s, name); } emit_u8(s, OP_DEFINE_METHOD_METHOD); } } if (is_static) emit_op(s, OP_swap); JS_FreeAtom(ctx, name); name = JS_ATOM_NULL; } if (s->token.val != '}') { js_parse_error(s, "expecting '%c'", '}'); goto fail; } if (!ctor_fd) { if (js_parse_class_default_ctor(s, class_flags & JS_DEFINE_CLASS_HAS_HERITAGE, &ctor_fd)) goto fail; } /* patch the constant pool index for the constructor */ put_u32(fd->byte_code.buf + ctor_cpool_offset, ctor_fd->parent_cpool_idx); /* store the class source code in the constructor. */ if (!fd->strip_source) { js_free(ctx, ctor_fd->source); ctor_fd->source_len = s->buf_ptr - class_start_ptr; ctor_fd->source = js_strndup(ctx, (const char *)class_start_ptr, ctor_fd->source_len); if (!ctor_fd->source) goto fail; } /* consume the '}' */ if (next_token(s)) goto fail; { ClassFieldsDef *cf = &class_fields[0]; int var_idx; if (cf->need_brand) { /* add a private brand to the prototype */ emit_op(s, OP_dup); emit_op(s, OP_null); emit_op(s, OP_swap); emit_op(s, OP_add_brand); /* define the brand field in 'this' of the initializer */ if (!cf->fields_init_fd) { if (emit_class_init_start(s, cf)) goto fail; } /* patch the start of the function to enable the OP_add_brand_instance code */ cf->fields_init_fd->byte_code.buf[cf->brand_push_pos] = OP_push_true; } /* store the function to initialize the fields to that it can be referenced by the constructor */ var_idx = define_var(s, fd, JS_ATOM_class_fields_init, JS_VAR_DEF_CONST); if (var_idx < 0) goto fail; if (cf->fields_init_fd) { emit_class_init_end(s, cf); } else { emit_op(s, OP_undefined); } emit_op(s, OP_scope_put_var_init); emit_atom(s, JS_ATOM_class_fields_init); emit_u16(s, s->cur_func->scope_level); } /* drop the prototype */ emit_op(s, OP_drop); if (class_fields[1].need_brand) { /* add a private brand to the class */ emit_op(s, OP_dup); emit_op(s, OP_dup); emit_op(s, OP_add_brand); } if (class_name != JS_ATOM_NULL) { /* store the class name in the scoped class name variable (it is independent from the class statement variable definition) */ emit_op(s, OP_dup); emit_op(s, OP_scope_put_var_init); emit_atom(s, class_name); emit_u16(s, fd->scope_level); } /* initialize the static fields */ if (class_fields[1].fields_init_fd != NULL) { ClassFieldsDef *cf = &class_fields[1]; emit_op(s, OP_dup); emit_class_init_end(s, cf); emit_op(s, OP_call_method); emit_u16(s, 0); emit_op(s, OP_drop); } pop_scope(s); pop_scope(s); /* the class statements have a block level scope */ if (class_var_name != JS_ATOM_NULL) { if (define_var(s, fd, class_var_name, JS_VAR_DEF_LET) < 0) goto fail; emit_op(s, OP_scope_put_var_init); emit_atom(s, class_var_name); emit_u16(s, fd->scope_level); } else { if (class_name == JS_ATOM_NULL) { /* cannot use OP_set_name because the name of the class must be defined before the static initializers are executed */ emit_op(s, OP_set_class_name); emit_u32(s, fd->last_opcode_pos + 1 - define_class_offset); } } if (export_flag != JS_PARSE_EXPORT_NONE) { if (!add_export_entry(s, fd->module, class_var_name, export_flag == JS_PARSE_EXPORT_NAMED ? class_var_name : JS_ATOM_default, JS_EXPORT_TYPE_LOCAL)) goto fail; } JS_FreeAtom(ctx, class_name); JS_FreeAtom(ctx, class_var_name); fd->js_mode = saved_js_mode; return 0; fail: JS_FreeAtom(ctx, name); JS_FreeAtom(ctx, class_name); JS_FreeAtom(ctx, class_var_name); fd->js_mode = saved_js_mode; return -1; } static __exception int js_parse_array_literal(JSParseState *s) { uint32_t idx; BOOL need_length; if (next_token(s)) return -1; /* small regular arrays are created on the stack */ idx = 0; while (s->token.val != ']' && idx < 32) { if (s->token.val == ',' || s->token.val == TOK_ELLIPSIS) break; if (js_parse_assign_expr(s)) return -1; idx++; /* accept trailing comma */ if (s->token.val == ',') { if (next_token(s)) return -1; } else if (s->token.val != ']') goto done; } emit_op(s, OP_array_from); emit_u16(s, idx); /* larger arrays and holes are handled with explicit indices */ need_length = FALSE; while (s->token.val != ']' && idx < 0x7fffffff) { if (s->token.val == TOK_ELLIPSIS) break; need_length = TRUE; if (s->token.val != ',') { if (js_parse_assign_expr(s)) return -1; emit_op(s, OP_define_field); emit_u32(s, __JS_AtomFromUInt32(idx)); need_length = FALSE; } idx++; /* accept trailing comma */ if (s->token.val == ',') { if (next_token(s)) return -1; } } if (s->token.val == ']') { if (need_length) { /* Set the length: Cannot use OP_define_field because length is not configurable */ emit_op(s, OP_dup); emit_op(s, OP_push_i32); emit_u32(s, idx); emit_op(s, OP_put_field); emit_atom(s, JS_ATOM_length); } goto done; } /* huge arrays and spread elements require a dynamic index on the stack */ emit_op(s, OP_push_i32); emit_u32(s, idx); /* stack has array, index */ while (s->token.val != ']') { if (s->token.val == TOK_ELLIPSIS) { if (next_token(s)) return -1; if (js_parse_assign_expr(s)) return -1; #if 1 emit_op(s, OP_append); #else int label_next, label_done; label_next = new_label(s); label_done = new_label(s); /* enumerate object */ emit_op(s, OP_for_of_start); emit_op(s, OP_rot5l); emit_op(s, OP_rot5l); emit_label(s, label_next); /* on stack: enum_rec array idx */ emit_op(s, OP_for_of_next); emit_u8(s, 2); emit_goto(s, OP_if_true, label_done); /* append element */ /* enum_rec array idx val -> enum_rec array new_idx */ emit_op(s, OP_define_array_el); emit_op(s, OP_inc); emit_goto(s, OP_goto, label_next); emit_label(s, label_done); /* close enumeration */ emit_op(s, OP_drop); /* drop undef val */ emit_op(s, OP_nip1); /* drop enum_rec */ emit_op(s, OP_nip1); emit_op(s, OP_nip1); #endif } else { need_length = TRUE; if (s->token.val != ',') { if (js_parse_assign_expr(s)) return -1; /* a idx val */ emit_op(s, OP_define_array_el); need_length = FALSE; } emit_op(s, OP_inc); } if (s->token.val != ',') break; if (next_token(s)) return -1; } if (need_length) { /* Set the length: cannot use OP_define_field because length is not configurable */ emit_op(s, OP_dup1); /* array length - array array length */ emit_op(s, OP_put_field); emit_atom(s, JS_ATOM_length); } else { emit_op(s, OP_drop); /* array length - array */ } done: return js_parse_expect(s, ']'); } /* check if scope chain contains a with statement */ static BOOL has_with_scope(JSFunctionDef *s, int scope_level) { while (s) { /* no with in strict mode */ if (!(s->js_mode & JS_MODE_STRICT)) { int scope_idx = s->scopes[scope_level].first; while (scope_idx >= 0) { JSVarDef *vd = &s->vars[scope_idx]; if (vd->var_name == JS_ATOM__with_) return TRUE; scope_idx = vd->scope_next; } } /* check parent scopes */ scope_level = s->parent_scope_level; s = s->parent; } return FALSE; } static __exception int get_lvalue(JSParseState *s, int *popcode, int *pscope, JSAtom *pname, int *plabel, int *pdepth, BOOL keep, int tok) { JSFunctionDef *fd; int opcode, scope, label, depth; JSAtom name; /* we check the last opcode to get the lvalue type */ fd = s->cur_func; scope = 0; name = JS_ATOM_NULL; label = -1; depth = 0; switch(opcode = get_prev_opcode(fd)) { case OP_scope_get_var: name = get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1); scope = get_u16(fd->byte_code.buf + fd->last_opcode_pos + 5); if ((name == JS_ATOM_arguments || name == JS_ATOM_eval) && (fd->js_mode & JS_MODE_STRICT)) { return js_parse_error(s, "invalid lvalue in strict mode"); } if (name == JS_ATOM_this || name == JS_ATOM_new_target) goto invalid_lvalue; if (has_with_scope(fd, scope)) { depth = 2; /* will generate OP_get_ref_value */ } else { depth = 0; } break; case OP_get_field: name = get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1); depth = 1; break; case OP_scope_get_private_field: name = get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1); scope = get_u16(fd->byte_code.buf + fd->last_opcode_pos + 5); depth = 1; break; case OP_get_array_el: depth = 2; break; case OP_get_super_value: depth = 3; break; default: invalid_lvalue: if (tok == TOK_FOR) { return js_parse_error(s, "invalid for in/of left hand-side"); } else if (tok == TOK_INC || tok == TOK_DEC) { return js_parse_error(s, "invalid increment/decrement operand"); } else if (tok == '[' || tok == '{') { return js_parse_error(s, "invalid destructuring target"); } else { return js_parse_error(s, "invalid assignment left-hand side"); } } /* remove the last opcode */ fd->byte_code.size = fd->last_opcode_pos; fd->last_opcode_pos = -1; if (keep) { /* get the value but keep the object/fields on the stack */ switch(opcode) { case OP_scope_get_var: if (depth != 0) { label = new_label(s); if (label < 0) return -1; emit_op(s, OP_scope_make_ref); emit_atom(s, name); emit_u32(s, label); emit_u16(s, scope); update_label(fd, label, 1); emit_op(s, OP_get_ref_value); opcode = OP_get_ref_value; } else { emit_op(s, OP_scope_get_var); emit_atom(s, name); emit_u16(s, scope); } break; case OP_get_field: emit_op(s, OP_get_field2); emit_atom(s, name); break; case OP_scope_get_private_field: emit_op(s, OP_scope_get_private_field2); emit_atom(s, name); emit_u16(s, scope); break; case OP_get_array_el: emit_op(s, OP_get_array_el3); break; case OP_get_super_value: emit_op(s, OP_to_propkey); emit_op(s, OP_dup3); emit_op(s, OP_get_super_value); break; default: abort(); } } else { switch(opcode) { case OP_scope_get_var: if (depth != 0) { label = new_label(s); if (label < 0) return -1; emit_op(s, OP_scope_make_ref); emit_atom(s, name); emit_u32(s, label); emit_u16(s, scope); update_label(fd, label, 1); opcode = OP_get_ref_value; } break; default: break; } } *popcode = opcode; *pscope = scope; /* name has refcount for OP_get_field and OP_get_ref_value, and JS_ATOM_NULL for other opcodes */ *pname = name; *plabel = label; if (pdepth) *pdepth = depth; return 0; } typedef enum { PUT_LVALUE_NOKEEP, /* [depth] v -> */ PUT_LVALUE_NOKEEP_DEPTH, /* [depth] v -> , keep depth (currently just disable optimizations) */ PUT_LVALUE_KEEP_TOP, /* [depth] v -> v */ PUT_LVALUE_KEEP_SECOND, /* [depth] v0 v -> v0 */ PUT_LVALUE_NOKEEP_BOTTOM, /* v [depth] -> */ } PutLValueEnum; /* name has a live reference. 'is_let' is only used with opcode = OP_scope_get_var which is never generated by get_lvalue(). */ static void put_lvalue(JSParseState *s, int opcode, int scope, JSAtom name, int label, PutLValueEnum special, BOOL is_let) { switch(opcode) { case OP_scope_get_var: /* depth = 0 */ switch(special) { case PUT_LVALUE_NOKEEP: case PUT_LVALUE_NOKEEP_DEPTH: case PUT_LVALUE_KEEP_SECOND: case PUT_LVALUE_NOKEEP_BOTTOM: break; case PUT_LVALUE_KEEP_TOP: emit_op(s, OP_dup); break; default: abort(); } break; case OP_get_field: case OP_scope_get_private_field: /* depth = 1 */ switch(special) { case PUT_LVALUE_NOKEEP: case PUT_LVALUE_NOKEEP_DEPTH: break; case PUT_LVALUE_KEEP_TOP: emit_op(s, OP_insert2); /* obj v -> v obj v */ break; case PUT_LVALUE_KEEP_SECOND: emit_op(s, OP_perm3); /* obj v0 v -> v0 obj v */ break; case PUT_LVALUE_NOKEEP_BOTTOM: emit_op(s, OP_swap); break; default: abort(); } break; case OP_get_array_el: case OP_get_ref_value: /* depth = 2 */ if (opcode == OP_get_ref_value) { JS_FreeAtom(s->ctx, name); emit_label(s, label); } switch(special) { case PUT_LVALUE_NOKEEP: emit_op(s, OP_nop); /* will trigger optimization */ break; case PUT_LVALUE_NOKEEP_DEPTH: break; case PUT_LVALUE_KEEP_TOP: emit_op(s, OP_insert3); /* obj prop v -> v obj prop v */ break; case PUT_LVALUE_KEEP_SECOND: emit_op(s, OP_perm4); /* obj prop v0 v -> v0 obj prop v */ break; case PUT_LVALUE_NOKEEP_BOTTOM: emit_op(s, OP_rot3l); break; default: abort(); } break; case OP_get_super_value: /* depth = 3 */ switch(special) { case PUT_LVALUE_NOKEEP: case PUT_LVALUE_NOKEEP_DEPTH: break; case PUT_LVALUE_KEEP_TOP: emit_op(s, OP_insert4); /* this obj prop v -> v this obj prop v */ break; case PUT_LVALUE_KEEP_SECOND: emit_op(s, OP_perm5); /* this obj prop v0 v -> v0 this obj prop v */ break; case PUT_LVALUE_NOKEEP_BOTTOM: emit_op(s, OP_rot4l); break; default: abort(); } break; default: break; } switch(opcode) { case OP_scope_get_var: /* val -- */ emit_op(s, is_let ? OP_scope_put_var_init : OP_scope_put_var); emit_u32(s, name); /* has refcount */ emit_u16(s, scope); break; case OP_get_field: emit_op(s, OP_put_field); emit_u32(s, name); /* name has refcount */ break; case OP_scope_get_private_field: emit_op(s, OP_scope_put_private_field); emit_u32(s, name); /* name has refcount */ emit_u16(s, scope); break; case OP_get_array_el: emit_op(s, OP_put_array_el); break; case OP_get_ref_value: emit_op(s, OP_put_ref_value); break; case OP_get_super_value: emit_op(s, OP_put_super_value); break; default: abort(); } } static __exception int js_parse_expr_paren(JSParseState *s) { if (js_parse_expect(s, '(')) return -1; if (js_parse_expr(s)) return -1; if (js_parse_expect(s, ')')) return -1; return 0; } static int js_unsupported_keyword(JSParseState *s, JSAtom atom) { char buf[ATOM_GET_STR_BUF_SIZE]; return js_parse_error(s, "unsupported keyword: %s", JS_AtomGetStr(s->ctx, buf, sizeof(buf), atom)); } static __exception int js_define_var(JSParseState *s, JSAtom name, int tok) { JSFunctionDef *fd = s->cur_func; JSVarDefEnum var_def_type; if (name == JS_ATOM_yield && fd->func_kind == JS_FUNC_GENERATOR) { return js_parse_error(s, "yield is a reserved identifier"); } if ((name == JS_ATOM_arguments || name == JS_ATOM_eval) && (fd->js_mode & JS_MODE_STRICT)) { return js_parse_error(s, "invalid variable name in strict mode"); } if (name == JS_ATOM_let && (tok == TOK_LET || tok == TOK_CONST)) { return js_parse_error(s, "invalid lexical variable name"); } switch(tok) { case TOK_LET: var_def_type = JS_VAR_DEF_LET; break; case TOK_CONST: var_def_type = JS_VAR_DEF_CONST; break; case TOK_VAR: var_def_type = JS_VAR_DEF_VAR; break; case TOK_CATCH: var_def_type = JS_VAR_DEF_CATCH; break; default: abort(); } if (define_var(s, fd, name, var_def_type) < 0) return -1; return 0; } static void js_emit_spread_code(JSParseState *s, int depth) { int label_rest_next, label_rest_done; /* XXX: could check if enum object is an actual array and optimize slice extraction. enumeration record and target array are in a different order from OP_append case. */ /* enum_rec xxx -- enum_rec xxx array 0 */ emit_op(s, OP_array_from); emit_u16(s, 0); emit_op(s, OP_push_i32); emit_u32(s, 0); emit_label(s, label_rest_next = new_label(s)); emit_op(s, OP_for_of_next); emit_u8(s, 2 + depth); label_rest_done = emit_goto(s, OP_if_true, -1); /* array idx val -- array idx */ emit_op(s, OP_define_array_el); emit_op(s, OP_inc); emit_goto(s, OP_goto, label_rest_next); emit_label(s, label_rest_done); /* enum_rec xxx array idx undef -- enum_rec xxx array */ emit_op(s, OP_drop); emit_op(s, OP_drop); } static int js_parse_check_duplicate_parameter(JSParseState *s, JSAtom name) { /* Check for duplicate parameter names */ JSFunctionDef *fd = s->cur_func; int i; for (i = 0; i < fd->arg_count; i++) { if (fd->args[i].var_name == name) goto duplicate; } for (i = 0; i < fd->var_count; i++) { if (fd->vars[i].var_name == name) goto duplicate; } return 0; duplicate: return js_parse_error(s, "duplicate parameter names not allowed in this context"); } /* tok = TOK_VAR, TOK_LET or TOK_CONST. Return whether a reference must be taken to the variable for proper 'with' or global variable evaluation */ /* Note: this function is needed only because variable references are not yet optimized in destructuring */ static BOOL need_var_reference(JSParseState *s, int tok) { JSFunctionDef *fd = s->cur_func; if (tok != TOK_VAR) return FALSE; /* no reference for let/const */ if (fd->js_mode & JS_MODE_STRICT) { if (!fd->is_global_var) return FALSE; /* local definitions in strict mode in function or direct eval */ if (s->is_module) return FALSE; /* in a module global variables are like closure variables */ } return TRUE; } static JSAtom js_parse_destructuring_var(JSParseState *s, int tok, int is_arg) { JSAtom name; if (!(s->token.val == TOK_IDENT && !s->token.u.ident.is_reserved) || ((s->cur_func->js_mode & JS_MODE_STRICT) && (s->token.u.ident.atom == JS_ATOM_eval || s->token.u.ident.atom == JS_ATOM_arguments))) { js_parse_error(s, "invalid destructuring target"); return JS_ATOM_NULL; } name = JS_DupAtom(s->ctx, s->token.u.ident.atom); if (is_arg && js_parse_check_duplicate_parameter(s, name)) goto fail; if (next_token(s)) goto fail; return name; fail: JS_FreeAtom(s->ctx, name); return JS_ATOM_NULL; } /* Return -1 if error, 0 if no initializer, 1 if an initializer is present at the top level. */ static int js_parse_destructuring_element(JSParseState *s, int tok, int is_arg, int hasval, int has_ellipsis, BOOL allow_initializer, BOOL export_flag) { int label_parse, label_assign, label_done, label_lvalue, depth_lvalue; int start_addr, assign_addr; JSAtom prop_name, var_name; int opcode, scope, tok1, skip_bits; BOOL has_initializer; if (has_ellipsis < 0) { /* pre-parse destructuration target for spread detection */ js_parse_skip_parens_token(s, &skip_bits, FALSE); has_ellipsis = skip_bits & SKIP_HAS_ELLIPSIS; } label_parse = new_label(s); label_assign = new_label(s); start_addr = s->cur_func->byte_code.size; if (hasval) { /* consume value from the stack */ emit_op(s, OP_dup); emit_op(s, OP_undefined); emit_op(s, OP_strict_eq); emit_goto(s, OP_if_true, label_parse); emit_label(s, label_assign); } else { emit_goto(s, OP_goto, label_parse); emit_label(s, label_assign); /* leave value on the stack */ emit_op(s, OP_dup); } assign_addr = s->cur_func->byte_code.size; if (s->token.val == '{') { if (next_token(s)) return -1; /* throw an exception if the value cannot be converted to an object */ emit_op(s, OP_to_object); if (has_ellipsis) { /* add excludeList on stack just below src object */ emit_op(s, OP_object); emit_op(s, OP_swap); } while (s->token.val != '}') { int prop_type; if (s->token.val == TOK_ELLIPSIS) { if (!has_ellipsis) { JS_ThrowInternalError(s->ctx, "unexpected ellipsis token"); return -1; } if (next_token(s)) return -1; if (tok) { var_name = js_parse_destructuring_var(s, tok, is_arg); if (var_name == JS_ATOM_NULL) return -1; if (need_var_reference(s, tok)) { /* Must make a reference for proper `with` semantics */ emit_op(s, OP_scope_get_var); emit_atom(s, var_name); emit_u16(s, s->cur_func->scope_level); JS_FreeAtom(s->ctx, var_name); goto lvalue0; } else { opcode = OP_scope_get_var; scope = s->cur_func->scope_level; label_lvalue = -1; depth_lvalue = 0; } } else { if (js_parse_left_hand_side_expr(s)) return -1; lvalue0: if (get_lvalue(s, &opcode, &scope, &var_name, &label_lvalue, &depth_lvalue, FALSE, '{')) return -1; } if (s->token.val != '}') { js_parse_error(s, "assignment rest property must be last"); goto var_error; } emit_op(s, OP_object); /* target */ emit_op(s, OP_copy_data_properties); emit_u8(s, 0 | ((depth_lvalue + 1) << 2) | ((depth_lvalue + 2) << 5)); goto set_val; } prop_type = js_parse_property_name(s, &prop_name, FALSE, TRUE, FALSE); if (prop_type < 0) return -1; var_name = JS_ATOM_NULL; if (prop_type == PROP_TYPE_IDENT) { if (next_token(s)) goto prop_error; if ((s->token.val == '[' || s->token.val == '{') && ((tok1 = js_parse_skip_parens_token(s, &skip_bits, FALSE)) == ',' || tok1 == '=' || tok1 == '}')) { if (prop_name == JS_ATOM_NULL) { /* computed property name on stack */ if (has_ellipsis) { /* define the property in excludeList */ emit_op(s, OP_to_propkey); /* avoid calling ToString twice */ emit_op(s, OP_perm3); /* TOS: src excludeList prop */ emit_op(s, OP_null); /* TOS: src excludeList prop null */ emit_op(s, OP_define_array_el); /* TOS: src excludeList prop */ emit_op(s, OP_perm3); /* TOS: excludeList src prop */ } /* get the computed property from the source object */ emit_op(s, OP_get_array_el2); } else { /* named property */ if (has_ellipsis) { /* define the property in excludeList */ emit_op(s, OP_swap); /* TOS: src excludeList */ emit_op(s, OP_null); /* TOS: src excludeList null */ emit_op(s, OP_define_field); /* TOS: src excludeList */ emit_atom(s, prop_name); emit_op(s, OP_swap); /* TOS: excludeList src */ } /* get the named property from the source object */ emit_op(s, OP_get_field2); emit_u32(s, prop_name); } if (js_parse_destructuring_element(s, tok, is_arg, TRUE, -1, TRUE, export_flag) < 0) return -1; if (s->token.val == '}') break; /* accept a trailing comma before the '}' */ if (js_parse_expect(s, ',')) return -1; continue; } if (prop_name == JS_ATOM_NULL) { emit_op(s, OP_to_propkey); if (has_ellipsis) { /* define the property in excludeList */ emit_op(s, OP_perm3); emit_op(s, OP_null); emit_op(s, OP_define_array_el); emit_op(s, OP_perm3); } /* source prop -- source source prop */ emit_op(s, OP_dup1); } else { if (has_ellipsis) { /* define the property in excludeList */ emit_op(s, OP_swap); emit_op(s, OP_null); emit_op(s, OP_define_field); emit_atom(s, prop_name); emit_op(s, OP_swap); } /* source -- source source */ emit_op(s, OP_dup); } if (tok) { var_name = js_parse_destructuring_var(s, tok, is_arg); if (var_name == JS_ATOM_NULL) goto prop_error; if (need_var_reference(s, tok)) { /* Must make a reference for proper `with` semantics */ emit_op(s, OP_scope_get_var); emit_atom(s, var_name); emit_u16(s, s->cur_func->scope_level); JS_FreeAtom(s->ctx, var_name); goto lvalue1; } else { /* no need to make a reference for let/const */ opcode = OP_scope_get_var; scope = s->cur_func->scope_level; label_lvalue = -1; depth_lvalue = 0; } } else { if (js_parse_left_hand_side_expr(s)) goto prop_error; lvalue1: if (get_lvalue(s, &opcode, &scope, &var_name, &label_lvalue, &depth_lvalue, FALSE, '{')) goto prop_error; /* swap ref and lvalue object if any */ if (prop_name == JS_ATOM_NULL) { switch(depth_lvalue) { case 0: break; case 1: /* source prop x -> x source prop */ emit_op(s, OP_rot3r); break; case 2: /* source prop x y -> x y source prop */ emit_op(s, OP_swap2); /* t p2 s p1 */ break; case 3: /* source prop x y z -> x y z source prop */ emit_op(s, OP_rot5l); emit_op(s, OP_rot5l); break; default: abort(); } } else { switch(depth_lvalue) { case 0: break; case 1: /* source x -> x source */ emit_op(s, OP_swap); break; case 2: /* source x y -> x y source */ emit_op(s, OP_rot3l); break; case 3: /* source x y z -> x y z source */ emit_op(s, OP_rot4l); break; default: abort(); } } } if (prop_name == JS_ATOM_NULL) { /* computed property name on stack */ /* XXX: should have OP_get_array_el2x with depth */ /* source prop -- val */ emit_op(s, OP_get_array_el); } else { /* named property */ /* XXX: should have OP_get_field2x with depth */ /* source -- val */ emit_op(s, OP_get_field); emit_u32(s, prop_name); } } else { /* prop_type = PROP_TYPE_VAR, cannot be a computed property */ if (is_arg && js_parse_check_duplicate_parameter(s, prop_name)) goto prop_error; if ((s->cur_func->js_mode & JS_MODE_STRICT) && (prop_name == JS_ATOM_eval || prop_name == JS_ATOM_arguments)) { js_parse_error(s, "invalid destructuring target"); goto prop_error; } if (has_ellipsis) { /* define the property in excludeList */ emit_op(s, OP_swap); emit_op(s, OP_null); emit_op(s, OP_define_field); emit_atom(s, prop_name); emit_op(s, OP_swap); } if (!tok || need_var_reference(s, tok)) { /* generate reference */ /* source -- source source */ emit_op(s, OP_dup); emit_op(s, OP_scope_get_var); emit_atom(s, prop_name); emit_u16(s, s->cur_func->scope_level); goto lvalue1; } else { /* no need to make a reference for let/const */ var_name = JS_DupAtom(s->ctx, prop_name); opcode = OP_scope_get_var; scope = s->cur_func->scope_level; label_lvalue = -1; depth_lvalue = 0; /* source -- source val */ emit_op(s, OP_get_field2); emit_u32(s, prop_name); } } set_val: if (tok) { if (js_define_var(s, var_name, tok)) goto var_error; if (export_flag) { if (!add_export_entry(s, s->cur_func->module, var_name, var_name, JS_EXPORT_TYPE_LOCAL)) goto var_error; } scope = s->cur_func->scope_level; /* XXX: check */ } if (s->token.val == '=') { /* handle optional default value */ int label_hasval; emit_op(s, OP_dup); emit_op(s, OP_undefined); emit_op(s, OP_strict_eq); label_hasval = emit_goto(s, OP_if_false, -1); if (next_token(s)) goto var_error; emit_op(s, OP_drop); if (js_parse_assign_expr(s)) goto var_error; if (opcode == OP_scope_get_var || opcode == OP_get_ref_value) set_object_name(s, var_name); emit_label(s, label_hasval); } /* store value into lvalue object */ put_lvalue(s, opcode, scope, var_name, label_lvalue, PUT_LVALUE_NOKEEP_DEPTH, (tok == TOK_CONST || tok == TOK_LET)); if (s->token.val == '}') break; /* accept a trailing comma before the '}' */ if (js_parse_expect(s, ',')) return -1; } /* drop the source object */ emit_op(s, OP_drop); if (has_ellipsis) { emit_op(s, OP_drop); /* pop excludeList */ } if (next_token(s)) return -1; } else if (s->token.val == '[') { BOOL has_spread; int enum_depth; BlockEnv block_env; if (next_token(s)) return -1; /* the block environment is only needed in generators in case 'yield' triggers a 'return' */ push_break_entry(s->cur_func, &block_env, JS_ATOM_NULL, -1, -1, 2); block_env.has_iterator = TRUE; emit_op(s, OP_for_of_start); has_spread = FALSE; while (s->token.val != ']') { /* get the next value */ if (s->token.val == TOK_ELLIPSIS) { if (next_token(s)) return -1; if (s->token.val == ',' || s->token.val == ']') return js_parse_error(s, "missing binding pattern..."); has_spread = TRUE; } if (s->token.val == ',') { /* do nothing, skip the value, has_spread is false */ emit_op(s, OP_for_of_next); emit_u8(s, 0); emit_op(s, OP_drop); emit_op(s, OP_drop); } else if ((s->token.val == '[' || s->token.val == '{') && ((tok1 = js_parse_skip_parens_token(s, &skip_bits, FALSE)) == ',' || tok1 == '=' || tok1 == ']')) { if (has_spread) { if (tok1 == '=') return js_parse_error(s, "rest element cannot have a default value"); js_emit_spread_code(s, 0); } else { emit_op(s, OP_for_of_next); emit_u8(s, 0); emit_op(s, OP_drop); } if (js_parse_destructuring_element(s, tok, is_arg, TRUE, skip_bits & SKIP_HAS_ELLIPSIS, TRUE, export_flag) < 0) return -1; } else { var_name = JS_ATOM_NULL; if (tok) { var_name = js_parse_destructuring_var(s, tok, is_arg); if (var_name == JS_ATOM_NULL) goto var_error; if (js_define_var(s, var_name, tok)) goto var_error; if (need_var_reference(s, tok)) { /* Must make a reference for proper `with` semantics */ emit_op(s, OP_scope_get_var); emit_atom(s, var_name); emit_u16(s, s->cur_func->scope_level); JS_FreeAtom(s->ctx, var_name); goto lvalue2; } else { /* no need to make a reference for let/const */ opcode = OP_scope_get_var; scope = s->cur_func->scope_level; label_lvalue = -1; enum_depth = 0; } } else { if (js_parse_left_hand_side_expr(s)) return -1; lvalue2: if (get_lvalue(s, &opcode, &scope, &var_name, &label_lvalue, &enum_depth, FALSE, '[')) { return -1; } } if (has_spread) { js_emit_spread_code(s, enum_depth); } else { emit_op(s, OP_for_of_next); emit_u8(s, enum_depth); emit_op(s, OP_drop); } if (s->token.val == '=' && !has_spread) { /* handle optional default value */ int label_hasval; emit_op(s, OP_dup); emit_op(s, OP_undefined); emit_op(s, OP_strict_eq); label_hasval = emit_goto(s, OP_if_false, -1); if (next_token(s)) goto var_error; emit_op(s, OP_drop); if (js_parse_assign_expr(s)) goto var_error; if (opcode == OP_scope_get_var || opcode == OP_get_ref_value) set_object_name(s, var_name); emit_label(s, label_hasval); } /* store value into lvalue object */ put_lvalue(s, opcode, scope, var_name, label_lvalue, PUT_LVALUE_NOKEEP_DEPTH, (tok == TOK_CONST || tok == TOK_LET)); } if (s->token.val == ']') break; if (has_spread) return js_parse_error(s, "rest element must be the last one"); /* accept a trailing comma before the ']' */ if (js_parse_expect(s, ',')) return -1; } /* close iterator object: if completed, enum_obj has been replaced by undefined */ emit_op(s, OP_iterator_close); pop_break_entry(s->cur_func); if (next_token(s)) return -1; } else { return js_parse_error(s, "invalid assignment syntax"); } if (s->token.val == '=' && allow_initializer) { label_done = emit_goto(s, OP_goto, -1); if (next_token(s)) return -1; emit_label(s, label_parse); if (hasval) emit_op(s, OP_drop); if (js_parse_assign_expr(s)) return -1; emit_goto(s, OP_goto, label_assign); emit_label(s, label_done); has_initializer = TRUE; } else { /* normally hasval is true except if js_parse_skip_parens_token() was wrong in the parsing */ // assert(hasval); if (!hasval) { js_parse_error(s, "too complicated destructuring expression"); return -1; } /* remove test and decrement label ref count */ memset(s->cur_func->byte_code.buf + start_addr, OP_nop, assign_addr - start_addr); s->cur_func->label_slots[label_parse].ref_count--; has_initializer = FALSE; } return has_initializer; prop_error: JS_FreeAtom(s->ctx, prop_name); var_error: JS_FreeAtom(s->ctx, var_name); return -1; } typedef enum FuncCallType { FUNC_CALL_NORMAL, FUNC_CALL_NEW, FUNC_CALL_SUPER_CTOR, FUNC_CALL_TEMPLATE, } FuncCallType; static void optional_chain_test(JSParseState *s, int *poptional_chaining_label, int drop_count) { int label_next, i; if (*poptional_chaining_label < 0) *poptional_chaining_label = new_label(s); /* XXX: could be more efficient with a specific opcode */ emit_op(s, OP_dup); emit_op(s, OP_is_undefined_or_null); label_next = emit_goto(s, OP_if_false, -1); for(i = 0; i < drop_count; i++) emit_op(s, OP_drop); emit_op(s, OP_undefined); emit_goto(s, OP_goto, *poptional_chaining_label); emit_label(s, label_next); } /* allowed parse_flags: PF_POSTFIX_CALL */ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags) { FuncCallType call_type; int optional_chaining_label; BOOL accept_lparen = (parse_flags & PF_POSTFIX_CALL) != 0; const uint8_t *op_token_ptr; call_type = FUNC_CALL_NORMAL; switch(s->token.val) { case TOK_NUMBER: { JSValue val; val = s->token.u.num.val; if (JS_VALUE_GET_TAG(val) == JS_TAG_INT) { emit_op(s, OP_push_i32); emit_u32(s, JS_VALUE_GET_INT(val)); } else if (JS_VALUE_GET_TAG(val) == JS_TAG_SHORT_BIG_INT) { int64_t v; v = JS_VALUE_GET_SHORT_BIG_INT(val); if (v >= INT32_MIN && v <= INT32_MAX) { emit_op(s, OP_push_bigint_i32); emit_u32(s, v); } else { goto large_number; } } else { large_number: if (emit_push_const(s, val, 0) < 0) return -1; } } if (next_token(s)) return -1; break; case TOK_TEMPLATE: if (js_parse_template(s, 0, NULL)) return -1; break; case TOK_STRING: if (emit_push_const(s, s->token.u.str.str, 1)) return -1; if (next_token(s)) return -1; break; case TOK_DIV_ASSIGN: s->buf_ptr -= 2; goto parse_regexp; case '/': s->buf_ptr--; parse_regexp: { JSValue str; int ret; if (!s->ctx->compile_regexp) return js_parse_error(s, "RegExp are not supported"); /* the previous token is '/' or '/=', so no need to free */ if (js_parse_regexp(s)) return -1; ret = emit_push_const(s, s->token.u.regexp.body, 0); str = s->ctx->compile_regexp(s->ctx, s->token.u.regexp.body, s->token.u.regexp.flags); if (JS_IsException(str)) { /* add the line number info */ int line_num, col_num; line_num = get_line_col(&col_num, s->buf_start, s->token.ptr - s->buf_start); build_backtrace(s->ctx, s->ctx->rt->current_exception, JS_UNDEFINED, s->filename, line_num + 1, col_num + 1, 0); return -1; } ret = emit_push_const(s, str, 0); JS_FreeValue(s->ctx, str); if (ret) return -1; /* we use a specific opcode to be sure the correct function is called (otherwise the bytecode would have to be verified by the RegExp constructor) */ emit_op(s, OP_regexp); if (next_token(s)) return -1; } break; case '(': if (js_parse_expr_paren(s)) return -1; break; case TOK_FUNCTION: if (js_parse_function_decl(s, JS_PARSE_FUNC_EXPR, JS_FUNC_NORMAL, JS_ATOM_NULL, s->token.ptr)) return -1; break; case TOK_CLASS: if (js_parse_class(s, TRUE, JS_PARSE_EXPORT_NONE)) return -1; break; case TOK_NULL: if (next_token(s)) return -1; emit_op(s, OP_null); break; case TOK_THIS: if (next_token(s)) return -1; emit_op(s, OP_scope_get_var); emit_atom(s, JS_ATOM_this); emit_u16(s, 0); break; case TOK_FALSE: if (next_token(s)) return -1; emit_op(s, OP_push_false); break; case TOK_TRUE: if (next_token(s)) return -1; emit_op(s, OP_push_true); break; case TOK_IDENT: { JSAtom name; const uint8_t *source_ptr; if (s->token.u.ident.is_reserved) { return js_parse_error_reserved_identifier(s); } source_ptr = s->token.ptr; if (token_is_pseudo_keyword(s, JS_ATOM_async) && peek_token(s, TRUE) != '\n') { if (next_token(s)) return -1; if (s->token.val == TOK_FUNCTION) { if (js_parse_function_decl(s, JS_PARSE_FUNC_EXPR, JS_FUNC_ASYNC, JS_ATOM_NULL, source_ptr)) return -1; } else { name = JS_DupAtom(s->ctx, JS_ATOM_async); goto do_get_var; } } else { if (s->token.u.ident.atom == JS_ATOM_arguments && !s->cur_func->arguments_allowed) { js_parse_error(s, "'arguments' identifier is not allowed in class field initializer"); return -1; } name = JS_DupAtom(s->ctx, s->token.u.ident.atom); if (next_token(s)) { JS_FreeAtom(s->ctx, name); return -1; } do_get_var: emit_source_pos(s, source_ptr); emit_op(s, OP_scope_get_var); emit_u32(s, name); emit_u16(s, s->cur_func->scope_level); } } break; case '{': case '[': if (s->token.val == '{') { if (js_parse_object_literal(s)) return -1; } else { if (js_parse_array_literal(s)) return -1; } break; case TOK_NEW: if (next_token(s)) return -1; if (s->token.val == '.') { if (next_token(s)) return -1; if (!token_is_pseudo_keyword(s, JS_ATOM_target)) return js_parse_error(s, "expecting target"); if (!s->cur_func->new_target_allowed) return js_parse_error(s, "new.target only allowed within functions"); if (next_token(s)) return -1; emit_op(s, OP_scope_get_var); emit_atom(s, JS_ATOM_new_target); emit_u16(s, 0); } else { if (js_parse_postfix_expr(s, 0)) return -1; accept_lparen = TRUE; if (s->token.val != '(') { /* new operator on an object */ emit_source_pos(s, s->token.ptr); emit_op(s, OP_dup); emit_op(s, OP_call_constructor); emit_u16(s, 0); } else { call_type = FUNC_CALL_NEW; } } break; case TOK_SUPER: if (next_token(s)) return -1; if (s->token.val == '(') { if (!s->cur_func->super_call_allowed) return js_parse_error(s, "super() is only valid in a derived class constructor"); call_type = FUNC_CALL_SUPER_CTOR; } else if (s->token.val == '.' || s->token.val == '[') { if (!s->cur_func->super_allowed) return js_parse_error(s, "'super' is only valid in a method"); emit_op(s, OP_scope_get_var); emit_atom(s, JS_ATOM_this); emit_u16(s, 0); emit_op(s, OP_scope_get_var); emit_atom(s, JS_ATOM_home_object); emit_u16(s, 0); emit_op(s, OP_get_super); } else { return js_parse_error(s, "invalid use of 'super'"); } break; case TOK_IMPORT: if (next_token(s)) return -1; if (s->token.val == '.') { if (next_token(s)) return -1; if (!token_is_pseudo_keyword(s, JS_ATOM_meta)) return js_parse_error(s, "meta expected"); if (!s->is_module) return js_parse_error(s, "import.meta only valid in module code"); if (next_token(s)) return -1; emit_op(s, OP_special_object); emit_u8(s, OP_SPECIAL_OBJECT_IMPORT_META); } else { if (js_parse_expect(s, '(')) return -1; if (!accept_lparen) return js_parse_error(s, "invalid use of 'import()'"); if (js_parse_assign_expr(s)) return -1; if (s->token.val == ',') { if (next_token(s)) return -1; if (s->token.val != ')') { if (js_parse_assign_expr(s)) return -1; /* accept a trailing comma */ if (s->token.val == ',') { if (next_token(s)) return -1; } } else { emit_op(s, OP_undefined); } } else { emit_op(s, OP_undefined); } if (js_parse_expect(s, ')')) return -1; emit_op(s, OP_import); } break; default: return js_parse_error(s, "unexpected token in expression: '%.*s'", (int)(s->buf_ptr - s->token.ptr), s->token.ptr); } optional_chaining_label = -1; for(;;) { JSFunctionDef *fd = s->cur_func; BOOL has_optional_chain = FALSE; if (s->token.val == TOK_QUESTION_MARK_DOT) { if ((parse_flags & PF_POSTFIX_CALL) == 0) return js_parse_error(s, "new keyword cannot be used with an optional chain"); op_token_ptr = s->token.ptr; /* optional chaining */ if (next_token(s)) return -1; has_optional_chain = TRUE; if (s->token.val == '(' && accept_lparen) { goto parse_func_call; } else if (s->token.val == '[') { goto parse_array_access; } else { goto parse_property; } } else if (s->token.val == TOK_TEMPLATE && call_type == FUNC_CALL_NORMAL) { if (optional_chaining_label >= 0) { return js_parse_error(s, "template literal cannot appear in an optional chain"); } call_type = FUNC_CALL_TEMPLATE; op_token_ptr = s->token.ptr; /* XXX: check if right position */ goto parse_func_call2; } else if (s->token.val == '(' && accept_lparen) { int opcode, arg_count, drop_count; /* function call */ parse_func_call: op_token_ptr = s->token.ptr; if (next_token(s)) return -1; if (call_type == FUNC_CALL_NORMAL) { parse_func_call2: switch(opcode = get_prev_opcode(fd)) { case OP_get_field: /* keep the object on the stack */ fd->byte_code.buf[fd->last_opcode_pos] = OP_get_field2; drop_count = 2; break; case OP_get_field_opt_chain: { int opt_chain_label, next_label; opt_chain_label = get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1 + 4 + 1); /* keep the object on the stack */ fd->byte_code.buf[fd->last_opcode_pos] = OP_get_field2; fd->byte_code.size = fd->last_opcode_pos + 1 + 4; next_label = emit_goto(s, OP_goto, -1); emit_label(s, opt_chain_label); /* need an additional undefined value for the case where the optional field does not exists */ emit_op(s, OP_undefined); emit_label(s, next_label); drop_count = 2; opcode = OP_get_field; } break; case OP_scope_get_private_field: /* keep the object on the stack */ fd->byte_code.buf[fd->last_opcode_pos] = OP_scope_get_private_field2; drop_count = 2; break; case OP_get_array_el: /* keep the object on the stack */ fd->byte_code.buf[fd->last_opcode_pos] = OP_get_array_el2; drop_count = 2; break; case OP_get_array_el_opt_chain: { int opt_chain_label, next_label; opt_chain_label = get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1 + 1); /* keep the object on the stack */ fd->byte_code.buf[fd->last_opcode_pos] = OP_get_array_el2; fd->byte_code.size = fd->last_opcode_pos + 1; next_label = emit_goto(s, OP_goto, -1); emit_label(s, opt_chain_label); /* need an additional undefined value for the case where the optional field does not exists */ emit_op(s, OP_undefined); emit_label(s, next_label); drop_count = 2; opcode = OP_get_array_el; } break; case OP_scope_get_var: { JSAtom name; int scope; name = get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1); scope = get_u16(fd->byte_code.buf + fd->last_opcode_pos + 5); if (name == JS_ATOM_eval && call_type == FUNC_CALL_NORMAL && !has_optional_chain) { /* direct 'eval' */ opcode = OP_eval; } else { /* verify if function name resolves to a simple get_loc/get_arg: a function call inside a `with` statement can resolve to a method call of the `with` context object */ /* XXX: always generate the OP_scope_get_ref and remove it in variable resolution pass ? */ if (has_with_scope(fd, scope)) { opcode = OP_scope_get_ref; fd->byte_code.buf[fd->last_opcode_pos] = opcode; } } drop_count = 1; } break; case OP_get_super_value: fd->byte_code.buf[fd->last_opcode_pos] = OP_get_array_el; /* on stack: this func_obj */ opcode = OP_get_array_el; drop_count = 2; break; default: opcode = OP_invalid; drop_count = 1; break; } if (has_optional_chain) { optional_chain_test(s, &optional_chaining_label, drop_count); } } else { opcode = OP_invalid; } if (call_type == FUNC_CALL_TEMPLATE) { if (js_parse_template(s, 1, &arg_count)) return -1; goto emit_func_call; } else if (call_type == FUNC_CALL_SUPER_CTOR) { emit_op(s, OP_scope_get_var); emit_atom(s, JS_ATOM_this_active_func); emit_u16(s, 0); emit_op(s, OP_get_super); emit_op(s, OP_scope_get_var); emit_atom(s, JS_ATOM_new_target); emit_u16(s, 0); } else if (call_type == FUNC_CALL_NEW) { emit_op(s, OP_dup); /* new.target = function */ } /* parse arguments */ arg_count = 0; while (s->token.val != ')') { if (arg_count >= 65535) { return js_parse_error(s, "Too many call arguments"); } if (s->token.val == TOK_ELLIPSIS) break; if (js_parse_assign_expr(s)) return -1; arg_count++; if (s->token.val == ')') break; /* accept a trailing comma before the ')' */ if (js_parse_expect(s, ',')) return -1; } if (s->token.val == TOK_ELLIPSIS) { emit_op(s, OP_array_from); emit_u16(s, arg_count); emit_op(s, OP_push_i32); emit_u32(s, arg_count); /* on stack: array idx */ while (s->token.val != ')') { if (s->token.val == TOK_ELLIPSIS) { if (next_token(s)) return -1; if (js_parse_assign_expr(s)) return -1; #if 1 /* XXX: could pass is_last indicator? */ emit_op(s, OP_append); #else int label_next, label_done; label_next = new_label(s); label_done = new_label(s); /* push enumerate object below array/idx pair */ emit_op(s, OP_for_of_start); emit_op(s, OP_rot5l); emit_op(s, OP_rot5l); emit_label(s, label_next); /* on stack: enum_rec array idx */ emit_op(s, OP_for_of_next); emit_u8(s, 2); emit_goto(s, OP_if_true, label_done); /* append element */ /* enum_rec array idx val -> enum_rec array new_idx */ emit_op(s, OP_define_array_el); emit_op(s, OP_inc); emit_goto(s, OP_goto, label_next); emit_label(s, label_done); /* close enumeration, drop enum_rec and idx */ emit_op(s, OP_drop); /* drop undef */ emit_op(s, OP_nip1); /* drop enum_rec */ emit_op(s, OP_nip1); emit_op(s, OP_nip1); #endif } else { if (js_parse_assign_expr(s)) return -1; /* array idx val */ emit_op(s, OP_define_array_el); emit_op(s, OP_inc); } if (s->token.val == ')') break; /* accept a trailing comma before the ')' */ if (js_parse_expect(s, ',')) return -1; } if (next_token(s)) return -1; /* drop the index */ emit_op(s, OP_drop); emit_source_pos(s, op_token_ptr); /* apply function call */ switch(opcode) { case OP_get_field: case OP_scope_get_private_field: case OP_get_array_el: case OP_scope_get_ref: /* obj func array -> func obj array */ emit_op(s, OP_perm3); emit_op(s, OP_apply); emit_u16(s, call_type == FUNC_CALL_NEW); break; case OP_eval: emit_op(s, OP_apply_eval); emit_u16(s, fd->scope_level); fd->has_eval_call = TRUE; break; default: if (call_type == FUNC_CALL_SUPER_CTOR) { emit_op(s, OP_apply); emit_u16(s, 1); /* set the 'this' value */ emit_op(s, OP_dup); emit_op(s, OP_scope_put_var_init); emit_atom(s, JS_ATOM_this); emit_u16(s, 0); emit_class_field_init(s); } else if (call_type == FUNC_CALL_NEW) { /* obj func array -> func obj array */ emit_op(s, OP_perm3); emit_op(s, OP_apply); emit_u16(s, 1); } else { /* func array -> func undef array */ emit_op(s, OP_undefined); emit_op(s, OP_swap); emit_op(s, OP_apply); emit_u16(s, 0); } break; } } else { if (next_token(s)) return -1; emit_func_call: emit_source_pos(s, op_token_ptr); switch(opcode) { case OP_get_field: case OP_scope_get_private_field: case OP_get_array_el: case OP_scope_get_ref: emit_op(s, OP_call_method); emit_u16(s, arg_count); break; case OP_eval: emit_op(s, OP_eval); emit_u16(s, arg_count); emit_u16(s, fd->scope_level); fd->has_eval_call = TRUE; break; default: if (call_type == FUNC_CALL_SUPER_CTOR) { emit_op(s, OP_call_constructor); emit_u16(s, arg_count); /* set the 'this' value */ emit_op(s, OP_dup); emit_op(s, OP_scope_put_var_init); emit_atom(s, JS_ATOM_this); emit_u16(s, 0); emit_class_field_init(s); } else if (call_type == FUNC_CALL_NEW) { emit_op(s, OP_call_constructor); emit_u16(s, arg_count); } else { emit_op(s, OP_call); emit_u16(s, arg_count); } break; } } call_type = FUNC_CALL_NORMAL; } else if (s->token.val == '.') { op_token_ptr = s->token.ptr; if (next_token(s)) return -1; parse_property: emit_source_pos(s, op_token_ptr); if (s->token.val == TOK_PRIVATE_NAME) { /* private class field */ if (get_prev_opcode(fd) == OP_get_super) { return js_parse_error(s, "private class field forbidden after super"); } if (has_optional_chain) { optional_chain_test(s, &optional_chaining_label, 1); } emit_op(s, OP_scope_get_private_field); emit_atom(s, s->token.u.ident.atom); emit_u16(s, s->cur_func->scope_level); } else { if (!token_is_ident(s->token.val)) { return js_parse_error(s, "expecting field name"); } if (get_prev_opcode(fd) == OP_get_super) { JSValue val; int ret; val = JS_AtomToValue(s->ctx, s->token.u.ident.atom); ret = emit_push_const(s, val, 1); JS_FreeValue(s->ctx, val); if (ret) return -1; emit_op(s, OP_get_super_value); } else { if (has_optional_chain) { optional_chain_test(s, &optional_chaining_label, 1); } emit_op(s, OP_get_field); emit_atom(s, s->token.u.ident.atom); } } if (next_token(s)) return -1; } else if (s->token.val == '[') { int prev_op; op_token_ptr = s->token.ptr; parse_array_access: prev_op = get_prev_opcode(fd); if (has_optional_chain) { optional_chain_test(s, &optional_chaining_label, 1); } if (next_token(s)) return -1; if (js_parse_expr(s)) return -1; if (js_parse_expect(s, ']')) return -1; emit_source_pos(s, op_token_ptr); if (prev_op == OP_get_super) { emit_op(s, OP_get_super_value); } else { emit_op(s, OP_get_array_el); } } else { break; } } if (optional_chaining_label >= 0) { JSFunctionDef *fd = s->cur_func; int opcode; emit_label_raw(s, optional_chaining_label); /* modify the last opcode so that it is an indicator of an optional chain */ opcode = get_prev_opcode(fd); if (opcode == OP_get_field || opcode == OP_get_array_el) { if (opcode == OP_get_field) opcode = OP_get_field_opt_chain; else opcode = OP_get_array_el_opt_chain; fd->byte_code.buf[fd->last_opcode_pos] = opcode; } else { fd->last_opcode_pos = -1; } } return 0; } static __exception int js_parse_delete(JSParseState *s) { JSFunctionDef *fd = s->cur_func; JSAtom name; int opcode; if (next_token(s)) return -1; if (js_parse_unary(s, PF_POW_FORBIDDEN)) return -1; switch(opcode = get_prev_opcode(fd)) { case OP_get_field: case OP_get_field_opt_chain: { JSValue val; int ret, opt_chain_label, next_label; if (opcode == OP_get_field_opt_chain) { opt_chain_label = get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1 + 4 + 1); } else { opt_chain_label = -1; } name = get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1); fd->byte_code.size = fd->last_opcode_pos; val = JS_AtomToValue(s->ctx, name); ret = emit_push_const(s, val, 1); JS_FreeValue(s->ctx, val); JS_FreeAtom(s->ctx, name); if (ret) return ret; emit_op(s, OP_delete); if (opt_chain_label >= 0) { next_label = emit_goto(s, OP_goto, -1); emit_label(s, opt_chain_label); /* if the optional chain is not taken, return 'true' */ emit_op(s, OP_drop); emit_op(s, OP_push_true); emit_label(s, next_label); } fd->last_opcode_pos = -1; } break; case OP_get_array_el: fd->byte_code.size = fd->last_opcode_pos; fd->last_opcode_pos = -1; emit_op(s, OP_delete); break; case OP_get_array_el_opt_chain: { int opt_chain_label, next_label; opt_chain_label = get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1 + 1); fd->byte_code.size = fd->last_opcode_pos; emit_op(s, OP_delete); next_label = emit_goto(s, OP_goto, -1); emit_label(s, opt_chain_label); /* if the optional chain is not taken, return 'true' */ emit_op(s, OP_drop); emit_op(s, OP_push_true); emit_label(s, next_label); fd->last_opcode_pos = -1; } break; case OP_scope_get_var: /* 'delete this': this is not a reference */ name = get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1); if (name == JS_ATOM_this || name == JS_ATOM_new_target) goto ret_true; if (fd->js_mode & JS_MODE_STRICT) { return js_parse_error(s, "cannot delete a direct reference in strict mode"); } else { fd->byte_code.buf[fd->last_opcode_pos] = OP_scope_delete_var; } break; case OP_scope_get_private_field: return js_parse_error(s, "cannot delete a private class field"); case OP_get_super_value: fd->byte_code.size = fd->last_opcode_pos; fd->last_opcode_pos = -1; emit_op(s, OP_throw_error); emit_atom(s, JS_ATOM_NULL); emit_u8(s, JS_THROW_ERROR_DELETE_SUPER); break; default: ret_true: emit_op(s, OP_drop); emit_op(s, OP_push_true); break; } return 0; } /* allowed parse_flags: PF_POW_ALLOWED, PF_POW_FORBIDDEN */ static __exception int js_parse_unary(JSParseState *s, int parse_flags) { int op; const uint8_t *op_token_ptr; switch(s->token.val) { case '+': case '-': case '!': case '~': case TOK_VOID: op_token_ptr = s->token.ptr; op = s->token.val; if (next_token(s)) return -1; if (js_parse_unary(s, PF_POW_FORBIDDEN)) return -1; switch(op) { case '-': emit_source_pos(s, op_token_ptr); emit_op(s, OP_neg); break; case '+': emit_source_pos(s, op_token_ptr); emit_op(s, OP_plus); break; case '!': emit_op(s, OP_lnot); break; case '~': emit_source_pos(s, op_token_ptr); emit_op(s, OP_not); break; case TOK_VOID: emit_op(s, OP_drop); emit_op(s, OP_undefined); break; default: abort(); } parse_flags = 0; break; case TOK_DEC: case TOK_INC: { int opcode, op, scope, label; JSAtom name; op = s->token.val; op_token_ptr = s->token.ptr; if (next_token(s)) return -1; if (js_parse_unary(s, 0)) return -1; if (get_lvalue(s, &opcode, &scope, &name, &label, NULL, TRUE, op)) return -1; emit_source_pos(s, op_token_ptr); emit_op(s, OP_dec + op - TOK_DEC); put_lvalue(s, opcode, scope, name, label, PUT_LVALUE_KEEP_TOP, FALSE); } break; case TOK_TYPEOF: { JSFunctionDef *fd; if (next_token(s)) return -1; if (js_parse_unary(s, PF_POW_FORBIDDEN)) return -1; /* reference access should not return an exception, so we patch the get_var */ fd = s->cur_func; if (get_prev_opcode(fd) == OP_scope_get_var) { fd->byte_code.buf[fd->last_opcode_pos] = OP_scope_get_var_undef; } emit_op(s, OP_typeof); parse_flags = 0; } break; case TOK_DELETE: if (js_parse_delete(s)) return -1; parse_flags = 0; break; case TOK_AWAIT: if (!(s->cur_func->func_kind & JS_FUNC_ASYNC)) return js_parse_error(s, "unexpected 'await' keyword"); if (!s->cur_func->in_function_body) return js_parse_error(s, "await in default expression"); if (next_token(s)) return -1; if (js_parse_unary(s, PF_POW_FORBIDDEN)) return -1; s->cur_func->has_await = TRUE; emit_op(s, OP_await); parse_flags = 0; break; default: if (js_parse_postfix_expr(s, PF_POSTFIX_CALL)) return -1; if (!s->got_lf && (s->token.val == TOK_DEC || s->token.val == TOK_INC)) { int opcode, op, scope, label; JSAtom name; op = s->token.val; op_token_ptr = s->token.ptr; if (get_lvalue(s, &opcode, &scope, &name, &label, NULL, TRUE, op)) return -1; emit_source_pos(s, op_token_ptr); emit_op(s, OP_post_dec + op - TOK_DEC); put_lvalue(s, opcode, scope, name, label, PUT_LVALUE_KEEP_SECOND, FALSE); if (next_token(s)) return -1; } break; } if (parse_flags & (PF_POW_ALLOWED | PF_POW_FORBIDDEN)) { if (s->token.val == TOK_POW) { /* Strict ES7 exponentiation syntax rules: To solve conficting semantics between different implementations regarding the precedence of prefix operators and the postifx exponential, ES7 specifies that -2**2 is a syntax error. */ if (parse_flags & PF_POW_FORBIDDEN) { JS_ThrowSyntaxError(s->ctx, "unparenthesized unary expression can't appear on the left-hand side of '**'"); return -1; } op_token_ptr = s->token.ptr; if (next_token(s)) return -1; if (js_parse_unary(s, PF_POW_ALLOWED)) return -1; emit_source_pos(s, op_token_ptr); emit_op(s, OP_pow); } } return 0; } /* allowed parse_flags: PF_IN_ACCEPTED */ static __exception int js_parse_expr_binary(JSParseState *s, int level, int parse_flags) { int op, opcode; const uint8_t *op_token_ptr; if (level == 0) { return js_parse_unary(s, PF_POW_ALLOWED); } else if (s->token.val == TOK_PRIVATE_NAME && (parse_flags & PF_IN_ACCEPTED) && level == 4 && peek_token(s, FALSE) == TOK_IN) { JSAtom atom; atom = JS_DupAtom(s->ctx, s->token.u.ident.atom); if (next_token(s)) goto fail_private_in; if (s->token.val != TOK_IN) goto fail_private_in; if (next_token(s)) goto fail_private_in; if (js_parse_expr_binary(s, level - 1, parse_flags)) { fail_private_in: JS_FreeAtom(s->ctx, atom); return -1; } emit_op(s, OP_scope_in_private_field); emit_atom(s, atom); emit_u16(s, s->cur_func->scope_level); JS_FreeAtom(s->ctx, atom); return 0; } else { if (js_parse_expr_binary(s, level - 1, parse_flags)) return -1; } for(;;) { op = s->token.val; op_token_ptr = s->token.ptr; switch(level) { case 1: switch(op) { case '*': opcode = OP_mul; break; case '/': opcode = OP_div; break; case '%': opcode = OP_mod; break; default: return 0; } break; case 2: switch(op) { case '+': opcode = OP_add; break; case '-': opcode = OP_sub; break; default: return 0; } break; case 3: switch(op) { case TOK_SHL: opcode = OP_shl; break; case TOK_SAR: opcode = OP_sar; break; case TOK_SHR: opcode = OP_shr; break; default: return 0; } break; case 4: switch(op) { case '<': opcode = OP_lt; break; case '>': opcode = OP_gt; break; case TOK_LTE: opcode = OP_lte; break; case TOK_GTE: opcode = OP_gte; break; case TOK_INSTANCEOF: opcode = OP_instanceof; break; case TOK_IN: if (parse_flags & PF_IN_ACCEPTED) { opcode = OP_in; } else { return 0; } break; default: return 0; } break; case 5: switch(op) { case TOK_EQ: opcode = OP_eq; break; case TOK_NEQ: opcode = OP_neq; break; case TOK_STRICT_EQ: opcode = OP_strict_eq; break; case TOK_STRICT_NEQ: opcode = OP_strict_neq; break; default: return 0; } break; case 6: switch(op) { case '&': opcode = OP_and; break; default: return 0; } break; case 7: switch(op) { case '^': opcode = OP_xor; break; default: return 0; } break; case 8: switch(op) { case '|': opcode = OP_or; break; default: return 0; } break; default: abort(); } if (next_token(s)) return -1; if (js_parse_expr_binary(s, level - 1, parse_flags)) return -1; emit_source_pos(s, op_token_ptr); emit_op(s, opcode); } return 0; } /* allowed parse_flags: PF_IN_ACCEPTED */ static __exception int js_parse_logical_and_or(JSParseState *s, int op, int parse_flags) { int label1; if (op == TOK_LAND) { if (js_parse_expr_binary(s, 8, parse_flags)) return -1; } else { if (js_parse_logical_and_or(s, TOK_LAND, parse_flags)) return -1; } if (s->token.val == op) { label1 = new_label(s); for(;;) { if (next_token(s)) return -1; emit_op(s, OP_dup); emit_goto(s, op == TOK_LAND ? OP_if_false : OP_if_true, label1); emit_op(s, OP_drop); if (op == TOK_LAND) { if (js_parse_expr_binary(s, 8, parse_flags)) return -1; } else { if (js_parse_logical_and_or(s, TOK_LAND, parse_flags)) return -1; } if (s->token.val != op) { if (s->token.val == TOK_DOUBLE_QUESTION_MARK) return js_parse_error(s, "cannot mix ?? with && or ||"); break; } } emit_label(s, label1); } return 0; } static __exception int js_parse_coalesce_expr(JSParseState *s, int parse_flags) { int label1; if (js_parse_logical_and_or(s, TOK_LOR, parse_flags)) return -1; if (s->token.val == TOK_DOUBLE_QUESTION_MARK) { label1 = new_label(s); for(;;) { if (next_token(s)) return -1; emit_op(s, OP_dup); emit_op(s, OP_is_undefined_or_null); emit_goto(s, OP_if_false, label1); emit_op(s, OP_drop); if (js_parse_expr_binary(s, 8, parse_flags)) return -1; if (s->token.val != TOK_DOUBLE_QUESTION_MARK) break; } emit_label(s, label1); } return 0; } /* allowed parse_flags: PF_IN_ACCEPTED */ static __exception int js_parse_cond_expr(JSParseState *s, int parse_flags) { int label1, label2; if (js_parse_coalesce_expr(s, parse_flags)) return -1; if (s->token.val == '?') { if (next_token(s)) return -1; label1 = emit_goto(s, OP_if_false, -1); if (js_parse_assign_expr(s)) return -1; if (js_parse_expect(s, ':')) return -1; label2 = emit_goto(s, OP_goto, -1); emit_label(s, label1); if (js_parse_assign_expr2(s, parse_flags & PF_IN_ACCEPTED)) return -1; emit_label(s, label2); } return 0; } /* allowed parse_flags: PF_IN_ACCEPTED */ static __exception int js_parse_assign_expr2(JSParseState *s, int parse_flags) { int opcode, op, scope, skip_bits; JSAtom name0 = JS_ATOM_NULL; JSAtom name; if (s->token.val == TOK_YIELD) { BOOL is_star = FALSE, is_async; if (!(s->cur_func->func_kind & JS_FUNC_GENERATOR)) return js_parse_error(s, "unexpected 'yield' keyword"); if (!s->cur_func->in_function_body) return js_parse_error(s, "yield in default expression"); if (next_token(s)) return -1; /* XXX: is there a better method to detect 'yield' without parameters ? */ if (s->token.val != ';' && s->token.val != ')' && s->token.val != ']' && s->token.val != '}' && s->token.val != ',' && s->token.val != ':' && !s->got_lf) { if (s->token.val == '*') { is_star = TRUE; if (next_token(s)) return -1; } if (js_parse_assign_expr2(s, parse_flags)) return -1; } else { emit_op(s, OP_undefined); } is_async = (s->cur_func->func_kind == JS_FUNC_ASYNC_GENERATOR); if (is_star) { int label_loop, label_return, label_next; int label_return1, label_yield, label_throw, label_throw1; int label_throw2; label_loop = new_label(s); label_yield = new_label(s); emit_op(s, is_async ? OP_for_await_of_start : OP_for_of_start); /* remove the catch offset (XXX: could avoid pushing back undefined) */ emit_op(s, OP_drop); emit_op(s, OP_undefined); emit_op(s, OP_undefined); /* initial value */ emit_label(s, label_loop); emit_op(s, OP_iterator_next); if (is_async) emit_op(s, OP_await); emit_op(s, OP_iterator_check_object); emit_op(s, OP_get_field2); emit_atom(s, JS_ATOM_done); label_next = emit_goto(s, OP_if_true, -1); /* end of loop */ emit_label(s, label_yield); if (is_async) { /* OP_async_yield_star takes the value as parameter */ emit_op(s, OP_get_field); emit_atom(s, JS_ATOM_value); emit_op(s, OP_async_yield_star); } else { /* OP_yield_star takes (value, done) as parameter */ emit_op(s, OP_yield_star); } emit_op(s, OP_dup); label_return = emit_goto(s, OP_if_true, -1); emit_op(s, OP_drop); emit_goto(s, OP_goto, label_loop); emit_label(s, label_return); emit_op(s, OP_push_i32); emit_u32(s, 2); emit_op(s, OP_strict_eq); label_throw = emit_goto(s, OP_if_true, -1); /* return handling */ if (is_async) emit_op(s, OP_await); emit_op(s, OP_iterator_call); emit_u8(s, 0); label_return1 = emit_goto(s, OP_if_true, -1); if (is_async) emit_op(s, OP_await); emit_op(s, OP_iterator_check_object); emit_op(s, OP_get_field2); emit_atom(s, JS_ATOM_done); emit_goto(s, OP_if_false, label_yield); emit_op(s, OP_get_field); emit_atom(s, JS_ATOM_value); emit_label(s, label_return1); emit_op(s, OP_nip); emit_op(s, OP_nip); emit_op(s, OP_nip); emit_return(s, TRUE); /* throw handling */ emit_label(s, label_throw); emit_op(s, OP_iterator_call); emit_u8(s, 1); label_throw1 = emit_goto(s, OP_if_true, -1); if (is_async) emit_op(s, OP_await); emit_op(s, OP_iterator_check_object); emit_op(s, OP_get_field2); emit_atom(s, JS_ATOM_done); emit_goto(s, OP_if_false, label_yield); emit_goto(s, OP_goto, label_next); /* close the iterator and throw a type error exception */ emit_label(s, label_throw1); emit_op(s, OP_iterator_call); emit_u8(s, 2); label_throw2 = emit_goto(s, OP_if_true, -1); if (is_async) emit_op(s, OP_await); emit_label(s, label_throw2); emit_op(s, OP_throw_error); emit_atom(s, JS_ATOM_NULL); emit_u8(s, JS_THROW_ERROR_ITERATOR_THROW); emit_label(s, label_next); emit_op(s, OP_get_field); emit_atom(s, JS_ATOM_value); emit_op(s, OP_nip); /* keep the value associated with done = true */ emit_op(s, OP_nip); emit_op(s, OP_nip); } else { int label_next; if (is_async) emit_op(s, OP_await); emit_op(s, OP_yield); label_next = emit_goto(s, OP_if_false, -1); emit_return(s, TRUE); emit_label(s, label_next); } return 0; } else if (s->token.val == '(' && js_parse_skip_parens_token(s, NULL, TRUE) == TOK_ARROW) { return js_parse_function_decl(s, JS_PARSE_FUNC_ARROW, JS_FUNC_NORMAL, JS_ATOM_NULL, s->token.ptr); } else if (token_is_pseudo_keyword(s, JS_ATOM_async)) { const uint8_t *source_ptr; int tok; JSParsePos pos; /* fast test */ tok = peek_token(s, TRUE); if (tok == TOK_FUNCTION || tok == '\n') goto next; source_ptr = s->token.ptr; js_parse_get_pos(s, &pos); if (next_token(s)) return -1; if ((s->token.val == '(' && js_parse_skip_parens_token(s, NULL, TRUE) == TOK_ARROW) || (s->token.val == TOK_IDENT && !s->token.u.ident.is_reserved && peek_token(s, TRUE) == TOK_ARROW)) { return js_parse_function_decl(s, JS_PARSE_FUNC_ARROW, JS_FUNC_ASYNC, JS_ATOM_NULL, source_ptr); } else { /* undo the token parsing */ if (js_parse_seek_token(s, &pos)) return -1; } } else if (s->token.val == TOK_IDENT && peek_token(s, TRUE) == TOK_ARROW) { return js_parse_function_decl(s, JS_PARSE_FUNC_ARROW, JS_FUNC_NORMAL, JS_ATOM_NULL, s->token.ptr); } else if ((s->token.val == '{' || s->token.val == '[') && js_parse_skip_parens_token(s, &skip_bits, FALSE) == '=') { if (js_parse_destructuring_element(s, 0, 0, FALSE, skip_bits & SKIP_HAS_ELLIPSIS, TRUE, FALSE) < 0) return -1; return 0; } next: if (s->token.val == TOK_IDENT) { /* name0 is used to check for OP_set_name pattern, not duplicated */ name0 = s->token.u.ident.atom; } if (js_parse_cond_expr(s, parse_flags)) return -1; op = s->token.val; if (op == '=' || (op >= TOK_MUL_ASSIGN && op <= TOK_POW_ASSIGN)) { int label; const uint8_t *op_token_ptr; op_token_ptr = s->token.ptr; if (next_token(s)) return -1; if (get_lvalue(s, &opcode, &scope, &name, &label, NULL, (op != '='), op) < 0) return -1; if (js_parse_assign_expr2(s, parse_flags)) { JS_FreeAtom(s->ctx, name); return -1; } if (op == '=') { if ((opcode == OP_get_ref_value || opcode == OP_scope_get_var) && name == name0) { set_object_name(s, name); } } else { static const uint8_t assign_opcodes[] = { OP_mul, OP_div, OP_mod, OP_add, OP_sub, OP_shl, OP_sar, OP_shr, OP_and, OP_xor, OP_or, OP_pow, }; op = assign_opcodes[op - TOK_MUL_ASSIGN]; emit_source_pos(s, op_token_ptr); emit_op(s, op); } put_lvalue(s, opcode, scope, name, label, PUT_LVALUE_KEEP_TOP, FALSE); } else if (op >= TOK_LAND_ASSIGN && op <= TOK_DOUBLE_QUESTION_MARK_ASSIGN) { int label, label1, depth_lvalue, label2; if (next_token(s)) return -1; if (get_lvalue(s, &opcode, &scope, &name, &label, &depth_lvalue, TRUE, op) < 0) return -1; emit_op(s, OP_dup); if (op == TOK_DOUBLE_QUESTION_MARK_ASSIGN) emit_op(s, OP_is_undefined_or_null); label1 = emit_goto(s, op == TOK_LOR_ASSIGN ? OP_if_true : OP_if_false, -1); emit_op(s, OP_drop); if (js_parse_assign_expr2(s, parse_flags)) { JS_FreeAtom(s->ctx, name); return -1; } if ((opcode == OP_get_ref_value || opcode == OP_scope_get_var) && name == name0) { set_object_name(s, name); } switch(depth_lvalue) { case 0: emit_op(s, OP_dup); break; case 1: emit_op(s, OP_insert2); break; case 2: emit_op(s, OP_insert3); break; case 3: emit_op(s, OP_insert4); break; default: abort(); } /* XXX: we disable the OP_put_ref_value optimization by not using put_lvalue() otherwise depth_lvalue is not correct */ put_lvalue(s, opcode, scope, name, label, PUT_LVALUE_NOKEEP_DEPTH, FALSE); label2 = emit_goto(s, OP_goto, -1); emit_label(s, label1); /* remove the lvalue stack entries */ while (depth_lvalue != 0) { emit_op(s, OP_nip); depth_lvalue--; } emit_label(s, label2); } return 0; } static __exception int js_parse_assign_expr(JSParseState *s) { return js_parse_assign_expr2(s, PF_IN_ACCEPTED); } /* allowed parse_flags: PF_IN_ACCEPTED */ static __exception int js_parse_expr2(JSParseState *s, int parse_flags) { BOOL comma = FALSE; for(;;) { if (js_parse_assign_expr2(s, parse_flags)) return -1; if (comma) { /* prevent get_lvalue from using the last expression as an lvalue. This also prevents the conversion of of get_var to get_ref for method lookup in function call inside `with` statement. */ s->cur_func->last_opcode_pos = -1; } if (s->token.val != ',') break; comma = TRUE; if (next_token(s)) return -1; emit_op(s, OP_drop); } return 0; } static __exception int js_parse_expr(JSParseState *s) { return js_parse_expr2(s, PF_IN_ACCEPTED); } static void push_break_entry(JSFunctionDef *fd, BlockEnv *be, JSAtom label_name, int label_break, int label_cont, int drop_count) { be->prev = fd->top_break; fd->top_break = be; be->label_name = label_name; be->label_break = label_break; be->label_cont = label_cont; be->drop_count = drop_count; be->label_finally = -1; be->scope_level = fd->scope_level; be->has_iterator = FALSE; be->is_regular_stmt = FALSE; } static void pop_break_entry(JSFunctionDef *fd) { BlockEnv *be; be = fd->top_break; fd->top_break = be->prev; } static __exception int emit_break(JSParseState *s, JSAtom name, int is_cont) { BlockEnv *top; int i, scope_level; scope_level = s->cur_func->scope_level; top = s->cur_func->top_break; while (top != NULL) { close_scopes(s, scope_level, top->scope_level); scope_level = top->scope_level; if (is_cont && top->label_cont != -1 && (name == JS_ATOM_NULL || top->label_name == name)) { /* continue stays inside the same block */ emit_goto(s, OP_goto, top->label_cont); return 0; } if (!is_cont && top->label_break != -1 && ((name == JS_ATOM_NULL && !top->is_regular_stmt) || top->label_name == name)) { emit_goto(s, OP_goto, top->label_break); return 0; } i = 0; if (top->has_iterator) { emit_op(s, OP_iterator_close); i += 3; } for(; i < top->drop_count; i++) emit_op(s, OP_drop); if (top->label_finally != -1) { /* must push dummy value to keep same stack depth */ emit_op(s, OP_undefined); emit_goto(s, OP_gosub, top->label_finally); emit_op(s, OP_drop); } top = top->prev; } if (name == JS_ATOM_NULL) { if (is_cont) return js_parse_error(s, "continue must be inside loop"); else return js_parse_error(s, "break must be inside loop or switch"); } else { return js_parse_error(s, "break/continue label not found"); } } /* execute the finally blocks before return */ static void emit_return(JSParseState *s, BOOL hasval) { BlockEnv *top; if (s->cur_func->func_kind != JS_FUNC_NORMAL) { if (!hasval) { /* no value: direct return in case of async generator */ emit_op(s, OP_undefined); hasval = TRUE; } else if (s->cur_func->func_kind == JS_FUNC_ASYNC_GENERATOR) { /* the await must be done before handling the "finally" in case it raises an exception */ emit_op(s, OP_await); } } top = s->cur_func->top_break; while (top != NULL) { if (top->has_iterator || top->label_finally != -1) { if (!hasval) { emit_op(s, OP_undefined); hasval = TRUE; } /* Remove the stack elements up to and including the catch offset. When 'yield' is used in an expression we have no easy way to count them, so we use this specific instruction instead. */ emit_op(s, OP_nip_catch); /* stack: iter_obj next ret_val */ if (top->has_iterator) { if (s->cur_func->func_kind == JS_FUNC_ASYNC_GENERATOR) { int label_next, label_next2; emit_op(s, OP_nip); /* next */ emit_op(s, OP_swap); emit_op(s, OP_get_field2); emit_atom(s, JS_ATOM_return); /* stack: iter_obj return_func */ emit_op(s, OP_dup); emit_op(s, OP_is_undefined_or_null); label_next = emit_goto(s, OP_if_true, -1); emit_op(s, OP_call_method); emit_u16(s, 0); emit_op(s, OP_iterator_check_object); emit_op(s, OP_await); label_next2 = emit_goto(s, OP_goto, -1); emit_label(s, label_next); emit_op(s, OP_drop); emit_label(s, label_next2); emit_op(s, OP_drop); } else { emit_op(s, OP_rot3r); emit_op(s, OP_undefined); /* dummy catch offset */ emit_op(s, OP_iterator_close); } } else { /* execute the "finally" block */ emit_goto(s, OP_gosub, top->label_finally); } } top = top->prev; } if (s->cur_func->is_derived_class_constructor) { int label_return; /* 'this' can be uninitialized, so it may be accessed only if the derived class constructor does not return an object */ if (hasval) { emit_op(s, OP_check_ctor_return); label_return = emit_goto(s, OP_if_false, -1); emit_op(s, OP_drop); } else { label_return = -1; } /* The error should be raised in the caller context, so we use a specific opcode */ emit_op(s, OP_scope_get_var_checkthis); emit_atom(s, JS_ATOM_this); emit_u16(s, 0); emit_label(s, label_return); emit_op(s, OP_return); } else if (s->cur_func->func_kind != JS_FUNC_NORMAL) { emit_op(s, OP_return_async); } else { emit_op(s, hasval ? OP_return : OP_return_undef); } } #define DECL_MASK_FUNC (1 << 0) /* allow normal function declaration */ /* ored with DECL_MASK_FUNC if function declarations are allowed with a label */ #define DECL_MASK_FUNC_WITH_LABEL (1 << 1) #define DECL_MASK_OTHER (1 << 2) /* all other declarations */ #define DECL_MASK_ALL (DECL_MASK_FUNC | DECL_MASK_FUNC_WITH_LABEL | DECL_MASK_OTHER) static __exception int js_parse_statement_or_decl(JSParseState *s, int decl_mask); static __exception int js_parse_statement(JSParseState *s) { return js_parse_statement_or_decl(s, 0); } static __exception int js_parse_block(JSParseState *s) { if (js_parse_expect(s, '{')) return -1; if (s->token.val != '}') { push_scope(s); for(;;) { if (js_parse_statement_or_decl(s, DECL_MASK_ALL)) return -1; if (s->token.val == '}') break; } pop_scope(s); } if (next_token(s)) return -1; return 0; } /* allowed parse_flags: PF_IN_ACCEPTED */ static __exception int js_parse_var(JSParseState *s, int parse_flags, int tok, BOOL export_flag) { JSContext *ctx = s->ctx; JSFunctionDef *fd = s->cur_func; JSAtom name = JS_ATOM_NULL; for (;;) { if (s->token.val == TOK_IDENT) { if (s->token.u.ident.is_reserved) { return js_parse_error_reserved_identifier(s); } name = JS_DupAtom(ctx, s->token.u.ident.atom); if (name == JS_ATOM_let && (tok == TOK_LET || tok == TOK_CONST)) { js_parse_error(s, "'let' is not a valid lexical identifier"); goto var_error; } if (next_token(s)) goto var_error; if (js_define_var(s, name, tok)) goto var_error; if (export_flag) { if (!add_export_entry(s, s->cur_func->module, name, name, JS_EXPORT_TYPE_LOCAL)) goto var_error; } if (s->token.val == '=') { if (next_token(s)) goto var_error; if (need_var_reference(s, tok)) { /* Must make a reference for proper `with` semantics */ int opcode, scope, label; JSAtom name1; emit_op(s, OP_scope_get_var); emit_atom(s, name); emit_u16(s, fd->scope_level); if (get_lvalue(s, &opcode, &scope, &name1, &label, NULL, FALSE, '=') < 0) goto var_error; if (js_parse_assign_expr2(s, parse_flags)) { JS_FreeAtom(ctx, name1); goto var_error; } set_object_name(s, name); put_lvalue(s, opcode, scope, name1, label, PUT_LVALUE_NOKEEP, FALSE); } else { if (js_parse_assign_expr2(s, parse_flags)) goto var_error; set_object_name(s, name); emit_op(s, (tok == TOK_CONST || tok == TOK_LET) ? OP_scope_put_var_init : OP_scope_put_var); emit_atom(s, name); emit_u16(s, fd->scope_level); } } else { if (tok == TOK_CONST) { js_parse_error(s, "missing initializer for const variable"); goto var_error; } if (tok == TOK_LET) { /* initialize lexical variable upon entering its scope */ emit_op(s, OP_undefined); emit_op(s, OP_scope_put_var_init); emit_atom(s, name); emit_u16(s, fd->scope_level); } } JS_FreeAtom(ctx, name); } else { int skip_bits; if ((s->token.val == '[' || s->token.val == '{') && js_parse_skip_parens_token(s, &skip_bits, FALSE) == '=') { emit_op(s, OP_undefined); if (js_parse_destructuring_element(s, tok, 0, TRUE, skip_bits & SKIP_HAS_ELLIPSIS, TRUE, export_flag) < 0) return -1; } else { return js_parse_error(s, "variable name expected"); } } if (s->token.val != ',') break; if (next_token(s)) return -1; } return 0; var_error: JS_FreeAtom(ctx, name); return -1; } /* test if the current token is a label. Use simplistic look-ahead scanner */ static BOOL is_label(JSParseState *s) { return (s->token.val == TOK_IDENT && !s->token.u.ident.is_reserved && peek_token(s, FALSE) == ':'); } /* test if the current token is a let keyword. Use simplistic look-ahead scanner */ static int is_let(JSParseState *s, int decl_mask) { int res = FALSE; const uint8_t *last_token_ptr; if (token_is_pseudo_keyword(s, JS_ATOM_let)) { JSParsePos pos; js_parse_get_pos(s, &pos); for (;;) { last_token_ptr = s->token.ptr; if (next_token(s)) { res = -1; break; } if (s->token.val == '[') { /* let [ is a syntax restriction: it never introduces an ExpressionStatement */ res = TRUE; break; } if (s->token.val == '{' || (s->token.val == TOK_IDENT && !s->token.u.ident.is_reserved) || s->token.val == TOK_LET || s->token.val == TOK_YIELD || s->token.val == TOK_AWAIT) { /* Check for possible ASI if not scanning for Declaration */ /* XXX: should also check that `{` introduces a BindingPattern, but Firefox does not and rejects eval("let=1;let\n{if(1)2;}") */ if (!has_lf_in_range(last_token_ptr, s->token.ptr) || (decl_mask & DECL_MASK_OTHER)) { res = TRUE; break; } break; } break; } if (js_parse_seek_token(s, &pos)) { res = -1; } } return res; } /* XXX: handle IteratorClose when exiting the loop before the enumeration is done */ static __exception int js_parse_for_in_of(JSParseState *s, int label_name, BOOL is_async) { JSContext *ctx = s->ctx; JSFunctionDef *fd = s->cur_func; JSAtom var_name; BOOL has_initializer, is_for_of, has_destructuring; int tok, tok1, opcode, scope, block_scope_level; int label_next, label_expr, label_cont, label_body, label_break; int pos_next, pos_expr; BlockEnv break_entry; has_initializer = FALSE; has_destructuring = FALSE; is_for_of = FALSE; block_scope_level = fd->scope_level; label_cont = new_label(s); label_body = new_label(s); label_break = new_label(s); label_next = new_label(s); /* create scope for the lexical variables declared in the enumeration expressions. XXX: Not completely correct because of weird capturing semantics in `for (i of o) a.push(function(){return i})` */ push_scope(s); /* local for_in scope starts here so individual elements can be closed in statement. */ push_break_entry(s->cur_func, &break_entry, label_name, label_break, label_cont, 1); break_entry.scope_level = block_scope_level; label_expr = emit_goto(s, OP_goto, -1); pos_next = s->cur_func->byte_code.size; emit_label(s, label_next); tok = s->token.val; switch (is_let(s, DECL_MASK_OTHER)) { case TRUE: tok = TOK_LET; break; case FALSE: break; default: return -1; } if (tok == TOK_VAR || tok == TOK_LET || tok == TOK_CONST) { if (next_token(s)) return -1; if (!(s->token.val == TOK_IDENT && !s->token.u.ident.is_reserved)) { if (s->token.val == '[' || s->token.val == '{') { if (js_parse_destructuring_element(s, tok, 0, TRUE, -1, FALSE, FALSE) < 0) return -1; has_destructuring = TRUE; } else { return js_parse_error(s, "variable name expected"); } var_name = JS_ATOM_NULL; } else { var_name = JS_DupAtom(ctx, s->token.u.ident.atom); if (next_token(s)) { JS_FreeAtom(s->ctx, var_name); return -1; } if (js_define_var(s, var_name, tok)) { JS_FreeAtom(s->ctx, var_name); return -1; } emit_op(s, (tok == TOK_CONST || tok == TOK_LET) ? OP_scope_put_var_init : OP_scope_put_var); emit_atom(s, var_name); emit_u16(s, fd->scope_level); } } else if (!is_async && token_is_pseudo_keyword(s, JS_ATOM_async) && peek_token(s, FALSE) == TOK_OF) { return js_parse_error(s, "'for of' expression cannot start with 'async'"); } else { int skip_bits; if ((s->token.val == '[' || s->token.val == '{') && ((tok1 = js_parse_skip_parens_token(s, &skip_bits, FALSE)) == TOK_IN || tok1 == TOK_OF)) { if (js_parse_destructuring_element(s, 0, 0, TRUE, skip_bits & SKIP_HAS_ELLIPSIS, TRUE, FALSE) < 0) return -1; } else { int lvalue_label; if (js_parse_left_hand_side_expr(s)) return -1; if (get_lvalue(s, &opcode, &scope, &var_name, &lvalue_label, NULL, FALSE, TOK_FOR)) return -1; put_lvalue(s, opcode, scope, var_name, lvalue_label, PUT_LVALUE_NOKEEP_BOTTOM, FALSE); } var_name = JS_ATOM_NULL; } emit_goto(s, OP_goto, label_body); pos_expr = s->cur_func->byte_code.size; emit_label(s, label_expr); if (s->token.val == '=') { /* XXX: potential scoping issue if inside `with` statement */ has_initializer = TRUE; /* parse and evaluate initializer prior to evaluating the object (only used with "for in" with a non lexical variable in non strict mode */ if (next_token(s) || js_parse_assign_expr2(s, 0)) { JS_FreeAtom(ctx, var_name); return -1; } if (var_name != JS_ATOM_NULL) { emit_op(s, OP_scope_put_var); emit_atom(s, var_name); emit_u16(s, fd->scope_level); } } JS_FreeAtom(ctx, var_name); if (token_is_pseudo_keyword(s, JS_ATOM_of)) { is_for_of = TRUE; if (has_initializer) goto initializer_error; } else if (s->token.val == TOK_IN) { if (is_async) return js_parse_error(s, "'for await' loop should be used with 'of'"); if (has_initializer && (tok != TOK_VAR || (fd->js_mode & JS_MODE_STRICT) || has_destructuring)) { initializer_error: return js_parse_error(s, "a declaration in the head of a for-%s loop can't have an initializer", is_for_of ? "of" : "in"); } } else { return js_parse_error(s, "expected 'of' or 'in' in for control expression"); } if (next_token(s)) return -1; if (is_for_of) { if (js_parse_assign_expr(s)) return -1; } else { if (js_parse_expr(s)) return -1; } /* close the scope after having evaluated the expression so that the TDZ values are in the closures */ close_scopes(s, s->cur_func->scope_level, block_scope_level); if (is_for_of) { /* set has_iterator after the iterable expression is parsed so that a yield in the expression does not try to close a not-yet-created iterator */ break_entry.has_iterator = TRUE; break_entry.drop_count += 2; if (is_async) emit_op(s, OP_for_await_of_start); else emit_op(s, OP_for_of_start); /* on stack: enum_rec */ } else { emit_op(s, OP_for_in_start); /* on stack: enum_obj */ } emit_goto(s, OP_goto, label_cont); if (js_parse_expect(s, ')')) return -1; if (OPTIMIZE) { /* move the `next` code here */ DynBuf *bc = &s->cur_func->byte_code; int chunk_size = pos_expr - pos_next; int offset = bc->size - pos_next; int i; dbuf_claim(bc, chunk_size); dbuf_put(bc, bc->buf + pos_next, chunk_size); memset(bc->buf + pos_next, OP_nop, chunk_size); /* `next` part ends with a goto */ s->cur_func->last_opcode_pos = bc->size - 5; /* relocate labels */ for (i = label_cont; i < s->cur_func->label_count; i++) { LabelSlot *ls = &s->cur_func->label_slots[i]; if (ls->pos >= pos_next && ls->pos < pos_expr) ls->pos += offset; } } emit_label(s, label_body); if (js_parse_statement(s)) return -1; close_scopes(s, s->cur_func->scope_level, block_scope_level); emit_label(s, label_cont); if (is_for_of) { if (is_async) { /* stack: iter_obj next catch_offset */ /* call the next method */ emit_op(s, OP_for_await_of_next); /* get the result of the promise */ emit_op(s, OP_await); /* unwrap the value and done values */ emit_op(s, OP_iterator_get_value_done); } else { emit_op(s, OP_for_of_next); emit_u8(s, 0); } } else { emit_op(s, OP_for_in_next); } /* on stack: enum_rec / enum_obj value bool */ emit_goto(s, OP_if_false, label_next); /* drop the undefined value from for_xx_next */ emit_op(s, OP_drop); emit_label(s, label_break); if (is_for_of) { /* close and drop enum_rec */ emit_op(s, OP_iterator_close); } else { emit_op(s, OP_drop); } pop_break_entry(s->cur_func); pop_scope(s); return 0; } static void set_eval_ret_undefined(JSParseState *s) { if (s->cur_func->eval_ret_idx >= 0) { emit_op(s, OP_undefined); emit_op(s, OP_put_loc); emit_u16(s, s->cur_func->eval_ret_idx); } } static __exception int js_parse_statement_or_decl(JSParseState *s, int decl_mask) { JSContext *ctx = s->ctx; JSAtom label_name; int tok; /* specific label handling */ /* XXX: support multiple labels on loop statements */ label_name = JS_ATOM_NULL; if (is_label(s)) { BlockEnv *be; label_name = JS_DupAtom(ctx, s->token.u.ident.atom); for (be = s->cur_func->top_break; be; be = be->prev) { if (be->label_name == label_name) { js_parse_error(s, "duplicate label name"); goto fail; } } if (next_token(s)) goto fail; if (js_parse_expect(s, ':')) goto fail; if (s->token.val != TOK_FOR && s->token.val != TOK_DO && s->token.val != TOK_WHILE) { /* labelled regular statement */ int label_break, mask; BlockEnv break_entry; label_break = new_label(s); push_break_entry(s->cur_func, &break_entry, label_name, label_break, -1, 0); break_entry.is_regular_stmt = TRUE; if (!(s->cur_func->js_mode & JS_MODE_STRICT) && (decl_mask & DECL_MASK_FUNC_WITH_LABEL)) { mask = DECL_MASK_FUNC | DECL_MASK_FUNC_WITH_LABEL; } else { mask = 0; } if (js_parse_statement_or_decl(s, mask)) goto fail; emit_label(s, label_break); pop_break_entry(s->cur_func); goto done; } } switch(tok = s->token.val) { case '{': if (js_parse_block(s)) goto fail; break; case TOK_RETURN: { const uint8_t *op_token_ptr; if (s->cur_func->is_eval) { js_parse_error(s, "return not in a function"); goto fail; } if (s->cur_func->func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT) { js_parse_error(s, "return in a static initializer block"); goto fail; } op_token_ptr = s->token.ptr; if (next_token(s)) goto fail; if (s->token.val != ';' && s->token.val != '}' && !s->got_lf) { if (js_parse_expr(s)) goto fail; emit_source_pos(s, op_token_ptr); emit_return(s, TRUE); } else { emit_source_pos(s, op_token_ptr); emit_return(s, FALSE); } if (js_parse_expect_semi(s)) goto fail; } break; case TOK_THROW: { const uint8_t *op_token_ptr; op_token_ptr = s->token.ptr; if (next_token(s)) goto fail; if (s->got_lf) { js_parse_error(s, "line terminator not allowed after throw"); goto fail; } if (js_parse_expr(s)) goto fail; emit_source_pos(s, op_token_ptr); emit_op(s, OP_throw); if (js_parse_expect_semi(s)) goto fail; } break; case TOK_LET: case TOK_CONST: haslet: if (!(decl_mask & DECL_MASK_OTHER)) { js_parse_error(s, "lexical declarations can't appear in single-statement context"); goto fail; } /* fall thru */ case TOK_VAR: if (next_token(s)) goto fail; if (js_parse_var(s, TRUE, tok, FALSE)) goto fail; if (js_parse_expect_semi(s)) goto fail; break; case TOK_IF: { int label1, label2, mask; if (next_token(s)) goto fail; /* create a new scope for `let f;if(1) function f(){}` */ push_scope(s); set_eval_ret_undefined(s); if (js_parse_expr_paren(s)) goto fail; label1 = emit_goto(s, OP_if_false, -1); if (s->cur_func->js_mode & JS_MODE_STRICT) mask = 0; else mask = DECL_MASK_FUNC; /* Annex B.3.4 */ if (js_parse_statement_or_decl(s, mask)) goto fail; if (s->token.val == TOK_ELSE) { label2 = emit_goto(s, OP_goto, -1); if (next_token(s)) goto fail; emit_label(s, label1); if (js_parse_statement_or_decl(s, mask)) goto fail; label1 = label2; } emit_label(s, label1); pop_scope(s); } break; case TOK_WHILE: { int label_cont, label_break; BlockEnv break_entry; label_cont = new_label(s); label_break = new_label(s); push_break_entry(s->cur_func, &break_entry, label_name, label_break, label_cont, 0); if (next_token(s)) goto fail; set_eval_ret_undefined(s); emit_label(s, label_cont); if (js_parse_expr_paren(s)) goto fail; emit_goto(s, OP_if_false, label_break); if (js_parse_statement(s)) goto fail; emit_goto(s, OP_goto, label_cont); emit_label(s, label_break); pop_break_entry(s->cur_func); } break; case TOK_DO: { int label_cont, label_break, label1; BlockEnv break_entry; label_cont = new_label(s); label_break = new_label(s); label1 = new_label(s); push_break_entry(s->cur_func, &break_entry, label_name, label_break, label_cont, 0); if (next_token(s)) goto fail; emit_label(s, label1); set_eval_ret_undefined(s); if (js_parse_statement(s)) goto fail; emit_label(s, label_cont); if (js_parse_expect(s, TOK_WHILE)) goto fail; if (js_parse_expr_paren(s)) goto fail; /* Insert semicolon if missing */ if (s->token.val == ';') { if (next_token(s)) goto fail; } emit_goto(s, OP_if_true, label1); emit_label(s, label_break); pop_break_entry(s->cur_func); } break; case TOK_FOR: { int label_cont, label_break, label_body, label_test; int pos_cont, pos_body, block_scope_level; BlockEnv break_entry; int tok, bits; BOOL is_async; if (next_token(s)) goto fail; set_eval_ret_undefined(s); bits = 0; is_async = FALSE; if (s->token.val == '(') { js_parse_skip_parens_token(s, &bits, FALSE); } else if (s->token.val == TOK_AWAIT) { if (!(s->cur_func->func_kind & JS_FUNC_ASYNC)) { js_parse_error(s, "for await is only valid in asynchronous functions"); goto fail; } is_async = TRUE; if (next_token(s)) goto fail; s->cur_func->has_await = TRUE; } if (js_parse_expect(s, '(')) goto fail; if (!(bits & SKIP_HAS_SEMI)) { /* parse for/in or for/of */ if (js_parse_for_in_of(s, label_name, is_async)) goto fail; break; } block_scope_level = s->cur_func->scope_level; /* create scope for the lexical variables declared in the initial, test and increment expressions */ push_scope(s); /* initial expression */ tok = s->token.val; if (tok != ';') { switch (is_let(s, DECL_MASK_OTHER)) { case TRUE: tok = TOK_LET; break; case FALSE: break; default: goto fail; } if (tok == TOK_VAR || tok == TOK_LET || tok == TOK_CONST) { if (next_token(s)) goto fail; if (js_parse_var(s, FALSE, tok, FALSE)) goto fail; } else { if (js_parse_expr2(s, FALSE)) goto fail; emit_op(s, OP_drop); } /* close the closures before the first iteration */ close_scopes(s, s->cur_func->scope_level, block_scope_level); } if (js_parse_expect(s, ';')) goto fail; label_test = new_label(s); label_cont = new_label(s); label_body = new_label(s); label_break = new_label(s); push_break_entry(s->cur_func, &break_entry, label_name, label_break, label_cont, 0); /* test expression */ if (s->token.val == ';') { /* no test expression */ label_test = label_body; } else { emit_label(s, label_test); if (js_parse_expr(s)) goto fail; emit_goto(s, OP_if_false, label_break); } if (js_parse_expect(s, ';')) goto fail; if (s->token.val == ')') { /* no end expression */ break_entry.label_cont = label_cont = label_test; pos_cont = 0; /* avoid warning */ } else { /* skip the end expression */ emit_goto(s, OP_goto, label_body); pos_cont = s->cur_func->byte_code.size; emit_label(s, label_cont); if (js_parse_expr(s)) goto fail; emit_op(s, OP_drop); if (label_test != label_body) emit_goto(s, OP_goto, label_test); } if (js_parse_expect(s, ')')) goto fail; pos_body = s->cur_func->byte_code.size; emit_label(s, label_body); if (js_parse_statement(s)) goto fail; /* close the closures before the next iteration */ /* XXX: check continue case */ close_scopes(s, s->cur_func->scope_level, block_scope_level); if (OPTIMIZE && label_test != label_body && label_cont != label_test) { /* move the increment code here */ DynBuf *bc = &s->cur_func->byte_code; int chunk_size = pos_body - pos_cont; int offset = bc->size - pos_cont; int i; dbuf_claim(bc, chunk_size); dbuf_put(bc, bc->buf + pos_cont, chunk_size); memset(bc->buf + pos_cont, OP_nop, chunk_size); /* increment part ends with a goto */ s->cur_func->last_opcode_pos = bc->size - 5; /* relocate labels */ for (i = label_cont; i < s->cur_func->label_count; i++) { LabelSlot *ls = &s->cur_func->label_slots[i]; if (ls->pos >= pos_cont && ls->pos < pos_body) ls->pos += offset; } } else { emit_goto(s, OP_goto, label_cont); } emit_label(s, label_break); pop_break_entry(s->cur_func); pop_scope(s); } break; case TOK_BREAK: case TOK_CONTINUE: { int is_cont = s->token.val - TOK_BREAK; int label; if (next_token(s)) goto fail; if (!s->got_lf && s->token.val == TOK_IDENT && !s->token.u.ident.is_reserved) label = s->token.u.ident.atom; else label = JS_ATOM_NULL; if (emit_break(s, label, is_cont)) goto fail; if (label != JS_ATOM_NULL) { if (next_token(s)) goto fail; } if (js_parse_expect_semi(s)) goto fail; } break; case TOK_SWITCH: { int label_case, label_break, label1; int default_label_pos; BlockEnv break_entry; if (next_token(s)) goto fail; set_eval_ret_undefined(s); if (js_parse_expr_paren(s)) goto fail; push_scope(s); label_break = new_label(s); push_break_entry(s->cur_func, &break_entry, label_name, label_break, -1, 1); if (js_parse_expect(s, '{')) goto fail; default_label_pos = -1; label_case = -1; while (s->token.val != '}') { if (s->token.val == TOK_CASE) { label1 = -1; if (label_case >= 0) { /* skip the case if needed */ label1 = emit_goto(s, OP_goto, -1); } emit_label(s, label_case); label_case = -1; for (;;) { /* parse a sequence of case clauses */ if (next_token(s)) goto fail; emit_op(s, OP_dup); if (js_parse_expr(s)) goto fail; if (js_parse_expect(s, ':')) goto fail; emit_op(s, OP_strict_eq); if (s->token.val == TOK_CASE) { label1 = emit_goto(s, OP_if_true, label1); } else { label_case = emit_goto(s, OP_if_false, -1); emit_label(s, label1); break; } } } else if (s->token.val == TOK_DEFAULT) { if (next_token(s)) goto fail; if (js_parse_expect(s, ':')) goto fail; if (default_label_pos >= 0) { js_parse_error(s, "duplicate default"); goto fail; } if (label_case < 0) { /* falling thru direct from switch expression */ label_case = emit_goto(s, OP_goto, -1); } /* Emit a dummy label opcode. Label will be patched after the end of the switch body. Do not use emit_label(s, 0) because it would clobber label 0 address, preventing proper optimizer operation. */ emit_op(s, OP_label); emit_u32(s, 0); default_label_pos = s->cur_func->byte_code.size - 4; } else { if (label_case < 0) { /* falling thru direct from switch expression */ js_parse_error(s, "invalid switch statement"); goto fail; } if (js_parse_statement_or_decl(s, DECL_MASK_ALL)) goto fail; } } if (js_parse_expect(s, '}')) goto fail; if (default_label_pos >= 0) { /* Ugly patch for the `default` label, shameful and risky */ put_u32(s->cur_func->byte_code.buf + default_label_pos, label_case); s->cur_func->label_slots[label_case].pos = default_label_pos + 4; } else { emit_label(s, label_case); } emit_label(s, label_break); emit_op(s, OP_drop); /* drop the switch expression */ pop_break_entry(s->cur_func); pop_scope(s); } break; case TOK_TRY: { int label_catch, label_catch2, label_finally, label_end; JSAtom name; BlockEnv block_env; set_eval_ret_undefined(s); if (next_token(s)) goto fail; label_catch = new_label(s); label_catch2 = new_label(s); label_finally = new_label(s); label_end = new_label(s); emit_goto(s, OP_catch, label_catch); push_break_entry(s->cur_func, &block_env, JS_ATOM_NULL, -1, -1, 1); block_env.label_finally = label_finally; if (js_parse_block(s)) goto fail; pop_break_entry(s->cur_func); if (js_is_live_code(s)) { /* drop the catch offset */ emit_op(s, OP_drop); /* must push dummy value to keep same stack size */ emit_op(s, OP_undefined); emit_goto(s, OP_gosub, label_finally); emit_op(s, OP_drop); emit_goto(s, OP_goto, label_end); } if (s->token.val == TOK_CATCH) { if (next_token(s)) goto fail; push_scope(s); /* catch variable */ emit_label(s, label_catch); if (s->token.val == '{') { /* support optional-catch-binding feature */ emit_op(s, OP_drop); /* pop the exception object */ } else { if (js_parse_expect(s, '(')) goto fail; if (!(s->token.val == TOK_IDENT && !s->token.u.ident.is_reserved)) { if (s->token.val == '[' || s->token.val == '{') { /* XXX: TOK_LET is not completely correct */ if (js_parse_destructuring_element(s, TOK_LET, 0, TRUE, -1, TRUE, FALSE) < 0) goto fail; } else { js_parse_error(s, "identifier expected"); goto fail; } } else { name = JS_DupAtom(ctx, s->token.u.ident.atom); if (next_token(s) || js_define_var(s, name, TOK_CATCH) < 0) { JS_FreeAtom(ctx, name); goto fail; } /* store the exception value in the catch variable */ emit_op(s, OP_scope_put_var); emit_u32(s, name); emit_u16(s, s->cur_func->scope_level); } if (js_parse_expect(s, ')')) goto fail; } /* XXX: should keep the address to nop it out if there is no finally block */ emit_goto(s, OP_catch, label_catch2); push_scope(s); /* catch block */ push_break_entry(s->cur_func, &block_env, JS_ATOM_NULL, -1, -1, 1); block_env.label_finally = label_finally; if (js_parse_block(s)) goto fail; pop_break_entry(s->cur_func); pop_scope(s); /* catch block */ pop_scope(s); /* catch variable */ if (js_is_live_code(s)) { /* drop the catch2 offset */ emit_op(s, OP_drop); /* XXX: should keep the address to nop it out if there is no finally block */ /* must push dummy value to keep same stack size */ emit_op(s, OP_undefined); emit_goto(s, OP_gosub, label_finally); emit_op(s, OP_drop); emit_goto(s, OP_goto, label_end); } /* catch exceptions thrown in the catch block to execute the * finally clause and rethrow the exception */ emit_label(s, label_catch2); /* catch value is at TOS, no need to push undefined */ emit_goto(s, OP_gosub, label_finally); emit_op(s, OP_throw); } else if (s->token.val == TOK_FINALLY) { /* finally without catch : execute the finally clause * and rethrow the exception */ emit_label(s, label_catch); /* catch value is at TOS, no need to push undefined */ emit_goto(s, OP_gosub, label_finally); emit_op(s, OP_throw); } else { js_parse_error(s, "expecting catch or finally"); goto fail; } emit_label(s, label_finally); if (s->token.val == TOK_FINALLY) { int saved_eval_ret_idx = 0; /* avoid warning */ if (next_token(s)) goto fail; /* on the stack: ret_value gosub_ret_value */ push_break_entry(s->cur_func, &block_env, JS_ATOM_NULL, -1, -1, 2); if (s->cur_func->eval_ret_idx >= 0) { /* 'finally' updates eval_ret only if not a normal termination */ saved_eval_ret_idx = add_var(s->ctx, s->cur_func, JS_ATOM__ret_); if (saved_eval_ret_idx < 0) goto fail; emit_op(s, OP_get_loc); emit_u16(s, s->cur_func->eval_ret_idx); emit_op(s, OP_put_loc); emit_u16(s, saved_eval_ret_idx); set_eval_ret_undefined(s); } if (js_parse_block(s)) goto fail; if (s->cur_func->eval_ret_idx >= 0) { emit_op(s, OP_get_loc); emit_u16(s, saved_eval_ret_idx); emit_op(s, OP_put_loc); emit_u16(s, s->cur_func->eval_ret_idx); } pop_break_entry(s->cur_func); } emit_op(s, OP_ret); emit_label(s, label_end); } break; case ';': /* empty statement */ if (next_token(s)) goto fail; break; case TOK_WITH: if (s->cur_func->js_mode & JS_MODE_STRICT) { js_parse_error(s, "invalid keyword: with"); goto fail; } else { int with_idx; if (next_token(s)) goto fail; if (js_parse_expr_paren(s)) goto fail; push_scope(s); with_idx = define_var(s, s->cur_func, JS_ATOM__with_, JS_VAR_DEF_WITH); if (with_idx < 0) goto fail; emit_op(s, OP_to_object); emit_op(s, OP_put_loc); emit_u16(s, with_idx); set_eval_ret_undefined(s); if (js_parse_statement(s)) goto fail; /* Popping scope drops lexical context for the with object variable */ pop_scope(s); } break; case TOK_FUNCTION: /* ES6 Annex B.3.2 and B.3.3 semantics */ if (!(decl_mask & DECL_MASK_FUNC)) goto func_decl_error; if (!(decl_mask & DECL_MASK_OTHER) && peek_token(s, FALSE) == '*') goto func_decl_error; goto parse_func_var; case TOK_IDENT: if (s->token.u.ident.is_reserved) { js_parse_error_reserved_identifier(s); goto fail; } /* Determine if `let` introduces a Declaration or an ExpressionStatement */ switch (is_let(s, decl_mask)) { case TRUE: tok = TOK_LET; goto haslet; case FALSE: break; default: goto fail; } if (token_is_pseudo_keyword(s, JS_ATOM_async) && peek_token(s, TRUE) == TOK_FUNCTION) { if (!(decl_mask & DECL_MASK_OTHER)) { func_decl_error: js_parse_error(s, "function declarations can't appear in single-statement context"); goto fail; } parse_func_var: if (js_parse_function_decl(s, JS_PARSE_FUNC_VAR, JS_FUNC_NORMAL, JS_ATOM_NULL, s->token.ptr)) goto fail; break; } goto hasexpr; case TOK_CLASS: if (!(decl_mask & DECL_MASK_OTHER)) { js_parse_error(s, "class declarations can't appear in single-statement context"); goto fail; } if (js_parse_class(s, FALSE, JS_PARSE_EXPORT_NONE)) return -1; break; case TOK_DEBUGGER: /* currently no debugger, so just skip the keyword */ if (next_token(s)) goto fail; if (js_parse_expect_semi(s)) goto fail; break; case TOK_ENUM: case TOK_EXPORT: case TOK_EXTENDS: js_unsupported_keyword(s, s->token.u.ident.atom); goto fail; default: hasexpr: emit_source_pos(s, s->token.ptr); if (js_parse_expr(s)) goto fail; if (s->cur_func->eval_ret_idx >= 0) { /* store the expression value so that it can be returned by eval() */ emit_op(s, OP_put_loc); emit_u16(s, s->cur_func->eval_ret_idx); } else { emit_op(s, OP_drop); /* drop the result */ } if (js_parse_expect_semi(s)) goto fail; break; } done: JS_FreeAtom(ctx, label_name); return 0; fail: JS_FreeAtom(ctx, label_name); return -1; } /* 'name' is freed. The module is referenced by 'ctx->loaded_modules' */ static JSModuleDef *js_new_module_def(JSContext *ctx, JSAtom name) { JSModuleDef *m; m = js_mallocz(ctx, sizeof(*m)); if (!m) { JS_FreeAtom(ctx, name); return NULL; } m->header.ref_count = 1; add_gc_object(ctx->rt, &m->header, JS_GC_OBJ_TYPE_MODULE); m->module_name = name; m->module_ns = JS_UNDEFINED; m->func_obj = JS_UNDEFINED; m->eval_exception = JS_UNDEFINED; m->meta_obj = JS_UNDEFINED; m->promise = JS_UNDEFINED; m->resolving_funcs[0] = JS_UNDEFINED; m->resolving_funcs[1] = JS_UNDEFINED; m->private_value = JS_UNDEFINED; list_add_tail(&m->link, &ctx->loaded_modules); return m; } static void js_mark_module_def(JSRuntime *rt, JSModuleDef *m, JS_MarkFunc *mark_func) { int i; for(i = 0; i < m->req_module_entries_count; i++) { JSReqModuleEntry *rme = &m->req_module_entries[i]; JS_MarkValue(rt, rme->attributes, mark_func); } for(i = 0; i < m->export_entries_count; i++) { JSExportEntry *me = &m->export_entries[i]; if (me->export_type == JS_EXPORT_TYPE_LOCAL && me->u.local.var_ref) { mark_func(rt, &me->u.local.var_ref->header); } } JS_MarkValue(rt, m->module_ns, mark_func); JS_MarkValue(rt, m->func_obj, mark_func); JS_MarkValue(rt, m->eval_exception, mark_func); JS_MarkValue(rt, m->meta_obj, mark_func); JS_MarkValue(rt, m->promise, mark_func); JS_MarkValue(rt, m->resolving_funcs[0], mark_func); JS_MarkValue(rt, m->resolving_funcs[1], mark_func); JS_MarkValue(rt, m->private_value, mark_func); } static void js_free_module_def(JSRuntime *rt, JSModuleDef *m) { int i; JS_FreeAtomRT(rt, m->module_name); for(i = 0; i < m->req_module_entries_count; i++) { JSReqModuleEntry *rme = &m->req_module_entries[i]; JS_FreeAtomRT(rt, rme->module_name); JS_FreeValueRT(rt, rme->attributes); } js_free_rt(rt, m->req_module_entries); for(i = 0; i < m->export_entries_count; i++) { JSExportEntry *me = &m->export_entries[i]; if (me->export_type == JS_EXPORT_TYPE_LOCAL) free_var_ref(rt, me->u.local.var_ref); JS_FreeAtomRT(rt, me->export_name); JS_FreeAtomRT(rt, me->local_name); } js_free_rt(rt, m->export_entries); js_free_rt(rt, m->star_export_entries); for(i = 0; i < m->import_entries_count; i++) { JSImportEntry *mi = &m->import_entries[i]; JS_FreeAtomRT(rt, mi->import_name); } js_free_rt(rt, m->import_entries); js_free_rt(rt, m->async_parent_modules); JS_FreeValueRT(rt, m->module_ns); JS_FreeValueRT(rt, m->func_obj); JS_FreeValueRT(rt, m->eval_exception); JS_FreeValueRT(rt, m->meta_obj); JS_FreeValueRT(rt, m->promise); JS_FreeValueRT(rt, m->resolving_funcs[0]); JS_FreeValueRT(rt, m->resolving_funcs[1]); JS_FreeValueRT(rt, m->private_value); /* during the GC the finalizers are called in an arbitrary order so the module may no longer be referenced by the JSContext list */ if (m->link.next) { list_del(&m->link); } remove_gc_object(&m->header); if (rt->gc_phase == JS_GC_PHASE_REMOVE_CYCLES && m->header.ref_count != 0) { list_add_tail(&m->header.link, &rt->gc_zero_ref_count_list); } else { js_free_rt(rt, m); } } static int add_req_module_entry(JSContext *ctx, JSModuleDef *m, JSAtom module_name) { JSReqModuleEntry *rme; if (js_resize_array(ctx, (void **)&m->req_module_entries, sizeof(JSReqModuleEntry), &m->req_module_entries_size, m->req_module_entries_count + 1)) return -1; rme = &m->req_module_entries[m->req_module_entries_count++]; rme->module_name = JS_DupAtom(ctx, module_name); rme->module = NULL; rme->attributes = JS_UNDEFINED; return m->req_module_entries_count - 1; } static JSExportEntry *find_export_entry(JSContext *ctx, JSModuleDef *m, JSAtom export_name) { JSExportEntry *me; int i; for(i = 0; i < m->export_entries_count; i++) { me = &m->export_entries[i]; if (me->export_name == export_name) return me; } return NULL; } static JSExportEntry *add_export_entry2(JSContext *ctx, JSParseState *s, JSModuleDef *m, JSAtom local_name, JSAtom export_name, JSExportTypeEnum export_type) { JSExportEntry *me; if (find_export_entry(ctx, m, export_name)) { char buf1[ATOM_GET_STR_BUF_SIZE]; if (s) { js_parse_error(s, "duplicate exported name '%s'", JS_AtomGetStr(ctx, buf1, sizeof(buf1), export_name)); } else { JS_ThrowSyntaxErrorAtom(ctx, "duplicate exported name '%s'", export_name); } return NULL; } if (js_resize_array(ctx, (void **)&m->export_entries, sizeof(JSExportEntry), &m->export_entries_size, m->export_entries_count + 1)) return NULL; me = &m->export_entries[m->export_entries_count++]; memset(me, 0, sizeof(*me)); me->local_name = JS_DupAtom(ctx, local_name); me->export_name = JS_DupAtom(ctx, export_name); me->export_type = export_type; return me; } static JSExportEntry *add_export_entry(JSParseState *s, JSModuleDef *m, JSAtom local_name, JSAtom export_name, JSExportTypeEnum export_type) { return add_export_entry2(s->ctx, s, m, local_name, export_name, export_type); } static int add_star_export_entry(JSContext *ctx, JSModuleDef *m, int req_module_idx) { JSStarExportEntry *se; if (js_resize_array(ctx, (void **)&m->star_export_entries, sizeof(JSStarExportEntry), &m->star_export_entries_size, m->star_export_entries_count + 1)) return -1; se = &m->star_export_entries[m->star_export_entries_count++]; se->req_module_idx = req_module_idx; return 0; } /* create a C module */ JSModuleDef *JS_NewCModule(JSContext *ctx, const char *name_str, JSModuleInitFunc *func) { JSModuleDef *m; JSAtom name; name = JS_NewAtom(ctx, name_str); if (name == JS_ATOM_NULL) return NULL; m = js_new_module_def(ctx, name); if (!m) return NULL; m->init_func = func; return m; } int JS_AddModuleExport(JSContext *ctx, JSModuleDef *m, const char *export_name) { JSExportEntry *me; JSAtom name; name = JS_NewAtom(ctx, export_name); if (name == JS_ATOM_NULL) return -1; me = add_export_entry2(ctx, NULL, m, JS_ATOM_NULL, name, JS_EXPORT_TYPE_LOCAL); JS_FreeAtom(ctx, name); if (!me) return -1; else return 0; } int JS_SetModuleExport(JSContext *ctx, JSModuleDef *m, const char *export_name, JSValue val) { JSExportEntry *me; JSAtom name; name = JS_NewAtom(ctx, export_name); if (name == JS_ATOM_NULL) goto fail; me = find_export_entry(ctx, m, name); JS_FreeAtom(ctx, name); if (!me) goto fail; set_value(ctx, me->u.local.var_ref->pvalue, val); return 0; fail: JS_FreeValue(ctx, val); return -1; } int JS_SetModulePrivateValue(JSContext *ctx, JSModuleDef *m, JSValue val) { set_value(ctx, &m->private_value, val); return 0; } JSValue JS_GetModulePrivateValue(JSContext *ctx, JSModuleDef *m) { return JS_DupValue(ctx, m->private_value); } void JS_SetModuleLoaderFunc(JSRuntime *rt, JSModuleNormalizeFunc *module_normalize, JSModuleLoaderFunc *module_loader, void *opaque) { rt->module_normalize_func = module_normalize; rt->module_loader_has_attr = FALSE; rt->u.module_loader_func = module_loader; rt->module_check_attrs = NULL; rt->module_loader_opaque = opaque; } void JS_SetModuleLoaderFunc2(JSRuntime *rt, JSModuleNormalizeFunc *module_normalize, JSModuleLoaderFunc2 *module_loader, JSModuleCheckSupportedImportAttributes *module_check_attrs, void *opaque) { rt->module_normalize_func = module_normalize; rt->module_loader_has_attr = TRUE; rt->u.module_loader_func2 = module_loader; rt->module_check_attrs = module_check_attrs; rt->module_loader_opaque = opaque; } /* default module filename normalizer */ static char *js_default_module_normalize_name(JSContext *ctx, const char *base_name, const char *name) { char *filename, *p; const char *r; int cap; int len; if (name[0] != '.') { /* if no initial dot, the module name is not modified */ return js_strdup(ctx, name); } p = strrchr(base_name, '/'); if (p) len = p - base_name; else len = 0; cap = len + strlen(name) + 1 + 1; filename = js_malloc(ctx, cap); if (!filename) return NULL; memcpy(filename, base_name, len); filename[len] = '\0'; /* we only normalize the leading '..' or '.' */ r = name; for(;;) { if (r[0] == '.' && r[1] == '/') { r += 2; } else if (r[0] == '.' && r[1] == '.' && r[2] == '/') { /* remove the last path element of filename, except if "." or ".." */ if (filename[0] == '\0') break; p = strrchr(filename, '/'); if (!p) p = filename; else p++; if (!strcmp(p, ".") || !strcmp(p, "..")) break; if (p > filename) p--; *p = '\0'; r += 3; } else { break; } } if (filename[0] != '\0') pstrcat(filename, cap, "/"); pstrcat(filename, cap, r); // printf("normalize: %s %s -> %s\n", base_name, name, filename); return filename; } static JSModuleDef *js_find_loaded_module(JSContext *ctx, JSAtom name) { struct list_head *el; JSModuleDef *m; /* first look at the loaded modules */ list_for_each(el, &ctx->loaded_modules) { m = list_entry(el, JSModuleDef, link); if (m->module_name == name) return m; } return NULL; } /* return NULL in case of exception (e.g. module could not be loaded) */ static JSModuleDef *js_host_resolve_imported_module(JSContext *ctx, const char *base_cname, const char *cname1, JSValueConst attributes) { JSRuntime *rt = ctx->rt; JSModuleDef *m; char *cname; JSAtom module_name; if (!rt->module_normalize_func) { cname = js_default_module_normalize_name(ctx, base_cname, cname1); } else { cname = rt->module_normalize_func(ctx, base_cname, cname1, rt->module_loader_opaque); } if (!cname) return NULL; module_name = JS_NewAtom(ctx, cname); if (module_name == JS_ATOM_NULL) { js_free(ctx, cname); return NULL; } /* first look at the loaded modules */ m = js_find_loaded_module(ctx, module_name); if (m) { js_free(ctx, cname); JS_FreeAtom(ctx, module_name); return m; } JS_FreeAtom(ctx, module_name); /* load the module */ if (!rt->u.module_loader_func) { /* XXX: use a syntax error ? */ JS_ThrowReferenceError(ctx, "could not load module '%s'", cname); js_free(ctx, cname); return NULL; } if (rt->module_loader_has_attr) { m = rt->u.module_loader_func2(ctx, cname, rt->module_loader_opaque, attributes); } else { m = rt->u.module_loader_func(ctx, cname, rt->module_loader_opaque); } js_free(ctx, cname); return m; } static JSModuleDef *js_host_resolve_imported_module_atom(JSContext *ctx, JSAtom base_module_name, JSAtom module_name1, JSValueConst attributes) { const char *base_cname, *cname; JSModuleDef *m; base_cname = JS_AtomToCString(ctx, base_module_name); if (!base_cname) return NULL; cname = JS_AtomToCString(ctx, module_name1); if (!cname) { JS_FreeCString(ctx, base_cname); return NULL; } m = js_host_resolve_imported_module(ctx, base_cname, cname, attributes); JS_FreeCString(ctx, base_cname); JS_FreeCString(ctx, cname); return m; } typedef struct JSResolveEntry { JSModuleDef *module; JSAtom name; } JSResolveEntry; typedef struct JSResolveState { JSResolveEntry *array; int size; int count; } JSResolveState; static int find_resolve_entry(JSResolveState *s, JSModuleDef *m, JSAtom name) { int i; for(i = 0; i < s->count; i++) { JSResolveEntry *re = &s->array[i]; if (re->module == m && re->name == name) return i; } return -1; } static int add_resolve_entry(JSContext *ctx, JSResolveState *s, JSModuleDef *m, JSAtom name) { JSResolveEntry *re; if (js_resize_array(ctx, (void **)&s->array, sizeof(JSResolveEntry), &s->size, s->count + 1)) return -1; re = &s->array[s->count++]; re->module = m; re->name = JS_DupAtom(ctx, name); return 0; } typedef enum JSResolveResultEnum { JS_RESOLVE_RES_EXCEPTION = -1, /* memory alloc error */ JS_RESOLVE_RES_FOUND = 0, JS_RESOLVE_RES_NOT_FOUND, JS_RESOLVE_RES_CIRCULAR, JS_RESOLVE_RES_AMBIGUOUS, } JSResolveResultEnum; static JSResolveResultEnum js_resolve_export1(JSContext *ctx, JSModuleDef **pmodule, JSExportEntry **pme, JSModuleDef *m, JSAtom export_name, JSResolveState *s) { JSExportEntry *me; *pmodule = NULL; *pme = NULL; if (find_resolve_entry(s, m, export_name) >= 0) return JS_RESOLVE_RES_CIRCULAR; if (add_resolve_entry(ctx, s, m, export_name) < 0) return JS_RESOLVE_RES_EXCEPTION; me = find_export_entry(ctx, m, export_name); if (me) { if (me->export_type == JS_EXPORT_TYPE_LOCAL) { /* local export */ *pmodule = m; *pme = me; return JS_RESOLVE_RES_FOUND; } else { /* indirect export */ JSModuleDef *m1; m1 = m->req_module_entries[me->u.req_module_idx].module; if (me->local_name == JS_ATOM__star_) { /* export ns from */ *pmodule = m; *pme = me; return JS_RESOLVE_RES_FOUND; } else { return js_resolve_export1(ctx, pmodule, pme, m1, me->local_name, s); } } } else { if (export_name != JS_ATOM_default) { /* not found in direct or indirect exports: try star exports */ int i; for(i = 0; i < m->star_export_entries_count; i++) { JSStarExportEntry *se = &m->star_export_entries[i]; JSModuleDef *m1, *res_m; JSExportEntry *res_me; JSResolveResultEnum ret; m1 = m->req_module_entries[se->req_module_idx].module; ret = js_resolve_export1(ctx, &res_m, &res_me, m1, export_name, s); if (ret == JS_RESOLVE_RES_AMBIGUOUS || ret == JS_RESOLVE_RES_EXCEPTION) { return ret; } else if (ret == JS_RESOLVE_RES_FOUND) { if (*pme != NULL) { if (*pmodule != res_m || res_me->local_name != (*pme)->local_name) { *pmodule = NULL; *pme = NULL; return JS_RESOLVE_RES_AMBIGUOUS; } } else { *pmodule = res_m; *pme = res_me; } } } if (*pme != NULL) return JS_RESOLVE_RES_FOUND; } return JS_RESOLVE_RES_NOT_FOUND; } } /* If the return value is JS_RESOLVE_RES_FOUND, return the module (*pmodule) and the corresponding local export entry (*pme). Otherwise return (NULL, NULL) */ static JSResolveResultEnum js_resolve_export(JSContext *ctx, JSModuleDef **pmodule, JSExportEntry **pme, JSModuleDef *m, JSAtom export_name) { JSResolveState ss, *s = &ss; int i; JSResolveResultEnum ret; s->array = NULL; s->size = 0; s->count = 0; ret = js_resolve_export1(ctx, pmodule, pme, m, export_name, s); for(i = 0; i < s->count; i++) JS_FreeAtom(ctx, s->array[i].name); js_free(ctx, s->array); return ret; } static void js_resolve_export_throw_error(JSContext *ctx, JSResolveResultEnum res, JSModuleDef *m, JSAtom export_name) { char buf1[ATOM_GET_STR_BUF_SIZE]; char buf2[ATOM_GET_STR_BUF_SIZE]; switch(res) { case JS_RESOLVE_RES_EXCEPTION: break; default: case JS_RESOLVE_RES_NOT_FOUND: JS_ThrowSyntaxError(ctx, "Could not find export '%s' in module '%s'", JS_AtomGetStr(ctx, buf1, sizeof(buf1), export_name), JS_AtomGetStr(ctx, buf2, sizeof(buf2), m->module_name)); break; case JS_RESOLVE_RES_CIRCULAR: JS_ThrowSyntaxError(ctx, "circular reference when looking for export '%s' in module '%s'", JS_AtomGetStr(ctx, buf1, sizeof(buf1), export_name), JS_AtomGetStr(ctx, buf2, sizeof(buf2), m->module_name)); break; case JS_RESOLVE_RES_AMBIGUOUS: JS_ThrowSyntaxError(ctx, "export '%s' in module '%s' is ambiguous", JS_AtomGetStr(ctx, buf1, sizeof(buf1), export_name), JS_AtomGetStr(ctx, buf2, sizeof(buf2), m->module_name)); break; } } typedef enum { EXPORTED_NAME_AMBIGUOUS, EXPORTED_NAME_NORMAL, EXPORTED_NAME_DELAYED, } ExportedNameEntryEnum; typedef struct ExportedNameEntry { JSAtom export_name; ExportedNameEntryEnum export_type; union { JSExportEntry *me; /* using when the list is built */ JSVarRef *var_ref; /* EXPORTED_NAME_NORMAL */ } u; } ExportedNameEntry; typedef struct GetExportNamesState { JSModuleDef **modules; int modules_size; int modules_count; ExportedNameEntry *exported_names; int exported_names_size; int exported_names_count; } GetExportNamesState; static int find_exported_name(GetExportNamesState *s, JSAtom name) { int i; for(i = 0; i < s->exported_names_count; i++) { if (s->exported_names[i].export_name == name) return i; } return -1; } static __exception int get_exported_names(JSContext *ctx, GetExportNamesState *s, JSModuleDef *m, BOOL from_star) { ExportedNameEntry *en; int i, j; /* check circular reference */ for(i = 0; i < s->modules_count; i++) { if (s->modules[i] == m) return 0; } if (js_resize_array(ctx, (void **)&s->modules, sizeof(s->modules[0]), &s->modules_size, s->modules_count + 1)) return -1; s->modules[s->modules_count++] = m; for(i = 0; i < m->export_entries_count; i++) { JSExportEntry *me = &m->export_entries[i]; if (from_star && me->export_name == JS_ATOM_default) continue; j = find_exported_name(s, me->export_name); if (j < 0) { if (js_resize_array(ctx, (void **)&s->exported_names, sizeof(s->exported_names[0]), &s->exported_names_size, s->exported_names_count + 1)) return -1; en = &s->exported_names[s->exported_names_count++]; en->export_name = me->export_name; /* avoid a second lookup for simple module exports */ if (from_star || me->export_type != JS_EXPORT_TYPE_LOCAL) en->u.me = NULL; else en->u.me = me; } else { en = &s->exported_names[j]; en->u.me = NULL; } } for(i = 0; i < m->star_export_entries_count; i++) { JSStarExportEntry *se = &m->star_export_entries[i]; JSModuleDef *m1; m1 = m->req_module_entries[se->req_module_idx].module; if (get_exported_names(ctx, s, m1, TRUE)) return -1; } return 0; } /* Unfortunately, the spec gives a different behavior from GetOwnProperty ! */ static int js_module_ns_has(JSContext *ctx, JSValueConst obj, JSAtom atom) { return (find_own_property1(JS_VALUE_GET_OBJ(obj), atom) != NULL); } static const JSClassExoticMethods js_module_ns_exotic_methods = { .has_property = js_module_ns_has, }; static int exported_names_cmp(const void *p1, const void *p2, void *opaque) { JSContext *ctx = opaque; const ExportedNameEntry *me1 = p1; const ExportedNameEntry *me2 = p2; JSValue str1, str2; int ret; /* XXX: should avoid allocation memory in atom comparison */ str1 = JS_AtomToString(ctx, me1->export_name); str2 = JS_AtomToString(ctx, me2->export_name); if (JS_IsException(str1) || JS_IsException(str2)) { /* XXX: raise an error ? */ ret = 0; } else { ret = js_string_compare(ctx, JS_VALUE_GET_STRING(str1), JS_VALUE_GET_STRING(str2)); } JS_FreeValue(ctx, str1); JS_FreeValue(ctx, str2); return ret; } static JSValue js_module_ns_autoinit(JSContext *ctx, JSObject *p, JSAtom atom, void *opaque) { JSModuleDef *m = opaque; JSResolveResultEnum res; JSExportEntry *res_me; JSModuleDef *res_m; JSVarRef *var_ref; res = js_resolve_export(ctx, &res_m, &res_me, m, atom); if (res != JS_RESOLVE_RES_FOUND) { /* fail safe: normally no error should happen here except for memory */ js_resolve_export_throw_error(ctx, res, m, atom); return JS_EXCEPTION; } if (res_me->local_name == JS_ATOM__star_) { return JS_GetModuleNamespace(ctx, res_m->req_module_entries[res_me->u.req_module_idx].module); } else { if (res_me->u.local.var_ref) { var_ref = res_me->u.local.var_ref; } else { JSObject *p1 = JS_VALUE_GET_OBJ(res_m->func_obj); var_ref = p1->u.func.var_refs[res_me->u.local.var_idx]; } /* WARNING: a varref is returned as a string ! */ return JS_MKPTR(JS_TAG_STRING, var_ref); } } static JSValue js_build_module_ns(JSContext *ctx, JSModuleDef *m) { JSValue obj; JSObject *p; GetExportNamesState s_s, *s = &s_s; int i, ret; JSProperty *pr; obj = JS_NewObjectClass(ctx, JS_CLASS_MODULE_NS); if (JS_IsException(obj)) return obj; p = JS_VALUE_GET_OBJ(obj); memset(s, 0, sizeof(*s)); ret = get_exported_names(ctx, s, m, FALSE); js_free(ctx, s->modules); if (ret) goto fail; /* Resolve the exported names. The ambiguous exports are removed */ for(i = 0; i < s->exported_names_count; i++) { ExportedNameEntry *en = &s->exported_names[i]; JSResolveResultEnum res; JSExportEntry *res_me; JSModuleDef *res_m; if (en->u.me) { res_me = en->u.me; /* fast case: no resolution needed */ res_m = m; res = JS_RESOLVE_RES_FOUND; } else { res = js_resolve_export(ctx, &res_m, &res_me, m, en->export_name); } if (res != JS_RESOLVE_RES_FOUND) { if (res != JS_RESOLVE_RES_AMBIGUOUS) { js_resolve_export_throw_error(ctx, res, m, en->export_name); goto fail; } en->export_type = EXPORTED_NAME_AMBIGUOUS; } else { if (res_me->local_name == JS_ATOM__star_) { en->export_type = EXPORTED_NAME_DELAYED; } else { if (res_me->u.local.var_ref) { en->u.var_ref = res_me->u.local.var_ref; } else { JSObject *p1 = JS_VALUE_GET_OBJ(res_m->func_obj); en->u.var_ref = p1->u.func.var_refs[res_me->u.local.var_idx]; } if (en->u.var_ref == NULL) en->export_type = EXPORTED_NAME_DELAYED; else en->export_type = EXPORTED_NAME_NORMAL; } } } /* sort the exported names */ rqsort(s->exported_names, s->exported_names_count, sizeof(s->exported_names[0]), exported_names_cmp, ctx); for(i = 0; i < s->exported_names_count; i++) { ExportedNameEntry *en = &s->exported_names[i]; switch(en->export_type) { case EXPORTED_NAME_NORMAL: { JSVarRef *var_ref = en->u.var_ref; pr = add_property(ctx, p, en->export_name, JS_PROP_ENUMERABLE | JS_PROP_WRITABLE | JS_PROP_VARREF); if (!pr) goto fail; var_ref->header.ref_count++; pr->u.var_ref = var_ref; } break; case EXPORTED_NAME_DELAYED: /* the exported namespace or reference may depend on circular references, so we resolve it lazily */ if (JS_DefineAutoInitProperty(ctx, obj, en->export_name, JS_AUTOINIT_ID_MODULE_NS, m, JS_PROP_ENUMERABLE | JS_PROP_WRITABLE) < 0) goto fail; break; default: break; } } js_free(ctx, s->exported_names); JS_DefinePropertyValue(ctx, obj, JS_ATOM_Symbol_toStringTag, JS_AtomToString(ctx, JS_ATOM_Module), 0); p->extensible = FALSE; return obj; fail: js_free(ctx, s->exported_names); JS_FreeValue(ctx, obj); return JS_EXCEPTION; } JSValue JS_GetModuleNamespace(JSContext *ctx, JSModuleDef *m) { if (JS_IsUndefined(m->module_ns)) { JSValue val; val = js_build_module_ns(ctx, m); if (JS_IsException(val)) return JS_EXCEPTION; m->module_ns = val; } return JS_DupValue(ctx, m->module_ns); } /* Load all the required modules for module 'm' */ static int js_resolve_module(JSContext *ctx, JSModuleDef *m) { int i; JSModuleDef *m1; if (m->resolved) return 0; #ifdef DUMP_MODULE_RESOLVE { char buf1[ATOM_GET_STR_BUF_SIZE]; printf("resolving module '%s':\n", JS_AtomGetStr(ctx, buf1, sizeof(buf1), m->module_name)); } #endif m->resolved = TRUE; /* resolve each requested module */ for(i = 0; i < m->req_module_entries_count; i++) { JSReqModuleEntry *rme = &m->req_module_entries[i]; m1 = js_host_resolve_imported_module_atom(ctx, m->module_name, rme->module_name, rme->attributes); if (!m1) return -1; rme->module = m1; /* already done in js_host_resolve_imported_module() except if the module was loaded with JS_EvalBinary() */ if (js_resolve_module(ctx, m1) < 0) return -1; } return 0; } /* Create the <eval> function associated with the module */ static int js_create_module_bytecode_function(JSContext *ctx, JSModuleDef *m) { JSFunctionBytecode *b; JSValue func_obj, bfunc; bfunc = m->func_obj; func_obj = JS_NewObjectProtoClass(ctx, ctx->function_proto, JS_CLASS_BYTECODE_FUNCTION); if (JS_IsException(func_obj)) return -1; m->func_obj = func_obj; b = JS_VALUE_GET_PTR(bfunc); func_obj = js_closure2(ctx, func_obj, b, NULL, NULL, TRUE, m); if (JS_IsException(func_obj)) { m->func_obj = JS_UNDEFINED; /* XXX: keep it ? */ JS_FreeValue(ctx, func_obj); return -1; } return 0; } /* must be done before js_link_module() because of cyclic references */ static int js_create_module_function(JSContext *ctx, JSModuleDef *m) { BOOL is_c_module; int i; JSVarRef *var_ref; if (m->func_created) return 0; is_c_module = (m->init_func != NULL); if (is_c_module) { /* initialize the exported variables */ for(i = 0; i < m->export_entries_count; i++) { JSExportEntry *me = &m->export_entries[i]; if (me->export_type == JS_EXPORT_TYPE_LOCAL) { var_ref = js_create_var_ref(ctx, FALSE); if (!var_ref) return -1; me->u.local.var_ref = var_ref; } } } else { if (js_create_module_bytecode_function(ctx, m)) return -1; } m->func_created = TRUE; /* do it on the dependencies */ for(i = 0; i < m->req_module_entries_count; i++) { JSReqModuleEntry *rme = &m->req_module_entries[i]; if (js_create_module_function(ctx, rme->module) < 0) return -1; } return 0; } /* Prepare a module to be executed by resolving all the imported variables. */ static int js_inner_module_linking(JSContext *ctx, JSModuleDef *m, JSModuleDef **pstack_top, int index) { int i; JSImportEntry *mi; JSModuleDef *m1; JSVarRef **var_refs, *var_ref; JSObject *p; BOOL is_c_module; JSValue ret_val; if (js_check_stack_overflow(ctx->rt, 0)) { JS_ThrowStackOverflow(ctx); return -1; } #ifdef DUMP_MODULE_RESOLVE { char buf1[ATOM_GET_STR_BUF_SIZE]; printf("js_inner_module_linking '%s':\n", JS_AtomGetStr(ctx, buf1, sizeof(buf1), m->module_name)); } #endif if (m->status == JS_MODULE_STATUS_LINKING || m->status == JS_MODULE_STATUS_LINKED || m->status == JS_MODULE_STATUS_EVALUATING_ASYNC || m->status == JS_MODULE_STATUS_EVALUATED) return index; assert(m->status == JS_MODULE_STATUS_UNLINKED); m->status = JS_MODULE_STATUS_LINKING; m->dfs_index = index; m->dfs_ancestor_index = index; index++; /* push 'm' on stack */ m->stack_prev = *pstack_top; *pstack_top = m; for(i = 0; i < m->req_module_entries_count; i++) { JSReqModuleEntry *rme = &m->req_module_entries[i]; m1 = rme->module; index = js_inner_module_linking(ctx, m1, pstack_top, index); if (index < 0) goto fail; assert(m1->status == JS_MODULE_STATUS_LINKING || m1->status == JS_MODULE_STATUS_LINKED || m1->status == JS_MODULE_STATUS_EVALUATING_ASYNC || m1->status == JS_MODULE_STATUS_EVALUATED); if (m1->status == JS_MODULE_STATUS_LINKING) { m->dfs_ancestor_index = min_int(m->dfs_ancestor_index, m1->dfs_ancestor_index); } } #ifdef DUMP_MODULE_RESOLVE { char buf1[ATOM_GET_STR_BUF_SIZE]; printf("instantiating module '%s':\n", JS_AtomGetStr(ctx, buf1, sizeof(buf1), m->module_name)); } #endif /* check the indirect exports */ for(i = 0; i < m->export_entries_count; i++) { JSExportEntry *me = &m->export_entries[i]; if (me->export_type == JS_EXPORT_TYPE_INDIRECT && me->local_name != JS_ATOM__star_) { JSResolveResultEnum ret; JSExportEntry *res_me; JSModuleDef *res_m, *m1; m1 = m->req_module_entries[me->u.req_module_idx].module; ret = js_resolve_export(ctx, &res_m, &res_me, m1, me->local_name); if (ret != JS_RESOLVE_RES_FOUND) { js_resolve_export_throw_error(ctx, ret, m, me->export_name); goto fail; } } } #ifdef DUMP_MODULE_RESOLVE { printf("exported bindings:\n"); for(i = 0; i < m->export_entries_count; i++) { JSExportEntry *me = &m->export_entries[i]; printf(" name="); print_atom(ctx, me->export_name); printf(" local="); print_atom(ctx, me->local_name); printf(" type=%d idx=%d\n", me->export_type, me->u.local.var_idx); } } #endif is_c_module = (m->init_func != NULL); if (!is_c_module) { p = JS_VALUE_GET_OBJ(m->func_obj); var_refs = p->u.func.var_refs; for(i = 0; i < m->import_entries_count; i++) { mi = &m->import_entries[i]; #ifdef DUMP_MODULE_RESOLVE printf("import var_idx=%d name=", mi->var_idx); print_atom(ctx, mi->import_name); printf(": "); #endif m1 = m->req_module_entries[mi->req_module_idx].module; if (mi->is_star) { JSValue val; /* name space import */ val = JS_GetModuleNamespace(ctx, m1); if (JS_IsException(val)) goto fail; set_value(ctx, &var_refs[mi->var_idx]->value, val); #ifdef DUMP_MODULE_RESOLVE printf("namespace\n"); #endif } else { JSResolveResultEnum ret; JSExportEntry *res_me; JSModuleDef *res_m; JSObject *p1; ret = js_resolve_export(ctx, &res_m, &res_me, m1, mi->import_name); if (ret != JS_RESOLVE_RES_FOUND) { js_resolve_export_throw_error(ctx, ret, m1, mi->import_name); goto fail; } if (res_me->local_name == JS_ATOM__star_) { JSValue val; JSModuleDef *m2; /* name space import from */ m2 = res_m->req_module_entries[res_me->u.req_module_idx].module; val = JS_GetModuleNamespace(ctx, m2); if (JS_IsException(val)) goto fail; var_ref = js_create_var_ref(ctx, TRUE); if (!var_ref) { JS_FreeValue(ctx, val); goto fail; } set_value(ctx, &var_ref->value, val); var_refs[mi->var_idx] = var_ref; #ifdef DUMP_MODULE_RESOLVE printf("namespace from\n"); #endif } else { var_ref = res_me->u.local.var_ref; if (!var_ref) { p1 = JS_VALUE_GET_OBJ(res_m->func_obj); var_ref = p1->u.func.var_refs[res_me->u.local.var_idx]; } var_ref->header.ref_count++; var_refs[mi->var_idx] = var_ref; #ifdef DUMP_MODULE_RESOLVE printf("local export (var_ref=%p)\n", var_ref); #endif } } } /* keep the exported variables in the module export entries (they are used when the eval function is deleted and cannot be initialized before in case imports are exported) */ for(i = 0; i < m->export_entries_count; i++) { JSExportEntry *me = &m->export_entries[i]; if (me->export_type == JS_EXPORT_TYPE_LOCAL) { var_ref = var_refs[me->u.local.var_idx]; var_ref->header.ref_count++; me->u.local.var_ref = var_ref; } } /* initialize the global variables */ ret_val = JS_Call(ctx, m->func_obj, JS_TRUE, 0, NULL); if (JS_IsException(ret_val)) goto fail; JS_FreeValue(ctx, ret_val); } assert(m->dfs_ancestor_index <= m->dfs_index); if (m->dfs_index == m->dfs_ancestor_index) { for(;;) { /* pop m1 from stack */ m1 = *pstack_top; *pstack_top = m1->stack_prev; m1->status = JS_MODULE_STATUS_LINKED; if (m1 == m) break; } } #ifdef DUMP_MODULE_RESOLVE printf("js_inner_module_linking done\n"); #endif return index; fail: return -1; } /* Prepare a module to be executed by resolving all the imported variables. */ static int js_link_module(JSContext *ctx, JSModuleDef *m) { JSModuleDef *stack_top, *m1; #ifdef DUMP_MODULE_RESOLVE { char buf1[ATOM_GET_STR_BUF_SIZE]; printf("js_link_module '%s':\n", JS_AtomGetStr(ctx, buf1, sizeof(buf1), m->module_name)); } #endif assert(m->status == JS_MODULE_STATUS_UNLINKED || m->status == JS_MODULE_STATUS_LINKED || m->status == JS_MODULE_STATUS_EVALUATING_ASYNC || m->status == JS_MODULE_STATUS_EVALUATED); stack_top = NULL; if (js_inner_module_linking(ctx, m, &stack_top, 0) < 0) { while (stack_top != NULL) { m1 = stack_top; assert(m1->status == JS_MODULE_STATUS_LINKING); m1->status = JS_MODULE_STATUS_UNLINKED; stack_top = m1->stack_prev; } return -1; } assert(stack_top == NULL); assert(m->status == JS_MODULE_STATUS_LINKED || m->status == JS_MODULE_STATUS_EVALUATING_ASYNC || m->status == JS_MODULE_STATUS_EVALUATED); return 0; } /* return JS_ATOM_NULL if the name cannot be found. Only works with not striped bytecode functions. */ JSAtom JS_GetScriptOrModuleName(JSContext *ctx, int n_stack_levels) { JSStackFrame *sf; JSFunctionBytecode *b; JSObject *p; /* XXX: currently we just use the filename of the englobing function from the debug info. May need to add a ScriptOrModule info in JSFunctionBytecode. */ sf = ctx->rt->current_stack_frame; if (!sf) return JS_ATOM_NULL; while (n_stack_levels-- > 0) { sf = sf->prev_frame; if (!sf) return JS_ATOM_NULL; } for(;;) { if (JS_VALUE_GET_TAG(sf->cur_func) != JS_TAG_OBJECT) return JS_ATOM_NULL; p = JS_VALUE_GET_OBJ(sf->cur_func); if (!js_class_has_bytecode(p->class_id)) return JS_ATOM_NULL; b = p->u.func.function_bytecode; if (!b->is_direct_or_indirect_eval) { if (!b->has_debug) return JS_ATOM_NULL; return JS_DupAtom(ctx, b->debug.filename); } else { sf = sf->prev_frame; if (!sf) return JS_ATOM_NULL; } } } JSAtom JS_GetModuleName(JSContext *ctx, JSModuleDef *m) { return JS_DupAtom(ctx, m->module_name); } JSValue JS_GetImportMeta(JSContext *ctx, JSModuleDef *m) { JSValue obj; /* allocate meta_obj only if requested to save memory */ obj = m->meta_obj; if (JS_IsUndefined(obj)) { obj = JS_NewObjectProto(ctx, JS_NULL); if (JS_IsException(obj)) return JS_EXCEPTION; m->meta_obj = obj; } return JS_DupValue(ctx, obj); } static JSValue js_import_meta(JSContext *ctx) { JSAtom filename; JSModuleDef *m; filename = JS_GetScriptOrModuleName(ctx, 0); if (filename == JS_ATOM_NULL) goto fail; /* XXX: inefficient, need to add a module or script pointer in JSFunctionBytecode */ m = js_find_loaded_module(ctx, filename); JS_FreeAtom(ctx, filename); if (!m) { fail: JS_ThrowTypeError(ctx, "import.meta not supported in this context"); return JS_EXCEPTION; } return JS_GetImportMeta(ctx, m); } static JSValue JS_NewModuleValue(JSContext *ctx, JSModuleDef *m) { return JS_DupValue(ctx, JS_MKPTR(JS_TAG_MODULE, m)); } static JSValue js_load_module_rejected(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data) { JSValueConst *resolving_funcs = (JSValueConst *)func_data; JSValueConst error; JSValue ret; /* XXX: check if the test is necessary */ if (argc >= 1) error = argv[0]; else error = JS_UNDEFINED; ret = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, 1, &error); JS_FreeValue(ctx, ret); return JS_UNDEFINED; } static JSValue js_load_module_fulfilled(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data) { JSValueConst *resolving_funcs = (JSValueConst *)func_data; JSModuleDef *m = JS_VALUE_GET_PTR(func_data[2]); JSValue ret, ns; /* return the module namespace */ ns = JS_GetModuleNamespace(ctx, m); if (JS_IsException(ns)) { JSValue err = JS_GetException(ctx); js_load_module_rejected(ctx, JS_UNDEFINED, 1, (JSValueConst *)&err, 0, func_data); return JS_UNDEFINED; } ret = JS_Call(ctx, resolving_funcs[0], JS_UNDEFINED, 1, (JSValueConst *)&ns); JS_FreeValue(ctx, ret); JS_FreeValue(ctx, ns); return JS_UNDEFINED; } static void JS_LoadModuleInternal(JSContext *ctx, const char *basename, const char *filename, JSValueConst *resolving_funcs, JSValueConst attributes) { JSValue evaluate_promise; JSModuleDef *m; JSValue ret, err, func_obj, evaluate_resolving_funcs[2]; JSValueConst func_data[3]; m = js_host_resolve_imported_module(ctx, basename, filename, attributes); if (!m) goto fail; if (js_resolve_module(ctx, m) < 0) { js_free_modules(ctx, JS_FREE_MODULE_NOT_RESOLVED); goto fail; } /* Evaluate the module code */ func_obj = JS_NewModuleValue(ctx, m); evaluate_promise = JS_EvalFunction(ctx, func_obj); if (JS_IsException(evaluate_promise)) { fail: err = JS_GetException(ctx); ret = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, 1, (JSValueConst *)&err); JS_FreeValue(ctx, ret); /* XXX: what to do if exception ? */ JS_FreeValue(ctx, err); return; } func_obj = JS_NewModuleValue(ctx, m); func_data[0] = resolving_funcs[0]; func_data[1] = resolving_funcs[1]; func_data[2] = func_obj; evaluate_resolving_funcs[0] = JS_NewCFunctionData(ctx, js_load_module_fulfilled, 0, 0, 3, func_data); evaluate_resolving_funcs[1] = JS_NewCFunctionData(ctx, js_load_module_rejected, 0, 0, 3, func_data); JS_FreeValue(ctx, func_obj); ret = js_promise_then(ctx, evaluate_promise, 2, (JSValueConst *)evaluate_resolving_funcs); JS_FreeValue(ctx, ret); JS_FreeValue(ctx, evaluate_resolving_funcs[0]); JS_FreeValue(ctx, evaluate_resolving_funcs[1]); JS_FreeValue(ctx, evaluate_promise); } /* Return a promise or an exception in case of memory error. Used by os.Worker() */ JSValue JS_LoadModule(JSContext *ctx, const char *basename, const char *filename) { JSValue promise, resolving_funcs[2]; promise = JS_NewPromiseCapability(ctx, resolving_funcs); if (JS_IsException(promise)) return JS_EXCEPTION; JS_LoadModuleInternal(ctx, basename, filename, (JSValueConst *)resolving_funcs, JS_UNDEFINED); JS_FreeValue(ctx, resolving_funcs[0]); JS_FreeValue(ctx, resolving_funcs[1]); return promise; } static JSValue js_dynamic_import_job(JSContext *ctx, int argc, JSValueConst *argv) { JSValueConst *resolving_funcs = argv; JSValueConst basename_val = argv[2]; JSValueConst specifier = argv[3]; JSValueConst attributes = argv[4]; const char *basename = NULL, *filename; JSValue ret, err; if (!JS_IsString(basename_val)) { JS_ThrowTypeError(ctx, "no function filename for import()"); goto exception; } basename = JS_ToCString(ctx, basename_val); if (!basename) goto exception; filename = JS_ToCString(ctx, specifier); if (!filename) goto exception; JS_LoadModuleInternal(ctx, basename, filename, resolving_funcs, attributes); JS_FreeCString(ctx, filename); JS_FreeCString(ctx, basename); return JS_UNDEFINED; exception: err = JS_GetException(ctx); ret = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, 1, (JSValueConst *)&err); JS_FreeValue(ctx, ret); /* XXX: what to do if exception ? */ JS_FreeValue(ctx, err); JS_FreeCString(ctx, basename); return JS_UNDEFINED; } static JSValue js_dynamic_import(JSContext *ctx, JSValueConst specifier, JSValueConst options) { JSAtom basename; JSValue promise, resolving_funcs[2], basename_val, err, ret; JSValue specifier_str = JS_UNDEFINED, attributes = JS_UNDEFINED, attributes_obj = JS_UNDEFINED; JSValueConst args[5]; basename = JS_GetScriptOrModuleName(ctx, 0); if (basename == JS_ATOM_NULL) basename_val = JS_NULL; else basename_val = JS_AtomToValue(ctx, basename); JS_FreeAtom(ctx, basename); if (JS_IsException(basename_val)) return basename_val; promise = JS_NewPromiseCapability(ctx, resolving_funcs); if (JS_IsException(promise)) { JS_FreeValue(ctx, basename_val); return promise; } /* the string conversion must occur here */ specifier_str = JS_ToString(ctx, specifier); if (JS_IsException(specifier_str)) goto exception; if (!JS_IsUndefined(options)) { if (!JS_IsObject(options)) { JS_ThrowTypeError(ctx, "options must be an object"); goto exception; } attributes_obj = JS_GetProperty(ctx, options, JS_ATOM_with); if (JS_IsException(attributes_obj)) goto exception; if (!JS_IsUndefined(attributes_obj)) { JSPropertyEnum *atoms; uint32_t atoms_len, i; JSValue val; if (!JS_IsObject(attributes_obj)) { JS_ThrowTypeError(ctx, "options.with must be an object"); goto exception; } attributes = JS_NewObjectProto(ctx, JS_NULL); if (JS_GetOwnPropertyNamesInternal(ctx, &atoms, &atoms_len, JS_VALUE_GET_OBJ(attributes_obj), JS_GPN_STRING_MASK | JS_GPN_ENUM_ONLY)) { goto exception; } for(i = 0; i < atoms_len; i++) { val = JS_GetProperty(ctx, attributes_obj, atoms[i].atom); if (JS_IsException(val)) goto exception1; if (!JS_IsString(val)) { JS_FreeValue(ctx, val); JS_ThrowTypeError(ctx, "module attribute values must be strings"); goto exception1; } if (JS_DefinePropertyValue(ctx, attributes, atoms[i].atom, val, JS_PROP_C_W_E) < 0) { exception1: JS_FreePropertyEnum(ctx, atoms, atoms_len); goto exception; } } JS_FreePropertyEnum(ctx, atoms, atoms_len); if (ctx->rt->module_check_attrs && ctx->rt->module_check_attrs(ctx, ctx->rt->module_loader_opaque, attributes) < 0) { goto exception; } JS_FreeValue(ctx, attributes_obj); } } args[0] = resolving_funcs[0]; args[1] = resolving_funcs[1]; args[2] = basename_val; args[3] = specifier_str; args[4] = attributes; /* cannot run JS_LoadModuleInternal synchronously because it would cause an unexpected recursion in js_evaluate_module() */ JS_EnqueueJob(ctx, js_dynamic_import_job, 5, args); done: JS_FreeValue(ctx, basename_val); JS_FreeValue(ctx, resolving_funcs[0]); JS_FreeValue(ctx, resolving_funcs[1]); JS_FreeValue(ctx, specifier_str); JS_FreeValue(ctx, attributes); return promise; exception: JS_FreeValue(ctx, attributes_obj); err = JS_GetException(ctx); ret = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, 1, (JSValueConst *)&err); JS_FreeValue(ctx, ret); JS_FreeValue(ctx, err); goto done; } static void js_set_module_evaluated(JSContext *ctx, JSModuleDef *m) { m->status = JS_MODULE_STATUS_EVALUATED; if (!JS_IsUndefined(m->promise)) { JSValue value, ret_val; assert(m->cycle_root == m); value = JS_UNDEFINED; ret_val = JS_Call(ctx, m->resolving_funcs[0], JS_UNDEFINED, 1, (JSValueConst *)&value); JS_FreeValue(ctx, ret_val); } } typedef struct { JSModuleDef **tab; int count; int size; } ExecModuleList; /* XXX: slow. Could use a linked list instead of ExecModuleList */ static BOOL find_in_exec_module_list(ExecModuleList *exec_list, JSModuleDef *m) { int i; for(i = 0; i < exec_list->count; i++) { if (exec_list->tab[i] == m) return TRUE; } return FALSE; } static int gather_available_ancestors(JSContext *ctx, JSModuleDef *module, ExecModuleList *exec_list) { int i; if (js_check_stack_overflow(ctx->rt, 0)) { JS_ThrowStackOverflow(ctx); return -1; } for(i = 0; i < module->async_parent_modules_count; i++) { JSModuleDef *m = module->async_parent_modules[i]; if (!find_in_exec_module_list(exec_list, m) && !m->cycle_root->eval_has_exception) { assert(m->status == JS_MODULE_STATUS_EVALUATING_ASYNC); assert(!m->eval_has_exception); assert(m->async_evaluation); assert(m->pending_async_dependencies > 0); m->pending_async_dependencies--; if (m->pending_async_dependencies == 0) { if (js_resize_array(ctx, (void **)&exec_list->tab, sizeof(exec_list->tab[0]), &exec_list->size, exec_list->count + 1)) { return -1; } exec_list->tab[exec_list->count++] = m; if (!m->has_tla) { if (gather_available_ancestors(ctx, m, exec_list)) return -1; } } } } return 0; } static int exec_module_list_cmp(const void *p1, const void *p2, void *opaque) { JSModuleDef *m1 = *(JSModuleDef **)p1; JSModuleDef *m2 = *(JSModuleDef **)p2; return (m1->async_evaluation_timestamp > m2->async_evaluation_timestamp) - (m1->async_evaluation_timestamp < m2->async_evaluation_timestamp); } static int js_execute_async_module(JSContext *ctx, JSModuleDef *m); static int js_execute_sync_module(JSContext *ctx, JSModuleDef *m, JSValue *pvalue); #ifdef DUMP_MODULE_EXEC static void js_dump_module(JSContext *ctx, const char *str, JSModuleDef *m) { char buf1[ATOM_GET_STR_BUF_SIZE]; static const char *module_status_str[] = { "unlinked", "linking", "linked", "evaluating", "evaluating_async", "evaluated" }; printf("%s: %s status=%s\n", str, JS_AtomGetStr(ctx, buf1, sizeof(buf1), m->module_name), module_status_str[m->status]); } #endif static JSValue js_async_module_execution_rejected(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data) { JSModuleDef *module = JS_VALUE_GET_PTR(func_data[0]); JSValueConst error = argv[0]; int i; #ifdef DUMP_MODULE_EXEC js_dump_module(ctx, __func__, module); #endif if (js_check_stack_overflow(ctx->rt, 0)) return JS_ThrowStackOverflow(ctx); if (module->status == JS_MODULE_STATUS_EVALUATED) { assert(module->eval_has_exception); return JS_UNDEFINED; } assert(module->status == JS_MODULE_STATUS_EVALUATING_ASYNC); assert(!module->eval_has_exception); assert(module->async_evaluation); module->eval_has_exception = TRUE; module->eval_exception = JS_DupValue(ctx, error); module->status = JS_MODULE_STATUS_EVALUATED; module->async_evaluation = FALSE; if (!JS_IsUndefined(module->promise)) { JSValue ret_val; assert(module->cycle_root == module); ret_val = JS_Call(ctx, module->resolving_funcs[1], JS_UNDEFINED, 1, &error); JS_FreeValue(ctx, ret_val); } for(i = 0; i < module->async_parent_modules_count; i++) { JSModuleDef *m = module->async_parent_modules[i]; JSValue m_obj = JS_NewModuleValue(ctx, m); js_async_module_execution_rejected(ctx, JS_UNDEFINED, 1, &error, 0, &m_obj); JS_FreeValue(ctx, m_obj); } return JS_UNDEFINED; } static JSValue js_async_module_execution_fulfilled(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data) { JSModuleDef *module = JS_VALUE_GET_PTR(func_data[0]); ExecModuleList exec_list_s, *exec_list = &exec_list_s; int i; #ifdef DUMP_MODULE_EXEC js_dump_module(ctx, __func__, module); #endif if (module->status == JS_MODULE_STATUS_EVALUATED) { assert(module->eval_has_exception); return JS_UNDEFINED; } assert(module->status == JS_MODULE_STATUS_EVALUATING_ASYNC); assert(!module->eval_has_exception); assert(module->async_evaluation); module->async_evaluation = FALSE; js_set_module_evaluated(ctx, module); exec_list->tab = NULL; exec_list->count = 0; exec_list->size = 0; if (gather_available_ancestors(ctx, module, exec_list) < 0) { js_free(ctx, exec_list->tab); return JS_EXCEPTION; } /* sort by increasing async_evaluation timestamp */ rqsort(exec_list->tab, exec_list->count, sizeof(exec_list->tab[0]), exec_module_list_cmp, NULL); for(i = 0; i < exec_list->count; i++) { JSModuleDef *m = exec_list->tab[i]; #ifdef DUMP_MODULE_EXEC printf(" %d/%d", i, exec_list->count); js_dump_module(ctx, "", m); #endif if (m->status == JS_MODULE_STATUS_EVALUATED) { assert(m->eval_has_exception); } else if (m->has_tla) { js_execute_async_module(ctx, m); } else { JSValue error; if (js_execute_sync_module(ctx, m, &error) < 0) { JSValue m_obj = JS_NewModuleValue(ctx, m); js_async_module_execution_rejected(ctx, JS_UNDEFINED, 1, (JSValueConst *)&error, 0, &m_obj); JS_FreeValue(ctx, m_obj); JS_FreeValue(ctx, error); } else { m->async_evaluation = FALSE; js_set_module_evaluated(ctx, m); } } } js_free(ctx, exec_list->tab); return JS_UNDEFINED; } static int js_execute_async_module(JSContext *ctx, JSModuleDef *m) { JSValue promise, m_obj; JSValue resolve_funcs[2], ret_val; #ifdef DUMP_MODULE_EXEC js_dump_module(ctx, __func__, m); #endif promise = js_async_function_call(ctx, m->func_obj, JS_UNDEFINED, 0, NULL, 0); if (JS_IsException(promise)) return -1; m_obj = JS_NewModuleValue(ctx, m); resolve_funcs[0] = JS_NewCFunctionData(ctx, js_async_module_execution_fulfilled, 0, 0, 1, (JSValueConst *)&m_obj); resolve_funcs[1] = JS_NewCFunctionData(ctx, js_async_module_execution_rejected, 0, 0, 1, (JSValueConst *)&m_obj); ret_val = js_promise_then(ctx, promise, 2, (JSValueConst *)resolve_funcs); JS_FreeValue(ctx, ret_val); JS_FreeValue(ctx, m_obj); JS_FreeValue(ctx, resolve_funcs[0]); JS_FreeValue(ctx, resolve_funcs[1]); JS_FreeValue(ctx, promise); return 0; } /* return < 0 in case of exception. *pvalue contains the exception. */ static int js_execute_sync_module(JSContext *ctx, JSModuleDef *m, JSValue *pvalue) { #ifdef DUMP_MODULE_EXEC js_dump_module(ctx, __func__, m); #endif if (m->init_func) { /* C module init : no asynchronous execution */ if (m->init_func(ctx, m) < 0) goto fail; } else { JSValue promise; JSPromiseStateEnum state; promise = js_async_function_call(ctx, m->func_obj, JS_UNDEFINED, 0, NULL, 0); if (JS_IsException(promise)) goto fail; state = JS_PromiseState(ctx, promise); if (state == JS_PROMISE_FULFILLED) { JS_FreeValue(ctx, promise); } else if (state == JS_PROMISE_REJECTED) { *pvalue = JS_PromiseResult(ctx, promise); JS_FreeValue(ctx, promise); return -1; } else { JS_FreeValue(ctx, promise); JS_ThrowTypeError(ctx, "promise is pending"); fail: *pvalue = JS_GetException(ctx); return -1; } } *pvalue = JS_UNDEFINED; return 0; } /* spec: InnerModuleEvaluation. Return (index, JS_UNDEFINED) or (-1, exception) */ static int js_inner_module_evaluation(JSContext *ctx, JSModuleDef *m, int index, JSModuleDef **pstack_top, JSValue *pvalue) { JSModuleDef *m1; int i; #ifdef DUMP_MODULE_EXEC js_dump_module(ctx, __func__, m); #endif if (js_check_stack_overflow(ctx->rt, 0)) { JS_ThrowStackOverflow(ctx); *pvalue = JS_GetException(ctx); return -1; } if (m->status == JS_MODULE_STATUS_EVALUATING_ASYNC || m->status == JS_MODULE_STATUS_EVALUATED) { if (m->eval_has_exception) { *pvalue = JS_DupValue(ctx, m->eval_exception); return -1; } else { *pvalue = JS_UNDEFINED; return index; } } if (m->status == JS_MODULE_STATUS_EVALUATING) { *pvalue = JS_UNDEFINED; return index; } assert(m->status == JS_MODULE_STATUS_LINKED); m->status = JS_MODULE_STATUS_EVALUATING; m->dfs_index = index; m->dfs_ancestor_index = index; m->pending_async_dependencies = 0; index++; /* push 'm' on stack */ m->stack_prev = *pstack_top; *pstack_top = m; for(i = 0; i < m->req_module_entries_count; i++) { JSReqModuleEntry *rme = &m->req_module_entries[i]; m1 = rme->module; index = js_inner_module_evaluation(ctx, m1, index, pstack_top, pvalue); if (index < 0) return -1; assert(m1->status == JS_MODULE_STATUS_EVALUATING || m1->status == JS_MODULE_STATUS_EVALUATING_ASYNC || m1->status == JS_MODULE_STATUS_EVALUATED); if (m1->status == JS_MODULE_STATUS_EVALUATING) { m->dfs_ancestor_index = min_int(m->dfs_ancestor_index, m1->dfs_ancestor_index); } else { m1 = m1->cycle_root; assert(m1->status == JS_MODULE_STATUS_EVALUATING_ASYNC || m1->status == JS_MODULE_STATUS_EVALUATED); if (m1->eval_has_exception) { *pvalue = JS_DupValue(ctx, m1->eval_exception); return -1; } } if (m1->async_evaluation) { m->pending_async_dependencies++; if (js_resize_array(ctx, (void **)&m1->async_parent_modules, sizeof(m1->async_parent_modules[0]), &m1->async_parent_modules_size, m1->async_parent_modules_count + 1)) { *pvalue = JS_GetException(ctx); return -1; } m1->async_parent_modules[m1->async_parent_modules_count++] = m; } } if (m->pending_async_dependencies > 0) { assert(!m->async_evaluation); m->async_evaluation = TRUE; m->async_evaluation_timestamp = ctx->rt->module_async_evaluation_next_timestamp++; } else if (m->has_tla) { assert(!m->async_evaluation); m->async_evaluation = TRUE; m->async_evaluation_timestamp = ctx->rt->module_async_evaluation_next_timestamp++; js_execute_async_module(ctx, m); } else { if (js_execute_sync_module(ctx, m, pvalue) < 0) return -1; } assert(m->dfs_ancestor_index <= m->dfs_index); if (m->dfs_index == m->dfs_ancestor_index) { for(;;) { /* pop m1 from stack */ m1 = *pstack_top; *pstack_top = m1->stack_prev; if (!m1->async_evaluation) { m1->status = JS_MODULE_STATUS_EVALUATED; } else { m1->status = JS_MODULE_STATUS_EVALUATING_ASYNC; } /* spec bug: cycle_root must be assigned before the test */ m1->cycle_root = m; if (m1 == m) break; } } *pvalue = JS_UNDEFINED; return index; } /* Run the <eval> function of the module and of all its requested modules. Return a promise or an exception. */ static JSValue js_evaluate_module(JSContext *ctx, JSModuleDef *m) { JSModuleDef *m1, *stack_top; JSValue ret_val, result; #ifdef DUMP_MODULE_EXEC js_dump_module(ctx, __func__, m); #endif assert(m->status == JS_MODULE_STATUS_LINKED || m->status == JS_MODULE_STATUS_EVALUATING_ASYNC || m->status == JS_MODULE_STATUS_EVALUATED); if (m->status == JS_MODULE_STATUS_EVALUATING_ASYNC || m->status == JS_MODULE_STATUS_EVALUATED) { m = m->cycle_root; } /* a promise may be created only on the cycle_root of a cycle */ if (!JS_IsUndefined(m->promise)) return JS_DupValue(ctx, m->promise); m->promise = JS_NewPromiseCapability(ctx, m->resolving_funcs); if (JS_IsException(m->promise)) return JS_EXCEPTION; stack_top = NULL; if (js_inner_module_evaluation(ctx, m, 0, &stack_top, &result) < 0) { while (stack_top != NULL) { m1 = stack_top; assert(m1->status == JS_MODULE_STATUS_EVALUATING); m1->status = JS_MODULE_STATUS_EVALUATED; m1->eval_has_exception = TRUE; m1->eval_exception = JS_DupValue(ctx, result); m1->cycle_root = m; /* spec bug: should be present */ stack_top = m1->stack_prev; } JS_FreeValue(ctx, result); assert(m->status == JS_MODULE_STATUS_EVALUATED); assert(m->eval_has_exception); ret_val = JS_Call(ctx, m->resolving_funcs[1], JS_UNDEFINED, 1, (JSValueConst *)&m->eval_exception); JS_FreeValue(ctx, ret_val); } else { #ifdef DUMP_MODULE_EXEC js_dump_module(ctx, " done", m); #endif assert(m->status == JS_MODULE_STATUS_EVALUATING_ASYNC || m->status == JS_MODULE_STATUS_EVALUATED); assert(!m->eval_has_exception); if (!m->async_evaluation) { JSValue value; assert(m->status == JS_MODULE_STATUS_EVALUATED); value = JS_UNDEFINED; ret_val = JS_Call(ctx, m->resolving_funcs[0], JS_UNDEFINED, 1, (JSValueConst *)&value); JS_FreeValue(ctx, ret_val); } assert(stack_top == NULL); } return JS_DupValue(ctx, m->promise); } static __exception int js_parse_with_clause(JSParseState *s, JSReqModuleEntry *rme) { JSContext *ctx = s->ctx; JSAtom key; int ret; const uint8_t *key_token_ptr; if (next_token(s)) return -1; if (js_parse_expect(s, '{')) return -1; while (s->token.val != '}') { key_token_ptr = s->token.ptr; if (s->token.val == TOK_STRING) { key = JS_ValueToAtom(ctx, s->token.u.str.str); if (key == JS_ATOM_NULL) return -1; } else { if (!token_is_ident(s->token.val)) { js_parse_error(s, "identifier expected"); return -1; } key = JS_DupAtom(ctx, s->token.u.ident.atom); } if (next_token(s)) return -1; if (js_parse_expect(s, ':')) { JS_FreeAtom(ctx, key); return -1; } if (s->token.val != TOK_STRING) { js_parse_error_pos(s, key_token_ptr, "string expected"); return -1; } if (JS_IsUndefined(rme->attributes)) { JSValue attributes = JS_NewObjectProto(ctx, JS_NULL); if (JS_IsException(attributes)) { JS_FreeAtom(ctx, key); return -1; } rme->attributes = attributes; } ret = JS_HasProperty(ctx, rme->attributes, key); if (ret != 0) { JS_FreeAtom(ctx, key); if (ret < 0) return -1; else return js_parse_error(s, "duplicate with key"); } ret = JS_DefinePropertyValue(ctx, rme->attributes, key, JS_DupValue(ctx, s->token.u.str.str), JS_PROP_C_W_E); JS_FreeAtom(ctx, key); if (ret < 0) return -1; if (next_token(s)) return -1; if (s->token.val != ',') break; if (next_token(s)) return -1; } if (!JS_IsUndefined(rme->attributes) && ctx->rt->module_check_attrs && ctx->rt->module_check_attrs(ctx, ctx->rt->module_loader_opaque, rme->attributes) < 0) { return -1; } return js_parse_expect(s, '}'); } /* return the module index in m->req_module_entries[] or < 0 if error */ static __exception int js_parse_from_clause(JSParseState *s, JSModuleDef *m) { JSAtom module_name; int idx; if (!token_is_pseudo_keyword(s, JS_ATOM_from)) { js_parse_error(s, "from clause expected"); return -1; } if (next_token(s)) return -1; if (s->token.val != TOK_STRING) { js_parse_error(s, "string expected"); return -1; } module_name = JS_ValueToAtom(s->ctx, s->token.u.str.str); if (module_name == JS_ATOM_NULL) return -1; if (next_token(s)) { JS_FreeAtom(s->ctx, module_name); return -1; } idx = add_req_module_entry(s->ctx, m, module_name); JS_FreeAtom(s->ctx, module_name); if (idx < 0) return -1; if (s->token.val == TOK_WITH) { if (js_parse_with_clause(s, &m->req_module_entries[idx])) return -1; } return idx; } static __exception int js_parse_export(JSParseState *s) { JSContext *ctx = s->ctx; JSModuleDef *m = s->cur_func->module; JSAtom local_name, export_name; int first_export, idx, i, tok; JSExportEntry *me; if (next_token(s)) return -1; tok = s->token.val; if (tok == TOK_CLASS) { return js_parse_class(s, FALSE, JS_PARSE_EXPORT_NAMED); } else if (tok == TOK_FUNCTION || (token_is_pseudo_keyword(s, JS_ATOM_async) && peek_token(s, TRUE) == TOK_FUNCTION)) { return js_parse_function_decl2(s, JS_PARSE_FUNC_STATEMENT, JS_FUNC_NORMAL, JS_ATOM_NULL, s->token.ptr, JS_PARSE_EXPORT_NAMED, NULL); } if (next_token(s)) return -1; switch(tok) { case '{': first_export = m->export_entries_count; while (s->token.val != '}') { if (!token_is_ident(s->token.val)) { js_parse_error(s, "identifier expected"); return -1; } local_name = JS_DupAtom(ctx, s->token.u.ident.atom); export_name = JS_ATOM_NULL; if (next_token(s)) goto fail; if (token_is_pseudo_keyword(s, JS_ATOM_as)) { if (next_token(s)) goto fail; if (s->token.val == TOK_STRING) { if (js_string_find_invalid_codepoint(JS_VALUE_GET_STRING(s->token.u.str.str)) >= 0) { js_parse_error(s, "contains unpaired surrogate"); goto fail; } export_name = JS_ValueToAtom(s->ctx, s->token.u.str.str); if (export_name == JS_ATOM_NULL) goto fail; } else { if (!token_is_ident(s->token.val)) { js_parse_error(s, "identifier expected"); goto fail; } export_name = JS_DupAtom(ctx, s->token.u.ident.atom); } if (next_token(s)) { fail: JS_FreeAtom(ctx, local_name); fail1: JS_FreeAtom(ctx, export_name); return -1; } } else { export_name = JS_DupAtom(ctx, local_name); } me = add_export_entry(s, m, local_name, export_name, JS_EXPORT_TYPE_LOCAL); JS_FreeAtom(ctx, local_name); JS_FreeAtom(ctx, export_name); if (!me) return -1; if (s->token.val != ',') break; if (next_token(s)) return -1; } if (js_parse_expect(s, '}')) return -1; if (token_is_pseudo_keyword(s, JS_ATOM_from)) { idx = js_parse_from_clause(s, m); if (idx < 0) return -1; for(i = first_export; i < m->export_entries_count; i++) { me = &m->export_entries[i]; me->export_type = JS_EXPORT_TYPE_INDIRECT; me->u.req_module_idx = idx; } } break; case '*': if (token_is_pseudo_keyword(s, JS_ATOM_as)) { /* export ns from */ if (next_token(s)) return -1; if (!token_is_ident(s->token.val)) { js_parse_error(s, "identifier expected"); return -1; } export_name = JS_DupAtom(ctx, s->token.u.ident.atom); if (next_token(s)) goto fail1; idx = js_parse_from_clause(s, m); if (idx < 0) goto fail1; me = add_export_entry(s, m, JS_ATOM__star_, export_name, JS_EXPORT_TYPE_INDIRECT); JS_FreeAtom(ctx, export_name); if (!me) return -1; me->u.req_module_idx = idx; } else { idx = js_parse_from_clause(s, m); if (idx < 0) return -1; if (add_star_export_entry(ctx, m, idx) < 0) return -1; } break; case TOK_DEFAULT: if (s->token.val == TOK_CLASS) { return js_parse_class(s, FALSE, JS_PARSE_EXPORT_DEFAULT); } else if (s->token.val == TOK_FUNCTION || (token_is_pseudo_keyword(s, JS_ATOM_async) && peek_token(s, TRUE) == TOK_FUNCTION)) { return js_parse_function_decl2(s, JS_PARSE_FUNC_STATEMENT, JS_FUNC_NORMAL, JS_ATOM_NULL, s->token.ptr, JS_PARSE_EXPORT_DEFAULT, NULL); } else { if (js_parse_assign_expr(s)) return -1; } /* set the name of anonymous functions */ set_object_name(s, JS_ATOM_default); /* store the value in the _default_ global variable and export it */ local_name = JS_ATOM__default_; if (define_var(s, s->cur_func, local_name, JS_VAR_DEF_LET) < 0) return -1; emit_op(s, OP_scope_put_var_init); emit_atom(s, local_name); emit_u16(s, 0); if (!add_export_entry(s, m, local_name, JS_ATOM_default, JS_EXPORT_TYPE_LOCAL)) return -1; break; case TOK_VAR: case TOK_LET: case TOK_CONST: return js_parse_var(s, TRUE, tok, TRUE); default: return js_parse_error(s, "invalid export syntax"); } return js_parse_expect_semi(s); } static int add_closure_var(JSContext *ctx, JSFunctionDef *s, JSClosureTypeEnum closure_type, int var_idx, JSAtom var_name, BOOL is_const, BOOL is_lexical, JSVarKindEnum var_kind); static int add_import(JSParseState *s, JSModuleDef *m, JSAtom local_name, JSAtom import_name, BOOL is_star) { JSContext *ctx = s->ctx; int i, var_idx; JSImportEntry *mi; if (local_name == JS_ATOM_arguments || local_name == JS_ATOM_eval) return js_parse_error(s, "invalid import binding"); if (local_name != JS_ATOM_default) { for (i = 0; i < s->cur_func->closure_var_count; i++) { if (s->cur_func->closure_var[i].var_name == local_name) return js_parse_error(s, "duplicate import binding"); } } var_idx = add_closure_var(ctx, s->cur_func, is_star ? JS_CLOSURE_MODULE_DECL : JS_CLOSURE_MODULE_IMPORT, m->import_entries_count, local_name, TRUE, TRUE, JS_VAR_NORMAL); if (var_idx < 0) return -1; if (js_resize_array(ctx, (void **)&m->import_entries, sizeof(JSImportEntry), &m->import_entries_size, m->import_entries_count + 1)) return -1; mi = &m->import_entries[m->import_entries_count++]; mi->import_name = JS_DupAtom(ctx, import_name); mi->var_idx = var_idx; mi->is_star = is_star; return 0; } static __exception int js_parse_import(JSParseState *s) { JSContext *ctx = s->ctx; JSModuleDef *m = s->cur_func->module; JSAtom local_name, import_name, module_name; int first_import, i, idx; if (next_token(s)) return -1; first_import = m->import_entries_count; if (s->token.val == TOK_STRING) { module_name = JS_ValueToAtom(ctx, s->token.u.str.str); if (module_name == JS_ATOM_NULL) return -1; if (next_token(s)) { JS_FreeAtom(ctx, module_name); return -1; } idx = add_req_module_entry(ctx, m, module_name); JS_FreeAtom(ctx, module_name); if (idx < 0) return -1; if (s->token.val == TOK_WITH) { if (js_parse_with_clause(s, &m->req_module_entries[idx])) return -1; } } else { if (s->token.val == TOK_IDENT) { if (s->token.u.ident.is_reserved) { return js_parse_error_reserved_identifier(s); } /* "default" import */ local_name = JS_DupAtom(ctx, s->token.u.ident.atom); import_name = JS_ATOM_default; if (next_token(s)) goto fail; if (add_import(s, m, local_name, import_name, FALSE)) goto fail; JS_FreeAtom(ctx, local_name); if (s->token.val != ',') goto end_import_clause; if (next_token(s)) return -1; } if (s->token.val == '*') { /* name space import */ if (next_token(s)) return -1; if (!token_is_pseudo_keyword(s, JS_ATOM_as)) return js_parse_error(s, "expecting 'as'"); if (next_token(s)) return -1; if (!token_is_ident(s->token.val)) { js_parse_error(s, "identifier expected"); return -1; } local_name = JS_DupAtom(ctx, s->token.u.ident.atom); import_name = JS_ATOM__star_; if (next_token(s)) goto fail; if (add_import(s, m, local_name, import_name, TRUE)) goto fail; JS_FreeAtom(ctx, local_name); } else if (s->token.val == '{') { if (next_token(s)) return -1; while (s->token.val != '}') { BOOL is_string; if (s->token.val == TOK_STRING) { is_string = TRUE; if (js_string_find_invalid_codepoint(JS_VALUE_GET_STRING(s->token.u.str.str)) >= 0) { js_parse_error(s, "contains unpaired surrogate"); return -1; } import_name = JS_ValueToAtom(s->ctx, s->token.u.str.str); if (import_name == JS_ATOM_NULL) return -1; } else { is_string = FALSE; if (!token_is_ident(s->token.val)) { js_parse_error(s, "identifier expected"); return -1; } import_name = JS_DupAtom(ctx, s->token.u.ident.atom); } local_name = JS_ATOM_NULL; if (next_token(s)) goto fail; if (token_is_pseudo_keyword(s, JS_ATOM_as)) { if (next_token(s)) goto fail; if (!token_is_ident(s->token.val)) { js_parse_error(s, "identifier expected"); goto fail; } local_name = JS_DupAtom(ctx, s->token.u.ident.atom); if (next_token(s)) goto fail; } else { if (is_string) { js_parse_error(s, "expecting 'as'"); fail: JS_FreeAtom(ctx, local_name); JS_FreeAtom(ctx, import_name); return -1; } local_name = JS_DupAtom(ctx, import_name); } if (add_import(s, m, local_name, import_name, FALSE)) goto fail; JS_FreeAtom(ctx, local_name); JS_FreeAtom(ctx, import_name); if (s->token.val != ',') break; if (next_token(s)) return -1; } if (js_parse_expect(s, '}')) return -1; } end_import_clause: idx = js_parse_from_clause(s, m); if (idx < 0) return -1; } for(i = first_import; i < m->import_entries_count; i++) m->import_entries[i].req_module_idx = idx; return js_parse_expect_semi(s); } static __exception int js_parse_source_element(JSParseState *s) { JSFunctionDef *fd = s->cur_func; int tok; if (s->token.val == TOK_FUNCTION || (token_is_pseudo_keyword(s, JS_ATOM_async) && peek_token(s, TRUE) == TOK_FUNCTION)) { if (js_parse_function_decl(s, JS_PARSE_FUNC_STATEMENT, JS_FUNC_NORMAL, JS_ATOM_NULL, s->token.ptr)) return -1; } else if (s->token.val == TOK_EXPORT && fd->module) { if (js_parse_export(s)) return -1; } else if (s->token.val == TOK_IMPORT && fd->module && ((tok = peek_token(s, FALSE)) != '(' && tok != '.')) { /* the peek_token is needed to avoid confusion with ImportCall (dynamic import) or import.meta */ if (js_parse_import(s)) return -1; } else { if (js_parse_statement_or_decl(s, DECL_MASK_ALL)) return -1; } return 0; } static JSFunctionDef *js_new_function_def(JSContext *ctx, JSFunctionDef *parent, BOOL is_eval, BOOL is_func_expr, const char *filename, const uint8_t *source_ptr, GetLineColCache *get_line_col_cache) { JSFunctionDef *fd; fd = js_mallocz(ctx, sizeof(*fd)); if (!fd) return NULL; fd->ctx = ctx; init_list_head(&fd->child_list); /* insert in parent list */ fd->parent = parent; fd->parent_cpool_idx = -1; if (parent) { list_add_tail(&fd->link, &parent->child_list); fd->js_mode = parent->js_mode; fd->parent_scope_level = parent->scope_level; } fd->strip_debug = ((ctx->rt->strip_flags & JS_STRIP_DEBUG) != 0); fd->strip_source = ((ctx->rt->strip_flags & (JS_STRIP_DEBUG | JS_STRIP_SOURCE)) != 0); fd->is_eval = is_eval; fd->is_func_expr = is_func_expr; js_dbuf_bytecode_init(ctx, &fd->byte_code); fd->last_opcode_pos = -1; fd->func_name = JS_ATOM_NULL; fd->var_object_idx = -1; fd->arg_var_object_idx = -1; fd->arguments_var_idx = -1; fd->arguments_arg_idx = -1; fd->func_var_idx = -1; fd->eval_ret_idx = -1; fd->this_var_idx = -1; fd->new_target_var_idx = -1; fd->this_active_func_var_idx = -1; fd->home_object_var_idx = -1; /* XXX: should distinguish arg, var and var object and body scopes */ fd->scopes = fd->def_scope_array; fd->scope_size = countof(fd->def_scope_array); fd->scope_count = 1; fd->scopes[0].first = -1; fd->scopes[0].parent = -1; fd->scope_level = 0; /* 0: var/arg scope */ fd->scope_first = -1; fd->body_scope = -1; fd->filename = JS_NewAtom(ctx, filename); fd->source_pos = source_ptr - get_line_col_cache->buf_start; fd->get_line_col_cache = get_line_col_cache; js_dbuf_init(ctx, &fd->pc2line); //fd->pc2line_last_line_num = line_num; //fd->pc2line_last_pc = 0; fd->last_opcode_source_ptr = source_ptr; return fd; } static void free_bytecode_atoms(JSRuntime *rt, const uint8_t *bc_buf, int bc_len, BOOL use_short_opcodes) { int pos, len, op; JSAtom atom; const JSOpCode *oi; pos = 0; while (pos < bc_len) { op = bc_buf[pos]; if (use_short_opcodes) oi = &short_opcode_info(op); else oi = &opcode_info[op]; len = oi->size; switch(oi->fmt) { case OP_FMT_atom: case OP_FMT_atom_u8: case OP_FMT_atom_u16: case OP_FMT_atom_label_u8: case OP_FMT_atom_label_u16: if ((pos + 1 + 4) > bc_len) break; /* may happen if there is not enough memory when emiting bytecode */ atom = get_u32(bc_buf + pos + 1); JS_FreeAtomRT(rt, atom); break; default: break; } pos += len; } } static void js_free_function_def(JSContext *ctx, JSFunctionDef *fd) { int i; struct list_head *el, *el1; /* free the child functions */ list_for_each_safe(el, el1, &fd->child_list) { JSFunctionDef *fd1; fd1 = list_entry(el, JSFunctionDef, link); js_free_function_def(ctx, fd1); } free_bytecode_atoms(ctx->rt, fd->byte_code.buf, fd->byte_code.size, fd->use_short_opcodes); dbuf_free(&fd->byte_code); js_free(ctx, fd->jump_slots); js_free(ctx, fd->label_slots); js_free(ctx, fd->line_number_slots); for(i = 0; i < fd->cpool_count; i++) { JS_FreeValue(ctx, fd->cpool[i]); } js_free(ctx, fd->cpool); JS_FreeAtom(ctx, fd->func_name); for(i = 0; i < fd->var_count; i++) { JS_FreeAtom(ctx, fd->vars[i].var_name); } js_free(ctx, fd->vars); for(i = 0; i < fd->arg_count; i++) { JS_FreeAtom(ctx, fd->args[i].var_name); } js_free(ctx, fd->args); for(i = 0; i < fd->global_var_count; i++) { JS_FreeAtom(ctx, fd->global_vars[i].var_name); } js_free(ctx, fd->global_vars); for(i = 0; i < fd->closure_var_count; i++) { JSClosureVar *cv = &fd->closure_var[i]; JS_FreeAtom(ctx, cv->var_name); } js_free(ctx, fd->closure_var); if (fd->scopes != fd->def_scope_array) js_free(ctx, fd->scopes); JS_FreeAtom(ctx, fd->filename); dbuf_free(&fd->pc2line); js_free(ctx, fd->source); if (fd->parent) { /* remove in parent list */ list_del(&fd->link); } js_free(ctx, fd); } #ifdef DUMP_BYTECODE static const char *skip_lines(const char *p, int n) { while (n-- > 0 && *p) { while (*p && *p++ != '\n') continue; } return p; } static void print_lines(const char *source, int line, int line1) { const char *s = source; const char *p = skip_lines(s, line); if (*p) { while (line++ < line1) { p = skip_lines(s = p, 1); printf(";; %.*s", (int)(p - s), s); if (!*p) { if (p[-1] != '\n') printf("\n"); break; } } } } static void dump_byte_code(JSContext *ctx, int pass, const uint8_t *tab, int len, const JSBytecodeVarDef *vardefs, const JSVarDef *args, int arg_count, const JSVarDef *vars, int var_count, const JSClosureVar *closure_var, int closure_var_count, const JSValue *cpool, uint32_t cpool_count, const char *source, const LabelSlot *label_slots, JSFunctionBytecode *b) { const JSOpCode *oi; int pos, pos_next, op, size, idx, addr, line, line1, in_source, line_num; uint8_t *bits = js_mallocz(ctx, len * sizeof(*bits)); BOOL use_short_opcodes = (b != NULL); if (b) { int col_num; line_num = find_line_num(ctx, b, -1, &col_num); } /* scan for jump targets */ for (pos = 0; pos < len; pos = pos_next) { op = tab[pos]; if (use_short_opcodes) oi = &short_opcode_info(op); else oi = &opcode_info[op]; pos_next = pos + oi->size; if (op < OP_COUNT) { switch (oi->fmt) { #if SHORT_OPCODES case OP_FMT_label8: pos++; addr = (int8_t)tab[pos]; goto has_addr; case OP_FMT_label16: pos++; addr = (int16_t)get_u16(tab + pos); goto has_addr; #endif case OP_FMT_atom_label_u8: case OP_FMT_atom_label_u16: pos += 4; /* fall thru */ case OP_FMT_label: case OP_FMT_label_u16: pos++; addr = get_u32(tab + pos); goto has_addr; has_addr: if (pass == 1) addr = label_slots[addr].pos; if (pass == 2) addr = label_slots[addr].pos2; if (pass == 3) addr += pos; if (addr >= 0 && addr < len) bits[addr] |= 1; break; } } } in_source = 0; if (source) { /* Always print first line: needed if single line */ print_lines(source, 0, 1); in_source = 1; } line1 = line = 1; pos = 0; while (pos < len) { op = tab[pos]; if (source && b) { int col_num; if (b) { line1 = find_line_num(ctx, b, pos, &col_num) - line_num + 1; } else if (op == OP_line_num) { /* XXX: no longer works */ line1 = get_u32(tab + pos + 1) - line_num + 1; } if (line1 > line) { if (!in_source) printf("\n"); in_source = 1; print_lines(source, line, line1); line = line1; //bits[pos] |= 2; } } if (in_source) printf("\n"); in_source = 0; if (op >= OP_COUNT) { printf("invalid opcode (0x%02x)\n", op); pos++; continue; } if (use_short_opcodes) oi = &short_opcode_info(op); else oi = &opcode_info[op]; size = oi->size; if (pos + size > len) { printf("truncated opcode (0x%02x)\n", op); break; } #if defined(DUMP_BYTECODE) && (DUMP_BYTECODE & 16) { int i, x, x0; x = x0 = printf("%5d ", pos); for (i = 0; i < size; i++) { if (i == 6) { printf("\n%*s", x = x0, ""); } x += printf(" %02X", tab[pos + i]); } printf("%*s", x0 + 20 - x, ""); } #endif if (bits[pos]) { printf("%5d: ", pos); } else { printf(" "); } printf("%s", oi->name); pos++; switch(oi->fmt) { case OP_FMT_none_int: printf(" %d", op - OP_push_0); break; case OP_FMT_npopx: printf(" %d", op - OP_call0); break; case OP_FMT_u8: printf(" %u", get_u8(tab + pos)); break; case OP_FMT_i8: printf(" %d", get_i8(tab + pos)); break; case OP_FMT_u16: case OP_FMT_npop: printf(" %u", get_u16(tab + pos)); break; case OP_FMT_npop_u16: printf(" %u,%u", get_u16(tab + pos), get_u16(tab + pos + 2)); break; case OP_FMT_i16: printf(" %d", get_i16(tab + pos)); break; case OP_FMT_i32: printf(" %d", get_i32(tab + pos)); break; case OP_FMT_u32: printf(" %u", get_u32(tab + pos)); break; #if SHORT_OPCODES case OP_FMT_label8: addr = get_i8(tab + pos); goto has_addr1; case OP_FMT_label16: addr = get_i16(tab + pos); goto has_addr1; #endif case OP_FMT_label: addr = get_u32(tab + pos); goto has_addr1; has_addr1: if (pass == 1) printf(" %u:%u", addr, label_slots[addr].pos); if (pass == 2) printf(" %u:%u", addr, label_slots[addr].pos2); if (pass == 3) printf(" %u", addr + pos); break; case OP_FMT_label_u16: addr = get_u32(tab + pos); if (pass == 1) printf(" %u:%u", addr, label_slots[addr].pos); if (pass == 2) printf(" %u:%u", addr, label_slots[addr].pos2); if (pass == 3) printf(" %u", addr + pos); printf(",%u", get_u16(tab + pos + 4)); break; #if SHORT_OPCODES case OP_FMT_const8: idx = get_u8(tab + pos); goto has_pool_idx; #endif case OP_FMT_const: idx = get_u32(tab + pos); goto has_pool_idx; has_pool_idx: printf(" %u: ", idx); if (idx < cpool_count) { JS_PrintValue(ctx, js_dump_value_write, stdout, cpool[idx], NULL); } break; case OP_FMT_atom: printf(" "); print_atom(ctx, get_u32(tab + pos)); break; case OP_FMT_atom_u8: printf(" "); print_atom(ctx, get_u32(tab + pos)); printf(",%d", get_u8(tab + pos + 4)); break; case OP_FMT_atom_u16: printf(" "); print_atom(ctx, get_u32(tab + pos)); printf(",%d", get_u16(tab + pos + 4)); break; case OP_FMT_atom_label_u8: case OP_FMT_atom_label_u16: printf(" "); print_atom(ctx, get_u32(tab + pos)); addr = get_u32(tab + pos + 4); if (pass == 1) printf(",%u:%u", addr, label_slots[addr].pos); if (pass == 2) printf(",%u:%u", addr, label_slots[addr].pos2); if (pass == 3) printf(",%u", addr + pos + 4); if (oi->fmt == OP_FMT_atom_label_u8) printf(",%u", get_u8(tab + pos + 8)); else printf(",%u", get_u16(tab + pos + 8)); break; case OP_FMT_none_loc: idx = (op - OP_get_loc0) % 4; goto has_loc; case OP_FMT_loc8: idx = get_u8(tab + pos); goto has_loc; case OP_FMT_loc: idx = get_u16(tab + pos); has_loc: printf(" %d: ", idx); if (idx < var_count) { print_atom(ctx, vars ? vars[idx].var_name : vardefs[arg_count + idx].var_name); } break; case OP_FMT_none_arg: idx = (op - OP_get_arg0) % 4; goto has_arg; case OP_FMT_arg: idx = get_u16(tab + pos); has_arg: printf(" %d: ", idx); if (idx < arg_count) { print_atom(ctx, args ? args[idx].var_name : vardefs[idx].var_name); } break; case OP_FMT_none_var_ref: idx = (op - OP_get_var_ref0) % 4; goto has_var_ref; case OP_FMT_var_ref: idx = get_u16(tab + pos); has_var_ref: printf(" %d: ", idx); if (idx < closure_var_count) { print_atom(ctx, closure_var[idx].var_name); } break; default: break; } printf("\n"); pos += oi->size - 1; } if (source) { if (!in_source) printf("\n"); print_lines(source, line, INT32_MAX); } js_free(ctx, bits); } static __maybe_unused void dump_pc2line(JSContext *ctx, const uint8_t *buf, int len) { const uint8_t *p_end, *p; int pc, v, line_num, col_num, ret; unsigned int op; uint32_t val; if (len <= 0) return; printf("%5s %5s %5s\n", "PC", "LINE", "COL"); p = buf; p_end = buf + len; /* get the function line and column numbers */ ret = get_leb128(&val, p, p_end); if (ret < 0) goto fail; p += ret; line_num = val + 1; ret = get_leb128(&val, p, p_end); if (ret < 0) goto fail; p += ret; col_num = val + 1; printf("%5s %5d %5d\n", "-", line_num, col_num); pc = 0; while (p < p_end) { op = *p++; if (op == 0) { ret = get_leb128(&val, p, p_end); if (ret < 0) goto fail; pc += val; p += ret; ret = get_sleb128(&v, p, p_end); if (ret < 0) goto fail; p += ret; line_num += v; } else { op -= PC2LINE_OP_FIRST; pc += (op / PC2LINE_RANGE); line_num += (op % PC2LINE_RANGE) + PC2LINE_BASE; } ret = get_sleb128(&v, p, p_end); if (ret < 0) goto fail; p += ret; col_num += v; printf("%5d %5d %5d\n", pc, line_num, col_num); } fail: ; } static __maybe_unused void js_dump_function_bytecode(JSContext *ctx, JSFunctionBytecode *b) { int i; char atom_buf[ATOM_GET_STR_BUF_SIZE]; const char *str; if (b->has_debug && b->debug.filename != JS_ATOM_NULL) { int line_num, col_num; str = JS_AtomGetStr(ctx, atom_buf, sizeof(atom_buf), b->debug.filename); line_num = find_line_num(ctx, b, -1, &col_num); printf("%s:%d:%d: ", str, line_num, col_num); } str = JS_AtomGetStr(ctx, atom_buf, sizeof(atom_buf), b->func_name); printf("function: %s%s\n", &"*"[b->func_kind != JS_FUNC_GENERATOR], str); if (b->js_mode) { printf(" mode:"); if (b->js_mode & JS_MODE_STRICT) printf(" strict"); printf("\n"); } if (b->arg_count && b->vardefs) { printf(" args:"); for(i = 0; i < b->arg_count; i++) { printf(" %s", JS_AtomGetStr(ctx, atom_buf, sizeof(atom_buf), b->vardefs[i].var_name)); } printf("\n"); } if (b->var_count && b->vardefs) { printf(" locals:\n"); for(i = 0; i < b->var_count; i++) { JSBytecodeVarDef *vd = &b->vardefs[b->arg_count + i]; printf("%5d: %s %s", i, vd->var_kind == JS_VAR_CATCH ? "catch" : (vd->var_kind == JS_VAR_FUNCTION_DECL || vd->var_kind == JS_VAR_NEW_FUNCTION_DECL) ? "function" : vd->is_const ? "const" : vd->is_lexical ? "let" : "var", JS_AtomGetStr(ctx, atom_buf, sizeof(atom_buf), vd->var_name)); if (vd->has_scope) printf(" [next:%d]", vd->scope_next); printf("\n"); } } if (b->closure_var_count) { printf(" closure vars:\n"); for(i = 0; i < b->closure_var_count; i++) { JSClosureVar *cv = &b->closure_var[i]; printf("%5d: %s %s", i, cv->is_const ? "const" : cv->is_lexical ? "let" : "var", JS_AtomGetStr(ctx, atom_buf, sizeof(atom_buf), cv->var_name)); switch(cv->closure_type) { case JS_CLOSURE_LOCAL: printf(" [loc%d]\n", cv->var_idx); break; case JS_CLOSURE_ARG: printf(" [arg%d]\n", cv->var_idx); break; case JS_CLOSURE_REF: printf(" [ref%d]\n", cv->var_idx); break; case JS_CLOSURE_GLOBAL_REF: printf(" [global_ref%d]\n", cv->var_idx); break; case JS_CLOSURE_GLOBAL_DECL: printf(" [global_decl]\n"); break; case JS_CLOSURE_GLOBAL: printf(" [global]\n"); break; case JS_CLOSURE_MODULE_DECL: printf(" [module_decl]\n"); break; case JS_CLOSURE_MODULE_IMPORT: printf(" [module_import]\n"); break; default: printf(" [?]\n"); break; } } } printf(" stack_size: %d\n", b->stack_size); printf(" var_ref_count: %d\n", b->var_ref_count); printf(" opcodes:\n"); dump_byte_code(ctx, 3, b->byte_code_buf, b->byte_code_len, b->vardefs, NULL, b->arg_count, NULL, b->var_count, b->closure_var, b->closure_var_count, b->cpool, b->cpool_count, b->has_debug ? b->debug.source : NULL, NULL, b); #if defined(DUMP_BYTECODE) && (DUMP_BYTECODE & 32) if (b->has_debug) dump_pc2line(ctx, b->debug.pc2line_buf, b->debug.pc2line_len); #endif printf("\n"); } #endif static int add_closure_var(JSContext *ctx, JSFunctionDef *s, JSClosureTypeEnum closure_type, int var_idx, JSAtom var_name, BOOL is_const, BOOL is_lexical, JSVarKindEnum var_kind) { JSClosureVar *cv; /* the closure variable indexes are currently stored on 16 bits */ if (s->closure_var_count >= JS_MAX_LOCAL_VARS) { JS_ThrowInternalError(ctx, "too many closure variables"); return -1; } if (js_resize_array(ctx, (void **)&s->closure_var, sizeof(s->closure_var[0]), &s->closure_var_size, s->closure_var_count + 1)) return -1; cv = &s->closure_var[s->closure_var_count++]; cv->closure_type = closure_type; cv->is_const = is_const; cv->is_lexical = is_lexical; cv->var_kind = var_kind; cv->var_idx = var_idx; cv->var_name = JS_DupAtom(ctx, var_name); return s->closure_var_count - 1; } static int find_closure_var(JSContext *ctx, JSFunctionDef *s, JSAtom var_name) { int i; for(i = 0; i < s->closure_var_count; i++) { JSClosureVar *cv = &s->closure_var[i]; if (cv->var_name == var_name) return i; } return -1; } /* 'fd' must be a parent of 's'. Create in 's' a closure referencing another one in 'fd' */ static int get_closure_var(JSContext *ctx, JSFunctionDef *s, JSFunctionDef *fd, JSClosureTypeEnum closure_type, int var_idx, JSAtom var_name, BOOL is_const, BOOL is_lexical, JSVarKindEnum var_kind) { int i; if (fd != s->parent) { var_idx = get_closure_var(ctx, s->parent, fd, closure_type, var_idx, var_name, is_const, is_lexical, var_kind); if (var_idx < 0) return -1; if (closure_type != JS_CLOSURE_GLOBAL_REF) closure_type = JS_CLOSURE_REF; } for(i = 0; i < s->closure_var_count; i++) { JSClosureVar *cv = &s->closure_var[i]; if (cv->var_idx == var_idx && cv->closure_type == closure_type) return i; } return add_closure_var(ctx, s, closure_type, var_idx, var_name, is_const, is_lexical, var_kind); } static int get_with_scope_opcode(int op) { if (op == OP_scope_get_var_undef) return OP_with_get_var; else return OP_with_get_var + (op - OP_scope_get_var); } static BOOL can_opt_put_ref_value(const uint8_t *bc_buf, int pos) { int opcode = bc_buf[pos]; return (bc_buf[pos + 1] == OP_put_ref_value && (opcode == OP_insert3 || opcode == OP_perm4 || opcode == OP_nop || opcode == OP_rot3l)); } static BOOL can_opt_put_global_ref_value(const uint8_t *bc_buf, int pos) { int opcode = bc_buf[pos]; return (bc_buf[pos + 1] == OP_put_ref_value && (opcode == OP_insert3 || opcode == OP_perm4 || opcode == OP_nop || opcode == OP_rot3l)); } static int optimize_scope_make_ref(JSContext *ctx, JSFunctionDef *s, DynBuf *bc, uint8_t *bc_buf, LabelSlot *ls, int pos_next, int get_op, int var_idx) { int label_pos, end_pos, pos; /* XXX: should optimize `loc(a) += expr` as `expr add_loc(a)` but only if expr does not modify `a`. should scan the code between pos_next and label_pos for operations that can potentially change `a`: OP_scope_make_ref(a), function calls, jumps and gosub. */ /* replace the reference get/put with normal variable accesses */ if (bc_buf[pos_next] == OP_get_ref_value) { dbuf_putc(bc, get_op); dbuf_put_u16(bc, var_idx); pos_next++; } /* remove the OP_label to make room for replacement */ /* label should have a refcount of 0 anyway */ /* XXX: should avoid this patch by inserting nops in phase 1 */ label_pos = ls->pos; pos = label_pos - 5; assert(bc_buf[pos] == OP_label); /* label points to an instruction pair: - insert3 / put_ref_value - perm4 / put_ref_value - rot3l / put_ref_value - nop / put_ref_value */ end_pos = label_pos + 2; if (bc_buf[label_pos] == OP_insert3) bc_buf[pos++] = OP_dup; bc_buf[pos] = get_op + 1; put_u16(bc_buf + pos + 1, var_idx); pos += 3; /* pad with OP_nop */ while (pos < end_pos) bc_buf[pos++] = OP_nop; return pos_next; } static int add_var_this(JSContext *ctx, JSFunctionDef *fd) { int idx; idx = add_var(ctx, fd, JS_ATOM_this); if (idx >= 0 && fd->is_derived_class_constructor) { JSVarDef *vd = &fd->vars[idx]; /* XXX: should have is_this flag or var type */ vd->is_lexical = 1; /* used to trigger 'uninitialized' checks in a derived class constructor */ } return idx; } static int resolve_pseudo_var(JSContext *ctx, JSFunctionDef *s, JSAtom var_name) { int var_idx; if (!s->has_this_binding) return -1; switch(var_name) { case JS_ATOM_home_object: /* 'home_object' pseudo variable */ if (s->home_object_var_idx < 0) s->home_object_var_idx = add_var(ctx, s, var_name); var_idx = s->home_object_var_idx; break; case JS_ATOM_this_active_func: /* 'this.active_func' pseudo variable */ if (s->this_active_func_var_idx < 0) s->this_active_func_var_idx = add_var(ctx, s, var_name); var_idx = s->this_active_func_var_idx; break; case JS_ATOM_new_target: /* 'new.target' pseudo variable */ if (s->new_target_var_idx < 0) s->new_target_var_idx = add_var(ctx, s, var_name); var_idx = s->new_target_var_idx; break; case JS_ATOM_this: /* 'this' pseudo variable */ if (s->this_var_idx < 0) s->this_var_idx = add_var_this(ctx, s); var_idx = s->this_var_idx; break; default: var_idx = -1; break; } return var_idx; } /* test if 'var_name' is in the variable object on the stack. If is it the case, handle it and jump to 'label_done' */ static void var_object_test(JSContext *ctx, JSFunctionDef *s, JSAtom var_name, int op, DynBuf *bc, int *plabel_done, BOOL is_with) { dbuf_putc(bc, get_with_scope_opcode(op)); dbuf_put_u32(bc, JS_DupAtom(ctx, var_name)); if (*plabel_done < 0) { *plabel_done = new_label_fd(s); if (*plabel_done < 0) { dbuf_set_error(bc); return; } } dbuf_put_u32(bc, *plabel_done); dbuf_putc(bc, is_with); update_label(s, *plabel_done, 1); s->jump_size++; } static inline void capture_var(JSFunctionDef *s, JSVarDef *vd) { if (!vd->is_captured) { vd->is_captured = 1; vd->var_ref_idx = s->var_ref_count++; } } /* return the position of the next opcode or -1 if error */ static int resolve_scope_var(JSContext *ctx, JSFunctionDef *s, JSAtom var_name, int scope_level, int op, DynBuf *bc, uint8_t *bc_buf, LabelSlot *ls, int pos_next) { int idx, var_idx, is_put; int label_done; JSFunctionDef *fd; JSVarDef *vd; BOOL is_pseudo_var, is_arg_scope; label_done = -1; /* XXX: could be simpler to use a specific function to resolve the pseudo variables */ is_pseudo_var = (var_name == JS_ATOM_home_object || var_name == JS_ATOM_this_active_func || var_name == JS_ATOM_new_target || var_name == JS_ATOM_this); /* resolve local scoped variables */ var_idx = -1; for (idx = s->scopes[scope_level].first; idx >= 0;) { vd = &s->vars[idx]; if (vd->var_name == var_name) { if (op == OP_scope_put_var || op == OP_scope_make_ref) { if (vd->is_const) { dbuf_putc(bc, OP_throw_error); dbuf_put_u32(bc, JS_DupAtom(ctx, var_name)); dbuf_putc(bc, JS_THROW_VAR_RO); goto done; } } var_idx = idx; break; } else if (vd->var_name == JS_ATOM__with_ && !is_pseudo_var) { dbuf_putc(bc, OP_get_loc); dbuf_put_u16(bc, idx); var_object_test(ctx, s, var_name, op, bc, &label_done, 1); } idx = vd->scope_next; } is_arg_scope = (idx == ARG_SCOPE_END); if (var_idx < 0) { /* argument scope: variables are not visible but pseudo variables are visible */ if (!is_arg_scope) { var_idx = find_var(ctx, s, var_name); } if (var_idx < 0 && is_pseudo_var) var_idx = resolve_pseudo_var(ctx, s, var_name); if (var_idx < 0 && var_name == JS_ATOM_arguments && s->has_arguments_binding) { /* 'arguments' pseudo variable */ var_idx = add_arguments_var(ctx, s); } if (var_idx < 0 && s->is_func_expr && var_name == s->func_name) { /* add a new variable with the function name */ var_idx = add_func_var(ctx, s, var_name); } } if (var_idx >= 0) { if ((op == OP_scope_put_var || op == OP_scope_make_ref) && !(var_idx & ARGUMENT_VAR_OFFSET) && s->vars[var_idx].is_const) { /* only happens when assigning a function expression name in strict mode */ dbuf_putc(bc, OP_throw_error); dbuf_put_u32(bc, JS_DupAtom(ctx, var_name)); dbuf_putc(bc, JS_THROW_VAR_RO); goto done; } /* OP_scope_put_var_init is only used to initialize a lexical variable, so it is never used in a with or var object. It can be used with a closure (module global variable case). */ switch (op) { case OP_scope_make_ref: if (!(var_idx & ARGUMENT_VAR_OFFSET) && s->vars[var_idx].var_kind == JS_VAR_FUNCTION_NAME) { /* Create a dummy object reference for the func_var */ dbuf_putc(bc, OP_object); dbuf_putc(bc, OP_get_loc); dbuf_put_u16(bc, var_idx); dbuf_putc(bc, OP_define_field); dbuf_put_u32(bc, JS_DupAtom(ctx, var_name)); dbuf_putc(bc, OP_push_atom_value); dbuf_put_u32(bc, JS_DupAtom(ctx, var_name)); } else if (label_done == -1 && can_opt_put_ref_value(bc_buf, ls->pos)) { int get_op; if (var_idx & ARGUMENT_VAR_OFFSET) { get_op = OP_get_arg; var_idx -= ARGUMENT_VAR_OFFSET; } else { if (s->vars[var_idx].is_lexical) get_op = OP_get_loc_check; else get_op = OP_get_loc; } pos_next = optimize_scope_make_ref(ctx, s, bc, bc_buf, ls, pos_next, get_op, var_idx); } else { /* Create a dummy object with a named slot that is a reference to the local variable */ if (var_idx & ARGUMENT_VAR_OFFSET) { capture_var(s, &s->args[var_idx - ARGUMENT_VAR_OFFSET]); dbuf_putc(bc, OP_make_arg_ref); dbuf_put_u32(bc, JS_DupAtom(ctx, var_name)); dbuf_put_u16(bc, var_idx - ARGUMENT_VAR_OFFSET); } else { capture_var(s, &s->vars[var_idx]); dbuf_putc(bc, OP_make_loc_ref); dbuf_put_u32(bc, JS_DupAtom(ctx, var_name)); dbuf_put_u16(bc, var_idx); } } break; case OP_scope_put_var: if (!(var_idx & ARGUMENT_VAR_OFFSET) && s->vars[var_idx].var_kind == JS_VAR_FUNCTION_NAME) { /* in non strict mode, modifying the function name is ignored */ dbuf_putc(bc, OP_drop); goto done; } goto local_scope_var; case OP_scope_get_ref: dbuf_putc(bc, OP_undefined); goto local_scope_var; case OP_scope_get_var_checkthis: case OP_scope_get_var_undef: case OP_scope_get_var: case OP_scope_put_var_init: local_scope_var: is_put = (op == OP_scope_put_var || op == OP_scope_put_var_init); if (var_idx & ARGUMENT_VAR_OFFSET) { dbuf_putc(bc, OP_get_arg + is_put); dbuf_put_u16(bc, var_idx - ARGUMENT_VAR_OFFSET); } else { if (is_put) { if (s->vars[var_idx].is_lexical) { if (op == OP_scope_put_var_init) { /* 'this' can only be initialized once */ if (var_name == JS_ATOM_this) dbuf_putc(bc, OP_put_loc_check_init); else dbuf_putc(bc, OP_put_loc); } else { dbuf_putc(bc, OP_put_loc_check); } } else { dbuf_putc(bc, OP_put_loc); } } else { if (s->vars[var_idx].is_lexical) { if (op == OP_scope_get_var_checkthis) { /* only used for 'this' return in derived class constructors */ dbuf_putc(bc, OP_get_loc_checkthis); } else { dbuf_putc(bc, OP_get_loc_check); } } else { dbuf_putc(bc, OP_get_loc); } } dbuf_put_u16(bc, var_idx); } break; case OP_scope_delete_var: dbuf_putc(bc, OP_push_false); break; } goto done; } /* check eval object */ if (!is_arg_scope && s->var_object_idx >= 0 && !is_pseudo_var) { dbuf_putc(bc, OP_get_loc); dbuf_put_u16(bc, s->var_object_idx); var_object_test(ctx, s, var_name, op, bc, &label_done, 0); } /* check eval object in argument scope */ if (s->arg_var_object_idx >= 0 && !is_pseudo_var) { dbuf_putc(bc, OP_get_loc); dbuf_put_u16(bc, s->arg_var_object_idx); var_object_test(ctx, s, var_name, op, bc, &label_done, 0); } /* check parent scopes */ for (fd = s; fd->parent;) { scope_level = fd->parent_scope_level; fd = fd->parent; for (idx = fd->scopes[scope_level].first; idx >= 0;) { vd = &fd->vars[idx]; if (vd->var_name == var_name) { if (op == OP_scope_put_var || op == OP_scope_make_ref) { if (vd->is_const) { dbuf_putc(bc, OP_throw_error); dbuf_put_u32(bc, JS_DupAtom(ctx, var_name)); dbuf_putc(bc, JS_THROW_VAR_RO); goto done; } } var_idx = idx; break; } else if (vd->var_name == JS_ATOM__with_ && !is_pseudo_var) { capture_var(fd, vd); idx = get_closure_var(ctx, s, fd, JS_CLOSURE_LOCAL, idx, vd->var_name, FALSE, FALSE, JS_VAR_NORMAL); if (idx >= 0) { dbuf_putc(bc, OP_get_var_ref); dbuf_put_u16(bc, idx); var_object_test(ctx, s, var_name, op, bc, &label_done, 1); } } idx = vd->scope_next; } is_arg_scope = (idx == ARG_SCOPE_END); if (var_idx >= 0) break; if (!is_arg_scope) { var_idx = find_var(ctx, fd, var_name); if (var_idx >= 0) break; } if (is_pseudo_var) { var_idx = resolve_pseudo_var(ctx, fd, var_name); if (var_idx >= 0) break; } if (var_name == JS_ATOM_arguments && fd->has_arguments_binding) { var_idx = add_arguments_var(ctx, fd); break; } if (fd->is_func_expr && fd->func_name == var_name) { /* add a new variable with the function name */ var_idx = add_func_var(ctx, fd, var_name); break; } /* check eval object */ if (!is_arg_scope && fd->var_object_idx >= 0 && !is_pseudo_var) { vd = &fd->vars[fd->var_object_idx]; capture_var(fd, vd); idx = get_closure_var(ctx, s, fd, JS_CLOSURE_LOCAL, fd->var_object_idx, vd->var_name, FALSE, FALSE, JS_VAR_NORMAL); dbuf_putc(bc, OP_get_var_ref); dbuf_put_u16(bc, idx); var_object_test(ctx, s, var_name, op, bc, &label_done, 0); } /* check eval object in argument scope */ if (fd->arg_var_object_idx >= 0 && !is_pseudo_var) { vd = &fd->vars[fd->arg_var_object_idx]; capture_var(fd, vd); idx = get_closure_var(ctx, s, fd, JS_CLOSURE_LOCAL, fd->arg_var_object_idx, vd->var_name, FALSE, FALSE, JS_VAR_NORMAL); dbuf_putc(bc, OP_get_var_ref); dbuf_put_u16(bc, idx); var_object_test(ctx, s, var_name, op, bc, &label_done, 0); } if (fd->is_eval) break; /* it it necessarily the top level function */ } /* check direct eval scope (in the closure of the eval function which is necessarily at the top level) */ if (!fd) fd = s; if (var_idx < 0 && fd->is_eval) { int idx1; for (idx1 = 0; idx1 < fd->closure_var_count; idx1++) { JSClosureVar *cv = &fd->closure_var[idx1]; if (var_name == cv->var_name) { if (fd != s) { JSClosureTypeEnum closure_type; if (cv->closure_type == JS_CLOSURE_GLOBAL || cv->closure_type == JS_CLOSURE_GLOBAL_DECL || cv->closure_type == JS_CLOSURE_GLOBAL_REF) closure_type = JS_CLOSURE_GLOBAL_REF; else closure_type = JS_CLOSURE_REF; idx = get_closure_var(ctx, s, fd, closure_type, idx1, cv->var_name, cv->is_const, cv->is_lexical, cv->var_kind); } else { idx = idx1; } if (cv->closure_type == JS_CLOSURE_GLOBAL || cv->closure_type == JS_CLOSURE_GLOBAL_DECL || cv->closure_type == JS_CLOSURE_GLOBAL_REF) goto has_global_idx; else goto has_idx; } else if ((cv->var_name == JS_ATOM__var_ || cv->var_name == JS_ATOM__arg_var_ || cv->var_name == JS_ATOM__with_) && !is_pseudo_var) { int is_with = (cv->var_name == JS_ATOM__with_); if (fd != s) { idx = get_closure_var(ctx, s, fd, JS_CLOSURE_REF, idx1, cv->var_name, FALSE, FALSE, JS_VAR_NORMAL); } else { idx = idx1; } dbuf_putc(bc, OP_get_var_ref); dbuf_put_u16(bc, idx); var_object_test(ctx, s, var_name, op, bc, &label_done, is_with); } } /* not found: add a closure for a global variable access */ idx1 = add_closure_var(ctx, fd, JS_CLOSURE_GLOBAL, 0, var_name, FALSE, FALSE, JS_VAR_NORMAL); if (idx1 < 0) return -1; if (fd != s) { idx = get_closure_var(ctx, s, fd, JS_CLOSURE_GLOBAL_REF, idx1, var_name, FALSE, FALSE, JS_VAR_NORMAL); } else { idx = idx1; } has_global_idx: /* global variable access */ switch (op) { case OP_scope_make_ref: if (label_done == -1 && can_opt_put_global_ref_value(bc_buf, ls->pos)) { pos_next = optimize_scope_make_ref(ctx, s, bc, bc_buf, ls, pos_next, OP_get_var, idx); } else { dbuf_putc(bc, OP_make_var_ref); dbuf_put_u32(bc, JS_DupAtom(ctx, var_name)); } break; case OP_scope_get_ref: /* XXX: should create a dummy object with a named slot that is a reference to the global variable */ dbuf_putc(bc, OP_undefined); dbuf_putc(bc, OP_get_var); dbuf_put_u16(bc, idx); break; case OP_scope_get_var_undef: case OP_scope_get_var: case OP_scope_put_var: dbuf_putc(bc, OP_get_var_undef + (op - OP_scope_get_var_undef)); dbuf_put_u16(bc, idx); break; case OP_scope_put_var_init: dbuf_putc(bc, OP_put_var_init); dbuf_put_u16(bc, idx); break; case OP_scope_delete_var: dbuf_putc(bc, OP_delete_var); dbuf_put_u32(bc, JS_DupAtom(ctx, var_name)); break; } } else { /* find the corresponding closure variable */ if (var_idx & ARGUMENT_VAR_OFFSET) { capture_var(fd, &fd->args[var_idx - ARGUMENT_VAR_OFFSET]); idx = get_closure_var(ctx, s, fd, JS_CLOSURE_ARG, var_idx - ARGUMENT_VAR_OFFSET, var_name, FALSE, FALSE, JS_VAR_NORMAL); } else { capture_var(fd, &fd->vars[var_idx]); idx = get_closure_var(ctx, s, fd, JS_CLOSURE_LOCAL, var_idx, var_name, fd->vars[var_idx].is_const, fd->vars[var_idx].is_lexical, fd->vars[var_idx].var_kind); } if (idx >= 0) { has_idx: if ((op == OP_scope_put_var || op == OP_scope_make_ref) && s->closure_var[idx].is_const) { dbuf_putc(bc, OP_throw_error); dbuf_put_u32(bc, JS_DupAtom(ctx, var_name)); dbuf_putc(bc, JS_THROW_VAR_RO); goto done; } switch (op) { case OP_scope_make_ref: if (s->closure_var[idx].var_kind == JS_VAR_FUNCTION_NAME) { /* Create a dummy object reference for the func_var */ dbuf_putc(bc, OP_object); dbuf_putc(bc, OP_get_var_ref); dbuf_put_u16(bc, idx); dbuf_putc(bc, OP_define_field); dbuf_put_u32(bc, JS_DupAtom(ctx, var_name)); dbuf_putc(bc, OP_push_atom_value); dbuf_put_u32(bc, JS_DupAtom(ctx, var_name)); } else if (label_done == -1 && can_opt_put_ref_value(bc_buf, ls->pos)) { int get_op; if (s->closure_var[idx].is_lexical) get_op = OP_get_var_ref_check; else get_op = OP_get_var_ref; pos_next = optimize_scope_make_ref(ctx, s, bc, bc_buf, ls, pos_next, get_op, idx); } else { /* Create a dummy object with a named slot that is a reference to the closure variable */ dbuf_putc(bc, OP_make_var_ref_ref); dbuf_put_u32(bc, JS_DupAtom(ctx, var_name)); dbuf_put_u16(bc, idx); } break; case OP_scope_put_var: if (s->closure_var[idx].var_kind == JS_VAR_FUNCTION_NAME) { /* in non strict mode, modifying the function name is ignored */ dbuf_putc(bc, OP_drop); goto done; } goto closure_scope_var; case OP_scope_get_ref: /* XXX: should create a dummy object with a named slot that is a reference to the closure variable */ dbuf_putc(bc, OP_undefined); goto closure_scope_var; case OP_scope_get_var_undef: case OP_scope_get_var: case OP_scope_put_var_init: closure_scope_var: is_put = (op == OP_scope_put_var || op == OP_scope_put_var_init); if (is_put) { if (s->closure_var[idx].is_lexical) { if (op == OP_scope_put_var_init) { /* 'this' can only be initialized once */ if (var_name == JS_ATOM_this) dbuf_putc(bc, OP_put_var_ref_check_init); else dbuf_putc(bc, OP_put_var_ref); } else { dbuf_putc(bc, OP_put_var_ref_check); } } else { dbuf_putc(bc, OP_put_var_ref); } } else { if (s->closure_var[idx].is_lexical) { dbuf_putc(bc, OP_get_var_ref_check); } else { dbuf_putc(bc, OP_get_var_ref); } } dbuf_put_u16(bc, idx); break; case OP_scope_delete_var: dbuf_putc(bc, OP_push_false); break; } goto done; } } done: if (label_done >= 0) { dbuf_putc(bc, OP_label); dbuf_put_u32(bc, label_done); s->label_slots[label_done].pos2 = bc->size; } return pos_next; } /* search in all scopes */ static int find_private_class_field_all(JSContext *ctx, JSFunctionDef *fd, JSAtom name, int scope_level) { int idx; idx = fd->scopes[scope_level].first; while (idx >= 0) { if (fd->vars[idx].var_name == name) return idx; idx = fd->vars[idx].scope_next; } return -1; } static void get_loc_or_ref(DynBuf *bc, BOOL is_ref, int idx) { /* if the field is not initialized, the error is catched when accessing it */ if (is_ref) dbuf_putc(bc, OP_get_var_ref); else dbuf_putc(bc, OP_get_loc); dbuf_put_u16(bc, idx); } static int resolve_scope_private_field1(JSContext *ctx, BOOL *pis_ref, int *pvar_kind, JSFunctionDef *s, JSAtom var_name, int scope_level) { int idx, var_kind; JSFunctionDef *fd; BOOL is_ref; fd = s; is_ref = FALSE; for(;;) { idx = find_private_class_field_all(ctx, fd, var_name, scope_level); if (idx >= 0) { var_kind = fd->vars[idx].var_kind; if (is_ref) { capture_var(fd, &fd->vars[idx]); idx = get_closure_var(ctx, s, fd, JS_CLOSURE_LOCAL, idx, var_name, TRUE, TRUE, JS_VAR_NORMAL); if (idx < 0) return -1; } break; } scope_level = fd->parent_scope_level; if (!fd->parent) { if (fd->is_eval) { /* closure of the eval function (top level) */ for (idx = 0; idx < fd->closure_var_count; idx++) { JSClosureVar *cv = &fd->closure_var[idx]; if (cv->var_name == var_name) { var_kind = cv->var_kind; is_ref = TRUE; if (fd != s) { idx = get_closure_var(ctx, s, fd, JS_CLOSURE_REF, idx, cv->var_name, cv->is_const, cv->is_lexical, cv->var_kind); if (idx < 0) return -1; } goto done; } } } /* XXX: no line number info */ JS_ThrowSyntaxErrorAtom(ctx, "undefined private field '%s'", var_name); return -1; } else { fd = fd->parent; } is_ref = TRUE; } done: *pis_ref = is_ref; *pvar_kind = var_kind; return idx; } /* return 0 if OK or -1 if the private field could not be resolved */ static int resolve_scope_private_field(JSContext *ctx, JSFunctionDef *s, JSAtom var_name, int scope_level, int op, DynBuf *bc) { int idx, var_kind; BOOL is_ref; idx = resolve_scope_private_field1(ctx, &is_ref, &var_kind, s, var_name, scope_level); if (idx < 0) return -1; assert(var_kind != JS_VAR_NORMAL); switch (op) { case OP_scope_get_private_field: case OP_scope_get_private_field2: switch(var_kind) { case JS_VAR_PRIVATE_FIELD: if (op == OP_scope_get_private_field2) dbuf_putc(bc, OP_dup); get_loc_or_ref(bc, is_ref, idx); dbuf_putc(bc, OP_get_private_field); break; case JS_VAR_PRIVATE_METHOD: get_loc_or_ref(bc, is_ref, idx); dbuf_putc(bc, OP_check_brand); if (op != OP_scope_get_private_field2) dbuf_putc(bc, OP_nip); break; case JS_VAR_PRIVATE_GETTER: case JS_VAR_PRIVATE_GETTER_SETTER: if (op == OP_scope_get_private_field2) dbuf_putc(bc, OP_dup); get_loc_or_ref(bc, is_ref, idx); dbuf_putc(bc, OP_check_brand); dbuf_putc(bc, OP_call_method); dbuf_put_u16(bc, 0); break; case JS_VAR_PRIVATE_SETTER: /* XXX: add clearer error message */ dbuf_putc(bc, OP_throw_error); dbuf_put_u32(bc, JS_DupAtom(ctx, var_name)); dbuf_putc(bc, JS_THROW_VAR_RO); break; default: abort(); } break; case OP_scope_put_private_field: switch(var_kind) { case JS_VAR_PRIVATE_FIELD: get_loc_or_ref(bc, is_ref, idx); dbuf_putc(bc, OP_put_private_field); break; case JS_VAR_PRIVATE_METHOD: case JS_VAR_PRIVATE_GETTER: /* XXX: add clearer error message */ dbuf_putc(bc, OP_throw_error); dbuf_put_u32(bc, JS_DupAtom(ctx, var_name)); dbuf_putc(bc, JS_THROW_VAR_RO); break; case JS_VAR_PRIVATE_SETTER: case JS_VAR_PRIVATE_GETTER_SETTER: { JSAtom setter_name = get_private_setter_name(ctx, var_name); if (setter_name == JS_ATOM_NULL) return -1; idx = resolve_scope_private_field1(ctx, &is_ref, &var_kind, s, setter_name, scope_level); JS_FreeAtom(ctx, setter_name); if (idx < 0) return -1; assert(var_kind == JS_VAR_PRIVATE_SETTER); get_loc_or_ref(bc, is_ref, idx); dbuf_putc(bc, OP_swap); /* obj func value */ dbuf_putc(bc, OP_rot3r); /* value obj func */ dbuf_putc(bc, OP_check_brand); dbuf_putc(bc, OP_rot3l); /* obj func value */ dbuf_putc(bc, OP_call_method); dbuf_put_u16(bc, 1); dbuf_putc(bc, OP_drop); } break; default: abort(); } break; case OP_scope_in_private_field: get_loc_or_ref(bc, is_ref, idx); dbuf_putc(bc, OP_private_in); break; default: abort(); } return 0; } static void mark_eval_captured_variables(JSContext *ctx, JSFunctionDef *s, int scope_level) { int idx; JSVarDef *vd; for (idx = s->scopes[scope_level].first; idx >= 0;) { vd = &s->vars[idx]; capture_var(s, vd); idx = vd->scope_next; } } /* XXX: should handle the argument scope generically */ static BOOL is_var_in_arg_scope(JSAtom var_name, JSVarKindEnum var_kind) { return (var_name == JS_ATOM_home_object || var_name == JS_ATOM_this_active_func || var_name == JS_ATOM_new_target || var_name == JS_ATOM_this || var_name == JS_ATOM__arg_var_ || var_kind == JS_VAR_FUNCTION_NAME); } static void add_eval_variables(JSContext *ctx, JSFunctionDef *s) { JSFunctionDef *fd; JSVarDef *vd; int i, scope_level, scope_idx; BOOL has_arguments_binding, has_this_binding, is_arg_scope; /* in non strict mode, variables are created in the caller's environment object */ if (!s->is_eval && !(s->js_mode & JS_MODE_STRICT)) { s->var_object_idx = add_var(ctx, s, JS_ATOM__var_); if (s->has_parameter_expressions) { /* an additional variable object is needed for the argument scope */ s->arg_var_object_idx = add_var(ctx, s, JS_ATOM__arg_var_); } } /* eval can potentially use 'arguments' so we must define it */ has_this_binding = s->has_this_binding; if (has_this_binding) { if (s->this_var_idx < 0) s->this_var_idx = add_var_this(ctx, s); if (s->new_target_var_idx < 0) s->new_target_var_idx = add_var(ctx, s, JS_ATOM_new_target); if (s->is_derived_class_constructor && s->this_active_func_var_idx < 0) s->this_active_func_var_idx = add_var(ctx, s, JS_ATOM_this_active_func); if (s->has_home_object && s->home_object_var_idx < 0) s->home_object_var_idx = add_var(ctx, s, JS_ATOM_home_object); } has_arguments_binding = s->has_arguments_binding; if (has_arguments_binding) { add_arguments_var(ctx, s); /* also add an arguments binding in the argument scope to raise an error if a direct eval in the argument scope tries to redefine it */ if (s->has_parameter_expressions && !(s->js_mode & JS_MODE_STRICT)) add_arguments_arg(ctx, s); } if (s->is_func_expr && s->func_name != JS_ATOM_NULL) add_func_var(ctx, s, s->func_name); for(i = 0; i < s->arg_count; i++) { vd = &s->args[i]; capture_var(s, vd); } for(i = 0; i < s->var_count; i++) { vd = &s->vars[i]; /* do not close top level last result */ if (vd->scope_level == 0 && vd->var_name != JS_ATOM__ret_ && vd->var_name != JS_ATOM_NULL) { capture_var(s, vd); } } /* eval can use all the variables of the enclosing functions, so they must be all put in the closure. The closure variables are ordered by scope. It works only because no closure are created before. */ assert(s->is_eval || s->closure_var_count == 0); /* XXX: inefficient, but eval performance is less critical */ fd = s; for(;;) { scope_level = fd->parent_scope_level; fd = fd->parent; if (!fd) break; /* add 'this' if it was not previously added */ if (!has_this_binding && fd->has_this_binding) { if (fd->this_var_idx < 0) fd->this_var_idx = add_var_this(ctx, fd); if (fd->new_target_var_idx < 0) fd->new_target_var_idx = add_var(ctx, fd, JS_ATOM_new_target); if (fd->is_derived_class_constructor && fd->this_active_func_var_idx < 0) fd->this_active_func_var_idx = add_var(ctx, fd, JS_ATOM_this_active_func); if (fd->has_home_object && fd->home_object_var_idx < 0) fd->home_object_var_idx = add_var(ctx, fd, JS_ATOM_home_object); has_this_binding = TRUE; } /* add 'arguments' if it was not previously added */ if (!has_arguments_binding && fd->has_arguments_binding) { add_arguments_var(ctx, fd); has_arguments_binding = TRUE; } /* add function name */ if (fd->is_func_expr && fd->func_name != JS_ATOM_NULL) add_func_var(ctx, fd, fd->func_name); /* add lexical variables */ scope_idx = fd->scopes[scope_level].first; while (scope_idx >= 0) { vd = &fd->vars[scope_idx]; capture_var(fd, vd); get_closure_var(ctx, s, fd, JS_CLOSURE_LOCAL, scope_idx, vd->var_name, vd->is_const, vd->is_lexical, vd->var_kind); scope_idx = vd->scope_next; } is_arg_scope = (scope_idx == ARG_SCOPE_END); if (!is_arg_scope) { /* add unscoped variables */ /* XXX: propagate is_const and var_kind too ? */ for(i = 0; i < fd->arg_count; i++) { vd = &fd->args[i]; if (vd->var_name != JS_ATOM_NULL) { capture_var(fd, vd); get_closure_var(ctx, s, fd, JS_CLOSURE_ARG, i, vd->var_name, FALSE, vd->is_lexical, JS_VAR_NORMAL); } } for(i = 0; i < fd->var_count; i++) { vd = &fd->vars[i]; /* do not close top level last result */ if (vd->scope_level == 0 && vd->var_name != JS_ATOM__ret_ && vd->var_name != JS_ATOM_NULL) { capture_var(fd, vd); get_closure_var(ctx, s, fd, JS_CLOSURE_LOCAL, i, vd->var_name, FALSE, vd->is_lexical, JS_VAR_NORMAL); } } } else { for(i = 0; i < fd->var_count; i++) { vd = &fd->vars[i]; /* do not close top level last result */ if (vd->scope_level == 0 && is_var_in_arg_scope(vd->var_name, vd->var_kind)) { capture_var(fd, vd); get_closure_var(ctx, s, fd, JS_CLOSURE_LOCAL, i, vd->var_name, FALSE, vd->is_lexical, JS_VAR_NORMAL); } } } if (fd->is_eval) { int idx; /* add direct eval variables (we are necessarily at the top level). */ for (idx = 0; idx < fd->closure_var_count; idx++) { JSClosureVar *cv = &fd->closure_var[idx]; /* Global variables are removed but module definitions are kept. */ if (cv->closure_type != JS_CLOSURE_GLOBAL_REF && cv->closure_type != JS_CLOSURE_GLOBAL_DECL && cv->closure_type != JS_CLOSURE_GLOBAL) { get_closure_var(ctx, s, fd, JS_CLOSURE_REF, idx, cv->var_name, cv->is_const, cv->is_lexical, cv->var_kind); } } } } } static void set_closure_from_var(JSContext *ctx, JSClosureVar *cv, JSBytecodeVarDef *vd, int var_idx) { cv->closure_type = JS_CLOSURE_LOCAL; cv->is_const = vd->is_const; cv->is_lexical = vd->is_lexical; cv->var_kind = vd->var_kind; cv->var_idx = var_idx; cv->var_name = JS_DupAtom(ctx, vd->var_name); } /* for direct eval compilation: add references to the variables of the calling function */ static __exception int add_closure_variables(JSContext *ctx, JSFunctionDef *s, JSFunctionBytecode *b, int scope_idx) { int i, count; JSBytecodeVarDef *vd; BOOL is_arg_scope; count = b->arg_count + b->var_count + b->closure_var_count; s->closure_var = NULL; s->closure_var_count = 0; s->closure_var_size = count; if (count == 0) return 0; s->closure_var = js_malloc(ctx, sizeof(s->closure_var[0]) * count); if (!s->closure_var) return -1; /* Add lexical variables in scope at the point of evaluation */ for (i = scope_idx; i >= 0;) { vd = &b->vardefs[b->arg_count + i]; if (vd->has_scope) { JSClosureVar *cv = &s->closure_var[s->closure_var_count++]; set_closure_from_var(ctx, cv, vd, i); } i = vd->scope_next; } is_arg_scope = (i == ARG_SCOPE_END); if (!is_arg_scope) { /* Add argument variables */ for(i = 0; i < b->arg_count; i++) { JSClosureVar *cv = &s->closure_var[s->closure_var_count++]; vd = &b->vardefs[i]; cv->closure_type = JS_CLOSURE_ARG; cv->is_const = FALSE; cv->is_lexical = FALSE; cv->var_kind = JS_VAR_NORMAL; cv->var_idx = i; cv->var_name = JS_DupAtom(ctx, vd->var_name); } /* Add local non lexical variables */ for(i = 0; i < b->var_count; i++) { vd = &b->vardefs[b->arg_count + i]; if (!vd->has_scope && vd->var_name != JS_ATOM__ret_) { JSClosureVar *cv = &s->closure_var[s->closure_var_count++]; set_closure_from_var(ctx, cv, vd, i); } } } else { /* only add pseudo variables */ for(i = 0; i < b->var_count; i++) { vd = &b->vardefs[b->arg_count + i]; if (!vd->has_scope && is_var_in_arg_scope(vd->var_name, vd->var_kind)) { JSClosureVar *cv = &s->closure_var[s->closure_var_count++]; set_closure_from_var(ctx, cv, vd, i); } } } for(i = 0; i < b->closure_var_count; i++) { JSClosureVar *cv0 = &b->closure_var[i]; JSClosureVar *cv; switch(cv0->closure_type) { case JS_CLOSURE_LOCAL: case JS_CLOSURE_ARG: case JS_CLOSURE_REF: case JS_CLOSURE_MODULE_DECL: case JS_CLOSURE_MODULE_IMPORT: break; case JS_CLOSURE_GLOBAL_REF: case JS_CLOSURE_GLOBAL_DECL: case JS_CLOSURE_GLOBAL: continue; /* not necessary to add global variables */ default: abort(); } cv = &s->closure_var[s->closure_var_count++]; cv->closure_type = JS_CLOSURE_REF; cv->is_const = cv0->is_const; cv->is_lexical = cv0->is_lexical; cv->var_kind = cv0->var_kind; cv->var_idx = i; cv->var_name = JS_DupAtom(ctx, cv0->var_name); } return 0; } typedef struct CodeContext { const uint8_t *bc_buf; /* code buffer */ int bc_len; /* length of the code buffer */ int pos; /* position past the matched code pattern */ int line_num; /* last visited OP_line_num parameter or -1 */ int op; int idx; int label; int val; JSAtom atom; } CodeContext; #define M2(op1, op2) ((op1) | ((op2) << 8)) #define M3(op1, op2, op3) ((op1) | ((op2) << 8) | ((op3) << 16)) #define M4(op1, op2, op3, op4) ((op1) | ((op2) << 8) | ((op3) << 16) | ((op4) << 24)) static BOOL code_match(CodeContext *s, int pos, ...) { const uint8_t *tab = s->bc_buf; int op, len, op1, line_num, pos_next; va_list ap; BOOL ret = FALSE; line_num = -1; va_start(ap, pos); for(;;) { op1 = va_arg(ap, int); if (op1 == -1) { s->pos = pos; s->line_num = line_num; ret = TRUE; break; } for (;;) { if (pos >= s->bc_len) goto done; op = tab[pos]; len = opcode_info[op].size; pos_next = pos + len; if (pos_next > s->bc_len) goto done; if (op == OP_line_num) { line_num = get_u32(tab + pos + 1); pos = pos_next; } else { break; } } if (op != op1) { if (op1 == (uint8_t)op1 || !op) break; if (op != (uint8_t)op1 && op != (uint8_t)(op1 >> 8) && op != (uint8_t)(op1 >> 16) && op != (uint8_t)(op1 >> 24)) { break; } s->op = op; } pos++; switch(opcode_info[op].fmt) { case OP_FMT_loc8: case OP_FMT_u8: { int idx = tab[pos]; int arg = va_arg(ap, int); if (arg == -1) { s->idx = idx; } else { if (arg != idx) goto done; } break; } case OP_FMT_u16: case OP_FMT_npop: case OP_FMT_loc: case OP_FMT_arg: case OP_FMT_var_ref: { int idx = get_u16(tab + pos); int arg = va_arg(ap, int); if (arg == -1) { s->idx = idx; } else { if (arg != idx) goto done; } break; } case OP_FMT_i32: case OP_FMT_u32: case OP_FMT_label: case OP_FMT_const: { s->label = get_u32(tab + pos); break; } case OP_FMT_label_u16: { s->label = get_u32(tab + pos); s->val = get_u16(tab + pos + 4); break; } case OP_FMT_atom: { s->atom = get_u32(tab + pos); break; } case OP_FMT_atom_u8: { s->atom = get_u32(tab + pos); s->val = get_u8(tab + pos + 4); break; } case OP_FMT_atom_u16: { s->atom = get_u32(tab + pos); s->val = get_u16(tab + pos + 4); break; } case OP_FMT_atom_label_u8: { s->atom = get_u32(tab + pos); s->label = get_u32(tab + pos + 4); s->val = get_u8(tab + pos + 8); break; } default: break; } pos = pos_next; } done: va_end(ap); return ret; } static void instantiate_hoisted_definitions(JSContext *ctx, JSFunctionDef *s, DynBuf *bc) { int i, idx, label_next = -1; /* add the hoisted functions in arguments and local variables */ for(i = 0; i < s->arg_count; i++) { JSVarDef *vd = &s->args[i]; if (vd->func_pool_idx >= 0) { dbuf_putc(bc, OP_fclosure); dbuf_put_u32(bc, vd->func_pool_idx); dbuf_putc(bc, OP_put_arg); dbuf_put_u16(bc, i); } } for(i = 0; i < s->var_count; i++) { JSVarDef *vd = &s->vars[i]; if (vd->scope_level == 0 && vd->func_pool_idx >= 0) { dbuf_putc(bc, OP_fclosure); dbuf_put_u32(bc, vd->func_pool_idx); dbuf_putc(bc, OP_put_loc); dbuf_put_u16(bc, i); } } /* the module global variables must be initialized before evaluating the module so that the exported functions are visible if there are cyclic module references */ if (s->module) { label_next = new_label_fd(s); if (label_next < 0) { dbuf_set_error(bc); return; } /* if 'this' is true, initialize the global variables and return */ dbuf_putc(bc, OP_push_this); dbuf_putc(bc, OP_if_false); dbuf_put_u32(bc, label_next); update_label(s, label_next, 1); s->jump_size++; } /* add the global variables (only happens if s->is_global_var is true) */ /* XXX: inefficient, add a closure index in JSGlobalVar */ for(i = 0; i < s->global_var_count; i++) { JSGlobalVar *hf = &s->global_vars[i]; BOOL has_var_obj = FALSE; BOOL force_init = hf->force_init; /* we are in an eval, so the closure contains all the enclosing variables */ /* If the outer function has a variable environment, create a property for the variable there */ for(idx = 0; idx < s->closure_var_count; idx++) { JSClosureVar *cv = &s->closure_var[idx]; if (cv->var_name == hf->var_name) { force_init = FALSE; goto closure_found; } if (cv->var_name == JS_ATOM__var_ || cv->var_name == JS_ATOM__arg_var_) { dbuf_putc(bc, OP_get_var_ref); dbuf_put_u16(bc, idx); has_var_obj = TRUE; force_init = TRUE; goto closure_found; } } abort(); closure_found: if (hf->cpool_idx >= 0 || force_init) { if (hf->cpool_idx >= 0) { dbuf_putc(bc, OP_fclosure); dbuf_put_u32(bc, hf->cpool_idx); if (hf->var_name == JS_ATOM__default_) { /* set default export function name */ dbuf_putc(bc, OP_set_name); dbuf_put_u32(bc, JS_DupAtom(ctx, JS_ATOM_default)); } } else { dbuf_putc(bc, OP_undefined); } if (!has_var_obj) { dbuf_putc(bc, OP_put_var_ref); dbuf_put_u16(bc, idx); } else { dbuf_putc(bc, OP_define_field); dbuf_put_u32(bc, JS_DupAtom(ctx, hf->var_name)); dbuf_putc(bc, OP_drop); } } JS_FreeAtom(ctx, hf->var_name); } if (s->module) { dbuf_putc(bc, OP_return_undef); dbuf_putc(bc, OP_label); dbuf_put_u32(bc, label_next); s->label_slots[label_next].pos2 = bc->size; } js_free(ctx, s->global_vars); s->global_vars = NULL; s->global_var_count = 0; s->global_var_size = 0; } static int skip_dead_code(JSFunctionDef *s, const uint8_t *bc_buf, int bc_len, int pos, int *linep) { int op, len, label; for (; pos < bc_len; pos += len) { op = bc_buf[pos]; len = opcode_info[op].size; if (op == OP_line_num) { *linep = get_u32(bc_buf + pos + 1); } else if (op == OP_label) { label = get_u32(bc_buf + pos + 1); if (update_label(s, label, 0) > 0) break; #if 0 if (s->label_slots[label].first_reloc) { printf("line %d: unreferenced label %d:%d has relocations\n", *linep, label, s->label_slots[label].pos2); } #endif assert(s->label_slots[label].first_reloc == NULL); } else { /* XXX: output a warning for unreachable code? */ JSAtom atom; switch(opcode_info[op].fmt) { case OP_FMT_label: case OP_FMT_label_u16: label = get_u32(bc_buf + pos + 1); update_label(s, label, -1); break; case OP_FMT_atom_label_u8: case OP_FMT_atom_label_u16: label = get_u32(bc_buf + pos + 5); update_label(s, label, -1); /* fall thru */ case OP_FMT_atom: case OP_FMT_atom_u8: case OP_FMT_atom_u16: atom = get_u32(bc_buf + pos + 1); JS_FreeAtom(s->ctx, atom); break; default: break; } } } return pos; } static int get_label_pos(JSFunctionDef *s, int label) { int i, pos; for (i = 0; i < 20; i++) { pos = s->label_slots[label].pos; for (;;) { switch (s->byte_code.buf[pos]) { case OP_line_num: case OP_label: pos += 5; continue; case OP_goto: label = get_u32(s->byte_code.buf + pos + 1); break; default: return pos; } break; } } return pos; } /* convert global variable accesses to local variables or closure variables when necessary */ static __exception int resolve_variables(JSContext *ctx, JSFunctionDef *s) { int pos, pos_next, bc_len, op, len, line_num, i, idx; uint8_t *bc_buf; JSAtom var_name; DynBuf bc_out; CodeContext cc; int scope; cc.bc_buf = bc_buf = s->byte_code.buf; cc.bc_len = bc_len = s->byte_code.size; js_dbuf_bytecode_init(ctx, &bc_out); /* first pass for runtime checks (must be done before the variables are created) */ /* XXX: inefficient */ for(i = 0; i < s->global_var_count; i++) { JSGlobalVar *hf = &s->global_vars[i]; /* check if global variable (XXX: simplify) */ for(idx = 0; idx < s->closure_var_count; idx++) { JSClosureVar *cv = &s->closure_var[idx]; if (cv->closure_type == JS_CLOSURE_GLOBAL_REF || cv->closure_type == JS_CLOSURE_GLOBAL_DECL || cv->closure_type == JS_CLOSURE_GLOBAL || cv->closure_type == JS_CLOSURE_MODULE_DECL || cv->closure_type == JS_CLOSURE_MODULE_IMPORT) goto next; /* don't look at global variables (they are at the end) */ if (cv->var_name == hf->var_name) { if (s->eval_type == JS_EVAL_TYPE_DIRECT && cv->is_lexical) { /* Check if a lexical variable is redefined as 'var'. XXX: Could abort compilation here, but for consistency with the other checks, we delay the error generation. */ dbuf_putc(&bc_out, OP_throw_error); dbuf_put_u32(&bc_out, JS_DupAtom(ctx, hf->var_name)); dbuf_putc(&bc_out, JS_THROW_VAR_REDECL); } goto next; } if (cv->var_name == JS_ATOM__var_ || cv->var_name == JS_ATOM__arg_var_) goto next; } next: ; } line_num = 0; /* avoid warning */ for (pos = 0; pos < bc_len; pos = pos_next) { op = bc_buf[pos]; len = opcode_info[op].size; pos_next = pos + len; switch(op) { case OP_line_num: line_num = get_u32(bc_buf + pos + 1); s->line_number_size++; goto no_change; case OP_eval: /* convert scope index to adjusted variable index */ { int call_argc = get_u16(bc_buf + pos + 1); scope = get_u16(bc_buf + pos + 1 + 2); mark_eval_captured_variables(ctx, s, scope); dbuf_putc(&bc_out, op); dbuf_put_u16(&bc_out, call_argc); dbuf_put_u16(&bc_out, s->scopes[scope].first - ARG_SCOPE_END); } break; case OP_apply_eval: /* convert scope index to adjusted variable index */ scope = get_u16(bc_buf + pos + 1); mark_eval_captured_variables(ctx, s, scope); dbuf_putc(&bc_out, op); dbuf_put_u16(&bc_out, s->scopes[scope].first - ARG_SCOPE_END); break; case OP_scope_get_var_checkthis: case OP_scope_get_var_undef: case OP_scope_get_var: case OP_scope_put_var: case OP_scope_delete_var: case OP_scope_get_ref: case OP_scope_put_var_init: var_name = get_u32(bc_buf + pos + 1); scope = get_u16(bc_buf + pos + 5); pos_next = resolve_scope_var(ctx, s, var_name, scope, op, &bc_out, NULL, NULL, pos_next); JS_FreeAtom(ctx, var_name); break; case OP_scope_make_ref: { int label; LabelSlot *ls; var_name = get_u32(bc_buf + pos + 1); label = get_u32(bc_buf + pos + 5); scope = get_u16(bc_buf + pos + 9); ls = &s->label_slots[label]; ls->ref_count--; /* always remove label reference */ pos_next = resolve_scope_var(ctx, s, var_name, scope, op, &bc_out, bc_buf, ls, pos_next); JS_FreeAtom(ctx, var_name); } break; case OP_scope_get_private_field: case OP_scope_get_private_field2: case OP_scope_put_private_field: case OP_scope_in_private_field: { int ret; var_name = get_u32(bc_buf + pos + 1); scope = get_u16(bc_buf + pos + 5); ret = resolve_scope_private_field(ctx, s, var_name, scope, op, &bc_out); if (ret < 0) goto fail; JS_FreeAtom(ctx, var_name); } break; case OP_gosub: s->jump_size++; if (OPTIMIZE) { /* remove calls to empty finalizers */ int label; LabelSlot *ls; label = get_u32(bc_buf + pos + 1); assert(label >= 0 && label < s->label_count); ls = &s->label_slots[label]; if (code_match(&cc, ls->pos, OP_ret, -1)) { ls->ref_count--; break; } } goto no_change; case OP_drop: if (0) { /* remove drops before return_undef */ /* do not perform this optimization in pass2 because it breaks patterns recognised in resolve_labels */ int pos1 = pos_next; int line1 = line_num; while (code_match(&cc, pos1, OP_drop, -1)) { if (cc.line_num >= 0) line1 = cc.line_num; pos1 = cc.pos; } if (code_match(&cc, pos1, OP_return_undef, -1)) { pos_next = pos1; if (line1 != -1 && line1 != line_num) { line_num = line1; s->line_number_size++; dbuf_putc(&bc_out, OP_line_num); dbuf_put_u32(&bc_out, line_num); } break; } } goto no_change; case OP_insert3: if (OPTIMIZE) { /* Transformation: insert3 put_array_el|put_ref_value drop -> put_array_el|put_ref_value */ if (code_match(&cc, pos_next, M2(OP_put_array_el, OP_put_ref_value), OP_drop, -1)) { dbuf_putc(&bc_out, cc.op); pos_next = cc.pos; if (cc.line_num != -1 && cc.line_num != line_num) { line_num = cc.line_num; s->line_number_size++; dbuf_putc(&bc_out, OP_line_num); dbuf_put_u32(&bc_out, line_num); } break; } } goto no_change; case OP_goto: s->jump_size++; /* fall thru */ case OP_tail_call: case OP_tail_call_method: case OP_return: case OP_return_undef: case OP_throw: case OP_throw_error: case OP_ret: if (OPTIMIZE) { /* remove dead code */ int line = -1; dbuf_put(&bc_out, bc_buf + pos, len); pos = skip_dead_code(s, bc_buf, bc_len, pos + len, &line); pos_next = pos; if (pos < bc_len && line >= 0 && line_num != line) { line_num = line; s->line_number_size++; dbuf_putc(&bc_out, OP_line_num); dbuf_put_u32(&bc_out, line_num); } break; } goto no_change; case OP_label: { int label; LabelSlot *ls; label = get_u32(bc_buf + pos + 1); assert(label >= 0 && label < s->label_count); ls = &s->label_slots[label]; ls->pos2 = bc_out.size + opcode_info[op].size; } goto no_change; case OP_enter_scope: { int scope_idx, scope = get_u16(bc_buf + pos + 1); if (scope == s->body_scope) { instantiate_hoisted_definitions(ctx, s, &bc_out); } for(scope_idx = s->scopes[scope].first; scope_idx >= 0;) { JSVarDef *vd = &s->vars[scope_idx]; if (vd->scope_level == scope) { if (scope_idx != s->arguments_arg_idx) { if (vd->var_kind == JS_VAR_FUNCTION_DECL || vd->var_kind == JS_VAR_NEW_FUNCTION_DECL) { /* Initialize lexical variable upon entering scope */ dbuf_putc(&bc_out, OP_fclosure); dbuf_put_u32(&bc_out, vd->func_pool_idx); dbuf_putc(&bc_out, OP_put_loc); dbuf_put_u16(&bc_out, scope_idx); } else { /* XXX: should check if variable can be used before initialization */ dbuf_putc(&bc_out, OP_set_loc_uninitialized); dbuf_put_u16(&bc_out, scope_idx); } } scope_idx = vd->scope_next; } else { break; } } } break; case OP_leave_scope: { int scope_idx, scope = get_u16(bc_buf + pos + 1); for(scope_idx = s->scopes[scope].first; scope_idx >= 0;) { JSVarDef *vd = &s->vars[scope_idx]; if (vd->scope_level == scope) { if (vd->is_captured) { dbuf_putc(&bc_out, OP_close_loc); dbuf_put_u16(&bc_out, scope_idx); } scope_idx = vd->scope_next; } else { break; } } } break; case OP_set_name: { /* remove dummy set_name opcodes */ JSAtom name = get_u32(bc_buf + pos + 1); if (name == JS_ATOM_NULL) break; } goto no_change; case OP_if_false: case OP_if_true: case OP_catch: s->jump_size++; goto no_change; case OP_dup: if (OPTIMIZE) { /* Transformation: dup if_false(l1) drop, l1: if_false(l2) -> if_false(l2) */ /* Transformation: dup if_true(l1) drop, l1: if_true(l2) -> if_true(l2) */ if (code_match(&cc, pos_next, M2(OP_if_false, OP_if_true), OP_drop, -1)) { int lab0, lab1, op1, pos1, line1, pos2; lab0 = lab1 = cc.label; assert(lab1 >= 0 && lab1 < s->label_count); op1 = cc.op; pos1 = cc.pos; line1 = cc.line_num; while (code_match(&cc, (pos2 = get_label_pos(s, lab1)), OP_dup, op1, OP_drop, -1)) { lab1 = cc.label; } if (code_match(&cc, pos2, op1, -1)) { s->jump_size++; update_label(s, lab0, -1); update_label(s, cc.label, +1); dbuf_putc(&bc_out, op1); dbuf_put_u32(&bc_out, cc.label); pos_next = pos1; if (line1 != -1 && line1 != line_num) { line_num = line1; s->line_number_size++; dbuf_putc(&bc_out, OP_line_num); dbuf_put_u32(&bc_out, line_num); } break; } } } goto no_change; case OP_nop: /* remove erased code */ break; case OP_set_class_name: /* only used during parsing */ break; case OP_get_field_opt_chain: /* equivalent to OP_get_field */ { JSAtom name = get_u32(bc_buf + pos + 1); dbuf_putc(&bc_out, OP_get_field); dbuf_put_u32(&bc_out, name); } break; case OP_get_array_el_opt_chain: /* equivalent to OP_get_array_el */ dbuf_putc(&bc_out, OP_get_array_el); break; default: no_change: dbuf_put(&bc_out, bc_buf + pos, len); break; } } /* set the new byte code */ dbuf_free(&s->byte_code); s->byte_code = bc_out; if (dbuf_error(&s->byte_code)) { JS_ThrowOutOfMemory(ctx); return -1; } return 0; fail: /* continue the copy to keep the atom refcounts consistent */ /* XXX: find a better solution ? */ for (; pos < bc_len; pos = pos_next) { op = bc_buf[pos]; len = opcode_info[op].size; pos_next = pos + len; dbuf_put(&bc_out, bc_buf + pos, len); } dbuf_free(&s->byte_code); s->byte_code = bc_out; return -1; } /* the pc2line table gives a source position for each PC value */ static void add_pc2line_info(JSFunctionDef *s, uint32_t pc, uint32_t source_pos) { if (s->line_number_slots != NULL && s->line_number_count < s->line_number_size && pc >= s->line_number_last_pc && source_pos != s->line_number_last) { s->line_number_slots[s->line_number_count].pc = pc; s->line_number_slots[s->line_number_count].source_pos = source_pos; s->line_number_count++; s->line_number_last_pc = pc; s->line_number_last = source_pos; } } /* XXX: could use a more compact storage */ /* XXX: get_line_col_cached() is slow. For more predictable performance, line/cols could be stored every N source bytes. Alternatively, get_line_col_cached() could be issued in emit_source_pos() so that the deltas are more likely to be small. */ static void compute_pc2line_info(JSFunctionDef *s) { if (!s->strip_debug) { int last_line_num, last_col_num; uint32_t last_pc = 0; int i, line_num, col_num; const uint8_t *buf_start = s->get_line_col_cache->buf_start; js_dbuf_init(s->ctx, &s->pc2line); last_line_num = get_line_col_cached(s->get_line_col_cache, &last_col_num, buf_start + s->source_pos); dbuf_put_leb128(&s->pc2line, last_line_num); /* line number minus 1 */ dbuf_put_leb128(&s->pc2line, last_col_num); /* column number minus 1 */ for (i = 0; i < s->line_number_count; i++) { uint32_t pc = s->line_number_slots[i].pc; uint32_t source_pos = s->line_number_slots[i].source_pos; int diff_pc, diff_line, diff_col; if (source_pos == -1) continue; diff_pc = pc - last_pc; if (diff_pc < 0) continue; line_num = get_line_col_cached(s->get_line_col_cache, &col_num, buf_start + source_pos); diff_line = line_num - last_line_num; diff_col = col_num - last_col_num; if (diff_line == 0 && diff_col == 0) continue; if (diff_line >= PC2LINE_BASE && diff_line < PC2LINE_BASE + PC2LINE_RANGE && diff_pc <= PC2LINE_DIFF_PC_MAX) { dbuf_putc(&s->pc2line, (diff_line - PC2LINE_BASE) + diff_pc * PC2LINE_RANGE + PC2LINE_OP_FIRST); } else { /* longer encoding */ dbuf_putc(&s->pc2line, 0); dbuf_put_leb128(&s->pc2line, diff_pc); dbuf_put_sleb128(&s->pc2line, diff_line); } dbuf_put_sleb128(&s->pc2line, diff_col); last_pc = pc; last_line_num = line_num; last_col_num = col_num; } } } static RelocEntry *add_reloc(JSContext *ctx, LabelSlot *ls, uint32_t addr, int size) { RelocEntry *re; re = js_malloc(ctx, sizeof(*re)); if (!re) return NULL; re->addr = addr; re->size = size; re->next = ls->first_reloc; ls->first_reloc = re; return re; } static BOOL code_has_label(CodeContext *s, int pos, int label) { while (pos < s->bc_len) { int op = s->bc_buf[pos]; if (op == OP_line_num) { pos += 5; continue; } if (op == OP_label) { int lab = get_u32(s->bc_buf + pos + 1); if (lab == label) return TRUE; pos += 5; continue; } if (op == OP_goto) { int lab = get_u32(s->bc_buf + pos + 1); if (lab == label) return TRUE; } break; } return FALSE; } /* return the target label, following the OP_goto jumps the first opcode at destination is stored in *pop */ static int find_jump_target(JSFunctionDef *s, int label0, int *pop, int *pline) { int i, pos, op, label; label = label0; update_label(s, label, -1); for (i = 0; i < 10; i++) { assert(label >= 0 && label < s->label_count); pos = s->label_slots[label].pos2; for (;;) { switch(op = s->byte_code.buf[pos]) { case OP_line_num: if (pline) *pline = get_u32(s->byte_code.buf + pos + 1); /* fall thru */ case OP_label: pos += opcode_info[op].size; continue; case OP_goto: label = get_u32(s->byte_code.buf + pos + 1); break; case OP_drop: /* ignore drop opcodes if followed by OP_return_undef */ while (s->byte_code.buf[++pos] == OP_drop) continue; if (s->byte_code.buf[pos] == OP_return_undef) op = OP_return_undef; /* fall thru */ default: goto done; } break; } } /* cycle detected, could issue a warning */ /* XXX: the combination of find_jump_target() and skip_dead_code() seems incorrect with cyclic labels. See for exemple: for (;;) { l:break l; l:break l; l:break l; l:break l; } Avoiding changing the target is just a workaround and might not suffice to completely fix the problem. */ label = label0; done: *pop = op; update_label(s, label, +1); return label; } static void push_short_int(DynBuf *bc_out, int val) { #if SHORT_OPCODES if (val >= -1 && val <= 7) { dbuf_putc(bc_out, OP_push_0 + val); return; } if (val == (int8_t)val) { dbuf_putc(bc_out, OP_push_i8); dbuf_putc(bc_out, val); return; } if (val == (int16_t)val) { dbuf_putc(bc_out, OP_push_i16); dbuf_put_u16(bc_out, val); return; } #endif dbuf_putc(bc_out, OP_push_i32); dbuf_put_u32(bc_out, val); } static void put_short_code(DynBuf *bc_out, int op, int idx) { #if SHORT_OPCODES if (idx < 4) { switch (op) { case OP_get_loc: dbuf_putc(bc_out, OP_get_loc0 + idx); return; case OP_put_loc: dbuf_putc(bc_out, OP_put_loc0 + idx); return; case OP_set_loc: dbuf_putc(bc_out, OP_set_loc0 + idx); return; case OP_get_arg: dbuf_putc(bc_out, OP_get_arg0 + idx); return; case OP_put_arg: dbuf_putc(bc_out, OP_put_arg0 + idx); return; case OP_set_arg: dbuf_putc(bc_out, OP_set_arg0 + idx); return; case OP_get_var_ref: dbuf_putc(bc_out, OP_get_var_ref0 + idx); return; case OP_put_var_ref: dbuf_putc(bc_out, OP_put_var_ref0 + idx); return; case OP_set_var_ref: dbuf_putc(bc_out, OP_set_var_ref0 + idx); return; case OP_call: dbuf_putc(bc_out, OP_call0 + idx); return; } } if (idx < 256) { switch (op) { case OP_get_loc: dbuf_putc(bc_out, OP_get_loc8); dbuf_putc(bc_out, idx); return; case OP_put_loc: dbuf_putc(bc_out, OP_put_loc8); dbuf_putc(bc_out, idx); return; case OP_set_loc: dbuf_putc(bc_out, OP_set_loc8); dbuf_putc(bc_out, idx); return; } } #endif dbuf_putc(bc_out, op); dbuf_put_u16(bc_out, idx); } /* peephole optimizations and resolve goto/labels */ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) { int pos, pos_next, bc_len, op, op1, len, i, line_num; const uint8_t *bc_buf; DynBuf bc_out; LabelSlot *label_slots, *ls; RelocEntry *re, *re_next; CodeContext cc; int label; #if SHORT_OPCODES JumpSlot *jp; #endif label_slots = s->label_slots; line_num = s->source_pos; cc.bc_buf = bc_buf = s->byte_code.buf; cc.bc_len = bc_len = s->byte_code.size; js_dbuf_bytecode_init(ctx, &bc_out); #if SHORT_OPCODES if (s->jump_size) { s->jump_slots = js_mallocz(s->ctx, sizeof(*s->jump_slots) * s->jump_size); if (s->jump_slots == NULL) return -1; } #endif /* XXX: Should skip this phase if not generating SHORT_OPCODES */ if (s->line_number_size && !s->strip_debug) { s->line_number_slots = js_mallocz(s->ctx, sizeof(*s->line_number_slots) * s->line_number_size); if (s->line_number_slots == NULL) return -1; s->line_number_last = s->source_pos; s->line_number_last_pc = 0; } /* initialize the 'home_object' variable if needed */ if (s->home_object_var_idx >= 0) { dbuf_putc(&bc_out, OP_special_object); dbuf_putc(&bc_out, OP_SPECIAL_OBJECT_HOME_OBJECT); put_short_code(&bc_out, OP_put_loc, s->home_object_var_idx); } /* initialize the 'this.active_func' variable if needed */ if (s->this_active_func_var_idx >= 0) { dbuf_putc(&bc_out, OP_special_object); dbuf_putc(&bc_out, OP_SPECIAL_OBJECT_THIS_FUNC); put_short_code(&bc_out, OP_put_loc, s->this_active_func_var_idx); } /* initialize the 'new.target' variable if needed */ if (s->new_target_var_idx >= 0) { dbuf_putc(&bc_out, OP_special_object); dbuf_putc(&bc_out, OP_SPECIAL_OBJECT_NEW_TARGET); put_short_code(&bc_out, OP_put_loc, s->new_target_var_idx); } /* initialize the 'this' variable if needed. In a derived class constructor, this is initially uninitialized. */ if (s->this_var_idx >= 0) { if (s->is_derived_class_constructor) { dbuf_putc(&bc_out, OP_set_loc_uninitialized); dbuf_put_u16(&bc_out, s->this_var_idx); } else { dbuf_putc(&bc_out, OP_push_this); put_short_code(&bc_out, OP_put_loc, s->this_var_idx); } } /* initialize the 'arguments' variable if needed */ if (s->arguments_var_idx >= 0) { if ((s->js_mode & JS_MODE_STRICT) || !s->has_simple_parameter_list) { dbuf_putc(&bc_out, OP_special_object); dbuf_putc(&bc_out, OP_SPECIAL_OBJECT_ARGUMENTS); } else { dbuf_putc(&bc_out, OP_special_object); dbuf_putc(&bc_out, OP_SPECIAL_OBJECT_MAPPED_ARGUMENTS); /* the arguments are implicitly captured because references to them are created with the 'argument' object */ for(i = 0; i < s->arg_count; i++) capture_var(s, &s->args[i]); } if (s->arguments_arg_idx >= 0) put_short_code(&bc_out, OP_set_loc, s->arguments_arg_idx); put_short_code(&bc_out, OP_put_loc, s->arguments_var_idx); } /* initialize a reference to the current function if needed */ if (s->func_var_idx >= 0) { dbuf_putc(&bc_out, OP_special_object); dbuf_putc(&bc_out, OP_SPECIAL_OBJECT_THIS_FUNC); put_short_code(&bc_out, OP_put_loc, s->func_var_idx); } /* initialize the variable environment object if needed */ if (s->var_object_idx >= 0) { dbuf_putc(&bc_out, OP_special_object); dbuf_putc(&bc_out, OP_SPECIAL_OBJECT_VAR_OBJECT); put_short_code(&bc_out, OP_put_loc, s->var_object_idx); } if (s->arg_var_object_idx >= 0) { dbuf_putc(&bc_out, OP_special_object); dbuf_putc(&bc_out, OP_SPECIAL_OBJECT_VAR_OBJECT); put_short_code(&bc_out, OP_put_loc, s->arg_var_object_idx); } for (pos = 0; pos < bc_len; pos = pos_next) { int val; op = bc_buf[pos]; len = opcode_info[op].size; pos_next = pos + len; switch(op) { case OP_line_num: /* line number info (for debug). We put it in a separate compressed table to reduce memory usage and get better performance */ line_num = get_u32(bc_buf + pos + 1); break; case OP_label: { label = get_u32(bc_buf + pos + 1); assert(label >= 0 && label < s->label_count); ls = &label_slots[label]; assert(ls->addr == -1); ls->addr = bc_out.size; /* resolve the relocation entries */ for(re = ls->first_reloc; re != NULL; re = re_next) { int diff = ls->addr - re->addr; re_next = re->next; switch (re->size) { case 4: put_u32(bc_out.buf + re->addr, diff); break; case 2: assert(diff == (int16_t)diff); put_u16(bc_out.buf + re->addr, diff); break; case 1: assert(diff == (int8_t)diff); put_u8(bc_out.buf + re->addr, diff); break; } js_free(ctx, re); } ls->first_reloc = NULL; } break; case OP_call: case OP_call_method: { /* detect and transform tail calls */ int argc; argc = get_u16(bc_buf + pos + 1); if (code_match(&cc, pos_next, OP_return, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; add_pc2line_info(s, bc_out.size, line_num); put_short_code(&bc_out, op + 1, argc); pos_next = skip_dead_code(s, bc_buf, bc_len, cc.pos, &line_num); break; } add_pc2line_info(s, bc_out.size, line_num); put_short_code(&bc_out, op, argc); break; } goto no_change; case OP_return: case OP_return_undef: case OP_return_async: case OP_throw: case OP_throw_error: pos_next = skip_dead_code(s, bc_buf, bc_len, pos_next, &line_num); goto no_change; case OP_goto: label = get_u32(bc_buf + pos + 1); has_goto: if (OPTIMIZE) { int line1 = -1; /* Use custom matcher because multiple labels can follow */ label = find_jump_target(s, label, &op1, &line1); if (code_has_label(&cc, pos_next, label)) { /* jump to next instruction: remove jump */ update_label(s, label, -1); break; } if (op1 == OP_return || op1 == OP_return_undef || op1 == OP_throw) { /* jump to return/throw: remove jump, append return/throw */ /* updating the line number obfuscates assembly listing */ //if (line1 != -1) line_num = line1; update_label(s, label, -1); add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, op1); pos_next = skip_dead_code(s, bc_buf, bc_len, pos_next, &line_num); break; } /* XXX: should duplicate single instructions followed by goto or return */ /* For example, can match one of these followed by return: push_i32 / push_const / push_atom_value / get_var / undefined / null / push_false / push_true / get_ref_value / get_loc / get_arg / get_var_ref */ } goto has_label; case OP_gosub: label = get_u32(bc_buf + pos + 1); if (0 && OPTIMIZE) { label = find_jump_target(s, label, &op1, NULL); if (op1 == OP_ret) { update_label(s, label, -1); /* empty finally clause: remove gosub */ break; } } goto has_label; case OP_catch: label = get_u32(bc_buf + pos + 1); goto has_label; case OP_if_true: case OP_if_false: label = get_u32(bc_buf + pos + 1); if (OPTIMIZE) { label = find_jump_target(s, label, &op1, NULL); /* transform if_false/if_true(l1) label(l1) -> drop label(l1) */ if (code_has_label(&cc, pos_next, label)) { update_label(s, label, -1); dbuf_putc(&bc_out, OP_drop); break; } /* transform if_false(l1) goto(l2) label(l1) -> if_false(l2) label(l1) */ if (code_match(&cc, pos_next, OP_goto, -1)) { int pos1 = cc.pos; int line1 = cc.line_num; if (code_has_label(&cc, pos1, label)) { if (line1 != -1) line_num = line1; pos_next = pos1; update_label(s, label, -1); label = cc.label; op ^= OP_if_true ^ OP_if_false; } } } has_label: add_pc2line_info(s, bc_out.size, line_num); if (op == OP_goto) { pos_next = skip_dead_code(s, bc_buf, bc_len, pos_next, &line_num); } assert(label >= 0 && label < s->label_count); ls = &label_slots[label]; #if SHORT_OPCODES jp = &s->jump_slots[s->jump_count++]; jp->op = op; jp->size = 4; jp->pos = bc_out.size + 1; jp->label = label; if (ls->addr == -1) { int diff = ls->pos2 - pos - 1; if (diff < 128 && (op == OP_if_false || op == OP_if_true || op == OP_goto)) { jp->size = 1; jp->op = OP_if_false8 + (op - OP_if_false); dbuf_putc(&bc_out, OP_if_false8 + (op - OP_if_false)); dbuf_putc(&bc_out, 0); if (!add_reloc(ctx, ls, bc_out.size - 1, 1)) goto fail; break; } if (diff < 32768 && op == OP_goto) { jp->size = 2; jp->op = OP_goto16; dbuf_putc(&bc_out, OP_goto16); dbuf_put_u16(&bc_out, 0); if (!add_reloc(ctx, ls, bc_out.size - 2, 2)) goto fail; break; } } else { int diff = ls->addr - bc_out.size - 1; if (diff == (int8_t)diff && (op == OP_if_false || op == OP_if_true || op == OP_goto)) { jp->size = 1; jp->op = OP_if_false8 + (op - OP_if_false); dbuf_putc(&bc_out, OP_if_false8 + (op - OP_if_false)); dbuf_putc(&bc_out, diff); break; } if (diff == (int16_t)diff && op == OP_goto) { jp->size = 2; jp->op = OP_goto16; dbuf_putc(&bc_out, OP_goto16); dbuf_put_u16(&bc_out, diff); break; } } #endif dbuf_putc(&bc_out, op); dbuf_put_u32(&bc_out, ls->addr - bc_out.size); if (ls->addr == -1) { /* unresolved yet: create a new relocation entry */ if (!add_reloc(ctx, ls, bc_out.size - 4, 4)) goto fail; } break; case OP_with_get_var: case OP_with_put_var: case OP_with_delete_var: case OP_with_make_ref: case OP_with_get_ref: { JSAtom atom; int is_with; atom = get_u32(bc_buf + pos + 1); label = get_u32(bc_buf + pos + 5); is_with = bc_buf[pos + 9]; if (OPTIMIZE) { label = find_jump_target(s, label, &op1, NULL); } assert(label >= 0 && label < s->label_count); ls = &label_slots[label]; add_pc2line_info(s, bc_out.size, line_num); #if SHORT_OPCODES jp = &s->jump_slots[s->jump_count++]; jp->op = op; jp->size = 4; jp->pos = bc_out.size + 5; jp->label = label; #endif dbuf_putc(&bc_out, op); dbuf_put_u32(&bc_out, atom); dbuf_put_u32(&bc_out, ls->addr - bc_out.size); if (ls->addr == -1) { /* unresolved yet: create a new relocation entry */ if (!add_reloc(ctx, ls, bc_out.size - 4, 4)) goto fail; } dbuf_putc(&bc_out, is_with); } break; case OP_drop: if (OPTIMIZE) { /* remove useless drops before return */ if (code_match(&cc, pos_next, OP_return_undef, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; break; } } goto no_change; case OP_null: #if SHORT_OPCODES if (OPTIMIZE) { /* transform null strict_eq into is_null */ if (code_match(&cc, pos_next, OP_strict_eq, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, OP_is_null); pos_next = cc.pos; break; } /* transform null strict_neq if_false/if_true -> is_null if_true/if_false */ if (code_match(&cc, pos_next, OP_strict_neq, M2(OP_if_false, OP_if_true), -1)) { if (cc.line_num >= 0) line_num = cc.line_num; add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, OP_is_null); pos_next = cc.pos; label = cc.label; op = cc.op ^ OP_if_false ^ OP_if_true; goto has_label; } } #endif /* fall thru */ case OP_push_false: case OP_push_true: if (OPTIMIZE) { val = (op == OP_push_true); if (code_match(&cc, pos_next, M2(OP_if_false, OP_if_true), -1)) { has_constant_test: if (cc.line_num >= 0) line_num = cc.line_num; if (val == cc.op - OP_if_false) { /* transform null if_false(l1) -> goto l1 */ /* transform false if_false(l1) -> goto l1 */ /* transform true if_true(l1) -> goto l1 */ pos_next = cc.pos; op = OP_goto; label = cc.label; goto has_goto; } else { /* transform null if_true(l1) -> nop */ /* transform false if_true(l1) -> nop */ /* transform true if_false(l1) -> nop */ pos_next = cc.pos; update_label(s, cc.label, -1); break; } } } goto no_change; case OP_push_i32: if (OPTIMIZE) { /* transform i32(val) neg -> i32(-val) */ val = get_i32(bc_buf + pos + 1); if ((val != INT32_MIN && val != 0) && code_match(&cc, pos_next, OP_neg, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; if (code_match(&cc, cc.pos, OP_drop, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; } else { add_pc2line_info(s, bc_out.size, line_num); push_short_int(&bc_out, -val); } pos_next = cc.pos; break; } /* remove push/drop pairs generated by the parser */ if (code_match(&cc, pos_next, OP_drop, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; pos_next = cc.pos; break; } /* Optimize constant tests: `if (0)`, `if (1)`, `if (!0)`... */ if (code_match(&cc, pos_next, M2(OP_if_false, OP_if_true), -1)) { val = (val != 0); goto has_constant_test; } add_pc2line_info(s, bc_out.size, line_num); push_short_int(&bc_out, val); break; } goto no_change; case OP_push_bigint_i32: if (OPTIMIZE) { /* transform i32(val) neg -> i32(-val) */ val = get_i32(bc_buf + pos + 1); if (val != INT32_MIN && code_match(&cc, pos_next, OP_neg, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; if (code_match(&cc, cc.pos, OP_drop, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; } else { add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, OP_push_bigint_i32); dbuf_put_u32(&bc_out, -val); } pos_next = cc.pos; break; } } goto no_change; #if SHORT_OPCODES case OP_push_const: case OP_fclosure: if (OPTIMIZE) { int idx = get_u32(bc_buf + pos + 1); if (idx < 256) { add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, OP_push_const8 + op - OP_push_const); dbuf_putc(&bc_out, idx); break; } } goto no_change; case OP_get_field: if (OPTIMIZE) { JSAtom atom = get_u32(bc_buf + pos + 1); if (atom == JS_ATOM_length) { JS_FreeAtom(ctx, atom); add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, OP_get_length); break; } } goto no_change; #endif case OP_push_atom_value: if (OPTIMIZE) { JSAtom atom = get_u32(bc_buf + pos + 1); /* remove push/drop pairs generated by the parser */ if (code_match(&cc, pos_next, OP_drop, -1)) { JS_FreeAtom(ctx, atom); if (cc.line_num >= 0) line_num = cc.line_num; pos_next = cc.pos; break; } #if SHORT_OPCODES if (atom == JS_ATOM_empty_string) { JS_FreeAtom(ctx, atom); add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, OP_push_empty_string); break; } #endif } goto no_change; case OP_to_propkey: if (OPTIMIZE) { /* remove redundant to_propkey opcodes when storing simple data */ if (code_match(&cc, pos_next, M3(OP_get_loc, OP_get_arg, OP_get_var_ref), -1, OP_put_array_el, -1) || code_match(&cc, pos_next, M3(OP_push_i32, OP_push_const, OP_push_atom_value), OP_put_array_el, -1) || code_match(&cc, pos_next, M4(OP_undefined, OP_null, OP_push_true, OP_push_false), OP_put_array_el, -1)) { break; } } goto no_change; case OP_undefined: if (OPTIMIZE) { /* remove push/drop pairs generated by the parser */ if (code_match(&cc, pos_next, OP_drop, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; pos_next = cc.pos; break; } /* transform undefined return -> return_undefined */ if (code_match(&cc, pos_next, OP_return, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, OP_return_undef); pos_next = cc.pos; break; } /* transform undefined if_true(l1)/if_false(l1) -> nop/goto(l1) */ if (code_match(&cc, pos_next, M2(OP_if_false, OP_if_true), -1)) { val = 0; goto has_constant_test; } #if SHORT_OPCODES /* transform undefined strict_eq -> is_undefined */ if (code_match(&cc, pos_next, OP_strict_eq, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, OP_is_undefined); pos_next = cc.pos; break; } /* transform undefined strict_neq if_false/if_true -> is_undefined if_true/if_false */ if (code_match(&cc, pos_next, OP_strict_neq, M2(OP_if_false, OP_if_true), -1)) { if (cc.line_num >= 0) line_num = cc.line_num; add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, OP_is_undefined); pos_next = cc.pos; label = cc.label; op = cc.op ^ OP_if_false ^ OP_if_true; goto has_label; } #endif } goto no_change; case OP_insert2: if (OPTIMIZE) { /* Transformation: insert2 put_field(a) drop -> put_field(a) */ if (code_match(&cc, pos_next, OP_put_field, OP_drop, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, OP_put_field); dbuf_put_u32(&bc_out, cc.atom); pos_next = cc.pos; break; } } goto no_change; case OP_dup: if (OPTIMIZE) { /* Transformation: dup put_x(n) drop -> put_x(n) */ int op1, line2 = -1; /* Transformation: dup put_x(n) -> set_x(n) */ if (code_match(&cc, pos_next, M4(OP_put_loc, OP_put_loc_check, OP_put_arg, OP_put_var_ref), -1, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; op1 = cc.op + 1; /* put_x -> set_x */ pos_next = cc.pos; if (code_match(&cc, cc.pos, OP_drop, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; op1 -= 1; /* set_x drop -> put_x */ pos_next = cc.pos; if (code_match(&cc, cc.pos, op1 - 1, cc.idx, -1)) { line2 = cc.line_num; /* delay line number update */ op1 += 1; /* put_x(n) get_x(n) -> set_x(n) */ pos_next = cc.pos; } } add_pc2line_info(s, bc_out.size, line_num); put_short_code(&bc_out, op1, cc.idx); if (line2 >= 0) line_num = line2; break; } } goto no_change; case OP_get_loc: if (OPTIMIZE) { /* transformation: get_loc(n) post_dec put_loc(n) drop -> dec_loc(n) get_loc(n) post_inc put_loc(n) drop -> inc_loc(n) get_loc(n) dec dup put_loc(n) drop -> dec_loc(n) get_loc(n) inc dup put_loc(n) drop -> inc_loc(n) */ int idx; idx = get_u16(bc_buf + pos + 1); if (idx >= 256) goto no_change; if (code_match(&cc, pos_next, M2(OP_post_dec, OP_post_inc), OP_put_loc, idx, OP_drop, -1) || code_match(&cc, pos_next, M2(OP_dec, OP_inc), OP_dup, OP_put_loc, idx, OP_drop, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, (cc.op == OP_inc || cc.op == OP_post_inc) ? OP_inc_loc : OP_dec_loc); dbuf_putc(&bc_out, idx); pos_next = cc.pos; break; } /* transformation: get_loc(n) push_atom_value(x) add dup put_loc(n) drop -> push_atom_value(x) add_loc(n) */ if (code_match(&cc, pos_next, OP_push_atom_value, OP_add, OP_dup, OP_put_loc, idx, OP_drop, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; add_pc2line_info(s, bc_out.size, line_num); #if SHORT_OPCODES if (cc.atom == JS_ATOM_empty_string) { JS_FreeAtom(ctx, cc.atom); dbuf_putc(&bc_out, OP_push_empty_string); } else #endif { dbuf_putc(&bc_out, OP_push_atom_value); dbuf_put_u32(&bc_out, cc.atom); } dbuf_putc(&bc_out, OP_add_loc); dbuf_putc(&bc_out, idx); pos_next = cc.pos; break; } /* transformation: get_loc(n) push_i32(x) add dup put_loc(n) drop -> push_i32(x) add_loc(n) */ if (code_match(&cc, pos_next, OP_push_i32, OP_add, OP_dup, OP_put_loc, idx, OP_drop, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; add_pc2line_info(s, bc_out.size, line_num); push_short_int(&bc_out, cc.label); dbuf_putc(&bc_out, OP_add_loc); dbuf_putc(&bc_out, idx); pos_next = cc.pos; break; } /* transformation: XXX: also do these: get_loc(n) get_loc(x) add dup put_loc(n) drop -> get_loc(x) add_loc(n) get_loc(n) get_arg(x) add dup put_loc(n) drop -> get_arg(x) add_loc(n) get_loc(n) get_var_ref(x) add dup put_loc(n) drop -> get_var_ref(x) add_loc(n) */ if (code_match(&cc, pos_next, M3(OP_get_loc, OP_get_arg, OP_get_var_ref), -1, OP_add, OP_dup, OP_put_loc, idx, OP_drop, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; add_pc2line_info(s, bc_out.size, line_num); put_short_code(&bc_out, cc.op, cc.idx); dbuf_putc(&bc_out, OP_add_loc); dbuf_putc(&bc_out, idx); pos_next = cc.pos; break; } add_pc2line_info(s, bc_out.size, line_num); put_short_code(&bc_out, op, idx); break; } goto no_change; #if SHORT_OPCODES case OP_get_arg: case OP_get_var_ref: if (OPTIMIZE) { int idx; idx = get_u16(bc_buf + pos + 1); add_pc2line_info(s, bc_out.size, line_num); put_short_code(&bc_out, op, idx); break; } goto no_change; #endif case OP_put_loc: case OP_put_loc_check: case OP_put_arg: case OP_put_var_ref: if (OPTIMIZE) { /* transformation: put_x(n) get_x(n) -> set_x(n) */ int idx; idx = get_u16(bc_buf + pos + 1); if (code_match(&cc, pos_next, op - 1, idx, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; add_pc2line_info(s, bc_out.size, line_num); put_short_code(&bc_out, op + 1, idx); pos_next = cc.pos; break; } add_pc2line_info(s, bc_out.size, line_num); put_short_code(&bc_out, op, idx); break; } goto no_change; case OP_post_inc: case OP_post_dec: if (OPTIMIZE) { /* transformation: post_inc put_x drop -> inc put_x post_inc perm3 put_field drop -> inc put_field post_inc perm4 put_array_el drop -> inc put_array_el */ int op1, idx; if (code_match(&cc, pos_next, M3(OP_put_loc, OP_put_arg, OP_put_var_ref), -1, OP_drop, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; op1 = cc.op; idx = cc.idx; pos_next = cc.pos; if (code_match(&cc, cc.pos, op1 - 1, idx, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; op1 += 1; /* put_x(n) get_x(n) -> set_x(n) */ pos_next = cc.pos; } add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, OP_dec + (op - OP_post_dec)); put_short_code(&bc_out, op1, idx); break; } if (code_match(&cc, pos_next, OP_perm3, OP_put_field, OP_drop, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, OP_dec + (op - OP_post_dec)); dbuf_putc(&bc_out, OP_put_field); dbuf_put_u32(&bc_out, cc.atom); pos_next = cc.pos; break; } if (code_match(&cc, pos_next, OP_perm4, OP_put_array_el, OP_drop, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, OP_dec + (op - OP_post_dec)); dbuf_putc(&bc_out, OP_put_array_el); pos_next = cc.pos; break; } } goto no_change; #if SHORT_OPCODES case OP_typeof: if (OPTIMIZE) { /* simplify typeof tests */ if (code_match(&cc, pos_next, OP_push_atom_value, M4(OP_strict_eq, OP_strict_neq, OP_eq, OP_neq), -1)) { if (cc.line_num >= 0) line_num = cc.line_num; int op1 = (cc.op == OP_strict_eq || cc.op == OP_eq) ? OP_strict_eq : OP_strict_neq; int op2 = -1; switch (cc.atom) { case JS_ATOM_undefined: op2 = OP_typeof_is_undefined; break; case JS_ATOM_function: op2 = OP_typeof_is_function; break; } if (op2 >= 0) { /* transform typeof(s) == "<type>" into is_<type> */ if (op1 == OP_strict_eq) { add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, op2); JS_FreeAtom(ctx, cc.atom); pos_next = cc.pos; break; } if (op1 == OP_strict_neq && code_match(&cc, cc.pos, OP_if_false, -1)) { /* transform typeof(s) != "<type>" if_false into is_<type> if_true */ if (cc.line_num >= 0) line_num = cc.line_num; add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, op2); JS_FreeAtom(ctx, cc.atom); pos_next = cc.pos; label = cc.label; op = OP_if_true; goto has_label; } } } } goto no_change; #endif default: no_change: add_pc2line_info(s, bc_out.size, line_num); dbuf_put(&bc_out, bc_buf + pos, len); break; } } /* check that there were no missing labels */ for(i = 0; i < s->label_count; i++) { assert(label_slots[i].first_reloc == NULL); } #if SHORT_OPCODES if (OPTIMIZE) { /* more jump optimizations */ int patch_offsets = 0; for (i = 0, jp = s->jump_slots; i < s->jump_count; i++, jp++) { LabelSlot *ls; JumpSlot *jp1; int j, pos, diff, delta; delta = 3; switch (op = jp->op) { case OP_goto16: delta = 1; /* fall thru */ case OP_if_false: case OP_if_true: case OP_goto: pos = jp->pos; diff = s->label_slots[jp->label].addr - pos; if (diff >= -128 && diff <= 127 + delta) { //put_u8(bc_out.buf + pos, diff); jp->size = 1; if (op == OP_goto16) { bc_out.buf[pos - 1] = jp->op = OP_goto8; } else { bc_out.buf[pos - 1] = jp->op = OP_if_false8 + (op - OP_if_false); } goto shrink; } else if (diff == (int16_t)diff && op == OP_goto) { //put_u16(bc_out.buf + pos, diff); jp->size = 2; delta = 2; bc_out.buf[pos - 1] = jp->op = OP_goto16; shrink: /* XXX: should reduce complexity, using 2 finger copy scheme */ memmove(bc_out.buf + pos + jp->size, bc_out.buf + pos + jp->size + delta, bc_out.size - pos - jp->size - delta); bc_out.size -= delta; patch_offsets++; for (j = 0, ls = s->label_slots; j < s->label_count; j++, ls++) { if (ls->addr > pos) ls->addr -= delta; } for (j = i + 1, jp1 = jp + 1; j < s->jump_count; j++, jp1++) { if (jp1->pos > pos) jp1->pos -= delta; } for (j = 0; j < s->line_number_count; j++) { if (s->line_number_slots[j].pc > pos) s->line_number_slots[j].pc -= delta; } continue; } break; } } if (patch_offsets) { JumpSlot *jp1; int j; for (j = 0, jp1 = s->jump_slots; j < s->jump_count; j++, jp1++) { int diff1 = s->label_slots[jp1->label].addr - jp1->pos; switch (jp1->size) { case 1: put_u8(bc_out.buf + jp1->pos, diff1); break; case 2: put_u16(bc_out.buf + jp1->pos, diff1); break; case 4: put_u32(bc_out.buf + jp1->pos, diff1); break; } } } } js_free(ctx, s->jump_slots); s->jump_slots = NULL; #endif js_free(ctx, s->label_slots); s->label_slots = NULL; /* XXX: should delay until copying to runtime bytecode function */ compute_pc2line_info(s); js_free(ctx, s->line_number_slots); s->line_number_slots = NULL; /* set the new byte code */ dbuf_free(&s->byte_code); s->byte_code = bc_out; s->use_short_opcodes = TRUE; if (dbuf_error(&s->byte_code)) { JS_ThrowOutOfMemory(ctx); return -1; } return 0; fail: /* XXX: not safe */ dbuf_free(&bc_out); return -1; } /* compute the maximum stack size needed by the function */ typedef struct StackSizeState { int bc_len; int stack_len_max; uint16_t *stack_level_tab; int32_t *catch_pos_tab; int *pc_stack; int pc_stack_len; int pc_stack_size; } StackSizeState; /* 'op' is only used for error indication */ static __exception int ss_check(JSContext *ctx, StackSizeState *s, int pos, int op, int stack_len, int catch_pos) { if ((unsigned)pos >= s->bc_len) { JS_ThrowInternalError(ctx, "bytecode buffer overflow (op=%d, pc=%d)", op, pos); return -1; } if (stack_len > s->stack_len_max) { s->stack_len_max = stack_len; if (s->stack_len_max > JS_STACK_SIZE_MAX) { JS_ThrowInternalError(ctx, "stack overflow (op=%d, pc=%d)", op, pos); return -1; } } if (s->stack_level_tab[pos] != 0xffff) { /* already explored: check that the stack size is consistent */ if (s->stack_level_tab[pos] != stack_len) { JS_ThrowInternalError(ctx, "inconsistent stack size: %d %d (pc=%d)", s->stack_level_tab[pos], stack_len, pos); return -1; } else if (s->catch_pos_tab[pos] != catch_pos) { JS_ThrowInternalError(ctx, "inconsistent catch position: %d %d (pc=%d)", s->catch_pos_tab[pos], catch_pos, pos); return -1; } else { return 0; } } /* mark as explored and store the stack size */ s->stack_level_tab[pos] = stack_len; s->catch_pos_tab[pos] = catch_pos; /* queue the new PC to explore */ if (js_resize_array(ctx, (void **)&s->pc_stack, sizeof(s->pc_stack[0]), &s->pc_stack_size, s->pc_stack_len + 1)) return -1; s->pc_stack[s->pc_stack_len++] = pos; return 0; } static __exception int compute_stack_size(JSContext *ctx, JSFunctionDef *fd, int *pstack_size) { StackSizeState s_s, *s = &s_s; int i, diff, n_pop, pos_next, stack_len, pos, op, catch_pos, catch_level; const JSOpCode *oi; const uint8_t *bc_buf; bc_buf = fd->byte_code.buf; s->bc_len = fd->byte_code.size; /* bc_len > 0 */ s->stack_level_tab = js_malloc(ctx, sizeof(s->stack_level_tab[0]) * s->bc_len); if (!s->stack_level_tab) return -1; for(i = 0; i < s->bc_len; i++) s->stack_level_tab[i] = 0xffff; s->pc_stack = NULL; s->catch_pos_tab = js_malloc(ctx, sizeof(s->catch_pos_tab[0]) * s->bc_len); if (!s->catch_pos_tab) goto fail; s->stack_len_max = 0; s->pc_stack_len = 0; s->pc_stack_size = 0; /* breadth-first graph exploration */ if (ss_check(ctx, s, 0, OP_invalid, 0, -1)) goto fail; while (s->pc_stack_len > 0) { pos = s->pc_stack[--s->pc_stack_len]; stack_len = s->stack_level_tab[pos]; catch_pos = s->catch_pos_tab[pos]; op = bc_buf[pos]; if (op == 0 || op >= OP_COUNT) { JS_ThrowInternalError(ctx, "invalid opcode (op=%d, pc=%d)", op, pos); goto fail; } oi = &short_opcode_info(op); #if defined(DUMP_BYTECODE) && (DUMP_BYTECODE & 64) printf("%5d: %10s %5d %5d\n", pos, oi->name, stack_len, catch_pos); #endif pos_next = pos + oi->size; if (pos_next > s->bc_len) { JS_ThrowInternalError(ctx, "bytecode buffer overflow (op=%d, pc=%d)", op, pos); goto fail; } n_pop = oi->n_pop; /* call pops a variable number of arguments */ if (oi->fmt == OP_FMT_npop || oi->fmt == OP_FMT_npop_u16) { n_pop += get_u16(bc_buf + pos + 1); } else { #if SHORT_OPCODES if (oi->fmt == OP_FMT_npopx) { n_pop += op - OP_call0; } #endif } if (stack_len < n_pop) { JS_ThrowInternalError(ctx, "stack underflow (op=%d, pc=%d)", op, pos); goto fail; } stack_len += oi->n_push - n_pop; if (stack_len > s->stack_len_max) { s->stack_len_max = stack_len; if (s->stack_len_max > JS_STACK_SIZE_MAX) { JS_ThrowInternalError(ctx, "stack overflow (op=%d, pc=%d)", op, pos); goto fail; } } switch(op) { case OP_tail_call: case OP_tail_call_method: case OP_return: case OP_return_undef: case OP_return_async: case OP_throw: case OP_throw_error: case OP_ret: goto done_insn; case OP_goto: diff = get_u32(bc_buf + pos + 1); pos_next = pos + 1 + diff; break; #if SHORT_OPCODES case OP_goto16: diff = (int16_t)get_u16(bc_buf + pos + 1); pos_next = pos + 1 + diff; break; case OP_goto8: diff = (int8_t)bc_buf[pos + 1]; pos_next = pos + 1 + diff; break; case OP_if_true8: case OP_if_false8: diff = (int8_t)bc_buf[pos + 1]; if (ss_check(ctx, s, pos + 1 + diff, op, stack_len, catch_pos)) goto fail; break; #endif case OP_if_true: case OP_if_false: diff = get_u32(bc_buf + pos + 1); if (ss_check(ctx, s, pos + 1 + diff, op, stack_len, catch_pos)) goto fail; break; case OP_gosub: diff = get_u32(bc_buf + pos + 1); if (ss_check(ctx, s, pos + 1 + diff, op, stack_len + 1, catch_pos)) goto fail; break; case OP_with_get_var: case OP_with_delete_var: diff = get_u32(bc_buf + pos + 5); if (ss_check(ctx, s, pos + 5 + diff, op, stack_len + 1, catch_pos)) goto fail; break; case OP_with_make_ref: case OP_with_get_ref: diff = get_u32(bc_buf + pos + 5); if (ss_check(ctx, s, pos + 5 + diff, op, stack_len + 2, catch_pos)) goto fail; break; case OP_with_put_var: diff = get_u32(bc_buf + pos + 5); if (ss_check(ctx, s, pos + 5 + diff, op, stack_len - 1, catch_pos)) goto fail; break; case OP_catch: diff = get_u32(bc_buf + pos + 1); if (ss_check(ctx, s, pos + 1 + diff, op, stack_len, catch_pos)) goto fail; catch_pos = pos; break; case OP_for_of_start: case OP_for_await_of_start: catch_pos = pos; break; /* we assume the catch offset entry is only removed with some op codes */ case OP_drop: catch_level = stack_len; goto check_catch; case OP_nip: catch_level = stack_len - 1; goto check_catch; case OP_nip1: catch_level = stack_len - 1; goto check_catch; case OP_iterator_close: catch_level = stack_len + 2; check_catch: /* Note: for for_of_start/for_await_of_start we consider the catch offset is on the first stack entry instead of the thirst */ if (catch_pos >= 0) { int level; level = s->stack_level_tab[catch_pos]; if (bc_buf[catch_pos] != OP_catch) level++; /* for_of_start, for_wait_of_start */ /* catch_level = stack_level before op_catch is executed ? */ if (catch_level == level) { catch_pos = s->catch_pos_tab[catch_pos]; } } break; case OP_nip_catch: if (catch_pos < 0) { JS_ThrowInternalError(ctx, "nip_catch: no catch op (pc=%d)", pos); goto fail; } stack_len = s->stack_level_tab[catch_pos]; if (bc_buf[catch_pos] != OP_catch) stack_len++; /* for_of_start, for_wait_of_start */ stack_len++; /* no stack overflow is possible by construction */ catch_pos = s->catch_pos_tab[catch_pos]; break; default: break; } if (ss_check(ctx, s, pos_next, op, stack_len, catch_pos)) goto fail; done_insn: ; } js_free(ctx, s->pc_stack); js_free(ctx, s->catch_pos_tab); js_free(ctx, s->stack_level_tab); *pstack_size = s->stack_len_max; return 0; fail: js_free(ctx, s->pc_stack); js_free(ctx, s->catch_pos_tab); js_free(ctx, s->stack_level_tab); *pstack_size = 0; return -1; } static int add_global_variables(JSContext *ctx, JSFunctionDef *fd) { int i, idx; JSModuleDef *m = fd->module; JSExportEntry *me; JSGlobalVar *hf; BOOL need_global_closures; /* Script: add the defined global variables. In the non strict direct eval not in global scope, the global variables are created in the enclosing scope so they are not created as variable references. In modules, the imported global variables were added as closure global variables in js_parse_import(). */ need_global_closures = TRUE; if (fd->eval_type == JS_EVAL_TYPE_DIRECT && !(fd->js_mode & JS_MODE_STRICT)) { /* XXX: add a flag ? */ for(idx = 0; idx < fd->closure_var_count; idx++) { JSClosureVar *cv = &fd->closure_var[idx]; if (cv->var_name == JS_ATOM__var_ || cv->var_name == JS_ATOM__arg_var_) { need_global_closures = FALSE; break; } } } if (need_global_closures) { JSClosureTypeEnum closure_type; if (fd->module) closure_type = JS_CLOSURE_MODULE_DECL; else closure_type = JS_CLOSURE_GLOBAL_DECL; for(i = 0; i < fd->global_var_count; i++) { JSVarKindEnum var_kind; hf = &fd->global_vars[i]; if (hf->cpool_idx >= 0 && !hf->is_lexical) { var_kind = JS_VAR_GLOBAL_FUNCTION_DECL; } else { var_kind = JS_VAR_NORMAL; } if (add_closure_var(ctx, fd, closure_type, i, hf->var_name, hf->is_const, hf->is_lexical, var_kind) < 0) return -1; } } if (fd->module) { /* resolve the variable names of the local exports */ for(i = 0; i < m->export_entries_count; i++) { me = &m->export_entries[i]; if (me->export_type == JS_EXPORT_TYPE_LOCAL) { idx = find_closure_var(ctx, fd, me->local_name); if (idx < 0) { JS_ThrowSyntaxErrorAtom(ctx, "exported variable '%s' does not exist", me->local_name); return -1; } me->u.local.var_idx = idx; } } } return 0; } /* create a function object from a function definition. The function definition is freed. All the child functions are also created. It must be done this way to resolve all the variables. */ static JSValue js_create_function(JSContext *ctx, JSFunctionDef *fd) { JSValue func_obj; JSFunctionBytecode *b; struct list_head *el, *el1; int stack_size, scope, idx; int function_size, byte_code_offset, cpool_offset; int closure_var_offset, vardefs_offset; BOOL strip_var_debug; /* recompute scope linkage */ for (scope = 0; scope < fd->scope_count; scope++) { fd->scopes[scope].first = -1; } if (fd->has_parameter_expressions) { /* special end of variable list marker for the argument scope */ fd->scopes[ARG_SCOPE_INDEX].first = ARG_SCOPE_END; } for (idx = 0; idx < fd->var_count; idx++) { JSVarDef *vd = &fd->vars[idx]; vd->scope_next = fd->scopes[vd->scope_level].first; fd->scopes[vd->scope_level].first = idx; } for (scope = 2; scope < fd->scope_count; scope++) { JSVarScope *sd = &fd->scopes[scope]; if (sd->first < 0) sd->first = fd->scopes[sd->parent].first; } for (idx = 0; idx < fd->var_count; idx++) { JSVarDef *vd = &fd->vars[idx]; if (vd->scope_next < 0 && vd->scope_level > 1) { scope = fd->scopes[vd->scope_level].parent; vd->scope_next = fd->scopes[scope].first; } } /* if the function contains an eval call, the closure variables are used to compile the eval and they must be ordered by scope, so it is necessary to create the closure variables before any other variable lookup is done. */ if (fd->has_eval_call) add_eval_variables(ctx, fd); /* add the module global variables in the closure */ if (fd->is_eval) { if (add_global_variables(ctx, fd)) goto fail; } /* first create all the child functions */ list_for_each_safe(el, el1, &fd->child_list) { JSFunctionDef *fd1; int cpool_idx; fd1 = list_entry(el, JSFunctionDef, link); cpool_idx = fd1->parent_cpool_idx; func_obj = js_create_function(ctx, fd1); if (JS_IsException(func_obj)) goto fail; /* save it in the constant pool */ assert(cpool_idx >= 0); fd->cpool[cpool_idx] = func_obj; } #if defined(DUMP_BYTECODE) && (DUMP_BYTECODE & 4) if (!fd->strip_debug) { printf("pass 1\n"); dump_byte_code(ctx, 1, fd->byte_code.buf, fd->byte_code.size, NULL, fd->args, fd->arg_count, fd->vars, fd->var_count, fd->closure_var, fd->closure_var_count, fd->cpool, fd->cpool_count, fd->source, fd->label_slots, NULL); printf("\n"); } #endif if (resolve_variables(ctx, fd)) goto fail; #if defined(DUMP_BYTECODE) && (DUMP_BYTECODE & 2) if (!fd->strip_debug) { printf("pass 2\n"); dump_byte_code(ctx, 2, fd->byte_code.buf, fd->byte_code.size, NULL, fd->args, fd->arg_count, fd->vars, fd->var_count, fd->closure_var, fd->closure_var_count, fd->cpool, fd->cpool_count, fd->source, fd->label_slots, NULL); printf("\n"); } #endif if (resolve_labels(ctx, fd)) goto fail; if (compute_stack_size(ctx, fd, &stack_size) < 0) goto fail; if (fd->strip_debug) { function_size = offsetof(JSFunctionBytecode, debug); } else { function_size = sizeof(*b); } cpool_offset = function_size; function_size += fd->cpool_count * sizeof(*fd->cpool); vardefs_offset = function_size; function_size += (fd->arg_count + fd->var_count) * sizeof(*b->vardefs); closure_var_offset = function_size; function_size += fd->closure_var_count * sizeof(*fd->closure_var); byte_code_offset = function_size; function_size += fd->byte_code.size; b = js_mallocz(ctx, function_size); if (!b) goto fail; b->header.ref_count = 1; b->byte_code_buf = (void *)((uint8_t*)b + byte_code_offset); b->byte_code_len = fd->byte_code.size; memcpy(b->byte_code_buf, fd->byte_code.buf, fd->byte_code.size); js_free(ctx, fd->byte_code.buf); fd->byte_code.buf = NULL; strip_var_debug = fd->strip_debug && !fd->has_eval_call; /* XXX: check */ b->func_name = fd->func_name; if (fd->arg_count + fd->var_count > 0) { int i; b->vardefs = (void *)((uint8_t*)b + vardefs_offset); for(i = 0; i < fd->arg_count; i++) { JSVarDef *vd = &fd->args[i]; JSBytecodeVarDef *vd1 = &b->vardefs[i]; if (strip_var_debug) { JS_FreeAtom(ctx, vd->var_name); vd1->var_name = JS_ATOM_NULL; } else { vd1->var_name = vd->var_name; } vd1->has_scope = (vd->scope_level != 0); vd1->scope_next = vd->scope_next; vd1->is_const = vd->is_const; vd1->is_lexical = vd->is_lexical; vd1->is_captured = vd->is_captured; vd1->var_kind = vd->var_kind; vd1->var_ref_idx = vd->var_ref_idx; } for(i = 0; i < fd->var_count; i++) { JSVarDef *vd = &fd->vars[i]; JSBytecodeVarDef *vd1 = &b->vardefs[i + fd->arg_count]; if (strip_var_debug) { JS_FreeAtom(ctx, vd->var_name); vd1->var_name = JS_ATOM_NULL; } else { vd1->var_name = vd->var_name; } vd1->has_scope = (vd->scope_level != 0); vd1->scope_next = vd->scope_next; vd1->is_const = vd->is_const; vd1->is_lexical = vd->is_lexical; vd1->is_captured = vd->is_captured; vd1->var_kind = vd->var_kind; vd1->var_ref_idx = vd->var_ref_idx; } b->var_count = fd->var_count; b->arg_count = fd->arg_count; b->defined_arg_count = fd->defined_arg_count; b->var_ref_count = fd->var_ref_count; js_free(ctx, fd->args); js_free(ctx, fd->vars); } b->cpool_count = fd->cpool_count; if (b->cpool_count) { b->cpool = (void *)((uint8_t*)b + cpool_offset); memcpy(b->cpool, fd->cpool, b->cpool_count * sizeof(*b->cpool)); } js_free(ctx, fd->cpool); fd->cpool = NULL; b->stack_size = stack_size; if (fd->strip_debug) { JS_FreeAtom(ctx, fd->filename); dbuf_free(&fd->pc2line); // probably useless } else { /* XXX: source and pc2line info should be packed at the end of the JSFunctionBytecode structure, avoiding allocation overhead */ b->has_debug = 1; b->debug.filename = fd->filename; //DynBuf pc2line; //compute_pc2line_info(fd, &pc2line); //js_free(ctx, fd->line_number_slots) b->debug.pc2line_buf = js_realloc(ctx, fd->pc2line.buf, fd->pc2line.size); if (!b->debug.pc2line_buf) b->debug.pc2line_buf = fd->pc2line.buf; b->debug.pc2line_len = fd->pc2line.size; b->debug.source = fd->source; b->debug.source_len = fd->source_len; } if (fd->scopes != fd->def_scope_array) js_free(ctx, fd->scopes); b->closure_var_count = fd->closure_var_count; if (b->closure_var_count) { if (strip_var_debug) { int i; for(i = 0; i < fd->closure_var_count; i++) { JSClosureVar *cv = &fd->closure_var[i]; if (cv->closure_type != JS_CLOSURE_GLOBAL_REF && cv->closure_type != JS_CLOSURE_GLOBAL_DECL && cv->closure_type != JS_CLOSURE_GLOBAL && cv->closure_type != JS_CLOSURE_MODULE_DECL && cv->closure_type != JS_CLOSURE_MODULE_IMPORT) { JS_FreeAtom(ctx, cv->var_name); cv->var_name = JS_ATOM_NULL; } } } b->closure_var = (void *)((uint8_t*)b + closure_var_offset); memcpy(b->closure_var, fd->closure_var, b->closure_var_count * sizeof(*b->closure_var)); } js_free(ctx, fd->closure_var); fd->closure_var = NULL; b->has_prototype = fd->has_prototype; b->has_simple_parameter_list = fd->has_simple_parameter_list; b->js_mode = fd->js_mode; b->is_derived_class_constructor = fd->is_derived_class_constructor; b->func_kind = fd->func_kind; b->need_home_object = (fd->home_object_var_idx >= 0 || fd->need_home_object); b->new_target_allowed = fd->new_target_allowed; b->super_call_allowed = fd->super_call_allowed; b->super_allowed = fd->super_allowed; b->arguments_allowed = fd->arguments_allowed; b->is_direct_or_indirect_eval = (fd->eval_type == JS_EVAL_TYPE_DIRECT || fd->eval_type == JS_EVAL_TYPE_INDIRECT); b->realm = JS_DupContext(ctx); add_gc_object(ctx->rt, &b->header, JS_GC_OBJ_TYPE_FUNCTION_BYTECODE); #if defined(DUMP_BYTECODE) && (DUMP_BYTECODE & 1) if (!fd->strip_debug) { js_dump_function_bytecode(ctx, b); } #endif if (fd->parent) { /* remove from parent list */ list_del(&fd->link); } js_free(ctx, fd); return JS_MKPTR(JS_TAG_FUNCTION_BYTECODE, b); fail: js_free_function_def(ctx, fd); return JS_EXCEPTION; } static void free_function_bytecode(JSRuntime *rt, JSFunctionBytecode *b) { int i; #if 0 { char buf[ATOM_GET_STR_BUF_SIZE]; printf("freeing %s\n", JS_AtomGetStrRT(rt, buf, sizeof(buf), b->func_name)); } #endif if (b->byte_code_buf) free_bytecode_atoms(rt, b->byte_code_buf, b->byte_code_len, TRUE); if (b->vardefs) { for(i = 0; i < b->arg_count + b->var_count; i++) { JS_FreeAtomRT(rt, b->vardefs[i].var_name); } } for(i = 0; i < b->cpool_count; i++) JS_FreeValueRT(rt, b->cpool[i]); for(i = 0; i < b->closure_var_count; i++) { JSClosureVar *cv = &b->closure_var[i]; JS_FreeAtomRT(rt, cv->var_name); } if (b->realm) JS_FreeContext(b->realm); JS_FreeAtomRT(rt, b->func_name); if (b->has_debug) { JS_FreeAtomRT(rt, b->debug.filename); js_free_rt(rt, b->debug.pc2line_buf); js_free_rt(rt, b->debug.source); } remove_gc_object(&b->header); if (rt->gc_phase == JS_GC_PHASE_REMOVE_CYCLES && b->header.ref_count != 0) { list_add_tail(&b->header.link, &rt->gc_zero_ref_count_list); } else { js_free_rt(rt, b); } } static __exception int js_parse_directives(JSParseState *s) { char str[20]; JSParsePos pos; BOOL has_semi; if (s->token.val != TOK_STRING) return 0; js_parse_get_pos(s, &pos); while(s->token.val == TOK_STRING) { /* Copy actual source string representation */ snprintf(str, sizeof str, "%.*s", (int)(s->buf_ptr - s->token.ptr - 2), s->token.ptr + 1); if (next_token(s)) return -1; has_semi = FALSE; switch (s->token.val) { case ';': if (next_token(s)) return -1; has_semi = TRUE; break; case '}': case TOK_EOF: has_semi = TRUE; break; case TOK_NUMBER: case TOK_STRING: case TOK_TEMPLATE: case TOK_IDENT: case TOK_REGEXP: case TOK_DEC: case TOK_INC: case TOK_NULL: case TOK_FALSE: case TOK_TRUE: case TOK_IF: case TOK_RETURN: case TOK_VAR: case TOK_THIS: case TOK_DELETE: case TOK_TYPEOF: case TOK_NEW: case TOK_DO: case TOK_WHILE: case TOK_FOR: case TOK_SWITCH: case TOK_THROW: case TOK_TRY: case TOK_FUNCTION: case TOK_DEBUGGER: case TOK_WITH: case TOK_CLASS: case TOK_CONST: case TOK_ENUM: case TOK_EXPORT: case TOK_IMPORT: case TOK_SUPER: case TOK_INTERFACE: case TOK_LET: case TOK_PACKAGE: case TOK_PRIVATE: case TOK_PROTECTED: case TOK_PUBLIC: case TOK_STATIC: /* automatic insertion of ';' */ if (s->got_lf) has_semi = TRUE; break; default: break; } if (!has_semi) break; if (!strcmp(str, "use strict")) { s->cur_func->has_use_strict = TRUE; s->cur_func->js_mode |= JS_MODE_STRICT; } } return js_parse_seek_token(s, &pos); } /* return TRUE if the keyword is forbidden only in strict mode */ static BOOL is_strict_future_keyword(JSAtom atom) { return (atom >= JS_ATOM_LAST_KEYWORD + 1 && atom <= JS_ATOM_LAST_STRICT_KEYWORD); } static int js_parse_function_check_names(JSParseState *s, JSFunctionDef *fd, JSAtom func_name) { JSAtom name; int i, idx; if (fd->js_mode & JS_MODE_STRICT) { if (!fd->has_simple_parameter_list && fd->has_use_strict) { return js_parse_error(s, "\"use strict\" not allowed in function with default or destructuring parameter"); } if (func_name == JS_ATOM_eval || func_name == JS_ATOM_arguments || is_strict_future_keyword(func_name)) { return js_parse_error(s, "invalid function name in strict code"); } for (idx = 0; idx < fd->arg_count; idx++) { name = fd->args[idx].var_name; if (name == JS_ATOM_eval || name == JS_ATOM_arguments || is_strict_future_keyword(name)) { return js_parse_error(s, "invalid argument name in strict code"); } } } /* check async_generator case */ if ((fd->js_mode & JS_MODE_STRICT) || !fd->has_simple_parameter_list || (fd->func_type == JS_PARSE_FUNC_METHOD && fd->func_kind == JS_FUNC_ASYNC) || fd->func_type == JS_PARSE_FUNC_ARROW || fd->func_type == JS_PARSE_FUNC_METHOD) { for (idx = 0; idx < fd->arg_count; idx++) { name = fd->args[idx].var_name; if (name != JS_ATOM_NULL) { for (i = 0; i < idx; i++) { if (fd->args[i].var_name == name) goto duplicate; } /* Check if argument name duplicates a destructuring parameter */ /* XXX: should have a flag for such variables */ for (i = 0; i < fd->var_count; i++) { if (fd->vars[i].var_name == name && fd->vars[i].scope_level == 0) goto duplicate; } } } } return 0; duplicate: return js_parse_error(s, "duplicate argument names not allowed in this context"); } /* create a function to initialize class fields */ static JSFunctionDef *js_parse_function_class_fields_init(JSParseState *s) { JSFunctionDef *fd; fd = js_new_function_def(s->ctx, s->cur_func, FALSE, FALSE, s->filename, s->buf_start, &s->get_line_col_cache); if (!fd) return NULL; fd->func_name = JS_ATOM_NULL; fd->has_prototype = FALSE; fd->has_home_object = TRUE; fd->has_arguments_binding = FALSE; fd->has_this_binding = TRUE; fd->is_derived_class_constructor = FALSE; fd->new_target_allowed = TRUE; fd->super_call_allowed = FALSE; fd->super_allowed = fd->has_home_object; fd->arguments_allowed = FALSE; fd->func_kind = JS_FUNC_NORMAL; fd->func_type = JS_PARSE_FUNC_METHOD; return fd; } /* func_name must be JS_ATOM_NULL for JS_PARSE_FUNC_STATEMENT and JS_PARSE_FUNC_EXPR, JS_PARSE_FUNC_ARROW and JS_PARSE_FUNC_VAR */ static __exception int js_parse_function_decl2(JSParseState *s, JSParseFunctionEnum func_type, JSFunctionKindEnum func_kind, JSAtom func_name, const uint8_t *ptr, JSParseExportEnum export_flag, JSFunctionDef **pfd) { JSContext *ctx = s->ctx; JSFunctionDef *fd = s->cur_func; BOOL is_expr; int func_idx, lexical_func_idx = -1; BOOL has_opt_arg; BOOL create_func_var = FALSE; is_expr = (func_type != JS_PARSE_FUNC_STATEMENT && func_type != JS_PARSE_FUNC_VAR); if (func_type == JS_PARSE_FUNC_STATEMENT || func_type == JS_PARSE_FUNC_VAR || func_type == JS_PARSE_FUNC_EXPR) { if (func_kind == JS_FUNC_NORMAL && token_is_pseudo_keyword(s, JS_ATOM_async) && peek_token(s, TRUE) != '\n') { if (next_token(s)) return -1; func_kind = JS_FUNC_ASYNC; } if (next_token(s)) return -1; if (s->token.val == '*') { if (next_token(s)) return -1; func_kind |= JS_FUNC_GENERATOR; } if (s->token.val == TOK_IDENT) { if (s->token.u.ident.is_reserved || (s->token.u.ident.atom == JS_ATOM_yield && func_type == JS_PARSE_FUNC_EXPR && (func_kind & JS_FUNC_GENERATOR)) || (s->token.u.ident.atom == JS_ATOM_await && ((func_type == JS_PARSE_FUNC_EXPR && (func_kind & JS_FUNC_ASYNC)) || func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT))) { return js_parse_error_reserved_identifier(s); } } if (s->token.val == TOK_IDENT || (((s->token.val == TOK_YIELD && !(fd->js_mode & JS_MODE_STRICT)) || (s->token.val == TOK_AWAIT && !s->is_module)) && func_type == JS_PARSE_FUNC_EXPR)) { func_name = JS_DupAtom(ctx, s->token.u.ident.atom); if (next_token(s)) { JS_FreeAtom(ctx, func_name); return -1; } } else { if (func_type != JS_PARSE_FUNC_EXPR && export_flag != JS_PARSE_EXPORT_DEFAULT) { return js_parse_error(s, "function name expected"); } } } else if (func_type != JS_PARSE_FUNC_ARROW) { func_name = JS_DupAtom(ctx, func_name); } if (fd->is_eval && fd->eval_type == JS_EVAL_TYPE_MODULE && (func_type == JS_PARSE_FUNC_STATEMENT || func_type == JS_PARSE_FUNC_VAR)) { JSGlobalVar *hf; hf = find_global_var(fd, func_name); /* XXX: should check scope chain */ if (hf && hf->scope_level == fd->scope_level) { js_parse_error(s, "invalid redefinition of global identifier in module code"); JS_FreeAtom(ctx, func_name); return -1; } } if (func_type == JS_PARSE_FUNC_VAR) { if (!(fd->js_mode & JS_MODE_STRICT) && func_kind == JS_FUNC_NORMAL && find_lexical_decl(ctx, fd, func_name, fd->scope_first, FALSE) < 0 && !((func_idx = find_var(ctx, fd, func_name)) >= 0 && (func_idx & ARGUMENT_VAR_OFFSET)) && !(func_name == JS_ATOM_arguments && fd->has_arguments_binding)) { create_func_var = TRUE; } /* Create the lexical name here so that the function closure contains it */ if (fd->is_eval && (fd->eval_type == JS_EVAL_TYPE_GLOBAL || fd->eval_type == JS_EVAL_TYPE_MODULE) && fd->scope_level == fd->body_scope) { /* avoid creating a lexical variable in the global scope. XXX: check annex B */ JSGlobalVar *hf; hf = find_global_var(fd, func_name); /* XXX: should check scope chain */ if (hf && hf->scope_level == fd->scope_level) { js_parse_error(s, "invalid redefinition of global identifier"); JS_FreeAtom(ctx, func_name); return -1; } } else { /* Always create a lexical name, fail if at the same scope as existing name */ /* Lexical variable will be initialized upon entering scope */ lexical_func_idx = define_var(s, fd, func_name, func_kind != JS_FUNC_NORMAL ? JS_VAR_DEF_NEW_FUNCTION_DECL : JS_VAR_DEF_FUNCTION_DECL); if (lexical_func_idx < 0) { JS_FreeAtom(ctx, func_name); return -1; } } } fd = js_new_function_def(ctx, fd, FALSE, is_expr, s->filename, ptr, &s->get_line_col_cache); if (!fd) { JS_FreeAtom(ctx, func_name); return -1; } if (pfd) *pfd = fd; s->cur_func = fd; fd->func_name = func_name; /* XXX: test !fd->is_generator is always false */ fd->has_prototype = (func_type == JS_PARSE_FUNC_STATEMENT || func_type == JS_PARSE_FUNC_VAR || func_type == JS_PARSE_FUNC_EXPR) && func_kind == JS_FUNC_NORMAL; fd->has_home_object = (func_type == JS_PARSE_FUNC_METHOD || func_type == JS_PARSE_FUNC_GETTER || func_type == JS_PARSE_FUNC_SETTER || func_type == JS_PARSE_FUNC_CLASS_CONSTRUCTOR || func_type == JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR); fd->has_arguments_binding = (func_type != JS_PARSE_FUNC_ARROW && func_type != JS_PARSE_FUNC_CLASS_STATIC_INIT); fd->has_this_binding = fd->has_arguments_binding; fd->is_derived_class_constructor = (func_type == JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR); if (func_type == JS_PARSE_FUNC_ARROW) { fd->new_target_allowed = fd->parent->new_target_allowed; fd->super_call_allowed = fd->parent->super_call_allowed; fd->super_allowed = fd->parent->super_allowed; fd->arguments_allowed = fd->parent->arguments_allowed; } else if (func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT) { fd->new_target_allowed = TRUE; // although new.target === undefined fd->super_call_allowed = FALSE; fd->super_allowed = TRUE; fd->arguments_allowed = FALSE; } else { fd->new_target_allowed = TRUE; fd->super_call_allowed = fd->is_derived_class_constructor; fd->super_allowed = fd->has_home_object; fd->arguments_allowed = TRUE; } /* fd->in_function_body == FALSE prevents yield/await during the parsing of the arguments in generator/async functions. They are parsed as regular identifiers for other function kinds. */ fd->func_kind = func_kind; fd->func_type = func_type; if (func_type == JS_PARSE_FUNC_CLASS_CONSTRUCTOR || func_type == JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR) { /* error if not invoked as a constructor */ emit_op(s, OP_check_ctor); } if (func_type == JS_PARSE_FUNC_CLASS_CONSTRUCTOR) { emit_class_field_init(s); } /* parse arguments */ fd->has_simple_parameter_list = TRUE; fd->has_parameter_expressions = FALSE; has_opt_arg = FALSE; if (func_type == JS_PARSE_FUNC_ARROW && s->token.val == TOK_IDENT) { JSAtom name; if (s->token.u.ident.is_reserved) { js_parse_error_reserved_identifier(s); goto fail; } name = s->token.u.ident.atom; if (add_arg(ctx, fd, name) < 0) goto fail; fd->defined_arg_count = 1; } else if (func_type != JS_PARSE_FUNC_CLASS_STATIC_INIT) { if (s->token.val == '(') { int skip_bits; /* if there is an '=' inside the parameter list, we consider there is a parameter expression inside */ js_parse_skip_parens_token(s, &skip_bits, FALSE); if (skip_bits & SKIP_HAS_ASSIGNMENT) fd->has_parameter_expressions = TRUE; if (next_token(s)) goto fail; } else { if (js_parse_expect(s, '(')) goto fail; } if (fd->has_parameter_expressions) { fd->scope_level = -1; /* force no parent scope */ if (push_scope(s) < 0) return -1; } while (s->token.val != ')') { JSAtom name; BOOL rest = FALSE; int idx, has_initializer; if (s->token.val == TOK_ELLIPSIS) { if (func_type == JS_PARSE_FUNC_SETTER) goto fail_accessor; fd->has_simple_parameter_list = FALSE; rest = TRUE; if (next_token(s)) goto fail; } if (s->token.val == '[' || s->token.val == '{') { fd->has_simple_parameter_list = FALSE; if (rest) { emit_op(s, OP_rest); emit_u16(s, fd->arg_count); } else { /* unnamed arg for destructuring */ idx = add_arg(ctx, fd, JS_ATOM_NULL); emit_op(s, OP_get_arg); emit_u16(s, idx); } has_initializer = js_parse_destructuring_element(s, fd->has_parameter_expressions ? TOK_LET : TOK_VAR, 1, TRUE, -1, TRUE, FALSE); if (has_initializer < 0) goto fail; if (has_initializer) has_opt_arg = TRUE; if (!has_opt_arg) fd->defined_arg_count++; } else if (s->token.val == TOK_IDENT) { if (s->token.u.ident.is_reserved) { js_parse_error_reserved_identifier(s); goto fail; } name = s->token.u.ident.atom; if (name == JS_ATOM_yield && fd->func_kind == JS_FUNC_GENERATOR) { js_parse_error_reserved_identifier(s); goto fail; } if (fd->has_parameter_expressions) { if (js_parse_check_duplicate_parameter(s, name)) goto fail; if (define_var(s, fd, name, JS_VAR_DEF_LET) < 0) goto fail; } /* XXX: could avoid allocating an argument if rest is true */ idx = add_arg(ctx, fd, name); if (idx < 0) goto fail; if (next_token(s)) goto fail; if (rest) { emit_op(s, OP_rest); emit_u16(s, idx); if (fd->has_parameter_expressions) { emit_op(s, OP_dup); emit_op(s, OP_scope_put_var_init); emit_atom(s, name); emit_u16(s, fd->scope_level); } emit_op(s, OP_put_arg); emit_u16(s, idx); fd->has_simple_parameter_list = FALSE; has_opt_arg = TRUE; } else if (s->token.val == '=') { int label; fd->has_simple_parameter_list = FALSE; has_opt_arg = TRUE; if (next_token(s)) goto fail; label = new_label(s); emit_op(s, OP_get_arg); emit_u16(s, idx); emit_op(s, OP_dup); emit_op(s, OP_undefined); emit_op(s, OP_strict_eq); emit_goto(s, OP_if_false, label); emit_op(s, OP_drop); if (js_parse_assign_expr(s)) goto fail; set_object_name(s, name); emit_op(s, OP_dup); emit_op(s, OP_put_arg); emit_u16(s, idx); emit_label(s, label); emit_op(s, OP_scope_put_var_init); emit_atom(s, name); emit_u16(s, fd->scope_level); } else { if (!has_opt_arg) { fd->defined_arg_count++; } if (fd->has_parameter_expressions) { /* copy the argument to the argument scope */ emit_op(s, OP_get_arg); emit_u16(s, idx); emit_op(s, OP_scope_put_var_init); emit_atom(s, name); emit_u16(s, fd->scope_level); } } } else { js_parse_error(s, "missing formal parameter"); goto fail; } if (rest && s->token.val != ')') { js_parse_expect(s, ')'); goto fail; } if (s->token.val == ')') break; if (js_parse_expect(s, ',')) goto fail; } if ((func_type == JS_PARSE_FUNC_GETTER && fd->arg_count != 0) || (func_type == JS_PARSE_FUNC_SETTER && fd->arg_count != 1)) { fail_accessor: js_parse_error(s, "invalid number of arguments for getter or setter"); goto fail; } } if (fd->has_parameter_expressions) { int idx; /* Copy the variables in the argument scope to the variable scope (see FunctionDeclarationInstantiation() in spec). The normal arguments are already present, so no need to copy them. */ idx = fd->scopes[fd->scope_level].first; while (idx >= 0) { JSVarDef *vd = &fd->vars[idx]; if (vd->scope_level != fd->scope_level) break; if (find_var(ctx, fd, vd->var_name) < 0) { if (add_var(ctx, fd, vd->var_name) < 0) goto fail; vd = &fd->vars[idx]; /* fd->vars may have been reallocated */ emit_op(s, OP_scope_get_var); emit_atom(s, vd->var_name); emit_u16(s, fd->scope_level); emit_op(s, OP_scope_put_var); emit_atom(s, vd->var_name); emit_u16(s, 0); } idx = vd->scope_next; } /* the argument scope has no parent, hence we don't use pop_scope(s) */ emit_op(s, OP_leave_scope); emit_u16(s, fd->scope_level); /* set the variable scope as the current scope */ fd->scope_level = 0; fd->scope_first = fd->scopes[fd->scope_level].first; } if (next_token(s)) goto fail; /* generator function: yield after the parameters are evaluated */ if (func_kind == JS_FUNC_GENERATOR || func_kind == JS_FUNC_ASYNC_GENERATOR) emit_op(s, OP_initial_yield); /* in generators, yield expression is forbidden during the parsing of the arguments */ fd->in_function_body = TRUE; push_scope(s); /* enter body scope */ fd->body_scope = fd->scope_level; if (s->token.val == TOK_ARROW && func_type == JS_PARSE_FUNC_ARROW) { if (next_token(s)) goto fail; if (s->token.val != '{') { if (js_parse_function_check_names(s, fd, func_name)) goto fail; if (js_parse_assign_expr(s)) goto fail; if (func_kind != JS_FUNC_NORMAL) emit_op(s, OP_return_async); else emit_op(s, OP_return); if (!fd->strip_source) { /* save the function source code */ /* the end of the function source code is after the last token of the function source stored into s->last_ptr */ fd->source_len = s->last_ptr - ptr; fd->source = js_strndup(ctx, (const char *)ptr, fd->source_len); if (!fd->source) goto fail; } goto done; } } if (func_type != JS_PARSE_FUNC_CLASS_STATIC_INIT) { if (js_parse_expect(s, '{')) goto fail; } if (js_parse_directives(s)) goto fail; /* in strict_mode, check function and argument names */ if (js_parse_function_check_names(s, fd, func_name)) goto fail; while (s->token.val != '}') { if (js_parse_source_element(s)) goto fail; } if (!fd->strip_source) { /* save the function source code */ fd->source_len = s->buf_ptr - ptr; fd->source = js_strndup(ctx, (const char *)ptr, fd->source_len); if (!fd->source) goto fail; } if (next_token(s)) { /* consume the '}' */ goto fail; } /* in case there is no return, add one */ if (js_is_live_code(s)) { emit_return(s, FALSE); } done: s->cur_func = fd->parent; /* Reparse identifiers after the function is terminated so that the token is parsed in the englobing function. It could be done by just using next_token() here for normal functions, but it is necessary for arrow functions with an expression body. */ reparse_ident_token(s); /* create the function object */ { int idx; JSAtom func_name = fd->func_name; /* the real object will be set at the end of the compilation */ idx = cpool_add(s, JS_NULL); fd->parent_cpool_idx = idx; if (is_expr) { /* for constructors, no code needs to be generated here */ if (func_type != JS_PARSE_FUNC_CLASS_CONSTRUCTOR && func_type != JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR) { /* OP_fclosure creates the function object from the bytecode and adds the scope information */ emit_op(s, OP_fclosure); emit_u32(s, idx); if (func_name == JS_ATOM_NULL) { emit_op(s, OP_set_name); emit_u32(s, JS_ATOM_NULL); } } } else if (func_type == JS_PARSE_FUNC_VAR) { emit_op(s, OP_fclosure); emit_u32(s, idx); if (create_func_var) { if (s->cur_func->is_global_var) { JSGlobalVar *hf; /* the global variable must be defined at the start of the function */ hf = add_global_var(ctx, s->cur_func, func_name); if (!hf) goto fail; /* it is considered as defined at the top level (needed for annex B.3.3.4 and B.3.3.5 checks) */ hf->scope_level = 0; hf->force_init = ((s->cur_func->js_mode & JS_MODE_STRICT) != 0); /* store directly into global var, bypass lexical scope */ emit_op(s, OP_dup); emit_op(s, OP_scope_put_var); emit_atom(s, func_name); emit_u16(s, 0); } else { /* do not call define_var to bypass lexical scope check */ func_idx = find_var(ctx, s->cur_func, func_name); if (func_idx < 0) { func_idx = add_var(ctx, s->cur_func, func_name); if (func_idx < 0) goto fail; } /* store directly into local var, bypass lexical catch scope */ emit_op(s, OP_dup); emit_op(s, OP_scope_put_var); emit_atom(s, func_name); emit_u16(s, 0); } } if (lexical_func_idx >= 0) { /* lexical variable will be initialized upon entering scope */ s->cur_func->vars[lexical_func_idx].func_pool_idx = idx; emit_op(s, OP_drop); } else { /* store function object into its lexical name */ /* XXX: could use OP_put_loc directly */ emit_op(s, OP_scope_put_var_init); emit_atom(s, func_name); emit_u16(s, s->cur_func->scope_level); } } else { if (!s->cur_func->is_global_var) { int var_idx = define_var(s, s->cur_func, func_name, JS_VAR_DEF_VAR); if (var_idx < 0) goto fail; /* the variable will be assigned at the top of the function */ if (var_idx & ARGUMENT_VAR_OFFSET) { s->cur_func->args[var_idx - ARGUMENT_VAR_OFFSET].func_pool_idx = idx; } else { s->cur_func->vars[var_idx].func_pool_idx = idx; } } else { JSAtom func_var_name; JSGlobalVar *hf; if (func_name == JS_ATOM_NULL) func_var_name = JS_ATOM__default_; /* export default */ else func_var_name = func_name; /* the variable will be assigned at the top of the function */ hf = add_global_var(ctx, s->cur_func, func_var_name); if (!hf) goto fail; hf->cpool_idx = idx; if (export_flag != JS_PARSE_EXPORT_NONE) { if (!add_export_entry(s, s->cur_func->module, func_var_name, export_flag == JS_PARSE_EXPORT_NAMED ? func_var_name : JS_ATOM_default, JS_EXPORT_TYPE_LOCAL)) goto fail; } } } } return 0; fail: s->cur_func = fd->parent; js_free_function_def(ctx, fd); if (pfd) *pfd = NULL; return -1; } static __exception int js_parse_function_decl(JSParseState *s, JSParseFunctionEnum func_type, JSFunctionKindEnum func_kind, JSAtom func_name, const uint8_t *ptr) { return js_parse_function_decl2(s, func_type, func_kind, func_name, ptr, JS_PARSE_EXPORT_NONE, NULL); } static __exception int js_parse_program(JSParseState *s) { JSFunctionDef *fd = s->cur_func; int idx; if (next_token(s)) return -1; if (js_parse_directives(s)) return -1; fd->is_global_var = (fd->eval_type == JS_EVAL_TYPE_GLOBAL) || (fd->eval_type == JS_EVAL_TYPE_MODULE) || !(fd->js_mode & JS_MODE_STRICT); if (!s->is_module) { /* hidden variable for the return value */ fd->eval_ret_idx = idx = add_var(s->ctx, fd, JS_ATOM__ret_); if (idx < 0) return -1; } while (s->token.val != TOK_EOF) { if (js_parse_source_element(s)) return -1; } if (!s->is_module) { /* return the value of the hidden variable eval_ret_idx */ if (fd->func_kind == JS_FUNC_ASYNC) { /* wrap the return value in an object so that promises can be safely returned */ emit_op(s, OP_object); emit_op(s, OP_dup); emit_op(s, OP_get_loc); emit_u16(s, fd->eval_ret_idx); emit_op(s, OP_put_field); emit_atom(s, JS_ATOM_value); } else { emit_op(s, OP_get_loc); emit_u16(s, fd->eval_ret_idx); } emit_return(s, TRUE); } else { emit_return(s, FALSE); } return 0; } static void js_parse_init(JSContext *ctx, JSParseState *s, const char *input, size_t input_len, const char *filename) { memset(s, 0, sizeof(*s)); s->ctx = ctx; s->filename = filename; s->buf_start = s->buf_ptr = (const uint8_t *)input; s->buf_end = s->buf_ptr + input_len; s->token.val = ' '; s->token.ptr = s->buf_ptr; s->get_line_col_cache.ptr = s->buf_start; s->get_line_col_cache.buf_start = s->buf_start; s->get_line_col_cache.line_num = 0; s->get_line_col_cache.col_num = 0; } static JSValue JS_EvalFunctionInternal(JSContext *ctx, JSValue fun_obj, JSValueConst this_obj, JSVarRef **var_refs, JSStackFrame *sf) { JSValue ret_val; uint32_t tag; tag = JS_VALUE_GET_TAG(fun_obj); if (tag == JS_TAG_FUNCTION_BYTECODE) { fun_obj = js_closure(ctx, fun_obj, var_refs, sf, TRUE); if (JS_IsException(fun_obj)) return JS_EXCEPTION; ret_val = JS_CallFree(ctx, fun_obj, this_obj, 0, NULL); } else if (tag == JS_TAG_MODULE) { JSModuleDef *m; m = JS_VALUE_GET_PTR(fun_obj); /* the module refcount should be >= 2 */ JS_FreeValue(ctx, fun_obj); if (js_create_module_function(ctx, m) < 0) goto fail; if (js_link_module(ctx, m) < 0) goto fail; ret_val = js_evaluate_module(ctx, m); if (JS_IsException(ret_val)) { fail: return JS_EXCEPTION; } } else { JS_FreeValue(ctx, fun_obj); ret_val = JS_ThrowTypeError(ctx, "bytecode function expected"); } return ret_val; } JSValue JS_EvalFunction(JSContext *ctx, JSValue fun_obj) { return JS_EvalFunctionInternal(ctx, fun_obj, ctx->global_obj, NULL, NULL); } /* 'input' must be zero terminated i.e. input[input_len] = '\0'. */ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj, const char *input, size_t input_len, const char *filename, int flags, int scope_idx) { JSParseState s1, *s = &s1; int err, js_mode, eval_type; JSValue fun_obj, ret_val; JSStackFrame *sf; JSVarRef **var_refs; JSFunctionBytecode *b; JSFunctionDef *fd; JSModuleDef *m; js_parse_init(ctx, s, input, input_len, filename); skip_shebang(&s->buf_ptr, s->buf_end); eval_type = flags & JS_EVAL_TYPE_MASK; m = NULL; if (eval_type == JS_EVAL_TYPE_DIRECT) { JSObject *p; sf = ctx->rt->current_stack_frame; assert(sf != NULL); assert(JS_VALUE_GET_TAG(sf->cur_func) == JS_TAG_OBJECT); p = JS_VALUE_GET_OBJ(sf->cur_func); assert(js_class_has_bytecode(p->class_id)); b = p->u.func.function_bytecode; var_refs = p->u.func.var_refs; js_mode = b->js_mode; } else { sf = NULL; b = NULL; var_refs = NULL; js_mode = 0; if (flags & JS_EVAL_FLAG_STRICT) js_mode |= JS_MODE_STRICT; if (eval_type == JS_EVAL_TYPE_MODULE) { JSAtom module_name = JS_NewAtom(ctx, filename); if (module_name == JS_ATOM_NULL) return JS_EXCEPTION; m = js_new_module_def(ctx, module_name); if (!m) return JS_EXCEPTION; js_mode |= JS_MODE_STRICT; } } fd = js_new_function_def(ctx, NULL, TRUE, FALSE, filename, s->buf_start, &s->get_line_col_cache); if (!fd) goto fail1; s->cur_func = fd; fd->eval_type = eval_type; fd->has_this_binding = (eval_type != JS_EVAL_TYPE_DIRECT); if (eval_type == JS_EVAL_TYPE_DIRECT) { fd->new_target_allowed = b->new_target_allowed; fd->super_call_allowed = b->super_call_allowed; fd->super_allowed = b->super_allowed; fd->arguments_allowed = b->arguments_allowed; } else { fd->new_target_allowed = FALSE; fd->super_call_allowed = FALSE; fd->super_allowed = FALSE; fd->arguments_allowed = TRUE; } fd->js_mode = js_mode; fd->func_name = JS_DupAtom(ctx, JS_ATOM__eval_); if (b) { if (add_closure_variables(ctx, fd, b, scope_idx)) goto fail; } fd->module = m; if (m != NULL || (flags & JS_EVAL_FLAG_ASYNC)) { fd->in_function_body = TRUE; fd->func_kind = JS_FUNC_ASYNC; } s->is_module = (m != NULL); s->allow_html_comments = !s->is_module; push_scope(s); /* body scope */ fd->body_scope = fd->scope_level; err = js_parse_program(s); if (err) { fail: free_token(s, &s->token); js_free_function_def(ctx, fd); goto fail1; } if (m != NULL) m->has_tla = fd->has_await; /* create the function object and all the enclosed functions */ fun_obj = js_create_function(ctx, fd); if (JS_IsException(fun_obj)) goto fail1; /* Could add a flag to avoid resolution if necessary */ if (m) { m->func_obj = fun_obj; if (js_resolve_module(ctx, m) < 0) goto fail1; fun_obj = JS_NewModuleValue(ctx, m); } if (flags & JS_EVAL_FLAG_COMPILE_ONLY) { ret_val = fun_obj; } else { ret_val = JS_EvalFunctionInternal(ctx, fun_obj, this_obj, var_refs, sf); } return ret_val; fail1: /* XXX: should free all the unresolved dependencies */ if (m) JS_FreeValue(ctx, JS_MKPTR(JS_TAG_MODULE, m)); return JS_EXCEPTION; } /* the indirection is needed to make 'eval' optional */ static JSValue JS_EvalInternal(JSContext *ctx, JSValueConst this_obj, const char *input, size_t input_len, const char *filename, int flags, int scope_idx) { BOOL backtrace_barrier = ((flags & JS_EVAL_FLAG_BACKTRACE_BARRIER) != 0); int saved_js_mode = 0; JSValue ret; if (unlikely(!ctx->eval_internal)) { return JS_ThrowTypeError(ctx, "eval is not supported"); } if (backtrace_barrier && ctx->rt->current_stack_frame) { saved_js_mode = ctx->rt->current_stack_frame->js_mode; ctx->rt->current_stack_frame->js_mode |= JS_MODE_BACKTRACE_BARRIER; } ret = ctx->eval_internal(ctx, this_obj, input, input_len, filename, flags, scope_idx); if (backtrace_barrier && ctx->rt->current_stack_frame) ctx->rt->current_stack_frame->js_mode = saved_js_mode; return ret; } static JSValue JS_EvalObject(JSContext *ctx, JSValueConst this_obj, JSValueConst val, int flags, int scope_idx) { JSValue ret; const char *str; size_t len; if (!JS_IsString(val)) return JS_DupValue(ctx, val); str = JS_ToCStringLen(ctx, &len, val); if (!str) return JS_EXCEPTION; ret = JS_EvalInternal(ctx, this_obj, str, len, "<input>", flags, scope_idx); JS_FreeCString(ctx, str); return ret; } JSValue JS_EvalThis(JSContext *ctx, JSValueConst this_obj, const char *input, size_t input_len, const char *filename, int eval_flags) { int eval_type = eval_flags & JS_EVAL_TYPE_MASK; JSValue ret; assert(eval_type == JS_EVAL_TYPE_GLOBAL || eval_type == JS_EVAL_TYPE_MODULE); ret = JS_EvalInternal(ctx, this_obj, input, input_len, filename, eval_flags, -1); return ret; } JSValue JS_Eval(JSContext *ctx, const char *input, size_t input_len, const char *filename, int eval_flags) { return JS_EvalThis(ctx, ctx->global_obj, input, input_len, filename, eval_flags); } int JS_ResolveModule(JSContext *ctx, JSValueConst obj) { if (JS_VALUE_GET_TAG(obj) == JS_TAG_MODULE) { JSModuleDef *m = JS_VALUE_GET_PTR(obj); if (js_resolve_module(ctx, m) < 0) { js_free_modules(ctx, JS_FREE_MODULE_NOT_RESOLVED); return -1; } } return 0; } /*******************************************************************/ /* object list */ typedef struct { JSObject *obj; uint32_t hash_next; /* -1 if no next entry */ } JSObjectListEntry; /* XXX: reuse it to optimize weak references */ typedef struct { JSObjectListEntry *object_tab; int object_count; int object_size; uint32_t *hash_table; uint32_t hash_size; } JSObjectList; static void js_object_list_init(JSObjectList *s) { memset(s, 0, sizeof(*s)); } static uint32_t js_object_list_get_hash(JSObject *p, uint32_t hash_size) { return ((uintptr_t)p * 3163) & (hash_size - 1); } static int js_object_list_resize_hash(JSContext *ctx, JSObjectList *s, uint32_t new_hash_size) { JSObjectListEntry *e; uint32_t i, h, *new_hash_table; new_hash_table = js_malloc(ctx, sizeof(new_hash_table[0]) * new_hash_size); if (!new_hash_table) return -1; js_free(ctx, s->hash_table); s->hash_table = new_hash_table; s->hash_size = new_hash_size; for(i = 0; i < s->hash_size; i++) { s->hash_table[i] = -1; } for(i = 0; i < s->object_count; i++) { e = &s->object_tab[i]; h = js_object_list_get_hash(e->obj, s->hash_size); e->hash_next = s->hash_table[h]; s->hash_table[h] = i; } return 0; } /* the reference count of 'obj' is not modified. Return 0 if OK, -1 if memory error */ static int js_object_list_add(JSContext *ctx, JSObjectList *s, JSObject *obj) { JSObjectListEntry *e; uint32_t h, new_hash_size; if (js_resize_array(ctx, (void *)&s->object_tab, sizeof(s->object_tab[0]), &s->object_size, s->object_count + 1)) return -1; if (unlikely((s->object_count + 1) >= s->hash_size)) { new_hash_size = max_uint32(s->hash_size, 4); while (new_hash_size <= s->object_count) new_hash_size *= 2; if (js_object_list_resize_hash(ctx, s, new_hash_size)) return -1; } e = &s->object_tab[s->object_count++]; h = js_object_list_get_hash(obj, s->hash_size); e->obj = obj; e->hash_next = s->hash_table[h]; s->hash_table[h] = s->object_count - 1; return 0; } /* return -1 if not present or the object index */ static int js_object_list_find(JSContext *ctx, JSObjectList *s, JSObject *obj) { JSObjectListEntry *e; uint32_t h, p; /* must test empty size because there is no hash table */ if (s->object_count == 0) return -1; h = js_object_list_get_hash(obj, s->hash_size); p = s->hash_table[h]; while (p != -1) { e = &s->object_tab[p]; if (e->obj == obj) return p; p = e->hash_next; } return -1; } static void js_object_list_end(JSContext *ctx, JSObjectList *s) { js_free(ctx, s->object_tab); js_free(ctx, s->hash_table); } /*******************************************************************/ /* binary object writer & reader */ typedef enum BCTagEnum { BC_TAG_NULL = 1, BC_TAG_UNDEFINED, BC_TAG_BOOL_FALSE, BC_TAG_BOOL_TRUE, BC_TAG_INT32, BC_TAG_FLOAT64, BC_TAG_STRING, BC_TAG_OBJECT, BC_TAG_ARRAY, BC_TAG_BIG_INT, BC_TAG_TEMPLATE_OBJECT, BC_TAG_FUNCTION_BYTECODE, BC_TAG_MODULE, BC_TAG_TYPED_ARRAY, BC_TAG_ARRAY_BUFFER, BC_TAG_SHARED_ARRAY_BUFFER, BC_TAG_DATE, BC_TAG_OBJECT_VALUE, BC_TAG_OBJECT_REFERENCE, } BCTagEnum; #define BC_VERSION 5 typedef struct BCWriterState { JSContext *ctx; DynBuf dbuf; BOOL allow_bytecode : 8; BOOL allow_sab : 8; BOOL allow_reference : 8; uint32_t first_atom; uint32_t *atom_to_idx; int atom_to_idx_size; JSAtom *idx_to_atom; int idx_to_atom_count; int idx_to_atom_size; uint8_t **sab_tab; int sab_tab_len; int sab_tab_size; /* list of referenced objects (used if allow_reference = TRUE) */ JSObjectList object_list; } BCWriterState; #ifdef DUMP_READ_OBJECT static const char * const bc_tag_str[] = { "invalid", "null", "undefined", "false", "true", "int32", "float64", "string", "object", "array", "bigint", "template", "function", "module", "TypedArray", "ArrayBuffer", "SharedArrayBuffer", "Date", "ObjectValue", "ObjectReference", }; #endif static inline BOOL is_be(void) { union { uint16_t a; uint8_t b; } u = {0x100}; return u.b; } static void bc_put_u8(BCWriterState *s, uint8_t v) { dbuf_putc(&s->dbuf, v); } static void bc_put_u16(BCWriterState *s, uint16_t v) { if (is_be()) v = bswap16(v); dbuf_put_u16(&s->dbuf, v); } static __maybe_unused void bc_put_u32(BCWriterState *s, uint32_t v) { if (is_be()) v = bswap32(v); dbuf_put_u32(&s->dbuf, v); } static void bc_put_u64(BCWriterState *s, uint64_t v) { if (is_be()) v = bswap64(v); dbuf_put(&s->dbuf, (uint8_t *)&v, sizeof(v)); } static void bc_put_leb128(BCWriterState *s, uint32_t v) { dbuf_put_leb128(&s->dbuf, v); } static void bc_put_sleb128(BCWriterState *s, int32_t v) { dbuf_put_sleb128(&s->dbuf, v); } static void bc_set_flags(uint32_t *pflags, int *pidx, uint32_t val, int n) { *pflags = *pflags | (val << *pidx); *pidx += n; } static int bc_atom_to_idx(BCWriterState *s, uint32_t *pres, JSAtom atom) { uint32_t v; if (atom < s->first_atom || __JS_AtomIsTaggedInt(atom)) { *pres = atom; return 0; } atom -= s->first_atom; if (atom < s->atom_to_idx_size && s->atom_to_idx[atom] != 0) { *pres = s->atom_to_idx[atom]; return 0; } if (atom >= s->atom_to_idx_size) { int old_size, i; old_size = s->atom_to_idx_size; if (js_resize_array(s->ctx, (void **)&s->atom_to_idx, sizeof(s->atom_to_idx[0]), &s->atom_to_idx_size, atom + 1)) return -1; /* XXX: could add a specific js_resize_array() function to do it */ for(i = old_size; i < s->atom_to_idx_size; i++) s->atom_to_idx[i] = 0; } if (js_resize_array(s->ctx, (void **)&s->idx_to_atom, sizeof(s->idx_to_atom[0]), &s->idx_to_atom_size, s->idx_to_atom_count + 1)) goto fail; v = s->idx_to_atom_count++; s->idx_to_atom[v] = atom + s->first_atom; v += s->first_atom; s->atom_to_idx[atom] = v; *pres = v; return 0; fail: *pres = 0; return -1; } static int bc_put_atom(BCWriterState *s, JSAtom atom) { uint32_t v; if (__JS_AtomIsTaggedInt(atom)) { v = (__JS_AtomToUInt32(atom) << 1) | 1; } else { if (bc_atom_to_idx(s, &v, atom)) return -1; v <<= 1; } bc_put_leb128(s, v); return 0; } static void bc_byte_swap(uint8_t *bc_buf, int bc_len) { int pos, len, op, fmt; pos = 0; while (pos < bc_len) { op = bc_buf[pos]; len = short_opcode_info(op).size; fmt = short_opcode_info(op).fmt; switch(fmt) { case OP_FMT_u16: case OP_FMT_i16: case OP_FMT_label16: case OP_FMT_npop: case OP_FMT_loc: case OP_FMT_arg: case OP_FMT_var_ref: put_u16(bc_buf + pos + 1, bswap16(get_u16(bc_buf + pos + 1))); break; case OP_FMT_i32: case OP_FMT_u32: case OP_FMT_const: case OP_FMT_label: case OP_FMT_atom: case OP_FMT_atom_u8: put_u32(bc_buf + pos + 1, bswap32(get_u32(bc_buf + pos + 1))); break; case OP_FMT_atom_u16: case OP_FMT_label_u16: put_u32(bc_buf + pos + 1, bswap32(get_u32(bc_buf + pos + 1))); put_u16(bc_buf + pos + 1 + 4, bswap16(get_u16(bc_buf + pos + 1 + 4))); break; case OP_FMT_atom_label_u8: case OP_FMT_atom_label_u16: put_u32(bc_buf + pos + 1, bswap32(get_u32(bc_buf + pos + 1))); put_u32(bc_buf + pos + 1 + 4, bswap32(get_u32(bc_buf + pos + 1 + 4))); if (fmt == OP_FMT_atom_label_u16) { put_u16(bc_buf + pos + 1 + 4 + 4, bswap16(get_u16(bc_buf + pos + 1 + 4 + 4))); } break; case OP_FMT_npop_u16: put_u16(bc_buf + pos + 1, bswap16(get_u16(bc_buf + pos + 1))); put_u16(bc_buf + pos + 1 + 2, bswap16(get_u16(bc_buf + pos + 1 + 2))); break; default: break; } pos += len; } } static int JS_WriteFunctionBytecode(BCWriterState *s, const uint8_t *bc_buf1, int bc_len) { int pos, len, op; JSAtom atom; uint8_t *bc_buf; uint32_t val; bc_buf = js_malloc(s->ctx, bc_len); if (!bc_buf) return -1; memcpy(bc_buf, bc_buf1, bc_len); pos = 0; while (pos < bc_len) { op = bc_buf[pos]; len = short_opcode_info(op).size; switch(short_opcode_info(op).fmt) { case OP_FMT_atom: case OP_FMT_atom_u8: case OP_FMT_atom_u16: case OP_FMT_atom_label_u8: case OP_FMT_atom_label_u16: atom = get_u32(bc_buf + pos + 1); if (bc_atom_to_idx(s, &val, atom)) goto fail; put_u32(bc_buf + pos + 1, val); break; default: break; } pos += len; } if (is_be()) bc_byte_swap(bc_buf, bc_len); dbuf_put(&s->dbuf, bc_buf, bc_len); js_free(s->ctx, bc_buf); return 0; fail: js_free(s->ctx, bc_buf); return -1; } static void JS_WriteString(BCWriterState *s, JSString *p) { int i; bc_put_leb128(s, ((uint32_t)p->len << 1) | p->is_wide_char); if (p->is_wide_char) { for(i = 0; i < p->len; i++) bc_put_u16(s, p->u.str16[i]); } else { dbuf_put(&s->dbuf, p->u.str8, p->len); } } static int JS_WriteBigInt(BCWriterState *s, JSValueConst obj) { JSBigIntBuf buf; JSBigInt *p; uint32_t len, i; js_limb_t v, b; int shift; bc_put_u8(s, BC_TAG_BIG_INT); if (JS_VALUE_GET_TAG(obj) == JS_TAG_SHORT_BIG_INT) p = js_bigint_set_short(&buf, obj); else p = JS_VALUE_GET_PTR(obj); if (p->len == 1 && p->tab[0] == 0) { /* zero case */ len = 0; } else { /* compute the length of the two's complement representation in bytes */ len = p->len * (JS_LIMB_BITS / 8); v = p->tab[p->len - 1]; shift = JS_LIMB_BITS - 8; while (shift > 0) { b = (v >> shift) & 0xff; if (b != 0x00 && b != 0xff) break; if ((b & 1) != ((v >> (shift - 1)) & 1)) break; shift -= 8; len--; } } bc_put_leb128(s, len); if (len > 0) { for(i = 0; i < (len / (JS_LIMB_BITS / 8)); i++) { #if JS_LIMB_BITS == 32 bc_put_u32(s, p->tab[i]); #else bc_put_u64(s, p->tab[i]); #endif } for(i = 0; i < len % (JS_LIMB_BITS / 8); i++) { bc_put_u8(s, (p->tab[p->len - 1] >> (i * 8)) & 0xff); } } return 0; } static int JS_WriteObjectRec(BCWriterState *s, JSValueConst obj); static int JS_WriteFunctionTag(BCWriterState *s, JSValueConst obj) { JSFunctionBytecode *b = JS_VALUE_GET_PTR(obj); uint32_t flags; int idx, i; bc_put_u8(s, BC_TAG_FUNCTION_BYTECODE); flags = idx = 0; bc_set_flags(&flags, &idx, b->has_prototype, 1); bc_set_flags(&flags, &idx, b->has_simple_parameter_list, 1); bc_set_flags(&flags, &idx, b->is_derived_class_constructor, 1); bc_set_flags(&flags, &idx, b->need_home_object, 1); bc_set_flags(&flags, &idx, b->func_kind, 2); bc_set_flags(&flags, &idx, b->new_target_allowed, 1); bc_set_flags(&flags, &idx, b->super_call_allowed, 1); bc_set_flags(&flags, &idx, b->super_allowed, 1); bc_set_flags(&flags, &idx, b->arguments_allowed, 1); bc_set_flags(&flags, &idx, b->has_debug, 1); bc_set_flags(&flags, &idx, b->is_direct_or_indirect_eval, 1); assert(idx <= 16); bc_put_u16(s, flags); bc_put_u8(s, b->js_mode); bc_put_atom(s, b->func_name); bc_put_leb128(s, b->arg_count); bc_put_leb128(s, b->var_count); bc_put_leb128(s, b->defined_arg_count); bc_put_leb128(s, b->stack_size); bc_put_leb128(s, b->var_ref_count); bc_put_leb128(s, b->closure_var_count); bc_put_leb128(s, b->cpool_count); bc_put_leb128(s, b->byte_code_len); if (b->vardefs) { bc_put_leb128(s, b->arg_count + b->var_count); for(i = 0; i < b->arg_count + b->var_count; i++) { JSBytecodeVarDef *vd = &b->vardefs[i]; bc_put_atom(s, vd->var_name); bc_put_leb128(s, vd->scope_next + 1); bc_put_leb128(s, vd->var_ref_idx); flags = idx = 0; bc_set_flags(&flags, &idx, vd->var_kind, 4); bc_set_flags(&flags, &idx, vd->is_const, 1); bc_set_flags(&flags, &idx, vd->is_lexical, 1); bc_set_flags(&flags, &idx, vd->is_captured, 1); bc_set_flags(&flags, &idx, vd->has_scope, 1); assert(idx <= 8); bc_put_u8(s, flags); } } else { bc_put_leb128(s, 0); } for(i = 0; i < b->closure_var_count; i++) { JSClosureVar *cv = &b->closure_var[i]; bc_put_atom(s, cv->var_name); bc_put_leb128(s, cv->var_idx); flags = idx = 0; bc_set_flags(&flags, &idx, cv->closure_type, 3); bc_set_flags(&flags, &idx, cv->is_const, 1); bc_set_flags(&flags, &idx, cv->is_lexical, 1); bc_set_flags(&flags, &idx, cv->var_kind, 4); assert(idx <= 16); bc_put_u16(s, flags); } if (JS_WriteFunctionBytecode(s, b->byte_code_buf, b->byte_code_len)) goto fail; if (b->has_debug) { bc_put_atom(s, b->debug.filename); bc_put_leb128(s, b->debug.pc2line_len); dbuf_put(&s->dbuf, b->debug.pc2line_buf, b->debug.pc2line_len); if (b->debug.source) { bc_put_leb128(s, b->debug.source_len); dbuf_put(&s->dbuf, (uint8_t *)b->debug.source, b->debug.source_len); } else { bc_put_leb128(s, 0); } } for(i = 0; i < b->cpool_count; i++) { if (JS_WriteObjectRec(s, b->cpool[i])) goto fail; } return 0; fail: return -1; } static int JS_WriteModule(BCWriterState *s, JSValueConst obj) { JSModuleDef *m = JS_VALUE_GET_PTR(obj); int i; bc_put_u8(s, BC_TAG_MODULE); bc_put_atom(s, m->module_name); bc_put_leb128(s, m->req_module_entries_count); for(i = 0; i < m->req_module_entries_count; i++) { JSReqModuleEntry *rme = &m->req_module_entries[i]; bc_put_atom(s, rme->module_name); if (JS_WriteObjectRec(s, rme->attributes)) goto fail; } bc_put_leb128(s, m->export_entries_count); for(i = 0; i < m->export_entries_count; i++) { JSExportEntry *me = &m->export_entries[i]; bc_put_u8(s, me->export_type); if (me->export_type == JS_EXPORT_TYPE_LOCAL) { bc_put_leb128(s, me->u.local.var_idx); } else { bc_put_leb128(s, me->u.req_module_idx); bc_put_atom(s, me->local_name); } bc_put_atom(s, me->export_name); } bc_put_leb128(s, m->star_export_entries_count); for(i = 0; i < m->star_export_entries_count; i++) { JSStarExportEntry *se = &m->star_export_entries[i]; bc_put_leb128(s, se->req_module_idx); } bc_put_leb128(s, m->import_entries_count); for(i = 0; i < m->import_entries_count; i++) { JSImportEntry *mi = &m->import_entries[i]; bc_put_leb128(s, mi->var_idx); bc_put_u8(s, mi->is_star); bc_put_atom(s, mi->import_name); bc_put_leb128(s, mi->req_module_idx); } bc_put_u8(s, m->has_tla); if (JS_WriteObjectRec(s, m->func_obj)) goto fail; return 0; fail: return -1; } /* XXX: be compatible with the structured clone algorithm */ static int JS_WriteArray(BCWriterState *s, JSValueConst obj) { JSContext *ctx = s->ctx; JSObject *p = JS_VALUE_GET_OBJ(obj); uint32_t i, len; int ret; BOOL is_template; JSShapeProperty *prs; JSProperty *pr; if (s->allow_bytecode && !p->extensible) { /* not extensible array: we consider it is a template when we are saving bytecode */ bc_put_u8(s, BC_TAG_TEMPLATE_OBJECT); is_template = TRUE; } else { bc_put_u8(s, BC_TAG_ARRAY); is_template = FALSE; } if (js_get_length32(ctx, &len, obj)) /* no side effect */ goto fail; bc_put_leb128(s, len); if (p->fast_array) { for(i = 0; i < p->u.array.count; i++) { ret = JS_WriteObjectRec(s, p->u.array.u.values[i]); if (ret) goto fail; } for(i = p->u.array.count; i < len; i++) { ret = JS_WriteObjectRec(s, JS_UNDEFINED); if (ret) goto fail; } } else { for(i = 0; i < len; i++) { JSAtom atom; atom = JS_NewAtomUInt32(ctx, i); if (atom == JS_ATOM_NULL) goto fail; prs = find_own_property(&pr, p, atom); JS_FreeAtom(ctx, atom); if (prs && (prs->flags & JS_PROP_ENUMERABLE)) { if (prs->flags & JS_PROP_TMASK) { JS_ThrowTypeError(ctx, "only value properties are supported"); goto fail; } ret = JS_WriteObjectRec(s, pr->u.value); if (ret) goto fail; } else { ret = JS_WriteObjectRec(s, JS_UNDEFINED); if (ret) goto fail; } } } if (is_template) { /* the 'raw' property is not enumerable */ prs = find_own_property(&pr, p, JS_ATOM_raw); if (prs) { if (prs->flags & JS_PROP_TMASK) { JS_ThrowTypeError(ctx, "only value properties are supported"); goto fail; } ret = JS_WriteObjectRec(s, pr->u.value); if (ret) goto fail; } else { ret = JS_WriteObjectRec(s, JS_UNDEFINED); if (ret) goto fail; } } return 0; fail: return -1; } static int JS_WriteObjectTag(BCWriterState *s, JSValueConst obj) { JSObject *p = JS_VALUE_GET_OBJ(obj); uint32_t i, prop_count; JSShape *sh; JSShapeProperty *pr; int pass; JSAtom atom; bc_put_u8(s, BC_TAG_OBJECT); prop_count = 0; sh = p->shape; for(pass = 0; pass < 2; pass++) { if (pass == 1) bc_put_leb128(s, prop_count); for(i = 0, pr = get_shape_prop(sh); i < sh->prop_count; i++, pr++) { atom = pr->atom; if (atom != JS_ATOM_NULL && JS_AtomIsString(s->ctx, atom) && (pr->flags & JS_PROP_ENUMERABLE)) { if (pr->flags & JS_PROP_TMASK) { JS_ThrowTypeError(s->ctx, "only value properties are supported"); goto fail; } if (pass == 0) { prop_count++; } else { bc_put_atom(s, atom); if (JS_WriteObjectRec(s, p->prop[i].u.value)) goto fail; } } } } return 0; fail: return -1; } static int JS_WriteTypedArray(BCWriterState *s, JSValueConst obj) { JSObject *p = JS_VALUE_GET_OBJ(obj); JSTypedArray *ta = p->u.typed_array; bc_put_u8(s, BC_TAG_TYPED_ARRAY); bc_put_u8(s, p->class_id - JS_CLASS_UINT8C_ARRAY); bc_put_leb128(s, p->u.array.count); bc_put_leb128(s, ta->offset); if (JS_WriteObjectRec(s, JS_MKPTR(JS_TAG_OBJECT, ta->buffer))) return -1; return 0; } static int JS_WriteArrayBuffer(BCWriterState *s, JSValueConst obj) { JSObject *p = JS_VALUE_GET_OBJ(obj); JSArrayBuffer *abuf = p->u.array_buffer; if (abuf->detached) { JS_ThrowTypeErrorDetachedArrayBuffer(s->ctx); return -1; } bc_put_u8(s, BC_TAG_ARRAY_BUFFER); bc_put_leb128(s, abuf->byte_length); bc_put_leb128(s, abuf->max_byte_length); dbuf_put(&s->dbuf, abuf->data, abuf->byte_length); return 0; } static int JS_WriteSharedArrayBuffer(BCWriterState *s, JSValueConst obj) { JSObject *p = JS_VALUE_GET_OBJ(obj); JSArrayBuffer *abuf = p->u.array_buffer; assert(!abuf->detached); /* SharedArrayBuffer are never detached */ bc_put_u8(s, BC_TAG_SHARED_ARRAY_BUFFER); bc_put_leb128(s, abuf->byte_length); bc_put_leb128(s, abuf->max_byte_length); bc_put_u64(s, (uintptr_t)abuf->data); if (js_resize_array(s->ctx, (void **)&s->sab_tab, sizeof(s->sab_tab[0]), &s->sab_tab_size, s->sab_tab_len + 1)) return -1; /* keep the SAB pointer so that the user can clone it or free it */ s->sab_tab[s->sab_tab_len++] = abuf->data; return 0; } static int JS_WriteObjectRec(BCWriterState *s, JSValueConst obj) { uint32_t tag; if (js_check_stack_overflow(s->ctx->rt, 0)) { JS_ThrowStackOverflow(s->ctx); return -1; } tag = JS_VALUE_GET_NORM_TAG(obj); switch(tag) { case JS_TAG_NULL: bc_put_u8(s, BC_TAG_NULL); break; case JS_TAG_UNDEFINED: bc_put_u8(s, BC_TAG_UNDEFINED); break; case JS_TAG_BOOL: bc_put_u8(s, BC_TAG_BOOL_FALSE + JS_VALUE_GET_INT(obj)); break; case JS_TAG_INT: bc_put_u8(s, BC_TAG_INT32); bc_put_sleb128(s, JS_VALUE_GET_INT(obj)); break; case JS_TAG_FLOAT64: { JSFloat64Union u; bc_put_u8(s, BC_TAG_FLOAT64); u.d = JS_VALUE_GET_FLOAT64(obj); bc_put_u64(s, u.u64); } break; case JS_TAG_STRING: { JSString *p = JS_VALUE_GET_STRING(obj); bc_put_u8(s, BC_TAG_STRING); JS_WriteString(s, p); } break; case JS_TAG_STRING_ROPE: { JSValue str; str = JS_ToString(s->ctx, obj); if (JS_IsException(str)) goto fail; JS_WriteObjectRec(s, str); JS_FreeValue(s->ctx, str); } break; case JS_TAG_FUNCTION_BYTECODE: if (!s->allow_bytecode) goto invalid_tag; if (JS_WriteFunctionTag(s, obj)) goto fail; break; case JS_TAG_MODULE: if (!s->allow_bytecode) goto invalid_tag; if (JS_WriteModule(s, obj)) goto fail; break; case JS_TAG_OBJECT: { JSObject *p = JS_VALUE_GET_OBJ(obj); int ret, idx; if (s->allow_reference) { idx = js_object_list_find(s->ctx, &s->object_list, p); if (idx >= 0) { bc_put_u8(s, BC_TAG_OBJECT_REFERENCE); bc_put_leb128(s, idx); break; } else { if (js_object_list_add(s->ctx, &s->object_list, p)) goto fail; } } else { if (p->tmp_mark) { JS_ThrowTypeError(s->ctx, "circular reference"); goto fail; } p->tmp_mark = 1; } switch(p->class_id) { case JS_CLASS_ARRAY: ret = JS_WriteArray(s, obj); break; case JS_CLASS_OBJECT: ret = JS_WriteObjectTag(s, obj); break; case JS_CLASS_ARRAY_BUFFER: ret = JS_WriteArrayBuffer(s, obj); break; case JS_CLASS_SHARED_ARRAY_BUFFER: if (!s->allow_sab) goto invalid_tag; ret = JS_WriteSharedArrayBuffer(s, obj); break; case JS_CLASS_DATE: bc_put_u8(s, BC_TAG_DATE); ret = JS_WriteObjectRec(s, p->u.object_data); break; case JS_CLASS_NUMBER: case JS_CLASS_STRING: case JS_CLASS_BOOLEAN: case JS_CLASS_BIG_INT: bc_put_u8(s, BC_TAG_OBJECT_VALUE); ret = JS_WriteObjectRec(s, p->u.object_data); break; default: if (p->class_id >= JS_CLASS_UINT8C_ARRAY && p->class_id <= JS_CLASS_FLOAT64_ARRAY) { ret = JS_WriteTypedArray(s, obj); } else { JS_ThrowTypeError(s->ctx, "unsupported object class"); ret = -1; } break; } p->tmp_mark = 0; if (ret) goto fail; } break; case JS_TAG_SHORT_BIG_INT: case JS_TAG_BIG_INT: if (JS_WriteBigInt(s, obj)) goto fail; break; default: invalid_tag: JS_ThrowInternalError(s->ctx, "unsupported tag (%d)", tag); goto fail; } return 0; fail: return -1; } /* create the atom table */ static int JS_WriteObjectAtoms(BCWriterState *s) { JSRuntime *rt = s->ctx->rt; DynBuf dbuf1; int i, atoms_size; dbuf1 = s->dbuf; js_dbuf_init(s->ctx, &s->dbuf); bc_put_u8(s, BC_VERSION); bc_put_leb128(s, s->idx_to_atom_count); for(i = 0; i < s->idx_to_atom_count; i++) { JSAtomStruct *p = rt->atom_array[s->idx_to_atom[i]]; JS_WriteString(s, p); } /* XXX: should check for OOM in above phase */ /* move the atoms at the start */ /* XXX: could just append dbuf1 data, but it uses more memory if dbuf1 is larger than dbuf */ atoms_size = s->dbuf.size; if (dbuf_claim(&dbuf1, atoms_size)) goto fail; memmove(dbuf1.buf + atoms_size, dbuf1.buf, dbuf1.size); memcpy(dbuf1.buf, s->dbuf.buf, atoms_size); dbuf1.size += atoms_size; dbuf_free(&s->dbuf); s->dbuf = dbuf1; return 0; fail: dbuf_free(&dbuf1); return -1; } uint8_t *JS_WriteObject2(JSContext *ctx, size_t *psize, JSValueConst obj, int flags, uint8_t ***psab_tab, size_t *psab_tab_len) { BCWriterState ss, *s = &ss; memset(s, 0, sizeof(*s)); s->ctx = ctx; s->allow_bytecode = ((flags & JS_WRITE_OBJ_BYTECODE) != 0); s->allow_sab = ((flags & JS_WRITE_OBJ_SAB) != 0); s->allow_reference = ((flags & JS_WRITE_OBJ_REFERENCE) != 0); /* XXX: could use a different version when bytecode is included */ if (s->allow_bytecode) s->first_atom = JS_ATOM_END; else s->first_atom = 1; js_dbuf_init(ctx, &s->dbuf); js_object_list_init(&s->object_list); if (JS_WriteObjectRec(s, obj)) goto fail; if (JS_WriteObjectAtoms(s)) goto fail; js_object_list_end(ctx, &s->object_list); js_free(ctx, s->atom_to_idx); js_free(ctx, s->idx_to_atom); *psize = s->dbuf.size; if (psab_tab) *psab_tab = s->sab_tab; if (psab_tab_len) *psab_tab_len = s->sab_tab_len; return s->dbuf.buf; fail: js_object_list_end(ctx, &s->object_list); js_free(ctx, s->atom_to_idx); js_free(ctx, s->idx_to_atom); dbuf_free(&s->dbuf); *psize = 0; if (psab_tab) *psab_tab = NULL; if (psab_tab_len) *psab_tab_len = 0; return NULL; } uint8_t *JS_WriteObject(JSContext *ctx, size_t *psize, JSValueConst obj, int flags) { return JS_WriteObject2(ctx, psize, obj, flags, NULL, NULL); } typedef struct BCReaderState { JSContext *ctx; const uint8_t *buf_start, *ptr, *buf_end; uint32_t first_atom; uint32_t idx_to_atom_count; JSAtom *idx_to_atom; int error_state; BOOL allow_sab : 8; BOOL allow_bytecode : 8; BOOL is_rom_data : 8; BOOL allow_reference : 8; /* object references */ JSObject **objects; int objects_count; int objects_size; #ifdef DUMP_READ_OBJECT const uint8_t *ptr_last; int level; #endif } BCReaderState; #ifdef DUMP_READ_OBJECT static void __attribute__((format(printf, 2, 3))) bc_read_trace(BCReaderState *s, const char *fmt, ...) { va_list ap; int i, n, n0; if (!s->ptr_last) s->ptr_last = s->buf_start; n = n0 = 0; if (s->ptr > s->ptr_last || s->ptr == s->buf_start) { n0 = printf("%04x: ", (int)(s->ptr_last - s->buf_start)); n += n0; } for (i = 0; s->ptr_last < s->ptr; i++) { if ((i & 7) == 0 && i > 0) { printf("\n%*s", n0, ""); n = n0; } n += printf(" %02x", *s->ptr_last++); } if (*fmt == '}') s->level--; if (n < 32 + s->level * 2) { printf("%*s", 32 + s->level * 2 - n, ""); } va_start(ap, fmt); vfprintf(stdout, fmt, ap); va_end(ap); if (strchr(fmt, '{')) s->level++; } #else #define bc_read_trace(...) #endif static int bc_read_error_end(BCReaderState *s) { if (!s->error_state) { JS_ThrowSyntaxError(s->ctx, "read after the end of the buffer"); } return s->error_state = -1; } static int bc_get_u8(BCReaderState *s, uint8_t *pval) { if (unlikely(s->buf_end - s->ptr < 1)) { *pval = 0; /* avoid warning */ return bc_read_error_end(s); } *pval = *s->ptr++; return 0; } static int bc_get_u16(BCReaderState *s, uint16_t *pval) { uint16_t v; if (unlikely(s->buf_end - s->ptr < 2)) { *pval = 0; /* avoid warning */ return bc_read_error_end(s); } v = get_u16(s->ptr); if (is_be()) v = bswap16(v); *pval = v; s->ptr += 2; return 0; } static __maybe_unused int bc_get_u32(BCReaderState *s, uint32_t *pval) { uint32_t v; if (unlikely(s->buf_end - s->ptr < 4)) { *pval = 0; /* avoid warning */ return bc_read_error_end(s); } v = get_u32(s->ptr); if (is_be()) v = bswap32(v); *pval = v; s->ptr += 4; return 0; } static int bc_get_u64(BCReaderState *s, uint64_t *pval) { uint64_t v; if (unlikely(s->buf_end - s->ptr < 8)) { *pval = 0; /* avoid warning */ return bc_read_error_end(s); } v = get_u64(s->ptr); if (is_be()) v = bswap64(v); *pval = v; s->ptr += 8; return 0; } static int bc_get_leb128(BCReaderState *s, uint32_t *pval) { int ret; ret = get_leb128(pval, s->ptr, s->buf_end); if (unlikely(ret < 0)) return bc_read_error_end(s); s->ptr += ret; return 0; } static int bc_get_sleb128(BCReaderState *s, int32_t *pval) { int ret; ret = get_sleb128(pval, s->ptr, s->buf_end); if (unlikely(ret < 0)) return bc_read_error_end(s); s->ptr += ret; return 0; } /* XXX: used to read an `int` with a positive value */ static int bc_get_leb128_int(BCReaderState *s, int *pval) { return bc_get_leb128(s, (uint32_t *)pval); } static int bc_get_leb128_u16(BCReaderState *s, uint16_t *pval) { uint32_t val; if (bc_get_leb128(s, &val)) { *pval = 0; return -1; } *pval = val; return 0; } static int bc_get_buf(BCReaderState *s, uint8_t *buf, uint32_t buf_len) { if (buf_len != 0) { if (unlikely(!buf || s->buf_end - s->ptr < buf_len)) return bc_read_error_end(s); memcpy(buf, s->ptr, buf_len); s->ptr += buf_len; } return 0; } static int bc_idx_to_atom(BCReaderState *s, JSAtom *patom, uint32_t idx) { JSAtom atom; if (__JS_AtomIsTaggedInt(idx)) { atom = idx; } else if (idx < s->first_atom) { atom = JS_DupAtom(s->ctx, idx); } else { idx -= s->first_atom; if (idx >= s->idx_to_atom_count) { JS_ThrowSyntaxError(s->ctx, "invalid atom index (pos=%u)", (unsigned int)(s->ptr - s->buf_start)); *patom = JS_ATOM_NULL; return s->error_state = -1; } atom = JS_DupAtom(s->ctx, s->idx_to_atom[idx]); } *patom = atom; return 0; } static int bc_get_atom(BCReaderState *s, JSAtom *patom) { uint32_t v; if (bc_get_leb128(s, &v)) return -1; if (v & 1) { *patom = __JS_AtomFromUInt32(v >> 1); return 0; } else { return bc_idx_to_atom(s, patom, v >> 1); } } static JSString *JS_ReadString(BCReaderState *s) { uint32_t len; size_t size; BOOL is_wide_char; JSString *p; if (bc_get_leb128(s, &len)) return NULL; is_wide_char = len & 1; len >>= 1; if (len > JS_STRING_LEN_MAX) { JS_ThrowInternalError(s->ctx, "string too long"); return NULL; } p = js_alloc_string(s->ctx, len, is_wide_char); if (!p) { s->error_state = -1; return NULL; } size = (size_t)len << is_wide_char; if ((s->buf_end - s->ptr) < size) { bc_read_error_end(s); js_free_string(s->ctx->rt, p); return NULL; } memcpy(p->u.str8, s->ptr, size); s->ptr += size; if (is_wide_char) { if (is_be()) { uint32_t i; for (i = 0; i < len; i++) p->u.str16[i] = bswap16(p->u.str16[i]); } } else { p->u.str8[size] = '\0'; /* add the trailing zero for 8 bit strings */ } #ifdef DUMP_READ_OBJECT JS_DumpString(s->ctx->rt, p); printf("\n"); #endif return p; } static uint32_t bc_get_flags(uint32_t flags, int *pidx, int n) { uint32_t val; /* XXX: this does not work for n == 32 */ val = (flags >> *pidx) & ((1U << n) - 1); *pidx += n; return val; } static int JS_ReadFunctionBytecode(BCReaderState *s, JSFunctionBytecode *b, int byte_code_offset, uint32_t bc_len) { uint8_t *bc_buf; int pos, len, op; JSAtom atom; uint32_t idx; if (s->is_rom_data) { /* directly use the input buffer */ if (unlikely(s->buf_end - s->ptr < bc_len)) return bc_read_error_end(s); bc_buf = (uint8_t *)s->ptr; s->ptr += bc_len; } else { bc_buf = (void *)((uint8_t*)b + byte_code_offset); if (bc_get_buf(s, bc_buf, bc_len)) return -1; } b->byte_code_buf = bc_buf; if (is_be()) bc_byte_swap(bc_buf, bc_len); pos = 0; while (pos < bc_len) { op = bc_buf[pos]; len = short_opcode_info(op).size; switch(short_opcode_info(op).fmt) { case OP_FMT_atom: case OP_FMT_atom_u8: case OP_FMT_atom_u16: case OP_FMT_atom_label_u8: case OP_FMT_atom_label_u16: idx = get_u32(bc_buf + pos + 1); if (s->is_rom_data) { /* just increment the reference count of the atom */ JS_DupAtom(s->ctx, (JSAtom)idx); } else { if (bc_idx_to_atom(s, &atom, idx)) { /* Note: the atoms will be freed up to this position */ b->byte_code_len = pos; return -1; } put_u32(bc_buf + pos + 1, atom); #ifdef DUMP_READ_OBJECT bc_read_trace(s, "at %d, fixup atom: ", pos + 1); print_atom(s->ctx, atom); printf("\n"); #endif } break; default: break; } pos += len; } return 0; } static JSValue JS_ReadBigInt(BCReaderState *s) { JSValue obj = JS_UNDEFINED; uint32_t len, i, n; JSBigInt *p; js_limb_t v; uint8_t v8; if (bc_get_leb128(s, &len)) goto fail; bc_read_trace(s, "len=%" PRId64 "\n", (int64_t)len); if (len == 0) { /* zero case */ bc_read_trace(s, "}\n"); return __JS_NewShortBigInt(s->ctx, 0); } p = js_bigint_new(s->ctx, (len - 1) / (JS_LIMB_BITS / 8) + 1); if (!p) goto fail; for(i = 0; i < len / (JS_LIMB_BITS / 8); i++) { #if JS_LIMB_BITS == 32 if (bc_get_u32(s, &v)) goto fail; #else if (bc_get_u64(s, &v)) goto fail; #endif p->tab[i] = v; } n = len % (JS_LIMB_BITS / 8); if (n != 0) { int shift; v = 0; for(i = 0; i < n; i++) { if (bc_get_u8(s, &v8)) goto fail; v |= (js_limb_t)v8 << (i * 8); } shift = JS_LIMB_BITS - n * 8; /* extend the sign */ if (shift != 0) { v = (js_slimb_t)(v << shift) >> shift; } p->tab[p->len - 1] = v; } bc_read_trace(s, "}\n"); return JS_CompactBigInt(s->ctx, p); fail: JS_FreeValue(s->ctx, obj); return JS_EXCEPTION; } static JSValue JS_ReadObjectRec(BCReaderState *s); static int BC_add_object_ref1(BCReaderState *s, JSObject *p) { if (s->allow_reference) { if (js_resize_array(s->ctx, (void *)&s->objects, sizeof(s->objects[0]), &s->objects_size, s->objects_count + 1)) return -1; s->objects[s->objects_count++] = p; } return 0; } static int BC_add_object_ref(BCReaderState *s, JSValueConst obj) { return BC_add_object_ref1(s, JS_VALUE_GET_OBJ(obj)); } static JSValue JS_ReadFunctionTag(BCReaderState *s) { JSContext *ctx = s->ctx; JSFunctionBytecode bc, *b; JSValue obj = JS_UNDEFINED; uint16_t v16; uint8_t v8; int idx, i, local_count; int cpool_offset, byte_code_offset; int closure_var_offset, vardefs_offset; uint64_t function_size; memset(&bc, 0, sizeof(bc)); bc.header.ref_count = 1; //bc.gc_header.mark = 0; if (bc_get_u16(s, &v16)) goto fail; idx = 0; bc.has_prototype = bc_get_flags(v16, &idx, 1); bc.has_simple_parameter_list = bc_get_flags(v16, &idx, 1); bc.is_derived_class_constructor = bc_get_flags(v16, &idx, 1); bc.need_home_object = bc_get_flags(v16, &idx, 1); bc.func_kind = bc_get_flags(v16, &idx, 2); bc.new_target_allowed = bc_get_flags(v16, &idx, 1); bc.super_call_allowed = bc_get_flags(v16, &idx, 1); bc.super_allowed = bc_get_flags(v16, &idx, 1); bc.arguments_allowed = bc_get_flags(v16, &idx, 1); bc.has_debug = bc_get_flags(v16, &idx, 1); bc.is_direct_or_indirect_eval = bc_get_flags(v16, &idx, 1); bc.read_only_bytecode = s->is_rom_data; if (bc_get_u8(s, &v8)) goto fail; bc.js_mode = v8; if (bc_get_atom(s, &bc.func_name)) //@ atom leak if failure goto fail; if (bc_get_leb128_u16(s, &bc.arg_count)) goto fail; if (bc_get_leb128_u16(s, &bc.var_count)) goto fail; if (bc_get_leb128_u16(s, &bc.defined_arg_count)) goto fail; if (bc_get_leb128_u16(s, &bc.stack_size)) goto fail; if (bc_get_leb128_u16(s, &bc.var_ref_count)) goto fail; if (bc_get_leb128_int(s, &bc.closure_var_count)) goto fail; if (bc_get_leb128_int(s, &bc.cpool_count)) goto fail; if (bc_get_leb128_int(s, &bc.byte_code_len)) goto fail; if (bc_get_leb128_int(s, &local_count)) goto fail; if (bc.has_debug) { function_size = sizeof(*b); } else { function_size = offsetof(JSFunctionBytecode, debug); } cpool_offset = function_size; function_size += (uint64_t)bc.cpool_count * sizeof(*bc.cpool); vardefs_offset = function_size; function_size += (uint64_t)local_count * sizeof(*bc.vardefs); closure_var_offset = function_size; function_size += (uint64_t)bc.closure_var_count * sizeof(*bc.closure_var); byte_code_offset = function_size; if (!bc.read_only_bytecode) { function_size += bc.byte_code_len; } if (function_size > INT32_MAX) return JS_ThrowOutOfMemory(ctx); b = js_mallocz(ctx, function_size); if (!b) return JS_EXCEPTION; memcpy(b, &bc, offsetof(JSFunctionBytecode, debug)); b->header.ref_count = 1; if (local_count != 0) { b->vardefs = (void *)((uint8_t*)b + vardefs_offset); } if (b->closure_var_count != 0) { b->closure_var = (void *)((uint8_t*)b + closure_var_offset); } if (b->cpool_count != 0) { b->cpool = (void *)((uint8_t*)b + cpool_offset); } add_gc_object(ctx->rt, &b->header, JS_GC_OBJ_TYPE_FUNCTION_BYTECODE); obj = JS_MKPTR(JS_TAG_FUNCTION_BYTECODE, b); #ifdef DUMP_READ_OBJECT bc_read_trace(s, "name: "); print_atom(s->ctx, b->func_name); printf("\n"); #endif bc_read_trace(s, "args=%d vars=%d defargs=%d closures=%d cpool=%d\n", b->arg_count, b->var_count, b->defined_arg_count, b->closure_var_count, b->cpool_count); bc_read_trace(s, "stack=%d bclen=%d locals=%d\n", b->stack_size, b->byte_code_len, local_count); if (local_count != 0) { bc_read_trace(s, "vars {\n"); for(i = 0; i < local_count; i++) { JSBytecodeVarDef *vd = &b->vardefs[i]; if (bc_get_atom(s, &vd->var_name)) goto fail; if (bc_get_leb128_int(s, &vd->scope_next)) goto fail; vd->scope_next--; if (bc_get_leb128_u16(s, &vd->var_ref_idx)) goto fail; if (bc_get_u8(s, &v8)) goto fail; idx = 0; vd->var_kind = bc_get_flags(v8, &idx, 4); vd->is_const = bc_get_flags(v8, &idx, 1); vd->is_lexical = bc_get_flags(v8, &idx, 1); vd->is_captured = bc_get_flags(v8, &idx, 1); vd->has_scope = bc_get_flags(v8, &idx, 1); #ifdef DUMP_READ_OBJECT bc_read_trace(s, "name: "); print_atom(s->ctx, vd->var_name); printf("\n"); #endif } bc_read_trace(s, "}\n"); } if (b->closure_var_count != 0) { bc_read_trace(s, "closure vars {\n"); for(i = 0; i < b->closure_var_count; i++) { JSClosureVar *cv = &b->closure_var[i]; int var_idx; if (bc_get_atom(s, &cv->var_name)) goto fail; if (bc_get_leb128_int(s, &var_idx)) goto fail; cv->var_idx = var_idx; if (bc_get_u16(s, &v16)) goto fail; idx = 0; cv->closure_type = bc_get_flags(v16, &idx, 3); cv->is_const = bc_get_flags(v16, &idx, 1); cv->is_lexical = bc_get_flags(v16, &idx, 1); cv->var_kind = bc_get_flags(v16, &idx, 4); #ifdef DUMP_READ_OBJECT bc_read_trace(s, "name: "); print_atom(s->ctx, cv->var_name); printf("\n"); #endif } bc_read_trace(s, "}\n"); } { bc_read_trace(s, "bytecode {\n"); if (JS_ReadFunctionBytecode(s, b, byte_code_offset, b->byte_code_len)) goto fail; bc_read_trace(s, "}\n"); } if (b->has_debug) { /* read optional debug information */ bc_read_trace(s, "debug {\n"); if (bc_get_atom(s, &b->debug.filename)) goto fail; #ifdef DUMP_READ_OBJECT bc_read_trace(s, "filename: "); print_atom(s->ctx, b->debug.filename); printf("\n"); #endif if (bc_get_leb128_int(s, &b->debug.pc2line_len)) goto fail; if (b->debug.pc2line_len) { b->debug.pc2line_buf = js_mallocz(ctx, b->debug.pc2line_len); if (!b->debug.pc2line_buf) goto fail; if (bc_get_buf(s, b->debug.pc2line_buf, b->debug.pc2line_len)) goto fail; } if (bc_get_leb128_int(s, &b->debug.source_len)) goto fail; if (b->debug.source_len) { bc_read_trace(s, "source: %d bytes\n", b->source_len); b->debug.source = js_mallocz(ctx, b->debug.source_len); if (!b->debug.source) goto fail; if (bc_get_buf(s, (uint8_t *)b->debug.source, b->debug.source_len)) goto fail; } bc_read_trace(s, "}\n"); } if (b->cpool_count != 0) { bc_read_trace(s, "cpool {\n"); for(i = 0; i < b->cpool_count; i++) { JSValue val; val = JS_ReadObjectRec(s); if (JS_IsException(val)) goto fail; b->cpool[i] = val; } bc_read_trace(s, "}\n"); } b->realm = JS_DupContext(ctx); return obj; fail: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue JS_ReadModule(BCReaderState *s) { JSContext *ctx = s->ctx; JSValue obj; JSModuleDef *m = NULL; JSAtom module_name; int i; uint8_t v8; if (bc_get_atom(s, &module_name)) goto fail; #ifdef DUMP_READ_OBJECT bc_read_trace(s, "name: "); print_atom(s->ctx, module_name); printf("\n"); #endif m = js_new_module_def(ctx, module_name); if (!m) goto fail; obj = JS_NewModuleValue(ctx, m); if (bc_get_leb128_int(s, &m->req_module_entries_count)) goto fail; if (m->req_module_entries_count != 0) { m->req_module_entries_size = m->req_module_entries_count; m->req_module_entries = js_mallocz(ctx, sizeof(m->req_module_entries[0]) * m->req_module_entries_size); if (!m->req_module_entries) goto fail; for(i = 0; i < m->req_module_entries_count; i++) { JSReqModuleEntry *rme = &m->req_module_entries[i]; JSValue val; if (bc_get_atom(s, &rme->module_name)) goto fail; val = JS_ReadObjectRec(s); if (JS_IsException(val)) goto fail; rme->attributes = val; } } if (bc_get_leb128_int(s, &m->export_entries_count)) goto fail; if (m->export_entries_count != 0) { m->export_entries_size = m->export_entries_count; m->export_entries = js_mallocz(ctx, sizeof(m->export_entries[0]) * m->export_entries_size); if (!m->export_entries) goto fail; for(i = 0; i < m->export_entries_count; i++) { JSExportEntry *me = &m->export_entries[i]; if (bc_get_u8(s, &v8)) goto fail; me->export_type = v8; if (me->export_type == JS_EXPORT_TYPE_LOCAL) { if (bc_get_leb128_int(s, &me->u.local.var_idx)) goto fail; } else { if (bc_get_leb128_int(s, &me->u.req_module_idx)) goto fail; if (bc_get_atom(s, &me->local_name)) goto fail; } if (bc_get_atom(s, &me->export_name)) goto fail; } } if (bc_get_leb128_int(s, &m->star_export_entries_count)) goto fail; if (m->star_export_entries_count != 0) { m->star_export_entries_size = m->star_export_entries_count; m->star_export_entries = js_mallocz(ctx, sizeof(m->star_export_entries[0]) * m->star_export_entries_size); if (!m->star_export_entries) goto fail; for(i = 0; i < m->star_export_entries_count; i++) { JSStarExportEntry *se = &m->star_export_entries[i]; if (bc_get_leb128_int(s, &se->req_module_idx)) goto fail; } } if (bc_get_leb128_int(s, &m->import_entries_count)) goto fail; if (m->import_entries_count != 0) { m->import_entries_size = m->import_entries_count; m->import_entries = js_mallocz(ctx, sizeof(m->import_entries[0]) * m->import_entries_size); if (!m->import_entries) goto fail; for(i = 0; i < m->import_entries_count; i++) { JSImportEntry *mi = &m->import_entries[i]; uint8_t v8; if (bc_get_leb128_int(s, &mi->var_idx)) goto fail; if (bc_get_u8(s, &v8)) goto fail; mi->is_star = (v8 != 0); if (bc_get_atom(s, &mi->import_name)) goto fail; if (bc_get_leb128_int(s, &mi->req_module_idx)) goto fail; } } if (bc_get_u8(s, &v8)) goto fail; m->has_tla = (v8 != 0); m->func_obj = JS_ReadObjectRec(s); if (JS_IsException(m->func_obj)) goto fail; return obj; fail: if (m) { JS_FreeValue(ctx, JS_MKPTR(JS_TAG_MODULE, m)); } return JS_EXCEPTION; } static JSValue JS_ReadObjectTag(BCReaderState *s) { JSContext *ctx = s->ctx; JSValue obj; uint32_t prop_count, i; JSAtom atom; JSValue val; int ret; obj = JS_NewObject(ctx); if (BC_add_object_ref(s, obj)) goto fail; if (bc_get_leb128(s, &prop_count)) goto fail; for(i = 0; i < prop_count; i++) { if (bc_get_atom(s, &atom)) goto fail; #ifdef DUMP_READ_OBJECT bc_read_trace(s, "propname: "); print_atom(s->ctx, atom); printf("\n"); #endif val = JS_ReadObjectRec(s); if (JS_IsException(val)) { JS_FreeAtom(ctx, atom); goto fail; } ret = JS_DefinePropertyValue(ctx, obj, atom, val, JS_PROP_C_W_E); JS_FreeAtom(ctx, atom); if (ret < 0) goto fail; } return obj; fail: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue JS_ReadArray(BCReaderState *s, int tag) { JSContext *ctx = s->ctx; JSValue obj; uint32_t len, i; JSValue val; int ret, prop_flags; BOOL is_template; obj = JS_NewArray(ctx); if (BC_add_object_ref(s, obj)) goto fail; is_template = (tag == BC_TAG_TEMPLATE_OBJECT); if (bc_get_leb128(s, &len)) goto fail; for(i = 0; i < len; i++) { val = JS_ReadObjectRec(s); if (JS_IsException(val)) goto fail; if (is_template) prop_flags = JS_PROP_ENUMERABLE; else prop_flags = JS_PROP_C_W_E; ret = JS_DefinePropertyValueUint32(ctx, obj, i, val, prop_flags); if (ret < 0) goto fail; } if (is_template) { val = JS_ReadObjectRec(s); if (JS_IsException(val)) goto fail; if (!JS_IsUndefined(val)) { ret = JS_DefinePropertyValue(ctx, obj, JS_ATOM_raw, val, 0); if (ret < 0) goto fail; } JS_PreventExtensions(ctx, obj); } return obj; fail: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue JS_ReadTypedArray(BCReaderState *s) { JSContext *ctx = s->ctx; JSValue obj = JS_UNDEFINED, array_buffer = JS_UNDEFINED; uint8_t array_tag; JSValueConst args[3]; uint32_t offset, len, idx; if (bc_get_u8(s, &array_tag)) return JS_EXCEPTION; if (array_tag >= JS_TYPED_ARRAY_COUNT) return JS_ThrowTypeError(ctx, "invalid typed array"); if (bc_get_leb128(s, &len)) return JS_EXCEPTION; if (bc_get_leb128(s, &offset)) return JS_EXCEPTION; /* XXX: this hack could be avoided if the typed array could be created before the array buffer */ idx = s->objects_count; if (BC_add_object_ref1(s, NULL)) goto fail; array_buffer = JS_ReadObjectRec(s); if (JS_IsException(array_buffer)) return JS_EXCEPTION; if (!js_get_array_buffer(ctx, array_buffer)) { JS_FreeValue(ctx, array_buffer); return JS_EXCEPTION; } args[0] = array_buffer; args[1] = JS_NewInt64(ctx, offset); args[2] = JS_NewInt64(ctx, len); obj = js_typed_array_constructor(ctx, JS_UNDEFINED, 3, args, JS_CLASS_UINT8C_ARRAY + array_tag); if (JS_IsException(obj)) goto fail; if (s->allow_reference) { s->objects[idx] = JS_VALUE_GET_OBJ(obj); } JS_FreeValue(ctx, array_buffer); return obj; fail: JS_FreeValue(ctx, array_buffer); JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue JS_ReadArrayBuffer(BCReaderState *s) { JSContext *ctx = s->ctx; uint32_t byte_length, max_byte_length; uint64_t max_byte_length_u64, *pmax_byte_length = NULL; JSValue obj; if (bc_get_leb128(s, &byte_length)) return JS_EXCEPTION; if (bc_get_leb128(s, &max_byte_length)) return JS_EXCEPTION; if (max_byte_length < byte_length) return JS_ThrowTypeError(ctx, "invalid array buffer"); if (max_byte_length != UINT32_MAX) { max_byte_length_u64 = max_byte_length; pmax_byte_length = &max_byte_length_u64; } if (unlikely(s->buf_end - s->ptr < byte_length)) { bc_read_error_end(s); return JS_EXCEPTION; } // makes a copy of the input obj = js_array_buffer_constructor3(ctx, JS_UNDEFINED, byte_length, pmax_byte_length, JS_CLASS_ARRAY_BUFFER, (uint8_t*)s->ptr, js_array_buffer_free, NULL, /*alloc_flag*/TRUE); if (JS_IsException(obj)) goto fail; if (BC_add_object_ref(s, obj)) goto fail; s->ptr += byte_length; return obj; fail: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue JS_ReadSharedArrayBuffer(BCReaderState *s) { JSContext *ctx = s->ctx; uint32_t byte_length, max_byte_length; uint64_t max_byte_length_u64, *pmax_byte_length = NULL; uint8_t *data_ptr; JSValue obj; uint64_t u64; if (bc_get_leb128(s, &byte_length)) return JS_EXCEPTION; if (bc_get_leb128(s, &max_byte_length)) return JS_EXCEPTION; if (max_byte_length < byte_length) return JS_ThrowTypeError(ctx, "invalid array buffer"); if (max_byte_length != UINT32_MAX) { max_byte_length_u64 = max_byte_length; pmax_byte_length = &max_byte_length_u64; } if (bc_get_u64(s, &u64)) return JS_EXCEPTION; data_ptr = (uint8_t *)(uintptr_t)u64; /* the SharedArrayBuffer is cloned */ obj = js_array_buffer_constructor3(ctx, JS_UNDEFINED, byte_length, pmax_byte_length, JS_CLASS_SHARED_ARRAY_BUFFER, data_ptr, NULL, NULL, FALSE); if (JS_IsException(obj)) goto fail; if (BC_add_object_ref(s, obj)) goto fail; return obj; fail: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue JS_ReadDate(BCReaderState *s) { JSContext *ctx = s->ctx; JSValue val, obj = JS_UNDEFINED; val = JS_ReadObjectRec(s); if (JS_IsException(val)) goto fail; if (!JS_IsNumber(val)) { JS_ThrowTypeError(ctx, "Number tag expected for date"); goto fail; } obj = JS_NewObjectProtoClass(ctx, ctx->class_proto[JS_CLASS_DATE], JS_CLASS_DATE); if (JS_IsException(obj)) goto fail; if (BC_add_object_ref(s, obj)) goto fail; JS_SetObjectData(ctx, obj, val); return obj; fail: JS_FreeValue(ctx, val); JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue JS_ReadObjectValue(BCReaderState *s) { JSContext *ctx = s->ctx; JSValue val, obj = JS_UNDEFINED; val = JS_ReadObjectRec(s); if (JS_IsException(val)) goto fail; obj = JS_ToObject(ctx, val); if (JS_IsException(obj)) goto fail; if (BC_add_object_ref(s, obj)) goto fail; JS_FreeValue(ctx, val); return obj; fail: JS_FreeValue(ctx, val); JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue JS_ReadObjectRec(BCReaderState *s) { JSContext *ctx = s->ctx; uint8_t tag; JSValue obj = JS_UNDEFINED; if (js_check_stack_overflow(ctx->rt, 0)) return JS_ThrowStackOverflow(ctx); if (bc_get_u8(s, &tag)) return JS_EXCEPTION; bc_read_trace(s, "%s {\n", bc_tag_str[tag]); switch(tag) { case BC_TAG_NULL: obj = JS_NULL; break; case BC_TAG_UNDEFINED: obj = JS_UNDEFINED; break; case BC_TAG_BOOL_FALSE: case BC_TAG_BOOL_TRUE: obj = JS_NewBool(ctx, tag - BC_TAG_BOOL_FALSE); break; case BC_TAG_INT32: { int32_t val; if (bc_get_sleb128(s, &val)) return JS_EXCEPTION; bc_read_trace(s, "%d\n", val); obj = JS_NewInt32(ctx, val); } break; case BC_TAG_FLOAT64: { JSFloat64Union u; if (bc_get_u64(s, &u.u64)) return JS_EXCEPTION; bc_read_trace(s, "%g\n", u.d); obj = __JS_NewFloat64(ctx, u.d); } break; case BC_TAG_STRING: { JSString *p; p = JS_ReadString(s); if (!p) return JS_EXCEPTION; obj = JS_MKPTR(JS_TAG_STRING, p); } break; case BC_TAG_FUNCTION_BYTECODE: if (!s->allow_bytecode) goto invalid_tag; obj = JS_ReadFunctionTag(s); break; case BC_TAG_MODULE: if (!s->allow_bytecode) goto invalid_tag; obj = JS_ReadModule(s); break; case BC_TAG_OBJECT: obj = JS_ReadObjectTag(s); break; case BC_TAG_ARRAY: case BC_TAG_TEMPLATE_OBJECT: obj = JS_ReadArray(s, tag); break; case BC_TAG_TYPED_ARRAY: obj = JS_ReadTypedArray(s); break; case BC_TAG_ARRAY_BUFFER: obj = JS_ReadArrayBuffer(s); break; case BC_TAG_SHARED_ARRAY_BUFFER: if (!s->allow_sab || !ctx->rt->sab_funcs.sab_dup) goto invalid_tag; obj = JS_ReadSharedArrayBuffer(s); break; case BC_TAG_DATE: obj = JS_ReadDate(s); break; case BC_TAG_OBJECT_VALUE: obj = JS_ReadObjectValue(s); break; case BC_TAG_BIG_INT: obj = JS_ReadBigInt(s); break; case BC_TAG_OBJECT_REFERENCE: { uint32_t val; if (!s->allow_reference) return JS_ThrowSyntaxError(ctx, "object references are not allowed"); if (bc_get_leb128(s, &val)) return JS_EXCEPTION; bc_read_trace(s, "%u\n", val); if (val >= s->objects_count) { return JS_ThrowSyntaxError(ctx, "invalid object reference (%u >= %u)", val, s->objects_count); } obj = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, s->objects[val])); } break; default: invalid_tag: return JS_ThrowSyntaxError(ctx, "invalid tag (tag=%d pos=%u)", tag, (unsigned int)(s->ptr - s->buf_start)); } bc_read_trace(s, "}\n"); return obj; } static int JS_ReadObjectAtoms(BCReaderState *s) { uint8_t v8; JSString *p; int i; JSAtom atom; if (bc_get_u8(s, &v8)) return -1; if (v8 != BC_VERSION) { JS_ThrowSyntaxError(s->ctx, "invalid version (%d expected=%d)", v8, BC_VERSION); return -1; } if (bc_get_leb128(s, &s->idx_to_atom_count)) return -1; bc_read_trace(s, "%d atom indexes {\n", s->idx_to_atom_count); if (s->idx_to_atom_count != 0) { s->idx_to_atom = js_mallocz(s->ctx, s->idx_to_atom_count * sizeof(s->idx_to_atom[0])); if (!s->idx_to_atom) return s->error_state = -1; } for(i = 0; i < s->idx_to_atom_count; i++) { p = JS_ReadString(s); if (!p) return -1; atom = JS_NewAtomStr(s->ctx, p); if (atom == JS_ATOM_NULL) return s->error_state = -1; s->idx_to_atom[i] = atom; if (s->is_rom_data && (atom != (i + s->first_atom))) s->is_rom_data = FALSE; /* atoms must be relocated */ } bc_read_trace(s, "}\n"); return 0; } static void bc_reader_free(BCReaderState *s) { int i; if (s->idx_to_atom) { for(i = 0; i < s->idx_to_atom_count; i++) { JS_FreeAtom(s->ctx, s->idx_to_atom[i]); } js_free(s->ctx, s->idx_to_atom); } js_free(s->ctx, s->objects); } JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len, int flags) { BCReaderState ss, *s = &ss; JSValue obj; ctx->binary_object_count += 1; ctx->binary_object_size += buf_len; memset(s, 0, sizeof(*s)); s->ctx = ctx; s->buf_start = buf; s->buf_end = buf + buf_len; s->ptr = buf; s->allow_bytecode = ((flags & JS_READ_OBJ_BYTECODE) != 0); s->is_rom_data = ((flags & JS_READ_OBJ_ROM_DATA) != 0); s->allow_sab = ((flags & JS_READ_OBJ_SAB) != 0); s->allow_reference = ((flags & JS_READ_OBJ_REFERENCE) != 0); if (s->allow_bytecode) s->first_atom = JS_ATOM_END; else s->first_atom = 1; if (JS_ReadObjectAtoms(s)) { obj = JS_EXCEPTION; } else { obj = JS_ReadObjectRec(s); } bc_reader_free(s); return obj; } /*******************************************************************/ /* runtime functions & objects */ static JSValue js_string_constructor(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv); static JSValue js_boolean_constructor(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv); static JSValue js_number_constructor(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv); static int check_function(JSContext *ctx, JSValueConst obj) { if (likely(JS_IsFunction(ctx, obj))) return 0; JS_ThrowTypeError(ctx, "not a function"); return -1; } static int check_exception_free(JSContext *ctx, JSValue obj) { JS_FreeValue(ctx, obj); return JS_IsException(obj); } static JSAtom find_atom(JSContext *ctx, const char *name) { JSAtom atom; int len; if (*name == '[') { name++; len = strlen(name) - 1; /* We assume 8 bit non null strings, which is the case for these symbols */ for(atom = JS_ATOM_Symbol_toPrimitive; atom < JS_ATOM_END; atom++) { JSAtomStruct *p = ctx->rt->atom_array[atom]; JSString *str = p; if (str->len == len && !memcmp(str->u.str8, name, len)) return JS_DupAtom(ctx, atom); } abort(); } else { atom = JS_NewAtom(ctx, name); } return atom; } static JSValue JS_NewObjectProtoList(JSContext *ctx, JSValueConst proto, const JSCFunctionListEntry *fields, int n_fields) { JSValue obj; obj = JS_NewObjectProtoClassAlloc(ctx, proto, JS_CLASS_OBJECT, n_fields); if (JS_IsException(obj)) return obj; if (JS_SetPropertyFunctionList(ctx, obj, fields, n_fields)) { JS_FreeValue(ctx, obj); return JS_EXCEPTION; } return obj; } static JSValue JS_InstantiateFunctionListItem2(JSContext *ctx, JSObject *p, JSAtom atom, void *opaque) { const JSCFunctionListEntry *e = opaque; JSValue val, proto; switch(e->def_type) { case JS_DEF_CFUNC: val = JS_NewCFunction2(ctx, e->u.func.cfunc.generic, e->name, e->u.func.length, e->u.func.cproto, e->magic); break; case JS_DEF_PROP_STRING: val = JS_NewAtomString(ctx, e->u.str); break; case JS_DEF_OBJECT: /* XXX: could add a flag */ if (atom == JS_ATOM_Symbol_unscopables) proto = JS_NULL; else proto = ctx->class_proto[JS_CLASS_OBJECT]; val = JS_NewObjectProtoList(ctx, proto, e->u.prop_list.tab, e->u.prop_list.len); break; default: abort(); } return val; } static int JS_InstantiateFunctionListItem(JSContext *ctx, JSValueConst obj, JSAtom atom, const JSCFunctionListEntry *e) { JSValue val; int prop_flags = e->prop_flags; switch(e->def_type) { case JS_DEF_ALIAS: /* using autoinit for aliases is not safe */ { JSAtom atom1 = find_atom(ctx, e->u.alias.name); switch (e->u.alias.base) { case -1: val = JS_GetProperty(ctx, obj, atom1); break; case 0: val = JS_GetProperty(ctx, ctx->global_obj, atom1); break; case 1: val = JS_GetProperty(ctx, ctx->class_proto[JS_CLASS_ARRAY], atom1); break; default: abort(); } JS_FreeAtom(ctx, atom1); if (JS_IsException(val)) return -1; if (atom == JS_ATOM_Symbol_toPrimitive) { /* Symbol.toPrimitive functions are not writable */ prop_flags = JS_PROP_CONFIGURABLE; } else if (atom == JS_ATOM_Symbol_hasInstance) { /* Function.prototype[Symbol.hasInstance] is not writable nor configurable */ prop_flags = 0; } } break; case JS_DEF_CFUNC: if (atom == JS_ATOM_Symbol_toPrimitive) { /* Symbol.toPrimitive functions are not writable */ prop_flags = JS_PROP_CONFIGURABLE; } else if (atom == JS_ATOM_Symbol_hasInstance) { /* Function.prototype[Symbol.hasInstance] is not writable nor configurable */ prop_flags = 0; } if (JS_DefineAutoInitProperty(ctx, obj, atom, JS_AUTOINIT_ID_PROP, (void *)e, prop_flags) < 0) return -1; return 0; case JS_DEF_CGETSET: /* XXX: use autoinit again ? */ case JS_DEF_CGETSET_MAGIC: { JSValue getter, setter; char buf[64]; getter = JS_UNDEFINED; if (e->u.getset.get.generic) { snprintf(buf, sizeof(buf), "get %s", e->name); getter = JS_NewCFunction2(ctx, e->u.getset.get.generic, buf, 0, e->def_type == JS_DEF_CGETSET_MAGIC ? JS_CFUNC_getter_magic : JS_CFUNC_getter, e->magic); if (JS_IsException(getter)) return -1; } setter = JS_UNDEFINED; if (e->u.getset.set.generic) { snprintf(buf, sizeof(buf), "set %s", e->name); setter = JS_NewCFunction2(ctx, e->u.getset.set.generic, buf, 1, e->def_type == JS_DEF_CGETSET_MAGIC ? JS_CFUNC_setter_magic : JS_CFUNC_setter, e->magic); if (JS_IsException(setter)) { JS_FreeValue(ctx, getter); return -1; } } if (JS_DefinePropertyGetSet(ctx, obj, atom, getter, setter, prop_flags) < 0) return -1; return 0; } break; case JS_DEF_PROP_INT32: val = JS_NewInt32(ctx, e->u.i32); break; case JS_DEF_PROP_INT64: val = JS_NewInt64(ctx, e->u.i64); break; case JS_DEF_PROP_DOUBLE: val = __JS_NewFloat64(ctx, e->u.f64); break; case JS_DEF_PROP_UNDEFINED: val = JS_UNDEFINED; break; case JS_DEF_PROP_ATOM: val = JS_AtomToValue(ctx, e->u.i32); break; case JS_DEF_PROP_BOOL: val = JS_NewBool(ctx, e->u.i32); break; case JS_DEF_PROP_STRING: case JS_DEF_OBJECT: if (JS_DefineAutoInitProperty(ctx, obj, atom, JS_AUTOINIT_ID_PROP, (void *)e, prop_flags) < 0) return -1; return 0; default: abort(); } if (JS_DefinePropertyValue(ctx, obj, atom, val, prop_flags) < 0) return -1; return 0; } int JS_SetPropertyFunctionList(JSContext *ctx, JSValueConst obj, const JSCFunctionListEntry *tab, int len) { int i, ret; for (i = 0; i < len; i++) { const JSCFunctionListEntry *e = &tab[i]; JSAtom atom = find_atom(ctx, e->name); if (atom == JS_ATOM_NULL) return -1; ret = JS_InstantiateFunctionListItem(ctx, obj, atom, e); JS_FreeAtom(ctx, atom); if (ret) return -1; } return 0; } int JS_AddModuleExportList(JSContext *ctx, JSModuleDef *m, const JSCFunctionListEntry *tab, int len) { int i; for(i = 0; i < len; i++) { if (JS_AddModuleExport(ctx, m, tab[i].name)) return -1; } return 0; } int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m, const JSCFunctionListEntry *tab, int len) { int i; JSValue val; for(i = 0; i < len; i++) { const JSCFunctionListEntry *e = &tab[i]; switch(e->def_type) { case JS_DEF_CFUNC: val = JS_NewCFunction2(ctx, e->u.func.cfunc.generic, e->name, e->u.func.length, e->u.func.cproto, e->magic); break; case JS_DEF_PROP_STRING: val = JS_NewString(ctx, e->u.str); break; case JS_DEF_PROP_INT32: val = JS_NewInt32(ctx, e->u.i32); break; case JS_DEF_PROP_INT64: val = JS_NewInt64(ctx, e->u.i64); break; case JS_DEF_PROP_DOUBLE: val = __JS_NewFloat64(ctx, e->u.f64); break; case JS_DEF_OBJECT: val = JS_NewObjectProtoList(ctx, ctx->class_proto[JS_CLASS_OBJECT], e->u.prop_list.tab, e->u.prop_list.len); break; default: abort(); } if (JS_SetModuleExport(ctx, m, e->name, val)) return -1; } return 0; } /* Note: 'func_obj' is not necessarily a constructor */ static int JS_SetConstructor2(JSContext *ctx, JSValueConst func_obj, JSValueConst proto, int proto_flags, int ctor_flags) { if (JS_DefinePropertyValue(ctx, func_obj, JS_ATOM_prototype, JS_DupValue(ctx, proto), proto_flags) < 0) return -1; if (JS_DefinePropertyValue(ctx, proto, JS_ATOM_constructor, JS_DupValue(ctx, func_obj), ctor_flags) < 0) return -1; set_cycle_flag(ctx, func_obj); set_cycle_flag(ctx, proto); return 0; } /* return 0 if OK, -1 if exception */ int JS_SetConstructor(JSContext *ctx, JSValueConst func_obj, JSValueConst proto) { return JS_SetConstructor2(ctx, func_obj, proto, 0, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); } #define JS_NEW_CTOR_NO_GLOBAL (1 << 0) /* don't create a global binding */ #define JS_NEW_CTOR_PROTO_CLASS (1 << 1) /* the prototype class is 'class_id' instead of JS_CLASS_OBJECT */ #define JS_NEW_CTOR_PROTO_EXIST (1 << 2) /* the prototype is already defined */ #define JS_NEW_CTOR_READONLY (1 << 3) /* read-only constructor field */ /* Return the constructor and. Define it as a global variable unless JS_NEW_CTOR_NO_GLOBAL is set. The new class inherit from parent_ctor if it is not JS_UNDEFINED. if class_id is != -1, class_proto[class_id] is set. */ static JSValue JS_NewCConstructor(JSContext *ctx, int class_id, const char *name, JSCFunction *func, int length, JSCFunctionEnum cproto, int magic, JSValueConst parent_ctor, const JSCFunctionListEntry *ctor_fields, int n_ctor_fields, const JSCFunctionListEntry *proto_fields, int n_proto_fields, int flags) { JSValue ctor = JS_UNDEFINED, proto, parent_proto; int proto_class_id, proto_flags, ctor_flags; proto_flags = 0; if (flags & JS_NEW_CTOR_READONLY) { ctor_flags = JS_PROP_CONFIGURABLE; } else { ctor_flags = JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE; } if (JS_IsUndefined(parent_ctor)) { parent_proto = JS_DupValue(ctx, ctx->class_proto[JS_CLASS_OBJECT]); parent_ctor = ctx->function_proto; } else { parent_proto = JS_GetProperty(ctx, parent_ctor, JS_ATOM_prototype); if (JS_IsException(parent_proto)) return JS_EXCEPTION; } if (flags & JS_NEW_CTOR_PROTO_EXIST) { proto = JS_DupValue(ctx, ctx->class_proto[class_id]); } else { if (flags & JS_NEW_CTOR_PROTO_CLASS) proto_class_id = class_id; else proto_class_id = JS_CLASS_OBJECT; /* one additional field: constructor */ proto = JS_NewObjectProtoClassAlloc(ctx, parent_proto, proto_class_id, n_proto_fields + 1); if (JS_IsException(proto)) goto fail; if (class_id >= 0) ctx->class_proto[class_id] = JS_DupValue(ctx, proto); } if (JS_SetPropertyFunctionList(ctx, proto, proto_fields, n_proto_fields)) goto fail; /* additional fields: name, length, prototype */ ctor = JS_NewCFunction3(ctx, func, name, length, cproto, magic, parent_ctor, n_ctor_fields + 3); if (JS_IsException(ctor)) goto fail; if (JS_SetPropertyFunctionList(ctx, ctor, ctor_fields, n_ctor_fields)) goto fail; if (!(flags & JS_NEW_CTOR_NO_GLOBAL)) { if (JS_DefinePropertyValueStr(ctx, ctx->global_obj, name, JS_DupValue(ctx, ctor), JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE) < 0) goto fail; } JS_SetConstructor2(ctx, ctor, proto, proto_flags, ctor_flags); JS_FreeValue(ctx, proto); JS_FreeValue(ctx, parent_proto); return ctor; fail: JS_FreeValue(ctx, proto); JS_FreeValue(ctx, parent_proto); JS_FreeValue(ctx, ctor); return JS_EXCEPTION; } static JSValue js_global_eval(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return JS_EvalObject(ctx, ctx->global_obj, argv[0], JS_EVAL_TYPE_INDIRECT, -1); } static JSValue js_global_isNaN(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { double d; if (unlikely(JS_ToFloat64(ctx, &d, argv[0]))) return JS_EXCEPTION; return JS_NewBool(ctx, isnan(d)); } static JSValue js_global_isFinite(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { double d; if (unlikely(JS_ToFloat64(ctx, &d, argv[0]))) return JS_EXCEPTION; return JS_NewBool(ctx, isfinite(d)); } /* Object class */ static JSValue JS_ToObject(JSContext *ctx, JSValueConst val) { int tag = JS_VALUE_GET_NORM_TAG(val); JSValue obj; switch(tag) { default: case JS_TAG_NULL: case JS_TAG_UNDEFINED: return JS_ThrowTypeError(ctx, "cannot convert to object"); case JS_TAG_OBJECT: case JS_TAG_EXCEPTION: return JS_DupValue(ctx, val); case JS_TAG_SHORT_BIG_INT: case JS_TAG_BIG_INT: obj = JS_NewObjectClass(ctx, JS_CLASS_BIG_INT); goto set_value; case JS_TAG_INT: case JS_TAG_FLOAT64: obj = JS_NewObjectClass(ctx, JS_CLASS_NUMBER); goto set_value; case JS_TAG_STRING: case JS_TAG_STRING_ROPE: /* XXX: should call the string constructor */ { JSValue str; str = JS_ToString(ctx, val); /* ensure that we never store a rope */ if (JS_IsException(str)) return JS_EXCEPTION; obj = JS_NewObjectClass(ctx, JS_CLASS_STRING); if (!JS_IsException(obj)) { JS_DefinePropertyValue(ctx, obj, JS_ATOM_length, JS_NewInt32(ctx, JS_VALUE_GET_STRING(str)->len), 0); JS_SetObjectData(ctx, obj, JS_DupValue(ctx, str)); } JS_FreeValue(ctx, str); return obj; } case JS_TAG_BOOL: obj = JS_NewObjectClass(ctx, JS_CLASS_BOOLEAN); goto set_value; case JS_TAG_SYMBOL: obj = JS_NewObjectClass(ctx, JS_CLASS_SYMBOL); set_value: if (!JS_IsException(obj)) JS_SetObjectData(ctx, obj, JS_DupValue(ctx, val)); return obj; } } static JSValue JS_ToObjectFree(JSContext *ctx, JSValue val) { JSValue obj = JS_ToObject(ctx, val); JS_FreeValue(ctx, val); return obj; } static int js_obj_to_desc(JSContext *ctx, JSPropertyDescriptor *d, JSValueConst desc) { JSValue val, getter, setter; int flags; if (!JS_IsObject(desc)) { JS_ThrowTypeErrorNotAnObject(ctx); return -1; } flags = 0; val = JS_UNDEFINED; getter = JS_UNDEFINED; setter = JS_UNDEFINED; if (JS_HasProperty(ctx, desc, JS_ATOM_enumerable)) { JSValue prop = JS_GetProperty(ctx, desc, JS_ATOM_enumerable); if (JS_IsException(prop)) goto fail; flags |= JS_PROP_HAS_ENUMERABLE; if (JS_ToBoolFree(ctx, prop)) flags |= JS_PROP_ENUMERABLE; } if (JS_HasProperty(ctx, desc, JS_ATOM_configurable)) { JSValue prop = JS_GetProperty(ctx, desc, JS_ATOM_configurable); if (JS_IsException(prop)) goto fail; flags |= JS_PROP_HAS_CONFIGURABLE; if (JS_ToBoolFree(ctx, prop)) flags |= JS_PROP_CONFIGURABLE; } if (JS_HasProperty(ctx, desc, JS_ATOM_value)) { flags |= JS_PROP_HAS_VALUE; val = JS_GetProperty(ctx, desc, JS_ATOM_value); if (JS_IsException(val)) goto fail; } if (JS_HasProperty(ctx, desc, JS_ATOM_writable)) { JSValue prop = JS_GetProperty(ctx, desc, JS_ATOM_writable); if (JS_IsException(prop)) goto fail; flags |= JS_PROP_HAS_WRITABLE; if (JS_ToBoolFree(ctx, prop)) flags |= JS_PROP_WRITABLE; } if (JS_HasProperty(ctx, desc, JS_ATOM_get)) { flags |= JS_PROP_HAS_GET; getter = JS_GetProperty(ctx, desc, JS_ATOM_get); if (JS_IsException(getter) || !(JS_IsUndefined(getter) || JS_IsFunction(ctx, getter))) { JS_ThrowTypeError(ctx, "invalid getter"); goto fail; } } if (JS_HasProperty(ctx, desc, JS_ATOM_set)) { flags |= JS_PROP_HAS_SET; setter = JS_GetProperty(ctx, desc, JS_ATOM_set); if (JS_IsException(setter) || !(JS_IsUndefined(setter) || JS_IsFunction(ctx, setter))) { JS_ThrowTypeError(ctx, "invalid setter"); goto fail; } } if ((flags & (JS_PROP_HAS_SET | JS_PROP_HAS_GET)) && (flags & (JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE))) { JS_ThrowTypeError(ctx, "cannot have setter/getter and value or writable"); goto fail; } d->flags = flags; d->value = val; d->getter = getter; d->setter = setter; return 0; fail: JS_FreeValue(ctx, val); JS_FreeValue(ctx, getter); JS_FreeValue(ctx, setter); return -1; } static __exception int JS_DefinePropertyDesc(JSContext *ctx, JSValueConst obj, JSAtom prop, JSValueConst desc, int flags) { JSPropertyDescriptor d; int ret; if (js_obj_to_desc(ctx, &d, desc) < 0) return -1; ret = JS_DefineProperty(ctx, obj, prop, d.value, d.getter, d.setter, d.flags | flags); js_free_desc(ctx, &d); return ret; } static __exception int JS_ObjectDefineProperties(JSContext *ctx, JSValueConst obj, JSValueConst properties) { JSValue props, desc; JSObject *p; JSPropertyEnum *atoms; uint32_t len, i; int ret = -1; if (!JS_IsObject(obj)) { JS_ThrowTypeErrorNotAnObject(ctx); return -1; } desc = JS_UNDEFINED; props = JS_ToObject(ctx, properties); if (JS_IsException(props)) return -1; p = JS_VALUE_GET_OBJ(props); /* XXX: not done in the same order as the spec */ if (JS_GetOwnPropertyNamesInternal(ctx, &atoms, &len, p, JS_GPN_ENUM_ONLY | JS_GPN_STRING_MASK | JS_GPN_SYMBOL_MASK) < 0) goto exception; for(i = 0; i < len; i++) { JS_FreeValue(ctx, desc); desc = JS_GetProperty(ctx, props, atoms[i].atom); if (JS_IsException(desc)) goto exception; if (JS_DefinePropertyDesc(ctx, obj, atoms[i].atom, desc, JS_PROP_THROW) < 0) goto exception; } ret = 0; exception: JS_FreePropertyEnum(ctx, atoms, len); JS_FreeValue(ctx, props); JS_FreeValue(ctx, desc); return ret; } static JSValue js_object_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { JSValue ret; if (!JS_IsUndefined(new_target) && JS_VALUE_GET_OBJ(new_target) != JS_VALUE_GET_OBJ(JS_GetActiveFunction(ctx))) { ret = js_create_from_ctor(ctx, new_target, JS_CLASS_OBJECT); } else { int tag = JS_VALUE_GET_NORM_TAG(argv[0]); switch(tag) { case JS_TAG_NULL: case JS_TAG_UNDEFINED: ret = JS_NewObject(ctx); break; default: ret = JS_ToObject(ctx, argv[0]); break; } } return ret; } static JSValue js_object_create(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValueConst proto, props; JSValue obj; proto = argv[0]; if (!JS_IsObject(proto) && !JS_IsNull(proto)) return JS_ThrowTypeError(ctx, "not a prototype"); obj = JS_NewObjectProto(ctx, proto); if (JS_IsException(obj)) return JS_EXCEPTION; props = argv[1]; if (!JS_IsUndefined(props)) { if (JS_ObjectDefineProperties(ctx, obj, props)) { JS_FreeValue(ctx, obj); return JS_EXCEPTION; } } return obj; } static JSValue js_object_getPrototypeOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSValueConst val; val = argv[0]; if (JS_VALUE_GET_TAG(val) != JS_TAG_OBJECT) { /* ES6 feature non compatible with ES5.1: primitive types are accepted */ if (magic || JS_VALUE_GET_TAG(val) == JS_TAG_NULL || JS_VALUE_GET_TAG(val) == JS_TAG_UNDEFINED) return JS_ThrowTypeErrorNotAnObject(ctx); } return JS_GetPrototype(ctx, val); } static JSValue js_object_setPrototypeOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValueConst obj; obj = argv[0]; if (JS_SetPrototypeInternal(ctx, obj, argv[1], TRUE) < 0) return JS_EXCEPTION; return JS_DupValue(ctx, obj); } /* magic = 1 if called as Reflect.defineProperty */ static JSValue js_object_defineProperty(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSValueConst obj, prop, desc; int ret, flags; JSAtom atom; obj = argv[0]; prop = argv[1]; desc = argv[2]; if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) return JS_ThrowTypeErrorNotAnObject(ctx); atom = JS_ValueToAtom(ctx, prop); if (unlikely(atom == JS_ATOM_NULL)) return JS_EXCEPTION; flags = 0; if (!magic) flags |= JS_PROP_THROW; ret = JS_DefinePropertyDesc(ctx, obj, atom, desc, flags); JS_FreeAtom(ctx, atom); if (ret < 0) { return JS_EXCEPTION; } else if (magic) { return JS_NewBool(ctx, ret); } else { return JS_DupValue(ctx, obj); } } static JSValue js_object_defineProperties(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // defineProperties(obj, properties) JSValueConst obj = argv[0]; if (JS_ObjectDefineProperties(ctx, obj, argv[1])) return JS_EXCEPTION; else return JS_DupValue(ctx, obj); } /* magic = 1 if called as __defineSetter__ */ static JSValue js_object___defineGetter__(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSValue obj; JSValueConst prop, value, get, set; int ret, flags; JSAtom atom; prop = argv[0]; value = argv[1]; obj = JS_ToObject(ctx, this_val); if (JS_IsException(obj)) return JS_EXCEPTION; if (check_function(ctx, value)) { JS_FreeValue(ctx, obj); return JS_EXCEPTION; } atom = JS_ValueToAtom(ctx, prop); if (unlikely(atom == JS_ATOM_NULL)) { JS_FreeValue(ctx, obj); return JS_EXCEPTION; } flags = JS_PROP_THROW | JS_PROP_HAS_ENUMERABLE | JS_PROP_ENUMERABLE | JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE; if (magic) { get = JS_UNDEFINED; set = value; flags |= JS_PROP_HAS_SET; } else { get = value; set = JS_UNDEFINED; flags |= JS_PROP_HAS_GET; } ret = JS_DefineProperty(ctx, obj, atom, JS_UNDEFINED, get, set, flags); JS_FreeValue(ctx, obj); JS_FreeAtom(ctx, atom); if (ret < 0) { return JS_EXCEPTION; } else { return JS_UNDEFINED; } } static JSValue js_object_getOwnPropertyDescriptor(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSValueConst prop; JSAtom atom; JSValue ret, obj; JSPropertyDescriptor desc; int res, flags; if (magic) { /* Reflect.getOwnPropertyDescriptor case */ if (JS_VALUE_GET_TAG(argv[0]) != JS_TAG_OBJECT) return JS_ThrowTypeErrorNotAnObject(ctx); obj = JS_DupValue(ctx, argv[0]); } else { obj = JS_ToObject(ctx, argv[0]); if (JS_IsException(obj)) return obj; } prop = argv[1]; atom = JS_ValueToAtom(ctx, prop); if (unlikely(atom == JS_ATOM_NULL)) goto exception; ret = JS_UNDEFINED; if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { res = JS_GetOwnPropertyInternal(ctx, &desc, JS_VALUE_GET_OBJ(obj), atom); if (res < 0) goto exception; if (res) { ret = JS_NewObject(ctx); if (JS_IsException(ret)) goto exception1; flags = JS_PROP_C_W_E | JS_PROP_THROW; if (desc.flags & JS_PROP_GETSET) { if (JS_DefinePropertyValue(ctx, ret, JS_ATOM_get, JS_DupValue(ctx, desc.getter), flags) < 0 || JS_DefinePropertyValue(ctx, ret, JS_ATOM_set, JS_DupValue(ctx, desc.setter), flags) < 0) goto exception1; } else { if (JS_DefinePropertyValue(ctx, ret, JS_ATOM_value, JS_DupValue(ctx, desc.value), flags) < 0 || JS_DefinePropertyValue(ctx, ret, JS_ATOM_writable, JS_NewBool(ctx, desc.flags & JS_PROP_WRITABLE), flags) < 0) goto exception1; } if (JS_DefinePropertyValue(ctx, ret, JS_ATOM_enumerable, JS_NewBool(ctx, desc.flags & JS_PROP_ENUMERABLE), flags) < 0 || JS_DefinePropertyValue(ctx, ret, JS_ATOM_configurable, JS_NewBool(ctx, desc.flags & JS_PROP_CONFIGURABLE), flags) < 0) goto exception1; js_free_desc(ctx, &desc); } } JS_FreeAtom(ctx, atom); JS_FreeValue(ctx, obj); return ret; exception1: js_free_desc(ctx, &desc); JS_FreeValue(ctx, ret); exception: JS_FreeAtom(ctx, atom); JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_object_getOwnPropertyDescriptors(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { //getOwnPropertyDescriptors(obj) JSValue obj, r; JSObject *p; JSPropertyEnum *props; uint32_t len, i; r = JS_UNDEFINED; obj = JS_ToObject(ctx, argv[0]); if (JS_IsException(obj)) return JS_EXCEPTION; p = JS_VALUE_GET_OBJ(obj); if (JS_GetOwnPropertyNamesInternal(ctx, &props, &len, p, JS_GPN_STRING_MASK | JS_GPN_SYMBOL_MASK)) goto exception; r = JS_NewObject(ctx); if (JS_IsException(r)) goto exception; for(i = 0; i < len; i++) { JSValue atomValue, desc; JSValueConst args[2]; atomValue = JS_AtomToValue(ctx, props[i].atom); if (JS_IsException(atomValue)) goto exception; args[0] = obj; args[1] = atomValue; desc = js_object_getOwnPropertyDescriptor(ctx, JS_UNDEFINED, 2, args, 0); JS_FreeValue(ctx, atomValue); if (JS_IsException(desc)) goto exception; if (!JS_IsUndefined(desc)) { if (JS_DefinePropertyValue(ctx, r, props[i].atom, desc, JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception; } } JS_FreePropertyEnum(ctx, props, len); JS_FreeValue(ctx, obj); return r; exception: JS_FreePropertyEnum(ctx, props, len); JS_FreeValue(ctx, obj); JS_FreeValue(ctx, r); return JS_EXCEPTION; } static JSValue JS_GetOwnPropertyNames2(JSContext *ctx, JSValueConst obj1, int flags, int kind) { JSValue obj, r, val, key, value; JSObject *p; JSPropertyEnum *atoms; uint32_t len, i, j; r = JS_UNDEFINED; val = JS_UNDEFINED; obj = JS_ToObject(ctx, obj1); if (JS_IsException(obj)) return JS_EXCEPTION; p = JS_VALUE_GET_OBJ(obj); if (JS_GetOwnPropertyNamesInternal(ctx, &atoms, &len, p, flags & ~JS_GPN_ENUM_ONLY)) goto exception; r = JS_NewArray(ctx); if (JS_IsException(r)) goto exception; for(j = i = 0; i < len; i++) { JSAtom atom = atoms[i].atom; if (flags & JS_GPN_ENUM_ONLY) { JSPropertyDescriptor desc; int res; /* Check if property is still enumerable */ res = JS_GetOwnPropertyInternal(ctx, &desc, p, atom); if (res < 0) goto exception; if (!res) continue; js_free_desc(ctx, &desc); if (!(desc.flags & JS_PROP_ENUMERABLE)) continue; } switch(kind) { default: case JS_ITERATOR_KIND_KEY: val = JS_AtomToValue(ctx, atom); if (JS_IsException(val)) goto exception; break; case JS_ITERATOR_KIND_VALUE: val = JS_GetProperty(ctx, obj, atom); if (JS_IsException(val)) goto exception; break; case JS_ITERATOR_KIND_KEY_AND_VALUE: val = JS_NewArray(ctx); if (JS_IsException(val)) goto exception; key = JS_AtomToValue(ctx, atom); if (JS_IsException(key)) goto exception1; if (JS_CreateDataPropertyUint32(ctx, val, 0, key, JS_PROP_THROW) < 0) goto exception1; value = JS_GetProperty(ctx, obj, atom); if (JS_IsException(value)) goto exception1; if (JS_CreateDataPropertyUint32(ctx, val, 1, value, JS_PROP_THROW) < 0) goto exception1; break; } if (JS_CreateDataPropertyUint32(ctx, r, j++, val, 0) < 0) goto exception; } goto done; exception1: JS_FreeValue(ctx, val); exception: JS_FreeValue(ctx, r); r = JS_EXCEPTION; done: JS_FreePropertyEnum(ctx, atoms, len); JS_FreeValue(ctx, obj); return r; } static JSValue js_object_getOwnPropertyNames(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return JS_GetOwnPropertyNames2(ctx, argv[0], JS_GPN_STRING_MASK, JS_ITERATOR_KIND_KEY); } static JSValue js_object_getOwnPropertySymbols(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return JS_GetOwnPropertyNames2(ctx, argv[0], JS_GPN_SYMBOL_MASK, JS_ITERATOR_KIND_KEY); } static JSValue js_object_keys(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int kind) { return JS_GetOwnPropertyNames2(ctx, argv[0], JS_GPN_ENUM_ONLY | JS_GPN_STRING_MASK, kind); } static JSValue js_object_isExtensible(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int reflect) { JSValueConst obj; int ret; obj = argv[0]; if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) { if (reflect) return JS_ThrowTypeErrorNotAnObject(ctx); else return JS_FALSE; } ret = JS_IsExtensible(ctx, obj); if (ret < 0) return JS_EXCEPTION; else return JS_NewBool(ctx, ret); } static JSValue js_object_preventExtensions(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int reflect) { JSValueConst obj; int ret; obj = argv[0]; if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) { if (reflect) return JS_ThrowTypeErrorNotAnObject(ctx); else return JS_DupValue(ctx, obj); } ret = JS_PreventExtensions(ctx, obj); if (ret < 0) return JS_EXCEPTION; if (reflect) { return JS_NewBool(ctx, ret); } else { if (!ret) return JS_ThrowTypeError(ctx, "proxy preventExtensions handler returned false"); return JS_DupValue(ctx, obj); } } static JSValue js_object_hasOwnProperty(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj; JSAtom atom; JSObject *p; BOOL ret; atom = JS_ValueToAtom(ctx, argv[0]); /* must be done first */ if (unlikely(atom == JS_ATOM_NULL)) return JS_EXCEPTION; obj = JS_ToObject(ctx, this_val); if (JS_IsException(obj)) { JS_FreeAtom(ctx, atom); return obj; } p = JS_VALUE_GET_OBJ(obj); ret = JS_GetOwnPropertyInternal(ctx, NULL, p, atom); JS_FreeAtom(ctx, atom); JS_FreeValue(ctx, obj); if (ret < 0) return JS_EXCEPTION; else return JS_NewBool(ctx, ret); } static JSValue js_object_hasOwn(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj; JSAtom atom; JSObject *p; BOOL ret; obj = JS_ToObject(ctx, argv[0]); if (JS_IsException(obj)) return obj; atom = JS_ValueToAtom(ctx, argv[1]); if (unlikely(atom == JS_ATOM_NULL)) { JS_FreeValue(ctx, obj); return JS_EXCEPTION; } p = JS_VALUE_GET_OBJ(obj); ret = JS_GetOwnPropertyInternal(ctx, NULL, p, atom); JS_FreeAtom(ctx, atom); JS_FreeValue(ctx, obj); if (ret < 0) return JS_EXCEPTION; else return JS_NewBool(ctx, ret); } static JSValue js_object_valueOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return JS_ToObject(ctx, this_val); } static JSValue js_object_toString(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj, tag; int is_array; JSAtom atom; JSObject *p; if (JS_IsNull(this_val)) { tag = js_new_string8(ctx, "Null"); } else if (JS_IsUndefined(this_val)) { tag = js_new_string8(ctx, "Undefined"); } else { obj = JS_ToObject(ctx, this_val); if (JS_IsException(obj)) return obj; is_array = JS_IsArray(ctx, obj); if (is_array < 0) { JS_FreeValue(ctx, obj); return JS_EXCEPTION; } if (is_array) { atom = JS_ATOM_Array; } else if (JS_IsFunction(ctx, obj)) { atom = JS_ATOM_Function; } else { p = JS_VALUE_GET_OBJ(obj); switch(p->class_id) { case JS_CLASS_STRING: case JS_CLASS_ARGUMENTS: case JS_CLASS_MAPPED_ARGUMENTS: case JS_CLASS_ERROR: case JS_CLASS_BOOLEAN: case JS_CLASS_NUMBER: case JS_CLASS_DATE: case JS_CLASS_REGEXP: atom = ctx->rt->class_array[p->class_id].class_name; break; default: atom = JS_ATOM_Object; break; } } tag = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_toStringTag); JS_FreeValue(ctx, obj); if (JS_IsException(tag)) return JS_EXCEPTION; if (!JS_IsString(tag)) { JS_FreeValue(ctx, tag); tag = JS_AtomToString(ctx, atom); } } return JS_ConcatString3(ctx, "[object ", tag, "]"); } static JSValue js_object_toLocaleString(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return JS_Invoke(ctx, this_val, JS_ATOM_toString, 0, NULL); } static JSValue js_object_assign(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // Object.assign(obj, source1) JSValue obj, s; int i; s = JS_UNDEFINED; obj = JS_ToObject(ctx, argv[0]); if (JS_IsException(obj)) goto exception; for (i = 1; i < argc; i++) { if (!JS_IsNull(argv[i]) && !JS_IsUndefined(argv[i])) { s = JS_ToObject(ctx, argv[i]); if (JS_IsException(s)) goto exception; if (JS_CopyDataProperties(ctx, obj, s, JS_UNDEFINED, TRUE)) goto exception; JS_FreeValue(ctx, s); } } return obj; exception: JS_FreeValue(ctx, obj); JS_FreeValue(ctx, s); return JS_EXCEPTION; } static JSValue js_object_seal(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int freeze_flag) { JSValueConst obj = argv[0]; JSObject *p; JSPropertyEnum *props; uint32_t len, i; int flags, desc_flags, res; if (!JS_IsObject(obj)) return JS_DupValue(ctx, obj); res = JS_PreventExtensions(ctx, obj); if (res < 0) return JS_EXCEPTION; if (!res) { return JS_ThrowTypeError(ctx, "proxy preventExtensions handler returned false"); } p = JS_VALUE_GET_OBJ(obj); flags = JS_GPN_STRING_MASK | JS_GPN_SYMBOL_MASK; if (JS_GetOwnPropertyNamesInternal(ctx, &props, &len, p, flags)) return JS_EXCEPTION; for(i = 0; i < len; i++) { JSPropertyDescriptor desc; JSAtom prop = props[i].atom; desc_flags = JS_PROP_THROW | JS_PROP_HAS_CONFIGURABLE; if (freeze_flag) { res = JS_GetOwnPropertyInternal(ctx, &desc, p, prop); if (res < 0) goto exception; if (res) { if (desc.flags & JS_PROP_WRITABLE) desc_flags |= JS_PROP_HAS_WRITABLE; js_free_desc(ctx, &desc); } } if (JS_DefineProperty(ctx, obj, prop, JS_UNDEFINED, JS_UNDEFINED, JS_UNDEFINED, desc_flags) < 0) goto exception; } JS_FreePropertyEnum(ctx, props, len); return JS_DupValue(ctx, obj); exception: JS_FreePropertyEnum(ctx, props, len); return JS_EXCEPTION; } static JSValue js_object_isSealed(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int is_frozen) { JSValueConst obj = argv[0]; JSObject *p; JSPropertyEnum *props; uint32_t len, i; int flags, res; if (!JS_IsObject(obj)) return JS_TRUE; p = JS_VALUE_GET_OBJ(obj); flags = JS_GPN_STRING_MASK | JS_GPN_SYMBOL_MASK; if (JS_GetOwnPropertyNamesInternal(ctx, &props, &len, p, flags)) return JS_EXCEPTION; for(i = 0; i < len; i++) { JSPropertyDescriptor desc; JSAtom prop = props[i].atom; res = JS_GetOwnPropertyInternal(ctx, &desc, p, prop); if (res < 0) goto exception; if (res) { js_free_desc(ctx, &desc); if ((desc.flags & JS_PROP_CONFIGURABLE) || (is_frozen && (desc.flags & JS_PROP_WRITABLE))) { res = FALSE; goto done; } } } res = JS_IsExtensible(ctx, obj); if (res < 0) return JS_EXCEPTION; res ^= 1; done: JS_FreePropertyEnum(ctx, props, len); return JS_NewBool(ctx, res); exception: JS_FreePropertyEnum(ctx, props, len); return JS_EXCEPTION; } static JSValue js_object_fromEntries(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj, iter, next_method = JS_UNDEFINED; JSValueConst iterable; BOOL done; /* RequireObjectCoercible() not necessary because it is tested in JS_GetIterator() by JS_GetProperty() */ iterable = argv[0]; obj = JS_NewObject(ctx); if (JS_IsException(obj)) return obj; iter = JS_GetIterator(ctx, iterable, FALSE); if (JS_IsException(iter)) goto fail; next_method = JS_GetProperty(ctx, iter, JS_ATOM_next); if (JS_IsException(next_method)) goto fail; for(;;) { JSValue key, value, item; item = JS_IteratorNext(ctx, iter, next_method, 0, NULL, &done); if (JS_IsException(item)) goto fail; if (done) break; key = JS_UNDEFINED; value = JS_UNDEFINED; if (!JS_IsObject(item)) { JS_ThrowTypeErrorNotAnObject(ctx); goto fail1; } key = JS_GetPropertyUint32(ctx, item, 0); if (JS_IsException(key)) goto fail1; value = JS_GetPropertyUint32(ctx, item, 1); if (JS_IsException(value)) { JS_FreeValue(ctx, key); goto fail1; } if (JS_DefinePropertyValueValue(ctx, obj, key, value, JS_PROP_C_W_E | JS_PROP_THROW) < 0) { fail1: JS_FreeValue(ctx, item); goto fail; } JS_FreeValue(ctx, item); } JS_FreeValue(ctx, next_method); JS_FreeValue(ctx, iter); return obj; fail: if (JS_IsObject(iter)) { /* close the iterator object, preserving pending exception */ JS_IteratorClose(ctx, iter, TRUE); } JS_FreeValue(ctx, next_method); JS_FreeValue(ctx, iter); JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_object_is(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return JS_NewBool(ctx, js_same_value(ctx, argv[0], argv[1])); } static JSValue JS_SpeciesConstructor(JSContext *ctx, JSValueConst obj, JSValueConst defaultConstructor) { JSValue ctor, species; if (!JS_IsObject(obj)) return JS_ThrowTypeErrorNotAnObject(ctx); ctor = JS_GetProperty(ctx, obj, JS_ATOM_constructor); if (JS_IsException(ctor)) return ctor; if (JS_IsUndefined(ctor)) return JS_DupValue(ctx, defaultConstructor); if (!JS_IsObject(ctor)) { JS_FreeValue(ctx, ctor); return JS_ThrowTypeErrorNotAnObject(ctx); } species = JS_GetProperty(ctx, ctor, JS_ATOM_Symbol_species); JS_FreeValue(ctx, ctor); if (JS_IsException(species)) return species; if (JS_IsUndefined(species) || JS_IsNull(species)) return JS_DupValue(ctx, defaultConstructor); if (!JS_IsConstructor(ctx, species)) { JS_ThrowTypeErrorNotAConstructor(ctx, species); JS_FreeValue(ctx, species); return JS_EXCEPTION; } return species; } static JSValue js_object_get___proto__(JSContext *ctx, JSValueConst this_val) { JSValue val, ret; val = JS_ToObject(ctx, this_val); if (JS_IsException(val)) return val; ret = JS_GetPrototype(ctx, val); JS_FreeValue(ctx, val); return ret; } static JSValue js_object_set___proto__(JSContext *ctx, JSValueConst this_val, JSValueConst proto) { if (JS_IsUndefined(this_val) || JS_IsNull(this_val)) return JS_ThrowTypeErrorNotAnObject(ctx); if (!JS_IsObject(proto) && !JS_IsNull(proto)) return JS_UNDEFINED; if (JS_SetPrototypeInternal(ctx, this_val, proto, TRUE) < 0) return JS_EXCEPTION; else return JS_UNDEFINED; } static JSValue js_object_isPrototypeOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj, v1; JSValueConst v; int res; v = argv[0]; if (!JS_IsObject(v)) return JS_FALSE; obj = JS_ToObject(ctx, this_val); if (JS_IsException(obj)) return JS_EXCEPTION; v1 = JS_DupValue(ctx, v); for(;;) { v1 = JS_GetPrototypeFree(ctx, v1); if (JS_IsException(v1)) goto exception; if (JS_IsNull(v1)) { res = FALSE; break; } if (JS_VALUE_GET_OBJ(obj) == JS_VALUE_GET_OBJ(v1)) { res = TRUE; break; } /* avoid infinite loop (possible with proxies) */ if (js_poll_interrupts(ctx)) goto exception; } JS_FreeValue(ctx, v1); JS_FreeValue(ctx, obj); return JS_NewBool(ctx, res); exception: JS_FreeValue(ctx, v1); JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_object_propertyIsEnumerable(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj = JS_UNDEFINED, res = JS_EXCEPTION; JSAtom prop; JSPropertyDescriptor desc; int has_prop; prop = JS_ValueToAtom(ctx, argv[0]); if (unlikely(prop == JS_ATOM_NULL)) goto exception; obj = JS_ToObject(ctx, this_val); if (JS_IsException(obj)) goto exception; has_prop = JS_GetOwnPropertyInternal(ctx, &desc, JS_VALUE_GET_OBJ(obj), prop); if (has_prop < 0) goto exception; if (has_prop) { res = JS_NewBool(ctx, desc.flags & JS_PROP_ENUMERABLE); js_free_desc(ctx, &desc); } else { res = JS_FALSE; } exception: JS_FreeAtom(ctx, prop); JS_FreeValue(ctx, obj); return res; } static JSValue js_object___lookupGetter__(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int setter) { JSValue obj, res = JS_EXCEPTION; JSAtom prop = JS_ATOM_NULL; JSPropertyDescriptor desc; int has_prop; obj = JS_ToObject(ctx, this_val); if (JS_IsException(obj)) goto exception; prop = JS_ValueToAtom(ctx, argv[0]); if (unlikely(prop == JS_ATOM_NULL)) goto exception; for (;;) { has_prop = JS_GetOwnPropertyInternal(ctx, &desc, JS_VALUE_GET_OBJ(obj), prop); if (has_prop < 0) goto exception; if (has_prop) { if (desc.flags & JS_PROP_GETSET) res = JS_DupValue(ctx, setter ? desc.setter : desc.getter); else res = JS_UNDEFINED; js_free_desc(ctx, &desc); break; } obj = JS_GetPrototypeFree(ctx, obj); if (JS_IsException(obj)) goto exception; if (JS_IsNull(obj)) { res = JS_UNDEFINED; break; } /* avoid infinite loop (possible with proxies) */ if (js_poll_interrupts(ctx)) goto exception; } exception: JS_FreeAtom(ctx, prop); JS_FreeValue(ctx, obj); return res; } static const JSCFunctionListEntry js_object_funcs[] = { JS_CFUNC_DEF("create", 2, js_object_create ), JS_CFUNC_MAGIC_DEF("getPrototypeOf", 1, js_object_getPrototypeOf, 0 ), JS_CFUNC_DEF("setPrototypeOf", 2, js_object_setPrototypeOf ), JS_CFUNC_MAGIC_DEF("defineProperty", 3, js_object_defineProperty, 0 ), JS_CFUNC_DEF("defineProperties", 2, js_object_defineProperties ), JS_CFUNC_DEF("getOwnPropertyNames", 1, js_object_getOwnPropertyNames ), JS_CFUNC_DEF("getOwnPropertySymbols", 1, js_object_getOwnPropertySymbols ), JS_CFUNC_MAGIC_DEF("groupBy", 2, js_object_groupBy, 0 ), JS_CFUNC_MAGIC_DEF("keys", 1, js_object_keys, JS_ITERATOR_KIND_KEY ), JS_CFUNC_MAGIC_DEF("values", 1, js_object_keys, JS_ITERATOR_KIND_VALUE ), JS_CFUNC_MAGIC_DEF("entries", 1, js_object_keys, JS_ITERATOR_KIND_KEY_AND_VALUE ), JS_CFUNC_MAGIC_DEF("isExtensible", 1, js_object_isExtensible, 0 ), JS_CFUNC_MAGIC_DEF("preventExtensions", 1, js_object_preventExtensions, 0 ), JS_CFUNC_MAGIC_DEF("getOwnPropertyDescriptor", 2, js_object_getOwnPropertyDescriptor, 0 ), JS_CFUNC_DEF("getOwnPropertyDescriptors", 1, js_object_getOwnPropertyDescriptors ), JS_CFUNC_DEF("is", 2, js_object_is ), JS_CFUNC_DEF("assign", 2, js_object_assign ), JS_CFUNC_MAGIC_DEF("seal", 1, js_object_seal, 0 ), JS_CFUNC_MAGIC_DEF("freeze", 1, js_object_seal, 1 ), JS_CFUNC_MAGIC_DEF("isSealed", 1, js_object_isSealed, 0 ), JS_CFUNC_MAGIC_DEF("isFrozen", 1, js_object_isSealed, 1 ), JS_CFUNC_DEF("fromEntries", 1, js_object_fromEntries ), JS_CFUNC_DEF("hasOwn", 2, js_object_hasOwn ), }; static const JSCFunctionListEntry js_object_proto_funcs[] = { JS_CFUNC_DEF("toString", 0, js_object_toString ), JS_CFUNC_DEF("toLocaleString", 0, js_object_toLocaleString ), JS_CFUNC_DEF("valueOf", 0, js_object_valueOf ), JS_CFUNC_DEF("hasOwnProperty", 1, js_object_hasOwnProperty ), JS_CFUNC_DEF("isPrototypeOf", 1, js_object_isPrototypeOf ), JS_CFUNC_DEF("propertyIsEnumerable", 1, js_object_propertyIsEnumerable ), JS_CGETSET_DEF("__proto__", js_object_get___proto__, js_object_set___proto__ ), JS_CFUNC_MAGIC_DEF("__defineGetter__", 2, js_object___defineGetter__, 0 ), JS_CFUNC_MAGIC_DEF("__defineSetter__", 2, js_object___defineGetter__, 1 ), JS_CFUNC_MAGIC_DEF("__lookupGetter__", 1, js_object___lookupGetter__, 0 ), JS_CFUNC_MAGIC_DEF("__lookupSetter__", 1, js_object___lookupGetter__, 1 ), }; /* Function class */ static JSValue js_function_proto(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return JS_UNDEFINED; } /* XXX: add a specific eval mode so that Function("}), ({") is rejected */ static JSValue js_function_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv, int magic) { JSFunctionKindEnum func_kind = magic; int i, n, ret; JSValue s, proto, obj = JS_UNDEFINED; StringBuffer b_s, *b = &b_s; string_buffer_init(ctx, b, 0); string_buffer_putc8(b, '('); if (func_kind == JS_FUNC_ASYNC || func_kind == JS_FUNC_ASYNC_GENERATOR) { string_buffer_puts8(b, "async "); } string_buffer_puts8(b, "function"); if (func_kind == JS_FUNC_GENERATOR || func_kind == JS_FUNC_ASYNC_GENERATOR) { string_buffer_putc8(b, '*'); } string_buffer_puts8(b, " anonymous("); n = argc - 1; for(i = 0; i < n; i++) { if (i != 0) { string_buffer_putc8(b, ','); } if (string_buffer_concat_value(b, argv[i])) goto fail; } string_buffer_puts8(b, "\n) {\n"); if (n >= 0) { if (string_buffer_concat_value(b, argv[n])) goto fail; } string_buffer_puts8(b, "\n})"); s = string_buffer_end(b); if (JS_IsException(s)) goto fail1; obj = JS_EvalObject(ctx, ctx->global_obj, s, JS_EVAL_TYPE_INDIRECT, -1); JS_FreeValue(ctx, s); if (JS_IsException(obj)) goto fail1; if (!JS_IsUndefined(new_target)) { /* set the prototype */ proto = JS_GetProperty(ctx, new_target, JS_ATOM_prototype); if (JS_IsException(proto)) goto fail1; if (!JS_IsObject(proto)) { JSContext *realm; JS_FreeValue(ctx, proto); realm = JS_GetFunctionRealm(ctx, new_target); if (!realm) goto fail1; proto = JS_DupValue(ctx, realm->class_proto[func_kind_to_class_id[func_kind]]); } ret = JS_SetPrototypeInternal(ctx, obj, proto, TRUE); JS_FreeValue(ctx, proto); if (ret < 0) goto fail1; } return obj; fail: string_buffer_free(b); fail1: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static __exception int js_get_length32(JSContext *ctx, uint32_t *pres, JSValueConst obj) { JSValue len_val; len_val = JS_GetProperty(ctx, obj, JS_ATOM_length); if (JS_IsException(len_val)) { *pres = 0; return -1; } return JS_ToUint32Free(ctx, pres, len_val); } static __exception int js_get_length64(JSContext *ctx, int64_t *pres, JSValueConst obj) { JSValue len_val; len_val = JS_GetProperty(ctx, obj, JS_ATOM_length); if (JS_IsException(len_val)) { *pres = 0; return -1; } return JS_ToLengthFree(ctx, pres, len_val); } static void free_arg_list(JSContext *ctx, JSValue *tab, uint32_t len) { uint32_t i; for(i = 0; i < len; i++) { JS_FreeValue(ctx, tab[i]); } js_free(ctx, tab); } /* XXX: should use ValueArray */ static JSValue *build_arg_list(JSContext *ctx, uint32_t *plen, JSValueConst array_arg) { uint32_t len, i; int64_t len64; JSValue *tab, ret; JSObject *p; if (JS_VALUE_GET_TAG(array_arg) != JS_TAG_OBJECT) { JS_ThrowTypeError(ctx, "not a object"); return NULL; } if (js_get_length64(ctx, &len64, array_arg)) return NULL; if (len64 > JS_MAX_LOCAL_VARS) { // XXX: check for stack overflow? JS_ThrowRangeError(ctx, "too many arguments in function call (only %d allowed)", JS_MAX_LOCAL_VARS); return NULL; } len = len64; /* avoid allocating 0 bytes */ tab = js_mallocz(ctx, sizeof(tab[0]) * max_uint32(1, len)); if (!tab) return NULL; p = JS_VALUE_GET_OBJ(array_arg); if ((p->class_id == JS_CLASS_ARRAY || p->class_id == JS_CLASS_ARGUMENTS || p->class_id == JS_CLASS_MAPPED_ARGUMENTS) && p->fast_array && len == p->u.array.count) { if (p->class_id == JS_CLASS_MAPPED_ARGUMENTS) { for(i = 0; i < len; i++) { tab[i] = JS_DupValue(ctx, *p->u.array.u.var_refs[i]->pvalue); } } else { for(i = 0; i < len; i++) { tab[i] = JS_DupValue(ctx, p->u.array.u.values[i]); } } } else { for(i = 0; i < len; i++) { ret = JS_GetPropertyUint32(ctx, array_arg, i); if (JS_IsException(ret)) { free_arg_list(ctx, tab, i); return NULL; } tab[i] = ret; } } *plen = len; return tab; } /* magic value: 0 = normal apply, 1 = apply for constructor, 2 = Reflect.apply */ static JSValue js_function_apply(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSValueConst this_arg, array_arg; uint32_t len; JSValue *tab, ret; if (check_function(ctx, this_val)) return JS_EXCEPTION; this_arg = argv[0]; array_arg = argv[1]; if ((JS_VALUE_GET_TAG(array_arg) == JS_TAG_UNDEFINED || JS_VALUE_GET_TAG(array_arg) == JS_TAG_NULL) && magic != 2) { return JS_Call(ctx, this_val, this_arg, 0, NULL); } tab = build_arg_list(ctx, &len, array_arg); if (!tab) return JS_EXCEPTION; if (magic & 1) { ret = JS_CallConstructor2(ctx, this_val, this_arg, len, (JSValueConst *)tab); } else { ret = JS_Call(ctx, this_val, this_arg, len, (JSValueConst *)tab); } free_arg_list(ctx, tab, len); return ret; } static JSValue js_function_call(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { if (argc <= 0) { return JS_Call(ctx, this_val, JS_UNDEFINED, 0, NULL); } else { return JS_Call(ctx, this_val, argv[0], argc - 1, argv + 1); } } static JSValue js_function_bind(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSBoundFunction *bf; JSValue func_obj, name1, len_val; JSObject *p; int arg_count, i, ret; if (check_function(ctx, this_val)) return JS_EXCEPTION; func_obj = JS_NewObjectProtoClass(ctx, ctx->function_proto, JS_CLASS_BOUND_FUNCTION); if (JS_IsException(func_obj)) return JS_EXCEPTION; p = JS_VALUE_GET_OBJ(func_obj); p->is_constructor = JS_IsConstructor(ctx, this_val); arg_count = max_int(0, argc - 1); bf = js_malloc(ctx, sizeof(*bf) + arg_count * sizeof(JSValue)); if (!bf) goto exception; bf->func_obj = JS_DupValue(ctx, this_val); bf->this_val = JS_DupValue(ctx, argv[0]); bf->argc = arg_count; for(i = 0; i < arg_count; i++) { bf->argv[i] = JS_DupValue(ctx, argv[i + 1]); } p->u.bound_function = bf; /* XXX: the spec could be simpler by only using GetOwnProperty */ ret = JS_GetOwnProperty(ctx, NULL, this_val, JS_ATOM_length); if (ret < 0) goto exception; if (!ret) { len_val = JS_NewInt32(ctx, 0); } else { len_val = JS_GetProperty(ctx, this_val, JS_ATOM_length); if (JS_IsException(len_val)) goto exception; if (JS_VALUE_GET_TAG(len_val) == JS_TAG_INT) { /* most common case */ int len1 = JS_VALUE_GET_INT(len_val); if (len1 <= arg_count) len1 = 0; else len1 -= arg_count; len_val = JS_NewInt32(ctx, len1); } else if (JS_VALUE_GET_NORM_TAG(len_val) == JS_TAG_FLOAT64) { double d = JS_VALUE_GET_FLOAT64(len_val); if (isnan(d)) { d = 0.0; } else { d = trunc(d); if (d <= (double)arg_count) d = 0.0; else d -= (double)arg_count; /* also converts -0 to +0 */ } len_val = JS_NewFloat64(ctx, d); } else { JS_FreeValue(ctx, len_val); len_val = JS_NewInt32(ctx, 0); } } JS_DefinePropertyValue(ctx, func_obj, JS_ATOM_length, len_val, JS_PROP_CONFIGURABLE); name1 = JS_GetProperty(ctx, this_val, JS_ATOM_name); if (JS_IsException(name1)) goto exception; if (!JS_IsString(name1)) { JS_FreeValue(ctx, name1); name1 = JS_AtomToString(ctx, JS_ATOM_empty_string); } name1 = JS_ConcatString3(ctx, "bound ", name1, ""); if (JS_IsException(name1)) goto exception; JS_DefinePropertyValue(ctx, func_obj, JS_ATOM_name, name1, JS_PROP_CONFIGURABLE); return func_obj; exception: JS_FreeValue(ctx, func_obj); return JS_EXCEPTION; } static JSValue js_function_toString(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSObject *p; JSFunctionKindEnum func_kind = JS_FUNC_NORMAL; if (check_function(ctx, this_val)) return JS_EXCEPTION; p = JS_VALUE_GET_OBJ(this_val); if (js_class_has_bytecode(p->class_id)) { JSFunctionBytecode *b = p->u.func.function_bytecode; if (b->has_debug && b->debug.source) { return JS_NewStringLen(ctx, b->debug.source, b->debug.source_len); } func_kind = b->func_kind; } { JSValue name; const char *pref, *suff; switch(func_kind) { default: case JS_FUNC_NORMAL: pref = "function "; break; case JS_FUNC_GENERATOR: pref = "function *"; break; case JS_FUNC_ASYNC: pref = "async function "; break; case JS_FUNC_ASYNC_GENERATOR: pref = "async function *"; break; } suff = "() {\n [native code]\n}"; name = JS_GetProperty(ctx, this_val, JS_ATOM_name); if (JS_IsUndefined(name)) name = JS_AtomToString(ctx, JS_ATOM_empty_string); return JS_ConcatString3(ctx, pref, name, suff); } } static JSValue js_function_hasInstance(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { int ret; ret = JS_OrdinaryIsInstanceOf(ctx, argv[0], this_val); if (ret < 0) return JS_EXCEPTION; else return JS_NewBool(ctx, ret); } static const JSCFunctionListEntry js_function_proto_funcs[] = { JS_CFUNC_DEF("call", 1, js_function_call ), JS_CFUNC_MAGIC_DEF("apply", 2, js_function_apply, 0 ), JS_CFUNC_DEF("bind", 1, js_function_bind ), JS_CFUNC_DEF("toString", 0, js_function_toString ), JS_CFUNC_DEF("[Symbol.hasInstance]", 1, js_function_hasInstance ), JS_CGETSET_DEF("fileName", js_function_proto_fileName, NULL ), JS_CGETSET_MAGIC_DEF("lineNumber", js_function_proto_lineNumber, NULL, 0 ), JS_CGETSET_MAGIC_DEF("columnNumber", js_function_proto_lineNumber, NULL, 1 ), }; /* Error class */ static JSValue iterator_to_array(JSContext *ctx, JSValueConst items) { JSValue iter, next_method = JS_UNDEFINED; JSValue v, r = JS_UNDEFINED; int64_t k; BOOL done; iter = JS_GetIterator(ctx, items, FALSE); if (JS_IsException(iter)) goto exception; next_method = JS_GetProperty(ctx, iter, JS_ATOM_next); if (JS_IsException(next_method)) goto exception; r = JS_NewArray(ctx); if (JS_IsException(r)) goto exception; for (k = 0;; k++) { v = JS_IteratorNext(ctx, iter, next_method, 0, NULL, &done); if (JS_IsException(v)) goto exception_close; if (done) break; if (JS_DefinePropertyValueInt64(ctx, r, k, v, JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception_close; } done: JS_FreeValue(ctx, next_method); JS_FreeValue(ctx, iter); return r; exception_close: JS_IteratorClose(ctx, iter, TRUE); exception: JS_FreeValue(ctx, r); r = JS_EXCEPTION; goto done; } static JSValue js_error_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv, int magic) { JSValue obj, msg, proto; JSValueConst message, options; int arg_index; if (JS_IsUndefined(new_target)) new_target = JS_GetActiveFunction(ctx); proto = JS_GetProperty(ctx, new_target, JS_ATOM_prototype); if (JS_IsException(proto)) return proto; if (!JS_IsObject(proto)) { JSContext *realm; JSValueConst proto1; JS_FreeValue(ctx, proto); realm = JS_GetFunctionRealm(ctx, new_target); if (!realm) return JS_EXCEPTION; if (magic < 0) { proto1 = realm->class_proto[JS_CLASS_ERROR]; } else { proto1 = realm->native_error_proto[magic]; } proto = JS_DupValue(ctx, proto1); } obj = JS_NewObjectProtoClass(ctx, proto, JS_CLASS_ERROR); JS_FreeValue(ctx, proto); if (JS_IsException(obj)) return obj; arg_index = (magic == JS_AGGREGATE_ERROR); message = argv[arg_index++]; if (!JS_IsUndefined(message)) { msg = JS_ToString(ctx, message); if (unlikely(JS_IsException(msg))) goto exception; JS_DefinePropertyValue(ctx, obj, JS_ATOM_message, msg, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); } if (arg_index < argc) { options = argv[arg_index]; if (JS_IsObject(options)) { int present = JS_HasProperty(ctx, options, JS_ATOM_cause); if (present < 0) goto exception; if (present) { JSValue cause = JS_GetProperty(ctx, options, JS_ATOM_cause); if (JS_IsException(cause)) goto exception; JS_DefinePropertyValue(ctx, obj, JS_ATOM_cause, cause, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); } } } if (magic == JS_AGGREGATE_ERROR) { JSValue error_list = iterator_to_array(ctx, argv[0]); if (JS_IsException(error_list)) goto exception; JS_DefinePropertyValue(ctx, obj, JS_ATOM_errors, error_list, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); } /* skip the Error() function in the backtrace */ build_backtrace(ctx, obj, JS_UNDEFINED, NULL, 0, 0, JS_BACKTRACE_FLAG_SKIP_FIRST_LEVEL); return obj; exception: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_error_toString(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue name, msg; if (!JS_IsObject(this_val)) return JS_ThrowTypeErrorNotAnObject(ctx); name = JS_GetProperty(ctx, this_val, JS_ATOM_name); if (JS_IsUndefined(name)) name = JS_AtomToString(ctx, JS_ATOM_Error); else name = JS_ToStringFree(ctx, name); if (JS_IsException(name)) return JS_EXCEPTION; msg = JS_GetProperty(ctx, this_val, JS_ATOM_message); if (JS_IsUndefined(msg)) msg = JS_AtomToString(ctx, JS_ATOM_empty_string); else msg = JS_ToStringFree(ctx, msg); if (JS_IsException(msg)) { JS_FreeValue(ctx, name); return JS_EXCEPTION; } if (!JS_IsEmptyString(name) && !JS_IsEmptyString(msg)) name = JS_ConcatString3(ctx, "", name, ": "); return JS_ConcatString(ctx, name, msg); } static const JSCFunctionListEntry js_error_proto_funcs[] = { JS_CFUNC_DEF("toString", 0, js_error_toString ), JS_PROP_STRING_DEF("name", "Error", JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE ), JS_PROP_STRING_DEF("message", "", JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE ), }; /* 2 entries for each native error class */ /* Note: we use an atom to avoid the autoinit definition which does not work in get_prop_string() */ static const JSCFunctionListEntry js_native_error_proto_funcs[] = { #define DEF(name) \ JS_PROP_ATOM_DEF("name", name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE ),\ JS_PROP_STRING_DEF("message", "", JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE ), DEF(JS_ATOM_EvalError) DEF(JS_ATOM_RangeError) DEF(JS_ATOM_ReferenceError) DEF(JS_ATOM_SyntaxError) DEF(JS_ATOM_TypeError) DEF(JS_ATOM_URIError) DEF(JS_ATOM_InternalError) DEF(JS_ATOM_AggregateError) #undef DEF }; static JSValue js_error_isError(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return JS_NewBool(ctx, JS_IsError(ctx, argv[0])); } static JSValue js_error_capture_stack_trace(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { if (!JS_IsObject(argv[0])) return JS_ThrowTypeErrorNotAnObject(ctx); build_backtrace(ctx, argv[0], argv[1], NULL, 0, 0, JS_BACKTRACE_FLAG_SKIP_FIRST_LEVEL); return JS_UNDEFINED; } static const JSCFunctionListEntry js_error_funcs[] = { JS_CFUNC_DEF("isError", 1, js_error_isError), JS_CFUNC_DEF("captureStackTrace", 2, js_error_capture_stack_trace), }; /* AggregateError */ /* used by C code. */ static JSValue js_aggregate_error_constructor(JSContext *ctx, JSValueConst errors) { JSValue obj; obj = JS_NewObjectProtoClass(ctx, ctx->native_error_proto[JS_AGGREGATE_ERROR], JS_CLASS_ERROR); if (JS_IsException(obj)) return obj; JS_DefinePropertyValue(ctx, obj, JS_ATOM_errors, JS_DupValue(ctx, errors), JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); return obj; } /* Array */ static int JS_CopySubArray(JSContext *ctx, JSValueConst obj, int64_t to_pos, int64_t from_pos, int64_t count, int dir) { JSObject *p; int64_t i, from, to, len; JSValue val; int fromPresent; p = NULL; if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { p = JS_VALUE_GET_OBJ(obj); if (p->class_id != JS_CLASS_ARRAY || !p->fast_array) { p = NULL; } } for (i = 0; i < count; ) { if (dir < 0) { from = from_pos + count - i - 1; to = to_pos + count - i - 1; } else { from = from_pos + i; to = to_pos + i; } if (p && p->fast_array && from >= 0 && from < (len = p->u.array.count) && to >= 0 && to < len) { int64_t l, j; /* Fast path for fast arrays. Since we don't look at the prototype chain, we can optimize only the cases where all the elements are present in the array. */ l = count - i; if (dir < 0) { l = min_int64(l, from + 1); l = min_int64(l, to + 1); for(j = 0; j < l; j++) { set_value(ctx, &p->u.array.u.values[to - j], JS_DupValue(ctx, p->u.array.u.values[from - j])); } } else { l = min_int64(l, len - from); l = min_int64(l, len - to); for(j = 0; j < l; j++) { set_value(ctx, &p->u.array.u.values[to + j], JS_DupValue(ctx, p->u.array.u.values[from + j])); } } i += l; } else { fromPresent = JS_TryGetPropertyInt64(ctx, obj, from, &val); if (fromPresent < 0) goto exception; if (fromPresent) { if (JS_SetPropertyInt64(ctx, obj, to, val) < 0) goto exception; } else { if (JS_DeletePropertyInt64(ctx, obj, to, JS_PROP_THROW) < 0) goto exception; } i++; } } return 0; exception: return -1; } static JSValue js_array_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { JSValue obj; int i; obj = js_create_from_ctor(ctx, new_target, JS_CLASS_ARRAY); if (JS_IsException(obj)) return obj; if (argc == 1 && JS_IsNumber(argv[0])) { uint32_t len; if (JS_ToArrayLengthFree(ctx, &len, JS_DupValue(ctx, argv[0]), TRUE)) goto fail; if (JS_SetProperty(ctx, obj, JS_ATOM_length, JS_NewUint32(ctx, len)) < 0) goto fail; } else { for(i = 0; i < argc; i++) { if (JS_SetPropertyUint32(ctx, obj, i, JS_DupValue(ctx, argv[i])) < 0) goto fail; } } return obj; fail: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_array_from(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // from(items, mapfn = void 0, this_arg = void 0) JSValueConst items = argv[0], mapfn, this_arg; JSValueConst args[2]; JSValue iter, r, v, v2, arrayLike, next_method, enum_obj; int64_t k, len; int done, mapping; mapping = FALSE; mapfn = JS_UNDEFINED; this_arg = JS_UNDEFINED; r = JS_UNDEFINED; arrayLike = JS_UNDEFINED; iter = JS_UNDEFINED; enum_obj = JS_UNDEFINED; next_method = JS_UNDEFINED; if (argc > 1) { mapfn = argv[1]; if (!JS_IsUndefined(mapfn)) { if (check_function(ctx, mapfn)) goto exception; mapping = 1; if (argc > 2) this_arg = argv[2]; } } iter = JS_GetProperty(ctx, items, JS_ATOM_Symbol_iterator); if (JS_IsException(iter)) goto exception; if (!JS_IsUndefined(iter) && !JS_IsNull(iter)) { if (!JS_IsFunction(ctx, iter)) { JS_ThrowTypeError(ctx, "value is not iterable"); goto exception; } if (JS_IsConstructor(ctx, this_val)) r = JS_CallConstructor(ctx, this_val, 0, NULL); else r = JS_NewArray(ctx); if (JS_IsException(r)) goto exception; enum_obj = JS_GetIterator2(ctx, items, iter); if (JS_IsException(enum_obj)) goto exception; next_method = JS_GetProperty(ctx, enum_obj, JS_ATOM_next); if (JS_IsException(next_method)) goto exception; for (k = 0;; k++) { v = JS_IteratorNext(ctx, enum_obj, next_method, 0, NULL, &done); if (JS_IsException(v)) goto exception; if (done) break; if (mapping) { args[0] = v; args[1] = JS_NewInt32(ctx, k); v2 = JS_Call(ctx, mapfn, this_arg, 2, args); JS_FreeValue(ctx, v); v = v2; if (JS_IsException(v)) goto exception_close; } if (JS_DefinePropertyValueInt64(ctx, r, k, v, JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception_close; } } else { arrayLike = JS_ToObject(ctx, items); if (JS_IsException(arrayLike)) goto exception; if (js_get_length64(ctx, &len, arrayLike) < 0) goto exception; v = JS_NewInt64(ctx, len); args[0] = v; if (JS_IsConstructor(ctx, this_val)) { r = JS_CallConstructor(ctx, this_val, 1, args); } else { r = js_array_constructor(ctx, JS_UNDEFINED, 1, args); } JS_FreeValue(ctx, v); if (JS_IsException(r)) goto exception; for(k = 0; k < len; k++) { v = JS_GetPropertyInt64(ctx, arrayLike, k); if (JS_IsException(v)) goto exception; if (mapping) { args[0] = v; args[1] = JS_NewInt32(ctx, k); v2 = JS_Call(ctx, mapfn, this_arg, 2, args); JS_FreeValue(ctx, v); v = v2; if (JS_IsException(v)) goto exception; } if (JS_DefinePropertyValueInt64(ctx, r, k, v, JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception; } } if (JS_SetProperty(ctx, r, JS_ATOM_length, JS_NewUint32(ctx, k)) < 0) goto exception; goto done; exception_close: JS_IteratorClose(ctx, enum_obj, TRUE); exception: JS_FreeValue(ctx, r); r = JS_EXCEPTION; done: JS_FreeValue(ctx, arrayLike); JS_FreeValue(ctx, iter); JS_FreeValue(ctx, enum_obj); JS_FreeValue(ctx, next_method); return r; } static JSValue js_array_of(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj, args[1]; int i; if (JS_IsConstructor(ctx, this_val)) { args[0] = JS_NewInt32(ctx, argc); obj = JS_CallConstructor(ctx, this_val, 1, (JSValueConst *)args); } else { obj = JS_NewArray(ctx); } if (JS_IsException(obj)) return JS_EXCEPTION; for(i = 0; i < argc; i++) { if (JS_CreateDataPropertyUint32(ctx, obj, i, JS_DupValue(ctx, argv[i]), JS_PROP_THROW) < 0) { goto fail; } } if (JS_SetProperty(ctx, obj, JS_ATOM_length, JS_NewUint32(ctx, argc)) < 0) { fail: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } return obj; } static JSValue js_array_isArray(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { int ret; ret = JS_IsArray(ctx, argv[0]); if (ret < 0) return JS_EXCEPTION; else return JS_NewBool(ctx, ret); } static JSValue js_get_this(JSContext *ctx, JSValueConst this_val) { return JS_DupValue(ctx, this_val); } static JSValue JS_ArraySpeciesCreate(JSContext *ctx, JSValueConst obj, JSValueConst len_val) { JSValue ctor, ret, species; int res; JSContext *realm; res = JS_IsArray(ctx, obj); if (res < 0) return JS_EXCEPTION; if (!res) return js_array_constructor(ctx, JS_UNDEFINED, 1, &len_val); ctor = JS_GetProperty(ctx, obj, JS_ATOM_constructor); if (JS_IsException(ctor)) return ctor; if (JS_IsConstructor(ctx, ctor)) { /* legacy web compatibility */ realm = JS_GetFunctionRealm(ctx, ctor); if (!realm) { JS_FreeValue(ctx, ctor); return JS_EXCEPTION; } if (realm != ctx && js_same_value(ctx, ctor, realm->array_ctor)) { JS_FreeValue(ctx, ctor); ctor = JS_UNDEFINED; } } if (JS_IsObject(ctor)) { species = JS_GetProperty(ctx, ctor, JS_ATOM_Symbol_species); JS_FreeValue(ctx, ctor); if (JS_IsException(species)) return species; ctor = species; if (JS_IsNull(ctor)) ctor = JS_UNDEFINED; } if (JS_IsUndefined(ctor)) { return js_array_constructor(ctx, JS_UNDEFINED, 1, &len_val); } else { ret = JS_CallConstructor(ctx, ctor, 1, &len_val); JS_FreeValue(ctx, ctor); return ret; } } static const JSCFunctionListEntry js_array_funcs[] = { JS_CFUNC_DEF("isArray", 1, js_array_isArray ), JS_CFUNC_DEF("from", 1, js_array_from ), JS_CFUNC_DEF("of", 0, js_array_of ), JS_CGETSET_DEF("[Symbol.species]", js_get_this, NULL ), }; static int JS_isConcatSpreadable(JSContext *ctx, JSValueConst obj) { JSValue val; if (!JS_IsObject(obj)) return FALSE; val = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_isConcatSpreadable); if (JS_IsException(val)) return -1; if (!JS_IsUndefined(val)) return JS_ToBoolFree(ctx, val); return JS_IsArray(ctx, obj); } static JSValue js_array_at(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj, ret; int64_t len, idx; JSValue *arrp; uint32_t count; obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &len, obj)) goto exception; if (JS_ToInt64Sat(ctx, &idx, argv[0])) goto exception; if (idx < 0) idx = len + idx; if (idx < 0 || idx >= len) { ret = JS_UNDEFINED; } else if (js_get_fast_array(ctx, obj, &arrp, &count) && idx < count) { ret = JS_DupValue(ctx, arrp[idx]); } else { int present = JS_TryGetPropertyInt64(ctx, obj, idx, &ret); if (present < 0) goto exception; if (!present) ret = JS_UNDEFINED; } JS_FreeValue(ctx, obj); return ret; exception: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_array_with(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue arr, obj, ret, *arrp, *pval; JSObject *p; int64_t i, len, idx; uint32_t count32; ret = JS_EXCEPTION; arr = JS_UNDEFINED; obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &len, obj)) goto exception; if (JS_ToInt64Sat(ctx, &idx, argv[0])) goto exception; if (idx < 0) idx = len + idx; if (idx < 0 || idx >= len) { JS_ThrowRangeError(ctx, "invalid array index: %" PRId64, idx); goto exception; } arr = js_allocate_fast_array(ctx, len); if (JS_IsException(arr)) goto exception; p = JS_VALUE_GET_OBJ(arr); i = 0; pval = p->u.array.u.values; if (js_get_fast_array(ctx, obj, &arrp, &count32) && count32 == len) { for (; i < idx; i++, pval++) *pval = JS_DupValue(ctx, arrp[i]); *pval = JS_DupValue(ctx, argv[1]); for (i++, pval++; i < len; i++, pval++) *pval = JS_DupValue(ctx, arrp[i]); } else { for (; i < idx; i++, pval++) if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval)) goto exception; *pval = JS_DupValue(ctx, argv[1]); for (i++, pval++; i < len; i++, pval++) { if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval)) goto exception; } } ret = arr; arr = JS_UNDEFINED; exception: JS_FreeValue(ctx, arr); JS_FreeValue(ctx, obj); return ret; } static JSValue js_array_concat(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj, arr, val; JSValueConst e; int64_t len, k, n; int i, res; arr = JS_UNDEFINED; obj = JS_ToObject(ctx, this_val); if (JS_IsException(obj)) goto exception; arr = JS_ArraySpeciesCreate(ctx, obj, JS_NewInt32(ctx, 0)); if (JS_IsException(arr)) goto exception; n = 0; for (i = -1; i < argc; i++) { if (i < 0) e = obj; else e = argv[i]; res = JS_isConcatSpreadable(ctx, e); if (res < 0) goto exception; if (res) { if (js_get_length64(ctx, &len, e)) goto exception; if (n + len > MAX_SAFE_INTEGER) { JS_ThrowTypeError(ctx, "Array loo long"); goto exception; } for (k = 0; k < len; k++, n++) { res = JS_TryGetPropertyInt64(ctx, e, k, &val); if (res < 0) goto exception; if (res) { if (JS_DefinePropertyValueInt64(ctx, arr, n, val, JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception; } } } else { if (n >= MAX_SAFE_INTEGER) { JS_ThrowTypeError(ctx, "Array loo long"); goto exception; } if (JS_DefinePropertyValueInt64(ctx, arr, n, JS_DupValue(ctx, e), JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception; n++; } } if (JS_SetProperty(ctx, arr, JS_ATOM_length, JS_NewInt64(ctx, n)) < 0) goto exception; JS_FreeValue(ctx, obj); return arr; exception: JS_FreeValue(ctx, arr); JS_FreeValue(ctx, obj); return JS_EXCEPTION; } #define special_every 0 #define special_some 1 #define special_forEach 2 #define special_map 3 #define special_filter 4 #define special_TA 8 static JSValue js_typed_array___speciesCreate(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv); static JSValue js_array_every(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int special) { JSValue obj, val, index_val, res, ret; JSValueConst args[3]; JSValueConst func, this_arg; int64_t len, k, n; int present; ret = JS_UNDEFINED; val = JS_UNDEFINED; if (special & special_TA) { obj = JS_DupValue(ctx, this_val); len = js_typed_array_get_length_unsafe(ctx, obj); if (len < 0) goto exception; } else { obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &len, obj)) goto exception; } func = argv[0]; this_arg = JS_UNDEFINED; if (argc > 1) this_arg = argv[1]; if (check_function(ctx, func)) goto exception; switch (special) { case special_every: case special_every | special_TA: ret = JS_TRUE; break; case special_some: case special_some | special_TA: ret = JS_FALSE; break; case special_map: /* XXX: JS_ArraySpeciesCreate should take int64_t */ ret = JS_ArraySpeciesCreate(ctx, obj, JS_NewInt64(ctx, len)); if (JS_IsException(ret)) goto exception; break; case special_filter: ret = JS_ArraySpeciesCreate(ctx, obj, JS_NewInt32(ctx, 0)); if (JS_IsException(ret)) goto exception; break; case special_map | special_TA: args[0] = obj; args[1] = JS_NewInt32(ctx, len); ret = js_typed_array___speciesCreate(ctx, JS_UNDEFINED, 2, args); if (JS_IsException(ret)) goto exception; break; case special_filter | special_TA: ret = JS_NewArray(ctx); if (JS_IsException(ret)) goto exception; break; } n = 0; for(k = 0; k < len; k++) { if (special & special_TA) { val = JS_GetPropertyInt64(ctx, obj, k); if (JS_IsException(val)) goto exception; present = TRUE; } else { present = JS_TryGetPropertyInt64(ctx, obj, k, &val); if (present < 0) goto exception; } if (present) { index_val = JS_NewInt64(ctx, k); if (JS_IsException(index_val)) goto exception; args[0] = val; args[1] = index_val; args[2] = obj; res = JS_Call(ctx, func, this_arg, 3, args); JS_FreeValue(ctx, index_val); if (JS_IsException(res)) goto exception; switch (special) { case special_every: case special_every | special_TA: if (!JS_ToBoolFree(ctx, res)) { ret = JS_FALSE; goto done; } break; case special_some: case special_some | special_TA: if (JS_ToBoolFree(ctx, res)) { ret = JS_TRUE; goto done; } break; case special_map: if (JS_DefinePropertyValueInt64(ctx, ret, k, res, JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception; break; case special_map | special_TA: if (JS_SetPropertyValue(ctx, ret, JS_NewInt32(ctx, k), res, JS_PROP_THROW) < 0) goto exception; break; case special_filter: case special_filter | special_TA: if (JS_ToBoolFree(ctx, res)) { if (JS_DefinePropertyValueInt64(ctx, ret, n++, JS_DupValue(ctx, val), JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception; } break; default: JS_FreeValue(ctx, res); break; } JS_FreeValue(ctx, val); val = JS_UNDEFINED; } } done: if (special == (special_filter | special_TA)) { JSValue arr; args[0] = obj; args[1] = JS_NewInt32(ctx, n); arr = js_typed_array___speciesCreate(ctx, JS_UNDEFINED, 2, args); if (JS_IsException(arr)) goto exception; args[0] = ret; res = JS_Invoke(ctx, arr, JS_ATOM_set, 1, args); if (check_exception_free(ctx, res)) { JS_FreeValue(ctx, arr); goto exception; } JS_FreeValue(ctx, ret); ret = arr; } JS_FreeValue(ctx, val); JS_FreeValue(ctx, obj); return ret; exception: JS_FreeValue(ctx, ret); JS_FreeValue(ctx, val); JS_FreeValue(ctx, obj); return JS_EXCEPTION; } #define special_reduce 0 #define special_reduceRight 1 static JSValue js_array_reduce(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int special) { JSValue obj, val, index_val, acc, acc1; JSValueConst args[4]; JSValueConst func; int64_t len, k, k1; int present; acc = JS_UNDEFINED; val = JS_UNDEFINED; if (special & special_TA) { obj = JS_DupValue(ctx, this_val); len = js_typed_array_get_length_unsafe(ctx, obj); if (len < 0) goto exception; } else { obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &len, obj)) goto exception; } func = argv[0]; if (check_function(ctx, func)) goto exception; k = 0; if (argc > 1) { acc = JS_DupValue(ctx, argv[1]); } else { for(;;) { if (k >= len) { JS_ThrowTypeError(ctx, "empty array"); goto exception; } k1 = (special & special_reduceRight) ? len - k - 1 : k; k++; if (special & special_TA) { acc = JS_GetPropertyInt64(ctx, obj, k1); if (JS_IsException(acc)) goto exception; break; } else { present = JS_TryGetPropertyInt64(ctx, obj, k1, &acc); if (present < 0) goto exception; if (present) break; } } } for (; k < len; k++) { k1 = (special & special_reduceRight) ? len - k - 1 : k; if (special & special_TA) { val = JS_GetPropertyInt64(ctx, obj, k1); if (JS_IsException(val)) goto exception; present = TRUE; } else { present = JS_TryGetPropertyInt64(ctx, obj, k1, &val); if (present < 0) goto exception; } if (present) { index_val = JS_NewInt64(ctx, k1); if (JS_IsException(index_val)) goto exception; args[0] = acc; args[1] = val; args[2] = index_val; args[3] = obj; acc1 = JS_Call(ctx, func, JS_UNDEFINED, 4, args); JS_FreeValue(ctx, index_val); JS_FreeValue(ctx, val); val = JS_UNDEFINED; if (JS_IsException(acc1)) goto exception; JS_FreeValue(ctx, acc); acc = acc1; } } JS_FreeValue(ctx, obj); return acc; exception: JS_FreeValue(ctx, acc); JS_FreeValue(ctx, val); JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_array_fill(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj; int64_t len, start, end; obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &len, obj)) goto exception; start = 0; if (argc > 1 && !JS_IsUndefined(argv[1])) { if (JS_ToInt64Clamp(ctx, &start, argv[1], 0, len, len)) goto exception; } end = len; if (argc > 2 && !JS_IsUndefined(argv[2])) { if (JS_ToInt64Clamp(ctx, &end, argv[2], 0, len, len)) goto exception; } /* XXX: should special case fast arrays */ while (start < end) { if (JS_SetPropertyInt64(ctx, obj, start, JS_DupValue(ctx, argv[0])) < 0) goto exception; start++; } return obj; exception: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_array_includes(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj, val; int64_t len, n; JSValue *arrp; uint32_t count; int res; obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &len, obj)) goto exception; res = FALSE; if (len > 0) { n = 0; if (argc > 1) { if (JS_ToInt64Clamp(ctx, &n, argv[1], 0, len, len)) goto exception; } if (js_get_fast_array(ctx, obj, &arrp, &count)) { for (; n < count; n++) { if (js_strict_eq2(ctx, JS_DupValue(ctx, argv[0]), JS_DupValue(ctx, arrp[n]), JS_EQ_SAME_VALUE_ZERO)) { res = TRUE; goto done; } } } for (; n < len; n++) { val = JS_GetPropertyInt64(ctx, obj, n); if (JS_IsException(val)) goto exception; if (js_strict_eq2(ctx, JS_DupValue(ctx, argv[0]), val, JS_EQ_SAME_VALUE_ZERO)) { res = TRUE; break; } } } done: JS_FreeValue(ctx, obj); return JS_NewBool(ctx, res); exception: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_array_indexOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj, val; int64_t len, n, res; JSValue *arrp; uint32_t count; obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &len, obj)) goto exception; res = -1; if (len > 0) { n = 0; if (argc > 1) { if (JS_ToInt64Clamp(ctx, &n, argv[1], 0, len, len)) goto exception; } if (js_get_fast_array(ctx, obj, &arrp, &count)) { for (; n < count; n++) { if (js_strict_eq2(ctx, JS_DupValue(ctx, argv[0]), JS_DupValue(ctx, arrp[n]), JS_EQ_STRICT)) { res = n; goto done; } } } for (; n < len; n++) { int present = JS_TryGetPropertyInt64(ctx, obj, n, &val); if (present < 0) goto exception; if (present) { if (js_strict_eq2(ctx, JS_DupValue(ctx, argv[0]), val, JS_EQ_STRICT)) { res = n; break; } } } } done: JS_FreeValue(ctx, obj); return JS_NewInt64(ctx, res); exception: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_array_lastIndexOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj, val; int64_t len, n, res; int present; obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &len, obj)) goto exception; res = -1; if (len > 0) { n = len - 1; if (argc > 1) { if (JS_ToInt64Clamp(ctx, &n, argv[1], -1, len - 1, len)) goto exception; } /* XXX: should special case fast arrays */ for (; n >= 0; n--) { present = JS_TryGetPropertyInt64(ctx, obj, n, &val); if (present < 0) goto exception; if (present) { if (js_strict_eq2(ctx, JS_DupValue(ctx, argv[0]), val, JS_EQ_STRICT)) { res = n; break; } } } } JS_FreeValue(ctx, obj); return JS_NewInt64(ctx, res); exception: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } enum { ArrayFind, ArrayFindIndex, ArrayFindLast, ArrayFindLastIndex, }; static JSValue js_array_find(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int mode) { JSValueConst func, this_arg; JSValueConst args[3]; JSValue obj, val, index_val, res; int64_t len, k, end; int dir; index_val = JS_UNDEFINED; val = JS_UNDEFINED; obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &len, obj)) goto exception; func = argv[0]; if (check_function(ctx, func)) goto exception; this_arg = JS_UNDEFINED; if (argc > 1) this_arg = argv[1]; k = 0; dir = 1; end = len; if (mode == ArrayFindLast || mode == ArrayFindLastIndex) { k = len - 1; dir = -1; end = -1; } // TODO(bnoordhuis) add fast path for fast arrays for(; k != end; k += dir) { index_val = JS_NewInt64(ctx, k); if (JS_IsException(index_val)) goto exception; val = JS_GetPropertyValue(ctx, obj, index_val); if (JS_IsException(val)) goto exception; args[0] = val; args[1] = index_val; args[2] = this_val; res = JS_Call(ctx, func, this_arg, 3, args); if (JS_IsException(res)) goto exception; if (JS_ToBoolFree(ctx, res)) { if (mode == ArrayFindIndex || mode == ArrayFindLastIndex) { JS_FreeValue(ctx, val); JS_FreeValue(ctx, obj); return index_val; } else { JS_FreeValue(ctx, index_val); JS_FreeValue(ctx, obj); return val; } } JS_FreeValue(ctx, val); JS_FreeValue(ctx, index_val); } JS_FreeValue(ctx, obj); if (mode == ArrayFindIndex || mode == ArrayFindLastIndex) return JS_NewInt32(ctx, -1); else return JS_UNDEFINED; exception: JS_FreeValue(ctx, index_val); JS_FreeValue(ctx, val); JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_array_toString(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj, method, ret; obj = JS_ToObject(ctx, this_val); if (JS_IsException(obj)) return JS_EXCEPTION; method = JS_GetProperty(ctx, obj, JS_ATOM_join); if (JS_IsException(method)) { ret = JS_EXCEPTION; } else if (!JS_IsFunction(ctx, method)) { /* Use intrinsic Object.prototype.toString */ JS_FreeValue(ctx, method); ret = js_object_toString(ctx, obj, 0, NULL); } else { ret = JS_CallFree(ctx, method, obj, 0, NULL); } JS_FreeValue(ctx, obj); return ret; } static JSValue js_array_join(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int toLocaleString) { JSValue obj, sep = JS_UNDEFINED, el; StringBuffer b_s, *b = &b_s; JSString *p = NULL; int64_t i, n; int c; obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &n, obj)) goto exception; c = ','; /* default separator */ if (!toLocaleString && argc > 0 && !JS_IsUndefined(argv[0])) { sep = JS_ToString(ctx, argv[0]); if (JS_IsException(sep)) goto exception; p = JS_VALUE_GET_STRING(sep); if (p->len == 1 && !p->is_wide_char) c = p->u.str8[0]; else c = -1; } string_buffer_init(ctx, b, 0); for(i = 0; i < n; i++) { if (i > 0) { if (c >= 0) { string_buffer_putc8(b, c); } else { string_buffer_concat(b, p, 0, p->len); } } el = JS_GetPropertyUint32(ctx, obj, i); if (JS_IsException(el)) goto fail; if (!JS_IsNull(el) && !JS_IsUndefined(el)) { if (toLocaleString) { el = JS_ToLocaleStringFree(ctx, el); } if (string_buffer_concat_value_free(b, el)) goto fail; } } JS_FreeValue(ctx, sep); JS_FreeValue(ctx, obj); return string_buffer_end(b); fail: string_buffer_free(b); JS_FreeValue(ctx, sep); exception: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_array_pop(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int shift) { JSValue obj, res = JS_UNDEFINED; int64_t len, newLen; JSValue *arrp; uint32_t count32; obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &len, obj)) goto exception; newLen = 0; if (len > 0) { newLen = len - 1; /* Special case fast arrays */ if (js_get_fast_array(ctx, obj, &arrp, &count32) && count32 == len) { JSObject *p = JS_VALUE_GET_OBJ(obj); if (shift) { res = arrp[0]; memmove(arrp, arrp + 1, (count32 - 1) * sizeof(*arrp)); p->u.array.count--; } else { res = arrp[count32 - 1]; p->u.array.count--; } } else { if (shift) { res = JS_GetPropertyInt64(ctx, obj, 0); if (JS_IsException(res)) goto exception; if (JS_CopySubArray(ctx, obj, 0, 1, len - 1, +1)) goto exception; } else { res = JS_GetPropertyInt64(ctx, obj, newLen); if (JS_IsException(res)) goto exception; } if (JS_DeletePropertyInt64(ctx, obj, newLen, JS_PROP_THROW) < 0) goto exception; } } if (JS_SetProperty(ctx, obj, JS_ATOM_length, JS_NewInt64(ctx, newLen)) < 0) goto exception; JS_FreeValue(ctx, obj); return res; exception: JS_FreeValue(ctx, res); JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_array_push(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int unshift) { JSValue obj; int i; int64_t len, from, newLen; if (likely(JS_VALUE_GET_TAG(this_val) == JS_TAG_OBJECT && !unshift)) { JSObject *p = JS_VALUE_GET_OBJ(this_val); if (likely(p->class_id == JS_CLASS_ARRAY && p->fast_array && can_extend_fast_array(p) && JS_VALUE_GET_TAG(p->prop[0].u.value) == JS_TAG_INT && JS_VALUE_GET_INT(p->prop[0].u.value) == p->u.array.count && (get_shape_prop(p->shape)->flags & JS_PROP_WRITABLE) != 0)) { /* fast case */ uint32_t new_len; new_len = p->u.array.count + argc; if (likely(new_len <= INT32_MAX)) { if (unlikely(new_len > p->u.array.u1.size)) { if (expand_fast_array(ctx, p, new_len)) return JS_EXCEPTION; } for(i = 0; i < argc; i++) p->u.array.u.values[p->u.array.count + i] = JS_DupValue(ctx, argv[i]); p->prop[0].u.value = JS_NewInt32(ctx, new_len); p->u.array.count = new_len; return JS_NewInt32(ctx, new_len); } } } obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &len, obj)) goto exception; newLen = len + argc; if (newLen > MAX_SAFE_INTEGER) { JS_ThrowTypeError(ctx, "Array loo long"); goto exception; } from = len; if (unshift && argc > 0) { if (JS_CopySubArray(ctx, obj, argc, 0, len, -1)) goto exception; from = 0; } for(i = 0; i < argc; i++) { if (JS_SetPropertyInt64(ctx, obj, from + i, JS_DupValue(ctx, argv[i])) < 0) goto exception; } if (JS_SetProperty(ctx, obj, JS_ATOM_length, JS_NewInt64(ctx, newLen)) < 0) goto exception; JS_FreeValue(ctx, obj); return JS_NewInt64(ctx, newLen); exception: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_array_reverse(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj, lval, hval; JSValue *arrp; int64_t len, l, h; int l_present, h_present; uint32_t count32; lval = JS_UNDEFINED; obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &len, obj)) goto exception; /* Special case fast arrays */ if (js_get_fast_array(ctx, obj, &arrp, &count32) && count32 == len) { uint32_t ll, hh; if (count32 > 1) { for (ll = 0, hh = count32 - 1; ll < hh; ll++, hh--) { lval = arrp[ll]; arrp[ll] = arrp[hh]; arrp[hh] = lval; } } return obj; } for (l = 0, h = len - 1; l < h; l++, h--) { l_present = JS_TryGetPropertyInt64(ctx, obj, l, &lval); if (l_present < 0) goto exception; h_present = JS_TryGetPropertyInt64(ctx, obj, h, &hval); if (h_present < 0) goto exception; if (h_present) { if (JS_SetPropertyInt64(ctx, obj, l, hval) < 0) goto exception; if (l_present) { if (JS_SetPropertyInt64(ctx, obj, h, lval) < 0) { lval = JS_UNDEFINED; goto exception; } lval = JS_UNDEFINED; } else { if (JS_DeletePropertyInt64(ctx, obj, h, JS_PROP_THROW) < 0) goto exception; } } else { if (l_present) { if (JS_DeletePropertyInt64(ctx, obj, l, JS_PROP_THROW) < 0) goto exception; if (JS_SetPropertyInt64(ctx, obj, h, lval) < 0) { lval = JS_UNDEFINED; goto exception; } lval = JS_UNDEFINED; } } } return obj; exception: JS_FreeValue(ctx, lval); JS_FreeValue(ctx, obj); return JS_EXCEPTION; } // Note: a.toReversed() is a.slice().reverse() with the twist that a.slice() // leaves holes in sparse arrays intact whereas a.toReversed() replaces them // with undefined, thus in effect creating a dense array. // Does not use Array[@@species], always returns a base Array. static JSValue js_array_toReversed(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue arr, obj, ret, *arrp, *pval; JSObject *p; int64_t i, len; uint32_t count32; ret = JS_EXCEPTION; arr = JS_UNDEFINED; obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &len, obj)) goto exception; arr = js_allocate_fast_array(ctx, len); if (JS_IsException(arr)) goto exception; if (len > 0) { p = JS_VALUE_GET_OBJ(arr); i = len - 1; pval = p->u.array.u.values; if (js_get_fast_array(ctx, obj, &arrp, &count32) && count32 == len) { for (; i >= 0; i--, pval++) *pval = JS_DupValue(ctx, arrp[i]); } else { // Query order is observable; test262 expects descending order. for (; i >= 0; i--, pval++) { if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval)) goto exception; } } } ret = arr; arr = JS_UNDEFINED; exception: JS_FreeValue(ctx, arr); JS_FreeValue(ctx, obj); return ret; } static JSValue js_array_slice(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int splice) { JSValue obj, arr, val, len_val; int64_t len, start, k, final, n, count, del_count, new_len; int kPresent; JSValue *arrp; uint32_t count32, i, item_count; arr = JS_UNDEFINED; obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &len, obj)) goto exception; if (JS_ToInt64Clamp(ctx, &start, argv[0], 0, len, len)) goto exception; if (splice) { if (argc == 0) { item_count = 0; del_count = 0; } else if (argc == 1) { item_count = 0; del_count = len - start; } else { item_count = argc - 2; if (JS_ToInt64Clamp(ctx, &del_count, argv[1], 0, len - start, 0)) goto exception; } if (len + item_count - del_count > MAX_SAFE_INTEGER) { JS_ThrowTypeError(ctx, "Array loo long"); goto exception; } count = del_count; } else { item_count = 0; /* avoid warning */ final = len; if (!JS_IsUndefined(argv[1])) { if (JS_ToInt64Clamp(ctx, &final, argv[1], 0, len, len)) goto exception; } count = max_int64(final - start, 0); } len_val = JS_NewInt64(ctx, count); arr = JS_ArraySpeciesCreate(ctx, obj, len_val); JS_FreeValue(ctx, len_val); if (JS_IsException(arr)) goto exception; k = start; final = start + count; n = 0; /* The fast array test on arr ensures that JS_CreateDataPropertyUint32() won't modify obj in case arr is an exotic object */ /* Special case fast arrays */ if (js_get_fast_array(ctx, obj, &arrp, &count32) && js_is_fast_array(ctx, arr)) { /* XXX: should share code with fast array constructor */ for (; k < final && k < count32; k++, n++) { if (JS_CreateDataPropertyUint32(ctx, arr, n, JS_DupValue(ctx, arrp[k]), JS_PROP_THROW) < 0) goto exception; } } /* Copy the remaining elements if any (handle case of inherited properties) */ for (; k < final; k++, n++) { kPresent = JS_TryGetPropertyInt64(ctx, obj, k, &val); if (kPresent < 0) goto exception; if (kPresent) { if (JS_CreateDataPropertyUint32(ctx, arr, n, val, JS_PROP_THROW) < 0) goto exception; } } if (JS_SetProperty(ctx, arr, JS_ATOM_length, JS_NewInt64(ctx, n)) < 0) goto exception; if (splice) { new_len = len + item_count - del_count; if (item_count != del_count) { if (JS_CopySubArray(ctx, obj, start + item_count, start + del_count, len - (start + del_count), item_count <= del_count ? +1 : -1) < 0) goto exception; for (k = len; k-- > new_len; ) { if (JS_DeletePropertyInt64(ctx, obj, k, JS_PROP_THROW) < 0) goto exception; } } for (i = 0; i < item_count; i++) { if (JS_SetPropertyInt64(ctx, obj, start + i, JS_DupValue(ctx, argv[i + 2])) < 0) goto exception; } if (JS_SetProperty(ctx, obj, JS_ATOM_length, JS_NewInt64(ctx, new_len)) < 0) goto exception; } JS_FreeValue(ctx, obj); return arr; exception: JS_FreeValue(ctx, obj); JS_FreeValue(ctx, arr); return JS_EXCEPTION; } static JSValue js_array_toSpliced(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue arr, obj, ret, *arrp, *pval, *last; JSObject *p; int64_t i, j, len, newlen, start, add, del; uint32_t count32; pval = NULL; last = NULL; ret = JS_EXCEPTION; arr = JS_UNDEFINED; obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &len, obj)) goto exception; start = 0; if (argc > 0) if (JS_ToInt64Clamp(ctx, &start, argv[0], 0, len, len)) goto exception; del = 0; if (argc > 0) del = len - start; if (argc > 1) if (JS_ToInt64Clamp(ctx, &del, argv[1], 0, del, 0)) goto exception; add = 0; if (argc > 2) add = argc - 2; newlen = len + add - del; if (newlen > MAX_SAFE_INTEGER) { JS_ThrowTypeError(ctx, "invalid array length"); goto exception; } arr = js_allocate_fast_array(ctx, newlen); if (JS_IsException(arr)) goto exception; if (newlen <= 0) goto done; p = JS_VALUE_GET_OBJ(arr); pval = &p->u.array.u.values[0]; last = &p->u.array.u.values[newlen]; if (js_get_fast_array(ctx, obj, &arrp, &count32) && count32 == len) { for (i = 0; i < start; i++, pval++) *pval = JS_DupValue(ctx, arrp[i]); for (j = 0; j < add; j++, pval++) *pval = JS_DupValue(ctx, argv[2 + j]); for (i += del; i < len; i++, pval++) *pval = JS_DupValue(ctx, arrp[i]); } else { for (i = 0; i < start; i++, pval++) if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval)) goto exception; for (j = 0; j < add; j++, pval++) *pval = JS_DupValue(ctx, argv[2 + j]); for (i += del; i < len; i++, pval++) if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval)) goto exception; } assert(pval == last); done: ret = arr; arr = JS_UNDEFINED; exception: JS_FreeValue(ctx, arr); JS_FreeValue(ctx, obj); return ret; } static JSValue js_array_copyWithin(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj; int64_t len, from, to, final, count; obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &len, obj)) goto exception; if (JS_ToInt64Clamp(ctx, &to, argv[0], 0, len, len)) goto exception; if (JS_ToInt64Clamp(ctx, &from, argv[1], 0, len, len)) goto exception; final = len; if (argc > 2 && !JS_IsUndefined(argv[2])) { if (JS_ToInt64Clamp(ctx, &final, argv[2], 0, len, len)) goto exception; } count = min_int64(final - from, len - to); if (JS_CopySubArray(ctx, obj, to, from, count, (from < to && to < from + count) ? -1 : +1)) goto exception; return obj; exception: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static int64_t JS_FlattenIntoArray(JSContext *ctx, JSValueConst target, JSValueConst source, int64_t sourceLen, int64_t targetIndex, int depth, JSValueConst mapperFunction, JSValueConst thisArg) { JSValue element; int64_t sourceIndex, elementLen; int present, is_array; if (js_check_stack_overflow(ctx->rt, 0)) { JS_ThrowStackOverflow(ctx); return -1; } for (sourceIndex = 0; sourceIndex < sourceLen; sourceIndex++) { present = JS_TryGetPropertyInt64(ctx, source, sourceIndex, &element); if (present < 0) return -1; if (!present) continue; if (!JS_IsUndefined(mapperFunction)) { JSValueConst args[3] = { element, JS_NewInt64(ctx, sourceIndex), source }; element = JS_Call(ctx, mapperFunction, thisArg, 3, args); JS_FreeValue(ctx, (JSValue)args[0]); JS_FreeValue(ctx, (JSValue)args[1]); if (JS_IsException(element)) return -1; } if (depth > 0) { is_array = JS_IsArray(ctx, element); if (is_array < 0) goto fail; if (is_array) { if (js_get_length64(ctx, &elementLen, element) < 0) goto fail; targetIndex = JS_FlattenIntoArray(ctx, target, element, elementLen, targetIndex, depth - 1, JS_UNDEFINED, JS_UNDEFINED); if (targetIndex < 0) goto fail; JS_FreeValue(ctx, element); continue; } } if (targetIndex >= MAX_SAFE_INTEGER) { JS_ThrowTypeError(ctx, "Array too long"); goto fail; } if (JS_DefinePropertyValueInt64(ctx, target, targetIndex, element, JS_PROP_C_W_E | JS_PROP_THROW) < 0) return -1; targetIndex++; } return targetIndex; fail: JS_FreeValue(ctx, element); return -1; } static JSValue js_array_flatten(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int map) { JSValue obj, arr; JSValueConst mapperFunction, thisArg; int64_t sourceLen; int depthNum; arr = JS_UNDEFINED; obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &sourceLen, obj)) goto exception; depthNum = 1; mapperFunction = JS_UNDEFINED; thisArg = JS_UNDEFINED; if (map) { mapperFunction = argv[0]; if (argc > 1) { thisArg = argv[1]; } if (check_function(ctx, mapperFunction)) goto exception; } else { if (argc > 0 && !JS_IsUndefined(argv[0])) { if (JS_ToInt32Sat(ctx, &depthNum, argv[0]) < 0) goto exception; } } arr = JS_ArraySpeciesCreate(ctx, obj, JS_NewInt32(ctx, 0)); if (JS_IsException(arr)) goto exception; if (JS_FlattenIntoArray(ctx, arr, obj, sourceLen, 0, depthNum, mapperFunction, thisArg) < 0) goto exception; JS_FreeValue(ctx, obj); return arr; exception: JS_FreeValue(ctx, obj); JS_FreeValue(ctx, arr); return JS_EXCEPTION; } /* Array sort */ typedef struct ValueSlot { JSValue val; JSString *str; int64_t pos; } ValueSlot; struct array_sort_context { JSContext *ctx; int exception; int has_method; JSValueConst method; }; static int js_array_cmp_generic(const void *a, const void *b, void *opaque) { struct array_sort_context *psc = opaque; JSContext *ctx = psc->ctx; JSValueConst argv[2]; JSValue res; ValueSlot *ap = (ValueSlot *)(void *)a; ValueSlot *bp = (ValueSlot *)(void *)b; int cmp; if (psc->exception) return 0; if (psc->has_method) { /* custom sort function is specified as returning 0 for identical * objects: avoid method call overhead. */ if (!memcmp(&ap->val, &bp->val, sizeof(ap->val))) goto cmp_same; argv[0] = ap->val; argv[1] = bp->val; res = JS_Call(ctx, psc->method, JS_UNDEFINED, 2, argv); if (JS_IsException(res)) goto exception; if (JS_VALUE_GET_TAG(res) == JS_TAG_INT) { int val = JS_VALUE_GET_INT(res); cmp = (val > 0) - (val < 0); } else { double val; if (JS_ToFloat64Free(ctx, &val, res) < 0) goto exception; cmp = (val > 0) - (val < 0); } } else { /* Not supposed to bypass ToString even for identical objects as * tested in test262/test/built-ins/Array/prototype/sort/bug_596_1.js */ if (!ap->str) { JSValue str = JS_ToString(ctx, ap->val); if (JS_IsException(str)) goto exception; ap->str = JS_VALUE_GET_STRING(str); } if (!bp->str) { JSValue str = JS_ToString(ctx, bp->val); if (JS_IsException(str)) goto exception; bp->str = JS_VALUE_GET_STRING(str); } cmp = js_string_compare(ctx, ap->str, bp->str); } if (cmp != 0) return cmp; cmp_same: /* make sort stable: compare array offsets */ return (ap->pos > bp->pos) - (ap->pos < bp->pos); exception: psc->exception = 1; return 0; } static JSValue js_array_sort(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { struct array_sort_context asc = { ctx, 0, 0, argv[0] }; JSValue obj = JS_UNDEFINED; ValueSlot *array = NULL; size_t array_size = 0, pos = 0, n = 0; int64_t i, len, undefined_count = 0; int present; if (!JS_IsUndefined(asc.method)) { if (check_function(ctx, asc.method)) goto exception; asc.has_method = 1; } obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &len, obj)) goto exception; /* XXX: should special case fast arrays */ for (i = 0; i < len; i++) { if (pos >= array_size) { size_t new_size, slack; ValueSlot *new_array; new_size = (array_size + (array_size >> 1) + 31) & ~15; new_array = js_realloc2(ctx, array, new_size * sizeof(*array), &slack); if (new_array == NULL) goto exception; new_size += slack / sizeof(*new_array); array = new_array; array_size = new_size; } present = JS_TryGetPropertyInt64(ctx, obj, i, &array[pos].val); if (present < 0) goto exception; if (present == 0) continue; if (JS_IsUndefined(array[pos].val)) { undefined_count++; continue; } array[pos].str = NULL; array[pos].pos = i; pos++; } rqsort(array, pos, sizeof(*array), js_array_cmp_generic, &asc); if (asc.exception) goto exception; /* XXX: should special case fast arrays */ while (n < pos) { if (array[n].str) JS_FreeValue(ctx, JS_MKPTR(JS_TAG_STRING, array[n].str)); if (array[n].pos == n) { JS_FreeValue(ctx, array[n].val); } else { if (JS_SetPropertyInt64(ctx, obj, n, array[n].val) < 0) { n++; goto exception; } } n++; } js_free(ctx, array); for (i = n; undefined_count-- > 0; i++) { if (JS_SetPropertyInt64(ctx, obj, i, JS_UNDEFINED) < 0) goto fail; } for (; i < len; i++) { if (JS_DeletePropertyInt64(ctx, obj, i, JS_PROP_THROW) < 0) goto fail; } return obj; exception: for (; n < pos; n++) { JS_FreeValue(ctx, array[n].val); if (array[n].str) JS_FreeValue(ctx, JS_MKPTR(JS_TAG_STRING, array[n].str)); } js_free(ctx, array); fail: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } // Note: a.toSorted() is a.slice().sort() with the twist that a.slice() // leaves holes in sparse arrays intact whereas a.toSorted() replaces them // with undefined, thus in effect creating a dense array. // Does not use Array[@@species], always returns a base Array. static JSValue js_array_toSorted(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue arr, obj, ret, *arrp, *pval; JSObject *p; int64_t i, len; uint32_t count32; int ok; ok = JS_IsUndefined(argv[0]) || JS_IsFunction(ctx, argv[0]); if (!ok) return JS_ThrowTypeError(ctx, "not a function"); ret = JS_EXCEPTION; arr = JS_UNDEFINED; obj = JS_ToObject(ctx, this_val); if (js_get_length64(ctx, &len, obj)) goto exception; arr = js_allocate_fast_array(ctx, len); if (JS_IsException(arr)) goto exception; if (len > 0) { p = JS_VALUE_GET_OBJ(arr); i = 0; pval = p->u.array.u.values; if (js_get_fast_array(ctx, obj, &arrp, &count32) && count32 == len) { for (; i < len; i++, pval++) *pval = JS_DupValue(ctx, arrp[i]); } else { for (; i < len; i++, pval++) { if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval)) goto exception; } } } ret = js_array_sort(ctx, arr, argc, argv); if (JS_IsException(ret)) goto exception; JS_FreeValue(ctx, ret); ret = arr; arr = JS_UNDEFINED; exception: JS_FreeValue(ctx, arr); JS_FreeValue(ctx, obj); return ret; } typedef struct JSArrayIteratorData { JSValue obj; JSIteratorKindEnum kind; uint32_t idx; } JSArrayIteratorData; static void js_array_iterator_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); JSArrayIteratorData *it = p->u.array_iterator_data; if (it) { JS_FreeValueRT(rt, it->obj); js_free_rt(rt, it); } } static void js_array_iterator_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); JSArrayIteratorData *it = p->u.array_iterator_data; if (it) { JS_MarkValue(rt, it->obj, mark_func); } } static JSValue js_create_array_iterator(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSValue enum_obj, arr; JSArrayIteratorData *it; JSIteratorKindEnum kind; int class_id; kind = magic & 3; if (magic & 4) { /* string iterator case */ arr = JS_ToStringCheckObject(ctx, this_val); class_id = JS_CLASS_STRING_ITERATOR; } else { arr = JS_ToObject(ctx, this_val); class_id = JS_CLASS_ARRAY_ITERATOR; } if (JS_IsException(arr)) goto fail; enum_obj = JS_NewObjectClass(ctx, class_id); if (JS_IsException(enum_obj)) goto fail; it = js_malloc(ctx, sizeof(*it)); if (!it) goto fail1; it->obj = arr; it->kind = kind; it->idx = 0; JS_SetOpaque(enum_obj, it); return enum_obj; fail1: JS_FreeValue(ctx, enum_obj); fail: JS_FreeValue(ctx, arr); return JS_EXCEPTION; } static JSValue js_array_iterator_next(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, BOOL *pdone, int magic) { JSArrayIteratorData *it; uint32_t len, idx; JSValue val, obj; JSObject *p; it = JS_GetOpaque2(ctx, this_val, JS_CLASS_ARRAY_ITERATOR); if (!it) goto fail1; if (JS_IsUndefined(it->obj)) goto done; p = JS_VALUE_GET_OBJ(it->obj); if (p->class_id >= JS_CLASS_UINT8C_ARRAY && p->class_id <= JS_CLASS_FLOAT64_ARRAY) { if (typed_array_is_oob(p)) { JS_ThrowTypeErrorArrayBufferOOB(ctx); goto fail1; } len = p->u.array.count; } else { if (js_get_length32(ctx, &len, it->obj)) { fail1: *pdone = FALSE; return JS_EXCEPTION; } } idx = it->idx; if (idx >= len) { JS_FreeValue(ctx, it->obj); it->obj = JS_UNDEFINED; done: *pdone = TRUE; return JS_UNDEFINED; } it->idx = idx + 1; *pdone = FALSE; if (it->kind == JS_ITERATOR_KIND_KEY) { return JS_NewUint32(ctx, idx); } else { val = JS_GetPropertyUint32(ctx, it->obj, idx); if (JS_IsException(val)) return JS_EXCEPTION; if (it->kind == JS_ITERATOR_KIND_VALUE) { return val; } else { JSValueConst args[2]; JSValue num; num = JS_NewUint32(ctx, idx); args[0] = num; args[1] = val; obj = js_create_array(ctx, 2, args); JS_FreeValue(ctx, val); JS_FreeValue(ctx, num); return obj; } } } /* Iterator Wrap */ typedef struct JSIteratorWrapData { JSValue wrapped_iter; JSValue wrapped_next; } JSIteratorWrapData; static void js_iterator_wrap_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); JSIteratorWrapData *it = p->u.iterator_wrap_data; if (it) { JS_FreeValueRT(rt, it->wrapped_iter); JS_FreeValueRT(rt, it->wrapped_next); js_free_rt(rt, it); } } static void js_iterator_wrap_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); JSIteratorWrapData *it = p->u.iterator_wrap_data; if (it) { JS_MarkValue(rt, it->wrapped_iter, mark_func); JS_MarkValue(rt, it->wrapped_next, mark_func); } } static JSValue js_iterator_wrap_next(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int *pdone, int magic) { JSIteratorWrapData *it; JSValue method, ret; it = JS_GetOpaque2(ctx, this_val, JS_CLASS_ITERATOR_WRAP); if (!it) return JS_EXCEPTION; if (magic == GEN_MAGIC_NEXT) { return JS_IteratorNext(ctx, it->wrapped_iter, it->wrapped_next, 0, NULL, pdone); } else { method = JS_GetProperty(ctx, it->wrapped_iter, JS_ATOM_return); if (JS_IsException(method)) return JS_EXCEPTION; if (JS_IsNull(method) || JS_IsUndefined(method)) { *pdone = TRUE; return JS_UNDEFINED; } ret = JS_IteratorNext2(ctx, it->wrapped_iter, method, 0, NULL, pdone); JS_FreeValue(ctx, method); return ret; } } static const JSCFunctionListEntry js_iterator_wrap_proto_funcs[] = { JS_ITERATOR_NEXT_DEF("next", 0, js_iterator_wrap_next, GEN_MAGIC_NEXT ), JS_ITERATOR_NEXT_DEF("return", 0, js_iterator_wrap_next, GEN_MAGIC_RETURN ), }; /* Iterator */ static JSValue js_iterator_constructor_getset(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data) { int ret; if (argc > 0) { // if setter if (!JS_IsObject(argv[0])) return JS_ThrowTypeErrorNotAnObject(ctx); ret = JS_DefinePropertyValue(ctx, this_val, JS_ATOM_constructor, JS_DupValue(ctx, argv[0]), JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); if (ret < 0) return JS_EXCEPTION; return JS_UNDEFINED; } else { return JS_DupValue(ctx, func_data[0]); } } static JSValue js_iterator_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { JSObject *p; if (JS_TAG_OBJECT != JS_VALUE_GET_TAG(new_target)) return JS_ThrowTypeError(ctx, "constructor requires 'new'"); p = JS_VALUE_GET_OBJ(new_target); if (p->class_id == JS_CLASS_C_FUNCTION && p->u.cfunc.c_function.generic == js_iterator_constructor) { return JS_ThrowTypeError(ctx, "abstract class not constructable"); } return js_create_from_ctor(ctx, new_target, JS_CLASS_ITERATOR); } // note: deliberately doesn't use space-saving bit fields for // |index|, |count| and |running| because tcc miscompiles them typedef struct JSIteratorConcatData { int index, count; // elements (not pairs!) in values[] array BOOL running; JSValue iter, next, values[]; // array of (object, method) pairs } JSIteratorConcatData; static void js_iterator_concat_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); JSIteratorConcatData *it = p->u.iterator_concat_data; if (it) { JS_FreeValueRT(rt, it->iter); JS_FreeValueRT(rt, it->next); for (int i = it->index; i < it->count; i++) JS_FreeValueRT(rt, it->values[i]); js_free_rt(rt, it); } } static void js_iterator_concat_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); JSIteratorConcatData *it = p->u.iterator_concat_data; if (it) { JS_MarkValue(rt, it->iter, mark_func); JS_MarkValue(rt, it->next, mark_func); for (int i = it->index; i < it->count; i++) JS_MarkValue(rt, it->values[i], mark_func); } } static JSValue js_iterator_concat_next(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int *pdone, int magic) { JSValue iter, item, next, val, *obj, *meth, ret; JSIteratorConcatData *it; int done; *pdone = FALSE; it = JS_GetOpaque2(ctx, this_val, JS_CLASS_ITERATOR_CONCAT); if (!it) return JS_EXCEPTION; if (it->running) return JS_ThrowTypeError(ctx, "already running"); it->running = TRUE; for(;;) { if (it->index >= it->count) { *pdone = TRUE; ret = JS_UNDEFINED; break; } obj = &it->values[it->index + 0]; meth = &it->values[it->index + 1]; iter = it->iter; if (JS_IsUndefined(iter)) { iter = JS_GetIterator2(ctx, *obj, *meth); if (JS_IsException(iter)) goto fail; it->iter = iter; } next = it->next; if (JS_IsUndefined(next)) { next = JS_GetProperty(ctx, iter, JS_ATOM_next); if (JS_IsException(next)) goto fail; it->next = next; } item = JS_IteratorNext2(ctx, iter, next, 0, NULL, &done); if (JS_IsException(item)) goto fail; if (done == 0) { ret = item; break; } else if (done == 2) { val = JS_GetProperty(ctx, item, JS_ATOM_done); if (JS_IsException(val)) { JS_FreeValue(ctx, item); fail: ret = JS_EXCEPTION; break; } done = JS_ToBoolFree(ctx, val); if (done) goto done_next; ret = JS_GetProperty(ctx, item, JS_ATOM_value); JS_FreeValue(ctx, item); break; } else { done_next: JS_FreeValue(ctx, item); JS_FreeValue(ctx, iter); JS_FreeValue(ctx, next); it->iter = JS_UNDEFINED; it->next = JS_UNDEFINED; JS_FreeValue(ctx, *meth); JS_FreeValue(ctx, *obj); it->index += 2; } } it->running = FALSE; return ret; } static JSValue js_iterator_concat_return(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSIteratorConcatData *it; JSValue ret; it = JS_GetOpaque2(ctx, this_val, JS_CLASS_ITERATOR_CONCAT); if (!it) return JS_EXCEPTION; if (it->running) return JS_ThrowTypeError(ctx, "already running"); ret = JS_UNDEFINED; if (!JS_IsUndefined(it->iter)) { it->running = TRUE; ret = JS_GetProperty(ctx, it->iter, JS_ATOM_return); if (JS_IsException(ret)) { it->running = FALSE; return JS_EXCEPTION; } ret = JS_CallFree(ctx, ret, it->iter, 0, NULL); it->running = FALSE; } while (it->index < it->count) JS_FreeValue(ctx, it->values[it->index++]); JS_FreeValue(ctx, it->iter); JS_FreeValue(ctx, it->next); it->iter = JS_UNDEFINED; it->next = JS_UNDEFINED; return ret; } static const JSCFunctionListEntry js_iterator_concat_proto_funcs[] = { JS_ITERATOR_NEXT_DEF("next", 0, js_iterator_concat_next, 0 ), JS_CFUNC_DEF("return", 0, js_iterator_concat_return ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Iterator Concat", JS_PROP_CONFIGURABLE ), }; static JSValue js_iterator_concat(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSIteratorConcatData *it; JSValue obj, method; it = js_malloc(ctx, sizeof(*it) + 2*argc * sizeof(it->values[0])); if (!it) return JS_EXCEPTION; it->running = FALSE; it->index = 0; it->count = 0; it->iter = JS_UNDEFINED; it->next = JS_UNDEFINED; for (int i = 0; i < argc; i++) { JSValueConst obj = argv[i]; if (!JS_IsObject(obj)) { JS_ThrowTypeErrorNotAnObject(ctx); goto fail; } method = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_iterator); if (JS_IsException(method)) goto fail; if (!JS_IsFunction(ctx, method)) { JS_ThrowTypeError(ctx, "not a function"); JS_FreeValue(ctx, method); goto fail; } it->values[it->count++] = JS_DupValue(ctx, obj); it->values[it->count++] = method; } obj = JS_NewObjectClass(ctx, JS_CLASS_ITERATOR_CONCAT); if (JS_IsException(obj)) goto fail; JS_SetOpaque(obj, it); return obj; fail: for (int i = 0; i < it->count; i++) JS_FreeValue(ctx, it->values[i]); js_free(ctx, it); return JS_EXCEPTION; } static JSValue js_iterator_from(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValueConst obj = argv[0]; JSValue method, iter, wrapper; JSIteratorWrapData *it; int ret; if (!JS_IsObject(obj)) { if (!JS_IsString(obj)) return JS_ThrowTypeError(ctx, "Iterator.from called on non-object"); } method = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_iterator); if (JS_IsException(method)) return JS_EXCEPTION; if (JS_IsNull(method) || JS_IsUndefined(method)) { iter = JS_DupValue(ctx, obj); } else { iter = JS_GetIterator2(ctx, obj, method); JS_FreeValue(ctx, method); if (JS_IsException(iter)) return JS_EXCEPTION; } wrapper = JS_UNDEFINED; method = JS_GetProperty(ctx, iter, JS_ATOM_next); if (JS_IsException(method)) goto fail; ret = JS_OrdinaryIsInstanceOf(ctx, iter, ctx->iterator_ctor); if (ret < 0) goto fail; if (ret) { JS_FreeValue(ctx, method); return iter; } wrapper = JS_NewObjectClass(ctx, JS_CLASS_ITERATOR_WRAP); if (JS_IsException(wrapper)) goto fail; it = js_malloc(ctx, sizeof(*it)); if (!it) goto fail; it->wrapped_iter = iter; it->wrapped_next = method; JS_SetOpaque(wrapper, it); return wrapper; fail: JS_FreeValue(ctx, method); JS_FreeValue(ctx, iter); JS_FreeValue(ctx, wrapper); return JS_EXCEPTION; } typedef enum JSIteratorHelperKindEnum { JS_ITERATOR_HELPER_KIND_DROP, JS_ITERATOR_HELPER_KIND_EVERY, JS_ITERATOR_HELPER_KIND_FILTER, JS_ITERATOR_HELPER_KIND_FIND, JS_ITERATOR_HELPER_KIND_FLAT_MAP, JS_ITERATOR_HELPER_KIND_FOR_EACH, JS_ITERATOR_HELPER_KIND_MAP, JS_ITERATOR_HELPER_KIND_SOME, JS_ITERATOR_HELPER_KIND_TAKE, } JSIteratorHelperKindEnum; typedef struct JSIteratorHelperData { JSValue obj; JSValue next; JSValue func; // predicate (filter) or mapper (flatMap, map) JSValue inner; // innerValue (flatMap) int64_t count; // limit (drop, take) or counter (filter, map, flatMap) JSIteratorHelperKindEnum kind : 8; uint8_t executing : 1; uint8_t done : 1; } JSIteratorHelperData; static JSValue js_create_iterator_helper(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSValueConst func; JSValue obj, method; int64_t count; JSIteratorHelperData *it; if (!JS_IsObject(this_val)) return JS_ThrowTypeErrorNotAnObject(ctx); func = JS_UNDEFINED; count = 0; switch(magic) { case JS_ITERATOR_HELPER_KIND_DROP: case JS_ITERATOR_HELPER_KIND_TAKE: { JSValue v; double dlimit; v = JS_ToNumber(ctx, argv[0]); if (JS_IsException(v)) goto fail; // Check for Infinity. if (JS_ToFloat64(ctx, &dlimit, v)) { JS_FreeValue(ctx, v); goto fail; } if (isnan(dlimit)) { JS_FreeValue(ctx, v); goto range_error; } if (!isfinite(dlimit)) { JS_FreeValue(ctx, v); if (dlimit < 0) goto range_error; else count = MAX_SAFE_INTEGER; } else { v = JS_ToIntegerFree(ctx, v); if (JS_IsException(v)) goto fail; if (JS_ToInt64Free(ctx, &count, v)) goto fail; } if (count < 0) goto range_error; } break; case JS_ITERATOR_HELPER_KIND_FILTER: case JS_ITERATOR_HELPER_KIND_FLAT_MAP: case JS_ITERATOR_HELPER_KIND_MAP: { func = argv[0]; if (check_function(ctx, func)) goto fail; } break; default: abort(); break; } method = JS_GetProperty(ctx, this_val, JS_ATOM_next); if (JS_IsException(method)) goto fail; obj = JS_NewObjectClass(ctx, JS_CLASS_ITERATOR_HELPER); if (JS_IsException(obj)) { JS_FreeValue(ctx, method); goto fail; } it = js_malloc(ctx, sizeof(*it)); if (!it) { JS_FreeValue(ctx, obj); JS_FreeValue(ctx, method); goto fail; } it->kind = magic; it->obj = JS_DupValue(ctx, this_val); it->func = JS_DupValue(ctx, func); it->next = method; it->inner = JS_UNDEFINED; it->count = count; it->executing = 0; it->done = 0; JS_SetOpaque(obj, it); return obj; range_error: JS_ThrowRangeError(ctx, "must be positive"); fail: JS_IteratorClose(ctx, this_val, TRUE); return JS_EXCEPTION; } static JSValue js_iterator_proto_func(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSValue item, method, ret, func, index_val, r; JSValueConst args[2]; int64_t idx; int done; if (!JS_IsObject(this_val)) return JS_ThrowTypeErrorNotAnObject(ctx); func = JS_UNDEFINED; method = JS_UNDEFINED; if (check_function(ctx, argv[0])) goto fail; func = JS_DupValue(ctx, argv[0]); method = JS_GetProperty(ctx, this_val, JS_ATOM_next); if (JS_IsException(method)) goto fail_no_close; r = JS_UNDEFINED; switch(magic) { case JS_ITERATOR_HELPER_KIND_EVERY: { r = JS_TRUE; for (idx = 0; /*empty*/; idx++) { item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); if (JS_IsException(item)) goto fail_no_close; if (done) break; index_val = JS_NewInt64(ctx, idx); args[0] = item; args[1] = index_val; ret = JS_Call(ctx, func, JS_UNDEFINED, countof(args), args); JS_FreeValue(ctx, item); JS_FreeValue(ctx, index_val); if (JS_IsException(ret)) goto fail; if (!JS_ToBoolFree(ctx, ret)) { if (JS_IteratorClose(ctx, this_val, FALSE) < 0) r = JS_EXCEPTION; else r = JS_FALSE; break; } index_val = JS_UNDEFINED; ret = JS_UNDEFINED; item = JS_UNDEFINED; } } break; case JS_ITERATOR_HELPER_KIND_FIND: { for (idx = 0; /*empty*/; idx++) { item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); if (JS_IsException(item)) goto fail_no_close; if (done) break; index_val = JS_NewInt64(ctx, idx); args[0] = item; args[1] = index_val; ret = JS_Call(ctx, func, JS_UNDEFINED, countof(args), args); JS_FreeValue(ctx, index_val); if (JS_IsException(ret)) { JS_FreeValue(ctx, item); goto fail; } if (JS_ToBoolFree(ctx, ret)) { if (JS_IteratorClose(ctx, this_val, FALSE) < 0) { JS_FreeValue(ctx, item); r = JS_EXCEPTION; } else { r = item; } break; } JS_FreeValue(ctx, item); index_val = JS_UNDEFINED; ret = JS_UNDEFINED; item = JS_UNDEFINED; } } break; case JS_ITERATOR_HELPER_KIND_FOR_EACH: { for (idx = 0; /*empty*/; idx++) { item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); if (JS_IsException(item)) goto fail_no_close; if (done) break; index_val = JS_NewInt64(ctx, idx); args[0] = item; args[1] = index_val; ret = JS_Call(ctx, func, JS_UNDEFINED, countof(args), args); JS_FreeValue(ctx, item); JS_FreeValue(ctx, index_val); if (JS_IsException(ret)) goto fail; JS_FreeValue(ctx, ret); index_val = JS_UNDEFINED; ret = JS_UNDEFINED; item = JS_UNDEFINED; } } break; case JS_ITERATOR_HELPER_KIND_SOME: { r = JS_FALSE; for (idx = 0; /*empty*/; idx++) { item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); if (JS_IsException(item)) goto fail_no_close; if (done) break; index_val = JS_NewInt64(ctx, idx); args[0] = item; args[1] = index_val; ret = JS_Call(ctx, func, JS_UNDEFINED, countof(args), args); JS_FreeValue(ctx, item); JS_FreeValue(ctx, index_val); if (JS_IsException(ret)) goto fail; if (JS_ToBoolFree(ctx, ret)) { if (JS_IteratorClose(ctx, this_val, FALSE) < 0) r = JS_EXCEPTION; else r = JS_TRUE; break; } index_val = JS_UNDEFINED; ret = JS_UNDEFINED; item = JS_UNDEFINED; } } break; default: abort(); break; } JS_FreeValue(ctx, func); JS_FreeValue(ctx, method); return r; fail: JS_IteratorClose(ctx, this_val, TRUE); fail_no_close: JS_FreeValue(ctx, func); JS_FreeValue(ctx, method); return JS_EXCEPTION; } static JSValue js_iterator_proto_reduce(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue item, method, ret, func, index_val, acc; JSValueConst args[3]; int64_t idx; int done; if (!JS_IsObject(this_val)) return JS_ThrowTypeErrorNotAnObject(ctx); acc = JS_UNDEFINED; func = JS_UNDEFINED; method = JS_UNDEFINED; if (check_function(ctx, argv[0])) goto exception; func = JS_DupValue(ctx, argv[0]); method = JS_GetProperty(ctx, this_val, JS_ATOM_next); if (JS_IsException(method)) goto exception; if (argc > 1) { acc = JS_DupValue(ctx, argv[1]); idx = 0; } else { acc = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); if (JS_IsException(acc)) goto exception_no_close; if (done) { JS_ThrowTypeError(ctx, "empty iterator"); goto exception; } idx = 1; } for (/* empty */; /*empty*/; idx++) { item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); if (JS_IsException(item)) goto exception_no_close; if (done) break; index_val = JS_NewInt64(ctx, idx); args[0] = acc; args[1] = item; args[2] = index_val; ret = JS_Call(ctx, func, JS_UNDEFINED, countof(args), args); JS_FreeValue(ctx, item); JS_FreeValue(ctx, index_val); if (JS_IsException(ret)) goto exception; JS_FreeValue(ctx, acc); acc = ret; index_val = JS_UNDEFINED; ret = JS_UNDEFINED; item = JS_UNDEFINED; } JS_FreeValue(ctx, func); JS_FreeValue(ctx, method); return acc; exception: JS_IteratorClose(ctx, this_val, TRUE); exception_no_close: JS_FreeValue(ctx, acc); JS_FreeValue(ctx, func); JS_FreeValue(ctx, method); return JS_EXCEPTION; } static JSValue js_iterator_proto_toArray(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue item, method, result; int64_t idx; int done; result = JS_UNDEFINED; if (!JS_IsObject(this_val)) return JS_ThrowTypeErrorNotAnObject(ctx); method = JS_GetProperty(ctx, this_val, JS_ATOM_next); if (JS_IsException(method)) return JS_EXCEPTION; result = JS_NewArray(ctx); if (JS_IsException(result)) goto exception; for (idx = 0; /*empty*/; idx++) { item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); if (JS_IsException(item)) goto exception; if (done) break; if (JS_DefinePropertyValueInt64(ctx, result, idx, item, JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception; } if (JS_SetProperty(ctx, result, JS_ATOM_length, JS_NewUint32(ctx, idx)) < 0) goto exception; JS_FreeValue(ctx, method); return result; exception: JS_FreeValue(ctx, result); JS_FreeValue(ctx, method); return JS_EXCEPTION; } static JSValue js_iterator_proto_iterator(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return JS_DupValue(ctx, this_val); } static JSValue js_iterator_proto_get_toStringTag(JSContext *ctx, JSValueConst this_val) { return JS_AtomToString(ctx, JS_ATOM_Iterator); } static JSValue js_iterator_proto_set_toStringTag(JSContext *ctx, JSValueConst this_val, JSValueConst val) { int res; if (!JS_IsObject(this_val)) return JS_ThrowTypeErrorNotAnObject(ctx); if (js_same_value(ctx, this_val, ctx->class_proto[JS_CLASS_ITERATOR])) return JS_ThrowTypeError(ctx, "Cannot assign to read only property"); res = JS_GetOwnProperty(ctx, NULL, this_val, JS_ATOM_Symbol_toStringTag); if (res < 0) return JS_EXCEPTION; if (res) { if (JS_SetProperty(ctx, this_val, JS_ATOM_Symbol_toStringTag, JS_DupValue(ctx, val)) < 0) return JS_EXCEPTION; } else { if (JS_DefinePropertyValue(ctx, this_val, JS_ATOM_Symbol_toStringTag, JS_DupValue(ctx, val), JS_PROP_C_W_E) < 0) return JS_EXCEPTION; } return JS_UNDEFINED; } /* Iterator Helper */ static void js_iterator_helper_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); JSIteratorHelperData *it = p->u.iterator_helper_data; if (it) { JS_FreeValueRT(rt, it->obj); JS_FreeValueRT(rt, it->func); JS_FreeValueRT(rt, it->next); JS_FreeValueRT(rt, it->inner); js_free_rt(rt, it); } } static void js_iterator_helper_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); JSIteratorHelperData *it = p->u.iterator_helper_data; if (it) { JS_MarkValue(rt, it->obj, mark_func); JS_MarkValue(rt, it->func, mark_func); JS_MarkValue(rt, it->next, mark_func); JS_MarkValue(rt, it->inner, mark_func); } } static JSValue js_iterator_helper_next(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int *pdone, int magic) { JSIteratorHelperData *it; JSValue ret; *pdone = FALSE; it = JS_GetOpaque2(ctx, this_val, JS_CLASS_ITERATOR_HELPER); if (!it) return JS_EXCEPTION; if (it->executing) return JS_ThrowTypeError(ctx, "cannot invoke a running iterator"); if (it->done) { *pdone = TRUE; return JS_UNDEFINED; } it->executing = 1; switch (it->kind) { case JS_ITERATOR_HELPER_KIND_DROP: { JSValue item, method; if (magic == GEN_MAGIC_NEXT) { method = JS_DupValue(ctx, it->next); } else { method = JS_GetProperty(ctx, it->obj, JS_ATOM_return); if (JS_IsException(method)) goto fail; } while (it->count > 0) { it->count--; item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone); if (JS_IsException(item)) { JS_FreeValue(ctx, method); goto fail_no_close; } JS_FreeValue(ctx, item); if (magic == GEN_MAGIC_RETURN) *pdone = TRUE; if (*pdone) { JS_FreeValue(ctx, method); ret = JS_UNDEFINED; goto done; } } item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone); JS_FreeValue(ctx, method); if (JS_IsException(item)) goto fail_no_close; ret = item; goto done; } break; case JS_ITERATOR_HELPER_KIND_FILTER: { JSValue item, method, selected, index_val; JSValueConst args[2]; if (magic == GEN_MAGIC_NEXT) { method = JS_DupValue(ctx, it->next); } else { method = JS_GetProperty(ctx, it->obj, JS_ATOM_return); if (JS_IsException(method)) goto fail; } filter_again: item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone); if (JS_IsException(item)) { JS_FreeValue(ctx, method); goto fail_no_close; } if (*pdone || magic == GEN_MAGIC_RETURN) { JS_FreeValue(ctx, method); ret = item; goto done; } index_val = JS_NewInt64(ctx, it->count++); args[0] = item; args[1] = index_val; selected = JS_Call(ctx, it->func, JS_UNDEFINED, countof(args), args); JS_FreeValue(ctx, index_val); if (JS_IsException(selected)) { JS_FreeValue(ctx, item); JS_FreeValue(ctx, method); goto fail; } if (JS_ToBoolFree(ctx, selected)) { JS_FreeValue(ctx, method); ret = item; goto done; } JS_FreeValue(ctx, item); goto filter_again; } break; case JS_ITERATOR_HELPER_KIND_FLAT_MAP: { JSValue item, method, index_val, iter; JSValueConst args[2]; flat_map_again: if (JS_IsUndefined(it->inner)) { if (magic == GEN_MAGIC_NEXT) { method = JS_DupValue(ctx, it->next); } else { method = JS_GetProperty(ctx, it->obj, JS_ATOM_return); if (JS_IsException(method)) goto fail; } item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone); JS_FreeValue(ctx, method); if (JS_IsException(item)) goto fail_no_close; if (*pdone || magic == GEN_MAGIC_RETURN) { ret = item; goto done; } index_val = JS_NewInt64(ctx, it->count++); args[0] = item; args[1] = index_val; ret = JS_Call(ctx, it->func, JS_UNDEFINED, countof(args), args); JS_FreeValue(ctx, item); JS_FreeValue(ctx, index_val); if (JS_IsException(ret)) goto fail; if (!JS_IsObject(ret)) { JS_FreeValue(ctx, ret); JS_ThrowTypeError(ctx, "not an object"); goto fail; } method = JS_GetProperty(ctx, ret, JS_ATOM_Symbol_iterator); if (JS_IsException(method)) { JS_FreeValue(ctx, ret); goto fail; } if (JS_IsNull(method) || JS_IsUndefined(method)) { JS_FreeValue(ctx, method); iter = ret; } else { iter = JS_GetIterator2(ctx, ret, method); JS_FreeValue(ctx, method); JS_FreeValue(ctx, ret); if (JS_IsException(iter)) goto fail; } it->inner = iter; } if (magic == GEN_MAGIC_NEXT) method = JS_GetProperty(ctx, it->inner, JS_ATOM_next); else method = JS_GetProperty(ctx, it->inner, JS_ATOM_return); if (JS_IsException(method)) { inner_fail: JS_IteratorClose(ctx, it->inner, FALSE); JS_FreeValue(ctx, it->inner); it->inner = JS_UNDEFINED; goto fail; } if (magic == GEN_MAGIC_RETURN && (JS_IsUndefined(method) || JS_IsNull(method))) { goto inner_end; } else { item = JS_IteratorNext(ctx, it->inner, method, 0, NULL, pdone); JS_FreeValue(ctx, method); if (JS_IsException(item)) goto inner_fail; } if (*pdone) { inner_end: *pdone = FALSE; // The outer iterator must continue. JS_IteratorClose(ctx, it->inner, FALSE); JS_FreeValue(ctx, it->inner); it->inner = JS_UNDEFINED; goto flat_map_again; } ret = item; goto done; } break; case JS_ITERATOR_HELPER_KIND_MAP: { JSValue item, method, index_val; JSValueConst args[2]; if (magic == GEN_MAGIC_NEXT) { method = JS_DupValue(ctx, it->next); } else { method = JS_GetProperty(ctx, it->obj, JS_ATOM_return); if (JS_IsException(method)) goto fail; } item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone); JS_FreeValue(ctx, method); if (JS_IsException(item)) goto fail_no_close; if (*pdone || magic == GEN_MAGIC_RETURN) { ret = item; goto done; } index_val = JS_NewInt64(ctx, it->count++); args[0] = item; args[1] = index_val; ret = JS_Call(ctx, it->func, JS_UNDEFINED, countof(args), args); JS_FreeValue(ctx, index_val); JS_FreeValue(ctx, item); if (JS_IsException(ret)) goto fail; goto done; } break; case JS_ITERATOR_HELPER_KIND_TAKE: { JSValue item, method; if (it->count > 0) { if (magic == GEN_MAGIC_NEXT) { method = JS_DupValue(ctx, it->next); } else { method = JS_GetProperty(ctx, it->obj, JS_ATOM_return); if (JS_IsException(method)) goto fail; } it->count--; item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone); JS_FreeValue(ctx, method); if (JS_IsException(item)) goto fail_no_close; ret = item; goto done; } *pdone = TRUE; if (JS_IteratorClose(ctx, it->obj, FALSE)) ret = JS_EXCEPTION; else ret = JS_UNDEFINED; goto done; } break; default: abort(); } done: it->done = magic == GEN_MAGIC_NEXT ? *pdone : 1; it->executing = 0; return ret; fail: /* close the iterator object, preserving pending exception */ JS_IteratorClose(ctx, it->obj, TRUE); fail_no_close: ret = JS_EXCEPTION; goto done; } static const JSCFunctionListEntry js_iterator_funcs[] = { JS_CFUNC_DEF("concat", 0, js_iterator_concat ), JS_CFUNC_DEF("from", 1, js_iterator_from ), }; static const JSCFunctionListEntry js_iterator_proto_funcs[] = { JS_CFUNC_MAGIC_DEF("drop", 1, js_create_iterator_helper, JS_ITERATOR_HELPER_KIND_DROP ), JS_CFUNC_MAGIC_DEF("filter", 1, js_create_iterator_helper, JS_ITERATOR_HELPER_KIND_FILTER ), JS_CFUNC_MAGIC_DEF("flatMap", 1, js_create_iterator_helper, JS_ITERATOR_HELPER_KIND_FLAT_MAP ), JS_CFUNC_MAGIC_DEF("map", 1, js_create_iterator_helper, JS_ITERATOR_HELPER_KIND_MAP ), JS_CFUNC_MAGIC_DEF("take", 1, js_create_iterator_helper, JS_ITERATOR_HELPER_KIND_TAKE ), JS_CFUNC_MAGIC_DEF("every", 1, js_iterator_proto_func, JS_ITERATOR_HELPER_KIND_EVERY ), JS_CFUNC_MAGIC_DEF("find", 1, js_iterator_proto_func, JS_ITERATOR_HELPER_KIND_FIND), JS_CFUNC_MAGIC_DEF("forEach", 1, js_iterator_proto_func, JS_ITERATOR_HELPER_KIND_FOR_EACH ), JS_CFUNC_MAGIC_DEF("some", 1, js_iterator_proto_func, JS_ITERATOR_HELPER_KIND_SOME ), JS_CFUNC_DEF("reduce", 1, js_iterator_proto_reduce ), JS_CFUNC_DEF("toArray", 0, js_iterator_proto_toArray ), JS_CFUNC_DEF("[Symbol.iterator]", 0, js_iterator_proto_iterator ), JS_CGETSET_DEF("[Symbol.toStringTag]", js_iterator_proto_get_toStringTag, js_iterator_proto_set_toStringTag), }; static const JSCFunctionListEntry js_iterator_helper_proto_funcs[] = { JS_ITERATOR_NEXT_DEF("next", 0, js_iterator_helper_next, GEN_MAGIC_NEXT ), JS_ITERATOR_NEXT_DEF("return", 0, js_iterator_helper_next, GEN_MAGIC_RETURN ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Iterator Helper", JS_PROP_CONFIGURABLE ), }; static const JSCFunctionListEntry js_array_unscopables_funcs[] = { JS_PROP_BOOL_DEF("at", TRUE, JS_PROP_C_W_E), JS_PROP_BOOL_DEF("copyWithin", TRUE, JS_PROP_C_W_E), JS_PROP_BOOL_DEF("entries", TRUE, JS_PROP_C_W_E), JS_PROP_BOOL_DEF("fill", TRUE, JS_PROP_C_W_E), JS_PROP_BOOL_DEF("find", TRUE, JS_PROP_C_W_E), JS_PROP_BOOL_DEF("findIndex", TRUE, JS_PROP_C_W_E), JS_PROP_BOOL_DEF("findLast", TRUE, JS_PROP_C_W_E), JS_PROP_BOOL_DEF("findLastIndex", TRUE, JS_PROP_C_W_E), JS_PROP_BOOL_DEF("flat", TRUE, JS_PROP_C_W_E), JS_PROP_BOOL_DEF("flatMap", TRUE, JS_PROP_C_W_E), JS_PROP_BOOL_DEF("includes", TRUE, JS_PROP_C_W_E), JS_PROP_BOOL_DEF("keys", TRUE, JS_PROP_C_W_E), JS_PROP_BOOL_DEF("toReversed", TRUE, JS_PROP_C_W_E), JS_PROP_BOOL_DEF("toSorted", TRUE, JS_PROP_C_W_E), JS_PROP_BOOL_DEF("toSpliced", TRUE, JS_PROP_C_W_E), JS_PROP_BOOL_DEF("values", TRUE, JS_PROP_C_W_E), }; static const JSCFunctionListEntry js_array_proto_funcs[] = { JS_CFUNC_DEF("at", 1, js_array_at ), JS_CFUNC_DEF("with", 2, js_array_with ), JS_CFUNC_DEF("concat", 1, js_array_concat ), JS_CFUNC_MAGIC_DEF("every", 1, js_array_every, special_every ), JS_CFUNC_MAGIC_DEF("some", 1, js_array_every, special_some ), JS_CFUNC_MAGIC_DEF("forEach", 1, js_array_every, special_forEach ), JS_CFUNC_MAGIC_DEF("map", 1, js_array_every, special_map ), JS_CFUNC_MAGIC_DEF("filter", 1, js_array_every, special_filter ), JS_CFUNC_MAGIC_DEF("reduce", 1, js_array_reduce, special_reduce ), JS_CFUNC_MAGIC_DEF("reduceRight", 1, js_array_reduce, special_reduceRight ), JS_CFUNC_DEF("fill", 1, js_array_fill ), JS_CFUNC_MAGIC_DEF("find", 1, js_array_find, ArrayFind ), JS_CFUNC_MAGIC_DEF("findIndex", 1, js_array_find, ArrayFindIndex ), JS_CFUNC_MAGIC_DEF("findLast", 1, js_array_find, ArrayFindLast ), JS_CFUNC_MAGIC_DEF("findLastIndex", 1, js_array_find, ArrayFindLastIndex ), JS_CFUNC_DEF("indexOf", 1, js_array_indexOf ), JS_CFUNC_DEF("lastIndexOf", 1, js_array_lastIndexOf ), JS_CFUNC_DEF("includes", 1, js_array_includes ), JS_CFUNC_MAGIC_DEF("join", 1, js_array_join, 0 ), JS_CFUNC_DEF("toString", 0, js_array_toString ), JS_CFUNC_MAGIC_DEF("toLocaleString", 0, js_array_join, 1 ), JS_CFUNC_MAGIC_DEF("pop", 0, js_array_pop, 0 ), JS_CFUNC_MAGIC_DEF("push", 1, js_array_push, 0 ), JS_CFUNC_MAGIC_DEF("shift", 0, js_array_pop, 1 ), JS_CFUNC_MAGIC_DEF("unshift", 1, js_array_push, 1 ), JS_CFUNC_DEF("reverse", 0, js_array_reverse ), JS_CFUNC_DEF("toReversed", 0, js_array_toReversed ), JS_CFUNC_DEF("sort", 1, js_array_sort ), JS_CFUNC_DEF("toSorted", 1, js_array_toSorted ), JS_CFUNC_MAGIC_DEF("slice", 2, js_array_slice, 0 ), JS_CFUNC_MAGIC_DEF("splice", 2, js_array_slice, 1 ), JS_CFUNC_DEF("toSpliced", 2, js_array_toSpliced ), JS_CFUNC_DEF("copyWithin", 2, js_array_copyWithin ), JS_CFUNC_MAGIC_DEF("flatMap", 1, js_array_flatten, 1 ), JS_CFUNC_MAGIC_DEF("flat", 0, js_array_flatten, 0 ), JS_CFUNC_MAGIC_DEF("values", 0, js_create_array_iterator, JS_ITERATOR_KIND_VALUE ), JS_ALIAS_DEF("[Symbol.iterator]", "values" ), JS_CFUNC_MAGIC_DEF("keys", 0, js_create_array_iterator, JS_ITERATOR_KIND_KEY ), JS_CFUNC_MAGIC_DEF("entries", 0, js_create_array_iterator, JS_ITERATOR_KIND_KEY_AND_VALUE ), JS_OBJECT_DEF("[Symbol.unscopables]", js_array_unscopables_funcs, countof(js_array_unscopables_funcs), JS_PROP_CONFIGURABLE ), }; static const JSCFunctionListEntry js_array_iterator_proto_funcs[] = { JS_ITERATOR_NEXT_DEF("next", 0, js_array_iterator_next, 0 ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Array Iterator", JS_PROP_CONFIGURABLE ), }; /* Number */ static JSValue js_number_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { JSValue val, obj; if (argc == 0) { val = JS_NewInt32(ctx, 0); } else { val = JS_ToNumeric(ctx, argv[0]); if (JS_IsException(val)) return val; switch(JS_VALUE_GET_TAG(val)) { case JS_TAG_SHORT_BIG_INT: val = JS_NewInt64(ctx, JS_VALUE_GET_SHORT_BIG_INT(val)); if (JS_IsException(val)) return val; break; case JS_TAG_BIG_INT: { JSBigInt *p = JS_VALUE_GET_PTR(val); double d; d = js_bigint_to_float64(ctx, p); JS_FreeValue(ctx, val); val = JS_NewFloat64(ctx, d); } break; default: break; } } if (!JS_IsUndefined(new_target)) { obj = js_create_from_ctor(ctx, new_target, JS_CLASS_NUMBER); if (!JS_IsException(obj)) JS_SetObjectData(ctx, obj, val); return obj; } else { return val; } } #if 0 static JSValue js_number___toInteger(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return JS_ToIntegerFree(ctx, JS_DupValue(ctx, argv[0])); } static JSValue js_number___toLength(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { int64_t v; if (JS_ToLengthFree(ctx, &v, JS_DupValue(ctx, argv[0]))) return JS_EXCEPTION; return JS_NewInt64(ctx, v); } #endif static JSValue js_number_isNaN(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { if (!JS_IsNumber(argv[0])) return JS_FALSE; return js_global_isNaN(ctx, this_val, argc, argv); } static JSValue js_number_isFinite(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { if (!JS_IsNumber(argv[0])) return JS_FALSE; return js_global_isFinite(ctx, this_val, argc, argv); } static JSValue js_number_isInteger(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { int ret; ret = JS_NumberIsInteger(ctx, argv[0]); if (ret < 0) return JS_EXCEPTION; else return JS_NewBool(ctx, ret); } static JSValue js_number_isSafeInteger(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { double d; if (!JS_IsNumber(argv[0])) return JS_FALSE; if (unlikely(JS_ToFloat64(ctx, &d, argv[0]))) return JS_EXCEPTION; return JS_NewBool(ctx, is_safe_integer(d)); } static const JSCFunctionListEntry js_number_funcs[] = { /* global ParseInt and parseFloat should be defined already or delayed */ JS_ALIAS_BASE_DEF("parseInt", "parseInt", 0 ), JS_ALIAS_BASE_DEF("parseFloat", "parseFloat", 0 ), JS_CFUNC_DEF("isNaN", 1, js_number_isNaN ), JS_CFUNC_DEF("isFinite", 1, js_number_isFinite ), JS_CFUNC_DEF("isInteger", 1, js_number_isInteger ), JS_CFUNC_DEF("isSafeInteger", 1, js_number_isSafeInteger ), JS_PROP_DOUBLE_DEF("MAX_VALUE", 1.7976931348623157e+308, 0 ), JS_PROP_DOUBLE_DEF("MIN_VALUE", 5e-324, 0 ), JS_PROP_DOUBLE_DEF("NaN", NAN, 0 ), JS_PROP_DOUBLE_DEF("NEGATIVE_INFINITY", -INFINITY, 0 ), JS_PROP_DOUBLE_DEF("POSITIVE_INFINITY", INFINITY, 0 ), JS_PROP_DOUBLE_DEF("EPSILON", 2.220446049250313e-16, 0 ), /* ES6 */ JS_PROP_DOUBLE_DEF("MAX_SAFE_INTEGER", 9007199254740991.0, 0 ), /* ES6 */ JS_PROP_DOUBLE_DEF("MIN_SAFE_INTEGER", -9007199254740991.0, 0 ), /* ES6 */ //JS_CFUNC_DEF("__toInteger", 1, js_number___toInteger ), //JS_CFUNC_DEF("__toLength", 1, js_number___toLength ), }; static JSValue js_thisNumberValue(JSContext *ctx, JSValueConst this_val) { if (JS_IsNumber(this_val)) return JS_DupValue(ctx, this_val); if (JS_VALUE_GET_TAG(this_val) == JS_TAG_OBJECT) { JSObject *p = JS_VALUE_GET_OBJ(this_val); if (p->class_id == JS_CLASS_NUMBER) { if (JS_IsNumber(p->u.object_data)) return JS_DupValue(ctx, p->u.object_data); } } return JS_ThrowTypeError(ctx, "not a number"); } static JSValue js_number_valueOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return js_thisNumberValue(ctx, this_val); } static int js_get_radix(JSContext *ctx, JSValueConst val) { int radix; if (JS_ToInt32Sat(ctx, &radix, val)) return -1; if (radix < 2 || radix > 36) { JS_ThrowRangeError(ctx, "radix must be between 2 and 36"); return -1; } return radix; } static JSValue js_number_toString(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSValue val; int base, flags; double d; val = js_thisNumberValue(ctx, this_val); if (JS_IsException(val)) return val; if (magic || JS_IsUndefined(argv[0])) { base = 10; } else { base = js_get_radix(ctx, argv[0]); if (base < 0) goto fail; } if (JS_VALUE_GET_TAG(val) == JS_TAG_INT) { char buf1[70]; int len; len = i64toa_radix(buf1, JS_VALUE_GET_INT(val), base); return js_new_string8_len(ctx, buf1, len); } if (JS_ToFloat64Free(ctx, &d, val)) return JS_EXCEPTION; flags = JS_DTOA_FORMAT_FREE; if (base != 10) flags |= JS_DTOA_EXP_DISABLED; return js_dtoa2(ctx, d, base, 0, flags); fail: JS_FreeValue(ctx, val); return JS_EXCEPTION; } static JSValue js_number_toFixed(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue val; int f, flags; double d; val = js_thisNumberValue(ctx, this_val); if (JS_IsException(val)) return val; if (JS_ToFloat64Free(ctx, &d, val)) return JS_EXCEPTION; if (JS_ToInt32Sat(ctx, &f, argv[0])) return JS_EXCEPTION; if (f < 0 || f > 100) return JS_ThrowRangeError(ctx, "invalid number of digits"); if (fabs(d) >= 1e21) flags = JS_DTOA_FORMAT_FREE; else flags = JS_DTOA_FORMAT_FRAC; return js_dtoa2(ctx, d, 10, f, flags); } static JSValue js_number_toExponential(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue val; int f, flags; double d; val = js_thisNumberValue(ctx, this_val); if (JS_IsException(val)) return val; if (JS_ToFloat64Free(ctx, &d, val)) return JS_EXCEPTION; if (JS_ToInt32Sat(ctx, &f, argv[0])) return JS_EXCEPTION; if (!isfinite(d)) { return JS_ToStringFree(ctx, __JS_NewFloat64(ctx, d)); } if (JS_IsUndefined(argv[0])) { flags = JS_DTOA_FORMAT_FREE; f = 0; } else { if (f < 0 || f > 100) return JS_ThrowRangeError(ctx, "invalid number of digits"); f++; flags = JS_DTOA_FORMAT_FIXED; } return js_dtoa2(ctx, d, 10, f, flags | JS_DTOA_EXP_ENABLED); } static JSValue js_number_toPrecision(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue val; int p; double d; val = js_thisNumberValue(ctx, this_val); if (JS_IsException(val)) return val; if (JS_ToFloat64Free(ctx, &d, val)) return JS_EXCEPTION; if (JS_IsUndefined(argv[0])) goto to_string; if (JS_ToInt32Sat(ctx, &p, argv[0])) return JS_EXCEPTION; if (!isfinite(d)) { to_string: return JS_ToStringFree(ctx, __JS_NewFloat64(ctx, d)); } if (p < 1 || p > 100) return JS_ThrowRangeError(ctx, "invalid number of digits"); return js_dtoa2(ctx, d, 10, p, JS_DTOA_FORMAT_FIXED); } static const JSCFunctionListEntry js_number_proto_funcs[] = { JS_CFUNC_DEF("toExponential", 1, js_number_toExponential ), JS_CFUNC_DEF("toFixed", 1, js_number_toFixed ), JS_CFUNC_DEF("toPrecision", 1, js_number_toPrecision ), JS_CFUNC_MAGIC_DEF("toString", 1, js_number_toString, 0 ), JS_CFUNC_MAGIC_DEF("toLocaleString", 0, js_number_toString, 1 ), JS_CFUNC_DEF("valueOf", 0, js_number_valueOf ), }; static JSValue js_parseInt(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { const char *str, *p; int radix, flags; JSValue ret; str = JS_ToCString(ctx, argv[0]); if (!str) return JS_EXCEPTION; if (JS_ToInt32(ctx, &radix, argv[1])) { JS_FreeCString(ctx, str); return JS_EXCEPTION; } if (radix != 0 && (radix < 2 || radix > 36)) { ret = JS_NAN; } else { p = str; p += skip_spaces(p); flags = ATOD_INT_ONLY | ATOD_ACCEPT_PREFIX_AFTER_SIGN; ret = js_atof(ctx, p, NULL, radix, flags); } JS_FreeCString(ctx, str); return ret; } static JSValue js_parseFloat(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { const char *str, *p; JSValue ret; str = JS_ToCString(ctx, argv[0]); if (!str) return JS_EXCEPTION; p = str; p += skip_spaces(p); ret = js_atof(ctx, p, NULL, 10, 0); JS_FreeCString(ctx, str); return ret; } /* Boolean */ static JSValue js_boolean_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { JSValue val, obj; val = JS_NewBool(ctx, JS_ToBool(ctx, argv[0])); if (!JS_IsUndefined(new_target)) { obj = js_create_from_ctor(ctx, new_target, JS_CLASS_BOOLEAN); if (!JS_IsException(obj)) JS_SetObjectData(ctx, obj, val); return obj; } else { return val; } } static JSValue js_thisBooleanValue(JSContext *ctx, JSValueConst this_val) { if (JS_VALUE_GET_TAG(this_val) == JS_TAG_BOOL) return JS_DupValue(ctx, this_val); if (JS_VALUE_GET_TAG(this_val) == JS_TAG_OBJECT) { JSObject *p = JS_VALUE_GET_OBJ(this_val); if (p->class_id == JS_CLASS_BOOLEAN) { if (JS_VALUE_GET_TAG(p->u.object_data) == JS_TAG_BOOL) return p->u.object_data; } } return JS_ThrowTypeError(ctx, "not a boolean"); } static JSValue js_boolean_toString(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue val = js_thisBooleanValue(ctx, this_val); if (JS_IsException(val)) return val; return JS_AtomToString(ctx, JS_VALUE_GET_BOOL(val) ? JS_ATOM_true : JS_ATOM_false); } static JSValue js_boolean_valueOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return js_thisBooleanValue(ctx, this_val); } static const JSCFunctionListEntry js_boolean_proto_funcs[] = { JS_CFUNC_DEF("toString", 0, js_boolean_toString ), JS_CFUNC_DEF("valueOf", 0, js_boolean_valueOf ), }; /* String */ static int js_string_get_own_property(JSContext *ctx, JSPropertyDescriptor *desc, JSValueConst obj, JSAtom prop) { JSObject *p; JSString *p1; uint32_t idx, ch; /* This is a class exotic method: obj class_id is JS_CLASS_STRING */ if (__JS_AtomIsTaggedInt(prop)) { p = JS_VALUE_GET_OBJ(obj); if (JS_VALUE_GET_TAG(p->u.object_data) == JS_TAG_STRING) { p1 = JS_VALUE_GET_STRING(p->u.object_data); idx = __JS_AtomToUInt32(prop); if (idx < p1->len) { if (desc) { ch = string_get(p1, idx); desc->flags = JS_PROP_ENUMERABLE; desc->value = js_new_string_char(ctx, ch); desc->getter = JS_UNDEFINED; desc->setter = JS_UNDEFINED; } return TRUE; } } } return FALSE; } static int js_string_define_own_property(JSContext *ctx, JSValueConst this_obj, JSAtom prop, JSValueConst val, JSValueConst getter, JSValueConst setter, int flags) { uint32_t idx; JSObject *p; JSString *p1, *p2; if (__JS_AtomIsTaggedInt(prop)) { idx = __JS_AtomToUInt32(prop); p = JS_VALUE_GET_OBJ(this_obj); if (JS_VALUE_GET_TAG(p->u.object_data) != JS_TAG_STRING) goto def; p1 = JS_VALUE_GET_STRING(p->u.object_data); if (idx >= p1->len) goto def; if (!check_define_prop_flags(JS_PROP_ENUMERABLE, flags)) goto fail; /* check that the same value is configured */ if (flags & JS_PROP_HAS_VALUE) { if (JS_VALUE_GET_TAG(val) != JS_TAG_STRING) goto fail; p2 = JS_VALUE_GET_STRING(val); if (p2->len != 1) goto fail; if (string_get(p1, idx) != string_get(p2, 0)) { fail: return JS_ThrowTypeErrorOrFalse(ctx, flags, "property is not configurable"); } } return TRUE; } else { def: return JS_DefineProperty(ctx, this_obj, prop, val, getter, setter, flags | JS_PROP_NO_EXOTIC); } } static int js_string_delete_property(JSContext *ctx, JSValueConst obj, JSAtom prop) { uint32_t idx; if (__JS_AtomIsTaggedInt(prop)) { idx = __JS_AtomToUInt32(prop); if (idx < js_string_obj_get_length(ctx, obj)) { return FALSE; } } return TRUE; } static const JSClassExoticMethods js_string_exotic_methods = { .get_own_property = js_string_get_own_property, .define_own_property = js_string_define_own_property, .delete_property = js_string_delete_property, }; static JSValue js_string_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { JSValue val, obj; if (argc == 0) { val = JS_AtomToString(ctx, JS_ATOM_empty_string); } else { if (JS_IsUndefined(new_target) && JS_IsSymbol(argv[0])) { JSAtomStruct *p = JS_VALUE_GET_PTR(argv[0]); val = JS_ConcatString3(ctx, "Symbol(", JS_AtomToString(ctx, js_get_atom_index(ctx->rt, p)), ")"); } else { val = JS_ToString(ctx, argv[0]); } if (JS_IsException(val)) return val; } if (!JS_IsUndefined(new_target)) { JSString *p1 = JS_VALUE_GET_STRING(val); obj = js_create_from_ctor(ctx, new_target, JS_CLASS_STRING); if (JS_IsException(obj)) { JS_FreeValue(ctx, val); } else { JS_SetObjectData(ctx, obj, val); JS_DefinePropertyValue(ctx, obj, JS_ATOM_length, JS_NewInt32(ctx, p1->len), 0); } return obj; } else { return val; } } static JSValue js_thisStringValue(JSContext *ctx, JSValueConst this_val) { if (JS_VALUE_GET_TAG(this_val) == JS_TAG_STRING || JS_VALUE_GET_TAG(this_val) == JS_TAG_STRING_ROPE) return JS_DupValue(ctx, this_val); if (JS_VALUE_GET_TAG(this_val) == JS_TAG_OBJECT) { JSObject *p = JS_VALUE_GET_OBJ(this_val); if (p->class_id == JS_CLASS_STRING) { if (JS_VALUE_GET_TAG(p->u.object_data) == JS_TAG_STRING) return JS_DupValue(ctx, p->u.object_data); } } return JS_ThrowTypeError(ctx, "not a string"); } static JSValue js_string_fromCharCode(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { int i; StringBuffer b_s, *b = &b_s; string_buffer_init(ctx, b, argc); for(i = 0; i < argc; i++) { int32_t c; if (JS_ToInt32(ctx, &c, argv[i]) || string_buffer_putc16(b, c & 0xffff)) { string_buffer_free(b); return JS_EXCEPTION; } } return string_buffer_end(b); } static JSValue js_string_fromCodePoint(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { double d; int i, c; StringBuffer b_s, *b = &b_s; /* XXX: could pre-compute string length if all arguments are JS_TAG_INT */ if (string_buffer_init(ctx, b, argc)) goto fail; for(i = 0; i < argc; i++) { if (JS_VALUE_GET_TAG(argv[i]) == JS_TAG_INT) { c = JS_VALUE_GET_INT(argv[i]); if (c < 0 || c > 0x10ffff) goto range_error; } else { if (JS_ToFloat64(ctx, &d, argv[i])) goto fail; if (isnan(d) || d < 0 || d > 0x10ffff || (c = (int)d) != d) goto range_error; } if (string_buffer_putc(b, c)) goto fail; } return string_buffer_end(b); range_error: JS_ThrowRangeError(ctx, "invalid code point"); fail: string_buffer_free(b); return JS_EXCEPTION; } static JSValue js_string_raw(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // raw(temp,...a) JSValue cooked, val, raw; StringBuffer b_s, *b = &b_s; int64_t i, n; string_buffer_init(ctx, b, 0); raw = JS_UNDEFINED; cooked = JS_ToObject(ctx, argv[0]); if (JS_IsException(cooked)) goto exception; raw = JS_ToObjectFree(ctx, JS_GetProperty(ctx, cooked, JS_ATOM_raw)); if (JS_IsException(raw)) goto exception; if (js_get_length64(ctx, &n, raw) < 0) goto exception; for (i = 0; i < n; i++) { val = JS_ToStringFree(ctx, JS_GetPropertyInt64(ctx, raw, i)); if (JS_IsException(val)) goto exception; string_buffer_concat_value_free(b, val); if (i < n - 1 && i + 1 < argc) { if (string_buffer_concat_value(b, argv[i + 1])) goto exception; } } JS_FreeValue(ctx, cooked); JS_FreeValue(ctx, raw); return string_buffer_end(b); exception: JS_FreeValue(ctx, cooked); JS_FreeValue(ctx, raw); string_buffer_free(b); return JS_EXCEPTION; } /* only used in test262 */ JSValue js_string_codePointRange(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { uint32_t start, end, i, n; StringBuffer b_s, *b = &b_s; if (JS_ToUint32(ctx, &start, argv[0]) || JS_ToUint32(ctx, &end, argv[1])) return JS_EXCEPTION; end = min_uint32(end, 0x10ffff + 1); if (start > end) { start = end; } n = end - start; if (end > 0x10000) { n += end - max_uint32(start, 0x10000); } if (string_buffer_init2(ctx, b, n, end >= 0x100)) return JS_EXCEPTION; for(i = start; i < end; i++) { string_buffer_putc(b, i); } return string_buffer_end(b); } #if 0 static JSValue js_string___isSpace(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { int c; if (JS_ToInt32(ctx, &c, argv[0])) return JS_EXCEPTION; return JS_NewBool(ctx, lre_is_space(c)); } #endif static JSValue js_string_charCodeAt(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue val, ret; JSString *p; int idx, c; val = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(val)) return val; p = JS_VALUE_GET_STRING(val); if (JS_ToInt32Sat(ctx, &idx, argv[0])) { JS_FreeValue(ctx, val); return JS_EXCEPTION; } if (idx < 0 || idx >= p->len) { ret = JS_NAN; } else { c = string_get(p, idx); ret = JS_NewInt32(ctx, c); } JS_FreeValue(ctx, val); return ret; } static JSValue js_string_charAt(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int is_at) { JSValue val, ret; JSString *p; int idx, c; val = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(val)) return val; p = JS_VALUE_GET_STRING(val); if (JS_ToInt32Sat(ctx, &idx, argv[0])) { JS_FreeValue(ctx, val); return JS_EXCEPTION; } if (idx < 0 && is_at) idx += p->len; if (idx < 0 || idx >= p->len) { if (is_at) ret = JS_UNDEFINED; else ret = JS_AtomToString(ctx, JS_ATOM_empty_string); } else { c = string_get(p, idx); ret = js_new_string_char(ctx, c); } JS_FreeValue(ctx, val); return ret; } static JSValue js_string_codePointAt(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue val, ret; JSString *p; int idx, c; val = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(val)) return val; p = JS_VALUE_GET_STRING(val); if (JS_ToInt32Sat(ctx, &idx, argv[0])) { JS_FreeValue(ctx, val); return JS_EXCEPTION; } if (idx < 0 || idx >= p->len) { ret = JS_UNDEFINED; } else { c = string_getc(p, &idx); ret = JS_NewInt32(ctx, c); } JS_FreeValue(ctx, val); return ret; } static JSValue js_string_concat(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue r; int i; /* XXX: Use more efficient method */ /* XXX: This method is OK if r has a single refcount */ /* XXX: should use string_buffer? */ r = JS_ToStringCheckObject(ctx, this_val); for (i = 0; i < argc; i++) { if (JS_IsException(r)) break; r = JS_ConcatString(ctx, r, JS_DupValue(ctx, argv[i])); } return r; } static int string_cmp(JSString *p1, JSString *p2, int x1, int x2, int len) { int i, c1, c2; for (i = 0; i < len; i++) { if ((c1 = string_get(p1, x1 + i)) != (c2 = string_get(p2, x2 + i))) return c1 - c2; } return 0; } static int string_indexof_char(JSString *p, int c, int from) { /* assuming 0 <= from <= p->len */ int i, len = p->len; if (p->is_wide_char) { for (i = from; i < len; i++) { if (p->u.str16[i] == c) return i; } } else { if ((c & ~0xff) == 0) { for (i = from; i < len; i++) { if (p->u.str8[i] == (uint8_t)c) return i; } } } return -1; } static int string_indexof(JSString *p1, JSString *p2, int from) { /* assuming 0 <= from <= p1->len */ int c, i, j, len1 = p1->len, len2 = p2->len; if (len2 == 0) return from; for (i = from, c = string_get(p2, 0); i + len2 <= len1; i = j + 1) { j = string_indexof_char(p1, c, i); if (j < 0 || j + len2 > len1) break; if (!string_cmp(p1, p2, j + 1, 1, len2 - 1)) return j; } return -1; } static int64_t string_advance_index(JSString *p, int64_t index, BOOL unicode) { if (!unicode || index >= p->len || !p->is_wide_char) { index++; } else { int index32 = (int)index; string_getc(p, &index32); index = index32; } return index; } /* return the position of the first invalid character in the string or -1 if none */ static int js_string_find_invalid_codepoint(JSString *p) { int i; if (!p->is_wide_char) return -1; for(i = 0; i < p->len; i++) { uint32_t c = p->u.str16[i]; if (is_surrogate(c)) { if (is_hi_surrogate(c) && (i + 1) < p->len && is_lo_surrogate(p->u.str16[i + 1])) { i++; } else { return i; } } } return -1; } static JSValue js_string_isWellFormed(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue str; JSString *p; BOOL ret; str = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(str)) return JS_EXCEPTION; p = JS_VALUE_GET_STRING(str); ret = (js_string_find_invalid_codepoint(p) < 0); JS_FreeValue(ctx, str); return JS_NewBool(ctx, ret); } static JSValue js_string_toWellFormed(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue str, ret; JSString *p; int i; str = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(str)) return JS_EXCEPTION; p = JS_VALUE_GET_STRING(str); /* avoid reallocating the string if it is well-formed */ i = js_string_find_invalid_codepoint(p); if (i < 0) return str; ret = js_new_string16_len(ctx, p->u.str16, p->len); JS_FreeValue(ctx, str); if (JS_IsException(ret)) return JS_EXCEPTION; p = JS_VALUE_GET_STRING(ret); for (; i < p->len; i++) { uint32_t c = p->u.str16[i]; if (is_surrogate(c)) { if (is_hi_surrogate(c) && (i + 1) < p->len && is_lo_surrogate(p->u.str16[i + 1])) { i++; } else { p->u.str16[i] = 0xFFFD; } } } return ret; } static JSValue js_string_indexOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int lastIndexOf) { JSValue str, v; int i, len, v_len, pos, start, stop, ret, inc; JSString *p; JSString *p1; str = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(str)) return str; v = JS_ToString(ctx, argv[0]); if (JS_IsException(v)) goto fail; p = JS_VALUE_GET_STRING(str); p1 = JS_VALUE_GET_STRING(v); len = p->len; v_len = p1->len; if (lastIndexOf) { pos = len - v_len; if (argc > 1) { double d; if (JS_ToFloat64(ctx, &d, argv[1])) goto fail; if (!isnan(d)) { if (d <= 0) pos = 0; else if (d < pos) pos = d; } } start = pos; stop = 0; inc = -1; } else { pos = 0; if (argc > 1) { if (JS_ToInt32Clamp(ctx, &pos, argv[1], 0, len, 0)) goto fail; } start = pos; stop = len - v_len; inc = 1; } ret = -1; if (len >= v_len && inc * (stop - start) >= 0) { for (i = start;; i += inc) { if (!string_cmp(p, p1, i, 0, v_len)) { ret = i; break; } if (i == stop) break; } } JS_FreeValue(ctx, str); JS_FreeValue(ctx, v); return JS_NewInt32(ctx, ret); fail: JS_FreeValue(ctx, str); JS_FreeValue(ctx, v); return JS_EXCEPTION; } /* return < 0 if exception or TRUE/FALSE */ static int js_is_regexp(JSContext *ctx, JSValueConst obj); static JSValue js_string_includes(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSValue str, v = JS_UNDEFINED; int i, len, v_len, pos, start, stop, ret; JSString *p; JSString *p1; str = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(str)) return str; ret = js_is_regexp(ctx, argv[0]); if (ret) { if (ret > 0) JS_ThrowTypeError(ctx, "regexp not supported"); goto fail; } v = JS_ToString(ctx, argv[0]); if (JS_IsException(v)) goto fail; p = JS_VALUE_GET_STRING(str); p1 = JS_VALUE_GET_STRING(v); len = p->len; v_len = p1->len; pos = (magic == 2) ? len : 0; if (argc > 1 && !JS_IsUndefined(argv[1])) { if (JS_ToInt32Clamp(ctx, &pos, argv[1], 0, len, 0)) goto fail; } len -= v_len; ret = 0; if (magic == 0) { start = pos; stop = len; } else { if (magic == 1) { if (pos > len) goto done; } else { pos -= v_len; } start = stop = pos; } if (start >= 0 && start <= stop) { for (i = start;; i++) { if (!string_cmp(p, p1, i, 0, v_len)) { ret = 1; break; } if (i == stop) break; } } done: JS_FreeValue(ctx, str); JS_FreeValue(ctx, v); return JS_NewBool(ctx, ret); fail: JS_FreeValue(ctx, str); JS_FreeValue(ctx, v); return JS_EXCEPTION; } static int check_regexp_g_flag(JSContext *ctx, JSValueConst regexp) { int ret; JSValue flags; ret = js_is_regexp(ctx, regexp); if (ret < 0) return -1; if (ret) { flags = JS_GetProperty(ctx, regexp, JS_ATOM_flags); if (JS_IsException(flags)) return -1; if (JS_IsUndefined(flags) || JS_IsNull(flags)) { JS_ThrowTypeError(ctx, "cannot convert to object"); return -1; } flags = JS_ToStringFree(ctx, flags); if (JS_IsException(flags)) return -1; ret = string_indexof_char(JS_VALUE_GET_STRING(flags), 'g', 0); JS_FreeValue(ctx, flags); if (ret < 0) { JS_ThrowTypeError(ctx, "regexp must have the 'g' flag"); return -1; } } return 0; } static JSValue js_string_match(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int atom) { // match(rx), search(rx), matchAll(rx) // atom is JS_ATOM_Symbol_match, JS_ATOM_Symbol_search, or JS_ATOM_Symbol_matchAll JSValueConst O = this_val, regexp = argv[0], args[2]; JSValue matcher, S, rx, result, str; int args_len; if (JS_IsUndefined(O) || JS_IsNull(O)) return JS_ThrowTypeError(ctx, "cannot convert to object"); if (JS_IsObject(regexp)) { matcher = JS_GetProperty(ctx, regexp, atom); if (JS_IsException(matcher)) return JS_EXCEPTION; if (atom == JS_ATOM_Symbol_matchAll) { if (check_regexp_g_flag(ctx, regexp) < 0) { JS_FreeValue(ctx, matcher); return JS_EXCEPTION; } } if (!JS_IsUndefined(matcher) && !JS_IsNull(matcher)) { return JS_CallFree(ctx, matcher, regexp, 1, &O); } } S = JS_ToString(ctx, O); if (JS_IsException(S)) return JS_EXCEPTION; args_len = 1; args[0] = regexp; str = JS_UNDEFINED; if (atom == JS_ATOM_Symbol_matchAll) { str = js_new_string8(ctx, "g"); if (JS_IsException(str)) goto fail; args[args_len++] = (JSValueConst)str; } rx = JS_CallConstructor(ctx, ctx->regexp_ctor, args_len, args); JS_FreeValue(ctx, str); if (JS_IsException(rx)) { fail: JS_FreeValue(ctx, S); return JS_EXCEPTION; } result = JS_InvokeFree(ctx, rx, atom, 1, (JSValueConst *)&S); JS_FreeValue(ctx, S); return result; } /* if captures != NULL, captures_val and matched are ignored. Otherwise, captures_len is ignored */ static int js_string_GetSubstitution(JSContext *ctx, StringBuffer *b, JSValueConst matched, JSString *sp, uint32_t position, JSValueConst captures_val, JSValueConst namedCaptures, JSValueConst rep, uint8_t **captures, uint32_t captures_len) { JSValue capture, name, s; uint32_t len, matched_len; int i, j, j0, k, k1, shift; int c, c1; JSString *rp; if (JS_VALUE_GET_TAG(rep) != JS_TAG_STRING) { JS_ThrowTypeError(ctx, "not a string"); goto exception; } shift = sp->is_wide_char; rp = JS_VALUE_GET_STRING(rep); if (captures) { matched_len = (captures[1] - captures[0]) >> shift; } else { captures_len = 0; if (!JS_IsUndefined(captures_val)) { if (js_get_length32(ctx, &captures_len, captures_val)) goto exception; } if (js_get_length32(ctx, &matched_len, matched)) goto exception; } len = rp->len; i = 0; for(;;) { j = string_indexof_char(rp, '$', i); if (j < 0 || j + 1 >= len) break; string_buffer_concat(b, rp, i, j); j0 = j++; c = string_get(rp, j++); if (c == '$') { string_buffer_putc8(b, '$'); } else if (c == '&') { if (captures) { string_buffer_concat(b, sp, position, position + matched_len); } else { if (string_buffer_concat_value(b, matched)) goto exception; } } else if (c == '`') { string_buffer_concat(b, sp, 0, position); } else if (c == '\'') { string_buffer_concat(b, sp, position + matched_len, sp->len); } else if (c >= '0' && c <= '9') { k = c - '0'; if (j < len) { c1 = string_get(rp, j); if (c1 >= '0' && c1 <= '9') { /* This behavior is specified in ES6 and refined in ECMA 2019 */ /* ECMA 2019 does not have the extra test, but Test262 S15.5.4.11_A3_T1..3 require this behavior */ k1 = k * 10 + c1 - '0'; if (k1 >= 1 && k1 < captures_len) { k = k1; j++; } } } if (k >= 1 && k < captures_len) { if (captures) { int start, end; if (captures[2 * k] && captures[2 * k + 1]) { start = (captures[2 * k] - sp->u.str8) >> shift; end = (captures[2 * k + 1] - sp->u.str8) >> shift; string_buffer_concat(b, sp, start, end); } } else { s = JS_GetPropertyInt64(ctx, captures_val, k); if (JS_IsException(s)) goto exception; if (!JS_IsUndefined(s)) { if (string_buffer_concat_value_free(b, s)) goto exception; } } } else { goto norep; } } else if (c == '<' && !JS_IsUndefined(namedCaptures)) { k = string_indexof_char(rp, '>', j); if (k < 0) goto norep; name = js_sub_string(ctx, rp, j, k); if (JS_IsException(name)) goto exception; capture = JS_GetPropertyValue(ctx, namedCaptures, name); if (JS_IsException(capture)) goto exception; if (!JS_IsUndefined(capture)) { if (string_buffer_concat_value_free(b, capture)) goto exception; } j = k + 1; } else { norep: string_buffer_concat(b, rp, j0, j); } i = j; } string_buffer_concat(b, rp, i, rp->len); return 0; exception: return -1; } static JSValue js_string_replace(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int is_replaceAll) { // replace(rx, rep) JSValueConst O = this_val, searchValue = argv[0], replaceValue = argv[1]; JSValueConst args[3]; JSValue str, search_str, replaceValue_str, repl_str; JSString *sp, *searchp; StringBuffer b_s, *b = &b_s; int pos, functionalReplace, endOfLastMatch; BOOL is_first; if (JS_IsUndefined(O) || JS_IsNull(O)) return JS_ThrowTypeError(ctx, "cannot convert to object"); search_str = JS_UNDEFINED; replaceValue_str = JS_UNDEFINED; repl_str = JS_UNDEFINED; if (JS_IsObject(searchValue)) { JSValue replacer; if (is_replaceAll) { if (check_regexp_g_flag(ctx, searchValue) < 0) return JS_EXCEPTION; } replacer = JS_GetProperty(ctx, searchValue, JS_ATOM_Symbol_replace); if (JS_IsException(replacer)) return JS_EXCEPTION; if (!JS_IsUndefined(replacer) && !JS_IsNull(replacer)) { args[0] = O; args[1] = replaceValue; return JS_CallFree(ctx, replacer, searchValue, 2, args); } } string_buffer_init(ctx, b, 0); str = JS_ToString(ctx, O); if (JS_IsException(str)) goto exception; search_str = JS_ToString(ctx, searchValue); if (JS_IsException(search_str)) goto exception; functionalReplace = JS_IsFunction(ctx, replaceValue); if (!functionalReplace) { replaceValue_str = JS_ToString(ctx, replaceValue); if (JS_IsException(replaceValue_str)) goto exception; } sp = JS_VALUE_GET_STRING(str); searchp = JS_VALUE_GET_STRING(search_str); endOfLastMatch = 0; is_first = TRUE; for(;;) { if (unlikely(searchp->len == 0)) { if (is_first) pos = 0; else if (endOfLastMatch >= sp->len) pos = -1; else pos = endOfLastMatch + 1; } else { pos = string_indexof(sp, searchp, endOfLastMatch); } if (pos < 0) { if (is_first) { string_buffer_free(b); JS_FreeValue(ctx, search_str); JS_FreeValue(ctx, replaceValue_str); return str; } else { break; } } string_buffer_concat(b, sp, endOfLastMatch, pos); if (functionalReplace) { args[0] = search_str; args[1] = JS_NewInt32(ctx, pos); args[2] = str; repl_str = JS_ToStringFree(ctx, JS_Call(ctx, replaceValue, JS_UNDEFINED, 3, args)); if (JS_IsException(repl_str)) goto exception; string_buffer_concat_value_free(b, repl_str); } else { if (js_string_GetSubstitution(ctx, b, search_str, sp, pos, JS_UNDEFINED, JS_UNDEFINED, replaceValue_str, NULL, 0)) { goto exception; } } endOfLastMatch = pos + searchp->len; is_first = FALSE; if (!is_replaceAll) break; } string_buffer_concat(b, sp, endOfLastMatch, sp->len); JS_FreeValue(ctx, search_str); JS_FreeValue(ctx, replaceValue_str); JS_FreeValue(ctx, str); return string_buffer_end(b); exception: string_buffer_free(b); JS_FreeValue(ctx, search_str); JS_FreeValue(ctx, replaceValue_str); JS_FreeValue(ctx, str); return JS_EXCEPTION; } static JSValue js_string_split(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // split(sep, limit) JSValueConst O = this_val, separator = argv[0], limit = argv[1]; JSValueConst args[2]; JSValue S, A, R, T; uint32_t lim, lengthA; int64_t p, q, s, r, e; JSString *sp, *rp; if (JS_IsUndefined(O) || JS_IsNull(O)) return JS_ThrowTypeError(ctx, "cannot convert to object"); S = JS_UNDEFINED; A = JS_UNDEFINED; R = JS_UNDEFINED; if (JS_IsObject(separator)) { JSValue splitter; splitter = JS_GetProperty(ctx, separator, JS_ATOM_Symbol_split); if (JS_IsException(splitter)) return JS_EXCEPTION; if (!JS_IsUndefined(splitter) && !JS_IsNull(splitter)) { args[0] = O; args[1] = limit; return JS_CallFree(ctx, splitter, separator, 2, args); } } S = JS_ToString(ctx, O); if (JS_IsException(S)) goto exception; A = JS_NewArray(ctx); if (JS_IsException(A)) goto exception; lengthA = 0; if (JS_IsUndefined(limit)) { lim = 0xffffffff; } else { if (JS_ToUint32(ctx, &lim, limit) < 0) goto exception; } sp = JS_VALUE_GET_STRING(S); s = sp->len; R = JS_ToString(ctx, separator); if (JS_IsException(R)) goto exception; rp = JS_VALUE_GET_STRING(R); r = rp->len; p = 0; if (lim == 0) goto done; if (JS_IsUndefined(separator)) goto add_tail; if (s == 0) { if (r != 0) goto add_tail; goto done; } for (q = p; (q += !r) <= s - r - !r; q = p = e + r) { e = string_indexof(sp, rp, q); if (e < 0) break; T = js_sub_string(ctx, sp, p, e); if (JS_IsException(T)) goto exception; if (JS_CreateDataPropertyUint32(ctx, A, lengthA++, T, 0) < 0) goto exception; if (lengthA == lim) goto done; } add_tail: T = js_sub_string(ctx, sp, p, s); if (JS_IsException(T)) goto exception; if (JS_CreateDataPropertyUint32(ctx, A, lengthA++, T,0 ) < 0) goto exception; done: JS_FreeValue(ctx, S); JS_FreeValue(ctx, R); return A; exception: JS_FreeValue(ctx, A); JS_FreeValue(ctx, S); JS_FreeValue(ctx, R); return JS_EXCEPTION; } static JSValue js_string_substring(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue str, ret; int a, b, start, end; JSString *p; str = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(str)) return str; p = JS_VALUE_GET_STRING(str); if (JS_ToInt32Clamp(ctx, &a, argv[0], 0, p->len, 0)) { JS_FreeValue(ctx, str); return JS_EXCEPTION; } b = p->len; if (!JS_IsUndefined(argv[1])) { if (JS_ToInt32Clamp(ctx, &b, argv[1], 0, p->len, 0)) { JS_FreeValue(ctx, str); return JS_EXCEPTION; } } if (a < b) { start = a; end = b; } else { start = b; end = a; } ret = js_sub_string(ctx, p, start, end); JS_FreeValue(ctx, str); return ret; } static JSValue js_string_substr(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue str, ret; int a, len, n; JSString *p; str = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(str)) return str; p = JS_VALUE_GET_STRING(str); len = p->len; if (JS_ToInt32Clamp(ctx, &a, argv[0], 0, len, len)) { JS_FreeValue(ctx, str); return JS_EXCEPTION; } n = len - a; if (!JS_IsUndefined(argv[1])) { if (JS_ToInt32Clamp(ctx, &n, argv[1], 0, len - a, 0)) { JS_FreeValue(ctx, str); return JS_EXCEPTION; } } ret = js_sub_string(ctx, p, a, a + n); JS_FreeValue(ctx, str); return ret; } static JSValue js_string_slice(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue str, ret; int len, start, end; JSString *p; str = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(str)) return str; p = JS_VALUE_GET_STRING(str); len = p->len; if (JS_ToInt32Clamp(ctx, &start, argv[0], 0, len, len)) { JS_FreeValue(ctx, str); return JS_EXCEPTION; } end = len; if (!JS_IsUndefined(argv[1])) { if (JS_ToInt32Clamp(ctx, &end, argv[1], 0, len, len)) { JS_FreeValue(ctx, str); return JS_EXCEPTION; } } ret = js_sub_string(ctx, p, start, max_int(end, start)); JS_FreeValue(ctx, str); return ret; } static JSValue js_string_pad(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int padEnd) { JSValue str, v = JS_UNDEFINED; StringBuffer b_s, *b = &b_s; JSString *p, *p1 = NULL; int n, len, c = ' '; str = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(str)) goto fail1; if (JS_ToInt32Sat(ctx, &n, argv[0])) goto fail2; p = JS_VALUE_GET_STRING(str); len = p->len; if (len >= n) return str; if (argc > 1 && !JS_IsUndefined(argv[1])) { v = JS_ToString(ctx, argv[1]); if (JS_IsException(v)) goto fail2; p1 = JS_VALUE_GET_STRING(v); if (p1->len == 0) { JS_FreeValue(ctx, v); return str; } if (p1->len == 1) { c = string_get(p1, 0); p1 = NULL; } } if (n > JS_STRING_LEN_MAX) { JS_ThrowRangeError(ctx, "invalid string length"); goto fail3; } if (string_buffer_init(ctx, b, n)) goto fail3; n -= len; if (padEnd) { if (string_buffer_concat(b, p, 0, len)) goto fail; } if (p1) { while (n > 0) { int chunk = min_int(n, p1->len); if (string_buffer_concat(b, p1, 0, chunk)) goto fail; n -= chunk; } } else { if (string_buffer_fill(b, c, n)) goto fail; } if (!padEnd) { if (string_buffer_concat(b, p, 0, len)) goto fail; } JS_FreeValue(ctx, v); JS_FreeValue(ctx, str); return string_buffer_end(b); fail: string_buffer_free(b); fail3: JS_FreeValue(ctx, v); fail2: JS_FreeValue(ctx, str); fail1: return JS_EXCEPTION; } static JSValue js_string_repeat(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue str; StringBuffer b_s, *b = &b_s; JSString *p; int64_t val; int n, len; str = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(str)) goto fail; if (JS_ToInt64Sat(ctx, &val, argv[0])) goto fail; if (val < 0 || val > 2147483647) { JS_ThrowRangeError(ctx, "invalid repeat count"); goto fail; } n = val; p = JS_VALUE_GET_STRING(str); len = p->len; if (len == 0 || n == 1) return str; // XXX: potential arithmetic overflow if (val * len > JS_STRING_LEN_MAX) { JS_ThrowRangeError(ctx, "invalid string length"); goto fail; } if (string_buffer_init2(ctx, b, n * len, p->is_wide_char)) goto fail; if (len == 1) { string_buffer_fill(b, string_get(p, 0), n); } else { while (n-- > 0) { string_buffer_concat(b, p, 0, len); } } JS_FreeValue(ctx, str); return string_buffer_end(b); fail: JS_FreeValue(ctx, str); return JS_EXCEPTION; } static JSValue js_string_trim(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSValue str, ret; int a, b, len; JSString *p; str = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(str)) return str; p = JS_VALUE_GET_STRING(str); a = 0; b = len = p->len; if (magic & 1) { while (a < len && lre_is_space(string_get(p, a))) a++; } if (magic & 2) { while (b > a && lre_is_space(string_get(p, b - 1))) b--; } ret = js_sub_string(ctx, p, a, b); JS_FreeValue(ctx, str); return ret; } /* return 0 if before the first char */ static int string_prevc(JSString *p, int *pidx) { int idx, c, c1; idx = *pidx; if (idx <= 0) return 0; idx--; if (p->is_wide_char) { c = p->u.str16[idx]; if (is_lo_surrogate(c) && idx > 0) { c1 = p->u.str16[idx - 1]; if (is_hi_surrogate(c1)) { c = from_surrogate(c1, c); idx--; } } } else { c = p->u.str8[idx]; } *pidx = idx; return c; } static BOOL test_final_sigma(JSString *p, int sigma_pos) { int k, c1; /* before C: skip case ignorable chars and check there is a cased letter */ k = sigma_pos; for(;;) { c1 = string_prevc(p, &k); if (!lre_is_case_ignorable(c1)) break; } if (!lre_is_cased(c1)) return FALSE; /* after C: skip case ignorable chars and check there is no cased letter */ k = sigma_pos + 1; for(;;) { if (k >= p->len) return TRUE; c1 = string_getc(p, &k); if (!lre_is_case_ignorable(c1)) break; } return !lre_is_cased(c1); } static JSValue js_string_toLowerCase(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int to_lower) { JSValue val; StringBuffer b_s, *b = &b_s; JSString *p; int i, c, j, l; uint32_t res[LRE_CC_RES_LEN_MAX]; val = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(val)) return val; p = JS_VALUE_GET_STRING(val); if (p->len == 0) return val; if (string_buffer_init(ctx, b, p->len)) goto fail; for(i = 0; i < p->len;) { c = string_getc(p, &i); if (c == 0x3a3 && to_lower && test_final_sigma(p, i - 1)) { res[0] = 0x3c2; /* final sigma */ l = 1; } else { l = lre_case_conv(res, c, to_lower); } for(j = 0; j < l; j++) { if (string_buffer_putc(b, res[j])) goto fail; } } JS_FreeValue(ctx, val); return string_buffer_end(b); fail: JS_FreeValue(ctx, val); string_buffer_free(b); return JS_EXCEPTION; } #ifdef CONFIG_ALL_UNICODE /* return (-1, NULL) if exception, otherwise (len, buf) */ static int JS_ToUTF32String(JSContext *ctx, uint32_t **pbuf, JSValueConst val1) { JSValue val; JSString *p; uint32_t *buf; int i, j, len; val = JS_ToString(ctx, val1); if (JS_IsException(val)) return -1; p = JS_VALUE_GET_STRING(val); len = p->len; /* UTF32 buffer length is len minus the number of correct surrogates pairs */ buf = js_malloc(ctx, sizeof(buf[0]) * max_int(len, 1)); if (!buf) { JS_FreeValue(ctx, val); goto fail; } for(i = j = 0; i < len;) buf[j++] = string_getc(p, &i); JS_FreeValue(ctx, val); *pbuf = buf; return j; fail: *pbuf = NULL; return -1; } static JSValue JS_NewUTF32String(JSContext *ctx, const uint32_t *buf, int len) { int i; StringBuffer b_s, *b = &b_s; if (string_buffer_init(ctx, b, len)) return JS_EXCEPTION; for(i = 0; i < len; i++) { if (string_buffer_putc(b, buf[i])) goto fail; } return string_buffer_end(b); fail: string_buffer_free(b); return JS_EXCEPTION; } static int js_string_normalize1(JSContext *ctx, uint32_t **pout_buf, JSValueConst val, UnicodeNormalizationEnum n_type) { int buf_len, out_len; uint32_t *buf, *out_buf; buf_len = JS_ToUTF32String(ctx, &buf, val); if (buf_len < 0) return -1; out_len = unicode_normalize(&out_buf, buf, buf_len, n_type, ctx->rt, (DynBufReallocFunc *)js_realloc_rt); js_free(ctx, buf); if (out_len < 0) return -1; *pout_buf = out_buf; return out_len; } static JSValue js_string_normalize(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { const char *form, *p; size_t form_len; int is_compat, out_len; UnicodeNormalizationEnum n_type; JSValue val; uint32_t *out_buf; val = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(val)) return val; if (argc == 0 || JS_IsUndefined(argv[0])) { n_type = UNICODE_NFC; } else { form = JS_ToCStringLen(ctx, &form_len, argv[0]); if (!form) goto fail1; p = form; if (p[0] != 'N' || p[1] != 'F') goto bad_form; p += 2; is_compat = FALSE; if (*p == 'K') { is_compat = TRUE; p++; } if (*p == 'C' || *p == 'D') { n_type = UNICODE_NFC + is_compat * 2 + (*p - 'C'); if ((p + 1 - form) != form_len) goto bad_form; } else { bad_form: JS_FreeCString(ctx, form); JS_ThrowRangeError(ctx, "bad normalization form"); fail1: JS_FreeValue(ctx, val); return JS_EXCEPTION; } JS_FreeCString(ctx, form); } out_len = js_string_normalize1(ctx, &out_buf, val, n_type); JS_FreeValue(ctx, val); if (out_len < 0) return JS_EXCEPTION; val = JS_NewUTF32String(ctx, out_buf, out_len); js_free(ctx, out_buf); return val; } /* return < 0, 0 or > 0 */ static int js_UTF32_compare(const uint32_t *buf1, int buf1_len, const uint32_t *buf2, int buf2_len) { int i, len, c, res; len = min_int(buf1_len, buf2_len); for(i = 0; i < len; i++) { /* Note: range is limited so a subtraction is valid */ c = buf1[i] - buf2[i]; if (c != 0) return c; } if (buf1_len == buf2_len) res = 0; else if (buf1_len < buf2_len) res = -1; else res = 1; return res; } static JSValue js_string_localeCompare(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue a, b; int cmp, a_len, b_len; uint32_t *a_buf, *b_buf; a = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(a)) return JS_EXCEPTION; b = JS_ToString(ctx, argv[0]); if (JS_IsException(b)) { JS_FreeValue(ctx, a); return JS_EXCEPTION; } a_len = js_string_normalize1(ctx, &a_buf, a, UNICODE_NFC); JS_FreeValue(ctx, a); if (a_len < 0) { JS_FreeValue(ctx, b); return JS_EXCEPTION; } b_len = js_string_normalize1(ctx, &b_buf, b, UNICODE_NFC); JS_FreeValue(ctx, b); if (b_len < 0) { js_free(ctx, a_buf); return JS_EXCEPTION; } cmp = js_UTF32_compare(a_buf, a_len, b_buf, b_len); js_free(ctx, a_buf); js_free(ctx, b_buf); return JS_NewInt32(ctx, cmp); } #else /* CONFIG_ALL_UNICODE */ static JSValue js_string_localeCompare(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue a, b; int cmp; a = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(a)) return JS_EXCEPTION; b = JS_ToString(ctx, argv[0]); if (JS_IsException(b)) { JS_FreeValue(ctx, a); return JS_EXCEPTION; } cmp = js_string_compare(ctx, JS_VALUE_GET_STRING(a), JS_VALUE_GET_STRING(b)); JS_FreeValue(ctx, a); JS_FreeValue(ctx, b); return JS_NewInt32(ctx, cmp); } #endif /* !CONFIG_ALL_UNICODE */ /* also used for String.prototype.valueOf */ static JSValue js_string_toString(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return js_thisStringValue(ctx, this_val); } /* String Iterator */ static JSValue js_string_iterator_next(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, BOOL *pdone, int magic) { JSArrayIteratorData *it; uint32_t idx, c, start; JSString *p; it = JS_GetOpaque2(ctx, this_val, JS_CLASS_STRING_ITERATOR); if (!it) { *pdone = FALSE; return JS_EXCEPTION; } if (JS_IsUndefined(it->obj)) goto done; p = JS_VALUE_GET_STRING(it->obj); idx = it->idx; if (idx >= p->len) { JS_FreeValue(ctx, it->obj); it->obj = JS_UNDEFINED; done: *pdone = TRUE; return JS_UNDEFINED; } start = idx; c = string_getc(p, (int *)&idx); it->idx = idx; *pdone = FALSE; if (c <= 0xffff) { return js_new_string_char(ctx, c); } else { return js_new_string16_len(ctx, p->u.str16 + start, 2); } } /* ES6 Annex B 2.3.2 etc. */ enum { magic_string_anchor, magic_string_big, magic_string_blink, magic_string_bold, magic_string_fixed, magic_string_fontcolor, magic_string_fontsize, magic_string_italics, magic_string_link, magic_string_small, magic_string_strike, magic_string_sub, magic_string_sup, }; static JSValue js_string_CreateHTML(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSValue str; const JSString *p; StringBuffer b_s, *b = &b_s; static struct { const char *tag, *attr; } const defs[] = { { "a", "name" }, { "big", NULL }, { "blink", NULL }, { "b", NULL }, { "tt", NULL }, { "font", "color" }, { "font", "size" }, { "i", NULL }, { "a", "href" }, { "small", NULL }, { "strike", NULL }, { "sub", NULL }, { "sup", NULL }, }; str = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(str)) return JS_EXCEPTION; string_buffer_init(ctx, b, 7); string_buffer_putc8(b, '<'); string_buffer_puts8(b, defs[magic].tag); if (defs[magic].attr) { // r += " " + attr + "=\"" + value + "\""; JSValue value; int i; string_buffer_putc8(b, ' '); string_buffer_puts8(b, defs[magic].attr); string_buffer_puts8(b, "=\""); value = JS_ToStringCheckObject(ctx, argv[0]); if (JS_IsException(value)) { JS_FreeValue(ctx, str); string_buffer_free(b); return JS_EXCEPTION; } p = JS_VALUE_GET_STRING(value); for (i = 0; i < p->len; i++) { int c = string_get(p, i); if (c == '"') { string_buffer_puts8(b, "&quot;"); } else { string_buffer_putc16(b, c); } } JS_FreeValue(ctx, value); string_buffer_putc8(b, '\"'); } // return r + ">" + str + "</" + tag + ">"; string_buffer_putc8(b, '>'); string_buffer_concat_value_free(b, str); string_buffer_puts8(b, "</"); string_buffer_puts8(b, defs[magic].tag); string_buffer_putc8(b, '>'); return string_buffer_end(b); } static const JSCFunctionListEntry js_string_funcs[] = { JS_CFUNC_DEF("fromCharCode", 1, js_string_fromCharCode ), JS_CFUNC_DEF("fromCodePoint", 1, js_string_fromCodePoint ), JS_CFUNC_DEF("raw", 1, js_string_raw ), }; static const JSCFunctionListEntry js_string_proto_funcs[] = { JS_PROP_INT32_DEF("length", 0, JS_PROP_CONFIGURABLE ), JS_CFUNC_MAGIC_DEF("at", 1, js_string_charAt, 1 ), JS_CFUNC_DEF("charCodeAt", 1, js_string_charCodeAt ), JS_CFUNC_MAGIC_DEF("charAt", 1, js_string_charAt, 0 ), JS_CFUNC_DEF("concat", 1, js_string_concat ), JS_CFUNC_DEF("codePointAt", 1, js_string_codePointAt ), JS_CFUNC_DEF("isWellFormed", 0, js_string_isWellFormed ), JS_CFUNC_DEF("toWellFormed", 0, js_string_toWellFormed ), JS_CFUNC_MAGIC_DEF("indexOf", 1, js_string_indexOf, 0 ), JS_CFUNC_MAGIC_DEF("lastIndexOf", 1, js_string_indexOf, 1 ), JS_CFUNC_MAGIC_DEF("includes", 1, js_string_includes, 0 ), JS_CFUNC_MAGIC_DEF("endsWith", 1, js_string_includes, 2 ), JS_CFUNC_MAGIC_DEF("startsWith", 1, js_string_includes, 1 ), JS_CFUNC_MAGIC_DEF("match", 1, js_string_match, JS_ATOM_Symbol_match ), JS_CFUNC_MAGIC_DEF("matchAll", 1, js_string_match, JS_ATOM_Symbol_matchAll ), JS_CFUNC_MAGIC_DEF("search", 1, js_string_match, JS_ATOM_Symbol_search ), JS_CFUNC_DEF("split", 2, js_string_split ), JS_CFUNC_DEF("substring", 2, js_string_substring ), JS_CFUNC_DEF("substr", 2, js_string_substr ), JS_CFUNC_DEF("slice", 2, js_string_slice ), JS_CFUNC_DEF("repeat", 1, js_string_repeat ), JS_CFUNC_MAGIC_DEF("replace", 2, js_string_replace, 0 ), JS_CFUNC_MAGIC_DEF("replaceAll", 2, js_string_replace, 1 ), JS_CFUNC_MAGIC_DEF("padEnd", 1, js_string_pad, 1 ), JS_CFUNC_MAGIC_DEF("padStart", 1, js_string_pad, 0 ), JS_CFUNC_MAGIC_DEF("trim", 0, js_string_trim, 3 ), JS_CFUNC_MAGIC_DEF("trimEnd", 0, js_string_trim, 2 ), JS_ALIAS_DEF("trimRight", "trimEnd" ), JS_CFUNC_MAGIC_DEF("trimStart", 0, js_string_trim, 1 ), JS_ALIAS_DEF("trimLeft", "trimStart" ), JS_CFUNC_DEF("toString", 0, js_string_toString ), JS_CFUNC_DEF("valueOf", 0, js_string_toString ), JS_CFUNC_MAGIC_DEF("toLowerCase", 0, js_string_toLowerCase, 1 ), JS_CFUNC_MAGIC_DEF("toUpperCase", 0, js_string_toLowerCase, 0 ), JS_CFUNC_MAGIC_DEF("toLocaleLowerCase", 0, js_string_toLowerCase, 1 ), JS_CFUNC_MAGIC_DEF("toLocaleUpperCase", 0, js_string_toLowerCase, 0 ), JS_CFUNC_MAGIC_DEF("[Symbol.iterator]", 0, js_create_array_iterator, JS_ITERATOR_KIND_VALUE | 4 ), /* ES6 Annex B 2.3.2 etc. */ JS_CFUNC_MAGIC_DEF("anchor", 1, js_string_CreateHTML, magic_string_anchor ), JS_CFUNC_MAGIC_DEF("big", 0, js_string_CreateHTML, magic_string_big ), JS_CFUNC_MAGIC_DEF("blink", 0, js_string_CreateHTML, magic_string_blink ), JS_CFUNC_MAGIC_DEF("bold", 0, js_string_CreateHTML, magic_string_bold ), JS_CFUNC_MAGIC_DEF("fixed", 0, js_string_CreateHTML, magic_string_fixed ), JS_CFUNC_MAGIC_DEF("fontcolor", 1, js_string_CreateHTML, magic_string_fontcolor ), JS_CFUNC_MAGIC_DEF("fontsize", 1, js_string_CreateHTML, magic_string_fontsize ), JS_CFUNC_MAGIC_DEF("italics", 0, js_string_CreateHTML, magic_string_italics ), JS_CFUNC_MAGIC_DEF("link", 1, js_string_CreateHTML, magic_string_link ), JS_CFUNC_MAGIC_DEF("small", 0, js_string_CreateHTML, magic_string_small ), JS_CFUNC_MAGIC_DEF("strike", 0, js_string_CreateHTML, magic_string_strike ), JS_CFUNC_MAGIC_DEF("sub", 0, js_string_CreateHTML, magic_string_sub ), JS_CFUNC_MAGIC_DEF("sup", 0, js_string_CreateHTML, magic_string_sup ), }; static const JSCFunctionListEntry js_string_iterator_proto_funcs[] = { JS_ITERATOR_NEXT_DEF("next", 0, js_string_iterator_next, 0 ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "String Iterator", JS_PROP_CONFIGURABLE ), }; static const JSCFunctionListEntry js_string_proto_normalize[] = { #ifdef CONFIG_ALL_UNICODE JS_CFUNC_DEF("normalize", 0, js_string_normalize ), #endif JS_CFUNC_DEF("localeCompare", 1, js_string_localeCompare ), }; int JS_AddIntrinsicStringNormalize(JSContext *ctx) { return JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_STRING], js_string_proto_normalize, countof(js_string_proto_normalize)); } /* Math */ /* precondition: a and b are not NaN */ static double js_fmin(double a, double b) { if (a == 0 && b == 0) { JSFloat64Union a1, b1; a1.d = a; b1.d = b; a1.u64 |= b1.u64; return a1.d; } else { return fmin(a, b); } } /* precondition: a and b are not NaN */ static double js_fmax(double a, double b) { if (a == 0 && b == 0) { JSFloat64Union a1, b1; a1.d = a; b1.d = b; a1.u64 &= b1.u64; return a1.d; } else { return fmax(a, b); } } static JSValue js_math_min_max(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { BOOL is_max = magic; double r, a; int i; uint32_t tag; if (unlikely(argc == 0)) { return __JS_NewFloat64(ctx, is_max ? -1.0 / 0.0 : 1.0 / 0.0); } tag = JS_VALUE_GET_TAG(argv[0]); if (tag == JS_TAG_INT) { int a1, r1 = JS_VALUE_GET_INT(argv[0]); for(i = 1; i < argc; i++) { tag = JS_VALUE_GET_TAG(argv[i]); if (tag != JS_TAG_INT) { r = r1; goto generic_case; } a1 = JS_VALUE_GET_INT(argv[i]); if (is_max) r1 = max_int(r1, a1); else r1 = min_int(r1, a1); } return JS_NewInt32(ctx, r1); } else { if (JS_ToFloat64(ctx, &r, argv[0])) return JS_EXCEPTION; i = 1; generic_case: while (i < argc) { if (JS_ToFloat64(ctx, &a, argv[i])) return JS_EXCEPTION; if (!isnan(r)) { if (isnan(a)) { r = a; } else { if (is_max) r = js_fmax(r, a); else r = js_fmin(r, a); } } i++; } return JS_NewFloat64(ctx, r); } } static double js_math_sign(double a) { if (isnan(a) || a == 0.0) return a; if (a < 0) return -1; else return 1; } static double js_math_round(double a) { JSFloat64Union u; uint64_t frac_mask, one; unsigned int e, s; u.d = a; e = (u.u64 >> 52) & 0x7ff; if (e < 1023) { /* abs(a) < 1 */ if (e == (1023 - 1) && u.u64 != 0xbfe0000000000000) { /* abs(a) > 0.5 or a = 0.5: return +/-1.0 */ u.u64 = (u.u64 & ((uint64_t)1 << 63)) | ((uint64_t)1023 << 52); } else { /* return +/-0.0 */ u.u64 &= (uint64_t)1 << 63; } } else if (e < (1023 + 52)) { s = u.u64 >> 63; one = (uint64_t)1 << (52 - (e - 1023)); frac_mask = one - 1; u.u64 += (one >> 1) - s; u.u64 &= ~frac_mask; /* truncate to an integer */ } /* otherwise: abs(a) >= 2^52, or NaN, +/-Infinity: no change */ return u.d; } static JSValue js_math_hypot(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { double r, a; int i; r = 0; if (argc > 0) { if (JS_ToFloat64(ctx, &r, argv[0])) return JS_EXCEPTION; if (argc == 1) { r = fabs(r); } else { /* use the built-in function to minimize precision loss */ for (i = 1; i < argc; i++) { if (JS_ToFloat64(ctx, &a, argv[i])) return JS_EXCEPTION; r = hypot(r, a); } } } return JS_NewFloat64(ctx, r); } static double js_math_f16round(double a) { return fromfp16(tofp16(a)); } static double js_math_fround(double a) { return (float)a; } static JSValue js_math_imul(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { uint32_t a, b, c; int32_t d; if (JS_ToUint32(ctx, &a, argv[0])) return JS_EXCEPTION; if (JS_ToUint32(ctx, &b, argv[1])) return JS_EXCEPTION; c = a * b; memcpy(&d, &c, sizeof(d)); return JS_NewInt32(ctx, d); } static JSValue js_math_clz32(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { uint32_t a, r; if (JS_ToUint32(ctx, &a, argv[0])) return JS_EXCEPTION; if (a == 0) r = 32; else r = clz32(a); return JS_NewInt32(ctx, r); } typedef enum { SUM_PRECISE_STATE_FINITE, SUM_PRECISE_STATE_INFINITY, SUM_PRECISE_STATE_MINUS_INFINITY, /* must be after SUM_PRECISE_STATE_INFINITY */ SUM_PRECISE_STATE_NAN, /* must be after SUM_PRECISE_STATE_MINUS_INFINITY */ } SumPreciseStateEnum; #define SP_LIMB_BITS 56 #define SP_RND_BITS (SP_LIMB_BITS - 53) /* we add one extra limb to avoid having to test for overflows during the sum */ #define SUM_PRECISE_ACC_LEN 39 #define SUM_PRECISE_COUNTER_INIT 250 typedef struct { SumPreciseStateEnum state; uint32_t counter; int n_limbs; /* 'acc' contains n_limbs and is not necessarily acc[n_limb - 1] may be 0. 0 indicates minus zero result when state = SUM_PRECISE_STATE_FINITE */ int64_t acc[SUM_PRECISE_ACC_LEN]; } SumPreciseState; static void sum_precise_init(SumPreciseState *s) { memset(s->acc, 0, sizeof(s->acc)); s->state = SUM_PRECISE_STATE_FINITE; s->counter = SUM_PRECISE_COUNTER_INIT; s->n_limbs = 0; } static void sum_precise_renorm(SumPreciseState *s) { int64_t v, carry; int i; carry = 0; for(i = 0; i < s->n_limbs; i++) { v = s->acc[i] + carry; s->acc[i] = v & (((uint64_t)1 << SP_LIMB_BITS) - 1); carry = v >> SP_LIMB_BITS; } /* we add a failsafe but it should be never reached in a reasonnable amount of time */ if (carry != 0 && s->n_limbs < SUM_PRECISE_ACC_LEN) s->acc[s->n_limbs++] = carry; } static void sum_precise_add(SumPreciseState *s, double d) { uint64_t a, m, a0, a1; int sgn, e, p; unsigned int shift; a = float64_as_uint64(d); sgn = a >> 63; e = (a >> 52) & ((1 << 11) - 1); m = a & (((uint64_t)1 << 52) - 1); if (unlikely(e == 2047)) { if (m == 0) { /* +/- infinity */ if (s->state == SUM_PRECISE_STATE_NAN || (s->state == SUM_PRECISE_STATE_MINUS_INFINITY && !sgn) || (s->state == SUM_PRECISE_STATE_INFINITY && sgn)) { s->state = SUM_PRECISE_STATE_NAN; } else { s->state = SUM_PRECISE_STATE_INFINITY + sgn; } } else { /* NaN */ s->state = SUM_PRECISE_STATE_NAN; } } else if (e == 0) { if (likely(m == 0)) { /* zero */ if (s->n_limbs == 0 && !sgn) s->n_limbs = 1; } else { /* subnormal */ p = 0; shift = 0; goto add; } } else { /* Note: we sum even if state != SUM_PRECISE_STATE_FINITE to avoid tests */ m |= (uint64_t)1 << 52; shift = e - 1; /* 'p' is the position of a0 in acc. The division is normally implementation as a multiplication by the compiler. */ p = shift / SP_LIMB_BITS; shift %= SP_LIMB_BITS; add: a0 = (m << shift) & (((uint64_t)1 << SP_LIMB_BITS) - 1); a1 = m >> (SP_LIMB_BITS - shift); if (!sgn) { s->acc[p] += a0; s->acc[p + 1] += a1; } else { s->acc[p] -= a0; s->acc[p + 1] -= a1; } s->n_limbs = max_int(s->n_limbs, p + 2); if (unlikely(--s->counter == 0)) { s->counter = SUM_PRECISE_COUNTER_INIT; sum_precise_renorm(s); } } } static double sum_precise_get_result(SumPreciseState *s) { int n, shift, e, p, is_neg; uint64_t m, addend; if (s->state != SUM_PRECISE_STATE_FINITE) { switch(s->state) { default: case SUM_PRECISE_STATE_INFINITY: return INFINITY; case SUM_PRECISE_STATE_MINUS_INFINITY: return -INFINITY; case SUM_PRECISE_STATE_NAN: return NAN; } } sum_precise_renorm(s); /* extract the sign and absolute value */ #if 0 { int i; printf("len=%d:", s->n_limbs); for(i = s->n_limbs - 1; i >= 0; i--) printf(" %014lx", s->acc[i]); printf("\n"); } #endif n = s->n_limbs; /* minus zero result */ if (n == 0) return -0.0; /* normalize */ while (n > 0 && s->acc[n - 1] == 0) n--; /* zero result. The spec tells it is always positive in the finite case */ if (n == 0) return 0.0; is_neg = (s->acc[n - 1] < 0); if (is_neg) { uint64_t v, carry; int i; /* negate */ /* XXX: do it only when needed */ carry = 1; for(i = 0; i < n - 1; i++) { v = (((uint64_t)1 << SP_LIMB_BITS) - 1) - s->acc[i] + carry; carry = v >> SP_LIMB_BITS; s->acc[i] = v & (((uint64_t)1 << SP_LIMB_BITS) - 1); } s->acc[n - 1] = -s->acc[n - 1] + carry - 1; while (n > 1 && s->acc[n - 1] == 0) n--; } /* subnormal case */ if (n == 1 && s->acc[0] < ((uint64_t)1 << 52)) return uint64_as_float64(((uint64_t)is_neg << 63) | s->acc[0]); /* normal case */ e = n * SP_LIMB_BITS; p = n - 1; m = s->acc[p]; shift = clz64(m) - (64 - SP_LIMB_BITS); e = e - shift - 52; if (shift != 0) { m <<= shift; if (p > 0) { int shift1; uint64_t nz; p--; shift1 = SP_LIMB_BITS - shift; nz = s->acc[p] & (((uint64_t)1 << shift1) - 1); m = m | (s->acc[p] >> shift1) | (nz != 0); } } if ((m & ((1 << SP_RND_BITS) - 1)) == (1 << (SP_RND_BITS - 1))) { /* see if the LSB part is non zero for the final rounding */ while (p > 0) { p--; if (s->acc[p] != 0) { m |= 1; break; } } } /* rounding to nearest with ties to even */ addend = (1 << (SP_RND_BITS - 1)) - 1 + ((m >> SP_RND_BITS) & 1); m = (m + addend) >> SP_RND_BITS; /* handle overflow in the rounding */ if (m == ((uint64_t)1 << 53)) e++; if (unlikely(e >= 2047)) { /* infinity */ return uint64_as_float64(((uint64_t)is_neg << 63) | ((uint64_t)2047 << 52)); } else { m &= (((uint64_t)1 << 52) - 1); return uint64_as_float64(((uint64_t)is_neg << 63) | ((uint64_t)e << 52) | m); } } static JSValue js_math_sumPrecise(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue iter, next, item, ret; uint32_t tag; int done; double d; SumPreciseState s_s, *s = &s_s; iter = JS_GetIterator(ctx, argv[0], FALSE); if (JS_IsException(iter)) return JS_EXCEPTION; ret = JS_EXCEPTION; next = JS_GetProperty(ctx, iter, JS_ATOM_next); if (JS_IsException(next)) goto fail; sum_precise_init(s); for (;;) { item = JS_IteratorNext(ctx, iter, next, 0, NULL, &done); if (JS_IsException(item)) goto fail; if (done) break; tag = JS_VALUE_GET_TAG(item); if (JS_TAG_IS_FLOAT64(tag)) { d = JS_VALUE_GET_FLOAT64(item); } else if (tag == JS_TAG_INT) { d = JS_VALUE_GET_INT(item); } else { JS_FreeValue(ctx, item); JS_ThrowTypeError(ctx, "not a number"); JS_IteratorClose(ctx, iter, TRUE); goto fail; } sum_precise_add(s, d); } ret = __JS_NewFloat64(ctx, sum_precise_get_result(s)); fail: JS_FreeValue(ctx, iter); JS_FreeValue(ctx, next); return ret; } /* xorshift* random number generator by Marsaglia */ static uint64_t xorshift64star(uint64_t *pstate) { uint64_t x; x = *pstate; x ^= x >> 12; x ^= x << 25; x ^= x >> 27; *pstate = x; return x * 0x2545F4914F6CDD1D; } static void js_random_init(JSContext *ctx) { struct timeval tv; gettimeofday(&tv, NULL); ctx->random_state = ((int64_t)tv.tv_sec * 1000000) + tv.tv_usec; /* the state must be non zero */ if (ctx->random_state == 0) ctx->random_state = 1; } static JSValue js_math_random(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSFloat64Union u; uint64_t v; v = xorshift64star(&ctx->random_state); /* 1.0 <= u.d < 2 */ u.u64 = ((uint64_t)0x3ff << 52) | (v >> 12); return __JS_NewFloat64(ctx, u.d - 1.0); } static const JSCFunctionListEntry js_math_funcs[] = { JS_CFUNC_MAGIC_DEF("min", 2, js_math_min_max, 0 ), JS_CFUNC_MAGIC_DEF("max", 2, js_math_min_max, 1 ), JS_CFUNC_SPECIAL_DEF("abs", 1, f_f, fabs ), JS_CFUNC_SPECIAL_DEF("floor", 1, f_f, floor ), JS_CFUNC_SPECIAL_DEF("ceil", 1, f_f, ceil ), JS_CFUNC_SPECIAL_DEF("round", 1, f_f, js_math_round ), JS_CFUNC_SPECIAL_DEF("sqrt", 1, f_f, sqrt ), JS_CFUNC_SPECIAL_DEF("acos", 1, f_f, acos ), JS_CFUNC_SPECIAL_DEF("asin", 1, f_f, asin ), JS_CFUNC_SPECIAL_DEF("atan", 1, f_f, atan ), JS_CFUNC_SPECIAL_DEF("atan2", 2, f_f_f, atan2 ), JS_CFUNC_SPECIAL_DEF("cos", 1, f_f, cos ), JS_CFUNC_SPECIAL_DEF("exp", 1, f_f, exp ), JS_CFUNC_SPECIAL_DEF("log", 1, f_f, log ), JS_CFUNC_SPECIAL_DEF("pow", 2, f_f_f, js_pow ), JS_CFUNC_SPECIAL_DEF("sin", 1, f_f, sin ), JS_CFUNC_SPECIAL_DEF("tan", 1, f_f, tan ), /* ES6 */ JS_CFUNC_SPECIAL_DEF("trunc", 1, f_f, trunc ), JS_CFUNC_SPECIAL_DEF("sign", 1, f_f, js_math_sign ), JS_CFUNC_SPECIAL_DEF("cosh", 1, f_f, cosh ), JS_CFUNC_SPECIAL_DEF("sinh", 1, f_f, sinh ), JS_CFUNC_SPECIAL_DEF("tanh", 1, f_f, tanh ), JS_CFUNC_SPECIAL_DEF("acosh", 1, f_f, acosh ), JS_CFUNC_SPECIAL_DEF("asinh", 1, f_f, asinh ), JS_CFUNC_SPECIAL_DEF("atanh", 1, f_f, atanh ), JS_CFUNC_SPECIAL_DEF("expm1", 1, f_f, expm1 ), JS_CFUNC_SPECIAL_DEF("log1p", 1, f_f, log1p ), JS_CFUNC_SPECIAL_DEF("log2", 1, f_f, log2 ), JS_CFUNC_SPECIAL_DEF("log10", 1, f_f, log10 ), JS_CFUNC_SPECIAL_DEF("cbrt", 1, f_f, cbrt ), JS_CFUNC_DEF("hypot", 2, js_math_hypot ), JS_CFUNC_DEF("random", 0, js_math_random ), JS_CFUNC_SPECIAL_DEF("f16round", 1, f_f, js_math_f16round ), JS_CFUNC_SPECIAL_DEF("fround", 1, f_f, js_math_fround ), JS_CFUNC_DEF("imul", 2, js_math_imul ), JS_CFUNC_DEF("clz32", 1, js_math_clz32 ), JS_CFUNC_DEF("sumPrecise", 1, js_math_sumPrecise ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Math", JS_PROP_CONFIGURABLE ), JS_PROP_DOUBLE_DEF("E", 2.718281828459045, 0 ), JS_PROP_DOUBLE_DEF("LN10", 2.302585092994046, 0 ), JS_PROP_DOUBLE_DEF("LN2", 0.6931471805599453, 0 ), JS_PROP_DOUBLE_DEF("LOG2E", 1.4426950408889634, 0 ), JS_PROP_DOUBLE_DEF("LOG10E", 0.4342944819032518, 0 ), JS_PROP_DOUBLE_DEF("PI", 3.141592653589793, 0 ), JS_PROP_DOUBLE_DEF("SQRT1_2", 0.7071067811865476, 0 ), JS_PROP_DOUBLE_DEF("SQRT2", 1.4142135623730951, 0 ), }; static const JSCFunctionListEntry js_math_obj[] = { JS_OBJECT_DEF("Math", js_math_funcs, countof(js_math_funcs), JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE ), }; /* Date */ /* OS dependent. d = argv[0] is in ms from 1970. Return the difference between UTC time and local time 'd' in minutes */ static int getTimezoneOffset(int64_t time) { #if 0 /* TODO expose this as a hook */ time_t ti; int res; time /= 1000; /* convert to seconds */ if (sizeof(time_t) == 4) { /* on 32-bit systems, we need to clamp the time value to the range of `time_t`. This is better than truncating values to 32 bits and hopefully provides the same result as 64-bit implementation of localtime_r. */ if ((time_t)-1 < 0) { if (time < INT32_MIN) { time = INT32_MIN; } else if (time > INT32_MAX) { time = INT32_MAX; } } else { if (time < 0) { time = 0; } else if (time > UINT32_MAX) { time = UINT32_MAX; } } } ti = time; #if defined(_WIN32) { struct tm *tm; time_t gm_ti, loc_ti; tm = gmtime(&ti); if (!tm) return 0; gm_ti = mktime(tm); tm = localtime(&ti); if (!tm) return 0; loc_ti = mktime(tm); res = (gm_ti - loc_ti) / 60; } #else { struct tm tm; localtime_r(&ti, &tm); res = -tm.tm_gmtoff / 60; } #endif return res; #endif /* 0 */ return 0; } #if 0 static JSValue js___date_getTimezoneOffset(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { double dd; if (JS_ToFloat64(ctx, &dd, argv[0])) return JS_EXCEPTION; if (isnan(dd)) return __JS_NewFloat64(ctx, dd); else return JS_NewInt32(ctx, getTimezoneOffset((int64_t)dd)); } static JSValue js_get_prototype_from_ctor(JSContext *ctx, JSValueConst ctor, JSValueConst def_proto) { JSValue proto; proto = JS_GetProperty(ctx, ctor, JS_ATOM_prototype); if (JS_IsException(proto)) return proto; if (!JS_IsObject(proto)) { JS_FreeValue(ctx, proto); proto = JS_DupValue(ctx, def_proto); } return proto; } /* create a new date object */ static JSValue js___date_create(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj, proto; proto = js_get_prototype_from_ctor(ctx, argv[0], argv[1]); if (JS_IsException(proto)) return proto; obj = JS_NewObjectProtoClass(ctx, proto, JS_CLASS_DATE); JS_FreeValue(ctx, proto); if (!JS_IsException(obj)) JS_SetObjectData(ctx, obj, JS_DupValue(ctx, argv[2])); return obj; } #endif /* RegExp */ static void js_regexp_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); JSRegExp *re = &p->u.regexp; if (re->bytecode != NULL) JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_STRING, re->bytecode)); if (re->pattern != NULL) JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_STRING, re->pattern)); } /* create a string containing the RegExp bytecode */ static JSValue js_compile_regexp(JSContext *ctx, JSValueConst pattern, JSValueConst flags) { const char *str; int re_flags, mask; uint8_t *re_bytecode_buf; size_t i, len; int re_bytecode_len; JSValue ret; char error_msg[64]; re_flags = 0; if (!JS_IsUndefined(flags)) { str = JS_ToCStringLen(ctx, &len, flags); if (!str) return JS_EXCEPTION; /* XXX: re_flags = LRE_FLAG_OCTAL unless strict mode? */ for (i = 0; i < len; i++) { switch(str[i]) { case 'd': mask = LRE_FLAG_INDICES; break; case 'g': mask = LRE_FLAG_GLOBAL; break; case 'i': mask = LRE_FLAG_IGNORECASE; break; case 'm': mask = LRE_FLAG_MULTILINE; break; case 's': mask = LRE_FLAG_DOTALL; break; case 'u': mask = LRE_FLAG_UNICODE; break; case 'v': mask = LRE_FLAG_UNICODE_SETS; break; case 'y': mask = LRE_FLAG_STICKY; break; default: goto bad_flags; } if ((re_flags & mask) != 0) { bad_flags: JS_FreeCString(ctx, str); goto bad_flags1; } re_flags |= mask; } JS_FreeCString(ctx, str); } /* 'u' and 'v' cannot be both set */ if ((re_flags & LRE_FLAG_UNICODE_SETS) && (re_flags & LRE_FLAG_UNICODE)) { bad_flags1: return JS_ThrowSyntaxError(ctx, "invalid regular expression flags"); } str = JS_ToCStringLen2(ctx, &len, pattern, !(re_flags & (LRE_FLAG_UNICODE | LRE_FLAG_UNICODE_SETS))); if (!str) return JS_EXCEPTION; re_bytecode_buf = lre_compile(&re_bytecode_len, error_msg, sizeof(error_msg), str, len, re_flags, ctx); JS_FreeCString(ctx, str); if (!re_bytecode_buf) { JS_ThrowSyntaxError(ctx, "%s", error_msg); return JS_EXCEPTION; } ret = js_new_string8_len(ctx, (const char *)re_bytecode_buf, re_bytecode_len); js_free(ctx, re_bytecode_buf); return ret; } /* fast regexp creation */ static JSValue JS_NewRegexp(JSContext *ctx, JSValue pattern, JSValue bc) { JSValue obj; JSProperty props[1]; JSObject *p; JSRegExp *re; /* sanity check */ if (unlikely(JS_VALUE_GET_TAG(bc) != JS_TAG_STRING || JS_VALUE_GET_TAG(pattern) != JS_TAG_STRING)) { JS_ThrowTypeError(ctx, "string expected"); goto fail; } props[0].u.value = JS_NewInt32(ctx, 0); /* lastIndex */ obj = JS_NewObjectFromShape(ctx, js_dup_shape(ctx->regexp_shape), JS_CLASS_REGEXP, props); if (JS_IsException(obj)) goto fail; p = JS_VALUE_GET_OBJ(obj); re = &p->u.regexp; re->pattern = JS_VALUE_GET_STRING(pattern); re->bytecode = JS_VALUE_GET_STRING(bc); return obj; fail: JS_FreeValue(ctx, bc); JS_FreeValue(ctx, pattern); return JS_EXCEPTION; } /* set the RegExp fields */ static JSValue js_regexp_set_internal(JSContext *ctx, JSValue obj, JSValue pattern, JSValue bc) { JSObject *p; JSRegExp *re; /* sanity check */ if (unlikely(JS_VALUE_GET_TAG(bc) != JS_TAG_STRING || JS_VALUE_GET_TAG(pattern) != JS_TAG_STRING)) { JS_ThrowTypeError(ctx, "string expected"); JS_FreeValue(ctx, obj); JS_FreeValue(ctx, bc); JS_FreeValue(ctx, pattern); return JS_EXCEPTION; } p = JS_VALUE_GET_OBJ(obj); re = &p->u.regexp; re->pattern = JS_VALUE_GET_STRING(pattern); re->bytecode = JS_VALUE_GET_STRING(bc); /* Note: cannot fail because the field is preallocated */ JS_DefinePropertyValue(ctx, obj, JS_ATOM_lastIndex, JS_NewInt32(ctx, 0), JS_PROP_WRITABLE); return obj; } static JSRegExp *js_get_regexp(JSContext *ctx, JSValueConst obj, BOOL throw_error) { if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { JSObject *p = JS_VALUE_GET_OBJ(obj); if (p->class_id == JS_CLASS_REGEXP) return &p->u.regexp; } if (throw_error) { JS_ThrowTypeErrorInvalidClass(ctx, JS_CLASS_REGEXP); } return NULL; } uint8_t *JS_GetRegExpBytecode(JSContext *ctx, JSValueConst obj, int *plen) { JSRegExp *re; if ((re = js_get_regexp(ctx, obj, TRUE)) == NULL) return NULL; *plen = re->bytecode->len; return re->bytecode->u.str8; } /* return < 0 if exception or TRUE/FALSE */ static int js_is_regexp(JSContext *ctx, JSValueConst obj) { JSValue m; if (!JS_IsObject(obj)) return FALSE; m = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_match); if (JS_IsException(m)) return -1; if (!JS_IsUndefined(m)) return JS_ToBoolFree(ctx, m); return js_get_regexp(ctx, obj, FALSE) != NULL; } static JSValue js_regexp_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { JSValue pattern, flags, bc, val, obj = JS_UNDEFINED; JSValueConst pat, flags1; JSRegExp *re; int pat_is_regexp; pat = argv[0]; flags1 = argv[1]; pat_is_regexp = js_is_regexp(ctx, pat); if (pat_is_regexp < 0) return JS_EXCEPTION; if (JS_IsUndefined(new_target)) { /* called as a function */ new_target = JS_GetActiveFunction(ctx); if (pat_is_regexp && JS_IsUndefined(flags1)) { JSValue ctor; BOOL res; ctor = JS_GetProperty(ctx, pat, JS_ATOM_constructor); if (JS_IsException(ctor)) return ctor; res = js_same_value(ctx, ctor, new_target); JS_FreeValue(ctx, ctor); if (res) return JS_DupValue(ctx, pat); } } re = js_get_regexp(ctx, pat, FALSE); flags = JS_UNDEFINED; if (re) { pattern = JS_DupValue(ctx, JS_MKPTR(JS_TAG_STRING, re->pattern)); if (JS_IsUndefined(flags1)) { bc = JS_DupValue(ctx, JS_MKPTR(JS_TAG_STRING, re->bytecode)); obj = js_create_from_ctor(ctx, new_target, JS_CLASS_REGEXP); if (JS_IsException(obj)) goto fail; goto no_compilation; } else { flags = JS_DupValue(ctx, flags1); } } else { if (pat_is_regexp) { pattern = JS_GetProperty(ctx, pat, JS_ATOM_source); if (JS_IsException(pattern)) goto fail; if (JS_IsUndefined(flags1)) { flags = JS_GetProperty(ctx, pat, JS_ATOM_flags); if (JS_IsException(flags)) goto fail; } else { flags = JS_DupValue(ctx, flags1); } } else { pattern = JS_DupValue(ctx, pat); flags = JS_DupValue(ctx, flags1); } if (JS_IsUndefined(pattern)) { pattern = JS_AtomToString(ctx, JS_ATOM_empty_string); } else { val = pattern; pattern = JS_ToString(ctx, val); JS_FreeValue(ctx, val); if (JS_IsException(pattern)) goto fail; } } obj = js_create_from_ctor(ctx, new_target, JS_CLASS_REGEXP); if (JS_IsException(obj)) goto fail; bc = js_compile_regexp(ctx, pattern, flags); if (JS_IsException(bc)) goto fail; JS_FreeValue(ctx, flags); no_compilation: return js_regexp_set_internal(ctx, obj, pattern, bc); fail: JS_FreeValue(ctx, pattern); JS_FreeValue(ctx, flags); JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_regexp_compile(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSRegExp *re1, *re; JSValueConst pattern1, flags1; JSValue bc, pattern; re = js_get_regexp(ctx, this_val, TRUE); if (!re) return JS_EXCEPTION; pattern1 = argv[0]; flags1 = argv[1]; re1 = js_get_regexp(ctx, pattern1, FALSE); if (re1) { if (!JS_IsUndefined(flags1)) return JS_ThrowTypeError(ctx, "flags must be undefined"); pattern = JS_DupValue(ctx, JS_MKPTR(JS_TAG_STRING, re1->pattern)); bc = JS_DupValue(ctx, JS_MKPTR(JS_TAG_STRING, re1->bytecode)); } else { bc = JS_UNDEFINED; if (JS_IsUndefined(pattern1)) pattern = JS_AtomToString(ctx, JS_ATOM_empty_string); else pattern = JS_ToString(ctx, pattern1); if (JS_IsException(pattern)) goto fail; bc = js_compile_regexp(ctx, pattern, flags1); if (JS_IsException(bc)) goto fail; } JS_FreeValue(ctx, JS_MKPTR(JS_TAG_STRING, re->pattern)); JS_FreeValue(ctx, JS_MKPTR(JS_TAG_STRING, re->bytecode)); re->pattern = JS_VALUE_GET_STRING(pattern); re->bytecode = JS_VALUE_GET_STRING(bc); if (JS_SetProperty(ctx, this_val, JS_ATOM_lastIndex, JS_NewInt32(ctx, 0)) < 0) return JS_EXCEPTION; return JS_DupValue(ctx, this_val); fail: JS_FreeValue(ctx, pattern); JS_FreeValue(ctx, bc); return JS_EXCEPTION; } static JSValue js_regexp_get_source(JSContext *ctx, JSValueConst this_val) { JSRegExp *re; JSString *p; StringBuffer b_s, *b = &b_s; int i, n, c, c2, bra; if (JS_VALUE_GET_TAG(this_val) != JS_TAG_OBJECT) return JS_ThrowTypeErrorNotAnObject(ctx); if (js_same_value(ctx, this_val, ctx->class_proto[JS_CLASS_REGEXP])) goto empty_regex; re = js_get_regexp(ctx, this_val, TRUE); if (!re) return JS_EXCEPTION; p = re->pattern; if (p->len == 0) { empty_regex: return js_new_string8(ctx, "(?:)"); } string_buffer_init2(ctx, b, p->len, p->is_wide_char); /* Escape '/' and newline sequences as needed */ bra = 0; for (i = 0, n = p->len; i < n;) { c2 = -1; switch (c = string_get(p, i++)) { case '\\': if (i < n) c2 = string_get(p, i++); break; case ']': bra = 0; break; case '[': if (!bra) { if (i < n && string_get(p, i) == ']') c2 = string_get(p, i++); bra = 1; } break; case '\n': c = '\\'; c2 = 'n'; break; case '\r': c = '\\'; c2 = 'r'; break; case '/': if (!bra) { c = '\\'; c2 = '/'; } break; } string_buffer_putc16(b, c); if (c2 >= 0) string_buffer_putc16(b, c2); } return string_buffer_end(b); } static JSValue js_regexp_get_flag(JSContext *ctx, JSValueConst this_val, int mask) { JSRegExp *re; int flags; if (JS_VALUE_GET_TAG(this_val) != JS_TAG_OBJECT) return JS_ThrowTypeErrorNotAnObject(ctx); re = js_get_regexp(ctx, this_val, FALSE); if (!re) { if (js_same_value(ctx, this_val, ctx->class_proto[JS_CLASS_REGEXP])) return JS_UNDEFINED; else return JS_ThrowTypeErrorInvalidClass(ctx, JS_CLASS_REGEXP); } flags = lre_get_flags(re->bytecode->u.str8); return JS_NewBool(ctx, flags & mask); } #define RE_FLAG_COUNT 8 static JSValue js_regexp_get_flags(JSContext *ctx, JSValueConst this_val) { char str[RE_FLAG_COUNT], *p = str; int res, i; static const int flag_atom[RE_FLAG_COUNT] = { JS_ATOM_hasIndices, JS_ATOM_global, JS_ATOM_ignoreCase, JS_ATOM_multiline, JS_ATOM_dotAll, JS_ATOM_unicode, JS_ATOM_unicodeSets, JS_ATOM_sticky, }; static const char flag_char[RE_FLAG_COUNT] = { 'd', 'g', 'i', 'm', 's', 'u', 'v', 'y' }; if (JS_VALUE_GET_TAG(this_val) != JS_TAG_OBJECT) return JS_ThrowTypeErrorNotAnObject(ctx); for(i = 0; i < RE_FLAG_COUNT; i++) { res = JS_ToBoolFree(ctx, JS_GetProperty(ctx, this_val, flag_atom[i])); if (res < 0) goto exception; if (res) *p++ = flag_char[i]; } return JS_NewStringLen(ctx, str, p - str); exception: return JS_EXCEPTION; } static JSValue js_regexp_toString(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue pattern, flags; StringBuffer b_s, *b = &b_s; if (!JS_IsObject(this_val)) return JS_ThrowTypeErrorNotAnObject(ctx); string_buffer_init(ctx, b, 0); string_buffer_putc8(b, '/'); pattern = JS_GetProperty(ctx, this_val, JS_ATOM_source); if (string_buffer_concat_value_free(b, pattern)) goto fail; string_buffer_putc8(b, '/'); flags = JS_GetProperty(ctx, this_val, JS_ATOM_flags); if (string_buffer_concat_value_free(b, flags)) goto fail; return string_buffer_end(b); fail: string_buffer_free(b); return JS_EXCEPTION; } int lre_check_stack_overflow(void *opaque, size_t alloca_size) { JSContext *ctx = opaque; if (!ctx) return 0; return js_check_stack_overflow(ctx->rt, alloca_size); } int lre_check_timeout(void *opaque) { JSContext *ctx = opaque; JSRuntime *rt; if (!ctx) return 0; rt = ctx->rt; return (rt->interrupt_handler && rt->interrupt_handler(rt, rt->interrupt_opaque)); } #ifndef CHA_BUILD void *lre_realloc(void *opaque, void *ptr, size_t size) { JSContext *ctx = opaque; /* No JS exception is raised here */ return js_realloc_rt(ctx->rt, ptr, size); } #endif static JSValue js_regexp_escape(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue str; StringBuffer b_s, *b = &b_s; JSString *p; uint32_t c; char s[16]; int i, i0; if (!JS_IsString(argv[0])) return JS_ThrowTypeError(ctx, "not a string"); str = JS_ToString(ctx, argv[0]); /* must call it to linearlize ropes */ if (JS_IsException(str)) return JS_EXCEPTION; p = JS_VALUE_GET_STRING(str); string_buffer_init2(ctx, b, 0, p->is_wide_char); for (i = 0; i < p->len; ) { i0 = i; c = string_getc(p, &i); if (c < 33) { if (c >= 9 && c <= 13) { string_buffer_putc8(b, '\\'); string_buffer_putc8(b, "tnvfr"[c - 9]); } else { goto hex2; } } else if (c < 128) { if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { if (i0 == 0) goto hex2; } else if (strchr(",-=<>#&!%:;@~'`\"", c)) { goto hex2; } else if (c != '_') { string_buffer_putc8(b, '\\'); } string_buffer_putc8(b, c); } else if (c < 256) { hex2: snprintf(s, sizeof(s), "\\x%02x", c); string_buffer_puts8(b, s); } else if (is_surrogate(c) || lre_is_space(c)) { snprintf(s, sizeof(s), "\\u%04x", c); string_buffer_puts8(b, s); } else { string_buffer_putc(b, c); } } JS_FreeValue(ctx, str); return string_buffer_end(b); } /* this_val must be of JS_CLASS_REGEXP */ static force_inline int js_regexp_get_lastIndex(JSContext *ctx, int64_t *plast_index, JSValueConst this_val) { JSObject *p = JS_VALUE_GET_OBJ(this_val); /* lastIndex is always the first property (it is not configurable) */ if (likely(JS_VALUE_GET_TAG(p->prop[0].u.value) == JS_TAG_INT)) { *plast_index = max_int(JS_VALUE_GET_INT(p->prop[0].u.value), 0); return 0; } else { return JS_ToLengthFree(ctx, plast_index, JS_DupValue(ctx, p->prop[0].u.value)); } } /* this_val must be of JS_CLASS_REGEXP */ static force_inline int js_regexp_set_lastIndex(JSContext *ctx, JSValueConst this_val, int last_index) { JSObject *p = JS_VALUE_GET_OBJ(this_val); /* lastIndex is always the first property (it is not configurable) */ if (likely(JS_VALUE_GET_TAG(p->prop[0].u.value) == JS_TAG_INT && (get_shape_prop(p->shape)->flags & JS_PROP_WRITABLE))) { set_value(ctx, &p->prop[0].u.value, JS_NewInt32(ctx, last_index)); } else { if (JS_SetProperty(ctx, this_val, JS_ATOM_lastIndex, JS_NewInt32(ctx, last_index)) < 0) return -1; } return 0; } static JSValue js_regexp_exec(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSRegExp *re = js_get_regexp(ctx, this_val, TRUE); JSString *str; JSValue t, ret, str_val, obj, groups; JSValue indices, indices_groups; uint8_t *re_bytecode; uint8_t **capture, *str_buf; int rc, capture_count, shift, i, re_flags, alloc_count; int64_t last_index; const char *group_name_ptr; JSObject *p_obj; JSAtom group_name; if (!re) return JS_EXCEPTION; str_val = JS_ToString(ctx, argv[0]); if (JS_IsException(str_val)) return JS_EXCEPTION; ret = JS_EXCEPTION; obj = JS_NULL; groups = JS_UNDEFINED; indices = JS_UNDEFINED; indices_groups = JS_UNDEFINED; capture = NULL; group_name = JS_ATOM_NULL; if (js_regexp_get_lastIndex(ctx, &last_index, this_val)) goto fail; re_bytecode = re->bytecode->u.str8; re_flags = lre_get_flags(re_bytecode); if ((re_flags & (LRE_FLAG_GLOBAL | LRE_FLAG_STICKY)) == 0) { last_index = 0; } str = JS_VALUE_GET_STRING(str_val); alloc_count = lre_get_alloc_count(re_bytecode); if (alloc_count > 0) { capture = js_malloc(ctx, sizeof(capture[0]) * alloc_count); if (!capture) goto fail; } capture_count = lre_get_capture_count(re_bytecode); shift = str->is_wide_char; str_buf = str->u.str8; if (last_index > str->len) { rc = 2; } else { rc = lre_exec(capture, re_bytecode, str_buf, last_index, str->len, shift, ctx); } if (rc != 1) { if (rc >= 0) { if (rc == 2 || (re_flags & (LRE_FLAG_GLOBAL | LRE_FLAG_STICKY))) { if (js_regexp_set_lastIndex(ctx, this_val, 0) < 0) goto fail; } } else { if (rc == LRE_RET_TIMEOUT) { JS_ThrowInterrupted(ctx); } else { JS_ThrowInternalError(ctx, "out of memory in regexp execution"); } goto fail; } } else { int prop_flags; JSProperty props[4]; if (re_flags & (LRE_FLAG_GLOBAL | LRE_FLAG_STICKY)) { if (js_regexp_set_lastIndex(ctx, this_val, (capture[1] - str_buf) >> shift) < 0) goto fail; } prop_flags = JS_PROP_C_W_E | JS_PROP_THROW; group_name_ptr = lre_get_groupnames(re_bytecode); if (group_name_ptr) { groups = JS_NewObjectProto(ctx, JS_NULL); if (JS_IsException(groups)) goto fail; } if (re_flags & LRE_FLAG_INDICES) { indices = JS_NewArray(ctx); if (JS_IsException(indices)) goto fail; if (group_name_ptr) { indices_groups = JS_NewObjectProto(ctx, JS_NULL); if (JS_IsException(indices_groups)) goto fail; } } props[0].u.value = JS_NewInt32(ctx, capture_count); /* length */ props[1].u.value = JS_NewInt32(ctx, (capture[0] - str_buf) >> shift); /* index */ props[2].u.value = str_val; /* input */ props[3].u.value = JS_DupValue(ctx, groups); /* groups */ str_val = JS_UNDEFINED; obj = JS_NewObjectFromShape(ctx, js_dup_shape(ctx->regexp_result_shape), JS_CLASS_ARRAY, props); if (JS_IsException(obj)) goto fail; p_obj = JS_VALUE_GET_OBJ(obj); if (expand_fast_array(ctx, p_obj, capture_count)) goto fail; for(i = 0; i < capture_count; i++) { uint8_t **match = &capture[2 * i]; int start = -1; int end = -1; JSValue val; if (group_name_ptr && i > 0) { if (*group_name_ptr) { /* XXX: slow, should create a shape when the regexp is compiled */ group_name = JS_NewAtom(ctx, group_name_ptr); if (group_name == JS_ATOM_NULL) goto fail; } group_name_ptr += strlen(group_name_ptr) + LRE_GROUP_NAME_TRAILER_LEN; } if (match[0] && match[1]) { start = (match[0] - str_buf) >> shift; end = (match[1] - str_buf) >> shift; } if (!JS_IsUndefined(indices)) { val = JS_UNDEFINED; if (start != -1) { val = JS_NewArray(ctx); if (JS_IsException(val)) goto fail; if (JS_DefinePropertyValueUint32(ctx, val, 0, JS_NewInt32(ctx, start), prop_flags) < 0) { JS_FreeValue(ctx, val); goto fail; } if (JS_DefinePropertyValueUint32(ctx, val, 1, JS_NewInt32(ctx, end), prop_flags) < 0) { JS_FreeValue(ctx, val); goto fail; } } if (group_name != JS_ATOM_NULL) { /* JS_HasProperty() cannot fail here */ if (!JS_IsUndefined(val) || !JS_HasProperty(ctx, indices_groups, group_name)) { if (JS_DefinePropertyValue(ctx, indices_groups, group_name, JS_DupValue(ctx, val), prop_flags) < 0) { JS_FreeValue(ctx, val); goto fail; } } } if (JS_DefinePropertyValueUint32(ctx, indices, i, val, prop_flags) < 0) { goto fail; } } val = JS_UNDEFINED; if (start != -1) { val = js_sub_string(ctx, str, start, end); if (JS_IsException(val)) goto fail; } if (group_name != JS_ATOM_NULL) { /* JS_HasProperty() cannot fail here */ if (!JS_IsUndefined(val) || !JS_HasProperty(ctx, groups, group_name)) { if (JS_DefinePropertyValue(ctx, groups, group_name, JS_DupValue(ctx, val), prop_flags) < 0) { JS_FreeValue(ctx, val); goto fail; } } JS_FreeAtom(ctx, group_name); group_name = JS_ATOM_NULL; } p_obj->u.array.u.values[p_obj->u.array.count++] = val; } if (!JS_IsUndefined(indices)) { t = indices_groups, indices_groups = JS_UNDEFINED; if (JS_DefinePropertyValue(ctx, indices, JS_ATOM_groups, t, prop_flags) < 0) { goto fail; } t = indices, indices = JS_UNDEFINED; if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_indices, t, prop_flags) < 0) { goto fail; } } } ret = obj; obj = JS_UNDEFINED; fail: JS_FreeAtom(ctx, group_name); JS_FreeValue(ctx, indices_groups); JS_FreeValue(ctx, indices); JS_FreeValue(ctx, str_val); JS_FreeValue(ctx, groups); JS_FreeValue(ctx, obj); js_free(ctx, capture); return ret; } /* XXX: add group names support */ static JSValue js_regexp_replace(JSContext *ctx, JSValueConst this_val, JSValueConst arg, JSValueConst rep_val) { JSRegExp *re = js_get_regexp(ctx, this_val, TRUE); JSString *str; JSValue str_val; uint8_t *re_bytecode; int ret; uint8_t **capture, *str_buf; int capture_count, alloc_count, shift, re_flags; int next_src_pos, start, end; int64_t last_index; StringBuffer b_s, *b = &b_s; JSString *rp = JS_VALUE_GET_STRING(rep_val); const char *group_name_ptr; BOOL fullUnicode; if (!re) return JS_EXCEPTION; re_bytecode = re->bytecode->u.str8; group_name_ptr = lre_get_groupnames(re_bytecode); if (group_name_ptr) return JS_UNDEFINED; /* group names are not supported yet */ string_buffer_init(ctx, b, 0); capture = NULL; str_val = JS_ToString(ctx, arg); if (JS_IsException(str_val)) goto fail; str = JS_VALUE_GET_STRING(str_val); re_flags = lre_get_flags(re_bytecode); if (re_flags & LRE_FLAG_GLOBAL) { if (js_regexp_set_lastIndex(ctx, this_val, 0)) goto fail; } if ((re_flags & (LRE_FLAG_GLOBAL | LRE_FLAG_STICKY)) == 0) { last_index = 0; } else { if (js_regexp_get_lastIndex(ctx, &last_index, this_val)) goto fail; } alloc_count = lre_get_alloc_count(re_bytecode); if (alloc_count > 0) { capture = js_malloc(ctx, sizeof(capture[0]) * alloc_count); if (!capture) goto fail; } capture_count = lre_get_capture_count(re_bytecode); fullUnicode = ((re_flags & (LRE_FLAG_UNICODE | LRE_FLAG_UNICODE_SETS)) != 0); shift = str->is_wide_char; str_buf = str->u.str8; next_src_pos = 0; for (;;) { if (last_index > str->len) { ret = 0; } else { ret = lre_exec(capture, re_bytecode, str_buf, last_index, str->len, shift, ctx); } if (ret != 1) { if (ret >= 0) { if (ret == 2 || (re_flags & (LRE_FLAG_GLOBAL | LRE_FLAG_STICKY))) { if (js_regexp_set_lastIndex(ctx, this_val, 0) < 0) goto fail; } } else { if (ret == LRE_RET_TIMEOUT) { JS_ThrowInterrupted(ctx); } else { JS_ThrowInternalError(ctx, "out of memory in regexp execution"); } goto fail; } break; } start = (capture[0] - str_buf) >> shift; end = (capture[1] - str_buf) >> shift; last_index = end; if (next_src_pos < start) { if (string_buffer_concat(b, str, next_src_pos, start)) goto fail; } if (rp->len != 0) { if (js_string_GetSubstitution(ctx, b, JS_UNDEFINED, str, start, JS_UNDEFINED, JS_UNDEFINED, rep_val, capture, capture_count)) { goto fail; } } next_src_pos = end; if (!(re_flags & LRE_FLAG_GLOBAL)) { if (re_flags & LRE_FLAG_STICKY) { if (js_regexp_set_lastIndex(ctx, this_val, end) < 0) goto fail; } break; } if (end == start) { end = string_advance_index(str, end, fullUnicode); } last_index = end; } if (string_buffer_concat(b, str, next_src_pos, str->len)) goto fail; JS_FreeValue(ctx, str_val); js_free(ctx, capture); return string_buffer_end(b); fail: JS_FreeValue(ctx, str_val); js_free(ctx, capture); string_buffer_free(b); return JS_EXCEPTION; } static JSValue JS_RegExpExec(JSContext *ctx, JSValueConst r, JSValueConst s) { JSValue method, ret; method = JS_GetProperty(ctx, r, JS_ATOM_exec); if (JS_IsException(method)) return method; if (JS_IsFunction(ctx, method)) { ret = JS_CallFree(ctx, method, r, 1, &s); if (JS_IsException(ret)) return ret; if (!JS_IsObject(ret) && !JS_IsNull(ret)) { JS_FreeValue(ctx, ret); return JS_ThrowTypeError(ctx, "RegExp exec method must return an object or null"); } return ret; } JS_FreeValue(ctx, method); return js_regexp_exec(ctx, r, 1, &s); } static JSValue js_regexp_test(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue val; BOOL ret; val = JS_RegExpExec(ctx, this_val, argv[0]); if (JS_IsException(val)) return JS_EXCEPTION; ret = !JS_IsNull(val); JS_FreeValue(ctx, val); return JS_NewBool(ctx, ret); } static JSValue js_regexp_Symbol_match(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // [Symbol.match](str) JSValueConst rx = this_val; JSValue A, S, flags, result, matchStr; int global, n, fullUnicode, isEmpty; JSString *p; if (!JS_IsObject(rx)) return JS_ThrowTypeErrorNotAnObject(ctx); A = JS_UNDEFINED; flags = JS_UNDEFINED; result = JS_UNDEFINED; matchStr = JS_UNDEFINED; S = JS_ToString(ctx, argv[0]); if (JS_IsException(S)) goto exception; flags = JS_GetProperty(ctx, rx, JS_ATOM_flags); if (JS_IsException(flags)) goto exception; flags = JS_ToStringFree(ctx, flags); if (JS_IsException(flags)) goto exception; p = JS_VALUE_GET_STRING(flags); global = (-1 != string_indexof_char(p, 'g', 0)); if (!global) { A = JS_RegExpExec(ctx, rx, S); } else { fullUnicode = (string_indexof_char(p, 'u', 0) >= 0 || string_indexof_char(p, 'v', 0) >= 0); if (JS_SetProperty(ctx, rx, JS_ATOM_lastIndex, JS_NewInt32(ctx, 0)) < 0) goto exception; A = JS_NewArray(ctx); if (JS_IsException(A)) goto exception; n = 0; for(;;) { JS_FreeValue(ctx, result); result = JS_RegExpExec(ctx, rx, S); if (JS_IsException(result)) goto exception; if (JS_IsNull(result)) break; matchStr = JS_ToStringFree(ctx, JS_GetPropertyInt64(ctx, result, 0)); if (JS_IsException(matchStr)) goto exception; isEmpty = JS_IsEmptyString(matchStr); if (JS_DefinePropertyValueInt64(ctx, A, n++, matchStr, JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception; if (isEmpty) { int64_t thisIndex, nextIndex; if (JS_ToLengthFree(ctx, &thisIndex, JS_GetProperty(ctx, rx, JS_ATOM_lastIndex)) < 0) goto exception; p = JS_VALUE_GET_STRING(S); nextIndex = string_advance_index(p, thisIndex, fullUnicode); if (JS_SetProperty(ctx, rx, JS_ATOM_lastIndex, JS_NewInt64(ctx, nextIndex)) < 0) goto exception; } } if (n == 0) { JS_FreeValue(ctx, A); A = JS_NULL; } } JS_FreeValue(ctx, result); JS_FreeValue(ctx, flags); JS_FreeValue(ctx, S); return A; exception: JS_FreeValue(ctx, A); JS_FreeValue(ctx, result); JS_FreeValue(ctx, flags); JS_FreeValue(ctx, S); return JS_EXCEPTION; } typedef struct JSRegExpStringIteratorData { JSValue iterating_regexp; JSValue iterated_string; BOOL global; BOOL unicode; BOOL done; } JSRegExpStringIteratorData; static void js_regexp_string_iterator_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); JSRegExpStringIteratorData *it = p->u.regexp_string_iterator_data; if (it) { JS_FreeValueRT(rt, it->iterating_regexp); JS_FreeValueRT(rt, it->iterated_string); js_free_rt(rt, it); } } static void js_regexp_string_iterator_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); JSRegExpStringIteratorData *it = p->u.regexp_string_iterator_data; if (it) { JS_MarkValue(rt, it->iterating_regexp, mark_func); JS_MarkValue(rt, it->iterated_string, mark_func); } } static JSValue js_regexp_string_iterator_next(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, BOOL *pdone, int magic) { JSRegExpStringIteratorData *it; JSValueConst R, S; JSValue matchStr = JS_UNDEFINED, match = JS_UNDEFINED; JSString *sp; it = JS_GetOpaque2(ctx, this_val, JS_CLASS_REGEXP_STRING_ITERATOR); if (!it) goto exception; if (it->done) { *pdone = TRUE; return JS_UNDEFINED; } R = it->iterating_regexp; S = it->iterated_string; match = JS_RegExpExec(ctx, R, S); if (JS_IsException(match)) goto exception; if (JS_IsNull(match)) { it->done = TRUE; *pdone = TRUE; return JS_UNDEFINED; } else if (it->global) { matchStr = JS_ToStringFree(ctx, JS_GetPropertyInt64(ctx, match, 0)); if (JS_IsException(matchStr)) goto exception; if (JS_IsEmptyString(matchStr)) { int64_t thisIndex, nextIndex; if (JS_ToLengthFree(ctx, &thisIndex, JS_GetProperty(ctx, R, JS_ATOM_lastIndex)) < 0) goto exception; sp = JS_VALUE_GET_STRING(S); nextIndex = string_advance_index(sp, thisIndex, it->unicode); if (JS_SetProperty(ctx, R, JS_ATOM_lastIndex, JS_NewInt64(ctx, nextIndex)) < 0) goto exception; } JS_FreeValue(ctx, matchStr); } else { it->done = TRUE; } *pdone = FALSE; return match; exception: JS_FreeValue(ctx, match); JS_FreeValue(ctx, matchStr); *pdone = FALSE; return JS_EXCEPTION; } static JSValue js_regexp_Symbol_matchAll(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // [Symbol.matchAll](str) JSValueConst R = this_val; JSValue S, C, flags, matcher, iter; JSValueConst args[2]; JSString *strp; int64_t lastIndex; JSRegExpStringIteratorData *it; if (!JS_IsObject(R)) return JS_ThrowTypeErrorNotAnObject(ctx); C = JS_UNDEFINED; flags = JS_UNDEFINED; matcher = JS_UNDEFINED; iter = JS_UNDEFINED; S = JS_ToString(ctx, argv[0]); if (JS_IsException(S)) goto exception; C = JS_SpeciesConstructor(ctx, R, ctx->regexp_ctor); if (JS_IsException(C)) goto exception; flags = JS_ToStringFree(ctx, JS_GetProperty(ctx, R, JS_ATOM_flags)); if (JS_IsException(flags)) goto exception; args[0] = R; args[1] = flags; matcher = JS_CallConstructor(ctx, C, 2, args); if (JS_IsException(matcher)) goto exception; if (JS_ToLengthFree(ctx, &lastIndex, JS_GetProperty(ctx, R, JS_ATOM_lastIndex))) goto exception; if (JS_SetProperty(ctx, matcher, JS_ATOM_lastIndex, JS_NewInt64(ctx, lastIndex)) < 0) goto exception; iter = JS_NewObjectClass(ctx, JS_CLASS_REGEXP_STRING_ITERATOR); if (JS_IsException(iter)) goto exception; it = js_malloc(ctx, sizeof(*it)); if (!it) goto exception; it->iterating_regexp = matcher; it->iterated_string = S; strp = JS_VALUE_GET_STRING(flags); it->global = string_indexof_char(strp, 'g', 0) >= 0; it->unicode = (string_indexof_char(strp, 'u', 0) >= 0 || string_indexof_char(strp, 'v', 0) >= 0); it->done = FALSE; JS_SetOpaque(iter, it); JS_FreeValue(ctx, C); JS_FreeValue(ctx, flags); return iter; exception: JS_FreeValue(ctx, S); JS_FreeValue(ctx, C); JS_FreeValue(ctx, flags); JS_FreeValue(ctx, matcher); JS_FreeValue(ctx, iter); return JS_EXCEPTION; } typedef struct ValueBuffer { JSContext *ctx; JSValue *arr; JSValue def[4]; int len; int size; int error_status; } ValueBuffer; static int value_buffer_init(JSContext *ctx, ValueBuffer *b) { b->ctx = ctx; b->len = 0; b->size = 4; b->error_status = 0; b->arr = b->def; return 0; } static void value_buffer_free(ValueBuffer *b) { while (b->len > 0) JS_FreeValue(b->ctx, b->arr[--b->len]); if (b->arr != b->def) js_free(b->ctx, b->arr); b->arr = b->def; b->size = 4; } static int value_buffer_append(ValueBuffer *b, JSValue val) { if (b->error_status) return -1; if (b->len >= b->size) { int new_size = (b->len + (b->len >> 1) + 31) & ~16; size_t slack; JSValue *new_arr; if (b->arr == b->def) { new_arr = js_realloc2(b->ctx, NULL, sizeof(*b->arr) * new_size, &slack); if (new_arr) memcpy(new_arr, b->def, sizeof b->def); } else { new_arr = js_realloc2(b->ctx, b->arr, sizeof(*b->arr) * new_size, &slack); } if (!new_arr) { value_buffer_free(b); JS_FreeValue(b->ctx, val); b->error_status = -1; return -1; } new_size += slack / sizeof(*new_arr); b->arr = new_arr; b->size = new_size; } b->arr[b->len++] = val; return 0; } /* find in 'p' or its prototypes */ static JSShapeProperty *find_property_regexp(JSProperty **ppr, JSObject *p, JSAtom atom) { JSShapeProperty *prs; for(;;) { prs = find_own_property(ppr, p, atom); if (prs) return prs; p = p->shape->proto; if (!p) return NULL; if (p->is_exotic) return NULL; } } static BOOL check_regexp_getter(JSContext *ctx, JSObject *p, JSAtom atom, JSCFunction *func, int magic) { JSProperty *pr; JSShapeProperty *prs; prs = find_property_regexp(&pr, p, atom); if (!prs) return FALSE; if ((prs->flags & JS_PROP_TMASK) != JS_PROP_GETSET) return FALSE; if (!pr->u.getset.getter) return FALSE; return JS_IsCFunction(ctx, JS_MKPTR(JS_TAG_OBJECT, pr->u.getset.getter), func, magic); } static BOOL js_is_standard_regexp(JSContext *ctx, JSValueConst obj) { JSObject *p; JSProperty *pr; JSShapeProperty *prs; JSCFunctionType ft; if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) return FALSE; p = JS_VALUE_GET_OBJ(obj); if (p->class_id != JS_CLASS_REGEXP) return FALSE; /* check that the lastIndex is a number (no side effect while getting it) */ prs = find_own_property(&pr, p, JS_ATOM_lastIndex); if (!prs) return FALSE; if (!JS_IsNumber(pr->u.value)) return FALSE; /* check the 'exec' method. */ prs = find_property_regexp(&pr, p, JS_ATOM_exec); if (!prs) return FALSE; if ((prs->flags & JS_PROP_TMASK) != JS_PROP_NORMAL) return FALSE; if (!JS_IsCFunction(ctx, pr->u.value, js_regexp_exec, 0)) return FALSE; /* check the flag getters */ ft.getter = js_regexp_get_flags; if (!check_regexp_getter(ctx, p, JS_ATOM_flags, ft.generic, 0)) return FALSE; ft.getter_magic = js_regexp_get_flag; if (!check_regexp_getter(ctx, p, JS_ATOM_global, ft.generic, LRE_FLAG_GLOBAL)) return FALSE; if (!check_regexp_getter(ctx, p, JS_ATOM_unicode, ft.generic, LRE_FLAG_UNICODE)) return FALSE; /* XXX: need to check all accessors, need a faster way. */ return TRUE; } static JSValue js_regexp_Symbol_replace(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // [Symbol.replace](str, rep) JSValueConst rx = this_val, rep = argv[1]; JSValueConst args[6]; JSValue flags, str, rep_val, matched, tab, rep_str, namedCaptures, res; JSString *p, *sp; StringBuffer b_s, *b = &b_s; ValueBuffer v_b, *results = &v_b; int nextSourcePosition, n, j, functionalReplace, is_global, fullUnicode; uint32_t nCaptures; int64_t position; if (!JS_IsObject(rx)) return JS_ThrowTypeErrorNotAnObject(ctx); string_buffer_init(ctx, b, 0); value_buffer_init(ctx, results); rep_val = JS_UNDEFINED; matched = JS_UNDEFINED; tab = JS_UNDEFINED; flags = JS_UNDEFINED; rep_str = JS_UNDEFINED; namedCaptures = JS_UNDEFINED; str = JS_ToString(ctx, argv[0]); if (JS_IsException(str)) goto exception; sp = JS_VALUE_GET_STRING(str); functionalReplace = JS_IsFunction(ctx, rep); if (!functionalReplace) { rep_val = JS_ToString(ctx, rep); if (JS_IsException(rep_val)) goto exception; } if (!functionalReplace && js_is_standard_regexp(ctx, rx)) { /* use faster version for simple cases */ res = js_regexp_replace(ctx, rx, str, rep_val); if (!JS_IsUndefined(res)) goto done; } flags = JS_GetProperty(ctx, rx, JS_ATOM_flags); if (JS_IsException(flags)) goto exception; flags = JS_ToStringFree(ctx, flags); if (JS_IsException(flags)) goto exception; p = JS_VALUE_GET_STRING(flags); fullUnicode = 0; is_global = (-1 != string_indexof_char(p, 'g', 0)); if (is_global) { fullUnicode = (string_indexof_char(p, 'u', 0) >= 0 || string_indexof_char(p, 'v', 0) >= 0); if (JS_SetProperty(ctx, rx, JS_ATOM_lastIndex, JS_NewInt32(ctx, 0)) < 0) goto exception; } for(;;) { JSValue result; result = JS_RegExpExec(ctx, rx, str); if (JS_IsException(result)) goto exception; if (JS_IsNull(result)) break; if (value_buffer_append(results, result) < 0) goto exception; if (!is_global) break; JS_FreeValue(ctx, matched); matched = JS_ToStringFree(ctx, JS_GetPropertyInt64(ctx, result, 0)); if (JS_IsException(matched)) goto exception; if (JS_IsEmptyString(matched)) { /* always advance of at least one char */ int64_t thisIndex, nextIndex; if (JS_ToLengthFree(ctx, &thisIndex, JS_GetProperty(ctx, rx, JS_ATOM_lastIndex)) < 0) goto exception; nextIndex = string_advance_index(sp, thisIndex, fullUnicode); if (JS_SetProperty(ctx, rx, JS_ATOM_lastIndex, JS_NewInt64(ctx, nextIndex)) < 0) goto exception; } } nextSourcePosition = 0; for(j = 0; j < results->len; j++) { JSValueConst result; result = results->arr[j]; if (js_get_length32(ctx, &nCaptures, result) < 0) goto exception; JS_FreeValue(ctx, matched); matched = JS_ToStringFree(ctx, JS_GetPropertyInt64(ctx, result, 0)); if (JS_IsException(matched)) goto exception; if (JS_ToLengthFree(ctx, &position, JS_GetProperty(ctx, result, JS_ATOM_index))) goto exception; if (position > sp->len) position = sp->len; else if (position < 0) position = 0; /* ignore substition if going backward (can happen with custom regexp object) */ JS_FreeValue(ctx, tab); tab = JS_NewArray(ctx); if (JS_IsException(tab)) goto exception; if (JS_DefinePropertyValueInt64(ctx, tab, 0, JS_DupValue(ctx, matched), JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception; for(n = 1; n < nCaptures; n++) { JSValue capN; capN = JS_GetPropertyInt64(ctx, result, n); if (JS_IsException(capN)) goto exception; if (!JS_IsUndefined(capN)) { capN = JS_ToStringFree(ctx, capN); if (JS_IsException(capN)) goto exception; } if (JS_DefinePropertyValueInt64(ctx, tab, n, capN, JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception; } JS_FreeValue(ctx, namedCaptures); namedCaptures = JS_GetProperty(ctx, result, JS_ATOM_groups); if (JS_IsException(namedCaptures)) goto exception; if (functionalReplace) { if (JS_DefinePropertyValueInt64(ctx, tab, n++, JS_NewInt32(ctx, position), JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception; if (JS_DefinePropertyValueInt64(ctx, tab, n++, JS_DupValue(ctx, str), JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception; if (!JS_IsUndefined(namedCaptures)) { if (JS_DefinePropertyValueInt64(ctx, tab, n++, JS_DupValue(ctx, namedCaptures), JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception; } args[0] = JS_UNDEFINED; args[1] = tab; JS_FreeValue(ctx, rep_str); rep_str = JS_ToStringFree(ctx, js_function_apply(ctx, rep, 2, args, 0)); } else { JSValue namedCaptures1; StringBuffer b1_s, *b1 = &b1_s; int ret; if (!JS_IsUndefined(namedCaptures)) { namedCaptures1 = JS_ToObject(ctx, namedCaptures); if (JS_IsException(namedCaptures1)) goto exception; } else { namedCaptures1 = JS_UNDEFINED; } JS_FreeValue(ctx, rep_str); string_buffer_init(ctx, b1, 0); ret = js_string_GetSubstitution(ctx, b1, matched, sp, position, tab, namedCaptures1, rep_val, NULL, 0); rep_str = string_buffer_end(b1); JS_FreeValue(ctx, namedCaptures1); if (ret) goto exception; } if (JS_IsException(rep_str)) goto exception; if (position >= nextSourcePosition) { string_buffer_concat(b, sp, nextSourcePosition, position); string_buffer_concat_value(b, rep_str); nextSourcePosition = position + JS_VALUE_GET_STRING(matched)->len; } } string_buffer_concat(b, sp, nextSourcePosition, sp->len); res = string_buffer_end(b); goto done1; exception: res = JS_EXCEPTION; done: string_buffer_free(b); done1: value_buffer_free(results); JS_FreeValue(ctx, rep_val); JS_FreeValue(ctx, matched); JS_FreeValue(ctx, flags); JS_FreeValue(ctx, tab); JS_FreeValue(ctx, rep_str); JS_FreeValue(ctx, namedCaptures); JS_FreeValue(ctx, str); return res; } static JSValue js_regexp_Symbol_search(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValueConst rx = this_val; JSValue str, previousLastIndex, currentLastIndex, result, index; if (!JS_IsObject(rx)) return JS_ThrowTypeErrorNotAnObject(ctx); result = JS_UNDEFINED; currentLastIndex = JS_UNDEFINED; previousLastIndex = JS_UNDEFINED; str = JS_ToString(ctx, argv[0]); if (JS_IsException(str)) goto exception; previousLastIndex = JS_GetProperty(ctx, rx, JS_ATOM_lastIndex); if (JS_IsException(previousLastIndex)) goto exception; if (!js_same_value(ctx, previousLastIndex, JS_NewInt32(ctx, 0))) { if (JS_SetProperty(ctx, rx, JS_ATOM_lastIndex, JS_NewInt32(ctx, 0)) < 0) { goto exception; } } result = JS_RegExpExec(ctx, rx, str); if (JS_IsException(result)) goto exception; currentLastIndex = JS_GetProperty(ctx, rx, JS_ATOM_lastIndex); if (JS_IsException(currentLastIndex)) goto exception; if (js_same_value(ctx, currentLastIndex, previousLastIndex)) { JS_FreeValue(ctx, previousLastIndex); } else { if (JS_SetProperty(ctx, rx, JS_ATOM_lastIndex, previousLastIndex) < 0) { previousLastIndex = JS_UNDEFINED; goto exception; } } JS_FreeValue(ctx, str); JS_FreeValue(ctx, currentLastIndex); if (JS_IsNull(result)) { return JS_NewInt32(ctx, -1); } else { index = JS_GetProperty(ctx, result, JS_ATOM_index); JS_FreeValue(ctx, result); return index; } exception: JS_FreeValue(ctx, result); JS_FreeValue(ctx, str); JS_FreeValue(ctx, currentLastIndex); JS_FreeValue(ctx, previousLastIndex); return JS_EXCEPTION; } static JSValue js_regexp_Symbol_split(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // [Symbol.split](str, limit) JSValueConst rx = this_val; JSValueConst args[2]; JSValue str, ctor, splitter, A, flags, z, sub; JSString *strp; uint32_t lim, size, p, q; int unicodeMatching; int64_t lengthA, e, numberOfCaptures, i; if (!JS_IsObject(rx)) return JS_ThrowTypeErrorNotAnObject(ctx); ctor = JS_UNDEFINED; splitter = JS_UNDEFINED; A = JS_UNDEFINED; flags = JS_UNDEFINED; z = JS_UNDEFINED; str = JS_ToString(ctx, argv[0]); if (JS_IsException(str)) goto exception; ctor = JS_SpeciesConstructor(ctx, rx, ctx->regexp_ctor); if (JS_IsException(ctor)) goto exception; flags = JS_ToStringFree(ctx, JS_GetProperty(ctx, rx, JS_ATOM_flags)); if (JS_IsException(flags)) goto exception; strp = JS_VALUE_GET_STRING(flags); unicodeMatching = (string_indexof_char(strp, 'u', 0) >= 0 || string_indexof_char(strp, 'v', 0) >= 0); if (string_indexof_char(strp, 'y', 0) < 0) { flags = JS_ConcatString3(ctx, "", flags, "y"); if (JS_IsException(flags)) goto exception; } args[0] = rx; args[1] = flags; splitter = JS_CallConstructor(ctx, ctor, 2, args); if (JS_IsException(splitter)) goto exception; A = JS_NewArray(ctx); if (JS_IsException(A)) goto exception; lengthA = 0; if (JS_IsUndefined(argv[1])) { lim = 0xffffffff; } else { if (JS_ToUint32(ctx, &lim, argv[1]) < 0) goto exception; if (lim == 0) goto done; } strp = JS_VALUE_GET_STRING(str); p = q = 0; size = strp->len; if (size == 0) { z = JS_RegExpExec(ctx, splitter, str); if (JS_IsException(z)) goto exception; if (JS_IsNull(z)) goto add_tail; goto done; } while (q < size) { if (JS_SetProperty(ctx, splitter, JS_ATOM_lastIndex, JS_NewInt32(ctx, q)) < 0) goto exception; JS_FreeValue(ctx, z); z = JS_RegExpExec(ctx, splitter, str); if (JS_IsException(z)) goto exception; if (JS_IsNull(z)) { q = string_advance_index(strp, q, unicodeMatching); } else { if (JS_ToLengthFree(ctx, &e, JS_GetProperty(ctx, splitter, JS_ATOM_lastIndex))) goto exception; if (e > size) e = size; if (e == p) { q = string_advance_index(strp, q, unicodeMatching); } else { sub = js_sub_string(ctx, strp, p, q); if (JS_IsException(sub)) goto exception; if (JS_DefinePropertyValueInt64(ctx, A, lengthA++, sub, JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception; if (lengthA == lim) goto done; p = e; if (js_get_length64(ctx, &numberOfCaptures, z)) goto exception; for(i = 1; i < numberOfCaptures; i++) { sub = JS_GetPropertyInt64(ctx, z, i); if (JS_IsException(sub)) goto exception; if (JS_DefinePropertyValueInt64(ctx, A, lengthA++, sub, JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception; if (lengthA == lim) goto done; } q = p; } } } add_tail: if (p > size) p = size; sub = js_sub_string(ctx, strp, p, size); if (JS_IsException(sub)) goto exception; if (JS_DefinePropertyValueInt64(ctx, A, lengthA++, sub, JS_PROP_C_W_E | JS_PROP_THROW) < 0) goto exception; goto done; exception: JS_FreeValue(ctx, A); A = JS_EXCEPTION; done: JS_FreeValue(ctx, str); JS_FreeValue(ctx, ctor); JS_FreeValue(ctx, splitter); JS_FreeValue(ctx, flags); JS_FreeValue(ctx, z); return A; } static const JSCFunctionListEntry js_regexp_funcs[] = { JS_CFUNC_DEF("escape", 1, js_regexp_escape ), JS_CGETSET_DEF("[Symbol.species]", js_get_this, NULL ), }; static const JSCFunctionListEntry js_regexp_proto_funcs[] = { JS_CGETSET_DEF("flags", js_regexp_get_flags, NULL ), JS_CGETSET_DEF("source", js_regexp_get_source, NULL ), JS_CGETSET_MAGIC_DEF("global", js_regexp_get_flag, NULL, LRE_FLAG_GLOBAL ), JS_CGETSET_MAGIC_DEF("ignoreCase", js_regexp_get_flag, NULL, LRE_FLAG_IGNORECASE ), JS_CGETSET_MAGIC_DEF("multiline", js_regexp_get_flag, NULL, LRE_FLAG_MULTILINE ), JS_CGETSET_MAGIC_DEF("dotAll", js_regexp_get_flag, NULL, LRE_FLAG_DOTALL ), JS_CGETSET_MAGIC_DEF("unicode", js_regexp_get_flag, NULL, LRE_FLAG_UNICODE ), JS_CGETSET_MAGIC_DEF("unicodeSets", js_regexp_get_flag, NULL, LRE_FLAG_UNICODE_SETS ), JS_CGETSET_MAGIC_DEF("sticky", js_regexp_get_flag, NULL, LRE_FLAG_STICKY ), JS_CGETSET_MAGIC_DEF("hasIndices", js_regexp_get_flag, NULL, LRE_FLAG_INDICES ), JS_CFUNC_DEF("exec", 1, js_regexp_exec ), JS_CFUNC_DEF("compile", 2, js_regexp_compile ), JS_CFUNC_DEF("test", 1, js_regexp_test ), JS_CFUNC_DEF("toString", 0, js_regexp_toString ), JS_CFUNC_DEF("[Symbol.replace]", 2, js_regexp_Symbol_replace ), JS_CFUNC_DEF("[Symbol.match]", 1, js_regexp_Symbol_match ), JS_CFUNC_DEF("[Symbol.matchAll]", 1, js_regexp_Symbol_matchAll ), JS_CFUNC_DEF("[Symbol.search]", 1, js_regexp_Symbol_search ), JS_CFUNC_DEF("[Symbol.split]", 2, js_regexp_Symbol_split ), }; static const JSCFunctionListEntry js_regexp_string_iterator_proto_funcs[] = { JS_ITERATOR_NEXT_DEF("next", 0, js_regexp_string_iterator_next, 0 ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "RegExp String Iterator", JS_PROP_CONFIGURABLE ), }; void JS_AddIntrinsicRegExpCompiler(JSContext *ctx) { ctx->compile_regexp = js_compile_regexp; } int JS_AddIntrinsicRegExp(JSContext *ctx) { JSValue obj; JS_AddIntrinsicRegExpCompiler(ctx); obj = JS_NewCConstructor(ctx, JS_CLASS_REGEXP, "RegExp", js_regexp_constructor, 2, JS_CFUNC_constructor_or_func, 0, JS_UNDEFINED, js_regexp_funcs, countof(js_regexp_funcs), js_regexp_proto_funcs, countof(js_regexp_proto_funcs), 0); if (JS_IsException(obj)) return -1; ctx->regexp_ctor = obj; ctx->class_proto[JS_CLASS_REGEXP_STRING_ITERATOR] = JS_NewObjectProtoList(ctx, ctx->class_proto[JS_CLASS_ITERATOR], js_regexp_string_iterator_proto_funcs, countof(js_regexp_string_iterator_proto_funcs)); if (JS_IsException(ctx->class_proto[JS_CLASS_REGEXP_STRING_ITERATOR])) return -1; ctx->regexp_shape = js_new_shape2(ctx, get_proto_obj(ctx->class_proto[JS_CLASS_REGEXP]), JS_PROP_INITIAL_HASH_SIZE, 1); if (!ctx->regexp_shape) return -1; if (add_shape_property(ctx, &ctx->regexp_shape, NULL, JS_ATOM_lastIndex, JS_PROP_WRITABLE)) return -1; ctx->regexp_result_shape = js_new_shape2(ctx, get_proto_obj(ctx->class_proto[JS_CLASS_ARRAY]), JS_PROP_INITIAL_HASH_SIZE, 4); if (!ctx->regexp_result_shape) return -1; if (add_shape_property(ctx, &ctx->regexp_result_shape, NULL, JS_ATOM_length, JS_PROP_WRITABLE | JS_PROP_LENGTH)) return -1; if (add_shape_property(ctx, &ctx->regexp_result_shape, NULL, JS_ATOM_index, JS_PROP_C_W_E)) return -1; if (add_shape_property(ctx, &ctx->regexp_result_shape, NULL, JS_ATOM_input, JS_PROP_C_W_E)) return -1; if (add_shape_property(ctx, &ctx->regexp_result_shape, NULL, JS_ATOM_groups, JS_PROP_C_W_E)) return -1; return 0; } /* JSON */ static int json_parse_expect(JSParseState *s, int tok) { if (s->token.val != tok) { /* XXX: dump token correctly in all cases */ return js_parse_error(s, "expecting '%c'", tok); } return json_next_token(s); } typedef struct { int count; uint32_t hash_size; struct JSONParseRecordEntry *entries; uint32_t *hash_table; } JSONParseRecordObject; typedef struct JSONParseRecord { JSValue value; union { JSONParseRecordObject obj; struct { int count; struct JSONParseRecord *elements; } array; struct { uint32_t source_pos; uint32_t source_len; } primitive; } u; } JSONParseRecord; typedef struct JSONParseRecordEntry { JSAtom atom; uint32_t hash_next; JSONParseRecord parse_record; } JSONParseRecordEntry; static void json_parse_record_init_obj(JSContext *ctx, JSONParseRecord *pr, JSValueConst val) { pr->value = JS_DupValue(ctx, val); pr->u.obj.count = 0; pr->u.obj.entries = NULL; pr->u.obj.hash_table = NULL; pr->u.obj.hash_size = 0; } static void json_parse_record_init_array(JSContext *ctx, JSONParseRecord *pr, JSValueConst val) { pr->value = JS_DupValue(ctx, val); pr->u.array.count = 0; pr->u.array.elements = NULL; } static void json_parse_record_init_primitive(JSContext *ctx, JSONParseRecord *pr, JSValueConst val, uint32_t source_pos, uint32_t source_len) { pr->value = JS_DupValue(ctx, val); pr->u.primitive.source_pos = source_pos; pr->u.primitive.source_len = source_len; } static int json_parse_record_resize_hash(JSContext *ctx, JSONParseRecordObject *po, uint32_t new_hash_size) { uint32_t i, h, *new_hash_table; JSONParseRecordEntry *e; new_hash_table = js_malloc(ctx, sizeof(new_hash_table[0]) * new_hash_size); if (!new_hash_table) return -1; js_free(ctx, po->hash_table); po->hash_table = new_hash_table; po->hash_size = new_hash_size; for(i = 0; i < po->hash_size; i++) { po->hash_table[i] = -1; } for(i = 0; i < po->count; i++) { e = &po->entries[i]; h = e->atom & (po->hash_size - 1); e->hash_next = po->hash_table[h]; po->hash_table[h] = i; } return 0; } static JSONParseRecord *json_parse_record_add(JSContext *ctx, JSONParseRecord *pr, JSAtom key, int *psize) { JSONParseRecordObject *po = &pr->u.obj; JSONParseRecordEntry *e; JSONParseRecord *pr1; uint32_t h; if (js_resize_array(ctx, (void **)&po->entries, sizeof(po->entries[0]), psize, po->count + 1)) { return NULL; } /* don't use a hash table when the number of entries is small */ if (po->count >= 8 && (po->count + 1) > po->hash_size) { int hash_bits = 32 - clz32(po->count); if (json_parse_record_resize_hash(ctx, po, 1 << hash_bits)) return NULL; } e = &po->entries[po->count++]; e->atom = JS_DupAtom(ctx, key); pr1 = &e->parse_record; pr1->value = JS_UNDEFINED; if (po->hash_size != 0) { h = key & (po->hash_size - 1); e->hash_next = po->hash_table[h]; po->hash_table[h] = po->count - 1; } return pr1; } static JSONParseRecord *json_parse_record_find(JSONParseRecord *pr, JSAtom key) { JSONParseRecordObject *po = &pr->u.obj; JSONParseRecordEntry *e; uint32_t h, i; if (po->hash_size == 0) { for(i = 0; i < po->count; i++) { if (po->entries[i].atom == key) return &po->entries[i].parse_record; } } else { h = key & (po->hash_size - 1); i = po->hash_table[h]; while (i != -1) { e = &po->entries[i]; if (e->atom == key) return &e->parse_record; i = e->hash_next; } } return NULL; } static void json_free_parse_record(JSContext *ctx, JSONParseRecord *pr) { int i; if (!pr) return; if (JS_IsObject(pr->value)) { if (JS_IsArray(ctx, pr->value)) { for(i = 0; i < pr->u.array.count; i++) { json_free_parse_record(ctx, &pr->u.array.elements[i]); } js_free(ctx, pr->u.array.elements); } else { for(i = 0; i < pr->u.obj.count; i++) { JS_FreeAtom(ctx, pr->u.obj.entries[i].atom); json_free_parse_record(ctx, &pr->u.obj.entries[i].parse_record); } js_free(ctx, pr->u.obj.entries); js_free(ctx, pr->u.obj.hash_table); } } JS_FreeValue(ctx, pr->value); pr->value = JS_UNDEFINED; /* fail safe */ } /* 'pr' can be NULL */ static JSValue json_parse_value(JSParseState *s, JSONParseRecord *pr) { JSContext *ctx = s->ctx; JSValue val = JS_NULL; int ret; if (pr) { pr->value = JS_UNDEFINED; } switch(s->token.val) { case '{': { JSValue prop_val; JSAtom prop_name; JSONParseRecord *pr1; int pr_size; if (json_next_token(s)) goto fail; val = JS_NewObject(ctx); if (JS_IsException(val)) goto fail; if (pr) { json_parse_record_init_obj(ctx, pr, val); pr_size = 0; } if (s->token.val != '}') { for(;;) { if (s->token.val == TOK_STRING) { prop_name = JS_ValueToAtom(ctx, s->token.u.str.str); if (prop_name == JS_ATOM_NULL) goto fail; } else if (s->ext_json && s->token.val == TOK_IDENT) { prop_name = JS_DupAtom(ctx, s->token.u.ident.atom); } else { js_parse_error(s, "expecting property name"); goto fail; } if (json_next_token(s)) goto fail1; if (json_parse_expect(s, ':')) goto fail1; if (pr) { pr1 = json_parse_record_add(ctx, pr, prop_name, &pr_size); if (!pr1) goto fail1; } else { pr1 = NULL; } prop_val = json_parse_value(s, pr1); if (JS_IsException(prop_val)) { fail1: JS_FreeAtom(ctx, prop_name); goto fail; } ret = JS_DefinePropertyValue(ctx, val, prop_name, prop_val, JS_PROP_C_W_E); JS_FreeAtom(ctx, prop_name); if (ret < 0) goto fail; if (s->token.val != ',') break; if (json_next_token(s)) goto fail; if (s->ext_json && s->token.val == '}') break; } } if (json_parse_expect(s, '}')) goto fail; } break; case '[': { JSValue el; uint32_t idx; JSONParseRecord *pr1; int pr_size; if (json_next_token(s)) goto fail; val = JS_NewArray(ctx); if (JS_IsException(val)) goto fail; if (pr) { json_parse_record_init_array(ctx, pr, val); pr_size = 0; } if (s->token.val != ']') { idx = 0; for(;;) { if (pr) { if (js_resize_array(ctx, (void **)&pr->u.array.elements, sizeof(pr->u.array.elements[0]), &pr_size, pr->u.array.count + 1)) goto fail; pr1 = &pr->u.array.elements[pr->u.array.count++]; pr1->value = JS_UNDEFINED; } else { pr1 = NULL; } el = json_parse_value(s, pr1); if (JS_IsException(el)) goto fail; ret = JS_DefinePropertyValueUint32(ctx, val, idx, el, JS_PROP_C_W_E); if (ret < 0) goto fail; if (s->token.val != ',') break; if (json_next_token(s)) goto fail; idx++; if (s->ext_json && s->token.val == ']') break; } } if (json_parse_expect(s, ']')) goto fail; } break; case TOK_STRING: val = JS_DupValue(ctx, s->token.u.str.str); if (pr) { json_parse_record_init_primitive(ctx, pr, val, s->token.ptr - s->buf_start, s->buf_ptr - s->token.ptr); } if (json_next_token(s)) goto fail; break; case TOK_NUMBER: val = s->token.u.num.val; if (pr) { json_parse_record_init_primitive(ctx, pr, val, s->token.ptr - s->buf_start, s->buf_ptr - s->token.ptr); } if (json_next_token(s)) goto fail; break; case TOK_IDENT: if (s->token.u.ident.atom == JS_ATOM_false || s->token.u.ident.atom == JS_ATOM_true) { val = JS_NewBool(ctx, s->token.u.ident.atom == JS_ATOM_true); if (pr) { json_parse_record_init_primitive(ctx, pr, val, s->token.ptr - s->buf_start, s->buf_ptr - s->token.ptr); } } else if (s->token.u.ident.atom == JS_ATOM_null) { val = JS_NULL; if (pr) { json_parse_record_init_primitive(ctx, pr, val, s->token.ptr - s->buf_start, s->buf_ptr - s->token.ptr); } } else if (s->token.u.ident.atom == JS_ATOM_NaN && s->ext_json) { /* Note: json5 identifier handling is ambiguous e.g. is '{ NaN: 1 }' a valid JSON5 production ? */ val = JS_NewFloat64(s->ctx, NAN); } else if (s->token.u.ident.atom == JS_ATOM_Infinity && s->ext_json) { val = JS_NewFloat64(s->ctx, INFINITY); } else { goto def_token; } if (json_next_token(s)) goto fail; break; default: def_token: if (s->token.val == TOK_EOF) { js_parse_error(s, "Unexpected end of JSON input"); } else { js_parse_error(s, "unexpected token: '%.*s'", (int)(s->buf_ptr - s->token.ptr), s->token.ptr); } goto fail; } return val; fail: json_free_parse_record(ctx, pr); JS_FreeValue(ctx, val); return JS_EXCEPTION; } JSValue JS_ParseJSON3(JSContext *ctx, const char *buf, size_t buf_len, const char *filename, int flags, JSONParseRecord *pr) { JSParseState s1, *s = &s1; JSValue val = JS_UNDEFINED; js_parse_init(ctx, s, buf, buf_len, filename); s->ext_json = ((flags & JS_PARSE_JSON_EXT) != 0); if (json_next_token(s)) goto fail; val = json_parse_value(s, pr); if (JS_IsException(val)) goto fail; if (s->token.val != TOK_EOF) { if (js_parse_error(s, "unexpected data at the end")) { json_free_parse_record(ctx, pr); goto fail; } } return val; fail: JS_FreeValue(ctx, val); free_token(s, &s->token); return JS_EXCEPTION; } JSValue JS_ParseJSON2(JSContext *ctx, const char *buf, size_t buf_len, const char *filename, int flags) { return JS_ParseJSON3(ctx, buf, buf_len, filename, flags, NULL); } JSValue JS_ParseJSON(JSContext *ctx, const char *buf, size_t buf_len, const char *filename) { return JS_ParseJSON3(ctx, buf, buf_len, filename, 0, NULL); } /* if pr != NULL, then pr->value = holder by construction */ static JSValue internalize_json_property(JSContext *ctx, JSValueConst holder, JSAtom name, JSValueConst reviver, const char *text_str, JSONParseRecord *pr) { JSValue val, new_el, name_val, res, context; JSValueConst args[3]; int ret, is_array; uint32_t i, len = 0; JSAtom prop; JSPropertyEnum *atoms = NULL; if (js_check_stack_overflow(ctx->rt, 0)) { return JS_ThrowStackOverflow(ctx); } val = JS_GetProperty(ctx, holder, name); if (JS_IsException(val)) return val; if (pr) { if (JS_IsArray(ctx, pr->value)) { if (__JS_AtomIsTaggedInt(name)) { uint32_t idx = __JS_AtomToUInt32(name); if (idx < pr->u.array.count) { pr = &pr->u.array.elements[idx]; } else { pr = NULL; } } } else { pr = json_parse_record_find(pr, name); } if (pr && !js_same_value(ctx, pr->value, val)) { pr = NULL; } } context = JS_NewObject(ctx); if (JS_IsException(context)) goto fail; if (JS_IsObject(val)) { is_array = JS_IsArray(ctx, val); if (is_array < 0) goto fail; if (is_array) { if (js_get_length32(ctx, &len, val)) goto fail; } else { ret = JS_GetOwnPropertyNamesInternal(ctx, &atoms, &len, JS_VALUE_GET_OBJ(val), JS_GPN_ENUM_ONLY | JS_GPN_STRING_MASK); if (ret < 0) goto fail; } for(i = 0; i < len; i++) { if (is_array) { prop = JS_NewAtomUInt32(ctx, i); if (prop == JS_ATOM_NULL) goto fail; } else { prop = JS_DupAtom(ctx, atoms[i].atom); } new_el = internalize_json_property(ctx, val, prop, reviver, text_str, pr); if (JS_IsException(new_el)) { JS_FreeAtom(ctx, prop); goto fail; } if (JS_IsUndefined(new_el)) { ret = JS_DeleteProperty(ctx, val, prop, 0); } else { ret = JS_DefinePropertyValue(ctx, val, prop, new_el, JS_PROP_C_W_E); } JS_FreeAtom(ctx, prop); if (ret < 0) goto fail; } } else { if (pr) { new_el = JS_NewStringLen(ctx, text_str + pr->u.primitive.source_pos, pr->u.primitive.source_len); if (JS_IsException(new_el)) goto fail; if (JS_DefinePropertyValue(ctx, context, JS_ATOM_source, new_el, JS_PROP_C_W_E) < 0) goto fail; } } JS_FreePropertyEnum(ctx, atoms, len); atoms = NULL; name_val = JS_AtomToValue(ctx, name); if (JS_IsException(name_val)) goto fail; args[0] = name_val; args[1] = val; args[2] = context; res = JS_Call(ctx, reviver, holder, 3, args); JS_FreeValue(ctx, name_val); JS_FreeValue(ctx, val); JS_FreeValue(ctx, context); return res; fail: JS_FreePropertyEnum(ctx, atoms, len); JS_FreeValue(ctx, context); JS_FreeValue(ctx, val); return JS_EXCEPTION; } static JSValue js_json_parse(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj; const char *str; size_t len; str = JS_ToCStringLen(ctx, &len, argv[0]); if (!str) return JS_EXCEPTION; if (argc > 1 && JS_IsFunction(ctx, argv[1])) { JSONParseRecord pr_s, *pr = &pr_s, *pr1; JSValue root; JSValueConst reviver; int size; reviver = argv[1]; root = JS_NewObject(ctx); if (JS_IsException(root)) goto fail; json_parse_record_init_obj(ctx, pr, root); size = 0; pr1 = json_parse_record_add(ctx, pr, JS_ATOM_empty_string, &size); if (!pr1) goto fail1; obj = JS_ParseJSON3(ctx, str, len, "<input>", 0, pr1); if (JS_IsException(obj)) goto fail1; if (JS_DefinePropertyValue(ctx, root, JS_ATOM_empty_string, obj, JS_PROP_C_W_E) < 0) { JS_FreeValue(ctx, obj); fail1: json_free_parse_record(ctx, pr); JS_FreeValue(ctx, root); goto fail; } obj = internalize_json_property(ctx, root, JS_ATOM_empty_string, reviver, str, pr); json_free_parse_record(ctx, pr); JS_FreeValue(ctx, root); } else { obj = JS_ParseJSON3(ctx, str, len, "<input>", 0, NULL); } JS_FreeCString(ctx, str); return obj; fail: JS_FreeCString(ctx, str); return JS_EXCEPTION; } static JSValue js_json_isRawJSON(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValueConst obj = argv[0]; if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { JSObject *p = JS_VALUE_GET_OBJ(obj); return JS_NewBool(ctx, p->class_id == JS_CLASS_RAWJSON); } else { return JS_FALSE; } } static BOOL is_valid_raw_json_char(int c) { return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' || c == '"'); } static JSValue js_json_rawJSON(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue str, res, obj; JSString *p; str = JS_ToString(ctx, argv[0]); if (JS_IsException(str)) return str; p = JS_VALUE_GET_STRING(str); if (p->len == 0 || !is_valid_raw_json_char(string_get(p, 0)) || !is_valid_raw_json_char(string_get(p, p->len - 1))) { goto syntax_error; } res = js_json_parse(ctx, JS_UNDEFINED, 1, (JSValueConst *)&str); if (JS_IsException(res)) { syntax_error: JS_ThrowSyntaxError(ctx, "invalid rawJSON string"); goto fail; } JS_FreeValue(ctx, res); obj = JS_NewObjectProtoClass(ctx, JS_NULL, JS_CLASS_RAWJSON); if (JS_IsException(obj)) goto fail; if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_rawJSON, str, JS_PROP_ENUMERABLE) < 0) { JS_FreeValue(ctx, obj); return JS_EXCEPTION; } JS_PreventExtensions(ctx, obj); return obj; fail: JS_FreeValue(ctx, str); return JS_EXCEPTION; } typedef struct JSONStringifyContext { JSValueConst replacer_func; JSValue stack; JSValue property_list; JSValue gap; JSValue empty; StringBuffer *b; } JSONStringifyContext; static int JS_ToQuotedString(JSContext *ctx, StringBuffer *b, JSValueConst val1) { JSValue val; JSString *p; int i; uint32_t c; char buf[16]; val = JS_ToStringCheckObject(ctx, val1); if (JS_IsException(val)) return -1; p = JS_VALUE_GET_STRING(val); if (string_buffer_putc8(b, '\"')) goto fail; for(i = 0; i < p->len; ) { c = string_getc(p, &i); switch(c) { case '\t': c = 't'; goto quote; case '\r': c = 'r'; goto quote; case '\n': c = 'n'; goto quote; case '\b': c = 'b'; goto quote; case '\f': c = 'f'; goto quote; case '\"': case '\\': quote: if (string_buffer_putc8(b, '\\')) goto fail; if (string_buffer_putc8(b, c)) goto fail; break; default: if (c < 32 || is_surrogate(c)) { snprintf(buf, sizeof(buf), "\\u%04x", c); if (string_buffer_puts8(b, buf)) goto fail; } else { if (string_buffer_putc(b, c)) goto fail; } break; } } if (string_buffer_putc8(b, '\"')) goto fail; JS_FreeValue(ctx, val); return 0; fail: JS_FreeValue(ctx, val); return -1; } static int JS_ToQuotedStringFree(JSContext *ctx, StringBuffer *b, JSValue val) { int ret = JS_ToQuotedString(ctx, b, val); JS_FreeValue(ctx, val); return ret; } static JSValue js_json_check(JSContext *ctx, JSONStringifyContext *jsc, JSValueConst holder, JSValue val, JSValueConst key) { JSValue v; JSValueConst args[2]; /* check for object.toJSON method */ /* ECMA specifies this is done only for Object and BigInt */ if (JS_IsObject(val) || JS_IsBigInt(ctx, val)) { JSValue f = JS_GetProperty(ctx, val, JS_ATOM_toJSON); if (JS_IsException(f)) goto exception; if (JS_IsFunction(ctx, f)) { v = JS_CallFree(ctx, f, val, 1, &key); JS_FreeValue(ctx, val); val = v; if (JS_IsException(val)) goto exception; } else { JS_FreeValue(ctx, f); } } if (!JS_IsUndefined(jsc->replacer_func)) { args[0] = key; args[1] = val; v = JS_Call(ctx, jsc->replacer_func, holder, 2, args); JS_FreeValue(ctx, val); val = v; if (JS_IsException(val)) goto exception; } switch (JS_VALUE_GET_NORM_TAG(val)) { case JS_TAG_OBJECT: if (JS_IsFunction(ctx, val)) break; case JS_TAG_STRING: case JS_TAG_STRING_ROPE: case JS_TAG_INT: case JS_TAG_FLOAT64: case JS_TAG_BOOL: case JS_TAG_NULL: case JS_TAG_SHORT_BIG_INT: case JS_TAG_BIG_INT: case JS_TAG_EXCEPTION: return val; default: break; } JS_FreeValue(ctx, val); return JS_UNDEFINED; exception: JS_FreeValue(ctx, val); return JS_EXCEPTION; } static int js_json_to_str(JSContext *ctx, JSONStringifyContext *jsc, JSValueConst holder, JSValue val, JSValueConst indent) { JSValue indent1, sep, sep1, tab, v, prop; JSObject *p; int64_t i, len; int cl, ret; BOOL has_content; indent1 = JS_UNDEFINED; sep = JS_UNDEFINED; sep1 = JS_UNDEFINED; tab = JS_UNDEFINED; prop = JS_UNDEFINED; if (js_check_stack_overflow(ctx->rt, 0)) { JS_ThrowStackOverflow(ctx); goto exception; } if (JS_IsObject(val)) { p = JS_VALUE_GET_OBJ(val); cl = p->class_id; if (cl == JS_CLASS_STRING) { val = JS_ToStringFree(ctx, val); if (JS_IsException(val)) goto exception; goto concat_primitive; } else if (cl == JS_CLASS_NUMBER) { val = JS_ToNumberFree(ctx, val); if (JS_IsException(val)) goto exception; goto concat_primitive; } else if (cl == JS_CLASS_BOOLEAN || cl == JS_CLASS_BIG_INT) { /* This will thow the same error as for the primitive object */ set_value(ctx, &val, JS_DupValue(ctx, p->u.object_data)); goto concat_primitive; } else if (cl == JS_CLASS_RAWJSON) { JSValue val1; val1 = JS_GetProperty(ctx, val, JS_ATOM_rawJSON); if (JS_IsException(val1)) goto exception; JS_FreeValue(ctx, val); val = val1; goto concat_value; } v = js_array_includes(ctx, jsc->stack, 1, (JSValueConst *)&val); if (JS_IsException(v)) goto exception; if (JS_ToBoolFree(ctx, v)) { JS_ThrowTypeError(ctx, "circular reference"); goto exception; } indent1 = JS_ConcatString(ctx, JS_DupValue(ctx, indent), JS_DupValue(ctx, jsc->gap)); if (JS_IsException(indent1)) goto exception; if (!JS_IsEmptyString(jsc->gap)) { sep = JS_ConcatString3(ctx, "\n", JS_DupValue(ctx, indent1), ""); if (JS_IsException(sep)) goto exception; sep1 = js_new_string8(ctx, " "); if (JS_IsException(sep1)) goto exception; } else { sep = JS_DupValue(ctx, jsc->empty); sep1 = JS_DupValue(ctx, jsc->empty); } v = js_array_push(ctx, jsc->stack, 1, (JSValueConst *)&val, 0); if (check_exception_free(ctx, v)) goto exception; ret = JS_IsArray(ctx, val); if (ret < 0) goto exception; if (ret) { if (js_get_length64(ctx, &len, val)) goto exception; string_buffer_putc8(jsc->b, '['); for(i = 0; i < len; i++) { if (i > 0) string_buffer_putc8(jsc->b, ','); string_buffer_concat_value(jsc->b, sep); v = JS_GetPropertyInt64(ctx, val, i); if (JS_IsException(v)) goto exception; /* XXX: could do this string conversion only when needed */ prop = JS_ToStringFree(ctx, JS_NewInt64(ctx, i)); if (JS_IsException(prop)) goto exception; v = js_json_check(ctx, jsc, val, v, prop); JS_FreeValue(ctx, prop); prop = JS_UNDEFINED; if (JS_IsException(v)) goto exception; if (JS_IsUndefined(v)) v = JS_NULL; if (js_json_to_str(ctx, jsc, val, v, indent1)) goto exception; } if (len > 0 && !JS_IsEmptyString(jsc->gap)) { string_buffer_putc8(jsc->b, '\n'); string_buffer_concat_value(jsc->b, indent); } string_buffer_putc8(jsc->b, ']'); } else { if (!JS_IsUndefined(jsc->property_list)) tab = JS_DupValue(ctx, jsc->property_list); else tab = js_object_keys(ctx, JS_UNDEFINED, 1, (JSValueConst *)&val, JS_ITERATOR_KIND_KEY); if (JS_IsException(tab)) goto exception; if (js_get_length64(ctx, &len, tab)) goto exception; string_buffer_putc8(jsc->b, '{'); has_content = FALSE; for(i = 0; i < len; i++) { JS_FreeValue(ctx, prop); prop = JS_GetPropertyInt64(ctx, tab, i); if (JS_IsException(prop)) goto exception; v = JS_GetPropertyValue(ctx, val, JS_DupValue(ctx, prop)); if (JS_IsException(v)) goto exception; v = js_json_check(ctx, jsc, val, v, prop); if (JS_IsException(v)) goto exception; if (!JS_IsUndefined(v)) { if (has_content) string_buffer_putc8(jsc->b, ','); string_buffer_concat_value(jsc->b, sep); if (JS_ToQuotedString(ctx, jsc->b, prop)) { JS_FreeValue(ctx, v); goto exception; } string_buffer_putc8(jsc->b, ':'); string_buffer_concat_value(jsc->b, sep1); if (js_json_to_str(ctx, jsc, val, v, indent1)) goto exception; has_content = TRUE; } } if (has_content && !JS_IsEmptyString(jsc->gap)) { string_buffer_putc8(jsc->b, '\n'); string_buffer_concat_value(jsc->b, indent); } string_buffer_putc8(jsc->b, '}'); } if (check_exception_free(ctx, js_array_pop(ctx, jsc->stack, 0, NULL, 0))) goto exception; JS_FreeValue(ctx, val); JS_FreeValue(ctx, tab); JS_FreeValue(ctx, sep); JS_FreeValue(ctx, sep1); JS_FreeValue(ctx, indent1); JS_FreeValue(ctx, prop); return 0; } concat_primitive: switch (JS_VALUE_GET_NORM_TAG(val)) { case JS_TAG_STRING: case JS_TAG_STRING_ROPE: return JS_ToQuotedStringFree(ctx, jsc->b, val); case JS_TAG_FLOAT64: if (!isfinite(JS_VALUE_GET_FLOAT64(val))) { val = JS_NULL; } goto concat_value; case JS_TAG_INT: case JS_TAG_BOOL: case JS_TAG_NULL: concat_value: return string_buffer_concat_value_free(jsc->b, val); case JS_TAG_SHORT_BIG_INT: case JS_TAG_BIG_INT: /* reject big numbers: use toJSON method to override */ JS_ThrowTypeError(ctx, "Do not know how to serialize a BigInt"); goto exception; default: JS_FreeValue(ctx, val); return 0; } exception: JS_FreeValue(ctx, val); JS_FreeValue(ctx, tab); JS_FreeValue(ctx, sep); JS_FreeValue(ctx, sep1); JS_FreeValue(ctx, indent1); JS_FreeValue(ctx, prop); return -1; } JSValue JS_JSONStringify(JSContext *ctx, JSValueConst obj, JSValueConst replacer, JSValueConst space0) { StringBuffer b_s; JSONStringifyContext jsc_s, *jsc = &jsc_s; JSValue val, v, space, ret, wrapper; int res; int64_t i, j, n; jsc->replacer_func = JS_UNDEFINED; jsc->stack = JS_UNDEFINED; jsc->property_list = JS_UNDEFINED; jsc->gap = JS_UNDEFINED; jsc->b = &b_s; jsc->empty = JS_AtomToString(ctx, JS_ATOM_empty_string); ret = JS_UNDEFINED; wrapper = JS_UNDEFINED; string_buffer_init(ctx, jsc->b, 0); jsc->stack = JS_NewArray(ctx); if (JS_IsException(jsc->stack)) goto exception; if (JS_IsFunction(ctx, replacer)) { jsc->replacer_func = replacer; } else { res = JS_IsArray(ctx, replacer); if (res < 0) goto exception; if (res) { /* XXX: enumeration is not fully correct */ jsc->property_list = JS_NewArray(ctx); if (JS_IsException(jsc->property_list)) goto exception; if (js_get_length64(ctx, &n, replacer)) goto exception; for (i = j = 0; i < n; i++) { JSValue present; v = JS_GetPropertyInt64(ctx, replacer, i); if (JS_IsException(v)) goto exception; if (JS_IsObject(v)) { JSObject *p = JS_VALUE_GET_OBJ(v); if (p->class_id == JS_CLASS_STRING || p->class_id == JS_CLASS_NUMBER) { v = JS_ToStringFree(ctx, v); if (JS_IsException(v)) goto exception; } else { JS_FreeValue(ctx, v); continue; } } else if (JS_IsNumber(v)) { v = JS_ToStringFree(ctx, v); if (JS_IsException(v)) goto exception; } else if (!JS_IsString(v)) { JS_FreeValue(ctx, v); continue; } present = js_array_includes(ctx, jsc->property_list, 1, (JSValueConst *)&v); if (JS_IsException(present)) { JS_FreeValue(ctx, v); goto exception; } if (!JS_ToBoolFree(ctx, present)) { JS_SetPropertyInt64(ctx, jsc->property_list, j++, v); } else { JS_FreeValue(ctx, v); } } } } space = JS_DupValue(ctx, space0); if (JS_IsObject(space)) { JSObject *p = JS_VALUE_GET_OBJ(space); if (p->class_id == JS_CLASS_NUMBER) { space = JS_ToNumberFree(ctx, space); } else if (p->class_id == JS_CLASS_STRING) { space = JS_ToStringFree(ctx, space); } if (JS_IsException(space)) { JS_FreeValue(ctx, space); goto exception; } } if (JS_IsNumber(space)) { int n; if (JS_ToInt32Clamp(ctx, &n, space, 0, 10, 0)) goto exception; jsc->gap = js_new_string8_len(ctx, " ", n); } else if (JS_IsString(space)) { JSString *p = JS_VALUE_GET_STRING(space); jsc->gap = js_sub_string(ctx, p, 0, min_int(p->len, 10)); } else { jsc->gap = JS_DupValue(ctx, jsc->empty); } JS_FreeValue(ctx, space); if (JS_IsException(jsc->gap)) goto exception; wrapper = JS_NewObject(ctx); if (JS_IsException(wrapper)) goto exception; if (JS_DefinePropertyValue(ctx, wrapper, JS_ATOM_empty_string, JS_DupValue(ctx, obj), JS_PROP_C_W_E) < 0) goto exception; val = JS_DupValue(ctx, obj); val = js_json_check(ctx, jsc, wrapper, val, jsc->empty); if (JS_IsException(val)) goto exception; if (JS_IsUndefined(val)) { ret = JS_UNDEFINED; goto done1; } if (js_json_to_str(ctx, jsc, wrapper, val, jsc->empty)) goto exception; ret = string_buffer_end(jsc->b); goto done; exception: ret = JS_EXCEPTION; done1: string_buffer_free(jsc->b); done: JS_FreeValue(ctx, wrapper); JS_FreeValue(ctx, jsc->empty); JS_FreeValue(ctx, jsc->gap); JS_FreeValue(ctx, jsc->property_list); JS_FreeValue(ctx, jsc->stack); return ret; } static JSValue js_json_stringify(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // stringify(val, replacer, space) return JS_JSONStringify(ctx, argv[0], argv[1], argv[2]); } static const JSCFunctionListEntry js_json_funcs[] = { JS_CFUNC_DEF("isRawJSON", 1, js_json_isRawJSON ), JS_CFUNC_DEF("parse", 2, js_json_parse ), JS_CFUNC_DEF("rawJSON", 1, js_json_rawJSON ), JS_CFUNC_DEF("stringify", 3, js_json_stringify ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "JSON", JS_PROP_CONFIGURABLE ), }; static const JSCFunctionListEntry js_json_obj[] = { JS_OBJECT_DEF("JSON", js_json_funcs, countof(js_json_funcs), JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE ), }; int JS_AddIntrinsicJSON(JSContext *ctx) { /* add JSON as autoinit object */ return JS_SetPropertyFunctionList(ctx, ctx->global_obj, js_json_obj, countof(js_json_obj)); } /* Reflect */ static JSValue js_reflect_apply(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return js_function_apply(ctx, argv[0], max_int(0, argc - 1), argv + 1, 2); } static JSValue js_reflect_construct(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValueConst func, array_arg, new_target; JSValue *tab, ret; uint32_t len; func = argv[0]; array_arg = argv[1]; if (argc > 2) { new_target = argv[2]; if (!JS_IsConstructor(ctx, new_target)) return JS_ThrowTypeErrorNotAConstructor(ctx, new_target); } else { new_target = func; } tab = build_arg_list(ctx, &len, array_arg); if (!tab) return JS_EXCEPTION; ret = JS_CallConstructor2(ctx, func, new_target, len, (JSValueConst *)tab); free_arg_list(ctx, tab, len); return ret; } static JSValue js_reflect_deleteProperty(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValueConst obj; JSAtom atom; int ret; obj = argv[0]; if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) return JS_ThrowTypeErrorNotAnObject(ctx); atom = JS_ValueToAtom(ctx, argv[1]); if (unlikely(atom == JS_ATOM_NULL)) return JS_EXCEPTION; ret = JS_DeleteProperty(ctx, obj, atom, 0); JS_FreeAtom(ctx, atom); if (ret < 0) return JS_EXCEPTION; else return JS_NewBool(ctx, ret); } static JSValue js_reflect_get(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValueConst obj, prop, receiver; JSAtom atom; JSValue ret; obj = argv[0]; prop = argv[1]; if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) return JS_ThrowTypeErrorNotAnObject(ctx); if (argc > 2) receiver = argv[2]; else receiver = obj; atom = JS_ValueToAtom(ctx, prop); if (unlikely(atom == JS_ATOM_NULL)) return JS_EXCEPTION; ret = JS_GetPropertyInternal(ctx, obj, atom, receiver, FALSE); JS_FreeAtom(ctx, atom); return ret; } static JSValue js_reflect_has(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValueConst obj, prop; JSAtom atom; int ret; obj = argv[0]; prop = argv[1]; if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) return JS_ThrowTypeErrorNotAnObject(ctx); atom = JS_ValueToAtom(ctx, prop); if (unlikely(atom == JS_ATOM_NULL)) return JS_EXCEPTION; ret = JS_HasProperty(ctx, obj, atom); JS_FreeAtom(ctx, atom); if (ret < 0) return JS_EXCEPTION; else return JS_NewBool(ctx, ret); } static JSValue js_reflect_set(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValueConst obj, prop, val, receiver; int ret; JSAtom atom; obj = argv[0]; prop = argv[1]; val = argv[2]; if (argc > 3) receiver = argv[3]; else receiver = obj; if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) return JS_ThrowTypeErrorNotAnObject(ctx); atom = JS_ValueToAtom(ctx, prop); if (unlikely(atom == JS_ATOM_NULL)) return JS_EXCEPTION; ret = JS_SetPropertyInternal(ctx, obj, atom, JS_DupValue(ctx, val), receiver, 0); JS_FreeAtom(ctx, atom); if (ret < 0) return JS_EXCEPTION; else return JS_NewBool(ctx, ret); } static JSValue js_reflect_setPrototypeOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { int ret; ret = JS_SetPrototypeInternal(ctx, argv[0], argv[1], FALSE); if (ret < 0) return JS_EXCEPTION; else return JS_NewBool(ctx, ret); } static JSValue js_reflect_ownKeys(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { if (JS_VALUE_GET_TAG(argv[0]) != JS_TAG_OBJECT) return JS_ThrowTypeErrorNotAnObject(ctx); return JS_GetOwnPropertyNames2(ctx, argv[0], JS_GPN_STRING_MASK | JS_GPN_SYMBOL_MASK, JS_ITERATOR_KIND_KEY); } static const JSCFunctionListEntry js_reflect_funcs[] = { JS_CFUNC_DEF("apply", 3, js_reflect_apply ), JS_CFUNC_DEF("construct", 2, js_reflect_construct ), JS_CFUNC_MAGIC_DEF("defineProperty", 3, js_object_defineProperty, 1 ), JS_CFUNC_DEF("deleteProperty", 2, js_reflect_deleteProperty ), JS_CFUNC_DEF("get", 2, js_reflect_get ), JS_CFUNC_MAGIC_DEF("getOwnPropertyDescriptor", 2, js_object_getOwnPropertyDescriptor, 1 ), JS_CFUNC_MAGIC_DEF("getPrototypeOf", 1, js_object_getPrototypeOf, 1 ), JS_CFUNC_DEF("has", 2, js_reflect_has ), JS_CFUNC_MAGIC_DEF("isExtensible", 1, js_object_isExtensible, 1 ), JS_CFUNC_DEF("ownKeys", 1, js_reflect_ownKeys ), JS_CFUNC_MAGIC_DEF("preventExtensions", 1, js_object_preventExtensions, 1 ), JS_CFUNC_DEF("set", 3, js_reflect_set ), JS_CFUNC_DEF("setPrototypeOf", 2, js_reflect_setPrototypeOf ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Reflect", JS_PROP_CONFIGURABLE ), }; static const JSCFunctionListEntry js_reflect_obj[] = { JS_OBJECT_DEF("Reflect", js_reflect_funcs, countof(js_reflect_funcs), JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE ), }; /* Proxy */ static void js_proxy_finalizer(JSRuntime *rt, JSValue val) { JSProxyData *s = JS_GetOpaque(val, JS_CLASS_PROXY); if (s) { JS_FreeValueRT(rt, s->target); JS_FreeValueRT(rt, s->handler); js_free_rt(rt, s); } } static void js_proxy_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSProxyData *s = JS_GetOpaque(val, JS_CLASS_PROXY); if (s) { JS_MarkValue(rt, s->target, mark_func); JS_MarkValue(rt, s->handler, mark_func); } } static JSValue JS_ThrowTypeErrorRevokedProxy(JSContext *ctx) { return JS_ThrowTypeError(ctx, "revoked proxy"); } static JSProxyData *get_proxy_method(JSContext *ctx, JSValue *pmethod, JSValueConst obj, JSAtom name) { JSProxyData *s = JS_GetOpaque(obj, JS_CLASS_PROXY); JSValue method; /* safer to test recursion in all proxy methods */ if (js_check_stack_overflow(ctx->rt, 0)) { JS_ThrowStackOverflow(ctx); return NULL; } /* 's' should never be NULL */ if (s->is_revoked) { JS_ThrowTypeErrorRevokedProxy(ctx); return NULL; } method = JS_GetProperty(ctx, s->handler, name); if (JS_IsException(method)) return NULL; if (JS_IsNull(method)) method = JS_UNDEFINED; *pmethod = method; return s; } static JSValue js_proxy_get_prototype(JSContext *ctx, JSValueConst obj) { JSProxyData *s; JSValue method, ret, proto1; int res; s = get_proxy_method(ctx, &method, obj, JS_ATOM_getPrototypeOf); if (!s) return JS_EXCEPTION; if (JS_IsUndefined(method)) return JS_GetPrototype(ctx, s->target); ret = JS_CallFree(ctx, method, s->handler, 1, (JSValueConst *)&s->target); if (JS_IsException(ret)) return ret; if (JS_VALUE_GET_TAG(ret) != JS_TAG_NULL && JS_VALUE_GET_TAG(ret) != JS_TAG_OBJECT) { goto fail; } res = JS_IsExtensible(ctx, s->target); if (res < 0) { JS_FreeValue(ctx, ret); return JS_EXCEPTION; } if (!res) { /* check invariant */ proto1 = JS_GetPrototype(ctx, s->target); if (JS_IsException(proto1)) { JS_FreeValue(ctx, ret); return JS_EXCEPTION; } if (!js_same_value(ctx, proto1, ret)) { JS_FreeValue(ctx, proto1); fail: JS_FreeValue(ctx, ret); return JS_ThrowTypeError(ctx, "proxy: inconsistent prototype"); } JS_FreeValue(ctx, proto1); } return ret; } static int js_proxy_set_prototype(JSContext *ctx, JSValueConst obj, JSValueConst proto_val) { JSProxyData *s; JSValue method, ret, proto1; JSValueConst args[2]; BOOL res; int res2; s = get_proxy_method(ctx, &method, obj, JS_ATOM_setPrototypeOf); if (!s) return -1; if (JS_IsUndefined(method)) return JS_SetPrototypeInternal(ctx, s->target, proto_val, FALSE); args[0] = s->target; args[1] = proto_val; ret = JS_CallFree(ctx, method, s->handler, 2, args); if (JS_IsException(ret)) return -1; res = JS_ToBoolFree(ctx, ret); if (!res) return FALSE; res2 = JS_IsExtensible(ctx, s->target); if (res2 < 0) return -1; if (!res2) { proto1 = JS_GetPrototype(ctx, s->target); if (JS_IsException(proto1)) return -1; if (!js_same_value(ctx, proto_val, proto1)) { JS_FreeValue(ctx, proto1); JS_ThrowTypeError(ctx, "proxy: inconsistent prototype"); return -1; } JS_FreeValue(ctx, proto1); } return TRUE; } static int js_proxy_is_extensible(JSContext *ctx, JSValueConst obj) { JSProxyData *s; JSValue method, ret; BOOL res; int res2; s = get_proxy_method(ctx, &method, obj, JS_ATOM_isExtensible); if (!s) return -1; if (JS_IsUndefined(method)) return JS_IsExtensible(ctx, s->target); ret = JS_CallFree(ctx, method, s->handler, 1, (JSValueConst *)&s->target); if (JS_IsException(ret)) return -1; res = JS_ToBoolFree(ctx, ret); res2 = JS_IsExtensible(ctx, s->target); if (res2 < 0) return res2; if (res != res2) { JS_ThrowTypeError(ctx, "proxy: inconsistent isExtensible"); return -1; } return res; } static int js_proxy_prevent_extensions(JSContext *ctx, JSValueConst obj) { JSProxyData *s; JSValue method, ret; BOOL res; int res2; s = get_proxy_method(ctx, &method, obj, JS_ATOM_preventExtensions); if (!s) return -1; if (JS_IsUndefined(method)) return JS_PreventExtensions(ctx, s->target); ret = JS_CallFree(ctx, method, s->handler, 1, (JSValueConst *)&s->target); if (JS_IsException(ret)) return -1; res = JS_ToBoolFree(ctx, ret); if (res) { res2 = JS_IsExtensible(ctx, s->target); if (res2 < 0) return res2; if (res2) { JS_ThrowTypeError(ctx, "proxy: inconsistent preventExtensions"); return -1; } } return res; } static int js_proxy_has(JSContext *ctx, JSValueConst obj, JSAtom atom) { JSProxyData *s; JSValue method, ret1, atom_val; int ret, res; JSObject *p; JSValueConst args[2]; BOOL res2; s = get_proxy_method(ctx, &method, obj, JS_ATOM_has); if (!s) return -1; if (JS_IsUndefined(method)) return JS_HasProperty(ctx, s->target, atom); atom_val = JS_AtomToValue(ctx, atom); if (JS_IsException(atom_val)) { JS_FreeValue(ctx, method); return -1; } args[0] = s->target; args[1] = atom_val; ret1 = JS_CallFree(ctx, method, s->handler, 2, args); JS_FreeValue(ctx, atom_val); if (JS_IsException(ret1)) return -1; ret = JS_ToBoolFree(ctx, ret1); if (!ret) { JSPropertyDescriptor desc; p = JS_VALUE_GET_OBJ(s->target); res = JS_GetOwnPropertyInternal(ctx, &desc, p, atom); if (res < 0) return -1; if (res) { res2 = !(desc.flags & JS_PROP_CONFIGURABLE); js_free_desc(ctx, &desc); if (res2 || !p->extensible) { JS_ThrowTypeError(ctx, "proxy: inconsistent has"); return -1; } } } return ret; } static JSValue js_proxy_get(JSContext *ctx, JSValueConst obj, JSAtom atom, JSValueConst receiver) { JSProxyData *s; JSValue method, ret, atom_val; int res; JSValueConst args[3]; JSPropertyDescriptor desc; s = get_proxy_method(ctx, &method, obj, JS_ATOM_get); if (!s) return JS_EXCEPTION; /* Note: recursion is possible thru the prototype of s->target */ if (JS_IsUndefined(method)) return JS_GetPropertyInternal(ctx, s->target, atom, receiver, FALSE); atom_val = JS_AtomToValue(ctx, atom); if (JS_IsException(atom_val)) { JS_FreeValue(ctx, method); return JS_EXCEPTION; } args[0] = s->target; args[1] = atom_val; args[2] = receiver; ret = JS_CallFree(ctx, method, s->handler, 3, args); JS_FreeValue(ctx, atom_val); if (JS_IsException(ret)) return JS_EXCEPTION; res = JS_GetOwnPropertyInternal(ctx, &desc, JS_VALUE_GET_OBJ(s->target), atom); if (res < 0) { JS_FreeValue(ctx, ret); return JS_EXCEPTION; } if (res) { if ((desc.flags & (JS_PROP_GETSET | JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE)) == 0) { if (!js_same_value(ctx, desc.value, ret)) { goto fail; } } else if ((desc.flags & (JS_PROP_GETSET | JS_PROP_CONFIGURABLE)) == JS_PROP_GETSET) { if (JS_IsUndefined(desc.getter) && !JS_IsUndefined(ret)) { fail: js_free_desc(ctx, &desc); JS_FreeValue(ctx, ret); return JS_ThrowTypeError(ctx, "proxy: inconsistent get"); } } js_free_desc(ctx, &desc); } return ret; } static int js_proxy_set(JSContext *ctx, JSValueConst obj, JSAtom atom, JSValueConst value, JSValueConst receiver, int flags) { JSProxyData *s; JSValue method, ret1, atom_val; int ret, res; JSValueConst args[4]; s = get_proxy_method(ctx, &method, obj, JS_ATOM_set); if (!s) return -1; if (JS_IsUndefined(method)) { return JS_SetPropertyInternal(ctx, s->target, atom, JS_DupValue(ctx, value), receiver, flags); } atom_val = JS_AtomToValue(ctx, atom); if (JS_IsException(atom_val)) { JS_FreeValue(ctx, method); return -1; } args[0] = s->target; args[1] = atom_val; args[2] = value; args[3] = receiver; ret1 = JS_CallFree(ctx, method, s->handler, 4, args); JS_FreeValue(ctx, atom_val); if (JS_IsException(ret1)) return -1; ret = JS_ToBoolFree(ctx, ret1); if (ret) { JSPropertyDescriptor desc; res = JS_GetOwnPropertyInternal(ctx, &desc, JS_VALUE_GET_OBJ(s->target), atom); if (res < 0) return -1; if (res) { if ((desc.flags & (JS_PROP_GETSET | JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE)) == 0) { if (!js_same_value(ctx, desc.value, value)) { goto fail; } } else if ((desc.flags & (JS_PROP_GETSET | JS_PROP_CONFIGURABLE)) == JS_PROP_GETSET && JS_IsUndefined(desc.setter)) { fail: js_free_desc(ctx, &desc); JS_ThrowTypeError(ctx, "proxy: inconsistent set"); return -1; } js_free_desc(ctx, &desc); } } else { if ((flags & JS_PROP_THROW) || ((flags & JS_PROP_THROW_STRICT) && is_strict_mode(ctx))) { JS_ThrowTypeError(ctx, "proxy: cannot set property"); return -1; } } return ret; } static JSValue js_create_desc(JSContext *ctx, JSValueConst val, JSValueConst getter, JSValueConst setter, int flags) { JSValue ret; ret = JS_NewObject(ctx); if (JS_IsException(ret)) return ret; if (flags & JS_PROP_HAS_GET) { JS_DefinePropertyValue(ctx, ret, JS_ATOM_get, JS_DupValue(ctx, getter), JS_PROP_C_W_E); } if (flags & JS_PROP_HAS_SET) { JS_DefinePropertyValue(ctx, ret, JS_ATOM_set, JS_DupValue(ctx, setter), JS_PROP_C_W_E); } if (flags & JS_PROP_HAS_VALUE) { JS_DefinePropertyValue(ctx, ret, JS_ATOM_value, JS_DupValue(ctx, val), JS_PROP_C_W_E); } if (flags & JS_PROP_HAS_WRITABLE) { JS_DefinePropertyValue(ctx, ret, JS_ATOM_writable, JS_NewBool(ctx, flags & JS_PROP_WRITABLE), JS_PROP_C_W_E); } if (flags & JS_PROP_HAS_ENUMERABLE) { JS_DefinePropertyValue(ctx, ret, JS_ATOM_enumerable, JS_NewBool(ctx, flags & JS_PROP_ENUMERABLE), JS_PROP_C_W_E); } if (flags & JS_PROP_HAS_CONFIGURABLE) { JS_DefinePropertyValue(ctx, ret, JS_ATOM_configurable, JS_NewBool(ctx, flags & JS_PROP_CONFIGURABLE), JS_PROP_C_W_E); } return ret; } static int js_proxy_get_own_property(JSContext *ctx, JSPropertyDescriptor *pdesc, JSValueConst obj, JSAtom prop) { JSProxyData *s; JSValue method, trap_result_obj, prop_val; int res, target_desc_ret, ret; JSObject *p; JSValueConst args[2]; JSPropertyDescriptor result_desc, target_desc; s = get_proxy_method(ctx, &method, obj, JS_ATOM_getOwnPropertyDescriptor); if (!s) return -1; p = JS_VALUE_GET_OBJ(s->target); if (JS_IsUndefined(method)) { return JS_GetOwnPropertyInternal(ctx, pdesc, p, prop); } prop_val = JS_AtomToValue(ctx, prop); if (JS_IsException(prop_val)) { JS_FreeValue(ctx, method); return -1; } args[0] = s->target; args[1] = prop_val; trap_result_obj = JS_CallFree(ctx, method, s->handler, 2, args); JS_FreeValue(ctx, prop_val); if (JS_IsException(trap_result_obj)) return -1; if (!JS_IsObject(trap_result_obj) && !JS_IsUndefined(trap_result_obj)) { JS_FreeValue(ctx, trap_result_obj); goto fail; } target_desc_ret = JS_GetOwnPropertyInternal(ctx, &target_desc, p, prop); if (target_desc_ret < 0) { JS_FreeValue(ctx, trap_result_obj); return -1; } if (target_desc_ret) js_free_desc(ctx, &target_desc); if (JS_IsUndefined(trap_result_obj)) { if (target_desc_ret) { if (!(target_desc.flags & JS_PROP_CONFIGURABLE) || !p->extensible) goto fail; } ret = FALSE; } else { int flags1, extensible_target; extensible_target = JS_IsExtensible(ctx, s->target); if (extensible_target < 0) { JS_FreeValue(ctx, trap_result_obj); return -1; } res = js_obj_to_desc(ctx, &result_desc, trap_result_obj); JS_FreeValue(ctx, trap_result_obj); if (res < 0) return -1; /* convert the result_desc.flags to property flags */ if (result_desc.flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) { result_desc.flags |= JS_PROP_GETSET; } else { result_desc.flags |= JS_PROP_NORMAL; } result_desc.flags &= (JS_PROP_C_W_E | JS_PROP_TMASK); if (target_desc_ret) { /* convert result_desc.flags to defineProperty flags */ flags1 = result_desc.flags | JS_PROP_HAS_CONFIGURABLE | JS_PROP_HAS_ENUMERABLE; if (result_desc.flags & JS_PROP_GETSET) flags1 |= JS_PROP_HAS_GET | JS_PROP_HAS_SET; else flags1 |= JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE; /* XXX: not complete check: need to compare value & getter/setter as in defineproperty */ if (!check_define_prop_flags(target_desc.flags, flags1)) goto fail1; } else { if (!extensible_target) goto fail1; } if (!(result_desc.flags & JS_PROP_CONFIGURABLE)) { if (!target_desc_ret || (target_desc.flags & JS_PROP_CONFIGURABLE)) goto fail1; if ((result_desc.flags & (JS_PROP_GETSET | JS_PROP_WRITABLE)) == 0 && target_desc_ret && (target_desc.flags & JS_PROP_WRITABLE) != 0) { /* proxy-missing-checks */ fail1: js_free_desc(ctx, &result_desc); fail: JS_ThrowTypeError(ctx, "proxy: inconsistent getOwnPropertyDescriptor"); return -1; } } ret = TRUE; if (pdesc) { *pdesc = result_desc; } else { js_free_desc(ctx, &result_desc); } } return ret; } static int js_proxy_define_own_property(JSContext *ctx, JSValueConst obj, JSAtom prop, JSValueConst val, JSValueConst getter, JSValueConst setter, int flags) { JSProxyData *s; JSValue method, ret1, prop_val, desc_val; int res, ret; JSObject *p; JSValueConst args[3]; JSPropertyDescriptor desc; BOOL setting_not_configurable; s = get_proxy_method(ctx, &method, obj, JS_ATOM_defineProperty); if (!s) return -1; if (JS_IsUndefined(method)) { return JS_DefineProperty(ctx, s->target, prop, val, getter, setter, flags); } prop_val = JS_AtomToValue(ctx, prop); if (JS_IsException(prop_val)) { JS_FreeValue(ctx, method); return -1; } desc_val = js_create_desc(ctx, val, getter, setter, flags); if (JS_IsException(desc_val)) { JS_FreeValue(ctx, prop_val); JS_FreeValue(ctx, method); return -1; } args[0] = s->target; args[1] = prop_val; args[2] = desc_val; ret1 = JS_CallFree(ctx, method, s->handler, 3, args); JS_FreeValue(ctx, prop_val); JS_FreeValue(ctx, desc_val); if (JS_IsException(ret1)) return -1; ret = JS_ToBoolFree(ctx, ret1); if (!ret) { if (flags & JS_PROP_THROW) { JS_ThrowTypeError(ctx, "proxy: defineProperty exception"); return -1; } else { return 0; } } p = JS_VALUE_GET_OBJ(s->target); res = JS_GetOwnPropertyInternal(ctx, &desc, p, prop); if (res < 0) return -1; setting_not_configurable = ((flags & (JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE)) == JS_PROP_HAS_CONFIGURABLE); if (!res) { if (!p->extensible || setting_not_configurable) goto fail; } else { if (!check_define_prop_flags(desc.flags, flags)) goto fail1; /* do the missing check from check_define_prop_flags() */ if (!(desc.flags & JS_PROP_CONFIGURABLE)) { if ((desc.flags & JS_PROP_TMASK) == JS_PROP_GETSET) { if ((flags & JS_PROP_HAS_GET) && !js_same_value(ctx, getter, desc.getter)) { goto fail1; } if ((flags & JS_PROP_HAS_SET) && !js_same_value(ctx, setter, desc.setter)) { goto fail1; } } else if (!(desc.flags & JS_PROP_WRITABLE)) { if ((flags & JS_PROP_HAS_VALUE) && !js_same_value(ctx, val, desc.value)) { goto fail1; } } } /* additional checks */ if ((desc.flags & JS_PROP_CONFIGURABLE) && setting_not_configurable) goto fail1; if ((desc.flags & JS_PROP_TMASK) != JS_PROP_GETSET && (desc.flags & (JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE)) == JS_PROP_WRITABLE && (flags & (JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE)) == JS_PROP_HAS_WRITABLE) { fail1: js_free_desc(ctx, &desc); fail: JS_ThrowTypeError(ctx, "proxy: inconsistent defineProperty"); return -1; } js_free_desc(ctx, &desc); } return 1; } static int js_proxy_delete_property(JSContext *ctx, JSValueConst obj, JSAtom atom) { JSProxyData *s; JSValue method, ret, atom_val; int res, res2, is_extensible; JSValueConst args[2]; s = get_proxy_method(ctx, &method, obj, JS_ATOM_deleteProperty); if (!s) return -1; if (JS_IsUndefined(method)) { return JS_DeleteProperty(ctx, s->target, atom, 0); } atom_val = JS_AtomToValue(ctx, atom);; if (JS_IsException(atom_val)) { JS_FreeValue(ctx, method); return -1; } args[0] = s->target; args[1] = atom_val; ret = JS_CallFree(ctx, method, s->handler, 2, args); JS_FreeValue(ctx, atom_val); if (JS_IsException(ret)) return -1; res = JS_ToBoolFree(ctx, ret); if (res) { JSPropertyDescriptor desc; res2 = JS_GetOwnPropertyInternal(ctx, &desc, JS_VALUE_GET_OBJ(s->target), atom); if (res2 < 0) return -1; if (res2) { if (!(desc.flags & JS_PROP_CONFIGURABLE)) goto fail; is_extensible = JS_IsExtensible(ctx, s->target); if (is_extensible < 0) goto fail1; if (!is_extensible) { /* proxy-missing-checks */ fail: JS_ThrowTypeError(ctx, "proxy: inconsistent deleteProperty"); fail1: js_free_desc(ctx, &desc); return -1; } js_free_desc(ctx, &desc); } } return res; } /* return the index of the property or -1 if not found */ static int find_prop_key(const JSPropertyEnum *tab, int n, JSAtom atom) { int i; for(i = 0; i < n; i++) { if (tab[i].atom == atom) return i; } return -1; } static int js_proxy_get_own_property_names(JSContext *ctx, JSPropertyEnum **ptab, uint32_t *plen, JSValueConst obj) { JSProxyData *s; JSValue method, prop_array, val; uint32_t len, i, len2; JSPropertyEnum *tab, *tab2; JSAtom atom; JSPropertyDescriptor desc; int res, is_extensible, idx; s = get_proxy_method(ctx, &method, obj, JS_ATOM_ownKeys); if (!s) return -1; if (JS_IsUndefined(method)) { return JS_GetOwnPropertyNamesInternal(ctx, ptab, plen, JS_VALUE_GET_OBJ(s->target), JS_GPN_STRING_MASK | JS_GPN_SYMBOL_MASK); } prop_array = JS_CallFree(ctx, method, s->handler, 1, (JSValueConst *)&s->target); if (JS_IsException(prop_array)) return -1; tab = NULL; len = 0; tab2 = NULL; len2 = 0; if (js_get_length32(ctx, &len, prop_array)) goto fail; if (len > 0) { tab = js_mallocz(ctx, sizeof(tab[0]) * len); if (!tab) goto fail; } for(i = 0; i < len; i++) { val = JS_GetPropertyUint32(ctx, prop_array, i); if (JS_IsException(val)) goto fail; if (!JS_IsString(val) && !JS_IsSymbol(val)) { JS_FreeValue(ctx, val); JS_ThrowTypeError(ctx, "proxy: properties must be strings or symbols"); goto fail; } atom = JS_ValueToAtom(ctx, val); JS_FreeValue(ctx, val); if (atom == JS_ATOM_NULL) goto fail; tab[i].atom = atom; tab[i].is_enumerable = FALSE; /* XXX: redundant? */ } /* check duplicate properties (XXX: inefficient, could store the * properties an a temporary object to use the hash) */ for(i = 1; i < len; i++) { if (find_prop_key(tab, i, tab[i].atom) >= 0) { JS_ThrowTypeError(ctx, "proxy: duplicate property"); goto fail; } } is_extensible = JS_IsExtensible(ctx, s->target); if (is_extensible < 0) goto fail; /* check if there are non configurable properties */ if (s->is_revoked) { JS_ThrowTypeErrorRevokedProxy(ctx); goto fail; } if (JS_GetOwnPropertyNamesInternal(ctx, &tab2, &len2, JS_VALUE_GET_OBJ(s->target), JS_GPN_STRING_MASK | JS_GPN_SYMBOL_MASK)) goto fail; for(i = 0; i < len2; i++) { if (s->is_revoked) { JS_ThrowTypeErrorRevokedProxy(ctx); goto fail; } res = JS_GetOwnPropertyInternal(ctx, &desc, JS_VALUE_GET_OBJ(s->target), tab2[i].atom); if (res < 0) goto fail; if (res) { /* safety, property should be found */ js_free_desc(ctx, &desc); if (!(desc.flags & JS_PROP_CONFIGURABLE) || !is_extensible) { idx = find_prop_key(tab, len, tab2[i].atom); if (idx < 0) { JS_ThrowTypeError(ctx, "proxy: target property must be present in proxy ownKeys"); goto fail; } /* mark the property as found */ if (!is_extensible) tab[idx].is_enumerable = TRUE; } } } if (!is_extensible) { /* check that all property in 'tab' were checked */ for(i = 0; i < len; i++) { if (!tab[i].is_enumerable) { JS_ThrowTypeError(ctx, "proxy: property not present in target were returned by non extensible proxy"); goto fail; } } } JS_FreePropertyEnum(ctx, tab2, len2); JS_FreeValue(ctx, prop_array); *ptab = tab; *plen = len; return 0; fail: JS_FreePropertyEnum(ctx, tab2, len2); JS_FreePropertyEnum(ctx, tab, len); JS_FreeValue(ctx, prop_array); return -1; } static JSValue js_proxy_call_constructor(JSContext *ctx, JSValueConst func_obj, JSValueConst new_target, int argc, JSValueConst *argv) { JSProxyData *s; JSValue method, arg_array, ret; JSValueConst args[3]; s = get_proxy_method(ctx, &method, func_obj, JS_ATOM_construct); if (!s) return JS_EXCEPTION; if (!JS_IsConstructor(ctx, s->target)) return JS_ThrowTypeErrorNotAConstructor(ctx, s->target); if (JS_IsUndefined(method)) return JS_CallConstructor2(ctx, s->target, new_target, argc, argv); arg_array = js_create_array(ctx, argc, argv); if (JS_IsException(arg_array)) { ret = JS_EXCEPTION; goto fail; } args[0] = s->target; args[1] = arg_array; args[2] = new_target; ret = JS_Call(ctx, method, s->handler, 3, args); if (!JS_IsException(ret) && JS_VALUE_GET_TAG(ret) != JS_TAG_OBJECT) { JS_FreeValue(ctx, ret); ret = JS_ThrowTypeErrorNotAnObject(ctx); } fail: JS_FreeValue(ctx, method); JS_FreeValue(ctx, arg_array); return ret; } static JSValue js_proxy_call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, int argc, JSValueConst *argv, int flags) { JSProxyData *s; JSValue method, arg_array, ret; JSValueConst args[3]; if (flags & JS_CALL_FLAG_CONSTRUCTOR) return js_proxy_call_constructor(ctx, func_obj, this_obj, argc, argv); s = get_proxy_method(ctx, &method, func_obj, JS_ATOM_apply); if (!s) return JS_EXCEPTION; if (!s->is_func) { JS_FreeValue(ctx, method); return JS_ThrowTypeError(ctx, "not a function"); } if (JS_IsUndefined(method)) return JS_Call(ctx, s->target, this_obj, argc, argv); arg_array = js_create_array(ctx, argc, argv); if (JS_IsException(arg_array)) { ret = JS_EXCEPTION; goto fail; } args[0] = s->target; args[1] = this_obj; args[2] = arg_array; ret = JS_Call(ctx, method, s->handler, 3, args); fail: JS_FreeValue(ctx, method); JS_FreeValue(ctx, arg_array); return ret; } /* `js_resolve_proxy`: resolve the proxy chain `*pval` is updated with to ultimate proxy target `throw_exception` controls whether exceptions are thown or not - return -1 in case of error - otherwise return 0 */ static int js_resolve_proxy(JSContext *ctx, JSValueConst *pval, BOOL throw_exception) { int depth = 0; JSObject *p; JSProxyData *s; while (JS_VALUE_GET_TAG(*pval) == JS_TAG_OBJECT) { p = JS_VALUE_GET_OBJ(*pval); if (p->class_id != JS_CLASS_PROXY) break; if (depth++ > 1000) { if (throw_exception) JS_ThrowStackOverflow(ctx); return -1; } s = p->u.opaque; if (s->is_revoked) { if (throw_exception) JS_ThrowTypeErrorRevokedProxy(ctx); return -1; } *pval = s->target; } return 0; } static const JSClassExoticMethods js_proxy_exotic_methods = { .get_own_property = js_proxy_get_own_property, .define_own_property = js_proxy_define_own_property, .delete_property = js_proxy_delete_property, .get_own_property_names = js_proxy_get_own_property_names, .has_property = js_proxy_has, .get_property = js_proxy_get, .set_property = js_proxy_set, .get_prototype = js_proxy_get_prototype, .set_prototype = js_proxy_set_prototype, .is_extensible = js_proxy_is_extensible, .prevent_extensions = js_proxy_prevent_extensions, }; static JSValue js_proxy_constructor(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValueConst target, handler; JSValue obj; JSProxyData *s; target = argv[0]; handler = argv[1]; if (JS_VALUE_GET_TAG(target) != JS_TAG_OBJECT || JS_VALUE_GET_TAG(handler) != JS_TAG_OBJECT) return JS_ThrowTypeErrorNotAnObject(ctx); obj = JS_NewObjectProtoClass(ctx, JS_NULL, JS_CLASS_PROXY); if (JS_IsException(obj)) return obj; s = js_malloc(ctx, sizeof(JSProxyData)); if (!s) { JS_FreeValue(ctx, obj); return JS_EXCEPTION; } s->target = JS_DupValue(ctx, target); s->handler = JS_DupValue(ctx, handler); s->is_func = JS_IsFunction(ctx, target); s->is_revoked = FALSE; JS_SetOpaque(obj, s); JS_SetConstructorBit(ctx, obj, JS_IsConstructor(ctx, target)); return obj; } static JSValue js_proxy_revoke(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data) { JSProxyData *s = JS_GetOpaque(func_data[0], JS_CLASS_PROXY); if (s) { /* We do not free the handler and target in case they are referenced as constants in the C call stack */ s->is_revoked = TRUE; JS_FreeValue(ctx, func_data[0]); func_data[0] = JS_NULL; } return JS_UNDEFINED; } static JSValue js_proxy_revoke_constructor(JSContext *ctx, JSValueConst proxy_obj) { return JS_NewCFunctionData(ctx, js_proxy_revoke, 0, 0, 1, &proxy_obj); } static JSValue js_proxy_revocable(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue proxy_obj, revoke_obj = JS_UNDEFINED, obj; proxy_obj = js_proxy_constructor(ctx, JS_UNDEFINED, argc, argv); if (JS_IsException(proxy_obj)) goto fail; revoke_obj = js_proxy_revoke_constructor(ctx, proxy_obj); if (JS_IsException(revoke_obj)) goto fail; obj = JS_NewObject(ctx); if (JS_IsException(obj)) goto fail; // XXX: exceptions? JS_DefinePropertyValue(ctx, obj, JS_ATOM_proxy, proxy_obj, JS_PROP_C_W_E); JS_DefinePropertyValue(ctx, obj, JS_ATOM_revoke, revoke_obj, JS_PROP_C_W_E); return obj; fail: JS_FreeValue(ctx, proxy_obj); JS_FreeValue(ctx, revoke_obj); return JS_EXCEPTION; } static const JSCFunctionListEntry js_proxy_funcs[] = { JS_CFUNC_DEF("revocable", 2, js_proxy_revocable ), }; static const JSClassShortDef js_proxy_class_def[] = { { JS_ATOM_Object, js_proxy_finalizer, js_proxy_mark }, /* JS_CLASS_PROXY */ }; int JS_AddIntrinsicProxy(JSContext *ctx) { JSRuntime *rt = ctx->rt; JSValue obj1; if (!JS_IsRegisteredClass(rt, JS_CLASS_PROXY)) { if (init_class_range(rt, js_proxy_class_def, JS_CLASS_PROXY, countof(js_proxy_class_def))) return -1; rt->class_array[JS_CLASS_PROXY].exotic = &js_proxy_exotic_methods; rt->class_array[JS_CLASS_PROXY].call = js_proxy_call; } /* additional fields: name, length */ obj1 = JS_NewCFunction3(ctx, js_proxy_constructor, "Proxy", 2, JS_CFUNC_constructor, 0, ctx->function_proto, countof(js_proxy_funcs) + 2); if (JS_IsException(obj1)) return -1; JS_SetConstructorBit(ctx, obj1, TRUE); if (JS_SetPropertyFunctionList(ctx, obj1, js_proxy_funcs, countof(js_proxy_funcs))) goto fail; if (JS_DefinePropertyValueStr(ctx, ctx->global_obj, "Proxy", obj1, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE) < 0) goto fail; return 0; fail: JS_FreeValue(ctx, obj1); return -1; } /* Symbol */ static JSValue js_symbol_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { JSValue str; JSString *p; if (!JS_IsUndefined(new_target)) return JS_ThrowTypeErrorNotAConstructor(ctx, new_target); if (argc == 0 || JS_IsUndefined(argv[0])) { p = NULL; } else { str = JS_ToString(ctx, argv[0]); if (JS_IsException(str)) return JS_EXCEPTION; p = JS_VALUE_GET_STRING(str); } return JS_NewSymbol(ctx, p, JS_ATOM_TYPE_SYMBOL); } static JSValue js_thisSymbolValue(JSContext *ctx, JSValueConst this_val) { if (JS_VALUE_GET_TAG(this_val) == JS_TAG_SYMBOL) return JS_DupValue(ctx, this_val); if (JS_VALUE_GET_TAG(this_val) == JS_TAG_OBJECT) { JSObject *p = JS_VALUE_GET_OBJ(this_val); if (p->class_id == JS_CLASS_SYMBOL) { if (JS_VALUE_GET_TAG(p->u.object_data) == JS_TAG_SYMBOL) return JS_DupValue(ctx, p->u.object_data); } } return JS_ThrowTypeError(ctx, "not a symbol"); } static JSValue js_symbol_toString(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue val, ret; val = js_thisSymbolValue(ctx, this_val); if (JS_IsException(val)) return val; /* XXX: use JS_ToStringInternal() with a flags */ ret = js_string_constructor(ctx, JS_UNDEFINED, 1, (JSValueConst *)&val); JS_FreeValue(ctx, val); return ret; } static JSValue js_symbol_valueOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return js_thisSymbolValue(ctx, this_val); } static JSValue js_symbol_get_description(JSContext *ctx, JSValueConst this_val) { JSValue val, ret; JSAtomStruct *p; val = js_thisSymbolValue(ctx, this_val); if (JS_IsException(val)) return val; p = JS_VALUE_GET_PTR(val); if (p->len == 0 && p->is_wide_char != 0) { ret = JS_UNDEFINED; } else { ret = JS_AtomToString(ctx, js_get_atom_index(ctx->rt, p)); } JS_FreeValue(ctx, val); return ret; } static const JSCFunctionListEntry js_symbol_proto_funcs[] = { JS_CFUNC_DEF("toString", 0, js_symbol_toString ), JS_CFUNC_DEF("valueOf", 0, js_symbol_valueOf ), // XXX: should have writable: false JS_CFUNC_DEF("[Symbol.toPrimitive]", 1, js_symbol_valueOf ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Symbol", JS_PROP_CONFIGURABLE ), JS_CGETSET_DEF("description", js_symbol_get_description, NULL ), }; static JSValue js_symbol_for(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue str; str = JS_ToString(ctx, argv[0]); if (JS_IsException(str)) return JS_EXCEPTION; return JS_NewSymbol(ctx, JS_VALUE_GET_STRING(str), JS_ATOM_TYPE_GLOBAL_SYMBOL); } static JSValue js_symbol_keyFor(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSAtomStruct *p; if (!JS_IsSymbol(argv[0])) return JS_ThrowTypeError(ctx, "not a symbol"); p = JS_VALUE_GET_PTR(argv[0]); if (p->atom_type != JS_ATOM_TYPE_GLOBAL_SYMBOL) return JS_UNDEFINED; return JS_DupValue(ctx, JS_MKPTR(JS_TAG_STRING, p)); } static const JSCFunctionListEntry js_symbol_funcs[] = { JS_CFUNC_DEF("for", 1, js_symbol_for ), JS_CFUNC_DEF("keyFor", 1, js_symbol_keyFor ), JS_PROP_ATOM_DEF("toPrimitive", JS_ATOM_Symbol_toPrimitive, 0), JS_PROP_ATOM_DEF("iterator", JS_ATOM_Symbol_iterator, 0), JS_PROP_ATOM_DEF("match", JS_ATOM_Symbol_match, 0), JS_PROP_ATOM_DEF("matchAll", JS_ATOM_Symbol_matchAll, 0), JS_PROP_ATOM_DEF("replace", JS_ATOM_Symbol_replace, 0), JS_PROP_ATOM_DEF("search", JS_ATOM_Symbol_search, 0), JS_PROP_ATOM_DEF("split", JS_ATOM_Symbol_split, 0), JS_PROP_ATOM_DEF("toStringTag", JS_ATOM_Symbol_toStringTag, 0), JS_PROP_ATOM_DEF("isConcatSpreadable", JS_ATOM_Symbol_isConcatSpreadable, 0), JS_PROP_ATOM_DEF("hasInstance", JS_ATOM_Symbol_hasInstance, 0), JS_PROP_ATOM_DEF("species", JS_ATOM_Symbol_species, 0), JS_PROP_ATOM_DEF("unscopables", JS_ATOM_Symbol_unscopables, 0), JS_PROP_ATOM_DEF("asyncIterator", JS_ATOM_Symbol_asyncIterator, 0), }; /* Set/Map/WeakSet/WeakMap */ static BOOL js_weakref_is_target(JSValueConst val) { switch (JS_VALUE_GET_TAG(val)) { case JS_TAG_OBJECT: return TRUE; case JS_TAG_SYMBOL: { JSAtomStruct *p = JS_VALUE_GET_PTR(val); if (p->atom_type == JS_ATOM_TYPE_SYMBOL && p->hash != JS_ATOM_HASH_PRIVATE) return TRUE; } break; default: break; } return FALSE; } /* JS_UNDEFINED is considered as a live weakref */ /* XXX: add a specific JSWeakRef value type ? */ static BOOL js_weakref_is_live(JSValueConst val) { int *pref_count; if (JS_IsUndefined(val)) return TRUE; pref_count = JS_VALUE_GET_PTR(val); return (*pref_count != 0); } /* 'val' can be JS_UNDEFINED */ static void js_weakref_free(JSRuntime *rt, JSValue val) { if (JS_VALUE_GET_TAG(val) == JS_TAG_OBJECT) { JSObject *p = JS_VALUE_GET_OBJ(val); assert(p->weakref_count >= 1); p->weakref_count--; /* 'mark' is tested to avoid freeing the object structure when it is about to be freed in a cycle or in free_zero_refcount() */ if (p->weakref_count == 0 && p->header.ref_count == 0 && p->header.mark == 0) { js_free_rt(rt, p); } } else if (JS_VALUE_GET_TAG(val) == JS_TAG_SYMBOL) { JSString *p = JS_VALUE_GET_STRING(val); assert(p->hash >= 1); p->hash--; if (p->hash == 0 && p->header.ref_count == 0) { /* can remove the dummy structure */ js_free_rt(rt, p); } } } /* val must be an object, a symbol or undefined (see js_weakref_is_target). */ static JSValue js_weakref_new(JSContext *ctx, JSValueConst val) { if (JS_VALUE_GET_TAG(val) == JS_TAG_OBJECT) { JSObject *p = JS_VALUE_GET_OBJ(val); p->weakref_count++; } else if (JS_VALUE_GET_TAG(val) == JS_TAG_SYMBOL) { JSString *p = JS_VALUE_GET_STRING(val); /* XXX: could return an exception if too many references */ assert(p->hash < JS_ATOM_HASH_MASK - 2); p->hash++; } else { assert(JS_IsUndefined(val)); } return (JSValue)val; } #define MAGIC_SET (1 << 0) #define MAGIC_WEAK (1 << 1) static JSValue js_map_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv, int magic) { JSMapState *s; JSValue obj, adder = JS_UNDEFINED, iter = JS_UNDEFINED, next_method = JS_UNDEFINED; JSValueConst arr; BOOL is_set, is_weak; is_set = magic & MAGIC_SET; is_weak = ((magic & MAGIC_WEAK) != 0); obj = js_create_from_ctor(ctx, new_target, JS_CLASS_MAP + magic); if (JS_IsException(obj)) return JS_EXCEPTION; s = js_mallocz(ctx, sizeof(*s)); if (!s) goto fail; init_list_head(&s->records); s->is_weak = is_weak; if (is_weak) { s->weakref_header.weakref_type = JS_WEAKREF_TYPE_MAP; list_add_tail(&s->weakref_header.link, &ctx->rt->weakref_list); } JS_SetOpaque(obj, s); s->hash_bits = 1; s->hash_size = 1U << s->hash_bits; s->hash_table = js_mallocz(ctx, sizeof(s->hash_table[0]) * s->hash_size); if (!s->hash_table) goto fail; s->record_count_threshold = 4; arr = JS_UNDEFINED; if (argc > 0) arr = argv[0]; if (!JS_IsUndefined(arr) && !JS_IsNull(arr)) { JSValue item, ret; BOOL done; adder = JS_GetProperty(ctx, obj, is_set ? JS_ATOM_add : JS_ATOM_set); if (JS_IsException(adder)) goto fail; if (!JS_IsFunction(ctx, adder)) { JS_ThrowTypeError(ctx, "set/add is not a function"); goto fail; } iter = JS_GetIterator(ctx, arr, FALSE); if (JS_IsException(iter)) goto fail; next_method = JS_GetProperty(ctx, iter, JS_ATOM_next); if (JS_IsException(next_method)) goto fail; for(;;) { item = JS_IteratorNext(ctx, iter, next_method, 0, NULL, &done); if (JS_IsException(item)) goto fail; if (done) break; if (is_set) { ret = JS_Call(ctx, adder, obj, 1, (JSValueConst *)&item); if (JS_IsException(ret)) { JS_FreeValue(ctx, item); goto fail_close; } } else { JSValue key, value; JSValueConst args[2]; key = JS_UNDEFINED; value = JS_UNDEFINED; if (!JS_IsObject(item)) { JS_ThrowTypeErrorNotAnObject(ctx); goto fail1; } key = JS_GetPropertyUint32(ctx, item, 0); if (JS_IsException(key)) goto fail1; value = JS_GetPropertyUint32(ctx, item, 1); if (JS_IsException(value)) goto fail1; args[0] = key; args[1] = value; ret = JS_Call(ctx, adder, obj, 2, args); if (JS_IsException(ret)) { fail1: JS_FreeValue(ctx, item); JS_FreeValue(ctx, key); JS_FreeValue(ctx, value); goto fail_close; } JS_FreeValue(ctx, key); JS_FreeValue(ctx, value); } JS_FreeValue(ctx, ret); JS_FreeValue(ctx, item); } JS_FreeValue(ctx, next_method); JS_FreeValue(ctx, iter); JS_FreeValue(ctx, adder); } return obj; fail_close: /* close the iterator object, preserving pending exception */ JS_IteratorClose(ctx, iter, TRUE); fail: JS_FreeValue(ctx, next_method); JS_FreeValue(ctx, iter); JS_FreeValue(ctx, adder); JS_FreeValue(ctx, obj); return JS_EXCEPTION; } /* XXX: could normalize strings to speed up comparison */ static JSValue map_normalize_key(JSContext *ctx, JSValue key) { uint32_t tag = JS_VALUE_GET_TAG(key); /* convert -0.0 to +0.0 */ if (JS_TAG_IS_FLOAT64(tag) && JS_VALUE_GET_FLOAT64(key) == 0.0) { key = JS_NewInt32(ctx, 0); } return key; } static JSValueConst map_normalize_key_const(JSContext *ctx, JSValueConst key) { return (JSValueConst)map_normalize_key(ctx, (JSValue)key); } /* hash multipliers, same as the Linux kernel (see Knuth vol 3, section 6.4, exercise 9) */ #define HASH_MUL32 0x61C88647 #define HASH_MUL64 UINT64_C(0x61C8864680B583EB) static uint32_t map_hash32(uint32_t a, int hash_bits) { return (a * HASH_MUL32) >> (32 - hash_bits); } static uint32_t map_hash64(uint64_t a, int hash_bits) { return (a * HASH_MUL64) >> (64 - hash_bits); } static uint32_t map_hash_pointer(uintptr_t a, int hash_bits) { #ifdef JS_PTR64 return map_hash64(a, hash_bits); #else return map_hash32(a, hash_bits); #endif } /* XXX: better hash ? */ /* precondition: 1 <= hash_bits <= 32 */ static uint32_t map_hash_key(JSValueConst key, int hash_bits) { uint32_t tag = JS_VALUE_GET_NORM_TAG(key); uint32_t h; double d; JSBigInt *p; JSBigIntBuf buf; switch(tag) { case JS_TAG_BOOL: h = map_hash32(JS_VALUE_GET_INT(key) ^ JS_TAG_BOOL, hash_bits); break; case JS_TAG_STRING: h = map_hash32(hash_string(JS_VALUE_GET_STRING(key), 0) ^ JS_TAG_STRING, hash_bits); break; case JS_TAG_STRING_ROPE: h = map_hash32(hash_string_rope(key, 0) ^ JS_TAG_STRING, hash_bits); break; case JS_TAG_OBJECT: case JS_TAG_SYMBOL: h = map_hash_pointer((uintptr_t)JS_VALUE_GET_PTR(key) ^ tag, hash_bits); break; case JS_TAG_INT: d = JS_VALUE_GET_INT(key); goto hash_float64; case JS_TAG_FLOAT64: d = JS_VALUE_GET_FLOAT64(key); /* normalize the NaN */ if (isnan(d)) d = JS_FLOAT64_NAN; hash_float64: h = map_hash64(float64_as_uint64(d) ^ JS_TAG_FLOAT64, hash_bits); break; case JS_TAG_SHORT_BIG_INT: p = js_bigint_set_short(&buf, key); goto hash_bigint; case JS_TAG_BIG_INT: p = JS_VALUE_GET_PTR(key); hash_bigint: { int i; h = 1; for(i = p->len - 1; i >= 0; i--) { h = h * 263 + p->tab[i]; } /* the final step is necessary otherwise h mod n only depends of p->tab[i] mod n */ h = map_hash32(h ^ JS_TAG_BIG_INT, hash_bits); } break; default: h = 0; break; } return h; } static JSMapRecord *map_find_record(JSContext *ctx, JSMapState *s, JSValueConst key) { JSMapRecord *mr; uint32_t h; h = map_hash_key(key, s->hash_bits); for(mr = s->hash_table[h]; mr != NULL; mr = mr->hash_next) { if (mr->empty || (s->is_weak && !js_weakref_is_live(mr->key))) { /* cannot match */ } else { if (js_same_value_zero(ctx, mr->key, key)) return mr; } } return NULL; } static void map_hash_resize(JSContext *ctx, JSMapState *s) { uint32_t new_hash_size, h; int new_hash_bits; struct list_head *el; JSMapRecord *mr, **new_hash_table; /* XXX: no reporting of memory allocation failure */ new_hash_bits = min_int(s->hash_bits + 1, 31); new_hash_size = 1U << new_hash_bits; new_hash_table = js_realloc(ctx, s->hash_table, sizeof(new_hash_table[0]) * new_hash_size); if (!new_hash_table) return; memset(new_hash_table, 0, sizeof(new_hash_table[0]) * new_hash_size); list_for_each(el, &s->records) { mr = list_entry(el, JSMapRecord, link); if (mr->empty || (s->is_weak && !js_weakref_is_live(mr->key))) { } else { h = map_hash_key(mr->key, new_hash_bits); mr->hash_next = new_hash_table[h]; new_hash_table[h] = mr; } } s->hash_table = new_hash_table; s->hash_bits = new_hash_bits; s->hash_size = new_hash_size; s->record_count_threshold = new_hash_size * 2; } static JSMapRecord *map_add_record(JSContext *ctx, JSMapState *s, JSValueConst key) { uint32_t h; JSMapRecord *mr; mr = js_malloc(ctx, sizeof(*mr)); if (!mr) return NULL; mr->ref_count = 1; mr->empty = FALSE; if (s->is_weak) { mr->key = js_weakref_new(ctx, key); } else { mr->key = JS_DupValue(ctx, key); } h = map_hash_key(key, s->hash_bits); mr->hash_next = s->hash_table[h]; s->hash_table[h] = mr; list_add_tail(&mr->link, &s->records); s->record_count++; if (s->record_count >= s->record_count_threshold) { map_hash_resize(ctx, s); } return mr; } static JSMapRecord *set_add_record(JSContext *ctx, JSMapState *s, JSValueConst key) { JSMapRecord *mr; mr = map_add_record(ctx, s, key); if (!mr) return NULL; mr->value = JS_UNDEFINED; return mr; } /* warning: the record must be removed from the hash table before */ static void map_delete_record_internal(JSRuntime *rt, JSMapState *s, JSMapRecord *mr) { if (mr->empty) return; if (s->is_weak) { js_weakref_free(rt, mr->key); } else { JS_FreeValueRT(rt, mr->key); } JS_FreeValueRT(rt, mr->value); if (--mr->ref_count == 0) { list_del(&mr->link); js_free_rt(rt, mr); } else { /* keep a zombie record for iterators */ mr->empty = TRUE; mr->key = JS_UNDEFINED; mr->value = JS_UNDEFINED; } s->record_count--; } static void map_decref_record(JSRuntime *rt, JSMapRecord *mr) { if (--mr->ref_count == 0) { /* the record can be safely removed */ assert(mr->empty); list_del(&mr->link); js_free_rt(rt, mr); } } static void map_delete_weakrefs(JSRuntime *rt, JSWeakRefHeader *wh) { JSMapState *s = container_of(wh, JSMapState, weakref_header); struct list_head *el, *el1; JSMapRecord *mr1, **pmr; uint32_t h; list_for_each_safe(el, el1, &s->records) { JSMapRecord *mr = list_entry(el, JSMapRecord, link); if (!js_weakref_is_live(mr->key)) { /* even if key is not live it can be hashed as a pointer */ h = map_hash_key(mr->key, s->hash_bits); pmr = &s->hash_table[h]; for(;;) { mr1 = *pmr; /* the entry may already be removed from the hash table if the map was resized */ if (mr1 == NULL) goto done; if (mr1 == mr) break; pmr = &mr1->hash_next; } /* remove from the hash table */ *pmr = mr1->hash_next; done: map_delete_record_internal(rt, s, mr); } } } static JSValue js_map_set(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSMapState *s = JS_GetOpaque2(ctx, this_val, JS_CLASS_MAP + magic); JSMapRecord *mr; JSValueConst key, value; if (!s) return JS_EXCEPTION; key = map_normalize_key_const(ctx, argv[0]); if (s->is_weak && !js_weakref_is_target(key)) return JS_ThrowTypeError(ctx, "invalid value used as %s key", (magic & MAGIC_SET) ? "WeakSet" : "WeakMap"); if (magic & MAGIC_SET) value = JS_UNDEFINED; else value = argv[1]; mr = map_find_record(ctx, s, key); if (mr) { JS_FreeValue(ctx, mr->value); } else { mr = map_add_record(ctx, s, key); if (!mr) return JS_EXCEPTION; } mr->value = JS_DupValue(ctx, value); return JS_DupValue(ctx, this_val); } static JSValue js_map_get(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSMapState *s = JS_GetOpaque2(ctx, this_val, JS_CLASS_MAP + magic); JSMapRecord *mr; JSValueConst key; if (!s) return JS_EXCEPTION; key = map_normalize_key_const(ctx, argv[0]); mr = map_find_record(ctx, s, key); if (!mr) return JS_UNDEFINED; else return JS_DupValue(ctx, mr->value); } /* return JS_TRUE or JS_FALSE */ static JSValue map_delete_record(JSContext *ctx, JSMapState *s, JSValueConst key) { JSMapRecord *mr, **pmr; uint32_t h; key = map_normalize_key_const(ctx, key); h = map_hash_key(key, s->hash_bits); pmr = &s->hash_table[h]; for(;;) { mr = *pmr; if (mr == NULL) return JS_FALSE; if (mr->empty || (s->is_weak && !js_weakref_is_live(mr->key))) { /* not valid */ } else { if (js_same_value_zero(ctx, mr->key, key)) break; } pmr = &mr->hash_next; } /* remove from the hash table */ *pmr = mr->hash_next; map_delete_record_internal(ctx->rt, s, mr); return JS_TRUE; } static JSValue js_map_getOrInsert(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { BOOL computed = magic & 1; JSClassID class_id = magic >> 1; JSMapState *s = JS_GetOpaque2(ctx, this_val, class_id); JSMapRecord *mr; JSValueConst key; JSValue value; if (!s) return JS_EXCEPTION; if (computed && !JS_IsFunction(ctx, argv[1])) return JS_ThrowTypeError(ctx, "not a function"); key = map_normalize_key_const(ctx, argv[0]); if (s->is_weak && !js_weakref_is_target(key)) return JS_ThrowTypeError(ctx, "invalid value used as WeakMap key"); mr = map_find_record(ctx, s, key); if (!mr) { if (computed) { value = JS_Call(ctx, argv[1], JS_UNDEFINED, 1, &key); if (JS_IsException(value)) return JS_EXCEPTION; map_delete_record(ctx, s, key); } else { value = JS_DupValue(ctx, argv[1]); } mr = map_add_record(ctx, s, key); if (!mr) { JS_FreeValue(ctx, value); return JS_EXCEPTION; } mr->value = value; } return JS_DupValue(ctx, mr->value); } static JSValue js_map_has(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSMapState *s = JS_GetOpaque2(ctx, this_val, JS_CLASS_MAP + magic); JSMapRecord *mr; JSValueConst key; if (!s) return JS_EXCEPTION; key = map_normalize_key_const(ctx, argv[0]); mr = map_find_record(ctx, s, key); return JS_NewBool(ctx, mr != NULL); } static JSValue js_map_delete(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSMapState *s = JS_GetOpaque2(ctx, this_val, JS_CLASS_MAP + magic); if (!s) return JS_EXCEPTION; return map_delete_record(ctx, s, argv[0]); } static JSValue js_map_clear(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSMapState *s = JS_GetOpaque2(ctx, this_val, JS_CLASS_MAP + magic); struct list_head *el, *el1; JSMapRecord *mr; if (!s) return JS_EXCEPTION; /* remove from the hash table */ memset(s->hash_table, 0, sizeof(s->hash_table[0]) * s->hash_size); list_for_each_safe(el, el1, &s->records) { mr = list_entry(el, JSMapRecord, link); map_delete_record_internal(ctx->rt, s, mr); } return JS_UNDEFINED; } static JSValue js_map_get_size(JSContext *ctx, JSValueConst this_val, int magic) { JSMapState *s = JS_GetOpaque2(ctx, this_val, JS_CLASS_MAP + magic); if (!s) return JS_EXCEPTION; return JS_NewUint32(ctx, s->record_count); } static JSValue js_map_forEach(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSMapState *s = JS_GetOpaque2(ctx, this_val, JS_CLASS_MAP + magic); JSValueConst func, this_arg; JSValue ret, args[3]; struct list_head *el; JSMapRecord *mr; if (!s) return JS_EXCEPTION; func = argv[0]; if (argc > 1) this_arg = argv[1]; else this_arg = JS_UNDEFINED; if (check_function(ctx, func)) return JS_EXCEPTION; /* Note: the list can be modified while traversing it, but the current element is locked */ el = s->records.next; while (el != &s->records) { mr = list_entry(el, JSMapRecord, link); if (!mr->empty) { mr->ref_count++; /* must duplicate in case the record is deleted */ args[1] = JS_DupValue(ctx, mr->key); if (magic) args[0] = args[1]; else args[0] = JS_DupValue(ctx, mr->value); args[2] = (JSValue)this_val; ret = JS_Call(ctx, func, this_arg, 3, (JSValueConst *)args); JS_FreeValue(ctx, args[0]); if (!magic) JS_FreeValue(ctx, args[1]); el = el->next; map_decref_record(ctx->rt, mr); if (JS_IsException(ret)) return ret; JS_FreeValue(ctx, ret); } else { el = el->next; } } return JS_UNDEFINED; } static JSValue js_object_groupBy(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int is_map) { JSValueConst cb, args[2]; JSValue res, iter, next, groups, key, v, prop; JSAtom key_atom = JS_ATOM_NULL; int64_t idx; BOOL done; // "is function?" check must be observed before argv[0] is accessed cb = argv[1]; if (check_function(ctx, cb)) return JS_EXCEPTION; iter = JS_GetIterator(ctx, argv[0], /*is_async*/FALSE); if (JS_IsException(iter)) return JS_EXCEPTION; key = JS_UNDEFINED; key_atom = JS_ATOM_NULL; v = JS_UNDEFINED; prop = JS_UNDEFINED; groups = JS_UNDEFINED; next = JS_GetProperty(ctx, iter, JS_ATOM_next); if (JS_IsException(next)) goto exception; if (is_map) { groups = js_map_constructor(ctx, JS_UNDEFINED, 0, NULL, 0); } else { groups = JS_NewObjectProto(ctx, JS_NULL); } if (JS_IsException(groups)) goto exception; for (idx = 0; ; idx++) { if (idx >= MAX_SAFE_INTEGER) { JS_ThrowTypeError(ctx, "too many elements"); goto iterator_close_exception; } v = JS_IteratorNext(ctx, iter, next, 0, NULL, &done); if (JS_IsException(v)) goto exception; if (done) break; // v is JS_UNDEFINED args[0] = v; args[1] = JS_NewInt64(ctx, idx); key = JS_Call(ctx, cb, ctx->global_obj, 2, args); if (JS_IsException(key)) goto iterator_close_exception; if (is_map) { prop = js_map_get(ctx, groups, 1, (JSValueConst *)&key, 0); } else { key_atom = JS_ValueToAtom(ctx, key); JS_FreeValue(ctx, key); key = JS_UNDEFINED; if (key_atom == JS_ATOM_NULL) goto iterator_close_exception; prop = JS_GetProperty(ctx, groups, key_atom); } if (JS_IsException(prop)) goto exception; if (JS_IsUndefined(prop)) { prop = JS_NewArray(ctx); if (JS_IsException(prop)) goto exception; if (is_map) { args[0] = key; args[1] = prop; res = js_map_set(ctx, groups, 2, args, 0); if (JS_IsException(res)) goto exception; JS_FreeValue(ctx, res); } else { prop = JS_DupValue(ctx, prop); if (JS_DefinePropertyValue(ctx, groups, key_atom, prop, JS_PROP_C_W_E) < 0) { goto exception; } } } res = js_array_push(ctx, prop, 1, (JSValueConst *)&v, /*unshift*/0); if (JS_IsException(res)) goto exception; // res is an int64 JS_FreeValue(ctx, prop); JS_FreeValue(ctx, key); JS_FreeAtom(ctx, key_atom); JS_FreeValue(ctx, v); prop = JS_UNDEFINED; key = JS_UNDEFINED; key_atom = JS_ATOM_NULL; v = JS_UNDEFINED; } JS_FreeValue(ctx, iter); JS_FreeValue(ctx, next); return groups; iterator_close_exception: JS_IteratorClose(ctx, iter, TRUE); exception: JS_FreeAtom(ctx, key_atom); JS_FreeValue(ctx, prop); JS_FreeValue(ctx, key); JS_FreeValue(ctx, v); JS_FreeValue(ctx, groups); JS_FreeValue(ctx, iter); JS_FreeValue(ctx, next); return JS_EXCEPTION; } static void js_map_finalizer(JSRuntime *rt, JSValue val) { JSObject *p; JSMapState *s; struct list_head *el, *el1; JSMapRecord *mr; p = JS_VALUE_GET_OBJ(val); s = p->u.map_state; if (s) { /* if the object is deleted we are sure that no iterator is using it */ list_for_each_safe(el, el1, &s->records) { mr = list_entry(el, JSMapRecord, link); if (!mr->empty) { if (s->is_weak) js_weakref_free(rt, mr->key); else JS_FreeValueRT(rt, mr->key); JS_FreeValueRT(rt, mr->value); } js_free_rt(rt, mr); } js_free_rt(rt, s->hash_table); if (s->is_weak) { list_del(&s->weakref_header.link); } js_free_rt(rt, s); } } static void js_map_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); JSMapState *s; struct list_head *el; JSMapRecord *mr; s = p->u.map_state; if (s) { list_for_each(el, &s->records) { mr = list_entry(el, JSMapRecord, link); if (!s->is_weak) JS_MarkValue(rt, mr->key, mark_func); JS_MarkValue(rt, mr->value, mark_func); } } } /* Map Iterator */ typedef struct JSMapIteratorData { JSValue obj; JSIteratorKindEnum kind; JSMapRecord *cur_record; } JSMapIteratorData; static void js_map_iterator_finalizer(JSRuntime *rt, JSValue val) { JSObject *p; JSMapIteratorData *it; p = JS_VALUE_GET_OBJ(val); it = p->u.map_iterator_data; if (it) { /* During the GC sweep phase the Map finalizer may be called before the Map iterator finalizer */ if (JS_IsLiveObject(rt, it->obj) && it->cur_record) { map_decref_record(rt, it->cur_record); } JS_FreeValueRT(rt, it->obj); js_free_rt(rt, it); } } static void js_map_iterator_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); JSMapIteratorData *it; it = p->u.map_iterator_data; if (it) { /* the record is already marked by the object */ JS_MarkValue(rt, it->obj, mark_func); } } static JSValue js_create_map_iterator(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSIteratorKindEnum kind; JSMapState *s; JSMapIteratorData *it; JSValue enum_obj; kind = magic >> 2; magic &= 3; s = JS_GetOpaque2(ctx, this_val, JS_CLASS_MAP + magic); if (!s) return JS_EXCEPTION; enum_obj = JS_NewObjectClass(ctx, JS_CLASS_MAP_ITERATOR + magic); if (JS_IsException(enum_obj)) goto fail; it = js_malloc(ctx, sizeof(*it)); if (!it) { JS_FreeValue(ctx, enum_obj); goto fail; } it->obj = JS_DupValue(ctx, this_val); it->kind = kind; it->cur_record = NULL; JS_SetOpaque(enum_obj, it); return enum_obj; fail: return JS_EXCEPTION; } static JSValue js_map_iterator_next(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, BOOL *pdone, int magic) { JSMapIteratorData *it; JSMapState *s; JSMapRecord *mr; struct list_head *el; it = JS_GetOpaque2(ctx, this_val, JS_CLASS_MAP_ITERATOR + magic); if (!it) { *pdone = FALSE; return JS_EXCEPTION; } if (JS_IsUndefined(it->obj)) goto done; s = JS_GetOpaque(it->obj, JS_CLASS_MAP + magic); assert(s != NULL); if (!it->cur_record) { el = s->records.next; } else { mr = it->cur_record; el = mr->link.next; map_decref_record(ctx->rt, mr); /* the record can be freed here */ } for(;;) { if (el == &s->records) { /* no more record */ it->cur_record = NULL; JS_FreeValue(ctx, it->obj); it->obj = JS_UNDEFINED; done: /* end of enumeration */ *pdone = TRUE; return JS_UNDEFINED; } mr = list_entry(el, JSMapRecord, link); if (!mr->empty) break; /* get the next record */ el = mr->link.next; } /* lock the record so that it won't be freed */ mr->ref_count++; it->cur_record = mr; *pdone = FALSE; if (it->kind == JS_ITERATOR_KIND_KEY) { return JS_DupValue(ctx, mr->key); } else { JSValueConst args[2]; args[0] = mr->key; if (magic) args[1] = mr->key; else args[1] = mr->value; if (it->kind == JS_ITERATOR_KIND_VALUE) { return JS_DupValue(ctx, args[1]); } else { return js_create_array(ctx, 2, args); } } } static int get_set_record(JSContext *ctx, JSValueConst obj, int64_t *psize, JSValue *phas, JSValue *pkeys) { JSMapState *s; int64_t size; JSValue has = JS_UNDEFINED, keys = JS_UNDEFINED; s = JS_GetOpaque(obj, JS_CLASS_SET); if (s) { size = s->record_count; } else { JSValue v; double d; v = JS_GetProperty(ctx, obj, JS_ATOM_size); if (JS_IsException(v)) goto exception; if (JS_ToFloat64Free(ctx, &d, v) < 0) goto exception; if (isnan(d)) { JS_ThrowTypeError(ctx, ".size is not a number"); goto exception; } if (d < INT64_MIN) size = INT64_MIN; else if (d >= 0x1p63) /* must use INT64_MAX + 1 because INT64_MAX cannot be exactly represented as a double */ size = INT64_MAX; else size = (int64_t)d; if (size < 0) { JS_ThrowRangeError(ctx, ".size must be positive"); goto exception; } } has = JS_GetProperty(ctx, obj, JS_ATOM_has); if (JS_IsException(has)) goto exception; if (JS_IsUndefined(has)) { JS_ThrowTypeError(ctx, ".has is undefined"); goto exception; } if (!JS_IsFunction(ctx, has)) { JS_ThrowTypeError(ctx, ".has is not a function"); goto exception; } keys = JS_GetProperty(ctx, obj, JS_ATOM_keys); if (JS_IsException(keys)) goto exception; if (JS_IsUndefined(keys)) { JS_ThrowTypeError(ctx, ".keys is undefined"); goto exception; } if (!JS_IsFunction(ctx, keys)) { JS_ThrowTypeError(ctx, ".keys is not a function"); goto exception; } *psize = size; *phas = has; *pkeys = keys; return 0; exception: JS_FreeValue(ctx, has); JS_FreeValue(ctx, keys); *psize = 0; *phas = JS_UNDEFINED; *pkeys = JS_UNDEFINED; return -1; } /* copy 'this_val' in a new set without side effects */ static JSValue js_copy_set(JSContext *ctx, JSValueConst this_val) { JSValue newset; JSMapState *s, *t; struct list_head *el; JSMapRecord *mr; s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET); if (!s) return JS_EXCEPTION; newset = js_map_constructor(ctx, JS_UNDEFINED, 0, NULL, MAGIC_SET); if (JS_IsException(newset)) return JS_EXCEPTION; t = JS_GetOpaque(newset, JS_CLASS_SET); // can't clone this_val using js_map_constructor(), // test262 mandates we don't call the .add method list_for_each(el, &s->records) { mr = list_entry(el, JSMapRecord, link); if (mr->empty) continue; if (!set_add_record(ctx, t, mr->key)) goto exception; } return newset; exception: JS_FreeValue(ctx, newset); return JS_EXCEPTION; } static JSValue js_set_isDisjointFrom(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue item, iter, keys, has, next, rv, rval; int done; BOOL found; JSMapState *s; int64_t size; int ok; iter = JS_UNDEFINED; next = JS_UNDEFINED; rval = JS_EXCEPTION; s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET); if (!s) return JS_EXCEPTION; if (get_set_record(ctx, argv[0], &size, &has, &keys) < 0) goto exception; if (s->record_count <= size) { iter = js_create_map_iterator(ctx, this_val, 0, NULL, MAGIC_SET); if (JS_IsException(iter)) goto exception; found = FALSE; do { item = js_map_iterator_next(ctx, iter, 0, NULL, &done, MAGIC_SET); if (JS_IsException(item)) goto exception; if (done) // item is JS_UNDEFINED break; rv = JS_Call(ctx, has, argv[0], 1, (JSValueConst *)&item); JS_FreeValue(ctx, item); ok = JS_ToBoolFree(ctx, rv); // returns -1 if rv is JS_EXCEPTION if (ok < 0) goto exception; found = (ok > 0); } while (!found); } else { iter = JS_Call(ctx, keys, argv[0], 0, NULL); if (JS_IsException(iter)) goto exception; next = JS_GetProperty(ctx, iter, JS_ATOM_next); if (JS_IsException(next)) goto exception; found = FALSE; for(;;) { item = JS_IteratorNext(ctx, iter, next, 0, NULL, &done); if (JS_IsException(item)) goto exception; if (done) // item is JS_UNDEFINED break; item = map_normalize_key(ctx, item); found = (NULL != map_find_record(ctx, s, item)); JS_FreeValue(ctx, item); if (found) { JS_IteratorClose(ctx, iter, FALSE); break; } } } rval = !found ? JS_TRUE : JS_FALSE; exception: JS_FreeValue(ctx, has); JS_FreeValue(ctx, keys); JS_FreeValue(ctx, iter); JS_FreeValue(ctx, next); return rval; } static JSValue js_set_isSubsetOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue item, iter, keys, has, next, rv, rval; BOOL found; JSMapState *s; int64_t size; int done, ok; iter = JS_UNDEFINED; next = JS_UNDEFINED; rval = JS_EXCEPTION; s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET); if (!s) return JS_EXCEPTION; if (get_set_record(ctx, argv[0], &size, &has, &keys) < 0) goto exception; found = FALSE; if (s->record_count > size) goto fini; iter = js_create_map_iterator(ctx, this_val, 0, NULL, MAGIC_SET); if (JS_IsException(iter)) goto exception; found = TRUE; do { item = js_map_iterator_next(ctx, iter, 0, NULL, &done, MAGIC_SET); if (JS_IsException(item)) goto exception; if (done) // item is JS_UNDEFINED break; rv = JS_Call(ctx, has, argv[0], 1, (JSValueConst *)&item); JS_FreeValue(ctx, item); ok = JS_ToBoolFree(ctx, rv); // returns -1 if rv is JS_EXCEPTION if (ok < 0) goto exception; found = (ok > 0); } while (found); fini: rval = found ? JS_TRUE : JS_FALSE; exception: JS_FreeValue(ctx, has); JS_FreeValue(ctx, keys); JS_FreeValue(ctx, iter); JS_FreeValue(ctx, next); return rval; } static JSValue js_set_isSupersetOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue item, iter, keys, has, next, rval; int done; BOOL found; JSMapState *s; int64_t size; iter = JS_UNDEFINED; next = JS_UNDEFINED; rval = JS_EXCEPTION; s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET); if (!s) return JS_EXCEPTION; if (get_set_record(ctx, argv[0], &size, &has, &keys) < 0) goto exception; found = FALSE; if (s->record_count < size) goto fini; iter = JS_Call(ctx, keys, argv[0], 0, NULL); if (JS_IsException(iter)) goto exception; next = JS_GetProperty(ctx, iter, JS_ATOM_next); if (JS_IsException(next)) goto exception; found = TRUE; for(;;) { item = JS_IteratorNext(ctx, iter, next, 0, NULL, &done); if (JS_IsException(item)) goto exception; if (done) // item is JS_UNDEFINED break; item = map_normalize_key(ctx, item); found = (NULL != map_find_record(ctx, s, item)); JS_FreeValue(ctx, item); if (!found) { JS_IteratorClose(ctx, iter, FALSE); break; } } fini: rval = found ? JS_TRUE : JS_FALSE; exception: JS_FreeValue(ctx, has); JS_FreeValue(ctx, keys); JS_FreeValue(ctx, iter); JS_FreeValue(ctx, next); return rval; } static JSValue js_set_intersection(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue newset, item, iter, keys, has, next, rv; JSMapState *s, *t; JSMapRecord *mr; int64_t size; int done, ok; iter = JS_UNDEFINED; next = JS_UNDEFINED; newset = JS_UNDEFINED; s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET); if (!s) return JS_EXCEPTION; if (get_set_record(ctx, argv[0], &size, &has, &keys) < 0) goto exception; if (s->record_count > size) { iter = JS_Call(ctx, keys, argv[0], 0, NULL); if (JS_IsException(iter)) goto exception; next = JS_GetProperty(ctx, iter, JS_ATOM_next); if (JS_IsException(next)) goto exception; newset = js_map_constructor(ctx, JS_UNDEFINED, 0, NULL, MAGIC_SET); if (JS_IsException(newset)) goto exception; t = JS_GetOpaque(newset, JS_CLASS_SET); for (;;) { item = JS_IteratorNext(ctx, iter, next, 0, NULL, &done); if (JS_IsException(item)) goto exception; if (done) // item is JS_UNDEFINED break; item = map_normalize_key(ctx, item); if (!map_find_record(ctx, s, item)) { JS_FreeValue(ctx, item); } else if (map_find_record(ctx, t, item)) { JS_FreeValue(ctx, item); // no duplicates } else { mr = set_add_record(ctx, t, item); JS_FreeValue(ctx, item); if (!mr) goto exception; } } } else { iter = js_create_map_iterator(ctx, this_val, 0, NULL, MAGIC_SET); if (JS_IsException(iter)) goto exception; newset = js_map_constructor(ctx, JS_UNDEFINED, 0, NULL, MAGIC_SET); if (JS_IsException(newset)) goto exception; t = JS_GetOpaque(newset, JS_CLASS_SET); for (;;) { item = js_map_iterator_next(ctx, iter, 0, NULL, &done, MAGIC_SET); if (JS_IsException(item)) goto exception; if (done) // item is JS_UNDEFINED break; rv = JS_Call(ctx, has, argv[0], 1, (JSValueConst *)&item); ok = JS_ToBoolFree(ctx, rv); // returns -1 if rv is JS_EXCEPTION if (ok > 0) { item = map_normalize_key(ctx, item); if (map_find_record(ctx, t, item)) { JS_FreeValue(ctx, item); // no duplicates } else { mr = set_add_record(ctx, t, item); JS_FreeValue(ctx, item); if (!mr) goto exception; } } else { JS_FreeValue(ctx, item); if (ok < 0) goto exception; } } } goto fini; exception: JS_FreeValue(ctx, newset); newset = JS_EXCEPTION; fini: JS_FreeValue(ctx, has); JS_FreeValue(ctx, keys); JS_FreeValue(ctx, iter); JS_FreeValue(ctx, next); return newset; } static JSValue js_set_difference(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue newset, item, iter, keys, has, next, rv; JSMapState *s, *t; int64_t size; int done; int ok; iter = JS_UNDEFINED; next = JS_UNDEFINED; newset = JS_UNDEFINED; s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET); if (!s) return JS_EXCEPTION; if (get_set_record(ctx, argv[0], &size, &has, &keys) < 0) goto exception; newset = js_copy_set(ctx, this_val); if (JS_IsException(newset)) goto exception; t = JS_GetOpaque(newset, JS_CLASS_SET); if (s->record_count <= size) { iter = js_create_map_iterator(ctx, newset, 0, NULL, MAGIC_SET); if (JS_IsException(iter)) goto exception; for (;;) { item = js_map_iterator_next(ctx, iter, 0, NULL, &done, MAGIC_SET); if (JS_IsException(item)) goto exception; if (done) // item is JS_UNDEFINED break; rv = JS_Call(ctx, has, argv[0], 1, (JSValueConst *)&item); ok = JS_ToBoolFree(ctx, rv); // returns -1 if rv is JS_EXCEPTION if (ok < 0) { JS_FreeValue(ctx, item); goto exception; } if (ok) { map_delete_record(ctx, t, item); } JS_FreeValue(ctx, item); } } else { iter = JS_Call(ctx, keys, argv[0], 0, NULL); if (JS_IsException(iter)) goto exception; next = JS_GetProperty(ctx, iter, JS_ATOM_next); if (JS_IsException(next)) goto exception; for (;;) { item = JS_IteratorNext(ctx, iter, next, 0, NULL, &done); if (JS_IsException(item)) goto exception; if (done) // item is JS_UNDEFINED break; map_delete_record(ctx, t, item); JS_FreeValue(ctx, item); } } goto fini; exception: JS_FreeValue(ctx, newset); newset = JS_EXCEPTION; fini: JS_FreeValue(ctx, has); JS_FreeValue(ctx, keys); JS_FreeValue(ctx, iter); JS_FreeValue(ctx, next); return newset; } static JSValue js_set_symmetricDifference(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue newset, item, iter, next, has, keys; JSMapState *s, *t; JSMapRecord *mr; int64_t size; int done; BOOL present; s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET); if (!s) return JS_EXCEPTION; if (get_set_record(ctx, argv[0], &size, &has, &keys) < 0) return JS_EXCEPTION; JS_FreeValue(ctx, has); next = JS_UNDEFINED; newset = JS_UNDEFINED; iter = JS_Call(ctx, keys, argv[0], 0, NULL); if (JS_IsException(iter)) goto exception; next = JS_GetProperty(ctx, iter, JS_ATOM_next); if (JS_IsException(next)) goto exception; newset = js_copy_set(ctx, this_val); if (JS_IsException(newset)) goto exception; t = JS_GetOpaque(newset, JS_CLASS_SET); for (;;) { item = JS_IteratorNext(ctx, iter, next, 0, NULL, &done); if (JS_IsException(item)) goto exception; if (done) // item is JS_UNDEFINED break; // note the subtlety here: due to mutating iterators, it's // possible for keys to disappear during iteration; test262 // still expects us to maintain insertion order though, so // we first check |this|, then |new|; |new| is a copy of |this| // - if item exists in |this|, delete (if it exists) from |new| // - if item misses in |this| and |new|, add to |new| // - if item exists in |new| but misses in |this|, *don't* add it, // mutating iterator erased it item = map_normalize_key(ctx, item); present = (NULL != map_find_record(ctx, s, item)); mr = map_find_record(ctx, t, item); if (present) { map_delete_record(ctx, t, item); JS_FreeValue(ctx, item); } else if (mr) { JS_FreeValue(ctx, item); } else { mr = set_add_record(ctx, t, item); JS_FreeValue(ctx, item); if (!mr) goto exception; } } goto fini; exception: JS_FreeValue(ctx, newset); newset = JS_EXCEPTION; fini: JS_FreeValue(ctx, next); JS_FreeValue(ctx, iter); JS_FreeValue(ctx, keys); return newset; } static JSValue js_set_union(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue newset, item, iter, next, has, keys, rv; JSMapState *s; int64_t size; int done; s = JS_GetOpaque2(ctx, this_val, JS_CLASS_SET); if (!s) return JS_EXCEPTION; if (get_set_record(ctx, argv[0], &size, &has, &keys) < 0) return JS_EXCEPTION; JS_FreeValue(ctx, has); next = JS_UNDEFINED; newset = JS_UNDEFINED; iter = JS_Call(ctx, keys, argv[0], 0, NULL); if (JS_IsException(iter)) goto exception; next = JS_GetProperty(ctx, iter, JS_ATOM_next); if (JS_IsException(next)) goto exception; newset = js_copy_set(ctx, this_val); if (JS_IsException(newset)) goto exception; for (;;) { item = JS_IteratorNext(ctx, iter, next, 0, NULL, &done); if (JS_IsException(item)) goto exception; if (done) // item is JS_UNDEFINED break; rv = js_map_set(ctx, newset, 1, (JSValueConst *)&item, MAGIC_SET); JS_FreeValue(ctx, item); if (JS_IsException(rv)) goto exception; JS_FreeValue(ctx, rv); } goto fini; exception: JS_FreeValue(ctx, newset); newset = JS_EXCEPTION; fini: JS_FreeValue(ctx, next); JS_FreeValue(ctx, iter); JS_FreeValue(ctx, keys); return newset; } static const JSCFunctionListEntry js_map_funcs[] = { JS_CFUNC_MAGIC_DEF("groupBy", 2, js_object_groupBy, 1 ), JS_CGETSET_DEF("[Symbol.species]", js_get_this, NULL ), }; static const JSCFunctionListEntry js_map_proto_funcs[] = { JS_CFUNC_MAGIC_DEF("set", 2, js_map_set, 0 ), JS_CFUNC_MAGIC_DEF("get", 1, js_map_get, 0 ), JS_CFUNC_MAGIC_DEF("getOrInsert", 2, js_map_getOrInsert, (JS_CLASS_MAP << 1) | /*computed*/FALSE ), JS_CFUNC_MAGIC_DEF("getOrInsertComputed", 2, js_map_getOrInsert, (JS_CLASS_MAP << 1) | /*computed*/TRUE ), JS_CFUNC_MAGIC_DEF("has", 1, js_map_has, 0 ), JS_CFUNC_MAGIC_DEF("delete", 1, js_map_delete, 0 ), JS_CFUNC_MAGIC_DEF("clear", 0, js_map_clear, 0 ), JS_CGETSET_MAGIC_DEF("size", js_map_get_size, NULL, 0), JS_CFUNC_MAGIC_DEF("forEach", 1, js_map_forEach, 0 ), JS_CFUNC_MAGIC_DEF("values", 0, js_create_map_iterator, (JS_ITERATOR_KIND_VALUE << 2) | 0 ), JS_CFUNC_MAGIC_DEF("keys", 0, js_create_map_iterator, (JS_ITERATOR_KIND_KEY << 2) | 0 ), JS_CFUNC_MAGIC_DEF("entries", 0, js_create_map_iterator, (JS_ITERATOR_KIND_KEY_AND_VALUE << 2) | 0 ), JS_ALIAS_DEF("[Symbol.iterator]", "entries" ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Map", JS_PROP_CONFIGURABLE ), }; static const JSCFunctionListEntry js_map_iterator_proto_funcs[] = { JS_ITERATOR_NEXT_DEF("next", 0, js_map_iterator_next, 0 ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Map Iterator", JS_PROP_CONFIGURABLE ), }; static const JSCFunctionListEntry js_set_proto_funcs[] = { JS_CFUNC_MAGIC_DEF("add", 1, js_map_set, MAGIC_SET ), JS_CFUNC_MAGIC_DEF("has", 1, js_map_has, MAGIC_SET ), JS_CFUNC_MAGIC_DEF("delete", 1, js_map_delete, MAGIC_SET ), JS_CFUNC_MAGIC_DEF("clear", 0, js_map_clear, MAGIC_SET ), JS_CGETSET_MAGIC_DEF("size", js_map_get_size, NULL, MAGIC_SET ), JS_CFUNC_MAGIC_DEF("forEach", 1, js_map_forEach, MAGIC_SET ), JS_CFUNC_DEF("isDisjointFrom", 1, js_set_isDisjointFrom ), JS_CFUNC_DEF("isSubsetOf", 1, js_set_isSubsetOf ), JS_CFUNC_DEF("isSupersetOf", 1, js_set_isSupersetOf ), JS_CFUNC_DEF("intersection", 1, js_set_intersection ), JS_CFUNC_DEF("difference", 1, js_set_difference ), JS_CFUNC_DEF("symmetricDifference", 1, js_set_symmetricDifference ), JS_CFUNC_DEF("union", 1, js_set_union ), JS_CFUNC_MAGIC_DEF("values", 0, js_create_map_iterator, (JS_ITERATOR_KIND_KEY << 2) | MAGIC_SET ), JS_ALIAS_DEF("keys", "values" ), JS_ALIAS_DEF("[Symbol.iterator]", "values" ), JS_CFUNC_MAGIC_DEF("entries", 0, js_create_map_iterator, (JS_ITERATOR_KIND_KEY_AND_VALUE << 2) | MAGIC_SET ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Set", JS_PROP_CONFIGURABLE ), }; static const JSCFunctionListEntry js_set_iterator_proto_funcs[] = { JS_ITERATOR_NEXT_DEF("next", 0, js_map_iterator_next, MAGIC_SET ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Set Iterator", JS_PROP_CONFIGURABLE ), }; static const JSCFunctionListEntry js_weak_map_proto_funcs[] = { JS_CFUNC_MAGIC_DEF("set", 2, js_map_set, MAGIC_WEAK ), JS_CFUNC_MAGIC_DEF("get", 1, js_map_get, MAGIC_WEAK ), JS_CFUNC_MAGIC_DEF("getOrInsert", 2, js_map_getOrInsert, (JS_CLASS_WEAKMAP << 1) | /*computed*/FALSE ), JS_CFUNC_MAGIC_DEF("getOrInsertComputed", 2, js_map_getOrInsert, (JS_CLASS_WEAKMAP << 1) | /*computed*/TRUE ), JS_CFUNC_MAGIC_DEF("has", 1, js_map_has, MAGIC_WEAK ), JS_CFUNC_MAGIC_DEF("delete", 1, js_map_delete, MAGIC_WEAK ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "WeakMap", JS_PROP_CONFIGURABLE ), }; static const JSCFunctionListEntry js_weak_set_proto_funcs[] = { JS_CFUNC_MAGIC_DEF("add", 1, js_map_set, MAGIC_SET | MAGIC_WEAK ), JS_CFUNC_MAGIC_DEF("has", 1, js_map_has, MAGIC_SET | MAGIC_WEAK ), JS_CFUNC_MAGIC_DEF("delete", 1, js_map_delete, MAGIC_SET | MAGIC_WEAK ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "WeakSet", JS_PROP_CONFIGURABLE ), }; static const JSCFunctionListEntry * const js_map_proto_funcs_ptr[6] = { js_map_proto_funcs, js_set_proto_funcs, js_weak_map_proto_funcs, js_weak_set_proto_funcs, js_map_iterator_proto_funcs, js_set_iterator_proto_funcs, }; static const uint8_t js_map_proto_funcs_count[6] = { countof(js_map_proto_funcs), countof(js_set_proto_funcs), countof(js_weak_map_proto_funcs), countof(js_weak_set_proto_funcs), countof(js_map_iterator_proto_funcs), countof(js_set_iterator_proto_funcs), }; int JS_AddIntrinsicMapSet(JSContext *ctx) { int i; JSValue obj1; char buf[ATOM_GET_STR_BUF_SIZE]; for(i = 0; i < 4; i++) { JSCFunctionType ft; const char *name = JS_AtomGetStr(ctx, buf, sizeof(buf), JS_ATOM_Map + i); ft.constructor_magic = js_map_constructor; obj1 = JS_NewCConstructor(ctx, JS_CLASS_MAP + i, name, ft.generic, 0, JS_CFUNC_constructor_magic, i, JS_UNDEFINED, js_map_funcs, i < 2 ? countof(js_map_funcs) : 0, js_map_proto_funcs_ptr[i], js_map_proto_funcs_count[i], 0); if (JS_IsException(obj1)) return -1; JS_FreeValue(ctx, obj1); } for(i = 0; i < 2; i++) { ctx->class_proto[JS_CLASS_MAP_ITERATOR + i] = JS_NewObjectProtoList(ctx, ctx->class_proto[JS_CLASS_ITERATOR], js_map_proto_funcs_ptr[i + 4], js_map_proto_funcs_count[i + 4]); if (JS_IsException(ctx->class_proto[JS_CLASS_MAP_ITERATOR + i])) return -1; } return 0; } /* Generator */ static const JSCFunctionListEntry js_generator_function_proto_funcs[] = { JS_PROP_STRING_DEF("[Symbol.toStringTag]", "GeneratorFunction", JS_PROP_CONFIGURABLE), }; static const JSCFunctionListEntry js_generator_proto_funcs[] = { JS_ITERATOR_NEXT_DEF("next", 1, js_generator_next, GEN_MAGIC_NEXT ), JS_ITERATOR_NEXT_DEF("return", 1, js_generator_next, GEN_MAGIC_RETURN ), JS_ITERATOR_NEXT_DEF("throw", 1, js_generator_next, GEN_MAGIC_THROW ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Generator", JS_PROP_CONFIGURABLE), }; /* Promise */ typedef struct JSPromiseData { JSPromiseStateEnum promise_state; /* 0=fulfill, 1=reject, list of JSPromiseReactionData.link */ struct list_head promise_reactions[2]; BOOL is_handled; /* Note: only useful to debug */ JSValue promise_result; } JSPromiseData; typedef struct JSPromiseFunctionDataResolved { int ref_count; BOOL already_resolved; } JSPromiseFunctionDataResolved; typedef struct JSPromiseFunctionData { JSValue promise; JSPromiseFunctionDataResolved *presolved; } JSPromiseFunctionData; typedef struct JSPromiseReactionData { struct list_head link; /* not used in promise_reaction_job */ JSValue resolving_funcs[2]; JSValue handler; } JSPromiseReactionData; JSPromiseStateEnum JS_PromiseState(JSContext *ctx, JSValue promise) { JSPromiseData *s = JS_GetOpaque(promise, JS_CLASS_PROMISE); if (!s) return -1; return s->promise_state; } JSValue JS_PromiseResult(JSContext *ctx, JSValue promise) { JSPromiseData *s = JS_GetOpaque(promise, JS_CLASS_PROMISE); if (!s) return JS_UNDEFINED; return JS_DupValue(ctx, s->promise_result); } static int js_create_resolving_functions(JSContext *ctx, JSValue *args, JSValueConst promise); static void promise_reaction_data_free(JSRuntime *rt, JSPromiseReactionData *rd) { JS_FreeValueRT(rt, rd->resolving_funcs[0]); JS_FreeValueRT(rt, rd->resolving_funcs[1]); JS_FreeValueRT(rt, rd->handler); js_free_rt(rt, rd); } static JSValue promise_reaction_job(JSContext *ctx, int argc, JSValueConst *argv) { JSValueConst handler, arg, func; JSValue res, res2; BOOL is_reject; assert(argc == 5); handler = argv[2]; is_reject = JS_ToBool(ctx, argv[3]); arg = argv[4]; #ifdef DUMP_PROMISE printf("promise_reaction_job: is_reject=%d\n", is_reject); #endif if (JS_IsUndefined(handler)) { if (is_reject) { res = JS_Throw(ctx, JS_DupValue(ctx, arg)); } else { res = JS_DupValue(ctx, arg); } } else { res = JS_Call(ctx, handler, JS_UNDEFINED, 1, &arg); } is_reject = JS_IsException(res); if (is_reject) res = JS_GetException(ctx); func = argv[is_reject]; /* as an extension, we support undefined as value to avoid creating a dummy promise in the 'await' implementation of async functions */ if (!JS_IsUndefined(func)) { res2 = JS_Call(ctx, func, JS_UNDEFINED, 1, (JSValueConst *)&res); } else { res2 = JS_UNDEFINED; } JS_FreeValue(ctx, res); return res2; } void JS_SetHostPromiseRejectionTracker(JSRuntime *rt, JSHostPromiseRejectionTracker *cb, void *opaque) { rt->host_promise_rejection_tracker = cb; rt->host_promise_rejection_tracker_opaque = opaque; } static void fulfill_or_reject_promise(JSContext *ctx, JSValueConst promise, JSValueConst value, BOOL is_reject) { JSPromiseData *s = JS_GetOpaque(promise, JS_CLASS_PROMISE); struct list_head *el, *el1; JSPromiseReactionData *rd; JSValueConst args[5]; if (!s || s->promise_state != JS_PROMISE_PENDING) return; /* should never happen */ set_value(ctx, &s->promise_result, JS_DupValue(ctx, value)); s->promise_state = JS_PROMISE_FULFILLED + is_reject; #ifdef DUMP_PROMISE printf("fulfill_or_reject_promise: is_reject=%d\n", is_reject); #endif if (s->promise_state == JS_PROMISE_REJECTED && !s->is_handled) { JSRuntime *rt = ctx->rt; if (rt->host_promise_rejection_tracker) { rt->host_promise_rejection_tracker(ctx, promise, value, FALSE, rt->host_promise_rejection_tracker_opaque); } } list_for_each_safe(el, el1, &s->promise_reactions[is_reject]) { rd = list_entry(el, JSPromiseReactionData, link); args[0] = rd->resolving_funcs[0]; args[1] = rd->resolving_funcs[1]; args[2] = rd->handler; args[3] = JS_NewBool(ctx, is_reject); args[4] = value; JS_EnqueueJob(ctx, promise_reaction_job, 5, args); list_del(&rd->link); promise_reaction_data_free(ctx->rt, rd); } list_for_each_safe(el, el1, &s->promise_reactions[1 - is_reject]) { rd = list_entry(el, JSPromiseReactionData, link); list_del(&rd->link); promise_reaction_data_free(ctx->rt, rd); } } static void reject_promise(JSContext *ctx, JSValueConst promise, JSValueConst value) { fulfill_or_reject_promise(ctx, promise, value, TRUE); } static JSValue js_promise_resolve_thenable_job(JSContext *ctx, int argc, JSValueConst *argv) { JSValueConst promise, thenable, then; JSValue args[2], res; #ifdef DUMP_PROMISE printf("js_promise_resolve_thenable_job\n"); #endif assert(argc == 3); promise = argv[0]; thenable = argv[1]; then = argv[2]; if (js_create_resolving_functions(ctx, args, promise) < 0) return JS_EXCEPTION; res = JS_Call(ctx, then, thenable, 2, (JSValueConst *)args); if (JS_IsException(res)) { JSValue error = JS_GetException(ctx); res = JS_Call(ctx, args[1], JS_UNDEFINED, 1, (JSValueConst *)&error); JS_FreeValue(ctx, error); } JS_FreeValue(ctx, args[0]); JS_FreeValue(ctx, args[1]); return res; } static void js_promise_resolve_function_free_resolved(JSRuntime *rt, JSPromiseFunctionDataResolved *sr) { if (--sr->ref_count == 0) { js_free_rt(rt, sr); } } static int js_create_resolving_functions(JSContext *ctx, JSValue *resolving_funcs, JSValueConst promise) { JSValue obj; JSPromiseFunctionData *s; JSPromiseFunctionDataResolved *sr; int i, ret; sr = js_malloc(ctx, sizeof(*sr)); if (!sr) return -1; sr->ref_count = 1; sr->already_resolved = FALSE; /* must be shared between the two functions */ ret = 0; for(i = 0; i < 2; i++) { obj = JS_NewObjectProtoClass(ctx, ctx->function_proto, JS_CLASS_PROMISE_RESOLVE_FUNCTION + i); if (JS_IsException(obj)) goto fail; s = js_malloc(ctx, sizeof(*s)); if (!s) { JS_FreeValue(ctx, obj); fail: if (i != 0) JS_FreeValue(ctx, resolving_funcs[0]); ret = -1; break; } sr->ref_count++; s->presolved = sr; s->promise = JS_DupValue(ctx, promise); JS_SetOpaque(obj, s); js_function_set_properties(ctx, obj, JS_ATOM_empty_string, 1); resolving_funcs[i] = obj; } js_promise_resolve_function_free_resolved(ctx->rt, sr); return ret; } static void js_promise_resolve_function_finalizer(JSRuntime *rt, JSValue val) { JSPromiseFunctionData *s = JS_VALUE_GET_OBJ(val)->u.promise_function_data; if (s) { js_promise_resolve_function_free_resolved(rt, s->presolved); JS_FreeValueRT(rt, s->promise); js_free_rt(rt, s); } } static void js_promise_resolve_function_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSPromiseFunctionData *s = JS_VALUE_GET_OBJ(val)->u.promise_function_data; if (s) { JS_MarkValue(rt, s->promise, mark_func); } } static JSValue js_promise_resolve_function_call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_val, int argc, JSValueConst *argv, int flags) { JSObject *p = JS_VALUE_GET_OBJ(func_obj); JSPromiseFunctionData *s; JSValueConst resolution, args[3]; JSValue then; BOOL is_reject; s = p->u.promise_function_data; if (!s || s->presolved->already_resolved) return JS_UNDEFINED; s->presolved->already_resolved = TRUE; is_reject = p->class_id - JS_CLASS_PROMISE_RESOLVE_FUNCTION; if (argc > 0) resolution = argv[0]; else resolution = JS_UNDEFINED; #ifdef DUMP_PROMISE printf("js_promise_resolving_function_call: is_reject=%d ", is_reject); JS_DumpValue(ctx, "resolution", resolution); printf("\n"); #endif if (is_reject || !JS_IsObject(resolution)) { goto done; } else if (js_same_value(ctx, resolution, s->promise)) { JS_ThrowTypeError(ctx, "promise self resolution"); goto fail_reject; } then = JS_GetProperty(ctx, resolution, JS_ATOM_then); if (JS_IsException(then)) { JSValue error; fail_reject: error = JS_GetException(ctx); reject_promise(ctx, s->promise, error); JS_FreeValue(ctx, error); } else if (!JS_IsFunction(ctx, then)) { JS_FreeValue(ctx, then); done: fulfill_or_reject_promise(ctx, s->promise, resolution, is_reject); } else { args[0] = s->promise; args[1] = resolution; args[2] = then; JS_EnqueueJob(ctx, js_promise_resolve_thenable_job, 3, args); JS_FreeValue(ctx, then); } return JS_UNDEFINED; } static void js_promise_finalizer(JSRuntime *rt, JSValue val) { JSPromiseData *s = JS_GetOpaque(val, JS_CLASS_PROMISE); struct list_head *el, *el1; int i; if (!s) return; for(i = 0; i < 2; i++) { list_for_each_safe(el, el1, &s->promise_reactions[i]) { JSPromiseReactionData *rd = list_entry(el, JSPromiseReactionData, link); promise_reaction_data_free(rt, rd); } } JS_FreeValueRT(rt, s->promise_result); js_free_rt(rt, s); } static void js_promise_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSPromiseData *s = JS_GetOpaque(val, JS_CLASS_PROMISE); struct list_head *el; int i; if (!s) return; for(i = 0; i < 2; i++) { list_for_each(el, &s->promise_reactions[i]) { JSPromiseReactionData *rd = list_entry(el, JSPromiseReactionData, link); JS_MarkValue(rt, rd->resolving_funcs[0], mark_func); JS_MarkValue(rt, rd->resolving_funcs[1], mark_func); JS_MarkValue(rt, rd->handler, mark_func); } } JS_MarkValue(rt, s->promise_result, mark_func); } static JSValue js_promise_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { JSValueConst executor; JSValue obj; JSPromiseData *s; JSValue args[2], ret; int i; executor = argv[0]; if (check_function(ctx, executor)) return JS_EXCEPTION; obj = js_create_from_ctor(ctx, new_target, JS_CLASS_PROMISE); if (JS_IsException(obj)) return JS_EXCEPTION; s = js_mallocz(ctx, sizeof(*s)); if (!s) goto fail; s->promise_state = JS_PROMISE_PENDING; s->is_handled = FALSE; for(i = 0; i < 2; i++) init_list_head(&s->promise_reactions[i]); s->promise_result = JS_UNDEFINED; JS_SetOpaque(obj, s); if (js_create_resolving_functions(ctx, args, obj)) goto fail; ret = JS_Call(ctx, executor, JS_UNDEFINED, 2, (JSValueConst *)args); if (JS_IsException(ret)) { JSValue ret2, error; error = JS_GetException(ctx); ret2 = JS_Call(ctx, args[1], JS_UNDEFINED, 1, (JSValueConst *)&error); JS_FreeValue(ctx, error); if (JS_IsException(ret2)) goto fail1; JS_FreeValue(ctx, ret2); } JS_FreeValue(ctx, ret); JS_FreeValue(ctx, args[0]); JS_FreeValue(ctx, args[1]); return obj; fail1: JS_FreeValue(ctx, args[0]); JS_FreeValue(ctx, args[1]); fail: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_promise_executor(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data) { int i; for(i = 0; i < 2; i++) { if (!JS_IsUndefined(func_data[i])) return JS_ThrowTypeError(ctx, "resolving function already set"); func_data[i] = JS_DupValue(ctx, argv[i]); } return JS_UNDEFINED; } static JSValue js_promise_executor_new(JSContext *ctx) { JSValueConst func_data[2]; func_data[0] = JS_UNDEFINED; func_data[1] = JS_UNDEFINED; return JS_NewCFunctionData(ctx, js_promise_executor, 2, 0, 2, func_data); } static JSValue js_new_promise_capability(JSContext *ctx, JSValue *resolving_funcs, JSValueConst ctor) { JSValue executor, result_promise; JSCFunctionDataRecord *s; int i; executor = js_promise_executor_new(ctx); if (JS_IsException(executor)) return executor; if (JS_IsUndefined(ctor)) { result_promise = js_promise_constructor(ctx, ctor, 1, (JSValueConst *)&executor); } else { result_promise = JS_CallConstructor(ctx, ctor, 1, (JSValueConst *)&executor); } if (JS_IsException(result_promise)) goto fail; s = JS_GetOpaque(executor, JS_CLASS_C_FUNCTION_DATA); for(i = 0; i < 2; i++) { if (check_function(ctx, s->data[i])) goto fail; } for(i = 0; i < 2; i++) resolving_funcs[i] = JS_DupValue(ctx, s->data[i]); JS_FreeValue(ctx, executor); return result_promise; fail: JS_FreeValue(ctx, executor); JS_FreeValue(ctx, result_promise); return JS_EXCEPTION; } JSValue JS_NewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs) { return js_new_promise_capability(ctx, resolving_funcs, JS_UNDEFINED); } static JSValue js_promise_resolve(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSValue result_promise, resolving_funcs[2], ret; BOOL is_reject = magic; if (!JS_IsObject(this_val)) return JS_ThrowTypeErrorNotAnObject(ctx); if (!is_reject && JS_GetOpaque(argv[0], JS_CLASS_PROMISE)) { JSValue ctor; BOOL is_same; ctor = JS_GetProperty(ctx, argv[0], JS_ATOM_constructor); if (JS_IsException(ctor)) return ctor; is_same = js_same_value(ctx, ctor, this_val); JS_FreeValue(ctx, ctor); if (is_same) return JS_DupValue(ctx, argv[0]); } result_promise = js_new_promise_capability(ctx, resolving_funcs, this_val); if (JS_IsException(result_promise)) return result_promise; ret = JS_Call(ctx, resolving_funcs[is_reject], JS_UNDEFINED, 1, argv); JS_FreeValue(ctx, resolving_funcs[0]); JS_FreeValue(ctx, resolving_funcs[1]); if (JS_IsException(ret)) { JS_FreeValue(ctx, result_promise); return ret; } JS_FreeValue(ctx, ret); return result_promise; } static JSValue js_promise_withResolvers(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue result_promise, resolving_funcs[2], obj; if (!JS_IsObject(this_val)) return JS_ThrowTypeErrorNotAnObject(ctx); result_promise = js_new_promise_capability(ctx, resolving_funcs, this_val); if (JS_IsException(result_promise)) return result_promise; obj = JS_NewObject(ctx); if (JS_IsException(obj)) goto exception; if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_promise, result_promise, JS_PROP_C_W_E) < 0) { goto exception; } result_promise = JS_UNDEFINED; if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_resolve, resolving_funcs[0], JS_PROP_C_W_E) < 0) { goto exception; } resolving_funcs[0] = JS_UNDEFINED; if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_reject, resolving_funcs[1], JS_PROP_C_W_E) < 0) { goto exception; } return obj; exception: JS_FreeValue(ctx, resolving_funcs[0]); JS_FreeValue(ctx, resolving_funcs[1]); JS_FreeValue(ctx, result_promise); JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_promise_try(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue result_promise, resolving_funcs[2], ret, ret2; BOOL is_reject = 0; if (!JS_IsObject(this_val)) return JS_ThrowTypeErrorNotAnObject(ctx); result_promise = js_new_promise_capability(ctx, resolving_funcs, this_val); if (JS_IsException(result_promise)) return result_promise; ret = JS_Call(ctx, argv[0], JS_UNDEFINED, argc - 1, argv + 1); if (JS_IsException(ret)) { is_reject = 1; ret = JS_GetException(ctx); } ret2 = JS_Call(ctx, resolving_funcs[is_reject], JS_UNDEFINED, 1, (JSValueConst *)&ret); JS_FreeValue(ctx, resolving_funcs[0]); JS_FreeValue(ctx, resolving_funcs[1]); JS_FreeValue(ctx, ret); if (JS_IsException(ret2)) { JS_FreeValue(ctx, result_promise); return ret2; } JS_FreeValue(ctx, ret2); return result_promise; } static __exception int remainingElementsCount_add(JSContext *ctx, JSValueConst resolve_element_env, int addend) { JSValue val; int remainingElementsCount; val = JS_GetPropertyUint32(ctx, resolve_element_env, 0); if (JS_IsException(val)) return -1; if (JS_ToInt32Free(ctx, &remainingElementsCount, val)) return -1; remainingElementsCount += addend; if (JS_SetPropertyUint32(ctx, resolve_element_env, 0, JS_NewInt32(ctx, remainingElementsCount)) < 0) return -1; return (remainingElementsCount == 0); } #define PROMISE_MAGIC_all 0 #define PROMISE_MAGIC_allSettled 1 #define PROMISE_MAGIC_any 2 static JSValue js_promise_all_resolve_element(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data) { int resolve_type = magic & 3; int is_reject = magic & 4; BOOL alreadyCalled = JS_ToBool(ctx, func_data[0]); JSValueConst values = func_data[2]; JSValueConst resolve = func_data[3]; JSValueConst resolve_element_env = func_data[4]; JSValue ret, obj; int is_zero, index; if (JS_ToInt32(ctx, &index, func_data[1])) return JS_EXCEPTION; if (alreadyCalled) return JS_UNDEFINED; func_data[0] = JS_NewBool(ctx, TRUE); if (resolve_type == PROMISE_MAGIC_allSettled) { JSValue str; obj = JS_NewObject(ctx); if (JS_IsException(obj)) return JS_EXCEPTION; str = js_new_string8(ctx, is_reject ? "rejected" : "fulfilled"); if (JS_IsException(str)) goto fail1; if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_status, str, JS_PROP_C_W_E) < 0) goto fail1; if (JS_DefinePropertyValue(ctx, obj, is_reject ? JS_ATOM_reason : JS_ATOM_value, JS_DupValue(ctx, argv[0]), JS_PROP_C_W_E) < 0) { fail1: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } } else { obj = JS_DupValue(ctx, argv[0]); } if (JS_DefinePropertyValueUint32(ctx, values, index, obj, JS_PROP_C_W_E) < 0) return JS_EXCEPTION; is_zero = remainingElementsCount_add(ctx, resolve_element_env, -1); if (is_zero < 0) return JS_EXCEPTION; if (is_zero) { if (resolve_type == PROMISE_MAGIC_any) { JSValue error; error = js_aggregate_error_constructor(ctx, values); if (JS_IsException(error)) return JS_EXCEPTION; ret = JS_Call(ctx, resolve, JS_UNDEFINED, 1, (JSValueConst *)&error); JS_FreeValue(ctx, error); } else { ret = JS_Call(ctx, resolve, JS_UNDEFINED, 1, (JSValueConst *)&values); } if (JS_IsException(ret)) return ret; JS_FreeValue(ctx, ret); } return JS_UNDEFINED; } /* magic = 0: Promise.all 1: Promise.allSettled */ static JSValue js_promise_all(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSValue result_promise, resolving_funcs[2], item, next_promise, ret; JSValue next_method = JS_UNDEFINED, values = JS_UNDEFINED; JSValue resolve_element_env = JS_UNDEFINED, resolve_element, reject_element; JSValue promise_resolve = JS_UNDEFINED, iter = JS_UNDEFINED; JSValueConst then_args[2], resolve_element_data[5]; BOOL done; int index, is_zero, is_promise_any = (magic == PROMISE_MAGIC_any); if (!JS_IsObject(this_val)) return JS_ThrowTypeErrorNotAnObject(ctx); result_promise = js_new_promise_capability(ctx, resolving_funcs, this_val); if (JS_IsException(result_promise)) return result_promise; promise_resolve = JS_GetProperty(ctx, this_val, JS_ATOM_resolve); if (JS_IsException(promise_resolve) || check_function(ctx, promise_resolve)) goto fail_reject; iter = JS_GetIterator(ctx, argv[0], FALSE); if (JS_IsException(iter)) { JSValue error; fail_reject: error = JS_GetException(ctx); ret = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, 1, (JSValueConst *)&error); JS_FreeValue(ctx, error); if (JS_IsException(ret)) goto fail; JS_FreeValue(ctx, ret); } else { next_method = JS_GetProperty(ctx, iter, JS_ATOM_next); if (JS_IsException(next_method)) goto fail_reject; values = JS_NewArray(ctx); if (JS_IsException(values)) goto fail_reject; resolve_element_env = JS_NewArray(ctx); if (JS_IsException(resolve_element_env)) goto fail_reject; /* remainingElementsCount field */ if (JS_DefinePropertyValueUint32(ctx, resolve_element_env, 0, JS_NewInt32(ctx, 1), JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE | JS_PROP_WRITABLE) < 0) goto fail_reject; index = 0; for(;;) { /* XXX: conformance: should close the iterator if error on 'done' access, but not on 'value' access */ item = JS_IteratorNext(ctx, iter, next_method, 0, NULL, &done); if (JS_IsException(item)) goto fail_reject; if (done) break; next_promise = JS_Call(ctx, promise_resolve, this_val, 1, (JSValueConst *)&item); JS_FreeValue(ctx, item); if (JS_IsException(next_promise)) { fail_reject1: JS_IteratorClose(ctx, iter, TRUE); goto fail_reject; } resolve_element_data[0] = JS_NewBool(ctx, FALSE); resolve_element_data[1] = (JSValueConst)JS_NewInt32(ctx, index); resolve_element_data[2] = values; resolve_element_data[3] = resolving_funcs[is_promise_any]; resolve_element_data[4] = resolve_element_env; resolve_element = JS_NewCFunctionData(ctx, js_promise_all_resolve_element, 1, magic, 5, resolve_element_data); if (JS_IsException(resolve_element)) { JS_FreeValue(ctx, next_promise); goto fail_reject1; } if (magic == PROMISE_MAGIC_allSettled) { reject_element = JS_NewCFunctionData(ctx, js_promise_all_resolve_element, 1, magic | 4, 5, resolve_element_data); if (JS_IsException(reject_element)) { JS_FreeValue(ctx, next_promise); goto fail_reject1; } } else if (magic == PROMISE_MAGIC_any) { if (JS_DefinePropertyValueUint32(ctx, values, index, JS_UNDEFINED, JS_PROP_C_W_E) < 0) goto fail_reject1; reject_element = resolve_element; resolve_element = JS_DupValue(ctx, resolving_funcs[0]); } else { reject_element = JS_DupValue(ctx, resolving_funcs[1]); } if (remainingElementsCount_add(ctx, resolve_element_env, 1) < 0) { JS_FreeValue(ctx, next_promise); JS_FreeValue(ctx, resolve_element); JS_FreeValue(ctx, reject_element); goto fail_reject1; } then_args[0] = resolve_element; then_args[1] = reject_element; ret = JS_InvokeFree(ctx, next_promise, JS_ATOM_then, 2, then_args); JS_FreeValue(ctx, resolve_element); JS_FreeValue(ctx, reject_element); if (check_exception_free(ctx, ret)) goto fail_reject1; index++; } is_zero = remainingElementsCount_add(ctx, resolve_element_env, -1); if (is_zero < 0) goto fail_reject; if (is_zero) { if (magic == PROMISE_MAGIC_any) { JSValue error; error = js_aggregate_error_constructor(ctx, values); if (JS_IsException(error)) goto fail_reject; JS_FreeValue(ctx, values); values = error; } ret = JS_Call(ctx, resolving_funcs[is_promise_any], JS_UNDEFINED, 1, (JSValueConst *)&values); if (check_exception_free(ctx, ret)) goto fail_reject; } } done: JS_FreeValue(ctx, promise_resolve); JS_FreeValue(ctx, resolve_element_env); JS_FreeValue(ctx, values); JS_FreeValue(ctx, next_method); JS_FreeValue(ctx, iter); JS_FreeValue(ctx, resolving_funcs[0]); JS_FreeValue(ctx, resolving_funcs[1]); return result_promise; fail: JS_FreeValue(ctx, result_promise); result_promise = JS_EXCEPTION; goto done; } static JSValue js_promise_race(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue result_promise, resolving_funcs[2], item, next_promise, ret; JSValue next_method = JS_UNDEFINED, iter = JS_UNDEFINED; JSValue promise_resolve = JS_UNDEFINED; BOOL done; if (!JS_IsObject(this_val)) return JS_ThrowTypeErrorNotAnObject(ctx); result_promise = js_new_promise_capability(ctx, resolving_funcs, this_val); if (JS_IsException(result_promise)) return result_promise; promise_resolve = JS_GetProperty(ctx, this_val, JS_ATOM_resolve); if (JS_IsException(promise_resolve) || check_function(ctx, promise_resolve)) goto fail_reject; iter = JS_GetIterator(ctx, argv[0], FALSE); if (JS_IsException(iter)) { JSValue error; fail_reject: error = JS_GetException(ctx); ret = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, 1, (JSValueConst *)&error); JS_FreeValue(ctx, error); if (JS_IsException(ret)) goto fail; JS_FreeValue(ctx, ret); } else { next_method = JS_GetProperty(ctx, iter, JS_ATOM_next); if (JS_IsException(next_method)) goto fail_reject; for(;;) { /* XXX: conformance: should close the iterator if error on 'done' access, but not on 'value' access */ item = JS_IteratorNext(ctx, iter, next_method, 0, NULL, &done); if (JS_IsException(item)) goto fail_reject; if (done) break; next_promise = JS_Call(ctx, promise_resolve, this_val, 1, (JSValueConst *)&item); JS_FreeValue(ctx, item); if (JS_IsException(next_promise)) { fail_reject1: JS_IteratorClose(ctx, iter, TRUE); goto fail_reject; } ret = JS_InvokeFree(ctx, next_promise, JS_ATOM_then, 2, (JSValueConst *)resolving_funcs); if (check_exception_free(ctx, ret)) goto fail_reject1; } } done: JS_FreeValue(ctx, promise_resolve); JS_FreeValue(ctx, next_method); JS_FreeValue(ctx, iter); JS_FreeValue(ctx, resolving_funcs[0]); JS_FreeValue(ctx, resolving_funcs[1]); return result_promise; fail: //JS_FreeValue(ctx, next_method); // why not??? JS_FreeValue(ctx, result_promise); result_promise = JS_EXCEPTION; goto done; } static __exception int perform_promise_then(JSContext *ctx, JSValueConst promise, JSValueConst *resolve_reject, JSValueConst *cap_resolving_funcs) { JSPromiseData *s = JS_GetOpaque(promise, JS_CLASS_PROMISE); JSPromiseReactionData *rd_array[2], *rd; int i, j; rd_array[0] = NULL; rd_array[1] = NULL; for(i = 0; i < 2; i++) { JSValueConst handler; rd = js_mallocz(ctx, sizeof(*rd)); if (!rd) { if (i == 1) promise_reaction_data_free(ctx->rt, rd_array[0]); return -1; } for(j = 0; j < 2; j++) rd->resolving_funcs[j] = JS_DupValue(ctx, cap_resolving_funcs[j]); handler = resolve_reject[i]; if (!JS_IsFunction(ctx, handler)) handler = JS_UNDEFINED; rd->handler = JS_DupValue(ctx, handler); rd_array[i] = rd; } if (s->promise_state == JS_PROMISE_PENDING) { for(i = 0; i < 2; i++) list_add_tail(&rd_array[i]->link, &s->promise_reactions[i]); } else { JSValueConst args[5]; if (s->promise_state == JS_PROMISE_REJECTED && !s->is_handled) { JSRuntime *rt = ctx->rt; if (rt->host_promise_rejection_tracker) { rt->host_promise_rejection_tracker(ctx, promise, s->promise_result, TRUE, rt->host_promise_rejection_tracker_opaque); } } i = s->promise_state - JS_PROMISE_FULFILLED; rd = rd_array[i]; args[0] = rd->resolving_funcs[0]; args[1] = rd->resolving_funcs[1]; args[2] = rd->handler; args[3] = JS_NewBool(ctx, i); args[4] = s->promise_result; JS_EnqueueJob(ctx, promise_reaction_job, 5, args); for(i = 0; i < 2; i++) promise_reaction_data_free(ctx->rt, rd_array[i]); } s->is_handled = TRUE; return 0; } static JSValue js_promise_then(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue ctor, result_promise, resolving_funcs[2]; JSPromiseData *s; int i, ret; s = JS_GetOpaque2(ctx, this_val, JS_CLASS_PROMISE); if (!s) return JS_EXCEPTION; ctor = JS_SpeciesConstructor(ctx, this_val, JS_UNDEFINED); if (JS_IsException(ctor)) return ctor; result_promise = js_new_promise_capability(ctx, resolving_funcs, ctor); JS_FreeValue(ctx, ctor); if (JS_IsException(result_promise)) return result_promise; ret = perform_promise_then(ctx, this_val, argv, (JSValueConst *)resolving_funcs); for(i = 0; i < 2; i++) JS_FreeValue(ctx, resolving_funcs[i]); if (ret) { JS_FreeValue(ctx, result_promise); return JS_EXCEPTION; } return result_promise; } static JSValue js_promise_catch(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValueConst args[2]; args[0] = JS_UNDEFINED; args[1] = argv[0]; return JS_Invoke(ctx, this_val, JS_ATOM_then, 2, args); } static JSValue js_promise_finally_value_thunk(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data) { return JS_DupValue(ctx, func_data[0]); } static JSValue js_promise_finally_thrower(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data) { return JS_Throw(ctx, JS_DupValue(ctx, func_data[0])); } static JSValue js_promise_then_finally_func(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data) { JSValueConst ctor = func_data[0]; JSValueConst onFinally = func_data[1]; JSValue res, promise, ret, then_func; res = JS_Call(ctx, onFinally, JS_UNDEFINED, 0, NULL); if (JS_IsException(res)) return res; promise = js_promise_resolve(ctx, ctor, 1, (JSValueConst *)&res, 0); JS_FreeValue(ctx, res); if (JS_IsException(promise)) return promise; if (magic == 0) { then_func = JS_NewCFunctionData(ctx, js_promise_finally_value_thunk, 0, 0, 1, argv); } else { then_func = JS_NewCFunctionData(ctx, js_promise_finally_thrower, 0, 0, 1, argv); } if (JS_IsException(then_func)) { JS_FreeValue(ctx, promise); return then_func; } ret = JS_InvokeFree(ctx, promise, JS_ATOM_then, 1, (JSValueConst *)&then_func); JS_FreeValue(ctx, then_func); return ret; } static JSValue js_promise_finally(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValueConst onFinally = argv[0]; JSValue ctor, ret; JSValue then_funcs[2]; JSValueConst func_data[2]; int i; ctor = JS_SpeciesConstructor(ctx, this_val, JS_UNDEFINED); if (JS_IsException(ctor)) return ctor; if (!JS_IsFunction(ctx, onFinally)) { then_funcs[0] = JS_DupValue(ctx, onFinally); then_funcs[1] = JS_DupValue(ctx, onFinally); } else { func_data[0] = ctor; func_data[1] = onFinally; for(i = 0; i < 2; i++) { then_funcs[i] = JS_NewCFunctionData(ctx, js_promise_then_finally_func, 1, i, 2, func_data); if (JS_IsException(then_funcs[i])) { if (i == 1) JS_FreeValue(ctx, then_funcs[0]); JS_FreeValue(ctx, ctor); return JS_EXCEPTION; } } } JS_FreeValue(ctx, ctor); ret = JS_Invoke(ctx, this_val, JS_ATOM_then, 2, (JSValueConst *)then_funcs); JS_FreeValue(ctx, then_funcs[0]); JS_FreeValue(ctx, then_funcs[1]); return ret; } static const JSCFunctionListEntry js_promise_funcs[] = { JS_CFUNC_MAGIC_DEF("resolve", 1, js_promise_resolve, 0 ), JS_CFUNC_MAGIC_DEF("reject", 1, js_promise_resolve, 1 ), JS_CFUNC_MAGIC_DEF("all", 1, js_promise_all, PROMISE_MAGIC_all ), JS_CFUNC_MAGIC_DEF("allSettled", 1, js_promise_all, PROMISE_MAGIC_allSettled ), JS_CFUNC_MAGIC_DEF("any", 1, js_promise_all, PROMISE_MAGIC_any ), JS_CFUNC_DEF("try", 1, js_promise_try ), JS_CFUNC_DEF("race", 1, js_promise_race ), JS_CFUNC_DEF("withResolvers", 0, js_promise_withResolvers ), JS_CGETSET_DEF("[Symbol.species]", js_get_this, NULL), }; static const JSCFunctionListEntry js_promise_proto_funcs[] = { JS_CFUNC_DEF("then", 2, js_promise_then ), JS_CFUNC_DEF("catch", 1, js_promise_catch ), JS_CFUNC_DEF("finally", 1, js_promise_finally ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Promise", JS_PROP_CONFIGURABLE ), }; /* AsyncFunction */ static const JSCFunctionListEntry js_async_function_proto_funcs[] = { JS_PROP_STRING_DEF("[Symbol.toStringTag]", "AsyncFunction", JS_PROP_CONFIGURABLE ), }; /* AsyncIteratorPrototype */ static const JSCFunctionListEntry js_async_iterator_proto_funcs[] = { JS_CFUNC_DEF("[Symbol.asyncIterator]", 0, js_iterator_proto_iterator ), }; /* AsyncFromSyncIteratorPrototype */ typedef struct JSAsyncFromSyncIteratorData { JSValue sync_iter; JSValue next_method; } JSAsyncFromSyncIteratorData; static void js_async_from_sync_iterator_finalizer(JSRuntime *rt, JSValue val) { JSAsyncFromSyncIteratorData *s = JS_GetOpaque(val, JS_CLASS_ASYNC_FROM_SYNC_ITERATOR); if (s) { JS_FreeValueRT(rt, s->sync_iter); JS_FreeValueRT(rt, s->next_method); js_free_rt(rt, s); } } static void js_async_from_sync_iterator_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSAsyncFromSyncIteratorData *s = JS_GetOpaque(val, JS_CLASS_ASYNC_FROM_SYNC_ITERATOR); if (s) { JS_MarkValue(rt, s->sync_iter, mark_func); JS_MarkValue(rt, s->next_method, mark_func); } } static JSValue JS_CreateAsyncFromSyncIterator(JSContext *ctx, JSValueConst sync_iter) { JSValue async_iter, next_method; JSAsyncFromSyncIteratorData *s; next_method = JS_GetProperty(ctx, sync_iter, JS_ATOM_next); if (JS_IsException(next_method)) return JS_EXCEPTION; async_iter = JS_NewObjectClass(ctx, JS_CLASS_ASYNC_FROM_SYNC_ITERATOR); if (JS_IsException(async_iter)) { JS_FreeValue(ctx, next_method); return async_iter; } s = js_mallocz(ctx, sizeof(*s)); if (!s) { JS_FreeValue(ctx, async_iter); JS_FreeValue(ctx, next_method); return JS_EXCEPTION; } s->sync_iter = JS_DupValue(ctx, sync_iter); s->next_method = next_method; JS_SetOpaque(async_iter, s); return async_iter; } static JSValue js_async_from_sync_iterator_unwrap(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data) { return js_create_iterator_result(ctx, JS_DupValue(ctx, argv[0]), JS_ToBool(ctx, func_data[0])); } static JSValue js_async_from_sync_iterator_unwrap_func_create(JSContext *ctx, BOOL done) { JSValueConst func_data[1]; func_data[0] = (JSValueConst)JS_NewBool(ctx, done); return JS_NewCFunctionData(ctx, js_async_from_sync_iterator_unwrap, 1, 0, 1, func_data); } static JSValue js_async_from_sync_iterator_close_wrap(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data) { JS_Throw(ctx, JS_DupValue(ctx, argv[0])); JS_IteratorClose(ctx, func_data[0], TRUE); return JS_EXCEPTION; } static JSValue js_async_from_sync_iterator_close_wrap_func_create(JSContext *ctx, JSValueConst sync_iter) { return JS_NewCFunctionData(ctx, js_async_from_sync_iterator_close_wrap, 1, 0, 1, &sync_iter); } static JSValue js_async_from_sync_iterator_next(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { JSValue promise, resolving_funcs[2], value, err, method; JSAsyncFromSyncIteratorData *s; int done; int is_reject; promise = JS_NewPromiseCapability(ctx, resolving_funcs); if (JS_IsException(promise)) return JS_EXCEPTION; s = JS_GetOpaque(this_val, JS_CLASS_ASYNC_FROM_SYNC_ITERATOR); if (!s) { JS_ThrowTypeError(ctx, "not an Async-from-Sync Iterator"); goto reject; } if (magic == GEN_MAGIC_NEXT) { method = JS_DupValue(ctx, s->next_method); } else { method = JS_GetProperty(ctx, s->sync_iter, magic == GEN_MAGIC_RETURN ? JS_ATOM_return : JS_ATOM_throw); if (JS_IsException(method)) goto reject; if (JS_IsUndefined(method) || JS_IsNull(method)) { if (magic == GEN_MAGIC_RETURN) { err = js_create_iterator_result(ctx, JS_DupValue(ctx, argv[0]), TRUE); is_reject = 0; goto done_resolve; } else { if (JS_IteratorClose(ctx, s->sync_iter, FALSE)) goto reject; JS_ThrowTypeError(ctx, "throw is not a method"); goto reject; } } } value = JS_IteratorNext2(ctx, s->sync_iter, method, argc >= 1 ? 1 : 0, argv, &done); JS_FreeValue(ctx, method); if (JS_IsException(value)) goto reject; if (done == 2) { JSValue obj = value; value = JS_IteratorGetCompleteValue(ctx, obj, &done); JS_FreeValue(ctx, obj); if (JS_IsException(value)) goto reject; } if (JS_IsException(value)) goto reject; { JSValue value_wrapper_promise, resolve_reject[2]; int res; value_wrapper_promise = js_promise_resolve(ctx, ctx->promise_ctor, 1, (JSValueConst *)&value, 0); if (JS_IsException(value_wrapper_promise)) { JSValue res2; JS_FreeValue(ctx, value); if (magic != GEN_MAGIC_RETURN && !done) { JS_IteratorClose(ctx, s->sync_iter, TRUE); } reject: err = JS_GetException(ctx); is_reject = 1; done_resolve: res2 = JS_Call(ctx, resolving_funcs[is_reject], JS_UNDEFINED, 1, (JSValueConst *)&err); JS_FreeValue(ctx, err); JS_FreeValue(ctx, res2); JS_FreeValue(ctx, resolving_funcs[0]); JS_FreeValue(ctx, resolving_funcs[1]); return promise; } resolve_reject[0] = js_async_from_sync_iterator_unwrap_func_create(ctx, done); if (JS_IsException(resolve_reject[0])) { JS_FreeValue(ctx, value_wrapper_promise); goto fail; } if (done || magic == GEN_MAGIC_RETURN) { resolve_reject[1] = JS_UNDEFINED; } else { resolve_reject[1] = js_async_from_sync_iterator_close_wrap_func_create(ctx, s->sync_iter); if (JS_IsException(resolve_reject[1])) { JS_FreeValue(ctx, value_wrapper_promise); JS_FreeValue(ctx, resolve_reject[0]); goto fail; } } JS_FreeValue(ctx, value); res = perform_promise_then(ctx, value_wrapper_promise, (JSValueConst *)resolve_reject, (JSValueConst *)resolving_funcs); JS_FreeValue(ctx, resolve_reject[0]); JS_FreeValue(ctx, resolve_reject[1]); JS_FreeValue(ctx, value_wrapper_promise); JS_FreeValue(ctx, resolving_funcs[0]); JS_FreeValue(ctx, resolving_funcs[1]); if (res) { JS_FreeValue(ctx, promise); return JS_EXCEPTION; } } return promise; fail: JS_FreeValue(ctx, value); JS_FreeValue(ctx, resolving_funcs[0]); JS_FreeValue(ctx, resolving_funcs[1]); JS_FreeValue(ctx, promise); return JS_EXCEPTION; } static const JSCFunctionListEntry js_async_from_sync_iterator_proto_funcs[] = { JS_CFUNC_MAGIC_DEF("next", 1, js_async_from_sync_iterator_next, GEN_MAGIC_NEXT ), JS_CFUNC_MAGIC_DEF("return", 1, js_async_from_sync_iterator_next, GEN_MAGIC_RETURN ), JS_CFUNC_MAGIC_DEF("throw", 1, js_async_from_sync_iterator_next, GEN_MAGIC_THROW ), }; /* AsyncGeneratorFunction */ static const JSCFunctionListEntry js_async_generator_function_proto_funcs[] = { JS_PROP_STRING_DEF("[Symbol.toStringTag]", "AsyncGeneratorFunction", JS_PROP_CONFIGURABLE ), }; /* AsyncGenerator prototype */ static const JSCFunctionListEntry js_async_generator_proto_funcs[] = { JS_CFUNC_MAGIC_DEF("next", 1, js_async_generator_next, GEN_MAGIC_NEXT ), JS_CFUNC_MAGIC_DEF("return", 1, js_async_generator_next, GEN_MAGIC_RETURN ), JS_CFUNC_MAGIC_DEF("throw", 1, js_async_generator_next, GEN_MAGIC_THROW ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "AsyncGenerator", JS_PROP_CONFIGURABLE ), }; static JSClassShortDef const js_async_class_def[] = { { JS_ATOM_Promise, js_promise_finalizer, js_promise_mark }, /* JS_CLASS_PROMISE */ { JS_ATOM_PromiseResolveFunction, js_promise_resolve_function_finalizer, js_promise_resolve_function_mark }, /* JS_CLASS_PROMISE_RESOLVE_FUNCTION */ { JS_ATOM_PromiseRejectFunction, js_promise_resolve_function_finalizer, js_promise_resolve_function_mark }, /* JS_CLASS_PROMISE_REJECT_FUNCTION */ { JS_ATOM_AsyncFunction, js_bytecode_function_finalizer, js_bytecode_function_mark }, /* JS_CLASS_ASYNC_FUNCTION */ { JS_ATOM_AsyncFunctionResolve, js_async_function_resolve_finalizer, js_async_function_resolve_mark }, /* JS_CLASS_ASYNC_FUNCTION_RESOLVE */ { JS_ATOM_AsyncFunctionReject, js_async_function_resolve_finalizer, js_async_function_resolve_mark }, /* JS_CLASS_ASYNC_FUNCTION_REJECT */ { JS_ATOM_empty_string, js_async_from_sync_iterator_finalizer, js_async_from_sync_iterator_mark }, /* JS_CLASS_ASYNC_FROM_SYNC_ITERATOR */ { JS_ATOM_AsyncGeneratorFunction, js_bytecode_function_finalizer, js_bytecode_function_mark }, /* JS_CLASS_ASYNC_GENERATOR_FUNCTION */ { JS_ATOM_AsyncGenerator, js_async_generator_finalizer, js_async_generator_mark }, /* JS_CLASS_ASYNC_GENERATOR */ }; int JS_AddIntrinsicPromise(JSContext *ctx) { JSRuntime *rt = ctx->rt; JSValue obj1; JSCFunctionType ft; if (!JS_IsRegisteredClass(rt, JS_CLASS_PROMISE)) { if (init_class_range(rt, js_async_class_def, JS_CLASS_PROMISE, countof(js_async_class_def))) return -1; rt->class_array[JS_CLASS_PROMISE_RESOLVE_FUNCTION].call = js_promise_resolve_function_call; rt->class_array[JS_CLASS_PROMISE_REJECT_FUNCTION].call = js_promise_resolve_function_call; rt->class_array[JS_CLASS_ASYNC_FUNCTION].call = js_async_function_call; rt->class_array[JS_CLASS_ASYNC_FUNCTION_RESOLVE].call = js_async_function_resolve_call; rt->class_array[JS_CLASS_ASYNC_FUNCTION_REJECT].call = js_async_function_resolve_call; rt->class_array[JS_CLASS_ASYNC_GENERATOR_FUNCTION].call = js_async_generator_function_call; } /* Promise */ obj1 = JS_NewCConstructor(ctx, JS_CLASS_PROMISE, "Promise", js_promise_constructor, 1, JS_CFUNC_constructor, 0, JS_UNDEFINED, js_promise_funcs, countof(js_promise_funcs), js_promise_proto_funcs, countof(js_promise_proto_funcs), 0); if (JS_IsException(obj1)) return -1; ctx->promise_ctor = obj1; /* AsyncFunction */ ft.generic_magic = js_function_constructor; obj1 = JS_NewCConstructor(ctx, JS_CLASS_ASYNC_FUNCTION, "AsyncFunction", ft.generic, 1, JS_CFUNC_constructor_or_func_magic, JS_FUNC_ASYNC, ctx->function_ctor, NULL, 0, js_async_function_proto_funcs, countof(js_async_function_proto_funcs), JS_NEW_CTOR_NO_GLOBAL | JS_NEW_CTOR_READONLY); if (JS_IsException(obj1)) return -1; JS_FreeValue(ctx, obj1); /* AsyncIteratorPrototype */ ctx->async_iterator_proto = JS_NewObjectProtoList(ctx, ctx->class_proto[JS_CLASS_OBJECT], js_async_iterator_proto_funcs, countof(js_async_iterator_proto_funcs)); if (JS_IsException(ctx->async_iterator_proto)) return -1; /* AsyncFromSyncIteratorPrototype */ ctx->class_proto[JS_CLASS_ASYNC_FROM_SYNC_ITERATOR] = JS_NewObjectProtoList(ctx, ctx->async_iterator_proto, js_async_from_sync_iterator_proto_funcs, countof(js_async_from_sync_iterator_proto_funcs)); if (JS_IsException(ctx->class_proto[JS_CLASS_ASYNC_FROM_SYNC_ITERATOR])) return -1; /* AsyncGeneratorPrototype */ ctx->class_proto[JS_CLASS_ASYNC_GENERATOR] = JS_NewObjectProtoList(ctx, ctx->async_iterator_proto, js_async_generator_proto_funcs, countof(js_async_generator_proto_funcs)); if (JS_IsException(ctx->class_proto[JS_CLASS_ASYNC_GENERATOR])) return -1; /* AsyncGeneratorFunction */ ft.generic_magic = js_function_constructor; obj1 = JS_NewCConstructor(ctx, JS_CLASS_ASYNC_GENERATOR_FUNCTION, "AsyncGeneratorFunction", ft.generic, 1, JS_CFUNC_constructor_or_func_magic, JS_FUNC_ASYNC_GENERATOR, ctx->function_ctor, NULL, 0, js_async_generator_function_proto_funcs, countof(js_async_generator_function_proto_funcs), JS_NEW_CTOR_NO_GLOBAL | JS_NEW_CTOR_READONLY); if (JS_IsException(obj1)) return -1; JS_FreeValue(ctx, obj1); return JS_SetConstructor2(ctx, ctx->class_proto[JS_CLASS_ASYNC_GENERATOR_FUNCTION], ctx->class_proto[JS_CLASS_ASYNC_GENERATOR], JS_PROP_CONFIGURABLE, JS_PROP_CONFIGURABLE); } /* URI handling */ static int string_get_hex(JSString *p, int k, int n) { int c = 0, h; while (n-- > 0) { if ((h = from_hex(string_get(p, k++))) < 0) return -1; c = (c << 4) | h; } return c; } static int isURIReserved(int c) { return c < 0x100 && memchr(";/?:@&=+$,#", c, sizeof(";/?:@&=+$,#") - 1) != NULL; } static int __attribute__((format(printf, 2, 3))) js_throw_URIError(JSContext *ctx, const char *fmt, ...) { va_list ap; va_start(ap, fmt); JS_ThrowError(ctx, JS_URI_ERROR, fmt, ap); va_end(ap); return -1; } static int hex_decode(JSContext *ctx, JSString *p, int k) { int c; if (k >= p->len || string_get(p, k) != '%') return js_throw_URIError(ctx, "expecting %%"); if (k + 2 >= p->len || (c = string_get_hex(p, k + 1, 2)) < 0) return js_throw_URIError(ctx, "expecting hex digit"); return c; } static JSValue js_global_decodeURI(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int isComponent) { JSValue str; StringBuffer b_s, *b = &b_s; JSString *p; int k, c, c1, n, c_min; str = JS_ToString(ctx, argv[0]); if (JS_IsException(str)) return str; string_buffer_init(ctx, b, 0); p = JS_VALUE_GET_STRING(str); for (k = 0; k < p->len;) { c = string_get(p, k); if (c == '%') { c = hex_decode(ctx, p, k); if (c < 0) goto fail; k += 3; if (c < 0x80) { if (!isComponent && isURIReserved(c)) { c = '%'; k -= 2; } } else { /* Decode URI-encoded UTF-8 sequence */ if (c >= 0xc0 && c <= 0xdf) { n = 1; c_min = 0x80; c &= 0x1f; } else if (c >= 0xe0 && c <= 0xef) { n = 2; c_min = 0x800; c &= 0xf; } else if (c >= 0xf0 && c <= 0xf7) { n = 3; c_min = 0x10000; c &= 0x7; } else { n = 0; c_min = 1; c = 0; } while (n-- > 0) { c1 = hex_decode(ctx, p, k); if (c1 < 0) goto fail; k += 3; if ((c1 & 0xc0) != 0x80) { c = 0; break; } c = (c << 6) | (c1 & 0x3f); } if (c < c_min || c > 0x10FFFF || is_surrogate(c)) { js_throw_URIError(ctx, "malformed UTF-8"); goto fail; } } } else { k++; } string_buffer_putc(b, c); } JS_FreeValue(ctx, str); return string_buffer_end(b); fail: JS_FreeValue(ctx, str); string_buffer_free(b); return JS_EXCEPTION; } static int isUnescaped(int c) { static char const unescaped_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789" "@*_+-./"; return c < 0x100 && memchr(unescaped_chars, c, sizeof(unescaped_chars) - 1); } static int isURIUnescaped(int c, int isComponent) { return c < 0x100 && ((c >= 0x61 && c <= 0x7a) || (c >= 0x41 && c <= 0x5a) || (c >= 0x30 && c <= 0x39) || memchr("-_.!~*'()", c, sizeof("-_.!~*'()") - 1) != NULL || (!isComponent && isURIReserved(c))); } static int encodeURI_hex(StringBuffer *b, int c) { uint8_t buf[6]; int n = 0; const char *hex = "0123456789ABCDEF"; buf[n++] = '%'; if (c >= 256) { buf[n++] = 'u'; buf[n++] = hex[(c >> 12) & 15]; buf[n++] = hex[(c >> 8) & 15]; } buf[n++] = hex[(c >> 4) & 15]; buf[n++] = hex[(c >> 0) & 15]; return string_buffer_write8(b, buf, n); } static JSValue js_global_encodeURI(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int isComponent) { JSValue str; StringBuffer b_s, *b = &b_s; JSString *p; int k, c, c1; str = JS_ToString(ctx, argv[0]); if (JS_IsException(str)) return str; p = JS_VALUE_GET_STRING(str); string_buffer_init(ctx, b, p->len); for (k = 0; k < p->len;) { c = string_get(p, k); k++; if (isURIUnescaped(c, isComponent)) { string_buffer_putc16(b, c); } else { if (is_lo_surrogate(c)) { js_throw_URIError(ctx, "invalid character"); goto fail; } else if (is_hi_surrogate(c)) { if (k >= p->len) { js_throw_URIError(ctx, "expecting surrogate pair"); goto fail; } c1 = string_get(p, k); k++; if (!is_lo_surrogate(c1)) { js_throw_URIError(ctx, "expecting surrogate pair"); goto fail; } c = from_surrogate(c, c1); } if (c < 0x80) { encodeURI_hex(b, c); } else { /* XXX: use C UTF-8 conversion ? */ if (c < 0x800) { encodeURI_hex(b, (c >> 6) | 0xc0); } else { if (c < 0x10000) { encodeURI_hex(b, (c >> 12) | 0xe0); } else { encodeURI_hex(b, (c >> 18) | 0xf0); encodeURI_hex(b, ((c >> 12) & 0x3f) | 0x80); } encodeURI_hex(b, ((c >> 6) & 0x3f) | 0x80); } encodeURI_hex(b, (c & 0x3f) | 0x80); } } } JS_FreeValue(ctx, str); return string_buffer_end(b); fail: JS_FreeValue(ctx, str); string_buffer_free(b); return JS_EXCEPTION; } static JSValue js_global_escape(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue str; StringBuffer b_s, *b = &b_s; JSString *p; int i, len, c; str = JS_ToString(ctx, argv[0]); if (JS_IsException(str)) return str; p = JS_VALUE_GET_STRING(str); string_buffer_init(ctx, b, p->len); for (i = 0, len = p->len; i < len; i++) { c = string_get(p, i); if (isUnescaped(c)) { string_buffer_putc16(b, c); } else { encodeURI_hex(b, c); } } JS_FreeValue(ctx, str); return string_buffer_end(b); } static JSValue js_global_unescape(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue str; StringBuffer b_s, *b = &b_s; JSString *p; int i, len, c, n; str = JS_ToString(ctx, argv[0]); if (JS_IsException(str)) return str; string_buffer_init(ctx, b, 0); p = JS_VALUE_GET_STRING(str); for (i = 0, len = p->len; i < len; i++) { c = string_get(p, i); if (c == '%') { if (i + 6 <= len && string_get(p, i + 1) == 'u' && (n = string_get_hex(p, i + 2, 4)) >= 0) { c = n; i += 6 - 1; } else if (i + 3 <= len && (n = string_get_hex(p, i + 1, 2)) >= 0) { c = n; i += 3 - 1; } } string_buffer_putc16(b, c); } JS_FreeValue(ctx, str); return string_buffer_end(b); } /* global object */ static const JSCFunctionListEntry js_global_funcs[] = { JS_CFUNC_DEF("parseInt", 2, js_parseInt ), JS_CFUNC_DEF("parseFloat", 1, js_parseFloat ), JS_CFUNC_DEF("isNaN", 1, js_global_isNaN ), JS_CFUNC_DEF("isFinite", 1, js_global_isFinite ), JS_CFUNC_MAGIC_DEF("decodeURI", 1, js_global_decodeURI, 0 ), JS_CFUNC_MAGIC_DEF("decodeURIComponent", 1, js_global_decodeURI, 1 ), JS_CFUNC_MAGIC_DEF("encodeURI", 1, js_global_encodeURI, 0 ), JS_CFUNC_MAGIC_DEF("encodeURIComponent", 1, js_global_encodeURI, 1 ), JS_CFUNC_DEF("escape", 1, js_global_escape ), JS_CFUNC_DEF("unescape", 1, js_global_unescape ), JS_PROP_DOUBLE_DEF("Infinity", 1.0 / 0.0, 0 ), JS_PROP_DOUBLE_DEF("NaN", NAN, 0 ), JS_PROP_UNDEFINED_DEF("undefined", 0 ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "global", JS_PROP_CONFIGURABLE ), JS_CFUNC_DEF("eval", 1, js_global_eval ), }; /* Date */ static int64_t math_mod(int64_t a, int64_t b) { /* return positive modulo */ int64_t m = a % b; return m + (m < 0) * b; } static int64_t floor_div(int64_t a, int64_t b) { /* integer division rounding toward -Infinity */ int64_t m = a % b; return (a - (m + (m < 0) * b)) / b; } static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv); static __exception int JS_ThisTimeValue(JSContext *ctx, double *valp, JSValueConst this_val) { if (JS_VALUE_GET_TAG(this_val) == JS_TAG_OBJECT) { JSObject *p = JS_VALUE_GET_OBJ(this_val); if (p->class_id == JS_CLASS_DATE && JS_IsNumber(p->u.object_data)) return JS_ToFloat64(ctx, valp, p->u.object_data); } JS_ThrowTypeError(ctx, "not a Date object"); return -1; } static JSValue JS_SetThisTimeValue(JSContext *ctx, JSValueConst this_val, double v) { if (JS_VALUE_GET_TAG(this_val) == JS_TAG_OBJECT) { JSObject *p = JS_VALUE_GET_OBJ(this_val); if (p->class_id == JS_CLASS_DATE) { JS_FreeValue(ctx, p->u.object_data); p->u.object_data = JS_NewFloat64(ctx, v); return JS_DupValue(ctx, p->u.object_data); } } return JS_ThrowTypeError(ctx, "not a Date object"); } static int64_t days_from_year(int64_t y) { return 365 * (y - 1970) + floor_div(y - 1969, 4) - floor_div(y - 1901, 100) + floor_div(y - 1601, 400); } static int64_t days_in_year(int64_t y) { return 365 + !(y % 4) - !(y % 100) + !(y % 400); } /* return the year, update days */ static int64_t year_from_days(int64_t *days) { int64_t y, d1, nd, d = *days; y = floor_div(d * 10000, 3652425) + 1970; /* the initial approximation is very good, so only a few iterations are necessary */ for(;;) { d1 = d - days_from_year(y); if (d1 < 0) { y--; d1 += days_in_year(y); } else { nd = days_in_year(y); if (d1 < nd) break; d1 -= nd; y++; } } *days = d1; return y; } static int const month_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; static char const month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; static char const day_names[] = "SunMonTueWedThuFriSat"; static __exception int get_date_fields(JSContext *ctx, JSValueConst obj, double fields[minimum_length(9)], int is_local, int force) { double dval; int64_t d, days, wd, y, i, md, h, m, s, ms, tz = 0; if (JS_ThisTimeValue(ctx, &dval, obj)) return -1; if (isnan(dval)) { if (!force) return FALSE; /* NaN */ d = 0; /* initialize all fields to 0 */ } else { d = dval; /* assuming -8.64e15 <= dval <= -8.64e15 */ if (is_local) { tz = -getTimezoneOffset(d); d += tz * 60000; } } /* result is >= 0, we can use % */ h = math_mod(d, 86400000); days = (d - h) / 86400000; ms = h % 1000; h = (h - ms) / 1000; s = h % 60; h = (h - s) / 60; m = h % 60; h = (h - m) / 60; wd = math_mod(days + 4, 7); /* week day */ y = year_from_days(&days); for(i = 0; i < 11; i++) { md = month_days[i]; if (i == 1) md += days_in_year(y) - 365; if (days < md) break; days -= md; } fields[0] = y; fields[1] = i; fields[2] = days + 1; fields[3] = h; fields[4] = m; fields[5] = s; fields[6] = ms; fields[7] = wd; fields[8] = tz; return TRUE; } static double time_clip(double t) { if (t >= -8.64e15 && t <= 8.64e15) return trunc(t) + 0.0; /* convert -0 to +0 */ else return NAN; } /* The spec mandates the use of 'double' and it specifies the order of the operations */ static double set_date_fields(double fields[minimum_length(7)], int is_local) { double y, m, dt, ym, mn, day, h, s, milli, time, tv; int yi, mi, i; int64_t days; volatile double temp; /* enforce evaluation order */ /* emulate 21.4.1.15 MakeDay ( year, month, date ) */ y = fields[0]; m = fields[1]; dt = fields[2]; ym = y + floor(m / 12); mn = fmod(m, 12); if (mn < 0) mn += 12; if (ym < -271821 || ym > 275760) return NAN; yi = ym; mi = mn; days = days_from_year(yi); for(i = 0; i < mi; i++) { days += month_days[i]; if (i == 1) days += days_in_year(yi) - 365; } day = days + dt - 1; /* emulate 21.4.1.14 MakeTime ( hour, min, sec, ms ) */ h = fields[3]; m = fields[4]; s = fields[5]; milli = fields[6]; /* Use a volatile intermediary variable to ensure order of evaluation * as specified in ECMA. This fixes a test262 error on * test262/test/built-ins/Date/UTC/fp-evaluation-order.js. * Without the volatile qualifier, the compile can generate code * that performs the computation in a different order or with instructions * that produce a different result such as FMA (float multiply and add). */ time = h * 3600000; time += (temp = m * 60000); time += (temp = s * 1000); time += milli; /* emulate 21.4.1.16 MakeDate ( day, time ) */ tv = (temp = day * 86400000) + time; /* prevent generation of FMA */ if (!isfinite(tv)) return NAN; /* adjust for local time and clip */ if (is_local) { int64_t ti = tv < INT64_MIN ? INT64_MIN : tv >= 0x1p63 ? INT64_MAX : (int64_t)tv; tv += getTimezoneOffset(ti) * 60000; } return time_clip(tv); } static double set_date_fields_checked(double fields[minimum_length(7)], int is_local) { int i; double a; for(i = 0; i < 7; i++) { a = fields[i]; if (!isfinite(a)) return NAN; fields[i] = trunc(a); if (i == 0 && fields[0] >= 0 && fields[0] < 100) fields[0] += 1900; } return set_date_fields(fields, is_local); } static JSValue get_date_field(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { // get_date_field(obj, n, is_local) double fields[9]; int res, n, is_local; is_local = magic & 0x0F; n = (magic >> 4) & 0x0F; res = get_date_fields(ctx, this_val, fields, is_local, 0); if (res < 0) return JS_EXCEPTION; if (!res) return JS_NAN; if (magic & 0x100) { // getYear fields[0] -= 1900; } return JS_NewFloat64(ctx, fields[n]); } static JSValue set_date_field(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { // _field(obj, first_field, end_field, args, is_local) double fields[9]; int res, first_field, end_field, is_local, i, n, res1; double d, a; d = NAN; first_field = (magic >> 8) & 0x0F; end_field = (magic >> 4) & 0x0F; is_local = magic & 0x0F; res = get_date_fields(ctx, this_val, fields, is_local, first_field == 0); if (res < 0) return JS_EXCEPTION; res1 = res; // Argument coercion is observable and must be done unconditionally. n = min_int(argc, end_field - first_field); for(i = 0; i < n; i++) { if (JS_ToFloat64(ctx, &a, argv[i])) return JS_EXCEPTION; if (!isfinite(a)) res = FALSE; fields[first_field + i] = trunc(a); } if (!res1) return JS_NAN; /* thisTimeValue is NaN */ if (res && argc > 0) d = set_date_fields(fields, is_local); return JS_SetThisTimeValue(ctx, this_val, d); } /* fmt: 0: toUTCString: "Tue, 02 Jan 2018 23:04:46 GMT" 1: toString: "Wed Jan 03 2018 00:05:22 GMT+0100 (CET)" 2: toISOString: "2018-01-02T23:02:56.927Z" 3: toLocaleString: "1/2/2018, 11:40:40 PM" part: 1=date, 2=time 3=all XXX: should use a variant of strftime(). */ static JSValue get_date_string(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { // _string(obj, fmt, part) char buf[64]; double fields[9]; int res, fmt, part, pos; int y, mon, d, h, m, s, ms, wd, tz; fmt = (magic >> 4) & 0x0F; part = magic & 0x0F; res = get_date_fields(ctx, this_val, fields, fmt & 1, 0); if (res < 0) return JS_EXCEPTION; if (!res) { if (fmt == 2) return JS_ThrowRangeError(ctx, "Date value is NaN"); else return js_new_string8(ctx, "Invalid Date"); } y = fields[0]; mon = fields[1]; d = fields[2]; h = fields[3]; m = fields[4]; s = fields[5]; ms = fields[6]; wd = fields[7]; tz = fields[8]; pos = 0; if (part & 1) { /* date part */ switch(fmt) { case 0: pos += snprintf(buf + pos, sizeof(buf) - pos, "%.3s, %02d %.3s %0*d ", day_names + wd * 3, d, month_names + mon * 3, 4 + (y < 0), y); break; case 1: pos += snprintf(buf + pos, sizeof(buf) - pos, "%.3s %.3s %02d %0*d", day_names + wd * 3, month_names + mon * 3, d, 4 + (y < 0), y); if (part == 3) { buf[pos++] = ' '; } break; case 2: if (y >= 0 && y <= 9999) { pos += snprintf(buf + pos, sizeof(buf) - pos, "%04d", y); } else { pos += snprintf(buf + pos, sizeof(buf) - pos, "%+07d", y); } pos += snprintf(buf + pos, sizeof(buf) - pos, "-%02d-%02dT", mon + 1, d); break; case 3: pos += snprintf(buf + pos, sizeof(buf) - pos, "%02d/%02d/%0*d", mon + 1, d, 4 + (y < 0), y); if (part == 3) { buf[pos++] = ','; buf[pos++] = ' '; } break; } } if (part & 2) { /* time part */ switch(fmt) { case 0: pos += snprintf(buf + pos, sizeof(buf) - pos, "%02d:%02d:%02d GMT", h, m, s); break; case 1: pos += snprintf(buf + pos, sizeof(buf) - pos, "%02d:%02d:%02d GMT", h, m, s); if (tz < 0) { buf[pos++] = '-'; tz = -tz; } else { buf[pos++] = '+'; } /* tz is >= 0, can use % */ pos += snprintf(buf + pos, sizeof(buf) - pos, "%02d%02d", tz / 60, tz % 60); /* XXX: tack the time zone code? */ break; case 2: pos += snprintf(buf + pos, sizeof(buf) - pos, "%02d:%02d:%02d.%03dZ", h, m, s, ms); break; case 3: pos += snprintf(buf + pos, sizeof(buf) - pos, "%02d:%02d:%02d %cM", (h + 11) % 12 + 1, m, s, (h < 12) ? 'A' : 'P'); break; } } return JS_NewStringLen(ctx, buf, pos); } /* OS dependent: return the UTC time in ms since 1970. */ static int64_t date_now(void) { struct timeval tv; gettimeofday(&tv, NULL); return (int64_t)tv.tv_sec * 1000 + (tv.tv_usec / 1000); } static JSValue js_date_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { // Date(y, mon, d, h, m, s, ms) JSValue rv; int i, n; double val; if (JS_IsUndefined(new_target)) { /* invoked as function */ argc = 0; } n = argc; if (n == 0) { val = date_now(); } else if (n == 1) { JSValue v, dv; if (JS_VALUE_GET_TAG(argv[0]) == JS_TAG_OBJECT) { JSObject *p = JS_VALUE_GET_OBJ(argv[0]); if (p->class_id == JS_CLASS_DATE && JS_IsNumber(p->u.object_data)) { if (JS_ToFloat64(ctx, &val, p->u.object_data)) return JS_EXCEPTION; val = time_clip(val); goto has_val; } } v = JS_ToPrimitive(ctx, argv[0], HINT_NONE); if (JS_IsString(v)) { dv = js_Date_parse(ctx, JS_UNDEFINED, 1, (JSValueConst *)&v); JS_FreeValue(ctx, v); if (JS_IsException(dv)) return JS_EXCEPTION; if (JS_ToFloat64Free(ctx, &val, dv)) return JS_EXCEPTION; } else { if (JS_ToFloat64Free(ctx, &val, v)) return JS_EXCEPTION; } val = time_clip(val); } else { double fields[] = { 0, 0, 1, 0, 0, 0, 0 }; if (n > 7) n = 7; for(i = 0; i < n; i++) { if (JS_ToFloat64(ctx, &fields[i], argv[i])) return JS_EXCEPTION; } val = set_date_fields_checked(fields, 1); } has_val: #if 0 JSValueConst args[3]; args[0] = new_target; args[1] = ctx->class_proto[JS_CLASS_DATE]; args[2] = JS_NewFloat64(ctx, val); rv = js___date_create(ctx, JS_UNDEFINED, 3, args); #else rv = js_create_from_ctor(ctx, new_target, JS_CLASS_DATE); if (!JS_IsException(rv)) JS_SetObjectData(ctx, rv, JS_NewFloat64(ctx, val)); #endif if (!JS_IsException(rv) && JS_IsUndefined(new_target)) { /* invoked as a function, return (new Date()).toString(); */ JSValue s; s = get_date_string(ctx, rv, 0, NULL, 0x13); JS_FreeValue(ctx, rv); rv = s; } return rv; } static JSValue js_Date_UTC(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // UTC(y, mon, d, h, m, s, ms) double fields[] = { 0, 0, 1, 0, 0, 0, 0 }; int i, n; n = argc; if (n == 0) return JS_NAN; if (n > 7) n = 7; for(i = 0; i < n; i++) { if (JS_ToFloat64(ctx, &fields[i], argv[i])) return JS_EXCEPTION; } return JS_NewFloat64(ctx, set_date_fields_checked(fields, 0)); } /* Date string parsing */ static BOOL string_skip_char(const uint8_t *sp, int *pp, int c) { if (sp[*pp] == c) { *pp += 1; return TRUE; } else { return FALSE; } } /* skip spaces, update offset, return next char */ static int string_skip_spaces(const uint8_t *sp, int *pp) { int c; while ((c = sp[*pp]) == ' ') *pp += 1; return c; } /* skip dashes dots and commas */ static int string_skip_separators(const uint8_t *sp, int *pp) { int c; while ((c = sp[*pp]) == '-' || c == '/' || c == '.' || c == ',') *pp += 1; return c; } /* skip a word, stop on spaces, digits and separators, update offset */ static int string_skip_until(const uint8_t *sp, int *pp, const char *stoplist) { int c; while (!strchr(stoplist, c = sp[*pp])) *pp += 1; return c; } /* parse a numeric field (max_digits = 0 -> no maximum) */ static BOOL string_get_digits(const uint8_t *sp, int *pp, int *pval, int min_digits, int max_digits) { int v = 0; int c, p = *pp, p_start; p_start = p; while ((c = sp[p]) >= '0' && c <= '9') { /* arbitrary limit to 9 digits */ if (v >= 100000000) return FALSE; v = v * 10 + c - '0'; p++; if (p - p_start == max_digits) break; } if (p - p_start < min_digits) return FALSE; *pval = v; *pp = p; return TRUE; } static BOOL string_get_milliseconds(const uint8_t *sp, int *pp, int *pval) { /* parse optional fractional part as milliseconds and truncate. */ /* spec does not indicate which rounding should be used */ int mul = 100, ms = 0, c, p_start, p = *pp; c = sp[p]; if (c == '.' || c == ',') { p++; p_start = p; while ((c = sp[p]) >= '0' && c <= '9') { ms += (c - '0') * mul; mul /= 10; p++; if (p - p_start == 9) break; } if (p > p_start) { /* only consume the separator if digits are present */ *pval = ms; *pp = p; } } return TRUE; } static uint8_t upper_ascii(uint8_t c) { return c >= 'a' && c <= 'z' ? c - 'a' + 'A' : c; } static BOOL string_get_tzoffset(const uint8_t *sp, int *pp, int *tzp, BOOL strict) { int tz = 0, sgn, hh, mm, p = *pp; sgn = sp[p++]; if (sgn == '+' || sgn == '-') { int n = p; if (!string_get_digits(sp, &p, &hh, 1, 0)) return FALSE; n = p - n; if (strict && n != 2 && n != 4) return FALSE; while (n > 4) { n -= 2; hh /= 100; } if (n > 2) { mm = hh % 100; hh = hh / 100; } else { mm = 0; if (string_skip_char(sp, &p, ':')) { /* optional separator */ if (!string_get_digits(sp, &p, &mm, 2, 2)) return FALSE; } else { if (strict) return FALSE; /* [+-]HH is not accepted in strict mode */ } } if (hh > 23 || mm > 59) return FALSE; tz = hh * 60 + mm; if (sgn != '+') tz = -tz; } else if (sgn != 'Z') { return FALSE; } *pp = p; *tzp = tz; return TRUE; } static BOOL string_match(const uint8_t *sp, int *pp, const char *s) { int p = *pp; while (*s != '\0') { if (upper_ascii(sp[p]) != upper_ascii(*s++)) return FALSE; p++; } *pp = p; return TRUE; } static int find_abbrev(const uint8_t *sp, int p, const char *list, int count) { int n, i; for (n = 0; n < count; n++) { for (i = 0;; i++) { if (upper_ascii(sp[p + i]) != upper_ascii(list[n * 3 + i])) break; if (i == 2) return n; } } return -1; } static BOOL string_get_month(const uint8_t *sp, int *pp, int *pval) { int n; n = find_abbrev(sp, *pp, month_names, 12); if (n < 0) return FALSE; *pval = n + 1; *pp += 3; return TRUE; } /* parse toISOString format */ static BOOL js_date_parse_isostring(const uint8_t *sp, int fields[9], BOOL *is_local) { int sgn, i, p = 0; /* initialize fields to the beginning of the Epoch */ for (i = 0; i < 9; i++) { fields[i] = (i == 2); } *is_local = FALSE; /* year is either yyyy digits or [+-]yyyyyy */ sgn = sp[p]; if (sgn == '-' || sgn == '+') { p++; if (!string_get_digits(sp, &p, &fields[0], 6, 6)) return FALSE; if (sgn == '-') { if (fields[0] == 0) return FALSE; // reject -000000 fields[0] = -fields[0]; } } else { if (!string_get_digits(sp, &p, &fields[0], 4, 4)) return FALSE; } if (string_skip_char(sp, &p, '-')) { if (!string_get_digits(sp, &p, &fields[1], 2, 2)) /* month */ return FALSE; if (fields[1] < 1) return FALSE; fields[1] -= 1; if (string_skip_char(sp, &p, '-')) { if (!string_get_digits(sp, &p, &fields[2], 2, 2)) /* day */ return FALSE; if (fields[2] < 1) return FALSE; } } if (string_skip_char(sp, &p, 'T')) { *is_local = TRUE; if (!string_get_digits(sp, &p, &fields[3], 2, 2) /* hour */ || !string_skip_char(sp, &p, ':') || !string_get_digits(sp, &p, &fields[4], 2, 2)) { /* minute */ fields[3] = 100; // reject unconditionally return TRUE; } if (string_skip_char(sp, &p, ':')) { if (!string_get_digits(sp, &p, &fields[5], 2, 2)) /* second */ return FALSE; string_get_milliseconds(sp, &p, &fields[6]); } } /* parse the time zone offset if present: [+-]HH:mm or [+-]HHmm */ if (sp[p]) { *is_local = FALSE; if (!string_get_tzoffset(sp, &p, &fields[8], TRUE)) return FALSE; } /* error if extraneous characters */ return sp[p] == '\0'; } static struct { char name[6]; int16_t offset; } const js_tzabbr[] = { { "GMT", 0 }, // Greenwich Mean Time { "UTC", 0 }, // Coordinated Universal Time { "UT", 0 }, // Universal Time { "Z", 0 }, // Zulu Time { "EDT", -4 * 60 }, // Eastern Daylight Time { "EST", -5 * 60 }, // Eastern Standard Time { "CDT", -5 * 60 }, // Central Daylight Time { "CST", -6 * 60 }, // Central Standard Time { "MDT", -6 * 60 }, // Mountain Daylight Time { "MST", -7 * 60 }, // Mountain Standard Time { "PDT", -7 * 60 }, // Pacific Daylight Time { "PST", -8 * 60 }, // Pacific Standard Time { "WET", +0 * 60 }, // Western European Time { "WEST", +1 * 60 }, // Western European Summer Time { "CET", +1 * 60 }, // Central European Time { "CEST", +2 * 60 }, // Central European Summer Time { "EET", +2 * 60 }, // Eastern European Time { "EEST", +3 * 60 }, // Eastern European Summer Time }; static BOOL string_get_tzabbr(const uint8_t *sp, int *pp, int *offset) { for (size_t i = 0; i < countof(js_tzabbr); i++) { if (string_match(sp, pp, js_tzabbr[i].name)) { *offset = js_tzabbr[i].offset; return TRUE; } } return FALSE; } /* parse toString, toUTCString and other formats */ static BOOL js_date_parse_otherstring(const uint8_t *sp, int fields[minimum_length(9)], BOOL *is_local) { int c, i, val, p = 0, p_start; int num[3]; BOOL has_year = FALSE; BOOL has_mon = FALSE; BOOL has_time = FALSE; int num_index = 0; /* initialize fields to the beginning of 2001-01-01 */ fields[0] = 2001; fields[1] = 1; fields[2] = 1; for (i = 3; i < 9; i++) { fields[i] = 0; } *is_local = TRUE; while (string_skip_spaces(sp, &p)) { p_start = p; if ((c = sp[p]) == '+' || c == '-') { if (has_time && string_get_tzoffset(sp, &p, &fields[8], FALSE)) { *is_local = FALSE; } else { p++; if (string_get_digits(sp, &p, &val, 1, 0)) { if (c == '-') { if (val == 0) return FALSE; val = -val; } fields[0] = val; has_year = TRUE; } } } else if (string_get_digits(sp, &p, &val, 1, 0)) { if (string_skip_char(sp, &p, ':')) { /* time part */ fields[3] = val; if (!string_get_digits(sp, &p, &fields[4], 1, 2)) return FALSE; if (string_skip_char(sp, &p, ':')) { if (!string_get_digits(sp, &p, &fields[5], 1, 2)) return FALSE; string_get_milliseconds(sp, &p, &fields[6]); } has_time = TRUE; if ((sp[p] == '+' || sp[p] == '-') && string_get_tzoffset(sp, &p, &fields[8], FALSE)) { *is_local = FALSE; } } else { if (p - p_start > 2 && !has_year) { fields[0] = val; has_year = TRUE; } else if ((val < 1 || val > 31) && !has_year) { fields[0] = val + (val < 100) * 1900 + (val < 50) * 100; has_year = TRUE; } else { if (num_index == 3) return FALSE; num[num_index++] = val; } } } else if (string_get_month(sp, &p, &fields[1])) { has_mon = TRUE; string_skip_until(sp, &p, "0123456789 -/("); } else if (has_time && string_match(sp, &p, "PM")) { if (fields[3] < 12) fields[3] += 12; continue; } else if (has_time && string_match(sp, &p, "AM")) { if (fields[3] == 12) fields[3] -= 12; continue; } else if (string_get_tzabbr(sp, &p, &fields[8])) { *is_local = FALSE; continue; } else if (c == '(') { /* skip parenthesized phrase */ int level = 0; while ((c = sp[p]) != '\0') { p++; level += (c == '('); level -= (c == ')'); if (!level) break; } if (level > 0) return FALSE; } else if (c == ')') { return FALSE; } else { if (has_year + has_mon + has_time + num_index) return FALSE; /* skip a word */ string_skip_until(sp, &p, " -/("); } string_skip_separators(sp, &p); } if (num_index + has_year + has_mon > 3) return FALSE; switch (num_index) { case 0: if (!has_year) return FALSE; break; case 1: if (has_mon) fields[2] = num[0]; else fields[1] = num[0]; break; case 2: if (has_year) { fields[1] = num[0]; fields[2] = num[1]; } else if (has_mon) { fields[0] = num[1] + (num[1] < 100) * 1900 + (num[1] < 50) * 100; fields[2] = num[0]; } else { fields[1] = num[0]; fields[2] = num[1]; } break; case 3: fields[0] = num[2] + (num[2] < 100) * 1900 + (num[2] < 50) * 100; fields[1] = num[0]; fields[2] = num[1]; break; default: return FALSE; } if (fields[1] < 1 || fields[2] < 1) return FALSE; fields[1] -= 1; return TRUE; } static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue s, rv; int fields[9]; double fields1[9]; double d; int i, c; JSString *sp; uint8_t buf[128]; BOOL is_local; rv = JS_NAN; s = JS_ToString(ctx, argv[0]); if (JS_IsException(s)) return JS_EXCEPTION; sp = JS_VALUE_GET_STRING(s); /* convert the string as a byte array */ for (i = 0; i < sp->len && i < (int)countof(buf) - 1; i++) { c = string_get(sp, i); if (c > 255) c = (c == 0x2212) ? '-' : 'x'; buf[i] = c; } buf[i] = '\0'; if (js_date_parse_isostring(buf, fields, &is_local) || js_date_parse_otherstring(buf, fields, &is_local)) { static int const field_max[6] = { 0, 11, 31, 24, 59, 59 }; BOOL valid = TRUE; /* check field maximum values */ for (i = 1; i < 6; i++) { if (fields[i] > field_max[i]) valid = FALSE; } /* special case 24:00:00.000 */ if (fields[3] == 24 && (fields[4] | fields[5] | fields[6])) valid = FALSE; if (valid) { for(i = 0; i < 7; i++) fields1[i] = fields[i]; d = set_date_fields(fields1, is_local) - fields[8] * 60000; rv = JS_NewFloat64(ctx, d); } } JS_FreeValue(ctx, s); return rv; } static JSValue js_Date_now(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // now() return JS_NewInt64(ctx, date_now()); } static JSValue js_date_Symbol_toPrimitive(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // Symbol_toPrimitive(hint) JSValueConst obj = this_val; JSAtom hint = JS_ATOM_NULL; int hint_num; if (!JS_IsObject(obj)) return JS_ThrowTypeErrorNotAnObject(ctx); if (JS_IsString(argv[0])) { hint = JS_ValueToAtom(ctx, argv[0]); if (hint == JS_ATOM_NULL) return JS_EXCEPTION; JS_FreeAtom(ctx, hint); } switch (hint) { case JS_ATOM_number: case JS_ATOM_integer: hint_num = HINT_NUMBER; break; case JS_ATOM_string: case JS_ATOM_default: hint_num = HINT_STRING; break; default: return JS_ThrowTypeError(ctx, "invalid hint"); } return JS_ToPrimitive(ctx, obj, hint_num | HINT_FORCE_ORDINARY); } static JSValue js_date_getTimezoneOffset(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // getTimezoneOffset() double v; if (JS_ThisTimeValue(ctx, &v, this_val)) return JS_EXCEPTION; if (isnan(v)) return JS_NAN; else /* assuming -8.64e15 <= v <= -8.64e15 */ return JS_NewInt64(ctx, getTimezoneOffset((int64_t)trunc(v))); } static JSValue js_date_getTime(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // getTime() double v; if (JS_ThisTimeValue(ctx, &v, this_val)) return JS_EXCEPTION; return JS_NewFloat64(ctx, v); } static JSValue js_date_setTime(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // setTime(v) double v; if (JS_ThisTimeValue(ctx, &v, this_val) || JS_ToFloat64(ctx, &v, argv[0])) return JS_EXCEPTION; return JS_SetThisTimeValue(ctx, this_val, time_clip(v)); } static JSValue js_date_setYear(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // setYear(y) double y; JSValueConst args[1]; if (JS_ThisTimeValue(ctx, &y, this_val) || JS_ToFloat64(ctx, &y, argv[0])) return JS_EXCEPTION; y = +y; if (isfinite(y)) { y = trunc(y); if (y >= 0 && y < 100) y += 1900; } args[0] = JS_NewFloat64(ctx, y); return set_date_field(ctx, this_val, 1, args, 0x011); } static JSValue js_date_toJSON(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // toJSON(key) JSValue obj, tv, method, rv; double d; rv = JS_EXCEPTION; tv = JS_UNDEFINED; obj = JS_ToObject(ctx, this_val); tv = JS_ToPrimitive(ctx, obj, HINT_NUMBER); if (JS_IsException(tv)) goto exception; if (JS_IsNumber(tv)) { if (JS_ToFloat64(ctx, &d, tv) < 0) goto exception; if (!isfinite(d)) { rv = JS_NULL; goto done; } } method = JS_GetProperty(ctx, obj, JS_ATOM_toISOString); if (JS_IsException(method)) goto exception; if (!JS_IsFunction(ctx, method)) { JS_ThrowTypeError(ctx, "object needs toISOString method"); JS_FreeValue(ctx, method); goto exception; } rv = JS_CallFree(ctx, method, obj, 0, NULL); exception: done: JS_FreeValue(ctx, obj); JS_FreeValue(ctx, tv); return rv; } static const JSCFunctionListEntry js_date_funcs[] = { JS_CFUNC_DEF("now", 0, js_Date_now ), JS_CFUNC_DEF("parse", 1, js_Date_parse ), JS_CFUNC_DEF("UTC", 7, js_Date_UTC ), }; static const JSCFunctionListEntry js_date_proto_funcs[] = { JS_CFUNC_DEF("valueOf", 0, js_date_getTime ), JS_CFUNC_MAGIC_DEF("toString", 0, get_date_string, 0x13 ), JS_CFUNC_DEF("[Symbol.toPrimitive]", 1, js_date_Symbol_toPrimitive ), JS_CFUNC_MAGIC_DEF("toUTCString", 0, get_date_string, 0x03 ), JS_ALIAS_DEF("toGMTString", "toUTCString" ), JS_CFUNC_MAGIC_DEF("toISOString", 0, get_date_string, 0x23 ), JS_CFUNC_MAGIC_DEF("toDateString", 0, get_date_string, 0x11 ), JS_CFUNC_MAGIC_DEF("toTimeString", 0, get_date_string, 0x12 ), JS_CFUNC_MAGIC_DEF("toLocaleString", 0, get_date_string, 0x33 ), JS_CFUNC_MAGIC_DEF("toLocaleDateString", 0, get_date_string, 0x31 ), JS_CFUNC_MAGIC_DEF("toLocaleTimeString", 0, get_date_string, 0x32 ), JS_CFUNC_DEF("getTimezoneOffset", 0, js_date_getTimezoneOffset ), JS_CFUNC_DEF("getTime", 0, js_date_getTime ), JS_CFUNC_MAGIC_DEF("getYear", 0, get_date_field, 0x101 ), JS_CFUNC_MAGIC_DEF("getFullYear", 0, get_date_field, 0x01 ), JS_CFUNC_MAGIC_DEF("getUTCFullYear", 0, get_date_field, 0x00 ), JS_CFUNC_MAGIC_DEF("getMonth", 0, get_date_field, 0x11 ), JS_CFUNC_MAGIC_DEF("getUTCMonth", 0, get_date_field, 0x10 ), JS_CFUNC_MAGIC_DEF("getDate", 0, get_date_field, 0x21 ), JS_CFUNC_MAGIC_DEF("getUTCDate", 0, get_date_field, 0x20 ), JS_CFUNC_MAGIC_DEF("getHours", 0, get_date_field, 0x31 ), JS_CFUNC_MAGIC_DEF("getUTCHours", 0, get_date_field, 0x30 ), JS_CFUNC_MAGIC_DEF("getMinutes", 0, get_date_field, 0x41 ), JS_CFUNC_MAGIC_DEF("getUTCMinutes", 0, get_date_field, 0x40 ), JS_CFUNC_MAGIC_DEF("getSeconds", 0, get_date_field, 0x51 ), JS_CFUNC_MAGIC_DEF("getUTCSeconds", 0, get_date_field, 0x50 ), JS_CFUNC_MAGIC_DEF("getMilliseconds", 0, get_date_field, 0x61 ), JS_CFUNC_MAGIC_DEF("getUTCMilliseconds", 0, get_date_field, 0x60 ), JS_CFUNC_MAGIC_DEF("getDay", 0, get_date_field, 0x71 ), JS_CFUNC_MAGIC_DEF("getUTCDay", 0, get_date_field, 0x70 ), JS_CFUNC_DEF("setTime", 1, js_date_setTime ), JS_CFUNC_MAGIC_DEF("setMilliseconds", 1, set_date_field, 0x671 ), JS_CFUNC_MAGIC_DEF("setUTCMilliseconds", 1, set_date_field, 0x670 ), JS_CFUNC_MAGIC_DEF("setSeconds", 2, set_date_field, 0x571 ), JS_CFUNC_MAGIC_DEF("setUTCSeconds", 2, set_date_field, 0x570 ), JS_CFUNC_MAGIC_DEF("setMinutes", 3, set_date_field, 0x471 ), JS_CFUNC_MAGIC_DEF("setUTCMinutes", 3, set_date_field, 0x470 ), JS_CFUNC_MAGIC_DEF("setHours", 4, set_date_field, 0x371 ), JS_CFUNC_MAGIC_DEF("setUTCHours", 4, set_date_field, 0x370 ), JS_CFUNC_MAGIC_DEF("setDate", 1, set_date_field, 0x231 ), JS_CFUNC_MAGIC_DEF("setUTCDate", 1, set_date_field, 0x230 ), JS_CFUNC_MAGIC_DEF("setMonth", 2, set_date_field, 0x131 ), JS_CFUNC_MAGIC_DEF("setUTCMonth", 2, set_date_field, 0x130 ), JS_CFUNC_DEF("setYear", 1, js_date_setYear ), JS_CFUNC_MAGIC_DEF("setFullYear", 3, set_date_field, 0x031 ), JS_CFUNC_MAGIC_DEF("setUTCFullYear", 3, set_date_field, 0x030 ), JS_CFUNC_DEF("toJSON", 1, js_date_toJSON ), }; JSValue JS_NewDate(JSContext *ctx, double epoch_ms) { JSValue obj = js_create_from_ctor(ctx, JS_UNDEFINED, JS_CLASS_DATE); if (JS_IsException(obj)) return JS_EXCEPTION; JS_SetObjectData(ctx, obj, __JS_NewFloat64(ctx, time_clip(epoch_ms))); return obj; } int JS_AddIntrinsicDate(JSContext *ctx) { JSValue obj; /* Date */ obj = JS_NewCConstructor(ctx, JS_CLASS_DATE, "Date", js_date_constructor, 7, JS_CFUNC_constructor_or_func, 0, JS_UNDEFINED, js_date_funcs, countof(js_date_funcs), js_date_proto_funcs, countof(js_date_proto_funcs), 0); if (JS_IsException(obj)) return -1; JS_FreeValue(ctx, obj); return 0; } /* eval */ int JS_AddIntrinsicEval(JSContext *ctx) { ctx->eval_internal = __JS_EvalInternal; return 0; } /* BigInt */ static JSValue JS_ToBigIntCtorFree(JSContext *ctx, JSValue val) { uint32_t tag; redo: tag = JS_VALUE_GET_NORM_TAG(val); switch(tag) { case JS_TAG_INT: case JS_TAG_BOOL: val = JS_NewBigInt64(ctx, JS_VALUE_GET_INT(val)); break; case JS_TAG_SHORT_BIG_INT: case JS_TAG_BIG_INT: break; case JS_TAG_FLOAT64: { double d = JS_VALUE_GET_FLOAT64(val); JSBigInt *r; int res; r = js_bigint_from_float64(ctx, &res, d); if (!r) { if (res == 0) { val = JS_EXCEPTION; } else if (res == 1) { val = JS_ThrowRangeError(ctx, "cannot convert to BigInt: not an integer"); } else { val = JS_ThrowRangeError(ctx, "cannot convert NaN or Infinity to BigInt"); } } else { val = JS_CompactBigInt(ctx, r); } } break; case JS_TAG_STRING: case JS_TAG_STRING_ROPE: val = JS_StringToBigIntErr(ctx, val); break; case JS_TAG_OBJECT: val = JS_ToPrimitiveFree(ctx, val, HINT_NUMBER); if (JS_IsException(val)) break; goto redo; case JS_TAG_NULL: case JS_TAG_UNDEFINED: default: JS_FreeValue(ctx, val); return JS_ThrowTypeError(ctx, "cannot convert to BigInt"); } return val; } static JSValue js_bigint_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { if (!JS_IsUndefined(new_target)) return JS_ThrowTypeErrorNotAConstructor(ctx, new_target); return JS_ToBigIntCtorFree(ctx, JS_DupValue(ctx, argv[0])); } static JSValue js_thisBigIntValue(JSContext *ctx, JSValueConst this_val) { if (JS_IsBigInt(ctx, this_val)) return JS_DupValue(ctx, this_val); if (JS_VALUE_GET_TAG(this_val) == JS_TAG_OBJECT) { JSObject *p = JS_VALUE_GET_OBJ(this_val); if (p->class_id == JS_CLASS_BIG_INT) { if (JS_IsBigInt(ctx, p->u.object_data)) return JS_DupValue(ctx, p->u.object_data); } } return JS_ThrowTypeError(ctx, "not a BigInt"); } static JSValue js_bigint_toString(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue val; int base; JSValue ret; val = js_thisBigIntValue(ctx, this_val); if (JS_IsException(val)) return val; if (argc == 0 || JS_IsUndefined(argv[0])) { base = 10; } else { base = js_get_radix(ctx, argv[0]); if (base < 0) goto fail; } ret = js_bigint_to_string1(ctx, val, base); JS_FreeValue(ctx, val); return ret; fail: JS_FreeValue(ctx, val); return JS_EXCEPTION; } static JSValue js_bigint_valueOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return js_thisBigIntValue(ctx, this_val); } static JSValue js_bigint_asUintN(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int asIntN) { uint64_t bits; JSValue res, a; if (JS_ToIndex(ctx, &bits, argv[0])) return JS_EXCEPTION; a = JS_ToBigInt(ctx, argv[1]); if (JS_IsException(a)) return JS_EXCEPTION; if (bits == 0) { JS_FreeValue(ctx, a); res = __JS_NewShortBigInt(ctx, 0); } else if (JS_VALUE_GET_TAG(a) == JS_TAG_SHORT_BIG_INT) { /* fast case */ if (bits >= JS_SHORT_BIG_INT_BITS) { res = a; } else { uint64_t v; int shift; shift = 64 - bits; v = JS_VALUE_GET_SHORT_BIG_INT(a); v = v << shift; if (asIntN) v = (int64_t)v >> shift; else v = v >> shift; res = __JS_NewShortBigInt(ctx, v); } } else { JSBigInt *r, *p = JS_VALUE_GET_PTR(a); if (bits >= p->len * JS_LIMB_BITS) { res = a; } else { int len, shift, i; js_limb_t v; len = (bits + JS_LIMB_BITS - 1) / JS_LIMB_BITS; r = js_bigint_new(ctx, len); if (!r) { JS_FreeValue(ctx, a); return JS_EXCEPTION; } r->len = len; for(i = 0; i < len - 1; i++) r->tab[i] = p->tab[i]; shift = (-bits) & (JS_LIMB_BITS - 1); /* 0 <= shift <= JS_LIMB_BITS - 1 */ v = p->tab[len - 1] << shift; if (asIntN) v = (js_slimb_t)v >> shift; else v = v >> shift; r->tab[len - 1] = v; r = js_bigint_normalize(ctx, r); JS_FreeValue(ctx, a); res = JS_CompactBigInt(ctx, r); } } return res; } static const JSCFunctionListEntry js_bigint_funcs[] = { JS_CFUNC_MAGIC_DEF("asUintN", 2, js_bigint_asUintN, 0 ), JS_CFUNC_MAGIC_DEF("asIntN", 2, js_bigint_asUintN, 1 ), }; static const JSCFunctionListEntry js_bigint_proto_funcs[] = { JS_CFUNC_DEF("toString", 0, js_bigint_toString ), JS_CFUNC_DEF("valueOf", 0, js_bigint_valueOf ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "BigInt", JS_PROP_CONFIGURABLE ), }; static int JS_AddIntrinsicBigInt(JSContext *ctx) { JSValue obj1; obj1 = JS_NewCConstructor(ctx, JS_CLASS_BIG_INT, "BigInt", js_bigint_constructor, 1, JS_CFUNC_constructor_or_func, 0, JS_UNDEFINED, js_bigint_funcs, countof(js_bigint_funcs), js_bigint_proto_funcs, countof(js_bigint_proto_funcs), 0); if (JS_IsException(obj1)) return -1; JS_FreeValue(ctx, obj1); return 0; } /* Minimum amount of objects to be able to compile code and display error messages. */ static int JS_AddIntrinsicBasicObjects(JSContext *ctx) { JSValue obj; JSCFunctionType ft; int i; /* warning: ordering is tricky */ ctx->class_proto[JS_CLASS_OBJECT] = JS_NewObjectProtoClassAlloc(ctx, JS_NULL, JS_CLASS_OBJECT, countof(js_object_proto_funcs) + 1); if (JS_IsException(ctx->class_proto[JS_CLASS_OBJECT])) return -1; JS_SetImmutablePrototype(ctx, ctx->class_proto[JS_CLASS_OBJECT]); /* 2 more properties: caller and arguments */ ctx->function_proto = JS_NewCFunction3(ctx, js_function_proto, "", 0, JS_CFUNC_generic, 0, ctx->class_proto[JS_CLASS_OBJECT], countof(js_function_proto_funcs) + 3 + 2); if (JS_IsException(ctx->function_proto)) return -1; ctx->class_proto[JS_CLASS_BYTECODE_FUNCTION] = JS_DupValue(ctx, ctx->function_proto); ctx->global_obj = JS_NewObjectProtoClassAlloc(ctx, ctx->class_proto[JS_CLASS_OBJECT], JS_CLASS_GLOBAL_OBJECT, 64); if (JS_IsException(ctx->global_obj)) return -1; { JSObject *p; obj = JS_NewObjectProtoClassAlloc(ctx, JS_NULL, JS_CLASS_OBJECT, 4); p = JS_VALUE_GET_OBJ(ctx->global_obj); p->u.global_object.uninitialized_vars = obj; } ctx->global_var_obj = JS_NewObjectProtoClassAlloc(ctx, JS_NULL, JS_CLASS_OBJECT, 16); if (JS_IsException(ctx->global_var_obj)) return -1; /* Error */ ft.generic_magic = js_error_constructor; obj = JS_NewCConstructor(ctx, JS_CLASS_ERROR, "Error", ft.generic, 1, JS_CFUNC_constructor_or_func_magic, -1, JS_UNDEFINED, js_error_funcs, countof(js_error_funcs), js_error_proto_funcs, countof(js_error_proto_funcs), 0); if (JS_IsException(obj)) return -1; for(i = 0; i < JS_NATIVE_ERROR_COUNT; i++) { JSValue func_obj; const JSCFunctionListEntry *funcs; int n_args; char buf[ATOM_GET_STR_BUF_SIZE]; const char *name = JS_AtomGetStr(ctx, buf, sizeof(buf), JS_ATOM_EvalError + i); n_args = 1 + (i == JS_AGGREGATE_ERROR); funcs = js_native_error_proto_funcs + 2 * i; func_obj = JS_NewCConstructor(ctx, -1, name, ft.generic, n_args, JS_CFUNC_constructor_or_func_magic, i, obj, NULL, 0, funcs, 2, 0); if (JS_IsException(func_obj)) { JS_FreeValue(ctx, obj); return -1; } ctx->native_error_proto[i] = JS_GetProperty(ctx, func_obj, JS_ATOM_prototype); JS_FreeValue(ctx, func_obj); if (JS_IsException(ctx->native_error_proto[i])) { JS_FreeValue(ctx, obj); return -1; } } JS_FreeValue(ctx, obj); /* Array */ obj = JS_NewCConstructor(ctx, JS_CLASS_ARRAY, "Array", js_array_constructor, 1, JS_CFUNC_constructor_or_func, 0, JS_UNDEFINED, js_array_funcs, countof(js_array_funcs), js_array_proto_funcs, countof(js_array_proto_funcs), JS_NEW_CTOR_PROTO_CLASS); if (JS_IsException(obj)) return -1; ctx->array_ctor = obj; { JSObject *p = JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_ARRAY]); p->is_std_array_prototype = TRUE; } ctx->array_shape = js_new_shape2(ctx, get_proto_obj(ctx->class_proto[JS_CLASS_ARRAY]), JS_PROP_INITIAL_HASH_SIZE, 1); if (!ctx->array_shape) return -1; if (add_shape_property(ctx, &ctx->array_shape, NULL, JS_ATOM_length, JS_PROP_WRITABLE | JS_PROP_LENGTH)) return -1; ctx->arguments_shape = js_new_shape2(ctx, get_proto_obj(ctx->class_proto[JS_CLASS_OBJECT]), JS_PROP_INITIAL_HASH_SIZE, 3); if (!ctx->arguments_shape) return -1; if (add_shape_property(ctx, &ctx->arguments_shape, NULL, JS_ATOM_length, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE)) return -1; if (add_shape_property(ctx, &ctx->arguments_shape, NULL, JS_ATOM_Symbol_iterator, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE)) return -1; if (add_shape_property(ctx, &ctx->arguments_shape, NULL, JS_ATOM_callee, JS_PROP_GETSET)) return -1; ctx->mapped_arguments_shape = js_new_shape2(ctx, get_proto_obj(ctx->class_proto[JS_CLASS_OBJECT]), JS_PROP_INITIAL_HASH_SIZE, 3); if (!ctx->mapped_arguments_shape) return -1; if (add_shape_property(ctx, &ctx->mapped_arguments_shape, NULL, JS_ATOM_length, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE)) return -1; if (add_shape_property(ctx, &ctx->mapped_arguments_shape, NULL, JS_ATOM_Symbol_iterator, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE)) return -1; if (add_shape_property(ctx, &ctx->mapped_arguments_shape, NULL, JS_ATOM_callee, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE)) return -1; return 0; } int JS_AddIntrinsicBaseObjects(JSContext *ctx) { JSValue obj1, obj2; JSCFunctionType ft; ctx->throw_type_error = JS_NewCFunction(ctx, js_throw_type_error, NULL, 0); if (JS_IsException(ctx->throw_type_error)) return -1; /* add caller and arguments properties to throw a TypeError */ if (JS_DefineProperty(ctx, ctx->function_proto, JS_ATOM_caller, JS_UNDEFINED, ctx->throw_type_error, ctx->throw_type_error, JS_PROP_HAS_GET | JS_PROP_HAS_SET | JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE) < 0) return -1; if (JS_DefineProperty(ctx, ctx->function_proto, JS_ATOM_arguments, JS_UNDEFINED, ctx->throw_type_error, ctx->throw_type_error, JS_PROP_HAS_GET | JS_PROP_HAS_SET | JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE) < 0) return -1; JS_FreeValue(ctx, js_object_seal(ctx, JS_UNDEFINED, 1, (JSValueConst *)&ctx->throw_type_error, 1)); /* Object */ obj1 = JS_NewCConstructor(ctx, JS_CLASS_OBJECT, "Object", js_object_constructor, 1, JS_CFUNC_constructor_or_func, 0, JS_UNDEFINED, js_object_funcs, countof(js_object_funcs), js_object_proto_funcs, countof(js_object_proto_funcs), JS_NEW_CTOR_PROTO_EXIST); if (JS_IsException(obj1)) return -1; JS_FreeValue(ctx, obj1); /* Function */ ft.generic_magic = js_function_constructor; obj1 = JS_NewCConstructor(ctx, JS_CLASS_BYTECODE_FUNCTION, "Function", ft.generic, 1, JS_CFUNC_constructor_or_func_magic, JS_FUNC_NORMAL, JS_UNDEFINED, NULL, 0, js_function_proto_funcs, countof(js_function_proto_funcs), JS_NEW_CTOR_PROTO_EXIST); if (JS_IsException(obj1)) return -1; ctx->function_ctor = obj1; /* Iterator */ obj2 = JS_NewCConstructor(ctx, JS_CLASS_ITERATOR, "Iterator", js_iterator_constructor, 0, JS_CFUNC_constructor_or_func, 0, JS_UNDEFINED, js_iterator_funcs, countof(js_iterator_funcs), js_iterator_proto_funcs, countof(js_iterator_proto_funcs), 0); if (JS_IsException(obj2)) return -1; // quirk: Iterator.prototype.constructor is an accessor property // TODO(bnoordhuis) mildly inefficient because JS_NewGlobalCConstructor // first creates a .constructor value property that we then replace with // an accessor obj1 = JS_NewCFunctionData(ctx, js_iterator_constructor_getset, 0, 0, 1, (JSValueConst *)&obj2); if (JS_IsException(obj1)) { JS_FreeValue(ctx, obj2); return -1; } if (JS_DefineProperty(ctx, ctx->class_proto[JS_CLASS_ITERATOR], JS_ATOM_constructor, JS_UNDEFINED, obj1, obj1, JS_PROP_HAS_GET | JS_PROP_HAS_SET | JS_PROP_CONFIGURABLE) < 0) { JS_FreeValue(ctx, obj2); JS_FreeValue(ctx, obj1); return -1; } JS_FreeValue(ctx, obj1); ctx->iterator_ctor = obj2; ctx->class_proto[JS_CLASS_ITERATOR_CONCAT] = JS_NewObjectProtoList(ctx, ctx->class_proto[JS_CLASS_ITERATOR], js_iterator_concat_proto_funcs, countof(js_iterator_concat_proto_funcs)); if (JS_IsException(ctx->class_proto[JS_CLASS_ITERATOR_CONCAT])) return -1; ctx->class_proto[JS_CLASS_ITERATOR_HELPER] = JS_NewObjectProtoList(ctx, ctx->class_proto[JS_CLASS_ITERATOR], js_iterator_helper_proto_funcs, countof(js_iterator_helper_proto_funcs)); if (JS_IsException(ctx->class_proto[JS_CLASS_ITERATOR_HELPER])) return -1; ctx->class_proto[JS_CLASS_ITERATOR_WRAP] = JS_NewObjectProtoList(ctx, ctx->class_proto[JS_CLASS_ITERATOR], js_iterator_wrap_proto_funcs, countof(js_iterator_wrap_proto_funcs)); if (JS_IsException(ctx->class_proto[JS_CLASS_ITERATOR_WRAP])) return -1; /* needed to initialize arguments[Symbol.iterator] */ ctx->array_proto_values = JS_GetProperty(ctx, ctx->class_proto[JS_CLASS_ARRAY], JS_ATOM_values); if (JS_IsException(ctx->array_proto_values)) return -1; ctx->class_proto[JS_CLASS_ARRAY_ITERATOR] = JS_NewObjectProtoList(ctx, ctx->class_proto[JS_CLASS_ITERATOR], js_array_iterator_proto_funcs, countof(js_array_iterator_proto_funcs)); if (JS_IsException(ctx->class_proto[JS_CLASS_ARRAY_ITERATOR])) return -1; /* parseFloat and parseInteger must be defined before Number because of the Number.parseFloat and Number.parseInteger aliases */ if (JS_SetPropertyFunctionList(ctx, ctx->global_obj, js_global_funcs, countof(js_global_funcs))) return -1; /* Number */ obj1 = JS_NewCConstructor(ctx, JS_CLASS_NUMBER, "Number", js_number_constructor, 1, JS_CFUNC_constructor_or_func, 0, JS_UNDEFINED, js_number_funcs, countof(js_number_funcs), js_number_proto_funcs, countof(js_number_proto_funcs), JS_NEW_CTOR_PROTO_CLASS); if (JS_IsException(obj1)) return -1; JS_FreeValue(ctx, obj1); if (JS_SetObjectData(ctx, ctx->class_proto[JS_CLASS_NUMBER], JS_NewInt32(ctx, 0))) return -1; /* Boolean */ obj1 = JS_NewCConstructor(ctx, JS_CLASS_BOOLEAN, "Boolean", js_boolean_constructor, 1, JS_CFUNC_constructor_or_func, 0, JS_UNDEFINED, NULL, 0, js_boolean_proto_funcs, countof(js_boolean_proto_funcs), JS_NEW_CTOR_PROTO_CLASS); if (JS_IsException(obj1)) return -1; JS_FreeValue(ctx, obj1); if (JS_SetObjectData(ctx, ctx->class_proto[JS_CLASS_BOOLEAN], JS_NewBool(ctx, FALSE))) return -1; /* String */ obj1 = JS_NewCConstructor(ctx, JS_CLASS_STRING, "String", js_string_constructor, 1, JS_CFUNC_constructor_or_func, 0, JS_UNDEFINED, js_string_funcs, countof(js_string_funcs), js_string_proto_funcs, countof(js_string_proto_funcs), JS_NEW_CTOR_PROTO_CLASS); if (JS_IsException(obj1)) return -1; JS_FreeValue(ctx, obj1); if (JS_SetObjectData(ctx, ctx->class_proto[JS_CLASS_STRING], JS_AtomToString(ctx, JS_ATOM_empty_string))) return -1; ctx->class_proto[JS_CLASS_STRING_ITERATOR] = JS_NewObjectProtoList(ctx, ctx->class_proto[JS_CLASS_ITERATOR], js_string_iterator_proto_funcs, countof(js_string_iterator_proto_funcs)); if (JS_IsException(ctx->class_proto[JS_CLASS_STRING_ITERATOR])) return -1; /* Math: create as autoinit object */ js_random_init(ctx); if (JS_SetPropertyFunctionList(ctx, ctx->global_obj, js_math_obj, countof(js_math_obj))) return -1; /* ES6 Reflect: create as autoinit object */ if (JS_SetPropertyFunctionList(ctx, ctx->global_obj, js_reflect_obj, countof(js_reflect_obj))) return -1; /* ES6 Symbol */ obj1 = JS_NewCConstructor(ctx, JS_CLASS_SYMBOL, "Symbol", js_symbol_constructor, 0, JS_CFUNC_constructor_or_func, 0, JS_UNDEFINED, js_symbol_funcs, countof(js_symbol_funcs), js_symbol_proto_funcs, countof(js_symbol_proto_funcs), 0); if (JS_IsException(obj1)) return -1; JS_FreeValue(ctx, obj1); /* ES6 Generator */ ctx->class_proto[JS_CLASS_GENERATOR] = JS_NewObjectProtoList(ctx, ctx->class_proto[JS_CLASS_ITERATOR], js_generator_proto_funcs, countof(js_generator_proto_funcs)); if (JS_IsException(ctx->class_proto[JS_CLASS_GENERATOR])) return -1; ft.generic_magic = js_function_constructor; obj1 = JS_NewCConstructor(ctx, JS_CLASS_GENERATOR_FUNCTION, "GeneratorFunction", ft.generic, 1, JS_CFUNC_constructor_or_func_magic, JS_FUNC_GENERATOR, ctx->function_ctor, NULL, 0, js_generator_function_proto_funcs, countof(js_generator_function_proto_funcs), JS_NEW_CTOR_NO_GLOBAL | JS_NEW_CTOR_READONLY); if (JS_IsException(obj1)) return -1; JS_FreeValue(ctx, obj1); if (JS_SetConstructor2(ctx, ctx->class_proto[JS_CLASS_GENERATOR_FUNCTION], ctx->class_proto[JS_CLASS_GENERATOR], JS_PROP_CONFIGURABLE, JS_PROP_CONFIGURABLE)) return -1; /* global properties */ ctx->eval_obj = JS_GetProperty(ctx, ctx->global_obj, JS_ATOM_eval); if (JS_IsException(ctx->eval_obj)) return -1; if (JS_DefinePropertyValue(ctx, ctx->global_obj, JS_ATOM_globalThis, JS_DupValue(ctx, ctx->global_obj), JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE) < 0) return -1; /* BigInt */ if (JS_AddIntrinsicBigInt(ctx)) return -1; return 0; } /* Typed Arrays */ static uint8_t const typed_array_size_log2[JS_TYPED_ARRAY_COUNT] = { 0, 0, 0, 1, 1, 2, 2, 3, 3, // BigInt64Array, BigUint64Array 1, 2, 3 // Float16Array, Float32Array, Float64Array }; static JSValue js_array_buffer_constructor3(JSContext *ctx, JSValueConst new_target, uint64_t len, uint64_t *max_len, JSClassID class_id, uint8_t *buf, JSFreeArrayBufferDataFunc *free_func, void *opaque, BOOL alloc_flag) { JSRuntime *rt = ctx->rt; JSValue obj; JSArrayBuffer *abuf = NULL; uint64_t sab_alloc_len; if (!alloc_flag && buf && max_len && free_func != js_array_buffer_free) { // not observable from JS land, only through C API misuse; // JS code cannot create externally managed buffers directly return JS_ThrowInternalError(ctx, "resizable ArrayBuffers not supported " "for externally managed buffers"); } obj = js_create_from_ctor(ctx, new_target, class_id); if (JS_IsException(obj)) return obj; /* XXX: we are currently limited to 2 GB */ if (len > INT32_MAX) { JS_ThrowRangeError(ctx, "invalid array buffer length"); goto fail; } if (max_len && *max_len > INT32_MAX) { JS_ThrowRangeError(ctx, "invalid max array buffer length"); goto fail; } abuf = js_malloc(ctx, sizeof(*abuf)); if (!abuf) goto fail; abuf->byte_length = len; abuf->max_byte_length = max_len ? *max_len : -1; if (alloc_flag) { if (class_id == JS_CLASS_SHARED_ARRAY_BUFFER && rt->sab_funcs.sab_alloc) { // TOOD(bnoordhuis) resizing backing memory for SABs atomically // is hard so we cheat and allocate |maxByteLength| bytes upfront sab_alloc_len = max_len ? *max_len : len; abuf->data = rt->sab_funcs.sab_alloc(rt->sab_funcs.sab_opaque, max_int(sab_alloc_len, 1)); if (!abuf->data) goto fail; memset(abuf->data, 0, sab_alloc_len); } else { /* the allocation must be done after the object creation */ abuf->data = js_mallocz(ctx, max_int(len, 1)); if (!abuf->data) goto fail; } } else { if (class_id == JS_CLASS_SHARED_ARRAY_BUFFER && rt->sab_funcs.sab_dup) { rt->sab_funcs.sab_dup(rt->sab_funcs.sab_opaque, buf); } abuf->data = buf; } init_list_head(&abuf->array_list); abuf->detached = FALSE; abuf->shared = (class_id == JS_CLASS_SHARED_ARRAY_BUFFER); abuf->opaque = opaque; abuf->free_func = free_func; if (alloc_flag && buf) memcpy(abuf->data, buf, len); JS_SetOpaque(obj, abuf); return obj; fail: JS_FreeValue(ctx, obj); js_free(ctx, abuf); return JS_EXCEPTION; } static void js_array_buffer_free(JSRuntime *rt, void *opaque, void *ptr) { js_free_rt(rt, ptr); } static JSValue js_array_buffer_constructor2(JSContext *ctx, JSValueConst new_target, uint64_t len, uint64_t *max_len, JSClassID class_id) { return js_array_buffer_constructor3(ctx, new_target, len, max_len, class_id, NULL, js_array_buffer_free, NULL, TRUE); } static JSValue js_array_buffer_constructor1(JSContext *ctx, JSValueConst new_target, uint64_t len, uint64_t *max_len) { return js_array_buffer_constructor2(ctx, new_target, len, max_len, JS_CLASS_ARRAY_BUFFER); } JSValue JS_NewArrayBuffer(JSContext *ctx, uint8_t *buf, size_t len, JSFreeArrayBufferDataFunc *free_func, void *opaque, BOOL is_shared) { JSClassID class_id = is_shared ? JS_CLASS_SHARED_ARRAY_BUFFER : JS_CLASS_ARRAY_BUFFER; return js_array_buffer_constructor3(ctx, JS_UNDEFINED, len, NULL, class_id, buf, free_func, opaque, FALSE); } /* create a new ArrayBuffer of length 'len' and copy 'buf' to it */ JSValue JS_NewArrayBufferCopy(JSContext *ctx, const uint8_t *buf, size_t len) { return js_array_buffer_constructor3(ctx, JS_UNDEFINED, len, NULL, JS_CLASS_ARRAY_BUFFER, (uint8_t *)buf, js_array_buffer_free, NULL, TRUE); } static JSValue js_array_buffer_constructor0(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv, JSClassID class_id) { uint64_t len, max_len, *pmax_len = NULL; JSValue obj, val; int64_t i; if (JS_ToIndex(ctx, &len, argv[0])) return JS_EXCEPTION; if (argc < 2) goto next; if (!JS_IsObject(argv[1])) goto next; obj = JS_ToObject(ctx, argv[1]); if (JS_IsException(obj)) return JS_EXCEPTION; val = JS_GetProperty(ctx, obj, JS_ATOM_maxByteLength); JS_FreeValue(ctx, obj); if (JS_IsException(val)) return JS_EXCEPTION; if (JS_IsUndefined(val)) goto next; if (JS_ToInt64Free(ctx, &i, val)) return JS_EXCEPTION; // don't have to check i < 0 because len >= 0 if (len > i || i > MAX_SAFE_INTEGER) return JS_ThrowRangeError(ctx, "invalid array buffer max length"); max_len = i; pmax_len = &max_len; next: return js_array_buffer_constructor2(ctx, new_target, len, pmax_len, class_id); } static JSValue js_array_buffer_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { return js_array_buffer_constructor0(ctx, new_target, argc, argv, JS_CLASS_ARRAY_BUFFER); } static JSValue js_shared_array_buffer_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { return js_array_buffer_constructor0(ctx, new_target, argc, argv, JS_CLASS_SHARED_ARRAY_BUFFER); } /* also used for SharedArrayBuffer */ static void js_array_buffer_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); JSArrayBuffer *abuf = p->u.array_buffer; struct list_head *el, *el1; if (abuf) { /* The ArrayBuffer finalizer may be called before the typed array finalizers using it, so abuf->array_list is not necessarily empty. */ list_for_each_safe(el, el1, &abuf->array_list) { JSTypedArray *ta; JSObject *p1; ta = list_entry(el, JSTypedArray, link); ta->link.prev = NULL; ta->link.next = NULL; p1 = ta->obj; /* Note: the typed array length and offset fields are not modified */ if (p1->class_id != JS_CLASS_DATAVIEW) { p1->u.array.count = 0; p1->u.array.u.ptr = NULL; } } if (abuf->shared && rt->sab_funcs.sab_free) { rt->sab_funcs.sab_free(rt->sab_funcs.sab_opaque, abuf->data); } else { if (abuf->free_func) abuf->free_func(rt, abuf->opaque, abuf->data); } js_free_rt(rt, abuf); } } static JSValue js_array_buffer_isView(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSObject *p; BOOL res; res = FALSE; if (JS_VALUE_GET_TAG(argv[0]) == JS_TAG_OBJECT) { p = JS_VALUE_GET_OBJ(argv[0]); if (p->class_id >= JS_CLASS_UINT8C_ARRAY && p->class_id <= JS_CLASS_DATAVIEW) { res = TRUE; } } return JS_NewBool(ctx, res); } static const JSCFunctionListEntry js_array_buffer_funcs[] = { JS_CFUNC_DEF("isView", 1, js_array_buffer_isView ), JS_CGETSET_DEF("[Symbol.species]", js_get_this, NULL ), }; static JSValue JS_ThrowTypeErrorDetachedArrayBuffer(JSContext *ctx) { return JS_ThrowTypeError(ctx, "ArrayBuffer is detached"); } static JSValue JS_ThrowTypeErrorArrayBufferOOB(JSContext *ctx) { return JS_ThrowTypeError(ctx, "ArrayBuffer is detached or resized"); } // #sec-get-arraybuffer.prototype.detached static JSValue js_array_buffer_get_detached(JSContext *ctx, JSValueConst this_val) { JSArrayBuffer *abuf = JS_GetOpaque2(ctx, this_val, JS_CLASS_ARRAY_BUFFER); if (!abuf) return JS_EXCEPTION; if (abuf->shared) return JS_ThrowTypeError(ctx, "detached called on SharedArrayBuffer"); return JS_NewBool(ctx, abuf->detached); } static JSValue js_array_buffer_get_byteLength(JSContext *ctx, JSValueConst this_val, int class_id) { JSArrayBuffer *abuf = JS_GetOpaque2(ctx, this_val, class_id); if (!abuf) return JS_EXCEPTION; /* return 0 if detached */ return JS_NewUint32(ctx, abuf->byte_length); } static JSValue js_array_buffer_get_maxByteLength(JSContext *ctx, JSValueConst this_val, int class_id) { JSArrayBuffer *abuf = JS_GetOpaque2(ctx, this_val, class_id); if (!abuf) return JS_EXCEPTION; if (array_buffer_is_resizable(abuf)) return JS_NewUint32(ctx, abuf->max_byte_length); return JS_NewUint32(ctx, abuf->byte_length); } static JSValue js_array_buffer_get_resizable(JSContext *ctx, JSValueConst this_val, int class_id) { JSArrayBuffer *abuf = JS_GetOpaque2(ctx, this_val, class_id); if (!abuf) return JS_EXCEPTION; return JS_NewBool(ctx, array_buffer_is_resizable(abuf)); } static void js_array_buffer_update_typed_arrays(JSArrayBuffer *abuf) { uint32_t size_log2, size_elem; struct list_head *el; JSTypedArray *ta; JSObject *p; uint8_t *data; int64_t len; len = abuf->byte_length; data = abuf->data; // update lengths of all typed arrays backed by this array buffer list_for_each(el, &abuf->array_list) { ta = list_entry(el, JSTypedArray, link); p = ta->obj; if (p->class_id == JS_CLASS_DATAVIEW) { if (ta->track_rab) { if (ta->offset < len) ta->length = len - ta->offset; else ta->length = 0; } } else { p->u.array.count = 0; p->u.array.u.ptr = NULL; size_log2 = typed_array_size_log2(p->class_id); size_elem = 1 << size_log2; if (ta->track_rab) { if (len >= (int64_t)ta->offset + size_elem) { p->u.array.count = (len - ta->offset) >> size_log2; p->u.array.u.ptr = &data[ta->offset]; } } else { if (len >= (int64_t)ta->offset + ta->length) { p->u.array.count = ta->length >> size_log2; p->u.array.u.ptr = &data[ta->offset]; } } } } } void JS_DetachArrayBuffer(JSContext *ctx, JSValueConst obj) { JSArrayBuffer *abuf = JS_GetOpaque(obj, JS_CLASS_ARRAY_BUFFER); if (!abuf || abuf->detached) return; if (abuf->free_func) abuf->free_func(ctx->rt, abuf->opaque, abuf->data); abuf->data = NULL; abuf->byte_length = 0; abuf->detached = TRUE; js_array_buffer_update_typed_arrays(abuf); } /* get an ArrayBuffer or SharedArrayBuffer */ static JSArrayBuffer *js_get_array_buffer(JSContext *ctx, JSValueConst obj) { JSObject *p; if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) goto fail; p = JS_VALUE_GET_OBJ(obj); if (p->class_id != JS_CLASS_ARRAY_BUFFER && p->class_id != JS_CLASS_SHARED_ARRAY_BUFFER) { fail: JS_ThrowTypeErrorInvalidClass(ctx, JS_CLASS_ARRAY_BUFFER); return NULL; } return p->u.array_buffer; } /* return NULL if exception. WARNING: any JS call can detach the buffer and render the returned pointer invalid */ uint8_t *JS_GetArrayBuffer(JSContext *ctx, size_t *psize, JSValueConst obj) { JSArrayBuffer *abuf = js_get_array_buffer(ctx, obj); if (!abuf) goto fail; if (abuf->detached) { JS_ThrowTypeErrorDetachedArrayBuffer(ctx); goto fail; } *psize = abuf->byte_length; return abuf->data; fail: *psize = 0; return NULL; } static BOOL array_buffer_is_resizable(const JSArrayBuffer *abuf) { return abuf->max_byte_length >= 0; } // ES #sec-arraybuffer.prototype.transfer static JSValue js_array_buffer_transfer(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int transfer_to_fixed_length) { JSArrayBuffer *abuf; uint64_t new_len, *pmax_len, max_len; abuf = JS_GetOpaque2(ctx, this_val, JS_CLASS_ARRAY_BUFFER); if (!abuf) return JS_EXCEPTION; if (abuf->shared) return JS_ThrowTypeError(ctx, "cannot transfer a SharedArrayBuffer"); if (argc < 1 || JS_IsUndefined(argv[0])) new_len = abuf->byte_length; else if (JS_ToIndex(ctx, &new_len, argv[0])) return JS_EXCEPTION; if (abuf->detached) return JS_ThrowTypeErrorDetachedArrayBuffer(ctx); pmax_len = NULL; if (!transfer_to_fixed_length) { if (array_buffer_is_resizable(abuf)) { // carry over maxByteLength max_len = abuf->max_byte_length; if (new_len > max_len) return JS_ThrowTypeError(ctx, "invalid array buffer length"); // TODO(bnoordhuis) support externally managed RABs if (abuf->free_func == js_array_buffer_free) pmax_len = &max_len; } } /* create an empty AB */ if (new_len == 0) { JS_DetachArrayBuffer(ctx, this_val); return js_array_buffer_constructor2(ctx, JS_UNDEFINED, 0, pmax_len, JS_CLASS_ARRAY_BUFFER); } else { uint64_t old_len; uint8_t *bs, *new_bs; JSFreeArrayBufferDataFunc *free_func; bs = abuf->data; old_len = abuf->byte_length; free_func = abuf->free_func; /* if length mismatch, realloc. Otherwise, use the same backing buffer. */ if (new_len != old_len) { /* XXX: we are currently limited to 2 GB */ if (new_len > INT32_MAX) return JS_ThrowRangeError(ctx, "invalid array buffer length"); if (free_func != js_array_buffer_free) { /* cannot use js_realloc() because the buffer was allocated with a custom allocator */ new_bs = js_mallocz(ctx, new_len); if (!new_bs) return JS_EXCEPTION; memcpy(new_bs, bs, min_int(old_len, new_len)); abuf->free_func(ctx->rt, abuf->opaque, bs); bs = new_bs; free_func = js_array_buffer_free; } else { new_bs = js_realloc(ctx, bs, new_len); if (!new_bs) return JS_EXCEPTION; bs = new_bs; if (new_len > old_len) memset(bs + old_len, 0, new_len - old_len); } } /* neuter the backing buffer */ abuf->data = NULL; abuf->byte_length = 0; abuf->detached = TRUE; js_array_buffer_update_typed_arrays(abuf); return js_array_buffer_constructor3(ctx, JS_UNDEFINED, new_len, pmax_len, JS_CLASS_ARRAY_BUFFER, bs, free_func, NULL, FALSE); } } static JSValue js_array_buffer_resize(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int class_id) { JSArrayBuffer *abuf; uint8_t *data; int64_t len; abuf = JS_GetOpaque2(ctx, this_val, class_id); if (!abuf) return JS_EXCEPTION; if (JS_ToInt64(ctx, &len, argv[0])) return JS_EXCEPTION; if (abuf->detached) return JS_ThrowTypeErrorDetachedArrayBuffer(ctx); if (!array_buffer_is_resizable(abuf)) return JS_ThrowTypeError(ctx, "array buffer is not resizable"); // TODO(bnoordhuis) support externally managed RABs if (abuf->free_func != js_array_buffer_free) return JS_ThrowTypeError(ctx, "external array buffer is not resizable"); if (len < 0 || len > abuf->max_byte_length) { bad_length: return JS_ThrowRangeError(ctx, "invalid array buffer length"); } // SABs can only grow and we don't need to realloc because // js_array_buffer_constructor3 commits all memory upfront; // regular RABs are resizable both ways and realloc if (abuf->shared) { if (len < abuf->byte_length) goto bad_length; // Note this is off-spec; there's supposed to be a single atomic // |byteLength| property that's shared across SABs but we store // it per SAB instead. That means when thread A calls sab.grow(2) // at time t0, and thread B calls sab.grow(1) at time t1, we don't // throw a TypeError in thread B as the spec says we should, // instead both threads get their own view of the backing memory, // 2 bytes big in A, and 1 byte big in B abuf->byte_length = len; } else { data = js_realloc(ctx, abuf->data, max_int(len, 1)); if (!data) return JS_EXCEPTION; if (len > abuf->byte_length) memset(&data[abuf->byte_length], 0, len - abuf->byte_length); abuf->byte_length = len; abuf->data = data; } js_array_buffer_update_typed_arrays(abuf); return JS_UNDEFINED; } static JSValue js_array_buffer_slice(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int class_id) { JSArrayBuffer *abuf, *new_abuf; int64_t len, start, end, new_len; JSValue ctor, new_obj; abuf = JS_GetOpaque2(ctx, this_val, class_id); if (!abuf) return JS_EXCEPTION; if (abuf->detached) return JS_ThrowTypeErrorDetachedArrayBuffer(ctx); len = abuf->byte_length; if (JS_ToInt64Clamp(ctx, &start, argv[0], 0, len, len)) return JS_EXCEPTION; end = len; if (!JS_IsUndefined(argv[1])) { if (JS_ToInt64Clamp(ctx, &end, argv[1], 0, len, len)) return JS_EXCEPTION; } new_len = max_int64(end - start, 0); ctor = JS_SpeciesConstructor(ctx, this_val, JS_UNDEFINED); if (JS_IsException(ctor)) return ctor; if (JS_IsUndefined(ctor)) { new_obj = js_array_buffer_constructor2(ctx, JS_UNDEFINED, new_len, NULL, class_id); } else { JSValue args[1]; args[0] = JS_NewInt64(ctx, new_len); new_obj = JS_CallConstructor(ctx, ctor, 1, (JSValueConst *)args); JS_FreeValue(ctx, ctor); JS_FreeValue(ctx, args[0]); } if (JS_IsException(new_obj)) return new_obj; new_abuf = JS_GetOpaque2(ctx, new_obj, class_id); if (!new_abuf) goto fail; if (js_same_value(ctx, new_obj, this_val)) { JS_ThrowTypeError(ctx, "cannot use identical ArrayBuffer"); goto fail; } if (new_abuf->detached) { JS_ThrowTypeErrorDetachedArrayBuffer(ctx); goto fail; } if (new_abuf->byte_length < new_len) { JS_ThrowTypeError(ctx, "new ArrayBuffer is too small"); goto fail; } /* must test again because of side effects */ if (abuf->detached || abuf->byte_length < start + new_len) { JS_ThrowTypeErrorDetachedArrayBuffer(ctx); goto fail; } memcpy(new_abuf->data, abuf->data + start, new_len); return new_obj; fail: JS_FreeValue(ctx, new_obj); return JS_EXCEPTION; } static const JSCFunctionListEntry js_array_buffer_proto_funcs[] = { JS_CGETSET_MAGIC_DEF("byteLength", js_array_buffer_get_byteLength, NULL, JS_CLASS_ARRAY_BUFFER ), JS_CGETSET_MAGIC_DEF("maxByteLength", js_array_buffer_get_maxByteLength, NULL, JS_CLASS_ARRAY_BUFFER ), JS_CGETSET_MAGIC_DEF("resizable", js_array_buffer_get_resizable, NULL, JS_CLASS_ARRAY_BUFFER ), JS_CGETSET_DEF("detached", js_array_buffer_get_detached, NULL ), JS_CFUNC_MAGIC_DEF("resize", 1, js_array_buffer_resize, JS_CLASS_ARRAY_BUFFER ), JS_CFUNC_MAGIC_DEF("slice", 2, js_array_buffer_slice, JS_CLASS_ARRAY_BUFFER ), JS_CFUNC_MAGIC_DEF("transfer", 0, js_array_buffer_transfer, 0 ), JS_CFUNC_MAGIC_DEF("transferToFixedLength", 0, js_array_buffer_transfer, 1 ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "ArrayBuffer", JS_PROP_CONFIGURABLE ), }; /* SharedArrayBuffer */ static const JSCFunctionListEntry js_shared_array_buffer_funcs[] = { JS_CGETSET_DEF("[Symbol.species]", js_get_this, NULL ), }; static const JSCFunctionListEntry js_shared_array_buffer_proto_funcs[] = { JS_CGETSET_MAGIC_DEF("byteLength", js_array_buffer_get_byteLength, NULL, JS_CLASS_SHARED_ARRAY_BUFFER ), JS_CGETSET_MAGIC_DEF("maxByteLength", js_array_buffer_get_maxByteLength, NULL, JS_CLASS_SHARED_ARRAY_BUFFER ), JS_CGETSET_MAGIC_DEF("growable", js_array_buffer_get_resizable, NULL, JS_CLASS_SHARED_ARRAY_BUFFER ), JS_CFUNC_MAGIC_DEF("grow", 1, js_array_buffer_resize, JS_CLASS_SHARED_ARRAY_BUFFER ), JS_CFUNC_MAGIC_DEF("slice", 2, js_array_buffer_slice, JS_CLASS_SHARED_ARRAY_BUFFER ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "SharedArrayBuffer", JS_PROP_CONFIGURABLE ), }; static JSObject *get_typed_array(JSContext *ctx, JSValueConst this_val) { JSObject *p; if (JS_VALUE_GET_TAG(this_val) != JS_TAG_OBJECT) goto fail; p = JS_VALUE_GET_OBJ(this_val); if (!(p->class_id >= JS_CLASS_UINT8C_ARRAY && p->class_id <= JS_CLASS_FLOAT64_ARRAY)) { fail: JS_ThrowTypeError(ctx, "not a TypedArray"); return NULL; } return p; } // is the typed array detached or out of bounds relative to its RAB? // |p| must be a typed array, *not* a DataView static BOOL typed_array_is_oob(JSObject *p) { JSArrayBuffer *abuf; JSTypedArray *ta; int len, size_elem; int64_t end; assert(p->class_id >= JS_CLASS_UINT8C_ARRAY); assert(p->class_id <= JS_CLASS_FLOAT64_ARRAY); ta = p->u.typed_array; abuf = ta->buffer->u.array_buffer; if (abuf->detached) return TRUE; len = abuf->byte_length; if (ta->offset > len) return TRUE; if (ta->track_rab) return FALSE; if (len < (int64_t)ta->offset + ta->length) return TRUE; size_elem = 1 << typed_array_size_log2(p->class_id); end = (int64_t)ta->offset + (int64_t)p->u.array.count * size_elem; return end > len; } // Be *very* careful if you touch the typed array's memory directly: // the length is only valid until the next call into JS land because // JS code can detach or resize the backing array buffer. Functions // like JS_GetProperty and JS_ToIndex call JS code. // // Exclusively reading or writing elements with JS_GetProperty, // JS_GetPropertyInt64, JS_SetProperty, etc. is safe because they // perform bounds checks, as does js_get_fast_array_element. static int js_typed_array_get_length_unsafe(JSContext *ctx, JSValueConst obj) { JSObject *p; p = get_typed_array(ctx, obj); if (!p) return -1; if (typed_array_is_oob(p)) { JS_ThrowTypeErrorArrayBufferOOB(ctx); return -1; } return p->u.array.count; } static int validate_typed_array(JSContext *ctx, JSValueConst this_val) { JSObject *p; p = get_typed_array(ctx, this_val); if (!p) return -1; if (typed_array_is_oob(p)) { JS_ThrowTypeErrorArrayBufferOOB(ctx); return -1; } return 0; } static JSValue js_typed_array_get_length(JSContext *ctx, JSValueConst this_val) { JSObject *p; p = get_typed_array(ctx, this_val); if (!p) return JS_EXCEPTION; return JS_NewInt32(ctx, p->u.array.count); } static JSValue js_typed_array_get_buffer(JSContext *ctx, JSValueConst this_val) { JSObject *p; JSTypedArray *ta; p = get_typed_array(ctx, this_val); if (!p) return JS_EXCEPTION; ta = p->u.typed_array; return JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, ta->buffer)); } static JSValue js_typed_array_get_byteLength(JSContext *ctx, JSValueConst this_val) { JSObject *p; JSTypedArray *ta; int size_log2; p = get_typed_array(ctx, this_val); if (!p) return JS_EXCEPTION; if (typed_array_is_oob(p)) return JS_NewInt32(ctx, 0); ta = p->u.typed_array; if (!ta->track_rab) return JS_NewUint32(ctx, ta->length); size_log2 = typed_array_size_log2(p->class_id); return JS_NewInt64(ctx, (int64_t)p->u.array.count << size_log2); } static JSValue js_typed_array_get_byteOffset(JSContext *ctx, JSValueConst this_val) { JSObject *p; JSTypedArray *ta; p = get_typed_array(ctx, this_val); if (!p) return JS_EXCEPTION; if (typed_array_is_oob(p)) return JS_NewInt32(ctx, 0); ta = p->u.typed_array; return JS_NewUint32(ctx, ta->offset); } JSValue JS_NewTypedArray(JSContext *ctx, int argc, JSValueConst *argv, JSTypedArrayEnum type) { if (type < JS_TYPED_ARRAY_UINT8C || type > JS_TYPED_ARRAY_FLOAT64) return JS_ThrowRangeError(ctx, "invalid typed array type"); return js_typed_array_constructor(ctx, JS_UNDEFINED, argc, argv, JS_CLASS_UINT8C_ARRAY + type); } /* Return the buffer associated to the typed array or an exception if it is not a typed array or if the buffer is detached. pbyte_offset, pbyte_length or pbytes_per_element can be NULL. */ JSValue JS_GetTypedArrayBuffer(JSContext *ctx, JSValueConst obj, size_t *pbyte_offset, size_t *pbyte_length, size_t *pbytes_per_element) { JSObject *p; JSTypedArray *ta; p = get_typed_array(ctx, obj); if (!p) return JS_EXCEPTION; if (typed_array_is_oob(p)) return JS_ThrowTypeErrorArrayBufferOOB(ctx); ta = p->u.typed_array; if (pbyte_offset) *pbyte_offset = ta->offset; if (pbyte_length) *pbyte_length = ta->length; if (pbytes_per_element) { *pbytes_per_element = 1 << typed_array_size_log2(p->class_id); } return JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, ta->buffer)); } static JSValue js_typed_array_get_toStringTag(JSContext *ctx, JSValueConst this_val) { JSObject *p; if (JS_VALUE_GET_TAG(this_val) != JS_TAG_OBJECT) return JS_UNDEFINED; p = JS_VALUE_GET_OBJ(this_val); if (!(p->class_id >= JS_CLASS_UINT8C_ARRAY && p->class_id <= JS_CLASS_FLOAT64_ARRAY)) return JS_UNDEFINED; return JS_AtomToString(ctx, ctx->rt->class_array[p->class_id].class_name); } static JSValue js_typed_array_set_internal(JSContext *ctx, JSValueConst dst, JSValueConst src, JSValueConst off) { JSObject *p; JSObject *src_p; uint32_t i; int64_t dst_len, src_len, offset; JSValue val, src_obj = JS_UNDEFINED; p = get_typed_array(ctx, dst); if (!p) goto fail; if (JS_ToInt64Sat(ctx, &offset, off)) goto fail; if (offset < 0) goto range_error; if (typed_array_is_oob(p)) { detached: JS_ThrowTypeErrorArrayBufferOOB(ctx); goto fail; } dst_len = p->u.array.count; src_obj = JS_ToObject(ctx, src); if (JS_IsException(src_obj)) goto fail; src_p = JS_VALUE_GET_OBJ(src_obj); if (src_p->class_id >= JS_CLASS_UINT8C_ARRAY && src_p->class_id <= JS_CLASS_FLOAT64_ARRAY) { JSTypedArray *dest_ta = p->u.typed_array; JSArrayBuffer *dest_abuf = dest_ta->buffer->u.array_buffer; JSTypedArray *src_ta = src_p->u.typed_array; JSArrayBuffer *src_abuf = src_ta->buffer->u.array_buffer; int shift = typed_array_size_log2(p->class_id); if (typed_array_is_oob(src_p)) goto detached; src_len = src_p->u.array.count; if (offset > dst_len - src_len) goto range_error; /* copying between typed objects */ if (src_p->class_id == p->class_id) { /* same type, use memmove */ memmove(dest_abuf->data + dest_ta->offset + (offset << shift), src_abuf->data + src_ta->offset, src_len << shift); goto done; } if (dest_abuf->data == src_abuf->data) { /* copying between the same buffer using different types of mappings would require a temporary buffer */ } /* otherwise, default behavior is slow but correct */ } else { // can change |dst| as a side effect; per spec, // perform the range check against its old length if (js_get_length64(ctx, &src_len, src_obj)) goto fail; if (offset > dst_len - src_len) { range_error: JS_ThrowRangeError(ctx, "invalid array length"); goto fail; } } for(i = 0; i < src_len; i++) { val = JS_GetPropertyUint32(ctx, src_obj, i); if (JS_IsException(val)) goto fail; if (JS_SetPropertyUint32(ctx, dst, offset + i, val) < 0) goto fail; } done: JS_FreeValue(ctx, src_obj); return JS_UNDEFINED; fail: JS_FreeValue(ctx, src_obj); return JS_EXCEPTION; } static JSValue js_typed_array_at(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSObject *p; int64_t idx, len; p = get_typed_array(ctx, this_val); if (!p) return JS_EXCEPTION; if (typed_array_is_oob(p)) return JS_ThrowTypeErrorDetachedArrayBuffer(ctx); len = p->u.array.count; // note: can change p->u.array.count if (JS_ToInt64Sat(ctx, &idx, argv[0])) return JS_EXCEPTION; if (idx < 0) idx = len + idx; len = p->u.array.count; if (idx < 0 || idx >= len) return JS_UNDEFINED; return JS_GetPropertyInt64(ctx, this_val, idx); } static JSValue js_typed_array_with(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue arr, val; JSObject *p; int64_t idx, len; p = get_typed_array(ctx, this_val); if (!p) return JS_EXCEPTION; if (typed_array_is_oob(p)) return JS_ThrowTypeErrorDetachedArrayBuffer(ctx); len = p->u.array.count; if (JS_ToInt64Sat(ctx, &idx, argv[0])) return JS_EXCEPTION; if (idx < 0) idx = len + idx; val = JS_ToPrimitive(ctx, argv[1], HINT_NUMBER); if (JS_IsException(val)) return JS_EXCEPTION; if (typed_array_is_oob(p) || idx < 0 || idx >= p->u.array.count) return JS_ThrowRangeError(ctx, "invalid array index"); /* warning: 'this_val' may have been resized, so 'len' may be larger than its length */ arr = js_typed_array_constructor_ta(ctx, JS_UNDEFINED, this_val, p->class_id, len); if (JS_IsException(arr)) { JS_FreeValue(ctx, val); return JS_EXCEPTION; } if (JS_SetPropertyInt64(ctx, arr, idx, val) < 0) { JS_FreeValue(ctx, arr); return JS_EXCEPTION; } return arr; } static JSValue js_typed_array_set(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValueConst offset = JS_UNDEFINED; if (argc > 1) { offset = argv[1]; } return js_typed_array_set_internal(ctx, this_val, argv[0], offset); } static JSValue js_create_typed_array_iterator(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) { if (validate_typed_array(ctx, this_val)) return JS_EXCEPTION; return js_create_array_iterator(ctx, this_val, argc, argv, magic); } static JSValue js_typed_array_create(JSContext *ctx, JSValueConst ctor, int argc, JSValueConst *argv) { JSValue ret; int new_len; int64_t len; ret = JS_CallConstructor(ctx, ctor, argc, argv); if (JS_IsException(ret)) return ret; /* validate the typed array */ new_len = js_typed_array_get_length_unsafe(ctx, ret); if (new_len < 0) goto fail; if (argc == 1) { /* ensure that it is large enough */ if (JS_ToLengthFree(ctx, &len, JS_DupValue(ctx, argv[0]))) goto fail; if (new_len < len) { JS_ThrowTypeError(ctx, "TypedArray length is too small"); fail: JS_FreeValue(ctx, ret); return JS_EXCEPTION; } } return ret; } #if 0 static JSValue js_typed_array___create(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return js_typed_array_create(ctx, argv[0], max_int(argc - 1, 0), argv + 1); } #endif static JSValue js_typed_array___speciesCreate(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValueConst obj; JSObject *p; JSValue ctor, ret; int argc1; obj = argv[0]; p = get_typed_array(ctx, obj); if (!p) return JS_EXCEPTION; ctor = JS_SpeciesConstructor(ctx, obj, JS_UNDEFINED); if (JS_IsException(ctor)) return ctor; argc1 = max_int(argc - 1, 0); if (JS_IsUndefined(ctor)) { ret = js_typed_array_constructor(ctx, JS_UNDEFINED, argc1, argv + 1, p->class_id); } else { ret = js_typed_array_create(ctx, ctor, argc1, argv + 1); JS_FreeValue(ctx, ctor); } return ret; } static JSValue js_typed_array_from(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { // from(items, mapfn = void 0, this_arg = void 0) JSValueConst items = argv[0], mapfn, this_arg; JSValueConst args[2]; JSValue iter, arr, r, v, v2; int64_t k, len; int mapping; mapping = FALSE; mapfn = JS_UNDEFINED; this_arg = JS_UNDEFINED; r = JS_UNDEFINED; arr = JS_UNDEFINED; iter = JS_UNDEFINED; if (argc > 1) { mapfn = argv[1]; if (!JS_IsUndefined(mapfn)) { if (check_function(ctx, mapfn)) goto exception; mapping = 1; if (argc > 2) this_arg = argv[2]; } } iter = JS_GetProperty(ctx, items, JS_ATOM_Symbol_iterator); if (JS_IsException(iter)) goto exception; if (!JS_IsUndefined(iter) && !JS_IsNull(iter)) { uint32_t len1; if (!JS_IsFunction(ctx, iter)) { JS_ThrowTypeError(ctx, "value is not iterable"); goto exception; } arr = js_array_from_iterator(ctx, &len1, items, iter); if (JS_IsException(arr)) goto exception; len = len1; } else { arr = JS_ToObject(ctx, items); if (JS_IsException(arr)) goto exception; if (js_get_length64(ctx, &len, arr) < 0) goto exception; } v = JS_NewInt64(ctx, len); args[0] = v; r = js_typed_array_create(ctx, this_val, 1, args); JS_FreeValue(ctx, v); if (JS_IsException(r)) goto exception; for(k = 0; k < len; k++) { v = JS_GetPropertyInt64(ctx, arr, k); if (JS_IsException(v)) goto exception; if (mapping) { args[0] = v; args[1] = JS_NewInt32(ctx, k); v2 = JS_Call(ctx, mapfn, this_arg, 2, args); JS_FreeValue(ctx, v); v = v2; if (JS_IsException(v)) goto exception; } if (JS_SetPropertyInt64(ctx, r, k, v) < 0) goto exception; } goto done; exception: JS_FreeValue(ctx, r); r = JS_EXCEPTION; done: JS_FreeValue(ctx, arr); JS_FreeValue(ctx, iter); return r; } static JSValue js_typed_array_of(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue obj; JSValueConst args[1]; int i; args[0] = JS_NewInt32(ctx, argc); obj = js_typed_array_create(ctx, this_val, 1, args); if (JS_IsException(obj)) return obj; for(i = 0; i < argc; i++) { if (JS_SetPropertyUint32(ctx, obj, i, JS_DupValue(ctx, argv[i])) < 0) { JS_FreeValue(ctx, obj); return JS_EXCEPTION; } } return obj; } static JSValue js_typed_array_copyWithin(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSObject *p; int len, to, from, final, count, shift, space; p = get_typed_array(ctx, this_val); if (!p) return JS_EXCEPTION; if (typed_array_is_oob(p)) return JS_ThrowTypeErrorArrayBufferOOB(ctx); len = p->u.array.count; if (JS_ToInt32Clamp(ctx, &to, argv[0], 0, len, len)) return JS_EXCEPTION; if (JS_ToInt32Clamp(ctx, &from, argv[1], 0, len, len)) return JS_EXCEPTION; final = len; if (argc > 2 && !JS_IsUndefined(argv[2])) { if (JS_ToInt32Clamp(ctx, &final, argv[2], 0, len, len)) return JS_EXCEPTION; } if (typed_array_is_oob(p)) return JS_ThrowTypeErrorArrayBufferOOB(ctx); // RAB may have been resized by evil .valueOf method space = p->u.array.count - max_int(to, from); count = min_int(final - from, len - to); count = min_int(count, space); if (count > 0) { shift = typed_array_size_log2(p->class_id); memmove(p->u.array.u.uint8_ptr + (to << shift), p->u.array.u.uint8_ptr + (from << shift), count << shift); } return JS_DupValue(ctx, this_val); } static JSValue js_typed_array_fill(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSObject *p; int len, k, final, shift; uint64_t v64; p = get_typed_array(ctx, this_val); if (!p) return JS_EXCEPTION; if (typed_array_is_oob(p)) return JS_ThrowTypeErrorArrayBufferOOB(ctx); len = p->u.array.count; if (p->class_id == JS_CLASS_UINT8C_ARRAY) { int32_t v; if (JS_ToUint8ClampFree(ctx, &v, JS_DupValue(ctx, argv[0]))) return JS_EXCEPTION; v64 = v; } else if (p->class_id <= JS_CLASS_UINT32_ARRAY) { uint32_t v; if (JS_ToUint32(ctx, &v, argv[0])) return JS_EXCEPTION; v64 = v; } else if (p->class_id <= JS_CLASS_BIG_UINT64_ARRAY) { if (JS_ToBigInt64(ctx, (int64_t *)&v64, argv[0])) return JS_EXCEPTION; } else { double d; if (JS_ToFloat64(ctx, &d, argv[0])) return JS_EXCEPTION; if (p->class_id == JS_CLASS_FLOAT16_ARRAY) { v64 = tofp16(d); } else if (p->class_id == JS_CLASS_FLOAT32_ARRAY) { union { float f; uint32_t u32; } u; u.f = d; v64 = u.u32; } else { JSFloat64Union u; u.d = d; v64 = u.u64; } } k = 0; if (argc > 1) { if (JS_ToInt32Clamp(ctx, &k, argv[1], 0, len, len)) return JS_EXCEPTION; } final = len; if (argc > 2 && !JS_IsUndefined(argv[2])) { if (JS_ToInt32Clamp(ctx, &final, argv[2], 0, len, len)) return JS_EXCEPTION; } if (typed_array_is_oob(p)) return JS_ThrowTypeErrorArrayBufferOOB(ctx); // RAB may have been resized by evil .valueOf method final = min_int(final, p->u.array.count); shift = typed_array_size_log2(p->class_id); switch(shift) { case 0: if (k < final) { memset(p->u.array.u.uint8_ptr + k, v64, final - k); } break; case 1: for(; k < final; k++) { p->u.array.u.uint16_ptr[k] = v64; } break; case 2: for(; k < final; k++) { p->u.array.u.uint32_ptr[k] = v64; } break; case 3: for(; k < final; k++) { p->u.array.u.uint64_ptr[k] = v64; } break; default: abort(); } return JS_DupValue(ctx, this_val); } static JSValue js_typed_array_find(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int mode) { JSValueConst func, this_arg; JSValueConst args[3]; JSValue val, index_val, res; int len, k, end; int dir; val = JS_UNDEFINED; len = js_typed_array_get_length_unsafe(ctx, this_val); if (len < 0) goto exception; func = argv[0]; if (check_function(ctx, func)) goto exception; this_arg = JS_UNDEFINED; if (argc > 1) this_arg = argv[1]; k = 0; dir = 1; end = len; if (mode == ArrayFindLast || mode == ArrayFindLastIndex) { k = len - 1; dir = -1; end = -1; } for(; k != end; k += dir) { index_val = JS_NewInt32(ctx, k); val = JS_GetPropertyValue(ctx, this_val, index_val); if (JS_IsException(val)) goto exception; args[0] = val; args[1] = index_val; args[2] = this_val; res = JS_Call(ctx, func, this_arg, 3, args); if (JS_IsException(res)) goto exception; if (JS_ToBoolFree(ctx, res)) { if (mode == ArrayFindIndex || mode == ArrayFindLastIndex) { JS_FreeValue(ctx, val); return index_val; } else { return val; } } JS_FreeValue(ctx, val); } if (mode == ArrayFindIndex || mode == ArrayFindLastIndex) return JS_NewInt32(ctx, -1); else return JS_UNDEFINED; exception: JS_FreeValue(ctx, val); return JS_EXCEPTION; } #define special_indexOf 0 #define special_lastIndexOf 1 #define special_includes -1 static JSValue js_typed_array_indexOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int special) { JSObject *p; int len, tag, is_int, is_bigint, k, stop, inc, res = -1; int64_t v64; double d; float f; uint16_t hf; p = get_typed_array(ctx, this_val); if (!p) return JS_EXCEPTION; if (typed_array_is_oob(p)) return JS_ThrowTypeErrorArrayBufferOOB(ctx); len = p->u.array.count; if (len == 0) goto done; if (special == special_lastIndexOf) { k = len - 1; if (argc > 1) { int64_t k1; if (JS_ToInt64Clamp(ctx, &k1, argv[1], -1, len - 1, len)) goto exception; k = k1; if (k < 0) goto done; } stop = -1; inc = -1; } else { k = 0; if (argc > 1) { if (JS_ToInt32Clamp(ctx, &k, argv[1], 0, len, len)) goto exception; } stop = len; inc = 1; } /* includes function: 'undefined' can be found if searching out of bounds */ if (len > p->u.array.count && special == special_includes && JS_IsUndefined(argv[0]) && k < len) { res = 0; goto done; } // RAB may have been resized by evil .valueOf method len = min_int(len, p->u.array.count); if (len == 0) goto done; if (special == special_lastIndexOf) k = min_int(k, len - 1); else k = min_int(k, len); stop = min_int(stop, len); is_bigint = 0; is_int = 0; /* avoid warning */ v64 = 0; /* avoid warning */ tag = JS_VALUE_GET_NORM_TAG(argv[0]); if (tag == JS_TAG_INT) { is_int = 1; v64 = JS_VALUE_GET_INT(argv[0]); d = v64; } else if (tag == JS_TAG_FLOAT64) { d = JS_VALUE_GET_FLOAT64(argv[0]); if (d >= INT64_MIN && d < 0x1p63) { v64 = d; is_int = (v64 == d); } } else if (tag == JS_TAG_BIG_INT || tag == JS_TAG_SHORT_BIG_INT) { JSBigIntBuf buf1; JSBigInt *p1; int sz = (64 / JS_LIMB_BITS); if (tag == JS_TAG_SHORT_BIG_INT) p1 = js_bigint_set_short(&buf1, argv[0]); else p1 = JS_VALUE_GET_PTR(argv[0]); if (p->class_id == JS_CLASS_BIG_INT64_ARRAY) { if (p1->len > sz) goto done; /* does not fit an int64 : cannot be found */ } else if (p->class_id == JS_CLASS_BIG_UINT64_ARRAY) { if (js_bigint_sign(p1)) goto done; /* v < 0 */ if (p1->len <= sz) { /* OK */ } else if (p1->len == sz + 1 && p1->tab[sz] == 0) { /* 2^63 <= v <= 2^64-1 */ } else { goto done; } } else { goto done; } if (JS_ToBigInt64(ctx, &v64, argv[0])) goto exception; d = 0; is_bigint = 1; } else { goto done; } switch (p->class_id) { case JS_CLASS_INT8_ARRAY: if (is_int && (int8_t)v64 == v64) goto scan8; break; case JS_CLASS_UINT8C_ARRAY: case JS_CLASS_UINT8_ARRAY: if (is_int && (uint8_t)v64 == v64) { const uint8_t *pv, *pp; uint16_t v; scan8: pv = p->u.array.u.uint8_ptr; v = v64; if (inc > 0) { pp = NULL; if (pv) pp = memchr(pv + k, v, len - k); if (pp) res = pp - pv; } else { for (; k != stop; k += inc) { if (pv[k] == v) { res = k; break; } } } } break; case JS_CLASS_INT16_ARRAY: if (is_int && (int16_t)v64 == v64) goto scan16; break; case JS_CLASS_UINT16_ARRAY: if (is_int && (uint16_t)v64 == v64) { const uint16_t *pv; uint16_t v; scan16: pv = p->u.array.u.uint16_ptr; v = v64; for (; k != stop; k += inc) { if (pv[k] == v) { res = k; break; } } } break; case JS_CLASS_INT32_ARRAY: if (is_int && (int32_t)v64 == v64) goto scan32; break; case JS_CLASS_UINT32_ARRAY: if (is_int && (uint32_t)v64 == v64) { const uint32_t *pv; uint32_t v; scan32: pv = p->u.array.u.uint32_ptr; v = v64; for (; k != stop; k += inc) { if (pv[k] == v) { res = k; break; } } } break; case JS_CLASS_FLOAT16_ARRAY: if (is_bigint) break; if (isnan(d)) { const uint16_t *pv = p->u.array.u.fp16_ptr; /* special case: indexOf returns -1, includes finds NaN */ if (special != special_includes) goto done; for (; k != stop; k += inc) { if (isfp16nan(pv[k])) { res = k; break; } } } else if (d == 0) { // special case: includes also finds negative zero const uint16_t *pv = p->u.array.u.fp16_ptr; for (; k != stop; k += inc) { if (isfp16zero(pv[k])) { res = k; break; } } } else if (hf = tofp16(d), d == fromfp16(hf)) { const uint16_t *pv = p->u.array.u.fp16_ptr; for (; k != stop; k += inc) { if (pv[k] == hf) { res = k; break; } } } break; case JS_CLASS_FLOAT32_ARRAY: if (is_bigint) break; if (isnan(d)) { const float *pv = p->u.array.u.float_ptr; /* special case: indexOf returns -1, includes finds NaN */ if (special != special_includes) goto done; for (; k != stop; k += inc) { if (isnan(pv[k])) { res = k; break; } } } else if ((f = (float)d) == d) { const float *pv = p->u.array.u.float_ptr; for (; k != stop; k += inc) { if (pv[k] == f) { res = k; break; } } } break; case JS_CLASS_FLOAT64_ARRAY: if (is_bigint) break; if (isnan(d)) { const double *pv = p->u.array.u.double_ptr; /* special case: indexOf returns -1, includes finds NaN */ if (special != special_includes) goto done; for (; k != stop; k += inc) { if (isnan(pv[k])) { res = k; break; } } } else { const double *pv = p->u.array.u.double_ptr; for (; k != stop; k += inc) { if (pv[k] == d) { res = k; break; } } } break; case JS_CLASS_BIG_INT64_ARRAY: if (is_bigint) { goto scan64; } break; case JS_CLASS_BIG_UINT64_ARRAY: if (is_bigint) { const uint64_t *pv; uint64_t v; scan64: pv = p->u.array.u.uint64_ptr; v = v64; for (; k != stop; k += inc) { if (pv[k] == v) { res = k; break; } } } break; } done: if (special == special_includes) return JS_NewBool(ctx, res >= 0); else return JS_NewInt32(ctx, res); exception: return JS_EXCEPTION; } static JSValue js_typed_array_join(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int toLocaleString) { JSValue sep = JS_UNDEFINED, el; StringBuffer b_s, *b = &b_s; JSString *s = NULL; JSObject *p; int i, len, oldlen, newlen; int c; p = get_typed_array(ctx, this_val); if (!p) return JS_EXCEPTION; if (typed_array_is_oob(p)) return JS_ThrowTypeErrorArrayBufferOOB(ctx); len = oldlen = newlen = p->u.array.count; c = ','; /* default separator */ if (!toLocaleString && argc > 0 && !JS_IsUndefined(argv[0])) { sep = JS_ToString(ctx, argv[0]); if (JS_IsException(sep)) goto exception; s = JS_VALUE_GET_STRING(sep); if (s->len == 1 && !s->is_wide_char) c = s->u.str8[0]; else c = -1; // ToString(sep) can detach or resize the arraybuffer as a side effect newlen = p->u.array.count; len = min_int(len, newlen); } string_buffer_init(ctx, b, 0); /* XXX: optimize with direct access */ for(i = 0; i < len; i++) { if (i > 0) { if (c >= 0) { if (string_buffer_putc8(b, c)) goto fail; } else { if (string_buffer_concat(b, s, 0, s->len)) goto fail; } } el = JS_GetPropertyUint32(ctx, this_val, i); /* Can return undefined for example if the typed array is detached */ if (!JS_IsNull(el) && !JS_IsUndefined(el)) { if (JS_IsException(el)) goto fail; if (toLocaleString) { el = JS_ToLocaleStringFree(ctx, el); } if (string_buffer_concat_value_free(b, el)) goto fail; } } // add extra separators in case RAB was resized by evil .valueOf method i = max_int(1, newlen); for(/*empty*/; i < oldlen; i++) { if (c >= 0) { if (string_buffer_putc8(b, c)) goto fail; } else { if (string_buffer_concat(b, s, 0, s->len)) goto fail; } } JS_FreeValue(ctx, sep); return string_buffer_end(b); fail: string_buffer_free(b); JS_FreeValue(ctx, sep); exception: return JS_EXCEPTION; } static JSValue js_typed_array_reverse(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSObject *p; int len; len = js_typed_array_get_length_unsafe(ctx, this_val); if (len < 0) return JS_EXCEPTION; if (len > 0) { p = JS_VALUE_GET_OBJ(this_val); switch (typed_array_size_log2(p->class_id)) { case 0: { uint8_t *p1 = p->u.array.u.uint8_ptr; uint8_t *p2 = p1 + len - 1; while (p1 < p2) { uint8_t v = *p1; *p1++ = *p2; *p2-- = v; } } break; case 1: { uint16_t *p1 = p->u.array.u.uint16_ptr; uint16_t *p2 = p1 + len - 1; while (p1 < p2) { uint16_t v = *p1; *p1++ = *p2; *p2-- = v; } } break; case 2: { uint32_t *p1 = p->u.array.u.uint32_ptr; uint32_t *p2 = p1 + len - 1; while (p1 < p2) { uint32_t v = *p1; *p1++ = *p2; *p2-- = v; } } break; case 3: { uint64_t *p1 = p->u.array.u.uint64_ptr; uint64_t *p2 = p1 + len - 1; while (p1 < p2) { uint64_t v = *p1; *p1++ = *p2; *p2-- = v; } } break; default: abort(); } } return JS_DupValue(ctx, this_val); } static JSValue js_typed_array_toReversed(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue arr, ret; JSObject *p; p = get_typed_array(ctx, this_val); if (!p) return JS_EXCEPTION; arr = js_typed_array_constructor_ta(ctx, JS_UNDEFINED, this_val, p->class_id, p->u.array.count); if (JS_IsException(arr)) return JS_EXCEPTION; ret = js_typed_array_reverse(ctx, arr, argc, argv); JS_FreeValue(ctx, arr); return ret; } static void slice_memcpy(uint8_t *dst, const uint8_t *src, size_t len) { if (dst + len <= src || dst >= src + len) { /* no overlap: can use memcpy */ memcpy(dst, src, len); } else { /* otherwise the spec mandates byte copy */ while (len-- != 0) *dst++ = *src++; } } static JSValue js_typed_array_slice(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValueConst args[2]; JSValue arr, val; JSObject *p, *p1; int n, len, start, final, count, shift, space; arr = JS_UNDEFINED; p = get_typed_array(ctx, this_val); if (!p) goto exception; if (typed_array_is_oob(p)) return JS_ThrowTypeErrorArrayBufferOOB(ctx); len = p->u.array.count; if (JS_ToInt32Clamp(ctx, &start, argv[0], 0, len, len)) goto exception; final = len; if (!JS_IsUndefined(argv[1])) { if (JS_ToInt32Clamp(ctx, &final, argv[1], 0, len, len)) goto exception; } count = max_int(final - start, 0); shift = typed_array_size_log2(p->class_id); args[0] = this_val; args[1] = JS_NewInt32(ctx, count); arr = js_typed_array___speciesCreate(ctx, JS_UNDEFINED, 2, args); if (JS_IsException(arr)) goto exception; if (count > 0) { if (validate_typed_array(ctx, this_val) || validate_typed_array(ctx, arr)) goto exception; p1 = get_typed_array(ctx, arr); space = max_int(0, p->u.array.count - start); count = min_int(count, space); if (p1 != NULL && p->class_id == p1->class_id) { slice_memcpy(p1->u.array.u.uint8_ptr, p->u.array.u.uint8_ptr + (start << shift), count << shift); } else { for (n = 0; n < count; n++) { val = JS_GetPropertyValue(ctx, this_val, JS_NewInt32(ctx, start + n)); if (JS_IsException(val)) goto exception; if (JS_SetPropertyValue(ctx, arr, JS_NewInt32(ctx, n), val, JS_PROP_THROW) < 0) goto exception; } } } return arr; exception: JS_FreeValue(ctx, arr); return JS_EXCEPTION; } static JSValue js_typed_array_subarray(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValueConst args[4]; JSValue arr, ta_buffer; JSTypedArray *ta; JSObject *p; int len, start, final, count, shift, offset; BOOL is_auto; p = get_typed_array(ctx, this_val); if (!p) goto exception; len = p->u.array.count; if (JS_ToInt32Clamp(ctx, &start, argv[0], 0, len, len)) goto exception; shift = typed_array_size_log2(p->class_id); ta = p->u.typed_array; /* Read byteOffset (ta->offset) even if detached */ offset = ta->offset + (start << shift); final = len; if (JS_IsUndefined(argv[1])) { is_auto = ta->track_rab; } else { is_auto = FALSE; if (JS_ToInt32Clamp(ctx, &final, argv[1], 0, len, len)) goto exception; } count = max_int(final - start, 0); ta_buffer = js_typed_array_get_buffer(ctx, this_val); if (JS_IsException(ta_buffer)) goto exception; args[0] = this_val; args[1] = ta_buffer; args[2] = JS_NewInt32(ctx, offset); args[3] = JS_NewInt32(ctx, count); arr = js_typed_array___speciesCreate(ctx, JS_UNDEFINED, is_auto ? 3 : 4, args); JS_FreeValue(ctx, ta_buffer); return arr; exception: return JS_EXCEPTION; } /* TypedArray.prototype.sort */ static int js_cmp_doubles(double x, double y) { if (isnan(x)) return isnan(y) ? 0 : +1; if (isnan(y)) return -1; if (x < y) return -1; if (x > y) return 1; if (x != 0) return 0; if (signbit(x)) return signbit(y) ? 0 : -1; else return signbit(y) ? 1 : 0; } static int js_TA_cmp_int8(const void *a, const void *b, void *opaque) { return *(const int8_t *)a - *(const int8_t *)b; } static int js_TA_cmp_uint8(const void *a, const void *b, void *opaque) { return *(const uint8_t *)a - *(const uint8_t *)b; } static int js_TA_cmp_int16(const void *a, const void *b, void *opaque) { return *(const int16_t *)a - *(const int16_t *)b; } static int js_TA_cmp_uint16(const void *a, const void *b, void *opaque) { return *(const uint16_t *)a - *(const uint16_t *)b; } static int js_TA_cmp_int32(const void *a, const void *b, void *opaque) { int32_t x = *(const int32_t *)a; int32_t y = *(const int32_t *)b; return (y < x) - (y > x); } static int js_TA_cmp_uint32(const void *a, const void *b, void *opaque) { uint32_t x = *(const uint32_t *)a; uint32_t y = *(const uint32_t *)b; return (y < x) - (y > x); } static int js_TA_cmp_int64(const void *a, const void *b, void *opaque) { int64_t x = *(const int64_t *)a; int64_t y = *(const int64_t *)b; return (y < x) - (y > x); } static int js_TA_cmp_uint64(const void *a, const void *b, void *opaque) { uint64_t x = *(const uint64_t *)a; uint64_t y = *(const uint64_t *)b; return (y < x) - (y > x); } static int js_TA_cmp_float16(const void *a, const void *b, void *opaque) { return js_cmp_doubles(fromfp16(*(const uint16_t *)a), fromfp16(*(const uint16_t *)b)); } static int js_TA_cmp_float32(const void *a, const void *b, void *opaque) { return js_cmp_doubles(*(const float *)a, *(const float *)b); } static int js_TA_cmp_float64(const void *a, const void *b, void *opaque) { return js_cmp_doubles(*(const double *)a, *(const double *)b); } static JSValue js_TA_get_int8(JSContext *ctx, const void *a) { return JS_NewInt32(ctx, *(const int8_t *)a); } static JSValue js_TA_get_uint8(JSContext *ctx, const void *a) { return JS_NewInt32(ctx, *(const uint8_t *)a); } static JSValue js_TA_get_int16(JSContext *ctx, const void *a) { return JS_NewInt32(ctx, *(const int16_t *)a); } static JSValue js_TA_get_uint16(JSContext *ctx, const void *a) { return JS_NewInt32(ctx, *(const uint16_t *)a); } static JSValue js_TA_get_int32(JSContext *ctx, const void *a) { return JS_NewInt32(ctx, *(const int32_t *)a); } static JSValue js_TA_get_uint32(JSContext *ctx, const void *a) { return JS_NewUint32(ctx, *(const uint32_t *)a); } static JSValue js_TA_get_int64(JSContext *ctx, const void *a) { return JS_NewBigInt64(ctx, *(int64_t *)a); } static JSValue js_TA_get_uint64(JSContext *ctx, const void *a) { return JS_NewBigUint64(ctx, *(uint64_t *)a); } static JSValue js_TA_get_float16(JSContext *ctx, const void *a) { return __JS_NewFloat64(ctx, fromfp16(*(const uint16_t *)a)); } static JSValue js_TA_get_float32(JSContext *ctx, const void *a) { return __JS_NewFloat64(ctx, *(const float *)a); } static JSValue js_TA_get_float64(JSContext *ctx, const void *a) { return __JS_NewFloat64(ctx, *(const double *)a); } struct TA_sort_context { JSContext *ctx; int exception; /* 1 = exception, 2 = detached typed array */ uint8_t *array; JSValueConst cmp; JSValue (*getfun)(JSContext *ctx, const void *a); int elt_size; }; static int js_TA_cmp_generic(const void *a, const void *b, void *opaque) { struct TA_sort_context *psc = opaque; JSContext *ctx = psc->ctx; uint32_t a_idx, b_idx; JSValueConst argv[2]; JSValue res; int cmp; cmp = 0; if (!psc->exception) { /* Note: the typed array can be detached without causing an error */ a_idx = *(uint32_t *)a; b_idx = *(uint32_t *)b; argv[0] = psc->getfun(ctx, psc->array + a_idx * (size_t)psc->elt_size); argv[1] = psc->getfun(ctx, psc->array + b_idx * (size_t)(psc->elt_size)); res = JS_Call(ctx, psc->cmp, JS_UNDEFINED, 2, argv); if (JS_IsException(res)) { psc->exception = 1; goto done; } if (JS_VALUE_GET_TAG(res) == JS_TAG_INT) { int val = JS_VALUE_GET_INT(res); cmp = (val > 0) - (val < 0); } else { double val; if (JS_ToFloat64Free(ctx, &val, res) < 0) { psc->exception = 1; goto done; } else { cmp = (val > 0) - (val < 0); } } if (cmp == 0) { /* make sort stable: compare array offsets */ cmp = (a_idx > b_idx) - (a_idx < b_idx); } done: JS_FreeValue(ctx, (JSValue)argv[0]); JS_FreeValue(ctx, (JSValue)argv[1]); } return cmp; } static JSValue js_typed_array_sort(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSObject *p; int len; size_t elt_size; struct TA_sort_context tsc; int (*cmpfun)(const void *a, const void *b, void *opaque); tsc.ctx = ctx; tsc.exception = 0; tsc.cmp = argv[0]; if (!JS_IsUndefined(tsc.cmp) && check_function(ctx, tsc.cmp)) return JS_EXCEPTION; len = js_typed_array_get_length_unsafe(ctx, this_val); if (len < 0) return JS_EXCEPTION; if (len > 1) { p = JS_VALUE_GET_OBJ(this_val); switch (p->class_id) { case JS_CLASS_INT8_ARRAY: tsc.getfun = js_TA_get_int8; cmpfun = js_TA_cmp_int8; break; case JS_CLASS_UINT8C_ARRAY: case JS_CLASS_UINT8_ARRAY: tsc.getfun = js_TA_get_uint8; cmpfun = js_TA_cmp_uint8; break; case JS_CLASS_INT16_ARRAY: tsc.getfun = js_TA_get_int16; cmpfun = js_TA_cmp_int16; break; case JS_CLASS_UINT16_ARRAY: tsc.getfun = js_TA_get_uint16; cmpfun = js_TA_cmp_uint16; break; case JS_CLASS_INT32_ARRAY: tsc.getfun = js_TA_get_int32; cmpfun = js_TA_cmp_int32; break; case JS_CLASS_UINT32_ARRAY: tsc.getfun = js_TA_get_uint32; cmpfun = js_TA_cmp_uint32; break; case JS_CLASS_BIG_INT64_ARRAY: tsc.getfun = js_TA_get_int64; cmpfun = js_TA_cmp_int64; break; case JS_CLASS_BIG_UINT64_ARRAY: tsc.getfun = js_TA_get_uint64; cmpfun = js_TA_cmp_uint64; break; case JS_CLASS_FLOAT16_ARRAY: tsc.getfun = js_TA_get_float16; cmpfun = js_TA_cmp_float16; break; case JS_CLASS_FLOAT32_ARRAY: tsc.getfun = js_TA_get_float32; cmpfun = js_TA_cmp_float32; break; case JS_CLASS_FLOAT64_ARRAY: tsc.getfun = js_TA_get_float64; cmpfun = js_TA_cmp_float64; break; default: abort(); } elt_size = 1 << typed_array_size_log2(p->class_id); if (!JS_IsUndefined(tsc.cmp)) { uint32_t *array_idx; void *array; size_t i, j; /* the array must be copied because the comparison function may modify it */ array = js_malloc(ctx, len * elt_size); if (!array) return JS_EXCEPTION; memcpy(array, p->u.array.u.ptr, len * elt_size); /* array_idx is needed to have a stable sort */ array_idx = js_malloc(ctx, len * sizeof(array_idx[0])); if (!array_idx) { js_free(ctx, array); return JS_EXCEPTION; } for(i = 0; i < len; i++) array_idx[i] = i; tsc.elt_size = elt_size; tsc.array = array; rqsort(array_idx, len, sizeof(array_idx[0]), js_TA_cmp_generic, &tsc); if (tsc.exception) { if (tsc.exception == 1) { js_free(ctx, array_idx); js_free(ctx, array); return JS_EXCEPTION; } /* detached typed array during the sort: no error */ } else { void *array_ptr = p->u.array.u.ptr; len = min_int(len, p->u.array.count); switch(elt_size) { case 1: for(i = 0; i < len; i++) { j = array_idx[i]; ((uint8_t *)array_ptr)[i] = ((uint8_t *)array)[j]; } break; case 2: for(i = 0; i < len; i++) { j = array_idx[i]; ((uint16_t *)array_ptr)[i] = ((uint16_t *)array)[j]; } break; case 4: for(i = 0; i < len; i++) { j = array_idx[i]; ((uint32_t *)array_ptr)[i] = ((uint32_t *)array)[j]; } break; case 8: for(i = 0; i < len; i++) { j = array_idx[i]; ((uint64_t *)array_ptr)[i] = ((uint64_t *)array)[j]; } break; default: abort(); } } js_free(ctx, array_idx); js_free(ctx, array); } else { rqsort(p->u.array.u.ptr, len, elt_size, cmpfun, &tsc); if (tsc.exception) return JS_EXCEPTION; } } return JS_DupValue(ctx, this_val); } static JSValue js_typed_array_toSorted(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValue arr, ret; JSObject *p; p = get_typed_array(ctx, this_val); if (!p) return JS_EXCEPTION; arr = js_typed_array_constructor_ta(ctx, JS_UNDEFINED, this_val, p->class_id, p->u.array.count); if (JS_IsException(arr)) return JS_EXCEPTION; ret = js_typed_array_sort(ctx, arr, argc, argv); JS_FreeValue(ctx, arr); return ret; } static const JSCFunctionListEntry js_typed_array_base_funcs[] = { JS_CFUNC_DEF("from", 1, js_typed_array_from ), JS_CFUNC_DEF("of", 0, js_typed_array_of ), JS_CGETSET_DEF("[Symbol.species]", js_get_this, NULL ), }; static const JSCFunctionListEntry js_typed_array_base_proto_funcs[] = { JS_CGETSET_DEF("length", js_typed_array_get_length, NULL ), JS_CFUNC_DEF("at", 1, js_typed_array_at ), JS_CFUNC_DEF("with", 2, js_typed_array_with ), JS_CGETSET_DEF("buffer", js_typed_array_get_buffer, NULL ), JS_CGETSET_DEF("byteLength", js_typed_array_get_byteLength, NULL ), JS_CGETSET_DEF("byteOffset", js_typed_array_get_byteOffset, NULL ), JS_CFUNC_DEF("set", 1, js_typed_array_set ), JS_CFUNC_MAGIC_DEF("values", 0, js_create_typed_array_iterator, JS_ITERATOR_KIND_VALUE ), JS_ALIAS_DEF("[Symbol.iterator]", "values" ), JS_CFUNC_MAGIC_DEF("keys", 0, js_create_typed_array_iterator, JS_ITERATOR_KIND_KEY ), JS_CFUNC_MAGIC_DEF("entries", 0, js_create_typed_array_iterator, JS_ITERATOR_KIND_KEY_AND_VALUE ), JS_CGETSET_DEF("[Symbol.toStringTag]", js_typed_array_get_toStringTag, NULL ), JS_CFUNC_DEF("copyWithin", 2, js_typed_array_copyWithin ), JS_CFUNC_MAGIC_DEF("every", 1, js_array_every, special_every | special_TA ), JS_CFUNC_MAGIC_DEF("some", 1, js_array_every, special_some | special_TA ), JS_CFUNC_MAGIC_DEF("forEach", 1, js_array_every, special_forEach | special_TA ), JS_CFUNC_MAGIC_DEF("map", 1, js_array_every, special_map | special_TA ), JS_CFUNC_MAGIC_DEF("filter", 1, js_array_every, special_filter | special_TA ), JS_CFUNC_MAGIC_DEF("reduce", 1, js_array_reduce, special_reduce | special_TA ), JS_CFUNC_MAGIC_DEF("reduceRight", 1, js_array_reduce, special_reduceRight | special_TA ), JS_CFUNC_DEF("fill", 1, js_typed_array_fill ), JS_CFUNC_MAGIC_DEF("find", 1, js_typed_array_find, ArrayFind ), JS_CFUNC_MAGIC_DEF("findIndex", 1, js_typed_array_find, ArrayFindIndex ), JS_CFUNC_MAGIC_DEF("findLast", 1, js_typed_array_find, ArrayFindLast ), JS_CFUNC_MAGIC_DEF("findLastIndex", 1, js_typed_array_find, ArrayFindLastIndex ), JS_CFUNC_DEF("reverse", 0, js_typed_array_reverse ), JS_CFUNC_DEF("toReversed", 0, js_typed_array_toReversed ), JS_CFUNC_DEF("slice", 2, js_typed_array_slice ), JS_CFUNC_DEF("subarray", 2, js_typed_array_subarray ), JS_CFUNC_DEF("sort", 1, js_typed_array_sort ), JS_CFUNC_DEF("toSorted", 1, js_typed_array_toSorted ), JS_CFUNC_MAGIC_DEF("join", 1, js_typed_array_join, 0 ), JS_CFUNC_MAGIC_DEF("toLocaleString", 0, js_typed_array_join, 1 ), JS_CFUNC_MAGIC_DEF("indexOf", 1, js_typed_array_indexOf, special_indexOf ), JS_CFUNC_MAGIC_DEF("lastIndexOf", 1, js_typed_array_indexOf, special_lastIndexOf ), JS_CFUNC_MAGIC_DEF("includes", 1, js_typed_array_indexOf, special_includes ), //JS_ALIAS_BASE_DEF("toString", "toString", 2 /* Array.prototype. */), @@@ }; static const JSCFunctionListEntry js_typed_array_funcs[] = { JS_PROP_INT32_DEF("BYTES_PER_ELEMENT", 1, 0), JS_PROP_INT32_DEF("BYTES_PER_ELEMENT", 2, 0), JS_PROP_INT32_DEF("BYTES_PER_ELEMENT", 4, 0), JS_PROP_INT32_DEF("BYTES_PER_ELEMENT", 8, 0), }; static JSValue js_typed_array_base_constructor(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { return JS_ThrowTypeError(ctx, "cannot be called"); } /* 'obj' must be an allocated typed array object */ static int typed_array_init(JSContext *ctx, JSValueConst obj, JSValue buffer, uint64_t offset, uint64_t len, BOOL track_rab) { JSTypedArray *ta; JSObject *p, *pbuffer; JSArrayBuffer *abuf; int size_log2; p = JS_VALUE_GET_OBJ(obj); size_log2 = typed_array_size_log2(p->class_id); ta = js_malloc(ctx, sizeof(*ta)); if (!ta) { JS_FreeValue(ctx, buffer); return -1; } pbuffer = JS_VALUE_GET_OBJ(buffer); abuf = pbuffer->u.array_buffer; ta->obj = p; ta->buffer = pbuffer; ta->offset = offset; ta->length = len << size_log2; ta->track_rab = track_rab; list_add_tail(&ta->link, &abuf->array_list); p->u.typed_array = ta; p->u.array.count = len; p->u.array.u.ptr = abuf->data + offset; return 0; } static JSValue js_array_from_iterator(JSContext *ctx, uint32_t *plen, JSValueConst obj, JSValueConst method) { JSValue arr, iter, next_method = JS_UNDEFINED, val; BOOL done; uint32_t k; *plen = 0; arr = JS_NewArray(ctx); if (JS_IsException(arr)) return arr; iter = JS_GetIterator2(ctx, obj, method); if (JS_IsException(iter)) goto fail; next_method = JS_GetProperty(ctx, iter, JS_ATOM_next); if (JS_IsException(next_method)) goto fail; k = 0; for(;;) { val = JS_IteratorNext(ctx, iter, next_method, 0, NULL, &done); if (JS_IsException(val)) goto fail; if (done) break; if (JS_CreateDataPropertyUint32(ctx, arr, k, val, JS_PROP_THROW) < 0) goto fail; k++; } JS_FreeValue(ctx, next_method); JS_FreeValue(ctx, iter); *plen = k; return arr; fail: JS_FreeValue(ctx, next_method); JS_FreeValue(ctx, iter); JS_FreeValue(ctx, arr); return JS_EXCEPTION; } static JSValue js_typed_array_constructor_obj(JSContext *ctx, JSValueConst new_target, JSValueConst obj, int classid) { JSValue iter, ret, arr = JS_UNDEFINED, val, buffer; uint32_t i; int size_log2; int64_t len; size_log2 = typed_array_size_log2(classid); ret = js_create_from_ctor(ctx, new_target, classid); if (JS_IsException(ret)) return JS_EXCEPTION; iter = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_iterator); if (JS_IsException(iter)) goto fail; if (!JS_IsUndefined(iter) && !JS_IsNull(iter)) { uint32_t len1; arr = js_array_from_iterator(ctx, &len1, obj, iter); JS_FreeValue(ctx, iter); if (JS_IsException(arr)) goto fail; len = len1; } else { if (js_get_length64(ctx, &len, obj)) goto fail; arr = JS_DupValue(ctx, obj); } buffer = js_array_buffer_constructor1(ctx, JS_UNDEFINED, len << size_log2, NULL); if (JS_IsException(buffer)) goto fail; if (typed_array_init(ctx, ret, buffer, 0, len, /*track_rab*/FALSE)) goto fail; for(i = 0; i < len; i++) { val = JS_GetPropertyUint32(ctx, arr, i); if (JS_IsException(val)) goto fail; if (JS_SetPropertyUint32(ctx, ret, i, val) < 0) goto fail; } JS_FreeValue(ctx, arr); return ret; fail: JS_FreeValue(ctx, arr); JS_FreeValue(ctx, ret); return JS_EXCEPTION; } static JSValue js_typed_array_constructor_ta(JSContext *ctx, JSValueConst new_target, JSValueConst src_obj, int classid, uint32_t len) { JSObject *p, *src_buffer; JSTypedArray *ta; JSValue obj, buffer; uint32_t i; int size_log2; JSArrayBuffer *src_abuf, *abuf; obj = js_create_from_ctor(ctx, new_target, classid); if (JS_IsException(obj)) return obj; p = JS_VALUE_GET_OBJ(src_obj); if (typed_array_is_oob(p)) { JS_ThrowTypeErrorArrayBufferOOB(ctx); goto fail; } size_log2 = typed_array_size_log2(classid); buffer = js_array_buffer_constructor1(ctx, JS_UNDEFINED, (uint64_t)len << size_log2, NULL); if (JS_IsException(buffer)) goto fail; /* necessary because it could have been detached */ if (typed_array_is_oob(p)) { JS_FreeValue(ctx, buffer); JS_ThrowTypeErrorArrayBufferOOB(ctx); goto fail; } abuf = JS_GetOpaque(buffer, JS_CLASS_ARRAY_BUFFER); if (typed_array_init(ctx, obj, buffer, 0, len, /*track_rab*/FALSE)) goto fail; ta = p->u.typed_array; src_buffer = ta->buffer; src_abuf = src_buffer->u.array_buffer; if (p->class_id == classid && (int64_t)ta->offset + (int64_t)abuf->byte_length <= src_abuf->byte_length) { /* same type and no overflow: copy the content */ memcpy(abuf->data, src_abuf->data + ta->offset, abuf->byte_length); } else { for(i = 0; i < len; i++) { JSValue val; val = JS_GetPropertyUint32(ctx, src_obj, i); if (JS_IsException(val)) goto fail; if (JS_SetPropertyUint32(ctx, obj, i, val) < 0) goto fail; } } return obj; fail: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_typed_array_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv, int classid) { BOOL track_rab = FALSE; JSValue buffer, obj; JSArrayBuffer *abuf; int size_log2; uint64_t len, offset; size_log2 = typed_array_size_log2(classid); if (JS_VALUE_GET_TAG(argv[0]) != JS_TAG_OBJECT) { if (JS_ToIndex(ctx, &len, argv[0])) return JS_EXCEPTION; obj = js_create_from_ctor(ctx, new_target, classid); if (JS_IsException(obj)) return JS_EXCEPTION; buffer = js_array_buffer_constructor1(ctx, JS_UNDEFINED, len << size_log2, NULL); if (JS_IsException(buffer)) goto fail; offset = 0; } else { JSObject *p = JS_VALUE_GET_OBJ(argv[0]); if (p->class_id == JS_CLASS_ARRAY_BUFFER || p->class_id == JS_CLASS_SHARED_ARRAY_BUFFER) { obj = js_create_from_ctor(ctx, new_target, classid); if (JS_IsException(obj)) return JS_EXCEPTION; if (JS_ToIndex(ctx, &offset, argv[1])) goto fail; if ((offset & ((1 << size_log2) - 1)) != 0) goto invalid_offset; abuf = p->u.array_buffer; if (JS_IsUndefined(argv[2])) { if (abuf->detached) { JS_ThrowTypeErrorDetachedArrayBuffer(ctx); goto fail; } if (offset > abuf->byte_length) { invalid_offset: JS_ThrowRangeError(ctx, "invalid offset"); goto fail; } track_rab = array_buffer_is_resizable(abuf); if (!track_rab) { if ((abuf->byte_length & ((1 << size_log2) - 1)) != 0) goto invalid_length; } len = (abuf->byte_length - offset) >> size_log2; } else { if (JS_ToIndex(ctx, &len, argv[2])) goto fail; if (abuf->detached) { JS_ThrowTypeErrorDetachedArrayBuffer(ctx); goto fail; } if ((offset + (len << size_log2)) > abuf->byte_length) { invalid_length: JS_ThrowRangeError(ctx, "invalid length"); goto fail; } } buffer = JS_DupValue(ctx, argv[0]); } else { if (p->class_id >= JS_CLASS_UINT8C_ARRAY && p->class_id <= JS_CLASS_FLOAT64_ARRAY) { return js_typed_array_constructor_ta(ctx, new_target, argv[0], classid, p->u.array.count); } else { return js_typed_array_constructor_obj(ctx, new_target, argv[0], classid); } } } if (typed_array_init(ctx, obj, buffer, offset, len, track_rab)) goto fail; return obj; fail: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static void js_typed_array_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); JSTypedArray *ta = p->u.typed_array; if (ta) { /* during the GC the finalizers are called in an arbitrary order so the ArrayBuffer finalizer may have been called */ if (ta->link.next) { list_del(&ta->link); } JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, ta->buffer)); js_free_rt(rt, ta); } } static void js_typed_array_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); JSTypedArray *ta = p->u.typed_array; if (ta) { JS_MarkValue(rt, JS_MKPTR(JS_TAG_OBJECT, ta->buffer), mark_func); } } static JSValue js_dataview_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { BOOL recompute_len = FALSE; BOOL track_rab = FALSE; JSArrayBuffer *abuf; uint64_t offset; uint32_t len; JSValueConst buffer; JSValue obj; JSTypedArray *ta; JSObject *p; buffer = argv[0]; abuf = js_get_array_buffer(ctx, buffer); if (!abuf) return JS_EXCEPTION; offset = 0; if (argc > 1) { if (JS_ToIndex(ctx, &offset, argv[1])) return JS_EXCEPTION; } if (abuf->detached) return JS_ThrowTypeErrorDetachedArrayBuffer(ctx); if (offset > abuf->byte_length) return JS_ThrowRangeError(ctx, "invalid byteOffset"); len = abuf->byte_length - offset; if (argc > 2 && !JS_IsUndefined(argv[2])) { uint64_t l; if (JS_ToIndex(ctx, &l, argv[2])) return JS_EXCEPTION; if (l > len) return JS_ThrowRangeError(ctx, "invalid byteLength"); len = l; } else { recompute_len = TRUE; track_rab = array_buffer_is_resizable(abuf); } obj = js_create_from_ctor(ctx, new_target, JS_CLASS_DATAVIEW); if (JS_IsException(obj)) return JS_EXCEPTION; if (abuf->detached) { /* could have been detached in js_create_from_ctor() */ JS_ThrowTypeErrorDetachedArrayBuffer(ctx); goto fail; } // RAB could have been resized in js_create_from_ctor() if (offset > abuf->byte_length) { goto out_of_bound; } else if (recompute_len) { len = abuf->byte_length - offset; } else if (offset + len > abuf->byte_length) { out_of_bound: JS_ThrowRangeError(ctx, "invalid byteOffset or byteLength"); goto fail; } ta = js_malloc(ctx, sizeof(*ta)); if (!ta) { fail: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } p = JS_VALUE_GET_OBJ(obj); ta->obj = p; ta->buffer = JS_VALUE_GET_OBJ(JS_DupValue(ctx, buffer)); ta->offset = offset; ta->length = len; ta->track_rab = track_rab; list_add_tail(&ta->link, &abuf->array_list); p->u.typed_array = ta; return obj; } // is the DataView out of bounds relative to its parent arraybuffer? static BOOL dataview_is_oob(JSObject *p) { JSArrayBuffer *abuf; JSTypedArray *ta; assert(p->class_id == JS_CLASS_DATAVIEW); ta = p->u.typed_array; abuf = ta->buffer->u.array_buffer; if (abuf->detached) return TRUE; if (ta->offset > abuf->byte_length) return TRUE; if (ta->track_rab) return FALSE; return (int64_t)ta->offset + ta->length > abuf->byte_length; } static JSObject *get_dataview(JSContext *ctx, JSValueConst this_val) { JSObject *p; if (JS_VALUE_GET_TAG(this_val) != JS_TAG_OBJECT) goto fail; p = JS_VALUE_GET_OBJ(this_val); if (p->class_id != JS_CLASS_DATAVIEW) { fail: JS_ThrowTypeError(ctx, "not a DataView"); return NULL; } return p; } static JSValue js_dataview_get_buffer(JSContext *ctx, JSValueConst this_val) { JSObject *p; JSTypedArray *ta; p = get_dataview(ctx, this_val); if (!p) return JS_EXCEPTION; ta = p->u.typed_array; return JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, ta->buffer)); } static JSValue js_dataview_get_byteLength(JSContext *ctx, JSValueConst this_val) { JSArrayBuffer *abuf; JSTypedArray *ta; JSObject *p; p = get_dataview(ctx, this_val); if (!p) return JS_EXCEPTION; if (dataview_is_oob(p)) return JS_ThrowTypeErrorArrayBufferOOB(ctx); ta = p->u.typed_array; if (ta->track_rab) { abuf = ta->buffer->u.array_buffer; return JS_NewUint32(ctx, abuf->byte_length - ta->offset); } return JS_NewUint32(ctx, ta->length); } static JSValue js_dataview_get_byteOffset(JSContext *ctx, JSValueConst this_val) { JSTypedArray *ta; JSObject *p; p = get_dataview(ctx, this_val); if (!p) return JS_EXCEPTION; if (dataview_is_oob(p)) return JS_ThrowTypeErrorArrayBufferOOB(ctx); ta = p->u.typed_array; return JS_NewUint32(ctx, ta->offset); } static JSValue js_dataview_getValue(JSContext *ctx, JSValueConst this_obj, int argc, JSValueConst *argv, int class_id) { JSTypedArray *ta; JSArrayBuffer *abuf; BOOL littleEndian, is_swap; int size; uint8_t *ptr; uint32_t v; uint64_t pos; ta = JS_GetOpaque2(ctx, this_obj, JS_CLASS_DATAVIEW); if (!ta) return JS_EXCEPTION; size = 1 << typed_array_size_log2(class_id); if (JS_ToIndex(ctx, &pos, argv[0])) return JS_EXCEPTION; littleEndian = argc > 1 && JS_ToBool(ctx, argv[1]); is_swap = littleEndian ^ !is_be(); abuf = ta->buffer->u.array_buffer; if (abuf->detached) return JS_ThrowTypeErrorDetachedArrayBuffer(ctx); // order matters: this check should come before the next one if ((pos + size) > ta->length) return JS_ThrowRangeError(ctx, "out of bound"); // test262 expects a TypeError for this and V8, in its infinite wisdom, // throws a "detached array buffer" exception, but IMO that doesn't make // sense because the buffer is not in fact detached, it's still there if ((int64_t)ta->offset + ta->length > abuf->byte_length) return JS_ThrowTypeError(ctx, "out of bound"); ptr = abuf->data + ta->offset + pos; switch(class_id) { case JS_CLASS_INT8_ARRAY: return JS_NewInt32(ctx, *(int8_t *)ptr); case JS_CLASS_UINT8_ARRAY: return JS_NewInt32(ctx, *(uint8_t *)ptr); case JS_CLASS_INT16_ARRAY: v = get_u16(ptr); if (is_swap) v = bswap16(v); return JS_NewInt32(ctx, (int16_t)v); case JS_CLASS_UINT16_ARRAY: v = get_u16(ptr); if (is_swap) v = bswap16(v); return JS_NewInt32(ctx, v); case JS_CLASS_INT32_ARRAY: v = get_u32(ptr); if (is_swap) v = bswap32(v); return JS_NewInt32(ctx, v); case JS_CLASS_UINT32_ARRAY: v = get_u32(ptr); if (is_swap) v = bswap32(v); return JS_NewUint32(ctx, v); case JS_CLASS_BIG_INT64_ARRAY: { uint64_t v; v = get_u64(ptr); if (is_swap) v = bswap64(v); return JS_NewBigInt64(ctx, v); } break; case JS_CLASS_BIG_UINT64_ARRAY: { uint64_t v; v = get_u64(ptr); if (is_swap) v = bswap64(v); return JS_NewBigUint64(ctx, v); } break; case JS_CLASS_FLOAT16_ARRAY: { uint16_t v; v = get_u16(ptr); if (is_swap) v = bswap16(v); return __JS_NewFloat64(ctx, fromfp16(v)); } case JS_CLASS_FLOAT32_ARRAY: { union { float f; uint32_t i; } u; v = get_u32(ptr); if (is_swap) v = bswap32(v); u.i = v; return __JS_NewFloat64(ctx, u.f); } case JS_CLASS_FLOAT64_ARRAY: { union { double f; uint64_t i; } u; u.i = get_u64(ptr); if (is_swap) u.i = bswap64(u.i); return __JS_NewFloat64(ctx, u.f); } default: abort(); } } static JSValue js_dataview_setValue(JSContext *ctx, JSValueConst this_obj, int argc, JSValueConst *argv, int class_id) { JSTypedArray *ta; JSArrayBuffer *abuf; BOOL littleEndian, is_swap; int size; uint8_t *ptr; uint64_t v64; uint32_t v; uint64_t pos; JSValueConst val; ta = JS_GetOpaque2(ctx, this_obj, JS_CLASS_DATAVIEW); if (!ta) return JS_EXCEPTION; size = 1 << typed_array_size_log2(class_id); if (JS_ToIndex(ctx, &pos, argv[0])) return JS_EXCEPTION; val = argv[1]; v = 0; /* avoid warning */ v64 = 0; /* avoid warning */ if (class_id <= JS_CLASS_UINT32_ARRAY) { if (JS_ToUint32(ctx, &v, val)) return JS_EXCEPTION; } else if (class_id <= JS_CLASS_BIG_UINT64_ARRAY) { if (JS_ToBigInt64(ctx, (int64_t *)&v64, val)) return JS_EXCEPTION; } else { double d; if (JS_ToFloat64(ctx, &d, val)) return JS_EXCEPTION; if (class_id == JS_CLASS_FLOAT16_ARRAY) { v = tofp16(d); } else if (class_id == JS_CLASS_FLOAT32_ARRAY) { union { float f; uint32_t i; } u; u.f = d; v = u.i; } else { JSFloat64Union u; u.d = d; v64 = u.u64; } } littleEndian = argc > 2 && JS_ToBool(ctx, argv[2]); is_swap = littleEndian ^ !is_be(); abuf = ta->buffer->u.array_buffer; if (abuf->detached) return JS_ThrowTypeErrorDetachedArrayBuffer(ctx); // order matters: this check should come before the next one if ((pos + size) > ta->length) return JS_ThrowRangeError(ctx, "out of bound"); // test262 expects a TypeError for this and V8, in its infinite wisdom, // throws a "detached array buffer" exception, but IMO that doesn't make // sense because the buffer is not in fact detached, it's still there if ((int64_t)ta->offset + ta->length > abuf->byte_length) return JS_ThrowTypeError(ctx, "out of bound"); ptr = abuf->data + ta->offset + pos; switch(class_id) { case JS_CLASS_INT8_ARRAY: case JS_CLASS_UINT8_ARRAY: *ptr = v; break; case JS_CLASS_INT16_ARRAY: case JS_CLASS_UINT16_ARRAY: case JS_CLASS_FLOAT16_ARRAY: if (is_swap) v = bswap16(v); put_u16(ptr, v); break; case JS_CLASS_INT32_ARRAY: case JS_CLASS_UINT32_ARRAY: case JS_CLASS_FLOAT32_ARRAY: if (is_swap) v = bswap32(v); put_u32(ptr, v); break; case JS_CLASS_BIG_INT64_ARRAY: case JS_CLASS_BIG_UINT64_ARRAY: case JS_CLASS_FLOAT64_ARRAY: if (is_swap) v64 = bswap64(v64); put_u64(ptr, v64); break; default: abort(); } return JS_UNDEFINED; } static const JSCFunctionListEntry js_dataview_proto_funcs[] = { JS_CGETSET_DEF("buffer", js_dataview_get_buffer, NULL ), JS_CGETSET_DEF("byteLength", js_dataview_get_byteLength, NULL ), JS_CGETSET_DEF("byteOffset", js_dataview_get_byteOffset, NULL ), JS_CFUNC_MAGIC_DEF("getInt8", 1, js_dataview_getValue, JS_CLASS_INT8_ARRAY ), JS_CFUNC_MAGIC_DEF("getUint8", 1, js_dataview_getValue, JS_CLASS_UINT8_ARRAY ), JS_CFUNC_MAGIC_DEF("getInt16", 1, js_dataview_getValue, JS_CLASS_INT16_ARRAY ), JS_CFUNC_MAGIC_DEF("getUint16", 1, js_dataview_getValue, JS_CLASS_UINT16_ARRAY ), JS_CFUNC_MAGIC_DEF("getInt32", 1, js_dataview_getValue, JS_CLASS_INT32_ARRAY ), JS_CFUNC_MAGIC_DEF("getUint32", 1, js_dataview_getValue, JS_CLASS_UINT32_ARRAY ), JS_CFUNC_MAGIC_DEF("getBigInt64", 1, js_dataview_getValue, JS_CLASS_BIG_INT64_ARRAY ), JS_CFUNC_MAGIC_DEF("getBigUint64", 1, js_dataview_getValue, JS_CLASS_BIG_UINT64_ARRAY ), JS_CFUNC_MAGIC_DEF("getFloat16", 1, js_dataview_getValue, JS_CLASS_FLOAT16_ARRAY ), JS_CFUNC_MAGIC_DEF("getFloat32", 1, js_dataview_getValue, JS_CLASS_FLOAT32_ARRAY ), JS_CFUNC_MAGIC_DEF("getFloat64", 1, js_dataview_getValue, JS_CLASS_FLOAT64_ARRAY ), JS_CFUNC_MAGIC_DEF("setInt8", 2, js_dataview_setValue, JS_CLASS_INT8_ARRAY ), JS_CFUNC_MAGIC_DEF("setUint8", 2, js_dataview_setValue, JS_CLASS_UINT8_ARRAY ), JS_CFUNC_MAGIC_DEF("setInt16", 2, js_dataview_setValue, JS_CLASS_INT16_ARRAY ), JS_CFUNC_MAGIC_DEF("setUint16", 2, js_dataview_setValue, JS_CLASS_UINT16_ARRAY ), JS_CFUNC_MAGIC_DEF("setInt32", 2, js_dataview_setValue, JS_CLASS_INT32_ARRAY ), JS_CFUNC_MAGIC_DEF("setUint32", 2, js_dataview_setValue, JS_CLASS_UINT32_ARRAY ), JS_CFUNC_MAGIC_DEF("setBigInt64", 2, js_dataview_setValue, JS_CLASS_BIG_INT64_ARRAY ), JS_CFUNC_MAGIC_DEF("setBigUint64", 2, js_dataview_setValue, JS_CLASS_BIG_UINT64_ARRAY ), JS_CFUNC_MAGIC_DEF("setFloat16", 2, js_dataview_setValue, JS_CLASS_FLOAT16_ARRAY ), JS_CFUNC_MAGIC_DEF("setFloat32", 2, js_dataview_setValue, JS_CLASS_FLOAT32_ARRAY ), JS_CFUNC_MAGIC_DEF("setFloat64", 2, js_dataview_setValue, JS_CLASS_FLOAT64_ARRAY ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "DataView", JS_PROP_CONFIGURABLE ), }; int JS_GetTypedArrayType(JSValueConst obj) { JSClassID class_id = JS_GetClassID((JSValue)obj); if (class_id < JS_CLASS_UINT8C_ARRAY || class_id > JS_CLASS_BIG_UINT64_ARRAY) return -1; return class_id - JS_CLASS_UINT8C_ARRAY; } /* Atomics */ #ifdef CONFIG_ATOMICS typedef enum AtomicsOpEnum { ATOMICS_OP_ADD, ATOMICS_OP_AND, ATOMICS_OP_OR, ATOMICS_OP_SUB, ATOMICS_OP_XOR, ATOMICS_OP_EXCHANGE, ATOMICS_OP_COMPARE_EXCHANGE, ATOMICS_OP_LOAD, } AtomicsOpEnum; static JSObject *js_atomics_get_buf(JSContext *ctx, JSValueConst obj, JSValueConst idx_val, uint64_t *pidx, int is_waitable) { JSObject *p; JSTypedArray *ta; JSArrayBuffer *abuf; uint64_t idx; BOOL err; int old_len; if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) goto fail; p = JS_VALUE_GET_OBJ(obj); if (is_waitable) err = (p->class_id != JS_CLASS_INT32_ARRAY && p->class_id != JS_CLASS_BIG_INT64_ARRAY); else err = !(p->class_id >= JS_CLASS_INT8_ARRAY && p->class_id <= JS_CLASS_BIG_UINT64_ARRAY); if (err) { fail: JS_ThrowTypeError(ctx, "integer TypedArray expected"); return NULL; } ta = p->u.typed_array; abuf = ta->buffer->u.array_buffer; if (!abuf->shared) { if (is_waitable == 2) { JS_ThrowTypeError(ctx, "not a SharedArrayBuffer TypedArray"); return NULL; } if (abuf->detached) { JS_ThrowTypeErrorDetachedArrayBuffer(ctx); return NULL; } } old_len = p->u.array.count; if (JS_ToIndex(ctx, &idx, idx_val)) { return NULL; } if (idx >= old_len) goto oob; if (is_waitable != 1) { /* RevalidateAtomicAccess() */ if (typed_array_is_oob(p)) { JS_ThrowTypeErrorArrayBufferOOB(ctx); return NULL; } if (idx >= p->u.array.count) { oob: JS_ThrowRangeError(ctx, "out-of-bound access"); return NULL; } } *pidx = idx; return p; } static JSValue js_atomics_op(JSContext *ctx, JSValueConst this_obj, int argc, JSValueConst *argv, int op) { int size_log2; uint64_t v, a, rep_val, idx; void *ptr; JSValue ret; JSObject *p; p = js_atomics_get_buf(ctx, argv[0], argv[1], &idx, 0); if (!p) return JS_EXCEPTION; size_log2 = typed_array_size_log2(p->class_id); rep_val = 0; if (op == ATOMICS_OP_LOAD) { v = 0; } else { if (size_log2 == 3) { int64_t v64; if (JS_ToBigInt64(ctx, &v64, argv[2])) return JS_EXCEPTION; v = v64; if (op == ATOMICS_OP_COMPARE_EXCHANGE) { if (JS_ToBigInt64(ctx, &v64, argv[3])) return JS_EXCEPTION; rep_val = v64; } } else { uint32_t v32; if (JS_ToUint32(ctx, &v32, argv[2])) return JS_EXCEPTION; v = v32; if (op == ATOMICS_OP_COMPARE_EXCHANGE) { if (JS_ToUint32(ctx, &v32, argv[3])) return JS_EXCEPTION; rep_val = v32; } } if (typed_array_is_oob(p)) return JS_ThrowTypeErrorDetachedArrayBuffer(ctx); if (idx >= p->u.array.count) return JS_ThrowRangeError(ctx, "out-of-bound access"); } ptr = p->u.array.u.uint8_ptr + ((uintptr_t)idx << size_log2); switch(op | (size_log2 << 3)) { #define OP(op_name, func_name) \ case ATOMICS_OP_ ## op_name | (0 << 3): \ a = func_name((_Atomic(uint8_t) *)ptr, v); \ break; \ case ATOMICS_OP_ ## op_name | (1 << 3): \ a = func_name((_Atomic(uint16_t) *)ptr, v); \ break; \ case ATOMICS_OP_ ## op_name | (2 << 3): \ a = func_name((_Atomic(uint32_t) *)ptr, v); \ break; \ case ATOMICS_OP_ ## op_name | (3 << 3): \ a = func_name((_Atomic(uint64_t) *)ptr, v); \ break; OP(ADD, atomic_fetch_add) OP(AND, atomic_fetch_and) OP(OR, atomic_fetch_or) OP(SUB, atomic_fetch_sub) OP(XOR, atomic_fetch_xor) OP(EXCHANGE, atomic_exchange) #undef OP case ATOMICS_OP_LOAD | (0 << 3): a = atomic_load((_Atomic(uint8_t) *)ptr); break; case ATOMICS_OP_LOAD | (1 << 3): a = atomic_load((_Atomic(uint16_t) *)ptr); break; case ATOMICS_OP_LOAD | (2 << 3): a = atomic_load((_Atomic(uint32_t) *)ptr); break; case ATOMICS_OP_LOAD | (3 << 3): a = atomic_load((_Atomic(uint64_t) *)ptr); break; case ATOMICS_OP_COMPARE_EXCHANGE | (0 << 3): { uint8_t v1 = v; atomic_compare_exchange_strong((_Atomic(uint8_t) *)ptr, &v1, rep_val); a = v1; } break; case ATOMICS_OP_COMPARE_EXCHANGE | (1 << 3): { uint16_t v1 = v; atomic_compare_exchange_strong((_Atomic(uint16_t) *)ptr, &v1, rep_val); a = v1; } break; case ATOMICS_OP_COMPARE_EXCHANGE | (2 << 3): { uint32_t v1 = v; atomic_compare_exchange_strong((_Atomic(uint32_t) *)ptr, &v1, rep_val); a = v1; } break; case ATOMICS_OP_COMPARE_EXCHANGE | (3 << 3): { uint64_t v1 = v; atomic_compare_exchange_strong((_Atomic(uint64_t) *)ptr, &v1, rep_val); a = v1; } break; default: abort(); } switch(p->class_id) { case JS_CLASS_INT8_ARRAY: a = (int8_t)a; goto done; case JS_CLASS_UINT8_ARRAY: a = (uint8_t)a; goto done; case JS_CLASS_INT16_ARRAY: a = (int16_t)a; goto done; case JS_CLASS_UINT16_ARRAY: a = (uint16_t)a; goto done; case JS_CLASS_INT32_ARRAY: done: ret = JS_NewInt32(ctx, a); break; case JS_CLASS_UINT32_ARRAY: ret = JS_NewUint32(ctx, a); break; case JS_CLASS_BIG_INT64_ARRAY: ret = JS_NewBigInt64(ctx, a); break; case JS_CLASS_BIG_UINT64_ARRAY: ret = JS_NewBigUint64(ctx, a); break; default: abort(); } return ret; } static JSValue js_atomics_store(JSContext *ctx, JSValueConst this_obj, int argc, JSValueConst *argv) { int size_log2; void *ptr; JSValue ret; JSObject *p; uint64_t idx; int64_t v; p = js_atomics_get_buf(ctx, argv[0], argv[1], &idx, 0); if (!p) return JS_EXCEPTION; size_log2 = typed_array_size_log2(p->class_id); if (size_log2 == 3) { ret = JS_ToBigIntFree(ctx, JS_DupValue(ctx, argv[2])); if (JS_IsException(ret)) return ret; if (JS_ToBigInt64(ctx, &v, ret)) { JS_FreeValue(ctx, ret); return JS_EXCEPTION; } } else { uint32_t v32; /* XXX: spec, would be simpler to return the written value */ ret = JS_ToIntegerFree(ctx, JS_DupValue(ctx, argv[2])); if (JS_IsException(ret)) return ret; if (JS_ToUint32(ctx, &v32, ret)) { JS_FreeValue(ctx, ret); return JS_EXCEPTION; } v = v32; } if (typed_array_is_oob(p)) return JS_ThrowTypeErrorDetachedArrayBuffer(ctx); if (idx >= p->u.array.count) return JS_ThrowRangeError(ctx, "out-of-bound access"); ptr = p->u.array.u.uint8_ptr + ((uintptr_t)idx << size_log2); switch(size_log2) { case 0: atomic_store((_Atomic(uint8_t) *)ptr, v); break; case 1: atomic_store((_Atomic(uint16_t) *)ptr, v); break; case 2: atomic_store((_Atomic(uint32_t) *)ptr, v); break; case 3: atomic_store((_Atomic(uint64_t) *)ptr, v); break; default: abort(); } return ret; } static JSValue js_atomics_isLockFree(JSContext *ctx, JSValueConst this_obj, int argc, JSValueConst *argv) { int v, ret; if (JS_ToInt32Sat(ctx, &v, argv[0])) return JS_EXCEPTION; ret = (v == 1 || v == 2 || v == 4 || v == 8); return JS_NewBool(ctx, ret); } typedef struct JSAtomicsWaiter { struct list_head link; BOOL linked; pthread_cond_t cond; int32_t *ptr; } JSAtomicsWaiter; static pthread_mutex_t js_atomics_mutex = PTHREAD_MUTEX_INITIALIZER; static struct list_head js_atomics_waiter_list = LIST_HEAD_INIT(js_atomics_waiter_list); #if defined(__aarch64__) static inline void cpu_pause(void) { asm volatile("yield" ::: "memory"); } #elif defined(__x86_64) || defined(__i386__) static inline void cpu_pause(void) { asm volatile("pause" ::: "memory"); } #else static inline void cpu_pause(void) { } #endif // no-op: Atomics.pause() is not allowed to block or yield to another // thread, only to hint the CPU that it should back off for a bit; // the amount of work we do here is a good enough substitute static JSValue js_atomics_pause(JSContext *ctx, JSValueConst this_obj, int argc, JSValueConst *argv) { double d; if (argc > 0) { switch (JS_VALUE_GET_NORM_TAG(argv[0])) { case JS_TAG_FLOAT64: // accepted if and only if fraction == 0.0 d = JS_VALUE_GET_FLOAT64(argv[0]); if (isfinite(d)) if (0 == modf(d, &d)) break; // fallthru default: return JS_ThrowTypeError(ctx, "not an integral number"); case JS_TAG_UNDEFINED: case JS_TAG_INT: break; } } cpu_pause(); return JS_UNDEFINED; } static JSValue js_atomics_wait(JSContext *ctx, JSValueConst this_obj, int argc, JSValueConst *argv) { JSObject *p; int64_t v; int32_t v32; uint64_t idx; void *ptr; int64_t timeout; struct timespec ts; JSAtomicsWaiter waiter_s, *waiter; int ret, size_log2, res; double d; p = js_atomics_get_buf(ctx, argv[0], argv[1], &idx, 2); if (!p) return JS_EXCEPTION; size_log2 = typed_array_size_log2(p->class_id); ptr = p->u.array.u.uint8_ptr + ((uintptr_t)idx << size_log2); /* 'argv[0]' is a SharedArrayBuffer so it cannot be detached nor reduced */ if (size_log2 == 3) { if (JS_ToBigInt64(ctx, &v, argv[2])) return JS_EXCEPTION; } else { if (JS_ToInt32(ctx, &v32, argv[2])) return JS_EXCEPTION; v = v32; } if (JS_ToFloat64(ctx, &d, argv[3])) return JS_EXCEPTION; /* must use INT64_MAX + 1 because INT64_MAX cannot be exactly represented as a double */ if (isnan(d) || d >= 0x1p63) timeout = INT64_MAX; else if (d < 0) timeout = 0; else timeout = (int64_t)d; if (!ctx->rt->can_block) return JS_ThrowTypeError(ctx, "cannot block in this thread"); /* XXX: inefficient if large number of waiters, should hash on 'ptr' value */ /* XXX: use Linux futexes when available ? */ pthread_mutex_lock(&js_atomics_mutex); if (size_log2 == 3) { res = *(int64_t *)ptr != v; } else { res = *(int32_t *)ptr != v; } if (res) { pthread_mutex_unlock(&js_atomics_mutex); return JS_AtomToString(ctx, JS_ATOM_not_equal); } waiter = &waiter_s; waiter->ptr = ptr; pthread_cond_init(&waiter->cond, NULL); waiter->linked = TRUE; list_add_tail(&waiter->link, &js_atomics_waiter_list); if (timeout == INT64_MAX) { pthread_cond_wait(&waiter->cond, &js_atomics_mutex); ret = 0; } else { /* XXX: use clock monotonic */ clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += timeout / 1000; ts.tv_nsec += (timeout % 1000) * 1000000; if (ts.tv_nsec >= 1000000000) { ts.tv_nsec -= 1000000000; ts.tv_sec++; } ret = pthread_cond_timedwait(&waiter->cond, &js_atomics_mutex, &ts); } if (waiter->linked) list_del(&waiter->link); pthread_mutex_unlock(&js_atomics_mutex); pthread_cond_destroy(&waiter->cond); if (ret == ETIMEDOUT) { return JS_AtomToString(ctx, JS_ATOM_timed_out); } else { return JS_AtomToString(ctx, JS_ATOM_ok); } } static JSValue js_atomics_notify(JSContext *ctx, JSValueConst this_obj, int argc, JSValueConst *argv) { struct list_head *el, *el1, waiter_list; int32_t count, n; uint64_t idx; int size_log2; void *ptr; JSAtomicsWaiter *waiter; JSArrayBuffer *abuf; JSObject *p; p = js_atomics_get_buf(ctx, argv[0], argv[1], &idx, 1); if (!p) return JS_EXCEPTION; size_log2 = typed_array_size_log2(p->class_id); if (JS_IsUndefined(argv[2])) { count = INT32_MAX; } else { if (JS_ToInt32Clamp(ctx, &count, argv[2], 0, INT32_MAX, 0)) return JS_EXCEPTION; } n = 0; abuf = p->u.typed_array->buffer->u.array_buffer; if (abuf->shared && count > 0) { /* 'argv[0]' is a SharedArrayBuffer so it cannot be detached nor reduced */ ptr = p->u.array.u.uint8_ptr + ((uintptr_t)idx << size_log2); pthread_mutex_lock(&js_atomics_mutex); init_list_head(&waiter_list); list_for_each_safe(el, el1, &js_atomics_waiter_list) { waiter = list_entry(el, JSAtomicsWaiter, link); if (waiter->ptr == ptr) { list_del(&waiter->link); waiter->linked = FALSE; list_add_tail(&waiter->link, &waiter_list); n++; if (n >= count) break; } } list_for_each(el, &waiter_list) { waiter = list_entry(el, JSAtomicsWaiter, link); pthread_cond_signal(&waiter->cond); } pthread_mutex_unlock(&js_atomics_mutex); } return JS_NewInt32(ctx, n); } static const JSCFunctionListEntry js_atomics_funcs[] = { JS_CFUNC_MAGIC_DEF("add", 3, js_atomics_op, ATOMICS_OP_ADD ), JS_CFUNC_MAGIC_DEF("and", 3, js_atomics_op, ATOMICS_OP_AND ), JS_CFUNC_MAGIC_DEF("or", 3, js_atomics_op, ATOMICS_OP_OR ), JS_CFUNC_MAGIC_DEF("sub", 3, js_atomics_op, ATOMICS_OP_SUB ), JS_CFUNC_MAGIC_DEF("xor", 3, js_atomics_op, ATOMICS_OP_XOR ), JS_CFUNC_MAGIC_DEF("exchange", 3, js_atomics_op, ATOMICS_OP_EXCHANGE ), JS_CFUNC_MAGIC_DEF("compareExchange", 4, js_atomics_op, ATOMICS_OP_COMPARE_EXCHANGE ), JS_CFUNC_MAGIC_DEF("load", 2, js_atomics_op, ATOMICS_OP_LOAD ), JS_CFUNC_DEF("store", 3, js_atomics_store ), JS_CFUNC_DEF("isLockFree", 1, js_atomics_isLockFree ), JS_CFUNC_DEF("pause", 0, js_atomics_pause ), JS_CFUNC_DEF("wait", 4, js_atomics_wait ), JS_CFUNC_DEF("notify", 3, js_atomics_notify ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Atomics", JS_PROP_CONFIGURABLE ), }; static const JSCFunctionListEntry js_atomics_obj[] = { JS_OBJECT_DEF("Atomics", js_atomics_funcs, countof(js_atomics_funcs), JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE ), }; static int JS_AddIntrinsicAtomics(JSContext *ctx) { /* add Atomics as autoinit object */ return JS_SetPropertyFunctionList(ctx, ctx->global_obj, js_atomics_obj, countof(js_atomics_obj)); } #endif /* CONFIG_ATOMICS */ int JS_AddIntrinsicTypedArrays(JSContext *ctx) { JSValue typed_array_base_func, typed_array_base_proto, obj; int i, ret; obj = JS_NewCConstructor(ctx, JS_CLASS_ARRAY_BUFFER, "ArrayBuffer", js_array_buffer_constructor, 1, JS_CFUNC_constructor, 0, JS_UNDEFINED, js_array_buffer_funcs, countof(js_array_buffer_funcs), js_array_buffer_proto_funcs, countof(js_array_buffer_proto_funcs), 0); if (JS_IsException(obj)) return -1; JS_FreeValue(ctx, obj); obj = JS_NewCConstructor(ctx, JS_CLASS_SHARED_ARRAY_BUFFER, "SharedArrayBuffer", js_shared_array_buffer_constructor, 1, JS_CFUNC_constructor, 0, JS_UNDEFINED, js_shared_array_buffer_funcs, countof(js_shared_array_buffer_funcs), js_shared_array_buffer_proto_funcs, countof(js_shared_array_buffer_proto_funcs), 0); if (JS_IsException(obj)) return -1; JS_FreeValue(ctx, obj); typed_array_base_func = JS_NewCConstructor(ctx, -1, "TypedArray", js_typed_array_base_constructor, 0, JS_CFUNC_constructor_or_func, 0, JS_UNDEFINED, js_typed_array_base_funcs, countof(js_typed_array_base_funcs), js_typed_array_base_proto_funcs, countof(js_typed_array_base_proto_funcs), JS_NEW_CTOR_NO_GLOBAL); if (JS_IsException(typed_array_base_func)) return -1; /* TypedArray.prototype.toString must be the same object as Array.prototype.toString */ obj = JS_GetProperty(ctx, ctx->class_proto[JS_CLASS_ARRAY], JS_ATOM_toString); if (JS_IsException(obj)) goto fail; /* XXX: should use alias method in JSCFunctionListEntry */ //@@@ typed_array_base_proto = JS_GetProperty(ctx, typed_array_base_func, JS_ATOM_prototype); if (JS_IsException(typed_array_base_proto)) goto fail; ret = JS_DefinePropertyValue(ctx, typed_array_base_proto, JS_ATOM_toString, obj, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); JS_FreeValue(ctx, typed_array_base_proto); if (ret < 0) goto fail; /* Used to squelch a -Wcast-function-type warning. */ JSCFunctionType ft = { .generic_magic = js_typed_array_constructor }; for(i = JS_CLASS_UINT8C_ARRAY; i < JS_CLASS_UINT8C_ARRAY + JS_TYPED_ARRAY_COUNT; i++) { char buf[ATOM_GET_STR_BUF_SIZE]; const char *name; const JSCFunctionListEntry *bpe; name = JS_AtomGetStr(ctx, buf, sizeof(buf), JS_ATOM_Uint8ClampedArray + i - JS_CLASS_UINT8C_ARRAY); bpe = js_typed_array_funcs + typed_array_size_log2(i); obj = JS_NewCConstructor(ctx, i, name, ft.generic, 3, JS_CFUNC_constructor_magic, i, typed_array_base_func, bpe, 1, bpe, 1, 0); if (JS_IsException(obj)) { fail: JS_FreeValue(ctx, typed_array_base_func); return -1; } JS_FreeValue(ctx, obj); } JS_FreeValue(ctx, typed_array_base_func); /* DataView */ obj = JS_NewCConstructor(ctx, JS_CLASS_DATAVIEW, "DataView", js_dataview_constructor, 1, JS_CFUNC_constructor, 0, JS_UNDEFINED, NULL, 0, js_dataview_proto_funcs, countof(js_dataview_proto_funcs), 0); if (JS_IsException(obj)) return -1; JS_FreeValue(ctx, obj); /* Atomics */ #ifdef CONFIG_ATOMICS if (JS_AddIntrinsicAtomics(ctx)) return -1; #endif return 0; } /* WeakRef */ typedef struct JSWeakRefData { JSWeakRefHeader weakref_header; JSValue target; } JSWeakRefData; static void js_weakref_finalizer(JSRuntime *rt, JSValue val) { JSWeakRefData *wrd = JS_GetOpaque(val, JS_CLASS_WEAK_REF); if (!wrd) return; js_weakref_free(rt, wrd->target); list_del(&wrd->weakref_header.link); js_free_rt(rt, wrd); } static void weakref_delete_weakref(JSRuntime *rt, JSWeakRefHeader *wh) { JSWeakRefData *wrd = container_of(wh, JSWeakRefData, weakref_header); if (!js_weakref_is_live(wrd->target)) { js_weakref_free(rt, wrd->target); wrd->target = JS_UNDEFINED; } } static JSValue js_weakref_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { JSValueConst arg; JSValue obj; if (JS_IsUndefined(new_target)) return JS_ThrowTypeError(ctx, "constructor requires 'new'"); arg = argv[0]; if (!js_weakref_is_target(arg)) return JS_ThrowTypeError(ctx, "invalid target"); obj = js_create_from_ctor(ctx, new_target, JS_CLASS_WEAK_REF); if (JS_IsException(obj)) return JS_EXCEPTION; JSWeakRefData *wrd = js_mallocz(ctx, sizeof(*wrd)); if (!wrd) { JS_FreeValue(ctx, obj); return JS_EXCEPTION; } wrd->target = js_weakref_new(ctx, arg); wrd->weakref_header.weakref_type = JS_WEAKREF_TYPE_WEAKREF; list_add_tail(&wrd->weakref_header.link, &ctx->rt->weakref_list); JS_SetOpaque(obj, wrd); return obj; } static JSValue js_weakref_deref(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSWeakRefData *wrd = JS_GetOpaque2(ctx, this_val, JS_CLASS_WEAK_REF); if (!wrd) return JS_EXCEPTION; if (js_weakref_is_live(wrd->target)) return JS_DupValue(ctx, wrd->target); else return JS_UNDEFINED; } static const JSCFunctionListEntry js_weakref_proto_funcs[] = { JS_CFUNC_DEF("deref", 0, js_weakref_deref ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "WeakRef", JS_PROP_CONFIGURABLE ), }; static const JSClassShortDef js_weakref_class_def[] = { { JS_ATOM_WeakRef, js_weakref_finalizer, NULL }, /* JS_CLASS_WEAK_REF */ }; typedef struct JSFinRecEntry { struct list_head link; JSValue target; JSValue held_val; JSValue token; } JSFinRecEntry; typedef struct JSFinalizationRegistryData { JSWeakRefHeader weakref_header; struct list_head entries; /* list of JSFinRecEntry.link */ JSContext *realm; JSValue cb; } JSFinalizationRegistryData; static void js_finrec_finalizer(JSRuntime *rt, JSValue val) { JSFinalizationRegistryData *frd = JS_GetOpaque(val, JS_CLASS_FINALIZATION_REGISTRY); if (frd) { struct list_head *el, *el1; list_for_each_safe(el, el1, &frd->entries) { JSFinRecEntry *fre = list_entry(el, JSFinRecEntry, link); js_weakref_free(rt, fre->target); js_weakref_free(rt, fre->token); JS_FreeValueRT(rt, fre->held_val); js_free_rt(rt, fre); } JS_FreeValueRT(rt, frd->cb); JS_FreeContext(frd->realm); list_del(&frd->weakref_header.link); js_free_rt(rt, frd); } } static void js_finrec_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSFinalizationRegistryData *frd = JS_GetOpaque(val, JS_CLASS_FINALIZATION_REGISTRY); struct list_head *el; if (frd) { list_for_each(el, &frd->entries) { JSFinRecEntry *fre = list_entry(el, JSFinRecEntry, link); JS_MarkValue(rt, fre->held_val, mark_func); } JS_MarkValue(rt, frd->cb, mark_func); mark_func(rt, &frd->realm->header); } } static JSValue js_finrec_job(JSContext *ctx, int argc, JSValueConst *argv) { return JS_Call(ctx, argv[0], JS_UNDEFINED, 1, &argv[1]); } static void finrec_delete_weakref(JSRuntime *rt, JSWeakRefHeader *wh) { JSFinalizationRegistryData *frd = container_of(wh, JSFinalizationRegistryData, weakref_header); struct list_head *el, *el1; list_for_each_safe(el, el1, &frd->entries) { JSFinRecEntry *fre = list_entry(el, JSFinRecEntry, link); if (!js_weakref_is_live(fre->token)) { js_weakref_free(rt, fre->token); fre->token = JS_UNDEFINED; } if (!js_weakref_is_live(fre->target)) { JSValueConst args[2]; args[0] = frd->cb; args[1] = fre->held_val; /* no exception is raised to avoid recursing into the GC */ JS_EnqueueJob2(frd->realm, js_finrec_job, 2, args, TRUE); js_weakref_free(rt, fre->target); js_weakref_free(rt, fre->token); JS_FreeValueRT(rt, fre->held_val); list_del(&fre->link); js_free_rt(rt, fre); } } } static JSValue js_finrec_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { JSValueConst cb; JSValue obj; JSFinalizationRegistryData *frd; if (JS_IsUndefined(new_target)) return JS_ThrowTypeError(ctx, "constructor requires 'new'"); cb = argv[0]; if (!JS_IsFunction(ctx, cb)) return JS_ThrowTypeError(ctx, "argument must be a function"); obj = js_create_from_ctor(ctx, new_target, JS_CLASS_FINALIZATION_REGISTRY); if (JS_IsException(obj)) return JS_EXCEPTION; frd = js_mallocz(ctx, sizeof(*frd)); if (!frd) { JS_FreeValue(ctx, obj); return JS_EXCEPTION; } frd->weakref_header.weakref_type = JS_WEAKREF_TYPE_FINREC; list_add_tail(&frd->weakref_header.link, &ctx->rt->weakref_list); init_list_head(&frd->entries); frd->realm = JS_DupContext(ctx); frd->cb = JS_DupValue(ctx, cb); JS_SetOpaque(obj, frd); return obj; } static JSValue js_finrec_register(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSValueConst target, held_val, token; JSFinalizationRegistryData *frd; JSFinRecEntry *fre; frd = JS_GetOpaque2(ctx, this_val, JS_CLASS_FINALIZATION_REGISTRY); if (!frd) return JS_EXCEPTION; target = argv[0]; held_val = argv[1]; token = argc > 2 ? argv[2] : JS_UNDEFINED; if (!js_weakref_is_target(target)) return JS_ThrowTypeError(ctx, "invalid target"); if (js_same_value(ctx, target, held_val)) return JS_ThrowTypeError(ctx, "held value cannot be the target"); if (!JS_IsUndefined(token) && !js_weakref_is_target(token)) return JS_ThrowTypeError(ctx, "invalid unregister token"); fre = js_malloc(ctx, sizeof(*fre)); if (!fre) return JS_EXCEPTION; fre->target = js_weakref_new(ctx, target); fre->held_val = JS_DupValue(ctx, held_val); fre->token = js_weakref_new(ctx, token); list_add_tail(&fre->link, &frd->entries); return JS_UNDEFINED; } static JSValue js_finrec_unregister(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JSFinalizationRegistryData *frd = JS_GetOpaque2(ctx, this_val, JS_CLASS_FINALIZATION_REGISTRY); JSValueConst token; BOOL removed; struct list_head *el, *el1; if (!frd) return JS_EXCEPTION; token = argv[0]; if (!js_weakref_is_target(token)) return JS_ThrowTypeError(ctx, "invalid unregister token"); removed = FALSE; list_for_each_safe(el, el1, &frd->entries) { JSFinRecEntry *fre = list_entry(el, JSFinRecEntry, link); if (js_weakref_is_live(fre->token) && js_same_value(ctx, fre->token, token)) { js_weakref_free(ctx->rt, fre->target); js_weakref_free(ctx->rt, fre->token); JS_FreeValue(ctx, fre->held_val); list_del(&fre->link); js_free(ctx, fre); removed = TRUE; } } return JS_NewBool(ctx, removed); } static const JSCFunctionListEntry js_finrec_proto_funcs[] = { JS_CFUNC_DEF("register", 2, js_finrec_register ), JS_CFUNC_DEF("unregister", 1, js_finrec_unregister ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "FinalizationRegistry", JS_PROP_CONFIGURABLE ), }; static const JSClassShortDef js_finrec_class_def[] = { { JS_ATOM_FinalizationRegistry, js_finrec_finalizer, js_finrec_mark }, /* JS_CLASS_FINALIZATION_REGISTRY */ }; int JS_AddIntrinsicWeakRef(JSContext *ctx) { JSRuntime *rt = ctx->rt; JSValue obj; /* WeakRef */ if (!JS_IsRegisteredClass(rt, JS_CLASS_WEAK_REF)) { if (init_class_range(rt, js_weakref_class_def, JS_CLASS_WEAK_REF, countof(js_weakref_class_def))) return -1; } obj = JS_NewCConstructor(ctx, JS_CLASS_WEAK_REF, "WeakRef", js_weakref_constructor, 1, JS_CFUNC_constructor_or_func, 0, JS_UNDEFINED, NULL, 0, js_weakref_proto_funcs, countof(js_weakref_proto_funcs), 0); if (JS_IsException(obj)) return -1; JS_FreeValue(ctx, obj); /* FinalizationRegistry */ if (!JS_IsRegisteredClass(rt, JS_CLASS_FINALIZATION_REGISTRY)) { if (init_class_range(rt, js_finrec_class_def, JS_CLASS_FINALIZATION_REGISTRY, countof(js_finrec_class_def))) return -1; } obj = JS_NewCConstructor(ctx, JS_CLASS_FINALIZATION_REGISTRY, "FinalizationRegistry", js_finrec_constructor, 1, JS_CFUNC_constructor_or_func, 0, JS_UNDEFINED, NULL, 0, js_finrec_proto_funcs, countof(js_finrec_proto_funcs), 0); if (JS_IsException(obj)) return -1; JS_FreeValue(ctx, obj); return 0; } ����������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/qjs/quickjs.h��������������������������������������������������0000664�0000000�0000000�00000135405�15202323131�0022031�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * QuickJS Javascript Engine * * Copyright (c) 2017-2021 Fabrice Bellard * Copyright (c) 2017-2021 Charlie Gordon * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #ifndef QUICKJS_H #define QUICKJS_H #include <stdio.h> #include <stdint.h> #include <string.h> #ifdef __cplusplus extern "C" { #endif #if defined(__GNUC__) || defined(__clang__) #define js_likely(x) __builtin_expect(!!(x), 1) #define js_unlikely(x) __builtin_expect(!!(x), 0) #define js_force_inline inline __attribute__((always_inline)) #define __js_printf_like(f, a) __attribute__((format(printf, f, a))) #else #define js_likely(x) (x) #define js_unlikely(x) (x) #define js_force_inline inline #define __js_printf_like(a, b) #endif #define JS_BOOL int typedef struct JSRuntime JSRuntime; typedef struct JSContext JSContext; typedef struct JSClass JSClass; typedef uint32_t JSClassID; typedef uint32_t JSAtom; #if INTPTR_MAX >= INT64_MAX #define JS_PTR64 #define JS_PTR64_DEF(a) a #else #define JS_PTR64_DEF(a) #endif #ifndef JS_PTR64 #define JS_NAN_BOXING #endif #if defined(__SIZEOF_INT128__) && (INTPTR_MAX >= INT64_MAX) #define JS_LIMB_BITS 64 #else #define JS_LIMB_BITS 32 #endif #define JS_SHORT_BIG_INT_BITS JS_LIMB_BITS enum { /* all tags with a reference count are negative */ JS_TAG_FIRST = -9, /* first negative tag */ JS_TAG_BIG_INT = -9, JS_TAG_SYMBOL = -8, JS_TAG_STRING = -7, JS_TAG_STRING_ROPE = -6, JS_TAG_MODULE = -3, /* used internally */ JS_TAG_FUNCTION_BYTECODE = -2, /* used internally */ JS_TAG_OBJECT = -1, JS_TAG_INT = 0, JS_TAG_BOOL = 1, JS_TAG_NULL = 2, JS_TAG_UNDEFINED = 3, JS_TAG_UNINITIALIZED = 4, JS_TAG_CATCH_OFFSET = 5, JS_TAG_EXCEPTION = 6, JS_TAG_SHORT_BIG_INT = 7, JS_TAG_FLOAT64 = 8, /* any larger tag is FLOAT64 if JS_NAN_BOXING */ }; typedef struct JSRefCountHeader { int ref_count; } JSRefCountHeader; #define JS_FLOAT64_NAN NAN #ifdef CONFIG_CHECK_JSVALUE /* JSValue consistency : it is not possible to run the code in this mode, but it is useful to detect simple reference counting errors. It would be interesting to modify a static C analyzer to handle specific annotations (clang has such annotations but only for objective C) */ typedef struct __JSValue *JSValue; typedef const struct __JSValue *JSValueConst; #define JS_VALUE_GET_TAG(v) (int)((uintptr_t)(v) & 0xf) /* same as JS_VALUE_GET_TAG, but return JS_TAG_FLOAT64 with NaN boxing */ #define JS_VALUE_GET_NORM_TAG(v) JS_VALUE_GET_TAG(v) #define JS_VALUE_GET_INT(v) (int)((intptr_t)(v) >> 4) #define JS_VALUE_GET_BOOL(v) JS_VALUE_GET_INT(v) #define JS_VALUE_GET_FLOAT64(v) (double)JS_VALUE_GET_INT(v) #define JS_VALUE_GET_SHORT_BIG_INT(v) JS_VALUE_GET_INT(v) #define JS_VALUE_GET_PTR(v) (void *)((intptr_t)(v) & ~0xf) #define JS_MKVAL(tag, val) (JSValue)(intptr_t)(((val) << 4) | (tag)) #define JS_MKPTR(tag, p) (JSValue)((intptr_t)(p) | (tag)) #define JS_TAG_IS_FLOAT64(tag) ((unsigned)(tag) == JS_TAG_FLOAT64) #define JS_NAN JS_MKVAL(JS_TAG_FLOAT64, 1) static inline JSValue __JS_NewFloat64(JSContext *ctx, double d) { return JS_MKVAL(JS_TAG_FLOAT64, (int)d); } static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v) { return 0; } static inline JSValue __JS_NewShortBigInt(JSContext *ctx, int32_t d) { return JS_MKVAL(JS_TAG_SHORT_BIG_INT, d); } #elif defined(JS_NAN_BOXING) typedef uint64_t JSValue; #define JSValueConst JSValue #define JS_VALUE_GET_TAG(v) (int)((v) >> 32) #define JS_VALUE_GET_INT(v) (int)(v) #define JS_VALUE_GET_BOOL(v) (int)(v) #define JS_VALUE_GET_SHORT_BIG_INT(v) (int)(v) #define JS_VALUE_GET_PTR(v) (void *)(intptr_t)(v) #define JS_MKVAL(tag, val) (((uint64_t)(tag) << 32) | (uint32_t)(val)) #define JS_MKPTR(tag, ptr) (((uint64_t)(tag) << 32) | (uintptr_t)(ptr)) #define JS_FLOAT64_TAG_ADDEND (0x7ff80000 - JS_TAG_FIRST + 1) /* quiet NaN encoding */ static inline double JS_VALUE_GET_FLOAT64(JSValue v) { union { JSValue v; double d; } u; u.v = v; u.v += (uint64_t)JS_FLOAT64_TAG_ADDEND << 32; return u.d; } #define JS_NAN (0x7ff8000000000000 - ((uint64_t)JS_FLOAT64_TAG_ADDEND << 32)) static inline JSValue __JS_NewFloat64(JSContext *ctx, double d) { union { double d; uint64_t u64; } u; JSValue v; u.d = d; /* normalize NaN */ if (js_unlikely((u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000)) v = JS_NAN; else v = u.u64 - ((uint64_t)JS_FLOAT64_TAG_ADDEND << 32); return v; } #define JS_TAG_IS_FLOAT64(tag) ((unsigned)((tag) - JS_TAG_FIRST) >= (JS_TAG_FLOAT64 - JS_TAG_FIRST)) /* same as JS_VALUE_GET_TAG, but return JS_TAG_FLOAT64 with NaN boxing */ static inline int JS_VALUE_GET_NORM_TAG(JSValue v) { uint32_t tag; tag = JS_VALUE_GET_TAG(v); if (JS_TAG_IS_FLOAT64(tag)) return JS_TAG_FLOAT64; else return tag; } static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v) { uint32_t tag; tag = JS_VALUE_GET_TAG(v); return tag == (JS_NAN >> 32); } static inline JSValue __JS_NewShortBigInt(JSContext *ctx, int32_t d) { return JS_MKVAL(JS_TAG_SHORT_BIG_INT, d); } #else /* !JS_NAN_BOXING */ typedef union JSValueUnion { int32_t int32; double float64; void *ptr; #if JS_SHORT_BIG_INT_BITS == 32 int32_t short_big_int; #else int64_t short_big_int; #endif } JSValueUnion; typedef struct JSValue { JSValueUnion u; int64_t tag; } JSValue; #define JSValueConst JSValue #define JS_VALUE_GET_TAG(v) ((int32_t)(v).tag) /* same as JS_VALUE_GET_TAG, but return JS_TAG_FLOAT64 with NaN boxing */ #define JS_VALUE_GET_NORM_TAG(v) JS_VALUE_GET_TAG(v) #define JS_VALUE_GET_INT(v) ((v).u.int32) #define JS_VALUE_GET_BOOL(v) ((v).u.int32) #define JS_VALUE_GET_FLOAT64(v) ((v).u.float64) #define JS_VALUE_GET_SHORT_BIG_INT(v) ((v).u.short_big_int) #define JS_VALUE_GET_PTR(v) ((v).u.ptr) #define JS_MKVAL(tag, val) (JSValue){ (JSValueUnion){ .int32 = val }, tag } #define JS_MKPTR(tag, p) (JSValue){ (JSValueUnion){ .ptr = p }, tag } #define JS_TAG_IS_FLOAT64(tag) ((unsigned)(tag) == JS_TAG_FLOAT64) #define JS_NAN (JSValue){ .u.float64 = JS_FLOAT64_NAN, JS_TAG_FLOAT64 } static inline JSValue __JS_NewFloat64(JSContext *ctx, double d) { JSValue v; v.tag = JS_TAG_FLOAT64; v.u.float64 = d; return v; } static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v) { union { double d; uint64_t u64; } u; if (v.tag != JS_TAG_FLOAT64) return 0; u.d = v.u.float64; return (u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000; } static inline JSValue __JS_NewShortBigInt(JSContext *ctx, int64_t d) { JSValue v; v.tag = JS_TAG_SHORT_BIG_INT; v.u.short_big_int = d; return v; } #endif /* !JS_NAN_BOXING */ #define JS_VALUE_IS_BOTH_INT(v1, v2) ((JS_VALUE_GET_TAG(v1) | JS_VALUE_GET_TAG(v2)) == 0) #define JS_VALUE_IS_BOTH_FLOAT(v1, v2) (JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(v1)) && JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(v2))) #define JS_VALUE_HAS_REF_COUNT(v) ((unsigned)JS_VALUE_GET_TAG(v) >= (unsigned)JS_TAG_FIRST) /* special values */ #define JS_NULL JS_MKVAL(JS_TAG_NULL, 0) #define JS_UNDEFINED JS_MKVAL(JS_TAG_UNDEFINED, 0) #define JS_FALSE JS_MKVAL(JS_TAG_BOOL, 0) #define JS_TRUE JS_MKVAL(JS_TAG_BOOL, 1) #define JS_EXCEPTION JS_MKVAL(JS_TAG_EXCEPTION, 0) #define JS_UNINITIALIZED JS_MKVAL(JS_TAG_UNINITIALIZED, 0) /* flags for object properties */ #define JS_PROP_CONFIGURABLE (1 << 0) #define JS_PROP_WRITABLE (1 << 1) #define JS_PROP_ENUMERABLE (1 << 2) #define JS_PROP_C_W_E (JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE | JS_PROP_ENUMERABLE) #define JS_PROP_LENGTH (1 << 3) /* used internally in Arrays */ #define JS_PROP_TMASK (3 << 4) /* mask for NORMAL, GETSET, VARREF, AUTOINIT */ #define JS_PROP_NORMAL (0 << 4) #define JS_PROP_GETSET (1 << 4) #define JS_PROP_VARREF (2 << 4) /* used internally */ #define JS_PROP_AUTOINIT (3 << 4) /* used internally */ /* flags for JS_DefineProperty */ #define JS_PROP_HAS_SHIFT 8 #define JS_PROP_HAS_CONFIGURABLE (1 << 8) #define JS_PROP_HAS_WRITABLE (1 << 9) #define JS_PROP_HAS_ENUMERABLE (1 << 10) #define JS_PROP_HAS_GET (1 << 11) #define JS_PROP_HAS_SET (1 << 12) #define JS_PROP_HAS_VALUE (1 << 13) /* throw an exception if false would be returned (JS_DefineProperty/JS_SetProperty) */ #define JS_PROP_THROW (1 << 14) /* throw an exception if false would be returned in strict mode (JS_SetProperty) */ #define JS_PROP_THROW_STRICT (1 << 15) #define JS_PROP_NO_EXOTIC (1 << 16) /* internal use */ #ifndef JS_DEFAULT_STACK_SIZE #define JS_DEFAULT_STACK_SIZE (1024 * 1024) #endif /* JS_Eval() flags */ #define JS_EVAL_TYPE_GLOBAL (0 << 0) /* global code (default) */ #define JS_EVAL_TYPE_MODULE (1 << 0) /* module code */ #define JS_EVAL_TYPE_DIRECT (2 << 0) /* direct call (internal use) */ #define JS_EVAL_TYPE_INDIRECT (3 << 0) /* indirect call (internal use) */ #define JS_EVAL_TYPE_MASK (3 << 0) #define JS_EVAL_FLAG_STRICT (1 << 3) /* force 'strict' mode */ /* compile but do not run. The result is an object with a JS_TAG_FUNCTION_BYTECODE or JS_TAG_MODULE tag. It can be executed with JS_EvalFunction(). */ #define JS_EVAL_FLAG_COMPILE_ONLY (1 << 5) /* don't include the stack frames before this eval in the Error() backtraces */ #define JS_EVAL_FLAG_BACKTRACE_BARRIER (1 << 6) /* allow top-level await in normal script. JS_Eval() returns a promise. Only allowed with JS_EVAL_TYPE_GLOBAL */ #define JS_EVAL_FLAG_ASYNC (1 << 7) typedef JSValue JSCFunction(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv); typedef JSValue JSCFunctionMagic(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic); typedef JSValue JSCFunctionData(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data); typedef struct JSMallocState { size_t malloc_count; size_t malloc_size; size_t malloc_limit; void *opaque; /* user opaque */ } JSMallocState; typedef struct JSMallocFunctions { void *(*js_malloc)(JSMallocState *s, size_t size); void (*js_free)(JSMallocState *s, void *ptr); void *(*js_realloc)(JSMallocState *s, void *ptr, size_t size); size_t (*js_malloc_usable_size)(const void *ptr); } JSMallocFunctions; typedef struct JSGCObjectHeader JSGCObjectHeader; JSRuntime *JS_NewRuntime(void); /* info lifetime must exceed that of rt */ void JS_SetRuntimeInfo(JSRuntime *rt, const char *info); void JS_SetMemoryLimit(JSRuntime *rt, size_t limit); void JS_SetGCThreshold(JSRuntime *rt, size_t gc_threshold); /* use 0 to disable maximum stack size check */ void JS_SetMaxStackSize(JSRuntime *rt, size_t stack_size); /* should be called when changing thread to update the stack top value used to check stack overflow. */ void JS_UpdateStackTop(JSRuntime *rt); JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque); void JS_FreeRuntime(JSRuntime *rt); void *JS_GetRuntimeOpaque(JSRuntime *rt); void JS_SetRuntimeOpaque(JSRuntime *rt, void *opaque); typedef void JS_MarkFunc(JSRuntime *rt, JSGCObjectHeader *gp); void JS_MarkValue(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); void JS_RunGC(JSRuntime *rt); JS_BOOL JS_IsLiveObject(JSRuntime *rt, JSValueConst obj); JSContext *JS_NewContext(JSRuntime *rt); void JS_FreeContext(JSContext *s); JSContext *JS_DupContext(JSContext *ctx); void *JS_GetContextOpaque(JSContext *ctx); void JS_SetContextOpaque(JSContext *ctx, void *opaque); JSRuntime *JS_GetRuntime(JSContext *ctx); void JS_SetClassProto(JSContext *ctx, JSClassID class_id, JSValue obj); JSValue JS_GetClassProto(JSContext *ctx, JSClassID class_id); /* the following functions are used to select the intrinsic object to save memory */ JSContext *JS_NewContextRaw(JSRuntime *rt); int JS_AddIntrinsicBaseObjects(JSContext *ctx); int JS_AddIntrinsicDate(JSContext *ctx); int JS_AddIntrinsicEval(JSContext *ctx); int JS_AddIntrinsicStringNormalize(JSContext *ctx); void JS_AddIntrinsicRegExpCompiler(JSContext *ctx); int JS_AddIntrinsicRegExp(JSContext *ctx); int JS_AddIntrinsicJSON(JSContext *ctx); int JS_AddIntrinsicProxy(JSContext *ctx); int JS_AddIntrinsicMapSet(JSContext *ctx); int JS_AddIntrinsicTypedArrays(JSContext *ctx); int JS_AddIntrinsicPromise(JSContext *ctx); int JS_AddIntrinsicWeakRef(JSContext *ctx); JSValue js_string_codePointRange(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv); void *js_malloc_rt(JSRuntime *rt, size_t size); void js_free_rt(JSRuntime *rt, void *ptr); void *js_realloc_rt(JSRuntime *rt, void *ptr, size_t size); size_t js_malloc_usable_size_rt(JSRuntime *rt, const void *ptr); void *js_mallocz_rt(JSRuntime *rt, size_t size); void *js_malloc(JSContext *ctx, size_t size); void js_free(JSContext *ctx, void *ptr); void *js_realloc(JSContext *ctx, void *ptr, size_t size); size_t js_malloc_usable_size(JSContext *ctx, const void *ptr); void *js_realloc2(JSContext *ctx, void *ptr, size_t size, size_t *pslack); void *js_mallocz(JSContext *ctx, size_t size); char *js_strdup(JSContext *ctx, const char *str); char *js_strndup(JSContext *ctx, const char *s, size_t n); typedef struct JSMemoryUsage { int64_t malloc_size, malloc_limit, memory_used_size; int64_t malloc_count; int64_t memory_used_count; int64_t atom_count, atom_size; int64_t str_count, str_size; int64_t obj_count, obj_size; int64_t prop_count, prop_size; int64_t shape_count, shape_size; int64_t js_func_count, js_func_size, js_func_code_size; int64_t js_func_pc2line_count, js_func_pc2line_size; int64_t c_func_count, array_count; int64_t fast_array_count, fast_array_elements; int64_t binary_object_count, binary_object_size; } JSMemoryUsage; void JS_ComputeMemoryUsage(JSRuntime *rt, JSMemoryUsage *s); void JS_DumpMemoryUsage(FILE *fp, const JSMemoryUsage *s, JSRuntime *rt); /* atom support */ #define JS_ATOM_NULL 0 JSAtom JS_NewAtomLen(JSContext *ctx, const char *str, size_t len); JSAtom JS_NewAtom(JSContext *ctx, const char *str); JSAtom JS_NewAtomUInt32(JSContext *ctx, uint32_t n); JSAtom JS_DupAtom(JSContext *ctx, JSAtom v); JSValue JS_AtomIsNumericIndex1(JSContext *ctx, JSAtom atom); void JS_FreeAtom(JSContext *ctx, JSAtom v); void JS_FreeAtomRT(JSRuntime *rt, JSAtom v); JSValue JS_AtomToValue(JSContext *ctx, JSAtom atom); JSValue JS_AtomToString(JSContext *ctx, JSAtom atom); const char *JS_AtomToCStringLen(JSContext *ctx, size_t *plen, JSAtom atom); static inline const char *JS_AtomToCString(JSContext *ctx, JSAtom atom) { return JS_AtomToCStringLen(ctx, NULL, atom); } JSAtom JS_ValueToAtom(JSContext *ctx, JSValueConst val); /* object class support */ typedef struct JSPropertyEnum { JS_BOOL is_enumerable; JSAtom atom; } JSPropertyEnum; typedef struct JSPropertyDescriptor { int flags; JSValue value; JSValue getter; JSValue setter; } JSPropertyDescriptor; typedef struct JSClassExoticMethods { /* Return -1 if exception (can only happen in case of Proxy object), FALSE if the property does not exists, TRUE if it exists. If 1 is returned, the property descriptor 'desc' is filled if != NULL. */ int (*get_own_property)(JSContext *ctx, JSPropertyDescriptor *desc, JSValueConst obj, JSAtom prop); /* '*ptab' should hold the '*plen' property keys. Return 0 if OK, -1 if exception. The 'is_enumerable' field is ignored. */ int (*get_own_property_names)(JSContext *ctx, JSPropertyEnum **ptab, uint32_t *plen, JSValueConst obj); /* return < 0 if exception, or TRUE/FALSE */ int (*delete_property)(JSContext *ctx, JSValueConst obj, JSAtom prop); /* return < 0 if exception or TRUE/FALSE */ int (*define_own_property)(JSContext *ctx, JSValueConst this_obj, JSAtom prop, JSValueConst val, JSValueConst getter, JSValueConst setter, int flags); /* The following methods can be emulated with the previous ones, so they are usually not needed */ /* return < 0 if exception or TRUE/FALSE */ int (*has_property)(JSContext *ctx, JSValueConst obj, JSAtom atom); JSValue (*get_property)(JSContext *ctx, JSValueConst obj, JSAtom atom, JSValueConst receiver); /* return < 0 if exception or TRUE/FALSE */ int (*set_property)(JSContext *ctx, JSValueConst obj, JSAtom atom, JSValueConst value, JSValueConst receiver, int flags); /* To get a consistent object behavior when get_prototype != NULL, get_property, set_property and set_prototype must be != NULL and the object must be created with a JS_NULL prototype. */ JSValue (*get_prototype)(JSContext *ctx, JSValueConst obj); /* return < 0 if exception or TRUE/FALSE */ int (*set_prototype)(JSContext *ctx, JSValueConst obj, JSValueConst proto_val); /* return < 0 if exception or TRUE/FALSE */ int (*is_extensible)(JSContext *ctx, JSValueConst obj); /* return < 0 if exception or TRUE/FALSE */ int (*prevent_extensions)(JSContext *ctx, JSValueConst obj); } JSClassExoticMethods; typedef void JSClassFinalizer(JSRuntime *rt, JSValue val); typedef void JSClassGCMark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func); #define JS_CALL_FLAG_CONSTRUCTOR (1 << 0) typedef JSValue JSClassCall(JSContext *ctx, JSValueConst func_obj, JSValueConst this_val, int argc, JSValueConst *argv, int flags); typedef JS_BOOL JSClassCanDestroy(JSRuntime *rt, JSValueConst val); typedef struct JSClassDef { const char *class_name; JSClassFinalizer *finalizer; JSClassGCMark *gc_mark; /* if call != NULL, the object is a function. If (flags & JS_CALL_FLAG_CONSTRUCTOR) != 0, the function is called as a constructor. In this case, 'this_val' is new.target. A constructor call only happens if the object constructor bit is set (see JS_SetConstructorBit()). */ JSClassCall *call; /* XXX: suppress this indirection ? It is here only to save memory because only a few classes need these methods */ JSClassExoticMethods *exotic; JSClassCanDestroy *can_destroy; } JSClassDef; #define JS_INVALID_CLASS_ID 0 JSClassID JS_NewClassID(JSClassID *pclass_id); /* Returns the class ID if `v` is an object, otherwise returns JS_INVALID_CLASS_ID. */ JSClassID JS_GetClassID(JSValue v); int JS_NewClass(JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def); int JS_IsRegisteredClass(JSRuntime *rt, JSClassID class_id); /* value handling */ static js_force_inline JSValue JS_NewBool(JSContext *ctx, JS_BOOL val) { return JS_MKVAL(JS_TAG_BOOL, (val != 0)); } static js_force_inline JSValue JS_NewInt32(JSContext *ctx, int32_t val) { return JS_MKVAL(JS_TAG_INT, val); } static js_force_inline JSValue JS_NewCatchOffset(JSContext *ctx, int32_t val) { return JS_MKVAL(JS_TAG_CATCH_OFFSET, val); } static js_force_inline JSValue JS_NewInt64(JSContext *ctx, int64_t val) { JSValue v; if (val == (int32_t)val) { v = JS_NewInt32(ctx, val); } else { v = __JS_NewFloat64(ctx, val); } return v; } static js_force_inline JSValue JS_NewUint32(JSContext *ctx, uint32_t val) { JSValue v; if (val <= 0x7fffffff) { v = JS_NewInt32(ctx, val); } else { v = __JS_NewFloat64(ctx, val); } return v; } JSValue JS_NewBigInt64(JSContext *ctx, int64_t v); JSValue JS_NewBigUint64(JSContext *ctx, uint64_t v); static js_force_inline JSValue JS_NewFloat64(JSContext *ctx, double d) { int32_t val; union { double d; uint64_t u; } u, t; if (d >= INT32_MIN && d <= INT32_MAX) { u.d = d; val = (int32_t)d; t.d = val; /* -0 cannot be represented as integer, so we compare the bit representation */ if (u.u == t.u) return JS_MKVAL(JS_TAG_INT, val); } return __JS_NewFloat64(ctx, d); } static inline JS_BOOL JS_IsNumber(JSValueConst v) { int tag = JS_VALUE_GET_TAG(v); return tag == JS_TAG_INT || JS_TAG_IS_FLOAT64(tag); } static inline JS_BOOL JS_IsBigInt(JSContext *ctx, JSValueConst v) { int tag = JS_VALUE_GET_TAG(v); return tag == JS_TAG_BIG_INT || tag == JS_TAG_SHORT_BIG_INT; } static inline JS_BOOL JS_IsBool(JSValueConst v) { return JS_VALUE_GET_TAG(v) == JS_TAG_BOOL; } static inline JS_BOOL JS_IsNull(JSValueConst v) { return JS_VALUE_GET_TAG(v) == JS_TAG_NULL; } static inline JS_BOOL JS_IsUndefined(JSValueConst v) { return JS_VALUE_GET_TAG(v) == JS_TAG_UNDEFINED; } static inline JS_BOOL JS_IsException(JSValueConst v) { return js_unlikely(JS_VALUE_GET_TAG(v) == JS_TAG_EXCEPTION); } static inline JS_BOOL JS_IsUninitialized(JSValueConst v) { return js_unlikely(JS_VALUE_GET_TAG(v) == JS_TAG_UNINITIALIZED); } static inline JS_BOOL JS_IsString(JSValueConst v) { return JS_VALUE_GET_TAG(v) == JS_TAG_STRING || JS_VALUE_GET_TAG(v) == JS_TAG_STRING_ROPE; } static inline JS_BOOL JS_IsSymbol(JSValueConst v) { return JS_VALUE_GET_TAG(v) == JS_TAG_SYMBOL; } static inline JS_BOOL JS_IsObject(JSValueConst v) { return JS_VALUE_GET_TAG(v) == JS_TAG_OBJECT; } JSValue JS_Throw(JSContext *ctx, JSValue obj); void JS_SetUncatchableException(JSContext *ctx, JS_BOOL flag); JSValue JS_GetException(JSContext *ctx); JS_BOOL JS_HasException(JSContext *ctx); JS_BOOL JS_IsError(JSContext *ctx, JSValueConst val); JSValue JS_NewError(JSContext *ctx); JSValue __js_printf_like(2, 3) JS_ThrowSyntaxError(JSContext *ctx, const char *fmt, ...); JSValue __js_printf_like(2, 3) JS_ThrowTypeError(JSContext *ctx, const char *fmt, ...); JSValue __js_printf_like(2, 3) JS_ThrowReferenceError(JSContext *ctx, const char *fmt, ...); JSValue __js_printf_like(2, 3) JS_ThrowRangeError(JSContext *ctx, const char *fmt, ...); JSValue __js_printf_like(2, 3) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...); JSValue JS_ThrowOutOfMemory(JSContext *ctx); void __JS_FreeValue(JSContext *ctx, JSValue v); static inline void JS_FreeValue(JSContext *ctx, JSValue v) { if (JS_VALUE_HAS_REF_COUNT(v)) { JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v); if (--p->ref_count <= 0) { __JS_FreeValue(ctx, v); } } } void __JS_FreeValueRT(JSRuntime *rt, JSValue v); static inline void JS_FreeValueRT(JSRuntime *rt, JSValue v) { if (JS_VALUE_HAS_REF_COUNT(v)) { JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v); if (--p->ref_count <= 0) { __JS_FreeValueRT(rt, v); } } } static inline JSValue JS_DupValue(JSContext *ctx, JSValueConst v) { if (JS_VALUE_HAS_REF_COUNT(v)) { JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v); p->ref_count++; } return (JSValue)v; } static inline JSValue JS_DupValueRT(JSRuntime *rt, JSValueConst v) { if (JS_VALUE_HAS_REF_COUNT(v)) { JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v); p->ref_count++; } return (JSValue)v; } JS_BOOL JS_StrictEq(JSContext *ctx, JSValueConst op1, JSValueConst op2); JS_BOOL JS_SameValue(JSContext *ctx, JSValueConst op1, JSValueConst op2); JS_BOOL JS_SameValueZero(JSContext *ctx, JSValueConst op1, JSValueConst op2); int JS_ToBool(JSContext *ctx, JSValueConst val); /* return -1 for JS_EXCEPTION */ int JS_ToInt32(JSContext *ctx, int32_t *pres, JSValueConst val); static inline int JS_ToUint32(JSContext *ctx, uint32_t *pres, JSValueConst val) { return JS_ToInt32(ctx, (int32_t*)pres, val); } int JS_ToInt64(JSContext *ctx, int64_t *pres, JSValueConst val); int JS_ToIndex(JSContext *ctx, uint64_t *plen, JSValueConst val); int JS_ToFloat64(JSContext *ctx, double *pres, JSValueConst val); /* return an exception if 'val' is a Number */ int JS_ToBigInt64(JSContext *ctx, int64_t *pres, JSValueConst val); /* same as JS_ToInt64() but allow BigInt */ int JS_ToInt64Ext(JSContext *ctx, int64_t *pres, JSValueConst val); JSValue JS_NewStringLen(JSContext *ctx, const char *str1, size_t len1); static inline JSValue JS_NewString(JSContext *ctx, const char *str) { return JS_NewStringLen(ctx, str, strlen(str)); } JSValue JS_NewAtomString(JSContext *ctx, const char *str); JSValue JS_ToString(JSContext *ctx, JSValueConst val); JSValue JS_ToPropertyKey(JSContext *ctx, JSValueConst val); const char *JS_ToCStringLen2(JSContext *ctx, size_t *plen, JSValueConst val1, JS_BOOL cesu8); static inline const char *JS_ToCStringLen(JSContext *ctx, size_t *plen, JSValueConst val1) { return JS_ToCStringLen2(ctx, plen, val1, 0); } static inline const char *JS_ToCString(JSContext *ctx, JSValueConst val1) { return JS_ToCStringLen2(ctx, NULL, val1, 0); } void JS_FreeCString(JSContext *ctx, const char *ptr); JSValue JS_NewNarrowStringLen(JSContext *ctx, const char *str, size_t len); uint8_t *JS_GetNarrowStringBuffer(JSValueConst value); uint8_t *JS_GetRegExpBytecode(JSContext *ctx, JSValueConst obj, int *plen); uint32_t JS_GetStringLength(JSValueConst value); void JS_BuildBacktrace(JSContext *ctx, JSValueConst obj, int skip_first_level); JSValue JS_NewObjectProtoClass(JSContext *ctx, JSValueConst proto, JSClassID class_id); JSValue JS_NewObjectClass(JSContext *ctx, int class_id); JSValue JS_NewObjectProto(JSContext *ctx, JSValueConst proto); JSValue JS_NewObject(JSContext *ctx); JS_BOOL JS_IsFunction(JSContext* ctx, JSValueConst val); JS_BOOL JS_IsConstructor(JSContext* ctx, JSValueConst val); JS_BOOL JS_SetConstructorBit(JSContext *ctx, JSValueConst func_obj, JS_BOOL val); JSValue JS_NewArray(JSContext *ctx); int JS_IsArray(JSContext *ctx, JSValueConst val); JSValue JS_NewDate(JSContext *ctx, double epoch_ms); JSValue JS_GetPropertyInternal(JSContext *ctx, JSValueConst obj, JSAtom prop, JSValueConst receiver, JS_BOOL throw_ref_error); static js_force_inline JSValue JS_GetProperty(JSContext *ctx, JSValueConst this_obj, JSAtom prop) { return JS_GetPropertyInternal(ctx, this_obj, prop, this_obj, 0); } JSValue JS_GetPropertyStr(JSContext *ctx, JSValueConst this_obj, const char *prop); JSValue JS_GetPropertyUint32(JSContext *ctx, JSValueConst this_obj, uint32_t idx); int JS_SetPropertyInternal(JSContext *ctx, JSValueConst obj, JSAtom prop, JSValue val, JSValueConst this_obj, int flags); static inline int JS_SetProperty(JSContext *ctx, JSValueConst this_obj, JSAtom prop, JSValue val) { return JS_SetPropertyInternal(ctx, this_obj, prop, val, this_obj, JS_PROP_THROW); } int JS_SetPropertyUint32(JSContext *ctx, JSValueConst this_obj, uint32_t idx, JSValue val); int JS_SetPropertyInt64(JSContext *ctx, JSValueConst this_obj, int64_t idx, JSValue val); int JS_SetPropertyStr(JSContext *ctx, JSValueConst this_obj, const char *prop, JSValue val); int JS_HasProperty(JSContext *ctx, JSValueConst this_obj, JSAtom prop); int JS_IsExtensible(JSContext *ctx, JSValueConst obj); int JS_PreventExtensions(JSContext *ctx, JSValueConst obj); int JS_DeleteProperty(JSContext *ctx, JSValueConst obj, JSAtom prop, int flags); int JS_SetPrototype(JSContext *ctx, JSValueConst obj, JSValueConst proto_val); JSValue JS_GetPrototype(JSContext *ctx, JSValueConst val); #define JS_GPN_STRING_MASK (1 << 0) #define JS_GPN_SYMBOL_MASK (1 << 1) #define JS_GPN_PRIVATE_MASK (1 << 2) /* only include the enumerable properties */ #define JS_GPN_ENUM_ONLY (1 << 4) /* set theJSPropertyEnum.is_enumerable field */ #define JS_GPN_SET_ENUM (1 << 5) int JS_GetOwnPropertyNames(JSContext *ctx, JSPropertyEnum **ptab, uint32_t *plen, JSValueConst obj, int flags); void JS_FreePropertyEnum(JSContext *ctx, JSPropertyEnum *tab, uint32_t len); int JS_GetOwnProperty(JSContext *ctx, JSPropertyDescriptor *desc, JSValueConst obj, JSAtom prop); JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, int argc, JSValueConst *argv); JSValue JS_NewObjectFromCtor(JSContext *ctx, JSValueConst ctor, JSClassID class_id); JSValue JS_Invoke(JSContext *ctx, JSValueConst this_val, JSAtom atom, int argc, JSValueConst *argv); JSValue JS_CallConstructor(JSContext *ctx, JSValueConst func_obj, int argc, JSValueConst *argv); JSValue JS_CallConstructor2(JSContext *ctx, JSValueConst func_obj, JSValueConst new_target, int argc, JSValueConst *argv); JS_BOOL JS_DetectModule(const char *input, size_t input_len); /* 'input' must be zero terminated i.e. input[input_len] = '\0'. */ JSValue JS_Eval(JSContext *ctx, const char *input, size_t input_len, const char *filename, int eval_flags); /* same as JS_Eval() but with an explicit 'this_obj' parameter */ JSValue JS_EvalThis(JSContext *ctx, JSValueConst this_obj, const char *input, size_t input_len, const char *filename, int eval_flags); JSValue JS_GetGlobalObject(JSContext *ctx); int JS_IsInstanceOf(JSContext *ctx, JSValueConst val, JSValueConst obj); int JS_DefineProperty(JSContext *ctx, JSValueConst this_obj, JSAtom prop, JSValueConst val, JSValueConst getter, JSValueConst setter, int flags); int JS_DefinePropertyValue(JSContext *ctx, JSValueConst this_obj, JSAtom prop, JSValue val, int flags); int JS_DefinePropertyValueUint32(JSContext *ctx, JSValueConst this_obj, uint32_t idx, JSValue val, int flags); int JS_DefinePropertyValueStr(JSContext *ctx, JSValueConst this_obj, const char *prop, JSValue val, int flags); int JS_DefinePropertyGetSet(JSContext *ctx, JSValueConst this_obj, JSAtom prop, JSValue getter, JSValue setter, int flags); void JS_SetOpaque(JSValue obj, void *opaque); void *JS_GetOpaque(JSValueConst obj, JSClassID class_id); void *JS_GetOpaque2(JSContext *ctx, JSValueConst obj, JSClassID class_id); void *JS_GetAnyOpaque(JSValueConst obj, JSClassID *class_id); /* 'buf' must be zero terminated i.e. buf[buf_len] = '\0'. */ JSValue JS_ParseJSON(JSContext *ctx, const char *buf, size_t buf_len, const char *filename); #define JS_PARSE_JSON_EXT (1 << 0) /* allow extended JSON */ JSValue JS_ParseJSON2(JSContext *ctx, const char *buf, size_t buf_len, const char *filename, int flags); JSValue JS_JSONStringify(JSContext *ctx, JSValueConst obj, JSValueConst replacer, JSValueConst space0); typedef void JSFreeArrayBufferDataFunc(JSRuntime *rt, void *opaque, void *ptr); JSValue JS_NewArrayBuffer(JSContext *ctx, uint8_t *buf, size_t len, JSFreeArrayBufferDataFunc *free_func, void *opaque, JS_BOOL is_shared); JSValue JS_NewArrayBufferCopy(JSContext *ctx, const uint8_t *buf, size_t len); void JS_DetachArrayBuffer(JSContext *ctx, JSValueConst obj); uint8_t *JS_GetArrayBuffer(JSContext *ctx, size_t *psize, JSValueConst obj); typedef enum JSTypedArrayEnum { JS_TYPED_ARRAY_UINT8C = 0, JS_TYPED_ARRAY_INT8, JS_TYPED_ARRAY_UINT8, JS_TYPED_ARRAY_INT16, JS_TYPED_ARRAY_UINT16, JS_TYPED_ARRAY_INT32, JS_TYPED_ARRAY_UINT32, JS_TYPED_ARRAY_BIG_INT64, JS_TYPED_ARRAY_BIG_UINT64, JS_TYPED_ARRAY_FLOAT16, JS_TYPED_ARRAY_FLOAT32, JS_TYPED_ARRAY_FLOAT64, } JSTypedArrayEnum; JSValue JS_NewTypedArray(JSContext *ctx, int argc, JSValueConst *argv, JSTypedArrayEnum array_type); JSValue JS_GetTypedArrayBuffer(JSContext *ctx, JSValueConst obj, size_t *pbyte_offset, size_t *pbyte_length, size_t *pbytes_per_element); int JS_GetTypedArrayType(JSValueConst obj); typedef struct { void *(*sab_alloc)(void *opaque, size_t size); void (*sab_free)(void *opaque, void *ptr); void (*sab_dup)(void *opaque, void *ptr); void *sab_opaque; } JSSharedArrayBufferFunctions; void JS_SetSharedArrayBufferFunctions(JSRuntime *rt, const JSSharedArrayBufferFunctions *sf); typedef enum JSPromiseStateEnum { JS_PROMISE_PENDING, JS_PROMISE_FULFILLED, JS_PROMISE_REJECTED, } JSPromiseStateEnum; JSValue JS_NewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs); JSPromiseStateEnum JS_PromiseState(JSContext *ctx, JSValue promise); JSValue JS_PromiseResult(JSContext *ctx, JSValue promise); /* is_handled = TRUE means that the rejection is handled */ typedef void JSHostPromiseRejectionTracker(JSContext *ctx, JSValueConst promise, JSValueConst reason, JS_BOOL is_handled, void *opaque); void JS_SetHostPromiseRejectionTracker(JSRuntime *rt, JSHostPromiseRejectionTracker *cb, void *opaque); /* return != 0 if the JS code needs to be interrupted */ typedef int JSInterruptHandler(JSRuntime *rt, void *opaque); void JS_SetInterruptHandler(JSRuntime *rt, JSInterruptHandler *cb, void *opaque); /* if can_block is TRUE, Atomics.wait() can be used */ void JS_SetCanBlock(JSRuntime *rt, JS_BOOL can_block); /* select which debug info is stripped from the compiled code */ #define JS_STRIP_SOURCE (1 << 0) /* strip source code */ #define JS_STRIP_DEBUG (1 << 1) /* strip all debug info including source code */ void JS_SetStripInfo(JSRuntime *rt, int flags); int JS_GetStripInfo(JSRuntime *rt); /* set the [IsHTMLDDA] internal slot */ void JS_SetIsHTMLDDA(JSContext *ctx, JSValueConst obj); typedef struct JSModuleDef JSModuleDef; /* return the module specifier (allocated with js_malloc()) or NULL if exception */ typedef char *JSModuleNormalizeFunc(JSContext *ctx, const char *module_base_name, const char *module_name, void *opaque); typedef JSModuleDef *JSModuleLoaderFunc(JSContext *ctx, const char *module_name, void *opaque); typedef JSModuleDef *JSModuleLoaderFunc2(JSContext *ctx, const char *module_name, void *opaque, JSValueConst attributes); /* return -1 if exception, 0 if OK */ typedef int JSModuleCheckSupportedImportAttributes(JSContext *ctx, void *opaque, JSValueConst attributes); /* module_normalize = NULL is allowed and invokes the default module filename normalizer */ void JS_SetModuleLoaderFunc(JSRuntime *rt, JSModuleNormalizeFunc *module_normalize, JSModuleLoaderFunc *module_loader, void *opaque); /* same as JS_SetModuleLoaderFunc but with attributes. if module_check_attrs = NULL, no attribute checking is done. */ void JS_SetModuleLoaderFunc2(JSRuntime *rt, JSModuleNormalizeFunc *module_normalize, JSModuleLoaderFunc2 *module_loader, JSModuleCheckSupportedImportAttributes *module_check_attrs, void *opaque); /* return the import.meta object of a module */ JSValue JS_GetImportMeta(JSContext *ctx, JSModuleDef *m); JSAtom JS_GetModuleName(JSContext *ctx, JSModuleDef *m); JSValue JS_GetModuleNamespace(JSContext *ctx, JSModuleDef *m); /* JS Job support */ typedef JSValue JSJobFunc(JSContext *ctx, int argc, JSValueConst *argv); int JS_EnqueueJob(JSContext *ctx, JSJobFunc *job_func, int argc, JSValueConst *argv); JS_BOOL JS_IsJobPending(JSRuntime *rt); int JS_ExecutePendingJob(JSRuntime *rt, JSContext **pctx); /* Object Writer/Reader (currently only used to handle precompiled code) */ #define JS_WRITE_OBJ_BYTECODE (1 << 0) /* allow function/module */ #define JS_WRITE_OBJ_BSWAP (1 << 1) /* byte swapped output */ #define JS_WRITE_OBJ_SAB (1 << 2) /* allow SharedArrayBuffer */ #define JS_WRITE_OBJ_REFERENCE (1 << 3) /* allow object references to encode arbitrary object graph */ uint8_t *JS_WriteObject(JSContext *ctx, size_t *psize, JSValueConst obj, int flags); uint8_t *JS_WriteObject2(JSContext *ctx, size_t *psize, JSValueConst obj, int flags, uint8_t ***psab_tab, size_t *psab_tab_len); #define JS_READ_OBJ_BYTECODE (1 << 0) /* allow function/module */ #define JS_READ_OBJ_ROM_DATA (1 << 1) /* avoid duplicating 'buf' data */ #define JS_READ_OBJ_SAB (1 << 2) /* allow SharedArrayBuffer */ #define JS_READ_OBJ_REFERENCE (1 << 3) /* allow object references */ JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len, int flags); /* instantiate and evaluate a bytecode function. Only used when reading a script or module with JS_ReadObject() */ JSValue JS_EvalFunction(JSContext *ctx, JSValue fun_obj); /* load the dependencies of the module 'obj'. Useful when JS_ReadObject() returns a module. */ int JS_ResolveModule(JSContext *ctx, JSValueConst obj); /* only exported for os.Worker() */ JSAtom JS_GetScriptOrModuleName(JSContext *ctx, int n_stack_levels); /* only exported for os.Worker() */ JSValue JS_LoadModule(JSContext *ctx, const char *basename, const char *filename); /* C function definition */ typedef enum JSCFunctionEnum { /* XXX: should rename for namespace isolation */ JS_CFUNC_generic, JS_CFUNC_generic_magic, JS_CFUNC_constructor, JS_CFUNC_constructor_magic, JS_CFUNC_constructor_or_func, JS_CFUNC_constructor_or_func_magic, JS_CFUNC_f_f, JS_CFUNC_f_f_f, JS_CFUNC_getter, JS_CFUNC_setter, JS_CFUNC_getter_magic, JS_CFUNC_setter_magic, JS_CFUNC_iterator_next, } JSCFunctionEnum; typedef union JSCFunctionType { JSCFunction *generic; JSValue (*generic_magic)(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic); JSCFunction *constructor; JSValue (*constructor_magic)(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv, int magic); JSCFunction *constructor_or_func; double (*f_f)(double); double (*f_f_f)(double, double); JSValue (*getter)(JSContext *ctx, JSValueConst this_val); JSValue (*setter)(JSContext *ctx, JSValueConst this_val, JSValueConst val); JSValue (*getter_magic)(JSContext *ctx, JSValueConst this_val, int magic); JSValue (*setter_magic)(JSContext *ctx, JSValueConst this_val, JSValueConst val, int magic); JSValue (*iterator_next)(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int *pdone, int magic); } JSCFunctionType; JSValue JS_NewCFunction2(JSContext *ctx, JSCFunction *func, const char *name, int length, JSCFunctionEnum cproto, int magic); JSValue JS_NewCFunction3(JSContext *ctx, JSCFunction *func, const char *name, int length, JSCFunctionEnum cproto, int magic, JSValueConst proto_val, int n_fields); JSValue JS_NewCFunctionData(JSContext *ctx, JSCFunctionData *func, int length, int magic, int data_len, JSValueConst *data); static inline JSValue JS_NewCFunction(JSContext *ctx, JSCFunction *func, const char *name, int length) { return JS_NewCFunction2(ctx, func, name, length, JS_CFUNC_generic, 0); } static inline JSValue JS_NewCFunctionMagic(JSContext *ctx, JSCFunctionMagic *func, const char *name, int length, JSCFunctionEnum cproto, int magic) { /* Used to squelch a -Wcast-function-type warning. */ JSCFunctionType ft = { .generic_magic = func }; return JS_NewCFunction2(ctx, ft.generic, name, length, cproto, magic); } int JS_SetConstructor(JSContext *ctx, JSValueConst func_obj, JSValueConst proto); /* C property definition */ typedef struct JSCFunctionListEntry { const char *name; uint8_t prop_flags; uint8_t def_type; int16_t magic; union { struct { uint8_t length; /* XXX: should move outside union */ uint8_t cproto; /* XXX: should move outside union */ JSCFunctionType cfunc; } func; struct { JSCFunctionType get; JSCFunctionType set; } getset; struct { const char *name; int base; } alias; struct { const struct JSCFunctionListEntry *tab; int len; } prop_list; const char *str; int32_t i32; int64_t i64; double f64; } u; } JSCFunctionListEntry; #define JS_DEF_CFUNC 0 #define JS_DEF_CGETSET 1 #define JS_DEF_CGETSET_MAGIC 2 #define JS_DEF_PROP_STRING 3 #define JS_DEF_PROP_INT32 4 #define JS_DEF_PROP_INT64 5 #define JS_DEF_PROP_DOUBLE 6 #define JS_DEF_PROP_UNDEFINED 7 #define JS_DEF_OBJECT 8 #define JS_DEF_ALIAS 9 #define JS_DEF_PROP_ATOM 10 #define JS_DEF_PROP_BOOL 11 /* Note: c++ does not like nested designators */ #define JS_CFUNC_DEF(name, length, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } } #define JS_CFUNC_MAGIC_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_generic_magic, { .generic_magic = func1 } } } } #define JS_CFUNC_SPECIAL_DEF(name, length, cproto, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_ ## cproto, { .cproto = func1 } } } } #define JS_ITERATOR_NEXT_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_iterator_next, { .iterator_next = func1 } } } } #define JS_CGETSET_DEF(name, fgetter, fsetter) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } } #define JS_CGETSET_MAGIC_DEF(name, fgetter, fsetter, magic) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET_MAGIC, magic, .u = { .getset = { .get = { .getter_magic = fgetter }, .set = { .setter_magic = fsetter } } } } #define JS_PROP_STRING_DEF(name, cstr, prop_flags) { name, prop_flags, JS_DEF_PROP_STRING, 0, .u = { .str = cstr } } #define JS_PROP_INT32_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT32, 0, .u = { .i32 = val } } #define JS_PROP_INT64_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT64, 0, .u = { .i64 = val } } #define JS_PROP_DOUBLE_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_DOUBLE, 0, .u = { .f64 = val } } #define JS_PROP_UNDEFINED_DEF(name, prop_flags) { name, prop_flags, JS_DEF_PROP_UNDEFINED, 0, .u = { .i32 = 0 } } #define JS_PROP_ATOM_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_ATOM, 0, .u = { .i32 = val } } #define JS_PROP_BOOL_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_BOOL, 0, .u = { .i32 = val } } #define JS_OBJECT_DEF(name, tab, len, prop_flags) { name, prop_flags, JS_DEF_OBJECT, 0, .u = { .prop_list = { tab, len } } } #define JS_ALIAS_DEF(name, from) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, .u = { .alias = { from, -1 } } } #define JS_ALIAS_BASE_DEF(name, from, base) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, .u = { .alias = { from, base } } } int JS_SetPropertyFunctionList(JSContext *ctx, JSValueConst obj, const JSCFunctionListEntry *tab, int len); /* C module definition */ typedef int JSModuleInitFunc(JSContext *ctx, JSModuleDef *m); JSModuleDef *JS_NewCModule(JSContext *ctx, const char *name_str, JSModuleInitFunc *func); /* can only be called before the module is instantiated */ int JS_AddModuleExport(JSContext *ctx, JSModuleDef *m, const char *name_str); int JS_AddModuleExportList(JSContext *ctx, JSModuleDef *m, const JSCFunctionListEntry *tab, int len); /* can only be called after the module is instantiated */ int JS_SetModuleExport(JSContext *ctx, JSModuleDef *m, const char *export_name, JSValue val); int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m, const JSCFunctionListEntry *tab, int len); /* associate a JSValue to a C module */ int JS_SetModulePrivateValue(JSContext *ctx, JSModuleDef *m, JSValue val); JSValue JS_GetModulePrivateValue(JSContext *ctx, JSModuleDef *m); /* debug value output */ typedef struct { JS_BOOL show_hidden : 8; /* only show enumerable properties */ JS_BOOL raw_dump : 8; /* avoid doing autoinit and avoid any malloc() call (for internal use) */ uint32_t max_depth; /* recurse up to this depth, 0 = no limit */ uint32_t max_string_length; /* print no more than this length for strings, 0 = no limit */ uint32_t max_item_count; /* print no more than this count for arrays or objects, 0 = no limit */ } JSPrintValueOptions; typedef void JSPrintValueWrite(void *opaque, const char *buf, size_t len); void JS_PrintValueSetDefaultOptions(JSPrintValueOptions *options); void JS_PrintValueRT(JSRuntime *rt, JSPrintValueWrite *write_func, void *write_opaque, JSValueConst val, const JSPrintValueOptions *options); void JS_PrintValue(JSContext *ctx, JSPrintValueWrite *write_func, void *write_opaque, JSValueConst val, const JSPrintValueOptions *options); #undef js_unlikely #undef js_force_inline #ifdef __cplusplus } /* extern "C" { */ #endif #endif /* QUICKJS_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/quickjs-aux.h��������������������������������������������������0000664�0000000�0000000�00000000101�15202323131�0022007�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define toJSValueConst(x) (x) #define toJSValueConstArray(x) (x) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/quickjs.nim����������������������������������������������������0000664�0000000�0000000�00000110424�15202323131�0021562�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} from std/os import parentDir import constcharp import libregexp import dtoa export constcharp export libregexp.JS_BOOL {.passc: "-DNOT_LRE_ONLY".} {.passl: "-lm".} const CFLAGS0 = "-fwrapv -DCONFIG_VERSION='\"Monoucha 0.11.0\"' -DCHA_BUILD" when not compileOption("threads"): const CFLAGS = CFLAGS0 & " -DCHA_NO_THREADS" else: const CFLAGS = CFLAGS0 {.passl: "-lpthread".} {.compile("qjs/quickjs.c", CFLAGS).} {.passc: "-I" & currentSourcePath().parentDir().} const qjsheader = "qjs/quickjs.h" const # all tags with a reference count are negative JS_TAG_FIRST* = -9 ## first negative tag JS_TAG_BIG_INT* = -9 JS_TAG_SYMBOL* = -8 JS_TAG_STRING* = -7 JS_TAG_STRING_ROPE* = -6 JS_TAG_MODULE* = -3 ## used internally JS_TAG_FUNCTION_BYTECODE* = -2 ## used internally JS_TAG_OBJECT* = -1 JS_TAG_INT* = 0 JS_TAG_BOOL* = 1 JS_TAG_NULL* = 2 JS_TAG_UNDEFINED* = 3 JS_TAG_UNINITIALIZED* = 4 JS_TAG_CATCH_OFFSET* = 5 JS_TAG_EXCEPTION* = 6 JS_TAG_SHORT_BIG_INT* = 7 JS_TAG_FLOAT64* = 8 ## any larger tag is FLOAT64 if JS_NAN_BOXING when sizeof(int) < sizeof(int64): type JSValue* {.importc, header: qjsheader.} = distinct uint64 type JSValueConst* {.importc: "JSValueConst".} = distinct JSValue template JS_VALUE_GET_TAG*(v: JSValueConst): int32 = cast[int32](cast[uint64](v) shr 32) template JS_VALUE_GET_PTR*(v: JSValueConst): pointer = cast[pointer](v) template JS_MKVAL*(t, val: untyped): JSValue = JSValue((cast[uint64](int64(t)) shl 32) or uint32(val)) template JS_MKPTR*(t, p: untyped): JSValue = JSValue((cast[uint64](int64(t)) shl 32) or cast[uint](p)) else: type JSValueUnion* {.importc, header: qjsheader, union.} = object int32*: int32 float64*: float64 `ptr`*: pointer JSValue* {.importc, header: qjsheader.} = object u*: JSValueUnion tag*: int64 type JSValueConst* {.importc: "JSValueConst".} = distinct JSValue template JS_VALUE_GET_TAG*(v: JSValueConst): int32 = cast[int32](JSValue(v).tag) template JS_VALUE_GET_PTR*(v: JSValueConst): pointer = cast[pointer](JSValue(v).u) template JS_MKVAL*(t, val: untyped): JSValue = JSValue(u: JSValueUnion(`int32`: val), tag: t) template JS_MKPTR*(t, p: untyped): JSValue = JSValue(u: JSValueUnion(`ptr`: p), tag: t) type JSValueArray* = ptr UncheckedArray[JSValue] JSValueConstArray* = ptr UncheckedArray[JSValueConst] JSRuntimeT {.importc: "JSRuntime", header: qjsheader, incompleteStruct.} = object JSContextT {.importc: "JSContext", header: qjsheader, incompleteStruct.} = object JSModuleDefT {.importc: "JSModuleDef", header: qjsheader, incompleteStruct.} = object JSRuntime* = ptr JSRuntimeT JSContext* = ptr JSContextT JSModuleDef* = ptr JSModuleDefT JSCFunction* = proc(ctx: JSContext; this_val: JSValueConst; argc: cint; argv: JSValueConstArray): JSValue {.cdecl, raises: [].} JSCFunctionMagic* = proc(ctx: JSContext; this_val: JSValueConst; argc: cint; argv: JSValueConstArray; magic: cint): JSValue {.cdecl, raises: [].} JSCFunctionData* = proc(ctx: JSContext; this_val: JSValueConst; argc: cint; argv: JSValueConstArray; magic: cint; func_data: JSValueConstArray): JSValue {.cdecl, raises: [].} JSGetterFunction* = proc(ctx: JSContext; this_val: JSValueConst): JSValue {.cdecl, raises: [].} JSSetterFunction* = proc(ctx: JSContext; this_val, val: JSValueConst): JSValue {.cdecl, raises: [].} JSGetterMagicFunction* = proc(ctx: JSContext; this_val: JSValueConst; magic: cint): JSValue {.cdecl, raises: [].} JSSetterMagicFunction* = proc(ctx: JSContext; this_val, val: JSValueConst; magic: cint): JSValue {.cdecl, raises: [].} JSIteratorNextFunction* = proc(ctx: JSContext; this_val: JSValueConst; argc: cint; argv: JSValueConstArray; pdone: ptr cint; magic: cint): JSValue {.cdecl, raises: [].} JSClassID* = uint32 JSAtom* {.importc: "JSAtom", header: qjsheader.} = distinct uint32 JSClassFinalizer* = proc(rt: JSRuntime; val: JSValueConst) {. cdecl, raises: [].} JSClassCheckDestroy* = proc(rt: JSRuntime; val: JSValueConst): JS_BOOL {.cdecl, raises: [].} JSClassGCMark* = proc(rt: JSRuntime; val: JSValueConst; mark_func: JS_MarkFunc) {.cdecl, raises: [].} JS_MarkFunc* = proc(rt: JSRuntime; gp: ptr JSGCObjectHeader) {. cdecl, raises: [].} JSModuleNormalizeFunc* = proc(ctx: JSContext; module_base_name, module_name: cstringConst; opaque: pointer): cstring {.cdecl, raises: [].} JSModuleLoaderFunc* = proc(ctx: JSContext; module_name: cstringConst, opaque: pointer): JSModuleDef {.cdecl.} JSJobFunc* = proc(ctx: JSContext; argc: cint; argv: JSValueConstArray): JSValue {.cdecl.} JSGCObjectHeader* {.importc, header: qjsheader.} = object JSFreeArrayBufferDataFunc* = proc(rt: JSRuntime; opaque, p: pointer) {. cdecl, raises: [].} JSPropertyDescriptor* {.importc, header: qjsheader.} = object flags*: cint value*: JSValue getter*: JSValue setter*: JSValue JSClassExoticMethods* {.importc, header: qjsheader.} = object # Return -1 if exception (can only happen in case of Proxy object), # FALSE if the property does not exists, TRUE if it exists. If 1 is # returned, the property descriptor 'desc' is filled if != NULL. get_own_property*: proc(ctx: JSContext; desc: ptr JSPropertyDescriptor; obj: JSValueConst; prop: JSAtom): cint {.cdecl.} # '*ptab' should hold the '*plen' property keys. Return 0 if OK, # -1 if exception. The 'is_enumerable' field is ignored. get_own_property_names*: proc(ctx: JSContext; ptab: ptr ptr UncheckedArray[JSPropertyEnum]; plen: ptr uint32; obj: JSValueConst): cint {.cdecl.} # return < 0 if exception, or TRUE/FALSE delete_property*: proc(ctx: JSContext; obj: JSValueConst; prop: JSAtom): cint {.cdecl.} # return < 0 if exception or TRUE/FALSE define_own_property*: proc(ctx: JSContext; this_obj: JSValueConst; prop: JSAtom; val, getter, setter: JSValueConst; flags: cint): cint {.cdecl.} # The following methods can be emulated with the previous ones, # so they are usually not needed # return < 0 if exception or TRUE/FALSE has_property*: proc(ctx: JSContext; obj: JSValueConst; atom: JSAtom): cint {.cdecl.} get_property*: proc(ctx: JSContext; obj: JSValueConst; atom: JSAtom; receiver: JSValueConst): JSValue {.cdecl.} set_property*: proc(ctx: JSContext; obj: JSValueConst; atom: JSAtom; value, receiver: JSValueConst; flags: cint): cint {.cdecl.} # To get a consistent object behavior when get_prototype != NULL, # get_property, set_property and set_prototype must be != NULL # and the object must be created with a JS_NULL prototype. get_prototype*: proc(ctx: JSContext; obj: JSValueConst): JSValue {.cdecl.} # return < 0 if exception or TRUE/FALSE set_prototype*: proc(ctx: JSContext; obj, proto_val: JSValueConst): cint {. cdecl.} # return < 0 if exception or TRUE/FALSE is_extensible*: proc(ctx: JSContext; obj: JSValueConst): cint {.cdecl.} # return < 0 if exception or TRUE/FALSE prevent_extensions*: proc(ctx: JSContext; obj: JSValueConst): cint {.cdecl.} JSClassExoticMethodsConst* {.importc: "const JSClassExoticMethods *", header: qjsheader.} = ptr JSClassExoticMethods JSClassCallP* {.importc: "JSClassCall *".} = proc(ctx: JSContext; func_obj, this_val: JSValueConst; argc: cint; argv: JSValueConstArray; flags: cint): JSValue {.cdecl.} JSClassDef* {.importc, header: qjsheader.} = object class_name*: cstring # pure ASCII only! finalizer*: JSClassFinalizer gc_mark*: JSClassGCMark # if call != NULL, the object is a function. If (flags & # JS_CALL_FLAG_CONSTRUCTOR) != 0, the function is called as a constructor. # In this case, 'this_val' is new.target. A constructor call only happens # if the object constructor bit is set (see JS_SetConstructorBit()). call*: JSClassCallP exotic*: JSClassExoticMethodsConst can_destroy*: JSClassCheckDestroy JSClassDefConst* {.importc: "const JSClassDef *", header: qjsheader.} = ptr JSClassDef JSCFunctionEnum* {.size: sizeof(uint8).} = enum JS_CFUNC_generic, JS_CFUNC_generic_magic, JS_CFUNC_constructor, JS_CFUNC_constructor_magic, JS_CFUNC_constructor_or_func, JS_CFUNC_constructor_or_func_magic, JS_CFUNC_f_f, JS_CFUNC_f_f_f, JS_CFUNC_getter, JS_CFUNC_setter, JS_CFUNC_getter_magic, JS_CFUNC_setter_magic, JS_CFUNC_iterator_next JSCFunctionType* {.importc, union.} = object generic*: JSCFunction generic_magic*: JSCFunctionMagic constructor*: JSCFunction constructor_magic*: JSCFunctionMagic constructor_or_func*: JSCFunction # note: f_f, f_f_f omitted getter*: JSGetterFunction setter*: JSSetterFunction getter_magic*: JSGetterMagicFunction setter_magic*: JSSetterMagicFunction iterator_next*: JSIteratorNextFunction JSCFunctionListP* = ptr UncheckedArray[JSCFunctionListEntry] JSCFunctionListEntryFunc = object length*: uint8 cproto*: JSCFunctionEnum cfunc*: JSCFunctionType JSCFunctionListEntryGetSet = object get*: JSCFunctionType set*: JSCFunctionType JSCFunctionListEntryAlias = object name: cstring base: cint JSCFunctionListEntryPropList = object tab: JSCFunctionListP len: cint JSCFunctionListEntryU* {.union.} = object `func`* {.importc: "func".}: JSCFunctionListEntryFunc getset: JSCFunctionListEntryGetSet alias: JSCFunctionListEntryAlias prop_list: JSCFunctionListEntryPropList str: cstring i32: int32 i64: int64 f64: cdouble JSCFunctionListEntry* {.importc.} = object name*: cstring # pure ASCII or UTF-8 encoded prop_flags*: uint8 def_type*: uint8 magic*: int16 u* {.importc.}: JSCFunctionListEntryU JSPropertyEnum* {.importc.} = object is_enumerable*: JS_BOOL atom*: JSAtom JSMallocState* {.importc.} = object malloc_count: csize_t malloc_size: csize_t malloc_limit: csize_t opaque: pointer JSMallocStateP* = ptr JSMallocState JSMallocFunctions* {.importc.} = object js_malloc*: proc(s: JSMallocStateP; size: csize_t): pointer {.cdecl.} js_free*: proc(s: JSMallocStateP; p: pointer) {.cdecl.} js_realloc*: proc(s: JSMallocStateP; p: pointer; size: csize_t): pointer {.cdecl.} js_malloc_usable_size*: proc(p: pointer) {.cdecl.} JSSharedArrayBufferFunctions* {.importc.} = object sab_alloc*: proc(opaque: pointer; size: csize_t): pointer {.cdecl.} sab_free*: proc(opaque: pointer) {.cdecl.} sab_dup*: proc(opaque: pointer): pointer {.cdecl.} sab_opaque*: pointer JSPromiseStateEnum* {.size: sizeof(cint).} = enum JS_PROMISE_PENDING JS_PROMISE_FULFILLED JS_PROMISE_REJECTED proc `==`*(a, b: JSValue): bool {.error.} = discard proc `==`*(a, b: JSAtom): bool {.borrow.} converter toJSValueConst*(val: JSValue): JSValueConst {.importc, header: "quickjs-aux.h".} = JSValueConst(val) converter toJSValueConstArray*(val: JSValueArray): JSValueConstArray {. importc, header: "quickjs-aux.h".} = JSValueConstArray(val) template JS_NULL*(): untyped = JS_MKVAL(JS_TAG_NULL, 0) template JS_UNDEFINED*(): untyped = JS_MKVAL(JS_TAG_UNDEFINED, 0) template JS_FALSE*(): untyped = JS_MKVAL(JS_TAG_BOOL, 0) template JS_TRUE*(): untyped = JS_MKVAL(JS_TAG_BOOL, 1) template JS_EXCEPTION*(): untyped = JS_MKVAL(JS_TAG_EXCEPTION, 0) template JS_UNINITIALIZED*(): untyped = JS_MKVAL(JS_TAG_UNINITIALIZED, 0) const JS_EVAL_TYPE_GLOBAL* = cint(0 shl 0) ## global code (default) JS_EVAL_TYPE_MODULE* = cint(1 shl 0) ## module code JS_EVAL_TYPE_DIRECT* = cint(2 shl 0) ## direct call (internal use) JS_EVAL_TYPE_INDIRECT* = cint(3 shl 0) ## indirect call (internal use) JS_EVAL_TYPE_MASK* = cint(3 shl 0) JS_EVAL_FLAG_STRICT* = cint(1 shl 3) ## force 'strict' mode JS_EVAL_FLAG_COMPILE_ONLY* = cint(1 shl 5) ## compile but do not run. ## The result is an object with a JS_TAG_FUNCTION_BYTECODE or ## JS_TAG_MODULE tag. It can be executed with JS_EvalFunction(). JS_EVAL_FLAG_BACKTRACE_BARRIER* = cint(1 shl 6) ## allow top-level await in normal ## script. JS_Eval() returns a promise. Only allowed with ## JS_EVAL_TYPE_GLOBAL const JS_DEF_CFUNC* = 0 JS_DEF_CGETSET* = 1 JS_DEF_CGETSET_MAGIC* = 2 JS_DEF_PROP_STRING* = 3 JS_DEF_PROP_INT32* = 4 JS_DEF_PROP_INT64* = 5 JS_DEF_PROP_DOUBLE* = 6 JS_DEF_PROP_UNDEFINED* = 7 JS_DEF_OBJECT* = 8 JS_DEF_ALIAS* = 9 JS_DEF_PROP_ATOM* = 10 JS_DEF_PROP_BOOL* = 11 const JS_PROP_CONFIGURABLE* = (1 shl 0) JS_PROP_WRITABLE* = (1 shl 1) JS_PROP_ENUMERABLE* = (1 shl 2) JS_PROP_C_W_E* = (JS_PROP_CONFIGURABLE or JS_PROP_WRITABLE or JS_PROP_ENUMERABLE) JS_PROP_LENGTH* = (1 shl 3) # used internally in Arrays JS_PROP_TMASK* = (3 shl 4) # mask for NORMAL, GETSET, VARREF, AUTOINIT JS_PROP_NORMAL* = (0 shl 4) JS_PROP_GETSET* = (1 shl 4) JS_PROP_VARREF* = (2 shl 4) # used internally JS_PROP_AUTOINIT* = (3 shl 4) # used internally JS_PROP_THROW* = (1 shl 14) # Flags for JS_DefineProperty const JS_PROP_HAS_SHIFT* = cint(8) JS_PROP_HAS_CONFIGURABLE* = cint(1 shl 8) JS_PROP_HAS_WRITABLE* = cint(1 shl 9) JS_PROP_HAS_ENUMERABLE* = cint(1 shl 10) JS_PROP_HAS_GET* = cint(1 shl 11) JS_PROP_HAS_SET* = cint(1 shl 12) JS_PROP_HAS_VALUE* = cint(1 shl 13) template JS_CFUNC_DEF*(n: cstring; len: uint8; func1: JSCFunction; flags: cint): JSCFunctionListEntry = JSCFunctionListEntry(name: n, prop_flags: flags, def_type: JS_DEF_CFUNC, u: JSCFunctionListEntryU( `func`: JSCFunctionListEntryFunc( length: len, cproto: JS_CFUNC_generic, cfunc: JSCFunctionType(generic: func1)))) template JS_CFUNC_DEF*(n: string; len: uint8; func1: JSCFunction): JSCFunctionListEntry = JS_CFUNC_DEF(n, len, func1, JS_PROP_WRITABLE or JS_PROP_CONFIGURABLE) template JS_CGETSET_DEF*(n: string; fgetter: JSGetterFunction; fsetter: JSSetterFunction; flags: cint): JSCFunctionListEntry = JSCFunctionListEntry(name: cstring(n), prop_flags: flags, def_type: JS_DEF_CGETSET, u: JSCFunctionListEntryU( getset: JSCFunctionListEntryGetSet( get: JSCFunctionType(getter: fgetter), set: JSCFunctionType(setter: fsetter)))) template JS_CGETSET_DEF*(n: string; fgetter: JSGetterFunction; fsetter: JSSetterFunction): JSCFunctionListEntry = JS_CGETSET_DEF(n, fgetter, fsetter, JS_PROP_CONFIGURABLE) template JS_CGETSET_MAGIC_DEF*(n: cstring; fgetter: JSGetterMagicFunction; fsetter: JSSetterMagicFunction; m: int16; flags: cint): JSCFunctionListEntry = JSCFunctionListEntry(name: n, prop_flags: flags, def_type: JS_DEF_CGETSET_MAGIC, magic: m, u: JSCFunctionListEntryU( getset: JSCFunctionListEntryGetSet( get: JSCFunctionType(getter_magic: fgetter), set: JSCFunctionType(setter_magic: fsetter)))) template JS_CGETSET_MAGIC_DEF*(n: cstring; fgetter: JSGetterMagicFunction; fsetter: JSSetterMagicFunction; m: int16): JSCFunctionListEntry = JS_CGETSET_MAGIC_DEF(n, fgetter, fsetter, m, JS_PROP_CONFIGURABLE) template JS_PROP_STRING_DEF*(n, cstr: cstring; f: cint): JSCFunctionListEntry = JSCFunctionListEntry(name: n, prop_flags: f, def_type: JS_DEF_PROP_STRING, magic: 0, u: JSCFunctionListEntryU(str: cstr)) {.push header: qjsheader, importc.} proc JS_NewRuntime*(): JSRuntime proc JS_SetRuntimeInfo*(rt: JSRuntime; info: cstringConst) ## ## info lifetime must ## exceed that of rt proc JS_GetGCThreshold*(rt: JSRuntime): csize_t proc JS_SetGCThreshold*(rt: JSRuntime; gc_threshold: csize_t) proc JS_SetMaxStackSize*(rt: JSRuntime; stack_size: csize_t) ## ## use 0 to disable ## maximum stack check proc JS_UpdateStackTop*(rt: JSRuntime) ## ## should be called when changing thread to update the stack top value ## used to check stack overflow. proc JS_NewRuntime2*(mf: ptr JSMallocFunctions; opaque: pointer): JSRuntime proc JS_FreeRuntime*(rt: JSRuntime) proc JS_GetRuntimeOpaque*(rt: JSRuntime): pointer proc JS_SetRuntimeOpaque*(rt: JSRuntime; p: pointer) proc JS_UnsetCanDestroyHooks*(rt: JSRuntime) proc JS_MarkValue*(rt: JSRuntime; val: JSValueConst; mark_func: JS_MarkFunc) proc JS_RunGC*(rt: JSRuntime) proc JS_IsLiveObject*(rt: JSRuntime; obj: JSValueConst): JS_BOOL proc JS_NewContext*(rt: JSRuntime): JSContext proc JS_FreeContext*(ctx: JSContext) proc JS_DupContext*(ctx: JSContext): JSContext proc JS_SetContextOpaque*(ctx: JSContext; opaque: pointer) proc JS_GetContextOpaque*(ctx: JSContext): pointer proc JS_GetRuntime*(ctx: JSContext): JSRuntime proc JS_SetClassProto*(ctx: JSContext; class_id: JSClassID; obj: JSValue) proc JS_GetClassProto*(ctx: JSContext; class_id: JSClassID): JSValue # the following functions are used to select the intrinsic object to save memory proc JS_NewContextRaw*(rt: JSRuntime): JSContext proc JS_AddIntrinsicBaseObjects*(ctx: JSContext): cint proc JS_AddIntrinsicDate*(ctx: JSContext): cint proc JS_AddIntrinsicEval*(ctx: JSContext): cint proc JS_AddIntrinsicStringNormalize*(ctx: JSContext): cint proc JS_AddIntrinsicRegExpCompiler*(ctx: JSContext) proc JS_AddIntrinsicRegExp*(ctx: JSContext): cint proc JS_AddIntrinsicJSON*(ctx: JSContext): cint proc JS_AddIntrinsicProxy*(ctx: JSContext): cint proc JS_AddIntrinsicMapSet*(ctx: JSContext): cint proc JS_AddIntrinsicTypedArrays*(ctx: JSContext): cint proc JS_AddIntrinsicPromise*(ctx: JSContext): cint proc JS_AddIntrinsicWeakRef*(ctx: JSContext): cint proc js_string_codePointRange*(ctx: JSContext; this_val: JSValueConst; argc: cint; argv: JSValueConstArray): JSValue proc js_malloc_rt*(rt: JSRuntime; size: csize_t): pointer proc js_free_rt*(rt: JSRuntime; p: pointer) proc js_realloc_rt*(rt: JSRuntime; p: pointer; size: csize_t): pointer proc js_malloc_usable_size_rt*(rt: JSRuntime; p: pointer): csize_t proc js_mallocz_rt*(rt: JSRuntime; size: csize_t): pointer proc js_malloc*(ctx: JSContext; size: csize_t): pointer proc js_free*(ctx: JSContext; p: pointer) proc js_realloc*(ctx: JSContext; p: pointer; size: csize_t): pointer proc js_malloc_usable_size*(ctx: JSContext; p: pointer): csize_t proc js_realloc2*(ctx: JSContext; p: pointer; size: csize_t; pslack: ptr csize_t): pointer proc js_mallocz*(ctx: JSContext; size: csize_t): pointer proc js_strdup*(ctx: JSContext; str: cstringConst): cstring proc js_strndup*(ctx: JSContext; str: cstringConst; n: csize_t): cstring type JSMemoryUsage* {.importc, header: qjsheader.} = object malloc_size*, malloc_limit*, memory_used_size*: int64 malloc_count*: int64 memory_used_count*: int64 atom_count*, atom_size*: int64 str_count*, str_size*: int64 obj_count*, obj_size*: int64 prop_count*, prop_size*: int64 shape_count*, shape_size*: int64 js_func_count*, js_func_size*, js_func_code_size*: int64 js_func_pc2line_count*, js_func_pc2line_size*: int64 c_func_count*, array_count*: int64 fast_array_count*, fast_array_elements*: int64 binary_object_count*, binary_object_size*: int64 proc JS_ComputeMemoryUsage*(rt: JSRuntime; s: var JSMemoryUsage) proc JS_DumpMemoryUsage*(fp: File; s: var JSMemoryUsage; rt: JSRuntime) # atom support const JS_ATOM_NULL* = JSAtom(0) proc JS_NewAtomLen*(ctx: JSContext; str: cstringConst; len: csize_t): JSAtom proc JS_NewAtom*(ctx: JSContext; str: cstringConst): JSAtom proc JS_NewAtomUInt32*(ctx: JSContext; u: uint32): JSAtom proc JS_DupAtom*(ctx: JSContext; v: JSAtom): JSAtom proc JS_AtomIsNumericIndex1*(ctx: JSContext; atom: JSAtom): JSValue proc JS_FreeAtom*(ctx: JSContext; atom: JSAtom) proc JS_FreeAtomRT*(rt: JSRuntime; atom: JSAtom) proc JS_AtomToValue*(ctx: JSContext; atom: JSAtom): JSValue proc JS_AtomToString*(ctx: JSContext; atom: JSAtom): JSValue proc JS_AtomToCStringLen*(ctx: JSContext; plen: ptr csize_t; atom: JSAtom): cstringConst proc JS_AtomToCString*(ctx: JSContext; atom: JSAtom): cstringConst proc JS_ValueToAtom*(ctx: JSContext; val: JSValueConst): JSAtom # object class support const JS_INVALID_CLASS_ID* = JSClassID(0) proc JS_NewClassID*(pclass_id: var JSClassID): JSClassID proc JS_GetClassID*(obj: JSValueConst): JSClassID proc JS_NewClass*(rt: JSRuntime; class_id: JSClassID; class_def: ptr JSClassDef): cint proc JS_IsRegisteredClass*(rt: JSRuntime; class_id: JSClassID): cint # value handling proc JS_NewBool*(ctx: JSContext; val: JS_BOOL): JSValue proc JS_NewInt32*(ctx: JSContext; val: int32): JSValue proc JS_NewCatchOffset*(ctx: JSContext; val: int32): JSValue proc JS_NewInt64*(ctx: JSContext; val: int64): JSValue proc JS_NewUint32*(ctx: JSContext; val: uint32): JSValue proc JS_NewNumber*(ctx: JSContext; val: cdouble): JSValue proc JS_NewBigInt64*(ctx: JSContext; val: int64): JSValue proc JS_NewBigUInt64*(ctx: JSContext; val: uint64): JSValue proc JS_NewFloat64*(ctx: JSContext; val: cdouble): JSValue proc JS_IsNumber*(v: JSValueConst): JS_BOOL proc JS_IsBigInt*(v: JSValueConst): JS_BOOL proc JS_IsBool*(v: JSValueConst): JS_BOOL proc JS_IsNull*(v: JSValueConst): JS_BOOL proc JS_IsUndefined*(v: JSValueConst): JS_BOOL proc JS_IsException*(v: JSValueConst): JS_BOOL proc JS_IsUninitialized*(v: JSValueConst): JS_BOOL proc JS_IsString*(v: JSValueConst): JS_BOOL proc JS_IsSymbol*(v: JSValueConst): JS_BOOL proc JS_IsObject*(v: JSValueConst): JS_BOOL proc JS_Throw*(ctx: JSContext; obj: JSValue): JSValue proc JS_SetUncatchableException*(ctx: JSContext; flag: JS_BOOL) proc JS_GetException*(ctx: JSContext): JSValue proc JS_HasException*(ctx: JSContext): JS_BOOL proc JS_IsError*(v: JSValueConst): JS_BOOL proc JS_NewError*(ctx: JSContext): JSValue proc JS_ThrowSyntaxError*(ctx: JSContext; fmt: cstring): JSValue {.varargs, discardable.} proc JS_ThrowTypeError*(ctx: JSContext; fmt: cstring): JSValue {.varargs, discardable.} proc JS_ThrowReferenceError*(ctx: JSContext; fmt: cstring): JSValue {.varargs, discardable.} proc JS_ThrowRangeError*(ctx: JSContext; fmt: cstring): JSValue {.varargs, discardable.} proc JS_ThrowInternalError*(ctx: JSContext; fmt: cstring): JSValue {.varargs, discardable.} proc JS_ThrowOutOfMemory*(ctx: JSContext): JSValue {.discardable.} proc JS_FreeValue*(ctx: JSContext; v: JSValue) proc JS_FreeValueRT*(rt: JSRuntime; v: JSValue) proc JS_DupValue*(ctx: JSContext; v: JSValueConst): JSValue proc JS_DupValueRT*(rt: JSRuntime; v: JSValueConst): JSValue proc JS_StrictEq*(ctx: JSContext; op1, op2: JSValueConst): JS_BOOL proc JS_SameValue*(ctx: JSContext; op1, op2: JSValueConst): JS_BOOL # Similar to same-value equality, but +0 and -0 are considered equal. proc JS_SameValueZero*(ctx: JSContext; op1, op2: JSValueConst): JS_BOOL # return -1 for JS_EXCEPTION proc JS_ToBool*(ctx: JSContext; val: JSValueConst): cint proc JS_ToInt32*(ctx: JSContext; pres: var int32; val: JSValueConst): cint proc JS_ToUint32*(ctx: JSContext; pres: var uint32; val: JSValueConst): cint proc JS_ToInt64*(ctx: JSContext; pres: var int64; val: JSValueConst): cint proc JS_ToIndex*(ctx: JSContext; plen: var uint64; val: JSValueConst): cint proc JS_ToFloat64*(ctx: JSContext; pres: var float64; val: JSValueConst): cint # return an exception if 'val' is a Number proc JS_ToBigInt64*(ctx: JSContext; pres: var int64; val: JSValueConst): cint # same as JS_ToInt64 but allow BigInt proc JS_ToInt64Ext*(ctx: JSContext; pres: var int64; val: JSValueConst): cint proc JS_NewStringLen*(ctx: JSContext; str: cstringConst; len1: csize_t): JSValue proc JS_NewString*(ctx: JSContext; str: cstring): JSValue proc JS_NewAtomString*(ctx: JSContext; str: cstring): JSValue proc JS_ToString*(ctx: JSContext; val: JSValueConst): JSValue proc JS_ToPropertyKey*(ctx: JSContext; val: JSValueConst): JSValue proc JS_ToCStringLen2*(ctx: JSContext; plen: var csize_t; val1: JSValueConst; cesu8: JS_BOOL): cstringConst proc JS_ToCStringLen*(ctx: JSContext; plen: var csize_t; val1: JSValueConst): cstringConst proc JS_ToCString*(ctx: JSContext; val1: JSValueConst): cstringConst proc JS_FreeCString*(ctx: JSContext, p: cstringConst) # Monoucha extensions - unstable API! proc JS_NewNarrowStringLen*(ctx: JSContext; s: cstring; len: csize_t): JSValue proc JS_GetNarrowStringBuffer*(str: JSValueConst): ptr UncheckedArray[uint8] proc JS_GetStringLength*(str: JSValueConst): uint32 proc JS_GetRegExpBytecode*(ctx: JSContext; obj: JSValueConst; plen: var cint): ptr uint8 proc JS_NewObjectProtoClass*(ctx: JSContext; proto: JSValueConst; class_id: JSClassID): JSValue proc JS_NewObjectClass*(ctx: JSContext; class_id: JSClassID): JSValue proc JS_NewObjectProto*(ctx: JSContext; proto: JSValueConst): JSValue proc JS_NewObject*(ctx: JSContext): JSValue proc JS_IsFunction*(ctx: JSContext; val: JSValueConst): JS_BOOL proc JS_IsConstructor*(ctx: JSContext; val: JSValueConst): JS_BOOL proc JS_SetConstructorBit*(ctx: JSContext; func_obj: JSValueConst; val: JS_BOOL): JS_BOOL # takes ownership of the values proc JS_NewArray*(ctx: JSContext): JSValue proc JS_IsArray*(ctx: JSContext; v: JSValueConst): cint proc JS_NewDate*(ctx: JSContext; epoch_ms: float64): JSValue proc JS_GetProperty*(ctx: JSContext; this_obj: JSValueConst; prop: JSAtom): JSValue proc JS_GetPropertyStr*(ctx: JSContext; this_obj: JSValueConst; prop: cstring): JSValue proc JS_GetPropertyUint32*(ctx: JSContext; this_obj: JSValueConst; idx: uint32): JSValue proc JS_SetProperty*(ctx: JSContext; this_obj: JSValueConst; prop: JSAtom; val: JSValue): cint proc JS_SetPropertyUint32*(ctx: JSContext; this_obj: JSValueConst; idx: uint32; val: JSValue): cint proc JS_SetPropertyInt64*(ctx: JSContext; this_obj: JSValueConst; idx: int64; val: JSValue): cint proc JS_SetPropertyStr*(ctx: JSContext; this_obj: JSValueConst; prop: cstring; val: JSValue): cint proc JS_HasProperty*(ctx: JSContext; this_obj: JSValueConst; prop: JSAtom): cint proc JS_IsExtensible*(ctx: JSContext; obj: JSValueConst): cint proc JS_PreventExtensions*(ctx: JSContext; obj: JSValueConst): cint proc JS_DeleteProperty*(ctx: JSContext; obj: JSValueConst; prop: JSAtom; flags: cint): cint proc JS_SetPrototype*(ctx: JSContext; obj, proto_val: JSValueConst): cint proc JS_GetPrototype*(ctx: JSContext; val: JSValueConst): JSValue proc JS_GetLength*(ctx: JSContext; obj: JSValueConst; pres: ptr uint64): JSValue proc JS_SetLength*(ctx: JSContext; obj: JSValueConst; len: uint64): cint const JS_GPN_STRING_MASK* = cint(1 shl 0) JS_GPN_SYMBOL_MASK* = cint(1 shl 1) JS_GPN_PRIVATE_MASK* = cint(1 shl 2) JS_GPN_ENUM_ONLY* = cint(1 shl 3) JS_GPN_SET_ENUM* = cint(1 shl 4) proc JS_GetOwnPropertyNames*(ctx: JSContext; ptab: ptr ptr UncheckedArray[JSPropertyEnum]; plen: ptr uint32; obj: JSValueConst; flags: cint): cint proc JS_GetOwnProperty*(ctx: JSContext; desc: ptr JSPropertyDescriptor; obj: JSValueConst; prop: JSAtom): cint proc JS_FreePropertyEnum*(ctx: JSContext; tab: ptr UncheckedArray[JSPropertyEnum]; len: uint32) proc JS_Call*(ctx: JSContext; func_obj, this_obj: JSValueConst; argc: cint; argv: JSValueConstArray): JSValue # Monoucha extension - unstable API! proc JS_NewObjectFromCtor*(ctx: JSContext; ctor: JSValueConst; class_id: JSClassID): JSValue proc JS_Invoke*(ctx: JSContext; this_obj: JSValueConst; atom: JSAtom; argc: cint; argv: JSValueConstArray): JSValue proc JS_CallConstructor*(ctx: JSContext; func_obj: JSValueConst; argc: cint; argv: JSValueConstArray): JSValue proc JS_CallConstructor2*(ctx: JSContext; func_obj, new_target: JSValueConst; argc: cint; argv: JSValueConstArray): JSValue proc JS_DetectModule*(input: cstringConst; input_len: csize_t): JS_BOOL # 'input' must be zero terminated i.e. input[input_len] = '\0'. proc JS_Eval*(ctx: JSContext; input: cstringConst; input_len: csize_t; filename: cstring; eval_flags: cint): JSValue # same as JS_Eval() but with an explicit 'this_obj' parameter proc JS_EvalThis*(ctx: JSContext; this_obj: JSValueConst; input: cstringConst; input_len: csize_t; filename: cstringConst; eval_flags: cint): JSValue proc JS_GetGlobalObject*(ctx: JSContext): JSValue proc JS_IsInstanceOf*(ctx: JSContext; val, obj: JSValueConst): cint proc JS_DefineProperty*(ctx: JSContext; this_obj: JSValueConst; prop: JSAtom; val, getter, setter: JSValueConst; flags: cint): cint proc JS_DefinePropertyValue*(ctx: JSContext; this_obj: JSValueConst; prop: JSAtom; val: JSValue; flags: cint): cint proc JS_DefinePropertyValueUint32*(ctx: JSContext; this_obj: JSValueConst; idx: uint32; val: JSValue; flags: cint): cint proc JS_DefinePropertyValueStr*(ctx: JSContext; this_obj: JSValueConst; prop: cstring; val: JSValue; flags: cint): cint proc JS_DefinePropertyGetSet*(ctx: JSContext; this_obj: JSValueConst; prop: JSAtom; getter, setter: JSValue; flags: cint): cint proc JS_SetOpaque*(obj: JSValueConst; opaque: pointer) proc JS_GetOpaque*(obj: JSValueConst; class_id: JSClassID): pointer proc JS_GetOpaque2*(ctx: JSContext; obj: JSValueConst; class_id: JSClassID): pointer proc JS_GetAnyOpaque*(obj: JSValueConst; class_id: var JSClassID): pointer # 'buf' must be zero terminated i.e. buf[buf_len] = '\0'. proc JS_ParseJSON*(ctx: JSContext; buf: cstringConst; buf_len: csize_t; filename: cstringConst): JSValue proc JS_JSONStringify*(ctx: JSContext; obj, replacer, space0: JSValueConst): JSValue proc JS_NewArrayBuffer*(ctx: JSContext; buf: ptr UncheckedArray[uint8]; len: csize_t; free_func: JSFreeArrayBufferDataFunc; opaque: pointer; is_shared: JS_BOOL): JSValue proc JS_NewArrayBufferCopy*(ctx: JSContext; buf: ptr UncheckedArray[uint8]; len: csize_t): JSValue proc JS_DetachArrayBuffer*(ctx: JSContext; obj: JSValueConst) proc JS_GetArrayBuffer*(ctx: JSContext; psize: var csize_t; obj: JSValueConst): ptr uint8 proc JS_IsArrayBuffer*(obj: JSValueConst): JS_BOOL proc JS_GetUint8Array*(ctx: JSContext; psize: ptr csize_t; obj: JSValueConst): ptr UncheckedArray[uint8] type JSTypedArrayEnum* {.size: sizeof(cint).} = enum JS_TYPED_ARRAY_UINT8C = 0 JS_TYPED_ARRAY_INT8 JS_TYPED_ARRAY_UINT8 JS_TYPED_ARRAY_INT16 JS_TYPED_ARRAY_UINT16 JS_TYPED_ARRAY_INT32 JS_TYPED_ARRAY_UINT32 JS_TYPED_ARRAY_BIG_INT64 JS_TYPED_ARRAY_BIG_UINT64 JS_TYPED_ARRAY_FLOAT16 JS_TYPED_ARRAY_FLOAT32 JS_TYPED_ARRAY_FLOAT64 proc JS_NewTypedArray*(ctx: JSContext; argc: cint; argv: JSValueConstArray; array_type: JSTypedArrayEnum): JSValue proc JS_GetTypedArrayBuffer*(ctx: JSContext; obj: JSValueConst; pbyte_offset, pbyte_length, pbytes_per_element: var csize_t): JSValue proc JS_NewUint8Array*(ctx: JSContext; buf: ptr UncheckedArray[uint8]; len: csize_t; free_func: JSFreeArrayBufferDataFunc; opaque: pointer; is_shared: JS_BOOL): JSValue proc JS_GetTypedArrayType*(obj: JSValueConst): cint proc JS_GetUint8Array*(ctx: JSContext; psize: var csize_t; obj: JSValueConst): JS_BOOL proc JS_NewUint8ArrayCopy*(ctx: JSContext; buf: ptr UncheckedArray[uint8]; len: csize_t): JSValue proc JS_SetSharedArrayBufferFunctions*(rt: JSRuntime; sf: ptr JSSharedArrayBufferFunctions) proc JS_NewPromiseCapability*(ctx: JSContext; resolving_funcs: JSValueArray): JSValue proc JS_PromiseState*(ctx: JSContext; promise: JSValueConst): JSPromiseStateEnum proc JS_PromiseResult*(ctx: JSContext; promise: JSValueConst): JSValue proc JS_IsPromise*(val: JSValueConst): JS_BOOL proc JS_NewSymbol*(ctx: JSContext; description: cstringConst; is_global: JS_BOOL): JSValue # is_handled = TRUE means that the rejection is handled type JSHostPromiseRejectionTracker = proc(ctx: JSContext; promise, reason: JSValueConst; is_handled: JS_BOOL; opaque: pointer) {.cdecl.} proc JS_SetHostPromiseRejectionTracker*(rt: JSRuntime; cb: JSHostPromiseRejectionTracker; opaque: pointer) # return != 0 if the JS code needs to be interrupted type JSInterruptHandler* = proc(rt: JSRuntime; opaque: pointer): cint {.cdecl.} proc JS_SetInterruptHandler*(rt: JSRuntime; cb: JSInterruptHandler; opaque: pointer) # if can_block is TRUE, Atomics.wait() can be used proc JS_SetCanBlock*(rt: JSRuntime; can_block: JS_BOOL) # select which debug info is stripped from the compiled code const JS_STRIP_SOURCE* = cint(1 shl 0) ## strip source code const JS_STRIP_DEBUG* = cint(1 shl 1) ## strip all debug info including source ## code proc JS_SetStripInfo*(rt: JSRuntime; flags: cint) proc JS_GetStripInfo*(rt: JSRuntime): cint # set the [IsHTMLDDA] internal slot proc JS_SetIsHTMLDDA*(ctx: JSContext; obj: JSValueConst) proc JS_SetModuleLoaderFunc*(rt: JSRuntime; module_normalize: JSModuleNormalizeFunc; module_loader: JSModuleLoaderFunc; opaque: pointer) proc JS_GetImportMeta*(ctx: JSContext; m: JSModuleDef): JSValue proc JS_GetModuleName*(ctx: JSContext; m: JSModuleDef): JSAtom proc JS_GetModuleNamespace*(ctx: JSContext; m: JSModuleDef): JSValue # JS Job support proc JS_EnqueueJob*(ctx: JSContext; job_func: JSJobFunc; argc: cint; argv: JSValueConstArray): cint proc JS_IsJobPending*(rt: JSRuntime): JS_BOOL proc JS_ExecutePendingJob*(rt: JSRuntime; pctx: var JSContext): cint type JSSABTab* {.importc.} = object tab*: ptr ptr UncheckedArray[uint8] len*: csize_t # Object Writer/Reader (currently only used to handle precompiled code) const JS_WRITE_OBJ_BYTECODE* = (1 shl 0) ## allow function/module JS_WRITE_OBJ_BSWAP* = 0 ## byte swapped output JS_WRITE_OBJ_SAB* = (1 shl 2) ## allow SharedArrayBuffer JS_WRITE_OBJ_REFERENCE* = (1 shl 3) ## allow object references to encode ## arbitrary object graph proc JS_WriteObject*(ctx: JSContext; psize: ptr csize_t; obj: JSValueConst; flags: cint): ptr uint8 proc JS_WriteObject2*(ctx: JSContext; psize: ptr csize_t; obj: JSValueConst; flags: cint; psab_tab: ptr JSSABTab; psab_tab_len: ptr csize_t): ptr uint8 const JS_READ_OBJ_BYTECODE* = (1 shl 0) ## allow function/module JS_READ_OBJ_ROM_DATA* = 0 ## avoid duplicating 'buf' data JS_READ_OBJ_SAB* = (1 shl 2) ## allow SharedArrayBuffer JS_READ_OBJ_REFERENCE* = (1 shl 3) ## allow object references proc JS_ReadObject*(ctx: JSContext; buf: ptr uint8; buf_len: csize_t; flags: cint): JSValue proc JS_ReadObject2*(ctx: JSContext; buf: ptr uint8; buf_len: csize_t; flags: cint; psab_tab: ptr JSSABTab): JSValue proc JS_EvalFunction*(ctx: JSContext; val: JSValue): JSValue ## instantiate ## and evaluate a bytecode function. Only used when reading a script or ## module with JS_ReadObject() proc JS_ResolveModule*(ctx: JSContext; obj: JSValueConst): cint ## load the ## dependencies of the module 'obj'. Useful when JS_ReadObject() returns ## a module. # only exported for os.Worker() proc JS_GetScriptOrModuleName*(ctx: JSContext; n_stack_levels: cint): JSAtom # only exported for os.Worker() proc JS_LoadModule*(ctx: JSContext; basename, filename: cstringConst): JSValue # C function definition proc JS_NewCFunction2*(ctx: JSContext; cfunc: JSCFunction; name: cstring; length: cint; proto: JSCFunctionEnum; magic: cint): JSValue proc JS_NewCFunction3*(ctx: JSContext; cfunc: JSCFunction; name: cstring; length: cint; proto: JSCFunctionEnum; magic: cint; proto_val: JSValueConst; n_fields: cint): JSValue proc JS_NewCFunctionData*(ctx: JSContext; cfunc: JSCFunctionData; length, magic, data_len: cint; data: JSValueConstArray): JSValue proc JS_NewCFunctionData2*(ctx: JSContext; cfunc: JSCFunctionData; name: cstring; length, magic, data_len: cint; data: JSValueConstArray): JSValue proc JS_NewCFunction*(ctx: JSContext; cfunc: JSCFunction; name: cstring; length: cint): JSValue proc JS_SetConstructor*(ctx: JSContext; func_obj, proto: JSValueConst) # C property definition proc JS_SetPropertyFunctionList*(ctx: JSContext; obj: JSValueConst; tab: JSCFunctionListP; len: cint): cint # C module definition type JSModuleInitFunc* = proc(ctx: JSContext; m: JSModuleDef): cint proc JS_NewCModule*(ctx: JSContext; name_str: cstringConst; fun: JSModuleInitFunc): JSModuleDef # can only be called before the module is instantiated proc JS_AddModuleExport*(ctx: JSContext; m: JSModuleDef; name_str: cstringConst): cint proc JS_AddModuleExportList*(ctx: JSContext; m: JSModuleDef; tab: JSCFunctionListP; len: cint): cint # can only be called after the module is instantiated proc JS_SetModuleExport*(ctx: JSContext; m: JSModuleDef; export_name: cstringConst; val: JSValue): cint proc JS_SetModuleExportList*(ctx: JSContext; m: JSModuleDef; tab: JSCFunctionListP; len: cint): cint proc JS_SetModulePrivateValue*(ctx: JSContext; m: JSModuleDef; val: JSValue): cint ## associate a JSValue to a C module proc JS_GetModulePrivateValue*(ctx: JSContext; m: JSModuleDef): JSValue {.pop.} # header, importc {.pop.} # raises ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/tojs.nim�������������������������������������������������������0000664�0000000�0000000�00000023711�15202323131�0021072�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## Automatic conversion of Nim types to JavaScript types. ## ## Every conversion involves copying unless explicitly noted below. ## ## * Primitives are converted to their respective JavaScript counterparts. ## * seq is converted to a JS array. Note: this always copies the seq's ## contents. ## * enum is converted to its stringifier's output. ## * JSValue is returned as-is, *without* a DupValue operation. ## * JSArrayBuffer, JSUint8Array are converted to a JS object without copying ## their contents. ## * NarrowString is converted to a JS narrow string (with copying). For more ## information on JS string handling, see js/jstypes.nim. ## * Finally, ref object is converted to a JS object whose opaque is the ref ## object. (See below.) ## ## ref objects can be seamlessly converted to JS objects despite the fact ## that they are managed by two separate garbage collectors thanks to a patch ## in QJS: ## ## * Nim objects registered with registerType can be paired with one JS ## object each. This happens on-demand, whenever the Nim object has to be ## converted into JS. ## * Once the conversion happened, the JS object will be kept alive until the ## Nim object is destroyed, so that JS properties on the JS object are not ## lost during a re-conversion. ## * Similarly, the Nim object is kept alive so long as the JS object is alive. ## * The patched in can_destroy hook is used to synchronize reference counts ## of the two objects; this way, no memory leak occurs. {.push raises: [].} import std/macrocache import std/tables import std/typetraits import jsopaque import jstypes import jsutils import quickjs # Convert Nim types to the corresponding JavaScript type. proc toJS*(ctx: JSContext; s: string): JSValue proc toJS*(ctx: JSContext; n: int64): JSValue proc toJS*(ctx: JSContext; n: int32): JSValue proc toJS*(ctx: JSContext; n: int): JSValue proc toJS*(ctx: JSContext; n: uint16): JSValue proc toJS*(ctx: JSContext; n: uint32): JSValue proc toJS*(ctx: JSContext; n: uint64): JSValue proc toJS*(ctx: JSContext; n: float64): JSValue proc toJS*(ctx: JSContext; b: bool): JSValue proc toJS*[T](ctx: JSContext; s: seq[T]): JSValue proc toJS*[T](ctx: JSContext; s: set[T]): JSValue proc toJS*[T: tuple](ctx: JSContext; t: T): JSValue proc toJS*[T: enum](ctx: JSContext; e: T): JSValue proc toJS*(ctx: JSContext; j: JSValue): JSValue proc toJS*(ctx: JSContext; obj: ref object): JSValue proc toJS*(ctx: JSContext; abuf: JSArrayBuffer): JSValue proc toJS*(ctx: JSContext; u8a: JSArrayBufferView): JSValue proc toJS*(ctx: JSContext; ns: NarrowString): JSValue proc toJS*[T: JSDict](ctx: JSContext; dict: T): JSValue # Same as toJS, but used in constructors. ctor contains the target prototype, # used for subclassing from JS. proc toJSNew*(ctx: JSContext; obj: ref object; ctor: JSValueConst): JSValue proc newFunction*(ctx: JSContext; args: openArray[string]; body: string): JSValue = var paramList: seq[JSValue] = @[] for arg in args: paramList.add(ctx.toJS(arg)) paramList.add(ctx.toJS(body)) let fun = JS_CallConstructor(ctx, ctx.getOpaque().valRefs[jsvFunction], cint(paramList.len), paramList.toJSValueArray()) for param in paramList: JS_FreeValue(ctx, param) return fun proc toJS*(ctx: JSContext; s: cstring): JSValue = return JS_NewString(ctx, s) proc toJS*(ctx: JSContext; s: string): JSValue = return JS_NewStringLen(ctx, cstring(s), csize_t(s.len)) proc toJS*(ctx: JSContext; n: int16): JSValue = return JS_NewInt32(ctx, int32(n)) proc toJS*(ctx: JSContext; n: int32): JSValue = return JS_NewInt32(ctx, n) proc toJS*(ctx: JSContext; n: int64): JSValue = return JS_NewInt64(ctx, n) proc toJS*(ctx: JSContext; n: int): JSValue = when sizeof(int) > 4: return ctx.toJS(int64(n)) elif sizeof(int) > 2: return ctx.toJS(int32(n)) else: return ctx.toJS(int16(n)) proc toJS*(ctx: JSContext; n: uint16): JSValue = return JS_NewUint32(ctx, uint32(n)) proc toJS*(ctx: JSContext; n: uint32): JSValue = return JS_NewUint32(ctx, n) proc toJS*(ctx: JSContext; n: uint64): JSValue = #TODO this is incorrect return JS_NewFloat64(ctx, float64(n)) proc toJS*(ctx: JSContext; n: float64): JSValue = return JS_NewFloat64(ctx, n) proc toJS*(ctx: JSContext; b: bool): JSValue = return JS_NewBool(ctx, b) proc toJS*[T](ctx: JSContext; s: seq[T]): JSValue = var vals = newSeqOfCap[JSValue](s.len) for it in s: let val = ctx.toJS(it) if JS_IsException(val): ctx.freeValues(vals) return val vals.add(val) return ctx.newArrayFrom(vals) proc toJS*[T](ctx: JSContext; s: set[T]): JSValue = var vals: seq[JSValue] = @[] for e in s: let val = ctx.toJS(e) if JS_IsException(val): ctx.freeValues(vals) return val vals.add(val) let a = ctx.newArrayFrom(vals) if JS_IsException(a): return a let ret = JS_CallConstructor(ctx, ctx.getOpaque().valRefs[jsvSet], 1, a.toJSValueArray()) JS_FreeValue(ctx, a) return ret proc toJS*[T: tuple](ctx: JSContext; t: T): JSValue = const L = T.tupleLen var vals {.noinit.}: array[L, JSValue] var i = 0 {.push overflowChecks: off.} for it in t.fields: let val = ctx.toJS(it) if JS_IsException(val): break vals[i] = val inc i if i != L: ctx.freeValues(vals.toOpenArray(0, i - 1)) return JS_EXCEPTION {.pop.} return ctx.newArrayFrom(vals) proc toJSP0(ctx: JSContext; p, tp: pointer; ctor: JSValueConst): JSValue = let rtOpaque = JS_GetRuntime(ctx).getOpaque() rtOpaque.plist.withValue(p, obj): # a JSValue already points to this object. let val = JS_MKPTR(JS_TAG_OBJECT, obj[]) if val.getOpaque() != nil: # JS owns the Nim value, because it still holds an active # reference to it. return JS_DupValue(ctx, val) # Nim owned the JS value, but now JS wants to own Nim. # This means we must release the JS reference, and add a reference # to Nim. GC_ref(cast[RootRef](p)) JS_SetOpaque(val, p) return val let class = rtOpaque.typemap.getOrDefault(tp, 0) let jsObj = JS_NewObjectFromCtor(ctx, ctor, class) if JS_IsException(jsObj): return jsObj # We are constructing a new JS object, so we must add unforgeable properties # here. if not ctx.setUnforgeable(jsObj, class): JS_FreeValue(ctx, jsObj) return JS_EXCEPTION rtOpaque.plist[p] = JS_VALUE_GET_PTR(jsObj) JS_SetOpaque(jsObj, p) GC_ref(cast[RootRef](p)) return jsObj when defined(gcDestructors): proc getTypeInfo2[T](x: T): pointer {.magic: "GetTypeInfoV2".} else: template getTypeInfo2[T](x: T): pointer = getTypeInfo(x) # Get a unique pointer for each type. template getTypePtr*[T: ref object and not RootRef](x: T): pointer = # This returns static type info, so it only works for non-inheritable # objects. getTypeInfo2(x[]) template getTypePtr*[T: object and not RootObj](x: var T): pointer = getTypeInfo2(x) template getTypePtr*(x: RootRef): pointer = # Dereference the object's first member, m_type. cast[ptr pointer](x)[] template getTypePtr*[T: RootObj](x: var T): pointer = # See above. cast[ptr pointer](addr x)[] template getTypePtr*[T: ref object](t: typedesc[T]): pointer = var x: typeof(T()[]) getTypeInfo2(x) proc toJSRefObj*(ctx: JSContext; obj: ref object): JSValue = let p = cast[pointer](obj) let tp = getTypePtr(obj) return ctx.toJSP0(p, tp, JS_UNDEFINED) proc toJS*(ctx: JSContext; obj: ref object): JSValue = if obj == nil: return JS_NULL return ctx.toJSRefObj(obj) proc toJSNew*(ctx: JSContext; obj: ref object; ctor: JSValueConst): JSValue = if obj == nil: return JS_NULL let p = cast[pointer](obj) let tp = getTypePtr(obj) return ctx.toJSP0(p, tp, ctor) proc toJSEnum(ctx: JSContext; enumId: int; n: int; s: string): JSValue = let rt = JS_GetRuntime(ctx) let rtOpaque = rt.getOpaque() if rtOpaque.enumMap.len <= enumId: rtOpaque.enumMap.setLen(enumId + 1) if rtOpaque.enumMap[enumId].atoms.len <= n: rtOpaque.enumMap[enumId].atoms.setLen(n + 1) var atom = rtOpaque.enumMap[enumId].atoms[n] if atom == JS_ATOM_NULL: atom = JS_NewAtomLen(ctx, cstringConst(s), csize_t(s.len)) if atom == JS_ATOM_NULL: return JS_EXCEPTION rtOpaque.enumMap[enumId].atoms[n] = atom return JS_AtomToValue(ctx, atom) const EnumCounter = CacheCounter("EnumCounter") proc getJSEnumId*[T: enum](t: typedesc[T]): int = const enumId = EnumCounter.value static: assert int(T.low) >= 0 inc EnumCounter enumId proc toJS*[T: enum](ctx: JSContext; e: T): JSValue = const enumId = getJSEnumId(T) ctx.toJSEnum(enumId, int(e), $e) proc toJS(ctx: JSContext; j: JSValue): JSValue = return j proc toJS*(ctx: JSContext; abuf: JSArrayBuffer): JSValue = return JS_NewArrayBuffer(ctx, abuf.p, abuf.len, abuf.dealloc, nil, false) proc toJS*(ctx: JSContext; u8a: JSArrayBufferView): JSValue = let jsabuf = ctx.toJS(u8a.abuf) if JS_IsException(jsabuf): return jsabuf let offset = ctx.toJS(u8a.offset) if JS_IsException(offset): JS_FreeValue(ctx, jsabuf) return offset let len = ctx.toJS(u8a.len) if JS_IsException(len): JS_FreeValue(ctx, jsabuf) JS_FreeValue(ctx, offset) return len let argv = [JSValueConst(jsabuf), JSValueConst(offset), JSValueConst(len)] let ret = JS_NewTypedArray(ctx, 3, argv.toJSValueConstArray(), u8a.t) JS_FreeValue(ctx, jsabuf) JS_FreeValue(ctx, offset) JS_FreeValue(ctx, len) return ret proc toJS*(ctx: JSContext; ns: NarrowString): JSValue = return JS_NewNarrowStringLen(ctx, cstring(ns), csize_t(string(ns).len)) proc definePropertyConvert*[T](ctx: JSContext; this: JSValueConst; name: cstring; x: T): DefinePropertyResult = let val = ctx.toJS(x) if JS_IsException(val): return dprException ctx.defineProperty(this, name, val) proc toJS*[T: JSDict](ctx: JSContext; dict: T): JSValue = let obj = JS_NewObject(ctx) if JS_IsException(obj): return obj block good: for k, v in dict.fieldPairs: when k != "toFree": if ctx.definePropertyConvert(obj, k, v) == dprException: break good return obj JS_FreeValue(ctx, obj) return JS_EXCEPTION {.pop.} # raises: [] �������������������������������������������������������chawan-v0.4.0/lib/monoucha0/monoucha/version.nim����������������������������������������������������0000664�0000000�0000000�00000000064�15202323131�0021574�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������const Major* = 0 const Minor* = 11 const Patch* = 0 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/nim.cfg�����������������������������������������������������������������0000664�0000000�0000000�00000000046�15202323131�0017035�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������--styleCheck:usages --styleCheck:hint ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/test/�������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0016550�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/test/basic.nim����������������������������������������������������������0000664�0000000�0000000�00000001147�15202323131�0020341�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import std/unittest import monoucha/fromjs import monoucha/jsbind import monoucha/jsutils import monoucha/quickjs type MyGlobal = ref object s: string proc testFun(x: MyGlobal): string {.jsfunc.} = return "Hello, " & x.s test "hello JS": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() let global = MyGlobal(s: "world!") ctx.registerType(MyGlobal, asglobal = true) ctx.setGlobal(global) const code = "testFun()" let val = ctx.eval(code, "<test>", 0) var res: string check ctx.fromJS(val, res).isOk check res == "Hello, world!" JS_FreeValue(ctx, val) ctx.free() rt.free() �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/test/etc.nim������������������������������������������������������������0000664�0000000�0000000�00000007232�15202323131�0020034�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import std/options import std/unittest import monoucha/fromjs import monoucha/jsbind import monoucha/jsnull import monoucha/jspropenumlist import monoucha/jstypes import monoucha/jsutils import monoucha/quickjs import monoucha/tojs type TestEnum = enum teA = "a", teB = "b", teC = "c" type TestEnum2 = enum te2C = "c", te2B = "b", te2A = "a" test "enums": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() let val = ctx.toJS(teB) var e: TestEnum assert ctx.fromJS(val, e).isOk assert e == teB var e2: TestEnum2 let val2 = ctx.toJS(te2A) assert ctx.fromJS(val2, e2).isOk assert e2 == te2A ctx.free() rt.free() test "enums null": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() let val = ctx.toJS("b\0c") var e: TestEnum assert ctx.fromJS(val, e).isErr ctx.free() rt.free() type TestDict0 = object of JSDict a {.jsdefault: true.}: bool b: int c {.jsdefault.}: TestEnum d: TestDict1 e {.jsdefault.}: int32 f {.jsdefault.}: Option[JSValueConst] TestDict1 = object of JSDict a: Option[JSValueConst] TestDict2 = object of JSDict a {.jsdefault.}: Option[JSValueConst] b {.jsdefault: 2.}: int c {.jsdefault.}: string TestDict3 = object of TestDict2 proc default(e: typedesc[TestEnum]): TestEnum = return teB test "jsdict undefined missing fields": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() var res: TestDict0 assert ctx.fromJS(JS_UNDEFINED, res).isErr ctx.free() rt.free() test "optional jsdict undefined": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() var res: TestDict2 assert ctx.fromJS(JS_UNDEFINED, res).isOk, ctx.getExceptionMsg() ctx.free() rt.free() test "optional jsdict inherited": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() var res: TestDict3 assert ctx.fromJS(JS_UNDEFINED, res).isOk, ctx.getExceptionMsg() assert res.b == 2 ctx.free() rt.free() proc subroutine(ctx: JSContext; val: JSValueConst) = var res: TestDict0 assert ctx.fromJS(val, res).isOk, ctx.getExceptionMsg() discard ctx.eval("delete val.f", "<input>") assert res.a assert res.b == 1 assert res.c == teB assert res.e == 0 assert res.d.a.isNone doAssert ctx.defineProperty(res.f.get, "x", JS_NewInt32(ctx, 9)) == dprSuccess test "jsdict transitive JSValue descendant": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() const code = """ const val = { b: 1, d: { a: null }, f: { x: 1 } } val""" let val = ctx.eval(code, "<input>") ctx.subroutine(val) GC_fullCollect() JS_FreeValue(ctx, val) ctx.free() rt.free() test "jspropenumlist": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() var list = newJSPropertyEnumList(ctx, 0) list.add(1) list.add("hi") list.add(3) list.add(4) assert list.len == 4 js_free(ctx, list.buffer) ctx.free() rt.free() test "fromjs-seq": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() var test = @[1, 2, 3, 4] let jsTest = ctx.toJS(test) var test2: seq[int] assert ctx.fromJS(jsTest, test2).isOk assert test2 == test JS_FreeValue(ctx, jsTest) ctx.free() rt.free() test "fromjs-tuple": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() var test = (2, "hi") let jsTest = ctx.toJS(test) var test2: tuple[n: int; s: string] assert ctx.fromJS(jsTest, test2).isOk assert test2 == test JS_FreeValue(ctx, jsTest) ctx.free() rt.free() type X = ref object jsDestructor(X) proc foo(x: X; s: sink string) {.jsfunc.} = discard proc bar(x: X; s: sink(string)) {.jsfunc.} = discard test "sink": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() ctx.registerType(X) ctx.free() rt.free() ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/test/jsfile.nim���������������������������������������������������������0000664�0000000�0000000�00000000714�15202323131�0020533�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import std/posix import std/unittest import monoucha/javascript import monoucha/tojs type JSFile = ref object jsDestructor(JSFile) proc newJSFile(): JSFile {.jsctor.} = return JSFile() test "jsfin: object finalizers": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() ctx.registerType(JSFile) const code = """ { const file = new JSFile(); } const file = new JSFile(); """ JS_FreeValue(ctx, ctx.eval(code)) ctx.free() rt.free() ����������������������������������������������������chawan-v0.4.0/lib/monoucha0/test/manual.nim���������������������������������������������������������0000664�0000000�0000000�00000016704�15202323131�0020542�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import std/os import std/posix import std/strutils import std/unittest import results import monoucha/javascript import monoucha/jserror test "Hello, world": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() const code = "'Hello from JS!'" let val = ctx.eval(code) var res: string check ctx.fromJS(val, res).isOk check res == "Hello from JS!" JS_FreeValue(ctx, val) ctx.free() rt.free() test "Error handling": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() const code = "abcd" let res = ctx.eval(code, "<test>") check JS_IsException(res) const ex = """ ReferenceError: 'abcd' is not defined at <eval> (<test>:1:1) """ check ctx.getExceptionMsg() == ex check evalConvert[string](ctx, code, "<test>").error == ex JS_FreeValue(ctx, res) ctx.free() rt.free() type Planet = ref object of RootObj Earth = ref object of Planet Moon = ref object of Planet proc jsAssert(earth: Earth; pred: bool) {.jsfunc: "assert".} = assert pred test "registerType: registering type interfaces": type Moon = ref object jsDestructor(Moon) let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() ctx.registerType(Moon) const code = "Moon" let val = ctx.eval(code) var res: string check ctx.fromJS(val, res).isOk check res == """ function Moon() { [native code] }""" JS_FreeValue(ctx, val) ctx.free() rt.free() test "Global objects": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() let earth = Earth() ctx.registerType(Earth, asglobal = true) ctx.setGlobal(earth) const code = "assert(globalThis instanceof Earth)" let val = ctx.eval(code) check not JS_IsException(val) JS_FreeValue(ctx, val) ctx.free() rt.free() test "Inheritance": jsDestructor(Moon) jsDestructor(Planet) let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() let planetCID = ctx.registerType(Planet) ctx.registerType(Earth, parent = planetCID, asglobal = true) ctx.registerType(Moon, parent = planetCID) ctx.setGlobal(Earth()) const code = "assert(globalThis instanceof Planet)" let val = ctx.eval(code) check not JS_IsException(val) JS_FreeValue(ctx, val) ctx.free() rt.free() test "jsget, jsset: basic property reflectors": type Moon = ref object Earth = ref object moon {.jsget.}: Moon name {.jsgetset.}: string population {.jsset.}: int64 jsDestructor(Moon) let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() let earth = Earth(moon: Moon(), population: 1, name: "Earth") ctx.registerType(Earth, asglobal = true) ctx.registerType(Moon) ctx.setGlobal(earth) const code = """ globalThis.population = 8e9; "name: " + globalThis.name + ", moon: " + globalThis.moon; """ let val = ctx.eval(code) var res: string check ctx.fromJS(val, res).isOk check res == "name: Earth, moon: [object Moon]" check earth.population == int64(8e9) JS_FreeValue(ctx, val) ctx.free() rt.free() type Window = ref object console {.jsget.}: Console Console = ref object jsDestructor(Console) # aux stuff for tests proc jsAssert(window: Window; pred: bool) {.jsfunc: "assert".} = assert pred test "jsfunc: regular functions": proc log(console: Console; s: string) {.jsfunc.} = echo s let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() let window = Window(console: Console()) ctx.registerType(Window, asglobal = true) ctx.registerType(Console) ctx.setGlobal(window) const code = """ console.log('Hello, world!') """ let val = ctx.eval(code) check not JS_IsException(val) JS_FreeValue(ctx, val) ctx.free() rt.free() type JSFile = ref object buffer: pointer # some internal buffer handled as managed memory path {.jsget.}: string jsDestructor(JSFile) proc newJSFile(path: string): JSFile {.jsctor.} = return JSFile( path: path, buffer: alloc(4096) ) test "jsctor: constructors": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() ctx.registerType(Window, asglobal = true) ctx.registerType(JSFile, name = "File") ctx.setGlobal(Window()) const code = """ assert(new File('/path/to/file') + '' == '[object File]') """ let val = ctx.eval(code) check not JS_IsException(val) JS_FreeValue(ctx, val) ctx.free() rt.free() func name(file: JSFile): string {.jsfget.} = return file.path.substr(file.path.rfind('/') + 1) proc setName(file: JSFile; s: string) {.jsfset: "name".} = let i = file.path.rfind('/') file.path = file.path.substr(0, i) & s test "jsfget, jsfset: custom property reflectors": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() ctx.registerType(Window, asglobal = true) ctx.registerType(JSFile, name = "File") ctx.setGlobal(Window()) const code = """ const file = new File("/path/to/file"); assert(file.path === "/path/to/file"); assert(file.name === "file"); /* file */ file.name = "new-name"; assert(file.path === "/path/to/new-name"); """ let val = ctx.eval(code) check not JS_IsException(val) JS_FreeValue(ctx, val) ctx.free() rt.free() proc jsExists(path: string): bool {.jsstfunc: "JSFile#exists".} = return fileExists(path) test "jsstfunc: static functions": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() ctx.registerType(Window, asglobal = true) ctx.registerType(JSFile, name = "File") ctx.setGlobal(Window()) const code = """ assert(File.exists("doc/manual.md")); """ let val = ctx.eval(code) check not JS_IsException(val) JS_FreeValue(ctx, val) ctx.free() rt.free() # this will always return the result of the fstat call. proc owner(file: JSFile): int {.jsuffget.} = let fd = open(cstring(file.path), O_RDONLY, 0) if fd == -1: return -1 var stats = Stat.default if fstat(fd, stats) == -1: discard close(fd) return -1 return int(stats.st_uid) proc getOwner(file: JSFile): int {.jsuffget.} = return file.owner test "jsuffunc, jsufget, jsuffget: the LegacyUnforgeable property": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() ctx.registerType(Window, asglobal = true) ctx.registerType(JSFile, name = "File") const code = """ const file = new File("doc/manual.md"); const oldGetOwner = file.getOwner; file.getOwner = () => -2; /* doesn't work */ assert(oldGetOwner == file.getOwner); Object.defineProperty(file, "owner", { value: -2 }); /* throws */ """ let val = ctx.eval(code) check JS_IsException(val) JS_FreeValue(ctx, val) ctx.free() rt.free() var unrefd {.global.} = 0 proc finalize(file: JSFile) {.jsfin.} = if file.buffer != nil: dealloc(file.buffer) # Note: it is not necessary to nil out the pointer; it's just me being # paranoid :P file.buffer = nil inc unrefd test "jsfin: object finalizers": let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() GC_fullCollect() # ensure refc runs unrefd = 0 # ignore previous unrefs ctx.registerType(Window, asglobal = true) ctx.registerType(JSFile, name = "File") const code = """ /* this doesn't leak. yay :D */ { const file = new File("doc/manual.md"); } /* note that I put the above call in a separate scope, so QJS can unref * it immediately. in contrast, following file will not be deallocated until * the runtime is gone. */ const file = new File("doc/manual.md"); """ JS_FreeValue(ctx, ctx.eval(code)) GC_fullCollect() # ensure refc runs check unrefd == 1 # first file is already deallocated ctx.free() GC_fullCollect() # ensure refc runs check unrefd == 1 # the second file is still available rt.free() check unrefd == 2 # runtime is freed, so the second file gets deallocated too ������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/test/regexonly.nim������������������������������������������������������0000664�0000000�0000000�00000001103�15202323131�0021264�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import std/unittest import monoucha/libregexp proc match(re, str: string): bool = var plen: cint var e = newString(64) let bytecode = lre_compile(plen, cstring(e), cint(e.len), cstring(re), csize_t(re.len), 0, nil) let captureCount = lre_get_capture_count(bytecode) var capture = newSeq[ptr uint8](captureCount * 2) let res = lre_exec(addr capture[0], bytecode, cast[ptr uint8](cstring(str)), 0, cint(str.len), 3, nil) res == 1 test "regex only": check match(".*", "whatever") check match(".*", "") test r"\b": check not "\bth\b".match("Weather") �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/test/results.nim��������������������������������������������������������0000664�0000000�0000000�00000153505�15202323131�0020767�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (c) 2019 Jacek Sieka # Licensed and distributed under either of # * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT). # * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). # at your option. This file may not be copied, modified, or distributed except according to those terms. type ResultError*[E] = object of ValueError ## Error raised when using `tryValue` value of result when error is set ## See also Exception bridge mode error*: E ResultDefect* = object of Defect ## Defect raised when accessing value when error is set and vice versa ## See also Exception bridge mode Result*[T, E] = object ## Result type that can hold either a value or an error, but not both ## ## # Example ## ## ``` ## import results ## ## # Re-export `results` so that API is always available to users of your module! ## export results ## ## # It's convenient to create an alias - most likely, you'll do just fine ## # with strings or cstrings as error for a start ## ## type R = Result[int, string] ## ## # Once you have a type, use `ok` and `err`: ## ## func works(): R = ## # ok says it went... ok! ## R.ok 42 ## func fails(): R = ## # or type it like this, to not repeat the type: ## result.err "bad luck" ## ## func alsoWorks(): R = ## # or just use the shortcut - auto-deduced from the return type! ## ok(24) ## ## if (let w = works(); w.isOk): ## echo w[], " or use value: ", w.value ## ## # In case you think your callers want to differentiate between errors: ## type ## Error = enum ## a, b, c ## type RE[T] = Result[T, Error] ## ## # You can use the question mark operator to pass errors up the call stack ## func f(): R = ## let x = ?works() - ?fails() ## assert false, "will never reach" ## ## # If you provide this exception converter, this exception will be raised on ## # `tryValue`: ## func toException(v: Error): ref CatchableError = (ref CatchableError)(msg: $v) ## try: ## RE[int].err(a).tryValue() ## except CatchableError: ## echo "in here!" ## ## # You can use `Opt[T]` as a replacement for `Option` = `Opt` is an alias for ## # `Result[T, void]`, meaning you can use the full `Result` API on it: ## let x = Opt[int].ok(42) ## echo x.get() ## ## # ... or `Result[void, E]` as a replacement for `bool`, providing extra error ## # information! ## let y = Result[void, string].err("computation failed") ## echo y.error() ## ## ``` ## ## See the tests for more practical examples, specially when working with ## back and forth with the exception world! ## ## # Potential benefits: ## ## * Handling errors becomes explicit and mandatory at the call site - ## goodbye "out of sight, out of mind" ## * Errors are a visible part of the API - when they change, so must the ## calling code and compiler will point this out - nice! ## * Errors are a visible part of the API - your fellow programmer is ## reminded that things actually can go wrong ## * Jives well with Nim `discard` ## * Jives well with the new Defect exception hierarchy, where defects ## are raised for unrecoverable errors and the rest of the API uses ## results ## * Error and value return have similar performance characteristics ## * Caller can choose to turn them into exceptions at low cost - flexible ## for libraries! ## * Mostly relies on simple Nim features - though this library is no ## exception in that compiler bugs were discovered writing it :) ## ## # Potential costs: ## ## * Handling errors becomes explicit and mandatory - if you'd rather ignore ## them or just pass them to some catch-all, this is noise ## * When composing operations, value must be lifted before processing, ## adding potential verbosity / noise (fancy macro, anyone?) ## * There's no call stack captured by default (see also `catch` and ## `capture`) ## * The extra branching may be more expensive for the non-error path ## (though this can be minimized with PGO) ## ## The API visibility issue of exceptions can also be solved with ## `{.raises.}` annotations - as of now, the compiler doesn't remind ## you to do so, even though it knows what the right annotation should be. ## `{.raises.}` does not participate in generic typing, making it just as ## verbose but less flexible in some ways, if you want to type it out. ## ## Many system languages make a distinction between errors you want to ## handle and those that are simply bugs or unrealistic to deal with.. ## handling the latter will often involve aborting or crashing the funcess - ## reliable systems like Erlang will try to relaunch it. ## ## On the flip side we have dynamic languages like python where there's ## nothing exceptional about exceptions (hello StopIterator). Python is ## rarely used to build reliable systems - its strengths lie elsewhere. ## ## # Exception bridge mode ## ## When the error of a `Result` is an `Exception`, or a `toException` helper ## is present for your error type, the "Exception bridge mode" is ## enabled and instead of raising `ResultError`, `tryValue` will raise the ## given `Exception` on access. `[]` and `value` will continue to raise a ## `Defect`. ## ## This is an experimental feature that may be removed. ## ## # Other languages ## ## Result-style error handling seems pretty popular lately, specially with ## statically typed languages: ## Haskell: https://hackage.haskell.org/package/base-4.11.1.0/docs/Data-Either.html ## Rust: https://doc.rust-lang.org/std/result/enum.Result.html ## Modern C++: https://en.cppreference.com/w/cpp/utility/expected ## More C++: https://github.com/ned14/outcome ## ## Swift is interesting in that it uses a non-exception implementation but ## calls errors exceptions and has lots of syntactic sugar to make them feel ## that way by implicitly passing them up the call chain - with a mandatory ## annotation that function may throw: ## https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html ## ## # Considerations for the error type ## ## * Use a `string` or a `cstring` if you want to provide a diagnostic for ## the caller without an expectation that they will differentiate between ## different errors. Callers should never parse the given string! ## * Use an `enum` to provide in-depth errors where the caller is expected ## to have different logic for different errors ## * Use a complex type to include error-specific meta-data - or make the ## meta-data collection a visible part of your API in another way - this ## way it remains discoverable by the caller! ## ## A natural "error API" progression is starting with `Opt[T]`, then ## `Result[T, cstring]`, `Result[T, enum]` and `Result[T, object]` in ## escalating order of complexity. ## ## # Result equivalences with other types ## ## Result allows tightly controlling the amount of information that a ## function gives to the caller: ## ## ## `Result[void, void] == bool` ## ## Neither value nor error information, it either worked or didn't. Most ## often used for `proc`:s with side effects. ## ## ## `Result[T, void] == Option[T]` ## ## Return value if it worked, else tell the caller it failed. Most often ## used for simple computations. ## ## Works as a replacement for `Option[T]` (aliased as `Opt[T]`) ## ## ## `Result[T, E]` - ## ## Return value if it worked, or a statically known piece of information ## when it didn't - most often used when a function can fail in more than ## one way - E is typically a `string` or an `enum`. ## ## ## `Result[T, ref E]` ## ## Returning a `ref E` allows introducing dynamically typed error ## information, similar to exceptions. ## ## # Other implemenations in nim ## ## There are other implementations in nim that you might prefer: ## * Either from nimfp: https://github.com/vegansk/nimfp/blob/master/src/fp/either.nim ## * result_type: https://github.com/kapralos/result_type/ ## ## `Option` compatibility ## ## `Result[T, void]` is similar to `Option[T]`, except it can be used with ## all `Result` operators and helpers. ## ## One difference is `Option[ref|ptr T]` which disallows `nil` - `Opt[T]` ## allows an "ok" result to hold `nil` - this can be useful when `nil` is ## a valid outcome of a function, but increases complexity for the caller. ## ## # Implementation notes ## ## This implementation is mostly based on the one in rust. Compared to it, ## there are a few differences - if know of creative ways to improve things, ## I'm all ears. ## ## * Rust has the enum variants which lend themselves to nice construction ## where the full Result type isn't needed: `Err("some error")` doesn't ## need to know value type - maybe some creative converter or something ## can deal with this? ## * Nim templates allow us to fail fast without extra effort, meaning the ## other side of `and`/`or` isn't evaluated unless necessary - nice! ## * Rust uses From traits to deal with result translation as the result ## travels up the call stack - needs more tinkering - some implicit ## conversions would be nice here ## * Pattern matching in rust allows convenient extraction of value or error ## in one go. ## ## # Performance considerations ## ## When returning a Result instead of a simple value, there are a few things ## to take into consideration - in general, we are returning more ## information directly to the caller which has an associated cost. ## ## Result is a value type, thus its performance characteristics ## generally follow the performance of copying the value or error that ## it stores. `Result` would benefit greatly from "move" support in the ## language. ## ## In many cases, these performance costs are negligeable, but nonetheless ## they are important to be aware of, to structure your code in an efficient ## manner: ## ## * Memory overhead ## Result is stored in memory as a union with a `bool` discriminator - ## alignment makes it somewhat tricky to give an exact size, but in ## general, `Result[int, int]` will take up `2*sizeof(int)` bytes: ## 1 `int` for the discriminator and padding, 1 `int` for either the value ## or the error. The additional size means that returning may take up more ## registers or spill onto the stack. ## * Loss of RVO ## Nim does return-value-optimization by rewriting `proc f(): X` into ## `proc f(result: var X)` - in an expression like `let x = f()`, this ## allows it to avoid a copy from the "temporary" return value to `x` - ## when using Result, this copy currently happens always because you need ## to fetch the value from the Result in a second step: `let x = f().value` ## * Extra copies ## To avoid spurious evaluation of expressions in templates, we use a ## temporary variable sometimes - this means an unnecessary copy for some ## types. ## * Bad codegen ## When doing RVO, Nim generates poor and slow code: it uses a construct ## called `genericReset` that will zero-initialize a value using dynamic ## RTTI - a process that the C compiler subsequently is unable to ## optimize. This applies to all types, but is exacerbated with Result ## because of its bigger footprint - this should be fixed in compiler. ## * Double zero-initialization bug ## Nim has an initialization bug that causes additional poor performance: ## `var x = f()` will be expanded into `var x; zeroInit(x); f(x)` where ## `f(x)` will call the slow `genericReset` and zero-init `x` again, ## unnecessarily. ## ## Comparing `Result` performance to exceptions in Nim is difficult - it ## will depend on the error type used, the frequency at which exceptions ## happen, the amount of error handling code in the application and the ## compiler and backend used. ## ## * the default C backend in nim uses `setjmp` for exception handling - ## the relative performance of the happy path will depend on the structure ## of the code: how many exception handlers there are, how much unwinding ## happens. `setjmp` works by taking a snapshot of the full CPU state and ## saving it to memory when enterting a try block (or an implict try ## block, such as is introduced with `defer` and similar constructs). ## * an efficient exception handling mechanism (like the C++ backend or ## `nlvm`) will usually have a lower cost on the happy path because the ## value can be returned more efficiently. However, there is still a code ## and data size increase depending on the specific situation, as well as ## loss of optimization opportunities to consider. ## * raising an exception is usually (a lot) slower than returning an error ## through a Result - at raise time, capturing a call stack and allocating ## memory for the Exception is expensive, so the performance difference ## comes down to the complexity of the error type used. ## * checking for errors with Result is local branching operation that also ## happens on the happy path - this may be a cost. ## ## An accurate summary might be that Exceptions are at its most efficient ## when errors are not handled and don't happen. ## ## # Relevant nim bugs ## ## https://github.com/nim-lang/Nim/issues/13799 - type issues ## https://github.com/nim-lang/Nim/issues/8745 - genericReset slow ## https://github.com/nim-lang/Nim/issues/13879 - double-zero-init slow ## https://github.com/nim-lang/Nim/issues/14318 - generic error raises pragma (fixed in 1.6.14+) ## https://github.com/nim-lang/Nim/issues/23741 - inefficient codegen for temporaries ## https://github.com/nim-lang/Nim/issues/20699 (fixed in 2.0.0+) # case oResultPrivate: bool # of false: # eResultPrivate: E # of true: # vResultPrivate: T # ResultPrivate* works around (fixed in 1.6.14+): # * https://github.com/nim-lang/Nim/issues/3770 # * https://github.com/nim-lang/Nim/issues/20900 # # Do not use these fields directly in your code, they're not meant to be # public! when T is void: when E is void: oResultPrivate*: bool else: case oResultPrivate*: bool of false: eResultPrivate*: E of true: discard else: when E is void: case oResultPrivate*: bool of false: discard of true: vResultPrivate*: T else: case oResultPrivate*: bool of false: eResultPrivate*: E of true: vResultPrivate*: T Opt*[T] = Result[T, void] const resultsGenericsOpenSym* {.booldefine.} = true ## Enable the experimental `genericsOpenSym` feature or a workaround for the ## template injection problem in the issue linked below where scoped symbol ## resolution works differently for expanded bodies in templates depending on ## whether we're in a generic context or not. ## ## The issue leads to surprising errors where symbols from outer scopes get ## bound instead of the symbol created in the template scope which should be ## seen as a better candidate, breaking access to `error` in `valueOr` and ## friends. ## ## In Nim versions that do not support `genericsOpenSym`, a macro is used ## instead to reassign symbol matches which may or may not work depending on ## the complexity of the code. ## ## Nim 2.0.8 was released with an incomplete fix but already declares ## `nimHasGenericsOpenSym`. # TODO https://github.com/nim-lang/Nim/issues/22605 # TODO https://github.com/arnetheduck/nim-results/issues/34 # TODO https://github.com/nim-lang/Nim/issues/23386 # TODO https://github.com/nim-lang/Nim/issues/23385 # # Related PR:s (there's more probably, but this gives an overview) # https://github.com/nim-lang/Nim/pull/23102 # https://github.com/nim-lang/Nim/pull/23572 # https://github.com/nim-lang/Nim/pull/23873 # https://github.com/nim-lang/Nim/pull/23892 # https://github.com/nim-lang/Nim/pull/23939 resultsGenericsOpenSymWorkaround* {.booldefine.} = resultsGenericsOpenSym and not defined(nimHasGenericsOpenSym2) ## Prefer macro workaround to solve genericsOpenSym issue # TODO https://github.com/nim-lang/Nim/pull/23892#discussion_r1713434311 resultsGenericsOpenSymWorkaroundHint* {.booldefine.} = true resultsLent {.booldefine.} = (NimMajor, NimMinor, NimPatch) >= (2, 2, 0) or (defined(gcRefc) and ((NimMajor, NimMinor, NimPatch) >= (2, 0, 8))) ## Enable return of `lent` types - this *mostly* works in Nim 1.6.18+ but ## there have been edge cases reported as late as 1.6.14 - YMMV - ## conservatively, `lent` is therefore enabled only with the latest Nim ## version at the time of writing, where it could be verified to work with ## several large applications. ## ## ORC is not expected to work until 2.2. ## https://github.com/nim-lang/Nim/issues/23973 when resultsLent: template maybeLent(T: untyped): untyped = lent T else: template maybeLent(T: untyped): untyped = T func raiseResultOk[T, E](self: Result[T, E]) {.noreturn, noinline.} = # noinline because raising should take as little space as possible at call # site when T is void: raise (ref ResultError[void])(msg: "Trying to access error with value") else: raise (ref ResultError[T])( msg: "Trying to access error with value", error: self.vResultPrivate ) func raiseResultError[T, E](self: Result[T, E]) {.noreturn, noinline.} = # noinline because raising should take as little space as possible at call # site mixin toException when E is ref Exception: if self.eResultPrivate.isNil: # for example Result.default()! raise (ref ResultError[void])(msg: "Trying to access value with err (nil)") raise self.eResultPrivate elif E is void: raise (ref ResultError[void])(msg: "Trying to access value with err") elif compiles(toException(self.eResultPrivate)): raise toException(self.eResultPrivate) elif compiles($self.eResultPrivate): raise (ref ResultError[E])(error: self.eResultPrivate, msg: $self.eResultPrivate) else: raise (ref ResultError[E])( msg: "Trying to access value with err", error: self.eResultPrivate ) func raiseResultDefect(m: string, v: auto) {.noreturn, noinline.} = mixin `$` when compiles($v): raise (ref ResultDefect)(msg: m & ": " & $v) else: raise (ref ResultDefect)(msg: m) func raiseResultDefect(m: string) {.noreturn, noinline.} = raise (ref ResultDefect)(msg: m) template withAssertOk(self: Result, body: untyped): untyped = # Careful - `self` evaluated multiple times, which is fine in all current uses case self.oResultPrivate of false: when self.E isnot void: raiseResultDefect("Trying to access value with err Result", self.eResultPrivate) else: raiseResultDefect("Trying to access value with err Result") of true: body template ok*[T: not void, E](R: type Result[T, E], x: untyped): R = ## Initialize a result with a success and value ## Example: `Result[int, string].ok(42)` R(oResultPrivate: true, vResultPrivate: x) template ok*[E](R: type Result[void, E]): R = ## Initialize a result with a success and value ## Example: `Result[void, string].ok()` R(oResultPrivate: true) template ok*[T: not void, E](self: var Result[T, E], x: untyped) = ## Set the result to success and update value ## Example: `result.ok(42)` self = ok(type self, x) template ok*[E](self: var Result[void, E]) = ## Set the result to success and update value ## Example: `result.ok()` self = (type self).ok() template err*[T; E: not void](R: type Result[T, E], x: untyped): R = ## Initialize the result to an error ## Example: `Result[int, string].err("uh-oh")` R(oResultPrivate: false, eResultPrivate: x) template err*[T](R: type Result[T, cstring], x: string): R = ## Initialize the result to an error ## Example: `Result[int, string].err("uh-oh")` const s = x # avoid dangling cstring pointers R(oResultPrivate: false, eResultPrivate: cstring(s)) template err*[T](R: type Result[T, void]): R = ## Initialize the result to an error ## Example: `Result[int, void].err()` R(oResultPrivate: false) template err*[T; E: not void](self: var Result[T, E], x: untyped) = ## Set the result as an error ## Example: `result.err("uh-oh")` self = err(type self, x) template err*[T](self: var Result[T, cstring], x: string) = const s = x # Make sure we don't return a dangling pointer self = err(type self, cstring(s)) template err*[T](self: var Result[T, void]) = ## Set the result as an error ## Example: `result.err()` self = err(type self) template ok*(v: auto): auto = ok(typeof(result), v) template ok*(): auto = ok(typeof(result)) template err*(v: auto): auto = err(typeof(result), v) template err*(): auto = err(typeof(result)) template isOk*(self: Result): bool = self.oResultPrivate template isErr*(self: Result): bool = not self.oResultPrivate when not defined(nimHasEffectsOfs): template effectsOf(f: untyped) {.pragma, used.} func map*[T0: not void, E; T1: not void]( self: Result[T0, E], f: proc(x: T0): T1 ): Result[T1, E] {.inline, effectsOf: f.} = ## Transform value using f, or return error ## ## ``` ## let r = Result[int, cstring).ok(42) ## assert r.map(proc (v: int): int = $v).value() == "42" ## ``` case self.oResultPrivate of true: when T1 is void: f(self.vResultPrivate) result.ok() else: result.ok(f(self.vResultPrivate)) of false: when E is void: result.err() else: result.err(self.eResultPrivate) func map*[T: not void, E]( self: Result[T, E], f: proc(x: T) ): Result[void, E] {.inline, effectsOf: f.} = ## Transform value using f, or return error ## ## ``` ## let r = Result[int, cstring).ok(42) ## assert r.map(proc (v: int): int = $v).value() == "42" ## ``` case self.oResultPrivate of true: f(self.vResultPrivate) result.ok() of false: when E is void: result.err() else: result.err(self.eResultPrivate) func map*[E; T1: not void]( self: Result[void, E], f: proc(): T1 ): Result[T1, E] {.inline, effectsOf: f.} = ## Transform value using f, or return error case self.oResultPrivate of true: result.ok(f()) of false: when E is void: result.err() else: result.err(self.eResultPrivate) func map*[E]( self: Result[void, E], f: proc() ): Result[void, E] {.inline, effectsOf: f.} = ## Call f if `self` is ok case self.oResultPrivate of true: f() result.ok() of false: when E is void: result.err() else: result.err(self.eResultPrivate) func flatMap*[T0: not void, E, T1]( self: Result[T0, E], f: proc(x: T0): Result[T1, E] ): Result[T1, E] {.inline, effectsOf: f.} = case self.oResultPrivate of true: f(self.vResultPrivate) of false: when E is void: Result[T1, void].err() else: Result[T1, E].err(self.eResultPrivate) func flatMap*[E, T1]( self: Result[void, E], f: proc(): Result[T1, E] ): Result[T1, E] {.inline, effectsOf: f.} = case self.oResultPrivate of true: f() of false: when E is void: Result[T1, void].err() else: Result[T1, E].err(self.eResultPrivate) func mapErr*[T; E0: not void, E1: not void]( self: Result[T, E0], f: proc(x: E0): E1 ): Result[T, E1] {.inline, effectsOf: f.} = ## Transform error using f, or leave untouched case self.oResultPrivate of true: when T is void: result.ok() else: result.ok(self.vResultPrivate) of false: result.err(f(self.eResultPrivate)) func mapErr*[T; E1: not void]( self: Result[T, void], f: proc(): E1 ): Result[T, E1] {.inline, effectsOf: f.} = ## Transform error using f, or return value case self.oResultPrivate of true: when T is void: result.ok() else: result.ok(self.vResultPrivate) of false: result.err(f()) func mapErr*[T; E0: not void]( self: Result[T, E0], f: proc(x: E0) ): Result[T, void] {.inline, effectsOf: f.} = ## Transform error using f, or return value case self.oResultPrivate of true: when T is void: result.ok() else: result.ok(self.vResultPrivate) of false: f(self.eResultPrivate) result.err() func mapErr*[T]( self: Result[T, void], f: proc() ): Result[T, void] {.inline, effectsOf: f.} = ## Transform error using f, or return value case self.oResultPrivate of true: when T is void: result.ok() else: result.ok(self.vResultPrivate) of false: f() result.err() func mapConvert*[T0: not void, E]( self: Result[T0, E], T1: type ): Result[T1, E] {.inline.} = ## Convert result value to A using an conversion # Would be nice if it was automatic... case self.oResultPrivate of true: when T1 is void: result.ok() else: result.ok(T1(self.vResultPrivate)) of false: when E is void: result.err() else: result.err(self.eResultPrivate) func mapCast*[T0: not void, E]( self: Result[T0, E], T1: type ): Result[T1, E] {.inline.} = ## Convert result value to A using a cast ## Would be nice with nicer syntax... case self.oResultPrivate of true: when T1 is void: result.ok() else: result.ok(cast[T1](self.vResultPrivate)) of false: when E is void: result.err() else: result.err(self.eResultPrivate) func mapConvertErr*[T, E0](self: Result[T, E0], E1: type): Result[T, E1] {.inline.} = ## Convert result error to E1 using an conversion # Would be nice if it was automatic... when E0 is E1: result = self else: if self.oResultPrivate: when T is void: result.ok() else: result.ok(self.vResultPrivate) else: when E1 is void: result.err() else: result.err(E1(self.eResultPrivate)) func mapCastErr*[T, E0](self: Result[T, E0], E1: type): Result[T, E1] {.inline.} = ## Convert result value to A using a cast ## Would be nice with nicer syntax... if self.oResultPrivate: when T is void: result.ok() else: result.ok(self.vResultPrivate) else: result.err(cast[E1](self.eResultPrivate)) template `and`*[T0, E, T1](self: Result[T0, E], other: Result[T1, E]): Result[T1, E] = ## Evaluate `other` iff self.isOk, else return error ## fail-fast - will not evaluate other if a is an error let s = (self) # TODO avoid copy case s.oResultPrivate of true: other of false: when type(self) is type(other): s else: type R = type(other) when E is void: err(R) else: err(R, s.eResultPrivate) template `or`*[T, E0, E1](self: Result[T, E0], other: Result[T, E1]): Result[T, E1] = ## Evaluate `other` iff `not self.isOk`, else return `self` ## fail-fast - will not evaluate `other` if `self` is ok ## ## ``` ## func f(): Result[int, SomeEnum] = ## f2() or err(SomeEnum.V) # Collapse errors from other module / function ## ``` let s = (self) # TODO avoid copy case s.oResultPrivate of true: when type(self) is type(other): s else: type R = type(other) when T is void: ok(R) else: ok(R, s.vResultPrivate) of false: other template orErr*[T, E0, E1](self: Result[T, E0], error: E1): Result[T, E1] = ## Evaluate `other` iff `not self.isOk`, else return `self` ## fail-fast - will not evaluate `error` if `self` is ok ## ## ``` ## func f(): Result[int, SomeEnum] = ## f2().orErr(SomeEnum.V) # Collapse errors from other module / function ## ``` ## ## ** Experimental, may be removed ** let s = (self) # TODO avoid copy type R = Result[T, E1] case s.oResultPrivate of true: when type(self) is R: s else: when T is void: ok(R) else: ok(R, s.vResultPrivate) of false: err(R, error) template catch*(body: typed): Result[type(body), ref CatchableError] = ## Catch exceptions for body and store them in the Result ## ## ``` ## let r = catch: someFuncThatMayRaise() ## ``` type R = Result[type(body), ref CatchableError] try: when type(body) is void: body R.ok() else: R.ok(body) except CatchableError as eResultPrivate: R.err(eResultPrivate) template capture*[E: Exception](T: type, someExceptionExpr: ref E): Result[T, ref E] = ## Evaluate someExceptionExpr and put the exception into a result, making sure ## to capture a call stack at the capture site: ## ## ``` ## let eResultPrivate: Result[void, ValueError] = void.capture((ref ValueError)(msg: "test")) ## echo eResultPrivate.error().getStackTrace() ## ``` type R = Result[T, ref E] var ret: R try: # TODO is this needed? I think so, in order to grab a call stack, but # haven't actually tested... if true: # I'm sure there's a nicer way - this just works :) raise someExceptionExpr except E as caught: ret = R.err(caught) ret func `==`*[T0: not void, E0: not void, T1: not void, E1: not void]( lhs: Result[T0, E0], rhs: Result[T1, E1] ): bool {.inline.} = if lhs.oResultPrivate != rhs.oResultPrivate: false else: case lhs.oResultPrivate # and rhs.oResultPrivate implied of true: lhs.vResultPrivate == rhs.vResultPrivate of false: lhs.eResultPrivate == rhs.eResultPrivate func `==`*[E0, E1](lhs: Result[void, E0], rhs: Result[void, E1]): bool {.inline.} = if lhs.oResultPrivate != rhs.oResultPrivate: false else: case lhs.oResultPrivate # and rhs.oResultPrivate implied of true: true of false: lhs.eResultPrivate == rhs.eResultPrivate func `==`*[T0, T1](lhs: Result[T0, void], rhs: Result[T1, void]): bool {.inline.} = if lhs.oResultPrivate != rhs.oResultPrivate: false else: case lhs.oResultPrivate # and rhs.oResultPrivate implied of true: lhs.vResultPrivate == rhs.vResultPrivate of false: true func value*[E](self: Result[void, E]) {.inline.} = ## Fetch value of result if set, or raise Defect ## Exception bridge mode: raise given Exception instead ## See also: Option.get withAssertOk(self): discard func value*[T: not void, E](self: Result[T, E]): maybeLent T {.inline.} = ## Fetch value of result if set, or raise Defect ## Exception bridge mode: raise given Exception instead ## See also: Option.get withAssertOk(self): when T isnot void: # TODO: remove result usage. # A workaround for nim VM bug: # https://github.com/nim-lang/Nim/issues/22216 result = self.vResultPrivate func value*[T: not void, E](self: var Result[T, E]): var T {.inline.} = ## Fetch value of result if set, or raise Defect ## Exception bridge mode: raise given Exception instead ## See also: Option.get ( block: withAssertOk(self): addr self.vResultPrivate )[] template `[]`*[T: not void, E](self: Result[T, E]): T = ## Fetch value of result if set, or raise Defect ## Exception bridge mode: raise given Exception instead self.value() template `[]`*[E](self: Result[void, E]) = ## Fetch value of result if set, or raise Defect ## Exception bridge mode: raise given Exception instead self.value() template unsafeValue*[T: not void, E](self: Result[T, E]): T = ## Fetch value of result if set, undefined behavior if unset ## See also: `unsafeError` self.vResultPrivate template unsafeValue*[E](self: Result[void, E]) = ## Fetch value of result if set, undefined behavior if unset ## See also: `unsafeError` assert self.oResultPrivate # Emulate field access defect in debug builds func tryValue*[E](self: Result[void, E]) {.inline.} = ## Fetch value of result if set, or raise ## When E is an Exception, raise that exception - otherwise, raise a ResultError[E] mixin raiseResultError case self.oResultPrivate of false: self.raiseResultError() of true: discard func tryValue*[T: not void, E](self: Result[T, E]): maybeLent T {.inline.} = ## Fetch value of result if set, or raise ## When E is an Exception, raise that exception - otherwise, raise a ResultError[E] mixin raiseResultError case self.oResultPrivate of false: self.raiseResultError() of true: # TODO https://github.com/nim-lang/Nim/issues/22216 result = self.vResultPrivate func expect*[E](self: Result[void, E], m: string) = ## Return value of Result, or raise a `Defect` with the given message - use ## this helper to extract the value when an error is not expected, for example ## because the program logic dictates that the operation should never fail ## ## ```nim ## let r = Result[int, int].ok(42) ## # Put here a helpful comment why you think this won't fail ## echo r.expect("r was just set to ok(42)") ## ``` case self.oResultPrivate of false: when E isnot void: raiseResultDefect(m, self.eResultPrivate) else: raiseResultDefect(m) of true: discard func expect*[T: not void, E](self: Result[T, E], m: string): maybeLent T = ## Return value of Result, or raise a `Defect` with the given message - use ## this helper to extract the value when an error is not expected, for example ## because the program logic dictates that the operation should never fail ## ## ```nim ## let r = Result[int, int].ok(42) ## # Put here a helpful comment why you think this won't fail ## echo r.expect("r was just set to ok(42)") ## ``` case self.oResultPrivate of false: when E isnot void: raiseResultDefect(m, self.eResultPrivate) else: raiseResultDefect(m) of true: # TODO https://github.com/nim-lang/Nim/issues/22216 result = self.vResultPrivate func expect*[T: not void, E](self: var Result[T, E], m: string): var T = ( case self.oResultPrivate of false: when E isnot void: raiseResultDefect(m, self.eResultPrivate) else: raiseResultDefect(m) of true: addr self.vResultPrivate )[] func `$`*[T, E](self: Result[T, E]): string = ## Returns string representation of `self` case self.oResultPrivate of true: when T is void: "ok()" else: "ok(" & $self.vResultPrivate & ")" of false: when E is void: "none()" else: "err(" & $self.eResultPrivate & ")" func error*[T](self: Result[T, void]) = ## Fetch error of result if set, or raise Defect case self.oResultPrivate of true: when T isnot void: raiseResultDefect("Trying to access error when value is set", self.vResultPrivate) else: raiseResultDefect("Trying to access error when value is set") of false: discard func error*[T; E: not void](self: Result[T, E]): maybeLent E = ## Fetch error of result if set, or raise Defect case self.oResultPrivate of true: when T isnot void: raiseResultDefect("Trying to access error when value is set", self.vResultPrivate) else: raiseResultDefect("Trying to access error when value is set") of false: # TODO https://github.com/nim-lang/Nim/issues/22216 result = self.eResultPrivate func tryError*[T](self: Result[T, void]) {.inline.} = ## Fetch error of result if set, or raise ## Raises a ResultError[T] mixin raiseResultOk case self.oResultPrivate of true: self.raiseResultOk() of false: discard func tryError*[T; E: not void](self: Result[T, E]): maybeLent E {.inline.} = ## Fetch error of result if set, or raise ## Raises a ResultError[T] mixin raiseResultOk case self.oResultPrivate of true: self.raiseResultOk() of false: # TODO https://github.com/nim-lang/Nim/issues/22216 result = self.eResultPrivate template unsafeError*[T; E: not void](self: Result[T, E]): E = ## Fetch error of result if set, undefined behavior if unset ## See also: `unsafeValue` self.eResultPrivate template unsafeError*[T](self: Result[T, void]) = ## Fetch error of result if set, undefined behavior if unset ## See also: `unsafeValue` assert not self.oResultPrivate # Emulate field access defect in debug builds func optValue*[T, E](self: Result[T, E]): Opt[T] = ## Return the value of a Result as an Opt, or none if Result is an error case self.oResultPrivate of true: when T is void: Opt[void].ok() else: Opt.some(self.vResultPrivate) of false: Opt.none(T) func optError*[T, E](self: Result[T, E]): Opt[E] = ## Return the error of a Result as an Opt, or none if Result is a value case self.oResultPrivate of true: Opt.none(E) of false: Opt.some(self.eResultPrivate) # Alternative spellings for `value`, for `options` compatibility template get*[T: not void, E](self: Result[T, E]): T = self.value() template get*[E](self: Result[void, E]) = self.value() template tryGet*[T: not void, E](self: Result[T, E]): T = self.tryValue() template tryGet*[E](self: Result[void, E]) = self.tryValue() template unsafeGet*[T: not void, E](self: Result[T, E]): T = self.unsafeValue() template unsafeGet*[E](self: Result[void, E]) = self.unsafeValue() # `var` overloads should not be needed but result in invalid codegen (!): # https://github.com/nim-lang/Nim/issues/22049 (fixed in 1.6.16+) func get*[T: not void, E](self: var Result[T, E]): var T = self.value() func get*[T, E](self: Result[T, E], otherwise: T): T {.inline.} = ## Fetch value of result if set, or return the value `otherwise` ## See `valueOr` for a template version that avoids evaluating `otherwise` ## unless necessary case self.oResultPrivate of true: self.vResultPrivate of false: otherwise when resultsGenericsOpenSymWorkaround: import macros proc containsHack(n: NimNode): bool = if n.len == 0: n.eqIdent("isOkOr") or n.eqIdent("isErrOr") or n.eqIdent("valueOr") or n.eqIdent("errorOr") else: for child in n: if containsHack(child): return true false proc containsIdent(n: NimNode, what: string, with: NimNode): bool = if n == with: false # Don't replace if the right symbol is already being used elif n.eqIdent(what): true else: for child in n: if containsIdent(child, what, with): return true false proc replace(n: NimNode, what: string, with: NimNode): NimNode = if not containsIdent(n, what, with): # Fast path that avoids copies altogether return n if n == with: result = with elif n.eqIdent(what): when resultsGenericsOpenSymWorkaroundHint: hint("Replaced conflicting external symbol " & what, n) result = with else: case n.kind of nnkCallKinds: if n[0].containsHack(): # Don't replace inside nested expansion result = n elif n[0].eqIdent(what): if n.len == 1: if n[0] == with: result = n else: # No arguments - replace call symbol result = copyNimNode(n) result.add with when resultsGenericsOpenSymWorkaroundHint: hint("Replaced conflicting external symbol " & what, n[0]) else: # `error(...)` - replace args but not function name result = copyNimNode(n) result.add n[0] for i in 1 ..< n.len: result.add replace(n[i], what, with) else: result = copyNimNode(n) for i in 0 ..< n.len: result.add replace(n[i], what, with) of nnkExprEqExpr: # "error = xxx" - function call with named parameters and other weird stuff result = copyNimNode(n) result.add n[0] for i in 1 ..< n.len: result.add replace(n[i], what, with) of nnkLetSection, nnkVarSection, nnkFormalParams: result = copyNimNode(n) for i in 0 ..< n.len: result.add replace(n[i], what, with) of nnkDotExpr: # Ignore rhs in "abc.error" result = copyNimNode(n) result.add(replace(n[0], what, with)) result.add(n[1]) else: if ( n.kind == nnkForStmt and (n[0].eqIdent(what) or (n.len == 4 and n[1].eqIdent(what))) or (n.kind == nnkIdentDefs and n[0].eqIdent(what)) ): # Naming the symbol the same way requires lots of magic here - just # say no error("Shadowing variable declarations of `" & what & "` not supported", n[0]) result = copyNimNode(n) for i in 0 ..< n.len: result.add replace(n[i], what, with) macro replaceHack(body, what, with: untyped): untyped = # This hack replaces the `what` identifier with `with` except where # this replacing is not expected - this is an approximation of the intent # of injecting a template and likely doesn't cover all applicable cases result = replace(body, $what, with) template isOkOr*[T, E](self: Result[T, E], body: untyped) = ## Evaluate `body` iff result has been assigned an error ## `body` is evaluated lazily. ## ## Example: ## ``` ## let ## v = Result[int, string].err("hello") ## x = v.isOkOr: echo "not ok" ## # experimental: direct error access using an unqualified `error` symbol ## z = v.isOkOr: echo error ## ``` ## ## `error` access: ## ## TODO experimental, might change in the future ## ## The template contains a shortcut for accessing the error of the result, ## it can only be used outside of generic code, ## see https://github.com/status-im/nim-stew/issues/161#issuecomment-1397121386 let s = (self) # TODO avoid copy case s.oResultPrivate of false: when E isnot void: template error(): E {.used, gensym.} = s.eResultPrivate replaceHack(body, "error", error) else: body of true: discard template isErrOr*[T, E](self: Result[T, E], body: untyped) = ## Evaluate `body` iff result has been assigned a value ## `body` is evaluated lazily. ## ## Example: ## ``` ## let ## v = Result[int, string].ok(42) ## x = v.isErrOr: echo "not err" ## # experimental: direct value access using an unqualified `value` symbol ## z = v.isErrOr: echo value ## ``` ## ## `value` access: ## ## TODO experimental, might change in the future ## ## The template contains a shortcut for accessing the value of the result, ## it can only be used outside of generic code, ## see https://github.com/status-im/nim-stew/issues/161#issuecomment-1397121386 let s = (self) # TODO avoid copy case s.oResultPrivate of true: when T isnot void: template value(): T {.used, gensym.} = s.vResultPrivate replaceHack(body, "value", s.vResultPrivate) else: body of false: discard template valueOr*[T: not void, E](self: Result[T, E], def: untyped): T = ## Fetch value of result if set, or evaluate `def` ## `def` is evaluated lazily, and must be an expression of `T` or exit ## the scope (for example using `return` / `raise`) ## ## See `isOkOr` for a version that works with `Result[void, E]`. ## ## Example: ## ``` ## let ## v = Result[int, string].err("hello") ## x = v.valueOr: 42 # x == 42 now ## y = v.valueOr: raise (ref ValueError)(msg: "v is an error, gasp!") ## # experimental: direct error access using an unqualified `error` symbol ## z = v.valueOr: raise (ref ValueError)(msg: error) ## ``` ## ## `error` access: ## ## TODO experimental, might change in the future ## ## The template contains a shortcut for accessing the error of the result, ## it can only be used outside of generic code, ## see https://github.com/status-im/nim-stew/issues/161#issuecomment-1397121386 ## let s = (self) # TODO avoid copy case s.oResultPrivate of true: s.vResultPrivate of false: when E isnot void: template error(): E {.used, gensym.} = s.eResultPrivate replaceHack(def, "error", error) else: def template errorOr*[T; E: not void](self: Result[T, E], def: untyped): E = ## Fetch error of result if not set, or evaluate `def` ## `def` is evaluated lazily, and must be an expression of `T` or exit ## the scope (for example using `return` / `raise`) ## ## See `isErrOr` for a version that works with `Result[T, void]`. let s = (self) # TODO avoid copy case s.oResultPrivate of false: s.eResultPrivate of true: when T isnot void: template value(): T {.used, gensym.} = s.vResultPrivate replaceHack(def, "value", value) else: def else: # TODO https://github.com/nim-lang/Nim/pull/23892#discussion_r1713434311 const pushGenericsOpenSym = defined(nimHasGenericsOpenSym2) and resultsGenericsOpenSym template isOkOr*[T, E](self: Result[T, E], body: untyped) = ## Evaluate `body` iff result has been assigned an error ## `body` is evaluated lazily. ## ## Example: ## ``` ## let ## v = Result[int, string].err("hello") ## x = v.isOkOr: echo "not ok" ## # experimental: direct error access using an unqualified `error` symbol ## z = v.isOkOr: echo error ## ``` ## ## `error` access: ## ## TODO experimental, might change in the future ## ## The template contains a shortcut for accessing the error of the result, ## it can only be used outside of generic code, ## see https://github.com/status-im/nim-stew/issues/161#issuecomment-1397121386 let s = (self) # TODO avoid copy case s.oResultPrivate of false: when E isnot void: when pushGenericsOpenSym: {.push experimental: "genericsOpenSym".} template error(): E {.used.} = s.eResultPrivate body of true: discard template isErrOr*[T, E](self: Result[T, E], body: untyped) = ## Evaluate `body` iff result has been assigned a value ## `body` is evaluated lazily. ## ## Example: ## ``` ## let ## v = Result[int, string].ok(42) ## x = v.isErrOr: echo "not err" ## # experimental: direct value access using an unqualified `value` symbol ## z = v.isErrOr: echo value ## ``` ## ## `value` access: ## ## TODO experimental, might change in the future ## ## The template contains a shortcut for accessing the value of the result, ## it can only be used outside of generic code, ## see https://github.com/status-im/nim-stew/issues/161#issuecomment-1397121386 let s = (self) # TODO avoid copy case s.oResultPrivate of true: when T isnot void: when pushGenericsOpenSym: {.push experimental: "genericsOpenSym".} template value(): T {.used.} = s.vResultPrivate body of false: discard template valueOr*[T: not void, E](self: Result[T, E], def: untyped): T = ## Fetch value of result if set, or evaluate `def` ## `def` is evaluated lazily, and must be an expression of `T` or exit ## the scope (for example using `return` / `raise`) ## ## See `isOkOr` for a version that works with `Result[void, E]`. ## ## Example: ## ``` ## let ## v = Result[int, string].err("hello") ## x = v.valueOr: 42 # x == 42 now ## y = v.valueOr: raise (ref ValueError)(msg: "v is an error, gasp!") ## # experimental: direct error access using an unqualified `error` symbol ## z = v.valueOr: raise (ref ValueError)(msg: error) ## ``` ## ## `error` access: ## ## TODO experimental, might change in the future ## ## The template contains a shortcut for accessing the error of the result, ## it can only be used outside of generic code, ## see https://github.com/status-im/nim-stew/issues/161#issuecomment-1397121386 ## let s = (self) # TODO avoid copy case s.oResultPrivate of true: s.vResultPrivate of false: when E isnot void: when pushGenericsOpenSym: {.push experimental: "genericsOpenSym".} template error(): E {.used.} = s.eResultPrivate def template errorOr*[T; E: not void](self: Result[T, E], def: untyped): E = ## Fetch error of result if not set, or evaluate `def` ## `def` is evaluated lazily, and must be an expression of `T` or exit ## the scope (for example using `return` / `raise`) ## ## See `isErrOr` for a version that works with `Result[T, void]`. let s = (self) # TODO avoid copy case s.oResultPrivate of false: s.eResultPrivate of true: when T isnot void: when pushGenericsOpenSym: {.push experimental: "genericsOpenSym".} template value(): T {.used.} = s.vResultPrivate def func flatten*[T, E](self: Result[Result[T, E], E]): Result[T, E] = ## Remove one level of nesting case self.oResultPrivate of true: self.vResultPrivate of false: when E is void: err(Result[T, E]) else: err(Result[T, E], self.error) func filter*[T, E]( self: Result[T, E], callback: proc(x: T): Result[void, E] ): Result[T, E] {.effectsOf: callback.} = ## Apply `callback` to the `self`, iff `self` is not an error. If `callback` ## returns an error, return that error, else return `self` case self.oResultPrivate of true: callback(self.vResultPrivate) and self of false: self func filter*[E]( self: Result[void, E], callback: proc(): Result[void, E] ): Result[void, E] {.effectsOf: callback.} = ## Apply `callback` to the `self`, iff `self` is not an error. If `callback` ## returns an error, return that error, else return `self` case self.oResultPrivate of true: callback() and self of false: self func filter*[T]( self: Result[T, void], callback: proc(x: T): bool ): Result[T, void] {.effectsOf: callback.} = ## Apply `callback` to the `self`, iff `self` is not an error. If `callback` ## returns an error, return that error, else return `self` case self.oResultPrivate of true: if callback(self.vResultPrivate): self else: Result[T, void].err() of false: self # Options compatibility template some*[T](O: type Opt, v: T): Opt[T] = ## Create an `Opt` set to a value ## ## ``` ## let oResultPrivate = Opt.some(42) ## assert oResultPrivate.isSome and oResultPrivate.value() == 42 ## ``` Opt[T].ok(v) template none*(O: type Opt, T: type): Opt[T] = ## Create an `Opt` set to none ## ## ``` ## let oResultPrivate = Opt.none(int) ## assert oResultPrivate.isNone ## ``` Opt[T].err() template isSome*(oResultPrivate: Opt): bool = ## Alias for `isOk` isOk oResultPrivate template isNone*(oResultPrivate: Opt): bool = ## Alias of `isErr` isErr oResultPrivate # Syntactic convenience template `?`*[T, E](self: Result[T, E]): auto = ## Early return - if self is an error, we will return from the current ## function, else we'll move on.. ## ## ``` ## let v = ? funcWithResult() ## echo v # prints value, not Result! ## ``` ## Experimental # TODO the v copy is here to prevent multiple evaluations of self - could # probably avoid it with some fancy macro magic.. let v = (self) case v.oResultPrivate of false: # Instead of `return xxx` we use `result = xxx; return` which avoids the # need to rewrite `return` in macros that take over the `result` symbol and # its associated control flow - this hack increases compatibility with # chronos' async - see https://github.com/status-im/nim-stew/issues/37 for # more in-depth discussion. when typeof(result) is typeof(v): result = v return else: when E is void: result = err(typeof(result)) return else: result = err(typeof(result), v.eResultPrivate) return of true: when not (T is void): v.vResultPrivate # Collection integration iterator values*[T, E](self: Result[T, E]): maybeLent T = ## Iterate over a Result as a 0/1-item collection, returning its value if set case self.oResultPrivate of true: yield self.vResultPrivate of false: discard iterator errors*[T, E](self: Result[T, E]): maybeLent E = ## Iterate over a Result as a 0/1-item collection, returning its error if set case self.oResultPrivate of false: yield self.eResultPrivate of true: discard iterator items*[T](self: Opt[T]): maybeLent T = ## Iterate over an Opt as a 0/1-item collection, returning its value if set case self.oResultPrivate of true: yield self.vResultPrivate of false: discard iterator mvalues*[T, E](self: var Result[T, E]): var T = case self.oResultPrivate of true: yield self.vResultPrivate of false: discard iterator merrors*[T, E](self: var Result[T, E]): var E = case self.oResultPrivate of false: yield self.eResultPrivate of true: discard iterator mitems*[T](self: var Opt[T]): var T = case self.oResultPrivate of true: yield self.vResultPrivate of false: discard func containsValue*(self: Result, v: auto): bool = ## Return true iff the given result is set to a value that equals `v` case self.oResultPrivate of true: self.vResultPrivate == v of false: false func containsError*(self: Result, e: auto): bool = ## Return true iff the given result is set to an error that equals `e` case self.oResultPrivate of false: self.eResultPrivate == e of true: false func contains*(self: Opt, v: auto): bool = ## Return true iff the given `Opt` is set to a value that equals `v` - can ## also be used in the "infix" `in` form: ## ## ```nim ## assert "value" in Opt.some("value") ## ``` case self.oResultPrivate of true: self.vResultPrivate == v of false: false �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/monoucha0/todo��������������������������������������������������������������������0000664�0000000�0000000�00000000105�15202323131�0016455�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������* import QJS test suite * re-enable timezone offset as external hook �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/lib/updver����������������������������������������������������������������������������0000775�0000000�0000000�00000002133�15202323131�0015132�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh die() { echo "$*" 2>&1 exit 1 } test "$#" -eq 2 || die "Usage: updver [library] [version]" library=$1 dir=${library}0 vv=$(printf '%s\n' "$2" | sed 's/v//') major=$(printf '%s\n' "$vv" | sed 's/\..*//') minor=$(printf '%s\n' "$vv" | sed 's/[^.]*\.\([^.]*\)\..*/\1/') patch=$(printf '%s\n' "$vv" | sed 's/.*\.//') vs="$major.$minor.$patch" oldhdr=$(head -1 "$dir"/NEWS) msgfile=$(mktemp) printf '%s (%s)\n\n' "$vs" "$(date +'%Y.%m.%d')" > "$msgfile" cat "$dir"/NEWS >> "$msgfile" test -n "$EDITOR" || die 'missing $EDITOR env var' $EDITOR "$msgfile" printf 'Ok? (y/n) ' read -r ok case "$ok" in y|Y) ;; *) die "Aborted. (File is $msgfile.)" ;; esac cp "$msgfile" "$dir/"NEWS echo "/version/c version = \"$vs\" . p wq" | ed -s "$dir/$library".nimble echo "/Major/s/[0-9]*$/$major/ /Minor/s/[0-9]*$/$minor/ /Patch/s/[0-9]*$/$patch/ g/.*/p wq" | ed -s "$dir/$library"/version.nim git add . git commit -m "$library version $vs" tmp2=$(mktemp) while read line do if test "$line" = "$oldhdr"; then break; fi printf '%s\n' "$line" done <"$dir/"NEWS >"$tmp2" git tag -faeF "$tmp2" "v$vs" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/md2man��������������������������������������������������������������������������������0000775�0000000�0000000�00000000605�15202323131�0014237�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh if test $# -ne 1 then echo "Usage: md2man [in]" exit 1 fi sed -e 's/<!-- MANOFF -->.*<!-- MANON -->//g' \ -e '/<!-- MANOFF -->/,/<!-- MANON -->/d' \ "$1" | { read -r line; line=${line#"<!-- "} line=${line%" -->"} title=${line%' '*} section=${line##*' '} $PANDOC -p -t man --standalone -V title="$title" -V section="$section" } | sed -E '/^\.TH/s/""//g;/^\.TH/s/ *$//' ���������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/nim.cfg�������������������������������������������������������������������������������0000664�0000000�0000000�00000000375�15202323131�0014403�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������-p:"." -p:"src/" -p:"lib/chame0" -p:"lib/monoucha0" --mm:refc --include:"utils/myaddr" --import:"utils/eprint" --styleCheck:usages --styleCheck:hint --threads:off --panics:on @if nimUseStrictDefs: --experimental:strictDefs --warning:Uninit:off @end �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/����������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0013723�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/.gitignore������������������������������������������������������������������������0000664�0000000�0000000�00000000024�15202323131�0015707�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/EastAsianWidth.txt ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/charwidth_gen.nim�����������������������������������������������������������������0000664�0000000�0000000�00000065422�15202323131�0017247�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������const DoubleWidthRanges: array[64, tuple[ucs, mapped: uint32]] = [ (94176u32,94180u32),(94192u32,94198u32),(94208u32,101589u32), (101631u32,101662u32),(101760u32,101874u32),(110576u32,110579u32), (110581u32,110587u32),(110589u32,110590u32),(110592u32,110882u32), (110898u32,110898u32),(110928u32,110930u32),(110933u32,110933u32), (110948u32,110951u32),(110960u32,111355u32),(119552u32,119638u32), (119648u32,119670u32),(126980u32,126980u32),(127183u32,127183u32), (127374u32,127374u32),(127377u32,127386u32),(127488u32,127490u32), (127504u32,127547u32),(127552u32,127560u32),(127568u32,127569u32), (127584u32,127589u32),(127744u32,127776u32),(127789u32,127797u32), (127799u32,127868u32),(127870u32,127891u32),(127904u32,127946u32), (127951u32,127955u32),(127968u32,127984u32),(127988u32,127988u32), (127992u32,128062u32),(128064u32,128064u32),(128066u32,128252u32), (128255u32,128317u32),(128331u32,128334u32),(128336u32,128359u32), (128378u32,128378u32),(128405u32,128406u32),(128420u32,128420u32), (128507u32,128591u32),(128640u32,128709u32),(128716u32,128716u32), (128720u32,128722u32),(128725u32,128728u32),(128732u32,128735u32), (128747u32,128748u32),(128756u32,128764u32),(128992u32,129003u32), (129008u32,129008u32),(129292u32,129338u32),(129340u32,129349u32), (129351u32,129535u32),(129648u32,129660u32),(129664u32,129674u32), (129678u32,129734u32),(129736u32,129736u32),(129741u32,129756u32), (129759u32,129770u32),(129775u32,129784u32),(131072u32,196605u32), (196608u32,262141u32), ] const DoubleWidthAmbiguousRanges: array[179, tuple[ucs, mapped: uint32]] = [ (161u32,161u32),(164u32,164u32),(167u32,168u32),(170u32,170u32),(173u32,174u32), (176u32,180u32),(182u32,186u32),(188u32,191u32),(198u32,198u32),(208u32,208u32), (215u32,216u32),(222u32,225u32),(230u32,230u32),(232u32,234u32),(236u32,237u32), (240u32,240u32),(242u32,243u32),(247u32,250u32),(252u32,252u32),(254u32,254u32), (257u32,257u32),(273u32,273u32),(275u32,275u32),(283u32,283u32),(294u32,295u32), (299u32,299u32),(305u32,307u32),(312u32,312u32),(319u32,322u32),(324u32,324u32), (328u32,331u32),(333u32,333u32),(338u32,339u32),(358u32,359u32),(363u32,363u32), (462u32,462u32),(464u32,464u32),(466u32,466u32),(468u32,468u32),(470u32,470u32), (472u32,472u32),(474u32,474u32),(476u32,476u32),(593u32,593u32),(609u32,609u32), (708u32,708u32),(711u32,711u32),(713u32,715u32),(717u32,717u32),(720u32,720u32), (728u32,731u32),(733u32,733u32),(735u32,735u32),(768u32,879u32),(913u32,929u32), (931u32,937u32),(945u32,961u32),(963u32,969u32),(1025u32,1025u32), (1040u32,1103u32),(1105u32,1105u32),(8208u32,8208u32),(8211u32,8214u32), (8216u32,8217u32),(8220u32,8221u32),(8224u32,8226u32),(8228u32,8231u32), (8240u32,8240u32),(8242u32,8243u32),(8245u32,8245u32),(8251u32,8251u32), (8254u32,8254u32),(8308u32,8308u32),(8319u32,8319u32),(8321u32,8324u32), (8364u32,8364u32),(8451u32,8451u32),(8453u32,8453u32),(8457u32,8457u32), (8467u32,8467u32),(8470u32,8470u32),(8481u32,8482u32),(8486u32,8486u32), (8491u32,8491u32),(8531u32,8532u32),(8539u32,8542u32),(8544u32,8555u32), (8560u32,8569u32),(8585u32,8585u32),(8592u32,8601u32),(8632u32,8633u32), (8658u32,8658u32),(8660u32,8660u32),(8679u32,8679u32),(8704u32,8704u32), (8706u32,8707u32),(8711u32,8712u32),(8715u32,8715u32),(8719u32,8719u32), (8721u32,8721u32),(8725u32,8725u32),(8730u32,8730u32),(8733u32,8736u32), (8739u32,8739u32),(8741u32,8741u32),(8743u32,8748u32),(8750u32,8750u32), (8756u32,8759u32),(8764u32,8765u32),(8776u32,8776u32),(8780u32,8780u32), (8786u32,8786u32),(8800u32,8801u32),(8804u32,8807u32),(8810u32,8811u32), (8814u32,8815u32),(8834u32,8835u32),(8838u32,8839u32),(8853u32,8853u32), (8857u32,8857u32),(8869u32,8869u32),(8895u32,8895u32),(8978u32,8978u32), (9312u32,9449u32),(9451u32,9547u32),(9552u32,9587u32),(9600u32,9615u32), (9618u32,9621u32),(9632u32,9633u32),(9635u32,9641u32),(9650u32,9651u32), (9654u32,9655u32),(9660u32,9661u32),(9664u32,9665u32),(9670u32,9672u32), (9675u32,9675u32),(9678u32,9681u32),(9698u32,9701u32),(9711u32,9711u32), (9733u32,9734u32),(9737u32,9737u32),(9742u32,9743u32),(9756u32,9756u32), (9758u32,9758u32),(9792u32,9792u32),(9794u32,9794u32),(9824u32,9825u32), (9827u32,9829u32),(9831u32,9834u32),(9836u32,9837u32),(9839u32,9839u32), (9886u32,9887u32),(9919u32,9919u32),(9926u32,9933u32),(9935u32,9939u32), (9941u32,9953u32),(9955u32,9955u32),(9960u32,9961u32),(9963u32,9969u32), (9972u32,9972u32),(9974u32,9977u32),(9979u32,9980u32),(9982u32,9983u32), (10045u32,10045u32),(10102u32,10111u32),(11094u32,11097u32),(12872u32,12879u32), (57344u32,63743u32),(65024u32,65039u32),(65533u32,65533u32), (127232u32,127242u32),(127248u32,127277u32),(127280u32,127337u32), (127344u32,127373u32),(127375u32,127376u32),(127387u32,127404u32), (917760u32,917999u32),(983040u32,1048573u32),(1048576u32,1114109u32), ] const DoubleWidthTable: PropertyTable = [ uint32 4294967295u32,0u32,0u32,2147483648u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,4294967295u32, 4294967295u32,4294967295u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,201326592u32,1536u32,0u32,0u32,0u32,0u32,0u32,597504u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 1610612736u32,3145728u32,16711680u32,1048320u32,2147483648u32,588800u32, 1610615810u32,1065008u32,606864384u32,3104u32,256u32,12079104u32,0u32, 14680064u32,2147549184u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 402653184u32,0u32,2162688u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 4227858431u32,4294967295u32,4294967295u32,1048575u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4194303u32,4294901760u32,4294967295u32,2147483647u32,4294967294u32, 4294967295u32,4269801471u32,4294967295u32,4294967295u32,4294967295u32, 4294967264u32,4294901759u32,4294967295u32,4294967295u32,4294934527u32, 4294967295u32,4294967295u32,4294934591u32,2147483647u32,4294967295u32, 4294902015u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294909951u32, 4294967295u32,127u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,536870911u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,15u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,4294967295u32,4294967295u32, 4294967295u32,4294967295u32,4294967295u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32,0u32, 0u32,67043328u32,4294901760u32,4294443007u32,3967u32,0u32,0u32,0u32,0u32, 4294967294u32,4294967295u32,4294967295u32,1u32,0u32,0u32,0u32,127u32, ] ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/chawan.html�����������������������������������������������������������������������0000664�0000000�0000000�00000012251�15202323131�0016053�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <head> <title>Chawan Browser 0.4.0</title> <style> h1 { margin-top: 0 } .logo { float: right; margin: 0em 2ch } @media (max-width: 80ch) { .logo { display: none } } kbd { font-weight: bold; word-break: keep-all } a { word-break: keep-all } </style> </head> <body> <center><h1>Welcome to Chawan!</h1></center> <pre class=logo> _..................._ fr.,~.~,,~~.~~~,~,~~~l\ I!www~www~www~www~www!dp lCHCHCHCHCHCHCHCHCHCHCp lsAAAAAAAAAAAAAAAAAAp SWWWWWWWWWWWWWWWWWZ \Z<u>NMNMNMNMN</u>Z/ </pre> <p> This is the default visual home page. You can change it in your configuration file using the <code>start.visual-home</code> option. (e.g. <a href='cgi-bin:chabookmark?action=view'>cgi-bin:chabookmark?action=view</a> to automatically show bookmarks.) <p> Following is a list of default keybindings to get you started. (<kbd>C-{key}</kbd> means <kbd>Control</kbd> + <kbd>key</kbd>, <kbd>M-{key}</kbd> means <kbd>Meta</kbd> + <kbd>key</kbd>. Depending on your environment, the <kbd>Meta</kbd> key may be called <kbd>Alt</kbd> or <kbd>Escape</kbd>.) <ul> <li><kbd>q</kbd>: quit the browser <li><kbd>hjkl</kbd>, <kbd>Arrow keys</kbd>: move the cursor <li><kbd>J</kbd>, <kbd>K</kbd> (or <kbd>C-e</kbd>, <kbd>C-y</kbd>): scroll up/down by one row <li><kbd>C-l</kbd>: location bar (to enter a URL, etc.) <li><kbd>C-k</kbd>: web search <li><kbd>Return/Enter key</kbd>: open URL under cursor <li><kbd>c</kbd>, <kbd>C</kbd>: right click/context menu (shift = force menu) <li><kbd>M-l</kbd>: enter URL under cursor to location bar <li><kbd>I</kbd>: view image in external viewer <li><kbd>M-i</kbd>: toggle image display <li><kbd>M-j</kbd>: toggle JavaScript and reload <li><kbd>M-k</kbd>: toggle cookies and reload <li><kbd>v</kbd>, <kbd>V</kbd>, <kbd>C-v</kbd>: select (normal), select (line), select (block) <li><kbd>y</kbd>: copy current selection to system clipboard (needs OSC52/xsel) <li><kbd>U</kbd>: reload page <li><kbd>,</kbd> (comma), <kbd>.</kbd> (period): previous/next buffer <li><kbd>D</kbd>: discard (delete) current buffer, then move back to where you came from <li><kbd>d ,</kbd>, <kbd>d .</kbd>: discard (delete) current buffer, then move to previous/next buffer <li><kbd>M-y</kbd>: copy current buffer's URL to clipboard (needs OSC52/xsel) <li><kbd>u</kbd>: view link/title text currently under the cursor <li><kbd>s u</kbd>: show last alert message <li><kbd>y u</kbd>: copy the link currently under the cursor to clipboard (needs OSC52/xsel) <li><kbd>y I</kbd>: copy the image link currently under the cursor to clipboard (needs OSC52/xsel) <li><kbd>M-p</kbd>: go to the URL currently on the clipboard (needs xsel) <li><kbd>M-b</kbd>: open bookmark file <li><kbd>M-a</kbd>: add current page to bookmarks <li><kbd>[</kbd>, <kbd>]</kbd>: move cursor to the previous/next hyperlink <li><kbd>f</kbd>: toggle link hints; type a hint on the screen to jump there <li><kbd>C-d</kbd>, <kbd>C-u</kbd>: scroll up/down by half a page <li><kbd>C-f</kbd>, <kbd>C-b</kbd> (or <kbd>PgDn</kbd>, <kbd>PgUp</kbd>)</kbd>: scroll up/down by an entire page <li><kbd>{number}G</kbd> (or <kbd>{number}gg</kbd>): jump to {number}'th line <li><kbd>g 0</kbd>: jump to first character of the current line's visible part <li><kbd>g c</kbd>: jump to center of the current line's visible part <li><kbd>g $</kbd>: jump to last character of the current line's visible part <li><kbd>{</kbd>, <kbd>}</kbd>: move cursor to the previous/next paragraph <li><kbd>-</kbd>, <kbd>+</kbd> (or <kbd>zh</kbd>, <kbd>zl</kbd>): shift screen to the left/right by one cell <li><kbd> <li><kbd>&lt;</kbd>, <kbd>&gt;</kbd>: shift screen to the left/right by one page <li><kbd>/</kbd>, <kbd>?</kbd>: on-page search (or search backwards) <li><kbd>n</kbd>, <kbd>N</kbd>: next/previous match <li><kbd>C-z</kbd>: suspend the browser <li><kbd>C-c</kbd>: cancel loading <li><kbd>H</kbd>, <kbd>M</kbd>, <kbd>L</kbd>: move cursor to the highest/middle/lowest rows <li><kbd>z z</kbd>, <kbd>z .</kbd>: center on current line (and move to beginning) <li><kbd>z t</kbd>, <kbd>z -</kbd>: lower page until current line (and move to beginning) <li><kbd>z b</kbd>, <kbd>z RET</kbd>: raise page until current line (and move to beginning) <li><kbd>w</kbd>, <kbd>b</kbd>: move cursor to next/previous word <li><kbd>\</kbd>: toggle page source view <li><kbd>s e</kbd>: show rendered page in editor <li><kbd>s E</kbd>: show page source in editor <li><kbd>s s</kbd>: save rendered page to file <li><kbd>s S</kbd>: save current page's source <li><kbd>s I</kbd>: save image <li><kbd>s RET</kbd>: save page that link points to <li><kbd>0</kbd>: cursor to first cell on line <li><kbd>^</kbd>: cursor to first non-whitespace on line <li><kbd>$</kbd>: cursor to last character on line <li><kbd>m{char}</kbd>: set mark {char} <li><kbd>`{char}</kbd>, <kbd>'{char}</kbd>: jump to mark {char}, or line of {char} <li><kbd>{number}</kbd>, then movement: repeat movement n times (or move to nth line, depending on command) <li><kbd>: (colon)</kbd>: convert URL-like strings to anchor tags <li><kbd>C-a</kbd>/<kbd>*</kbd>, <kbd>#</kbd>: jump to next/previous exact match for the word under cursor (like <kbd>/\bword\b</kbd>) <li><kbd>M-c</kbd>: input command <li><kbd>M-c M-c</kbd>: command mode (browser console) </ul> <p> Happy browsing! </body> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/createmap.nim���������������������������������������������������������������������0000664�0000000�0000000�00000040057�15202323131�0016377�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import std/algorithm import std/os import std/sets import std/streams import std/strutils import std/tables type UCS16x16 = tuple[ucs, p: uint16] iterator mapPairs(path: string): tuple[a, b: int] = let s = readFile("res/" / path) var k = 0 while k < s.len: if s[k] == '\n': inc k continue if s[k] == '#': inc k while k < s.len and s[k] != '\n': inc k inc k continue while s[k] == ' ': inc k var j = k while s[k] in '0'..'9': inc k let index = parseInt(s.substr(j, k - 1)) inc k # tab j = k while s[k] in {'0'..'9', 'A'..'F', 'x'}: inc k let n = parseHexInt(s.substr(j, k - 1)) while k < s.len and s[k] != '\n': inc k inc k yield (index, n) # All single-byte encodings map to ucs-2. proc loadCharsetMap8(path: string): tuple[ decode: seq[uint16], encode: tuple[start, len: uint8; offset: uint16] ] = var start = 0'u8 var len = 0'u8 var offset = 0'u16 var previ = -1 var prevu = -1 for index, n in mapPairs(path): while result.decode.len < index: result.decode.add(0) result.decode.add(uint16(n)) if previ + 1 != index or prevu + 1 != n: if len > result.encode.len: result.encode = (start, len, offset) start = uint8(index) offset = uint16(n) len = 0 else: inc len previ = index prevu = n if len > result.encode.len: result.encode = (start, len, offset) proc loadCharsetMapISO2022JPKatakana(path: string): seq[uint16] = result = @[] var i = 0 for index, n in mapPairs(path): result.add(uint16(n)) assert index == i inc i proc loadGB18030Ranges(path: string): seq[UCS16x16] = result = @[] var pindex = -1 var pn = -1 for index, n in mapPairs(path): if uint32(index) > uint32(high(uint16)): break assert pn < n assert pindex < index pn = n pindex = index result.add((uint16(n), uint16(index))) proc loadCharsetMap16(path: string): tuple[ decode: seq[uint16], encode: seq[UCS16x16] ] = var found = initHashSet[int]() for index, n in mapPairs(path): while result.decode.len < index: result.decode.add(0) result.decode.add(uint16(n)) if n notin found: found.incl(n) result.encode.add((uint16(n), uint16(index))) result.encode.sort() proc loadCharsetMapJis0208(path: string): tuple[ decode: seq[uint16], encode: seq[UCS16x16] ] = var found = initHashSet[int]() found.incl(0x2212) result.encode.add((0x2212u16, 60u16)) for index, n in mapPairs(path): while result.decode.len < index: result.decode.add(0) result.decode.add(uint16(n)) if n notin found: found.incl(n) result.encode.add((uint16(n), uint16(index))) result.encode.sort() proc loadCharsetMapSJIS(path: string): seq[UCS16x16] = var found = initHashSet[int]() result.add((0x2212u16, 60u16)) for index, n in mapPairs(path): if index < 8272: found.incl(n) continue if index in 8272..8835: continue # skip if n in found: continue found.incl(n) result.add((uint16(n), uint16(index))) result.sort() proc loadBig5Map(path: string; offset: static uint16): tuple[ decode: array[19782u16 - offset, uint16]; encodeLow, encodeHigh: seq[UCS16x16] ] = var found = initHashSet[int]() for index, n in mapPairs(path): # Set high mappings to 1, then linear search encodeHigh. # Note that this means encodeHigh cannot be de-duped. Luckily, there appear # to be no duplicates in there. assert n != 1 if n > int(uint16.high): result.decode[uint16(index) - offset] = 1 else: result.decode[uint16(index) - offset] = uint16(n) if n in [0x2550, 0x255E, 0x2561, 0x256A, 0x5341, 0x5345]: if n notin found: found.incl(n) continue else: if n in found: assert n <= int(uint16.high) continue found.incl(n) if n < 0x10000: result.encodeLow.add((uint16(n), uint16(index))) else: assert n in 0x20000 ..< 0x30000 result.encodeHigh.add((uint16(n - 0x10000), uint16(index))) #for i in result.decode: assert x != 0 # fail result.encodeLow.sort() result.encodeHigh.sort() type LineWriter = object s: Stream line: string proc write(writer: var LineWriter; s: string) = if s.len + writer.line.len > 80: writer.s.writeLine(writer.line) writer.line = "" writer.line &= s proc flush(writer: var LineWriter) = writer.s.writeLine(writer.line) writer.line = "" proc writeCharsetMap8(s: Stream; path, outname: string) = let (decode, encode) = loadCharsetMap8(path) s.write("const " & outname & "Decode*: array[" & $decode.len & ", uint16] = [\n") var writer = LineWriter(s: s) writer.write("uint16 ") for c in decode: writer.write($c & ",") writer.flush() s.write("]\n") s.write("const " & outname & "Encode* = (start: " & $encode.start & "u8, len: " & $encode.len & "u8, offset: " & $encode.offset & "u16)\n\n") type Run = tuple[p, ucs: uint16; len: uint8] # Writes a list of runs in the following format: # * rightmost 13 bits: pointer # * middle 12 bits: UCS codepoint offset - pointer # * top 7 bits: run length # The codepoint offset is the first UCS codepoint found in the run list minus # the first pointer, so that you get the codepoint again as # "offset + pointer + diff". proc writeRuns(writer: var LineWriter; runs: seq[Run]; isJis0212 = false): uint16 = var ucslo = uint16.high var pucs = 0u16 var pp = 0u16 for (p, ucs, len) in runs: ucslo = min(ucslo, ucs) if not isJis0212: assert ucs >= pucs assert p >= pp assert len < 128 pp = p pucs = ucs for (p, ucs, len) in runs: let diff0 = int(ucs) - int(p) - int(ucslo) let diff = uint16(diff0) assert diff0 >= 0 assert (p and 0x1FFF) == p assert (diff and 0xFFF) == diff let pack32 = (uint32(p) and 0x1FFF) or # 13 bits ((uint32(diff) and 0xFFF) shl 13) or # 12 bits (uint32(len) shl 25) # 7 bits assert pack32 shr 25 == len # 13 + 12 + 7 = 32 writer.write($pack32 & "u32,") writer.flush() return ucslo proc writeGB18030Map(s: Stream; path, outname: string) = let (decode, encode) = loadCharsetMap16(path) var runs: seq[Run] = @[] var runs2: seq[Run] = @[] var L = 0u16 var L2 = 0u16 var runc = 0u16 var runp = 0u16 var runlen = 0u8 var runvals: set[uint16] = {} for i, val in decode: let row = i div 190 let col = i mod 190 if row <= 0x1F: if runlen == 0 or runc + uint16(runlen) != val: if runlen != 0: runs.add((runp, runc, runlen)) runlen = 0 runc = val runp = L2 runvals.incl(val) assert runlen < 255 inc runlen inc L2 continue if row == 0x20 and col == 0: # finish final run1 assert runlen > 0 runs.add((runp, runc, runlen)) runlen = 0 if row <= 0x26 and col <= 0x5F: continue if row >= 0x29 and col <= 0x5F and row < 0x7C: if row == 0x29 and col == 0: L2 = 0 if runlen == 0 or runc + uint16(runlen) != val or runlen >= 127: if runlen != 0: runs2.add((runp, runc, runlen)) runlen = 0 runc = val runp = L2 runvals.incl(val) inc L2 inc runlen continue elif row >= 0x7C and runlen > 0: runs2.add((runp, runc, runlen)) runlen = 0 inc L s.writeLine("const " & outname & "Runs*: array[" & $runs.len & ", uint32] = [") var writer = LineWriter(s: s) let ucslo = writer.writeRuns(runs) s.writeLine("]") s.writeLine("const " & outname & "RunsOffset* = " & $ucslo & "u16") s.writeLine("const " & outname & "Runs2*: array[" & $runs2.len & ", uint32] = [") let ucslo2 = writer.writeRuns(runs2) s.writeLine("]") s.writeLine("const " & outname & "RunsOffset2* = " & $ucslo2 & "u16") s.writeLine("const " & outname & "Decode*: array[" & $L & ", uint16] = [") s.write("uint16 ") for i, val in decode: let row = i div 190 if row <= 0x1F: continue # runs let col = i mod 190 if row <= 0x26 and col <= 0x5F: continue # PUA if row >= 0x29 and col <= 0x5F and row < 0x7C: continue # runs 2 writer.write($val & ",") writer.flush() s.writeLine("]") var EL = 0 for (val, index) in encode: if val in runvals: continue inc EL s.writeLine("const " & outname & "Encode*: array[" & $EL & ", UCS16x16] = [") for (val, index) in encode: if val in runvals: continue writer.write("(" & $val & "u16," & $index & "u16),") writer.flush() s.write("]\n\n") proc writeJis0208Map(s: Stream; path, outname: string) = let (decode, encode) = loadCharsetMapJis0208(path) var L = 0 for i in 0 ..< decode.len: let row = i div 94 if row in 0x8 .. 0xB or row in 0xD .. 0xE or row in 0x54 .. 0x57 or row in 0x5C .. 0x71: continue inc L s.write("const " & outname & "Decode*: array[" & $L & ", uint16] = [\n") var writer = LineWriter(s: s) writer.write("uint16 ") for i, val in decode: let row = i div 94 if row in 0x8 .. 0xB or row in 0xD .. 0xE or row in 0x54 .. 0x57 or row in 0x5C .. 0x71: continue writer.write($val & ",") writer.flush() s.write("]\n") s.write("const " & outname & "Encode*: array[" & $encode.len & ", UCS16x16] = [\n") for (val, index) in encode: writer.write("(" & $val & "u16," & $index & "u16),") writer.flush() s.write("]\n\n") proc writeJis0212Map(s: Stream; path, outname: string) = let (decode, _) = loadCharsetMap16(path) var writer = LineWriter(s: s) s.writeLine("const " & outname & "Decode*: array[" & $decode.len & ", uint16] = [") s.write("uint16 ") for val in decode: writer.write($val & ",") writer.flush() s.writeLine("]") proc writeEUCKRMap(s: Stream; path, outname: string) = let (decode, encode) = loadCharsetMap16(path) var runs: seq[tuple[p, ucs: uint16; len: uint8]] = @[] var runs2: seq[tuple[p, ucs: uint16; len: uint8]] = @[] var runc = 0u16 var runp = 0u16 var runlen = 0u8 var L = 0 var L2 = 0u16 var runvals: set[uint16] = {} for i, val in decode: let col = i mod 190 if col in 0x1A .. 0x1F or col in 0x3A .. 0x3F: continue let row = i div 190 if row <= 0x1F: if runlen == 0 or runc + uint16(runlen) != val: if runlen != 0: runs.add((runp, runc, runlen)) runlen = 0 runc = val runp = L2 runvals.incl(val) inc runlen inc L2 continue if col < 0x60: if val == 0: continue if row == 0x20 and col == 0: runs.add((runp, runc, runlen)) runlen = 0 L2 = 0 if runlen == 0 or runc + uint16(runlen) != val: if runlen != 0: runs2.add((runp, runc, runlen)) runlen = 0 runc = val runp = L2 runvals.incl(val) inc runlen inc L2 else: if row > 0x45 and runlen > 0: runs2.add((runp, runc, runlen)) runlen = 0 inc L var writer = LineWriter(s: s) s.writeLine("const " & outname & "Runs*: array[" & $runs.len & ", uint32] = [") let ucslo = writer.writeRuns(runs) s.write("]\n") s.writeLine("const " & outname & "RunsOffset* = " & $ucslo & "u16") s.writeLine("const " & outname & "Runs2*: array[" & $runs2.len & ", uint32] = [") let ucslo2 = writer.writeRuns(runs2) s.write("]\n") s.writeLine("const " & outname & "RunsOffset2* = " & $ucslo2 & "u16") s.writeLine("const " & outname & "Decode*: array[" & $L & ", uint16] = [") s.write("uint16 ") for i, val in decode: let col = i mod 190 if col in 0x1A .. 0x1F: continue if col in 0x3A .. 0x3F: continue let row = i div 190 if row <= 0x1F: continue # runs if col < 0x60: continue # runs2 / empty space writer.write($val & ",") writer.flush() s.write("]\n") var EL = 0 for (val, index) in encode: if val in runvals: continue inc EL s.writeLine("const " & outname & "Encode*: array[" & $EL & ", UCS16x16] = [") for (val, index) in encode: if val in runvals: continue writer.write("(" & $val & "u16," & $index & "u16),") writer.flush() s.write("]\n\n") proc writeGB18030RangesMap(s: Stream; path, outname: string) = let ranges = loadGB18030Ranges(path) s.write("const " & outname & "*: array[" & $ranges.len & ", UCS16x16] = [\n") var writer = LineWriter(s: s) for (val, index) in ranges: writer.write("(" & $val & "u16," & $index & "u16),") writer.flush() s.write("]\n\n") proc writeBig5Map(s: Stream; path, outname: string; offset: static uint16) = let (decode, encode0, encode1) = loadBig5Map(path, offset) s.write("const " & outname & "Decode*: array[" & $decode.len & ", uint16] = [\n") var writer = LineWriter(s: s) writer.write("uint16 ") for val in decode: writer.write($val & ",") writer.flush() s.write("]\n") s.write("const " & outname & "EncodeLow*: array[" & $encode0.len & ", UCS16x16] = [\n") for (val, index) in encode0: writer.write("(" & $val & "u16," & $index & "u16),") writer.flush() s.write("]\n") s.write("const " & outname & "EncodeHigh*: array[" & $encode1.len & ", UCS16x16] = [\n") for (val, index) in encode1: writer.write("(" & $val & "u16," & $index & "u16),") writer.flush() s.write("]\n\n") proc writeShiftJISMap(s: Stream; path, outname: string) = let encode = loadCharsetMapSJIS(path) s.write("const " & outname & "Encode*: array[" & $encode.len & ", UCS16x16] = [\n") var writer = LineWriter(s: s) for (val, index) in encode: writer.write("(" & $val & "u16," & $index & "u16),") writer.flush() s.write("]\n\n") proc writeISO2022JPKatakanaEncode(s: Stream; path: string) = let encode = loadCharsetMapISO2022JPKatakana(path) s.write("const Iso2022JPKatakanaMap*: array[" & $encode.len & ", uint8] = [\n") var writer = LineWriter(s: s) writer.write("uint8 ") for index in encode: if index == 0: break assert index - 0x3000 <= 0xFF writer.write($int(index - 0x3000) & ",") writer.flush() s.write("]\n\n") let s = newFileStream(stdout) s.writeLine("const Big5DecodeOffset* = 942") s.writeLine("type UCS16x16* = tuple[ucs, p: uint16]") s.writeLine() s.writeCharsetMap8("index-ibm866.txt", "Ibm866") s.writeCharsetMap8("index-iso-8859-2.txt", "Iso8859_2") s.writeCharsetMap8("index-iso-8859-3.txt", "Iso8859_3") s.writeCharsetMap8("index-iso-8859-4.txt", "Iso8859_4") s.writeCharsetMap8("index-iso-8859-5.txt", "Iso8859_5") s.writeCharsetMap8("index-iso-8859-6.txt", "Iso8859_6") s.writeCharsetMap8("index-iso-8859-7.txt", "Iso8859_7") s.writeCharsetMap8("index-iso-8859-8.txt", "Iso8859_8") s.writeCharsetMap8("index-iso-8859-10.txt", "Iso8859_10") s.writeCharsetMap8("index-iso-8859-13.txt", "Iso8859_13") s.writeCharsetMap8("index-iso-8859-14.txt", "Iso8859_14") s.writeCharsetMap8("index-iso-8859-15.txt", "Iso8859_15") s.writeCharsetMap8("index-iso-8859-16.txt", "Iso8859_16") s.writeCharsetMap8("index-koi8-r.txt", "Koi8r") s.writeCharsetMap8("index-koi8-u.txt", "Koi8u") s.writeCharsetMap8("index-macintosh.txt", "Macintosh") s.writeCharsetMap8("index-windows-874.txt", "Windows874") s.writeCharsetMap8("index-windows-1250.txt", "Windows1250") s.writeCharsetMap8("index-windows-1251.txt", "Windows1251") s.writeCharsetMap8("index-windows-1252.txt", "Windows1252") s.writeCharsetMap8("index-windows-1253.txt", "Windows1253") s.writeCharsetMap8("index-windows-1254.txt", "Windows1254") s.writeCharsetMap8("index-windows-1255.txt", "Windows1255") s.writeCharsetMap8("index-windows-1256.txt", "Windows1256") s.writeCharsetMap8("index-windows-1257.txt", "Windows1257") s.writeCharsetMap8("index-windows-1258.txt", "Windows1258") s.writeCharsetMap8("index-x-mac-cyrillic.txt", "XMacCyrillic") s.writeGB18030Map("index-gb18030.txt", "GB18030") s.writeJis0208Map("index-jis0208.txt", "Jis0208") s.writeJis0212Map("index-jis0212.txt", "Jis0212") s.writeEUCKRMap("index-euc-kr.txt", "EucKR") s.writeGB18030RangesMap("index-gb18030-ranges.txt", "GB18030Ranges") const Big5DecodeOffset* = 942 s.writeBig5Map("index-big5.txt", "Big5", offset = Big5DecodeOffset) s.writeShiftJISMap("index-jis0208.txt", "ShiftJIS") s.writeISO2022JPKatakanaEncode("index-iso-2022-jp-katakana.txt") s.close() ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/gencharwidth.nim������������������������������������������������������������������0000664�0000000�0000000�00000006357�15202323131�0017112�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/strutils import io/chafile import types/opt import utils/myposix import utils/proptable import utils/twtstr var DoubleWidthRanges: seq[(uint32, uint32)] = @[] var DoubleWidthAmbiguousRanges: seq[(uint32, uint32)] = @[] proc add(res: var seq[(uint32, uint32)]; firstcol: string) = let (rstart, rend) = if ".." in firstcol: let fcs = firstcol.split("..") (uint32(parseHexInt64(fcs[0]).get), uint32(parseHexInt64(fcs[1]).get)) else: let u = uint32(parseHexInt64(firstcol).get) (u, u) if res.len > 0 and res[^1][1] + 1 == rstart: res[^1][1] = rend else: res.add((rstart, rend)) proc loadRanges() = var s: string if readFile("res/EastAsianWidth.txt", s).isErr: die("failed to read res/EastAsianWidth.txt") for line in s.split('\n'): if line.len == 0 or line[0] == '#': continue var i = 0 var firstcol = "" var status = "" while i < line.len and line[i] notin {'#', ';'}: if line[i] != ' ': firstcol &= line[i] inc i if line[i] != '#': inc i while i < line.len and line[i] notin {'#', ';'}: if line[i] != ' ': status &= line[i] inc i case status of "W", "F": DoubleWidthRanges.add(firstcol) of "A": DoubleWidthAmbiguousRanges.add(firstcol) type LineWriter = object line: string proc flush(writer: var LineWriter) = let stdout = cast[ChaFile](stdout) discard stdout.write(writer.line & '\n') writer.line = "" proc write(writer: var LineWriter, s: string) = if s.len + writer.line.len > 80: writer.flush() writer.line &= s func makePropertyTable(ranges: RangeMap): PropertyTable = var ucs = 0u32 var k = 0 while ucs <= 0xFFFF: if k > ranges.len: break if ranges[k][0] > ucs: ucs = ranges[k][0] continue if ranges[k][1] < ucs: inc k continue let i = ucs div (sizeof(ptint) * 8) let m = ucs mod (sizeof(ptint) * 8) result[i] = result[i] or ptint(1 shl m) inc ucs proc main() = loadRanges() var DoubleWidthTable = makePropertyTable(DoubleWidthRanges) # Control chars return a width of 2, and are displayed as ^{letter}. for c in Controls: let u = ptint(c) let i = u div (sizeof(ptint) * 8) let m = u mod (sizeof(ptint) * 8) DoubleWidthTable[i] = DoubleWidthTable[i] or ptint(1 shl m) var dwrLen = 0 for (ucs, mapped) in DoubleWidthRanges: if ucs > uint16.high: # lower ranges are added to DoubleWidthTable inc dwrLen echo "const DoubleWidthRanges: array[" & $dwrLen & ", tuple[ucs, mapped: uint32]] = [" var writer = LineWriter() for (ucs, mapped) in DoubleWidthRanges: if ucs > uint16.high: # lower ranges are added to DoubleWidthTable writer.write("(" & $ucs & "u32," & $mapped & "u32),") writer.flush() echo "]" echo "" echo "const DoubleWidthAmbiguousRanges: array[" & $DoubleWidthAmbiguousRanges.len & ", tuple[ucs, mapped: uint32]] = [" for (ucs, mapped) in DoubleWidthAmbiguousRanges: writer.write("(" & $ucs & "u32," & $mapped & "u32),") writer.flush() echo "]" echo "" echo "const DoubleWidthTable: PropertyTable = [" writer.write("uint32 ") for u in DoubleWidthTable: writer.write($u & "u32,") writer.flush() echo "]" echo "" main() {.pop.} # raises: [] ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-big5.txt��������������������������������������������������������������������0000664�0000000�0000000�00002501457�15202323131�0016435�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-big5.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 8dfc771062e7be0810919082c2c06baa2236147909e0ecc235b1cb9ad782ac82 # Date: 2018-01-06 942 0x43F0 䏰 (<CJK Ideograph Extension A>) 943 0x4C32 䰲 (<CJK Ideograph Extension A>) 944 0x4603 䘃 (<CJK Ideograph Extension A>) 945 0x45A6 䖦 (<CJK Ideograph Extension A>) 946 0x4578 䕸 (<CJK Ideograph Extension A>) 947 0x27267 𧉧 (<CJK Ideograph Extension B>) 948 0x4D77 䵷 (<CJK Ideograph Extension A>) 949 0x45B3 䖳 (<CJK Ideograph Extension A>) 950 0x27CB1 𧲱 (<CJK Ideograph Extension B>) 951 0x4CE2 䳢 (<CJK Ideograph Extension A>) 952 0x27CC5 𧳅 (<CJK Ideograph Extension B>) 953 0x3B95 㮕 (<CJK Ideograph Extension A>) 954 0x4736 䜶 (<CJK Ideograph Extension A>) 955 0x4744 䝄 (<CJK Ideograph Extension A>) 956 0x4C47 䱇 (<CJK Ideograph Extension A>) 957 0x4C40 䱀 (<CJK Ideograph Extension A>) 958 0x242BF 𤊿 (<CJK Ideograph Extension B>) 959 0x23617 𣘗 (<CJK Ideograph Extension B>) 960 0x27352 𧍒 (<CJK Ideograph Extension B>) 961 0x26E8B 𦺋 (<CJK Ideograph Extension B>) 962 0x270D2 𧃒 (<CJK Ideograph Extension B>) 963 0x4C57 䱗 (<CJK Ideograph Extension A>) 964 0x2A351 𪍑 (<CJK Ideograph Extension B>) 965 0x474F 䝏 (<CJK Ideograph Extension A>) 966 0x45DA 䗚 (<CJK Ideograph Extension A>) 967 0x4C85 䲅 (<CJK Ideograph Extension A>) 968 0x27C6C 𧱬 (<CJK Ideograph Extension B>) 969 0x4D07 䴇 (<CJK Ideograph Extension A>) 970 0x4AA4 䪤 (<CJK Ideograph Extension A>) 971 0x46A1 䚡 (<CJK Ideograph Extension A>) 972 0x26B23 𦬣 (<CJK Ideograph Extension B>) 973 0x7225 爥 (<CJK Ideograph>) 974 0x25A54 𥩔 (<CJK Ideograph Extension B>) 975 0x21A63 𡩣 (<CJK Ideograph Extension B>) 976 0x23E06 𣸆 (<CJK Ideograph Extension B>) 977 0x23F61 𣽡 (<CJK Ideograph Extension B>) 978 0x664D 晍 (<CJK Ideograph>) 979 0x56FB 囻 (<CJK Ideograph>) 981 0x7D95 綕 (<CJK Ideograph>) 982 0x591D 夝 (<CJK Ideograph>) 983 0x28BB9 𨮹 (<CJK Ideograph Extension B>) 984 0x3DF4 㷴 (<CJK Ideograph Extension A>) 985 0x9734 霴 (<CJK Ideograph>) 986 0x27BEF 𧯯 (<CJK Ideograph Extension B>) 987 0x5BDB 寛 (<CJK Ideograph>) 988 0x21D5E 𡵞 (<CJK Ideograph Extension B>) 989 0x5AA4 媤 (<CJK Ideograph>) 990 0x3625 㘥 (<CJK Ideograph Extension A>) 991 0x29EB0 𩺰 (<CJK Ideograph Extension B>) 992 0x5AD1 嫑 (<CJK Ideograph>) 993 0x5BB7 宷 (<CJK Ideograph>) 994 0x5CFC 峼 (<CJK Ideograph>) 995 0x676E 杮 (<CJK Ideograph>) 996 0x8593 薓 (<CJK Ideograph>) 997 0x29945 𩥅 (<CJK Ideograph Extension B>) 998 0x7461 瑡 (<CJK Ideograph>) 999 0x749D 璝 (<CJK Ideograph>) 1000 0x3875 㡵 (<CJK Ideograph Extension A>) 1001 0x21D53 𡵓 (<CJK Ideograph Extension B>) 1002 0x2369E 𣚞 (<CJK Ideograph Extension B>) 1003 0x26021 𦀡 (<CJK Ideograph Extension B>) 1004 0x3EEC 㻬 (<CJK Ideograph Extension A>) 1005 0x258DE 𥣞 (<CJK Ideograph Extension B>) 1006 0x3AF5 㫵 (<CJK Ideograph Extension A>) 1007 0x7AFC 竼 (<CJK Ideograph>) 1008 0x9F97 龗 (<CJK Ideograph>) 1009 0x24161 𤅡 (<CJK Ideograph Extension B>) 1010 0x2890D 𨤍 (<CJK Ideograph Extension B>) 1011 0x231EA 𣇪 (<CJK Ideograph Extension B>) 1012 0x20A8A 𠪊 (<CJK Ideograph Extension B>) 1013 0x2325E 𣉞 (<CJK Ideograph Extension B>) 1014 0x430A 䌊 (<CJK Ideograph Extension A>) 1015 0x8484 蒄 (<CJK Ideograph>) 1016 0x9F96 龖 (<CJK Ideograph>) 1017 0x942F 鐯 (<CJK Ideograph>) 1018 0x4930 䤰 (<CJK Ideograph Extension A>) 1019 0x8613 蘓 (<CJK Ideograph>) 1020 0x5896 墖 (<CJK Ideograph>) 1021 0x974A 靊 (<CJK Ideograph>) 1022 0x9218 鈘 (<CJK Ideograph>) 1023 0x79D0 秐 (<CJK Ideograph>) 1024 0x7A32 稲 (<CJK Ideograph>) 1025 0x6660 晠 (<CJK Ideograph>) 1026 0x6A29 権 (<CJK Ideograph>) 1027 0x889D 袝 (<CJK Ideograph>) 1028 0x744C 瑌 (<CJK Ideograph>) 1029 0x7BC5 篅 (<CJK Ideograph>) 1030 0x6782 枂 (<CJK Ideograph>) 1031 0x7A2C 稬 (<CJK Ideograph>) 1032 0x524F 剏 (<CJK Ideograph>) 1033 0x9046 遆 (<CJK Ideograph>) 1034 0x34E6 㓦 (<CJK Ideograph Extension A>) 1035 0x73C4 珄 (<CJK Ideograph>) 1036 0x25DB9 𥶹 (<CJK Ideograph Extension B>) 1037 0x74C6 瓆 (<CJK Ideograph>) 1038 0x9FC7 鿇 (<CJK Ideograph>) 1039 0x57B3 垳 (<CJK Ideograph>) 1040 0x492F 䤯 (<CJK Ideograph Extension A>) 1041 0x544C 呌 (<CJK Ideograph>) 1042 0x4131 䄱 (<CJK Ideograph Extension A>) 1043 0x2368E 𣚎 (<CJK Ideograph Extension B>) 1044 0x5818 堘 (<CJK Ideograph>) 1045 0x7A72 穲 (<CJK Ideograph>) 1046 0x27B65 𧭥 (<CJK Ideograph Extension B>) 1047 0x8B8F 讏 (<CJK Ideograph>) 1048 0x46AE 䚮 (<CJK Ideograph Extension A>) 1049 0x26E88 𦺈 (<CJK Ideograph Extension B>) 1050 0x4181 䆁 (<CJK Ideograph Extension A>) 1051 0x25D99 𥶙 (<CJK Ideograph Extension B>) 1052 0x7BAE 箮 (<CJK Ideograph>) 1053 0x224BC 𢒼 (<CJK Ideograph Extension B>) 1054 0x9FC8 鿈 (<CJK Ideograph>) 1055 0x224C1 𢓁 (<CJK Ideograph Extension B>) 1056 0x224C9 𢓉 (<CJK Ideograph Extension B>) 1057 0x224CC 𢓌 (<CJK Ideograph Extension B>) 1058 0x9FC9 鿉 (<CJK Ideograph>) 1059 0x8504 蔄 (<CJK Ideograph>) 1060 0x235BB 𣖻 (<CJK Ideograph Extension B>) 1061 0x40B4 䂴 (<CJK Ideograph Extension A>) 1062 0x9FCA 鿊 (<CJK Ideograph>) 1063 0x44E1 䓡 (<CJK Ideograph Extension A>) 1064 0x2ADFF 𪷿 (<CJK Ideograph Extension C>) 1065 0x62C1 拁 (<CJK Ideograph>) 1066 0x706E 灮 (<CJK Ideograph>) 1067 0x9FCB 鿋 (<CJK Ideograph>) 1099 0x31C0 ㇀ (CJK STROKE T) 1100 0x31C1 ㇁ (CJK STROKE WG) 1101 0x31C2 ㇂ (CJK STROKE XG) 1102 0x31C3 ㇃ (CJK STROKE BXG) 1103 0x31C4 ㇄ (CJK STROKE SW) 1104 0x2010C 𠄌 (<CJK Ideograph Extension B>) 1105 0x31C5 ㇅ (CJK STROKE HZZ) 1106 0x200D1 𠃑 (<CJK Ideograph Extension B>) 1107 0x200CD 𠃍 (<CJK Ideograph Extension B>) 1108 0x31C6 ㇆ (CJK STROKE HZG) 1109 0x31C7 ㇇ (CJK STROKE HP) 1110 0x200CB 𠃋 (<CJK Ideograph Extension B>) 1111 0x21FE8 𡿨 (<CJK Ideograph Extension B>) 1112 0x31C8 ㇈ (CJK STROKE HZWG) 1113 0x200CA 𠃊 (<CJK Ideograph Extension B>) 1114 0x31C9 ㇉ (CJK STROKE SZWG) 1115 0x31CA ㇊ (CJK STROKE HZT) 1116 0x31CB ㇋ (CJK STROKE HZZP) 1117 0x31CC ㇌ (CJK STROKE HPWG) 1118 0x2010E 𠄎 (<CJK Ideograph Extension B>) 1119 0x31CD ㇍ (CJK STROKE HZW) 1120 0x31CE ㇎ (CJK STROKE HZZZ) 1121 0x0100 Ā (LATIN CAPITAL LETTER A WITH MACRON) 1122 0x00C1 Á (LATIN CAPITAL LETTER A WITH ACUTE) 1123 0x01CD Ǎ (LATIN CAPITAL LETTER A WITH CARON) 1124 0x00C0 À (LATIN CAPITAL LETTER A WITH GRAVE) 1125 0x0112 Ē (LATIN CAPITAL LETTER E WITH MACRON) 1126 0x00C9 É (LATIN CAPITAL LETTER E WITH ACUTE) 1127 0x011A Ě (LATIN CAPITAL LETTER E WITH CARON) 1128 0x00C8 È (LATIN CAPITAL LETTER E WITH GRAVE) 1129 0x014C Ō (LATIN CAPITAL LETTER O WITH MACRON) 1130 0x00D3 Ó (LATIN CAPITAL LETTER O WITH ACUTE) 1131 0x01D1 Ǒ (LATIN CAPITAL LETTER O WITH CARON) 1132 0x00D2 Ò (LATIN CAPITAL LETTER O WITH GRAVE) 1134 0x1EBE Ế (LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE) 1136 0x1EC0 Ề (LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE) 1137 0x00CA Ê (LATIN CAPITAL LETTER E WITH CIRCUMFLEX) 1138 0x0101 ā (LATIN SMALL LETTER A WITH MACRON) 1139 0x00E1 á (LATIN SMALL LETTER A WITH ACUTE) 1140 0x01CE ǎ (LATIN SMALL LETTER A WITH CARON) 1141 0x00E0 à (LATIN SMALL LETTER A WITH GRAVE) 1142 0x0251 ɑ (LATIN SMALL LETTER ALPHA) 1143 0x0113 ē (LATIN SMALL LETTER E WITH MACRON) 1144 0x00E9 é (LATIN SMALL LETTER E WITH ACUTE) 1145 0x011B ě (LATIN SMALL LETTER E WITH CARON) 1146 0x00E8 è (LATIN SMALL LETTER E WITH GRAVE) 1147 0x012B ī (LATIN SMALL LETTER I WITH MACRON) 1148 0x00ED í (LATIN SMALL LETTER I WITH ACUTE) 1149 0x01D0 ǐ (LATIN SMALL LETTER I WITH CARON) 1150 0x00EC ì (LATIN SMALL LETTER I WITH GRAVE) 1151 0x014D ō (LATIN SMALL LETTER O WITH MACRON) 1152 0x00F3 ó (LATIN SMALL LETTER O WITH ACUTE) 1153 0x01D2 ǒ (LATIN SMALL LETTER O WITH CARON) 1154 0x00F2 ò (LATIN SMALL LETTER O WITH GRAVE) 1155 0x016B ū (LATIN SMALL LETTER U WITH MACRON) 1156 0x00FA ú (LATIN SMALL LETTER U WITH ACUTE) 1157 0x01D4 ǔ (LATIN SMALL LETTER U WITH CARON) 1158 0x00F9 ù (LATIN SMALL LETTER U WITH GRAVE) 1159 0x01D6 ǖ (LATIN SMALL LETTER U WITH DIAERESIS AND MACRON) 1160 0x01D8 ǘ (LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE) 1161 0x01DA ǚ (LATIN SMALL LETTER U WITH DIAERESIS AND CARON) 1162 0x01DC ǜ (LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE) 1163 0x00FC ü (LATIN SMALL LETTER U WITH DIAERESIS) 1165 0x1EBF ế (LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE) 1167 0x1EC1 ề (LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE) 1168 0x00EA ê (LATIN SMALL LETTER E WITH CIRCUMFLEX) 1169 0x0261 ɡ (LATIN SMALL LETTER SCRIPT G) 1170 0x23DA ⏚ (EARTH GROUND) 1171 0x23DB ⏛ (FUSE) 1256 0x2A3A9 𪎩 (<CJK Ideograph Extension B>) 1257 0x21145 𡅅 (<CJK Ideograph Extension B>) 1259 0x650A 攊 (<CJK Ideograph>) 1262 0x4E3D 丽 (<CJK Ideograph>) 1263 0x6EDD 滝 (<CJK Ideograph>) 1264 0x9D4E 鵎 (<CJK Ideograph>) 1265 0x91DF 釟 (<CJK Ideograph>) 1268 0x27735 𧜵 (<CJK Ideograph Extension B>) 1269 0x6491 撑 (<CJK Ideograph>) 1270 0x4F1A 会 (<CJK Ideograph>) 1271 0x4F28 伨 (<CJK Ideograph>) 1272 0x4FA8 侨 (<CJK Ideograph>) 1273 0x5156 兖 (<CJK Ideograph>) 1274 0x5174 兴 (<CJK Ideograph>) 1275 0x519C 农 (<CJK Ideograph>) 1276 0x51E4 凤 (<CJK Ideograph>) 1277 0x52A1 务 (<CJK Ideograph>) 1278 0x52A8 动 (<CJK Ideograph>) 1279 0x533B 医 (<CJK Ideograph>) 1280 0x534E 华 (<CJK Ideograph>) 1281 0x53D1 发 (<CJK Ideograph>) 1282 0x53D8 变 (<CJK Ideograph>) 1283 0x56E2 团 (<CJK Ideograph>) 1284 0x58F0 声 (<CJK Ideograph>) 1285 0x5904 处 (<CJK Ideograph>) 1286 0x5907 备 (<CJK Ideograph>) 1287 0x5932 夲 (<CJK Ideograph>) 1288 0x5934 头 (<CJK Ideograph>) 1289 0x5B66 学 (<CJK Ideograph>) 1290 0x5B9E 实 (<CJK Ideograph>) 1291 0x5B9F 実 (<CJK Ideograph>) 1292 0x5C9A 岚 (<CJK Ideograph>) 1293 0x5E86 庆 (<CJK Ideograph>) 1294 0x603B 总 (<CJK Ideograph>) 1295 0x6589 斉 (<CJK Ideograph>) 1296 0x67FE 柾 (<CJK Ideograph>) 1297 0x6804 栄 (<CJK Ideograph>) 1298 0x6865 桥 (<CJK Ideograph>) 1299 0x6D4E 济 (<CJK Ideograph>) 1300 0x70BC 炼 (<CJK Ideograph>) 1301 0x7535 电 (<CJK Ideograph>) 1302 0x7EA4 纤 (<CJK Ideograph>) 1303 0x7EAC 纬 (<CJK Ideograph>) 1304 0x7EBA 纺 (<CJK Ideograph>) 1305 0x7EC7 织 (<CJK Ideograph>) 1306 0x7ECF 经 (<CJK Ideograph>) 1307 0x7EDF 统 (<CJK Ideograph>) 1308 0x7F06 缆 (<CJK Ideograph>) 1309 0x7F37 缷 (<CJK Ideograph>) 1310 0x827A 艺 (<CJK Ideograph>) 1311 0x82CF 苏 (<CJK Ideograph>) 1312 0x836F 药 (<CJK Ideograph>) 1313 0x89C6 视 (<CJK Ideograph>) 1314 0x8BBE 设 (<CJK Ideograph>) 1315 0x8BE2 询 (<CJK Ideograph>) 1316 0x8F66 车 (<CJK Ideograph>) 1317 0x8F67 轧 (<CJK Ideograph>) 1318 0x8F6E 轮 (<CJK Ideograph>) 1319 0x7411 琑 (<CJK Ideograph>) 1320 0x7CFC 糼 (<CJK Ideograph>) 1321 0x7DCD 緍 (<CJK Ideograph>) 1322 0x6946 楆 (<CJK Ideograph>) 1323 0x7AC9 竉 (<CJK Ideograph>) 1324 0x5227 刧 (<CJK Ideograph>) 1329 0x918C 醌 (<CJK Ideograph>) 1330 0x78B8 碸 (<CJK Ideograph>) 1331 0x915E 酞 (<CJK Ideograph>) 1332 0x80BC 肼 (<CJK Ideograph>) 1334 0x8D0B 贋 (<CJK Ideograph>) 1335 0x80F6 胶 (<CJK Ideograph>) 1336 0x209E7 𠧧 (<CJK Ideograph Extension B>) 1339 0x809F 肟 (<CJK Ideograph>) 1340 0x9EC7 黇 (<CJK Ideograph>) 1341 0x4CCD 䳍 (<CJK Ideograph Extension A>) 1342 0x9DC9 鷉 (<CJK Ideograph>) 1343 0x9E0C 鸌 (<CJK Ideograph>) 1344 0x4C3E 䰾 (<CJK Ideograph Extension A>) 1345 0x29DF6 𩷶 (<CJK Ideograph Extension B>) 1346 0x2700E 𧀎 (<CJK Ideograph Extension B>) 1347 0x9E0A 鸊 (<CJK Ideograph>) 1348 0x2A133 𪄳 (<CJK Ideograph Extension B>) 1349 0x35C1 㗁 (<CJK Ideograph Extension A>) 1351 0x6E9A 溚 (<CJK Ideograph>) 1352 0x823E 舾 (<CJK Ideograph>) 1353 0x7519 甙 (<CJK Ideograph>) 1355 0x4911 䤑 (<CJK Ideograph Extension A>) 1356 0x9A6C 马 (<CJK Ideograph>) 1357 0x9A8F 骏 (<CJK Ideograph>) 1358 0x9F99 龙 (<CJK Ideograph>) 1359 0x7987 禇 (<CJK Ideograph>) 1360 0x2846C 𨑬 (<CJK Ideograph Extension B>) 1361 0x21DCA 𡷊 (<CJK Ideograph Extension B>) 1362 0x205D0 𠗐 (<CJK Ideograph Extension B>) 1363 0x22AE6 𢫦 (<CJK Ideograph Extension B>) 1364 0x4E24 两 (<CJK Ideograph>) 1365 0x4E81 亁 (<CJK Ideograph>) 1366 0x4E80 亀 (<CJK Ideograph>) 1367 0x4E87 亇 (<CJK Ideograph>) 1368 0x4EBF 亿 (<CJK Ideograph>) 1369 0x4EEB 仫 (<CJK Ideograph>) 1370 0x4F37 伷 (<CJK Ideograph>) 1371 0x344C 㑌 (<CJK Ideograph Extension A>) 1372 0x4FBD 侽 (<CJK Ideograph>) 1373 0x3E48 㹈 (<CJK Ideograph Extension A>) 1374 0x5003 倃 (<CJK Ideograph>) 1375 0x5088 傈 (<CJK Ideograph>) 1376 0x347D 㑽 (<CJK Ideograph Extension A>) 1377 0x3493 㒓 (<CJK Ideograph Extension A>) 1378 0x34A5 㒥 (<CJK Ideograph Extension A>) 1379 0x5186 円 (<CJK Ideograph>) 1380 0x5905 夅 (<CJK Ideograph>) 1381 0x51DB 凛 (<CJK Ideograph>) 1382 0x51FC 凼 (<CJK Ideograph>) 1383 0x5205 刅 (<CJK Ideograph>) 1384 0x4E89 争 (<CJK Ideograph>) 1385 0x5279 剹 (<CJK Ideograph>) 1386 0x5290 劐 (<CJK Ideograph>) 1387 0x5327 匧 (<CJK Ideograph>) 1388 0x35C7 㗇 (<CJK Ideograph Extension A>) 1389 0x53A9 厩 (<CJK Ideograph>) 1390 0x3551 㕑 (<CJK Ideograph Extension A>) 1391 0x53B0 厰 (<CJK Ideograph>) 1392 0x3553 㕓 (<CJK Ideograph Extension A>) 1393 0x53C2 参 (<CJK Ideograph>) 1394 0x5423 吣 (<CJK Ideograph>) 1395 0x356D 㕭 (<CJK Ideograph Extension A>) 1396 0x3572 㕲 (<CJK Ideograph Extension A>) 1397 0x3681 㚁 (<CJK Ideograph Extension A>) 1398 0x5493 咓 (<CJK Ideograph>) 1399 0x54A3 咣 (<CJK Ideograph>) 1400 0x54B4 咴 (<CJK Ideograph>) 1401 0x54B9 咹 (<CJK Ideograph>) 1402 0x54D0 哐 (<CJK Ideograph>) 1403 0x54EF 哯 (<CJK Ideograph>) 1404 0x5518 唘 (<CJK Ideograph>) 1405 0x5523 唣 (<CJK Ideograph>) 1406 0x5528 唨 (<CJK Ideograph>) 1407 0x3598 㖘 (<CJK Ideograph Extension A>) 1408 0x553F 唿 (<CJK Ideograph>) 1409 0x35A5 㖥 (<CJK Ideograph Extension A>) 1410 0x35BF 㖿 (<CJK Ideograph Extension A>) 1411 0x55D7 嗗 (<CJK Ideograph>) 1412 0x35C5 㗅 (<CJK Ideograph Extension A>) 1413 0x27D84 𧶄 (<CJK Ideograph Extension B>) 1414 0x5525 唥 (<CJK Ideograph>) 1416 0x20C42 𠱂 (<CJK Ideograph Extension B>) 1417 0x20D15 𠴕 (<CJK Ideograph Extension B>) 1418 0x2512B 𥄫 (<CJK Ideograph Extension B>) 1419 0x5590 喐 (<CJK Ideograph>) 1420 0x22CC6 𢳆 (<CJK Ideograph Extension B>) 1421 0x39EC 㧬 (<CJK Ideograph Extension A>) 1422 0x20341 𠍁 (<CJK Ideograph Extension B>) 1423 0x8E46 蹆 (<CJK Ideograph>) 1424 0x24DB8 𤶸 (<CJK Ideograph Extension B>) 1425 0x294E5 𩓥 (<CJK Ideograph Extension B>) 1426 0x4053 䁓 (<CJK Ideograph Extension A>) 1427 0x280BE 𨂾 (<CJK Ideograph Extension B>) 1428 0x777A 睺 (<CJK Ideograph>) 1429 0x22C38 𢰸 (<CJK Ideograph Extension B>) 1430 0x3A34 㨴 (<CJK Ideograph Extension A>) 1431 0x47D5 䟕 (<CJK Ideograph Extension A>) 1432 0x2815D 𨅝 (<CJK Ideograph Extension B>) 1433 0x269F2 𦧲 (<CJK Ideograph Extension B>) 1434 0x24DEA 𤷪 (<CJK Ideograph Extension B>) 1435 0x64DD 擝 (<CJK Ideograph>) 1436 0x20D7C 𠵼 (<CJK Ideograph Extension B>) 1437 0x20FB4 𠾴 (<CJK Ideograph Extension B>) 1438 0x20CD5 𠳕 (<CJK Ideograph Extension B>) 1439 0x210F4 𡃴 (<CJK Ideograph Extension B>) 1440 0x648D 撍 (<CJK Ideograph>) 1441 0x8E7E 蹾 (<CJK Ideograph>) 1442 0x20E96 𠺖 (<CJK Ideograph Extension B>) 1443 0x20C0B 𠰋 (<CJK Ideograph Extension B>) 1444 0x20F64 𠽤 (<CJK Ideograph Extension B>) 1445 0x22CA9 𢲩 (<CJK Ideograph Extension B>) 1446 0x28256 𨉖 (<CJK Ideograph Extension B>) 1447 0x244D3 𤓓 (<CJK Ideograph Extension B>) 1449 0x20D46 𠵆 (<CJK Ideograph Extension B>) 1450 0x29A4D 𩩍 (<CJK Ideograph Extension B>) 1451 0x280E9 𨃩 (<CJK Ideograph Extension B>) 1452 0x47F4 䟴 (<CJK Ideograph Extension A>) 1453 0x24EA7 𤺧 (<CJK Ideograph Extension B>) 1454 0x22CC2 𢳂 (<CJK Ideograph Extension B>) 1455 0x9AB2 骲 (<CJK Ideograph>) 1456 0x3A67 㩧 (<CJK Ideograph Extension A>) 1457 0x295F4 𩗴 (<CJK Ideograph Extension B>) 1458 0x3FED 㿭 (<CJK Ideograph Extension A>) 1459 0x3506 㔆 (<CJK Ideograph Extension A>) 1460 0x252C7 𥋇 (<CJK Ideograph Extension B>) 1461 0x297D4 𩟔 (<CJK Ideograph Extension B>) 1462 0x278C8 𧣈 (<CJK Ideograph Extension B>) 1463 0x22D44 𢵄 (<CJK Ideograph Extension B>) 1464 0x9D6E 鵮 (<CJK Ideograph>) 1465 0x9815 頕 (<CJK Ideograph>) 1467 0x43D9 䏙 (<CJK Ideograph Extension A>) 1468 0x260A5 𦂥 (<CJK Ideograph Extension B>) 1469 0x64B4 撴 (<CJK Ideograph>) 1470 0x54E3 哣 (<CJK Ideograph>) 1471 0x22D4C 𢵌 (<CJK Ideograph Extension B>) 1472 0x22BCA 𢯊 (<CJK Ideograph Extension B>) 1473 0x21077 𡁷 (<CJK Ideograph Extension B>) 1474 0x39FB 㧻 (<CJK Ideograph Extension A>) 1475 0x2106F 𡁯 (<CJK Ideograph Extension B>) 1476 0x266DA 𦛚 (<CJK Ideograph Extension B>) 1477 0x26716 𦜖 (<CJK Ideograph Extension B>) 1478 0x279A0 𧦠 (<CJK Ideograph Extension B>) 1479 0x64EA 擪 (<CJK Ideograph>) 1480 0x25052 𥁒 (<CJK Ideograph Extension B>) 1481 0x20C43 𠱃 (<CJK Ideograph Extension B>) 1482 0x8E68 蹨 (<CJK Ideograph>) 1483 0x221A1 𢆡 (<CJK Ideograph Extension B>) 1484 0x28B4C 𨭌 (<CJK Ideograph Extension B>) 1485 0x20731 𠜱 (<CJK Ideograph Extension B>) 1487 0x480B 䠋 (<CJK Ideograph Extension A>) 1488 0x201A9 𠆩 (<CJK Ideograph Extension B>) 1489 0x3FFA 㿺 (<CJK Ideograph Extension A>) 1490 0x5873 塳 (<CJK Ideograph>) 1491 0x22D8D 𢶍 (<CJK Ideograph Extension B>) 1493 0x245C8 𤗈 (<CJK Ideograph Extension B>) 1494 0x204FC 𠓼 (<CJK Ideograph Extension B>) 1495 0x26097 𦂗 (<CJK Ideograph Extension B>) 1496 0x20F4C 𠽌 (<CJK Ideograph Extension B>) 1497 0x20D96 𠶖 (<CJK Ideograph Extension B>) 1498 0x5579 啹 (<CJK Ideograph>) 1499 0x40BB 䂻 (<CJK Ideograph Extension A>) 1500 0x43BA 䎺 (<CJK Ideograph Extension A>) 1502 0x4AB4 䪴 (<CJK Ideograph Extension A>) 1503 0x22A66 𢩦 (<CJK Ideograph Extension B>) 1504 0x2109D 𡂝 (<CJK Ideograph Extension B>) 1505 0x81AA 膪 (<CJK Ideograph>) 1506 0x98F5 飵 (<CJK Ideograph>) 1507 0x20D9C 𠶜 (<CJK Ideograph Extension B>) 1508 0x6379 捹 (<CJK Ideograph>) 1509 0x39FE 㧾 (<CJK Ideograph Extension A>) 1510 0x22775 𢝵 (<CJK Ideograph Extension B>) 1511 0x8DC0 跀 (<CJK Ideograph>) 1512 0x56A1 嚡 (<CJK Ideograph>) 1513 0x647C 摼 (<CJK Ideograph>) 1514 0x3E43 㹃 (<CJK Ideograph Extension A>) 1516 0x2A601 𪘁 (<CJK Ideograph Extension B>) 1517 0x20E09 𠸉 (<CJK Ideograph Extension B>) 1518 0x22ACF 𢫏 (<CJK Ideograph Extension B>) 1519 0x22CC9 𢳉 (<CJK Ideograph Extension B>) 1521 0x210C8 𡃈 (<CJK Ideograph Extension B>) 1522 0x239C2 𣧂 (<CJK Ideograph Extension B>) 1523 0x3992 㦒 (<CJK Ideograph Extension A>) 1524 0x3A06 㨆 (<CJK Ideograph Extension A>) 1525 0x2829B 𨊛 (<CJK Ideograph Extension B>) 1526 0x3578 㕸 (<CJK Ideograph Extension A>) 1527 0x25E49 𥹉 (<CJK Ideograph Extension B>) 1528 0x220C7 𢃇 (<CJK Ideograph Extension B>) 1529 0x5652 噒 (<CJK Ideograph>) 1530 0x20F31 𠼱 (<CJK Ideograph Extension B>) 1531 0x22CB2 𢲲 (<CJK Ideograph Extension B>) 1532 0x29720 𩜠 (<CJK Ideograph Extension B>) 1533 0x34BC 㒼 (<CJK Ideograph Extension A>) 1534 0x6C3D 氽 (<CJK Ideograph>) 1535 0x24E3B 𤸻 (<CJK Ideograph Extension B>) 1538 0x27574 𧕴 (<CJK Ideograph Extension B>) 1539 0x22E8B 𢺋 (<CJK Ideograph Extension B>) 1540 0x22208 𢈈 (<CJK Ideograph Extension B>) 1541 0x2A65B 𪙛 (<CJK Ideograph Extension B>) 1542 0x28CCD 𨳍 (<CJK Ideograph Extension B>) 1543 0x20E7A 𠹺 (<CJK Ideograph Extension B>) 1544 0x20C34 𠰴 (<CJK Ideograph Extension B>) 1545 0x2681C 𦠜 (<CJK Ideograph Extension B>) 1546 0x7F93 羓 (<CJK Ideograph>) 1547 0x210CF 𡃏 (<CJK Ideograph Extension B>) 1548 0x22803 𢠃 (<CJK Ideograph Extension B>) 1549 0x22939 𢤹 (<CJK Ideograph Extension B>) 1550 0x35FB 㗻 (<CJK Ideograph Extension A>) 1551 0x251E3 𥇣 (<CJK Ideograph Extension B>) 1552 0x20E8C 𠺌 (<CJK Ideograph Extension B>) 1553 0x20F8D 𠾍 (<CJK Ideograph Extension B>) 1554 0x20EAA 𠺪 (<CJK Ideograph Extension B>) 1555 0x3F93 㾓 (<CJK Ideograph Extension A>) 1556 0x20F30 𠼰 (<CJK Ideograph Extension B>) 1557 0x20D47 𠵇 (<CJK Ideograph Extension B>) 1558 0x2114F 𡅏 (<CJK Ideograph Extension B>) 1559 0x20E4C 𠹌 (<CJK Ideograph Extension B>) 1561 0x20EAB 𠺫 (<CJK Ideograph Extension B>) 1562 0x20BA9 𠮩 (<CJK Ideograph Extension B>) 1563 0x20D48 𠵈 (<CJK Ideograph Extension B>) 1564 0x210C0 𡃀 (<CJK Ideograph Extension B>) 1565 0x2113D 𡄽 (<CJK Ideograph Extension B>) 1566 0x3FF9 㿹 (<CJK Ideograph Extension A>) 1567 0x22696 𢚖 (<CJK Ideograph Extension B>) 1568 0x6432 搲 (<CJK Ideograph>) 1569 0x20FAD 𠾭 (<CJK Ideograph Extension B>) 1570 0x233F4 𣏴 (<CJK Ideograph Extension B>) 1571 0x27639 𧘹 (<CJK Ideograph Extension B>) 1572 0x22BCE 𢯎 (<CJK Ideograph Extension B>) 1573 0x20D7E 𠵾 (<CJK Ideograph Extension B>) 1574 0x20D7F 𠵿 (<CJK Ideograph Extension B>) 1575 0x22C51 𢱑 (<CJK Ideograph Extension B>) 1576 0x22C55 𢱕 (<CJK Ideograph Extension B>) 1577 0x3A18 㨘 (<CJK Ideograph Extension A>) 1578 0x20E98 𠺘 (<CJK Ideograph Extension B>) 1579 0x210C7 𡃇 (<CJK Ideograph Extension B>) 1580 0x20F2E 𠼮 (<CJK Ideograph Extension B>) 1581 0x2A632 𪘲 (<CJK Ideograph Extension B>) 1582 0x26B50 𦭐 (<CJK Ideograph Extension B>) 1583 0x28CD2 𨳒 (<CJK Ideograph Extension B>) 1584 0x28D99 𨶙 (<CJK Ideograph Extension B>) 1585 0x28CCA 𨳊 (<CJK Ideograph Extension B>) 1586 0x95AA 閪 (<CJK Ideograph>) 1587 0x54CC 哌 (<CJK Ideograph>) 1588 0x82C4 苄 (<CJK Ideograph>) 1589 0x55B9 喹 (<CJK Ideograph>) 1591 0x29EC3 𩻃 (<CJK Ideograph Extension B>) 1592 0x9C26 鰦 (<CJK Ideograph>) 1593 0x9AB6 骶 (<CJK Ideograph>) 1594 0x2775E 𧝞 (<CJK Ideograph Extension B>) 1595 0x22DEE 𢷮 (<CJK Ideograph Extension B>) 1596 0x7140 煀 (<CJK Ideograph>) 1597 0x816D 腭 (<CJK Ideograph>) 1598 0x80EC 胬 (<CJK Ideograph>) 1599 0x5C1C 尜 (<CJK Ideograph>) 1600 0x26572 𦕲 (<CJK Ideograph Extension B>) 1601 0x8134 脴 (<CJK Ideograph>) 1602 0x3797 㞗 (<CJK Ideograph Extension A>) 1603 0x535F 卟 (<CJK Ideograph>) 1604 0x280BD 𨂽 (<CJK Ideograph Extension B>) 1605 0x91B6 醶 (<CJK Ideograph>) 1606 0x20EFA 𠻺 (<CJK Ideograph Extension B>) 1607 0x20E0F 𠸏 (<CJK Ideograph Extension B>) 1608 0x20E77 𠹷 (<CJK Ideograph Extension B>) 1609 0x20EFB 𠻻 (<CJK Ideograph Extension B>) 1610 0x35DD 㗝 (<CJK Ideograph Extension A>) 1611 0x24DEB 𤷫 (<CJK Ideograph Extension B>) 1612 0x3609 㘉 (<CJK Ideograph Extension A>) 1613 0x20CD6 𠳖 (<CJK Ideograph Extension B>) 1614 0x56AF 嚯 (<CJK Ideograph>) 1615 0x227B5 𢞵 (<CJK Ideograph Extension B>) 1616 0x210C9 𡃉 (<CJK Ideograph Extension B>) 1617 0x20E10 𠸐 (<CJK Ideograph Extension B>) 1618 0x20E78 𠹸 (<CJK Ideograph Extension B>) 1619 0x21078 𡁸 (<CJK Ideograph Extension B>) 1620 0x21148 𡅈 (<CJK Ideograph Extension B>) 1621 0x28207 𨈇 (<CJK Ideograph Extension B>) 1622 0x21455 𡑕 (<CJK Ideograph Extension B>) 1623 0x20E79 𠹹 (<CJK Ideograph Extension B>) 1624 0x24E50 𤹐 (<CJK Ideograph Extension B>) 1625 0x22DA4 𢶤 (<CJK Ideograph Extension B>) 1626 0x5A54 婔 (<CJK Ideograph>) 1627 0x2101D 𡀝 (<CJK Ideograph Extension B>) 1628 0x2101E 𡀞 (<CJK Ideograph Extension B>) 1629 0x210F5 𡃵 (<CJK Ideograph Extension B>) 1630 0x210F6 𡃶 (<CJK Ideograph Extension B>) 1631 0x579C 垜 (<CJK Ideograph>) 1632 0x20E11 𠸑 (<CJK Ideograph Extension B>) 1633 0x27694 𧚔 (<CJK Ideograph Extension B>) 1634 0x282CD 𨋍 (<CJK Ideograph Extension B>) 1635 0x20FB5 𠾵 (<CJK Ideograph Extension B>) 1636 0x20E7B 𠹻 (<CJK Ideograph Extension B>) 1637 0x2517E 𥅾 (<CJK Ideograph Extension B>) 1638 0x3703 㜃 (<CJK Ideograph Extension A>) 1639 0x20FB6 𠾶 (<CJK Ideograph Extension B>) 1640 0x21180 𡆀 (<CJK Ideograph Extension B>) 1641 0x252D8 𥋘 (<CJK Ideograph Extension B>) 1642 0x2A2BD 𪊽 (<CJK Ideograph Extension B>) 1643 0x249DA 𤧚 (<CJK Ideograph Extension B>) 1644 0x2183A 𡠺 (<CJK Ideograph Extension B>) 1645 0x24177 𤅷 (<CJK Ideograph Extension B>) 1646 0x2827C 𨉼 (<CJK Ideograph Extension B>) 1647 0x5899 墙 (<CJK Ideograph>) 1648 0x5268 剨 (<CJK Ideograph>) 1649 0x361A 㘚 (<CJK Ideograph Extension A>) 1650 0x2573D 𥜽 (<CJK Ideograph Extension B>) 1651 0x7BB2 箲 (<CJK Ideograph>) 1652 0x5B68 孨 (<CJK Ideograph>) 1653 0x4800 䠀 (<CJK Ideograph Extension A>) 1654 0x4B2C 䬬 (<CJK Ideograph Extension A>) 1655 0x9F27 鼧 (<CJK Ideograph>) 1656 0x49E7 䧧 (<CJK Ideograph Extension A>) 1657 0x9C1F 鰟 (<CJK Ideograph>) 1658 0x9B8D 鮍 (<CJK Ideograph>) 1659 0x25B74 𥭴 (<CJK Ideograph Extension B>) 1660 0x2313D 𣄽 (<CJK Ideograph Extension B>) 1661 0x55FB 嗻 (<CJK Ideograph>) 1662 0x35F2 㗲 (<CJK Ideograph Extension A>) 1663 0x5689 嚉 (<CJK Ideograph>) 1664 0x4E28 丨 (<CJK Ideograph>) 1665 0x5902 夂 (<CJK Ideograph>) 1666 0x21BC1 𡯁 (<CJK Ideograph Extension B>) 1667 0x2F878 屮 (CJK COMPATIBILITY IDEOGRAPH-2F878) 1668 0x9751 靑 (<CJK Ideograph>) 1669 0x20086 𠂆 (<CJK Ideograph Extension B>) 1670 0x4E5B 乛 (<CJK Ideograph>) 1671 0x4EBB 亻 (<CJK Ideograph>) 1672 0x353E 㔾 (<CJK Ideograph Extension A>) 1673 0x5C23 尣 (<CJK Ideograph>) 1674 0x5F51 彑 (<CJK Ideograph>) 1675 0x5FC4 忄 (<CJK Ideograph>) 1676 0x38FA 㣺 (<CJK Ideograph Extension A>) 1677 0x624C 扌 (<CJK Ideograph>) 1678 0x6535 攵 (<CJK Ideograph>) 1679 0x6B7A 歺 (<CJK Ideograph>) 1680 0x6C35 氵 (<CJK Ideograph>) 1681 0x6C3A 氺 (<CJK Ideograph>) 1682 0x706C 灬 (<CJK Ideograph>) 1683 0x722B 爫 (<CJK Ideograph>) 1684 0x4E2C 丬 (<CJK Ideograph>) 1685 0x72AD 犭 (<CJK Ideograph>) 1686 0x248E9 𤣩 (<CJK Ideograph Extension B>) 1687 0x7F52 罒 (<CJK Ideograph>) 1688 0x793B 礻 (<CJK Ideograph>) 1689 0x7CF9 糹 (<CJK Ideograph>) 1690 0x7F53 罓 (<CJK Ideograph>) 1691 0x2626A 𦉪 (<CJK Ideograph Extension B>) 1692 0x34C1 㓁 (<CJK Ideograph Extension A>) 1694 0x2634B 𦍋 (<CJK Ideograph Extension B>) 1695 0x8002 耂 (<CJK Ideograph>) 1696 0x8080 肀 (<CJK Ideograph>) 1697 0x26612 𦘒 (<CJK Ideograph Extension B>) 1698 0x26951 𦥑 (<CJK Ideograph Extension B>) 1699 0x535D 卝 (<CJK Ideograph>) 1700 0x8864 衤 (<CJK Ideograph>) 1701 0x89C1 见 (<CJK Ideograph>) 1702 0x278B2 𧢲 (<CJK Ideograph Extension B>) 1703 0x8BA0 讠 (<CJK Ideograph>) 1704 0x8D1D 贝 (<CJK Ideograph>) 1705 0x9485 钅 (<CJK Ideograph>) 1706 0x9578 镸 (<CJK Ideograph>) 1707 0x957F 长 (<CJK Ideograph>) 1708 0x95E8 门 (<CJK Ideograph>) 1709 0x28E0F 𨸏 (<CJK Ideograph Extension B>) 1710 0x97E6 韦 (<CJK Ideograph>) 1711 0x9875 页 (<CJK Ideograph>) 1712 0x98CE 风 (<CJK Ideograph>) 1713 0x98DE 飞 (<CJK Ideograph>) 1714 0x9963 饣 (<CJK Ideograph>) 1715 0x29810 𩠐 (<CJK Ideograph Extension B>) 1716 0x9C7C 鱼 (<CJK Ideograph>) 1717 0x9E1F 鸟 (<CJK Ideograph>) 1718 0x9EC4 黄 (<CJK Ideograph>) 1719 0x6B6F 歯 (<CJK Ideograph>) 1720 0xF907 龜 (CJK COMPATIBILITY IDEOGRAPH-F907) 1721 0x4E37 丷 (<CJK Ideograph>) 1722 0x20087 𠂇 (<CJK Ideograph Extension B>) 1723 0x961D 阝 (<CJK Ideograph>) 1724 0x6237 户 (<CJK Ideograph>) 1725 0x94A2 钢 (<CJK Ideograph>) 1727 0x503B 倻 (<CJK Ideograph>) 1728 0x6DFE 淾 (<CJK Ideograph>) 1729 0x29C73 𩱳 (<CJK Ideograph Extension B>) 1730 0x9FA6 龦 (<CJK Ideograph>) 1731 0x3DC9 㷉 (<CJK Ideograph Extension A>) 1732 0x888F 袏 (<CJK Ideograph>) 1733 0x2414E 𤅎 (<CJK Ideograph Extension B>) 1734 0x7077 灷 (<CJK Ideograph>) 1735 0x5CF5 峵 (<CJK Ideograph>) 1736 0x4B20 䬠 (<CJK Ideograph Extension A>) 1737 0x251CD 𥇍 (<CJK Ideograph Extension B>) 1738 0x3559 㕙 (<CJK Ideograph Extension A>) 1739 0x25D30 𥴰 (<CJK Ideograph Extension B>) 1740 0x6122 愢 (<CJK Ideograph>) 1741 0x28A32 𨨲 (<CJK Ideograph Extension B>) 1742 0x8FA7 辧 (<CJK Ideograph>) 1743 0x91F6 釶 (<CJK Ideograph>) 1744 0x7191 熑 (<CJK Ideograph>) 1745 0x6719 朙 (<CJK Ideograph>) 1746 0x73BA 玺 (<CJK Ideograph>) 1747 0x23281 𣊁 (<CJK Ideograph Extension B>) 1748 0x2A107 𪄇 (<CJK Ideograph Extension B>) 1749 0x3C8B 㲋 (<CJK Ideograph Extension A>) 1750 0x21980 𡦀 (<CJK Ideograph Extension B>) 1751 0x4B10 䬐 (<CJK Ideograph Extension A>) 1752 0x78E4 磤 (<CJK Ideograph>) 1753 0x7402 琂 (<CJK Ideograph>) 1754 0x51AE 冮 (<CJK Ideograph>) 1755 0x2870F 𨜏 (<CJK Ideograph Extension B>) 1756 0x4009 䀉 (<CJK Ideograph Extension A>) 1757 0x6A63 橣 (<CJK Ideograph>) 1758 0x2A2BA 𪊺 (<CJK Ideograph Extension B>) 1759 0x4223 䈣 (<CJK Ideograph Extension A>) 1760 0x860F 蘏 (<CJK Ideograph>) 1761 0x20A6F 𠩯 (<CJK Ideograph Extension B>) 1762 0x7A2A 稪 (<CJK Ideograph>) 1763 0x29947 𩥇 (<CJK Ideograph Extension B>) 1764 0x28AEA 𨫪 (<CJK Ideograph Extension B>) 1765 0x9755 靕 (<CJK Ideograph>) 1766 0x704D 灍 (<CJK Ideograph>) 1767 0x5324 匤 (<CJK Ideograph>) 1768 0x2207E 𢁾 (<CJK Ideograph Extension B>) 1769 0x93F4 鏴 (<CJK Ideograph>) 1770 0x76D9 盙 (<CJK Ideograph>) 1771 0x289E3 𨧣 (<CJK Ideograph Extension B>) 1772 0x9FA7 龧 (<CJK Ideograph>) 1773 0x77DD 矝 (<CJK Ideograph>) 1774 0x4EA3 亣 (<CJK Ideograph>) 1775 0x4FF0 俰 (<CJK Ideograph>) 1776 0x50BC 傼 (<CJK Ideograph>) 1777 0x4E2F 丯 (<CJK Ideograph>) 1778 0x4F17 众 (<CJK Ideograph>) 1779 0x9FA8 龨 (<CJK Ideograph>) 1780 0x5434 吴 (<CJK Ideograph>) 1781 0x7D8B 綋 (<CJK Ideograph>) 1782 0x5892 墒 (<CJK Ideograph>) 1783 0x58D0 壐 (<CJK Ideograph>) 1784 0x21DB6 𡶶 (<CJK Ideograph Extension B>) 1785 0x5E92 庒 (<CJK Ideograph>) 1786 0x5E99 庙 (<CJK Ideograph>) 1787 0x5FC2 忂 (<CJK Ideograph>) 1788 0x22712 𢜒 (<CJK Ideograph Extension B>) 1789 0x658B 斋 (<CJK Ideograph>) 1790 0x233F9 𣏹 (<CJK Ideograph Extension B>) 1791 0x6919 椙 (<CJK Ideograph>) 1792 0x6A43 橃 (<CJK Ideograph>) 1793 0x23C63 𣱣 (<CJK Ideograph Extension B>) 1794 0x6CFF 泿 (<CJK Ideograph>) 1796 0x7200 爀 (<CJK Ideograph>) 1797 0x24505 𤔅 (<CJK Ideograph Extension B>) 1798 0x738C 玌 (<CJK Ideograph>) 1799 0x3EDB 㻛 (<CJK Ideograph Extension A>) 1800 0x24A13 𤨓 (<CJK Ideograph Extension B>) 1801 0x5B15 嬕 (<CJK Ideograph>) 1802 0x74B9 璹 (<CJK Ideograph>) 1803 0x8B83 讃 (<CJK Ideograph>) 1804 0x25CA4 𥲤 (<CJK Ideograph Extension B>) 1805 0x25695 𥚕 (<CJK Ideograph Extension B>) 1806 0x7A93 窓 (<CJK Ideograph>) 1807 0x7BEC 篬 (<CJK Ideograph>) 1808 0x7CC3 糃 (<CJK Ideograph>) 1809 0x7E6C 繬 (<CJK Ideograph>) 1810 0x82F8 苸 (<CJK Ideograph>) 1811 0x8597 薗 (<CJK Ideograph>) 1812 0x9FA9 龩 (<CJK Ideograph>) 1813 0x8890 袐 (<CJK Ideograph>) 1814 0x9FAA 龪 (<CJK Ideograph>) 1815 0x8EB9 躹 (<CJK Ideograph>) 1816 0x9FAB 龫 (<CJK Ideograph>) 1817 0x8FCF 迏 (<CJK Ideograph>) 1818 0x855F 蕟 (<CJK Ideograph>) 1819 0x99E0 駠 (<CJK Ideograph>) 1820 0x9221 鈡 (<CJK Ideograph>) 1821 0x9FAC 龬 (<CJK Ideograph>) 1822 0x28DB9 𨶹 (<CJK Ideograph Extension B>) 1823 0x2143F 𡐿 (<CJK Ideograph Extension B>) 1824 0x4071 䁱 (<CJK Ideograph Extension A>) 1825 0x42A2 䊢 (<CJK Ideograph Extension A>) 1826 0x5A1A 娚 (<CJK Ideograph>) 1830 0x9868 顨 (<CJK Ideograph>) 1831 0x676B 杫 (<CJK Ideograph>) 1832 0x4276 䉶 (<CJK Ideograph Extension A>) 1833 0x573D 圽 (<CJK Ideograph>) 1835 0x85D6 藖 (<CJK Ideograph>) 1836 0x2497B 𤥻 (<CJK Ideograph Extension B>) 1837 0x82BF 芿 (<CJK Ideograph>) 1838 0x2710D 𧄍 (<CJK Ideograph Extension B>) 1839 0x4C81 䲁 (<CJK Ideograph Extension A>) 1840 0x26D74 𦵴 (<CJK Ideograph Extension B>) 1841 0x5D7B 嵻 (<CJK Ideograph>) 1842 0x26B15 𦬕 (<CJK Ideograph Extension B>) 1843 0x26FBE 𦾾 (<CJK Ideograph Extension B>) 1844 0x9FAD 龭 (<CJK Ideograph>) 1845 0x9FAE 龮 (<CJK Ideograph>) 1846 0x5B96 宖 (<CJK Ideograph>) 1847 0x9FAF 龯 (<CJK Ideograph>) 1848 0x66E7 曧 (<CJK Ideograph>) 1849 0x7E5B 繛 (<CJK Ideograph>) 1850 0x6E57 湗 (<CJK Ideograph>) 1851 0x79CA 秊 (<CJK Ideograph>) 1852 0x3D88 㶈 (<CJK Ideograph Extension A>) 1853 0x44C3 䓃 (<CJK Ideograph Extension A>) 1854 0x23256 𣉖 (<CJK Ideograph Extension B>) 1855 0x22796 𢞖 (<CJK Ideograph Extension B>) 1856 0x439A 䎚 (<CJK Ideograph Extension A>) 1857 0x4536 䔶 (<CJK Ideograph Extension A>) 1859 0x5CD5 峕 (<CJK Ideograph>) 1860 0x23B1A 𣬚 (<CJK Ideograph Extension B>) 1861 0x8AF9 諹 (<CJK Ideograph>) 1862 0x5C78 屸 (<CJK Ideograph>) 1863 0x3D12 㴒 (<CJK Ideograph Extension A>) 1864 0x23551 𣕑 (<CJK Ideograph Extension B>) 1865 0x5D78 嵸 (<CJK Ideograph>) 1866 0x9FB2 龲 (<CJK Ideograph>) 1867 0x7157 煗 (<CJK Ideograph>) 1868 0x4558 䕘 (<CJK Ideograph Extension A>) 1869 0x240EC 𤃬 (<CJK Ideograph Extension B>) 1870 0x21E23 𡸣 (<CJK Ideograph Extension B>) 1871 0x4C77 䱷 (<CJK Ideograph Extension A>) 1872 0x3978 㥸 (<CJK Ideograph Extension A>) 1873 0x344A 㑊 (<CJK Ideograph Extension A>) 1874 0x201A4 𠆤 (<CJK Ideograph Extension B>) 1875 0x26C41 𦱁 (<CJK Ideograph Extension B>) 1876 0x8ACC 諌 (<CJK Ideograph>) 1877 0x4FB4 侴 (<CJK Ideograph>) 1878 0x20239 𠈹 (<CJK Ideograph Extension B>) 1879 0x59BF 妿 (<CJK Ideograph>) 1880 0x816C 腬 (<CJK Ideograph>) 1881 0x9856 顖 (<CJK Ideograph>) 1882 0x298FA 𩣺 (<CJK Ideograph Extension B>) 1883 0x5F3B 弻 (<CJK Ideograph>) 1884 0x20B9F 𠮟 (<CJK Ideograph Extension B>) 1886 0x221C1 𢇁 (<CJK Ideograph Extension B>) 1887 0x2896D 𨥭 (<CJK Ideograph Extension B>) 1888 0x4102 䄂 (<CJK Ideograph Extension A>) 1889 0x46BB 䚻 (<CJK Ideograph Extension A>) 1890 0x29079 𩁹 (<CJK Ideograph Extension B>) 1891 0x3F07 㼇 (<CJK Ideograph Extension A>) 1892 0x9FB3 龳 (<CJK Ideograph>) 1893 0x2A1B5 𪆵 (<CJK Ideograph Extension B>) 1894 0x40F8 䃸 (<CJK Ideograph Extension A>) 1895 0x37D6 㟖 (<CJK Ideograph Extension A>) 1896 0x46F7 䛷 (<CJK Ideograph Extension A>) 1897 0x26C46 𦱆 (<CJK Ideograph Extension B>) 1898 0x417C 䅼 (<CJK Ideograph Extension A>) 1899 0x286B2 𨚲 (<CJK Ideograph Extension B>) 1900 0x273FF 𧏿 (<CJK Ideograph Extension B>) 1901 0x456D 䕭 (<CJK Ideograph Extension A>) 1902 0x38D4 㣔 (<CJK Ideograph Extension A>) 1903 0x2549A 𥒚 (<CJK Ideograph Extension B>) 1904 0x4561 䕡 (<CJK Ideograph Extension A>) 1905 0x451B 䔛 (<CJK Ideograph Extension A>) 1906 0x4D89 䶉 (<CJK Ideograph Extension A>) 1907 0x4C7B 䱻 (<CJK Ideograph Extension A>) 1908 0x4D76 䵶 (<CJK Ideograph Extension A>) 1909 0x45EA 䗪 (<CJK Ideograph Extension A>) 1910 0x3FC8 㿈 (<CJK Ideograph Extension A>) 1911 0x24B0F 𤬏 (<CJK Ideograph Extension B>) 1912 0x3661 㙡 (<CJK Ideograph Extension A>) 1913 0x44DE 䓞 (<CJK Ideograph Extension A>) 1914 0x44BD 䒽 (<CJK Ideograph Extension A>) 1915 0x41ED 䇭 (<CJK Ideograph Extension A>) 1916 0x5D3E 崾 (<CJK Ideograph>) 1917 0x5D48 嵈 (<CJK Ideograph>) 1918 0x5D56 嵖 (<CJK Ideograph>) 1919 0x3DFC 㷼 (<CJK Ideograph Extension A>) 1920 0x380F 㠏 (<CJK Ideograph Extension A>) 1921 0x5DA4 嶤 (<CJK Ideograph>) 1922 0x5DB9 嶹 (<CJK Ideograph>) 1923 0x3820 㠠 (<CJK Ideograph Extension A>) 1924 0x3838 㠸 (<CJK Ideograph Extension A>) 1925 0x5E42 幂 (<CJK Ideograph>) 1926 0x5EBD 庽 (<CJK Ideograph>) 1927 0x5F25 弥 (<CJK Ideograph>) 1928 0x5F83 徃 (<CJK Ideograph>) 1929 0x3908 㤈 (<CJK Ideograph Extension A>) 1930 0x3914 㤔 (<CJK Ideograph Extension A>) 1931 0x393F 㤿 (<CJK Ideograph Extension A>) 1932 0x394D 㥍 (<CJK Ideograph Extension A>) 1933 0x60D7 惗 (<CJK Ideograph>) 1934 0x613D 愽 (<CJK Ideograph>) 1935 0x5CE5 峥 (<CJK Ideograph>) 1936 0x3989 㦉 (<CJK Ideograph Extension A>) 1937 0x61B7 憷 (<CJK Ideograph>) 1938 0x61B9 憹 (<CJK Ideograph>) 1939 0x61CF 懏 (<CJK Ideograph>) 1940 0x39B8 㦸 (<CJK Ideograph Extension A>) 1941 0x622C 戬 (<CJK Ideograph>) 1942 0x6290 抐 (<CJK Ideograph>) 1943 0x62E5 拥 (<CJK Ideograph>) 1944 0x6318 挘 (<CJK Ideograph>) 1945 0x39F8 㧸 (<CJK Ideograph Extension A>) 1946 0x56B1 嚱 (<CJK Ideograph>) 1947 0x3A03 㨃 (<CJK Ideograph Extension A>) 1948 0x63E2 揢 (<CJK Ideograph>) 1949 0x63FB 揻 (<CJK Ideograph>) 1950 0x6407 搇 (<CJK Ideograph>) 1951 0x645A 摚 (<CJK Ideograph>) 1952 0x3A4B 㩋 (<CJK Ideograph Extension A>) 1953 0x64C0 擀 (<CJK Ideograph>) 1954 0x5D15 崕 (<CJK Ideograph>) 1955 0x5621 嘡 (<CJK Ideograph>) 1956 0x9F9F 龟 (<CJK Ideograph>) 1957 0x3A97 㪗 (<CJK Ideograph Extension A>) 1958 0x6586 斆 (<CJK Ideograph>) 1959 0x3ABD 㪽 (<CJK Ideograph Extension A>) 1960 0x65FF 旿 (<CJK Ideograph>) 1961 0x6653 晓 (<CJK Ideograph>) 1962 0x3AF2 㫲 (<CJK Ideograph Extension A>) 1963 0x6692 暒 (<CJK Ideograph>) 1964 0x3B22 㬢 (<CJK Ideograph Extension A>) 1965 0x6716 朖 (<CJK Ideograph>) 1966 0x3B42 㭂 (<CJK Ideograph Extension A>) 1967 0x67A4 枤 (<CJK Ideograph>) 1968 0x6800 栀 (<CJK Ideograph>) 1969 0x3B58 㭘 (<CJK Ideograph Extension A>) 1970 0x684A 桊 (<CJK Ideograph>) 1971 0x6884 梄 (<CJK Ideograph>) 1972 0x3B72 㭲 (<CJK Ideograph Extension A>) 1973 0x3B71 㭱 (<CJK Ideograph Extension A>) 1974 0x3B7B 㭻 (<CJK Ideograph Extension A>) 1975 0x6909 椉 (<CJK Ideograph>) 1976 0x6943 楃 (<CJK Ideograph>) 1977 0x725C 牜 (<CJK Ideograph>) 1978 0x6964 楤 (<CJK Ideograph>) 1979 0x699F 榟 (<CJK Ideograph>) 1980 0x6985 榅 (<CJK Ideograph>) 1981 0x3BBC 㮼 (<CJK Ideograph Extension A>) 1982 0x69D6 槖 (<CJK Ideograph>) 1983 0x3BDD 㯝 (<CJK Ideograph Extension A>) 1984 0x6A65 橥 (<CJK Ideograph>) 1985 0x6A74 橴 (<CJK Ideograph>) 1986 0x6A71 橱 (<CJK Ideograph>) 1987 0x6A82 檂 (<CJK Ideograph>) 1988 0x3BEC 㯬 (<CJK Ideograph Extension A>) 1989 0x6A99 檙 (<CJK Ideograph>) 1990 0x3BF2 㯲 (<CJK Ideograph Extension A>) 1991 0x6AAB 檫 (<CJK Ideograph>) 1992 0x6AB5 檵 (<CJK Ideograph>) 1993 0x6AD4 櫔 (<CJK Ideograph>) 1994 0x6AF6 櫶 (<CJK Ideograph>) 1995 0x6B81 殁 (<CJK Ideograph>) 1996 0x6BC1 毁 (<CJK Ideograph>) 1997 0x6BEA 毪 (<CJK Ideograph>) 1998 0x6C75 汵 (<CJK Ideograph>) 1999 0x6CAA 沪 (<CJK Ideograph>) 2000 0x3CCB 㳋 (<CJK Ideograph Extension A>) 2001 0x6D02 洂 (<CJK Ideograph>) 2002 0x6D06 洆 (<CJK Ideograph>) 2003 0x6D26 洦 (<CJK Ideograph>) 2004 0x6D81 涁 (<CJK Ideograph>) 2005 0x3CEF 㳯 (<CJK Ideograph Extension A>) 2006 0x6DA4 涤 (<CJK Ideograph>) 2007 0x6DB1 涱 (<CJK Ideograph>) 2008 0x6E15 渕 (<CJK Ideograph>) 2009 0x6E18 渘 (<CJK Ideograph>) 2010 0x6E29 温 (<CJK Ideograph>) 2011 0x6E86 溆 (<CJK Ideograph>) 2012 0x289C0 𨧀 (<CJK Ideograph Extension B>) 2013 0x6EBB 溻 (<CJK Ideograph>) 2014 0x6EE2 滢 (<CJK Ideograph>) 2015 0x6EDA 滚 (<CJK Ideograph>) 2016 0x9F7F 齿 (<CJK Ideograph>) 2017 0x6EE8 滨 (<CJK Ideograph>) 2018 0x6EE9 滩 (<CJK Ideograph>) 2019 0x6F24 漤 (<CJK Ideograph>) 2020 0x6F34 漴 (<CJK Ideograph>) 2021 0x3D46 㵆 (<CJK Ideograph Extension A>) 2022 0x23F41 𣽁 (<CJK Ideograph Extension B>) 2023 0x6F81 澁 (<CJK Ideograph>) 2024 0x6FBE 澾 (<CJK Ideograph>) 2025 0x3D6A 㵪 (<CJK Ideograph Extension A>) 2026 0x3D75 㵵 (<CJK Ideograph Extension A>) 2027 0x71B7 熷 (<CJK Ideograph>) 2028 0x5C99 岙 (<CJK Ideograph>) 2029 0x3D8A 㶊 (<CJK Ideograph Extension A>) 2030 0x702C 瀬 (<CJK Ideograph>) 2031 0x3D91 㶑 (<CJK Ideograph Extension A>) 2032 0x7050 灐 (<CJK Ideograph>) 2033 0x7054 灔 (<CJK Ideograph>) 2034 0x706F 灯 (<CJK Ideograph>) 2035 0x707F 灿 (<CJK Ideograph>) 2036 0x7089 炉 (<CJK Ideograph>) 2037 0x20325 𠌥 (<CJK Ideograph Extension B>) 2038 0x43C1 䏁 (<CJK Ideograph Extension A>) 2039 0x35F1 㗱 (<CJK Ideograph Extension A>) 2040 0x20ED8 𠻘 (<CJK Ideograph Extension B>) 2041 0x23ED7 𣻗 (<CJK Ideograph Extension B>) 2042 0x57BE 垾 (<CJK Ideograph>) 2043 0x26ED3 𦻓 (<CJK Ideograph Extension B>) 2044 0x713E 焾 (<CJK Ideograph>) 2045 0x257E0 𥟠 (<CJK Ideograph Extension B>) 2046 0x364E 㙎 (<CJK Ideograph Extension A>) 2047 0x69A2 榢 (<CJK Ideograph>) 2048 0x28BE9 𨯩 (<CJK Ideograph Extension B>) 2049 0x5B74 孴 (<CJK Ideograph>) 2050 0x7A49 穉 (<CJK Ideograph>) 2051 0x258E1 𥣡 (<CJK Ideograph Extension B>) 2052 0x294D9 𩓙 (<CJK Ideograph Extension B>) 2053 0x7A65 穥 (<CJK Ideograph>) 2054 0x7A7D 穽 (<CJK Ideograph>) 2055 0x259AC 𥦬 (<CJK Ideograph Extension B>) 2056 0x7ABB 窻 (<CJK Ideograph>) 2057 0x7AB0 窰 (<CJK Ideograph>) 2058 0x7AC2 竂 (<CJK Ideograph>) 2059 0x7AC3 竃 (<CJK Ideograph>) 2060 0x71D1 燑 (<CJK Ideograph>) 2061 0x2648D 𦒍 (<CJK Ideograph Extension B>) 2062 0x41CA 䇊 (<CJK Ideograph Extension A>) 2063 0x7ADA 竚 (<CJK Ideograph>) 2064 0x7ADD 竝 (<CJK Ideograph>) 2065 0x7AEA 竪 (<CJK Ideograph>) 2066 0x41EF 䇯 (<CJK Ideograph Extension A>) 2067 0x54B2 咲 (<CJK Ideograph>) 2068 0x25C01 𥰁 (<CJK Ideograph Extension B>) 2069 0x7B0B 笋 (<CJK Ideograph>) 2070 0x7B55 筕 (<CJK Ideograph>) 2071 0x7B29 笩 (<CJK Ideograph>) 2072 0x2530E 𥌎 (<CJK Ideograph Extension B>) 2073 0x25CFE 𥳾 (<CJK Ideograph Extension B>) 2074 0x7BA2 箢 (<CJK Ideograph>) 2075 0x7B6F 筯 (<CJK Ideograph>) 2076 0x839C 莜 (<CJK Ideograph>) 2077 0x25BB4 𥮴 (<CJK Ideograph Extension B>) 2078 0x26C7F 𦱿 (<CJK Ideograph Extension B>) 2079 0x7BD0 篐 (<CJK Ideograph>) 2080 0x8421 萡 (<CJK Ideograph>) 2081 0x7B92 箒 (<CJK Ideograph>) 2082 0x7BB8 箸 (<CJK Ideograph>) 2083 0x25D20 𥴠 (<CJK Ideograph Extension B>) 2084 0x3DAD 㶭 (<CJK Ideograph Extension A>) 2085 0x25C65 𥱥 (<CJK Ideograph Extension B>) 2086 0x8492 蒒 (<CJK Ideograph>) 2087 0x7BFA 篺 (<CJK Ideograph>) 2088 0x7C06 簆 (<CJK Ideograph>) 2089 0x7C35 簵 (<CJK Ideograph>) 2090 0x25CC1 𥳁 (<CJK Ideograph Extension B>) 2091 0x7C44 籄 (<CJK Ideograph>) 2092 0x7C83 粃 (<CJK Ideograph>) 2093 0x24882 𤢂 (<CJK Ideograph Extension B>) 2094 0x7CA6 粦 (<CJK Ideograph>) 2095 0x667D 晽 (<CJK Ideograph>) 2096 0x24578 𤕸 (<CJK Ideograph Extension B>) 2097 0x7CC9 糉 (<CJK Ideograph>) 2098 0x7CC7 糇 (<CJK Ideograph>) 2099 0x7CE6 糦 (<CJK Ideograph>) 2100 0x7C74 籴 (<CJK Ideograph>) 2101 0x7CF3 糳 (<CJK Ideograph>) 2102 0x7CF5 糵 (<CJK Ideograph>) 2103 0x7CCE 糎 (<CJK Ideograph>) 2104 0x7E67 繧 (<CJK Ideograph>) 2105 0x451D 䔝 (<CJK Ideograph Extension A>) 2106 0x26E44 𦹄 (<CJK Ideograph Extension B>) 2107 0x7D5D 絝 (<CJK Ideograph>) 2108 0x26ED6 𦻖 (<CJK Ideograph Extension B>) 2109 0x748D 璍 (<CJK Ideograph>) 2110 0x7D89 綉 (<CJK Ideograph>) 2111 0x7DAB 綫 (<CJK Ideograph>) 2112 0x7135 焵 (<CJK Ideograph>) 2113 0x7DB3 綳 (<CJK Ideograph>) 2114 0x7DD2 緒 (<CJK Ideograph>) 2115 0x24057 𤁗 (<CJK Ideograph Extension B>) 2116 0x26029 𦀩 (<CJK Ideograph Extension B>) 2117 0x7DE4 緤 (<CJK Ideograph>) 2118 0x3D13 㴓 (<CJK Ideograph Extension A>) 2119 0x7DF5 緵 (<CJK Ideograph>) 2120 0x217F9 𡟹 (<CJK Ideograph Extension B>) 2121 0x7DE5 緥 (<CJK Ideograph>) 2122 0x2836D 𨍭 (<CJK Ideograph Extension B>) 2123 0x7E1D 縝 (<CJK Ideograph>) 2124 0x26121 𦄡 (<CJK Ideograph Extension B>) 2125 0x2615A 𦅚 (<CJK Ideograph Extension B>) 2126 0x7E6E 繮 (<CJK Ideograph>) 2127 0x7E92 纒 (<CJK Ideograph>) 2128 0x432B 䌫 (<CJK Ideograph Extension A>) 2129 0x946C 鑬 (<CJK Ideograph>) 2130 0x7E27 縧 (<CJK Ideograph>) 2131 0x7F40 罀 (<CJK Ideograph>) 2132 0x7F41 罁 (<CJK Ideograph>) 2133 0x7F47 罇 (<CJK Ideograph>) 2134 0x7936 礶 (<CJK Ideograph>) 2135 0x262D0 𦋐 (<CJK Ideograph Extension B>) 2136 0x99E1 駡 (<CJK Ideograph>) 2137 0x7F97 羗 (<CJK Ideograph>) 2138 0x26351 𦍑 (<CJK Ideograph Extension B>) 2139 0x7FA3 羣 (<CJK Ideograph>) 2140 0x21661 𡙡 (<CJK Ideograph Extension B>) 2141 0x20068 𠁨 (<CJK Ideograph Extension B>) 2142 0x455C 䕜 (<CJK Ideograph Extension A>) 2143 0x23766 𣝦 (<CJK Ideograph Extension B>) 2144 0x4503 䔃 (<CJK Ideograph Extension A>) 2145 0x2833A 𨌺 (<CJK Ideograph Extension B>) 2146 0x7FFA 翺 (<CJK Ideograph>) 2147 0x26489 𦒉 (<CJK Ideograph Extension B>) 2148 0x8005 者 (<CJK Ideograph>) 2149 0x8008 耈 (<CJK Ideograph>) 2150 0x801D 耝 (<CJK Ideograph>) 2151 0x8028 耨 (<CJK Ideograph>) 2152 0x802F 耯 (<CJK Ideograph>) 2153 0x2A087 𪂇 (<CJK Ideograph Extension B>) 2154 0x26CC3 𦳃 (<CJK Ideograph Extension B>) 2155 0x803B 耻 (<CJK Ideograph>) 2156 0x803C 耼 (<CJK Ideograph>) 2157 0x8061 聡 (<CJK Ideograph>) 2158 0x22714 𢜔 (<CJK Ideograph Extension B>) 2159 0x4989 䦉 (<CJK Ideograph Extension A>) 2160 0x26626 𦘦 (<CJK Ideograph Extension B>) 2161 0x23DE3 𣷣 (<CJK Ideograph Extension B>) 2162 0x266E8 𦛨 (<CJK Ideograph Extension B>) 2163 0x6725 朥 (<CJK Ideograph>) 2164 0x80A7 肧 (<CJK Ideograph>) 2165 0x28A48 𨩈 (<CJK Ideograph Extension B>) 2166 0x8107 脇 (<CJK Ideograph>) 2167 0x811A 脚 (<CJK Ideograph>) 2168 0x58B0 墰 (<CJK Ideograph>) 2169 0x226F6 𢛶 (<CJK Ideograph Extension B>) 2170 0x6C7F 汿 (<CJK Ideograph>) 2171 0x26498 𦒘 (<CJK Ideograph Extension B>) 2172 0x24FB8 𤾸 (<CJK Ideograph Extension B>) 2173 0x64E7 擧 (<CJK Ideograph>) 2174 0x2148A 𡒊 (<CJK Ideograph Extension B>) 2175 0x8218 舘 (<CJK Ideograph>) 2176 0x2185E 𡡞 (<CJK Ideograph Extension B>) 2177 0x6A53 橓 (<CJK Ideograph>) 2178 0x24A65 𤩥 (<CJK Ideograph Extension B>) 2179 0x24A95 𤪕 (<CJK Ideograph Extension B>) 2180 0x447A 䑺 (<CJK Ideograph Extension A>) 2181 0x8229 舩 (<CJK Ideograph>) 2182 0x20B0D 𠬍 (<CJK Ideograph Extension B>) 2183 0x26A52 𦩒 (<CJK Ideograph Extension B>) 2184 0x23D7E 𣵾 (<CJK Ideograph Extension B>) 2185 0x4FF9 俹 (<CJK Ideograph>) 2186 0x214FD 𡓽 (<CJK Ideograph Extension B>) 2187 0x84E2 蓢 (<CJK Ideograph>) 2188 0x8362 荢 (<CJK Ideograph>) 2189 0x26B0A 𦬊 (<CJK Ideograph Extension B>) 2190 0x249A7 𤦧 (<CJK Ideograph Extension B>) 2191 0x23530 𣔰 (<CJK Ideograph Extension B>) 2192 0x21773 𡝳 (<CJK Ideograph Extension B>) 2193 0x23DF8 𣷸 (<CJK Ideograph Extension B>) 2194 0x82AA 芪 (<CJK Ideograph>) 2195 0x691B 椛 (<CJK Ideograph>) 2196 0x2F994 芳 (CJK COMPATIBILITY IDEOGRAPH-2F994) 2197 0x41DB 䇛 (<CJK Ideograph Extension A>) 2198 0x854B 蕋 (<CJK Ideograph>) 2199 0x82D0 苐 (<CJK Ideograph>) 2200 0x831A 茚 (<CJK Ideograph>) 2201 0x20E16 𠸖 (<CJK Ideograph Extension B>) 2202 0x217B4 𡞴 (<CJK Ideograph Extension B>) 2203 0x36C1 㛁 (<CJK Ideograph Extension A>) 2204 0x2317D 𣅽 (<CJK Ideograph Extension B>) 2205 0x2355A 𣕚 (<CJK Ideograph Extension B>) 2206 0x827B 艻 (<CJK Ideograph>) 2207 0x82E2 苢 (<CJK Ideograph>) 2208 0x8318 茘 (<CJK Ideograph>) 2209 0x23E8B 𣺋 (<CJK Ideograph Extension B>) 2210 0x26DA3 𦶣 (<CJK Ideograph Extension B>) 2211 0x26B05 𦬅 (<CJK Ideograph Extension B>) 2212 0x26B97 𦮗 (<CJK Ideograph Extension B>) 2213 0x235CE 𣗎 (<CJK Ideograph Extension B>) 2214 0x3DBF 㶿 (<CJK Ideograph Extension A>) 2215 0x831D 茝 (<CJK Ideograph>) 2216 0x55EC 嗬 (<CJK Ideograph>) 2217 0x8385 莅 (<CJK Ideograph>) 2218 0x450B 䔋 (<CJK Ideograph Extension A>) 2219 0x26DA5 𦶥 (<CJK Ideograph Extension B>) 2220 0x83AC 莬 (<CJK Ideograph>) 2221 0x83C1 菁 (<CJK Ideograph>) 2222 0x83D3 菓 (<CJK Ideograph>) 2223 0x347E 㑾 (<CJK Ideograph Extension A>) 2224 0x26ED4 𦻔 (<CJK Ideograph Extension B>) 2225 0x6A57 橗 (<CJK Ideograph>) 2226 0x855A 蕚 (<CJK Ideograph>) 2227 0x3496 㒖 (<CJK Ideograph Extension A>) 2228 0x26E42 𦹂 (<CJK Ideograph Extension B>) 2229 0x22EEF 𢻯 (<CJK Ideograph Extension B>) 2230 0x8458 葘 (<CJK Ideograph>) 2231 0x25BE4 𥯤 (<CJK Ideograph Extension B>) 2232 0x8471 葱 (<CJK Ideograph>) 2233 0x3DD3 㷓 (<CJK Ideograph Extension A>) 2234 0x44E4 䓤 (<CJK Ideograph Extension A>) 2235 0x6AA7 檧 (<CJK Ideograph>) 2236 0x844A 葊 (<CJK Ideograph>) 2237 0x23CB5 𣲵 (<CJK Ideograph Extension B>) 2238 0x7958 祘 (<CJK Ideograph>) 2239 0x84A8 蒨 (<CJK Ideograph>) 2240 0x26B96 𦮖 (<CJK Ideograph Extension B>) 2241 0x26E77 𦹷 (<CJK Ideograph Extension B>) 2242 0x26E43 𦹃 (<CJK Ideograph Extension B>) 2243 0x84DE 蓞 (<CJK Ideograph>) 2244 0x840F 萏 (<CJK Ideograph>) 2245 0x8391 莑 (<CJK Ideograph>) 2246 0x44A0 䒠 (<CJK Ideograph Extension A>) 2247 0x8493 蒓 (<CJK Ideograph>) 2248 0x84E4 蓤 (<CJK Ideograph>) 2249 0x25C91 𥲑 (<CJK Ideograph Extension B>) 2250 0x4240 䉀 (<CJK Ideograph Extension A>) 2251 0x25CC0 𥳀 (<CJK Ideograph Extension B>) 2252 0x4543 䕃 (<CJK Ideograph Extension A>) 2253 0x8534 蔴 (<CJK Ideograph>) 2254 0x5AF2 嫲 (<CJK Ideograph>) 2255 0x26E99 𦺙 (<CJK Ideograph Extension B>) 2256 0x4527 䔧 (<CJK Ideograph Extension A>) 2257 0x8573 蕳 (<CJK Ideograph>) 2258 0x4516 䔖 (<CJK Ideograph Extension A>) 2259 0x67BF 枿 (<CJK Ideograph>) 2260 0x8616 蘖 (<CJK Ideograph>) 2261 0x28625 𨘥 (<CJK Ideograph Extension B>) 2262 0x2863B 𨘻 (<CJK Ideograph Extension B>) 2263 0x85C1 藁 (<CJK Ideograph>) 2264 0x27088 𧂈 (<CJK Ideograph Extension B>) 2265 0x8602 蘂 (<CJK Ideograph>) 2266 0x21582 𡖂 (<CJK Ideograph Extension B>) 2267 0x270CD 𧃍 (<CJK Ideograph Extension B>) 2268 0x2F9B2 䕫 (CJK COMPATIBILITY IDEOGRAPH-2F9B2) 2269 0x456A 䕪 (<CJK Ideograph Extension A>) 2270 0x8628 蘨 (<CJK Ideograph>) 2271 0x3648 㙈 (<CJK Ideograph Extension A>) 2272 0x218A2 𡢢 (<CJK Ideograph Extension B>) 2273 0x53F7 号 (<CJK Ideograph>) 2274 0x2739A 𧎚 (<CJK Ideograph Extension B>) 2275 0x867E 虾 (<CJK Ideograph>) 2276 0x8771 蝱 (<CJK Ideograph>) 2277 0x2A0F8 𪃸 (<CJK Ideograph Extension B>) 2278 0x87EE 蟮 (<CJK Ideograph>) 2279 0x22C27 𢰧 (<CJK Ideograph Extension B>) 2280 0x87B1 螱 (<CJK Ideograph>) 2281 0x87DA 蟚 (<CJK Ideograph>) 2282 0x880F 蠏 (<CJK Ideograph>) 2283 0x5661 噡 (<CJK Ideograph>) 2284 0x866C 虬 (<CJK Ideograph>) 2285 0x6856 桖 (<CJK Ideograph>) 2286 0x460F 䘏 (<CJK Ideograph Extension A>) 2287 0x8845 衅 (<CJK Ideograph>) 2288 0x8846 衆 (<CJK Ideograph>) 2289 0x275E0 𧗠 (<CJK Ideograph Extension B>) 2290 0x23DB9 𣶹 (<CJK Ideograph Extension B>) 2291 0x275E4 𧗤 (<CJK Ideograph Extension B>) 2292 0x885E 衞 (<CJK Ideograph>) 2293 0x889C 袜 (<CJK Ideograph>) 2294 0x465B 䙛 (<CJK Ideograph Extension A>) 2295 0x88B4 袴 (<CJK Ideograph>) 2296 0x88B5 袵 (<CJK Ideograph>) 2297 0x63C1 揁 (<CJK Ideograph>) 2298 0x88C5 装 (<CJK Ideograph>) 2299 0x7777 睷 (<CJK Ideograph>) 2300 0x2770F 𧜏 (<CJK Ideograph Extension B>) 2301 0x8987 覇 (<CJK Ideograph>) 2302 0x898A 覊 (<CJK Ideograph>) 2303 0x89A6 覦 (<CJK Ideograph>) 2304 0x89A9 覩 (<CJK Ideograph>) 2305 0x89A7 覧 (<CJK Ideograph>) 2306 0x89BC 覼 (<CJK Ideograph>) 2307 0x28A25 𨨥 (<CJK Ideograph Extension B>) 2308 0x89E7 觧 (<CJK Ideograph>) 2309 0x27924 𧤤 (<CJK Ideograph Extension B>) 2310 0x27ABD 𧪽 (<CJK Ideograph Extension B>) 2311 0x8A9C 誜 (<CJK Ideograph>) 2312 0x7793 瞓 (<CJK Ideograph>) 2313 0x91FE 釾 (<CJK Ideograph>) 2314 0x8A90 誐 (<CJK Ideograph>) 2315 0x27A59 𧩙 (<CJK Ideograph Extension B>) 2316 0x7AE9 竩 (<CJK Ideograph>) 2317 0x27B3A 𧬺 (<CJK Ideograph Extension B>) 2318 0x23F8F 𣾏 (<CJK Ideograph Extension B>) 2319 0x4713 䜓 (<CJK Ideograph Extension A>) 2320 0x27B38 𧬸 (<CJK Ideograph Extension B>) 2321 0x717C 煼 (<CJK Ideograph>) 2322 0x8B0C 謌 (<CJK Ideograph>) 2323 0x8B1F 謟 (<CJK Ideograph>) 2324 0x25430 𥐰 (<CJK Ideograph Extension B>) 2325 0x25565 𥕥 (<CJK Ideograph Extension B>) 2326 0x8B3F 謿 (<CJK Ideograph>) 2327 0x8B4C 譌 (<CJK Ideograph>) 2328 0x8B4D 譍 (<CJK Ideograph>) 2329 0x8AA9 誩 (<CJK Ideograph>) 2330 0x24A7A 𤩺 (<CJK Ideograph Extension B>) 2331 0x8B90 讐 (<CJK Ideograph>) 2332 0x8B9B 讛 (<CJK Ideograph>) 2333 0x8AAF 誯 (<CJK Ideograph>) 2334 0x216DF 𡛟 (<CJK Ideograph Extension B>) 2335 0x4615 䘕 (<CJK Ideograph Extension A>) 2336 0x884F 衏 (<CJK Ideograph>) 2337 0x8C9B 貛 (<CJK Ideograph>) 2338 0x27D54 𧵔 (<CJK Ideograph Extension B>) 2339 0x27D8F 𧶏 (<CJK Ideograph Extension B>) 2340 0x2F9D4 貫 (CJK COMPATIBILITY IDEOGRAPH-2F9D4) 2341 0x3725 㜥 (<CJK Ideograph Extension A>) 2342 0x27D53 𧵓 (<CJK Ideograph Extension B>) 2343 0x8CD6 賖 (<CJK Ideograph>) 2344 0x27D98 𧶘 (<CJK Ideograph Extension B>) 2345 0x27DBD 𧶽 (<CJK Ideograph Extension B>) 2346 0x8D12 贒 (<CJK Ideograph>) 2347 0x8D03 贃 (<CJK Ideograph>) 2348 0x21910 𡤐 (<CJK Ideograph Extension B>) 2349 0x8CDB 賛 (<CJK Ideograph>) 2350 0x705C 灜 (<CJK Ideograph>) 2351 0x8D11 贑 (<CJK Ideograph>) 2352 0x24CC9 𤳉 (<CJK Ideograph Extension B>) 2353 0x3ED0 㻐 (<CJK Ideograph Extension A>) 2354 0x8D77 起 (<CJK Ideograph>) 2355 0x8DA9 趩 (<CJK Ideograph>) 2356 0x28002 𨀂 (<CJK Ideograph Extension B>) 2357 0x21014 𡀔 (<CJK Ideograph Extension B>) 2358 0x2498A 𤦊 (<CJK Ideograph Extension B>) 2359 0x3B7C 㭼 (<CJK Ideograph Extension A>) 2360 0x281BC 𨆼 (<CJK Ideograph Extension B>) 2361 0x2710C 𧄌 (<CJK Ideograph Extension B>) 2362 0x7AE7 竧 (<CJK Ideograph>) 2363 0x8EAD 躭 (<CJK Ideograph>) 2364 0x8EB6 躶 (<CJK Ideograph>) 2365 0x8EC3 軃 (<CJK Ideograph>) 2366 0x92D4 鋔 (<CJK Ideograph>) 2367 0x8F19 輙 (<CJK Ideograph>) 2368 0x8F2D 輭 (<CJK Ideograph>) 2369 0x28365 𨍥 (<CJK Ideograph Extension B>) 2370 0x28412 𨐒 (<CJK Ideograph Extension B>) 2371 0x8FA5 辥 (<CJK Ideograph>) 2372 0x9303 錃 (<CJK Ideograph>) 2373 0x2A29F 𪊟 (<CJK Ideograph Extension B>) 2374 0x20A50 𠩐 (<CJK Ideograph Extension B>) 2375 0x8FB3 辳 (<CJK Ideograph>) 2376 0x492A 䤪 (<CJK Ideograph Extension A>) 2377 0x289DE 𨧞 (<CJK Ideograph Extension B>) 2378 0x2853D 𨔽 (<CJK Ideograph Extension B>) 2379 0x23DBB 𣶻 (<CJK Ideograph Extension B>) 2380 0x5EF8 廸 (<CJK Ideograph>) 2381 0x23262 𣉢 (<CJK Ideograph Extension B>) 2382 0x8FF9 迹 (<CJK Ideograph>) 2383 0x2A014 𪀔 (<CJK Ideograph Extension B>) 2384 0x286BC 𨚼 (<CJK Ideograph Extension B>) 2385 0x28501 𨔁 (<CJK Ideograph Extension B>) 2386 0x22325 𢌥 (<CJK Ideograph Extension B>) 2387 0x3980 㦀 (<CJK Ideograph Extension A>) 2388 0x26ED7 𦻗 (<CJK Ideograph Extension B>) 2389 0x9037 逷 (<CJK Ideograph>) 2390 0x2853C 𨔼 (<CJK Ideograph Extension B>) 2391 0x27ABE 𧪾 (<CJK Ideograph Extension B>) 2392 0x9061 遡 (<CJK Ideograph>) 2393 0x2856C 𨕬 (<CJK Ideograph Extension B>) 2394 0x2860B 𨘋 (<CJK Ideograph Extension B>) 2395 0x90A8 邨 (<CJK Ideograph>) 2396 0x28713 𨜓 (<CJK Ideograph Extension B>) 2397 0x90C4 郄 (<CJK Ideograph>) 2398 0x286E6 𨛦 (<CJK Ideograph Extension B>) 2399 0x90AE 邮 (<CJK Ideograph>) 2400 0x90FD 都 (<CJK Ideograph>) 2401 0x9167 酧 (<CJK Ideograph>) 2402 0x3AF0 㫰 (<CJK Ideograph Extension A>) 2403 0x91A9 醩 (<CJK Ideograph>) 2404 0x91C4 釄 (<CJK Ideograph>) 2405 0x7CAC 粬 (<CJK Ideograph>) 2406 0x28933 𨤳 (<CJK Ideograph Extension B>) 2407 0x21E89 𡺉 (<CJK Ideograph Extension B>) 2408 0x920E 鈎 (<CJK Ideograph>) 2409 0x6C9F 沟 (<CJK Ideograph>) 2410 0x9241 鉁 (<CJK Ideograph>) 2411 0x9262 鉢 (<CJK Ideograph>) 2412 0x255B9 𥖹 (<CJK Ideograph Extension B>) 2413 0x92B9 銹 (<CJK Ideograph>) 2414 0x28AC6 𨫆 (<CJK Ideograph Extension B>) 2415 0x23C9B 𣲛 (<CJK Ideograph Extension B>) 2416 0x28B0C 𨬌 (<CJK Ideograph Extension B>) 2417 0x255DB 𥗛 (<CJK Ideograph Extension B>) 2418 0x20D31 𠴱 (<CJK Ideograph Extension B>) 2419 0x932C 錬 (<CJK Ideograph>) 2420 0x936B 鍫 (<CJK Ideograph>) 2421 0x28AE1 𨫡 (<CJK Ideograph Extension B>) 2422 0x28BEB 𨯫 (<CJK Ideograph Extension B>) 2423 0x708F 炏 (<CJK Ideograph>) 2424 0x5AC3 嫃 (<CJK Ideograph>) 2425 0x28AE2 𨫢 (<CJK Ideograph Extension B>) 2426 0x28AE5 𨫥 (<CJK Ideograph Extension B>) 2427 0x4965 䥥 (<CJK Ideograph Extension A>) 2428 0x9244 鉄 (<CJK Ideograph>) 2429 0x28BEC 𨯬 (<CJK Ideograph Extension B>) 2430 0x28C39 𨰹 (<CJK Ideograph Extension B>) 2431 0x28BFF 𨯿 (<CJK Ideograph Extension B>) 2432 0x9373 鍳 (<CJK Ideograph>) 2433 0x945B 鑛 (<CJK Ideograph>) 2434 0x8EBC 躼 (<CJK Ideograph>) 2435 0x9585 閅 (<CJK Ideograph>) 2436 0x95A6 閦 (<CJK Ideograph>) 2437 0x9426 鐦 (<CJK Ideograph>) 2438 0x95A0 閠 (<CJK Ideograph>) 2439 0x6FF6 濶 (<CJK Ideograph>) 2440 0x42B9 䊹 (<CJK Ideograph Extension A>) 2441 0x2267A 𢙺 (<CJK Ideograph Extension B>) 2442 0x286D8 𨛘 (<CJK Ideograph Extension B>) 2443 0x2127C 𡉼 (<CJK Ideograph Extension B>) 2444 0x23E2E 𣸮 (<CJK Ideograph Extension B>) 2445 0x49DF 䧟 (<CJK Ideograph Extension A>) 2446 0x6C1C 氜 (<CJK Ideograph>) 2447 0x967B 陻 (<CJK Ideograph>) 2448 0x9696 隖 (<CJK Ideograph>) 2449 0x416C 䅬 (<CJK Ideograph Extension A>) 2450 0x96A3 隣 (<CJK Ideograph>) 2451 0x26ED5 𦻕 (<CJK Ideograph Extension B>) 2452 0x61DA 懚 (<CJK Ideograph>) 2453 0x96B6 隶 (<CJK Ideograph>) 2454 0x78F5 磵 (<CJK Ideograph>) 2455 0x28AE0 𨫠 (<CJK Ideograph Extension B>) 2456 0x96BD 隽 (<CJK Ideograph>) 2457 0x53CC 双 (<CJK Ideograph>) 2458 0x49A1 䦡 (<CJK Ideograph Extension A>) 2459 0x26CB8 𦲸 (<CJK Ideograph Extension B>) 2460 0x20274 𠉴 (<CJK Ideograph Extension B>) 2461 0x26410 𦐐 (<CJK Ideograph Extension B>) 2462 0x290AF 𩂯 (<CJK Ideograph Extension B>) 2463 0x290E5 𩃥 (<CJK Ideograph Extension B>) 2464 0x24AD1 𤫑 (<CJK Ideograph Extension B>) 2465 0x21915 𡤕 (<CJK Ideograph Extension B>) 2466 0x2330A 𣌊 (<CJK Ideograph Extension B>) 2467 0x9731 霱 (<CJK Ideograph>) 2468 0x8642 虂 (<CJK Ideograph>) 2469 0x9736 霶 (<CJK Ideograph>) 2470 0x4A0F 䨏 (<CJK Ideograph Extension A>) 2471 0x453D 䔽 (<CJK Ideograph Extension A>) 2472 0x4585 䖅 (<CJK Ideograph Extension A>) 2473 0x24AE9 𤫩 (<CJK Ideograph Extension B>) 2474 0x7075 灵 (<CJK Ideograph>) 2475 0x5B41 孁 (<CJK Ideograph>) 2476 0x971B 霛 (<CJK Ideograph>) 2477 0x975C 靜 (<CJK Ideograph>) 2478 0x291D5 𩇕 (<CJK Ideograph Extension B>) 2479 0x9757 靗 (<CJK Ideograph>) 2480 0x5B4A 孊 (<CJK Ideograph>) 2481 0x291EB 𩇫 (<CJK Ideograph Extension B>) 2482 0x975F 靟 (<CJK Ideograph>) 2483 0x9425 鐥 (<CJK Ideograph>) 2484 0x50D0 僐 (<CJK Ideograph>) 2485 0x230B7 𣂷 (<CJK Ideograph Extension B>) 2486 0x230BC 𣂼 (<CJK Ideograph Extension B>) 2487 0x9789 鞉 (<CJK Ideograph>) 2488 0x979F 鞟 (<CJK Ideograph>) 2489 0x97B1 鞱 (<CJK Ideograph>) 2490 0x97BE 鞾 (<CJK Ideograph>) 2491 0x97C0 韀 (<CJK Ideograph>) 2492 0x97D2 韒 (<CJK Ideograph>) 2493 0x97E0 韠 (<CJK Ideograph>) 2494 0x2546C 𥑬 (<CJK Ideograph Extension B>) 2495 0x97EE 韮 (<CJK Ideograph>) 2496 0x741C 琜 (<CJK Ideograph>) 2497 0x29433 𩐳 (<CJK Ideograph Extension B>) 2498 0x97FF 響 (<CJK Ideograph>) 2499 0x97F5 韵 (<CJK Ideograph>) 2500 0x2941D 𩐝 (<CJK Ideograph Extension B>) 2501 0x2797A 𧥺 (<CJK Ideograph Extension B>) 2502 0x4AD1 䫑 (<CJK Ideograph Extension A>) 2503 0x9834 頴 (<CJK Ideograph>) 2504 0x9833 頳 (<CJK Ideograph>) 2505 0x984B 顋 (<CJK Ideograph>) 2506 0x9866 顦 (<CJK Ideograph>) 2507 0x3B0E 㬎 (<CJK Ideograph Extension A>) 2508 0x27175 𧅵 (<CJK Ideograph Extension B>) 2509 0x3D51 㵑 (<CJK Ideograph Extension A>) 2510 0x20630 𠘰 (<CJK Ideograph Extension B>) 2511 0x2415C 𤅜 (<CJK Ideograph Extension B>) 2512 0x25706 𥜆 (<CJK Ideograph Extension B>) 2513 0x98CA 飊 (<CJK Ideograph>) 2514 0x98B7 颷 (<CJK Ideograph>) 2515 0x98C8 飈 (<CJK Ideograph>) 2516 0x98C7 飇 (<CJK Ideograph>) 2517 0x4AFF 䫿 (<CJK Ideograph Extension A>) 2518 0x26D27 𦴧 (<CJK Ideograph Extension B>) 2519 0x216D3 𡛓 (<CJK Ideograph Extension B>) 2520 0x55B0 喰 (<CJK Ideograph>) 2521 0x98E1 飡 (<CJK Ideograph>) 2522 0x98E6 飦 (<CJK Ideograph>) 2523 0x98EC 飬 (<CJK Ideograph>) 2524 0x9378 鍸 (<CJK Ideograph>) 2525 0x9939 餹 (<CJK Ideograph>) 2526 0x24A29 𤨩 (<CJK Ideograph Extension B>) 2527 0x4B72 䭲 (<CJK Ideograph Extension A>) 2528 0x29857 𩡗 (<CJK Ideograph Extension B>) 2529 0x29905 𩤅 (<CJK Ideograph Extension B>) 2530 0x99F5 駵 (<CJK Ideograph>) 2531 0x9A0C 騌 (<CJK Ideograph>) 2532 0x9A3B 騻 (<CJK Ideograph>) 2533 0x9A10 騐 (<CJK Ideograph>) 2534 0x9A58 驘 (<CJK Ideograph>) 2535 0x25725 𥜥 (<CJK Ideograph Extension B>) 2536 0x36C4 㛄 (<CJK Ideograph Extension A>) 2537 0x290B1 𩂱 (<CJK Ideograph Extension B>) 2538 0x29BD5 𩯕 (<CJK Ideograph Extension B>) 2539 0x9AE0 髠 (<CJK Ideograph>) 2540 0x9AE2 髢 (<CJK Ideograph>) 2541 0x29B05 𩬅 (<CJK Ideograph Extension B>) 2542 0x9AF4 髴 (<CJK Ideograph>) 2543 0x4C0E 䰎 (<CJK Ideograph Extension A>) 2544 0x9B14 鬔 (<CJK Ideograph>) 2545 0x9B2D 鬭 (<CJK Ideograph>) 2546 0x28600 𨘀 (<CJK Ideograph Extension B>) 2547 0x5034 倴 (<CJK Ideograph>) 2548 0x9B34 鬴 (<CJK Ideograph>) 2549 0x269A8 𦦨 (<CJK Ideograph Extension B>) 2550 0x38C3 㣃 (<CJK Ideograph Extension A>) 2551 0x2307D 𣁽 (<CJK Ideograph Extension B>) 2552 0x9B50 魐 (<CJK Ideograph>) 2553 0x9B40 魀 (<CJK Ideograph>) 2554 0x29D3E 𩴾 (<CJK Ideograph Extension B>) 2555 0x5A45 婅 (<CJK Ideograph>) 2556 0x21863 𡡣 (<CJK Ideograph Extension B>) 2557 0x9B8E 鮎 (<CJK Ideograph>) 2558 0x2424B 𤉋 (<CJK Ideograph Extension B>) 2559 0x9C02 鰂 (<CJK Ideograph>) 2560 0x9BFF 鯿 (<CJK Ideograph>) 2561 0x9C0C 鰌 (<CJK Ideograph>) 2562 0x29E68 𩹨 (<CJK Ideograph Extension B>) 2563 0x9DD4 鷔 (<CJK Ideograph>) 2564 0x29FB7 𩾷 (<CJK Ideograph Extension B>) 2565 0x2A192 𪆒 (<CJK Ideograph Extension B>) 2566 0x2A1AB 𪆫 (<CJK Ideograph Extension B>) 2567 0x2A0E1 𪃡 (<CJK Ideograph Extension B>) 2568 0x2A123 𪄣 (<CJK Ideograph Extension B>) 2569 0x2A1DF 𪇟 (<CJK Ideograph Extension B>) 2570 0x9D7E 鵾 (<CJK Ideograph>) 2571 0x9D83 鶃 (<CJK Ideograph>) 2572 0x2A134 𪄴 (<CJK Ideograph Extension B>) 2573 0x9E0E 鸎 (<CJK Ideograph>) 2574 0x6888 梈 (<CJK Ideograph>) 2575 0x9DC4 鷄 (<CJK Ideograph>) 2576 0x2215B 𢅛 (<CJK Ideograph Extension B>) 2577 0x2A193 𪆓 (<CJK Ideograph Extension B>) 2578 0x2A220 𪈠 (<CJK Ideograph Extension B>) 2579 0x2193B 𡤻 (<CJK Ideograph Extension B>) 2580 0x2A233 𪈳 (<CJK Ideograph Extension B>) 2581 0x9D39 鴹 (<CJK Ideograph>) 2582 0x2A0B9 𪂹 (<CJK Ideograph Extension B>) 2583 0x2A2B4 𪊴 (<CJK Ideograph Extension B>) 2584 0x9E90 麐 (<CJK Ideograph>) 2585 0x9E95 麕 (<CJK Ideograph>) 2586 0x9E9E 麞 (<CJK Ideograph>) 2587 0x9EA2 麢 (<CJK Ideograph>) 2588 0x4D34 䴴 (<CJK Ideograph Extension A>) 2589 0x9EAA 麪 (<CJK Ideograph>) 2590 0x9EAF 麯 (<CJK Ideograph>) 2591 0x24364 𤍤 (<CJK Ideograph Extension B>) 2592 0x9EC1 黁 (<CJK Ideograph>) 2593 0x3B60 㭠 (<CJK Ideograph Extension A>) 2594 0x39E5 㧥 (<CJK Ideograph Extension A>) 2595 0x3D1D 㴝 (<CJK Ideograph Extension A>) 2596 0x4F32 伲 (<CJK Ideograph>) 2597 0x37BE 㞾 (<CJK Ideograph Extension A>) 2598 0x28C2B 𨰫 (<CJK Ideograph Extension B>) 2599 0x9F02 鼂 (<CJK Ideograph>) 2600 0x9F08 鼈 (<CJK Ideograph>) 2601 0x4B96 䮖 (<CJK Ideograph Extension A>) 2602 0x9424 鐤 (<CJK Ideograph>) 2603 0x26DA2 𦶢 (<CJK Ideograph Extension B>) 2604 0x9F17 鼗 (<CJK Ideograph>) 2605 0x9F16 鼖 (<CJK Ideograph>) 2606 0x9F39 鼹 (<CJK Ideograph>) 2607 0x569F 嚟 (<CJK Ideograph>) 2608 0x568A 嚊 (<CJK Ideograph>) 2609 0x9F45 齅 (<CJK Ideograph>) 2610 0x99B8 馸 (<CJK Ideograph>) 2611 0x2908B 𩂋 (<CJK Ideograph Extension B>) 2612 0x97F2 韲 (<CJK Ideograph>) 2613 0x847F 葿 (<CJK Ideograph>) 2614 0x9F62 齢 (<CJK Ideograph>) 2615 0x9F69 齩 (<CJK Ideograph>) 2616 0x7ADC 竜 (<CJK Ideograph>) 2617 0x9F8E 龎 (<CJK Ideograph>) 2618 0x7216 爖 (<CJK Ideograph>) 2619 0x4BBE 䮾 (<CJK Ideograph Extension A>) 2620 0x24975 𤥵 (<CJK Ideograph Extension B>) 2621 0x249BB 𤦻 (<CJK Ideograph Extension B>) 2622 0x7177 煷 (<CJK Ideograph>) 2623 0x249F8 𤧸 (<CJK Ideograph Extension B>) 2624 0x24348 𤍈 (<CJK Ideograph Extension B>) 2625 0x24A51 𤩑 (<CJK Ideograph Extension B>) 2626 0x739E 玞 (<CJK Ideograph>) 2627 0x28BDA 𨯚 (<CJK Ideograph Extension B>) 2628 0x218FA 𡣺 (<CJK Ideograph Extension B>) 2629 0x799F 禟 (<CJK Ideograph>) 2630 0x2897E 𨥾 (<CJK Ideograph Extension B>) 2631 0x28E36 𨸶 (<CJK Ideograph Extension B>) 2632 0x9369 鍩 (<CJK Ideograph>) 2633 0x93F3 鏳 (<CJK Ideograph>) 2634 0x28A44 𨩄 (<CJK Ideograph Extension B>) 2635 0x92EC 鋬 (<CJK Ideograph>) 2636 0x9381 鎁 (<CJK Ideograph>) 2637 0x93CB 鏋 (<CJK Ideograph>) 2638 0x2896C 𨥬 (<CJK Ideograph Extension B>) 2639 0x244B9 𤒹 (<CJK Ideograph Extension B>) 2640 0x7217 爗 (<CJK Ideograph>) 2641 0x3EEB 㻫 (<CJK Ideograph Extension A>) 2642 0x7772 睲 (<CJK Ideograph>) 2643 0x7A43 穃 (<CJK Ideograph>) 2644 0x70D0 烐 (<CJK Ideograph>) 2645 0x24473 𤑳 (<CJK Ideograph Extension B>) 2646 0x243F8 𤏸 (<CJK Ideograph Extension B>) 2647 0x717E 煾 (<CJK Ideograph>) 2648 0x217EF 𡟯 (<CJK Ideograph Extension B>) 2649 0x70A3 炣 (<CJK Ideograph>) 2650 0x218BE 𡢾 (<CJK Ideograph Extension B>) 2651 0x23599 𣖙 (<CJK Ideograph Extension B>) 2652 0x3EC7 㻇 (<CJK Ideograph Extension A>) 2653 0x21885 𡢅 (<CJK Ideograph Extension B>) 2654 0x2542F 𥐯 (<CJK Ideograph Extension B>) 2655 0x217F8 𡟸 (<CJK Ideograph Extension B>) 2656 0x3722 㜢 (<CJK Ideograph Extension A>) 2657 0x216FB 𡛻 (<CJK Ideograph Extension B>) 2658 0x21839 𡠹 (<CJK Ideograph Extension B>) 2659 0x36E1 㛡 (<CJK Ideograph Extension A>) 2660 0x21774 𡝴 (<CJK Ideograph Extension B>) 2661 0x218D1 𡣑 (<CJK Ideograph Extension B>) 2662 0x25F4B 𥽋 (<CJK Ideograph Extension B>) 2663 0x3723 㜣 (<CJK Ideograph Extension A>) 2664 0x216C0 𡛀 (<CJK Ideograph Extension B>) 2665 0x575B 坛 (<CJK Ideograph>) 2666 0x24A25 𤨥 (<CJK Ideograph Extension B>) 2667 0x213FE 𡏾 (<CJK Ideograph Extension B>) 2668 0x212A8 𡊨 (<CJK Ideograph Extension B>) 2669 0x213C6 𡏆 (<CJK Ideograph Extension B>) 2670 0x214B6 𡒶 (<CJK Ideograph Extension B>) 2671 0x8503 蔃 (<CJK Ideograph>) 2672 0x236A6 𣚦 (<CJK Ideograph Extension B>) 2673 0x8503 蔃 (<CJK Ideograph>) 2674 0x8455 葕 (<CJK Ideograph>) 2675 0x24994 𤦔 (<CJK Ideograph Extension B>) 2676 0x27165 𧅥 (<CJK Ideograph Extension B>) 2677 0x23E31 𣸱 (<CJK Ideograph Extension B>) 2678 0x2555C 𥕜 (<CJK Ideograph Extension B>) 2679 0x23EFB 𣻻 (<CJK Ideograph Extension B>) 2680 0x27052 𧁒 (<CJK Ideograph Extension B>) 2681 0x44F4 䓴 (<CJK Ideograph Extension A>) 2682 0x236EE 𣛮 (<CJK Ideograph Extension B>) 2683 0x2999D 𩦝 (<CJK Ideograph Extension B>) 2684 0x26F26 𦼦 (<CJK Ideograph Extension B>) 2685 0x67F9 柹 (<CJK Ideograph>) 2686 0x3733 㜳 (<CJK Ideograph Extension A>) 2687 0x3C15 㰕 (<CJK Ideograph Extension A>) 2688 0x3DE7 㷧 (<CJK Ideograph Extension A>) 2689 0x586C 塬 (<CJK Ideograph>) 2690 0x21922 𡤢 (<CJK Ideograph Extension B>) 2691 0x6810 栐 (<CJK Ideograph>) 2692 0x4057 䁗 (<CJK Ideograph Extension A>) 2693 0x2373F 𣜿 (<CJK Ideograph Extension B>) 2694 0x240E1 𤃡 (<CJK Ideograph Extension B>) 2695 0x2408B 𤂋 (<CJK Ideograph Extension B>) 2696 0x2410F 𤄏 (<CJK Ideograph Extension B>) 2697 0x26C21 𦰡 (<CJK Ideograph Extension B>) 2698 0x54CB 哋 (<CJK Ideograph>) 2699 0x569E 嚞 (<CJK Ideograph>) 2700 0x266B1 𦚱 (<CJK Ideograph Extension B>) 2701 0x5692 嚒 (<CJK Ideograph>) 2702 0x20FDF 𠿟 (<CJK Ideograph Extension B>) 2703 0x20BA8 𠮨 (<CJK Ideograph Extension B>) 2704 0x20E0D 𠸍 (<CJK Ideograph Extension B>) 2705 0x93C6 鏆 (<CJK Ideograph>) 2706 0x28B13 𨬓 (<CJK Ideograph Extension B>) 2707 0x939C 鎜 (<CJK Ideograph>) 2708 0x4EF8 仸 (<CJK Ideograph>) 2709 0x512B 儫 (<CJK Ideograph>) 2710 0x3819 㠙 (<CJK Ideograph Extension A>) 2711 0x24436 𤐶 (<CJK Ideograph Extension B>) 2712 0x4EBC 亼 (<CJK Ideograph>) 2713 0x20465 𠑥 (<CJK Ideograph Extension B>) 2714 0x2037F 𠍿 (<CJK Ideograph Extension B>) 2715 0x4F4B 佋 (<CJK Ideograph>) 2716 0x4F8A 侊 (<CJK Ideograph>) 2717 0x25651 𥙑 (<CJK Ideograph Extension B>) 2718 0x5A68 婨 (<CJK Ideograph>) 2719 0x201AB 𠆫 (<CJK Ideograph Extension B>) 2720 0x203CB 𠏋 (<CJK Ideograph Extension B>) 2721 0x3999 㦙 (<CJK Ideograph Extension A>) 2722 0x2030A 𠌊 (<CJK Ideograph Extension B>) 2723 0x20414 𠐔 (<CJK Ideograph Extension B>) 2724 0x3435 㐵 (<CJK Ideograph Extension A>) 2725 0x4F29 伩 (<CJK Ideograph>) 2726 0x202C0 𠋀 (<CJK Ideograph Extension B>) 2727 0x28EB3 𨺳 (<CJK Ideograph Extension B>) 2728 0x20275 𠉵 (<CJK Ideograph Extension B>) 2729 0x8ADA 諚 (<CJK Ideograph>) 2730 0x2020C 𠈌 (<CJK Ideograph Extension B>) 2731 0x4E98 亘 (<CJK Ideograph>) 2732 0x50CD 働 (<CJK Ideograph>) 2733 0x510D 儍 (<CJK Ideograph>) 2734 0x4FA2 侢 (<CJK Ideograph>) 2735 0x4F03 伃 (<CJK Ideograph>) 2736 0x24A0E 𤨎 (<CJK Ideograph Extension B>) 2737 0x23E8A 𣺊 (<CJK Ideograph Extension B>) 2738 0x4F42 佂 (<CJK Ideograph>) 2739 0x502E 倮 (<CJK Ideograph>) 2740 0x506C 偬 (<CJK Ideograph>) 2741 0x5081 傁 (<CJK Ideograph>) 2742 0x4FCC 俌 (<CJK Ideograph>) 2743 0x4FE5 俥 (<CJK Ideograph>) 2744 0x5058 偘 (<CJK Ideograph>) 2745 0x50FC 僼 (<CJK Ideograph>) 2746 0x5159 兙 (<CJK Ideograph>) 2747 0x515B 兛 (<CJK Ideograph>) 2748 0x515D 兝 (<CJK Ideograph>) 2749 0x515E 兞 (<CJK Ideograph>) 2750 0x6E76 湶 (<CJK Ideograph>) 2751 0x23595 𣖕 (<CJK Ideograph Extension B>) 2752 0x23E39 𣸹 (<CJK Ideograph Extension B>) 2753 0x23EBF 𣺿 (<CJK Ideograph Extension B>) 2754 0x6D72 浲 (<CJK Ideograph>) 2755 0x21884 𡢄 (<CJK Ideograph Extension B>) 2756 0x23E89 𣺉 (<CJK Ideograph Extension B>) 2757 0x51A8 冨 (<CJK Ideograph>) 2758 0x51C3 凃 (<CJK Ideograph>) 2759 0x205E0 𠗠 (<CJK Ideograph Extension B>) 2760 0x44DD 䓝 (<CJK Ideograph Extension A>) 2761 0x204A3 𠒣 (<CJK Ideograph Extension B>) 2762 0x20492 𠒒 (<CJK Ideograph Extension B>) 2763 0x20491 𠒑 (<CJK Ideograph Extension B>) 2764 0x8D7A 赺 (<CJK Ideograph>) 2765 0x28A9C 𨪜 (<CJK Ideograph Extension B>) 2766 0x2070E 𠜎 (<CJK Ideograph Extension B>) 2767 0x5259 剙 (<CJK Ideograph>) 2768 0x52A4 劤 (<CJK Ideograph>) 2769 0x20873 𠡳 (<CJK Ideograph Extension B>) 2770 0x52E1 勡 (<CJK Ideograph>) 2771 0x936E 鍮 (<CJK Ideograph>) 2772 0x467A 䙺 (<CJK Ideograph Extension A>) 2773 0x718C 熌 (<CJK Ideograph>) 2774 0x2438C 𤎌 (<CJK Ideograph Extension B>) 2775 0x20C20 𠰠 (<CJK Ideograph Extension B>) 2776 0x249AC 𤦬 (<CJK Ideograph Extension B>) 2777 0x210E4 𡃤 (<CJK Ideograph Extension B>) 2778 0x69D1 槑 (<CJK Ideograph>) 2779 0x20E1D 𠸝 (<CJK Ideograph Extension B>) 2780 0x7479 瑹 (<CJK Ideograph>) 2781 0x3EDE 㻞 (<CJK Ideograph Extension A>) 2782 0x7499 璙 (<CJK Ideograph>) 2783 0x7414 琔 (<CJK Ideograph>) 2784 0x7456 瑖 (<CJK Ideograph>) 2785 0x7398 玘 (<CJK Ideograph>) 2786 0x4B8E 䮎 (<CJK Ideograph Extension A>) 2787 0x24ABC 𤪼 (<CJK Ideograph Extension B>) 2788 0x2408D 𤂍 (<CJK Ideograph Extension B>) 2789 0x53D0 叐 (<CJK Ideograph>) 2790 0x3584 㖄 (<CJK Ideograph Extension A>) 2791 0x720F 爏 (<CJK Ideograph>) 2792 0x240C9 𤃉 (<CJK Ideograph Extension B>) 2793 0x55B4 喴 (<CJK Ideograph>) 2794 0x20345 𠍅 (<CJK Ideograph Extension B>) 2795 0x54CD 响 (<CJK Ideograph>) 2796 0x20BC6 𠯆 (<CJK Ideograph Extension B>) 2797 0x571D 圝 (<CJK Ideograph>) 2798 0x925D 鉝 (<CJK Ideograph>) 2799 0x96F4 雴 (<CJK Ideograph>) 2800 0x9366 鍦 (<CJK Ideograph>) 2801 0x57DD 埝 (<CJK Ideograph>) 2802 0x578D 垍 (<CJK Ideograph>) 2803 0x577F 坿 (<CJK Ideograph>) 2804 0x363E 㘾 (<CJK Ideograph Extension A>) 2805 0x58CB 壋 (<CJK Ideograph>) 2806 0x5A99 媙 (<CJK Ideograph>) 2807 0x28A46 𨩆 (<CJK Ideograph Extension B>) 2808 0x216FA 𡛺 (<CJK Ideograph Extension B>) 2809 0x2176F 𡝯 (<CJK Ideograph Extension B>) 2810 0x21710 𡜐 (<CJK Ideograph Extension B>) 2811 0x5A2C 娬 (<CJK Ideograph>) 2812 0x59B8 妸 (<CJK Ideograph>) 2813 0x928F 銏 (<CJK Ideograph>) 2814 0x5A7E 婾 (<CJK Ideograph>) 2815 0x5ACF 嫏 (<CJK Ideograph>) 2816 0x5A12 娒 (<CJK Ideograph>) 2817 0x25946 𥥆 (<CJK Ideograph Extension B>) 2818 0x219F3 𡧳 (<CJK Ideograph Extension B>) 2819 0x21861 𡡡 (<CJK Ideograph Extension B>) 2820 0x24295 𤊕 (<CJK Ideograph Extension B>) 2821 0x36F5 㛵 (<CJK Ideograph Extension A>) 2822 0x6D05 洅 (<CJK Ideograph>) 2823 0x7443 瑃 (<CJK Ideograph>) 2824 0x5A21 娡 (<CJK Ideograph>) 2825 0x25E83 𥺃 (<CJK Ideograph Extension B>) 2826 0x5A81 媁 (<CJK Ideograph>) 2827 0x28BD7 𨯗 (<CJK Ideograph Extension B>) 2828 0x20413 𠐓 (<CJK Ideograph Extension B>) 2829 0x93E0 鏠 (<CJK Ideograph>) 2830 0x748C 璌 (<CJK Ideograph>) 2831 0x21303 𡌃 (<CJK Ideograph Extension B>) 2832 0x7105 焅 (<CJK Ideograph>) 2833 0x4972 䥲 (<CJK Ideograph Extension A>) 2834 0x9408 鐈 (<CJK Ideograph>) 2835 0x289FB 𨧻 (<CJK Ideograph Extension B>) 2836 0x93BD 鎽 (<CJK Ideograph>) 2837 0x37A0 㞠 (<CJK Ideograph Extension A>) 2838 0x5C1E 尞 (<CJK Ideograph>) 2839 0x5C9E 岞 (<CJK Ideograph>) 2840 0x5E5E 幞 (<CJK Ideograph>) 2841 0x5E48 幈 (<CJK Ideograph>) 2842 0x21996 𡦖 (<CJK Ideograph Extension B>) 2843 0x2197C 𡥼 (<CJK Ideograph Extension B>) 2844 0x23AEE 𣫮 (<CJK Ideograph Extension B>) 2845 0x5ECD 廍 (<CJK Ideograph>) 2846 0x5B4F 孏 (<CJK Ideograph>) 2847 0x21903 𡤃 (<CJK Ideograph Extension B>) 2848 0x21904 𡤄 (<CJK Ideograph Extension B>) 2849 0x3701 㜁 (<CJK Ideograph Extension A>) 2850 0x218A0 𡢠 (<CJK Ideograph Extension B>) 2851 0x36DD 㛝 (<CJK Ideograph Extension A>) 2852 0x216FE 𡛾 (<CJK Ideograph Extension B>) 2853 0x36D3 㛓 (<CJK Ideograph Extension A>) 2854 0x812A 脪 (<CJK Ideograph>) 2855 0x28A47 𨩇 (<CJK Ideograph Extension B>) 2856 0x21DBA 𡶺 (<CJK Ideograph Extension B>) 2857 0x23472 𣑲 (<CJK Ideograph Extension B>) 2858 0x289A8 𨦨 (<CJK Ideograph Extension B>) 2859 0x5F0C 弌 (<CJK Ideograph>) 2860 0x5F0E 弎 (<CJK Ideograph>) 2861 0x21927 𡤧 (<CJK Ideograph Extension B>) 2862 0x217AB 𡞫 (<CJK Ideograph Extension B>) 2863 0x5A6B 婫 (<CJK Ideograph>) 2864 0x2173B 𡜻 (<CJK Ideograph Extension B>) 2865 0x5B44 孄 (<CJK Ideograph>) 2866 0x8614 蘔 (<CJK Ideograph>) 2867 0x275FD 𧗽 (<CJK Ideograph Extension B>) 2868 0x8860 衠 (<CJK Ideograph>) 2869 0x607E 恾 (<CJK Ideograph>) 2870 0x22860 𢡠 (<CJK Ideograph Extension B>) 2871 0x2262B 𢘫 (<CJK Ideograph Extension B>) 2872 0x5FDB 忛 (<CJK Ideograph>) 2873 0x3EB8 㺸 (<CJK Ideograph Extension A>) 2874 0x225AF 𢖯 (<CJK Ideograph Extension B>) 2875 0x225BE 𢖾 (<CJK Ideograph Extension B>) 2876 0x29088 𩂈 (<CJK Ideograph Extension B>) 2877 0x26F73 𦽳 (<CJK Ideograph Extension B>) 2878 0x61C0 懀 (<CJK Ideograph>) 2879 0x2003E 𠀾 (<CJK Ideograph Extension B>) 2880 0x20046 𠁆 (<CJK Ideograph Extension B>) 2881 0x2261B 𢘛 (<CJK Ideograph Extension B>) 2882 0x6199 憙 (<CJK Ideograph>) 2883 0x6198 憘 (<CJK Ideograph>) 2884 0x6075 恵 (<CJK Ideograph>) 2885 0x22C9B 𢲛 (<CJK Ideograph Extension B>) 2886 0x22D07 𢴇 (<CJK Ideograph Extension B>) 2887 0x246D4 𤛔 (<CJK Ideograph Extension B>) 2888 0x2914D 𩅍 (<CJK Ideograph Extension B>) 2889 0x6471 摱 (<CJK Ideograph>) 2890 0x24665 𤙥 (<CJK Ideograph Extension B>) 2891 0x22B6A 𢭪 (<CJK Ideograph Extension B>) 2892 0x3A29 㨩 (<CJK Ideograph Extension A>) 2893 0x22B22 𢬢 (<CJK Ideograph Extension B>) 2894 0x23450 𣑐 (<CJK Ideograph Extension B>) 2895 0x298EA 𩣪 (<CJK Ideograph Extension B>) 2896 0x22E78 𢹸 (<CJK Ideograph Extension B>) 2897 0x6337 挷 (<CJK Ideograph>) 2898 0x2A45B 𪑛 (<CJK Ideograph Extension B>) 2899 0x64B6 撶 (<CJK Ideograph>) 2900 0x6331 挱 (<CJK Ideograph>) 2901 0x63D1 揑 (<CJK Ideograph>) 2902 0x249E3 𤧣 (<CJK Ideograph Extension B>) 2903 0x22D67 𢵧 (<CJK Ideograph Extension B>) 2904 0x62A4 护 (<CJK Ideograph>) 2905 0x22CA1 𢲡 (<CJK Ideograph Extension B>) 2906 0x643B 搻 (<CJK Ideograph>) 2907 0x656B 敫 (<CJK Ideograph>) 2908 0x6972 楲 (<CJK Ideograph>) 2909 0x3BF4 㯴 (<CJK Ideograph Extension A>) 2910 0x2308E 𣂎 (<CJK Ideograph Extension B>) 2911 0x232AD 𣊭 (<CJK Ideograph Extension B>) 2912 0x24989 𤦉 (<CJK Ideograph Extension B>) 2913 0x232AB 𣊫 (<CJK Ideograph Extension B>) 2914 0x550D 唍 (<CJK Ideograph>) 2915 0x232E0 𣋠 (<CJK Ideograph Extension B>) 2916 0x218D9 𡣙 (<CJK Ideograph Extension B>) 2917 0x2943F 𩐿 (<CJK Ideograph Extension B>) 2918 0x66CE 曎 (<CJK Ideograph>) 2919 0x23289 𣊉 (<CJK Ideograph Extension B>) 2920 0x231B3 𣆳 (<CJK Ideograph Extension B>) 2921 0x3AE0 㫠 (<CJK Ideograph Extension A>) 2922 0x4190 䆐 (<CJK Ideograph Extension A>) 2923 0x25584 𥖄 (<CJK Ideograph Extension B>) 2924 0x28B22 𨬢 (<CJK Ideograph Extension B>) 2925 0x2558F 𥖏 (<CJK Ideograph Extension B>) 2926 0x216FC 𡛼 (<CJK Ideograph Extension B>) 2927 0x2555B 𥕛 (<CJK Ideograph Extension B>) 2928 0x25425 𥐥 (<CJK Ideograph Extension B>) 2929 0x78EE 磮 (<CJK Ideograph>) 2930 0x23103 𣄃 (<CJK Ideograph Extension B>) 2931 0x2182A 𡠪 (<CJK Ideograph Extension B>) 2932 0x23234 𣈴 (<CJK Ideograph Extension B>) 2933 0x3464 㑤 (<CJK Ideograph Extension A>) 2934 0x2320F 𣈏 (<CJK Ideograph Extension B>) 2935 0x23182 𣆂 (<CJK Ideograph Extension B>) 2936 0x242C9 𤋉 (<CJK Ideograph Extension B>) 2937 0x668E 暎 (<CJK Ideograph>) 2938 0x26D24 𦴤 (<CJK Ideograph Extension B>) 2939 0x666B 晫 (<CJK Ideograph>) 2940 0x4B93 䮓 (<CJK Ideograph Extension A>) 2941 0x6630 昰 (<CJK Ideograph>) 2942 0x27870 𧡰 (<CJK Ideograph Extension B>) 2943 0x21DEB 𡷫 (<CJK Ideograph Extension B>) 2944 0x6663 晣 (<CJK Ideograph>) 2945 0x232D2 𣋒 (<CJK Ideograph Extension B>) 2946 0x232E1 𣋡 (<CJK Ideograph Extension B>) 2947 0x661E 昞 (<CJK Ideograph>) 2948 0x25872 𥡲 (<CJK Ideograph Extension B>) 2949 0x38D1 㣑 (<CJK Ideograph Extension A>) 2950 0x2383A 𣠺 (<CJK Ideograph Extension B>) 2951 0x237BC 𣞼 (<CJK Ideograph Extension B>) 2952 0x3B99 㮙 (<CJK Ideograph Extension A>) 2953 0x237A2 𣞢 (<CJK Ideograph Extension B>) 2954 0x233FE 𣏾 (<CJK Ideograph Extension B>) 2955 0x74D0 瓐 (<CJK Ideograph>) 2956 0x3B96 㮖 (<CJK Ideograph Extension A>) 2957 0x678F 枏 (<CJK Ideograph>) 2958 0x2462A 𤘪 (<CJK Ideograph Extension B>) 2959 0x68B6 梶 (<CJK Ideograph>) 2960 0x681E 栞 (<CJK Ideograph>) 2961 0x3BC4 㯄 (<CJK Ideograph Extension A>) 2962 0x6ABE 檾 (<CJK Ideograph>) 2963 0x3863 㡣 (<CJK Ideograph Extension A>) 2964 0x237D5 𣟕 (<CJK Ideograph Extension B>) 2965 0x24487 𤒇 (<CJK Ideograph Extension B>) 2966 0x6A33 樳 (<CJK Ideograph>) 2967 0x6A52 橒 (<CJK Ideograph>) 2968 0x6AC9 櫉 (<CJK Ideograph>) 2969 0x6B05 欅 (<CJK Ideograph>) 2970 0x21912 𡤒 (<CJK Ideograph Extension B>) 2971 0x6511 攑 (<CJK Ideograph>) 2972 0x6898 梘 (<CJK Ideograph>) 2973 0x6A4C 橌 (<CJK Ideograph>) 2974 0x3BD7 㯗 (<CJK Ideograph Extension A>) 2975 0x6A7A 橺 (<CJK Ideograph>) 2976 0x6B57 歗 (<CJK Ideograph>) 2977 0x23FC0 𣿀 (<CJK Ideograph Extension B>) 2978 0x23C9A 𣲚 (<CJK Ideograph Extension B>) 2979 0x93A0 鎠 (<CJK Ideograph>) 2980 0x92F2 鋲 (<CJK Ideograph>) 2981 0x28BEA 𨯪 (<CJK Ideograph Extension B>) 2982 0x28ACB 𨫋 (<CJK Ideograph Extension B>) 2983 0x9289 銉 (<CJK Ideograph>) 2984 0x2801E 𨀞 (<CJK Ideograph Extension B>) 2985 0x289DC 𨧜 (<CJK Ideograph Extension B>) 2986 0x9467 鑧 (<CJK Ideograph>) 2987 0x6DA5 涥 (<CJK Ideograph>) 2988 0x6F0B 漋 (<CJK Ideograph>) 2989 0x249EC 𤧬 (<CJK Ideograph Extension B>) 2990 0x6D67 浧 (<CJK Ideograph>) 2991 0x23F7F 𣽿 (<CJK Ideograph Extension B>) 2992 0x3D8F 㶏 (<CJK Ideograph Extension A>) 2993 0x6E04 渄 (<CJK Ideograph>) 2994 0x2403C 𤀼 (<CJK Ideograph Extension B>) 2995 0x5A3D 娽 (<CJK Ideograph>) 2996 0x6E0A 渊 (<CJK Ideograph>) 2997 0x5847 塇 (<CJK Ideograph>) 2998 0x6D24 洤 (<CJK Ideograph>) 2999 0x7842 硂 (<CJK Ideograph>) 3000 0x713B 焻 (<CJK Ideograph>) 3001 0x2431A 𤌚 (<CJK Ideograph Extension B>) 3002 0x24276 𤉶 (<CJK Ideograph Extension B>) 3003 0x70F1 烱 (<CJK Ideograph>) 3004 0x7250 牐 (<CJK Ideograph>) 3005 0x7287 犇 (<CJK Ideograph>) 3006 0x7294 犔 (<CJK Ideograph>) 3007 0x2478F 𤞏 (<CJK Ideograph Extension B>) 3008 0x24725 𤜥 (<CJK Ideograph Extension B>) 3009 0x5179 兹 (<CJK Ideograph>) 3010 0x24AA4 𤪤 (<CJK Ideograph Extension B>) 3011 0x205EB 𠗫 (<CJK Ideograph Extension B>) 3012 0x747A 瑺 (<CJK Ideograph>) 3013 0x23EF8 𣻸 (<CJK Ideograph Extension B>) 3014 0x2365F 𣙟 (<CJK Ideograph Extension B>) 3015 0x24A4A 𤩊 (<CJK Ideograph Extension B>) 3016 0x24917 𤤗 (<CJK Ideograph Extension B>) 3017 0x25FE1 𥿡 (<CJK Ideograph Extension B>) 3018 0x3F06 㼆 (<CJK Ideograph Extension A>) 3019 0x3EB1 㺱 (<CJK Ideograph Extension A>) 3020 0x24ADF 𤫟 (<CJK Ideograph Extension B>) 3021 0x28C23 𨰣 (<CJK Ideograph Extension B>) 3022 0x23F35 𣼵 (<CJK Ideograph Extension B>) 3023 0x60A7 悧 (<CJK Ideograph>) 3024 0x3EF3 㻳 (<CJK Ideograph Extension A>) 3025 0x74CC 瓌 (<CJK Ideograph>) 3026 0x743C 琼 (<CJK Ideograph>) 3027 0x9387 鎇 (<CJK Ideograph>) 3028 0x7437 琷 (<CJK Ideograph>) 3029 0x449F 䒟 (<CJK Ideograph Extension A>) 3030 0x26DEA 𦷪 (<CJK Ideograph Extension B>) 3031 0x4551 䕑 (<CJK Ideograph Extension A>) 3032 0x7583 疃 (<CJK Ideograph>) 3033 0x3F63 㽣 (<CJK Ideograph Extension A>) 3034 0x24CD9 𤳙 (<CJK Ideograph Extension B>) 3035 0x24D06 𤴆 (<CJK Ideograph Extension B>) 3036 0x3F58 㽘 (<CJK Ideograph Extension A>) 3037 0x7555 畕 (<CJK Ideograph>) 3038 0x7673 癳 (<CJK Ideograph>) 3039 0x2A5C6 𪗆 (<CJK Ideograph Extension B>) 3040 0x3B19 㬙 (<CJK Ideograph Extension A>) 3041 0x7468 瑨 (<CJK Ideograph>) 3042 0x28ACC 𨫌 (<CJK Ideograph Extension B>) 3043 0x249AB 𤦫 (<CJK Ideograph Extension B>) 3044 0x2498E 𤦎 (<CJK Ideograph Extension B>) 3045 0x3AFB 㫻 (<CJK Ideograph Extension A>) 3046 0x3DCD 㷍 (<CJK Ideograph Extension A>) 3047 0x24A4E 𤩎 (<CJK Ideograph Extension B>) 3048 0x3EFF 㻿 (<CJK Ideograph Extension A>) 3049 0x249C5 𤧅 (<CJK Ideograph Extension B>) 3050 0x248F3 𤣳 (<CJK Ideograph Extension B>) 3051 0x91FA 釺 (<CJK Ideograph>) 3052 0x5732 圲 (<CJK Ideograph>) 3053 0x9342 鍂 (<CJK Ideograph>) 3054 0x28AE3 𨫣 (<CJK Ideograph Extension B>) 3055 0x21864 𡡤 (<CJK Ideograph Extension B>) 3056 0x50DF 僟 (<CJK Ideograph>) 3057 0x25221 𥈡 (<CJK Ideograph Extension B>) 3058 0x251E7 𥇧 (<CJK Ideograph Extension B>) 3059 0x7778 睸 (<CJK Ideograph>) 3060 0x23232 𣈲 (<CJK Ideograph Extension B>) 3061 0x770E 眎 (<CJK Ideograph>) 3062 0x770F 眏 (<CJK Ideograph>) 3063 0x777B 睻 (<CJK Ideograph>) 3064 0x24697 𤚗 (<CJK Ideograph Extension B>) 3065 0x23781 𣞁 (<CJK Ideograph Extension B>) 3066 0x3A5E 㩞 (<CJK Ideograph Extension A>) 3067 0x248F0 𤣰 (<CJK Ideograph Extension B>) 3068 0x7438 琸 (<CJK Ideograph>) 3069 0x749B 璛 (<CJK Ideograph>) 3070 0x3EBF 㺿 (<CJK Ideograph Extension A>) 3071 0x24ABA 𤪺 (<CJK Ideograph Extension B>) 3072 0x24AC7 𤫇 (<CJK Ideograph Extension B>) 3073 0x40C8 䃈 (<CJK Ideograph Extension A>) 3074 0x24A96 𤪖 (<CJK Ideograph Extension B>) 3075 0x261AE 𦆮 (<CJK Ideograph Extension B>) 3076 0x9307 錇 (<CJK Ideograph>) 3077 0x25581 𥖁 (<CJK Ideograph Extension B>) 3078 0x781E 砞 (<CJK Ideograph>) 3079 0x788D 碍 (<CJK Ideograph>) 3080 0x7888 碈 (<CJK Ideograph>) 3081 0x78D2 磒 (<CJK Ideograph>) 3082 0x73D0 珐 (<CJK Ideograph>) 3083 0x7959 祙 (<CJK Ideograph>) 3084 0x27741 𧝁 (<CJK Ideograph Extension B>) 3085 0x256E3 𥛣 (<CJK Ideograph Extension B>) 3086 0x410E 䄎 (<CJK Ideograph Extension A>) 3087 0x799B 禛 (<CJK Ideograph>) 3088 0x8496 蒖 (<CJK Ideograph>) 3089 0x79A5 禥 (<CJK Ideograph>) 3090 0x6A2D 樭 (<CJK Ideograph>) 3091 0x23EFA 𣻺 (<CJK Ideograph Extension B>) 3092 0x7A3A 稺 (<CJK Ideograph>) 3093 0x79F4 秴 (<CJK Ideograph>) 3094 0x416E 䅮 (<CJK Ideograph Extension A>) 3095 0x216E6 𡛦 (<CJK Ideograph Extension B>) 3096 0x4132 䄲 (<CJK Ideograph Extension A>) 3097 0x9235 鈵 (<CJK Ideograph>) 3098 0x79F1 秱 (<CJK Ideograph>) 3099 0x20D4C 𠵌 (<CJK Ideograph Extension B>) 3100 0x2498C 𤦌 (<CJK Ideograph Extension B>) 3101 0x20299 𠊙 (<CJK Ideograph Extension B>) 3102 0x23DBA 𣶺 (<CJK Ideograph Extension B>) 3103 0x2176E 𡝮 (<CJK Ideograph Extension B>) 3104 0x3597 㖗 (<CJK Ideograph Extension A>) 3105 0x556B 啫 (<CJK Ideograph>) 3106 0x3570 㕰 (<CJK Ideograph Extension A>) 3107 0x36AA 㚪 (<CJK Ideograph Extension A>) 3108 0x201D4 𠇔 (<CJK Ideograph Extension B>) 3109 0x20C0D 𠰍 (<CJK Ideograph Extension B>) 3110 0x7AE2 竢 (<CJK Ideograph>) 3111 0x5A59 婙 (<CJK Ideograph>) 3112 0x226F5 𢛵 (<CJK Ideograph Extension B>) 3113 0x25AAF 𥪯 (<CJK Ideograph Extension B>) 3114 0x25A9C 𥪜 (<CJK Ideograph Extension B>) 3115 0x5A0D 娍 (<CJK Ideograph>) 3116 0x2025B 𠉛 (<CJK Ideograph Extension B>) 3117 0x78F0 磰 (<CJK Ideograph>) 3118 0x5A2A 娪 (<CJK Ideograph>) 3119 0x25BC6 𥯆 (<CJK Ideograph Extension B>) 3120 0x7AFE 竾 (<CJK Ideograph>) 3121 0x41F9 䇹 (<CJK Ideograph Extension A>) 3122 0x7C5D 籝 (<CJK Ideograph>) 3123 0x7C6D 籭 (<CJK Ideograph>) 3124 0x4211 䈑 (<CJK Ideograph Extension A>) 3125 0x25BB3 𥮳 (<CJK Ideograph Extension B>) 3126 0x25EBC 𥺼 (<CJK Ideograph Extension B>) 3127 0x25EA6 𥺦 (<CJK Ideograph Extension B>) 3128 0x7CCD 糍 (<CJK Ideograph>) 3129 0x249F9 𤧹 (<CJK Ideograph Extension B>) 3130 0x217B0 𡞰 (<CJK Ideograph Extension B>) 3131 0x7C8E 粎 (<CJK Ideograph>) 3132 0x7C7C 籼 (<CJK Ideograph>) 3133 0x7CAE 粮 (<CJK Ideograph>) 3134 0x6AB2 檲 (<CJK Ideograph>) 3135 0x7DDC 緜 (<CJK Ideograph>) 3136 0x7E07 縇 (<CJK Ideograph>) 3137 0x7DD3 緓 (<CJK Ideograph>) 3138 0x7F4E 罎 (<CJK Ideograph>) 3139 0x26261 𦉡 (<CJK Ideograph Extension B>) 3140 0x2615C 𦅜 (<CJK Ideograph Extension B>) 3141 0x27B48 𧭈 (<CJK Ideograph Extension B>) 3142 0x7D97 綗 (<CJK Ideograph>) 3143 0x25E82 𥺂 (<CJK Ideograph Extension B>) 3144 0x426A 䉪 (<CJK Ideograph Extension A>) 3145 0x26B75 𦭵 (<CJK Ideograph Extension B>) 3146 0x20916 𠤖 (<CJK Ideograph Extension B>) 3147 0x67D6 柖 (<CJK Ideograph>) 3148 0x2004E 𠁎 (<CJK Ideograph Extension B>) 3149 0x235CF 𣗏 (<CJK Ideograph Extension B>) 3150 0x57C4 埄 (<CJK Ideograph>) 3151 0x26412 𦐒 (<CJK Ideograph Extension B>) 3152 0x263F8 𦏸 (<CJK Ideograph Extension B>) 3153 0x24962 𤥢 (<CJK Ideograph Extension B>) 3154 0x7FDD 翝 (<CJK Ideograph>) 3155 0x7B27 笧 (<CJK Ideograph>) 3156 0x2082C 𠠬 (<CJK Ideograph Extension B>) 3157 0x25AE9 𥫩 (<CJK Ideograph Extension B>) 3158 0x25D43 𥵃 (<CJK Ideograph Extension B>) 3159 0x7B0C 笌 (<CJK Ideograph>) 3160 0x25E0E 𥸎 (<CJK Ideograph Extension B>) 3161 0x99E6 駦 (<CJK Ideograph>) 3162 0x8645 虅 (<CJK Ideograph>) 3163 0x9A63 驣 (<CJK Ideograph>) 3164 0x6A1C 樜 (<CJK Ideograph>) 3165 0x2343F 𣐿 (<CJK Ideograph Extension B>) 3166 0x39E2 㧢 (<CJK Ideograph Extension A>) 3167 0x249F7 𤧷 (<CJK Ideograph Extension B>) 3168 0x265AD 𦖭 (<CJK Ideograph Extension B>) 3169 0x9A1F 騟 (<CJK Ideograph>) 3170 0x265A0 𦖠 (<CJK Ideograph Extension B>) 3171 0x8480 蒀 (<CJK Ideograph>) 3172 0x27127 𧄧 (<CJK Ideograph Extension B>) 3173 0x26CD1 𦳑 (<CJK Ideograph Extension B>) 3174 0x44EA 䓪 (<CJK Ideograph Extension A>) 3175 0x8137 脷 (<CJK Ideograph>) 3176 0x4402 䐂 (<CJK Ideograph Extension A>) 3177 0x80C6 胆 (<CJK Ideograph>) 3178 0x8109 脉 (<CJK Ideograph>) 3179 0x8142 腂 (<CJK Ideograph>) 3180 0x267B4 𦞴 (<CJK Ideograph Extension B>) 3181 0x98C3 飃 (<CJK Ideograph>) 3182 0x26A42 𦩂 (<CJK Ideograph Extension B>) 3183 0x8262 艢 (<CJK Ideograph>) 3184 0x8265 艥 (<CJK Ideograph>) 3185 0x26A51 𦩑 (<CJK Ideograph Extension B>) 3186 0x8453 葓 (<CJK Ideograph>) 3187 0x26DA7 𦶧 (<CJK Ideograph Extension B>) 3188 0x8610 蘐 (<CJK Ideograph>) 3189 0x2721B 𧈛 (<CJK Ideograph Extension B>) 3190 0x5A86 媆 (<CJK Ideograph>) 3191 0x417F 䅿 (<CJK Ideograph Extension A>) 3192 0x21840 𡡀 (<CJK Ideograph Extension B>) 3193 0x5B2B 嬫 (<CJK Ideograph>) 3194 0x218A1 𡢡 (<CJK Ideograph Extension B>) 3195 0x5AE4 嫤 (<CJK Ideograph>) 3196 0x218D8 𡣘 (<CJK Ideograph Extension B>) 3197 0x86A0 蚠 (<CJK Ideograph>) 3198 0x2F9BC 蜨 (CJK COMPATIBILITY IDEOGRAPH-2F9BC) 3199 0x23D8F 𣶏 (<CJK Ideograph Extension B>) 3200 0x882D 蠭 (<CJK Ideograph>) 3201 0x27422 𧐢 (<CJK Ideograph Extension B>) 3202 0x5A02 娂 (<CJK Ideograph>) 3203 0x886E 衮 (<CJK Ideograph>) 3204 0x4F45 佅 (<CJK Ideograph>) 3205 0x8887 袇 (<CJK Ideograph>) 3206 0x88BF 袿 (<CJK Ideograph>) 3207 0x88E6 裦 (<CJK Ideograph>) 3208 0x8965 襥 (<CJK Ideograph>) 3209 0x894D 襍 (<CJK Ideograph>) 3210 0x25683 𥚃 (<CJK Ideograph Extension B>) 3211 0x8954 襔 (<CJK Ideograph>) 3212 0x27785 𧞅 (<CJK Ideograph Extension B>) 3213 0x27784 𧞄 (<CJK Ideograph Extension B>) 3214 0x28BF5 𨯵 (<CJK Ideograph Extension B>) 3215 0x28BD9 𨯙 (<CJK Ideograph Extension B>) 3216 0x28B9C 𨮜 (<CJK Ideograph Extension B>) 3217 0x289F9 𨧹 (<CJK Ideograph Extension B>) 3218 0x3EAD 㺭 (<CJK Ideograph Extension A>) 3219 0x84A3 蒣 (<CJK Ideograph>) 3220 0x46F5 䛵 (<CJK Ideograph Extension A>) 3221 0x46CF 䛏 (<CJK Ideograph Extension A>) 3222 0x37F2 㟲 (<CJK Ideograph Extension A>) 3223 0x8A3D 訽 (<CJK Ideograph>) 3224 0x8A1C 訜 (<CJK Ideograph>) 3225 0x29448 𩑈 (<CJK Ideograph Extension B>) 3226 0x5F4D 彍 (<CJK Ideograph>) 3227 0x922B 鈫 (<CJK Ideograph>) 3228 0x24284 𤊄 (<CJK Ideograph Extension B>) 3229 0x65D4 旔 (<CJK Ideograph>) 3230 0x7129 焩 (<CJK Ideograph>) 3231 0x70C4 烄 (<CJK Ideograph>) 3232 0x21845 𡡅 (<CJK Ideograph Extension B>) 3233 0x9D6D 鵭 (<CJK Ideograph>) 3234 0x8C9F 貟 (<CJK Ideograph>) 3235 0x8CE9 賩 (<CJK Ideograph>) 3236 0x27DDC 𧷜 (<CJK Ideograph Extension B>) 3237 0x599A 妚 (<CJK Ideograph>) 3238 0x77C3 矃 (<CJK Ideograph>) 3239 0x59F0 姰 (<CJK Ideograph>) 3240 0x436E 䍮 (<CJK Ideograph Extension A>) 3241 0x36D4 㛔 (<CJK Ideograph Extension A>) 3242 0x8E2A 踪 (<CJK Ideograph>) 3243 0x8EA7 躧 (<CJK Ideograph>) 3244 0x24C09 𤰉 (<CJK Ideograph Extension B>) 3245 0x8F30 輰 (<CJK Ideograph>) 3246 0x8F4A 轊 (<CJK Ideograph>) 3247 0x42F4 䋴 (<CJK Ideograph Extension A>) 3248 0x6C58 汘 (<CJK Ideograph>) 3249 0x6FBB 澻 (<CJK Ideograph>) 3250 0x22321 𢌡 (<CJK Ideograph Extension B>) 3251 0x489B 䢛 (<CJK Ideograph Extension A>) 3252 0x6F79 潹 (<CJK Ideograph>) 3253 0x6E8B 溋 (<CJK Ideograph>) 3254 0x217DA 𡟚 (<CJK Ideograph Extension B>) 3255 0x9BE9 鯩 (<CJK Ideograph>) 3256 0x36B5 㚵 (<CJK Ideograph Extension A>) 3257 0x2492F 𤤯 (<CJK Ideograph Extension B>) 3258 0x90BB 邻 (<CJK Ideograph>) 3259 0x9097 邗 (<CJK Ideograph>) 3260 0x5571 啱 (<CJK Ideograph>) 3261 0x4906 䤆 (<CJK Ideograph Extension A>) 3262 0x91BB 醻 (<CJK Ideograph>) 3263 0x9404 鐄 (<CJK Ideograph>) 3264 0x28A4B 𨩋 (<CJK Ideograph Extension B>) 3265 0x4062 䁢 (<CJK Ideograph Extension A>) 3266 0x28AFC 𨫼 (<CJK Ideograph Extension B>) 3267 0x9427 鐧 (<CJK Ideograph>) 3268 0x28C1D 𨰝 (<CJK Ideograph Extension B>) 3269 0x28C3B 𨰻 (<CJK Ideograph Extension B>) 3270 0x84E5 蓥 (<CJK Ideograph>) 3271 0x8A2B 訫 (<CJK Ideograph>) 3272 0x9599 閙 (<CJK Ideograph>) 3273 0x95A7 閧 (<CJK Ideograph>) 3274 0x9597 閗 (<CJK Ideograph>) 3275 0x9596 閖 (<CJK Ideograph>) 3276 0x28D34 𨴴 (<CJK Ideograph Extension B>) 3277 0x7445 瑅 (<CJK Ideograph>) 3278 0x3EC2 㻂 (<CJK Ideograph Extension A>) 3279 0x248FF 𤣿 (<CJK Ideograph Extension B>) 3280 0x24A42 𤩂 (<CJK Ideograph Extension B>) 3281 0x243EA 𤏪 (<CJK Ideograph Extension B>) 3282 0x3EE7 㻧 (<CJK Ideograph Extension A>) 3283 0x23225 𣈥 (<CJK Ideograph Extension B>) 3284 0x968F 随 (<CJK Ideograph>) 3285 0x28EE7 𨻧 (<CJK Ideograph Extension B>) 3286 0x28E66 𨹦 (<CJK Ideograph Extension B>) 3287 0x28E65 𨹥 (<CJK Ideograph Extension B>) 3288 0x3ECC 㻌 (<CJK Ideograph Extension A>) 3289 0x249ED 𤧭 (<CJK Ideograph Extension B>) 3290 0x24A78 𤩸 (<CJK Ideograph Extension B>) 3291 0x23FEE 𣿮 (<CJK Ideograph Extension B>) 3292 0x7412 琒 (<CJK Ideograph>) 3293 0x746B 瑫 (<CJK Ideograph>) 3294 0x3EFC 㻼 (<CJK Ideograph Extension A>) 3295 0x9741 靁 (<CJK Ideograph>) 3296 0x290B0 𩂰 (<CJK Ideograph Extension B>) 3297 0x6847 桇 (<CJK Ideograph>) 3298 0x4A1D 䨝 (<CJK Ideograph Extension A>) 3299 0x29093 𩂓 (<CJK Ideograph Extension B>) 3300 0x257DF 𥟟 (<CJK Ideograph Extension B>) 3301 0x975D 靝 (<CJK Ideograph>) 3302 0x9368 鍨 (<CJK Ideograph>) 3303 0x28989 𨦉 (<CJK Ideograph Extension B>) 3304 0x28C26 𨰦 (<CJK Ideograph Extension B>) 3305 0x28B2F 𨬯 (<CJK Ideograph Extension B>) 3306 0x263BE 𦎾 (<CJK Ideograph Extension B>) 3307 0x92BA 銺 (<CJK Ideograph>) 3308 0x5B11 嬑 (<CJK Ideograph>) 3309 0x8B69 譩 (<CJK Ideograph>) 3310 0x493C 䤼 (<CJK Ideograph Extension A>) 3311 0x73F9 珹 (<CJK Ideograph>) 3312 0x2421B 𤈛 (<CJK Ideograph Extension B>) 3313 0x979B 鞛 (<CJK Ideograph>) 3314 0x9771 靱 (<CJK Ideograph>) 3315 0x9938 餸 (<CJK Ideograph>) 3316 0x20F26 𠼦 (<CJK Ideograph Extension B>) 3317 0x5DC1 巁 (<CJK Ideograph>) 3318 0x28BC5 𨯅 (<CJK Ideograph Extension B>) 3319 0x24AB2 𤪲 (<CJK Ideograph Extension B>) 3320 0x981F 頟 (<CJK Ideograph>) 3321 0x294DA 𩓚 (<CJK Ideograph Extension B>) 3322 0x92F6 鋶 (<CJK Ideograph>) 3323 0x295D7 𩗗 (<CJK Ideograph Extension B>) 3324 0x91E5 釥 (<CJK Ideograph>) 3325 0x44C0 䓀 (<CJK Ideograph Extension A>) 3326 0x28B50 𨭐 (<CJK Ideograph Extension B>) 3327 0x24A67 𤩧 (<CJK Ideograph Extension B>) 3328 0x28B64 𨭤 (<CJK Ideograph Extension B>) 3329 0x98DC 飜 (<CJK Ideograph>) 3330 0x28A45 𨩅 (<CJK Ideograph Extension B>) 3331 0x3F00 㼀 (<CJK Ideograph Extension A>) 3332 0x922A 鈪 (<CJK Ideograph>) 3333 0x4925 䤥 (<CJK Ideograph Extension A>) 3334 0x8414 萔 (<CJK Ideograph>) 3335 0x993B 餻 (<CJK Ideograph>) 3336 0x994D 饍 (<CJK Ideograph>) 3337 0x27B06 𧬆 (<CJK Ideograph Extension B>) 3338 0x3DFD 㷽 (<CJK Ideograph Extension A>) 3339 0x999B 馛 (<CJK Ideograph>) 3340 0x4B6F 䭯 (<CJK Ideograph Extension A>) 3341 0x99AA 馪 (<CJK Ideograph>) 3342 0x9A5C 驜 (<CJK Ideograph>) 3343 0x28B65 𨭥 (<CJK Ideograph Extension B>) 3344 0x258C8 𥣈 (<CJK Ideograph Extension B>) 3345 0x6A8F 檏 (<CJK Ideograph>) 3346 0x9A21 騡 (<CJK Ideograph>) 3347 0x5AFE 嫾 (<CJK Ideograph>) 3348 0x9A2F 騯 (<CJK Ideograph>) 3349 0x298F1 𩣱 (<CJK Ideograph Extension B>) 3350 0x4B90 䮐 (<CJK Ideograph Extension A>) 3351 0x29948 𩥈 (<CJK Ideograph Extension B>) 3352 0x99BC 馼 (<CJK Ideograph>) 3353 0x4BBD 䮽 (<CJK Ideograph Extension A>) 3354 0x4B97 䮗 (<CJK Ideograph Extension A>) 3355 0x937D 鍽 (<CJK Ideograph>) 3356 0x5872 塲 (<CJK Ideograph>) 3357 0x21302 𡌂 (<CJK Ideograph Extension B>) 3358 0x5822 堢 (<CJK Ideograph>) 3359 0x249B8 𤦸 (<CJK Ideograph Extension B>) 3360 0x214E8 𡓨 (<CJK Ideograph Extension B>) 3361 0x7844 硄 (<CJK Ideograph>) 3362 0x2271F 𢜟 (<CJK Ideograph Extension B>) 3363 0x23DB8 𣶸 (<CJK Ideograph Extension B>) 3364 0x68C5 棅 (<CJK Ideograph>) 3365 0x3D7D 㵽 (<CJK Ideograph Extension A>) 3366 0x9458 鑘 (<CJK Ideograph>) 3367 0x3927 㤧 (<CJK Ideograph Extension A>) 3368 0x6150 慐 (<CJK Ideograph>) 3369 0x22781 𢞁 (<CJK Ideograph Extension B>) 3370 0x2296B 𢥫 (<CJK Ideograph Extension B>) 3371 0x6107 愇 (<CJK Ideograph>) 3372 0x9C4F 鱏 (<CJK Ideograph>) 3373 0x9C53 鱓 (<CJK Ideograph>) 3374 0x9C7B 鱻 (<CJK Ideograph>) 3375 0x9C35 鰵 (<CJK Ideograph>) 3376 0x9C10 鰐 (<CJK Ideograph>) 3377 0x9B7F 魿 (<CJK Ideograph>) 3378 0x9BCF 鯏 (<CJK Ideograph>) 3379 0x29E2D 𩸭 (<CJK Ideograph Extension B>) 3380 0x9B9F 鮟 (<CJK Ideograph>) 3381 0x2A1F5 𪇵 (<CJK Ideograph Extension B>) 3382 0x2A0FE 𪃾 (<CJK Ideograph Extension B>) 3383 0x9D21 鴡 (<CJK Ideograph>) 3384 0x4CAE 䲮 (<CJK Ideograph Extension A>) 3385 0x24104 𤄄 (<CJK Ideograph Extension B>) 3386 0x9E18 鸘 (<CJK Ideograph>) 3387 0x4CB0 䲰 (<CJK Ideograph Extension A>) 3388 0x9D0C 鴌 (<CJK Ideograph>) 3389 0x2A1B4 𪆴 (<CJK Ideograph Extension B>) 3390 0x2A0ED 𪃭 (<CJK Ideograph Extension B>) 3391 0x2A0F3 𪃳 (<CJK Ideograph Extension B>) 3392 0x2992F 𩤯 (<CJK Ideograph Extension B>) 3393 0x9DA5 鶥 (<CJK Ideograph>) 3394 0x84BD 蒽 (<CJK Ideograph>) 3395 0x26E12 𦸒 (<CJK Ideograph Extension B>) 3396 0x26FDF 𦿟 (<CJK Ideograph Extension B>) 3397 0x26B82 𦮂 (<CJK Ideograph Extension B>) 3398 0x85FC 藼 (<CJK Ideograph>) 3399 0x4533 䔳 (<CJK Ideograph Extension A>) 3400 0x26DA4 𦶤 (<CJK Ideograph Extension B>) 3401 0x26E84 𦺄 (<CJK Ideograph Extension B>) 3402 0x26DF0 𦷰 (<CJK Ideograph Extension B>) 3403 0x8420 萠 (<CJK Ideograph>) 3404 0x85EE 藮 (<CJK Ideograph>) 3405 0x26E00 𦸀 (<CJK Ideograph Extension B>) 3406 0x237D7 𣟗 (<CJK Ideograph Extension B>) 3407 0x26064 𦁤 (<CJK Ideograph Extension B>) 3408 0x79E2 秢 (<CJK Ideograph>) 3409 0x2359C 𣖜 (<CJK Ideograph Extension B>) 3410 0x23640 𣙀 (<CJK Ideograph Extension B>) 3411 0x492D 䤭 (<CJK Ideograph Extension A>) 3412 0x249DE 𤧞 (<CJK Ideograph Extension B>) 3413 0x3D62 㵢 (<CJK Ideograph Extension A>) 3414 0x93DB 鏛 (<CJK Ideograph>) 3415 0x92BE 銾 (<CJK Ideograph>) 3416 0x9348 鍈 (<CJK Ideograph>) 3417 0x202BF 𠊿 (<CJK Ideograph Extension B>) 3418 0x78B9 碹 (<CJK Ideograph>) 3419 0x9277 鉷 (<CJK Ideograph>) 3420 0x944D 鑍 (<CJK Ideograph>) 3421 0x4FE4 俤 (<CJK Ideograph>) 3422 0x3440 㑀 (<CJK Ideograph Extension A>) 3423 0x9064 遤 (<CJK Ideograph>) 3424 0x2555D 𥕝 (<CJK Ideograph Extension B>) 3425 0x783D 砽 (<CJK Ideograph>) 3426 0x7854 硔 (<CJK Ideograph>) 3427 0x78B6 碶 (<CJK Ideograph>) 3428 0x784B 硋 (<CJK Ideograph>) 3429 0x21757 𡝗 (<CJK Ideograph Extension B>) 3430 0x231C9 𣇉 (<CJK Ideograph Extension B>) 3431 0x24941 𤥁 (<CJK Ideograph Extension B>) 3432 0x369A 㚚 (<CJK Ideograph Extension A>) 3433 0x4F72 佲 (<CJK Ideograph>) 3434 0x6FDA 濚 (<CJK Ideograph>) 3435 0x6FD9 濙 (<CJK Ideograph>) 3436 0x701E 瀞 (<CJK Ideograph>) 3437 0x701E 瀞 (<CJK Ideograph>) 3438 0x5414 吔 (<CJK Ideograph>) 3439 0x241B5 𤆵 (<CJK Ideograph Extension B>) 3440 0x57BB 垻 (<CJK Ideograph>) 3441 0x58F3 壳 (<CJK Ideograph>) 3442 0x578A 垊 (<CJK Ideograph>) 3443 0x9D16 鴖 (<CJK Ideograph>) 3444 0x57D7 埗 (<CJK Ideograph>) 3445 0x7134 焴 (<CJK Ideograph>) 3446 0x34AF 㒯 (<CJK Ideograph Extension A>) 3447 0x241AC 𤆬 (<CJK Ideograph Extension B>) 3448 0x71EB 燫 (<CJK Ideograph>) 3449 0x26C40 𦱀 (<CJK Ideograph Extension B>) 3450 0x24F97 𤾗 (<CJK Ideograph Extension B>) 3451 0x5B28 嬨 (<CJK Ideograph>) 3452 0x217B5 𡞵 (<CJK Ideograph Extension B>) 3453 0x28A49 𨩉 (<CJK Ideograph Extension B>) 3454 0x610C 愌 (<CJK Ideograph>) 3455 0x5ACE 嫎 (<CJK Ideograph>) 3456 0x5A0B 娋 (<CJK Ideograph>) 3457 0x42BC 䊼 (<CJK Ideograph Extension A>) 3458 0x24488 𤒈 (<CJK Ideograph Extension B>) 3459 0x372C 㜬 (<CJK Ideograph Extension A>) 3460 0x4B7B 䭻 (<CJK Ideograph Extension A>) 3461 0x289FC 𨧼 (<CJK Ideograph Extension B>) 3462 0x93BB 鎻 (<CJK Ideograph>) 3463 0x93B8 鎸 (<CJK Ideograph>) 3464 0x218D6 𡣖 (<CJK Ideograph Extension B>) 3465 0x20F1D 𠼝 (<CJK Ideograph Extension B>) 3466 0x8472 葲 (<CJK Ideograph>) 3467 0x26CC0 𦳀 (<CJK Ideograph Extension B>) 3468 0x21413 𡐓 (<CJK Ideograph Extension B>) 3469 0x242FA 𤋺 (<CJK Ideograph Extension B>) 3470 0x22C26 𢰦 (<CJK Ideograph Extension B>) 3471 0x243C1 𤏁 (<CJK Ideograph Extension B>) 3472 0x5994 妔 (<CJK Ideograph>) 3473 0x23DB7 𣶷 (<CJK Ideograph Extension B>) 3474 0x26741 𦝁 (<CJK Ideograph Extension B>) 3475 0x7DA8 綨 (<CJK Ideograph>) 3476 0x2615B 𦅛 (<CJK Ideograph Extension B>) 3477 0x260A4 𦂤 (<CJK Ideograph Extension B>) 3478 0x249B9 𤦹 (<CJK Ideograph Extension B>) 3479 0x2498B 𤦋 (<CJK Ideograph Extension B>) 3480 0x289FA 𨧺 (<CJK Ideograph Extension B>) 3481 0x92E5 鋥 (<CJK Ideograph>) 3482 0x73E2 珢 (<CJK Ideograph>) 3483 0x3EE9 㻩 (<CJK Ideograph Extension A>) 3484 0x74B4 璴 (<CJK Ideograph>) 3485 0x28B63 𨭣 (<CJK Ideograph Extension B>) 3486 0x2189F 𡢟 (<CJK Ideograph Extension B>) 3487 0x3EE1 㻡 (<CJK Ideograph Extension A>) 3488 0x24AB3 𤪳 (<CJK Ideograph Extension B>) 3489 0x6AD8 櫘 (<CJK Ideograph>) 3490 0x73F3 珳 (<CJK Ideograph>) 3491 0x73FB 珻 (<CJK Ideograph>) 3492 0x3ED6 㻖 (<CJK Ideograph Extension A>) 3493 0x24A3E 𤨾 (<CJK Ideograph Extension B>) 3494 0x24A94 𤪔 (<CJK Ideograph Extension B>) 3495 0x217D9 𡟙 (<CJK Ideograph Extension B>) 3496 0x24A66 𤩦 (<CJK Ideograph Extension B>) 3497 0x203A7 𠎧 (<CJK Ideograph Extension B>) 3498 0x21424 𡐤 (<CJK Ideograph Extension B>) 3499 0x249E5 𤧥 (<CJK Ideograph Extension B>) 3500 0x7448 瑈 (<CJK Ideograph>) 3501 0x24916 𤤖 (<CJK Ideograph Extension B>) 3502 0x70A5 炥 (<CJK Ideograph>) 3503 0x24976 𤥶 (<CJK Ideograph Extension B>) 3504 0x9284 銄 (<CJK Ideograph>) 3505 0x73E6 珦 (<CJK Ideograph>) 3506 0x935F 鍟 (<CJK Ideograph>) 3507 0x204FE 𠓾 (<CJK Ideograph Extension B>) 3508 0x9331 錱 (<CJK Ideograph>) 3509 0x28ACE 𨫎 (<CJK Ideograph Extension B>) 3510 0x28A16 𨨖 (<CJK Ideograph Extension B>) 3511 0x9386 鎆 (<CJK Ideograph>) 3512 0x28BE7 𨯧 (<CJK Ideograph Extension B>) 3513 0x255D5 𥗕 (<CJK Ideograph Extension B>) 3514 0x4935 䤵 (<CJK Ideograph Extension A>) 3515 0x28A82 𨪂 (<CJK Ideograph Extension B>) 3516 0x716B 煫 (<CJK Ideograph>) 3517 0x24943 𤥃 (<CJK Ideograph Extension B>) 3518 0x20CFF 𠳿 (<CJK Ideograph Extension B>) 3519 0x56A4 嚤 (<CJK Ideograph>) 3520 0x2061A 𠘚 (<CJK Ideograph Extension B>) 3521 0x20BEB 𠯫 (<CJK Ideograph Extension B>) 3522 0x20CB8 𠲸 (<CJK Ideograph Extension B>) 3523 0x5502 唂 (<CJK Ideograph>) 3524 0x79C4 秄 (<CJK Ideograph>) 3525 0x217FA 𡟺 (<CJK Ideograph Extension B>) 3526 0x7DFE 緾 (<CJK Ideograph>) 3527 0x216C2 𡛂 (<CJK Ideograph Extension B>) 3528 0x24A50 𤩐 (<CJK Ideograph Extension B>) 3529 0x21852 𡡒 (<CJK Ideograph Extension B>) 3530 0x452E 䔮 (<CJK Ideograph Extension A>) 3531 0x9401 鐁 (<CJK Ideograph>) 3532 0x370A 㜊 (<CJK Ideograph Extension A>) 3533 0x28AC0 𨫀 (<CJK Ideograph Extension B>) 3534 0x249AD 𤦭 (<CJK Ideograph Extension B>) 3535 0x59B0 妰 (<CJK Ideograph>) 3536 0x218BF 𡢿 (<CJK Ideograph Extension B>) 3537 0x21883 𡢃 (<CJK Ideograph Extension B>) 3538 0x27484 𧒄 (<CJK Ideograph Extension B>) 3539 0x5AA1 媡 (<CJK Ideograph>) 3540 0x36E2 㛢 (<CJK Ideograph Extension A>) 3541 0x23D5B 𣵛 (<CJK Ideograph Extension B>) 3542 0x36B0 㚰 (<CJK Ideograph Extension A>) 3543 0x925F 鉟 (<CJK Ideograph>) 3544 0x5A79 婹 (<CJK Ideograph>) 3545 0x28A81 𨪁 (<CJK Ideograph Extension B>) 3546 0x21862 𡡢 (<CJK Ideograph Extension B>) 3547 0x9374 鍴 (<CJK Ideograph>) 3548 0x3CCD 㳍 (<CJK Ideograph Extension A>) 3549 0x20AB4 𠪴 (<CJK Ideograph Extension B>) 3550 0x4A96 䪖 (<CJK Ideograph Extension A>) 3551 0x398A 㦊 (<CJK Ideograph Extension A>) 3552 0x50F4 僴 (<CJK Ideograph>) 3553 0x3D69 㵩 (<CJK Ideograph Extension A>) 3554 0x3D4C 㵌 (<CJK Ideograph Extension A>) 3555 0x2139C 𡎜 (<CJK Ideograph Extension B>) 3556 0x7175 煵 (<CJK Ideograph>) 3557 0x42FB 䋻 (<CJK Ideograph Extension A>) 3558 0x28218 𨈘 (<CJK Ideograph Extension B>) 3559 0x6E0F 渏 (<CJK Ideograph>) 3560 0x290E4 𩃤 (<CJK Ideograph Extension B>) 3561 0x44EB 䓫 (<CJK Ideograph Extension A>) 3562 0x6D57 浗 (<CJK Ideograph>) 3563 0x27E4F 𧹏 (<CJK Ideograph Extension B>) 3564 0x7067 灧 (<CJK Ideograph>) 3565 0x6CAF 沯 (<CJK Ideograph>) 3566 0x3CD6 㳖 (<CJK Ideograph Extension A>) 3567 0x23FED 𣿭 (<CJK Ideograph Extension B>) 3568 0x23E2D 𣸭 (<CJK Ideograph Extension B>) 3569 0x6E02 渂 (<CJK Ideograph>) 3570 0x6F0C 漌 (<CJK Ideograph>) 3571 0x3D6F 㵯 (<CJK Ideograph Extension A>) 3572 0x203F5 𠏵 (<CJK Ideograph Extension B>) 3573 0x7551 畑 (<CJK Ideograph>) 3574 0x36BC 㚼 (<CJK Ideograph Extension A>) 3575 0x34C8 㓈 (<CJK Ideograph Extension A>) 3576 0x4680 䚀 (<CJK Ideograph Extension A>) 3577 0x3EDA 㻚 (<CJK Ideograph Extension A>) 3578 0x4871 䡱 (<CJK Ideograph Extension A>) 3579 0x59C4 姄 (<CJK Ideograph>) 3580 0x926E 鉮 (<CJK Ideograph>) 3581 0x493E 䤾 (<CJK Ideograph Extension A>) 3582 0x8F41 轁 (<CJK Ideograph>) 3583 0x28C1C 𨰜 (<CJK Ideograph Extension B>) 3584 0x26BC0 𦯀 (<CJK Ideograph Extension B>) 3585 0x5812 堒 (<CJK Ideograph>) 3586 0x57C8 埈 (<CJK Ideograph>) 3587 0x36D6 㛖 (<CJK Ideograph Extension A>) 3588 0x21452 𡑒 (<CJK Ideograph Extension B>) 3589 0x70FE 烾 (<CJK Ideograph>) 3590 0x24362 𤍢 (<CJK Ideograph Extension B>) 3591 0x24A71 𤩱 (<CJK Ideograph Extension B>) 3592 0x22FE3 𢿣 (<CJK Ideograph Extension B>) 3593 0x212B0 𡊰 (<CJK Ideograph Extension B>) 3594 0x223BD 𢎽 (<CJK Ideograph Extension B>) 3595 0x68B9 梹 (<CJK Ideograph>) 3596 0x6967 楧 (<CJK Ideograph>) 3597 0x21398 𡎘 (<CJK Ideograph Extension B>) 3598 0x234E5 𣓥 (<CJK Ideograph Extension B>) 3599 0x27BF4 𧯴 (<CJK Ideograph Extension B>) 3600 0x236DF 𣛟 (<CJK Ideograph Extension B>) 3601 0x28A83 𨪃 (<CJK Ideograph Extension B>) 3602 0x237D6 𣟖 (<CJK Ideograph Extension B>) 3603 0x233FA 𣏺 (<CJK Ideograph Extension B>) 3604 0x24C9F 𤲟 (<CJK Ideograph Extension B>) 3605 0x6A1A 樚 (<CJK Ideograph>) 3606 0x236AD 𣚭 (<CJK Ideograph Extension B>) 3607 0x26CB7 𦲷 (<CJK Ideograph Extension B>) 3608 0x843E 萾 (<CJK Ideograph>) 3609 0x44DF 䓟 (<CJK Ideograph Extension A>) 3610 0x44CE 䓎 (<CJK Ideograph Extension A>) 3611 0x26D26 𦴦 (<CJK Ideograph Extension B>) 3612 0x26D51 𦵑 (<CJK Ideograph Extension B>) 3613 0x26C82 𦲂 (<CJK Ideograph Extension B>) 3614 0x26FDE 𦿞 (<CJK Ideograph Extension B>) 3615 0x6F17 漗 (<CJK Ideograph>) 3616 0x27109 𧄉 (<CJK Ideograph Extension B>) 3617 0x833D 茽 (<CJK Ideograph>) 3618 0x2173A 𡜺 (<CJK Ideograph Extension B>) 3619 0x83ED 菭 (<CJK Ideograph>) 3620 0x26C80 𦲀 (<CJK Ideograph Extension B>) 3621 0x27053 𧁓 (<CJK Ideograph Extension B>) 3622 0x217DB 𡟛 (<CJK Ideograph Extension B>) 3623 0x5989 妉 (<CJK Ideograph>) 3624 0x5A82 媂 (<CJK Ideograph>) 3625 0x217B3 𡞳 (<CJK Ideograph Extension B>) 3626 0x5A61 婡 (<CJK Ideograph>) 3627 0x5A71 婱 (<CJK Ideograph>) 3628 0x21905 𡤅 (<CJK Ideograph Extension B>) 3629 0x241FC 𤇼 (<CJK Ideograph Extension B>) 3630 0x372D 㜭 (<CJK Ideograph Extension A>) 3631 0x59EF 姯 (<CJK Ideograph>) 3632 0x2173C 𡜼 (<CJK Ideograph Extension B>) 3633 0x36C7 㛇 (<CJK Ideograph Extension A>) 3634 0x718E 熎 (<CJK Ideograph>) 3635 0x9390 鎐 (<CJK Ideograph>) 3636 0x669A 暚 (<CJK Ideograph>) 3637 0x242A5 𤊥 (<CJK Ideograph Extension B>) 3638 0x5A6E 婮 (<CJK Ideograph>) 3639 0x5A2B 娫 (<CJK Ideograph>) 3640 0x24293 𤊓 (<CJK Ideograph Extension B>) 3641 0x6A2B 樫 (<CJK Ideograph>) 3642 0x23EF9 𣻹 (<CJK Ideograph Extension B>) 3643 0x27736 𧜶 (<CJK Ideograph Extension B>) 3644 0x2445B 𤑛 (<CJK Ideograph Extension B>) 3645 0x242CA 𤋊 (<CJK Ideograph Extension B>) 3646 0x711D 焝 (<CJK Ideograph>) 3647 0x24259 𤉙 (<CJK Ideograph Extension B>) 3648 0x289E1 𨧡 (<CJK Ideograph Extension B>) 3649 0x4FB0 侰 (<CJK Ideograph>) 3650 0x26D28 𦴨 (<CJK Ideograph Extension B>) 3651 0x5CC2 峂 (<CJK Ideograph>) 3652 0x244CE 𤓎 (<CJK Ideograph Extension B>) 3653 0x27E4D 𧹍 (<CJK Ideograph Extension B>) 3654 0x243BD 𤎽 (<CJK Ideograph Extension B>) 3655 0x6A0C 樌 (<CJK Ideograph>) 3656 0x24256 𤉖 (<CJK Ideograph Extension B>) 3657 0x21304 𡌄 (<CJK Ideograph Extension B>) 3658 0x70A6 炦 (<CJK Ideograph>) 3659 0x7133 焳 (<CJK Ideograph>) 3660 0x243E9 𤏩 (<CJK Ideograph Extension B>) 3661 0x3DA5 㶥 (<CJK Ideograph Extension A>) 3662 0x6CDF 泟 (<CJK Ideograph>) 3663 0x2F825 勇 (CJK COMPATIBILITY IDEOGRAPH-2F825) 3664 0x24A4F 𤩏 (<CJK Ideograph Extension B>) 3665 0x7E65 繥 (<CJK Ideograph>) 3666 0x59EB 姫 (<CJK Ideograph>) 3667 0x5D2F 崯 (<CJK Ideograph>) 3668 0x3DF3 㷳 (<CJK Ideograph Extension A>) 3669 0x5F5C 彜 (<CJK Ideograph>) 3670 0x24A5D 𤩝 (<CJK Ideograph Extension B>) 3671 0x217DF 𡟟 (<CJK Ideograph Extension B>) 3672 0x7DA4 綤 (<CJK Ideograph>) 3673 0x8426 萦 (<CJK Ideograph>) 3674 0x5485 咅 (<CJK Ideograph>) 3675 0x23AFA 𣫺 (<CJK Ideograph Extension B>) 3676 0x23300 𣌀 (<CJK Ideograph Extension B>) 3677 0x20214 𠈔 (<CJK Ideograph Extension B>) 3678 0x577E 坾 (<CJK Ideograph>) 3679 0x208D5 𠣕 (<CJK Ideograph Extension B>) 3680 0x20619 𠘙 (<CJK Ideograph Extension B>) 3681 0x3FE5 㿥 (<CJK Ideograph Extension A>) 3682 0x21F9E 𡾞 (<CJK Ideograph Extension B>) 3683 0x2A2B6 𪊶 (<CJK Ideograph Extension B>) 3684 0x7003 瀃 (<CJK Ideograph>) 3685 0x2915B 𩅛 (<CJK Ideograph Extension B>) 3686 0x5D70 嵰 (<CJK Ideograph>) 3687 0x738F 玏 (<CJK Ideograph>) 3688 0x7CD3 糓 (<CJK Ideograph>) 3689 0x28A59 𨩙 (<CJK Ideograph Extension B>) 3690 0x29420 𩐠 (<CJK Ideograph Extension B>) 3691 0x4FC8 俈 (<CJK Ideograph>) 3692 0x7FE7 翧 (<CJK Ideograph>) 3693 0x72CD 狍 (<CJK Ideograph>) 3694 0x7310 猐 (<CJK Ideograph>) 3695 0x27AF4 𧫴 (<CJK Ideograph Extension B>) 3696 0x7338 猸 (<CJK Ideograph>) 3697 0x7339 猹 (<CJK Ideograph>) 3698 0x256F6 𥛶 (<CJK Ideograph Extension B>) 3699 0x7341 獁 (<CJK Ideograph>) 3700 0x7348 獈 (<CJK Ideograph>) 3701 0x3EA9 㺩 (<CJK Ideograph Extension A>) 3702 0x27B18 𧬘 (<CJK Ideograph Extension B>) 3703 0x906C 遬 (<CJK Ideograph>) 3704 0x71F5 燵 (<CJK Ideograph>) 3705 0x248F2 𤣲 (<CJK Ideograph Extension B>) 3706 0x73E1 珡 (<CJK Ideograph>) 3707 0x81F6 臶 (<CJK Ideograph>) 3708 0x3ECA 㻊 (<CJK Ideograph Extension A>) 3709 0x770C 県 (<CJK Ideograph>) 3710 0x3ED1 㻑 (<CJK Ideograph Extension A>) 3711 0x6CA2 沢 (<CJK Ideograph>) 3712 0x56FD 国 (<CJK Ideograph>) 3713 0x7419 琙 (<CJK Ideograph>) 3714 0x741E 琞 (<CJK Ideograph>) 3715 0x741F 琟 (<CJK Ideograph>) 3716 0x3EE2 㻢 (<CJK Ideograph Extension A>) 3717 0x3EF0 㻰 (<CJK Ideograph Extension A>) 3718 0x3EF4 㻴 (<CJK Ideograph Extension A>) 3719 0x3EFA 㻺 (<CJK Ideograph Extension A>) 3720 0x74D3 瓓 (<CJK Ideograph>) 3721 0x3F0E 㼎 (<CJK Ideograph Extension A>) 3722 0x3F53 㽓 (<CJK Ideograph Extension A>) 3723 0x7542 畂 (<CJK Ideograph>) 3724 0x756D 畭 (<CJK Ideograph>) 3725 0x7572 畲 (<CJK Ideograph>) 3726 0x758D 疍 (<CJK Ideograph>) 3727 0x3F7C 㽼 (<CJK Ideograph Extension A>) 3728 0x75C8 痈 (<CJK Ideograph>) 3729 0x75DC 痜 (<CJK Ideograph>) 3730 0x3FC0 㿀 (<CJK Ideograph Extension A>) 3731 0x764D 癍 (<CJK Ideograph>) 3732 0x3FD7 㿗 (<CJK Ideograph Extension A>) 3733 0x7674 癴 (<CJK Ideograph>) 3734 0x3FDC 㿜 (<CJK Ideograph Extension A>) 3735 0x767A 発 (<CJK Ideograph>) 3736 0x24F5C 𤽜 (<CJK Ideograph Extension B>) 3737 0x7188 熈 (<CJK Ideograph>) 3738 0x5623 嘣 (<CJK Ideograph>) 3739 0x8980 覀 (<CJK Ideograph>) 3740 0x5869 塩 (<CJK Ideograph>) 3741 0x401D 䀝 (<CJK Ideograph Extension A>) 3742 0x7743 睃 (<CJK Ideograph>) 3743 0x4039 䀹 (<CJK Ideograph Extension A>) 3744 0x6761 条 (<CJK Ideograph>) 3745 0x4045 䁅 (<CJK Ideograph Extension A>) 3746 0x35DB 㗛 (<CJK Ideograph Extension A>) 3747 0x7798 瞘 (<CJK Ideograph>) 3748 0x406A 䁪 (<CJK Ideograph Extension A>) 3749 0x406F 䁯 (<CJK Ideograph Extension A>) 3750 0x5C5E 属 (<CJK Ideograph>) 3751 0x77BE 瞾 (<CJK Ideograph>) 3752 0x77CB 矋 (<CJK Ideograph>) 3753 0x58F2 売 (<CJK Ideograph>) 3754 0x7818 砘 (<CJK Ideograph>) 3755 0x70B9 点 (<CJK Ideograph>) 3756 0x781C 砜 (<CJK Ideograph>) 3757 0x40A8 䂨 (<CJK Ideograph Extension A>) 3758 0x7839 砹 (<CJK Ideograph>) 3759 0x7847 硇 (<CJK Ideograph>) 3760 0x7851 硑 (<CJK Ideograph>) 3761 0x7866 硦 (<CJK Ideograph>) 3762 0x8448 葈 (<CJK Ideograph>) 3763 0x25535 𥔵 (<CJK Ideograph Extension B>) 3764 0x7933 礳 (<CJK Ideograph>) 3765 0x6803 栃 (<CJK Ideograph>) 3766 0x7932 礲 (<CJK Ideograph>) 3767 0x4103 䄃 (<CJK Ideograph Extension A>) 3768 0x4109 䄉 (<CJK Ideograph Extension A>) 3769 0x7991 禑 (<CJK Ideograph>) 3770 0x7999 禙 (<CJK Ideograph>) 3771 0x8FBB 辻 (<CJK Ideograph>) 3772 0x7A06 稆 (<CJK Ideograph>) 3773 0x8FBC 込 (<CJK Ideograph>) 3774 0x4167 䅧 (<CJK Ideograph Extension A>) 3775 0x7A91 窑 (<CJK Ideograph>) 3776 0x41B2 䆲 (<CJK Ideograph Extension A>) 3777 0x7ABC 窼 (<CJK Ideograph>) 3778 0x8279 艹 (<CJK Ideograph>) 3779 0x41C4 䇄 (<CJK Ideograph Extension A>) 3780 0x7ACF 竏 (<CJK Ideograph>) 3781 0x7ADB 竛 (<CJK Ideograph>) 3782 0x41CF 䇏 (<CJK Ideograph Extension A>) 3783 0x4E21 両 (<CJK Ideograph>) 3784 0x7B62 筢 (<CJK Ideograph>) 3785 0x7B6C 筬 (<CJK Ideograph>) 3786 0x7B7B 筻 (<CJK Ideograph>) 3787 0x7C12 簒 (<CJK Ideograph>) 3788 0x7C1B 簛 (<CJK Ideograph>) 3789 0x4260 䉠 (<CJK Ideograph Extension A>) 3790 0x427A 䉺 (<CJK Ideograph Extension A>) 3791 0x7C7B 类 (<CJK Ideograph>) 3792 0x7C9C 粜 (<CJK Ideograph>) 3793 0x428C 䊌 (<CJK Ideograph Extension A>) 3794 0x7CB8 粸 (<CJK Ideograph>) 3795 0x4294 䊔 (<CJK Ideograph Extension A>) 3796 0x7CED 糭 (<CJK Ideograph>) 3797 0x8F93 输 (<CJK Ideograph>) 3798 0x70C0 烀 (<CJK Ideograph>) 3799 0x20CCF 𠳏 (<CJK Ideograph Extension B>) 3800 0x7DCF 総 (<CJK Ideograph>) 3801 0x7DD4 緔 (<CJK Ideograph>) 3802 0x7DD0 緐 (<CJK Ideograph>) 3803 0x7DFD 緽 (<CJK Ideograph>) 3804 0x7FAE 羮 (<CJK Ideograph>) 3805 0x7FB4 羴 (<CJK Ideograph>) 3806 0x729F 犟 (<CJK Ideograph>) 3807 0x4397 䎗 (<CJK Ideograph Extension A>) 3808 0x8020 耠 (<CJK Ideograph>) 3809 0x8025 耥 (<CJK Ideograph>) 3810 0x7B39 笹 (<CJK Ideograph>) 3811 0x802E 耮 (<CJK Ideograph>) 3812 0x8031 耱 (<CJK Ideograph>) 3813 0x8054 联 (<CJK Ideograph>) 3814 0x3DCC 㷌 (<CJK Ideograph Extension A>) 3815 0x57B4 垴 (<CJK Ideograph>) 3816 0x70A0 炠 (<CJK Ideograph>) 3817 0x80B7 肷 (<CJK Ideograph>) 3818 0x80E9 胩 (<CJK Ideograph>) 3819 0x43ED 䏭 (<CJK Ideograph Extension A>) 3820 0x810C 脌 (<CJK Ideograph>) 3821 0x732A 猪 (<CJK Ideograph>) 3822 0x810E 脎 (<CJK Ideograph>) 3823 0x8112 脒 (<CJK Ideograph>) 3824 0x7560 畠 (<CJK Ideograph>) 3825 0x8114 脔 (<CJK Ideograph>) 3826 0x4401 䐁 (<CJK Ideograph Extension A>) 3827 0x3B39 㬹 (<CJK Ideograph Extension A>) 3828 0x8156 腖 (<CJK Ideograph>) 3829 0x8159 腙 (<CJK Ideograph>) 3830 0x815A 腚 (<CJK Ideograph>) 3831 0x4413 䐓 (<CJK Ideograph Extension A>) 3832 0x583A 堺 (<CJK Ideograph>) 3833 0x817C 腼 (<CJK Ideograph>) 3834 0x8184 膄 (<CJK Ideograph>) 3835 0x4425 䐥 (<CJK Ideograph Extension A>) 3836 0x8193 膓 (<CJK Ideograph>) 3837 0x442D 䐭 (<CJK Ideograph Extension A>) 3838 0x81A5 膥 (<CJK Ideograph>) 3839 0x57EF 埯 (<CJK Ideograph>) 3840 0x81C1 臁 (<CJK Ideograph>) 3841 0x81E4 臤 (<CJK Ideograph>) 3842 0x8254 艔 (<CJK Ideograph>) 3843 0x448F 䒏 (<CJK Ideograph Extension A>) 3844 0x82A6 芦 (<CJK Ideograph>) 3845 0x8276 艶 (<CJK Ideograph>) 3846 0x82CA 苊 (<CJK Ideograph>) 3847 0x82D8 苘 (<CJK Ideograph>) 3848 0x82FF 苿 (<CJK Ideograph>) 3849 0x44B0 䒰 (<CJK Ideograph Extension A>) 3850 0x8357 荗 (<CJK Ideograph>) 3851 0x9669 险 (<CJK Ideograph>) 3852 0x698A 榊 (<CJK Ideograph>) 3853 0x8405 萅 (<CJK Ideograph>) 3854 0x70F5 烵 (<CJK Ideograph>) 3855 0x8464 葤 (<CJK Ideograph>) 3856 0x60E3 惣 (<CJK Ideograph>) 3857 0x8488 蒈 (<CJK Ideograph>) 3858 0x4504 䔄 (<CJK Ideograph Extension A>) 3859 0x84BE 蒾 (<CJK Ideograph>) 3860 0x84E1 蓡 (<CJK Ideograph>) 3861 0x84F8 蓸 (<CJK Ideograph>) 3862 0x8510 蔐 (<CJK Ideograph>) 3863 0x8538 蔸 (<CJK Ideograph>) 3864 0x8552 蕒 (<CJK Ideograph>) 3865 0x453B 䔻 (<CJK Ideograph Extension A>) 3866 0x856F 蕯 (<CJK Ideograph>) 3867 0x8570 蕰 (<CJK Ideograph>) 3868 0x85E0 藠 (<CJK Ideograph>) 3869 0x4577 䕷 (<CJK Ideograph Extension A>) 3870 0x8672 虲 (<CJK Ideograph>) 3871 0x8692 蚒 (<CJK Ideograph>) 3872 0x86B2 蚲 (<CJK Ideograph>) 3873 0x86EF 蛯 (<CJK Ideograph>) 3874 0x9645 际 (<CJK Ideograph>) 3875 0x878B 螋 (<CJK Ideograph>) 3876 0x4606 䘆 (<CJK Ideograph Extension A>) 3877 0x4617 䘗 (<CJK Ideograph Extension A>) 3878 0x88AE 袮 (<CJK Ideograph>) 3879 0x88FF 裿 (<CJK Ideograph>) 3880 0x8924 褤 (<CJK Ideograph>) 3881 0x8947 襇 (<CJK Ideograph>) 3882 0x8991 覑 (<CJK Ideograph>) 3883 0x27967 𧥧 (<CJK Ideograph Extension B>) 3884 0x8A29 訩 (<CJK Ideograph>) 3885 0x8A38 訸 (<CJK Ideograph>) 3886 0x8A94 誔 (<CJK Ideograph>) 3887 0x8AB4 誴 (<CJK Ideograph>) 3888 0x8C51 豑 (<CJK Ideograph>) 3889 0x8CD4 賔 (<CJK Ideograph>) 3890 0x8CF2 賲 (<CJK Ideograph>) 3891 0x8D1C 贜 (<CJK Ideograph>) 3892 0x4798 䞘 (<CJK Ideograph Extension A>) 3893 0x585F 塟 (<CJK Ideograph>) 3894 0x8DC3 跃 (<CJK Ideograph>) 3895 0x47ED 䟭 (<CJK Ideograph Extension A>) 3896 0x4EEE 仮 (<CJK Ideograph>) 3897 0x8E3A 踺 (<CJK Ideograph>) 3898 0x55D8 嗘 (<CJK Ideograph>) 3899 0x5754 坔 (<CJK Ideograph>) 3900 0x8E71 蹱 (<CJK Ideograph>) 3901 0x55F5 嗵 (<CJK Ideograph>) 3902 0x8EB0 躰 (<CJK Ideograph>) 3903 0x4837 䠷 (<CJK Ideograph Extension A>) 3904 0x8ECE 軎 (<CJK Ideograph>) 3905 0x8EE2 転 (<CJK Ideograph>) 3906 0x8EE4 軤 (<CJK Ideograph>) 3907 0x8EED 軭 (<CJK Ideograph>) 3908 0x8EF2 軲 (<CJK Ideograph>) 3909 0x8FB7 辷 (<CJK Ideograph>) 3910 0x8FC1 迁 (<CJK Ideograph>) 3911 0x8FCA 迊 (<CJK Ideograph>) 3912 0x8FCC 迌 (<CJK Ideograph>) 3913 0x9033 逳 (<CJK Ideograph>) 3914 0x99C4 駄 (<CJK Ideograph>) 3915 0x48AD 䢭 (<CJK Ideograph Extension A>) 3916 0x98E0 飠 (<CJK Ideograph>) 3917 0x9213 鈓 (<CJK Ideograph>) 3918 0x491E 䤞 (<CJK Ideograph Extension A>) 3919 0x9228 鈨 (<CJK Ideograph>) 3920 0x9258 鉘 (<CJK Ideograph>) 3921 0x926B 鉫 (<CJK Ideograph>) 3922 0x92B1 銱 (<CJK Ideograph>) 3923 0x92AE 銮 (<CJK Ideograph>) 3924 0x92BF 銿 (<CJK Ideograph>) 3925 0x92E3 鋣 (<CJK Ideograph>) 3926 0x92EB 鋫 (<CJK Ideograph>) 3927 0x92F3 鋳 (<CJK Ideograph>) 3928 0x92F4 鋴 (<CJK Ideograph>) 3929 0x92FD 鋽 (<CJK Ideograph>) 3930 0x9343 鍃 (<CJK Ideograph>) 3931 0x9384 鎄 (<CJK Ideograph>) 3932 0x93AD 鎭 (<CJK Ideograph>) 3933 0x4945 䥅 (<CJK Ideograph Extension A>) 3934 0x4951 䥑 (<CJK Ideograph Extension A>) 3935 0x9EBF 麿 (<CJK Ideograph>) 3936 0x9417 鐗 (<CJK Ideograph>) 3937 0x5301 匁 (<CJK Ideograph>) 3938 0x941D 鐝 (<CJK Ideograph>) 3939 0x942D 鐭 (<CJK Ideograph>) 3940 0x943E 鐾 (<CJK Ideograph>) 3941 0x496A 䥪 (<CJK Ideograph Extension A>) 3942 0x9454 鑔 (<CJK Ideograph>) 3943 0x9479 鑹 (<CJK Ideograph>) 3944 0x952D 锭 (<CJK Ideograph>) 3945 0x95A2 関 (<CJK Ideograph>) 3946 0x49A7 䦧 (<CJK Ideograph Extension A>) 3947 0x95F4 间 (<CJK Ideograph>) 3948 0x9633 阳 (<CJK Ideograph>) 3949 0x49E5 䧥 (<CJK Ideograph Extension A>) 3950 0x67A0 枠 (<CJK Ideograph>) 3951 0x4A24 䨤 (<CJK Ideograph Extension A>) 3952 0x9740 靀 (<CJK Ideograph>) 3953 0x4A35 䨵 (<CJK Ideograph Extension A>) 3954 0x97B2 鞲 (<CJK Ideograph>) 3955 0x97C2 韂 (<CJK Ideograph>) 3956 0x5654 噔 (<CJK Ideograph>) 3957 0x4AE4 䫤 (<CJK Ideograph Extension A>) 3958 0x60E8 惨 (<CJK Ideograph>) 3959 0x98B9 颹 (<CJK Ideograph>) 3960 0x4B19 䬙 (<CJK Ideograph Extension A>) 3961 0x98F1 飱 (<CJK Ideograph>) 3962 0x5844 塄 (<CJK Ideograph>) 3963 0x990E 餎 (<CJK Ideograph>) 3964 0x9919 餙 (<CJK Ideograph>) 3965 0x51B4 冴 (<CJK Ideograph>) 3966 0x991C 餜 (<CJK Ideograph>) 3967 0x9937 餷 (<CJK Ideograph>) 3968 0x9942 饂 (<CJK Ideograph>) 3969 0x995D 饝 (<CJK Ideograph>) 3970 0x9962 饢 (<CJK Ideograph>) 3971 0x4B70 䭰 (<CJK Ideograph Extension A>) 3972 0x99C5 駅 (<CJK Ideograph>) 3973 0x4B9D 䮝 (<CJK Ideograph Extension A>) 3974 0x9A3C 騼 (<CJK Ideograph>) 3975 0x9B0F 鬏 (<CJK Ideograph>) 3976 0x7A83 窃 (<CJK Ideograph>) 3977 0x9B69 魩 (<CJK Ideograph>) 3978 0x9B81 鮁 (<CJK Ideograph>) 3979 0x9BDD 鯝 (<CJK Ideograph>) 3980 0x9BF1 鯱 (<CJK Ideograph>) 3981 0x9BF4 鯴 (<CJK Ideograph>) 3982 0x4C6D 䱭 (<CJK Ideograph Extension A>) 3983 0x9C20 鰠 (<CJK Ideograph>) 3984 0x376F 㝯 (<CJK Ideograph Extension A>) 3985 0x21BC2 𡯂 (<CJK Ideograph Extension B>) 3986 0x9D49 鵉 (<CJK Ideograph>) 3987 0x9C3A 鰺 (<CJK Ideograph>) 3988 0x9EFE 黾 (<CJK Ideograph>) 3989 0x5650 噐 (<CJK Ideograph>) 3990 0x9D93 鶓 (<CJK Ideograph>) 3991 0x9DBD 鶽 (<CJK Ideograph>) 3992 0x9DC0 鷀 (<CJK Ideograph>) 3993 0x9DFC 鷼 (<CJK Ideograph>) 3994 0x94F6 银 (<CJK Ideograph>) 3995 0x8FB6 辶 (<CJK Ideograph>) 3996 0x9E7B 鹻 (<CJK Ideograph>) 3997 0x9EAC 麬 (<CJK Ideograph>) 3998 0x9EB1 麱 (<CJK Ideograph>) 3999 0x9EBD 麽 (<CJK Ideograph>) 4000 0x9EC6 黆 (<CJK Ideograph>) 4001 0x94DC 铜 (<CJK Ideograph>) 4002 0x9EE2 黢 (<CJK Ideograph>) 4003 0x9EF1 黱 (<CJK Ideograph>) 4004 0x9EF8 黸 (<CJK Ideograph>) 4005 0x7AC8 竈 (<CJK Ideograph>) 4006 0x9F44 齄 (<CJK Ideograph>) 4007 0x20094 𠂔 (<CJK Ideograph Extension B>) 4008 0x202B7 𠊷 (<CJK Ideograph Extension B>) 4009 0x203A0 𠎠 (<CJK Ideograph Extension B>) 4010 0x691A 椚 (<CJK Ideograph>) 4011 0x94C3 铃 (<CJK Ideograph>) 4012 0x59AC 妬 (<CJK Ideograph>) 4013 0x204D7 𠓗 (<CJK Ideograph Extension B>) 4014 0x5840 塀 (<CJK Ideograph>) 4015 0x94C1 铁 (<CJK Ideograph>) 4016 0x37B9 㞹 (<CJK Ideograph Extension A>) 4017 0x205D5 𠗕 (<CJK Ideograph Extension B>) 4018 0x20615 𠘕 (<CJK Ideograph Extension B>) 4019 0x20676 𠙶 (<CJK Ideograph Extension B>) 4020 0x216BA 𡚺 (<CJK Ideograph Extension B>) 4021 0x5757 块 (<CJK Ideograph>) 4022 0x7173 煳 (<CJK Ideograph>) 4023 0x20AC2 𠫂 (<CJK Ideograph Extension B>) 4024 0x20ACD 𠫍 (<CJK Ideograph Extension B>) 4025 0x20BBF 𠮿 (<CJK Ideograph Extension B>) 4026 0x546A 呪 (<CJK Ideograph>) 4027 0x2F83B 吆 (CJK COMPATIBILITY IDEOGRAPH-2F83B) 4028 0x20BCB 𠯋 (<CJK Ideograph Extension B>) 4029 0x549E 咞 (<CJK Ideograph>) 4030 0x20BFB 𠯻 (<CJK Ideograph Extension B>) 4031 0x20C3B 𠰻 (<CJK Ideograph Extension B>) 4032 0x20C53 𠱓 (<CJK Ideograph Extension B>) 4033 0x20C65 𠱥 (<CJK Ideograph Extension B>) 4034 0x20C7C 𠱼 (<CJK Ideograph Extension B>) 4035 0x60E7 惧 (<CJK Ideograph>) 4036 0x20C8D 𠲍 (<CJK Ideograph Extension B>) 4037 0x567A 噺 (<CJK Ideograph>) 4038 0x20CB5 𠲵 (<CJK Ideograph Extension B>) 4039 0x20CDD 𠳝 (<CJK Ideograph Extension B>) 4040 0x20CED 𠳭 (<CJK Ideograph Extension B>) 4041 0x20D6F 𠵯 (<CJK Ideograph Extension B>) 4042 0x20DB2 𠶲 (<CJK Ideograph Extension B>) 4043 0x20DC8 𠷈 (<CJK Ideograph Extension B>) 4044 0x6955 楕 (<CJK Ideograph>) 4045 0x9C2F 鰯 (<CJK Ideograph>) 4046 0x87A5 螥 (<CJK Ideograph>) 4047 0x20E04 𠸄 (<CJK Ideograph Extension B>) 4048 0x20E0E 𠸎 (<CJK Ideograph Extension B>) 4049 0x20ED7 𠻗 (<CJK Ideograph Extension B>) 4050 0x20F90 𠾐 (<CJK Ideograph Extension B>) 4051 0x20F2D 𠼭 (<CJK Ideograph Extension B>) 4052 0x20E73 𠹳 (<CJK Ideograph Extension B>) 4053 0x5C20 尠 (<CJK Ideograph>) 4054 0x20FBC 𠾼 (<CJK Ideograph Extension B>) 4055 0x5E0B 帋 (<CJK Ideograph>) 4056 0x2105C 𡁜 (<CJK Ideograph Extension B>) 4057 0x2104F 𡁏 (<CJK Ideograph Extension B>) 4058 0x21076 𡁶 (<CJK Ideograph Extension B>) 4059 0x671E 朞 (<CJK Ideograph>) 4060 0x2107B 𡁻 (<CJK Ideograph Extension B>) 4061 0x21088 𡂈 (<CJK Ideograph Extension B>) 4062 0x21096 𡂖 (<CJK Ideograph Extension B>) 4063 0x3647 㙇 (<CJK Ideograph Extension A>) 4064 0x210BF 𡂿 (<CJK Ideograph Extension B>) 4065 0x210D3 𡃓 (<CJK Ideograph Extension B>) 4066 0x2112F 𡄯 (<CJK Ideograph Extension B>) 4067 0x2113B 𡄻 (<CJK Ideograph Extension B>) 4068 0x5364 卤 (<CJK Ideograph>) 4069 0x84AD 蒭 (<CJK Ideograph>) 4070 0x212E3 𡋣 (<CJK Ideograph Extension B>) 4071 0x21375 𡍵 (<CJK Ideograph Extension B>) 4072 0x21336 𡌶 (<CJK Ideograph Extension B>) 4073 0x8B81 讁 (<CJK Ideograph>) 4074 0x21577 𡕷 (<CJK Ideograph Extension B>) 4075 0x21619 𡘙 (<CJK Ideograph Extension B>) 4076 0x217C3 𡟃 (<CJK Ideograph Extension B>) 4077 0x217C7 𡟇 (<CJK Ideograph Extension B>) 4078 0x4E78 乸 (<CJK Ideograph>) 4079 0x70BB 炻 (<CJK Ideograph>) 4080 0x2182D 𡠭 (<CJK Ideograph Extension B>) 4081 0x2196A 𡥪 (<CJK Ideograph Extension B>) 4082 0x21A2D 𡨭 (<CJK Ideograph Extension B>) 4083 0x21A45 𡩅 (<CJK Ideograph Extension B>) 4084 0x21C2A 𡰪 (<CJK Ideograph Extension B>) 4085 0x21C70 𡱰 (<CJK Ideograph Extension B>) 4086 0x21CAC 𡲬 (<CJK Ideograph Extension B>) 4087 0x21EC8 𡻈 (<CJK Ideograph Extension B>) 4088 0x62C3 拃 (<CJK Ideograph>) 4089 0x21ED5 𡻕 (<CJK Ideograph Extension B>) 4090 0x21F15 𡼕 (<CJK Ideograph Extension B>) 4091 0x7198 熘 (<CJK Ideograph>) 4092 0x6855 桕 (<CJK Ideograph>) 4093 0x22045 𢁅 (<CJK Ideograph Extension B>) 4094 0x69E9 槩 (<CJK Ideograph>) 4095 0x36C8 㛈 (<CJK Ideograph Extension A>) 4096 0x2227C 𢉼 (<CJK Ideograph Extension B>) 4097 0x223D7 𢏗 (<CJK Ideograph Extension B>) 4098 0x223FA 𢏺 (<CJK Ideograph Extension B>) 4099 0x2272A 𢜪 (<CJK Ideograph Extension B>) 4100 0x22871 𢡱 (<CJK Ideograph Extension B>) 4101 0x2294F 𢥏 (<CJK Ideograph Extension B>) 4102 0x82FD 苽 (<CJK Ideograph>) 4103 0x22967 𢥧 (<CJK Ideograph Extension B>) 4104 0x22993 𢦓 (<CJK Ideograph Extension B>) 4105 0x22AD5 𢫕 (<CJK Ideograph Extension B>) 4106 0x89A5 覥 (<CJK Ideograph>) 4107 0x22AE8 𢫨 (<CJK Ideograph Extension B>) 4108 0x8FA0 辠 (<CJK Ideograph>) 4109 0x22B0E 𢬎 (<CJK Ideograph Extension B>) 4110 0x97B8 鞸 (<CJK Ideograph>) 4111 0x22B3F 𢬿 (<CJK Ideograph Extension B>) 4112 0x9847 顇 (<CJK Ideograph>) 4113 0x9ABD 骽 (<CJK Ideograph>) 4114 0x22C4C 𢱌 (<CJK Ideograph Extension B>) 4116 0x22C88 𢲈 (<CJK Ideograph Extension B>) 4117 0x22CB7 𢲷 (<CJK Ideograph Extension B>) 4118 0x25BE8 𥯨 (<CJK Ideograph Extension B>) 4119 0x22D08 𢴈 (<CJK Ideograph Extension B>) 4120 0x22D12 𢴒 (<CJK Ideograph Extension B>) 4121 0x22DB7 𢶷 (<CJK Ideograph Extension B>) 4122 0x22D95 𢶕 (<CJK Ideograph Extension B>) 4123 0x22E42 𢹂 (<CJK Ideograph Extension B>) 4124 0x22F74 𢽴 (<CJK Ideograph Extension B>) 4125 0x22FCC 𢿌 (<CJK Ideograph Extension B>) 4126 0x23033 𣀳 (<CJK Ideograph Extension B>) 4127 0x23066 𣁦 (<CJK Ideograph Extension B>) 4128 0x2331F 𣌟 (<CJK Ideograph Extension B>) 4129 0x233DE 𣏞 (<CJK Ideograph Extension B>) 4130 0x5FB1 徱 (<CJK Ideograph>) 4131 0x6648 晈 (<CJK Ideograph>) 4132 0x66BF 暿 (<CJK Ideograph>) 4133 0x27A79 𧩹 (<CJK Ideograph Extension B>) 4134 0x23567 𣕧 (<CJK Ideograph Extension B>) 4135 0x235F3 𣗳 (<CJK Ideograph Extension B>) 4136 0x7201 爁 (<CJK Ideograph>) 4137 0x249BA 𤦺 (<CJK Ideograph Extension B>) 4138 0x77D7 矗 (<CJK Ideograph>) 4139 0x2361A 𣘚 (<CJK Ideograph Extension B>) 4140 0x23716 𣜖 (<CJK Ideograph Extension B>) 4141 0x7E87 纇 (<CJK Ideograph>) 4142 0x20346 𠍆 (<CJK Ideograph Extension B>) 4143 0x58B5 墵 (<CJK Ideograph>) 4144 0x670E 朎 (<CJK Ideograph>) 4145 0x6918 椘 (<CJK Ideograph>) 4146 0x23AA7 𣪧 (<CJK Ideograph Extension B>) 4147 0x27657 𧙗 (<CJK Ideograph Extension B>) 4148 0x25FE2 𥿢 (<CJK Ideograph Extension B>) 4149 0x23E11 𣸑 (<CJK Ideograph Extension B>) 4150 0x23EB9 𣺹 (<CJK Ideograph Extension B>) 4151 0x275FE 𧗾 (<CJK Ideograph Extension B>) 4152 0x2209A 𢂚 (<CJK Ideograph Extension B>) 4153 0x48D0 䣐 (<CJK Ideograph Extension A>) 4154 0x4AB8 䪸 (<CJK Ideograph Extension A>) 4155 0x24119 𤄙 (<CJK Ideograph Extension B>) 4156 0x28A9A 𨪚 (<CJK Ideograph Extension B>) 4157 0x242EE 𤋮 (<CJK Ideograph Extension B>) 4158 0x2430D 𤌍 (<CJK Ideograph Extension B>) 4159 0x2403B 𤀻 (<CJK Ideograph Extension B>) 4160 0x24334 𤌴 (<CJK Ideograph Extension B>) 4161 0x24396 𤎖 (<CJK Ideograph Extension B>) 4162 0x24A45 𤩅 (<CJK Ideograph Extension B>) 4163 0x205CA 𠗊 (<CJK Ideograph Extension B>) 4164 0x51D2 凒 (<CJK Ideograph>) 4165 0x20611 𠘑 (<CJK Ideograph Extension B>) 4166 0x599F 妟 (<CJK Ideograph>) 4167 0x21EA8 𡺨 (<CJK Ideograph Extension B>) 4168 0x3BBE 㮾 (<CJK Ideograph Extension A>) 4169 0x23CFF 𣳿 (<CJK Ideograph Extension B>) 4170 0x24404 𤐄 (<CJK Ideograph Extension B>) 4171 0x244D6 𤓖 (<CJK Ideograph Extension B>) 4172 0x5788 垈 (<CJK Ideograph>) 4173 0x24674 𤙴 (<CJK Ideograph Extension B>) 4174 0x399B 㦛 (<CJK Ideograph Extension A>) 4175 0x2472F 𤜯 (<CJK Ideograph Extension B>) 4176 0x285E8 𨗨 (<CJK Ideograph Extension B>) 4177 0x299C9 𩧉 (<CJK Ideograph Extension B>) 4178 0x3762 㝢 (<CJK Ideograph Extension A>) 4179 0x221C3 𢇃 (<CJK Ideograph Extension B>) 4180 0x8B5E 譞 (<CJK Ideograph>) 4181 0x28B4E 𨭎 (<CJK Ideograph Extension B>) 4182 0x99D6 駖 (<CJK Ideograph>) 4183 0x24812 𤠒 (<CJK Ideograph Extension B>) 4184 0x248FB 𤣻 (<CJK Ideograph Extension B>) 4185 0x24A15 𤨕 (<CJK Ideograph Extension B>) 4186 0x7209 爉 (<CJK Ideograph>) 4187 0x24AC0 𤫀 (<CJK Ideograph Extension B>) 4188 0x20C78 𠱸 (<CJK Ideograph Extension B>) 4189 0x5965 奥 (<CJK Ideograph>) 4190 0x24EA5 𤺥 (<CJK Ideograph Extension B>) 4191 0x24F86 𤾆 (<CJK Ideograph Extension B>) 4192 0x20779 𠝹 (<CJK Ideograph Extension B>) 4193 0x8EDA 軚 (<CJK Ideograph>) 4194 0x2502C 𥀬 (<CJK Ideograph Extension B>) 4195 0x528F 劏 (<CJK Ideograph>) 4196 0x573F 圿 (<CJK Ideograph>) 4197 0x7171 煱 (<CJK Ideograph>) 4198 0x25299 𥊙 (<CJK Ideograph Extension B>) 4199 0x25419 𥐙 (<CJK Ideograph Extension B>) 4200 0x23F4A 𣽊 (<CJK Ideograph Extension B>) 4201 0x24AA7 𤪧 (<CJK Ideograph Extension B>) 4202 0x55BC 喼 (<CJK Ideograph>) 4203 0x25446 𥑆 (<CJK Ideograph Extension B>) 4204 0x2546E 𥑮 (<CJK Ideograph Extension B>) 4205 0x26B52 𦭒 (<CJK Ideograph Extension B>) 4206 0x91D4 釔 (<CJK Ideograph>) 4207 0x3473 㑳 (<CJK Ideograph Extension A>) 4208 0x2553F 𥔿 (<CJK Ideograph Extension B>) 4209 0x27632 𧘲 (<CJK Ideograph Extension B>) 4210 0x2555E 𥕞 (<CJK Ideograph Extension B>) 4211 0x4718 䜘 (<CJK Ideograph Extension A>) 4212 0x25562 𥕢 (<CJK Ideograph Extension B>) 4213 0x25566 𥕦 (<CJK Ideograph Extension B>) 4214 0x257C7 𥟇 (<CJK Ideograph Extension B>) 4215 0x2493F 𤤿 (<CJK Ideograph Extension B>) 4216 0x2585D 𥡝 (<CJK Ideograph Extension B>) 4217 0x5066 偦 (<CJK Ideograph>) 4218 0x34FB 㓻 (<CJK Ideograph Extension A>) 4219 0x233CC 𣏌 (<CJK Ideograph Extension B>) 4220 0x60DE 惞 (<CJK Ideograph>) 4221 0x25903 𥤃 (<CJK Ideograph Extension B>) 4222 0x477C 䝼 (<CJK Ideograph Extension A>) 4223 0x28948 𨥈 (<CJK Ideograph Extension B>) 4224 0x25AAE 𥪮 (<CJK Ideograph Extension B>) 4225 0x25B89 𥮉 (<CJK Ideograph Extension B>) 4226 0x25C06 𥰆 (<CJK Ideograph Extension B>) 4227 0x21D90 𡶐 (<CJK Ideograph Extension B>) 4228 0x57A1 垡 (<CJK Ideograph>) 4229 0x7151 煑 (<CJK Ideograph>) 4230 0x6FB6 澶 (<CJK Ideograph>) 4231 0x26102 𦄂 (<CJK Ideograph Extension B>) 4232 0x27C12 𧰒 (<CJK Ideograph Extension B>) 4233 0x9056 遖 (<CJK Ideograph>) 4234 0x261B2 𦆲 (<CJK Ideograph Extension B>) 4235 0x24F9A 𤾚 (<CJK Ideograph Extension B>) 4236 0x8B62 譢 (<CJK Ideograph>) 4237 0x26402 𦐂 (<CJK Ideograph Extension B>) 4238 0x2644A 𦑊 (<CJK Ideograph Extension B>) 4239 0x5D5B 嵛 (<CJK Ideograph>) 4240 0x26BF7 𦯷 (<CJK Ideograph Extension B>) 4241 0x8F36 輶 (<CJK Ideograph>) 4242 0x26484 𦒄 (<CJK Ideograph Extension B>) 4243 0x2191C 𡤜 (<CJK Ideograph Extension B>) 4244 0x8AEA 諪 (<CJK Ideograph>) 4245 0x249F6 𤧶 (<CJK Ideograph Extension B>) 4246 0x26488 𦒈 (<CJK Ideograph Extension B>) 4247 0x23FEF 𣿯 (<CJK Ideograph Extension B>) 4248 0x26512 𦔒 (<CJK Ideograph Extension B>) 4249 0x4BC0 䯀 (<CJK Ideograph Extension A>) 4250 0x265BF 𦖿 (<CJK Ideograph Extension B>) 4251 0x266B5 𦚵 (<CJK Ideograph Extension B>) 4252 0x2271B 𢜛 (<CJK Ideograph Extension B>) 4253 0x9465 鑥 (<CJK Ideograph>) 4254 0x257E1 𥟡 (<CJK Ideograph Extension B>) 4255 0x6195 憕 (<CJK Ideograph>) 4256 0x5A27 娧 (<CJK Ideograph>) 4257 0x2F8CD 晉 (CJK COMPATIBILITY IDEOGRAPH-2F8CD) 4258 0x4FBB 侻 (<CJK Ideograph>) 4259 0x56B9 嚹 (<CJK Ideograph>) 4260 0x24521 𤔡 (<CJK Ideograph Extension B>) 4261 0x266FC 𦛼 (<CJK Ideograph Extension B>) 4262 0x4E6A 乪 (<CJK Ideograph>) 4263 0x24934 𤤴 (<CJK Ideograph Extension B>) 4264 0x9656 陖 (<CJK Ideograph>) 4265 0x6D8F 涏 (<CJK Ideograph>) 4266 0x26CBD 𦲽 (<CJK Ideograph Extension B>) 4267 0x3618 㘘 (<CJK Ideograph Extension A>) 4268 0x8977 襷 (<CJK Ideograph>) 4269 0x26799 𦞙 (<CJK Ideograph Extension B>) 4270 0x2686E 𦡮 (<CJK Ideograph Extension B>) 4271 0x26411 𦐑 (<CJK Ideograph Extension B>) 4272 0x2685E 𦡞 (<CJK Ideograph Extension B>) 4273 0x71DF 營 (<CJK Ideograph>) 4274 0x268C7 𦣇 (<CJK Ideograph Extension B>) 4275 0x7B42 筂 (<CJK Ideograph>) 4276 0x290C0 𩃀 (<CJK Ideograph Extension B>) 4277 0x20A11 𠨑 (<CJK Ideograph Extension B>) 4278 0x26926 𦤦 (<CJK Ideograph Extension B>) 4279 0x9104 鄄 (<CJK Ideograph>) 4280 0x26939 𦤹 (<CJK Ideograph Extension B>) 4281 0x7A45 穅 (<CJK Ideograph>) 4282 0x9DF0 鷰 (<CJK Ideograph>) 4283 0x269FA 𦧺 (<CJK Ideograph Extension B>) 4284 0x9A26 騦 (<CJK Ideograph>) 4285 0x26A2D 𦨭 (<CJK Ideograph Extension B>) 4286 0x365F 㙟 (<CJK Ideograph Extension A>) 4287 0x26469 𦑩 (<CJK Ideograph Extension B>) 4288 0x20021 𠀡 (<CJK Ideograph Extension B>) 4289 0x7983 禃 (<CJK Ideograph>) 4290 0x26A34 𦨴 (<CJK Ideograph Extension B>) 4291 0x26B5B 𦭛 (<CJK Ideograph Extension B>) 4292 0x5D2C 崬 (<CJK Ideograph>) 4293 0x23519 𣔙 (<CJK Ideograph Extension B>) 4294 0x83CF 菏 (<CJK Ideograph>) 4295 0x26B9D 𦮝 (<CJK Ideograph Extension B>) 4296 0x46D0 䛐 (<CJK Ideograph Extension A>) 4297 0x26CA4 𦲤 (<CJK Ideograph Extension B>) 4298 0x753B 画 (<CJK Ideograph>) 4299 0x8865 补 (<CJK Ideograph>) 4300 0x26DAE 𦶮 (<CJK Ideograph Extension B>) 4301 0x58B6 墶 (<CJK Ideograph>) 4302 0x371C 㜜 (<CJK Ideograph Extension A>) 4303 0x2258D 𢖍 (<CJK Ideograph Extension B>) 4304 0x2704B 𧁋 (<CJK Ideograph Extension B>) 4305 0x271CD 𧇍 (<CJK Ideograph Extension B>) 4306 0x3C54 㱔 (<CJK Ideograph Extension A>) 4307 0x27280 𧊀 (<CJK Ideograph Extension B>) 4308 0x27285 𧊅 (<CJK Ideograph Extension B>) 4309 0x9281 銁 (<CJK Ideograph>) 4310 0x2217A 𢅺 (<CJK Ideograph Extension B>) 4311 0x2728B 𧊋 (<CJK Ideograph Extension B>) 4312 0x9330 錰 (<CJK Ideograph>) 4313 0x272E6 𧋦 (<CJK Ideograph Extension B>) 4314 0x249D0 𤧐 (<CJK Ideograph Extension B>) 4315 0x6C39 氹 (<CJK Ideograph>) 4316 0x949F 钟 (<CJK Ideograph>) 4317 0x27450 𧑐 (<CJK Ideograph Extension B>) 4318 0x20EF8 𠻸 (<CJK Ideograph Extension B>) 4319 0x8827 蠧 (<CJK Ideograph>) 4320 0x88F5 裵 (<CJK Ideograph>) 4321 0x22926 𢤦 (<CJK Ideograph Extension B>) 4322 0x28473 𨑳 (<CJK Ideograph Extension B>) 4323 0x217B1 𡞱 (<CJK Ideograph Extension B>) 4324 0x6EB8 溸 (<CJK Ideograph>) 4325 0x24A2A 𤨪 (<CJK Ideograph Extension B>) 4326 0x21820 𡠠 (<CJK Ideograph Extension B>) 4327 0x39A4 㦤 (<CJK Ideograph Extension A>) 4328 0x36B9 㚹 (<CJK Ideograph Extension A>) 4329 0x5C10 尐 (<CJK Ideograph>) 4330 0x79E3 秣 (<CJK Ideograph>) 4331 0x453F 䔿 (<CJK Ideograph Extension A>) 4332 0x66B6 暶 (<CJK Ideograph>) 4333 0x29CAD 𩲭 (<CJK Ideograph Extension B>) 4334 0x298A4 𩢤 (<CJK Ideograph Extension B>) 4335 0x8943 襃 (<CJK Ideograph>) 4336 0x277CC 𧟌 (<CJK Ideograph Extension B>) 4337 0x27858 𧡘 (<CJK Ideograph Extension B>) 4338 0x56D6 囖 (<CJK Ideograph>) 4339 0x40DF 䃟 (<CJK Ideograph Extension A>) 4340 0x2160A 𡘊 (<CJK Ideograph Extension B>) 4341 0x39A1 㦡 (<CJK Ideograph Extension A>) 4342 0x2372F 𣜯 (<CJK Ideograph Extension B>) 4343 0x280E8 𨃨 (<CJK Ideograph Extension B>) 4344 0x213C5 𡏅 (<CJK Ideograph Extension B>) 4345 0x71AD 熭 (<CJK Ideograph>) 4346 0x8366 荦 (<CJK Ideograph>) 4347 0x279DD 𧧝 (<CJK Ideograph Extension B>) 4348 0x291A8 𩆨 (<CJK Ideograph Extension B>) 4349 0x5A67 婧 (<CJK Ideograph>) 4350 0x4CB7 䲷 (<CJK Ideograph Extension A>) 4351 0x270AF 𧂯 (<CJK Ideograph Extension B>) 4352 0x289AB 𨦫 (<CJK Ideograph Extension B>) 4353 0x279FD 𧧽 (<CJK Ideograph Extension B>) 4354 0x27A0A 𧨊 (<CJK Ideograph Extension B>) 4355 0x27B0B 𧬋 (<CJK Ideograph Extension B>) 4356 0x27D66 𧵦 (<CJK Ideograph Extension B>) 4357 0x2417A 𤅺 (<CJK Ideograph Extension B>) 4358 0x7B43 筃 (<CJK Ideograph>) 4359 0x797E 祾 (<CJK Ideograph>) 4360 0x28009 𨀉 (<CJK Ideograph Extension B>) 4361 0x6FB5 澵 (<CJK Ideograph>) 4362 0x2A2DF 𪋟 (<CJK Ideograph Extension B>) 4363 0x6A03 樃 (<CJK Ideograph>) 4364 0x28318 𨌘 (<CJK Ideograph Extension B>) 4365 0x53A2 厢 (<CJK Ideograph>) 4366 0x26E07 𦸇 (<CJK Ideograph Extension B>) 4367 0x93BF 鎿 (<CJK Ideograph>) 4368 0x6836 栶 (<CJK Ideograph>) 4369 0x975D 靝 (<CJK Ideograph>) 4370 0x2816F 𨅯 (<CJK Ideograph Extension B>) 4371 0x28023 𨀣 (<CJK Ideograph Extension B>) 4372 0x269B5 𦦵 (<CJK Ideograph Extension B>) 4373 0x213ED 𡏭 (<CJK Ideograph Extension B>) 4374 0x2322F 𣈯 (<CJK Ideograph Extension B>) 4375 0x28048 𨁈 (<CJK Ideograph Extension B>) 4376 0x5D85 嶅 (<CJK Ideograph>) 4377 0x28C30 𨰰 (<CJK Ideograph Extension B>) 4378 0x28083 𨂃 (<CJK Ideograph Extension B>) 4379 0x5715 圕 (<CJK Ideograph>) 4380 0x9823 頣 (<CJK Ideograph>) 4381 0x28949 𨥉 (<CJK Ideograph Extension B>) 4382 0x5DAB 嶫 (<CJK Ideograph>) 4383 0x24988 𤦈 (<CJK Ideograph Extension B>) 4384 0x65BE 斾 (<CJK Ideograph>) 4385 0x69D5 槕 (<CJK Ideograph>) 4386 0x53D2 叒 (<CJK Ideograph>) 4387 0x24AA5 𤪥 (<CJK Ideograph Extension B>) 4388 0x23F81 𣾁 (<CJK Ideograph Extension B>) 4389 0x3C11 㰑 (<CJK Ideograph Extension A>) 4390 0x6736 朶 (<CJK Ideograph>) 4391 0x28090 𨂐 (<CJK Ideograph Extension B>) 4392 0x280F4 𨃴 (<CJK Ideograph Extension B>) 4393 0x2812E 𨄮 (<CJK Ideograph Extension B>) 4394 0x21FA1 𡾡 (<CJK Ideograph Extension B>) 4395 0x2814F 𨅏 (<CJK Ideograph Extension B>) 4396 0x28189 𨆉 (<CJK Ideograph Extension B>) 4397 0x281AF 𨆯 (<CJK Ideograph Extension B>) 4398 0x2821A 𨈚 (<CJK Ideograph Extension B>) 4399 0x28306 𨌆 (<CJK Ideograph Extension B>) 4400 0x2832F 𨌯 (<CJK Ideograph Extension B>) 4401 0x2838A 𨎊 (<CJK Ideograph Extension B>) 4402 0x35CA 㗊 (<CJK Ideograph Extension A>) 4403 0x28468 𨑨 (<CJK Ideograph Extension B>) 4404 0x286AA 𨚪 (<CJK Ideograph Extension B>) 4405 0x48FA 䣺 (<CJK Ideograph Extension A>) 4406 0x63E6 揦 (<CJK Ideograph>) 4407 0x28956 𨥖 (<CJK Ideograph Extension B>) 4408 0x7808 砈 (<CJK Ideograph>) 4409 0x9255 鉕 (<CJK Ideograph>) 4410 0x289B8 𨦸 (<CJK Ideograph Extension B>) 4411 0x43F2 䏲 (<CJK Ideograph Extension A>) 4412 0x289E7 𨧧 (<CJK Ideograph Extension B>) 4413 0x43DF 䏟 (<CJK Ideograph Extension A>) 4414 0x289E8 𨧨 (<CJK Ideograph Extension B>) 4415 0x28B46 𨭆 (<CJK Ideograph Extension B>) 4416 0x28BD4 𨯔 (<CJK Ideograph Extension B>) 4417 0x59F8 姸 (<CJK Ideograph>) 4418 0x28C09 𨰉 (<CJK Ideograph Extension B>) 4419 0x8F0B 輋 (<CJK Ideograph>) 4420 0x28FC5 𨿅 (<CJK Ideograph Extension B>) 4421 0x290EC 𩃬 (<CJK Ideograph Extension B>) 4422 0x7B51 筑 (<CJK Ideograph>) 4423 0x29110 𩄐 (<CJK Ideograph Extension B>) 4424 0x2913C 𩄼 (<CJK Ideograph Extension B>) 4425 0x3DF7 㷷 (<CJK Ideograph Extension A>) 4426 0x2915E 𩅞 (<CJK Ideograph Extension B>) 4427 0x24ACA 𤫊 (<CJK Ideograph Extension B>) 4428 0x8FD0 运 (<CJK Ideograph>) 4429 0x728F 犏 (<CJK Ideograph>) 4430 0x568B 嚋 (<CJK Ideograph>) 4431 0x294E7 𩓧 (<CJK Ideograph Extension B>) 4432 0x295E9 𩗩 (<CJK Ideograph Extension B>) 4433 0x295B0 𩖰 (<CJK Ideograph Extension B>) 4434 0x295B8 𩖸 (<CJK Ideograph Extension B>) 4435 0x29732 𩜲 (<CJK Ideograph Extension B>) 4436 0x298D1 𩣑 (<CJK Ideograph Extension B>) 4437 0x29949 𩥉 (<CJK Ideograph Extension B>) 4438 0x2996A 𩥪 (<CJK Ideograph Extension B>) 4439 0x299C3 𩧃 (<CJK Ideograph Extension B>) 4440 0x29A28 𩨨 (<CJK Ideograph Extension B>) 4441 0x29B0E 𩬎 (<CJK Ideograph Extension B>) 4442 0x29D5A 𩵚 (<CJK Ideograph Extension B>) 4443 0x29D9B 𩶛 (<CJK Ideograph Extension B>) 4444 0x7E9F 纟 (<CJK Ideograph>) 4445 0x29EF8 𩻸 (<CJK Ideograph Extension B>) 4446 0x29F23 𩼣 (<CJK Ideograph Extension B>) 4447 0x4CA4 䲤 (<CJK Ideograph Extension A>) 4448 0x9547 镇 (<CJK Ideograph>) 4449 0x2A293 𪊓 (<CJK Ideograph Extension B>) 4450 0x71A2 熢 (<CJK Ideograph>) 4451 0x2A2FF 𪋿 (<CJK Ideograph Extension B>) 4452 0x4D91 䶑 (<CJK Ideograph Extension A>) 4453 0x9012 递 (<CJK Ideograph>) 4454 0x2A5CB 𪗋 (<CJK Ideograph Extension B>) 4455 0x4D9C 䶜 (<CJK Ideograph Extension A>) 4456 0x20C9C 𠲜 (<CJK Ideograph Extension B>) 4457 0x8FBE 达 (<CJK Ideograph>) 4458 0x55C1 嗁 (<CJK Ideograph>) 4459 0x8FBA 辺 (<CJK Ideograph>) 4460 0x224B0 𢒰 (<CJK Ideograph Extension B>) 4461 0x8FB9 边 (<CJK Ideograph>) 4462 0x24A93 𤪓 (<CJK Ideograph Extension B>) 4463 0x4509 䔉 (<CJK Ideograph Extension A>) 4464 0x7E7F 繿 (<CJK Ideograph>) 4465 0x6F56 潖 (<CJK Ideograph>) 4466 0x6AB1 檱 (<CJK Ideograph>) 4467 0x4EEA 仪 (<CJK Ideograph>) 4468 0x34E4 㓤 (<CJK Ideograph Extension A>) 4469 0x28B2C 𨬬 (<CJK Ideograph Extension B>) 4470 0x2789D 𧢝 (<CJK Ideograph Extension B>) 4471 0x373A 㜺 (<CJK Ideograph Extension A>) 4472 0x8E80 躀 (<CJK Ideograph>) 4473 0x217F5 𡟵 (<CJK Ideograph Extension B>) 4474 0x28024 𨀤 (<CJK Ideograph Extension B>) 4475 0x28B6C 𨭬 (<CJK Ideograph Extension B>) 4476 0x28B99 𨮙 (<CJK Ideograph Extension B>) 4477 0x27A3E 𧨾 (<CJK Ideograph Extension B>) 4478 0x266AF 𦚯 (<CJK Ideograph Extension B>) 4479 0x3DEB 㷫 (<CJK Ideograph Extension A>) 4480 0x27655 𧙕 (<CJK Ideograph Extension B>) 4481 0x23CB7 𣲷 (<CJK Ideograph Extension B>) 4482 0x25635 𥘵 (<CJK Ideograph Extension B>) 4483 0x25956 𥥖 (<CJK Ideograph Extension B>) 4484 0x4E9A 亚 (<CJK Ideograph>) 4485 0x25E81 𥺁 (<CJK Ideograph Extension B>) 4486 0x26258 𦉘 (<CJK Ideograph Extension B>) 4487 0x56BF 嚿 (<CJK Ideograph>) 4488 0x20E6D 𠹭 (<CJK Ideograph Extension B>) 4489 0x8E0E 踎 (<CJK Ideograph>) 4490 0x5B6D 孭 (<CJK Ideograph>) 4491 0x23E88 𣺈 (<CJK Ideograph Extension B>) 4492 0x24C9E 𤲞 (<CJK Ideograph Extension B>) 4493 0x63DE 揞 (<CJK Ideograph>) 4494 0x62D0 拐 (<CJK Ideograph>) 4495 0x217F6 𡟶 (<CJK Ideograph Extension B>) 4496 0x2187B 𡡻 (<CJK Ideograph Extension B>) 4497 0x6530 攰 (<CJK Ideograph>) 4498 0x562D 嘭 (<CJK Ideograph>) 4499 0x25C4A 𥱊 (<CJK Ideograph Extension B>) 4500 0x541A 吚 (<CJK Ideograph>) 4501 0x25311 𥌑 (<CJK Ideograph Extension B>) 4502 0x3DC6 㷆 (<CJK Ideograph Extension A>) 4503 0x29D98 𩶘 (<CJK Ideograph Extension B>) 4504 0x4C7D 䱽 (<CJK Ideograph Extension A>) 4505 0x5622 嘢 (<CJK Ideograph>) 4506 0x561E 嘞 (<CJK Ideograph>) 4507 0x7F49 罉 (<CJK Ideograph>) 4508 0x25ED8 𥻘 (<CJK Ideograph Extension B>) 4509 0x5975 奵 (<CJK Ideograph>) 4510 0x23D40 𣵀 (<CJK Ideograph Extension B>) 4511 0x8770 蝰 (<CJK Ideograph>) 4512 0x4E1C 东 (<CJK Ideograph>) 4513 0x20FEA 𠿪 (<CJK Ideograph Extension B>) 4514 0x20D49 𠵉 (<CJK Ideograph Extension B>) 4515 0x236BA 𣚺 (<CJK Ideograph Extension B>) 4516 0x8117 脗 (<CJK Ideograph>) 4517 0x9D5E 鵞 (<CJK Ideograph>) 4518 0x8D18 贘 (<CJK Ideograph>) 4519 0x763B 瘻 (<CJK Ideograph>) 4520 0x9C45 鱅 (<CJK Ideograph>) 4521 0x764E 癎 (<CJK Ideograph>) 4522 0x77B9 瞹 (<CJK Ideograph>) 4523 0x9345 鍅 (<CJK Ideograph>) 4524 0x5432 吲 (<CJK Ideograph>) 4525 0x8148 腈 (<CJK Ideograph>) 4526 0x82F7 苷 (<CJK Ideograph>) 4527 0x5625 嘥 (<CJK Ideograph>) 4528 0x8132 脲 (<CJK Ideograph>) 4529 0x8418 萘 (<CJK Ideograph>) 4530 0x80BD 肽 (<CJK Ideograph>) 4531 0x55EA 嗪 (<CJK Ideograph>) 4532 0x7962 祢 (<CJK Ideograph>) 4533 0x5643 噃 (<CJK Ideograph>) 4534 0x5416 吖 (<CJK Ideograph>) 4535 0x20E9D 𠺝 (<CJK Ideograph Extension B>) 4536 0x35CE 㗎 (<CJK Ideograph Extension A>) 4537 0x5605 嘅 (<CJK Ideograph>) 4538 0x55F1 嗱 (<CJK Ideograph>) 4539 0x66F1 曱 (<CJK Ideograph>) 4540 0x282E2 𨋢 (<CJK Ideograph Extension B>) 4541 0x362D 㘭 (<CJK Ideograph Extension A>) 4542 0x7534 甴 (<CJK Ideograph>) 4543 0x55F0 嗰 (<CJK Ideograph>) 4544 0x55BA 喺 (<CJK Ideograph>) 4545 0x5497 咗 (<CJK Ideograph>) 4546 0x5572 啲 (<CJK Ideograph>) 4547 0x20C41 𠱁 (<CJK Ideograph Extension B>) 4548 0x20C96 𠲖 (<CJK Ideograph Extension B>) 4549 0x5ED0 廐 (<CJK Ideograph>) 4550 0x25148 𥅈 (<CJK Ideograph Extension B>) 4551 0x20E76 𠹶 (<CJK Ideograph Extension B>) 4552 0x22C62 𢱢 (<CJK Ideograph Extension B>) 4553 0x20EA2 𠺢 (<CJK Ideograph Extension B>) 4554 0x9EAB 麫 (<CJK Ideograph>) 4555 0x7D5A 絚 (<CJK Ideograph>) 4556 0x55DE 嗞 (<CJK Ideograph>) 4557 0x21075 𡁵 (<CJK Ideograph Extension B>) 4558 0x629D 抝 (<CJK Ideograph>) 4559 0x976D 靭 (<CJK Ideograph>) 4560 0x5494 咔 (<CJK Ideograph>) 4561 0x8CCD 賍 (<CJK Ideograph>) 4562 0x71F6 燶 (<CJK Ideograph>) 4563 0x9176 酶 (<CJK Ideograph>) 4564 0x63FC 揼 (<CJK Ideograph>) 4565 0x63B9 掹 (<CJK Ideograph>) 4566 0x63FE 揾 (<CJK Ideograph>) 4567 0x5569 啩 (<CJK Ideograph>) 4568 0x22B43 𢭃 (<CJK Ideograph Extension B>) 4569 0x9C72 鱲 (<CJK Ideograph>) 4570 0x22EB3 𢺳 (<CJK Ideograph Extension B>) 4571 0x519A 冚 (<CJK Ideograph>) 4572 0x34DF 㓟 (<CJK Ideograph Extension A>) 4573 0x20DA7 𠶧 (<CJK Ideograph Extension B>) 4574 0x51A7 冧 (<CJK Ideograph>) 4575 0x544D 呍 (<CJK Ideograph>) 4576 0x551E 唞 (<CJK Ideograph>) 4577 0x5513 唓 (<CJK Ideograph>) 4578 0x7666 癦 (<CJK Ideograph>) 4579 0x8E2D 踭 (<CJK Ideograph>) 4580 0x2688A 𦢊 (<CJK Ideograph Extension B>) 4581 0x75B1 疱 (<CJK Ideograph>) 4582 0x80B6 肶 (<CJK Ideograph>) 4583 0x8804 蠄 (<CJK Ideograph>) 4584 0x8786 螆 (<CJK Ideograph>) 4585 0x88C7 裇 (<CJK Ideograph>) 4586 0x81B6 膶 (<CJK Ideograph>) 4587 0x841C 萜 (<CJK Ideograph>) 4588 0x210C1 𡃁 (<CJK Ideograph Extension B>) 4589 0x44EC 䓬 (<CJK Ideograph Extension A>) 4590 0x7304 猄 (<CJK Ideograph>) 4591 0x24706 𤜆 (<CJK Ideograph Extension B>) 4592 0x5B90 宐 (<CJK Ideograph>) 4593 0x830B 茋 (<CJK Ideograph>) 4594 0x26893 𦢓 (<CJK Ideograph Extension B>) 4595 0x567B 噻 (<CJK Ideograph>) 4596 0x226F4 𢛴 (<CJK Ideograph Extension B>) 4597 0x27D2F 𧴯 (<CJK Ideograph Extension B>) 4598 0x241A3 𤆣 (<CJK Ideograph Extension B>) 4599 0x27D73 𧵳 (<CJK Ideograph Extension B>) 4600 0x26ED0 𦻐 (<CJK Ideograph Extension B>) 4601 0x272B6 𧊶 (<CJK Ideograph Extension B>) 4602 0x9170 酰 (<CJK Ideograph>) 4603 0x211D9 𡇙 (<CJK Ideograph Extension B>) 4604 0x9208 鈈 (<CJK Ideograph>) 4605 0x23CFC 𣳼 (<CJK Ideograph Extension B>) 4606 0x2A6A9 𪚩 (<CJK Ideograph Extension B>) 4607 0x20EAC 𠺬 (<CJK Ideograph Extension B>) 4608 0x20EF9 𠻹 (<CJK Ideograph Extension B>) 4609 0x7266 牦 (<CJK Ideograph>) 4610 0x21CA2 𡲢 (<CJK Ideograph Extension B>) 4611 0x474E 䝎 (<CJK Ideograph Extension A>) 4612 0x24FC2 𤿂 (<CJK Ideograph Extension B>) 4613 0x27FF9 𧿹 (<CJK Ideograph Extension B>) 4614 0x20FEB 𠿫 (<CJK Ideograph Extension B>) 4615 0x40FA 䃺 (<CJK Ideograph Extension A>) 4616 0x9C5D 鱝 (<CJK Ideograph>) 4617 0x651F 攟 (<CJK Ideograph>) 4618 0x22DA0 𢶠 (<CJK Ideograph Extension B>) 4619 0x48F3 䣳 (<CJK Ideograph Extension A>) 4620 0x247E0 𤟠 (<CJK Ideograph Extension B>) 4621 0x29D7C 𩵼 (<CJK Ideograph Extension B>) 4622 0x20FEC 𠿬 (<CJK Ideograph Extension B>) 4623 0x20E0A 𠸊 (<CJK Ideograph Extension B>) 4624 0x6062 恢 (<CJK Ideograph>) 4625 0x275A3 𧖣 (<CJK Ideograph Extension B>) 4626 0x20FED 𠿭 (<CJK Ideograph Extension B>) 4628 0x26048 𦁈 (<CJK Ideograph Extension B>) 4629 0x21187 𡆇 (<CJK Ideograph Extension B>) 4630 0x71A3 熣 (<CJK Ideograph>) 4631 0x7E8E 纎 (<CJK Ideograph>) 4632 0x9D50 鵐 (<CJK Ideograph>) 4633 0x4E1A 业 (<CJK Ideograph>) 4634 0x4E04 丄 (<CJK Ideograph>) 4635 0x3577 㕷 (<CJK Ideograph Extension A>) 4636 0x5B0D 嬍 (<CJK Ideograph>) 4637 0x6CB2 沲 (<CJK Ideograph>) 4638 0x5367 卧 (<CJK Ideograph>) 4639 0x36AC 㚬 (<CJK Ideograph Extension A>) 4640 0x39DC 㧜 (<CJK Ideograph Extension A>) 4641 0x537D 卽 (<CJK Ideograph>) 4642 0x36A5 㚥 (<CJK Ideograph Extension A>) 4643 0x24618 𤘘 (<CJK Ideograph Extension B>) 4644 0x589A 墚 (<CJK Ideograph>) 4645 0x24B6E 𤭮 (<CJK Ideograph Extension B>) 4646 0x822D 舭 (<CJK Ideograph>) 4647 0x544B 呋 (<CJK Ideograph>) 4648 0x57AA 垪 (<CJK Ideograph>) 4649 0x25A95 𥪕 (<CJK Ideograph Extension B>) 4650 0x20979 𠥹 (<CJK Ideograph Extension B>) 4652 0x3A52 㩒 (<CJK Ideograph Extension A>) 4653 0x22465 𢑥 (<CJK Ideograph Extension B>) 4654 0x7374 獴 (<CJK Ideograph>) 4655 0x29EAC 𩺬 (<CJK Ideograph Extension B>) 4656 0x4D09 䴉 (<CJK Ideograph Extension A>) 4657 0x9BED 鯭 (<CJK Ideograph>) 4658 0x23CFE 𣳾 (<CJK Ideograph Extension B>) 4659 0x29F30 𩼰 (<CJK Ideograph Extension B>) 4660 0x4C5B 䱛 (<CJK Ideograph Extension A>) 4661 0x24FA9 𤾩 (<CJK Ideograph Extension B>) 4662 0x2959E 𩖞 (<CJK Ideograph Extension B>) 4663 0x29FDE 𩿞 (<CJK Ideograph Extension B>) 4664 0x845C 葜 (<CJK Ideograph>) 4665 0x23DB6 𣶶 (<CJK Ideograph Extension B>) 4666 0x272B2 𧊲 (<CJK Ideograph Extension B>) 4667 0x267B3 𦞳 (<CJK Ideograph Extension B>) 4668 0x23720 𣜠 (<CJK Ideograph Extension B>) 4669 0x632E 挮 (<CJK Ideograph>) 4670 0x7D25 紥 (<CJK Ideograph>) 4671 0x23EF7 𣻷 (<CJK Ideograph Extension B>) 4672 0x23E2C 𣸬 (<CJK Ideograph Extension B>) 4673 0x3A2A 㨪 (<CJK Ideograph Extension A>) 4674 0x9008 逈 (<CJK Ideograph>) 4675 0x52CC 勌 (<CJK Ideograph>) 4676 0x3E74 㹴 (<CJK Ideograph Extension A>) 4677 0x367A 㙺 (<CJK Ideograph Extension A>) 4678 0x45E9 䗩 (<CJK Ideograph Extension A>) 4679 0x2048E 𠒎 (<CJK Ideograph Extension B>) 4680 0x7640 癀 (<CJK Ideograph>) 4681 0x5AF0 嫰 (<CJK Ideograph>) 4682 0x20EB6 𠺶 (<CJK Ideograph Extension B>) 4683 0x787A 硺 (<CJK Ideograph>) 4684 0x27F2E 𧼮 (<CJK Ideograph Extension B>) 4685 0x58A7 墧 (<CJK Ideograph>) 4686 0x40BF 䂿 (<CJK Ideograph Extension A>) 4687 0x567C 噼 (<CJK Ideograph>) 4688 0x9B8B 鮋 (<CJK Ideograph>) 4689 0x5D74 嵴 (<CJK Ideograph>) 4690 0x7654 癔 (<CJK Ideograph>) 4691 0x2A434 𪐴 (<CJK Ideograph Extension B>) 4692 0x9E85 麅 (<CJK Ideograph>) 4693 0x4CE1 䳡 (<CJK Ideograph Extension A>) 4694 0x75F9 痹 (<CJK Ideograph>) 4695 0x37FB 㟻 (<CJK Ideograph Extension A>) 4696 0x6119 愙 (<CJK Ideograph>) 4697 0x230DA 𣃚 (<CJK Ideograph Extension B>) 4698 0x243F2 𤏲 (<CJK Ideograph Extension B>) 4700 0x565D 噝 (<CJK Ideograph>) 4701 0x212A9 𡊩 (<CJK Ideograph Extension B>) 4702 0x57A7 垧 (<CJK Ideograph>) 4703 0x24963 𤥣 (<CJK Ideograph Extension B>) 4704 0x29E06 𩸆 (<CJK Ideograph Extension B>) 4705 0x5234 刴 (<CJK Ideograph>) 4706 0x270AE 𧂮 (<CJK Ideograph Extension B>) 4707 0x35AD 㖭 (<CJK Ideograph Extension A>) 4708 0x6C4A 汊 (<CJK Ideograph>) 4709 0x9D7C 鵼 (<CJK Ideograph>) 4710 0x7C56 籖 (<CJK Ideograph>) 4711 0x9B39 鬹 (<CJK Ideograph>) 4712 0x57DE 埞 (<CJK Ideograph>) 4713 0x2176C 𡝬 (<CJK Ideograph Extension B>) 4714 0x5C53 屓 (<CJK Ideograph>) 4715 0x64D3 擓 (<CJK Ideograph>) 4716 0x294D0 𩓐 (<CJK Ideograph Extension B>) 4717 0x26335 𦌵 (<CJK Ideograph Extension B>) 4718 0x27164 𧅤 (<CJK Ideograph Extension B>) 4719 0x86AD 蚭 (<CJK Ideograph>) 4720 0x20D28 𠴨 (<CJK Ideograph Extension B>) 4721 0x26D22 𦴢 (<CJK Ideograph Extension B>) 4722 0x24AE2 𤫢 (<CJK Ideograph Extension B>) 4723 0x20D71 𠵱 (<CJK Ideograph Extension B>) 4725 0x51FE 凾 (<CJK Ideograph>) 4726 0x21F0F 𡼏 (<CJK Ideograph Extension B>) 4727 0x5D8E 嶎 (<CJK Ideograph>) 4728 0x9703 霃 (<CJK Ideograph>) 4729 0x21DD1 𡷑 (<CJK Ideograph Extension B>) 4730 0x9E81 麁 (<CJK Ideograph>) 4731 0x904C 遌 (<CJK Ideograph>) 4732 0x7B1F 笟 (<CJK Ideograph>) 4733 0x9B02 鬂 (<CJK Ideograph>) 4734 0x5CD1 峑 (<CJK Ideograph>) 4735 0x7BA3 箣 (<CJK Ideograph>) 4736 0x6268 扨 (<CJK Ideograph>) 4737 0x6335 挵 (<CJK Ideograph>) 4738 0x9AFF 髿 (<CJK Ideograph>) 4739 0x7BCF 篏 (<CJK Ideograph>) 4740 0x9B2A 鬪 (<CJK Ideograph>) 4741 0x7C7E 籾 (<CJK Ideograph>) 4742 0x9B2E 鬮 (<CJK Ideograph>) 4743 0x7C42 籂 (<CJK Ideograph>) 4744 0x7C86 粆 (<CJK Ideograph>) 4745 0x9C15 鰕 (<CJK Ideograph>) 4746 0x7BFC 篼 (<CJK Ideograph>) 4747 0x9B09 鬉 (<CJK Ideograph>) 4748 0x9F17 鼗 (<CJK Ideograph>) 4749 0x9C1B 鰛 (<CJK Ideograph>) 4750 0x2493E 𤤾 (<CJK Ideograph Extension B>) 4751 0x9F5A 齚 (<CJK Ideograph>) 4752 0x5573 啳 (<CJK Ideograph>) 4753 0x5BC3 寃 (<CJK Ideograph>) 4754 0x4FFD 俽 (<CJK Ideograph>) 4755 0x9E98 麘 (<CJK Ideograph>) 4756 0x4FF2 俲 (<CJK Ideograph>) 4757 0x5260 剠 (<CJK Ideograph>) 4758 0x3E06 㸆 (<CJK Ideograph Extension A>) 4759 0x52D1 勑 (<CJK Ideograph>) 4760 0x5767 坧 (<CJK Ideograph>) 4761 0x5056 偖 (<CJK Ideograph>) 4762 0x59B7 妷 (<CJK Ideograph>) 4763 0x5E12 帒 (<CJK Ideograph>) 4764 0x97C8 韈 (<CJK Ideograph>) 4765 0x9DAB 鶫 (<CJK Ideograph>) 4766 0x8F5C 轜 (<CJK Ideograph>) 4767 0x5469 呩 (<CJK Ideograph>) 4768 0x97B4 鞴 (<CJK Ideograph>) 4769 0x9940 饀 (<CJK Ideograph>) 4770 0x97BA 鞺 (<CJK Ideograph>) 4771 0x532C 匬 (<CJK Ideograph>) 4772 0x6130 愰 (<CJK Ideograph>) 4773 0x692C 椬 (<CJK Ideograph>) 4774 0x53DA 叚 (<CJK Ideograph>) 4775 0x9C0A 鰊 (<CJK Ideograph>) 4776 0x9D02 鴂 (<CJK Ideograph>) 4777 0x4C3B 䰻 (<CJK Ideograph Extension A>) 4778 0x9641 陁 (<CJK Ideograph>) 4779 0x6980 榀 (<CJK Ideograph>) 4780 0x50A6 傦 (<CJK Ideograph>) 4781 0x7546 畆 (<CJK Ideograph>) 4782 0x2176D 𡝭 (<CJK Ideograph Extension B>) 4783 0x99DA 駚 (<CJK Ideograph>) 4784 0x5273 剳 (<CJK Ideograph>) 4786 0x9159 酙 (<CJK Ideograph>) 4787 0x9681 隁 (<CJK Ideograph>) 4788 0x915C 酜 (<CJK Ideograph>) 4790 0x9151 酑 (<CJK Ideograph>) 4791 0x28E97 𨺗 (<CJK Ideograph Extension B>) 4792 0x637F 捿 (<CJK Ideograph>) 4793 0x26D23 𦴣 (<CJK Ideograph Extension B>) 4794 0x6ACA 櫊 (<CJK Ideograph>) 4795 0x5611 嘑 (<CJK Ideograph>) 4796 0x918E 醎 (<CJK Ideograph>) 4797 0x757A 畺 (<CJK Ideograph>) 4798 0x6285 抅 (<CJK Ideograph>) 4799 0x203FC 𠏼 (<CJK Ideograph Extension B>) 4800 0x734F 獏 (<CJK Ideograph>) 4801 0x7C70 籰 (<CJK Ideograph>) 4802 0x25C21 𥰡 (<CJK Ideograph Extension B>) 4803 0x23CFD 𣳽 (<CJK Ideograph Extension B>) 4805 0x24919 𤤙 (<CJK Ideograph Extension B>) 4806 0x76D6 盖 (<CJK Ideograph>) 4807 0x9B9D 鮝 (<CJK Ideograph>) 4808 0x4E2A 个 (<CJK Ideograph>) 4809 0x20CD4 𠳔 (<CJK Ideograph Extension B>) 4810 0x83BE 莾 (<CJK Ideograph>) 4811 0x8842 衂 (<CJK Ideograph>) 4813 0x5C4A 届 (<CJK Ideograph>) 4814 0x69C0 槀 (<CJK Ideograph>) 4815 0x50ED 僭 (<CJK Ideograph>) 4816 0x577A 坺 (<CJK Ideograph>) 4817 0x521F 刟 (<CJK Ideograph>) 4818 0x5DF5 巵 (<CJK Ideograph>) 4819 0x4ECE 从 (<CJK Ideograph>) 4820 0x6C31 氱 (<CJK Ideograph>) 4821 0x201F2 𠇲 (<CJK Ideograph Extension B>) 4822 0x4F39 伹 (<CJK Ideograph>) 4823 0x549C 咜 (<CJK Ideograph>) 4824 0x54DA 哚 (<CJK Ideograph>) 4825 0x529A 劚 (<CJK Ideograph>) 4826 0x8D82 趂 (<CJK Ideograph>) 4827 0x35FE 㗾 (<CJK Ideograph Extension A>) 4828 0x5F0C 弌 (<CJK Ideograph>) 4829 0x35F3 㗳 (<CJK Ideograph Extension A>) 4831 0x6B52 歒 (<CJK Ideograph>) 4832 0x917C 酼 (<CJK Ideograph>) 4833 0x9FA5 龥 (<CJK Ideograph>) 4834 0x9B97 鮗 (<CJK Ideograph>) 4835 0x982E 頮 (<CJK Ideograph>) 4836 0x98B4 颴 (<CJK Ideograph>) 4837 0x9ABA 骺 (<CJK Ideograph>) 4838 0x9EA8 麨 (<CJK Ideograph>) 4839 0x9E84 麄 (<CJK Ideograph>) 4840 0x717A 煺 (<CJK Ideograph>) 4841 0x7B14 笔 (<CJK Ideograph>) 4843 0x6BFA 毺 (<CJK Ideograph>) 4844 0x8818 蠘 (<CJK Ideograph>) 4845 0x7F78 罸 (<CJK Ideograph>) 4847 0x5620 嘠 (<CJK Ideograph>) 4848 0x2A64A 𪙊 (<CJK Ideograph Extension B>) 4849 0x8E77 蹷 (<CJK Ideograph>) 4850 0x9F53 齓 (<CJK Ideograph>) 4852 0x8DD4 跔 (<CJK Ideograph>) 4853 0x8E4F 蹏 (<CJK Ideograph>) 4854 0x9E1C 鸜 (<CJK Ideograph>) 4855 0x8E01 踁 (<CJK Ideograph>) 4856 0x6282 抂 (<CJK Ideograph>) 4857 0x2837D 𨍽 (<CJK Ideograph Extension B>) 4858 0x8E28 踨 (<CJK Ideograph>) 4859 0x8E75 蹵 (<CJK Ideograph>) 4860 0x7AD3 竓 (<CJK Ideograph>) 4861 0x24A77 𤩷 (<CJK Ideograph Extension B>) 4862 0x7A3E 稾 (<CJK Ideograph>) 4863 0x78D8 磘 (<CJK Ideograph>) 4864 0x6CEA 泪 (<CJK Ideograph>) 4865 0x8A67 詧 (<CJK Ideograph>) 4866 0x7607 瘇 (<CJK Ideograph>) 4867 0x28A5A 𨩚 (<CJK Ideograph Extension B>) 4868 0x9F26 鼦 (<CJK Ideograph>) 4869 0x6CCE 泎 (<CJK Ideograph>) 4870 0x87D6 蟖 (<CJK Ideograph>) 4871 0x75C3 痃 (<CJK Ideograph>) 4872 0x2A2B2 𪊲 (<CJK Ideograph Extension B>) 4873 0x7853 硓 (<CJK Ideograph>) 4874 0x2F840 咢 (CJK COMPATIBILITY IDEOGRAPH-2F840) 4875 0x8D0C 贌 (<CJK Ideograph>) 4876 0x72E2 狢 (<CJK Ideograph>) 4877 0x7371 獱 (<CJK Ideograph>) 4878 0x8B2D 謭 (<CJK Ideograph>) 4879 0x7302 猂 (<CJK Ideograph>) 4880 0x74F1 瓱 (<CJK Ideograph>) 4881 0x8CEB 賫 (<CJK Ideograph>) 4882 0x24ABB 𤪻 (<CJK Ideograph Extension B>) 4883 0x862F 蘯 (<CJK Ideograph>) 4884 0x5FBA 徺 (<CJK Ideograph>) 4885 0x88A0 袠 (<CJK Ideograph>) 4886 0x44B7 䒷 (<CJK Ideograph Extension A>) 4888 0x2183B 𡠻 (<CJK Ideograph Extension B>) 4889 0x26E05 𦸅 (<CJK Ideograph Extension B>) 4891 0x8A7E 詾 (<CJK Ideograph>) 4892 0x2251B 𢔛 (<CJK Ideograph Extension B>) 4894 0x60FD 惽 (<CJK Ideograph>) 4895 0x7667 癧 (<CJK Ideograph>) 4896 0x9AD7 髗 (<CJK Ideograph>) 4897 0x9D44 鵄 (<CJK Ideograph>) 4898 0x936E 鍮 (<CJK Ideograph>) 4899 0x9B8F 鮏 (<CJK Ideograph>) 4900 0x87F5 蟵 (<CJK Ideograph>) 4902 0x880F 蠏 (<CJK Ideograph>) 4903 0x8CF7 賷 (<CJK Ideograph>) 4904 0x732C 猬 (<CJK Ideograph>) 4905 0x9721 霡 (<CJK Ideograph>) 4906 0x9BB0 鮰 (<CJK Ideograph>) 4907 0x35D6 㗖 (<CJK Ideograph Extension A>) 4908 0x72B2 犲 (<CJK Ideograph>) 4909 0x4C07 䰇 (<CJK Ideograph Extension A>) 4910 0x7C51 籑 (<CJK Ideograph>) 4911 0x994A 饊 (<CJK Ideograph>) 4912 0x26159 𦅙 (<CJK Ideograph Extension B>) 4913 0x6159 慙 (<CJK Ideograph>) 4914 0x4C04 䰄 (<CJK Ideograph Extension A>) 4915 0x9E96 麖 (<CJK Ideograph>) 4916 0x617D 慽 (<CJK Ideograph>) 4918 0x575F 坟 (<CJK Ideograph>) 4919 0x616F 慯 (<CJK Ideograph>) 4920 0x62A6 抦 (<CJK Ideograph>) 4921 0x6239 戹 (<CJK Ideograph>) 4922 0x62CE 拎 (<CJK Ideograph>) 4923 0x3A5C 㩜 (<CJK Ideograph Extension A>) 4924 0x61E2 懢 (<CJK Ideograph>) 4925 0x53AA 厪 (<CJK Ideograph>) 4926 0x233F5 𣏵 (<CJK Ideograph Extension B>) 4927 0x6364 捤 (<CJK Ideograph>) 4928 0x6802 栂 (<CJK Ideograph>) 4929 0x35D2 㗒 (<CJK Ideograph Extension A>) 4930 0x5D57 嵗 (<CJK Ideograph>) 4931 0x28BC2 𨯂 (<CJK Ideograph Extension B>) 4932 0x8FDA 迚 (<CJK Ideograph>) 4933 0x28E39 𨸹 (<CJK Ideograph Extension B>) 4935 0x50D9 僙 (<CJK Ideograph>) 4936 0x21D46 𡵆 (<CJK Ideograph Extension B>) 4937 0x7906 礆 (<CJK Ideograph>) 4938 0x5332 匲 (<CJK Ideograph>) 4939 0x9638 阸 (<CJK Ideograph>) 4940 0x20F3B 𠼻 (<CJK Ideograph Extension B>) 4941 0x4065 䁥 (<CJK Ideograph Extension A>) 4943 0x77FE 矾 (<CJK Ideograph>) 4945 0x7CC2 糂 (<CJK Ideograph>) 4946 0x25F1A 𥼚 (<CJK Ideograph Extension B>) 4947 0x7CDA 糚 (<CJK Ideograph>) 4948 0x7A2D 稭 (<CJK Ideograph>) 4949 0x8066 聦 (<CJK Ideograph>) 4950 0x8063 聣 (<CJK Ideograph>) 4951 0x7D4D 絍 (<CJK Ideograph>) 4952 0x7505 甅 (<CJK Ideograph>) 4953 0x74F2 瓲 (<CJK Ideograph>) 4954 0x8994 覔 (<CJK Ideograph>) 4955 0x821A 舚 (<CJK Ideograph>) 4956 0x670C 朌 (<CJK Ideograph>) 4957 0x8062 聢 (<CJK Ideograph>) 4958 0x27486 𧒆 (<CJK Ideograph Extension B>) 4959 0x805B 聛 (<CJK Ideograph>) 4960 0x74F0 瓰 (<CJK Ideograph>) 4961 0x8103 脃 (<CJK Ideograph>) 4962 0x7724 眤 (<CJK Ideograph>) 4963 0x8989 覉 (<CJK Ideograph>) 4964 0x267CC 𦟌 (<CJK Ideograph Extension B>) 4965 0x7553 畓 (<CJK Ideograph>) 4966 0x26ED1 𦻑 (<CJK Ideograph Extension B>) 4967 0x87A9 螩 (<CJK Ideograph>) 4968 0x87CE 蟎 (<CJK Ideograph>) 4969 0x81C8 臈 (<CJK Ideograph>) 4970 0x878C 螌 (<CJK Ideograph>) 4971 0x8A49 詉 (<CJK Ideograph>) 4972 0x8CAD 貭 (<CJK Ideograph>) 4973 0x8B43 譃 (<CJK Ideograph>) 4974 0x772B 眫 (<CJK Ideograph>) 4975 0x74F8 瓸 (<CJK Ideograph>) 4976 0x84DA 蓚 (<CJK Ideograph>) 4977 0x3635 㘵 (<CJK Ideograph Extension A>) 4978 0x69B2 榲 (<CJK Ideograph>) 4979 0x8DA6 趦 (<CJK Ideograph>) 4981 0x89A9 覩 (<CJK Ideograph>) 4982 0x7468 瑨 (<CJK Ideograph>) 4983 0x6DB9 涹 (<CJK Ideograph>) 4984 0x87C1 蟁 (<CJK Ideograph>) 4985 0x24011 𤀑 (<CJK Ideograph Extension B>) 4986 0x74E7 瓧 (<CJK Ideograph>) 4987 0x3DDB 㷛 (<CJK Ideograph Extension A>) 4988 0x7176 煶 (<CJK Ideograph>) 4989 0x60A4 悤 (<CJK Ideograph>) 4990 0x619C 憜 (<CJK Ideograph>) 4991 0x3CD1 㳑 (<CJK Ideograph Extension A>) 4992 0x7162 煢 (<CJK Ideograph>) 4993 0x6077 恷 (<CJK Ideograph>) 4995 0x7F71 罱 (<CJK Ideograph>) 4996 0x28B2D 𨬭 (<CJK Ideograph Extension B>) 4997 0x7250 牐 (<CJK Ideograph>) 4998 0x60E9 惩 (<CJK Ideograph>) 4999 0x4B7E 䭾 (<CJK Ideograph Extension A>) 5000 0x5220 删 (<CJK Ideograph>) 5001 0x3C18 㰘 (<CJK Ideograph Extension A>) 5002 0x23CC7 𣳇 (<CJK Ideograph Extension B>) 5003 0x25ED7 𥻗 (<CJK Ideograph Extension B>) 5004 0x27656 𧙖 (<CJK Ideograph Extension B>) 5005 0x25531 𥔱 (<CJK Ideograph Extension B>) 5006 0x21944 𡥄 (<CJK Ideograph Extension B>) 5007 0x212FE 𡋾 (<CJK Ideograph Extension B>) 5008 0x29903 𩤃 (<CJK Ideograph Extension B>) 5009 0x26DDC 𦷜 (<CJK Ideograph Extension B>) 5010 0x270AD 𧂭 (<CJK Ideograph Extension B>) 5011 0x5CC1 峁 (<CJK Ideograph>) 5012 0x261AD 𦆭 (<CJK Ideograph Extension B>) 5013 0x28A0F 𨨏 (<CJK Ideograph Extension B>) 5014 0x23677 𣙷 (<CJK Ideograph Extension B>) 5015 0x200EE 𠃮 (<CJK Ideograph Extension B>) 5016 0x26846 𦡆 (<CJK Ideograph Extension B>) 5017 0x24F0E 𤼎 (<CJK Ideograph Extension B>) 5018 0x4562 䕢 (<CJK Ideograph Extension A>) 5019 0x5B1F 嬟 (<CJK Ideograph>) 5020 0x2634C 𦍌 (<CJK Ideograph Extension B>) 5021 0x9F50 齐 (<CJK Ideograph>) 5022 0x9EA6 麦 (<CJK Ideograph>) 5023 0x2626B 𦉫 (<CJK Ideograph Extension B>) 5024 0x3000   (IDEOGRAPHIC SPACE) 5025 0xFF0C , (FULLWIDTH COMMA) 5026 0x3001 、 (IDEOGRAPHIC COMMA) 5027 0x3002 。 (IDEOGRAPHIC FULL STOP) 5028 0xFF0E . (FULLWIDTH FULL STOP) 5029 0x2027 ‧ (HYPHENATION POINT) 5030 0xFF1B ; (FULLWIDTH SEMICOLON) 5031 0xFF1A : (FULLWIDTH COLON) 5032 0xFF1F ? (FULLWIDTH QUESTION MARK) 5033 0xFF01 ! (FULLWIDTH EXCLAMATION MARK) 5034 0xFE30 ︰ (PRESENTATION FORM FOR VERTICAL TWO DOT LEADER) 5035 0x2026 … (HORIZONTAL ELLIPSIS) 5036 0x2025 ‥ (TWO DOT LEADER) 5037 0xFE50 ﹐ (SMALL COMMA) 5038 0xFE51 ﹑ (SMALL IDEOGRAPHIC COMMA) 5039 0xFE52 ﹒ (SMALL FULL STOP) 5040 0x00B7 · (MIDDLE DOT) 5041 0xFE54 ﹔ (SMALL SEMICOLON) 5042 0xFE55 ﹕ (SMALL COLON) 5043 0xFE56 ﹖ (SMALL QUESTION MARK) 5044 0xFE57 ﹗ (SMALL EXCLAMATION MARK) 5045 0xFF5C | (FULLWIDTH VERTICAL LINE) 5046 0x2013 – (EN DASH) 5047 0xFE31 ︱ (PRESENTATION FORM FOR VERTICAL EM DASH) 5048 0x2014 — (EM DASH) 5049 0xFE33 ︳ (PRESENTATION FORM FOR VERTICAL LOW LINE) 5050 0x2574 ╴ (BOX DRAWINGS LIGHT LEFT) 5051 0xFE34 ︴ (PRESENTATION FORM FOR VERTICAL WAVY LOW LINE) 5052 0xFE4F ﹏ (WAVY LOW LINE) 5053 0xFF08 ( (FULLWIDTH LEFT PARENTHESIS) 5054 0xFF09 ) (FULLWIDTH RIGHT PARENTHESIS) 5055 0xFE35 ︵ (PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS) 5056 0xFE36 ︶ (PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS) 5057 0xFF5B { (FULLWIDTH LEFT CURLY BRACKET) 5058 0xFF5D } (FULLWIDTH RIGHT CURLY BRACKET) 5059 0xFE37 ︷ (PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET) 5060 0xFE38 ︸ (PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET) 5061 0x3014 〔 (LEFT TORTOISE SHELL BRACKET) 5062 0x3015 〕 (RIGHT TORTOISE SHELL BRACKET) 5063 0xFE39 ︹ (PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET) 5064 0xFE3A ︺ (PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET) 5065 0x3010 【 (LEFT BLACK LENTICULAR BRACKET) 5066 0x3011 】 (RIGHT BLACK LENTICULAR BRACKET) 5067 0xFE3B ︻ (PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET) 5068 0xFE3C ︼ (PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET) 5069 0x300A 《 (LEFT DOUBLE ANGLE BRACKET) 5070 0x300B 》 (RIGHT DOUBLE ANGLE BRACKET) 5071 0xFE3D ︽ (PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET) 5072 0xFE3E ︾ (PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET) 5073 0x3008 〈 (LEFT ANGLE BRACKET) 5074 0x3009 〉 (RIGHT ANGLE BRACKET) 5075 0xFE3F ︿ (PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET) 5076 0xFE40 ﹀ (PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET) 5077 0x300C 「 (LEFT CORNER BRACKET) 5078 0x300D 」 (RIGHT CORNER BRACKET) 5079 0xFE41 ﹁ (PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET) 5080 0xFE42 ﹂ (PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET) 5081 0x300E 『 (LEFT WHITE CORNER BRACKET) 5082 0x300F 』 (RIGHT WHITE CORNER BRACKET) 5083 0xFE43 ﹃ (PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET) 5084 0xFE44 ﹄ (PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET) 5085 0xFE59 ﹙ (SMALL LEFT PARENTHESIS) 5086 0xFE5A ﹚ (SMALL RIGHT PARENTHESIS) 5087 0xFE5B ﹛ (SMALL LEFT CURLY BRACKET) 5088 0xFE5C ﹜ (SMALL RIGHT CURLY BRACKET) 5089 0xFE5D ﹝ (SMALL LEFT TORTOISE SHELL BRACKET) 5090 0xFE5E ﹞ (SMALL RIGHT TORTOISE SHELL BRACKET) 5091 0x2018 ‘ (LEFT SINGLE QUOTATION MARK) 5092 0x2019 ’ (RIGHT SINGLE QUOTATION MARK) 5093 0x201C “ (LEFT DOUBLE QUOTATION MARK) 5094 0x201D ” (RIGHT DOUBLE QUOTATION MARK) 5095 0x301D 〝 (REVERSED DOUBLE PRIME QUOTATION MARK) 5096 0x301E 〞 (DOUBLE PRIME QUOTATION MARK) 5097 0x2035 ‵ (REVERSED PRIME) 5098 0x2032 ′ (PRIME) 5099 0xFF03 # (FULLWIDTH NUMBER SIGN) 5100 0xFF06 & (FULLWIDTH AMPERSAND) 5101 0xFF0A * (FULLWIDTH ASTERISK) 5102 0x203B ※ (REFERENCE MARK) 5103 0x00A7 § (SECTION SIGN) 5104 0x3003 〃 (DITTO MARK) 5105 0x25CB ○ (WHITE CIRCLE) 5106 0x25CF ● (BLACK CIRCLE) 5107 0x25B3 △ (WHITE UP-POINTING TRIANGLE) 5108 0x25B2 ▲ (BLACK UP-POINTING TRIANGLE) 5109 0x25CE ◎ (BULLSEYE) 5110 0x2606 ☆ (WHITE STAR) 5111 0x2605 ★ (BLACK STAR) 5112 0x25C7 ◇ (WHITE DIAMOND) 5113 0x25C6 ◆ (BLACK DIAMOND) 5114 0x25A1 □ (WHITE SQUARE) 5115 0x25A0 ■ (BLACK SQUARE) 5116 0x25BD ▽ (WHITE DOWN-POINTING TRIANGLE) 5117 0x25BC ▼ (BLACK DOWN-POINTING TRIANGLE) 5118 0x32A3 ㊣ (CIRCLED IDEOGRAPH CORRECT) 5119 0x2105 ℅ (CARE OF) 5120 0x00AF ¯ (MACRON) 5121 0xFFE3  ̄ (FULLWIDTH MACRON) 5122 0xFF3F _ (FULLWIDTH LOW LINE) 5123 0x02CD ˍ (MODIFIER LETTER LOW MACRON) 5124 0xFE49 ﹉ (DASHED OVERLINE) 5125 0xFE4A ﹊ (CENTRELINE OVERLINE) 5126 0xFE4D ﹍ (DASHED LOW LINE) 5127 0xFE4E ﹎ (CENTRELINE LOW LINE) 5128 0xFE4B ﹋ (WAVY OVERLINE) 5129 0xFE4C ﹌ (DOUBLE WAVY OVERLINE) 5130 0xFE5F ﹟ (SMALL NUMBER SIGN) 5131 0xFE60 ﹠ (SMALL AMPERSAND) 5132 0xFE61 ﹡ (SMALL ASTERISK) 5133 0xFF0B + (FULLWIDTH PLUS SIGN) 5134 0xFF0D - (FULLWIDTH HYPHEN-MINUS) 5135 0x00D7 × (MULTIPLICATION SIGN) 5136 0x00F7 ÷ (DIVISION SIGN) 5137 0x00B1 ± (PLUS-MINUS SIGN) 5138 0x221A √ (SQUARE ROOT) 5139 0xFF1C < (FULLWIDTH LESS-THAN SIGN) 5140 0xFF1E > (FULLWIDTH GREATER-THAN SIGN) 5141 0xFF1D = (FULLWIDTH EQUALS SIGN) 5142 0x2266 ≦ (LESS-THAN OVER EQUAL TO) 5143 0x2267 ≧ (GREATER-THAN OVER EQUAL TO) 5144 0x2260 ≠ (NOT EQUAL TO) 5145 0x221E ∞ (INFINITY) 5146 0x2252 ≒ (APPROXIMATELY EQUAL TO OR THE IMAGE OF) 5147 0x2261 ≡ (IDENTICAL TO) 5148 0xFE62 ﹢ (SMALL PLUS SIGN) 5149 0xFE63 ﹣ (SMALL HYPHEN-MINUS) 5150 0xFE64 ﹤ (SMALL LESS-THAN SIGN) 5151 0xFE65 ﹥ (SMALL GREATER-THAN SIGN) 5152 0xFE66 ﹦ (SMALL EQUALS SIGN) 5153 0xFF5E ~ (FULLWIDTH TILDE) 5154 0x2229 ∩ (INTERSECTION) 5155 0x222A ∪ (UNION) 5156 0x22A5 ⊥ (UP TACK) 5157 0x2220 ∠ (ANGLE) 5158 0x221F ∟ (RIGHT ANGLE) 5159 0x22BF ⊿ (RIGHT TRIANGLE) 5160 0x33D2 ㏒ (SQUARE LOG) 5161 0x33D1 ㏑ (SQUARE LN) 5162 0x222B ∫ (INTEGRAL) 5163 0x222E ∮ (CONTOUR INTEGRAL) 5164 0x2235 ∵ (BECAUSE) 5165 0x2234 ∴ (THEREFORE) 5166 0x2640 ♀ (FEMALE SIGN) 5167 0x2642 ♂ (MALE SIGN) 5168 0x2295 ⊕ (CIRCLED PLUS) 5169 0x2299 ⊙ (CIRCLED DOT OPERATOR) 5170 0x2191 ↑ (UPWARDS ARROW) 5171 0x2193 ↓ (DOWNWARDS ARROW) 5172 0x2190 ← (LEFTWARDS ARROW) 5173 0x2192 → (RIGHTWARDS ARROW) 5174 0x2196 ↖ (NORTH WEST ARROW) 5175 0x2197 ↗ (NORTH EAST ARROW) 5176 0x2199 ↙ (SOUTH WEST ARROW) 5177 0x2198 ↘ (SOUTH EAST ARROW) 5178 0x2225 ∥ (PARALLEL TO) 5179 0x2223 ∣ (DIVIDES) 5180 0xFF0F / (FULLWIDTH SOLIDUS) 5181 0xFF3C \ (FULLWIDTH REVERSE SOLIDUS) 5182 0x2215 ∕ (DIVISION SLASH) 5183 0xFE68 ﹨ (SMALL REVERSE SOLIDUS) 5184 0xFF04 $ (FULLWIDTH DOLLAR SIGN) 5185 0xFFE5 ¥ (FULLWIDTH YEN SIGN) 5186 0x3012 〒 (POSTAL MARK) 5187 0xFFE0 ¢ (FULLWIDTH CENT SIGN) 5188 0xFFE1 £ (FULLWIDTH POUND SIGN) 5189 0xFF05 % (FULLWIDTH PERCENT SIGN) 5190 0xFF20 @ (FULLWIDTH COMMERCIAL AT) 5191 0x2103 ℃ (DEGREE CELSIUS) 5192 0x2109 ℉ (DEGREE FAHRENHEIT) 5193 0xFE69 ﹩ (SMALL DOLLAR SIGN) 5194 0xFE6A ﹪ (SMALL PERCENT SIGN) 5195 0xFE6B ﹫ (SMALL COMMERCIAL AT) 5196 0x33D5 ㏕ (SQUARE MIL) 5197 0x339C ㎜ (SQUARE MM) 5198 0x339D ㎝ (SQUARE CM) 5199 0x339E ㎞ (SQUARE KM) 5200 0x33CE ㏎ (SQUARE KM CAPITAL) 5201 0x33A1 ㎡ (SQUARE M SQUARED) 5202 0x338E ㎎ (SQUARE MG) 5203 0x338F ㎏ (SQUARE KG) 5204 0x33C4 ㏄ (SQUARE CC) 5205 0x00B0 ° (DEGREE SIGN) 5206 0x5159 兙 (<CJK Ideograph>) 5207 0x515B 兛 (<CJK Ideograph>) 5208 0x515E 兞 (<CJK Ideograph>) 5209 0x515D 兝 (<CJK Ideograph>) 5210 0x5161 兡 (<CJK Ideograph>) 5211 0x5163 兣 (<CJK Ideograph>) 5212 0x55E7 嗧 (<CJK Ideograph>) 5213 0x74E9 瓩 (<CJK Ideograph>) 5214 0x7CCE 糎 (<CJK Ideograph>) 5215 0x2581 ▁ (LOWER ONE EIGHTH BLOCK) 5216 0x2582 ▂ (LOWER ONE QUARTER BLOCK) 5217 0x2583 ▃ (LOWER THREE EIGHTHS BLOCK) 5218 0x2584 ▄ (LOWER HALF BLOCK) 5219 0x2585 ▅ (LOWER FIVE EIGHTHS BLOCK) 5220 0x2586 ▆ (LOWER THREE QUARTERS BLOCK) 5221 0x2587 ▇ (LOWER SEVEN EIGHTHS BLOCK) 5222 0x2588 █ (FULL BLOCK) 5223 0x258F ▏ (LEFT ONE EIGHTH BLOCK) 5224 0x258E ▎ (LEFT ONE QUARTER BLOCK) 5225 0x258D ▍ (LEFT THREE EIGHTHS BLOCK) 5226 0x258C ▌ (LEFT HALF BLOCK) 5227 0x258B ▋ (LEFT FIVE EIGHTHS BLOCK) 5228 0x258A ▊ (LEFT THREE QUARTERS BLOCK) 5229 0x2589 ▉ (LEFT SEVEN EIGHTHS BLOCK) 5230 0x253C ┼ (BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL) 5231 0x2534 ┴ (BOX DRAWINGS LIGHT UP AND HORIZONTAL) 5232 0x252C ┬ (BOX DRAWINGS LIGHT DOWN AND HORIZONTAL) 5233 0x2524 ┤ (BOX DRAWINGS LIGHT VERTICAL AND LEFT) 5234 0x251C ├ (BOX DRAWINGS LIGHT VERTICAL AND RIGHT) 5235 0x2594 ▔ (UPPER ONE EIGHTH BLOCK) 5236 0x2500 ─ (BOX DRAWINGS LIGHT HORIZONTAL) 5237 0x2502 │ (BOX DRAWINGS LIGHT VERTICAL) 5238 0x2595 ▕ (RIGHT ONE EIGHTH BLOCK) 5239 0x250C ┌ (BOX DRAWINGS LIGHT DOWN AND RIGHT) 5240 0x2510 ┐ (BOX DRAWINGS LIGHT DOWN AND LEFT) 5241 0x2514 └ (BOX DRAWINGS LIGHT UP AND RIGHT) 5242 0x2518 ┘ (BOX DRAWINGS LIGHT UP AND LEFT) 5243 0x256D ╭ (BOX DRAWINGS LIGHT ARC DOWN AND RIGHT) 5244 0x256E ╮ (BOX DRAWINGS LIGHT ARC DOWN AND LEFT) 5245 0x2570 ╰ (BOX DRAWINGS LIGHT ARC UP AND RIGHT) 5246 0x256F ╯ (BOX DRAWINGS LIGHT ARC UP AND LEFT) 5247 0x2550 ═ (BOX DRAWINGS DOUBLE HORIZONTAL) 5248 0x255E ╞ (BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE) 5249 0x256A ╪ (BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE) 5250 0x2561 ╡ (BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE) 5251 0x25E2 ◢ (BLACK LOWER RIGHT TRIANGLE) 5252 0x25E3 ◣ (BLACK LOWER LEFT TRIANGLE) 5253 0x25E5 ◥ (BLACK UPPER RIGHT TRIANGLE) 5254 0x25E4 ◤ (BLACK UPPER LEFT TRIANGLE) 5255 0x2571 ╱ (BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT) 5256 0x2572 ╲ (BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT) 5257 0x2573 ╳ (BOX DRAWINGS LIGHT DIAGONAL CROSS) 5258 0xFF10 0 (FULLWIDTH DIGIT ZERO) 5259 0xFF11 1 (FULLWIDTH DIGIT ONE) 5260 0xFF12 2 (FULLWIDTH DIGIT TWO) 5261 0xFF13 3 (FULLWIDTH DIGIT THREE) 5262 0xFF14 4 (FULLWIDTH DIGIT FOUR) 5263 0xFF15 5 (FULLWIDTH DIGIT FIVE) 5264 0xFF16 6 (FULLWIDTH DIGIT SIX) 5265 0xFF17 7 (FULLWIDTH DIGIT SEVEN) 5266 0xFF18 8 (FULLWIDTH DIGIT EIGHT) 5267 0xFF19 9 (FULLWIDTH DIGIT NINE) 5268 0x2160 Ⅰ (ROMAN NUMERAL ONE) 5269 0x2161 Ⅱ (ROMAN NUMERAL TWO) 5270 0x2162 Ⅲ (ROMAN NUMERAL THREE) 5271 0x2163 Ⅳ (ROMAN NUMERAL FOUR) 5272 0x2164 Ⅴ (ROMAN NUMERAL FIVE) 5273 0x2165 Ⅵ (ROMAN NUMERAL SIX) 5274 0x2166 Ⅶ (ROMAN NUMERAL SEVEN) 5275 0x2167 Ⅷ (ROMAN NUMERAL EIGHT) 5276 0x2168 Ⅸ (ROMAN NUMERAL NINE) 5277 0x2169 Ⅹ (ROMAN NUMERAL TEN) 5278 0x3021 〡 (HANGZHOU NUMERAL ONE) 5279 0x3022 〢 (HANGZHOU NUMERAL TWO) 5280 0x3023 〣 (HANGZHOU NUMERAL THREE) 5281 0x3024 〤 (HANGZHOU NUMERAL FOUR) 5282 0x3025 〥 (HANGZHOU NUMERAL FIVE) 5283 0x3026 〦 (HANGZHOU NUMERAL SIX) 5284 0x3027 〧 (HANGZHOU NUMERAL SEVEN) 5285 0x3028 〨 (HANGZHOU NUMERAL EIGHT) 5286 0x3029 〩 (HANGZHOU NUMERAL NINE) 5287 0x5341 十 (<CJK Ideograph>) 5288 0x5344 卄 (<CJK Ideograph>) 5289 0x5345 卅 (<CJK Ideograph>) 5290 0xFF21 A (FULLWIDTH LATIN CAPITAL LETTER A) 5291 0xFF22 B (FULLWIDTH LATIN CAPITAL LETTER B) 5292 0xFF23 C (FULLWIDTH LATIN CAPITAL LETTER C) 5293 0xFF24 D (FULLWIDTH LATIN CAPITAL LETTER D) 5294 0xFF25 E (FULLWIDTH LATIN CAPITAL LETTER E) 5295 0xFF26 F (FULLWIDTH LATIN CAPITAL LETTER F) 5296 0xFF27 G (FULLWIDTH LATIN CAPITAL LETTER G) 5297 0xFF28 H (FULLWIDTH LATIN CAPITAL LETTER H) 5298 0xFF29 I (FULLWIDTH LATIN CAPITAL LETTER I) 5299 0xFF2A J (FULLWIDTH LATIN CAPITAL LETTER J) 5300 0xFF2B K (FULLWIDTH LATIN CAPITAL LETTER K) 5301 0xFF2C L (FULLWIDTH LATIN CAPITAL LETTER L) 5302 0xFF2D M (FULLWIDTH LATIN CAPITAL LETTER M) 5303 0xFF2E N (FULLWIDTH LATIN CAPITAL LETTER N) 5304 0xFF2F O (FULLWIDTH LATIN CAPITAL LETTER O) 5305 0xFF30 P (FULLWIDTH LATIN CAPITAL LETTER P) 5306 0xFF31 Q (FULLWIDTH LATIN CAPITAL LETTER Q) 5307 0xFF32 R (FULLWIDTH LATIN CAPITAL LETTER R) 5308 0xFF33 S (FULLWIDTH LATIN CAPITAL LETTER S) 5309 0xFF34 T (FULLWIDTH LATIN CAPITAL LETTER T) 5310 0xFF35 U (FULLWIDTH LATIN CAPITAL LETTER U) 5311 0xFF36 V (FULLWIDTH LATIN CAPITAL LETTER V) 5312 0xFF37 W (FULLWIDTH LATIN CAPITAL LETTER W) 5313 0xFF38 X (FULLWIDTH LATIN CAPITAL LETTER X) 5314 0xFF39 Y (FULLWIDTH LATIN CAPITAL LETTER Y) 5315 0xFF3A Z (FULLWIDTH LATIN CAPITAL LETTER Z) 5316 0xFF41 a (FULLWIDTH LATIN SMALL LETTER A) 5317 0xFF42 b (FULLWIDTH LATIN SMALL LETTER B) 5318 0xFF43 c (FULLWIDTH LATIN SMALL LETTER C) 5319 0xFF44 d (FULLWIDTH LATIN SMALL LETTER D) 5320 0xFF45 e (FULLWIDTH LATIN SMALL LETTER E) 5321 0xFF46 f (FULLWIDTH LATIN SMALL LETTER F) 5322 0xFF47 g (FULLWIDTH LATIN SMALL LETTER G) 5323 0xFF48 h (FULLWIDTH LATIN SMALL LETTER H) 5324 0xFF49 i (FULLWIDTH LATIN SMALL LETTER I) 5325 0xFF4A j (FULLWIDTH LATIN SMALL LETTER J) 5326 0xFF4B k (FULLWIDTH LATIN SMALL LETTER K) 5327 0xFF4C l (FULLWIDTH LATIN SMALL LETTER L) 5328 0xFF4D m (FULLWIDTH LATIN SMALL LETTER M) 5329 0xFF4E n (FULLWIDTH LATIN SMALL LETTER N) 5330 0xFF4F o (FULLWIDTH LATIN SMALL LETTER O) 5331 0xFF50 p (FULLWIDTH LATIN SMALL LETTER P) 5332 0xFF51 q (FULLWIDTH LATIN SMALL LETTER Q) 5333 0xFF52 r (FULLWIDTH LATIN SMALL LETTER R) 5334 0xFF53 s (FULLWIDTH LATIN SMALL LETTER S) 5335 0xFF54 t (FULLWIDTH LATIN SMALL LETTER T) 5336 0xFF55 u (FULLWIDTH LATIN SMALL LETTER U) 5337 0xFF56 v (FULLWIDTH LATIN SMALL LETTER V) 5338 0xFF57 w (FULLWIDTH LATIN SMALL LETTER W) 5339 0xFF58 x (FULLWIDTH LATIN SMALL LETTER X) 5340 0xFF59 y (FULLWIDTH LATIN SMALL LETTER Y) 5341 0xFF5A z (FULLWIDTH LATIN SMALL LETTER Z) 5342 0x0391 Α (GREEK CAPITAL LETTER ALPHA) 5343 0x0392 Β (GREEK CAPITAL LETTER BETA) 5344 0x0393 Γ (GREEK CAPITAL LETTER GAMMA) 5345 0x0394 Δ (GREEK CAPITAL LETTER DELTA) 5346 0x0395 Ε (GREEK CAPITAL LETTER EPSILON) 5347 0x0396 Ζ (GREEK CAPITAL LETTER ZETA) 5348 0x0397 Η (GREEK CAPITAL LETTER ETA) 5349 0x0398 Θ (GREEK CAPITAL LETTER THETA) 5350 0x0399 Ι (GREEK CAPITAL LETTER IOTA) 5351 0x039A Κ (GREEK CAPITAL LETTER KAPPA) 5352 0x039B Λ (GREEK CAPITAL LETTER LAMDA) 5353 0x039C Μ (GREEK CAPITAL LETTER MU) 5354 0x039D Ν (GREEK CAPITAL LETTER NU) 5355 0x039E Ξ (GREEK CAPITAL LETTER XI) 5356 0x039F Ο (GREEK CAPITAL LETTER OMICRON) 5357 0x03A0 Π (GREEK CAPITAL LETTER PI) 5358 0x03A1 Ρ (GREEK CAPITAL LETTER RHO) 5359 0x03A3 Σ (GREEK CAPITAL LETTER SIGMA) 5360 0x03A4 Τ (GREEK CAPITAL LETTER TAU) 5361 0x03A5 Υ (GREEK CAPITAL LETTER UPSILON) 5362 0x03A6 Φ (GREEK CAPITAL LETTER PHI) 5363 0x03A7 Χ (GREEK CAPITAL LETTER CHI) 5364 0x03A8 Ψ (GREEK CAPITAL LETTER PSI) 5365 0x03A9 Ω (GREEK CAPITAL LETTER OMEGA) 5366 0x03B1 α (GREEK SMALL LETTER ALPHA) 5367 0x03B2 β (GREEK SMALL LETTER BETA) 5368 0x03B3 γ (GREEK SMALL LETTER GAMMA) 5369 0x03B4 δ (GREEK SMALL LETTER DELTA) 5370 0x03B5 ε (GREEK SMALL LETTER EPSILON) 5371 0x03B6 ζ (GREEK SMALL LETTER ZETA) 5372 0x03B7 η (GREEK SMALL LETTER ETA) 5373 0x03B8 θ (GREEK SMALL LETTER THETA) 5374 0x03B9 ι (GREEK SMALL LETTER IOTA) 5375 0x03BA κ (GREEK SMALL LETTER KAPPA) 5376 0x03BB λ (GREEK SMALL LETTER LAMDA) 5377 0x03BC μ (GREEK SMALL LETTER MU) 5378 0x03BD ν (GREEK SMALL LETTER NU) 5379 0x03BE ξ (GREEK SMALL LETTER XI) 5380 0x03BF ο (GREEK SMALL LETTER OMICRON) 5381 0x03C0 π (GREEK SMALL LETTER PI) 5382 0x03C1 ρ (GREEK SMALL LETTER RHO) 5383 0x03C3 σ (GREEK SMALL LETTER SIGMA) 5384 0x03C4 τ (GREEK SMALL LETTER TAU) 5385 0x03C5 υ (GREEK SMALL LETTER UPSILON) 5386 0x03C6 φ (GREEK SMALL LETTER PHI) 5387 0x03C7 χ (GREEK SMALL LETTER CHI) 5388 0x03C8 ψ (GREEK SMALL LETTER PSI) 5389 0x03C9 ω (GREEK SMALL LETTER OMEGA) 5390 0x3105 ㄅ (BOPOMOFO LETTER B) 5391 0x3106 ㄆ (BOPOMOFO LETTER P) 5392 0x3107 ㄇ (BOPOMOFO LETTER M) 5393 0x3108 ㄈ (BOPOMOFO LETTER F) 5394 0x3109 ㄉ (BOPOMOFO LETTER D) 5395 0x310A ㄊ (BOPOMOFO LETTER T) 5396 0x310B ㄋ (BOPOMOFO LETTER N) 5397 0x310C ㄌ (BOPOMOFO LETTER L) 5398 0x310D ㄍ (BOPOMOFO LETTER G) 5399 0x310E ㄎ (BOPOMOFO LETTER K) 5400 0x310F ㄏ (BOPOMOFO LETTER H) 5401 0x3110 ㄐ (BOPOMOFO LETTER J) 5402 0x3111 ㄑ (BOPOMOFO LETTER Q) 5403 0x3112 ㄒ (BOPOMOFO LETTER X) 5404 0x3113 ㄓ (BOPOMOFO LETTER ZH) 5405 0x3114 ㄔ (BOPOMOFO LETTER CH) 5406 0x3115 ㄕ (BOPOMOFO LETTER SH) 5407 0x3116 ㄖ (BOPOMOFO LETTER R) 5408 0x3117 ㄗ (BOPOMOFO LETTER Z) 5409 0x3118 ㄘ (BOPOMOFO LETTER C) 5410 0x3119 ㄙ (BOPOMOFO LETTER S) 5411 0x311A ㄚ (BOPOMOFO LETTER A) 5412 0x311B ㄛ (BOPOMOFO LETTER O) 5413 0x311C ㄜ (BOPOMOFO LETTER E) 5414 0x311D ㄝ (BOPOMOFO LETTER EH) 5415 0x311E ㄞ (BOPOMOFO LETTER AI) 5416 0x311F ㄟ (BOPOMOFO LETTER EI) 5417 0x3120 ㄠ (BOPOMOFO LETTER AU) 5418 0x3121 ㄡ (BOPOMOFO LETTER OU) 5419 0x3122 ㄢ (BOPOMOFO LETTER AN) 5420 0x3123 ㄣ (BOPOMOFO LETTER EN) 5421 0x3124 ㄤ (BOPOMOFO LETTER ANG) 5422 0x3125 ㄥ (BOPOMOFO LETTER ENG) 5423 0x3126 ㄦ (BOPOMOFO LETTER ER) 5424 0x3127 ㄧ (BOPOMOFO LETTER I) 5425 0x3128 ㄨ (BOPOMOFO LETTER U) 5426 0x3129 ㄩ (BOPOMOFO LETTER IU) 5427 0x02D9 ˙ (DOT ABOVE) 5428 0x02C9 ˉ (MODIFIER LETTER MACRON) 5429 0x02CA ˊ (MODIFIER LETTER ACUTE ACCENT) 5430 0x02C7 ˇ (CARON) 5431 0x02CB ˋ (MODIFIER LETTER GRAVE ACCENT) 5432 0x2400 ␀ (SYMBOL FOR NULL) 5433 0x2401 ␁ (SYMBOL FOR START OF HEADING) 5434 0x2402 ␂ (SYMBOL FOR START OF TEXT) 5435 0x2403 ␃ (SYMBOL FOR END OF TEXT) 5436 0x2404 ␄ (SYMBOL FOR END OF TRANSMISSION) 5437 0x2405 ␅ (SYMBOL FOR ENQUIRY) 5438 0x2406 ␆ (SYMBOL FOR ACKNOWLEDGE) 5439 0x2407 ␇ (SYMBOL FOR BELL) 5440 0x2408 ␈ (SYMBOL FOR BACKSPACE) 5441 0x2409 ␉ (SYMBOL FOR HORIZONTAL TABULATION) 5442 0x240A ␊ (SYMBOL FOR LINE FEED) 5443 0x240B ␋ (SYMBOL FOR VERTICAL TABULATION) 5444 0x240C ␌ (SYMBOL FOR FORM FEED) 5445 0x240D ␍ (SYMBOL FOR CARRIAGE RETURN) 5446 0x240E ␎ (SYMBOL FOR SHIFT OUT) 5447 0x240F ␏ (SYMBOL FOR SHIFT IN) 5448 0x2410 ␐ (SYMBOL FOR DATA LINK ESCAPE) 5449 0x2411 ␑ (SYMBOL FOR DEVICE CONTROL ONE) 5450 0x2412 ␒ (SYMBOL FOR DEVICE CONTROL TWO) 5451 0x2413 ␓ (SYMBOL FOR DEVICE CONTROL THREE) 5452 0x2414 ␔ (SYMBOL FOR DEVICE CONTROL FOUR) 5453 0x2415 ␕ (SYMBOL FOR NEGATIVE ACKNOWLEDGE) 5454 0x2416 ␖ (SYMBOL FOR SYNCHRONOUS IDLE) 5455 0x2417 ␗ (SYMBOL FOR END OF TRANSMISSION BLOCK) 5456 0x2418 ␘ (SYMBOL FOR CANCEL) 5457 0x2419 ␙ (SYMBOL FOR END OF MEDIUM) 5458 0x241A ␚ (SYMBOL FOR SUBSTITUTE) 5459 0x241B ␛ (SYMBOL FOR ESCAPE) 5460 0x241C ␜ (SYMBOL FOR FILE SEPARATOR) 5461 0x241D ␝ (SYMBOL FOR GROUP SEPARATOR) 5462 0x241E ␞ (SYMBOL FOR RECORD SEPARATOR) 5463 0x241F ␟ (SYMBOL FOR UNIT SEPARATOR) 5464 0x2421 ␡ (SYMBOL FOR DELETE) 5465 0x20AC € (EURO SIGN) 5495 0x4E00 一 (<CJK Ideograph>) 5496 0x4E59 乙 (<CJK Ideograph>) 5497 0x4E01 丁 (<CJK Ideograph>) 5498 0x4E03 七 (<CJK Ideograph>) 5499 0x4E43 乃 (<CJK Ideograph>) 5500 0x4E5D 九 (<CJK Ideograph>) 5501 0x4E86 了 (<CJK Ideograph>) 5502 0x4E8C 二 (<CJK Ideograph>) 5503 0x4EBA 人 (<CJK Ideograph>) 5504 0x513F 儿 (<CJK Ideograph>) 5505 0x5165 入 (<CJK Ideograph>) 5506 0x516B 八 (<CJK Ideograph>) 5507 0x51E0 几 (<CJK Ideograph>) 5508 0x5200 刀 (<CJK Ideograph>) 5509 0x5201 刁 (<CJK Ideograph>) 5510 0x529B 力 (<CJK Ideograph>) 5511 0x5315 匕 (<CJK Ideograph>) 5512 0x5341 十 (<CJK Ideograph>) 5513 0x535C 卜 (<CJK Ideograph>) 5514 0x53C8 又 (<CJK Ideograph>) 5515 0x4E09 三 (<CJK Ideograph>) 5516 0x4E0B 下 (<CJK Ideograph>) 5517 0x4E08 丈 (<CJK Ideograph>) 5518 0x4E0A 上 (<CJK Ideograph>) 5519 0x4E2B 丫 (<CJK Ideograph>) 5520 0x4E38 丸 (<CJK Ideograph>) 5521 0x51E1 凡 (<CJK Ideograph>) 5522 0x4E45 久 (<CJK Ideograph>) 5523 0x4E48 么 (<CJK Ideograph>) 5524 0x4E5F 也 (<CJK Ideograph>) 5525 0x4E5E 乞 (<CJK Ideograph>) 5526 0x4E8E 于 (<CJK Ideograph>) 5527 0x4EA1 亡 (<CJK Ideograph>) 5528 0x5140 兀 (<CJK Ideograph>) 5529 0x5203 刃 (<CJK Ideograph>) 5530 0x52FA 勺 (<CJK Ideograph>) 5531 0x5343 千 (<CJK Ideograph>) 5532 0x53C9 叉 (<CJK Ideograph>) 5533 0x53E3 口 (<CJK Ideograph>) 5534 0x571F 土 (<CJK Ideograph>) 5535 0x58EB 士 (<CJK Ideograph>) 5536 0x5915 夕 (<CJK Ideograph>) 5537 0x5927 大 (<CJK Ideograph>) 5538 0x5973 女 (<CJK Ideograph>) 5539 0x5B50 子 (<CJK Ideograph>) 5540 0x5B51 孑 (<CJK Ideograph>) 5541 0x5B53 孓 (<CJK Ideograph>) 5542 0x5BF8 寸 (<CJK Ideograph>) 5543 0x5C0F 小 (<CJK Ideograph>) 5544 0x5C22 尢 (<CJK Ideograph>) 5545 0x5C38 尸 (<CJK Ideograph>) 5546 0x5C71 山 (<CJK Ideograph>) 5547 0x5DDD 川 (<CJK Ideograph>) 5548 0x5DE5 工 (<CJK Ideograph>) 5549 0x5DF1 己 (<CJK Ideograph>) 5550 0x5DF2 已 (<CJK Ideograph>) 5551 0x5DF3 巳 (<CJK Ideograph>) 5552 0x5DFE 巾 (<CJK Ideograph>) 5553 0x5E72 干 (<CJK Ideograph>) 5554 0x5EFE 廾 (<CJK Ideograph>) 5555 0x5F0B 弋 (<CJK Ideograph>) 5556 0x5F13 弓 (<CJK Ideograph>) 5557 0x624D 才 (<CJK Ideograph>) 5558 0x4E11 丑 (<CJK Ideograph>) 5559 0x4E10 丐 (<CJK Ideograph>) 5560 0x4E0D 不 (<CJK Ideograph>) 5561 0x4E2D 中 (<CJK Ideograph>) 5562 0x4E30 丰 (<CJK Ideograph>) 5563 0x4E39 丹 (<CJK Ideograph>) 5564 0x4E4B 之 (<CJK Ideograph>) 5565 0x5C39 尹 (<CJK Ideograph>) 5566 0x4E88 予 (<CJK Ideograph>) 5567 0x4E91 云 (<CJK Ideograph>) 5568 0x4E95 井 (<CJK Ideograph>) 5569 0x4E92 互 (<CJK Ideograph>) 5570 0x4E94 五 (<CJK Ideograph>) 5571 0x4EA2 亢 (<CJK Ideograph>) 5572 0x4EC1 仁 (<CJK Ideograph>) 5573 0x4EC0 什 (<CJK Ideograph>) 5574 0x4EC3 仃 (<CJK Ideograph>) 5575 0x4EC6 仆 (<CJK Ideograph>) 5576 0x4EC7 仇 (<CJK Ideograph>) 5577 0x4ECD 仍 (<CJK Ideograph>) 5578 0x4ECA 今 (<CJK Ideograph>) 5579 0x4ECB 介 (<CJK Ideograph>) 5580 0x4EC4 仄 (<CJK Ideograph>) 5581 0x5143 元 (<CJK Ideograph>) 5582 0x5141 允 (<CJK Ideograph>) 5583 0x5167 內 (<CJK Ideograph>) 5584 0x516D 六 (<CJK Ideograph>) 5585 0x516E 兮 (<CJK Ideograph>) 5586 0x516C 公 (<CJK Ideograph>) 5587 0x5197 冗 (<CJK Ideograph>) 5588 0x51F6 凶 (<CJK Ideograph>) 5589 0x5206 分 (<CJK Ideograph>) 5590 0x5207 切 (<CJK Ideograph>) 5591 0x5208 刈 (<CJK Ideograph>) 5592 0x52FB 勻 (<CJK Ideograph>) 5593 0x52FE 勾 (<CJK Ideograph>) 5594 0x52FF 勿 (<CJK Ideograph>) 5595 0x5316 化 (<CJK Ideograph>) 5596 0x5339 匹 (<CJK Ideograph>) 5597 0x5348 午 (<CJK Ideograph>) 5598 0x5347 升 (<CJK Ideograph>) 5599 0x5345 卅 (<CJK Ideograph>) 5600 0x535E 卞 (<CJK Ideograph>) 5601 0x5384 厄 (<CJK Ideograph>) 5602 0x53CB 友 (<CJK Ideograph>) 5603 0x53CA 及 (<CJK Ideograph>) 5604 0x53CD 反 (<CJK Ideograph>) 5605 0x58EC 壬 (<CJK Ideograph>) 5606 0x5929 天 (<CJK Ideograph>) 5607 0x592B 夫 (<CJK Ideograph>) 5608 0x592A 太 (<CJK Ideograph>) 5609 0x592D 夭 (<CJK Ideograph>) 5610 0x5B54 孔 (<CJK Ideograph>) 5611 0x5C11 少 (<CJK Ideograph>) 5612 0x5C24 尤 (<CJK Ideograph>) 5613 0x5C3A 尺 (<CJK Ideograph>) 5614 0x5C6F 屯 (<CJK Ideograph>) 5615 0x5DF4 巴 (<CJK Ideograph>) 5616 0x5E7B 幻 (<CJK Ideograph>) 5617 0x5EFF 廿 (<CJK Ideograph>) 5618 0x5F14 弔 (<CJK Ideograph>) 5619 0x5F15 引 (<CJK Ideograph>) 5620 0x5FC3 心 (<CJK Ideograph>) 5621 0x6208 戈 (<CJK Ideograph>) 5622 0x6236 戶 (<CJK Ideograph>) 5623 0x624B 手 (<CJK Ideograph>) 5624 0x624E 扎 (<CJK Ideograph>) 5625 0x652F 支 (<CJK Ideograph>) 5626 0x6587 文 (<CJK Ideograph>) 5627 0x6597 斗 (<CJK Ideograph>) 5628 0x65A4 斤 (<CJK Ideograph>) 5629 0x65B9 方 (<CJK Ideograph>) 5630 0x65E5 日 (<CJK Ideograph>) 5631 0x66F0 曰 (<CJK Ideograph>) 5632 0x6708 月 (<CJK Ideograph>) 5633 0x6728 木 (<CJK Ideograph>) 5634 0x6B20 欠 (<CJK Ideograph>) 5635 0x6B62 止 (<CJK Ideograph>) 5636 0x6B79 歹 (<CJK Ideograph>) 5637 0x6BCB 毋 (<CJK Ideograph>) 5638 0x6BD4 比 (<CJK Ideograph>) 5639 0x6BDB 毛 (<CJK Ideograph>) 5640 0x6C0F 氏 (<CJK Ideograph>) 5641 0x6C34 水 (<CJK Ideograph>) 5642 0x706B 火 (<CJK Ideograph>) 5643 0x722A 爪 (<CJK Ideograph>) 5644 0x7236 父 (<CJK Ideograph>) 5645 0x723B 爻 (<CJK Ideograph>) 5646 0x7247 片 (<CJK Ideograph>) 5647 0x7259 牙 (<CJK Ideograph>) 5648 0x725B 牛 (<CJK Ideograph>) 5649 0x72AC 犬 (<CJK Ideograph>) 5650 0x738B 王 (<CJK Ideograph>) 5651 0x4E19 丙 (<CJK Ideograph>) 5652 0x4E16 世 (<CJK Ideograph>) 5653 0x4E15 丕 (<CJK Ideograph>) 5654 0x4E14 且 (<CJK Ideograph>) 5655 0x4E18 丘 (<CJK Ideograph>) 5656 0x4E3B 主 (<CJK Ideograph>) 5657 0x4E4D 乍 (<CJK Ideograph>) 5658 0x4E4F 乏 (<CJK Ideograph>) 5659 0x4E4E 乎 (<CJK Ideograph>) 5660 0x4EE5 以 (<CJK Ideograph>) 5661 0x4ED8 付 (<CJK Ideograph>) 5662 0x4ED4 仔 (<CJK Ideograph>) 5663 0x4ED5 仕 (<CJK Ideograph>) 5664 0x4ED6 他 (<CJK Ideograph>) 5665 0x4ED7 仗 (<CJK Ideograph>) 5666 0x4EE3 代 (<CJK Ideograph>) 5667 0x4EE4 令 (<CJK Ideograph>) 5668 0x4ED9 仙 (<CJK Ideograph>) 5669 0x4EDE 仞 (<CJK Ideograph>) 5670 0x5145 充 (<CJK Ideograph>) 5671 0x5144 兄 (<CJK Ideograph>) 5672 0x5189 冉 (<CJK Ideograph>) 5673 0x518A 冊 (<CJK Ideograph>) 5674 0x51AC 冬 (<CJK Ideograph>) 5675 0x51F9 凹 (<CJK Ideograph>) 5676 0x51FA 出 (<CJK Ideograph>) 5677 0x51F8 凸 (<CJK Ideograph>) 5678 0x520A 刊 (<CJK Ideograph>) 5679 0x52A0 加 (<CJK Ideograph>) 5680 0x529F 功 (<CJK Ideograph>) 5681 0x5305 包 (<CJK Ideograph>) 5682 0x5306 匆 (<CJK Ideograph>) 5683 0x5317 北 (<CJK Ideograph>) 5684 0x531D 匝 (<CJK Ideograph>) 5685 0x4EDF 仟 (<CJK Ideograph>) 5686 0x534A 半 (<CJK Ideograph>) 5687 0x5349 卉 (<CJK Ideograph>) 5688 0x5361 卡 (<CJK Ideograph>) 5689 0x5360 占 (<CJK Ideograph>) 5690 0x536F 卯 (<CJK Ideograph>) 5691 0x536E 卮 (<CJK Ideograph>) 5692 0x53BB 去 (<CJK Ideograph>) 5693 0x53EF 可 (<CJK Ideograph>) 5694 0x53E4 古 (<CJK Ideograph>) 5695 0x53F3 右 (<CJK Ideograph>) 5696 0x53EC 召 (<CJK Ideograph>) 5697 0x53EE 叮 (<CJK Ideograph>) 5698 0x53E9 叩 (<CJK Ideograph>) 5699 0x53E8 叨 (<CJK Ideograph>) 5700 0x53FC 叼 (<CJK Ideograph>) 5701 0x53F8 司 (<CJK Ideograph>) 5702 0x53F5 叵 (<CJK Ideograph>) 5703 0x53EB 叫 (<CJK Ideograph>) 5704 0x53E6 另 (<CJK Ideograph>) 5705 0x53EA 只 (<CJK Ideograph>) 5706 0x53F2 史 (<CJK Ideograph>) 5707 0x53F1 叱 (<CJK Ideograph>) 5708 0x53F0 台 (<CJK Ideograph>) 5709 0x53E5 句 (<CJK Ideograph>) 5710 0x53ED 叭 (<CJK Ideograph>) 5711 0x53FB 叻 (<CJK Ideograph>) 5712 0x56DB 四 (<CJK Ideograph>) 5713 0x56DA 囚 (<CJK Ideograph>) 5714 0x5916 外 (<CJK Ideograph>) 5715 0x592E 央 (<CJK Ideograph>) 5716 0x5931 失 (<CJK Ideograph>) 5717 0x5974 奴 (<CJK Ideograph>) 5718 0x5976 奶 (<CJK Ideograph>) 5719 0x5B55 孕 (<CJK Ideograph>) 5720 0x5B83 它 (<CJK Ideograph>) 5721 0x5C3C 尼 (<CJK Ideograph>) 5722 0x5DE8 巨 (<CJK Ideograph>) 5723 0x5DE7 巧 (<CJK Ideograph>) 5724 0x5DE6 左 (<CJK Ideograph>) 5725 0x5E02 市 (<CJK Ideograph>) 5726 0x5E03 布 (<CJK Ideograph>) 5727 0x5E73 平 (<CJK Ideograph>) 5728 0x5E7C 幼 (<CJK Ideograph>) 5729 0x5F01 弁 (<CJK Ideograph>) 5730 0x5F18 弘 (<CJK Ideograph>) 5731 0x5F17 弗 (<CJK Ideograph>) 5732 0x5FC5 必 (<CJK Ideograph>) 5733 0x620A 戊 (<CJK Ideograph>) 5734 0x6253 打 (<CJK Ideograph>) 5735 0x6254 扔 (<CJK Ideograph>) 5736 0x6252 扒 (<CJK Ideograph>) 5737 0x6251 扑 (<CJK Ideograph>) 5738 0x65A5 斥 (<CJK Ideograph>) 5739 0x65E6 旦 (<CJK Ideograph>) 5740 0x672E 朮 (<CJK Ideograph>) 5741 0x672C 本 (<CJK Ideograph>) 5742 0x672A 未 (<CJK Ideograph>) 5743 0x672B 末 (<CJK Ideograph>) 5744 0x672D 札 (<CJK Ideograph>) 5745 0x6B63 正 (<CJK Ideograph>) 5746 0x6BCD 母 (<CJK Ideograph>) 5747 0x6C11 民 (<CJK Ideograph>) 5748 0x6C10 氐 (<CJK Ideograph>) 5749 0x6C38 永 (<CJK Ideograph>) 5750 0x6C41 汁 (<CJK Ideograph>) 5751 0x6C40 汀 (<CJK Ideograph>) 5752 0x6C3E 氾 (<CJK Ideograph>) 5753 0x72AF 犯 (<CJK Ideograph>) 5754 0x7384 玄 (<CJK Ideograph>) 5755 0x7389 玉 (<CJK Ideograph>) 5756 0x74DC 瓜 (<CJK Ideograph>) 5757 0x74E6 瓦 (<CJK Ideograph>) 5758 0x7518 甘 (<CJK Ideograph>) 5759 0x751F 生 (<CJK Ideograph>) 5760 0x7528 用 (<CJK Ideograph>) 5761 0x7529 甩 (<CJK Ideograph>) 5762 0x7530 田 (<CJK Ideograph>) 5763 0x7531 由 (<CJK Ideograph>) 5764 0x7532 甲 (<CJK Ideograph>) 5765 0x7533 申 (<CJK Ideograph>) 5766 0x758B 疋 (<CJK Ideograph>) 5767 0x767D 白 (<CJK Ideograph>) 5768 0x76AE 皮 (<CJK Ideograph>) 5769 0x76BF 皿 (<CJK Ideograph>) 5770 0x76EE 目 (<CJK Ideograph>) 5771 0x77DB 矛 (<CJK Ideograph>) 5772 0x77E2 矢 (<CJK Ideograph>) 5773 0x77F3 石 (<CJK Ideograph>) 5774 0x793A 示 (<CJK Ideograph>) 5775 0x79BE 禾 (<CJK Ideograph>) 5776 0x7A74 穴 (<CJK Ideograph>) 5777 0x7ACB 立 (<CJK Ideograph>) 5778 0x4E1E 丞 (<CJK Ideograph>) 5779 0x4E1F 丟 (<CJK Ideograph>) 5780 0x4E52 乒 (<CJK Ideograph>) 5781 0x4E53 乓 (<CJK Ideograph>) 5782 0x4E69 乩 (<CJK Ideograph>) 5783 0x4E99 亙 (<CJK Ideograph>) 5784 0x4EA4 交 (<CJK Ideograph>) 5785 0x4EA6 亦 (<CJK Ideograph>) 5786 0x4EA5 亥 (<CJK Ideograph>) 5787 0x4EFF 仿 (<CJK Ideograph>) 5788 0x4F09 伉 (<CJK Ideograph>) 5789 0x4F19 伙 (<CJK Ideograph>) 5790 0x4F0A 伊 (<CJK Ideograph>) 5791 0x4F15 伕 (<CJK Ideograph>) 5792 0x4F0D 伍 (<CJK Ideograph>) 5793 0x4F10 伐 (<CJK Ideograph>) 5794 0x4F11 休 (<CJK Ideograph>) 5795 0x4F0F 伏 (<CJK Ideograph>) 5796 0x4EF2 仲 (<CJK Ideograph>) 5797 0x4EF6 件 (<CJK Ideograph>) 5798 0x4EFB 任 (<CJK Ideograph>) 5799 0x4EF0 仰 (<CJK Ideograph>) 5800 0x4EF3 仳 (<CJK Ideograph>) 5801 0x4EFD 份 (<CJK Ideograph>) 5802 0x4F01 企 (<CJK Ideograph>) 5803 0x4F0B 伋 (<CJK Ideograph>) 5804 0x5149 光 (<CJK Ideograph>) 5805 0x5147 兇 (<CJK Ideograph>) 5806 0x5146 兆 (<CJK Ideograph>) 5807 0x5148 先 (<CJK Ideograph>) 5808 0x5168 全 (<CJK Ideograph>) 5809 0x5171 共 (<CJK Ideograph>) 5810 0x518D 再 (<CJK Ideograph>) 5811 0x51B0 冰 (<CJK Ideograph>) 5812 0x5217 列 (<CJK Ideograph>) 5813 0x5211 刑 (<CJK Ideograph>) 5814 0x5212 划 (<CJK Ideograph>) 5815 0x520E 刎 (<CJK Ideograph>) 5816 0x5216 刖 (<CJK Ideograph>) 5817 0x52A3 劣 (<CJK Ideograph>) 5818 0x5308 匈 (<CJK Ideograph>) 5819 0x5321 匡 (<CJK Ideograph>) 5820 0x5320 匠 (<CJK Ideograph>) 5821 0x5370 印 (<CJK Ideograph>) 5822 0x5371 危 (<CJK Ideograph>) 5823 0x5409 吉 (<CJK Ideograph>) 5824 0x540F 吏 (<CJK Ideograph>) 5825 0x540C 同 (<CJK Ideograph>) 5826 0x540A 吊 (<CJK Ideograph>) 5827 0x5410 吐 (<CJK Ideograph>) 5828 0x5401 吁 (<CJK Ideograph>) 5829 0x540B 吋 (<CJK Ideograph>) 5830 0x5404 各 (<CJK Ideograph>) 5831 0x5411 向 (<CJK Ideograph>) 5832 0x540D 名 (<CJK Ideograph>) 5833 0x5408 合 (<CJK Ideograph>) 5834 0x5403 吃 (<CJK Ideograph>) 5835 0x540E 后 (<CJK Ideograph>) 5836 0x5406 吆 (<CJK Ideograph>) 5837 0x5412 吒 (<CJK Ideograph>) 5838 0x56E0 因 (<CJK Ideograph>) 5839 0x56DE 回 (<CJK Ideograph>) 5840 0x56DD 囝 (<CJK Ideograph>) 5841 0x5733 圳 (<CJK Ideograph>) 5842 0x5730 地 (<CJK Ideograph>) 5843 0x5728 在 (<CJK Ideograph>) 5844 0x572D 圭 (<CJK Ideograph>) 5845 0x572C 圬 (<CJK Ideograph>) 5846 0x572F 圯 (<CJK Ideograph>) 5847 0x5729 圩 (<CJK Ideograph>) 5848 0x5919 夙 (<CJK Ideograph>) 5849 0x591A 多 (<CJK Ideograph>) 5850 0x5937 夷 (<CJK Ideograph>) 5851 0x5938 夸 (<CJK Ideograph>) 5852 0x5984 妄 (<CJK Ideograph>) 5853 0x5978 奸 (<CJK Ideograph>) 5854 0x5983 妃 (<CJK Ideograph>) 5855 0x597D 好 (<CJK Ideograph>) 5856 0x5979 她 (<CJK Ideograph>) 5857 0x5982 如 (<CJK Ideograph>) 5858 0x5981 妁 (<CJK Ideograph>) 5859 0x5B57 字 (<CJK Ideograph>) 5860 0x5B58 存 (<CJK Ideograph>) 5861 0x5B87 宇 (<CJK Ideograph>) 5862 0x5B88 守 (<CJK Ideograph>) 5863 0x5B85 宅 (<CJK Ideograph>) 5864 0x5B89 安 (<CJK Ideograph>) 5865 0x5BFA 寺 (<CJK Ideograph>) 5866 0x5C16 尖 (<CJK Ideograph>) 5867 0x5C79 屹 (<CJK Ideograph>) 5868 0x5DDE 州 (<CJK Ideograph>) 5869 0x5E06 帆 (<CJK Ideograph>) 5870 0x5E76 并 (<CJK Ideograph>) 5871 0x5E74 年 (<CJK Ideograph>) 5872 0x5F0F 式 (<CJK Ideograph>) 5873 0x5F1B 弛 (<CJK Ideograph>) 5874 0x5FD9 忙 (<CJK Ideograph>) 5875 0x5FD6 忖 (<CJK Ideograph>) 5876 0x620E 戎 (<CJK Ideograph>) 5877 0x620C 戌 (<CJK Ideograph>) 5878 0x620D 戍 (<CJK Ideograph>) 5879 0x6210 成 (<CJK Ideograph>) 5880 0x6263 扣 (<CJK Ideograph>) 5881 0x625B 扛 (<CJK Ideograph>) 5882 0x6258 托 (<CJK Ideograph>) 5883 0x6536 收 (<CJK Ideograph>) 5884 0x65E9 早 (<CJK Ideograph>) 5885 0x65E8 旨 (<CJK Ideograph>) 5886 0x65EC 旬 (<CJK Ideograph>) 5887 0x65ED 旭 (<CJK Ideograph>) 5888 0x66F2 曲 (<CJK Ideograph>) 5889 0x66F3 曳 (<CJK Ideograph>) 5890 0x6709 有 (<CJK Ideograph>) 5891 0x673D 朽 (<CJK Ideograph>) 5892 0x6734 朴 (<CJK Ideograph>) 5893 0x6731 朱 (<CJK Ideograph>) 5894 0x6735 朵 (<CJK Ideograph>) 5895 0x6B21 次 (<CJK Ideograph>) 5896 0x6B64 此 (<CJK Ideograph>) 5897 0x6B7B 死 (<CJK Ideograph>) 5898 0x6C16 氖 (<CJK Ideograph>) 5899 0x6C5D 汝 (<CJK Ideograph>) 5900 0x6C57 汗 (<CJK Ideograph>) 5901 0x6C59 汙 (<CJK Ideograph>) 5902 0x6C5F 江 (<CJK Ideograph>) 5903 0x6C60 池 (<CJK Ideograph>) 5904 0x6C50 汐 (<CJK Ideograph>) 5905 0x6C55 汕 (<CJK Ideograph>) 5906 0x6C61 污 (<CJK Ideograph>) 5907 0x6C5B 汛 (<CJK Ideograph>) 5908 0x6C4D 汍 (<CJK Ideograph>) 5909 0x6C4E 汎 (<CJK Ideograph>) 5910 0x7070 灰 (<CJK Ideograph>) 5911 0x725F 牟 (<CJK Ideograph>) 5912 0x725D 牝 (<CJK Ideograph>) 5913 0x767E 百 (<CJK Ideograph>) 5914 0x7AF9 竹 (<CJK Ideograph>) 5915 0x7C73 米 (<CJK Ideograph>) 5916 0x7CF8 糸 (<CJK Ideograph>) 5917 0x7F36 缶 (<CJK Ideograph>) 5918 0x7F8A 羊 (<CJK Ideograph>) 5919 0x7FBD 羽 (<CJK Ideograph>) 5920 0x8001 老 (<CJK Ideograph>) 5921 0x8003 考 (<CJK Ideograph>) 5922 0x800C 而 (<CJK Ideograph>) 5923 0x8012 耒 (<CJK Ideograph>) 5924 0x8033 耳 (<CJK Ideograph>) 5925 0x807F 聿 (<CJK Ideograph>) 5926 0x8089 肉 (<CJK Ideograph>) 5927 0x808B 肋 (<CJK Ideograph>) 5928 0x808C 肌 (<CJK Ideograph>) 5929 0x81E3 臣 (<CJK Ideograph>) 5930 0x81EA 自 (<CJK Ideograph>) 5931 0x81F3 至 (<CJK Ideograph>) 5932 0x81FC 臼 (<CJK Ideograph>) 5933 0x820C 舌 (<CJK Ideograph>) 5934 0x821B 舛 (<CJK Ideograph>) 5935 0x821F 舟 (<CJK Ideograph>) 5936 0x826E 艮 (<CJK Ideograph>) 5937 0x8272 色 (<CJK Ideograph>) 5938 0x827E 艾 (<CJK Ideograph>) 5939 0x866B 虫 (<CJK Ideograph>) 5940 0x8840 血 (<CJK Ideograph>) 5941 0x884C 行 (<CJK Ideograph>) 5942 0x8863 衣 (<CJK Ideograph>) 5943 0x897F 西 (<CJK Ideograph>) 5944 0x9621 阡 (<CJK Ideograph>) 5945 0x4E32 串 (<CJK Ideograph>) 5946 0x4EA8 亨 (<CJK Ideograph>) 5947 0x4F4D 位 (<CJK Ideograph>) 5948 0x4F4F 住 (<CJK Ideograph>) 5949 0x4F47 佇 (<CJK Ideograph>) 5950 0x4F57 佗 (<CJK Ideograph>) 5951 0x4F5E 佞 (<CJK Ideograph>) 5952 0x4F34 伴 (<CJK Ideograph>) 5953 0x4F5B 佛 (<CJK Ideograph>) 5954 0x4F55 何 (<CJK Ideograph>) 5955 0x4F30 估 (<CJK Ideograph>) 5956 0x4F50 佐 (<CJK Ideograph>) 5957 0x4F51 佑 (<CJK Ideograph>) 5958 0x4F3D 伽 (<CJK Ideograph>) 5959 0x4F3A 伺 (<CJK Ideograph>) 5960 0x4F38 伸 (<CJK Ideograph>) 5961 0x4F43 佃 (<CJK Ideograph>) 5962 0x4F54 佔 (<CJK Ideograph>) 5963 0x4F3C 似 (<CJK Ideograph>) 5964 0x4F46 但 (<CJK Ideograph>) 5965 0x4F63 佣 (<CJK Ideograph>) 5966 0x4F5C 作 (<CJK Ideograph>) 5967 0x4F60 你 (<CJK Ideograph>) 5968 0x4F2F 伯 (<CJK Ideograph>) 5969 0x4F4E 低 (<CJK Ideograph>) 5970 0x4F36 伶 (<CJK Ideograph>) 5971 0x4F59 余 (<CJK Ideograph>) 5972 0x4F5D 佝 (<CJK Ideograph>) 5973 0x4F48 佈 (<CJK Ideograph>) 5974 0x4F5A 佚 (<CJK Ideograph>) 5975 0x514C 兌 (<CJK Ideograph>) 5976 0x514B 克 (<CJK Ideograph>) 5977 0x514D 免 (<CJK Ideograph>) 5978 0x5175 兵 (<CJK Ideograph>) 5979 0x51B6 冶 (<CJK Ideograph>) 5980 0x51B7 冷 (<CJK Ideograph>) 5981 0x5225 別 (<CJK Ideograph>) 5982 0x5224 判 (<CJK Ideograph>) 5983 0x5229 利 (<CJK Ideograph>) 5984 0x522A 刪 (<CJK Ideograph>) 5985 0x5228 刨 (<CJK Ideograph>) 5986 0x52AB 劫 (<CJK Ideograph>) 5987 0x52A9 助 (<CJK Ideograph>) 5988 0x52AA 努 (<CJK Ideograph>) 5989 0x52AC 劬 (<CJK Ideograph>) 5990 0x5323 匣 (<CJK Ideograph>) 5991 0x5373 即 (<CJK Ideograph>) 5992 0x5375 卵 (<CJK Ideograph>) 5993 0x541D 吝 (<CJK Ideograph>) 5994 0x542D 吭 (<CJK Ideograph>) 5995 0x541E 吞 (<CJK Ideograph>) 5996 0x543E 吾 (<CJK Ideograph>) 5997 0x5426 否 (<CJK Ideograph>) 5998 0x544E 呎 (<CJK Ideograph>) 5999 0x5427 吧 (<CJK Ideograph>) 6000 0x5446 呆 (<CJK Ideograph>) 6001 0x5443 呃 (<CJK Ideograph>) 6002 0x5433 吳 (<CJK Ideograph>) 6003 0x5448 呈 (<CJK Ideograph>) 6004 0x5442 呂 (<CJK Ideograph>) 6005 0x541B 君 (<CJK Ideograph>) 6006 0x5429 吩 (<CJK Ideograph>) 6007 0x544A 告 (<CJK Ideograph>) 6008 0x5439 吹 (<CJK Ideograph>) 6009 0x543B 吻 (<CJK Ideograph>) 6010 0x5438 吸 (<CJK Ideograph>) 6011 0x542E 吮 (<CJK Ideograph>) 6012 0x5435 吵 (<CJK Ideograph>) 6013 0x5436 吶 (<CJK Ideograph>) 6014 0x5420 吠 (<CJK Ideograph>) 6015 0x543C 吼 (<CJK Ideograph>) 6016 0x5440 呀 (<CJK Ideograph>) 6017 0x5431 吱 (<CJK Ideograph>) 6018 0x542B 含 (<CJK Ideograph>) 6019 0x541F 吟 (<CJK Ideograph>) 6020 0x542C 听 (<CJK Ideograph>) 6021 0x56EA 囪 (<CJK Ideograph>) 6022 0x56F0 困 (<CJK Ideograph>) 6023 0x56E4 囤 (<CJK Ideograph>) 6024 0x56EB 囫 (<CJK Ideograph>) 6025 0x574A 坊 (<CJK Ideograph>) 6026 0x5751 坑 (<CJK Ideograph>) 6027 0x5740 址 (<CJK Ideograph>) 6028 0x574D 坍 (<CJK Ideograph>) 6029 0x5747 均 (<CJK Ideograph>) 6030 0x574E 坎 (<CJK Ideograph>) 6031 0x573E 圾 (<CJK Ideograph>) 6032 0x5750 坐 (<CJK Ideograph>) 6033 0x574F 坏 (<CJK Ideograph>) 6034 0x573B 圻 (<CJK Ideograph>) 6035 0x58EF 壯 (<CJK Ideograph>) 6036 0x593E 夾 (<CJK Ideograph>) 6037 0x599D 妝 (<CJK Ideograph>) 6038 0x5992 妒 (<CJK Ideograph>) 6039 0x59A8 妨 (<CJK Ideograph>) 6040 0x599E 妞 (<CJK Ideograph>) 6041 0x59A3 妣 (<CJK Ideograph>) 6042 0x5999 妙 (<CJK Ideograph>) 6043 0x5996 妖 (<CJK Ideograph>) 6044 0x598D 妍 (<CJK Ideograph>) 6045 0x59A4 妤 (<CJK Ideograph>) 6046 0x5993 妓 (<CJK Ideograph>) 6047 0x598A 妊 (<CJK Ideograph>) 6048 0x59A5 妥 (<CJK Ideograph>) 6049 0x5B5D 孝 (<CJK Ideograph>) 6050 0x5B5C 孜 (<CJK Ideograph>) 6051 0x5B5A 孚 (<CJK Ideograph>) 6052 0x5B5B 孛 (<CJK Ideograph>) 6053 0x5B8C 完 (<CJK Ideograph>) 6054 0x5B8B 宋 (<CJK Ideograph>) 6055 0x5B8F 宏 (<CJK Ideograph>) 6056 0x5C2C 尬 (<CJK Ideograph>) 6057 0x5C40 局 (<CJK Ideograph>) 6058 0x5C41 屁 (<CJK Ideograph>) 6059 0x5C3F 尿 (<CJK Ideograph>) 6060 0x5C3E 尾 (<CJK Ideograph>) 6061 0x5C90 岐 (<CJK Ideograph>) 6062 0x5C91 岑 (<CJK Ideograph>) 6063 0x5C94 岔 (<CJK Ideograph>) 6064 0x5C8C 岌 (<CJK Ideograph>) 6065 0x5DEB 巫 (<CJK Ideograph>) 6066 0x5E0C 希 (<CJK Ideograph>) 6067 0x5E8F 序 (<CJK Ideograph>) 6068 0x5E87 庇 (<CJK Ideograph>) 6069 0x5E8A 床 (<CJK Ideograph>) 6070 0x5EF7 廷 (<CJK Ideograph>) 6071 0x5F04 弄 (<CJK Ideograph>) 6072 0x5F1F 弟 (<CJK Ideograph>) 6073 0x5F64 彤 (<CJK Ideograph>) 6074 0x5F62 形 (<CJK Ideograph>) 6075 0x5F77 彷 (<CJK Ideograph>) 6076 0x5F79 役 (<CJK Ideograph>) 6077 0x5FD8 忘 (<CJK Ideograph>) 6078 0x5FCC 忌 (<CJK Ideograph>) 6079 0x5FD7 志 (<CJK Ideograph>) 6080 0x5FCD 忍 (<CJK Ideograph>) 6081 0x5FF1 忱 (<CJK Ideograph>) 6082 0x5FEB 快 (<CJK Ideograph>) 6083 0x5FF8 忸 (<CJK Ideograph>) 6084 0x5FEA 忪 (<CJK Ideograph>) 6085 0x6212 戒 (<CJK Ideograph>) 6086 0x6211 我 (<CJK Ideograph>) 6087 0x6284 抄 (<CJK Ideograph>) 6088 0x6297 抗 (<CJK Ideograph>) 6089 0x6296 抖 (<CJK Ideograph>) 6090 0x6280 技 (<CJK Ideograph>) 6091 0x6276 扶 (<CJK Ideograph>) 6092 0x6289 抉 (<CJK Ideograph>) 6093 0x626D 扭 (<CJK Ideograph>) 6094 0x628A 把 (<CJK Ideograph>) 6095 0x627C 扼 (<CJK Ideograph>) 6096 0x627E 找 (<CJK Ideograph>) 6097 0x6279 批 (<CJK Ideograph>) 6098 0x6273 扳 (<CJK Ideograph>) 6099 0x6292 抒 (<CJK Ideograph>) 6100 0x626F 扯 (<CJK Ideograph>) 6101 0x6298 折 (<CJK Ideograph>) 6102 0x626E 扮 (<CJK Ideograph>) 6103 0x6295 投 (<CJK Ideograph>) 6104 0x6293 抓 (<CJK Ideograph>) 6105 0x6291 抑 (<CJK Ideograph>) 6106 0x6286 抆 (<CJK Ideograph>) 6107 0x6539 改 (<CJK Ideograph>) 6108 0x653B 攻 (<CJK Ideograph>) 6109 0x6538 攸 (<CJK Ideograph>) 6110 0x65F1 旱 (<CJK Ideograph>) 6111 0x66F4 更 (<CJK Ideograph>) 6112 0x675F 束 (<CJK Ideograph>) 6113 0x674E 李 (<CJK Ideograph>) 6114 0x674F 杏 (<CJK Ideograph>) 6115 0x6750 材 (<CJK Ideograph>) 6116 0x6751 村 (<CJK Ideograph>) 6117 0x675C 杜 (<CJK Ideograph>) 6118 0x6756 杖 (<CJK Ideograph>) 6119 0x675E 杞 (<CJK Ideograph>) 6120 0x6749 杉 (<CJK Ideograph>) 6121 0x6746 杆 (<CJK Ideograph>) 6122 0x6760 杠 (<CJK Ideograph>) 6123 0x6753 杓 (<CJK Ideograph>) 6124 0x6757 杗 (<CJK Ideograph>) 6125 0x6B65 步 (<CJK Ideograph>) 6126 0x6BCF 每 (<CJK Ideograph>) 6127 0x6C42 求 (<CJK Ideograph>) 6128 0x6C5E 汞 (<CJK Ideograph>) 6129 0x6C99 沙 (<CJK Ideograph>) 6130 0x6C81 沁 (<CJK Ideograph>) 6131 0x6C88 沈 (<CJK Ideograph>) 6132 0x6C89 沉 (<CJK Ideograph>) 6133 0x6C85 沅 (<CJK Ideograph>) 6134 0x6C9B 沛 (<CJK Ideograph>) 6135 0x6C6A 汪 (<CJK Ideograph>) 6136 0x6C7A 決 (<CJK Ideograph>) 6137 0x6C90 沐 (<CJK Ideograph>) 6138 0x6C70 汰 (<CJK Ideograph>) 6139 0x6C8C 沌 (<CJK Ideograph>) 6140 0x6C68 汨 (<CJK Ideograph>) 6141 0x6C96 沖 (<CJK Ideograph>) 6142 0x6C92 沒 (<CJK Ideograph>) 6143 0x6C7D 汽 (<CJK Ideograph>) 6144 0x6C83 沃 (<CJK Ideograph>) 6145 0x6C72 汲 (<CJK Ideograph>) 6146 0x6C7E 汾 (<CJK Ideograph>) 6147 0x6C74 汴 (<CJK Ideograph>) 6148 0x6C86 沆 (<CJK Ideograph>) 6149 0x6C76 汶 (<CJK Ideograph>) 6150 0x6C8D 沍 (<CJK Ideograph>) 6151 0x6C94 沔 (<CJK Ideograph>) 6152 0x6C98 沘 (<CJK Ideograph>) 6153 0x6C82 沂 (<CJK Ideograph>) 6154 0x7076 灶 (<CJK Ideograph>) 6155 0x707C 灼 (<CJK Ideograph>) 6156 0x707D 災 (<CJK Ideograph>) 6157 0x7078 灸 (<CJK Ideograph>) 6158 0x7262 牢 (<CJK Ideograph>) 6159 0x7261 牡 (<CJK Ideograph>) 6160 0x7260 牠 (<CJK Ideograph>) 6161 0x72C4 狄 (<CJK Ideograph>) 6162 0x72C2 狂 (<CJK Ideograph>) 6163 0x7396 玖 (<CJK Ideograph>) 6164 0x752C 甬 (<CJK Ideograph>) 6165 0x752B 甫 (<CJK Ideograph>) 6166 0x7537 男 (<CJK Ideograph>) 6167 0x7538 甸 (<CJK Ideograph>) 6168 0x7682 皂 (<CJK Ideograph>) 6169 0x76EF 盯 (<CJK Ideograph>) 6170 0x77E3 矣 (<CJK Ideograph>) 6171 0x79C1 私 (<CJK Ideograph>) 6172 0x79C0 秀 (<CJK Ideograph>) 6173 0x79BF 禿 (<CJK Ideograph>) 6174 0x7A76 究 (<CJK Ideograph>) 6175 0x7CFB 系 (<CJK Ideograph>) 6176 0x7F55 罕 (<CJK Ideograph>) 6177 0x8096 肖 (<CJK Ideograph>) 6178 0x8093 肓 (<CJK Ideograph>) 6179 0x809D 肝 (<CJK Ideograph>) 6180 0x8098 肘 (<CJK Ideograph>) 6181 0x809B 肛 (<CJK Ideograph>) 6182 0x809A 肚 (<CJK Ideograph>) 6183 0x80B2 育 (<CJK Ideograph>) 6184 0x826F 良 (<CJK Ideograph>) 6185 0x8292 芒 (<CJK Ideograph>) 6186 0x828B 芋 (<CJK Ideograph>) 6187 0x828D 芍 (<CJK Ideograph>) 6188 0x898B 見 (<CJK Ideograph>) 6189 0x89D2 角 (<CJK Ideograph>) 6190 0x8A00 言 (<CJK Ideograph>) 6191 0x8C37 谷 (<CJK Ideograph>) 6192 0x8C46 豆 (<CJK Ideograph>) 6193 0x8C55 豕 (<CJK Ideograph>) 6194 0x8C9D 貝 (<CJK Ideograph>) 6195 0x8D64 赤 (<CJK Ideograph>) 6196 0x8D70 走 (<CJK Ideograph>) 6197 0x8DB3 足 (<CJK Ideograph>) 6198 0x8EAB 身 (<CJK Ideograph>) 6199 0x8ECA 車 (<CJK Ideograph>) 6200 0x8F9B 辛 (<CJK Ideograph>) 6201 0x8FB0 辰 (<CJK Ideograph>) 6202 0x8FC2 迂 (<CJK Ideograph>) 6203 0x8FC6 迆 (<CJK Ideograph>) 6204 0x8FC5 迅 (<CJK Ideograph>) 6205 0x8FC4 迄 (<CJK Ideograph>) 6206 0x5DE1 巡 (<CJK Ideograph>) 6207 0x9091 邑 (<CJK Ideograph>) 6208 0x90A2 邢 (<CJK Ideograph>) 6209 0x90AA 邪 (<CJK Ideograph>) 6210 0x90A6 邦 (<CJK Ideograph>) 6211 0x90A3 那 (<CJK Ideograph>) 6212 0x9149 酉 (<CJK Ideograph>) 6213 0x91C6 釆 (<CJK Ideograph>) 6214 0x91CC 里 (<CJK Ideograph>) 6215 0x9632 防 (<CJK Ideograph>) 6216 0x962E 阮 (<CJK Ideograph>) 6217 0x9631 阱 (<CJK Ideograph>) 6218 0x962A 阪 (<CJK Ideograph>) 6219 0x962C 阬 (<CJK Ideograph>) 6220 0x4E26 並 (<CJK Ideograph>) 6221 0x4E56 乖 (<CJK Ideograph>) 6222 0x4E73 乳 (<CJK Ideograph>) 6223 0x4E8B 事 (<CJK Ideograph>) 6224 0x4E9B 些 (<CJK Ideograph>) 6225 0x4E9E 亞 (<CJK Ideograph>) 6226 0x4EAB 享 (<CJK Ideograph>) 6227 0x4EAC 京 (<CJK Ideograph>) 6228 0x4F6F 佯 (<CJK Ideograph>) 6229 0x4F9D 依 (<CJK Ideograph>) 6230 0x4F8D 侍 (<CJK Ideograph>) 6231 0x4F73 佳 (<CJK Ideograph>) 6232 0x4F7F 使 (<CJK Ideograph>) 6233 0x4F6C 佬 (<CJK Ideograph>) 6234 0x4F9B 供 (<CJK Ideograph>) 6235 0x4F8B 例 (<CJK Ideograph>) 6236 0x4F86 來 (<CJK Ideograph>) 6237 0x4F83 侃 (<CJK Ideograph>) 6238 0x4F70 佰 (<CJK Ideograph>) 6239 0x4F75 併 (<CJK Ideograph>) 6240 0x4F88 侈 (<CJK Ideograph>) 6241 0x4F69 佩 (<CJK Ideograph>) 6242 0x4F7B 佻 (<CJK Ideograph>) 6243 0x4F96 侖 (<CJK Ideograph>) 6244 0x4F7E 佾 (<CJK Ideograph>) 6245 0x4F8F 侏 (<CJK Ideograph>) 6246 0x4F91 侑 (<CJK Ideograph>) 6247 0x4F7A 佺 (<CJK Ideograph>) 6248 0x5154 兔 (<CJK Ideograph>) 6249 0x5152 兒 (<CJK Ideograph>) 6250 0x5155 兕 (<CJK Ideograph>) 6251 0x5169 兩 (<CJK Ideograph>) 6252 0x5177 具 (<CJK Ideograph>) 6253 0x5176 其 (<CJK Ideograph>) 6254 0x5178 典 (<CJK Ideograph>) 6255 0x51BD 冽 (<CJK Ideograph>) 6256 0x51FD 函 (<CJK Ideograph>) 6257 0x523B 刻 (<CJK Ideograph>) 6258 0x5238 券 (<CJK Ideograph>) 6259 0x5237 刷 (<CJK Ideograph>) 6260 0x523A 刺 (<CJK Ideograph>) 6261 0x5230 到 (<CJK Ideograph>) 6262 0x522E 刮 (<CJK Ideograph>) 6263 0x5236 制 (<CJK Ideograph>) 6264 0x5241 剁 (<CJK Ideograph>) 6265 0x52BE 劾 (<CJK Ideograph>) 6266 0x52BB 劻 (<CJK Ideograph>) 6267 0x5352 卒 (<CJK Ideograph>) 6268 0x5354 協 (<CJK Ideograph>) 6269 0x5353 卓 (<CJK Ideograph>) 6270 0x5351 卑 (<CJK Ideograph>) 6271 0x5366 卦 (<CJK Ideograph>) 6272 0x5377 卷 (<CJK Ideograph>) 6273 0x5378 卸 (<CJK Ideograph>) 6274 0x5379 卹 (<CJK Ideograph>) 6275 0x53D6 取 (<CJK Ideograph>) 6276 0x53D4 叔 (<CJK Ideograph>) 6277 0x53D7 受 (<CJK Ideograph>) 6278 0x5473 味 (<CJK Ideograph>) 6279 0x5475 呵 (<CJK Ideograph>) 6280 0x5496 咖 (<CJK Ideograph>) 6281 0x5478 呸 (<CJK Ideograph>) 6282 0x5495 咕 (<CJK Ideograph>) 6283 0x5480 咀 (<CJK Ideograph>) 6284 0x547B 呻 (<CJK Ideograph>) 6285 0x5477 呷 (<CJK Ideograph>) 6286 0x5484 咄 (<CJK Ideograph>) 6287 0x5492 咒 (<CJK Ideograph>) 6288 0x5486 咆 (<CJK Ideograph>) 6289 0x547C 呼 (<CJK Ideograph>) 6290 0x5490 咐 (<CJK Ideograph>) 6291 0x5471 呱 (<CJK Ideograph>) 6292 0x5476 呶 (<CJK Ideograph>) 6293 0x548C 和 (<CJK Ideograph>) 6294 0x549A 咚 (<CJK Ideograph>) 6295 0x5462 呢 (<CJK Ideograph>) 6296 0x5468 周 (<CJK Ideograph>) 6297 0x548B 咋 (<CJK Ideograph>) 6298 0x547D 命 (<CJK Ideograph>) 6299 0x548E 咎 (<CJK Ideograph>) 6300 0x56FA 固 (<CJK Ideograph>) 6301 0x5783 垃 (<CJK Ideograph>) 6302 0x5777 坷 (<CJK Ideograph>) 6303 0x576A 坪 (<CJK Ideograph>) 6304 0x5769 坩 (<CJK Ideograph>) 6305 0x5761 坡 (<CJK Ideograph>) 6306 0x5766 坦 (<CJK Ideograph>) 6307 0x5764 坤 (<CJK Ideograph>) 6308 0x577C 坼 (<CJK Ideograph>) 6309 0x591C 夜 (<CJK Ideograph>) 6310 0x5949 奉 (<CJK Ideograph>) 6311 0x5947 奇 (<CJK Ideograph>) 6312 0x5948 奈 (<CJK Ideograph>) 6313 0x5944 奄 (<CJK Ideograph>) 6314 0x5954 奔 (<CJK Ideograph>) 6315 0x59BE 妾 (<CJK Ideograph>) 6316 0x59BB 妻 (<CJK Ideograph>) 6317 0x59D4 委 (<CJK Ideograph>) 6318 0x59B9 妹 (<CJK Ideograph>) 6319 0x59AE 妮 (<CJK Ideograph>) 6320 0x59D1 姑 (<CJK Ideograph>) 6321 0x59C6 姆 (<CJK Ideograph>) 6322 0x59D0 姐 (<CJK Ideograph>) 6323 0x59CD 姍 (<CJK Ideograph>) 6324 0x59CB 始 (<CJK Ideograph>) 6325 0x59D3 姓 (<CJK Ideograph>) 6326 0x59CA 姊 (<CJK Ideograph>) 6327 0x59AF 妯 (<CJK Ideograph>) 6328 0x59B3 妳 (<CJK Ideograph>) 6329 0x59D2 姒 (<CJK Ideograph>) 6330 0x59C5 姅 (<CJK Ideograph>) 6331 0x5B5F 孟 (<CJK Ideograph>) 6332 0x5B64 孤 (<CJK Ideograph>) 6333 0x5B63 季 (<CJK Ideograph>) 6334 0x5B97 宗 (<CJK Ideograph>) 6335 0x5B9A 定 (<CJK Ideograph>) 6336 0x5B98 官 (<CJK Ideograph>) 6337 0x5B9C 宜 (<CJK Ideograph>) 6338 0x5B99 宙 (<CJK Ideograph>) 6339 0x5B9B 宛 (<CJK Ideograph>) 6340 0x5C1A 尚 (<CJK Ideograph>) 6341 0x5C48 屈 (<CJK Ideograph>) 6342 0x5C45 居 (<CJK Ideograph>) 6343 0x5C46 屆 (<CJK Ideograph>) 6344 0x5CB7 岷 (<CJK Ideograph>) 6345 0x5CA1 岡 (<CJK Ideograph>) 6346 0x5CB8 岸 (<CJK Ideograph>) 6347 0x5CA9 岩 (<CJK Ideograph>) 6348 0x5CAB 岫 (<CJK Ideograph>) 6349 0x5CB1 岱 (<CJK Ideograph>) 6350 0x5CB3 岳 (<CJK Ideograph>) 6351 0x5E18 帘 (<CJK Ideograph>) 6352 0x5E1A 帚 (<CJK Ideograph>) 6353 0x5E16 帖 (<CJK Ideograph>) 6354 0x5E15 帕 (<CJK Ideograph>) 6355 0x5E1B 帛 (<CJK Ideograph>) 6356 0x5E11 帑 (<CJK Ideograph>) 6357 0x5E78 幸 (<CJK Ideograph>) 6358 0x5E9A 庚 (<CJK Ideograph>) 6359 0x5E97 店 (<CJK Ideograph>) 6360 0x5E9C 府 (<CJK Ideograph>) 6361 0x5E95 底 (<CJK Ideograph>) 6362 0x5E96 庖 (<CJK Ideograph>) 6363 0x5EF6 延 (<CJK Ideograph>) 6364 0x5F26 弦 (<CJK Ideograph>) 6365 0x5F27 弧 (<CJK Ideograph>) 6366 0x5F29 弩 (<CJK Ideograph>) 6367 0x5F80 往 (<CJK Ideograph>) 6368 0x5F81 征 (<CJK Ideograph>) 6369 0x5F7F 彿 (<CJK Ideograph>) 6370 0x5F7C 彼 (<CJK Ideograph>) 6371 0x5FDD 忝 (<CJK Ideograph>) 6372 0x5FE0 忠 (<CJK Ideograph>) 6373 0x5FFD 忽 (<CJK Ideograph>) 6374 0x5FF5 念 (<CJK Ideograph>) 6375 0x5FFF 忿 (<CJK Ideograph>) 6376 0x600F 怏 (<CJK Ideograph>) 6377 0x6014 怔 (<CJK Ideograph>) 6378 0x602F 怯 (<CJK Ideograph>) 6379 0x6035 怵 (<CJK Ideograph>) 6380 0x6016 怖 (<CJK Ideograph>) 6381 0x602A 怪 (<CJK Ideograph>) 6382 0x6015 怕 (<CJK Ideograph>) 6383 0x6021 怡 (<CJK Ideograph>) 6384 0x6027 性 (<CJK Ideograph>) 6385 0x6029 怩 (<CJK Ideograph>) 6386 0x602B 怫 (<CJK Ideograph>) 6387 0x601B 怛 (<CJK Ideograph>) 6388 0x6216 或 (<CJK Ideograph>) 6389 0x6215 戕 (<CJK Ideograph>) 6390 0x623F 房 (<CJK Ideograph>) 6391 0x623E 戾 (<CJK Ideograph>) 6392 0x6240 所 (<CJK Ideograph>) 6393 0x627F 承 (<CJK Ideograph>) 6394 0x62C9 拉 (<CJK Ideograph>) 6395 0x62CC 拌 (<CJK Ideograph>) 6396 0x62C4 拄 (<CJK Ideograph>) 6397 0x62BF 抿 (<CJK Ideograph>) 6398 0x62C2 拂 (<CJK Ideograph>) 6399 0x62B9 抹 (<CJK Ideograph>) 6400 0x62D2 拒 (<CJK Ideograph>) 6401 0x62DB 招 (<CJK Ideograph>) 6402 0x62AB 披 (<CJK Ideograph>) 6403 0x62D3 拓 (<CJK Ideograph>) 6404 0x62D4 拔 (<CJK Ideograph>) 6405 0x62CB 拋 (<CJK Ideograph>) 6406 0x62C8 拈 (<CJK Ideograph>) 6407 0x62A8 抨 (<CJK Ideograph>) 6408 0x62BD 抽 (<CJK Ideograph>) 6409 0x62BC 押 (<CJK Ideograph>) 6410 0x62D0 拐 (<CJK Ideograph>) 6411 0x62D9 拙 (<CJK Ideograph>) 6412 0x62C7 拇 (<CJK Ideograph>) 6413 0x62CD 拍 (<CJK Ideograph>) 6414 0x62B5 抵 (<CJK Ideograph>) 6415 0x62DA 拚 (<CJK Ideograph>) 6416 0x62B1 抱 (<CJK Ideograph>) 6417 0x62D8 拘 (<CJK Ideograph>) 6418 0x62D6 拖 (<CJK Ideograph>) 6419 0x62D7 拗 (<CJK Ideograph>) 6420 0x62C6 拆 (<CJK Ideograph>) 6421 0x62AC 抬 (<CJK Ideograph>) 6422 0x62CE 拎 (<CJK Ideograph>) 6423 0x653E 放 (<CJK Ideograph>) 6424 0x65A7 斧 (<CJK Ideograph>) 6425 0x65BC 於 (<CJK Ideograph>) 6426 0x65FA 旺 (<CJK Ideograph>) 6427 0x6614 昔 (<CJK Ideograph>) 6428 0x6613 易 (<CJK Ideograph>) 6429 0x660C 昌 (<CJK Ideograph>) 6430 0x6606 昆 (<CJK Ideograph>) 6431 0x6602 昂 (<CJK Ideograph>) 6432 0x660E 明 (<CJK Ideograph>) 6433 0x6600 昀 (<CJK Ideograph>) 6434 0x660F 昏 (<CJK Ideograph>) 6435 0x6615 昕 (<CJK Ideograph>) 6436 0x660A 昊 (<CJK Ideograph>) 6437 0x6607 昇 (<CJK Ideograph>) 6438 0x670D 服 (<CJK Ideograph>) 6439 0x670B 朋 (<CJK Ideograph>) 6440 0x676D 杭 (<CJK Ideograph>) 6441 0x678B 枋 (<CJK Ideograph>) 6442 0x6795 枕 (<CJK Ideograph>) 6443 0x6771 東 (<CJK Ideograph>) 6444 0x679C 果 (<CJK Ideograph>) 6445 0x6773 杳 (<CJK Ideograph>) 6446 0x6777 杷 (<CJK Ideograph>) 6447 0x6787 枇 (<CJK Ideograph>) 6448 0x679D 枝 (<CJK Ideograph>) 6449 0x6797 林 (<CJK Ideograph>) 6450 0x676F 杯 (<CJK Ideograph>) 6451 0x6770 杰 (<CJK Ideograph>) 6452 0x677F 板 (<CJK Ideograph>) 6453 0x6789 枉 (<CJK Ideograph>) 6454 0x677E 松 (<CJK Ideograph>) 6455 0x6790 析 (<CJK Ideograph>) 6456 0x6775 杵 (<CJK Ideograph>) 6457 0x679A 枚 (<CJK Ideograph>) 6458 0x6793 枓 (<CJK Ideograph>) 6459 0x677C 杼 (<CJK Ideograph>) 6460 0x676A 杪 (<CJK Ideograph>) 6461 0x6772 杲 (<CJK Ideograph>) 6462 0x6B23 欣 (<CJK Ideograph>) 6463 0x6B66 武 (<CJK Ideograph>) 6464 0x6B67 歧 (<CJK Ideograph>) 6465 0x6B7F 歿 (<CJK Ideograph>) 6466 0x6C13 氓 (<CJK Ideograph>) 6467 0x6C1B 氛 (<CJK Ideograph>) 6468 0x6CE3 泣 (<CJK Ideograph>) 6469 0x6CE8 注 (<CJK Ideograph>) 6470 0x6CF3 泳 (<CJK Ideograph>) 6471 0x6CB1 沱 (<CJK Ideograph>) 6472 0x6CCC 泌 (<CJK Ideograph>) 6473 0x6CE5 泥 (<CJK Ideograph>) 6474 0x6CB3 河 (<CJK Ideograph>) 6475 0x6CBD 沽 (<CJK Ideograph>) 6476 0x6CBE 沾 (<CJK Ideograph>) 6477 0x6CBC 沼 (<CJK Ideograph>) 6478 0x6CE2 波 (<CJK Ideograph>) 6479 0x6CAB 沫 (<CJK Ideograph>) 6480 0x6CD5 法 (<CJK Ideograph>) 6481 0x6CD3 泓 (<CJK Ideograph>) 6482 0x6CB8 沸 (<CJK Ideograph>) 6483 0x6CC4 泄 (<CJK Ideograph>) 6484 0x6CB9 油 (<CJK Ideograph>) 6485 0x6CC1 況 (<CJK Ideograph>) 6486 0x6CAE 沮 (<CJK Ideograph>) 6487 0x6CD7 泗 (<CJK Ideograph>) 6488 0x6CC5 泅 (<CJK Ideograph>) 6489 0x6CF1 泱 (<CJK Ideograph>) 6490 0x6CBF 沿 (<CJK Ideograph>) 6491 0x6CBB 治 (<CJK Ideograph>) 6492 0x6CE1 泡 (<CJK Ideograph>) 6493 0x6CDB 泛 (<CJK Ideograph>) 6494 0x6CCA 泊 (<CJK Ideograph>) 6495 0x6CAC 沬 (<CJK Ideograph>) 6496 0x6CEF 泯 (<CJK Ideograph>) 6497 0x6CDC 泜 (<CJK Ideograph>) 6498 0x6CD6 泖 (<CJK Ideograph>) 6499 0x6CE0 泠 (<CJK Ideograph>) 6500 0x7095 炕 (<CJK Ideograph>) 6501 0x708E 炎 (<CJK Ideograph>) 6502 0x7092 炒 (<CJK Ideograph>) 6503 0x708A 炊 (<CJK Ideograph>) 6504 0x7099 炙 (<CJK Ideograph>) 6505 0x722C 爬 (<CJK Ideograph>) 6506 0x722D 爭 (<CJK Ideograph>) 6507 0x7238 爸 (<CJK Ideograph>) 6508 0x7248 版 (<CJK Ideograph>) 6509 0x7267 牧 (<CJK Ideograph>) 6510 0x7269 物 (<CJK Ideograph>) 6511 0x72C0 狀 (<CJK Ideograph>) 6512 0x72CE 狎 (<CJK Ideograph>) 6513 0x72D9 狙 (<CJK Ideograph>) 6514 0x72D7 狗 (<CJK Ideograph>) 6515 0x72D0 狐 (<CJK Ideograph>) 6516 0x73A9 玩 (<CJK Ideograph>) 6517 0x73A8 玨 (<CJK Ideograph>) 6518 0x739F 玟 (<CJK Ideograph>) 6519 0x73AB 玫 (<CJK Ideograph>) 6520 0x73A5 玥 (<CJK Ideograph>) 6521 0x753D 甽 (<CJK Ideograph>) 6522 0x759D 疝 (<CJK Ideograph>) 6523 0x7599 疙 (<CJK Ideograph>) 6524 0x759A 疚 (<CJK Ideograph>) 6525 0x7684 的 (<CJK Ideograph>) 6526 0x76C2 盂 (<CJK Ideograph>) 6527 0x76F2 盲 (<CJK Ideograph>) 6528 0x76F4 直 (<CJK Ideograph>) 6529 0x77E5 知 (<CJK Ideograph>) 6530 0x77FD 矽 (<CJK Ideograph>) 6531 0x793E 社 (<CJK Ideograph>) 6532 0x7940 祀 (<CJK Ideograph>) 6533 0x7941 祁 (<CJK Ideograph>) 6534 0x79C9 秉 (<CJK Ideograph>) 6535 0x79C8 秈 (<CJK Ideograph>) 6536 0x7A7A 空 (<CJK Ideograph>) 6537 0x7A79 穹 (<CJK Ideograph>) 6538 0x7AFA 竺 (<CJK Ideograph>) 6539 0x7CFE 糾 (<CJK Ideograph>) 6540 0x7F54 罔 (<CJK Ideograph>) 6541 0x7F8C 羌 (<CJK Ideograph>) 6542 0x7F8B 羋 (<CJK Ideograph>) 6543 0x8005 者 (<CJK Ideograph>) 6544 0x80BA 肺 (<CJK Ideograph>) 6545 0x80A5 肥 (<CJK Ideograph>) 6546 0x80A2 肢 (<CJK Ideograph>) 6547 0x80B1 肱 (<CJK Ideograph>) 6548 0x80A1 股 (<CJK Ideograph>) 6549 0x80AB 肫 (<CJK Ideograph>) 6550 0x80A9 肩 (<CJK Ideograph>) 6551 0x80B4 肴 (<CJK Ideograph>) 6552 0x80AA 肪 (<CJK Ideograph>) 6553 0x80AF 肯 (<CJK Ideograph>) 6554 0x81E5 臥 (<CJK Ideograph>) 6555 0x81FE 臾 (<CJK Ideograph>) 6556 0x820D 舍 (<CJK Ideograph>) 6557 0x82B3 芳 (<CJK Ideograph>) 6558 0x829D 芝 (<CJK Ideograph>) 6559 0x8299 芙 (<CJK Ideograph>) 6560 0x82AD 芭 (<CJK Ideograph>) 6561 0x82BD 芽 (<CJK Ideograph>) 6562 0x829F 芟 (<CJK Ideograph>) 6563 0x82B9 芹 (<CJK Ideograph>) 6564 0x82B1 花 (<CJK Ideograph>) 6565 0x82AC 芬 (<CJK Ideograph>) 6566 0x82A5 芥 (<CJK Ideograph>) 6567 0x82AF 芯 (<CJK Ideograph>) 6568 0x82B8 芸 (<CJK Ideograph>) 6569 0x82A3 芣 (<CJK Ideograph>) 6570 0x82B0 芰 (<CJK Ideograph>) 6571 0x82BE 芾 (<CJK Ideograph>) 6572 0x82B7 芷 (<CJK Ideograph>) 6573 0x864E 虎 (<CJK Ideograph>) 6574 0x8671 虱 (<CJK Ideograph>) 6575 0x521D 初 (<CJK Ideograph>) 6576 0x8868 表 (<CJK Ideograph>) 6577 0x8ECB 軋 (<CJK Ideograph>) 6578 0x8FCE 迎 (<CJK Ideograph>) 6579 0x8FD4 返 (<CJK Ideograph>) 6580 0x8FD1 近 (<CJK Ideograph>) 6581 0x90B5 邵 (<CJK Ideograph>) 6582 0x90B8 邸 (<CJK Ideograph>) 6583 0x90B1 邱 (<CJK Ideograph>) 6584 0x90B6 邶 (<CJK Ideograph>) 6585 0x91C7 采 (<CJK Ideograph>) 6586 0x91D1 金 (<CJK Ideograph>) 6587 0x9577 長 (<CJK Ideograph>) 6588 0x9580 門 (<CJK Ideograph>) 6589 0x961C 阜 (<CJK Ideograph>) 6590 0x9640 陀 (<CJK Ideograph>) 6591 0x963F 阿 (<CJK Ideograph>) 6592 0x963B 阻 (<CJK Ideograph>) 6593 0x9644 附 (<CJK Ideograph>) 6594 0x9642 陂 (<CJK Ideograph>) 6595 0x96B9 隹 (<CJK Ideograph>) 6596 0x96E8 雨 (<CJK Ideograph>) 6597 0x9752 青 (<CJK Ideograph>) 6598 0x975E 非 (<CJK Ideograph>) 6599 0x4E9F 亟 (<CJK Ideograph>) 6600 0x4EAD 亭 (<CJK Ideograph>) 6601 0x4EAE 亮 (<CJK Ideograph>) 6602 0x4FE1 信 (<CJK Ideograph>) 6603 0x4FB5 侵 (<CJK Ideograph>) 6604 0x4FAF 侯 (<CJK Ideograph>) 6605 0x4FBF 便 (<CJK Ideograph>) 6606 0x4FE0 俠 (<CJK Ideograph>) 6607 0x4FD1 俑 (<CJK Ideograph>) 6608 0x4FCF 俏 (<CJK Ideograph>) 6609 0x4FDD 保 (<CJK Ideograph>) 6610 0x4FC3 促 (<CJK Ideograph>) 6611 0x4FB6 侶 (<CJK Ideograph>) 6612 0x4FD8 俘 (<CJK Ideograph>) 6613 0x4FDF 俟 (<CJK Ideograph>) 6614 0x4FCA 俊 (<CJK Ideograph>) 6615 0x4FD7 俗 (<CJK Ideograph>) 6616 0x4FAE 侮 (<CJK Ideograph>) 6617 0x4FD0 俐 (<CJK Ideograph>) 6618 0x4FC4 俄 (<CJK Ideograph>) 6619 0x4FC2 係 (<CJK Ideograph>) 6620 0x4FDA 俚 (<CJK Ideograph>) 6621 0x4FCE 俎 (<CJK Ideograph>) 6622 0x4FDE 俞 (<CJK Ideograph>) 6623 0x4FB7 侷 (<CJK Ideograph>) 6624 0x5157 兗 (<CJK Ideograph>) 6625 0x5192 冒 (<CJK Ideograph>) 6626 0x5191 冑 (<CJK Ideograph>) 6627 0x51A0 冠 (<CJK Ideograph>) 6628 0x524E 剎 (<CJK Ideograph>) 6629 0x5243 剃 (<CJK Ideograph>) 6630 0x524A 削 (<CJK Ideograph>) 6631 0x524D 前 (<CJK Ideograph>) 6632 0x524C 剌 (<CJK Ideograph>) 6633 0x524B 剋 (<CJK Ideograph>) 6634 0x5247 則 (<CJK Ideograph>) 6635 0x52C7 勇 (<CJK Ideograph>) 6636 0x52C9 勉 (<CJK Ideograph>) 6637 0x52C3 勃 (<CJK Ideograph>) 6638 0x52C1 勁 (<CJK Ideograph>) 6639 0x530D 匍 (<CJK Ideograph>) 6640 0x5357 南 (<CJK Ideograph>) 6641 0x537B 卻 (<CJK Ideograph>) 6642 0x539A 厚 (<CJK Ideograph>) 6643 0x53DB 叛 (<CJK Ideograph>) 6644 0x54AC 咬 (<CJK Ideograph>) 6645 0x54C0 哀 (<CJK Ideograph>) 6646 0x54A8 咨 (<CJK Ideograph>) 6647 0x54CE 哎 (<CJK Ideograph>) 6648 0x54C9 哉 (<CJK Ideograph>) 6649 0x54B8 咸 (<CJK Ideograph>) 6650 0x54A6 咦 (<CJK Ideograph>) 6651 0x54B3 咳 (<CJK Ideograph>) 6652 0x54C7 哇 (<CJK Ideograph>) 6653 0x54C2 哂 (<CJK Ideograph>) 6654 0x54BD 咽 (<CJK Ideograph>) 6655 0x54AA 咪 (<CJK Ideograph>) 6656 0x54C1 品 (<CJK Ideograph>) 6657 0x54C4 哄 (<CJK Ideograph>) 6658 0x54C8 哈 (<CJK Ideograph>) 6659 0x54AF 咯 (<CJK Ideograph>) 6660 0x54AB 咫 (<CJK Ideograph>) 6661 0x54B1 咱 (<CJK Ideograph>) 6662 0x54BB 咻 (<CJK Ideograph>) 6663 0x54A9 咩 (<CJK Ideograph>) 6664 0x54A7 咧 (<CJK Ideograph>) 6665 0x54BF 咿 (<CJK Ideograph>) 6666 0x56FF 囿 (<CJK Ideograph>) 6667 0x5782 垂 (<CJK Ideograph>) 6668 0x578B 型 (<CJK Ideograph>) 6669 0x57A0 垠 (<CJK Ideograph>) 6670 0x57A3 垣 (<CJK Ideograph>) 6671 0x57A2 垢 (<CJK Ideograph>) 6672 0x57CE 城 (<CJK Ideograph>) 6673 0x57AE 垮 (<CJK Ideograph>) 6674 0x5793 垓 (<CJK Ideograph>) 6675 0x5955 奕 (<CJK Ideograph>) 6676 0x5951 契 (<CJK Ideograph>) 6677 0x594F 奏 (<CJK Ideograph>) 6678 0x594E 奎 (<CJK Ideograph>) 6679 0x5950 奐 (<CJK Ideograph>) 6680 0x59DC 姜 (<CJK Ideograph>) 6681 0x59D8 姘 (<CJK Ideograph>) 6682 0x59FF 姿 (<CJK Ideograph>) 6683 0x59E3 姣 (<CJK Ideograph>) 6684 0x59E8 姨 (<CJK Ideograph>) 6685 0x5A03 娃 (<CJK Ideograph>) 6686 0x59E5 姥 (<CJK Ideograph>) 6687 0x59EA 姪 (<CJK Ideograph>) 6688 0x59DA 姚 (<CJK Ideograph>) 6689 0x59E6 姦 (<CJK Ideograph>) 6690 0x5A01 威 (<CJK Ideograph>) 6691 0x59FB 姻 (<CJK Ideograph>) 6692 0x5B69 孩 (<CJK Ideograph>) 6693 0x5BA3 宣 (<CJK Ideograph>) 6694 0x5BA6 宦 (<CJK Ideograph>) 6695 0x5BA4 室 (<CJK Ideograph>) 6696 0x5BA2 客 (<CJK Ideograph>) 6697 0x5BA5 宥 (<CJK Ideograph>) 6698 0x5C01 封 (<CJK Ideograph>) 6699 0x5C4E 屎 (<CJK Ideograph>) 6700 0x5C4F 屏 (<CJK Ideograph>) 6701 0x5C4D 屍 (<CJK Ideograph>) 6702 0x5C4B 屋 (<CJK Ideograph>) 6703 0x5CD9 峙 (<CJK Ideograph>) 6704 0x5CD2 峒 (<CJK Ideograph>) 6705 0x5DF7 巷 (<CJK Ideograph>) 6706 0x5E1D 帝 (<CJK Ideograph>) 6707 0x5E25 帥 (<CJK Ideograph>) 6708 0x5E1F 帟 (<CJK Ideograph>) 6709 0x5E7D 幽 (<CJK Ideograph>) 6710 0x5EA0 庠 (<CJK Ideograph>) 6711 0x5EA6 度 (<CJK Ideograph>) 6712 0x5EFA 建 (<CJK Ideograph>) 6713 0x5F08 弈 (<CJK Ideograph>) 6714 0x5F2D 弭 (<CJK Ideograph>) 6715 0x5F65 彥 (<CJK Ideograph>) 6716 0x5F88 很 (<CJK Ideograph>) 6717 0x5F85 待 (<CJK Ideograph>) 6718 0x5F8A 徊 (<CJK Ideograph>) 6719 0x5F8B 律 (<CJK Ideograph>) 6720 0x5F87 徇 (<CJK Ideograph>) 6721 0x5F8C 後 (<CJK Ideograph>) 6722 0x5F89 徉 (<CJK Ideograph>) 6723 0x6012 怒 (<CJK Ideograph>) 6724 0x601D 思 (<CJK Ideograph>) 6725 0x6020 怠 (<CJK Ideograph>) 6726 0x6025 急 (<CJK Ideograph>) 6727 0x600E 怎 (<CJK Ideograph>) 6728 0x6028 怨 (<CJK Ideograph>) 6729 0x604D 恍 (<CJK Ideograph>) 6730 0x6070 恰 (<CJK Ideograph>) 6731 0x6068 恨 (<CJK Ideograph>) 6732 0x6062 恢 (<CJK Ideograph>) 6733 0x6046 恆 (<CJK Ideograph>) 6734 0x6043 恃 (<CJK Ideograph>) 6735 0x606C 恬 (<CJK Ideograph>) 6736 0x606B 恫 (<CJK Ideograph>) 6737 0x606A 恪 (<CJK Ideograph>) 6738 0x6064 恤 (<CJK Ideograph>) 6739 0x6241 扁 (<CJK Ideograph>) 6740 0x62DC 拜 (<CJK Ideograph>) 6741 0x6316 挖 (<CJK Ideograph>) 6742 0x6309 按 (<CJK Ideograph>) 6743 0x62FC 拼 (<CJK Ideograph>) 6744 0x62ED 拭 (<CJK Ideograph>) 6745 0x6301 持 (<CJK Ideograph>) 6746 0x62EE 拮 (<CJK Ideograph>) 6747 0x62FD 拽 (<CJK Ideograph>) 6748 0x6307 指 (<CJK Ideograph>) 6749 0x62F1 拱 (<CJK Ideograph>) 6750 0x62F7 拷 (<CJK Ideograph>) 6751 0x62EF 拯 (<CJK Ideograph>) 6752 0x62EC 括 (<CJK Ideograph>) 6753 0x62FE 拾 (<CJK Ideograph>) 6754 0x62F4 拴 (<CJK Ideograph>) 6755 0x6311 挑 (<CJK Ideograph>) 6756 0x6302 挂 (<CJK Ideograph>) 6757 0x653F 政 (<CJK Ideograph>) 6758 0x6545 故 (<CJK Ideograph>) 6759 0x65AB 斫 (<CJK Ideograph>) 6760 0x65BD 施 (<CJK Ideograph>) 6761 0x65E2 既 (<CJK Ideograph>) 6762 0x6625 春 (<CJK Ideograph>) 6763 0x662D 昭 (<CJK Ideograph>) 6764 0x6620 映 (<CJK Ideograph>) 6765 0x6627 昧 (<CJK Ideograph>) 6766 0x662F 是 (<CJK Ideograph>) 6767 0x661F 星 (<CJK Ideograph>) 6768 0x6628 昨 (<CJK Ideograph>) 6769 0x6631 昱 (<CJK Ideograph>) 6770 0x6624 昤 (<CJK Ideograph>) 6771 0x66F7 曷 (<CJK Ideograph>) 6772 0x67FF 柿 (<CJK Ideograph>) 6773 0x67D3 染 (<CJK Ideograph>) 6774 0x67F1 柱 (<CJK Ideograph>) 6775 0x67D4 柔 (<CJK Ideograph>) 6776 0x67D0 某 (<CJK Ideograph>) 6777 0x67EC 柬 (<CJK Ideograph>) 6778 0x67B6 架 (<CJK Ideograph>) 6779 0x67AF 枯 (<CJK Ideograph>) 6780 0x67F5 柵 (<CJK Ideograph>) 6781 0x67E9 柩 (<CJK Ideograph>) 6782 0x67EF 柯 (<CJK Ideograph>) 6783 0x67C4 柄 (<CJK Ideograph>) 6784 0x67D1 柑 (<CJK Ideograph>) 6785 0x67B4 枴 (<CJK Ideograph>) 6786 0x67DA 柚 (<CJK Ideograph>) 6787 0x67E5 查 (<CJK Ideograph>) 6788 0x67B8 枸 (<CJK Ideograph>) 6789 0x67CF 柏 (<CJK Ideograph>) 6790 0x67DE 柞 (<CJK Ideograph>) 6791 0x67F3 柳 (<CJK Ideograph>) 6792 0x67B0 枰 (<CJK Ideograph>) 6793 0x67D9 柙 (<CJK Ideograph>) 6794 0x67E2 柢 (<CJK Ideograph>) 6795 0x67DD 柝 (<CJK Ideograph>) 6796 0x67D2 柒 (<CJK Ideograph>) 6797 0x6B6A 歪 (<CJK Ideograph>) 6798 0x6B83 殃 (<CJK Ideograph>) 6799 0x6B86 殆 (<CJK Ideograph>) 6800 0x6BB5 段 (<CJK Ideograph>) 6801 0x6BD2 毒 (<CJK Ideograph>) 6802 0x6BD7 毗 (<CJK Ideograph>) 6803 0x6C1F 氟 (<CJK Ideograph>) 6804 0x6CC9 泉 (<CJK Ideograph>) 6805 0x6D0B 洋 (<CJK Ideograph>) 6806 0x6D32 洲 (<CJK Ideograph>) 6807 0x6D2A 洪 (<CJK Ideograph>) 6808 0x6D41 流 (<CJK Ideograph>) 6809 0x6D25 津 (<CJK Ideograph>) 6810 0x6D0C 洌 (<CJK Ideograph>) 6811 0x6D31 洱 (<CJK Ideograph>) 6812 0x6D1E 洞 (<CJK Ideograph>) 6813 0x6D17 洗 (<CJK Ideograph>) 6814 0x6D3B 活 (<CJK Ideograph>) 6815 0x6D3D 洽 (<CJK Ideograph>) 6816 0x6D3E 派 (<CJK Ideograph>) 6817 0x6D36 洶 (<CJK Ideograph>) 6818 0x6D1B 洛 (<CJK Ideograph>) 6819 0x6CF5 泵 (<CJK Ideograph>) 6820 0x6D39 洹 (<CJK Ideograph>) 6821 0x6D27 洧 (<CJK Ideograph>) 6822 0x6D38 洸 (<CJK Ideograph>) 6823 0x6D29 洩 (<CJK Ideograph>) 6824 0x6D2E 洮 (<CJK Ideograph>) 6825 0x6D35 洵 (<CJK Ideograph>) 6826 0x6D0E 洎 (<CJK Ideograph>) 6827 0x6D2B 洫 (<CJK Ideograph>) 6828 0x70AB 炫 (<CJK Ideograph>) 6829 0x70BA 為 (<CJK Ideograph>) 6830 0x70B3 炳 (<CJK Ideograph>) 6831 0x70AC 炬 (<CJK Ideograph>) 6832 0x70AF 炯 (<CJK Ideograph>) 6833 0x70AD 炭 (<CJK Ideograph>) 6834 0x70B8 炸 (<CJK Ideograph>) 6835 0x70AE 炮 (<CJK Ideograph>) 6836 0x70A4 炤 (<CJK Ideograph>) 6837 0x7230 爰 (<CJK Ideograph>) 6838 0x7272 牲 (<CJK Ideograph>) 6839 0x726F 牯 (<CJK Ideograph>) 6840 0x7274 牴 (<CJK Ideograph>) 6841 0x72E9 狩 (<CJK Ideograph>) 6842 0x72E0 狠 (<CJK Ideograph>) 6843 0x72E1 狡 (<CJK Ideograph>) 6844 0x73B7 玷 (<CJK Ideograph>) 6845 0x73CA 珊 (<CJK Ideograph>) 6846 0x73BB 玻 (<CJK Ideograph>) 6847 0x73B2 玲 (<CJK Ideograph>) 6848 0x73CD 珍 (<CJK Ideograph>) 6849 0x73C0 珀 (<CJK Ideograph>) 6850 0x73B3 玳 (<CJK Ideograph>) 6851 0x751A 甚 (<CJK Ideograph>) 6852 0x752D 甭 (<CJK Ideograph>) 6853 0x754F 畏 (<CJK Ideograph>) 6854 0x754C 界 (<CJK Ideograph>) 6855 0x754E 畎 (<CJK Ideograph>) 6856 0x754B 畋 (<CJK Ideograph>) 6857 0x75AB 疫 (<CJK Ideograph>) 6858 0x75A4 疤 (<CJK Ideograph>) 6859 0x75A5 疥 (<CJK Ideograph>) 6860 0x75A2 疢 (<CJK Ideograph>) 6861 0x75A3 疣 (<CJK Ideograph>) 6862 0x7678 癸 (<CJK Ideograph>) 6863 0x7686 皆 (<CJK Ideograph>) 6864 0x7687 皇 (<CJK Ideograph>) 6865 0x7688 皈 (<CJK Ideograph>) 6866 0x76C8 盈 (<CJK Ideograph>) 6867 0x76C6 盆 (<CJK Ideograph>) 6868 0x76C3 盃 (<CJK Ideograph>) 6869 0x76C5 盅 (<CJK Ideograph>) 6870 0x7701 省 (<CJK Ideograph>) 6871 0x76F9 盹 (<CJK Ideograph>) 6872 0x76F8 相 (<CJK Ideograph>) 6873 0x7709 眉 (<CJK Ideograph>) 6874 0x770B 看 (<CJK Ideograph>) 6875 0x76FE 盾 (<CJK Ideograph>) 6876 0x76FC 盼 (<CJK Ideograph>) 6877 0x7707 眇 (<CJK Ideograph>) 6878 0x77DC 矜 (<CJK Ideograph>) 6879 0x7802 砂 (<CJK Ideograph>) 6880 0x7814 研 (<CJK Ideograph>) 6881 0x780C 砌 (<CJK Ideograph>) 6882 0x780D 砍 (<CJK Ideograph>) 6883 0x7946 祆 (<CJK Ideograph>) 6884 0x7949 祉 (<CJK Ideograph>) 6885 0x7948 祈 (<CJK Ideograph>) 6886 0x7947 祇 (<CJK Ideograph>) 6887 0x79B9 禹 (<CJK Ideograph>) 6888 0x79BA 禺 (<CJK Ideograph>) 6889 0x79D1 科 (<CJK Ideograph>) 6890 0x79D2 秒 (<CJK Ideograph>) 6891 0x79CB 秋 (<CJK Ideograph>) 6892 0x7A7F 穿 (<CJK Ideograph>) 6893 0x7A81 突 (<CJK Ideograph>) 6894 0x7AFF 竿 (<CJK Ideograph>) 6895 0x7AFD 竽 (<CJK Ideograph>) 6896 0x7C7D 籽 (<CJK Ideograph>) 6897 0x7D02 紂 (<CJK Ideograph>) 6898 0x7D05 紅 (<CJK Ideograph>) 6899 0x7D00 紀 (<CJK Ideograph>) 6900 0x7D09 紉 (<CJK Ideograph>) 6901 0x7D07 紇 (<CJK Ideograph>) 6902 0x7D04 約 (<CJK Ideograph>) 6903 0x7D06 紆 (<CJK Ideograph>) 6904 0x7F38 缸 (<CJK Ideograph>) 6905 0x7F8E 美 (<CJK Ideograph>) 6906 0x7FBF 羿 (<CJK Ideograph>) 6907 0x8004 耄 (<CJK Ideograph>) 6908 0x8010 耐 (<CJK Ideograph>) 6909 0x800D 耍 (<CJK Ideograph>) 6910 0x8011 耑 (<CJK Ideograph>) 6911 0x8036 耶 (<CJK Ideograph>) 6912 0x80D6 胖 (<CJK Ideograph>) 6913 0x80E5 胥 (<CJK Ideograph>) 6914 0x80DA 胚 (<CJK Ideograph>) 6915 0x80C3 胃 (<CJK Ideograph>) 6916 0x80C4 胄 (<CJK Ideograph>) 6917 0x80CC 背 (<CJK Ideograph>) 6918 0x80E1 胡 (<CJK Ideograph>) 6919 0x80DB 胛 (<CJK Ideograph>) 6920 0x80CE 胎 (<CJK Ideograph>) 6921 0x80DE 胞 (<CJK Ideograph>) 6922 0x80E4 胤 (<CJK Ideograph>) 6923 0x80DD 胝 (<CJK Ideograph>) 6924 0x81F4 致 (<CJK Ideograph>) 6925 0x8222 舢 (<CJK Ideograph>) 6926 0x82E7 苧 (<CJK Ideograph>) 6927 0x8303 范 (<CJK Ideograph>) 6928 0x8305 茅 (<CJK Ideograph>) 6929 0x82E3 苣 (<CJK Ideograph>) 6930 0x82DB 苛 (<CJK Ideograph>) 6931 0x82E6 苦 (<CJK Ideograph>) 6932 0x8304 茄 (<CJK Ideograph>) 6933 0x82E5 若 (<CJK Ideograph>) 6934 0x8302 茂 (<CJK Ideograph>) 6935 0x8309 茉 (<CJK Ideograph>) 6936 0x82D2 苒 (<CJK Ideograph>) 6937 0x82D7 苗 (<CJK Ideograph>) 6938 0x82F1 英 (<CJK Ideograph>) 6939 0x8301 茁 (<CJK Ideograph>) 6940 0x82DC 苜 (<CJK Ideograph>) 6941 0x82D4 苔 (<CJK Ideograph>) 6942 0x82D1 苑 (<CJK Ideograph>) 6943 0x82DE 苞 (<CJK Ideograph>) 6944 0x82D3 苓 (<CJK Ideograph>) 6945 0x82DF 苟 (<CJK Ideograph>) 6946 0x82EF 苯 (<CJK Ideograph>) 6947 0x8306 茆 (<CJK Ideograph>) 6948 0x8650 虐 (<CJK Ideograph>) 6949 0x8679 虹 (<CJK Ideograph>) 6950 0x867B 虻 (<CJK Ideograph>) 6951 0x867A 虺 (<CJK Ideograph>) 6952 0x884D 衍 (<CJK Ideograph>) 6953 0x886B 衫 (<CJK Ideograph>) 6954 0x8981 要 (<CJK Ideograph>) 6955 0x89D4 觔 (<CJK Ideograph>) 6956 0x8A08 計 (<CJK Ideograph>) 6957 0x8A02 訂 (<CJK Ideograph>) 6958 0x8A03 訃 (<CJK Ideograph>) 6959 0x8C9E 貞 (<CJK Ideograph>) 6960 0x8CA0 負 (<CJK Ideograph>) 6961 0x8D74 赴 (<CJK Ideograph>) 6962 0x8D73 赳 (<CJK Ideograph>) 6963 0x8DB4 趴 (<CJK Ideograph>) 6964 0x8ECD 軍 (<CJK Ideograph>) 6965 0x8ECC 軌 (<CJK Ideograph>) 6966 0x8FF0 述 (<CJK Ideograph>) 6967 0x8FE6 迦 (<CJK Ideograph>) 6968 0x8FE2 迢 (<CJK Ideograph>) 6969 0x8FEA 迪 (<CJK Ideograph>) 6970 0x8FE5 迥 (<CJK Ideograph>) 6971 0x8FED 迭 (<CJK Ideograph>) 6972 0x8FEB 迫 (<CJK Ideograph>) 6973 0x8FE4 迤 (<CJK Ideograph>) 6974 0x8FE8 迨 (<CJK Ideograph>) 6975 0x90CA 郊 (<CJK Ideograph>) 6976 0x90CE 郎 (<CJK Ideograph>) 6977 0x90C1 郁 (<CJK Ideograph>) 6978 0x90C3 郃 (<CJK Ideograph>) 6979 0x914B 酋 (<CJK Ideograph>) 6980 0x914A 酊 (<CJK Ideograph>) 6981 0x91CD 重 (<CJK Ideograph>) 6982 0x9582 閂 (<CJK Ideograph>) 6983 0x9650 限 (<CJK Ideograph>) 6984 0x964B 陋 (<CJK Ideograph>) 6985 0x964C 陌 (<CJK Ideograph>) 6986 0x964D 降 (<CJK Ideograph>) 6987 0x9762 面 (<CJK Ideograph>) 6988 0x9769 革 (<CJK Ideograph>) 6989 0x97CB 韋 (<CJK Ideograph>) 6990 0x97ED 韭 (<CJK Ideograph>) 6991 0x97F3 音 (<CJK Ideograph>) 6992 0x9801 頁 (<CJK Ideograph>) 6993 0x98A8 風 (<CJK Ideograph>) 6994 0x98DB 飛 (<CJK Ideograph>) 6995 0x98DF 食 (<CJK Ideograph>) 6996 0x9996 首 (<CJK Ideograph>) 6997 0x9999 香 (<CJK Ideograph>) 6998 0x4E58 乘 (<CJK Ideograph>) 6999 0x4EB3 亳 (<CJK Ideograph>) 7000 0x500C 倌 (<CJK Ideograph>) 7001 0x500D 倍 (<CJK Ideograph>) 7002 0x5023 倣 (<CJK Ideograph>) 7003 0x4FEF 俯 (<CJK Ideograph>) 7004 0x5026 倦 (<CJK Ideograph>) 7005 0x5025 倥 (<CJK Ideograph>) 7006 0x4FF8 俸 (<CJK Ideograph>) 7007 0x5029 倩 (<CJK Ideograph>) 7008 0x5016 倖 (<CJK Ideograph>) 7009 0x5006 倆 (<CJK Ideograph>) 7010 0x503C 值 (<CJK Ideograph>) 7011 0x501F 借 (<CJK Ideograph>) 7012 0x501A 倚 (<CJK Ideograph>) 7013 0x5012 倒 (<CJK Ideograph>) 7014 0x5011 們 (<CJK Ideograph>) 7015 0x4FFA 俺 (<CJK Ideograph>) 7016 0x5000 倀 (<CJK Ideograph>) 7017 0x5014 倔 (<CJK Ideograph>) 7018 0x5028 倨 (<CJK Ideograph>) 7019 0x4FF1 俱 (<CJK Ideograph>) 7020 0x5021 倡 (<CJK Ideograph>) 7021 0x500B 個 (<CJK Ideograph>) 7022 0x5019 候 (<CJK Ideograph>) 7023 0x5018 倘 (<CJK Ideograph>) 7024 0x4FF3 俳 (<CJK Ideograph>) 7025 0x4FEE 修 (<CJK Ideograph>) 7026 0x502D 倭 (<CJK Ideograph>) 7027 0x502A 倪 (<CJK Ideograph>) 7028 0x4FFE 俾 (<CJK Ideograph>) 7029 0x502B 倫 (<CJK Ideograph>) 7030 0x5009 倉 (<CJK Ideograph>) 7031 0x517C 兼 (<CJK Ideograph>) 7032 0x51A4 冤 (<CJK Ideograph>) 7033 0x51A5 冥 (<CJK Ideograph>) 7034 0x51A2 冢 (<CJK Ideograph>) 7035 0x51CD 凍 (<CJK Ideograph>) 7036 0x51CC 凌 (<CJK Ideograph>) 7037 0x51C6 准 (<CJK Ideograph>) 7038 0x51CB 凋 (<CJK Ideograph>) 7039 0x5256 剖 (<CJK Ideograph>) 7040 0x525C 剜 (<CJK Ideograph>) 7041 0x5254 剔 (<CJK Ideograph>) 7042 0x525B 剛 (<CJK Ideograph>) 7043 0x525D 剝 (<CJK Ideograph>) 7044 0x532A 匪 (<CJK Ideograph>) 7045 0x537F 卿 (<CJK Ideograph>) 7046 0x539F 原 (<CJK Ideograph>) 7047 0x539D 厝 (<CJK Ideograph>) 7048 0x53DF 叟 (<CJK Ideograph>) 7049 0x54E8 哨 (<CJK Ideograph>) 7050 0x5510 唐 (<CJK Ideograph>) 7051 0x5501 唁 (<CJK Ideograph>) 7052 0x5537 唷 (<CJK Ideograph>) 7053 0x54FC 哼 (<CJK Ideograph>) 7054 0x54E5 哥 (<CJK Ideograph>) 7055 0x54F2 哲 (<CJK Ideograph>) 7056 0x5506 唆 (<CJK Ideograph>) 7057 0x54FA 哺 (<CJK Ideograph>) 7058 0x5514 唔 (<CJK Ideograph>) 7059 0x54E9 哩 (<CJK Ideograph>) 7060 0x54ED 哭 (<CJK Ideograph>) 7061 0x54E1 員 (<CJK Ideograph>) 7062 0x5509 唉 (<CJK Ideograph>) 7063 0x54EE 哮 (<CJK Ideograph>) 7064 0x54EA 哪 (<CJK Ideograph>) 7065 0x54E6 哦 (<CJK Ideograph>) 7066 0x5527 唧 (<CJK Ideograph>) 7067 0x5507 唇 (<CJK Ideograph>) 7068 0x54FD 哽 (<CJK Ideograph>) 7069 0x550F 唏 (<CJK Ideograph>) 7070 0x5703 圃 (<CJK Ideograph>) 7071 0x5704 圄 (<CJK Ideograph>) 7072 0x57C2 埂 (<CJK Ideograph>) 7073 0x57D4 埔 (<CJK Ideograph>) 7074 0x57CB 埋 (<CJK Ideograph>) 7075 0x57C3 埃 (<CJK Ideograph>) 7076 0x5809 堉 (<CJK Ideograph>) 7077 0x590F 夏 (<CJK Ideograph>) 7078 0x5957 套 (<CJK Ideograph>) 7079 0x5958 奘 (<CJK Ideograph>) 7080 0x595A 奚 (<CJK Ideograph>) 7081 0x5A11 娑 (<CJK Ideograph>) 7082 0x5A18 娘 (<CJK Ideograph>) 7083 0x5A1C 娜 (<CJK Ideograph>) 7084 0x5A1F 娟 (<CJK Ideograph>) 7085 0x5A1B 娛 (<CJK Ideograph>) 7086 0x5A13 娓 (<CJK Ideograph>) 7087 0x59EC 姬 (<CJK Ideograph>) 7088 0x5A20 娠 (<CJK Ideograph>) 7089 0x5A23 娣 (<CJK Ideograph>) 7090 0x5A29 娩 (<CJK Ideograph>) 7091 0x5A25 娥 (<CJK Ideograph>) 7092 0x5A0C 娌 (<CJK Ideograph>) 7093 0x5A09 娉 (<CJK Ideograph>) 7094 0x5B6B 孫 (<CJK Ideograph>) 7095 0x5C58 屘 (<CJK Ideograph>) 7096 0x5BB0 宰 (<CJK Ideograph>) 7097 0x5BB3 害 (<CJK Ideograph>) 7098 0x5BB6 家 (<CJK Ideograph>) 7099 0x5BB4 宴 (<CJK Ideograph>) 7100 0x5BAE 宮 (<CJK Ideograph>) 7101 0x5BB5 宵 (<CJK Ideograph>) 7102 0x5BB9 容 (<CJK Ideograph>) 7103 0x5BB8 宸 (<CJK Ideograph>) 7104 0x5C04 射 (<CJK Ideograph>) 7105 0x5C51 屑 (<CJK Ideograph>) 7106 0x5C55 展 (<CJK Ideograph>) 7107 0x5C50 屐 (<CJK Ideograph>) 7108 0x5CED 峭 (<CJK Ideograph>) 7109 0x5CFD 峽 (<CJK Ideograph>) 7110 0x5CFB 峻 (<CJK Ideograph>) 7111 0x5CEA 峪 (<CJK Ideograph>) 7112 0x5CE8 峨 (<CJK Ideograph>) 7113 0x5CF0 峰 (<CJK Ideograph>) 7114 0x5CF6 島 (<CJK Ideograph>) 7115 0x5D01 崁 (<CJK Ideograph>) 7116 0x5CF4 峴 (<CJK Ideograph>) 7117 0x5DEE 差 (<CJK Ideograph>) 7118 0x5E2D 席 (<CJK Ideograph>) 7119 0x5E2B 師 (<CJK Ideograph>) 7120 0x5EAB 庫 (<CJK Ideograph>) 7121 0x5EAD 庭 (<CJK Ideograph>) 7122 0x5EA7 座 (<CJK Ideograph>) 7123 0x5F31 弱 (<CJK Ideograph>) 7124 0x5F92 徒 (<CJK Ideograph>) 7125 0x5F91 徑 (<CJK Ideograph>) 7126 0x5F90 徐 (<CJK Ideograph>) 7127 0x6059 恙 (<CJK Ideograph>) 7128 0x6063 恣 (<CJK Ideograph>) 7129 0x6065 恥 (<CJK Ideograph>) 7130 0x6050 恐 (<CJK Ideograph>) 7131 0x6055 恕 (<CJK Ideograph>) 7132 0x606D 恭 (<CJK Ideograph>) 7133 0x6069 恩 (<CJK Ideograph>) 7134 0x606F 息 (<CJK Ideograph>) 7135 0x6084 悄 (<CJK Ideograph>) 7136 0x609F 悟 (<CJK Ideograph>) 7137 0x609A 悚 (<CJK Ideograph>) 7138 0x608D 悍 (<CJK Ideograph>) 7139 0x6094 悔 (<CJK Ideograph>) 7140 0x608C 悌 (<CJK Ideograph>) 7141 0x6085 悅 (<CJK Ideograph>) 7142 0x6096 悖 (<CJK Ideograph>) 7143 0x6247 扇 (<CJK Ideograph>) 7144 0x62F3 拳 (<CJK Ideograph>) 7145 0x6308 挈 (<CJK Ideograph>) 7146 0x62FF 拿 (<CJK Ideograph>) 7147 0x634E 捎 (<CJK Ideograph>) 7148 0x633E 挾 (<CJK Ideograph>) 7149 0x632F 振 (<CJK Ideograph>) 7150 0x6355 捕 (<CJK Ideograph>) 7151 0x6342 捂 (<CJK Ideograph>) 7152 0x6346 捆 (<CJK Ideograph>) 7153 0x634F 捏 (<CJK Ideograph>) 7154 0x6349 捉 (<CJK Ideograph>) 7155 0x633A 挺 (<CJK Ideograph>) 7156 0x6350 捐 (<CJK Ideograph>) 7157 0x633D 挽 (<CJK Ideograph>) 7158 0x632A 挪 (<CJK Ideograph>) 7159 0x632B 挫 (<CJK Ideograph>) 7160 0x6328 挨 (<CJK Ideograph>) 7161 0x634D 捍 (<CJK Ideograph>) 7162 0x634C 捌 (<CJK Ideograph>) 7163 0x6548 效 (<CJK Ideograph>) 7164 0x6549 敉 (<CJK Ideograph>) 7165 0x6599 料 (<CJK Ideograph>) 7166 0x65C1 旁 (<CJK Ideograph>) 7167 0x65C5 旅 (<CJK Ideograph>) 7168 0x6642 時 (<CJK Ideograph>) 7169 0x6649 晉 (<CJK Ideograph>) 7170 0x664F 晏 (<CJK Ideograph>) 7171 0x6643 晃 (<CJK Ideograph>) 7172 0x6652 晒 (<CJK Ideograph>) 7173 0x664C 晌 (<CJK Ideograph>) 7174 0x6645 晅 (<CJK Ideograph>) 7175 0x6641 晁 (<CJK Ideograph>) 7176 0x66F8 書 (<CJK Ideograph>) 7177 0x6714 朔 (<CJK Ideograph>) 7178 0x6715 朕 (<CJK Ideograph>) 7179 0x6717 朗 (<CJK Ideograph>) 7180 0x6821 校 (<CJK Ideograph>) 7181 0x6838 核 (<CJK Ideograph>) 7182 0x6848 案 (<CJK Ideograph>) 7183 0x6846 框 (<CJK Ideograph>) 7184 0x6853 桓 (<CJK Ideograph>) 7185 0x6839 根 (<CJK Ideograph>) 7186 0x6842 桂 (<CJK Ideograph>) 7187 0x6854 桔 (<CJK Ideograph>) 7188 0x6829 栩 (<CJK Ideograph>) 7189 0x68B3 梳 (<CJK Ideograph>) 7190 0x6817 栗 (<CJK Ideograph>) 7191 0x684C 桌 (<CJK Ideograph>) 7192 0x6851 桑 (<CJK Ideograph>) 7193 0x683D 栽 (<CJK Ideograph>) 7194 0x67F4 柴 (<CJK Ideograph>) 7195 0x6850 桐 (<CJK Ideograph>) 7196 0x6840 桀 (<CJK Ideograph>) 7197 0x683C 格 (<CJK Ideograph>) 7198 0x6843 桃 (<CJK Ideograph>) 7199 0x682A 株 (<CJK Ideograph>) 7200 0x6845 桅 (<CJK Ideograph>) 7201 0x6813 栓 (<CJK Ideograph>) 7202 0x6818 栘 (<CJK Ideograph>) 7203 0x6841 桁 (<CJK Ideograph>) 7204 0x6B8A 殊 (<CJK Ideograph>) 7205 0x6B89 殉 (<CJK Ideograph>) 7206 0x6BB7 殷 (<CJK Ideograph>) 7207 0x6C23 氣 (<CJK Ideograph>) 7208 0x6C27 氧 (<CJK Ideograph>) 7209 0x6C28 氨 (<CJK Ideograph>) 7210 0x6C26 氦 (<CJK Ideograph>) 7211 0x6C24 氤 (<CJK Ideograph>) 7212 0x6CF0 泰 (<CJK Ideograph>) 7213 0x6D6A 浪 (<CJK Ideograph>) 7214 0x6D95 涕 (<CJK Ideograph>) 7215 0x6D88 消 (<CJK Ideograph>) 7216 0x6D87 涇 (<CJK Ideograph>) 7217 0x6D66 浦 (<CJK Ideograph>) 7218 0x6D78 浸 (<CJK Ideograph>) 7219 0x6D77 海 (<CJK Ideograph>) 7220 0x6D59 浙 (<CJK Ideograph>) 7221 0x6D93 涓 (<CJK Ideograph>) 7222 0x6D6C 浬 (<CJK Ideograph>) 7223 0x6D89 涉 (<CJK Ideograph>) 7224 0x6D6E 浮 (<CJK Ideograph>) 7225 0x6D5A 浚 (<CJK Ideograph>) 7226 0x6D74 浴 (<CJK Ideograph>) 7227 0x6D69 浩 (<CJK Ideograph>) 7228 0x6D8C 涌 (<CJK Ideograph>) 7229 0x6D8A 涊 (<CJK Ideograph>) 7230 0x6D79 浹 (<CJK Ideograph>) 7231 0x6D85 涅 (<CJK Ideograph>) 7232 0x6D65 浥 (<CJK Ideograph>) 7233 0x6D94 涔 (<CJK Ideograph>) 7234 0x70CA 烊 (<CJK Ideograph>) 7235 0x70D8 烘 (<CJK Ideograph>) 7236 0x70E4 烤 (<CJK Ideograph>) 7237 0x70D9 烙 (<CJK Ideograph>) 7238 0x70C8 烈 (<CJK Ideograph>) 7239 0x70CF 烏 (<CJK Ideograph>) 7240 0x7239 爹 (<CJK Ideograph>) 7241 0x7279 特 (<CJK Ideograph>) 7242 0x72FC 狼 (<CJK Ideograph>) 7243 0x72F9 狹 (<CJK Ideograph>) 7244 0x72FD 狽 (<CJK Ideograph>) 7245 0x72F8 狸 (<CJK Ideograph>) 7246 0x72F7 狷 (<CJK Ideograph>) 7247 0x7386 玆 (<CJK Ideograph>) 7248 0x73ED 班 (<CJK Ideograph>) 7249 0x7409 琉 (<CJK Ideograph>) 7250 0x73EE 珮 (<CJK Ideograph>) 7251 0x73E0 珠 (<CJK Ideograph>) 7252 0x73EA 珪 (<CJK Ideograph>) 7253 0x73DE 珞 (<CJK Ideograph>) 7254 0x7554 畔 (<CJK Ideograph>) 7255 0x755D 畝 (<CJK Ideograph>) 7256 0x755C 畜 (<CJK Ideograph>) 7257 0x755A 畚 (<CJK Ideograph>) 7258 0x7559 留 (<CJK Ideograph>) 7259 0x75BE 疾 (<CJK Ideograph>) 7260 0x75C5 病 (<CJK Ideograph>) 7261 0x75C7 症 (<CJK Ideograph>) 7262 0x75B2 疲 (<CJK Ideograph>) 7263 0x75B3 疳 (<CJK Ideograph>) 7264 0x75BD 疽 (<CJK Ideograph>) 7265 0x75BC 疼 (<CJK Ideograph>) 7266 0x75B9 疹 (<CJK Ideograph>) 7267 0x75C2 痂 (<CJK Ideograph>) 7268 0x75B8 疸 (<CJK Ideograph>) 7269 0x768B 皋 (<CJK Ideograph>) 7270 0x76B0 皰 (<CJK Ideograph>) 7271 0x76CA 益 (<CJK Ideograph>) 7272 0x76CD 盍 (<CJK Ideograph>) 7273 0x76CE 盎 (<CJK Ideograph>) 7274 0x7729 眩 (<CJK Ideograph>) 7275 0x771F 真 (<CJK Ideograph>) 7276 0x7720 眠 (<CJK Ideograph>) 7277 0x7728 眨 (<CJK Ideograph>) 7278 0x77E9 矩 (<CJK Ideograph>) 7279 0x7830 砰 (<CJK Ideograph>) 7280 0x7827 砧 (<CJK Ideograph>) 7281 0x7838 砸 (<CJK Ideograph>) 7282 0x781D 砝 (<CJK Ideograph>) 7283 0x7834 破 (<CJK Ideograph>) 7284 0x7837 砷 (<CJK Ideograph>) 7285 0x7825 砥 (<CJK Ideograph>) 7286 0x782D 砭 (<CJK Ideograph>) 7287 0x7820 砠 (<CJK Ideograph>) 7288 0x781F 砟 (<CJK Ideograph>) 7289 0x7832 砲 (<CJK Ideograph>) 7290 0x7955 祕 (<CJK Ideograph>) 7291 0x7950 祐 (<CJK Ideograph>) 7292 0x7960 祠 (<CJK Ideograph>) 7293 0x795F 祟 (<CJK Ideograph>) 7294 0x7956 祖 (<CJK Ideograph>) 7295 0x795E 神 (<CJK Ideograph>) 7296 0x795D 祝 (<CJK Ideograph>) 7297 0x7957 祗 (<CJK Ideograph>) 7298 0x795A 祚 (<CJK Ideograph>) 7299 0x79E4 秤 (<CJK Ideograph>) 7300 0x79E3 秣 (<CJK Ideograph>) 7301 0x79E7 秧 (<CJK Ideograph>) 7302 0x79DF 租 (<CJK Ideograph>) 7303 0x79E6 秦 (<CJK Ideograph>) 7304 0x79E9 秩 (<CJK Ideograph>) 7305 0x79D8 秘 (<CJK Ideograph>) 7306 0x7A84 窄 (<CJK Ideograph>) 7307 0x7A88 窈 (<CJK Ideograph>) 7308 0x7AD9 站 (<CJK Ideograph>) 7309 0x7B06 笆 (<CJK Ideograph>) 7310 0x7B11 笑 (<CJK Ideograph>) 7311 0x7C89 粉 (<CJK Ideograph>) 7312 0x7D21 紡 (<CJK Ideograph>) 7313 0x7D17 紗 (<CJK Ideograph>) 7314 0x7D0B 紋 (<CJK Ideograph>) 7315 0x7D0A 紊 (<CJK Ideograph>) 7316 0x7D20 素 (<CJK Ideograph>) 7317 0x7D22 索 (<CJK Ideograph>) 7318 0x7D14 純 (<CJK Ideograph>) 7319 0x7D10 紐 (<CJK Ideograph>) 7320 0x7D15 紕 (<CJK Ideograph>) 7321 0x7D1A 級 (<CJK Ideograph>) 7322 0x7D1C 紜 (<CJK Ideograph>) 7323 0x7D0D 納 (<CJK Ideograph>) 7324 0x7D19 紙 (<CJK Ideograph>) 7325 0x7D1B 紛 (<CJK Ideograph>) 7326 0x7F3A 缺 (<CJK Ideograph>) 7327 0x7F5F 罟 (<CJK Ideograph>) 7328 0x7F94 羔 (<CJK Ideograph>) 7329 0x7FC5 翅 (<CJK Ideograph>) 7330 0x7FC1 翁 (<CJK Ideograph>) 7331 0x8006 耆 (<CJK Ideograph>) 7332 0x8018 耘 (<CJK Ideograph>) 7333 0x8015 耕 (<CJK Ideograph>) 7334 0x8019 耙 (<CJK Ideograph>) 7335 0x8017 耗 (<CJK Ideograph>) 7336 0x803D 耽 (<CJK Ideograph>) 7337 0x803F 耿 (<CJK Ideograph>) 7338 0x80F1 胱 (<CJK Ideograph>) 7339 0x8102 脂 (<CJK Ideograph>) 7340 0x80F0 胰 (<CJK Ideograph>) 7341 0x8105 脅 (<CJK Ideograph>) 7342 0x80ED 胭 (<CJK Ideograph>) 7343 0x80F4 胴 (<CJK Ideograph>) 7344 0x8106 脆 (<CJK Ideograph>) 7345 0x80F8 胸 (<CJK Ideograph>) 7346 0x80F3 胳 (<CJK Ideograph>) 7347 0x8108 脈 (<CJK Ideograph>) 7348 0x80FD 能 (<CJK Ideograph>) 7349 0x810A 脊 (<CJK Ideograph>) 7350 0x80FC 胼 (<CJK Ideograph>) 7351 0x80EF 胯 (<CJK Ideograph>) 7352 0x81ED 臭 (<CJK Ideograph>) 7353 0x81EC 臬 (<CJK Ideograph>) 7354 0x8200 舀 (<CJK Ideograph>) 7355 0x8210 舐 (<CJK Ideograph>) 7356 0x822A 航 (<CJK Ideograph>) 7357 0x822B 舫 (<CJK Ideograph>) 7358 0x8228 舨 (<CJK Ideograph>) 7359 0x822C 般 (<CJK Ideograph>) 7360 0x82BB 芻 (<CJK Ideograph>) 7361 0x832B 茫 (<CJK Ideograph>) 7362 0x8352 荒 (<CJK Ideograph>) 7363 0x8354 荔 (<CJK Ideograph>) 7364 0x834A 荊 (<CJK Ideograph>) 7365 0x8338 茸 (<CJK Ideograph>) 7366 0x8350 荐 (<CJK Ideograph>) 7367 0x8349 草 (<CJK Ideograph>) 7368 0x8335 茵 (<CJK Ideograph>) 7369 0x8334 茴 (<CJK Ideograph>) 7370 0x834F 荏 (<CJK Ideograph>) 7371 0x8332 茲 (<CJK Ideograph>) 7372 0x8339 茹 (<CJK Ideograph>) 7373 0x8336 茶 (<CJK Ideograph>) 7374 0x8317 茗 (<CJK Ideograph>) 7375 0x8340 荀 (<CJK Ideograph>) 7376 0x8331 茱 (<CJK Ideograph>) 7377 0x8328 茨 (<CJK Ideograph>) 7378 0x8343 荃 (<CJK Ideograph>) 7379 0x8654 虔 (<CJK Ideograph>) 7380 0x868A 蚊 (<CJK Ideograph>) 7381 0x86AA 蚪 (<CJK Ideograph>) 7382 0x8693 蚓 (<CJK Ideograph>) 7383 0x86A4 蚤 (<CJK Ideograph>) 7384 0x86A9 蚩 (<CJK Ideograph>) 7385 0x868C 蚌 (<CJK Ideograph>) 7386 0x86A3 蚣 (<CJK Ideograph>) 7387 0x869C 蚜 (<CJK Ideograph>) 7388 0x8870 衰 (<CJK Ideograph>) 7389 0x8877 衷 (<CJK Ideograph>) 7390 0x8881 袁 (<CJK Ideograph>) 7391 0x8882 袂 (<CJK Ideograph>) 7392 0x887D 衽 (<CJK Ideograph>) 7393 0x8879 衹 (<CJK Ideograph>) 7394 0x8A18 記 (<CJK Ideograph>) 7395 0x8A10 訐 (<CJK Ideograph>) 7396 0x8A0E 討 (<CJK Ideograph>) 7397 0x8A0C 訌 (<CJK Ideograph>) 7398 0x8A15 訕 (<CJK Ideograph>) 7399 0x8A0A 訊 (<CJK Ideograph>) 7400 0x8A17 託 (<CJK Ideograph>) 7401 0x8A13 訓 (<CJK Ideograph>) 7402 0x8A16 訖 (<CJK Ideograph>) 7403 0x8A0F 訏 (<CJK Ideograph>) 7404 0x8A11 訑 (<CJK Ideograph>) 7405 0x8C48 豈 (<CJK Ideograph>) 7406 0x8C7A 豺 (<CJK Ideograph>) 7407 0x8C79 豹 (<CJK Ideograph>) 7408 0x8CA1 財 (<CJK Ideograph>) 7409 0x8CA2 貢 (<CJK Ideograph>) 7410 0x8D77 起 (<CJK Ideograph>) 7411 0x8EAC 躬 (<CJK Ideograph>) 7412 0x8ED2 軒 (<CJK Ideograph>) 7413 0x8ED4 軔 (<CJK Ideograph>) 7414 0x8ECF 軏 (<CJK Ideograph>) 7415 0x8FB1 辱 (<CJK Ideograph>) 7416 0x9001 送 (<CJK Ideograph>) 7417 0x9006 逆 (<CJK Ideograph>) 7418 0x8FF7 迷 (<CJK Ideograph>) 7419 0x9000 退 (<CJK Ideograph>) 7420 0x8FFA 迺 (<CJK Ideograph>) 7421 0x8FF4 迴 (<CJK Ideograph>) 7422 0x9003 逃 (<CJK Ideograph>) 7423 0x8FFD 追 (<CJK Ideograph>) 7424 0x9005 逅 (<CJK Ideograph>) 7425 0x8FF8 迸 (<CJK Ideograph>) 7426 0x9095 邕 (<CJK Ideograph>) 7427 0x90E1 郡 (<CJK Ideograph>) 7428 0x90DD 郝 (<CJK Ideograph>) 7429 0x90E2 郢 (<CJK Ideograph>) 7430 0x9152 酒 (<CJK Ideograph>) 7431 0x914D 配 (<CJK Ideograph>) 7432 0x914C 酌 (<CJK Ideograph>) 7433 0x91D8 釘 (<CJK Ideograph>) 7434 0x91DD 針 (<CJK Ideograph>) 7435 0x91D7 釗 (<CJK Ideograph>) 7436 0x91DC 釜 (<CJK Ideograph>) 7437 0x91D9 釙 (<CJK Ideograph>) 7438 0x9583 閃 (<CJK Ideograph>) 7439 0x9662 院 (<CJK Ideograph>) 7440 0x9663 陣 (<CJK Ideograph>) 7441 0x9661 陡 (<CJK Ideograph>) 7442 0x965B 陛 (<CJK Ideograph>) 7443 0x965D 陝 (<CJK Ideograph>) 7444 0x9664 除 (<CJK Ideograph>) 7445 0x9658 陘 (<CJK Ideograph>) 7446 0x965E 陞 (<CJK Ideograph>) 7447 0x96BB 隻 (<CJK Ideograph>) 7448 0x98E2 飢 (<CJK Ideograph>) 7449 0x99AC 馬 (<CJK Ideograph>) 7450 0x9AA8 骨 (<CJK Ideograph>) 7451 0x9AD8 高 (<CJK Ideograph>) 7452 0x9B25 鬥 (<CJK Ideograph>) 7453 0x9B32 鬲 (<CJK Ideograph>) 7454 0x9B3C 鬼 (<CJK Ideograph>) 7455 0x4E7E 乾 (<CJK Ideograph>) 7456 0x507A 偺 (<CJK Ideograph>) 7457 0x507D 偽 (<CJK Ideograph>) 7458 0x505C 停 (<CJK Ideograph>) 7459 0x5047 假 (<CJK Ideograph>) 7460 0x5043 偃 (<CJK Ideograph>) 7461 0x504C 偌 (<CJK Ideograph>) 7462 0x505A 做 (<CJK Ideograph>) 7463 0x5049 偉 (<CJK Ideograph>) 7464 0x5065 健 (<CJK Ideograph>) 7465 0x5076 偶 (<CJK Ideograph>) 7466 0x504E 偎 (<CJK Ideograph>) 7467 0x5055 偕 (<CJK Ideograph>) 7468 0x5075 偵 (<CJK Ideograph>) 7469 0x5074 側 (<CJK Ideograph>) 7470 0x5077 偷 (<CJK Ideograph>) 7471 0x504F 偏 (<CJK Ideograph>) 7472 0x500F 倏 (<CJK Ideograph>) 7473 0x506F 偯 (<CJK Ideograph>) 7474 0x506D 偭 (<CJK Ideograph>) 7475 0x515C 兜 (<CJK Ideograph>) 7476 0x5195 冕 (<CJK Ideograph>) 7477 0x51F0 凰 (<CJK Ideograph>) 7478 0x526A 剪 (<CJK Ideograph>) 7479 0x526F 副 (<CJK Ideograph>) 7480 0x52D2 勒 (<CJK Ideograph>) 7481 0x52D9 務 (<CJK Ideograph>) 7482 0x52D8 勘 (<CJK Ideograph>) 7483 0x52D5 動 (<CJK Ideograph>) 7484 0x5310 匐 (<CJK Ideograph>) 7485 0x530F 匏 (<CJK Ideograph>) 7486 0x5319 匙 (<CJK Ideograph>) 7487 0x533F 匿 (<CJK Ideograph>) 7488 0x5340 區 (<CJK Ideograph>) 7489 0x533E 匾 (<CJK Ideograph>) 7490 0x53C3 參 (<CJK Ideograph>) 7491 0x66FC 曼 (<CJK Ideograph>) 7492 0x5546 商 (<CJK Ideograph>) 7493 0x556A 啪 (<CJK Ideograph>) 7494 0x5566 啦 (<CJK Ideograph>) 7495 0x5544 啄 (<CJK Ideograph>) 7496 0x555E 啞 (<CJK Ideograph>) 7497 0x5561 啡 (<CJK Ideograph>) 7498 0x5543 啃 (<CJK Ideograph>) 7499 0x554A 啊 (<CJK Ideograph>) 7500 0x5531 唱 (<CJK Ideograph>) 7501 0x5556 啖 (<CJK Ideograph>) 7502 0x554F 問 (<CJK Ideograph>) 7503 0x5555 啕 (<CJK Ideograph>) 7504 0x552F 唯 (<CJK Ideograph>) 7505 0x5564 啤 (<CJK Ideograph>) 7506 0x5538 唸 (<CJK Ideograph>) 7507 0x552E 售 (<CJK Ideograph>) 7508 0x555C 啜 (<CJK Ideograph>) 7509 0x552C 唬 (<CJK Ideograph>) 7510 0x5563 啣 (<CJK Ideograph>) 7511 0x5533 唳 (<CJK Ideograph>) 7512 0x5541 啁 (<CJK Ideograph>) 7513 0x5557 啗 (<CJK Ideograph>) 7514 0x5708 圈 (<CJK Ideograph>) 7515 0x570B 國 (<CJK Ideograph>) 7516 0x5709 圉 (<CJK Ideograph>) 7517 0x57DF 域 (<CJK Ideograph>) 7518 0x5805 堅 (<CJK Ideograph>) 7519 0x580A 堊 (<CJK Ideograph>) 7520 0x5806 堆 (<CJK Ideograph>) 7521 0x57E0 埠 (<CJK Ideograph>) 7522 0x57E4 埤 (<CJK Ideograph>) 7523 0x57FA 基 (<CJK Ideograph>) 7524 0x5802 堂 (<CJK Ideograph>) 7525 0x5835 堵 (<CJK Ideograph>) 7526 0x57F7 執 (<CJK Ideograph>) 7527 0x57F9 培 (<CJK Ideograph>) 7528 0x5920 夠 (<CJK Ideograph>) 7529 0x5962 奢 (<CJK Ideograph>) 7530 0x5A36 娶 (<CJK Ideograph>) 7531 0x5A41 婁 (<CJK Ideograph>) 7532 0x5A49 婉 (<CJK Ideograph>) 7533 0x5A66 婦 (<CJK Ideograph>) 7534 0x5A6A 婪 (<CJK Ideograph>) 7535 0x5A40 婀 (<CJK Ideograph>) 7536 0x5A3C 娼 (<CJK Ideograph>) 7537 0x5A62 婢 (<CJK Ideograph>) 7538 0x5A5A 婚 (<CJK Ideograph>) 7539 0x5A46 婆 (<CJK Ideograph>) 7540 0x5A4A 婊 (<CJK Ideograph>) 7541 0x5B70 孰 (<CJK Ideograph>) 7542 0x5BC7 寇 (<CJK Ideograph>) 7543 0x5BC5 寅 (<CJK Ideograph>) 7544 0x5BC4 寄 (<CJK Ideograph>) 7545 0x5BC2 寂 (<CJK Ideograph>) 7546 0x5BBF 宿 (<CJK Ideograph>) 7547 0x5BC6 密 (<CJK Ideograph>) 7548 0x5C09 尉 (<CJK Ideograph>) 7549 0x5C08 專 (<CJK Ideograph>) 7550 0x5C07 將 (<CJK Ideograph>) 7551 0x5C60 屠 (<CJK Ideograph>) 7552 0x5C5C 屜 (<CJK Ideograph>) 7553 0x5C5D 屝 (<CJK Ideograph>) 7554 0x5D07 崇 (<CJK Ideograph>) 7555 0x5D06 崆 (<CJK Ideograph>) 7556 0x5D0E 崎 (<CJK Ideograph>) 7557 0x5D1B 崛 (<CJK Ideograph>) 7558 0x5D16 崖 (<CJK Ideograph>) 7559 0x5D22 崢 (<CJK Ideograph>) 7560 0x5D11 崑 (<CJK Ideograph>) 7561 0x5D29 崩 (<CJK Ideograph>) 7562 0x5D14 崔 (<CJK Ideograph>) 7563 0x5D19 崙 (<CJK Ideograph>) 7564 0x5D24 崤 (<CJK Ideograph>) 7565 0x5D27 崧 (<CJK Ideograph>) 7566 0x5D17 崗 (<CJK Ideograph>) 7567 0x5DE2 巢 (<CJK Ideograph>) 7568 0x5E38 常 (<CJK Ideograph>) 7569 0x5E36 帶 (<CJK Ideograph>) 7570 0x5E33 帳 (<CJK Ideograph>) 7571 0x5E37 帷 (<CJK Ideograph>) 7572 0x5EB7 康 (<CJK Ideograph>) 7573 0x5EB8 庸 (<CJK Ideograph>) 7574 0x5EB6 庶 (<CJK Ideograph>) 7575 0x5EB5 庵 (<CJK Ideograph>) 7576 0x5EBE 庾 (<CJK Ideograph>) 7577 0x5F35 張 (<CJK Ideograph>) 7578 0x5F37 強 (<CJK Ideograph>) 7579 0x5F57 彗 (<CJK Ideograph>) 7580 0x5F6C 彬 (<CJK Ideograph>) 7581 0x5F69 彩 (<CJK Ideograph>) 7582 0x5F6B 彫 (<CJK Ideograph>) 7583 0x5F97 得 (<CJK Ideograph>) 7584 0x5F99 徙 (<CJK Ideograph>) 7585 0x5F9E 從 (<CJK Ideograph>) 7586 0x5F98 徘 (<CJK Ideograph>) 7587 0x5FA1 御 (<CJK Ideograph>) 7588 0x5FA0 徠 (<CJK Ideograph>) 7589 0x5F9C 徜 (<CJK Ideograph>) 7590 0x607F 恿 (<CJK Ideograph>) 7591 0x60A3 患 (<CJK Ideograph>) 7592 0x6089 悉 (<CJK Ideograph>) 7593 0x60A0 悠 (<CJK Ideograph>) 7594 0x60A8 您 (<CJK Ideograph>) 7595 0x60CB 惋 (<CJK Ideograph>) 7596 0x60B4 悴 (<CJK Ideograph>) 7597 0x60E6 惦 (<CJK Ideograph>) 7598 0x60BD 悽 (<CJK Ideograph>) 7599 0x60C5 情 (<CJK Ideograph>) 7600 0x60BB 悻 (<CJK Ideograph>) 7601 0x60B5 悵 (<CJK Ideograph>) 7602 0x60DC 惜 (<CJK Ideograph>) 7603 0x60BC 悼 (<CJK Ideograph>) 7604 0x60D8 惘 (<CJK Ideograph>) 7605 0x60D5 惕 (<CJK Ideograph>) 7606 0x60C6 惆 (<CJK Ideograph>) 7607 0x60DF 惟 (<CJK Ideograph>) 7608 0x60B8 悸 (<CJK Ideograph>) 7609 0x60DA 惚 (<CJK Ideograph>) 7610 0x60C7 惇 (<CJK Ideograph>) 7611 0x621A 戚 (<CJK Ideograph>) 7612 0x621B 戛 (<CJK Ideograph>) 7613 0x6248 扈 (<CJK Ideograph>) 7614 0x63A0 掠 (<CJK Ideograph>) 7615 0x63A7 控 (<CJK Ideograph>) 7616 0x6372 捲 (<CJK Ideograph>) 7617 0x6396 掖 (<CJK Ideograph>) 7618 0x63A2 探 (<CJK Ideograph>) 7619 0x63A5 接 (<CJK Ideograph>) 7620 0x6377 捷 (<CJK Ideograph>) 7621 0x6367 捧 (<CJK Ideograph>) 7622 0x6398 掘 (<CJK Ideograph>) 7623 0x63AA 措 (<CJK Ideograph>) 7624 0x6371 捱 (<CJK Ideograph>) 7625 0x63A9 掩 (<CJK Ideograph>) 7626 0x6389 掉 (<CJK Ideograph>) 7627 0x6383 掃 (<CJK Ideograph>) 7628 0x639B 掛 (<CJK Ideograph>) 7629 0x636B 捫 (<CJK Ideograph>) 7630 0x63A8 推 (<CJK Ideograph>) 7631 0x6384 掄 (<CJK Ideograph>) 7632 0x6388 授 (<CJK Ideograph>) 7633 0x6399 掙 (<CJK Ideograph>) 7634 0x63A1 採 (<CJK Ideograph>) 7635 0x63AC 掬 (<CJK Ideograph>) 7636 0x6392 排 (<CJK Ideograph>) 7637 0x638F 掏 (<CJK Ideograph>) 7638 0x6380 掀 (<CJK Ideograph>) 7639 0x637B 捻 (<CJK Ideograph>) 7640 0x6369 捩 (<CJK Ideograph>) 7641 0x6368 捨 (<CJK Ideograph>) 7642 0x637A 捺 (<CJK Ideograph>) 7643 0x655D 敝 (<CJK Ideograph>) 7644 0x6556 敖 (<CJK Ideograph>) 7645 0x6551 救 (<CJK Ideograph>) 7646 0x6559 教 (<CJK Ideograph>) 7647 0x6557 敗 (<CJK Ideograph>) 7648 0x555F 啟 (<CJK Ideograph>) 7649 0x654F 敏 (<CJK Ideograph>) 7650 0x6558 敘 (<CJK Ideograph>) 7651 0x6555 敕 (<CJK Ideograph>) 7652 0x6554 敔 (<CJK Ideograph>) 7653 0x659C 斜 (<CJK Ideograph>) 7654 0x659B 斛 (<CJK Ideograph>) 7655 0x65AC 斬 (<CJK Ideograph>) 7656 0x65CF 族 (<CJK Ideograph>) 7657 0x65CB 旋 (<CJK Ideograph>) 7658 0x65CC 旌 (<CJK Ideograph>) 7659 0x65CE 旎 (<CJK Ideograph>) 7660 0x665D 晝 (<CJK Ideograph>) 7661 0x665A 晚 (<CJK Ideograph>) 7662 0x6664 晤 (<CJK Ideograph>) 7663 0x6668 晨 (<CJK Ideograph>) 7664 0x6666 晦 (<CJK Ideograph>) 7665 0x665E 晞 (<CJK Ideograph>) 7666 0x66F9 曹 (<CJK Ideograph>) 7667 0x52D7 勗 (<CJK Ideograph>) 7668 0x671B 望 (<CJK Ideograph>) 7669 0x6881 梁 (<CJK Ideograph>) 7670 0x68AF 梯 (<CJK Ideograph>) 7671 0x68A2 梢 (<CJK Ideograph>) 7672 0x6893 梓 (<CJK Ideograph>) 7673 0x68B5 梵 (<CJK Ideograph>) 7674 0x687F 桿 (<CJK Ideograph>) 7675 0x6876 桶 (<CJK Ideograph>) 7676 0x68B1 梱 (<CJK Ideograph>) 7677 0x68A7 梧 (<CJK Ideograph>) 7678 0x6897 梗 (<CJK Ideograph>) 7679 0x68B0 械 (<CJK Ideograph>) 7680 0x6883 梃 (<CJK Ideograph>) 7681 0x68C4 棄 (<CJK Ideograph>) 7682 0x68AD 梭 (<CJK Ideograph>) 7683 0x6886 梆 (<CJK Ideograph>) 7684 0x6885 梅 (<CJK Ideograph>) 7685 0x6894 梔 (<CJK Ideograph>) 7686 0x689D 條 (<CJK Ideograph>) 7687 0x68A8 梨 (<CJK Ideograph>) 7688 0x689F 梟 (<CJK Ideograph>) 7689 0x68A1 梡 (<CJK Ideograph>) 7690 0x6882 梂 (<CJK Ideograph>) 7691 0x6B32 欲 (<CJK Ideograph>) 7692 0x6BBA 殺 (<CJK Ideograph>) 7693 0x6BEB 毫 (<CJK Ideograph>) 7694 0x6BEC 毬 (<CJK Ideograph>) 7695 0x6C2B 氫 (<CJK Ideograph>) 7696 0x6D8E 涎 (<CJK Ideograph>) 7697 0x6DBC 涼 (<CJK Ideograph>) 7698 0x6DF3 淳 (<CJK Ideograph>) 7699 0x6DD9 淙 (<CJK Ideograph>) 7700 0x6DB2 液 (<CJK Ideograph>) 7701 0x6DE1 淡 (<CJK Ideograph>) 7702 0x6DCC 淌 (<CJK Ideograph>) 7703 0x6DE4 淤 (<CJK Ideograph>) 7704 0x6DFB 添 (<CJK Ideograph>) 7705 0x6DFA 淺 (<CJK Ideograph>) 7706 0x6E05 清 (<CJK Ideograph>) 7707 0x6DC7 淇 (<CJK Ideograph>) 7708 0x6DCB 淋 (<CJK Ideograph>) 7709 0x6DAF 涯 (<CJK Ideograph>) 7710 0x6DD1 淑 (<CJK Ideograph>) 7711 0x6DAE 涮 (<CJK Ideograph>) 7712 0x6DDE 淞 (<CJK Ideograph>) 7713 0x6DF9 淹 (<CJK Ideograph>) 7714 0x6DB8 涸 (<CJK Ideograph>) 7715 0x6DF7 混 (<CJK Ideograph>) 7716 0x6DF5 淵 (<CJK Ideograph>) 7717 0x6DC5 淅 (<CJK Ideograph>) 7718 0x6DD2 淒 (<CJK Ideograph>) 7719 0x6E1A 渚 (<CJK Ideograph>) 7720 0x6DB5 涵 (<CJK Ideograph>) 7721 0x6DDA 淚 (<CJK Ideograph>) 7722 0x6DEB 淫 (<CJK Ideograph>) 7723 0x6DD8 淘 (<CJK Ideograph>) 7724 0x6DEA 淪 (<CJK Ideograph>) 7725 0x6DF1 深 (<CJK Ideograph>) 7726 0x6DEE 淮 (<CJK Ideograph>) 7727 0x6DE8 淨 (<CJK Ideograph>) 7728 0x6DC6 淆 (<CJK Ideograph>) 7729 0x6DC4 淄 (<CJK Ideograph>) 7730 0x6DAA 涪 (<CJK Ideograph>) 7731 0x6DEC 淬 (<CJK Ideograph>) 7732 0x6DBF 涿 (<CJK Ideograph>) 7733 0x6DE6 淦 (<CJK Ideograph>) 7734 0x70F9 烹 (<CJK Ideograph>) 7735 0x7109 焉 (<CJK Ideograph>) 7736 0x710A 焊 (<CJK Ideograph>) 7737 0x70FD 烽 (<CJK Ideograph>) 7738 0x70EF 烯 (<CJK Ideograph>) 7739 0x723D 爽 (<CJK Ideograph>) 7740 0x727D 牽 (<CJK Ideograph>) 7741 0x7281 犁 (<CJK Ideograph>) 7742 0x731C 猜 (<CJK Ideograph>) 7743 0x731B 猛 (<CJK Ideograph>) 7744 0x7316 猖 (<CJK Ideograph>) 7745 0x7313 猓 (<CJK Ideograph>) 7746 0x7319 猙 (<CJK Ideograph>) 7747 0x7387 率 (<CJK Ideograph>) 7748 0x7405 琅 (<CJK Ideograph>) 7749 0x740A 琊 (<CJK Ideograph>) 7750 0x7403 球 (<CJK Ideograph>) 7751 0x7406 理 (<CJK Ideograph>) 7752 0x73FE 現 (<CJK Ideograph>) 7753 0x740D 琍 (<CJK Ideograph>) 7754 0x74E0 瓠 (<CJK Ideograph>) 7755 0x74F6 瓶 (<CJK Ideograph>) 7756 0x74F7 瓷 (<CJK Ideograph>) 7757 0x751C 甜 (<CJK Ideograph>) 7758 0x7522 產 (<CJK Ideograph>) 7759 0x7565 略 (<CJK Ideograph>) 7760 0x7566 畦 (<CJK Ideograph>) 7761 0x7562 畢 (<CJK Ideograph>) 7762 0x7570 異 (<CJK Ideograph>) 7763 0x758F 疏 (<CJK Ideograph>) 7764 0x75D4 痔 (<CJK Ideograph>) 7765 0x75D5 痕 (<CJK Ideograph>) 7766 0x75B5 疵 (<CJK Ideograph>) 7767 0x75CA 痊 (<CJK Ideograph>) 7768 0x75CD 痍 (<CJK Ideograph>) 7769 0x768E 皎 (<CJK Ideograph>) 7770 0x76D4 盔 (<CJK Ideograph>) 7771 0x76D2 盒 (<CJK Ideograph>) 7772 0x76DB 盛 (<CJK Ideograph>) 7773 0x7737 眷 (<CJK Ideograph>) 7774 0x773E 眾 (<CJK Ideograph>) 7775 0x773C 眼 (<CJK Ideograph>) 7776 0x7736 眶 (<CJK Ideograph>) 7777 0x7738 眸 (<CJK Ideograph>) 7778 0x773A 眺 (<CJK Ideograph>) 7779 0x786B 硫 (<CJK Ideograph>) 7780 0x7843 硃 (<CJK Ideograph>) 7781 0x784E 硎 (<CJK Ideograph>) 7782 0x7965 祥 (<CJK Ideograph>) 7783 0x7968 票 (<CJK Ideograph>) 7784 0x796D 祭 (<CJK Ideograph>) 7785 0x79FB 移 (<CJK Ideograph>) 7786 0x7A92 窒 (<CJK Ideograph>) 7787 0x7A95 窕 (<CJK Ideograph>) 7788 0x7B20 笠 (<CJK Ideograph>) 7789 0x7B28 笨 (<CJK Ideograph>) 7790 0x7B1B 笛 (<CJK Ideograph>) 7791 0x7B2C 第 (<CJK Ideograph>) 7792 0x7B26 符 (<CJK Ideograph>) 7793 0x7B19 笙 (<CJK Ideograph>) 7794 0x7B1E 笞 (<CJK Ideograph>) 7795 0x7B2E 笮 (<CJK Ideograph>) 7796 0x7C92 粒 (<CJK Ideograph>) 7797 0x7C97 粗 (<CJK Ideograph>) 7798 0x7C95 粕 (<CJK Ideograph>) 7799 0x7D46 絆 (<CJK Ideograph>) 7800 0x7D43 絃 (<CJK Ideograph>) 7801 0x7D71 統 (<CJK Ideograph>) 7802 0x7D2E 紮 (<CJK Ideograph>) 7803 0x7D39 紹 (<CJK Ideograph>) 7804 0x7D3C 紼 (<CJK Ideograph>) 7805 0x7D40 絀 (<CJK Ideograph>) 7806 0x7D30 細 (<CJK Ideograph>) 7807 0x7D33 紳 (<CJK Ideograph>) 7808 0x7D44 組 (<CJK Ideograph>) 7809 0x7D2F 累 (<CJK Ideograph>) 7810 0x7D42 終 (<CJK Ideograph>) 7811 0x7D32 紲 (<CJK Ideograph>) 7812 0x7D31 紱 (<CJK Ideograph>) 7813 0x7F3D 缽 (<CJK Ideograph>) 7814 0x7F9E 羞 (<CJK Ideograph>) 7815 0x7F9A 羚 (<CJK Ideograph>) 7816 0x7FCC 翌 (<CJK Ideograph>) 7817 0x7FCE 翎 (<CJK Ideograph>) 7818 0x7FD2 習 (<CJK Ideograph>) 7819 0x801C 耜 (<CJK Ideograph>) 7820 0x804A 聊 (<CJK Ideograph>) 7821 0x8046 聆 (<CJK Ideograph>) 7822 0x812F 脯 (<CJK Ideograph>) 7823 0x8116 脖 (<CJK Ideograph>) 7824 0x8123 脣 (<CJK Ideograph>) 7825 0x812B 脫 (<CJK Ideograph>) 7826 0x8129 脩 (<CJK Ideograph>) 7827 0x8130 脰 (<CJK Ideograph>) 7828 0x8124 脤 (<CJK Ideograph>) 7829 0x8202 舂 (<CJK Ideograph>) 7830 0x8235 舵 (<CJK Ideograph>) 7831 0x8237 舷 (<CJK Ideograph>) 7832 0x8236 舶 (<CJK Ideograph>) 7833 0x8239 船 (<CJK Ideograph>) 7834 0x838E 莎 (<CJK Ideograph>) 7835 0x839E 莞 (<CJK Ideograph>) 7836 0x8398 莘 (<CJK Ideograph>) 7837 0x8378 荸 (<CJK Ideograph>) 7838 0x83A2 莢 (<CJK Ideograph>) 7839 0x8396 莖 (<CJK Ideograph>) 7840 0x83BD 莽 (<CJK Ideograph>) 7841 0x83AB 莫 (<CJK Ideograph>) 7842 0x8392 莒 (<CJK Ideograph>) 7843 0x838A 莊 (<CJK Ideograph>) 7844 0x8393 莓 (<CJK Ideograph>) 7845 0x8389 莉 (<CJK Ideograph>) 7846 0x83A0 莠 (<CJK Ideograph>) 7847 0x8377 荷 (<CJK Ideograph>) 7848 0x837B 荻 (<CJK Ideograph>) 7849 0x837C 荼 (<CJK Ideograph>) 7850 0x8386 莆 (<CJK Ideograph>) 7851 0x83A7 莧 (<CJK Ideograph>) 7852 0x8655 處 (<CJK Ideograph>) 7853 0x5F6A 彪 (<CJK Ideograph>) 7854 0x86C7 蛇 (<CJK Ideograph>) 7855 0x86C0 蛀 (<CJK Ideograph>) 7856 0x86B6 蚶 (<CJK Ideograph>) 7857 0x86C4 蛄 (<CJK Ideograph>) 7858 0x86B5 蚵 (<CJK Ideograph>) 7859 0x86C6 蛆 (<CJK Ideograph>) 7860 0x86CB 蛋 (<CJK Ideograph>) 7861 0x86B1 蚱 (<CJK Ideograph>) 7862 0x86AF 蚯 (<CJK Ideograph>) 7863 0x86C9 蛉 (<CJK Ideograph>) 7864 0x8853 術 (<CJK Ideograph>) 7865 0x889E 袞 (<CJK Ideograph>) 7866 0x8888 袈 (<CJK Ideograph>) 7867 0x88AB 被 (<CJK Ideograph>) 7868 0x8892 袒 (<CJK Ideograph>) 7869 0x8896 袖 (<CJK Ideograph>) 7870 0x888D 袍 (<CJK Ideograph>) 7871 0x888B 袋 (<CJK Ideograph>) 7872 0x8993 覓 (<CJK Ideograph>) 7873 0x898F 規 (<CJK Ideograph>) 7874 0x8A2A 訪 (<CJK Ideograph>) 7875 0x8A1D 訝 (<CJK Ideograph>) 7876 0x8A23 訣 (<CJK Ideograph>) 7877 0x8A25 訥 (<CJK Ideograph>) 7878 0x8A31 許 (<CJK Ideograph>) 7879 0x8A2D 設 (<CJK Ideograph>) 7880 0x8A1F 訟 (<CJK Ideograph>) 7881 0x8A1B 訛 (<CJK Ideograph>) 7882 0x8A22 訢 (<CJK Ideograph>) 7883 0x8C49 豉 (<CJK Ideograph>) 7884 0x8C5A 豚 (<CJK Ideograph>) 7885 0x8CA9 販 (<CJK Ideograph>) 7886 0x8CAC 責 (<CJK Ideograph>) 7887 0x8CAB 貫 (<CJK Ideograph>) 7888 0x8CA8 貨 (<CJK Ideograph>) 7889 0x8CAA 貪 (<CJK Ideograph>) 7890 0x8CA7 貧 (<CJK Ideograph>) 7891 0x8D67 赧 (<CJK Ideograph>) 7892 0x8D66 赦 (<CJK Ideograph>) 7893 0x8DBE 趾 (<CJK Ideograph>) 7894 0x8DBA 趺 (<CJK Ideograph>) 7895 0x8EDB 軛 (<CJK Ideograph>) 7896 0x8EDF 軟 (<CJK Ideograph>) 7897 0x9019 這 (<CJK Ideograph>) 7898 0x900D 逍 (<CJK Ideograph>) 7899 0x901A 通 (<CJK Ideograph>) 7900 0x9017 逗 (<CJK Ideograph>) 7901 0x9023 連 (<CJK Ideograph>) 7902 0x901F 速 (<CJK Ideograph>) 7903 0x901D 逝 (<CJK Ideograph>) 7904 0x9010 逐 (<CJK Ideograph>) 7905 0x9015 逕 (<CJK Ideograph>) 7906 0x901E 逞 (<CJK Ideograph>) 7907 0x9020 造 (<CJK Ideograph>) 7908 0x900F 透 (<CJK Ideograph>) 7909 0x9022 逢 (<CJK Ideograph>) 7910 0x9016 逖 (<CJK Ideograph>) 7911 0x901B 逛 (<CJK Ideograph>) 7912 0x9014 途 (<CJK Ideograph>) 7913 0x90E8 部 (<CJK Ideograph>) 7914 0x90ED 郭 (<CJK Ideograph>) 7915 0x90FD 都 (<CJK Ideograph>) 7916 0x9157 酗 (<CJK Ideograph>) 7917 0x91CE 野 (<CJK Ideograph>) 7918 0x91F5 釵 (<CJK Ideograph>) 7919 0x91E6 釦 (<CJK Ideograph>) 7920 0x91E3 釣 (<CJK Ideograph>) 7921 0x91E7 釧 (<CJK Ideograph>) 7922 0x91ED 釭 (<CJK Ideograph>) 7923 0x91E9 釩 (<CJK Ideograph>) 7924 0x9589 閉 (<CJK Ideograph>) 7925 0x966A 陪 (<CJK Ideograph>) 7926 0x9675 陵 (<CJK Ideograph>) 7927 0x9673 陳 (<CJK Ideograph>) 7928 0x9678 陸 (<CJK Ideograph>) 7929 0x9670 陰 (<CJK Ideograph>) 7930 0x9674 陴 (<CJK Ideograph>) 7931 0x9676 陶 (<CJK Ideograph>) 7932 0x9677 陷 (<CJK Ideograph>) 7933 0x966C 陬 (<CJK Ideograph>) 7934 0x96C0 雀 (<CJK Ideograph>) 7935 0x96EA 雪 (<CJK Ideograph>) 7936 0x96E9 雩 (<CJK Ideograph>) 7937 0x7AE0 章 (<CJK Ideograph>) 7938 0x7ADF 竟 (<CJK Ideograph>) 7939 0x9802 頂 (<CJK Ideograph>) 7940 0x9803 頃 (<CJK Ideograph>) 7941 0x9B5A 魚 (<CJK Ideograph>) 7942 0x9CE5 鳥 (<CJK Ideograph>) 7943 0x9E75 鹵 (<CJK Ideograph>) 7944 0x9E7F 鹿 (<CJK Ideograph>) 7945 0x9EA5 麥 (<CJK Ideograph>) 7946 0x9EBB 麻 (<CJK Ideograph>) 7947 0x50A2 傢 (<CJK Ideograph>) 7948 0x508D 傍 (<CJK Ideograph>) 7949 0x5085 傅 (<CJK Ideograph>) 7950 0x5099 備 (<CJK Ideograph>) 7951 0x5091 傑 (<CJK Ideograph>) 7952 0x5080 傀 (<CJK Ideograph>) 7953 0x5096 傖 (<CJK Ideograph>) 7954 0x5098 傘 (<CJK Ideograph>) 7955 0x509A 傚 (<CJK Ideograph>) 7956 0x6700 最 (<CJK Ideograph>) 7957 0x51F1 凱 (<CJK Ideograph>) 7958 0x5272 割 (<CJK Ideograph>) 7959 0x5274 剴 (<CJK Ideograph>) 7960 0x5275 創 (<CJK Ideograph>) 7961 0x5269 剩 (<CJK Ideograph>) 7962 0x52DE 勞 (<CJK Ideograph>) 7963 0x52DD 勝 (<CJK Ideograph>) 7964 0x52DB 勛 (<CJK Ideograph>) 7965 0x535A 博 (<CJK Ideograph>) 7966 0x53A5 厥 (<CJK Ideograph>) 7967 0x557B 啻 (<CJK Ideograph>) 7968 0x5580 喀 (<CJK Ideograph>) 7969 0x55A7 喧 (<CJK Ideograph>) 7970 0x557C 啼 (<CJK Ideograph>) 7971 0x558A 喊 (<CJK Ideograph>) 7972 0x559D 喝 (<CJK Ideograph>) 7973 0x5598 喘 (<CJK Ideograph>) 7974 0x5582 喂 (<CJK Ideograph>) 7975 0x559C 喜 (<CJK Ideograph>) 7976 0x55AA 喪 (<CJK Ideograph>) 7977 0x5594 喔 (<CJK Ideograph>) 7978 0x5587 喇 (<CJK Ideograph>) 7979 0x558B 喋 (<CJK Ideograph>) 7980 0x5583 喃 (<CJK Ideograph>) 7981 0x55B3 喳 (<CJK Ideograph>) 7982 0x55AE 單 (<CJK Ideograph>) 7983 0x559F 喟 (<CJK Ideograph>) 7984 0x553E 唾 (<CJK Ideograph>) 7985 0x55B2 喲 (<CJK Ideograph>) 7986 0x559A 喚 (<CJK Ideograph>) 7987 0x55BB 喻 (<CJK Ideograph>) 7988 0x55AC 喬 (<CJK Ideograph>) 7989 0x55B1 喱 (<CJK Ideograph>) 7990 0x557E 啾 (<CJK Ideograph>) 7991 0x5589 喉 (<CJK Ideograph>) 7992 0x55AB 喫 (<CJK Ideograph>) 7993 0x5599 喙 (<CJK Ideograph>) 7994 0x570D 圍 (<CJK Ideograph>) 7995 0x582F 堯 (<CJK Ideograph>) 7996 0x582A 堪 (<CJK Ideograph>) 7997 0x5834 場 (<CJK Ideograph>) 7998 0x5824 堤 (<CJK Ideograph>) 7999 0x5830 堰 (<CJK Ideograph>) 8000 0x5831 報 (<CJK Ideograph>) 8001 0x5821 堡 (<CJK Ideograph>) 8002 0x581D 堝 (<CJK Ideograph>) 8003 0x5820 堠 (<CJK Ideograph>) 8004 0x58F9 壹 (<CJK Ideograph>) 8005 0x58FA 壺 (<CJK Ideograph>) 8006 0x5960 奠 (<CJK Ideograph>) 8007 0x5A77 婷 (<CJK Ideograph>) 8008 0x5A9A 媚 (<CJK Ideograph>) 8009 0x5A7F 婿 (<CJK Ideograph>) 8010 0x5A92 媒 (<CJK Ideograph>) 8011 0x5A9B 媛 (<CJK Ideograph>) 8012 0x5AA7 媧 (<CJK Ideograph>) 8013 0x5B73 孳 (<CJK Ideograph>) 8014 0x5B71 孱 (<CJK Ideograph>) 8015 0x5BD2 寒 (<CJK Ideograph>) 8016 0x5BCC 富 (<CJK Ideograph>) 8017 0x5BD3 寓 (<CJK Ideograph>) 8018 0x5BD0 寐 (<CJK Ideograph>) 8019 0x5C0A 尊 (<CJK Ideograph>) 8020 0x5C0B 尋 (<CJK Ideograph>) 8021 0x5C31 就 (<CJK Ideograph>) 8022 0x5D4C 嵌 (<CJK Ideograph>) 8023 0x5D50 嵐 (<CJK Ideograph>) 8024 0x5D34 崴 (<CJK Ideograph>) 8025 0x5D47 嵇 (<CJK Ideograph>) 8026 0x5DFD 巽 (<CJK Ideograph>) 8027 0x5E45 幅 (<CJK Ideograph>) 8028 0x5E3D 帽 (<CJK Ideograph>) 8029 0x5E40 幀 (<CJK Ideograph>) 8030 0x5E43 幃 (<CJK Ideograph>) 8031 0x5E7E 幾 (<CJK Ideograph>) 8032 0x5ECA 廊 (<CJK Ideograph>) 8033 0x5EC1 廁 (<CJK Ideograph>) 8034 0x5EC2 廂 (<CJK Ideograph>) 8035 0x5EC4 廄 (<CJK Ideograph>) 8036 0x5F3C 弼 (<CJK Ideograph>) 8037 0x5F6D 彭 (<CJK Ideograph>) 8038 0x5FA9 復 (<CJK Ideograph>) 8039 0x5FAA 循 (<CJK Ideograph>) 8040 0x5FA8 徨 (<CJK Ideograph>) 8041 0x60D1 惑 (<CJK Ideograph>) 8042 0x60E1 惡 (<CJK Ideograph>) 8043 0x60B2 悲 (<CJK Ideograph>) 8044 0x60B6 悶 (<CJK Ideograph>) 8045 0x60E0 惠 (<CJK Ideograph>) 8046 0x611C 愜 (<CJK Ideograph>) 8047 0x6123 愣 (<CJK Ideograph>) 8048 0x60FA 惺 (<CJK Ideograph>) 8049 0x6115 愕 (<CJK Ideograph>) 8050 0x60F0 惰 (<CJK Ideograph>) 8051 0x60FB 惻 (<CJK Ideograph>) 8052 0x60F4 惴 (<CJK Ideograph>) 8053 0x6168 慨 (<CJK Ideograph>) 8054 0x60F1 惱 (<CJK Ideograph>) 8055 0x610E 愎 (<CJK Ideograph>) 8056 0x60F6 惶 (<CJK Ideograph>) 8057 0x6109 愉 (<CJK Ideograph>) 8058 0x6100 愀 (<CJK Ideograph>) 8059 0x6112 愒 (<CJK Ideograph>) 8060 0x621F 戟 (<CJK Ideograph>) 8061 0x6249 扉 (<CJK Ideograph>) 8062 0x63A3 掣 (<CJK Ideograph>) 8063 0x638C 掌 (<CJK Ideograph>) 8064 0x63CF 描 (<CJK Ideograph>) 8065 0x63C0 揀 (<CJK Ideograph>) 8066 0x63E9 揩 (<CJK Ideograph>) 8067 0x63C9 揉 (<CJK Ideograph>) 8068 0x63C6 揆 (<CJK Ideograph>) 8069 0x63CD 揍 (<CJK Ideograph>) 8070 0x63D2 插 (<CJK Ideograph>) 8071 0x63E3 揣 (<CJK Ideograph>) 8072 0x63D0 提 (<CJK Ideograph>) 8073 0x63E1 握 (<CJK Ideograph>) 8074 0x63D6 揖 (<CJK Ideograph>) 8075 0x63ED 揭 (<CJK Ideograph>) 8076 0x63EE 揮 (<CJK Ideograph>) 8077 0x6376 捶 (<CJK Ideograph>) 8078 0x63F4 援 (<CJK Ideograph>) 8079 0x63EA 揪 (<CJK Ideograph>) 8080 0x63DB 換 (<CJK Ideograph>) 8081 0x6452 摒 (<CJK Ideograph>) 8082 0x63DA 揚 (<CJK Ideograph>) 8083 0x63F9 揹 (<CJK Ideograph>) 8084 0x655E 敞 (<CJK Ideograph>) 8085 0x6566 敦 (<CJK Ideograph>) 8086 0x6562 敢 (<CJK Ideograph>) 8087 0x6563 散 (<CJK Ideograph>) 8088 0x6591 斑 (<CJK Ideograph>) 8089 0x6590 斐 (<CJK Ideograph>) 8090 0x65AF 斯 (<CJK Ideograph>) 8091 0x666E 普 (<CJK Ideograph>) 8092 0x6670 晰 (<CJK Ideograph>) 8093 0x6674 晴 (<CJK Ideograph>) 8094 0x6676 晶 (<CJK Ideograph>) 8095 0x666F 景 (<CJK Ideograph>) 8096 0x6691 暑 (<CJK Ideograph>) 8097 0x667A 智 (<CJK Ideograph>) 8098 0x667E 晾 (<CJK Ideograph>) 8099 0x6677 晷 (<CJK Ideograph>) 8100 0x66FE 曾 (<CJK Ideograph>) 8101 0x66FF 替 (<CJK Ideograph>) 8102 0x671F 期 (<CJK Ideograph>) 8103 0x671D 朝 (<CJK Ideograph>) 8104 0x68FA 棺 (<CJK Ideograph>) 8105 0x68D5 棕 (<CJK Ideograph>) 8106 0x68E0 棠 (<CJK Ideograph>) 8107 0x68D8 棘 (<CJK Ideograph>) 8108 0x68D7 棗 (<CJK Ideograph>) 8109 0x6905 椅 (<CJK Ideograph>) 8110 0x68DF 棟 (<CJK Ideograph>) 8111 0x68F5 棵 (<CJK Ideograph>) 8112 0x68EE 森 (<CJK Ideograph>) 8113 0x68E7 棧 (<CJK Ideograph>) 8114 0x68F9 棹 (<CJK Ideograph>) 8115 0x68D2 棒 (<CJK Ideograph>) 8116 0x68F2 棲 (<CJK Ideograph>) 8117 0x68E3 棣 (<CJK Ideograph>) 8118 0x68CB 棋 (<CJK Ideograph>) 8119 0x68CD 棍 (<CJK Ideograph>) 8120 0x690D 植 (<CJK Ideograph>) 8121 0x6912 椒 (<CJK Ideograph>) 8122 0x690E 椎 (<CJK Ideograph>) 8123 0x68C9 棉 (<CJK Ideograph>) 8124 0x68DA 棚 (<CJK Ideograph>) 8125 0x696E 楮 (<CJK Ideograph>) 8126 0x68FB 棻 (<CJK Ideograph>) 8127 0x6B3E 款 (<CJK Ideograph>) 8128 0x6B3A 欺 (<CJK Ideograph>) 8129 0x6B3D 欽 (<CJK Ideograph>) 8130 0x6B98 殘 (<CJK Ideograph>) 8131 0x6B96 殖 (<CJK Ideograph>) 8132 0x6BBC 殼 (<CJK Ideograph>) 8133 0x6BEF 毯 (<CJK Ideograph>) 8134 0x6C2E 氮 (<CJK Ideograph>) 8135 0x6C2F 氯 (<CJK Ideograph>) 8136 0x6C2C 氬 (<CJK Ideograph>) 8137 0x6E2F 港 (<CJK Ideograph>) 8138 0x6E38 游 (<CJK Ideograph>) 8139 0x6E54 湔 (<CJK Ideograph>) 8140 0x6E21 渡 (<CJK Ideograph>) 8141 0x6E32 渲 (<CJK Ideograph>) 8142 0x6E67 湧 (<CJK Ideograph>) 8143 0x6E4A 湊 (<CJK Ideograph>) 8144 0x6E20 渠 (<CJK Ideograph>) 8145 0x6E25 渥 (<CJK Ideograph>) 8146 0x6E23 渣 (<CJK Ideograph>) 8147 0x6E1B 減 (<CJK Ideograph>) 8148 0x6E5B 湛 (<CJK Ideograph>) 8149 0x6E58 湘 (<CJK Ideograph>) 8150 0x6E24 渤 (<CJK Ideograph>) 8151 0x6E56 湖 (<CJK Ideograph>) 8152 0x6E6E 湮 (<CJK Ideograph>) 8153 0x6E2D 渭 (<CJK Ideograph>) 8154 0x6E26 渦 (<CJK Ideograph>) 8155 0x6E6F 湯 (<CJK Ideograph>) 8156 0x6E34 渴 (<CJK Ideograph>) 8157 0x6E4D 湍 (<CJK Ideograph>) 8158 0x6E3A 渺 (<CJK Ideograph>) 8159 0x6E2C 測 (<CJK Ideograph>) 8160 0x6E43 湃 (<CJK Ideograph>) 8161 0x6E1D 渝 (<CJK Ideograph>) 8162 0x6E3E 渾 (<CJK Ideograph>) 8163 0x6ECB 滋 (<CJK Ideograph>) 8164 0x6E89 溉 (<CJK Ideograph>) 8165 0x6E19 渙 (<CJK Ideograph>) 8166 0x6E4E 湎 (<CJK Ideograph>) 8167 0x6E63 湣 (<CJK Ideograph>) 8168 0x6E44 湄 (<CJK Ideograph>) 8169 0x6E72 湲 (<CJK Ideograph>) 8170 0x6E69 湩 (<CJK Ideograph>) 8171 0x6E5F 湟 (<CJK Ideograph>) 8172 0x7119 焙 (<CJK Ideograph>) 8173 0x711A 焚 (<CJK Ideograph>) 8174 0x7126 焦 (<CJK Ideograph>) 8175 0x7130 焰 (<CJK Ideograph>) 8176 0x7121 無 (<CJK Ideograph>) 8177 0x7136 然 (<CJK Ideograph>) 8178 0x716E 煮 (<CJK Ideograph>) 8179 0x711C 焜 (<CJK Ideograph>) 8180 0x724C 牌 (<CJK Ideograph>) 8181 0x7284 犄 (<CJK Ideograph>) 8182 0x7280 犀 (<CJK Ideograph>) 8183 0x7336 猶 (<CJK Ideograph>) 8184 0x7325 猥 (<CJK Ideograph>) 8185 0x7334 猴 (<CJK Ideograph>) 8186 0x7329 猩 (<CJK Ideograph>) 8187 0x743A 琺 (<CJK Ideograph>) 8188 0x742A 琪 (<CJK Ideograph>) 8189 0x7433 琳 (<CJK Ideograph>) 8190 0x7422 琢 (<CJK Ideograph>) 8191 0x7425 琥 (<CJK Ideograph>) 8192 0x7435 琵 (<CJK Ideograph>) 8193 0x7436 琶 (<CJK Ideograph>) 8194 0x7434 琴 (<CJK Ideograph>) 8195 0x742F 琯 (<CJK Ideograph>) 8196 0x741B 琛 (<CJK Ideograph>) 8197 0x7426 琦 (<CJK Ideograph>) 8198 0x7428 琨 (<CJK Ideograph>) 8199 0x7525 甥 (<CJK Ideograph>) 8200 0x7526 甦 (<CJK Ideograph>) 8201 0x756B 畫 (<CJK Ideograph>) 8202 0x756A 番 (<CJK Ideograph>) 8203 0x75E2 痢 (<CJK Ideograph>) 8204 0x75DB 痛 (<CJK Ideograph>) 8205 0x75E3 痣 (<CJK Ideograph>) 8206 0x75D9 痙 (<CJK Ideograph>) 8207 0x75D8 痘 (<CJK Ideograph>) 8208 0x75DE 痞 (<CJK Ideograph>) 8209 0x75E0 痠 (<CJK Ideograph>) 8210 0x767B 登 (<CJK Ideograph>) 8211 0x767C 發 (<CJK Ideograph>) 8212 0x7696 皖 (<CJK Ideograph>) 8213 0x7693 皓 (<CJK Ideograph>) 8214 0x76B4 皴 (<CJK Ideograph>) 8215 0x76DC 盜 (<CJK Ideograph>) 8216 0x774F 睏 (<CJK Ideograph>) 8217 0x77ED 短 (<CJK Ideograph>) 8218 0x785D 硝 (<CJK Ideograph>) 8219 0x786C 硬 (<CJK Ideograph>) 8220 0x786F 硯 (<CJK Ideograph>) 8221 0x7A0D 稍 (<CJK Ideograph>) 8222 0x7A08 稈 (<CJK Ideograph>) 8223 0x7A0B 程 (<CJK Ideograph>) 8224 0x7A05 稅 (<CJK Ideograph>) 8225 0x7A00 稀 (<CJK Ideograph>) 8226 0x7A98 窘 (<CJK Ideograph>) 8227 0x7A97 窗 (<CJK Ideograph>) 8228 0x7A96 窖 (<CJK Ideograph>) 8229 0x7AE5 童 (<CJK Ideograph>) 8230 0x7AE3 竣 (<CJK Ideograph>) 8231 0x7B49 等 (<CJK Ideograph>) 8232 0x7B56 策 (<CJK Ideograph>) 8233 0x7B46 筆 (<CJK Ideograph>) 8234 0x7B50 筐 (<CJK Ideograph>) 8235 0x7B52 筒 (<CJK Ideograph>) 8236 0x7B54 答 (<CJK Ideograph>) 8237 0x7B4D 筍 (<CJK Ideograph>) 8238 0x7B4B 筋 (<CJK Ideograph>) 8239 0x7B4F 筏 (<CJK Ideograph>) 8240 0x7B51 筑 (<CJK Ideograph>) 8241 0x7C9F 粟 (<CJK Ideograph>) 8242 0x7CA5 粥 (<CJK Ideograph>) 8243 0x7D5E 絞 (<CJK Ideograph>) 8244 0x7D50 結 (<CJK Ideograph>) 8245 0x7D68 絨 (<CJK Ideograph>) 8246 0x7D55 絕 (<CJK Ideograph>) 8247 0x7D2B 紫 (<CJK Ideograph>) 8248 0x7D6E 絮 (<CJK Ideograph>) 8249 0x7D72 絲 (<CJK Ideograph>) 8250 0x7D61 絡 (<CJK Ideograph>) 8251 0x7D66 給 (<CJK Ideograph>) 8252 0x7D62 絢 (<CJK Ideograph>) 8253 0x7D70 絰 (<CJK Ideograph>) 8254 0x7D73 絳 (<CJK Ideograph>) 8255 0x5584 善 (<CJK Ideograph>) 8256 0x7FD4 翔 (<CJK Ideograph>) 8257 0x7FD5 翕 (<CJK Ideograph>) 8258 0x800B 耋 (<CJK Ideograph>) 8259 0x8052 聒 (<CJK Ideograph>) 8260 0x8085 肅 (<CJK Ideograph>) 8261 0x8155 腕 (<CJK Ideograph>) 8262 0x8154 腔 (<CJK Ideograph>) 8263 0x814B 腋 (<CJK Ideograph>) 8264 0x8151 腑 (<CJK Ideograph>) 8265 0x814E 腎 (<CJK Ideograph>) 8266 0x8139 脹 (<CJK Ideograph>) 8267 0x8146 腆 (<CJK Ideograph>) 8268 0x813E 脾 (<CJK Ideograph>) 8269 0x814C 腌 (<CJK Ideograph>) 8270 0x8153 腓 (<CJK Ideograph>) 8271 0x8174 腴 (<CJK Ideograph>) 8272 0x8212 舒 (<CJK Ideograph>) 8273 0x821C 舜 (<CJK Ideograph>) 8274 0x83E9 菩 (<CJK Ideograph>) 8275 0x8403 萃 (<CJK Ideograph>) 8276 0x83F8 菸 (<CJK Ideograph>) 8277 0x840D 萍 (<CJK Ideograph>) 8278 0x83E0 菠 (<CJK Ideograph>) 8279 0x83C5 菅 (<CJK Ideograph>) 8280 0x840B 萋 (<CJK Ideograph>) 8281 0x83C1 菁 (<CJK Ideograph>) 8282 0x83EF 華 (<CJK Ideograph>) 8283 0x83F1 菱 (<CJK Ideograph>) 8284 0x83F4 菴 (<CJK Ideograph>) 8285 0x8457 著 (<CJK Ideograph>) 8286 0x840A 萊 (<CJK Ideograph>) 8287 0x83F0 菰 (<CJK Ideograph>) 8288 0x840C 萌 (<CJK Ideograph>) 8289 0x83CC 菌 (<CJK Ideograph>) 8290 0x83FD 菽 (<CJK Ideograph>) 8291 0x83F2 菲 (<CJK Ideograph>) 8292 0x83CA 菊 (<CJK Ideograph>) 8293 0x8438 萸 (<CJK Ideograph>) 8294 0x840E 萎 (<CJK Ideograph>) 8295 0x8404 萄 (<CJK Ideograph>) 8296 0x83DC 菜 (<CJK Ideograph>) 8297 0x8407 萇 (<CJK Ideograph>) 8298 0x83D4 菔 (<CJK Ideograph>) 8299 0x83DF 菟 (<CJK Ideograph>) 8300 0x865B 虛 (<CJK Ideograph>) 8301 0x86DF 蛟 (<CJK Ideograph>) 8302 0x86D9 蛙 (<CJK Ideograph>) 8303 0x86ED 蛭 (<CJK Ideograph>) 8304 0x86D4 蛔 (<CJK Ideograph>) 8305 0x86DB 蛛 (<CJK Ideograph>) 8306 0x86E4 蛤 (<CJK Ideograph>) 8307 0x86D0 蛐 (<CJK Ideograph>) 8308 0x86DE 蛞 (<CJK Ideograph>) 8309 0x8857 街 (<CJK Ideograph>) 8310 0x88C1 裁 (<CJK Ideograph>) 8311 0x88C2 裂 (<CJK Ideograph>) 8312 0x88B1 袱 (<CJK Ideograph>) 8313 0x8983 覃 (<CJK Ideograph>) 8314 0x8996 視 (<CJK Ideograph>) 8315 0x8A3B 註 (<CJK Ideograph>) 8316 0x8A60 詠 (<CJK Ideograph>) 8317 0x8A55 評 (<CJK Ideograph>) 8318 0x8A5E 詞 (<CJK Ideograph>) 8319 0x8A3C 証 (<CJK Ideograph>) 8320 0x8A41 詁 (<CJK Ideograph>) 8321 0x8A54 詔 (<CJK Ideograph>) 8322 0x8A5B 詛 (<CJK Ideograph>) 8323 0x8A50 詐 (<CJK Ideograph>) 8324 0x8A46 詆 (<CJK Ideograph>) 8325 0x8A34 訴 (<CJK Ideograph>) 8326 0x8A3A 診 (<CJK Ideograph>) 8327 0x8A36 訶 (<CJK Ideograph>) 8328 0x8A56 詖 (<CJK Ideograph>) 8329 0x8C61 象 (<CJK Ideograph>) 8330 0x8C82 貂 (<CJK Ideograph>) 8331 0x8CAF 貯 (<CJK Ideograph>) 8332 0x8CBC 貼 (<CJK Ideograph>) 8333 0x8CB3 貳 (<CJK Ideograph>) 8334 0x8CBD 貽 (<CJK Ideograph>) 8335 0x8CC1 賁 (<CJK Ideograph>) 8336 0x8CBB 費 (<CJK Ideograph>) 8337 0x8CC0 賀 (<CJK Ideograph>) 8338 0x8CB4 貴 (<CJK Ideograph>) 8339 0x8CB7 買 (<CJK Ideograph>) 8340 0x8CB6 貶 (<CJK Ideograph>) 8341 0x8CBF 貿 (<CJK Ideograph>) 8342 0x8CB8 貸 (<CJK Ideograph>) 8343 0x8D8A 越 (<CJK Ideograph>) 8344 0x8D85 超 (<CJK Ideograph>) 8345 0x8D81 趁 (<CJK Ideograph>) 8346 0x8DCE 跎 (<CJK Ideograph>) 8347 0x8DDD 距 (<CJK Ideograph>) 8348 0x8DCB 跋 (<CJK Ideograph>) 8349 0x8DDA 跚 (<CJK Ideograph>) 8350 0x8DD1 跑 (<CJK Ideograph>) 8351 0x8DCC 跌 (<CJK Ideograph>) 8352 0x8DDB 跛 (<CJK Ideograph>) 8353 0x8DC6 跆 (<CJK Ideograph>) 8354 0x8EFB 軻 (<CJK Ideograph>) 8355 0x8EF8 軸 (<CJK Ideograph>) 8356 0x8EFC 軼 (<CJK Ideograph>) 8357 0x8F9C 辜 (<CJK Ideograph>) 8358 0x902E 逮 (<CJK Ideograph>) 8359 0x9035 逵 (<CJK Ideograph>) 8360 0x9031 週 (<CJK Ideograph>) 8361 0x9038 逸 (<CJK Ideograph>) 8362 0x9032 進 (<CJK Ideograph>) 8363 0x9036 逶 (<CJK Ideograph>) 8364 0x9102 鄂 (<CJK Ideograph>) 8365 0x90F5 郵 (<CJK Ideograph>) 8366 0x9109 鄉 (<CJK Ideograph>) 8367 0x90FE 郾 (<CJK Ideograph>) 8368 0x9163 酣 (<CJK Ideograph>) 8369 0x9165 酥 (<CJK Ideograph>) 8370 0x91CF 量 (<CJK Ideograph>) 8371 0x9214 鈔 (<CJK Ideograph>) 8372 0x9215 鈕 (<CJK Ideograph>) 8373 0x9223 鈣 (<CJK Ideograph>) 8374 0x9209 鈉 (<CJK Ideograph>) 8375 0x921E 鈞 (<CJK Ideograph>) 8376 0x920D 鈍 (<CJK Ideograph>) 8377 0x9210 鈐 (<CJK Ideograph>) 8378 0x9207 鈇 (<CJK Ideograph>) 8379 0x9211 鈑 (<CJK Ideograph>) 8380 0x9594 閔 (<CJK Ideograph>) 8381 0x958F 閏 (<CJK Ideograph>) 8382 0x958B 開 (<CJK Ideograph>) 8383 0x9591 閑 (<CJK Ideograph>) 8384 0x9593 間 (<CJK Ideograph>) 8385 0x9592 閒 (<CJK Ideograph>) 8386 0x958E 閎 (<CJK Ideograph>) 8387 0x968A 隊 (<CJK Ideograph>) 8388 0x968E 階 (<CJK Ideograph>) 8389 0x968B 隋 (<CJK Ideograph>) 8390 0x967D 陽 (<CJK Ideograph>) 8391 0x9685 隅 (<CJK Ideograph>) 8392 0x9686 隆 (<CJK Ideograph>) 8393 0x968D 隍 (<CJK Ideograph>) 8394 0x9672 陲 (<CJK Ideograph>) 8395 0x9684 隄 (<CJK Ideograph>) 8396 0x96C1 雁 (<CJK Ideograph>) 8397 0x96C5 雅 (<CJK Ideograph>) 8398 0x96C4 雄 (<CJK Ideograph>) 8399 0x96C6 集 (<CJK Ideograph>) 8400 0x96C7 雇 (<CJK Ideograph>) 8401 0x96EF 雯 (<CJK Ideograph>) 8402 0x96F2 雲 (<CJK Ideograph>) 8403 0x97CC 韌 (<CJK Ideograph>) 8404 0x9805 項 (<CJK Ideograph>) 8405 0x9806 順 (<CJK Ideograph>) 8406 0x9808 須 (<CJK Ideograph>) 8407 0x98E7 飧 (<CJK Ideograph>) 8408 0x98EA 飪 (<CJK Ideograph>) 8409 0x98EF 飯 (<CJK Ideograph>) 8410 0x98E9 飩 (<CJK Ideograph>) 8411 0x98F2 飲 (<CJK Ideograph>) 8412 0x98ED 飭 (<CJK Ideograph>) 8413 0x99AE 馮 (<CJK Ideograph>) 8414 0x99AD 馭 (<CJK Ideograph>) 8415 0x9EC3 黃 (<CJK Ideograph>) 8416 0x9ECD 黍 (<CJK Ideograph>) 8417 0x9ED1 黑 (<CJK Ideograph>) 8418 0x4E82 亂 (<CJK Ideograph>) 8419 0x50AD 傭 (<CJK Ideograph>) 8420 0x50B5 債 (<CJK Ideograph>) 8421 0x50B2 傲 (<CJK Ideograph>) 8422 0x50B3 傳 (<CJK Ideograph>) 8423 0x50C5 僅 (<CJK Ideograph>) 8424 0x50BE 傾 (<CJK Ideograph>) 8425 0x50AC 催 (<CJK Ideograph>) 8426 0x50B7 傷 (<CJK Ideograph>) 8427 0x50BB 傻 (<CJK Ideograph>) 8428 0x50AF 傯 (<CJK Ideograph>) 8429 0x50C7 僇 (<CJK Ideograph>) 8430 0x527F 剿 (<CJK Ideograph>) 8431 0x5277 剷 (<CJK Ideograph>) 8432 0x527D 剽 (<CJK Ideograph>) 8433 0x52DF 募 (<CJK Ideograph>) 8434 0x52E6 勦 (<CJK Ideograph>) 8435 0x52E4 勤 (<CJK Ideograph>) 8436 0x52E2 勢 (<CJK Ideograph>) 8437 0x52E3 勣 (<CJK Ideograph>) 8438 0x532F 匯 (<CJK Ideograph>) 8439 0x55DF 嗟 (<CJK Ideograph>) 8440 0x55E8 嗨 (<CJK Ideograph>) 8441 0x55D3 嗓 (<CJK Ideograph>) 8442 0x55E6 嗦 (<CJK Ideograph>) 8443 0x55CE 嗎 (<CJK Ideograph>) 8444 0x55DC 嗜 (<CJK Ideograph>) 8445 0x55C7 嗇 (<CJK Ideograph>) 8446 0x55D1 嗑 (<CJK Ideograph>) 8447 0x55E3 嗣 (<CJK Ideograph>) 8448 0x55E4 嗤 (<CJK Ideograph>) 8449 0x55EF 嗯 (<CJK Ideograph>) 8450 0x55DA 嗚 (<CJK Ideograph>) 8451 0x55E1 嗡 (<CJK Ideograph>) 8452 0x55C5 嗅 (<CJK Ideograph>) 8453 0x55C6 嗆 (<CJK Ideograph>) 8454 0x55E5 嗥 (<CJK Ideograph>) 8455 0x55C9 嗉 (<CJK Ideograph>) 8456 0x5712 園 (<CJK Ideograph>) 8457 0x5713 圓 (<CJK Ideograph>) 8458 0x585E 塞 (<CJK Ideograph>) 8459 0x5851 塑 (<CJK Ideograph>) 8460 0x5858 塘 (<CJK Ideograph>) 8461 0x5857 塗 (<CJK Ideograph>) 8462 0x585A 塚 (<CJK Ideograph>) 8463 0x5854 塔 (<CJK Ideograph>) 8464 0x586B 填 (<CJK Ideograph>) 8465 0x584C 塌 (<CJK Ideograph>) 8466 0x586D 塭 (<CJK Ideograph>) 8467 0x584A 塊 (<CJK Ideograph>) 8468 0x5862 塢 (<CJK Ideograph>) 8469 0x5852 塒 (<CJK Ideograph>) 8470 0x584B 塋 (<CJK Ideograph>) 8471 0x5967 奧 (<CJK Ideograph>) 8472 0x5AC1 嫁 (<CJK Ideograph>) 8473 0x5AC9 嫉 (<CJK Ideograph>) 8474 0x5ACC 嫌 (<CJK Ideograph>) 8475 0x5ABE 媾 (<CJK Ideograph>) 8476 0x5ABD 媽 (<CJK Ideograph>) 8477 0x5ABC 媼 (<CJK Ideograph>) 8478 0x5AB3 媳 (<CJK Ideograph>) 8479 0x5AC2 嫂 (<CJK Ideograph>) 8480 0x5AB2 媲 (<CJK Ideograph>) 8481 0x5D69 嵩 (<CJK Ideograph>) 8482 0x5D6F 嵯 (<CJK Ideograph>) 8483 0x5E4C 幌 (<CJK Ideograph>) 8484 0x5E79 幹 (<CJK Ideograph>) 8485 0x5EC9 廉 (<CJK Ideograph>) 8486 0x5EC8 廈 (<CJK Ideograph>) 8487 0x5F12 弒 (<CJK Ideograph>) 8488 0x5F59 彙 (<CJK Ideograph>) 8489 0x5FAC 徬 (<CJK Ideograph>) 8490 0x5FAE 微 (<CJK Ideograph>) 8491 0x611A 愚 (<CJK Ideograph>) 8492 0x610F 意 (<CJK Ideograph>) 8493 0x6148 慈 (<CJK Ideograph>) 8494 0x611F 感 (<CJK Ideograph>) 8495 0x60F3 想 (<CJK Ideograph>) 8496 0x611B 愛 (<CJK Ideograph>) 8497 0x60F9 惹 (<CJK Ideograph>) 8498 0x6101 愁 (<CJK Ideograph>) 8499 0x6108 愈 (<CJK Ideograph>) 8500 0x614E 慎 (<CJK Ideograph>) 8501 0x614C 慌 (<CJK Ideograph>) 8502 0x6144 慄 (<CJK Ideograph>) 8503 0x614D 慍 (<CJK Ideograph>) 8504 0x613E 愾 (<CJK Ideograph>) 8505 0x6134 愴 (<CJK Ideograph>) 8506 0x6127 愧 (<CJK Ideograph>) 8507 0x610D 愍 (<CJK Ideograph>) 8508 0x6106 愆 (<CJK Ideograph>) 8509 0x6137 愷 (<CJK Ideograph>) 8510 0x6221 戡 (<CJK Ideograph>) 8511 0x6222 戢 (<CJK Ideograph>) 8512 0x6413 搓 (<CJK Ideograph>) 8513 0x643E 搾 (<CJK Ideograph>) 8514 0x641E 搞 (<CJK Ideograph>) 8515 0x642A 搪 (<CJK Ideograph>) 8516 0x642D 搭 (<CJK Ideograph>) 8517 0x643D 搽 (<CJK Ideograph>) 8518 0x642C 搬 (<CJK Ideograph>) 8519 0x640F 搏 (<CJK Ideograph>) 8520 0x641C 搜 (<CJK Ideograph>) 8521 0x6414 搔 (<CJK Ideograph>) 8522 0x640D 損 (<CJK Ideograph>) 8523 0x6436 搶 (<CJK Ideograph>) 8524 0x6416 搖 (<CJK Ideograph>) 8525 0x6417 搗 (<CJK Ideograph>) 8526 0x6406 搆 (<CJK Ideograph>) 8527 0x656C 敬 (<CJK Ideograph>) 8528 0x659F 斟 (<CJK Ideograph>) 8529 0x65B0 新 (<CJK Ideograph>) 8530 0x6697 暗 (<CJK Ideograph>) 8531 0x6689 暉 (<CJK Ideograph>) 8532 0x6687 暇 (<CJK Ideograph>) 8533 0x6688 暈 (<CJK Ideograph>) 8534 0x6696 暖 (<CJK Ideograph>) 8535 0x6684 暄 (<CJK Ideograph>) 8536 0x6698 暘 (<CJK Ideograph>) 8537 0x668D 暍 (<CJK Ideograph>) 8538 0x6703 會 (<CJK Ideograph>) 8539 0x6994 榔 (<CJK Ideograph>) 8540 0x696D 業 (<CJK Ideograph>) 8541 0x695A 楚 (<CJK Ideograph>) 8542 0x6977 楷 (<CJK Ideograph>) 8543 0x6960 楠 (<CJK Ideograph>) 8544 0x6954 楔 (<CJK Ideograph>) 8545 0x6975 極 (<CJK Ideograph>) 8546 0x6930 椰 (<CJK Ideograph>) 8547 0x6982 概 (<CJK Ideograph>) 8548 0x694A 楊 (<CJK Ideograph>) 8549 0x6968 楨 (<CJK Ideograph>) 8550 0x696B 楫 (<CJK Ideograph>) 8551 0x695E 楞 (<CJK Ideograph>) 8552 0x6953 楓 (<CJK Ideograph>) 8553 0x6979 楹 (<CJK Ideograph>) 8554 0x6986 榆 (<CJK Ideograph>) 8555 0x695D 楝 (<CJK Ideograph>) 8556 0x6963 楣 (<CJK Ideograph>) 8557 0x695B 楛 (<CJK Ideograph>) 8558 0x6B47 歇 (<CJK Ideograph>) 8559 0x6B72 歲 (<CJK Ideograph>) 8560 0x6BC0 毀 (<CJK Ideograph>) 8561 0x6BBF 殿 (<CJK Ideograph>) 8562 0x6BD3 毓 (<CJK Ideograph>) 8563 0x6BFD 毽 (<CJK Ideograph>) 8564 0x6EA2 溢 (<CJK Ideograph>) 8565 0x6EAF 溯 (<CJK Ideograph>) 8566 0x6ED3 滓 (<CJK Ideograph>) 8567 0x6EB6 溶 (<CJK Ideograph>) 8568 0x6EC2 滂 (<CJK Ideograph>) 8569 0x6E90 源 (<CJK Ideograph>) 8570 0x6E9D 溝 (<CJK Ideograph>) 8571 0x6EC7 滇 (<CJK Ideograph>) 8572 0x6EC5 滅 (<CJK Ideograph>) 8573 0x6EA5 溥 (<CJK Ideograph>) 8574 0x6E98 溘 (<CJK Ideograph>) 8575 0x6EBC 溼 (<CJK Ideograph>) 8576 0x6EBA 溺 (<CJK Ideograph>) 8577 0x6EAB 溫 (<CJK Ideograph>) 8578 0x6ED1 滑 (<CJK Ideograph>) 8579 0x6E96 準 (<CJK Ideograph>) 8580 0x6E9C 溜 (<CJK Ideograph>) 8581 0x6EC4 滄 (<CJK Ideograph>) 8582 0x6ED4 滔 (<CJK Ideograph>) 8583 0x6EAA 溪 (<CJK Ideograph>) 8584 0x6EA7 溧 (<CJK Ideograph>) 8585 0x6EB4 溴 (<CJK Ideograph>) 8586 0x714E 煎 (<CJK Ideograph>) 8587 0x7159 煙 (<CJK Ideograph>) 8588 0x7169 煩 (<CJK Ideograph>) 8589 0x7164 煤 (<CJK Ideograph>) 8590 0x7149 煉 (<CJK Ideograph>) 8591 0x7167 照 (<CJK Ideograph>) 8592 0x715C 煜 (<CJK Ideograph>) 8593 0x716C 煬 (<CJK Ideograph>) 8594 0x7166 煦 (<CJK Ideograph>) 8595 0x714C 煌 (<CJK Ideograph>) 8596 0x7165 煥 (<CJK Ideograph>) 8597 0x715E 煞 (<CJK Ideograph>) 8598 0x7146 煆 (<CJK Ideograph>) 8599 0x7168 煨 (<CJK Ideograph>) 8600 0x7156 煖 (<CJK Ideograph>) 8601 0x723A 爺 (<CJK Ideograph>) 8602 0x7252 牒 (<CJK Ideograph>) 8603 0x7337 猷 (<CJK Ideograph>) 8604 0x7345 獅 (<CJK Ideograph>) 8605 0x733F 猿 (<CJK Ideograph>) 8606 0x733E 猾 (<CJK Ideograph>) 8607 0x746F 瑯 (<CJK Ideograph>) 8608 0x745A 瑚 (<CJK Ideograph>) 8609 0x7455 瑕 (<CJK Ideograph>) 8610 0x745F 瑟 (<CJK Ideograph>) 8611 0x745E 瑞 (<CJK Ideograph>) 8612 0x7441 瑁 (<CJK Ideograph>) 8613 0x743F 琿 (<CJK Ideograph>) 8614 0x7459 瑙 (<CJK Ideograph>) 8615 0x745B 瑛 (<CJK Ideograph>) 8616 0x745C 瑜 (<CJK Ideograph>) 8617 0x7576 當 (<CJK Ideograph>) 8618 0x7578 畸 (<CJK Ideograph>) 8619 0x7600 瘀 (<CJK Ideograph>) 8620 0x75F0 痰 (<CJK Ideograph>) 8621 0x7601 瘁 (<CJK Ideograph>) 8622 0x75F2 痲 (<CJK Ideograph>) 8623 0x75F1 痱 (<CJK Ideograph>) 8624 0x75FA 痺 (<CJK Ideograph>) 8625 0x75FF 痿 (<CJK Ideograph>) 8626 0x75F4 痴 (<CJK Ideograph>) 8627 0x75F3 痳 (<CJK Ideograph>) 8628 0x76DE 盞 (<CJK Ideograph>) 8629 0x76DF 盟 (<CJK Ideograph>) 8630 0x775B 睛 (<CJK Ideograph>) 8631 0x776B 睫 (<CJK Ideograph>) 8632 0x7766 睦 (<CJK Ideograph>) 8633 0x775E 睞 (<CJK Ideograph>) 8634 0x7763 督 (<CJK Ideograph>) 8635 0x7779 睹 (<CJK Ideograph>) 8636 0x776A 睪 (<CJK Ideograph>) 8637 0x776C 睬 (<CJK Ideograph>) 8638 0x775C 睜 (<CJK Ideograph>) 8639 0x7765 睥 (<CJK Ideograph>) 8640 0x7768 睨 (<CJK Ideograph>) 8641 0x7762 睢 (<CJK Ideograph>) 8642 0x77EE 矮 (<CJK Ideograph>) 8643 0x788E 碎 (<CJK Ideograph>) 8644 0x78B0 碰 (<CJK Ideograph>) 8645 0x7897 碗 (<CJK Ideograph>) 8646 0x7898 碘 (<CJK Ideograph>) 8647 0x788C 碌 (<CJK Ideograph>) 8648 0x7889 碉 (<CJK Ideograph>) 8649 0x787C 硼 (<CJK Ideograph>) 8650 0x7891 碑 (<CJK Ideograph>) 8651 0x7893 碓 (<CJK Ideograph>) 8652 0x787F 硿 (<CJK Ideograph>) 8653 0x797A 祺 (<CJK Ideograph>) 8654 0x797F 祿 (<CJK Ideograph>) 8655 0x7981 禁 (<CJK Ideograph>) 8656 0x842C 萬 (<CJK Ideograph>) 8657 0x79BD 禽 (<CJK Ideograph>) 8658 0x7A1C 稜 (<CJK Ideograph>) 8659 0x7A1A 稚 (<CJK Ideograph>) 8660 0x7A20 稠 (<CJK Ideograph>) 8661 0x7A14 稔 (<CJK Ideograph>) 8662 0x7A1F 稟 (<CJK Ideograph>) 8663 0x7A1E 稞 (<CJK Ideograph>) 8664 0x7A9F 窟 (<CJK Ideograph>) 8665 0x7AA0 窠 (<CJK Ideograph>) 8666 0x7B77 筷 (<CJK Ideograph>) 8667 0x7BC0 節 (<CJK Ideograph>) 8668 0x7B60 筠 (<CJK Ideograph>) 8669 0x7B6E 筮 (<CJK Ideograph>) 8670 0x7B67 筧 (<CJK Ideograph>) 8671 0x7CB1 粱 (<CJK Ideograph>) 8672 0x7CB3 粳 (<CJK Ideograph>) 8673 0x7CB5 粵 (<CJK Ideograph>) 8674 0x7D93 經 (<CJK Ideograph>) 8675 0x7D79 絹 (<CJK Ideograph>) 8676 0x7D91 綑 (<CJK Ideograph>) 8677 0x7D81 綁 (<CJK Ideograph>) 8678 0x7D8F 綏 (<CJK Ideograph>) 8679 0x7D5B 絛 (<CJK Ideograph>) 8680 0x7F6E 置 (<CJK Ideograph>) 8681 0x7F69 罩 (<CJK Ideograph>) 8682 0x7F6A 罪 (<CJK Ideograph>) 8683 0x7F72 署 (<CJK Ideograph>) 8684 0x7FA9 義 (<CJK Ideograph>) 8685 0x7FA8 羨 (<CJK Ideograph>) 8686 0x7FA4 群 (<CJK Ideograph>) 8687 0x8056 聖 (<CJK Ideograph>) 8688 0x8058 聘 (<CJK Ideograph>) 8689 0x8086 肆 (<CJK Ideograph>) 8690 0x8084 肄 (<CJK Ideograph>) 8691 0x8171 腱 (<CJK Ideograph>) 8692 0x8170 腰 (<CJK Ideograph>) 8693 0x8178 腸 (<CJK Ideograph>) 8694 0x8165 腥 (<CJK Ideograph>) 8695 0x816E 腮 (<CJK Ideograph>) 8696 0x8173 腳 (<CJK Ideograph>) 8697 0x816B 腫 (<CJK Ideograph>) 8698 0x8179 腹 (<CJK Ideograph>) 8699 0x817A 腺 (<CJK Ideograph>) 8700 0x8166 腦 (<CJK Ideograph>) 8701 0x8205 舅 (<CJK Ideograph>) 8702 0x8247 艇 (<CJK Ideograph>) 8703 0x8482 蒂 (<CJK Ideograph>) 8704 0x8477 葷 (<CJK Ideograph>) 8705 0x843D 落 (<CJK Ideograph>) 8706 0x8431 萱 (<CJK Ideograph>) 8707 0x8475 葵 (<CJK Ideograph>) 8708 0x8466 葦 (<CJK Ideograph>) 8709 0x846B 葫 (<CJK Ideograph>) 8710 0x8449 葉 (<CJK Ideograph>) 8711 0x846C 葬 (<CJK Ideograph>) 8712 0x845B 葛 (<CJK Ideograph>) 8713 0x843C 萼 (<CJK Ideograph>) 8714 0x8435 萵 (<CJK Ideograph>) 8715 0x8461 葡 (<CJK Ideograph>) 8716 0x8463 董 (<CJK Ideograph>) 8717 0x8469 葩 (<CJK Ideograph>) 8718 0x846D 葭 (<CJK Ideograph>) 8719 0x8446 葆 (<CJK Ideograph>) 8720 0x865E 虞 (<CJK Ideograph>) 8721 0x865C 虜 (<CJK Ideograph>) 8722 0x865F 號 (<CJK Ideograph>) 8723 0x86F9 蛹 (<CJK Ideograph>) 8724 0x8713 蜓 (<CJK Ideograph>) 8725 0x8708 蜈 (<CJK Ideograph>) 8726 0x8707 蜇 (<CJK Ideograph>) 8727 0x8700 蜀 (<CJK Ideograph>) 8728 0x86FE 蛾 (<CJK Ideograph>) 8729 0x86FB 蛻 (<CJK Ideograph>) 8730 0x8702 蜂 (<CJK Ideograph>) 8731 0x8703 蜃 (<CJK Ideograph>) 8732 0x8706 蜆 (<CJK Ideograph>) 8733 0x870A 蜊 (<CJK Ideograph>) 8734 0x8859 衙 (<CJK Ideograph>) 8735 0x88DF 裟 (<CJK Ideograph>) 8736 0x88D4 裔 (<CJK Ideograph>) 8737 0x88D9 裙 (<CJK Ideograph>) 8738 0x88DC 補 (<CJK Ideograph>) 8739 0x88D8 裘 (<CJK Ideograph>) 8740 0x88DD 裝 (<CJK Ideograph>) 8741 0x88E1 裡 (<CJK Ideograph>) 8742 0x88CA 裊 (<CJK Ideograph>) 8743 0x88D5 裕 (<CJK Ideograph>) 8744 0x88D2 裒 (<CJK Ideograph>) 8745 0x899C 覜 (<CJK Ideograph>) 8746 0x89E3 解 (<CJK Ideograph>) 8747 0x8A6B 詫 (<CJK Ideograph>) 8748 0x8A72 該 (<CJK Ideograph>) 8749 0x8A73 詳 (<CJK Ideograph>) 8750 0x8A66 試 (<CJK Ideograph>) 8751 0x8A69 詩 (<CJK Ideograph>) 8752 0x8A70 詰 (<CJK Ideograph>) 8753 0x8A87 誇 (<CJK Ideograph>) 8754 0x8A7C 詼 (<CJK Ideograph>) 8755 0x8A63 詣 (<CJK Ideograph>) 8756 0x8AA0 誠 (<CJK Ideograph>) 8757 0x8A71 話 (<CJK Ideograph>) 8758 0x8A85 誅 (<CJK Ideograph>) 8759 0x8A6D 詭 (<CJK Ideograph>) 8760 0x8A62 詢 (<CJK Ideograph>) 8761 0x8A6E 詮 (<CJK Ideograph>) 8762 0x8A6C 詬 (<CJK Ideograph>) 8763 0x8A79 詹 (<CJK Ideograph>) 8764 0x8A7B 詻 (<CJK Ideograph>) 8765 0x8A3E 訾 (<CJK Ideograph>) 8766 0x8A68 詨 (<CJK Ideograph>) 8767 0x8C62 豢 (<CJK Ideograph>) 8768 0x8C8A 貊 (<CJK Ideograph>) 8769 0x8C89 貉 (<CJK Ideograph>) 8770 0x8CCA 賊 (<CJK Ideograph>) 8771 0x8CC7 資 (<CJK Ideograph>) 8772 0x8CC8 賈 (<CJK Ideograph>) 8773 0x8CC4 賄 (<CJK Ideograph>) 8774 0x8CB2 貲 (<CJK Ideograph>) 8775 0x8CC3 賃 (<CJK Ideograph>) 8776 0x8CC2 賂 (<CJK Ideograph>) 8777 0x8CC5 賅 (<CJK Ideograph>) 8778 0x8DE1 跡 (<CJK Ideograph>) 8779 0x8DDF 跟 (<CJK Ideograph>) 8780 0x8DE8 跨 (<CJK Ideograph>) 8781 0x8DEF 路 (<CJK Ideograph>) 8782 0x8DF3 跳 (<CJK Ideograph>) 8783 0x8DFA 跺 (<CJK Ideograph>) 8784 0x8DEA 跪 (<CJK Ideograph>) 8785 0x8DE4 跤 (<CJK Ideograph>) 8786 0x8DE6 跦 (<CJK Ideograph>) 8787 0x8EB2 躲 (<CJK Ideograph>) 8788 0x8F03 較 (<CJK Ideograph>) 8789 0x8F09 載 (<CJK Ideograph>) 8790 0x8EFE 軾 (<CJK Ideograph>) 8791 0x8F0A 輊 (<CJK Ideograph>) 8792 0x8F9F 辟 (<CJK Ideograph>) 8793 0x8FB2 農 (<CJK Ideograph>) 8794 0x904B 運 (<CJK Ideograph>) 8795 0x904A 遊 (<CJK Ideograph>) 8796 0x9053 道 (<CJK Ideograph>) 8797 0x9042 遂 (<CJK Ideograph>) 8798 0x9054 達 (<CJK Ideograph>) 8799 0x903C 逼 (<CJK Ideograph>) 8800 0x9055 違 (<CJK Ideograph>) 8801 0x9050 遐 (<CJK Ideograph>) 8802 0x9047 遇 (<CJK Ideograph>) 8803 0x904F 遏 (<CJK Ideograph>) 8804 0x904E 過 (<CJK Ideograph>) 8805 0x904D 遍 (<CJK Ideograph>) 8806 0x9051 遑 (<CJK Ideograph>) 8807 0x903E 逾 (<CJK Ideograph>) 8808 0x9041 遁 (<CJK Ideograph>) 8809 0x9112 鄒 (<CJK Ideograph>) 8810 0x9117 鄗 (<CJK Ideograph>) 8811 0x916C 酬 (<CJK Ideograph>) 8812 0x916A 酪 (<CJK Ideograph>) 8813 0x9169 酩 (<CJK Ideograph>) 8814 0x91C9 釉 (<CJK Ideograph>) 8815 0x9237 鈷 (<CJK Ideograph>) 8816 0x9257 鉗 (<CJK Ideograph>) 8817 0x9238 鈸 (<CJK Ideograph>) 8818 0x923D 鈽 (<CJK Ideograph>) 8819 0x9240 鉀 (<CJK Ideograph>) 8820 0x923E 鈾 (<CJK Ideograph>) 8821 0x925B 鉛 (<CJK Ideograph>) 8822 0x924B 鉋 (<CJK Ideograph>) 8823 0x9264 鉤 (<CJK Ideograph>) 8824 0x9251 鉑 (<CJK Ideograph>) 8825 0x9234 鈴 (<CJK Ideograph>) 8826 0x9249 鉉 (<CJK Ideograph>) 8827 0x924D 鉍 (<CJK Ideograph>) 8828 0x9245 鉅 (<CJK Ideograph>) 8829 0x9239 鈹 (<CJK Ideograph>) 8830 0x923F 鈿 (<CJK Ideograph>) 8831 0x925A 鉚 (<CJK Ideograph>) 8832 0x9598 閘 (<CJK Ideograph>) 8833 0x9698 隘 (<CJK Ideograph>) 8834 0x9694 隔 (<CJK Ideograph>) 8835 0x9695 隕 (<CJK Ideograph>) 8836 0x96CD 雍 (<CJK Ideograph>) 8837 0x96CB 雋 (<CJK Ideograph>) 8838 0x96C9 雉 (<CJK Ideograph>) 8839 0x96CA 雊 (<CJK Ideograph>) 8840 0x96F7 雷 (<CJK Ideograph>) 8841 0x96FB 電 (<CJK Ideograph>) 8842 0x96F9 雹 (<CJK Ideograph>) 8843 0x96F6 零 (<CJK Ideograph>) 8844 0x9756 靖 (<CJK Ideograph>) 8845 0x9774 靴 (<CJK Ideograph>) 8846 0x9776 靶 (<CJK Ideograph>) 8847 0x9810 預 (<CJK Ideograph>) 8848 0x9811 頑 (<CJK Ideograph>) 8849 0x9813 頓 (<CJK Ideograph>) 8850 0x980A 頊 (<CJK Ideograph>) 8851 0x9812 頒 (<CJK Ideograph>) 8852 0x980C 頌 (<CJK Ideograph>) 8853 0x98FC 飼 (<CJK Ideograph>) 8854 0x98F4 飴 (<CJK Ideograph>) 8855 0x98FD 飽 (<CJK Ideograph>) 8856 0x98FE 飾 (<CJK Ideograph>) 8857 0x99B3 馳 (<CJK Ideograph>) 8858 0x99B1 馱 (<CJK Ideograph>) 8859 0x99B4 馴 (<CJK Ideograph>) 8860 0x9AE1 髡 (<CJK Ideograph>) 8861 0x9CE9 鳩 (<CJK Ideograph>) 8862 0x9E82 麂 (<CJK Ideograph>) 8863 0x9F0E 鼎 (<CJK Ideograph>) 8864 0x9F13 鼓 (<CJK Ideograph>) 8865 0x9F20 鼠 (<CJK Ideograph>) 8866 0x50E7 僧 (<CJK Ideograph>) 8867 0x50EE 僮 (<CJK Ideograph>) 8868 0x50E5 僥 (<CJK Ideograph>) 8869 0x50D6 僖 (<CJK Ideograph>) 8870 0x50ED 僭 (<CJK Ideograph>) 8871 0x50DA 僚 (<CJK Ideograph>) 8872 0x50D5 僕 (<CJK Ideograph>) 8873 0x50CF 像 (<CJK Ideograph>) 8874 0x50D1 僑 (<CJK Ideograph>) 8875 0x50F1 僱 (<CJK Ideograph>) 8876 0x50CE 僎 (<CJK Ideograph>) 8877 0x50E9 僩 (<CJK Ideograph>) 8878 0x5162 兢 (<CJK Ideograph>) 8879 0x51F3 凳 (<CJK Ideograph>) 8880 0x5283 劃 (<CJK Ideograph>) 8881 0x5282 劂 (<CJK Ideograph>) 8882 0x5331 匱 (<CJK Ideograph>) 8883 0x53AD 厭 (<CJK Ideograph>) 8884 0x55FE 嗾 (<CJK Ideograph>) 8885 0x5600 嘀 (<CJK Ideograph>) 8886 0x561B 嘛 (<CJK Ideograph>) 8887 0x5617 嘗 (<CJK Ideograph>) 8888 0x55FD 嗽 (<CJK Ideograph>) 8889 0x5614 嘔 (<CJK Ideograph>) 8890 0x5606 嘆 (<CJK Ideograph>) 8891 0x5609 嘉 (<CJK Ideograph>) 8892 0x560D 嘍 (<CJK Ideograph>) 8893 0x560E 嘎 (<CJK Ideograph>) 8894 0x55F7 嗷 (<CJK Ideograph>) 8895 0x5616 嘖 (<CJK Ideograph>) 8896 0x561F 嘟 (<CJK Ideograph>) 8897 0x5608 嘈 (<CJK Ideograph>) 8898 0x5610 嘐 (<CJK Ideograph>) 8899 0x55F6 嗶 (<CJK Ideograph>) 8900 0x5718 團 (<CJK Ideograph>) 8901 0x5716 圖 (<CJK Ideograph>) 8902 0x5875 塵 (<CJK Ideograph>) 8903 0x587E 塾 (<CJK Ideograph>) 8904 0x5883 境 (<CJK Ideograph>) 8905 0x5893 墓 (<CJK Ideograph>) 8906 0x588A 墊 (<CJK Ideograph>) 8907 0x5879 塹 (<CJK Ideograph>) 8908 0x5885 墅 (<CJK Ideograph>) 8909 0x587D 塽 (<CJK Ideograph>) 8910 0x58FD 壽 (<CJK Ideograph>) 8911 0x5925 夥 (<CJK Ideograph>) 8912 0x5922 夢 (<CJK Ideograph>) 8913 0x5924 夤 (<CJK Ideograph>) 8914 0x596A 奪 (<CJK Ideograph>) 8915 0x5969 奩 (<CJK Ideograph>) 8916 0x5AE1 嫡 (<CJK Ideograph>) 8917 0x5AE6 嫦 (<CJK Ideograph>) 8918 0x5AE9 嫩 (<CJK Ideograph>) 8919 0x5AD7 嫗 (<CJK Ideograph>) 8920 0x5AD6 嫖 (<CJK Ideograph>) 8921 0x5AD8 嫘 (<CJK Ideograph>) 8922 0x5AE3 嫣 (<CJK Ideograph>) 8923 0x5B75 孵 (<CJK Ideograph>) 8924 0x5BDE 寞 (<CJK Ideograph>) 8925 0x5BE7 寧 (<CJK Ideograph>) 8926 0x5BE1 寡 (<CJK Ideograph>) 8927 0x5BE5 寥 (<CJK Ideograph>) 8928 0x5BE6 實 (<CJK Ideograph>) 8929 0x5BE8 寨 (<CJK Ideograph>) 8930 0x5BE2 寢 (<CJK Ideograph>) 8931 0x5BE4 寤 (<CJK Ideograph>) 8932 0x5BDF 察 (<CJK Ideograph>) 8933 0x5C0D 對 (<CJK Ideograph>) 8934 0x5C62 屢 (<CJK Ideograph>) 8935 0x5D84 嶄 (<CJK Ideograph>) 8936 0x5D87 嶇 (<CJK Ideograph>) 8937 0x5E5B 幛 (<CJK Ideograph>) 8938 0x5E63 幣 (<CJK Ideograph>) 8939 0x5E55 幕 (<CJK Ideograph>) 8940 0x5E57 幗 (<CJK Ideograph>) 8941 0x5E54 幔 (<CJK Ideograph>) 8942 0x5ED3 廓 (<CJK Ideograph>) 8943 0x5ED6 廖 (<CJK Ideograph>) 8944 0x5F0A 弊 (<CJK Ideograph>) 8945 0x5F46 彆 (<CJK Ideograph>) 8946 0x5F70 彰 (<CJK Ideograph>) 8947 0x5FB9 徹 (<CJK Ideograph>) 8948 0x6147 慇 (<CJK Ideograph>) 8949 0x613F 愿 (<CJK Ideograph>) 8950 0x614B 態 (<CJK Ideograph>) 8951 0x6177 慷 (<CJK Ideograph>) 8952 0x6162 慢 (<CJK Ideograph>) 8953 0x6163 慣 (<CJK Ideograph>) 8954 0x615F 慟 (<CJK Ideograph>) 8955 0x615A 慚 (<CJK Ideograph>) 8956 0x6158 慘 (<CJK Ideograph>) 8957 0x6175 慵 (<CJK Ideograph>) 8958 0x622A 截 (<CJK Ideograph>) 8959 0x6487 撇 (<CJK Ideograph>) 8960 0x6458 摘 (<CJK Ideograph>) 8961 0x6454 摔 (<CJK Ideograph>) 8962 0x64A4 撤 (<CJK Ideograph>) 8963 0x6478 摸 (<CJK Ideograph>) 8964 0x645F 摟 (<CJK Ideograph>) 8965 0x647A 摺 (<CJK Ideograph>) 8966 0x6451 摑 (<CJK Ideograph>) 8967 0x6467 摧 (<CJK Ideograph>) 8968 0x6434 搴 (<CJK Ideograph>) 8969 0x646D 摭 (<CJK Ideograph>) 8970 0x647B 摻 (<CJK Ideograph>) 8971 0x6572 敲 (<CJK Ideograph>) 8972 0x65A1 斡 (<CJK Ideograph>) 8973 0x65D7 旗 (<CJK Ideograph>) 8974 0x65D6 旖 (<CJK Ideograph>) 8975 0x66A2 暢 (<CJK Ideograph>) 8976 0x66A8 暨 (<CJK Ideograph>) 8977 0x669D 暝 (<CJK Ideograph>) 8978 0x699C 榜 (<CJK Ideograph>) 8979 0x69A8 榨 (<CJK Ideograph>) 8980 0x6995 榕 (<CJK Ideograph>) 8981 0x69C1 槁 (<CJK Ideograph>) 8982 0x69AE 榮 (<CJK Ideograph>) 8983 0x69D3 槓 (<CJK Ideograph>) 8984 0x69CB 構 (<CJK Ideograph>) 8985 0x699B 榛 (<CJK Ideograph>) 8986 0x69B7 榷 (<CJK Ideograph>) 8987 0x69BB 榻 (<CJK Ideograph>) 8988 0x69AB 榫 (<CJK Ideograph>) 8989 0x69B4 榴 (<CJK Ideograph>) 8990 0x69D0 槐 (<CJK Ideograph>) 8991 0x69CD 槍 (<CJK Ideograph>) 8992 0x69AD 榭 (<CJK Ideograph>) 8993 0x69CC 槌 (<CJK Ideograph>) 8994 0x69A6 榦 (<CJK Ideograph>) 8995 0x69C3 槃 (<CJK Ideograph>) 8996 0x69A3 榣 (<CJK Ideograph>) 8997 0x6B49 歉 (<CJK Ideograph>) 8998 0x6B4C 歌 (<CJK Ideograph>) 8999 0x6C33 氳 (<CJK Ideograph>) 9000 0x6F33 漳 (<CJK Ideograph>) 9001 0x6F14 演 (<CJK Ideograph>) 9002 0x6EFE 滾 (<CJK Ideograph>) 9003 0x6F13 漓 (<CJK Ideograph>) 9004 0x6EF4 滴 (<CJK Ideograph>) 9005 0x6F29 漩 (<CJK Ideograph>) 9006 0x6F3E 漾 (<CJK Ideograph>) 9007 0x6F20 漠 (<CJK Ideograph>) 9008 0x6F2C 漬 (<CJK Ideograph>) 9009 0x6F0F 漏 (<CJK Ideograph>) 9010 0x6F02 漂 (<CJK Ideograph>) 9011 0x6F22 漢 (<CJK Ideograph>) 9012 0x6EFF 滿 (<CJK Ideograph>) 9013 0x6EEF 滯 (<CJK Ideograph>) 9014 0x6F06 漆 (<CJK Ideograph>) 9015 0x6F31 漱 (<CJK Ideograph>) 9016 0x6F38 漸 (<CJK Ideograph>) 9017 0x6F32 漲 (<CJK Ideograph>) 9018 0x6F23 漣 (<CJK Ideograph>) 9019 0x6F15 漕 (<CJK Ideograph>) 9020 0x6F2B 漫 (<CJK Ideograph>) 9021 0x6F2F 漯 (<CJK Ideograph>) 9022 0x6F88 澈 (<CJK Ideograph>) 9023 0x6F2A 漪 (<CJK Ideograph>) 9024 0x6EEC 滬 (<CJK Ideograph>) 9025 0x6F01 漁 (<CJK Ideograph>) 9026 0x6EF2 滲 (<CJK Ideograph>) 9027 0x6ECC 滌 (<CJK Ideograph>) 9028 0x6EF7 滷 (<CJK Ideograph>) 9029 0x7194 熔 (<CJK Ideograph>) 9030 0x7199 熙 (<CJK Ideograph>) 9031 0x717D 煽 (<CJK Ideograph>) 9032 0x718A 熊 (<CJK Ideograph>) 9033 0x7184 熄 (<CJK Ideograph>) 9034 0x7192 熒 (<CJK Ideograph>) 9035 0x723E 爾 (<CJK Ideograph>) 9036 0x7292 犒 (<CJK Ideograph>) 9037 0x7296 犖 (<CJK Ideograph>) 9038 0x7344 獄 (<CJK Ideograph>) 9039 0x7350 獐 (<CJK Ideograph>) 9040 0x7464 瑤 (<CJK Ideograph>) 9041 0x7463 瑣 (<CJK Ideograph>) 9042 0x746A 瑪 (<CJK Ideograph>) 9043 0x7470 瑰 (<CJK Ideograph>) 9044 0x746D 瑭 (<CJK Ideograph>) 9045 0x7504 甄 (<CJK Ideograph>) 9046 0x7591 疑 (<CJK Ideograph>) 9047 0x7627 瘧 (<CJK Ideograph>) 9048 0x760D 瘍 (<CJK Ideograph>) 9049 0x760B 瘋 (<CJK Ideograph>) 9050 0x7609 瘉 (<CJK Ideograph>) 9051 0x7613 瘓 (<CJK Ideograph>) 9052 0x76E1 盡 (<CJK Ideograph>) 9053 0x76E3 監 (<CJK Ideograph>) 9054 0x7784 瞄 (<CJK Ideograph>) 9055 0x777D 睽 (<CJK Ideograph>) 9056 0x777F 睿 (<CJK Ideograph>) 9057 0x7761 睡 (<CJK Ideograph>) 9058 0x78C1 磁 (<CJK Ideograph>) 9059 0x789F 碟 (<CJK Ideograph>) 9060 0x78A7 碧 (<CJK Ideograph>) 9061 0x78B3 碳 (<CJK Ideograph>) 9062 0x78A9 碩 (<CJK Ideograph>) 9063 0x78A3 碣 (<CJK Ideograph>) 9064 0x798E 禎 (<CJK Ideograph>) 9065 0x798F 福 (<CJK Ideograph>) 9066 0x798D 禍 (<CJK Ideograph>) 9067 0x7A2E 種 (<CJK Ideograph>) 9068 0x7A31 稱 (<CJK Ideograph>) 9069 0x7AAA 窪 (<CJK Ideograph>) 9070 0x7AA9 窩 (<CJK Ideograph>) 9071 0x7AED 竭 (<CJK Ideograph>) 9072 0x7AEF 端 (<CJK Ideograph>) 9073 0x7BA1 管 (<CJK Ideograph>) 9074 0x7B95 箕 (<CJK Ideograph>) 9075 0x7B8B 箋 (<CJK Ideograph>) 9076 0x7B75 筵 (<CJK Ideograph>) 9077 0x7B97 算 (<CJK Ideograph>) 9078 0x7B9D 箝 (<CJK Ideograph>) 9079 0x7B94 箔 (<CJK Ideograph>) 9080 0x7B8F 箏 (<CJK Ideograph>) 9081 0x7BB8 箸 (<CJK Ideograph>) 9082 0x7B87 箇 (<CJK Ideograph>) 9083 0x7B84 箄 (<CJK Ideograph>) 9084 0x7CB9 粹 (<CJK Ideograph>) 9085 0x7CBD 粽 (<CJK Ideograph>) 9086 0x7CBE 精 (<CJK Ideograph>) 9087 0x7DBB 綻 (<CJK Ideograph>) 9088 0x7DB0 綰 (<CJK Ideograph>) 9089 0x7D9C 綜 (<CJK Ideograph>) 9090 0x7DBD 綽 (<CJK Ideograph>) 9091 0x7DBE 綾 (<CJK Ideograph>) 9092 0x7DA0 綠 (<CJK Ideograph>) 9093 0x7DCA 緊 (<CJK Ideograph>) 9094 0x7DB4 綴 (<CJK Ideograph>) 9095 0x7DB2 網 (<CJK Ideograph>) 9096 0x7DB1 綱 (<CJK Ideograph>) 9097 0x7DBA 綺 (<CJK Ideograph>) 9098 0x7DA2 綢 (<CJK Ideograph>) 9099 0x7DBF 綿 (<CJK Ideograph>) 9100 0x7DB5 綵 (<CJK Ideograph>) 9101 0x7DB8 綸 (<CJK Ideograph>) 9102 0x7DAD 維 (<CJK Ideograph>) 9103 0x7DD2 緒 (<CJK Ideograph>) 9104 0x7DC7 緇 (<CJK Ideograph>) 9105 0x7DAC 綬 (<CJK Ideograph>) 9106 0x7F70 罰 (<CJK Ideograph>) 9107 0x7FE0 翠 (<CJK Ideograph>) 9108 0x7FE1 翡 (<CJK Ideograph>) 9109 0x7FDF 翟 (<CJK Ideograph>) 9110 0x805E 聞 (<CJK Ideograph>) 9111 0x805A 聚 (<CJK Ideograph>) 9112 0x8087 肇 (<CJK Ideograph>) 9113 0x8150 腐 (<CJK Ideograph>) 9114 0x8180 膀 (<CJK Ideograph>) 9115 0x818F 膏 (<CJK Ideograph>) 9116 0x8188 膈 (<CJK Ideograph>) 9117 0x818A 膊 (<CJK Ideograph>) 9118 0x817F 腿 (<CJK Ideograph>) 9119 0x8182 膂 (<CJK Ideograph>) 9120 0x81E7 臧 (<CJK Ideograph>) 9121 0x81FA 臺 (<CJK Ideograph>) 9122 0x8207 與 (<CJK Ideograph>) 9123 0x8214 舔 (<CJK Ideograph>) 9124 0x821E 舞 (<CJK Ideograph>) 9125 0x824B 艋 (<CJK Ideograph>) 9126 0x84C9 蓉 (<CJK Ideograph>) 9127 0x84BF 蒿 (<CJK Ideograph>) 9128 0x84C6 蓆 (<CJK Ideograph>) 9129 0x84C4 蓄 (<CJK Ideograph>) 9130 0x8499 蒙 (<CJK Ideograph>) 9131 0x849E 蒞 (<CJK Ideograph>) 9132 0x84B2 蒲 (<CJK Ideograph>) 9133 0x849C 蒜 (<CJK Ideograph>) 9134 0x84CB 蓋 (<CJK Ideograph>) 9135 0x84B8 蒸 (<CJK Ideograph>) 9136 0x84C0 蓀 (<CJK Ideograph>) 9137 0x84D3 蓓 (<CJK Ideograph>) 9138 0x8490 蒐 (<CJK Ideograph>) 9139 0x84BC 蒼 (<CJK Ideograph>) 9140 0x84D1 蓑 (<CJK Ideograph>) 9141 0x84CA 蓊 (<CJK Ideograph>) 9142 0x873F 蜿 (<CJK Ideograph>) 9143 0x871C 蜜 (<CJK Ideograph>) 9144 0x873B 蜻 (<CJK Ideograph>) 9145 0x8722 蜢 (<CJK Ideograph>) 9146 0x8725 蜥 (<CJK Ideograph>) 9147 0x8734 蜴 (<CJK Ideograph>) 9148 0x8718 蜘 (<CJK Ideograph>) 9149 0x8755 蝕 (<CJK Ideograph>) 9150 0x8737 蜷 (<CJK Ideograph>) 9151 0x8729 蜩 (<CJK Ideograph>) 9152 0x88F3 裳 (<CJK Ideograph>) 9153 0x8902 褂 (<CJK Ideograph>) 9154 0x88F4 裴 (<CJK Ideograph>) 9155 0x88F9 裹 (<CJK Ideograph>) 9156 0x88F8 裸 (<CJK Ideograph>) 9157 0x88FD 製 (<CJK Ideograph>) 9158 0x88E8 裨 (<CJK Ideograph>) 9159 0x891A 褚 (<CJK Ideograph>) 9160 0x88EF 裯 (<CJK Ideograph>) 9161 0x8AA6 誦 (<CJK Ideograph>) 9162 0x8A8C 誌 (<CJK Ideograph>) 9163 0x8A9E 語 (<CJK Ideograph>) 9164 0x8AA3 誣 (<CJK Ideograph>) 9165 0x8A8D 認 (<CJK Ideograph>) 9166 0x8AA1 誡 (<CJK Ideograph>) 9167 0x8A93 誓 (<CJK Ideograph>) 9168 0x8AA4 誤 (<CJK Ideograph>) 9169 0x8AAA 說 (<CJK Ideograph>) 9170 0x8AA5 誥 (<CJK Ideograph>) 9171 0x8AA8 誨 (<CJK Ideograph>) 9172 0x8A98 誘 (<CJK Ideograph>) 9173 0x8A91 誑 (<CJK Ideograph>) 9174 0x8A9A 誚 (<CJK Ideograph>) 9175 0x8AA7 誧 (<CJK Ideograph>) 9176 0x8C6A 豪 (<CJK Ideograph>) 9177 0x8C8D 貍 (<CJK Ideograph>) 9178 0x8C8C 貌 (<CJK Ideograph>) 9179 0x8CD3 賓 (<CJK Ideograph>) 9180 0x8CD1 賑 (<CJK Ideograph>) 9181 0x8CD2 賒 (<CJK Ideograph>) 9182 0x8D6B 赫 (<CJK Ideograph>) 9183 0x8D99 趙 (<CJK Ideograph>) 9184 0x8D95 趕 (<CJK Ideograph>) 9185 0x8DFC 跼 (<CJK Ideograph>) 9186 0x8F14 輔 (<CJK Ideograph>) 9187 0x8F12 輒 (<CJK Ideograph>) 9188 0x8F15 輕 (<CJK Ideograph>) 9189 0x8F13 輓 (<CJK Ideograph>) 9190 0x8FA3 辣 (<CJK Ideograph>) 9191 0x9060 遠 (<CJK Ideograph>) 9192 0x9058 遘 (<CJK Ideograph>) 9193 0x905C 遜 (<CJK Ideograph>) 9194 0x9063 遣 (<CJK Ideograph>) 9195 0x9059 遙 (<CJK Ideograph>) 9196 0x905E 遞 (<CJK Ideograph>) 9197 0x9062 遢 (<CJK Ideograph>) 9198 0x905D 遝 (<CJK Ideograph>) 9199 0x905B 遛 (<CJK Ideograph>) 9200 0x9119 鄙 (<CJK Ideograph>) 9201 0x9118 鄘 (<CJK Ideograph>) 9202 0x911E 鄞 (<CJK Ideograph>) 9203 0x9175 酵 (<CJK Ideograph>) 9204 0x9178 酸 (<CJK Ideograph>) 9205 0x9177 酷 (<CJK Ideograph>) 9206 0x9174 酴 (<CJK Ideograph>) 9207 0x9278 鉸 (<CJK Ideograph>) 9208 0x9280 銀 (<CJK Ideograph>) 9209 0x9285 銅 (<CJK Ideograph>) 9210 0x9298 銘 (<CJK Ideograph>) 9211 0x9296 銖 (<CJK Ideograph>) 9212 0x927B 鉻 (<CJK Ideograph>) 9213 0x9293 銓 (<CJK Ideograph>) 9214 0x929C 銜 (<CJK Ideograph>) 9215 0x92A8 銨 (<CJK Ideograph>) 9216 0x927C 鉼 (<CJK Ideograph>) 9217 0x9291 銑 (<CJK Ideograph>) 9218 0x95A1 閡 (<CJK Ideograph>) 9219 0x95A8 閨 (<CJK Ideograph>) 9220 0x95A9 閩 (<CJK Ideograph>) 9221 0x95A3 閣 (<CJK Ideograph>) 9222 0x95A5 閥 (<CJK Ideograph>) 9223 0x95A4 閤 (<CJK Ideograph>) 9224 0x9699 隙 (<CJK Ideograph>) 9225 0x969C 障 (<CJK Ideograph>) 9226 0x969B 際 (<CJK Ideograph>) 9227 0x96CC 雌 (<CJK Ideograph>) 9228 0x96D2 雒 (<CJK Ideograph>) 9229 0x9700 需 (<CJK Ideograph>) 9230 0x977C 靼 (<CJK Ideograph>) 9231 0x9785 鞅 (<CJK Ideograph>) 9232 0x97F6 韶 (<CJK Ideograph>) 9233 0x9817 頗 (<CJK Ideograph>) 9234 0x9818 領 (<CJK Ideograph>) 9235 0x98AF 颯 (<CJK Ideograph>) 9236 0x98B1 颱 (<CJK Ideograph>) 9237 0x9903 餃 (<CJK Ideograph>) 9238 0x9905 餅 (<CJK Ideograph>) 9239 0x990C 餌 (<CJK Ideograph>) 9240 0x9909 餉 (<CJK Ideograph>) 9241 0x99C1 駁 (<CJK Ideograph>) 9242 0x9AAF 骯 (<CJK Ideograph>) 9243 0x9AB0 骰 (<CJK Ideograph>) 9244 0x9AE6 髦 (<CJK Ideograph>) 9245 0x9B41 魁 (<CJK Ideograph>) 9246 0x9B42 魂 (<CJK Ideograph>) 9247 0x9CF4 鳴 (<CJK Ideograph>) 9248 0x9CF6 鳶 (<CJK Ideograph>) 9249 0x9CF3 鳳 (<CJK Ideograph>) 9250 0x9EBC 麼 (<CJK Ideograph>) 9251 0x9F3B 鼻 (<CJK Ideograph>) 9252 0x9F4A 齊 (<CJK Ideograph>) 9253 0x5104 億 (<CJK Ideograph>) 9254 0x5100 儀 (<CJK Ideograph>) 9255 0x50FB 僻 (<CJK Ideograph>) 9256 0x50F5 僵 (<CJK Ideograph>) 9257 0x50F9 價 (<CJK Ideograph>) 9258 0x5102 儂 (<CJK Ideograph>) 9259 0x5108 儈 (<CJK Ideograph>) 9260 0x5109 儉 (<CJK Ideograph>) 9261 0x5105 儅 (<CJK Ideograph>) 9262 0x51DC 凜 (<CJK Ideograph>) 9263 0x5287 劇 (<CJK Ideograph>) 9264 0x5288 劈 (<CJK Ideograph>) 9265 0x5289 劉 (<CJK Ideograph>) 9266 0x528D 劍 (<CJK Ideograph>) 9267 0x528A 劊 (<CJK Ideograph>) 9268 0x52F0 勰 (<CJK Ideograph>) 9269 0x53B2 厲 (<CJK Ideograph>) 9270 0x562E 嘮 (<CJK Ideograph>) 9271 0x563B 嘻 (<CJK Ideograph>) 9272 0x5639 嘹 (<CJK Ideograph>) 9273 0x5632 嘲 (<CJK Ideograph>) 9274 0x563F 嘿 (<CJK Ideograph>) 9275 0x5634 嘴 (<CJK Ideograph>) 9276 0x5629 嘩 (<CJK Ideograph>) 9277 0x5653 噓 (<CJK Ideograph>) 9278 0x564E 噎 (<CJK Ideograph>) 9279 0x5657 噗 (<CJK Ideograph>) 9280 0x5674 噴 (<CJK Ideograph>) 9281 0x5636 嘶 (<CJK Ideograph>) 9282 0x562F 嘯 (<CJK Ideograph>) 9283 0x5630 嘰 (<CJK Ideograph>) 9284 0x5880 墀 (<CJK Ideograph>) 9285 0x589F 墟 (<CJK Ideograph>) 9286 0x589E 增 (<CJK Ideograph>) 9287 0x58B3 墳 (<CJK Ideograph>) 9288 0x589C 墜 (<CJK Ideograph>) 9289 0x58AE 墮 (<CJK Ideograph>) 9290 0x58A9 墩 (<CJK Ideograph>) 9291 0x58A6 墦 (<CJK Ideograph>) 9292 0x596D 奭 (<CJK Ideograph>) 9293 0x5B09 嬉 (<CJK Ideograph>) 9294 0x5AFB 嫻 (<CJK Ideograph>) 9295 0x5B0B 嬋 (<CJK Ideograph>) 9296 0x5AF5 嫵 (<CJK Ideograph>) 9297 0x5B0C 嬌 (<CJK Ideograph>) 9298 0x5B08 嬈 (<CJK Ideograph>) 9299 0x5BEE 寮 (<CJK Ideograph>) 9300 0x5BEC 寬 (<CJK Ideograph>) 9301 0x5BE9 審 (<CJK Ideograph>) 9302 0x5BEB 寫 (<CJK Ideograph>) 9303 0x5C64 層 (<CJK Ideograph>) 9304 0x5C65 履 (<CJK Ideograph>) 9305 0x5D9D 嶝 (<CJK Ideograph>) 9306 0x5D94 嶔 (<CJK Ideograph>) 9307 0x5E62 幢 (<CJK Ideograph>) 9308 0x5E5F 幟 (<CJK Ideograph>) 9309 0x5E61 幡 (<CJK Ideograph>) 9310 0x5EE2 廢 (<CJK Ideograph>) 9311 0x5EDA 廚 (<CJK Ideograph>) 9312 0x5EDF 廟 (<CJK Ideograph>) 9313 0x5EDD 廝 (<CJK Ideograph>) 9314 0x5EE3 廣 (<CJK Ideograph>) 9315 0x5EE0 廠 (<CJK Ideograph>) 9316 0x5F48 彈 (<CJK Ideograph>) 9317 0x5F71 影 (<CJK Ideograph>) 9318 0x5FB7 德 (<CJK Ideograph>) 9319 0x5FB5 徵 (<CJK Ideograph>) 9320 0x6176 慶 (<CJK Ideograph>) 9321 0x6167 慧 (<CJK Ideograph>) 9322 0x616E 慮 (<CJK Ideograph>) 9323 0x615D 慝 (<CJK Ideograph>) 9324 0x6155 慕 (<CJK Ideograph>) 9325 0x6182 憂 (<CJK Ideograph>) 9326 0x617C 慼 (<CJK Ideograph>) 9327 0x6170 慰 (<CJK Ideograph>) 9328 0x616B 慫 (<CJK Ideograph>) 9329 0x617E 慾 (<CJK Ideograph>) 9330 0x61A7 憧 (<CJK Ideograph>) 9331 0x6190 憐 (<CJK Ideograph>) 9332 0x61AB 憫 (<CJK Ideograph>) 9333 0x618E 憎 (<CJK Ideograph>) 9334 0x61AC 憬 (<CJK Ideograph>) 9335 0x619A 憚 (<CJK Ideograph>) 9336 0x61A4 憤 (<CJK Ideograph>) 9337 0x6194 憔 (<CJK Ideograph>) 9338 0x61AE 憮 (<CJK Ideograph>) 9339 0x622E 戮 (<CJK Ideograph>) 9340 0x6469 摩 (<CJK Ideograph>) 9341 0x646F 摯 (<CJK Ideograph>) 9342 0x6479 摹 (<CJK Ideograph>) 9343 0x649E 撞 (<CJK Ideograph>) 9344 0x64B2 撲 (<CJK Ideograph>) 9345 0x6488 撈 (<CJK Ideograph>) 9346 0x6490 撐 (<CJK Ideograph>) 9347 0x64B0 撰 (<CJK Ideograph>) 9348 0x64A5 撥 (<CJK Ideograph>) 9349 0x6493 撓 (<CJK Ideograph>) 9350 0x6495 撕 (<CJK Ideograph>) 9351 0x64A9 撩 (<CJK Ideograph>) 9352 0x6492 撒 (<CJK Ideograph>) 9353 0x64AE 撮 (<CJK Ideograph>) 9354 0x64AD 播 (<CJK Ideograph>) 9355 0x64AB 撫 (<CJK Ideograph>) 9356 0x649A 撚 (<CJK Ideograph>) 9357 0x64AC 撬 (<CJK Ideograph>) 9358 0x6499 撙 (<CJK Ideograph>) 9359 0x64A2 撢 (<CJK Ideograph>) 9360 0x64B3 撳 (<CJK Ideograph>) 9361 0x6575 敵 (<CJK Ideograph>) 9362 0x6577 敷 (<CJK Ideograph>) 9363 0x6578 數 (<CJK Ideograph>) 9364 0x66AE 暮 (<CJK Ideograph>) 9365 0x66AB 暫 (<CJK Ideograph>) 9366 0x66B4 暴 (<CJK Ideograph>) 9367 0x66B1 暱 (<CJK Ideograph>) 9368 0x6A23 樣 (<CJK Ideograph>) 9369 0x6A1F 樟 (<CJK Ideograph>) 9370 0x69E8 槨 (<CJK Ideograph>) 9371 0x6A01 樁 (<CJK Ideograph>) 9372 0x6A1E 樞 (<CJK Ideograph>) 9373 0x6A19 標 (<CJK Ideograph>) 9374 0x69FD 槽 (<CJK Ideograph>) 9375 0x6A21 模 (<CJK Ideograph>) 9376 0x6A13 樓 (<CJK Ideograph>) 9377 0x6A0A 樊 (<CJK Ideograph>) 9378 0x69F3 槳 (<CJK Ideograph>) 9379 0x6A02 樂 (<CJK Ideograph>) 9380 0x6A05 樅 (<CJK Ideograph>) 9381 0x69ED 槭 (<CJK Ideograph>) 9382 0x6A11 樑 (<CJK Ideograph>) 9383 0x6B50 歐 (<CJK Ideograph>) 9384 0x6B4E 歎 (<CJK Ideograph>) 9385 0x6BA4 殤 (<CJK Ideograph>) 9386 0x6BC5 毅 (<CJK Ideograph>) 9387 0x6BC6 毆 (<CJK Ideograph>) 9388 0x6F3F 漿 (<CJK Ideograph>) 9389 0x6F7C 潼 (<CJK Ideograph>) 9390 0x6F84 澄 (<CJK Ideograph>) 9391 0x6F51 潑 (<CJK Ideograph>) 9392 0x6F66 潦 (<CJK Ideograph>) 9393 0x6F54 潔 (<CJK Ideograph>) 9394 0x6F86 澆 (<CJK Ideograph>) 9395 0x6F6D 潭 (<CJK Ideograph>) 9396 0x6F5B 潛 (<CJK Ideograph>) 9397 0x6F78 潸 (<CJK Ideograph>) 9398 0x6F6E 潮 (<CJK Ideograph>) 9399 0x6F8E 澎 (<CJK Ideograph>) 9400 0x6F7A 潺 (<CJK Ideograph>) 9401 0x6F70 潰 (<CJK Ideograph>) 9402 0x6F64 潤 (<CJK Ideograph>) 9403 0x6F97 澗 (<CJK Ideograph>) 9404 0x6F58 潘 (<CJK Ideograph>) 9405 0x6ED5 滕 (<CJK Ideograph>) 9406 0x6F6F 潯 (<CJK Ideograph>) 9407 0x6F60 潠 (<CJK Ideograph>) 9408 0x6F5F 潟 (<CJK Ideograph>) 9409 0x719F 熟 (<CJK Ideograph>) 9410 0x71AC 熬 (<CJK Ideograph>) 9411 0x71B1 熱 (<CJK Ideograph>) 9412 0x71A8 熨 (<CJK Ideograph>) 9413 0x7256 牖 (<CJK Ideograph>) 9414 0x729B 犛 (<CJK Ideograph>) 9415 0x734E 獎 (<CJK Ideograph>) 9416 0x7357 獗 (<CJK Ideograph>) 9417 0x7469 瑩 (<CJK Ideograph>) 9418 0x748B 璋 (<CJK Ideograph>) 9419 0x7483 璃 (<CJK Ideograph>) 9420 0x747E 瑾 (<CJK Ideograph>) 9421 0x7480 璀 (<CJK Ideograph>) 9422 0x757F 畿 (<CJK Ideograph>) 9423 0x7620 瘠 (<CJK Ideograph>) 9424 0x7629 瘩 (<CJK Ideograph>) 9425 0x761F 瘟 (<CJK Ideograph>) 9426 0x7624 瘤 (<CJK Ideograph>) 9427 0x7626 瘦 (<CJK Ideograph>) 9428 0x7621 瘡 (<CJK Ideograph>) 9429 0x7622 瘢 (<CJK Ideograph>) 9430 0x769A 皚 (<CJK Ideograph>) 9431 0x76BA 皺 (<CJK Ideograph>) 9432 0x76E4 盤 (<CJK Ideograph>) 9433 0x778E 瞎 (<CJK Ideograph>) 9434 0x7787 瞇 (<CJK Ideograph>) 9435 0x778C 瞌 (<CJK Ideograph>) 9436 0x7791 瞑 (<CJK Ideograph>) 9437 0x778B 瞋 (<CJK Ideograph>) 9438 0x78CB 磋 (<CJK Ideograph>) 9439 0x78C5 磅 (<CJK Ideograph>) 9440 0x78BA 確 (<CJK Ideograph>) 9441 0x78CA 磊 (<CJK Ideograph>) 9442 0x78BE 碾 (<CJK Ideograph>) 9443 0x78D5 磕 (<CJK Ideograph>) 9444 0x78BC 碼 (<CJK Ideograph>) 9445 0x78D0 磐 (<CJK Ideograph>) 9446 0x7A3F 稿 (<CJK Ideograph>) 9447 0x7A3C 稼 (<CJK Ideograph>) 9448 0x7A40 穀 (<CJK Ideograph>) 9449 0x7A3D 稽 (<CJK Ideograph>) 9450 0x7A37 稷 (<CJK Ideograph>) 9451 0x7A3B 稻 (<CJK Ideograph>) 9452 0x7AAF 窯 (<CJK Ideograph>) 9453 0x7AAE 窮 (<CJK Ideograph>) 9454 0x7BAD 箭 (<CJK Ideograph>) 9455 0x7BB1 箱 (<CJK Ideograph>) 9456 0x7BC4 範 (<CJK Ideograph>) 9457 0x7BB4 箴 (<CJK Ideograph>) 9458 0x7BC6 篆 (<CJK Ideograph>) 9459 0x7BC7 篇 (<CJK Ideograph>) 9460 0x7BC1 篁 (<CJK Ideograph>) 9461 0x7BA0 箠 (<CJK Ideograph>) 9462 0x7BCC 篌 (<CJK Ideograph>) 9463 0x7CCA 糊 (<CJK Ideograph>) 9464 0x7DE0 締 (<CJK Ideograph>) 9465 0x7DF4 練 (<CJK Ideograph>) 9466 0x7DEF 緯 (<CJK Ideograph>) 9467 0x7DFB 緻 (<CJK Ideograph>) 9468 0x7DD8 緘 (<CJK Ideograph>) 9469 0x7DEC 緬 (<CJK Ideograph>) 9470 0x7DDD 緝 (<CJK Ideograph>) 9471 0x7DE8 編 (<CJK Ideograph>) 9472 0x7DE3 緣 (<CJK Ideograph>) 9473 0x7DDA 線 (<CJK Ideograph>) 9474 0x7DDE 緞 (<CJK Ideograph>) 9475 0x7DE9 緩 (<CJK Ideograph>) 9476 0x7D9E 綞 (<CJK Ideograph>) 9477 0x7DD9 緙 (<CJK Ideograph>) 9478 0x7DF2 緲 (<CJK Ideograph>) 9479 0x7DF9 緹 (<CJK Ideograph>) 9480 0x7F75 罵 (<CJK Ideograph>) 9481 0x7F77 罷 (<CJK Ideograph>) 9482 0x7FAF 羯 (<CJK Ideograph>) 9483 0x7FE9 翩 (<CJK Ideograph>) 9484 0x8026 耦 (<CJK Ideograph>) 9485 0x819B 膛 (<CJK Ideograph>) 9486 0x819C 膜 (<CJK Ideograph>) 9487 0x819D 膝 (<CJK Ideograph>) 9488 0x81A0 膠 (<CJK Ideograph>) 9489 0x819A 膚 (<CJK Ideograph>) 9490 0x8198 膘 (<CJK Ideograph>) 9491 0x8517 蔗 (<CJK Ideograph>) 9492 0x853D 蔽 (<CJK Ideograph>) 9493 0x851A 蔚 (<CJK Ideograph>) 9494 0x84EE 蓮 (<CJK Ideograph>) 9495 0x852C 蔬 (<CJK Ideograph>) 9496 0x852D 蔭 (<CJK Ideograph>) 9497 0x8513 蔓 (<CJK Ideograph>) 9498 0x8511 蔑 (<CJK Ideograph>) 9499 0x8523 蔣 (<CJK Ideograph>) 9500 0x8521 蔡 (<CJK Ideograph>) 9501 0x8514 蔔 (<CJK Ideograph>) 9502 0x84EC 蓬 (<CJK Ideograph>) 9503 0x8525 蔥 (<CJK Ideograph>) 9504 0x84FF 蓿 (<CJK Ideograph>) 9505 0x8506 蔆 (<CJK Ideograph>) 9506 0x8782 螂 (<CJK Ideograph>) 9507 0x8774 蝴 (<CJK Ideograph>) 9508 0x8776 蝶 (<CJK Ideograph>) 9509 0x8760 蝠 (<CJK Ideograph>) 9510 0x8766 蝦 (<CJK Ideograph>) 9511 0x8778 蝸 (<CJK Ideograph>) 9512 0x8768 蝨 (<CJK Ideograph>) 9513 0x8759 蝙 (<CJK Ideograph>) 9514 0x8757 蝗 (<CJK Ideograph>) 9515 0x874C 蝌 (<CJK Ideograph>) 9516 0x8753 蝓 (<CJK Ideograph>) 9517 0x885B 衛 (<CJK Ideograph>) 9518 0x885D 衝 (<CJK Ideograph>) 9519 0x8910 褐 (<CJK Ideograph>) 9520 0x8907 複 (<CJK Ideograph>) 9521 0x8912 褒 (<CJK Ideograph>) 9522 0x8913 褓 (<CJK Ideograph>) 9523 0x8915 褕 (<CJK Ideograph>) 9524 0x890A 褊 (<CJK Ideograph>) 9525 0x8ABC 誼 (<CJK Ideograph>) 9526 0x8AD2 諒 (<CJK Ideograph>) 9527 0x8AC7 談 (<CJK Ideograph>) 9528 0x8AC4 諄 (<CJK Ideograph>) 9529 0x8A95 誕 (<CJK Ideograph>) 9530 0x8ACB 請 (<CJK Ideograph>) 9531 0x8AF8 諸 (<CJK Ideograph>) 9532 0x8AB2 課 (<CJK Ideograph>) 9533 0x8AC9 諉 (<CJK Ideograph>) 9534 0x8AC2 諂 (<CJK Ideograph>) 9535 0x8ABF 調 (<CJK Ideograph>) 9536 0x8AB0 誰 (<CJK Ideograph>) 9537 0x8AD6 論 (<CJK Ideograph>) 9538 0x8ACD 諍 (<CJK Ideograph>) 9539 0x8AB6 誶 (<CJK Ideograph>) 9540 0x8AB9 誹 (<CJK Ideograph>) 9541 0x8ADB 諛 (<CJK Ideograph>) 9542 0x8C4C 豌 (<CJK Ideograph>) 9543 0x8C4E 豎 (<CJK Ideograph>) 9544 0x8C6C 豬 (<CJK Ideograph>) 9545 0x8CE0 賠 (<CJK Ideograph>) 9546 0x8CDE 賞 (<CJK Ideograph>) 9547 0x8CE6 賦 (<CJK Ideograph>) 9548 0x8CE4 賤 (<CJK Ideograph>) 9549 0x8CEC 賬 (<CJK Ideograph>) 9550 0x8CED 賭 (<CJK Ideograph>) 9551 0x8CE2 賢 (<CJK Ideograph>) 9552 0x8CE3 賣 (<CJK Ideograph>) 9553 0x8CDC 賜 (<CJK Ideograph>) 9554 0x8CEA 質 (<CJK Ideograph>) 9555 0x8CE1 賡 (<CJK Ideograph>) 9556 0x8D6D 赭 (<CJK Ideograph>) 9557 0x8D9F 趟 (<CJK Ideograph>) 9558 0x8DA3 趣 (<CJK Ideograph>) 9559 0x8E2B 踫 (<CJK Ideograph>) 9560 0x8E10 踐 (<CJK Ideograph>) 9561 0x8E1D 踝 (<CJK Ideograph>) 9562 0x8E22 踢 (<CJK Ideograph>) 9563 0x8E0F 踏 (<CJK Ideograph>) 9564 0x8E29 踩 (<CJK Ideograph>) 9565 0x8E1F 踟 (<CJK Ideograph>) 9566 0x8E21 踡 (<CJK Ideograph>) 9567 0x8E1E 踞 (<CJK Ideograph>) 9568 0x8EBA 躺 (<CJK Ideograph>) 9569 0x8F1D 輝 (<CJK Ideograph>) 9570 0x8F1B 輛 (<CJK Ideograph>) 9571 0x8F1F 輟 (<CJK Ideograph>) 9572 0x8F29 輩 (<CJK Ideograph>) 9573 0x8F26 輦 (<CJK Ideograph>) 9574 0x8F2A 輪 (<CJK Ideograph>) 9575 0x8F1C 輜 (<CJK Ideograph>) 9576 0x8F1E 輞 (<CJK Ideograph>) 9577 0x8F25 輥 (<CJK Ideograph>) 9578 0x9069 適 (<CJK Ideograph>) 9579 0x906E 遮 (<CJK Ideograph>) 9580 0x9068 遨 (<CJK Ideograph>) 9581 0x906D 遭 (<CJK Ideograph>) 9582 0x9077 遷 (<CJK Ideograph>) 9583 0x9130 鄰 (<CJK Ideograph>) 9584 0x912D 鄭 (<CJK Ideograph>) 9585 0x9127 鄧 (<CJK Ideograph>) 9586 0x9131 鄱 (<CJK Ideograph>) 9587 0x9187 醇 (<CJK Ideograph>) 9588 0x9189 醉 (<CJK Ideograph>) 9589 0x918B 醋 (<CJK Ideograph>) 9590 0x9183 醃 (<CJK Ideograph>) 9591 0x92C5 鋅 (<CJK Ideograph>) 9592 0x92BB 銻 (<CJK Ideograph>) 9593 0x92B7 銷 (<CJK Ideograph>) 9594 0x92EA 鋪 (<CJK Ideograph>) 9595 0x92AC 銬 (<CJK Ideograph>) 9596 0x92E4 鋤 (<CJK Ideograph>) 9597 0x92C1 鋁 (<CJK Ideograph>) 9598 0x92B3 銳 (<CJK Ideograph>) 9599 0x92BC 銼 (<CJK Ideograph>) 9600 0x92D2 鋒 (<CJK Ideograph>) 9601 0x92C7 鋇 (<CJK Ideograph>) 9602 0x92F0 鋰 (<CJK Ideograph>) 9603 0x92B2 銲 (<CJK Ideograph>) 9604 0x95AD 閭 (<CJK Ideograph>) 9605 0x95B1 閱 (<CJK Ideograph>) 9606 0x9704 霄 (<CJK Ideograph>) 9607 0x9706 霆 (<CJK Ideograph>) 9608 0x9707 震 (<CJK Ideograph>) 9609 0x9709 霉 (<CJK Ideograph>) 9610 0x9760 靠 (<CJK Ideograph>) 9611 0x978D 鞍 (<CJK Ideograph>) 9612 0x978B 鞋 (<CJK Ideograph>) 9613 0x978F 鞏 (<CJK Ideograph>) 9614 0x9821 頡 (<CJK Ideograph>) 9615 0x982B 頫 (<CJK Ideograph>) 9616 0x981C 頜 (<CJK Ideograph>) 9617 0x98B3 颳 (<CJK Ideograph>) 9618 0x990A 養 (<CJK Ideograph>) 9619 0x9913 餓 (<CJK Ideograph>) 9620 0x9912 餒 (<CJK Ideograph>) 9621 0x9918 餘 (<CJK Ideograph>) 9622 0x99DD 駝 (<CJK Ideograph>) 9623 0x99D0 駐 (<CJK Ideograph>) 9624 0x99DF 駟 (<CJK Ideograph>) 9625 0x99DB 駛 (<CJK Ideograph>) 9626 0x99D1 駑 (<CJK Ideograph>) 9627 0x99D5 駕 (<CJK Ideograph>) 9628 0x99D2 駒 (<CJK Ideograph>) 9629 0x99D9 駙 (<CJK Ideograph>) 9630 0x9AB7 骷 (<CJK Ideograph>) 9631 0x9AEE 髮 (<CJK Ideograph>) 9632 0x9AEF 髯 (<CJK Ideograph>) 9633 0x9B27 鬧 (<CJK Ideograph>) 9634 0x9B45 魅 (<CJK Ideograph>) 9635 0x9B44 魄 (<CJK Ideograph>) 9636 0x9B77 魷 (<CJK Ideograph>) 9637 0x9B6F 魯 (<CJK Ideograph>) 9638 0x9D06 鴆 (<CJK Ideograph>) 9639 0x9D09 鴉 (<CJK Ideograph>) 9640 0x9D03 鴃 (<CJK Ideograph>) 9641 0x9EA9 麩 (<CJK Ideograph>) 9642 0x9EBE 麾 (<CJK Ideograph>) 9643 0x9ECE 黎 (<CJK Ideograph>) 9644 0x58A8 墨 (<CJK Ideograph>) 9645 0x9F52 齒 (<CJK Ideograph>) 9646 0x5112 儒 (<CJK Ideograph>) 9647 0x5118 儘 (<CJK Ideograph>) 9648 0x5114 儔 (<CJK Ideograph>) 9649 0x5110 儐 (<CJK Ideograph>) 9650 0x5115 儕 (<CJK Ideograph>) 9651 0x5180 冀 (<CJK Ideograph>) 9652 0x51AA 冪 (<CJK Ideograph>) 9653 0x51DD 凝 (<CJK Ideograph>) 9654 0x5291 劑 (<CJK Ideograph>) 9655 0x5293 劓 (<CJK Ideograph>) 9656 0x52F3 勳 (<CJK Ideograph>) 9657 0x5659 噙 (<CJK Ideograph>) 9658 0x566B 噫 (<CJK Ideograph>) 9659 0x5679 噹 (<CJK Ideograph>) 9660 0x5669 噩 (<CJK Ideograph>) 9661 0x5664 噤 (<CJK Ideograph>) 9662 0x5678 噸 (<CJK Ideograph>) 9663 0x566A 噪 (<CJK Ideograph>) 9664 0x5668 器 (<CJK Ideograph>) 9665 0x5665 噥 (<CJK Ideograph>) 9666 0x5671 噱 (<CJK Ideograph>) 9667 0x566F 噯 (<CJK Ideograph>) 9668 0x566C 噬 (<CJK Ideograph>) 9669 0x5662 噢 (<CJK Ideograph>) 9670 0x5676 噶 (<CJK Ideograph>) 9671 0x58C1 壁 (<CJK Ideograph>) 9672 0x58BE 墾 (<CJK Ideograph>) 9673 0x58C7 壇 (<CJK Ideograph>) 9674 0x58C5 壅 (<CJK Ideograph>) 9675 0x596E 奮 (<CJK Ideograph>) 9676 0x5B1D 嬝 (<CJK Ideograph>) 9677 0x5B34 嬴 (<CJK Ideograph>) 9678 0x5B78 學 (<CJK Ideograph>) 9679 0x5BF0 寰 (<CJK Ideograph>) 9680 0x5C0E 導 (<CJK Ideograph>) 9681 0x5F4A 彊 (<CJK Ideograph>) 9682 0x61B2 憲 (<CJK Ideograph>) 9683 0x6191 憑 (<CJK Ideograph>) 9684 0x61A9 憩 (<CJK Ideograph>) 9685 0x618A 憊 (<CJK Ideograph>) 9686 0x61CD 懍 (<CJK Ideograph>) 9687 0x61B6 憶 (<CJK Ideograph>) 9688 0x61BE 憾 (<CJK Ideograph>) 9689 0x61CA 懊 (<CJK Ideograph>) 9690 0x61C8 懈 (<CJK Ideograph>) 9691 0x6230 戰 (<CJK Ideograph>) 9692 0x64C5 擅 (<CJK Ideograph>) 9693 0x64C1 擁 (<CJK Ideograph>) 9694 0x64CB 擋 (<CJK Ideograph>) 9695 0x64BB 撻 (<CJK Ideograph>) 9696 0x64BC 撼 (<CJK Ideograph>) 9697 0x64DA 據 (<CJK Ideograph>) 9698 0x64C4 擄 (<CJK Ideograph>) 9699 0x64C7 擇 (<CJK Ideograph>) 9700 0x64C2 擂 (<CJK Ideograph>) 9701 0x64CD 操 (<CJK Ideograph>) 9702 0x64BF 撿 (<CJK Ideograph>) 9703 0x64D2 擒 (<CJK Ideograph>) 9704 0x64D4 擔 (<CJK Ideograph>) 9705 0x64BE 撾 (<CJK Ideograph>) 9706 0x6574 整 (<CJK Ideograph>) 9707 0x66C6 曆 (<CJK Ideograph>) 9708 0x66C9 曉 (<CJK Ideograph>) 9709 0x66B9 暹 (<CJK Ideograph>) 9710 0x66C4 曄 (<CJK Ideograph>) 9711 0x66C7 曇 (<CJK Ideograph>) 9712 0x66B8 暸 (<CJK Ideograph>) 9713 0x6A3D 樽 (<CJK Ideograph>) 9714 0x6A38 樸 (<CJK Ideograph>) 9715 0x6A3A 樺 (<CJK Ideograph>) 9716 0x6A59 橙 (<CJK Ideograph>) 9717 0x6A6B 橫 (<CJK Ideograph>) 9718 0x6A58 橘 (<CJK Ideograph>) 9719 0x6A39 樹 (<CJK Ideograph>) 9720 0x6A44 橄 (<CJK Ideograph>) 9721 0x6A62 橢 (<CJK Ideograph>) 9722 0x6A61 橡 (<CJK Ideograph>) 9723 0x6A4B 橋 (<CJK Ideograph>) 9724 0x6A47 橇 (<CJK Ideograph>) 9725 0x6A35 樵 (<CJK Ideograph>) 9726 0x6A5F 機 (<CJK Ideograph>) 9727 0x6A48 橈 (<CJK Ideograph>) 9728 0x6B59 歙 (<CJK Ideograph>) 9729 0x6B77 歷 (<CJK Ideograph>) 9730 0x6C05 氅 (<CJK Ideograph>) 9731 0x6FC2 濂 (<CJK Ideograph>) 9732 0x6FB1 澱 (<CJK Ideograph>) 9733 0x6FA1 澡 (<CJK Ideograph>) 9734 0x6FC3 濃 (<CJK Ideograph>) 9735 0x6FA4 澤 (<CJK Ideograph>) 9736 0x6FC1 濁 (<CJK Ideograph>) 9737 0x6FA7 澧 (<CJK Ideograph>) 9738 0x6FB3 澳 (<CJK Ideograph>) 9739 0x6FC0 激 (<CJK Ideograph>) 9740 0x6FB9 澹 (<CJK Ideograph>) 9741 0x6FB6 澶 (<CJK Ideograph>) 9742 0x6FA6 澦 (<CJK Ideograph>) 9743 0x6FA0 澠 (<CJK Ideograph>) 9744 0x6FB4 澴 (<CJK Ideograph>) 9745 0x71BE 熾 (<CJK Ideograph>) 9746 0x71C9 燉 (<CJK Ideograph>) 9747 0x71D0 燐 (<CJK Ideograph>) 9748 0x71D2 燒 (<CJK Ideograph>) 9749 0x71C8 燈 (<CJK Ideograph>) 9750 0x71D5 燕 (<CJK Ideograph>) 9751 0x71B9 熹 (<CJK Ideograph>) 9752 0x71CE 燎 (<CJK Ideograph>) 9753 0x71D9 燙 (<CJK Ideograph>) 9754 0x71DC 燜 (<CJK Ideograph>) 9755 0x71C3 燃 (<CJK Ideograph>) 9756 0x71C4 燄 (<CJK Ideograph>) 9757 0x7368 獨 (<CJK Ideograph>) 9758 0x749C 璜 (<CJK Ideograph>) 9759 0x74A3 璣 (<CJK Ideograph>) 9760 0x7498 璘 (<CJK Ideograph>) 9761 0x749F 璟 (<CJK Ideograph>) 9762 0x749E 璞 (<CJK Ideograph>) 9763 0x74E2 瓢 (<CJK Ideograph>) 9764 0x750C 甌 (<CJK Ideograph>) 9765 0x750D 甍 (<CJK Ideograph>) 9766 0x7634 瘴 (<CJK Ideograph>) 9767 0x7638 瘸 (<CJK Ideograph>) 9768 0x763A 瘺 (<CJK Ideograph>) 9769 0x76E7 盧 (<CJK Ideograph>) 9770 0x76E5 盥 (<CJK Ideograph>) 9771 0x77A0 瞠 (<CJK Ideograph>) 9772 0x779E 瞞 (<CJK Ideograph>) 9773 0x779F 瞟 (<CJK Ideograph>) 9774 0x77A5 瞥 (<CJK Ideograph>) 9775 0x78E8 磨 (<CJK Ideograph>) 9776 0x78DA 磚 (<CJK Ideograph>) 9777 0x78EC 磬 (<CJK Ideograph>) 9778 0x78E7 磧 (<CJK Ideograph>) 9779 0x79A6 禦 (<CJK Ideograph>) 9780 0x7A4D 積 (<CJK Ideograph>) 9781 0x7A4E 穎 (<CJK Ideograph>) 9782 0x7A46 穆 (<CJK Ideograph>) 9783 0x7A4C 穌 (<CJK Ideograph>) 9784 0x7A4B 穋 (<CJK Ideograph>) 9785 0x7ABA 窺 (<CJK Ideograph>) 9786 0x7BD9 篙 (<CJK Ideograph>) 9787 0x7C11 簑 (<CJK Ideograph>) 9788 0x7BC9 築 (<CJK Ideograph>) 9789 0x7BE4 篤 (<CJK Ideograph>) 9790 0x7BDB 篛 (<CJK Ideograph>) 9791 0x7BE1 篡 (<CJK Ideograph>) 9792 0x7BE9 篩 (<CJK Ideograph>) 9793 0x7BE6 篦 (<CJK Ideograph>) 9794 0x7CD5 糕 (<CJK Ideograph>) 9795 0x7CD6 糖 (<CJK Ideograph>) 9796 0x7E0A 縊 (<CJK Ideograph>) 9797 0x7E11 縑 (<CJK Ideograph>) 9798 0x7E08 縈 (<CJK Ideograph>) 9799 0x7E1B 縛 (<CJK Ideograph>) 9800 0x7E23 縣 (<CJK Ideograph>) 9801 0x7E1E 縞 (<CJK Ideograph>) 9802 0x7E1D 縝 (<CJK Ideograph>) 9803 0x7E09 縉 (<CJK Ideograph>) 9804 0x7E10 縐 (<CJK Ideograph>) 9805 0x7F79 罹 (<CJK Ideograph>) 9806 0x7FB2 羲 (<CJK Ideograph>) 9807 0x7FF0 翰 (<CJK Ideograph>) 9808 0x7FF1 翱 (<CJK Ideograph>) 9809 0x7FEE 翮 (<CJK Ideograph>) 9810 0x8028 耨 (<CJK Ideograph>) 9811 0x81B3 膳 (<CJK Ideograph>) 9812 0x81A9 膩 (<CJK Ideograph>) 9813 0x81A8 膨 (<CJK Ideograph>) 9814 0x81FB 臻 (<CJK Ideograph>) 9815 0x8208 興 (<CJK Ideograph>) 9816 0x8258 艘 (<CJK Ideograph>) 9817 0x8259 艙 (<CJK Ideograph>) 9818 0x854A 蕊 (<CJK Ideograph>) 9819 0x8559 蕙 (<CJK Ideograph>) 9820 0x8548 蕈 (<CJK Ideograph>) 9821 0x8568 蕨 (<CJK Ideograph>) 9822 0x8569 蕩 (<CJK Ideograph>) 9823 0x8543 蕃 (<CJK Ideograph>) 9824 0x8549 蕉 (<CJK Ideograph>) 9825 0x856D 蕭 (<CJK Ideograph>) 9826 0x856A 蕪 (<CJK Ideograph>) 9827 0x855E 蕞 (<CJK Ideograph>) 9828 0x8783 螃 (<CJK Ideograph>) 9829 0x879F 螟 (<CJK Ideograph>) 9830 0x879E 螞 (<CJK Ideograph>) 9831 0x87A2 螢 (<CJK Ideograph>) 9832 0x878D 融 (<CJK Ideograph>) 9833 0x8861 衡 (<CJK Ideograph>) 9834 0x892A 褪 (<CJK Ideograph>) 9835 0x8932 褲 (<CJK Ideograph>) 9836 0x8925 褥 (<CJK Ideograph>) 9837 0x892B 褫 (<CJK Ideograph>) 9838 0x8921 褡 (<CJK Ideograph>) 9839 0x89AA 親 (<CJK Ideograph>) 9840 0x89A6 覦 (<CJK Ideograph>) 9841 0x8AE6 諦 (<CJK Ideograph>) 9842 0x8AFA 諺 (<CJK Ideograph>) 9843 0x8AEB 諫 (<CJK Ideograph>) 9844 0x8AF1 諱 (<CJK Ideograph>) 9845 0x8B00 謀 (<CJK Ideograph>) 9846 0x8ADC 諜 (<CJK Ideograph>) 9847 0x8AE7 諧 (<CJK Ideograph>) 9848 0x8AEE 諮 (<CJK Ideograph>) 9849 0x8AFE 諾 (<CJK Ideograph>) 9850 0x8B01 謁 (<CJK Ideograph>) 9851 0x8B02 謂 (<CJK Ideograph>) 9852 0x8AF7 諷 (<CJK Ideograph>) 9853 0x8AED 諭 (<CJK Ideograph>) 9854 0x8AF3 諳 (<CJK Ideograph>) 9855 0x8AF6 諶 (<CJK Ideograph>) 9856 0x8AFC 諼 (<CJK Ideograph>) 9857 0x8C6B 豫 (<CJK Ideograph>) 9858 0x8C6D 豭 (<CJK Ideograph>) 9859 0x8C93 貓 (<CJK Ideograph>) 9860 0x8CF4 賴 (<CJK Ideograph>) 9861 0x8E44 蹄 (<CJK Ideograph>) 9862 0x8E31 踱 (<CJK Ideograph>) 9863 0x8E34 踴 (<CJK Ideograph>) 9864 0x8E42 蹂 (<CJK Ideograph>) 9865 0x8E39 踹 (<CJK Ideograph>) 9866 0x8E35 踵 (<CJK Ideograph>) 9867 0x8F3B 輻 (<CJK Ideograph>) 9868 0x8F2F 輯 (<CJK Ideograph>) 9869 0x8F38 輸 (<CJK Ideograph>) 9870 0x8F33 輳 (<CJK Ideograph>) 9871 0x8FA8 辨 (<CJK Ideograph>) 9872 0x8FA6 辦 (<CJK Ideograph>) 9873 0x9075 遵 (<CJK Ideograph>) 9874 0x9074 遴 (<CJK Ideograph>) 9875 0x9078 選 (<CJK Ideograph>) 9876 0x9072 遲 (<CJK Ideograph>) 9877 0x907C 遼 (<CJK Ideograph>) 9878 0x907A 遺 (<CJK Ideograph>) 9879 0x9134 鄴 (<CJK Ideograph>) 9880 0x9192 醒 (<CJK Ideograph>) 9881 0x9320 錠 (<CJK Ideograph>) 9882 0x9336 錶 (<CJK Ideograph>) 9883 0x92F8 鋸 (<CJK Ideograph>) 9884 0x9333 錳 (<CJK Ideograph>) 9885 0x932F 錯 (<CJK Ideograph>) 9886 0x9322 錢 (<CJK Ideograph>) 9887 0x92FC 鋼 (<CJK Ideograph>) 9888 0x932B 錫 (<CJK Ideograph>) 9889 0x9304 錄 (<CJK Ideograph>) 9890 0x931A 錚 (<CJK Ideograph>) 9891 0x9310 錐 (<CJK Ideograph>) 9892 0x9326 錦 (<CJK Ideograph>) 9893 0x9321 錡 (<CJK Ideograph>) 9894 0x9315 錕 (<CJK Ideograph>) 9895 0x932E 錮 (<CJK Ideograph>) 9896 0x9319 錙 (<CJK Ideograph>) 9897 0x95BB 閻 (<CJK Ideograph>) 9898 0x96A7 隧 (<CJK Ideograph>) 9899 0x96A8 隨 (<CJK Ideograph>) 9900 0x96AA 險 (<CJK Ideograph>) 9901 0x96D5 雕 (<CJK Ideograph>) 9902 0x970E 霎 (<CJK Ideograph>) 9903 0x9711 霑 (<CJK Ideograph>) 9904 0x9716 霖 (<CJK Ideograph>) 9905 0x970D 霍 (<CJK Ideograph>) 9906 0x9713 霓 (<CJK Ideograph>) 9907 0x970F 霏 (<CJK Ideograph>) 9908 0x975B 靛 (<CJK Ideograph>) 9909 0x975C 靜 (<CJK Ideograph>) 9910 0x9766 靦 (<CJK Ideograph>) 9911 0x9798 鞘 (<CJK Ideograph>) 9912 0x9830 頰 (<CJK Ideograph>) 9913 0x9838 頸 (<CJK Ideograph>) 9914 0x983B 頻 (<CJK Ideograph>) 9915 0x9837 頷 (<CJK Ideograph>) 9916 0x982D 頭 (<CJK Ideograph>) 9917 0x9839 頹 (<CJK Ideograph>) 9918 0x9824 頤 (<CJK Ideograph>) 9919 0x9910 餐 (<CJK Ideograph>) 9920 0x9928 館 (<CJK Ideograph>) 9921 0x991E 餞 (<CJK Ideograph>) 9922 0x991B 餛 (<CJK Ideograph>) 9923 0x9921 餡 (<CJK Ideograph>) 9924 0x991A 餚 (<CJK Ideograph>) 9925 0x99ED 駭 (<CJK Ideograph>) 9926 0x99E2 駢 (<CJK Ideograph>) 9927 0x99F1 駱 (<CJK Ideograph>) 9928 0x9AB8 骸 (<CJK Ideograph>) 9929 0x9ABC 骼 (<CJK Ideograph>) 9930 0x9AFB 髻 (<CJK Ideograph>) 9931 0x9AED 髭 (<CJK Ideograph>) 9932 0x9B28 鬨 (<CJK Ideograph>) 9933 0x9B91 鮑 (<CJK Ideograph>) 9934 0x9D15 鴕 (<CJK Ideograph>) 9935 0x9D23 鴣 (<CJK Ideograph>) 9936 0x9D26 鴦 (<CJK Ideograph>) 9937 0x9D28 鴨 (<CJK Ideograph>) 9938 0x9D12 鴒 (<CJK Ideograph>) 9939 0x9D1B 鴛 (<CJK Ideograph>) 9940 0x9ED8 默 (<CJK Ideograph>) 9941 0x9ED4 黔 (<CJK Ideograph>) 9942 0x9F8D 龍 (<CJK Ideograph>) 9943 0x9F9C 龜 (<CJK Ideograph>) 9944 0x512A 優 (<CJK Ideograph>) 9945 0x511F 償 (<CJK Ideograph>) 9946 0x5121 儡 (<CJK Ideograph>) 9947 0x5132 儲 (<CJK Ideograph>) 9948 0x52F5 勵 (<CJK Ideograph>) 9949 0x568E 嚎 (<CJK Ideograph>) 9950 0x5680 嚀 (<CJK Ideograph>) 9951 0x5690 嚐 (<CJK Ideograph>) 9952 0x5685 嚅 (<CJK Ideograph>) 9953 0x5687 嚇 (<CJK Ideograph>) 9954 0x568F 嚏 (<CJK Ideograph>) 9955 0x58D5 壕 (<CJK Ideograph>) 9956 0x58D3 壓 (<CJK Ideograph>) 9957 0x58D1 壑 (<CJK Ideograph>) 9958 0x58CE 壎 (<CJK Ideograph>) 9959 0x5B30 嬰 (<CJK Ideograph>) 9960 0x5B2A 嬪 (<CJK Ideograph>) 9961 0x5B24 嬤 (<CJK Ideograph>) 9962 0x5B7A 孺 (<CJK Ideograph>) 9963 0x5C37 尷 (<CJK Ideograph>) 9964 0x5C68 屨 (<CJK Ideograph>) 9965 0x5DBC 嶼 (<CJK Ideograph>) 9966 0x5DBA 嶺 (<CJK Ideograph>) 9967 0x5DBD 嶽 (<CJK Ideograph>) 9968 0x5DB8 嶸 (<CJK Ideograph>) 9969 0x5E6B 幫 (<CJK Ideograph>) 9970 0x5F4C 彌 (<CJK Ideograph>) 9971 0x5FBD 徽 (<CJK Ideograph>) 9972 0x61C9 應 (<CJK Ideograph>) 9973 0x61C2 懂 (<CJK Ideograph>) 9974 0x61C7 懇 (<CJK Ideograph>) 9975 0x61E6 懦 (<CJK Ideograph>) 9976 0x61CB 懋 (<CJK Ideograph>) 9977 0x6232 戲 (<CJK Ideograph>) 9978 0x6234 戴 (<CJK Ideograph>) 9979 0x64CE 擎 (<CJK Ideograph>) 9980 0x64CA 擊 (<CJK Ideograph>) 9981 0x64D8 擘 (<CJK Ideograph>) 9982 0x64E0 擠 (<CJK Ideograph>) 9983 0x64F0 擰 (<CJK Ideograph>) 9984 0x64E6 擦 (<CJK Ideograph>) 9985 0x64EC 擬 (<CJK Ideograph>) 9986 0x64F1 擱 (<CJK Ideograph>) 9987 0x64E2 擢 (<CJK Ideograph>) 9988 0x64ED 擭 (<CJK Ideograph>) 9989 0x6582 斂 (<CJK Ideograph>) 9990 0x6583 斃 (<CJK Ideograph>) 9991 0x66D9 曙 (<CJK Ideograph>) 9992 0x66D6 曖 (<CJK Ideograph>) 9993 0x6A80 檀 (<CJK Ideograph>) 9994 0x6A94 檔 (<CJK Ideograph>) 9995 0x6A84 檄 (<CJK Ideograph>) 9996 0x6AA2 檢 (<CJK Ideograph>) 9997 0x6A9C 檜 (<CJK Ideograph>) 9998 0x6ADB 櫛 (<CJK Ideograph>) 9999 0x6AA3 檣 (<CJK Ideograph>) 10000 0x6A7E 橾 (<CJK Ideograph>) 10001 0x6A97 檗 (<CJK Ideograph>) 10002 0x6A90 檐 (<CJK Ideograph>) 10003 0x6AA0 檠 (<CJK Ideograph>) 10004 0x6B5C 歜 (<CJK Ideograph>) 10005 0x6BAE 殮 (<CJK Ideograph>) 10006 0x6BDA 毚 (<CJK Ideograph>) 10007 0x6C08 氈 (<CJK Ideograph>) 10008 0x6FD8 濘 (<CJK Ideograph>) 10009 0x6FF1 濱 (<CJK Ideograph>) 10010 0x6FDF 濟 (<CJK Ideograph>) 10011 0x6FE0 濠 (<CJK Ideograph>) 10012 0x6FDB 濛 (<CJK Ideograph>) 10013 0x6FE4 濤 (<CJK Ideograph>) 10014 0x6FEB 濫 (<CJK Ideograph>) 10015 0x6FEF 濯 (<CJK Ideograph>) 10016 0x6F80 澀 (<CJK Ideograph>) 10017 0x6FEC 濬 (<CJK Ideograph>) 10018 0x6FE1 濡 (<CJK Ideograph>) 10019 0x6FE9 濩 (<CJK Ideograph>) 10020 0x6FD5 濕 (<CJK Ideograph>) 10021 0x6FEE 濮 (<CJK Ideograph>) 10022 0x6FF0 濰 (<CJK Ideograph>) 10023 0x71E7 燧 (<CJK Ideograph>) 10024 0x71DF 營 (<CJK Ideograph>) 10025 0x71EE 燮 (<CJK Ideograph>) 10026 0x71E6 燦 (<CJK Ideograph>) 10027 0x71E5 燥 (<CJK Ideograph>) 10028 0x71ED 燭 (<CJK Ideograph>) 10029 0x71EC 燬 (<CJK Ideograph>) 10030 0x71F4 燴 (<CJK Ideograph>) 10031 0x71E0 燠 (<CJK Ideograph>) 10032 0x7235 爵 (<CJK Ideograph>) 10033 0x7246 牆 (<CJK Ideograph>) 10034 0x7370 獰 (<CJK Ideograph>) 10035 0x7372 獲 (<CJK Ideograph>) 10036 0x74A9 璩 (<CJK Ideograph>) 10037 0x74B0 環 (<CJK Ideograph>) 10038 0x74A6 璦 (<CJK Ideograph>) 10039 0x74A8 璨 (<CJK Ideograph>) 10040 0x7646 癆 (<CJK Ideograph>) 10041 0x7642 療 (<CJK Ideograph>) 10042 0x764C 癌 (<CJK Ideograph>) 10043 0x76EA 盪 (<CJK Ideograph>) 10044 0x77B3 瞳 (<CJK Ideograph>) 10045 0x77AA 瞪 (<CJK Ideograph>) 10046 0x77B0 瞰 (<CJK Ideograph>) 10047 0x77AC 瞬 (<CJK Ideograph>) 10048 0x77A7 瞧 (<CJK Ideograph>) 10049 0x77AD 瞭 (<CJK Ideograph>) 10050 0x77EF 矯 (<CJK Ideograph>) 10051 0x78F7 磷 (<CJK Ideograph>) 10052 0x78FA 磺 (<CJK Ideograph>) 10053 0x78F4 磴 (<CJK Ideograph>) 10054 0x78EF 磯 (<CJK Ideograph>) 10055 0x7901 礁 (<CJK Ideograph>) 10056 0x79A7 禧 (<CJK Ideograph>) 10057 0x79AA 禪 (<CJK Ideograph>) 10058 0x7A57 穗 (<CJK Ideograph>) 10059 0x7ABF 窿 (<CJK Ideograph>) 10060 0x7C07 簇 (<CJK Ideograph>) 10061 0x7C0D 簍 (<CJK Ideograph>) 10062 0x7BFE 篾 (<CJK Ideograph>) 10063 0x7BF7 篷 (<CJK Ideograph>) 10064 0x7C0C 簌 (<CJK Ideograph>) 10065 0x7BE0 篠 (<CJK Ideograph>) 10066 0x7CE0 糠 (<CJK Ideograph>) 10067 0x7CDC 糜 (<CJK Ideograph>) 10068 0x7CDE 糞 (<CJK Ideograph>) 10069 0x7CE2 糢 (<CJK Ideograph>) 10070 0x7CDF 糟 (<CJK Ideograph>) 10071 0x7CD9 糙 (<CJK Ideograph>) 10072 0x7CDD 糝 (<CJK Ideograph>) 10073 0x7E2E 縮 (<CJK Ideograph>) 10074 0x7E3E 績 (<CJK Ideograph>) 10075 0x7E46 繆 (<CJK Ideograph>) 10076 0x7E37 縷 (<CJK Ideograph>) 10077 0x7E32 縲 (<CJK Ideograph>) 10078 0x7E43 繃 (<CJK Ideograph>) 10079 0x7E2B 縫 (<CJK Ideograph>) 10080 0x7E3D 總 (<CJK Ideograph>) 10081 0x7E31 縱 (<CJK Ideograph>) 10082 0x7E45 繅 (<CJK Ideograph>) 10083 0x7E41 繁 (<CJK Ideograph>) 10084 0x7E34 縴 (<CJK Ideograph>) 10085 0x7E39 縹 (<CJK Ideograph>) 10086 0x7E48 繈 (<CJK Ideograph>) 10087 0x7E35 縵 (<CJK Ideograph>) 10088 0x7E3F 縿 (<CJK Ideograph>) 10089 0x7E2F 縯 (<CJK Ideograph>) 10090 0x7F44 罄 (<CJK Ideograph>) 10091 0x7FF3 翳 (<CJK Ideograph>) 10092 0x7FFC 翼 (<CJK Ideograph>) 10093 0x8071 聱 (<CJK Ideograph>) 10094 0x8072 聲 (<CJK Ideograph>) 10095 0x8070 聰 (<CJK Ideograph>) 10096 0x806F 聯 (<CJK Ideograph>) 10097 0x8073 聳 (<CJK Ideograph>) 10098 0x81C6 臆 (<CJK Ideograph>) 10099 0x81C3 臃 (<CJK Ideograph>) 10100 0x81BA 膺 (<CJK Ideograph>) 10101 0x81C2 臂 (<CJK Ideograph>) 10102 0x81C0 臀 (<CJK Ideograph>) 10103 0x81BF 膿 (<CJK Ideograph>) 10104 0x81BD 膽 (<CJK Ideograph>) 10105 0x81C9 臉 (<CJK Ideograph>) 10106 0x81BE 膾 (<CJK Ideograph>) 10107 0x81E8 臨 (<CJK Ideograph>) 10108 0x8209 舉 (<CJK Ideograph>) 10109 0x8271 艱 (<CJK Ideograph>) 10110 0x85AA 薪 (<CJK Ideograph>) 10111 0x8584 薄 (<CJK Ideograph>) 10112 0x857E 蕾 (<CJK Ideograph>) 10113 0x859C 薜 (<CJK Ideograph>) 10114 0x8591 薑 (<CJK Ideograph>) 10115 0x8594 薔 (<CJK Ideograph>) 10116 0x85AF 薯 (<CJK Ideograph>) 10117 0x859B 薛 (<CJK Ideograph>) 10118 0x8587 薇 (<CJK Ideograph>) 10119 0x85A8 薨 (<CJK Ideograph>) 10120 0x858A 薊 (<CJK Ideograph>) 10121 0x8667 虧 (<CJK Ideograph>) 10122 0x87C0 蟀 (<CJK Ideograph>) 10123 0x87D1 蟑 (<CJK Ideograph>) 10124 0x87B3 螳 (<CJK Ideograph>) 10125 0x87D2 蟒 (<CJK Ideograph>) 10126 0x87C6 蟆 (<CJK Ideograph>) 10127 0x87AB 螫 (<CJK Ideograph>) 10128 0x87BB 螻 (<CJK Ideograph>) 10129 0x87BA 螺 (<CJK Ideograph>) 10130 0x87C8 蟈 (<CJK Ideograph>) 10131 0x87CB 蟋 (<CJK Ideograph>) 10132 0x893B 褻 (<CJK Ideograph>) 10133 0x8936 褶 (<CJK Ideograph>) 10134 0x8944 襄 (<CJK Ideograph>) 10135 0x8938 褸 (<CJK Ideograph>) 10136 0x893D 褽 (<CJK Ideograph>) 10137 0x89AC 覬 (<CJK Ideograph>) 10138 0x8B0E 謎 (<CJK Ideograph>) 10139 0x8B17 謗 (<CJK Ideograph>) 10140 0x8B19 謙 (<CJK Ideograph>) 10141 0x8B1B 講 (<CJK Ideograph>) 10142 0x8B0A 謊 (<CJK Ideograph>) 10143 0x8B20 謠 (<CJK Ideograph>) 10144 0x8B1D 謝 (<CJK Ideograph>) 10145 0x8B04 謄 (<CJK Ideograph>) 10146 0x8B10 謐 (<CJK Ideograph>) 10147 0x8C41 豁 (<CJK Ideograph>) 10148 0x8C3F 谿 (<CJK Ideograph>) 10149 0x8C73 豳 (<CJK Ideograph>) 10150 0x8CFA 賺 (<CJK Ideograph>) 10151 0x8CFD 賽 (<CJK Ideograph>) 10152 0x8CFC 購 (<CJK Ideograph>) 10153 0x8CF8 賸 (<CJK Ideograph>) 10154 0x8CFB 賻 (<CJK Ideograph>) 10155 0x8DA8 趨 (<CJK Ideograph>) 10156 0x8E49 蹉 (<CJK Ideograph>) 10157 0x8E4B 蹋 (<CJK Ideograph>) 10158 0x8E48 蹈 (<CJK Ideograph>) 10159 0x8E4A 蹊 (<CJK Ideograph>) 10160 0x8F44 轄 (<CJK Ideograph>) 10161 0x8F3E 輾 (<CJK Ideograph>) 10162 0x8F42 轂 (<CJK Ideograph>) 10163 0x8F45 轅 (<CJK Ideograph>) 10164 0x8F3F 輿 (<CJK Ideograph>) 10165 0x907F 避 (<CJK Ideograph>) 10166 0x907D 遽 (<CJK Ideograph>) 10167 0x9084 還 (<CJK Ideograph>) 10168 0x9081 邁 (<CJK Ideograph>) 10169 0x9082 邂 (<CJK Ideograph>) 10170 0x9080 邀 (<CJK Ideograph>) 10171 0x9139 鄹 (<CJK Ideograph>) 10172 0x91A3 醣 (<CJK Ideograph>) 10173 0x919E 醞 (<CJK Ideograph>) 10174 0x919C 醜 (<CJK Ideograph>) 10175 0x934D 鍍 (<CJK Ideograph>) 10176 0x9382 鎂 (<CJK Ideograph>) 10177 0x9328 錨 (<CJK Ideograph>) 10178 0x9375 鍵 (<CJK Ideograph>) 10179 0x934A 鍊 (<CJK Ideograph>) 10180 0x9365 鍥 (<CJK Ideograph>) 10181 0x934B 鍋 (<CJK Ideograph>) 10182 0x9318 錘 (<CJK Ideograph>) 10183 0x937E 鍾 (<CJK Ideograph>) 10184 0x936C 鍬 (<CJK Ideograph>) 10185 0x935B 鍛 (<CJK Ideograph>) 10186 0x9370 鍰 (<CJK Ideograph>) 10187 0x935A 鍚 (<CJK Ideograph>) 10188 0x9354 鍔 (<CJK Ideograph>) 10189 0x95CA 闊 (<CJK Ideograph>) 10190 0x95CB 闋 (<CJK Ideograph>) 10191 0x95CC 闌 (<CJK Ideograph>) 10192 0x95C8 闈 (<CJK Ideograph>) 10193 0x95C6 闆 (<CJK Ideograph>) 10194 0x96B1 隱 (<CJK Ideograph>) 10195 0x96B8 隸 (<CJK Ideograph>) 10196 0x96D6 雖 (<CJK Ideograph>) 10197 0x971C 霜 (<CJK Ideograph>) 10198 0x971E 霞 (<CJK Ideograph>) 10199 0x97A0 鞠 (<CJK Ideograph>) 10200 0x97D3 韓 (<CJK Ideograph>) 10201 0x9846 顆 (<CJK Ideograph>) 10202 0x98B6 颶 (<CJK Ideograph>) 10203 0x9935 餵 (<CJK Ideograph>) 10204 0x9A01 騁 (<CJK Ideograph>) 10205 0x99FF 駿 (<CJK Ideograph>) 10206 0x9BAE 鮮 (<CJK Ideograph>) 10207 0x9BAB 鮫 (<CJK Ideograph>) 10208 0x9BAA 鮪 (<CJK Ideograph>) 10209 0x9BAD 鮭 (<CJK Ideograph>) 10210 0x9D3B 鴻 (<CJK Ideograph>) 10211 0x9D3F 鴿 (<CJK Ideograph>) 10212 0x9E8B 麋 (<CJK Ideograph>) 10213 0x9ECF 黏 (<CJK Ideograph>) 10214 0x9EDE 點 (<CJK Ideograph>) 10215 0x9EDC 黜 (<CJK Ideograph>) 10216 0x9EDD 黝 (<CJK Ideograph>) 10217 0x9EDB 黛 (<CJK Ideograph>) 10218 0x9F3E 鼾 (<CJK Ideograph>) 10219 0x9F4B 齋 (<CJK Ideograph>) 10220 0x53E2 叢 (<CJK Ideograph>) 10221 0x5695 嚕 (<CJK Ideograph>) 10222 0x56AE 嚮 (<CJK Ideograph>) 10223 0x58D9 壙 (<CJK Ideograph>) 10224 0x58D8 壘 (<CJK Ideograph>) 10225 0x5B38 嬸 (<CJK Ideograph>) 10226 0x5F5D 彝 (<CJK Ideograph>) 10227 0x61E3 懣 (<CJK Ideograph>) 10228 0x6233 戳 (<CJK Ideograph>) 10229 0x64F4 擴 (<CJK Ideograph>) 10230 0x64F2 擲 (<CJK Ideograph>) 10231 0x64FE 擾 (<CJK Ideograph>) 10232 0x6506 攆 (<CJK Ideograph>) 10233 0x64FA 擺 (<CJK Ideograph>) 10234 0x64FB 擻 (<CJK Ideograph>) 10235 0x64F7 擷 (<CJK Ideograph>) 10236 0x65B7 斷 (<CJK Ideograph>) 10237 0x66DC 曜 (<CJK Ideograph>) 10238 0x6726 朦 (<CJK Ideograph>) 10239 0x6AB3 檳 (<CJK Ideograph>) 10240 0x6AAC 檬 (<CJK Ideograph>) 10241 0x6AC3 櫃 (<CJK Ideograph>) 10242 0x6ABB 檻 (<CJK Ideograph>) 10243 0x6AB8 檸 (<CJK Ideograph>) 10244 0x6AC2 櫂 (<CJK Ideograph>) 10245 0x6AAE 檮 (<CJK Ideograph>) 10246 0x6AAF 檯 (<CJK Ideograph>) 10247 0x6B5F 歟 (<CJK Ideograph>) 10248 0x6B78 歸 (<CJK Ideograph>) 10249 0x6BAF 殯 (<CJK Ideograph>) 10250 0x7009 瀉 (<CJK Ideograph>) 10251 0x700B 瀋 (<CJK Ideograph>) 10252 0x6FFE 濾 (<CJK Ideograph>) 10253 0x7006 瀆 (<CJK Ideograph>) 10254 0x6FFA 濺 (<CJK Ideograph>) 10255 0x7011 瀑 (<CJK Ideograph>) 10256 0x700F 瀏 (<CJK Ideograph>) 10257 0x71FB 燻 (<CJK Ideograph>) 10258 0x71FC 燼 (<CJK Ideograph>) 10259 0x71FE 燾 (<CJK Ideograph>) 10260 0x71F8 燸 (<CJK Ideograph>) 10261 0x7377 獷 (<CJK Ideograph>) 10262 0x7375 獵 (<CJK Ideograph>) 10263 0x74A7 璧 (<CJK Ideograph>) 10264 0x74BF 璿 (<CJK Ideograph>) 10265 0x7515 甕 (<CJK Ideograph>) 10266 0x7656 癖 (<CJK Ideograph>) 10267 0x7658 癘 (<CJK Ideograph>) 10268 0x7652 癒 (<CJK Ideograph>) 10269 0x77BD 瞽 (<CJK Ideograph>) 10270 0x77BF 瞿 (<CJK Ideograph>) 10271 0x77BB 瞻 (<CJK Ideograph>) 10272 0x77BC 瞼 (<CJK Ideograph>) 10273 0x790E 礎 (<CJK Ideograph>) 10274 0x79AE 禮 (<CJK Ideograph>) 10275 0x7A61 穡 (<CJK Ideograph>) 10276 0x7A62 穢 (<CJK Ideograph>) 10277 0x7A60 穠 (<CJK Ideograph>) 10278 0x7AC4 竄 (<CJK Ideograph>) 10279 0x7AC5 竅 (<CJK Ideograph>) 10280 0x7C2B 簫 (<CJK Ideograph>) 10281 0x7C27 簧 (<CJK Ideograph>) 10282 0x7C2A 簪 (<CJK Ideograph>) 10283 0x7C1E 簞 (<CJK Ideograph>) 10284 0x7C23 簣 (<CJK Ideograph>) 10285 0x7C21 簡 (<CJK Ideograph>) 10286 0x7CE7 糧 (<CJK Ideograph>) 10287 0x7E54 織 (<CJK Ideograph>) 10288 0x7E55 繕 (<CJK Ideograph>) 10289 0x7E5E 繞 (<CJK Ideograph>) 10290 0x7E5A 繚 (<CJK Ideograph>) 10291 0x7E61 繡 (<CJK Ideograph>) 10292 0x7E52 繒 (<CJK Ideograph>) 10293 0x7E59 繙 (<CJK Ideograph>) 10294 0x7F48 罈 (<CJK Ideograph>) 10295 0x7FF9 翹 (<CJK Ideograph>) 10296 0x7FFB 翻 (<CJK Ideograph>) 10297 0x8077 職 (<CJK Ideograph>) 10298 0x8076 聶 (<CJK Ideograph>) 10299 0x81CD 臍 (<CJK Ideograph>) 10300 0x81CF 臏 (<CJK Ideograph>) 10301 0x820A 舊 (<CJK Ideograph>) 10302 0x85CF 藏 (<CJK Ideograph>) 10303 0x85A9 薩 (<CJK Ideograph>) 10304 0x85CD 藍 (<CJK Ideograph>) 10305 0x85D0 藐 (<CJK Ideograph>) 10306 0x85C9 藉 (<CJK Ideograph>) 10307 0x85B0 薰 (<CJK Ideograph>) 10308 0x85BA 薺 (<CJK Ideograph>) 10309 0x85B9 薹 (<CJK Ideograph>) 10310 0x85A6 薦 (<CJK Ideograph>) 10311 0x87EF 蟯 (<CJK Ideograph>) 10312 0x87EC 蟬 (<CJK Ideograph>) 10313 0x87F2 蟲 (<CJK Ideograph>) 10314 0x87E0 蟠 (<CJK Ideograph>) 10315 0x8986 覆 (<CJK Ideograph>) 10316 0x89B2 覲 (<CJK Ideograph>) 10317 0x89F4 觴 (<CJK Ideograph>) 10318 0x8B28 謨 (<CJK Ideograph>) 10319 0x8B39 謹 (<CJK Ideograph>) 10320 0x8B2C 謬 (<CJK Ideograph>) 10321 0x8B2B 謫 (<CJK Ideograph>) 10322 0x8C50 豐 (<CJK Ideograph>) 10323 0x8D05 贅 (<CJK Ideograph>) 10324 0x8E59 蹙 (<CJK Ideograph>) 10325 0x8E63 蹣 (<CJK Ideograph>) 10326 0x8E66 蹦 (<CJK Ideograph>) 10327 0x8E64 蹤 (<CJK Ideograph>) 10328 0x8E5F 蹟 (<CJK Ideograph>) 10329 0x8E55 蹕 (<CJK Ideograph>) 10330 0x8EC0 軀 (<CJK Ideograph>) 10331 0x8F49 轉 (<CJK Ideograph>) 10332 0x8F4D 轍 (<CJK Ideograph>) 10333 0x9087 邇 (<CJK Ideograph>) 10334 0x9083 邃 (<CJK Ideograph>) 10335 0x9088 邈 (<CJK Ideograph>) 10336 0x91AB 醫 (<CJK Ideograph>) 10337 0x91AC 醬 (<CJK Ideograph>) 10338 0x91D0 釐 (<CJK Ideograph>) 10339 0x9394 鎔 (<CJK Ideograph>) 10340 0x938A 鎊 (<CJK Ideograph>) 10341 0x9396 鎖 (<CJK Ideograph>) 10342 0x93A2 鎢 (<CJK Ideograph>) 10343 0x93B3 鎳 (<CJK Ideograph>) 10344 0x93AE 鎮 (<CJK Ideograph>) 10345 0x93AC 鎬 (<CJK Ideograph>) 10346 0x93B0 鎰 (<CJK Ideograph>) 10347 0x9398 鎘 (<CJK Ideograph>) 10348 0x939A 鎚 (<CJK Ideograph>) 10349 0x9397 鎗 (<CJK Ideograph>) 10350 0x95D4 闔 (<CJK Ideograph>) 10351 0x95D6 闖 (<CJK Ideograph>) 10352 0x95D0 闐 (<CJK Ideograph>) 10353 0x95D5 闕 (<CJK Ideograph>) 10354 0x96E2 離 (<CJK Ideograph>) 10355 0x96DC 雜 (<CJK Ideograph>) 10356 0x96D9 雙 (<CJK Ideograph>) 10357 0x96DB 雛 (<CJK Ideograph>) 10358 0x96DE 雞 (<CJK Ideograph>) 10359 0x9724 霤 (<CJK Ideograph>) 10360 0x97A3 鞣 (<CJK Ideograph>) 10361 0x97A6 鞦 (<CJK Ideograph>) 10362 0x97AD 鞭 (<CJK Ideograph>) 10363 0x97F9 韹 (<CJK Ideograph>) 10364 0x984D 額 (<CJK Ideograph>) 10365 0x984F 顏 (<CJK Ideograph>) 10366 0x984C 題 (<CJK Ideograph>) 10367 0x984E 顎 (<CJK Ideograph>) 10368 0x9853 顓 (<CJK Ideograph>) 10369 0x98BA 颺 (<CJK Ideograph>) 10370 0x993E 餾 (<CJK Ideograph>) 10371 0x993F 餿 (<CJK Ideograph>) 10372 0x993D 餽 (<CJK Ideograph>) 10373 0x992E 餮 (<CJK Ideograph>) 10374 0x99A5 馥 (<CJK Ideograph>) 10375 0x9A0E 騎 (<CJK Ideograph>) 10376 0x9AC1 髁 (<CJK Ideograph>) 10377 0x9B03 鬃 (<CJK Ideograph>) 10378 0x9B06 鬆 (<CJK Ideograph>) 10379 0x9B4F 魏 (<CJK Ideograph>) 10380 0x9B4E 魎 (<CJK Ideograph>) 10381 0x9B4D 魍 (<CJK Ideograph>) 10382 0x9BCA 鯊 (<CJK Ideograph>) 10383 0x9BC9 鯉 (<CJK Ideograph>) 10384 0x9BFD 鯽 (<CJK Ideograph>) 10385 0x9BC8 鯈 (<CJK Ideograph>) 10386 0x9BC0 鯀 (<CJK Ideograph>) 10387 0x9D51 鵑 (<CJK Ideograph>) 10388 0x9D5D 鵝 (<CJK Ideograph>) 10389 0x9D60 鵠 (<CJK Ideograph>) 10390 0x9EE0 黠 (<CJK Ideograph>) 10391 0x9F15 鼕 (<CJK Ideograph>) 10392 0x9F2C 鼬 (<CJK Ideograph>) 10393 0x5133 儳 (<CJK Ideograph>) 10394 0x56A5 嚥 (<CJK Ideograph>) 10395 0x58DE 壞 (<CJK Ideograph>) 10396 0x58DF 壟 (<CJK Ideograph>) 10397 0x58E2 壢 (<CJK Ideograph>) 10398 0x5BF5 寵 (<CJK Ideograph>) 10399 0x9F90 龐 (<CJK Ideograph>) 10400 0x5EEC 廬 (<CJK Ideograph>) 10401 0x61F2 懲 (<CJK Ideograph>) 10402 0x61F7 懷 (<CJK Ideograph>) 10403 0x61F6 懶 (<CJK Ideograph>) 10404 0x61F5 懵 (<CJK Ideograph>) 10405 0x6500 攀 (<CJK Ideograph>) 10406 0x650F 攏 (<CJK Ideograph>) 10407 0x66E0 曠 (<CJK Ideograph>) 10408 0x66DD 曝 (<CJK Ideograph>) 10409 0x6AE5 櫥 (<CJK Ideograph>) 10410 0x6ADD 櫝 (<CJK Ideograph>) 10411 0x6ADA 櫚 (<CJK Ideograph>) 10412 0x6AD3 櫓 (<CJK Ideograph>) 10413 0x701B 瀛 (<CJK Ideograph>) 10414 0x701F 瀟 (<CJK Ideograph>) 10415 0x7028 瀨 (<CJK Ideograph>) 10416 0x701A 瀚 (<CJK Ideograph>) 10417 0x701D 瀝 (<CJK Ideograph>) 10418 0x7015 瀕 (<CJK Ideograph>) 10419 0x7018 瀘 (<CJK Ideograph>) 10420 0x7206 爆 (<CJK Ideograph>) 10421 0x720D 爍 (<CJK Ideograph>) 10422 0x7258 牘 (<CJK Ideograph>) 10423 0x72A2 犢 (<CJK Ideograph>) 10424 0x7378 獸 (<CJK Ideograph>) 10425 0x737A 獺 (<CJK Ideograph>) 10426 0x74BD 璽 (<CJK Ideograph>) 10427 0x74CA 瓊 (<CJK Ideograph>) 10428 0x74E3 瓣 (<CJK Ideograph>) 10429 0x7587 疇 (<CJK Ideograph>) 10430 0x7586 疆 (<CJK Ideograph>) 10431 0x765F 癟 (<CJK Ideograph>) 10432 0x7661 癡 (<CJK Ideograph>) 10433 0x77C7 矇 (<CJK Ideograph>) 10434 0x7919 礙 (<CJK Ideograph>) 10435 0x79B1 禱 (<CJK Ideograph>) 10436 0x7A6B 穫 (<CJK Ideograph>) 10437 0x7A69 穩 (<CJK Ideograph>) 10438 0x7C3E 簾 (<CJK Ideograph>) 10439 0x7C3F 簿 (<CJK Ideograph>) 10440 0x7C38 簸 (<CJK Ideograph>) 10441 0x7C3D 簽 (<CJK Ideograph>) 10442 0x7C37 簷 (<CJK Ideograph>) 10443 0x7C40 籀 (<CJK Ideograph>) 10444 0x7E6B 繫 (<CJK Ideograph>) 10445 0x7E6D 繭 (<CJK Ideograph>) 10446 0x7E79 繹 (<CJK Ideograph>) 10447 0x7E69 繩 (<CJK Ideograph>) 10448 0x7E6A 繪 (<CJK Ideograph>) 10449 0x7F85 羅 (<CJK Ideograph>) 10450 0x7E73 繳 (<CJK Ideograph>) 10451 0x7FB6 羶 (<CJK Ideograph>) 10452 0x7FB9 羹 (<CJK Ideograph>) 10453 0x7FB8 羸 (<CJK Ideograph>) 10454 0x81D8 臘 (<CJK Ideograph>) 10455 0x85E9 藩 (<CJK Ideograph>) 10456 0x85DD 藝 (<CJK Ideograph>) 10457 0x85EA 藪 (<CJK Ideograph>) 10458 0x85D5 藕 (<CJK Ideograph>) 10459 0x85E4 藤 (<CJK Ideograph>) 10460 0x85E5 藥 (<CJK Ideograph>) 10461 0x85F7 藷 (<CJK Ideograph>) 10462 0x87FB 蟻 (<CJK Ideograph>) 10463 0x8805 蠅 (<CJK Ideograph>) 10464 0x880D 蠍 (<CJK Ideograph>) 10465 0x87F9 蟹 (<CJK Ideograph>) 10466 0x87FE 蟾 (<CJK Ideograph>) 10467 0x8960 襠 (<CJK Ideograph>) 10468 0x895F 襟 (<CJK Ideograph>) 10469 0x8956 襖 (<CJK Ideograph>) 10470 0x895E 襞 (<CJK Ideograph>) 10471 0x8B41 譁 (<CJK Ideograph>) 10472 0x8B5C 譜 (<CJK Ideograph>) 10473 0x8B58 識 (<CJK Ideograph>) 10474 0x8B49 證 (<CJK Ideograph>) 10475 0x8B5A 譚 (<CJK Ideograph>) 10476 0x8B4E 譎 (<CJK Ideograph>) 10477 0x8B4F 譏 (<CJK Ideograph>) 10478 0x8B46 譆 (<CJK Ideograph>) 10479 0x8B59 譙 (<CJK Ideograph>) 10480 0x8D08 贈 (<CJK Ideograph>) 10481 0x8D0A 贊 (<CJK Ideograph>) 10482 0x8E7C 蹼 (<CJK Ideograph>) 10483 0x8E72 蹲 (<CJK Ideograph>) 10484 0x8E87 躇 (<CJK Ideograph>) 10485 0x8E76 蹶 (<CJK Ideograph>) 10486 0x8E6C 蹬 (<CJK Ideograph>) 10487 0x8E7A 蹺 (<CJK Ideograph>) 10488 0x8E74 蹴 (<CJK Ideograph>) 10489 0x8F54 轔 (<CJK Ideograph>) 10490 0x8F4E 轎 (<CJK Ideograph>) 10491 0x8FAD 辭 (<CJK Ideograph>) 10492 0x908A 邊 (<CJK Ideograph>) 10493 0x908B 邋 (<CJK Ideograph>) 10494 0x91B1 醱 (<CJK Ideograph>) 10495 0x91AE 醮 (<CJK Ideograph>) 10496 0x93E1 鏡 (<CJK Ideograph>) 10497 0x93D1 鏑 (<CJK Ideograph>) 10498 0x93DF 鏟 (<CJK Ideograph>) 10499 0x93C3 鏃 (<CJK Ideograph>) 10500 0x93C8 鏈 (<CJK Ideograph>) 10501 0x93DC 鏜 (<CJK Ideograph>) 10502 0x93DD 鏝 (<CJK Ideograph>) 10503 0x93D6 鏖 (<CJK Ideograph>) 10504 0x93E2 鏢 (<CJK Ideograph>) 10505 0x93CD 鏍 (<CJK Ideograph>) 10506 0x93D8 鏘 (<CJK Ideograph>) 10507 0x93E4 鏤 (<CJK Ideograph>) 10508 0x93D7 鏗 (<CJK Ideograph>) 10509 0x93E8 鏨 (<CJK Ideograph>) 10510 0x95DC 關 (<CJK Ideograph>) 10511 0x96B4 隴 (<CJK Ideograph>) 10512 0x96E3 難 (<CJK Ideograph>) 10513 0x972A 霪 (<CJK Ideograph>) 10514 0x9727 霧 (<CJK Ideograph>) 10515 0x9761 靡 (<CJK Ideograph>) 10516 0x97DC 韜 (<CJK Ideograph>) 10517 0x97FB 韻 (<CJK Ideograph>) 10518 0x985E 類 (<CJK Ideograph>) 10519 0x9858 願 (<CJK Ideograph>) 10520 0x985B 顛 (<CJK Ideograph>) 10521 0x98BC 颼 (<CJK Ideograph>) 10522 0x9945 饅 (<CJK Ideograph>) 10523 0x9949 饉 (<CJK Ideograph>) 10524 0x9A16 騖 (<CJK Ideograph>) 10525 0x9A19 騙 (<CJK Ideograph>) 10526 0x9B0D 鬍 (<CJK Ideograph>) 10527 0x9BE8 鯨 (<CJK Ideograph>) 10528 0x9BE7 鯧 (<CJK Ideograph>) 10529 0x9BD6 鯖 (<CJK Ideograph>) 10530 0x9BDB 鯛 (<CJK Ideograph>) 10531 0x9D89 鶉 (<CJK Ideograph>) 10532 0x9D61 鵡 (<CJK Ideograph>) 10533 0x9D72 鵲 (<CJK Ideograph>) 10534 0x9D6A 鵪 (<CJK Ideograph>) 10535 0x9D6C 鵬 (<CJK Ideograph>) 10536 0x9E92 麒 (<CJK Ideograph>) 10537 0x9E97 麗 (<CJK Ideograph>) 10538 0x9E93 麓 (<CJK Ideograph>) 10539 0x9EB4 麴 (<CJK Ideograph>) 10540 0x52F8 勸 (<CJK Ideograph>) 10541 0x56A8 嚨 (<CJK Ideograph>) 10542 0x56B7 嚷 (<CJK Ideograph>) 10543 0x56B6 嚶 (<CJK Ideograph>) 10544 0x56B4 嚴 (<CJK Ideograph>) 10545 0x56BC 嚼 (<CJK Ideograph>) 10546 0x58E4 壤 (<CJK Ideograph>) 10547 0x5B40 孀 (<CJK Ideograph>) 10548 0x5B43 孃 (<CJK Ideograph>) 10549 0x5B7D 孽 (<CJK Ideograph>) 10550 0x5BF6 寶 (<CJK Ideograph>) 10551 0x5DC9 巉 (<CJK Ideograph>) 10552 0x61F8 懸 (<CJK Ideograph>) 10553 0x61FA 懺 (<CJK Ideograph>) 10554 0x6518 攘 (<CJK Ideograph>) 10555 0x6514 攔 (<CJK Ideograph>) 10556 0x6519 攙 (<CJK Ideograph>) 10557 0x66E6 曦 (<CJK Ideograph>) 10558 0x6727 朧 (<CJK Ideograph>) 10559 0x6AEC 櫬 (<CJK Ideograph>) 10560 0x703E 瀾 (<CJK Ideograph>) 10561 0x7030 瀰 (<CJK Ideograph>) 10562 0x7032 瀲 (<CJK Ideograph>) 10563 0x7210 爐 (<CJK Ideograph>) 10564 0x737B 獻 (<CJK Ideograph>) 10565 0x74CF 瓏 (<CJK Ideograph>) 10566 0x7662 癢 (<CJK Ideograph>) 10567 0x7665 癥 (<CJK Ideograph>) 10568 0x7926 礦 (<CJK Ideograph>) 10569 0x792A 礪 (<CJK Ideograph>) 10570 0x792C 礬 (<CJK Ideograph>) 10571 0x792B 礫 (<CJK Ideograph>) 10572 0x7AC7 竇 (<CJK Ideograph>) 10573 0x7AF6 競 (<CJK Ideograph>) 10574 0x7C4C 籌 (<CJK Ideograph>) 10575 0x7C43 籃 (<CJK Ideograph>) 10576 0x7C4D 籍 (<CJK Ideograph>) 10577 0x7CEF 糯 (<CJK Ideograph>) 10578 0x7CF0 糰 (<CJK Ideograph>) 10579 0x8FAE 辮 (<CJK Ideograph>) 10580 0x7E7D 繽 (<CJK Ideograph>) 10581 0x7E7C 繼 (<CJK Ideograph>) 10582 0x7E82 纂 (<CJK Ideograph>) 10583 0x7F4C 罌 (<CJK Ideograph>) 10584 0x8000 耀 (<CJK Ideograph>) 10585 0x81DA 臚 (<CJK Ideograph>) 10586 0x8266 艦 (<CJK Ideograph>) 10587 0x85FB 藻 (<CJK Ideograph>) 10588 0x85F9 藹 (<CJK Ideograph>) 10589 0x8611 蘑 (<CJK Ideograph>) 10590 0x85FA 藺 (<CJK Ideograph>) 10591 0x8606 蘆 (<CJK Ideograph>) 10592 0x860B 蘋 (<CJK Ideograph>) 10593 0x8607 蘇 (<CJK Ideograph>) 10594 0x860A 蘊 (<CJK Ideograph>) 10595 0x8814 蠔 (<CJK Ideograph>) 10596 0x8815 蠕 (<CJK Ideograph>) 10597 0x8964 襤 (<CJK Ideograph>) 10598 0x89BA 覺 (<CJK Ideograph>) 10599 0x89F8 觸 (<CJK Ideograph>) 10600 0x8B70 議 (<CJK Ideograph>) 10601 0x8B6C 譬 (<CJK Ideograph>) 10602 0x8B66 警 (<CJK Ideograph>) 10603 0x8B6F 譯 (<CJK Ideograph>) 10604 0x8B5F 譟 (<CJK Ideograph>) 10605 0x8B6B 譫 (<CJK Ideograph>) 10606 0x8D0F 贏 (<CJK Ideograph>) 10607 0x8D0D 贍 (<CJK Ideograph>) 10608 0x8E89 躉 (<CJK Ideograph>) 10609 0x8E81 躁 (<CJK Ideograph>) 10610 0x8E85 躅 (<CJK Ideograph>) 10611 0x8E82 躂 (<CJK Ideograph>) 10612 0x91B4 醴 (<CJK Ideograph>) 10613 0x91CB 釋 (<CJK Ideograph>) 10614 0x9418 鐘 (<CJK Ideograph>) 10615 0x9403 鐃 (<CJK Ideograph>) 10616 0x93FD 鏽 (<CJK Ideograph>) 10617 0x95E1 闡 (<CJK Ideograph>) 10618 0x9730 霰 (<CJK Ideograph>) 10619 0x98C4 飄 (<CJK Ideograph>) 10620 0x9952 饒 (<CJK Ideograph>) 10621 0x9951 饑 (<CJK Ideograph>) 10622 0x99A8 馨 (<CJK Ideograph>) 10623 0x9A2B 騫 (<CJK Ideograph>) 10624 0x9A30 騰 (<CJK Ideograph>) 10625 0x9A37 騷 (<CJK Ideograph>) 10626 0x9A35 騵 (<CJK Ideograph>) 10627 0x9C13 鰓 (<CJK Ideograph>) 10628 0x9C0D 鰍 (<CJK Ideograph>) 10629 0x9E79 鹹 (<CJK Ideograph>) 10630 0x9EB5 麵 (<CJK Ideograph>) 10631 0x9EE8 黨 (<CJK Ideograph>) 10632 0x9F2F 鼯 (<CJK Ideograph>) 10633 0x9F5F 齟 (<CJK Ideograph>) 10634 0x9F63 齣 (<CJK Ideograph>) 10635 0x9F61 齡 (<CJK Ideograph>) 10636 0x5137 儷 (<CJK Ideograph>) 10637 0x5138 儸 (<CJK Ideograph>) 10638 0x56C1 囁 (<CJK Ideograph>) 10639 0x56C0 囀 (<CJK Ideograph>) 10640 0x56C2 囂 (<CJK Ideograph>) 10641 0x5914 夔 (<CJK Ideograph>) 10642 0x5C6C 屬 (<CJK Ideograph>) 10643 0x5DCD 巍 (<CJK Ideograph>) 10644 0x61FC 懼 (<CJK Ideograph>) 10645 0x61FE 懾 (<CJK Ideograph>) 10646 0x651D 攝 (<CJK Ideograph>) 10647 0x651C 攜 (<CJK Ideograph>) 10648 0x6595 斕 (<CJK Ideograph>) 10649 0x66E9 曩 (<CJK Ideograph>) 10650 0x6AFB 櫻 (<CJK Ideograph>) 10651 0x6B04 欄 (<CJK Ideograph>) 10652 0x6AFA 櫺 (<CJK Ideograph>) 10653 0x6BB2 殲 (<CJK Ideograph>) 10654 0x704C 灌 (<CJK Ideograph>) 10655 0x721B 爛 (<CJK Ideograph>) 10656 0x72A7 犧 (<CJK Ideograph>) 10657 0x74D6 瓖 (<CJK Ideograph>) 10658 0x74D4 瓔 (<CJK Ideograph>) 10659 0x7669 癩 (<CJK Ideograph>) 10660 0x77D3 矓 (<CJK Ideograph>) 10661 0x7C50 籐 (<CJK Ideograph>) 10662 0x7E8F 纏 (<CJK Ideograph>) 10663 0x7E8C 續 (<CJK Ideograph>) 10664 0x7FBC 羼 (<CJK Ideograph>) 10665 0x8617 蘗 (<CJK Ideograph>) 10666 0x862D 蘭 (<CJK Ideograph>) 10667 0x861A 蘚 (<CJK Ideograph>) 10668 0x8823 蠣 (<CJK Ideograph>) 10669 0x8822 蠢 (<CJK Ideograph>) 10670 0x8821 蠡 (<CJK Ideograph>) 10671 0x881F 蠟 (<CJK Ideograph>) 10672 0x896A 襪 (<CJK Ideograph>) 10673 0x896C 襬 (<CJK Ideograph>) 10674 0x89BD 覽 (<CJK Ideograph>) 10675 0x8B74 譴 (<CJK Ideograph>) 10676 0x8B77 護 (<CJK Ideograph>) 10677 0x8B7D 譽 (<CJK Ideograph>) 10678 0x8D13 贓 (<CJK Ideograph>) 10679 0x8E8A 躊 (<CJK Ideograph>) 10680 0x8E8D 躍 (<CJK Ideograph>) 10681 0x8E8B 躋 (<CJK Ideograph>) 10682 0x8F5F 轟 (<CJK Ideograph>) 10683 0x8FAF 辯 (<CJK Ideograph>) 10684 0x91BA 醺 (<CJK Ideograph>) 10685 0x942E 鐮 (<CJK Ideograph>) 10686 0x9433 鐳 (<CJK Ideograph>) 10687 0x9435 鐵 (<CJK Ideograph>) 10688 0x943A 鐺 (<CJK Ideograph>) 10689 0x9438 鐸 (<CJK Ideograph>) 10690 0x9432 鐲 (<CJK Ideograph>) 10691 0x942B 鐫 (<CJK Ideograph>) 10692 0x95E2 闢 (<CJK Ideograph>) 10693 0x9738 霸 (<CJK Ideograph>) 10694 0x9739 霹 (<CJK Ideograph>) 10695 0x9732 露 (<CJK Ideograph>) 10696 0x97FF 響 (<CJK Ideograph>) 10697 0x9867 顧 (<CJK Ideograph>) 10698 0x9865 顥 (<CJK Ideograph>) 10699 0x9957 饗 (<CJK Ideograph>) 10700 0x9A45 驅 (<CJK Ideograph>) 10701 0x9A43 驃 (<CJK Ideograph>) 10702 0x9A40 驀 (<CJK Ideograph>) 10703 0x9A3E 騾 (<CJK Ideograph>) 10704 0x9ACF 髏 (<CJK Ideograph>) 10705 0x9B54 魔 (<CJK Ideograph>) 10706 0x9B51 魑 (<CJK Ideograph>) 10707 0x9C2D 鰭 (<CJK Ideograph>) 10708 0x9C25 鰥 (<CJK Ideograph>) 10709 0x9DAF 鶯 (<CJK Ideograph>) 10710 0x9DB4 鶴 (<CJK Ideograph>) 10711 0x9DC2 鷂 (<CJK Ideograph>) 10712 0x9DB8 鶸 (<CJK Ideograph>) 10713 0x9E9D 麝 (<CJK Ideograph>) 10714 0x9EEF 黯 (<CJK Ideograph>) 10715 0x9F19 鼙 (<CJK Ideograph>) 10716 0x9F5C 齜 (<CJK Ideograph>) 10717 0x9F66 齦 (<CJK Ideograph>) 10718 0x9F67 齧 (<CJK Ideograph>) 10719 0x513C 儼 (<CJK Ideograph>) 10720 0x513B 儻 (<CJK Ideograph>) 10721 0x56C8 囈 (<CJK Ideograph>) 10722 0x56CA 囊 (<CJK Ideograph>) 10723 0x56C9 囉 (<CJK Ideograph>) 10724 0x5B7F 孿 (<CJK Ideograph>) 10725 0x5DD4 巔 (<CJK Ideograph>) 10726 0x5DD2 巒 (<CJK Ideograph>) 10727 0x5F4E 彎 (<CJK Ideograph>) 10728 0x61FF 懿 (<CJK Ideograph>) 10729 0x6524 攤 (<CJK Ideograph>) 10730 0x6B0A 權 (<CJK Ideograph>) 10731 0x6B61 歡 (<CJK Ideograph>) 10732 0x7051 灑 (<CJK Ideograph>) 10733 0x7058 灘 (<CJK Ideograph>) 10734 0x7380 玀 (<CJK Ideograph>) 10735 0x74E4 瓤 (<CJK Ideograph>) 10736 0x758A 疊 (<CJK Ideograph>) 10737 0x766E 癮 (<CJK Ideograph>) 10738 0x766C 癬 (<CJK Ideograph>) 10739 0x79B3 禳 (<CJK Ideograph>) 10740 0x7C60 籠 (<CJK Ideograph>) 10741 0x7C5F 籟 (<CJK Ideograph>) 10742 0x807E 聾 (<CJK Ideograph>) 10743 0x807D 聽 (<CJK Ideograph>) 10744 0x81DF 臟 (<CJK Ideograph>) 10745 0x8972 襲 (<CJK Ideograph>) 10746 0x896F 襯 (<CJK Ideograph>) 10747 0x89FC 觼 (<CJK Ideograph>) 10748 0x8B80 讀 (<CJK Ideograph>) 10749 0x8D16 贖 (<CJK Ideograph>) 10750 0x8D17 贗 (<CJK Ideograph>) 10751 0x8E91 躑 (<CJK Ideograph>) 10752 0x8E93 躓 (<CJK Ideograph>) 10753 0x8F61 轡 (<CJK Ideograph>) 10754 0x9148 酈 (<CJK Ideograph>) 10755 0x9444 鑄 (<CJK Ideograph>) 10756 0x9451 鑑 (<CJK Ideograph>) 10757 0x9452 鑒 (<CJK Ideograph>) 10758 0x973D 霽 (<CJK Ideograph>) 10759 0x973E 霾 (<CJK Ideograph>) 10760 0x97C3 韃 (<CJK Ideograph>) 10761 0x97C1 韁 (<CJK Ideograph>) 10762 0x986B 顫 (<CJK Ideograph>) 10763 0x9955 饕 (<CJK Ideograph>) 10764 0x9A55 驕 (<CJK Ideograph>) 10765 0x9A4D 驍 (<CJK Ideograph>) 10766 0x9AD2 髒 (<CJK Ideograph>) 10767 0x9B1A 鬚 (<CJK Ideograph>) 10768 0x9C49 鱉 (<CJK Ideograph>) 10769 0x9C31 鰱 (<CJK Ideograph>) 10770 0x9C3E 鰾 (<CJK Ideograph>) 10771 0x9C3B 鰻 (<CJK Ideograph>) 10772 0x9DD3 鷓 (<CJK Ideograph>) 10773 0x9DD7 鷗 (<CJK Ideograph>) 10774 0x9F34 鼴 (<CJK Ideograph>) 10775 0x9F6C 齬 (<CJK Ideograph>) 10776 0x9F6A 齪 (<CJK Ideograph>) 10777 0x9F94 龔 (<CJK Ideograph>) 10778 0x56CC 囌 (<CJK Ideograph>) 10779 0x5DD6 巖 (<CJK Ideograph>) 10780 0x6200 戀 (<CJK Ideograph>) 10781 0x6523 攣 (<CJK Ideograph>) 10782 0x652B 攫 (<CJK Ideograph>) 10783 0x652A 攪 (<CJK Ideograph>) 10784 0x66EC 曬 (<CJK Ideograph>) 10785 0x6B10 欐 (<CJK Ideograph>) 10786 0x74DA 瓚 (<CJK Ideograph>) 10787 0x7ACA 竊 (<CJK Ideograph>) 10788 0x7C64 籤 (<CJK Ideograph>) 10789 0x7C63 籣 (<CJK Ideograph>) 10790 0x7C65 籥 (<CJK Ideograph>) 10791 0x7E93 纓 (<CJK Ideograph>) 10792 0x7E96 纖 (<CJK Ideograph>) 10793 0x7E94 纔 (<CJK Ideograph>) 10794 0x81E2 臢 (<CJK Ideograph>) 10795 0x8638 蘸 (<CJK Ideograph>) 10796 0x863F 蘿 (<CJK Ideograph>) 10797 0x8831 蠱 (<CJK Ideograph>) 10798 0x8B8A 變 (<CJK Ideograph>) 10799 0x9090 邐 (<CJK Ideograph>) 10800 0x908F 邏 (<CJK Ideograph>) 10801 0x9463 鑣 (<CJK Ideograph>) 10802 0x9460 鑠 (<CJK Ideograph>) 10803 0x9464 鑤 (<CJK Ideograph>) 10804 0x9768 靨 (<CJK Ideograph>) 10805 0x986F 顯 (<CJK Ideograph>) 10806 0x995C 饜 (<CJK Ideograph>) 10807 0x9A5A 驚 (<CJK Ideograph>) 10808 0x9A5B 驛 (<CJK Ideograph>) 10809 0x9A57 驗 (<CJK Ideograph>) 10810 0x9AD3 髓 (<CJK Ideograph>) 10811 0x9AD4 體 (<CJK Ideograph>) 10812 0x9AD1 髑 (<CJK Ideograph>) 10813 0x9C54 鱔 (<CJK Ideograph>) 10814 0x9C57 鱗 (<CJK Ideograph>) 10815 0x9C56 鱖 (<CJK Ideograph>) 10816 0x9DE5 鷥 (<CJK Ideograph>) 10817 0x9E9F 麟 (<CJK Ideograph>) 10818 0x9EF4 黴 (<CJK Ideograph>) 10819 0x56D1 囑 (<CJK Ideograph>) 10820 0x58E9 壩 (<CJK Ideograph>) 10821 0x652C 攬 (<CJK Ideograph>) 10822 0x705E 灞 (<CJK Ideograph>) 10823 0x7671 癱 (<CJK Ideograph>) 10824 0x7672 癲 (<CJK Ideograph>) 10825 0x77D7 矗 (<CJK Ideograph>) 10826 0x7F50 罐 (<CJK Ideograph>) 10827 0x7F88 羈 (<CJK Ideograph>) 10828 0x8836 蠶 (<CJK Ideograph>) 10829 0x8839 蠹 (<CJK Ideograph>) 10830 0x8862 衢 (<CJK Ideograph>) 10831 0x8B93 讓 (<CJK Ideograph>) 10832 0x8B92 讒 (<CJK Ideograph>) 10833 0x8B96 讖 (<CJK Ideograph>) 10834 0x8277 艷 (<CJK Ideograph>) 10835 0x8D1B 贛 (<CJK Ideograph>) 10836 0x91C0 釀 (<CJK Ideograph>) 10837 0x946A 鑪 (<CJK Ideograph>) 10838 0x9742 靂 (<CJK Ideograph>) 10839 0x9748 靈 (<CJK Ideograph>) 10840 0x9744 靄 (<CJK Ideograph>) 10841 0x97C6 韆 (<CJK Ideograph>) 10842 0x9870 顰 (<CJK Ideograph>) 10843 0x9A5F 驟 (<CJK Ideograph>) 10844 0x9B22 鬢 (<CJK Ideograph>) 10845 0x9B58 魘 (<CJK Ideograph>) 10846 0x9C5F 鱟 (<CJK Ideograph>) 10847 0x9DF9 鷹 (<CJK Ideograph>) 10848 0x9DFA 鷺 (<CJK Ideograph>) 10849 0x9E7C 鹼 (<CJK Ideograph>) 10850 0x9E7D 鹽 (<CJK Ideograph>) 10851 0x9F07 鼇 (<CJK Ideograph>) 10852 0x9F77 齷 (<CJK Ideograph>) 10853 0x9F72 齲 (<CJK Ideograph>) 10854 0x5EF3 廳 (<CJK Ideograph>) 10855 0x6B16 欖 (<CJK Ideograph>) 10856 0x7063 灣 (<CJK Ideograph>) 10857 0x7C6C 籬 (<CJK Ideograph>) 10858 0x7C6E 籮 (<CJK Ideograph>) 10859 0x883B 蠻 (<CJK Ideograph>) 10860 0x89C0 觀 (<CJK Ideograph>) 10861 0x8EA1 躡 (<CJK Ideograph>) 10862 0x91C1 釁 (<CJK Ideograph>) 10863 0x9472 鑲 (<CJK Ideograph>) 10864 0x9470 鑰 (<CJK Ideograph>) 10865 0x9871 顱 (<CJK Ideograph>) 10866 0x995E 饞 (<CJK Ideograph>) 10867 0x9AD6 髖 (<CJK Ideograph>) 10868 0x9B23 鬣 (<CJK Ideograph>) 10869 0x9ECC 黌 (<CJK Ideograph>) 10870 0x7064 灤 (<CJK Ideograph>) 10871 0x77DA 矚 (<CJK Ideograph>) 10872 0x8B9A 讚 (<CJK Ideograph>) 10873 0x9477 鑷 (<CJK Ideograph>) 10874 0x97C9 韉 (<CJK Ideograph>) 10875 0x9A62 驢 (<CJK Ideograph>) 10876 0x9A65 驥 (<CJK Ideograph>) 10877 0x7E9C 纜 (<CJK Ideograph>) 10878 0x8B9C 讜 (<CJK Ideograph>) 10879 0x8EAA 躪 (<CJK Ideograph>) 10880 0x91C5 釅 (<CJK Ideograph>) 10881 0x947D 鑽 (<CJK Ideograph>) 10882 0x947E 鑾 (<CJK Ideograph>) 10883 0x947C 鑼 (<CJK Ideograph>) 10884 0x9C77 鱷 (<CJK Ideograph>) 10885 0x9C78 鱸 (<CJK Ideograph>) 10886 0x9EF7 黷 (<CJK Ideograph>) 10887 0x8C54 豔 (<CJK Ideograph>) 10888 0x947F 鑿 (<CJK Ideograph>) 10889 0x9E1A 鸚 (<CJK Ideograph>) 10890 0x7228 爨 (<CJK Ideograph>) 10891 0x9A6A 驪 (<CJK Ideograph>) 10892 0x9B31 鬱 (<CJK Ideograph>) 10893 0x9E1B 鸛 (<CJK Ideograph>) 10894 0x9E1E 鸞 (<CJK Ideograph>) 10895 0x7C72 籲 (<CJK Ideograph>) 10896 0x2460 ① (CIRCLED DIGIT ONE) 10897 0x2461 ② (CIRCLED DIGIT TWO) 10898 0x2462 ③ (CIRCLED DIGIT THREE) 10899 0x2463 ④ (CIRCLED DIGIT FOUR) 10900 0x2464 ⑤ (CIRCLED DIGIT FIVE) 10901 0x2465 ⑥ (CIRCLED DIGIT SIX) 10902 0x2466 ⑦ (CIRCLED DIGIT SEVEN) 10903 0x2467 ⑧ (CIRCLED DIGIT EIGHT) 10904 0x2468 ⑨ (CIRCLED DIGIT NINE) 10905 0x2469 ⑩ (CIRCLED NUMBER TEN) 10906 0x2474 ⑴ (PARENTHESIZED DIGIT ONE) 10907 0x2475 ⑵ (PARENTHESIZED DIGIT TWO) 10908 0x2476 ⑶ (PARENTHESIZED DIGIT THREE) 10909 0x2477 ⑷ (PARENTHESIZED DIGIT FOUR) 10910 0x2478 ⑸ (PARENTHESIZED DIGIT FIVE) 10911 0x2479 ⑹ (PARENTHESIZED DIGIT SIX) 10912 0x247A ⑺ (PARENTHESIZED DIGIT SEVEN) 10913 0x247B ⑻ (PARENTHESIZED DIGIT EIGHT) 10914 0x247C ⑼ (PARENTHESIZED DIGIT NINE) 10915 0x247D ⑽ (PARENTHESIZED NUMBER TEN) 10916 0x2170 ⅰ (SMALL ROMAN NUMERAL ONE) 10917 0x2171 ⅱ (SMALL ROMAN NUMERAL TWO) 10918 0x2172 ⅲ (SMALL ROMAN NUMERAL THREE) 10919 0x2173 ⅳ (SMALL ROMAN NUMERAL FOUR) 10920 0x2174 ⅴ (SMALL ROMAN NUMERAL FIVE) 10921 0x2175 ⅵ (SMALL ROMAN NUMERAL SIX) 10922 0x2176 ⅶ (SMALL ROMAN NUMERAL SEVEN) 10923 0x2177 ⅷ (SMALL ROMAN NUMERAL EIGHT) 10924 0x2178 ⅸ (SMALL ROMAN NUMERAL NINE) 10925 0x2179 ⅹ (SMALL ROMAN NUMERAL TEN) 10926 0x4E36 丶 (<CJK Ideograph>) 10927 0x4E3F 丿 (<CJK Ideograph>) 10928 0x4E85 亅 (<CJK Ideograph>) 10929 0x4EA0 亠 (<CJK Ideograph>) 10930 0x5182 冂 (<CJK Ideograph>) 10931 0x5196 冖 (<CJK Ideograph>) 10932 0x51AB 冫 (<CJK Ideograph>) 10933 0x52F9 勹 (<CJK Ideograph>) 10934 0x5338 匸 (<CJK Ideograph>) 10935 0x5369 卩 (<CJK Ideograph>) 10936 0x53B6 厶 (<CJK Ideograph>) 10937 0x590A 夊 (<CJK Ideograph>) 10938 0x5B80 宀 (<CJK Ideograph>) 10939 0x5DDB 巛 (<CJK Ideograph>) 10940 0x2F33 ⼳ (KANGXI RADICAL SHORT THREAD) 10941 0x5E7F 广 (<CJK Ideograph>) 10942 0x5EF4 廴 (<CJK Ideograph>) 10943 0x5F50 彐 (<CJK Ideograph>) 10944 0x5F61 彡 (<CJK Ideograph>) 10945 0x6534 攴 (<CJK Ideograph>) 10946 0x65E0 无 (<CJK Ideograph>) 10947 0x7592 疒 (<CJK Ideograph>) 10948 0x7676 癶 (<CJK Ideograph>) 10949 0x8FB5 辵 (<CJK Ideograph>) 10950 0x96B6 隶 (<CJK Ideograph>) 10951 0x00A8 ¨ (DIAERESIS) 10952 0x02C6 ˆ (MODIFIER LETTER CIRCUMFLEX ACCENT) 10953 0x30FD ヽ (KATAKANA ITERATION MARK) 10954 0x30FE ヾ (KATAKANA VOICED ITERATION MARK) 10955 0x309D ゝ (HIRAGANA ITERATION MARK) 10956 0x309E ゞ (HIRAGANA VOICED ITERATION MARK) 10957 0x3003 〃 (DITTO MARK) 10958 0x4EDD 仝 (<CJK Ideograph>) 10959 0x3005 々 (IDEOGRAPHIC ITERATION MARK) 10960 0x3006 〆 (IDEOGRAPHIC CLOSING MARK) 10961 0x3007 〇 (IDEOGRAPHIC NUMBER ZERO) 10962 0x30FC ー (KATAKANA-HIRAGANA PROLONGED SOUND MARK) 10963 0xFF3B [ (FULLWIDTH LEFT SQUARE BRACKET) 10964 0xFF3D ] (FULLWIDTH RIGHT SQUARE BRACKET) 10965 0x273D ✽ (HEAVY TEARDROP-SPOKED ASTERISK) 10966 0x3041 ぁ (HIRAGANA LETTER SMALL A) 10967 0x3042 あ (HIRAGANA LETTER A) 10968 0x3043 ぃ (HIRAGANA LETTER SMALL I) 10969 0x3044 い (HIRAGANA LETTER I) 10970 0x3045 ぅ (HIRAGANA LETTER SMALL U) 10971 0x3046 う (HIRAGANA LETTER U) 10972 0x3047 ぇ (HIRAGANA LETTER SMALL E) 10973 0x3048 え (HIRAGANA LETTER E) 10974 0x3049 ぉ (HIRAGANA LETTER SMALL O) 10975 0x304A お (HIRAGANA LETTER O) 10976 0x304B か (HIRAGANA LETTER KA) 10977 0x304C が (HIRAGANA LETTER GA) 10978 0x304D き (HIRAGANA LETTER KI) 10979 0x304E ぎ (HIRAGANA LETTER GI) 10980 0x304F く (HIRAGANA LETTER KU) 10981 0x3050 ぐ (HIRAGANA LETTER GU) 10982 0x3051 け (HIRAGANA LETTER KE) 10983 0x3052 げ (HIRAGANA LETTER GE) 10984 0x3053 こ (HIRAGANA LETTER KO) 10985 0x3054 ご (HIRAGANA LETTER GO) 10986 0x3055 さ (HIRAGANA LETTER SA) 10987 0x3056 ざ (HIRAGANA LETTER ZA) 10988 0x3057 し (HIRAGANA LETTER SI) 10989 0x3058 じ (HIRAGANA LETTER ZI) 10990 0x3059 す (HIRAGANA LETTER SU) 10991 0x305A ず (HIRAGANA LETTER ZU) 10992 0x305B せ (HIRAGANA LETTER SE) 10993 0x305C ぜ (HIRAGANA LETTER ZE) 10994 0x305D そ (HIRAGANA LETTER SO) 10995 0x305E ぞ (HIRAGANA LETTER ZO) 10996 0x305F た (HIRAGANA LETTER TA) 10997 0x3060 だ (HIRAGANA LETTER DA) 10998 0x3061 ち (HIRAGANA LETTER TI) 10999 0x3062 ぢ (HIRAGANA LETTER DI) 11000 0x3063 っ (HIRAGANA LETTER SMALL TU) 11001 0x3064 つ (HIRAGANA LETTER TU) 11002 0x3065 づ (HIRAGANA LETTER DU) 11003 0x3066 て (HIRAGANA LETTER TE) 11004 0x3067 で (HIRAGANA LETTER DE) 11005 0x3068 と (HIRAGANA LETTER TO) 11006 0x3069 ど (HIRAGANA LETTER DO) 11007 0x306A な (HIRAGANA LETTER NA) 11008 0x306B に (HIRAGANA LETTER NI) 11009 0x306C ぬ (HIRAGANA LETTER NU) 11010 0x306D ね (HIRAGANA LETTER NE) 11011 0x306E の (HIRAGANA LETTER NO) 11012 0x306F は (HIRAGANA LETTER HA) 11013 0x3070 ば (HIRAGANA LETTER BA) 11014 0x3071 ぱ (HIRAGANA LETTER PA) 11015 0x3072 ひ (HIRAGANA LETTER HI) 11016 0x3073 び (HIRAGANA LETTER BI) 11017 0x3074 ぴ (HIRAGANA LETTER PI) 11018 0x3075 ふ (HIRAGANA LETTER HU) 11019 0x3076 ぶ (HIRAGANA LETTER BU) 11020 0x3077 ぷ (HIRAGANA LETTER PU) 11021 0x3078 へ (HIRAGANA LETTER HE) 11022 0x3079 べ (HIRAGANA LETTER BE) 11023 0x307A ぺ (HIRAGANA LETTER PE) 11024 0x307B ほ (HIRAGANA LETTER HO) 11025 0x307C ぼ (HIRAGANA LETTER BO) 11026 0x307D ぽ (HIRAGANA LETTER PO) 11027 0x307E ま (HIRAGANA LETTER MA) 11028 0x307F み (HIRAGANA LETTER MI) 11029 0x3080 む (HIRAGANA LETTER MU) 11030 0x3081 め (HIRAGANA LETTER ME) 11031 0x3082 も (HIRAGANA LETTER MO) 11032 0x3083 ゃ (HIRAGANA LETTER SMALL YA) 11033 0x3084 や (HIRAGANA LETTER YA) 11034 0x3085 ゅ (HIRAGANA LETTER SMALL YU) 11035 0x3086 ゆ (HIRAGANA LETTER YU) 11036 0x3087 ょ (HIRAGANA LETTER SMALL YO) 11037 0x3088 よ (HIRAGANA LETTER YO) 11038 0x3089 ら (HIRAGANA LETTER RA) 11039 0x308A り (HIRAGANA LETTER RI) 11040 0x308B る (HIRAGANA LETTER RU) 11041 0x308C れ (HIRAGANA LETTER RE) 11042 0x308D ろ (HIRAGANA LETTER RO) 11043 0x308E ゎ (HIRAGANA LETTER SMALL WA) 11044 0x308F わ (HIRAGANA LETTER WA) 11045 0x3090 ゐ (HIRAGANA LETTER WI) 11046 0x3091 ゑ (HIRAGANA LETTER WE) 11047 0x3092 を (HIRAGANA LETTER WO) 11048 0x3093 ん (HIRAGANA LETTER N) 11049 0x30A1 ァ (KATAKANA LETTER SMALL A) 11050 0x30A2 ア (KATAKANA LETTER A) 11051 0x30A3 ィ (KATAKANA LETTER SMALL I) 11052 0x30A4 イ (KATAKANA LETTER I) 11053 0x30A5 ゥ (KATAKANA LETTER SMALL U) 11054 0x30A6 ウ (KATAKANA LETTER U) 11055 0x30A7 ェ (KATAKANA LETTER SMALL E) 11056 0x30A8 エ (KATAKANA LETTER E) 11057 0x30A9 ォ (KATAKANA LETTER SMALL O) 11058 0x30AA オ (KATAKANA LETTER O) 11059 0x30AB カ (KATAKANA LETTER KA) 11060 0x30AC ガ (KATAKANA LETTER GA) 11061 0x30AD キ (KATAKANA LETTER KI) 11062 0x30AE ギ (KATAKANA LETTER GI) 11063 0x30AF ク (KATAKANA LETTER KU) 11064 0x30B0 グ (KATAKANA LETTER GU) 11065 0x30B1 ケ (KATAKANA LETTER KE) 11066 0x30B2 ゲ (KATAKANA LETTER GE) 11067 0x30B3 コ (KATAKANA LETTER KO) 11068 0x30B4 ゴ (KATAKANA LETTER GO) 11069 0x30B5 サ (KATAKANA LETTER SA) 11070 0x30B6 ザ (KATAKANA LETTER ZA) 11071 0x30B7 シ (KATAKANA LETTER SI) 11072 0x30B8 ジ (KATAKANA LETTER ZI) 11073 0x30B9 ス (KATAKANA LETTER SU) 11074 0x30BA ズ (KATAKANA LETTER ZU) 11075 0x30BB セ (KATAKANA LETTER SE) 11076 0x30BC ゼ (KATAKANA LETTER ZE) 11077 0x30BD ソ (KATAKANA LETTER SO) 11078 0x30BE ゾ (KATAKANA LETTER ZO) 11079 0x30BF タ (KATAKANA LETTER TA) 11080 0x30C0 ダ (KATAKANA LETTER DA) 11081 0x30C1 チ (KATAKANA LETTER TI) 11082 0x30C2 ヂ (KATAKANA LETTER DI) 11083 0x30C3 ッ (KATAKANA LETTER SMALL TU) 11084 0x30C4 ツ (KATAKANA LETTER TU) 11085 0x30C5 ヅ (KATAKANA LETTER DU) 11086 0x30C6 テ (KATAKANA LETTER TE) 11087 0x30C7 デ (KATAKANA LETTER DE) 11088 0x30C8 ト (KATAKANA LETTER TO) 11089 0x30C9 ド (KATAKANA LETTER DO) 11090 0x30CA ナ (KATAKANA LETTER NA) 11091 0x30CB ニ (KATAKANA LETTER NI) 11092 0x30CC ヌ (KATAKANA LETTER NU) 11093 0x30CD ネ (KATAKANA LETTER NE) 11094 0x30CE ノ (KATAKANA LETTER NO) 11095 0x30CF ハ (KATAKANA LETTER HA) 11096 0x30D0 バ (KATAKANA LETTER BA) 11097 0x30D1 パ (KATAKANA LETTER PA) 11098 0x30D2 ヒ (KATAKANA LETTER HI) 11099 0x30D3 ビ (KATAKANA LETTER BI) 11100 0x30D4 ピ (KATAKANA LETTER PI) 11101 0x30D5 フ (KATAKANA LETTER HU) 11102 0x30D6 ブ (KATAKANA LETTER BU) 11103 0x30D7 プ (KATAKANA LETTER PU) 11104 0x30D8 ヘ (KATAKANA LETTER HE) 11105 0x30D9 ベ (KATAKANA LETTER BE) 11106 0x30DA ペ (KATAKANA LETTER PE) 11107 0x30DB ホ (KATAKANA LETTER HO) 11108 0x30DC ボ (KATAKANA LETTER BO) 11109 0x30DD ポ (KATAKANA LETTER PO) 11110 0x30DE マ (KATAKANA LETTER MA) 11111 0x30DF ミ (KATAKANA LETTER MI) 11112 0x30E0 ム (KATAKANA LETTER MU) 11113 0x30E1 メ (KATAKANA LETTER ME) 11114 0x30E2 モ (KATAKANA LETTER MO) 11115 0x30E3 ャ (KATAKANA LETTER SMALL YA) 11116 0x30E4 ヤ (KATAKANA LETTER YA) 11117 0x30E5 ュ (KATAKANA LETTER SMALL YU) 11118 0x30E6 ユ (KATAKANA LETTER YU) 11119 0x30E7 ョ (KATAKANA LETTER SMALL YO) 11120 0x30E8 ヨ (KATAKANA LETTER YO) 11121 0x30E9 ラ (KATAKANA LETTER RA) 11122 0x30EA リ (KATAKANA LETTER RI) 11123 0x30EB ル (KATAKANA LETTER RU) 11124 0x30EC レ (KATAKANA LETTER RE) 11125 0x30ED ロ (KATAKANA LETTER RO) 11126 0x30EE ヮ (KATAKANA LETTER SMALL WA) 11127 0x30EF ワ (KATAKANA LETTER WA) 11128 0x30F0 ヰ (KATAKANA LETTER WI) 11129 0x30F1 ヱ (KATAKANA LETTER WE) 11130 0x30F2 ヲ (KATAKANA LETTER WO) 11131 0x30F3 ン (KATAKANA LETTER N) 11132 0x30F4 ヴ (KATAKANA LETTER VU) 11133 0x30F5 ヵ (KATAKANA LETTER SMALL KA) 11134 0x30F6 ヶ (KATAKANA LETTER SMALL KE) 11135 0x0410 А (CYRILLIC CAPITAL LETTER A) 11136 0x0411 Б (CYRILLIC CAPITAL LETTER BE) 11137 0x0412 В (CYRILLIC CAPITAL LETTER VE) 11138 0x0413 Г (CYRILLIC CAPITAL LETTER GHE) 11139 0x0414 Д (CYRILLIC CAPITAL LETTER DE) 11140 0x0415 Е (CYRILLIC CAPITAL LETTER IE) 11141 0x0401 Ё (CYRILLIC CAPITAL LETTER IO) 11142 0x0416 Ж (CYRILLIC CAPITAL LETTER ZHE) 11143 0x0417 З (CYRILLIC CAPITAL LETTER ZE) 11144 0x0418 И (CYRILLIC CAPITAL LETTER I) 11145 0x0419 Й (CYRILLIC CAPITAL LETTER SHORT I) 11146 0x041A К (CYRILLIC CAPITAL LETTER KA) 11147 0x041B Л (CYRILLIC CAPITAL LETTER EL) 11148 0x041C М (CYRILLIC CAPITAL LETTER EM) 11149 0x041D Н (CYRILLIC CAPITAL LETTER EN) 11150 0x041E О (CYRILLIC CAPITAL LETTER O) 11151 0x041F П (CYRILLIC CAPITAL LETTER PE) 11152 0x0420 Р (CYRILLIC CAPITAL LETTER ER) 11153 0x0421 С (CYRILLIC CAPITAL LETTER ES) 11154 0x0422 Т (CYRILLIC CAPITAL LETTER TE) 11155 0x0423 У (CYRILLIC CAPITAL LETTER U) 11156 0x0424 Ф (CYRILLIC CAPITAL LETTER EF) 11157 0x0425 Х (CYRILLIC CAPITAL LETTER HA) 11158 0x0426 Ц (CYRILLIC CAPITAL LETTER TSE) 11159 0x0427 Ч (CYRILLIC CAPITAL LETTER CHE) 11160 0x0428 Ш (CYRILLIC CAPITAL LETTER SHA) 11161 0x0429 Щ (CYRILLIC CAPITAL LETTER SHCHA) 11162 0x042A Ъ (CYRILLIC CAPITAL LETTER HARD SIGN) 11163 0x042B Ы (CYRILLIC CAPITAL LETTER YERU) 11164 0x042C Ь (CYRILLIC CAPITAL LETTER SOFT SIGN) 11165 0x042D Э (CYRILLIC CAPITAL LETTER E) 11166 0x042E Ю (CYRILLIC CAPITAL LETTER YU) 11167 0x042F Я (CYRILLIC CAPITAL LETTER YA) 11168 0x0430 а (CYRILLIC SMALL LETTER A) 11169 0x0431 б (CYRILLIC SMALL LETTER BE) 11170 0x0432 в (CYRILLIC SMALL LETTER VE) 11171 0x0433 г (CYRILLIC SMALL LETTER GHE) 11172 0x0434 д (CYRILLIC SMALL LETTER DE) 11173 0x0435 е (CYRILLIC SMALL LETTER IE) 11174 0x0451 ё (CYRILLIC SMALL LETTER IO) 11175 0x0436 ж (CYRILLIC SMALL LETTER ZHE) 11176 0x0437 з (CYRILLIC SMALL LETTER ZE) 11177 0x0438 и (CYRILLIC SMALL LETTER I) 11178 0x0439 й (CYRILLIC SMALL LETTER SHORT I) 11179 0x043A к (CYRILLIC SMALL LETTER KA) 11180 0x043B л (CYRILLIC SMALL LETTER EL) 11181 0x043C м (CYRILLIC SMALL LETTER EM) 11182 0x043D н (CYRILLIC SMALL LETTER EN) 11183 0x043E о (CYRILLIC SMALL LETTER O) 11184 0x043F п (CYRILLIC SMALL LETTER PE) 11185 0x0440 р (CYRILLIC SMALL LETTER ER) 11186 0x0441 с (CYRILLIC SMALL LETTER ES) 11187 0x0442 т (CYRILLIC SMALL LETTER TE) 11188 0x0443 у (CYRILLIC SMALL LETTER U) 11189 0x0444 ф (CYRILLIC SMALL LETTER EF) 11190 0x0445 х (CYRILLIC SMALL LETTER HA) 11191 0x0446 ц (CYRILLIC SMALL LETTER TSE) 11192 0x0447 ч (CYRILLIC SMALL LETTER CHE) 11193 0x0448 ш (CYRILLIC SMALL LETTER SHA) 11194 0x0449 щ (CYRILLIC SMALL LETTER SHCHA) 11195 0x044A ъ (CYRILLIC SMALL LETTER HARD SIGN) 11196 0x044B ы (CYRILLIC SMALL LETTER YERU) 11197 0x044C ь (CYRILLIC SMALL LETTER SOFT SIGN) 11198 0x044D э (CYRILLIC SMALL LETTER E) 11199 0x044E ю (CYRILLIC SMALL LETTER YU) 11200 0x044F я (CYRILLIC SMALL LETTER YA) 11201 0x21E7 ⇧ (UPWARDS WHITE ARROW) 11202 0x21B8 ↸ (NORTH WEST ARROW TO LONG BAR) 11203 0x21B9 ↹ (LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR) 11204 0x31CF ㇏ (CJK STROKE N) 11205 0x200CC 𠃌 (<CJK Ideograph Extension B>) 11206 0x4E5A 乚 (<CJK Ideograph>) 11207 0x2008A 𠂊 (<CJK Ideograph Extension B>) 11208 0x5202 刂 (<CJK Ideograph>) 11209 0x4491 䒑 (<CJK Ideograph Extension A>) 11210 0x9FB0 龰 (<CJK Ideograph>) 11211 0x5188 冈 (<CJK Ideograph>) 11212 0x9FB1 龱 (<CJK Ideograph>) 11213 0x27607 𧘇 (<CJK Ideograph Extension B>) 11254 0xFFE2 ¬ (FULLWIDTH NOT SIGN) 11255 0xFFE4 ¦ (FULLWIDTH BROKEN BAR) 11256 0xFF07 ' (FULLWIDTH APOSTROPHE) 11257 0xFF02 " (FULLWIDTH QUOTATION MARK) 11258 0x3231 ㈱ (PARENTHESIZED IDEOGRAPH STOCK) 11259 0x2116 № (NUMERO SIGN) 11260 0x2121 ℡ (TELEPHONE SIGN) 11261 0x309B ゛ (KATAKANA-HIRAGANA VOICED SOUND MARK) 11262 0x309C ゜ (KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK) 11263 0x2E80 ⺀ (CJK RADICAL REPEAT) 11264 0x2E84 ⺄ (CJK RADICAL SECOND THREE) 11265 0x2E86 ⺆ (CJK RADICAL BOX) 11266 0x2E87 ⺇ (CJK RADICAL TABLE) 11267 0x2E88 ⺈ (CJK RADICAL KNIFE ONE) 11268 0x2E8A ⺊ (CJK RADICAL DIVINATION) 11269 0x2E8C ⺌ (CJK RADICAL SMALL ONE) 11270 0x2E8D ⺍ (CJK RADICAL SMALL TWO) 11271 0x2E95 ⺕ (CJK RADICAL SNOUT TWO) 11272 0x2E9C ⺜ (CJK RADICAL SUN) 11273 0x2E9D ⺝ (CJK RADICAL MOON) 11274 0x2EA5 ⺥ (CJK RADICAL PAW TWO) 11275 0x2EA7 ⺧ (CJK RADICAL COW) 11276 0x2EAA ⺪ (CJK RADICAL BOLT OF CLOTH) 11277 0x2EAC ⺬ (CJK RADICAL SPIRIT ONE) 11278 0x2EAE ⺮ (CJK RADICAL BAMBOO) 11279 0x2EB6 ⺶ (CJK RADICAL SHEEP) 11280 0x2EBC ⺼ (CJK RADICAL MEAT) 11281 0x2EBE ⺾ (CJK RADICAL GRASS ONE) 11282 0x2EC6 ⻆ (CJK RADICAL SIMPLIFIED HORN) 11283 0x2ECA ⻊ (CJK RADICAL FOOT) 11284 0x2ECC ⻌ (CJK RADICAL SIMPLIFIED WALK) 11285 0x2ECD ⻍ (CJK RADICAL WALK ONE) 11286 0x2ECF ⻏ (CJK RADICAL CITY) 11287 0x2ED6 ⻖ (CJK RADICAL MOUND TWO) 11288 0x2ED7 ⻗ (CJK RADICAL RAIN) 11289 0x2EDE ⻞ (CJK RADICAL EAT TWO) 11290 0x2EE3 ⻣ (CJK RADICAL BONE) 11294 0x0283 ʃ (LATIN SMALL LETTER ESH) 11295 0x0250 ɐ (LATIN SMALL LETTER TURNED A) 11296 0x025B ɛ (LATIN SMALL LETTER OPEN E) 11297 0x0254 ɔ (LATIN SMALL LETTER OPEN O) 11298 0x0275 ɵ (LATIN SMALL LETTER BARRED O) 11299 0x0153 œ (LATIN SMALL LIGATURE OE) 11300 0x00F8 ø (LATIN SMALL LETTER O WITH STROKE) 11301 0x014B ŋ (LATIN SMALL LETTER ENG) 11302 0x028A ʊ (LATIN SMALL LETTER UPSILON) 11303 0x026A ɪ (LATIN LETTER SMALL CAPITAL I) 11304 0x4E42 乂 (<CJK Ideograph>) 11305 0x4E5C 乜 (<CJK Ideograph>) 11306 0x51F5 凵 (<CJK Ideograph>) 11307 0x531A 匚 (<CJK Ideograph>) 11308 0x5382 厂 (<CJK Ideograph>) 11309 0x4E07 万 (<CJK Ideograph>) 11310 0x4E0C 丌 (<CJK Ideograph>) 11311 0x4E47 乇 (<CJK Ideograph>) 11312 0x4E8D 亍 (<CJK Ideograph>) 11313 0x56D7 囗 (<CJK Ideograph>) 11314 0xFA0C 兀 (CJK COMPATIBILITY IDEOGRAPH-FA0C) 11315 0x5C6E 屮 (<CJK Ideograph>) 11316 0x5F73 彳 (<CJK Ideograph>) 11317 0x4E0F 丏 (<CJK Ideograph>) 11318 0x5187 冇 (<CJK Ideograph>) 11319 0x4E0E 与 (<CJK Ideograph>) 11320 0x4E2E 丮 (<CJK Ideograph>) 11321 0x4E93 亓 (<CJK Ideograph>) 11322 0x4EC2 仂 (<CJK Ideograph>) 11323 0x4EC9 仉 (<CJK Ideograph>) 11324 0x4EC8 仈 (<CJK Ideograph>) 11325 0x5198 冘 (<CJK Ideograph>) 11326 0x52FC 勼 (<CJK Ideograph>) 11327 0x536C 卬 (<CJK Ideograph>) 11328 0x53B9 厹 (<CJK Ideograph>) 11329 0x5720 圠 (<CJK Ideograph>) 11330 0x5903 夃 (<CJK Ideograph>) 11331 0x592C 夬 (<CJK Ideograph>) 11332 0x5C10 尐 (<CJK Ideograph>) 11333 0x5DFF 巿 (<CJK Ideograph>) 11334 0x65E1 旡 (<CJK Ideograph>) 11335 0x6BB3 殳 (<CJK Ideograph>) 11336 0x6BCC 毌 (<CJK Ideograph>) 11337 0x6C14 气 (<CJK Ideograph>) 11338 0x723F 爿 (<CJK Ideograph>) 11339 0x4E31 丱 (<CJK Ideograph>) 11340 0x4E3C 丼 (<CJK Ideograph>) 11341 0x4EE8 仨 (<CJK Ideograph>) 11342 0x4EDC 仜 (<CJK Ideograph>) 11343 0x4EE9 仩 (<CJK Ideograph>) 11344 0x4EE1 仡 (<CJK Ideograph>) 11345 0x4EDD 仝 (<CJK Ideograph>) 11346 0x4EDA 仚 (<CJK Ideograph>) 11347 0x520C 刌 (<CJK Ideograph>) 11348 0x531C 匜 (<CJK Ideograph>) 11349 0x534C 卌 (<CJK Ideograph>) 11350 0x5722 圢 (<CJK Ideograph>) 11351 0x5723 圣 (<CJK Ideograph>) 11352 0x5917 夗 (<CJK Ideograph>) 11353 0x592F 夯 (<CJK Ideograph>) 11354 0x5B81 宁 (<CJK Ideograph>) 11355 0x5B84 宄 (<CJK Ideograph>) 11356 0x5C12 尒 (<CJK Ideograph>) 11357 0x5C3B 尻 (<CJK Ideograph>) 11358 0x5C74 屴 (<CJK Ideograph>) 11359 0x5C73 屳 (<CJK Ideograph>) 11360 0x5E04 帄 (<CJK Ideograph>) 11361 0x5E80 庀 (<CJK Ideograph>) 11362 0x5E82 庂 (<CJK Ideograph>) 11363 0x5FC9 忉 (<CJK Ideograph>) 11364 0x6209 戉 (<CJK Ideograph>) 11365 0x6250 扐 (<CJK Ideograph>) 11366 0x6C15 氕 (<CJK Ideograph>) 11367 0x6C36 氶 (<CJK Ideograph>) 11368 0x6C43 汃 (<CJK Ideograph>) 11369 0x6C3F 氿 (<CJK Ideograph>) 11370 0x6C3B 氻 (<CJK Ideograph>) 11371 0x72AE 犮 (<CJK Ideograph>) 11372 0x72B0 犰 (<CJK Ideograph>) 11373 0x738A 玊 (<CJK Ideograph>) 11374 0x79B8 禸 (<CJK Ideograph>) 11375 0x808A 肊 (<CJK Ideograph>) 11376 0x961E 阞 (<CJK Ideograph>) 11377 0x4F0E 伎 (<CJK Ideograph>) 11378 0x4F18 优 (<CJK Ideograph>) 11379 0x4F2C 伬 (<CJK Ideograph>) 11380 0x4EF5 仵 (<CJK Ideograph>) 11381 0x4F14 伔 (<CJK Ideograph>) 11382 0x4EF1 仱 (<CJK Ideograph>) 11383 0x4F00 伀 (<CJK Ideograph>) 11384 0x4EF7 价 (<CJK Ideograph>) 11385 0x4F08 伈 (<CJK Ideograph>) 11386 0x4F1D 伝 (<CJK Ideograph>) 11387 0x4F02 伂 (<CJK Ideograph>) 11388 0x4F05 伅 (<CJK Ideograph>) 11389 0x4F22 伢 (<CJK Ideograph>) 11390 0x4F13 伓 (<CJK Ideograph>) 11391 0x4F04 伄 (<CJK Ideograph>) 11392 0x4EF4 仴 (<CJK Ideograph>) 11393 0x4F12 伒 (<CJK Ideograph>) 11394 0x51B1 冱 (<CJK Ideograph>) 11395 0x5213 刓 (<CJK Ideograph>) 11396 0x5209 刉 (<CJK Ideograph>) 11397 0x5210 刐 (<CJK Ideograph>) 11398 0x52A6 劦 (<CJK Ideograph>) 11399 0x5322 匢 (<CJK Ideograph>) 11400 0x531F 匟 (<CJK Ideograph>) 11401 0x534D 卍 (<CJK Ideograph>) 11402 0x538A 厊 (<CJK Ideograph>) 11403 0x5407 吇 (<CJK Ideograph>) 11404 0x56E1 囡 (<CJK Ideograph>) 11405 0x56DF 囟 (<CJK Ideograph>) 11406 0x572E 圮 (<CJK Ideograph>) 11407 0x572A 圪 (<CJK Ideograph>) 11408 0x5734 圴 (<CJK Ideograph>) 11409 0x593C 夼 (<CJK Ideograph>) 11410 0x5980 妀 (<CJK Ideograph>) 11411 0x597C 奼 (<CJK Ideograph>) 11412 0x5985 妅 (<CJK Ideograph>) 11413 0x597B 奻 (<CJK Ideograph>) 11414 0x597E 奾 (<CJK Ideograph>) 11415 0x5977 奷 (<CJK Ideograph>) 11416 0x597F 奿 (<CJK Ideograph>) 11417 0x5B56 孖 (<CJK Ideograph>) 11418 0x5C15 尕 (<CJK Ideograph>) 11419 0x5C25 尥 (<CJK Ideograph>) 11420 0x5C7C 屼 (<CJK Ideograph>) 11421 0x5C7A 屺 (<CJK Ideograph>) 11422 0x5C7B 屻 (<CJK Ideograph>) 11423 0x5C7E 屾 (<CJK Ideograph>) 11424 0x5DDF 巟 (<CJK Ideograph>) 11425 0x5E75 幵 (<CJK Ideograph>) 11426 0x5E84 庄 (<CJK Ideograph>) 11427 0x5F02 异 (<CJK Ideograph>) 11428 0x5F1A 弚 (<CJK Ideograph>) 11429 0x5F74 彴 (<CJK Ideograph>) 11430 0x5FD5 忕 (<CJK Ideograph>) 11431 0x5FD4 忔 (<CJK Ideograph>) 11432 0x5FCF 忏 (<CJK Ideograph>) 11433 0x625C 扜 (<CJK Ideograph>) 11434 0x625E 扞 (<CJK Ideograph>) 11435 0x6264 扤 (<CJK Ideograph>) 11436 0x6261 扡 (<CJK Ideograph>) 11437 0x6266 扦 (<CJK Ideograph>) 11438 0x6262 扢 (<CJK Ideograph>) 11439 0x6259 扙 (<CJK Ideograph>) 11440 0x6260 扠 (<CJK Ideograph>) 11441 0x625A 扚 (<CJK Ideograph>) 11442 0x6265 扥 (<CJK Ideograph>) 11443 0x65EF 旯 (<CJK Ideograph>) 11444 0x65EE 旮 (<CJK Ideograph>) 11445 0x673E 朾 (<CJK Ideograph>) 11446 0x6739 朹 (<CJK Ideograph>) 11447 0x6738 朸 (<CJK Ideograph>) 11448 0x673B 朻 (<CJK Ideograph>) 11449 0x673A 机 (<CJK Ideograph>) 11450 0x673F 朿 (<CJK Ideograph>) 11451 0x673C 朼 (<CJK Ideograph>) 11452 0x6733 朳 (<CJK Ideograph>) 11453 0x6C18 氘 (<CJK Ideograph>) 11454 0x6C46 汆 (<CJK Ideograph>) 11455 0x6C52 汒 (<CJK Ideograph>) 11456 0x6C5C 汜 (<CJK Ideograph>) 11457 0x6C4F 汏 (<CJK Ideograph>) 11458 0x6C4A 汊 (<CJK Ideograph>) 11459 0x6C54 汔 (<CJK Ideograph>) 11460 0x6C4B 汋 (<CJK Ideograph>) 11461 0x6C4C 汌 (<CJK Ideograph>) 11462 0x7071 灱 (<CJK Ideograph>) 11463 0x725E 牞 (<CJK Ideograph>) 11464 0x72B4 犴 (<CJK Ideograph>) 11465 0x72B5 犵 (<CJK Ideograph>) 11466 0x738E 玎 (<CJK Ideograph>) 11467 0x752A 甪 (<CJK Ideograph>) 11468 0x767F 癿 (<CJK Ideograph>) 11469 0x7A75 穵 (<CJK Ideograph>) 11470 0x7F51 网 (<CJK Ideograph>) 11471 0x8278 艸 (<CJK Ideograph>) 11472 0x827C 艼 (<CJK Ideograph>) 11473 0x8280 芀 (<CJK Ideograph>) 11474 0x827D 艽 (<CJK Ideograph>) 11475 0x827F 艿 (<CJK Ideograph>) 11476 0x864D 虍 (<CJK Ideograph>) 11477 0x897E 襾 (<CJK Ideograph>) 11478 0x9099 邙 (<CJK Ideograph>) 11479 0x9097 邗 (<CJK Ideograph>) 11480 0x9098 邘 (<CJK Ideograph>) 11481 0x909B 邛 (<CJK Ideograph>) 11482 0x9094 邔 (<CJK Ideograph>) 11483 0x9622 阢 (<CJK Ideograph>) 11484 0x9624 阤 (<CJK Ideograph>) 11485 0x9620 阠 (<CJK Ideograph>) 11486 0x9623 阣 (<CJK Ideograph>) 11487 0x4F56 佖 (<CJK Ideograph>) 11488 0x4F3B 伻 (<CJK Ideograph>) 11489 0x4F62 佢 (<CJK Ideograph>) 11490 0x4F49 佉 (<CJK Ideograph>) 11491 0x4F53 体 (<CJK Ideograph>) 11492 0x4F64 佤 (<CJK Ideograph>) 11493 0x4F3E 伾 (<CJK Ideograph>) 11494 0x4F67 佧 (<CJK Ideograph>) 11495 0x4F52 佒 (<CJK Ideograph>) 11496 0x4F5F 佟 (<CJK Ideograph>) 11497 0x4F41 佁 (<CJK Ideograph>) 11498 0x4F58 佘 (<CJK Ideograph>) 11499 0x4F2D 伭 (<CJK Ideograph>) 11500 0x4F33 伳 (<CJK Ideograph>) 11501 0x4F3F 伿 (<CJK Ideograph>) 11502 0x4F61 佡 (<CJK Ideograph>) 11503 0x518F 冏 (<CJK Ideograph>) 11504 0x51B9 冹 (<CJK Ideograph>) 11505 0x521C 刜 (<CJK Ideograph>) 11506 0x521E 刞 (<CJK Ideograph>) 11507 0x5221 刡 (<CJK Ideograph>) 11508 0x52AD 劭 (<CJK Ideograph>) 11509 0x52AE 劮 (<CJK Ideograph>) 11510 0x5309 匉 (<CJK Ideograph>) 11511 0x5363 卣 (<CJK Ideograph>) 11512 0x5372 卲 (<CJK Ideograph>) 11513 0x538E 厎 (<CJK Ideograph>) 11514 0x538F 厏 (<CJK Ideograph>) 11515 0x5430 吰 (<CJK Ideograph>) 11516 0x5437 吷 (<CJK Ideograph>) 11517 0x542A 吪 (<CJK Ideograph>) 11518 0x5454 呔 (<CJK Ideograph>) 11519 0x5445 呅 (<CJK Ideograph>) 11520 0x5419 吙 (<CJK Ideograph>) 11521 0x541C 吜 (<CJK Ideograph>) 11522 0x5425 吥 (<CJK Ideograph>) 11523 0x5418 吘 (<CJK Ideograph>) 11524 0x543D 吽 (<CJK Ideograph>) 11525 0x544F 呏 (<CJK Ideograph>) 11526 0x5441 呁 (<CJK Ideograph>) 11527 0x5428 吨 (<CJK Ideograph>) 11528 0x5424 吤 (<CJK Ideograph>) 11529 0x5447 呇 (<CJK Ideograph>) 11530 0x56EE 囮 (<CJK Ideograph>) 11531 0x56E7 囧 (<CJK Ideograph>) 11532 0x56E5 囥 (<CJK Ideograph>) 11533 0x5741 坁 (<CJK Ideograph>) 11534 0x5745 坅 (<CJK Ideograph>) 11535 0x574C 坌 (<CJK Ideograph>) 11536 0x5749 坉 (<CJK Ideograph>) 11537 0x574B 坋 (<CJK Ideograph>) 11538 0x5752 坒 (<CJK Ideograph>) 11539 0x5906 夆 (<CJK Ideograph>) 11540 0x5940 奀 (<CJK Ideograph>) 11541 0x59A6 妦 (<CJK Ideograph>) 11542 0x5998 妘 (<CJK Ideograph>) 11543 0x59A0 妠 (<CJK Ideograph>) 11544 0x5997 妗 (<CJK Ideograph>) 11545 0x598E 妎 (<CJK Ideograph>) 11546 0x59A2 妢 (<CJK Ideograph>) 11547 0x5990 妐 (<CJK Ideograph>) 11548 0x598F 妏 (<CJK Ideograph>) 11549 0x59A7 妧 (<CJK Ideograph>) 11550 0x59A1 妡 (<CJK Ideograph>) 11551 0x5B8E 宎 (<CJK Ideograph>) 11552 0x5B92 宒 (<CJK Ideograph>) 11553 0x5C28 尨 (<CJK Ideograph>) 11554 0x5C2A 尪 (<CJK Ideograph>) 11555 0x5C8D 岍 (<CJK Ideograph>) 11556 0x5C8F 岏 (<CJK Ideograph>) 11557 0x5C88 岈 (<CJK Ideograph>) 11558 0x5C8B 岋 (<CJK Ideograph>) 11559 0x5C89 岉 (<CJK Ideograph>) 11560 0x5C92 岒 (<CJK Ideograph>) 11561 0x5C8A 岊 (<CJK Ideograph>) 11562 0x5C86 岆 (<CJK Ideograph>) 11563 0x5C93 岓 (<CJK Ideograph>) 11564 0x5C95 岕 (<CJK Ideograph>) 11565 0x5DE0 巠 (<CJK Ideograph>) 11566 0x5E0A 帊 (<CJK Ideograph>) 11567 0x5E0E 帎 (<CJK Ideograph>) 11568 0x5E8B 庋 (<CJK Ideograph>) 11569 0x5E89 庉 (<CJK Ideograph>) 11570 0x5E8C 庌 (<CJK Ideograph>) 11571 0x5E88 庈 (<CJK Ideograph>) 11572 0x5E8D 庍 (<CJK Ideograph>) 11573 0x5F05 弅 (<CJK Ideograph>) 11574 0x5F1D 弝 (<CJK Ideograph>) 11575 0x5F78 彸 (<CJK Ideograph>) 11576 0x5F76 彶 (<CJK Ideograph>) 11577 0x5FD2 忒 (<CJK Ideograph>) 11578 0x5FD1 忑 (<CJK Ideograph>) 11579 0x5FD0 忐 (<CJK Ideograph>) 11580 0x5FED 忭 (<CJK Ideograph>) 11581 0x5FE8 忨 (<CJK Ideograph>) 11582 0x5FEE 忮 (<CJK Ideograph>) 11583 0x5FF3 忳 (<CJK Ideograph>) 11584 0x5FE1 忡 (<CJK Ideograph>) 11585 0x5FE4 忤 (<CJK Ideograph>) 11586 0x5FE3 忣 (<CJK Ideograph>) 11587 0x5FFA 忺 (<CJK Ideograph>) 11588 0x5FEF 忯 (<CJK Ideograph>) 11589 0x5FF7 忷 (<CJK Ideograph>) 11590 0x5FFB 忻 (<CJK Ideograph>) 11591 0x6000 怀 (<CJK Ideograph>) 11592 0x5FF4 忴 (<CJK Ideograph>) 11593 0x623A 戺 (<CJK Ideograph>) 11594 0x6283 抃 (<CJK Ideograph>) 11595 0x628C 抌 (<CJK Ideograph>) 11596 0x628E 抎 (<CJK Ideograph>) 11597 0x628F 抏 (<CJK Ideograph>) 11598 0x6294 抔 (<CJK Ideograph>) 11599 0x6287 抇 (<CJK Ideograph>) 11600 0x6271 扱 (<CJK Ideograph>) 11601 0x627B 扻 (<CJK Ideograph>) 11602 0x627A 扺 (<CJK Ideograph>) 11603 0x6270 扰 (<CJK Ideograph>) 11604 0x6281 抁 (<CJK Ideograph>) 11605 0x6288 抈 (<CJK Ideograph>) 11606 0x6277 扷 (<CJK Ideograph>) 11607 0x627D 扽 (<CJK Ideograph>) 11608 0x6272 扲 (<CJK Ideograph>) 11609 0x6274 扴 (<CJK Ideograph>) 11610 0x6537 攷 (<CJK Ideograph>) 11611 0x65F0 旰 (<CJK Ideograph>) 11612 0x65F4 旴 (<CJK Ideograph>) 11613 0x65F3 旳 (<CJK Ideograph>) 11614 0x65F2 旲 (<CJK Ideograph>) 11615 0x65F5 旵 (<CJK Ideograph>) 11616 0x6745 杅 (<CJK Ideograph>) 11617 0x6747 杇 (<CJK Ideograph>) 11618 0x6759 杙 (<CJK Ideograph>) 11619 0x6755 杕 (<CJK Ideograph>) 11620 0x674C 杌 (<CJK Ideograph>) 11621 0x6748 杈 (<CJK Ideograph>) 11622 0x675D 杝 (<CJK Ideograph>) 11623 0x674D 杍 (<CJK Ideograph>) 11624 0x675A 杚 (<CJK Ideograph>) 11625 0x674B 杋 (<CJK Ideograph>) 11626 0x6BD0 毐 (<CJK Ideograph>) 11627 0x6C19 氙 (<CJK Ideograph>) 11628 0x6C1A 氚 (<CJK Ideograph>) 11629 0x6C78 汸 (<CJK Ideograph>) 11630 0x6C67 汧 (<CJK Ideograph>) 11631 0x6C6B 汫 (<CJK Ideograph>) 11632 0x6C84 沄 (<CJK Ideograph>) 11633 0x6C8B 沋 (<CJK Ideograph>) 11634 0x6C8F 沏 (<CJK Ideograph>) 11635 0x6C71 汱 (<CJK Ideograph>) 11636 0x6C6F 汯 (<CJK Ideograph>) 11637 0x6C69 汩 (<CJK Ideograph>) 11638 0x6C9A 沚 (<CJK Ideograph>) 11639 0x6C6D 汭 (<CJK Ideograph>) 11640 0x6C87 沇 (<CJK Ideograph>) 11641 0x6C95 沕 (<CJK Ideograph>) 11642 0x6C9C 沜 (<CJK Ideograph>) 11643 0x6C66 汦 (<CJK Ideograph>) 11644 0x6C73 汳 (<CJK Ideograph>) 11645 0x6C65 汥 (<CJK Ideograph>) 11646 0x6C7B 汻 (<CJK Ideograph>) 11647 0x6C8E 沎 (<CJK Ideograph>) 11648 0x7074 灴 (<CJK Ideograph>) 11649 0x707A 灺 (<CJK Ideograph>) 11650 0x7263 牣 (<CJK Ideograph>) 11651 0x72BF 犿 (<CJK Ideograph>) 11652 0x72BD 犽 (<CJK Ideograph>) 11653 0x72C3 狃 (<CJK Ideograph>) 11654 0x72C6 狆 (<CJK Ideograph>) 11655 0x72C1 狁 (<CJK Ideograph>) 11656 0x72BA 犺 (<CJK Ideograph>) 11657 0x72C5 狅 (<CJK Ideograph>) 11658 0x7395 玕 (<CJK Ideograph>) 11659 0x7397 玗 (<CJK Ideograph>) 11660 0x7393 玓 (<CJK Ideograph>) 11661 0x7394 玔 (<CJK Ideograph>) 11662 0x7392 玒 (<CJK Ideograph>) 11663 0x753A 町 (<CJK Ideograph>) 11664 0x7539 甹 (<CJK Ideograph>) 11665 0x7594 疔 (<CJK Ideograph>) 11666 0x7595 疕 (<CJK Ideograph>) 11667 0x7681 皁 (<CJK Ideograph>) 11668 0x793D 礽 (<CJK Ideograph>) 11669 0x8034 耴 (<CJK Ideograph>) 11670 0x8095 肕 (<CJK Ideograph>) 11671 0x8099 肙 (<CJK Ideograph>) 11672 0x8090 肐 (<CJK Ideograph>) 11673 0x8092 肒 (<CJK Ideograph>) 11674 0x809C 肜 (<CJK Ideograph>) 11675 0x8290 芐 (<CJK Ideograph>) 11676 0x828F 芏 (<CJK Ideograph>) 11677 0x8285 芅 (<CJK Ideograph>) 11678 0x828E 芎 (<CJK Ideograph>) 11679 0x8291 芑 (<CJK Ideograph>) 11680 0x8293 芓 (<CJK Ideograph>) 11681 0x828A 芊 (<CJK Ideograph>) 11682 0x8283 芃 (<CJK Ideograph>) 11683 0x8284 芄 (<CJK Ideograph>) 11684 0x8C78 豸 (<CJK Ideograph>) 11685 0x8FC9 迉 (<CJK Ideograph>) 11686 0x8FBF 辿 (<CJK Ideograph>) 11687 0x909F 邟 (<CJK Ideograph>) 11688 0x90A1 邡 (<CJK Ideograph>) 11689 0x90A5 邥 (<CJK Ideograph>) 11690 0x909E 邞 (<CJK Ideograph>) 11691 0x90A7 邧 (<CJK Ideograph>) 11692 0x90A0 邠 (<CJK Ideograph>) 11693 0x9630 阰 (<CJK Ideograph>) 11694 0x9628 阨 (<CJK Ideograph>) 11695 0x962F 阯 (<CJK Ideograph>) 11696 0x962D 阭 (<CJK Ideograph>) 11697 0x4E33 丳 (<CJK Ideograph>) 11698 0x4F98 侘 (<CJK Ideograph>) 11699 0x4F7C 佼 (<CJK Ideograph>) 11700 0x4F85 侅 (<CJK Ideograph>) 11701 0x4F7D 佽 (<CJK Ideograph>) 11702 0x4F80 侀 (<CJK Ideograph>) 11703 0x4F87 侇 (<CJK Ideograph>) 11704 0x4F76 佶 (<CJK Ideograph>) 11705 0x4F74 佴 (<CJK Ideograph>) 11706 0x4F89 侉 (<CJK Ideograph>) 11707 0x4F84 侄 (<CJK Ideograph>) 11708 0x4F77 佷 (<CJK Ideograph>) 11709 0x4F4C 佌 (<CJK Ideograph>) 11710 0x4F97 侗 (<CJK Ideograph>) 11711 0x4F6A 佪 (<CJK Ideograph>) 11712 0x4F9A 侚 (<CJK Ideograph>) 11713 0x4F79 佹 (<CJK Ideograph>) 11714 0x4F81 侁 (<CJK Ideograph>) 11715 0x4F78 佸 (<CJK Ideograph>) 11716 0x4F90 侐 (<CJK Ideograph>) 11717 0x4F9C 侜 (<CJK Ideograph>) 11718 0x4F94 侔 (<CJK Ideograph>) 11719 0x4F9E 侞 (<CJK Ideograph>) 11720 0x4F92 侒 (<CJK Ideograph>) 11721 0x4F82 侂 (<CJK Ideograph>) 11722 0x4F95 侕 (<CJK Ideograph>) 11723 0x4F6B 佫 (<CJK Ideograph>) 11724 0x4F6E 佮 (<CJK Ideograph>) 11725 0x519E 冞 (<CJK Ideograph>) 11726 0x51BC 冼 (<CJK Ideograph>) 11727 0x51BE 冾 (<CJK Ideograph>) 11728 0x5235 刵 (<CJK Ideograph>) 11729 0x5232 刲 (<CJK Ideograph>) 11730 0x5233 刳 (<CJK Ideograph>) 11731 0x5246 剆 (<CJK Ideograph>) 11732 0x5231 刱 (<CJK Ideograph>) 11733 0x52BC 劼 (<CJK Ideograph>) 11734 0x530A 匊 (<CJK Ideograph>) 11735 0x530B 匋 (<CJK Ideograph>) 11736 0x533C 匼 (<CJK Ideograph>) 11737 0x5392 厒 (<CJK Ideograph>) 11738 0x5394 厔 (<CJK Ideograph>) 11739 0x5487 咇 (<CJK Ideograph>) 11740 0x547F 呿 (<CJK Ideograph>) 11741 0x5481 咁 (<CJK Ideograph>) 11742 0x5491 咑 (<CJK Ideograph>) 11743 0x5482 咂 (<CJK Ideograph>) 11744 0x5488 咈 (<CJK Ideograph>) 11745 0x546B 呫 (<CJK Ideograph>) 11746 0x547A 呺 (<CJK Ideograph>) 11747 0x547E 呾 (<CJK Ideograph>) 11748 0x5465 呥 (<CJK Ideograph>) 11749 0x546C 呬 (<CJK Ideograph>) 11750 0x5474 呴 (<CJK Ideograph>) 11751 0x5466 呦 (<CJK Ideograph>) 11752 0x548D 咍 (<CJK Ideograph>) 11753 0x546F 呯 (<CJK Ideograph>) 11754 0x5461 呡 (<CJK Ideograph>) 11755 0x5460 呠 (<CJK Ideograph>) 11756 0x5498 咘 (<CJK Ideograph>) 11757 0x5463 呣 (<CJK Ideograph>) 11758 0x5467 呧 (<CJK Ideograph>) 11759 0x5464 呤 (<CJK Ideograph>) 11760 0x56F7 囷 (<CJK Ideograph>) 11761 0x56F9 囹 (<CJK Ideograph>) 11762 0x576F 坯 (<CJK Ideograph>) 11763 0x5772 坲 (<CJK Ideograph>) 11764 0x576D 坭 (<CJK Ideograph>) 11765 0x576B 坫 (<CJK Ideograph>) 11766 0x5771 坱 (<CJK Ideograph>) 11767 0x5770 坰 (<CJK Ideograph>) 11768 0x5776 坶 (<CJK Ideograph>) 11769 0x5780 垀 (<CJK Ideograph>) 11770 0x5775 坵 (<CJK Ideograph>) 11771 0x577B 坻 (<CJK Ideograph>) 11772 0x5773 坳 (<CJK Ideograph>) 11773 0x5774 坴 (<CJK Ideograph>) 11774 0x5762 坢 (<CJK Ideograph>) 11775 0x5768 坨 (<CJK Ideograph>) 11776 0x577D 坽 (<CJK Ideograph>) 11777 0x590C 夌 (<CJK Ideograph>) 11778 0x5945 奅 (<CJK Ideograph>) 11779 0x59B5 妵 (<CJK Ideograph>) 11780 0x59BA 妺 (<CJK Ideograph>) 11781 0x59CF 姏 (<CJK Ideograph>) 11782 0x59CE 姎 (<CJK Ideograph>) 11783 0x59B2 妲 (<CJK Ideograph>) 11784 0x59CC 姌 (<CJK Ideograph>) 11785 0x59C1 姁 (<CJK Ideograph>) 11786 0x59B6 妶 (<CJK Ideograph>) 11787 0x59BC 妼 (<CJK Ideograph>) 11788 0x59C3 姃 (<CJK Ideograph>) 11789 0x59D6 姖 (<CJK Ideograph>) 11790 0x59B1 妱 (<CJK Ideograph>) 11791 0x59BD 妽 (<CJK Ideograph>) 11792 0x59C0 姀 (<CJK Ideograph>) 11793 0x59C8 姈 (<CJK Ideograph>) 11794 0x59B4 妴 (<CJK Ideograph>) 11795 0x59C7 姇 (<CJK Ideograph>) 11796 0x5B62 孢 (<CJK Ideograph>) 11797 0x5B65 孥 (<CJK Ideograph>) 11798 0x5B93 宓 (<CJK Ideograph>) 11799 0x5B95 宕 (<CJK Ideograph>) 11800 0x5C44 屄 (<CJK Ideograph>) 11801 0x5C47 屇 (<CJK Ideograph>) 11802 0x5CAE 岮 (<CJK Ideograph>) 11803 0x5CA4 岤 (<CJK Ideograph>) 11804 0x5CA0 岠 (<CJK Ideograph>) 11805 0x5CB5 岵 (<CJK Ideograph>) 11806 0x5CAF 岯 (<CJK Ideograph>) 11807 0x5CA8 岨 (<CJK Ideograph>) 11808 0x5CAC 岬 (<CJK Ideograph>) 11809 0x5C9F 岟 (<CJK Ideograph>) 11810 0x5CA3 岣 (<CJK Ideograph>) 11811 0x5CAD 岭 (<CJK Ideograph>) 11812 0x5CA2 岢 (<CJK Ideograph>) 11813 0x5CAA 岪 (<CJK Ideograph>) 11814 0x5CA7 岧 (<CJK Ideograph>) 11815 0x5C9D 岝 (<CJK Ideograph>) 11816 0x5CA5 岥 (<CJK Ideograph>) 11817 0x5CB6 岶 (<CJK Ideograph>) 11818 0x5CB0 岰 (<CJK Ideograph>) 11819 0x5CA6 岦 (<CJK Ideograph>) 11820 0x5E17 帗 (<CJK Ideograph>) 11821 0x5E14 帔 (<CJK Ideograph>) 11822 0x5E19 帙 (<CJK Ideograph>) 11823 0x5F28 弨 (<CJK Ideograph>) 11824 0x5F22 弢 (<CJK Ideograph>) 11825 0x5F23 弣 (<CJK Ideograph>) 11826 0x5F24 弤 (<CJK Ideograph>) 11827 0x5F54 彔 (<CJK Ideograph>) 11828 0x5F82 徂 (<CJK Ideograph>) 11829 0x5F7E 彾 (<CJK Ideograph>) 11830 0x5F7D 彽 (<CJK Ideograph>) 11831 0x5FDE 忞 (<CJK Ideograph>) 11832 0x5FE5 忥 (<CJK Ideograph>) 11833 0x602D 怭 (<CJK Ideograph>) 11834 0x6026 怦 (<CJK Ideograph>) 11835 0x6019 怙 (<CJK Ideograph>) 11836 0x6032 怲 (<CJK Ideograph>) 11837 0x600B 怋 (<CJK Ideograph>) 11838 0x6034 怴 (<CJK Ideograph>) 11839 0x600A 怊 (<CJK Ideograph>) 11840 0x6017 怗 (<CJK Ideograph>) 11841 0x6033 怳 (<CJK Ideograph>) 11842 0x601A 怚 (<CJK Ideograph>) 11843 0x601E 怞 (<CJK Ideograph>) 11844 0x602C 怬 (<CJK Ideograph>) 11845 0x6022 怢 (<CJK Ideograph>) 11846 0x600D 怍 (<CJK Ideograph>) 11847 0x6010 怐 (<CJK Ideograph>) 11848 0x602E 怮 (<CJK Ideograph>) 11849 0x6013 怓 (<CJK Ideograph>) 11850 0x6011 怑 (<CJK Ideograph>) 11851 0x600C 怌 (<CJK Ideograph>) 11852 0x6009 怉 (<CJK Ideograph>) 11853 0x601C 怜 (<CJK Ideograph>) 11854 0x6214 戔 (<CJK Ideograph>) 11855 0x623D 戽 (<CJK Ideograph>) 11856 0x62AD 抭 (<CJK Ideograph>) 11857 0x62B4 抴 (<CJK Ideograph>) 11858 0x62D1 拑 (<CJK Ideograph>) 11859 0x62BE 抾 (<CJK Ideograph>) 11860 0x62AA 抪 (<CJK Ideograph>) 11861 0x62B6 抶 (<CJK Ideograph>) 11862 0x62CA 拊 (<CJK Ideograph>) 11863 0x62AE 抮 (<CJK Ideograph>) 11864 0x62B3 抳 (<CJK Ideograph>) 11865 0x62AF 抯 (<CJK Ideograph>) 11866 0x62BB 抻 (<CJK Ideograph>) 11867 0x62A9 抩 (<CJK Ideograph>) 11868 0x62B0 抰 (<CJK Ideograph>) 11869 0x62B8 抸 (<CJK Ideograph>) 11870 0x653D 攽 (<CJK Ideograph>) 11871 0x65A8 斨 (<CJK Ideograph>) 11872 0x65BB 斻 (<CJK Ideograph>) 11873 0x6609 昉 (<CJK Ideograph>) 11874 0x65FC 旼 (<CJK Ideograph>) 11875 0x6604 昄 (<CJK Ideograph>) 11876 0x6612 昒 (<CJK Ideograph>) 11877 0x6608 昈 (<CJK Ideograph>) 11878 0x65FB 旻 (<CJK Ideograph>) 11879 0x6603 昃 (<CJK Ideograph>) 11880 0x660B 昋 (<CJK Ideograph>) 11881 0x660D 昍 (<CJK Ideograph>) 11882 0x6605 昅 (<CJK Ideograph>) 11883 0x65FD 旽 (<CJK Ideograph>) 11884 0x6611 昑 (<CJK Ideograph>) 11885 0x6610 昐 (<CJK Ideograph>) 11886 0x66F6 曶 (<CJK Ideograph>) 11887 0x670A 朊 (<CJK Ideograph>) 11888 0x6785 枅 (<CJK Ideograph>) 11889 0x676C 杬 (<CJK Ideograph>) 11890 0x678E 枎 (<CJK Ideograph>) 11891 0x6792 枒 (<CJK Ideograph>) 11892 0x6776 杶 (<CJK Ideograph>) 11893 0x677B 杻 (<CJK Ideograph>) 11894 0x6798 枘 (<CJK Ideograph>) 11895 0x6786 枆 (<CJK Ideograph>) 11896 0x6784 构 (<CJK Ideograph>) 11897 0x6774 杴 (<CJK Ideograph>) 11898 0x678D 枍 (<CJK Ideograph>) 11899 0x678C 枌 (<CJK Ideograph>) 11900 0x677A 杺 (<CJK Ideograph>) 11901 0x679F 枟 (<CJK Ideograph>) 11902 0x6791 枑 (<CJK Ideograph>) 11903 0x6799 枙 (<CJK Ideograph>) 11904 0x6783 枃 (<CJK Ideograph>) 11905 0x677D 杽 (<CJK Ideograph>) 11906 0x6781 极 (<CJK Ideograph>) 11907 0x6778 杸 (<CJK Ideograph>) 11908 0x6779 杹 (<CJK Ideograph>) 11909 0x6794 枔 (<CJK Ideograph>) 11910 0x6B25 欥 (<CJK Ideograph>) 11911 0x6B80 殀 (<CJK Ideograph>) 11912 0x6B7E 歾 (<CJK Ideograph>) 11913 0x6BDE 毞 (<CJK Ideograph>) 11914 0x6C1D 氝 (<CJK Ideograph>) 11915 0x6C93 沓 (<CJK Ideograph>) 11916 0x6CEC 泬 (<CJK Ideograph>) 11917 0x6CEB 泫 (<CJK Ideograph>) 11918 0x6CEE 泮 (<CJK Ideograph>) 11919 0x6CD9 泙 (<CJK Ideograph>) 11920 0x6CB6 沶 (<CJK Ideograph>) 11921 0x6CD4 泔 (<CJK Ideograph>) 11922 0x6CAD 沭 (<CJK Ideograph>) 11923 0x6CE7 泧 (<CJK Ideograph>) 11924 0x6CB7 沷 (<CJK Ideograph>) 11925 0x6CD0 泐 (<CJK Ideograph>) 11926 0x6CC2 泂 (<CJK Ideograph>) 11927 0x6CBA 沺 (<CJK Ideograph>) 11928 0x6CC3 泃 (<CJK Ideograph>) 11929 0x6CC6 泆 (<CJK Ideograph>) 11930 0x6CED 泭 (<CJK Ideograph>) 11931 0x6CF2 泲 (<CJK Ideograph>) 11932 0x6CD2 泒 (<CJK Ideograph>) 11933 0x6CDD 泝 (<CJK Ideograph>) 11934 0x6CB4 沴 (<CJK Ideograph>) 11935 0x6C8A 沊 (<CJK Ideograph>) 11936 0x6C9D 沝 (<CJK Ideograph>) 11937 0x6C80 沀 (<CJK Ideograph>) 11938 0x6CDE 泞 (<CJK Ideograph>) 11939 0x6CC0 泀 (<CJK Ideograph>) 11940 0x6D30 洰 (<CJK Ideograph>) 11941 0x6CCD 泍 (<CJK Ideograph>) 11942 0x6CC7 泇 (<CJK Ideograph>) 11943 0x6CB0 沰 (<CJK Ideograph>) 11944 0x6CF9 泹 (<CJK Ideograph>) 11945 0x6CCF 泏 (<CJK Ideograph>) 11946 0x6CE9 泩 (<CJK Ideograph>) 11947 0x6CD1 泑 (<CJK Ideograph>) 11948 0x7094 炔 (<CJK Ideograph>) 11949 0x7098 炘 (<CJK Ideograph>) 11950 0x7085 炅 (<CJK Ideograph>) 11951 0x7093 炓 (<CJK Ideograph>) 11952 0x7086 炆 (<CJK Ideograph>) 11953 0x7084 炄 (<CJK Ideograph>) 11954 0x7091 炑 (<CJK Ideograph>) 11955 0x7096 炖 (<CJK Ideograph>) 11956 0x7082 炂 (<CJK Ideograph>) 11957 0x709A 炚 (<CJK Ideograph>) 11958 0x7083 炃 (<CJK Ideograph>) 11959 0x726A 牪 (<CJK Ideograph>) 11960 0x72D6 狖 (<CJK Ideograph>) 11961 0x72CB 狋 (<CJK Ideograph>) 11962 0x72D8 狘 (<CJK Ideograph>) 11963 0x72C9 狉 (<CJK Ideograph>) 11964 0x72DC 狜 (<CJK Ideograph>) 11965 0x72D2 狒 (<CJK Ideograph>) 11966 0x72D4 狔 (<CJK Ideograph>) 11967 0x72DA 狚 (<CJK Ideograph>) 11968 0x72CC 狌 (<CJK Ideograph>) 11969 0x72D1 狑 (<CJK Ideograph>) 11970 0x73A4 玤 (<CJK Ideograph>) 11971 0x73A1 玡 (<CJK Ideograph>) 11972 0x73AD 玭 (<CJK Ideograph>) 11973 0x73A6 玦 (<CJK Ideograph>) 11974 0x73A2 玢 (<CJK Ideograph>) 11975 0x73A0 玠 (<CJK Ideograph>) 11976 0x73AC 玬 (<CJK Ideograph>) 11977 0x739D 玝 (<CJK Ideograph>) 11978 0x74DD 瓝 (<CJK Ideograph>) 11979 0x74E8 瓨 (<CJK Ideograph>) 11980 0x753F 甿 (<CJK Ideograph>) 11981 0x7540 畀 (<CJK Ideograph>) 11982 0x753E 甾 (<CJK Ideograph>) 11983 0x758C 疌 (<CJK Ideograph>) 11984 0x7598 疘 (<CJK Ideograph>) 11985 0x76AF 皯 (<CJK Ideograph>) 11986 0x76F3 盳 (<CJK Ideograph>) 11987 0x76F1 盱 (<CJK Ideograph>) 11988 0x76F0 盰 (<CJK Ideograph>) 11989 0x76F5 盵 (<CJK Ideograph>) 11990 0x77F8 矸 (<CJK Ideograph>) 11991 0x77FC 矼 (<CJK Ideograph>) 11992 0x77F9 矹 (<CJK Ideograph>) 11993 0x77FB 矻 (<CJK Ideograph>) 11994 0x77FA 矺 (<CJK Ideograph>) 11995 0x77F7 矷 (<CJK Ideograph>) 11996 0x7942 祂 (<CJK Ideograph>) 11997 0x793F 礿 (<CJK Ideograph>) 11998 0x79C5 秅 (<CJK Ideograph>) 11999 0x7A78 穸 (<CJK Ideograph>) 12000 0x7A7B 穻 (<CJK Ideograph>) 12001 0x7AFB 竻 (<CJK Ideograph>) 12002 0x7C75 籵 (<CJK Ideograph>) 12003 0x7CFD 糽 (<CJK Ideograph>) 12004 0x8035 耵 (<CJK Ideograph>) 12005 0x808F 肏 (<CJK Ideograph>) 12006 0x80AE 肮 (<CJK Ideograph>) 12007 0x80A3 肣 (<CJK Ideograph>) 12008 0x80B8 肸 (<CJK Ideograph>) 12009 0x80B5 肵 (<CJK Ideograph>) 12010 0x80AD 肭 (<CJK Ideograph>) 12011 0x8220 舠 (<CJK Ideograph>) 12012 0x82A0 芠 (<CJK Ideograph>) 12013 0x82C0 苀 (<CJK Ideograph>) 12014 0x82AB 芫 (<CJK Ideograph>) 12015 0x829A 芚 (<CJK Ideograph>) 12016 0x8298 芘 (<CJK Ideograph>) 12017 0x829B 芛 (<CJK Ideograph>) 12018 0x82B5 芵 (<CJK Ideograph>) 12019 0x82A7 芧 (<CJK Ideograph>) 12020 0x82AE 芮 (<CJK Ideograph>) 12021 0x82BC 芼 (<CJK Ideograph>) 12022 0x829E 芞 (<CJK Ideograph>) 12023 0x82BA 芺 (<CJK Ideograph>) 12024 0x82B4 芴 (<CJK Ideograph>) 12025 0x82A8 芨 (<CJK Ideograph>) 12026 0x82A1 芡 (<CJK Ideograph>) 12027 0x82A9 芩 (<CJK Ideograph>) 12028 0x82C2 苂 (<CJK Ideograph>) 12029 0x82A4 芤 (<CJK Ideograph>) 12030 0x82C3 苃 (<CJK Ideograph>) 12031 0x82B6 芶 (<CJK Ideograph>) 12032 0x82A2 芢 (<CJK Ideograph>) 12033 0x8670 虰 (<CJK Ideograph>) 12034 0x866F 虯 (<CJK Ideograph>) 12035 0x866D 虭 (<CJK Ideograph>) 12036 0x866E 虮 (<CJK Ideograph>) 12037 0x8C56 豖 (<CJK Ideograph>) 12038 0x8FD2 迒 (<CJK Ideograph>) 12039 0x8FCB 迋 (<CJK Ideograph>) 12040 0x8FD3 迓 (<CJK Ideograph>) 12041 0x8FCD 迍 (<CJK Ideograph>) 12042 0x8FD6 迖 (<CJK Ideograph>) 12043 0x8FD5 迕 (<CJK Ideograph>) 12044 0x8FD7 迗 (<CJK Ideograph>) 12045 0x90B2 邲 (<CJK Ideograph>) 12046 0x90B4 邴 (<CJK Ideograph>) 12047 0x90AF 邯 (<CJK Ideograph>) 12048 0x90B3 邳 (<CJK Ideograph>) 12049 0x90B0 邰 (<CJK Ideograph>) 12050 0x9639 阹 (<CJK Ideograph>) 12051 0x963D 阽 (<CJK Ideograph>) 12052 0x963C 阼 (<CJK Ideograph>) 12053 0x963A 阺 (<CJK Ideograph>) 12054 0x9643 陃 (<CJK Ideograph>) 12055 0x4FCD 俍 (<CJK Ideograph>) 12056 0x4FC5 俅 (<CJK Ideograph>) 12057 0x4FD3 俓 (<CJK Ideograph>) 12058 0x4FB2 侲 (<CJK Ideograph>) 12059 0x4FC9 俉 (<CJK Ideograph>) 12060 0x4FCB 俋 (<CJK Ideograph>) 12061 0x4FC1 俁 (<CJK Ideograph>) 12062 0x4FD4 俔 (<CJK Ideograph>) 12063 0x4FDC 俜 (<CJK Ideograph>) 12064 0x4FD9 俙 (<CJK Ideograph>) 12065 0x4FBB 侻 (<CJK Ideograph>) 12066 0x4FB3 侳 (<CJK Ideograph>) 12067 0x4FDB 俛 (<CJK Ideograph>) 12068 0x4FC7 俇 (<CJK Ideograph>) 12069 0x4FD6 俖 (<CJK Ideograph>) 12070 0x4FBA 侺 (<CJK Ideograph>) 12071 0x4FC0 俀 (<CJK Ideograph>) 12072 0x4FB9 侹 (<CJK Ideograph>) 12073 0x4FEC 俬 (<CJK Ideograph>) 12074 0x5244 剄 (<CJK Ideograph>) 12075 0x5249 剉 (<CJK Ideograph>) 12076 0x52C0 勀 (<CJK Ideograph>) 12077 0x52C2 勂 (<CJK Ideograph>) 12078 0x533D 匽 (<CJK Ideograph>) 12079 0x537C 卼 (<CJK Ideograph>) 12080 0x5397 厗 (<CJK Ideograph>) 12081 0x5396 厖 (<CJK Ideograph>) 12082 0x5399 厙 (<CJK Ideograph>) 12083 0x5398 厘 (<CJK Ideograph>) 12084 0x54BA 咺 (<CJK Ideograph>) 12085 0x54A1 咡 (<CJK Ideograph>) 12086 0x54AD 咭 (<CJK Ideograph>) 12087 0x54A5 咥 (<CJK Ideograph>) 12088 0x54CF 哏 (<CJK Ideograph>) 12089 0x54C3 哃 (<CJK Ideograph>) 12090 0x830D 茍 (<CJK Ideograph>) 12091 0x54B7 咷 (<CJK Ideograph>) 12092 0x54AE 咮 (<CJK Ideograph>) 12093 0x54D6 哖 (<CJK Ideograph>) 12094 0x54B6 咶 (<CJK Ideograph>) 12095 0x54C5 哅 (<CJK Ideograph>) 12096 0x54C6 哆 (<CJK Ideograph>) 12097 0x54A0 咠 (<CJK Ideograph>) 12098 0x5470 呰 (<CJK Ideograph>) 12099 0x54BC 咼 (<CJK Ideograph>) 12100 0x54A2 咢 (<CJK Ideograph>) 12101 0x54BE 咾 (<CJK Ideograph>) 12102 0x5472 呲 (<CJK Ideograph>) 12103 0x54DE 哞 (<CJK Ideograph>) 12104 0x54B0 咰 (<CJK Ideograph>) 12105 0x57B5 垵 (<CJK Ideograph>) 12106 0x579E 垞 (<CJK Ideograph>) 12107 0x579F 垟 (<CJK Ideograph>) 12108 0x57A4 垤 (<CJK Ideograph>) 12109 0x578C 垌 (<CJK Ideograph>) 12110 0x5797 垗 (<CJK Ideograph>) 12111 0x579D 垝 (<CJK Ideograph>) 12112 0x579B 垛 (<CJK Ideograph>) 12113 0x5794 垔 (<CJK Ideograph>) 12114 0x5798 垘 (<CJK Ideograph>) 12115 0x578F 垏 (<CJK Ideograph>) 12116 0x5799 垙 (<CJK Ideograph>) 12117 0x57A5 垥 (<CJK Ideograph>) 12118 0x579A 垚 (<CJK Ideograph>) 12119 0x5795 垕 (<CJK Ideograph>) 12120 0x58F4 壴 (<CJK Ideograph>) 12121 0x590D 复 (<CJK Ideograph>) 12122 0x5953 奓 (<CJK Ideograph>) 12123 0x59E1 姡 (<CJK Ideograph>) 12124 0x59DE 姞 (<CJK Ideograph>) 12125 0x59EE 姮 (<CJK Ideograph>) 12126 0x5A00 娀 (<CJK Ideograph>) 12127 0x59F1 姱 (<CJK Ideograph>) 12128 0x59DD 姝 (<CJK Ideograph>) 12129 0x59FA 姺 (<CJK Ideograph>) 12130 0x59FD 姽 (<CJK Ideograph>) 12131 0x59FC 姼 (<CJK Ideograph>) 12132 0x59F6 姶 (<CJK Ideograph>) 12133 0x59E4 姤 (<CJK Ideograph>) 12134 0x59F2 姲 (<CJK Ideograph>) 12135 0x59F7 姷 (<CJK Ideograph>) 12136 0x59DB 姛 (<CJK Ideograph>) 12137 0x59E9 姩 (<CJK Ideograph>) 12138 0x59F3 姳 (<CJK Ideograph>) 12139 0x59F5 姵 (<CJK Ideograph>) 12140 0x59E0 姠 (<CJK Ideograph>) 12141 0x59FE 姾 (<CJK Ideograph>) 12142 0x59F4 姴 (<CJK Ideograph>) 12143 0x59ED 姭 (<CJK Ideograph>) 12144 0x5BA8 宨 (<CJK Ideograph>) 12145 0x5C4C 屌 (<CJK Ideograph>) 12146 0x5CD0 峐 (<CJK Ideograph>) 12147 0x5CD8 峘 (<CJK Ideograph>) 12148 0x5CCC 峌 (<CJK Ideograph>) 12149 0x5CD7 峗 (<CJK Ideograph>) 12150 0x5CCB 峋 (<CJK Ideograph>) 12151 0x5CDB 峛 (<CJK Ideograph>) 12152 0x5CDE 峞 (<CJK Ideograph>) 12153 0x5CDA 峚 (<CJK Ideograph>) 12154 0x5CC9 峉 (<CJK Ideograph>) 12155 0x5CC7 峇 (<CJK Ideograph>) 12156 0x5CCA 峊 (<CJK Ideograph>) 12157 0x5CD6 峖 (<CJK Ideograph>) 12158 0x5CD3 峓 (<CJK Ideograph>) 12159 0x5CD4 峔 (<CJK Ideograph>) 12160 0x5CCF 峏 (<CJK Ideograph>) 12161 0x5CC8 峈 (<CJK Ideograph>) 12162 0x5CC6 峆 (<CJK Ideograph>) 12163 0x5CCE 峎 (<CJK Ideograph>) 12164 0x5CDF 峟 (<CJK Ideograph>) 12165 0x5CF8 峸 (<CJK Ideograph>) 12166 0x5DF9 巹 (<CJK Ideograph>) 12167 0x5E21 帡 (<CJK Ideograph>) 12168 0x5E22 帢 (<CJK Ideograph>) 12169 0x5E23 帣 (<CJK Ideograph>) 12170 0x5E20 帠 (<CJK Ideograph>) 12171 0x5E24 帤 (<CJK Ideograph>) 12172 0x5EB0 庰 (<CJK Ideograph>) 12173 0x5EA4 庤 (<CJK Ideograph>) 12174 0x5EA2 庢 (<CJK Ideograph>) 12175 0x5E9B 庛 (<CJK Ideograph>) 12176 0x5EA3 庣 (<CJK Ideograph>) 12177 0x5EA5 庥 (<CJK Ideograph>) 12178 0x5F07 弇 (<CJK Ideograph>) 12179 0x5F2E 弮 (<CJK Ideograph>) 12180 0x5F56 彖 (<CJK Ideograph>) 12181 0x5F86 徆 (<CJK Ideograph>) 12182 0x6037 怷 (<CJK Ideograph>) 12183 0x6039 怹 (<CJK Ideograph>) 12184 0x6054 恔 (<CJK Ideograph>) 12185 0x6072 恲 (<CJK Ideograph>) 12186 0x605E 恞 (<CJK Ideograph>) 12187 0x6045 恅 (<CJK Ideograph>) 12188 0x6053 恓 (<CJK Ideograph>) 12189 0x6047 恇 (<CJK Ideograph>) 12190 0x6049 恉 (<CJK Ideograph>) 12191 0x605B 恛 (<CJK Ideograph>) 12192 0x604C 恌 (<CJK Ideograph>) 12193 0x6040 恀 (<CJK Ideograph>) 12194 0x6042 恂 (<CJK Ideograph>) 12195 0x605F 恟 (<CJK Ideograph>) 12196 0x6024 怤 (<CJK Ideograph>) 12197 0x6044 恄 (<CJK Ideograph>) 12198 0x6058 恘 (<CJK Ideograph>) 12199 0x6066 恦 (<CJK Ideograph>) 12200 0x606E 恮 (<CJK Ideograph>) 12201 0x6242 扂 (<CJK Ideograph>) 12202 0x6243 扃 (<CJK Ideograph>) 12203 0x62CF 拏 (<CJK Ideograph>) 12204 0x630D 挍 (<CJK Ideograph>) 12205 0x630B 挋 (<CJK Ideograph>) 12206 0x62F5 拵 (<CJK Ideograph>) 12207 0x630E 挎 (<CJK Ideograph>) 12208 0x6303 挃 (<CJK Ideograph>) 12209 0x62EB 拫 (<CJK Ideograph>) 12210 0x62F9 拹 (<CJK Ideograph>) 12211 0x630F 挏 (<CJK Ideograph>) 12212 0x630C 挌 (<CJK Ideograph>) 12213 0x62F8 拸 (<CJK Ideograph>) 12214 0x62F6 拶 (<CJK Ideograph>) 12215 0x6300 挀 (<CJK Ideograph>) 12216 0x6313 挓 (<CJK Ideograph>) 12217 0x6314 挔 (<CJK Ideograph>) 12218 0x62FA 拺 (<CJK Ideograph>) 12219 0x6315 挕 (<CJK Ideograph>) 12220 0x62FB 拻 (<CJK Ideograph>) 12221 0x62F0 拰 (<CJK Ideograph>) 12222 0x6541 敁 (<CJK Ideograph>) 12223 0x6543 敃 (<CJK Ideograph>) 12224 0x65AA 斪 (<CJK Ideograph>) 12225 0x65BF 斿 (<CJK Ideograph>) 12226 0x6636 昶 (<CJK Ideograph>) 12227 0x6621 昡 (<CJK Ideograph>) 12228 0x6632 昲 (<CJK Ideograph>) 12229 0x6635 昵 (<CJK Ideograph>) 12230 0x661C 昜 (<CJK Ideograph>) 12231 0x6626 昦 (<CJK Ideograph>) 12232 0x6622 昢 (<CJK Ideograph>) 12233 0x6633 昳 (<CJK Ideograph>) 12234 0x662B 昫 (<CJK Ideograph>) 12235 0x663A 昺 (<CJK Ideograph>) 12236 0x661D 昝 (<CJK Ideograph>) 12237 0x6634 昴 (<CJK Ideograph>) 12238 0x6639 昹 (<CJK Ideograph>) 12239 0x662E 昮 (<CJK Ideograph>) 12240 0x670F 朏 (<CJK Ideograph>) 12241 0x6710 朐 (<CJK Ideograph>) 12242 0x67C1 柁 (<CJK Ideograph>) 12243 0x67F2 柲 (<CJK Ideograph>) 12244 0x67C8 柈 (<CJK Ideograph>) 12245 0x67BA 枺 (<CJK Ideograph>) 12246 0x67DC 柜 (<CJK Ideograph>) 12247 0x67BB 枻 (<CJK Ideograph>) 12248 0x67F8 柸 (<CJK Ideograph>) 12249 0x67D8 柘 (<CJK Ideograph>) 12250 0x67C0 柀 (<CJK Ideograph>) 12251 0x67B7 枷 (<CJK Ideograph>) 12252 0x67C5 柅 (<CJK Ideograph>) 12253 0x67EB 柫 (<CJK Ideograph>) 12254 0x67E4 柤 (<CJK Ideograph>) 12255 0x67DF 柟 (<CJK Ideograph>) 12256 0x67B5 枵 (<CJK Ideograph>) 12257 0x67CD 柍 (<CJK Ideograph>) 12258 0x67B3 枳 (<CJK Ideograph>) 12259 0x67F7 柷 (<CJK Ideograph>) 12260 0x67F6 柶 (<CJK Ideograph>) 12261 0x67EE 柮 (<CJK Ideograph>) 12262 0x67E3 柣 (<CJK Ideograph>) 12263 0x67C2 柂 (<CJK Ideograph>) 12264 0x67B9 枹 (<CJK Ideograph>) 12265 0x67CE 柎 (<CJK Ideograph>) 12266 0x67E7 柧 (<CJK Ideograph>) 12267 0x67F0 柰 (<CJK Ideograph>) 12268 0x67B2 枲 (<CJK Ideograph>) 12269 0x67FC 柼 (<CJK Ideograph>) 12270 0x67C6 柆 (<CJK Ideograph>) 12271 0x67ED 柭 (<CJK Ideograph>) 12272 0x67CC 柌 (<CJK Ideograph>) 12273 0x67AE 枮 (<CJK Ideograph>) 12274 0x67E6 柦 (<CJK Ideograph>) 12275 0x67DB 柛 (<CJK Ideograph>) 12276 0x67FA 柺 (<CJK Ideograph>) 12277 0x67C9 柉 (<CJK Ideograph>) 12278 0x67CA 柊 (<CJK Ideograph>) 12279 0x67C3 柃 (<CJK Ideograph>) 12280 0x67EA 柪 (<CJK Ideograph>) 12281 0x67CB 柋 (<CJK Ideograph>) 12282 0x6B28 欨 (<CJK Ideograph>) 12283 0x6B82 殂 (<CJK Ideograph>) 12284 0x6B84 殄 (<CJK Ideograph>) 12285 0x6BB6 殶 (<CJK Ideograph>) 12286 0x6BD6 毖 (<CJK Ideograph>) 12287 0x6BD8 毘 (<CJK Ideograph>) 12288 0x6BE0 毠 (<CJK Ideograph>) 12289 0x6C20 氠 (<CJK Ideograph>) 12290 0x6C21 氡 (<CJK Ideograph>) 12291 0x6D28 洨 (<CJK Ideograph>) 12292 0x6D34 洴 (<CJK Ideograph>) 12293 0x6D2D 洭 (<CJK Ideograph>) 12294 0x6D1F 洟 (<CJK Ideograph>) 12295 0x6D3C 洼 (<CJK Ideograph>) 12296 0x6D3F 洿 (<CJK Ideograph>) 12297 0x6D12 洒 (<CJK Ideograph>) 12298 0x6D0A 洊 (<CJK Ideograph>) 12299 0x6CDA 泚 (<CJK Ideograph>) 12300 0x6D33 洳 (<CJK Ideograph>) 12301 0x6D04 洄 (<CJK Ideograph>) 12302 0x6D19 洙 (<CJK Ideograph>) 12303 0x6D3A 洺 (<CJK Ideograph>) 12304 0x6D1A 洚 (<CJK Ideograph>) 12305 0x6D11 洑 (<CJK Ideograph>) 12306 0x6D00 洀 (<CJK Ideograph>) 12307 0x6D1D 洝 (<CJK Ideograph>) 12308 0x6D42 浂 (<CJK Ideograph>) 12309 0x6D01 洁 (<CJK Ideograph>) 12310 0x6D18 洘 (<CJK Ideograph>) 12311 0x6D37 洷 (<CJK Ideograph>) 12312 0x6D03 洃 (<CJK Ideograph>) 12313 0x6D0F 洏 (<CJK Ideograph>) 12314 0x6D40 浀 (<CJK Ideograph>) 12315 0x6D07 洇 (<CJK Ideograph>) 12316 0x6D20 洠 (<CJK Ideograph>) 12317 0x6D2C 洬 (<CJK Ideograph>) 12318 0x6D08 洈 (<CJK Ideograph>) 12319 0x6D22 洢 (<CJK Ideograph>) 12320 0x6D09 洉 (<CJK Ideograph>) 12321 0x6D10 洐 (<CJK Ideograph>) 12322 0x70B7 炷 (<CJK Ideograph>) 12323 0x709F 炟 (<CJK Ideograph>) 12324 0x70BE 炾 (<CJK Ideograph>) 12325 0x70B1 炱 (<CJK Ideograph>) 12326 0x70B0 炰 (<CJK Ideograph>) 12327 0x70A1 炡 (<CJK Ideograph>) 12328 0x70B4 炴 (<CJK Ideograph>) 12329 0x70B5 炵 (<CJK Ideograph>) 12330 0x70A9 炩 (<CJK Ideograph>) 12331 0x7241 牁 (<CJK Ideograph>) 12332 0x7249 牉 (<CJK Ideograph>) 12333 0x724A 牊 (<CJK Ideograph>) 12334 0x726C 牬 (<CJK Ideograph>) 12335 0x7270 牰 (<CJK Ideograph>) 12336 0x7273 牳 (<CJK Ideograph>) 12337 0x726E 牮 (<CJK Ideograph>) 12338 0x72CA 狊 (<CJK Ideograph>) 12339 0x72E4 狤 (<CJK Ideograph>) 12340 0x72E8 狨 (<CJK Ideograph>) 12341 0x72EB 狫 (<CJK Ideograph>) 12342 0x72DF 狟 (<CJK Ideograph>) 12343 0x72EA 狪 (<CJK Ideograph>) 12344 0x72E6 狦 (<CJK Ideograph>) 12345 0x72E3 狣 (<CJK Ideograph>) 12346 0x7385 玅 (<CJK Ideograph>) 12347 0x73CC 珌 (<CJK Ideograph>) 12348 0x73C2 珂 (<CJK Ideograph>) 12349 0x73C8 珈 (<CJK Ideograph>) 12350 0x73C5 珅 (<CJK Ideograph>) 12351 0x73B9 玹 (<CJK Ideograph>) 12352 0x73B6 玶 (<CJK Ideograph>) 12353 0x73B5 玵 (<CJK Ideograph>) 12354 0x73B4 玴 (<CJK Ideograph>) 12355 0x73EB 珫 (<CJK Ideograph>) 12356 0x73BF 玿 (<CJK Ideograph>) 12357 0x73C7 珇 (<CJK Ideograph>) 12358 0x73BE 玾 (<CJK Ideograph>) 12359 0x73C3 珃 (<CJK Ideograph>) 12360 0x73C6 珆 (<CJK Ideograph>) 12361 0x73B8 玸 (<CJK Ideograph>) 12362 0x73CB 珋 (<CJK Ideograph>) 12363 0x74EC 瓬 (<CJK Ideograph>) 12364 0x74EE 瓮 (<CJK Ideograph>) 12365 0x752E 甮 (<CJK Ideograph>) 12366 0x7547 畇 (<CJK Ideograph>) 12367 0x7548 畈 (<CJK Ideograph>) 12368 0x75A7 疧 (<CJK Ideograph>) 12369 0x75AA 疪 (<CJK Ideograph>) 12370 0x7679 癹 (<CJK Ideograph>) 12371 0x76C4 盄 (<CJK Ideograph>) 12372 0x7708 眈 (<CJK Ideograph>) 12373 0x7703 眃 (<CJK Ideograph>) 12374 0x7704 眄 (<CJK Ideograph>) 12375 0x7705 眅 (<CJK Ideograph>) 12376 0x770A 眊 (<CJK Ideograph>) 12377 0x76F7 盷 (<CJK Ideograph>) 12378 0x76FB 盻 (<CJK Ideograph>) 12379 0x76FA 盺 (<CJK Ideograph>) 12380 0x77E7 矧 (<CJK Ideograph>) 12381 0x77E8 矨 (<CJK Ideograph>) 12382 0x7806 砆 (<CJK Ideograph>) 12383 0x7811 砑 (<CJK Ideograph>) 12384 0x7812 砒 (<CJK Ideograph>) 12385 0x7805 砅 (<CJK Ideograph>) 12386 0x7810 砐 (<CJK Ideograph>) 12387 0x780F 砏 (<CJK Ideograph>) 12388 0x780E 砎 (<CJK Ideograph>) 12389 0x7809 砉 (<CJK Ideograph>) 12390 0x7803 砃 (<CJK Ideograph>) 12391 0x7813 砓 (<CJK Ideograph>) 12392 0x794A 祊 (<CJK Ideograph>) 12393 0x794C 祌 (<CJK Ideograph>) 12394 0x794B 祋 (<CJK Ideograph>) 12395 0x7945 祅 (<CJK Ideograph>) 12396 0x7944 祄 (<CJK Ideograph>) 12397 0x79D5 秕 (<CJK Ideograph>) 12398 0x79CD 种 (<CJK Ideograph>) 12399 0x79CF 秏 (<CJK Ideograph>) 12400 0x79D6 秖 (<CJK Ideograph>) 12401 0x79CE 秎 (<CJK Ideograph>) 12402 0x7A80 窀 (<CJK Ideograph>) 12403 0x7A7E 穾 (<CJK Ideograph>) 12404 0x7AD1 竑 (<CJK Ideograph>) 12405 0x7B00 笀 (<CJK Ideograph>) 12406 0x7B01 笁 (<CJK Ideograph>) 12407 0x7C7A 籺 (<CJK Ideograph>) 12408 0x7C78 籸 (<CJK Ideograph>) 12409 0x7C79 籹 (<CJK Ideograph>) 12410 0x7C7F 籿 (<CJK Ideograph>) 12411 0x7C80 粀 (<CJK Ideograph>) 12412 0x7C81 粁 (<CJK Ideograph>) 12413 0x7D03 紃 (<CJK Ideograph>) 12414 0x7D08 紈 (<CJK Ideograph>) 12415 0x7D01 紁 (<CJK Ideograph>) 12416 0x7F58 罘 (<CJK Ideograph>) 12417 0x7F91 羑 (<CJK Ideograph>) 12418 0x7F8D 羍 (<CJK Ideograph>) 12419 0x7FBE 羾 (<CJK Ideograph>) 12420 0x8007 耇 (<CJK Ideograph>) 12421 0x800E 耎 (<CJK Ideograph>) 12422 0x800F 耏 (<CJK Ideograph>) 12423 0x8014 耔 (<CJK Ideograph>) 12424 0x8037 耷 (<CJK Ideograph>) 12425 0x80D8 胘 (<CJK Ideograph>) 12426 0x80C7 胇 (<CJK Ideograph>) 12427 0x80E0 胠 (<CJK Ideograph>) 12428 0x80D1 胑 (<CJK Ideograph>) 12429 0x80C8 胈 (<CJK Ideograph>) 12430 0x80C2 胂 (<CJK Ideograph>) 12431 0x80D0 胐 (<CJK Ideograph>) 12432 0x80C5 胅 (<CJK Ideograph>) 12433 0x80E3 胣 (<CJK Ideograph>) 12434 0x80D9 胙 (<CJK Ideograph>) 12435 0x80DC 胜 (<CJK Ideograph>) 12436 0x80CA 胊 (<CJK Ideograph>) 12437 0x80D5 胕 (<CJK Ideograph>) 12438 0x80C9 胉 (<CJK Ideograph>) 12439 0x80CF 胏 (<CJK Ideograph>) 12440 0x80D7 胗 (<CJK Ideograph>) 12441 0x80E6 胦 (<CJK Ideograph>) 12442 0x80CD 胍 (<CJK Ideograph>) 12443 0x81FF 臿 (<CJK Ideograph>) 12444 0x8221 舡 (<CJK Ideograph>) 12445 0x8294 芔 (<CJK Ideograph>) 12446 0x82D9 苙 (<CJK Ideograph>) 12447 0x82FE 苾 (<CJK Ideograph>) 12448 0x82F9 苹 (<CJK Ideograph>) 12449 0x8307 茇 (<CJK Ideograph>) 12450 0x82E8 苨 (<CJK Ideograph>) 12451 0x8300 茀 (<CJK Ideograph>) 12452 0x82D5 苕 (<CJK Ideograph>) 12453 0x833A 茺 (<CJK Ideograph>) 12454 0x82EB 苫 (<CJK Ideograph>) 12455 0x82D6 苖 (<CJK Ideograph>) 12456 0x82F4 苴 (<CJK Ideograph>) 12457 0x82EC 苬 (<CJK Ideograph>) 12458 0x82E1 苡 (<CJK Ideograph>) 12459 0x82F2 苲 (<CJK Ideograph>) 12460 0x82F5 苵 (<CJK Ideograph>) 12461 0x830C 茌 (<CJK Ideograph>) 12462 0x82FB 苻 (<CJK Ideograph>) 12463 0x82F6 苶 (<CJK Ideograph>) 12464 0x82F0 苰 (<CJK Ideograph>) 12465 0x82EA 苪 (<CJK Ideograph>) 12466 0x82E4 苤 (<CJK Ideograph>) 12467 0x82E0 苠 (<CJK Ideograph>) 12468 0x82FA 苺 (<CJK Ideograph>) 12469 0x82F3 苳 (<CJK Ideograph>) 12470 0x82ED 苭 (<CJK Ideograph>) 12471 0x8677 虷 (<CJK Ideograph>) 12472 0x8674 虴 (<CJK Ideograph>) 12473 0x867C 虼 (<CJK Ideograph>) 12474 0x8673 虳 (<CJK Ideograph>) 12475 0x8841 衁 (<CJK Ideograph>) 12476 0x884E 衎 (<CJK Ideograph>) 12477 0x8867 衧 (<CJK Ideograph>) 12478 0x886A 衪 (<CJK Ideograph>) 12479 0x8869 衩 (<CJK Ideograph>) 12480 0x89D3 觓 (<CJK Ideograph>) 12481 0x8A04 訄 (<CJK Ideograph>) 12482 0x8A07 訇 (<CJK Ideograph>) 12483 0x8D72 赲 (<CJK Ideograph>) 12484 0x8FE3 迣 (<CJK Ideograph>) 12485 0x8FE1 迡 (<CJK Ideograph>) 12486 0x8FEE 迮 (<CJK Ideograph>) 12487 0x8FE0 迠 (<CJK Ideograph>) 12488 0x90F1 郱 (<CJK Ideograph>) 12489 0x90BD 邽 (<CJK Ideograph>) 12490 0x90BF 邿 (<CJK Ideograph>) 12491 0x90D5 郕 (<CJK Ideograph>) 12492 0x90C5 郅 (<CJK Ideograph>) 12493 0x90BE 邾 (<CJK Ideograph>) 12494 0x90C7 郇 (<CJK Ideograph>) 12495 0x90CB 郋 (<CJK Ideograph>) 12496 0x90C8 郈 (<CJK Ideograph>) 12497 0x91D4 釔 (<CJK Ideograph>) 12498 0x91D3 釓 (<CJK Ideograph>) 12499 0x9654 陔 (<CJK Ideograph>) 12500 0x964F 陏 (<CJK Ideograph>) 12501 0x9651 陑 (<CJK Ideograph>) 12502 0x9653 陓 (<CJK Ideograph>) 12503 0x964A 陊 (<CJK Ideograph>) 12504 0x964E 陎 (<CJK Ideograph>) 12505 0x501E 倞 (<CJK Ideograph>) 12506 0x5005 倅 (<CJK Ideograph>) 12507 0x5007 倇 (<CJK Ideograph>) 12508 0x5013 倓 (<CJK Ideograph>) 12509 0x5022 倢 (<CJK Ideograph>) 12510 0x5030 倰 (<CJK Ideograph>) 12511 0x501B 倛 (<CJK Ideograph>) 12512 0x4FF5 俵 (<CJK Ideograph>) 12513 0x4FF4 俴 (<CJK Ideograph>) 12514 0x5033 倳 (<CJK Ideograph>) 12515 0x5037 倷 (<CJK Ideograph>) 12516 0x502C 倬 (<CJK Ideograph>) 12517 0x4FF6 俶 (<CJK Ideograph>) 12518 0x4FF7 俷 (<CJK Ideograph>) 12519 0x5017 倗 (<CJK Ideograph>) 12520 0x501C 倜 (<CJK Ideograph>) 12521 0x5020 倠 (<CJK Ideograph>) 12522 0x5027 倧 (<CJK Ideograph>) 12523 0x5035 倵 (<CJK Ideograph>) 12524 0x502F 倯 (<CJK Ideograph>) 12525 0x5031 倱 (<CJK Ideograph>) 12526 0x500E 倎 (<CJK Ideograph>) 12527 0x515A 党 (<CJK Ideograph>) 12528 0x5194 冔 (<CJK Ideograph>) 12529 0x5193 冓 (<CJK Ideograph>) 12530 0x51CA 凊 (<CJK Ideograph>) 12531 0x51C4 凄 (<CJK Ideograph>) 12532 0x51C5 凅 (<CJK Ideograph>) 12533 0x51C8 凈 (<CJK Ideograph>) 12534 0x51CE 凎 (<CJK Ideograph>) 12535 0x5261 剡 (<CJK Ideograph>) 12536 0x525A 剚 (<CJK Ideograph>) 12537 0x5252 剒 (<CJK Ideograph>) 12538 0x525E 剞 (<CJK Ideograph>) 12539 0x525F 剟 (<CJK Ideograph>) 12540 0x5255 剕 (<CJK Ideograph>) 12541 0x5262 剢 (<CJK Ideograph>) 12542 0x52CD 勍 (<CJK Ideograph>) 12543 0x530E 匎 (<CJK Ideograph>) 12544 0x539E 厞 (<CJK Ideograph>) 12545 0x5526 唦 (<CJK Ideograph>) 12546 0x54E2 哢 (<CJK Ideograph>) 12547 0x5517 唗 (<CJK Ideograph>) 12548 0x5512 唒 (<CJK Ideograph>) 12549 0x54E7 哧 (<CJK Ideograph>) 12550 0x54F3 哳 (<CJK Ideograph>) 12551 0x54E4 哤 (<CJK Ideograph>) 12552 0x551A 唚 (<CJK Ideograph>) 12553 0x54FF 哿 (<CJK Ideograph>) 12554 0x5504 唄 (<CJK Ideograph>) 12555 0x5508 唈 (<CJK Ideograph>) 12556 0x54EB 哫 (<CJK Ideograph>) 12557 0x5511 唑 (<CJK Ideograph>) 12558 0x5505 唅 (<CJK Ideograph>) 12559 0x54F1 哱 (<CJK Ideograph>) 12560 0x550A 唊 (<CJK Ideograph>) 12561 0x54FB 哻 (<CJK Ideograph>) 12562 0x54F7 哷 (<CJK Ideograph>) 12563 0x54F8 哸 (<CJK Ideograph>) 12564 0x54E0 哠 (<CJK Ideograph>) 12565 0x550E 唎 (<CJK Ideograph>) 12566 0x5503 唃 (<CJK Ideograph>) 12567 0x550B 唋 (<CJK Ideograph>) 12568 0x5701 圁 (<CJK Ideograph>) 12569 0x5702 圂 (<CJK Ideograph>) 12570 0x57CC 埌 (<CJK Ideograph>) 12571 0x5832 堲 (<CJK Ideograph>) 12572 0x57D5 埕 (<CJK Ideograph>) 12573 0x57D2 埒 (<CJK Ideograph>) 12574 0x57BA 垺 (<CJK Ideograph>) 12575 0x57C6 埆 (<CJK Ideograph>) 12576 0x57BD 垽 (<CJK Ideograph>) 12577 0x57BC 垼 (<CJK Ideograph>) 12578 0x57B8 垸 (<CJK Ideograph>) 12579 0x57B6 垶 (<CJK Ideograph>) 12580 0x57BF 垿 (<CJK Ideograph>) 12581 0x57C7 埇 (<CJK Ideograph>) 12582 0x57D0 埐 (<CJK Ideograph>) 12583 0x57B9 垹 (<CJK Ideograph>) 12584 0x57C1 埁 (<CJK Ideograph>) 12585 0x590E 夎 (<CJK Ideograph>) 12586 0x594A 奊 (<CJK Ideograph>) 12587 0x5A19 娙 (<CJK Ideograph>) 12588 0x5A16 娖 (<CJK Ideograph>) 12589 0x5A2D 娭 (<CJK Ideograph>) 12590 0x5A2E 娮 (<CJK Ideograph>) 12591 0x5A15 娕 (<CJK Ideograph>) 12592 0x5A0F 娏 (<CJK Ideograph>) 12593 0x5A17 娗 (<CJK Ideograph>) 12594 0x5A0A 娊 (<CJK Ideograph>) 12595 0x5A1E 娞 (<CJK Ideograph>) 12596 0x5A33 娳 (<CJK Ideograph>) 12597 0x5B6C 孬 (<CJK Ideograph>) 12598 0x5BA7 宧 (<CJK Ideograph>) 12599 0x5BAD 宭 (<CJK Ideograph>) 12600 0x5BAC 宬 (<CJK Ideograph>) 12601 0x5C03 尃 (<CJK Ideograph>) 12602 0x5C56 屖 (<CJK Ideograph>) 12603 0x5C54 屔 (<CJK Ideograph>) 12604 0x5CEC 峬 (<CJK Ideograph>) 12605 0x5CFF 峿 (<CJK Ideograph>) 12606 0x5CEE 峮 (<CJK Ideograph>) 12607 0x5CF1 峱 (<CJK Ideograph>) 12608 0x5CF7 峷 (<CJK Ideograph>) 12609 0x5D00 崀 (<CJK Ideograph>) 12610 0x5CF9 峹 (<CJK Ideograph>) 12611 0x5E29 帩 (<CJK Ideograph>) 12612 0x5E28 帨 (<CJK Ideograph>) 12613 0x5EA8 庨 (<CJK Ideograph>) 12614 0x5EAE 庮 (<CJK Ideograph>) 12615 0x5EAA 庪 (<CJK Ideograph>) 12616 0x5EAC 庬 (<CJK Ideograph>) 12617 0x5F33 弳 (<CJK Ideograph>) 12618 0x5F30 弰 (<CJK Ideograph>) 12619 0x5F67 彧 (<CJK Ideograph>) 12620 0x605D 恝 (<CJK Ideograph>) 12621 0x605A 恚 (<CJK Ideograph>) 12622 0x6067 恧 (<CJK Ideograph>) 12623 0x6041 恁 (<CJK Ideograph>) 12624 0x60A2 悢 (<CJK Ideograph>) 12625 0x6088 悈 (<CJK Ideograph>) 12626 0x6080 悀 (<CJK Ideograph>) 12627 0x6092 悒 (<CJK Ideograph>) 12628 0x6081 悁 (<CJK Ideograph>) 12629 0x609D 悝 (<CJK Ideograph>) 12630 0x6083 悃 (<CJK Ideograph>) 12631 0x6095 悕 (<CJK Ideograph>) 12632 0x609B 悛 (<CJK Ideograph>) 12633 0x6097 悗 (<CJK Ideograph>) 12634 0x6087 悇 (<CJK Ideograph>) 12635 0x609C 悜 (<CJK Ideograph>) 12636 0x608E 悎 (<CJK Ideograph>) 12637 0x6219 戙 (<CJK Ideograph>) 12638 0x6246 扆 (<CJK Ideograph>) 12639 0x62F2 拲 (<CJK Ideograph>) 12640 0x6310 挐 (<CJK Ideograph>) 12641 0x6356 捖 (<CJK Ideograph>) 12642 0x632C 挬 (<CJK Ideograph>) 12643 0x6344 捄 (<CJK Ideograph>) 12644 0x6345 捅 (<CJK Ideograph>) 12645 0x6336 挶 (<CJK Ideograph>) 12646 0x6343 捃 (<CJK Ideograph>) 12647 0x63E4 揤 (<CJK Ideograph>) 12648 0x6339 挹 (<CJK Ideograph>) 12649 0x634B 捋 (<CJK Ideograph>) 12650 0x634A 捊 (<CJK Ideograph>) 12651 0x633C 挼 (<CJK Ideograph>) 12652 0x6329 挩 (<CJK Ideograph>) 12653 0x6341 捁 (<CJK Ideograph>) 12654 0x6334 挴 (<CJK Ideograph>) 12655 0x6358 捘 (<CJK Ideograph>) 12656 0x6354 捔 (<CJK Ideograph>) 12657 0x6359 捙 (<CJK Ideograph>) 12658 0x632D 挭 (<CJK Ideograph>) 12659 0x6347 捇 (<CJK Ideograph>) 12660 0x6333 挳 (<CJK Ideograph>) 12661 0x635A 捚 (<CJK Ideograph>) 12662 0x6351 捑 (<CJK Ideograph>) 12663 0x6338 挸 (<CJK Ideograph>) 12664 0x6357 捗 (<CJK Ideograph>) 12665 0x6340 捀 (<CJK Ideograph>) 12666 0x6348 捈 (<CJK Ideograph>) 12667 0x654A 敊 (<CJK Ideograph>) 12668 0x6546 敆 (<CJK Ideograph>) 12669 0x65C6 旆 (<CJK Ideograph>) 12670 0x65C3 旃 (<CJK Ideograph>) 12671 0x65C4 旄 (<CJK Ideograph>) 12672 0x65C2 旂 (<CJK Ideograph>) 12673 0x664A 晊 (<CJK Ideograph>) 12674 0x665F 晟 (<CJK Ideograph>) 12675 0x6647 晇 (<CJK Ideograph>) 12676 0x6651 晑 (<CJK Ideograph>) 12677 0x6712 朒 (<CJK Ideograph>) 12678 0x6713 朓 (<CJK Ideograph>) 12679 0x681F 栟 (<CJK Ideograph>) 12680 0x681A 栚 (<CJK Ideograph>) 12681 0x6849 桉 (<CJK Ideograph>) 12682 0x6832 栲 (<CJK Ideograph>) 12683 0x6833 栳 (<CJK Ideograph>) 12684 0x683B 栻 (<CJK Ideograph>) 12685 0x684B 桋 (<CJK Ideograph>) 12686 0x684F 桏 (<CJK Ideograph>) 12687 0x6816 栖 (<CJK Ideograph>) 12688 0x6831 栱 (<CJK Ideograph>) 12689 0x681C 栜 (<CJK Ideograph>) 12690 0x6835 栵 (<CJK Ideograph>) 12691 0x682B 栫 (<CJK Ideograph>) 12692 0x682D 栭 (<CJK Ideograph>) 12693 0x682F 栯 (<CJK Ideograph>) 12694 0x684E 桎 (<CJK Ideograph>) 12695 0x6844 桄 (<CJK Ideograph>) 12696 0x6834 栴 (<CJK Ideograph>) 12697 0x681D 栝 (<CJK Ideograph>) 12698 0x6812 栒 (<CJK Ideograph>) 12699 0x6814 栔 (<CJK Ideograph>) 12700 0x6826 栦 (<CJK Ideograph>) 12701 0x6828 栨 (<CJK Ideograph>) 12702 0x682E 栮 (<CJK Ideograph>) 12703 0x684D 桍 (<CJK Ideograph>) 12704 0x683A 栺 (<CJK Ideograph>) 12705 0x6825 栥 (<CJK Ideograph>) 12706 0x6820 栠 (<CJK Ideograph>) 12707 0x6B2C 欬 (<CJK Ideograph>) 12708 0x6B2F 欯 (<CJK Ideograph>) 12709 0x6B2D 欭 (<CJK Ideograph>) 12710 0x6B31 欱 (<CJK Ideograph>) 12711 0x6B34 欴 (<CJK Ideograph>) 12712 0x6B6D 歭 (<CJK Ideograph>) 12713 0x8082 肂 (<CJK Ideograph>) 12714 0x6B88 殈 (<CJK Ideograph>) 12715 0x6BE6 毦 (<CJK Ideograph>) 12716 0x6BE4 毤 (<CJK Ideograph>) 12717 0x6BE8 毨 (<CJK Ideograph>) 12718 0x6BE3 毣 (<CJK Ideograph>) 12719 0x6BE2 毢 (<CJK Ideograph>) 12720 0x6BE7 毧 (<CJK Ideograph>) 12721 0x6C25 氥 (<CJK Ideograph>) 12722 0x6D7A 浺 (<CJK Ideograph>) 12723 0x6D63 浣 (<CJK Ideograph>) 12724 0x6D64 浤 (<CJK Ideograph>) 12725 0x6D76 浶 (<CJK Ideograph>) 12726 0x6D0D 洍 (<CJK Ideograph>) 12727 0x6D61 浡 (<CJK Ideograph>) 12728 0x6D92 涒 (<CJK Ideograph>) 12729 0x6D58 浘 (<CJK Ideograph>) 12730 0x6D62 浢 (<CJK Ideograph>) 12731 0x6D6D 浭 (<CJK Ideograph>) 12732 0x6D6F 浯 (<CJK Ideograph>) 12733 0x6D91 涑 (<CJK Ideograph>) 12734 0x6D8D 涍 (<CJK Ideograph>) 12735 0x6DEF 淯 (<CJK Ideograph>) 12736 0x6D7F 浿 (<CJK Ideograph>) 12737 0x6D86 涆 (<CJK Ideograph>) 12738 0x6D5E 浞 (<CJK Ideograph>) 12739 0x6D67 浧 (<CJK Ideograph>) 12740 0x6D60 浠 (<CJK Ideograph>) 12741 0x6D97 涗 (<CJK Ideograph>) 12742 0x6D70 浰 (<CJK Ideograph>) 12743 0x6D7C 浼 (<CJK Ideograph>) 12744 0x6D5F 浟 (<CJK Ideograph>) 12745 0x6D82 涂 (<CJK Ideograph>) 12746 0x6D98 涘 (<CJK Ideograph>) 12747 0x6D2F 洯 (<CJK Ideograph>) 12748 0x6D68 浨 (<CJK Ideograph>) 12749 0x6D8B 涋 (<CJK Ideograph>) 12750 0x6D7E 浾 (<CJK Ideograph>) 12751 0x6D80 涀 (<CJK Ideograph>) 12752 0x6D84 涄 (<CJK Ideograph>) 12753 0x6D16 洖 (<CJK Ideograph>) 12754 0x6D83 涃 (<CJK Ideograph>) 12755 0x6D7B 浻 (<CJK Ideograph>) 12756 0x6D7D 浽 (<CJK Ideograph>) 12757 0x6D75 浵 (<CJK Ideograph>) 12758 0x6D90 涐 (<CJK Ideograph>) 12759 0x70DC 烜 (<CJK Ideograph>) 12760 0x70D3 烓 (<CJK Ideograph>) 12761 0x70D1 烑 (<CJK Ideograph>) 12762 0x70DD 烝 (<CJK Ideograph>) 12763 0x70CB 烋 (<CJK Ideograph>) 12764 0x7F39 缹 (<CJK Ideograph>) 12765 0x70E2 烢 (<CJK Ideograph>) 12766 0x70D7 烗 (<CJK Ideograph>) 12767 0x70D2 烒 (<CJK Ideograph>) 12768 0x70DE 烞 (<CJK Ideograph>) 12769 0x70E0 烠 (<CJK Ideograph>) 12770 0x70D4 烔 (<CJK Ideograph>) 12771 0x70CD 烍 (<CJK Ideograph>) 12772 0x70C5 烅 (<CJK Ideograph>) 12773 0x70C6 烆 (<CJK Ideograph>) 12774 0x70C7 烇 (<CJK Ideograph>) 12775 0x70DA 烚 (<CJK Ideograph>) 12776 0x70CE 烎 (<CJK Ideograph>) 12777 0x70E1 烡 (<CJK Ideograph>) 12778 0x7242 牂 (<CJK Ideograph>) 12779 0x7278 牸 (<CJK Ideograph>) 12780 0x7277 牷 (<CJK Ideograph>) 12781 0x7276 牶 (<CJK Ideograph>) 12782 0x7300 猀 (<CJK Ideograph>) 12783 0x72FA 狺 (<CJK Ideograph>) 12784 0x72F4 狴 (<CJK Ideograph>) 12785 0x72FE 狾 (<CJK Ideograph>) 12786 0x72F6 狶 (<CJK Ideograph>) 12787 0x72F3 狳 (<CJK Ideograph>) 12788 0x72FB 狻 (<CJK Ideograph>) 12789 0x7301 猁 (<CJK Ideograph>) 12790 0x73D3 珓 (<CJK Ideograph>) 12791 0x73D9 珙 (<CJK Ideograph>) 12792 0x73E5 珥 (<CJK Ideograph>) 12793 0x73D6 珖 (<CJK Ideograph>) 12794 0x73BC 玼 (<CJK Ideograph>) 12795 0x73E7 珧 (<CJK Ideograph>) 12796 0x73E3 珣 (<CJK Ideograph>) 12797 0x73E9 珩 (<CJK Ideograph>) 12798 0x73DC 珜 (<CJK Ideograph>) 12799 0x73D2 珒 (<CJK Ideograph>) 12800 0x73DB 珛 (<CJK Ideograph>) 12801 0x73D4 珔 (<CJK Ideograph>) 12802 0x73DD 珝 (<CJK Ideograph>) 12803 0x73DA 珚 (<CJK Ideograph>) 12804 0x73D7 珗 (<CJK Ideograph>) 12805 0x73D8 珘 (<CJK Ideograph>) 12806 0x73E8 珨 (<CJK Ideograph>) 12807 0x74DE 瓞 (<CJK Ideograph>) 12808 0x74DF 瓟 (<CJK Ideograph>) 12809 0x74F4 瓴 (<CJK Ideograph>) 12810 0x74F5 瓵 (<CJK Ideograph>) 12811 0x7521 甡 (<CJK Ideograph>) 12812 0x755B 畛 (<CJK Ideograph>) 12813 0x755F 畟 (<CJK Ideograph>) 12814 0x75B0 疰 (<CJK Ideograph>) 12815 0x75C1 痁 (<CJK Ideograph>) 12816 0x75BB 疻 (<CJK Ideograph>) 12817 0x75C4 痄 (<CJK Ideograph>) 12818 0x75C0 痀 (<CJK Ideograph>) 12819 0x75BF 疿 (<CJK Ideograph>) 12820 0x75B6 疶 (<CJK Ideograph>) 12821 0x75BA 疺 (<CJK Ideograph>) 12822 0x768A 皊 (<CJK Ideograph>) 12823 0x76C9 盉 (<CJK Ideograph>) 12824 0x771D 眝 (<CJK Ideograph>) 12825 0x771B 眛 (<CJK Ideograph>) 12826 0x7710 眐 (<CJK Ideograph>) 12827 0x7713 眓 (<CJK Ideograph>) 12828 0x7712 眒 (<CJK Ideograph>) 12829 0x7723 眣 (<CJK Ideograph>) 12830 0x7711 眑 (<CJK Ideograph>) 12831 0x7715 眕 (<CJK Ideograph>) 12832 0x7719 眙 (<CJK Ideograph>) 12833 0x771A 眚 (<CJK Ideograph>) 12834 0x7722 眢 (<CJK Ideograph>) 12835 0x7727 眧 (<CJK Ideograph>) 12836 0x7823 砣 (<CJK Ideograph>) 12837 0x782C 砬 (<CJK Ideograph>) 12838 0x7822 砢 (<CJK Ideograph>) 12839 0x7835 砵 (<CJK Ideograph>) 12840 0x782F 砯 (<CJK Ideograph>) 12841 0x7828 砨 (<CJK Ideograph>) 12842 0x782E 砮 (<CJK Ideograph>) 12843 0x782B 砫 (<CJK Ideograph>) 12844 0x7821 砡 (<CJK Ideograph>) 12845 0x7829 砩 (<CJK Ideograph>) 12846 0x7833 砳 (<CJK Ideograph>) 12847 0x782A 砪 (<CJK Ideograph>) 12848 0x7831 砱 (<CJK Ideograph>) 12849 0x7954 祔 (<CJK Ideograph>) 12850 0x795B 祛 (<CJK Ideograph>) 12851 0x794F 祏 (<CJK Ideograph>) 12852 0x795C 祜 (<CJK Ideograph>) 12853 0x7953 祓 (<CJK Ideograph>) 12854 0x7952 祒 (<CJK Ideograph>) 12855 0x7951 祑 (<CJK Ideograph>) 12856 0x79EB 秫 (<CJK Ideograph>) 12857 0x79EC 秬 (<CJK Ideograph>) 12858 0x79E0 秠 (<CJK Ideograph>) 12859 0x79EE 秮 (<CJK Ideograph>) 12860 0x79ED 秭 (<CJK Ideograph>) 12861 0x79EA 秪 (<CJK Ideograph>) 12862 0x79DC 秜 (<CJK Ideograph>) 12863 0x79DE 秞 (<CJK Ideograph>) 12864 0x79DD 秝 (<CJK Ideograph>) 12865 0x7A86 窆 (<CJK Ideograph>) 12866 0x7A89 窉 (<CJK Ideograph>) 12867 0x7A85 窅 (<CJK Ideograph>) 12868 0x7A8B 窋 (<CJK Ideograph>) 12869 0x7A8C 窌 (<CJK Ideograph>) 12870 0x7A8A 窊 (<CJK Ideograph>) 12871 0x7A87 窇 (<CJK Ideograph>) 12872 0x7AD8 竘 (<CJK Ideograph>) 12873 0x7B10 笐 (<CJK Ideograph>) 12874 0x7B04 笄 (<CJK Ideograph>) 12875 0x7B13 笓 (<CJK Ideograph>) 12876 0x7B05 笅 (<CJK Ideograph>) 12877 0x7B0F 笏 (<CJK Ideograph>) 12878 0x7B08 笈 (<CJK Ideograph>) 12879 0x7B0A 笊 (<CJK Ideograph>) 12880 0x7B0E 笎 (<CJK Ideograph>) 12881 0x7B09 笉 (<CJK Ideograph>) 12882 0x7B12 笒 (<CJK Ideograph>) 12883 0x7C84 粄 (<CJK Ideograph>) 12884 0x7C91 粑 (<CJK Ideograph>) 12885 0x7C8A 粊 (<CJK Ideograph>) 12886 0x7C8C 粌 (<CJK Ideograph>) 12887 0x7C88 粈 (<CJK Ideograph>) 12888 0x7C8D 粍 (<CJK Ideograph>) 12889 0x7C85 粅 (<CJK Ideograph>) 12890 0x7D1E 紞 (<CJK Ideograph>) 12891 0x7D1D 紝 (<CJK Ideograph>) 12892 0x7D11 紑 (<CJK Ideograph>) 12893 0x7D0E 紎 (<CJK Ideograph>) 12894 0x7D18 紘 (<CJK Ideograph>) 12895 0x7D16 紖 (<CJK Ideograph>) 12896 0x7D13 紓 (<CJK Ideograph>) 12897 0x7D1F 紟 (<CJK Ideograph>) 12898 0x7D12 紒 (<CJK Ideograph>) 12899 0x7D0F 紏 (<CJK Ideograph>) 12900 0x7D0C 紌 (<CJK Ideograph>) 12901 0x7F5C 罜 (<CJK Ideograph>) 12902 0x7F61 罡 (<CJK Ideograph>) 12903 0x7F5E 罞 (<CJK Ideograph>) 12904 0x7F60 罠 (<CJK Ideograph>) 12905 0x7F5D 罝 (<CJK Ideograph>) 12906 0x7F5B 罛 (<CJK Ideograph>) 12907 0x7F96 羖 (<CJK Ideograph>) 12908 0x7F92 羒 (<CJK Ideograph>) 12909 0x7FC3 翃 (<CJK Ideograph>) 12910 0x7FC2 翂 (<CJK Ideograph>) 12911 0x7FC0 翀 (<CJK Ideograph>) 12912 0x8016 耖 (<CJK Ideograph>) 12913 0x803E 耾 (<CJK Ideograph>) 12914 0x8039 耹 (<CJK Ideograph>) 12915 0x80FA 胺 (<CJK Ideograph>) 12916 0x80F2 胲 (<CJK Ideograph>) 12917 0x80F9 胹 (<CJK Ideograph>) 12918 0x80F5 胵 (<CJK Ideograph>) 12919 0x8101 脁 (<CJK Ideograph>) 12920 0x80FB 胻 (<CJK Ideograph>) 12921 0x8100 脀 (<CJK Ideograph>) 12922 0x8201 舁 (<CJK Ideograph>) 12923 0x822F 舯 (<CJK Ideograph>) 12924 0x8225 舥 (<CJK Ideograph>) 12925 0x8333 茳 (<CJK Ideograph>) 12926 0x832D 茭 (<CJK Ideograph>) 12927 0x8344 荄 (<CJK Ideograph>) 12928 0x8319 茙 (<CJK Ideograph>) 12929 0x8351 荑 (<CJK Ideograph>) 12930 0x8325 茥 (<CJK Ideograph>) 12931 0x8356 荖 (<CJK Ideograph>) 12932 0x833F 茿 (<CJK Ideograph>) 12933 0x8341 荁 (<CJK Ideograph>) 12934 0x8326 茦 (<CJK Ideograph>) 12935 0x831C 茜 (<CJK Ideograph>) 12936 0x8322 茢 (<CJK Ideograph>) 12937 0x8342 荂 (<CJK Ideograph>) 12938 0x834E 荎 (<CJK Ideograph>) 12939 0x831B 茛 (<CJK Ideograph>) 12940 0x832A 茪 (<CJK Ideograph>) 12941 0x8308 茈 (<CJK Ideograph>) 12942 0x833C 茼 (<CJK Ideograph>) 12943 0x834D 荍 (<CJK Ideograph>) 12944 0x8316 茖 (<CJK Ideograph>) 12945 0x8324 茤 (<CJK Ideograph>) 12946 0x8320 茠 (<CJK Ideograph>) 12947 0x8337 茷 (<CJK Ideograph>) 12948 0x832F 茯 (<CJK Ideograph>) 12949 0x8329 茩 (<CJK Ideograph>) 12950 0x8347 荇 (<CJK Ideograph>) 12951 0x8345 荅 (<CJK Ideograph>) 12952 0x834C 荌 (<CJK Ideograph>) 12953 0x8353 荓 (<CJK Ideograph>) 12954 0x831E 茞 (<CJK Ideograph>) 12955 0x832C 茬 (<CJK Ideograph>) 12956 0x834B 荋 (<CJK Ideograph>) 12957 0x8327 茧 (<CJK Ideograph>) 12958 0x8348 荈 (<CJK Ideograph>) 12959 0x8653 虓 (<CJK Ideograph>) 12960 0x8652 虒 (<CJK Ideograph>) 12961 0x86A2 蚢 (<CJK Ideograph>) 12962 0x86A8 蚨 (<CJK Ideograph>) 12963 0x8696 蚖 (<CJK Ideograph>) 12964 0x868D 蚍 (<CJK Ideograph>) 12965 0x8691 蚑 (<CJK Ideograph>) 12966 0x869E 蚞 (<CJK Ideograph>) 12967 0x8687 蚇 (<CJK Ideograph>) 12968 0x8697 蚗 (<CJK Ideograph>) 12969 0x8686 蚆 (<CJK Ideograph>) 12970 0x868B 蚋 (<CJK Ideograph>) 12971 0x869A 蚚 (<CJK Ideograph>) 12972 0x8685 蚅 (<CJK Ideograph>) 12973 0x86A5 蚥 (<CJK Ideograph>) 12974 0x8699 蚙 (<CJK Ideograph>) 12975 0x86A1 蚡 (<CJK Ideograph>) 12976 0x86A7 蚧 (<CJK Ideograph>) 12977 0x8695 蚕 (<CJK Ideograph>) 12978 0x8698 蚘 (<CJK Ideograph>) 12979 0x868E 蚎 (<CJK Ideograph>) 12980 0x869D 蚝 (<CJK Ideograph>) 12981 0x8690 蚐 (<CJK Ideograph>) 12982 0x8694 蚔 (<CJK Ideograph>) 12983 0x8843 衃 (<CJK Ideograph>) 12984 0x8844 衄 (<CJK Ideograph>) 12985 0x886D 衭 (<CJK Ideograph>) 12986 0x8875 衵 (<CJK Ideograph>) 12987 0x8876 衶 (<CJK Ideograph>) 12988 0x8872 衲 (<CJK Ideograph>) 12989 0x8880 袀 (<CJK Ideograph>) 12990 0x8871 衱 (<CJK Ideograph>) 12991 0x887F 衿 (<CJK Ideograph>) 12992 0x886F 衯 (<CJK Ideograph>) 12993 0x8883 袃 (<CJK Ideograph>) 12994 0x887E 衾 (<CJK Ideograph>) 12995 0x8874 衴 (<CJK Ideograph>) 12996 0x887C 衼 (<CJK Ideograph>) 12997 0x8A12 訒 (<CJK Ideograph>) 12998 0x8C47 豇 (<CJK Ideograph>) 12999 0x8C57 豗 (<CJK Ideograph>) 13000 0x8C7B 豻 (<CJK Ideograph>) 13001 0x8CA4 貤 (<CJK Ideograph>) 13002 0x8CA3 貣 (<CJK Ideograph>) 13003 0x8D76 赶 (<CJK Ideograph>) 13004 0x8D78 赸 (<CJK Ideograph>) 13005 0x8DB5 趵 (<CJK Ideograph>) 13006 0x8DB7 趷 (<CJK Ideograph>) 13007 0x8DB6 趶 (<CJK Ideograph>) 13008 0x8ED1 軑 (<CJK Ideograph>) 13009 0x8ED3 軓 (<CJK Ideograph>) 13010 0x8FFE 迾 (<CJK Ideograph>) 13011 0x8FF5 迵 (<CJK Ideograph>) 13012 0x9002 适 (<CJK Ideograph>) 13013 0x8FFF 迿 (<CJK Ideograph>) 13014 0x8FFB 迻 (<CJK Ideograph>) 13015 0x9004 逄 (<CJK Ideograph>) 13016 0x8FFC 迼 (<CJK Ideograph>) 13017 0x8FF6 迶 (<CJK Ideograph>) 13018 0x90D6 郖 (<CJK Ideograph>) 13019 0x90E0 郠 (<CJK Ideograph>) 13020 0x90D9 郙 (<CJK Ideograph>) 13021 0x90DA 郚 (<CJK Ideograph>) 13022 0x90E3 郣 (<CJK Ideograph>) 13023 0x90DF 郟 (<CJK Ideograph>) 13024 0x90E5 郥 (<CJK Ideograph>) 13025 0x90D8 郘 (<CJK Ideograph>) 13026 0x90DB 郛 (<CJK Ideograph>) 13027 0x90D7 郗 (<CJK Ideograph>) 13028 0x90DC 郜 (<CJK Ideograph>) 13029 0x90E4 郤 (<CJK Ideograph>) 13030 0x9150 酐 (<CJK Ideograph>) 13031 0x914E 酎 (<CJK Ideograph>) 13032 0x914F 酏 (<CJK Ideograph>) 13033 0x91D5 釕 (<CJK Ideograph>) 13034 0x91E2 釢 (<CJK Ideograph>) 13035 0x91DA 釚 (<CJK Ideograph>) 13036 0x965C 陜 (<CJK Ideograph>) 13037 0x965F 陟 (<CJK Ideograph>) 13038 0x96BC 隼 (<CJK Ideograph>) 13039 0x98E3 飣 (<CJK Ideograph>) 13040 0x9ADF 髟 (<CJK Ideograph>) 13041 0x9B2F 鬯 (<CJK Ideograph>) 13042 0x4E7F 乿 (<CJK Ideograph>) 13043 0x5070 偰 (<CJK Ideograph>) 13044 0x506A 偪 (<CJK Ideograph>) 13045 0x5061 偡 (<CJK Ideograph>) 13046 0x505E 偞 (<CJK Ideograph>) 13047 0x5060 偠 (<CJK Ideograph>) 13048 0x5053 偓 (<CJK Ideograph>) 13049 0x504B 偋 (<CJK Ideograph>) 13050 0x505D 偝 (<CJK Ideograph>) 13051 0x5072 偲 (<CJK Ideograph>) 13052 0x5048 偈 (<CJK Ideograph>) 13053 0x504D 偍 (<CJK Ideograph>) 13054 0x5041 偁 (<CJK Ideograph>) 13055 0x505B 偛 (<CJK Ideograph>) 13056 0x504A 偊 (<CJK Ideograph>) 13057 0x5062 偢 (<CJK Ideograph>) 13058 0x5015 倕 (<CJK Ideograph>) 13059 0x5045 偅 (<CJK Ideograph>) 13060 0x505F 偟 (<CJK Ideograph>) 13061 0x5069 偩 (<CJK Ideograph>) 13062 0x506B 偫 (<CJK Ideograph>) 13063 0x5063 偣 (<CJK Ideograph>) 13064 0x5064 偤 (<CJK Ideograph>) 13065 0x5046 偆 (<CJK Ideograph>) 13066 0x5040 偀 (<CJK Ideograph>) 13067 0x506E 偮 (<CJK Ideograph>) 13068 0x5073 偳 (<CJK Ideograph>) 13069 0x5057 偗 (<CJK Ideograph>) 13070 0x5051 偑 (<CJK Ideograph>) 13071 0x51D0 凐 (<CJK Ideograph>) 13072 0x526B 剫 (<CJK Ideograph>) 13073 0x526D 剭 (<CJK Ideograph>) 13074 0x526C 剬 (<CJK Ideograph>) 13075 0x526E 剮 (<CJK Ideograph>) 13076 0x52D6 勖 (<CJK Ideograph>) 13077 0x52D3 勓 (<CJK Ideograph>) 13078 0x532D 匭 (<CJK Ideograph>) 13079 0x539C 厜 (<CJK Ideograph>) 13080 0x5575 啵 (<CJK Ideograph>) 13081 0x5576 啶 (<CJK Ideograph>) 13082 0x553C 唼 (<CJK Ideograph>) 13083 0x554D 啍 (<CJK Ideograph>) 13084 0x5550 啐 (<CJK Ideograph>) 13085 0x5534 唴 (<CJK Ideograph>) 13086 0x552A 唪 (<CJK Ideograph>) 13087 0x5551 啑 (<CJK Ideograph>) 13088 0x5562 啢 (<CJK Ideograph>) 13089 0x5536 唶 (<CJK Ideograph>) 13090 0x5535 唵 (<CJK Ideograph>) 13091 0x5530 唰 (<CJK Ideograph>) 13092 0x5552 啒 (<CJK Ideograph>) 13093 0x5545 啅 (<CJK Ideograph>) 13094 0x550C 唌 (<CJK Ideograph>) 13095 0x5532 唲 (<CJK Ideograph>) 13096 0x5565 啥 (<CJK Ideograph>) 13097 0x554E 啎 (<CJK Ideograph>) 13098 0x5539 唹 (<CJK Ideograph>) 13099 0x5548 啈 (<CJK Ideograph>) 13100 0x552D 唭 (<CJK Ideograph>) 13101 0x553B 唻 (<CJK Ideograph>) 13102 0x5540 啀 (<CJK Ideograph>) 13103 0x554B 啋 (<CJK Ideograph>) 13104 0x570A 圊 (<CJK Ideograph>) 13105 0x5707 圇 (<CJK Ideograph>) 13106 0x57FB 埻 (<CJK Ideograph>) 13107 0x5814 堔 (<CJK Ideograph>) 13108 0x57E2 埢 (<CJK Ideograph>) 13109 0x57F6 埶 (<CJK Ideograph>) 13110 0x57DC 埜 (<CJK Ideograph>) 13111 0x57F4 埴 (<CJK Ideograph>) 13112 0x5800 堀 (<CJK Ideograph>) 13113 0x57ED 埭 (<CJK Ideograph>) 13114 0x57FD 埽 (<CJK Ideograph>) 13115 0x5808 堈 (<CJK Ideograph>) 13116 0x57F8 埸 (<CJK Ideograph>) 13117 0x580B 堋 (<CJK Ideograph>) 13118 0x57F3 埳 (<CJK Ideograph>) 13119 0x57CF 埏 (<CJK Ideograph>) 13120 0x5807 堇 (<CJK Ideograph>) 13121 0x57EE 埮 (<CJK Ideograph>) 13122 0x57E3 埣 (<CJK Ideograph>) 13123 0x57F2 埲 (<CJK Ideograph>) 13124 0x57E5 埥 (<CJK Ideograph>) 13125 0x57EC 埬 (<CJK Ideograph>) 13126 0x57E1 埡 (<CJK Ideograph>) 13127 0x580E 堎 (<CJK Ideograph>) 13128 0x57FC 埼 (<CJK Ideograph>) 13129 0x5810 堐 (<CJK Ideograph>) 13130 0x57E7 埧 (<CJK Ideograph>) 13131 0x5801 堁 (<CJK Ideograph>) 13132 0x580C 堌 (<CJK Ideograph>) 13133 0x57F1 埱 (<CJK Ideograph>) 13134 0x57E9 埩 (<CJK Ideograph>) 13135 0x57F0 埰 (<CJK Ideograph>) 13136 0x580D 堍 (<CJK Ideograph>) 13137 0x5804 堄 (<CJK Ideograph>) 13138 0x595C 奜 (<CJK Ideograph>) 13139 0x5A60 婠 (<CJK Ideograph>) 13140 0x5A58 婘 (<CJK Ideograph>) 13141 0x5A55 婕 (<CJK Ideograph>) 13142 0x5A67 婧 (<CJK Ideograph>) 13143 0x5A5E 婞 (<CJK Ideograph>) 13144 0x5A38 娸 (<CJK Ideograph>) 13145 0x5A35 娵 (<CJK Ideograph>) 13146 0x5A6D 婭 (<CJK Ideograph>) 13147 0x5A50 婐 (<CJK Ideograph>) 13148 0x5A5F 婟 (<CJK Ideograph>) 13149 0x5A65 婥 (<CJK Ideograph>) 13150 0x5A6C 婬 (<CJK Ideograph>) 13151 0x5A53 婓 (<CJK Ideograph>) 13152 0x5A64 婤 (<CJK Ideograph>) 13153 0x5A57 婗 (<CJK Ideograph>) 13154 0x5A43 婃 (<CJK Ideograph>) 13155 0x5A5D 婝 (<CJK Ideograph>) 13156 0x5A52 婒 (<CJK Ideograph>) 13157 0x5A44 婄 (<CJK Ideograph>) 13158 0x5A5B 婛 (<CJK Ideograph>) 13159 0x5A48 婈 (<CJK Ideograph>) 13160 0x5A8E 媎 (<CJK Ideograph>) 13161 0x5A3E 娾 (<CJK Ideograph>) 13162 0x5A4D 婍 (<CJK Ideograph>) 13163 0x5A39 娹 (<CJK Ideograph>) 13164 0x5A4C 婌 (<CJK Ideograph>) 13165 0x5A70 婰 (<CJK Ideograph>) 13166 0x5A69 婩 (<CJK Ideograph>) 13167 0x5A47 婇 (<CJK Ideograph>) 13168 0x5A51 婑 (<CJK Ideograph>) 13169 0x5A56 婖 (<CJK Ideograph>) 13170 0x5A42 婂 (<CJK Ideograph>) 13171 0x5A5C 婜 (<CJK Ideograph>) 13172 0x5B72 孲 (<CJK Ideograph>) 13173 0x5B6E 孮 (<CJK Ideograph>) 13174 0x5BC1 寁 (<CJK Ideograph>) 13175 0x5BC0 寀 (<CJK Ideograph>) 13176 0x5C59 屙 (<CJK Ideograph>) 13177 0x5D1E 崞 (<CJK Ideograph>) 13178 0x5D0B 崋 (<CJK Ideograph>) 13179 0x5D1D 崝 (<CJK Ideograph>) 13180 0x5D1A 崚 (<CJK Ideograph>) 13181 0x5D20 崠 (<CJK Ideograph>) 13182 0x5D0C 崌 (<CJK Ideograph>) 13183 0x5D28 崨 (<CJK Ideograph>) 13184 0x5D0D 崍 (<CJK Ideograph>) 13185 0x5D26 崦 (<CJK Ideograph>) 13186 0x5D25 崥 (<CJK Ideograph>) 13187 0x5D0F 崏 (<CJK Ideograph>) 13188 0x5D30 崰 (<CJK Ideograph>) 13189 0x5D12 崒 (<CJK Ideograph>) 13190 0x5D23 崣 (<CJK Ideograph>) 13191 0x5D1F 崟 (<CJK Ideograph>) 13192 0x5D2E 崮 (<CJK Ideograph>) 13193 0x5E3E 帾 (<CJK Ideograph>) 13194 0x5E34 帴 (<CJK Ideograph>) 13195 0x5EB1 庱 (<CJK Ideograph>) 13196 0x5EB4 庴 (<CJK Ideograph>) 13197 0x5EB9 庹 (<CJK Ideograph>) 13198 0x5EB2 庲 (<CJK Ideograph>) 13199 0x5EB3 庳 (<CJK Ideograph>) 13200 0x5F36 弶 (<CJK Ideograph>) 13201 0x5F38 弸 (<CJK Ideograph>) 13202 0x5F9B 徛 (<CJK Ideograph>) 13203 0x5F96 徖 (<CJK Ideograph>) 13204 0x5F9F 徟 (<CJK Ideograph>) 13205 0x608A 悊 (<CJK Ideograph>) 13206 0x6090 悐 (<CJK Ideograph>) 13207 0x6086 悆 (<CJK Ideograph>) 13208 0x60BE 悾 (<CJK Ideograph>) 13209 0x60B0 悰 (<CJK Ideograph>) 13210 0x60BA 悺 (<CJK Ideograph>) 13211 0x60D3 惓 (<CJK Ideograph>) 13212 0x60D4 惔 (<CJK Ideograph>) 13213 0x60CF 惏 (<CJK Ideograph>) 13214 0x60E4 惤 (<CJK Ideograph>) 13215 0x60D9 惙 (<CJK Ideograph>) 13216 0x60DD 惝 (<CJK Ideograph>) 13217 0x60C8 惈 (<CJK Ideograph>) 13218 0x60B1 悱 (<CJK Ideograph>) 13219 0x60DB 惛 (<CJK Ideograph>) 13220 0x60B7 悷 (<CJK Ideograph>) 13221 0x60CA 惊 (<CJK Ideograph>) 13222 0x60BF 悿 (<CJK Ideograph>) 13223 0x60C3 惃 (<CJK Ideograph>) 13224 0x60CD 惍 (<CJK Ideograph>) 13225 0x60C0 惀 (<CJK Ideograph>) 13226 0x6332 挲 (<CJK Ideograph>) 13227 0x6365 捥 (<CJK Ideograph>) 13228 0x638A 掊 (<CJK Ideograph>) 13229 0x6382 掂 (<CJK Ideograph>) 13230 0x637D 捽 (<CJK Ideograph>) 13231 0x63BD 掽 (<CJK Ideograph>) 13232 0x639E 掞 (<CJK Ideograph>) 13233 0x63AD 掭 (<CJK Ideograph>) 13234 0x639D 掝 (<CJK Ideograph>) 13235 0x6397 掗 (<CJK Ideograph>) 13236 0x63AB 掫 (<CJK Ideograph>) 13237 0x638E 掎 (<CJK Ideograph>) 13238 0x636F 捯 (<CJK Ideograph>) 13239 0x6387 掇 (<CJK Ideograph>) 13240 0x6390 掐 (<CJK Ideograph>) 13241 0x636E 据 (<CJK Ideograph>) 13242 0x63AF 掯 (<CJK Ideograph>) 13243 0x6375 捵 (<CJK Ideograph>) 13244 0x639C 掜 (<CJK Ideograph>) 13245 0x636D 捭 (<CJK Ideograph>) 13246 0x63AE 掮 (<CJK Ideograph>) 13247 0x637C 捼 (<CJK Ideograph>) 13248 0x63A4 掤 (<CJK Ideograph>) 13249 0x633B 挻 (<CJK Ideograph>) 13250 0x639F 掟 (<CJK Ideograph>) 13251 0x6378 捸 (<CJK Ideograph>) 13252 0x6385 掅 (<CJK Ideograph>) 13253 0x6381 掁 (<CJK Ideograph>) 13254 0x6391 掑 (<CJK Ideograph>) 13255 0x638D 掍 (<CJK Ideograph>) 13256 0x6370 捰 (<CJK Ideograph>) 13257 0x6553 敓 (<CJK Ideograph>) 13258 0x65CD 旍 (<CJK Ideograph>) 13259 0x6665 晥 (<CJK Ideograph>) 13260 0x6661 晡 (<CJK Ideograph>) 13261 0x665B 晛 (<CJK Ideograph>) 13262 0x6659 晙 (<CJK Ideograph>) 13263 0x665C 晜 (<CJK Ideograph>) 13264 0x6662 晢 (<CJK Ideograph>) 13265 0x6718 朘 (<CJK Ideograph>) 13266 0x6879 桹 (<CJK Ideograph>) 13267 0x6887 梇 (<CJK Ideograph>) 13268 0x6890 梐 (<CJK Ideograph>) 13269 0x689C 梜 (<CJK Ideograph>) 13270 0x686D 桭 (<CJK Ideograph>) 13271 0x686E 桮 (<CJK Ideograph>) 13272 0x68AE 梮 (<CJK Ideograph>) 13273 0x68AB 梫 (<CJK Ideograph>) 13274 0x6956 楖 (<CJK Ideograph>) 13275 0x686F 桯 (<CJK Ideograph>) 13276 0x68A3 梣 (<CJK Ideograph>) 13277 0x68AC 梬 (<CJK Ideograph>) 13278 0x68A9 梩 (<CJK Ideograph>) 13279 0x6875 桵 (<CJK Ideograph>) 13280 0x6874 桴 (<CJK Ideograph>) 13281 0x68B2 梲 (<CJK Ideograph>) 13282 0x688F 梏 (<CJK Ideograph>) 13283 0x6877 桷 (<CJK Ideograph>) 13284 0x6892 梒 (<CJK Ideograph>) 13285 0x687C 桼 (<CJK Ideograph>) 13286 0x686B 桫 (<CJK Ideograph>) 13287 0x6872 桲 (<CJK Ideograph>) 13288 0x68AA 梪 (<CJK Ideograph>) 13289 0x6880 梀 (<CJK Ideograph>) 13290 0x6871 桱 (<CJK Ideograph>) 13291 0x687E 桾 (<CJK Ideograph>) 13292 0x689B 梛 (<CJK Ideograph>) 13293 0x6896 梖 (<CJK Ideograph>) 13294 0x688B 梋 (<CJK Ideograph>) 13295 0x68A0 梠 (<CJK Ideograph>) 13296 0x6889 梉 (<CJK Ideograph>) 13297 0x68A4 梤 (<CJK Ideograph>) 13298 0x6878 桸 (<CJK Ideograph>) 13299 0x687B 桻 (<CJK Ideograph>) 13300 0x6891 梑 (<CJK Ideograph>) 13301 0x688C 梌 (<CJK Ideograph>) 13302 0x688A 梊 (<CJK Ideograph>) 13303 0x687D 桽 (<CJK Ideograph>) 13304 0x6B36 欶 (<CJK Ideograph>) 13305 0x6B33 欳 (<CJK Ideograph>) 13306 0x6B37 欷 (<CJK Ideograph>) 13307 0x6B38 欸 (<CJK Ideograph>) 13308 0x6B91 殑 (<CJK Ideograph>) 13309 0x6B8F 殏 (<CJK Ideograph>) 13310 0x6B8D 殍 (<CJK Ideograph>) 13311 0x6B8E 殎 (<CJK Ideograph>) 13312 0x6B8C 殌 (<CJK Ideograph>) 13313 0x6C2A 氪 (<CJK Ideograph>) 13314 0x6DC0 淀 (<CJK Ideograph>) 13315 0x6DAB 涫 (<CJK Ideograph>) 13316 0x6DB4 涴 (<CJK Ideograph>) 13317 0x6DB3 涳 (<CJK Ideograph>) 13318 0x6E74 湴 (<CJK Ideograph>) 13319 0x6DAC 涬 (<CJK Ideograph>) 13320 0x6DE9 淩 (<CJK Ideograph>) 13321 0x6DE2 淢 (<CJK Ideograph>) 13322 0x6DB7 涷 (<CJK Ideograph>) 13323 0x6DF6 淶 (<CJK Ideograph>) 13324 0x6DD4 淔 (<CJK Ideograph>) 13325 0x6E00 渀 (<CJK Ideograph>) 13326 0x6DC8 淈 (<CJK Ideograph>) 13327 0x6DE0 淠 (<CJK Ideograph>) 13328 0x6DDF 淟 (<CJK Ideograph>) 13329 0x6DD6 淖 (<CJK Ideograph>) 13330 0x6DBE 涾 (<CJK Ideograph>) 13331 0x6DE5 淥 (<CJK Ideograph>) 13332 0x6DDC 淜 (<CJK Ideograph>) 13333 0x6DDD 淝 (<CJK Ideograph>) 13334 0x6DDB 淛 (<CJK Ideograph>) 13335 0x6DF4 淴 (<CJK Ideograph>) 13336 0x6DCA 淊 (<CJK Ideograph>) 13337 0x6DBD 涽 (<CJK Ideograph>) 13338 0x6DED 淭 (<CJK Ideograph>) 13339 0x6DF0 淰 (<CJK Ideograph>) 13340 0x6DBA 涺 (<CJK Ideograph>) 13341 0x6DD5 淕 (<CJK Ideograph>) 13342 0x6DC2 淂 (<CJK Ideograph>) 13343 0x6DCF 淏 (<CJK Ideograph>) 13344 0x6DC9 淉 (<CJK Ideograph>) 13345 0x6DD0 淐 (<CJK Ideograph>) 13346 0x6DF2 淲 (<CJK Ideograph>) 13347 0x6DD3 淓 (<CJK Ideograph>) 13348 0x6DFD 淽 (<CJK Ideograph>) 13349 0x6DD7 淗 (<CJK Ideograph>) 13350 0x6DCD 淍 (<CJK Ideograph>) 13351 0x6DE3 淣 (<CJK Ideograph>) 13352 0x6DBB 涻 (<CJK Ideograph>) 13353 0x70FA 烺 (<CJK Ideograph>) 13354 0x710D 焍 (<CJK Ideograph>) 13355 0x70F7 烷 (<CJK Ideograph>) 13356 0x7117 焗 (<CJK Ideograph>) 13357 0x70F4 烴 (<CJK Ideograph>) 13358 0x710C 焌 (<CJK Ideograph>) 13359 0x70F0 烰 (<CJK Ideograph>) 13360 0x7104 焄 (<CJK Ideograph>) 13361 0x70F3 烳 (<CJK Ideograph>) 13362 0x7110 焐 (<CJK Ideograph>) 13363 0x70FC 烼 (<CJK Ideograph>) 13364 0x70FF 烿 (<CJK Ideograph>) 13365 0x7106 焆 (<CJK Ideograph>) 13366 0x7113 焓 (<CJK Ideograph>) 13367 0x7100 焀 (<CJK Ideograph>) 13368 0x70F8 烸 (<CJK Ideograph>) 13369 0x70F6 烶 (<CJK Ideograph>) 13370 0x710B 焋 (<CJK Ideograph>) 13371 0x7102 焂 (<CJK Ideograph>) 13372 0x710E 焎 (<CJK Ideograph>) 13373 0x727E 牾 (<CJK Ideograph>) 13374 0x727B 牻 (<CJK Ideograph>) 13375 0x727C 牼 (<CJK Ideograph>) 13376 0x727F 牿 (<CJK Ideograph>) 13377 0x731D 猝 (<CJK Ideograph>) 13378 0x7317 猗 (<CJK Ideograph>) 13379 0x7307 猇 (<CJK Ideograph>) 13380 0x7311 猑 (<CJK Ideograph>) 13381 0x7318 猘 (<CJK Ideograph>) 13382 0x730A 猊 (<CJK Ideograph>) 13383 0x7308 猈 (<CJK Ideograph>) 13384 0x72FF 狿 (<CJK Ideograph>) 13385 0x730F 猏 (<CJK Ideograph>) 13386 0x731E 猞 (<CJK Ideograph>) 13387 0x7388 玈 (<CJK Ideograph>) 13388 0x73F6 珶 (<CJK Ideograph>) 13389 0x73F8 珸 (<CJK Ideograph>) 13390 0x73F5 珵 (<CJK Ideograph>) 13391 0x7404 琄 (<CJK Ideograph>) 13392 0x7401 琁 (<CJK Ideograph>) 13393 0x73FD 珽 (<CJK Ideograph>) 13394 0x7407 琇 (<CJK Ideograph>) 13395 0x7400 琀 (<CJK Ideograph>) 13396 0x73FA 珺 (<CJK Ideograph>) 13397 0x73FC 珼 (<CJK Ideograph>) 13398 0x73FF 珿 (<CJK Ideograph>) 13399 0x740C 琌 (<CJK Ideograph>) 13400 0x740B 琋 (<CJK Ideograph>) 13401 0x73F4 珴 (<CJK Ideograph>) 13402 0x7408 琈 (<CJK Ideograph>) 13403 0x7564 畤 (<CJK Ideograph>) 13404 0x7563 畣 (<CJK Ideograph>) 13405 0x75CE 痎 (<CJK Ideograph>) 13406 0x75D2 痒 (<CJK Ideograph>) 13407 0x75CF 痏 (<CJK Ideograph>) 13408 0x75CB 痋 (<CJK Ideograph>) 13409 0x75CC 痌 (<CJK Ideograph>) 13410 0x75D1 痑 (<CJK Ideograph>) 13411 0x75D0 痐 (<CJK Ideograph>) 13412 0x768F 皏 (<CJK Ideograph>) 13413 0x7689 皉 (<CJK Ideograph>) 13414 0x76D3 盓 (<CJK Ideograph>) 13415 0x7739 眹 (<CJK Ideograph>) 13416 0x772F 眯 (<CJK Ideograph>) 13417 0x772D 眭 (<CJK Ideograph>) 13418 0x7731 眱 (<CJK Ideograph>) 13419 0x7732 眲 (<CJK Ideograph>) 13420 0x7734 眴 (<CJK Ideograph>) 13421 0x7733 眳 (<CJK Ideograph>) 13422 0x773D 眽 (<CJK Ideograph>) 13423 0x7725 眥 (<CJK Ideograph>) 13424 0x773B 眻 (<CJK Ideograph>) 13425 0x7735 眵 (<CJK Ideograph>) 13426 0x7848 硈 (<CJK Ideograph>) 13427 0x7852 硒 (<CJK Ideograph>) 13428 0x7849 硉 (<CJK Ideograph>) 13429 0x784D 硍 (<CJK Ideograph>) 13430 0x784A 硊 (<CJK Ideograph>) 13431 0x784C 硌 (<CJK Ideograph>) 13432 0x7826 砦 (<CJK Ideograph>) 13433 0x7845 硅 (<CJK Ideograph>) 13434 0x7850 硐 (<CJK Ideograph>) 13435 0x7964 祤 (<CJK Ideograph>) 13436 0x7967 祧 (<CJK Ideograph>) 13437 0x7969 祩 (<CJK Ideograph>) 13438 0x796A 祪 (<CJK Ideograph>) 13439 0x7963 祣 (<CJK Ideograph>) 13440 0x796B 祫 (<CJK Ideograph>) 13441 0x7961 祡 (<CJK Ideograph>) 13442 0x79BB 离 (<CJK Ideograph>) 13443 0x79FA 秺 (<CJK Ideograph>) 13444 0x79F8 秸 (<CJK Ideograph>) 13445 0x79F6 秶 (<CJK Ideograph>) 13446 0x79F7 秷 (<CJK Ideograph>) 13447 0x7A8F 窏 (<CJK Ideograph>) 13448 0x7A94 窔 (<CJK Ideograph>) 13449 0x7A90 窐 (<CJK Ideograph>) 13450 0x7B35 笵 (<CJK Ideograph>) 13451 0x7B47 筇 (<CJK Ideograph>) 13452 0x7B34 笴 (<CJK Ideograph>) 13453 0x7B25 笥 (<CJK Ideograph>) 13454 0x7B30 笰 (<CJK Ideograph>) 13455 0x7B22 笢 (<CJK Ideograph>) 13456 0x7B24 笤 (<CJK Ideograph>) 13457 0x7B33 笳 (<CJK Ideograph>) 13458 0x7B18 笘 (<CJK Ideograph>) 13459 0x7B2A 笪 (<CJK Ideograph>) 13460 0x7B1D 笝 (<CJK Ideograph>) 13461 0x7B31 笱 (<CJK Ideograph>) 13462 0x7B2B 笫 (<CJK Ideograph>) 13463 0x7B2D 笭 (<CJK Ideograph>) 13464 0x7B2F 笯 (<CJK Ideograph>) 13465 0x7B32 笲 (<CJK Ideograph>) 13466 0x7B38 笸 (<CJK Ideograph>) 13467 0x7B1A 笚 (<CJK Ideograph>) 13468 0x7B23 笣 (<CJK Ideograph>) 13469 0x7C94 粔 (<CJK Ideograph>) 13470 0x7C98 粘 (<CJK Ideograph>) 13471 0x7C96 粖 (<CJK Ideograph>) 13472 0x7CA3 粣 (<CJK Ideograph>) 13473 0x7D35 紵 (<CJK Ideograph>) 13474 0x7D3D 紽 (<CJK Ideograph>) 13475 0x7D38 紸 (<CJK Ideograph>) 13476 0x7D36 紶 (<CJK Ideograph>) 13477 0x7D3A 紺 (<CJK Ideograph>) 13478 0x7D45 絅 (<CJK Ideograph>) 13479 0x7D2C 紬 (<CJK Ideograph>) 13480 0x7D29 紩 (<CJK Ideograph>) 13481 0x7D41 絁 (<CJK Ideograph>) 13482 0x7D47 絇 (<CJK Ideograph>) 13483 0x7D3E 紾 (<CJK Ideograph>) 13484 0x7D3F 紿 (<CJK Ideograph>) 13485 0x7D4A 絊 (<CJK Ideograph>) 13486 0x7D3B 紻 (<CJK Ideograph>) 13487 0x7D28 紨 (<CJK Ideograph>) 13488 0x7F63 罣 (<CJK Ideograph>) 13489 0x7F95 羕 (<CJK Ideograph>) 13490 0x7F9C 羜 (<CJK Ideograph>) 13491 0x7F9D 羝 (<CJK Ideograph>) 13492 0x7F9B 羛 (<CJK Ideograph>) 13493 0x7FCA 翊 (<CJK Ideograph>) 13494 0x7FCB 翋 (<CJK Ideograph>) 13495 0x7FCD 翍 (<CJK Ideograph>) 13496 0x7FD0 翐 (<CJK Ideograph>) 13497 0x7FD1 翑 (<CJK Ideograph>) 13498 0x7FC7 翇 (<CJK Ideograph>) 13499 0x7FCF 翏 (<CJK Ideograph>) 13500 0x7FC9 翉 (<CJK Ideograph>) 13501 0x801F 耟 (<CJK Ideograph>) 13502 0x801E 耞 (<CJK Ideograph>) 13503 0x801B 耛 (<CJK Ideograph>) 13504 0x8047 聇 (<CJK Ideograph>) 13505 0x8043 聃 (<CJK Ideograph>) 13506 0x8048 聈 (<CJK Ideograph>) 13507 0x8118 脘 (<CJK Ideograph>) 13508 0x8125 脥 (<CJK Ideograph>) 13509 0x8119 脙 (<CJK Ideograph>) 13510 0x811B 脛 (<CJK Ideograph>) 13511 0x812D 脭 (<CJK Ideograph>) 13512 0x811F 脟 (<CJK Ideograph>) 13513 0x812C 脬 (<CJK Ideograph>) 13514 0x811E 脞 (<CJK Ideograph>) 13515 0x8121 脡 (<CJK Ideograph>) 13516 0x8115 脕 (<CJK Ideograph>) 13517 0x8127 脧 (<CJK Ideograph>) 13518 0x811D 脝 (<CJK Ideograph>) 13519 0x8122 脢 (<CJK Ideograph>) 13520 0x8211 舑 (<CJK Ideograph>) 13521 0x8238 舸 (<CJK Ideograph>) 13522 0x8233 舳 (<CJK Ideograph>) 13523 0x823A 舺 (<CJK Ideograph>) 13524 0x8234 舴 (<CJK Ideograph>) 13525 0x8232 舲 (<CJK Ideograph>) 13526 0x8274 艴 (<CJK Ideograph>) 13527 0x8390 莐 (<CJK Ideograph>) 13528 0x83A3 莣 (<CJK Ideograph>) 13529 0x83A8 莨 (<CJK Ideograph>) 13530 0x838D 莍 (<CJK Ideograph>) 13531 0x837A 荺 (<CJK Ideograph>) 13532 0x8373 荳 (<CJK Ideograph>) 13533 0x83A4 莤 (<CJK Ideograph>) 13534 0x8374 荴 (<CJK Ideograph>) 13535 0x838F 莏 (<CJK Ideograph>) 13536 0x8381 莁 (<CJK Ideograph>) 13537 0x8395 莕 (<CJK Ideograph>) 13538 0x8399 莙 (<CJK Ideograph>) 13539 0x8375 荵 (<CJK Ideograph>) 13540 0x8394 莔 (<CJK Ideograph>) 13541 0x83A9 莩 (<CJK Ideograph>) 13542 0x837D 荽 (<CJK Ideograph>) 13543 0x8383 莃 (<CJK Ideograph>) 13544 0x838C 莌 (<CJK Ideograph>) 13545 0x839D 莝 (<CJK Ideograph>) 13546 0x839B 莛 (<CJK Ideograph>) 13547 0x83AA 莪 (<CJK Ideograph>) 13548 0x838B 莋 (<CJK Ideograph>) 13549 0x837E 荾 (<CJK Ideograph>) 13550 0x83A5 莥 (<CJK Ideograph>) 13551 0x83AF 莯 (<CJK Ideograph>) 13552 0x8388 莈 (<CJK Ideograph>) 13553 0x8397 莗 (<CJK Ideograph>) 13554 0x83B0 莰 (<CJK Ideograph>) 13555 0x837F 荿 (<CJK Ideograph>) 13556 0x83A6 莦 (<CJK Ideograph>) 13557 0x8387 莇 (<CJK Ideograph>) 13558 0x83AE 莮 (<CJK Ideograph>) 13559 0x8376 荶 (<CJK Ideograph>) 13560 0x839A 莚 (<CJK Ideograph>) 13561 0x8659 虙 (<CJK Ideograph>) 13562 0x8656 虖 (<CJK Ideograph>) 13563 0x86BF 蚿 (<CJK Ideograph>) 13564 0x86B7 蚷 (<CJK Ideograph>) 13565 0x86C2 蛂 (<CJK Ideograph>) 13566 0x86C1 蛁 (<CJK Ideograph>) 13567 0x86C5 蛅 (<CJK Ideograph>) 13568 0x86BA 蚺 (<CJK Ideograph>) 13569 0x86B0 蚰 (<CJK Ideograph>) 13570 0x86C8 蛈 (<CJK Ideograph>) 13571 0x86B9 蚹 (<CJK Ideograph>) 13572 0x86B3 蚳 (<CJK Ideograph>) 13573 0x86B8 蚸 (<CJK Ideograph>) 13574 0x86CC 蛌 (<CJK Ideograph>) 13575 0x86B4 蚴 (<CJK Ideograph>) 13576 0x86BB 蚻 (<CJK Ideograph>) 13577 0x86BC 蚼 (<CJK Ideograph>) 13578 0x86C3 蛃 (<CJK Ideograph>) 13579 0x86BD 蚽 (<CJK Ideograph>) 13580 0x86BE 蚾 (<CJK Ideograph>) 13581 0x8852 衒 (<CJK Ideograph>) 13582 0x8889 袉 (<CJK Ideograph>) 13583 0x8895 袕 (<CJK Ideograph>) 13584 0x88A8 袨 (<CJK Ideograph>) 13585 0x88A2 袢 (<CJK Ideograph>) 13586 0x88AA 袪 (<CJK Ideograph>) 13587 0x889A 袚 (<CJK Ideograph>) 13588 0x8891 袑 (<CJK Ideograph>) 13589 0x88A1 袡 (<CJK Ideograph>) 13590 0x889F 袟 (<CJK Ideograph>) 13591 0x8898 袘 (<CJK Ideograph>) 13592 0x88A7 袧 (<CJK Ideograph>) 13593 0x8899 袙 (<CJK Ideograph>) 13594 0x889B 袛 (<CJK Ideograph>) 13595 0x8897 袗 (<CJK Ideograph>) 13596 0x88A4 袤 (<CJK Ideograph>) 13597 0x88AC 袬 (<CJK Ideograph>) 13598 0x888C 袌 (<CJK Ideograph>) 13599 0x8893 袓 (<CJK Ideograph>) 13600 0x888E 袎 (<CJK Ideograph>) 13601 0x8982 覂 (<CJK Ideograph>) 13602 0x89D6 觖 (<CJK Ideograph>) 13603 0x89D9 觙 (<CJK Ideograph>) 13604 0x89D5 觕 (<CJK Ideograph>) 13605 0x8A30 訰 (<CJK Ideograph>) 13606 0x8A27 訧 (<CJK Ideograph>) 13607 0x8A2C 訬 (<CJK Ideograph>) 13608 0x8A1E 訞 (<CJK Ideograph>) 13609 0x8C39 谹 (<CJK Ideograph>) 13610 0x8C3B 谻 (<CJK Ideograph>) 13611 0x8C5C 豜 (<CJK Ideograph>) 13612 0x8C5D 豝 (<CJK Ideograph>) 13613 0x8C7D 豽 (<CJK Ideograph>) 13614 0x8CA5 貥 (<CJK Ideograph>) 13615 0x8D7D 赽 (<CJK Ideograph>) 13616 0x8D7B 赻 (<CJK Ideograph>) 13617 0x8D79 赹 (<CJK Ideograph>) 13618 0x8DBC 趼 (<CJK Ideograph>) 13619 0x8DC2 跂 (<CJK Ideograph>) 13620 0x8DB9 趹 (<CJK Ideograph>) 13621 0x8DBF 趿 (<CJK Ideograph>) 13622 0x8DC1 跁 (<CJK Ideograph>) 13623 0x8ED8 軘 (<CJK Ideograph>) 13624 0x8EDE 軞 (<CJK Ideograph>) 13625 0x8EDD 軝 (<CJK Ideograph>) 13626 0x8EDC 軜 (<CJK Ideograph>) 13627 0x8ED7 軗 (<CJK Ideograph>) 13628 0x8EE0 軠 (<CJK Ideograph>) 13629 0x8EE1 軡 (<CJK Ideograph>) 13630 0x9024 逤 (<CJK Ideograph>) 13631 0x900B 逋 (<CJK Ideograph>) 13632 0x9011 逑 (<CJK Ideograph>) 13633 0x901C 逜 (<CJK Ideograph>) 13634 0x900C 逌 (<CJK Ideograph>) 13635 0x9021 逡 (<CJK Ideograph>) 13636 0x90EF 郯 (<CJK Ideograph>) 13637 0x90EA 郪 (<CJK Ideograph>) 13638 0x90F0 郰 (<CJK Ideograph>) 13639 0x90F4 郴 (<CJK Ideograph>) 13640 0x90F2 郲 (<CJK Ideograph>) 13641 0x90F3 郳 (<CJK Ideograph>) 13642 0x90D4 郔 (<CJK Ideograph>) 13643 0x90EB 郫 (<CJK Ideograph>) 13644 0x90EC 郬 (<CJK Ideograph>) 13645 0x90E9 郩 (<CJK Ideograph>) 13646 0x9156 酖 (<CJK Ideograph>) 13647 0x9158 酘 (<CJK Ideograph>) 13648 0x915A 酚 (<CJK Ideograph>) 13649 0x9153 酓 (<CJK Ideograph>) 13650 0x9155 酕 (<CJK Ideograph>) 13651 0x91EC 釬 (<CJK Ideograph>) 13652 0x91F4 釴 (<CJK Ideograph>) 13653 0x91F1 釱 (<CJK Ideograph>) 13654 0x91F3 釳 (<CJK Ideograph>) 13655 0x91F8 釸 (<CJK Ideograph>) 13656 0x91E4 釤 (<CJK Ideograph>) 13657 0x91F9 釹 (<CJK Ideograph>) 13658 0x91EA 釪 (<CJK Ideograph>) 13659 0x91EB 釫 (<CJK Ideograph>) 13660 0x91F7 釷 (<CJK Ideograph>) 13661 0x91E8 釨 (<CJK Ideograph>) 13662 0x91EE 釮 (<CJK Ideograph>) 13663 0x957A 镺 (<CJK Ideograph>) 13664 0x9586 閆 (<CJK Ideograph>) 13665 0x9588 閈 (<CJK Ideograph>) 13666 0x967C 陼 (<CJK Ideograph>) 13667 0x966D 陭 (<CJK Ideograph>) 13668 0x966B 陫 (<CJK Ideograph>) 13669 0x9671 陱 (<CJK Ideograph>) 13670 0x966F 陯 (<CJK Ideograph>) 13671 0x96BF 隿 (<CJK Ideograph>) 13672 0x976A 靪 (<CJK Ideograph>) 13673 0x9804 頄 (<CJK Ideograph>) 13674 0x98E5 飥 (<CJK Ideograph>) 13675 0x9997 馗 (<CJK Ideograph>) 13676 0x509B 傛 (<CJK Ideograph>) 13677 0x5095 傕 (<CJK Ideograph>) 13678 0x5094 傔 (<CJK Ideograph>) 13679 0x509E 傞 (<CJK Ideograph>) 13680 0x508B 傋 (<CJK Ideograph>) 13681 0x50A3 傣 (<CJK Ideograph>) 13682 0x5083 傃 (<CJK Ideograph>) 13683 0x508C 傌 (<CJK Ideograph>) 13684 0x508E 傎 (<CJK Ideograph>) 13685 0x509D 傝 (<CJK Ideograph>) 13686 0x5068 偨 (<CJK Ideograph>) 13687 0x509C 傜 (<CJK Ideograph>) 13688 0x5092 傒 (<CJK Ideograph>) 13689 0x5082 傂 (<CJK Ideograph>) 13690 0x5087 傇 (<CJK Ideograph>) 13691 0x515F 兟 (<CJK Ideograph>) 13692 0x51D4 凔 (<CJK Ideograph>) 13693 0x5312 匒 (<CJK Ideograph>) 13694 0x5311 匑 (<CJK Ideograph>) 13695 0x53A4 厤 (<CJK Ideograph>) 13696 0x53A7 厧 (<CJK Ideograph>) 13697 0x5591 喑 (<CJK Ideograph>) 13698 0x55A8 喨 (<CJK Ideograph>) 13699 0x55A5 喥 (<CJK Ideograph>) 13700 0x55AD 喭 (<CJK Ideograph>) 13701 0x5577 啷 (<CJK Ideograph>) 13702 0x5645 噅 (<CJK Ideograph>) 13703 0x55A2 喢 (<CJK Ideograph>) 13704 0x5593 喓 (<CJK Ideograph>) 13705 0x5588 喈 (<CJK Ideograph>) 13706 0x558F 喏 (<CJK Ideograph>) 13707 0x55B5 喵 (<CJK Ideograph>) 13708 0x5581 喁 (<CJK Ideograph>) 13709 0x55A3 喣 (<CJK Ideograph>) 13710 0x5592 喒 (<CJK Ideograph>) 13711 0x55A4 喤 (<CJK Ideograph>) 13712 0x557D 啽 (<CJK Ideograph>) 13713 0x558C 喌 (<CJK Ideograph>) 13714 0x55A6 喦 (<CJK Ideograph>) 13715 0x557F 啿 (<CJK Ideograph>) 13716 0x5595 喕 (<CJK Ideograph>) 13717 0x55A1 喡 (<CJK Ideograph>) 13718 0x558E 喎 (<CJK Ideograph>) 13719 0x570C 圌 (<CJK Ideograph>) 13720 0x5829 堩 (<CJK Ideograph>) 13721 0x5837 堷 (<CJK Ideograph>) 13722 0x5819 堙 (<CJK Ideograph>) 13723 0x581E 堞 (<CJK Ideograph>) 13724 0x5827 堧 (<CJK Ideograph>) 13725 0x5823 堣 (<CJK Ideograph>) 13726 0x5828 堨 (<CJK Ideograph>) 13727 0x57F5 埵 (<CJK Ideograph>) 13728 0x5848 塈 (<CJK Ideograph>) 13729 0x5825 堥 (<CJK Ideograph>) 13730 0x581C 堜 (<CJK Ideograph>) 13731 0x581B 堛 (<CJK Ideograph>) 13732 0x5833 堳 (<CJK Ideograph>) 13733 0x583F 堿 (<CJK Ideograph>) 13734 0x5836 堶 (<CJK Ideograph>) 13735 0x582E 堮 (<CJK Ideograph>) 13736 0x5839 堹 (<CJK Ideograph>) 13737 0x5838 堸 (<CJK Ideograph>) 13738 0x582D 堭 (<CJK Ideograph>) 13739 0x582C 堬 (<CJK Ideograph>) 13740 0x583B 堻 (<CJK Ideograph>) 13741 0x5961 奡 (<CJK Ideograph>) 13742 0x5AAF 媯 (<CJK Ideograph>) 13743 0x5A94 媔 (<CJK Ideograph>) 13744 0x5A9F 媟 (<CJK Ideograph>) 13745 0x5A7A 婺 (<CJK Ideograph>) 13746 0x5AA2 媢 (<CJK Ideograph>) 13747 0x5A9E 媞 (<CJK Ideograph>) 13748 0x5A78 婸 (<CJK Ideograph>) 13749 0x5AA6 媦 (<CJK Ideograph>) 13750 0x5A7C 婼 (<CJK Ideograph>) 13751 0x5AA5 媥 (<CJK Ideograph>) 13752 0x5AAC 媬 (<CJK Ideograph>) 13753 0x5A95 媕 (<CJK Ideograph>) 13754 0x5AAE 媮 (<CJK Ideograph>) 13755 0x5A37 娷 (<CJK Ideograph>) 13756 0x5A84 媄 (<CJK Ideograph>) 13757 0x5A8A 媊 (<CJK Ideograph>) 13758 0x5A97 媗 (<CJK Ideograph>) 13759 0x5A83 媃 (<CJK Ideograph>) 13760 0x5A8B 媋 (<CJK Ideograph>) 13761 0x5AA9 媩 (<CJK Ideograph>) 13762 0x5A7B 婻 (<CJK Ideograph>) 13763 0x5A7D 婽 (<CJK Ideograph>) 13764 0x5A8C 媌 (<CJK Ideograph>) 13765 0x5A9C 媜 (<CJK Ideograph>) 13766 0x5A8F 媏 (<CJK Ideograph>) 13767 0x5A93 媓 (<CJK Ideograph>) 13768 0x5A9D 媝 (<CJK Ideograph>) 13769 0x5BEA 寪 (<CJK Ideograph>) 13770 0x5BCD 寍 (<CJK Ideograph>) 13771 0x5BCB 寋 (<CJK Ideograph>) 13772 0x5BD4 寔 (<CJK Ideograph>) 13773 0x5BD1 寑 (<CJK Ideograph>) 13774 0x5BCA 寊 (<CJK Ideograph>) 13775 0x5BCE 寎 (<CJK Ideograph>) 13776 0x5C0C 尌 (<CJK Ideograph>) 13777 0x5C30 尰 (<CJK Ideograph>) 13778 0x5D37 崷 (<CJK Ideograph>) 13779 0x5D43 嵃 (<CJK Ideograph>) 13780 0x5D6B 嵫 (<CJK Ideograph>) 13781 0x5D41 嵁 (<CJK Ideograph>) 13782 0x5D4B 嵋 (<CJK Ideograph>) 13783 0x5D3F 崿 (<CJK Ideograph>) 13784 0x5D35 崵 (<CJK Ideograph>) 13785 0x5D51 嵑 (<CJK Ideograph>) 13786 0x5D4E 嵎 (<CJK Ideograph>) 13787 0x5D55 嵕 (<CJK Ideograph>) 13788 0x5D33 崳 (<CJK Ideograph>) 13789 0x5D3A 崺 (<CJK Ideograph>) 13790 0x5D52 嵒 (<CJK Ideograph>) 13791 0x5D3D 崽 (<CJK Ideograph>) 13792 0x5D31 崱 (<CJK Ideograph>) 13793 0x5D59 嵙 (<CJK Ideograph>) 13794 0x5D42 嵂 (<CJK Ideograph>) 13795 0x5D39 崹 (<CJK Ideograph>) 13796 0x5D49 嵉 (<CJK Ideograph>) 13797 0x5D38 崸 (<CJK Ideograph>) 13798 0x5D3C 崼 (<CJK Ideograph>) 13799 0x5D32 崲 (<CJK Ideograph>) 13800 0x5D36 崶 (<CJK Ideograph>) 13801 0x5D40 嵀 (<CJK Ideograph>) 13802 0x5D45 嵅 (<CJK Ideograph>) 13803 0x5E44 幄 (<CJK Ideograph>) 13804 0x5E41 幁 (<CJK Ideograph>) 13805 0x5F58 彘 (<CJK Ideograph>) 13806 0x5FA6 徦 (<CJK Ideograph>) 13807 0x5FA5 徥 (<CJK Ideograph>) 13808 0x5FAB 徫 (<CJK Ideograph>) 13809 0x60C9 惉 (<CJK Ideograph>) 13810 0x60B9 悹 (<CJK Ideograph>) 13811 0x60CC 惌 (<CJK Ideograph>) 13812 0x60E2 惢 (<CJK Ideograph>) 13813 0x60CE 惎 (<CJK Ideograph>) 13814 0x60C4 惄 (<CJK Ideograph>) 13815 0x6114 愔 (<CJK Ideograph>) 13816 0x60F2 惲 (<CJK Ideograph>) 13817 0x610A 愊 (<CJK Ideograph>) 13818 0x6116 愖 (<CJK Ideograph>) 13819 0x6105 愅 (<CJK Ideograph>) 13820 0x60F5 惵 (<CJK Ideograph>) 13821 0x6113 愓 (<CJK Ideograph>) 13822 0x60F8 惸 (<CJK Ideograph>) 13823 0x60FC 惼 (<CJK Ideograph>) 13824 0x60FE 惾 (<CJK Ideograph>) 13825 0x60C1 惁 (<CJK Ideograph>) 13826 0x6103 愃 (<CJK Ideograph>) 13827 0x6118 愘 (<CJK Ideograph>) 13828 0x611D 愝 (<CJK Ideograph>) 13829 0x6110 愐 (<CJK Ideograph>) 13830 0x60FF 惿 (<CJK Ideograph>) 13831 0x6104 愄 (<CJK Ideograph>) 13832 0x610B 愋 (<CJK Ideograph>) 13833 0x624A 扊 (<CJK Ideograph>) 13834 0x6394 掔 (<CJK Ideograph>) 13835 0x63B1 掱 (<CJK Ideograph>) 13836 0x63B0 掰 (<CJK Ideograph>) 13837 0x63CE 揎 (<CJK Ideograph>) 13838 0x63E5 揥 (<CJK Ideograph>) 13839 0x63E8 揨 (<CJK Ideograph>) 13840 0x63EF 揯 (<CJK Ideograph>) 13841 0x63C3 揃 (<CJK Ideograph>) 13842 0x649D 撝 (<CJK Ideograph>) 13843 0x63F3 揳 (<CJK Ideograph>) 13844 0x63CA 揊 (<CJK Ideograph>) 13845 0x63E0 揠 (<CJK Ideograph>) 13846 0x63F6 揶 (<CJK Ideograph>) 13847 0x63D5 揕 (<CJK Ideograph>) 13848 0x63F2 揲 (<CJK Ideograph>) 13849 0x63F5 揵 (<CJK Ideograph>) 13850 0x6461 摡 (<CJK Ideograph>) 13851 0x63DF 揟 (<CJK Ideograph>) 13852 0x63BE 掾 (<CJK Ideograph>) 13853 0x63DD 揝 (<CJK Ideograph>) 13854 0x63DC 揜 (<CJK Ideograph>) 13855 0x63C4 揄 (<CJK Ideograph>) 13856 0x63D8 揘 (<CJK Ideograph>) 13857 0x63D3 揓 (<CJK Ideograph>) 13858 0x63C2 揂 (<CJK Ideograph>) 13859 0x63C7 揇 (<CJK Ideograph>) 13860 0x63CC 揌 (<CJK Ideograph>) 13861 0x63CB 揋 (<CJK Ideograph>) 13862 0x63C8 揈 (<CJK Ideograph>) 13863 0x63F0 揰 (<CJK Ideograph>) 13864 0x63D7 揗 (<CJK Ideograph>) 13865 0x63D9 揙 (<CJK Ideograph>) 13866 0x6532 攲 (<CJK Ideograph>) 13867 0x6567 敧 (<CJK Ideograph>) 13868 0x656A 敪 (<CJK Ideograph>) 13869 0x6564 敤 (<CJK Ideograph>) 13870 0x655C 敜 (<CJK Ideograph>) 13871 0x6568 敨 (<CJK Ideograph>) 13872 0x6565 敥 (<CJK Ideograph>) 13873 0x658C 斌 (<CJK Ideograph>) 13874 0x659D 斝 (<CJK Ideograph>) 13875 0x659E 斞 (<CJK Ideograph>) 13876 0x65AE 斮 (<CJK Ideograph>) 13877 0x65D0 旐 (<CJK Ideograph>) 13878 0x65D2 旒 (<CJK Ideograph>) 13879 0x667C 晼 (<CJK Ideograph>) 13880 0x666C 晬 (<CJK Ideograph>) 13881 0x667B 晻 (<CJK Ideograph>) 13882 0x6680 暀 (<CJK Ideograph>) 13883 0x6671 晱 (<CJK Ideograph>) 13884 0x6679 晹 (<CJK Ideograph>) 13885 0x666A 晪 (<CJK Ideograph>) 13886 0x6672 晲 (<CJK Ideograph>) 13887 0x6701 朁 (<CJK Ideograph>) 13888 0x690C 椌 (<CJK Ideograph>) 13889 0x68D3 棓 (<CJK Ideograph>) 13890 0x6904 椄 (<CJK Ideograph>) 13891 0x68DC 棜 (<CJK Ideograph>) 13892 0x692A 椪 (<CJK Ideograph>) 13893 0x68EC 棬 (<CJK Ideograph>) 13894 0x68EA 棪 (<CJK Ideograph>) 13895 0x68F1 棱 (<CJK Ideograph>) 13896 0x690F 椏 (<CJK Ideograph>) 13897 0x68D6 棖 (<CJK Ideograph>) 13898 0x68F7 棷 (<CJK Ideograph>) 13899 0x68EB 棫 (<CJK Ideograph>) 13900 0x68E4 棤 (<CJK Ideograph>) 13901 0x68F6 棶 (<CJK Ideograph>) 13902 0x6913 椓 (<CJK Ideograph>) 13903 0x6910 椐 (<CJK Ideograph>) 13904 0x68F3 棳 (<CJK Ideograph>) 13905 0x68E1 棡 (<CJK Ideograph>) 13906 0x6907 椇 (<CJK Ideograph>) 13907 0x68CC 棌 (<CJK Ideograph>) 13908 0x6908 椈 (<CJK Ideograph>) 13909 0x6970 楰 (<CJK Ideograph>) 13910 0x68B4 梴 (<CJK Ideograph>) 13911 0x6911 椑 (<CJK Ideograph>) 13912 0x68EF 棯 (<CJK Ideograph>) 13913 0x68C6 棆 (<CJK Ideograph>) 13914 0x6914 椔 (<CJK Ideograph>) 13915 0x68F8 棸 (<CJK Ideograph>) 13916 0x68D0 棐 (<CJK Ideograph>) 13917 0x68FD 棽 (<CJK Ideograph>) 13918 0x68FC 棼 (<CJK Ideograph>) 13919 0x68E8 棨 (<CJK Ideograph>) 13920 0x690B 椋 (<CJK Ideograph>) 13921 0x690A 椊 (<CJK Ideograph>) 13922 0x6917 椗 (<CJK Ideograph>) 13923 0x68CE 棎 (<CJK Ideograph>) 13924 0x68C8 棈 (<CJK Ideograph>) 13925 0x68DD 棝 (<CJK Ideograph>) 13926 0x68DE 棞 (<CJK Ideograph>) 13927 0x68E6 棦 (<CJK Ideograph>) 13928 0x68F4 棴 (<CJK Ideograph>) 13929 0x68D1 棑 (<CJK Ideograph>) 13930 0x6906 椆 (<CJK Ideograph>) 13931 0x68D4 棔 (<CJK Ideograph>) 13932 0x68E9 棩 (<CJK Ideograph>) 13933 0x6915 椕 (<CJK Ideograph>) 13934 0x6925 椥 (<CJK Ideograph>) 13935 0x68C7 棇 (<CJK Ideograph>) 13936 0x6B39 欹 (<CJK Ideograph>) 13937 0x6B3B 欻 (<CJK Ideograph>) 13938 0x6B3F 欿 (<CJK Ideograph>) 13939 0x6B3C 欼 (<CJK Ideograph>) 13940 0x6B94 殔 (<CJK Ideograph>) 13941 0x6B97 殗 (<CJK Ideograph>) 13942 0x6B99 殙 (<CJK Ideograph>) 13943 0x6B95 殕 (<CJK Ideograph>) 13944 0x6BBD 殽 (<CJK Ideograph>) 13945 0x6BF0 毰 (<CJK Ideograph>) 13946 0x6BF2 毲 (<CJK Ideograph>) 13947 0x6BF3 毳 (<CJK Ideograph>) 13948 0x6C30 氰 (<CJK Ideograph>) 13949 0x6DFC 淼 (<CJK Ideograph>) 13950 0x6E46 湆 (<CJK Ideograph>) 13951 0x6E47 湇 (<CJK Ideograph>) 13952 0x6E1F 渟 (<CJK Ideograph>) 13953 0x6E49 湉 (<CJK Ideograph>) 13954 0x6E88 溈 (<CJK Ideograph>) 13955 0x6E3C 渼 (<CJK Ideograph>) 13956 0x6E3D 渽 (<CJK Ideograph>) 13957 0x6E45 湅 (<CJK Ideograph>) 13958 0x6E62 湢 (<CJK Ideograph>) 13959 0x6E2B 渫 (<CJK Ideograph>) 13960 0x6E3F 渿 (<CJK Ideograph>) 13961 0x6E41 湁 (<CJK Ideograph>) 13962 0x6E5D 湝 (<CJK Ideograph>) 13963 0x6E73 湳 (<CJK Ideograph>) 13964 0x6E1C 渜 (<CJK Ideograph>) 13965 0x6E33 渳 (<CJK Ideograph>) 13966 0x6E4B 湋 (<CJK Ideograph>) 13967 0x6E40 湀 (<CJK Ideograph>) 13968 0x6E51 湑 (<CJK Ideograph>) 13969 0x6E3B 渻 (<CJK Ideograph>) 13970 0x6E03 渃 (<CJK Ideograph>) 13971 0x6E2E 渮 (<CJK Ideograph>) 13972 0x6E5E 湞 (<CJK Ideograph>) 13973 0x6E68 湨 (<CJK Ideograph>) 13974 0x6E5C 湜 (<CJK Ideograph>) 13975 0x6E61 湡 (<CJK Ideograph>) 13976 0x6E31 渱 (<CJK Ideograph>) 13977 0x6E28 渨 (<CJK Ideograph>) 13978 0x6E60 湠 (<CJK Ideograph>) 13979 0x6E71 湱 (<CJK Ideograph>) 13980 0x6E6B 湫 (<CJK Ideograph>) 13981 0x6E39 渹 (<CJK Ideograph>) 13982 0x6E22 渢 (<CJK Ideograph>) 13983 0x6E30 渰 (<CJK Ideograph>) 13984 0x6E53 湓 (<CJK Ideograph>) 13985 0x6E65 湥 (<CJK Ideograph>) 13986 0x6E27 渧 (<CJK Ideograph>) 13987 0x6E78 湸 (<CJK Ideograph>) 13988 0x6E64 湤 (<CJK Ideograph>) 13989 0x6E77 湷 (<CJK Ideograph>) 13990 0x6E55 湕 (<CJK Ideograph>) 13991 0x6E79 湹 (<CJK Ideograph>) 13992 0x6E52 湒 (<CJK Ideograph>) 13993 0x6E66 湦 (<CJK Ideograph>) 13994 0x6E35 渵 (<CJK Ideograph>) 13995 0x6E36 渶 (<CJK Ideograph>) 13996 0x6E5A 湚 (<CJK Ideograph>) 13997 0x7120 焠 (<CJK Ideograph>) 13998 0x711E 焞 (<CJK Ideograph>) 13999 0x712F 焯 (<CJK Ideograph>) 14000 0x70FB 烻 (<CJK Ideograph>) 14001 0x712E 焮 (<CJK Ideograph>) 14002 0x7131 焱 (<CJK Ideograph>) 14003 0x7123 焣 (<CJK Ideograph>) 14004 0x7125 焥 (<CJK Ideograph>) 14005 0x7122 焢 (<CJK Ideograph>) 14006 0x7132 焲 (<CJK Ideograph>) 14007 0x711F 焟 (<CJK Ideograph>) 14008 0x7128 焨 (<CJK Ideograph>) 14009 0x713A 焺 (<CJK Ideograph>) 14010 0x711B 焛 (<CJK Ideograph>) 14011 0x724B 牋 (<CJK Ideograph>) 14012 0x725A 牚 (<CJK Ideograph>) 14013 0x7288 犈 (<CJK Ideograph>) 14014 0x7289 犉 (<CJK Ideograph>) 14015 0x7286 犆 (<CJK Ideograph>) 14016 0x7285 犅 (<CJK Ideograph>) 14017 0x728B 犋 (<CJK Ideograph>) 14018 0x7312 猒 (<CJK Ideograph>) 14019 0x730B 猋 (<CJK Ideograph>) 14020 0x7330 猰 (<CJK Ideograph>) 14021 0x7322 猢 (<CJK Ideograph>) 14022 0x7331 猱 (<CJK Ideograph>) 14023 0x7333 猳 (<CJK Ideograph>) 14024 0x7327 猧 (<CJK Ideograph>) 14025 0x7332 猲 (<CJK Ideograph>) 14026 0x732D 猭 (<CJK Ideograph>) 14027 0x7326 猦 (<CJK Ideograph>) 14028 0x7323 猣 (<CJK Ideograph>) 14029 0x7335 猵 (<CJK Ideograph>) 14030 0x730C 猌 (<CJK Ideograph>) 14031 0x742E 琮 (<CJK Ideograph>) 14032 0x742C 琬 (<CJK Ideograph>) 14033 0x7430 琰 (<CJK Ideograph>) 14034 0x742B 琫 (<CJK Ideograph>) 14035 0x7416 琖 (<CJK Ideograph>) 14036 0x741A 琚 (<CJK Ideograph>) 14037 0x7421 琡 (<CJK Ideograph>) 14038 0x742D 琭 (<CJK Ideograph>) 14039 0x7431 琱 (<CJK Ideograph>) 14040 0x7424 琤 (<CJK Ideograph>) 14041 0x7423 琣 (<CJK Ideograph>) 14042 0x741D 琝 (<CJK Ideograph>) 14043 0x7429 琩 (<CJK Ideograph>) 14044 0x7420 琠 (<CJK Ideograph>) 14045 0x7432 琲 (<CJK Ideograph>) 14046 0x74FB 瓻 (<CJK Ideograph>) 14047 0x752F 甯 (<CJK Ideograph>) 14048 0x756F 畯 (<CJK Ideograph>) 14049 0x756C 畬 (<CJK Ideograph>) 14050 0x75E7 痧 (<CJK Ideograph>) 14051 0x75DA 痚 (<CJK Ideograph>) 14052 0x75E1 痡 (<CJK Ideograph>) 14053 0x75E6 痦 (<CJK Ideograph>) 14054 0x75DD 痝 (<CJK Ideograph>) 14055 0x75DF 痟 (<CJK Ideograph>) 14056 0x75E4 痤 (<CJK Ideograph>) 14057 0x75D7 痗 (<CJK Ideograph>) 14058 0x7695 皕 (<CJK Ideograph>) 14059 0x7692 皒 (<CJK Ideograph>) 14060 0x76DA 盚 (<CJK Ideograph>) 14061 0x7746 睆 (<CJK Ideograph>) 14062 0x7747 睇 (<CJK Ideograph>) 14063 0x7744 睄 (<CJK Ideograph>) 14064 0x774D 睍 (<CJK Ideograph>) 14065 0x7745 睅 (<CJK Ideograph>) 14066 0x774A 睊 (<CJK Ideograph>) 14067 0x774E 睎 (<CJK Ideograph>) 14068 0x774B 睋 (<CJK Ideograph>) 14069 0x774C 睌 (<CJK Ideograph>) 14070 0x77DE 矞 (<CJK Ideograph>) 14071 0x77EC 矬 (<CJK Ideograph>) 14072 0x7860 硠 (<CJK Ideograph>) 14073 0x7864 硤 (<CJK Ideograph>) 14074 0x7865 硥 (<CJK Ideograph>) 14075 0x785C 硜 (<CJK Ideograph>) 14076 0x786D 硭 (<CJK Ideograph>) 14077 0x7871 硱 (<CJK Ideograph>) 14078 0x786A 硪 (<CJK Ideograph>) 14079 0x786E 确 (<CJK Ideograph>) 14080 0x7870 硰 (<CJK Ideograph>) 14081 0x7869 硩 (<CJK Ideograph>) 14082 0x7868 硨 (<CJK Ideograph>) 14083 0x785E 硞 (<CJK Ideograph>) 14084 0x7862 硢 (<CJK Ideograph>) 14085 0x7974 祴 (<CJK Ideograph>) 14086 0x7973 祳 (<CJK Ideograph>) 14087 0x7972 祲 (<CJK Ideograph>) 14088 0x7970 祰 (<CJK Ideograph>) 14089 0x7A02 稂 (<CJK Ideograph>) 14090 0x7A0A 稊 (<CJK Ideograph>) 14091 0x7A03 稃 (<CJK Ideograph>) 14092 0x7A0C 稌 (<CJK Ideograph>) 14093 0x7A04 稄 (<CJK Ideograph>) 14094 0x7A99 窙 (<CJK Ideograph>) 14095 0x7AE6 竦 (<CJK Ideograph>) 14096 0x7AE4 竤 (<CJK Ideograph>) 14097 0x7B4A 筊 (<CJK Ideograph>) 14098 0x7B3B 笻 (<CJK Ideograph>) 14099 0x7B44 筄 (<CJK Ideograph>) 14100 0x7B48 筈 (<CJK Ideograph>) 14101 0x7B4C 筌 (<CJK Ideograph>) 14102 0x7B4E 筎 (<CJK Ideograph>) 14103 0x7B40 筀 (<CJK Ideograph>) 14104 0x7B58 筘 (<CJK Ideograph>) 14105 0x7B45 筅 (<CJK Ideograph>) 14106 0x7CA2 粢 (<CJK Ideograph>) 14107 0x7C9E 粞 (<CJK Ideograph>) 14108 0x7CA8 粨 (<CJK Ideograph>) 14109 0x7CA1 粡 (<CJK Ideograph>) 14110 0x7D58 絘 (<CJK Ideograph>) 14111 0x7D6F 絯 (<CJK Ideograph>) 14112 0x7D63 絣 (<CJK Ideograph>) 14113 0x7D53 絓 (<CJK Ideograph>) 14114 0x7D56 絖 (<CJK Ideograph>) 14115 0x7D67 絧 (<CJK Ideograph>) 14116 0x7D6A 絪 (<CJK Ideograph>) 14117 0x7D4F 絏 (<CJK Ideograph>) 14118 0x7D6D 絭 (<CJK Ideograph>) 14119 0x7D5C 絜 (<CJK Ideograph>) 14120 0x7D6B 絫 (<CJK Ideograph>) 14121 0x7D52 絒 (<CJK Ideograph>) 14122 0x7D54 絔 (<CJK Ideograph>) 14123 0x7D69 絩 (<CJK Ideograph>) 14124 0x7D51 絑 (<CJK Ideograph>) 14125 0x7D5F 絟 (<CJK Ideograph>) 14126 0x7D4E 絎 (<CJK Ideograph>) 14127 0x7F3E 缾 (<CJK Ideograph>) 14128 0x7F3F 缿 (<CJK Ideograph>) 14129 0x7F65 罥 (<CJK Ideograph>) 14130 0x7F66 罦 (<CJK Ideograph>) 14131 0x7FA2 羢 (<CJK Ideograph>) 14132 0x7FA0 羠 (<CJK Ideograph>) 14133 0x7FA1 羡 (<CJK Ideograph>) 14134 0x7FD7 翗 (<CJK Ideograph>) 14135 0x8051 聑 (<CJK Ideograph>) 14136 0x804F 聏 (<CJK Ideograph>) 14137 0x8050 聐 (<CJK Ideograph>) 14138 0x80FE 胾 (<CJK Ideograph>) 14139 0x80D4 胔 (<CJK Ideograph>) 14140 0x8143 腃 (<CJK Ideograph>) 14141 0x814A 腊 (<CJK Ideograph>) 14142 0x8152 腒 (<CJK Ideograph>) 14143 0x814F 腏 (<CJK Ideograph>) 14144 0x8147 腇 (<CJK Ideograph>) 14145 0x813D 脽 (<CJK Ideograph>) 14146 0x814D 腍 (<CJK Ideograph>) 14147 0x813A 脺 (<CJK Ideograph>) 14148 0x81E6 臦 (<CJK Ideograph>) 14149 0x81EE 臮 (<CJK Ideograph>) 14150 0x81F7 臷 (<CJK Ideograph>) 14151 0x81F8 臸 (<CJK Ideograph>) 14152 0x81F9 臹 (<CJK Ideograph>) 14153 0x8204 舄 (<CJK Ideograph>) 14154 0x823C 舼 (<CJK Ideograph>) 14155 0x823D 舽 (<CJK Ideograph>) 14156 0x823F 舿 (<CJK Ideograph>) 14157 0x8275 艵 (<CJK Ideograph>) 14158 0x833B 茻 (<CJK Ideograph>) 14159 0x83CF 菏 (<CJK Ideograph>) 14160 0x83F9 菹 (<CJK Ideograph>) 14161 0x8423 萣 (<CJK Ideograph>) 14162 0x83C0 菀 (<CJK Ideograph>) 14163 0x83E8 菨 (<CJK Ideograph>) 14164 0x8412 萒 (<CJK Ideograph>) 14165 0x83E7 菧 (<CJK Ideograph>) 14166 0x83E4 菤 (<CJK Ideograph>) 14167 0x83FC 菼 (<CJK Ideograph>) 14168 0x83F6 菶 (<CJK Ideograph>) 14169 0x8410 萐 (<CJK Ideograph>) 14170 0x83C6 菆 (<CJK Ideograph>) 14171 0x83C8 菈 (<CJK Ideograph>) 14172 0x83EB 菫 (<CJK Ideograph>) 14173 0x83E3 菣 (<CJK Ideograph>) 14174 0x83BF 莿 (<CJK Ideograph>) 14175 0x8401 萁 (<CJK Ideograph>) 14176 0x83DD 菝 (<CJK Ideograph>) 14177 0x83E5 菥 (<CJK Ideograph>) 14178 0x83D8 菘 (<CJK Ideograph>) 14179 0x83FF 菿 (<CJK Ideograph>) 14180 0x83E1 菡 (<CJK Ideograph>) 14181 0x83CB 菋 (<CJK Ideograph>) 14182 0x83CE 菎 (<CJK Ideograph>) 14183 0x83D6 菖 (<CJK Ideograph>) 14184 0x83F5 菵 (<CJK Ideograph>) 14185 0x83C9 菉 (<CJK Ideograph>) 14186 0x8409 萉 (<CJK Ideograph>) 14187 0x840F 萏 (<CJK Ideograph>) 14188 0x83DE 菞 (<CJK Ideograph>) 14189 0x8411 萑 (<CJK Ideograph>) 14190 0x8406 萆 (<CJK Ideograph>) 14191 0x83C2 菂 (<CJK Ideograph>) 14192 0x83F3 菳 (<CJK Ideograph>) 14193 0x83D5 菕 (<CJK Ideograph>) 14194 0x83FA 菺 (<CJK Ideograph>) 14195 0x83C7 菇 (<CJK Ideograph>) 14196 0x83D1 菑 (<CJK Ideograph>) 14197 0x83EA 菪 (<CJK Ideograph>) 14198 0x8413 萓 (<CJK Ideograph>) 14199 0x83C3 菃 (<CJK Ideograph>) 14200 0x83EC 菬 (<CJK Ideograph>) 14201 0x83EE 菮 (<CJK Ideograph>) 14202 0x83C4 菄 (<CJK Ideograph>) 14203 0x83FB 菻 (<CJK Ideograph>) 14204 0x83D7 菗 (<CJK Ideograph>) 14205 0x83E2 菢 (<CJK Ideograph>) 14206 0x841B 萛 (<CJK Ideograph>) 14207 0x83DB 菛 (<CJK Ideograph>) 14208 0x83FE 菾 (<CJK Ideograph>) 14209 0x86D8 蛘 (<CJK Ideograph>) 14210 0x86E2 蛢 (<CJK Ideograph>) 14211 0x86E6 蛦 (<CJK Ideograph>) 14212 0x86D3 蛓 (<CJK Ideograph>) 14213 0x86E3 蛣 (<CJK Ideograph>) 14214 0x86DA 蛚 (<CJK Ideograph>) 14215 0x86EA 蛪 (<CJK Ideograph>) 14216 0x86DD 蛝 (<CJK Ideograph>) 14217 0x86EB 蛫 (<CJK Ideograph>) 14218 0x86DC 蛜 (<CJK Ideograph>) 14219 0x86EC 蛬 (<CJK Ideograph>) 14220 0x86E9 蛩 (<CJK Ideograph>) 14221 0x86D7 蛗 (<CJK Ideograph>) 14222 0x86E8 蛨 (<CJK Ideograph>) 14223 0x86D1 蛑 (<CJK Ideograph>) 14224 0x8848 衈 (<CJK Ideograph>) 14225 0x8856 衖 (<CJK Ideograph>) 14226 0x8855 衕 (<CJK Ideograph>) 14227 0x88BA 袺 (<CJK Ideograph>) 14228 0x88D7 裗 (<CJK Ideograph>) 14229 0x88B9 袹 (<CJK Ideograph>) 14230 0x88B8 袸 (<CJK Ideograph>) 14231 0x88C0 裀 (<CJK Ideograph>) 14232 0x88BE 袾 (<CJK Ideograph>) 14233 0x88B6 袶 (<CJK Ideograph>) 14234 0x88BC 袼 (<CJK Ideograph>) 14235 0x88B7 袷 (<CJK Ideograph>) 14236 0x88BD 袽 (<CJK Ideograph>) 14237 0x88B2 袲 (<CJK Ideograph>) 14238 0x8901 褁 (<CJK Ideograph>) 14239 0x88C9 裉 (<CJK Ideograph>) 14240 0x8995 覕 (<CJK Ideograph>) 14241 0x8998 覘 (<CJK Ideograph>) 14242 0x8997 覗 (<CJK Ideograph>) 14243 0x89DD 觝 (<CJK Ideograph>) 14244 0x89DA 觚 (<CJK Ideograph>) 14245 0x89DB 觛 (<CJK Ideograph>) 14246 0x8A4E 詎 (<CJK Ideograph>) 14247 0x8A4D 詍 (<CJK Ideograph>) 14248 0x8A39 訹 (<CJK Ideograph>) 14249 0x8A59 詙 (<CJK Ideograph>) 14250 0x8A40 詀 (<CJK Ideograph>) 14251 0x8A57 詗 (<CJK Ideograph>) 14252 0x8A58 詘 (<CJK Ideograph>) 14253 0x8A44 詄 (<CJK Ideograph>) 14254 0x8A45 詅 (<CJK Ideograph>) 14255 0x8A52 詒 (<CJK Ideograph>) 14256 0x8A48 詈 (<CJK Ideograph>) 14257 0x8A51 詑 (<CJK Ideograph>) 14258 0x8A4A 詊 (<CJK Ideograph>) 14259 0x8A4C 詌 (<CJK Ideograph>) 14260 0x8A4F 詏 (<CJK Ideograph>) 14261 0x8C5F 豟 (<CJK Ideograph>) 14262 0x8C81 貁 (<CJK Ideograph>) 14263 0x8C80 貀 (<CJK Ideograph>) 14264 0x8CBA 貺 (<CJK Ideograph>) 14265 0x8CBE 貾 (<CJK Ideograph>) 14266 0x8CB0 貰 (<CJK Ideograph>) 14267 0x8CB9 貹 (<CJK Ideograph>) 14268 0x8CB5 貵 (<CJK Ideograph>) 14269 0x8D84 趄 (<CJK Ideograph>) 14270 0x8D80 趀 (<CJK Ideograph>) 14271 0x8D89 趉 (<CJK Ideograph>) 14272 0x8DD8 跘 (<CJK Ideograph>) 14273 0x8DD3 跓 (<CJK Ideograph>) 14274 0x8DCD 跍 (<CJK Ideograph>) 14275 0x8DC7 跇 (<CJK Ideograph>) 14276 0x8DD6 跖 (<CJK Ideograph>) 14277 0x8DDC 跜 (<CJK Ideograph>) 14278 0x8DCF 跏 (<CJK Ideograph>) 14279 0x8DD5 跕 (<CJK Ideograph>) 14280 0x8DD9 跙 (<CJK Ideograph>) 14281 0x8DC8 跈 (<CJK Ideograph>) 14282 0x8DD7 跗 (<CJK Ideograph>) 14283 0x8DC5 跅 (<CJK Ideograph>) 14284 0x8EEF 軯 (<CJK Ideograph>) 14285 0x8EF7 軷 (<CJK Ideograph>) 14286 0x8EFA 軺 (<CJK Ideograph>) 14287 0x8EF9 軹 (<CJK Ideograph>) 14288 0x8EE6 軦 (<CJK Ideograph>) 14289 0x8EEE 軮 (<CJK Ideograph>) 14290 0x8EE5 軥 (<CJK Ideograph>) 14291 0x8EF5 軵 (<CJK Ideograph>) 14292 0x8EE7 軧 (<CJK Ideograph>) 14293 0x8EE8 軨 (<CJK Ideograph>) 14294 0x8EF6 軶 (<CJK Ideograph>) 14295 0x8EEB 軫 (<CJK Ideograph>) 14296 0x8EF1 軱 (<CJK Ideograph>) 14297 0x8EEC 軬 (<CJK Ideograph>) 14298 0x8EF4 軴 (<CJK Ideograph>) 14299 0x8EE9 軩 (<CJK Ideograph>) 14300 0x902D 逭 (<CJK Ideograph>) 14301 0x9034 逴 (<CJK Ideograph>) 14302 0x902F 逯 (<CJK Ideograph>) 14303 0x9106 鄆 (<CJK Ideograph>) 14304 0x912C 鄬 (<CJK Ideograph>) 14305 0x9104 鄄 (<CJK Ideograph>) 14306 0x90FF 郿 (<CJK Ideograph>) 14307 0x90FC 郼 (<CJK Ideograph>) 14308 0x9108 鄈 (<CJK Ideograph>) 14309 0x90F9 郹 (<CJK Ideograph>) 14310 0x90FB 郻 (<CJK Ideograph>) 14311 0x9101 鄁 (<CJK Ideograph>) 14312 0x9100 鄀 (<CJK Ideograph>) 14313 0x9107 鄇 (<CJK Ideograph>) 14314 0x9105 鄅 (<CJK Ideograph>) 14315 0x9103 鄃 (<CJK Ideograph>) 14316 0x9161 酡 (<CJK Ideograph>) 14317 0x9164 酤 (<CJK Ideograph>) 14318 0x915F 酟 (<CJK Ideograph>) 14319 0x9162 酢 (<CJK Ideograph>) 14320 0x9160 酠 (<CJK Ideograph>) 14321 0x9201 鈁 (<CJK Ideograph>) 14322 0x920A 鈊 (<CJK Ideograph>) 14323 0x9225 鈥 (<CJK Ideograph>) 14324 0x9203 鈃 (<CJK Ideograph>) 14325 0x921A 鈚 (<CJK Ideograph>) 14326 0x9226 鈦 (<CJK Ideograph>) 14327 0x920F 鈏 (<CJK Ideograph>) 14328 0x920C 鈌 (<CJK Ideograph>) 14329 0x9200 鈀 (<CJK Ideograph>) 14330 0x9212 鈒 (<CJK Ideograph>) 14331 0x91FF 釿 (<CJK Ideograph>) 14332 0x91FD 釽 (<CJK Ideograph>) 14333 0x9206 鈆 (<CJK Ideograph>) 14334 0x9204 鈄 (<CJK Ideograph>) 14335 0x9227 鈧 (<CJK Ideograph>) 14336 0x9202 鈂 (<CJK Ideograph>) 14337 0x921C 鈜 (<CJK Ideograph>) 14338 0x9224 鈤 (<CJK Ideograph>) 14339 0x9219 鈙 (<CJK Ideograph>) 14340 0x9217 鈗 (<CJK Ideograph>) 14341 0x9205 鈅 (<CJK Ideograph>) 14342 0x9216 鈖 (<CJK Ideograph>) 14343 0x957B 镻 (<CJK Ideograph>) 14344 0x958D 閍 (<CJK Ideograph>) 14345 0x958C 閌 (<CJK Ideograph>) 14346 0x9590 閐 (<CJK Ideograph>) 14347 0x9687 隇 (<CJK Ideograph>) 14348 0x967E 陾 (<CJK Ideograph>) 14349 0x9688 隈 (<CJK Ideograph>) 14350 0x9689 隉 (<CJK Ideograph>) 14351 0x9683 隃 (<CJK Ideograph>) 14352 0x9680 隀 (<CJK Ideograph>) 14353 0x96C2 雂 (<CJK Ideograph>) 14354 0x96C8 雈 (<CJK Ideograph>) 14355 0x96C3 雃 (<CJK Ideograph>) 14356 0x96F1 雱 (<CJK Ideograph>) 14357 0x96F0 雰 (<CJK Ideograph>) 14358 0x976C 靬 (<CJK Ideograph>) 14359 0x9770 靰 (<CJK Ideograph>) 14360 0x976E 靮 (<CJK Ideograph>) 14361 0x9807 頇 (<CJK Ideograph>) 14362 0x98A9 颩 (<CJK Ideograph>) 14363 0x98EB 飫 (<CJK Ideograph>) 14364 0x9CE6 鳦 (<CJK Ideograph>) 14365 0x9EF9 黹 (<CJK Ideograph>) 14366 0x4E83 亃 (<CJK Ideograph>) 14367 0x4E84 亄 (<CJK Ideograph>) 14368 0x4EB6 亶 (<CJK Ideograph>) 14369 0x50BD 傽 (<CJK Ideograph>) 14370 0x50BF 傿 (<CJK Ideograph>) 14371 0x50C6 僆 (<CJK Ideograph>) 14372 0x50AE 傮 (<CJK Ideograph>) 14373 0x50C4 僄 (<CJK Ideograph>) 14374 0x50CA 僊 (<CJK Ideograph>) 14375 0x50B4 傴 (<CJK Ideograph>) 14376 0x50C8 僈 (<CJK Ideograph>) 14377 0x50C2 僂 (<CJK Ideograph>) 14378 0x50B0 傰 (<CJK Ideograph>) 14379 0x50C1 僁 (<CJK Ideograph>) 14380 0x50BA 傺 (<CJK Ideograph>) 14381 0x50B1 傱 (<CJK Ideograph>) 14382 0x50CB 僋 (<CJK Ideograph>) 14383 0x50C9 僉 (<CJK Ideograph>) 14384 0x50B6 傶 (<CJK Ideograph>) 14385 0x50B8 傸 (<CJK Ideograph>) 14386 0x51D7 凗 (<CJK Ideograph>) 14387 0x527A 剺 (<CJK Ideograph>) 14388 0x5278 剸 (<CJK Ideograph>) 14389 0x527B 剻 (<CJK Ideograph>) 14390 0x527C 剼 (<CJK Ideograph>) 14391 0x55C3 嗃 (<CJK Ideograph>) 14392 0x55DB 嗛 (<CJK Ideograph>) 14393 0x55CC 嗌 (<CJK Ideograph>) 14394 0x55D0 嗐 (<CJK Ideograph>) 14395 0x55CB 嗋 (<CJK Ideograph>) 14396 0x55CA 嗊 (<CJK Ideograph>) 14397 0x55DD 嗝 (<CJK Ideograph>) 14398 0x55C0 嗀 (<CJK Ideograph>) 14399 0x55D4 嗔 (<CJK Ideograph>) 14400 0x55C4 嗄 (<CJK Ideograph>) 14401 0x55E9 嗩 (<CJK Ideograph>) 14402 0x55BF 喿 (<CJK Ideograph>) 14403 0x55D2 嗒 (<CJK Ideograph>) 14404 0x558D 喍 (<CJK Ideograph>) 14405 0x55CF 嗏 (<CJK Ideograph>) 14406 0x55D5 嗕 (<CJK Ideograph>) 14407 0x55E2 嗢 (<CJK Ideograph>) 14408 0x55D6 嗖 (<CJK Ideograph>) 14409 0x55C8 嗈 (<CJK Ideograph>) 14410 0x55F2 嗲 (<CJK Ideograph>) 14411 0x55CD 嗍 (<CJK Ideograph>) 14412 0x55D9 嗙 (<CJK Ideograph>) 14413 0x55C2 嗂 (<CJK Ideograph>) 14414 0x5714 圔 (<CJK Ideograph>) 14415 0x5853 塓 (<CJK Ideograph>) 14416 0x5868 塨 (<CJK Ideograph>) 14417 0x5864 塤 (<CJK Ideograph>) 14418 0x584F 塏 (<CJK Ideograph>) 14419 0x584D 塍 (<CJK Ideograph>) 14420 0x5849 塉 (<CJK Ideograph>) 14421 0x586F 塯 (<CJK Ideograph>) 14422 0x5855 塕 (<CJK Ideograph>) 14423 0x584E 塎 (<CJK Ideograph>) 14424 0x585D 塝 (<CJK Ideograph>) 14425 0x5859 塙 (<CJK Ideograph>) 14426 0x5865 塥 (<CJK Ideograph>) 14427 0x585B 塛 (<CJK Ideograph>) 14428 0x583D 堽 (<CJK Ideograph>) 14429 0x5863 塣 (<CJK Ideograph>) 14430 0x5871 塱 (<CJK Ideograph>) 14431 0x58FC 壼 (<CJK Ideograph>) 14432 0x5AC7 嫇 (<CJK Ideograph>) 14433 0x5AC4 嫄 (<CJK Ideograph>) 14434 0x5ACB 嫋 (<CJK Ideograph>) 14435 0x5ABA 媺 (<CJK Ideograph>) 14436 0x5AB8 媸 (<CJK Ideograph>) 14437 0x5AB1 媱 (<CJK Ideograph>) 14438 0x5AB5 媵 (<CJK Ideograph>) 14439 0x5AB0 媰 (<CJK Ideograph>) 14440 0x5ABF 媿 (<CJK Ideograph>) 14441 0x5AC8 嫈 (<CJK Ideograph>) 14442 0x5ABB 媻 (<CJK Ideograph>) 14443 0x5AC6 嫆 (<CJK Ideograph>) 14444 0x5AB7 媷 (<CJK Ideograph>) 14445 0x5AC0 嫀 (<CJK Ideograph>) 14446 0x5ACA 嫊 (<CJK Ideograph>) 14447 0x5AB4 媴 (<CJK Ideograph>) 14448 0x5AB6 媶 (<CJK Ideograph>) 14449 0x5ACD 嫍 (<CJK Ideograph>) 14450 0x5AB9 媹 (<CJK Ideograph>) 14451 0x5A90 媐 (<CJK Ideograph>) 14452 0x5BD6 寖 (<CJK Ideograph>) 14453 0x5BD8 寘 (<CJK Ideograph>) 14454 0x5BD9 寙 (<CJK Ideograph>) 14455 0x5C1F 尟 (<CJK Ideograph>) 14456 0x5C33 尳 (<CJK Ideograph>) 14457 0x5D71 嵱 (<CJK Ideograph>) 14458 0x5D63 嵣 (<CJK Ideograph>) 14459 0x5D4A 嵊 (<CJK Ideograph>) 14460 0x5D65 嵥 (<CJK Ideograph>) 14461 0x5D72 嵲 (<CJK Ideograph>) 14462 0x5D6C 嵬 (<CJK Ideograph>) 14463 0x5D5E 嵞 (<CJK Ideograph>) 14464 0x5D68 嵨 (<CJK Ideograph>) 14465 0x5D67 嵧 (<CJK Ideograph>) 14466 0x5D62 嵢 (<CJK Ideograph>) 14467 0x5DF0 巰 (<CJK Ideograph>) 14468 0x5E4F 幏 (<CJK Ideograph>) 14469 0x5E4E 幎 (<CJK Ideograph>) 14470 0x5E4A 幊 (<CJK Ideograph>) 14471 0x5E4D 幍 (<CJK Ideograph>) 14472 0x5E4B 幋 (<CJK Ideograph>) 14473 0x5EC5 廅 (<CJK Ideograph>) 14474 0x5ECC 廌 (<CJK Ideograph>) 14475 0x5EC6 廆 (<CJK Ideograph>) 14476 0x5ECB 廋 (<CJK Ideograph>) 14477 0x5EC7 廇 (<CJK Ideograph>) 14478 0x5F40 彀 (<CJK Ideograph>) 14479 0x5FAF 徯 (<CJK Ideograph>) 14480 0x5FAD 徭 (<CJK Ideograph>) 14481 0x60F7 惷 (<CJK Ideograph>) 14482 0x6149 慉 (<CJK Ideograph>) 14483 0x614A 慊 (<CJK Ideograph>) 14484 0x612B 愫 (<CJK Ideograph>) 14485 0x6145 慅 (<CJK Ideograph>) 14486 0x6136 愶 (<CJK Ideograph>) 14487 0x6132 愲 (<CJK Ideograph>) 14488 0x612E 愮 (<CJK Ideograph>) 14489 0x6146 慆 (<CJK Ideograph>) 14490 0x612F 愯 (<CJK Ideograph>) 14491 0x614F 慏 (<CJK Ideograph>) 14492 0x6129 愩 (<CJK Ideograph>) 14493 0x6140 慀 (<CJK Ideograph>) 14494 0x6220 戠 (<CJK Ideograph>) 14495 0x9168 酨 (<CJK Ideograph>) 14496 0x6223 戣 (<CJK Ideograph>) 14497 0x6225 戥 (<CJK Ideograph>) 14498 0x6224 戤 (<CJK Ideograph>) 14499 0x63C5 揅 (<CJK Ideograph>) 14500 0x63F1 揱 (<CJK Ideograph>) 14501 0x63EB 揫 (<CJK Ideograph>) 14502 0x6410 搐 (<CJK Ideograph>) 14503 0x6412 搒 (<CJK Ideograph>) 14504 0x6409 搉 (<CJK Ideograph>) 14505 0x6420 搠 (<CJK Ideograph>) 14506 0x6424 搤 (<CJK Ideograph>) 14507 0x6433 搳 (<CJK Ideograph>) 14508 0x6443 摃 (<CJK Ideograph>) 14509 0x641F 搟 (<CJK Ideograph>) 14510 0x6415 搕 (<CJK Ideograph>) 14511 0x6418 搘 (<CJK Ideograph>) 14512 0x6439 搹 (<CJK Ideograph>) 14513 0x6437 搷 (<CJK Ideograph>) 14514 0x6422 搢 (<CJK Ideograph>) 14515 0x6423 搣 (<CJK Ideograph>) 14516 0x640C 搌 (<CJK Ideograph>) 14517 0x6426 搦 (<CJK Ideograph>) 14518 0x6430 搰 (<CJK Ideograph>) 14519 0x6428 搨 (<CJK Ideograph>) 14520 0x6441 摁 (<CJK Ideograph>) 14521 0x6435 搵 (<CJK Ideograph>) 14522 0x642F 搯 (<CJK Ideograph>) 14523 0x640A 搊 (<CJK Ideograph>) 14524 0x641A 搚 (<CJK Ideograph>) 14525 0x6440 摀 (<CJK Ideograph>) 14526 0x6425 搥 (<CJK Ideograph>) 14527 0x6427 搧 (<CJK Ideograph>) 14528 0x640B 搋 (<CJK Ideograph>) 14529 0x63E7 揧 (<CJK Ideograph>) 14530 0x641B 搛 (<CJK Ideograph>) 14531 0x642E 搮 (<CJK Ideograph>) 14532 0x6421 搡 (<CJK Ideograph>) 14533 0x640E 搎 (<CJK Ideograph>) 14534 0x656F 敯 (<CJK Ideograph>) 14535 0x6592 斒 (<CJK Ideograph>) 14536 0x65D3 旓 (<CJK Ideograph>) 14537 0x6686 暆 (<CJK Ideograph>) 14538 0x668C 暌 (<CJK Ideograph>) 14539 0x6695 暕 (<CJK Ideograph>) 14540 0x6690 暐 (<CJK Ideograph>) 14541 0x668B 暋 (<CJK Ideograph>) 14542 0x668A 暊 (<CJK Ideograph>) 14543 0x6699 暙 (<CJK Ideograph>) 14544 0x6694 暔 (<CJK Ideograph>) 14545 0x6678 晸 (<CJK Ideograph>) 14546 0x6720 朠 (<CJK Ideograph>) 14547 0x6966 楦 (<CJK Ideograph>) 14548 0x695F 楟 (<CJK Ideograph>) 14549 0x6938 椸 (<CJK Ideograph>) 14550 0x694E 楎 (<CJK Ideograph>) 14551 0x6962 楢 (<CJK Ideograph>) 14552 0x6971 楱 (<CJK Ideograph>) 14553 0x693F 椿 (<CJK Ideograph>) 14554 0x6945 楅 (<CJK Ideograph>) 14555 0x696A 楪 (<CJK Ideograph>) 14556 0x6939 椹 (<CJK Ideograph>) 14557 0x6942 楂 (<CJK Ideograph>) 14558 0x6957 楗 (<CJK Ideograph>) 14559 0x6959 楙 (<CJK Ideograph>) 14560 0x697A 楺 (<CJK Ideograph>) 14561 0x6948 楈 (<CJK Ideograph>) 14562 0x6949 楉 (<CJK Ideograph>) 14563 0x6935 椵 (<CJK Ideograph>) 14564 0x696C 楬 (<CJK Ideograph>) 14565 0x6933 椳 (<CJK Ideograph>) 14566 0x693D 椽 (<CJK Ideograph>) 14567 0x6965 楥 (<CJK Ideograph>) 14568 0x68F0 棰 (<CJK Ideograph>) 14569 0x6978 楸 (<CJK Ideograph>) 14570 0x6934 椴 (<CJK Ideograph>) 14571 0x6969 楩 (<CJK Ideograph>) 14572 0x6940 楀 (<CJK Ideograph>) 14573 0x696F 楯 (<CJK Ideograph>) 14574 0x6944 楄 (<CJK Ideograph>) 14575 0x6976 楶 (<CJK Ideograph>) 14576 0x6958 楘 (<CJK Ideograph>) 14577 0x6941 楁 (<CJK Ideograph>) 14578 0x6974 楴 (<CJK Ideograph>) 14579 0x694C 楌 (<CJK Ideograph>) 14580 0x693B 椻 (<CJK Ideograph>) 14581 0x694B 楋 (<CJK Ideograph>) 14582 0x6937 椷 (<CJK Ideograph>) 14583 0x695C 楜 (<CJK Ideograph>) 14584 0x694F 楏 (<CJK Ideograph>) 14585 0x6951 楑 (<CJK Ideograph>) 14586 0x6932 椲 (<CJK Ideograph>) 14587 0x6952 楒 (<CJK Ideograph>) 14588 0x692F 椯 (<CJK Ideograph>) 14589 0x697B 楻 (<CJK Ideograph>) 14590 0x693C 椼 (<CJK Ideograph>) 14591 0x6B46 歆 (<CJK Ideograph>) 14592 0x6B45 歅 (<CJK Ideograph>) 14593 0x6B43 歃 (<CJK Ideograph>) 14594 0x6B42 歂 (<CJK Ideograph>) 14595 0x6B48 歈 (<CJK Ideograph>) 14596 0x6B41 歁 (<CJK Ideograph>) 14597 0x6B9B 殛 (<CJK Ideograph>) 14598 0xFA0D 嗀 (CJK COMPATIBILITY IDEOGRAPH-FA0D) 14599 0x6BFB 毻 (<CJK Ideograph>) 14600 0x6BFC 毼 (<CJK Ideograph>) 14601 0x6BF9 毹 (<CJK Ideograph>) 14602 0x6BF7 毷 (<CJK Ideograph>) 14603 0x6BF8 毸 (<CJK Ideograph>) 14604 0x6E9B 溛 (<CJK Ideograph>) 14605 0x6ED6 滖 (<CJK Ideograph>) 14606 0x6EC8 滈 (<CJK Ideograph>) 14607 0x6E8F 溏 (<CJK Ideograph>) 14608 0x6EC0 滀 (<CJK Ideograph>) 14609 0x6E9F 溟 (<CJK Ideograph>) 14610 0x6E93 溓 (<CJK Ideograph>) 14611 0x6E94 溔 (<CJK Ideograph>) 14612 0x6EA0 溠 (<CJK Ideograph>) 14613 0x6EB1 溱 (<CJK Ideograph>) 14614 0x6EB9 溹 (<CJK Ideograph>) 14615 0x6EC6 滆 (<CJK Ideograph>) 14616 0x6ED2 滒 (<CJK Ideograph>) 14617 0x6EBD 溽 (<CJK Ideograph>) 14618 0x6EC1 滁 (<CJK Ideograph>) 14619 0x6E9E 溞 (<CJK Ideograph>) 14620 0x6EC9 滉 (<CJK Ideograph>) 14621 0x6EB7 溷 (<CJK Ideograph>) 14622 0x6EB0 溰 (<CJK Ideograph>) 14623 0x6ECD 滍 (<CJK Ideograph>) 14624 0x6EA6 溦 (<CJK Ideograph>) 14625 0x6ECF 滏 (<CJK Ideograph>) 14626 0x6EB2 溲 (<CJK Ideograph>) 14627 0x6EBE 溾 (<CJK Ideograph>) 14628 0x6EC3 滃 (<CJK Ideograph>) 14629 0x6EDC 滜 (<CJK Ideograph>) 14630 0x6ED8 滘 (<CJK Ideograph>) 14631 0x6E99 溙 (<CJK Ideograph>) 14632 0x6E92 溒 (<CJK Ideograph>) 14633 0x6E8E 溎 (<CJK Ideograph>) 14634 0x6E8D 溍 (<CJK Ideograph>) 14635 0x6EA4 溤 (<CJK Ideograph>) 14636 0x6EA1 溡 (<CJK Ideograph>) 14637 0x6EBF 溿 (<CJK Ideograph>) 14638 0x6EB3 溳 (<CJK Ideograph>) 14639 0x6ED0 滐 (<CJK Ideograph>) 14640 0x6ECA 滊 (<CJK Ideograph>) 14641 0x6E97 溗 (<CJK Ideograph>) 14642 0x6EAE 溮 (<CJK Ideograph>) 14643 0x6EA3 溣 (<CJK Ideograph>) 14644 0x7147 煇 (<CJK Ideograph>) 14645 0x7154 煔 (<CJK Ideograph>) 14646 0x7152 煒 (<CJK Ideograph>) 14647 0x7163 煣 (<CJK Ideograph>) 14648 0x7160 煠 (<CJK Ideograph>) 14649 0x7141 煁 (<CJK Ideograph>) 14650 0x715D 煝 (<CJK Ideograph>) 14651 0x7162 煢 (<CJK Ideograph>) 14652 0x7172 煲 (<CJK Ideograph>) 14653 0x7178 煸 (<CJK Ideograph>) 14654 0x716A 煪 (<CJK Ideograph>) 14655 0x7161 煡 (<CJK Ideograph>) 14656 0x7142 煂 (<CJK Ideograph>) 14657 0x7158 煘 (<CJK Ideograph>) 14658 0x7143 煃 (<CJK Ideograph>) 14659 0x714B 煋 (<CJK Ideograph>) 14660 0x7170 煰 (<CJK Ideograph>) 14661 0x715F 煟 (<CJK Ideograph>) 14662 0x7150 煐 (<CJK Ideograph>) 14663 0x7153 煓 (<CJK Ideograph>) 14664 0x7144 煄 (<CJK Ideograph>) 14665 0x714D 煍 (<CJK Ideograph>) 14666 0x715A 煚 (<CJK Ideograph>) 14667 0x724F 牏 (<CJK Ideograph>) 14668 0x728D 犍 (<CJK Ideograph>) 14669 0x728C 犌 (<CJK Ideograph>) 14670 0x7291 犑 (<CJK Ideograph>) 14671 0x7290 犐 (<CJK Ideograph>) 14672 0x728E 犎 (<CJK Ideograph>) 14673 0x733C 猼 (<CJK Ideograph>) 14674 0x7342 獂 (<CJK Ideograph>) 14675 0x733B 猻 (<CJK Ideograph>) 14676 0x733A 猺 (<CJK Ideograph>) 14677 0x7340 獀 (<CJK Ideograph>) 14678 0x734A 獊 (<CJK Ideograph>) 14679 0x7349 獉 (<CJK Ideograph>) 14680 0x7444 瑄 (<CJK Ideograph>) 14681 0x744A 瑊 (<CJK Ideograph>) 14682 0x744B 瑋 (<CJK Ideograph>) 14683 0x7452 瑒 (<CJK Ideograph>) 14684 0x7451 瑑 (<CJK Ideograph>) 14685 0x7457 瑗 (<CJK Ideograph>) 14686 0x7440 瑀 (<CJK Ideograph>) 14687 0x744F 瑏 (<CJK Ideograph>) 14688 0x7450 瑐 (<CJK Ideograph>) 14689 0x744E 瑎 (<CJK Ideograph>) 14690 0x7442 瑂 (<CJK Ideograph>) 14691 0x7446 瑆 (<CJK Ideograph>) 14692 0x744D 瑍 (<CJK Ideograph>) 14693 0x7454 瑔 (<CJK Ideograph>) 14694 0x74E1 瓡 (<CJK Ideograph>) 14695 0x74FF 瓿 (<CJK Ideograph>) 14696 0x74FE 瓾 (<CJK Ideograph>) 14697 0x74FD 瓽 (<CJK Ideograph>) 14698 0x751D 甝 (<CJK Ideograph>) 14699 0x7579 畹 (<CJK Ideograph>) 14700 0x7577 畷 (<CJK Ideograph>) 14701 0x6983 榃 (<CJK Ideograph>) 14702 0x75EF 痯 (<CJK Ideograph>) 14703 0x760F 瘏 (<CJK Ideograph>) 14704 0x7603 瘃 (<CJK Ideograph>) 14705 0x75F7 痷 (<CJK Ideograph>) 14706 0x75FE 痾 (<CJK Ideograph>) 14707 0x75FC 痼 (<CJK Ideograph>) 14708 0x75F9 痹 (<CJK Ideograph>) 14709 0x75F8 痸 (<CJK Ideograph>) 14710 0x7610 瘐 (<CJK Ideograph>) 14711 0x75FB 痻 (<CJK Ideograph>) 14712 0x75F6 痶 (<CJK Ideograph>) 14713 0x75ED 痭 (<CJK Ideograph>) 14714 0x75F5 痵 (<CJK Ideograph>) 14715 0x75FD 痽 (<CJK Ideograph>) 14716 0x7699 皙 (<CJK Ideograph>) 14717 0x76B5 皵 (<CJK Ideograph>) 14718 0x76DD 盝 (<CJK Ideograph>) 14719 0x7755 睕 (<CJK Ideograph>) 14720 0x775F 睟 (<CJK Ideograph>) 14721 0x7760 睠 (<CJK Ideograph>) 14722 0x7752 睒 (<CJK Ideograph>) 14723 0x7756 睖 (<CJK Ideograph>) 14724 0x775A 睚 (<CJK Ideograph>) 14725 0x7769 睩 (<CJK Ideograph>) 14726 0x7767 睧 (<CJK Ideograph>) 14727 0x7754 睔 (<CJK Ideograph>) 14728 0x7759 睙 (<CJK Ideograph>) 14729 0x776D 睭 (<CJK Ideograph>) 14730 0x77E0 矠 (<CJK Ideograph>) 14731 0x7887 碇 (<CJK Ideograph>) 14732 0x789A 碚 (<CJK Ideograph>) 14733 0x7894 碔 (<CJK Ideograph>) 14734 0x788F 碏 (<CJK Ideograph>) 14735 0x7884 碄 (<CJK Ideograph>) 14736 0x7895 碕 (<CJK Ideograph>) 14737 0x7885 碅 (<CJK Ideograph>) 14738 0x7886 碆 (<CJK Ideograph>) 14739 0x78A1 碡 (<CJK Ideograph>) 14740 0x7883 碃 (<CJK Ideograph>) 14741 0x7879 硹 (<CJK Ideograph>) 14742 0x7899 碙 (<CJK Ideograph>) 14743 0x7880 碀 (<CJK Ideograph>) 14744 0x7896 碖 (<CJK Ideograph>) 14745 0x787B 硻 (<CJK Ideograph>) 14746 0x797C 祼 (<CJK Ideograph>) 14747 0x7982 禂 (<CJK Ideograph>) 14748 0x797D 祽 (<CJK Ideograph>) 14749 0x7979 祹 (<CJK Ideograph>) 14750 0x7A11 稑 (<CJK Ideograph>) 14751 0x7A18 稘 (<CJK Ideograph>) 14752 0x7A19 稙 (<CJK Ideograph>) 14753 0x7A12 稒 (<CJK Ideograph>) 14754 0x7A17 稗 (<CJK Ideograph>) 14755 0x7A15 稕 (<CJK Ideograph>) 14756 0x7A22 稢 (<CJK Ideograph>) 14757 0x7A13 稓 (<CJK Ideograph>) 14758 0x7A1B 稛 (<CJK Ideograph>) 14759 0x7A10 稐 (<CJK Ideograph>) 14760 0x7AA3 窣 (<CJK Ideograph>) 14761 0x7AA2 窢 (<CJK Ideograph>) 14762 0x7A9E 窞 (<CJK Ideograph>) 14763 0x7AEB 竫 (<CJK Ideograph>) 14764 0x7B66 筦 (<CJK Ideograph>) 14765 0x7B64 筤 (<CJK Ideograph>) 14766 0x7B6D 筭 (<CJK Ideograph>) 14767 0x7B74 筴 (<CJK Ideograph>) 14768 0x7B69 筩 (<CJK Ideograph>) 14769 0x7B72 筲 (<CJK Ideograph>) 14770 0x7B65 筥 (<CJK Ideograph>) 14771 0x7B73 筳 (<CJK Ideograph>) 14772 0x7B71 筱 (<CJK Ideograph>) 14773 0x7B70 筰 (<CJK Ideograph>) 14774 0x7B61 筡 (<CJK Ideograph>) 14775 0x7B78 筸 (<CJK Ideograph>) 14776 0x7B76 筶 (<CJK Ideograph>) 14777 0x7B63 筣 (<CJK Ideograph>) 14778 0x7CB2 粲 (<CJK Ideograph>) 14779 0x7CB4 粴 (<CJK Ideograph>) 14780 0x7CAF 粯 (<CJK Ideograph>) 14781 0x7D88 綈 (<CJK Ideograph>) 14782 0x7D86 綆 (<CJK Ideograph>) 14783 0x7D80 綀 (<CJK Ideograph>) 14784 0x7D8D 綍 (<CJK Ideograph>) 14785 0x7D7F 絿 (<CJK Ideograph>) 14786 0x7D85 綅 (<CJK Ideograph>) 14787 0x7D7A 絺 (<CJK Ideograph>) 14788 0x7D8E 綎 (<CJK Ideograph>) 14789 0x7D7B 絻 (<CJK Ideograph>) 14790 0x7D83 綃 (<CJK Ideograph>) 14791 0x7D7C 絼 (<CJK Ideograph>) 14792 0x7D8C 綌 (<CJK Ideograph>) 14793 0x7D94 綔 (<CJK Ideograph>) 14794 0x7D84 綄 (<CJK Ideograph>) 14795 0x7D7D 絽 (<CJK Ideograph>) 14796 0x7D92 綒 (<CJK Ideograph>) 14797 0x7F6D 罭 (<CJK Ideograph>) 14798 0x7F6B 罫 (<CJK Ideograph>) 14799 0x7F67 罧 (<CJK Ideograph>) 14800 0x7F68 罨 (<CJK Ideograph>) 14801 0x7F6C 罬 (<CJK Ideograph>) 14802 0x7FA6 羦 (<CJK Ideograph>) 14803 0x7FA5 羥 (<CJK Ideograph>) 14804 0x7FA7 羧 (<CJK Ideograph>) 14805 0x7FDB 翛 (<CJK Ideograph>) 14806 0x7FDC 翜 (<CJK Ideograph>) 14807 0x8021 耡 (<CJK Ideograph>) 14808 0x8164 腤 (<CJK Ideograph>) 14809 0x8160 腠 (<CJK Ideograph>) 14810 0x8177 腷 (<CJK Ideograph>) 14811 0x815C 腜 (<CJK Ideograph>) 14812 0x8169 腩 (<CJK Ideograph>) 14813 0x815B 腛 (<CJK Ideograph>) 14814 0x8162 腢 (<CJK Ideograph>) 14815 0x8172 腲 (<CJK Ideograph>) 14816 0x6721 朡 (<CJK Ideograph>) 14817 0x815E 腞 (<CJK Ideograph>) 14818 0x8176 腶 (<CJK Ideograph>) 14819 0x8167 腧 (<CJK Ideograph>) 14820 0x816F 腯 (<CJK Ideograph>) 14821 0x8144 腄 (<CJK Ideograph>) 14822 0x8161 腡 (<CJK Ideograph>) 14823 0x821D 舝 (<CJK Ideograph>) 14824 0x8249 艉 (<CJK Ideograph>) 14825 0x8244 艄 (<CJK Ideograph>) 14826 0x8240 艀 (<CJK Ideograph>) 14827 0x8242 艂 (<CJK Ideograph>) 14828 0x8245 艅 (<CJK Ideograph>) 14829 0x84F1 蓱 (<CJK Ideograph>) 14830 0x843F 萿 (<CJK Ideograph>) 14831 0x8456 葖 (<CJK Ideograph>) 14832 0x8476 葶 (<CJK Ideograph>) 14833 0x8479 葹 (<CJK Ideograph>) 14834 0x848F 蒏 (<CJK Ideograph>) 14835 0x848D 蒍 (<CJK Ideograph>) 14836 0x8465 葥 (<CJK Ideograph>) 14837 0x8451 葑 (<CJK Ideograph>) 14838 0x8440 葀 (<CJK Ideograph>) 14839 0x8486 蒆 (<CJK Ideograph>) 14840 0x8467 葧 (<CJK Ideograph>) 14841 0x8430 萰 (<CJK Ideograph>) 14842 0x844D 葍 (<CJK Ideograph>) 14843 0x847D 葽 (<CJK Ideograph>) 14844 0x845A 葚 (<CJK Ideograph>) 14845 0x8459 葙 (<CJK Ideograph>) 14846 0x8474 葴 (<CJK Ideograph>) 14847 0x8473 葳 (<CJK Ideograph>) 14848 0x845D 葝 (<CJK Ideograph>) 14849 0x8507 蔇 (<CJK Ideograph>) 14850 0x845E 葞 (<CJK Ideograph>) 14851 0x8437 萷 (<CJK Ideograph>) 14852 0x843A 萺 (<CJK Ideograph>) 14853 0x8434 萴 (<CJK Ideograph>) 14854 0x847A 葺 (<CJK Ideograph>) 14855 0x8443 葃 (<CJK Ideograph>) 14856 0x8478 葸 (<CJK Ideograph>) 14857 0x8432 萲 (<CJK Ideograph>) 14858 0x8445 葅 (<CJK Ideograph>) 14859 0x8429 萩 (<CJK Ideograph>) 14860 0x83D9 菙 (<CJK Ideograph>) 14861 0x844B 葋 (<CJK Ideograph>) 14862 0x842F 萯 (<CJK Ideograph>) 14863 0x8442 葂 (<CJK Ideograph>) 14864 0x842D 萭 (<CJK Ideograph>) 14865 0x845F 葟 (<CJK Ideograph>) 14866 0x8470 葰 (<CJK Ideograph>) 14867 0x8439 萹 (<CJK Ideograph>) 14868 0x844E 葎 (<CJK Ideograph>) 14869 0x844C 葌 (<CJK Ideograph>) 14870 0x8452 葒 (<CJK Ideograph>) 14871 0x846F 葯 (<CJK Ideograph>) 14872 0x84C5 蓅 (<CJK Ideograph>) 14873 0x848E 蒎 (<CJK Ideograph>) 14874 0x843B 萻 (<CJK Ideograph>) 14875 0x8447 葇 (<CJK Ideograph>) 14876 0x8436 萶 (<CJK Ideograph>) 14877 0x8433 萳 (<CJK Ideograph>) 14878 0x8468 葨 (<CJK Ideograph>) 14879 0x847E 葾 (<CJK Ideograph>) 14880 0x8444 葄 (<CJK Ideograph>) 14881 0x842B 萫 (<CJK Ideograph>) 14882 0x8460 葠 (<CJK Ideograph>) 14883 0x8454 葔 (<CJK Ideograph>) 14884 0x846E 葮 (<CJK Ideograph>) 14885 0x8450 葐 (<CJK Ideograph>) 14886 0x870B 蜋 (<CJK Ideograph>) 14887 0x8704 蜄 (<CJK Ideograph>) 14888 0x86F7 蛷 (<CJK Ideograph>) 14889 0x870C 蜌 (<CJK Ideograph>) 14890 0x86FA 蛺 (<CJK Ideograph>) 14891 0x86D6 蛖 (<CJK Ideograph>) 14892 0x86F5 蛵 (<CJK Ideograph>) 14893 0x874D 蝍 (<CJK Ideograph>) 14894 0x86F8 蛸 (<CJK Ideograph>) 14895 0x870E 蜎 (<CJK Ideograph>) 14896 0x8709 蜉 (<CJK Ideograph>) 14897 0x8701 蜁 (<CJK Ideograph>) 14898 0x86F6 蛶 (<CJK Ideograph>) 14899 0x870D 蜍 (<CJK Ideograph>) 14900 0x8705 蜅 (<CJK Ideograph>) 14901 0x88D6 裖 (<CJK Ideograph>) 14902 0x88CB 裋 (<CJK Ideograph>) 14903 0x88CD 裍 (<CJK Ideograph>) 14904 0x88CE 裎 (<CJK Ideograph>) 14905 0x88DE 裞 (<CJK Ideograph>) 14906 0x88DB 裛 (<CJK Ideograph>) 14907 0x88DA 裚 (<CJK Ideograph>) 14908 0x88CC 裌 (<CJK Ideograph>) 14909 0x88D0 裐 (<CJK Ideograph>) 14910 0x8985 覅 (<CJK Ideograph>) 14911 0x899B 覛 (<CJK Ideograph>) 14912 0x89DF 觟 (<CJK Ideograph>) 14913 0x89E5 觥 (<CJK Ideograph>) 14914 0x89E4 觤 (<CJK Ideograph>) 14915 0x89E1 觡 (<CJK Ideograph>) 14916 0x89E0 觠 (<CJK Ideograph>) 14917 0x89E2 觢 (<CJK Ideograph>) 14918 0x89DC 觜 (<CJK Ideograph>) 14919 0x89E6 触 (<CJK Ideograph>) 14920 0x8A76 詶 (<CJK Ideograph>) 14921 0x8A86 誆 (<CJK Ideograph>) 14922 0x8A7F 詿 (<CJK Ideograph>) 14923 0x8A61 詡 (<CJK Ideograph>) 14924 0x8A3F 訿 (<CJK Ideograph>) 14925 0x8A77 詷 (<CJK Ideograph>) 14926 0x8A82 誂 (<CJK Ideograph>) 14927 0x8A84 誄 (<CJK Ideograph>) 14928 0x8A75 詵 (<CJK Ideograph>) 14929 0x8A83 誃 (<CJK Ideograph>) 14930 0x8A81 誁 (<CJK Ideograph>) 14931 0x8A74 詴 (<CJK Ideograph>) 14932 0x8A7A 詺 (<CJK Ideograph>) 14933 0x8C3C 谼 (<CJK Ideograph>) 14934 0x8C4B 豋 (<CJK Ideograph>) 14935 0x8C4A 豊 (<CJK Ideograph>) 14936 0x8C65 豥 (<CJK Ideograph>) 14937 0x8C64 豤 (<CJK Ideograph>) 14938 0x8C66 豦 (<CJK Ideograph>) 14939 0x8C86 貆 (<CJK Ideograph>) 14940 0x8C84 貄 (<CJK Ideograph>) 14941 0x8C85 貅 (<CJK Ideograph>) 14942 0x8CCC 賌 (<CJK Ideograph>) 14943 0x8D68 赨 (<CJK Ideograph>) 14944 0x8D69 赩 (<CJK Ideograph>) 14945 0x8D91 趑 (<CJK Ideograph>) 14946 0x8D8C 趌 (<CJK Ideograph>) 14947 0x8D8E 趎 (<CJK Ideograph>) 14948 0x8D8F 趏 (<CJK Ideograph>) 14949 0x8D8D 趍 (<CJK Ideograph>) 14950 0x8D93 趓 (<CJK Ideograph>) 14951 0x8D94 趔 (<CJK Ideograph>) 14952 0x8D90 趐 (<CJK Ideograph>) 14953 0x8D92 趒 (<CJK Ideograph>) 14954 0x8DF0 跰 (<CJK Ideograph>) 14955 0x8DE0 跠 (<CJK Ideograph>) 14956 0x8DEC 跬 (<CJK Ideograph>) 14957 0x8DF1 跱 (<CJK Ideograph>) 14958 0x8DEE 跮 (<CJK Ideograph>) 14959 0x8DD0 跐 (<CJK Ideograph>) 14960 0x8DE9 跩 (<CJK Ideograph>) 14961 0x8DE3 跣 (<CJK Ideograph>) 14962 0x8DE2 跢 (<CJK Ideograph>) 14963 0x8DE7 跧 (<CJK Ideograph>) 14964 0x8DF2 跲 (<CJK Ideograph>) 14965 0x8DEB 跫 (<CJK Ideograph>) 14966 0x8DF4 跴 (<CJK Ideograph>) 14967 0x8F06 輆 (<CJK Ideograph>) 14968 0x8EFF 軿 (<CJK Ideograph>) 14969 0x8F01 輁 (<CJK Ideograph>) 14970 0x8F00 輀 (<CJK Ideograph>) 14971 0x8F05 輅 (<CJK Ideograph>) 14972 0x8F07 輇 (<CJK Ideograph>) 14973 0x8F08 輈 (<CJK Ideograph>) 14974 0x8F02 輂 (<CJK Ideograph>) 14975 0x8F0B 輋 (<CJK Ideograph>) 14976 0x9052 遒 (<CJK Ideograph>) 14977 0x903F 逿 (<CJK Ideograph>) 14978 0x9044 遄 (<CJK Ideograph>) 14979 0x9049 遉 (<CJK Ideograph>) 14980 0x903D 逽 (<CJK Ideograph>) 14981 0x9110 鄐 (<CJK Ideograph>) 14982 0x910D 鄍 (<CJK Ideograph>) 14983 0x910F 鄏 (<CJK Ideograph>) 14984 0x9111 鄑 (<CJK Ideograph>) 14985 0x9116 鄖 (<CJK Ideograph>) 14986 0x9114 鄔 (<CJK Ideograph>) 14987 0x910B 鄋 (<CJK Ideograph>) 14988 0x910E 鄎 (<CJK Ideograph>) 14989 0x916E 酮 (<CJK Ideograph>) 14990 0x916F 酯 (<CJK Ideograph>) 14991 0x9248 鉈 (<CJK Ideograph>) 14992 0x9252 鉒 (<CJK Ideograph>) 14993 0x9230 鈰 (<CJK Ideograph>) 14994 0x923A 鈺 (<CJK Ideograph>) 14995 0x9266 鉦 (<CJK Ideograph>) 14996 0x9233 鈳 (<CJK Ideograph>) 14997 0x9265 鉥 (<CJK Ideograph>) 14998 0x925E 鉞 (<CJK Ideograph>) 14999 0x9283 銃 (<CJK Ideograph>) 15000 0x922E 鈮 (<CJK Ideograph>) 15001 0x924A 鉊 (<CJK Ideograph>) 15002 0x9246 鉆 (<CJK Ideograph>) 15003 0x926D 鉭 (<CJK Ideograph>) 15004 0x926C 鉬 (<CJK Ideograph>) 15005 0x924F 鉏 (<CJK Ideograph>) 15006 0x9260 鉠 (<CJK Ideograph>) 15007 0x9267 鉧 (<CJK Ideograph>) 15008 0x926F 鉯 (<CJK Ideograph>) 15009 0x9236 鈶 (<CJK Ideograph>) 15010 0x9261 鉡 (<CJK Ideograph>) 15011 0x9270 鉰 (<CJK Ideograph>) 15012 0x9231 鈱 (<CJK Ideograph>) 15013 0x9254 鉔 (<CJK Ideograph>) 15014 0x9263 鉣 (<CJK Ideograph>) 15015 0x9250 鉐 (<CJK Ideograph>) 15016 0x9272 鉲 (<CJK Ideograph>) 15017 0x924E 鉎 (<CJK Ideograph>) 15018 0x9253 鉓 (<CJK Ideograph>) 15019 0x924C 鉌 (<CJK Ideograph>) 15020 0x9256 鉖 (<CJK Ideograph>) 15021 0x9232 鈲 (<CJK Ideograph>) 15022 0x959F 閟 (<CJK Ideograph>) 15023 0x959C 閜 (<CJK Ideograph>) 15024 0x959E 閞 (<CJK Ideograph>) 15025 0x959B 閛 (<CJK Ideograph>) 15026 0x9692 隒 (<CJK Ideograph>) 15027 0x9693 隓 (<CJK Ideograph>) 15028 0x9691 隑 (<CJK Ideograph>) 15029 0x9697 隗 (<CJK Ideograph>) 15030 0x96CE 雎 (<CJK Ideograph>) 15031 0x96FA 雺 (<CJK Ideograph>) 15032 0x96FD 雽 (<CJK Ideograph>) 15033 0x96F8 雸 (<CJK Ideograph>) 15034 0x96F5 雵 (<CJK Ideograph>) 15035 0x9773 靳 (<CJK Ideograph>) 15036 0x9777 靷 (<CJK Ideograph>) 15037 0x9778 靸 (<CJK Ideograph>) 15038 0x9772 靲 (<CJK Ideograph>) 15039 0x980F 頏 (<CJK Ideograph>) 15040 0x980D 頍 (<CJK Ideograph>) 15041 0x980E 頎 (<CJK Ideograph>) 15042 0x98AC 颬 (<CJK Ideograph>) 15043 0x98F6 飶 (<CJK Ideograph>) 15044 0x98F9 飹 (<CJK Ideograph>) 15045 0x99AF 馯 (<CJK Ideograph>) 15046 0x99B2 馲 (<CJK Ideograph>) 15047 0x99B0 馰 (<CJK Ideograph>) 15048 0x99B5 馵 (<CJK Ideograph>) 15049 0x9AAD 骭 (<CJK Ideograph>) 15050 0x9AAB 骫 (<CJK Ideograph>) 15051 0x9B5B 魛 (<CJK Ideograph>) 15052 0x9CEA 鳪 (<CJK Ideograph>) 15053 0x9CED 鳭 (<CJK Ideograph>) 15054 0x9CE7 鳧 (<CJK Ideograph>) 15055 0x9E80 麀 (<CJK Ideograph>) 15056 0x9EFD 黽 (<CJK Ideograph>) 15057 0x50E6 僦 (<CJK Ideograph>) 15058 0x50D4 僔 (<CJK Ideograph>) 15059 0x50D7 僗 (<CJK Ideograph>) 15060 0x50E8 僨 (<CJK Ideograph>) 15061 0x50F3 僳 (<CJK Ideograph>) 15062 0x50DB 僛 (<CJK Ideograph>) 15063 0x50EA 僪 (<CJK Ideograph>) 15064 0x50DD 僝 (<CJK Ideograph>) 15065 0x50E4 僤 (<CJK Ideograph>) 15066 0x50D3 僓 (<CJK Ideograph>) 15067 0x50EC 僬 (<CJK Ideograph>) 15068 0x50F0 僰 (<CJK Ideograph>) 15069 0x50EF 僯 (<CJK Ideograph>) 15070 0x50E3 僣 (<CJK Ideograph>) 15071 0x50E0 僠 (<CJK Ideograph>) 15072 0x51D8 凘 (<CJK Ideograph>) 15073 0x5280 劀 (<CJK Ideograph>) 15074 0x5281 劁 (<CJK Ideograph>) 15075 0x52E9 勩 (<CJK Ideograph>) 15076 0x52EB 勫 (<CJK Ideograph>) 15077 0x5330 匰 (<CJK Ideograph>) 15078 0x53AC 厬 (<CJK Ideograph>) 15079 0x5627 嘧 (<CJK Ideograph>) 15080 0x5615 嘕 (<CJK Ideograph>) 15081 0x560C 嘌 (<CJK Ideograph>) 15082 0x5612 嘒 (<CJK Ideograph>) 15083 0x55FC 嗼 (<CJK Ideograph>) 15084 0x560F 嘏 (<CJK Ideograph>) 15085 0x561C 嘜 (<CJK Ideograph>) 15086 0x5601 嘁 (<CJK Ideograph>) 15087 0x5613 嘓 (<CJK Ideograph>) 15088 0x5602 嘂 (<CJK Ideograph>) 15089 0x55FA 嗺 (<CJK Ideograph>) 15090 0x561D 嘝 (<CJK Ideograph>) 15091 0x5604 嘄 (<CJK Ideograph>) 15092 0x55FF 嗿 (<CJK Ideograph>) 15093 0x55F9 嗹 (<CJK Ideograph>) 15094 0x5889 墉 (<CJK Ideograph>) 15095 0x587C 塼 (<CJK Ideograph>) 15096 0x5890 墐 (<CJK Ideograph>) 15097 0x5898 墘 (<CJK Ideograph>) 15098 0x5886 墆 (<CJK Ideograph>) 15099 0x5881 墁 (<CJK Ideograph>) 15100 0x587F 塿 (<CJK Ideograph>) 15101 0x5874 塴 (<CJK Ideograph>) 15102 0x588B 墋 (<CJK Ideograph>) 15103 0x587A 塺 (<CJK Ideograph>) 15104 0x5887 墇 (<CJK Ideograph>) 15105 0x5891 墑 (<CJK Ideograph>) 15106 0x588E 墎 (<CJK Ideograph>) 15107 0x5876 塶 (<CJK Ideograph>) 15108 0x5882 墂 (<CJK Ideograph>) 15109 0x5888 墈 (<CJK Ideograph>) 15110 0x587B 塻 (<CJK Ideograph>) 15111 0x5894 墔 (<CJK Ideograph>) 15112 0x588F 墏 (<CJK Ideograph>) 15113 0x58FE 壾 (<CJK Ideograph>) 15114 0x596B 奫 (<CJK Ideograph>) 15115 0x5ADC 嫜 (<CJK Ideograph>) 15116 0x5AEE 嫮 (<CJK Ideograph>) 15117 0x5AE5 嫥 (<CJK Ideograph>) 15118 0x5AD5 嫕 (<CJK Ideograph>) 15119 0x5AEA 嫪 (<CJK Ideograph>) 15120 0x5ADA 嫚 (<CJK Ideograph>) 15121 0x5AED 嫭 (<CJK Ideograph>) 15122 0x5AEB 嫫 (<CJK Ideograph>) 15123 0x5AF3 嫳 (<CJK Ideograph>) 15124 0x5AE2 嫢 (<CJK Ideograph>) 15125 0x5AE0 嫠 (<CJK Ideograph>) 15126 0x5ADB 嫛 (<CJK Ideograph>) 15127 0x5AEC 嫬 (<CJK Ideograph>) 15128 0x5ADE 嫞 (<CJK Ideograph>) 15129 0x5ADD 嫝 (<CJK Ideograph>) 15130 0x5AD9 嫙 (<CJK Ideograph>) 15131 0x5AE8 嫨 (<CJK Ideograph>) 15132 0x5ADF 嫟 (<CJK Ideograph>) 15133 0x5B77 孷 (<CJK Ideograph>) 15134 0x5BE0 寠 (<CJK Ideograph>) 15135 0x5BE3 寣 (<CJK Ideograph>) 15136 0x5C63 屣 (<CJK Ideograph>) 15137 0x5D82 嶂 (<CJK Ideograph>) 15138 0x5D80 嶀 (<CJK Ideograph>) 15139 0x5D7D 嵽 (<CJK Ideograph>) 15140 0x5D86 嶆 (<CJK Ideograph>) 15141 0x5D7A 嵺 (<CJK Ideograph>) 15142 0x5D81 嶁 (<CJK Ideograph>) 15143 0x5D77 嵷 (<CJK Ideograph>) 15144 0x5D8A 嶊 (<CJK Ideograph>) 15145 0x5D89 嶉 (<CJK Ideograph>) 15146 0x5D88 嶈 (<CJK Ideograph>) 15147 0x5D7E 嵾 (<CJK Ideograph>) 15148 0x5D7C 嵼 (<CJK Ideograph>) 15149 0x5D8D 嶍 (<CJK Ideograph>) 15150 0x5D79 嵹 (<CJK Ideograph>) 15151 0x5D7F 嵿 (<CJK Ideograph>) 15152 0x5E58 幘 (<CJK Ideograph>) 15153 0x5E59 幙 (<CJK Ideograph>) 15154 0x5E53 幓 (<CJK Ideograph>) 15155 0x5ED8 廘 (<CJK Ideograph>) 15156 0x5ED1 廑 (<CJK Ideograph>) 15157 0x5ED7 廗 (<CJK Ideograph>) 15158 0x5ECE 廎 (<CJK Ideograph>) 15159 0x5EDC 廜 (<CJK Ideograph>) 15160 0x5ED5 廕 (<CJK Ideograph>) 15161 0x5ED9 廙 (<CJK Ideograph>) 15162 0x5ED2 廒 (<CJK Ideograph>) 15163 0x5ED4 廔 (<CJK Ideograph>) 15164 0x5F44 彄 (<CJK Ideograph>) 15165 0x5F43 彃 (<CJK Ideograph>) 15166 0x5F6F 彯 (<CJK Ideograph>) 15167 0x5FB6 徶 (<CJK Ideograph>) 15168 0x612C 愬 (<CJK Ideograph>) 15169 0x6128 愨 (<CJK Ideograph>) 15170 0x6141 慁 (<CJK Ideograph>) 15171 0x615E 慞 (<CJK Ideograph>) 15172 0x6171 慱 (<CJK Ideograph>) 15173 0x6173 慳 (<CJK Ideograph>) 15174 0x6152 慒 (<CJK Ideograph>) 15175 0x6153 慓 (<CJK Ideograph>) 15176 0x6172 慲 (<CJK Ideograph>) 15177 0x616C 慬 (<CJK Ideograph>) 15178 0x6180 憀 (<CJK Ideograph>) 15179 0x6174 慴 (<CJK Ideograph>) 15180 0x6154 慔 (<CJK Ideograph>) 15181 0x617A 慺 (<CJK Ideograph>) 15182 0x615B 慛 (<CJK Ideograph>) 15183 0x6165 慥 (<CJK Ideograph>) 15184 0x613B 愻 (<CJK Ideograph>) 15185 0x616A 慪 (<CJK Ideograph>) 15186 0x6161 慡 (<CJK Ideograph>) 15187 0x6156 慖 (<CJK Ideograph>) 15188 0x6229 戩 (<CJK Ideograph>) 15189 0x6227 戧 (<CJK Ideograph>) 15190 0x622B 戫 (<CJK Ideograph>) 15191 0x642B 搫 (<CJK Ideograph>) 15192 0x644D 摍 (<CJK Ideograph>) 15193 0x645B 摛 (<CJK Ideograph>) 15194 0x645D 摝 (<CJK Ideograph>) 15195 0x6474 摴 (<CJK Ideograph>) 15196 0x6476 摶 (<CJK Ideograph>) 15197 0x6472 摲 (<CJK Ideograph>) 15198 0x6473 摳 (<CJK Ideograph>) 15199 0x647D 摽 (<CJK Ideograph>) 15200 0x6475 摵 (<CJK Ideograph>) 15201 0x6466 摦 (<CJK Ideograph>) 15202 0x64A6 撦 (<CJK Ideograph>) 15203 0x644E 摎 (<CJK Ideograph>) 15204 0x6482 撂 (<CJK Ideograph>) 15205 0x645E 摞 (<CJK Ideograph>) 15206 0x645C 摜 (<CJK Ideograph>) 15207 0x644B 摋 (<CJK Ideograph>) 15208 0x6453 摓 (<CJK Ideograph>) 15209 0x6460 摠 (<CJK Ideograph>) 15210 0x6450 摐 (<CJK Ideograph>) 15211 0x647F 摿 (<CJK Ideograph>) 15212 0x643F 搿 (<CJK Ideograph>) 15213 0x646C 摬 (<CJK Ideograph>) 15214 0x646B 摫 (<CJK Ideograph>) 15215 0x6459 摙 (<CJK Ideograph>) 15216 0x6465 摥 (<CJK Ideograph>) 15217 0x6477 摷 (<CJK Ideograph>) 15218 0x6573 敳 (<CJK Ideograph>) 15219 0x65A0 斠 (<CJK Ideograph>) 15220 0x66A1 暡 (<CJK Ideograph>) 15221 0x66A0 暠 (<CJK Ideograph>) 15222 0x669F 暟 (<CJK Ideograph>) 15223 0x6705 朅 (<CJK Ideograph>) 15224 0x6704 朄 (<CJK Ideograph>) 15225 0x6722 朢 (<CJK Ideograph>) 15226 0x69B1 榱 (<CJK Ideograph>) 15227 0x69B6 榶 (<CJK Ideograph>) 15228 0x69C9 槉 (<CJK Ideograph>) 15229 0x69A0 榠 (<CJK Ideograph>) 15230 0x69CE 槎 (<CJK Ideograph>) 15231 0x6996 榖 (<CJK Ideograph>) 15232 0x69B0 榰 (<CJK Ideograph>) 15233 0x69AC 榬 (<CJK Ideograph>) 15234 0x69BC 榼 (<CJK Ideograph>) 15235 0x6991 榑 (<CJK Ideograph>) 15236 0x6999 榙 (<CJK Ideograph>) 15237 0x698E 榎 (<CJK Ideograph>) 15238 0x69A7 榧 (<CJK Ideograph>) 15239 0x698D 榍 (<CJK Ideograph>) 15240 0x69A9 榩 (<CJK Ideograph>) 15241 0x69BE 榾 (<CJK Ideograph>) 15242 0x69AF 榯 (<CJK Ideograph>) 15243 0x69BF 榿 (<CJK Ideograph>) 15244 0x69C4 槄 (<CJK Ideograph>) 15245 0x69BD 榽 (<CJK Ideograph>) 15246 0x69A4 榤 (<CJK Ideograph>) 15247 0x69D4 槔 (<CJK Ideograph>) 15248 0x69B9 榹 (<CJK Ideograph>) 15249 0x69CA 槊 (<CJK Ideograph>) 15250 0x699A 榚 (<CJK Ideograph>) 15251 0x69CF 槏 (<CJK Ideograph>) 15252 0x69B3 榳 (<CJK Ideograph>) 15253 0x6993 榓 (<CJK Ideograph>) 15254 0x69AA 榪 (<CJK Ideograph>) 15255 0x69A1 榡 (<CJK Ideograph>) 15256 0x699E 榞 (<CJK Ideograph>) 15257 0x69D9 槙 (<CJK Ideograph>) 15258 0x6997 榗 (<CJK Ideograph>) 15259 0x6990 榐 (<CJK Ideograph>) 15260 0x69C2 槂 (<CJK Ideograph>) 15261 0x69B5 榵 (<CJK Ideograph>) 15262 0x69A5 榥 (<CJK Ideograph>) 15263 0x69C6 槆 (<CJK Ideograph>) 15264 0x6B4A 歊 (<CJK Ideograph>) 15265 0x6B4D 歍 (<CJK Ideograph>) 15266 0x6B4B 歋 (<CJK Ideograph>) 15267 0x6B9E 殞 (<CJK Ideograph>) 15268 0x6B9F 殟 (<CJK Ideograph>) 15269 0x6BA0 殠 (<CJK Ideograph>) 15270 0x6BC3 毃 (<CJK Ideograph>) 15271 0x6BC4 毄 (<CJK Ideograph>) 15272 0x6BFE 毾 (<CJK Ideograph>) 15273 0x6ECE 滎 (<CJK Ideograph>) 15274 0x6EF5 滵 (<CJK Ideograph>) 15275 0x6EF1 滱 (<CJK Ideograph>) 15276 0x6F03 漃 (<CJK Ideograph>) 15277 0x6F25 漥 (<CJK Ideograph>) 15278 0x6EF8 滸 (<CJK Ideograph>) 15279 0x6F37 漷 (<CJK Ideograph>) 15280 0x6EFB 滻 (<CJK Ideograph>) 15281 0x6F2E 漮 (<CJK Ideograph>) 15282 0x6F09 漉 (<CJK Ideograph>) 15283 0x6F4E 潎 (<CJK Ideograph>) 15284 0x6F19 漙 (<CJK Ideograph>) 15285 0x6F1A 漚 (<CJK Ideograph>) 15286 0x6F27 漧 (<CJK Ideograph>) 15287 0x6F18 漘 (<CJK Ideograph>) 15288 0x6F3B 漻 (<CJK Ideograph>) 15289 0x6F12 漒 (<CJK Ideograph>) 15290 0x6EED 滭 (<CJK Ideograph>) 15291 0x6F0A 漊 (<CJK Ideograph>) 15292 0x6F36 漶 (<CJK Ideograph>) 15293 0x6F73 潳 (<CJK Ideograph>) 15294 0x6EF9 滹 (<CJK Ideograph>) 15295 0x6EEE 滮 (<CJK Ideograph>) 15296 0x6F2D 漭 (<CJK Ideograph>) 15297 0x6F40 潀 (<CJK Ideograph>) 15298 0x6F30 漰 (<CJK Ideograph>) 15299 0x6F3C 漼 (<CJK Ideograph>) 15300 0x6F35 漵 (<CJK Ideograph>) 15301 0x6EEB 滫 (<CJK Ideograph>) 15302 0x6F07 漇 (<CJK Ideograph>) 15303 0x6F0E 漎 (<CJK Ideograph>) 15304 0x6F43 潃 (<CJK Ideograph>) 15305 0x6F05 漅 (<CJK Ideograph>) 15306 0x6EFD 滽 (<CJK Ideograph>) 15307 0x6EF6 滶 (<CJK Ideograph>) 15308 0x6F39 漹 (<CJK Ideograph>) 15309 0x6F1C 漜 (<CJK Ideograph>) 15310 0x6EFC 滼 (<CJK Ideograph>) 15311 0x6F3A 漺 (<CJK Ideograph>) 15312 0x6F1F 漟 (<CJK Ideograph>) 15313 0x6F0D 漍 (<CJK Ideograph>) 15314 0x6F1E 漞 (<CJK Ideograph>) 15315 0x6F08 漈 (<CJK Ideograph>) 15316 0x6F21 漡 (<CJK Ideograph>) 15317 0x7187 熇 (<CJK Ideograph>) 15318 0x7190 熐 (<CJK Ideograph>) 15319 0x7189 熉 (<CJK Ideograph>) 15320 0x7180 熀 (<CJK Ideograph>) 15321 0x7185 熅 (<CJK Ideograph>) 15322 0x7182 熂 (<CJK Ideograph>) 15323 0x718F 熏 (<CJK Ideograph>) 15324 0x717B 煻 (<CJK Ideograph>) 15325 0x7186 熆 (<CJK Ideograph>) 15326 0x7181 熁 (<CJK Ideograph>) 15327 0x7197 熗 (<CJK Ideograph>) 15328 0x7244 牄 (<CJK Ideograph>) 15329 0x7253 牓 (<CJK Ideograph>) 15330 0x7297 犗 (<CJK Ideograph>) 15331 0x7295 犕 (<CJK Ideograph>) 15332 0x7293 犓 (<CJK Ideograph>) 15333 0x7343 獃 (<CJK Ideograph>) 15334 0x734D 獍 (<CJK Ideograph>) 15335 0x7351 獑 (<CJK Ideograph>) 15336 0x734C 獌 (<CJK Ideograph>) 15337 0x7462 瑢 (<CJK Ideograph>) 15338 0x7473 瑳 (<CJK Ideograph>) 15339 0x7471 瑱 (<CJK Ideograph>) 15340 0x7475 瑵 (<CJK Ideograph>) 15341 0x7472 瑲 (<CJK Ideograph>) 15342 0x7467 瑧 (<CJK Ideograph>) 15343 0x746E 瑮 (<CJK Ideograph>) 15344 0x7500 甀 (<CJK Ideograph>) 15345 0x7502 甂 (<CJK Ideograph>) 15346 0x7503 甃 (<CJK Ideograph>) 15347 0x757D 畽 (<CJK Ideograph>) 15348 0x7590 疐 (<CJK Ideograph>) 15349 0x7616 瘖 (<CJK Ideograph>) 15350 0x7608 瘈 (<CJK Ideograph>) 15351 0x760C 瘌 (<CJK Ideograph>) 15352 0x7615 瘕 (<CJK Ideograph>) 15353 0x7611 瘑 (<CJK Ideograph>) 15354 0x760A 瘊 (<CJK Ideograph>) 15355 0x7614 瘔 (<CJK Ideograph>) 15356 0x76B8 皸 (<CJK Ideograph>) 15357 0x7781 瞁 (<CJK Ideograph>) 15358 0x777C 睼 (<CJK Ideograph>) 15359 0x7785 瞅 (<CJK Ideograph>) 15360 0x7782 瞂 (<CJK Ideograph>) 15361 0x776E 睮 (<CJK Ideograph>) 15362 0x7780 瞀 (<CJK Ideograph>) 15363 0x776F 睯 (<CJK Ideograph>) 15364 0x777E 睾 (<CJK Ideograph>) 15365 0x7783 瞃 (<CJK Ideograph>) 15366 0x78B2 碲 (<CJK Ideograph>) 15367 0x78AA 碪 (<CJK Ideograph>) 15368 0x78B4 碴 (<CJK Ideograph>) 15369 0x78AD 碭 (<CJK Ideograph>) 15370 0x78A8 碨 (<CJK Ideograph>) 15371 0x787E 硾 (<CJK Ideograph>) 15372 0x78AB 碫 (<CJK Ideograph>) 15373 0x789E 碞 (<CJK Ideograph>) 15374 0x78A5 碥 (<CJK Ideograph>) 15375 0x78A0 碠 (<CJK Ideograph>) 15376 0x78AC 碬 (<CJK Ideograph>) 15377 0x78A2 碢 (<CJK Ideograph>) 15378 0x78A4 碤 (<CJK Ideograph>) 15379 0x7998 禘 (<CJK Ideograph>) 15380 0x798A 禊 (<CJK Ideograph>) 15381 0x798B 禋 (<CJK Ideograph>) 15382 0x7996 禖 (<CJK Ideograph>) 15383 0x7995 禕 (<CJK Ideograph>) 15384 0x7994 禔 (<CJK Ideograph>) 15385 0x7993 禓 (<CJK Ideograph>) 15386 0x7997 禗 (<CJK Ideograph>) 15387 0x7988 禈 (<CJK Ideograph>) 15388 0x7992 禒 (<CJK Ideograph>) 15389 0x7990 禐 (<CJK Ideograph>) 15390 0x7A2B 稫 (<CJK Ideograph>) 15391 0x7A4A 穊 (<CJK Ideograph>) 15392 0x7A30 稰 (<CJK Ideograph>) 15393 0x7A2F 稯 (<CJK Ideograph>) 15394 0x7A28 稨 (<CJK Ideograph>) 15395 0x7A26 稦 (<CJK Ideograph>) 15396 0x7AA8 窨 (<CJK Ideograph>) 15397 0x7AAB 窫 (<CJK Ideograph>) 15398 0x7AAC 窬 (<CJK Ideograph>) 15399 0x7AEE 竮 (<CJK Ideograph>) 15400 0x7B88 箈 (<CJK Ideograph>) 15401 0x7B9C 箜 (<CJK Ideograph>) 15402 0x7B8A 箊 (<CJK Ideograph>) 15403 0x7B91 箑 (<CJK Ideograph>) 15404 0x7B90 箐 (<CJK Ideograph>) 15405 0x7B96 箖 (<CJK Ideograph>) 15406 0x7B8D 箍 (<CJK Ideograph>) 15407 0x7B8C 箌 (<CJK Ideograph>) 15408 0x7B9B 箛 (<CJK Ideograph>) 15409 0x7B8E 箎 (<CJK Ideograph>) 15410 0x7B85 箅 (<CJK Ideograph>) 15411 0x7B98 箘 (<CJK Ideograph>) 15412 0x5284 劄 (<CJK Ideograph>) 15413 0x7B99 箙 (<CJK Ideograph>) 15414 0x7BA4 箤 (<CJK Ideograph>) 15415 0x7B82 箂 (<CJK Ideograph>) 15416 0x7CBB 粻 (<CJK Ideograph>) 15417 0x7CBF 粿 (<CJK Ideograph>) 15418 0x7CBC 粼 (<CJK Ideograph>) 15419 0x7CBA 粺 (<CJK Ideograph>) 15420 0x7DA7 綧 (<CJK Ideograph>) 15421 0x7DB7 綷 (<CJK Ideograph>) 15422 0x7DC2 緂 (<CJK Ideograph>) 15423 0x7DA3 綣 (<CJK Ideograph>) 15424 0x7DAA 綪 (<CJK Ideograph>) 15425 0x7DC1 緁 (<CJK Ideograph>) 15426 0x7DC0 緀 (<CJK Ideograph>) 15427 0x7DC5 緅 (<CJK Ideograph>) 15428 0x7D9D 綝 (<CJK Ideograph>) 15429 0x7DCE 緎 (<CJK Ideograph>) 15430 0x7DC4 緄 (<CJK Ideograph>) 15431 0x7DC6 緆 (<CJK Ideograph>) 15432 0x7DCB 緋 (<CJK Ideograph>) 15433 0x7DCC 緌 (<CJK Ideograph>) 15434 0x7DAF 綯 (<CJK Ideograph>) 15435 0x7DB9 綹 (<CJK Ideograph>) 15436 0x7D96 綖 (<CJK Ideograph>) 15437 0x7DBC 綼 (<CJK Ideograph>) 15438 0x7D9F 綟 (<CJK Ideograph>) 15439 0x7DA6 綦 (<CJK Ideograph>) 15440 0x7DAE 綮 (<CJK Ideograph>) 15441 0x7DA9 綩 (<CJK Ideograph>) 15442 0x7DA1 綡 (<CJK Ideograph>) 15443 0x7DC9 緉 (<CJK Ideograph>) 15444 0x7F73 罳 (<CJK Ideograph>) 15445 0x7FE2 翢 (<CJK Ideograph>) 15446 0x7FE3 翣 (<CJK Ideograph>) 15447 0x7FE5 翥 (<CJK Ideograph>) 15448 0x7FDE 翞 (<CJK Ideograph>) 15449 0x8024 耤 (<CJK Ideograph>) 15450 0x805D 聝 (<CJK Ideograph>) 15451 0x805C 聜 (<CJK Ideograph>) 15452 0x8189 膉 (<CJK Ideograph>) 15453 0x8186 膆 (<CJK Ideograph>) 15454 0x8183 膃 (<CJK Ideograph>) 15455 0x8187 膇 (<CJK Ideograph>) 15456 0x818D 膍 (<CJK Ideograph>) 15457 0x818C 膌 (<CJK Ideograph>) 15458 0x818B 膋 (<CJK Ideograph>) 15459 0x8215 舕 (<CJK Ideograph>) 15460 0x8497 蒗 (<CJK Ideograph>) 15461 0x84A4 蒤 (<CJK Ideograph>) 15462 0x84A1 蒡 (<CJK Ideograph>) 15463 0x849F 蒟 (<CJK Ideograph>) 15464 0x84BA 蒺 (<CJK Ideograph>) 15465 0x84CE 蓎 (<CJK Ideograph>) 15466 0x84C2 蓂 (<CJK Ideograph>) 15467 0x84AC 蒬 (<CJK Ideograph>) 15468 0x84AE 蒮 (<CJK Ideograph>) 15469 0x84AB 蒫 (<CJK Ideograph>) 15470 0x84B9 蒹 (<CJK Ideograph>) 15471 0x84B4 蒴 (<CJK Ideograph>) 15472 0x84C1 蓁 (<CJK Ideograph>) 15473 0x84CD 蓍 (<CJK Ideograph>) 15474 0x84AA 蒪 (<CJK Ideograph>) 15475 0x849A 蒚 (<CJK Ideograph>) 15476 0x84B1 蒱 (<CJK Ideograph>) 15477 0x84D0 蓐 (<CJK Ideograph>) 15478 0x849D 蒝 (<CJK Ideograph>) 15479 0x84A7 蒧 (<CJK Ideograph>) 15480 0x84BB 蒻 (<CJK Ideograph>) 15481 0x84A2 蒢 (<CJK Ideograph>) 15482 0x8494 蒔 (<CJK Ideograph>) 15483 0x84C7 蓇 (<CJK Ideograph>) 15484 0x84CC 蓌 (<CJK Ideograph>) 15485 0x849B 蒛 (<CJK Ideograph>) 15486 0x84A9 蒩 (<CJK Ideograph>) 15487 0x84AF 蒯 (<CJK Ideograph>) 15488 0x84A8 蒨 (<CJK Ideograph>) 15489 0x84D6 蓖 (<CJK Ideograph>) 15490 0x8498 蒘 (<CJK Ideograph>) 15491 0x84B6 蒶 (<CJK Ideograph>) 15492 0x84CF 蓏 (<CJK Ideograph>) 15493 0x84A0 蒠 (<CJK Ideograph>) 15494 0x84D7 蓗 (<CJK Ideograph>) 15495 0x84D4 蓔 (<CJK Ideograph>) 15496 0x84D2 蓒 (<CJK Ideograph>) 15497 0x84DB 蓛 (<CJK Ideograph>) 15498 0x84B0 蒰 (<CJK Ideograph>) 15499 0x8491 蒑 (<CJK Ideograph>) 15500 0x8661 虡 (<CJK Ideograph>) 15501 0x8733 蜳 (<CJK Ideograph>) 15502 0x8723 蜣 (<CJK Ideograph>) 15503 0x8728 蜨 (<CJK Ideograph>) 15504 0x876B 蝫 (<CJK Ideograph>) 15505 0x8740 蝀 (<CJK Ideograph>) 15506 0x872E 蜮 (<CJK Ideograph>) 15507 0x871E 蜞 (<CJK Ideograph>) 15508 0x8721 蜡 (<CJK Ideograph>) 15509 0x8719 蜙 (<CJK Ideograph>) 15510 0x871B 蜛 (<CJK Ideograph>) 15511 0x8743 蝃 (<CJK Ideograph>) 15512 0x872C 蜬 (<CJK Ideograph>) 15513 0x8741 蝁 (<CJK Ideograph>) 15514 0x873E 蜾 (<CJK Ideograph>) 15515 0x8746 蝆 (<CJK Ideograph>) 15516 0x8720 蜠 (<CJK Ideograph>) 15517 0x8732 蜲 (<CJK Ideograph>) 15518 0x872A 蜪 (<CJK Ideograph>) 15519 0x872D 蜭 (<CJK Ideograph>) 15520 0x873C 蜼 (<CJK Ideograph>) 15521 0x8712 蜒 (<CJK Ideograph>) 15522 0x873A 蜺 (<CJK Ideograph>) 15523 0x8731 蜱 (<CJK Ideograph>) 15524 0x8735 蜵 (<CJK Ideograph>) 15525 0x8742 蝂 (<CJK Ideograph>) 15526 0x8726 蜦 (<CJK Ideograph>) 15527 0x8727 蜧 (<CJK Ideograph>) 15528 0x8738 蜸 (<CJK Ideograph>) 15529 0x8724 蜤 (<CJK Ideograph>) 15530 0x871A 蜚 (<CJK Ideograph>) 15531 0x8730 蜰 (<CJK Ideograph>) 15532 0x8711 蜑 (<CJK Ideograph>) 15533 0x88F7 裷 (<CJK Ideograph>) 15534 0x88E7 裧 (<CJK Ideograph>) 15535 0x88F1 裱 (<CJK Ideograph>) 15536 0x88F2 裲 (<CJK Ideograph>) 15537 0x88FA 裺 (<CJK Ideograph>) 15538 0x88FE 裾 (<CJK Ideograph>) 15539 0x88EE 裮 (<CJK Ideograph>) 15540 0x88FC 裼 (<CJK Ideograph>) 15541 0x88F6 裶 (<CJK Ideograph>) 15542 0x88FB 裻 (<CJK Ideograph>) 15543 0x88F0 裰 (<CJK Ideograph>) 15544 0x88EC 裬 (<CJK Ideograph>) 15545 0x88EB 裫 (<CJK Ideograph>) 15546 0x899D 覝 (<CJK Ideograph>) 15547 0x89A1 覡 (<CJK Ideograph>) 15548 0x899F 覟 (<CJK Ideograph>) 15549 0x899E 覞 (<CJK Ideograph>) 15550 0x89E9 觩 (<CJK Ideograph>) 15551 0x89EB 觫 (<CJK Ideograph>) 15552 0x89E8 觨 (<CJK Ideograph>) 15553 0x8AAB 誫 (<CJK Ideograph>) 15554 0x8A99 誙 (<CJK Ideograph>) 15555 0x8A8B 誋 (<CJK Ideograph>) 15556 0x8A92 誒 (<CJK Ideograph>) 15557 0x8A8F 誏 (<CJK Ideograph>) 15558 0x8A96 誖 (<CJK Ideograph>) 15559 0x8C3D 谽 (<CJK Ideograph>) 15560 0x8C68 豨 (<CJK Ideograph>) 15561 0x8C69 豩 (<CJK Ideograph>) 15562 0x8CD5 賕 (<CJK Ideograph>) 15563 0x8CCF 賏 (<CJK Ideograph>) 15564 0x8CD7 賗 (<CJK Ideograph>) 15565 0x8D96 趖 (<CJK Ideograph>) 15566 0x8E09 踉 (<CJK Ideograph>) 15567 0x8E02 踂 (<CJK Ideograph>) 15568 0x8DFF 跿 (<CJK Ideograph>) 15569 0x8E0D 踍 (<CJK Ideograph>) 15570 0x8DFD 跽 (<CJK Ideograph>) 15571 0x8E0A 踊 (<CJK Ideograph>) 15572 0x8E03 踃 (<CJK Ideograph>) 15573 0x8E07 踇 (<CJK Ideograph>) 15574 0x8E06 踆 (<CJK Ideograph>) 15575 0x8E05 踅 (<CJK Ideograph>) 15576 0x8DFE 跾 (<CJK Ideograph>) 15577 0x8E00 踀 (<CJK Ideograph>) 15578 0x8E04 踄 (<CJK Ideograph>) 15579 0x8F10 輐 (<CJK Ideograph>) 15580 0x8F11 輑 (<CJK Ideograph>) 15581 0x8F0E 輎 (<CJK Ideograph>) 15582 0x8F0D 輍 (<CJK Ideograph>) 15583 0x9123 鄣 (<CJK Ideograph>) 15584 0x911C 鄜 (<CJK Ideograph>) 15585 0x9120 鄠 (<CJK Ideograph>) 15586 0x9122 鄢 (<CJK Ideograph>) 15587 0x911F 鄟 (<CJK Ideograph>) 15588 0x911D 鄝 (<CJK Ideograph>) 15589 0x911A 鄚 (<CJK Ideograph>) 15590 0x9124 鄤 (<CJK Ideograph>) 15591 0x9121 鄡 (<CJK Ideograph>) 15592 0x911B 鄛 (<CJK Ideograph>) 15593 0x917A 酺 (<CJK Ideograph>) 15594 0x9172 酲 (<CJK Ideograph>) 15595 0x9179 酹 (<CJK Ideograph>) 15596 0x9173 酳 (<CJK Ideograph>) 15597 0x92A5 銥 (<CJK Ideograph>) 15598 0x92A4 銤 (<CJK Ideograph>) 15599 0x9276 鉶 (<CJK Ideograph>) 15600 0x929B 銛 (<CJK Ideograph>) 15601 0x927A 鉺 (<CJK Ideograph>) 15602 0x92A0 銠 (<CJK Ideograph>) 15603 0x9294 銔 (<CJK Ideograph>) 15604 0x92AA 銪 (<CJK Ideograph>) 15605 0x928D 銍 (<CJK Ideograph>) 15606 0x92A6 銦 (<CJK Ideograph>) 15607 0x929A 銚 (<CJK Ideograph>) 15608 0x92AB 銫 (<CJK Ideograph>) 15609 0x9279 鉹 (<CJK Ideograph>) 15610 0x9297 銗 (<CJK Ideograph>) 15611 0x927F 鉿 (<CJK Ideograph>) 15612 0x92A3 銣 (<CJK Ideograph>) 15613 0x92EE 鋮 (<CJK Ideograph>) 15614 0x928E 銎 (<CJK Ideograph>) 15615 0x9282 銂 (<CJK Ideograph>) 15616 0x9295 銕 (<CJK Ideograph>) 15617 0x92A2 銢 (<CJK Ideograph>) 15618 0x927D 鉽 (<CJK Ideograph>) 15619 0x9288 銈 (<CJK Ideograph>) 15620 0x92A1 銡 (<CJK Ideograph>) 15621 0x928A 銊 (<CJK Ideograph>) 15622 0x9286 銆 (<CJK Ideograph>) 15623 0x928C 銌 (<CJK Ideograph>) 15624 0x9299 銙 (<CJK Ideograph>) 15625 0x92A7 銧 (<CJK Ideograph>) 15626 0x927E 鉾 (<CJK Ideograph>) 15627 0x9287 銇 (<CJK Ideograph>) 15628 0x92A9 銩 (<CJK Ideograph>) 15629 0x929D 銝 (<CJK Ideograph>) 15630 0x928B 銋 (<CJK Ideograph>) 15631 0x922D 鈭 (<CJK Ideograph>) 15632 0x969E 隞 (<CJK Ideograph>) 15633 0x96A1 隡 (<CJK Ideograph>) 15634 0x96FF 雿 (<CJK Ideograph>) 15635 0x9758 靘 (<CJK Ideograph>) 15636 0x977D 靽 (<CJK Ideograph>) 15637 0x977A 靺 (<CJK Ideograph>) 15638 0x977E 靾 (<CJK Ideograph>) 15639 0x9783 鞃 (<CJK Ideograph>) 15640 0x9780 鞀 (<CJK Ideograph>) 15641 0x9782 鞂 (<CJK Ideograph>) 15642 0x977B 靻 (<CJK Ideograph>) 15643 0x9784 鞄 (<CJK Ideograph>) 15644 0x9781 鞁 (<CJK Ideograph>) 15645 0x977F 靿 (<CJK Ideograph>) 15646 0x97CE 韎 (<CJK Ideograph>) 15647 0x97CD 韍 (<CJK Ideograph>) 15648 0x9816 頖 (<CJK Ideograph>) 15649 0x98AD 颭 (<CJK Ideograph>) 15650 0x98AE 颮 (<CJK Ideograph>) 15651 0x9902 餂 (<CJK Ideograph>) 15652 0x9900 餀 (<CJK Ideograph>) 15653 0x9907 餇 (<CJK Ideograph>) 15654 0x999D 馝 (<CJK Ideograph>) 15655 0x999C 馜 (<CJK Ideograph>) 15656 0x99C3 駃 (<CJK Ideograph>) 15657 0x99B9 馹 (<CJK Ideograph>) 15658 0x99BB 馻 (<CJK Ideograph>) 15659 0x99BA 馺 (<CJK Ideograph>) 15660 0x99C2 駂 (<CJK Ideograph>) 15661 0x99BD 馽 (<CJK Ideograph>) 15662 0x99C7 駇 (<CJK Ideograph>) 15663 0x9AB1 骱 (<CJK Ideograph>) 15664 0x9AE3 髣 (<CJK Ideograph>) 15665 0x9AE7 髧 (<CJK Ideograph>) 15666 0x9B3E 鬾 (<CJK Ideograph>) 15667 0x9B3F 鬿 (<CJK Ideograph>) 15668 0x9B60 魠 (<CJK Ideograph>) 15669 0x9B61 魡 (<CJK Ideograph>) 15670 0x9B5F 魟 (<CJK Ideograph>) 15671 0x9CF1 鳱 (<CJK Ideograph>) 15672 0x9CF2 鳲 (<CJK Ideograph>) 15673 0x9CF5 鳵 (<CJK Ideograph>) 15674 0x9EA7 麧 (<CJK Ideograph>) 15675 0x50FF 僿 (<CJK Ideograph>) 15676 0x5103 儃 (<CJK Ideograph>) 15677 0x5130 儰 (<CJK Ideograph>) 15678 0x50F8 僸 (<CJK Ideograph>) 15679 0x5106 儆 (<CJK Ideograph>) 15680 0x5107 儇 (<CJK Ideograph>) 15681 0x50F6 僶 (<CJK Ideograph>) 15682 0x50FE 僾 (<CJK Ideograph>) 15683 0x510B 儋 (<CJK Ideograph>) 15684 0x510C 儌 (<CJK Ideograph>) 15685 0x50FD 僽 (<CJK Ideograph>) 15686 0x510A 儊 (<CJK Ideograph>) 15687 0x528B 劋 (<CJK Ideograph>) 15688 0x528C 劌 (<CJK Ideograph>) 15689 0x52F1 勱 (<CJK Ideograph>) 15690 0x52EF 勯 (<CJK Ideograph>) 15691 0x5648 噈 (<CJK Ideograph>) 15692 0x5642 噂 (<CJK Ideograph>) 15693 0x564C 噌 (<CJK Ideograph>) 15694 0x5635 嘵 (<CJK Ideograph>) 15695 0x5641 噁 (<CJK Ideograph>) 15696 0x564A 噊 (<CJK Ideograph>) 15697 0x5649 噉 (<CJK Ideograph>) 15698 0x5646 噆 (<CJK Ideograph>) 15699 0x5658 噘 (<CJK Ideograph>) 15700 0x565A 噚 (<CJK Ideograph>) 15701 0x5640 噀 (<CJK Ideograph>) 15702 0x5633 嘳 (<CJK Ideograph>) 15703 0x563D 嘽 (<CJK Ideograph>) 15704 0x562C 嘬 (<CJK Ideograph>) 15705 0x563E 嘾 (<CJK Ideograph>) 15706 0x5638 嘸 (<CJK Ideograph>) 15707 0x562A 嘪 (<CJK Ideograph>) 15708 0x563A 嘺 (<CJK Ideograph>) 15709 0x571A 圚 (<CJK Ideograph>) 15710 0x58AB 墫 (<CJK Ideograph>) 15711 0x589D 墝 (<CJK Ideograph>) 15712 0x58B1 墱 (<CJK Ideograph>) 15713 0x58A0 墠 (<CJK Ideograph>) 15714 0x58A3 墣 (<CJK Ideograph>) 15715 0x58AF 墯 (<CJK Ideograph>) 15716 0x58AC 墬 (<CJK Ideograph>) 15717 0x58A5 墥 (<CJK Ideograph>) 15718 0x58A1 墡 (<CJK Ideograph>) 15719 0x58FF 壿 (<CJK Ideograph>) 15720 0x5AFF 嫿 (<CJK Ideograph>) 15721 0x5AF4 嫴 (<CJK Ideograph>) 15722 0x5AFD 嫽 (<CJK Ideograph>) 15723 0x5AF7 嫷 (<CJK Ideograph>) 15724 0x5AF6 嫶 (<CJK Ideograph>) 15725 0x5B03 嬃 (<CJK Ideograph>) 15726 0x5AF8 嫸 (<CJK Ideograph>) 15727 0x5B02 嬂 (<CJK Ideograph>) 15728 0x5AF9 嫹 (<CJK Ideograph>) 15729 0x5B01 嬁 (<CJK Ideograph>) 15730 0x5B07 嬇 (<CJK Ideograph>) 15731 0x5B05 嬅 (<CJK Ideograph>) 15732 0x5B0F 嬏 (<CJK Ideograph>) 15733 0x5C67 屧 (<CJK Ideograph>) 15734 0x5D99 嶙 (<CJK Ideograph>) 15735 0x5D97 嶗 (<CJK Ideograph>) 15736 0x5D9F 嶟 (<CJK Ideograph>) 15737 0x5D92 嶒 (<CJK Ideograph>) 15738 0x5DA2 嶢 (<CJK Ideograph>) 15739 0x5D93 嶓 (<CJK Ideograph>) 15740 0x5D95 嶕 (<CJK Ideograph>) 15741 0x5DA0 嶠 (<CJK Ideograph>) 15742 0x5D9C 嶜 (<CJK Ideograph>) 15743 0x5DA1 嶡 (<CJK Ideograph>) 15744 0x5D9A 嶚 (<CJK Ideograph>) 15745 0x5D9E 嶞 (<CJK Ideograph>) 15746 0x5E69 幩 (<CJK Ideograph>) 15747 0x5E5D 幝 (<CJK Ideograph>) 15748 0x5E60 幠 (<CJK Ideograph>) 15749 0x5E5C 幜 (<CJK Ideograph>) 15750 0x7DF3 緳 (<CJK Ideograph>) 15751 0x5EDB 廛 (<CJK Ideograph>) 15752 0x5EDE 廞 (<CJK Ideograph>) 15753 0x5EE1 廡 (<CJK Ideograph>) 15754 0x5F49 彉 (<CJK Ideograph>) 15755 0x5FB2 徲 (<CJK Ideograph>) 15756 0x618B 憋 (<CJK Ideograph>) 15757 0x6183 憃 (<CJK Ideograph>) 15758 0x6179 慹 (<CJK Ideograph>) 15759 0x61B1 憱 (<CJK Ideograph>) 15760 0x61B0 憰 (<CJK Ideograph>) 15761 0x61A2 憢 (<CJK Ideograph>) 15762 0x6189 憉 (<CJK Ideograph>) 15763 0x619B 憛 (<CJK Ideograph>) 15764 0x6193 憓 (<CJK Ideograph>) 15765 0x61AF 憯 (<CJK Ideograph>) 15766 0x61AD 憭 (<CJK Ideograph>) 15767 0x619F 憟 (<CJK Ideograph>) 15768 0x6192 憒 (<CJK Ideograph>) 15769 0x61AA 憪 (<CJK Ideograph>) 15770 0x61A1 憡 (<CJK Ideograph>) 15771 0x618D 憍 (<CJK Ideograph>) 15772 0x6166 慦 (<CJK Ideograph>) 15773 0x61B3 憳 (<CJK Ideograph>) 15774 0x622D 戭 (<CJK Ideograph>) 15775 0x646E 摮 (<CJK Ideograph>) 15776 0x6470 摰 (<CJK Ideograph>) 15777 0x6496 撖 (<CJK Ideograph>) 15778 0x64A0 撠 (<CJK Ideograph>) 15779 0x6485 撅 (<CJK Ideograph>) 15780 0x6497 撗 (<CJK Ideograph>) 15781 0x649C 撜 (<CJK Ideograph>) 15782 0x648F 撏 (<CJK Ideograph>) 15783 0x648B 撋 (<CJK Ideograph>) 15784 0x648A 撊 (<CJK Ideograph>) 15785 0x648C 撌 (<CJK Ideograph>) 15786 0x64A3 撣 (<CJK Ideograph>) 15787 0x649F 撟 (<CJK Ideograph>) 15788 0x6468 摨 (<CJK Ideograph>) 15789 0x64B1 撱 (<CJK Ideograph>) 15790 0x6498 撘 (<CJK Ideograph>) 15791 0x6576 敶 (<CJK Ideograph>) 15792 0x657A 敺 (<CJK Ideograph>) 15793 0x6579 敹 (<CJK Ideograph>) 15794 0x657B 敻 (<CJK Ideograph>) 15795 0x65B2 斲 (<CJK Ideograph>) 15796 0x65B3 斳 (<CJK Ideograph>) 15797 0x66B5 暵 (<CJK Ideograph>) 15798 0x66B0 暰 (<CJK Ideograph>) 15799 0x66A9 暩 (<CJK Ideograph>) 15800 0x66B2 暲 (<CJK Ideograph>) 15801 0x66B7 暷 (<CJK Ideograph>) 15802 0x66AA 暪 (<CJK Ideograph>) 15803 0x66AF 暯 (<CJK Ideograph>) 15804 0x6A00 樀 (<CJK Ideograph>) 15805 0x6A06 樆 (<CJK Ideograph>) 15806 0x6A17 樗 (<CJK Ideograph>) 15807 0x69E5 槥 (<CJK Ideograph>) 15808 0x69F8 槸 (<CJK Ideograph>) 15809 0x6A15 樕 (<CJK Ideograph>) 15810 0x69F1 槱 (<CJK Ideograph>) 15811 0x69E4 槤 (<CJK Ideograph>) 15812 0x6A20 樠 (<CJK Ideograph>) 15813 0x69FF 槿 (<CJK Ideograph>) 15814 0x69EC 槬 (<CJK Ideograph>) 15815 0x69E2 槢 (<CJK Ideograph>) 15816 0x6A1B 樛 (<CJK Ideograph>) 15817 0x6A1D 樝 (<CJK Ideograph>) 15818 0x69FE 槾 (<CJK Ideograph>) 15819 0x6A27 樧 (<CJK Ideograph>) 15820 0x69F2 槲 (<CJK Ideograph>) 15821 0x69EE 槮 (<CJK Ideograph>) 15822 0x6A14 樔 (<CJK Ideograph>) 15823 0x69F7 槷 (<CJK Ideograph>) 15824 0x69E7 槧 (<CJK Ideograph>) 15825 0x6A40 橀 (<CJK Ideograph>) 15826 0x6A08 樈 (<CJK Ideograph>) 15827 0x69E6 槦 (<CJK Ideograph>) 15828 0x69FB 槻 (<CJK Ideograph>) 15829 0x6A0D 樍 (<CJK Ideograph>) 15830 0x69FC 槼 (<CJK Ideograph>) 15831 0x69EB 槫 (<CJK Ideograph>) 15832 0x6A09 樉 (<CJK Ideograph>) 15833 0x6A04 樄 (<CJK Ideograph>) 15834 0x6A18 樘 (<CJK Ideograph>) 15835 0x6A25 樥 (<CJK Ideograph>) 15836 0x6A0F 樏 (<CJK Ideograph>) 15837 0x69F6 槶 (<CJK Ideograph>) 15838 0x6A26 樦 (<CJK Ideograph>) 15839 0x6A07 樇 (<CJK Ideograph>) 15840 0x69F4 槴 (<CJK Ideograph>) 15841 0x6A16 樖 (<CJK Ideograph>) 15842 0x6B51 歑 (<CJK Ideograph>) 15843 0x6BA5 殥 (<CJK Ideograph>) 15844 0x6BA3 殣 (<CJK Ideograph>) 15845 0x6BA2 殢 (<CJK Ideograph>) 15846 0x6BA6 殦 (<CJK Ideograph>) 15847 0x6C01 氁 (<CJK Ideograph>) 15848 0x6C00 氀 (<CJK Ideograph>) 15849 0x6BFF 毿 (<CJK Ideograph>) 15850 0x6C02 氂 (<CJK Ideograph>) 15851 0x6F41 潁 (<CJK Ideograph>) 15852 0x6F26 漦 (<CJK Ideograph>) 15853 0x6F7E 潾 (<CJK Ideograph>) 15854 0x6F87 澇 (<CJK Ideograph>) 15855 0x6FC6 濆 (<CJK Ideograph>) 15856 0x6F92 澒 (<CJK Ideograph>) 15857 0x6F8D 澍 (<CJK Ideograph>) 15858 0x6F89 澉 (<CJK Ideograph>) 15859 0x6F8C 澌 (<CJK Ideograph>) 15860 0x6F62 潢 (<CJK Ideograph>) 15861 0x6F4F 潏 (<CJK Ideograph>) 15862 0x6F85 澅 (<CJK Ideograph>) 15863 0x6F5A 潚 (<CJK Ideograph>) 15864 0x6F96 澖 (<CJK Ideograph>) 15865 0x6F76 潶 (<CJK Ideograph>) 15866 0x6F6C 潬 (<CJK Ideograph>) 15867 0x6F82 澂 (<CJK Ideograph>) 15868 0x6F55 潕 (<CJK Ideograph>) 15869 0x6F72 潲 (<CJK Ideograph>) 15870 0x6F52 潒 (<CJK Ideograph>) 15871 0x6F50 潐 (<CJK Ideograph>) 15872 0x6F57 潗 (<CJK Ideograph>) 15873 0x6F94 澔 (<CJK Ideograph>) 15874 0x6F93 澓 (<CJK Ideograph>) 15875 0x6F5D 潝 (<CJK Ideograph>) 15876 0x6F00 漀 (<CJK Ideograph>) 15877 0x6F61 潡 (<CJK Ideograph>) 15878 0x6F6B 潫 (<CJK Ideograph>) 15879 0x6F7D 潽 (<CJK Ideograph>) 15880 0x6F67 潧 (<CJK Ideograph>) 15881 0x6F90 澐 (<CJK Ideograph>) 15882 0x6F53 潓 (<CJK Ideograph>) 15883 0x6F8B 澋 (<CJK Ideograph>) 15884 0x6F69 潩 (<CJK Ideograph>) 15885 0x6F7F 潿 (<CJK Ideograph>) 15886 0x6F95 澕 (<CJK Ideograph>) 15887 0x6F63 潣 (<CJK Ideograph>) 15888 0x6F77 潷 (<CJK Ideograph>) 15889 0x6F6A 潪 (<CJK Ideograph>) 15890 0x6F7B 潻 (<CJK Ideograph>) 15891 0x71B2 熲 (<CJK Ideograph>) 15892 0x71AF 熯 (<CJK Ideograph>) 15893 0x719B 熛 (<CJK Ideograph>) 15894 0x71B0 熰 (<CJK Ideograph>) 15895 0x71A0 熠 (<CJK Ideograph>) 15896 0x719A 熚 (<CJK Ideograph>) 15897 0x71A9 熩 (<CJK Ideograph>) 15898 0x71B5 熵 (<CJK Ideograph>) 15899 0x719D 熝 (<CJK Ideograph>) 15900 0x71A5 熥 (<CJK Ideograph>) 15901 0x719E 熞 (<CJK Ideograph>) 15902 0x71A4 熤 (<CJK Ideograph>) 15903 0x71A1 熡 (<CJK Ideograph>) 15904 0x71AA 熪 (<CJK Ideograph>) 15905 0x719C 熜 (<CJK Ideograph>) 15906 0x71A7 熧 (<CJK Ideograph>) 15907 0x71B3 熳 (<CJK Ideograph>) 15908 0x7298 犘 (<CJK Ideograph>) 15909 0x729A 犚 (<CJK Ideograph>) 15910 0x7358 獘 (<CJK Ideograph>) 15911 0x7352 獒 (<CJK Ideograph>) 15912 0x735E 獞 (<CJK Ideograph>) 15913 0x735F 獟 (<CJK Ideograph>) 15914 0x7360 獠 (<CJK Ideograph>) 15915 0x735D 獝 (<CJK Ideograph>) 15916 0x735B 獛 (<CJK Ideograph>) 15917 0x7361 獡 (<CJK Ideograph>) 15918 0x735A 獚 (<CJK Ideograph>) 15919 0x7359 獙 (<CJK Ideograph>) 15920 0x7362 獢 (<CJK Ideograph>) 15921 0x7487 璇 (<CJK Ideograph>) 15922 0x7489 璉 (<CJK Ideograph>) 15923 0x748A 璊 (<CJK Ideograph>) 15924 0x7486 璆 (<CJK Ideograph>) 15925 0x7481 璁 (<CJK Ideograph>) 15926 0x747D 瑽 (<CJK Ideograph>) 15927 0x7485 璅 (<CJK Ideograph>) 15928 0x7488 璈 (<CJK Ideograph>) 15929 0x747C 瑼 (<CJK Ideograph>) 15930 0x7479 瑹 (<CJK Ideograph>) 15931 0x7508 甈 (<CJK Ideograph>) 15932 0x7507 甇 (<CJK Ideograph>) 15933 0x757E 畾 (<CJK Ideograph>) 15934 0x7625 瘥 (<CJK Ideograph>) 15935 0x761E 瘞 (<CJK Ideograph>) 15936 0x7619 瘙 (<CJK Ideograph>) 15937 0x761D 瘝 (<CJK Ideograph>) 15938 0x761C 瘜 (<CJK Ideograph>) 15939 0x7623 瘣 (<CJK Ideograph>) 15940 0x761A 瘚 (<CJK Ideograph>) 15941 0x7628 瘨 (<CJK Ideograph>) 15942 0x761B 瘛 (<CJK Ideograph>) 15943 0x769C 皜 (<CJK Ideograph>) 15944 0x769D 皝 (<CJK Ideograph>) 15945 0x769E 皞 (<CJK Ideograph>) 15946 0x769B 皛 (<CJK Ideograph>) 15947 0x778D 瞍 (<CJK Ideograph>) 15948 0x778F 瞏 (<CJK Ideograph>) 15949 0x7789 瞉 (<CJK Ideograph>) 15950 0x7788 瞈 (<CJK Ideograph>) 15951 0x78CD 磍 (<CJK Ideograph>) 15952 0x78BB 碻 (<CJK Ideograph>) 15953 0x78CF 磏 (<CJK Ideograph>) 15954 0x78CC 磌 (<CJK Ideograph>) 15955 0x78D1 磑 (<CJK Ideograph>) 15956 0x78CE 磎 (<CJK Ideograph>) 15957 0x78D4 磔 (<CJK Ideograph>) 15958 0x78C8 磈 (<CJK Ideograph>) 15959 0x78C3 磃 (<CJK Ideograph>) 15960 0x78C4 磄 (<CJK Ideograph>) 15961 0x78C9 磉 (<CJK Ideograph>) 15962 0x799A 禚 (<CJK Ideograph>) 15963 0x79A1 禡 (<CJK Ideograph>) 15964 0x79A0 禠 (<CJK Ideograph>) 15965 0x799C 禜 (<CJK Ideograph>) 15966 0x79A2 禢 (<CJK Ideograph>) 15967 0x799B 禛 (<CJK Ideograph>) 15968 0x6B76 歶 (<CJK Ideograph>) 15969 0x7A39 稹 (<CJK Ideograph>) 15970 0x7AB2 窲 (<CJK Ideograph>) 15971 0x7AB4 窴 (<CJK Ideograph>) 15972 0x7AB3 窳 (<CJK Ideograph>) 15973 0x7BB7 箷 (<CJK Ideograph>) 15974 0x7BCB 篋 (<CJK Ideograph>) 15975 0x7BBE 箾 (<CJK Ideograph>) 15976 0x7BAC 箬 (<CJK Ideograph>) 15977 0x7BCE 篎 (<CJK Ideograph>) 15978 0x7BAF 箯 (<CJK Ideograph>) 15979 0x7BB9 箹 (<CJK Ideograph>) 15980 0x7BCA 篊 (<CJK Ideograph>) 15981 0x7BB5 箵 (<CJK Ideograph>) 15982 0x7CC5 糅 (<CJK Ideograph>) 15983 0x7CC8 糈 (<CJK Ideograph>) 15984 0x7CCC 糌 (<CJK Ideograph>) 15985 0x7CCB 糋 (<CJK Ideograph>) 15986 0x7DF7 緷 (<CJK Ideograph>) 15987 0x7DDB 緛 (<CJK Ideograph>) 15988 0x7DEA 緪 (<CJK Ideograph>) 15989 0x7DE7 緧 (<CJK Ideograph>) 15990 0x7DD7 緗 (<CJK Ideograph>) 15991 0x7DE1 緡 (<CJK Ideograph>) 15992 0x7E03 縃 (<CJK Ideograph>) 15993 0x7DFA 緺 (<CJK Ideograph>) 15994 0x7DE6 緦 (<CJK Ideograph>) 15995 0x7DF6 緶 (<CJK Ideograph>) 15996 0x7DF1 緱 (<CJK Ideograph>) 15997 0x7DF0 緰 (<CJK Ideograph>) 15998 0x7DEE 緮 (<CJK Ideograph>) 15999 0x7DDF 緟 (<CJK Ideograph>) 16000 0x7F76 罶 (<CJK Ideograph>) 16001 0x7FAC 羬 (<CJK Ideograph>) 16002 0x7FB0 羰 (<CJK Ideograph>) 16003 0x7FAD 羭 (<CJK Ideograph>) 16004 0x7FED 翭 (<CJK Ideograph>) 16005 0x7FEB 翫 (<CJK Ideograph>) 16006 0x7FEA 翪 (<CJK Ideograph>) 16007 0x7FEC 翬 (<CJK Ideograph>) 16008 0x7FE6 翦 (<CJK Ideograph>) 16009 0x7FE8 翨 (<CJK Ideograph>) 16010 0x8064 聤 (<CJK Ideograph>) 16011 0x8067 聧 (<CJK Ideograph>) 16012 0x81A3 膣 (<CJK Ideograph>) 16013 0x819F 膟 (<CJK Ideograph>) 16014 0x819E 膞 (<CJK Ideograph>) 16015 0x8195 膕 (<CJK Ideograph>) 16016 0x81A2 膢 (<CJK Ideograph>) 16017 0x8199 膙 (<CJK Ideograph>) 16018 0x8197 膗 (<CJK Ideograph>) 16019 0x8216 舖 (<CJK Ideograph>) 16020 0x824F 艏 (<CJK Ideograph>) 16021 0x8253 艓 (<CJK Ideograph>) 16022 0x8252 艒 (<CJK Ideograph>) 16023 0x8250 艐 (<CJK Ideograph>) 16024 0x824E 艎 (<CJK Ideograph>) 16025 0x8251 艑 (<CJK Ideograph>) 16026 0x8524 蔤 (<CJK Ideograph>) 16027 0x853B 蔻 (<CJK Ideograph>) 16028 0x850F 蔏 (<CJK Ideograph>) 16029 0x8500 蔀 (<CJK Ideograph>) 16030 0x8529 蔩 (<CJK Ideograph>) 16031 0x850E 蔎 (<CJK Ideograph>) 16032 0x8509 蔉 (<CJK Ideograph>) 16033 0x850D 蔍 (<CJK Ideograph>) 16034 0x851F 蔟 (<CJK Ideograph>) 16035 0x850A 蔊 (<CJK Ideograph>) 16036 0x8527 蔧 (<CJK Ideograph>) 16037 0x851C 蔜 (<CJK Ideograph>) 16038 0x84FB 蓻 (<CJK Ideograph>) 16039 0x852B 蔫 (<CJK Ideograph>) 16040 0x84FA 蓺 (<CJK Ideograph>) 16041 0x8508 蔈 (<CJK Ideograph>) 16042 0x850C 蔌 (<CJK Ideograph>) 16043 0x84F4 蓴 (<CJK Ideograph>) 16044 0x852A 蔪 (<CJK Ideograph>) 16045 0x84F2 蓲 (<CJK Ideograph>) 16046 0x8515 蔕 (<CJK Ideograph>) 16047 0x84F7 蓷 (<CJK Ideograph>) 16048 0x84EB 蓫 (<CJK Ideograph>) 16049 0x84F3 蓳 (<CJK Ideograph>) 16050 0x84FC 蓼 (<CJK Ideograph>) 16051 0x8512 蔒 (<CJK Ideograph>) 16052 0x84EA 蓪 (<CJK Ideograph>) 16053 0x84E9 蓩 (<CJK Ideograph>) 16054 0x8516 蔖 (<CJK Ideograph>) 16055 0x84FE 蓾 (<CJK Ideograph>) 16056 0x8528 蔨 (<CJK Ideograph>) 16057 0x851D 蔝 (<CJK Ideograph>) 16058 0x852E 蔮 (<CJK Ideograph>) 16059 0x8502 蔂 (<CJK Ideograph>) 16060 0x84FD 蓽 (<CJK Ideograph>) 16061 0x851E 蔞 (<CJK Ideograph>) 16062 0x84F6 蓶 (<CJK Ideograph>) 16063 0x8531 蔱 (<CJK Ideograph>) 16064 0x8526 蔦 (<CJK Ideograph>) 16065 0x84E7 蓧 (<CJK Ideograph>) 16066 0x84E8 蓨 (<CJK Ideograph>) 16067 0x84F0 蓰 (<CJK Ideograph>) 16068 0x84EF 蓯 (<CJK Ideograph>) 16069 0x84F9 蓹 (<CJK Ideograph>) 16070 0x8518 蔘 (<CJK Ideograph>) 16071 0x8520 蔠 (<CJK Ideograph>) 16072 0x8530 蔰 (<CJK Ideograph>) 16073 0x850B 蔋 (<CJK Ideograph>) 16074 0x8519 蔙 (<CJK Ideograph>) 16075 0x852F 蔯 (<CJK Ideograph>) 16076 0x8662 虢 (<CJK Ideograph>) 16077 0x8756 蝖 (<CJK Ideograph>) 16078 0x8763 蝣 (<CJK Ideograph>) 16079 0x8764 蝤 (<CJK Ideograph>) 16080 0x8777 蝷 (<CJK Ideograph>) 16081 0x87E1 蟡 (<CJK Ideograph>) 16082 0x8773 蝳 (<CJK Ideograph>) 16083 0x8758 蝘 (<CJK Ideograph>) 16084 0x8754 蝔 (<CJK Ideograph>) 16085 0x875B 蝛 (<CJK Ideograph>) 16086 0x8752 蝒 (<CJK Ideograph>) 16087 0x8761 蝡 (<CJK Ideograph>) 16088 0x875A 蝚 (<CJK Ideograph>) 16089 0x8751 蝑 (<CJK Ideograph>) 16090 0x875E 蝞 (<CJK Ideograph>) 16091 0x876D 蝭 (<CJK Ideograph>) 16092 0x876A 蝪 (<CJK Ideograph>) 16093 0x8750 蝐 (<CJK Ideograph>) 16094 0x874E 蝎 (<CJK Ideograph>) 16095 0x875F 蝟 (<CJK Ideograph>) 16096 0x875D 蝝 (<CJK Ideograph>) 16097 0x876F 蝯 (<CJK Ideograph>) 16098 0x876C 蝬 (<CJK Ideograph>) 16099 0x877A 蝺 (<CJK Ideograph>) 16100 0x876E 蝮 (<CJK Ideograph>) 16101 0x875C 蝜 (<CJK Ideograph>) 16102 0x8765 蝥 (<CJK Ideograph>) 16103 0x874F 蝏 (<CJK Ideograph>) 16104 0x877B 蝻 (<CJK Ideograph>) 16105 0x8775 蝵 (<CJK Ideograph>) 16106 0x8762 蝢 (<CJK Ideograph>) 16107 0x8767 蝧 (<CJK Ideograph>) 16108 0x8769 蝩 (<CJK Ideograph>) 16109 0x885A 衚 (<CJK Ideograph>) 16110 0x8905 褅 (<CJK Ideograph>) 16111 0x890C 褌 (<CJK Ideograph>) 16112 0x8914 褔 (<CJK Ideograph>) 16113 0x890B 褋 (<CJK Ideograph>) 16114 0x8917 褗 (<CJK Ideograph>) 16115 0x8918 褘 (<CJK Ideograph>) 16116 0x8919 褙 (<CJK Ideograph>) 16117 0x8906 褆 (<CJK Ideograph>) 16118 0x8916 褖 (<CJK Ideograph>) 16119 0x8911 褑 (<CJK Ideograph>) 16120 0x890E 褎 (<CJK Ideograph>) 16121 0x8909 褉 (<CJK Ideograph>) 16122 0x89A2 覢 (<CJK Ideograph>) 16123 0x89A4 覤 (<CJK Ideograph>) 16124 0x89A3 覣 (<CJK Ideograph>) 16125 0x89ED 觭 (<CJK Ideograph>) 16126 0x89F0 觰 (<CJK Ideograph>) 16127 0x89EC 觬 (<CJK Ideograph>) 16128 0x8ACF 諏 (<CJK Ideograph>) 16129 0x8AC6 諆 (<CJK Ideograph>) 16130 0x8AB8 誸 (<CJK Ideograph>) 16131 0x8AD3 諓 (<CJK Ideograph>) 16132 0x8AD1 諑 (<CJK Ideograph>) 16133 0x8AD4 諔 (<CJK Ideograph>) 16134 0x8AD5 諕 (<CJK Ideograph>) 16135 0x8ABB 誻 (<CJK Ideograph>) 16136 0x8AD7 諗 (<CJK Ideograph>) 16137 0x8ABE 誾 (<CJK Ideograph>) 16138 0x8AC0 諀 (<CJK Ideograph>) 16139 0x8AC5 諅 (<CJK Ideograph>) 16140 0x8AD8 諘 (<CJK Ideograph>) 16141 0x8AC3 諃 (<CJK Ideograph>) 16142 0x8ABA 誺 (<CJK Ideograph>) 16143 0x8ABD 誽 (<CJK Ideograph>) 16144 0x8AD9 諙 (<CJK Ideograph>) 16145 0x8C3E 谾 (<CJK Ideograph>) 16146 0x8C4D 豍 (<CJK Ideograph>) 16147 0x8C8F 貏 (<CJK Ideograph>) 16148 0x8CE5 賥 (<CJK Ideograph>) 16149 0x8CDF 賟 (<CJK Ideograph>) 16150 0x8CD9 賙 (<CJK Ideograph>) 16151 0x8CE8 賨 (<CJK Ideograph>) 16152 0x8CDA 賚 (<CJK Ideograph>) 16153 0x8CDD 賝 (<CJK Ideograph>) 16154 0x8CE7 賧 (<CJK Ideograph>) 16155 0x8DA0 趠 (<CJK Ideograph>) 16156 0x8D9C 趜 (<CJK Ideograph>) 16157 0x8DA1 趡 (<CJK Ideograph>) 16158 0x8D9B 趛 (<CJK Ideograph>) 16159 0x8E20 踠 (<CJK Ideograph>) 16160 0x8E23 踣 (<CJK Ideograph>) 16161 0x8E25 踥 (<CJK Ideograph>) 16162 0x8E24 踤 (<CJK Ideograph>) 16163 0x8E2E 踮 (<CJK Ideograph>) 16164 0x8E15 踕 (<CJK Ideograph>) 16165 0x8E1B 踛 (<CJK Ideograph>) 16166 0x8E16 踖 (<CJK Ideograph>) 16167 0x8E11 踑 (<CJK Ideograph>) 16168 0x8E19 踙 (<CJK Ideograph>) 16169 0x8E26 踦 (<CJK Ideograph>) 16170 0x8E27 踧 (<CJK Ideograph>) 16171 0x8E14 踔 (<CJK Ideograph>) 16172 0x8E12 踒 (<CJK Ideograph>) 16173 0x8E18 踘 (<CJK Ideograph>) 16174 0x8E13 踓 (<CJK Ideograph>) 16175 0x8E1C 踜 (<CJK Ideograph>) 16176 0x8E17 踗 (<CJK Ideograph>) 16177 0x8E1A 踚 (<CJK Ideograph>) 16178 0x8F2C 輬 (<CJK Ideograph>) 16179 0x8F24 輤 (<CJK Ideograph>) 16180 0x8F18 輘 (<CJK Ideograph>) 16181 0x8F1A 輚 (<CJK Ideograph>) 16182 0x8F20 輠 (<CJK Ideograph>) 16183 0x8F23 輣 (<CJK Ideograph>) 16184 0x8F16 輖 (<CJK Ideograph>) 16185 0x8F17 輗 (<CJK Ideograph>) 16186 0x9073 遳 (<CJK Ideograph>) 16187 0x9070 遰 (<CJK Ideograph>) 16188 0x906F 遯 (<CJK Ideograph>) 16189 0x9067 遧 (<CJK Ideograph>) 16190 0x906B 遫 (<CJK Ideograph>) 16191 0x912F 鄯 (<CJK Ideograph>) 16192 0x912B 鄫 (<CJK Ideograph>) 16193 0x9129 鄩 (<CJK Ideograph>) 16194 0x912A 鄪 (<CJK Ideograph>) 16195 0x9132 鄲 (<CJK Ideograph>) 16196 0x9126 鄦 (<CJK Ideograph>) 16197 0x912E 鄮 (<CJK Ideograph>) 16198 0x9185 醅 (<CJK Ideograph>) 16199 0x9186 醆 (<CJK Ideograph>) 16200 0x918A 醊 (<CJK Ideograph>) 16201 0x9181 醁 (<CJK Ideograph>) 16202 0x9182 醂 (<CJK Ideograph>) 16203 0x9184 醄 (<CJK Ideograph>) 16204 0x9180 醀 (<CJK Ideograph>) 16205 0x92D0 鋐 (<CJK Ideograph>) 16206 0x92C3 鋃 (<CJK Ideograph>) 16207 0x92C4 鋄 (<CJK Ideograph>) 16208 0x92C0 鋀 (<CJK Ideograph>) 16209 0x92D9 鋙 (<CJK Ideograph>) 16210 0x92B6 銶 (<CJK Ideograph>) 16211 0x92CF 鋏 (<CJK Ideograph>) 16212 0x92F1 鋱 (<CJK Ideograph>) 16213 0x92DF 鋟 (<CJK Ideograph>) 16214 0x92D8 鋘 (<CJK Ideograph>) 16215 0x92E9 鋩 (<CJK Ideograph>) 16216 0x92D7 鋗 (<CJK Ideograph>) 16217 0x92DD 鋝 (<CJK Ideograph>) 16218 0x92CC 鋌 (<CJK Ideograph>) 16219 0x92EF 鋯 (<CJK Ideograph>) 16220 0x92C2 鋂 (<CJK Ideograph>) 16221 0x92E8 鋨 (<CJK Ideograph>) 16222 0x92CA 鋊 (<CJK Ideograph>) 16223 0x92C8 鋈 (<CJK Ideograph>) 16224 0x92CE 鋎 (<CJK Ideograph>) 16225 0x92E6 鋦 (<CJK Ideograph>) 16226 0x92CD 鋍 (<CJK Ideograph>) 16227 0x92D5 鋕 (<CJK Ideograph>) 16228 0x92C9 鋉 (<CJK Ideograph>) 16229 0x92E0 鋠 (<CJK Ideograph>) 16230 0x92DE 鋞 (<CJK Ideograph>) 16231 0x92E7 鋧 (<CJK Ideograph>) 16232 0x92D1 鋑 (<CJK Ideograph>) 16233 0x92D3 鋓 (<CJK Ideograph>) 16234 0x92B5 銵 (<CJK Ideograph>) 16235 0x92E1 鋡 (<CJK Ideograph>) 16236 0x92C6 鋆 (<CJK Ideograph>) 16237 0x92B4 銴 (<CJK Ideograph>) 16238 0x957C 镼 (<CJK Ideograph>) 16239 0x95AC 閬 (<CJK Ideograph>) 16240 0x95AB 閫 (<CJK Ideograph>) 16241 0x95AE 閮 (<CJK Ideograph>) 16242 0x95B0 閰 (<CJK Ideograph>) 16243 0x96A4 隤 (<CJK Ideograph>) 16244 0x96A2 隢 (<CJK Ideograph>) 16245 0x96D3 雓 (<CJK Ideograph>) 16246 0x9705 霅 (<CJK Ideograph>) 16247 0x9708 霈 (<CJK Ideograph>) 16248 0x9702 霂 (<CJK Ideograph>) 16249 0x975A 靚 (<CJK Ideograph>) 16250 0x978A 鞊 (<CJK Ideograph>) 16251 0x978E 鞎 (<CJK Ideograph>) 16252 0x9788 鞈 (<CJK Ideograph>) 16253 0x97D0 韐 (<CJK Ideograph>) 16254 0x97CF 韏 (<CJK Ideograph>) 16255 0x981E 頞 (<CJK Ideograph>) 16256 0x981D 頝 (<CJK Ideograph>) 16257 0x9826 頦 (<CJK Ideograph>) 16258 0x9829 頩 (<CJK Ideograph>) 16259 0x9828 頨 (<CJK Ideograph>) 16260 0x9820 頠 (<CJK Ideograph>) 16261 0x981B 頛 (<CJK Ideograph>) 16262 0x9827 頧 (<CJK Ideograph>) 16263 0x98B2 颲 (<CJK Ideograph>) 16264 0x9908 餈 (<CJK Ideograph>) 16265 0x98FA 飺 (<CJK Ideograph>) 16266 0x9911 餑 (<CJK Ideograph>) 16267 0x9914 餔 (<CJK Ideograph>) 16268 0x9916 餖 (<CJK Ideograph>) 16269 0x9917 餗 (<CJK Ideograph>) 16270 0x9915 餕 (<CJK Ideograph>) 16271 0x99DC 駜 (<CJK Ideograph>) 16272 0x99CD 駍 (<CJK Ideograph>) 16273 0x99CF 駏 (<CJK Ideograph>) 16274 0x99D3 駓 (<CJK Ideograph>) 16275 0x99D4 駔 (<CJK Ideograph>) 16276 0x99CE 駎 (<CJK Ideograph>) 16277 0x99C9 駉 (<CJK Ideograph>) 16278 0x99D6 駖 (<CJK Ideograph>) 16279 0x99D8 駘 (<CJK Ideograph>) 16280 0x99CB 駋 (<CJK Ideograph>) 16281 0x99D7 駗 (<CJK Ideograph>) 16282 0x99CC 駌 (<CJK Ideograph>) 16283 0x9AB3 骳 (<CJK Ideograph>) 16284 0x9AEC 髬 (<CJK Ideograph>) 16285 0x9AEB 髫 (<CJK Ideograph>) 16286 0x9AF3 髳 (<CJK Ideograph>) 16287 0x9AF2 髲 (<CJK Ideograph>) 16288 0x9AF1 髱 (<CJK Ideograph>) 16289 0x9B46 魆 (<CJK Ideograph>) 16290 0x9B43 魃 (<CJK Ideograph>) 16291 0x9B67 魧 (<CJK Ideograph>) 16292 0x9B74 魴 (<CJK Ideograph>) 16293 0x9B71 魱 (<CJK Ideograph>) 16294 0x9B66 魦 (<CJK Ideograph>) 16295 0x9B76 魶 (<CJK Ideograph>) 16296 0x9B75 魵 (<CJK Ideograph>) 16297 0x9B70 魰 (<CJK Ideograph>) 16298 0x9B68 魨 (<CJK Ideograph>) 16299 0x9B64 魤 (<CJK Ideograph>) 16300 0x9B6C 魬 (<CJK Ideograph>) 16301 0x9CFC 鳼 (<CJK Ideograph>) 16302 0x9CFA 鳺 (<CJK Ideograph>) 16303 0x9CFD 鳽 (<CJK Ideograph>) 16304 0x9CFF 鳿 (<CJK Ideograph>) 16305 0x9CF7 鳷 (<CJK Ideograph>) 16306 0x9D07 鴇 (<CJK Ideograph>) 16307 0x9D00 鴀 (<CJK Ideograph>) 16308 0x9CF9 鳹 (<CJK Ideograph>) 16309 0x9CFB 鳻 (<CJK Ideograph>) 16310 0x9D08 鴈 (<CJK Ideograph>) 16311 0x9D05 鴅 (<CJK Ideograph>) 16312 0x9D04 鴄 (<CJK Ideograph>) 16313 0x9E83 麃 (<CJK Ideograph>) 16314 0x9ED3 黓 (<CJK Ideograph>) 16315 0x9F0F 鼏 (<CJK Ideograph>) 16316 0x9F10 鼐 (<CJK Ideograph>) 16317 0x511C 儜 (<CJK Ideograph>) 16318 0x5113 儓 (<CJK Ideograph>) 16319 0x5117 儗 (<CJK Ideograph>) 16320 0x511A 儚 (<CJK Ideograph>) 16321 0x5111 儑 (<CJK Ideograph>) 16322 0x51DE 凞 (<CJK Ideograph>) 16323 0x5334 匴 (<CJK Ideograph>) 16324 0x53E1 叡 (<CJK Ideograph>) 16325 0x5670 噰 (<CJK Ideograph>) 16326 0x5660 噠 (<CJK Ideograph>) 16327 0x566E 噮 (<CJK Ideograph>) 16328 0x5673 噳 (<CJK Ideograph>) 16329 0x5666 噦 (<CJK Ideograph>) 16330 0x5663 噣 (<CJK Ideograph>) 16331 0x566D 噭 (<CJK Ideograph>) 16332 0x5672 噲 (<CJK Ideograph>) 16333 0x565E 噞 (<CJK Ideograph>) 16334 0x5677 噷 (<CJK Ideograph>) 16335 0x571C 圜 (<CJK Ideograph>) 16336 0x571B 圛 (<CJK Ideograph>) 16337 0x58C8 壈 (<CJK Ideograph>) 16338 0x58BD 墽 (<CJK Ideograph>) 16339 0x58C9 壉 (<CJK Ideograph>) 16340 0x58BF 墿 (<CJK Ideograph>) 16341 0x58BA 墺 (<CJK Ideograph>) 16342 0x58C2 壂 (<CJK Ideograph>) 16343 0x58BC 墼 (<CJK Ideograph>) 16344 0x58C6 壆 (<CJK Ideograph>) 16345 0x5B17 嬗 (<CJK Ideograph>) 16346 0x5B19 嬙 (<CJK Ideograph>) 16347 0x5B1B 嬛 (<CJK Ideograph>) 16348 0x5B21 嬡 (<CJK Ideograph>) 16349 0x5B14 嬔 (<CJK Ideograph>) 16350 0x5B13 嬓 (<CJK Ideograph>) 16351 0x5B10 嬐 (<CJK Ideograph>) 16352 0x5B16 嬖 (<CJK Ideograph>) 16353 0x5B28 嬨 (<CJK Ideograph>) 16354 0x5B1A 嬚 (<CJK Ideograph>) 16355 0x5B20 嬠 (<CJK Ideograph>) 16356 0x5B1E 嬞 (<CJK Ideograph>) 16357 0x5BEF 寯 (<CJK Ideograph>) 16358 0x5DAC 嶬 (<CJK Ideograph>) 16359 0x5DB1 嶱 (<CJK Ideograph>) 16360 0x5DA9 嶩 (<CJK Ideograph>) 16361 0x5DA7 嶧 (<CJK Ideograph>) 16362 0x5DB5 嶵 (<CJK Ideograph>) 16363 0x5DB0 嶰 (<CJK Ideograph>) 16364 0x5DAE 嶮 (<CJK Ideograph>) 16365 0x5DAA 嶪 (<CJK Ideograph>) 16366 0x5DA8 嶨 (<CJK Ideograph>) 16367 0x5DB2 嶲 (<CJK Ideograph>) 16368 0x5DAD 嶭 (<CJK Ideograph>) 16369 0x5DAF 嶯 (<CJK Ideograph>) 16370 0x5DB4 嶴 (<CJK Ideograph>) 16371 0x5E67 幧 (<CJK Ideograph>) 16372 0x5E68 幨 (<CJK Ideograph>) 16373 0x5E66 幦 (<CJK Ideograph>) 16374 0x5E6F 幯 (<CJK Ideograph>) 16375 0x5EE9 廩 (<CJK Ideograph>) 16376 0x5EE7 廧 (<CJK Ideograph>) 16377 0x5EE6 廦 (<CJK Ideograph>) 16378 0x5EE8 廨 (<CJK Ideograph>) 16379 0x5EE5 廥 (<CJK Ideograph>) 16380 0x5F4B 彋 (<CJK Ideograph>) 16381 0x5FBC 徼 (<CJK Ideograph>) 16382 0x619D 憝 (<CJK Ideograph>) 16383 0x61A8 憨 (<CJK Ideograph>) 16384 0x6196 憖 (<CJK Ideograph>) 16385 0x61C5 懅 (<CJK Ideograph>) 16386 0x61B4 憴 (<CJK Ideograph>) 16387 0x61C6 懆 (<CJK Ideograph>) 16388 0x61C1 懁 (<CJK Ideograph>) 16389 0x61CC 懌 (<CJK Ideograph>) 16390 0x61BA 憺 (<CJK Ideograph>) 16391 0x61BF 憿 (<CJK Ideograph>) 16392 0x61B8 憸 (<CJK Ideograph>) 16393 0x618C 憌 (<CJK Ideograph>) 16394 0x64D7 擗 (<CJK Ideograph>) 16395 0x64D6 擖 (<CJK Ideograph>) 16396 0x64D0 擐 (<CJK Ideograph>) 16397 0x64CF 擏 (<CJK Ideograph>) 16398 0x64C9 擉 (<CJK Ideograph>) 16399 0x64BD 撽 (<CJK Ideograph>) 16400 0x6489 撉 (<CJK Ideograph>) 16401 0x64C3 擃 (<CJK Ideograph>) 16402 0x64DB 擛 (<CJK Ideograph>) 16403 0x64F3 擳 (<CJK Ideograph>) 16404 0x64D9 擙 (<CJK Ideograph>) 16405 0x6533 攳 (<CJK Ideograph>) 16406 0x657F 敿 (<CJK Ideograph>) 16407 0x657C 敼 (<CJK Ideograph>) 16408 0x65A2 斢 (<CJK Ideograph>) 16409 0x66C8 曈 (<CJK Ideograph>) 16410 0x66BE 暾 (<CJK Ideograph>) 16411 0x66C0 曀 (<CJK Ideograph>) 16412 0x66CA 曊 (<CJK Ideograph>) 16413 0x66CB 曋 (<CJK Ideograph>) 16414 0x66CF 曏 (<CJK Ideograph>) 16415 0x66BD 暽 (<CJK Ideograph>) 16416 0x66BB 暻 (<CJK Ideograph>) 16417 0x66BA 暺 (<CJK Ideograph>) 16418 0x66CC 曌 (<CJK Ideograph>) 16419 0x6723 朣 (<CJK Ideograph>) 16420 0x6A34 樴 (<CJK Ideograph>) 16421 0x6A66 橦 (<CJK Ideograph>) 16422 0x6A49 橉 (<CJK Ideograph>) 16423 0x6A67 橧 (<CJK Ideograph>) 16424 0x6A32 樲 (<CJK Ideograph>) 16425 0x6A68 橨 (<CJK Ideograph>) 16426 0x6A3E 樾 (<CJK Ideograph>) 16427 0x6A5D 橝 (<CJK Ideograph>) 16428 0x6A6D 橭 (<CJK Ideograph>) 16429 0x6A76 橶 (<CJK Ideograph>) 16430 0x6A5B 橛 (<CJK Ideograph>) 16431 0x6A51 橑 (<CJK Ideograph>) 16432 0x6A28 樨 (<CJK Ideograph>) 16433 0x6A5A 橚 (<CJK Ideograph>) 16434 0x6A3B 樻 (<CJK Ideograph>) 16435 0x6A3F 樿 (<CJK Ideograph>) 16436 0x6A41 橁 (<CJK Ideograph>) 16437 0x6A6A 橪 (<CJK Ideograph>) 16438 0x6A64 橤 (<CJK Ideograph>) 16439 0x6A50 橐 (<CJK Ideograph>) 16440 0x6A4F 橏 (<CJK Ideograph>) 16441 0x6A54 橔 (<CJK Ideograph>) 16442 0x6A6F 橯 (<CJK Ideograph>) 16443 0x6A69 橩 (<CJK Ideograph>) 16444 0x6A60 橠 (<CJK Ideograph>) 16445 0x6A3C 樼 (<CJK Ideograph>) 16446 0x6A5E 橞 (<CJK Ideograph>) 16447 0x6A56 橖 (<CJK Ideograph>) 16448 0x6A55 橕 (<CJK Ideograph>) 16449 0x6A4D 橍 (<CJK Ideograph>) 16450 0x6A4E 橎 (<CJK Ideograph>) 16451 0x6A46 橆 (<CJK Ideograph>) 16452 0x6B55 歕 (<CJK Ideograph>) 16453 0x6B54 歔 (<CJK Ideograph>) 16454 0x6B56 歖 (<CJK Ideograph>) 16455 0x6BA7 殧 (<CJK Ideograph>) 16456 0x6BAA 殪 (<CJK Ideograph>) 16457 0x6BAB 殫 (<CJK Ideograph>) 16458 0x6BC8 毈 (<CJK Ideograph>) 16459 0x6BC7 毇 (<CJK Ideograph>) 16460 0x6C04 氄 (<CJK Ideograph>) 16461 0x6C03 氃 (<CJK Ideograph>) 16462 0x6C06 氆 (<CJK Ideograph>) 16463 0x6FAD 澭 (<CJK Ideograph>) 16464 0x6FCB 濋 (<CJK Ideograph>) 16465 0x6FA3 澣 (<CJK Ideograph>) 16466 0x6FC7 濇 (<CJK Ideograph>) 16467 0x6FBC 澼 (<CJK Ideograph>) 16468 0x6FCE 濎 (<CJK Ideograph>) 16469 0x6FC8 濈 (<CJK Ideograph>) 16470 0x6F5E 潞 (<CJK Ideograph>) 16471 0x6FC4 濄 (<CJK Ideograph>) 16472 0x6FBD 澽 (<CJK Ideograph>) 16473 0x6F9E 澞 (<CJK Ideograph>) 16474 0x6FCA 濊 (<CJK Ideograph>) 16475 0x6FA8 澨 (<CJK Ideograph>) 16476 0x7004 瀄 (<CJK Ideograph>) 16477 0x6FA5 澥 (<CJK Ideograph>) 16478 0x6FAE 澮 (<CJK Ideograph>) 16479 0x6FBA 澺 (<CJK Ideograph>) 16480 0x6FAC 澬 (<CJK Ideograph>) 16481 0x6FAA 澪 (<CJK Ideograph>) 16482 0x6FCF 濏 (<CJK Ideograph>) 16483 0x6FBF 澿 (<CJK Ideograph>) 16484 0x6FB8 澸 (<CJK Ideograph>) 16485 0x6FA2 澢 (<CJK Ideograph>) 16486 0x6FC9 濉 (<CJK Ideograph>) 16487 0x6FAB 澫 (<CJK Ideograph>) 16488 0x6FCD 濍 (<CJK Ideograph>) 16489 0x6FAF 澯 (<CJK Ideograph>) 16490 0x6FB2 澲 (<CJK Ideograph>) 16491 0x6FB0 澰 (<CJK Ideograph>) 16492 0x71C5 燅 (<CJK Ideograph>) 16493 0x71C2 燂 (<CJK Ideograph>) 16494 0x71BF 熿 (<CJK Ideograph>) 16495 0x71B8 熸 (<CJK Ideograph>) 16496 0x71D6 燖 (<CJK Ideograph>) 16497 0x71C0 燀 (<CJK Ideograph>) 16498 0x71C1 燁 (<CJK Ideograph>) 16499 0x71CB 燋 (<CJK Ideograph>) 16500 0x71D4 燔 (<CJK Ideograph>) 16501 0x71CA 燊 (<CJK Ideograph>) 16502 0x71C7 燇 (<CJK Ideograph>) 16503 0x71CF 燏 (<CJK Ideograph>) 16504 0x71BD 熽 (<CJK Ideograph>) 16505 0x71D8 燘 (<CJK Ideograph>) 16506 0x71BC 熼 (<CJK Ideograph>) 16507 0x71C6 燆 (<CJK Ideograph>) 16508 0x71DA 燚 (<CJK Ideograph>) 16509 0x71DB 燛 (<CJK Ideograph>) 16510 0x729D 犝 (<CJK Ideograph>) 16511 0x729E 犞 (<CJK Ideograph>) 16512 0x7369 獩 (<CJK Ideograph>) 16513 0x7366 獦 (<CJK Ideograph>) 16514 0x7367 獧 (<CJK Ideograph>) 16515 0x736C 獬 (<CJK Ideograph>) 16516 0x7365 獥 (<CJK Ideograph>) 16517 0x736B 獫 (<CJK Ideograph>) 16518 0x736A 獪 (<CJK Ideograph>) 16519 0x747F 瑿 (<CJK Ideograph>) 16520 0x749A 璚 (<CJK Ideograph>) 16521 0x74A0 璠 (<CJK Ideograph>) 16522 0x7494 璔 (<CJK Ideograph>) 16523 0x7492 璒 (<CJK Ideograph>) 16524 0x7495 璕 (<CJK Ideograph>) 16525 0x74A1 璡 (<CJK Ideograph>) 16526 0x750B 甋 (<CJK Ideograph>) 16527 0x7580 疀 (<CJK Ideograph>) 16528 0x762F 瘯 (<CJK Ideograph>) 16529 0x762D 瘭 (<CJK Ideograph>) 16530 0x7631 瘱 (<CJK Ideograph>) 16531 0x763D 瘽 (<CJK Ideograph>) 16532 0x7633 瘳 (<CJK Ideograph>) 16533 0x763C 瘼 (<CJK Ideograph>) 16534 0x7635 瘵 (<CJK Ideograph>) 16535 0x7632 瘲 (<CJK Ideograph>) 16536 0x7630 瘰 (<CJK Ideograph>) 16537 0x76BB 皻 (<CJK Ideograph>) 16538 0x76E6 盦 (<CJK Ideograph>) 16539 0x779A 瞚 (<CJK Ideograph>) 16540 0x779D 瞝 (<CJK Ideograph>) 16541 0x77A1 瞡 (<CJK Ideograph>) 16542 0x779C 瞜 (<CJK Ideograph>) 16543 0x779B 瞛 (<CJK Ideograph>) 16544 0x77A2 瞢 (<CJK Ideograph>) 16545 0x77A3 瞣 (<CJK Ideograph>) 16546 0x7795 瞕 (<CJK Ideograph>) 16547 0x7799 瞙 (<CJK Ideograph>) 16548 0x7797 瞗 (<CJK Ideograph>) 16549 0x78DD 磝 (<CJK Ideograph>) 16550 0x78E9 磩 (<CJK Ideograph>) 16551 0x78E5 磥 (<CJK Ideograph>) 16552 0x78EA 磪 (<CJK Ideograph>) 16553 0x78DE 磞 (<CJK Ideograph>) 16554 0x78E3 磣 (<CJK Ideograph>) 16555 0x78DB 磛 (<CJK Ideograph>) 16556 0x78E1 磡 (<CJK Ideograph>) 16557 0x78E2 磢 (<CJK Ideograph>) 16558 0x78ED 磭 (<CJK Ideograph>) 16559 0x78DF 磟 (<CJK Ideograph>) 16560 0x78E0 磠 (<CJK Ideograph>) 16561 0x79A4 禤 (<CJK Ideograph>) 16562 0x7A44 穄 (<CJK Ideograph>) 16563 0x7A48 穈 (<CJK Ideograph>) 16564 0x7A47 穇 (<CJK Ideograph>) 16565 0x7AB6 窶 (<CJK Ideograph>) 16566 0x7AB8 窸 (<CJK Ideograph>) 16567 0x7AB5 窵 (<CJK Ideograph>) 16568 0x7AB1 窱 (<CJK Ideograph>) 16569 0x7AB7 窷 (<CJK Ideograph>) 16570 0x7BDE 篞 (<CJK Ideograph>) 16571 0x7BE3 篣 (<CJK Ideograph>) 16572 0x7BE7 篧 (<CJK Ideograph>) 16573 0x7BDD 篝 (<CJK Ideograph>) 16574 0x7BD5 篕 (<CJK Ideograph>) 16575 0x7BE5 篥 (<CJK Ideograph>) 16576 0x7BDA 篚 (<CJK Ideograph>) 16577 0x7BE8 篨 (<CJK Ideograph>) 16578 0x7BF9 篹 (<CJK Ideograph>) 16579 0x7BD4 篔 (<CJK Ideograph>) 16580 0x7BEA 篪 (<CJK Ideograph>) 16581 0x7BE2 篢 (<CJK Ideograph>) 16582 0x7BDC 篜 (<CJK Ideograph>) 16583 0x7BEB 篫 (<CJK Ideograph>) 16584 0x7BD8 篘 (<CJK Ideograph>) 16585 0x7BDF 篟 (<CJK Ideograph>) 16586 0x7CD2 糒 (<CJK Ideograph>) 16587 0x7CD4 糔 (<CJK Ideograph>) 16588 0x7CD7 糗 (<CJK Ideograph>) 16589 0x7CD0 糐 (<CJK Ideograph>) 16590 0x7CD1 糑 (<CJK Ideograph>) 16591 0x7E12 縒 (<CJK Ideograph>) 16592 0x7E21 縡 (<CJK Ideograph>) 16593 0x7E17 縗 (<CJK Ideograph>) 16594 0x7E0C 縌 (<CJK Ideograph>) 16595 0x7E1F 縟 (<CJK Ideograph>) 16596 0x7E20 縠 (<CJK Ideograph>) 16597 0x7E13 縓 (<CJK Ideograph>) 16598 0x7E0E 縎 (<CJK Ideograph>) 16599 0x7E1C 縜 (<CJK Ideograph>) 16600 0x7E15 縕 (<CJK Ideograph>) 16601 0x7E1A 縚 (<CJK Ideograph>) 16602 0x7E22 縢 (<CJK Ideograph>) 16603 0x7E0B 縋 (<CJK Ideograph>) 16604 0x7E0F 縏 (<CJK Ideograph>) 16605 0x7E16 縖 (<CJK Ideograph>) 16606 0x7E0D 縍 (<CJK Ideograph>) 16607 0x7E14 縔 (<CJK Ideograph>) 16608 0x7E25 縥 (<CJK Ideograph>) 16609 0x7E24 縤 (<CJK Ideograph>) 16610 0x7F43 罃 (<CJK Ideograph>) 16611 0x7F7B 罻 (<CJK Ideograph>) 16612 0x7F7C 罼 (<CJK Ideograph>) 16613 0x7F7A 罺 (<CJK Ideograph>) 16614 0x7FB1 羱 (<CJK Ideograph>) 16615 0x7FEF 翯 (<CJK Ideograph>) 16616 0x802A 耪 (<CJK Ideograph>) 16617 0x8029 耩 (<CJK Ideograph>) 16618 0x806C 聬 (<CJK Ideograph>) 16619 0x81B1 膱 (<CJK Ideograph>) 16620 0x81A6 膦 (<CJK Ideograph>) 16621 0x81AE 膮 (<CJK Ideograph>) 16622 0x81B9 膹 (<CJK Ideograph>) 16623 0x81B5 膵 (<CJK Ideograph>) 16624 0x81AB 膫 (<CJK Ideograph>) 16625 0x81B0 膰 (<CJK Ideograph>) 16626 0x81AC 膬 (<CJK Ideograph>) 16627 0x81B4 膴 (<CJK Ideograph>) 16628 0x81B2 膲 (<CJK Ideograph>) 16629 0x81B7 膷 (<CJK Ideograph>) 16630 0x81A7 膧 (<CJK Ideograph>) 16631 0x81F2 臲 (<CJK Ideograph>) 16632 0x8255 艕 (<CJK Ideograph>) 16633 0x8256 艖 (<CJK Ideograph>) 16634 0x8257 艗 (<CJK Ideograph>) 16635 0x8556 蕖 (<CJK Ideograph>) 16636 0x8545 蕅 (<CJK Ideograph>) 16637 0x856B 蕫 (<CJK Ideograph>) 16638 0x854D 蕍 (<CJK Ideograph>) 16639 0x8553 蕓 (<CJK Ideograph>) 16640 0x8561 蕡 (<CJK Ideograph>) 16641 0x8558 蕘 (<CJK Ideograph>) 16642 0x8540 蕀 (<CJK Ideograph>) 16643 0x8546 蕆 (<CJK Ideograph>) 16644 0x8564 蕤 (<CJK Ideograph>) 16645 0x8541 蕁 (<CJK Ideograph>) 16646 0x8562 蕢 (<CJK Ideograph>) 16647 0x8544 蕄 (<CJK Ideograph>) 16648 0x8551 蕑 (<CJK Ideograph>) 16649 0x8547 蕇 (<CJK Ideograph>) 16650 0x8563 蕣 (<CJK Ideograph>) 16651 0x853E 蔾 (<CJK Ideograph>) 16652 0x855B 蕛 (<CJK Ideograph>) 16653 0x8571 蕱 (<CJK Ideograph>) 16654 0x854E 蕎 (<CJK Ideograph>) 16655 0x856E 蕮 (<CJK Ideograph>) 16656 0x8575 蕵 (<CJK Ideograph>) 16657 0x8555 蕕 (<CJK Ideograph>) 16658 0x8567 蕧 (<CJK Ideograph>) 16659 0x8560 蕠 (<CJK Ideograph>) 16660 0x858C 薌 (<CJK Ideograph>) 16661 0x8566 蕦 (<CJK Ideograph>) 16662 0x855D 蕝 (<CJK Ideograph>) 16663 0x8554 蕔 (<CJK Ideograph>) 16664 0x8565 蕥 (<CJK Ideograph>) 16665 0x856C 蕬 (<CJK Ideograph>) 16666 0x8663 虣 (<CJK Ideograph>) 16667 0x8665 虥 (<CJK Ideograph>) 16668 0x8664 虤 (<CJK Ideograph>) 16669 0x879B 螛 (<CJK Ideograph>) 16670 0x878F 螏 (<CJK Ideograph>) 16671 0x8797 螗 (<CJK Ideograph>) 16672 0x8793 螓 (<CJK Ideograph>) 16673 0x8792 螒 (<CJK Ideograph>) 16674 0x8788 螈 (<CJK Ideograph>) 16675 0x8781 螁 (<CJK Ideograph>) 16676 0x8796 螖 (<CJK Ideograph>) 16677 0x8798 螘 (<CJK Ideograph>) 16678 0x8779 蝹 (<CJK Ideograph>) 16679 0x8787 螇 (<CJK Ideograph>) 16680 0x87A3 螣 (<CJK Ideograph>) 16681 0x8785 螅 (<CJK Ideograph>) 16682 0x8790 螐 (<CJK Ideograph>) 16683 0x8791 螑 (<CJK Ideograph>) 16684 0x879D 螝 (<CJK Ideograph>) 16685 0x8784 螄 (<CJK Ideograph>) 16686 0x8794 螔 (<CJK Ideograph>) 16687 0x879C 螜 (<CJK Ideograph>) 16688 0x879A 螚 (<CJK Ideograph>) 16689 0x8789 螉 (<CJK Ideograph>) 16690 0x891E 褞 (<CJK Ideograph>) 16691 0x8926 褦 (<CJK Ideograph>) 16692 0x8930 褰 (<CJK Ideograph>) 16693 0x892D 褭 (<CJK Ideograph>) 16694 0x892E 褮 (<CJK Ideograph>) 16695 0x8927 褧 (<CJK Ideograph>) 16696 0x8931 褱 (<CJK Ideograph>) 16697 0x8922 褢 (<CJK Ideograph>) 16698 0x8929 褩 (<CJK Ideograph>) 16699 0x8923 褣 (<CJK Ideograph>) 16700 0x892F 褯 (<CJK Ideograph>) 16701 0x892C 褬 (<CJK Ideograph>) 16702 0x891F 褟 (<CJK Ideograph>) 16703 0x89F1 觱 (<CJK Ideograph>) 16704 0x8AE0 諠 (<CJK Ideograph>) 16705 0x8AE2 諢 (<CJK Ideograph>) 16706 0x8AF2 諲 (<CJK Ideograph>) 16707 0x8AF4 諴 (<CJK Ideograph>) 16708 0x8AF5 諵 (<CJK Ideograph>) 16709 0x8ADD 諝 (<CJK Ideograph>) 16710 0x8B14 謔 (<CJK Ideograph>) 16711 0x8AE4 諤 (<CJK Ideograph>) 16712 0x8ADF 諟 (<CJK Ideograph>) 16713 0x8AF0 諰 (<CJK Ideograph>) 16714 0x8AC8 諈 (<CJK Ideograph>) 16715 0x8ADE 諞 (<CJK Ideograph>) 16716 0x8AE1 諡 (<CJK Ideograph>) 16717 0x8AE8 諨 (<CJK Ideograph>) 16718 0x8AFF 諿 (<CJK Ideograph>) 16719 0x8AEF 諯 (<CJK Ideograph>) 16720 0x8AFB 諻 (<CJK Ideograph>) 16721 0x8C91 貑 (<CJK Ideograph>) 16722 0x8C92 貒 (<CJK Ideograph>) 16723 0x8C90 貐 (<CJK Ideograph>) 16724 0x8CF5 賵 (<CJK Ideograph>) 16725 0x8CEE 賮 (<CJK Ideograph>) 16726 0x8CF1 賱 (<CJK Ideograph>) 16727 0x8CF0 賰 (<CJK Ideograph>) 16728 0x8CF3 賳 (<CJK Ideograph>) 16729 0x8D6C 赬 (<CJK Ideograph>) 16730 0x8D6E 赮 (<CJK Ideograph>) 16731 0x8DA5 趥 (<CJK Ideograph>) 16732 0x8DA7 趧 (<CJK Ideograph>) 16733 0x8E33 踳 (<CJK Ideograph>) 16734 0x8E3E 踾 (<CJK Ideograph>) 16735 0x8E38 踸 (<CJK Ideograph>) 16736 0x8E40 蹀 (<CJK Ideograph>) 16737 0x8E45 蹅 (<CJK Ideograph>) 16738 0x8E36 踶 (<CJK Ideograph>) 16739 0x8E3C 踼 (<CJK Ideograph>) 16740 0x8E3D 踽 (<CJK Ideograph>) 16741 0x8E41 蹁 (<CJK Ideograph>) 16742 0x8E30 踰 (<CJK Ideograph>) 16743 0x8E3F 踿 (<CJK Ideograph>) 16744 0x8EBD 躽 (<CJK Ideograph>) 16745 0x8F36 輶 (<CJK Ideograph>) 16746 0x8F2E 輮 (<CJK Ideograph>) 16747 0x8F35 輵 (<CJK Ideograph>) 16748 0x8F32 輲 (<CJK Ideograph>) 16749 0x8F39 輹 (<CJK Ideograph>) 16750 0x8F37 輷 (<CJK Ideograph>) 16751 0x8F34 輴 (<CJK Ideograph>) 16752 0x9076 遶 (<CJK Ideograph>) 16753 0x9079 遹 (<CJK Ideograph>) 16754 0x907B 遻 (<CJK Ideograph>) 16755 0x9086 邆 (<CJK Ideograph>) 16756 0x90FA 郺 (<CJK Ideograph>) 16757 0x9133 鄳 (<CJK Ideograph>) 16758 0x9135 鄵 (<CJK Ideograph>) 16759 0x9136 鄶 (<CJK Ideograph>) 16760 0x9193 醓 (<CJK Ideograph>) 16761 0x9190 醐 (<CJK Ideograph>) 16762 0x9191 醑 (<CJK Ideograph>) 16763 0x918D 醍 (<CJK Ideograph>) 16764 0x918F 醏 (<CJK Ideograph>) 16765 0x9327 錧 (<CJK Ideograph>) 16766 0x931E 錞 (<CJK Ideograph>) 16767 0x9308 錈 (<CJK Ideograph>) 16768 0x931F 錟 (<CJK Ideograph>) 16769 0x9306 錆 (<CJK Ideograph>) 16770 0x930F 錏 (<CJK Ideograph>) 16771 0x937A 鍺 (<CJK Ideograph>) 16772 0x9338 錸 (<CJK Ideograph>) 16773 0x933C 錼 (<CJK Ideograph>) 16774 0x931B 錛 (<CJK Ideograph>) 16775 0x9323 錣 (<CJK Ideograph>) 16776 0x9312 錒 (<CJK Ideograph>) 16777 0x9301 錁 (<CJK Ideograph>) 16778 0x9346 鍆 (<CJK Ideograph>) 16779 0x932D 錭 (<CJK Ideograph>) 16780 0x930E 錎 (<CJK Ideograph>) 16781 0x930D 錍 (<CJK Ideograph>) 16782 0x92CB 鋋 (<CJK Ideograph>) 16783 0x931D 錝 (<CJK Ideograph>) 16784 0x92FA 鋺 (<CJK Ideograph>) 16785 0x9325 錥 (<CJK Ideograph>) 16786 0x9313 錓 (<CJK Ideograph>) 16787 0x92F9 鋹 (<CJK Ideograph>) 16788 0x92F7 鋷 (<CJK Ideograph>) 16789 0x9334 錴 (<CJK Ideograph>) 16790 0x9302 錂 (<CJK Ideograph>) 16791 0x9324 錤 (<CJK Ideograph>) 16792 0x92FF 鋿 (<CJK Ideograph>) 16793 0x9329 錩 (<CJK Ideograph>) 16794 0x9339 錹 (<CJK Ideograph>) 16795 0x9335 錵 (<CJK Ideograph>) 16796 0x932A 錪 (<CJK Ideograph>) 16797 0x9314 錔 (<CJK Ideograph>) 16798 0x930C 錌 (<CJK Ideograph>) 16799 0x930B 錋 (<CJK Ideograph>) 16800 0x92FE 鋾 (<CJK Ideograph>) 16801 0x9309 錉 (<CJK Ideograph>) 16802 0x9300 錀 (<CJK Ideograph>) 16803 0x92FB 鋻 (<CJK Ideograph>) 16804 0x9316 錖 (<CJK Ideograph>) 16805 0x95BC 閼 (<CJK Ideograph>) 16806 0x95CD 闍 (<CJK Ideograph>) 16807 0x95BE 閾 (<CJK Ideograph>) 16808 0x95B9 閹 (<CJK Ideograph>) 16809 0x95BA 閺 (<CJK Ideograph>) 16810 0x95B6 閶 (<CJK Ideograph>) 16811 0x95BF 閿 (<CJK Ideograph>) 16812 0x95B5 閵 (<CJK Ideograph>) 16813 0x95BD 閽 (<CJK Ideograph>) 16814 0x96A9 隩 (<CJK Ideograph>) 16815 0x96D4 雔 (<CJK Ideograph>) 16816 0x970B 霋 (<CJK Ideograph>) 16817 0x9712 霒 (<CJK Ideograph>) 16818 0x9710 霐 (<CJK Ideograph>) 16819 0x9799 鞙 (<CJK Ideograph>) 16820 0x9797 鞗 (<CJK Ideograph>) 16821 0x9794 鞔 (<CJK Ideograph>) 16822 0x97F0 韰 (<CJK Ideograph>) 16823 0x97F8 韸 (<CJK Ideograph>) 16824 0x9835 頵 (<CJK Ideograph>) 16825 0x982F 頯 (<CJK Ideograph>) 16826 0x9832 頲 (<CJK Ideograph>) 16827 0x9924 餤 (<CJK Ideograph>) 16828 0x991F 餟 (<CJK Ideograph>) 16829 0x9927 餧 (<CJK Ideograph>) 16830 0x9929 餩 (<CJK Ideograph>) 16831 0x999E 馞 (<CJK Ideograph>) 16832 0x99EE 駮 (<CJK Ideograph>) 16833 0x99EC 駬 (<CJK Ideograph>) 16834 0x99E5 駥 (<CJK Ideograph>) 16835 0x99E4 駤 (<CJK Ideograph>) 16836 0x99F0 駰 (<CJK Ideograph>) 16837 0x99E3 駣 (<CJK Ideograph>) 16838 0x99EA 駪 (<CJK Ideograph>) 16839 0x99E9 駩 (<CJK Ideograph>) 16840 0x99E7 駧 (<CJK Ideograph>) 16841 0x9AB9 骹 (<CJK Ideograph>) 16842 0x9ABF 骿 (<CJK Ideograph>) 16843 0x9AB4 骴 (<CJK Ideograph>) 16844 0x9ABB 骻 (<CJK Ideograph>) 16845 0x9AF6 髶 (<CJK Ideograph>) 16846 0x9AFA 髺 (<CJK Ideograph>) 16847 0x9AF9 髹 (<CJK Ideograph>) 16848 0x9AF7 髷 (<CJK Ideograph>) 16849 0x9B33 鬳 (<CJK Ideograph>) 16850 0x9B80 鮀 (<CJK Ideograph>) 16851 0x9B85 鮅 (<CJK Ideograph>) 16852 0x9B87 鮇 (<CJK Ideograph>) 16853 0x9B7C 魼 (<CJK Ideograph>) 16854 0x9B7E 魾 (<CJK Ideograph>) 16855 0x9B7B 魻 (<CJK Ideograph>) 16856 0x9B82 鮂 (<CJK Ideograph>) 16857 0x9B93 鮓 (<CJK Ideograph>) 16858 0x9B92 鮒 (<CJK Ideograph>) 16859 0x9B90 鮐 (<CJK Ideograph>) 16860 0x9B7A 魺 (<CJK Ideograph>) 16861 0x9B95 鮕 (<CJK Ideograph>) 16862 0x9B7D 魽 (<CJK Ideograph>) 16863 0x9B88 鮈 (<CJK Ideograph>) 16864 0x9D25 鴥 (<CJK Ideograph>) 16865 0x9D17 鴗 (<CJK Ideograph>) 16866 0x9D20 鴠 (<CJK Ideograph>) 16867 0x9D1E 鴞 (<CJK Ideograph>) 16868 0x9D14 鴔 (<CJK Ideograph>) 16869 0x9D29 鴩 (<CJK Ideograph>) 16870 0x9D1D 鴝 (<CJK Ideograph>) 16871 0x9D18 鴘 (<CJK Ideograph>) 16872 0x9D22 鴢 (<CJK Ideograph>) 16873 0x9D10 鴐 (<CJK Ideograph>) 16874 0x9D19 鴙 (<CJK Ideograph>) 16875 0x9D1F 鴟 (<CJK Ideograph>) 16876 0x9E88 麈 (<CJK Ideograph>) 16877 0x9E86 麆 (<CJK Ideograph>) 16878 0x9E87 麇 (<CJK Ideograph>) 16879 0x9EAE 麮 (<CJK Ideograph>) 16880 0x9EAD 麭 (<CJK Ideograph>) 16881 0x9ED5 黕 (<CJK Ideograph>) 16882 0x9ED6 黖 (<CJK Ideograph>) 16883 0x9EFA 黺 (<CJK Ideograph>) 16884 0x9F12 鼒 (<CJK Ideograph>) 16885 0x9F3D 鼽 (<CJK Ideograph>) 16886 0x5126 儦 (<CJK Ideograph>) 16887 0x5125 儥 (<CJK Ideograph>) 16888 0x5122 儢 (<CJK Ideograph>) 16889 0x5124 儤 (<CJK Ideograph>) 16890 0x5120 儠 (<CJK Ideograph>) 16891 0x5129 儩 (<CJK Ideograph>) 16892 0x52F4 勴 (<CJK Ideograph>) 16893 0x5693 嚓 (<CJK Ideograph>) 16894 0x568C 嚌 (<CJK Ideograph>) 16895 0x568D 嚍 (<CJK Ideograph>) 16896 0x5686 嚆 (<CJK Ideograph>) 16897 0x5684 嚄 (<CJK Ideograph>) 16898 0x5683 嚃 (<CJK Ideograph>) 16899 0x567E 噾 (<CJK Ideograph>) 16900 0x5682 嚂 (<CJK Ideograph>) 16901 0x567F 噿 (<CJK Ideograph>) 16902 0x5681 嚁 (<CJK Ideograph>) 16903 0x58D6 壖 (<CJK Ideograph>) 16904 0x58D4 壔 (<CJK Ideograph>) 16905 0x58CF 壏 (<CJK Ideograph>) 16906 0x58D2 壒 (<CJK Ideograph>) 16907 0x5B2D 嬭 (<CJK Ideograph>) 16908 0x5B25 嬥 (<CJK Ideograph>) 16909 0x5B32 嬲 (<CJK Ideograph>) 16910 0x5B23 嬣 (<CJK Ideograph>) 16911 0x5B2C 嬬 (<CJK Ideograph>) 16912 0x5B27 嬧 (<CJK Ideograph>) 16913 0x5B26 嬦 (<CJK Ideograph>) 16914 0x5B2F 嬯 (<CJK Ideograph>) 16915 0x5B2E 嬮 (<CJK Ideograph>) 16916 0x5B7B 孻 (<CJK Ideograph>) 16917 0x5BF1 寱 (<CJK Ideograph>) 16918 0x5BF2 寲 (<CJK Ideograph>) 16919 0x5DB7 嶷 (<CJK Ideograph>) 16920 0x5E6C 幬 (<CJK Ideograph>) 16921 0x5E6A 幪 (<CJK Ideograph>) 16922 0x5FBE 徾 (<CJK Ideograph>) 16923 0x5FBB 徻 (<CJK Ideograph>) 16924 0x61C3 懃 (<CJK Ideograph>) 16925 0x61B5 憵 (<CJK Ideograph>) 16926 0x61BC 憼 (<CJK Ideograph>) 16927 0x61E7 懧 (<CJK Ideograph>) 16928 0x61E0 懠 (<CJK Ideograph>) 16929 0x61E5 懥 (<CJK Ideograph>) 16930 0x61E4 懤 (<CJK Ideograph>) 16931 0x61E8 懨 (<CJK Ideograph>) 16932 0x61DE 懞 (<CJK Ideograph>) 16933 0x64EF 擯 (<CJK Ideograph>) 16934 0x64E9 擩 (<CJK Ideograph>) 16935 0x64E3 擣 (<CJK Ideograph>) 16936 0x64EB 擫 (<CJK Ideograph>) 16937 0x64E4 擤 (<CJK Ideograph>) 16938 0x64E8 擨 (<CJK Ideograph>) 16939 0x6581 斁 (<CJK Ideograph>) 16940 0x6580 斀 (<CJK Ideograph>) 16941 0x65B6 斶 (<CJK Ideograph>) 16942 0x65DA 旚 (<CJK Ideograph>) 16943 0x66D2 曒 (<CJK Ideograph>) 16944 0x6A8D 檍 (<CJK Ideograph>) 16945 0x6A96 檖 (<CJK Ideograph>) 16946 0x6A81 檁 (<CJK Ideograph>) 16947 0x6AA5 檥 (<CJK Ideograph>) 16948 0x6A89 檉 (<CJK Ideograph>) 16949 0x6A9F 檟 (<CJK Ideograph>) 16950 0x6A9B 檛 (<CJK Ideograph>) 16951 0x6AA1 檡 (<CJK Ideograph>) 16952 0x6A9E 檞 (<CJK Ideograph>) 16953 0x6A87 檇 (<CJK Ideograph>) 16954 0x6A93 檓 (<CJK Ideograph>) 16955 0x6A8E 檎 (<CJK Ideograph>) 16956 0x6A95 檕 (<CJK Ideograph>) 16957 0x6A83 檃 (<CJK Ideograph>) 16958 0x6AA8 檨 (<CJK Ideograph>) 16959 0x6AA4 檤 (<CJK Ideograph>) 16960 0x6A91 檑 (<CJK Ideograph>) 16961 0x6A7F 橿 (<CJK Ideograph>) 16962 0x6AA6 檦 (<CJK Ideograph>) 16963 0x6A9A 檚 (<CJK Ideograph>) 16964 0x6A85 檅 (<CJK Ideograph>) 16965 0x6A8C 檌 (<CJK Ideograph>) 16966 0x6A92 檒 (<CJK Ideograph>) 16967 0x6B5B 歛 (<CJK Ideograph>) 16968 0x6BAD 殭 (<CJK Ideograph>) 16969 0x6C09 氉 (<CJK Ideograph>) 16970 0x6FCC 濌 (<CJK Ideograph>) 16971 0x6FA9 澩 (<CJK Ideograph>) 16972 0x6FF4 濴 (<CJK Ideograph>) 16973 0x6FD4 濔 (<CJK Ideograph>) 16974 0x6FE3 濣 (<CJK Ideograph>) 16975 0x6FDC 濜 (<CJK Ideograph>) 16976 0x6FED 濭 (<CJK Ideograph>) 16977 0x6FE7 濧 (<CJK Ideograph>) 16978 0x6FE6 濦 (<CJK Ideograph>) 16979 0x6FDE 濞 (<CJK Ideograph>) 16980 0x6FF2 濲 (<CJK Ideograph>) 16981 0x6FDD 濝 (<CJK Ideograph>) 16982 0x6FE2 濢 (<CJK Ideograph>) 16983 0x6FE8 濨 (<CJK Ideograph>) 16984 0x71E1 燡 (<CJK Ideograph>) 16985 0x71F1 燱 (<CJK Ideograph>) 16986 0x71E8 燨 (<CJK Ideograph>) 16987 0x71F2 燲 (<CJK Ideograph>) 16988 0x71E4 燤 (<CJK Ideograph>) 16989 0x71F0 燰 (<CJK Ideograph>) 16990 0x71E2 燢 (<CJK Ideograph>) 16991 0x7373 獳 (<CJK Ideograph>) 16992 0x736E 獮 (<CJK Ideograph>) 16993 0x736F 獯 (<CJK Ideograph>) 16994 0x7497 璗 (<CJK Ideograph>) 16995 0x74B2 璲 (<CJK Ideograph>) 16996 0x74AB 璫 (<CJK Ideograph>) 16997 0x7490 璐 (<CJK Ideograph>) 16998 0x74AA 璪 (<CJK Ideograph>) 16999 0x74AD 璭 (<CJK Ideograph>) 17000 0x74B1 璱 (<CJK Ideograph>) 17001 0x74A5 璥 (<CJK Ideograph>) 17002 0x74AF 璯 (<CJK Ideograph>) 17003 0x7510 甐 (<CJK Ideograph>) 17004 0x7511 甑 (<CJK Ideograph>) 17005 0x7512 甒 (<CJK Ideograph>) 17006 0x750F 甏 (<CJK Ideograph>) 17007 0x7584 疄 (<CJK Ideograph>) 17008 0x7643 癃 (<CJK Ideograph>) 17009 0x7648 癈 (<CJK Ideograph>) 17010 0x7649 癉 (<CJK Ideograph>) 17011 0x7647 癇 (<CJK Ideograph>) 17012 0x76A4 皤 (<CJK Ideograph>) 17013 0x76E9 盩 (<CJK Ideograph>) 17014 0x77B5 瞵 (<CJK Ideograph>) 17015 0x77AB 瞫 (<CJK Ideograph>) 17016 0x77B2 瞲 (<CJK Ideograph>) 17017 0x77B7 瞷 (<CJK Ideograph>) 17018 0x77B6 瞶 (<CJK Ideograph>) 17019 0x77B4 瞴 (<CJK Ideograph>) 17020 0x77B1 瞱 (<CJK Ideograph>) 17021 0x77A8 瞨 (<CJK Ideograph>) 17022 0x77F0 矰 (<CJK Ideograph>) 17023 0x78F3 磳 (<CJK Ideograph>) 17024 0x78FD 磽 (<CJK Ideograph>) 17025 0x7902 礂 (<CJK Ideograph>) 17026 0x78FB 磻 (<CJK Ideograph>) 17027 0x78FC 磼 (<CJK Ideograph>) 17028 0x78F2 磲 (<CJK Ideograph>) 17029 0x7905 礅 (<CJK Ideograph>) 17030 0x78F9 磹 (<CJK Ideograph>) 17031 0x78FE 磾 (<CJK Ideograph>) 17032 0x7904 礄 (<CJK Ideograph>) 17033 0x79AB 禫 (<CJK Ideograph>) 17034 0x79A8 禨 (<CJK Ideograph>) 17035 0x7A5C 穜 (<CJK Ideograph>) 17036 0x7A5B 穛 (<CJK Ideograph>) 17037 0x7A56 穖 (<CJK Ideograph>) 17038 0x7A58 穘 (<CJK Ideograph>) 17039 0x7A54 穔 (<CJK Ideograph>) 17040 0x7A5A 穚 (<CJK Ideograph>) 17041 0x7ABE 窾 (<CJK Ideograph>) 17042 0x7AC0 竀 (<CJK Ideograph>) 17043 0x7AC1 竁 (<CJK Ideograph>) 17044 0x7C05 簅 (<CJK Ideograph>) 17045 0x7C0F 簏 (<CJK Ideograph>) 17046 0x7BF2 篲 (<CJK Ideograph>) 17047 0x7C00 簀 (<CJK Ideograph>) 17048 0x7BFF 篿 (<CJK Ideograph>) 17049 0x7BFB 篻 (<CJK Ideograph>) 17050 0x7C0E 簎 (<CJK Ideograph>) 17051 0x7BF4 篴 (<CJK Ideograph>) 17052 0x7C0B 簋 (<CJK Ideograph>) 17053 0x7BF3 篳 (<CJK Ideograph>) 17054 0x7C02 簂 (<CJK Ideograph>) 17055 0x7C09 簉 (<CJK Ideograph>) 17056 0x7C03 簃 (<CJK Ideograph>) 17057 0x7C01 簁 (<CJK Ideograph>) 17058 0x7BF8 篸 (<CJK Ideograph>) 17059 0x7BFD 篽 (<CJK Ideograph>) 17060 0x7C06 簆 (<CJK Ideograph>) 17061 0x7BF0 篰 (<CJK Ideograph>) 17062 0x7BF1 篱 (<CJK Ideograph>) 17063 0x7C10 簐 (<CJK Ideograph>) 17064 0x7C0A 簊 (<CJK Ideograph>) 17065 0x7CE8 糨 (<CJK Ideograph>) 17066 0x7E2D 縭 (<CJK Ideograph>) 17067 0x7E3C 縼 (<CJK Ideograph>) 17068 0x7E42 繂 (<CJK Ideograph>) 17069 0x7E33 縳 (<CJK Ideograph>) 17070 0x9848 顈 (<CJK Ideograph>) 17071 0x7E38 縸 (<CJK Ideograph>) 17072 0x7E2A 縪 (<CJK Ideograph>) 17073 0x7E49 繉 (<CJK Ideograph>) 17074 0x7E40 繀 (<CJK Ideograph>) 17075 0x7E47 繇 (<CJK Ideograph>) 17076 0x7E29 縩 (<CJK Ideograph>) 17077 0x7E4C 繌 (<CJK Ideograph>) 17078 0x7E30 縰 (<CJK Ideograph>) 17079 0x7E3B 縻 (<CJK Ideograph>) 17080 0x7E36 縶 (<CJK Ideograph>) 17081 0x7E44 繄 (<CJK Ideograph>) 17082 0x7E3A 縺 (<CJK Ideograph>) 17083 0x7F45 罅 (<CJK Ideograph>) 17084 0x7F7F 罿 (<CJK Ideograph>) 17085 0x7F7E 罾 (<CJK Ideograph>) 17086 0x7F7D 罽 (<CJK Ideograph>) 17087 0x7FF4 翴 (<CJK Ideograph>) 17088 0x7FF2 翲 (<CJK Ideograph>) 17089 0x802C 耬 (<CJK Ideograph>) 17090 0x81BB 膻 (<CJK Ideograph>) 17091 0x81C4 臄 (<CJK Ideograph>) 17092 0x81CC 臌 (<CJK Ideograph>) 17093 0x81CA 臊 (<CJK Ideograph>) 17094 0x81C5 臅 (<CJK Ideograph>) 17095 0x81C7 臇 (<CJK Ideograph>) 17096 0x81BC 膼 (<CJK Ideograph>) 17097 0x81E9 臩 (<CJK Ideograph>) 17098 0x825B 艛 (<CJK Ideograph>) 17099 0x825A 艚 (<CJK Ideograph>) 17100 0x825C 艜 (<CJK Ideograph>) 17101 0x8583 薃 (<CJK Ideograph>) 17102 0x8580 薀 (<CJK Ideograph>) 17103 0x858F 薏 (<CJK Ideograph>) 17104 0x85A7 薧 (<CJK Ideograph>) 17105 0x8595 薕 (<CJK Ideograph>) 17106 0x85A0 薠 (<CJK Ideograph>) 17107 0x858B 薋 (<CJK Ideograph>) 17108 0x85A3 薣 (<CJK Ideograph>) 17109 0x857B 蕻 (<CJK Ideograph>) 17110 0x85A4 薤 (<CJK Ideograph>) 17111 0x859A 薚 (<CJK Ideograph>) 17112 0x859E 薞 (<CJK Ideograph>) 17113 0x8577 蕷 (<CJK Ideograph>) 17114 0x857C 蕼 (<CJK Ideograph>) 17115 0x8589 薉 (<CJK Ideograph>) 17116 0x85A1 薡 (<CJK Ideograph>) 17117 0x857A 蕺 (<CJK Ideograph>) 17118 0x8578 蕸 (<CJK Ideograph>) 17119 0x8557 蕗 (<CJK Ideograph>) 17120 0x858E 薎 (<CJK Ideograph>) 17121 0x8596 薖 (<CJK Ideograph>) 17122 0x8586 薆 (<CJK Ideograph>) 17123 0x858D 薍 (<CJK Ideograph>) 17124 0x8599 薙 (<CJK Ideograph>) 17125 0x859D 薝 (<CJK Ideograph>) 17126 0x8581 薁 (<CJK Ideograph>) 17127 0x85A2 薢 (<CJK Ideograph>) 17128 0x8582 薂 (<CJK Ideograph>) 17129 0x8588 薈 (<CJK Ideograph>) 17130 0x8585 薅 (<CJK Ideograph>) 17131 0x8579 蕹 (<CJK Ideograph>) 17132 0x8576 蕶 (<CJK Ideograph>) 17133 0x8598 薘 (<CJK Ideograph>) 17134 0x8590 薐 (<CJK Ideograph>) 17135 0x859F 薟 (<CJK Ideograph>) 17136 0x8668 虨 (<CJK Ideograph>) 17137 0x87BE 螾 (<CJK Ideograph>) 17138 0x87AA 螪 (<CJK Ideograph>) 17139 0x87AD 螭 (<CJK Ideograph>) 17140 0x87C5 蟅 (<CJK Ideograph>) 17141 0x87B0 螰 (<CJK Ideograph>) 17142 0x87AC 螬 (<CJK Ideograph>) 17143 0x87B9 螹 (<CJK Ideograph>) 17144 0x87B5 螵 (<CJK Ideograph>) 17145 0x87BC 螼 (<CJK Ideograph>) 17146 0x87AE 螮 (<CJK Ideograph>) 17147 0x87C9 蟉 (<CJK Ideograph>) 17148 0x87C3 蟃 (<CJK Ideograph>) 17149 0x87C2 蟂 (<CJK Ideograph>) 17150 0x87CC 蟌 (<CJK Ideograph>) 17151 0x87B7 螷 (<CJK Ideograph>) 17152 0x87AF 螯 (<CJK Ideograph>) 17153 0x87C4 蟄 (<CJK Ideograph>) 17154 0x87CA 蟊 (<CJK Ideograph>) 17155 0x87B4 螴 (<CJK Ideograph>) 17156 0x87B6 螶 (<CJK Ideograph>) 17157 0x87BF 螿 (<CJK Ideograph>) 17158 0x87B8 螸 (<CJK Ideograph>) 17159 0x87BD 螽 (<CJK Ideograph>) 17160 0x87DE 蟞 (<CJK Ideograph>) 17161 0x87B2 螲 (<CJK Ideograph>) 17162 0x8935 褵 (<CJK Ideograph>) 17163 0x8933 褳 (<CJK Ideograph>) 17164 0x893C 褼 (<CJK Ideograph>) 17165 0x893E 褾 (<CJK Ideograph>) 17166 0x8941 襁 (<CJK Ideograph>) 17167 0x8952 襒 (<CJK Ideograph>) 17168 0x8937 褷 (<CJK Ideograph>) 17169 0x8942 襂 (<CJK Ideograph>) 17170 0x89AD 覭 (<CJK Ideograph>) 17171 0x89AF 覯 (<CJK Ideograph>) 17172 0x89AE 覮 (<CJK Ideograph>) 17173 0x89F2 觲 (<CJK Ideograph>) 17174 0x89F3 觳 (<CJK Ideograph>) 17175 0x8B1E 謞 (<CJK Ideograph>) 17176 0x8B18 謘 (<CJK Ideograph>) 17177 0x8B16 謖 (<CJK Ideograph>) 17178 0x8B11 謑 (<CJK Ideograph>) 17179 0x8B05 謅 (<CJK Ideograph>) 17180 0x8B0B 謋 (<CJK Ideograph>) 17181 0x8B22 謢 (<CJK Ideograph>) 17182 0x8B0F 謏 (<CJK Ideograph>) 17183 0x8B12 謒 (<CJK Ideograph>) 17184 0x8B15 謕 (<CJK Ideograph>) 17185 0x8B07 謇 (<CJK Ideograph>) 17186 0x8B0D 謍 (<CJK Ideograph>) 17187 0x8B08 謈 (<CJK Ideograph>) 17188 0x8B06 謆 (<CJK Ideograph>) 17189 0x8B1C 謜 (<CJK Ideograph>) 17190 0x8B13 謓 (<CJK Ideograph>) 17191 0x8B1A 謚 (<CJK Ideograph>) 17192 0x8C4F 豏 (<CJK Ideograph>) 17193 0x8C70 豰 (<CJK Ideograph>) 17194 0x8C72 豲 (<CJK Ideograph>) 17195 0x8C71 豱 (<CJK Ideograph>) 17196 0x8C6F 豯 (<CJK Ideograph>) 17197 0x8C95 貕 (<CJK Ideograph>) 17198 0x8C94 貔 (<CJK Ideograph>) 17199 0x8CF9 賹 (<CJK Ideograph>) 17200 0x8D6F 赯 (<CJK Ideograph>) 17201 0x8E4E 蹎 (<CJK Ideograph>) 17202 0x8E4D 蹍 (<CJK Ideograph>) 17203 0x8E53 蹓 (<CJK Ideograph>) 17204 0x8E50 蹐 (<CJK Ideograph>) 17205 0x8E4C 蹌 (<CJK Ideograph>) 17206 0x8E47 蹇 (<CJK Ideograph>) 17207 0x8F43 轃 (<CJK Ideograph>) 17208 0x8F40 轀 (<CJK Ideograph>) 17209 0x9085 邅 (<CJK Ideograph>) 17210 0x907E 遾 (<CJK Ideograph>) 17211 0x9138 鄸 (<CJK Ideograph>) 17212 0x919A 醚 (<CJK Ideograph>) 17213 0x91A2 醢 (<CJK Ideograph>) 17214 0x919B 醛 (<CJK Ideograph>) 17215 0x9199 醙 (<CJK Ideograph>) 17216 0x919F 醟 (<CJK Ideograph>) 17217 0x91A1 醡 (<CJK Ideograph>) 17218 0x919D 醝 (<CJK Ideograph>) 17219 0x91A0 醠 (<CJK Ideograph>) 17220 0x93A1 鎡 (<CJK Ideograph>) 17221 0x9383 鎃 (<CJK Ideograph>) 17222 0x93AF 鎯 (<CJK Ideograph>) 17223 0x9364 鍤 (<CJK Ideograph>) 17224 0x9356 鍖 (<CJK Ideograph>) 17225 0x9347 鍇 (<CJK Ideograph>) 17226 0x937C 鍼 (<CJK Ideograph>) 17227 0x9358 鍘 (<CJK Ideograph>) 17228 0x935C 鍜 (<CJK Ideograph>) 17229 0x9376 鍶 (<CJK Ideograph>) 17230 0x9349 鍉 (<CJK Ideograph>) 17231 0x9350 鍐 (<CJK Ideograph>) 17232 0x9351 鍑 (<CJK Ideograph>) 17233 0x9360 鍠 (<CJK Ideograph>) 17234 0x936D 鍭 (<CJK Ideograph>) 17235 0x938F 鎏 (<CJK Ideograph>) 17236 0x934C 鍌 (<CJK Ideograph>) 17237 0x936A 鍪 (<CJK Ideograph>) 17238 0x9379 鍹 (<CJK Ideograph>) 17239 0x9357 鍗 (<CJK Ideograph>) 17240 0x9355 鍕 (<CJK Ideograph>) 17241 0x9352 鍒 (<CJK Ideograph>) 17242 0x934F 鍏 (<CJK Ideograph>) 17243 0x9371 鍱 (<CJK Ideograph>) 17244 0x9377 鍷 (<CJK Ideograph>) 17245 0x937B 鍻 (<CJK Ideograph>) 17246 0x9361 鍡 (<CJK Ideograph>) 17247 0x935E 鍞 (<CJK Ideograph>) 17248 0x9363 鍣 (<CJK Ideograph>) 17249 0x9367 鍧 (<CJK Ideograph>) 17250 0x9380 鎀 (<CJK Ideograph>) 17251 0x934E 鍎 (<CJK Ideograph>) 17252 0x9359 鍙 (<CJK Ideograph>) 17253 0x95C7 闇 (<CJK Ideograph>) 17254 0x95C0 闀 (<CJK Ideograph>) 17255 0x95C9 闉 (<CJK Ideograph>) 17256 0x95C3 闃 (<CJK Ideograph>) 17257 0x95C5 闅 (<CJK Ideograph>) 17258 0x95B7 閷 (<CJK Ideograph>) 17259 0x96AE 隮 (<CJK Ideograph>) 17260 0x96B0 隰 (<CJK Ideograph>) 17261 0x96AC 隬 (<CJK Ideograph>) 17262 0x9720 霠 (<CJK Ideograph>) 17263 0x971F 霟 (<CJK Ideograph>) 17264 0x9718 霘 (<CJK Ideograph>) 17265 0x971D 霝 (<CJK Ideograph>) 17266 0x9719 霙 (<CJK Ideograph>) 17267 0x979A 鞚 (<CJK Ideograph>) 17268 0x97A1 鞡 (<CJK Ideograph>) 17269 0x979C 鞜 (<CJK Ideograph>) 17270 0x979E 鞞 (<CJK Ideograph>) 17271 0x979D 鞝 (<CJK Ideograph>) 17272 0x97D5 韕 (<CJK Ideograph>) 17273 0x97D4 韔 (<CJK Ideograph>) 17274 0x97F1 韱 (<CJK Ideograph>) 17275 0x9841 顁 (<CJK Ideograph>) 17276 0x9844 顄 (<CJK Ideograph>) 17277 0x984A 顊 (<CJK Ideograph>) 17278 0x9849 顉 (<CJK Ideograph>) 17279 0x9845 顅 (<CJK Ideograph>) 17280 0x9843 顃 (<CJK Ideograph>) 17281 0x9925 餥 (<CJK Ideograph>) 17282 0x992B 餫 (<CJK Ideograph>) 17283 0x992C 餬 (<CJK Ideograph>) 17284 0x992A 餪 (<CJK Ideograph>) 17285 0x9933 餳 (<CJK Ideograph>) 17286 0x9932 餲 (<CJK Ideograph>) 17287 0x992F 餯 (<CJK Ideograph>) 17288 0x992D 餭 (<CJK Ideograph>) 17289 0x9931 餱 (<CJK Ideograph>) 17290 0x9930 餰 (<CJK Ideograph>) 17291 0x9998 馘 (<CJK Ideograph>) 17292 0x99A3 馣 (<CJK Ideograph>) 17293 0x99A1 馡 (<CJK Ideograph>) 17294 0x9A02 騂 (<CJK Ideograph>) 17295 0x99FA 駺 (<CJK Ideograph>) 17296 0x99F4 駴 (<CJK Ideograph>) 17297 0x99F7 駷 (<CJK Ideograph>) 17298 0x99F9 駹 (<CJK Ideograph>) 17299 0x99F8 駸 (<CJK Ideograph>) 17300 0x99F6 駶 (<CJK Ideograph>) 17301 0x99FB 駻 (<CJK Ideograph>) 17302 0x99FD 駽 (<CJK Ideograph>) 17303 0x99FE 駾 (<CJK Ideograph>) 17304 0x99FC 駼 (<CJK Ideograph>) 17305 0x9A03 騃 (<CJK Ideograph>) 17306 0x9ABE 骾 (<CJK Ideograph>) 17307 0x9AFE 髾 (<CJK Ideograph>) 17308 0x9AFD 髽 (<CJK Ideograph>) 17309 0x9B01 鬁 (<CJK Ideograph>) 17310 0x9AFC 髼 (<CJK Ideograph>) 17311 0x9B48 魈 (<CJK Ideograph>) 17312 0x9B9A 鮚 (<CJK Ideograph>) 17313 0x9BA8 鮨 (<CJK Ideograph>) 17314 0x9B9E 鮞 (<CJK Ideograph>) 17315 0x9B9B 鮛 (<CJK Ideograph>) 17316 0x9BA6 鮦 (<CJK Ideograph>) 17317 0x9BA1 鮡 (<CJK Ideograph>) 17318 0x9BA5 鮥 (<CJK Ideograph>) 17319 0x9BA4 鮤 (<CJK Ideograph>) 17320 0x9B86 鮆 (<CJK Ideograph>) 17321 0x9BA2 鮢 (<CJK Ideograph>) 17322 0x9BA0 鮠 (<CJK Ideograph>) 17323 0x9BAF 鮯 (<CJK Ideograph>) 17324 0x9D33 鴳 (<CJK Ideograph>) 17325 0x9D41 鵁 (<CJK Ideograph>) 17326 0x9D67 鵧 (<CJK Ideograph>) 17327 0x9D36 鴶 (<CJK Ideograph>) 17328 0x9D2E 鴮 (<CJK Ideograph>) 17329 0x9D2F 鴯 (<CJK Ideograph>) 17330 0x9D31 鴱 (<CJK Ideograph>) 17331 0x9D38 鴸 (<CJK Ideograph>) 17332 0x9D30 鴰 (<CJK Ideograph>) 17333 0x9D45 鵅 (<CJK Ideograph>) 17334 0x9D42 鵂 (<CJK Ideograph>) 17335 0x9D43 鵃 (<CJK Ideograph>) 17336 0x9D3E 鴾 (<CJK Ideograph>) 17337 0x9D37 鴷 (<CJK Ideograph>) 17338 0x9D40 鵀 (<CJK Ideograph>) 17339 0x9D3D 鴽 (<CJK Ideograph>) 17340 0x7FF5 翵 (<CJK Ideograph>) 17341 0x9D2D 鴭 (<CJK Ideograph>) 17342 0x9E8A 麊 (<CJK Ideograph>) 17343 0x9E89 麉 (<CJK Ideograph>) 17344 0x9E8D 麍 (<CJK Ideograph>) 17345 0x9EB0 麰 (<CJK Ideograph>) 17346 0x9EC8 黈 (<CJK Ideograph>) 17347 0x9EDA 黚 (<CJK Ideograph>) 17348 0x9EFB 黻 (<CJK Ideograph>) 17349 0x9EFF 黿 (<CJK Ideograph>) 17350 0x9F24 鼤 (<CJK Ideograph>) 17351 0x9F23 鼣 (<CJK Ideograph>) 17352 0x9F22 鼢 (<CJK Ideograph>) 17353 0x9F54 齔 (<CJK Ideograph>) 17354 0x9FA0 龠 (<CJK Ideograph>) 17355 0x5131 儱 (<CJK Ideograph>) 17356 0x512D 儭 (<CJK Ideograph>) 17357 0x512E 儮 (<CJK Ideograph>) 17358 0x5698 嚘 (<CJK Ideograph>) 17359 0x569C 嚜 (<CJK Ideograph>) 17360 0x5697 嚗 (<CJK Ideograph>) 17361 0x569A 嚚 (<CJK Ideograph>) 17362 0x569D 嚝 (<CJK Ideograph>) 17363 0x5699 嚙 (<CJK Ideograph>) 17364 0x5970 奰 (<CJK Ideograph>) 17365 0x5B3C 嬼 (<CJK Ideograph>) 17366 0x5C69 屩 (<CJK Ideograph>) 17367 0x5C6A 屪 (<CJK Ideograph>) 17368 0x5DC0 巀 (<CJK Ideograph>) 17369 0x5E6D 幭 (<CJK Ideograph>) 17370 0x5E6E 幮 (<CJK Ideograph>) 17371 0x61D8 懘 (<CJK Ideograph>) 17372 0x61DF 懟 (<CJK Ideograph>) 17373 0x61ED 懭 (<CJK Ideograph>) 17374 0x61EE 懮 (<CJK Ideograph>) 17375 0x61F1 懱 (<CJK Ideograph>) 17376 0x61EA 懪 (<CJK Ideograph>) 17377 0x61F0 懰 (<CJK Ideograph>) 17378 0x61EB 懫 (<CJK Ideograph>) 17379 0x61D6 懖 (<CJK Ideograph>) 17380 0x61E9 懩 (<CJK Ideograph>) 17381 0x64FF 擿 (<CJK Ideograph>) 17382 0x6504 攄 (<CJK Ideograph>) 17383 0x64FD 擽 (<CJK Ideograph>) 17384 0x64F8 擸 (<CJK Ideograph>) 17385 0x6501 攁 (<CJK Ideograph>) 17386 0x6503 攃 (<CJK Ideograph>) 17387 0x64FC 擼 (<CJK Ideograph>) 17388 0x6594 斔 (<CJK Ideograph>) 17389 0x65DB 旛 (<CJK Ideograph>) 17390 0x66DA 曚 (<CJK Ideograph>) 17391 0x66DB 曛 (<CJK Ideograph>) 17392 0x66D8 曘 (<CJK Ideograph>) 17393 0x6AC5 櫅 (<CJK Ideograph>) 17394 0x6AB9 檹 (<CJK Ideograph>) 17395 0x6ABD 檽 (<CJK Ideograph>) 17396 0x6AE1 櫡 (<CJK Ideograph>) 17397 0x6AC6 櫆 (<CJK Ideograph>) 17398 0x6ABA 檺 (<CJK Ideograph>) 17399 0x6AB6 檶 (<CJK Ideograph>) 17400 0x6AB7 檷 (<CJK Ideograph>) 17401 0x6AC7 櫇 (<CJK Ideograph>) 17402 0x6AB4 檴 (<CJK Ideograph>) 17403 0x6AAD 檭 (<CJK Ideograph>) 17404 0x6B5E 歞 (<CJK Ideograph>) 17405 0x6BC9 毉 (<CJK Ideograph>) 17406 0x6C0B 氋 (<CJK Ideograph>) 17407 0x7007 瀇 (<CJK Ideograph>) 17408 0x700C 瀌 (<CJK Ideograph>) 17409 0x700D 瀍 (<CJK Ideograph>) 17410 0x7001 瀁 (<CJK Ideograph>) 17411 0x7005 瀅 (<CJK Ideograph>) 17412 0x7014 瀔 (<CJK Ideograph>) 17413 0x700E 瀎 (<CJK Ideograph>) 17414 0x6FFF 濿 (<CJK Ideograph>) 17415 0x7000 瀀 (<CJK Ideograph>) 17416 0x6FFB 濻 (<CJK Ideograph>) 17417 0x7026 瀦 (<CJK Ideograph>) 17418 0x6FFC 濼 (<CJK Ideograph>) 17419 0x6FF7 濷 (<CJK Ideograph>) 17420 0x700A 瀊 (<CJK Ideograph>) 17421 0x7201 爁 (<CJK Ideograph>) 17422 0x71FF 燿 (<CJK Ideograph>) 17423 0x71F9 燹 (<CJK Ideograph>) 17424 0x7203 爃 (<CJK Ideograph>) 17425 0x71FD 燽 (<CJK Ideograph>) 17426 0x7376 獶 (<CJK Ideograph>) 17427 0x74B8 璸 (<CJK Ideograph>) 17428 0x74C0 瓀 (<CJK Ideograph>) 17429 0x74B5 璵 (<CJK Ideograph>) 17430 0x74C1 瓁 (<CJK Ideograph>) 17431 0x74BE 璾 (<CJK Ideograph>) 17432 0x74B6 璶 (<CJK Ideograph>) 17433 0x74BB 璻 (<CJK Ideograph>) 17434 0x74C2 瓂 (<CJK Ideograph>) 17435 0x7514 甔 (<CJK Ideograph>) 17436 0x7513 甓 (<CJK Ideograph>) 17437 0x765C 癜 (<CJK Ideograph>) 17438 0x7664 癤 (<CJK Ideograph>) 17439 0x7659 癙 (<CJK Ideograph>) 17440 0x7650 癐 (<CJK Ideograph>) 17441 0x7653 癓 (<CJK Ideograph>) 17442 0x7657 癗 (<CJK Ideograph>) 17443 0x765A 癚 (<CJK Ideograph>) 17444 0x76A6 皦 (<CJK Ideograph>) 17445 0x76BD 皽 (<CJK Ideograph>) 17446 0x76EC 盬 (<CJK Ideograph>) 17447 0x77C2 矂 (<CJK Ideograph>) 17448 0x77BA 瞺 (<CJK Ideograph>) 17449 0x78FF 磿 (<CJK Ideograph>) 17450 0x790C 礌 (<CJK Ideograph>) 17451 0x7913 礓 (<CJK Ideograph>) 17452 0x7914 礔 (<CJK Ideograph>) 17453 0x7909 礉 (<CJK Ideograph>) 17454 0x7910 礐 (<CJK Ideograph>) 17455 0x7912 礒 (<CJK Ideograph>) 17456 0x7911 礑 (<CJK Ideograph>) 17457 0x79AD 禭 (<CJK Ideograph>) 17458 0x79AC 禬 (<CJK Ideograph>) 17459 0x7A5F 穟 (<CJK Ideograph>) 17460 0x7C1C 簜 (<CJK Ideograph>) 17461 0x7C29 簩 (<CJK Ideograph>) 17462 0x7C19 簙 (<CJK Ideograph>) 17463 0x7C20 簠 (<CJK Ideograph>) 17464 0x7C1F 簟 (<CJK Ideograph>) 17465 0x7C2D 簭 (<CJK Ideograph>) 17466 0x7C1D 簝 (<CJK Ideograph>) 17467 0x7C26 簦 (<CJK Ideograph>) 17468 0x7C28 簨 (<CJK Ideograph>) 17469 0x7C22 簢 (<CJK Ideograph>) 17470 0x7C25 簥 (<CJK Ideograph>) 17471 0x7C30 簰 (<CJK Ideograph>) 17472 0x7E5C 繜 (<CJK Ideograph>) 17473 0x7E50 繐 (<CJK Ideograph>) 17474 0x7E56 繖 (<CJK Ideograph>) 17475 0x7E63 繣 (<CJK Ideograph>) 17476 0x7E58 繘 (<CJK Ideograph>) 17477 0x7E62 繢 (<CJK Ideograph>) 17478 0x7E5F 繟 (<CJK Ideograph>) 17479 0x7E51 繑 (<CJK Ideograph>) 17480 0x7E60 繠 (<CJK Ideograph>) 17481 0x7E57 繗 (<CJK Ideograph>) 17482 0x7E53 繓 (<CJK Ideograph>) 17483 0x7FB5 羵 (<CJK Ideograph>) 17484 0x7FB3 羳 (<CJK Ideograph>) 17485 0x7FF7 翷 (<CJK Ideograph>) 17486 0x7FF8 翸 (<CJK Ideograph>) 17487 0x8075 聵 (<CJK Ideograph>) 17488 0x81D1 臑 (<CJK Ideograph>) 17489 0x81D2 臒 (<CJK Ideograph>) 17490 0x81D0 臐 (<CJK Ideograph>) 17491 0x825F 艟 (<CJK Ideograph>) 17492 0x825E 艞 (<CJK Ideograph>) 17493 0x85B4 薴 (<CJK Ideograph>) 17494 0x85C6 藆 (<CJK Ideograph>) 17495 0x85C0 藀 (<CJK Ideograph>) 17496 0x85C3 藃 (<CJK Ideograph>) 17497 0x85C2 藂 (<CJK Ideograph>) 17498 0x85B3 薳 (<CJK Ideograph>) 17499 0x85B5 薵 (<CJK Ideograph>) 17500 0x85BD 薽 (<CJK Ideograph>) 17501 0x85C7 藇 (<CJK Ideograph>) 17502 0x85C4 藄 (<CJK Ideograph>) 17503 0x85BF 薿 (<CJK Ideograph>) 17504 0x85CB 藋 (<CJK Ideograph>) 17505 0x85CE 藎 (<CJK Ideograph>) 17506 0x85C8 藈 (<CJK Ideograph>) 17507 0x85C5 藅 (<CJK Ideograph>) 17508 0x85B1 薱 (<CJK Ideograph>) 17509 0x85B6 薶 (<CJK Ideograph>) 17510 0x85D2 藒 (<CJK Ideograph>) 17511 0x8624 蘤 (<CJK Ideograph>) 17512 0x85B8 薸 (<CJK Ideograph>) 17513 0x85B7 薷 (<CJK Ideograph>) 17514 0x85BE 薾 (<CJK Ideograph>) 17515 0x8669 虩 (<CJK Ideograph>) 17516 0x87E7 蟧 (<CJK Ideograph>) 17517 0x87E6 蟦 (<CJK Ideograph>) 17518 0x87E2 蟢 (<CJK Ideograph>) 17519 0x87DB 蟛 (<CJK Ideograph>) 17520 0x87EB 蟫 (<CJK Ideograph>) 17521 0x87EA 蟪 (<CJK Ideograph>) 17522 0x87E5 蟥 (<CJK Ideograph>) 17523 0x87DF 蟟 (<CJK Ideograph>) 17524 0x87F3 蟳 (<CJK Ideograph>) 17525 0x87E4 蟤 (<CJK Ideograph>) 17526 0x87D4 蟔 (<CJK Ideograph>) 17527 0x87DC 蟜 (<CJK Ideograph>) 17528 0x87D3 蟓 (<CJK Ideograph>) 17529 0x87ED 蟭 (<CJK Ideograph>) 17530 0x87D8 蟘 (<CJK Ideograph>) 17531 0x87E3 蟣 (<CJK Ideograph>) 17532 0x87A4 螤 (<CJK Ideograph>) 17533 0x87D7 蟗 (<CJK Ideograph>) 17534 0x87D9 蟙 (<CJK Ideograph>) 17535 0x8801 蠁 (<CJK Ideograph>) 17536 0x87F4 蟴 (<CJK Ideograph>) 17537 0x87E8 蟨 (<CJK Ideograph>) 17538 0x87DD 蟝 (<CJK Ideograph>) 17539 0x8953 襓 (<CJK Ideograph>) 17540 0x894B 襋 (<CJK Ideograph>) 17541 0x894F 襏 (<CJK Ideograph>) 17542 0x894C 襌 (<CJK Ideograph>) 17543 0x8946 襆 (<CJK Ideograph>) 17544 0x8950 襐 (<CJK Ideograph>) 17545 0x8951 襑 (<CJK Ideograph>) 17546 0x8949 襉 (<CJK Ideograph>) 17547 0x8B2A 謪 (<CJK Ideograph>) 17548 0x8B27 謧 (<CJK Ideograph>) 17549 0x8B23 謣 (<CJK Ideograph>) 17550 0x8B33 謳 (<CJK Ideograph>) 17551 0x8B30 謰 (<CJK Ideograph>) 17552 0x8B35 謵 (<CJK Ideograph>) 17553 0x8B47 譇 (<CJK Ideograph>) 17554 0x8B2F 謯 (<CJK Ideograph>) 17555 0x8B3C 謼 (<CJK Ideograph>) 17556 0x8B3E 謾 (<CJK Ideograph>) 17557 0x8B31 謱 (<CJK Ideograph>) 17558 0x8B25 謥 (<CJK Ideograph>) 17559 0x8B37 謷 (<CJK Ideograph>) 17560 0x8B26 謦 (<CJK Ideograph>) 17561 0x8B36 謶 (<CJK Ideograph>) 17562 0x8B2E 謮 (<CJK Ideograph>) 17563 0x8B24 謤 (<CJK Ideograph>) 17564 0x8B3B 謻 (<CJK Ideograph>) 17565 0x8B3D 謽 (<CJK Ideograph>) 17566 0x8B3A 謺 (<CJK Ideograph>) 17567 0x8C42 豂 (<CJK Ideograph>) 17568 0x8C75 豵 (<CJK Ideograph>) 17569 0x8C99 貙 (<CJK Ideograph>) 17570 0x8C98 貘 (<CJK Ideograph>) 17571 0x8C97 貗 (<CJK Ideograph>) 17572 0x8CFE 賾 (<CJK Ideograph>) 17573 0x8D04 贄 (<CJK Ideograph>) 17574 0x8D02 贂 (<CJK Ideograph>) 17575 0x8D00 贀 (<CJK Ideograph>) 17576 0x8E5C 蹜 (<CJK Ideograph>) 17577 0x8E62 蹢 (<CJK Ideograph>) 17578 0x8E60 蹠 (<CJK Ideograph>) 17579 0x8E57 蹗 (<CJK Ideograph>) 17580 0x8E56 蹖 (<CJK Ideograph>) 17581 0x8E5E 蹞 (<CJK Ideograph>) 17582 0x8E65 蹥 (<CJK Ideograph>) 17583 0x8E67 蹧 (<CJK Ideograph>) 17584 0x8E5B 蹛 (<CJK Ideograph>) 17585 0x8E5A 蹚 (<CJK Ideograph>) 17586 0x8E61 蹡 (<CJK Ideograph>) 17587 0x8E5D 蹝 (<CJK Ideograph>) 17588 0x8E69 蹩 (<CJK Ideograph>) 17589 0x8E54 蹔 (<CJK Ideograph>) 17590 0x8F46 轆 (<CJK Ideograph>) 17591 0x8F47 轇 (<CJK Ideograph>) 17592 0x8F48 轈 (<CJK Ideograph>) 17593 0x8F4B 轋 (<CJK Ideograph>) 17594 0x9128 鄨 (<CJK Ideograph>) 17595 0x913A 鄺 (<CJK Ideograph>) 17596 0x913B 鄻 (<CJK Ideograph>) 17597 0x913E 鄾 (<CJK Ideograph>) 17598 0x91A8 醨 (<CJK Ideograph>) 17599 0x91A5 醥 (<CJK Ideograph>) 17600 0x91A7 醧 (<CJK Ideograph>) 17601 0x91AF 醯 (<CJK Ideograph>) 17602 0x91AA 醪 (<CJK Ideograph>) 17603 0x93B5 鎵 (<CJK Ideograph>) 17604 0x938C 鎌 (<CJK Ideograph>) 17605 0x9392 鎒 (<CJK Ideograph>) 17606 0x93B7 鎷 (<CJK Ideograph>) 17607 0x939B 鎛 (<CJK Ideograph>) 17608 0x939D 鎝 (<CJK Ideograph>) 17609 0x9389 鎉 (<CJK Ideograph>) 17610 0x93A7 鎧 (<CJK Ideograph>) 17611 0x938E 鎎 (<CJK Ideograph>) 17612 0x93AA 鎪 (<CJK Ideograph>) 17613 0x939E 鎞 (<CJK Ideograph>) 17614 0x93A6 鎦 (<CJK Ideograph>) 17615 0x9395 鎕 (<CJK Ideograph>) 17616 0x9388 鎈 (<CJK Ideograph>) 17617 0x9399 鎙 (<CJK Ideograph>) 17618 0x939F 鎟 (<CJK Ideograph>) 17619 0x938D 鎍 (<CJK Ideograph>) 17620 0x93B1 鎱 (<CJK Ideograph>) 17621 0x9391 鎑 (<CJK Ideograph>) 17622 0x93B2 鎲 (<CJK Ideograph>) 17623 0x93A4 鎤 (<CJK Ideograph>) 17624 0x93A8 鎨 (<CJK Ideograph>) 17625 0x93B4 鎴 (<CJK Ideograph>) 17626 0x93A3 鎣 (<CJK Ideograph>) 17627 0x93A5 鎥 (<CJK Ideograph>) 17628 0x95D2 闒 (<CJK Ideograph>) 17629 0x95D3 闓 (<CJK Ideograph>) 17630 0x95D1 闑 (<CJK Ideograph>) 17631 0x96B3 隳 (<CJK Ideograph>) 17632 0x96D7 雗 (<CJK Ideograph>) 17633 0x96DA 雚 (<CJK Ideograph>) 17634 0x5DC2 巂 (<CJK Ideograph>) 17635 0x96DF 雟 (<CJK Ideograph>) 17636 0x96D8 雘 (<CJK Ideograph>) 17637 0x96DD 雝 (<CJK Ideograph>) 17638 0x9723 霣 (<CJK Ideograph>) 17639 0x9722 霢 (<CJK Ideograph>) 17640 0x9725 霥 (<CJK Ideograph>) 17641 0x97AC 鞬 (<CJK Ideograph>) 17642 0x97AE 鞮 (<CJK Ideograph>) 17643 0x97A8 鞨 (<CJK Ideograph>) 17644 0x97AB 鞫 (<CJK Ideograph>) 17645 0x97A4 鞤 (<CJK Ideograph>) 17646 0x97AA 鞪 (<CJK Ideograph>) 17647 0x97A2 鞢 (<CJK Ideograph>) 17648 0x97A5 鞥 (<CJK Ideograph>) 17649 0x97D7 韗 (<CJK Ideograph>) 17650 0x97D9 韙 (<CJK Ideograph>) 17651 0x97D6 韖 (<CJK Ideograph>) 17652 0x97D8 韘 (<CJK Ideograph>) 17653 0x97FA 韺 (<CJK Ideograph>) 17654 0x9850 顐 (<CJK Ideograph>) 17655 0x9851 顑 (<CJK Ideograph>) 17656 0x9852 顒 (<CJK Ideograph>) 17657 0x98B8 颸 (<CJK Ideograph>) 17658 0x9941 饁 (<CJK Ideograph>) 17659 0x993C 餼 (<CJK Ideograph>) 17660 0x993A 餺 (<CJK Ideograph>) 17661 0x9A0F 騏 (<CJK Ideograph>) 17662 0x9A0B 騋 (<CJK Ideograph>) 17663 0x9A09 騉 (<CJK Ideograph>) 17664 0x9A0D 騍 (<CJK Ideograph>) 17665 0x9A04 騄 (<CJK Ideograph>) 17666 0x9A11 騑 (<CJK Ideograph>) 17667 0x9A0A 騊 (<CJK Ideograph>) 17668 0x9A05 騅 (<CJK Ideograph>) 17669 0x9A07 騇 (<CJK Ideograph>) 17670 0x9A06 騆 (<CJK Ideograph>) 17671 0x9AC0 髀 (<CJK Ideograph>) 17672 0x9ADC 髜 (<CJK Ideograph>) 17673 0x9B08 鬈 (<CJK Ideograph>) 17674 0x9B04 鬄 (<CJK Ideograph>) 17675 0x9B05 鬅 (<CJK Ideograph>) 17676 0x9B29 鬩 (<CJK Ideograph>) 17677 0x9B35 鬵 (<CJK Ideograph>) 17678 0x9B4A 魊 (<CJK Ideograph>) 17679 0x9B4C 魌 (<CJK Ideograph>) 17680 0x9B4B 魋 (<CJK Ideograph>) 17681 0x9BC7 鯇 (<CJK Ideograph>) 17682 0x9BC6 鯆 (<CJK Ideograph>) 17683 0x9BC3 鯃 (<CJK Ideograph>) 17684 0x9BBF 鮿 (<CJK Ideograph>) 17685 0x9BC1 鯁 (<CJK Ideograph>) 17686 0x9BB5 鮵 (<CJK Ideograph>) 17687 0x9BB8 鮸 (<CJK Ideograph>) 17688 0x9BD3 鯓 (<CJK Ideograph>) 17689 0x9BB6 鮶 (<CJK Ideograph>) 17690 0x9BC4 鯄 (<CJK Ideograph>) 17691 0x9BB9 鮹 (<CJK Ideograph>) 17692 0x9BBD 鮽 (<CJK Ideograph>) 17693 0x9D5C 鵜 (<CJK Ideograph>) 17694 0x9D53 鵓 (<CJK Ideograph>) 17695 0x9D4F 鵏 (<CJK Ideograph>) 17696 0x9D4A 鵊 (<CJK Ideograph>) 17697 0x9D5B 鵛 (<CJK Ideograph>) 17698 0x9D4B 鵋 (<CJK Ideograph>) 17699 0x9D59 鵙 (<CJK Ideograph>) 17700 0x9D56 鵖 (<CJK Ideograph>) 17701 0x9D4C 鵌 (<CJK Ideograph>) 17702 0x9D57 鵗 (<CJK Ideograph>) 17703 0x9D52 鵒 (<CJK Ideograph>) 17704 0x9D54 鵔 (<CJK Ideograph>) 17705 0x9D5F 鵟 (<CJK Ideograph>) 17706 0x9D58 鵘 (<CJK Ideograph>) 17707 0x9D5A 鵚 (<CJK Ideograph>) 17708 0x9E8E 麎 (<CJK Ideograph>) 17709 0x9E8C 麌 (<CJK Ideograph>) 17710 0x9EDF 黟 (<CJK Ideograph>) 17711 0x9F01 鼁 (<CJK Ideograph>) 17712 0x9F00 鼀 (<CJK Ideograph>) 17713 0x9F16 鼖 (<CJK Ideograph>) 17714 0x9F25 鼥 (<CJK Ideograph>) 17715 0x9F2B 鼫 (<CJK Ideograph>) 17716 0x9F2A 鼪 (<CJK Ideograph>) 17717 0x9F29 鼩 (<CJK Ideograph>) 17718 0x9F28 鼨 (<CJK Ideograph>) 17719 0x9F4C 齌 (<CJK Ideograph>) 17720 0x9F55 齕 (<CJK Ideograph>) 17721 0x5134 儴 (<CJK Ideograph>) 17722 0x5135 儵 (<CJK Ideograph>) 17723 0x5296 劖 (<CJK Ideograph>) 17724 0x52F7 勷 (<CJK Ideograph>) 17725 0x53B4 厴 (<CJK Ideograph>) 17726 0x56AB 嚫 (<CJK Ideograph>) 17727 0x56AD 嚭 (<CJK Ideograph>) 17728 0x56A6 嚦 (<CJK Ideograph>) 17729 0x56A7 嚧 (<CJK Ideograph>) 17730 0x56AA 嚪 (<CJK Ideograph>) 17731 0x56AC 嚬 (<CJK Ideograph>) 17732 0x58DA 壚 (<CJK Ideograph>) 17733 0x58DD 壝 (<CJK Ideograph>) 17734 0x58DB 壛 (<CJK Ideograph>) 17735 0x5912 夒 (<CJK Ideograph>) 17736 0x5B3D 嬽 (<CJK Ideograph>) 17737 0x5B3E 嬾 (<CJK Ideograph>) 17738 0x5B3F 嬿 (<CJK Ideograph>) 17739 0x5DC3 巃 (<CJK Ideograph>) 17740 0x5E70 幰 (<CJK Ideograph>) 17741 0x5FBF 徿 (<CJK Ideograph>) 17742 0x61FB 懻 (<CJK Ideograph>) 17743 0x6507 攇 (<CJK Ideograph>) 17744 0x6510 攐 (<CJK Ideograph>) 17745 0x650D 攍 (<CJK Ideograph>) 17746 0x6509 攉 (<CJK Ideograph>) 17747 0x650C 攌 (<CJK Ideograph>) 17748 0x650E 攎 (<CJK Ideograph>) 17749 0x6584 斄 (<CJK Ideograph>) 17750 0x65DE 旞 (<CJK Ideograph>) 17751 0x65DD 旝 (<CJK Ideograph>) 17752 0x66DE 曞 (<CJK Ideograph>) 17753 0x6AE7 櫧 (<CJK Ideograph>) 17754 0x6AE0 櫠 (<CJK Ideograph>) 17755 0x6ACC 櫌 (<CJK Ideograph>) 17756 0x6AD1 櫑 (<CJK Ideograph>) 17757 0x6AD9 櫙 (<CJK Ideograph>) 17758 0x6ACB 櫋 (<CJK Ideograph>) 17759 0x6ADF 櫟 (<CJK Ideograph>) 17760 0x6ADC 櫜 (<CJK Ideograph>) 17761 0x6AD0 櫐 (<CJK Ideograph>) 17762 0x6AEB 櫫 (<CJK Ideograph>) 17763 0x6ACF 櫏 (<CJK Ideograph>) 17764 0x6ACD 櫍 (<CJK Ideograph>) 17765 0x6ADE 櫞 (<CJK Ideograph>) 17766 0x6B60 歠 (<CJK Ideograph>) 17767 0x6BB0 殰 (<CJK Ideograph>) 17768 0x6C0C 氌 (<CJK Ideograph>) 17769 0x7019 瀙 (<CJK Ideograph>) 17770 0x7027 瀧 (<CJK Ideograph>) 17771 0x7020 瀠 (<CJK Ideograph>) 17772 0x7016 瀖 (<CJK Ideograph>) 17773 0x702B 瀫 (<CJK Ideograph>) 17774 0x7021 瀡 (<CJK Ideograph>) 17775 0x7022 瀢 (<CJK Ideograph>) 17776 0x7023 瀣 (<CJK Ideograph>) 17777 0x7029 瀩 (<CJK Ideograph>) 17778 0x7017 瀗 (<CJK Ideograph>) 17779 0x7024 瀤 (<CJK Ideograph>) 17780 0x701C 瀜 (<CJK Ideograph>) 17781 0x702A 瀪 (<CJK Ideograph>) 17782 0x720C 爌 (<CJK Ideograph>) 17783 0x720A 爊 (<CJK Ideograph>) 17784 0x7207 爇 (<CJK Ideograph>) 17785 0x7202 爂 (<CJK Ideograph>) 17786 0x7205 爅 (<CJK Ideograph>) 17787 0x72A5 犥 (<CJK Ideograph>) 17788 0x72A6 犦 (<CJK Ideograph>) 17789 0x72A4 犤 (<CJK Ideograph>) 17790 0x72A3 犣 (<CJK Ideograph>) 17791 0x72A1 犡 (<CJK Ideograph>) 17792 0x74CB 瓋 (<CJK Ideograph>) 17793 0x74C5 瓅 (<CJK Ideograph>) 17794 0x74B7 璷 (<CJK Ideograph>) 17795 0x74C3 瓃 (<CJK Ideograph>) 17796 0x7516 甖 (<CJK Ideograph>) 17797 0x7660 癠 (<CJK Ideograph>) 17798 0x77C9 矉 (<CJK Ideograph>) 17799 0x77CA 矊 (<CJK Ideograph>) 17800 0x77C4 矄 (<CJK Ideograph>) 17801 0x77F1 矱 (<CJK Ideograph>) 17802 0x791D 礝 (<CJK Ideograph>) 17803 0x791B 礛 (<CJK Ideograph>) 17804 0x7921 礡 (<CJK Ideograph>) 17805 0x791C 礜 (<CJK Ideograph>) 17806 0x7917 礗 (<CJK Ideograph>) 17807 0x791E 礞 (<CJK Ideograph>) 17808 0x79B0 禰 (<CJK Ideograph>) 17809 0x7A67 穧 (<CJK Ideograph>) 17810 0x7A68 穨 (<CJK Ideograph>) 17811 0x7C33 簳 (<CJK Ideograph>) 17812 0x7C3C 簼 (<CJK Ideograph>) 17813 0x7C39 簹 (<CJK Ideograph>) 17814 0x7C2C 簬 (<CJK Ideograph>) 17815 0x7C3B 簻 (<CJK Ideograph>) 17816 0x7CEC 糬 (<CJK Ideograph>) 17817 0x7CEA 糪 (<CJK Ideograph>) 17818 0x7E76 繶 (<CJK Ideograph>) 17819 0x7E75 繵 (<CJK Ideograph>) 17820 0x7E78 繸 (<CJK Ideograph>) 17821 0x7E70 繰 (<CJK Ideograph>) 17822 0x7E77 繷 (<CJK Ideograph>) 17823 0x7E6F 繯 (<CJK Ideograph>) 17824 0x7E7A 繺 (<CJK Ideograph>) 17825 0x7E72 繲 (<CJK Ideograph>) 17826 0x7E74 繴 (<CJK Ideograph>) 17827 0x7E68 繨 (<CJK Ideograph>) 17828 0x7F4B 罋 (<CJK Ideograph>) 17829 0x7F4A 罊 (<CJK Ideograph>) 17830 0x7F83 羃 (<CJK Ideograph>) 17831 0x7F86 羆 (<CJK Ideograph>) 17832 0x7FB7 羷 (<CJK Ideograph>) 17833 0x7FFD 翽 (<CJK Ideograph>) 17834 0x7FFE 翾 (<CJK Ideograph>) 17835 0x8078 聸 (<CJK Ideograph>) 17836 0x81D7 臗 (<CJK Ideograph>) 17837 0x81D5 臕 (<CJK Ideograph>) 17838 0x8264 艤 (<CJK Ideograph>) 17839 0x8261 艡 (<CJK Ideograph>) 17840 0x8263 艣 (<CJK Ideograph>) 17841 0x85EB 藫 (<CJK Ideograph>) 17842 0x85F1 藱 (<CJK Ideograph>) 17843 0x85ED 藭 (<CJK Ideograph>) 17844 0x85D9 藙 (<CJK Ideograph>) 17845 0x85E1 藡 (<CJK Ideograph>) 17846 0x85E8 藨 (<CJK Ideograph>) 17847 0x85DA 藚 (<CJK Ideograph>) 17848 0x85D7 藗 (<CJK Ideograph>) 17849 0x85EC 藬 (<CJK Ideograph>) 17850 0x85F2 藲 (<CJK Ideograph>) 17851 0x85F8 藸 (<CJK Ideograph>) 17852 0x85D8 藘 (<CJK Ideograph>) 17853 0x85DF 藟 (<CJK Ideograph>) 17854 0x85E3 藣 (<CJK Ideograph>) 17855 0x85DC 藜 (<CJK Ideograph>) 17856 0x85D1 藑 (<CJK Ideograph>) 17857 0x85F0 藰 (<CJK Ideograph>) 17858 0x85E6 藦 (<CJK Ideograph>) 17859 0x85EF 藯 (<CJK Ideograph>) 17860 0x85DE 藞 (<CJK Ideograph>) 17861 0x85E2 藢 (<CJK Ideograph>) 17862 0x8800 蠀 (<CJK Ideograph>) 17863 0x87FA 蟺 (<CJK Ideograph>) 17864 0x8803 蠃 (<CJK Ideograph>) 17865 0x87F6 蟶 (<CJK Ideograph>) 17866 0x87F7 蟷 (<CJK Ideograph>) 17867 0x8809 蠉 (<CJK Ideograph>) 17868 0x880C 蠌 (<CJK Ideograph>) 17869 0x880B 蠋 (<CJK Ideograph>) 17870 0x8806 蠆 (<CJK Ideograph>) 17871 0x87FC 蟼 (<CJK Ideograph>) 17872 0x8808 蠈 (<CJK Ideograph>) 17873 0x87FF 蟿 (<CJK Ideograph>) 17874 0x880A 蠊 (<CJK Ideograph>) 17875 0x8802 蠂 (<CJK Ideograph>) 17876 0x8962 襢 (<CJK Ideograph>) 17877 0x895A 襚 (<CJK Ideograph>) 17878 0x895B 襛 (<CJK Ideograph>) 17879 0x8957 襗 (<CJK Ideograph>) 17880 0x8961 襡 (<CJK Ideograph>) 17881 0x895C 襜 (<CJK Ideograph>) 17882 0x8958 襘 (<CJK Ideograph>) 17883 0x895D 襝 (<CJK Ideograph>) 17884 0x8959 襙 (<CJK Ideograph>) 17885 0x8988 覈 (<CJK Ideograph>) 17886 0x89B7 覷 (<CJK Ideograph>) 17887 0x89B6 覶 (<CJK Ideograph>) 17888 0x89F6 觶 (<CJK Ideograph>) 17889 0x8B50 譐 (<CJK Ideograph>) 17890 0x8B48 譈 (<CJK Ideograph>) 17891 0x8B4A 譊 (<CJK Ideograph>) 17892 0x8B40 譀 (<CJK Ideograph>) 17893 0x8B53 譓 (<CJK Ideograph>) 17894 0x8B56 譖 (<CJK Ideograph>) 17895 0x8B54 譔 (<CJK Ideograph>) 17896 0x8B4B 譋 (<CJK Ideograph>) 17897 0x8B55 譕 (<CJK Ideograph>) 17898 0x8B51 譑 (<CJK Ideograph>) 17899 0x8B42 譂 (<CJK Ideograph>) 17900 0x8B52 譒 (<CJK Ideograph>) 17901 0x8B57 譗 (<CJK Ideograph>) 17902 0x8C43 豃 (<CJK Ideograph>) 17903 0x8C77 豷 (<CJK Ideograph>) 17904 0x8C76 豶 (<CJK Ideograph>) 17905 0x8C9A 貚 (<CJK Ideograph>) 17906 0x8D06 贆 (<CJK Ideograph>) 17907 0x8D07 贇 (<CJK Ideograph>) 17908 0x8D09 贉 (<CJK Ideograph>) 17909 0x8DAC 趬 (<CJK Ideograph>) 17910 0x8DAA 趪 (<CJK Ideograph>) 17911 0x8DAD 趭 (<CJK Ideograph>) 17912 0x8DAB 趫 (<CJK Ideograph>) 17913 0x8E6D 蹭 (<CJK Ideograph>) 17914 0x8E78 蹸 (<CJK Ideograph>) 17915 0x8E73 蹳 (<CJK Ideograph>) 17916 0x8E6A 蹪 (<CJK Ideograph>) 17917 0x8E6F 蹯 (<CJK Ideograph>) 17918 0x8E7B 蹻 (<CJK Ideograph>) 17919 0x8EC2 軂 (<CJK Ideograph>) 17920 0x8F52 轒 (<CJK Ideograph>) 17921 0x8F51 轑 (<CJK Ideograph>) 17922 0x8F4F 轏 (<CJK Ideograph>) 17923 0x8F50 轐 (<CJK Ideograph>) 17924 0x8F53 轓 (<CJK Ideograph>) 17925 0x8FB4 辴 (<CJK Ideograph>) 17926 0x9140 酀 (<CJK Ideograph>) 17927 0x913F 鄿 (<CJK Ideograph>) 17928 0x91B0 醰 (<CJK Ideograph>) 17929 0x91AD 醭 (<CJK Ideograph>) 17930 0x93DE 鏞 (<CJK Ideograph>) 17931 0x93C7 鏇 (<CJK Ideograph>) 17932 0x93CF 鏏 (<CJK Ideograph>) 17933 0x93C2 鏂 (<CJK Ideograph>) 17934 0x93DA 鏚 (<CJK Ideograph>) 17935 0x93D0 鏐 (<CJK Ideograph>) 17936 0x93F9 鏹 (<CJK Ideograph>) 17937 0x93EC 鏬 (<CJK Ideograph>) 17938 0x93CC 鏌 (<CJK Ideograph>) 17939 0x93D9 鏙 (<CJK Ideograph>) 17940 0x93A9 鎩 (<CJK Ideograph>) 17941 0x93E6 鏦 (<CJK Ideograph>) 17942 0x93CA 鏊 (<CJK Ideograph>) 17943 0x93D4 鏔 (<CJK Ideograph>) 17944 0x93EE 鏮 (<CJK Ideograph>) 17945 0x93E3 鏣 (<CJK Ideograph>) 17946 0x93D5 鏕 (<CJK Ideograph>) 17947 0x93C4 鏄 (<CJK Ideograph>) 17948 0x93CE 鏎 (<CJK Ideograph>) 17949 0x93C0 鏀 (<CJK Ideograph>) 17950 0x93D2 鏒 (<CJK Ideograph>) 17951 0x93E7 鏧 (<CJK Ideograph>) 17952 0x957D 镽 (<CJK Ideograph>) 17953 0x95DA 闚 (<CJK Ideograph>) 17954 0x95DB 闛 (<CJK Ideograph>) 17955 0x96E1 雡 (<CJK Ideograph>) 17956 0x9729 霩 (<CJK Ideograph>) 17957 0x972B 霫 (<CJK Ideograph>) 17958 0x972C 霬 (<CJK Ideograph>) 17959 0x9728 霨 (<CJK Ideograph>) 17960 0x9726 霦 (<CJK Ideograph>) 17961 0x97B3 鞳 (<CJK Ideograph>) 17962 0x97B7 鞷 (<CJK Ideograph>) 17963 0x97B6 鞶 (<CJK Ideograph>) 17964 0x97DD 韝 (<CJK Ideograph>) 17965 0x97DE 韞 (<CJK Ideograph>) 17966 0x97DF 韟 (<CJK Ideograph>) 17967 0x985C 顜 (<CJK Ideograph>) 17968 0x9859 顙 (<CJK Ideograph>) 17969 0x985D 顝 (<CJK Ideograph>) 17970 0x9857 顗 (<CJK Ideograph>) 17971 0x98BF 颿 (<CJK Ideograph>) 17972 0x98BD 颽 (<CJK Ideograph>) 17973 0x98BB 颻 (<CJK Ideograph>) 17974 0x98BE 颾 (<CJK Ideograph>) 17975 0x9948 饈 (<CJK Ideograph>) 17976 0x9947 饇 (<CJK Ideograph>) 17977 0x9943 饃 (<CJK Ideograph>) 17978 0x99A6 馦 (<CJK Ideograph>) 17979 0x99A7 馧 (<CJK Ideograph>) 17980 0x9A1A 騚 (<CJK Ideograph>) 17981 0x9A15 騕 (<CJK Ideograph>) 17982 0x9A25 騥 (<CJK Ideograph>) 17983 0x9A1D 騝 (<CJK Ideograph>) 17984 0x9A24 騤 (<CJK Ideograph>) 17985 0x9A1B 騛 (<CJK Ideograph>) 17986 0x9A22 騢 (<CJK Ideograph>) 17987 0x9A20 騠 (<CJK Ideograph>) 17988 0x9A27 騧 (<CJK Ideograph>) 17989 0x9A23 騣 (<CJK Ideograph>) 17990 0x9A1E 騞 (<CJK Ideograph>) 17991 0x9A1C 騜 (<CJK Ideograph>) 17992 0x9A14 騔 (<CJK Ideograph>) 17993 0x9AC2 髂 (<CJK Ideograph>) 17994 0x9B0B 鬋 (<CJK Ideograph>) 17995 0x9B0A 鬊 (<CJK Ideograph>) 17996 0x9B0E 鬎 (<CJK Ideograph>) 17997 0x9B0C 鬌 (<CJK Ideograph>) 17998 0x9B37 鬷 (<CJK Ideograph>) 17999 0x9BEA 鯪 (<CJK Ideograph>) 18000 0x9BEB 鯫 (<CJK Ideograph>) 18001 0x9BE0 鯠 (<CJK Ideograph>) 18002 0x9BDE 鯞 (<CJK Ideograph>) 18003 0x9BE4 鯤 (<CJK Ideograph>) 18004 0x9BE6 鯦 (<CJK Ideograph>) 18005 0x9BE2 鯢 (<CJK Ideograph>) 18006 0x9BF0 鯰 (<CJK Ideograph>) 18007 0x9BD4 鯔 (<CJK Ideograph>) 18008 0x9BD7 鯗 (<CJK Ideograph>) 18009 0x9BEC 鯬 (<CJK Ideograph>) 18010 0x9BDC 鯜 (<CJK Ideograph>) 18011 0x9BD9 鯙 (<CJK Ideograph>) 18012 0x9BE5 鯥 (<CJK Ideograph>) 18013 0x9BD5 鯕 (<CJK Ideograph>) 18014 0x9BE1 鯡 (<CJK Ideograph>) 18015 0x9BDA 鯚 (<CJK Ideograph>) 18016 0x9D77 鵷 (<CJK Ideograph>) 18017 0x9D81 鶁 (<CJK Ideograph>) 18018 0x9D8A 鶊 (<CJK Ideograph>) 18019 0x9D84 鶄 (<CJK Ideograph>) 18020 0x9D88 鶈 (<CJK Ideograph>) 18021 0x9D71 鵱 (<CJK Ideograph>) 18022 0x9D80 鶀 (<CJK Ideograph>) 18023 0x9D78 鵸 (<CJK Ideograph>) 18024 0x9D86 鶆 (<CJK Ideograph>) 18025 0x9D8B 鶋 (<CJK Ideograph>) 18026 0x9D8C 鶌 (<CJK Ideograph>) 18027 0x9D7D 鵽 (<CJK Ideograph>) 18028 0x9D6B 鵫 (<CJK Ideograph>) 18029 0x9D74 鵴 (<CJK Ideograph>) 18030 0x9D75 鵵 (<CJK Ideograph>) 18031 0x9D70 鵰 (<CJK Ideograph>) 18032 0x9D69 鵩 (<CJK Ideograph>) 18033 0x9D85 鶅 (<CJK Ideograph>) 18034 0x9D73 鵳 (<CJK Ideograph>) 18035 0x9D7B 鵻 (<CJK Ideograph>) 18036 0x9D82 鶂 (<CJK Ideograph>) 18037 0x9D6F 鵯 (<CJK Ideograph>) 18038 0x9D79 鵹 (<CJK Ideograph>) 18039 0x9D7F 鵿 (<CJK Ideograph>) 18040 0x9D87 鶇 (<CJK Ideograph>) 18041 0x9D68 鵨 (<CJK Ideograph>) 18042 0x9E94 麔 (<CJK Ideograph>) 18043 0x9E91 麑 (<CJK Ideograph>) 18044 0x9EC0 黀 (<CJK Ideograph>) 18045 0x9EFC 黼 (<CJK Ideograph>) 18046 0x9F2D 鼭 (<CJK Ideograph>) 18047 0x9F40 齀 (<CJK Ideograph>) 18048 0x9F41 齁 (<CJK Ideograph>) 18049 0x9F4D 齍 (<CJK Ideograph>) 18050 0x9F56 齖 (<CJK Ideograph>) 18051 0x9F57 齗 (<CJK Ideograph>) 18052 0x9F58 齘 (<CJK Ideograph>) 18053 0x5337 匷 (<CJK Ideograph>) 18054 0x56B2 嚲 (<CJK Ideograph>) 18055 0x56B5 嚵 (<CJK Ideograph>) 18056 0x56B3 嚳 (<CJK Ideograph>) 18057 0x58E3 壣 (<CJK Ideograph>) 18058 0x5B45 孅 (<CJK Ideograph>) 18059 0x5DC6 巆 (<CJK Ideograph>) 18060 0x5DC7 巇 (<CJK Ideograph>) 18061 0x5EEE 廮 (<CJK Ideograph>) 18062 0x5EEF 廯 (<CJK Ideograph>) 18063 0x5FC0 忀 (<CJK Ideograph>) 18064 0x5FC1 忁 (<CJK Ideograph>) 18065 0x61F9 懹 (<CJK Ideograph>) 18066 0x6517 攗 (<CJK Ideograph>) 18067 0x6516 攖 (<CJK Ideograph>) 18068 0x6515 攕 (<CJK Ideograph>) 18069 0x6513 攓 (<CJK Ideograph>) 18070 0x65DF 旟 (<CJK Ideograph>) 18071 0x66E8 曨 (<CJK Ideograph>) 18072 0x66E3 曣 (<CJK Ideograph>) 18073 0x66E4 曤 (<CJK Ideograph>) 18074 0x6AF3 櫳 (<CJK Ideograph>) 18075 0x6AF0 櫰 (<CJK Ideograph>) 18076 0x6AEA 櫪 (<CJK Ideograph>) 18077 0x6AE8 櫨 (<CJK Ideograph>) 18078 0x6AF9 櫹 (<CJK Ideograph>) 18079 0x6AF1 櫱 (<CJK Ideograph>) 18080 0x6AEE 櫮 (<CJK Ideograph>) 18081 0x6AEF 櫯 (<CJK Ideograph>) 18082 0x703C 瀼 (<CJK Ideograph>) 18083 0x7035 瀵 (<CJK Ideograph>) 18084 0x702F 瀯 (<CJK Ideograph>) 18085 0x7037 瀷 (<CJK Ideograph>) 18086 0x7034 瀴 (<CJK Ideograph>) 18087 0x7031 瀱 (<CJK Ideograph>) 18088 0x7042 灂 (<CJK Ideograph>) 18089 0x7038 瀸 (<CJK Ideograph>) 18090 0x703F 瀿 (<CJK Ideograph>) 18091 0x703A 瀺 (<CJK Ideograph>) 18092 0x7039 瀹 (<CJK Ideograph>) 18093 0x7040 灀 (<CJK Ideograph>) 18094 0x703B 瀻 (<CJK Ideograph>) 18095 0x7033 瀳 (<CJK Ideograph>) 18096 0x7041 灁 (<CJK Ideograph>) 18097 0x7213 爓 (<CJK Ideograph>) 18098 0x7214 爔 (<CJK Ideograph>) 18099 0x72A8 犨 (<CJK Ideograph>) 18100 0x737D 獽 (<CJK Ideograph>) 18101 0x737C 獼 (<CJK Ideograph>) 18102 0x74BA 璺 (<CJK Ideograph>) 18103 0x76AB 皫 (<CJK Ideograph>) 18104 0x76AA 皪 (<CJK Ideograph>) 18105 0x76BE 皾 (<CJK Ideograph>) 18106 0x76ED 盭 (<CJK Ideograph>) 18107 0x77CC 矌 (<CJK Ideograph>) 18108 0x77CE 矎 (<CJK Ideograph>) 18109 0x77CF 矏 (<CJK Ideograph>) 18110 0x77CD 矍 (<CJK Ideograph>) 18111 0x77F2 矲 (<CJK Ideograph>) 18112 0x7925 礥 (<CJK Ideograph>) 18113 0x7923 礣 (<CJK Ideograph>) 18114 0x7927 礧 (<CJK Ideograph>) 18115 0x7928 礨 (<CJK Ideograph>) 18116 0x7924 礤 (<CJK Ideograph>) 18117 0x7929 礩 (<CJK Ideograph>) 18118 0x79B2 禲 (<CJK Ideograph>) 18119 0x7A6E 穮 (<CJK Ideograph>) 18120 0x7A6C 穬 (<CJK Ideograph>) 18121 0x7A6D 穭 (<CJK Ideograph>) 18122 0x7AF7 竷 (<CJK Ideograph>) 18123 0x7C49 籉 (<CJK Ideograph>) 18124 0x7C48 籈 (<CJK Ideograph>) 18125 0x7C4A 籊 (<CJK Ideograph>) 18126 0x7C47 籇 (<CJK Ideograph>) 18127 0x7C45 籅 (<CJK Ideograph>) 18128 0x7CEE 糮 (<CJK Ideograph>) 18129 0x7E7B 繻 (<CJK Ideograph>) 18130 0x7E7E 繾 (<CJK Ideograph>) 18131 0x7E81 纁 (<CJK Ideograph>) 18132 0x7E80 纀 (<CJK Ideograph>) 18133 0x7FBA 羺 (<CJK Ideograph>) 18134 0x7FFF 翿 (<CJK Ideograph>) 18135 0x8079 聹 (<CJK Ideograph>) 18136 0x81DB 臛 (<CJK Ideograph>) 18137 0x81D9 臙 (<CJK Ideograph>) 18138 0x820B 舋 (<CJK Ideograph>) 18139 0x8268 艨 (<CJK Ideograph>) 18140 0x8269 艩 (<CJK Ideograph>) 18141 0x8622 蘢 (<CJK Ideograph>) 18142 0x85FF 藿 (<CJK Ideograph>) 18143 0x8601 蘁 (<CJK Ideograph>) 18144 0x85FE 藾 (<CJK Ideograph>) 18145 0x861B 蘛 (<CJK Ideograph>) 18146 0x8600 蘀 (<CJK Ideograph>) 18147 0x85F6 藶 (<CJK Ideograph>) 18148 0x8604 蘄 (<CJK Ideograph>) 18149 0x8609 蘉 (<CJK Ideograph>) 18150 0x8605 蘅 (<CJK Ideograph>) 18151 0x860C 蘌 (<CJK Ideograph>) 18152 0x85FD 藽 (<CJK Ideograph>) 18153 0x8819 蠙 (<CJK Ideograph>) 18154 0x8810 蠐 (<CJK Ideograph>) 18155 0x8811 蠑 (<CJK Ideograph>) 18156 0x8817 蠗 (<CJK Ideograph>) 18157 0x8813 蠓 (<CJK Ideograph>) 18158 0x8816 蠖 (<CJK Ideograph>) 18159 0x8963 襣 (<CJK Ideograph>) 18160 0x8966 襦 (<CJK Ideograph>) 18161 0x89B9 覹 (<CJK Ideograph>) 18162 0x89F7 觷 (<CJK Ideograph>) 18163 0x8B60 譠 (<CJK Ideograph>) 18164 0x8B6A 譪 (<CJK Ideograph>) 18165 0x8B5D 譝 (<CJK Ideograph>) 18166 0x8B68 譨 (<CJK Ideograph>) 18167 0x8B63 譣 (<CJK Ideograph>) 18168 0x8B65 譥 (<CJK Ideograph>) 18169 0x8B67 譧 (<CJK Ideograph>) 18170 0x8B6D 譭 (<CJK Ideograph>) 18171 0x8DAE 趮 (<CJK Ideograph>) 18172 0x8E86 躆 (<CJK Ideograph>) 18173 0x8E88 躈 (<CJK Ideograph>) 18174 0x8E84 躄 (<CJK Ideograph>) 18175 0x8F59 轙 (<CJK Ideograph>) 18176 0x8F56 轖 (<CJK Ideograph>) 18177 0x8F57 轗 (<CJK Ideograph>) 18178 0x8F55 轕 (<CJK Ideograph>) 18179 0x8F58 轘 (<CJK Ideograph>) 18180 0x8F5A 轚 (<CJK Ideograph>) 18181 0x908D 邍 (<CJK Ideograph>) 18182 0x9143 酃 (<CJK Ideograph>) 18183 0x9141 酁 (<CJK Ideograph>) 18184 0x91B7 醷 (<CJK Ideograph>) 18185 0x91B5 醵 (<CJK Ideograph>) 18186 0x91B2 醲 (<CJK Ideograph>) 18187 0x91B3 醳 (<CJK Ideograph>) 18188 0x940B 鐋 (<CJK Ideograph>) 18189 0x9413 鐓 (<CJK Ideograph>) 18190 0x93FB 鏻 (<CJK Ideograph>) 18191 0x9420 鐠 (<CJK Ideograph>) 18192 0x940F 鐏 (<CJK Ideograph>) 18193 0x9414 鐔 (<CJK Ideograph>) 18194 0x93FE 鏾 (<CJK Ideograph>) 18195 0x9415 鐕 (<CJK Ideograph>) 18196 0x9410 鐐 (<CJK Ideograph>) 18197 0x9428 鐨 (<CJK Ideograph>) 18198 0x9419 鐙 (<CJK Ideograph>) 18199 0x940D 鐍 (<CJK Ideograph>) 18200 0x93F5 鏵 (<CJK Ideograph>) 18201 0x9400 鐀 (<CJK Ideograph>) 18202 0x93F7 鏷 (<CJK Ideograph>) 18203 0x9407 鐇 (<CJK Ideograph>) 18204 0x940E 鐎 (<CJK Ideograph>) 18205 0x9416 鐖 (<CJK Ideograph>) 18206 0x9412 鐒 (<CJK Ideograph>) 18207 0x93FA 鏺 (<CJK Ideograph>) 18208 0x9409 鐉 (<CJK Ideograph>) 18209 0x93F8 鏸 (<CJK Ideograph>) 18210 0x940A 鐊 (<CJK Ideograph>) 18211 0x93FF 鏿 (<CJK Ideograph>) 18212 0x93FC 鏼 (<CJK Ideograph>) 18213 0x940C 鐌 (<CJK Ideograph>) 18214 0x93F6 鏶 (<CJK Ideograph>) 18215 0x9411 鐑 (<CJK Ideograph>) 18216 0x9406 鐆 (<CJK Ideograph>) 18217 0x95DE 闞 (<CJK Ideograph>) 18218 0x95E0 闠 (<CJK Ideograph>) 18219 0x95DF 闟 (<CJK Ideograph>) 18220 0x972E 霮 (<CJK Ideograph>) 18221 0x972F 霯 (<CJK Ideograph>) 18222 0x97B9 鞹 (<CJK Ideograph>) 18223 0x97BB 鞻 (<CJK Ideograph>) 18224 0x97FD 韽 (<CJK Ideograph>) 18225 0x97FE 韾 (<CJK Ideograph>) 18226 0x9860 顠 (<CJK Ideograph>) 18227 0x9862 顢 (<CJK Ideograph>) 18228 0x9863 顣 (<CJK Ideograph>) 18229 0x985F 顟 (<CJK Ideograph>) 18230 0x98C1 飁 (<CJK Ideograph>) 18231 0x98C2 飂 (<CJK Ideograph>) 18232 0x9950 饐 (<CJK Ideograph>) 18233 0x994E 饎 (<CJK Ideograph>) 18234 0x9959 饙 (<CJK Ideograph>) 18235 0x994C 饌 (<CJK Ideograph>) 18236 0x994B 饋 (<CJK Ideograph>) 18237 0x9953 饓 (<CJK Ideograph>) 18238 0x9A32 騲 (<CJK Ideograph>) 18239 0x9A34 騴 (<CJK Ideograph>) 18240 0x9A31 騱 (<CJK Ideograph>) 18241 0x9A2C 騬 (<CJK Ideograph>) 18242 0x9A2A 騪 (<CJK Ideograph>) 18243 0x9A36 騶 (<CJK Ideograph>) 18244 0x9A29 騩 (<CJK Ideograph>) 18245 0x9A2E 騮 (<CJK Ideograph>) 18246 0x9A38 騸 (<CJK Ideograph>) 18247 0x9A2D 騭 (<CJK Ideograph>) 18248 0x9AC7 髇 (<CJK Ideograph>) 18249 0x9ACA 髊 (<CJK Ideograph>) 18250 0x9AC6 髆 (<CJK Ideograph>) 18251 0x9B10 鬐 (<CJK Ideograph>) 18252 0x9B12 鬒 (<CJK Ideograph>) 18253 0x9B11 鬑 (<CJK Ideograph>) 18254 0x9C0B 鰋 (<CJK Ideograph>) 18255 0x9C08 鰈 (<CJK Ideograph>) 18256 0x9BF7 鯷 (<CJK Ideograph>) 18257 0x9C05 鰅 (<CJK Ideograph>) 18258 0x9C12 鰒 (<CJK Ideograph>) 18259 0x9BF8 鯸 (<CJK Ideograph>) 18260 0x9C40 鱀 (<CJK Ideograph>) 18261 0x9C07 鰇 (<CJK Ideograph>) 18262 0x9C0E 鰎 (<CJK Ideograph>) 18263 0x9C06 鰆 (<CJK Ideograph>) 18264 0x9C17 鰗 (<CJK Ideograph>) 18265 0x9C14 鰔 (<CJK Ideograph>) 18266 0x9C09 鰉 (<CJK Ideograph>) 18267 0x9D9F 鶟 (<CJK Ideograph>) 18268 0x9D99 鶙 (<CJK Ideograph>) 18269 0x9DA4 鶤 (<CJK Ideograph>) 18270 0x9D9D 鶝 (<CJK Ideograph>) 18271 0x9D92 鶒 (<CJK Ideograph>) 18272 0x9D98 鶘 (<CJK Ideograph>) 18273 0x9D90 鶐 (<CJK Ideograph>) 18274 0x9D9B 鶛 (<CJK Ideograph>) 18275 0x9DA0 鶠 (<CJK Ideograph>) 18276 0x9D94 鶔 (<CJK Ideograph>) 18277 0x9D9C 鶜 (<CJK Ideograph>) 18278 0x9DAA 鶪 (<CJK Ideograph>) 18279 0x9D97 鶗 (<CJK Ideograph>) 18280 0x9DA1 鶡 (<CJK Ideograph>) 18281 0x9D9A 鶚 (<CJK Ideograph>) 18282 0x9DA2 鶢 (<CJK Ideograph>) 18283 0x9DA8 鶨 (<CJK Ideograph>) 18284 0x9D9E 鶞 (<CJK Ideograph>) 18285 0x9DA3 鶣 (<CJK Ideograph>) 18286 0x9DBF 鶿 (<CJK Ideograph>) 18287 0x9DA9 鶩 (<CJK Ideograph>) 18288 0x9D96 鶖 (<CJK Ideograph>) 18289 0x9DA6 鶦 (<CJK Ideograph>) 18290 0x9DA7 鶧 (<CJK Ideograph>) 18291 0x9E99 麙 (<CJK Ideograph>) 18292 0x9E9B 麛 (<CJK Ideograph>) 18293 0x9E9A 麚 (<CJK Ideograph>) 18294 0x9EE5 黥 (<CJK Ideograph>) 18295 0x9EE4 黤 (<CJK Ideograph>) 18296 0x9EE7 黧 (<CJK Ideograph>) 18297 0x9EE6 黦 (<CJK Ideograph>) 18298 0x9F30 鼰 (<CJK Ideograph>) 18299 0x9F2E 鼮 (<CJK Ideograph>) 18300 0x9F5B 齛 (<CJK Ideograph>) 18301 0x9F60 齠 (<CJK Ideograph>) 18302 0x9F5E 齞 (<CJK Ideograph>) 18303 0x9F5D 齝 (<CJK Ideograph>) 18304 0x9F59 齙 (<CJK Ideograph>) 18305 0x9F91 龑 (<CJK Ideograph>) 18306 0x513A 儺 (<CJK Ideograph>) 18307 0x5139 儹 (<CJK Ideograph>) 18308 0x5298 劘 (<CJK Ideograph>) 18309 0x5297 劗 (<CJK Ideograph>) 18310 0x56C3 囃 (<CJK Ideograph>) 18311 0x56BD 嚽 (<CJK Ideograph>) 18312 0x56BE 嚾 (<CJK Ideograph>) 18313 0x5B48 孈 (<CJK Ideograph>) 18314 0x5B47 孇 (<CJK Ideograph>) 18315 0x5DCB 巋 (<CJK Ideograph>) 18316 0x5DCF 巏 (<CJK Ideograph>) 18317 0x5EF1 廱 (<CJK Ideograph>) 18318 0x61FD 懽 (<CJK Ideograph>) 18319 0x651B 攛 (<CJK Ideograph>) 18320 0x6B02 欂 (<CJK Ideograph>) 18321 0x6AFC 櫼 (<CJK Ideograph>) 18322 0x6B03 欃 (<CJK Ideograph>) 18323 0x6AF8 櫸 (<CJK Ideograph>) 18324 0x6B00 欀 (<CJK Ideograph>) 18325 0x7043 灃 (<CJK Ideograph>) 18326 0x7044 灄 (<CJK Ideograph>) 18327 0x704A 灊 (<CJK Ideograph>) 18328 0x7048 灈 (<CJK Ideograph>) 18329 0x7049 灉 (<CJK Ideograph>) 18330 0x7045 灅 (<CJK Ideograph>) 18331 0x7046 灆 (<CJK Ideograph>) 18332 0x721D 爝 (<CJK Ideograph>) 18333 0x721A 爚 (<CJK Ideograph>) 18334 0x7219 爙 (<CJK Ideograph>) 18335 0x737E 獾 (<CJK Ideograph>) 18336 0x7517 甗 (<CJK Ideograph>) 18337 0x766A 癪 (<CJK Ideograph>) 18338 0x77D0 矐 (<CJK Ideograph>) 18339 0x792D 礭 (<CJK Ideograph>) 18340 0x7931 礱 (<CJK Ideograph>) 18341 0x792F 礯 (<CJK Ideograph>) 18342 0x7C54 籔 (<CJK Ideograph>) 18343 0x7C53 籓 (<CJK Ideograph>) 18344 0x7CF2 糲 (<CJK Ideograph>) 18345 0x7E8A 纊 (<CJK Ideograph>) 18346 0x7E87 纇 (<CJK Ideograph>) 18347 0x7E88 纈 (<CJK Ideograph>) 18348 0x7E8B 纋 (<CJK Ideograph>) 18349 0x7E86 纆 (<CJK Ideograph>) 18350 0x7E8D 纍 (<CJK Ideograph>) 18351 0x7F4D 罍 (<CJK Ideograph>) 18352 0x7FBB 羻 (<CJK Ideograph>) 18353 0x8030 耰 (<CJK Ideograph>) 18354 0x81DD 臝 (<CJK Ideograph>) 18355 0x8618 蘘 (<CJK Ideograph>) 18356 0x862A 蘪 (<CJK Ideograph>) 18357 0x8626 蘦 (<CJK Ideograph>) 18358 0x861F 蘟 (<CJK Ideograph>) 18359 0x8623 蘣 (<CJK Ideograph>) 18360 0x861C 蘜 (<CJK Ideograph>) 18361 0x8619 蘙 (<CJK Ideograph>) 18362 0x8627 蘧 (<CJK Ideograph>) 18363 0x862E 蘮 (<CJK Ideograph>) 18364 0x8621 蘡 (<CJK Ideograph>) 18365 0x8620 蘠 (<CJK Ideograph>) 18366 0x8629 蘩 (<CJK Ideograph>) 18367 0x861E 蘞 (<CJK Ideograph>) 18368 0x8625 蘥 (<CJK Ideograph>) 18369 0x8829 蠩 (<CJK Ideograph>) 18370 0x881D 蠝 (<CJK Ideograph>) 18371 0x881B 蠛 (<CJK Ideograph>) 18372 0x8820 蠠 (<CJK Ideograph>) 18373 0x8824 蠤 (<CJK Ideograph>) 18374 0x881C 蠜 (<CJK Ideograph>) 18375 0x882B 蠫 (<CJK Ideograph>) 18376 0x884A 衊 (<CJK Ideograph>) 18377 0x896D 襭 (<CJK Ideograph>) 18378 0x8969 襩 (<CJK Ideograph>) 18379 0x896E 襮 (<CJK Ideograph>) 18380 0x896B 襫 (<CJK Ideograph>) 18381 0x89FA 觺 (<CJK Ideograph>) 18382 0x8B79 譹 (<CJK Ideograph>) 18383 0x8B78 譸 (<CJK Ideograph>) 18384 0x8B45 譅 (<CJK Ideograph>) 18385 0x8B7A 譺 (<CJK Ideograph>) 18386 0x8B7B 譻 (<CJK Ideograph>) 18387 0x8D10 贐 (<CJK Ideograph>) 18388 0x8D14 贔 (<CJK Ideograph>) 18389 0x8DAF 趯 (<CJK Ideograph>) 18390 0x8E8E 躎 (<CJK Ideograph>) 18391 0x8E8C 躌 (<CJK Ideograph>) 18392 0x8F5E 轞 (<CJK Ideograph>) 18393 0x8F5B 轛 (<CJK Ideograph>) 18394 0x8F5D 轝 (<CJK Ideograph>) 18395 0x9146 酆 (<CJK Ideograph>) 18396 0x9144 酄 (<CJK Ideograph>) 18397 0x9145 酅 (<CJK Ideograph>) 18398 0x91B9 醹 (<CJK Ideograph>) 18399 0x943F 鐿 (<CJK Ideograph>) 18400 0x943B 鐻 (<CJK Ideograph>) 18401 0x9436 鐶 (<CJK Ideograph>) 18402 0x9429 鐩 (<CJK Ideograph>) 18403 0x943D 鐽 (<CJK Ideograph>) 18404 0x943C 鐼 (<CJK Ideograph>) 18405 0x9430 鐰 (<CJK Ideograph>) 18406 0x9439 鐹 (<CJK Ideograph>) 18407 0x942A 鐪 (<CJK Ideograph>) 18408 0x9437 鐷 (<CJK Ideograph>) 18409 0x942C 鐬 (<CJK Ideograph>) 18410 0x9440 鑀 (<CJK Ideograph>) 18411 0x9431 鐱 (<CJK Ideograph>) 18412 0x95E5 闥 (<CJK Ideograph>) 18413 0x95E4 闤 (<CJK Ideograph>) 18414 0x95E3 闣 (<CJK Ideograph>) 18415 0x9735 霵 (<CJK Ideograph>) 18416 0x973A 霺 (<CJK Ideograph>) 18417 0x97BF 鞿 (<CJK Ideograph>) 18418 0x97E1 韡 (<CJK Ideograph>) 18419 0x9864 顤 (<CJK Ideograph>) 18420 0x98C9 飉 (<CJK Ideograph>) 18421 0x98C6 飆 (<CJK Ideograph>) 18422 0x98C0 飀 (<CJK Ideograph>) 18423 0x9958 饘 (<CJK Ideograph>) 18424 0x9956 饖 (<CJK Ideograph>) 18425 0x9A39 騹 (<CJK Ideograph>) 18426 0x9A3D 騽 (<CJK Ideograph>) 18427 0x9A46 驆 (<CJK Ideograph>) 18428 0x9A44 驄 (<CJK Ideograph>) 18429 0x9A42 驂 (<CJK Ideograph>) 18430 0x9A41 驁 (<CJK Ideograph>) 18431 0x9A3A 騺 (<CJK Ideograph>) 18432 0x9A3F 騿 (<CJK Ideograph>) 18433 0x9ACD 髍 (<CJK Ideograph>) 18434 0x9B15 鬕 (<CJK Ideograph>) 18435 0x9B17 鬗 (<CJK Ideograph>) 18436 0x9B18 鬘 (<CJK Ideograph>) 18437 0x9B16 鬖 (<CJK Ideograph>) 18438 0x9B3A 鬺 (<CJK Ideograph>) 18439 0x9B52 魒 (<CJK Ideograph>) 18440 0x9C2B 鰫 (<CJK Ideograph>) 18441 0x9C1D 鰝 (<CJK Ideograph>) 18442 0x9C1C 鰜 (<CJK Ideograph>) 18443 0x9C2C 鰬 (<CJK Ideograph>) 18444 0x9C23 鰣 (<CJK Ideograph>) 18445 0x9C28 鰨 (<CJK Ideograph>) 18446 0x9C29 鰩 (<CJK Ideograph>) 18447 0x9C24 鰤 (<CJK Ideograph>) 18448 0x9C21 鰡 (<CJK Ideograph>) 18449 0x9DB7 鶷 (<CJK Ideograph>) 18450 0x9DB6 鶶 (<CJK Ideograph>) 18451 0x9DBC 鶼 (<CJK Ideograph>) 18452 0x9DC1 鷁 (<CJK Ideograph>) 18453 0x9DC7 鷇 (<CJK Ideograph>) 18454 0x9DCA 鷊 (<CJK Ideograph>) 18455 0x9DCF 鷏 (<CJK Ideograph>) 18456 0x9DBE 鶾 (<CJK Ideograph>) 18457 0x9DC5 鷅 (<CJK Ideograph>) 18458 0x9DC3 鷃 (<CJK Ideograph>) 18459 0x9DBB 鶻 (<CJK Ideograph>) 18460 0x9DB5 鶵 (<CJK Ideograph>) 18461 0x9DCE 鷎 (<CJK Ideograph>) 18462 0x9DB9 鶹 (<CJK Ideograph>) 18463 0x9DBA 鶺 (<CJK Ideograph>) 18464 0x9DAC 鶬 (<CJK Ideograph>) 18465 0x9DC8 鷈 (<CJK Ideograph>) 18466 0x9DB1 鶱 (<CJK Ideograph>) 18467 0x9DAD 鶭 (<CJK Ideograph>) 18468 0x9DCC 鷌 (<CJK Ideograph>) 18469 0x9DB3 鶳 (<CJK Ideograph>) 18470 0x9DCD 鷍 (<CJK Ideograph>) 18471 0x9DB2 鶲 (<CJK Ideograph>) 18472 0x9E7A 鹺 (<CJK Ideograph>) 18473 0x9E9C 麜 (<CJK Ideograph>) 18474 0x9EEB 黫 (<CJK Ideograph>) 18475 0x9EEE 黮 (<CJK Ideograph>) 18476 0x9EED 黭 (<CJK Ideograph>) 18477 0x9F1B 鼛 (<CJK Ideograph>) 18478 0x9F18 鼘 (<CJK Ideograph>) 18479 0x9F1A 鼚 (<CJK Ideograph>) 18480 0x9F31 鼱 (<CJK Ideograph>) 18481 0x9F4E 齎 (<CJK Ideograph>) 18482 0x9F65 齥 (<CJK Ideograph>) 18483 0x9F64 齤 (<CJK Ideograph>) 18484 0x9F92 龒 (<CJK Ideograph>) 18485 0x4EB9 亹 (<CJK Ideograph>) 18486 0x56C6 囆 (<CJK Ideograph>) 18487 0x56C5 囅 (<CJK Ideograph>) 18488 0x56CB 囋 (<CJK Ideograph>) 18489 0x5971 奱 (<CJK Ideograph>) 18490 0x5B4B 孋 (<CJK Ideograph>) 18491 0x5B4C 孌 (<CJK Ideograph>) 18492 0x5DD5 巕 (<CJK Ideograph>) 18493 0x5DD1 巑 (<CJK Ideograph>) 18494 0x5EF2 廲 (<CJK Ideograph>) 18495 0x6521 攡 (<CJK Ideograph>) 18496 0x6520 攠 (<CJK Ideograph>) 18497 0x6526 攦 (<CJK Ideograph>) 18498 0x6522 攢 (<CJK Ideograph>) 18499 0x6B0B 欋 (<CJK Ideograph>) 18500 0x6B08 欈 (<CJK Ideograph>) 18501 0x6B09 欉 (<CJK Ideograph>) 18502 0x6C0D 氍 (<CJK Ideograph>) 18503 0x7055 灕 (<CJK Ideograph>) 18504 0x7056 灖 (<CJK Ideograph>) 18505 0x7057 灗 (<CJK Ideograph>) 18506 0x7052 灒 (<CJK Ideograph>) 18507 0x721E 爞 (<CJK Ideograph>) 18508 0x721F 爟 (<CJK Ideograph>) 18509 0x72A9 犩 (<CJK Ideograph>) 18510 0x737F 獿 (<CJK Ideograph>) 18511 0x74D8 瓘 (<CJK Ideograph>) 18512 0x74D5 瓕 (<CJK Ideograph>) 18513 0x74D9 瓙 (<CJK Ideograph>) 18514 0x74D7 瓗 (<CJK Ideograph>) 18515 0x766D 癭 (<CJK Ideograph>) 18516 0x76AD 皭 (<CJK Ideograph>) 18517 0x7935 礵 (<CJK Ideograph>) 18518 0x79B4 禴 (<CJK Ideograph>) 18519 0x7A70 穰 (<CJK Ideograph>) 18520 0x7A71 穱 (<CJK Ideograph>) 18521 0x7C57 籗 (<CJK Ideograph>) 18522 0x7C5C 籜 (<CJK Ideograph>) 18523 0x7C59 籙 (<CJK Ideograph>) 18524 0x7C5B 籛 (<CJK Ideograph>) 18525 0x7C5A 籚 (<CJK Ideograph>) 18526 0x7CF4 糴 (<CJK Ideograph>) 18527 0x7CF1 糱 (<CJK Ideograph>) 18528 0x7E91 纑 (<CJK Ideograph>) 18529 0x7F4F 罏 (<CJK Ideograph>) 18530 0x7F87 羇 (<CJK Ideograph>) 18531 0x81DE 臞 (<CJK Ideograph>) 18532 0x826B 艫 (<CJK Ideograph>) 18533 0x8634 蘴 (<CJK Ideograph>) 18534 0x8635 蘵 (<CJK Ideograph>) 18535 0x8633 蘳 (<CJK Ideograph>) 18536 0x862C 蘬 (<CJK Ideograph>) 18537 0x8632 蘲 (<CJK Ideograph>) 18538 0x8636 蘶 (<CJK Ideograph>) 18539 0x882C 蠬 (<CJK Ideograph>) 18540 0x8828 蠨 (<CJK Ideograph>) 18541 0x8826 蠦 (<CJK Ideograph>) 18542 0x882A 蠪 (<CJK Ideograph>) 18543 0x8825 蠥 (<CJK Ideograph>) 18544 0x8971 襱 (<CJK Ideograph>) 18545 0x89BF 覿 (<CJK Ideograph>) 18546 0x89BE 覾 (<CJK Ideograph>) 18547 0x89FB 觻 (<CJK Ideograph>) 18548 0x8B7E 譾 (<CJK Ideograph>) 18549 0x8B84 讄 (<CJK Ideograph>) 18550 0x8B82 讂 (<CJK Ideograph>) 18551 0x8B86 讆 (<CJK Ideograph>) 18552 0x8B85 讅 (<CJK Ideograph>) 18553 0x8B7F 譿 (<CJK Ideograph>) 18554 0x8D15 贕 (<CJK Ideograph>) 18555 0x8E95 躕 (<CJK Ideograph>) 18556 0x8E94 躔 (<CJK Ideograph>) 18557 0x8E9A 躚 (<CJK Ideograph>) 18558 0x8E92 躒 (<CJK Ideograph>) 18559 0x8E90 躐 (<CJK Ideograph>) 18560 0x8E96 躖 (<CJK Ideograph>) 18561 0x8E97 躗 (<CJK Ideograph>) 18562 0x8F60 轠 (<CJK Ideograph>) 18563 0x8F62 轢 (<CJK Ideograph>) 18564 0x9147 酇 (<CJK Ideograph>) 18565 0x944C 鑌 (<CJK Ideograph>) 18566 0x9450 鑐 (<CJK Ideograph>) 18567 0x944A 鑊 (<CJK Ideograph>) 18568 0x944B 鑋 (<CJK Ideograph>) 18569 0x944F 鑏 (<CJK Ideograph>) 18570 0x9447 鑇 (<CJK Ideograph>) 18571 0x9445 鑅 (<CJK Ideograph>) 18572 0x9448 鑈 (<CJK Ideograph>) 18573 0x9449 鑉 (<CJK Ideograph>) 18574 0x9446 鑆 (<CJK Ideograph>) 18575 0x973F 霿 (<CJK Ideograph>) 18576 0x97E3 韣 (<CJK Ideograph>) 18577 0x986A 顪 (<CJK Ideograph>) 18578 0x9869 顩 (<CJK Ideograph>) 18579 0x98CB 飋 (<CJK Ideograph>) 18580 0x9954 饔 (<CJK Ideograph>) 18581 0x995B 饛 (<CJK Ideograph>) 18582 0x9A4E 驎 (<CJK Ideograph>) 18583 0x9A53 驓 (<CJK Ideograph>) 18584 0x9A54 驔 (<CJK Ideograph>) 18585 0x9A4C 驌 (<CJK Ideograph>) 18586 0x9A4F 驏 (<CJK Ideograph>) 18587 0x9A48 驈 (<CJK Ideograph>) 18588 0x9A4A 驊 (<CJK Ideograph>) 18589 0x9A49 驉 (<CJK Ideograph>) 18590 0x9A52 驒 (<CJK Ideograph>) 18591 0x9A50 驐 (<CJK Ideograph>) 18592 0x9AD0 髐 (<CJK Ideograph>) 18593 0x9B19 鬙 (<CJK Ideograph>) 18594 0x9B2B 鬫 (<CJK Ideograph>) 18595 0x9B3B 鬻 (<CJK Ideograph>) 18596 0x9B56 魖 (<CJK Ideograph>) 18597 0x9B55 魕 (<CJK Ideograph>) 18598 0x9C46 鱆 (<CJK Ideograph>) 18599 0x9C48 鱈 (<CJK Ideograph>) 18600 0x9C3F 鰿 (<CJK Ideograph>) 18601 0x9C44 鱄 (<CJK Ideograph>) 18602 0x9C39 鰹 (<CJK Ideograph>) 18603 0x9C33 鰳 (<CJK Ideograph>) 18604 0x9C41 鱁 (<CJK Ideograph>) 18605 0x9C3C 鰼 (<CJK Ideograph>) 18606 0x9C37 鰷 (<CJK Ideograph>) 18607 0x9C34 鰴 (<CJK Ideograph>) 18608 0x9C32 鰲 (<CJK Ideograph>) 18609 0x9C3D 鰽 (<CJK Ideograph>) 18610 0x9C36 鰶 (<CJK Ideograph>) 18611 0x9DDB 鷛 (<CJK Ideograph>) 18612 0x9DD2 鷒 (<CJK Ideograph>) 18613 0x9DDE 鷞 (<CJK Ideograph>) 18614 0x9DDA 鷚 (<CJK Ideograph>) 18615 0x9DCB 鷋 (<CJK Ideograph>) 18616 0x9DD0 鷐 (<CJK Ideograph>) 18617 0x9DDC 鷜 (<CJK Ideograph>) 18618 0x9DD1 鷑 (<CJK Ideograph>) 18619 0x9DDF 鷟 (<CJK Ideograph>) 18620 0x9DE9 鷩 (<CJK Ideograph>) 18621 0x9DD9 鷙 (<CJK Ideograph>) 18622 0x9DD8 鷘 (<CJK Ideograph>) 18623 0x9DD6 鷖 (<CJK Ideograph>) 18624 0x9DF5 鷵 (<CJK Ideograph>) 18625 0x9DD5 鷕 (<CJK Ideograph>) 18626 0x9DDD 鷝 (<CJK Ideograph>) 18627 0x9EB6 麶 (<CJK Ideograph>) 18628 0x9EF0 黰 (<CJK Ideograph>) 18629 0x9F35 鼵 (<CJK Ideograph>) 18630 0x9F33 鼳 (<CJK Ideograph>) 18631 0x9F32 鼲 (<CJK Ideograph>) 18632 0x9F42 齂 (<CJK Ideograph>) 18633 0x9F6B 齫 (<CJK Ideograph>) 18634 0x9F95 龕 (<CJK Ideograph>) 18635 0x9FA2 龢 (<CJK Ideograph>) 18636 0x513D 儽 (<CJK Ideograph>) 18637 0x5299 劙 (<CJK Ideograph>) 18638 0x58E8 壨 (<CJK Ideograph>) 18639 0x58E7 壧 (<CJK Ideograph>) 18640 0x5972 奲 (<CJK Ideograph>) 18641 0x5B4D 孍 (<CJK Ideograph>) 18642 0x5DD8 巘 (<CJK Ideograph>) 18643 0x882F 蠯 (<CJK Ideograph>) 18644 0x5F4F 彏 (<CJK Ideograph>) 18645 0x6201 戁 (<CJK Ideograph>) 18646 0x6203 戃 (<CJK Ideograph>) 18647 0x6204 戄 (<CJK Ideograph>) 18648 0x6529 攩 (<CJK Ideograph>) 18649 0x6525 攥 (<CJK Ideograph>) 18650 0x6596 斖 (<CJK Ideograph>) 18651 0x66EB 曫 (<CJK Ideograph>) 18652 0x6B11 欑 (<CJK Ideograph>) 18653 0x6B12 欒 (<CJK Ideograph>) 18654 0x6B0F 欏 (<CJK Ideograph>) 18655 0x6BCA 毊 (<CJK Ideograph>) 18656 0x705B 灛 (<CJK Ideograph>) 18657 0x705A 灚 (<CJK Ideograph>) 18658 0x7222 爢 (<CJK Ideograph>) 18659 0x7382 玂 (<CJK Ideograph>) 18660 0x7381 玁 (<CJK Ideograph>) 18661 0x7383 玃 (<CJK Ideograph>) 18662 0x7670 癰 (<CJK Ideograph>) 18663 0x77D4 矔 (<CJK Ideograph>) 18664 0x7C67 籧 (<CJK Ideograph>) 18665 0x7C66 籦 (<CJK Ideograph>) 18666 0x7E95 纕 (<CJK Ideograph>) 18667 0x826C 艬 (<CJK Ideograph>) 18668 0x863A 蘺 (<CJK Ideograph>) 18669 0x8640 虀 (<CJK Ideograph>) 18670 0x8639 蘹 (<CJK Ideograph>) 18671 0x863C 蘼 (<CJK Ideograph>) 18672 0x8631 蘱 (<CJK Ideograph>) 18673 0x863B 蘻 (<CJK Ideograph>) 18674 0x863E 蘾 (<CJK Ideograph>) 18675 0x8830 蠰 (<CJK Ideograph>) 18676 0x8832 蠲 (<CJK Ideograph>) 18677 0x882E 蠮 (<CJK Ideograph>) 18678 0x8833 蠳 (<CJK Ideograph>) 18679 0x8976 襶 (<CJK Ideograph>) 18680 0x8974 襴 (<CJK Ideograph>) 18681 0x8973 襳 (<CJK Ideograph>) 18682 0x89FE 觾 (<CJK Ideograph>) 18683 0x8B8C 讌 (<CJK Ideograph>) 18684 0x8B8E 讎 (<CJK Ideograph>) 18685 0x8B8B 讋 (<CJK Ideograph>) 18686 0x8B88 讈 (<CJK Ideograph>) 18687 0x8C45 豅 (<CJK Ideograph>) 18688 0x8D19 贙 (<CJK Ideograph>) 18689 0x8E98 躘 (<CJK Ideograph>) 18690 0x8F64 轤 (<CJK Ideograph>) 18691 0x8F63 轣 (<CJK Ideograph>) 18692 0x91BC 醼 (<CJK Ideograph>) 18693 0x9462 鑢 (<CJK Ideograph>) 18694 0x9455 鑕 (<CJK Ideograph>) 18695 0x945D 鑝 (<CJK Ideograph>) 18696 0x9457 鑗 (<CJK Ideograph>) 18697 0x945E 鑞 (<CJK Ideograph>) 18698 0x97C4 韄 (<CJK Ideograph>) 18699 0x97C5 韅 (<CJK Ideograph>) 18700 0x9800 頀 (<CJK Ideograph>) 18701 0x9A56 驖 (<CJK Ideograph>) 18702 0x9A59 驙 (<CJK Ideograph>) 18703 0x9B1E 鬞 (<CJK Ideograph>) 18704 0x9B1F 鬟 (<CJK Ideograph>) 18705 0x9B20 鬠 (<CJK Ideograph>) 18706 0x9C52 鱒 (<CJK Ideograph>) 18707 0x9C58 鱘 (<CJK Ideograph>) 18708 0x9C50 鱐 (<CJK Ideograph>) 18709 0x9C4A 鱊 (<CJK Ideograph>) 18710 0x9C4D 鱍 (<CJK Ideograph>) 18711 0x9C4B 鱋 (<CJK Ideograph>) 18712 0x9C55 鱕 (<CJK Ideograph>) 18713 0x9C59 鱙 (<CJK Ideograph>) 18714 0x9C4C 鱌 (<CJK Ideograph>) 18715 0x9C4E 鱎 (<CJK Ideograph>) 18716 0x9DFB 鷻 (<CJK Ideograph>) 18717 0x9DF7 鷷 (<CJK Ideograph>) 18718 0x9DEF 鷯 (<CJK Ideograph>) 18719 0x9DE3 鷣 (<CJK Ideograph>) 18720 0x9DEB 鷫 (<CJK Ideograph>) 18721 0x9DF8 鷸 (<CJK Ideograph>) 18722 0x9DE4 鷤 (<CJK Ideograph>) 18723 0x9DF6 鷶 (<CJK Ideograph>) 18724 0x9DE1 鷡 (<CJK Ideograph>) 18725 0x9DEE 鷮 (<CJK Ideograph>) 18726 0x9DE6 鷦 (<CJK Ideograph>) 18727 0x9DF2 鷲 (<CJK Ideograph>) 18728 0x9DF0 鷰 (<CJK Ideograph>) 18729 0x9DE2 鷢 (<CJK Ideograph>) 18730 0x9DEC 鷬 (<CJK Ideograph>) 18731 0x9DF4 鷴 (<CJK Ideograph>) 18732 0x9DF3 鷳 (<CJK Ideograph>) 18733 0x9DE8 鷨 (<CJK Ideograph>) 18734 0x9DED 鷭 (<CJK Ideograph>) 18735 0x9EC2 黂 (<CJK Ideograph>) 18736 0x9ED0 黐 (<CJK Ideograph>) 18737 0x9EF2 黲 (<CJK Ideograph>) 18738 0x9EF3 黳 (<CJK Ideograph>) 18739 0x9F06 鼆 (<CJK Ideograph>) 18740 0x9F1C 鼜 (<CJK Ideograph>) 18741 0x9F38 鼸 (<CJK Ideograph>) 18742 0x9F37 鼷 (<CJK Ideograph>) 18743 0x9F36 鼶 (<CJK Ideograph>) 18744 0x9F43 齃 (<CJK Ideograph>) 18745 0x9F4F 齏 (<CJK Ideograph>) 18746 0x9F71 齱 (<CJK Ideograph>) 18747 0x9F70 齰 (<CJK Ideograph>) 18748 0x9F6E 齮 (<CJK Ideograph>) 18749 0x9F6F 齯 (<CJK Ideograph>) 18750 0x56D3 囓 (<CJK Ideograph>) 18751 0x56CD 囍 (<CJK Ideograph>) 18752 0x5B4E 孎 (<CJK Ideograph>) 18753 0x5C6D 屭 (<CJK Ideograph>) 18754 0x652D 攭 (<CJK Ideograph>) 18755 0x66ED 曭 (<CJK Ideograph>) 18756 0x66EE 曮 (<CJK Ideograph>) 18757 0x6B13 欓 (<CJK Ideograph>) 18758 0x705F 灟 (<CJK Ideograph>) 18759 0x7061 灡 (<CJK Ideograph>) 18760 0x705D 灝 (<CJK Ideograph>) 18761 0x7060 灠 (<CJK Ideograph>) 18762 0x7223 爣 (<CJK Ideograph>) 18763 0x74DB 瓛 (<CJK Ideograph>) 18764 0x74E5 瓥 (<CJK Ideograph>) 18765 0x77D5 矕 (<CJK Ideograph>) 18766 0x7938 礸 (<CJK Ideograph>) 18767 0x79B7 禷 (<CJK Ideograph>) 18768 0x79B6 禶 (<CJK Ideograph>) 18769 0x7C6A 籪 (<CJK Ideograph>) 18770 0x7E97 纗 (<CJK Ideograph>) 18771 0x7F89 羉 (<CJK Ideograph>) 18772 0x826D 艭 (<CJK Ideograph>) 18773 0x8643 虃 (<CJK Ideograph>) 18774 0x8838 蠸 (<CJK Ideograph>) 18775 0x8837 蠷 (<CJK Ideograph>) 18776 0x8835 蠵 (<CJK Ideograph>) 18777 0x884B 衋 (<CJK Ideograph>) 18778 0x8B94 讔 (<CJK Ideograph>) 18779 0x8B95 讕 (<CJK Ideograph>) 18780 0x8E9E 躞 (<CJK Ideograph>) 18781 0x8E9F 躟 (<CJK Ideograph>) 18782 0x8EA0 躠 (<CJK Ideograph>) 18783 0x8E9D 躝 (<CJK Ideograph>) 18784 0x91BE 醾 (<CJK Ideograph>) 18785 0x91BD 醽 (<CJK Ideograph>) 18786 0x91C2 釂 (<CJK Ideograph>) 18787 0x946B 鑫 (<CJK Ideograph>) 18788 0x9468 鑨 (<CJK Ideograph>) 18789 0x9469 鑩 (<CJK Ideograph>) 18790 0x96E5 雥 (<CJK Ideograph>) 18791 0x9746 靆 (<CJK Ideograph>) 18792 0x9743 靃 (<CJK Ideograph>) 18793 0x9747 靇 (<CJK Ideograph>) 18794 0x97C7 韇 (<CJK Ideograph>) 18795 0x97E5 韥 (<CJK Ideograph>) 18796 0x9A5E 驞 (<CJK Ideograph>) 18797 0x9AD5 髕 (<CJK Ideograph>) 18798 0x9B59 魙 (<CJK Ideograph>) 18799 0x9C63 鱣 (<CJK Ideograph>) 18800 0x9C67 鱧 (<CJK Ideograph>) 18801 0x9C66 鱦 (<CJK Ideograph>) 18802 0x9C62 鱢 (<CJK Ideograph>) 18803 0x9C5E 鱞 (<CJK Ideograph>) 18804 0x9C60 鱠 (<CJK Ideograph>) 18805 0x9E02 鸂 (<CJK Ideograph>) 18806 0x9DFE 鷾 (<CJK Ideograph>) 18807 0x9E07 鸇 (<CJK Ideograph>) 18808 0x9E03 鸃 (<CJK Ideograph>) 18809 0x9E06 鸆 (<CJK Ideograph>) 18810 0x9E05 鸅 (<CJK Ideograph>) 18811 0x9E00 鸀 (<CJK Ideograph>) 18812 0x9E01 鸁 (<CJK Ideograph>) 18813 0x9E09 鸉 (<CJK Ideograph>) 18814 0x9DFF 鷿 (<CJK Ideograph>) 18815 0x9DFD 鷽 (<CJK Ideograph>) 18816 0x9E04 鸄 (<CJK Ideograph>) 18817 0x9EA0 麠 (<CJK Ideograph>) 18818 0x9F1E 鼞 (<CJK Ideograph>) 18819 0x9F46 齆 (<CJK Ideograph>) 18820 0x9F74 齴 (<CJK Ideograph>) 18821 0x9F75 齵 (<CJK Ideograph>) 18822 0x9F76 齶 (<CJK Ideograph>) 18823 0x56D4 囔 (<CJK Ideograph>) 18824 0x652E 攮 (<CJK Ideograph>) 18825 0x65B8 斸 (<CJK Ideograph>) 18826 0x6B18 欘 (<CJK Ideograph>) 18827 0x6B19 欙 (<CJK Ideograph>) 18828 0x6B17 欗 (<CJK Ideograph>) 18829 0x6B1A 欚 (<CJK Ideograph>) 18830 0x7062 灢 (<CJK Ideograph>) 18831 0x7226 爦 (<CJK Ideograph>) 18832 0x72AA 犪 (<CJK Ideograph>) 18833 0x77D8 矘 (<CJK Ideograph>) 18834 0x77D9 矙 (<CJK Ideograph>) 18835 0x7939 礹 (<CJK Ideograph>) 18836 0x7C69 籩 (<CJK Ideograph>) 18837 0x7C6B 籫 (<CJK Ideograph>) 18838 0x7CF6 糶 (<CJK Ideograph>) 18839 0x7E9A 纚 (<CJK Ideograph>) 18840 0x7E98 纘 (<CJK Ideograph>) 18841 0x7E9B 纛 (<CJK Ideograph>) 18842 0x7E99 纙 (<CJK Ideograph>) 18843 0x81E0 臠 (<CJK Ideograph>) 18844 0x81E1 臡 (<CJK Ideograph>) 18845 0x8646 虆 (<CJK Ideograph>) 18846 0x8647 虇 (<CJK Ideograph>) 18847 0x8648 虈 (<CJK Ideograph>) 18848 0x8979 襹 (<CJK Ideograph>) 18849 0x897A 襺 (<CJK Ideograph>) 18850 0x897C 襼 (<CJK Ideograph>) 18851 0x897B 襻 (<CJK Ideograph>) 18852 0x89FF 觿 (<CJK Ideograph>) 18853 0x8B98 讘 (<CJK Ideograph>) 18854 0x8B99 讙 (<CJK Ideograph>) 18855 0x8EA5 躥 (<CJK Ideograph>) 18856 0x8EA4 躤 (<CJK Ideograph>) 18857 0x8EA3 躣 (<CJK Ideograph>) 18858 0x946E 鑮 (<CJK Ideograph>) 18859 0x946D 鑭 (<CJK Ideograph>) 18860 0x946F 鑯 (<CJK Ideograph>) 18861 0x9471 鑱 (<CJK Ideograph>) 18862 0x9473 鑳 (<CJK Ideograph>) 18863 0x9749 靉 (<CJK Ideograph>) 18864 0x9872 顲 (<CJK Ideograph>) 18865 0x995F 饟 (<CJK Ideograph>) 18866 0x9C68 鱨 (<CJK Ideograph>) 18867 0x9C6E 鱮 (<CJK Ideograph>) 18868 0x9C6D 鱭 (<CJK Ideograph>) 18869 0x9E0B 鸋 (<CJK Ideograph>) 18870 0x9E0D 鸍 (<CJK Ideograph>) 18871 0x9E10 鸐 (<CJK Ideograph>) 18872 0x9E0F 鸏 (<CJK Ideograph>) 18873 0x9E12 鸒 (<CJK Ideograph>) 18874 0x9E11 鸑 (<CJK Ideograph>) 18875 0x9EA1 麡 (<CJK Ideograph>) 18876 0x9EF5 黵 (<CJK Ideograph>) 18877 0x9F09 鼉 (<CJK Ideograph>) 18878 0x9F47 齇 (<CJK Ideograph>) 18879 0x9F78 齸 (<CJK Ideograph>) 18880 0x9F7B 齻 (<CJK Ideograph>) 18881 0x9F7A 齺 (<CJK Ideograph>) 18882 0x9F79 齹 (<CJK Ideograph>) 18883 0x571E 圞 (<CJK Ideograph>) 18884 0x7066 灦 (<CJK Ideograph>) 18885 0x7C6F 籯 (<CJK Ideograph>) 18886 0x883C 蠼 (<CJK Ideograph>) 18887 0x8DB2 趲 (<CJK Ideograph>) 18888 0x8EA6 躦 (<CJK Ideograph>) 18889 0x91C3 釃 (<CJK Ideograph>) 18890 0x9474 鑴 (<CJK Ideograph>) 18891 0x9478 鑸 (<CJK Ideograph>) 18892 0x9476 鑶 (<CJK Ideograph>) 18893 0x9475 鑵 (<CJK Ideograph>) 18894 0x9A60 驠 (<CJK Ideograph>) 18895 0x9C74 鱴 (<CJK Ideograph>) 18896 0x9C73 鱳 (<CJK Ideograph>) 18897 0x9C71 鱱 (<CJK Ideograph>) 18898 0x9C75 鱵 (<CJK Ideograph>) 18899 0x9E14 鸔 (<CJK Ideograph>) 18900 0x9E13 鸓 (<CJK Ideograph>) 18901 0x9EF6 黶 (<CJK Ideograph>) 18902 0x9F0A 鼊 (<CJK Ideograph>) 18903 0x9FA4 龤 (<CJK Ideograph>) 18904 0x7068 灨 (<CJK Ideograph>) 18905 0x7065 灥 (<CJK Ideograph>) 18906 0x7CF7 糷 (<CJK Ideograph>) 18907 0x866A 虪 (<CJK Ideograph>) 18908 0x883E 蠾 (<CJK Ideograph>) 18909 0x883D 蠽 (<CJK Ideograph>) 18910 0x883F 蠿 (<CJK Ideograph>) 18911 0x8B9E 讞 (<CJK Ideograph>) 18912 0x8C9C 貜 (<CJK Ideograph>) 18913 0x8EA9 躩 (<CJK Ideograph>) 18914 0x8EC9 軉 (<CJK Ideograph>) 18915 0x974B 靋 (<CJK Ideograph>) 18916 0x9873 顳 (<CJK Ideograph>) 18917 0x9874 顴 (<CJK Ideograph>) 18918 0x98CC 飌 (<CJK Ideograph>) 18919 0x9961 饡 (<CJK Ideograph>) 18920 0x99AB 馫 (<CJK Ideograph>) 18921 0x9A64 驤 (<CJK Ideograph>) 18922 0x9A66 驦 (<CJK Ideograph>) 18923 0x9A67 驧 (<CJK Ideograph>) 18924 0x9B24 鬤 (<CJK Ideograph>) 18925 0x9E15 鸕 (<CJK Ideograph>) 18926 0x9E17 鸗 (<CJK Ideograph>) 18927 0x9F48 齈 (<CJK Ideograph>) 18928 0x6207 戇 (<CJK Ideograph>) 18929 0x6B1E 欞 (<CJK Ideograph>) 18930 0x7227 爧 (<CJK Ideograph>) 18931 0x864C 虌 (<CJK Ideograph>) 18932 0x8EA8 躨 (<CJK Ideograph>) 18933 0x9482 钂 (<CJK Ideograph>) 18934 0x9480 钀 (<CJK Ideograph>) 18935 0x9481 钁 (<CJK Ideograph>) 18936 0x9A69 驩 (<CJK Ideograph>) 18937 0x9A68 驨 (<CJK Ideograph>) 18938 0x9B2E 鬮 (<CJK Ideograph>) 18939 0x9E19 鸙 (<CJK Ideograph>) 18940 0x7229 爩 (<CJK Ideograph>) 18941 0x864B 虋 (<CJK Ideograph>) 18942 0x8B9F 讟 (<CJK Ideograph>) 18943 0x9483 钃 (<CJK Ideograph>) 18944 0x9C79 鱹 (<CJK Ideograph>) 18945 0x9EB7 麷 (<CJK Ideograph>) 18946 0x7675 癵 (<CJK Ideograph>) 18947 0x9A6B 驫 (<CJK Ideograph>) 18948 0x9C7A 鱺 (<CJK Ideograph>) 18949 0x9E1D 鸝 (<CJK Ideograph>) 18950 0x7069 灩 (<CJK Ideograph>) 18951 0x706A 灪 (<CJK Ideograph>) 18952 0x9EA4 麤 (<CJK Ideograph>) 18953 0x9F7E 齾 (<CJK Ideograph>) 18954 0x9F49 齉 (<CJK Ideograph>) 18955 0x9F98 龘 (<CJK Ideograph>) 18956 0x7881 碁 (<CJK Ideograph>) 18957 0x92B9 銹 (<CJK Ideograph>) 18958 0x88CF 裏 (<CJK Ideograph>) 18959 0x58BB 墻 (<CJK Ideograph>) 18960 0x6052 恒 (<CJK Ideograph>) 18961 0x7CA7 粧 (<CJK Ideograph>) 18962 0x5AFA 嫺 (<CJK Ideograph>) 18963 0x2554 ╔ (BOX DRAWINGS DOUBLE DOWN AND RIGHT) 18964 0x2566 ╦ (BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL) 18965 0x2557 ╗ (BOX DRAWINGS DOUBLE DOWN AND LEFT) 18966 0x2560 ╠ (BOX DRAWINGS DOUBLE VERTICAL AND RIGHT) 18967 0x256C ╬ (BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL) 18968 0x2563 ╣ (BOX DRAWINGS DOUBLE VERTICAL AND LEFT) 18969 0x255A ╚ (BOX DRAWINGS DOUBLE UP AND RIGHT) 18970 0x2569 ╩ (BOX DRAWINGS DOUBLE UP AND HORIZONTAL) 18971 0x255D ╝ (BOX DRAWINGS DOUBLE UP AND LEFT) 18972 0x2552 ╒ (BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE) 18973 0x2564 ╤ (BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE) 18974 0x2555 ╕ (BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE) 18975 0x255E ╞ (BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE) 18976 0x256A ╪ (BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE) 18977 0x2561 ╡ (BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE) 18978 0x2558 ╘ (BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE) 18979 0x2567 ╧ (BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE) 18980 0x255B ╛ (BOX DRAWINGS UP SINGLE AND LEFT DOUBLE) 18981 0x2553 ╓ (BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE) 18982 0x2565 ╥ (BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE) 18983 0x2556 ╖ (BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE) 18984 0x255F ╟ (BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE) 18985 0x256B ╫ (BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE) 18986 0x2562 ╢ (BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE) 18987 0x2559 ╙ (BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE) 18988 0x2568 ╨ (BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE) 18989 0x255C ╜ (BOX DRAWINGS UP DOUBLE AND LEFT SINGLE) 18990 0x2551 ║ (BOX DRAWINGS DOUBLE VERTICAL) 18991 0x2550 ═ (BOX DRAWINGS DOUBLE HORIZONTAL) 18992 0x256D ╭ (BOX DRAWINGS LIGHT ARC DOWN AND RIGHT) 18993 0x256E ╮ (BOX DRAWINGS LIGHT ARC DOWN AND LEFT) 18994 0x2570 ╰ (BOX DRAWINGS LIGHT ARC UP AND RIGHT) 18995 0x256F ╯ (BOX DRAWINGS LIGHT ARC UP AND LEFT) 18996 0xFFED ■ (HALFWIDTH BLACK SQUARE) 18997 0x20547 𠕇 (<CJK Ideograph Extension B>) 18998 0x92DB 鋛 (<CJK Ideograph>) 18999 0x205DF 𠗟 (<CJK Ideograph Extension B>) 19000 0x23FC5 𣿅 (<CJK Ideograph Extension B>) 19001 0x854C 蕌 (<CJK Ideograph>) 19002 0x42B5 䊵 (<CJK Ideograph Extension A>) 19003 0x73EF 珯 (<CJK Ideograph>) 19004 0x51B5 况 (<CJK Ideograph>) 19005 0x3649 㙉 (<CJK Ideograph Extension A>) 19006 0x24942 𤥂 (<CJK Ideograph Extension B>) 19007 0x289E4 𨧤 (<CJK Ideograph Extension B>) 19008 0x9344 鍄 (<CJK Ideograph>) 19009 0x219DB 𡧛 (<CJK Ideograph Extension B>) 19010 0x82EE 苮 (<CJK Ideograph>) 19011 0x23CC8 𣳈 (<CJK Ideograph Extension B>) 19012 0x783C 砼 (<CJK Ideograph>) 19013 0x6744 杄 (<CJK Ideograph>) 19014 0x62DF 拟 (<CJK Ideograph>) 19015 0x24933 𤤳 (<CJK Ideograph Extension B>) 19016 0x289AA 𨦪 (<CJK Ideograph Extension B>) 19017 0x202A0 𠊠 (<CJK Ideograph Extension B>) 19018 0x26BB3 𦮳 (<CJK Ideograph Extension B>) 19019 0x21305 𡌅 (<CJK Ideograph Extension B>) 19020 0x4FAB 侫 (<CJK Ideograph>) 19021 0x224ED 𢓭 (<CJK Ideograph Extension B>) 19022 0x5008 倈 (<CJK Ideograph>) 19023 0x26D29 𦴩 (<CJK Ideograph Extension B>) 19024 0x27A84 𧪄 (<CJK Ideograph Extension B>) 19025 0x23600 𣘀 (<CJK Ideograph Extension B>) 19026 0x24AB1 𤪱 (<CJK Ideograph Extension B>) 19027 0x22513 𢔓 (<CJK Ideograph Extension B>) 19028 0x5029 倩 (<CJK Ideograph>) 19029 0x2037E 𠍾 (<CJK Ideograph Extension B>) 19030 0x5FA4 徤 (<CJK Ideograph>) 19031 0x20380 𠎀 (<CJK Ideograph Extension B>) 19032 0x20347 𠍇 (<CJK Ideograph Extension B>) 19033 0x6EDB 滛 (<CJK Ideograph>) 19034 0x2041F 𠐟 (<CJK Ideograph Extension B>) 19035 0x507D 偽 (<CJK Ideograph>) 19036 0x5101 儁 (<CJK Ideograph>) 19037 0x347A 㑺 (<CJK Ideograph Extension A>) 19038 0x510E 儎 (<CJK Ideograph>) 19039 0x986C 顬 (<CJK Ideograph>) 19040 0x3743 㝃 (<CJK Ideograph Extension A>) 19041 0x8416 萖 (<CJK Ideograph>) 19042 0x249A4 𤦤 (<CJK Ideograph Extension B>) 19043 0x20487 𠒇 (<CJK Ideograph Extension B>) 19044 0x5160 兠 (<CJK Ideograph>) 19045 0x233B4 𣎴 (<CJK Ideograph Extension B>) 19046 0x516A 兪 (<CJK Ideograph>) 19047 0x20BFF 𠯿 (<CJK Ideograph Extension B>) 19048 0x220FC 𢃼 (<CJK Ideograph Extension B>) 19049 0x202E5 𠋥 (<CJK Ideograph Extension B>) 19050 0x22530 𢔰 (<CJK Ideograph Extension B>) 19051 0x2058E 𠖎 (<CJK Ideograph Extension B>) 19052 0x23233 𣈳 (<CJK Ideograph Extension B>) 19053 0x21983 𡦃 (<CJK Ideograph Extension B>) 19054 0x5B82 宂 (<CJK Ideograph>) 19055 0x877D 蝽 (<CJK Ideograph>) 19056 0x205B3 𠖳 (<CJK Ideograph Extension B>) 19057 0x23C99 𣲙 (<CJK Ideograph Extension B>) 19058 0x51B2 冲 (<CJK Ideograph>) 19059 0x51B8 冸 (<CJK Ideograph>) 19060 0x9D34 鴴 (<CJK Ideograph>) 19061 0x51C9 凉 (<CJK Ideograph>) 19062 0x51CF 减 (<CJK Ideograph>) 19063 0x51D1 凑 (<CJK Ideograph>) 19064 0x3CDC 㳜 (<CJK Ideograph Extension A>) 19065 0x51D3 凓 (<CJK Ideograph>) 19066 0x24AA6 𤪦 (<CJK Ideograph Extension B>) 19067 0x51B3 决 (<CJK Ideograph>) 19068 0x51E2 凢 (<CJK Ideograph>) 19069 0x5342 卂 (<CJK Ideograph>) 19070 0x51ED 凭 (<CJK Ideograph>) 19071 0x83CD 菍 (<CJK Ideograph>) 19072 0x693E 椾 (<CJK Ideograph>) 19073 0x2372D 𣜭 (<CJK Ideograph Extension B>) 19074 0x5F7B 彻 (<CJK Ideograph>) 19075 0x520B 刋 (<CJK Ideograph>) 19076 0x5226 刦 (<CJK Ideograph>) 19077 0x523C 刼 (<CJK Ideograph>) 19078 0x52B5 劵 (<CJK Ideograph>) 19079 0x5257 剗 (<CJK Ideograph>) 19080 0x5294 劔 (<CJK Ideograph>) 19081 0x52B9 効 (<CJK Ideograph>) 19082 0x52C5 勅 (<CJK Ideograph>) 19083 0x7C15 簕 (<CJK Ideograph>) 19084 0x8542 蕂 (<CJK Ideograph>) 19085 0x52E0 勠 (<CJK Ideograph>) 19086 0x860D 蘍 (<CJK Ideograph>) 19087 0x26B13 𦬓 (<CJK Ideograph Extension B>) 19088 0x5305 包 (<CJK Ideograph>) 19089 0x28ADE 𨫞 (<CJK Ideograph Extension B>) 19090 0x5549 啉 (<CJK Ideograph>) 19091 0x6ED9 滙 (<CJK Ideograph>) 19092 0x23F80 𣾀 (<CJK Ideograph Extension B>) 19093 0x20954 𠥔 (<CJK Ideograph Extension B>) 19094 0x23FEC 𣿬 (<CJK Ideograph Extension B>) 19095 0x5333 匳 (<CJK Ideograph>) 19096 0x5344 卄 (<CJK Ideograph>) 19097 0x20BE2 𠯢 (<CJK Ideograph Extension B>) 19098 0x6CCB 泋 (<CJK Ideograph>) 19099 0x21726 𡜦 (<CJK Ideograph Extension B>) 19100 0x681B 栛 (<CJK Ideograph>) 19101 0x73D5 珕 (<CJK Ideograph>) 19102 0x604A 恊 (<CJK Ideograph>) 19103 0x3EAA 㺪 (<CJK Ideograph Extension A>) 19104 0x38CC 㣌 (<CJK Ideograph Extension A>) 19105 0x216E8 𡛨 (<CJK Ideograph Extension B>) 19106 0x71DD 燝 (<CJK Ideograph>) 19107 0x44A2 䒢 (<CJK Ideograph Extension A>) 19108 0x536D 卭 (<CJK Ideograph>) 19109 0x5374 却 (<CJK Ideograph>) 19110 0x286AB 𨚫 (<CJK Ideograph Extension B>) 19111 0x537E 卾 (<CJK Ideograph>) 19112 0x537F 卿 (<CJK Ideograph>) 19113 0x21596 𡖖 (<CJK Ideograph Extension B>) 19114 0x21613 𡘓 (<CJK Ideograph Extension B>) 19115 0x77E6 矦 (<CJK Ideograph>) 19116 0x5393 厓 (<CJK Ideograph>) 19117 0x28A9B 𨪛 (<CJK Ideograph Extension B>) 19118 0x53A0 厠 (<CJK Ideograph>) 19119 0x53AB 厫 (<CJK Ideograph>) 19120 0x53AE 厮 (<CJK Ideograph>) 19121 0x73A7 玧 (<CJK Ideograph>) 19122 0x25772 𥝲 (<CJK Ideograph Extension B>) 19123 0x3F59 㽙 (<CJK Ideograph Extension A>) 19124 0x739C 玜 (<CJK Ideograph>) 19125 0x53C1 叁 (<CJK Ideograph>) 19126 0x53C5 叅 (<CJK Ideograph>) 19127 0x6C49 汉 (<CJK Ideograph>) 19128 0x4E49 义 (<CJK Ideograph>) 19129 0x57FE 埾 (<CJK Ideograph>) 19130 0x53D9 叙 (<CJK Ideograph>) 19131 0x3AAB 㪫 (<CJK Ideograph Extension A>) 19132 0x20B8F 𠮏 (<CJK Ideograph Extension B>) 19133 0x53E0 叠 (<CJK Ideograph>) 19134 0x23FEB 𣿫 (<CJK Ideograph Extension B>) 19135 0x22DA3 𢶣 (<CJK Ideograph Extension B>) 19136 0x53F6 叶 (<CJK Ideograph>) 19137 0x20C77 𠱷 (<CJK Ideograph Extension B>) 19138 0x5413 吓 (<CJK Ideograph>) 19139 0x7079 灹 (<CJK Ideograph>) 19140 0x552B 唫 (<CJK Ideograph>) 19141 0x6657 晗 (<CJK Ideograph>) 19142 0x6D5B 浛 (<CJK Ideograph>) 19143 0x546D 呭 (<CJK Ideograph>) 19144 0x26B53 𦭓 (<CJK Ideograph Extension B>) 19145 0x20D74 𠵴 (<CJK Ideograph Extension B>) 19146 0x555D 啝 (<CJK Ideograph>) 19147 0x548F 咏 (<CJK Ideograph>) 19148 0x54A4 咤 (<CJK Ideograph>) 19149 0x47A6 䞦 (<CJK Ideograph Extension A>) 19150 0x2170D 𡜍 (<CJK Ideograph Extension B>) 19151 0x20EDD 𠻝 (<CJK Ideograph Extension B>) 19152 0x3DB4 㶴 (<CJK Ideograph Extension A>) 19153 0x20D4D 𠵍 (<CJK Ideograph Extension B>) 19154 0x289BC 𨦼 (<CJK Ideograph Extension B>) 19155 0x22698 𢚘 (<CJK Ideograph Extension B>) 19156 0x5547 啇 (<CJK Ideograph>) 19157 0x4CED 䳭 (<CJK Ideograph Extension A>) 19158 0x542F 启 (<CJK Ideograph>) 19159 0x7417 琗 (<CJK Ideograph>) 19160 0x5586 喆 (<CJK Ideograph>) 19161 0x55A9 喩 (<CJK Ideograph>) 19162 0x5605 嘅 (<CJK Ideograph>) 19163 0x218D7 𡣗 (<CJK Ideograph Extension B>) 19164 0x2403A 𤀺 (<CJK Ideograph Extension B>) 19165 0x4552 䕒 (<CJK Ideograph Extension A>) 19166 0x24435 𤐵 (<CJK Ideograph Extension B>) 19167 0x66B3 暳 (<CJK Ideograph>) 19168 0x210B4 𡂴 (<CJK Ideograph Extension B>) 19169 0x5637 嘷 (<CJK Ideograph>) 19170 0x66CD 曍 (<CJK Ideograph>) 19171 0x2328A 𣊊 (<CJK Ideograph Extension B>) 19172 0x66A4 暤 (<CJK Ideograph>) 19173 0x66AD 暭 (<CJK Ideograph>) 19174 0x564D 噍 (<CJK Ideograph>) 19175 0x564F 噏 (<CJK Ideograph>) 19176 0x78F1 磱 (<CJK Ideograph>) 19177 0x56F1 囱 (<CJK Ideograph>) 19178 0x9787 鞇 (<CJK Ideograph>) 19179 0x53FE 叾 (<CJK Ideograph>) 19180 0x5700 圀 (<CJK Ideograph>) 19181 0x56EF 囯 (<CJK Ideograph>) 19182 0x56ED 园 (<CJK Ideograph>) 19183 0x28B66 𨭦 (<CJK Ideograph Extension B>) 19184 0x3623 㘣 (<CJK Ideograph Extension A>) 19185 0x2124F 𡉏 (<CJK Ideograph Extension B>) 19186 0x5746 坆 (<CJK Ideograph>) 19187 0x241A5 𤆥 (<CJK Ideograph Extension B>) 19188 0x6C6E 汮 (<CJK Ideograph>) 19189 0x708B 炋 (<CJK Ideograph>) 19190 0x5742 坂 (<CJK Ideograph>) 19191 0x36B1 㚱 (<CJK Ideograph Extension A>) 19192 0x26C7E 𦱾 (<CJK Ideograph Extension B>) 19193 0x57E6 埦 (<CJK Ideograph>) 19194 0x21416 𡐖 (<CJK Ideograph Extension B>) 19195 0x5803 堃 (<CJK Ideograph>) 19196 0x21454 𡑔 (<CJK Ideograph Extension B>) 19197 0x24363 𤍣 (<CJK Ideograph Extension B>) 19198 0x5826 堦 (<CJK Ideograph>) 19199 0x24BF5 𤯵 (<CJK Ideograph Extension B>) 19200 0x585C 塜 (<CJK Ideograph>) 19201 0x58AA 墪 (<CJK Ideograph>) 19202 0x3561 㕡 (<CJK Ideograph Extension A>) 19203 0x58E0 壠 (<CJK Ideograph>) 19204 0x58DC 壜 (<CJK Ideograph>) 19205 0x2123C 𡈼 (<CJK Ideograph Extension B>) 19206 0x58FB 壻 (<CJK Ideograph>) 19207 0x5BFF 寿 (<CJK Ideograph>) 19208 0x5743 坃 (<CJK Ideograph>) 19209 0x2A150 𪅐 (<CJK Ideograph Extension B>) 19210 0x24278 𤉸 (<CJK Ideograph Extension B>) 19211 0x93D3 鏓 (<CJK Ideograph>) 19212 0x35A1 㖡 (<CJK Ideograph Extension A>) 19213 0x591F 够 (<CJK Ideograph>) 19214 0x68A6 梦 (<CJK Ideograph>) 19215 0x36C3 㛃 (<CJK Ideograph Extension A>) 19216 0x6E59 湙 (<CJK Ideograph>) 19217 0x2163E 𡘾 (<CJK Ideograph Extension B>) 19218 0x5A24 娤 (<CJK Ideograph>) 19219 0x5553 啓 (<CJK Ideograph>) 19220 0x21692 𡚒 (<CJK Ideograph Extension B>) 19221 0x8505 蔅 (<CJK Ideograph>) 19222 0x59C9 姉 (<CJK Ideograph>) 19223 0x20D4E 𠵎 (<CJK Ideograph Extension B>) 19224 0x26C81 𦲁 (<CJK Ideograph Extension B>) 19225 0x26D2A 𦴪 (<CJK Ideograph Extension B>) 19226 0x217DC 𡟜 (<CJK Ideograph Extension B>) 19227 0x59D9 姙 (<CJK Ideograph>) 19228 0x217FB 𡟻 (<CJK Ideograph Extension B>) 19229 0x217B2 𡞲 (<CJK Ideograph Extension B>) 19230 0x26DA6 𦶦 (<CJK Ideograph Extension B>) 19231 0x6D71 浱 (<CJK Ideograph>) 19232 0x21828 𡠨 (<CJK Ideograph Extension B>) 19233 0x216D5 𡛕 (<CJK Ideograph Extension B>) 19234 0x59F9 姹 (<CJK Ideograph>) 19235 0x26E45 𦹅 (<CJK Ideograph Extension B>) 19236 0x5AAB 媫 (<CJK Ideograph>) 19237 0x5A63 婣 (<CJK Ideograph>) 19238 0x36E6 㛦 (<CJK Ideograph Extension A>) 19239 0x249A9 𤦩 (<CJK Ideograph Extension B>) 19240 0x5A77 婷 (<CJK Ideograph>) 19241 0x3708 㜈 (<CJK Ideograph Extension A>) 19242 0x5A96 媖 (<CJK Ideograph>) 19243 0x7465 瑥 (<CJK Ideograph>) 19244 0x5AD3 嫓 (<CJK Ideograph>) 19245 0x26FA1 𦾡 (<CJK Ideograph Extension B>) 19246 0x22554 𢕔 (<CJK Ideograph Extension B>) 19247 0x3D85 㶅 (<CJK Ideograph Extension A>) 19248 0x21911 𡤑 (<CJK Ideograph Extension B>) 19249 0x3732 㜲 (<CJK Ideograph Extension A>) 19250 0x216B8 𡚸 (<CJK Ideograph Extension B>) 19251 0x5E83 広 (<CJK Ideograph>) 19252 0x52D0 勐 (<CJK Ideograph>) 19253 0x5B76 孶 (<CJK Ideograph>) 19254 0x6588 斈 (<CJK Ideograph>) 19255 0x5B7C 孼 (<CJK Ideograph>) 19256 0x27A0E 𧨎 (<CJK Ideograph Extension B>) 19257 0x4004 䀄 (<CJK Ideograph Extension A>) 19258 0x485D 䡝 (<CJK Ideograph Extension A>) 19259 0x20204 𠈄 (<CJK Ideograph Extension B>) 19260 0x5BD5 寕 (<CJK Ideograph>) 19261 0x6160 慠 (<CJK Ideograph>) 19262 0x21A34 𡨴 (<CJK Ideograph Extension B>) 19263 0x259CC 𥧌 (<CJK Ideograph Extension B>) 19264 0x205A5 𠖥 (<CJK Ideograph Extension B>) 19265 0x5BF3 寳 (<CJK Ideograph>) 19266 0x5B9D 宝 (<CJK Ideograph>) 19267 0x4D10 䴐 (<CJK Ideograph Extension A>) 19268 0x5C05 尅 (<CJK Ideograph>) 19269 0x21B44 𡭄 (<CJK Ideograph Extension B>) 19270 0x5C13 尓 (<CJK Ideograph>) 19271 0x73CE 珎 (<CJK Ideograph>) 19272 0x5C14 尔 (<CJK Ideograph>) 19273 0x21CA5 𡲥 (<CJK Ideograph Extension B>) 19274 0x26B28 𦬨 (<CJK Ideograph Extension B>) 19275 0x5C49 屉 (<CJK Ideograph>) 19276 0x48DD 䣝 (<CJK Ideograph Extension A>) 19277 0x5C85 岅 (<CJK Ideograph>) 19278 0x5CE9 峩 (<CJK Ideograph>) 19279 0x5CEF 峯 (<CJK Ideograph>) 19280 0x5D8B 嶋 (<CJK Ideograph>) 19281 0x21DF9 𡷹 (<CJK Ideograph Extension B>) 19282 0x21E37 𡸷 (<CJK Ideograph Extension B>) 19283 0x5D10 崐 (<CJK Ideograph>) 19284 0x5D18 崘 (<CJK Ideograph>) 19285 0x5D46 嵆 (<CJK Ideograph>) 19286 0x21EA4 𡺤 (<CJK Ideograph Extension B>) 19287 0x5CBA 岺 (<CJK Ideograph>) 19288 0x5DD7 巗 (<CJK Ideograph>) 19289 0x82FC 苼 (<CJK Ideograph>) 19290 0x382D 㠭 (<CJK Ideograph Extension A>) 19291 0x24901 𤤁 (<CJK Ideograph Extension B>) 19292 0x22049 𢁉 (<CJK Ideograph Extension B>) 19293 0x22173 𢅳 (<CJK Ideograph Extension B>) 19294 0x8287 芇 (<CJK Ideograph>) 19295 0x3836 㠶 (<CJK Ideograph Extension A>) 19296 0x3BC2 㯂 (<CJK Ideograph Extension A>) 19297 0x5E2E 帮 (<CJK Ideograph>) 19298 0x6A8A 檊 (<CJK Ideograph>) 19299 0x5E75 幵 (<CJK Ideograph>) 19300 0x5E7A 幺 (<CJK Ideograph>) 19301 0x244BC 𤒼 (<CJK Ideograph Extension B>) 19302 0x20CD3 𠳓 (<CJK Ideograph Extension B>) 19303 0x53A6 厦 (<CJK Ideograph>) 19304 0x4EB7 亷 (<CJK Ideograph>) 19305 0x5ED0 廐 (<CJK Ideograph>) 19306 0x53A8 厨 (<CJK Ideograph>) 19307 0x21771 𡝱 (<CJK Ideograph Extension B>) 19308 0x5E09 帉 (<CJK Ideograph>) 19309 0x5EF4 廴 (<CJK Ideograph>) 19310 0x28482 𨒂 (<CJK Ideograph Extension B>) 19311 0x5EF9 廹 (<CJK Ideograph>) 19312 0x5EFB 廻 (<CJK Ideograph>) 19313 0x38A0 㢠 (<CJK Ideograph Extension A>) 19314 0x5EFC 廼 (<CJK Ideograph>) 19315 0x683E 栾 (<CJK Ideograph>) 19316 0x941B 鐛 (<CJK Ideograph>) 19317 0x5F0D 弍 (<CJK Ideograph>) 19318 0x201C1 𠇁 (<CJK Ideograph Extension B>) 19319 0x2F894 弢 (CJK COMPATIBILITY IDEOGRAPH-2F894) 19320 0x3ADE 㫞 (<CJK Ideograph Extension A>) 19321 0x48AE 䢮 (<CJK Ideograph Extension A>) 19322 0x2133A 𡌺 (<CJK Ideograph Extension B>) 19323 0x5F3A 强 (<CJK Ideograph>) 19324 0x26888 𦢈 (<CJK Ideograph Extension B>) 19325 0x223D0 𢏐 (<CJK Ideograph Extension B>) 19326 0x5F58 彘 (<CJK Ideograph>) 19327 0x22471 𢑱 (<CJK Ideograph Extension B>) 19328 0x5F63 彣 (<CJK Ideograph>) 19329 0x97BD 鞽 (<CJK Ideograph>) 19330 0x26E6E 𦹮 (<CJK Ideograph Extension B>) 19331 0x5F72 彲 (<CJK Ideograph>) 19332 0x9340 鍀 (<CJK Ideograph>) 19333 0x28A36 𨨶 (<CJK Ideograph Extension B>) 19334 0x5FA7 徧 (<CJK Ideograph>) 19335 0x5DB6 嶶 (<CJK Ideograph>) 19336 0x3D5F 㵟 (<CJK Ideograph Extension A>) 19337 0x25250 𥉐 (<CJK Ideograph Extension B>) 19338 0x21F6A 𡽪 (<CJK Ideograph Extension B>) 19339 0x270F8 𧃸 (<CJK Ideograph Extension B>) 19340 0x22668 𢙨 (<CJK Ideograph Extension B>) 19341 0x91D6 釖 (<CJK Ideograph>) 19342 0x2029E 𠊞 (<CJK Ideograph Extension B>) 19343 0x28A29 𨨩 (<CJK Ideograph Extension B>) 19344 0x6031 怱 (<CJK Ideograph>) 19345 0x6685 暅 (<CJK Ideograph>) 19346 0x21877 𡡷 (<CJK Ideograph Extension B>) 19347 0x3963 㥣 (<CJK Ideograph Extension A>) 19348 0x3DC7 㷇 (<CJK Ideograph Extension A>) 19349 0x3639 㘹 (<CJK Ideograph Extension A>) 19350 0x5790 垐 (<CJK Ideograph>) 19351 0x227B4 𢞴 (<CJK Ideograph Extension B>) 19352 0x7971 祱 (<CJK Ideograph>) 19353 0x3E40 㹀 (<CJK Ideograph Extension A>) 19354 0x609E 悞 (<CJK Ideograph>) 19355 0x60A4 悤 (<CJK Ideograph>) 19356 0x60B3 悳 (<CJK Ideograph>) 19357 0x24982 𤦂 (<CJK Ideograph Extension B>) 19358 0x2498F 𤦏 (<CJK Ideograph Extension B>) 19359 0x27A53 𧩓 (<CJK Ideograph Extension B>) 19360 0x74A4 璤 (<CJK Ideograph>) 19361 0x50E1 僡 (<CJK Ideograph>) 19362 0x5AA0 媠 (<CJK Ideograph>) 19363 0x6164 慤 (<CJK Ideograph>) 19364 0x8424 萤 (<CJK Ideograph>) 19365 0x6142 慂 (<CJK Ideograph>) 19366 0x2F8A6 慈 (CJK COMPATIBILITY IDEOGRAPH-2F8A6) 19367 0x26ED2 𦻒 (<CJK Ideograph Extension B>) 19368 0x6181 憁 (<CJK Ideograph>) 19369 0x51F4 凴 (<CJK Ideograph>) 19370 0x20656 𠙖 (<CJK Ideograph Extension B>) 19371 0x6187 憇 (<CJK Ideograph>) 19372 0x5BAA 宪 (<CJK Ideograph>) 19373 0x23FB7 𣾷 (<CJK Ideograph Extension B>) 19374 0x2285F 𢡟 (<CJK Ideograph Extension B>) 19375 0x61D3 懓 (<CJK Ideograph>) 19376 0x28B9D 𨮝 (<CJK Ideograph Extension B>) 19377 0x2995D 𩥝 (<CJK Ideograph Extension B>) 19378 0x61D0 懐 (<CJK Ideograph>) 19379 0x3932 㤲 (<CJK Ideograph Extension A>) 19380 0x22980 𢦀 (<CJK Ideograph Extension B>) 19381 0x228C1 𢣁 (<CJK Ideograph Extension B>) 19382 0x6023 怣 (<CJK Ideograph>) 19383 0x615C 慜 (<CJK Ideograph>) 19384 0x651E 攞 (<CJK Ideograph>) 19385 0x638B 掋 (<CJK Ideograph>) 19386 0x20118 𠄘 (<CJK Ideograph Extension B>) 19387 0x62C5 担 (<CJK Ideograph>) 19388 0x21770 𡝰 (<CJK Ideograph Extension B>) 19389 0x62D5 拕 (<CJK Ideograph>) 19390 0x22E0D 𢸍 (<CJK Ideograph Extension B>) 19391 0x636C 捬 (<CJK Ideograph>) 19392 0x249DF 𤧟 (<CJK Ideograph Extension B>) 19393 0x3A17 㨗 (<CJK Ideograph Extension A>) 19394 0x6438 搸 (<CJK Ideograph>) 19395 0x63F8 揸 (<CJK Ideograph>) 19396 0x2138E 𡎎 (<CJK Ideograph Extension B>) 19397 0x217FC 𡟼 (<CJK Ideograph Extension B>) 19398 0x6490 撐 (<CJK Ideograph>) 19399 0x6F8A 澊 (<CJK Ideograph>) 19400 0x22E36 𢸶 (<CJK Ideograph Extension B>) 19401 0x9814 頔 (<CJK Ideograph>) 19402 0x2408C 𤂌 (<CJK Ideograph Extension B>) 19403 0x2571D 𥜝 (<CJK Ideograph Extension B>) 19404 0x64E1 擡 (<CJK Ideograph>) 19405 0x64E5 擥 (<CJK Ideograph>) 19406 0x947B 鑻 (<CJK Ideograph>) 19407 0x3A66 㩦 (<CJK Ideograph Extension A>) 19408 0x643A 携 (<CJK Ideograph>) 19409 0x3A57 㩗 (<CJK Ideograph Extension A>) 19410 0x654D 敍 (<CJK Ideograph>) 19411 0x6F16 漖 (<CJK Ideograph>) 19412 0x24A28 𤨨 (<CJK Ideograph Extension B>) 19413 0x24A23 𤨣 (<CJK Ideograph Extension B>) 19414 0x6585 斅 (<CJK Ideograph>) 19415 0x656D 敭 (<CJK Ideograph>) 19416 0x655F 敟 (<CJK Ideograph>) 19417 0x2307E 𣁾 (<CJK Ideograph Extension B>) 19418 0x65B5 斵 (<CJK Ideograph>) 19419 0x24940 𤥀 (<CJK Ideograph Extension B>) 19420 0x4B37 䬷 (<CJK Ideograph Extension A>) 19421 0x65D1 旑 (<CJK Ideograph>) 19422 0x40D8 䃘 (<CJK Ideograph Extension A>) 19423 0x21829 𡠩 (<CJK Ideograph Extension B>) 19424 0x65E0 无 (<CJK Ideograph>) 19425 0x65E3 旣 (<CJK Ideograph>) 19426 0x5FDF 忟 (<CJK Ideograph>) 19427 0x23400 𣐀 (<CJK Ideograph Extension B>) 19428 0x6618 昘 (<CJK Ideograph>) 19429 0x231F7 𣇷 (<CJK Ideograph Extension B>) 19430 0x231F8 𣇸 (<CJK Ideograph Extension B>) 19431 0x6644 晄 (<CJK Ideograph>) 19432 0x231A4 𣆤 (<CJK Ideograph Extension B>) 19433 0x231A5 𣆥 (<CJK Ideograph Extension B>) 19434 0x664B 晋 (<CJK Ideograph>) 19435 0x20E75 𠹵 (<CJK Ideograph Extension B>) 19436 0x6667 晧 (<CJK Ideograph>) 19437 0x251E6 𥇦 (<CJK Ideograph Extension B>) 19438 0x6673 晳 (<CJK Ideograph>) 19439 0x6674 晴 (<CJK Ideograph>) 19440 0x21E3D 𡸽 (<CJK Ideograph Extension B>) 19441 0x23231 𣈱 (<CJK Ideograph Extension B>) 19442 0x285F4 𨗴 (<CJK Ideograph Extension B>) 19443 0x231C8 𣇈 (<CJK Ideograph Extension B>) 19444 0x25313 𥌓 (<CJK Ideograph Extension B>) 19445 0x77C5 矅 (<CJK Ideograph>) 19446 0x228F7 𢣷 (<CJK Ideograph Extension B>) 19447 0x99A4 馤 (<CJK Ideograph>) 19448 0x6702 朂 (<CJK Ideograph>) 19449 0x2439C 𤎜 (<CJK Ideograph Extension B>) 19450 0x24A21 𤨡 (<CJK Ideograph Extension B>) 19451 0x3B2B 㬫 (<CJK Ideograph Extension A>) 19452 0x69FA 槺 (<CJK Ideograph>) 19453 0x237C2 𣟂 (<CJK Ideograph Extension B>) 19454 0x675E 杞 (<CJK Ideograph>) 19455 0x6767 杧 (<CJK Ideograph>) 19456 0x6762 杢 (<CJK Ideograph>) 19457 0x241CD 𤇍 (<CJK Ideograph Extension B>) 19458 0x290ED 𩃭 (<CJK Ideograph Extension B>) 19459 0x67D7 柗 (<CJK Ideograph>) 19460 0x44E9 䓩 (<CJK Ideograph Extension A>) 19461 0x6822 栢 (<CJK Ideograph>) 19462 0x6E50 湐 (<CJK Ideograph>) 19463 0x923C 鈼 (<CJK Ideograph>) 19464 0x6801 栁 (<CJK Ideograph>) 19465 0x233E6 𣏦 (<CJK Ideograph Extension B>) 19466 0x26DA0 𦶠 (<CJK Ideograph Extension B>) 19467 0x685D 桝 (<CJK Ideograph>) 19468 0x2346F 𣑯 (<CJK Ideograph Extension B>) 19469 0x69E1 槡 (<CJK Ideograph>) 19470 0x6A0B 樋 (<CJK Ideograph>) 19471 0x28ADF 𨫟 (<CJK Ideograph Extension B>) 19472 0x6973 楳 (<CJK Ideograph>) 19473 0x68C3 棃 (<CJK Ideograph>) 19474 0x235CD 𣗍 (<CJK Ideograph Extension B>) 19475 0x6901 椁 (<CJK Ideograph>) 19476 0x6900 椀 (<CJK Ideograph>) 19477 0x3D32 㴲 (<CJK Ideograph Extension A>) 19478 0x3A01 㨁 (<CJK Ideograph Extension A>) 19479 0x2363C 𣘼 (<CJK Ideograph Extension B>) 19480 0x3B80 㮀 (<CJK Ideograph Extension A>) 19481 0x67AC 枬 (<CJK Ideograph>) 19482 0x6961 楡 (<CJK Ideograph>) 19483 0x28A4A 𨩊 (<CJK Ideograph Extension B>) 19484 0x42FC 䋼 (<CJK Ideograph Extension A>) 19485 0x6936 椶 (<CJK Ideograph>) 19486 0x6998 榘 (<CJK Ideograph>) 19487 0x3BA1 㮡 (<CJK Ideograph Extension A>) 19488 0x203C9 𠏉 (<CJK Ideograph Extension B>) 19489 0x8363 荣 (<CJK Ideograph>) 19490 0x5090 傐 (<CJK Ideograph>) 19491 0x69F9 槹 (<CJK Ideograph>) 19492 0x23659 𣙙 (<CJK Ideograph Extension B>) 19493 0x2212A 𢄪 (<CJK Ideograph Extension B>) 19494 0x6A45 橅 (<CJK Ideograph>) 19495 0x23703 𣜃 (<CJK Ideograph Extension B>) 19496 0x6A9D 檝 (<CJK Ideograph>) 19497 0x3BF3 㯳 (<CJK Ideograph Extension A>) 19498 0x67B1 枱 (<CJK Ideograph>) 19499 0x6AC8 櫈 (<CJK Ideograph>) 19500 0x2919C 𩆜 (<CJK Ideograph Extension B>) 19501 0x3C0D 㰍 (<CJK Ideograph Extension A>) 19502 0x6B1D 欝 (<CJK Ideograph>) 19503 0x20923 𠤣 (<CJK Ideograph Extension B>) 19504 0x60DE 惞 (<CJK Ideograph>) 19505 0x6B35 欵 (<CJK Ideograph>) 19506 0x6B74 歴 (<CJK Ideograph>) 19507 0x227CD 𢟍 (<CJK Ideograph Extension B>) 19508 0x6EB5 溵 (<CJK Ideograph>) 19509 0x23ADB 𣫛 (<CJK Ideograph Extension B>) 19510 0x203B5 𠎵 (<CJK Ideograph Extension B>) 19511 0x21958 𡥘 (<CJK Ideograph Extension B>) 19512 0x3740 㝀 (<CJK Ideograph Extension A>) 19513 0x5421 吡 (<CJK Ideograph>) 19514 0x23B5A 𣭚 (<CJK Ideograph Extension B>) 19515 0x6BE1 毡 (<CJK Ideograph>) 19516 0x23EFC 𣻼 (<CJK Ideograph Extension B>) 19517 0x6BDC 毜 (<CJK Ideograph>) 19518 0x6C37 氷 (<CJK Ideograph>) 19519 0x2248B 𢒋 (<CJK Ideograph Extension B>) 19520 0x248F1 𤣱 (<CJK Ideograph Extension B>) 19521 0x26B51 𦭑 (<CJK Ideograph Extension B>) 19522 0x6C5A 汚 (<CJK Ideograph>) 19523 0x8226 舦 (<CJK Ideograph>) 19524 0x6C79 汹 (<CJK Ideograph>) 19525 0x23DBC 𣶼 (<CJK Ideograph Extension B>) 19526 0x44C5 䓅 (<CJK Ideograph Extension A>) 19527 0x23DBD 𣶽 (<CJK Ideograph Extension B>) 19528 0x241A4 𤆤 (<CJK Ideograph Extension B>) 19529 0x2490C 𤤌 (<CJK Ideograph Extension B>) 19530 0x24900 𤤀 (<CJK Ideograph Extension B>) 19531 0x23CC9 𣳉 (<CJK Ideograph Extension B>) 19532 0x36E5 㛥 (<CJK Ideograph Extension A>) 19533 0x3CEB 㳫 (<CJK Ideograph Extension A>) 19534 0x20D32 𠴲 (<CJK Ideograph Extension B>) 19535 0x9B83 鮃 (<CJK Ideograph>) 19536 0x231F9 𣇹 (<CJK Ideograph Extension B>) 19537 0x22491 𢒑 (<CJK Ideograph Extension B>) 19538 0x7F8F 羏 (<CJK Ideograph>) 19539 0x6837 样 (<CJK Ideograph>) 19540 0x26D25 𦴥 (<CJK Ideograph Extension B>) 19541 0x26DA1 𦶡 (<CJK Ideograph Extension B>) 19542 0x26DEB 𦷫 (<CJK Ideograph Extension B>) 19543 0x6D96 涖 (<CJK Ideograph>) 19544 0x6D5C 浜 (<CJK Ideograph>) 19545 0x6E7C 湼 (<CJK Ideograph>) 19546 0x6F04 漄 (<CJK Ideograph>) 19547 0x2497F 𤥿 (<CJK Ideograph Extension B>) 19548 0x24085 𤂅 (<CJK Ideograph Extension B>) 19549 0x26E72 𦹲 (<CJK Ideograph Extension B>) 19550 0x8533 蔳 (<CJK Ideograph>) 19551 0x26F74 𦽴 (<CJK Ideograph Extension B>) 19552 0x51C7 凇 (<CJK Ideograph>) 19553 0x6C9C 沜 (<CJK Ideograph>) 19554 0x6E1D 渝 (<CJK Ideograph>) 19555 0x842E 萮 (<CJK Ideograph>) 19556 0x28B21 𨬡 (<CJK Ideograph Extension B>) 19557 0x6E2F 港 (<CJK Ideograph>) 19558 0x23E2F 𣸯 (<CJK Ideograph Extension B>) 19559 0x7453 瑓 (<CJK Ideograph>) 19560 0x23F82 𣾂 (<CJK Ideograph Extension B>) 19561 0x79CC 秌 (<CJK Ideograph>) 19562 0x6E4F 湏 (<CJK Ideograph>) 19563 0x5A91 媑 (<CJK Ideograph>) 19564 0x2304B 𣁋 (<CJK Ideograph Extension B>) 19565 0x6FF8 濸 (<CJK Ideograph>) 19566 0x370D 㜍 (<CJK Ideograph Extension A>) 19567 0x6F9D 澝 (<CJK Ideograph>) 19568 0x23E30 𣸰 (<CJK Ideograph Extension B>) 19569 0x6EFA 滺 (<CJK Ideograph>) 19570 0x21497 𡒗 (<CJK Ideograph Extension B>) 19571 0x2403D 𤀽 (<CJK Ideograph Extension B>) 19572 0x4555 䕕 (<CJK Ideograph Extension A>) 19573 0x93F0 鏰 (<CJK Ideograph>) 19574 0x6F44 潄 (<CJK Ideograph>) 19575 0x6F5C 潜 (<CJK Ideograph>) 19576 0x3D4E 㵎 (<CJK Ideograph Extension A>) 19577 0x6F74 潴 (<CJK Ideograph>) 19578 0x29170 𩅰 (<CJK Ideograph Extension B>) 19579 0x3D3B 㴻 (<CJK Ideograph Extension A>) 19580 0x6F9F 澟 (<CJK Ideograph>) 19581 0x24144 𤅄 (<CJK Ideograph Extension B>) 19582 0x6FD3 濓 (<CJK Ideograph>) 19583 0x24091 𤂑 (<CJK Ideograph Extension B>) 19584 0x24155 𤅕 (<CJK Ideograph Extension B>) 19585 0x24039 𤀹 (<CJK Ideograph Extension B>) 19586 0x23FF0 𣿰 (<CJK Ideograph Extension B>) 19587 0x23FB4 𣾴 (<CJK Ideograph Extension B>) 19588 0x2413F 𤄿 (<CJK Ideograph Extension B>) 19589 0x51DF 凟 (<CJK Ideograph>) 19590 0x24156 𤅖 (<CJK Ideograph Extension B>) 19591 0x24157 𤅗 (<CJK Ideograph Extension B>) 19592 0x24140 𤅀 (<CJK Ideograph Extension B>) 19593 0x261DD 𦇝 (<CJK Ideograph Extension B>) 19594 0x704B 灋 (<CJK Ideograph>) 19595 0x707E 灾 (<CJK Ideograph>) 19596 0x70A7 炧 (<CJK Ideograph>) 19597 0x7081 炁 (<CJK Ideograph>) 19598 0x70CC 烌 (<CJK Ideograph>) 19599 0x70D5 烕 (<CJK Ideograph>) 19600 0x70D6 烖 (<CJK Ideograph>) 19601 0x70DF 烟 (<CJK Ideograph>) 19602 0x4104 䄄 (<CJK Ideograph Extension A>) 19603 0x3DE8 㷨 (<CJK Ideograph Extension A>) 19604 0x71B4 熴 (<CJK Ideograph>) 19605 0x7196 熖 (<CJK Ideograph>) 19606 0x24277 𤉷 (<CJK Ideograph Extension B>) 19607 0x712B 焫 (<CJK Ideograph>) 19608 0x7145 煅 (<CJK Ideograph>) 19609 0x5A88 媈 (<CJK Ideograph>) 19610 0x714A 煊 (<CJK Ideograph>) 19611 0x716E 煮 (<CJK Ideograph>) 19612 0x5C9C 岜 (<CJK Ideograph>) 19613 0x24365 𤍥 (<CJK Ideograph Extension B>) 19614 0x714F 煏 (<CJK Ideograph>) 19615 0x9362 鍢 (<CJK Ideograph>) 19616 0x242C1 𤋁 (<CJK Ideograph Extension B>) 19617 0x712C 焬 (<CJK Ideograph>) 19618 0x2445A 𤑚 (<CJK Ideograph Extension B>) 19619 0x24A27 𤨧 (<CJK Ideograph Extension B>) 19620 0x24A22 𤨢 (<CJK Ideograph Extension B>) 19621 0x71BA 熺 (<CJK Ideograph>) 19622 0x28BE8 𨯨 (<CJK Ideograph Extension B>) 19623 0x70BD 炽 (<CJK Ideograph>) 19624 0x720E 爎 (<CJK Ideograph>) 19625 0x9442 鑂 (<CJK Ideograph>) 19626 0x7215 爕 (<CJK Ideograph>) 19627 0x5911 夑 (<CJK Ideograph>) 19628 0x9443 鑃 (<CJK Ideograph>) 19629 0x7224 爤 (<CJK Ideograph>) 19630 0x9341 鍁 (<CJK Ideograph>) 19631 0x25605 𥘅 (<CJK Ideograph Extension B>) 19632 0x722E 爮 (<CJK Ideograph>) 19633 0x7240 牀 (<CJK Ideograph>) 19634 0x24974 𤥴 (<CJK Ideograph Extension B>) 19635 0x68BD 梽 (<CJK Ideograph>) 19636 0x7255 牕 (<CJK Ideograph>) 19637 0x7257 牗 (<CJK Ideograph>) 19638 0x3E55 㹕 (<CJK Ideograph Extension A>) 19639 0x23044 𣁄 (<CJK Ideograph Extension B>) 19640 0x680D 栍 (<CJK Ideograph>) 19641 0x6F3D 漽 (<CJK Ideograph>) 19642 0x7282 犂 (<CJK Ideograph>) 19643 0x732A 猪 (<CJK Ideograph>) 19644 0x732B 猫 (<CJK Ideograph>) 19645 0x24823 𤠣 (<CJK Ideograph Extension B>) 19646 0x2882B 𨠫 (<CJK Ideograph Extension B>) 19647 0x48ED 䣭 (<CJK Ideograph Extension A>) 19648 0x28804 𨠄 (<CJK Ideograph Extension B>) 19649 0x7328 猨 (<CJK Ideograph>) 19650 0x732E 献 (<CJK Ideograph>) 19651 0x73CF 珏 (<CJK Ideograph>) 19652 0x73AA 玪 (<CJK Ideograph>) 19653 0x20C3A 𠰺 (<CJK Ideograph Extension B>) 19654 0x26A2E 𦨮 (<CJK Ideograph Extension B>) 19655 0x73C9 珉 (<CJK Ideograph>) 19656 0x7449 瑉 (<CJK Ideograph>) 19657 0x241E2 𤇢 (<CJK Ideograph Extension B>) 19658 0x216E7 𡛧 (<CJK Ideograph Extension B>) 19659 0x24A24 𤨤 (<CJK Ideograph Extension B>) 19660 0x6623 昣 (<CJK Ideograph>) 19661 0x36C5 㛅 (<CJK Ideograph Extension A>) 19662 0x249B7 𤦷 (<CJK Ideograph Extension B>) 19663 0x2498D 𤦍 (<CJK Ideograph Extension B>) 19664 0x249FB 𤧻 (<CJK Ideograph Extension B>) 19665 0x73F7 珷 (<CJK Ideograph>) 19666 0x7415 琕 (<CJK Ideograph>) 19667 0x6903 椃 (<CJK Ideograph>) 19668 0x24A26 𤨦 (<CJK Ideograph Extension B>) 19669 0x7439 琹 (<CJK Ideograph>) 19670 0x205C3 𠗃 (<CJK Ideograph Extension B>) 19671 0x3ED7 㻗 (<CJK Ideograph Extension A>) 19672 0x745C 瑜 (<CJK Ideograph>) 19673 0x228AD 𢢭 (<CJK Ideograph Extension B>) 19674 0x7460 瑠 (<CJK Ideograph>) 19675 0x28EB2 𨺲 (<CJK Ideograph Extension B>) 19676 0x7447 瑇 (<CJK Ideograph>) 19677 0x73E4 珤 (<CJK Ideograph>) 19678 0x7476 瑶 (<CJK Ideograph>) 19679 0x83B9 莹 (<CJK Ideograph>) 19680 0x746C 瑬 (<CJK Ideograph>) 19681 0x3730 㜰 (<CJK Ideograph Extension A>) 19682 0x7474 瑴 (<CJK Ideograph>) 19683 0x93F1 鏱 (<CJK Ideograph>) 19684 0x6A2C 樬 (<CJK Ideograph>) 19685 0x7482 璂 (<CJK Ideograph>) 19686 0x4953 䥓 (<CJK Ideograph Extension A>) 19687 0x24A8C 𤪌 (<CJK Ideograph Extension B>) 19688 0x2415F 𤅟 (<CJK Ideograph Extension B>) 19689 0x24A79 𤩹 (<CJK Ideograph Extension B>) 19690 0x28B8F 𨮏 (<CJK Ideograph Extension B>) 19691 0x5B46 孆 (<CJK Ideograph>) 19692 0x28C03 𨰃 (<CJK Ideograph Extension B>) 19693 0x2189E 𡢞 (<CJK Ideograph Extension B>) 19694 0x74C8 瓈 (<CJK Ideograph>) 19695 0x21988 𡦈 (<CJK Ideograph Extension B>) 19696 0x750E 甎 (<CJK Ideograph>) 19697 0x74E9 瓩 (<CJK Ideograph>) 19698 0x751E 甞 (<CJK Ideograph>) 19699 0x28ED9 𨻙 (<CJK Ideograph Extension B>) 19700 0x21A4B 𡩋 (<CJK Ideograph Extension B>) 19701 0x5BD7 寗 (<CJK Ideograph>) 19702 0x28EAC 𨺬 (<CJK Ideograph Extension B>) 19703 0x9385 鎅 (<CJK Ideograph>) 19704 0x754D 畍 (<CJK Ideograph>) 19705 0x754A 畊 (<CJK Ideograph>) 19706 0x7567 畧 (<CJK Ideograph>) 19707 0x756E 畮 (<CJK Ideograph>) 19708 0x24F82 𤾂 (<CJK Ideograph Extension B>) 19709 0x3F04 㼄 (<CJK Ideograph Extension A>) 19710 0x24D13 𤴓 (<CJK Ideograph Extension B>) 19711 0x758E 疎 (<CJK Ideograph>) 19712 0x745D 瑝 (<CJK Ideograph>) 19713 0x759E 疞 (<CJK Ideograph>) 19714 0x75B4 疴 (<CJK Ideograph>) 19715 0x7602 瘂 (<CJK Ideograph>) 19716 0x762C 瘬 (<CJK Ideograph>) 19717 0x7651 癑 (<CJK Ideograph>) 19718 0x764F 癏 (<CJK Ideograph>) 19719 0x766F 癯 (<CJK Ideograph>) 19720 0x7676 癶 (<CJK Ideograph>) 19721 0x263F5 𦏵 (<CJK Ideograph Extension B>) 19722 0x7690 皐 (<CJK Ideograph>) 19723 0x81EF 臯 (<CJK Ideograph>) 19724 0x37F8 㟸 (<CJK Ideograph Extension A>) 19725 0x26911 𦤑 (<CJK Ideograph Extension B>) 19726 0x2690E 𦤎 (<CJK Ideograph Extension B>) 19727 0x76A1 皡 (<CJK Ideograph>) 19728 0x76A5 皥 (<CJK Ideograph>) 19729 0x76B7 皷 (<CJK Ideograph>) 19730 0x76CC 盌 (<CJK Ideograph>) 19731 0x26F9F 𦾟 (<CJK Ideograph Extension B>) 19732 0x8462 葢 (<CJK Ideograph>) 19733 0x2509D 𥂝 (<CJK Ideograph Extension B>) 19734 0x2517D 𥅽 (<CJK Ideograph Extension B>) 19735 0x21E1C 𡸜 (<CJK Ideograph Extension B>) 19736 0x771E 眞 (<CJK Ideograph>) 19737 0x7726 眦 (<CJK Ideograph>) 19738 0x7740 着 (<CJK Ideograph>) 19739 0x64AF 撯 (<CJK Ideograph>) 19740 0x25220 𥈠 (<CJK Ideograph Extension B>) 19741 0x7758 睘 (<CJK Ideograph>) 19742 0x232AC 𣊬 (<CJK Ideograph Extension B>) 19743 0x77AF 瞯 (<CJK Ideograph>) 19744 0x28964 𨥤 (<CJK Ideograph Extension B>) 19745 0x28968 𨥨 (<CJK Ideograph Extension B>) 19746 0x216C1 𡛁 (<CJK Ideograph Extension B>) 19747 0x77F4 矴 (<CJK Ideograph>) 19748 0x7809 砉 (<CJK Ideograph>) 19749 0x21376 𡍶 (<CJK Ideograph Extension B>) 19750 0x24A12 𤨒 (<CJK Ideograph Extension B>) 19751 0x68CA 棊 (<CJK Ideograph>) 19752 0x78AF 碯 (<CJK Ideograph>) 19753 0x78C7 磇 (<CJK Ideograph>) 19754 0x78D3 磓 (<CJK Ideograph>) 19755 0x96A5 隥 (<CJK Ideograph>) 19756 0x792E 礮 (<CJK Ideograph>) 19757 0x255E0 𥗠 (<CJK Ideograph Extension B>) 19758 0x78D7 磗 (<CJK Ideograph>) 19759 0x7934 礴 (<CJK Ideograph>) 19760 0x78B1 碱 (<CJK Ideograph>) 19761 0x2760C 𧘌 (<CJK Ideograph Extension B>) 19762 0x8FB8 辸 (<CJK Ideograph>) 19763 0x8884 袄 (<CJK Ideograph>) 19764 0x28B2B 𨬫 (<CJK Ideograph Extension B>) 19765 0x26083 𦂃 (<CJK Ideograph Extension B>) 19766 0x2261C 𢘜 (<CJK Ideograph Extension B>) 19767 0x7986 禆 (<CJK Ideograph>) 19768 0x8900 褀 (<CJK Ideograph>) 19769 0x6902 椂 (<CJK Ideograph>) 19770 0x7980 禀 (<CJK Ideograph>) 19771 0x25857 𥡗 (<CJK Ideograph Extension B>) 19772 0x799D 禝 (<CJK Ideograph>) 19773 0x27B39 𧬹 (<CJK Ideograph Extension B>) 19774 0x793C 礼 (<CJK Ideograph>) 19775 0x79A9 禩 (<CJK Ideograph>) 19776 0x6E2A 渪 (<CJK Ideograph>) 19777 0x27126 𧄦 (<CJK Ideograph Extension B>) 19778 0x3EA8 㺨 (<CJK Ideograph Extension A>) 19779 0x79C6 秆 (<CJK Ideograph>) 19780 0x2910D 𩄍 (<CJK Ideograph Extension B>) 19781 0x79D4 秔 (<CJK Ideograph>) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-euc-kr.txt������������������������������������������������������������������0000664�0000000�0000000�00002437605�15202323131�0017000�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-euc-kr.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 1d97134cbf187263585bc8f593ca4196654ed4c7a673f5672eaad4f5d9fdc4ba # Date: 2018-01-06 0 0xAC02 갂 (HANGUL SYLLABLE GAGG) 1 0xAC03 갃 (HANGUL SYLLABLE GAGS) 2 0xAC05 갅 (HANGUL SYLLABLE GANJ) 3 0xAC06 갆 (HANGUL SYLLABLE GANH) 4 0xAC0B 갋 (HANGUL SYLLABLE GALB) 5 0xAC0C 갌 (HANGUL SYLLABLE GALS) 6 0xAC0D 갍 (HANGUL SYLLABLE GALT) 7 0xAC0E 갎 (HANGUL SYLLABLE GALP) 8 0xAC0F 갏 (HANGUL SYLLABLE GALH) 9 0xAC18 갘 (HANGUL SYLLABLE GAK) 10 0xAC1E 갞 (HANGUL SYLLABLE GAEGG) 11 0xAC1F 갟 (HANGUL SYLLABLE GAEGS) 12 0xAC21 갡 (HANGUL SYLLABLE GAENJ) 13 0xAC22 갢 (HANGUL SYLLABLE GAENH) 14 0xAC23 갣 (HANGUL SYLLABLE GAED) 15 0xAC25 갥 (HANGUL SYLLABLE GAELG) 16 0xAC26 갦 (HANGUL SYLLABLE GAELM) 17 0xAC27 갧 (HANGUL SYLLABLE GAELB) 18 0xAC28 갨 (HANGUL SYLLABLE GAELS) 19 0xAC29 갩 (HANGUL SYLLABLE GAELT) 20 0xAC2A 갪 (HANGUL SYLLABLE GAELP) 21 0xAC2B 갫 (HANGUL SYLLABLE GAELH) 22 0xAC2E 갮 (HANGUL SYLLABLE GAEBS) 23 0xAC32 갲 (HANGUL SYLLABLE GAEJ) 24 0xAC33 갳 (HANGUL SYLLABLE GAEC) 25 0xAC34 갴 (HANGUL SYLLABLE GAEK) 32 0xAC35 갵 (HANGUL SYLLABLE GAET) 33 0xAC36 갶 (HANGUL SYLLABLE GAEP) 34 0xAC37 갷 (HANGUL SYLLABLE GAEH) 35 0xAC3A 갺 (HANGUL SYLLABLE GYAGG) 36 0xAC3B 갻 (HANGUL SYLLABLE GYAGS) 37 0xAC3D 갽 (HANGUL SYLLABLE GYANJ) 38 0xAC3E 갾 (HANGUL SYLLABLE GYANH) 39 0xAC3F 갿 (HANGUL SYLLABLE GYAD) 40 0xAC41 걁 (HANGUL SYLLABLE GYALG) 41 0xAC42 걂 (HANGUL SYLLABLE GYALM) 42 0xAC43 걃 (HANGUL SYLLABLE GYALB) 43 0xAC44 걄 (HANGUL SYLLABLE GYALS) 44 0xAC45 걅 (HANGUL SYLLABLE GYALT) 45 0xAC46 걆 (HANGUL SYLLABLE GYALP) 46 0xAC47 걇 (HANGUL SYLLABLE GYALH) 47 0xAC48 걈 (HANGUL SYLLABLE GYAM) 48 0xAC49 걉 (HANGUL SYLLABLE GYAB) 49 0xAC4A 걊 (HANGUL SYLLABLE GYABS) 50 0xAC4C 걌 (HANGUL SYLLABLE GYASS) 51 0xAC4E 걎 (HANGUL SYLLABLE GYAJ) 52 0xAC4F 걏 (HANGUL SYLLABLE GYAC) 53 0xAC50 걐 (HANGUL SYLLABLE GYAK) 54 0xAC51 걑 (HANGUL SYLLABLE GYAT) 55 0xAC52 걒 (HANGUL SYLLABLE GYAP) 56 0xAC53 걓 (HANGUL SYLLABLE GYAH) 57 0xAC55 걕 (HANGUL SYLLABLE GYAEG) 64 0xAC56 걖 (HANGUL SYLLABLE GYAEGG) 65 0xAC57 걗 (HANGUL SYLLABLE GYAEGS) 66 0xAC59 걙 (HANGUL SYLLABLE GYAENJ) 67 0xAC5A 걚 (HANGUL SYLLABLE GYAENH) 68 0xAC5B 걛 (HANGUL SYLLABLE GYAED) 69 0xAC5D 걝 (HANGUL SYLLABLE GYAELG) 70 0xAC5E 걞 (HANGUL SYLLABLE GYAELM) 71 0xAC5F 걟 (HANGUL SYLLABLE GYAELB) 72 0xAC60 걠 (HANGUL SYLLABLE GYAELS) 73 0xAC61 걡 (HANGUL SYLLABLE GYAELT) 74 0xAC62 걢 (HANGUL SYLLABLE GYAELP) 75 0xAC63 걣 (HANGUL SYLLABLE GYAELH) 76 0xAC64 걤 (HANGUL SYLLABLE GYAEM) 77 0xAC65 걥 (HANGUL SYLLABLE GYAEB) 78 0xAC66 걦 (HANGUL SYLLABLE GYAEBS) 79 0xAC67 걧 (HANGUL SYLLABLE GYAES) 80 0xAC68 걨 (HANGUL SYLLABLE GYAESS) 81 0xAC69 걩 (HANGUL SYLLABLE GYAENG) 82 0xAC6A 걪 (HANGUL SYLLABLE GYAEJ) 83 0xAC6B 걫 (HANGUL SYLLABLE GYAEC) 84 0xAC6C 걬 (HANGUL SYLLABLE GYAEK) 85 0xAC6D 걭 (HANGUL SYLLABLE GYAET) 86 0xAC6E 걮 (HANGUL SYLLABLE GYAEP) 87 0xAC6F 걯 (HANGUL SYLLABLE GYAEH) 88 0xAC72 걲 (HANGUL SYLLABLE GEOGG) 89 0xAC73 걳 (HANGUL SYLLABLE GEOGS) 90 0xAC75 걵 (HANGUL SYLLABLE GEONJ) 91 0xAC76 걶 (HANGUL SYLLABLE GEONH) 92 0xAC79 걹 (HANGUL SYLLABLE GEOLG) 93 0xAC7B 걻 (HANGUL SYLLABLE GEOLB) 94 0xAC7C 걼 (HANGUL SYLLABLE GEOLS) 95 0xAC7D 걽 (HANGUL SYLLABLE GEOLT) 96 0xAC7E 걾 (HANGUL SYLLABLE GEOLP) 97 0xAC7F 걿 (HANGUL SYLLABLE GEOLH) 98 0xAC82 겂 (HANGUL SYLLABLE GEOBS) 99 0xAC87 겇 (HANGUL SYLLABLE GEOC) 100 0xAC88 겈 (HANGUL SYLLABLE GEOK) 101 0xAC8D 겍 (HANGUL SYLLABLE GEG) 102 0xAC8E 겎 (HANGUL SYLLABLE GEGG) 103 0xAC8F 겏 (HANGUL SYLLABLE GEGS) 104 0xAC91 겑 (HANGUL SYLLABLE GENJ) 105 0xAC92 겒 (HANGUL SYLLABLE GENH) 106 0xAC93 겓 (HANGUL SYLLABLE GED) 107 0xAC95 겕 (HANGUL SYLLABLE GELG) 108 0xAC96 겖 (HANGUL SYLLABLE GELM) 109 0xAC97 겗 (HANGUL SYLLABLE GELB) 110 0xAC98 겘 (HANGUL SYLLABLE GELS) 111 0xAC99 겙 (HANGUL SYLLABLE GELT) 112 0xAC9A 겚 (HANGUL SYLLABLE GELP) 113 0xAC9B 겛 (HANGUL SYLLABLE GELH) 114 0xAC9E 겞 (HANGUL SYLLABLE GEBS) 115 0xACA2 겢 (HANGUL SYLLABLE GEJ) 116 0xACA3 겣 (HANGUL SYLLABLE GEC) 117 0xACA4 겤 (HANGUL SYLLABLE GEK) 118 0xACA5 겥 (HANGUL SYLLABLE GET) 119 0xACA6 겦 (HANGUL SYLLABLE GEP) 120 0xACA7 겧 (HANGUL SYLLABLE GEH) 121 0xACAB 겫 (HANGUL SYLLABLE GYEOGS) 122 0xACAD 겭 (HANGUL SYLLABLE GYEONJ) 123 0xACAE 겮 (HANGUL SYLLABLE GYEONH) 124 0xACB1 겱 (HANGUL SYLLABLE GYEOLG) 125 0xACB2 겲 (HANGUL SYLLABLE GYEOLM) 126 0xACB3 겳 (HANGUL SYLLABLE GYEOLB) 127 0xACB4 겴 (HANGUL SYLLABLE GYEOLS) 128 0xACB5 겵 (HANGUL SYLLABLE GYEOLT) 129 0xACB6 겶 (HANGUL SYLLABLE GYEOLP) 130 0xACB7 겷 (HANGUL SYLLABLE GYEOLH) 131 0xACBA 겺 (HANGUL SYLLABLE GYEOBS) 132 0xACBE 겾 (HANGUL SYLLABLE GYEOJ) 133 0xACBF 겿 (HANGUL SYLLABLE GYEOC) 134 0xACC0 곀 (HANGUL SYLLABLE GYEOK) 135 0xACC2 곂 (HANGUL SYLLABLE GYEOP) 136 0xACC3 곃 (HANGUL SYLLABLE GYEOH) 137 0xACC5 곅 (HANGUL SYLLABLE GYEG) 138 0xACC6 곆 (HANGUL SYLLABLE GYEGG) 139 0xACC7 곇 (HANGUL SYLLABLE GYEGS) 140 0xACC9 곉 (HANGUL SYLLABLE GYENJ) 141 0xACCA 곊 (HANGUL SYLLABLE GYENH) 142 0xACCB 곋 (HANGUL SYLLABLE GYED) 143 0xACCD 곍 (HANGUL SYLLABLE GYELG) 144 0xACCE 곎 (HANGUL SYLLABLE GYELM) 145 0xACCF 곏 (HANGUL SYLLABLE GYELB) 146 0xACD0 곐 (HANGUL SYLLABLE GYELS) 147 0xACD1 곑 (HANGUL SYLLABLE GYELT) 148 0xACD2 곒 (HANGUL SYLLABLE GYELP) 149 0xACD3 곓 (HANGUL SYLLABLE GYELH) 150 0xACD4 곔 (HANGUL SYLLABLE GYEM) 151 0xACD6 곖 (HANGUL SYLLABLE GYEBS) 152 0xACD8 곘 (HANGUL SYLLABLE GYESS) 153 0xACD9 곙 (HANGUL SYLLABLE GYENG) 154 0xACDA 곚 (HANGUL SYLLABLE GYEJ) 155 0xACDB 곛 (HANGUL SYLLABLE GYEC) 156 0xACDC 곜 (HANGUL SYLLABLE GYEK) 157 0xACDD 곝 (HANGUL SYLLABLE GYET) 158 0xACDE 곞 (HANGUL SYLLABLE GYEP) 159 0xACDF 곟 (HANGUL SYLLABLE GYEH) 160 0xACE2 곢 (HANGUL SYLLABLE GOGG) 161 0xACE3 곣 (HANGUL SYLLABLE GOGS) 162 0xACE5 곥 (HANGUL SYLLABLE GONJ) 163 0xACE6 곦 (HANGUL SYLLABLE GONH) 164 0xACE9 곩 (HANGUL SYLLABLE GOLG) 165 0xACEB 곫 (HANGUL SYLLABLE GOLB) 166 0xACED 곭 (HANGUL SYLLABLE GOLT) 167 0xACEE 곮 (HANGUL SYLLABLE GOLP) 168 0xACF2 곲 (HANGUL SYLLABLE GOBS) 169 0xACF4 곴 (HANGUL SYLLABLE GOSS) 170 0xACF7 곷 (HANGUL SYLLABLE GOC) 171 0xACF8 곸 (HANGUL SYLLABLE GOK) 172 0xACF9 곹 (HANGUL SYLLABLE GOT) 173 0xACFA 곺 (HANGUL SYLLABLE GOP) 174 0xACFB 곻 (HANGUL SYLLABLE GOH) 175 0xACFE 곾 (HANGUL SYLLABLE GWAGG) 176 0xACFF 곿 (HANGUL SYLLABLE GWAGS) 177 0xAD01 괁 (HANGUL SYLLABLE GWANJ) 178 0xAD02 괂 (HANGUL SYLLABLE GWANH) 179 0xAD03 괃 (HANGUL SYLLABLE GWAD) 180 0xAD05 괅 (HANGUL SYLLABLE GWALG) 181 0xAD07 괇 (HANGUL SYLLABLE GWALB) 182 0xAD08 괈 (HANGUL SYLLABLE GWALS) 183 0xAD09 괉 (HANGUL SYLLABLE GWALT) 184 0xAD0A 괊 (HANGUL SYLLABLE GWALP) 185 0xAD0B 괋 (HANGUL SYLLABLE GWALH) 186 0xAD0E 괎 (HANGUL SYLLABLE GWABS) 187 0xAD10 괐 (HANGUL SYLLABLE GWASS) 188 0xAD12 괒 (HANGUL SYLLABLE GWAJ) 189 0xAD13 괓 (HANGUL SYLLABLE GWAC) 190 0xAD14 괔 (HANGUL SYLLABLE GWAK) 191 0xAD15 괕 (HANGUL SYLLABLE GWAT) 192 0xAD16 괖 (HANGUL SYLLABLE GWAP) 193 0xAD17 괗 (HANGUL SYLLABLE GWAH) 194 0xAD19 괙 (HANGUL SYLLABLE GWAEG) 195 0xAD1A 괚 (HANGUL SYLLABLE GWAEGG) 196 0xAD1B 괛 (HANGUL SYLLABLE GWAEGS) 197 0xAD1D 괝 (HANGUL SYLLABLE GWAENJ) 198 0xAD1E 괞 (HANGUL SYLLABLE GWAENH) 199 0xAD1F 괟 (HANGUL SYLLABLE GWAED) 200 0xAD21 괡 (HANGUL SYLLABLE GWAELG) 201 0xAD22 괢 (HANGUL SYLLABLE GWAELM) 202 0xAD23 괣 (HANGUL SYLLABLE GWAELB) 203 0xAD24 괤 (HANGUL SYLLABLE GWAELS) 204 0xAD25 괥 (HANGUL SYLLABLE GWAELT) 205 0xAD26 괦 (HANGUL SYLLABLE GWAELP) 206 0xAD27 괧 (HANGUL SYLLABLE GWAELH) 207 0xAD28 괨 (HANGUL SYLLABLE GWAEM) 208 0xAD2A 괪 (HANGUL SYLLABLE GWAEBS) 209 0xAD2B 괫 (HANGUL SYLLABLE GWAES) 210 0xAD2E 괮 (HANGUL SYLLABLE GWAEJ) 211 0xAD2F 괯 (HANGUL SYLLABLE GWAEC) 212 0xAD30 괰 (HANGUL SYLLABLE GWAEK) 213 0xAD31 괱 (HANGUL SYLLABLE GWAET) 214 0xAD32 괲 (HANGUL SYLLABLE GWAEP) 215 0xAD33 괳 (HANGUL SYLLABLE GWAEH) 222 0xAD36 괶 (HANGUL SYLLABLE GOEGG) 223 0xAD37 괷 (HANGUL SYLLABLE GOEGS) 224 0xAD39 괹 (HANGUL SYLLABLE GOENJ) 225 0xAD3A 괺 (HANGUL SYLLABLE GOENH) 226 0xAD3B 괻 (HANGUL SYLLABLE GOED) 227 0xAD3D 괽 (HANGUL SYLLABLE GOELG) 228 0xAD3E 괾 (HANGUL SYLLABLE GOELM) 229 0xAD3F 괿 (HANGUL SYLLABLE GOELB) 230 0xAD40 굀 (HANGUL SYLLABLE GOELS) 231 0xAD41 굁 (HANGUL SYLLABLE GOELT) 232 0xAD42 굂 (HANGUL SYLLABLE GOELP) 233 0xAD43 굃 (HANGUL SYLLABLE GOELH) 234 0xAD46 굆 (HANGUL SYLLABLE GOEBS) 235 0xAD48 굈 (HANGUL SYLLABLE GOESS) 236 0xAD4A 굊 (HANGUL SYLLABLE GOEJ) 237 0xAD4B 굋 (HANGUL SYLLABLE GOEC) 238 0xAD4C 굌 (HANGUL SYLLABLE GOEK) 239 0xAD4D 굍 (HANGUL SYLLABLE GOET) 240 0xAD4E 굎 (HANGUL SYLLABLE GOEP) 241 0xAD4F 굏 (HANGUL SYLLABLE GOEH) 242 0xAD51 굑 (HANGUL SYLLABLE GYOG) 243 0xAD52 굒 (HANGUL SYLLABLE GYOGG) 244 0xAD53 굓 (HANGUL SYLLABLE GYOGS) 245 0xAD55 굕 (HANGUL SYLLABLE GYONJ) 246 0xAD56 굖 (HANGUL SYLLABLE GYONH) 247 0xAD57 굗 (HANGUL SYLLABLE GYOD) 254 0xAD59 굙 (HANGUL SYLLABLE GYOLG) 255 0xAD5A 굚 (HANGUL SYLLABLE GYOLM) 256 0xAD5B 굛 (HANGUL SYLLABLE GYOLB) 257 0xAD5C 굜 (HANGUL SYLLABLE GYOLS) 258 0xAD5D 굝 (HANGUL SYLLABLE GYOLT) 259 0xAD5E 굞 (HANGUL SYLLABLE GYOLP) 260 0xAD5F 굟 (HANGUL SYLLABLE GYOLH) 261 0xAD60 굠 (HANGUL SYLLABLE GYOM) 262 0xAD62 굢 (HANGUL SYLLABLE GYOBS) 263 0xAD64 굤 (HANGUL SYLLABLE GYOSS) 264 0xAD65 굥 (HANGUL SYLLABLE GYONG) 265 0xAD66 굦 (HANGUL SYLLABLE GYOJ) 266 0xAD67 굧 (HANGUL SYLLABLE GYOC) 267 0xAD68 굨 (HANGUL SYLLABLE GYOK) 268 0xAD69 굩 (HANGUL SYLLABLE GYOT) 269 0xAD6A 굪 (HANGUL SYLLABLE GYOP) 270 0xAD6B 굫 (HANGUL SYLLABLE GYOH) 271 0xAD6E 굮 (HANGUL SYLLABLE GUGG) 272 0xAD6F 굯 (HANGUL SYLLABLE GUGS) 273 0xAD71 굱 (HANGUL SYLLABLE GUNJ) 274 0xAD72 굲 (HANGUL SYLLABLE GUNH) 275 0xAD77 굷 (HANGUL SYLLABLE GULB) 276 0xAD78 굸 (HANGUL SYLLABLE GULS) 277 0xAD79 굹 (HANGUL SYLLABLE GULT) 278 0xAD7A 굺 (HANGUL SYLLABLE GULP) 279 0xAD7E 굾 (HANGUL SYLLABLE GUBS) 280 0xAD80 궀 (HANGUL SYLLABLE GUSS) 281 0xAD83 궃 (HANGUL SYLLABLE GUC) 282 0xAD84 궄 (HANGUL SYLLABLE GUK) 283 0xAD85 궅 (HANGUL SYLLABLE GUT) 284 0xAD86 궆 (HANGUL SYLLABLE GUP) 285 0xAD87 궇 (HANGUL SYLLABLE GUH) 286 0xAD8A 궊 (HANGUL SYLLABLE GWEOGG) 287 0xAD8B 궋 (HANGUL SYLLABLE GWEOGS) 288 0xAD8D 궍 (HANGUL SYLLABLE GWEONJ) 289 0xAD8E 궎 (HANGUL SYLLABLE GWEONH) 290 0xAD8F 궏 (HANGUL SYLLABLE GWEOD) 291 0xAD91 궑 (HANGUL SYLLABLE GWEOLG) 292 0xAD92 궒 (HANGUL SYLLABLE GWEOLM) 293 0xAD93 궓 (HANGUL SYLLABLE GWEOLB) 294 0xAD94 궔 (HANGUL SYLLABLE GWEOLS) 295 0xAD95 궕 (HANGUL SYLLABLE GWEOLT) 296 0xAD96 궖 (HANGUL SYLLABLE GWEOLP) 297 0xAD97 궗 (HANGUL SYLLABLE GWEOLH) 298 0xAD98 궘 (HANGUL SYLLABLE GWEOM) 299 0xAD99 궙 (HANGUL SYLLABLE GWEOB) 300 0xAD9A 궚 (HANGUL SYLLABLE GWEOBS) 301 0xAD9B 궛 (HANGUL SYLLABLE GWEOS) 302 0xAD9E 궞 (HANGUL SYLLABLE GWEOJ) 303 0xAD9F 궟 (HANGUL SYLLABLE GWEOC) 304 0xADA0 궠 (HANGUL SYLLABLE GWEOK) 305 0xADA1 궡 (HANGUL SYLLABLE GWEOT) 306 0xADA2 궢 (HANGUL SYLLABLE GWEOP) 307 0xADA3 궣 (HANGUL SYLLABLE GWEOH) 308 0xADA5 궥 (HANGUL SYLLABLE GWEG) 309 0xADA6 궦 (HANGUL SYLLABLE GWEGG) 310 0xADA7 궧 (HANGUL SYLLABLE GWEGS) 311 0xADA8 궨 (HANGUL SYLLABLE GWEN) 312 0xADA9 궩 (HANGUL SYLLABLE GWENJ) 313 0xADAA 궪 (HANGUL SYLLABLE GWENH) 314 0xADAB 궫 (HANGUL SYLLABLE GWED) 315 0xADAC 궬 (HANGUL SYLLABLE GWEL) 316 0xADAD 궭 (HANGUL SYLLABLE GWELG) 317 0xADAE 궮 (HANGUL SYLLABLE GWELM) 318 0xADAF 궯 (HANGUL SYLLABLE GWELB) 319 0xADB0 궰 (HANGUL SYLLABLE GWELS) 320 0xADB1 궱 (HANGUL SYLLABLE GWELT) 321 0xADB2 궲 (HANGUL SYLLABLE GWELP) 322 0xADB3 궳 (HANGUL SYLLABLE GWELH) 323 0xADB4 궴 (HANGUL SYLLABLE GWEM) 324 0xADB5 궵 (HANGUL SYLLABLE GWEB) 325 0xADB6 궶 (HANGUL SYLLABLE GWEBS) 326 0xADB8 궸 (HANGUL SYLLABLE GWESS) 327 0xADB9 궹 (HANGUL SYLLABLE GWENG) 328 0xADBA 궺 (HANGUL SYLLABLE GWEJ) 329 0xADBB 궻 (HANGUL SYLLABLE GWEC) 330 0xADBC 궼 (HANGUL SYLLABLE GWEK) 331 0xADBD 궽 (HANGUL SYLLABLE GWET) 332 0xADBE 궾 (HANGUL SYLLABLE GWEP) 333 0xADBF 궿 (HANGUL SYLLABLE GWEH) 334 0xADC2 귂 (HANGUL SYLLABLE GWIGG) 335 0xADC3 귃 (HANGUL SYLLABLE GWIGS) 336 0xADC5 귅 (HANGUL SYLLABLE GWINJ) 337 0xADC6 귆 (HANGUL SYLLABLE GWINH) 338 0xADC7 귇 (HANGUL SYLLABLE GWID) 339 0xADC9 귉 (HANGUL SYLLABLE GWILG) 340 0xADCA 귊 (HANGUL SYLLABLE GWILM) 341 0xADCB 귋 (HANGUL SYLLABLE GWILB) 342 0xADCC 귌 (HANGUL SYLLABLE GWILS) 343 0xADCD 귍 (HANGUL SYLLABLE GWILT) 344 0xADCE 귎 (HANGUL SYLLABLE GWILP) 345 0xADCF 귏 (HANGUL SYLLABLE GWILH) 346 0xADD2 귒 (HANGUL SYLLABLE GWIBS) 347 0xADD4 귔 (HANGUL SYLLABLE GWISS) 348 0xADD5 귕 (HANGUL SYLLABLE GWING) 349 0xADD6 귖 (HANGUL SYLLABLE GWIJ) 350 0xADD7 귗 (HANGUL SYLLABLE GWIC) 351 0xADD8 귘 (HANGUL SYLLABLE GWIK) 352 0xADD9 귙 (HANGUL SYLLABLE GWIT) 353 0xADDA 귚 (HANGUL SYLLABLE GWIP) 354 0xADDB 귛 (HANGUL SYLLABLE GWIH) 355 0xADDD 귝 (HANGUL SYLLABLE GYUG) 356 0xADDE 귞 (HANGUL SYLLABLE GYUGG) 357 0xADDF 귟 (HANGUL SYLLABLE GYUGS) 358 0xADE1 귡 (HANGUL SYLLABLE GYUNJ) 359 0xADE2 귢 (HANGUL SYLLABLE GYUNH) 360 0xADE3 귣 (HANGUL SYLLABLE GYUD) 361 0xADE5 귥 (HANGUL SYLLABLE GYULG) 362 0xADE6 귦 (HANGUL SYLLABLE GYULM) 363 0xADE7 귧 (HANGUL SYLLABLE GYULB) 364 0xADE8 귨 (HANGUL SYLLABLE GYULS) 365 0xADE9 귩 (HANGUL SYLLABLE GYULT) 366 0xADEA 귪 (HANGUL SYLLABLE GYULP) 367 0xADEB 귫 (HANGUL SYLLABLE GYULH) 368 0xADEC 귬 (HANGUL SYLLABLE GYUM) 369 0xADED 귭 (HANGUL SYLLABLE GYUB) 370 0xADEE 귮 (HANGUL SYLLABLE GYUBS) 371 0xADEF 귯 (HANGUL SYLLABLE GYUS) 372 0xADF0 귰 (HANGUL SYLLABLE GYUSS) 373 0xADF1 귱 (HANGUL SYLLABLE GYUNG) 374 0xADF2 귲 (HANGUL SYLLABLE GYUJ) 375 0xADF3 귳 (HANGUL SYLLABLE GYUC) 376 0xADF4 귴 (HANGUL SYLLABLE GYUK) 377 0xADF5 귵 (HANGUL SYLLABLE GYUT) 378 0xADF6 귶 (HANGUL SYLLABLE GYUP) 379 0xADF7 귷 (HANGUL SYLLABLE GYUH) 380 0xADFA 귺 (HANGUL SYLLABLE GEUGG) 381 0xADFB 귻 (HANGUL SYLLABLE GEUGS) 382 0xADFD 귽 (HANGUL SYLLABLE GEUNJ) 383 0xADFE 귾 (HANGUL SYLLABLE GEUNH) 384 0xAE02 긂 (HANGUL SYLLABLE GEULM) 385 0xAE03 긃 (HANGUL SYLLABLE GEULB) 386 0xAE04 긄 (HANGUL SYLLABLE GEULS) 387 0xAE05 긅 (HANGUL SYLLABLE GEULT) 388 0xAE06 긆 (HANGUL SYLLABLE GEULP) 389 0xAE07 긇 (HANGUL SYLLABLE GEULH) 390 0xAE0A 긊 (HANGUL SYLLABLE GEUBS) 391 0xAE0C 긌 (HANGUL SYLLABLE GEUSS) 392 0xAE0E 긎 (HANGUL SYLLABLE GEUJ) 393 0xAE0F 긏 (HANGUL SYLLABLE GEUC) 394 0xAE10 긐 (HANGUL SYLLABLE GEUK) 395 0xAE11 긑 (HANGUL SYLLABLE GEUT) 396 0xAE12 긒 (HANGUL SYLLABLE GEUP) 397 0xAE13 긓 (HANGUL SYLLABLE GEUH) 398 0xAE15 긕 (HANGUL SYLLABLE GYIG) 399 0xAE16 긖 (HANGUL SYLLABLE GYIGG) 400 0xAE17 긗 (HANGUL SYLLABLE GYIGS) 401 0xAE18 긘 (HANGUL SYLLABLE GYIN) 402 0xAE19 긙 (HANGUL SYLLABLE GYINJ) 403 0xAE1A 긚 (HANGUL SYLLABLE GYINH) 404 0xAE1B 긛 (HANGUL SYLLABLE GYID) 405 0xAE1C 긜 (HANGUL SYLLABLE GYIL) 412 0xAE1D 긝 (HANGUL SYLLABLE GYILG) 413 0xAE1E 긞 (HANGUL SYLLABLE GYILM) 414 0xAE1F 긟 (HANGUL SYLLABLE GYILB) 415 0xAE20 긠 (HANGUL SYLLABLE GYILS) 416 0xAE21 긡 (HANGUL SYLLABLE GYILT) 417 0xAE22 긢 (HANGUL SYLLABLE GYILP) 418 0xAE23 긣 (HANGUL SYLLABLE GYILH) 419 0xAE24 긤 (HANGUL SYLLABLE GYIM) 420 0xAE25 긥 (HANGUL SYLLABLE GYIB) 421 0xAE26 긦 (HANGUL SYLLABLE GYIBS) 422 0xAE27 긧 (HANGUL SYLLABLE GYIS) 423 0xAE28 긨 (HANGUL SYLLABLE GYISS) 424 0xAE29 긩 (HANGUL SYLLABLE GYING) 425 0xAE2A 긪 (HANGUL SYLLABLE GYIJ) 426 0xAE2B 긫 (HANGUL SYLLABLE GYIC) 427 0xAE2C 긬 (HANGUL SYLLABLE GYIK) 428 0xAE2D 긭 (HANGUL SYLLABLE GYIT) 429 0xAE2E 긮 (HANGUL SYLLABLE GYIP) 430 0xAE2F 긯 (HANGUL SYLLABLE GYIH) 431 0xAE32 긲 (HANGUL SYLLABLE GIGG) 432 0xAE33 긳 (HANGUL SYLLABLE GIGS) 433 0xAE35 긵 (HANGUL SYLLABLE GINJ) 434 0xAE36 긶 (HANGUL SYLLABLE GINH) 435 0xAE39 긹 (HANGUL SYLLABLE GILG) 436 0xAE3B 긻 (HANGUL SYLLABLE GILB) 437 0xAE3C 긼 (HANGUL SYLLABLE GILS) 444 0xAE3D 긽 (HANGUL SYLLABLE GILT) 445 0xAE3E 긾 (HANGUL SYLLABLE GILP) 446 0xAE3F 긿 (HANGUL SYLLABLE GILH) 447 0xAE42 깂 (HANGUL SYLLABLE GIBS) 448 0xAE44 깄 (HANGUL SYLLABLE GISS) 449 0xAE47 깇 (HANGUL SYLLABLE GIC) 450 0xAE48 깈 (HANGUL SYLLABLE GIK) 451 0xAE49 깉 (HANGUL SYLLABLE GIT) 452 0xAE4B 깋 (HANGUL SYLLABLE GIH) 453 0xAE4F 깏 (HANGUL SYLLABLE GGAGS) 454 0xAE51 깑 (HANGUL SYLLABLE GGANJ) 455 0xAE52 깒 (HANGUL SYLLABLE GGANH) 456 0xAE53 깓 (HANGUL SYLLABLE GGAD) 457 0xAE55 깕 (HANGUL SYLLABLE GGALG) 458 0xAE57 깗 (HANGUL SYLLABLE GGALB) 459 0xAE58 깘 (HANGUL SYLLABLE GGALS) 460 0xAE59 깙 (HANGUL SYLLABLE GGALT) 461 0xAE5A 깚 (HANGUL SYLLABLE GGALP) 462 0xAE5B 깛 (HANGUL SYLLABLE GGALH) 463 0xAE5E 깞 (HANGUL SYLLABLE GGABS) 464 0xAE62 깢 (HANGUL SYLLABLE GGAJ) 465 0xAE63 깣 (HANGUL SYLLABLE GGAC) 466 0xAE64 깤 (HANGUL SYLLABLE GGAK) 467 0xAE66 깦 (HANGUL SYLLABLE GGAP) 468 0xAE67 깧 (HANGUL SYLLABLE GGAH) 469 0xAE6A 깪 (HANGUL SYLLABLE GGAEGG) 470 0xAE6B 깫 (HANGUL SYLLABLE GGAEGS) 471 0xAE6D 깭 (HANGUL SYLLABLE GGAENJ) 472 0xAE6E 깮 (HANGUL SYLLABLE GGAENH) 473 0xAE6F 깯 (HANGUL SYLLABLE GGAED) 474 0xAE71 깱 (HANGUL SYLLABLE GGAELG) 475 0xAE72 깲 (HANGUL SYLLABLE GGAELM) 476 0xAE73 깳 (HANGUL SYLLABLE GGAELB) 477 0xAE74 깴 (HANGUL SYLLABLE GGAELS) 478 0xAE75 깵 (HANGUL SYLLABLE GGAELT) 479 0xAE76 깶 (HANGUL SYLLABLE GGAELP) 480 0xAE77 깷 (HANGUL SYLLABLE GGAELH) 481 0xAE7A 깺 (HANGUL SYLLABLE GGAEBS) 482 0xAE7E 깾 (HANGUL SYLLABLE GGAEJ) 483 0xAE7F 깿 (HANGUL SYLLABLE GGAEC) 484 0xAE80 꺀 (HANGUL SYLLABLE GGAEK) 485 0xAE81 꺁 (HANGUL SYLLABLE GGAET) 486 0xAE82 꺂 (HANGUL SYLLABLE GGAEP) 487 0xAE83 꺃 (HANGUL SYLLABLE GGAEH) 488 0xAE86 꺆 (HANGUL SYLLABLE GGYAGG) 489 0xAE87 꺇 (HANGUL SYLLABLE GGYAGS) 490 0xAE88 꺈 (HANGUL SYLLABLE GGYAN) 491 0xAE89 꺉 (HANGUL SYLLABLE GGYANJ) 492 0xAE8A 꺊 (HANGUL SYLLABLE GGYANH) 493 0xAE8B 꺋 (HANGUL SYLLABLE GGYAD) 494 0xAE8D 꺍 (HANGUL SYLLABLE GGYALG) 495 0xAE8E 꺎 (HANGUL SYLLABLE GGYALM) 496 0xAE8F 꺏 (HANGUL SYLLABLE GGYALB) 497 0xAE90 꺐 (HANGUL SYLLABLE GGYALS) 498 0xAE91 꺑 (HANGUL SYLLABLE GGYALT) 499 0xAE92 꺒 (HANGUL SYLLABLE GGYALP) 500 0xAE93 꺓 (HANGUL SYLLABLE GGYALH) 501 0xAE94 꺔 (HANGUL SYLLABLE GGYAM) 502 0xAE95 꺕 (HANGUL SYLLABLE GGYAB) 503 0xAE96 꺖 (HANGUL SYLLABLE GGYABS) 504 0xAE97 꺗 (HANGUL SYLLABLE GGYAS) 505 0xAE98 꺘 (HANGUL SYLLABLE GGYASS) 506 0xAE99 꺙 (HANGUL SYLLABLE GGYANG) 507 0xAE9A 꺚 (HANGUL SYLLABLE GGYAJ) 508 0xAE9B 꺛 (HANGUL SYLLABLE GGYAC) 509 0xAE9C 꺜 (HANGUL SYLLABLE GGYAK) 510 0xAE9D 꺝 (HANGUL SYLLABLE GGYAT) 511 0xAE9E 꺞 (HANGUL SYLLABLE GGYAP) 512 0xAE9F 꺟 (HANGUL SYLLABLE GGYAH) 513 0xAEA0 꺠 (HANGUL SYLLABLE GGYAE) 514 0xAEA1 꺡 (HANGUL SYLLABLE GGYAEG) 515 0xAEA2 꺢 (HANGUL SYLLABLE GGYAEGG) 516 0xAEA3 꺣 (HANGUL SYLLABLE GGYAEGS) 517 0xAEA4 꺤 (HANGUL SYLLABLE GGYAEN) 518 0xAEA5 꺥 (HANGUL SYLLABLE GGYAENJ) 519 0xAEA6 꺦 (HANGUL SYLLABLE GGYAENH) 520 0xAEA7 꺧 (HANGUL SYLLABLE GGYAED) 521 0xAEA8 꺨 (HANGUL SYLLABLE GGYAEL) 522 0xAEA9 꺩 (HANGUL SYLLABLE GGYAELG) 523 0xAEAA 꺪 (HANGUL SYLLABLE GGYAELM) 524 0xAEAB 꺫 (HANGUL SYLLABLE GGYAELB) 525 0xAEAC 꺬 (HANGUL SYLLABLE GGYAELS) 526 0xAEAD 꺭 (HANGUL SYLLABLE GGYAELT) 527 0xAEAE 꺮 (HANGUL SYLLABLE GGYAELP) 528 0xAEAF 꺯 (HANGUL SYLLABLE GGYAELH) 529 0xAEB0 꺰 (HANGUL SYLLABLE GGYAEM) 530 0xAEB1 꺱 (HANGUL SYLLABLE GGYAEB) 531 0xAEB2 꺲 (HANGUL SYLLABLE GGYAEBS) 532 0xAEB3 꺳 (HANGUL SYLLABLE GGYAES) 533 0xAEB4 꺴 (HANGUL SYLLABLE GGYAESS) 534 0xAEB5 꺵 (HANGUL SYLLABLE GGYAENG) 535 0xAEB6 꺶 (HANGUL SYLLABLE GGYAEJ) 536 0xAEB7 꺷 (HANGUL SYLLABLE GGYAEC) 537 0xAEB8 꺸 (HANGUL SYLLABLE GGYAEK) 538 0xAEB9 꺹 (HANGUL SYLLABLE GGYAET) 539 0xAEBA 꺺 (HANGUL SYLLABLE GGYAEP) 540 0xAEBB 꺻 (HANGUL SYLLABLE GGYAEH) 541 0xAEBF 꺿 (HANGUL SYLLABLE GGEOGS) 542 0xAEC1 껁 (HANGUL SYLLABLE GGEONJ) 543 0xAEC2 껂 (HANGUL SYLLABLE GGEONH) 544 0xAEC3 껃 (HANGUL SYLLABLE GGEOD) 545 0xAEC5 껅 (HANGUL SYLLABLE GGEOLG) 546 0xAEC6 껆 (HANGUL SYLLABLE GGEOLM) 547 0xAEC7 껇 (HANGUL SYLLABLE GGEOLB) 548 0xAEC8 껈 (HANGUL SYLLABLE GGEOLS) 549 0xAEC9 껉 (HANGUL SYLLABLE GGEOLT) 550 0xAECA 껊 (HANGUL SYLLABLE GGEOLP) 551 0xAECB 껋 (HANGUL SYLLABLE GGEOLH) 552 0xAECE 껎 (HANGUL SYLLABLE GGEOBS) 553 0xAED2 껒 (HANGUL SYLLABLE GGEOJ) 554 0xAED3 껓 (HANGUL SYLLABLE GGEOC) 555 0xAED4 껔 (HANGUL SYLLABLE GGEOK) 556 0xAED5 껕 (HANGUL SYLLABLE GGEOT) 557 0xAED6 껖 (HANGUL SYLLABLE GGEOP) 558 0xAED7 껗 (HANGUL SYLLABLE GGEOH) 559 0xAEDA 껚 (HANGUL SYLLABLE GGEGG) 560 0xAEDB 껛 (HANGUL SYLLABLE GGEGS) 561 0xAEDD 껝 (HANGUL SYLLABLE GGENJ) 562 0xAEDE 껞 (HANGUL SYLLABLE GGENH) 563 0xAEDF 껟 (HANGUL SYLLABLE GGED) 564 0xAEE0 껠 (HANGUL SYLLABLE GGEL) 565 0xAEE1 껡 (HANGUL SYLLABLE GGELG) 566 0xAEE2 껢 (HANGUL SYLLABLE GGELM) 567 0xAEE3 껣 (HANGUL SYLLABLE GGELB) 568 0xAEE4 껤 (HANGUL SYLLABLE GGELS) 569 0xAEE5 껥 (HANGUL SYLLABLE GGELT) 570 0xAEE6 껦 (HANGUL SYLLABLE GGELP) 571 0xAEE7 껧 (HANGUL SYLLABLE GGELH) 572 0xAEE9 껩 (HANGUL SYLLABLE GGEB) 573 0xAEEA 껪 (HANGUL SYLLABLE GGEBS) 574 0xAEEC 껬 (HANGUL SYLLABLE GGESS) 575 0xAEEE 껮 (HANGUL SYLLABLE GGEJ) 576 0xAEEF 껯 (HANGUL SYLLABLE GGEC) 577 0xAEF0 껰 (HANGUL SYLLABLE GGEK) 578 0xAEF1 껱 (HANGUL SYLLABLE GGET) 579 0xAEF2 껲 (HANGUL SYLLABLE GGEP) 580 0xAEF3 껳 (HANGUL SYLLABLE GGEH) 581 0xAEF5 껵 (HANGUL SYLLABLE GGYEOG) 582 0xAEF6 껶 (HANGUL SYLLABLE GGYEOGG) 583 0xAEF7 껷 (HANGUL SYLLABLE GGYEOGS) 584 0xAEF9 껹 (HANGUL SYLLABLE GGYEONJ) 585 0xAEFA 껺 (HANGUL SYLLABLE GGYEONH) 586 0xAEFB 껻 (HANGUL SYLLABLE GGYEOD) 587 0xAEFD 껽 (HANGUL SYLLABLE GGYEOLG) 588 0xAEFE 껾 (HANGUL SYLLABLE GGYEOLM) 589 0xAEFF 껿 (HANGUL SYLLABLE GGYEOLB) 590 0xAF00 꼀 (HANGUL SYLLABLE GGYEOLS) 591 0xAF01 꼁 (HANGUL SYLLABLE GGYEOLT) 592 0xAF02 꼂 (HANGUL SYLLABLE GGYEOLP) 593 0xAF03 꼃 (HANGUL SYLLABLE GGYEOLH) 594 0xAF04 꼄 (HANGUL SYLLABLE GGYEOM) 595 0xAF05 꼅 (HANGUL SYLLABLE GGYEOB) 602 0xAF06 꼆 (HANGUL SYLLABLE GGYEOBS) 603 0xAF09 꼉 (HANGUL SYLLABLE GGYEONG) 604 0xAF0A 꼊 (HANGUL SYLLABLE GGYEOJ) 605 0xAF0B 꼋 (HANGUL SYLLABLE GGYEOC) 606 0xAF0C 꼌 (HANGUL SYLLABLE GGYEOK) 607 0xAF0E 꼎 (HANGUL SYLLABLE GGYEOP) 608 0xAF0F 꼏 (HANGUL SYLLABLE GGYEOH) 609 0xAF11 꼑 (HANGUL SYLLABLE GGYEG) 610 0xAF12 꼒 (HANGUL SYLLABLE GGYEGG) 611 0xAF13 꼓 (HANGUL SYLLABLE GGYEGS) 612 0xAF14 꼔 (HANGUL SYLLABLE GGYEN) 613 0xAF15 꼕 (HANGUL SYLLABLE GGYENJ) 614 0xAF16 꼖 (HANGUL SYLLABLE GGYENH) 615 0xAF17 꼗 (HANGUL SYLLABLE GGYED) 616 0xAF18 꼘 (HANGUL SYLLABLE GGYEL) 617 0xAF19 꼙 (HANGUL SYLLABLE GGYELG) 618 0xAF1A 꼚 (HANGUL SYLLABLE GGYELM) 619 0xAF1B 꼛 (HANGUL SYLLABLE GGYELB) 620 0xAF1C 꼜 (HANGUL SYLLABLE GGYELS) 621 0xAF1D 꼝 (HANGUL SYLLABLE GGYELT) 622 0xAF1E 꼞 (HANGUL SYLLABLE GGYELP) 623 0xAF1F 꼟 (HANGUL SYLLABLE GGYELH) 624 0xAF20 꼠 (HANGUL SYLLABLE GGYEM) 625 0xAF21 꼡 (HANGUL SYLLABLE GGYEB) 626 0xAF22 꼢 (HANGUL SYLLABLE GGYEBS) 627 0xAF23 꼣 (HANGUL SYLLABLE GGYES) 634 0xAF24 꼤 (HANGUL SYLLABLE GGYESS) 635 0xAF25 꼥 (HANGUL SYLLABLE GGYENG) 636 0xAF26 꼦 (HANGUL SYLLABLE GGYEJ) 637 0xAF27 꼧 (HANGUL SYLLABLE GGYEC) 638 0xAF28 꼨 (HANGUL SYLLABLE GGYEK) 639 0xAF29 꼩 (HANGUL SYLLABLE GGYET) 640 0xAF2A 꼪 (HANGUL SYLLABLE GGYEP) 641 0xAF2B 꼫 (HANGUL SYLLABLE GGYEH) 642 0xAF2E 꼮 (HANGUL SYLLABLE GGOGG) 643 0xAF2F 꼯 (HANGUL SYLLABLE GGOGS) 644 0xAF31 꼱 (HANGUL SYLLABLE GGONJ) 645 0xAF33 꼳 (HANGUL SYLLABLE GGOD) 646 0xAF35 꼵 (HANGUL SYLLABLE GGOLG) 647 0xAF36 꼶 (HANGUL SYLLABLE GGOLM) 648 0xAF37 꼷 (HANGUL SYLLABLE GGOLB) 649 0xAF38 꼸 (HANGUL SYLLABLE GGOLS) 650 0xAF39 꼹 (HANGUL SYLLABLE GGOLT) 651 0xAF3A 꼺 (HANGUL SYLLABLE GGOLP) 652 0xAF3B 꼻 (HANGUL SYLLABLE GGOLH) 653 0xAF3E 꼾 (HANGUL SYLLABLE GGOBS) 654 0xAF40 꽀 (HANGUL SYLLABLE GGOSS) 655 0xAF44 꽄 (HANGUL SYLLABLE GGOK) 656 0xAF45 꽅 (HANGUL SYLLABLE GGOT) 657 0xAF46 꽆 (HANGUL SYLLABLE GGOP) 658 0xAF47 꽇 (HANGUL SYLLABLE GGOH) 659 0xAF4A 꽊 (HANGUL SYLLABLE GGWAGG) 660 0xAF4B 꽋 (HANGUL SYLLABLE GGWAGS) 661 0xAF4C 꽌 (HANGUL SYLLABLE GGWAN) 662 0xAF4D 꽍 (HANGUL SYLLABLE GGWANJ) 663 0xAF4E 꽎 (HANGUL SYLLABLE GGWANH) 664 0xAF4F 꽏 (HANGUL SYLLABLE GGWAD) 665 0xAF51 꽑 (HANGUL SYLLABLE GGWALG) 666 0xAF52 꽒 (HANGUL SYLLABLE GGWALM) 667 0xAF53 꽓 (HANGUL SYLLABLE GGWALB) 668 0xAF54 꽔 (HANGUL SYLLABLE GGWALS) 669 0xAF55 꽕 (HANGUL SYLLABLE GGWALT) 670 0xAF56 꽖 (HANGUL SYLLABLE GGWALP) 671 0xAF57 꽗 (HANGUL SYLLABLE GGWALH) 672 0xAF58 꽘 (HANGUL SYLLABLE GGWAM) 673 0xAF59 꽙 (HANGUL SYLLABLE GGWAB) 674 0xAF5A 꽚 (HANGUL SYLLABLE GGWABS) 675 0xAF5B 꽛 (HANGUL SYLLABLE GGWAS) 676 0xAF5E 꽞 (HANGUL SYLLABLE GGWAJ) 677 0xAF5F 꽟 (HANGUL SYLLABLE GGWAC) 678 0xAF60 꽠 (HANGUL SYLLABLE GGWAK) 679 0xAF61 꽡 (HANGUL SYLLABLE GGWAT) 680 0xAF62 꽢 (HANGUL SYLLABLE GGWAP) 681 0xAF63 꽣 (HANGUL SYLLABLE GGWAH) 682 0xAF66 꽦 (HANGUL SYLLABLE GGWAEGG) 683 0xAF67 꽧 (HANGUL SYLLABLE GGWAEGS) 684 0xAF68 꽨 (HANGUL SYLLABLE GGWAEN) 685 0xAF69 꽩 (HANGUL SYLLABLE GGWAENJ) 686 0xAF6A 꽪 (HANGUL SYLLABLE GGWAENH) 687 0xAF6B 꽫 (HANGUL SYLLABLE GGWAED) 688 0xAF6C 꽬 (HANGUL SYLLABLE GGWAEL) 689 0xAF6D 꽭 (HANGUL SYLLABLE GGWAELG) 690 0xAF6E 꽮 (HANGUL SYLLABLE GGWAELM) 691 0xAF6F 꽯 (HANGUL SYLLABLE GGWAELB) 692 0xAF70 꽰 (HANGUL SYLLABLE GGWAELS) 693 0xAF71 꽱 (HANGUL SYLLABLE GGWAELT) 694 0xAF72 꽲 (HANGUL SYLLABLE GGWAELP) 695 0xAF73 꽳 (HANGUL SYLLABLE GGWAELH) 696 0xAF74 꽴 (HANGUL SYLLABLE GGWAEM) 697 0xAF75 꽵 (HANGUL SYLLABLE GGWAEB) 698 0xAF76 꽶 (HANGUL SYLLABLE GGWAEBS) 699 0xAF77 꽷 (HANGUL SYLLABLE GGWAES) 700 0xAF78 꽸 (HANGUL SYLLABLE GGWAESS) 701 0xAF7A 꽺 (HANGUL SYLLABLE GGWAEJ) 702 0xAF7B 꽻 (HANGUL SYLLABLE GGWAEC) 703 0xAF7C 꽼 (HANGUL SYLLABLE GGWAEK) 704 0xAF7D 꽽 (HANGUL SYLLABLE GGWAET) 705 0xAF7E 꽾 (HANGUL SYLLABLE GGWAEP) 706 0xAF7F 꽿 (HANGUL SYLLABLE GGWAEH) 707 0xAF81 꾁 (HANGUL SYLLABLE GGOEG) 708 0xAF82 꾂 (HANGUL SYLLABLE GGOEGG) 709 0xAF83 꾃 (HANGUL SYLLABLE GGOEGS) 710 0xAF85 꾅 (HANGUL SYLLABLE GGOENJ) 711 0xAF86 꾆 (HANGUL SYLLABLE GGOENH) 712 0xAF87 꾇 (HANGUL SYLLABLE GGOED) 713 0xAF89 꾉 (HANGUL SYLLABLE GGOELG) 714 0xAF8A 꾊 (HANGUL SYLLABLE GGOELM) 715 0xAF8B 꾋 (HANGUL SYLLABLE GGOELB) 716 0xAF8C 꾌 (HANGUL SYLLABLE GGOELS) 717 0xAF8D 꾍 (HANGUL SYLLABLE GGOELT) 718 0xAF8E 꾎 (HANGUL SYLLABLE GGOELP) 719 0xAF8F 꾏 (HANGUL SYLLABLE GGOELH) 720 0xAF92 꾒 (HANGUL SYLLABLE GGOEBS) 721 0xAF93 꾓 (HANGUL SYLLABLE GGOES) 722 0xAF94 꾔 (HANGUL SYLLABLE GGOESS) 723 0xAF96 꾖 (HANGUL SYLLABLE GGOEJ) 724 0xAF97 꾗 (HANGUL SYLLABLE GGOEC) 725 0xAF98 꾘 (HANGUL SYLLABLE GGOEK) 726 0xAF99 꾙 (HANGUL SYLLABLE GGOET) 727 0xAF9A 꾚 (HANGUL SYLLABLE GGOEP) 728 0xAF9B 꾛 (HANGUL SYLLABLE GGOEH) 729 0xAF9D 꾝 (HANGUL SYLLABLE GGYOG) 730 0xAF9E 꾞 (HANGUL SYLLABLE GGYOGG) 731 0xAF9F 꾟 (HANGUL SYLLABLE GGYOGS) 732 0xAFA0 꾠 (HANGUL SYLLABLE GGYON) 733 0xAFA1 꾡 (HANGUL SYLLABLE GGYONJ) 734 0xAFA2 꾢 (HANGUL SYLLABLE GGYONH) 735 0xAFA3 꾣 (HANGUL SYLLABLE GGYOD) 736 0xAFA4 꾤 (HANGUL SYLLABLE GGYOL) 737 0xAFA5 꾥 (HANGUL SYLLABLE GGYOLG) 738 0xAFA6 꾦 (HANGUL SYLLABLE GGYOLM) 739 0xAFA7 꾧 (HANGUL SYLLABLE GGYOLB) 740 0xAFA8 꾨 (HANGUL SYLLABLE GGYOLS) 741 0xAFA9 꾩 (HANGUL SYLLABLE GGYOLT) 742 0xAFAA 꾪 (HANGUL SYLLABLE GGYOLP) 743 0xAFAB 꾫 (HANGUL SYLLABLE GGYOLH) 744 0xAFAC 꾬 (HANGUL SYLLABLE GGYOM) 745 0xAFAD 꾭 (HANGUL SYLLABLE GGYOB) 746 0xAFAE 꾮 (HANGUL SYLLABLE GGYOBS) 747 0xAFAF 꾯 (HANGUL SYLLABLE GGYOS) 748 0xAFB0 꾰 (HANGUL SYLLABLE GGYOSS) 749 0xAFB1 꾱 (HANGUL SYLLABLE GGYONG) 750 0xAFB2 꾲 (HANGUL SYLLABLE GGYOJ) 751 0xAFB3 꾳 (HANGUL SYLLABLE GGYOC) 752 0xAFB4 꾴 (HANGUL SYLLABLE GGYOK) 753 0xAFB5 꾵 (HANGUL SYLLABLE GGYOT) 754 0xAFB6 꾶 (HANGUL SYLLABLE GGYOP) 755 0xAFB7 꾷 (HANGUL SYLLABLE GGYOH) 756 0xAFBA 꾺 (HANGUL SYLLABLE GGUGG) 757 0xAFBB 꾻 (HANGUL SYLLABLE GGUGS) 758 0xAFBD 꾽 (HANGUL SYLLABLE GGUNJ) 759 0xAFBE 꾾 (HANGUL SYLLABLE GGUNH) 760 0xAFBF 꾿 (HANGUL SYLLABLE GGUD) 761 0xAFC1 꿁 (HANGUL SYLLABLE GGULG) 762 0xAFC2 꿂 (HANGUL SYLLABLE GGULM) 763 0xAFC3 꿃 (HANGUL SYLLABLE GGULB) 764 0xAFC4 꿄 (HANGUL SYLLABLE GGULS) 765 0xAFC5 꿅 (HANGUL SYLLABLE GGULT) 766 0xAFC6 꿆 (HANGUL SYLLABLE GGULP) 767 0xAFCA 꿊 (HANGUL SYLLABLE GGUBS) 768 0xAFCC 꿌 (HANGUL SYLLABLE GGUSS) 769 0xAFCF 꿏 (HANGUL SYLLABLE GGUC) 770 0xAFD0 꿐 (HANGUL SYLLABLE GGUK) 771 0xAFD1 꿑 (HANGUL SYLLABLE GGUT) 772 0xAFD2 꿒 (HANGUL SYLLABLE GGUP) 773 0xAFD3 꿓 (HANGUL SYLLABLE GGUH) 774 0xAFD5 꿕 (HANGUL SYLLABLE GGWEOG) 775 0xAFD6 꿖 (HANGUL SYLLABLE GGWEOGG) 776 0xAFD7 꿗 (HANGUL SYLLABLE GGWEOGS) 777 0xAFD8 꿘 (HANGUL SYLLABLE GGWEON) 778 0xAFD9 꿙 (HANGUL SYLLABLE GGWEONJ) 779 0xAFDA 꿚 (HANGUL SYLLABLE GGWEONH) 780 0xAFDB 꿛 (HANGUL SYLLABLE GGWEOD) 781 0xAFDD 꿝 (HANGUL SYLLABLE GGWEOLG) 782 0xAFDE 꿞 (HANGUL SYLLABLE GGWEOLM) 783 0xAFDF 꿟 (HANGUL SYLLABLE GGWEOLB) 784 0xAFE0 꿠 (HANGUL SYLLABLE GGWEOLS) 785 0xAFE1 꿡 (HANGUL SYLLABLE GGWEOLT) 792 0xAFE2 꿢 (HANGUL SYLLABLE GGWEOLP) 793 0xAFE3 꿣 (HANGUL SYLLABLE GGWEOLH) 794 0xAFE4 꿤 (HANGUL SYLLABLE GGWEOM) 795 0xAFE5 꿥 (HANGUL SYLLABLE GGWEOB) 796 0xAFE6 꿦 (HANGUL SYLLABLE GGWEOBS) 797 0xAFE7 꿧 (HANGUL SYLLABLE GGWEOS) 798 0xAFEA 꿪 (HANGUL SYLLABLE GGWEOJ) 799 0xAFEB 꿫 (HANGUL SYLLABLE GGWEOC) 800 0xAFEC 꿬 (HANGUL SYLLABLE GGWEOK) 801 0xAFED 꿭 (HANGUL SYLLABLE GGWEOT) 802 0xAFEE 꿮 (HANGUL SYLLABLE GGWEOP) 803 0xAFEF 꿯 (HANGUL SYLLABLE GGWEOH) 804 0xAFF2 꿲 (HANGUL SYLLABLE GGWEGG) 805 0xAFF3 꿳 (HANGUL SYLLABLE GGWEGS) 806 0xAFF5 꿵 (HANGUL SYLLABLE GGWENJ) 807 0xAFF6 꿶 (HANGUL SYLLABLE GGWENH) 808 0xAFF7 꿷 (HANGUL SYLLABLE GGWED) 809 0xAFF9 꿹 (HANGUL SYLLABLE GGWELG) 810 0xAFFA 꿺 (HANGUL SYLLABLE GGWELM) 811 0xAFFB 꿻 (HANGUL SYLLABLE GGWELB) 812 0xAFFC 꿼 (HANGUL SYLLABLE GGWELS) 813 0xAFFD 꿽 (HANGUL SYLLABLE GGWELT) 814 0xAFFE 꿾 (HANGUL SYLLABLE GGWELP) 815 0xAFFF 꿿 (HANGUL SYLLABLE GGWELH) 816 0xB002 뀂 (HANGUL SYLLABLE GGWEBS) 817 0xB003 뀃 (HANGUL SYLLABLE GGWES) 824 0xB005 뀅 (HANGUL SYLLABLE GGWENG) 825 0xB006 뀆 (HANGUL SYLLABLE GGWEJ) 826 0xB007 뀇 (HANGUL SYLLABLE GGWEC) 827 0xB008 뀈 (HANGUL SYLLABLE GGWEK) 828 0xB009 뀉 (HANGUL SYLLABLE GGWET) 829 0xB00A 뀊 (HANGUL SYLLABLE GGWEP) 830 0xB00B 뀋 (HANGUL SYLLABLE GGWEH) 831 0xB00D 뀍 (HANGUL SYLLABLE GGWIG) 832 0xB00E 뀎 (HANGUL SYLLABLE GGWIGG) 833 0xB00F 뀏 (HANGUL SYLLABLE GGWIGS) 834 0xB011 뀑 (HANGUL SYLLABLE GGWINJ) 835 0xB012 뀒 (HANGUL SYLLABLE GGWINH) 836 0xB013 뀓 (HANGUL SYLLABLE GGWID) 837 0xB015 뀕 (HANGUL SYLLABLE GGWILG) 838 0xB016 뀖 (HANGUL SYLLABLE GGWILM) 839 0xB017 뀗 (HANGUL SYLLABLE GGWILB) 840 0xB018 뀘 (HANGUL SYLLABLE GGWILS) 841 0xB019 뀙 (HANGUL SYLLABLE GGWILT) 842 0xB01A 뀚 (HANGUL SYLLABLE GGWILP) 843 0xB01B 뀛 (HANGUL SYLLABLE GGWILH) 844 0xB01E 뀞 (HANGUL SYLLABLE GGWIBS) 845 0xB01F 뀟 (HANGUL SYLLABLE GGWIS) 846 0xB020 뀠 (HANGUL SYLLABLE GGWISS) 847 0xB021 뀡 (HANGUL SYLLABLE GGWING) 848 0xB022 뀢 (HANGUL SYLLABLE GGWIJ) 849 0xB023 뀣 (HANGUL SYLLABLE GGWIC) 850 0xB024 뀤 (HANGUL SYLLABLE GGWIK) 851 0xB025 뀥 (HANGUL SYLLABLE GGWIT) 852 0xB026 뀦 (HANGUL SYLLABLE GGWIP) 853 0xB027 뀧 (HANGUL SYLLABLE GGWIH) 854 0xB029 뀩 (HANGUL SYLLABLE GGYUG) 855 0xB02A 뀪 (HANGUL SYLLABLE GGYUGG) 856 0xB02B 뀫 (HANGUL SYLLABLE GGYUGS) 857 0xB02C 뀬 (HANGUL SYLLABLE GGYUN) 858 0xB02D 뀭 (HANGUL SYLLABLE GGYUNJ) 859 0xB02E 뀮 (HANGUL SYLLABLE GGYUNH) 860 0xB02F 뀯 (HANGUL SYLLABLE GGYUD) 861 0xB030 뀰 (HANGUL SYLLABLE GGYUL) 862 0xB031 뀱 (HANGUL SYLLABLE GGYULG) 863 0xB032 뀲 (HANGUL SYLLABLE GGYULM) 864 0xB033 뀳 (HANGUL SYLLABLE GGYULB) 865 0xB034 뀴 (HANGUL SYLLABLE GGYULS) 866 0xB035 뀵 (HANGUL SYLLABLE GGYULT) 867 0xB036 뀶 (HANGUL SYLLABLE GGYULP) 868 0xB037 뀷 (HANGUL SYLLABLE GGYULH) 869 0xB038 뀸 (HANGUL SYLLABLE GGYUM) 870 0xB039 뀹 (HANGUL SYLLABLE GGYUB) 871 0xB03A 뀺 (HANGUL SYLLABLE GGYUBS) 872 0xB03B 뀻 (HANGUL SYLLABLE GGYUS) 873 0xB03C 뀼 (HANGUL SYLLABLE GGYUSS) 874 0xB03D 뀽 (HANGUL SYLLABLE GGYUNG) 875 0xB03E 뀾 (HANGUL SYLLABLE GGYUJ) 876 0xB03F 뀿 (HANGUL SYLLABLE GGYUC) 877 0xB040 끀 (HANGUL SYLLABLE GGYUK) 878 0xB041 끁 (HANGUL SYLLABLE GGYUT) 879 0xB042 끂 (HANGUL SYLLABLE GGYUP) 880 0xB043 끃 (HANGUL SYLLABLE GGYUH) 881 0xB046 끆 (HANGUL SYLLABLE GGEUGG) 882 0xB047 끇 (HANGUL SYLLABLE GGEUGS) 883 0xB049 끉 (HANGUL SYLLABLE GGEUNJ) 884 0xB04B 끋 (HANGUL SYLLABLE GGEUD) 885 0xB04D 끍 (HANGUL SYLLABLE GGEULG) 886 0xB04F 끏 (HANGUL SYLLABLE GGEULB) 887 0xB050 끐 (HANGUL SYLLABLE GGEULS) 888 0xB051 끑 (HANGUL SYLLABLE GGEULT) 889 0xB052 끒 (HANGUL SYLLABLE GGEULP) 890 0xB056 끖 (HANGUL SYLLABLE GGEUBS) 891 0xB058 끘 (HANGUL SYLLABLE GGEUSS) 892 0xB05A 끚 (HANGUL SYLLABLE GGEUJ) 893 0xB05B 끛 (HANGUL SYLLABLE GGEUC) 894 0xB05C 끜 (HANGUL SYLLABLE GGEUK) 895 0xB05E 끞 (HANGUL SYLLABLE GGEUP) 896 0xB05F 끟 (HANGUL SYLLABLE GGEUH) 897 0xB060 끠 (HANGUL SYLLABLE GGYI) 898 0xB061 끡 (HANGUL SYLLABLE GGYIG) 899 0xB062 끢 (HANGUL SYLLABLE GGYIGG) 900 0xB063 끣 (HANGUL SYLLABLE GGYIGS) 901 0xB064 끤 (HANGUL SYLLABLE GGYIN) 902 0xB065 끥 (HANGUL SYLLABLE GGYINJ) 903 0xB066 끦 (HANGUL SYLLABLE GGYINH) 904 0xB067 끧 (HANGUL SYLLABLE GGYID) 905 0xB068 끨 (HANGUL SYLLABLE GGYIL) 906 0xB069 끩 (HANGUL SYLLABLE GGYILG) 907 0xB06A 끪 (HANGUL SYLLABLE GGYILM) 908 0xB06B 끫 (HANGUL SYLLABLE GGYILB) 909 0xB06C 끬 (HANGUL SYLLABLE GGYILS) 910 0xB06D 끭 (HANGUL SYLLABLE GGYILT) 911 0xB06E 끮 (HANGUL SYLLABLE GGYILP) 912 0xB06F 끯 (HANGUL SYLLABLE GGYILH) 913 0xB070 끰 (HANGUL SYLLABLE GGYIM) 914 0xB071 끱 (HANGUL SYLLABLE GGYIB) 915 0xB072 끲 (HANGUL SYLLABLE GGYIBS) 916 0xB073 끳 (HANGUL SYLLABLE GGYIS) 917 0xB074 끴 (HANGUL SYLLABLE GGYISS) 918 0xB075 끵 (HANGUL SYLLABLE GGYING) 919 0xB076 끶 (HANGUL SYLLABLE GGYIJ) 920 0xB077 끷 (HANGUL SYLLABLE GGYIC) 921 0xB078 끸 (HANGUL SYLLABLE GGYIK) 922 0xB079 끹 (HANGUL SYLLABLE GGYIT) 923 0xB07A 끺 (HANGUL SYLLABLE GGYIP) 924 0xB07B 끻 (HANGUL SYLLABLE GGYIH) 925 0xB07E 끾 (HANGUL SYLLABLE GGIGG) 926 0xB07F 끿 (HANGUL SYLLABLE GGIGS) 927 0xB081 낁 (HANGUL SYLLABLE GGINJ) 928 0xB082 낂 (HANGUL SYLLABLE GGINH) 929 0xB083 낃 (HANGUL SYLLABLE GGID) 930 0xB085 낅 (HANGUL SYLLABLE GGILG) 931 0xB086 낆 (HANGUL SYLLABLE GGILM) 932 0xB087 낇 (HANGUL SYLLABLE GGILB) 933 0xB088 낈 (HANGUL SYLLABLE GGILS) 934 0xB089 낉 (HANGUL SYLLABLE GGILT) 935 0xB08A 낊 (HANGUL SYLLABLE GGILP) 936 0xB08B 낋 (HANGUL SYLLABLE GGILH) 937 0xB08E 낎 (HANGUL SYLLABLE GGIBS) 938 0xB090 낐 (HANGUL SYLLABLE GGISS) 939 0xB092 낒 (HANGUL SYLLABLE GGIJ) 940 0xB093 낓 (HANGUL SYLLABLE GGIC) 941 0xB094 낔 (HANGUL SYLLABLE GGIK) 942 0xB095 낕 (HANGUL SYLLABLE GGIT) 943 0xB096 낖 (HANGUL SYLLABLE GGIP) 944 0xB097 낗 (HANGUL SYLLABLE GGIH) 945 0xB09B 낛 (HANGUL SYLLABLE NAGS) 946 0xB09D 낝 (HANGUL SYLLABLE NANJ) 947 0xB09E 낞 (HANGUL SYLLABLE NANH) 948 0xB0A3 낣 (HANGUL SYLLABLE NALB) 949 0xB0A4 낤 (HANGUL SYLLABLE NALS) 950 0xB0A5 낥 (HANGUL SYLLABLE NALT) 951 0xB0A6 낦 (HANGUL SYLLABLE NALP) 952 0xB0A7 낧 (HANGUL SYLLABLE NALH) 953 0xB0AA 낪 (HANGUL SYLLABLE NABS) 954 0xB0B0 낰 (HANGUL SYLLABLE NAK) 955 0xB0B2 낲 (HANGUL SYLLABLE NAP) 956 0xB0B6 낶 (HANGUL SYLLABLE NAEGG) 957 0xB0B7 낷 (HANGUL SYLLABLE NAEGS) 958 0xB0B9 낹 (HANGUL SYLLABLE NAENJ) 959 0xB0BA 낺 (HANGUL SYLLABLE NAENH) 960 0xB0BB 낻 (HANGUL SYLLABLE NAED) 961 0xB0BD 낽 (HANGUL SYLLABLE NAELG) 962 0xB0BE 낾 (HANGUL SYLLABLE NAELM) 963 0xB0BF 낿 (HANGUL SYLLABLE NAELB) 964 0xB0C0 냀 (HANGUL SYLLABLE NAELS) 965 0xB0C1 냁 (HANGUL SYLLABLE NAELT) 966 0xB0C2 냂 (HANGUL SYLLABLE NAELP) 967 0xB0C3 냃 (HANGUL SYLLABLE NAELH) 968 0xB0C6 냆 (HANGUL SYLLABLE NAEBS) 969 0xB0CA 냊 (HANGUL SYLLABLE NAEJ) 970 0xB0CB 냋 (HANGUL SYLLABLE NAEC) 971 0xB0CC 냌 (HANGUL SYLLABLE NAEK) 972 0xB0CD 냍 (HANGUL SYLLABLE NAET) 973 0xB0CE 냎 (HANGUL SYLLABLE NAEP) 974 0xB0CF 냏 (HANGUL SYLLABLE NAEH) 975 0xB0D2 냒 (HANGUL SYLLABLE NYAGG) 982 0xB0D3 냓 (HANGUL SYLLABLE NYAGS) 983 0xB0D5 냕 (HANGUL SYLLABLE NYANJ) 984 0xB0D6 냖 (HANGUL SYLLABLE NYANH) 985 0xB0D7 냗 (HANGUL SYLLABLE NYAD) 986 0xB0D9 냙 (HANGUL SYLLABLE NYALG) 987 0xB0DA 냚 (HANGUL SYLLABLE NYALM) 988 0xB0DB 냛 (HANGUL SYLLABLE NYALB) 989 0xB0DC 냜 (HANGUL SYLLABLE NYALS) 990 0xB0DD 냝 (HANGUL SYLLABLE NYALT) 991 0xB0DE 냞 (HANGUL SYLLABLE NYALP) 992 0xB0DF 냟 (HANGUL SYLLABLE NYALH) 993 0xB0E1 냡 (HANGUL SYLLABLE NYAB) 994 0xB0E2 냢 (HANGUL SYLLABLE NYABS) 995 0xB0E3 냣 (HANGUL SYLLABLE NYAS) 996 0xB0E4 냤 (HANGUL SYLLABLE NYASS) 997 0xB0E6 냦 (HANGUL SYLLABLE NYAJ) 998 0xB0E7 냧 (HANGUL SYLLABLE NYAC) 999 0xB0E8 냨 (HANGUL SYLLABLE NYAK) 1000 0xB0E9 냩 (HANGUL SYLLABLE NYAT) 1001 0xB0EA 냪 (HANGUL SYLLABLE NYAP) 1002 0xB0EB 냫 (HANGUL SYLLABLE NYAH) 1003 0xB0EC 냬 (HANGUL SYLLABLE NYAE) 1004 0xB0ED 냭 (HANGUL SYLLABLE NYAEG) 1005 0xB0EE 냮 (HANGUL SYLLABLE NYAEGG) 1006 0xB0EF 냯 (HANGUL SYLLABLE NYAEGS) 1007 0xB0F0 냰 (HANGUL SYLLABLE NYAEN) 1014 0xB0F1 냱 (HANGUL SYLLABLE NYAENJ) 1015 0xB0F2 냲 (HANGUL SYLLABLE NYAENH) 1016 0xB0F3 냳 (HANGUL SYLLABLE NYAED) 1017 0xB0F4 냴 (HANGUL SYLLABLE NYAEL) 1018 0xB0F5 냵 (HANGUL SYLLABLE NYAELG) 1019 0xB0F6 냶 (HANGUL SYLLABLE NYAELM) 1020 0xB0F7 냷 (HANGUL SYLLABLE NYAELB) 1021 0xB0F8 냸 (HANGUL SYLLABLE NYAELS) 1022 0xB0F9 냹 (HANGUL SYLLABLE NYAELT) 1023 0xB0FA 냺 (HANGUL SYLLABLE NYAELP) 1024 0xB0FB 냻 (HANGUL SYLLABLE NYAELH) 1025 0xB0FC 냼 (HANGUL SYLLABLE NYAEM) 1026 0xB0FD 냽 (HANGUL SYLLABLE NYAEB) 1027 0xB0FE 냾 (HANGUL SYLLABLE NYAEBS) 1028 0xB0FF 냿 (HANGUL SYLLABLE NYAES) 1029 0xB100 넀 (HANGUL SYLLABLE NYAESS) 1030 0xB101 넁 (HANGUL SYLLABLE NYAENG) 1031 0xB102 넂 (HANGUL SYLLABLE NYAEJ) 1032 0xB103 넃 (HANGUL SYLLABLE NYAEC) 1033 0xB104 넄 (HANGUL SYLLABLE NYAEK) 1034 0xB105 넅 (HANGUL SYLLABLE NYAET) 1035 0xB106 넆 (HANGUL SYLLABLE NYAEP) 1036 0xB107 넇 (HANGUL SYLLABLE NYAEH) 1037 0xB10A 넊 (HANGUL SYLLABLE NEOGG) 1038 0xB10D 넍 (HANGUL SYLLABLE NEONJ) 1039 0xB10E 넎 (HANGUL SYLLABLE NEONH) 1040 0xB10F 넏 (HANGUL SYLLABLE NEOD) 1041 0xB111 넑 (HANGUL SYLLABLE NEOLG) 1042 0xB114 넔 (HANGUL SYLLABLE NEOLS) 1043 0xB115 넕 (HANGUL SYLLABLE NEOLT) 1044 0xB116 넖 (HANGUL SYLLABLE NEOLP) 1045 0xB117 넗 (HANGUL SYLLABLE NEOLH) 1046 0xB11A 넚 (HANGUL SYLLABLE NEOBS) 1047 0xB11E 넞 (HANGUL SYLLABLE NEOJ) 1048 0xB11F 넟 (HANGUL SYLLABLE NEOC) 1049 0xB120 넠 (HANGUL SYLLABLE NEOK) 1050 0xB121 넡 (HANGUL SYLLABLE NEOT) 1051 0xB122 넢 (HANGUL SYLLABLE NEOP) 1052 0xB126 넦 (HANGUL SYLLABLE NEGG) 1053 0xB127 넧 (HANGUL SYLLABLE NEGS) 1054 0xB129 넩 (HANGUL SYLLABLE NENJ) 1055 0xB12A 넪 (HANGUL SYLLABLE NENH) 1056 0xB12B 넫 (HANGUL SYLLABLE NED) 1057 0xB12D 넭 (HANGUL SYLLABLE NELG) 1058 0xB12E 넮 (HANGUL SYLLABLE NELM) 1059 0xB12F 넯 (HANGUL SYLLABLE NELB) 1060 0xB130 넰 (HANGUL SYLLABLE NELS) 1061 0xB131 넱 (HANGUL SYLLABLE NELT) 1062 0xB132 넲 (HANGUL SYLLABLE NELP) 1063 0xB133 넳 (HANGUL SYLLABLE NELH) 1064 0xB136 넶 (HANGUL SYLLABLE NEBS) 1065 0xB13A 넺 (HANGUL SYLLABLE NEJ) 1066 0xB13B 넻 (HANGUL SYLLABLE NEC) 1067 0xB13C 넼 (HANGUL SYLLABLE NEK) 1068 0xB13D 넽 (HANGUL SYLLABLE NET) 1069 0xB13E 넾 (HANGUL SYLLABLE NEP) 1070 0xB13F 넿 (HANGUL SYLLABLE NEH) 1071 0xB142 녂 (HANGUL SYLLABLE NYEOGG) 1072 0xB143 녃 (HANGUL SYLLABLE NYEOGS) 1073 0xB145 녅 (HANGUL SYLLABLE NYEONJ) 1074 0xB146 녆 (HANGUL SYLLABLE NYEONH) 1075 0xB147 녇 (HANGUL SYLLABLE NYEOD) 1076 0xB149 녉 (HANGUL SYLLABLE NYEOLG) 1077 0xB14A 녊 (HANGUL SYLLABLE NYEOLM) 1078 0xB14B 녋 (HANGUL SYLLABLE NYEOLB) 1079 0xB14C 녌 (HANGUL SYLLABLE NYEOLS) 1080 0xB14D 녍 (HANGUL SYLLABLE NYEOLT) 1081 0xB14E 녎 (HANGUL SYLLABLE NYEOLP) 1082 0xB14F 녏 (HANGUL SYLLABLE NYEOLH) 1083 0xB152 녒 (HANGUL SYLLABLE NYEOBS) 1084 0xB153 녓 (HANGUL SYLLABLE NYEOS) 1085 0xB156 녖 (HANGUL SYLLABLE NYEOJ) 1086 0xB157 녗 (HANGUL SYLLABLE NYEOC) 1087 0xB159 녙 (HANGUL SYLLABLE NYEOT) 1088 0xB15A 녚 (HANGUL SYLLABLE NYEOP) 1089 0xB15B 녛 (HANGUL SYLLABLE NYEOH) 1090 0xB15D 녝 (HANGUL SYLLABLE NYEG) 1091 0xB15E 녞 (HANGUL SYLLABLE NYEGG) 1092 0xB15F 녟 (HANGUL SYLLABLE NYEGS) 1093 0xB161 녡 (HANGUL SYLLABLE NYENJ) 1094 0xB162 녢 (HANGUL SYLLABLE NYENH) 1095 0xB163 녣 (HANGUL SYLLABLE NYED) 1096 0xB164 녤 (HANGUL SYLLABLE NYEL) 1097 0xB165 녥 (HANGUL SYLLABLE NYELG) 1098 0xB166 녦 (HANGUL SYLLABLE NYELM) 1099 0xB167 녧 (HANGUL SYLLABLE NYELB) 1100 0xB168 녨 (HANGUL SYLLABLE NYELS) 1101 0xB169 녩 (HANGUL SYLLABLE NYELT) 1102 0xB16A 녪 (HANGUL SYLLABLE NYELP) 1103 0xB16B 녫 (HANGUL SYLLABLE NYELH) 1104 0xB16C 녬 (HANGUL SYLLABLE NYEM) 1105 0xB16D 녭 (HANGUL SYLLABLE NYEB) 1106 0xB16E 녮 (HANGUL SYLLABLE NYEBS) 1107 0xB16F 녯 (HANGUL SYLLABLE NYES) 1108 0xB170 녰 (HANGUL SYLLABLE NYESS) 1109 0xB171 녱 (HANGUL SYLLABLE NYENG) 1110 0xB172 녲 (HANGUL SYLLABLE NYEJ) 1111 0xB173 녳 (HANGUL SYLLABLE NYEC) 1112 0xB174 녴 (HANGUL SYLLABLE NYEK) 1113 0xB175 녵 (HANGUL SYLLABLE NYET) 1114 0xB176 녶 (HANGUL SYLLABLE NYEP) 1115 0xB177 녷 (HANGUL SYLLABLE NYEH) 1116 0xB17A 녺 (HANGUL SYLLABLE NOGG) 1117 0xB17B 녻 (HANGUL SYLLABLE NOGS) 1118 0xB17D 녽 (HANGUL SYLLABLE NONJ) 1119 0xB17E 녾 (HANGUL SYLLABLE NONH) 1120 0xB17F 녿 (HANGUL SYLLABLE NOD) 1121 0xB181 놁 (HANGUL SYLLABLE NOLG) 1122 0xB183 놃 (HANGUL SYLLABLE NOLB) 1123 0xB184 놄 (HANGUL SYLLABLE NOLS) 1124 0xB185 놅 (HANGUL SYLLABLE NOLT) 1125 0xB186 놆 (HANGUL SYLLABLE NOLP) 1126 0xB187 놇 (HANGUL SYLLABLE NOLH) 1127 0xB18A 놊 (HANGUL SYLLABLE NOBS) 1128 0xB18C 놌 (HANGUL SYLLABLE NOSS) 1129 0xB18E 놎 (HANGUL SYLLABLE NOJ) 1130 0xB18F 놏 (HANGUL SYLLABLE NOC) 1131 0xB190 놐 (HANGUL SYLLABLE NOK) 1132 0xB191 놑 (HANGUL SYLLABLE NOT) 1133 0xB195 놕 (HANGUL SYLLABLE NWAG) 1134 0xB196 놖 (HANGUL SYLLABLE NWAGG) 1135 0xB197 놗 (HANGUL SYLLABLE NWAGS) 1136 0xB199 놙 (HANGUL SYLLABLE NWANJ) 1137 0xB19A 놚 (HANGUL SYLLABLE NWANH) 1138 0xB19B 놛 (HANGUL SYLLABLE NWAD) 1139 0xB19D 놝 (HANGUL SYLLABLE NWALG) 1140 0xB19E 놞 (HANGUL SYLLABLE NWALM) 1141 0xB19F 놟 (HANGUL SYLLABLE NWALB) 1142 0xB1A0 놠 (HANGUL SYLLABLE NWALS) 1143 0xB1A1 놡 (HANGUL SYLLABLE NWALT) 1144 0xB1A2 놢 (HANGUL SYLLABLE NWALP) 1145 0xB1A3 놣 (HANGUL SYLLABLE NWALH) 1146 0xB1A4 놤 (HANGUL SYLLABLE NWAM) 1147 0xB1A5 놥 (HANGUL SYLLABLE NWAB) 1148 0xB1A6 놦 (HANGUL SYLLABLE NWABS) 1149 0xB1A7 놧 (HANGUL SYLLABLE NWAS) 1150 0xB1A9 놩 (HANGUL SYLLABLE NWANG) 1151 0xB1AA 놪 (HANGUL SYLLABLE NWAJ) 1152 0xB1AB 놫 (HANGUL SYLLABLE NWAC) 1153 0xB1AC 놬 (HANGUL SYLLABLE NWAK) 1154 0xB1AD 놭 (HANGUL SYLLABLE NWAT) 1155 0xB1AE 놮 (HANGUL SYLLABLE NWAP) 1156 0xB1AF 놯 (HANGUL SYLLABLE NWAH) 1157 0xB1B0 놰 (HANGUL SYLLABLE NWAE) 1158 0xB1B1 놱 (HANGUL SYLLABLE NWAEG) 1159 0xB1B2 놲 (HANGUL SYLLABLE NWAEGG) 1160 0xB1B3 놳 (HANGUL SYLLABLE NWAEGS) 1161 0xB1B4 놴 (HANGUL SYLLABLE NWAEN) 1162 0xB1B5 놵 (HANGUL SYLLABLE NWAENJ) 1163 0xB1B6 놶 (HANGUL SYLLABLE NWAENH) 1164 0xB1B7 놷 (HANGUL SYLLABLE NWAED) 1165 0xB1B8 놸 (HANGUL SYLLABLE NWAEL) 1172 0xB1B9 놹 (HANGUL SYLLABLE NWAELG) 1173 0xB1BA 놺 (HANGUL SYLLABLE NWAELM) 1174 0xB1BB 놻 (HANGUL SYLLABLE NWAELB) 1175 0xB1BC 놼 (HANGUL SYLLABLE NWAELS) 1176 0xB1BD 놽 (HANGUL SYLLABLE NWAELT) 1177 0xB1BE 놾 (HANGUL SYLLABLE NWAELP) 1178 0xB1BF 놿 (HANGUL SYLLABLE NWAELH) 1179 0xB1C0 뇀 (HANGUL SYLLABLE NWAEM) 1180 0xB1C1 뇁 (HANGUL SYLLABLE NWAEB) 1181 0xB1C2 뇂 (HANGUL SYLLABLE NWAEBS) 1182 0xB1C3 뇃 (HANGUL SYLLABLE NWAES) 1183 0xB1C4 뇄 (HANGUL SYLLABLE NWAESS) 1184 0xB1C5 뇅 (HANGUL SYLLABLE NWAENG) 1185 0xB1C6 뇆 (HANGUL SYLLABLE NWAEJ) 1186 0xB1C7 뇇 (HANGUL SYLLABLE NWAEC) 1187 0xB1C8 뇈 (HANGUL SYLLABLE NWAEK) 1188 0xB1C9 뇉 (HANGUL SYLLABLE NWAET) 1189 0xB1CA 뇊 (HANGUL SYLLABLE NWAEP) 1190 0xB1CB 뇋 (HANGUL SYLLABLE NWAEH) 1191 0xB1CD 뇍 (HANGUL SYLLABLE NOEG) 1192 0xB1CE 뇎 (HANGUL SYLLABLE NOEGG) 1193 0xB1CF 뇏 (HANGUL SYLLABLE NOEGS) 1194 0xB1D1 뇑 (HANGUL SYLLABLE NOENJ) 1195 0xB1D2 뇒 (HANGUL SYLLABLE NOENH) 1196 0xB1D3 뇓 (HANGUL SYLLABLE NOED) 1197 0xB1D5 뇕 (HANGUL SYLLABLE NOELG) 1204 0xB1D6 뇖 (HANGUL SYLLABLE NOELM) 1205 0xB1D7 뇗 (HANGUL SYLLABLE NOELB) 1206 0xB1D8 뇘 (HANGUL SYLLABLE NOELS) 1207 0xB1D9 뇙 (HANGUL SYLLABLE NOELT) 1208 0xB1DA 뇚 (HANGUL SYLLABLE NOELP) 1209 0xB1DB 뇛 (HANGUL SYLLABLE NOELH) 1210 0xB1DE 뇞 (HANGUL SYLLABLE NOEBS) 1211 0xB1E0 뇠 (HANGUL SYLLABLE NOESS) 1212 0xB1E1 뇡 (HANGUL SYLLABLE NOENG) 1213 0xB1E2 뇢 (HANGUL SYLLABLE NOEJ) 1214 0xB1E3 뇣 (HANGUL SYLLABLE NOEC) 1215 0xB1E4 뇤 (HANGUL SYLLABLE NOEK) 1216 0xB1E5 뇥 (HANGUL SYLLABLE NOET) 1217 0xB1E6 뇦 (HANGUL SYLLABLE NOEP) 1218 0xB1E7 뇧 (HANGUL SYLLABLE NOEH) 1219 0xB1EA 뇪 (HANGUL SYLLABLE NYOGG) 1220 0xB1EB 뇫 (HANGUL SYLLABLE NYOGS) 1221 0xB1ED 뇭 (HANGUL SYLLABLE NYONJ) 1222 0xB1EE 뇮 (HANGUL SYLLABLE NYONH) 1223 0xB1EF 뇯 (HANGUL SYLLABLE NYOD) 1224 0xB1F1 뇱 (HANGUL SYLLABLE NYOLG) 1225 0xB1F2 뇲 (HANGUL SYLLABLE NYOLM) 1226 0xB1F3 뇳 (HANGUL SYLLABLE NYOLB) 1227 0xB1F4 뇴 (HANGUL SYLLABLE NYOLS) 1228 0xB1F5 뇵 (HANGUL SYLLABLE NYOLT) 1229 0xB1F6 뇶 (HANGUL SYLLABLE NYOLP) 1230 0xB1F7 뇷 (HANGUL SYLLABLE NYOLH) 1231 0xB1F8 뇸 (HANGUL SYLLABLE NYOM) 1232 0xB1FA 뇺 (HANGUL SYLLABLE NYOBS) 1233 0xB1FC 뇼 (HANGUL SYLLABLE NYOSS) 1234 0xB1FE 뇾 (HANGUL SYLLABLE NYOJ) 1235 0xB1FF 뇿 (HANGUL SYLLABLE NYOC) 1236 0xB200 눀 (HANGUL SYLLABLE NYOK) 1237 0xB201 눁 (HANGUL SYLLABLE NYOT) 1238 0xB202 눂 (HANGUL SYLLABLE NYOP) 1239 0xB203 눃 (HANGUL SYLLABLE NYOH) 1240 0xB206 눆 (HANGUL SYLLABLE NUGG) 1241 0xB207 눇 (HANGUL SYLLABLE NUGS) 1242 0xB209 눉 (HANGUL SYLLABLE NUNJ) 1243 0xB20A 눊 (HANGUL SYLLABLE NUNH) 1244 0xB20D 눍 (HANGUL SYLLABLE NULG) 1245 0xB20E 눎 (HANGUL SYLLABLE NULM) 1246 0xB20F 눏 (HANGUL SYLLABLE NULB) 1247 0xB210 눐 (HANGUL SYLLABLE NULS) 1248 0xB211 눑 (HANGUL SYLLABLE NULT) 1249 0xB212 눒 (HANGUL SYLLABLE NULP) 1250 0xB213 눓 (HANGUL SYLLABLE NULH) 1251 0xB216 눖 (HANGUL SYLLABLE NUBS) 1252 0xB218 눘 (HANGUL SYLLABLE NUSS) 1253 0xB21A 눚 (HANGUL SYLLABLE NUJ) 1254 0xB21B 눛 (HANGUL SYLLABLE NUC) 1255 0xB21C 눜 (HANGUL SYLLABLE NUK) 1256 0xB21D 눝 (HANGUL SYLLABLE NUT) 1257 0xB21E 눞 (HANGUL SYLLABLE NUP) 1258 0xB21F 눟 (HANGUL SYLLABLE NUH) 1259 0xB221 눡 (HANGUL SYLLABLE NWEOG) 1260 0xB222 눢 (HANGUL SYLLABLE NWEOGG) 1261 0xB223 눣 (HANGUL SYLLABLE NWEOGS) 1262 0xB224 눤 (HANGUL SYLLABLE NWEON) 1263 0xB225 눥 (HANGUL SYLLABLE NWEONJ) 1264 0xB226 눦 (HANGUL SYLLABLE NWEONH) 1265 0xB227 눧 (HANGUL SYLLABLE NWEOD) 1266 0xB228 눨 (HANGUL SYLLABLE NWEOL) 1267 0xB229 눩 (HANGUL SYLLABLE NWEOLG) 1268 0xB22A 눪 (HANGUL SYLLABLE NWEOLM) 1269 0xB22B 눫 (HANGUL SYLLABLE NWEOLB) 1270 0xB22C 눬 (HANGUL SYLLABLE NWEOLS) 1271 0xB22D 눭 (HANGUL SYLLABLE NWEOLT) 1272 0xB22E 눮 (HANGUL SYLLABLE NWEOLP) 1273 0xB22F 눯 (HANGUL SYLLABLE NWEOLH) 1274 0xB230 눰 (HANGUL SYLLABLE NWEOM) 1275 0xB231 눱 (HANGUL SYLLABLE NWEOB) 1276 0xB232 눲 (HANGUL SYLLABLE NWEOBS) 1277 0xB233 눳 (HANGUL SYLLABLE NWEOS) 1278 0xB235 눵 (HANGUL SYLLABLE NWEONG) 1279 0xB236 눶 (HANGUL SYLLABLE NWEOJ) 1280 0xB237 눷 (HANGUL SYLLABLE NWEOC) 1281 0xB238 눸 (HANGUL SYLLABLE NWEOK) 1282 0xB239 눹 (HANGUL SYLLABLE NWEOT) 1283 0xB23A 눺 (HANGUL SYLLABLE NWEOP) 1284 0xB23B 눻 (HANGUL SYLLABLE NWEOH) 1285 0xB23D 눽 (HANGUL SYLLABLE NWEG) 1286 0xB23E 눾 (HANGUL SYLLABLE NWEGG) 1287 0xB23F 눿 (HANGUL SYLLABLE NWEGS) 1288 0xB240 뉀 (HANGUL SYLLABLE NWEN) 1289 0xB241 뉁 (HANGUL SYLLABLE NWENJ) 1290 0xB242 뉂 (HANGUL SYLLABLE NWENH) 1291 0xB243 뉃 (HANGUL SYLLABLE NWED) 1292 0xB244 뉄 (HANGUL SYLLABLE NWEL) 1293 0xB245 뉅 (HANGUL SYLLABLE NWELG) 1294 0xB246 뉆 (HANGUL SYLLABLE NWELM) 1295 0xB247 뉇 (HANGUL SYLLABLE NWELB) 1296 0xB248 뉈 (HANGUL SYLLABLE NWELS) 1297 0xB249 뉉 (HANGUL SYLLABLE NWELT) 1298 0xB24A 뉊 (HANGUL SYLLABLE NWELP) 1299 0xB24B 뉋 (HANGUL SYLLABLE NWELH) 1300 0xB24C 뉌 (HANGUL SYLLABLE NWEM) 1301 0xB24D 뉍 (HANGUL SYLLABLE NWEB) 1302 0xB24E 뉎 (HANGUL SYLLABLE NWEBS) 1303 0xB24F 뉏 (HANGUL SYLLABLE NWES) 1304 0xB250 뉐 (HANGUL SYLLABLE NWESS) 1305 0xB251 뉑 (HANGUL SYLLABLE NWENG) 1306 0xB252 뉒 (HANGUL SYLLABLE NWEJ) 1307 0xB253 뉓 (HANGUL SYLLABLE NWEC) 1308 0xB254 뉔 (HANGUL SYLLABLE NWEK) 1309 0xB255 뉕 (HANGUL SYLLABLE NWET) 1310 0xB256 뉖 (HANGUL SYLLABLE NWEP) 1311 0xB257 뉗 (HANGUL SYLLABLE NWEH) 1312 0xB259 뉙 (HANGUL SYLLABLE NWIG) 1313 0xB25A 뉚 (HANGUL SYLLABLE NWIGG) 1314 0xB25B 뉛 (HANGUL SYLLABLE NWIGS) 1315 0xB25D 뉝 (HANGUL SYLLABLE NWINJ) 1316 0xB25E 뉞 (HANGUL SYLLABLE NWINH) 1317 0xB25F 뉟 (HANGUL SYLLABLE NWID) 1318 0xB261 뉡 (HANGUL SYLLABLE NWILG) 1319 0xB262 뉢 (HANGUL SYLLABLE NWILM) 1320 0xB263 뉣 (HANGUL SYLLABLE NWILB) 1321 0xB264 뉤 (HANGUL SYLLABLE NWILS) 1322 0xB265 뉥 (HANGUL SYLLABLE NWILT) 1323 0xB266 뉦 (HANGUL SYLLABLE NWILP) 1324 0xB267 뉧 (HANGUL SYLLABLE NWILH) 1325 0xB26A 뉪 (HANGUL SYLLABLE NWIBS) 1326 0xB26B 뉫 (HANGUL SYLLABLE NWIS) 1327 0xB26C 뉬 (HANGUL SYLLABLE NWISS) 1328 0xB26D 뉭 (HANGUL SYLLABLE NWING) 1329 0xB26E 뉮 (HANGUL SYLLABLE NWIJ) 1330 0xB26F 뉯 (HANGUL SYLLABLE NWIC) 1331 0xB270 뉰 (HANGUL SYLLABLE NWIK) 1332 0xB271 뉱 (HANGUL SYLLABLE NWIT) 1333 0xB272 뉲 (HANGUL SYLLABLE NWIP) 1334 0xB273 뉳 (HANGUL SYLLABLE NWIH) 1335 0xB276 뉶 (HANGUL SYLLABLE NYUGG) 1336 0xB277 뉷 (HANGUL SYLLABLE NYUGS) 1337 0xB278 뉸 (HANGUL SYLLABLE NYUN) 1338 0xB279 뉹 (HANGUL SYLLABLE NYUNJ) 1339 0xB27A 뉺 (HANGUL SYLLABLE NYUNH) 1340 0xB27B 뉻 (HANGUL SYLLABLE NYUD) 1341 0xB27D 뉽 (HANGUL SYLLABLE NYULG) 1342 0xB27E 뉾 (HANGUL SYLLABLE NYULM) 1343 0xB27F 뉿 (HANGUL SYLLABLE NYULB) 1344 0xB280 늀 (HANGUL SYLLABLE NYULS) 1345 0xB281 늁 (HANGUL SYLLABLE NYULT) 1346 0xB282 늂 (HANGUL SYLLABLE NYULP) 1347 0xB283 늃 (HANGUL SYLLABLE NYULH) 1348 0xB286 늆 (HANGUL SYLLABLE NYUBS) 1349 0xB287 늇 (HANGUL SYLLABLE NYUS) 1350 0xB288 늈 (HANGUL SYLLABLE NYUSS) 1351 0xB28A 늊 (HANGUL SYLLABLE NYUJ) 1352 0xB28B 늋 (HANGUL SYLLABLE NYUC) 1353 0xB28C 늌 (HANGUL SYLLABLE NYUK) 1354 0xB28D 늍 (HANGUL SYLLABLE NYUT) 1355 0xB28E 늎 (HANGUL SYLLABLE NYUP) 1362 0xB28F 늏 (HANGUL SYLLABLE NYUH) 1363 0xB292 늒 (HANGUL SYLLABLE NEUGG) 1364 0xB293 늓 (HANGUL SYLLABLE NEUGS) 1365 0xB295 늕 (HANGUL SYLLABLE NEUNJ) 1366 0xB296 늖 (HANGUL SYLLABLE NEUNH) 1367 0xB297 늗 (HANGUL SYLLABLE NEUD) 1368 0xB29B 늛 (HANGUL SYLLABLE NEULB) 1369 0xB29C 늜 (HANGUL SYLLABLE NEULS) 1370 0xB29D 늝 (HANGUL SYLLABLE NEULT) 1371 0xB29E 늞 (HANGUL SYLLABLE NEULP) 1372 0xB29F 늟 (HANGUL SYLLABLE NEULH) 1373 0xB2A2 늢 (HANGUL SYLLABLE NEUBS) 1374 0xB2A4 늤 (HANGUL SYLLABLE NEUSS) 1375 0xB2A7 늧 (HANGUL SYLLABLE NEUC) 1376 0xB2A8 늨 (HANGUL SYLLABLE NEUK) 1377 0xB2A9 늩 (HANGUL SYLLABLE NEUT) 1378 0xB2AB 늫 (HANGUL SYLLABLE NEUH) 1379 0xB2AD 늭 (HANGUL SYLLABLE NYIG) 1380 0xB2AE 늮 (HANGUL SYLLABLE NYIGG) 1381 0xB2AF 늯 (HANGUL SYLLABLE NYIGS) 1382 0xB2B1 늱 (HANGUL SYLLABLE NYINJ) 1383 0xB2B2 늲 (HANGUL SYLLABLE NYINH) 1384 0xB2B3 늳 (HANGUL SYLLABLE NYID) 1385 0xB2B5 늵 (HANGUL SYLLABLE NYILG) 1386 0xB2B6 늶 (HANGUL SYLLABLE NYILM) 1387 0xB2B7 늷 (HANGUL SYLLABLE NYILB) 1394 0xB2B8 늸 (HANGUL SYLLABLE NYILS) 1395 0xB2B9 늹 (HANGUL SYLLABLE NYILT) 1396 0xB2BA 늺 (HANGUL SYLLABLE NYILP) 1397 0xB2BB 늻 (HANGUL SYLLABLE NYILH) 1398 0xB2BC 늼 (HANGUL SYLLABLE NYIM) 1399 0xB2BD 늽 (HANGUL SYLLABLE NYIB) 1400 0xB2BE 늾 (HANGUL SYLLABLE NYIBS) 1401 0xB2BF 늿 (HANGUL SYLLABLE NYIS) 1402 0xB2C0 닀 (HANGUL SYLLABLE NYISS) 1403 0xB2C1 닁 (HANGUL SYLLABLE NYING) 1404 0xB2C2 닂 (HANGUL SYLLABLE NYIJ) 1405 0xB2C3 닃 (HANGUL SYLLABLE NYIC) 1406 0xB2C4 닄 (HANGUL SYLLABLE NYIK) 1407 0xB2C5 닅 (HANGUL SYLLABLE NYIT) 1408 0xB2C6 닆 (HANGUL SYLLABLE NYIP) 1409 0xB2C7 닇 (HANGUL SYLLABLE NYIH) 1410 0xB2CA 닊 (HANGUL SYLLABLE NIGG) 1411 0xB2CB 닋 (HANGUL SYLLABLE NIGS) 1412 0xB2CD 닍 (HANGUL SYLLABLE NINJ) 1413 0xB2CE 닎 (HANGUL SYLLABLE NINH) 1414 0xB2CF 닏 (HANGUL SYLLABLE NID) 1415 0xB2D1 닑 (HANGUL SYLLABLE NILG) 1416 0xB2D3 닓 (HANGUL SYLLABLE NILB) 1417 0xB2D4 닔 (HANGUL SYLLABLE NILS) 1418 0xB2D5 닕 (HANGUL SYLLABLE NILT) 1419 0xB2D6 닖 (HANGUL SYLLABLE NILP) 1420 0xB2D7 닗 (HANGUL SYLLABLE NILH) 1421 0xB2DA 닚 (HANGUL SYLLABLE NIBS) 1422 0xB2DC 닜 (HANGUL SYLLABLE NISS) 1423 0xB2DE 닞 (HANGUL SYLLABLE NIJ) 1424 0xB2DF 닟 (HANGUL SYLLABLE NIC) 1425 0xB2E0 닠 (HANGUL SYLLABLE NIK) 1426 0xB2E1 닡 (HANGUL SYLLABLE NIT) 1427 0xB2E3 닣 (HANGUL SYLLABLE NIH) 1428 0xB2E7 닧 (HANGUL SYLLABLE DAGS) 1429 0xB2E9 닩 (HANGUL SYLLABLE DANJ) 1430 0xB2EA 닪 (HANGUL SYLLABLE DANH) 1431 0xB2F0 닰 (HANGUL SYLLABLE DALS) 1432 0xB2F1 닱 (HANGUL SYLLABLE DALT) 1433 0xB2F2 닲 (HANGUL SYLLABLE DALP) 1434 0xB2F6 닶 (HANGUL SYLLABLE DABS) 1435 0xB2FC 닼 (HANGUL SYLLABLE DAK) 1436 0xB2FD 닽 (HANGUL SYLLABLE DAT) 1437 0xB2FE 닾 (HANGUL SYLLABLE DAP) 1438 0xB302 댂 (HANGUL SYLLABLE DAEGG) 1439 0xB303 댃 (HANGUL SYLLABLE DAEGS) 1440 0xB305 댅 (HANGUL SYLLABLE DAENJ) 1441 0xB306 댆 (HANGUL SYLLABLE DAENH) 1442 0xB307 댇 (HANGUL SYLLABLE DAED) 1443 0xB309 댉 (HANGUL SYLLABLE DAELG) 1444 0xB30A 댊 (HANGUL SYLLABLE DAELM) 1445 0xB30B 댋 (HANGUL SYLLABLE DAELB) 1446 0xB30C 댌 (HANGUL SYLLABLE DAELS) 1447 0xB30D 댍 (HANGUL SYLLABLE DAELT) 1448 0xB30E 댎 (HANGUL SYLLABLE DAELP) 1449 0xB30F 댏 (HANGUL SYLLABLE DAELH) 1450 0xB312 댒 (HANGUL SYLLABLE DAEBS) 1451 0xB316 댖 (HANGUL SYLLABLE DAEJ) 1452 0xB317 댗 (HANGUL SYLLABLE DAEC) 1453 0xB318 댘 (HANGUL SYLLABLE DAEK) 1454 0xB319 댙 (HANGUL SYLLABLE DAET) 1455 0xB31A 댚 (HANGUL SYLLABLE DAEP) 1456 0xB31B 댛 (HANGUL SYLLABLE DAEH) 1457 0xB31D 댝 (HANGUL SYLLABLE DYAG) 1458 0xB31E 댞 (HANGUL SYLLABLE DYAGG) 1459 0xB31F 댟 (HANGUL SYLLABLE DYAGS) 1460 0xB320 댠 (HANGUL SYLLABLE DYAN) 1461 0xB321 댡 (HANGUL SYLLABLE DYANJ) 1462 0xB322 댢 (HANGUL SYLLABLE DYANH) 1463 0xB323 댣 (HANGUL SYLLABLE DYAD) 1464 0xB324 댤 (HANGUL SYLLABLE DYAL) 1465 0xB325 댥 (HANGUL SYLLABLE DYALG) 1466 0xB326 댦 (HANGUL SYLLABLE DYALM) 1467 0xB327 댧 (HANGUL SYLLABLE DYALB) 1468 0xB328 댨 (HANGUL SYLLABLE DYALS) 1469 0xB329 댩 (HANGUL SYLLABLE DYALT) 1470 0xB32A 댪 (HANGUL SYLLABLE DYALP) 1471 0xB32B 댫 (HANGUL SYLLABLE DYALH) 1472 0xB32C 댬 (HANGUL SYLLABLE DYAM) 1473 0xB32D 댭 (HANGUL SYLLABLE DYAB) 1474 0xB32E 댮 (HANGUL SYLLABLE DYABS) 1475 0xB32F 댯 (HANGUL SYLLABLE DYAS) 1476 0xB330 댰 (HANGUL SYLLABLE DYASS) 1477 0xB331 댱 (HANGUL SYLLABLE DYANG) 1478 0xB332 댲 (HANGUL SYLLABLE DYAJ) 1479 0xB333 댳 (HANGUL SYLLABLE DYAC) 1480 0xB334 댴 (HANGUL SYLLABLE DYAK) 1481 0xB335 댵 (HANGUL SYLLABLE DYAT) 1482 0xB336 댶 (HANGUL SYLLABLE DYAP) 1483 0xB337 댷 (HANGUL SYLLABLE DYAH) 1484 0xB338 댸 (HANGUL SYLLABLE DYAE) 1485 0xB339 댹 (HANGUL SYLLABLE DYAEG) 1486 0xB33A 댺 (HANGUL SYLLABLE DYAEGG) 1487 0xB33B 댻 (HANGUL SYLLABLE DYAEGS) 1488 0xB33C 댼 (HANGUL SYLLABLE DYAEN) 1489 0xB33D 댽 (HANGUL SYLLABLE DYAENJ) 1490 0xB33E 댾 (HANGUL SYLLABLE DYAENH) 1491 0xB33F 댿 (HANGUL SYLLABLE DYAED) 1492 0xB340 덀 (HANGUL SYLLABLE DYAEL) 1493 0xB341 덁 (HANGUL SYLLABLE DYAELG) 1494 0xB342 덂 (HANGUL SYLLABLE DYAELM) 1495 0xB343 덃 (HANGUL SYLLABLE DYAELB) 1496 0xB344 덄 (HANGUL SYLLABLE DYAELS) 1497 0xB345 덅 (HANGUL SYLLABLE DYAELT) 1498 0xB346 덆 (HANGUL SYLLABLE DYAELP) 1499 0xB347 덇 (HANGUL SYLLABLE DYAELH) 1500 0xB348 덈 (HANGUL SYLLABLE DYAEM) 1501 0xB349 덉 (HANGUL SYLLABLE DYAEB) 1502 0xB34A 덊 (HANGUL SYLLABLE DYAEBS) 1503 0xB34B 덋 (HANGUL SYLLABLE DYAES) 1504 0xB34C 덌 (HANGUL SYLLABLE DYAESS) 1505 0xB34D 덍 (HANGUL SYLLABLE DYAENG) 1506 0xB34E 덎 (HANGUL SYLLABLE DYAEJ) 1507 0xB34F 덏 (HANGUL SYLLABLE DYAEC) 1508 0xB350 덐 (HANGUL SYLLABLE DYAEK) 1509 0xB351 덑 (HANGUL SYLLABLE DYAET) 1510 0xB352 덒 (HANGUL SYLLABLE DYAEP) 1511 0xB353 덓 (HANGUL SYLLABLE DYAEH) 1512 0xB357 덗 (HANGUL SYLLABLE DEOGS) 1513 0xB359 덙 (HANGUL SYLLABLE DEONJ) 1514 0xB35A 덚 (HANGUL SYLLABLE DEONH) 1515 0xB35D 덝 (HANGUL SYLLABLE DEOLG) 1516 0xB360 덠 (HANGUL SYLLABLE DEOLS) 1517 0xB361 덡 (HANGUL SYLLABLE DEOLT) 1518 0xB362 덢 (HANGUL SYLLABLE DEOLP) 1519 0xB363 덣 (HANGUL SYLLABLE DEOLH) 1520 0xB366 덦 (HANGUL SYLLABLE DEOBS) 1521 0xB368 덨 (HANGUL SYLLABLE DEOSS) 1522 0xB36A 덪 (HANGUL SYLLABLE DEOJ) 1523 0xB36C 덬 (HANGUL SYLLABLE DEOK) 1524 0xB36D 덭 (HANGUL SYLLABLE DEOT) 1525 0xB36F 덯 (HANGUL SYLLABLE DEOH) 1526 0xB372 덲 (HANGUL SYLLABLE DEGG) 1527 0xB373 덳 (HANGUL SYLLABLE DEGS) 1528 0xB375 덵 (HANGUL SYLLABLE DENJ) 1529 0xB376 덶 (HANGUL SYLLABLE DENH) 1530 0xB377 덷 (HANGUL SYLLABLE DED) 1531 0xB379 덹 (HANGUL SYLLABLE DELG) 1532 0xB37A 덺 (HANGUL SYLLABLE DELM) 1533 0xB37B 덻 (HANGUL SYLLABLE DELB) 1534 0xB37C 덼 (HANGUL SYLLABLE DELS) 1535 0xB37D 덽 (HANGUL SYLLABLE DELT) 1536 0xB37E 덾 (HANGUL SYLLABLE DELP) 1537 0xB37F 덿 (HANGUL SYLLABLE DELH) 1538 0xB382 뎂 (HANGUL SYLLABLE DEBS) 1539 0xB386 뎆 (HANGUL SYLLABLE DEJ) 1540 0xB387 뎇 (HANGUL SYLLABLE DEC) 1541 0xB388 뎈 (HANGUL SYLLABLE DEK) 1542 0xB389 뎉 (HANGUL SYLLABLE DET) 1543 0xB38A 뎊 (HANGUL SYLLABLE DEP) 1544 0xB38B 뎋 (HANGUL SYLLABLE DEH) 1545 0xB38D 뎍 (HANGUL SYLLABLE DYEOG) 1552 0xB38E 뎎 (HANGUL SYLLABLE DYEOGG) 1553 0xB38F 뎏 (HANGUL SYLLABLE DYEOGS) 1554 0xB391 뎑 (HANGUL SYLLABLE DYEONJ) 1555 0xB392 뎒 (HANGUL SYLLABLE DYEONH) 1556 0xB393 뎓 (HANGUL SYLLABLE DYEOD) 1557 0xB395 뎕 (HANGUL SYLLABLE DYEOLG) 1558 0xB396 뎖 (HANGUL SYLLABLE DYEOLM) 1559 0xB397 뎗 (HANGUL SYLLABLE DYEOLB) 1560 0xB398 뎘 (HANGUL SYLLABLE DYEOLS) 1561 0xB399 뎙 (HANGUL SYLLABLE DYEOLT) 1562 0xB39A 뎚 (HANGUL SYLLABLE DYEOLP) 1563 0xB39B 뎛 (HANGUL SYLLABLE DYEOLH) 1564 0xB39C 뎜 (HANGUL SYLLABLE DYEOM) 1565 0xB39D 뎝 (HANGUL SYLLABLE DYEOB) 1566 0xB39E 뎞 (HANGUL SYLLABLE DYEOBS) 1567 0xB39F 뎟 (HANGUL SYLLABLE DYEOS) 1568 0xB3A2 뎢 (HANGUL SYLLABLE DYEOJ) 1569 0xB3A3 뎣 (HANGUL SYLLABLE DYEOC) 1570 0xB3A4 뎤 (HANGUL SYLLABLE DYEOK) 1571 0xB3A5 뎥 (HANGUL SYLLABLE DYEOT) 1572 0xB3A6 뎦 (HANGUL SYLLABLE DYEOP) 1573 0xB3A7 뎧 (HANGUL SYLLABLE DYEOH) 1574 0xB3A9 뎩 (HANGUL SYLLABLE DYEG) 1575 0xB3AA 뎪 (HANGUL SYLLABLE DYEGG) 1576 0xB3AB 뎫 (HANGUL SYLLABLE DYEGS) 1577 0xB3AD 뎭 (HANGUL SYLLABLE DYENJ) 1584 0xB3AE 뎮 (HANGUL SYLLABLE DYENH) 1585 0xB3AF 뎯 (HANGUL SYLLABLE DYED) 1586 0xB3B0 뎰 (HANGUL SYLLABLE DYEL) 1587 0xB3B1 뎱 (HANGUL SYLLABLE DYELG) 1588 0xB3B2 뎲 (HANGUL SYLLABLE DYELM) 1589 0xB3B3 뎳 (HANGUL SYLLABLE DYELB) 1590 0xB3B4 뎴 (HANGUL SYLLABLE DYELS) 1591 0xB3B5 뎵 (HANGUL SYLLABLE DYELT) 1592 0xB3B6 뎶 (HANGUL SYLLABLE DYELP) 1593 0xB3B7 뎷 (HANGUL SYLLABLE DYELH) 1594 0xB3B8 뎸 (HANGUL SYLLABLE DYEM) 1595 0xB3B9 뎹 (HANGUL SYLLABLE DYEB) 1596 0xB3BA 뎺 (HANGUL SYLLABLE DYEBS) 1597 0xB3BB 뎻 (HANGUL SYLLABLE DYES) 1598 0xB3BC 뎼 (HANGUL SYLLABLE DYESS) 1599 0xB3BD 뎽 (HANGUL SYLLABLE DYENG) 1600 0xB3BE 뎾 (HANGUL SYLLABLE DYEJ) 1601 0xB3BF 뎿 (HANGUL SYLLABLE DYEC) 1602 0xB3C0 돀 (HANGUL SYLLABLE DYEK) 1603 0xB3C1 돁 (HANGUL SYLLABLE DYET) 1604 0xB3C2 돂 (HANGUL SYLLABLE DYEP) 1605 0xB3C3 돃 (HANGUL SYLLABLE DYEH) 1606 0xB3C6 돆 (HANGUL SYLLABLE DOGG) 1607 0xB3C7 돇 (HANGUL SYLLABLE DOGS) 1608 0xB3C9 돉 (HANGUL SYLLABLE DONJ) 1609 0xB3CA 돊 (HANGUL SYLLABLE DONH) 1610 0xB3CD 돍 (HANGUL SYLLABLE DOLG) 1611 0xB3CF 돏 (HANGUL SYLLABLE DOLB) 1612 0xB3D1 돑 (HANGUL SYLLABLE DOLT) 1613 0xB3D2 돒 (HANGUL SYLLABLE DOLP) 1614 0xB3D3 돓 (HANGUL SYLLABLE DOLH) 1615 0xB3D6 돖 (HANGUL SYLLABLE DOBS) 1616 0xB3D8 돘 (HANGUL SYLLABLE DOSS) 1617 0xB3DA 돚 (HANGUL SYLLABLE DOJ) 1618 0xB3DC 돜 (HANGUL SYLLABLE DOK) 1619 0xB3DE 돞 (HANGUL SYLLABLE DOP) 1620 0xB3DF 돟 (HANGUL SYLLABLE DOH) 1621 0xB3E1 돡 (HANGUL SYLLABLE DWAG) 1622 0xB3E2 돢 (HANGUL SYLLABLE DWAGG) 1623 0xB3E3 돣 (HANGUL SYLLABLE DWAGS) 1624 0xB3E5 돥 (HANGUL SYLLABLE DWANJ) 1625 0xB3E6 돦 (HANGUL SYLLABLE DWANH) 1626 0xB3E7 돧 (HANGUL SYLLABLE DWAD) 1627 0xB3E9 돩 (HANGUL SYLLABLE DWALG) 1628 0xB3EA 돪 (HANGUL SYLLABLE DWALM) 1629 0xB3EB 돫 (HANGUL SYLLABLE DWALB) 1630 0xB3EC 돬 (HANGUL SYLLABLE DWALS) 1631 0xB3ED 돭 (HANGUL SYLLABLE DWALT) 1632 0xB3EE 돮 (HANGUL SYLLABLE DWALP) 1633 0xB3EF 돯 (HANGUL SYLLABLE DWALH) 1634 0xB3F0 돰 (HANGUL SYLLABLE DWAM) 1635 0xB3F1 돱 (HANGUL SYLLABLE DWAB) 1636 0xB3F2 돲 (HANGUL SYLLABLE DWABS) 1637 0xB3F3 돳 (HANGUL SYLLABLE DWAS) 1638 0xB3F4 돴 (HANGUL SYLLABLE DWASS) 1639 0xB3F5 돵 (HANGUL SYLLABLE DWANG) 1640 0xB3F6 돶 (HANGUL SYLLABLE DWAJ) 1641 0xB3F7 돷 (HANGUL SYLLABLE DWAC) 1642 0xB3F8 돸 (HANGUL SYLLABLE DWAK) 1643 0xB3F9 돹 (HANGUL SYLLABLE DWAT) 1644 0xB3FA 돺 (HANGUL SYLLABLE DWAP) 1645 0xB3FB 돻 (HANGUL SYLLABLE DWAH) 1646 0xB3FD 돽 (HANGUL SYLLABLE DWAEG) 1647 0xB3FE 돾 (HANGUL SYLLABLE DWAEGG) 1648 0xB3FF 돿 (HANGUL SYLLABLE DWAEGS) 1649 0xB400 됀 (HANGUL SYLLABLE DWAEN) 1650 0xB401 됁 (HANGUL SYLLABLE DWAENJ) 1651 0xB402 됂 (HANGUL SYLLABLE DWAENH) 1652 0xB403 됃 (HANGUL SYLLABLE DWAED) 1653 0xB404 됄 (HANGUL SYLLABLE DWAEL) 1654 0xB405 됅 (HANGUL SYLLABLE DWAELG) 1655 0xB406 됆 (HANGUL SYLLABLE DWAELM) 1656 0xB407 됇 (HANGUL SYLLABLE DWAELB) 1657 0xB408 됈 (HANGUL SYLLABLE DWAELS) 1658 0xB409 됉 (HANGUL SYLLABLE DWAELT) 1659 0xB40A 됊 (HANGUL SYLLABLE DWAELP) 1660 0xB40B 됋 (HANGUL SYLLABLE DWAELH) 1661 0xB40C 됌 (HANGUL SYLLABLE DWAEM) 1662 0xB40D 됍 (HANGUL SYLLABLE DWAEB) 1663 0xB40E 됎 (HANGUL SYLLABLE DWAEBS) 1664 0xB40F 됏 (HANGUL SYLLABLE DWAES) 1665 0xB411 됑 (HANGUL SYLLABLE DWAENG) 1666 0xB412 됒 (HANGUL SYLLABLE DWAEJ) 1667 0xB413 됓 (HANGUL SYLLABLE DWAEC) 1668 0xB414 됔 (HANGUL SYLLABLE DWAEK) 1669 0xB415 됕 (HANGUL SYLLABLE DWAET) 1670 0xB416 됖 (HANGUL SYLLABLE DWAEP) 1671 0xB417 됗 (HANGUL SYLLABLE DWAEH) 1672 0xB419 됙 (HANGUL SYLLABLE DOEG) 1673 0xB41A 됚 (HANGUL SYLLABLE DOEGG) 1674 0xB41B 됛 (HANGUL SYLLABLE DOEGS) 1675 0xB41D 됝 (HANGUL SYLLABLE DOENJ) 1676 0xB41E 됞 (HANGUL SYLLABLE DOENH) 1677 0xB41F 됟 (HANGUL SYLLABLE DOED) 1678 0xB421 됡 (HANGUL SYLLABLE DOELG) 1679 0xB422 됢 (HANGUL SYLLABLE DOELM) 1680 0xB423 됣 (HANGUL SYLLABLE DOELB) 1681 0xB424 됤 (HANGUL SYLLABLE DOELS) 1682 0xB425 됥 (HANGUL SYLLABLE DOELT) 1683 0xB426 됦 (HANGUL SYLLABLE DOELP) 1684 0xB427 됧 (HANGUL SYLLABLE DOELH) 1685 0xB42A 됪 (HANGUL SYLLABLE DOEBS) 1686 0xB42C 됬 (HANGUL SYLLABLE DOESS) 1687 0xB42D 됭 (HANGUL SYLLABLE DOENG) 1688 0xB42E 됮 (HANGUL SYLLABLE DOEJ) 1689 0xB42F 됯 (HANGUL SYLLABLE DOEC) 1690 0xB430 됰 (HANGUL SYLLABLE DOEK) 1691 0xB431 됱 (HANGUL SYLLABLE DOET) 1692 0xB432 됲 (HANGUL SYLLABLE DOEP) 1693 0xB433 됳 (HANGUL SYLLABLE DOEH) 1694 0xB435 됵 (HANGUL SYLLABLE DYOG) 1695 0xB436 됶 (HANGUL SYLLABLE DYOGG) 1696 0xB437 됷 (HANGUL SYLLABLE DYOGS) 1697 0xB438 됸 (HANGUL SYLLABLE DYON) 1698 0xB439 됹 (HANGUL SYLLABLE DYONJ) 1699 0xB43A 됺 (HANGUL SYLLABLE DYONH) 1700 0xB43B 됻 (HANGUL SYLLABLE DYOD) 1701 0xB43C 됼 (HANGUL SYLLABLE DYOL) 1702 0xB43D 됽 (HANGUL SYLLABLE DYOLG) 1703 0xB43E 됾 (HANGUL SYLLABLE DYOLM) 1704 0xB43F 됿 (HANGUL SYLLABLE DYOLB) 1705 0xB440 둀 (HANGUL SYLLABLE DYOLS) 1706 0xB441 둁 (HANGUL SYLLABLE DYOLT) 1707 0xB442 둂 (HANGUL SYLLABLE DYOLP) 1708 0xB443 둃 (HANGUL SYLLABLE DYOLH) 1709 0xB444 둄 (HANGUL SYLLABLE DYOM) 1710 0xB445 둅 (HANGUL SYLLABLE DYOB) 1711 0xB446 둆 (HANGUL SYLLABLE DYOBS) 1712 0xB447 둇 (HANGUL SYLLABLE DYOS) 1713 0xB448 둈 (HANGUL SYLLABLE DYOSS) 1714 0xB449 둉 (HANGUL SYLLABLE DYONG) 1715 0xB44A 둊 (HANGUL SYLLABLE DYOJ) 1716 0xB44B 둋 (HANGUL SYLLABLE DYOC) 1717 0xB44C 둌 (HANGUL SYLLABLE DYOK) 1718 0xB44D 둍 (HANGUL SYLLABLE DYOT) 1719 0xB44E 둎 (HANGUL SYLLABLE DYOP) 1720 0xB44F 둏 (HANGUL SYLLABLE DYOH) 1721 0xB452 둒 (HANGUL SYLLABLE DUGG) 1722 0xB453 둓 (HANGUL SYLLABLE DUGS) 1723 0xB455 둕 (HANGUL SYLLABLE DUNJ) 1724 0xB456 둖 (HANGUL SYLLABLE DUNH) 1725 0xB457 둗 (HANGUL SYLLABLE DUD) 1726 0xB459 둙 (HANGUL SYLLABLE DULG) 1727 0xB45A 둚 (HANGUL SYLLABLE DULM) 1728 0xB45B 둛 (HANGUL SYLLABLE DULB) 1729 0xB45C 둜 (HANGUL SYLLABLE DULS) 1730 0xB45D 둝 (HANGUL SYLLABLE DULT) 1731 0xB45E 둞 (HANGUL SYLLABLE DULP) 1732 0xB45F 둟 (HANGUL SYLLABLE DULH) 1733 0xB462 둢 (HANGUL SYLLABLE DUBS) 1734 0xB464 둤 (HANGUL SYLLABLE DUSS) 1735 0xB466 둦 (HANGUL SYLLABLE DUJ) 1742 0xB467 둧 (HANGUL SYLLABLE DUC) 1743 0xB468 둨 (HANGUL SYLLABLE DUK) 1744 0xB469 둩 (HANGUL SYLLABLE DUT) 1745 0xB46A 둪 (HANGUL SYLLABLE DUP) 1746 0xB46B 둫 (HANGUL SYLLABLE DUH) 1747 0xB46D 둭 (HANGUL SYLLABLE DWEOG) 1748 0xB46E 둮 (HANGUL SYLLABLE DWEOGG) 1749 0xB46F 둯 (HANGUL SYLLABLE DWEOGS) 1750 0xB470 둰 (HANGUL SYLLABLE DWEON) 1751 0xB471 둱 (HANGUL SYLLABLE DWEONJ) 1752 0xB472 둲 (HANGUL SYLLABLE DWEONH) 1753 0xB473 둳 (HANGUL SYLLABLE DWEOD) 1754 0xB474 둴 (HANGUL SYLLABLE DWEOL) 1755 0xB475 둵 (HANGUL SYLLABLE DWEOLG) 1756 0xB476 둶 (HANGUL SYLLABLE DWEOLM) 1757 0xB477 둷 (HANGUL SYLLABLE DWEOLB) 1758 0xB478 둸 (HANGUL SYLLABLE DWEOLS) 1759 0xB479 둹 (HANGUL SYLLABLE DWEOLT) 1760 0xB47A 둺 (HANGUL SYLLABLE DWEOLP) 1761 0xB47B 둻 (HANGUL SYLLABLE DWEOLH) 1762 0xB47C 둼 (HANGUL SYLLABLE DWEOM) 1763 0xB47D 둽 (HANGUL SYLLABLE DWEOB) 1764 0xB47E 둾 (HANGUL SYLLABLE DWEOBS) 1765 0xB47F 둿 (HANGUL SYLLABLE DWEOS) 1766 0xB481 뒁 (HANGUL SYLLABLE DWEONG) 1767 0xB482 뒂 (HANGUL SYLLABLE DWEOJ) 1774 0xB483 뒃 (HANGUL SYLLABLE DWEOC) 1775 0xB484 뒄 (HANGUL SYLLABLE DWEOK) 1776 0xB485 뒅 (HANGUL SYLLABLE DWEOT) 1777 0xB486 뒆 (HANGUL SYLLABLE DWEOP) 1778 0xB487 뒇 (HANGUL SYLLABLE DWEOH) 1779 0xB489 뒉 (HANGUL SYLLABLE DWEG) 1780 0xB48A 뒊 (HANGUL SYLLABLE DWEGG) 1781 0xB48B 뒋 (HANGUL SYLLABLE DWEGS) 1782 0xB48C 뒌 (HANGUL SYLLABLE DWEN) 1783 0xB48D 뒍 (HANGUL SYLLABLE DWENJ) 1784 0xB48E 뒎 (HANGUL SYLLABLE DWENH) 1785 0xB48F 뒏 (HANGUL SYLLABLE DWED) 1786 0xB490 뒐 (HANGUL SYLLABLE DWEL) 1787 0xB491 뒑 (HANGUL SYLLABLE DWELG) 1788 0xB492 뒒 (HANGUL SYLLABLE DWELM) 1789 0xB493 뒓 (HANGUL SYLLABLE DWELB) 1790 0xB494 뒔 (HANGUL SYLLABLE DWELS) 1791 0xB495 뒕 (HANGUL SYLLABLE DWELT) 1792 0xB496 뒖 (HANGUL SYLLABLE DWELP) 1793 0xB497 뒗 (HANGUL SYLLABLE DWELH) 1794 0xB498 뒘 (HANGUL SYLLABLE DWEM) 1795 0xB499 뒙 (HANGUL SYLLABLE DWEB) 1796 0xB49A 뒚 (HANGUL SYLLABLE DWEBS) 1797 0xB49B 뒛 (HANGUL SYLLABLE DWES) 1798 0xB49C 뒜 (HANGUL SYLLABLE DWESS) 1799 0xB49E 뒞 (HANGUL SYLLABLE DWEJ) 1800 0xB49F 뒟 (HANGUL SYLLABLE DWEC) 1801 0xB4A0 뒠 (HANGUL SYLLABLE DWEK) 1802 0xB4A1 뒡 (HANGUL SYLLABLE DWET) 1803 0xB4A2 뒢 (HANGUL SYLLABLE DWEP) 1804 0xB4A3 뒣 (HANGUL SYLLABLE DWEH) 1805 0xB4A5 뒥 (HANGUL SYLLABLE DWIG) 1806 0xB4A6 뒦 (HANGUL SYLLABLE DWIGG) 1807 0xB4A7 뒧 (HANGUL SYLLABLE DWIGS) 1808 0xB4A9 뒩 (HANGUL SYLLABLE DWINJ) 1809 0xB4AA 뒪 (HANGUL SYLLABLE DWINH) 1810 0xB4AB 뒫 (HANGUL SYLLABLE DWID) 1811 0xB4AD 뒭 (HANGUL SYLLABLE DWILG) 1812 0xB4AE 뒮 (HANGUL SYLLABLE DWILM) 1813 0xB4AF 뒯 (HANGUL SYLLABLE DWILB) 1814 0xB4B0 뒰 (HANGUL SYLLABLE DWILS) 1815 0xB4B1 뒱 (HANGUL SYLLABLE DWILT) 1816 0xB4B2 뒲 (HANGUL SYLLABLE DWILP) 1817 0xB4B3 뒳 (HANGUL SYLLABLE DWILH) 1818 0xB4B4 뒴 (HANGUL SYLLABLE DWIM) 1819 0xB4B6 뒶 (HANGUL SYLLABLE DWIBS) 1820 0xB4B8 뒸 (HANGUL SYLLABLE DWISS) 1821 0xB4BA 뒺 (HANGUL SYLLABLE DWIJ) 1822 0xB4BB 뒻 (HANGUL SYLLABLE DWIC) 1823 0xB4BC 뒼 (HANGUL SYLLABLE DWIK) 1824 0xB4BD 뒽 (HANGUL SYLLABLE DWIT) 1825 0xB4BE 뒾 (HANGUL SYLLABLE DWIP) 1826 0xB4BF 뒿 (HANGUL SYLLABLE DWIH) 1827 0xB4C1 듁 (HANGUL SYLLABLE DYUG) 1828 0xB4C2 듂 (HANGUL SYLLABLE DYUGG) 1829 0xB4C3 듃 (HANGUL SYLLABLE DYUGS) 1830 0xB4C5 듅 (HANGUL SYLLABLE DYUNJ) 1831 0xB4C6 듆 (HANGUL SYLLABLE DYUNH) 1832 0xB4C7 듇 (HANGUL SYLLABLE DYUD) 1833 0xB4C9 듉 (HANGUL SYLLABLE DYULG) 1834 0xB4CA 듊 (HANGUL SYLLABLE DYULM) 1835 0xB4CB 듋 (HANGUL SYLLABLE DYULB) 1836 0xB4CC 듌 (HANGUL SYLLABLE DYULS) 1837 0xB4CD 듍 (HANGUL SYLLABLE DYULT) 1838 0xB4CE 듎 (HANGUL SYLLABLE DYULP) 1839 0xB4CF 듏 (HANGUL SYLLABLE DYULH) 1840 0xB4D1 듑 (HANGUL SYLLABLE DYUB) 1841 0xB4D2 듒 (HANGUL SYLLABLE DYUBS) 1842 0xB4D3 듓 (HANGUL SYLLABLE DYUS) 1843 0xB4D4 듔 (HANGUL SYLLABLE DYUSS) 1844 0xB4D6 듖 (HANGUL SYLLABLE DYUJ) 1845 0xB4D7 듗 (HANGUL SYLLABLE DYUC) 1846 0xB4D8 듘 (HANGUL SYLLABLE DYUK) 1847 0xB4D9 듙 (HANGUL SYLLABLE DYUT) 1848 0xB4DA 듚 (HANGUL SYLLABLE DYUP) 1849 0xB4DB 듛 (HANGUL SYLLABLE DYUH) 1850 0xB4DE 듞 (HANGUL SYLLABLE DEUGG) 1851 0xB4DF 듟 (HANGUL SYLLABLE DEUGS) 1852 0xB4E1 듡 (HANGUL SYLLABLE DEUNJ) 1853 0xB4E2 듢 (HANGUL SYLLABLE DEUNH) 1854 0xB4E5 듥 (HANGUL SYLLABLE DEULG) 1855 0xB4E7 듧 (HANGUL SYLLABLE DEULB) 1856 0xB4E8 듨 (HANGUL SYLLABLE DEULS) 1857 0xB4E9 듩 (HANGUL SYLLABLE DEULT) 1858 0xB4EA 듪 (HANGUL SYLLABLE DEULP) 1859 0xB4EB 듫 (HANGUL SYLLABLE DEULH) 1860 0xB4EE 듮 (HANGUL SYLLABLE DEUBS) 1861 0xB4F0 듰 (HANGUL SYLLABLE DEUSS) 1862 0xB4F2 듲 (HANGUL SYLLABLE DEUJ) 1863 0xB4F3 듳 (HANGUL SYLLABLE DEUC) 1864 0xB4F4 듴 (HANGUL SYLLABLE DEUK) 1865 0xB4F5 듵 (HANGUL SYLLABLE DEUT) 1866 0xB4F6 듶 (HANGUL SYLLABLE DEUP) 1867 0xB4F7 듷 (HANGUL SYLLABLE DEUH) 1868 0xB4F9 듹 (HANGUL SYLLABLE DYIG) 1869 0xB4FA 듺 (HANGUL SYLLABLE DYIGG) 1870 0xB4FB 듻 (HANGUL SYLLABLE DYIGS) 1871 0xB4FC 듼 (HANGUL SYLLABLE DYIN) 1872 0xB4FD 듽 (HANGUL SYLLABLE DYINJ) 1873 0xB4FE 듾 (HANGUL SYLLABLE DYINH) 1874 0xB4FF 듿 (HANGUL SYLLABLE DYID) 1875 0xB500 딀 (HANGUL SYLLABLE DYIL) 1876 0xB501 딁 (HANGUL SYLLABLE DYILG) 1877 0xB502 딂 (HANGUL SYLLABLE DYILM) 1878 0xB503 딃 (HANGUL SYLLABLE DYILB) 1879 0xB504 딄 (HANGUL SYLLABLE DYILS) 1880 0xB505 딅 (HANGUL SYLLABLE DYILT) 1881 0xB506 딆 (HANGUL SYLLABLE DYILP) 1882 0xB507 딇 (HANGUL SYLLABLE DYILH) 1883 0xB508 딈 (HANGUL SYLLABLE DYIM) 1884 0xB509 딉 (HANGUL SYLLABLE DYIB) 1885 0xB50A 딊 (HANGUL SYLLABLE DYIBS) 1886 0xB50B 딋 (HANGUL SYLLABLE DYIS) 1887 0xB50C 딌 (HANGUL SYLLABLE DYISS) 1888 0xB50D 딍 (HANGUL SYLLABLE DYING) 1889 0xB50E 딎 (HANGUL SYLLABLE DYIJ) 1890 0xB50F 딏 (HANGUL SYLLABLE DYIC) 1891 0xB510 딐 (HANGUL SYLLABLE DYIK) 1892 0xB511 딑 (HANGUL SYLLABLE DYIT) 1893 0xB512 딒 (HANGUL SYLLABLE DYIP) 1894 0xB513 딓 (HANGUL SYLLABLE DYIH) 1895 0xB516 딖 (HANGUL SYLLABLE DIGG) 1896 0xB517 딗 (HANGUL SYLLABLE DIGS) 1897 0xB519 딙 (HANGUL SYLLABLE DINJ) 1898 0xB51A 딚 (HANGUL SYLLABLE DINH) 1899 0xB51D 딝 (HANGUL SYLLABLE DILG) 1900 0xB51E 딞 (HANGUL SYLLABLE DILM) 1901 0xB51F 딟 (HANGUL SYLLABLE DILB) 1902 0xB520 딠 (HANGUL SYLLABLE DILS) 1903 0xB521 딡 (HANGUL SYLLABLE DILT) 1904 0xB522 딢 (HANGUL SYLLABLE DILP) 1905 0xB523 딣 (HANGUL SYLLABLE DILH) 1906 0xB526 딦 (HANGUL SYLLABLE DIBS) 1907 0xB52B 딫 (HANGUL SYLLABLE DIC) 1908 0xB52C 딬 (HANGUL SYLLABLE DIK) 1909 0xB52D 딭 (HANGUL SYLLABLE DIT) 1910 0xB52E 딮 (HANGUL SYLLABLE DIP) 1911 0xB52F 딯 (HANGUL SYLLABLE DIH) 1912 0xB532 딲 (HANGUL SYLLABLE DDAGG) 1913 0xB533 딳 (HANGUL SYLLABLE DDAGS) 1914 0xB535 딵 (HANGUL SYLLABLE DDANJ) 1915 0xB536 딶 (HANGUL SYLLABLE DDANH) 1916 0xB537 딷 (HANGUL SYLLABLE DDAD) 1917 0xB539 딹 (HANGUL SYLLABLE DDALG) 1918 0xB53A 딺 (HANGUL SYLLABLE DDALM) 1919 0xB53B 딻 (HANGUL SYLLABLE DDALB) 1920 0xB53C 딼 (HANGUL SYLLABLE DDALS) 1921 0xB53D 딽 (HANGUL SYLLABLE DDALT) 1922 0xB53E 딾 (HANGUL SYLLABLE DDALP) 1923 0xB53F 딿 (HANGUL SYLLABLE DDALH) 1924 0xB542 땂 (HANGUL SYLLABLE DDABS) 1925 0xB546 땆 (HANGUL SYLLABLE DDAJ) 1932 0xB547 땇 (HANGUL SYLLABLE DDAC) 1933 0xB548 땈 (HANGUL SYLLABLE DDAK) 1934 0xB549 땉 (HANGUL SYLLABLE DDAT) 1935 0xB54A 땊 (HANGUL SYLLABLE DDAP) 1936 0xB54E 땎 (HANGUL SYLLABLE DDAEGG) 1937 0xB54F 땏 (HANGUL SYLLABLE DDAEGS) 1938 0xB551 땑 (HANGUL SYLLABLE DDAENJ) 1939 0xB552 땒 (HANGUL SYLLABLE DDAENH) 1940 0xB553 땓 (HANGUL SYLLABLE DDAED) 1941 0xB555 땕 (HANGUL SYLLABLE DDAELG) 1942 0xB556 땖 (HANGUL SYLLABLE DDAELM) 1943 0xB557 땗 (HANGUL SYLLABLE DDAELB) 1944 0xB558 땘 (HANGUL SYLLABLE DDAELS) 1945 0xB559 땙 (HANGUL SYLLABLE DDAELT) 1946 0xB55A 땚 (HANGUL SYLLABLE DDAELP) 1947 0xB55B 땛 (HANGUL SYLLABLE DDAELH) 1948 0xB55E 땞 (HANGUL SYLLABLE DDAEBS) 1949 0xB562 땢 (HANGUL SYLLABLE DDAEJ) 1950 0xB563 땣 (HANGUL SYLLABLE DDAEC) 1951 0xB564 땤 (HANGUL SYLLABLE DDAEK) 1952 0xB565 땥 (HANGUL SYLLABLE DDAET) 1953 0xB566 땦 (HANGUL SYLLABLE DDAEP) 1954 0xB567 땧 (HANGUL SYLLABLE DDAEH) 1955 0xB568 땨 (HANGUL SYLLABLE DDYA) 1956 0xB569 땩 (HANGUL SYLLABLE DDYAG) 1957 0xB56A 땪 (HANGUL SYLLABLE DDYAGG) 1964 0xB56B 땫 (HANGUL SYLLABLE DDYAGS) 1965 0xB56C 땬 (HANGUL SYLLABLE DDYAN) 1966 0xB56D 땭 (HANGUL SYLLABLE DDYANJ) 1967 0xB56E 땮 (HANGUL SYLLABLE DDYANH) 1968 0xB56F 땯 (HANGUL SYLLABLE DDYAD) 1969 0xB570 땰 (HANGUL SYLLABLE DDYAL) 1970 0xB571 땱 (HANGUL SYLLABLE DDYALG) 1971 0xB572 땲 (HANGUL SYLLABLE DDYALM) 1972 0xB573 땳 (HANGUL SYLLABLE DDYALB) 1973 0xB574 땴 (HANGUL SYLLABLE DDYALS) 1974 0xB575 땵 (HANGUL SYLLABLE DDYALT) 1975 0xB576 땶 (HANGUL SYLLABLE DDYALP) 1976 0xB577 땷 (HANGUL SYLLABLE DDYALH) 1977 0xB578 땸 (HANGUL SYLLABLE DDYAM) 1978 0xB579 땹 (HANGUL SYLLABLE DDYAB) 1979 0xB57A 땺 (HANGUL SYLLABLE DDYABS) 1980 0xB57B 땻 (HANGUL SYLLABLE DDYAS) 1981 0xB57C 땼 (HANGUL SYLLABLE DDYASS) 1982 0xB57D 땽 (HANGUL SYLLABLE DDYANG) 1983 0xB57E 땾 (HANGUL SYLLABLE DDYAJ) 1984 0xB57F 땿 (HANGUL SYLLABLE DDYAC) 1985 0xB580 떀 (HANGUL SYLLABLE DDYAK) 1986 0xB581 떁 (HANGUL SYLLABLE DDYAT) 1987 0xB582 떂 (HANGUL SYLLABLE DDYAP) 1988 0xB583 떃 (HANGUL SYLLABLE DDYAH) 1989 0xB584 떄 (HANGUL SYLLABLE DDYAE) 1990 0xB585 떅 (HANGUL SYLLABLE DDYAEG) 1991 0xB586 떆 (HANGUL SYLLABLE DDYAEGG) 1992 0xB587 떇 (HANGUL SYLLABLE DDYAEGS) 1993 0xB588 떈 (HANGUL SYLLABLE DDYAEN) 1994 0xB589 떉 (HANGUL SYLLABLE DDYAENJ) 1995 0xB58A 떊 (HANGUL SYLLABLE DDYAENH) 1996 0xB58B 떋 (HANGUL SYLLABLE DDYAED) 1997 0xB58C 떌 (HANGUL SYLLABLE DDYAEL) 1998 0xB58D 떍 (HANGUL SYLLABLE DDYAELG) 1999 0xB58E 떎 (HANGUL SYLLABLE DDYAELM) 2000 0xB58F 떏 (HANGUL SYLLABLE DDYAELB) 2001 0xB590 떐 (HANGUL SYLLABLE DDYAELS) 2002 0xB591 떑 (HANGUL SYLLABLE DDYAELT) 2003 0xB592 떒 (HANGUL SYLLABLE DDYAELP) 2004 0xB593 떓 (HANGUL SYLLABLE DDYAELH) 2005 0xB594 떔 (HANGUL SYLLABLE DDYAEM) 2006 0xB595 떕 (HANGUL SYLLABLE DDYAEB) 2007 0xB596 떖 (HANGUL SYLLABLE DDYAEBS) 2008 0xB597 떗 (HANGUL SYLLABLE DDYAES) 2009 0xB598 떘 (HANGUL SYLLABLE DDYAESS) 2010 0xB599 떙 (HANGUL SYLLABLE DDYAENG) 2011 0xB59A 떚 (HANGUL SYLLABLE DDYAEJ) 2012 0xB59B 떛 (HANGUL SYLLABLE DDYAEC) 2013 0xB59C 떜 (HANGUL SYLLABLE DDYAEK) 2014 0xB59D 떝 (HANGUL SYLLABLE DDYAET) 2015 0xB59E 떞 (HANGUL SYLLABLE DDYAEP) 2016 0xB59F 떟 (HANGUL SYLLABLE DDYAEH) 2017 0xB5A2 떢 (HANGUL SYLLABLE DDEOGG) 2018 0xB5A3 떣 (HANGUL SYLLABLE DDEOGS) 2019 0xB5A5 떥 (HANGUL SYLLABLE DDEONJ) 2020 0xB5A6 떦 (HANGUL SYLLABLE DDEONH) 2021 0xB5A7 떧 (HANGUL SYLLABLE DDEOD) 2022 0xB5A9 떩 (HANGUL SYLLABLE DDEOLG) 2023 0xB5AC 떬 (HANGUL SYLLABLE DDEOLS) 2024 0xB5AD 떭 (HANGUL SYLLABLE DDEOLT) 2025 0xB5AE 떮 (HANGUL SYLLABLE DDEOLP) 2026 0xB5AF 떯 (HANGUL SYLLABLE DDEOLH) 2027 0xB5B2 떲 (HANGUL SYLLABLE DDEOBS) 2028 0xB5B6 떶 (HANGUL SYLLABLE DDEOJ) 2029 0xB5B7 떷 (HANGUL SYLLABLE DDEOC) 2030 0xB5B8 떸 (HANGUL SYLLABLE DDEOK) 2031 0xB5B9 떹 (HANGUL SYLLABLE DDEOT) 2032 0xB5BA 떺 (HANGUL SYLLABLE DDEOP) 2033 0xB5BE 떾 (HANGUL SYLLABLE DDEGG) 2034 0xB5BF 떿 (HANGUL SYLLABLE DDEGS) 2035 0xB5C1 뗁 (HANGUL SYLLABLE DDENJ) 2036 0xB5C2 뗂 (HANGUL SYLLABLE DDENH) 2037 0xB5C3 뗃 (HANGUL SYLLABLE DDED) 2038 0xB5C5 뗅 (HANGUL SYLLABLE DDELG) 2039 0xB5C6 뗆 (HANGUL SYLLABLE DDELM) 2040 0xB5C7 뗇 (HANGUL SYLLABLE DDELB) 2041 0xB5C8 뗈 (HANGUL SYLLABLE DDELS) 2042 0xB5C9 뗉 (HANGUL SYLLABLE DDELT) 2043 0xB5CA 뗊 (HANGUL SYLLABLE DDELP) 2044 0xB5CB 뗋 (HANGUL SYLLABLE DDELH) 2045 0xB5CE 뗎 (HANGUL SYLLABLE DDEBS) 2046 0xB5D2 뗒 (HANGUL SYLLABLE DDEJ) 2047 0xB5D3 뗓 (HANGUL SYLLABLE DDEC) 2048 0xB5D4 뗔 (HANGUL SYLLABLE DDEK) 2049 0xB5D5 뗕 (HANGUL SYLLABLE DDET) 2050 0xB5D6 뗖 (HANGUL SYLLABLE DDEP) 2051 0xB5D7 뗗 (HANGUL SYLLABLE DDEH) 2052 0xB5D9 뗙 (HANGUL SYLLABLE DDYEOG) 2053 0xB5DA 뗚 (HANGUL SYLLABLE DDYEOGG) 2054 0xB5DB 뗛 (HANGUL SYLLABLE DDYEOGS) 2055 0xB5DC 뗜 (HANGUL SYLLABLE DDYEON) 2056 0xB5DD 뗝 (HANGUL SYLLABLE DDYEONJ) 2057 0xB5DE 뗞 (HANGUL SYLLABLE DDYEONH) 2058 0xB5DF 뗟 (HANGUL SYLLABLE DDYEOD) 2059 0xB5E0 뗠 (HANGUL SYLLABLE DDYEOL) 2060 0xB5E1 뗡 (HANGUL SYLLABLE DDYEOLG) 2061 0xB5E2 뗢 (HANGUL SYLLABLE DDYEOLM) 2062 0xB5E3 뗣 (HANGUL SYLLABLE DDYEOLB) 2063 0xB5E4 뗤 (HANGUL SYLLABLE DDYEOLS) 2064 0xB5E5 뗥 (HANGUL SYLLABLE DDYEOLT) 2065 0xB5E6 뗦 (HANGUL SYLLABLE DDYEOLP) 2066 0xB5E7 뗧 (HANGUL SYLLABLE DDYEOLH) 2067 0xB5E8 뗨 (HANGUL SYLLABLE DDYEOM) 2068 0xB5E9 뗩 (HANGUL SYLLABLE DDYEOB) 2069 0xB5EA 뗪 (HANGUL SYLLABLE DDYEOBS) 2070 0xB5EB 뗫 (HANGUL SYLLABLE DDYEOS) 2071 0xB5ED 뗭 (HANGUL SYLLABLE DDYEONG) 2072 0xB5EE 뗮 (HANGUL SYLLABLE DDYEOJ) 2073 0xB5EF 뗯 (HANGUL SYLLABLE DDYEOC) 2074 0xB5F0 뗰 (HANGUL SYLLABLE DDYEOK) 2075 0xB5F1 뗱 (HANGUL SYLLABLE DDYEOT) 2076 0xB5F2 뗲 (HANGUL SYLLABLE DDYEOP) 2077 0xB5F3 뗳 (HANGUL SYLLABLE DDYEOH) 2078 0xB5F4 뗴 (HANGUL SYLLABLE DDYE) 2079 0xB5F5 뗵 (HANGUL SYLLABLE DDYEG) 2080 0xB5F6 뗶 (HANGUL SYLLABLE DDYEGG) 2081 0xB5F7 뗷 (HANGUL SYLLABLE DDYEGS) 2082 0xB5F8 뗸 (HANGUL SYLLABLE DDYEN) 2083 0xB5F9 뗹 (HANGUL SYLLABLE DDYENJ) 2084 0xB5FA 뗺 (HANGUL SYLLABLE DDYENH) 2085 0xB5FB 뗻 (HANGUL SYLLABLE DDYED) 2086 0xB5FC 뗼 (HANGUL SYLLABLE DDYEL) 2087 0xB5FD 뗽 (HANGUL SYLLABLE DDYELG) 2088 0xB5FE 뗾 (HANGUL SYLLABLE DDYELM) 2089 0xB5FF 뗿 (HANGUL SYLLABLE DDYELB) 2090 0xB600 똀 (HANGUL SYLLABLE DDYELS) 2091 0xB601 똁 (HANGUL SYLLABLE DDYELT) 2092 0xB602 똂 (HANGUL SYLLABLE DDYELP) 2093 0xB603 똃 (HANGUL SYLLABLE DDYELH) 2094 0xB604 똄 (HANGUL SYLLABLE DDYEM) 2095 0xB605 똅 (HANGUL SYLLABLE DDYEB) 2096 0xB606 똆 (HANGUL SYLLABLE DDYEBS) 2097 0xB607 똇 (HANGUL SYLLABLE DDYES) 2098 0xB608 똈 (HANGUL SYLLABLE DDYESS) 2099 0xB609 똉 (HANGUL SYLLABLE DDYENG) 2100 0xB60A 똊 (HANGUL SYLLABLE DDYEJ) 2101 0xB60B 똋 (HANGUL SYLLABLE DDYEC) 2102 0xB60C 똌 (HANGUL SYLLABLE DDYEK) 2103 0xB60D 똍 (HANGUL SYLLABLE DDYET) 2104 0xB60E 똎 (HANGUL SYLLABLE DDYEP) 2105 0xB60F 똏 (HANGUL SYLLABLE DDYEH) 2106 0xB612 똒 (HANGUL SYLLABLE DDOGG) 2107 0xB613 똓 (HANGUL SYLLABLE DDOGS) 2108 0xB615 똕 (HANGUL SYLLABLE DDONJ) 2109 0xB616 똖 (HANGUL SYLLABLE DDONH) 2110 0xB617 똗 (HANGUL SYLLABLE DDOD) 2111 0xB619 똙 (HANGUL SYLLABLE DDOLG) 2112 0xB61A 똚 (HANGUL SYLLABLE DDOLM) 2113 0xB61B 똛 (HANGUL SYLLABLE DDOLB) 2114 0xB61C 똜 (HANGUL SYLLABLE DDOLS) 2115 0xB61D 똝 (HANGUL SYLLABLE DDOLT) 2122 0xB61E 똞 (HANGUL SYLLABLE DDOLP) 2123 0xB61F 똟 (HANGUL SYLLABLE DDOLH) 2124 0xB620 똠 (HANGUL SYLLABLE DDOM) 2125 0xB621 똡 (HANGUL SYLLABLE DDOB) 2126 0xB622 똢 (HANGUL SYLLABLE DDOBS) 2127 0xB623 똣 (HANGUL SYLLABLE DDOS) 2128 0xB624 똤 (HANGUL SYLLABLE DDOSS) 2129 0xB626 똦 (HANGUL SYLLABLE DDOJ) 2130 0xB627 똧 (HANGUL SYLLABLE DDOC) 2131 0xB628 똨 (HANGUL SYLLABLE DDOK) 2132 0xB629 똩 (HANGUL SYLLABLE DDOT) 2133 0xB62A 똪 (HANGUL SYLLABLE DDOP) 2134 0xB62B 똫 (HANGUL SYLLABLE DDOH) 2135 0xB62D 똭 (HANGUL SYLLABLE DDWAG) 2136 0xB62E 똮 (HANGUL SYLLABLE DDWAGG) 2137 0xB62F 똯 (HANGUL SYLLABLE DDWAGS) 2138 0xB630 똰 (HANGUL SYLLABLE DDWAN) 2139 0xB631 똱 (HANGUL SYLLABLE DDWANJ) 2140 0xB632 똲 (HANGUL SYLLABLE DDWANH) 2141 0xB633 똳 (HANGUL SYLLABLE DDWAD) 2142 0xB635 똵 (HANGUL SYLLABLE DDWALG) 2143 0xB636 똶 (HANGUL SYLLABLE DDWALM) 2144 0xB637 똷 (HANGUL SYLLABLE DDWALB) 2145 0xB638 똸 (HANGUL SYLLABLE DDWALS) 2146 0xB639 똹 (HANGUL SYLLABLE DDWALT) 2147 0xB63A 똺 (HANGUL SYLLABLE DDWALP) 2154 0xB63B 똻 (HANGUL SYLLABLE DDWALH) 2155 0xB63C 똼 (HANGUL SYLLABLE DDWAM) 2156 0xB63D 똽 (HANGUL SYLLABLE DDWAB) 2157 0xB63E 똾 (HANGUL SYLLABLE DDWABS) 2158 0xB63F 똿 (HANGUL SYLLABLE DDWAS) 2159 0xB640 뙀 (HANGUL SYLLABLE DDWASS) 2160 0xB641 뙁 (HANGUL SYLLABLE DDWANG) 2161 0xB642 뙂 (HANGUL SYLLABLE DDWAJ) 2162 0xB643 뙃 (HANGUL SYLLABLE DDWAC) 2163 0xB644 뙄 (HANGUL SYLLABLE DDWAK) 2164 0xB645 뙅 (HANGUL SYLLABLE DDWAT) 2165 0xB646 뙆 (HANGUL SYLLABLE DDWAP) 2166 0xB647 뙇 (HANGUL SYLLABLE DDWAH) 2167 0xB649 뙉 (HANGUL SYLLABLE DDWAEG) 2168 0xB64A 뙊 (HANGUL SYLLABLE DDWAEGG) 2169 0xB64B 뙋 (HANGUL SYLLABLE DDWAEGS) 2170 0xB64C 뙌 (HANGUL SYLLABLE DDWAEN) 2171 0xB64D 뙍 (HANGUL SYLLABLE DDWAENJ) 2172 0xB64E 뙎 (HANGUL SYLLABLE DDWAENH) 2173 0xB64F 뙏 (HANGUL SYLLABLE DDWAED) 2174 0xB650 뙐 (HANGUL SYLLABLE DDWAEL) 2175 0xB651 뙑 (HANGUL SYLLABLE DDWAELG) 2176 0xB652 뙒 (HANGUL SYLLABLE DDWAELM) 2177 0xB653 뙓 (HANGUL SYLLABLE DDWAELB) 2178 0xB654 뙔 (HANGUL SYLLABLE DDWAELS) 2179 0xB655 뙕 (HANGUL SYLLABLE DDWAELT) 2180 0xB656 뙖 (HANGUL SYLLABLE DDWAELP) 2181 0xB657 뙗 (HANGUL SYLLABLE DDWAELH) 2182 0xB658 뙘 (HANGUL SYLLABLE DDWAEM) 2183 0xB659 뙙 (HANGUL SYLLABLE DDWAEB) 2184 0xB65A 뙚 (HANGUL SYLLABLE DDWAEBS) 2185 0xB65B 뙛 (HANGUL SYLLABLE DDWAES) 2186 0xB65C 뙜 (HANGUL SYLLABLE DDWAESS) 2187 0xB65D 뙝 (HANGUL SYLLABLE DDWAENG) 2188 0xB65E 뙞 (HANGUL SYLLABLE DDWAEJ) 2189 0xB65F 뙟 (HANGUL SYLLABLE DDWAEC) 2190 0xB660 뙠 (HANGUL SYLLABLE DDWAEK) 2191 0xB661 뙡 (HANGUL SYLLABLE DDWAET) 2192 0xB662 뙢 (HANGUL SYLLABLE DDWAEP) 2193 0xB663 뙣 (HANGUL SYLLABLE DDWAEH) 2194 0xB665 뙥 (HANGUL SYLLABLE DDOEG) 2195 0xB666 뙦 (HANGUL SYLLABLE DDOEGG) 2196 0xB667 뙧 (HANGUL SYLLABLE DDOEGS) 2197 0xB669 뙩 (HANGUL SYLLABLE DDOENJ) 2198 0xB66A 뙪 (HANGUL SYLLABLE DDOENH) 2199 0xB66B 뙫 (HANGUL SYLLABLE DDOED) 2200 0xB66C 뙬 (HANGUL SYLLABLE DDOEL) 2201 0xB66D 뙭 (HANGUL SYLLABLE DDOELG) 2202 0xB66E 뙮 (HANGUL SYLLABLE DDOELM) 2203 0xB66F 뙯 (HANGUL SYLLABLE DDOELB) 2204 0xB670 뙰 (HANGUL SYLLABLE DDOELS) 2205 0xB671 뙱 (HANGUL SYLLABLE DDOELT) 2206 0xB672 뙲 (HANGUL SYLLABLE DDOELP) 2207 0xB673 뙳 (HANGUL SYLLABLE DDOELH) 2208 0xB674 뙴 (HANGUL SYLLABLE DDOEM) 2209 0xB675 뙵 (HANGUL SYLLABLE DDOEB) 2210 0xB676 뙶 (HANGUL SYLLABLE DDOEBS) 2211 0xB677 뙷 (HANGUL SYLLABLE DDOES) 2212 0xB678 뙸 (HANGUL SYLLABLE DDOESS) 2213 0xB679 뙹 (HANGUL SYLLABLE DDOENG) 2214 0xB67A 뙺 (HANGUL SYLLABLE DDOEJ) 2215 0xB67B 뙻 (HANGUL SYLLABLE DDOEC) 2216 0xB67C 뙼 (HANGUL SYLLABLE DDOEK) 2217 0xB67D 뙽 (HANGUL SYLLABLE DDOET) 2218 0xB67E 뙾 (HANGUL SYLLABLE DDOEP) 2219 0xB67F 뙿 (HANGUL SYLLABLE DDOEH) 2220 0xB680 뚀 (HANGUL SYLLABLE DDYO) 2221 0xB681 뚁 (HANGUL SYLLABLE DDYOG) 2222 0xB682 뚂 (HANGUL SYLLABLE DDYOGG) 2223 0xB683 뚃 (HANGUL SYLLABLE DDYOGS) 2224 0xB684 뚄 (HANGUL SYLLABLE DDYON) 2225 0xB685 뚅 (HANGUL SYLLABLE DDYONJ) 2226 0xB686 뚆 (HANGUL SYLLABLE DDYONH) 2227 0xB687 뚇 (HANGUL SYLLABLE DDYOD) 2228 0xB688 뚈 (HANGUL SYLLABLE DDYOL) 2229 0xB689 뚉 (HANGUL SYLLABLE DDYOLG) 2230 0xB68A 뚊 (HANGUL SYLLABLE DDYOLM) 2231 0xB68B 뚋 (HANGUL SYLLABLE DDYOLB) 2232 0xB68C 뚌 (HANGUL SYLLABLE DDYOLS) 2233 0xB68D 뚍 (HANGUL SYLLABLE DDYOLT) 2234 0xB68E 뚎 (HANGUL SYLLABLE DDYOLP) 2235 0xB68F 뚏 (HANGUL SYLLABLE DDYOLH) 2236 0xB690 뚐 (HANGUL SYLLABLE DDYOM) 2237 0xB691 뚑 (HANGUL SYLLABLE DDYOB) 2238 0xB692 뚒 (HANGUL SYLLABLE DDYOBS) 2239 0xB693 뚓 (HANGUL SYLLABLE DDYOS) 2240 0xB694 뚔 (HANGUL SYLLABLE DDYOSS) 2241 0xB695 뚕 (HANGUL SYLLABLE DDYONG) 2242 0xB696 뚖 (HANGUL SYLLABLE DDYOJ) 2243 0xB697 뚗 (HANGUL SYLLABLE DDYOC) 2244 0xB698 뚘 (HANGUL SYLLABLE DDYOK) 2245 0xB699 뚙 (HANGUL SYLLABLE DDYOT) 2246 0xB69A 뚚 (HANGUL SYLLABLE DDYOP) 2247 0xB69B 뚛 (HANGUL SYLLABLE DDYOH) 2248 0xB69E 뚞 (HANGUL SYLLABLE DDUGG) 2249 0xB69F 뚟 (HANGUL SYLLABLE DDUGS) 2250 0xB6A1 뚡 (HANGUL SYLLABLE DDUNJ) 2251 0xB6A2 뚢 (HANGUL SYLLABLE DDUNH) 2252 0xB6A3 뚣 (HANGUL SYLLABLE DDUD) 2253 0xB6A5 뚥 (HANGUL SYLLABLE DDULG) 2254 0xB6A6 뚦 (HANGUL SYLLABLE DDULM) 2255 0xB6A7 뚧 (HANGUL SYLLABLE DDULB) 2256 0xB6A8 뚨 (HANGUL SYLLABLE DDULS) 2257 0xB6A9 뚩 (HANGUL SYLLABLE DDULT) 2258 0xB6AA 뚪 (HANGUL SYLLABLE DDULP) 2259 0xB6AD 뚭 (HANGUL SYLLABLE DDUB) 2260 0xB6AE 뚮 (HANGUL SYLLABLE DDUBS) 2261 0xB6AF 뚯 (HANGUL SYLLABLE DDUS) 2262 0xB6B0 뚰 (HANGUL SYLLABLE DDUSS) 2263 0xB6B2 뚲 (HANGUL SYLLABLE DDUJ) 2264 0xB6B3 뚳 (HANGUL SYLLABLE DDUC) 2265 0xB6B4 뚴 (HANGUL SYLLABLE DDUK) 2266 0xB6B5 뚵 (HANGUL SYLLABLE DDUT) 2267 0xB6B6 뚶 (HANGUL SYLLABLE DDUP) 2268 0xB6B7 뚷 (HANGUL SYLLABLE DDUH) 2269 0xB6B8 뚸 (HANGUL SYLLABLE DDWEO) 2270 0xB6B9 뚹 (HANGUL SYLLABLE DDWEOG) 2271 0xB6BA 뚺 (HANGUL SYLLABLE DDWEOGG) 2272 0xB6BB 뚻 (HANGUL SYLLABLE DDWEOGS) 2273 0xB6BC 뚼 (HANGUL SYLLABLE DDWEON) 2274 0xB6BD 뚽 (HANGUL SYLLABLE DDWEONJ) 2275 0xB6BE 뚾 (HANGUL SYLLABLE DDWEONH) 2276 0xB6BF 뚿 (HANGUL SYLLABLE DDWEOD) 2277 0xB6C0 뛀 (HANGUL SYLLABLE DDWEOL) 2278 0xB6C1 뛁 (HANGUL SYLLABLE DDWEOLG) 2279 0xB6C2 뛂 (HANGUL SYLLABLE DDWEOLM) 2280 0xB6C3 뛃 (HANGUL SYLLABLE DDWEOLB) 2281 0xB6C4 뛄 (HANGUL SYLLABLE DDWEOLS) 2282 0xB6C5 뛅 (HANGUL SYLLABLE DDWEOLT) 2283 0xB6C6 뛆 (HANGUL SYLLABLE DDWEOLP) 2284 0xB6C7 뛇 (HANGUL SYLLABLE DDWEOLH) 2285 0xB6C8 뛈 (HANGUL SYLLABLE DDWEOM) 2286 0xB6C9 뛉 (HANGUL SYLLABLE DDWEOB) 2287 0xB6CA 뛊 (HANGUL SYLLABLE DDWEOBS) 2288 0xB6CB 뛋 (HANGUL SYLLABLE DDWEOS) 2289 0xB6CC 뛌 (HANGUL SYLLABLE DDWEOSS) 2290 0xB6CD 뛍 (HANGUL SYLLABLE DDWEONG) 2291 0xB6CE 뛎 (HANGUL SYLLABLE DDWEOJ) 2292 0xB6CF 뛏 (HANGUL SYLLABLE DDWEOC) 2293 0xB6D0 뛐 (HANGUL SYLLABLE DDWEOK) 2294 0xB6D1 뛑 (HANGUL SYLLABLE DDWEOT) 2295 0xB6D2 뛒 (HANGUL SYLLABLE DDWEOP) 2296 0xB6D3 뛓 (HANGUL SYLLABLE DDWEOH) 2297 0xB6D5 뛕 (HANGUL SYLLABLE DDWEG) 2298 0xB6D6 뛖 (HANGUL SYLLABLE DDWEGG) 2299 0xB6D7 뛗 (HANGUL SYLLABLE DDWEGS) 2300 0xB6D8 뛘 (HANGUL SYLLABLE DDWEN) 2301 0xB6D9 뛙 (HANGUL SYLLABLE DDWENJ) 2302 0xB6DA 뛚 (HANGUL SYLLABLE DDWENH) 2303 0xB6DB 뛛 (HANGUL SYLLABLE DDWED) 2304 0xB6DC 뛜 (HANGUL SYLLABLE DDWEL) 2305 0xB6DD 뛝 (HANGUL SYLLABLE DDWELG) 2312 0xB6DE 뛞 (HANGUL SYLLABLE DDWELM) 2313 0xB6DF 뛟 (HANGUL SYLLABLE DDWELB) 2314 0xB6E0 뛠 (HANGUL SYLLABLE DDWELS) 2315 0xB6E1 뛡 (HANGUL SYLLABLE DDWELT) 2316 0xB6E2 뛢 (HANGUL SYLLABLE DDWELP) 2317 0xB6E3 뛣 (HANGUL SYLLABLE DDWELH) 2318 0xB6E4 뛤 (HANGUL SYLLABLE DDWEM) 2319 0xB6E5 뛥 (HANGUL SYLLABLE DDWEB) 2320 0xB6E6 뛦 (HANGUL SYLLABLE DDWEBS) 2321 0xB6E7 뛧 (HANGUL SYLLABLE DDWES) 2322 0xB6E8 뛨 (HANGUL SYLLABLE DDWESS) 2323 0xB6E9 뛩 (HANGUL SYLLABLE DDWENG) 2324 0xB6EA 뛪 (HANGUL SYLLABLE DDWEJ) 2325 0xB6EB 뛫 (HANGUL SYLLABLE DDWEC) 2326 0xB6EC 뛬 (HANGUL SYLLABLE DDWEK) 2327 0xB6ED 뛭 (HANGUL SYLLABLE DDWET) 2328 0xB6EE 뛮 (HANGUL SYLLABLE DDWEP) 2329 0xB6EF 뛯 (HANGUL SYLLABLE DDWEH) 2330 0xB6F1 뛱 (HANGUL SYLLABLE DDWIG) 2331 0xB6F2 뛲 (HANGUL SYLLABLE DDWIGG) 2332 0xB6F3 뛳 (HANGUL SYLLABLE DDWIGS) 2333 0xB6F5 뛵 (HANGUL SYLLABLE DDWINJ) 2334 0xB6F6 뛶 (HANGUL SYLLABLE DDWINH) 2335 0xB6F7 뛷 (HANGUL SYLLABLE DDWID) 2336 0xB6F9 뛹 (HANGUL SYLLABLE DDWILG) 2337 0xB6FA 뛺 (HANGUL SYLLABLE DDWILM) 2344 0xB6FB 뛻 (HANGUL SYLLABLE DDWILB) 2345 0xB6FC 뛼 (HANGUL SYLLABLE DDWILS) 2346 0xB6FD 뛽 (HANGUL SYLLABLE DDWILT) 2347 0xB6FE 뛾 (HANGUL SYLLABLE DDWILP) 2348 0xB6FF 뛿 (HANGUL SYLLABLE DDWILH) 2349 0xB702 뜂 (HANGUL SYLLABLE DDWIBS) 2350 0xB703 뜃 (HANGUL SYLLABLE DDWIS) 2351 0xB704 뜄 (HANGUL SYLLABLE DDWISS) 2352 0xB706 뜆 (HANGUL SYLLABLE DDWIJ) 2353 0xB707 뜇 (HANGUL SYLLABLE DDWIC) 2354 0xB708 뜈 (HANGUL SYLLABLE DDWIK) 2355 0xB709 뜉 (HANGUL SYLLABLE DDWIT) 2356 0xB70A 뜊 (HANGUL SYLLABLE DDWIP) 2357 0xB70B 뜋 (HANGUL SYLLABLE DDWIH) 2358 0xB70C 뜌 (HANGUL SYLLABLE DDYU) 2359 0xB70D 뜍 (HANGUL SYLLABLE DDYUG) 2360 0xB70E 뜎 (HANGUL SYLLABLE DDYUGG) 2361 0xB70F 뜏 (HANGUL SYLLABLE DDYUGS) 2362 0xB710 뜐 (HANGUL SYLLABLE DDYUN) 2363 0xB711 뜑 (HANGUL SYLLABLE DDYUNJ) 2364 0xB712 뜒 (HANGUL SYLLABLE DDYUNH) 2365 0xB713 뜓 (HANGUL SYLLABLE DDYUD) 2366 0xB714 뜔 (HANGUL SYLLABLE DDYUL) 2367 0xB715 뜕 (HANGUL SYLLABLE DDYULG) 2368 0xB716 뜖 (HANGUL SYLLABLE DDYULM) 2369 0xB717 뜗 (HANGUL SYLLABLE DDYULB) 2370 0xB718 뜘 (HANGUL SYLLABLE DDYULS) 2371 0xB719 뜙 (HANGUL SYLLABLE DDYULT) 2372 0xB71A 뜚 (HANGUL SYLLABLE DDYULP) 2373 0xB71B 뜛 (HANGUL SYLLABLE DDYULH) 2374 0xB71C 뜜 (HANGUL SYLLABLE DDYUM) 2375 0xB71D 뜝 (HANGUL SYLLABLE DDYUB) 2376 0xB71E 뜞 (HANGUL SYLLABLE DDYUBS) 2377 0xB71F 뜟 (HANGUL SYLLABLE DDYUS) 2378 0xB720 뜠 (HANGUL SYLLABLE DDYUSS) 2379 0xB721 뜡 (HANGUL SYLLABLE DDYUNG) 2380 0xB722 뜢 (HANGUL SYLLABLE DDYUJ) 2381 0xB723 뜣 (HANGUL SYLLABLE DDYUC) 2382 0xB724 뜤 (HANGUL SYLLABLE DDYUK) 2383 0xB725 뜥 (HANGUL SYLLABLE DDYUT) 2384 0xB726 뜦 (HANGUL SYLLABLE DDYUP) 2385 0xB727 뜧 (HANGUL SYLLABLE DDYUH) 2386 0xB72A 뜪 (HANGUL SYLLABLE DDEUGG) 2387 0xB72B 뜫 (HANGUL SYLLABLE DDEUGS) 2388 0xB72D 뜭 (HANGUL SYLLABLE DDEUNJ) 2389 0xB72E 뜮 (HANGUL SYLLABLE DDEUNH) 2390 0xB731 뜱 (HANGUL SYLLABLE DDEULG) 2391 0xB732 뜲 (HANGUL SYLLABLE DDEULM) 2392 0xB733 뜳 (HANGUL SYLLABLE DDEULB) 2393 0xB734 뜴 (HANGUL SYLLABLE DDEULS) 2394 0xB735 뜵 (HANGUL SYLLABLE DDEULT) 2395 0xB736 뜶 (HANGUL SYLLABLE DDEULP) 2396 0xB737 뜷 (HANGUL SYLLABLE DDEULH) 2397 0xB73A 뜺 (HANGUL SYLLABLE DDEUBS) 2398 0xB73C 뜼 (HANGUL SYLLABLE DDEUSS) 2399 0xB73D 뜽 (HANGUL SYLLABLE DDEUNG) 2400 0xB73E 뜾 (HANGUL SYLLABLE DDEUJ) 2401 0xB73F 뜿 (HANGUL SYLLABLE DDEUC) 2402 0xB740 띀 (HANGUL SYLLABLE DDEUK) 2403 0xB741 띁 (HANGUL SYLLABLE DDEUT) 2404 0xB742 띂 (HANGUL SYLLABLE DDEUP) 2405 0xB743 띃 (HANGUL SYLLABLE DDEUH) 2406 0xB745 띅 (HANGUL SYLLABLE DDYIG) 2407 0xB746 띆 (HANGUL SYLLABLE DDYIGG) 2408 0xB747 띇 (HANGUL SYLLABLE DDYIGS) 2409 0xB749 띉 (HANGUL SYLLABLE DDYINJ) 2410 0xB74A 띊 (HANGUL SYLLABLE DDYINH) 2411 0xB74B 띋 (HANGUL SYLLABLE DDYID) 2412 0xB74D 띍 (HANGUL SYLLABLE DDYILG) 2413 0xB74E 띎 (HANGUL SYLLABLE DDYILM) 2414 0xB74F 띏 (HANGUL SYLLABLE DDYILB) 2415 0xB750 띐 (HANGUL SYLLABLE DDYILS) 2416 0xB751 띑 (HANGUL SYLLABLE DDYILT) 2417 0xB752 띒 (HANGUL SYLLABLE DDYILP) 2418 0xB753 띓 (HANGUL SYLLABLE DDYILH) 2419 0xB756 띖 (HANGUL SYLLABLE DDYIBS) 2420 0xB757 띗 (HANGUL SYLLABLE DDYIS) 2421 0xB758 띘 (HANGUL SYLLABLE DDYISS) 2422 0xB759 띙 (HANGUL SYLLABLE DDYING) 2423 0xB75A 띚 (HANGUL SYLLABLE DDYIJ) 2424 0xB75B 띛 (HANGUL SYLLABLE DDYIC) 2425 0xB75C 띜 (HANGUL SYLLABLE DDYIK) 2426 0xB75D 띝 (HANGUL SYLLABLE DDYIT) 2427 0xB75E 띞 (HANGUL SYLLABLE DDYIP) 2428 0xB75F 띟 (HANGUL SYLLABLE DDYIH) 2429 0xB761 띡 (HANGUL SYLLABLE DDIG) 2430 0xB762 띢 (HANGUL SYLLABLE DDIGG) 2431 0xB763 띣 (HANGUL SYLLABLE DDIGS) 2432 0xB765 띥 (HANGUL SYLLABLE DDINJ) 2433 0xB766 띦 (HANGUL SYLLABLE DDINH) 2434 0xB767 띧 (HANGUL SYLLABLE DDID) 2435 0xB769 띩 (HANGUL SYLLABLE DDILG) 2436 0xB76A 띪 (HANGUL SYLLABLE DDILM) 2437 0xB76B 띫 (HANGUL SYLLABLE DDILB) 2438 0xB76C 띬 (HANGUL SYLLABLE DDILS) 2439 0xB76D 띭 (HANGUL SYLLABLE DDILT) 2440 0xB76E 띮 (HANGUL SYLLABLE DDILP) 2441 0xB76F 띯 (HANGUL SYLLABLE DDILH) 2442 0xB772 띲 (HANGUL SYLLABLE DDIBS) 2443 0xB774 띴 (HANGUL SYLLABLE DDISS) 2444 0xB776 띶 (HANGUL SYLLABLE DDIJ) 2445 0xB777 띷 (HANGUL SYLLABLE DDIC) 2446 0xB778 띸 (HANGUL SYLLABLE DDIK) 2447 0xB779 띹 (HANGUL SYLLABLE DDIT) 2448 0xB77A 띺 (HANGUL SYLLABLE DDIP) 2449 0xB77B 띻 (HANGUL SYLLABLE DDIH) 2450 0xB77E 띾 (HANGUL SYLLABLE RAGG) 2451 0xB77F 띿 (HANGUL SYLLABLE RAGS) 2452 0xB781 랁 (HANGUL SYLLABLE RANJ) 2453 0xB782 랂 (HANGUL SYLLABLE RANH) 2454 0xB783 랃 (HANGUL SYLLABLE RAD) 2455 0xB785 랅 (HANGUL SYLLABLE RALG) 2456 0xB786 랆 (HANGUL SYLLABLE RALM) 2457 0xB787 랇 (HANGUL SYLLABLE RALB) 2458 0xB788 랈 (HANGUL SYLLABLE RALS) 2459 0xB789 랉 (HANGUL SYLLABLE RALT) 2460 0xB78A 랊 (HANGUL SYLLABLE RALP) 2461 0xB78B 랋 (HANGUL SYLLABLE RALH) 2462 0xB78E 랎 (HANGUL SYLLABLE RABS) 2463 0xB793 랓 (HANGUL SYLLABLE RAC) 2464 0xB794 랔 (HANGUL SYLLABLE RAK) 2465 0xB795 랕 (HANGUL SYLLABLE RAT) 2466 0xB79A 랚 (HANGUL SYLLABLE RAEGG) 2467 0xB79B 랛 (HANGUL SYLLABLE RAEGS) 2468 0xB79D 랝 (HANGUL SYLLABLE RAENJ) 2469 0xB79E 랞 (HANGUL SYLLABLE RAENH) 2470 0xB79F 랟 (HANGUL SYLLABLE RAED) 2471 0xB7A1 랡 (HANGUL SYLLABLE RAELG) 2472 0xB7A2 랢 (HANGUL SYLLABLE RAELM) 2473 0xB7A3 랣 (HANGUL SYLLABLE RAELB) 2474 0xB7A4 랤 (HANGUL SYLLABLE RAELS) 2475 0xB7A5 랥 (HANGUL SYLLABLE RAELT) 2476 0xB7A6 랦 (HANGUL SYLLABLE RAELP) 2477 0xB7A7 랧 (HANGUL SYLLABLE RAELH) 2478 0xB7AA 랪 (HANGUL SYLLABLE RAEBS) 2479 0xB7AE 랮 (HANGUL SYLLABLE RAEJ) 2480 0xB7AF 랯 (HANGUL SYLLABLE RAEC) 2481 0xB7B0 랰 (HANGUL SYLLABLE RAEK) 2482 0xB7B1 랱 (HANGUL SYLLABLE RAET) 2483 0xB7B2 랲 (HANGUL SYLLABLE RAEP) 2484 0xB7B3 랳 (HANGUL SYLLABLE RAEH) 2485 0xB7B6 랶 (HANGUL SYLLABLE RYAGG) 2486 0xB7B7 랷 (HANGUL SYLLABLE RYAGS) 2487 0xB7B9 랹 (HANGUL SYLLABLE RYANJ) 2488 0xB7BA 랺 (HANGUL SYLLABLE RYANH) 2489 0xB7BB 랻 (HANGUL SYLLABLE RYAD) 2490 0xB7BC 랼 (HANGUL SYLLABLE RYAL) 2491 0xB7BD 랽 (HANGUL SYLLABLE RYALG) 2492 0xB7BE 랾 (HANGUL SYLLABLE RYALM) 2493 0xB7BF 랿 (HANGUL SYLLABLE RYALB) 2494 0xB7C0 럀 (HANGUL SYLLABLE RYALS) 2495 0xB7C1 럁 (HANGUL SYLLABLE RYALT) 2502 0xB7C2 럂 (HANGUL SYLLABLE RYALP) 2503 0xB7C3 럃 (HANGUL SYLLABLE RYALH) 2504 0xB7C4 럄 (HANGUL SYLLABLE RYAM) 2505 0xB7C5 럅 (HANGUL SYLLABLE RYAB) 2506 0xB7C6 럆 (HANGUL SYLLABLE RYABS) 2507 0xB7C8 럈 (HANGUL SYLLABLE RYASS) 2508 0xB7CA 럊 (HANGUL SYLLABLE RYAJ) 2509 0xB7CB 럋 (HANGUL SYLLABLE RYAC) 2510 0xB7CC 럌 (HANGUL SYLLABLE RYAK) 2511 0xB7CD 럍 (HANGUL SYLLABLE RYAT) 2512 0xB7CE 럎 (HANGUL SYLLABLE RYAP) 2513 0xB7CF 럏 (HANGUL SYLLABLE RYAH) 2514 0xB7D0 럐 (HANGUL SYLLABLE RYAE) 2515 0xB7D1 럑 (HANGUL SYLLABLE RYAEG) 2516 0xB7D2 럒 (HANGUL SYLLABLE RYAEGG) 2517 0xB7D3 럓 (HANGUL SYLLABLE RYAEGS) 2518 0xB7D4 럔 (HANGUL SYLLABLE RYAEN) 2519 0xB7D5 럕 (HANGUL SYLLABLE RYAENJ) 2520 0xB7D6 럖 (HANGUL SYLLABLE RYAENH) 2521 0xB7D7 럗 (HANGUL SYLLABLE RYAED) 2522 0xB7D8 럘 (HANGUL SYLLABLE RYAEL) 2523 0xB7D9 럙 (HANGUL SYLLABLE RYAELG) 2524 0xB7DA 럚 (HANGUL SYLLABLE RYAELM) 2525 0xB7DB 럛 (HANGUL SYLLABLE RYAELB) 2526 0xB7DC 럜 (HANGUL SYLLABLE RYAELS) 2527 0xB7DD 럝 (HANGUL SYLLABLE RYAELT) 2534 0xB7DE 럞 (HANGUL SYLLABLE RYAELP) 2535 0xB7DF 럟 (HANGUL SYLLABLE RYAELH) 2536 0xB7E0 럠 (HANGUL SYLLABLE RYAEM) 2537 0xB7E1 럡 (HANGUL SYLLABLE RYAEB) 2538 0xB7E2 럢 (HANGUL SYLLABLE RYAEBS) 2539 0xB7E3 럣 (HANGUL SYLLABLE RYAES) 2540 0xB7E4 럤 (HANGUL SYLLABLE RYAESS) 2541 0xB7E5 럥 (HANGUL SYLLABLE RYAENG) 2542 0xB7E6 럦 (HANGUL SYLLABLE RYAEJ) 2543 0xB7E7 럧 (HANGUL SYLLABLE RYAEC) 2544 0xB7E8 럨 (HANGUL SYLLABLE RYAEK) 2545 0xB7E9 럩 (HANGUL SYLLABLE RYAET) 2546 0xB7EA 럪 (HANGUL SYLLABLE RYAEP) 2547 0xB7EB 럫 (HANGUL SYLLABLE RYAEH) 2548 0xB7EE 럮 (HANGUL SYLLABLE REOGG) 2549 0xB7EF 럯 (HANGUL SYLLABLE REOGS) 2550 0xB7F1 럱 (HANGUL SYLLABLE REONJ) 2551 0xB7F2 럲 (HANGUL SYLLABLE REONH) 2552 0xB7F3 럳 (HANGUL SYLLABLE REOD) 2553 0xB7F5 럵 (HANGUL SYLLABLE REOLG) 2554 0xB7F6 럶 (HANGUL SYLLABLE REOLM) 2555 0xB7F7 럷 (HANGUL SYLLABLE REOLB) 2556 0xB7F8 럸 (HANGUL SYLLABLE REOLS) 2557 0xB7F9 럹 (HANGUL SYLLABLE REOLT) 2558 0xB7FA 럺 (HANGUL SYLLABLE REOLP) 2559 0xB7FB 럻 (HANGUL SYLLABLE REOLH) 2560 0xB7FE 럾 (HANGUL SYLLABLE REOBS) 2561 0xB802 렂 (HANGUL SYLLABLE REOJ) 2562 0xB803 렃 (HANGUL SYLLABLE REOC) 2563 0xB804 렄 (HANGUL SYLLABLE REOK) 2564 0xB805 렅 (HANGUL SYLLABLE REOT) 2565 0xB806 렆 (HANGUL SYLLABLE REOP) 2566 0xB80A 렊 (HANGUL SYLLABLE REGG) 2567 0xB80B 렋 (HANGUL SYLLABLE REGS) 2568 0xB80D 렍 (HANGUL SYLLABLE RENJ) 2569 0xB80E 렎 (HANGUL SYLLABLE RENH) 2570 0xB80F 렏 (HANGUL SYLLABLE RED) 2571 0xB811 렑 (HANGUL SYLLABLE RELG) 2572 0xB812 렒 (HANGUL SYLLABLE RELM) 2573 0xB813 렓 (HANGUL SYLLABLE RELB) 2574 0xB814 렔 (HANGUL SYLLABLE RELS) 2575 0xB815 렕 (HANGUL SYLLABLE RELT) 2576 0xB816 렖 (HANGUL SYLLABLE RELP) 2577 0xB817 렗 (HANGUL SYLLABLE RELH) 2578 0xB81A 렚 (HANGUL SYLLABLE REBS) 2579 0xB81C 렜 (HANGUL SYLLABLE RESS) 2580 0xB81E 렞 (HANGUL SYLLABLE REJ) 2581 0xB81F 렟 (HANGUL SYLLABLE REC) 2582 0xB820 렠 (HANGUL SYLLABLE REK) 2583 0xB821 렡 (HANGUL SYLLABLE RET) 2584 0xB822 렢 (HANGUL SYLLABLE REP) 2585 0xB823 렣 (HANGUL SYLLABLE REH) 2586 0xB826 렦 (HANGUL SYLLABLE RYEOGG) 2587 0xB827 렧 (HANGUL SYLLABLE RYEOGS) 2588 0xB829 렩 (HANGUL SYLLABLE RYEONJ) 2589 0xB82A 렪 (HANGUL SYLLABLE RYEONH) 2590 0xB82B 렫 (HANGUL SYLLABLE RYEOD) 2591 0xB82D 렭 (HANGUL SYLLABLE RYEOLG) 2592 0xB82E 렮 (HANGUL SYLLABLE RYEOLM) 2593 0xB82F 렯 (HANGUL SYLLABLE RYEOLB) 2594 0xB830 렰 (HANGUL SYLLABLE RYEOLS) 2595 0xB831 렱 (HANGUL SYLLABLE RYEOLT) 2596 0xB832 렲 (HANGUL SYLLABLE RYEOLP) 2597 0xB833 렳 (HANGUL SYLLABLE RYEOLH) 2598 0xB836 렶 (HANGUL SYLLABLE RYEOBS) 2599 0xB83A 렺 (HANGUL SYLLABLE RYEOJ) 2600 0xB83B 렻 (HANGUL SYLLABLE RYEOC) 2601 0xB83C 렼 (HANGUL SYLLABLE RYEOK) 2602 0xB83D 렽 (HANGUL SYLLABLE RYEOT) 2603 0xB83E 렾 (HANGUL SYLLABLE RYEOP) 2604 0xB83F 렿 (HANGUL SYLLABLE RYEOH) 2605 0xB841 롁 (HANGUL SYLLABLE RYEG) 2606 0xB842 롂 (HANGUL SYLLABLE RYEGG) 2607 0xB843 롃 (HANGUL SYLLABLE RYEGS) 2608 0xB845 롅 (HANGUL SYLLABLE RYENJ) 2609 0xB846 롆 (HANGUL SYLLABLE RYENH) 2610 0xB847 롇 (HANGUL SYLLABLE RYED) 2611 0xB848 롈 (HANGUL SYLLABLE RYEL) 2612 0xB849 롉 (HANGUL SYLLABLE RYELG) 2613 0xB84A 롊 (HANGUL SYLLABLE RYELM) 2614 0xB84B 롋 (HANGUL SYLLABLE RYELB) 2615 0xB84C 롌 (HANGUL SYLLABLE RYELS) 2616 0xB84D 롍 (HANGUL SYLLABLE RYELT) 2617 0xB84E 롎 (HANGUL SYLLABLE RYELP) 2618 0xB84F 롏 (HANGUL SYLLABLE RYELH) 2619 0xB850 롐 (HANGUL SYLLABLE RYEM) 2620 0xB852 롒 (HANGUL SYLLABLE RYEBS) 2621 0xB854 롔 (HANGUL SYLLABLE RYESS) 2622 0xB855 롕 (HANGUL SYLLABLE RYENG) 2623 0xB856 롖 (HANGUL SYLLABLE RYEJ) 2624 0xB857 롗 (HANGUL SYLLABLE RYEC) 2625 0xB858 롘 (HANGUL SYLLABLE RYEK) 2626 0xB859 롙 (HANGUL SYLLABLE RYET) 2627 0xB85A 롚 (HANGUL SYLLABLE RYEP) 2628 0xB85B 롛 (HANGUL SYLLABLE RYEH) 2629 0xB85E 롞 (HANGUL SYLLABLE ROGG) 2630 0xB85F 롟 (HANGUL SYLLABLE ROGS) 2631 0xB861 롡 (HANGUL SYLLABLE RONJ) 2632 0xB862 롢 (HANGUL SYLLABLE RONH) 2633 0xB863 롣 (HANGUL SYLLABLE ROD) 2634 0xB865 롥 (HANGUL SYLLABLE ROLG) 2635 0xB866 롦 (HANGUL SYLLABLE ROLM) 2636 0xB867 롧 (HANGUL SYLLABLE ROLB) 2637 0xB868 롨 (HANGUL SYLLABLE ROLS) 2638 0xB869 롩 (HANGUL SYLLABLE ROLT) 2639 0xB86A 롪 (HANGUL SYLLABLE ROLP) 2640 0xB86B 롫 (HANGUL SYLLABLE ROLH) 2641 0xB86E 롮 (HANGUL SYLLABLE ROBS) 2642 0xB870 롰 (HANGUL SYLLABLE ROSS) 2643 0xB872 롲 (HANGUL SYLLABLE ROJ) 2644 0xB873 롳 (HANGUL SYLLABLE ROC) 2645 0xB874 롴 (HANGUL SYLLABLE ROK) 2646 0xB875 롵 (HANGUL SYLLABLE ROT) 2647 0xB876 롶 (HANGUL SYLLABLE ROP) 2648 0xB877 롷 (HANGUL SYLLABLE ROH) 2649 0xB879 롹 (HANGUL SYLLABLE RWAG) 2650 0xB87A 롺 (HANGUL SYLLABLE RWAGG) 2651 0xB87B 롻 (HANGUL SYLLABLE RWAGS) 2652 0xB87D 롽 (HANGUL SYLLABLE RWANJ) 2653 0xB87E 롾 (HANGUL SYLLABLE RWANH) 2654 0xB87F 롿 (HANGUL SYLLABLE RWAD) 2655 0xB880 뢀 (HANGUL SYLLABLE RWAL) 2656 0xB881 뢁 (HANGUL SYLLABLE RWALG) 2657 0xB882 뢂 (HANGUL SYLLABLE RWALM) 2658 0xB883 뢃 (HANGUL SYLLABLE RWALB) 2659 0xB884 뢄 (HANGUL SYLLABLE RWALS) 2660 0xB885 뢅 (HANGUL SYLLABLE RWALT) 2661 0xB886 뢆 (HANGUL SYLLABLE RWALP) 2662 0xB887 뢇 (HANGUL SYLLABLE RWALH) 2663 0xB888 뢈 (HANGUL SYLLABLE RWAM) 2664 0xB889 뢉 (HANGUL SYLLABLE RWAB) 2665 0xB88A 뢊 (HANGUL SYLLABLE RWABS) 2666 0xB88B 뢋 (HANGUL SYLLABLE RWAS) 2667 0xB88C 뢌 (HANGUL SYLLABLE RWASS) 2668 0xB88E 뢎 (HANGUL SYLLABLE RWAJ) 2669 0xB88F 뢏 (HANGUL SYLLABLE RWAC) 2670 0xB890 뢐 (HANGUL SYLLABLE RWAK) 2671 0xB891 뢑 (HANGUL SYLLABLE RWAT) 2672 0xB892 뢒 (HANGUL SYLLABLE RWAP) 2673 0xB893 뢓 (HANGUL SYLLABLE RWAH) 2674 0xB894 뢔 (HANGUL SYLLABLE RWAE) 2675 0xB895 뢕 (HANGUL SYLLABLE RWAEG) 2676 0xB896 뢖 (HANGUL SYLLABLE RWAEGG) 2677 0xB897 뢗 (HANGUL SYLLABLE RWAEGS) 2678 0xB898 뢘 (HANGUL SYLLABLE RWAEN) 2679 0xB899 뢙 (HANGUL SYLLABLE RWAENJ) 2680 0xB89A 뢚 (HANGUL SYLLABLE RWAENH) 2681 0xB89B 뢛 (HANGUL SYLLABLE RWAED) 2682 0xB89C 뢜 (HANGUL SYLLABLE RWAEL) 2683 0xB89D 뢝 (HANGUL SYLLABLE RWAELG) 2684 0xB89E 뢞 (HANGUL SYLLABLE RWAELM) 2685 0xB89F 뢟 (HANGUL SYLLABLE RWAELB) 2692 0xB8A0 뢠 (HANGUL SYLLABLE RWAELS) 2693 0xB8A1 뢡 (HANGUL SYLLABLE RWAELT) 2694 0xB8A2 뢢 (HANGUL SYLLABLE RWAELP) 2695 0xB8A3 뢣 (HANGUL SYLLABLE RWAELH) 2696 0xB8A4 뢤 (HANGUL SYLLABLE RWAEM) 2697 0xB8A5 뢥 (HANGUL SYLLABLE RWAEB) 2698 0xB8A6 뢦 (HANGUL SYLLABLE RWAEBS) 2699 0xB8A7 뢧 (HANGUL SYLLABLE RWAES) 2700 0xB8A9 뢩 (HANGUL SYLLABLE RWAENG) 2701 0xB8AA 뢪 (HANGUL SYLLABLE RWAEJ) 2702 0xB8AB 뢫 (HANGUL SYLLABLE RWAEC) 2703 0xB8AC 뢬 (HANGUL SYLLABLE RWAEK) 2704 0xB8AD 뢭 (HANGUL SYLLABLE RWAET) 2705 0xB8AE 뢮 (HANGUL SYLLABLE RWAEP) 2706 0xB8AF 뢯 (HANGUL SYLLABLE RWAEH) 2707 0xB8B1 뢱 (HANGUL SYLLABLE ROEG) 2708 0xB8B2 뢲 (HANGUL SYLLABLE ROEGG) 2709 0xB8B3 뢳 (HANGUL SYLLABLE ROEGS) 2710 0xB8B5 뢵 (HANGUL SYLLABLE ROENJ) 2711 0xB8B6 뢶 (HANGUL SYLLABLE ROENH) 2712 0xB8B7 뢷 (HANGUL SYLLABLE ROED) 2713 0xB8B9 뢹 (HANGUL SYLLABLE ROELG) 2714 0xB8BA 뢺 (HANGUL SYLLABLE ROELM) 2715 0xB8BB 뢻 (HANGUL SYLLABLE ROELB) 2716 0xB8BC 뢼 (HANGUL SYLLABLE ROELS) 2717 0xB8BD 뢽 (HANGUL SYLLABLE ROELT) 2724 0xB8BE 뢾 (HANGUL SYLLABLE ROELP) 2725 0xB8BF 뢿 (HANGUL SYLLABLE ROELH) 2726 0xB8C2 룂 (HANGUL SYLLABLE ROEBS) 2727 0xB8C4 룄 (HANGUL SYLLABLE ROESS) 2728 0xB8C6 룆 (HANGUL SYLLABLE ROEJ) 2729 0xB8C7 룇 (HANGUL SYLLABLE ROEC) 2730 0xB8C8 룈 (HANGUL SYLLABLE ROEK) 2731 0xB8C9 룉 (HANGUL SYLLABLE ROET) 2732 0xB8CA 룊 (HANGUL SYLLABLE ROEP) 2733 0xB8CB 룋 (HANGUL SYLLABLE ROEH) 2734 0xB8CD 룍 (HANGUL SYLLABLE RYOG) 2735 0xB8CE 룎 (HANGUL SYLLABLE RYOGG) 2736 0xB8CF 룏 (HANGUL SYLLABLE RYOGS) 2737 0xB8D1 룑 (HANGUL SYLLABLE RYONJ) 2738 0xB8D2 룒 (HANGUL SYLLABLE RYONH) 2739 0xB8D3 룓 (HANGUL SYLLABLE RYOD) 2740 0xB8D5 룕 (HANGUL SYLLABLE RYOLG) 2741 0xB8D6 룖 (HANGUL SYLLABLE RYOLM) 2742 0xB8D7 룗 (HANGUL SYLLABLE RYOLB) 2743 0xB8D8 룘 (HANGUL SYLLABLE RYOLS) 2744 0xB8D9 룙 (HANGUL SYLLABLE RYOLT) 2745 0xB8DA 룚 (HANGUL SYLLABLE RYOLP) 2746 0xB8DB 룛 (HANGUL SYLLABLE RYOLH) 2747 0xB8DC 룜 (HANGUL SYLLABLE RYOM) 2748 0xB8DE 룞 (HANGUL SYLLABLE RYOBS) 2749 0xB8E0 룠 (HANGUL SYLLABLE RYOSS) 2750 0xB8E2 룢 (HANGUL SYLLABLE RYOJ) 2751 0xB8E3 룣 (HANGUL SYLLABLE RYOC) 2752 0xB8E4 룤 (HANGUL SYLLABLE RYOK) 2753 0xB8E5 룥 (HANGUL SYLLABLE RYOT) 2754 0xB8E6 룦 (HANGUL SYLLABLE RYOP) 2755 0xB8E7 룧 (HANGUL SYLLABLE RYOH) 2756 0xB8EA 룪 (HANGUL SYLLABLE RUGG) 2757 0xB8EB 룫 (HANGUL SYLLABLE RUGS) 2758 0xB8ED 룭 (HANGUL SYLLABLE RUNJ) 2759 0xB8EE 룮 (HANGUL SYLLABLE RUNH) 2760 0xB8EF 룯 (HANGUL SYLLABLE RUD) 2761 0xB8F1 룱 (HANGUL SYLLABLE RULG) 2762 0xB8F2 룲 (HANGUL SYLLABLE RULM) 2763 0xB8F3 룳 (HANGUL SYLLABLE RULB) 2764 0xB8F4 룴 (HANGUL SYLLABLE RULS) 2765 0xB8F5 룵 (HANGUL SYLLABLE RULT) 2766 0xB8F6 룶 (HANGUL SYLLABLE RULP) 2767 0xB8F7 룷 (HANGUL SYLLABLE RULH) 2768 0xB8FA 룺 (HANGUL SYLLABLE RUBS) 2769 0xB8FC 룼 (HANGUL SYLLABLE RUSS) 2770 0xB8FE 룾 (HANGUL SYLLABLE RUJ) 2771 0xB8FF 룿 (HANGUL SYLLABLE RUC) 2772 0xB900 뤀 (HANGUL SYLLABLE RUK) 2773 0xB901 뤁 (HANGUL SYLLABLE RUT) 2774 0xB902 뤂 (HANGUL SYLLABLE RUP) 2775 0xB903 뤃 (HANGUL SYLLABLE RUH) 2776 0xB905 뤅 (HANGUL SYLLABLE RWEOG) 2777 0xB906 뤆 (HANGUL SYLLABLE RWEOGG) 2778 0xB907 뤇 (HANGUL SYLLABLE RWEOGS) 2779 0xB908 뤈 (HANGUL SYLLABLE RWEON) 2780 0xB909 뤉 (HANGUL SYLLABLE RWEONJ) 2781 0xB90A 뤊 (HANGUL SYLLABLE RWEONH) 2782 0xB90B 뤋 (HANGUL SYLLABLE RWEOD) 2783 0xB90C 뤌 (HANGUL SYLLABLE RWEOL) 2784 0xB90D 뤍 (HANGUL SYLLABLE RWEOLG) 2785 0xB90E 뤎 (HANGUL SYLLABLE RWEOLM) 2786 0xB90F 뤏 (HANGUL SYLLABLE RWEOLB) 2787 0xB910 뤐 (HANGUL SYLLABLE RWEOLS) 2788 0xB911 뤑 (HANGUL SYLLABLE RWEOLT) 2789 0xB912 뤒 (HANGUL SYLLABLE RWEOLP) 2790 0xB913 뤓 (HANGUL SYLLABLE RWEOLH) 2791 0xB914 뤔 (HANGUL SYLLABLE RWEOM) 2792 0xB915 뤕 (HANGUL SYLLABLE RWEOB) 2793 0xB916 뤖 (HANGUL SYLLABLE RWEOBS) 2794 0xB917 뤗 (HANGUL SYLLABLE RWEOS) 2795 0xB919 뤙 (HANGUL SYLLABLE RWEONG) 2796 0xB91A 뤚 (HANGUL SYLLABLE RWEOJ) 2797 0xB91B 뤛 (HANGUL SYLLABLE RWEOC) 2798 0xB91C 뤜 (HANGUL SYLLABLE RWEOK) 2799 0xB91D 뤝 (HANGUL SYLLABLE RWEOT) 2800 0xB91E 뤞 (HANGUL SYLLABLE RWEOP) 2801 0xB91F 뤟 (HANGUL SYLLABLE RWEOH) 2802 0xB921 뤡 (HANGUL SYLLABLE RWEG) 2803 0xB922 뤢 (HANGUL SYLLABLE RWEGG) 2804 0xB923 뤣 (HANGUL SYLLABLE RWEGS) 2805 0xB924 뤤 (HANGUL SYLLABLE RWEN) 2806 0xB925 뤥 (HANGUL SYLLABLE RWENJ) 2807 0xB926 뤦 (HANGUL SYLLABLE RWENH) 2808 0xB927 뤧 (HANGUL SYLLABLE RWED) 2809 0xB928 뤨 (HANGUL SYLLABLE RWEL) 2810 0xB929 뤩 (HANGUL SYLLABLE RWELG) 2811 0xB92A 뤪 (HANGUL SYLLABLE RWELM) 2812 0xB92B 뤫 (HANGUL SYLLABLE RWELB) 2813 0xB92C 뤬 (HANGUL SYLLABLE RWELS) 2814 0xB92D 뤭 (HANGUL SYLLABLE RWELT) 2815 0xB92E 뤮 (HANGUL SYLLABLE RWELP) 2816 0xB92F 뤯 (HANGUL SYLLABLE RWELH) 2817 0xB930 뤰 (HANGUL SYLLABLE RWEM) 2818 0xB931 뤱 (HANGUL SYLLABLE RWEB) 2819 0xB932 뤲 (HANGUL SYLLABLE RWEBS) 2820 0xB933 뤳 (HANGUL SYLLABLE RWES) 2821 0xB934 뤴 (HANGUL SYLLABLE RWESS) 2822 0xB935 뤵 (HANGUL SYLLABLE RWENG) 2823 0xB936 뤶 (HANGUL SYLLABLE RWEJ) 2824 0xB937 뤷 (HANGUL SYLLABLE RWEC) 2825 0xB938 뤸 (HANGUL SYLLABLE RWEK) 2826 0xB939 뤹 (HANGUL SYLLABLE RWET) 2827 0xB93A 뤺 (HANGUL SYLLABLE RWEP) 2828 0xB93B 뤻 (HANGUL SYLLABLE RWEH) 2829 0xB93E 뤾 (HANGUL SYLLABLE RWIGG) 2830 0xB93F 뤿 (HANGUL SYLLABLE RWIGS) 2831 0xB941 륁 (HANGUL SYLLABLE RWINJ) 2832 0xB942 륂 (HANGUL SYLLABLE RWINH) 2833 0xB943 륃 (HANGUL SYLLABLE RWID) 2834 0xB945 륅 (HANGUL SYLLABLE RWILG) 2835 0xB946 륆 (HANGUL SYLLABLE RWILM) 2836 0xB947 륇 (HANGUL SYLLABLE RWILB) 2837 0xB948 륈 (HANGUL SYLLABLE RWILS) 2838 0xB949 륉 (HANGUL SYLLABLE RWILT) 2839 0xB94A 륊 (HANGUL SYLLABLE RWILP) 2840 0xB94B 륋 (HANGUL SYLLABLE RWILH) 2841 0xB94D 륍 (HANGUL SYLLABLE RWIB) 2842 0xB94E 륎 (HANGUL SYLLABLE RWIBS) 2843 0xB950 륐 (HANGUL SYLLABLE RWISS) 2844 0xB952 륒 (HANGUL SYLLABLE RWIJ) 2845 0xB953 륓 (HANGUL SYLLABLE RWIC) 2846 0xB954 륔 (HANGUL SYLLABLE RWIK) 2847 0xB955 륕 (HANGUL SYLLABLE RWIT) 2848 0xB956 륖 (HANGUL SYLLABLE RWIP) 2849 0xB957 륗 (HANGUL SYLLABLE RWIH) 2850 0xB95A 륚 (HANGUL SYLLABLE RYUGG) 2851 0xB95B 륛 (HANGUL SYLLABLE RYUGS) 2852 0xB95D 륝 (HANGUL SYLLABLE RYUNJ) 2853 0xB95E 륞 (HANGUL SYLLABLE RYUNH) 2854 0xB95F 륟 (HANGUL SYLLABLE RYUD) 2855 0xB961 륡 (HANGUL SYLLABLE RYULG) 2856 0xB962 륢 (HANGUL SYLLABLE RYULM) 2857 0xB963 륣 (HANGUL SYLLABLE RYULB) 2858 0xB964 륤 (HANGUL SYLLABLE RYULS) 2859 0xB965 륥 (HANGUL SYLLABLE RYULT) 2860 0xB966 륦 (HANGUL SYLLABLE RYULP) 2861 0xB967 륧 (HANGUL SYLLABLE RYULH) 2862 0xB96A 륪 (HANGUL SYLLABLE RYUBS) 2863 0xB96C 륬 (HANGUL SYLLABLE RYUSS) 2864 0xB96E 륮 (HANGUL SYLLABLE RYUJ) 2865 0xB96F 륯 (HANGUL SYLLABLE RYUC) 2866 0xB970 륰 (HANGUL SYLLABLE RYUK) 2867 0xB971 륱 (HANGUL SYLLABLE RYUT) 2868 0xB972 륲 (HANGUL SYLLABLE RYUP) 2869 0xB973 륳 (HANGUL SYLLABLE RYUH) 2870 0xB976 륶 (HANGUL SYLLABLE REUGG) 2871 0xB977 륷 (HANGUL SYLLABLE REUGS) 2872 0xB979 륹 (HANGUL SYLLABLE REUNJ) 2873 0xB97A 륺 (HANGUL SYLLABLE REUNH) 2874 0xB97B 륻 (HANGUL SYLLABLE REUD) 2875 0xB97D 륽 (HANGUL SYLLABLE REULG) 2882 0xB97E 륾 (HANGUL SYLLABLE REULM) 2883 0xB97F 륿 (HANGUL SYLLABLE REULB) 2884 0xB980 릀 (HANGUL SYLLABLE REULS) 2885 0xB981 릁 (HANGUL SYLLABLE REULT) 2886 0xB982 릂 (HANGUL SYLLABLE REULP) 2887 0xB983 릃 (HANGUL SYLLABLE REULH) 2888 0xB986 릆 (HANGUL SYLLABLE REUBS) 2889 0xB988 릈 (HANGUL SYLLABLE REUSS) 2890 0xB98B 릋 (HANGUL SYLLABLE REUC) 2891 0xB98C 릌 (HANGUL SYLLABLE REUK) 2892 0xB98F 릏 (HANGUL SYLLABLE REUH) 2893 0xB990 릐 (HANGUL SYLLABLE RYI) 2894 0xB991 릑 (HANGUL SYLLABLE RYIG) 2895 0xB992 릒 (HANGUL SYLLABLE RYIGG) 2896 0xB993 릓 (HANGUL SYLLABLE RYIGS) 2897 0xB994 릔 (HANGUL SYLLABLE RYIN) 2898 0xB995 릕 (HANGUL SYLLABLE RYINJ) 2899 0xB996 릖 (HANGUL SYLLABLE RYINH) 2900 0xB997 릗 (HANGUL SYLLABLE RYID) 2901 0xB998 릘 (HANGUL SYLLABLE RYIL) 2902 0xB999 릙 (HANGUL SYLLABLE RYILG) 2903 0xB99A 릚 (HANGUL SYLLABLE RYILM) 2904 0xB99B 릛 (HANGUL SYLLABLE RYILB) 2905 0xB99C 릜 (HANGUL SYLLABLE RYILS) 2906 0xB99D 릝 (HANGUL SYLLABLE RYILT) 2907 0xB99E 릞 (HANGUL SYLLABLE RYILP) 2914 0xB99F 릟 (HANGUL SYLLABLE RYILH) 2915 0xB9A0 릠 (HANGUL SYLLABLE RYIM) 2916 0xB9A1 릡 (HANGUL SYLLABLE RYIB) 2917 0xB9A2 릢 (HANGUL SYLLABLE RYIBS) 2918 0xB9A3 릣 (HANGUL SYLLABLE RYIS) 2919 0xB9A4 릤 (HANGUL SYLLABLE RYISS) 2920 0xB9A5 릥 (HANGUL SYLLABLE RYING) 2921 0xB9A6 릦 (HANGUL SYLLABLE RYIJ) 2922 0xB9A7 릧 (HANGUL SYLLABLE RYIC) 2923 0xB9A8 릨 (HANGUL SYLLABLE RYIK) 2924 0xB9A9 릩 (HANGUL SYLLABLE RYIT) 2925 0xB9AA 릪 (HANGUL SYLLABLE RYIP) 2926 0xB9AB 릫 (HANGUL SYLLABLE RYIH) 2927 0xB9AE 릮 (HANGUL SYLLABLE RIGG) 2928 0xB9AF 릯 (HANGUL SYLLABLE RIGS) 2929 0xB9B1 릱 (HANGUL SYLLABLE RINJ) 2930 0xB9B2 릲 (HANGUL SYLLABLE RINH) 2931 0xB9B3 릳 (HANGUL SYLLABLE RID) 2932 0xB9B5 릵 (HANGUL SYLLABLE RILG) 2933 0xB9B6 릶 (HANGUL SYLLABLE RILM) 2934 0xB9B7 릷 (HANGUL SYLLABLE RILB) 2935 0xB9B8 릸 (HANGUL SYLLABLE RILS) 2936 0xB9B9 릹 (HANGUL SYLLABLE RILT) 2937 0xB9BA 릺 (HANGUL SYLLABLE RILP) 2938 0xB9BB 릻 (HANGUL SYLLABLE RILH) 2939 0xB9BE 릾 (HANGUL SYLLABLE RIBS) 2940 0xB9C0 맀 (HANGUL SYLLABLE RISS) 2941 0xB9C2 맂 (HANGUL SYLLABLE RIJ) 2942 0xB9C3 맃 (HANGUL SYLLABLE RIC) 2943 0xB9C4 맄 (HANGUL SYLLABLE RIK) 2944 0xB9C5 맅 (HANGUL SYLLABLE RIT) 2945 0xB9C6 맆 (HANGUL SYLLABLE RIP) 2946 0xB9C7 맇 (HANGUL SYLLABLE RIH) 2947 0xB9CA 맊 (HANGUL SYLLABLE MAGG) 2948 0xB9CB 맋 (HANGUL SYLLABLE MAGS) 2949 0xB9CD 맍 (HANGUL SYLLABLE MANJ) 2950 0xB9D3 맓 (HANGUL SYLLABLE MALB) 2951 0xB9D4 맔 (HANGUL SYLLABLE MALS) 2952 0xB9D5 맕 (HANGUL SYLLABLE MALT) 2953 0xB9D6 맖 (HANGUL SYLLABLE MALP) 2954 0xB9D7 맗 (HANGUL SYLLABLE MALH) 2955 0xB9DA 맚 (HANGUL SYLLABLE MABS) 2956 0xB9DC 맜 (HANGUL SYLLABLE MASS) 2957 0xB9DF 맟 (HANGUL SYLLABLE MAC) 2958 0xB9E0 맠 (HANGUL SYLLABLE MAK) 2959 0xB9E2 맢 (HANGUL SYLLABLE MAP) 2960 0xB9E6 맦 (HANGUL SYLLABLE MAEGG) 2961 0xB9E7 맧 (HANGUL SYLLABLE MAEGS) 2962 0xB9E9 맩 (HANGUL SYLLABLE MAENJ) 2963 0xB9EA 맪 (HANGUL SYLLABLE MAENH) 2964 0xB9EB 맫 (HANGUL SYLLABLE MAED) 2965 0xB9ED 맭 (HANGUL SYLLABLE MAELG) 2966 0xB9EE 맮 (HANGUL SYLLABLE MAELM) 2967 0xB9EF 맯 (HANGUL SYLLABLE MAELB) 2968 0xB9F0 맰 (HANGUL SYLLABLE MAELS) 2969 0xB9F1 맱 (HANGUL SYLLABLE MAELT) 2970 0xB9F2 맲 (HANGUL SYLLABLE MAELP) 2971 0xB9F3 맳 (HANGUL SYLLABLE MAELH) 2972 0xB9F6 맶 (HANGUL SYLLABLE MAEBS) 2973 0xB9FB 맻 (HANGUL SYLLABLE MAEC) 2974 0xB9FC 맼 (HANGUL SYLLABLE MAEK) 2975 0xB9FD 맽 (HANGUL SYLLABLE MAET) 2976 0xB9FE 맾 (HANGUL SYLLABLE MAEP) 2977 0xB9FF 맿 (HANGUL SYLLABLE MAEH) 2978 0xBA02 먂 (HANGUL SYLLABLE MYAGG) 2979 0xBA03 먃 (HANGUL SYLLABLE MYAGS) 2980 0xBA04 먄 (HANGUL SYLLABLE MYAN) 2981 0xBA05 먅 (HANGUL SYLLABLE MYANJ) 2982 0xBA06 먆 (HANGUL SYLLABLE MYANH) 2983 0xBA07 먇 (HANGUL SYLLABLE MYAD) 2984 0xBA09 먉 (HANGUL SYLLABLE MYALG) 2985 0xBA0A 먊 (HANGUL SYLLABLE MYALM) 2986 0xBA0B 먋 (HANGUL SYLLABLE MYALB) 2987 0xBA0C 먌 (HANGUL SYLLABLE MYALS) 2988 0xBA0D 먍 (HANGUL SYLLABLE MYALT) 2989 0xBA0E 먎 (HANGUL SYLLABLE MYALP) 2990 0xBA0F 먏 (HANGUL SYLLABLE MYALH) 2991 0xBA10 먐 (HANGUL SYLLABLE MYAM) 2992 0xBA11 먑 (HANGUL SYLLABLE MYAB) 2993 0xBA12 먒 (HANGUL SYLLABLE MYABS) 2994 0xBA13 먓 (HANGUL SYLLABLE MYAS) 2995 0xBA14 먔 (HANGUL SYLLABLE MYASS) 2996 0xBA16 먖 (HANGUL SYLLABLE MYAJ) 2997 0xBA17 먗 (HANGUL SYLLABLE MYAC) 2998 0xBA18 먘 (HANGUL SYLLABLE MYAK) 2999 0xBA19 먙 (HANGUL SYLLABLE MYAT) 3000 0xBA1A 먚 (HANGUL SYLLABLE MYAP) 3001 0xBA1B 먛 (HANGUL SYLLABLE MYAH) 3002 0xBA1C 먜 (HANGUL SYLLABLE MYAE) 3003 0xBA1D 먝 (HANGUL SYLLABLE MYAEG) 3004 0xBA1E 먞 (HANGUL SYLLABLE MYAEGG) 3005 0xBA1F 먟 (HANGUL SYLLABLE MYAEGS) 3006 0xBA20 먠 (HANGUL SYLLABLE MYAEN) 3007 0xBA21 먡 (HANGUL SYLLABLE MYAENJ) 3008 0xBA22 먢 (HANGUL SYLLABLE MYAENH) 3009 0xBA23 먣 (HANGUL SYLLABLE MYAED) 3010 0xBA24 먤 (HANGUL SYLLABLE MYAEL) 3011 0xBA25 먥 (HANGUL SYLLABLE MYAELG) 3012 0xBA26 먦 (HANGUL SYLLABLE MYAELM) 3013 0xBA27 먧 (HANGUL SYLLABLE MYAELB) 3014 0xBA28 먨 (HANGUL SYLLABLE MYAELS) 3015 0xBA29 먩 (HANGUL SYLLABLE MYAELT) 3016 0xBA2A 먪 (HANGUL SYLLABLE MYAELP) 3017 0xBA2B 먫 (HANGUL SYLLABLE MYAELH) 3018 0xBA2C 먬 (HANGUL SYLLABLE MYAEM) 3019 0xBA2D 먭 (HANGUL SYLLABLE MYAEB) 3020 0xBA2E 먮 (HANGUL SYLLABLE MYAEBS) 3021 0xBA2F 먯 (HANGUL SYLLABLE MYAES) 3022 0xBA30 먰 (HANGUL SYLLABLE MYAESS) 3023 0xBA31 먱 (HANGUL SYLLABLE MYAENG) 3024 0xBA32 먲 (HANGUL SYLLABLE MYAEJ) 3025 0xBA33 먳 (HANGUL SYLLABLE MYAEC) 3026 0xBA34 먴 (HANGUL SYLLABLE MYAEK) 3027 0xBA35 먵 (HANGUL SYLLABLE MYAET) 3028 0xBA36 먶 (HANGUL SYLLABLE MYAEP) 3029 0xBA37 먷 (HANGUL SYLLABLE MYAEH) 3030 0xBA3A 먺 (HANGUL SYLLABLE MEOGG) 3031 0xBA3B 먻 (HANGUL SYLLABLE MEOGS) 3032 0xBA3D 먽 (HANGUL SYLLABLE MEONJ) 3033 0xBA3E 먾 (HANGUL SYLLABLE MEONH) 3034 0xBA3F 먿 (HANGUL SYLLABLE MEOD) 3035 0xBA41 멁 (HANGUL SYLLABLE MEOLG) 3036 0xBA43 멃 (HANGUL SYLLABLE MEOLB) 3037 0xBA44 멄 (HANGUL SYLLABLE MEOLS) 3038 0xBA45 멅 (HANGUL SYLLABLE MEOLT) 3039 0xBA46 멆 (HANGUL SYLLABLE MEOLP) 3040 0xBA47 멇 (HANGUL SYLLABLE MEOLH) 3041 0xBA4A 멊 (HANGUL SYLLABLE MEOBS) 3042 0xBA4C 멌 (HANGUL SYLLABLE MEOSS) 3043 0xBA4F 멏 (HANGUL SYLLABLE MEOC) 3044 0xBA50 멐 (HANGUL SYLLABLE MEOK) 3045 0xBA51 멑 (HANGUL SYLLABLE MEOT) 3046 0xBA52 멒 (HANGUL SYLLABLE MEOP) 3047 0xBA56 멖 (HANGUL SYLLABLE MEGG) 3048 0xBA57 멗 (HANGUL SYLLABLE MEGS) 3049 0xBA59 멙 (HANGUL SYLLABLE MENJ) 3050 0xBA5A 멚 (HANGUL SYLLABLE MENH) 3051 0xBA5B 멛 (HANGUL SYLLABLE MED) 3052 0xBA5D 멝 (HANGUL SYLLABLE MELG) 3053 0xBA5E 멞 (HANGUL SYLLABLE MELM) 3054 0xBA5F 멟 (HANGUL SYLLABLE MELB) 3055 0xBA60 멠 (HANGUL SYLLABLE MELS) 3056 0xBA61 멡 (HANGUL SYLLABLE MELT) 3057 0xBA62 멢 (HANGUL SYLLABLE MELP) 3058 0xBA63 멣 (HANGUL SYLLABLE MELH) 3059 0xBA66 멦 (HANGUL SYLLABLE MEBS) 3060 0xBA6A 멪 (HANGUL SYLLABLE MEJ) 3061 0xBA6B 멫 (HANGUL SYLLABLE MEC) 3062 0xBA6C 멬 (HANGUL SYLLABLE MEK) 3063 0xBA6D 멭 (HANGUL SYLLABLE MET) 3064 0xBA6E 멮 (HANGUL SYLLABLE MEP) 3065 0xBA6F 멯 (HANGUL SYLLABLE MEH) 3072 0xBA72 멲 (HANGUL SYLLABLE MYEOGG) 3073 0xBA73 멳 (HANGUL SYLLABLE MYEOGS) 3074 0xBA75 멵 (HANGUL SYLLABLE MYEONJ) 3075 0xBA76 멶 (HANGUL SYLLABLE MYEONH) 3076 0xBA77 멷 (HANGUL SYLLABLE MYEOD) 3077 0xBA79 멹 (HANGUL SYLLABLE MYEOLG) 3078 0xBA7A 멺 (HANGUL SYLLABLE MYEOLM) 3079 0xBA7B 멻 (HANGUL SYLLABLE MYEOLB) 3080 0xBA7C 멼 (HANGUL SYLLABLE MYEOLS) 3081 0xBA7D 멽 (HANGUL SYLLABLE MYEOLT) 3082 0xBA7E 멾 (HANGUL SYLLABLE MYEOLP) 3083 0xBA7F 멿 (HANGUL SYLLABLE MYEOLH) 3084 0xBA80 몀 (HANGUL SYLLABLE MYEOM) 3085 0xBA81 몁 (HANGUL SYLLABLE MYEOB) 3086 0xBA82 몂 (HANGUL SYLLABLE MYEOBS) 3087 0xBA86 몆 (HANGUL SYLLABLE MYEOJ) 3088 0xBA88 몈 (HANGUL SYLLABLE MYEOK) 3089 0xBA89 몉 (HANGUL SYLLABLE MYEOT) 3090 0xBA8A 몊 (HANGUL SYLLABLE MYEOP) 3091 0xBA8B 몋 (HANGUL SYLLABLE MYEOH) 3092 0xBA8D 몍 (HANGUL SYLLABLE MYEG) 3093 0xBA8E 몎 (HANGUL SYLLABLE MYEGG) 3094 0xBA8F 몏 (HANGUL SYLLABLE MYEGS) 3095 0xBA90 몐 (HANGUL SYLLABLE MYEN) 3096 0xBA91 몑 (HANGUL SYLLABLE MYENJ) 3097 0xBA92 몒 (HANGUL SYLLABLE MYENH) 3104 0xBA93 몓 (HANGUL SYLLABLE MYED) 3105 0xBA94 몔 (HANGUL SYLLABLE MYEL) 3106 0xBA95 몕 (HANGUL SYLLABLE MYELG) 3107 0xBA96 몖 (HANGUL SYLLABLE MYELM) 3108 0xBA97 몗 (HANGUL SYLLABLE MYELB) 3109 0xBA98 몘 (HANGUL SYLLABLE MYELS) 3110 0xBA99 몙 (HANGUL SYLLABLE MYELT) 3111 0xBA9A 몚 (HANGUL SYLLABLE MYELP) 3112 0xBA9B 몛 (HANGUL SYLLABLE MYELH) 3113 0xBA9C 몜 (HANGUL SYLLABLE MYEM) 3114 0xBA9D 몝 (HANGUL SYLLABLE MYEB) 3115 0xBA9E 몞 (HANGUL SYLLABLE MYEBS) 3116 0xBA9F 몟 (HANGUL SYLLABLE MYES) 3117 0xBAA0 몠 (HANGUL SYLLABLE MYESS) 3118 0xBAA1 몡 (HANGUL SYLLABLE MYENG) 3119 0xBAA2 몢 (HANGUL SYLLABLE MYEJ) 3120 0xBAA3 몣 (HANGUL SYLLABLE MYEC) 3121 0xBAA4 몤 (HANGUL SYLLABLE MYEK) 3122 0xBAA5 몥 (HANGUL SYLLABLE MYET) 3123 0xBAA6 몦 (HANGUL SYLLABLE MYEP) 3124 0xBAA7 몧 (HANGUL SYLLABLE MYEH) 3125 0xBAAA 몪 (HANGUL SYLLABLE MOGG) 3126 0xBAAD 몭 (HANGUL SYLLABLE MONJ) 3127 0xBAAE 몮 (HANGUL SYLLABLE MONH) 3128 0xBAAF 몯 (HANGUL SYLLABLE MOD) 3129 0xBAB1 몱 (HANGUL SYLLABLE MOLG) 3130 0xBAB3 몳 (HANGUL SYLLABLE MOLB) 3131 0xBAB4 몴 (HANGUL SYLLABLE MOLS) 3132 0xBAB5 몵 (HANGUL SYLLABLE MOLT) 3133 0xBAB6 몶 (HANGUL SYLLABLE MOLP) 3134 0xBAB7 몷 (HANGUL SYLLABLE MOLH) 3135 0xBABA 몺 (HANGUL SYLLABLE MOBS) 3136 0xBABC 몼 (HANGUL SYLLABLE MOSS) 3137 0xBABE 몾 (HANGUL SYLLABLE MOJ) 3138 0xBABF 몿 (HANGUL SYLLABLE MOC) 3139 0xBAC0 뫀 (HANGUL SYLLABLE MOK) 3140 0xBAC1 뫁 (HANGUL SYLLABLE MOT) 3141 0xBAC2 뫂 (HANGUL SYLLABLE MOP) 3142 0xBAC3 뫃 (HANGUL SYLLABLE MOH) 3143 0xBAC5 뫅 (HANGUL SYLLABLE MWAG) 3144 0xBAC6 뫆 (HANGUL SYLLABLE MWAGG) 3145 0xBAC7 뫇 (HANGUL SYLLABLE MWAGS) 3146 0xBAC9 뫉 (HANGUL SYLLABLE MWANJ) 3147 0xBACA 뫊 (HANGUL SYLLABLE MWANH) 3148 0xBACB 뫋 (HANGUL SYLLABLE MWAD) 3149 0xBACC 뫌 (HANGUL SYLLABLE MWAL) 3150 0xBACD 뫍 (HANGUL SYLLABLE MWALG) 3151 0xBACE 뫎 (HANGUL SYLLABLE MWALM) 3152 0xBACF 뫏 (HANGUL SYLLABLE MWALB) 3153 0xBAD0 뫐 (HANGUL SYLLABLE MWALS) 3154 0xBAD1 뫑 (HANGUL SYLLABLE MWALT) 3155 0xBAD2 뫒 (HANGUL SYLLABLE MWALP) 3156 0xBAD3 뫓 (HANGUL SYLLABLE MWALH) 3157 0xBAD4 뫔 (HANGUL SYLLABLE MWAM) 3158 0xBAD5 뫕 (HANGUL SYLLABLE MWAB) 3159 0xBAD6 뫖 (HANGUL SYLLABLE MWABS) 3160 0xBAD7 뫗 (HANGUL SYLLABLE MWAS) 3161 0xBADA 뫚 (HANGUL SYLLABLE MWAJ) 3162 0xBADB 뫛 (HANGUL SYLLABLE MWAC) 3163 0xBADC 뫜 (HANGUL SYLLABLE MWAK) 3164 0xBADD 뫝 (HANGUL SYLLABLE MWAT) 3165 0xBADE 뫞 (HANGUL SYLLABLE MWAP) 3166 0xBADF 뫟 (HANGUL SYLLABLE MWAH) 3167 0xBAE0 뫠 (HANGUL SYLLABLE MWAE) 3168 0xBAE1 뫡 (HANGUL SYLLABLE MWAEG) 3169 0xBAE2 뫢 (HANGUL SYLLABLE MWAEGG) 3170 0xBAE3 뫣 (HANGUL SYLLABLE MWAEGS) 3171 0xBAE4 뫤 (HANGUL SYLLABLE MWAEN) 3172 0xBAE5 뫥 (HANGUL SYLLABLE MWAENJ) 3173 0xBAE6 뫦 (HANGUL SYLLABLE MWAENH) 3174 0xBAE7 뫧 (HANGUL SYLLABLE MWAED) 3175 0xBAE8 뫨 (HANGUL SYLLABLE MWAEL) 3176 0xBAE9 뫩 (HANGUL SYLLABLE MWAELG) 3177 0xBAEA 뫪 (HANGUL SYLLABLE MWAELM) 3178 0xBAEB 뫫 (HANGUL SYLLABLE MWAELB) 3179 0xBAEC 뫬 (HANGUL SYLLABLE MWAELS) 3180 0xBAED 뫭 (HANGUL SYLLABLE MWAELT) 3181 0xBAEE 뫮 (HANGUL SYLLABLE MWAELP) 3182 0xBAEF 뫯 (HANGUL SYLLABLE MWAELH) 3183 0xBAF0 뫰 (HANGUL SYLLABLE MWAEM) 3184 0xBAF1 뫱 (HANGUL SYLLABLE MWAEB) 3185 0xBAF2 뫲 (HANGUL SYLLABLE MWAEBS) 3186 0xBAF3 뫳 (HANGUL SYLLABLE MWAES) 3187 0xBAF4 뫴 (HANGUL SYLLABLE MWAESS) 3188 0xBAF5 뫵 (HANGUL SYLLABLE MWAENG) 3189 0xBAF6 뫶 (HANGUL SYLLABLE MWAEJ) 3190 0xBAF7 뫷 (HANGUL SYLLABLE MWAEC) 3191 0xBAF8 뫸 (HANGUL SYLLABLE MWAEK) 3192 0xBAF9 뫹 (HANGUL SYLLABLE MWAET) 3193 0xBAFA 뫺 (HANGUL SYLLABLE MWAEP) 3194 0xBAFB 뫻 (HANGUL SYLLABLE MWAEH) 3195 0xBAFD 뫽 (HANGUL SYLLABLE MOEG) 3196 0xBAFE 뫾 (HANGUL SYLLABLE MOEGG) 3197 0xBAFF 뫿 (HANGUL SYLLABLE MOEGS) 3198 0xBB01 묁 (HANGUL SYLLABLE MOENJ) 3199 0xBB02 묂 (HANGUL SYLLABLE MOENH) 3200 0xBB03 묃 (HANGUL SYLLABLE MOED) 3201 0xBB05 묅 (HANGUL SYLLABLE MOELG) 3202 0xBB06 묆 (HANGUL SYLLABLE MOELM) 3203 0xBB07 묇 (HANGUL SYLLABLE MOELB) 3204 0xBB08 묈 (HANGUL SYLLABLE MOELS) 3205 0xBB09 묉 (HANGUL SYLLABLE MOELT) 3206 0xBB0A 묊 (HANGUL SYLLABLE MOELP) 3207 0xBB0B 묋 (HANGUL SYLLABLE MOELH) 3208 0xBB0C 묌 (HANGUL SYLLABLE MOEM) 3209 0xBB0E 묎 (HANGUL SYLLABLE MOEBS) 3210 0xBB10 묐 (HANGUL SYLLABLE MOESS) 3211 0xBB12 묒 (HANGUL SYLLABLE MOEJ) 3212 0xBB13 묓 (HANGUL SYLLABLE MOEC) 3213 0xBB14 묔 (HANGUL SYLLABLE MOEK) 3214 0xBB15 묕 (HANGUL SYLLABLE MOET) 3215 0xBB16 묖 (HANGUL SYLLABLE MOEP) 3216 0xBB17 묗 (HANGUL SYLLABLE MOEH) 3217 0xBB19 묙 (HANGUL SYLLABLE MYOG) 3218 0xBB1A 묚 (HANGUL SYLLABLE MYOGG) 3219 0xBB1B 묛 (HANGUL SYLLABLE MYOGS) 3220 0xBB1D 묝 (HANGUL SYLLABLE MYONJ) 3221 0xBB1E 묞 (HANGUL SYLLABLE MYONH) 3222 0xBB1F 묟 (HANGUL SYLLABLE MYOD) 3223 0xBB21 묡 (HANGUL SYLLABLE MYOLG) 3224 0xBB22 묢 (HANGUL SYLLABLE MYOLM) 3225 0xBB23 묣 (HANGUL SYLLABLE MYOLB) 3226 0xBB24 묤 (HANGUL SYLLABLE MYOLS) 3227 0xBB25 묥 (HANGUL SYLLABLE MYOLT) 3228 0xBB26 묦 (HANGUL SYLLABLE MYOLP) 3229 0xBB27 묧 (HANGUL SYLLABLE MYOLH) 3230 0xBB28 묨 (HANGUL SYLLABLE MYOM) 3231 0xBB2A 묪 (HANGUL SYLLABLE MYOBS) 3232 0xBB2C 묬 (HANGUL SYLLABLE MYOSS) 3233 0xBB2D 묭 (HANGUL SYLLABLE MYONG) 3234 0xBB2E 묮 (HANGUL SYLLABLE MYOJ) 3235 0xBB2F 묯 (HANGUL SYLLABLE MYOC) 3236 0xBB30 묰 (HANGUL SYLLABLE MYOK) 3237 0xBB31 묱 (HANGUL SYLLABLE MYOT) 3238 0xBB32 묲 (HANGUL SYLLABLE MYOP) 3239 0xBB33 묳 (HANGUL SYLLABLE MYOH) 3240 0xBB37 묷 (HANGUL SYLLABLE MUGS) 3241 0xBB39 묹 (HANGUL SYLLABLE MUNJ) 3242 0xBB3A 묺 (HANGUL SYLLABLE MUNH) 3243 0xBB3F 묿 (HANGUL SYLLABLE MULB) 3244 0xBB40 뭀 (HANGUL SYLLABLE MULS) 3245 0xBB41 뭁 (HANGUL SYLLABLE MULT) 3246 0xBB42 뭂 (HANGUL SYLLABLE MULP) 3247 0xBB43 뭃 (HANGUL SYLLABLE MULH) 3248 0xBB46 뭆 (HANGUL SYLLABLE MUBS) 3249 0xBB48 뭈 (HANGUL SYLLABLE MUSS) 3250 0xBB4A 뭊 (HANGUL SYLLABLE MUJ) 3251 0xBB4B 뭋 (HANGUL SYLLABLE MUC) 3252 0xBB4C 뭌 (HANGUL SYLLABLE MUK) 3253 0xBB4E 뭎 (HANGUL SYLLABLE MUP) 3254 0xBB51 뭑 (HANGUL SYLLABLE MWEOG) 3255 0xBB52 뭒 (HANGUL SYLLABLE MWEOGG) 3262 0xBB53 뭓 (HANGUL SYLLABLE MWEOGS) 3263 0xBB55 뭕 (HANGUL SYLLABLE MWEONJ) 3264 0xBB56 뭖 (HANGUL SYLLABLE MWEONH) 3265 0xBB57 뭗 (HANGUL SYLLABLE MWEOD) 3266 0xBB59 뭙 (HANGUL SYLLABLE MWEOLG) 3267 0xBB5A 뭚 (HANGUL SYLLABLE MWEOLM) 3268 0xBB5B 뭛 (HANGUL SYLLABLE MWEOLB) 3269 0xBB5C 뭜 (HANGUL SYLLABLE MWEOLS) 3270 0xBB5D 뭝 (HANGUL SYLLABLE MWEOLT) 3271 0xBB5E 뭞 (HANGUL SYLLABLE MWEOLP) 3272 0xBB5F 뭟 (HANGUL SYLLABLE MWEOLH) 3273 0xBB60 뭠 (HANGUL SYLLABLE MWEOM) 3274 0xBB62 뭢 (HANGUL SYLLABLE MWEOBS) 3275 0xBB64 뭤 (HANGUL SYLLABLE MWEOSS) 3276 0xBB65 뭥 (HANGUL SYLLABLE MWEONG) 3277 0xBB66 뭦 (HANGUL SYLLABLE MWEOJ) 3278 0xBB67 뭧 (HANGUL SYLLABLE MWEOC) 3279 0xBB68 뭨 (HANGUL SYLLABLE MWEOK) 3280 0xBB69 뭩 (HANGUL SYLLABLE MWEOT) 3281 0xBB6A 뭪 (HANGUL SYLLABLE MWEOP) 3282 0xBB6B 뭫 (HANGUL SYLLABLE MWEOH) 3283 0xBB6D 뭭 (HANGUL SYLLABLE MWEG) 3284 0xBB6E 뭮 (HANGUL SYLLABLE MWEGG) 3285 0xBB6F 뭯 (HANGUL SYLLABLE MWEGS) 3286 0xBB70 뭰 (HANGUL SYLLABLE MWEN) 3287 0xBB71 뭱 (HANGUL SYLLABLE MWENJ) 3294 0xBB72 뭲 (HANGUL SYLLABLE MWENH) 3295 0xBB73 뭳 (HANGUL SYLLABLE MWED) 3296 0xBB74 뭴 (HANGUL SYLLABLE MWEL) 3297 0xBB75 뭵 (HANGUL SYLLABLE MWELG) 3298 0xBB76 뭶 (HANGUL SYLLABLE MWELM) 3299 0xBB77 뭷 (HANGUL SYLLABLE MWELB) 3300 0xBB78 뭸 (HANGUL SYLLABLE MWELS) 3301 0xBB79 뭹 (HANGUL SYLLABLE MWELT) 3302 0xBB7A 뭺 (HANGUL SYLLABLE MWELP) 3303 0xBB7B 뭻 (HANGUL SYLLABLE MWELH) 3304 0xBB7C 뭼 (HANGUL SYLLABLE MWEM) 3305 0xBB7D 뭽 (HANGUL SYLLABLE MWEB) 3306 0xBB7E 뭾 (HANGUL SYLLABLE MWEBS) 3307 0xBB7F 뭿 (HANGUL SYLLABLE MWES) 3308 0xBB80 뮀 (HANGUL SYLLABLE MWESS) 3309 0xBB81 뮁 (HANGUL SYLLABLE MWENG) 3310 0xBB82 뮂 (HANGUL SYLLABLE MWEJ) 3311 0xBB83 뮃 (HANGUL SYLLABLE MWEC) 3312 0xBB84 뮄 (HANGUL SYLLABLE MWEK) 3313 0xBB85 뮅 (HANGUL SYLLABLE MWET) 3314 0xBB86 뮆 (HANGUL SYLLABLE MWEP) 3315 0xBB87 뮇 (HANGUL SYLLABLE MWEH) 3316 0xBB89 뮉 (HANGUL SYLLABLE MWIG) 3317 0xBB8A 뮊 (HANGUL SYLLABLE MWIGG) 3318 0xBB8B 뮋 (HANGUL SYLLABLE MWIGS) 3319 0xBB8D 뮍 (HANGUL SYLLABLE MWINJ) 3320 0xBB8E 뮎 (HANGUL SYLLABLE MWINH) 3321 0xBB8F 뮏 (HANGUL SYLLABLE MWID) 3322 0xBB91 뮑 (HANGUL SYLLABLE MWILG) 3323 0xBB92 뮒 (HANGUL SYLLABLE MWILM) 3324 0xBB93 뮓 (HANGUL SYLLABLE MWILB) 3325 0xBB94 뮔 (HANGUL SYLLABLE MWILS) 3326 0xBB95 뮕 (HANGUL SYLLABLE MWILT) 3327 0xBB96 뮖 (HANGUL SYLLABLE MWILP) 3328 0xBB97 뮗 (HANGUL SYLLABLE MWILH) 3329 0xBB98 뮘 (HANGUL SYLLABLE MWIM) 3330 0xBB99 뮙 (HANGUL SYLLABLE MWIB) 3331 0xBB9A 뮚 (HANGUL SYLLABLE MWIBS) 3332 0xBB9B 뮛 (HANGUL SYLLABLE MWIS) 3333 0xBB9C 뮜 (HANGUL SYLLABLE MWISS) 3334 0xBB9D 뮝 (HANGUL SYLLABLE MWING) 3335 0xBB9E 뮞 (HANGUL SYLLABLE MWIJ) 3336 0xBB9F 뮟 (HANGUL SYLLABLE MWIC) 3337 0xBBA0 뮠 (HANGUL SYLLABLE MWIK) 3338 0xBBA1 뮡 (HANGUL SYLLABLE MWIT) 3339 0xBBA2 뮢 (HANGUL SYLLABLE MWIP) 3340 0xBBA3 뮣 (HANGUL SYLLABLE MWIH) 3341 0xBBA5 뮥 (HANGUL SYLLABLE MYUG) 3342 0xBBA6 뮦 (HANGUL SYLLABLE MYUGG) 3343 0xBBA7 뮧 (HANGUL SYLLABLE MYUGS) 3344 0xBBA9 뮩 (HANGUL SYLLABLE MYUNJ) 3345 0xBBAA 뮪 (HANGUL SYLLABLE MYUNH) 3346 0xBBAB 뮫 (HANGUL SYLLABLE MYUD) 3347 0xBBAD 뮭 (HANGUL SYLLABLE MYULG) 3348 0xBBAE 뮮 (HANGUL SYLLABLE MYULM) 3349 0xBBAF 뮯 (HANGUL SYLLABLE MYULB) 3350 0xBBB0 뮰 (HANGUL SYLLABLE MYULS) 3351 0xBBB1 뮱 (HANGUL SYLLABLE MYULT) 3352 0xBBB2 뮲 (HANGUL SYLLABLE MYULP) 3353 0xBBB3 뮳 (HANGUL SYLLABLE MYULH) 3354 0xBBB5 뮵 (HANGUL SYLLABLE MYUB) 3355 0xBBB6 뮶 (HANGUL SYLLABLE MYUBS) 3356 0xBBB8 뮸 (HANGUL SYLLABLE MYUSS) 3357 0xBBB9 뮹 (HANGUL SYLLABLE MYUNG) 3358 0xBBBA 뮺 (HANGUL SYLLABLE MYUJ) 3359 0xBBBB 뮻 (HANGUL SYLLABLE MYUC) 3360 0xBBBC 뮼 (HANGUL SYLLABLE MYUK) 3361 0xBBBD 뮽 (HANGUL SYLLABLE MYUT) 3362 0xBBBE 뮾 (HANGUL SYLLABLE MYUP) 3363 0xBBBF 뮿 (HANGUL SYLLABLE MYUH) 3364 0xBBC1 믁 (HANGUL SYLLABLE MEUG) 3365 0xBBC2 믂 (HANGUL SYLLABLE MEUGG) 3366 0xBBC3 믃 (HANGUL SYLLABLE MEUGS) 3367 0xBBC5 믅 (HANGUL SYLLABLE MEUNJ) 3368 0xBBC6 믆 (HANGUL SYLLABLE MEUNH) 3369 0xBBC7 믇 (HANGUL SYLLABLE MEUD) 3370 0xBBC9 믉 (HANGUL SYLLABLE MEULG) 3371 0xBBCA 믊 (HANGUL SYLLABLE MEULM) 3372 0xBBCB 믋 (HANGUL SYLLABLE MEULB) 3373 0xBBCC 믌 (HANGUL SYLLABLE MEULS) 3374 0xBBCD 믍 (HANGUL SYLLABLE MEULT) 3375 0xBBCE 믎 (HANGUL SYLLABLE MEULP) 3376 0xBBCF 믏 (HANGUL SYLLABLE MEULH) 3377 0xBBD1 믑 (HANGUL SYLLABLE MEUB) 3378 0xBBD2 믒 (HANGUL SYLLABLE MEUBS) 3379 0xBBD4 믔 (HANGUL SYLLABLE MEUSS) 3380 0xBBD5 믕 (HANGUL SYLLABLE MEUNG) 3381 0xBBD6 믖 (HANGUL SYLLABLE MEUJ) 3382 0xBBD7 믗 (HANGUL SYLLABLE MEUC) 3383 0xBBD8 믘 (HANGUL SYLLABLE MEUK) 3384 0xBBD9 믙 (HANGUL SYLLABLE MEUT) 3385 0xBBDA 믚 (HANGUL SYLLABLE MEUP) 3386 0xBBDB 믛 (HANGUL SYLLABLE MEUH) 3387 0xBBDC 믜 (HANGUL SYLLABLE MYI) 3388 0xBBDD 믝 (HANGUL SYLLABLE MYIG) 3389 0xBBDE 믞 (HANGUL SYLLABLE MYIGG) 3390 0xBBDF 믟 (HANGUL SYLLABLE MYIGS) 3391 0xBBE0 믠 (HANGUL SYLLABLE MYIN) 3392 0xBBE1 믡 (HANGUL SYLLABLE MYINJ) 3393 0xBBE2 믢 (HANGUL SYLLABLE MYINH) 3394 0xBBE3 믣 (HANGUL SYLLABLE MYID) 3395 0xBBE4 믤 (HANGUL SYLLABLE MYIL) 3396 0xBBE5 믥 (HANGUL SYLLABLE MYILG) 3397 0xBBE6 믦 (HANGUL SYLLABLE MYILM) 3398 0xBBE7 믧 (HANGUL SYLLABLE MYILB) 3399 0xBBE8 믨 (HANGUL SYLLABLE MYILS) 3400 0xBBE9 믩 (HANGUL SYLLABLE MYILT) 3401 0xBBEA 믪 (HANGUL SYLLABLE MYILP) 3402 0xBBEB 믫 (HANGUL SYLLABLE MYILH) 3403 0xBBEC 믬 (HANGUL SYLLABLE MYIM) 3404 0xBBED 믭 (HANGUL SYLLABLE MYIB) 3405 0xBBEE 믮 (HANGUL SYLLABLE MYIBS) 3406 0xBBEF 믯 (HANGUL SYLLABLE MYIS) 3407 0xBBF0 믰 (HANGUL SYLLABLE MYISS) 3408 0xBBF1 믱 (HANGUL SYLLABLE MYING) 3409 0xBBF2 믲 (HANGUL SYLLABLE MYIJ) 3410 0xBBF3 믳 (HANGUL SYLLABLE MYIC) 3411 0xBBF4 믴 (HANGUL SYLLABLE MYIK) 3412 0xBBF5 믵 (HANGUL SYLLABLE MYIT) 3413 0xBBF6 믶 (HANGUL SYLLABLE MYIP) 3414 0xBBF7 믷 (HANGUL SYLLABLE MYIH) 3415 0xBBFA 믺 (HANGUL SYLLABLE MIGG) 3416 0xBBFB 믻 (HANGUL SYLLABLE MIGS) 3417 0xBBFD 믽 (HANGUL SYLLABLE MINJ) 3418 0xBBFE 믾 (HANGUL SYLLABLE MINH) 3419 0xBC01 밁 (HANGUL SYLLABLE MILG) 3420 0xBC03 밃 (HANGUL SYLLABLE MILB) 3421 0xBC04 밄 (HANGUL SYLLABLE MILS) 3422 0xBC05 밅 (HANGUL SYLLABLE MILT) 3423 0xBC06 밆 (HANGUL SYLLABLE MILP) 3424 0xBC07 밇 (HANGUL SYLLABLE MILH) 3425 0xBC0A 밊 (HANGUL SYLLABLE MIBS) 3426 0xBC0E 밎 (HANGUL SYLLABLE MIJ) 3427 0xBC10 밐 (HANGUL SYLLABLE MIK) 3428 0xBC12 밒 (HANGUL SYLLABLE MIP) 3429 0xBC13 밓 (HANGUL SYLLABLE MIH) 3430 0xBC19 밙 (HANGUL SYLLABLE BANJ) 3431 0xBC1A 밚 (HANGUL SYLLABLE BANH) 3432 0xBC20 밠 (HANGUL SYLLABLE BALS) 3433 0xBC21 밡 (HANGUL SYLLABLE BALT) 3434 0xBC22 밢 (HANGUL SYLLABLE BALP) 3435 0xBC23 밣 (HANGUL SYLLABLE BALH) 3436 0xBC26 밦 (HANGUL SYLLABLE BABS) 3437 0xBC28 밨 (HANGUL SYLLABLE BASS) 3438 0xBC2A 밪 (HANGUL SYLLABLE BAJ) 3439 0xBC2B 밫 (HANGUL SYLLABLE BAC) 3440 0xBC2C 밬 (HANGUL SYLLABLE BAK) 3441 0xBC2E 밮 (HANGUL SYLLABLE BAP) 3442 0xBC2F 밯 (HANGUL SYLLABLE BAH) 3443 0xBC32 밲 (HANGUL SYLLABLE BAEGG) 3444 0xBC33 밳 (HANGUL SYLLABLE BAEGS) 3445 0xBC35 밵 (HANGUL SYLLABLE BAENJ) 3452 0xBC36 밶 (HANGUL SYLLABLE BAENH) 3453 0xBC37 밷 (HANGUL SYLLABLE BAED) 3454 0xBC39 밹 (HANGUL SYLLABLE BAELG) 3455 0xBC3A 밺 (HANGUL SYLLABLE BAELM) 3456 0xBC3B 밻 (HANGUL SYLLABLE BAELB) 3457 0xBC3C 밼 (HANGUL SYLLABLE BAELS) 3458 0xBC3D 밽 (HANGUL SYLLABLE BAELT) 3459 0xBC3E 밾 (HANGUL SYLLABLE BAELP) 3460 0xBC3F 밿 (HANGUL SYLLABLE BAELH) 3461 0xBC42 뱂 (HANGUL SYLLABLE BAEBS) 3462 0xBC46 뱆 (HANGUL SYLLABLE BAEJ) 3463 0xBC47 뱇 (HANGUL SYLLABLE BAEC) 3464 0xBC48 뱈 (HANGUL SYLLABLE BAEK) 3465 0xBC4A 뱊 (HANGUL SYLLABLE BAEP) 3466 0xBC4B 뱋 (HANGUL SYLLABLE BAEH) 3467 0xBC4E 뱎 (HANGUL SYLLABLE BYAGG) 3468 0xBC4F 뱏 (HANGUL SYLLABLE BYAGS) 3469 0xBC51 뱑 (HANGUL SYLLABLE BYANJ) 3470 0xBC52 뱒 (HANGUL SYLLABLE BYANH) 3471 0xBC53 뱓 (HANGUL SYLLABLE BYAD) 3472 0xBC54 뱔 (HANGUL SYLLABLE BYAL) 3473 0xBC55 뱕 (HANGUL SYLLABLE BYALG) 3474 0xBC56 뱖 (HANGUL SYLLABLE BYALM) 3475 0xBC57 뱗 (HANGUL SYLLABLE BYALB) 3476 0xBC58 뱘 (HANGUL SYLLABLE BYALS) 3477 0xBC59 뱙 (HANGUL SYLLABLE BYALT) 3484 0xBC5A 뱚 (HANGUL SYLLABLE BYALP) 3485 0xBC5B 뱛 (HANGUL SYLLABLE BYALH) 3486 0xBC5C 뱜 (HANGUL SYLLABLE BYAM) 3487 0xBC5E 뱞 (HANGUL SYLLABLE BYABS) 3488 0xBC5F 뱟 (HANGUL SYLLABLE BYAS) 3489 0xBC60 뱠 (HANGUL SYLLABLE BYASS) 3490 0xBC61 뱡 (HANGUL SYLLABLE BYANG) 3491 0xBC62 뱢 (HANGUL SYLLABLE BYAJ) 3492 0xBC63 뱣 (HANGUL SYLLABLE BYAC) 3493 0xBC64 뱤 (HANGUL SYLLABLE BYAK) 3494 0xBC65 뱥 (HANGUL SYLLABLE BYAT) 3495 0xBC66 뱦 (HANGUL SYLLABLE BYAP) 3496 0xBC67 뱧 (HANGUL SYLLABLE BYAH) 3497 0xBC68 뱨 (HANGUL SYLLABLE BYAE) 3498 0xBC69 뱩 (HANGUL SYLLABLE BYAEG) 3499 0xBC6A 뱪 (HANGUL SYLLABLE BYAEGG) 3500 0xBC6B 뱫 (HANGUL SYLLABLE BYAEGS) 3501 0xBC6C 뱬 (HANGUL SYLLABLE BYAEN) 3502 0xBC6D 뱭 (HANGUL SYLLABLE BYAENJ) 3503 0xBC6E 뱮 (HANGUL SYLLABLE BYAENH) 3504 0xBC6F 뱯 (HANGUL SYLLABLE BYAED) 3505 0xBC70 뱰 (HANGUL SYLLABLE BYAEL) 3506 0xBC71 뱱 (HANGUL SYLLABLE BYAELG) 3507 0xBC72 뱲 (HANGUL SYLLABLE BYAELM) 3508 0xBC73 뱳 (HANGUL SYLLABLE BYAELB) 3509 0xBC74 뱴 (HANGUL SYLLABLE BYAELS) 3510 0xBC75 뱵 (HANGUL SYLLABLE BYAELT) 3511 0xBC76 뱶 (HANGUL SYLLABLE BYAELP) 3512 0xBC77 뱷 (HANGUL SYLLABLE BYAELH) 3513 0xBC78 뱸 (HANGUL SYLLABLE BYAEM) 3514 0xBC79 뱹 (HANGUL SYLLABLE BYAEB) 3515 0xBC7A 뱺 (HANGUL SYLLABLE BYAEBS) 3516 0xBC7B 뱻 (HANGUL SYLLABLE BYAES) 3517 0xBC7C 뱼 (HANGUL SYLLABLE BYAESS) 3518 0xBC7D 뱽 (HANGUL SYLLABLE BYAENG) 3519 0xBC7E 뱾 (HANGUL SYLLABLE BYAEJ) 3520 0xBC7F 뱿 (HANGUL SYLLABLE BYAEC) 3521 0xBC80 벀 (HANGUL SYLLABLE BYAEK) 3522 0xBC81 벁 (HANGUL SYLLABLE BYAET) 3523 0xBC82 벂 (HANGUL SYLLABLE BYAEP) 3524 0xBC83 벃 (HANGUL SYLLABLE BYAEH) 3525 0xBC86 벆 (HANGUL SYLLABLE BEOGG) 3526 0xBC87 벇 (HANGUL SYLLABLE BEOGS) 3527 0xBC89 벉 (HANGUL SYLLABLE BEONJ) 3528 0xBC8A 벊 (HANGUL SYLLABLE BEONH) 3529 0xBC8D 벍 (HANGUL SYLLABLE BEOLG) 3530 0xBC8F 벏 (HANGUL SYLLABLE BEOLB) 3531 0xBC90 벐 (HANGUL SYLLABLE BEOLS) 3532 0xBC91 벑 (HANGUL SYLLABLE BEOLT) 3533 0xBC92 벒 (HANGUL SYLLABLE BEOLP) 3534 0xBC93 벓 (HANGUL SYLLABLE BEOLH) 3535 0xBC96 벖 (HANGUL SYLLABLE BEOBS) 3536 0xBC98 벘 (HANGUL SYLLABLE BEOSS) 3537 0xBC9B 벛 (HANGUL SYLLABLE BEOC) 3538 0xBC9C 벜 (HANGUL SYLLABLE BEOK) 3539 0xBC9D 벝 (HANGUL SYLLABLE BEOT) 3540 0xBC9E 벞 (HANGUL SYLLABLE BEOP) 3541 0xBC9F 벟 (HANGUL SYLLABLE BEOH) 3542 0xBCA2 벢 (HANGUL SYLLABLE BEGG) 3543 0xBCA3 벣 (HANGUL SYLLABLE BEGS) 3544 0xBCA5 벥 (HANGUL SYLLABLE BENJ) 3545 0xBCA6 벦 (HANGUL SYLLABLE BENH) 3546 0xBCA9 벩 (HANGUL SYLLABLE BELG) 3547 0xBCAA 벪 (HANGUL SYLLABLE BELM) 3548 0xBCAB 벫 (HANGUL SYLLABLE BELB) 3549 0xBCAC 벬 (HANGUL SYLLABLE BELS) 3550 0xBCAD 벭 (HANGUL SYLLABLE BELT) 3551 0xBCAE 벮 (HANGUL SYLLABLE BELP) 3552 0xBCAF 벯 (HANGUL SYLLABLE BELH) 3553 0xBCB2 벲 (HANGUL SYLLABLE BEBS) 3554 0xBCB6 벶 (HANGUL SYLLABLE BEJ) 3555 0xBCB7 벷 (HANGUL SYLLABLE BEC) 3556 0xBCB8 벸 (HANGUL SYLLABLE BEK) 3557 0xBCB9 벹 (HANGUL SYLLABLE BET) 3558 0xBCBA 벺 (HANGUL SYLLABLE BEP) 3559 0xBCBB 벻 (HANGUL SYLLABLE BEH) 3560 0xBCBE 벾 (HANGUL SYLLABLE BYEOGG) 3561 0xBCBF 벿 (HANGUL SYLLABLE BYEOGS) 3562 0xBCC1 볁 (HANGUL SYLLABLE BYEONJ) 3563 0xBCC2 볂 (HANGUL SYLLABLE BYEONH) 3564 0xBCC3 볃 (HANGUL SYLLABLE BYEOD) 3565 0xBCC5 볅 (HANGUL SYLLABLE BYEOLG) 3566 0xBCC6 볆 (HANGUL SYLLABLE BYEOLM) 3567 0xBCC7 볇 (HANGUL SYLLABLE BYEOLB) 3568 0xBCC8 볈 (HANGUL SYLLABLE BYEOLS) 3569 0xBCC9 볉 (HANGUL SYLLABLE BYEOLT) 3570 0xBCCA 볊 (HANGUL SYLLABLE BYEOLP) 3571 0xBCCB 볋 (HANGUL SYLLABLE BYEOLH) 3572 0xBCCC 볌 (HANGUL SYLLABLE BYEOM) 3573 0xBCCE 볎 (HANGUL SYLLABLE BYEOBS) 3574 0xBCD2 볒 (HANGUL SYLLABLE BYEOJ) 3575 0xBCD3 볓 (HANGUL SYLLABLE BYEOC) 3576 0xBCD4 볔 (HANGUL SYLLABLE BYEOK) 3577 0xBCD6 볖 (HANGUL SYLLABLE BYEOP) 3578 0xBCD7 볗 (HANGUL SYLLABLE BYEOH) 3579 0xBCD9 볙 (HANGUL SYLLABLE BYEG) 3580 0xBCDA 볚 (HANGUL SYLLABLE BYEGG) 3581 0xBCDB 볛 (HANGUL SYLLABLE BYEGS) 3582 0xBCDD 볝 (HANGUL SYLLABLE BYENJ) 3583 0xBCDE 볞 (HANGUL SYLLABLE BYENH) 3584 0xBCDF 볟 (HANGUL SYLLABLE BYED) 3585 0xBCE0 볠 (HANGUL SYLLABLE BYEL) 3586 0xBCE1 볡 (HANGUL SYLLABLE BYELG) 3587 0xBCE2 볢 (HANGUL SYLLABLE BYELM) 3588 0xBCE3 볣 (HANGUL SYLLABLE BYELB) 3589 0xBCE4 볤 (HANGUL SYLLABLE BYELS) 3590 0xBCE5 볥 (HANGUL SYLLABLE BYELT) 3591 0xBCE6 볦 (HANGUL SYLLABLE BYELP) 3592 0xBCE7 볧 (HANGUL SYLLABLE BYELH) 3593 0xBCE8 볨 (HANGUL SYLLABLE BYEM) 3594 0xBCE9 볩 (HANGUL SYLLABLE BYEB) 3595 0xBCEA 볪 (HANGUL SYLLABLE BYEBS) 3596 0xBCEB 볫 (HANGUL SYLLABLE BYES) 3597 0xBCEC 볬 (HANGUL SYLLABLE BYESS) 3598 0xBCED 볭 (HANGUL SYLLABLE BYENG) 3599 0xBCEE 볮 (HANGUL SYLLABLE BYEJ) 3600 0xBCEF 볯 (HANGUL SYLLABLE BYEC) 3601 0xBCF0 볰 (HANGUL SYLLABLE BYEK) 3602 0xBCF1 볱 (HANGUL SYLLABLE BYET) 3603 0xBCF2 볲 (HANGUL SYLLABLE BYEP) 3604 0xBCF3 볳 (HANGUL SYLLABLE BYEH) 3605 0xBCF7 볷 (HANGUL SYLLABLE BOGS) 3606 0xBCF9 볹 (HANGUL SYLLABLE BONJ) 3607 0xBCFA 볺 (HANGUL SYLLABLE BONH) 3608 0xBCFB 볻 (HANGUL SYLLABLE BOD) 3609 0xBCFD 볽 (HANGUL SYLLABLE BOLG) 3610 0xBCFE 볾 (HANGUL SYLLABLE BOLM) 3611 0xBCFF 볿 (HANGUL SYLLABLE BOLB) 3612 0xBD00 봀 (HANGUL SYLLABLE BOLS) 3613 0xBD01 봁 (HANGUL SYLLABLE BOLT) 3614 0xBD02 봂 (HANGUL SYLLABLE BOLP) 3615 0xBD03 봃 (HANGUL SYLLABLE BOLH) 3616 0xBD06 봆 (HANGUL SYLLABLE BOBS) 3617 0xBD08 봈 (HANGUL SYLLABLE BOSS) 3618 0xBD0A 봊 (HANGUL SYLLABLE BOJ) 3619 0xBD0B 봋 (HANGUL SYLLABLE BOC) 3620 0xBD0C 봌 (HANGUL SYLLABLE BOK) 3621 0xBD0D 봍 (HANGUL SYLLABLE BOT) 3622 0xBD0E 봎 (HANGUL SYLLABLE BOP) 3623 0xBD0F 봏 (HANGUL SYLLABLE BOH) 3624 0xBD11 봑 (HANGUL SYLLABLE BWAG) 3625 0xBD12 봒 (HANGUL SYLLABLE BWAGG) 3626 0xBD13 봓 (HANGUL SYLLABLE BWAGS) 3627 0xBD15 봕 (HANGUL SYLLABLE BWANJ) 3628 0xBD16 봖 (HANGUL SYLLABLE BWANH) 3629 0xBD17 봗 (HANGUL SYLLABLE BWAD) 3630 0xBD18 봘 (HANGUL SYLLABLE BWAL) 3631 0xBD19 봙 (HANGUL SYLLABLE BWALG) 3632 0xBD1A 봚 (HANGUL SYLLABLE BWALM) 3633 0xBD1B 봛 (HANGUL SYLLABLE BWALB) 3634 0xBD1C 봜 (HANGUL SYLLABLE BWALS) 3635 0xBD1D 봝 (HANGUL SYLLABLE BWALT) 3642 0xBD1E 봞 (HANGUL SYLLABLE BWALP) 3643 0xBD1F 봟 (HANGUL SYLLABLE BWALH) 3644 0xBD20 봠 (HANGUL SYLLABLE BWAM) 3645 0xBD21 봡 (HANGUL SYLLABLE BWAB) 3646 0xBD22 봢 (HANGUL SYLLABLE BWABS) 3647 0xBD23 봣 (HANGUL SYLLABLE BWAS) 3648 0xBD25 봥 (HANGUL SYLLABLE BWANG) 3649 0xBD26 봦 (HANGUL SYLLABLE BWAJ) 3650 0xBD27 봧 (HANGUL SYLLABLE BWAC) 3651 0xBD28 봨 (HANGUL SYLLABLE BWAK) 3652 0xBD29 봩 (HANGUL SYLLABLE BWAT) 3653 0xBD2A 봪 (HANGUL SYLLABLE BWAP) 3654 0xBD2B 봫 (HANGUL SYLLABLE BWAH) 3655 0xBD2D 봭 (HANGUL SYLLABLE BWAEG) 3656 0xBD2E 봮 (HANGUL SYLLABLE BWAEGG) 3657 0xBD2F 봯 (HANGUL SYLLABLE BWAEGS) 3658 0xBD30 봰 (HANGUL SYLLABLE BWAEN) 3659 0xBD31 봱 (HANGUL SYLLABLE BWAENJ) 3660 0xBD32 봲 (HANGUL SYLLABLE BWAENH) 3661 0xBD33 봳 (HANGUL SYLLABLE BWAED) 3662 0xBD34 봴 (HANGUL SYLLABLE BWAEL) 3663 0xBD35 봵 (HANGUL SYLLABLE BWAELG) 3664 0xBD36 봶 (HANGUL SYLLABLE BWAELM) 3665 0xBD37 봷 (HANGUL SYLLABLE BWAELB) 3666 0xBD38 봸 (HANGUL SYLLABLE BWAELS) 3667 0xBD39 봹 (HANGUL SYLLABLE BWAELT) 3674 0xBD3A 봺 (HANGUL SYLLABLE BWAELP) 3675 0xBD3B 봻 (HANGUL SYLLABLE BWAELH) 3676 0xBD3C 봼 (HANGUL SYLLABLE BWAEM) 3677 0xBD3D 봽 (HANGUL SYLLABLE BWAEB) 3678 0xBD3E 봾 (HANGUL SYLLABLE BWAEBS) 3679 0xBD3F 봿 (HANGUL SYLLABLE BWAES) 3680 0xBD41 뵁 (HANGUL SYLLABLE BWAENG) 3681 0xBD42 뵂 (HANGUL SYLLABLE BWAEJ) 3682 0xBD43 뵃 (HANGUL SYLLABLE BWAEC) 3683 0xBD44 뵄 (HANGUL SYLLABLE BWAEK) 3684 0xBD45 뵅 (HANGUL SYLLABLE BWAET) 3685 0xBD46 뵆 (HANGUL SYLLABLE BWAEP) 3686 0xBD47 뵇 (HANGUL SYLLABLE BWAEH) 3687 0xBD4A 뵊 (HANGUL SYLLABLE BOEGG) 3688 0xBD4B 뵋 (HANGUL SYLLABLE BOEGS) 3689 0xBD4D 뵍 (HANGUL SYLLABLE BOENJ) 3690 0xBD4E 뵎 (HANGUL SYLLABLE BOENH) 3691 0xBD4F 뵏 (HANGUL SYLLABLE BOED) 3692 0xBD51 뵑 (HANGUL SYLLABLE BOELG) 3693 0xBD52 뵒 (HANGUL SYLLABLE BOELM) 3694 0xBD53 뵓 (HANGUL SYLLABLE BOELB) 3695 0xBD54 뵔 (HANGUL SYLLABLE BOELS) 3696 0xBD55 뵕 (HANGUL SYLLABLE BOELT) 3697 0xBD56 뵖 (HANGUL SYLLABLE BOELP) 3698 0xBD57 뵗 (HANGUL SYLLABLE BOELH) 3699 0xBD5A 뵚 (HANGUL SYLLABLE BOEBS) 3700 0xBD5B 뵛 (HANGUL SYLLABLE BOES) 3701 0xBD5C 뵜 (HANGUL SYLLABLE BOESS) 3702 0xBD5D 뵝 (HANGUL SYLLABLE BOENG) 3703 0xBD5E 뵞 (HANGUL SYLLABLE BOEJ) 3704 0xBD5F 뵟 (HANGUL SYLLABLE BOEC) 3705 0xBD60 뵠 (HANGUL SYLLABLE BOEK) 3706 0xBD61 뵡 (HANGUL SYLLABLE BOET) 3707 0xBD62 뵢 (HANGUL SYLLABLE BOEP) 3708 0xBD63 뵣 (HANGUL SYLLABLE BOEH) 3709 0xBD65 뵥 (HANGUL SYLLABLE BYOG) 3710 0xBD66 뵦 (HANGUL SYLLABLE BYOGG) 3711 0xBD67 뵧 (HANGUL SYLLABLE BYOGS) 3712 0xBD69 뵩 (HANGUL SYLLABLE BYONJ) 3713 0xBD6A 뵪 (HANGUL SYLLABLE BYONH) 3714 0xBD6B 뵫 (HANGUL SYLLABLE BYOD) 3715 0xBD6C 뵬 (HANGUL SYLLABLE BYOL) 3716 0xBD6D 뵭 (HANGUL SYLLABLE BYOLG) 3717 0xBD6E 뵮 (HANGUL SYLLABLE BYOLM) 3718 0xBD6F 뵯 (HANGUL SYLLABLE BYOLB) 3719 0xBD70 뵰 (HANGUL SYLLABLE BYOLS) 3720 0xBD71 뵱 (HANGUL SYLLABLE BYOLT) 3721 0xBD72 뵲 (HANGUL SYLLABLE BYOLP) 3722 0xBD73 뵳 (HANGUL SYLLABLE BYOLH) 3723 0xBD74 뵴 (HANGUL SYLLABLE BYOM) 3724 0xBD75 뵵 (HANGUL SYLLABLE BYOB) 3725 0xBD76 뵶 (HANGUL SYLLABLE BYOBS) 3726 0xBD77 뵷 (HANGUL SYLLABLE BYOS) 3727 0xBD78 뵸 (HANGUL SYLLABLE BYOSS) 3728 0xBD79 뵹 (HANGUL SYLLABLE BYONG) 3729 0xBD7A 뵺 (HANGUL SYLLABLE BYOJ) 3730 0xBD7B 뵻 (HANGUL SYLLABLE BYOC) 3731 0xBD7C 뵼 (HANGUL SYLLABLE BYOK) 3732 0xBD7D 뵽 (HANGUL SYLLABLE BYOT) 3733 0xBD7E 뵾 (HANGUL SYLLABLE BYOP) 3734 0xBD7F 뵿 (HANGUL SYLLABLE BYOH) 3735 0xBD82 붂 (HANGUL SYLLABLE BUGG) 3736 0xBD83 붃 (HANGUL SYLLABLE BUGS) 3737 0xBD85 붅 (HANGUL SYLLABLE BUNJ) 3738 0xBD86 붆 (HANGUL SYLLABLE BUNH) 3739 0xBD8B 붋 (HANGUL SYLLABLE BULB) 3740 0xBD8C 붌 (HANGUL SYLLABLE BULS) 3741 0xBD8D 붍 (HANGUL SYLLABLE BULT) 3742 0xBD8E 붎 (HANGUL SYLLABLE BULP) 3743 0xBD8F 붏 (HANGUL SYLLABLE BULH) 3744 0xBD92 붒 (HANGUL SYLLABLE BUBS) 3745 0xBD94 붔 (HANGUL SYLLABLE BUSS) 3746 0xBD96 붖 (HANGUL SYLLABLE BUJ) 3747 0xBD97 붗 (HANGUL SYLLABLE BUC) 3748 0xBD98 붘 (HANGUL SYLLABLE BUK) 3749 0xBD9B 붛 (HANGUL SYLLABLE BUH) 3750 0xBD9D 붝 (HANGUL SYLLABLE BWEOG) 3751 0xBD9E 붞 (HANGUL SYLLABLE BWEOGG) 3752 0xBD9F 붟 (HANGUL SYLLABLE BWEOGS) 3753 0xBDA0 붠 (HANGUL SYLLABLE BWEON) 3754 0xBDA1 붡 (HANGUL SYLLABLE BWEONJ) 3755 0xBDA2 붢 (HANGUL SYLLABLE BWEONH) 3756 0xBDA3 붣 (HANGUL SYLLABLE BWEOD) 3757 0xBDA5 붥 (HANGUL SYLLABLE BWEOLG) 3758 0xBDA6 붦 (HANGUL SYLLABLE BWEOLM) 3759 0xBDA7 붧 (HANGUL SYLLABLE BWEOLB) 3760 0xBDA8 붨 (HANGUL SYLLABLE BWEOLS) 3761 0xBDA9 붩 (HANGUL SYLLABLE BWEOLT) 3762 0xBDAA 붪 (HANGUL SYLLABLE BWEOLP) 3763 0xBDAB 붫 (HANGUL SYLLABLE BWEOLH) 3764 0xBDAC 붬 (HANGUL SYLLABLE BWEOM) 3765 0xBDAD 붭 (HANGUL SYLLABLE BWEOB) 3766 0xBDAE 붮 (HANGUL SYLLABLE BWEOBS) 3767 0xBDAF 붯 (HANGUL SYLLABLE BWEOS) 3768 0xBDB1 붱 (HANGUL SYLLABLE BWEONG) 3769 0xBDB2 붲 (HANGUL SYLLABLE BWEOJ) 3770 0xBDB3 붳 (HANGUL SYLLABLE BWEOC) 3771 0xBDB4 붴 (HANGUL SYLLABLE BWEOK) 3772 0xBDB5 붵 (HANGUL SYLLABLE BWEOT) 3773 0xBDB6 붶 (HANGUL SYLLABLE BWEOP) 3774 0xBDB7 붷 (HANGUL SYLLABLE BWEOH) 3775 0xBDB9 붹 (HANGUL SYLLABLE BWEG) 3776 0xBDBA 붺 (HANGUL SYLLABLE BWEGG) 3777 0xBDBB 붻 (HANGUL SYLLABLE BWEGS) 3778 0xBDBC 붼 (HANGUL SYLLABLE BWEN) 3779 0xBDBD 붽 (HANGUL SYLLABLE BWENJ) 3780 0xBDBE 붾 (HANGUL SYLLABLE BWENH) 3781 0xBDBF 붿 (HANGUL SYLLABLE BWED) 3782 0xBDC0 뷀 (HANGUL SYLLABLE BWEL) 3783 0xBDC1 뷁 (HANGUL SYLLABLE BWELG) 3784 0xBDC2 뷂 (HANGUL SYLLABLE BWELM) 3785 0xBDC3 뷃 (HANGUL SYLLABLE BWELB) 3786 0xBDC4 뷄 (HANGUL SYLLABLE BWELS) 3787 0xBDC5 뷅 (HANGUL SYLLABLE BWELT) 3788 0xBDC6 뷆 (HANGUL SYLLABLE BWELP) 3789 0xBDC7 뷇 (HANGUL SYLLABLE BWELH) 3790 0xBDC8 뷈 (HANGUL SYLLABLE BWEM) 3791 0xBDC9 뷉 (HANGUL SYLLABLE BWEB) 3792 0xBDCA 뷊 (HANGUL SYLLABLE BWEBS) 3793 0xBDCB 뷋 (HANGUL SYLLABLE BWES) 3794 0xBDCC 뷌 (HANGUL SYLLABLE BWESS) 3795 0xBDCD 뷍 (HANGUL SYLLABLE BWENG) 3796 0xBDCE 뷎 (HANGUL SYLLABLE BWEJ) 3797 0xBDCF 뷏 (HANGUL SYLLABLE BWEC) 3798 0xBDD0 뷐 (HANGUL SYLLABLE BWEK) 3799 0xBDD1 뷑 (HANGUL SYLLABLE BWET) 3800 0xBDD2 뷒 (HANGUL SYLLABLE BWEP) 3801 0xBDD3 뷓 (HANGUL SYLLABLE BWEH) 3802 0xBDD6 뷖 (HANGUL SYLLABLE BWIGG) 3803 0xBDD7 뷗 (HANGUL SYLLABLE BWIGS) 3804 0xBDD9 뷙 (HANGUL SYLLABLE BWINJ) 3805 0xBDDA 뷚 (HANGUL SYLLABLE BWINH) 3806 0xBDDB 뷛 (HANGUL SYLLABLE BWID) 3807 0xBDDD 뷝 (HANGUL SYLLABLE BWILG) 3808 0xBDDE 뷞 (HANGUL SYLLABLE BWILM) 3809 0xBDDF 뷟 (HANGUL SYLLABLE BWILB) 3810 0xBDE0 뷠 (HANGUL SYLLABLE BWILS) 3811 0xBDE1 뷡 (HANGUL SYLLABLE BWILT) 3812 0xBDE2 뷢 (HANGUL SYLLABLE BWILP) 3813 0xBDE3 뷣 (HANGUL SYLLABLE BWILH) 3814 0xBDE4 뷤 (HANGUL SYLLABLE BWIM) 3815 0xBDE5 뷥 (HANGUL SYLLABLE BWIB) 3816 0xBDE6 뷦 (HANGUL SYLLABLE BWIBS) 3817 0xBDE7 뷧 (HANGUL SYLLABLE BWIS) 3818 0xBDE8 뷨 (HANGUL SYLLABLE BWISS) 3819 0xBDEA 뷪 (HANGUL SYLLABLE BWIJ) 3820 0xBDEB 뷫 (HANGUL SYLLABLE BWIC) 3821 0xBDEC 뷬 (HANGUL SYLLABLE BWIK) 3822 0xBDED 뷭 (HANGUL SYLLABLE BWIT) 3823 0xBDEE 뷮 (HANGUL SYLLABLE BWIP) 3824 0xBDEF 뷯 (HANGUL SYLLABLE BWIH) 3825 0xBDF1 뷱 (HANGUL SYLLABLE BYUG) 3832 0xBDF2 뷲 (HANGUL SYLLABLE BYUGG) 3833 0xBDF3 뷳 (HANGUL SYLLABLE BYUGS) 3834 0xBDF5 뷵 (HANGUL SYLLABLE BYUNJ) 3835 0xBDF6 뷶 (HANGUL SYLLABLE BYUNH) 3836 0xBDF7 뷷 (HANGUL SYLLABLE BYUD) 3837 0xBDF9 뷹 (HANGUL SYLLABLE BYULG) 3838 0xBDFA 뷺 (HANGUL SYLLABLE BYULM) 3839 0xBDFB 뷻 (HANGUL SYLLABLE BYULB) 3840 0xBDFC 뷼 (HANGUL SYLLABLE BYULS) 3841 0xBDFD 뷽 (HANGUL SYLLABLE BYULT) 3842 0xBDFE 뷾 (HANGUL SYLLABLE BYULP) 3843 0xBDFF 뷿 (HANGUL SYLLABLE BYULH) 3844 0xBE01 븁 (HANGUL SYLLABLE BYUB) 3845 0xBE02 븂 (HANGUL SYLLABLE BYUBS) 3846 0xBE04 븄 (HANGUL SYLLABLE BYUSS) 3847 0xBE06 븆 (HANGUL SYLLABLE BYUJ) 3848 0xBE07 븇 (HANGUL SYLLABLE BYUC) 3849 0xBE08 븈 (HANGUL SYLLABLE BYUK) 3850 0xBE09 븉 (HANGUL SYLLABLE BYUT) 3851 0xBE0A 븊 (HANGUL SYLLABLE BYUP) 3852 0xBE0B 븋 (HANGUL SYLLABLE BYUH) 3853 0xBE0E 븎 (HANGUL SYLLABLE BEUGG) 3854 0xBE0F 븏 (HANGUL SYLLABLE BEUGS) 3855 0xBE11 븑 (HANGUL SYLLABLE BEUNJ) 3856 0xBE12 븒 (HANGUL SYLLABLE BEUNH) 3857 0xBE13 븓 (HANGUL SYLLABLE BEUD) 3864 0xBE15 븕 (HANGUL SYLLABLE BEULG) 3865 0xBE16 븖 (HANGUL SYLLABLE BEULM) 3866 0xBE17 븗 (HANGUL SYLLABLE BEULB) 3867 0xBE18 븘 (HANGUL SYLLABLE BEULS) 3868 0xBE19 븙 (HANGUL SYLLABLE BEULT) 3869 0xBE1A 븚 (HANGUL SYLLABLE BEULP) 3870 0xBE1B 븛 (HANGUL SYLLABLE BEULH) 3871 0xBE1E 븞 (HANGUL SYLLABLE BEUBS) 3872 0xBE20 븠 (HANGUL SYLLABLE BEUSS) 3873 0xBE21 븡 (HANGUL SYLLABLE BEUNG) 3874 0xBE22 븢 (HANGUL SYLLABLE BEUJ) 3875 0xBE23 븣 (HANGUL SYLLABLE BEUC) 3876 0xBE24 븤 (HANGUL SYLLABLE BEUK) 3877 0xBE25 븥 (HANGUL SYLLABLE BEUT) 3878 0xBE26 븦 (HANGUL SYLLABLE BEUP) 3879 0xBE27 븧 (HANGUL SYLLABLE BEUH) 3880 0xBE28 븨 (HANGUL SYLLABLE BYI) 3881 0xBE29 븩 (HANGUL SYLLABLE BYIG) 3882 0xBE2A 븪 (HANGUL SYLLABLE BYIGG) 3883 0xBE2B 븫 (HANGUL SYLLABLE BYIGS) 3884 0xBE2C 븬 (HANGUL SYLLABLE BYIN) 3885 0xBE2D 븭 (HANGUL SYLLABLE BYINJ) 3886 0xBE2E 븮 (HANGUL SYLLABLE BYINH) 3887 0xBE2F 븯 (HANGUL SYLLABLE BYID) 3888 0xBE30 븰 (HANGUL SYLLABLE BYIL) 3889 0xBE31 븱 (HANGUL SYLLABLE BYILG) 3890 0xBE32 븲 (HANGUL SYLLABLE BYILM) 3891 0xBE33 븳 (HANGUL SYLLABLE BYILB) 3892 0xBE34 븴 (HANGUL SYLLABLE BYILS) 3893 0xBE35 븵 (HANGUL SYLLABLE BYILT) 3894 0xBE36 븶 (HANGUL SYLLABLE BYILP) 3895 0xBE37 븷 (HANGUL SYLLABLE BYILH) 3896 0xBE38 븸 (HANGUL SYLLABLE BYIM) 3897 0xBE39 븹 (HANGUL SYLLABLE BYIB) 3898 0xBE3A 븺 (HANGUL SYLLABLE BYIBS) 3899 0xBE3B 븻 (HANGUL SYLLABLE BYIS) 3900 0xBE3C 븼 (HANGUL SYLLABLE BYISS) 3901 0xBE3D 븽 (HANGUL SYLLABLE BYING) 3902 0xBE3E 븾 (HANGUL SYLLABLE BYIJ) 3903 0xBE3F 븿 (HANGUL SYLLABLE BYIC) 3904 0xBE40 빀 (HANGUL SYLLABLE BYIK) 3905 0xBE41 빁 (HANGUL SYLLABLE BYIT) 3906 0xBE42 빂 (HANGUL SYLLABLE BYIP) 3907 0xBE43 빃 (HANGUL SYLLABLE BYIH) 3908 0xBE46 빆 (HANGUL SYLLABLE BIGG) 3909 0xBE47 빇 (HANGUL SYLLABLE BIGS) 3910 0xBE49 빉 (HANGUL SYLLABLE BINJ) 3911 0xBE4A 빊 (HANGUL SYLLABLE BINH) 3912 0xBE4B 빋 (HANGUL SYLLABLE BID) 3913 0xBE4D 빍 (HANGUL SYLLABLE BILG) 3914 0xBE4F 빏 (HANGUL SYLLABLE BILB) 3915 0xBE50 빐 (HANGUL SYLLABLE BILS) 3916 0xBE51 빑 (HANGUL SYLLABLE BILT) 3917 0xBE52 빒 (HANGUL SYLLABLE BILP) 3918 0xBE53 빓 (HANGUL SYLLABLE BILH) 3919 0xBE56 빖 (HANGUL SYLLABLE BIBS) 3920 0xBE58 빘 (HANGUL SYLLABLE BISS) 3921 0xBE5C 빜 (HANGUL SYLLABLE BIK) 3922 0xBE5D 빝 (HANGUL SYLLABLE BIT) 3923 0xBE5E 빞 (HANGUL SYLLABLE BIP) 3924 0xBE5F 빟 (HANGUL SYLLABLE BIH) 3925 0xBE62 빢 (HANGUL SYLLABLE BBAGG) 3926 0xBE63 빣 (HANGUL SYLLABLE BBAGS) 3927 0xBE65 빥 (HANGUL SYLLABLE BBANJ) 3928 0xBE66 빦 (HANGUL SYLLABLE BBANH) 3929 0xBE67 빧 (HANGUL SYLLABLE BBAD) 3930 0xBE69 빩 (HANGUL SYLLABLE BBALG) 3931 0xBE6B 빫 (HANGUL SYLLABLE BBALB) 3932 0xBE6C 빬 (HANGUL SYLLABLE BBALS) 3933 0xBE6D 빭 (HANGUL SYLLABLE BBALT) 3934 0xBE6E 빮 (HANGUL SYLLABLE BBALP) 3935 0xBE6F 빯 (HANGUL SYLLABLE BBALH) 3936 0xBE72 빲 (HANGUL SYLLABLE BBABS) 3937 0xBE76 빶 (HANGUL SYLLABLE BBAJ) 3938 0xBE77 빷 (HANGUL SYLLABLE BBAC) 3939 0xBE78 빸 (HANGUL SYLLABLE BBAK) 3940 0xBE79 빹 (HANGUL SYLLABLE BBAT) 3941 0xBE7A 빺 (HANGUL SYLLABLE BBAP) 3942 0xBE7E 빾 (HANGUL SYLLABLE BBAEGG) 3943 0xBE7F 빿 (HANGUL SYLLABLE BBAEGS) 3944 0xBE81 뺁 (HANGUL SYLLABLE BBAENJ) 3945 0xBE82 뺂 (HANGUL SYLLABLE BBAENH) 3946 0xBE83 뺃 (HANGUL SYLLABLE BBAED) 3947 0xBE85 뺅 (HANGUL SYLLABLE BBAELG) 3948 0xBE86 뺆 (HANGUL SYLLABLE BBAELM) 3949 0xBE87 뺇 (HANGUL SYLLABLE BBAELB) 3950 0xBE88 뺈 (HANGUL SYLLABLE BBAELS) 3951 0xBE89 뺉 (HANGUL SYLLABLE BBAELT) 3952 0xBE8A 뺊 (HANGUL SYLLABLE BBAELP) 3953 0xBE8B 뺋 (HANGUL SYLLABLE BBAELH) 3954 0xBE8E 뺎 (HANGUL SYLLABLE BBAEBS) 3955 0xBE92 뺒 (HANGUL SYLLABLE BBAEJ) 3956 0xBE93 뺓 (HANGUL SYLLABLE BBAEC) 3957 0xBE94 뺔 (HANGUL SYLLABLE BBAEK) 3958 0xBE95 뺕 (HANGUL SYLLABLE BBAET) 3959 0xBE96 뺖 (HANGUL SYLLABLE BBAEP) 3960 0xBE97 뺗 (HANGUL SYLLABLE BBAEH) 3961 0xBE9A 뺚 (HANGUL SYLLABLE BBYAGG) 3962 0xBE9B 뺛 (HANGUL SYLLABLE BBYAGS) 3963 0xBE9C 뺜 (HANGUL SYLLABLE BBYAN) 3964 0xBE9D 뺝 (HANGUL SYLLABLE BBYANJ) 3965 0xBE9E 뺞 (HANGUL SYLLABLE BBYANH) 3966 0xBE9F 뺟 (HANGUL SYLLABLE BBYAD) 3967 0xBEA0 뺠 (HANGUL SYLLABLE BBYAL) 3968 0xBEA1 뺡 (HANGUL SYLLABLE BBYALG) 3969 0xBEA2 뺢 (HANGUL SYLLABLE BBYALM) 3970 0xBEA3 뺣 (HANGUL SYLLABLE BBYALB) 3971 0xBEA4 뺤 (HANGUL SYLLABLE BBYALS) 3972 0xBEA5 뺥 (HANGUL SYLLABLE BBYALT) 3973 0xBEA6 뺦 (HANGUL SYLLABLE BBYALP) 3974 0xBEA7 뺧 (HANGUL SYLLABLE BBYALH) 3975 0xBEA9 뺩 (HANGUL SYLLABLE BBYAB) 3976 0xBEAA 뺪 (HANGUL SYLLABLE BBYABS) 3977 0xBEAB 뺫 (HANGUL SYLLABLE BBYAS) 3978 0xBEAC 뺬 (HANGUL SYLLABLE BBYASS) 3979 0xBEAD 뺭 (HANGUL SYLLABLE BBYANG) 3980 0xBEAE 뺮 (HANGUL SYLLABLE BBYAJ) 3981 0xBEAF 뺯 (HANGUL SYLLABLE BBYAC) 3982 0xBEB0 뺰 (HANGUL SYLLABLE BBYAK) 3983 0xBEB1 뺱 (HANGUL SYLLABLE BBYAT) 3984 0xBEB2 뺲 (HANGUL SYLLABLE BBYAP) 3985 0xBEB3 뺳 (HANGUL SYLLABLE BBYAH) 3986 0xBEB4 뺴 (HANGUL SYLLABLE BBYAE) 3987 0xBEB5 뺵 (HANGUL SYLLABLE BBYAEG) 3988 0xBEB6 뺶 (HANGUL SYLLABLE BBYAEGG) 3989 0xBEB7 뺷 (HANGUL SYLLABLE BBYAEGS) 3990 0xBEB8 뺸 (HANGUL SYLLABLE BBYAEN) 3991 0xBEB9 뺹 (HANGUL SYLLABLE BBYAENJ) 3992 0xBEBA 뺺 (HANGUL SYLLABLE BBYAENH) 3993 0xBEBB 뺻 (HANGUL SYLLABLE BBYAED) 3994 0xBEBC 뺼 (HANGUL SYLLABLE BBYAEL) 3995 0xBEBD 뺽 (HANGUL SYLLABLE BBYAELG) 3996 0xBEBE 뺾 (HANGUL SYLLABLE BBYAELM) 3997 0xBEBF 뺿 (HANGUL SYLLABLE BBYAELB) 3998 0xBEC0 뻀 (HANGUL SYLLABLE BBYAELS) 3999 0xBEC1 뻁 (HANGUL SYLLABLE BBYAELT) 4000 0xBEC2 뻂 (HANGUL SYLLABLE BBYAELP) 4001 0xBEC3 뻃 (HANGUL SYLLABLE BBYAELH) 4002 0xBEC4 뻄 (HANGUL SYLLABLE BBYAEM) 4003 0xBEC5 뻅 (HANGUL SYLLABLE BBYAEB) 4004 0xBEC6 뻆 (HANGUL SYLLABLE BBYAEBS) 4005 0xBEC7 뻇 (HANGUL SYLLABLE BBYAES) 4006 0xBEC8 뻈 (HANGUL SYLLABLE BBYAESS) 4007 0xBEC9 뻉 (HANGUL SYLLABLE BBYAENG) 4008 0xBECA 뻊 (HANGUL SYLLABLE BBYAEJ) 4009 0xBECB 뻋 (HANGUL SYLLABLE BBYAEC) 4010 0xBECC 뻌 (HANGUL SYLLABLE BBYAEK) 4011 0xBECD 뻍 (HANGUL SYLLABLE BBYAET) 4012 0xBECE 뻎 (HANGUL SYLLABLE BBYAEP) 4013 0xBECF 뻏 (HANGUL SYLLABLE BBYAEH) 4014 0xBED2 뻒 (HANGUL SYLLABLE BBEOGG) 4015 0xBED3 뻓 (HANGUL SYLLABLE BBEOGS) 4022 0xBED5 뻕 (HANGUL SYLLABLE BBEONJ) 4023 0xBED6 뻖 (HANGUL SYLLABLE BBEONH) 4024 0xBED9 뻙 (HANGUL SYLLABLE BBEOLG) 4025 0xBEDA 뻚 (HANGUL SYLLABLE BBEOLM) 4026 0xBEDB 뻛 (HANGUL SYLLABLE BBEOLB) 4027 0xBEDC 뻜 (HANGUL SYLLABLE BBEOLS) 4028 0xBEDD 뻝 (HANGUL SYLLABLE BBEOLT) 4029 0xBEDE 뻞 (HANGUL SYLLABLE BBEOLP) 4030 0xBEDF 뻟 (HANGUL SYLLABLE BBEOLH) 4031 0xBEE1 뻡 (HANGUL SYLLABLE BBEOB) 4032 0xBEE2 뻢 (HANGUL SYLLABLE BBEOBS) 4033 0xBEE6 뻦 (HANGUL SYLLABLE BBEOJ) 4034 0xBEE7 뻧 (HANGUL SYLLABLE BBEOC) 4035 0xBEE8 뻨 (HANGUL SYLLABLE BBEOK) 4036 0xBEE9 뻩 (HANGUL SYLLABLE BBEOT) 4037 0xBEEA 뻪 (HANGUL SYLLABLE BBEOP) 4038 0xBEEB 뻫 (HANGUL SYLLABLE BBEOH) 4039 0xBEED 뻭 (HANGUL SYLLABLE BBEG) 4040 0xBEEE 뻮 (HANGUL SYLLABLE BBEGG) 4041 0xBEEF 뻯 (HANGUL SYLLABLE BBEGS) 4042 0xBEF0 뻰 (HANGUL SYLLABLE BBEN) 4043 0xBEF1 뻱 (HANGUL SYLLABLE BBENJ) 4044 0xBEF2 뻲 (HANGUL SYLLABLE BBENH) 4045 0xBEF3 뻳 (HANGUL SYLLABLE BBED) 4046 0xBEF4 뻴 (HANGUL SYLLABLE BBEL) 4047 0xBEF5 뻵 (HANGUL SYLLABLE BBELG) 4054 0xBEF6 뻶 (HANGUL SYLLABLE BBELM) 4055 0xBEF7 뻷 (HANGUL SYLLABLE BBELB) 4056 0xBEF8 뻸 (HANGUL SYLLABLE BBELS) 4057 0xBEF9 뻹 (HANGUL SYLLABLE BBELT) 4058 0xBEFA 뻺 (HANGUL SYLLABLE BBELP) 4059 0xBEFB 뻻 (HANGUL SYLLABLE BBELH) 4060 0xBEFC 뻼 (HANGUL SYLLABLE BBEM) 4061 0xBEFD 뻽 (HANGUL SYLLABLE BBEB) 4062 0xBEFE 뻾 (HANGUL SYLLABLE BBEBS) 4063 0xBEFF 뻿 (HANGUL SYLLABLE BBES) 4064 0xBF00 뼀 (HANGUL SYLLABLE BBESS) 4065 0xBF02 뼂 (HANGUL SYLLABLE BBEJ) 4066 0xBF03 뼃 (HANGUL SYLLABLE BBEC) 4067 0xBF04 뼄 (HANGUL SYLLABLE BBEK) 4068 0xBF05 뼅 (HANGUL SYLLABLE BBET) 4069 0xBF06 뼆 (HANGUL SYLLABLE BBEP) 4070 0xBF07 뼇 (HANGUL SYLLABLE BBEH) 4071 0xBF0A 뼊 (HANGUL SYLLABLE BBYEOGG) 4072 0xBF0B 뼋 (HANGUL SYLLABLE BBYEOGS) 4073 0xBF0C 뼌 (HANGUL SYLLABLE BBYEON) 4074 0xBF0D 뼍 (HANGUL SYLLABLE BBYEONJ) 4075 0xBF0E 뼎 (HANGUL SYLLABLE BBYEONH) 4076 0xBF0F 뼏 (HANGUL SYLLABLE BBYEOD) 4077 0xBF10 뼐 (HANGUL SYLLABLE BBYEOL) 4078 0xBF11 뼑 (HANGUL SYLLABLE BBYEOLG) 4079 0xBF12 뼒 (HANGUL SYLLABLE BBYEOLM) 4080 0xBF13 뼓 (HANGUL SYLLABLE BBYEOLB) 4081 0xBF14 뼔 (HANGUL SYLLABLE BBYEOLS) 4082 0xBF15 뼕 (HANGUL SYLLABLE BBYEOLT) 4083 0xBF16 뼖 (HANGUL SYLLABLE BBYEOLP) 4084 0xBF17 뼗 (HANGUL SYLLABLE BBYEOLH) 4085 0xBF1A 뼚 (HANGUL SYLLABLE BBYEOBS) 4086 0xBF1E 뼞 (HANGUL SYLLABLE BBYEOJ) 4087 0xBF1F 뼟 (HANGUL SYLLABLE BBYEOC) 4088 0xBF20 뼠 (HANGUL SYLLABLE BBYEOK) 4089 0xBF21 뼡 (HANGUL SYLLABLE BBYEOT) 4090 0xBF22 뼢 (HANGUL SYLLABLE BBYEOP) 4091 0xBF23 뼣 (HANGUL SYLLABLE BBYEOH) 4092 0xBF24 뼤 (HANGUL SYLLABLE BBYE) 4093 0xBF25 뼥 (HANGUL SYLLABLE BBYEG) 4094 0xBF26 뼦 (HANGUL SYLLABLE BBYEGG) 4095 0xBF27 뼧 (HANGUL SYLLABLE BBYEGS) 4096 0xBF28 뼨 (HANGUL SYLLABLE BBYEN) 4097 0xBF29 뼩 (HANGUL SYLLABLE BBYENJ) 4098 0xBF2A 뼪 (HANGUL SYLLABLE BBYENH) 4099 0xBF2B 뼫 (HANGUL SYLLABLE BBYED) 4100 0xBF2C 뼬 (HANGUL SYLLABLE BBYEL) 4101 0xBF2D 뼭 (HANGUL SYLLABLE BBYELG) 4102 0xBF2E 뼮 (HANGUL SYLLABLE BBYELM) 4103 0xBF2F 뼯 (HANGUL SYLLABLE BBYELB) 4104 0xBF30 뼰 (HANGUL SYLLABLE BBYELS) 4105 0xBF31 뼱 (HANGUL SYLLABLE BBYELT) 4106 0xBF32 뼲 (HANGUL SYLLABLE BBYELP) 4107 0xBF33 뼳 (HANGUL SYLLABLE BBYELH) 4108 0xBF34 뼴 (HANGUL SYLLABLE BBYEM) 4109 0xBF35 뼵 (HANGUL SYLLABLE BBYEB) 4110 0xBF36 뼶 (HANGUL SYLLABLE BBYEBS) 4111 0xBF37 뼷 (HANGUL SYLLABLE BBYES) 4112 0xBF38 뼸 (HANGUL SYLLABLE BBYESS) 4113 0xBF39 뼹 (HANGUL SYLLABLE BBYENG) 4114 0xBF3A 뼺 (HANGUL SYLLABLE BBYEJ) 4115 0xBF3B 뼻 (HANGUL SYLLABLE BBYEC) 4116 0xBF3C 뼼 (HANGUL SYLLABLE BBYEK) 4117 0xBF3D 뼽 (HANGUL SYLLABLE BBYET) 4118 0xBF3E 뼾 (HANGUL SYLLABLE BBYEP) 4119 0xBF3F 뼿 (HANGUL SYLLABLE BBYEH) 4120 0xBF42 뽂 (HANGUL SYLLABLE BBOGG) 4121 0xBF43 뽃 (HANGUL SYLLABLE BBOGS) 4122 0xBF45 뽅 (HANGUL SYLLABLE BBONJ) 4123 0xBF46 뽆 (HANGUL SYLLABLE BBONH) 4124 0xBF47 뽇 (HANGUL SYLLABLE BBOD) 4125 0xBF49 뽉 (HANGUL SYLLABLE BBOLG) 4126 0xBF4A 뽊 (HANGUL SYLLABLE BBOLM) 4127 0xBF4B 뽋 (HANGUL SYLLABLE BBOLB) 4128 0xBF4C 뽌 (HANGUL SYLLABLE BBOLS) 4129 0xBF4D 뽍 (HANGUL SYLLABLE BBOLT) 4130 0xBF4E 뽎 (HANGUL SYLLABLE BBOLP) 4131 0xBF4F 뽏 (HANGUL SYLLABLE BBOLH) 4132 0xBF52 뽒 (HANGUL SYLLABLE BBOBS) 4133 0xBF53 뽓 (HANGUL SYLLABLE BBOS) 4134 0xBF54 뽔 (HANGUL SYLLABLE BBOSS) 4135 0xBF56 뽖 (HANGUL SYLLABLE BBOJ) 4136 0xBF57 뽗 (HANGUL SYLLABLE BBOC) 4137 0xBF58 뽘 (HANGUL SYLLABLE BBOK) 4138 0xBF59 뽙 (HANGUL SYLLABLE BBOT) 4139 0xBF5A 뽚 (HANGUL SYLLABLE BBOP) 4140 0xBF5B 뽛 (HANGUL SYLLABLE BBOH) 4141 0xBF5C 뽜 (HANGUL SYLLABLE BBWA) 4142 0xBF5D 뽝 (HANGUL SYLLABLE BBWAG) 4143 0xBF5E 뽞 (HANGUL SYLLABLE BBWAGG) 4144 0xBF5F 뽟 (HANGUL SYLLABLE BBWAGS) 4145 0xBF60 뽠 (HANGUL SYLLABLE BBWAN) 4146 0xBF61 뽡 (HANGUL SYLLABLE BBWANJ) 4147 0xBF62 뽢 (HANGUL SYLLABLE BBWANH) 4148 0xBF63 뽣 (HANGUL SYLLABLE BBWAD) 4149 0xBF64 뽤 (HANGUL SYLLABLE BBWAL) 4150 0xBF65 뽥 (HANGUL SYLLABLE BBWALG) 4151 0xBF66 뽦 (HANGUL SYLLABLE BBWALM) 4152 0xBF67 뽧 (HANGUL SYLLABLE BBWALB) 4153 0xBF68 뽨 (HANGUL SYLLABLE BBWALS) 4154 0xBF69 뽩 (HANGUL SYLLABLE BBWALT) 4155 0xBF6A 뽪 (HANGUL SYLLABLE BBWALP) 4156 0xBF6B 뽫 (HANGUL SYLLABLE BBWALH) 4157 0xBF6C 뽬 (HANGUL SYLLABLE BBWAM) 4158 0xBF6D 뽭 (HANGUL SYLLABLE BBWAB) 4159 0xBF6E 뽮 (HANGUL SYLLABLE BBWABS) 4160 0xBF6F 뽯 (HANGUL SYLLABLE BBWAS) 4161 0xBF70 뽰 (HANGUL SYLLABLE BBWASS) 4162 0xBF71 뽱 (HANGUL SYLLABLE BBWANG) 4163 0xBF72 뽲 (HANGUL SYLLABLE BBWAJ) 4164 0xBF73 뽳 (HANGUL SYLLABLE BBWAC) 4165 0xBF74 뽴 (HANGUL SYLLABLE BBWAK) 4166 0xBF75 뽵 (HANGUL SYLLABLE BBWAT) 4167 0xBF76 뽶 (HANGUL SYLLABLE BBWAP) 4168 0xBF77 뽷 (HANGUL SYLLABLE BBWAH) 4169 0xBF78 뽸 (HANGUL SYLLABLE BBWAE) 4170 0xBF79 뽹 (HANGUL SYLLABLE BBWAEG) 4171 0xBF7A 뽺 (HANGUL SYLLABLE BBWAEGG) 4172 0xBF7B 뽻 (HANGUL SYLLABLE BBWAEGS) 4173 0xBF7C 뽼 (HANGUL SYLLABLE BBWAEN) 4174 0xBF7D 뽽 (HANGUL SYLLABLE BBWAENJ) 4175 0xBF7E 뽾 (HANGUL SYLLABLE BBWAENH) 4176 0xBF7F 뽿 (HANGUL SYLLABLE BBWAED) 4177 0xBF80 뾀 (HANGUL SYLLABLE BBWAEL) 4178 0xBF81 뾁 (HANGUL SYLLABLE BBWAELG) 4179 0xBF82 뾂 (HANGUL SYLLABLE BBWAELM) 4180 0xBF83 뾃 (HANGUL SYLLABLE BBWAELB) 4181 0xBF84 뾄 (HANGUL SYLLABLE BBWAELS) 4182 0xBF85 뾅 (HANGUL SYLLABLE BBWAELT) 4183 0xBF86 뾆 (HANGUL SYLLABLE BBWAELP) 4184 0xBF87 뾇 (HANGUL SYLLABLE BBWAELH) 4185 0xBF88 뾈 (HANGUL SYLLABLE BBWAEM) 4186 0xBF89 뾉 (HANGUL SYLLABLE BBWAEB) 4187 0xBF8A 뾊 (HANGUL SYLLABLE BBWAEBS) 4188 0xBF8B 뾋 (HANGUL SYLLABLE BBWAES) 4189 0xBF8C 뾌 (HANGUL SYLLABLE BBWAESS) 4190 0xBF8D 뾍 (HANGUL SYLLABLE BBWAENG) 4191 0xBF8E 뾎 (HANGUL SYLLABLE BBWAEJ) 4192 0xBF8F 뾏 (HANGUL SYLLABLE BBWAEC) 4193 0xBF90 뾐 (HANGUL SYLLABLE BBWAEK) 4194 0xBF91 뾑 (HANGUL SYLLABLE BBWAET) 4195 0xBF92 뾒 (HANGUL SYLLABLE BBWAEP) 4196 0xBF93 뾓 (HANGUL SYLLABLE BBWAEH) 4197 0xBF95 뾕 (HANGUL SYLLABLE BBOEG) 4198 0xBF96 뾖 (HANGUL SYLLABLE BBOEGG) 4199 0xBF97 뾗 (HANGUL SYLLABLE BBOEGS) 4200 0xBF98 뾘 (HANGUL SYLLABLE BBOEN) 4201 0xBF99 뾙 (HANGUL SYLLABLE BBOENJ) 4202 0xBF9A 뾚 (HANGUL SYLLABLE BBOENH) 4203 0xBF9B 뾛 (HANGUL SYLLABLE BBOED) 4204 0xBF9C 뾜 (HANGUL SYLLABLE BBOEL) 4205 0xBF9D 뾝 (HANGUL SYLLABLE BBOELG) 4212 0xBF9E 뾞 (HANGUL SYLLABLE BBOELM) 4213 0xBF9F 뾟 (HANGUL SYLLABLE BBOELB) 4214 0xBFA0 뾠 (HANGUL SYLLABLE BBOELS) 4215 0xBFA1 뾡 (HANGUL SYLLABLE BBOELT) 4216 0xBFA2 뾢 (HANGUL SYLLABLE BBOELP) 4217 0xBFA3 뾣 (HANGUL SYLLABLE BBOELH) 4218 0xBFA4 뾤 (HANGUL SYLLABLE BBOEM) 4219 0xBFA5 뾥 (HANGUL SYLLABLE BBOEB) 4220 0xBFA6 뾦 (HANGUL SYLLABLE BBOEBS) 4221 0xBFA7 뾧 (HANGUL SYLLABLE BBOES) 4222 0xBFA8 뾨 (HANGUL SYLLABLE BBOESS) 4223 0xBFA9 뾩 (HANGUL SYLLABLE BBOENG) 4224 0xBFAA 뾪 (HANGUL SYLLABLE BBOEJ) 4225 0xBFAB 뾫 (HANGUL SYLLABLE BBOEC) 4226 0xBFAC 뾬 (HANGUL SYLLABLE BBOEK) 4227 0xBFAD 뾭 (HANGUL SYLLABLE BBOET) 4228 0xBFAE 뾮 (HANGUL SYLLABLE BBOEP) 4229 0xBFAF 뾯 (HANGUL SYLLABLE BBOEH) 4230 0xBFB1 뾱 (HANGUL SYLLABLE BBYOG) 4231 0xBFB2 뾲 (HANGUL SYLLABLE BBYOGG) 4232 0xBFB3 뾳 (HANGUL SYLLABLE BBYOGS) 4233 0xBFB4 뾴 (HANGUL SYLLABLE BBYON) 4234 0xBFB5 뾵 (HANGUL SYLLABLE BBYONJ) 4235 0xBFB6 뾶 (HANGUL SYLLABLE BBYONH) 4236 0xBFB7 뾷 (HANGUL SYLLABLE BBYOD) 4237 0xBFB8 뾸 (HANGUL SYLLABLE BBYOL) 4244 0xBFB9 뾹 (HANGUL SYLLABLE BBYOLG) 4245 0xBFBA 뾺 (HANGUL SYLLABLE BBYOLM) 4246 0xBFBB 뾻 (HANGUL SYLLABLE BBYOLB) 4247 0xBFBC 뾼 (HANGUL SYLLABLE BBYOLS) 4248 0xBFBD 뾽 (HANGUL SYLLABLE BBYOLT) 4249 0xBFBE 뾾 (HANGUL SYLLABLE BBYOLP) 4250 0xBFBF 뾿 (HANGUL SYLLABLE BBYOLH) 4251 0xBFC0 뿀 (HANGUL SYLLABLE BBYOM) 4252 0xBFC1 뿁 (HANGUL SYLLABLE BBYOB) 4253 0xBFC2 뿂 (HANGUL SYLLABLE BBYOBS) 4254 0xBFC3 뿃 (HANGUL SYLLABLE BBYOS) 4255 0xBFC4 뿄 (HANGUL SYLLABLE BBYOSS) 4256 0xBFC6 뿆 (HANGUL SYLLABLE BBYOJ) 4257 0xBFC7 뿇 (HANGUL SYLLABLE BBYOC) 4258 0xBFC8 뿈 (HANGUL SYLLABLE BBYOK) 4259 0xBFC9 뿉 (HANGUL SYLLABLE BBYOT) 4260 0xBFCA 뿊 (HANGUL SYLLABLE BBYOP) 4261 0xBFCB 뿋 (HANGUL SYLLABLE BBYOH) 4262 0xBFCE 뿎 (HANGUL SYLLABLE BBUGG) 4263 0xBFCF 뿏 (HANGUL SYLLABLE BBUGS) 4264 0xBFD1 뿑 (HANGUL SYLLABLE BBUNJ) 4265 0xBFD2 뿒 (HANGUL SYLLABLE BBUNH) 4266 0xBFD3 뿓 (HANGUL SYLLABLE BBUD) 4267 0xBFD5 뿕 (HANGUL SYLLABLE BBULG) 4268 0xBFD6 뿖 (HANGUL SYLLABLE BBULM) 4269 0xBFD7 뿗 (HANGUL SYLLABLE BBULB) 4270 0xBFD8 뿘 (HANGUL SYLLABLE BBULS) 4271 0xBFD9 뿙 (HANGUL SYLLABLE BBULT) 4272 0xBFDA 뿚 (HANGUL SYLLABLE BBULP) 4273 0xBFDB 뿛 (HANGUL SYLLABLE BBULH) 4274 0xBFDD 뿝 (HANGUL SYLLABLE BBUB) 4275 0xBFDE 뿞 (HANGUL SYLLABLE BBUBS) 4276 0xBFE0 뿠 (HANGUL SYLLABLE BBUSS) 4277 0xBFE2 뿢 (HANGUL SYLLABLE BBUJ) 4278 0xBFE3 뿣 (HANGUL SYLLABLE BBUC) 4279 0xBFE4 뿤 (HANGUL SYLLABLE BBUK) 4280 0xBFE5 뿥 (HANGUL SYLLABLE BBUT) 4281 0xBFE6 뿦 (HANGUL SYLLABLE BBUP) 4282 0xBFE7 뿧 (HANGUL SYLLABLE BBUH) 4283 0xBFE8 뿨 (HANGUL SYLLABLE BBWEO) 4284 0xBFE9 뿩 (HANGUL SYLLABLE BBWEOG) 4285 0xBFEA 뿪 (HANGUL SYLLABLE BBWEOGG) 4286 0xBFEB 뿫 (HANGUL SYLLABLE BBWEOGS) 4287 0xBFEC 뿬 (HANGUL SYLLABLE BBWEON) 4288 0xBFED 뿭 (HANGUL SYLLABLE BBWEONJ) 4289 0xBFEE 뿮 (HANGUL SYLLABLE BBWEONH) 4290 0xBFEF 뿯 (HANGUL SYLLABLE BBWEOD) 4291 0xBFF0 뿰 (HANGUL SYLLABLE BBWEOL) 4292 0xBFF1 뿱 (HANGUL SYLLABLE BBWEOLG) 4293 0xBFF2 뿲 (HANGUL SYLLABLE BBWEOLM) 4294 0xBFF3 뿳 (HANGUL SYLLABLE BBWEOLB) 4295 0xBFF4 뿴 (HANGUL SYLLABLE BBWEOLS) 4296 0xBFF5 뿵 (HANGUL SYLLABLE BBWEOLT) 4297 0xBFF6 뿶 (HANGUL SYLLABLE BBWEOLP) 4298 0xBFF7 뿷 (HANGUL SYLLABLE BBWEOLH) 4299 0xBFF8 뿸 (HANGUL SYLLABLE BBWEOM) 4300 0xBFF9 뿹 (HANGUL SYLLABLE BBWEOB) 4301 0xBFFA 뿺 (HANGUL SYLLABLE BBWEOBS) 4302 0xBFFB 뿻 (HANGUL SYLLABLE BBWEOS) 4303 0xBFFC 뿼 (HANGUL SYLLABLE BBWEOSS) 4304 0xBFFD 뿽 (HANGUL SYLLABLE BBWEONG) 4305 0xBFFE 뿾 (HANGUL SYLLABLE BBWEOJ) 4306 0xBFFF 뿿 (HANGUL SYLLABLE BBWEOC) 4307 0xC000 쀀 (HANGUL SYLLABLE BBWEOK) 4308 0xC001 쀁 (HANGUL SYLLABLE BBWEOT) 4309 0xC002 쀂 (HANGUL SYLLABLE BBWEOP) 4310 0xC003 쀃 (HANGUL SYLLABLE BBWEOH) 4311 0xC004 쀄 (HANGUL SYLLABLE BBWE) 4312 0xC005 쀅 (HANGUL SYLLABLE BBWEG) 4313 0xC006 쀆 (HANGUL SYLLABLE BBWEGG) 4314 0xC007 쀇 (HANGUL SYLLABLE BBWEGS) 4315 0xC008 쀈 (HANGUL SYLLABLE BBWEN) 4316 0xC009 쀉 (HANGUL SYLLABLE BBWENJ) 4317 0xC00A 쀊 (HANGUL SYLLABLE BBWENH) 4318 0xC00B 쀋 (HANGUL SYLLABLE BBWED) 4319 0xC00C 쀌 (HANGUL SYLLABLE BBWEL) 4320 0xC00D 쀍 (HANGUL SYLLABLE BBWELG) 4321 0xC00E 쀎 (HANGUL SYLLABLE BBWELM) 4322 0xC00F 쀏 (HANGUL SYLLABLE BBWELB) 4323 0xC010 쀐 (HANGUL SYLLABLE BBWELS) 4324 0xC011 쀑 (HANGUL SYLLABLE BBWELT) 4325 0xC012 쀒 (HANGUL SYLLABLE BBWELP) 4326 0xC013 쀓 (HANGUL SYLLABLE BBWELH) 4327 0xC014 쀔 (HANGUL SYLLABLE BBWEM) 4328 0xC015 쀕 (HANGUL SYLLABLE BBWEB) 4329 0xC016 쀖 (HANGUL SYLLABLE BBWEBS) 4330 0xC017 쀗 (HANGUL SYLLABLE BBWES) 4331 0xC018 쀘 (HANGUL SYLLABLE BBWESS) 4332 0xC019 쀙 (HANGUL SYLLABLE BBWENG) 4333 0xC01A 쀚 (HANGUL SYLLABLE BBWEJ) 4334 0xC01B 쀛 (HANGUL SYLLABLE BBWEC) 4335 0xC01C 쀜 (HANGUL SYLLABLE BBWEK) 4336 0xC01D 쀝 (HANGUL SYLLABLE BBWET) 4337 0xC01E 쀞 (HANGUL SYLLABLE BBWEP) 4338 0xC01F 쀟 (HANGUL SYLLABLE BBWEH) 4339 0xC020 쀠 (HANGUL SYLLABLE BBWI) 4340 0xC021 쀡 (HANGUL SYLLABLE BBWIG) 4341 0xC022 쀢 (HANGUL SYLLABLE BBWIGG) 4342 0xC023 쀣 (HANGUL SYLLABLE BBWIGS) 4343 0xC024 쀤 (HANGUL SYLLABLE BBWIN) 4344 0xC025 쀥 (HANGUL SYLLABLE BBWINJ) 4345 0xC026 쀦 (HANGUL SYLLABLE BBWINH) 4346 0xC027 쀧 (HANGUL SYLLABLE BBWID) 4347 0xC028 쀨 (HANGUL SYLLABLE BBWIL) 4348 0xC029 쀩 (HANGUL SYLLABLE BBWILG) 4349 0xC02A 쀪 (HANGUL SYLLABLE BBWILM) 4350 0xC02B 쀫 (HANGUL SYLLABLE BBWILB) 4351 0xC02C 쀬 (HANGUL SYLLABLE BBWILS) 4352 0xC02D 쀭 (HANGUL SYLLABLE BBWILT) 4353 0xC02E 쀮 (HANGUL SYLLABLE BBWILP) 4354 0xC02F 쀯 (HANGUL SYLLABLE BBWILH) 4355 0xC030 쀰 (HANGUL SYLLABLE BBWIM) 4356 0xC031 쀱 (HANGUL SYLLABLE BBWIB) 4357 0xC032 쀲 (HANGUL SYLLABLE BBWIBS) 4358 0xC033 쀳 (HANGUL SYLLABLE BBWIS) 4359 0xC034 쀴 (HANGUL SYLLABLE BBWISS) 4360 0xC035 쀵 (HANGUL SYLLABLE BBWING) 4361 0xC036 쀶 (HANGUL SYLLABLE BBWIJ) 4362 0xC037 쀷 (HANGUL SYLLABLE BBWIC) 4363 0xC038 쀸 (HANGUL SYLLABLE BBWIK) 4364 0xC039 쀹 (HANGUL SYLLABLE BBWIT) 4365 0xC03A 쀺 (HANGUL SYLLABLE BBWIP) 4366 0xC03B 쀻 (HANGUL SYLLABLE BBWIH) 4367 0xC03D 쀽 (HANGUL SYLLABLE BBYUG) 4368 0xC03E 쀾 (HANGUL SYLLABLE BBYUGG) 4369 0xC03F 쀿 (HANGUL SYLLABLE BBYUGS) 4370 0xC040 쁀 (HANGUL SYLLABLE BBYUN) 4371 0xC041 쁁 (HANGUL SYLLABLE BBYUNJ) 4372 0xC042 쁂 (HANGUL SYLLABLE BBYUNH) 4373 0xC043 쁃 (HANGUL SYLLABLE BBYUD) 4374 0xC044 쁄 (HANGUL SYLLABLE BBYUL) 4375 0xC045 쁅 (HANGUL SYLLABLE BBYULG) 4376 0xC046 쁆 (HANGUL SYLLABLE BBYULM) 4377 0xC047 쁇 (HANGUL SYLLABLE BBYULB) 4378 0xC048 쁈 (HANGUL SYLLABLE BBYULS) 4379 0xC049 쁉 (HANGUL SYLLABLE BBYULT) 4380 0xC04A 쁊 (HANGUL SYLLABLE BBYULP) 4381 0xC04B 쁋 (HANGUL SYLLABLE BBYULH) 4382 0xC04C 쁌 (HANGUL SYLLABLE BBYUM) 4383 0xC04D 쁍 (HANGUL SYLLABLE BBYUB) 4384 0xC04E 쁎 (HANGUL SYLLABLE BBYUBS) 4385 0xC04F 쁏 (HANGUL SYLLABLE BBYUS) 4386 0xC050 쁐 (HANGUL SYLLABLE BBYUSS) 4387 0xC052 쁒 (HANGUL SYLLABLE BBYUJ) 4388 0xC053 쁓 (HANGUL SYLLABLE BBYUC) 4389 0xC054 쁔 (HANGUL SYLLABLE BBYUK) 4390 0xC055 쁕 (HANGUL SYLLABLE BBYUT) 4391 0xC056 쁖 (HANGUL SYLLABLE BBYUP) 4392 0xC057 쁗 (HANGUL SYLLABLE BBYUH) 4393 0xC059 쁙 (HANGUL SYLLABLE BBEUG) 4394 0xC05A 쁚 (HANGUL SYLLABLE BBEUGG) 4395 0xC05B 쁛 (HANGUL SYLLABLE BBEUGS) 4402 0xC05D 쁝 (HANGUL SYLLABLE BBEUNJ) 4403 0xC05E 쁞 (HANGUL SYLLABLE BBEUNH) 4404 0xC05F 쁟 (HANGUL SYLLABLE BBEUD) 4405 0xC061 쁡 (HANGUL SYLLABLE BBEULG) 4406 0xC062 쁢 (HANGUL SYLLABLE BBEULM) 4407 0xC063 쁣 (HANGUL SYLLABLE BBEULB) 4408 0xC064 쁤 (HANGUL SYLLABLE BBEULS) 4409 0xC065 쁥 (HANGUL SYLLABLE BBEULT) 4410 0xC066 쁦 (HANGUL SYLLABLE BBEULP) 4411 0xC067 쁧 (HANGUL SYLLABLE BBEULH) 4412 0xC06A 쁪 (HANGUL SYLLABLE BBEUBS) 4413 0xC06B 쁫 (HANGUL SYLLABLE BBEUS) 4414 0xC06C 쁬 (HANGUL SYLLABLE BBEUSS) 4415 0xC06D 쁭 (HANGUL SYLLABLE BBEUNG) 4416 0xC06E 쁮 (HANGUL SYLLABLE BBEUJ) 4417 0xC06F 쁯 (HANGUL SYLLABLE BBEUC) 4418 0xC070 쁰 (HANGUL SYLLABLE BBEUK) 4419 0xC071 쁱 (HANGUL SYLLABLE BBEUT) 4420 0xC072 쁲 (HANGUL SYLLABLE BBEUP) 4421 0xC073 쁳 (HANGUL SYLLABLE BBEUH) 4422 0xC074 쁴 (HANGUL SYLLABLE BBYI) 4423 0xC075 쁵 (HANGUL SYLLABLE BBYIG) 4424 0xC076 쁶 (HANGUL SYLLABLE BBYIGG) 4425 0xC077 쁷 (HANGUL SYLLABLE BBYIGS) 4426 0xC078 쁸 (HANGUL SYLLABLE BBYIN) 4427 0xC079 쁹 (HANGUL SYLLABLE BBYINJ) 4434 0xC07A 쁺 (HANGUL SYLLABLE BBYINH) 4435 0xC07B 쁻 (HANGUL SYLLABLE BBYID) 4436 0xC07C 쁼 (HANGUL SYLLABLE BBYIL) 4437 0xC07D 쁽 (HANGUL SYLLABLE BBYILG) 4438 0xC07E 쁾 (HANGUL SYLLABLE BBYILM) 4439 0xC07F 쁿 (HANGUL SYLLABLE BBYILB) 4440 0xC080 삀 (HANGUL SYLLABLE BBYILS) 4441 0xC081 삁 (HANGUL SYLLABLE BBYILT) 4442 0xC082 삂 (HANGUL SYLLABLE BBYILP) 4443 0xC083 삃 (HANGUL SYLLABLE BBYILH) 4444 0xC084 삄 (HANGUL SYLLABLE BBYIM) 4445 0xC085 삅 (HANGUL SYLLABLE BBYIB) 4446 0xC086 삆 (HANGUL SYLLABLE BBYIBS) 4447 0xC087 삇 (HANGUL SYLLABLE BBYIS) 4448 0xC088 삈 (HANGUL SYLLABLE BBYISS) 4449 0xC089 삉 (HANGUL SYLLABLE BBYING) 4450 0xC08A 삊 (HANGUL SYLLABLE BBYIJ) 4451 0xC08B 삋 (HANGUL SYLLABLE BBYIC) 4452 0xC08C 삌 (HANGUL SYLLABLE BBYIK) 4453 0xC08D 삍 (HANGUL SYLLABLE BBYIT) 4454 0xC08E 삎 (HANGUL SYLLABLE BBYIP) 4455 0xC08F 삏 (HANGUL SYLLABLE BBYIH) 4456 0xC092 삒 (HANGUL SYLLABLE BBIGG) 4457 0xC093 삓 (HANGUL SYLLABLE BBIGS) 4458 0xC095 삕 (HANGUL SYLLABLE BBINJ) 4459 0xC096 삖 (HANGUL SYLLABLE BBINH) 4460 0xC097 삗 (HANGUL SYLLABLE BBID) 4461 0xC099 삙 (HANGUL SYLLABLE BBILG) 4462 0xC09A 삚 (HANGUL SYLLABLE BBILM) 4463 0xC09B 삛 (HANGUL SYLLABLE BBILB) 4464 0xC09C 삜 (HANGUL SYLLABLE BBILS) 4465 0xC09D 삝 (HANGUL SYLLABLE BBILT) 4466 0xC09E 삞 (HANGUL SYLLABLE BBILP) 4467 0xC09F 삟 (HANGUL SYLLABLE BBILH) 4468 0xC0A2 삢 (HANGUL SYLLABLE BBIBS) 4469 0xC0A4 삤 (HANGUL SYLLABLE BBISS) 4470 0xC0A6 삦 (HANGUL SYLLABLE BBIJ) 4471 0xC0A7 삧 (HANGUL SYLLABLE BBIC) 4472 0xC0A8 삨 (HANGUL SYLLABLE BBIK) 4473 0xC0A9 삩 (HANGUL SYLLABLE BBIT) 4474 0xC0AA 삪 (HANGUL SYLLABLE BBIP) 4475 0xC0AB 삫 (HANGUL SYLLABLE BBIH) 4476 0xC0AE 삮 (HANGUL SYLLABLE SAGG) 4477 0xC0B1 삱 (HANGUL SYLLABLE SANJ) 4478 0xC0B2 삲 (HANGUL SYLLABLE SANH) 4479 0xC0B7 삷 (HANGUL SYLLABLE SALB) 4480 0xC0B8 삸 (HANGUL SYLLABLE SALS) 4481 0xC0B9 삹 (HANGUL SYLLABLE SALT) 4482 0xC0BA 삺 (HANGUL SYLLABLE SALP) 4483 0xC0BB 삻 (HANGUL SYLLABLE SALH) 4484 0xC0BE 삾 (HANGUL SYLLABLE SABS) 4485 0xC0C2 샂 (HANGUL SYLLABLE SAJ) 4486 0xC0C3 샃 (HANGUL SYLLABLE SAC) 4487 0xC0C4 샄 (HANGUL SYLLABLE SAK) 4488 0xC0C6 샆 (HANGUL SYLLABLE SAP) 4489 0xC0C7 샇 (HANGUL SYLLABLE SAH) 4490 0xC0CA 샊 (HANGUL SYLLABLE SAEGG) 4491 0xC0CB 샋 (HANGUL SYLLABLE SAEGS) 4492 0xC0CD 샍 (HANGUL SYLLABLE SAENJ) 4493 0xC0CE 샎 (HANGUL SYLLABLE SAENH) 4494 0xC0CF 샏 (HANGUL SYLLABLE SAED) 4495 0xC0D1 샑 (HANGUL SYLLABLE SAELG) 4496 0xC0D2 샒 (HANGUL SYLLABLE SAELM) 4497 0xC0D3 샓 (HANGUL SYLLABLE SAELB) 4498 0xC0D4 샔 (HANGUL SYLLABLE SAELS) 4499 0xC0D5 샕 (HANGUL SYLLABLE SAELT) 4500 0xC0D6 샖 (HANGUL SYLLABLE SAELP) 4501 0xC0D7 샗 (HANGUL SYLLABLE SAELH) 4502 0xC0DA 샚 (HANGUL SYLLABLE SAEBS) 4503 0xC0DE 샞 (HANGUL SYLLABLE SAEJ) 4504 0xC0DF 샟 (HANGUL SYLLABLE SAEC) 4505 0xC0E0 샠 (HANGUL SYLLABLE SAEK) 4506 0xC0E1 샡 (HANGUL SYLLABLE SAET) 4507 0xC0E2 샢 (HANGUL SYLLABLE SAEP) 4508 0xC0E3 샣 (HANGUL SYLLABLE SAEH) 4509 0xC0E6 샦 (HANGUL SYLLABLE SYAGG) 4510 0xC0E7 샧 (HANGUL SYLLABLE SYAGS) 4511 0xC0E9 샩 (HANGUL SYLLABLE SYANJ) 4512 0xC0EA 샪 (HANGUL SYLLABLE SYANH) 4513 0xC0EB 샫 (HANGUL SYLLABLE SYAD) 4514 0xC0ED 샭 (HANGUL SYLLABLE SYALG) 4515 0xC0EE 샮 (HANGUL SYLLABLE SYALM) 4516 0xC0EF 샯 (HANGUL SYLLABLE SYALB) 4517 0xC0F0 샰 (HANGUL SYLLABLE SYALS) 4518 0xC0F1 샱 (HANGUL SYLLABLE SYALT) 4519 0xC0F2 샲 (HANGUL SYLLABLE SYALP) 4520 0xC0F3 샳 (HANGUL SYLLABLE SYALH) 4521 0xC0F6 샶 (HANGUL SYLLABLE SYABS) 4522 0xC0F8 샸 (HANGUL SYLLABLE SYASS) 4523 0xC0FA 샺 (HANGUL SYLLABLE SYAJ) 4524 0xC0FB 샻 (HANGUL SYLLABLE SYAC) 4525 0xC0FC 샼 (HANGUL SYLLABLE SYAK) 4526 0xC0FD 샽 (HANGUL SYLLABLE SYAT) 4527 0xC0FE 샾 (HANGUL SYLLABLE SYAP) 4528 0xC0FF 샿 (HANGUL SYLLABLE SYAH) 4529 0xC101 섁 (HANGUL SYLLABLE SYAEG) 4530 0xC102 섂 (HANGUL SYLLABLE SYAEGG) 4531 0xC103 섃 (HANGUL SYLLABLE SYAEGS) 4532 0xC105 섅 (HANGUL SYLLABLE SYAENJ) 4533 0xC106 섆 (HANGUL SYLLABLE SYAENH) 4534 0xC107 섇 (HANGUL SYLLABLE SYAED) 4535 0xC109 섉 (HANGUL SYLLABLE SYAELG) 4536 0xC10A 섊 (HANGUL SYLLABLE SYAELM) 4537 0xC10B 섋 (HANGUL SYLLABLE SYAELB) 4538 0xC10C 섌 (HANGUL SYLLABLE SYAELS) 4539 0xC10D 섍 (HANGUL SYLLABLE SYAELT) 4540 0xC10E 섎 (HANGUL SYLLABLE SYAELP) 4541 0xC10F 섏 (HANGUL SYLLABLE SYAELH) 4542 0xC111 섑 (HANGUL SYLLABLE SYAEB) 4543 0xC112 섒 (HANGUL SYLLABLE SYAEBS) 4544 0xC113 섓 (HANGUL SYLLABLE SYAES) 4545 0xC114 섔 (HANGUL SYLLABLE SYAESS) 4546 0xC116 섖 (HANGUL SYLLABLE SYAEJ) 4547 0xC117 섗 (HANGUL SYLLABLE SYAEC) 4548 0xC118 섘 (HANGUL SYLLABLE SYAEK) 4549 0xC119 섙 (HANGUL SYLLABLE SYAET) 4550 0xC11A 섚 (HANGUL SYLLABLE SYAEP) 4551 0xC11B 섛 (HANGUL SYLLABLE SYAEH) 4552 0xC121 섡 (HANGUL SYLLABLE SEONJ) 4553 0xC122 섢 (HANGUL SYLLABLE SEONH) 4554 0xC125 섥 (HANGUL SYLLABLE SEOLG) 4555 0xC128 섨 (HANGUL SYLLABLE SEOLS) 4556 0xC129 섩 (HANGUL SYLLABLE SEOLT) 4557 0xC12A 섪 (HANGUL SYLLABLE SEOLP) 4558 0xC12B 섫 (HANGUL SYLLABLE SEOLH) 4559 0xC12E 섮 (HANGUL SYLLABLE SEOBS) 4560 0xC132 섲 (HANGUL SYLLABLE SEOJ) 4561 0xC133 섳 (HANGUL SYLLABLE SEOC) 4562 0xC134 섴 (HANGUL SYLLABLE SEOK) 4563 0xC135 섵 (HANGUL SYLLABLE SEOT) 4564 0xC137 섷 (HANGUL SYLLABLE SEOH) 4565 0xC13A 섺 (HANGUL SYLLABLE SEGG) 4566 0xC13B 섻 (HANGUL SYLLABLE SEGS) 4567 0xC13D 섽 (HANGUL SYLLABLE SENJ) 4568 0xC13E 섾 (HANGUL SYLLABLE SENH) 4569 0xC13F 섿 (HANGUL SYLLABLE SED) 4570 0xC141 셁 (HANGUL SYLLABLE SELG) 4571 0xC142 셂 (HANGUL SYLLABLE SELM) 4572 0xC143 셃 (HANGUL SYLLABLE SELB) 4573 0xC144 셄 (HANGUL SYLLABLE SELS) 4574 0xC145 셅 (HANGUL SYLLABLE SELT) 4575 0xC146 셆 (HANGUL SYLLABLE SELP) 4576 0xC147 셇 (HANGUL SYLLABLE SELH) 4577 0xC14A 셊 (HANGUL SYLLABLE SEBS) 4578 0xC14E 셎 (HANGUL SYLLABLE SEJ) 4579 0xC14F 셏 (HANGUL SYLLABLE SEC) 4580 0xC150 셐 (HANGUL SYLLABLE SEK) 4581 0xC151 셑 (HANGUL SYLLABLE SET) 4582 0xC152 셒 (HANGUL SYLLABLE SEP) 4583 0xC153 셓 (HANGUL SYLLABLE SEH) 4584 0xC156 셖 (HANGUL SYLLABLE SYEOGG) 4585 0xC157 셗 (HANGUL SYLLABLE SYEOGS) 4592 0xC159 셙 (HANGUL SYLLABLE SYEONJ) 4593 0xC15A 셚 (HANGUL SYLLABLE SYEONH) 4594 0xC15B 셛 (HANGUL SYLLABLE SYEOD) 4595 0xC15D 셝 (HANGUL SYLLABLE SYEOLG) 4596 0xC15E 셞 (HANGUL SYLLABLE SYEOLM) 4597 0xC15F 셟 (HANGUL SYLLABLE SYEOLB) 4598 0xC160 셠 (HANGUL SYLLABLE SYEOLS) 4599 0xC161 셡 (HANGUL SYLLABLE SYEOLT) 4600 0xC162 셢 (HANGUL SYLLABLE SYEOLP) 4601 0xC163 셣 (HANGUL SYLLABLE SYEOLH) 4602 0xC166 셦 (HANGUL SYLLABLE SYEOBS) 4603 0xC16A 셪 (HANGUL SYLLABLE SYEOJ) 4604 0xC16B 셫 (HANGUL SYLLABLE SYEOC) 4605 0xC16C 셬 (HANGUL SYLLABLE SYEOK) 4606 0xC16D 셭 (HANGUL SYLLABLE SYEOT) 4607 0xC16E 셮 (HANGUL SYLLABLE SYEOP) 4608 0xC16F 셯 (HANGUL SYLLABLE SYEOH) 4609 0xC171 셱 (HANGUL SYLLABLE SYEG) 4610 0xC172 셲 (HANGUL SYLLABLE SYEGG) 4611 0xC173 셳 (HANGUL SYLLABLE SYEGS) 4612 0xC175 셵 (HANGUL SYLLABLE SYENJ) 4613 0xC176 셶 (HANGUL SYLLABLE SYENH) 4614 0xC177 셷 (HANGUL SYLLABLE SYED) 4615 0xC179 셹 (HANGUL SYLLABLE SYELG) 4616 0xC17A 셺 (HANGUL SYLLABLE SYELM) 4617 0xC17B 셻 (HANGUL SYLLABLE SYELB) 4624 0xC17C 셼 (HANGUL SYLLABLE SYELS) 4625 0xC17D 셽 (HANGUL SYLLABLE SYELT) 4626 0xC17E 셾 (HANGUL SYLLABLE SYELP) 4627 0xC17F 셿 (HANGUL SYLLABLE SYELH) 4628 0xC180 솀 (HANGUL SYLLABLE SYEM) 4629 0xC181 솁 (HANGUL SYLLABLE SYEB) 4630 0xC182 솂 (HANGUL SYLLABLE SYEBS) 4631 0xC183 솃 (HANGUL SYLLABLE SYES) 4632 0xC184 솄 (HANGUL SYLLABLE SYESS) 4633 0xC186 솆 (HANGUL SYLLABLE SYEJ) 4634 0xC187 솇 (HANGUL SYLLABLE SYEC) 4635 0xC188 솈 (HANGUL SYLLABLE SYEK) 4636 0xC189 솉 (HANGUL SYLLABLE SYET) 4637 0xC18A 솊 (HANGUL SYLLABLE SYEP) 4638 0xC18B 솋 (HANGUL SYLLABLE SYEH) 4639 0xC18F 솏 (HANGUL SYLLABLE SOGS) 4640 0xC191 솑 (HANGUL SYLLABLE SONJ) 4641 0xC192 솒 (HANGUL SYLLABLE SONH) 4642 0xC193 솓 (HANGUL SYLLABLE SOD) 4643 0xC195 솕 (HANGUL SYLLABLE SOLG) 4644 0xC197 솗 (HANGUL SYLLABLE SOLB) 4645 0xC198 솘 (HANGUL SYLLABLE SOLS) 4646 0xC199 솙 (HANGUL SYLLABLE SOLT) 4647 0xC19A 솚 (HANGUL SYLLABLE SOLP) 4648 0xC19B 솛 (HANGUL SYLLABLE SOLH) 4649 0xC19E 솞 (HANGUL SYLLABLE SOBS) 4650 0xC1A0 솠 (HANGUL SYLLABLE SOSS) 4651 0xC1A2 솢 (HANGUL SYLLABLE SOJ) 4652 0xC1A3 솣 (HANGUL SYLLABLE SOC) 4653 0xC1A4 솤 (HANGUL SYLLABLE SOK) 4654 0xC1A6 솦 (HANGUL SYLLABLE SOP) 4655 0xC1A7 솧 (HANGUL SYLLABLE SOH) 4656 0xC1AA 솪 (HANGUL SYLLABLE SWAGG) 4657 0xC1AB 솫 (HANGUL SYLLABLE SWAGS) 4658 0xC1AD 솭 (HANGUL SYLLABLE SWANJ) 4659 0xC1AE 솮 (HANGUL SYLLABLE SWANH) 4660 0xC1AF 솯 (HANGUL SYLLABLE SWAD) 4661 0xC1B1 솱 (HANGUL SYLLABLE SWALG) 4662 0xC1B2 솲 (HANGUL SYLLABLE SWALM) 4663 0xC1B3 솳 (HANGUL SYLLABLE SWALB) 4664 0xC1B4 솴 (HANGUL SYLLABLE SWALS) 4665 0xC1B5 솵 (HANGUL SYLLABLE SWALT) 4666 0xC1B6 솶 (HANGUL SYLLABLE SWALP) 4667 0xC1B7 솷 (HANGUL SYLLABLE SWALH) 4668 0xC1B8 솸 (HANGUL SYLLABLE SWAM) 4669 0xC1B9 솹 (HANGUL SYLLABLE SWAB) 4670 0xC1BA 솺 (HANGUL SYLLABLE SWABS) 4671 0xC1BB 솻 (HANGUL SYLLABLE SWAS) 4672 0xC1BC 솼 (HANGUL SYLLABLE SWASS) 4673 0xC1BE 솾 (HANGUL SYLLABLE SWAJ) 4674 0xC1BF 솿 (HANGUL SYLLABLE SWAC) 4675 0xC1C0 쇀 (HANGUL SYLLABLE SWAK) 4676 0xC1C1 쇁 (HANGUL SYLLABLE SWAT) 4677 0xC1C2 쇂 (HANGUL SYLLABLE SWAP) 4678 0xC1C3 쇃 (HANGUL SYLLABLE SWAH) 4679 0xC1C5 쇅 (HANGUL SYLLABLE SWAEG) 4680 0xC1C6 쇆 (HANGUL SYLLABLE SWAEGG) 4681 0xC1C7 쇇 (HANGUL SYLLABLE SWAEGS) 4682 0xC1C9 쇉 (HANGUL SYLLABLE SWAENJ) 4683 0xC1CA 쇊 (HANGUL SYLLABLE SWAENH) 4684 0xC1CB 쇋 (HANGUL SYLLABLE SWAED) 4685 0xC1CD 쇍 (HANGUL SYLLABLE SWAELG) 4686 0xC1CE 쇎 (HANGUL SYLLABLE SWAELM) 4687 0xC1CF 쇏 (HANGUL SYLLABLE SWAELB) 4688 0xC1D0 쇐 (HANGUL SYLLABLE SWAELS) 4689 0xC1D1 쇑 (HANGUL SYLLABLE SWAELT) 4690 0xC1D2 쇒 (HANGUL SYLLABLE SWAELP) 4691 0xC1D3 쇓 (HANGUL SYLLABLE SWAELH) 4692 0xC1D5 쇕 (HANGUL SYLLABLE SWAEB) 4693 0xC1D6 쇖 (HANGUL SYLLABLE SWAEBS) 4694 0xC1D9 쇙 (HANGUL SYLLABLE SWAENG) 4695 0xC1DA 쇚 (HANGUL SYLLABLE SWAEJ) 4696 0xC1DB 쇛 (HANGUL SYLLABLE SWAEC) 4697 0xC1DC 쇜 (HANGUL SYLLABLE SWAEK) 4698 0xC1DD 쇝 (HANGUL SYLLABLE SWAET) 4699 0xC1DE 쇞 (HANGUL SYLLABLE SWAEP) 4700 0xC1DF 쇟 (HANGUL SYLLABLE SWAEH) 4701 0xC1E1 쇡 (HANGUL SYLLABLE SOEG) 4702 0xC1E2 쇢 (HANGUL SYLLABLE SOEGG) 4703 0xC1E3 쇣 (HANGUL SYLLABLE SOEGS) 4704 0xC1E5 쇥 (HANGUL SYLLABLE SOENJ) 4705 0xC1E6 쇦 (HANGUL SYLLABLE SOENH) 4706 0xC1E7 쇧 (HANGUL SYLLABLE SOED) 4707 0xC1E9 쇩 (HANGUL SYLLABLE SOELG) 4708 0xC1EA 쇪 (HANGUL SYLLABLE SOELM) 4709 0xC1EB 쇫 (HANGUL SYLLABLE SOELB) 4710 0xC1EC 쇬 (HANGUL SYLLABLE SOELS) 4711 0xC1ED 쇭 (HANGUL SYLLABLE SOELT) 4712 0xC1EE 쇮 (HANGUL SYLLABLE SOELP) 4713 0xC1EF 쇯 (HANGUL SYLLABLE SOELH) 4714 0xC1F2 쇲 (HANGUL SYLLABLE SOEBS) 4715 0xC1F4 쇴 (HANGUL SYLLABLE SOESS) 4716 0xC1F5 쇵 (HANGUL SYLLABLE SOENG) 4717 0xC1F6 쇶 (HANGUL SYLLABLE SOEJ) 4718 0xC1F7 쇷 (HANGUL SYLLABLE SOEC) 4719 0xC1F8 쇸 (HANGUL SYLLABLE SOEK) 4720 0xC1F9 쇹 (HANGUL SYLLABLE SOET) 4721 0xC1FA 쇺 (HANGUL SYLLABLE SOEP) 4722 0xC1FB 쇻 (HANGUL SYLLABLE SOEH) 4723 0xC1FE 쇾 (HANGUL SYLLABLE SYOGG) 4724 0xC1FF 쇿 (HANGUL SYLLABLE SYOGS) 4725 0xC201 숁 (HANGUL SYLLABLE SYONJ) 4726 0xC202 숂 (HANGUL SYLLABLE SYONH) 4727 0xC203 숃 (HANGUL SYLLABLE SYOD) 4728 0xC205 숅 (HANGUL SYLLABLE SYOLG) 4729 0xC206 숆 (HANGUL SYLLABLE SYOLM) 4730 0xC207 숇 (HANGUL SYLLABLE SYOLB) 4731 0xC208 숈 (HANGUL SYLLABLE SYOLS) 4732 0xC209 숉 (HANGUL SYLLABLE SYOLT) 4733 0xC20A 숊 (HANGUL SYLLABLE SYOLP) 4734 0xC20B 숋 (HANGUL SYLLABLE SYOLH) 4735 0xC20E 숎 (HANGUL SYLLABLE SYOBS) 4736 0xC210 숐 (HANGUL SYLLABLE SYOSS) 4737 0xC212 숒 (HANGUL SYLLABLE SYOJ) 4738 0xC213 숓 (HANGUL SYLLABLE SYOC) 4739 0xC214 숔 (HANGUL SYLLABLE SYOK) 4740 0xC215 숕 (HANGUL SYLLABLE SYOT) 4741 0xC216 숖 (HANGUL SYLLABLE SYOP) 4742 0xC217 숗 (HANGUL SYLLABLE SYOH) 4743 0xC21A 숚 (HANGUL SYLLABLE SUGG) 4744 0xC21B 숛 (HANGUL SYLLABLE SUGS) 4745 0xC21D 숝 (HANGUL SYLLABLE SUNJ) 4746 0xC21E 숞 (HANGUL SYLLABLE SUNH) 4747 0xC221 숡 (HANGUL SYLLABLE SULG) 4748 0xC222 숢 (HANGUL SYLLABLE SULM) 4749 0xC223 숣 (HANGUL SYLLABLE SULB) 4750 0xC224 숤 (HANGUL SYLLABLE SULS) 4751 0xC225 숥 (HANGUL SYLLABLE SULT) 4752 0xC226 숦 (HANGUL SYLLABLE SULP) 4753 0xC227 숧 (HANGUL SYLLABLE SULH) 4754 0xC22A 숪 (HANGUL SYLLABLE SUBS) 4755 0xC22C 숬 (HANGUL SYLLABLE SUSS) 4756 0xC22E 숮 (HANGUL SYLLABLE SUJ) 4757 0xC230 숰 (HANGUL SYLLABLE SUK) 4758 0xC233 숳 (HANGUL SYLLABLE SUH) 4759 0xC235 숵 (HANGUL SYLLABLE SWEOG) 4760 0xC236 숶 (HANGUL SYLLABLE SWEOGG) 4761 0xC237 숷 (HANGUL SYLLABLE SWEOGS) 4762 0xC238 숸 (HANGUL SYLLABLE SWEON) 4763 0xC239 숹 (HANGUL SYLLABLE SWEONJ) 4764 0xC23A 숺 (HANGUL SYLLABLE SWEONH) 4765 0xC23B 숻 (HANGUL SYLLABLE SWEOD) 4766 0xC23C 숼 (HANGUL SYLLABLE SWEOL) 4767 0xC23D 숽 (HANGUL SYLLABLE SWEOLG) 4768 0xC23E 숾 (HANGUL SYLLABLE SWEOLM) 4769 0xC23F 숿 (HANGUL SYLLABLE SWEOLB) 4770 0xC240 쉀 (HANGUL SYLLABLE SWEOLS) 4771 0xC241 쉁 (HANGUL SYLLABLE SWEOLT) 4772 0xC242 쉂 (HANGUL SYLLABLE SWEOLP) 4773 0xC243 쉃 (HANGUL SYLLABLE SWEOLH) 4774 0xC244 쉄 (HANGUL SYLLABLE SWEOM) 4775 0xC245 쉅 (HANGUL SYLLABLE SWEOB) 4782 0xC246 쉆 (HANGUL SYLLABLE SWEOBS) 4783 0xC247 쉇 (HANGUL SYLLABLE SWEOS) 4784 0xC249 쉉 (HANGUL SYLLABLE SWEONG) 4785 0xC24A 쉊 (HANGUL SYLLABLE SWEOJ) 4786 0xC24B 쉋 (HANGUL SYLLABLE SWEOC) 4787 0xC24C 쉌 (HANGUL SYLLABLE SWEOK) 4788 0xC24D 쉍 (HANGUL SYLLABLE SWEOT) 4789 0xC24E 쉎 (HANGUL SYLLABLE SWEOP) 4790 0xC24F 쉏 (HANGUL SYLLABLE SWEOH) 4791 0xC252 쉒 (HANGUL SYLLABLE SWEGG) 4792 0xC253 쉓 (HANGUL SYLLABLE SWEGS) 4793 0xC255 쉕 (HANGUL SYLLABLE SWENJ) 4794 0xC256 쉖 (HANGUL SYLLABLE SWENH) 4795 0xC257 쉗 (HANGUL SYLLABLE SWED) 4796 0xC259 쉙 (HANGUL SYLLABLE SWELG) 4797 0xC25A 쉚 (HANGUL SYLLABLE SWELM) 4798 0xC25B 쉛 (HANGUL SYLLABLE SWELB) 4799 0xC25C 쉜 (HANGUL SYLLABLE SWELS) 4800 0xC25D 쉝 (HANGUL SYLLABLE SWELT) 4801 0xC25E 쉞 (HANGUL SYLLABLE SWELP) 4802 0xC25F 쉟 (HANGUL SYLLABLE SWELH) 4803 0xC261 쉡 (HANGUL SYLLABLE SWEB) 4804 0xC262 쉢 (HANGUL SYLLABLE SWEBS) 4805 0xC263 쉣 (HANGUL SYLLABLE SWES) 4806 0xC264 쉤 (HANGUL SYLLABLE SWESS) 4807 0xC266 쉦 (HANGUL SYLLABLE SWEJ) 4814 0xC267 쉧 (HANGUL SYLLABLE SWEC) 4815 0xC268 쉨 (HANGUL SYLLABLE SWEK) 4816 0xC269 쉩 (HANGUL SYLLABLE SWET) 4817 0xC26A 쉪 (HANGUL SYLLABLE SWEP) 4818 0xC26B 쉫 (HANGUL SYLLABLE SWEH) 4819 0xC26E 쉮 (HANGUL SYLLABLE SWIGG) 4820 0xC26F 쉯 (HANGUL SYLLABLE SWIGS) 4821 0xC271 쉱 (HANGUL SYLLABLE SWINJ) 4822 0xC272 쉲 (HANGUL SYLLABLE SWINH) 4823 0xC273 쉳 (HANGUL SYLLABLE SWID) 4824 0xC275 쉵 (HANGUL SYLLABLE SWILG) 4825 0xC276 쉶 (HANGUL SYLLABLE SWILM) 4826 0xC277 쉷 (HANGUL SYLLABLE SWILB) 4827 0xC278 쉸 (HANGUL SYLLABLE SWILS) 4828 0xC279 쉹 (HANGUL SYLLABLE SWILT) 4829 0xC27A 쉺 (HANGUL SYLLABLE SWILP) 4830 0xC27B 쉻 (HANGUL SYLLABLE SWILH) 4831 0xC27E 쉾 (HANGUL SYLLABLE SWIBS) 4832 0xC280 슀 (HANGUL SYLLABLE SWISS) 4833 0xC282 슂 (HANGUL SYLLABLE SWIJ) 4834 0xC283 슃 (HANGUL SYLLABLE SWIC) 4835 0xC284 슄 (HANGUL SYLLABLE SWIK) 4836 0xC285 슅 (HANGUL SYLLABLE SWIT) 4837 0xC286 슆 (HANGUL SYLLABLE SWIP) 4838 0xC287 슇 (HANGUL SYLLABLE SWIH) 4839 0xC28A 슊 (HANGUL SYLLABLE SYUGG) 4840 0xC28B 슋 (HANGUL SYLLABLE SYUGS) 4841 0xC28C 슌 (HANGUL SYLLABLE SYUN) 4842 0xC28D 슍 (HANGUL SYLLABLE SYUNJ) 4843 0xC28E 슎 (HANGUL SYLLABLE SYUNH) 4844 0xC28F 슏 (HANGUL SYLLABLE SYUD) 4845 0xC291 슑 (HANGUL SYLLABLE SYULG) 4846 0xC292 슒 (HANGUL SYLLABLE SYULM) 4847 0xC293 슓 (HANGUL SYLLABLE SYULB) 4848 0xC294 슔 (HANGUL SYLLABLE SYULS) 4849 0xC295 슕 (HANGUL SYLLABLE SYULT) 4850 0xC296 슖 (HANGUL SYLLABLE SYULP) 4851 0xC297 슗 (HANGUL SYLLABLE SYULH) 4852 0xC299 슙 (HANGUL SYLLABLE SYUB) 4853 0xC29A 슚 (HANGUL SYLLABLE SYUBS) 4854 0xC29C 슜 (HANGUL SYLLABLE SYUSS) 4855 0xC29E 슞 (HANGUL SYLLABLE SYUJ) 4856 0xC29F 슟 (HANGUL SYLLABLE SYUC) 4857 0xC2A0 슠 (HANGUL SYLLABLE SYUK) 4858 0xC2A1 슡 (HANGUL SYLLABLE SYUT) 4859 0xC2A2 슢 (HANGUL SYLLABLE SYUP) 4860 0xC2A3 슣 (HANGUL SYLLABLE SYUH) 4861 0xC2A6 슦 (HANGUL SYLLABLE SEUGG) 4862 0xC2A7 슧 (HANGUL SYLLABLE SEUGS) 4863 0xC2A9 슩 (HANGUL SYLLABLE SEUNJ) 4864 0xC2AA 슪 (HANGUL SYLLABLE SEUNH) 4865 0xC2AB 슫 (HANGUL SYLLABLE SEUD) 4866 0xC2AE 슮 (HANGUL SYLLABLE SEULM) 4867 0xC2AF 슯 (HANGUL SYLLABLE SEULB) 4868 0xC2B0 슰 (HANGUL SYLLABLE SEULS) 4869 0xC2B1 슱 (HANGUL SYLLABLE SEULT) 4870 0xC2B2 슲 (HANGUL SYLLABLE SEULP) 4871 0xC2B3 슳 (HANGUL SYLLABLE SEULH) 4872 0xC2B6 슶 (HANGUL SYLLABLE SEUBS) 4873 0xC2B8 슸 (HANGUL SYLLABLE SEUSS) 4874 0xC2BA 슺 (HANGUL SYLLABLE SEUJ) 4875 0xC2BB 슻 (HANGUL SYLLABLE SEUC) 4876 0xC2BC 슼 (HANGUL SYLLABLE SEUK) 4877 0xC2BD 슽 (HANGUL SYLLABLE SEUT) 4878 0xC2BE 슾 (HANGUL SYLLABLE SEUP) 4879 0xC2BF 슿 (HANGUL SYLLABLE SEUH) 4880 0xC2C0 싀 (HANGUL SYLLABLE SYI) 4881 0xC2C1 싁 (HANGUL SYLLABLE SYIG) 4882 0xC2C2 싂 (HANGUL SYLLABLE SYIGG) 4883 0xC2C3 싃 (HANGUL SYLLABLE SYIGS) 4884 0xC2C4 싄 (HANGUL SYLLABLE SYIN) 4885 0xC2C5 싅 (HANGUL SYLLABLE SYINJ) 4886 0xC2C6 싆 (HANGUL SYLLABLE SYINH) 4887 0xC2C7 싇 (HANGUL SYLLABLE SYID) 4888 0xC2C8 싈 (HANGUL SYLLABLE SYIL) 4889 0xC2C9 싉 (HANGUL SYLLABLE SYILG) 4890 0xC2CA 싊 (HANGUL SYLLABLE SYILM) 4891 0xC2CB 싋 (HANGUL SYLLABLE SYILB) 4892 0xC2CC 싌 (HANGUL SYLLABLE SYILS) 4893 0xC2CD 싍 (HANGUL SYLLABLE SYILT) 4894 0xC2CE 싎 (HANGUL SYLLABLE SYILP) 4895 0xC2CF 싏 (HANGUL SYLLABLE SYILH) 4896 0xC2D0 싐 (HANGUL SYLLABLE SYIM) 4897 0xC2D1 싑 (HANGUL SYLLABLE SYIB) 4898 0xC2D2 싒 (HANGUL SYLLABLE SYIBS) 4899 0xC2D3 싓 (HANGUL SYLLABLE SYIS) 4900 0xC2D4 싔 (HANGUL SYLLABLE SYISS) 4901 0xC2D5 싕 (HANGUL SYLLABLE SYING) 4902 0xC2D6 싖 (HANGUL SYLLABLE SYIJ) 4903 0xC2D7 싗 (HANGUL SYLLABLE SYIC) 4904 0xC2D8 싘 (HANGUL SYLLABLE SYIK) 4905 0xC2D9 싙 (HANGUL SYLLABLE SYIT) 4906 0xC2DA 싚 (HANGUL SYLLABLE SYIP) 4907 0xC2DB 싛 (HANGUL SYLLABLE SYIH) 4908 0xC2DE 싞 (HANGUL SYLLABLE SIGG) 4909 0xC2DF 싟 (HANGUL SYLLABLE SIGS) 4910 0xC2E1 싡 (HANGUL SYLLABLE SINJ) 4911 0xC2E2 싢 (HANGUL SYLLABLE SINH) 4912 0xC2E5 싥 (HANGUL SYLLABLE SILG) 4913 0xC2E6 싦 (HANGUL SYLLABLE SILM) 4914 0xC2E7 싧 (HANGUL SYLLABLE SILB) 4915 0xC2E8 싨 (HANGUL SYLLABLE SILS) 4916 0xC2E9 싩 (HANGUL SYLLABLE SILT) 4917 0xC2EA 싪 (HANGUL SYLLABLE SILP) 4918 0xC2EE 싮 (HANGUL SYLLABLE SIBS) 4919 0xC2F0 싰 (HANGUL SYLLABLE SISS) 4920 0xC2F2 싲 (HANGUL SYLLABLE SIJ) 4921 0xC2F3 싳 (HANGUL SYLLABLE SIC) 4922 0xC2F4 싴 (HANGUL SYLLABLE SIK) 4923 0xC2F5 싵 (HANGUL SYLLABLE SIT) 4924 0xC2F7 싷 (HANGUL SYLLABLE SIH) 4925 0xC2FA 싺 (HANGUL SYLLABLE SSAGG) 4926 0xC2FD 싽 (HANGUL SYLLABLE SSANJ) 4927 0xC2FE 싾 (HANGUL SYLLABLE SSANH) 4928 0xC2FF 싿 (HANGUL SYLLABLE SSAD) 4929 0xC301 쌁 (HANGUL SYLLABLE SSALG) 4930 0xC302 쌂 (HANGUL SYLLABLE SSALM) 4931 0xC303 쌃 (HANGUL SYLLABLE SSALB) 4932 0xC304 쌄 (HANGUL SYLLABLE SSALS) 4933 0xC305 쌅 (HANGUL SYLLABLE SSALT) 4934 0xC306 쌆 (HANGUL SYLLABLE SSALP) 4935 0xC307 쌇 (HANGUL SYLLABLE SSALH) 4936 0xC30A 쌊 (HANGUL SYLLABLE SSABS) 4937 0xC30B 쌋 (HANGUL SYLLABLE SSAS) 4938 0xC30E 쌎 (HANGUL SYLLABLE SSAJ) 4939 0xC30F 쌏 (HANGUL SYLLABLE SSAC) 4940 0xC310 쌐 (HANGUL SYLLABLE SSAK) 4941 0xC311 쌑 (HANGUL SYLLABLE SSAT) 4942 0xC312 쌒 (HANGUL SYLLABLE SSAP) 4943 0xC316 쌖 (HANGUL SYLLABLE SSAEGG) 4944 0xC317 쌗 (HANGUL SYLLABLE SSAEGS) 4945 0xC319 쌙 (HANGUL SYLLABLE SSAENJ) 4946 0xC31A 쌚 (HANGUL SYLLABLE SSAENH) 4947 0xC31B 쌛 (HANGUL SYLLABLE SSAED) 4948 0xC31D 쌝 (HANGUL SYLLABLE SSAELG) 4949 0xC31E 쌞 (HANGUL SYLLABLE SSAELM) 4950 0xC31F 쌟 (HANGUL SYLLABLE SSAELB) 4951 0xC320 쌠 (HANGUL SYLLABLE SSAELS) 4952 0xC321 쌡 (HANGUL SYLLABLE SSAELT) 4953 0xC322 쌢 (HANGUL SYLLABLE SSAELP) 4954 0xC323 쌣 (HANGUL SYLLABLE SSAELH) 4955 0xC326 쌦 (HANGUL SYLLABLE SSAEBS) 4956 0xC327 쌧 (HANGUL SYLLABLE SSAES) 4957 0xC32A 쌪 (HANGUL SYLLABLE SSAEJ) 4958 0xC32B 쌫 (HANGUL SYLLABLE SSAEC) 4959 0xC32C 쌬 (HANGUL SYLLABLE SSAEK) 4960 0xC32D 쌭 (HANGUL SYLLABLE SSAET) 4961 0xC32E 쌮 (HANGUL SYLLABLE SSAEP) 4962 0xC32F 쌯 (HANGUL SYLLABLE SSAEH) 4963 0xC330 쌰 (HANGUL SYLLABLE SSYA) 4964 0xC331 쌱 (HANGUL SYLLABLE SSYAG) 4965 0xC332 쌲 (HANGUL SYLLABLE SSYAGG) 4972 0xC333 쌳 (HANGUL SYLLABLE SSYAGS) 4973 0xC334 쌴 (HANGUL SYLLABLE SSYAN) 4974 0xC335 쌵 (HANGUL SYLLABLE SSYANJ) 4975 0xC336 쌶 (HANGUL SYLLABLE SSYANH) 4976 0xC337 쌷 (HANGUL SYLLABLE SSYAD) 4977 0xC338 쌸 (HANGUL SYLLABLE SSYAL) 4978 0xC339 쌹 (HANGUL SYLLABLE SSYALG) 4979 0xC33A 쌺 (HANGUL SYLLABLE SSYALM) 4980 0xC33B 쌻 (HANGUL SYLLABLE SSYALB) 4981 0xC33C 쌼 (HANGUL SYLLABLE SSYALS) 4982 0xC33D 쌽 (HANGUL SYLLABLE SSYALT) 4983 0xC33E 쌾 (HANGUL SYLLABLE SSYALP) 4984 0xC33F 쌿 (HANGUL SYLLABLE SSYALH) 4985 0xC340 썀 (HANGUL SYLLABLE SSYAM) 4986 0xC341 썁 (HANGUL SYLLABLE SSYAB) 4987 0xC342 썂 (HANGUL SYLLABLE SSYABS) 4988 0xC343 썃 (HANGUL SYLLABLE SSYAS) 4989 0xC344 썄 (HANGUL SYLLABLE SSYASS) 4990 0xC346 썆 (HANGUL SYLLABLE SSYAJ) 4991 0xC347 썇 (HANGUL SYLLABLE SSYAC) 4992 0xC348 썈 (HANGUL SYLLABLE SSYAK) 4993 0xC349 썉 (HANGUL SYLLABLE SSYAT) 4994 0xC34A 썊 (HANGUL SYLLABLE SSYAP) 4995 0xC34B 썋 (HANGUL SYLLABLE SSYAH) 4996 0xC34C 썌 (HANGUL SYLLABLE SSYAE) 4997 0xC34D 썍 (HANGUL SYLLABLE SSYAEG) 5004 0xC34E 썎 (HANGUL SYLLABLE SSYAEGG) 5005 0xC34F 썏 (HANGUL SYLLABLE SSYAEGS) 5006 0xC350 썐 (HANGUL SYLLABLE SSYAEN) 5007 0xC351 썑 (HANGUL SYLLABLE SSYAENJ) 5008 0xC352 썒 (HANGUL SYLLABLE SSYAENH) 5009 0xC353 썓 (HANGUL SYLLABLE SSYAED) 5010 0xC354 썔 (HANGUL SYLLABLE SSYAEL) 5011 0xC355 썕 (HANGUL SYLLABLE SSYAELG) 5012 0xC356 썖 (HANGUL SYLLABLE SSYAELM) 5013 0xC357 썗 (HANGUL SYLLABLE SSYAELB) 5014 0xC358 썘 (HANGUL SYLLABLE SSYAELS) 5015 0xC359 썙 (HANGUL SYLLABLE SSYAELT) 5016 0xC35A 썚 (HANGUL SYLLABLE SSYAELP) 5017 0xC35B 썛 (HANGUL SYLLABLE SSYAELH) 5018 0xC35C 썜 (HANGUL SYLLABLE SSYAEM) 5019 0xC35D 썝 (HANGUL SYLLABLE SSYAEB) 5020 0xC35E 썞 (HANGUL SYLLABLE SSYAEBS) 5021 0xC35F 썟 (HANGUL SYLLABLE SSYAES) 5022 0xC360 썠 (HANGUL SYLLABLE SSYAESS) 5023 0xC361 썡 (HANGUL SYLLABLE SSYAENG) 5024 0xC362 썢 (HANGUL SYLLABLE SSYAEJ) 5025 0xC363 썣 (HANGUL SYLLABLE SSYAEC) 5026 0xC364 썤 (HANGUL SYLLABLE SSYAEK) 5027 0xC365 썥 (HANGUL SYLLABLE SSYAET) 5028 0xC366 썦 (HANGUL SYLLABLE SSYAEP) 5029 0xC367 썧 (HANGUL SYLLABLE SSYAEH) 5030 0xC36A 썪 (HANGUL SYLLABLE SSEOGG) 5031 0xC36B 썫 (HANGUL SYLLABLE SSEOGS) 5032 0xC36D 썭 (HANGUL SYLLABLE SSEONJ) 5033 0xC36E 썮 (HANGUL SYLLABLE SSEONH) 5034 0xC36F 썯 (HANGUL SYLLABLE SSEOD) 5035 0xC371 썱 (HANGUL SYLLABLE SSEOLG) 5036 0xC373 썳 (HANGUL SYLLABLE SSEOLB) 5037 0xC374 썴 (HANGUL SYLLABLE SSEOLS) 5038 0xC375 썵 (HANGUL SYLLABLE SSEOLT) 5039 0xC376 썶 (HANGUL SYLLABLE SSEOLP) 5040 0xC377 썷 (HANGUL SYLLABLE SSEOLH) 5041 0xC37A 썺 (HANGUL SYLLABLE SSEOBS) 5042 0xC37B 썻 (HANGUL SYLLABLE SSEOS) 5043 0xC37E 썾 (HANGUL SYLLABLE SSEOJ) 5044 0xC37F 썿 (HANGUL SYLLABLE SSEOC) 5045 0xC380 쎀 (HANGUL SYLLABLE SSEOK) 5046 0xC381 쎁 (HANGUL SYLLABLE SSEOT) 5047 0xC382 쎂 (HANGUL SYLLABLE SSEOP) 5048 0xC383 쎃 (HANGUL SYLLABLE SSEOH) 5049 0xC385 쎅 (HANGUL SYLLABLE SSEG) 5050 0xC386 쎆 (HANGUL SYLLABLE SSEGG) 5051 0xC387 쎇 (HANGUL SYLLABLE SSEGS) 5052 0xC389 쎉 (HANGUL SYLLABLE SSENJ) 5053 0xC38A 쎊 (HANGUL SYLLABLE SSENH) 5054 0xC38B 쎋 (HANGUL SYLLABLE SSED) 5055 0xC38D 쎍 (HANGUL SYLLABLE SSELG) 5056 0xC38E 쎎 (HANGUL SYLLABLE SSELM) 5057 0xC38F 쎏 (HANGUL SYLLABLE SSELB) 5058 0xC390 쎐 (HANGUL SYLLABLE SSELS) 5059 0xC391 쎑 (HANGUL SYLLABLE SSELT) 5060 0xC392 쎒 (HANGUL SYLLABLE SSELP) 5061 0xC393 쎓 (HANGUL SYLLABLE SSELH) 5062 0xC394 쎔 (HANGUL SYLLABLE SSEM) 5063 0xC395 쎕 (HANGUL SYLLABLE SSEB) 5064 0xC396 쎖 (HANGUL SYLLABLE SSEBS) 5065 0xC397 쎗 (HANGUL SYLLABLE SSES) 5066 0xC398 쎘 (HANGUL SYLLABLE SSESS) 5067 0xC399 쎙 (HANGUL SYLLABLE SSENG) 5068 0xC39A 쎚 (HANGUL SYLLABLE SSEJ) 5069 0xC39B 쎛 (HANGUL SYLLABLE SSEC) 5070 0xC39C 쎜 (HANGUL SYLLABLE SSEK) 5071 0xC39D 쎝 (HANGUL SYLLABLE SSET) 5072 0xC39E 쎞 (HANGUL SYLLABLE SSEP) 5073 0xC39F 쎟 (HANGUL SYLLABLE SSEH) 5074 0xC3A0 쎠 (HANGUL SYLLABLE SSYEO) 5075 0xC3A1 쎡 (HANGUL SYLLABLE SSYEOG) 5076 0xC3A2 쎢 (HANGUL SYLLABLE SSYEOGG) 5077 0xC3A3 쎣 (HANGUL SYLLABLE SSYEOGS) 5078 0xC3A4 쎤 (HANGUL SYLLABLE SSYEON) 5079 0xC3A5 쎥 (HANGUL SYLLABLE SSYEONJ) 5080 0xC3A6 쎦 (HANGUL SYLLABLE SSYEONH) 5081 0xC3A7 쎧 (HANGUL SYLLABLE SSYEOD) 5082 0xC3A8 쎨 (HANGUL SYLLABLE SSYEOL) 5083 0xC3A9 쎩 (HANGUL SYLLABLE SSYEOLG) 5084 0xC3AA 쎪 (HANGUL SYLLABLE SSYEOLM) 5085 0xC3AB 쎫 (HANGUL SYLLABLE SSYEOLB) 5086 0xC3AC 쎬 (HANGUL SYLLABLE SSYEOLS) 5087 0xC3AD 쎭 (HANGUL SYLLABLE SSYEOLT) 5088 0xC3AE 쎮 (HANGUL SYLLABLE SSYEOLP) 5089 0xC3AF 쎯 (HANGUL SYLLABLE SSYEOLH) 5090 0xC3B0 쎰 (HANGUL SYLLABLE SSYEOM) 5091 0xC3B1 쎱 (HANGUL SYLLABLE SSYEOB) 5092 0xC3B2 쎲 (HANGUL SYLLABLE SSYEOBS) 5093 0xC3B3 쎳 (HANGUL SYLLABLE SSYEOS) 5094 0xC3B4 쎴 (HANGUL SYLLABLE SSYEOSS) 5095 0xC3B5 쎵 (HANGUL SYLLABLE SSYEONG) 5096 0xC3B6 쎶 (HANGUL SYLLABLE SSYEOJ) 5097 0xC3B7 쎷 (HANGUL SYLLABLE SSYEOC) 5098 0xC3B8 쎸 (HANGUL SYLLABLE SSYEOK) 5099 0xC3B9 쎹 (HANGUL SYLLABLE SSYEOT) 5100 0xC3BA 쎺 (HANGUL SYLLABLE SSYEOP) 5101 0xC3BB 쎻 (HANGUL SYLLABLE SSYEOH) 5102 0xC3BC 쎼 (HANGUL SYLLABLE SSYE) 5103 0xC3BD 쎽 (HANGUL SYLLABLE SSYEG) 5104 0xC3BE 쎾 (HANGUL SYLLABLE SSYEGG) 5105 0xC3BF 쎿 (HANGUL SYLLABLE SSYEGS) 5106 0xC3C1 쏁 (HANGUL SYLLABLE SSYENJ) 5107 0xC3C2 쏂 (HANGUL SYLLABLE SSYENH) 5108 0xC3C3 쏃 (HANGUL SYLLABLE SSYED) 5109 0xC3C4 쏄 (HANGUL SYLLABLE SSYEL) 5110 0xC3C5 쏅 (HANGUL SYLLABLE SSYELG) 5111 0xC3C6 쏆 (HANGUL SYLLABLE SSYELM) 5112 0xC3C7 쏇 (HANGUL SYLLABLE SSYELB) 5113 0xC3C8 쏈 (HANGUL SYLLABLE SSYELS) 5114 0xC3C9 쏉 (HANGUL SYLLABLE SSYELT) 5115 0xC3CA 쏊 (HANGUL SYLLABLE SSYELP) 5116 0xC3CB 쏋 (HANGUL SYLLABLE SSYELH) 5117 0xC3CC 쏌 (HANGUL SYLLABLE SSYEM) 5118 0xC3CD 쏍 (HANGUL SYLLABLE SSYEB) 5119 0xC3CE 쏎 (HANGUL SYLLABLE SSYEBS) 5120 0xC3CF 쏏 (HANGUL SYLLABLE SSYES) 5121 0xC3D0 쏐 (HANGUL SYLLABLE SSYESS) 5122 0xC3D1 쏑 (HANGUL SYLLABLE SSYENG) 5123 0xC3D2 쏒 (HANGUL SYLLABLE SSYEJ) 5124 0xC3D3 쏓 (HANGUL SYLLABLE SSYEC) 5125 0xC3D4 쏔 (HANGUL SYLLABLE SSYEK) 5126 0xC3D5 쏕 (HANGUL SYLLABLE SSYET) 5127 0xC3D6 쏖 (HANGUL SYLLABLE SSYEP) 5128 0xC3D7 쏗 (HANGUL SYLLABLE SSYEH) 5129 0xC3DA 쏚 (HANGUL SYLLABLE SSOGG) 5130 0xC3DB 쏛 (HANGUL SYLLABLE SSOGS) 5131 0xC3DD 쏝 (HANGUL SYLLABLE SSONJ) 5132 0xC3DE 쏞 (HANGUL SYLLABLE SSONH) 5133 0xC3E1 쏡 (HANGUL SYLLABLE SSOLG) 5134 0xC3E3 쏣 (HANGUL SYLLABLE SSOLB) 5135 0xC3E4 쏤 (HANGUL SYLLABLE SSOLS) 5136 0xC3E5 쏥 (HANGUL SYLLABLE SSOLT) 5137 0xC3E6 쏦 (HANGUL SYLLABLE SSOLP) 5138 0xC3E7 쏧 (HANGUL SYLLABLE SSOLH) 5139 0xC3EA 쏪 (HANGUL SYLLABLE SSOBS) 5140 0xC3EB 쏫 (HANGUL SYLLABLE SSOS) 5141 0xC3EC 쏬 (HANGUL SYLLABLE SSOSS) 5142 0xC3EE 쏮 (HANGUL SYLLABLE SSOJ) 5143 0xC3EF 쏯 (HANGUL SYLLABLE SSOC) 5144 0xC3F0 쏰 (HANGUL SYLLABLE SSOK) 5145 0xC3F1 쏱 (HANGUL SYLLABLE SSOT) 5146 0xC3F2 쏲 (HANGUL SYLLABLE SSOP) 5147 0xC3F3 쏳 (HANGUL SYLLABLE SSOH) 5148 0xC3F6 쏶 (HANGUL SYLLABLE SSWAGG) 5149 0xC3F7 쏷 (HANGUL SYLLABLE SSWAGS) 5150 0xC3F9 쏹 (HANGUL SYLLABLE SSWANJ) 5151 0xC3FA 쏺 (HANGUL SYLLABLE SSWANH) 5152 0xC3FB 쏻 (HANGUL SYLLABLE SSWAD) 5153 0xC3FC 쏼 (HANGUL SYLLABLE SSWAL) 5154 0xC3FD 쏽 (HANGUL SYLLABLE SSWALG) 5155 0xC3FE 쏾 (HANGUL SYLLABLE SSWALM) 5162 0xC3FF 쏿 (HANGUL SYLLABLE SSWALB) 5163 0xC400 쐀 (HANGUL SYLLABLE SSWALS) 5164 0xC401 쐁 (HANGUL SYLLABLE SSWALT) 5165 0xC402 쐂 (HANGUL SYLLABLE SSWALP) 5166 0xC403 쐃 (HANGUL SYLLABLE SSWALH) 5167 0xC404 쐄 (HANGUL SYLLABLE SSWAM) 5168 0xC405 쐅 (HANGUL SYLLABLE SSWAB) 5169 0xC406 쐆 (HANGUL SYLLABLE SSWABS) 5170 0xC407 쐇 (HANGUL SYLLABLE SSWAS) 5171 0xC409 쐉 (HANGUL SYLLABLE SSWANG) 5172 0xC40A 쐊 (HANGUL SYLLABLE SSWAJ) 5173 0xC40B 쐋 (HANGUL SYLLABLE SSWAC) 5174 0xC40C 쐌 (HANGUL SYLLABLE SSWAK) 5175 0xC40D 쐍 (HANGUL SYLLABLE SSWAT) 5176 0xC40E 쐎 (HANGUL SYLLABLE SSWAP) 5177 0xC40F 쐏 (HANGUL SYLLABLE SSWAH) 5178 0xC411 쐑 (HANGUL SYLLABLE SSWAEG) 5179 0xC412 쐒 (HANGUL SYLLABLE SSWAEGG) 5180 0xC413 쐓 (HANGUL SYLLABLE SSWAEGS) 5181 0xC414 쐔 (HANGUL SYLLABLE SSWAEN) 5182 0xC415 쐕 (HANGUL SYLLABLE SSWAENJ) 5183 0xC416 쐖 (HANGUL SYLLABLE SSWAENH) 5184 0xC417 쐗 (HANGUL SYLLABLE SSWAED) 5185 0xC418 쐘 (HANGUL SYLLABLE SSWAEL) 5186 0xC419 쐙 (HANGUL SYLLABLE SSWAELG) 5187 0xC41A 쐚 (HANGUL SYLLABLE SSWAELM) 5194 0xC41B 쐛 (HANGUL SYLLABLE SSWAELB) 5195 0xC41C 쐜 (HANGUL SYLLABLE SSWAELS) 5196 0xC41D 쐝 (HANGUL SYLLABLE SSWAELT) 5197 0xC41E 쐞 (HANGUL SYLLABLE SSWAELP) 5198 0xC41F 쐟 (HANGUL SYLLABLE SSWAELH) 5199 0xC420 쐠 (HANGUL SYLLABLE SSWAEM) 5200 0xC421 쐡 (HANGUL SYLLABLE SSWAEB) 5201 0xC422 쐢 (HANGUL SYLLABLE SSWAEBS) 5202 0xC423 쐣 (HANGUL SYLLABLE SSWAES) 5203 0xC425 쐥 (HANGUL SYLLABLE SSWAENG) 5204 0xC426 쐦 (HANGUL SYLLABLE SSWAEJ) 5205 0xC427 쐧 (HANGUL SYLLABLE SSWAEC) 5206 0xC428 쐨 (HANGUL SYLLABLE SSWAEK) 5207 0xC429 쐩 (HANGUL SYLLABLE SSWAET) 5208 0xC42A 쐪 (HANGUL SYLLABLE SSWAEP) 5209 0xC42B 쐫 (HANGUL SYLLABLE SSWAEH) 5210 0xC42D 쐭 (HANGUL SYLLABLE SSOEG) 5211 0xC42E 쐮 (HANGUL SYLLABLE SSOEGG) 5212 0xC42F 쐯 (HANGUL SYLLABLE SSOEGS) 5213 0xC431 쐱 (HANGUL SYLLABLE SSOENJ) 5214 0xC432 쐲 (HANGUL SYLLABLE SSOENH) 5215 0xC433 쐳 (HANGUL SYLLABLE SSOED) 5216 0xC435 쐵 (HANGUL SYLLABLE SSOELG) 5217 0xC436 쐶 (HANGUL SYLLABLE SSOELM) 5218 0xC437 쐷 (HANGUL SYLLABLE SSOELB) 5219 0xC438 쐸 (HANGUL SYLLABLE SSOELS) 5220 0xC439 쐹 (HANGUL SYLLABLE SSOELT) 5221 0xC43A 쐺 (HANGUL SYLLABLE SSOELP) 5222 0xC43B 쐻 (HANGUL SYLLABLE SSOELH) 5223 0xC43E 쐾 (HANGUL SYLLABLE SSOEBS) 5224 0xC43F 쐿 (HANGUL SYLLABLE SSOES) 5225 0xC440 쑀 (HANGUL SYLLABLE SSOESS) 5226 0xC441 쑁 (HANGUL SYLLABLE SSOENG) 5227 0xC442 쑂 (HANGUL SYLLABLE SSOEJ) 5228 0xC443 쑃 (HANGUL SYLLABLE SSOEC) 5229 0xC444 쑄 (HANGUL SYLLABLE SSOEK) 5230 0xC445 쑅 (HANGUL SYLLABLE SSOET) 5231 0xC446 쑆 (HANGUL SYLLABLE SSOEP) 5232 0xC447 쑇 (HANGUL SYLLABLE SSOEH) 5233 0xC449 쑉 (HANGUL SYLLABLE SSYOG) 5234 0xC44A 쑊 (HANGUL SYLLABLE SSYOGG) 5235 0xC44B 쑋 (HANGUL SYLLABLE SSYOGS) 5236 0xC44C 쑌 (HANGUL SYLLABLE SSYON) 5237 0xC44D 쑍 (HANGUL SYLLABLE SSYONJ) 5238 0xC44E 쑎 (HANGUL SYLLABLE SSYONH) 5239 0xC44F 쑏 (HANGUL SYLLABLE SSYOD) 5240 0xC450 쑐 (HANGUL SYLLABLE SSYOL) 5241 0xC451 쑑 (HANGUL SYLLABLE SSYOLG) 5242 0xC452 쑒 (HANGUL SYLLABLE SSYOLM) 5243 0xC453 쑓 (HANGUL SYLLABLE SSYOLB) 5244 0xC454 쑔 (HANGUL SYLLABLE SSYOLS) 5245 0xC455 쑕 (HANGUL SYLLABLE SSYOLT) 5246 0xC456 쑖 (HANGUL SYLLABLE SSYOLP) 5247 0xC457 쑗 (HANGUL SYLLABLE SSYOLH) 5248 0xC458 쑘 (HANGUL SYLLABLE SSYOM) 5249 0xC459 쑙 (HANGUL SYLLABLE SSYOB) 5250 0xC45A 쑚 (HANGUL SYLLABLE SSYOBS) 5251 0xC45B 쑛 (HANGUL SYLLABLE SSYOS) 5252 0xC45C 쑜 (HANGUL SYLLABLE SSYOSS) 5253 0xC45D 쑝 (HANGUL SYLLABLE SSYONG) 5254 0xC45E 쑞 (HANGUL SYLLABLE SSYOJ) 5255 0xC45F 쑟 (HANGUL SYLLABLE SSYOC) 5256 0xC460 쑠 (HANGUL SYLLABLE SSYOK) 5257 0xC461 쑡 (HANGUL SYLLABLE SSYOT) 5258 0xC462 쑢 (HANGUL SYLLABLE SSYOP) 5259 0xC463 쑣 (HANGUL SYLLABLE SSYOH) 5260 0xC466 쑦 (HANGUL SYLLABLE SSUGG) 5261 0xC467 쑧 (HANGUL SYLLABLE SSUGS) 5262 0xC469 쑩 (HANGUL SYLLABLE SSUNJ) 5263 0xC46A 쑪 (HANGUL SYLLABLE SSUNH) 5264 0xC46B 쑫 (HANGUL SYLLABLE SSUD) 5265 0xC46D 쑭 (HANGUL SYLLABLE SSULG) 5266 0xC46E 쑮 (HANGUL SYLLABLE SSULM) 5267 0xC46F 쑯 (HANGUL SYLLABLE SSULB) 5268 0xC470 쑰 (HANGUL SYLLABLE SSULS) 5269 0xC471 쑱 (HANGUL SYLLABLE SSULT) 5270 0xC472 쑲 (HANGUL SYLLABLE SSULP) 5271 0xC473 쑳 (HANGUL SYLLABLE SSULH) 5272 0xC476 쑶 (HANGUL SYLLABLE SSUBS) 5273 0xC477 쑷 (HANGUL SYLLABLE SSUS) 5274 0xC478 쑸 (HANGUL SYLLABLE SSUSS) 5275 0xC47A 쑺 (HANGUL SYLLABLE SSUJ) 5276 0xC47B 쑻 (HANGUL SYLLABLE SSUC) 5277 0xC47C 쑼 (HANGUL SYLLABLE SSUK) 5278 0xC47D 쑽 (HANGUL SYLLABLE SSUT) 5279 0xC47E 쑾 (HANGUL SYLLABLE SSUP) 5280 0xC47F 쑿 (HANGUL SYLLABLE SSUH) 5281 0xC481 쒁 (HANGUL SYLLABLE SSWEOG) 5282 0xC482 쒂 (HANGUL SYLLABLE SSWEOGG) 5283 0xC483 쒃 (HANGUL SYLLABLE SSWEOGS) 5284 0xC484 쒄 (HANGUL SYLLABLE SSWEON) 5285 0xC485 쒅 (HANGUL SYLLABLE SSWEONJ) 5286 0xC486 쒆 (HANGUL SYLLABLE SSWEONH) 5287 0xC487 쒇 (HANGUL SYLLABLE SSWEOD) 5288 0xC488 쒈 (HANGUL SYLLABLE SSWEOL) 5289 0xC489 쒉 (HANGUL SYLLABLE SSWEOLG) 5290 0xC48A 쒊 (HANGUL SYLLABLE SSWEOLM) 5291 0xC48B 쒋 (HANGUL SYLLABLE SSWEOLB) 5292 0xC48C 쒌 (HANGUL SYLLABLE SSWEOLS) 5293 0xC48D 쒍 (HANGUL SYLLABLE SSWEOLT) 5294 0xC48E 쒎 (HANGUL SYLLABLE SSWEOLP) 5295 0xC48F 쒏 (HANGUL SYLLABLE SSWEOLH) 5296 0xC490 쒐 (HANGUL SYLLABLE SSWEOM) 5297 0xC491 쒑 (HANGUL SYLLABLE SSWEOB) 5298 0xC492 쒒 (HANGUL SYLLABLE SSWEOBS) 5299 0xC493 쒓 (HANGUL SYLLABLE SSWEOS) 5300 0xC495 쒕 (HANGUL SYLLABLE SSWEONG) 5301 0xC496 쒖 (HANGUL SYLLABLE SSWEOJ) 5302 0xC497 쒗 (HANGUL SYLLABLE SSWEOC) 5303 0xC498 쒘 (HANGUL SYLLABLE SSWEOK) 5304 0xC499 쒙 (HANGUL SYLLABLE SSWEOT) 5305 0xC49A 쒚 (HANGUL SYLLABLE SSWEOP) 5306 0xC49B 쒛 (HANGUL SYLLABLE SSWEOH) 5307 0xC49D 쒝 (HANGUL SYLLABLE SSWEG) 5308 0xC49E 쒞 (HANGUL SYLLABLE SSWEGG) 5309 0xC49F 쒟 (HANGUL SYLLABLE SSWEGS) 5310 0xC4A0 쒠 (HANGUL SYLLABLE SSWEN) 5311 0xC4A1 쒡 (HANGUL SYLLABLE SSWENJ) 5312 0xC4A2 쒢 (HANGUL SYLLABLE SSWENH) 5313 0xC4A3 쒣 (HANGUL SYLLABLE SSWED) 5314 0xC4A4 쒤 (HANGUL SYLLABLE SSWEL) 5315 0xC4A5 쒥 (HANGUL SYLLABLE SSWELG) 5316 0xC4A6 쒦 (HANGUL SYLLABLE SSWELM) 5317 0xC4A7 쒧 (HANGUL SYLLABLE SSWELB) 5318 0xC4A8 쒨 (HANGUL SYLLABLE SSWELS) 5319 0xC4A9 쒩 (HANGUL SYLLABLE SSWELT) 5320 0xC4AA 쒪 (HANGUL SYLLABLE SSWELP) 5321 0xC4AB 쒫 (HANGUL SYLLABLE SSWELH) 5322 0xC4AC 쒬 (HANGUL SYLLABLE SSWEM) 5323 0xC4AD 쒭 (HANGUL SYLLABLE SSWEB) 5324 0xC4AE 쒮 (HANGUL SYLLABLE SSWEBS) 5325 0xC4AF 쒯 (HANGUL SYLLABLE SSWES) 5326 0xC4B0 쒰 (HANGUL SYLLABLE SSWESS) 5327 0xC4B1 쒱 (HANGUL SYLLABLE SSWENG) 5328 0xC4B2 쒲 (HANGUL SYLLABLE SSWEJ) 5329 0xC4B3 쒳 (HANGUL SYLLABLE SSWEC) 5330 0xC4B4 쒴 (HANGUL SYLLABLE SSWEK) 5331 0xC4B5 쒵 (HANGUL SYLLABLE SSWET) 5332 0xC4B6 쒶 (HANGUL SYLLABLE SSWEP) 5333 0xC4B7 쒷 (HANGUL SYLLABLE SSWEH) 5334 0xC4B9 쒹 (HANGUL SYLLABLE SSWIG) 5335 0xC4BA 쒺 (HANGUL SYLLABLE SSWIGG) 5336 0xC4BB 쒻 (HANGUL SYLLABLE SSWIGS) 5337 0xC4BD 쒽 (HANGUL SYLLABLE SSWINJ) 5338 0xC4BE 쒾 (HANGUL SYLLABLE SSWINH) 5339 0xC4BF 쒿 (HANGUL SYLLABLE SSWID) 5340 0xC4C0 쓀 (HANGUL SYLLABLE SSWIL) 5341 0xC4C1 쓁 (HANGUL SYLLABLE SSWILG) 5342 0xC4C2 쓂 (HANGUL SYLLABLE SSWILM) 5343 0xC4C3 쓃 (HANGUL SYLLABLE SSWILB) 5344 0xC4C4 쓄 (HANGUL SYLLABLE SSWILS) 5345 0xC4C5 쓅 (HANGUL SYLLABLE SSWILT) 5352 0xC4C6 쓆 (HANGUL SYLLABLE SSWILP) 5353 0xC4C7 쓇 (HANGUL SYLLABLE SSWILH) 5354 0xC4C8 쓈 (HANGUL SYLLABLE SSWIM) 5355 0xC4C9 쓉 (HANGUL SYLLABLE SSWIB) 5356 0xC4CA 쓊 (HANGUL SYLLABLE SSWIBS) 5357 0xC4CB 쓋 (HANGUL SYLLABLE SSWIS) 5358 0xC4CC 쓌 (HANGUL SYLLABLE SSWISS) 5359 0xC4CD 쓍 (HANGUL SYLLABLE SSWING) 5360 0xC4CE 쓎 (HANGUL SYLLABLE SSWIJ) 5361 0xC4CF 쓏 (HANGUL SYLLABLE SSWIC) 5362 0xC4D0 쓐 (HANGUL SYLLABLE SSWIK) 5363 0xC4D1 쓑 (HANGUL SYLLABLE SSWIT) 5364 0xC4D2 쓒 (HANGUL SYLLABLE SSWIP) 5365 0xC4D3 쓓 (HANGUL SYLLABLE SSWIH) 5366 0xC4D4 쓔 (HANGUL SYLLABLE SSYU) 5367 0xC4D5 쓕 (HANGUL SYLLABLE SSYUG) 5368 0xC4D6 쓖 (HANGUL SYLLABLE SSYUGG) 5369 0xC4D7 쓗 (HANGUL SYLLABLE SSYUGS) 5370 0xC4D8 쓘 (HANGUL SYLLABLE SSYUN) 5371 0xC4D9 쓙 (HANGUL SYLLABLE SSYUNJ) 5372 0xC4DA 쓚 (HANGUL SYLLABLE SSYUNH) 5373 0xC4DB 쓛 (HANGUL SYLLABLE SSYUD) 5374 0xC4DC 쓜 (HANGUL SYLLABLE SSYUL) 5375 0xC4DD 쓝 (HANGUL SYLLABLE SSYULG) 5376 0xC4DE 쓞 (HANGUL SYLLABLE SSYULM) 5377 0xC4DF 쓟 (HANGUL SYLLABLE SSYULB) 5384 0xC4E0 쓠 (HANGUL SYLLABLE SSYULS) 5385 0xC4E1 쓡 (HANGUL SYLLABLE SSYULT) 5386 0xC4E2 쓢 (HANGUL SYLLABLE SSYULP) 5387 0xC4E3 쓣 (HANGUL SYLLABLE SSYULH) 5388 0xC4E4 쓤 (HANGUL SYLLABLE SSYUM) 5389 0xC4E5 쓥 (HANGUL SYLLABLE SSYUB) 5390 0xC4E6 쓦 (HANGUL SYLLABLE SSYUBS) 5391 0xC4E7 쓧 (HANGUL SYLLABLE SSYUS) 5392 0xC4E8 쓨 (HANGUL SYLLABLE SSYUSS) 5393 0xC4EA 쓪 (HANGUL SYLLABLE SSYUJ) 5394 0xC4EB 쓫 (HANGUL SYLLABLE SSYUC) 5395 0xC4EC 쓬 (HANGUL SYLLABLE SSYUK) 5396 0xC4ED 쓭 (HANGUL SYLLABLE SSYUT) 5397 0xC4EE 쓮 (HANGUL SYLLABLE SSYUP) 5398 0xC4EF 쓯 (HANGUL SYLLABLE SSYUH) 5399 0xC4F2 쓲 (HANGUL SYLLABLE SSEUGG) 5400 0xC4F3 쓳 (HANGUL SYLLABLE SSEUGS) 5401 0xC4F5 쓵 (HANGUL SYLLABLE SSEUNJ) 5402 0xC4F6 쓶 (HANGUL SYLLABLE SSEUNH) 5403 0xC4F7 쓷 (HANGUL SYLLABLE SSEUD) 5404 0xC4F9 쓹 (HANGUL SYLLABLE SSEULG) 5405 0xC4FB 쓻 (HANGUL SYLLABLE SSEULB) 5406 0xC4FC 쓼 (HANGUL SYLLABLE SSEULS) 5407 0xC4FD 쓽 (HANGUL SYLLABLE SSEULT) 5408 0xC4FE 쓾 (HANGUL SYLLABLE SSEULP) 5409 0xC502 씂 (HANGUL SYLLABLE SSEUBS) 5410 0xC503 씃 (HANGUL SYLLABLE SSEUS) 5411 0xC504 씄 (HANGUL SYLLABLE SSEUSS) 5412 0xC505 씅 (HANGUL SYLLABLE SSEUNG) 5413 0xC506 씆 (HANGUL SYLLABLE SSEUJ) 5414 0xC507 씇 (HANGUL SYLLABLE SSEUC) 5415 0xC508 씈 (HANGUL SYLLABLE SSEUK) 5416 0xC509 씉 (HANGUL SYLLABLE SSEUT) 5417 0xC50A 씊 (HANGUL SYLLABLE SSEUP) 5418 0xC50B 씋 (HANGUL SYLLABLE SSEUH) 5419 0xC50D 씍 (HANGUL SYLLABLE SSYIG) 5420 0xC50E 씎 (HANGUL SYLLABLE SSYIGG) 5421 0xC50F 씏 (HANGUL SYLLABLE SSYIGS) 5422 0xC511 씑 (HANGUL SYLLABLE SSYINJ) 5423 0xC512 씒 (HANGUL SYLLABLE SSYINH) 5424 0xC513 씓 (HANGUL SYLLABLE SSYID) 5425 0xC515 씕 (HANGUL SYLLABLE SSYILG) 5426 0xC516 씖 (HANGUL SYLLABLE SSYILM) 5427 0xC517 씗 (HANGUL SYLLABLE SSYILB) 5428 0xC518 씘 (HANGUL SYLLABLE SSYILS) 5429 0xC519 씙 (HANGUL SYLLABLE SSYILT) 5430 0xC51A 씚 (HANGUL SYLLABLE SSYILP) 5431 0xC51B 씛 (HANGUL SYLLABLE SSYILH) 5432 0xC51D 씝 (HANGUL SYLLABLE SSYIB) 5433 0xC51E 씞 (HANGUL SYLLABLE SSYIBS) 5434 0xC51F 씟 (HANGUL SYLLABLE SSYIS) 5435 0xC520 씠 (HANGUL SYLLABLE SSYISS) 5436 0xC521 씡 (HANGUL SYLLABLE SSYING) 5437 0xC522 씢 (HANGUL SYLLABLE SSYIJ) 5438 0xC523 씣 (HANGUL SYLLABLE SSYIC) 5439 0xC524 씤 (HANGUL SYLLABLE SSYIK) 5440 0xC525 씥 (HANGUL SYLLABLE SSYIT) 5441 0xC526 씦 (HANGUL SYLLABLE SSYIP) 5442 0xC527 씧 (HANGUL SYLLABLE SSYIH) 5443 0xC52A 씪 (HANGUL SYLLABLE SSIGG) 5444 0xC52B 씫 (HANGUL SYLLABLE SSIGS) 5445 0xC52D 씭 (HANGUL SYLLABLE SSINJ) 5446 0xC52E 씮 (HANGUL SYLLABLE SSINH) 5447 0xC52F 씯 (HANGUL SYLLABLE SSID) 5448 0xC531 씱 (HANGUL SYLLABLE SSILG) 5449 0xC532 씲 (HANGUL SYLLABLE SSILM) 5450 0xC533 씳 (HANGUL SYLLABLE SSILB) 5451 0xC534 씴 (HANGUL SYLLABLE SSILS) 5452 0xC535 씵 (HANGUL SYLLABLE SSILT) 5453 0xC536 씶 (HANGUL SYLLABLE SSILP) 5454 0xC537 씷 (HANGUL SYLLABLE SSILH) 5455 0xC53A 씺 (HANGUL SYLLABLE SSIBS) 5456 0xC53C 씼 (HANGUL SYLLABLE SSISS) 5457 0xC53E 씾 (HANGUL SYLLABLE SSIJ) 5458 0xC53F 씿 (HANGUL SYLLABLE SSIC) 5459 0xC540 앀 (HANGUL SYLLABLE SSIK) 5460 0xC541 앁 (HANGUL SYLLABLE SSIT) 5461 0xC542 앂 (HANGUL SYLLABLE SSIP) 5462 0xC543 앃 (HANGUL SYLLABLE SSIH) 5463 0xC546 앆 (HANGUL SYLLABLE AGG) 5464 0xC547 앇 (HANGUL SYLLABLE AGS) 5465 0xC54B 앋 (HANGUL SYLLABLE AD) 5466 0xC54F 앏 (HANGUL SYLLABLE ALB) 5467 0xC550 앐 (HANGUL SYLLABLE ALS) 5468 0xC551 앑 (HANGUL SYLLABLE ALT) 5469 0xC552 앒 (HANGUL SYLLABLE ALP) 5470 0xC556 앖 (HANGUL SYLLABLE ABS) 5471 0xC55A 앚 (HANGUL SYLLABLE AJ) 5472 0xC55B 앛 (HANGUL SYLLABLE AC) 5473 0xC55C 앜 (HANGUL SYLLABLE AK) 5474 0xC55F 앟 (HANGUL SYLLABLE AH) 5475 0xC562 앢 (HANGUL SYLLABLE AEGG) 5476 0xC563 앣 (HANGUL SYLLABLE AEGS) 5477 0xC565 앥 (HANGUL SYLLABLE AENJ) 5478 0xC566 앦 (HANGUL SYLLABLE AENH) 5479 0xC567 앧 (HANGUL SYLLABLE AED) 5480 0xC569 앩 (HANGUL SYLLABLE AELG) 5481 0xC56A 앪 (HANGUL SYLLABLE AELM) 5482 0xC56B 앫 (HANGUL SYLLABLE AELB) 5483 0xC56C 앬 (HANGUL SYLLABLE AELS) 5484 0xC56D 앭 (HANGUL SYLLABLE AELT) 5485 0xC56E 앮 (HANGUL SYLLABLE AELP) 5486 0xC56F 앯 (HANGUL SYLLABLE AELH) 5487 0xC572 앲 (HANGUL SYLLABLE AEBS) 5488 0xC576 앶 (HANGUL SYLLABLE AEJ) 5489 0xC577 앷 (HANGUL SYLLABLE AEC) 5490 0xC578 앸 (HANGUL SYLLABLE AEK) 5491 0xC579 앹 (HANGUL SYLLABLE AET) 5492 0xC57A 앺 (HANGUL SYLLABLE AEP) 5493 0xC57B 앻 (HANGUL SYLLABLE AEH) 5494 0xC57E 앾 (HANGUL SYLLABLE YAGG) 5495 0xC57F 앿 (HANGUL SYLLABLE YAGS) 5496 0xC581 얁 (HANGUL SYLLABLE YANJ) 5497 0xC582 얂 (HANGUL SYLLABLE YANH) 5498 0xC583 얃 (HANGUL SYLLABLE YAD) 5499 0xC585 얅 (HANGUL SYLLABLE YALG) 5500 0xC586 얆 (HANGUL SYLLABLE YALM) 5501 0xC588 얈 (HANGUL SYLLABLE YALS) 5502 0xC589 얉 (HANGUL SYLLABLE YALT) 5503 0xC58A 얊 (HANGUL SYLLABLE YALP) 5504 0xC58B 얋 (HANGUL SYLLABLE YALH) 5505 0xC58E 얎 (HANGUL SYLLABLE YABS) 5506 0xC590 얐 (HANGUL SYLLABLE YASS) 5507 0xC592 얒 (HANGUL SYLLABLE YAJ) 5508 0xC593 얓 (HANGUL SYLLABLE YAC) 5509 0xC594 얔 (HANGUL SYLLABLE YAK) 5510 0xC596 얖 (HANGUL SYLLABLE YAP) 5511 0xC599 얙 (HANGUL SYLLABLE YAEG) 5512 0xC59A 얚 (HANGUL SYLLABLE YAEGG) 5513 0xC59B 얛 (HANGUL SYLLABLE YAEGS) 5514 0xC59D 얝 (HANGUL SYLLABLE YAENJ) 5515 0xC59E 얞 (HANGUL SYLLABLE YAENH) 5516 0xC59F 얟 (HANGUL SYLLABLE YAED) 5517 0xC5A1 얡 (HANGUL SYLLABLE YAELG) 5518 0xC5A2 얢 (HANGUL SYLLABLE YAELM) 5519 0xC5A3 얣 (HANGUL SYLLABLE YAELB) 5520 0xC5A4 얤 (HANGUL SYLLABLE YAELS) 5521 0xC5A5 얥 (HANGUL SYLLABLE YAELT) 5522 0xC5A6 얦 (HANGUL SYLLABLE YAELP) 5523 0xC5A7 얧 (HANGUL SYLLABLE YAELH) 5524 0xC5A8 얨 (HANGUL SYLLABLE YAEM) 5525 0xC5AA 얪 (HANGUL SYLLABLE YAEBS) 5526 0xC5AB 얫 (HANGUL SYLLABLE YAES) 5527 0xC5AC 얬 (HANGUL SYLLABLE YAESS) 5528 0xC5AD 얭 (HANGUL SYLLABLE YAENG) 5529 0xC5AE 얮 (HANGUL SYLLABLE YAEJ) 5530 0xC5AF 얯 (HANGUL SYLLABLE YAEC) 5531 0xC5B0 얰 (HANGUL SYLLABLE YAEK) 5532 0xC5B1 얱 (HANGUL SYLLABLE YAET) 5533 0xC5B2 얲 (HANGUL SYLLABLE YAEP) 5534 0xC5B3 얳 (HANGUL SYLLABLE YAEH) 5535 0xC5B6 얶 (HANGUL SYLLABLE EOGG) 5542 0xC5B7 얷 (HANGUL SYLLABLE EOGS) 5543 0xC5BA 얺 (HANGUL SYLLABLE EONH) 5544 0xC5BF 얿 (HANGUL SYLLABLE EOLB) 5545 0xC5C0 엀 (HANGUL SYLLABLE EOLS) 5546 0xC5C1 엁 (HANGUL SYLLABLE EOLT) 5547 0xC5C2 엂 (HANGUL SYLLABLE EOLP) 5548 0xC5C3 엃 (HANGUL SYLLABLE EOLH) 5549 0xC5CB 엋 (HANGUL SYLLABLE EOC) 5550 0xC5CD 엍 (HANGUL SYLLABLE EOT) 5551 0xC5CF 엏 (HANGUL SYLLABLE EOH) 5552 0xC5D2 엒 (HANGUL SYLLABLE EGG) 5553 0xC5D3 엓 (HANGUL SYLLABLE EGS) 5554 0xC5D5 엕 (HANGUL SYLLABLE ENJ) 5555 0xC5D6 엖 (HANGUL SYLLABLE ENH) 5556 0xC5D7 엗 (HANGUL SYLLABLE ED) 5557 0xC5D9 엙 (HANGUL SYLLABLE ELG) 5558 0xC5DA 엚 (HANGUL SYLLABLE ELM) 5559 0xC5DB 엛 (HANGUL SYLLABLE ELB) 5560 0xC5DC 엜 (HANGUL SYLLABLE ELS) 5561 0xC5DD 엝 (HANGUL SYLLABLE ELT) 5562 0xC5DE 엞 (HANGUL SYLLABLE ELP) 5563 0xC5DF 엟 (HANGUL SYLLABLE ELH) 5564 0xC5E2 엢 (HANGUL SYLLABLE EBS) 5565 0xC5E4 엤 (HANGUL SYLLABLE ESS) 5566 0xC5E6 엦 (HANGUL SYLLABLE EJ) 5567 0xC5E7 엧 (HANGUL SYLLABLE EC) 5574 0xC5E8 엨 (HANGUL SYLLABLE EK) 5575 0xC5E9 엩 (HANGUL SYLLABLE ET) 5576 0xC5EA 엪 (HANGUL SYLLABLE EP) 5577 0xC5EB 엫 (HANGUL SYLLABLE EH) 5578 0xC5EF 엯 (HANGUL SYLLABLE YEOGS) 5579 0xC5F1 엱 (HANGUL SYLLABLE YEONJ) 5580 0xC5F2 엲 (HANGUL SYLLABLE YEONH) 5581 0xC5F3 엳 (HANGUL SYLLABLE YEOD) 5582 0xC5F5 엵 (HANGUL SYLLABLE YEOLG) 5583 0xC5F8 엸 (HANGUL SYLLABLE YEOLS) 5584 0xC5F9 엹 (HANGUL SYLLABLE YEOLT) 5585 0xC5FA 엺 (HANGUL SYLLABLE YEOLP) 5586 0xC5FB 엻 (HANGUL SYLLABLE YEOLH) 5587 0xC602 옂 (HANGUL SYLLABLE YEOJ) 5588 0xC603 옃 (HANGUL SYLLABLE YEOC) 5589 0xC604 옄 (HANGUL SYLLABLE YEOK) 5590 0xC609 옉 (HANGUL SYLLABLE YEG) 5591 0xC60A 옊 (HANGUL SYLLABLE YEGG) 5592 0xC60B 옋 (HANGUL SYLLABLE YEGS) 5593 0xC60D 옍 (HANGUL SYLLABLE YENJ) 5594 0xC60E 옎 (HANGUL SYLLABLE YENH) 5595 0xC60F 옏 (HANGUL SYLLABLE YED) 5596 0xC611 옑 (HANGUL SYLLABLE YELG) 5597 0xC612 옒 (HANGUL SYLLABLE YELM) 5598 0xC613 옓 (HANGUL SYLLABLE YELB) 5599 0xC614 옔 (HANGUL SYLLABLE YELS) 5600 0xC615 옕 (HANGUL SYLLABLE YELT) 5601 0xC616 옖 (HANGUL SYLLABLE YELP) 5602 0xC617 옗 (HANGUL SYLLABLE YELH) 5603 0xC61A 옚 (HANGUL SYLLABLE YEBS) 5604 0xC61D 옝 (HANGUL SYLLABLE YENG) 5605 0xC61E 옞 (HANGUL SYLLABLE YEJ) 5606 0xC61F 옟 (HANGUL SYLLABLE YEC) 5607 0xC620 옠 (HANGUL SYLLABLE YEK) 5608 0xC621 옡 (HANGUL SYLLABLE YET) 5609 0xC622 옢 (HANGUL SYLLABLE YEP) 5610 0xC623 옣 (HANGUL SYLLABLE YEH) 5611 0xC626 옦 (HANGUL SYLLABLE OGG) 5612 0xC627 옧 (HANGUL SYLLABLE OGS) 5613 0xC629 옩 (HANGUL SYLLABLE ONJ) 5614 0xC62A 옪 (HANGUL SYLLABLE ONH) 5615 0xC62B 옫 (HANGUL SYLLABLE OD) 5616 0xC62F 옯 (HANGUL SYLLABLE OLB) 5617 0xC631 옱 (HANGUL SYLLABLE OLT) 5618 0xC632 옲 (HANGUL SYLLABLE OLP) 5619 0xC636 옶 (HANGUL SYLLABLE OBS) 5620 0xC638 옸 (HANGUL SYLLABLE OSS) 5621 0xC63A 옺 (HANGUL SYLLABLE OJ) 5622 0xC63C 옼 (HANGUL SYLLABLE OK) 5623 0xC63D 옽 (HANGUL SYLLABLE OT) 5624 0xC63E 옾 (HANGUL SYLLABLE OP) 5625 0xC63F 옿 (HANGUL SYLLABLE OH) 5626 0xC642 왂 (HANGUL SYLLABLE WAGG) 5627 0xC643 왃 (HANGUL SYLLABLE WAGS) 5628 0xC645 왅 (HANGUL SYLLABLE WANJ) 5629 0xC646 왆 (HANGUL SYLLABLE WANH) 5630 0xC647 왇 (HANGUL SYLLABLE WAD) 5631 0xC649 왉 (HANGUL SYLLABLE WALG) 5632 0xC64A 왊 (HANGUL SYLLABLE WALM) 5633 0xC64B 왋 (HANGUL SYLLABLE WALB) 5634 0xC64C 왌 (HANGUL SYLLABLE WALS) 5635 0xC64D 왍 (HANGUL SYLLABLE WALT) 5636 0xC64E 왎 (HANGUL SYLLABLE WALP) 5637 0xC64F 왏 (HANGUL SYLLABLE WALH) 5638 0xC652 왒 (HANGUL SYLLABLE WABS) 5639 0xC656 왖 (HANGUL SYLLABLE WAJ) 5640 0xC657 왗 (HANGUL SYLLABLE WAC) 5641 0xC658 왘 (HANGUL SYLLABLE WAK) 5642 0xC659 왙 (HANGUL SYLLABLE WAT) 5643 0xC65A 왚 (HANGUL SYLLABLE WAP) 5644 0xC65B 왛 (HANGUL SYLLABLE WAH) 5645 0xC65E 왞 (HANGUL SYLLABLE WAEGG) 5646 0xC65F 왟 (HANGUL SYLLABLE WAEGS) 5647 0xC661 왡 (HANGUL SYLLABLE WAENJ) 5648 0xC662 왢 (HANGUL SYLLABLE WAENH) 5649 0xC663 왣 (HANGUL SYLLABLE WAED) 5650 0xC664 왤 (HANGUL SYLLABLE WAEL) 5651 0xC665 왥 (HANGUL SYLLABLE WAELG) 5652 0xC666 왦 (HANGUL SYLLABLE WAELM) 5653 0xC667 왧 (HANGUL SYLLABLE WAELB) 5654 0xC668 왨 (HANGUL SYLLABLE WAELS) 5655 0xC669 왩 (HANGUL SYLLABLE WAELT) 5656 0xC66A 왪 (HANGUL SYLLABLE WAELP) 5657 0xC66B 왫 (HANGUL SYLLABLE WAELH) 5658 0xC66D 왭 (HANGUL SYLLABLE WAEB) 5659 0xC66E 왮 (HANGUL SYLLABLE WAEBS) 5660 0xC670 왰 (HANGUL SYLLABLE WAESS) 5661 0xC672 왲 (HANGUL SYLLABLE WAEJ) 5662 0xC673 왳 (HANGUL SYLLABLE WAEC) 5663 0xC674 왴 (HANGUL SYLLABLE WAEK) 5664 0xC675 왵 (HANGUL SYLLABLE WAET) 5665 0xC676 왶 (HANGUL SYLLABLE WAEP) 5666 0xC677 왷 (HANGUL SYLLABLE WAEH) 5667 0xC67A 왺 (HANGUL SYLLABLE OEGG) 5668 0xC67B 왻 (HANGUL SYLLABLE OEGS) 5669 0xC67D 왽 (HANGUL SYLLABLE OENJ) 5670 0xC67E 왾 (HANGUL SYLLABLE OENH) 5671 0xC67F 왿 (HANGUL SYLLABLE OED) 5672 0xC681 욁 (HANGUL SYLLABLE OELG) 5673 0xC682 욂 (HANGUL SYLLABLE OELM) 5674 0xC683 욃 (HANGUL SYLLABLE OELB) 5675 0xC684 욄 (HANGUL SYLLABLE OELS) 5676 0xC685 욅 (HANGUL SYLLABLE OELT) 5677 0xC686 욆 (HANGUL SYLLABLE OELP) 5678 0xC687 욇 (HANGUL SYLLABLE OELH) 5679 0xC68A 욊 (HANGUL SYLLABLE OEBS) 5680 0xC68C 욌 (HANGUL SYLLABLE OESS) 5681 0xC68E 욎 (HANGUL SYLLABLE OEJ) 5682 0xC68F 욏 (HANGUL SYLLABLE OEC) 5683 0xC690 욐 (HANGUL SYLLABLE OEK) 5684 0xC691 욑 (HANGUL SYLLABLE OET) 5685 0xC692 욒 (HANGUL SYLLABLE OEP) 5686 0xC693 욓 (HANGUL SYLLABLE OEH) 5687 0xC696 욖 (HANGUL SYLLABLE YOGG) 5688 0xC697 욗 (HANGUL SYLLABLE YOGS) 5689 0xC699 욙 (HANGUL SYLLABLE YONJ) 5690 0xC69A 욚 (HANGUL SYLLABLE YONH) 5691 0xC69B 욛 (HANGUL SYLLABLE YOD) 5692 0xC69D 욝 (HANGUL SYLLABLE YOLG) 5693 0xC69E 욞 (HANGUL SYLLABLE YOLM) 5694 0xC69F 욟 (HANGUL SYLLABLE YOLB) 5695 0xC6A0 욠 (HANGUL SYLLABLE YOLS) 5696 0xC6A1 욡 (HANGUL SYLLABLE YOLT) 5697 0xC6A2 욢 (HANGUL SYLLABLE YOLP) 5698 0xC6A3 욣 (HANGUL SYLLABLE YOLH) 5699 0xC6A6 욦 (HANGUL SYLLABLE YOBS) 5700 0xC6A8 욨 (HANGUL SYLLABLE YOSS) 5701 0xC6AA 욪 (HANGUL SYLLABLE YOJ) 5702 0xC6AB 욫 (HANGUL SYLLABLE YOC) 5703 0xC6AC 욬 (HANGUL SYLLABLE YOK) 5704 0xC6AD 욭 (HANGUL SYLLABLE YOT) 5705 0xC6AE 욮 (HANGUL SYLLABLE YOP) 5706 0xC6AF 욯 (HANGUL SYLLABLE YOH) 5707 0xC6B2 욲 (HANGUL SYLLABLE UGG) 5708 0xC6B3 욳 (HANGUL SYLLABLE UGS) 5709 0xC6B5 욵 (HANGUL SYLLABLE UNJ) 5710 0xC6B6 욶 (HANGUL SYLLABLE UNH) 5711 0xC6B7 욷 (HANGUL SYLLABLE UD) 5712 0xC6BB 욻 (HANGUL SYLLABLE ULB) 5713 0xC6BC 욼 (HANGUL SYLLABLE ULS) 5714 0xC6BD 욽 (HANGUL SYLLABLE ULT) 5715 0xC6BE 욾 (HANGUL SYLLABLE ULP) 5716 0xC6BF 욿 (HANGUL SYLLABLE ULH) 5717 0xC6C2 웂 (HANGUL SYLLABLE UBS) 5718 0xC6C4 웄 (HANGUL SYLLABLE USS) 5719 0xC6C6 웆 (HANGUL SYLLABLE UJ) 5720 0xC6C7 웇 (HANGUL SYLLABLE UC) 5721 0xC6C8 웈 (HANGUL SYLLABLE UK) 5722 0xC6C9 웉 (HANGUL SYLLABLE UT) 5723 0xC6CA 웊 (HANGUL SYLLABLE UP) 5724 0xC6CB 웋 (HANGUL SYLLABLE UH) 5725 0xC6CE 웎 (HANGUL SYLLABLE WEOGG) 5732 0xC6CF 웏 (HANGUL SYLLABLE WEOGS) 5733 0xC6D1 웑 (HANGUL SYLLABLE WEONJ) 5734 0xC6D2 웒 (HANGUL SYLLABLE WEONH) 5735 0xC6D3 웓 (HANGUL SYLLABLE WEOD) 5736 0xC6D5 웕 (HANGUL SYLLABLE WEOLG) 5737 0xC6D6 웖 (HANGUL SYLLABLE WEOLM) 5738 0xC6D7 웗 (HANGUL SYLLABLE WEOLB) 5739 0xC6D8 웘 (HANGUL SYLLABLE WEOLS) 5740 0xC6D9 웙 (HANGUL SYLLABLE WEOLT) 5741 0xC6DA 웚 (HANGUL SYLLABLE WEOLP) 5742 0xC6DB 웛 (HANGUL SYLLABLE WEOLH) 5743 0xC6DE 웞 (HANGUL SYLLABLE WEOBS) 5744 0xC6DF 웟 (HANGUL SYLLABLE WEOS) 5745 0xC6E2 웢 (HANGUL SYLLABLE WEOJ) 5746 0xC6E3 웣 (HANGUL SYLLABLE WEOC) 5747 0xC6E4 웤 (HANGUL SYLLABLE WEOK) 5748 0xC6E5 웥 (HANGUL SYLLABLE WEOT) 5749 0xC6E6 웦 (HANGUL SYLLABLE WEOP) 5750 0xC6E7 웧 (HANGUL SYLLABLE WEOH) 5751 0xC6EA 웪 (HANGUL SYLLABLE WEGG) 5752 0xC6EB 웫 (HANGUL SYLLABLE WEGS) 5753 0xC6ED 웭 (HANGUL SYLLABLE WENJ) 5754 0xC6EE 웮 (HANGUL SYLLABLE WENH) 5755 0xC6EF 웯 (HANGUL SYLLABLE WED) 5756 0xC6F1 웱 (HANGUL SYLLABLE WELG) 5757 0xC6F2 웲 (HANGUL SYLLABLE WELM) 5764 0xC6F3 웳 (HANGUL SYLLABLE WELB) 5765 0xC6F4 웴 (HANGUL SYLLABLE WELS) 5766 0xC6F5 웵 (HANGUL SYLLABLE WELT) 5767 0xC6F6 웶 (HANGUL SYLLABLE WELP) 5768 0xC6F7 웷 (HANGUL SYLLABLE WELH) 5769 0xC6FA 웺 (HANGUL SYLLABLE WEBS) 5770 0xC6FB 웻 (HANGUL SYLLABLE WES) 5771 0xC6FC 웼 (HANGUL SYLLABLE WESS) 5772 0xC6FE 웾 (HANGUL SYLLABLE WEJ) 5773 0xC6FF 웿 (HANGUL SYLLABLE WEC) 5774 0xC700 윀 (HANGUL SYLLABLE WEK) 5775 0xC701 윁 (HANGUL SYLLABLE WET) 5776 0xC702 윂 (HANGUL SYLLABLE WEP) 5777 0xC703 윃 (HANGUL SYLLABLE WEH) 5778 0xC706 윆 (HANGUL SYLLABLE WIGG) 5779 0xC707 윇 (HANGUL SYLLABLE WIGS) 5780 0xC709 윉 (HANGUL SYLLABLE WINJ) 5781 0xC70A 윊 (HANGUL SYLLABLE WINH) 5782 0xC70B 윋 (HANGUL SYLLABLE WID) 5783 0xC70D 윍 (HANGUL SYLLABLE WILG) 5784 0xC70E 윎 (HANGUL SYLLABLE WILM) 5785 0xC70F 윏 (HANGUL SYLLABLE WILB) 5786 0xC710 윐 (HANGUL SYLLABLE WILS) 5787 0xC711 윑 (HANGUL SYLLABLE WILT) 5788 0xC712 윒 (HANGUL SYLLABLE WILP) 5789 0xC713 윓 (HANGUL SYLLABLE WILH) 5790 0xC716 윖 (HANGUL SYLLABLE WIBS) 5791 0xC718 윘 (HANGUL SYLLABLE WISS) 5792 0xC71A 윚 (HANGUL SYLLABLE WIJ) 5793 0xC71B 윛 (HANGUL SYLLABLE WIC) 5794 0xC71C 윜 (HANGUL SYLLABLE WIK) 5795 0xC71D 윝 (HANGUL SYLLABLE WIT) 5796 0xC71E 윞 (HANGUL SYLLABLE WIP) 5797 0xC71F 윟 (HANGUL SYLLABLE WIH) 5798 0xC722 윢 (HANGUL SYLLABLE YUGG) 5799 0xC723 윣 (HANGUL SYLLABLE YUGS) 5800 0xC725 윥 (HANGUL SYLLABLE YUNJ) 5801 0xC726 윦 (HANGUL SYLLABLE YUNH) 5802 0xC727 윧 (HANGUL SYLLABLE YUD) 5803 0xC729 윩 (HANGUL SYLLABLE YULG) 5804 0xC72A 윪 (HANGUL SYLLABLE YULM) 5805 0xC72B 윫 (HANGUL SYLLABLE YULB) 5806 0xC72C 윬 (HANGUL SYLLABLE YULS) 5807 0xC72D 윭 (HANGUL SYLLABLE YULT) 5808 0xC72E 윮 (HANGUL SYLLABLE YULP) 5809 0xC72F 윯 (HANGUL SYLLABLE YULH) 5810 0xC732 윲 (HANGUL SYLLABLE YUBS) 5811 0xC734 윴 (HANGUL SYLLABLE YUSS) 5812 0xC736 윶 (HANGUL SYLLABLE YUJ) 5813 0xC738 윸 (HANGUL SYLLABLE YUK) 5814 0xC739 윹 (HANGUL SYLLABLE YUT) 5815 0xC73A 윺 (HANGUL SYLLABLE YUP) 5816 0xC73B 윻 (HANGUL SYLLABLE YUH) 5817 0xC73E 윾 (HANGUL SYLLABLE EUGG) 5818 0xC73F 윿 (HANGUL SYLLABLE EUGS) 5819 0xC741 읁 (HANGUL SYLLABLE EUNJ) 5820 0xC742 읂 (HANGUL SYLLABLE EUNH) 5821 0xC743 읃 (HANGUL SYLLABLE EUD) 5822 0xC745 읅 (HANGUL SYLLABLE EULG) 5823 0xC746 읆 (HANGUL SYLLABLE EULM) 5824 0xC747 읇 (HANGUL SYLLABLE EULB) 5825 0xC748 읈 (HANGUL SYLLABLE EULS) 5826 0xC749 읉 (HANGUL SYLLABLE EULT) 5827 0xC74B 읋 (HANGUL SYLLABLE EULH) 5828 0xC74E 읎 (HANGUL SYLLABLE EUBS) 5829 0xC750 읐 (HANGUL SYLLABLE EUSS) 5830 0xC759 읙 (HANGUL SYLLABLE YIG) 5831 0xC75A 읚 (HANGUL SYLLABLE YIGG) 5832 0xC75B 읛 (HANGUL SYLLABLE YIGS) 5833 0xC75D 읝 (HANGUL SYLLABLE YINJ) 5834 0xC75E 읞 (HANGUL SYLLABLE YINH) 5835 0xC75F 읟 (HANGUL SYLLABLE YID) 5836 0xC761 읡 (HANGUL SYLLABLE YILG) 5837 0xC762 읢 (HANGUL SYLLABLE YILM) 5838 0xC763 읣 (HANGUL SYLLABLE YILB) 5839 0xC764 읤 (HANGUL SYLLABLE YILS) 5840 0xC765 읥 (HANGUL SYLLABLE YILT) 5841 0xC766 읦 (HANGUL SYLLABLE YILP) 5842 0xC767 읧 (HANGUL SYLLABLE YILH) 5843 0xC769 읩 (HANGUL SYLLABLE YIB) 5844 0xC76A 읪 (HANGUL SYLLABLE YIBS) 5845 0xC76C 읬 (HANGUL SYLLABLE YISS) 5846 0xC76D 읭 (HANGUL SYLLABLE YING) 5847 0xC76E 읮 (HANGUL SYLLABLE YIJ) 5848 0xC76F 읯 (HANGUL SYLLABLE YIC) 5849 0xC770 읰 (HANGUL SYLLABLE YIK) 5850 0xC771 읱 (HANGUL SYLLABLE YIT) 5851 0xC772 읲 (HANGUL SYLLABLE YIP) 5852 0xC773 읳 (HANGUL SYLLABLE YIH) 5853 0xC776 읶 (HANGUL SYLLABLE IGG) 5854 0xC777 읷 (HANGUL SYLLABLE IGS) 5855 0xC779 읹 (HANGUL SYLLABLE INJ) 5856 0xC77A 읺 (HANGUL SYLLABLE INH) 5857 0xC77B 읻 (HANGUL SYLLABLE ID) 5858 0xC77F 읿 (HANGUL SYLLABLE ILB) 5859 0xC780 잀 (HANGUL SYLLABLE ILS) 5860 0xC781 잁 (HANGUL SYLLABLE ILT) 5861 0xC782 잂 (HANGUL SYLLABLE ILP) 5862 0xC786 잆 (HANGUL SYLLABLE IBS) 5863 0xC78B 잋 (HANGUL SYLLABLE IC) 5864 0xC78C 잌 (HANGUL SYLLABLE IK) 5865 0xC78D 잍 (HANGUL SYLLABLE IT) 5866 0xC78F 잏 (HANGUL SYLLABLE IH) 5867 0xC792 잒 (HANGUL SYLLABLE JAGG) 5868 0xC793 잓 (HANGUL SYLLABLE JAGS) 5869 0xC795 잕 (HANGUL SYLLABLE JANJ) 5870 0xC799 잙 (HANGUL SYLLABLE JALG) 5871 0xC79B 잛 (HANGUL SYLLABLE JALB) 5872 0xC79C 잜 (HANGUL SYLLABLE JALS) 5873 0xC79D 잝 (HANGUL SYLLABLE JALT) 5874 0xC79E 잞 (HANGUL SYLLABLE JALP) 5875 0xC79F 잟 (HANGUL SYLLABLE JALH) 5876 0xC7A2 잢 (HANGUL SYLLABLE JABS) 5877 0xC7A7 잧 (HANGUL SYLLABLE JAC) 5878 0xC7A8 잨 (HANGUL SYLLABLE JAK) 5879 0xC7A9 잩 (HANGUL SYLLABLE JAT) 5880 0xC7AA 잪 (HANGUL SYLLABLE JAP) 5881 0xC7AB 잫 (HANGUL SYLLABLE JAH) 5882 0xC7AE 잮 (HANGUL SYLLABLE JAEGG) 5883 0xC7AF 잯 (HANGUL SYLLABLE JAEGS) 5884 0xC7B1 잱 (HANGUL SYLLABLE JAENJ) 5885 0xC7B2 잲 (HANGUL SYLLABLE JAENH) 5886 0xC7B3 잳 (HANGUL SYLLABLE JAED) 5887 0xC7B5 잵 (HANGUL SYLLABLE JAELG) 5888 0xC7B6 잶 (HANGUL SYLLABLE JAELM) 5889 0xC7B7 잷 (HANGUL SYLLABLE JAELB) 5890 0xC7B8 잸 (HANGUL SYLLABLE JAELS) 5891 0xC7B9 잹 (HANGUL SYLLABLE JAELT) 5892 0xC7BA 잺 (HANGUL SYLLABLE JAELP) 5893 0xC7BB 잻 (HANGUL SYLLABLE JAELH) 5894 0xC7BE 잾 (HANGUL SYLLABLE JAEBS) 5895 0xC7C2 쟂 (HANGUL SYLLABLE JAEJ) 5896 0xC7C3 쟃 (HANGUL SYLLABLE JAEC) 5897 0xC7C4 쟄 (HANGUL SYLLABLE JAEK) 5898 0xC7C5 쟅 (HANGUL SYLLABLE JAET) 5899 0xC7C6 쟆 (HANGUL SYLLABLE JAEP) 5900 0xC7C7 쟇 (HANGUL SYLLABLE JAEH) 5901 0xC7CA 쟊 (HANGUL SYLLABLE JYAGG) 5902 0xC7CB 쟋 (HANGUL SYLLABLE JYAGS) 5903 0xC7CD 쟍 (HANGUL SYLLABLE JYANJ) 5904 0xC7CF 쟏 (HANGUL SYLLABLE JYAD) 5905 0xC7D1 쟑 (HANGUL SYLLABLE JYALG) 5906 0xC7D2 쟒 (HANGUL SYLLABLE JYALM) 5907 0xC7D3 쟓 (HANGUL SYLLABLE JYALB) 5908 0xC7D4 쟔 (HANGUL SYLLABLE JYALS) 5909 0xC7D5 쟕 (HANGUL SYLLABLE JYALT) 5910 0xC7D6 쟖 (HANGUL SYLLABLE JYALP) 5911 0xC7D7 쟗 (HANGUL SYLLABLE JYALH) 5912 0xC7D9 쟙 (HANGUL SYLLABLE JYAB) 5913 0xC7DA 쟚 (HANGUL SYLLABLE JYABS) 5914 0xC7DB 쟛 (HANGUL SYLLABLE JYAS) 5915 0xC7DC 쟜 (HANGUL SYLLABLE JYASS) 5922 0xC7DE 쟞 (HANGUL SYLLABLE JYAJ) 5923 0xC7DF 쟟 (HANGUL SYLLABLE JYAC) 5924 0xC7E0 쟠 (HANGUL SYLLABLE JYAK) 5925 0xC7E1 쟡 (HANGUL SYLLABLE JYAT) 5926 0xC7E2 쟢 (HANGUL SYLLABLE JYAP) 5927 0xC7E3 쟣 (HANGUL SYLLABLE JYAH) 5928 0xC7E5 쟥 (HANGUL SYLLABLE JYAEG) 5929 0xC7E6 쟦 (HANGUL SYLLABLE JYAEGG) 5930 0xC7E7 쟧 (HANGUL SYLLABLE JYAEGS) 5931 0xC7E9 쟩 (HANGUL SYLLABLE JYAENJ) 5932 0xC7EA 쟪 (HANGUL SYLLABLE JYAENH) 5933 0xC7EB 쟫 (HANGUL SYLLABLE JYAED) 5934 0xC7ED 쟭 (HANGUL SYLLABLE JYAELG) 5935 0xC7EE 쟮 (HANGUL SYLLABLE JYAELM) 5936 0xC7EF 쟯 (HANGUL SYLLABLE JYAELB) 5937 0xC7F0 쟰 (HANGUL SYLLABLE JYAELS) 5938 0xC7F1 쟱 (HANGUL SYLLABLE JYAELT) 5939 0xC7F2 쟲 (HANGUL SYLLABLE JYAELP) 5940 0xC7F3 쟳 (HANGUL SYLLABLE JYAELH) 5941 0xC7F4 쟴 (HANGUL SYLLABLE JYAEM) 5942 0xC7F5 쟵 (HANGUL SYLLABLE JYAEB) 5943 0xC7F6 쟶 (HANGUL SYLLABLE JYAEBS) 5944 0xC7F7 쟷 (HANGUL SYLLABLE JYAES) 5945 0xC7F8 쟸 (HANGUL SYLLABLE JYAESS) 5946 0xC7F9 쟹 (HANGUL SYLLABLE JYAENG) 5947 0xC7FA 쟺 (HANGUL SYLLABLE JYAEJ) 5954 0xC7FB 쟻 (HANGUL SYLLABLE JYAEC) 5955 0xC7FC 쟼 (HANGUL SYLLABLE JYAEK) 5956 0xC7FD 쟽 (HANGUL SYLLABLE JYAET) 5957 0xC7FE 쟾 (HANGUL SYLLABLE JYAEP) 5958 0xC7FF 쟿 (HANGUL SYLLABLE JYAEH) 5959 0xC802 젂 (HANGUL SYLLABLE JEOGG) 5960 0xC803 젃 (HANGUL SYLLABLE JEOGS) 5961 0xC805 젅 (HANGUL SYLLABLE JEONJ) 5962 0xC806 젆 (HANGUL SYLLABLE JEONH) 5963 0xC807 젇 (HANGUL SYLLABLE JEOD) 5964 0xC809 젉 (HANGUL SYLLABLE JEOLG) 5965 0xC80B 젋 (HANGUL SYLLABLE JEOLB) 5966 0xC80C 젌 (HANGUL SYLLABLE JEOLS) 5967 0xC80D 젍 (HANGUL SYLLABLE JEOLT) 5968 0xC80E 젎 (HANGUL SYLLABLE JEOLP) 5969 0xC80F 젏 (HANGUL SYLLABLE JEOLH) 5970 0xC812 젒 (HANGUL SYLLABLE JEOBS) 5971 0xC814 젔 (HANGUL SYLLABLE JEOSS) 5972 0xC817 젗 (HANGUL SYLLABLE JEOC) 5973 0xC818 젘 (HANGUL SYLLABLE JEOK) 5974 0xC819 젙 (HANGUL SYLLABLE JEOT) 5975 0xC81A 젚 (HANGUL SYLLABLE JEOP) 5976 0xC81B 젛 (HANGUL SYLLABLE JEOH) 5977 0xC81E 젞 (HANGUL SYLLABLE JEGG) 5978 0xC81F 젟 (HANGUL SYLLABLE JEGS) 5979 0xC821 젡 (HANGUL SYLLABLE JENJ) 5980 0xC822 젢 (HANGUL SYLLABLE JENH) 5981 0xC823 젣 (HANGUL SYLLABLE JED) 5982 0xC825 젥 (HANGUL SYLLABLE JELG) 5983 0xC826 젦 (HANGUL SYLLABLE JELM) 5984 0xC827 젧 (HANGUL SYLLABLE JELB) 5985 0xC828 젨 (HANGUL SYLLABLE JELS) 5986 0xC829 젩 (HANGUL SYLLABLE JELT) 5987 0xC82A 젪 (HANGUL SYLLABLE JELP) 5988 0xC82B 젫 (HANGUL SYLLABLE JELH) 5989 0xC82E 젮 (HANGUL SYLLABLE JEBS) 5990 0xC830 젰 (HANGUL SYLLABLE JESS) 5991 0xC832 젲 (HANGUL SYLLABLE JEJ) 5992 0xC833 젳 (HANGUL SYLLABLE JEC) 5993 0xC834 젴 (HANGUL SYLLABLE JEK) 5994 0xC835 젵 (HANGUL SYLLABLE JET) 5995 0xC836 젶 (HANGUL SYLLABLE JEP) 5996 0xC837 젷 (HANGUL SYLLABLE JEH) 5997 0xC839 젹 (HANGUL SYLLABLE JYEOG) 5998 0xC83A 젺 (HANGUL SYLLABLE JYEOGG) 5999 0xC83B 젻 (HANGUL SYLLABLE JYEOGS) 6000 0xC83D 젽 (HANGUL SYLLABLE JYEONJ) 6001 0xC83E 젾 (HANGUL SYLLABLE JYEONH) 6002 0xC83F 젿 (HANGUL SYLLABLE JYEOD) 6003 0xC841 졁 (HANGUL SYLLABLE JYEOLG) 6004 0xC842 졂 (HANGUL SYLLABLE JYEOLM) 6005 0xC843 졃 (HANGUL SYLLABLE JYEOLB) 6006 0xC844 졄 (HANGUL SYLLABLE JYEOLS) 6007 0xC845 졅 (HANGUL SYLLABLE JYEOLT) 6008 0xC846 졆 (HANGUL SYLLABLE JYEOLP) 6009 0xC847 졇 (HANGUL SYLLABLE JYEOLH) 6010 0xC84A 졊 (HANGUL SYLLABLE JYEOBS) 6011 0xC84B 졋 (HANGUL SYLLABLE JYEOS) 6012 0xC84E 졎 (HANGUL SYLLABLE JYEOJ) 6013 0xC84F 졏 (HANGUL SYLLABLE JYEOC) 6014 0xC850 졐 (HANGUL SYLLABLE JYEOK) 6015 0xC851 졑 (HANGUL SYLLABLE JYEOT) 6016 0xC852 졒 (HANGUL SYLLABLE JYEOP) 6017 0xC853 졓 (HANGUL SYLLABLE JYEOH) 6018 0xC855 졕 (HANGUL SYLLABLE JYEG) 6019 0xC856 졖 (HANGUL SYLLABLE JYEGG) 6020 0xC857 졗 (HANGUL SYLLABLE JYEGS) 6021 0xC858 졘 (HANGUL SYLLABLE JYEN) 6022 0xC859 졙 (HANGUL SYLLABLE JYENJ) 6023 0xC85A 졚 (HANGUL SYLLABLE JYENH) 6024 0xC85B 졛 (HANGUL SYLLABLE JYED) 6025 0xC85C 졜 (HANGUL SYLLABLE JYEL) 6026 0xC85D 졝 (HANGUL SYLLABLE JYELG) 6027 0xC85E 졞 (HANGUL SYLLABLE JYELM) 6028 0xC85F 졟 (HANGUL SYLLABLE JYELB) 6029 0xC860 졠 (HANGUL SYLLABLE JYELS) 6030 0xC861 졡 (HANGUL SYLLABLE JYELT) 6031 0xC862 졢 (HANGUL SYLLABLE JYELP) 6032 0xC863 졣 (HANGUL SYLLABLE JYELH) 6033 0xC864 졤 (HANGUL SYLLABLE JYEM) 6034 0xC865 졥 (HANGUL SYLLABLE JYEB) 6035 0xC866 졦 (HANGUL SYLLABLE JYEBS) 6036 0xC867 졧 (HANGUL SYLLABLE JYES) 6037 0xC868 졨 (HANGUL SYLLABLE JYESS) 6038 0xC869 졩 (HANGUL SYLLABLE JYENG) 6039 0xC86A 졪 (HANGUL SYLLABLE JYEJ) 6040 0xC86B 졫 (HANGUL SYLLABLE JYEC) 6041 0xC86C 졬 (HANGUL SYLLABLE JYEK) 6042 0xC86D 졭 (HANGUL SYLLABLE JYET) 6043 0xC86E 졮 (HANGUL SYLLABLE JYEP) 6044 0xC86F 졯 (HANGUL SYLLABLE JYEH) 6045 0xC872 졲 (HANGUL SYLLABLE JOGG) 6046 0xC873 졳 (HANGUL SYLLABLE JOGS) 6047 0xC875 졵 (HANGUL SYLLABLE JONJ) 6048 0xC876 졶 (HANGUL SYLLABLE JONH) 6049 0xC877 졷 (HANGUL SYLLABLE JOD) 6050 0xC879 졹 (HANGUL SYLLABLE JOLG) 6051 0xC87B 졻 (HANGUL SYLLABLE JOLB) 6052 0xC87C 졼 (HANGUL SYLLABLE JOLS) 6053 0xC87D 졽 (HANGUL SYLLABLE JOLT) 6054 0xC87E 졾 (HANGUL SYLLABLE JOLP) 6055 0xC87F 졿 (HANGUL SYLLABLE JOLH) 6056 0xC882 좂 (HANGUL SYLLABLE JOBS) 6057 0xC884 좄 (HANGUL SYLLABLE JOSS) 6058 0xC888 좈 (HANGUL SYLLABLE JOK) 6059 0xC889 좉 (HANGUL SYLLABLE JOT) 6060 0xC88A 좊 (HANGUL SYLLABLE JOP) 6061 0xC88E 좎 (HANGUL SYLLABLE JWAGG) 6062 0xC88F 좏 (HANGUL SYLLABLE JWAGS) 6063 0xC890 좐 (HANGUL SYLLABLE JWAN) 6064 0xC891 좑 (HANGUL SYLLABLE JWANJ) 6065 0xC892 좒 (HANGUL SYLLABLE JWANH) 6066 0xC893 좓 (HANGUL SYLLABLE JWAD) 6067 0xC895 좕 (HANGUL SYLLABLE JWALG) 6068 0xC896 좖 (HANGUL SYLLABLE JWALM) 6069 0xC897 좗 (HANGUL SYLLABLE JWALB) 6070 0xC898 좘 (HANGUL SYLLABLE JWALS) 6071 0xC899 좙 (HANGUL SYLLABLE JWALT) 6072 0xC89A 좚 (HANGUL SYLLABLE JWALP) 6073 0xC89B 좛 (HANGUL SYLLABLE JWALH) 6074 0xC89C 좜 (HANGUL SYLLABLE JWAM) 6075 0xC89E 좞 (HANGUL SYLLABLE JWABS) 6076 0xC8A0 좠 (HANGUL SYLLABLE JWASS) 6077 0xC8A2 좢 (HANGUL SYLLABLE JWAJ) 6078 0xC8A3 좣 (HANGUL SYLLABLE JWAC) 6079 0xC8A4 좤 (HANGUL SYLLABLE JWAK) 6080 0xC8A5 좥 (HANGUL SYLLABLE JWAT) 6081 0xC8A6 좦 (HANGUL SYLLABLE JWAP) 6082 0xC8A7 좧 (HANGUL SYLLABLE JWAH) 6083 0xC8A9 좩 (HANGUL SYLLABLE JWAEG) 6084 0xC8AA 좪 (HANGUL SYLLABLE JWAEGG) 6085 0xC8AB 좫 (HANGUL SYLLABLE JWAEGS) 6086 0xC8AC 좬 (HANGUL SYLLABLE JWAEN) 6087 0xC8AD 좭 (HANGUL SYLLABLE JWAENJ) 6088 0xC8AE 좮 (HANGUL SYLLABLE JWAENH) 6089 0xC8AF 좯 (HANGUL SYLLABLE JWAED) 6090 0xC8B0 좰 (HANGUL SYLLABLE JWAEL) 6091 0xC8B1 좱 (HANGUL SYLLABLE JWAELG) 6092 0xC8B2 좲 (HANGUL SYLLABLE JWAELM) 6093 0xC8B3 좳 (HANGUL SYLLABLE JWAELB) 6094 0xC8B4 좴 (HANGUL SYLLABLE JWAELS) 6095 0xC8B5 좵 (HANGUL SYLLABLE JWAELT) 6096 0xC8B6 좶 (HANGUL SYLLABLE JWAELP) 6097 0xC8B7 좷 (HANGUL SYLLABLE JWAELH) 6098 0xC8B8 좸 (HANGUL SYLLABLE JWAEM) 6099 0xC8B9 좹 (HANGUL SYLLABLE JWAEB) 6100 0xC8BA 좺 (HANGUL SYLLABLE JWAEBS) 6101 0xC8BB 좻 (HANGUL SYLLABLE JWAES) 6102 0xC8BE 좾 (HANGUL SYLLABLE JWAEJ) 6103 0xC8BF 좿 (HANGUL SYLLABLE JWAEC) 6104 0xC8C0 죀 (HANGUL SYLLABLE JWAEK) 6105 0xC8C1 죁 (HANGUL SYLLABLE JWAET) 6112 0xC8C2 죂 (HANGUL SYLLABLE JWAEP) 6113 0xC8C3 죃 (HANGUL SYLLABLE JWAEH) 6114 0xC8C5 죅 (HANGUL SYLLABLE JOEG) 6115 0xC8C6 죆 (HANGUL SYLLABLE JOEGG) 6116 0xC8C7 죇 (HANGUL SYLLABLE JOEGS) 6117 0xC8C9 죉 (HANGUL SYLLABLE JOENJ) 6118 0xC8CA 죊 (HANGUL SYLLABLE JOENH) 6119 0xC8CB 죋 (HANGUL SYLLABLE JOED) 6120 0xC8CD 죍 (HANGUL SYLLABLE JOELG) 6121 0xC8CE 죎 (HANGUL SYLLABLE JOELM) 6122 0xC8CF 죏 (HANGUL SYLLABLE JOELB) 6123 0xC8D0 죐 (HANGUL SYLLABLE JOELS) 6124 0xC8D1 죑 (HANGUL SYLLABLE JOELT) 6125 0xC8D2 죒 (HANGUL SYLLABLE JOELP) 6126 0xC8D3 죓 (HANGUL SYLLABLE JOELH) 6127 0xC8D6 죖 (HANGUL SYLLABLE JOEBS) 6128 0xC8D8 죘 (HANGUL SYLLABLE JOESS) 6129 0xC8DA 죚 (HANGUL SYLLABLE JOEJ) 6130 0xC8DB 죛 (HANGUL SYLLABLE JOEC) 6131 0xC8DC 죜 (HANGUL SYLLABLE JOEK) 6132 0xC8DD 죝 (HANGUL SYLLABLE JOET) 6133 0xC8DE 죞 (HANGUL SYLLABLE JOEP) 6134 0xC8DF 죟 (HANGUL SYLLABLE JOEH) 6135 0xC8E2 죢 (HANGUL SYLLABLE JYOGG) 6136 0xC8E3 죣 (HANGUL SYLLABLE JYOGS) 6137 0xC8E5 죥 (HANGUL SYLLABLE JYONJ) 6144 0xC8E6 죦 (HANGUL SYLLABLE JYONH) 6145 0xC8E7 죧 (HANGUL SYLLABLE JYOD) 6146 0xC8E8 죨 (HANGUL SYLLABLE JYOL) 6147 0xC8E9 죩 (HANGUL SYLLABLE JYOLG) 6148 0xC8EA 죪 (HANGUL SYLLABLE JYOLM) 6149 0xC8EB 죫 (HANGUL SYLLABLE JYOLB) 6150 0xC8EC 죬 (HANGUL SYLLABLE JYOLS) 6151 0xC8ED 죭 (HANGUL SYLLABLE JYOLT) 6152 0xC8EE 죮 (HANGUL SYLLABLE JYOLP) 6153 0xC8EF 죯 (HANGUL SYLLABLE JYOLH) 6154 0xC8F0 죰 (HANGUL SYLLABLE JYOM) 6155 0xC8F1 죱 (HANGUL SYLLABLE JYOB) 6156 0xC8F2 죲 (HANGUL SYLLABLE JYOBS) 6157 0xC8F3 죳 (HANGUL SYLLABLE JYOS) 6158 0xC8F4 죴 (HANGUL SYLLABLE JYOSS) 6159 0xC8F6 죶 (HANGUL SYLLABLE JYOJ) 6160 0xC8F7 죷 (HANGUL SYLLABLE JYOC) 6161 0xC8F8 죸 (HANGUL SYLLABLE JYOK) 6162 0xC8F9 죹 (HANGUL SYLLABLE JYOT) 6163 0xC8FA 죺 (HANGUL SYLLABLE JYOP) 6164 0xC8FB 죻 (HANGUL SYLLABLE JYOH) 6165 0xC8FE 죾 (HANGUL SYLLABLE JUGG) 6166 0xC8FF 죿 (HANGUL SYLLABLE JUGS) 6167 0xC901 줁 (HANGUL SYLLABLE JUNJ) 6168 0xC902 줂 (HANGUL SYLLABLE JUNH) 6169 0xC903 줃 (HANGUL SYLLABLE JUD) 6170 0xC907 줇 (HANGUL SYLLABLE JULB) 6171 0xC908 줈 (HANGUL SYLLABLE JULS) 6172 0xC909 줉 (HANGUL SYLLABLE JULT) 6173 0xC90A 줊 (HANGUL SYLLABLE JULP) 6174 0xC90B 줋 (HANGUL SYLLABLE JULH) 6175 0xC90E 줎 (HANGUL SYLLABLE JUBS) 6176 0x3000   (IDEOGRAPHIC SPACE) 6177 0x3001 、 (IDEOGRAPHIC COMMA) 6178 0x3002 。 (IDEOGRAPHIC FULL STOP) 6179 0x00B7 · (MIDDLE DOT) 6180 0x2025 ‥ (TWO DOT LEADER) 6181 0x2026 … (HORIZONTAL ELLIPSIS) 6182 0x00A8 ¨ (DIAERESIS) 6183 0x3003 〃 (DITTO MARK) 6184 0x00AD ­ (SOFT HYPHEN) 6185 0x2015 ― (HORIZONTAL BAR) 6186 0x2225 ∥ (PARALLEL TO) 6187 0xFF3C \ (FULLWIDTH REVERSE SOLIDUS) 6188 0x223C ∼ (TILDE OPERATOR) 6189 0x2018 ‘ (LEFT SINGLE QUOTATION MARK) 6190 0x2019 ’ (RIGHT SINGLE QUOTATION MARK) 6191 0x201C “ (LEFT DOUBLE QUOTATION MARK) 6192 0x201D ” (RIGHT DOUBLE QUOTATION MARK) 6193 0x3014 〔 (LEFT TORTOISE SHELL BRACKET) 6194 0x3015 〕 (RIGHT TORTOISE SHELL BRACKET) 6195 0x3008 〈 (LEFT ANGLE BRACKET) 6196 0x3009 〉 (RIGHT ANGLE BRACKET) 6197 0x300A 《 (LEFT DOUBLE ANGLE BRACKET) 6198 0x300B 》 (RIGHT DOUBLE ANGLE BRACKET) 6199 0x300C 「 (LEFT CORNER BRACKET) 6200 0x300D 」 (RIGHT CORNER BRACKET) 6201 0x300E 『 (LEFT WHITE CORNER BRACKET) 6202 0x300F 』 (RIGHT WHITE CORNER BRACKET) 6203 0x3010 【 (LEFT BLACK LENTICULAR BRACKET) 6204 0x3011 】 (RIGHT BLACK LENTICULAR BRACKET) 6205 0x00B1 ± (PLUS-MINUS SIGN) 6206 0x00D7 × (MULTIPLICATION SIGN) 6207 0x00F7 ÷ (DIVISION SIGN) 6208 0x2260 ≠ (NOT EQUAL TO) 6209 0x2264 ≤ (LESS-THAN OR EQUAL TO) 6210 0x2265 ≥ (GREATER-THAN OR EQUAL TO) 6211 0x221E ∞ (INFINITY) 6212 0x2234 ∴ (THEREFORE) 6213 0x00B0 ° (DEGREE SIGN) 6214 0x2032 ′ (PRIME) 6215 0x2033 ″ (DOUBLE PRIME) 6216 0x2103 ℃ (DEGREE CELSIUS) 6217 0x212B Å (ANGSTROM SIGN) 6218 0xFFE0 ¢ (FULLWIDTH CENT SIGN) 6219 0xFFE1 £ (FULLWIDTH POUND SIGN) 6220 0xFFE5 ¥ (FULLWIDTH YEN SIGN) 6221 0x2642 ♂ (MALE SIGN) 6222 0x2640 ♀ (FEMALE SIGN) 6223 0x2220 ∠ (ANGLE) 6224 0x22A5 ⊥ (UP TACK) 6225 0x2312 ⌒ (ARC) 6226 0x2202 ∂ (PARTIAL DIFFERENTIAL) 6227 0x2207 ∇ (NABLA) 6228 0x2261 ≡ (IDENTICAL TO) 6229 0x2252 ≒ (APPROXIMATELY EQUAL TO OR THE IMAGE OF) 6230 0x00A7 § (SECTION SIGN) 6231 0x203B ※ (REFERENCE MARK) 6232 0x2606 ☆ (WHITE STAR) 6233 0x2605 ★ (BLACK STAR) 6234 0x25CB ○ (WHITE CIRCLE) 6235 0x25CF ● (BLACK CIRCLE) 6236 0x25CE ◎ (BULLSEYE) 6237 0x25C7 ◇ (WHITE DIAMOND) 6238 0x25C6 ◆ (BLACK DIAMOND) 6239 0x25A1 □ (WHITE SQUARE) 6240 0x25A0 ■ (BLACK SQUARE) 6241 0x25B3 △ (WHITE UP-POINTING TRIANGLE) 6242 0x25B2 ▲ (BLACK UP-POINTING TRIANGLE) 6243 0x25BD ▽ (WHITE DOWN-POINTING TRIANGLE) 6244 0x25BC ▼ (BLACK DOWN-POINTING TRIANGLE) 6245 0x2192 → (RIGHTWARDS ARROW) 6246 0x2190 ← (LEFTWARDS ARROW) 6247 0x2191 ↑ (UPWARDS ARROW) 6248 0x2193 ↓ (DOWNWARDS ARROW) 6249 0x2194 ↔ (LEFT RIGHT ARROW) 6250 0x3013 〓 (GETA MARK) 6251 0x226A ≪ (MUCH LESS-THAN) 6252 0x226B ≫ (MUCH GREATER-THAN) 6253 0x221A √ (SQUARE ROOT) 6254 0x223D ∽ (REVERSED TILDE) 6255 0x221D ∝ (PROPORTIONAL TO) 6256 0x2235 ∵ (BECAUSE) 6257 0x222B ∫ (INTEGRAL) 6258 0x222C ∬ (DOUBLE INTEGRAL) 6259 0x2208 ∈ (ELEMENT OF) 6260 0x220B ∋ (CONTAINS AS MEMBER) 6261 0x2286 ⊆ (SUBSET OF OR EQUAL TO) 6262 0x2287 ⊇ (SUPERSET OF OR EQUAL TO) 6263 0x2282 ⊂ (SUBSET OF) 6264 0x2283 ⊃ (SUPERSET OF) 6265 0x222A ∪ (UNION) 6266 0x2229 ∩ (INTERSECTION) 6267 0x2227 ∧ (LOGICAL AND) 6268 0x2228 ∨ (LOGICAL OR) 6269 0xFFE2 ¬ (FULLWIDTH NOT SIGN) 6270 0xC910 줐 (HANGUL SYLLABLE JUSS) 6271 0xC912 줒 (HANGUL SYLLABLE JUJ) 6272 0xC913 줓 (HANGUL SYLLABLE JUC) 6273 0xC914 줔 (HANGUL SYLLABLE JUK) 6274 0xC915 줕 (HANGUL SYLLABLE JUT) 6275 0xC916 줖 (HANGUL SYLLABLE JUP) 6276 0xC917 줗 (HANGUL SYLLABLE JUH) 6277 0xC919 줙 (HANGUL SYLLABLE JWEOG) 6278 0xC91A 줚 (HANGUL SYLLABLE JWEOGG) 6279 0xC91B 줛 (HANGUL SYLLABLE JWEOGS) 6280 0xC91C 줜 (HANGUL SYLLABLE JWEON) 6281 0xC91D 줝 (HANGUL SYLLABLE JWEONJ) 6282 0xC91E 줞 (HANGUL SYLLABLE JWEONH) 6283 0xC91F 줟 (HANGUL SYLLABLE JWEOD) 6284 0xC920 줠 (HANGUL SYLLABLE JWEOL) 6285 0xC921 줡 (HANGUL SYLLABLE JWEOLG) 6286 0xC922 줢 (HANGUL SYLLABLE JWEOLM) 6287 0xC923 줣 (HANGUL SYLLABLE JWEOLB) 6288 0xC924 줤 (HANGUL SYLLABLE JWEOLS) 6289 0xC925 줥 (HANGUL SYLLABLE JWEOLT) 6290 0xC926 줦 (HANGUL SYLLABLE JWEOLP) 6291 0xC927 줧 (HANGUL SYLLABLE JWEOLH) 6292 0xC928 줨 (HANGUL SYLLABLE JWEOM) 6293 0xC929 줩 (HANGUL SYLLABLE JWEOB) 6294 0xC92A 줪 (HANGUL SYLLABLE JWEOBS) 6295 0xC92B 줫 (HANGUL SYLLABLE JWEOS) 6302 0xC92D 줭 (HANGUL SYLLABLE JWEONG) 6303 0xC92E 줮 (HANGUL SYLLABLE JWEOJ) 6304 0xC92F 줯 (HANGUL SYLLABLE JWEOC) 6305 0xC930 줰 (HANGUL SYLLABLE JWEOK) 6306 0xC931 줱 (HANGUL SYLLABLE JWEOT) 6307 0xC932 줲 (HANGUL SYLLABLE JWEOP) 6308 0xC933 줳 (HANGUL SYLLABLE JWEOH) 6309 0xC935 줵 (HANGUL SYLLABLE JWEG) 6310 0xC936 줶 (HANGUL SYLLABLE JWEGG) 6311 0xC937 줷 (HANGUL SYLLABLE JWEGS) 6312 0xC938 줸 (HANGUL SYLLABLE JWEN) 6313 0xC939 줹 (HANGUL SYLLABLE JWENJ) 6314 0xC93A 줺 (HANGUL SYLLABLE JWENH) 6315 0xC93B 줻 (HANGUL SYLLABLE JWED) 6316 0xC93C 줼 (HANGUL SYLLABLE JWEL) 6317 0xC93D 줽 (HANGUL SYLLABLE JWELG) 6318 0xC93E 줾 (HANGUL SYLLABLE JWELM) 6319 0xC93F 줿 (HANGUL SYLLABLE JWELB) 6320 0xC940 쥀 (HANGUL SYLLABLE JWELS) 6321 0xC941 쥁 (HANGUL SYLLABLE JWELT) 6322 0xC942 쥂 (HANGUL SYLLABLE JWELP) 6323 0xC943 쥃 (HANGUL SYLLABLE JWELH) 6324 0xC944 쥄 (HANGUL SYLLABLE JWEM) 6325 0xC945 쥅 (HANGUL SYLLABLE JWEB) 6326 0xC946 쥆 (HANGUL SYLLABLE JWEBS) 6327 0xC947 쥇 (HANGUL SYLLABLE JWES) 6334 0xC948 쥈 (HANGUL SYLLABLE JWESS) 6335 0xC949 쥉 (HANGUL SYLLABLE JWENG) 6336 0xC94A 쥊 (HANGUL SYLLABLE JWEJ) 6337 0xC94B 쥋 (HANGUL SYLLABLE JWEC) 6338 0xC94C 쥌 (HANGUL SYLLABLE JWEK) 6339 0xC94D 쥍 (HANGUL SYLLABLE JWET) 6340 0xC94E 쥎 (HANGUL SYLLABLE JWEP) 6341 0xC94F 쥏 (HANGUL SYLLABLE JWEH) 6342 0xC952 쥒 (HANGUL SYLLABLE JWIGG) 6343 0xC953 쥓 (HANGUL SYLLABLE JWIGS) 6344 0xC955 쥕 (HANGUL SYLLABLE JWINJ) 6345 0xC956 쥖 (HANGUL SYLLABLE JWINH) 6346 0xC957 쥗 (HANGUL SYLLABLE JWID) 6347 0xC959 쥙 (HANGUL SYLLABLE JWILG) 6348 0xC95A 쥚 (HANGUL SYLLABLE JWILM) 6349 0xC95B 쥛 (HANGUL SYLLABLE JWILB) 6350 0xC95C 쥜 (HANGUL SYLLABLE JWILS) 6351 0xC95D 쥝 (HANGUL SYLLABLE JWILT) 6352 0xC95E 쥞 (HANGUL SYLLABLE JWILP) 6353 0xC95F 쥟 (HANGUL SYLLABLE JWILH) 6354 0xC962 쥢 (HANGUL SYLLABLE JWIBS) 6355 0xC964 쥤 (HANGUL SYLLABLE JWISS) 6356 0xC965 쥥 (HANGUL SYLLABLE JWING) 6357 0xC966 쥦 (HANGUL SYLLABLE JWIJ) 6358 0xC967 쥧 (HANGUL SYLLABLE JWIC) 6359 0xC968 쥨 (HANGUL SYLLABLE JWIK) 6360 0xC969 쥩 (HANGUL SYLLABLE JWIT) 6361 0xC96A 쥪 (HANGUL SYLLABLE JWIP) 6362 0xC96B 쥫 (HANGUL SYLLABLE JWIH) 6363 0xC96D 쥭 (HANGUL SYLLABLE JYUG) 6364 0xC96E 쥮 (HANGUL SYLLABLE JYUGG) 6365 0xC96F 쥯 (HANGUL SYLLABLE JYUGS) 6366 0x21D2 ⇒ (RIGHTWARDS DOUBLE ARROW) 6367 0x21D4 ⇔ (LEFT RIGHT DOUBLE ARROW) 6368 0x2200 ∀ (FOR ALL) 6369 0x2203 ∃ (THERE EXISTS) 6370 0x00B4 ´ (ACUTE ACCENT) 6371 0xFF5E ~ (FULLWIDTH TILDE) 6372 0x02C7 ˇ (CARON) 6373 0x02D8 ˘ (BREVE) 6374 0x02DD ˝ (DOUBLE ACUTE ACCENT) 6375 0x02DA ˚ (RING ABOVE) 6376 0x02D9 ˙ (DOT ABOVE) 6377 0x00B8 ¸ (CEDILLA) 6378 0x02DB ˛ (OGONEK) 6379 0x00A1 ¡ (INVERTED EXCLAMATION MARK) 6380 0x00BF ¿ (INVERTED QUESTION MARK) 6381 0x02D0 ː (MODIFIER LETTER TRIANGULAR COLON) 6382 0x222E ∮ (CONTOUR INTEGRAL) 6383 0x2211 ∑ (N-ARY SUMMATION) 6384 0x220F ∏ (N-ARY PRODUCT) 6385 0x00A4 ¤ (CURRENCY SIGN) 6386 0x2109 ℉ (DEGREE FAHRENHEIT) 6387 0x2030 ‰ (PER MILLE SIGN) 6388 0x25C1 ◁ (WHITE LEFT-POINTING TRIANGLE) 6389 0x25C0 ◀ (BLACK LEFT-POINTING TRIANGLE) 6390 0x25B7 ▷ (WHITE RIGHT-POINTING TRIANGLE) 6391 0x25B6 ▶ (BLACK RIGHT-POINTING TRIANGLE) 6392 0x2664 ♤ (WHITE SPADE SUIT) 6393 0x2660 ♠ (BLACK SPADE SUIT) 6394 0x2661 ♡ (WHITE HEART SUIT) 6395 0x2665 ♥ (BLACK HEART SUIT) 6396 0x2667 ♧ (WHITE CLUB SUIT) 6397 0x2663 ♣ (BLACK CLUB SUIT) 6398 0x2299 ⊙ (CIRCLED DOT OPERATOR) 6399 0x25C8 ◈ (WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND) 6400 0x25A3 ▣ (WHITE SQUARE CONTAINING BLACK SMALL SQUARE) 6401 0x25D0 ◐ (CIRCLE WITH LEFT HALF BLACK) 6402 0x25D1 ◑ (CIRCLE WITH RIGHT HALF BLACK) 6403 0x2592 ▒ (MEDIUM SHADE) 6404 0x25A4 ▤ (SQUARE WITH HORIZONTAL FILL) 6405 0x25A5 ▥ (SQUARE WITH VERTICAL FILL) 6406 0x25A8 ▨ (SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL) 6407 0x25A7 ▧ (SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL) 6408 0x25A6 ▦ (SQUARE WITH ORTHOGONAL CROSSHATCH FILL) 6409 0x25A9 ▩ (SQUARE WITH DIAGONAL CROSSHATCH FILL) 6410 0x2668 ♨ (HOT SPRINGS) 6411 0x260F ☏ (WHITE TELEPHONE) 6412 0x260E ☎ (BLACK TELEPHONE) 6413 0x261C ☜ (WHITE LEFT POINTING INDEX) 6414 0x261E ☞ (WHITE RIGHT POINTING INDEX) 6415 0x00B6 ¶ (PILCROW SIGN) 6416 0x2020 † (DAGGER) 6417 0x2021 ‡ (DOUBLE DAGGER) 6418 0x2195 ↕ (UP DOWN ARROW) 6419 0x2197 ↗ (NORTH EAST ARROW) 6420 0x2199 ↙ (SOUTH WEST ARROW) 6421 0x2196 ↖ (NORTH WEST ARROW) 6422 0x2198 ↘ (SOUTH EAST ARROW) 6423 0x266D ♭ (MUSIC FLAT SIGN) 6424 0x2669 ♩ (QUARTER NOTE) 6425 0x266A ♪ (EIGHTH NOTE) 6426 0x266C ♬ (BEAMED SIXTEENTH NOTES) 6427 0x327F ㉿ (KOREAN STANDARD SYMBOL) 6428 0x321C ㈜ (PARENTHESIZED HANGUL CIEUC U) 6429 0x2116 № (NUMERO SIGN) 6430 0x33C7 ㏇ (SQUARE CO) 6431 0x2122 ™ (TRADE MARK SIGN) 6432 0x33C2 ㏂ (SQUARE AM) 6433 0x33D8 ㏘ (SQUARE PM) 6434 0x2121 ℡ (TELEPHONE SIGN) 6435 0x20AC € (EURO SIGN) 6436 0x00AE ® (REGISTERED SIGN) 6460 0xC971 쥱 (HANGUL SYLLABLE JYUNJ) 6461 0xC972 쥲 (HANGUL SYLLABLE JYUNH) 6462 0xC973 쥳 (HANGUL SYLLABLE JYUD) 6463 0xC975 쥵 (HANGUL SYLLABLE JYULG) 6464 0xC976 쥶 (HANGUL SYLLABLE JYULM) 6465 0xC977 쥷 (HANGUL SYLLABLE JYULB) 6466 0xC978 쥸 (HANGUL SYLLABLE JYULS) 6467 0xC979 쥹 (HANGUL SYLLABLE JYULT) 6468 0xC97A 쥺 (HANGUL SYLLABLE JYULP) 6469 0xC97B 쥻 (HANGUL SYLLABLE JYULH) 6470 0xC97D 쥽 (HANGUL SYLLABLE JYUB) 6471 0xC97E 쥾 (HANGUL SYLLABLE JYUBS) 6472 0xC97F 쥿 (HANGUL SYLLABLE JYUS) 6473 0xC980 즀 (HANGUL SYLLABLE JYUSS) 6474 0xC981 즁 (HANGUL SYLLABLE JYUNG) 6475 0xC982 즂 (HANGUL SYLLABLE JYUJ) 6476 0xC983 즃 (HANGUL SYLLABLE JYUC) 6477 0xC984 즄 (HANGUL SYLLABLE JYUK) 6478 0xC985 즅 (HANGUL SYLLABLE JYUT) 6479 0xC986 즆 (HANGUL SYLLABLE JYUP) 6480 0xC987 즇 (HANGUL SYLLABLE JYUH) 6481 0xC98A 즊 (HANGUL SYLLABLE JEUGG) 6482 0xC98B 즋 (HANGUL SYLLABLE JEUGS) 6483 0xC98D 즍 (HANGUL SYLLABLE JEUNJ) 6484 0xC98E 즎 (HANGUL SYLLABLE JEUNH) 6485 0xC98F 즏 (HANGUL SYLLABLE JEUD) 6492 0xC991 즑 (HANGUL SYLLABLE JEULG) 6493 0xC992 즒 (HANGUL SYLLABLE JEULM) 6494 0xC993 즓 (HANGUL SYLLABLE JEULB) 6495 0xC994 즔 (HANGUL SYLLABLE JEULS) 6496 0xC995 즕 (HANGUL SYLLABLE JEULT) 6497 0xC996 즖 (HANGUL SYLLABLE JEULP) 6498 0xC997 즗 (HANGUL SYLLABLE JEULH) 6499 0xC99A 즚 (HANGUL SYLLABLE JEUBS) 6500 0xC99C 즜 (HANGUL SYLLABLE JEUSS) 6501 0xC99E 즞 (HANGUL SYLLABLE JEUJ) 6502 0xC99F 즟 (HANGUL SYLLABLE JEUC) 6503 0xC9A0 즠 (HANGUL SYLLABLE JEUK) 6504 0xC9A1 즡 (HANGUL SYLLABLE JEUT) 6505 0xC9A2 즢 (HANGUL SYLLABLE JEUP) 6506 0xC9A3 즣 (HANGUL SYLLABLE JEUH) 6507 0xC9A4 즤 (HANGUL SYLLABLE JYI) 6508 0xC9A5 즥 (HANGUL SYLLABLE JYIG) 6509 0xC9A6 즦 (HANGUL SYLLABLE JYIGG) 6510 0xC9A7 즧 (HANGUL SYLLABLE JYIGS) 6511 0xC9A8 즨 (HANGUL SYLLABLE JYIN) 6512 0xC9A9 즩 (HANGUL SYLLABLE JYINJ) 6513 0xC9AA 즪 (HANGUL SYLLABLE JYINH) 6514 0xC9AB 즫 (HANGUL SYLLABLE JYID) 6515 0xC9AC 즬 (HANGUL SYLLABLE JYIL) 6516 0xC9AD 즭 (HANGUL SYLLABLE JYILG) 6517 0xC9AE 즮 (HANGUL SYLLABLE JYILM) 6524 0xC9AF 즯 (HANGUL SYLLABLE JYILB) 6525 0xC9B0 즰 (HANGUL SYLLABLE JYILS) 6526 0xC9B1 즱 (HANGUL SYLLABLE JYILT) 6527 0xC9B2 즲 (HANGUL SYLLABLE JYILP) 6528 0xC9B3 즳 (HANGUL SYLLABLE JYILH) 6529 0xC9B4 즴 (HANGUL SYLLABLE JYIM) 6530 0xC9B5 즵 (HANGUL SYLLABLE JYIB) 6531 0xC9B6 즶 (HANGUL SYLLABLE JYIBS) 6532 0xC9B7 즷 (HANGUL SYLLABLE JYIS) 6533 0xC9B8 즸 (HANGUL SYLLABLE JYISS) 6534 0xC9B9 즹 (HANGUL SYLLABLE JYING) 6535 0xC9BA 즺 (HANGUL SYLLABLE JYIJ) 6536 0xC9BB 즻 (HANGUL SYLLABLE JYIC) 6537 0xC9BC 즼 (HANGUL SYLLABLE JYIK) 6538 0xC9BD 즽 (HANGUL SYLLABLE JYIT) 6539 0xC9BE 즾 (HANGUL SYLLABLE JYIP) 6540 0xC9BF 즿 (HANGUL SYLLABLE JYIH) 6541 0xC9C2 짂 (HANGUL SYLLABLE JIGG) 6542 0xC9C3 짃 (HANGUL SYLLABLE JIGS) 6543 0xC9C5 짅 (HANGUL SYLLABLE JINJ) 6544 0xC9C6 짆 (HANGUL SYLLABLE JINH) 6545 0xC9C9 짉 (HANGUL SYLLABLE JILG) 6546 0xC9CB 짋 (HANGUL SYLLABLE JILB) 6547 0xC9CC 짌 (HANGUL SYLLABLE JILS) 6548 0xC9CD 짍 (HANGUL SYLLABLE JILT) 6549 0xC9CE 짎 (HANGUL SYLLABLE JILP) 6550 0xC9CF 짏 (HANGUL SYLLABLE JILH) 6551 0xC9D2 짒 (HANGUL SYLLABLE JIBS) 6552 0xC9D4 짔 (HANGUL SYLLABLE JISS) 6553 0xC9D7 짗 (HANGUL SYLLABLE JIC) 6554 0xC9D8 짘 (HANGUL SYLLABLE JIK) 6555 0xC9DB 짛 (HANGUL SYLLABLE JIH) 6556 0xFF01 ! (FULLWIDTH EXCLAMATION MARK) 6557 0xFF02 " (FULLWIDTH QUOTATION MARK) 6558 0xFF03 # (FULLWIDTH NUMBER SIGN) 6559 0xFF04 $ (FULLWIDTH DOLLAR SIGN) 6560 0xFF05 % (FULLWIDTH PERCENT SIGN) 6561 0xFF06 & (FULLWIDTH AMPERSAND) 6562 0xFF07 ' (FULLWIDTH APOSTROPHE) 6563 0xFF08 ( (FULLWIDTH LEFT PARENTHESIS) 6564 0xFF09 ) (FULLWIDTH RIGHT PARENTHESIS) 6565 0xFF0A * (FULLWIDTH ASTERISK) 6566 0xFF0B + (FULLWIDTH PLUS SIGN) 6567 0xFF0C , (FULLWIDTH COMMA) 6568 0xFF0D - (FULLWIDTH HYPHEN-MINUS) 6569 0xFF0E . (FULLWIDTH FULL STOP) 6570 0xFF0F / (FULLWIDTH SOLIDUS) 6571 0xFF10 0 (FULLWIDTH DIGIT ZERO) 6572 0xFF11 1 (FULLWIDTH DIGIT ONE) 6573 0xFF12 2 (FULLWIDTH DIGIT TWO) 6574 0xFF13 3 (FULLWIDTH DIGIT THREE) 6575 0xFF14 4 (FULLWIDTH DIGIT FOUR) 6576 0xFF15 5 (FULLWIDTH DIGIT FIVE) 6577 0xFF16 6 (FULLWIDTH DIGIT SIX) 6578 0xFF17 7 (FULLWIDTH DIGIT SEVEN) 6579 0xFF18 8 (FULLWIDTH DIGIT EIGHT) 6580 0xFF19 9 (FULLWIDTH DIGIT NINE) 6581 0xFF1A : (FULLWIDTH COLON) 6582 0xFF1B ; (FULLWIDTH SEMICOLON) 6583 0xFF1C < (FULLWIDTH LESS-THAN SIGN) 6584 0xFF1D = (FULLWIDTH EQUALS SIGN) 6585 0xFF1E > (FULLWIDTH GREATER-THAN SIGN) 6586 0xFF1F ? (FULLWIDTH QUESTION MARK) 6587 0xFF20 @ (FULLWIDTH COMMERCIAL AT) 6588 0xFF21 A (FULLWIDTH LATIN CAPITAL LETTER A) 6589 0xFF22 B (FULLWIDTH LATIN CAPITAL LETTER B) 6590 0xFF23 C (FULLWIDTH LATIN CAPITAL LETTER C) 6591 0xFF24 D (FULLWIDTH LATIN CAPITAL LETTER D) 6592 0xFF25 E (FULLWIDTH LATIN CAPITAL LETTER E) 6593 0xFF26 F (FULLWIDTH LATIN CAPITAL LETTER F) 6594 0xFF27 G (FULLWIDTH LATIN CAPITAL LETTER G) 6595 0xFF28 H (FULLWIDTH LATIN CAPITAL LETTER H) 6596 0xFF29 I (FULLWIDTH LATIN CAPITAL LETTER I) 6597 0xFF2A J (FULLWIDTH LATIN CAPITAL LETTER J) 6598 0xFF2B K (FULLWIDTH LATIN CAPITAL LETTER K) 6599 0xFF2C L (FULLWIDTH LATIN CAPITAL LETTER L) 6600 0xFF2D M (FULLWIDTH LATIN CAPITAL LETTER M) 6601 0xFF2E N (FULLWIDTH LATIN CAPITAL LETTER N) 6602 0xFF2F O (FULLWIDTH LATIN CAPITAL LETTER O) 6603 0xFF30 P (FULLWIDTH LATIN CAPITAL LETTER P) 6604 0xFF31 Q (FULLWIDTH LATIN CAPITAL LETTER Q) 6605 0xFF32 R (FULLWIDTH LATIN CAPITAL LETTER R) 6606 0xFF33 S (FULLWIDTH LATIN CAPITAL LETTER S) 6607 0xFF34 T (FULLWIDTH LATIN CAPITAL LETTER T) 6608 0xFF35 U (FULLWIDTH LATIN CAPITAL LETTER U) 6609 0xFF36 V (FULLWIDTH LATIN CAPITAL LETTER V) 6610 0xFF37 W (FULLWIDTH LATIN CAPITAL LETTER W) 6611 0xFF38 X (FULLWIDTH LATIN CAPITAL LETTER X) 6612 0xFF39 Y (FULLWIDTH LATIN CAPITAL LETTER Y) 6613 0xFF3A Z (FULLWIDTH LATIN CAPITAL LETTER Z) 6614 0xFF3B [ (FULLWIDTH LEFT SQUARE BRACKET) 6615 0xFFE6 ₩ (FULLWIDTH WON SIGN) 6616 0xFF3D ] (FULLWIDTH RIGHT SQUARE BRACKET) 6617 0xFF3E ^ (FULLWIDTH CIRCUMFLEX ACCENT) 6618 0xFF3F _ (FULLWIDTH LOW LINE) 6619 0xFF40 ` (FULLWIDTH GRAVE ACCENT) 6620 0xFF41 a (FULLWIDTH LATIN SMALL LETTER A) 6621 0xFF42 b (FULLWIDTH LATIN SMALL LETTER B) 6622 0xFF43 c (FULLWIDTH LATIN SMALL LETTER C) 6623 0xFF44 d (FULLWIDTH LATIN SMALL LETTER D) 6624 0xFF45 e (FULLWIDTH LATIN SMALL LETTER E) 6625 0xFF46 f (FULLWIDTH LATIN SMALL LETTER F) 6626 0xFF47 g (FULLWIDTH LATIN SMALL LETTER G) 6627 0xFF48 h (FULLWIDTH LATIN SMALL LETTER H) 6628 0xFF49 i (FULLWIDTH LATIN SMALL LETTER I) 6629 0xFF4A j (FULLWIDTH LATIN SMALL LETTER J) 6630 0xFF4B k (FULLWIDTH LATIN SMALL LETTER K) 6631 0xFF4C l (FULLWIDTH LATIN SMALL LETTER L) 6632 0xFF4D m (FULLWIDTH LATIN SMALL LETTER M) 6633 0xFF4E n (FULLWIDTH LATIN SMALL LETTER N) 6634 0xFF4F o (FULLWIDTH LATIN SMALL LETTER O) 6635 0xFF50 p (FULLWIDTH LATIN SMALL LETTER P) 6636 0xFF51 q (FULLWIDTH LATIN SMALL LETTER Q) 6637 0xFF52 r (FULLWIDTH LATIN SMALL LETTER R) 6638 0xFF53 s (FULLWIDTH LATIN SMALL LETTER S) 6639 0xFF54 t (FULLWIDTH LATIN SMALL LETTER T) 6640 0xFF55 u (FULLWIDTH LATIN SMALL LETTER U) 6641 0xFF56 v (FULLWIDTH LATIN SMALL LETTER V) 6642 0xFF57 w (FULLWIDTH LATIN SMALL LETTER W) 6643 0xFF58 x (FULLWIDTH LATIN SMALL LETTER X) 6644 0xFF59 y (FULLWIDTH LATIN SMALL LETTER Y) 6645 0xFF5A z (FULLWIDTH LATIN SMALL LETTER Z) 6646 0xFF5B { (FULLWIDTH LEFT CURLY BRACKET) 6647 0xFF5C | (FULLWIDTH VERTICAL LINE) 6648 0xFF5D } (FULLWIDTH RIGHT CURLY BRACKET) 6649 0xFFE3  ̄ (FULLWIDTH MACRON) 6650 0xC9DE 짞 (HANGUL SYLLABLE JJAGG) 6651 0xC9DF 짟 (HANGUL SYLLABLE JJAGS) 6652 0xC9E1 짡 (HANGUL SYLLABLE JJANJ) 6653 0xC9E3 짣 (HANGUL SYLLABLE JJAD) 6654 0xC9E5 짥 (HANGUL SYLLABLE JJALG) 6655 0xC9E6 짦 (HANGUL SYLLABLE JJALM) 6656 0xC9E8 짨 (HANGUL SYLLABLE JJALS) 6657 0xC9E9 짩 (HANGUL SYLLABLE JJALT) 6658 0xC9EA 짪 (HANGUL SYLLABLE JJALP) 6659 0xC9EB 짫 (HANGUL SYLLABLE JJALH) 6660 0xC9EE 짮 (HANGUL SYLLABLE JJABS) 6661 0xC9F2 짲 (HANGUL SYLLABLE JJAJ) 6662 0xC9F3 짳 (HANGUL SYLLABLE JJAC) 6663 0xC9F4 짴 (HANGUL SYLLABLE JJAK) 6664 0xC9F5 짵 (HANGUL SYLLABLE JJAT) 6665 0xC9F6 짶 (HANGUL SYLLABLE JJAP) 6666 0xC9F7 짷 (HANGUL SYLLABLE JJAH) 6667 0xC9FA 짺 (HANGUL SYLLABLE JJAEGG) 6668 0xC9FB 짻 (HANGUL SYLLABLE JJAEGS) 6669 0xC9FD 짽 (HANGUL SYLLABLE JJAENJ) 6670 0xC9FE 짾 (HANGUL SYLLABLE JJAENH) 6671 0xC9FF 짿 (HANGUL SYLLABLE JJAED) 6672 0xCA01 쨁 (HANGUL SYLLABLE JJAELG) 6673 0xCA02 쨂 (HANGUL SYLLABLE JJAELM) 6674 0xCA03 쨃 (HANGUL SYLLABLE JJAELB) 6675 0xCA04 쨄 (HANGUL SYLLABLE JJAELS) 6682 0xCA05 쨅 (HANGUL SYLLABLE JJAELT) 6683 0xCA06 쨆 (HANGUL SYLLABLE JJAELP) 6684 0xCA07 쨇 (HANGUL SYLLABLE JJAELH) 6685 0xCA0A 쨊 (HANGUL SYLLABLE JJAEBS) 6686 0xCA0E 쨎 (HANGUL SYLLABLE JJAEJ) 6687 0xCA0F 쨏 (HANGUL SYLLABLE JJAEC) 6688 0xCA10 쨐 (HANGUL SYLLABLE JJAEK) 6689 0xCA11 쨑 (HANGUL SYLLABLE JJAET) 6690 0xCA12 쨒 (HANGUL SYLLABLE JJAEP) 6691 0xCA13 쨓 (HANGUL SYLLABLE JJAEH) 6692 0xCA15 쨕 (HANGUL SYLLABLE JJYAG) 6693 0xCA16 쨖 (HANGUL SYLLABLE JJYAGG) 6694 0xCA17 쨗 (HANGUL SYLLABLE JJYAGS) 6695 0xCA19 쨙 (HANGUL SYLLABLE JJYANJ) 6696 0xCA1A 쨚 (HANGUL SYLLABLE JJYANH) 6697 0xCA1B 쨛 (HANGUL SYLLABLE JJYAD) 6698 0xCA1C 쨜 (HANGUL SYLLABLE JJYAL) 6699 0xCA1D 쨝 (HANGUL SYLLABLE JJYALG) 6700 0xCA1E 쨞 (HANGUL SYLLABLE JJYALM) 6701 0xCA1F 쨟 (HANGUL SYLLABLE JJYALB) 6702 0xCA20 쨠 (HANGUL SYLLABLE JJYALS) 6703 0xCA21 쨡 (HANGUL SYLLABLE JJYALT) 6704 0xCA22 쨢 (HANGUL SYLLABLE JJYALP) 6705 0xCA23 쨣 (HANGUL SYLLABLE JJYALH) 6706 0xCA24 쨤 (HANGUL SYLLABLE JJYAM) 6707 0xCA25 쨥 (HANGUL SYLLABLE JJYAB) 6714 0xCA26 쨦 (HANGUL SYLLABLE JJYABS) 6715 0xCA27 쨧 (HANGUL SYLLABLE JJYAS) 6716 0xCA28 쨨 (HANGUL SYLLABLE JJYASS) 6717 0xCA2A 쨪 (HANGUL SYLLABLE JJYAJ) 6718 0xCA2B 쨫 (HANGUL SYLLABLE JJYAC) 6719 0xCA2C 쨬 (HANGUL SYLLABLE JJYAK) 6720 0xCA2D 쨭 (HANGUL SYLLABLE JJYAT) 6721 0xCA2E 쨮 (HANGUL SYLLABLE JJYAP) 6722 0xCA2F 쨯 (HANGUL SYLLABLE JJYAH) 6723 0xCA30 쨰 (HANGUL SYLLABLE JJYAE) 6724 0xCA31 쨱 (HANGUL SYLLABLE JJYAEG) 6725 0xCA32 쨲 (HANGUL SYLLABLE JJYAEGG) 6726 0xCA33 쨳 (HANGUL SYLLABLE JJYAEGS) 6727 0xCA34 쨴 (HANGUL SYLLABLE JJYAEN) 6728 0xCA35 쨵 (HANGUL SYLLABLE JJYAENJ) 6729 0xCA36 쨶 (HANGUL SYLLABLE JJYAENH) 6730 0xCA37 쨷 (HANGUL SYLLABLE JJYAED) 6731 0xCA38 쨸 (HANGUL SYLLABLE JJYAEL) 6732 0xCA39 쨹 (HANGUL SYLLABLE JJYAELG) 6733 0xCA3A 쨺 (HANGUL SYLLABLE JJYAELM) 6734 0xCA3B 쨻 (HANGUL SYLLABLE JJYAELB) 6735 0xCA3C 쨼 (HANGUL SYLLABLE JJYAELS) 6736 0xCA3D 쨽 (HANGUL SYLLABLE JJYAELT) 6737 0xCA3E 쨾 (HANGUL SYLLABLE JJYAELP) 6738 0xCA3F 쨿 (HANGUL SYLLABLE JJYAELH) 6739 0xCA40 쩀 (HANGUL SYLLABLE JJYAEM) 6740 0xCA41 쩁 (HANGUL SYLLABLE JJYAEB) 6741 0xCA42 쩂 (HANGUL SYLLABLE JJYAEBS) 6742 0xCA43 쩃 (HANGUL SYLLABLE JJYAES) 6743 0xCA44 쩄 (HANGUL SYLLABLE JJYAESS) 6744 0xCA45 쩅 (HANGUL SYLLABLE JJYAENG) 6745 0xCA46 쩆 (HANGUL SYLLABLE JJYAEJ) 6746 0x3131 ㄱ (HANGUL LETTER KIYEOK) 6747 0x3132 ㄲ (HANGUL LETTER SSANGKIYEOK) 6748 0x3133 ㄳ (HANGUL LETTER KIYEOK-SIOS) 6749 0x3134 ㄴ (HANGUL LETTER NIEUN) 6750 0x3135 ㄵ (HANGUL LETTER NIEUN-CIEUC) 6751 0x3136 ㄶ (HANGUL LETTER NIEUN-HIEUH) 6752 0x3137 ㄷ (HANGUL LETTER TIKEUT) 6753 0x3138 ㄸ (HANGUL LETTER SSANGTIKEUT) 6754 0x3139 ㄹ (HANGUL LETTER RIEUL) 6755 0x313A ㄺ (HANGUL LETTER RIEUL-KIYEOK) 6756 0x313B ㄻ (HANGUL LETTER RIEUL-MIEUM) 6757 0x313C ㄼ (HANGUL LETTER RIEUL-PIEUP) 6758 0x313D ㄽ (HANGUL LETTER RIEUL-SIOS) 6759 0x313E ㄾ (HANGUL LETTER RIEUL-THIEUTH) 6760 0x313F ㄿ (HANGUL LETTER RIEUL-PHIEUPH) 6761 0x3140 ㅀ (HANGUL LETTER RIEUL-HIEUH) 6762 0x3141 ㅁ (HANGUL LETTER MIEUM) 6763 0x3142 ㅂ (HANGUL LETTER PIEUP) 6764 0x3143 ㅃ (HANGUL LETTER SSANGPIEUP) 6765 0x3144 ㅄ (HANGUL LETTER PIEUP-SIOS) 6766 0x3145 ㅅ (HANGUL LETTER SIOS) 6767 0x3146 ㅆ (HANGUL LETTER SSANGSIOS) 6768 0x3147 ㅇ (HANGUL LETTER IEUNG) 6769 0x3148 ㅈ (HANGUL LETTER CIEUC) 6770 0x3149 ㅉ (HANGUL LETTER SSANGCIEUC) 6771 0x314A ㅊ (HANGUL LETTER CHIEUCH) 6772 0x314B ㅋ (HANGUL LETTER KHIEUKH) 6773 0x314C ㅌ (HANGUL LETTER THIEUTH) 6774 0x314D ㅍ (HANGUL LETTER PHIEUPH) 6775 0x314E ㅎ (HANGUL LETTER HIEUH) 6776 0x314F ㅏ (HANGUL LETTER A) 6777 0x3150 ㅐ (HANGUL LETTER AE) 6778 0x3151 ㅑ (HANGUL LETTER YA) 6779 0x3152 ㅒ (HANGUL LETTER YAE) 6780 0x3153 ㅓ (HANGUL LETTER EO) 6781 0x3154 ㅔ (HANGUL LETTER E) 6782 0x3155 ㅕ (HANGUL LETTER YEO) 6783 0x3156 ㅖ (HANGUL LETTER YE) 6784 0x3157 ㅗ (HANGUL LETTER O) 6785 0x3158 ㅘ (HANGUL LETTER WA) 6786 0x3159 ㅙ (HANGUL LETTER WAE) 6787 0x315A ㅚ (HANGUL LETTER OE) 6788 0x315B ㅛ (HANGUL LETTER YO) 6789 0x315C ㅜ (HANGUL LETTER U) 6790 0x315D ㅝ (HANGUL LETTER WEO) 6791 0x315E ㅞ (HANGUL LETTER WE) 6792 0x315F ㅟ (HANGUL LETTER WI) 6793 0x3160 ㅠ (HANGUL LETTER YU) 6794 0x3161 ㅡ (HANGUL LETTER EU) 6795 0x3162 ㅢ (HANGUL LETTER YI) 6796 0x3163 ㅣ (HANGUL LETTER I) 6797 0x3164 ㅤ (HANGUL FILLER) 6798 0x3165 ㅥ (HANGUL LETTER SSANGNIEUN) 6799 0x3166 ㅦ (HANGUL LETTER NIEUN-TIKEUT) 6800 0x3167 ㅧ (HANGUL LETTER NIEUN-SIOS) 6801 0x3168 ㅨ (HANGUL LETTER NIEUN-PANSIOS) 6802 0x3169 ㅩ (HANGUL LETTER RIEUL-KIYEOK-SIOS) 6803 0x316A ㅪ (HANGUL LETTER RIEUL-TIKEUT) 6804 0x316B ㅫ (HANGUL LETTER RIEUL-PIEUP-SIOS) 6805 0x316C ㅬ (HANGUL LETTER RIEUL-PANSIOS) 6806 0x316D ㅭ (HANGUL LETTER RIEUL-YEORINHIEUH) 6807 0x316E ㅮ (HANGUL LETTER MIEUM-PIEUP) 6808 0x316F ㅯ (HANGUL LETTER MIEUM-SIOS) 6809 0x3170 ㅰ (HANGUL LETTER MIEUM-PANSIOS) 6810 0x3171 ㅱ (HANGUL LETTER KAPYEOUNMIEUM) 6811 0x3172 ㅲ (HANGUL LETTER PIEUP-KIYEOK) 6812 0x3173 ㅳ (HANGUL LETTER PIEUP-TIKEUT) 6813 0x3174 ㅴ (HANGUL LETTER PIEUP-SIOS-KIYEOK) 6814 0x3175 ㅵ (HANGUL LETTER PIEUP-SIOS-TIKEUT) 6815 0x3176 ㅶ (HANGUL LETTER PIEUP-CIEUC) 6816 0x3177 ㅷ (HANGUL LETTER PIEUP-THIEUTH) 6817 0x3178 ㅸ (HANGUL LETTER KAPYEOUNPIEUP) 6818 0x3179 ㅹ (HANGUL LETTER KAPYEOUNSSANGPIEUP) 6819 0x317A ㅺ (HANGUL LETTER SIOS-KIYEOK) 6820 0x317B ㅻ (HANGUL LETTER SIOS-NIEUN) 6821 0x317C ㅼ (HANGUL LETTER SIOS-TIKEUT) 6822 0x317D ㅽ (HANGUL LETTER SIOS-PIEUP) 6823 0x317E ㅾ (HANGUL LETTER SIOS-CIEUC) 6824 0x317F ㅿ (HANGUL LETTER PANSIOS) 6825 0x3180 ㆀ (HANGUL LETTER SSANGIEUNG) 6826 0x3181 ㆁ (HANGUL LETTER YESIEUNG) 6827 0x3182 ㆂ (HANGUL LETTER YESIEUNG-SIOS) 6828 0x3183 ㆃ (HANGUL LETTER YESIEUNG-PANSIOS) 6829 0x3184 ㆄ (HANGUL LETTER KAPYEOUNPHIEUPH) 6830 0x3185 ㆅ (HANGUL LETTER SSANGHIEUH) 6831 0x3186 ㆆ (HANGUL LETTER YEORINHIEUH) 6832 0x3187 ㆇ (HANGUL LETTER YO-YA) 6833 0x3188 ㆈ (HANGUL LETTER YO-YAE) 6834 0x3189 ㆉ (HANGUL LETTER YO-I) 6835 0x318A ㆊ (HANGUL LETTER YU-YEO) 6836 0x318B ㆋ (HANGUL LETTER YU-YE) 6837 0x318C ㆌ (HANGUL LETTER YU-I) 6838 0x318D ㆍ (HANGUL LETTER ARAEA) 6839 0x318E ㆎ (HANGUL LETTER ARAEAE) 6840 0xCA47 쩇 (HANGUL SYLLABLE JJYAEC) 6841 0xCA48 쩈 (HANGUL SYLLABLE JJYAEK) 6842 0xCA49 쩉 (HANGUL SYLLABLE JJYAET) 6843 0xCA4A 쩊 (HANGUL SYLLABLE JJYAEP) 6844 0xCA4B 쩋 (HANGUL SYLLABLE JJYAEH) 6845 0xCA4E 쩎 (HANGUL SYLLABLE JJEOGG) 6846 0xCA4F 쩏 (HANGUL SYLLABLE JJEOGS) 6847 0xCA51 쩑 (HANGUL SYLLABLE JJEONJ) 6848 0xCA52 쩒 (HANGUL SYLLABLE JJEONH) 6849 0xCA53 쩓 (HANGUL SYLLABLE JJEOD) 6850 0xCA55 쩕 (HANGUL SYLLABLE JJEOLG) 6851 0xCA56 쩖 (HANGUL SYLLABLE JJEOLM) 6852 0xCA57 쩗 (HANGUL SYLLABLE JJEOLB) 6853 0xCA58 쩘 (HANGUL SYLLABLE JJEOLS) 6854 0xCA59 쩙 (HANGUL SYLLABLE JJEOLT) 6855 0xCA5A 쩚 (HANGUL SYLLABLE JJEOLP) 6856 0xCA5B 쩛 (HANGUL SYLLABLE JJEOLH) 6857 0xCA5E 쩞 (HANGUL SYLLABLE JJEOBS) 6858 0xCA62 쩢 (HANGUL SYLLABLE JJEOJ) 6859 0xCA63 쩣 (HANGUL SYLLABLE JJEOC) 6860 0xCA64 쩤 (HANGUL SYLLABLE JJEOK) 6861 0xCA65 쩥 (HANGUL SYLLABLE JJEOT) 6862 0xCA66 쩦 (HANGUL SYLLABLE JJEOP) 6863 0xCA67 쩧 (HANGUL SYLLABLE JJEOH) 6864 0xCA69 쩩 (HANGUL SYLLABLE JJEG) 6865 0xCA6A 쩪 (HANGUL SYLLABLE JJEGG) 6872 0xCA6B 쩫 (HANGUL SYLLABLE JJEGS) 6873 0xCA6C 쩬 (HANGUL SYLLABLE JJEN) 6874 0xCA6D 쩭 (HANGUL SYLLABLE JJENJ) 6875 0xCA6E 쩮 (HANGUL SYLLABLE JJENH) 6876 0xCA6F 쩯 (HANGUL SYLLABLE JJED) 6877 0xCA70 쩰 (HANGUL SYLLABLE JJEL) 6878 0xCA71 쩱 (HANGUL SYLLABLE JJELG) 6879 0xCA72 쩲 (HANGUL SYLLABLE JJELM) 6880 0xCA73 쩳 (HANGUL SYLLABLE JJELB) 6881 0xCA74 쩴 (HANGUL SYLLABLE JJELS) 6882 0xCA75 쩵 (HANGUL SYLLABLE JJELT) 6883 0xCA76 쩶 (HANGUL SYLLABLE JJELP) 6884 0xCA77 쩷 (HANGUL SYLLABLE JJELH) 6885 0xCA78 쩸 (HANGUL SYLLABLE JJEM) 6886 0xCA79 쩹 (HANGUL SYLLABLE JJEB) 6887 0xCA7A 쩺 (HANGUL SYLLABLE JJEBS) 6888 0xCA7B 쩻 (HANGUL SYLLABLE JJES) 6889 0xCA7C 쩼 (HANGUL SYLLABLE JJESS) 6890 0xCA7E 쩾 (HANGUL SYLLABLE JJEJ) 6891 0xCA7F 쩿 (HANGUL SYLLABLE JJEC) 6892 0xCA80 쪀 (HANGUL SYLLABLE JJEK) 6893 0xCA81 쪁 (HANGUL SYLLABLE JJET) 6894 0xCA82 쪂 (HANGUL SYLLABLE JJEP) 6895 0xCA83 쪃 (HANGUL SYLLABLE JJEH) 6896 0xCA85 쪅 (HANGUL SYLLABLE JJYEOG) 6897 0xCA86 쪆 (HANGUL SYLLABLE JJYEOGG) 6904 0xCA87 쪇 (HANGUL SYLLABLE JJYEOGS) 6905 0xCA88 쪈 (HANGUL SYLLABLE JJYEON) 6906 0xCA89 쪉 (HANGUL SYLLABLE JJYEONJ) 6907 0xCA8A 쪊 (HANGUL SYLLABLE JJYEONH) 6908 0xCA8B 쪋 (HANGUL SYLLABLE JJYEOD) 6909 0xCA8C 쪌 (HANGUL SYLLABLE JJYEOL) 6910 0xCA8D 쪍 (HANGUL SYLLABLE JJYEOLG) 6911 0xCA8E 쪎 (HANGUL SYLLABLE JJYEOLM) 6912 0xCA8F 쪏 (HANGUL SYLLABLE JJYEOLB) 6913 0xCA90 쪐 (HANGUL SYLLABLE JJYEOLS) 6914 0xCA91 쪑 (HANGUL SYLLABLE JJYEOLT) 6915 0xCA92 쪒 (HANGUL SYLLABLE JJYEOLP) 6916 0xCA93 쪓 (HANGUL SYLLABLE JJYEOLH) 6917 0xCA94 쪔 (HANGUL SYLLABLE JJYEOM) 6918 0xCA95 쪕 (HANGUL SYLLABLE JJYEOB) 6919 0xCA96 쪖 (HANGUL SYLLABLE JJYEOBS) 6920 0xCA97 쪗 (HANGUL SYLLABLE JJYEOS) 6921 0xCA99 쪙 (HANGUL SYLLABLE JJYEONG) 6922 0xCA9A 쪚 (HANGUL SYLLABLE JJYEOJ) 6923 0xCA9B 쪛 (HANGUL SYLLABLE JJYEOC) 6924 0xCA9C 쪜 (HANGUL SYLLABLE JJYEOK) 6925 0xCA9D 쪝 (HANGUL SYLLABLE JJYEOT) 6926 0xCA9E 쪞 (HANGUL SYLLABLE JJYEOP) 6927 0xCA9F 쪟 (HANGUL SYLLABLE JJYEOH) 6928 0xCAA0 쪠 (HANGUL SYLLABLE JJYE) 6929 0xCAA1 쪡 (HANGUL SYLLABLE JJYEG) 6930 0xCAA2 쪢 (HANGUL SYLLABLE JJYEGG) 6931 0xCAA3 쪣 (HANGUL SYLLABLE JJYEGS) 6932 0xCAA4 쪤 (HANGUL SYLLABLE JJYEN) 6933 0xCAA5 쪥 (HANGUL SYLLABLE JJYENJ) 6934 0xCAA6 쪦 (HANGUL SYLLABLE JJYENH) 6935 0xCAA7 쪧 (HANGUL SYLLABLE JJYED) 6936 0x2170 ⅰ (SMALL ROMAN NUMERAL ONE) 6937 0x2171 ⅱ (SMALL ROMAN NUMERAL TWO) 6938 0x2172 ⅲ (SMALL ROMAN NUMERAL THREE) 6939 0x2173 ⅳ (SMALL ROMAN NUMERAL FOUR) 6940 0x2174 ⅴ (SMALL ROMAN NUMERAL FIVE) 6941 0x2175 ⅵ (SMALL ROMAN NUMERAL SIX) 6942 0x2176 ⅶ (SMALL ROMAN NUMERAL SEVEN) 6943 0x2177 ⅷ (SMALL ROMAN NUMERAL EIGHT) 6944 0x2178 ⅸ (SMALL ROMAN NUMERAL NINE) 6945 0x2179 ⅹ (SMALL ROMAN NUMERAL TEN) 6951 0x2160 Ⅰ (ROMAN NUMERAL ONE) 6952 0x2161 Ⅱ (ROMAN NUMERAL TWO) 6953 0x2162 Ⅲ (ROMAN NUMERAL THREE) 6954 0x2163 Ⅳ (ROMAN NUMERAL FOUR) 6955 0x2164 Ⅴ (ROMAN NUMERAL FIVE) 6956 0x2165 Ⅵ (ROMAN NUMERAL SIX) 6957 0x2166 Ⅶ (ROMAN NUMERAL SEVEN) 6958 0x2167 Ⅷ (ROMAN NUMERAL EIGHT) 6959 0x2168 Ⅸ (ROMAN NUMERAL NINE) 6960 0x2169 Ⅹ (ROMAN NUMERAL TEN) 6968 0x0391 Α (GREEK CAPITAL LETTER ALPHA) 6969 0x0392 Β (GREEK CAPITAL LETTER BETA) 6970 0x0393 Γ (GREEK CAPITAL LETTER GAMMA) 6971 0x0394 Δ (GREEK CAPITAL LETTER DELTA) 6972 0x0395 Ε (GREEK CAPITAL LETTER EPSILON) 6973 0x0396 Ζ (GREEK CAPITAL LETTER ZETA) 6974 0x0397 Η (GREEK CAPITAL LETTER ETA) 6975 0x0398 Θ (GREEK CAPITAL LETTER THETA) 6976 0x0399 Ι (GREEK CAPITAL LETTER IOTA) 6977 0x039A Κ (GREEK CAPITAL LETTER KAPPA) 6978 0x039B Λ (GREEK CAPITAL LETTER LAMDA) 6979 0x039C Μ (GREEK CAPITAL LETTER MU) 6980 0x039D Ν (GREEK CAPITAL LETTER NU) 6981 0x039E Ξ (GREEK CAPITAL LETTER XI) 6982 0x039F Ο (GREEK CAPITAL LETTER OMICRON) 6983 0x03A0 Π (GREEK CAPITAL LETTER PI) 6984 0x03A1 Ρ (GREEK CAPITAL LETTER RHO) 6985 0x03A3 Σ (GREEK CAPITAL LETTER SIGMA) 6986 0x03A4 Τ (GREEK CAPITAL LETTER TAU) 6987 0x03A5 Υ (GREEK CAPITAL LETTER UPSILON) 6988 0x03A6 Φ (GREEK CAPITAL LETTER PHI) 6989 0x03A7 Χ (GREEK CAPITAL LETTER CHI) 6990 0x03A8 Ψ (GREEK CAPITAL LETTER PSI) 6991 0x03A9 Ω (GREEK CAPITAL LETTER OMEGA) 7000 0x03B1 α (GREEK SMALL LETTER ALPHA) 7001 0x03B2 β (GREEK SMALL LETTER BETA) 7002 0x03B3 γ (GREEK SMALL LETTER GAMMA) 7003 0x03B4 δ (GREEK SMALL LETTER DELTA) 7004 0x03B5 ε (GREEK SMALL LETTER EPSILON) 7005 0x03B6 ζ (GREEK SMALL LETTER ZETA) 7006 0x03B7 η (GREEK SMALL LETTER ETA) 7007 0x03B8 θ (GREEK SMALL LETTER THETA) 7008 0x03B9 ι (GREEK SMALL LETTER IOTA) 7009 0x03BA κ (GREEK SMALL LETTER KAPPA) 7010 0x03BB λ (GREEK SMALL LETTER LAMDA) 7011 0x03BC μ (GREEK SMALL LETTER MU) 7012 0x03BD ν (GREEK SMALL LETTER NU) 7013 0x03BE ξ (GREEK SMALL LETTER XI) 7014 0x03BF ο (GREEK SMALL LETTER OMICRON) 7015 0x03C0 π (GREEK SMALL LETTER PI) 7016 0x03C1 ρ (GREEK SMALL LETTER RHO) 7017 0x03C3 σ (GREEK SMALL LETTER SIGMA) 7018 0x03C4 τ (GREEK SMALL LETTER TAU) 7019 0x03C5 υ (GREEK SMALL LETTER UPSILON) 7020 0x03C6 φ (GREEK SMALL LETTER PHI) 7021 0x03C7 χ (GREEK SMALL LETTER CHI) 7022 0x03C8 ψ (GREEK SMALL LETTER PSI) 7023 0x03C9 ω (GREEK SMALL LETTER OMEGA) 7030 0xCAA8 쪨 (HANGUL SYLLABLE JJYEL) 7031 0xCAA9 쪩 (HANGUL SYLLABLE JJYELG) 7032 0xCAAA 쪪 (HANGUL SYLLABLE JJYELM) 7033 0xCAAB 쪫 (HANGUL SYLLABLE JJYELB) 7034 0xCAAC 쪬 (HANGUL SYLLABLE JJYELS) 7035 0xCAAD 쪭 (HANGUL SYLLABLE JJYELT) 7036 0xCAAE 쪮 (HANGUL SYLLABLE JJYELP) 7037 0xCAAF 쪯 (HANGUL SYLLABLE JJYELH) 7038 0xCAB0 쪰 (HANGUL SYLLABLE JJYEM) 7039 0xCAB1 쪱 (HANGUL SYLLABLE JJYEB) 7040 0xCAB2 쪲 (HANGUL SYLLABLE JJYEBS) 7041 0xCAB3 쪳 (HANGUL SYLLABLE JJYES) 7042 0xCAB4 쪴 (HANGUL SYLLABLE JJYESS) 7043 0xCAB5 쪵 (HANGUL SYLLABLE JJYENG) 7044 0xCAB6 쪶 (HANGUL SYLLABLE JJYEJ) 7045 0xCAB7 쪷 (HANGUL SYLLABLE JJYEC) 7046 0xCAB8 쪸 (HANGUL SYLLABLE JJYEK) 7047 0xCAB9 쪹 (HANGUL SYLLABLE JJYET) 7048 0xCABA 쪺 (HANGUL SYLLABLE JJYEP) 7049 0xCABB 쪻 (HANGUL SYLLABLE JJYEH) 7050 0xCABE 쪾 (HANGUL SYLLABLE JJOGG) 7051 0xCABF 쪿 (HANGUL SYLLABLE JJOGS) 7052 0xCAC1 쫁 (HANGUL SYLLABLE JJONJ) 7053 0xCAC2 쫂 (HANGUL SYLLABLE JJONH) 7054 0xCAC3 쫃 (HANGUL SYLLABLE JJOD) 7055 0xCAC5 쫅 (HANGUL SYLLABLE JJOLG) 7062 0xCAC6 쫆 (HANGUL SYLLABLE JJOLM) 7063 0xCAC7 쫇 (HANGUL SYLLABLE JJOLB) 7064 0xCAC8 쫈 (HANGUL SYLLABLE JJOLS) 7065 0xCAC9 쫉 (HANGUL SYLLABLE JJOLT) 7066 0xCACA 쫊 (HANGUL SYLLABLE JJOLP) 7067 0xCACB 쫋 (HANGUL SYLLABLE JJOLH) 7068 0xCACE 쫎 (HANGUL SYLLABLE JJOBS) 7069 0xCAD0 쫐 (HANGUL SYLLABLE JJOSS) 7070 0xCAD2 쫒 (HANGUL SYLLABLE JJOJ) 7071 0xCAD4 쫔 (HANGUL SYLLABLE JJOK) 7072 0xCAD5 쫕 (HANGUL SYLLABLE JJOT) 7073 0xCAD6 쫖 (HANGUL SYLLABLE JJOP) 7074 0xCAD7 쫗 (HANGUL SYLLABLE JJOH) 7075 0xCADA 쫚 (HANGUL SYLLABLE JJWAGG) 7076 0xCADB 쫛 (HANGUL SYLLABLE JJWAGS) 7077 0xCADC 쫜 (HANGUL SYLLABLE JJWAN) 7078 0xCADD 쫝 (HANGUL SYLLABLE JJWANJ) 7079 0xCADE 쫞 (HANGUL SYLLABLE JJWANH) 7080 0xCADF 쫟 (HANGUL SYLLABLE JJWAD) 7081 0xCAE1 쫡 (HANGUL SYLLABLE JJWALG) 7082 0xCAE2 쫢 (HANGUL SYLLABLE JJWALM) 7083 0xCAE3 쫣 (HANGUL SYLLABLE JJWALB) 7084 0xCAE4 쫤 (HANGUL SYLLABLE JJWALS) 7085 0xCAE5 쫥 (HANGUL SYLLABLE JJWALT) 7086 0xCAE6 쫦 (HANGUL SYLLABLE JJWALP) 7087 0xCAE7 쫧 (HANGUL SYLLABLE JJWALH) 7094 0xCAE8 쫨 (HANGUL SYLLABLE JJWAM) 7095 0xCAE9 쫩 (HANGUL SYLLABLE JJWAB) 7096 0xCAEA 쫪 (HANGUL SYLLABLE JJWABS) 7097 0xCAEB 쫫 (HANGUL SYLLABLE JJWAS) 7098 0xCAED 쫭 (HANGUL SYLLABLE JJWANG) 7099 0xCAEE 쫮 (HANGUL SYLLABLE JJWAJ) 7100 0xCAEF 쫯 (HANGUL SYLLABLE JJWAC) 7101 0xCAF0 쫰 (HANGUL SYLLABLE JJWAK) 7102 0xCAF1 쫱 (HANGUL SYLLABLE JJWAT) 7103 0xCAF2 쫲 (HANGUL SYLLABLE JJWAP) 7104 0xCAF3 쫳 (HANGUL SYLLABLE JJWAH) 7105 0xCAF5 쫵 (HANGUL SYLLABLE JJWAEG) 7106 0xCAF6 쫶 (HANGUL SYLLABLE JJWAEGG) 7107 0xCAF7 쫷 (HANGUL SYLLABLE JJWAEGS) 7108 0xCAF8 쫸 (HANGUL SYLLABLE JJWAEN) 7109 0xCAF9 쫹 (HANGUL SYLLABLE JJWAENJ) 7110 0xCAFA 쫺 (HANGUL SYLLABLE JJWAENH) 7111 0xCAFB 쫻 (HANGUL SYLLABLE JJWAED) 7112 0xCAFC 쫼 (HANGUL SYLLABLE JJWAEL) 7113 0xCAFD 쫽 (HANGUL SYLLABLE JJWAELG) 7114 0xCAFE 쫾 (HANGUL SYLLABLE JJWAELM) 7115 0xCAFF 쫿 (HANGUL SYLLABLE JJWAELB) 7116 0xCB00 쬀 (HANGUL SYLLABLE JJWAELS) 7117 0xCB01 쬁 (HANGUL SYLLABLE JJWAELT) 7118 0xCB02 쬂 (HANGUL SYLLABLE JJWAELP) 7119 0xCB03 쬃 (HANGUL SYLLABLE JJWAELH) 7120 0xCB04 쬄 (HANGUL SYLLABLE JJWAEM) 7121 0xCB05 쬅 (HANGUL SYLLABLE JJWAEB) 7122 0xCB06 쬆 (HANGUL SYLLABLE JJWAEBS) 7123 0xCB07 쬇 (HANGUL SYLLABLE JJWAES) 7124 0xCB09 쬉 (HANGUL SYLLABLE JJWAENG) 7125 0xCB0A 쬊 (HANGUL SYLLABLE JJWAEJ) 7126 0x2500 ─ (BOX DRAWINGS LIGHT HORIZONTAL) 7127 0x2502 │ (BOX DRAWINGS LIGHT VERTICAL) 7128 0x250C ┌ (BOX DRAWINGS LIGHT DOWN AND RIGHT) 7129 0x2510 ┐ (BOX DRAWINGS LIGHT DOWN AND LEFT) 7130 0x2518 ┘ (BOX DRAWINGS LIGHT UP AND LEFT) 7131 0x2514 └ (BOX DRAWINGS LIGHT UP AND RIGHT) 7132 0x251C ├ (BOX DRAWINGS LIGHT VERTICAL AND RIGHT) 7133 0x252C ┬ (BOX DRAWINGS LIGHT DOWN AND HORIZONTAL) 7134 0x2524 ┤ (BOX DRAWINGS LIGHT VERTICAL AND LEFT) 7135 0x2534 ┴ (BOX DRAWINGS LIGHT UP AND HORIZONTAL) 7136 0x253C ┼ (BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL) 7137 0x2501 ━ (BOX DRAWINGS HEAVY HORIZONTAL) 7138 0x2503 ┃ (BOX DRAWINGS HEAVY VERTICAL) 7139 0x250F ┏ (BOX DRAWINGS HEAVY DOWN AND RIGHT) 7140 0x2513 ┓ (BOX DRAWINGS HEAVY DOWN AND LEFT) 7141 0x251B ┛ (BOX DRAWINGS HEAVY UP AND LEFT) 7142 0x2517 ┗ (BOX DRAWINGS HEAVY UP AND RIGHT) 7143 0x2523 ┣ (BOX DRAWINGS HEAVY VERTICAL AND RIGHT) 7144 0x2533 ┳ (BOX DRAWINGS HEAVY DOWN AND HORIZONTAL) 7145 0x252B ┫ (BOX DRAWINGS HEAVY VERTICAL AND LEFT) 7146 0x253B ┻ (BOX DRAWINGS HEAVY UP AND HORIZONTAL) 7147 0x254B ╋ (BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL) 7148 0x2520 ┠ (BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT) 7149 0x252F ┯ (BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY) 7150 0x2528 ┨ (BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT) 7151 0x2537 ┷ (BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY) 7152 0x253F ┿ (BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY) 7153 0x251D ┝ (BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY) 7154 0x2530 ┰ (BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT) 7155 0x2525 ┥ (BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY) 7156 0x2538 ┸ (BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT) 7157 0x2542 ╂ (BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT) 7158 0x2512 ┒ (BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT) 7159 0x2511 ┑ (BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY) 7160 0x251A ┚ (BOX DRAWINGS UP HEAVY AND LEFT LIGHT) 7161 0x2519 ┙ (BOX DRAWINGS UP LIGHT AND LEFT HEAVY) 7162 0x2516 ┖ (BOX DRAWINGS UP HEAVY AND RIGHT LIGHT) 7163 0x2515 ┕ (BOX DRAWINGS UP LIGHT AND RIGHT HEAVY) 7164 0x250E ┎ (BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT) 7165 0x250D ┍ (BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY) 7166 0x251E ┞ (BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT) 7167 0x251F ┟ (BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT) 7168 0x2521 ┡ (BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY) 7169 0x2522 ┢ (BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY) 7170 0x2526 ┦ (BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT) 7171 0x2527 ┧ (BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT) 7172 0x2529 ┩ (BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY) 7173 0x252A ┪ (BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY) 7174 0x252D ┭ (BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT) 7175 0x252E ┮ (BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT) 7176 0x2531 ┱ (BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY) 7177 0x2532 ┲ (BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY) 7178 0x2535 ┵ (BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT) 7179 0x2536 ┶ (BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT) 7180 0x2539 ┹ (BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY) 7181 0x253A ┺ (BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY) 7182 0x253D ┽ (BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT) 7183 0x253E ┾ (BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT) 7184 0x2540 ╀ (BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT) 7185 0x2541 ╁ (BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT) 7186 0x2543 ╃ (BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT) 7187 0x2544 ╄ (BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT) 7188 0x2545 ╅ (BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT) 7189 0x2546 ╆ (BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT) 7190 0x2547 ╇ (BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY) 7191 0x2548 ╈ (BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY) 7192 0x2549 ╉ (BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY) 7193 0x254A ╊ (BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY) 7220 0xCB0B 쬋 (HANGUL SYLLABLE JJWAEC) 7221 0xCB0C 쬌 (HANGUL SYLLABLE JJWAEK) 7222 0xCB0D 쬍 (HANGUL SYLLABLE JJWAET) 7223 0xCB0E 쬎 (HANGUL SYLLABLE JJWAEP) 7224 0xCB0F 쬏 (HANGUL SYLLABLE JJWAEH) 7225 0xCB11 쬑 (HANGUL SYLLABLE JJOEG) 7226 0xCB12 쬒 (HANGUL SYLLABLE JJOEGG) 7227 0xCB13 쬓 (HANGUL SYLLABLE JJOEGS) 7228 0xCB15 쬕 (HANGUL SYLLABLE JJOENJ) 7229 0xCB16 쬖 (HANGUL SYLLABLE JJOENH) 7230 0xCB17 쬗 (HANGUL SYLLABLE JJOED) 7231 0xCB19 쬙 (HANGUL SYLLABLE JJOELG) 7232 0xCB1A 쬚 (HANGUL SYLLABLE JJOELM) 7233 0xCB1B 쬛 (HANGUL SYLLABLE JJOELB) 7234 0xCB1C 쬜 (HANGUL SYLLABLE JJOELS) 7235 0xCB1D 쬝 (HANGUL SYLLABLE JJOELT) 7236 0xCB1E 쬞 (HANGUL SYLLABLE JJOELP) 7237 0xCB1F 쬟 (HANGUL SYLLABLE JJOELH) 7238 0xCB22 쬢 (HANGUL SYLLABLE JJOEBS) 7239 0xCB23 쬣 (HANGUL SYLLABLE JJOES) 7240 0xCB24 쬤 (HANGUL SYLLABLE JJOESS) 7241 0xCB25 쬥 (HANGUL SYLLABLE JJOENG) 7242 0xCB26 쬦 (HANGUL SYLLABLE JJOEJ) 7243 0xCB27 쬧 (HANGUL SYLLABLE JJOEC) 7244 0xCB28 쬨 (HANGUL SYLLABLE JJOEK) 7245 0xCB29 쬩 (HANGUL SYLLABLE JJOET) 7252 0xCB2A 쬪 (HANGUL SYLLABLE JJOEP) 7253 0xCB2B 쬫 (HANGUL SYLLABLE JJOEH) 7254 0xCB2C 쬬 (HANGUL SYLLABLE JJYO) 7255 0xCB2D 쬭 (HANGUL SYLLABLE JJYOG) 7256 0xCB2E 쬮 (HANGUL SYLLABLE JJYOGG) 7257 0xCB2F 쬯 (HANGUL SYLLABLE JJYOGS) 7258 0xCB30 쬰 (HANGUL SYLLABLE JJYON) 7259 0xCB31 쬱 (HANGUL SYLLABLE JJYONJ) 7260 0xCB32 쬲 (HANGUL SYLLABLE JJYONH) 7261 0xCB33 쬳 (HANGUL SYLLABLE JJYOD) 7262 0xCB34 쬴 (HANGUL SYLLABLE JJYOL) 7263 0xCB35 쬵 (HANGUL SYLLABLE JJYOLG) 7264 0xCB36 쬶 (HANGUL SYLLABLE JJYOLM) 7265 0xCB37 쬷 (HANGUL SYLLABLE JJYOLB) 7266 0xCB38 쬸 (HANGUL SYLLABLE JJYOLS) 7267 0xCB39 쬹 (HANGUL SYLLABLE JJYOLT) 7268 0xCB3A 쬺 (HANGUL SYLLABLE JJYOLP) 7269 0xCB3B 쬻 (HANGUL SYLLABLE JJYOLH) 7270 0xCB3C 쬼 (HANGUL SYLLABLE JJYOM) 7271 0xCB3D 쬽 (HANGUL SYLLABLE JJYOB) 7272 0xCB3E 쬾 (HANGUL SYLLABLE JJYOBS) 7273 0xCB3F 쬿 (HANGUL SYLLABLE JJYOS) 7274 0xCB40 쭀 (HANGUL SYLLABLE JJYOSS) 7275 0xCB42 쭂 (HANGUL SYLLABLE JJYOJ) 7276 0xCB43 쭃 (HANGUL SYLLABLE JJYOC) 7277 0xCB44 쭄 (HANGUL SYLLABLE JJYOK) 7284 0xCB45 쭅 (HANGUL SYLLABLE JJYOT) 7285 0xCB46 쭆 (HANGUL SYLLABLE JJYOP) 7286 0xCB47 쭇 (HANGUL SYLLABLE JJYOH) 7287 0xCB4A 쭊 (HANGUL SYLLABLE JJUGG) 7288 0xCB4B 쭋 (HANGUL SYLLABLE JJUGS) 7289 0xCB4D 쭍 (HANGUL SYLLABLE JJUNJ) 7290 0xCB4E 쭎 (HANGUL SYLLABLE JJUNH) 7291 0xCB4F 쭏 (HANGUL SYLLABLE JJUD) 7292 0xCB51 쭑 (HANGUL SYLLABLE JJULG) 7293 0xCB52 쭒 (HANGUL SYLLABLE JJULM) 7294 0xCB53 쭓 (HANGUL SYLLABLE JJULB) 7295 0xCB54 쭔 (HANGUL SYLLABLE JJULS) 7296 0xCB55 쭕 (HANGUL SYLLABLE JJULT) 7297 0xCB56 쭖 (HANGUL SYLLABLE JJULP) 7298 0xCB57 쭗 (HANGUL SYLLABLE JJULH) 7299 0xCB5A 쭚 (HANGUL SYLLABLE JJUBS) 7300 0xCB5B 쭛 (HANGUL SYLLABLE JJUS) 7301 0xCB5C 쭜 (HANGUL SYLLABLE JJUSS) 7302 0xCB5E 쭞 (HANGUL SYLLABLE JJUJ) 7303 0xCB5F 쭟 (HANGUL SYLLABLE JJUC) 7304 0xCB60 쭠 (HANGUL SYLLABLE JJUK) 7305 0xCB61 쭡 (HANGUL SYLLABLE JJUT) 7306 0xCB62 쭢 (HANGUL SYLLABLE JJUP) 7307 0xCB63 쭣 (HANGUL SYLLABLE JJUH) 7308 0xCB65 쭥 (HANGUL SYLLABLE JJWEOG) 7309 0xCB66 쭦 (HANGUL SYLLABLE JJWEOGG) 7310 0xCB67 쭧 (HANGUL SYLLABLE JJWEOGS) 7311 0xCB68 쭨 (HANGUL SYLLABLE JJWEON) 7312 0xCB69 쭩 (HANGUL SYLLABLE JJWEONJ) 7313 0xCB6A 쭪 (HANGUL SYLLABLE JJWEONH) 7314 0xCB6B 쭫 (HANGUL SYLLABLE JJWEOD) 7315 0xCB6C 쭬 (HANGUL SYLLABLE JJWEOL) 7316 0x3395 ㎕ (SQUARE MU L) 7317 0x3396 ㎖ (SQUARE ML) 7318 0x3397 ㎗ (SQUARE DL) 7319 0x2113 ℓ (SCRIPT SMALL L) 7320 0x3398 ㎘ (SQUARE KL) 7321 0x33C4 ㏄ (SQUARE CC) 7322 0x33A3 ㎣ (SQUARE MM CUBED) 7323 0x33A4 ㎤ (SQUARE CM CUBED) 7324 0x33A5 ㎥ (SQUARE M CUBED) 7325 0x33A6 ㎦ (SQUARE KM CUBED) 7326 0x3399 ㎙ (SQUARE FM) 7327 0x339A ㎚ (SQUARE NM) 7328 0x339B ㎛ (SQUARE MU M) 7329 0x339C ㎜ (SQUARE MM) 7330 0x339D ㎝ (SQUARE CM) 7331 0x339E ㎞ (SQUARE KM) 7332 0x339F ㎟ (SQUARE MM SQUARED) 7333 0x33A0 ㎠ (SQUARE CM SQUARED) 7334 0x33A1 ㎡ (SQUARE M SQUARED) 7335 0x33A2 ㎢ (SQUARE KM SQUARED) 7336 0x33CA ㏊ (SQUARE HA) 7337 0x338D ㎍ (SQUARE MU G) 7338 0x338E ㎎ (SQUARE MG) 7339 0x338F ㎏ (SQUARE KG) 7340 0x33CF ㏏ (SQUARE KT) 7341 0x3388 ㎈ (SQUARE CAL) 7342 0x3389 ㎉ (SQUARE KCAL) 7343 0x33C8 ㏈ (SQUARE DB) 7344 0x33A7 ㎧ (SQUARE M OVER S) 7345 0x33A8 ㎨ (SQUARE M OVER S SQUARED) 7346 0x33B0 ㎰ (SQUARE PS) 7347 0x33B1 ㎱ (SQUARE NS) 7348 0x33B2 ㎲ (SQUARE MU S) 7349 0x33B3 ㎳ (SQUARE MS) 7350 0x33B4 ㎴ (SQUARE PV) 7351 0x33B5 ㎵ (SQUARE NV) 7352 0x33B6 ㎶ (SQUARE MU V) 7353 0x33B7 ㎷ (SQUARE MV) 7354 0x33B8 ㎸ (SQUARE KV) 7355 0x33B9 ㎹ (SQUARE MV MEGA) 7356 0x3380 ㎀ (SQUARE PA AMPS) 7357 0x3381 ㎁ (SQUARE NA) 7358 0x3382 ㎂ (SQUARE MU A) 7359 0x3383 ㎃ (SQUARE MA) 7360 0x3384 ㎄ (SQUARE KA) 7361 0x33BA ㎺ (SQUARE PW) 7362 0x33BB ㎻ (SQUARE NW) 7363 0x33BC ㎼ (SQUARE MU W) 7364 0x33BD ㎽ (SQUARE MW) 7365 0x33BE ㎾ (SQUARE KW) 7366 0x33BF ㎿ (SQUARE MW MEGA) 7367 0x3390 ㎐ (SQUARE HZ) 7368 0x3391 ㎑ (SQUARE KHZ) 7369 0x3392 ㎒ (SQUARE MHZ) 7370 0x3393 ㎓ (SQUARE GHZ) 7371 0x3394 ㎔ (SQUARE THZ) 7372 0x2126 Ω (OHM SIGN) 7373 0x33C0 ㏀ (SQUARE K OHM) 7374 0x33C1 ㏁ (SQUARE M OHM) 7375 0x338A ㎊ (SQUARE PF) 7376 0x338B ㎋ (SQUARE NF) 7377 0x338C ㎌ (SQUARE MU F) 7378 0x33D6 ㏖ (SQUARE MOL) 7379 0x33C5 ㏅ (SQUARE CD) 7380 0x33AD ㎭ (SQUARE RAD) 7381 0x33AE ㎮ (SQUARE RAD OVER S) 7382 0x33AF ㎯ (SQUARE RAD OVER S SQUARED) 7383 0x33DB ㏛ (SQUARE SR) 7384 0x33A9 ㎩ (SQUARE PA) 7385 0x33AA ㎪ (SQUARE KPA) 7386 0x33AB ㎫ (SQUARE MPA) 7387 0x33AC ㎬ (SQUARE GPA) 7388 0x33DD ㏝ (SQUARE WB) 7389 0x33D0 ㏐ (SQUARE LM) 7390 0x33D3 ㏓ (SQUARE LX) 7391 0x33C3 ㏃ (SQUARE BQ) 7392 0x33C9 ㏉ (SQUARE GY) 7393 0x33DC ㏜ (SQUARE SV) 7394 0x33C6 ㏆ (SQUARE C OVER KG) 7410 0xCB6D 쭭 (HANGUL SYLLABLE JJWEOLG) 7411 0xCB6E 쭮 (HANGUL SYLLABLE JJWEOLM) 7412 0xCB6F 쭯 (HANGUL SYLLABLE JJWEOLB) 7413 0xCB70 쭰 (HANGUL SYLLABLE JJWEOLS) 7414 0xCB71 쭱 (HANGUL SYLLABLE JJWEOLT) 7415 0xCB72 쭲 (HANGUL SYLLABLE JJWEOLP) 7416 0xCB73 쭳 (HANGUL SYLLABLE JJWEOLH) 7417 0xCB74 쭴 (HANGUL SYLLABLE JJWEOM) 7418 0xCB75 쭵 (HANGUL SYLLABLE JJWEOB) 7419 0xCB76 쭶 (HANGUL SYLLABLE JJWEOBS) 7420 0xCB77 쭷 (HANGUL SYLLABLE JJWEOS) 7421 0xCB7A 쭺 (HANGUL SYLLABLE JJWEOJ) 7422 0xCB7B 쭻 (HANGUL SYLLABLE JJWEOC) 7423 0xCB7C 쭼 (HANGUL SYLLABLE JJWEOK) 7424 0xCB7D 쭽 (HANGUL SYLLABLE JJWEOT) 7425 0xCB7E 쭾 (HANGUL SYLLABLE JJWEOP) 7426 0xCB7F 쭿 (HANGUL SYLLABLE JJWEOH) 7427 0xCB80 쮀 (HANGUL SYLLABLE JJWE) 7428 0xCB81 쮁 (HANGUL SYLLABLE JJWEG) 7429 0xCB82 쮂 (HANGUL SYLLABLE JJWEGG) 7430 0xCB83 쮃 (HANGUL SYLLABLE JJWEGS) 7431 0xCB84 쮄 (HANGUL SYLLABLE JJWEN) 7432 0xCB85 쮅 (HANGUL SYLLABLE JJWENJ) 7433 0xCB86 쮆 (HANGUL SYLLABLE JJWENH) 7434 0xCB87 쮇 (HANGUL SYLLABLE JJWED) 7435 0xCB88 쮈 (HANGUL SYLLABLE JJWEL) 7442 0xCB89 쮉 (HANGUL SYLLABLE JJWELG) 7443 0xCB8A 쮊 (HANGUL SYLLABLE JJWELM) 7444 0xCB8B 쮋 (HANGUL SYLLABLE JJWELB) 7445 0xCB8C 쮌 (HANGUL SYLLABLE JJWELS) 7446 0xCB8D 쮍 (HANGUL SYLLABLE JJWELT) 7447 0xCB8E 쮎 (HANGUL SYLLABLE JJWELP) 7448 0xCB8F 쮏 (HANGUL SYLLABLE JJWELH) 7449 0xCB90 쮐 (HANGUL SYLLABLE JJWEM) 7450 0xCB91 쮑 (HANGUL SYLLABLE JJWEB) 7451 0xCB92 쮒 (HANGUL SYLLABLE JJWEBS) 7452 0xCB93 쮓 (HANGUL SYLLABLE JJWES) 7453 0xCB94 쮔 (HANGUL SYLLABLE JJWESS) 7454 0xCB95 쮕 (HANGUL SYLLABLE JJWENG) 7455 0xCB96 쮖 (HANGUL SYLLABLE JJWEJ) 7456 0xCB97 쮗 (HANGUL SYLLABLE JJWEC) 7457 0xCB98 쮘 (HANGUL SYLLABLE JJWEK) 7458 0xCB99 쮙 (HANGUL SYLLABLE JJWET) 7459 0xCB9A 쮚 (HANGUL SYLLABLE JJWEP) 7460 0xCB9B 쮛 (HANGUL SYLLABLE JJWEH) 7461 0xCB9D 쮝 (HANGUL SYLLABLE JJWIG) 7462 0xCB9E 쮞 (HANGUL SYLLABLE JJWIGG) 7463 0xCB9F 쮟 (HANGUL SYLLABLE JJWIGS) 7464 0xCBA0 쮠 (HANGUL SYLLABLE JJWIN) 7465 0xCBA1 쮡 (HANGUL SYLLABLE JJWINJ) 7466 0xCBA2 쮢 (HANGUL SYLLABLE JJWINH) 7467 0xCBA3 쮣 (HANGUL SYLLABLE JJWID) 7474 0xCBA4 쮤 (HANGUL SYLLABLE JJWIL) 7475 0xCBA5 쮥 (HANGUL SYLLABLE JJWILG) 7476 0xCBA6 쮦 (HANGUL SYLLABLE JJWILM) 7477 0xCBA7 쮧 (HANGUL SYLLABLE JJWILB) 7478 0xCBA8 쮨 (HANGUL SYLLABLE JJWILS) 7479 0xCBA9 쮩 (HANGUL SYLLABLE JJWILT) 7480 0xCBAA 쮪 (HANGUL SYLLABLE JJWILP) 7481 0xCBAB 쮫 (HANGUL SYLLABLE JJWILH) 7482 0xCBAC 쮬 (HANGUL SYLLABLE JJWIM) 7483 0xCBAD 쮭 (HANGUL SYLLABLE JJWIB) 7484 0xCBAE 쮮 (HANGUL SYLLABLE JJWIBS) 7485 0xCBAF 쮯 (HANGUL SYLLABLE JJWIS) 7486 0xCBB0 쮰 (HANGUL SYLLABLE JJWISS) 7487 0xCBB1 쮱 (HANGUL SYLLABLE JJWING) 7488 0xCBB2 쮲 (HANGUL SYLLABLE JJWIJ) 7489 0xCBB3 쮳 (HANGUL SYLLABLE JJWIC) 7490 0xCBB4 쮴 (HANGUL SYLLABLE JJWIK) 7491 0xCBB5 쮵 (HANGUL SYLLABLE JJWIT) 7492 0xCBB6 쮶 (HANGUL SYLLABLE JJWIP) 7493 0xCBB7 쮷 (HANGUL SYLLABLE JJWIH) 7494 0xCBB9 쮹 (HANGUL SYLLABLE JJYUG) 7495 0xCBBA 쮺 (HANGUL SYLLABLE JJYUGG) 7496 0xCBBB 쮻 (HANGUL SYLLABLE JJYUGS) 7497 0xCBBC 쮼 (HANGUL SYLLABLE JJYUN) 7498 0xCBBD 쮽 (HANGUL SYLLABLE JJYUNJ) 7499 0xCBBE 쮾 (HANGUL SYLLABLE JJYUNH) 7500 0xCBBF 쮿 (HANGUL SYLLABLE JJYUD) 7501 0xCBC0 쯀 (HANGUL SYLLABLE JJYUL) 7502 0xCBC1 쯁 (HANGUL SYLLABLE JJYULG) 7503 0xCBC2 쯂 (HANGUL SYLLABLE JJYULM) 7504 0xCBC3 쯃 (HANGUL SYLLABLE JJYULB) 7505 0xCBC4 쯄 (HANGUL SYLLABLE JJYULS) 7506 0x00C6 Æ (LATIN CAPITAL LETTER AE) 7507 0x00D0 Ð (LATIN CAPITAL LETTER ETH) 7508 0x00AA ª (FEMININE ORDINAL INDICATOR) 7509 0x0126 Ħ (LATIN CAPITAL LETTER H WITH STROKE) 7511 0x0132 IJ (LATIN CAPITAL LIGATURE IJ) 7513 0x013F Ŀ (LATIN CAPITAL LETTER L WITH MIDDLE DOT) 7514 0x0141 Ł (LATIN CAPITAL LETTER L WITH STROKE) 7515 0x00D8 Ø (LATIN CAPITAL LETTER O WITH STROKE) 7516 0x0152 Œ (LATIN CAPITAL LIGATURE OE) 7517 0x00BA º (MASCULINE ORDINAL INDICATOR) 7518 0x00DE Þ (LATIN CAPITAL LETTER THORN) 7519 0x0166 Ŧ (LATIN CAPITAL LETTER T WITH STROKE) 7520 0x014A Ŋ (LATIN CAPITAL LETTER ENG) 7522 0x3260 ㉠ (CIRCLED HANGUL KIYEOK) 7523 0x3261 ㉡ (CIRCLED HANGUL NIEUN) 7524 0x3262 ㉢ (CIRCLED HANGUL TIKEUT) 7525 0x3263 ㉣ (CIRCLED HANGUL RIEUL) 7526 0x3264 ㉤ (CIRCLED HANGUL MIEUM) 7527 0x3265 ㉥ (CIRCLED HANGUL PIEUP) 7528 0x3266 ㉦ (CIRCLED HANGUL SIOS) 7529 0x3267 ㉧ (CIRCLED HANGUL IEUNG) 7530 0x3268 ㉨ (CIRCLED HANGUL CIEUC) 7531 0x3269 ㉩ (CIRCLED HANGUL CHIEUCH) 7532 0x326A ㉪ (CIRCLED HANGUL KHIEUKH) 7533 0x326B ㉫ (CIRCLED HANGUL THIEUTH) 7534 0x326C ㉬ (CIRCLED HANGUL PHIEUPH) 7535 0x326D ㉭ (CIRCLED HANGUL HIEUH) 7536 0x326E ㉮ (CIRCLED HANGUL KIYEOK A) 7537 0x326F ㉯ (CIRCLED HANGUL NIEUN A) 7538 0x3270 ㉰ (CIRCLED HANGUL TIKEUT A) 7539 0x3271 ㉱ (CIRCLED HANGUL RIEUL A) 7540 0x3272 ㉲ (CIRCLED HANGUL MIEUM A) 7541 0x3273 ㉳ (CIRCLED HANGUL PIEUP A) 7542 0x3274 ㉴ (CIRCLED HANGUL SIOS A) 7543 0x3275 ㉵ (CIRCLED HANGUL IEUNG A) 7544 0x3276 ㉶ (CIRCLED HANGUL CIEUC A) 7545 0x3277 ㉷ (CIRCLED HANGUL CHIEUCH A) 7546 0x3278 ㉸ (CIRCLED HANGUL KHIEUKH A) 7547 0x3279 ㉹ (CIRCLED HANGUL THIEUTH A) 7548 0x327A ㉺ (CIRCLED HANGUL PHIEUPH A) 7549 0x327B ㉻ (CIRCLED HANGUL HIEUH A) 7550 0x24D0 ⓐ (CIRCLED LATIN SMALL LETTER A) 7551 0x24D1 ⓑ (CIRCLED LATIN SMALL LETTER B) 7552 0x24D2 ⓒ (CIRCLED LATIN SMALL LETTER C) 7553 0x24D3 ⓓ (CIRCLED LATIN SMALL LETTER D) 7554 0x24D4 ⓔ (CIRCLED LATIN SMALL LETTER E) 7555 0x24D5 ⓕ (CIRCLED LATIN SMALL LETTER F) 7556 0x24D6 ⓖ (CIRCLED LATIN SMALL LETTER G) 7557 0x24D7 ⓗ (CIRCLED LATIN SMALL LETTER H) 7558 0x24D8 ⓘ (CIRCLED LATIN SMALL LETTER I) 7559 0x24D9 ⓙ (CIRCLED LATIN SMALL LETTER J) 7560 0x24DA ⓚ (CIRCLED LATIN SMALL LETTER K) 7561 0x24DB ⓛ (CIRCLED LATIN SMALL LETTER L) 7562 0x24DC ⓜ (CIRCLED LATIN SMALL LETTER M) 7563 0x24DD ⓝ (CIRCLED LATIN SMALL LETTER N) 7564 0x24DE ⓞ (CIRCLED LATIN SMALL LETTER O) 7565 0x24DF ⓟ (CIRCLED LATIN SMALL LETTER P) 7566 0x24E0 ⓠ (CIRCLED LATIN SMALL LETTER Q) 7567 0x24E1 ⓡ (CIRCLED LATIN SMALL LETTER R) 7568 0x24E2 ⓢ (CIRCLED LATIN SMALL LETTER S) 7569 0x24E3 ⓣ (CIRCLED LATIN SMALL LETTER T) 7570 0x24E4 ⓤ (CIRCLED LATIN SMALL LETTER U) 7571 0x24E5 ⓥ (CIRCLED LATIN SMALL LETTER V) 7572 0x24E6 ⓦ (CIRCLED LATIN SMALL LETTER W) 7573 0x24E7 ⓧ (CIRCLED LATIN SMALL LETTER X) 7574 0x24E8 ⓨ (CIRCLED LATIN SMALL LETTER Y) 7575 0x24E9 ⓩ (CIRCLED LATIN SMALL LETTER Z) 7576 0x2460 ① (CIRCLED DIGIT ONE) 7577 0x2461 ② (CIRCLED DIGIT TWO) 7578 0x2462 ③ (CIRCLED DIGIT THREE) 7579 0x2463 ④ (CIRCLED DIGIT FOUR) 7580 0x2464 ⑤ (CIRCLED DIGIT FIVE) 7581 0x2465 ⑥ (CIRCLED DIGIT SIX) 7582 0x2466 ⑦ (CIRCLED DIGIT SEVEN) 7583 0x2467 ⑧ (CIRCLED DIGIT EIGHT) 7584 0x2468 ⑨ (CIRCLED DIGIT NINE) 7585 0x2469 ⑩ (CIRCLED NUMBER TEN) 7586 0x246A ⑪ (CIRCLED NUMBER ELEVEN) 7587 0x246B ⑫ (CIRCLED NUMBER TWELVE) 7588 0x246C ⑬ (CIRCLED NUMBER THIRTEEN) 7589 0x246D ⑭ (CIRCLED NUMBER FOURTEEN) 7590 0x246E ⑮ (CIRCLED NUMBER FIFTEEN) 7591 0x00BD ½ (VULGAR FRACTION ONE HALF) 7592 0x2153 ⅓ (VULGAR FRACTION ONE THIRD) 7593 0x2154 ⅔ (VULGAR FRACTION TWO THIRDS) 7594 0x00BC ¼ (VULGAR FRACTION ONE QUARTER) 7595 0x00BE ¾ (VULGAR FRACTION THREE QUARTERS) 7596 0x215B ⅛ (VULGAR FRACTION ONE EIGHTH) 7597 0x215C ⅜ (VULGAR FRACTION THREE EIGHTHS) 7598 0x215D ⅝ (VULGAR FRACTION FIVE EIGHTHS) 7599 0x215E ⅞ (VULGAR FRACTION SEVEN EIGHTHS) 7600 0xCBC5 쯅 (HANGUL SYLLABLE JJYULT) 7601 0xCBC6 쯆 (HANGUL SYLLABLE JJYULP) 7602 0xCBC7 쯇 (HANGUL SYLLABLE JJYULH) 7603 0xCBC8 쯈 (HANGUL SYLLABLE JJYUM) 7604 0xCBC9 쯉 (HANGUL SYLLABLE JJYUB) 7605 0xCBCA 쯊 (HANGUL SYLLABLE JJYUBS) 7606 0xCBCB 쯋 (HANGUL SYLLABLE JJYUS) 7607 0xCBCC 쯌 (HANGUL SYLLABLE JJYUSS) 7608 0xCBCD 쯍 (HANGUL SYLLABLE JJYUNG) 7609 0xCBCE 쯎 (HANGUL SYLLABLE JJYUJ) 7610 0xCBCF 쯏 (HANGUL SYLLABLE JJYUC) 7611 0xCBD0 쯐 (HANGUL SYLLABLE JJYUK) 7612 0xCBD1 쯑 (HANGUL SYLLABLE JJYUT) 7613 0xCBD2 쯒 (HANGUL SYLLABLE JJYUP) 7614 0xCBD3 쯓 (HANGUL SYLLABLE JJYUH) 7615 0xCBD5 쯕 (HANGUL SYLLABLE JJEUG) 7616 0xCBD6 쯖 (HANGUL SYLLABLE JJEUGG) 7617 0xCBD7 쯗 (HANGUL SYLLABLE JJEUGS) 7618 0xCBD8 쯘 (HANGUL SYLLABLE JJEUN) 7619 0xCBD9 쯙 (HANGUL SYLLABLE JJEUNJ) 7620 0xCBDA 쯚 (HANGUL SYLLABLE JJEUNH) 7621 0xCBDB 쯛 (HANGUL SYLLABLE JJEUD) 7622 0xCBDC 쯜 (HANGUL SYLLABLE JJEUL) 7623 0xCBDD 쯝 (HANGUL SYLLABLE JJEULG) 7624 0xCBDE 쯞 (HANGUL SYLLABLE JJEULM) 7625 0xCBDF 쯟 (HANGUL SYLLABLE JJEULB) 7632 0xCBE0 쯠 (HANGUL SYLLABLE JJEULS) 7633 0xCBE1 쯡 (HANGUL SYLLABLE JJEULT) 7634 0xCBE2 쯢 (HANGUL SYLLABLE JJEULP) 7635 0xCBE3 쯣 (HANGUL SYLLABLE JJEULH) 7636 0xCBE5 쯥 (HANGUL SYLLABLE JJEUB) 7637 0xCBE6 쯦 (HANGUL SYLLABLE JJEUBS) 7638 0xCBE8 쯨 (HANGUL SYLLABLE JJEUSS) 7639 0xCBEA 쯪 (HANGUL SYLLABLE JJEUJ) 7640 0xCBEB 쯫 (HANGUL SYLLABLE JJEUC) 7641 0xCBEC 쯬 (HANGUL SYLLABLE JJEUK) 7642 0xCBED 쯭 (HANGUL SYLLABLE JJEUT) 7643 0xCBEE 쯮 (HANGUL SYLLABLE JJEUP) 7644 0xCBEF 쯯 (HANGUL SYLLABLE JJEUH) 7645 0xCBF0 쯰 (HANGUL SYLLABLE JJYI) 7646 0xCBF1 쯱 (HANGUL SYLLABLE JJYIG) 7647 0xCBF2 쯲 (HANGUL SYLLABLE JJYIGG) 7648 0xCBF3 쯳 (HANGUL SYLLABLE JJYIGS) 7649 0xCBF4 쯴 (HANGUL SYLLABLE JJYIN) 7650 0xCBF5 쯵 (HANGUL SYLLABLE JJYINJ) 7651 0xCBF6 쯶 (HANGUL SYLLABLE JJYINH) 7652 0xCBF7 쯷 (HANGUL SYLLABLE JJYID) 7653 0xCBF8 쯸 (HANGUL SYLLABLE JJYIL) 7654 0xCBF9 쯹 (HANGUL SYLLABLE JJYILG) 7655 0xCBFA 쯺 (HANGUL SYLLABLE JJYILM) 7656 0xCBFB 쯻 (HANGUL SYLLABLE JJYILB) 7657 0xCBFC 쯼 (HANGUL SYLLABLE JJYILS) 7664 0xCBFD 쯽 (HANGUL SYLLABLE JJYILT) 7665 0xCBFE 쯾 (HANGUL SYLLABLE JJYILP) 7666 0xCBFF 쯿 (HANGUL SYLLABLE JJYILH) 7667 0xCC00 찀 (HANGUL SYLLABLE JJYIM) 7668 0xCC01 찁 (HANGUL SYLLABLE JJYIB) 7669 0xCC02 찂 (HANGUL SYLLABLE JJYIBS) 7670 0xCC03 찃 (HANGUL SYLLABLE JJYIS) 7671 0xCC04 찄 (HANGUL SYLLABLE JJYISS) 7672 0xCC05 찅 (HANGUL SYLLABLE JJYING) 7673 0xCC06 찆 (HANGUL SYLLABLE JJYIJ) 7674 0xCC07 찇 (HANGUL SYLLABLE JJYIC) 7675 0xCC08 찈 (HANGUL SYLLABLE JJYIK) 7676 0xCC09 찉 (HANGUL SYLLABLE JJYIT) 7677 0xCC0A 찊 (HANGUL SYLLABLE JJYIP) 7678 0xCC0B 찋 (HANGUL SYLLABLE JJYIH) 7679 0xCC0E 찎 (HANGUL SYLLABLE JJIGG) 7680 0xCC0F 찏 (HANGUL SYLLABLE JJIGS) 7681 0xCC11 찑 (HANGUL SYLLABLE JJINJ) 7682 0xCC12 찒 (HANGUL SYLLABLE JJINH) 7683 0xCC13 찓 (HANGUL SYLLABLE JJID) 7684 0xCC15 찕 (HANGUL SYLLABLE JJILG) 7685 0xCC16 찖 (HANGUL SYLLABLE JJILM) 7686 0xCC17 찗 (HANGUL SYLLABLE JJILB) 7687 0xCC18 찘 (HANGUL SYLLABLE JJILS) 7688 0xCC19 찙 (HANGUL SYLLABLE JJILT) 7689 0xCC1A 찚 (HANGUL SYLLABLE JJILP) 7690 0xCC1B 찛 (HANGUL SYLLABLE JJILH) 7691 0xCC1E 찞 (HANGUL SYLLABLE JJIBS) 7692 0xCC1F 찟 (HANGUL SYLLABLE JJIS) 7693 0xCC20 찠 (HANGUL SYLLABLE JJISS) 7694 0xCC23 찣 (HANGUL SYLLABLE JJIC) 7695 0xCC24 찤 (HANGUL SYLLABLE JJIK) 7696 0x00E6 æ (LATIN SMALL LETTER AE) 7697 0x0111 đ (LATIN SMALL LETTER D WITH STROKE) 7698 0x00F0 ð (LATIN SMALL LETTER ETH) 7699 0x0127 ħ (LATIN SMALL LETTER H WITH STROKE) 7700 0x0131 ı (LATIN SMALL LETTER DOTLESS I) 7701 0x0133 ij (LATIN SMALL LIGATURE IJ) 7702 0x0138 ĸ (LATIN SMALL LETTER KRA) 7703 0x0140 ŀ (LATIN SMALL LETTER L WITH MIDDLE DOT) 7704 0x0142 ł (LATIN SMALL LETTER L WITH STROKE) 7705 0x00F8 ø (LATIN SMALL LETTER O WITH STROKE) 7706 0x0153 œ (LATIN SMALL LIGATURE OE) 7707 0x00DF ß (LATIN SMALL LETTER SHARP S) 7708 0x00FE þ (LATIN SMALL LETTER THORN) 7709 0x0167 ŧ (LATIN SMALL LETTER T WITH STROKE) 7710 0x014B ŋ (LATIN SMALL LETTER ENG) 7711 0x0149 ʼn (LATIN SMALL LETTER N PRECEDED BY APOSTROPHE) 7712 0x3200 ㈀ (PARENTHESIZED HANGUL KIYEOK) 7713 0x3201 ㈁ (PARENTHESIZED HANGUL NIEUN) 7714 0x3202 ㈂ (PARENTHESIZED HANGUL TIKEUT) 7715 0x3203 ㈃ (PARENTHESIZED HANGUL RIEUL) 7716 0x3204 ㈄ (PARENTHESIZED HANGUL MIEUM) 7717 0x3205 ㈅ (PARENTHESIZED HANGUL PIEUP) 7718 0x3206 ㈆ (PARENTHESIZED HANGUL SIOS) 7719 0x3207 ㈇ (PARENTHESIZED HANGUL IEUNG) 7720 0x3208 ㈈ (PARENTHESIZED HANGUL CIEUC) 7721 0x3209 ㈉ (PARENTHESIZED HANGUL CHIEUCH) 7722 0x320A ㈊ (PARENTHESIZED HANGUL KHIEUKH) 7723 0x320B ㈋ (PARENTHESIZED HANGUL THIEUTH) 7724 0x320C ㈌ (PARENTHESIZED HANGUL PHIEUPH) 7725 0x320D ㈍ (PARENTHESIZED HANGUL HIEUH) 7726 0x320E ㈎ (PARENTHESIZED HANGUL KIYEOK A) 7727 0x320F ㈏ (PARENTHESIZED HANGUL NIEUN A) 7728 0x3210 ㈐ (PARENTHESIZED HANGUL TIKEUT A) 7729 0x3211 ㈑ (PARENTHESIZED HANGUL RIEUL A) 7730 0x3212 ㈒ (PARENTHESIZED HANGUL MIEUM A) 7731 0x3213 ㈓ (PARENTHESIZED HANGUL PIEUP A) 7732 0x3214 ㈔ (PARENTHESIZED HANGUL SIOS A) 7733 0x3215 ㈕ (PARENTHESIZED HANGUL IEUNG A) 7734 0x3216 ㈖ (PARENTHESIZED HANGUL CIEUC A) 7735 0x3217 ㈗ (PARENTHESIZED HANGUL CHIEUCH A) 7736 0x3218 ㈘ (PARENTHESIZED HANGUL KHIEUKH A) 7737 0x3219 ㈙ (PARENTHESIZED HANGUL THIEUTH A) 7738 0x321A ㈚ (PARENTHESIZED HANGUL PHIEUPH A) 7739 0x321B ㈛ (PARENTHESIZED HANGUL HIEUH A) 7740 0x249C ⒜ (PARENTHESIZED LATIN SMALL LETTER A) 7741 0x249D ⒝ (PARENTHESIZED LATIN SMALL LETTER B) 7742 0x249E ⒞ (PARENTHESIZED LATIN SMALL LETTER C) 7743 0x249F ⒟ (PARENTHESIZED LATIN SMALL LETTER D) 7744 0x24A0 ⒠ (PARENTHESIZED LATIN SMALL LETTER E) 7745 0x24A1 ⒡ (PARENTHESIZED LATIN SMALL LETTER F) 7746 0x24A2 ⒢ (PARENTHESIZED LATIN SMALL LETTER G) 7747 0x24A3 ⒣ (PARENTHESIZED LATIN SMALL LETTER H) 7748 0x24A4 ⒤ (PARENTHESIZED LATIN SMALL LETTER I) 7749 0x24A5 ⒥ (PARENTHESIZED LATIN SMALL LETTER J) 7750 0x24A6 ⒦ (PARENTHESIZED LATIN SMALL LETTER K) 7751 0x24A7 ⒧ (PARENTHESIZED LATIN SMALL LETTER L) 7752 0x24A8 ⒨ (PARENTHESIZED LATIN SMALL LETTER M) 7753 0x24A9 ⒩ (PARENTHESIZED LATIN SMALL LETTER N) 7754 0x24AA ⒪ (PARENTHESIZED LATIN SMALL LETTER O) 7755 0x24AB ⒫ (PARENTHESIZED LATIN SMALL LETTER P) 7756 0x24AC ⒬ (PARENTHESIZED LATIN SMALL LETTER Q) 7757 0x24AD ⒭ (PARENTHESIZED LATIN SMALL LETTER R) 7758 0x24AE ⒮ (PARENTHESIZED LATIN SMALL LETTER S) 7759 0x24AF ⒯ (PARENTHESIZED LATIN SMALL LETTER T) 7760 0x24B0 ⒰ (PARENTHESIZED LATIN SMALL LETTER U) 7761 0x24B1 ⒱ (PARENTHESIZED LATIN SMALL LETTER V) 7762 0x24B2 ⒲ (PARENTHESIZED LATIN SMALL LETTER W) 7763 0x24B3 ⒳ (PARENTHESIZED LATIN SMALL LETTER X) 7764 0x24B4 ⒴ (PARENTHESIZED LATIN SMALL LETTER Y) 7765 0x24B5 ⒵ (PARENTHESIZED LATIN SMALL LETTER Z) 7766 0x2474 ⑴ (PARENTHESIZED DIGIT ONE) 7767 0x2475 ⑵ (PARENTHESIZED DIGIT TWO) 7768 0x2476 ⑶ (PARENTHESIZED DIGIT THREE) 7769 0x2477 ⑷ (PARENTHESIZED DIGIT FOUR) 7770 0x2478 ⑸ (PARENTHESIZED DIGIT FIVE) 7771 0x2479 ⑹ (PARENTHESIZED DIGIT SIX) 7772 0x247A ⑺ (PARENTHESIZED DIGIT SEVEN) 7773 0x247B ⑻ (PARENTHESIZED DIGIT EIGHT) 7774 0x247C ⑼ (PARENTHESIZED DIGIT NINE) 7775 0x247D ⑽ (PARENTHESIZED NUMBER TEN) 7776 0x247E ⑾ (PARENTHESIZED NUMBER ELEVEN) 7777 0x247F ⑿ (PARENTHESIZED NUMBER TWELVE) 7778 0x2480 ⒀ (PARENTHESIZED NUMBER THIRTEEN) 7779 0x2481 ⒁ (PARENTHESIZED NUMBER FOURTEEN) 7780 0x2482 ⒂ (PARENTHESIZED NUMBER FIFTEEN) 7781 0x00B9 ¹ (SUPERSCRIPT ONE) 7782 0x00B2 ² (SUPERSCRIPT TWO) 7783 0x00B3 ³ (SUPERSCRIPT THREE) 7784 0x2074 ⁴ (SUPERSCRIPT FOUR) 7785 0x207F ⁿ (SUPERSCRIPT LATIN SMALL LETTER N) 7786 0x2081 ₁ (SUBSCRIPT ONE) 7787 0x2082 ₂ (SUBSCRIPT TWO) 7788 0x2083 ₃ (SUBSCRIPT THREE) 7789 0x2084 ₄ (SUBSCRIPT FOUR) 7790 0xCC25 찥 (HANGUL SYLLABLE JJIT) 7791 0xCC26 찦 (HANGUL SYLLABLE JJIP) 7792 0xCC2A 찪 (HANGUL SYLLABLE CAGG) 7793 0xCC2B 찫 (HANGUL SYLLABLE CAGS) 7794 0xCC2D 찭 (HANGUL SYLLABLE CANJ) 7795 0xCC2F 찯 (HANGUL SYLLABLE CAD) 7796 0xCC31 찱 (HANGUL SYLLABLE CALG) 7797 0xCC32 찲 (HANGUL SYLLABLE CALM) 7798 0xCC33 찳 (HANGUL SYLLABLE CALB) 7799 0xCC34 찴 (HANGUL SYLLABLE CALS) 7800 0xCC35 찵 (HANGUL SYLLABLE CALT) 7801 0xCC36 찶 (HANGUL SYLLABLE CALP) 7802 0xCC37 찷 (HANGUL SYLLABLE CALH) 7803 0xCC3A 찺 (HANGUL SYLLABLE CABS) 7804 0xCC3F 찿 (HANGUL SYLLABLE CAC) 7805 0xCC40 챀 (HANGUL SYLLABLE CAK) 7806 0xCC41 챁 (HANGUL SYLLABLE CAT) 7807 0xCC42 챂 (HANGUL SYLLABLE CAP) 7808 0xCC43 챃 (HANGUL SYLLABLE CAH) 7809 0xCC46 챆 (HANGUL SYLLABLE CAEGG) 7810 0xCC47 챇 (HANGUL SYLLABLE CAEGS) 7811 0xCC49 챉 (HANGUL SYLLABLE CAENJ) 7812 0xCC4A 챊 (HANGUL SYLLABLE CAENH) 7813 0xCC4B 챋 (HANGUL SYLLABLE CAED) 7814 0xCC4D 챍 (HANGUL SYLLABLE CAELG) 7815 0xCC4E 챎 (HANGUL SYLLABLE CAELM) 7822 0xCC4F 챏 (HANGUL SYLLABLE CAELB) 7823 0xCC50 챐 (HANGUL SYLLABLE CAELS) 7824 0xCC51 챑 (HANGUL SYLLABLE CAELT) 7825 0xCC52 챒 (HANGUL SYLLABLE CAELP) 7826 0xCC53 챓 (HANGUL SYLLABLE CAELH) 7827 0xCC56 챖 (HANGUL SYLLABLE CAEBS) 7828 0xCC5A 챚 (HANGUL SYLLABLE CAEJ) 7829 0xCC5B 챛 (HANGUL SYLLABLE CAEC) 7830 0xCC5C 챜 (HANGUL SYLLABLE CAEK) 7831 0xCC5D 챝 (HANGUL SYLLABLE CAET) 7832 0xCC5E 챞 (HANGUL SYLLABLE CAEP) 7833 0xCC5F 챟 (HANGUL SYLLABLE CAEH) 7834 0xCC61 챡 (HANGUL SYLLABLE CYAG) 7835 0xCC62 챢 (HANGUL SYLLABLE CYAGG) 7836 0xCC63 챣 (HANGUL SYLLABLE CYAGS) 7837 0xCC65 챥 (HANGUL SYLLABLE CYANJ) 7838 0xCC67 챧 (HANGUL SYLLABLE CYAD) 7839 0xCC69 챩 (HANGUL SYLLABLE CYALG) 7840 0xCC6A 챪 (HANGUL SYLLABLE CYALM) 7841 0xCC6B 챫 (HANGUL SYLLABLE CYALB) 7842 0xCC6C 챬 (HANGUL SYLLABLE CYALS) 7843 0xCC6D 챭 (HANGUL SYLLABLE CYALT) 7844 0xCC6E 챮 (HANGUL SYLLABLE CYALP) 7845 0xCC6F 챯 (HANGUL SYLLABLE CYALH) 7846 0xCC71 챱 (HANGUL SYLLABLE CYAB) 7847 0xCC72 챲 (HANGUL SYLLABLE CYABS) 7854 0xCC73 챳 (HANGUL SYLLABLE CYAS) 7855 0xCC74 챴 (HANGUL SYLLABLE CYASS) 7856 0xCC76 챶 (HANGUL SYLLABLE CYAJ) 7857 0xCC77 챷 (HANGUL SYLLABLE CYAC) 7858 0xCC78 챸 (HANGUL SYLLABLE CYAK) 7859 0xCC79 챹 (HANGUL SYLLABLE CYAT) 7860 0xCC7A 챺 (HANGUL SYLLABLE CYAP) 7861 0xCC7B 챻 (HANGUL SYLLABLE CYAH) 7862 0xCC7C 챼 (HANGUL SYLLABLE CYAE) 7863 0xCC7D 챽 (HANGUL SYLLABLE CYAEG) 7864 0xCC7E 챾 (HANGUL SYLLABLE CYAEGG) 7865 0xCC7F 챿 (HANGUL SYLLABLE CYAEGS) 7866 0xCC80 첀 (HANGUL SYLLABLE CYAEN) 7867 0xCC81 첁 (HANGUL SYLLABLE CYAENJ) 7868 0xCC82 첂 (HANGUL SYLLABLE CYAENH) 7869 0xCC83 첃 (HANGUL SYLLABLE CYAED) 7870 0xCC84 첄 (HANGUL SYLLABLE CYAEL) 7871 0xCC85 첅 (HANGUL SYLLABLE CYAELG) 7872 0xCC86 첆 (HANGUL SYLLABLE CYAELM) 7873 0xCC87 첇 (HANGUL SYLLABLE CYAELB) 7874 0xCC88 첈 (HANGUL SYLLABLE CYAELS) 7875 0xCC89 첉 (HANGUL SYLLABLE CYAELT) 7876 0xCC8A 첊 (HANGUL SYLLABLE CYAELP) 7877 0xCC8B 첋 (HANGUL SYLLABLE CYAELH) 7878 0xCC8C 첌 (HANGUL SYLLABLE CYAEM) 7879 0xCC8D 첍 (HANGUL SYLLABLE CYAEB) 7880 0xCC8E 첎 (HANGUL SYLLABLE CYAEBS) 7881 0xCC8F 첏 (HANGUL SYLLABLE CYAES) 7882 0xCC90 첐 (HANGUL SYLLABLE CYAESS) 7883 0xCC91 첑 (HANGUL SYLLABLE CYAENG) 7884 0xCC92 첒 (HANGUL SYLLABLE CYAEJ) 7885 0xCC93 첓 (HANGUL SYLLABLE CYAEC) 7886 0x3041 ぁ (HIRAGANA LETTER SMALL A) 7887 0x3042 あ (HIRAGANA LETTER A) 7888 0x3043 ぃ (HIRAGANA LETTER SMALL I) 7889 0x3044 い (HIRAGANA LETTER I) 7890 0x3045 ぅ (HIRAGANA LETTER SMALL U) 7891 0x3046 う (HIRAGANA LETTER U) 7892 0x3047 ぇ (HIRAGANA LETTER SMALL E) 7893 0x3048 え (HIRAGANA LETTER E) 7894 0x3049 ぉ (HIRAGANA LETTER SMALL O) 7895 0x304A お (HIRAGANA LETTER O) 7896 0x304B か (HIRAGANA LETTER KA) 7897 0x304C が (HIRAGANA LETTER GA) 7898 0x304D き (HIRAGANA LETTER KI) 7899 0x304E ぎ (HIRAGANA LETTER GI) 7900 0x304F く (HIRAGANA LETTER KU) 7901 0x3050 ぐ (HIRAGANA LETTER GU) 7902 0x3051 け (HIRAGANA LETTER KE) 7903 0x3052 げ (HIRAGANA LETTER GE) 7904 0x3053 こ (HIRAGANA LETTER KO) 7905 0x3054 ご (HIRAGANA LETTER GO) 7906 0x3055 さ (HIRAGANA LETTER SA) 7907 0x3056 ざ (HIRAGANA LETTER ZA) 7908 0x3057 し (HIRAGANA LETTER SI) 7909 0x3058 じ (HIRAGANA LETTER ZI) 7910 0x3059 す (HIRAGANA LETTER SU) 7911 0x305A ず (HIRAGANA LETTER ZU) 7912 0x305B せ (HIRAGANA LETTER SE) 7913 0x305C ぜ (HIRAGANA LETTER ZE) 7914 0x305D そ (HIRAGANA LETTER SO) 7915 0x305E ぞ (HIRAGANA LETTER ZO) 7916 0x305F た (HIRAGANA LETTER TA) 7917 0x3060 だ (HIRAGANA LETTER DA) 7918 0x3061 ち (HIRAGANA LETTER TI) 7919 0x3062 ぢ (HIRAGANA LETTER DI) 7920 0x3063 っ (HIRAGANA LETTER SMALL TU) 7921 0x3064 つ (HIRAGANA LETTER TU) 7922 0x3065 づ (HIRAGANA LETTER DU) 7923 0x3066 て (HIRAGANA LETTER TE) 7924 0x3067 で (HIRAGANA LETTER DE) 7925 0x3068 と (HIRAGANA LETTER TO) 7926 0x3069 ど (HIRAGANA LETTER DO) 7927 0x306A な (HIRAGANA LETTER NA) 7928 0x306B に (HIRAGANA LETTER NI) 7929 0x306C ぬ (HIRAGANA LETTER NU) 7930 0x306D ね (HIRAGANA LETTER NE) 7931 0x306E の (HIRAGANA LETTER NO) 7932 0x306F は (HIRAGANA LETTER HA) 7933 0x3070 ば (HIRAGANA LETTER BA) 7934 0x3071 ぱ (HIRAGANA LETTER PA) 7935 0x3072 ひ (HIRAGANA LETTER HI) 7936 0x3073 び (HIRAGANA LETTER BI) 7937 0x3074 ぴ (HIRAGANA LETTER PI) 7938 0x3075 ふ (HIRAGANA LETTER HU) 7939 0x3076 ぶ (HIRAGANA LETTER BU) 7940 0x3077 ぷ (HIRAGANA LETTER PU) 7941 0x3078 へ (HIRAGANA LETTER HE) 7942 0x3079 べ (HIRAGANA LETTER BE) 7943 0x307A ぺ (HIRAGANA LETTER PE) 7944 0x307B ほ (HIRAGANA LETTER HO) 7945 0x307C ぼ (HIRAGANA LETTER BO) 7946 0x307D ぽ (HIRAGANA LETTER PO) 7947 0x307E ま (HIRAGANA LETTER MA) 7948 0x307F み (HIRAGANA LETTER MI) 7949 0x3080 む (HIRAGANA LETTER MU) 7950 0x3081 め (HIRAGANA LETTER ME) 7951 0x3082 も (HIRAGANA LETTER MO) 7952 0x3083 ゃ (HIRAGANA LETTER SMALL YA) 7953 0x3084 や (HIRAGANA LETTER YA) 7954 0x3085 ゅ (HIRAGANA LETTER SMALL YU) 7955 0x3086 ゆ (HIRAGANA LETTER YU) 7956 0x3087 ょ (HIRAGANA LETTER SMALL YO) 7957 0x3088 よ (HIRAGANA LETTER YO) 7958 0x3089 ら (HIRAGANA LETTER RA) 7959 0x308A り (HIRAGANA LETTER RI) 7960 0x308B る (HIRAGANA LETTER RU) 7961 0x308C れ (HIRAGANA LETTER RE) 7962 0x308D ろ (HIRAGANA LETTER RO) 7963 0x308E ゎ (HIRAGANA LETTER SMALL WA) 7964 0x308F わ (HIRAGANA LETTER WA) 7965 0x3090 ゐ (HIRAGANA LETTER WI) 7966 0x3091 ゑ (HIRAGANA LETTER WE) 7967 0x3092 を (HIRAGANA LETTER WO) 7968 0x3093 ん (HIRAGANA LETTER N) 7980 0xCC94 첔 (HANGUL SYLLABLE CYAEK) 7981 0xCC95 첕 (HANGUL SYLLABLE CYAET) 7982 0xCC96 첖 (HANGUL SYLLABLE CYAEP) 7983 0xCC97 첗 (HANGUL SYLLABLE CYAEH) 7984 0xCC9A 첚 (HANGUL SYLLABLE CEOGG) 7985 0xCC9B 첛 (HANGUL SYLLABLE CEOGS) 7986 0xCC9D 첝 (HANGUL SYLLABLE CEONJ) 7987 0xCC9E 첞 (HANGUL SYLLABLE CEONH) 7988 0xCC9F 첟 (HANGUL SYLLABLE CEOD) 7989 0xCCA1 첡 (HANGUL SYLLABLE CEOLG) 7990 0xCCA2 첢 (HANGUL SYLLABLE CEOLM) 7991 0xCCA3 첣 (HANGUL SYLLABLE CEOLB) 7992 0xCCA4 첤 (HANGUL SYLLABLE CEOLS) 7993 0xCCA5 첥 (HANGUL SYLLABLE CEOLT) 7994 0xCCA6 첦 (HANGUL SYLLABLE CEOLP) 7995 0xCCA7 첧 (HANGUL SYLLABLE CEOLH) 7996 0xCCAA 첪 (HANGUL SYLLABLE CEOBS) 7997 0xCCAE 첮 (HANGUL SYLLABLE CEOJ) 7998 0xCCAF 첯 (HANGUL SYLLABLE CEOC) 7999 0xCCB0 첰 (HANGUL SYLLABLE CEOK) 8000 0xCCB1 첱 (HANGUL SYLLABLE CEOT) 8001 0xCCB2 첲 (HANGUL SYLLABLE CEOP) 8002 0xCCB3 첳 (HANGUL SYLLABLE CEOH) 8003 0xCCB6 첶 (HANGUL SYLLABLE CEGG) 8004 0xCCB7 첷 (HANGUL SYLLABLE CEGS) 8005 0xCCB9 첹 (HANGUL SYLLABLE CENJ) 8012 0xCCBA 첺 (HANGUL SYLLABLE CENH) 8013 0xCCBB 첻 (HANGUL SYLLABLE CED) 8014 0xCCBD 첽 (HANGUL SYLLABLE CELG) 8015 0xCCBE 첾 (HANGUL SYLLABLE CELM) 8016 0xCCBF 첿 (HANGUL SYLLABLE CELB) 8017 0xCCC0 쳀 (HANGUL SYLLABLE CELS) 8018 0xCCC1 쳁 (HANGUL SYLLABLE CELT) 8019 0xCCC2 쳂 (HANGUL SYLLABLE CELP) 8020 0xCCC3 쳃 (HANGUL SYLLABLE CELH) 8021 0xCCC6 쳆 (HANGUL SYLLABLE CEBS) 8022 0xCCC8 쳈 (HANGUL SYLLABLE CESS) 8023 0xCCCA 쳊 (HANGUL SYLLABLE CEJ) 8024 0xCCCB 쳋 (HANGUL SYLLABLE CEC) 8025 0xCCCC 쳌 (HANGUL SYLLABLE CEK) 8026 0xCCCD 쳍 (HANGUL SYLLABLE CET) 8027 0xCCCE 쳎 (HANGUL SYLLABLE CEP) 8028 0xCCCF 쳏 (HANGUL SYLLABLE CEH) 8029 0xCCD1 쳑 (HANGUL SYLLABLE CYEOG) 8030 0xCCD2 쳒 (HANGUL SYLLABLE CYEOGG) 8031 0xCCD3 쳓 (HANGUL SYLLABLE CYEOGS) 8032 0xCCD5 쳕 (HANGUL SYLLABLE CYEONJ) 8033 0xCCD6 쳖 (HANGUL SYLLABLE CYEONH) 8034 0xCCD7 쳗 (HANGUL SYLLABLE CYEOD) 8035 0xCCD8 쳘 (HANGUL SYLLABLE CYEOL) 8036 0xCCD9 쳙 (HANGUL SYLLABLE CYEOLG) 8037 0xCCDA 쳚 (HANGUL SYLLABLE CYEOLM) 8044 0xCCDB 쳛 (HANGUL SYLLABLE CYEOLB) 8045 0xCCDC 쳜 (HANGUL SYLLABLE CYEOLS) 8046 0xCCDD 쳝 (HANGUL SYLLABLE CYEOLT) 8047 0xCCDE 쳞 (HANGUL SYLLABLE CYEOLP) 8048 0xCCDF 쳟 (HANGUL SYLLABLE CYEOLH) 8049 0xCCE0 쳠 (HANGUL SYLLABLE CYEOM) 8050 0xCCE1 쳡 (HANGUL SYLLABLE CYEOB) 8051 0xCCE2 쳢 (HANGUL SYLLABLE CYEOBS) 8052 0xCCE3 쳣 (HANGUL SYLLABLE CYEOS) 8053 0xCCE5 쳥 (HANGUL SYLLABLE CYEONG) 8054 0xCCE6 쳦 (HANGUL SYLLABLE CYEOJ) 8055 0xCCE7 쳧 (HANGUL SYLLABLE CYEOC) 8056 0xCCE8 쳨 (HANGUL SYLLABLE CYEOK) 8057 0xCCE9 쳩 (HANGUL SYLLABLE CYEOT) 8058 0xCCEA 쳪 (HANGUL SYLLABLE CYEOP) 8059 0xCCEB 쳫 (HANGUL SYLLABLE CYEOH) 8060 0xCCED 쳭 (HANGUL SYLLABLE CYEG) 8061 0xCCEE 쳮 (HANGUL SYLLABLE CYEGG) 8062 0xCCEF 쳯 (HANGUL SYLLABLE CYEGS) 8063 0xCCF1 쳱 (HANGUL SYLLABLE CYENJ) 8064 0xCCF2 쳲 (HANGUL SYLLABLE CYENH) 8065 0xCCF3 쳳 (HANGUL SYLLABLE CYED) 8066 0xCCF4 쳴 (HANGUL SYLLABLE CYEL) 8067 0xCCF5 쳵 (HANGUL SYLLABLE CYELG) 8068 0xCCF6 쳶 (HANGUL SYLLABLE CYELM) 8069 0xCCF7 쳷 (HANGUL SYLLABLE CYELB) 8070 0xCCF8 쳸 (HANGUL SYLLABLE CYELS) 8071 0xCCF9 쳹 (HANGUL SYLLABLE CYELT) 8072 0xCCFA 쳺 (HANGUL SYLLABLE CYELP) 8073 0xCCFB 쳻 (HANGUL SYLLABLE CYELH) 8074 0xCCFC 쳼 (HANGUL SYLLABLE CYEM) 8075 0xCCFD 쳽 (HANGUL SYLLABLE CYEB) 8076 0x30A1 ァ (KATAKANA LETTER SMALL A) 8077 0x30A2 ア (KATAKANA LETTER A) 8078 0x30A3 ィ (KATAKANA LETTER SMALL I) 8079 0x30A4 イ (KATAKANA LETTER I) 8080 0x30A5 ゥ (KATAKANA LETTER SMALL U) 8081 0x30A6 ウ (KATAKANA LETTER U) 8082 0x30A7 ェ (KATAKANA LETTER SMALL E) 8083 0x30A8 エ (KATAKANA LETTER E) 8084 0x30A9 ォ (KATAKANA LETTER SMALL O) 8085 0x30AA オ (KATAKANA LETTER O) 8086 0x30AB カ (KATAKANA LETTER KA) 8087 0x30AC ガ (KATAKANA LETTER GA) 8088 0x30AD キ (KATAKANA LETTER KI) 8089 0x30AE ギ (KATAKANA LETTER GI) 8090 0x30AF ク (KATAKANA LETTER KU) 8091 0x30B0 グ (KATAKANA LETTER GU) 8092 0x30B1 ケ (KATAKANA LETTER KE) 8093 0x30B2 ゲ (KATAKANA LETTER GE) 8094 0x30B3 コ (KATAKANA LETTER KO) 8095 0x30B4 ゴ (KATAKANA LETTER GO) 8096 0x30B5 サ (KATAKANA LETTER SA) 8097 0x30B6 ザ (KATAKANA LETTER ZA) 8098 0x30B7 シ (KATAKANA LETTER SI) 8099 0x30B8 ジ (KATAKANA LETTER ZI) 8100 0x30B9 ス (KATAKANA LETTER SU) 8101 0x30BA ズ (KATAKANA LETTER ZU) 8102 0x30BB セ (KATAKANA LETTER SE) 8103 0x30BC ゼ (KATAKANA LETTER ZE) 8104 0x30BD ソ (KATAKANA LETTER SO) 8105 0x30BE ゾ (KATAKANA LETTER ZO) 8106 0x30BF タ (KATAKANA LETTER TA) 8107 0x30C0 ダ (KATAKANA LETTER DA) 8108 0x30C1 チ (KATAKANA LETTER TI) 8109 0x30C2 ヂ (KATAKANA LETTER DI) 8110 0x30C3 ッ (KATAKANA LETTER SMALL TU) 8111 0x30C4 ツ (KATAKANA LETTER TU) 8112 0x30C5 ヅ (KATAKANA LETTER DU) 8113 0x30C6 テ (KATAKANA LETTER TE) 8114 0x30C7 デ (KATAKANA LETTER DE) 8115 0x30C8 ト (KATAKANA LETTER TO) 8116 0x30C9 ド (KATAKANA LETTER DO) 8117 0x30CA ナ (KATAKANA LETTER NA) 8118 0x30CB ニ (KATAKANA LETTER NI) 8119 0x30CC ヌ (KATAKANA LETTER NU) 8120 0x30CD ネ (KATAKANA LETTER NE) 8121 0x30CE ノ (KATAKANA LETTER NO) 8122 0x30CF ハ (KATAKANA LETTER HA) 8123 0x30D0 バ (KATAKANA LETTER BA) 8124 0x30D1 パ (KATAKANA LETTER PA) 8125 0x30D2 ヒ (KATAKANA LETTER HI) 8126 0x30D3 ビ (KATAKANA LETTER BI) 8127 0x30D4 ピ (KATAKANA LETTER PI) 8128 0x30D5 フ (KATAKANA LETTER HU) 8129 0x30D6 ブ (KATAKANA LETTER BU) 8130 0x30D7 プ (KATAKANA LETTER PU) 8131 0x30D8 ヘ (KATAKANA LETTER HE) 8132 0x30D9 ベ (KATAKANA LETTER BE) 8133 0x30DA ペ (KATAKANA LETTER PE) 8134 0x30DB ホ (KATAKANA LETTER HO) 8135 0x30DC ボ (KATAKANA LETTER BO) 8136 0x30DD ポ (KATAKANA LETTER PO) 8137 0x30DE マ (KATAKANA LETTER MA) 8138 0x30DF ミ (KATAKANA LETTER MI) 8139 0x30E0 ム (KATAKANA LETTER MU) 8140 0x30E1 メ (KATAKANA LETTER ME) 8141 0x30E2 モ (KATAKANA LETTER MO) 8142 0x30E3 ャ (KATAKANA LETTER SMALL YA) 8143 0x30E4 ヤ (KATAKANA LETTER YA) 8144 0x30E5 ュ (KATAKANA LETTER SMALL YU) 8145 0x30E6 ユ (KATAKANA LETTER YU) 8146 0x30E7 ョ (KATAKANA LETTER SMALL YO) 8147 0x30E8 ヨ (KATAKANA LETTER YO) 8148 0x30E9 ラ (KATAKANA LETTER RA) 8149 0x30EA リ (KATAKANA LETTER RI) 8150 0x30EB ル (KATAKANA LETTER RU) 8151 0x30EC レ (KATAKANA LETTER RE) 8152 0x30ED ロ (KATAKANA LETTER RO) 8153 0x30EE ヮ (KATAKANA LETTER SMALL WA) 8154 0x30EF ワ (KATAKANA LETTER WA) 8155 0x30F0 ヰ (KATAKANA LETTER WI) 8156 0x30F1 ヱ (KATAKANA LETTER WE) 8157 0x30F2 ヲ (KATAKANA LETTER WO) 8158 0x30F3 ン (KATAKANA LETTER N) 8159 0x30F4 ヴ (KATAKANA LETTER VU) 8160 0x30F5 ヵ (KATAKANA LETTER SMALL KA) 8161 0x30F6 ヶ (KATAKANA LETTER SMALL KE) 8170 0xCCFE 쳾 (HANGUL SYLLABLE CYEBS) 8171 0xCCFF 쳿 (HANGUL SYLLABLE CYES) 8172 0xCD00 촀 (HANGUL SYLLABLE CYESS) 8173 0xCD02 촂 (HANGUL SYLLABLE CYEJ) 8174 0xCD03 촃 (HANGUL SYLLABLE CYEC) 8175 0xCD04 촄 (HANGUL SYLLABLE CYEK) 8176 0xCD05 촅 (HANGUL SYLLABLE CYET) 8177 0xCD06 촆 (HANGUL SYLLABLE CYEP) 8178 0xCD07 촇 (HANGUL SYLLABLE CYEH) 8179 0xCD0A 촊 (HANGUL SYLLABLE COGG) 8180 0xCD0B 촋 (HANGUL SYLLABLE COGS) 8181 0xCD0D 촍 (HANGUL SYLLABLE CONJ) 8182 0xCD0E 촎 (HANGUL SYLLABLE CONH) 8183 0xCD0F 촏 (HANGUL SYLLABLE COD) 8184 0xCD11 촑 (HANGUL SYLLABLE COLG) 8185 0xCD12 촒 (HANGUL SYLLABLE COLM) 8186 0xCD13 촓 (HANGUL SYLLABLE COLB) 8187 0xCD14 촔 (HANGUL SYLLABLE COLS) 8188 0xCD15 촕 (HANGUL SYLLABLE COLT) 8189 0xCD16 촖 (HANGUL SYLLABLE COLP) 8190 0xCD17 촗 (HANGUL SYLLABLE COLH) 8191 0xCD1A 촚 (HANGUL SYLLABLE COBS) 8192 0xCD1C 촜 (HANGUL SYLLABLE COSS) 8193 0xCD1E 촞 (HANGUL SYLLABLE COJ) 8194 0xCD1F 촟 (HANGUL SYLLABLE COC) 8195 0xCD20 촠 (HANGUL SYLLABLE COK) 8202 0xCD21 촡 (HANGUL SYLLABLE COT) 8203 0xCD22 촢 (HANGUL SYLLABLE COP) 8204 0xCD23 촣 (HANGUL SYLLABLE COH) 8205 0xCD25 촥 (HANGUL SYLLABLE CWAG) 8206 0xCD26 촦 (HANGUL SYLLABLE CWAGG) 8207 0xCD27 촧 (HANGUL SYLLABLE CWAGS) 8208 0xCD29 촩 (HANGUL SYLLABLE CWANJ) 8209 0xCD2A 촪 (HANGUL SYLLABLE CWANH) 8210 0xCD2B 촫 (HANGUL SYLLABLE CWAD) 8211 0xCD2D 촭 (HANGUL SYLLABLE CWALG) 8212 0xCD2E 촮 (HANGUL SYLLABLE CWALM) 8213 0xCD2F 촯 (HANGUL SYLLABLE CWALB) 8214 0xCD30 촰 (HANGUL SYLLABLE CWALS) 8215 0xCD31 촱 (HANGUL SYLLABLE CWALT) 8216 0xCD32 촲 (HANGUL SYLLABLE CWALP) 8217 0xCD33 촳 (HANGUL SYLLABLE CWALH) 8218 0xCD34 촴 (HANGUL SYLLABLE CWAM) 8219 0xCD35 촵 (HANGUL SYLLABLE CWAB) 8220 0xCD36 촶 (HANGUL SYLLABLE CWABS) 8221 0xCD37 촷 (HANGUL SYLLABLE CWAS) 8222 0xCD38 촸 (HANGUL SYLLABLE CWASS) 8223 0xCD3A 촺 (HANGUL SYLLABLE CWAJ) 8224 0xCD3B 촻 (HANGUL SYLLABLE CWAC) 8225 0xCD3C 촼 (HANGUL SYLLABLE CWAK) 8226 0xCD3D 촽 (HANGUL SYLLABLE CWAT) 8227 0xCD3E 촾 (HANGUL SYLLABLE CWAP) 8234 0xCD3F 촿 (HANGUL SYLLABLE CWAH) 8235 0xCD40 쵀 (HANGUL SYLLABLE CWAE) 8236 0xCD41 쵁 (HANGUL SYLLABLE CWAEG) 8237 0xCD42 쵂 (HANGUL SYLLABLE CWAEGG) 8238 0xCD43 쵃 (HANGUL SYLLABLE CWAEGS) 8239 0xCD44 쵄 (HANGUL SYLLABLE CWAEN) 8240 0xCD45 쵅 (HANGUL SYLLABLE CWAENJ) 8241 0xCD46 쵆 (HANGUL SYLLABLE CWAENH) 8242 0xCD47 쵇 (HANGUL SYLLABLE CWAED) 8243 0xCD48 쵈 (HANGUL SYLLABLE CWAEL) 8244 0xCD49 쵉 (HANGUL SYLLABLE CWAELG) 8245 0xCD4A 쵊 (HANGUL SYLLABLE CWAELM) 8246 0xCD4B 쵋 (HANGUL SYLLABLE CWAELB) 8247 0xCD4C 쵌 (HANGUL SYLLABLE CWAELS) 8248 0xCD4D 쵍 (HANGUL SYLLABLE CWAELT) 8249 0xCD4E 쵎 (HANGUL SYLLABLE CWAELP) 8250 0xCD4F 쵏 (HANGUL SYLLABLE CWAELH) 8251 0xCD50 쵐 (HANGUL SYLLABLE CWAEM) 8252 0xCD51 쵑 (HANGUL SYLLABLE CWAEB) 8253 0xCD52 쵒 (HANGUL SYLLABLE CWAEBS) 8254 0xCD53 쵓 (HANGUL SYLLABLE CWAES) 8255 0xCD54 쵔 (HANGUL SYLLABLE CWAESS) 8256 0xCD55 쵕 (HANGUL SYLLABLE CWAENG) 8257 0xCD56 쵖 (HANGUL SYLLABLE CWAEJ) 8258 0xCD57 쵗 (HANGUL SYLLABLE CWAEC) 8259 0xCD58 쵘 (HANGUL SYLLABLE CWAEK) 8260 0xCD59 쵙 (HANGUL SYLLABLE CWAET) 8261 0xCD5A 쵚 (HANGUL SYLLABLE CWAEP) 8262 0xCD5B 쵛 (HANGUL SYLLABLE CWAEH) 8263 0xCD5D 쵝 (HANGUL SYLLABLE COEG) 8264 0xCD5E 쵞 (HANGUL SYLLABLE COEGG) 8265 0xCD5F 쵟 (HANGUL SYLLABLE COEGS) 8266 0x0410 А (CYRILLIC CAPITAL LETTER A) 8267 0x0411 Б (CYRILLIC CAPITAL LETTER BE) 8268 0x0412 В (CYRILLIC CAPITAL LETTER VE) 8269 0x0413 Г (CYRILLIC CAPITAL LETTER GHE) 8270 0x0414 Д (CYRILLIC CAPITAL LETTER DE) 8271 0x0415 Е (CYRILLIC CAPITAL LETTER IE) 8272 0x0401 Ё (CYRILLIC CAPITAL LETTER IO) 8273 0x0416 Ж (CYRILLIC CAPITAL LETTER ZHE) 8274 0x0417 З (CYRILLIC CAPITAL LETTER ZE) 8275 0x0418 И (CYRILLIC CAPITAL LETTER I) 8276 0x0419 Й (CYRILLIC CAPITAL LETTER SHORT I) 8277 0x041A К (CYRILLIC CAPITAL LETTER KA) 8278 0x041B Л (CYRILLIC CAPITAL LETTER EL) 8279 0x041C М (CYRILLIC CAPITAL LETTER EM) 8280 0x041D Н (CYRILLIC CAPITAL LETTER EN) 8281 0x041E О (CYRILLIC CAPITAL LETTER O) 8282 0x041F П (CYRILLIC CAPITAL LETTER PE) 8283 0x0420 Р (CYRILLIC CAPITAL LETTER ER) 8284 0x0421 С (CYRILLIC CAPITAL LETTER ES) 8285 0x0422 Т (CYRILLIC CAPITAL LETTER TE) 8286 0x0423 У (CYRILLIC CAPITAL LETTER U) 8287 0x0424 Ф (CYRILLIC CAPITAL LETTER EF) 8288 0x0425 Х (CYRILLIC CAPITAL LETTER HA) 8289 0x0426 Ц (CYRILLIC CAPITAL LETTER TSE) 8290 0x0427 Ч (CYRILLIC CAPITAL LETTER CHE) 8291 0x0428 Ш (CYRILLIC CAPITAL LETTER SHA) 8292 0x0429 Щ (CYRILLIC CAPITAL LETTER SHCHA) 8293 0x042A Ъ (CYRILLIC CAPITAL LETTER HARD SIGN) 8294 0x042B Ы (CYRILLIC CAPITAL LETTER YERU) 8295 0x042C Ь (CYRILLIC CAPITAL LETTER SOFT SIGN) 8296 0x042D Э (CYRILLIC CAPITAL LETTER E) 8297 0x042E Ю (CYRILLIC CAPITAL LETTER YU) 8298 0x042F Я (CYRILLIC CAPITAL LETTER YA) 8314 0x0430 а (CYRILLIC SMALL LETTER A) 8315 0x0431 б (CYRILLIC SMALL LETTER BE) 8316 0x0432 в (CYRILLIC SMALL LETTER VE) 8317 0x0433 г (CYRILLIC SMALL LETTER GHE) 8318 0x0434 д (CYRILLIC SMALL LETTER DE) 8319 0x0435 е (CYRILLIC SMALL LETTER IE) 8320 0x0451 ё (CYRILLIC SMALL LETTER IO) 8321 0x0436 ж (CYRILLIC SMALL LETTER ZHE) 8322 0x0437 з (CYRILLIC SMALL LETTER ZE) 8323 0x0438 и (CYRILLIC SMALL LETTER I) 8324 0x0439 й (CYRILLIC SMALL LETTER SHORT I) 8325 0x043A к (CYRILLIC SMALL LETTER KA) 8326 0x043B л (CYRILLIC SMALL LETTER EL) 8327 0x043C м (CYRILLIC SMALL LETTER EM) 8328 0x043D н (CYRILLIC SMALL LETTER EN) 8329 0x043E о (CYRILLIC SMALL LETTER O) 8330 0x043F п (CYRILLIC SMALL LETTER PE) 8331 0x0440 р (CYRILLIC SMALL LETTER ER) 8332 0x0441 с (CYRILLIC SMALL LETTER ES) 8333 0x0442 т (CYRILLIC SMALL LETTER TE) 8334 0x0443 у (CYRILLIC SMALL LETTER U) 8335 0x0444 ф (CYRILLIC SMALL LETTER EF) 8336 0x0445 х (CYRILLIC SMALL LETTER HA) 8337 0x0446 ц (CYRILLIC SMALL LETTER TSE) 8338 0x0447 ч (CYRILLIC SMALL LETTER CHE) 8339 0x0448 ш (CYRILLIC SMALL LETTER SHA) 8340 0x0449 щ (CYRILLIC SMALL LETTER SHCHA) 8341 0x044A ъ (CYRILLIC SMALL LETTER HARD SIGN) 8342 0x044B ы (CYRILLIC SMALL LETTER YERU) 8343 0x044C ь (CYRILLIC SMALL LETTER SOFT SIGN) 8344 0x044D э (CYRILLIC SMALL LETTER E) 8345 0x044E ю (CYRILLIC SMALL LETTER YU) 8346 0x044F я (CYRILLIC SMALL LETTER YA) 8360 0xCD61 쵡 (HANGUL SYLLABLE COENJ) 8361 0xCD62 쵢 (HANGUL SYLLABLE COENH) 8362 0xCD63 쵣 (HANGUL SYLLABLE COED) 8363 0xCD65 쵥 (HANGUL SYLLABLE COELG) 8364 0xCD66 쵦 (HANGUL SYLLABLE COELM) 8365 0xCD67 쵧 (HANGUL SYLLABLE COELB) 8366 0xCD68 쵨 (HANGUL SYLLABLE COELS) 8367 0xCD69 쵩 (HANGUL SYLLABLE COELT) 8368 0xCD6A 쵪 (HANGUL SYLLABLE COELP) 8369 0xCD6B 쵫 (HANGUL SYLLABLE COELH) 8370 0xCD6E 쵮 (HANGUL SYLLABLE COEBS) 8371 0xCD70 쵰 (HANGUL SYLLABLE COESS) 8372 0xCD72 쵲 (HANGUL SYLLABLE COEJ) 8373 0xCD73 쵳 (HANGUL SYLLABLE COEC) 8374 0xCD74 쵴 (HANGUL SYLLABLE COEK) 8375 0xCD75 쵵 (HANGUL SYLLABLE COET) 8376 0xCD76 쵶 (HANGUL SYLLABLE COEP) 8377 0xCD77 쵷 (HANGUL SYLLABLE COEH) 8378 0xCD79 쵹 (HANGUL SYLLABLE CYOG) 8379 0xCD7A 쵺 (HANGUL SYLLABLE CYOGG) 8380 0xCD7B 쵻 (HANGUL SYLLABLE CYOGS) 8381 0xCD7C 쵼 (HANGUL SYLLABLE CYON) 8382 0xCD7D 쵽 (HANGUL SYLLABLE CYONJ) 8383 0xCD7E 쵾 (HANGUL SYLLABLE CYONH) 8384 0xCD7F 쵿 (HANGUL SYLLABLE CYOD) 8385 0xCD80 춀 (HANGUL SYLLABLE CYOL) 8392 0xCD81 춁 (HANGUL SYLLABLE CYOLG) 8393 0xCD82 춂 (HANGUL SYLLABLE CYOLM) 8394 0xCD83 춃 (HANGUL SYLLABLE CYOLB) 8395 0xCD84 춄 (HANGUL SYLLABLE CYOLS) 8396 0xCD85 춅 (HANGUL SYLLABLE CYOLT) 8397 0xCD86 춆 (HANGUL SYLLABLE CYOLP) 8398 0xCD87 춇 (HANGUL SYLLABLE CYOLH) 8399 0xCD89 춉 (HANGUL SYLLABLE CYOB) 8400 0xCD8A 춊 (HANGUL SYLLABLE CYOBS) 8401 0xCD8B 춋 (HANGUL SYLLABLE CYOS) 8402 0xCD8C 춌 (HANGUL SYLLABLE CYOSS) 8403 0xCD8D 춍 (HANGUL SYLLABLE CYONG) 8404 0xCD8E 춎 (HANGUL SYLLABLE CYOJ) 8405 0xCD8F 춏 (HANGUL SYLLABLE CYOC) 8406 0xCD90 춐 (HANGUL SYLLABLE CYOK) 8407 0xCD91 춑 (HANGUL SYLLABLE CYOT) 8408 0xCD92 춒 (HANGUL SYLLABLE CYOP) 8409 0xCD93 춓 (HANGUL SYLLABLE CYOH) 8410 0xCD96 춖 (HANGUL SYLLABLE CUGG) 8411 0xCD97 춗 (HANGUL SYLLABLE CUGS) 8412 0xCD99 춙 (HANGUL SYLLABLE CUNJ) 8413 0xCD9A 춚 (HANGUL SYLLABLE CUNH) 8414 0xCD9B 춛 (HANGUL SYLLABLE CUD) 8415 0xCD9D 춝 (HANGUL SYLLABLE CULG) 8416 0xCD9E 춞 (HANGUL SYLLABLE CULM) 8417 0xCD9F 춟 (HANGUL SYLLABLE CULB) 8424 0xCDA0 춠 (HANGUL SYLLABLE CULS) 8425 0xCDA1 춡 (HANGUL SYLLABLE CULT) 8426 0xCDA2 춢 (HANGUL SYLLABLE CULP) 8427 0xCDA3 춣 (HANGUL SYLLABLE CULH) 8428 0xCDA6 춦 (HANGUL SYLLABLE CUBS) 8429 0xCDA8 춨 (HANGUL SYLLABLE CUSS) 8430 0xCDAA 춪 (HANGUL SYLLABLE CUJ) 8431 0xCDAB 춫 (HANGUL SYLLABLE CUC) 8432 0xCDAC 춬 (HANGUL SYLLABLE CUK) 8433 0xCDAD 춭 (HANGUL SYLLABLE CUT) 8434 0xCDAE 춮 (HANGUL SYLLABLE CUP) 8435 0xCDAF 춯 (HANGUL SYLLABLE CUH) 8436 0xCDB1 춱 (HANGUL SYLLABLE CWEOG) 8437 0xCDB2 춲 (HANGUL SYLLABLE CWEOGG) 8438 0xCDB3 춳 (HANGUL SYLLABLE CWEOGS) 8439 0xCDB4 춴 (HANGUL SYLLABLE CWEON) 8440 0xCDB5 춵 (HANGUL SYLLABLE CWEONJ) 8441 0xCDB6 춶 (HANGUL SYLLABLE CWEONH) 8442 0xCDB7 춷 (HANGUL SYLLABLE CWEOD) 8443 0xCDB8 춸 (HANGUL SYLLABLE CWEOL) 8444 0xCDB9 춹 (HANGUL SYLLABLE CWEOLG) 8445 0xCDBA 춺 (HANGUL SYLLABLE CWEOLM) 8446 0xCDBB 춻 (HANGUL SYLLABLE CWEOLB) 8447 0xCDBC 춼 (HANGUL SYLLABLE CWEOLS) 8448 0xCDBD 춽 (HANGUL SYLLABLE CWEOLT) 8449 0xCDBE 춾 (HANGUL SYLLABLE CWEOLP) 8450 0xCDBF 춿 (HANGUL SYLLABLE CWEOLH) 8451 0xCDC0 췀 (HANGUL SYLLABLE CWEOM) 8452 0xCDC1 췁 (HANGUL SYLLABLE CWEOB) 8453 0xCDC2 췂 (HANGUL SYLLABLE CWEOBS) 8454 0xCDC3 췃 (HANGUL SYLLABLE CWEOS) 8455 0xCDC5 췅 (HANGUL SYLLABLE CWEONG) 8550 0xCDC6 췆 (HANGUL SYLLABLE CWEOJ) 8551 0xCDC7 췇 (HANGUL SYLLABLE CWEOC) 8552 0xCDC8 췈 (HANGUL SYLLABLE CWEOK) 8553 0xCDC9 췉 (HANGUL SYLLABLE CWEOT) 8554 0xCDCA 췊 (HANGUL SYLLABLE CWEOP) 8555 0xCDCB 췋 (HANGUL SYLLABLE CWEOH) 8556 0xCDCD 췍 (HANGUL SYLLABLE CWEG) 8557 0xCDCE 췎 (HANGUL SYLLABLE CWEGG) 8558 0xCDCF 췏 (HANGUL SYLLABLE CWEGS) 8559 0xCDD1 췑 (HANGUL SYLLABLE CWENJ) 8560 0xCDD2 췒 (HANGUL SYLLABLE CWENH) 8561 0xCDD3 췓 (HANGUL SYLLABLE CWED) 8562 0xCDD4 췔 (HANGUL SYLLABLE CWEL) 8563 0xCDD5 췕 (HANGUL SYLLABLE CWELG) 8564 0xCDD6 췖 (HANGUL SYLLABLE CWELM) 8565 0xCDD7 췗 (HANGUL SYLLABLE CWELB) 8566 0xCDD8 췘 (HANGUL SYLLABLE CWELS) 8567 0xCDD9 췙 (HANGUL SYLLABLE CWELT) 8568 0xCDDA 췚 (HANGUL SYLLABLE CWELP) 8569 0xCDDB 췛 (HANGUL SYLLABLE CWELH) 8570 0xCDDC 췜 (HANGUL SYLLABLE CWEM) 8571 0xCDDD 췝 (HANGUL SYLLABLE CWEB) 8572 0xCDDE 췞 (HANGUL SYLLABLE CWEBS) 8573 0xCDDF 췟 (HANGUL SYLLABLE CWES) 8574 0xCDE0 췠 (HANGUL SYLLABLE CWESS) 8575 0xCDE1 췡 (HANGUL SYLLABLE CWENG) 8582 0xCDE2 췢 (HANGUL SYLLABLE CWEJ) 8583 0xCDE3 췣 (HANGUL SYLLABLE CWEC) 8584 0xCDE4 췤 (HANGUL SYLLABLE CWEK) 8585 0xCDE5 췥 (HANGUL SYLLABLE CWET) 8586 0xCDE6 췦 (HANGUL SYLLABLE CWEP) 8587 0xCDE7 췧 (HANGUL SYLLABLE CWEH) 8588 0xCDE9 췩 (HANGUL SYLLABLE CWIG) 8589 0xCDEA 췪 (HANGUL SYLLABLE CWIGG) 8590 0xCDEB 췫 (HANGUL SYLLABLE CWIGS) 8591 0xCDED 췭 (HANGUL SYLLABLE CWINJ) 8592 0xCDEE 췮 (HANGUL SYLLABLE CWINH) 8593 0xCDEF 췯 (HANGUL SYLLABLE CWID) 8594 0xCDF1 췱 (HANGUL SYLLABLE CWILG) 8595 0xCDF2 췲 (HANGUL SYLLABLE CWILM) 8596 0xCDF3 췳 (HANGUL SYLLABLE CWILB) 8597 0xCDF4 췴 (HANGUL SYLLABLE CWILS) 8598 0xCDF5 췵 (HANGUL SYLLABLE CWILT) 8599 0xCDF6 췶 (HANGUL SYLLABLE CWILP) 8600 0xCDF7 췷 (HANGUL SYLLABLE CWILH) 8601 0xCDFA 췺 (HANGUL SYLLABLE CWIBS) 8602 0xCDFC 췼 (HANGUL SYLLABLE CWISS) 8603 0xCDFE 췾 (HANGUL SYLLABLE CWIJ) 8604 0xCDFF 췿 (HANGUL SYLLABLE CWIC) 8605 0xCE00 츀 (HANGUL SYLLABLE CWIK) 8606 0xCE01 츁 (HANGUL SYLLABLE CWIT) 8607 0xCE02 츂 (HANGUL SYLLABLE CWIP) 8614 0xCE03 츃 (HANGUL SYLLABLE CWIH) 8615 0xCE05 츅 (HANGUL SYLLABLE CYUG) 8616 0xCE06 츆 (HANGUL SYLLABLE CYUGG) 8617 0xCE07 츇 (HANGUL SYLLABLE CYUGS) 8618 0xCE09 츉 (HANGUL SYLLABLE CYUNJ) 8619 0xCE0A 츊 (HANGUL SYLLABLE CYUNH) 8620 0xCE0B 츋 (HANGUL SYLLABLE CYUD) 8621 0xCE0D 츍 (HANGUL SYLLABLE CYULG) 8622 0xCE0E 츎 (HANGUL SYLLABLE CYULM) 8623 0xCE0F 츏 (HANGUL SYLLABLE CYULB) 8624 0xCE10 츐 (HANGUL SYLLABLE CYULS) 8625 0xCE11 츑 (HANGUL SYLLABLE CYULT) 8626 0xCE12 츒 (HANGUL SYLLABLE CYULP) 8627 0xCE13 츓 (HANGUL SYLLABLE CYULH) 8628 0xCE15 츕 (HANGUL SYLLABLE CYUB) 8629 0xCE16 츖 (HANGUL SYLLABLE CYUBS) 8630 0xCE17 츗 (HANGUL SYLLABLE CYUS) 8631 0xCE18 츘 (HANGUL SYLLABLE CYUSS) 8632 0xCE1A 츚 (HANGUL SYLLABLE CYUJ) 8633 0xCE1B 츛 (HANGUL SYLLABLE CYUC) 8634 0xCE1C 츜 (HANGUL SYLLABLE CYUK) 8635 0xCE1D 츝 (HANGUL SYLLABLE CYUT) 8636 0xCE1E 츞 (HANGUL SYLLABLE CYUP) 8637 0xCE1F 츟 (HANGUL SYLLABLE CYUH) 8638 0xCE22 츢 (HANGUL SYLLABLE CEUGG) 8639 0xCE23 츣 (HANGUL SYLLABLE CEUGS) 8640 0xCE25 츥 (HANGUL SYLLABLE CEUNJ) 8641 0xCE26 츦 (HANGUL SYLLABLE CEUNH) 8642 0xCE27 츧 (HANGUL SYLLABLE CEUD) 8643 0xCE29 츩 (HANGUL SYLLABLE CEULG) 8644 0xCE2A 츪 (HANGUL SYLLABLE CEULM) 8645 0xCE2B 츫 (HANGUL SYLLABLE CEULB) 8740 0xCE2C 츬 (HANGUL SYLLABLE CEULS) 8741 0xCE2D 츭 (HANGUL SYLLABLE CEULT) 8742 0xCE2E 츮 (HANGUL SYLLABLE CEULP) 8743 0xCE2F 츯 (HANGUL SYLLABLE CEULH) 8744 0xCE32 츲 (HANGUL SYLLABLE CEUBS) 8745 0xCE34 츴 (HANGUL SYLLABLE CEUSS) 8746 0xCE36 츶 (HANGUL SYLLABLE CEUJ) 8747 0xCE37 츷 (HANGUL SYLLABLE CEUC) 8748 0xCE38 츸 (HANGUL SYLLABLE CEUK) 8749 0xCE39 츹 (HANGUL SYLLABLE CEUT) 8750 0xCE3A 츺 (HANGUL SYLLABLE CEUP) 8751 0xCE3B 츻 (HANGUL SYLLABLE CEUH) 8752 0xCE3C 츼 (HANGUL SYLLABLE CYI) 8753 0xCE3D 츽 (HANGUL SYLLABLE CYIG) 8754 0xCE3E 츾 (HANGUL SYLLABLE CYIGG) 8755 0xCE3F 츿 (HANGUL SYLLABLE CYIGS) 8756 0xCE40 칀 (HANGUL SYLLABLE CYIN) 8757 0xCE41 칁 (HANGUL SYLLABLE CYINJ) 8758 0xCE42 칂 (HANGUL SYLLABLE CYINH) 8759 0xCE43 칃 (HANGUL SYLLABLE CYID) 8760 0xCE44 칄 (HANGUL SYLLABLE CYIL) 8761 0xCE45 칅 (HANGUL SYLLABLE CYILG) 8762 0xCE46 칆 (HANGUL SYLLABLE CYILM) 8763 0xCE47 칇 (HANGUL SYLLABLE CYILB) 8764 0xCE48 칈 (HANGUL SYLLABLE CYILS) 8765 0xCE49 칉 (HANGUL SYLLABLE CYILT) 8772 0xCE4A 칊 (HANGUL SYLLABLE CYILP) 8773 0xCE4B 칋 (HANGUL SYLLABLE CYILH) 8774 0xCE4C 칌 (HANGUL SYLLABLE CYIM) 8775 0xCE4D 칍 (HANGUL SYLLABLE CYIB) 8776 0xCE4E 칎 (HANGUL SYLLABLE CYIBS) 8777 0xCE4F 칏 (HANGUL SYLLABLE CYIS) 8778 0xCE50 칐 (HANGUL SYLLABLE CYISS) 8779 0xCE51 칑 (HANGUL SYLLABLE CYING) 8780 0xCE52 칒 (HANGUL SYLLABLE CYIJ) 8781 0xCE53 칓 (HANGUL SYLLABLE CYIC) 8782 0xCE54 칔 (HANGUL SYLLABLE CYIK) 8783 0xCE55 칕 (HANGUL SYLLABLE CYIT) 8784 0xCE56 칖 (HANGUL SYLLABLE CYIP) 8785 0xCE57 칗 (HANGUL SYLLABLE CYIH) 8786 0xCE5A 칚 (HANGUL SYLLABLE CIGG) 8787 0xCE5B 칛 (HANGUL SYLLABLE CIGS) 8788 0xCE5D 칝 (HANGUL SYLLABLE CINJ) 8789 0xCE5E 칞 (HANGUL SYLLABLE CINH) 8790 0xCE62 칢 (HANGUL SYLLABLE CILM) 8791 0xCE63 칣 (HANGUL SYLLABLE CILB) 8792 0xCE64 칤 (HANGUL SYLLABLE CILS) 8793 0xCE65 칥 (HANGUL SYLLABLE CILT) 8794 0xCE66 칦 (HANGUL SYLLABLE CILP) 8795 0xCE67 칧 (HANGUL SYLLABLE CILH) 8796 0xCE6A 칪 (HANGUL SYLLABLE CIBS) 8797 0xCE6C 칬 (HANGUL SYLLABLE CISS) 8804 0xCE6E 칮 (HANGUL SYLLABLE CIJ) 8805 0xCE6F 칯 (HANGUL SYLLABLE CIC) 8806 0xCE70 칰 (HANGUL SYLLABLE CIK) 8807 0xCE71 칱 (HANGUL SYLLABLE CIT) 8808 0xCE72 칲 (HANGUL SYLLABLE CIP) 8809 0xCE73 칳 (HANGUL SYLLABLE CIH) 8810 0xCE76 칶 (HANGUL SYLLABLE KAGG) 8811 0xCE77 칷 (HANGUL SYLLABLE KAGS) 8812 0xCE79 칹 (HANGUL SYLLABLE KANJ) 8813 0xCE7A 칺 (HANGUL SYLLABLE KANH) 8814 0xCE7B 칻 (HANGUL SYLLABLE KAD) 8815 0xCE7D 칽 (HANGUL SYLLABLE KALG) 8816 0xCE7E 칾 (HANGUL SYLLABLE KALM) 8817 0xCE7F 칿 (HANGUL SYLLABLE KALB) 8818 0xCE80 캀 (HANGUL SYLLABLE KALS) 8819 0xCE81 캁 (HANGUL SYLLABLE KALT) 8820 0xCE82 캂 (HANGUL SYLLABLE KALP) 8821 0xCE83 캃 (HANGUL SYLLABLE KALH) 8822 0xCE86 캆 (HANGUL SYLLABLE KABS) 8823 0xCE88 캈 (HANGUL SYLLABLE KASS) 8824 0xCE8A 캊 (HANGUL SYLLABLE KAJ) 8825 0xCE8B 캋 (HANGUL SYLLABLE KAC) 8826 0xCE8C 캌 (HANGUL SYLLABLE KAK) 8827 0xCE8D 캍 (HANGUL SYLLABLE KAT) 8828 0xCE8E 캎 (HANGUL SYLLABLE KAP) 8829 0xCE8F 캏 (HANGUL SYLLABLE KAH) 8830 0xCE92 캒 (HANGUL SYLLABLE KAEGG) 8831 0xCE93 캓 (HANGUL SYLLABLE KAEGS) 8832 0xCE95 캕 (HANGUL SYLLABLE KAENJ) 8833 0xCE96 캖 (HANGUL SYLLABLE KAENH) 8834 0xCE97 캗 (HANGUL SYLLABLE KAED) 8835 0xCE99 캙 (HANGUL SYLLABLE KAELG) 8930 0xCE9A 캚 (HANGUL SYLLABLE KAELM) 8931 0xCE9B 캛 (HANGUL SYLLABLE KAELB) 8932 0xCE9C 캜 (HANGUL SYLLABLE KAELS) 8933 0xCE9D 캝 (HANGUL SYLLABLE KAELT) 8934 0xCE9E 캞 (HANGUL SYLLABLE KAELP) 8935 0xCE9F 캟 (HANGUL SYLLABLE KAELH) 8936 0xCEA2 캢 (HANGUL SYLLABLE KAEBS) 8937 0xCEA6 캦 (HANGUL SYLLABLE KAEJ) 8938 0xCEA7 캧 (HANGUL SYLLABLE KAEC) 8939 0xCEA8 캨 (HANGUL SYLLABLE KAEK) 8940 0xCEA9 캩 (HANGUL SYLLABLE KAET) 8941 0xCEAA 캪 (HANGUL SYLLABLE KAEP) 8942 0xCEAB 캫 (HANGUL SYLLABLE KAEH) 8943 0xCEAE 캮 (HANGUL SYLLABLE KYAGG) 8944 0xCEAF 캯 (HANGUL SYLLABLE KYAGS) 8945 0xCEB0 캰 (HANGUL SYLLABLE KYAN) 8946 0xCEB1 캱 (HANGUL SYLLABLE KYANJ) 8947 0xCEB2 캲 (HANGUL SYLLABLE KYANH) 8948 0xCEB3 캳 (HANGUL SYLLABLE KYAD) 8949 0xCEB4 캴 (HANGUL SYLLABLE KYAL) 8950 0xCEB5 캵 (HANGUL SYLLABLE KYALG) 8951 0xCEB6 캶 (HANGUL SYLLABLE KYALM) 8952 0xCEB7 캷 (HANGUL SYLLABLE KYALB) 8953 0xCEB8 캸 (HANGUL SYLLABLE KYALS) 8954 0xCEB9 캹 (HANGUL SYLLABLE KYALT) 8955 0xCEBA 캺 (HANGUL SYLLABLE KYALP) 8962 0xCEBB 캻 (HANGUL SYLLABLE KYALH) 8963 0xCEBC 캼 (HANGUL SYLLABLE KYAM) 8964 0xCEBD 캽 (HANGUL SYLLABLE KYAB) 8965 0xCEBE 캾 (HANGUL SYLLABLE KYABS) 8966 0xCEBF 캿 (HANGUL SYLLABLE KYAS) 8967 0xCEC0 컀 (HANGUL SYLLABLE KYASS) 8968 0xCEC2 컂 (HANGUL SYLLABLE KYAJ) 8969 0xCEC3 컃 (HANGUL SYLLABLE KYAC) 8970 0xCEC4 컄 (HANGUL SYLLABLE KYAK) 8971 0xCEC5 컅 (HANGUL SYLLABLE KYAT) 8972 0xCEC6 컆 (HANGUL SYLLABLE KYAP) 8973 0xCEC7 컇 (HANGUL SYLLABLE KYAH) 8974 0xCEC8 컈 (HANGUL SYLLABLE KYAE) 8975 0xCEC9 컉 (HANGUL SYLLABLE KYAEG) 8976 0xCECA 컊 (HANGUL SYLLABLE KYAEGG) 8977 0xCECB 컋 (HANGUL SYLLABLE KYAEGS) 8978 0xCECC 컌 (HANGUL SYLLABLE KYAEN) 8979 0xCECD 컍 (HANGUL SYLLABLE KYAENJ) 8980 0xCECE 컎 (HANGUL SYLLABLE KYAENH) 8981 0xCECF 컏 (HANGUL SYLLABLE KYAED) 8982 0xCED0 컐 (HANGUL SYLLABLE KYAEL) 8983 0xCED1 컑 (HANGUL SYLLABLE KYAELG) 8984 0xCED2 컒 (HANGUL SYLLABLE KYAELM) 8985 0xCED3 컓 (HANGUL SYLLABLE KYAELB) 8986 0xCED4 컔 (HANGUL SYLLABLE KYAELS) 8987 0xCED5 컕 (HANGUL SYLLABLE KYAELT) 8994 0xCED6 컖 (HANGUL SYLLABLE KYAELP) 8995 0xCED7 컗 (HANGUL SYLLABLE KYAELH) 8996 0xCED8 컘 (HANGUL SYLLABLE KYAEM) 8997 0xCED9 컙 (HANGUL SYLLABLE KYAEB) 8998 0xCEDA 컚 (HANGUL SYLLABLE KYAEBS) 8999 0xCEDB 컛 (HANGUL SYLLABLE KYAES) 9000 0xCEDC 컜 (HANGUL SYLLABLE KYAESS) 9001 0xCEDD 컝 (HANGUL SYLLABLE KYAENG) 9002 0xCEDE 컞 (HANGUL SYLLABLE KYAEJ) 9003 0xCEDF 컟 (HANGUL SYLLABLE KYAEC) 9004 0xCEE0 컠 (HANGUL SYLLABLE KYAEK) 9005 0xCEE1 컡 (HANGUL SYLLABLE KYAET) 9006 0xCEE2 컢 (HANGUL SYLLABLE KYAEP) 9007 0xCEE3 컣 (HANGUL SYLLABLE KYAEH) 9008 0xCEE6 컦 (HANGUL SYLLABLE KEOGG) 9009 0xCEE7 컧 (HANGUL SYLLABLE KEOGS) 9010 0xCEE9 컩 (HANGUL SYLLABLE KEONJ) 9011 0xCEEA 컪 (HANGUL SYLLABLE KEONH) 9012 0xCEED 컭 (HANGUL SYLLABLE KEOLG) 9013 0xCEEE 컮 (HANGUL SYLLABLE KEOLM) 9014 0xCEEF 컯 (HANGUL SYLLABLE KEOLB) 9015 0xCEF0 컰 (HANGUL SYLLABLE KEOLS) 9016 0xCEF1 컱 (HANGUL SYLLABLE KEOLT) 9017 0xCEF2 컲 (HANGUL SYLLABLE KEOLP) 9018 0xCEF3 컳 (HANGUL SYLLABLE KEOLH) 9019 0xCEF6 컶 (HANGUL SYLLABLE KEOBS) 9020 0xCEFA 컺 (HANGUL SYLLABLE KEOJ) 9021 0xCEFB 컻 (HANGUL SYLLABLE KEOC) 9022 0xCEFC 컼 (HANGUL SYLLABLE KEOK) 9023 0xCEFD 컽 (HANGUL SYLLABLE KEOT) 9024 0xCEFE 컾 (HANGUL SYLLABLE KEOP) 9025 0xCEFF 컿 (HANGUL SYLLABLE KEOH) 9026 0xAC00 가 (HANGUL SYLLABLE GA) 9027 0xAC01 각 (HANGUL SYLLABLE GAG) 9028 0xAC04 간 (HANGUL SYLLABLE GAN) 9029 0xAC07 갇 (HANGUL SYLLABLE GAD) 9030 0xAC08 갈 (HANGUL SYLLABLE GAL) 9031 0xAC09 갉 (HANGUL SYLLABLE GALG) 9032 0xAC0A 갊 (HANGUL SYLLABLE GALM) 9033 0xAC10 감 (HANGUL SYLLABLE GAM) 9034 0xAC11 갑 (HANGUL SYLLABLE GAB) 9035 0xAC12 값 (HANGUL SYLLABLE GABS) 9036 0xAC13 갓 (HANGUL SYLLABLE GAS) 9037 0xAC14 갔 (HANGUL SYLLABLE GASS) 9038 0xAC15 강 (HANGUL SYLLABLE GANG) 9039 0xAC16 갖 (HANGUL SYLLABLE GAJ) 9040 0xAC17 갗 (HANGUL SYLLABLE GAC) 9041 0xAC19 같 (HANGUL SYLLABLE GAT) 9042 0xAC1A 갚 (HANGUL SYLLABLE GAP) 9043 0xAC1B 갛 (HANGUL SYLLABLE GAH) 9044 0xAC1C 개 (HANGUL SYLLABLE GAE) 9045 0xAC1D 객 (HANGUL SYLLABLE GAEG) 9046 0xAC20 갠 (HANGUL SYLLABLE GAEN) 9047 0xAC24 갤 (HANGUL SYLLABLE GAEL) 9048 0xAC2C 갬 (HANGUL SYLLABLE GAEM) 9049 0xAC2D 갭 (HANGUL SYLLABLE GAEB) 9050 0xAC2F 갯 (HANGUL SYLLABLE GAES) 9051 0xAC30 갰 (HANGUL SYLLABLE GAESS) 9052 0xAC31 갱 (HANGUL SYLLABLE GAENG) 9053 0xAC38 갸 (HANGUL SYLLABLE GYA) 9054 0xAC39 갹 (HANGUL SYLLABLE GYAG) 9055 0xAC3C 갼 (HANGUL SYLLABLE GYAN) 9056 0xAC40 걀 (HANGUL SYLLABLE GYAL) 9057 0xAC4B 걋 (HANGUL SYLLABLE GYAS) 9058 0xAC4D 걍 (HANGUL SYLLABLE GYANG) 9059 0xAC54 걔 (HANGUL SYLLABLE GYAE) 9060 0xAC58 걘 (HANGUL SYLLABLE GYAEN) 9061 0xAC5C 걜 (HANGUL SYLLABLE GYAEL) 9062 0xAC70 거 (HANGUL SYLLABLE GEO) 9063 0xAC71 걱 (HANGUL SYLLABLE GEOG) 9064 0xAC74 건 (HANGUL SYLLABLE GEON) 9065 0xAC77 걷 (HANGUL SYLLABLE GEOD) 9066 0xAC78 걸 (HANGUL SYLLABLE GEOL) 9067 0xAC7A 걺 (HANGUL SYLLABLE GEOLM) 9068 0xAC80 검 (HANGUL SYLLABLE GEOM) 9069 0xAC81 겁 (HANGUL SYLLABLE GEOB) 9070 0xAC83 것 (HANGUL SYLLABLE GEOS) 9071 0xAC84 겄 (HANGUL SYLLABLE GEOSS) 9072 0xAC85 겅 (HANGUL SYLLABLE GEONG) 9073 0xAC86 겆 (HANGUL SYLLABLE GEOJ) 9074 0xAC89 겉 (HANGUL SYLLABLE GEOT) 9075 0xAC8A 겊 (HANGUL SYLLABLE GEOP) 9076 0xAC8B 겋 (HANGUL SYLLABLE GEOH) 9077 0xAC8C 게 (HANGUL SYLLABLE GE) 9078 0xAC90 겐 (HANGUL SYLLABLE GEN) 9079 0xAC94 겔 (HANGUL SYLLABLE GEL) 9080 0xAC9C 겜 (HANGUL SYLLABLE GEM) 9081 0xAC9D 겝 (HANGUL SYLLABLE GEB) 9082 0xAC9F 겟 (HANGUL SYLLABLE GES) 9083 0xACA0 겠 (HANGUL SYLLABLE GESS) 9084 0xACA1 겡 (HANGUL SYLLABLE GENG) 9085 0xACA8 겨 (HANGUL SYLLABLE GYEO) 9086 0xACA9 격 (HANGUL SYLLABLE GYEOG) 9087 0xACAA 겪 (HANGUL SYLLABLE GYEOGG) 9088 0xACAC 견 (HANGUL SYLLABLE GYEON) 9089 0xACAF 겯 (HANGUL SYLLABLE GYEOD) 9090 0xACB0 결 (HANGUL SYLLABLE GYEOL) 9091 0xACB8 겸 (HANGUL SYLLABLE GYEOM) 9092 0xACB9 겹 (HANGUL SYLLABLE GYEOB) 9093 0xACBB 겻 (HANGUL SYLLABLE GYEOS) 9094 0xACBC 겼 (HANGUL SYLLABLE GYEOSS) 9095 0xACBD 경 (HANGUL SYLLABLE GYEONG) 9096 0xACC1 곁 (HANGUL SYLLABLE GYEOT) 9097 0xACC4 계 (HANGUL SYLLABLE GYE) 9098 0xACC8 곈 (HANGUL SYLLABLE GYEN) 9099 0xACCC 곌 (HANGUL SYLLABLE GYEL) 9100 0xACD5 곕 (HANGUL SYLLABLE GYEB) 9101 0xACD7 곗 (HANGUL SYLLABLE GYES) 9102 0xACE0 고 (HANGUL SYLLABLE GO) 9103 0xACE1 곡 (HANGUL SYLLABLE GOG) 9104 0xACE4 곤 (HANGUL SYLLABLE GON) 9105 0xACE7 곧 (HANGUL SYLLABLE GOD) 9106 0xACE8 골 (HANGUL SYLLABLE GOL) 9107 0xACEA 곪 (HANGUL SYLLABLE GOLM) 9108 0xACEC 곬 (HANGUL SYLLABLE GOLS) 9109 0xACEF 곯 (HANGUL SYLLABLE GOLH) 9110 0xACF0 곰 (HANGUL SYLLABLE GOM) 9111 0xACF1 곱 (HANGUL SYLLABLE GOB) 9112 0xACF3 곳 (HANGUL SYLLABLE GOS) 9113 0xACF5 공 (HANGUL SYLLABLE GONG) 9114 0xACF6 곶 (HANGUL SYLLABLE GOJ) 9115 0xACFC 과 (HANGUL SYLLABLE GWA) 9116 0xACFD 곽 (HANGUL SYLLABLE GWAG) 9117 0xAD00 관 (HANGUL SYLLABLE GWAN) 9118 0xAD04 괄 (HANGUL SYLLABLE GWAL) 9119 0xAD06 괆 (HANGUL SYLLABLE GWALM) 9120 0xCF02 켂 (HANGUL SYLLABLE KEGG) 9121 0xCF03 켃 (HANGUL SYLLABLE KEGS) 9122 0xCF05 켅 (HANGUL SYLLABLE KENJ) 9123 0xCF06 켆 (HANGUL SYLLABLE KENH) 9124 0xCF07 켇 (HANGUL SYLLABLE KED) 9125 0xCF09 켉 (HANGUL SYLLABLE KELG) 9126 0xCF0A 켊 (HANGUL SYLLABLE KELM) 9127 0xCF0B 켋 (HANGUL SYLLABLE KELB) 9128 0xCF0C 켌 (HANGUL SYLLABLE KELS) 9129 0xCF0D 켍 (HANGUL SYLLABLE KELT) 9130 0xCF0E 켎 (HANGUL SYLLABLE KELP) 9131 0xCF0F 켏 (HANGUL SYLLABLE KELH) 9132 0xCF12 켒 (HANGUL SYLLABLE KEBS) 9133 0xCF14 켔 (HANGUL SYLLABLE KESS) 9134 0xCF16 켖 (HANGUL SYLLABLE KEJ) 9135 0xCF17 켗 (HANGUL SYLLABLE KEC) 9136 0xCF18 켘 (HANGUL SYLLABLE KEK) 9137 0xCF19 켙 (HANGUL SYLLABLE KET) 9138 0xCF1A 켚 (HANGUL SYLLABLE KEP) 9139 0xCF1B 켛 (HANGUL SYLLABLE KEH) 9140 0xCF1D 켝 (HANGUL SYLLABLE KYEOG) 9141 0xCF1E 켞 (HANGUL SYLLABLE KYEOGG) 9142 0xCF1F 켟 (HANGUL SYLLABLE KYEOGS) 9143 0xCF21 켡 (HANGUL SYLLABLE KYEONJ) 9144 0xCF22 켢 (HANGUL SYLLABLE KYEONH) 9145 0xCF23 켣 (HANGUL SYLLABLE KYEOD) 9152 0xCF25 켥 (HANGUL SYLLABLE KYEOLG) 9153 0xCF26 켦 (HANGUL SYLLABLE KYEOLM) 9154 0xCF27 켧 (HANGUL SYLLABLE KYEOLB) 9155 0xCF28 켨 (HANGUL SYLLABLE KYEOLS) 9156 0xCF29 켩 (HANGUL SYLLABLE KYEOLT) 9157 0xCF2A 켪 (HANGUL SYLLABLE KYEOLP) 9158 0xCF2B 켫 (HANGUL SYLLABLE KYEOLH) 9159 0xCF2E 켮 (HANGUL SYLLABLE KYEOBS) 9160 0xCF32 켲 (HANGUL SYLLABLE KYEOJ) 9161 0xCF33 켳 (HANGUL SYLLABLE KYEOC) 9162 0xCF34 켴 (HANGUL SYLLABLE KYEOK) 9163 0xCF35 켵 (HANGUL SYLLABLE KYEOT) 9164 0xCF36 켶 (HANGUL SYLLABLE KYEOP) 9165 0xCF37 켷 (HANGUL SYLLABLE KYEOH) 9166 0xCF39 켹 (HANGUL SYLLABLE KYEG) 9167 0xCF3A 켺 (HANGUL SYLLABLE KYEGG) 9168 0xCF3B 켻 (HANGUL SYLLABLE KYEGS) 9169 0xCF3C 켼 (HANGUL SYLLABLE KYEN) 9170 0xCF3D 켽 (HANGUL SYLLABLE KYENJ) 9171 0xCF3E 켾 (HANGUL SYLLABLE KYENH) 9172 0xCF3F 켿 (HANGUL SYLLABLE KYED) 9173 0xCF40 콀 (HANGUL SYLLABLE KYEL) 9174 0xCF41 콁 (HANGUL SYLLABLE KYELG) 9175 0xCF42 콂 (HANGUL SYLLABLE KYELM) 9176 0xCF43 콃 (HANGUL SYLLABLE KYELB) 9177 0xCF44 콄 (HANGUL SYLLABLE KYELS) 9184 0xCF45 콅 (HANGUL SYLLABLE KYELT) 9185 0xCF46 콆 (HANGUL SYLLABLE KYELP) 9186 0xCF47 콇 (HANGUL SYLLABLE KYELH) 9187 0xCF48 콈 (HANGUL SYLLABLE KYEM) 9188 0xCF49 콉 (HANGUL SYLLABLE KYEB) 9189 0xCF4A 콊 (HANGUL SYLLABLE KYEBS) 9190 0xCF4B 콋 (HANGUL SYLLABLE KYES) 9191 0xCF4C 콌 (HANGUL SYLLABLE KYESS) 9192 0xCF4D 콍 (HANGUL SYLLABLE KYENG) 9193 0xCF4E 콎 (HANGUL SYLLABLE KYEJ) 9194 0xCF4F 콏 (HANGUL SYLLABLE KYEC) 9195 0xCF50 콐 (HANGUL SYLLABLE KYEK) 9196 0xCF51 콑 (HANGUL SYLLABLE KYET) 9197 0xCF52 콒 (HANGUL SYLLABLE KYEP) 9198 0xCF53 콓 (HANGUL SYLLABLE KYEH) 9199 0xCF56 콖 (HANGUL SYLLABLE KOGG) 9200 0xCF57 콗 (HANGUL SYLLABLE KOGS) 9201 0xCF59 콙 (HANGUL SYLLABLE KONJ) 9202 0xCF5A 콚 (HANGUL SYLLABLE KONH) 9203 0xCF5B 콛 (HANGUL SYLLABLE KOD) 9204 0xCF5D 콝 (HANGUL SYLLABLE KOLG) 9205 0xCF5E 콞 (HANGUL SYLLABLE KOLM) 9206 0xCF5F 콟 (HANGUL SYLLABLE KOLB) 9207 0xCF60 콠 (HANGUL SYLLABLE KOLS) 9208 0xCF61 콡 (HANGUL SYLLABLE KOLT) 9209 0xCF62 콢 (HANGUL SYLLABLE KOLP) 9210 0xCF63 콣 (HANGUL SYLLABLE KOLH) 9211 0xCF66 콦 (HANGUL SYLLABLE KOBS) 9212 0xCF68 콨 (HANGUL SYLLABLE KOSS) 9213 0xCF6A 콪 (HANGUL SYLLABLE KOJ) 9214 0xCF6B 콫 (HANGUL SYLLABLE KOC) 9215 0xCF6C 콬 (HANGUL SYLLABLE KOK) 9216 0xAD0C 괌 (HANGUL SYLLABLE GWAM) 9217 0xAD0D 괍 (HANGUL SYLLABLE GWAB) 9218 0xAD0F 괏 (HANGUL SYLLABLE GWAS) 9219 0xAD11 광 (HANGUL SYLLABLE GWANG) 9220 0xAD18 괘 (HANGUL SYLLABLE GWAE) 9221 0xAD1C 괜 (HANGUL SYLLABLE GWAEN) 9222 0xAD20 괠 (HANGUL SYLLABLE GWAEL) 9223 0xAD29 괩 (HANGUL SYLLABLE GWAEB) 9224 0xAD2C 괬 (HANGUL SYLLABLE GWAESS) 9225 0xAD2D 괭 (HANGUL SYLLABLE GWAENG) 9226 0xAD34 괴 (HANGUL SYLLABLE GOE) 9227 0xAD35 괵 (HANGUL SYLLABLE GOEG) 9228 0xAD38 괸 (HANGUL SYLLABLE GOEN) 9229 0xAD3C 괼 (HANGUL SYLLABLE GOEL) 9230 0xAD44 굄 (HANGUL SYLLABLE GOEM) 9231 0xAD45 굅 (HANGUL SYLLABLE GOEB) 9232 0xAD47 굇 (HANGUL SYLLABLE GOES) 9233 0xAD49 굉 (HANGUL SYLLABLE GOENG) 9234 0xAD50 교 (HANGUL SYLLABLE GYO) 9235 0xAD54 굔 (HANGUL SYLLABLE GYON) 9236 0xAD58 굘 (HANGUL SYLLABLE GYOL) 9237 0xAD61 굡 (HANGUL SYLLABLE GYOB) 9238 0xAD63 굣 (HANGUL SYLLABLE GYOS) 9239 0xAD6C 구 (HANGUL SYLLABLE GU) 9240 0xAD6D 국 (HANGUL SYLLABLE GUG) 9241 0xAD70 군 (HANGUL SYLLABLE GUN) 9242 0xAD73 굳 (HANGUL SYLLABLE GUD) 9243 0xAD74 굴 (HANGUL SYLLABLE GUL) 9244 0xAD75 굵 (HANGUL SYLLABLE GULG) 9245 0xAD76 굶 (HANGUL SYLLABLE GULM) 9246 0xAD7B 굻 (HANGUL SYLLABLE GULH) 9247 0xAD7C 굼 (HANGUL SYLLABLE GUM) 9248 0xAD7D 굽 (HANGUL SYLLABLE GUB) 9249 0xAD7F 굿 (HANGUL SYLLABLE GUS) 9250 0xAD81 궁 (HANGUL SYLLABLE GUNG) 9251 0xAD82 궂 (HANGUL SYLLABLE GUJ) 9252 0xAD88 궈 (HANGUL SYLLABLE GWEO) 9253 0xAD89 궉 (HANGUL SYLLABLE GWEOG) 9254 0xAD8C 권 (HANGUL SYLLABLE GWEON) 9255 0xAD90 궐 (HANGUL SYLLABLE GWEOL) 9256 0xAD9C 궜 (HANGUL SYLLABLE GWEOSS) 9257 0xAD9D 궝 (HANGUL SYLLABLE GWEONG) 9258 0xADA4 궤 (HANGUL SYLLABLE GWE) 9259 0xADB7 궷 (HANGUL SYLLABLE GWES) 9260 0xADC0 귀 (HANGUL SYLLABLE GWI) 9261 0xADC1 귁 (HANGUL SYLLABLE GWIG) 9262 0xADC4 귄 (HANGUL SYLLABLE GWIN) 9263 0xADC8 귈 (HANGUL SYLLABLE GWIL) 9264 0xADD0 귐 (HANGUL SYLLABLE GWIM) 9265 0xADD1 귑 (HANGUL SYLLABLE GWIB) 9266 0xADD3 귓 (HANGUL SYLLABLE GWIS) 9267 0xADDC 규 (HANGUL SYLLABLE GYU) 9268 0xADE0 균 (HANGUL SYLLABLE GYUN) 9269 0xADE4 귤 (HANGUL SYLLABLE GYUL) 9270 0xADF8 그 (HANGUL SYLLABLE GEU) 9271 0xADF9 극 (HANGUL SYLLABLE GEUG) 9272 0xADFC 근 (HANGUL SYLLABLE GEUN) 9273 0xADFF 귿 (HANGUL SYLLABLE GEUD) 9274 0xAE00 글 (HANGUL SYLLABLE GEUL) 9275 0xAE01 긁 (HANGUL SYLLABLE GEULG) 9276 0xAE08 금 (HANGUL SYLLABLE GEUM) 9277 0xAE09 급 (HANGUL SYLLABLE GEUB) 9278 0xAE0B 긋 (HANGUL SYLLABLE GEUS) 9279 0xAE0D 긍 (HANGUL SYLLABLE GEUNG) 9280 0xAE14 긔 (HANGUL SYLLABLE GYI) 9281 0xAE30 기 (HANGUL SYLLABLE GI) 9282 0xAE31 긱 (HANGUL SYLLABLE GIG) 9283 0xAE34 긴 (HANGUL SYLLABLE GIN) 9284 0xAE37 긷 (HANGUL SYLLABLE GID) 9285 0xAE38 길 (HANGUL SYLLABLE GIL) 9286 0xAE3A 긺 (HANGUL SYLLABLE GILM) 9287 0xAE40 김 (HANGUL SYLLABLE GIM) 9288 0xAE41 깁 (HANGUL SYLLABLE GIB) 9289 0xAE43 깃 (HANGUL SYLLABLE GIS) 9290 0xAE45 깅 (HANGUL SYLLABLE GING) 9291 0xAE46 깆 (HANGUL SYLLABLE GIJ) 9292 0xAE4A 깊 (HANGUL SYLLABLE GIP) 9293 0xAE4C 까 (HANGUL SYLLABLE GGA) 9294 0xAE4D 깍 (HANGUL SYLLABLE GGAG) 9295 0xAE4E 깎 (HANGUL SYLLABLE GGAGG) 9296 0xAE50 깐 (HANGUL SYLLABLE GGAN) 9297 0xAE54 깔 (HANGUL SYLLABLE GGAL) 9298 0xAE56 깖 (HANGUL SYLLABLE GGALM) 9299 0xAE5C 깜 (HANGUL SYLLABLE GGAM) 9300 0xAE5D 깝 (HANGUL SYLLABLE GGAB) 9301 0xAE5F 깟 (HANGUL SYLLABLE GGAS) 9302 0xAE60 깠 (HANGUL SYLLABLE GGASS) 9303 0xAE61 깡 (HANGUL SYLLABLE GGANG) 9304 0xAE65 깥 (HANGUL SYLLABLE GGAT) 9305 0xAE68 깨 (HANGUL SYLLABLE GGAE) 9306 0xAE69 깩 (HANGUL SYLLABLE GGAEG) 9307 0xAE6C 깬 (HANGUL SYLLABLE GGAEN) 9308 0xAE70 깰 (HANGUL SYLLABLE GGAEL) 9309 0xAE78 깸 (HANGUL SYLLABLE GGAEM) 9310 0xCF6D 콭 (HANGUL SYLLABLE KOT) 9311 0xCF6E 콮 (HANGUL SYLLABLE KOP) 9312 0xCF6F 콯 (HANGUL SYLLABLE KOH) 9313 0xCF72 콲 (HANGUL SYLLABLE KWAGG) 9314 0xCF73 콳 (HANGUL SYLLABLE KWAGS) 9315 0xCF75 콵 (HANGUL SYLLABLE KWANJ) 9316 0xCF76 콶 (HANGUL SYLLABLE KWANH) 9317 0xCF77 콷 (HANGUL SYLLABLE KWAD) 9318 0xCF79 콹 (HANGUL SYLLABLE KWALG) 9319 0xCF7A 콺 (HANGUL SYLLABLE KWALM) 9320 0xCF7B 콻 (HANGUL SYLLABLE KWALB) 9321 0xCF7C 콼 (HANGUL SYLLABLE KWALS) 9322 0xCF7D 콽 (HANGUL SYLLABLE KWALT) 9323 0xCF7E 콾 (HANGUL SYLLABLE KWALP) 9324 0xCF7F 콿 (HANGUL SYLLABLE KWALH) 9325 0xCF81 쾁 (HANGUL SYLLABLE KWAB) 9326 0xCF82 쾂 (HANGUL SYLLABLE KWABS) 9327 0xCF83 쾃 (HANGUL SYLLABLE KWAS) 9328 0xCF84 쾄 (HANGUL SYLLABLE KWASS) 9329 0xCF86 쾆 (HANGUL SYLLABLE KWAJ) 9330 0xCF87 쾇 (HANGUL SYLLABLE KWAC) 9331 0xCF88 쾈 (HANGUL SYLLABLE KWAK) 9332 0xCF89 쾉 (HANGUL SYLLABLE KWAT) 9333 0xCF8A 쾊 (HANGUL SYLLABLE KWAP) 9334 0xCF8B 쾋 (HANGUL SYLLABLE KWAH) 9335 0xCF8D 쾍 (HANGUL SYLLABLE KWAEG) 9342 0xCF8E 쾎 (HANGUL SYLLABLE KWAEGG) 9343 0xCF8F 쾏 (HANGUL SYLLABLE KWAEGS) 9344 0xCF90 쾐 (HANGUL SYLLABLE KWAEN) 9345 0xCF91 쾑 (HANGUL SYLLABLE KWAENJ) 9346 0xCF92 쾒 (HANGUL SYLLABLE KWAENH) 9347 0xCF93 쾓 (HANGUL SYLLABLE KWAED) 9348 0xCF94 쾔 (HANGUL SYLLABLE KWAEL) 9349 0xCF95 쾕 (HANGUL SYLLABLE KWAELG) 9350 0xCF96 쾖 (HANGUL SYLLABLE KWAELM) 9351 0xCF97 쾗 (HANGUL SYLLABLE KWAELB) 9352 0xCF98 쾘 (HANGUL SYLLABLE KWAELS) 9353 0xCF99 쾙 (HANGUL SYLLABLE KWAELT) 9354 0xCF9A 쾚 (HANGUL SYLLABLE KWAELP) 9355 0xCF9B 쾛 (HANGUL SYLLABLE KWAELH) 9356 0xCF9C 쾜 (HANGUL SYLLABLE KWAEM) 9357 0xCF9D 쾝 (HANGUL SYLLABLE KWAEB) 9358 0xCF9E 쾞 (HANGUL SYLLABLE KWAEBS) 9359 0xCF9F 쾟 (HANGUL SYLLABLE KWAES) 9360 0xCFA0 쾠 (HANGUL SYLLABLE KWAESS) 9361 0xCFA2 쾢 (HANGUL SYLLABLE KWAEJ) 9362 0xCFA3 쾣 (HANGUL SYLLABLE KWAEC) 9363 0xCFA4 쾤 (HANGUL SYLLABLE KWAEK) 9364 0xCFA5 쾥 (HANGUL SYLLABLE KWAET) 9365 0xCFA6 쾦 (HANGUL SYLLABLE KWAEP) 9366 0xCFA7 쾧 (HANGUL SYLLABLE KWAEH) 9367 0xCFA9 쾩 (HANGUL SYLLABLE KOEG) 9374 0xCFAA 쾪 (HANGUL SYLLABLE KOEGG) 9375 0xCFAB 쾫 (HANGUL SYLLABLE KOEGS) 9376 0xCFAC 쾬 (HANGUL SYLLABLE KOEN) 9377 0xCFAD 쾭 (HANGUL SYLLABLE KOENJ) 9378 0xCFAE 쾮 (HANGUL SYLLABLE KOENH) 9379 0xCFAF 쾯 (HANGUL SYLLABLE KOED) 9380 0xCFB1 쾱 (HANGUL SYLLABLE KOELG) 9381 0xCFB2 쾲 (HANGUL SYLLABLE KOELM) 9382 0xCFB3 쾳 (HANGUL SYLLABLE KOELB) 9383 0xCFB4 쾴 (HANGUL SYLLABLE KOELS) 9384 0xCFB5 쾵 (HANGUL SYLLABLE KOELT) 9385 0xCFB6 쾶 (HANGUL SYLLABLE KOELP) 9386 0xCFB7 쾷 (HANGUL SYLLABLE KOELH) 9387 0xCFB8 쾸 (HANGUL SYLLABLE KOEM) 9388 0xCFB9 쾹 (HANGUL SYLLABLE KOEB) 9389 0xCFBA 쾺 (HANGUL SYLLABLE KOEBS) 9390 0xCFBB 쾻 (HANGUL SYLLABLE KOES) 9391 0xCFBC 쾼 (HANGUL SYLLABLE KOESS) 9392 0xCFBD 쾽 (HANGUL SYLLABLE KOENG) 9393 0xCFBE 쾾 (HANGUL SYLLABLE KOEJ) 9394 0xCFBF 쾿 (HANGUL SYLLABLE KOEC) 9395 0xCFC0 쿀 (HANGUL SYLLABLE KOEK) 9396 0xCFC1 쿁 (HANGUL SYLLABLE KOET) 9397 0xCFC2 쿂 (HANGUL SYLLABLE KOEP) 9398 0xCFC3 쿃 (HANGUL SYLLABLE KOEH) 9399 0xCFC5 쿅 (HANGUL SYLLABLE KYOG) 9400 0xCFC6 쿆 (HANGUL SYLLABLE KYOGG) 9401 0xCFC7 쿇 (HANGUL SYLLABLE KYOGS) 9402 0xCFC8 쿈 (HANGUL SYLLABLE KYON) 9403 0xCFC9 쿉 (HANGUL SYLLABLE KYONJ) 9404 0xCFCA 쿊 (HANGUL SYLLABLE KYONH) 9405 0xCFCB 쿋 (HANGUL SYLLABLE KYOD) 9406 0xAE79 깹 (HANGUL SYLLABLE GGAEB) 9407 0xAE7B 깻 (HANGUL SYLLABLE GGAES) 9408 0xAE7C 깼 (HANGUL SYLLABLE GGAESS) 9409 0xAE7D 깽 (HANGUL SYLLABLE GGAENG) 9410 0xAE84 꺄 (HANGUL SYLLABLE GGYA) 9411 0xAE85 꺅 (HANGUL SYLLABLE GGYAG) 9412 0xAE8C 꺌 (HANGUL SYLLABLE GGYAL) 9413 0xAEBC 꺼 (HANGUL SYLLABLE GGEO) 9414 0xAEBD 꺽 (HANGUL SYLLABLE GGEOG) 9415 0xAEBE 꺾 (HANGUL SYLLABLE GGEOGG) 9416 0xAEC0 껀 (HANGUL SYLLABLE GGEON) 9417 0xAEC4 껄 (HANGUL SYLLABLE GGEOL) 9418 0xAECC 껌 (HANGUL SYLLABLE GGEOM) 9419 0xAECD 껍 (HANGUL SYLLABLE GGEOB) 9420 0xAECF 껏 (HANGUL SYLLABLE GGEOS) 9421 0xAED0 껐 (HANGUL SYLLABLE GGEOSS) 9422 0xAED1 껑 (HANGUL SYLLABLE GGEONG) 9423 0xAED8 께 (HANGUL SYLLABLE GGE) 9424 0xAED9 껙 (HANGUL SYLLABLE GGEG) 9425 0xAEDC 껜 (HANGUL SYLLABLE GGEN) 9426 0xAEE8 껨 (HANGUL SYLLABLE GGEM) 9427 0xAEEB 껫 (HANGUL SYLLABLE GGES) 9428 0xAEED 껭 (HANGUL SYLLABLE GGENG) 9429 0xAEF4 껴 (HANGUL SYLLABLE GGYEO) 9430 0xAEF8 껸 (HANGUL SYLLABLE GGYEON) 9431 0xAEFC 껼 (HANGUL SYLLABLE GGYEOL) 9432 0xAF07 꼇 (HANGUL SYLLABLE GGYEOS) 9433 0xAF08 꼈 (HANGUL SYLLABLE GGYEOSS) 9434 0xAF0D 꼍 (HANGUL SYLLABLE GGYEOT) 9435 0xAF10 꼐 (HANGUL SYLLABLE GGYE) 9436 0xAF2C 꼬 (HANGUL SYLLABLE GGO) 9437 0xAF2D 꼭 (HANGUL SYLLABLE GGOG) 9438 0xAF30 꼰 (HANGUL SYLLABLE GGON) 9439 0xAF32 꼲 (HANGUL SYLLABLE GGONH) 9440 0xAF34 꼴 (HANGUL SYLLABLE GGOL) 9441 0xAF3C 꼼 (HANGUL SYLLABLE GGOM) 9442 0xAF3D 꼽 (HANGUL SYLLABLE GGOB) 9443 0xAF3F 꼿 (HANGUL SYLLABLE GGOS) 9444 0xAF41 꽁 (HANGUL SYLLABLE GGONG) 9445 0xAF42 꽂 (HANGUL SYLLABLE GGOJ) 9446 0xAF43 꽃 (HANGUL SYLLABLE GGOC) 9447 0xAF48 꽈 (HANGUL SYLLABLE GGWA) 9448 0xAF49 꽉 (HANGUL SYLLABLE GGWAG) 9449 0xAF50 꽐 (HANGUL SYLLABLE GGWAL) 9450 0xAF5C 꽜 (HANGUL SYLLABLE GGWASS) 9451 0xAF5D 꽝 (HANGUL SYLLABLE GGWANG) 9452 0xAF64 꽤 (HANGUL SYLLABLE GGWAE) 9453 0xAF65 꽥 (HANGUL SYLLABLE GGWAEG) 9454 0xAF79 꽹 (HANGUL SYLLABLE GGWAENG) 9455 0xAF80 꾀 (HANGUL SYLLABLE GGOE) 9456 0xAF84 꾄 (HANGUL SYLLABLE GGOEN) 9457 0xAF88 꾈 (HANGUL SYLLABLE GGOEL) 9458 0xAF90 꾐 (HANGUL SYLLABLE GGOEM) 9459 0xAF91 꾑 (HANGUL SYLLABLE GGOEB) 9460 0xAF95 꾕 (HANGUL SYLLABLE GGOENG) 9461 0xAF9C 꾜 (HANGUL SYLLABLE GGYO) 9462 0xAFB8 꾸 (HANGUL SYLLABLE GGU) 9463 0xAFB9 꾹 (HANGUL SYLLABLE GGUG) 9464 0xAFBC 꾼 (HANGUL SYLLABLE GGUN) 9465 0xAFC0 꿀 (HANGUL SYLLABLE GGUL) 9466 0xAFC7 꿇 (HANGUL SYLLABLE GGULH) 9467 0xAFC8 꿈 (HANGUL SYLLABLE GGUM) 9468 0xAFC9 꿉 (HANGUL SYLLABLE GGUB) 9469 0xAFCB 꿋 (HANGUL SYLLABLE GGUS) 9470 0xAFCD 꿍 (HANGUL SYLLABLE GGUNG) 9471 0xAFCE 꿎 (HANGUL SYLLABLE GGUJ) 9472 0xAFD4 꿔 (HANGUL SYLLABLE GGWEO) 9473 0xAFDC 꿜 (HANGUL SYLLABLE GGWEOL) 9474 0xAFE8 꿨 (HANGUL SYLLABLE GGWEOSS) 9475 0xAFE9 꿩 (HANGUL SYLLABLE GGWEONG) 9476 0xAFF0 꿰 (HANGUL SYLLABLE GGWE) 9477 0xAFF1 꿱 (HANGUL SYLLABLE GGWEG) 9478 0xAFF4 꿴 (HANGUL SYLLABLE GGWEN) 9479 0xAFF8 꿸 (HANGUL SYLLABLE GGWEL) 9480 0xB000 뀀 (HANGUL SYLLABLE GGWEM) 9481 0xB001 뀁 (HANGUL SYLLABLE GGWEB) 9482 0xB004 뀄 (HANGUL SYLLABLE GGWESS) 9483 0xB00C 뀌 (HANGUL SYLLABLE GGWI) 9484 0xB010 뀐 (HANGUL SYLLABLE GGWIN) 9485 0xB014 뀔 (HANGUL SYLLABLE GGWIL) 9486 0xB01C 뀜 (HANGUL SYLLABLE GGWIM) 9487 0xB01D 뀝 (HANGUL SYLLABLE GGWIB) 9488 0xB028 뀨 (HANGUL SYLLABLE GGYU) 9489 0xB044 끄 (HANGUL SYLLABLE GGEU) 9490 0xB045 끅 (HANGUL SYLLABLE GGEUG) 9491 0xB048 끈 (HANGUL SYLLABLE GGEUN) 9492 0xB04A 끊 (HANGUL SYLLABLE GGEUNH) 9493 0xB04C 끌 (HANGUL SYLLABLE GGEUL) 9494 0xB04E 끎 (HANGUL SYLLABLE GGEULM) 9495 0xB053 끓 (HANGUL SYLLABLE GGEULH) 9496 0xB054 끔 (HANGUL SYLLABLE GGEUM) 9497 0xB055 끕 (HANGUL SYLLABLE GGEUB) 9498 0xB057 끗 (HANGUL SYLLABLE GGEUS) 9499 0xB059 끙 (HANGUL SYLLABLE GGEUNG) 9500 0xCFCC 쿌 (HANGUL SYLLABLE KYOL) 9501 0xCFCD 쿍 (HANGUL SYLLABLE KYOLG) 9502 0xCFCE 쿎 (HANGUL SYLLABLE KYOLM) 9503 0xCFCF 쿏 (HANGUL SYLLABLE KYOLB) 9504 0xCFD0 쿐 (HANGUL SYLLABLE KYOLS) 9505 0xCFD1 쿑 (HANGUL SYLLABLE KYOLT) 9506 0xCFD2 쿒 (HANGUL SYLLABLE KYOLP) 9507 0xCFD3 쿓 (HANGUL SYLLABLE KYOLH) 9508 0xCFD4 쿔 (HANGUL SYLLABLE KYOM) 9509 0xCFD5 쿕 (HANGUL SYLLABLE KYOB) 9510 0xCFD6 쿖 (HANGUL SYLLABLE KYOBS) 9511 0xCFD7 쿗 (HANGUL SYLLABLE KYOS) 9512 0xCFD8 쿘 (HANGUL SYLLABLE KYOSS) 9513 0xCFD9 쿙 (HANGUL SYLLABLE KYONG) 9514 0xCFDA 쿚 (HANGUL SYLLABLE KYOJ) 9515 0xCFDB 쿛 (HANGUL SYLLABLE KYOC) 9516 0xCFDC 쿜 (HANGUL SYLLABLE KYOK) 9517 0xCFDD 쿝 (HANGUL SYLLABLE KYOT) 9518 0xCFDE 쿞 (HANGUL SYLLABLE KYOP) 9519 0xCFDF 쿟 (HANGUL SYLLABLE KYOH) 9520 0xCFE2 쿢 (HANGUL SYLLABLE KUGG) 9521 0xCFE3 쿣 (HANGUL SYLLABLE KUGS) 9522 0xCFE5 쿥 (HANGUL SYLLABLE KUNJ) 9523 0xCFE6 쿦 (HANGUL SYLLABLE KUNH) 9524 0xCFE7 쿧 (HANGUL SYLLABLE KUD) 9525 0xCFE9 쿩 (HANGUL SYLLABLE KULG) 9532 0xCFEA 쿪 (HANGUL SYLLABLE KULM) 9533 0xCFEB 쿫 (HANGUL SYLLABLE KULB) 9534 0xCFEC 쿬 (HANGUL SYLLABLE KULS) 9535 0xCFED 쿭 (HANGUL SYLLABLE KULT) 9536 0xCFEE 쿮 (HANGUL SYLLABLE KULP) 9537 0xCFEF 쿯 (HANGUL SYLLABLE KULH) 9538 0xCFF2 쿲 (HANGUL SYLLABLE KUBS) 9539 0xCFF4 쿴 (HANGUL SYLLABLE KUSS) 9540 0xCFF6 쿶 (HANGUL SYLLABLE KUJ) 9541 0xCFF7 쿷 (HANGUL SYLLABLE KUC) 9542 0xCFF8 쿸 (HANGUL SYLLABLE KUK) 9543 0xCFF9 쿹 (HANGUL SYLLABLE KUT) 9544 0xCFFA 쿺 (HANGUL SYLLABLE KUP) 9545 0xCFFB 쿻 (HANGUL SYLLABLE KUH) 9546 0xCFFD 쿽 (HANGUL SYLLABLE KWEOG) 9547 0xCFFE 쿾 (HANGUL SYLLABLE KWEOGG) 9548 0xCFFF 쿿 (HANGUL SYLLABLE KWEOGS) 9549 0xD001 퀁 (HANGUL SYLLABLE KWEONJ) 9550 0xD002 퀂 (HANGUL SYLLABLE KWEONH) 9551 0xD003 퀃 (HANGUL SYLLABLE KWEOD) 9552 0xD005 퀅 (HANGUL SYLLABLE KWEOLG) 9553 0xD006 퀆 (HANGUL SYLLABLE KWEOLM) 9554 0xD007 퀇 (HANGUL SYLLABLE KWEOLB) 9555 0xD008 퀈 (HANGUL SYLLABLE KWEOLS) 9556 0xD009 퀉 (HANGUL SYLLABLE KWEOLT) 9557 0xD00A 퀊 (HANGUL SYLLABLE KWEOLP) 9564 0xD00B 퀋 (HANGUL SYLLABLE KWEOLH) 9565 0xD00C 퀌 (HANGUL SYLLABLE KWEOM) 9566 0xD00D 퀍 (HANGUL SYLLABLE KWEOB) 9567 0xD00E 퀎 (HANGUL SYLLABLE KWEOBS) 9568 0xD00F 퀏 (HANGUL SYLLABLE KWEOS) 9569 0xD010 퀐 (HANGUL SYLLABLE KWEOSS) 9570 0xD012 퀒 (HANGUL SYLLABLE KWEOJ) 9571 0xD013 퀓 (HANGUL SYLLABLE KWEOC) 9572 0xD014 퀔 (HANGUL SYLLABLE KWEOK) 9573 0xD015 퀕 (HANGUL SYLLABLE KWEOT) 9574 0xD016 퀖 (HANGUL SYLLABLE KWEOP) 9575 0xD017 퀗 (HANGUL SYLLABLE KWEOH) 9576 0xD019 퀙 (HANGUL SYLLABLE KWEG) 9577 0xD01A 퀚 (HANGUL SYLLABLE KWEGG) 9578 0xD01B 퀛 (HANGUL SYLLABLE KWEGS) 9579 0xD01C 퀜 (HANGUL SYLLABLE KWEN) 9580 0xD01D 퀝 (HANGUL SYLLABLE KWENJ) 9581 0xD01E 퀞 (HANGUL SYLLABLE KWENH) 9582 0xD01F 퀟 (HANGUL SYLLABLE KWED) 9583 0xD020 퀠 (HANGUL SYLLABLE KWEL) 9584 0xD021 퀡 (HANGUL SYLLABLE KWELG) 9585 0xD022 퀢 (HANGUL SYLLABLE KWELM) 9586 0xD023 퀣 (HANGUL SYLLABLE KWELB) 9587 0xD024 퀤 (HANGUL SYLLABLE KWELS) 9588 0xD025 퀥 (HANGUL SYLLABLE KWELT) 9589 0xD026 퀦 (HANGUL SYLLABLE KWELP) 9590 0xD027 퀧 (HANGUL SYLLABLE KWELH) 9591 0xD028 퀨 (HANGUL SYLLABLE KWEM) 9592 0xD029 퀩 (HANGUL SYLLABLE KWEB) 9593 0xD02A 퀪 (HANGUL SYLLABLE KWEBS) 9594 0xD02B 퀫 (HANGUL SYLLABLE KWES) 9595 0xD02C 퀬 (HANGUL SYLLABLE KWESS) 9596 0xB05D 끝 (HANGUL SYLLABLE GGEUT) 9597 0xB07C 끼 (HANGUL SYLLABLE GGI) 9598 0xB07D 끽 (HANGUL SYLLABLE GGIG) 9599 0xB080 낀 (HANGUL SYLLABLE GGIN) 9600 0xB084 낄 (HANGUL SYLLABLE GGIL) 9601 0xB08C 낌 (HANGUL SYLLABLE GGIM) 9602 0xB08D 낍 (HANGUL SYLLABLE GGIB) 9603 0xB08F 낏 (HANGUL SYLLABLE GGIS) 9604 0xB091 낑 (HANGUL SYLLABLE GGING) 9605 0xB098 나 (HANGUL SYLLABLE NA) 9606 0xB099 낙 (HANGUL SYLLABLE NAG) 9607 0xB09A 낚 (HANGUL SYLLABLE NAGG) 9608 0xB09C 난 (HANGUL SYLLABLE NAN) 9609 0xB09F 낟 (HANGUL SYLLABLE NAD) 9610 0xB0A0 날 (HANGUL SYLLABLE NAL) 9611 0xB0A1 낡 (HANGUL SYLLABLE NALG) 9612 0xB0A2 낢 (HANGUL SYLLABLE NALM) 9613 0xB0A8 남 (HANGUL SYLLABLE NAM) 9614 0xB0A9 납 (HANGUL SYLLABLE NAB) 9615 0xB0AB 낫 (HANGUL SYLLABLE NAS) 9616 0xB0AC 났 (HANGUL SYLLABLE NASS) 9617 0xB0AD 낭 (HANGUL SYLLABLE NANG) 9618 0xB0AE 낮 (HANGUL SYLLABLE NAJ) 9619 0xB0AF 낯 (HANGUL SYLLABLE NAC) 9620 0xB0B1 낱 (HANGUL SYLLABLE NAT) 9621 0xB0B3 낳 (HANGUL SYLLABLE NAH) 9622 0xB0B4 내 (HANGUL SYLLABLE NAE) 9623 0xB0B5 낵 (HANGUL SYLLABLE NAEG) 9624 0xB0B8 낸 (HANGUL SYLLABLE NAEN) 9625 0xB0BC 낼 (HANGUL SYLLABLE NAEL) 9626 0xB0C4 냄 (HANGUL SYLLABLE NAEM) 9627 0xB0C5 냅 (HANGUL SYLLABLE NAEB) 9628 0xB0C7 냇 (HANGUL SYLLABLE NAES) 9629 0xB0C8 냈 (HANGUL SYLLABLE NAESS) 9630 0xB0C9 냉 (HANGUL SYLLABLE NAENG) 9631 0xB0D0 냐 (HANGUL SYLLABLE NYA) 9632 0xB0D1 냑 (HANGUL SYLLABLE NYAG) 9633 0xB0D4 냔 (HANGUL SYLLABLE NYAN) 9634 0xB0D8 냘 (HANGUL SYLLABLE NYAL) 9635 0xB0E0 냠 (HANGUL SYLLABLE NYAM) 9636 0xB0E5 냥 (HANGUL SYLLABLE NYANG) 9637 0xB108 너 (HANGUL SYLLABLE NEO) 9638 0xB109 넉 (HANGUL SYLLABLE NEOG) 9639 0xB10B 넋 (HANGUL SYLLABLE NEOGS) 9640 0xB10C 넌 (HANGUL SYLLABLE NEON) 9641 0xB110 널 (HANGUL SYLLABLE NEOL) 9642 0xB112 넒 (HANGUL SYLLABLE NEOLM) 9643 0xB113 넓 (HANGUL SYLLABLE NEOLB) 9644 0xB118 넘 (HANGUL SYLLABLE NEOM) 9645 0xB119 넙 (HANGUL SYLLABLE NEOB) 9646 0xB11B 넛 (HANGUL SYLLABLE NEOS) 9647 0xB11C 넜 (HANGUL SYLLABLE NEOSS) 9648 0xB11D 넝 (HANGUL SYLLABLE NEONG) 9649 0xB123 넣 (HANGUL SYLLABLE NEOH) 9650 0xB124 네 (HANGUL SYLLABLE NE) 9651 0xB125 넥 (HANGUL SYLLABLE NEG) 9652 0xB128 넨 (HANGUL SYLLABLE NEN) 9653 0xB12C 넬 (HANGUL SYLLABLE NEL) 9654 0xB134 넴 (HANGUL SYLLABLE NEM) 9655 0xB135 넵 (HANGUL SYLLABLE NEB) 9656 0xB137 넷 (HANGUL SYLLABLE NES) 9657 0xB138 넸 (HANGUL SYLLABLE NESS) 9658 0xB139 넹 (HANGUL SYLLABLE NENG) 9659 0xB140 녀 (HANGUL SYLLABLE NYEO) 9660 0xB141 녁 (HANGUL SYLLABLE NYEOG) 9661 0xB144 년 (HANGUL SYLLABLE NYEON) 9662 0xB148 녈 (HANGUL SYLLABLE NYEOL) 9663 0xB150 념 (HANGUL SYLLABLE NYEOM) 9664 0xB151 녑 (HANGUL SYLLABLE NYEOB) 9665 0xB154 녔 (HANGUL SYLLABLE NYEOSS) 9666 0xB155 녕 (HANGUL SYLLABLE NYEONG) 9667 0xB158 녘 (HANGUL SYLLABLE NYEOK) 9668 0xB15C 녜 (HANGUL SYLLABLE NYE) 9669 0xB160 녠 (HANGUL SYLLABLE NYEN) 9670 0xB178 노 (HANGUL SYLLABLE NO) 9671 0xB179 녹 (HANGUL SYLLABLE NOG) 9672 0xB17C 논 (HANGUL SYLLABLE NON) 9673 0xB180 놀 (HANGUL SYLLABLE NOL) 9674 0xB182 놂 (HANGUL SYLLABLE NOLM) 9675 0xB188 놈 (HANGUL SYLLABLE NOM) 9676 0xB189 놉 (HANGUL SYLLABLE NOB) 9677 0xB18B 놋 (HANGUL SYLLABLE NOS) 9678 0xB18D 농 (HANGUL SYLLABLE NONG) 9679 0xB192 높 (HANGUL SYLLABLE NOP) 9680 0xB193 놓 (HANGUL SYLLABLE NOH) 9681 0xB194 놔 (HANGUL SYLLABLE NWA) 9682 0xB198 놘 (HANGUL SYLLABLE NWAN) 9683 0xB19C 놜 (HANGUL SYLLABLE NWAL) 9684 0xB1A8 놨 (HANGUL SYLLABLE NWASS) 9685 0xB1CC 뇌 (HANGUL SYLLABLE NOE) 9686 0xB1D0 뇐 (HANGUL SYLLABLE NOEN) 9687 0xB1D4 뇔 (HANGUL SYLLABLE NOEL) 9688 0xB1DC 뇜 (HANGUL SYLLABLE NOEM) 9689 0xB1DD 뇝 (HANGUL SYLLABLE NOEB) 9690 0xD02E 퀮 (HANGUL SYLLABLE KWEJ) 9691 0xD02F 퀯 (HANGUL SYLLABLE KWEC) 9692 0xD030 퀰 (HANGUL SYLLABLE KWEK) 9693 0xD031 퀱 (HANGUL SYLLABLE KWET) 9694 0xD032 퀲 (HANGUL SYLLABLE KWEP) 9695 0xD033 퀳 (HANGUL SYLLABLE KWEH) 9696 0xD036 퀶 (HANGUL SYLLABLE KWIGG) 9697 0xD037 퀷 (HANGUL SYLLABLE KWIGS) 9698 0xD039 퀹 (HANGUL SYLLABLE KWINJ) 9699 0xD03A 퀺 (HANGUL SYLLABLE KWINH) 9700 0xD03B 퀻 (HANGUL SYLLABLE KWID) 9701 0xD03D 퀽 (HANGUL SYLLABLE KWILG) 9702 0xD03E 퀾 (HANGUL SYLLABLE KWILM) 9703 0xD03F 퀿 (HANGUL SYLLABLE KWILB) 9704 0xD040 큀 (HANGUL SYLLABLE KWILS) 9705 0xD041 큁 (HANGUL SYLLABLE KWILT) 9706 0xD042 큂 (HANGUL SYLLABLE KWILP) 9707 0xD043 큃 (HANGUL SYLLABLE KWILH) 9708 0xD046 큆 (HANGUL SYLLABLE KWIBS) 9709 0xD048 큈 (HANGUL SYLLABLE KWISS) 9710 0xD04A 큊 (HANGUL SYLLABLE KWIJ) 9711 0xD04B 큋 (HANGUL SYLLABLE KWIC) 9712 0xD04C 큌 (HANGUL SYLLABLE KWIK) 9713 0xD04D 큍 (HANGUL SYLLABLE KWIT) 9714 0xD04E 큎 (HANGUL SYLLABLE KWIP) 9715 0xD04F 큏 (HANGUL SYLLABLE KWIH) 9722 0xD051 큑 (HANGUL SYLLABLE KYUG) 9723 0xD052 큒 (HANGUL SYLLABLE KYUGG) 9724 0xD053 큓 (HANGUL SYLLABLE KYUGS) 9725 0xD055 큕 (HANGUL SYLLABLE KYUNJ) 9726 0xD056 큖 (HANGUL SYLLABLE KYUNH) 9727 0xD057 큗 (HANGUL SYLLABLE KYUD) 9728 0xD059 큙 (HANGUL SYLLABLE KYULG) 9729 0xD05A 큚 (HANGUL SYLLABLE KYULM) 9730 0xD05B 큛 (HANGUL SYLLABLE KYULB) 9731 0xD05C 큜 (HANGUL SYLLABLE KYULS) 9732 0xD05D 큝 (HANGUL SYLLABLE KYULT) 9733 0xD05E 큞 (HANGUL SYLLABLE KYULP) 9734 0xD05F 큟 (HANGUL SYLLABLE KYULH) 9735 0xD061 큡 (HANGUL SYLLABLE KYUB) 9736 0xD062 큢 (HANGUL SYLLABLE KYUBS) 9737 0xD063 큣 (HANGUL SYLLABLE KYUS) 9738 0xD064 큤 (HANGUL SYLLABLE KYUSS) 9739 0xD065 큥 (HANGUL SYLLABLE KYUNG) 9740 0xD066 큦 (HANGUL SYLLABLE KYUJ) 9741 0xD067 큧 (HANGUL SYLLABLE KYUC) 9742 0xD068 큨 (HANGUL SYLLABLE KYUK) 9743 0xD069 큩 (HANGUL SYLLABLE KYUT) 9744 0xD06A 큪 (HANGUL SYLLABLE KYUP) 9745 0xD06B 큫 (HANGUL SYLLABLE KYUH) 9746 0xD06E 큮 (HANGUL SYLLABLE KEUGG) 9747 0xD06F 큯 (HANGUL SYLLABLE KEUGS) 9754 0xD071 큱 (HANGUL SYLLABLE KEUNJ) 9755 0xD072 큲 (HANGUL SYLLABLE KEUNH) 9756 0xD073 큳 (HANGUL SYLLABLE KEUD) 9757 0xD075 큵 (HANGUL SYLLABLE KEULG) 9758 0xD076 큶 (HANGUL SYLLABLE KEULM) 9759 0xD077 큷 (HANGUL SYLLABLE KEULB) 9760 0xD078 큸 (HANGUL SYLLABLE KEULS) 9761 0xD079 큹 (HANGUL SYLLABLE KEULT) 9762 0xD07A 큺 (HANGUL SYLLABLE KEULP) 9763 0xD07B 큻 (HANGUL SYLLABLE KEULH) 9764 0xD07E 큾 (HANGUL SYLLABLE KEUBS) 9765 0xD07F 큿 (HANGUL SYLLABLE KEUS) 9766 0xD080 킀 (HANGUL SYLLABLE KEUSS) 9767 0xD082 킂 (HANGUL SYLLABLE KEUJ) 9768 0xD083 킃 (HANGUL SYLLABLE KEUC) 9769 0xD084 킄 (HANGUL SYLLABLE KEUK) 9770 0xD085 킅 (HANGUL SYLLABLE KEUT) 9771 0xD086 킆 (HANGUL SYLLABLE KEUP) 9772 0xD087 킇 (HANGUL SYLLABLE KEUH) 9773 0xD088 킈 (HANGUL SYLLABLE KYI) 9774 0xD089 킉 (HANGUL SYLLABLE KYIG) 9775 0xD08A 킊 (HANGUL SYLLABLE KYIGG) 9776 0xD08B 킋 (HANGUL SYLLABLE KYIGS) 9777 0xD08C 킌 (HANGUL SYLLABLE KYIN) 9778 0xD08D 킍 (HANGUL SYLLABLE KYINJ) 9779 0xD08E 킎 (HANGUL SYLLABLE KYINH) 9780 0xD08F 킏 (HANGUL SYLLABLE KYID) 9781 0xD090 킐 (HANGUL SYLLABLE KYIL) 9782 0xD091 킑 (HANGUL SYLLABLE KYILG) 9783 0xD092 킒 (HANGUL SYLLABLE KYILM) 9784 0xD093 킓 (HANGUL SYLLABLE KYILB) 9785 0xD094 킔 (HANGUL SYLLABLE KYILS) 9786 0xB1DF 뇟 (HANGUL SYLLABLE NOES) 9787 0xB1E8 뇨 (HANGUL SYLLABLE NYO) 9788 0xB1E9 뇩 (HANGUL SYLLABLE NYOG) 9789 0xB1EC 뇬 (HANGUL SYLLABLE NYON) 9790 0xB1F0 뇰 (HANGUL SYLLABLE NYOL) 9791 0xB1F9 뇹 (HANGUL SYLLABLE NYOB) 9792 0xB1FB 뇻 (HANGUL SYLLABLE NYOS) 9793 0xB1FD 뇽 (HANGUL SYLLABLE NYONG) 9794 0xB204 누 (HANGUL SYLLABLE NU) 9795 0xB205 눅 (HANGUL SYLLABLE NUG) 9796 0xB208 눈 (HANGUL SYLLABLE NUN) 9797 0xB20B 눋 (HANGUL SYLLABLE NUD) 9798 0xB20C 눌 (HANGUL SYLLABLE NUL) 9799 0xB214 눔 (HANGUL SYLLABLE NUM) 9800 0xB215 눕 (HANGUL SYLLABLE NUB) 9801 0xB217 눗 (HANGUL SYLLABLE NUS) 9802 0xB219 눙 (HANGUL SYLLABLE NUNG) 9803 0xB220 눠 (HANGUL SYLLABLE NWEO) 9804 0xB234 눴 (HANGUL SYLLABLE NWEOSS) 9805 0xB23C 눼 (HANGUL SYLLABLE NWE) 9806 0xB258 뉘 (HANGUL SYLLABLE NWI) 9807 0xB25C 뉜 (HANGUL SYLLABLE NWIN) 9808 0xB260 뉠 (HANGUL SYLLABLE NWIL) 9809 0xB268 뉨 (HANGUL SYLLABLE NWIM) 9810 0xB269 뉩 (HANGUL SYLLABLE NWIB) 9811 0xB274 뉴 (HANGUL SYLLABLE NYU) 9812 0xB275 뉵 (HANGUL SYLLABLE NYUG) 9813 0xB27C 뉼 (HANGUL SYLLABLE NYUL) 9814 0xB284 늄 (HANGUL SYLLABLE NYUM) 9815 0xB285 늅 (HANGUL SYLLABLE NYUB) 9816 0xB289 늉 (HANGUL SYLLABLE NYUNG) 9817 0xB290 느 (HANGUL SYLLABLE NEU) 9818 0xB291 늑 (HANGUL SYLLABLE NEUG) 9819 0xB294 는 (HANGUL SYLLABLE NEUN) 9820 0xB298 늘 (HANGUL SYLLABLE NEUL) 9821 0xB299 늙 (HANGUL SYLLABLE NEULG) 9822 0xB29A 늚 (HANGUL SYLLABLE NEULM) 9823 0xB2A0 늠 (HANGUL SYLLABLE NEUM) 9824 0xB2A1 늡 (HANGUL SYLLABLE NEUB) 9825 0xB2A3 늣 (HANGUL SYLLABLE NEUS) 9826 0xB2A5 능 (HANGUL SYLLABLE NEUNG) 9827 0xB2A6 늦 (HANGUL SYLLABLE NEUJ) 9828 0xB2AA 늪 (HANGUL SYLLABLE NEUP) 9829 0xB2AC 늬 (HANGUL SYLLABLE NYI) 9830 0xB2B0 늰 (HANGUL SYLLABLE NYIN) 9831 0xB2B4 늴 (HANGUL SYLLABLE NYIL) 9832 0xB2C8 니 (HANGUL SYLLABLE NI) 9833 0xB2C9 닉 (HANGUL SYLLABLE NIG) 9834 0xB2CC 닌 (HANGUL SYLLABLE NIN) 9835 0xB2D0 닐 (HANGUL SYLLABLE NIL) 9836 0xB2D2 닒 (HANGUL SYLLABLE NILM) 9837 0xB2D8 님 (HANGUL SYLLABLE NIM) 9838 0xB2D9 닙 (HANGUL SYLLABLE NIB) 9839 0xB2DB 닛 (HANGUL SYLLABLE NIS) 9840 0xB2DD 닝 (HANGUL SYLLABLE NING) 9841 0xB2E2 닢 (HANGUL SYLLABLE NIP) 9842 0xB2E4 다 (HANGUL SYLLABLE DA) 9843 0xB2E5 닥 (HANGUL SYLLABLE DAG) 9844 0xB2E6 닦 (HANGUL SYLLABLE DAGG) 9845 0xB2E8 단 (HANGUL SYLLABLE DAN) 9846 0xB2EB 닫 (HANGUL SYLLABLE DAD) 9847 0xB2EC 달 (HANGUL SYLLABLE DAL) 9848 0xB2ED 닭 (HANGUL SYLLABLE DALG) 9849 0xB2EE 닮 (HANGUL SYLLABLE DALM) 9850 0xB2EF 닯 (HANGUL SYLLABLE DALB) 9851 0xB2F3 닳 (HANGUL SYLLABLE DALH) 9852 0xB2F4 담 (HANGUL SYLLABLE DAM) 9853 0xB2F5 답 (HANGUL SYLLABLE DAB) 9854 0xB2F7 닷 (HANGUL SYLLABLE DAS) 9855 0xB2F8 닸 (HANGUL SYLLABLE DASS) 9856 0xB2F9 당 (HANGUL SYLLABLE DANG) 9857 0xB2FA 닺 (HANGUL SYLLABLE DAJ) 9858 0xB2FB 닻 (HANGUL SYLLABLE DAC) 9859 0xB2FF 닿 (HANGUL SYLLABLE DAH) 9860 0xB300 대 (HANGUL SYLLABLE DAE) 9861 0xB301 댁 (HANGUL SYLLABLE DAEG) 9862 0xB304 댄 (HANGUL SYLLABLE DAEN) 9863 0xB308 댈 (HANGUL SYLLABLE DAEL) 9864 0xB310 댐 (HANGUL SYLLABLE DAEM) 9865 0xB311 댑 (HANGUL SYLLABLE DAEB) 9866 0xB313 댓 (HANGUL SYLLABLE DAES) 9867 0xB314 댔 (HANGUL SYLLABLE DAESS) 9868 0xB315 댕 (HANGUL SYLLABLE DAENG) 9869 0xB31C 댜 (HANGUL SYLLABLE DYA) 9870 0xB354 더 (HANGUL SYLLABLE DEO) 9871 0xB355 덕 (HANGUL SYLLABLE DEOG) 9872 0xB356 덖 (HANGUL SYLLABLE DEOGG) 9873 0xB358 던 (HANGUL SYLLABLE DEON) 9874 0xB35B 덛 (HANGUL SYLLABLE DEOD) 9875 0xB35C 덜 (HANGUL SYLLABLE DEOL) 9876 0xB35E 덞 (HANGUL SYLLABLE DEOLM) 9877 0xB35F 덟 (HANGUL SYLLABLE DEOLB) 9878 0xB364 덤 (HANGUL SYLLABLE DEOM) 9879 0xB365 덥 (HANGUL SYLLABLE DEOB) 9880 0xD095 킕 (HANGUL SYLLABLE KYILT) 9881 0xD096 킖 (HANGUL SYLLABLE KYILP) 9882 0xD097 킗 (HANGUL SYLLABLE KYILH) 9883 0xD098 킘 (HANGUL SYLLABLE KYIM) 9884 0xD099 킙 (HANGUL SYLLABLE KYIB) 9885 0xD09A 킚 (HANGUL SYLLABLE KYIBS) 9886 0xD09B 킛 (HANGUL SYLLABLE KYIS) 9887 0xD09C 킜 (HANGUL SYLLABLE KYISS) 9888 0xD09D 킝 (HANGUL SYLLABLE KYING) 9889 0xD09E 킞 (HANGUL SYLLABLE KYIJ) 9890 0xD09F 킟 (HANGUL SYLLABLE KYIC) 9891 0xD0A0 킠 (HANGUL SYLLABLE KYIK) 9892 0xD0A1 킡 (HANGUL SYLLABLE KYIT) 9893 0xD0A2 킢 (HANGUL SYLLABLE KYIP) 9894 0xD0A3 킣 (HANGUL SYLLABLE KYIH) 9895 0xD0A6 킦 (HANGUL SYLLABLE KIGG) 9896 0xD0A7 킧 (HANGUL SYLLABLE KIGS) 9897 0xD0A9 킩 (HANGUL SYLLABLE KINJ) 9898 0xD0AA 킪 (HANGUL SYLLABLE KINH) 9899 0xD0AB 킫 (HANGUL SYLLABLE KID) 9900 0xD0AD 킭 (HANGUL SYLLABLE KILG) 9901 0xD0AE 킮 (HANGUL SYLLABLE KILM) 9902 0xD0AF 킯 (HANGUL SYLLABLE KILB) 9903 0xD0B0 킰 (HANGUL SYLLABLE KILS) 9904 0xD0B1 킱 (HANGUL SYLLABLE KILT) 9905 0xD0B2 킲 (HANGUL SYLLABLE KILP) 9912 0xD0B3 킳 (HANGUL SYLLABLE KILH) 9913 0xD0B6 킶 (HANGUL SYLLABLE KIBS) 9914 0xD0B8 킸 (HANGUL SYLLABLE KISS) 9915 0xD0BA 킺 (HANGUL SYLLABLE KIJ) 9916 0xD0BB 킻 (HANGUL SYLLABLE KIC) 9917 0xD0BC 킼 (HANGUL SYLLABLE KIK) 9918 0xD0BD 킽 (HANGUL SYLLABLE KIT) 9919 0xD0BE 킾 (HANGUL SYLLABLE KIP) 9920 0xD0BF 킿 (HANGUL SYLLABLE KIH) 9921 0xD0C2 탂 (HANGUL SYLLABLE TAGG) 9922 0xD0C3 탃 (HANGUL SYLLABLE TAGS) 9923 0xD0C5 탅 (HANGUL SYLLABLE TANJ) 9924 0xD0C6 탆 (HANGUL SYLLABLE TANH) 9925 0xD0C7 탇 (HANGUL SYLLABLE TAD) 9926 0xD0CA 탊 (HANGUL SYLLABLE TALM) 9927 0xD0CB 탋 (HANGUL SYLLABLE TALB) 9928 0xD0CC 탌 (HANGUL SYLLABLE TALS) 9929 0xD0CD 탍 (HANGUL SYLLABLE TALT) 9930 0xD0CE 탎 (HANGUL SYLLABLE TALP) 9931 0xD0CF 탏 (HANGUL SYLLABLE TALH) 9932 0xD0D2 탒 (HANGUL SYLLABLE TABS) 9933 0xD0D6 탖 (HANGUL SYLLABLE TAJ) 9934 0xD0D7 탗 (HANGUL SYLLABLE TAC) 9935 0xD0D8 탘 (HANGUL SYLLABLE TAK) 9936 0xD0D9 탙 (HANGUL SYLLABLE TAT) 9937 0xD0DA 탚 (HANGUL SYLLABLE TAP) 9944 0xD0DB 탛 (HANGUL SYLLABLE TAH) 9945 0xD0DE 탞 (HANGUL SYLLABLE TAEGG) 9946 0xD0DF 탟 (HANGUL SYLLABLE TAEGS) 9947 0xD0E1 탡 (HANGUL SYLLABLE TAENJ) 9948 0xD0E2 탢 (HANGUL SYLLABLE TAENH) 9949 0xD0E3 탣 (HANGUL SYLLABLE TAED) 9950 0xD0E5 탥 (HANGUL SYLLABLE TAELG) 9951 0xD0E6 탦 (HANGUL SYLLABLE TAELM) 9952 0xD0E7 탧 (HANGUL SYLLABLE TAELB) 9953 0xD0E8 탨 (HANGUL SYLLABLE TAELS) 9954 0xD0E9 탩 (HANGUL SYLLABLE TAELT) 9955 0xD0EA 탪 (HANGUL SYLLABLE TAELP) 9956 0xD0EB 탫 (HANGUL SYLLABLE TAELH) 9957 0xD0EE 탮 (HANGUL SYLLABLE TAEBS) 9958 0xD0F2 탲 (HANGUL SYLLABLE TAEJ) 9959 0xD0F3 탳 (HANGUL SYLLABLE TAEC) 9960 0xD0F4 탴 (HANGUL SYLLABLE TAEK) 9961 0xD0F5 탵 (HANGUL SYLLABLE TAET) 9962 0xD0F6 탶 (HANGUL SYLLABLE TAEP) 9963 0xD0F7 탷 (HANGUL SYLLABLE TAEH) 9964 0xD0F9 탹 (HANGUL SYLLABLE TYAG) 9965 0xD0FA 탺 (HANGUL SYLLABLE TYAGG) 9966 0xD0FB 탻 (HANGUL SYLLABLE TYAGS) 9967 0xD0FC 탼 (HANGUL SYLLABLE TYAN) 9968 0xD0FD 탽 (HANGUL SYLLABLE TYANJ) 9969 0xD0FE 탾 (HANGUL SYLLABLE TYANH) 9970 0xD0FF 탿 (HANGUL SYLLABLE TYAD) 9971 0xD100 턀 (HANGUL SYLLABLE TYAL) 9972 0xD101 턁 (HANGUL SYLLABLE TYALG) 9973 0xD102 턂 (HANGUL SYLLABLE TYALM) 9974 0xD103 턃 (HANGUL SYLLABLE TYALB) 9975 0xD104 턄 (HANGUL SYLLABLE TYALS) 9976 0xB367 덧 (HANGUL SYLLABLE DEOS) 9977 0xB369 덩 (HANGUL SYLLABLE DEONG) 9978 0xB36B 덫 (HANGUL SYLLABLE DEOC) 9979 0xB36E 덮 (HANGUL SYLLABLE DEOP) 9980 0xB370 데 (HANGUL SYLLABLE DE) 9981 0xB371 덱 (HANGUL SYLLABLE DEG) 9982 0xB374 덴 (HANGUL SYLLABLE DEN) 9983 0xB378 델 (HANGUL SYLLABLE DEL) 9984 0xB380 뎀 (HANGUL SYLLABLE DEM) 9985 0xB381 뎁 (HANGUL SYLLABLE DEB) 9986 0xB383 뎃 (HANGUL SYLLABLE DES) 9987 0xB384 뎄 (HANGUL SYLLABLE DESS) 9988 0xB385 뎅 (HANGUL SYLLABLE DENG) 9989 0xB38C 뎌 (HANGUL SYLLABLE DYEO) 9990 0xB390 뎐 (HANGUL SYLLABLE DYEON) 9991 0xB394 뎔 (HANGUL SYLLABLE DYEOL) 9992 0xB3A0 뎠 (HANGUL SYLLABLE DYEOSS) 9993 0xB3A1 뎡 (HANGUL SYLLABLE DYEONG) 9994 0xB3A8 뎨 (HANGUL SYLLABLE DYE) 9995 0xB3AC 뎬 (HANGUL SYLLABLE DYEN) 9996 0xB3C4 도 (HANGUL SYLLABLE DO) 9997 0xB3C5 독 (HANGUL SYLLABLE DOG) 9998 0xB3C8 돈 (HANGUL SYLLABLE DON) 9999 0xB3CB 돋 (HANGUL SYLLABLE DOD) 10000 0xB3CC 돌 (HANGUL SYLLABLE DOL) 10001 0xB3CE 돎 (HANGUL SYLLABLE DOLM) 10002 0xB3D0 돐 (HANGUL SYLLABLE DOLS) 10003 0xB3D4 돔 (HANGUL SYLLABLE DOM) 10004 0xB3D5 돕 (HANGUL SYLLABLE DOB) 10005 0xB3D7 돗 (HANGUL SYLLABLE DOS) 10006 0xB3D9 동 (HANGUL SYLLABLE DONG) 10007 0xB3DB 돛 (HANGUL SYLLABLE DOC) 10008 0xB3DD 돝 (HANGUL SYLLABLE DOT) 10009 0xB3E0 돠 (HANGUL SYLLABLE DWA) 10010 0xB3E4 돤 (HANGUL SYLLABLE DWAN) 10011 0xB3E8 돨 (HANGUL SYLLABLE DWAL) 10012 0xB3FC 돼 (HANGUL SYLLABLE DWAE) 10013 0xB410 됐 (HANGUL SYLLABLE DWAESS) 10014 0xB418 되 (HANGUL SYLLABLE DOE) 10015 0xB41C 된 (HANGUL SYLLABLE DOEN) 10016 0xB420 될 (HANGUL SYLLABLE DOEL) 10017 0xB428 됨 (HANGUL SYLLABLE DOEM) 10018 0xB429 됩 (HANGUL SYLLABLE DOEB) 10019 0xB42B 됫 (HANGUL SYLLABLE DOES) 10020 0xB434 됴 (HANGUL SYLLABLE DYO) 10021 0xB450 두 (HANGUL SYLLABLE DU) 10022 0xB451 둑 (HANGUL SYLLABLE DUG) 10023 0xB454 둔 (HANGUL SYLLABLE DUN) 10024 0xB458 둘 (HANGUL SYLLABLE DUL) 10025 0xB460 둠 (HANGUL SYLLABLE DUM) 10026 0xB461 둡 (HANGUL SYLLABLE DUB) 10027 0xB463 둣 (HANGUL SYLLABLE DUS) 10028 0xB465 둥 (HANGUL SYLLABLE DUNG) 10029 0xB46C 둬 (HANGUL SYLLABLE DWEO) 10030 0xB480 뒀 (HANGUL SYLLABLE DWEOSS) 10031 0xB488 뒈 (HANGUL SYLLABLE DWE) 10032 0xB49D 뒝 (HANGUL SYLLABLE DWENG) 10033 0xB4A4 뒤 (HANGUL SYLLABLE DWI) 10034 0xB4A8 뒨 (HANGUL SYLLABLE DWIN) 10035 0xB4AC 뒬 (HANGUL SYLLABLE DWIL) 10036 0xB4B5 뒵 (HANGUL SYLLABLE DWIB) 10037 0xB4B7 뒷 (HANGUL SYLLABLE DWIS) 10038 0xB4B9 뒹 (HANGUL SYLLABLE DWING) 10039 0xB4C0 듀 (HANGUL SYLLABLE DYU) 10040 0xB4C4 듄 (HANGUL SYLLABLE DYUN) 10041 0xB4C8 듈 (HANGUL SYLLABLE DYUL) 10042 0xB4D0 듐 (HANGUL SYLLABLE DYUM) 10043 0xB4D5 듕 (HANGUL SYLLABLE DYUNG) 10044 0xB4DC 드 (HANGUL SYLLABLE DEU) 10045 0xB4DD 득 (HANGUL SYLLABLE DEUG) 10046 0xB4E0 든 (HANGUL SYLLABLE DEUN) 10047 0xB4E3 듣 (HANGUL SYLLABLE DEUD) 10048 0xB4E4 들 (HANGUL SYLLABLE DEUL) 10049 0xB4E6 듦 (HANGUL SYLLABLE DEULM) 10050 0xB4EC 듬 (HANGUL SYLLABLE DEUM) 10051 0xB4ED 듭 (HANGUL SYLLABLE DEUB) 10052 0xB4EF 듯 (HANGUL SYLLABLE DEUS) 10053 0xB4F1 등 (HANGUL SYLLABLE DEUNG) 10054 0xB4F8 듸 (HANGUL SYLLABLE DYI) 10055 0xB514 디 (HANGUL SYLLABLE DI) 10056 0xB515 딕 (HANGUL SYLLABLE DIG) 10057 0xB518 딘 (HANGUL SYLLABLE DIN) 10058 0xB51B 딛 (HANGUL SYLLABLE DID) 10059 0xB51C 딜 (HANGUL SYLLABLE DIL) 10060 0xB524 딤 (HANGUL SYLLABLE DIM) 10061 0xB525 딥 (HANGUL SYLLABLE DIB) 10062 0xB527 딧 (HANGUL SYLLABLE DIS) 10063 0xB528 딨 (HANGUL SYLLABLE DISS) 10064 0xB529 딩 (HANGUL SYLLABLE DING) 10065 0xB52A 딪 (HANGUL SYLLABLE DIJ) 10066 0xB530 따 (HANGUL SYLLABLE DDA) 10067 0xB531 딱 (HANGUL SYLLABLE DDAG) 10068 0xB534 딴 (HANGUL SYLLABLE DDAN) 10069 0xB538 딸 (HANGUL SYLLABLE DDAL) 10070 0xD105 턅 (HANGUL SYLLABLE TYALT) 10071 0xD106 턆 (HANGUL SYLLABLE TYALP) 10072 0xD107 턇 (HANGUL SYLLABLE TYALH) 10073 0xD108 턈 (HANGUL SYLLABLE TYAM) 10074 0xD109 턉 (HANGUL SYLLABLE TYAB) 10075 0xD10A 턊 (HANGUL SYLLABLE TYABS) 10076 0xD10B 턋 (HANGUL SYLLABLE TYAS) 10077 0xD10C 턌 (HANGUL SYLLABLE TYASS) 10078 0xD10E 턎 (HANGUL SYLLABLE TYAJ) 10079 0xD10F 턏 (HANGUL SYLLABLE TYAC) 10080 0xD110 턐 (HANGUL SYLLABLE TYAK) 10081 0xD111 턑 (HANGUL SYLLABLE TYAT) 10082 0xD112 턒 (HANGUL SYLLABLE TYAP) 10083 0xD113 턓 (HANGUL SYLLABLE TYAH) 10084 0xD114 턔 (HANGUL SYLLABLE TYAE) 10085 0xD115 턕 (HANGUL SYLLABLE TYAEG) 10086 0xD116 턖 (HANGUL SYLLABLE TYAEGG) 10087 0xD117 턗 (HANGUL SYLLABLE TYAEGS) 10088 0xD118 턘 (HANGUL SYLLABLE TYAEN) 10089 0xD119 턙 (HANGUL SYLLABLE TYAENJ) 10090 0xD11A 턚 (HANGUL SYLLABLE TYAENH) 10091 0xD11B 턛 (HANGUL SYLLABLE TYAED) 10092 0xD11C 턜 (HANGUL SYLLABLE TYAEL) 10093 0xD11D 턝 (HANGUL SYLLABLE TYAELG) 10094 0xD11E 턞 (HANGUL SYLLABLE TYAELM) 10095 0xD11F 턟 (HANGUL SYLLABLE TYAELB) 10102 0xD120 턠 (HANGUL SYLLABLE TYAELS) 10103 0xD121 턡 (HANGUL SYLLABLE TYAELT) 10104 0xD122 턢 (HANGUL SYLLABLE TYAELP) 10105 0xD123 턣 (HANGUL SYLLABLE TYAELH) 10106 0xD124 턤 (HANGUL SYLLABLE TYAEM) 10107 0xD125 턥 (HANGUL SYLLABLE TYAEB) 10108 0xD126 턦 (HANGUL SYLLABLE TYAEBS) 10109 0xD127 턧 (HANGUL SYLLABLE TYAES) 10110 0xD128 턨 (HANGUL SYLLABLE TYAESS) 10111 0xD129 턩 (HANGUL SYLLABLE TYAENG) 10112 0xD12A 턪 (HANGUL SYLLABLE TYAEJ) 10113 0xD12B 턫 (HANGUL SYLLABLE TYAEC) 10114 0xD12C 턬 (HANGUL SYLLABLE TYAEK) 10115 0xD12D 턭 (HANGUL SYLLABLE TYAET) 10116 0xD12E 턮 (HANGUL SYLLABLE TYAEP) 10117 0xD12F 턯 (HANGUL SYLLABLE TYAEH) 10118 0xD132 턲 (HANGUL SYLLABLE TEOGG) 10119 0xD133 턳 (HANGUL SYLLABLE TEOGS) 10120 0xD135 턵 (HANGUL SYLLABLE TEONJ) 10121 0xD136 턶 (HANGUL SYLLABLE TEONH) 10122 0xD137 턷 (HANGUL SYLLABLE TEOD) 10123 0xD139 턹 (HANGUL SYLLABLE TEOLG) 10124 0xD13B 턻 (HANGUL SYLLABLE TEOLB) 10125 0xD13C 턼 (HANGUL SYLLABLE TEOLS) 10126 0xD13D 턽 (HANGUL SYLLABLE TEOLT) 10127 0xD13E 턾 (HANGUL SYLLABLE TEOLP) 10134 0xD13F 턿 (HANGUL SYLLABLE TEOLH) 10135 0xD142 텂 (HANGUL SYLLABLE TEOBS) 10136 0xD146 텆 (HANGUL SYLLABLE TEOJ) 10137 0xD147 텇 (HANGUL SYLLABLE TEOC) 10138 0xD148 텈 (HANGUL SYLLABLE TEOK) 10139 0xD149 텉 (HANGUL SYLLABLE TEOT) 10140 0xD14A 텊 (HANGUL SYLLABLE TEOP) 10141 0xD14B 텋 (HANGUL SYLLABLE TEOH) 10142 0xD14E 텎 (HANGUL SYLLABLE TEGG) 10143 0xD14F 텏 (HANGUL SYLLABLE TEGS) 10144 0xD151 텑 (HANGUL SYLLABLE TENJ) 10145 0xD152 텒 (HANGUL SYLLABLE TENH) 10146 0xD153 텓 (HANGUL SYLLABLE TED) 10147 0xD155 텕 (HANGUL SYLLABLE TELG) 10148 0xD156 텖 (HANGUL SYLLABLE TELM) 10149 0xD157 텗 (HANGUL SYLLABLE TELB) 10150 0xD158 텘 (HANGUL SYLLABLE TELS) 10151 0xD159 텙 (HANGUL SYLLABLE TELT) 10152 0xD15A 텚 (HANGUL SYLLABLE TELP) 10153 0xD15B 텛 (HANGUL SYLLABLE TELH) 10154 0xD15E 텞 (HANGUL SYLLABLE TEBS) 10155 0xD160 텠 (HANGUL SYLLABLE TESS) 10156 0xD162 텢 (HANGUL SYLLABLE TEJ) 10157 0xD163 텣 (HANGUL SYLLABLE TEC) 10158 0xD164 텤 (HANGUL SYLLABLE TEK) 10159 0xD165 텥 (HANGUL SYLLABLE TET) 10160 0xD166 텦 (HANGUL SYLLABLE TEP) 10161 0xD167 텧 (HANGUL SYLLABLE TEH) 10162 0xD169 텩 (HANGUL SYLLABLE TYEOG) 10163 0xD16A 텪 (HANGUL SYLLABLE TYEOGG) 10164 0xD16B 텫 (HANGUL SYLLABLE TYEOGS) 10165 0xD16D 텭 (HANGUL SYLLABLE TYEONJ) 10166 0xB540 땀 (HANGUL SYLLABLE DDAM) 10167 0xB541 땁 (HANGUL SYLLABLE DDAB) 10168 0xB543 땃 (HANGUL SYLLABLE DDAS) 10169 0xB544 땄 (HANGUL SYLLABLE DDASS) 10170 0xB545 땅 (HANGUL SYLLABLE DDANG) 10171 0xB54B 땋 (HANGUL SYLLABLE DDAH) 10172 0xB54C 때 (HANGUL SYLLABLE DDAE) 10173 0xB54D 땍 (HANGUL SYLLABLE DDAEG) 10174 0xB550 땐 (HANGUL SYLLABLE DDAEN) 10175 0xB554 땔 (HANGUL SYLLABLE DDAEL) 10176 0xB55C 땜 (HANGUL SYLLABLE DDAEM) 10177 0xB55D 땝 (HANGUL SYLLABLE DDAEB) 10178 0xB55F 땟 (HANGUL SYLLABLE DDAES) 10179 0xB560 땠 (HANGUL SYLLABLE DDAESS) 10180 0xB561 땡 (HANGUL SYLLABLE DDAENG) 10181 0xB5A0 떠 (HANGUL SYLLABLE DDEO) 10182 0xB5A1 떡 (HANGUL SYLLABLE DDEOG) 10183 0xB5A4 떤 (HANGUL SYLLABLE DDEON) 10184 0xB5A8 떨 (HANGUL SYLLABLE DDEOL) 10185 0xB5AA 떪 (HANGUL SYLLABLE DDEOLM) 10186 0xB5AB 떫 (HANGUL SYLLABLE DDEOLB) 10187 0xB5B0 떰 (HANGUL SYLLABLE DDEOM) 10188 0xB5B1 떱 (HANGUL SYLLABLE DDEOB) 10189 0xB5B3 떳 (HANGUL SYLLABLE DDEOS) 10190 0xB5B4 떴 (HANGUL SYLLABLE DDEOSS) 10191 0xB5B5 떵 (HANGUL SYLLABLE DDEONG) 10192 0xB5BB 떻 (HANGUL SYLLABLE DDEOH) 10193 0xB5BC 떼 (HANGUL SYLLABLE DDE) 10194 0xB5BD 떽 (HANGUL SYLLABLE DDEG) 10195 0xB5C0 뗀 (HANGUL SYLLABLE DDEN) 10196 0xB5C4 뗄 (HANGUL SYLLABLE DDEL) 10197 0xB5CC 뗌 (HANGUL SYLLABLE DDEM) 10198 0xB5CD 뗍 (HANGUL SYLLABLE DDEB) 10199 0xB5CF 뗏 (HANGUL SYLLABLE DDES) 10200 0xB5D0 뗐 (HANGUL SYLLABLE DDESS) 10201 0xB5D1 뗑 (HANGUL SYLLABLE DDENG) 10202 0xB5D8 뗘 (HANGUL SYLLABLE DDYEO) 10203 0xB5EC 뗬 (HANGUL SYLLABLE DDYEOSS) 10204 0xB610 또 (HANGUL SYLLABLE DDO) 10205 0xB611 똑 (HANGUL SYLLABLE DDOG) 10206 0xB614 똔 (HANGUL SYLLABLE DDON) 10207 0xB618 똘 (HANGUL SYLLABLE DDOL) 10208 0xB625 똥 (HANGUL SYLLABLE DDONG) 10209 0xB62C 똬 (HANGUL SYLLABLE DDWA) 10210 0xB634 똴 (HANGUL SYLLABLE DDWAL) 10211 0xB648 뙈 (HANGUL SYLLABLE DDWAE) 10212 0xB664 뙤 (HANGUL SYLLABLE DDOE) 10213 0xB668 뙨 (HANGUL SYLLABLE DDOEN) 10214 0xB69C 뚜 (HANGUL SYLLABLE DDU) 10215 0xB69D 뚝 (HANGUL SYLLABLE DDUG) 10216 0xB6A0 뚠 (HANGUL SYLLABLE DDUN) 10217 0xB6A4 뚤 (HANGUL SYLLABLE DDUL) 10218 0xB6AB 뚫 (HANGUL SYLLABLE DDULH) 10219 0xB6AC 뚬 (HANGUL SYLLABLE DDUM) 10220 0xB6B1 뚱 (HANGUL SYLLABLE DDUNG) 10221 0xB6D4 뛔 (HANGUL SYLLABLE DDWE) 10222 0xB6F0 뛰 (HANGUL SYLLABLE DDWI) 10223 0xB6F4 뛴 (HANGUL SYLLABLE DDWIN) 10224 0xB6F8 뛸 (HANGUL SYLLABLE DDWIL) 10225 0xB700 뜀 (HANGUL SYLLABLE DDWIM) 10226 0xB701 뜁 (HANGUL SYLLABLE DDWIB) 10227 0xB705 뜅 (HANGUL SYLLABLE DDWING) 10228 0xB728 뜨 (HANGUL SYLLABLE DDEU) 10229 0xB729 뜩 (HANGUL SYLLABLE DDEUG) 10230 0xB72C 뜬 (HANGUL SYLLABLE DDEUN) 10231 0xB72F 뜯 (HANGUL SYLLABLE DDEUD) 10232 0xB730 뜰 (HANGUL SYLLABLE DDEUL) 10233 0xB738 뜸 (HANGUL SYLLABLE DDEUM) 10234 0xB739 뜹 (HANGUL SYLLABLE DDEUB) 10235 0xB73B 뜻 (HANGUL SYLLABLE DDEUS) 10236 0xB744 띄 (HANGUL SYLLABLE DDYI) 10237 0xB748 띈 (HANGUL SYLLABLE DDYIN) 10238 0xB74C 띌 (HANGUL SYLLABLE DDYIL) 10239 0xB754 띔 (HANGUL SYLLABLE DDYIM) 10240 0xB755 띕 (HANGUL SYLLABLE DDYIB) 10241 0xB760 띠 (HANGUL SYLLABLE DDI) 10242 0xB764 띤 (HANGUL SYLLABLE DDIN) 10243 0xB768 띨 (HANGUL SYLLABLE DDIL) 10244 0xB770 띰 (HANGUL SYLLABLE DDIM) 10245 0xB771 띱 (HANGUL SYLLABLE DDIB) 10246 0xB773 띳 (HANGUL SYLLABLE DDIS) 10247 0xB775 띵 (HANGUL SYLLABLE DDING) 10248 0xB77C 라 (HANGUL SYLLABLE RA) 10249 0xB77D 락 (HANGUL SYLLABLE RAG) 10250 0xB780 란 (HANGUL SYLLABLE RAN) 10251 0xB784 랄 (HANGUL SYLLABLE RAL) 10252 0xB78C 람 (HANGUL SYLLABLE RAM) 10253 0xB78D 랍 (HANGUL SYLLABLE RAB) 10254 0xB78F 랏 (HANGUL SYLLABLE RAS) 10255 0xB790 랐 (HANGUL SYLLABLE RASS) 10256 0xB791 랑 (HANGUL SYLLABLE RANG) 10257 0xB792 랒 (HANGUL SYLLABLE RAJ) 10258 0xB796 랖 (HANGUL SYLLABLE RAP) 10259 0xB797 랗 (HANGUL SYLLABLE RAH) 10260 0xD16E 텮 (HANGUL SYLLABLE TYEONH) 10261 0xD16F 텯 (HANGUL SYLLABLE TYEOD) 10262 0xD170 텰 (HANGUL SYLLABLE TYEOL) 10263 0xD171 텱 (HANGUL SYLLABLE TYEOLG) 10264 0xD172 텲 (HANGUL SYLLABLE TYEOLM) 10265 0xD173 텳 (HANGUL SYLLABLE TYEOLB) 10266 0xD174 텴 (HANGUL SYLLABLE TYEOLS) 10267 0xD175 텵 (HANGUL SYLLABLE TYEOLT) 10268 0xD176 텶 (HANGUL SYLLABLE TYEOLP) 10269 0xD177 텷 (HANGUL SYLLABLE TYEOLH) 10270 0xD178 텸 (HANGUL SYLLABLE TYEOM) 10271 0xD179 텹 (HANGUL SYLLABLE TYEOB) 10272 0xD17A 텺 (HANGUL SYLLABLE TYEOBS) 10273 0xD17B 텻 (HANGUL SYLLABLE TYEOS) 10274 0xD17D 텽 (HANGUL SYLLABLE TYEONG) 10275 0xD17E 텾 (HANGUL SYLLABLE TYEOJ) 10276 0xD17F 텿 (HANGUL SYLLABLE TYEOC) 10277 0xD180 톀 (HANGUL SYLLABLE TYEOK) 10278 0xD181 톁 (HANGUL SYLLABLE TYEOT) 10279 0xD182 톂 (HANGUL SYLLABLE TYEOP) 10280 0xD183 톃 (HANGUL SYLLABLE TYEOH) 10281 0xD185 톅 (HANGUL SYLLABLE TYEG) 10282 0xD186 톆 (HANGUL SYLLABLE TYEGG) 10283 0xD187 톇 (HANGUL SYLLABLE TYEGS) 10284 0xD189 톉 (HANGUL SYLLABLE TYENJ) 10285 0xD18A 톊 (HANGUL SYLLABLE TYENH) 10292 0xD18B 톋 (HANGUL SYLLABLE TYED) 10293 0xD18C 톌 (HANGUL SYLLABLE TYEL) 10294 0xD18D 톍 (HANGUL SYLLABLE TYELG) 10295 0xD18E 톎 (HANGUL SYLLABLE TYELM) 10296 0xD18F 톏 (HANGUL SYLLABLE TYELB) 10297 0xD190 톐 (HANGUL SYLLABLE TYELS) 10298 0xD191 톑 (HANGUL SYLLABLE TYELT) 10299 0xD192 톒 (HANGUL SYLLABLE TYELP) 10300 0xD193 톓 (HANGUL SYLLABLE TYELH) 10301 0xD194 톔 (HANGUL SYLLABLE TYEM) 10302 0xD195 톕 (HANGUL SYLLABLE TYEB) 10303 0xD196 톖 (HANGUL SYLLABLE TYEBS) 10304 0xD197 톗 (HANGUL SYLLABLE TYES) 10305 0xD198 톘 (HANGUL SYLLABLE TYESS) 10306 0xD199 톙 (HANGUL SYLLABLE TYENG) 10307 0xD19A 톚 (HANGUL SYLLABLE TYEJ) 10308 0xD19B 톛 (HANGUL SYLLABLE TYEC) 10309 0xD19C 톜 (HANGUL SYLLABLE TYEK) 10310 0xD19D 톝 (HANGUL SYLLABLE TYET) 10311 0xD19E 톞 (HANGUL SYLLABLE TYEP) 10312 0xD19F 톟 (HANGUL SYLLABLE TYEH) 10313 0xD1A2 톢 (HANGUL SYLLABLE TOGG) 10314 0xD1A3 톣 (HANGUL SYLLABLE TOGS) 10315 0xD1A5 톥 (HANGUL SYLLABLE TONJ) 10316 0xD1A6 톦 (HANGUL SYLLABLE TONH) 10317 0xD1A7 톧 (HANGUL SYLLABLE TOD) 10324 0xD1A9 톩 (HANGUL SYLLABLE TOLG) 10325 0xD1AA 톪 (HANGUL SYLLABLE TOLM) 10326 0xD1AB 톫 (HANGUL SYLLABLE TOLB) 10327 0xD1AC 톬 (HANGUL SYLLABLE TOLS) 10328 0xD1AD 톭 (HANGUL SYLLABLE TOLT) 10329 0xD1AE 톮 (HANGUL SYLLABLE TOLP) 10330 0xD1AF 톯 (HANGUL SYLLABLE TOLH) 10331 0xD1B2 톲 (HANGUL SYLLABLE TOBS) 10332 0xD1B4 톴 (HANGUL SYLLABLE TOSS) 10333 0xD1B6 톶 (HANGUL SYLLABLE TOJ) 10334 0xD1B7 톷 (HANGUL SYLLABLE TOC) 10335 0xD1B8 톸 (HANGUL SYLLABLE TOK) 10336 0xD1B9 톹 (HANGUL SYLLABLE TOT) 10337 0xD1BB 톻 (HANGUL SYLLABLE TOH) 10338 0xD1BD 톽 (HANGUL SYLLABLE TWAG) 10339 0xD1BE 톾 (HANGUL SYLLABLE TWAGG) 10340 0xD1BF 톿 (HANGUL SYLLABLE TWAGS) 10341 0xD1C1 퇁 (HANGUL SYLLABLE TWANJ) 10342 0xD1C2 퇂 (HANGUL SYLLABLE TWANH) 10343 0xD1C3 퇃 (HANGUL SYLLABLE TWAD) 10344 0xD1C4 퇄 (HANGUL SYLLABLE TWAL) 10345 0xD1C5 퇅 (HANGUL SYLLABLE TWALG) 10346 0xD1C6 퇆 (HANGUL SYLLABLE TWALM) 10347 0xD1C7 퇇 (HANGUL SYLLABLE TWALB) 10348 0xD1C8 퇈 (HANGUL SYLLABLE TWALS) 10349 0xD1C9 퇉 (HANGUL SYLLABLE TWALT) 10350 0xD1CA 퇊 (HANGUL SYLLABLE TWALP) 10351 0xD1CB 퇋 (HANGUL SYLLABLE TWALH) 10352 0xD1CC 퇌 (HANGUL SYLLABLE TWAM) 10353 0xD1CD 퇍 (HANGUL SYLLABLE TWAB) 10354 0xD1CE 퇎 (HANGUL SYLLABLE TWABS) 10355 0xD1CF 퇏 (HANGUL SYLLABLE TWAS) 10356 0xB798 래 (HANGUL SYLLABLE RAE) 10357 0xB799 랙 (HANGUL SYLLABLE RAEG) 10358 0xB79C 랜 (HANGUL SYLLABLE RAEN) 10359 0xB7A0 랠 (HANGUL SYLLABLE RAEL) 10360 0xB7A8 램 (HANGUL SYLLABLE RAEM) 10361 0xB7A9 랩 (HANGUL SYLLABLE RAEB) 10362 0xB7AB 랫 (HANGUL SYLLABLE RAES) 10363 0xB7AC 랬 (HANGUL SYLLABLE RAESS) 10364 0xB7AD 랭 (HANGUL SYLLABLE RAENG) 10365 0xB7B4 랴 (HANGUL SYLLABLE RYA) 10366 0xB7B5 략 (HANGUL SYLLABLE RYAG) 10367 0xB7B8 랸 (HANGUL SYLLABLE RYAN) 10368 0xB7C7 럇 (HANGUL SYLLABLE RYAS) 10369 0xB7C9 량 (HANGUL SYLLABLE RYANG) 10370 0xB7EC 러 (HANGUL SYLLABLE REO) 10371 0xB7ED 럭 (HANGUL SYLLABLE REOG) 10372 0xB7F0 런 (HANGUL SYLLABLE REON) 10373 0xB7F4 럴 (HANGUL SYLLABLE REOL) 10374 0xB7FC 럼 (HANGUL SYLLABLE REOM) 10375 0xB7FD 럽 (HANGUL SYLLABLE REOB) 10376 0xB7FF 럿 (HANGUL SYLLABLE REOS) 10377 0xB800 렀 (HANGUL SYLLABLE REOSS) 10378 0xB801 렁 (HANGUL SYLLABLE REONG) 10379 0xB807 렇 (HANGUL SYLLABLE REOH) 10380 0xB808 레 (HANGUL SYLLABLE RE) 10381 0xB809 렉 (HANGUL SYLLABLE REG) 10382 0xB80C 렌 (HANGUL SYLLABLE REN) 10383 0xB810 렐 (HANGUL SYLLABLE REL) 10384 0xB818 렘 (HANGUL SYLLABLE REM) 10385 0xB819 렙 (HANGUL SYLLABLE REB) 10386 0xB81B 렛 (HANGUL SYLLABLE RES) 10387 0xB81D 렝 (HANGUL SYLLABLE RENG) 10388 0xB824 려 (HANGUL SYLLABLE RYEO) 10389 0xB825 력 (HANGUL SYLLABLE RYEOG) 10390 0xB828 련 (HANGUL SYLLABLE RYEON) 10391 0xB82C 렬 (HANGUL SYLLABLE RYEOL) 10392 0xB834 렴 (HANGUL SYLLABLE RYEOM) 10393 0xB835 렵 (HANGUL SYLLABLE RYEOB) 10394 0xB837 렷 (HANGUL SYLLABLE RYEOS) 10395 0xB838 렸 (HANGUL SYLLABLE RYEOSS) 10396 0xB839 령 (HANGUL SYLLABLE RYEONG) 10397 0xB840 례 (HANGUL SYLLABLE RYE) 10398 0xB844 롄 (HANGUL SYLLABLE RYEN) 10399 0xB851 롑 (HANGUL SYLLABLE RYEB) 10400 0xB853 롓 (HANGUL SYLLABLE RYES) 10401 0xB85C 로 (HANGUL SYLLABLE RO) 10402 0xB85D 록 (HANGUL SYLLABLE ROG) 10403 0xB860 론 (HANGUL SYLLABLE RON) 10404 0xB864 롤 (HANGUL SYLLABLE ROL) 10405 0xB86C 롬 (HANGUL SYLLABLE ROM) 10406 0xB86D 롭 (HANGUL SYLLABLE ROB) 10407 0xB86F 롯 (HANGUL SYLLABLE ROS) 10408 0xB871 롱 (HANGUL SYLLABLE RONG) 10409 0xB878 롸 (HANGUL SYLLABLE RWA) 10410 0xB87C 롼 (HANGUL SYLLABLE RWAN) 10411 0xB88D 뢍 (HANGUL SYLLABLE RWANG) 10412 0xB8A8 뢨 (HANGUL SYLLABLE RWAESS) 10413 0xB8B0 뢰 (HANGUL SYLLABLE ROE) 10414 0xB8B4 뢴 (HANGUL SYLLABLE ROEN) 10415 0xB8B8 뢸 (HANGUL SYLLABLE ROEL) 10416 0xB8C0 룀 (HANGUL SYLLABLE ROEM) 10417 0xB8C1 룁 (HANGUL SYLLABLE ROEB) 10418 0xB8C3 룃 (HANGUL SYLLABLE ROES) 10419 0xB8C5 룅 (HANGUL SYLLABLE ROENG) 10420 0xB8CC 료 (HANGUL SYLLABLE RYO) 10421 0xB8D0 룐 (HANGUL SYLLABLE RYON) 10422 0xB8D4 룔 (HANGUL SYLLABLE RYOL) 10423 0xB8DD 룝 (HANGUL SYLLABLE RYOB) 10424 0xB8DF 룟 (HANGUL SYLLABLE RYOS) 10425 0xB8E1 룡 (HANGUL SYLLABLE RYONG) 10426 0xB8E8 루 (HANGUL SYLLABLE RU) 10427 0xB8E9 룩 (HANGUL SYLLABLE RUG) 10428 0xB8EC 룬 (HANGUL SYLLABLE RUN) 10429 0xB8F0 룰 (HANGUL SYLLABLE RUL) 10430 0xB8F8 룸 (HANGUL SYLLABLE RUM) 10431 0xB8F9 룹 (HANGUL SYLLABLE RUB) 10432 0xB8FB 룻 (HANGUL SYLLABLE RUS) 10433 0xB8FD 룽 (HANGUL SYLLABLE RUNG) 10434 0xB904 뤄 (HANGUL SYLLABLE RWEO) 10435 0xB918 뤘 (HANGUL SYLLABLE RWEOSS) 10436 0xB920 뤠 (HANGUL SYLLABLE RWE) 10437 0xB93C 뤼 (HANGUL SYLLABLE RWI) 10438 0xB93D 뤽 (HANGUL SYLLABLE RWIG) 10439 0xB940 륀 (HANGUL SYLLABLE RWIN) 10440 0xB944 륄 (HANGUL SYLLABLE RWIL) 10441 0xB94C 륌 (HANGUL SYLLABLE RWIM) 10442 0xB94F 륏 (HANGUL SYLLABLE RWIS) 10443 0xB951 륑 (HANGUL SYLLABLE RWING) 10444 0xB958 류 (HANGUL SYLLABLE RYU) 10445 0xB959 륙 (HANGUL SYLLABLE RYUG) 10446 0xB95C 륜 (HANGUL SYLLABLE RYUN) 10447 0xB960 률 (HANGUL SYLLABLE RYUL) 10448 0xB968 륨 (HANGUL SYLLABLE RYUM) 10449 0xB969 륩 (HANGUL SYLLABLE RYUB) 10450 0xD1D0 퇐 (HANGUL SYLLABLE TWASS) 10451 0xD1D1 퇑 (HANGUL SYLLABLE TWANG) 10452 0xD1D2 퇒 (HANGUL SYLLABLE TWAJ) 10453 0xD1D3 퇓 (HANGUL SYLLABLE TWAC) 10454 0xD1D4 퇔 (HANGUL SYLLABLE TWAK) 10455 0xD1D5 퇕 (HANGUL SYLLABLE TWAT) 10456 0xD1D6 퇖 (HANGUL SYLLABLE TWAP) 10457 0xD1D7 퇗 (HANGUL SYLLABLE TWAH) 10458 0xD1D9 퇙 (HANGUL SYLLABLE TWAEG) 10459 0xD1DA 퇚 (HANGUL SYLLABLE TWAEGG) 10460 0xD1DB 퇛 (HANGUL SYLLABLE TWAEGS) 10461 0xD1DC 퇜 (HANGUL SYLLABLE TWAEN) 10462 0xD1DD 퇝 (HANGUL SYLLABLE TWAENJ) 10463 0xD1DE 퇞 (HANGUL SYLLABLE TWAENH) 10464 0xD1DF 퇟 (HANGUL SYLLABLE TWAED) 10465 0xD1E0 퇠 (HANGUL SYLLABLE TWAEL) 10466 0xD1E1 퇡 (HANGUL SYLLABLE TWAELG) 10467 0xD1E2 퇢 (HANGUL SYLLABLE TWAELM) 10468 0xD1E3 퇣 (HANGUL SYLLABLE TWAELB) 10469 0xD1E4 퇤 (HANGUL SYLLABLE TWAELS) 10470 0xD1E5 퇥 (HANGUL SYLLABLE TWAELT) 10471 0xD1E6 퇦 (HANGUL SYLLABLE TWAELP) 10472 0xD1E7 퇧 (HANGUL SYLLABLE TWAELH) 10473 0xD1E8 퇨 (HANGUL SYLLABLE TWAEM) 10474 0xD1E9 퇩 (HANGUL SYLLABLE TWAEB) 10475 0xD1EA 퇪 (HANGUL SYLLABLE TWAEBS) 10482 0xD1EB 퇫 (HANGUL SYLLABLE TWAES) 10483 0xD1EC 퇬 (HANGUL SYLLABLE TWAESS) 10484 0xD1ED 퇭 (HANGUL SYLLABLE TWAENG) 10485 0xD1EE 퇮 (HANGUL SYLLABLE TWAEJ) 10486 0xD1EF 퇯 (HANGUL SYLLABLE TWAEC) 10487 0xD1F0 퇰 (HANGUL SYLLABLE TWAEK) 10488 0xD1F1 퇱 (HANGUL SYLLABLE TWAET) 10489 0xD1F2 퇲 (HANGUL SYLLABLE TWAEP) 10490 0xD1F3 퇳 (HANGUL SYLLABLE TWAEH) 10491 0xD1F5 퇵 (HANGUL SYLLABLE TOEG) 10492 0xD1F6 퇶 (HANGUL SYLLABLE TOEGG) 10493 0xD1F7 퇷 (HANGUL SYLLABLE TOEGS) 10494 0xD1F9 퇹 (HANGUL SYLLABLE TOENJ) 10495 0xD1FA 퇺 (HANGUL SYLLABLE TOENH) 10496 0xD1FB 퇻 (HANGUL SYLLABLE TOED) 10497 0xD1FC 퇼 (HANGUL SYLLABLE TOEL) 10498 0xD1FD 퇽 (HANGUL SYLLABLE TOELG) 10499 0xD1FE 퇾 (HANGUL SYLLABLE TOELM) 10500 0xD1FF 퇿 (HANGUL SYLLABLE TOELB) 10501 0xD200 툀 (HANGUL SYLLABLE TOELS) 10502 0xD201 툁 (HANGUL SYLLABLE TOELT) 10503 0xD202 툂 (HANGUL SYLLABLE TOELP) 10504 0xD203 툃 (HANGUL SYLLABLE TOELH) 10505 0xD204 툄 (HANGUL SYLLABLE TOEM) 10506 0xD205 툅 (HANGUL SYLLABLE TOEB) 10507 0xD206 툆 (HANGUL SYLLABLE TOEBS) 10514 0xD208 툈 (HANGUL SYLLABLE TOESS) 10515 0xD20A 툊 (HANGUL SYLLABLE TOEJ) 10516 0xD20B 툋 (HANGUL SYLLABLE TOEC) 10517 0xD20C 툌 (HANGUL SYLLABLE TOEK) 10518 0xD20D 툍 (HANGUL SYLLABLE TOET) 10519 0xD20E 툎 (HANGUL SYLLABLE TOEP) 10520 0xD20F 툏 (HANGUL SYLLABLE TOEH) 10521 0xD211 툑 (HANGUL SYLLABLE TYOG) 10522 0xD212 툒 (HANGUL SYLLABLE TYOGG) 10523 0xD213 툓 (HANGUL SYLLABLE TYOGS) 10524 0xD214 툔 (HANGUL SYLLABLE TYON) 10525 0xD215 툕 (HANGUL SYLLABLE TYONJ) 10526 0xD216 툖 (HANGUL SYLLABLE TYONH) 10527 0xD217 툗 (HANGUL SYLLABLE TYOD) 10528 0xD218 툘 (HANGUL SYLLABLE TYOL) 10529 0xD219 툙 (HANGUL SYLLABLE TYOLG) 10530 0xD21A 툚 (HANGUL SYLLABLE TYOLM) 10531 0xD21B 툛 (HANGUL SYLLABLE TYOLB) 10532 0xD21C 툜 (HANGUL SYLLABLE TYOLS) 10533 0xD21D 툝 (HANGUL SYLLABLE TYOLT) 10534 0xD21E 툞 (HANGUL SYLLABLE TYOLP) 10535 0xD21F 툟 (HANGUL SYLLABLE TYOLH) 10536 0xD220 툠 (HANGUL SYLLABLE TYOM) 10537 0xD221 툡 (HANGUL SYLLABLE TYOB) 10538 0xD222 툢 (HANGUL SYLLABLE TYOBS) 10539 0xD223 툣 (HANGUL SYLLABLE TYOS) 10540 0xD224 툤 (HANGUL SYLLABLE TYOSS) 10541 0xD225 툥 (HANGUL SYLLABLE TYONG) 10542 0xD226 툦 (HANGUL SYLLABLE TYOJ) 10543 0xD227 툧 (HANGUL SYLLABLE TYOC) 10544 0xD228 툨 (HANGUL SYLLABLE TYOK) 10545 0xD229 툩 (HANGUL SYLLABLE TYOT) 10546 0xB96B 륫 (HANGUL SYLLABLE RYUS) 10547 0xB96D 륭 (HANGUL SYLLABLE RYUNG) 10548 0xB974 르 (HANGUL SYLLABLE REU) 10549 0xB975 륵 (HANGUL SYLLABLE REUG) 10550 0xB978 른 (HANGUL SYLLABLE REUN) 10551 0xB97C 를 (HANGUL SYLLABLE REUL) 10552 0xB984 름 (HANGUL SYLLABLE REUM) 10553 0xB985 릅 (HANGUL SYLLABLE REUB) 10554 0xB987 릇 (HANGUL SYLLABLE REUS) 10555 0xB989 릉 (HANGUL SYLLABLE REUNG) 10556 0xB98A 릊 (HANGUL SYLLABLE REUJ) 10557 0xB98D 릍 (HANGUL SYLLABLE REUT) 10558 0xB98E 릎 (HANGUL SYLLABLE REUP) 10559 0xB9AC 리 (HANGUL SYLLABLE RI) 10560 0xB9AD 릭 (HANGUL SYLLABLE RIG) 10561 0xB9B0 린 (HANGUL SYLLABLE RIN) 10562 0xB9B4 릴 (HANGUL SYLLABLE RIL) 10563 0xB9BC 림 (HANGUL SYLLABLE RIM) 10564 0xB9BD 립 (HANGUL SYLLABLE RIB) 10565 0xB9BF 릿 (HANGUL SYLLABLE RIS) 10566 0xB9C1 링 (HANGUL SYLLABLE RING) 10567 0xB9C8 마 (HANGUL SYLLABLE MA) 10568 0xB9C9 막 (HANGUL SYLLABLE MAG) 10569 0xB9CC 만 (HANGUL SYLLABLE MAN) 10570 0xB9CE 많 (HANGUL SYLLABLE MANH) 10571 0xB9CF 맏 (HANGUL SYLLABLE MAD) 10572 0xB9D0 말 (HANGUL SYLLABLE MAL) 10573 0xB9D1 맑 (HANGUL SYLLABLE MALG) 10574 0xB9D2 맒 (HANGUL SYLLABLE MALM) 10575 0xB9D8 맘 (HANGUL SYLLABLE MAM) 10576 0xB9D9 맙 (HANGUL SYLLABLE MAB) 10577 0xB9DB 맛 (HANGUL SYLLABLE MAS) 10578 0xB9DD 망 (HANGUL SYLLABLE MANG) 10579 0xB9DE 맞 (HANGUL SYLLABLE MAJ) 10580 0xB9E1 맡 (HANGUL SYLLABLE MAT) 10581 0xB9E3 맣 (HANGUL SYLLABLE MAH) 10582 0xB9E4 매 (HANGUL SYLLABLE MAE) 10583 0xB9E5 맥 (HANGUL SYLLABLE MAEG) 10584 0xB9E8 맨 (HANGUL SYLLABLE MAEN) 10585 0xB9EC 맬 (HANGUL SYLLABLE MAEL) 10586 0xB9F4 맴 (HANGUL SYLLABLE MAEM) 10587 0xB9F5 맵 (HANGUL SYLLABLE MAEB) 10588 0xB9F7 맷 (HANGUL SYLLABLE MAES) 10589 0xB9F8 맸 (HANGUL SYLLABLE MAESS) 10590 0xB9F9 맹 (HANGUL SYLLABLE MAENG) 10591 0xB9FA 맺 (HANGUL SYLLABLE MAEJ) 10592 0xBA00 먀 (HANGUL SYLLABLE MYA) 10593 0xBA01 먁 (HANGUL SYLLABLE MYAG) 10594 0xBA08 먈 (HANGUL SYLLABLE MYAL) 10595 0xBA15 먕 (HANGUL SYLLABLE MYANG) 10596 0xBA38 머 (HANGUL SYLLABLE MEO) 10597 0xBA39 먹 (HANGUL SYLLABLE MEOG) 10598 0xBA3C 먼 (HANGUL SYLLABLE MEON) 10599 0xBA40 멀 (HANGUL SYLLABLE MEOL) 10600 0xBA42 멂 (HANGUL SYLLABLE MEOLM) 10601 0xBA48 멈 (HANGUL SYLLABLE MEOM) 10602 0xBA49 멉 (HANGUL SYLLABLE MEOB) 10603 0xBA4B 멋 (HANGUL SYLLABLE MEOS) 10604 0xBA4D 멍 (HANGUL SYLLABLE MEONG) 10605 0xBA4E 멎 (HANGUL SYLLABLE MEOJ) 10606 0xBA53 멓 (HANGUL SYLLABLE MEOH) 10607 0xBA54 메 (HANGUL SYLLABLE ME) 10608 0xBA55 멕 (HANGUL SYLLABLE MEG) 10609 0xBA58 멘 (HANGUL SYLLABLE MEN) 10610 0xBA5C 멜 (HANGUL SYLLABLE MEL) 10611 0xBA64 멤 (HANGUL SYLLABLE MEM) 10612 0xBA65 멥 (HANGUL SYLLABLE MEB) 10613 0xBA67 멧 (HANGUL SYLLABLE MES) 10614 0xBA68 멨 (HANGUL SYLLABLE MESS) 10615 0xBA69 멩 (HANGUL SYLLABLE MENG) 10616 0xBA70 며 (HANGUL SYLLABLE MYEO) 10617 0xBA71 멱 (HANGUL SYLLABLE MYEOG) 10618 0xBA74 면 (HANGUL SYLLABLE MYEON) 10619 0xBA78 멸 (HANGUL SYLLABLE MYEOL) 10620 0xBA83 몃 (HANGUL SYLLABLE MYEOS) 10621 0xBA84 몄 (HANGUL SYLLABLE MYEOSS) 10622 0xBA85 명 (HANGUL SYLLABLE MYEONG) 10623 0xBA87 몇 (HANGUL SYLLABLE MYEOC) 10624 0xBA8C 몌 (HANGUL SYLLABLE MYE) 10625 0xBAA8 모 (HANGUL SYLLABLE MO) 10626 0xBAA9 목 (HANGUL SYLLABLE MOG) 10627 0xBAAB 몫 (HANGUL SYLLABLE MOGS) 10628 0xBAAC 몬 (HANGUL SYLLABLE MON) 10629 0xBAB0 몰 (HANGUL SYLLABLE MOL) 10630 0xBAB2 몲 (HANGUL SYLLABLE MOLM) 10631 0xBAB8 몸 (HANGUL SYLLABLE MOM) 10632 0xBAB9 몹 (HANGUL SYLLABLE MOB) 10633 0xBABB 못 (HANGUL SYLLABLE MOS) 10634 0xBABD 몽 (HANGUL SYLLABLE MONG) 10635 0xBAC4 뫄 (HANGUL SYLLABLE MWA) 10636 0xBAC8 뫈 (HANGUL SYLLABLE MWAN) 10637 0xBAD8 뫘 (HANGUL SYLLABLE MWASS) 10638 0xBAD9 뫙 (HANGUL SYLLABLE MWANG) 10639 0xBAFC 뫼 (HANGUL SYLLABLE MOE) 10640 0xD22A 툪 (HANGUL SYLLABLE TYOP) 10641 0xD22B 툫 (HANGUL SYLLABLE TYOH) 10642 0xD22E 툮 (HANGUL SYLLABLE TUGG) 10643 0xD22F 툯 (HANGUL SYLLABLE TUGS) 10644 0xD231 툱 (HANGUL SYLLABLE TUNJ) 10645 0xD232 툲 (HANGUL SYLLABLE TUNH) 10646 0xD233 툳 (HANGUL SYLLABLE TUD) 10647 0xD235 툵 (HANGUL SYLLABLE TULG) 10648 0xD236 툶 (HANGUL SYLLABLE TULM) 10649 0xD237 툷 (HANGUL SYLLABLE TULB) 10650 0xD238 툸 (HANGUL SYLLABLE TULS) 10651 0xD239 툹 (HANGUL SYLLABLE TULT) 10652 0xD23A 툺 (HANGUL SYLLABLE TULP) 10653 0xD23B 툻 (HANGUL SYLLABLE TULH) 10654 0xD23E 툾 (HANGUL SYLLABLE TUBS) 10655 0xD240 퉀 (HANGUL SYLLABLE TUSS) 10656 0xD242 퉂 (HANGUL SYLLABLE TUJ) 10657 0xD243 퉃 (HANGUL SYLLABLE TUC) 10658 0xD244 퉄 (HANGUL SYLLABLE TUK) 10659 0xD245 퉅 (HANGUL SYLLABLE TUT) 10660 0xD246 퉆 (HANGUL SYLLABLE TUP) 10661 0xD247 퉇 (HANGUL SYLLABLE TUH) 10662 0xD249 퉉 (HANGUL SYLLABLE TWEOG) 10663 0xD24A 퉊 (HANGUL SYLLABLE TWEOGG) 10664 0xD24B 퉋 (HANGUL SYLLABLE TWEOGS) 10665 0xD24C 퉌 (HANGUL SYLLABLE TWEON) 10672 0xD24D 퉍 (HANGUL SYLLABLE TWEONJ) 10673 0xD24E 퉎 (HANGUL SYLLABLE TWEONH) 10674 0xD24F 퉏 (HANGUL SYLLABLE TWEOD) 10675 0xD250 퉐 (HANGUL SYLLABLE TWEOL) 10676 0xD251 퉑 (HANGUL SYLLABLE TWEOLG) 10677 0xD252 퉒 (HANGUL SYLLABLE TWEOLM) 10678 0xD253 퉓 (HANGUL SYLLABLE TWEOLB) 10679 0xD254 퉔 (HANGUL SYLLABLE TWEOLS) 10680 0xD255 퉕 (HANGUL SYLLABLE TWEOLT) 10681 0xD256 퉖 (HANGUL SYLLABLE TWEOLP) 10682 0xD257 퉗 (HANGUL SYLLABLE TWEOLH) 10683 0xD258 퉘 (HANGUL SYLLABLE TWEOM) 10684 0xD259 퉙 (HANGUL SYLLABLE TWEOB) 10685 0xD25A 퉚 (HANGUL SYLLABLE TWEOBS) 10686 0xD25B 퉛 (HANGUL SYLLABLE TWEOS) 10687 0xD25D 퉝 (HANGUL SYLLABLE TWEONG) 10688 0xD25E 퉞 (HANGUL SYLLABLE TWEOJ) 10689 0xD25F 퉟 (HANGUL SYLLABLE TWEOC) 10690 0xD260 퉠 (HANGUL SYLLABLE TWEOK) 10691 0xD261 퉡 (HANGUL SYLLABLE TWEOT) 10692 0xD262 퉢 (HANGUL SYLLABLE TWEOP) 10693 0xD263 퉣 (HANGUL SYLLABLE TWEOH) 10694 0xD265 퉥 (HANGUL SYLLABLE TWEG) 10695 0xD266 퉦 (HANGUL SYLLABLE TWEGG) 10696 0xD267 퉧 (HANGUL SYLLABLE TWEGS) 10697 0xD268 퉨 (HANGUL SYLLABLE TWEN) 10704 0xD269 퉩 (HANGUL SYLLABLE TWENJ) 10705 0xD26A 퉪 (HANGUL SYLLABLE TWENH) 10706 0xD26B 퉫 (HANGUL SYLLABLE TWED) 10707 0xD26C 퉬 (HANGUL SYLLABLE TWEL) 10708 0xD26D 퉭 (HANGUL SYLLABLE TWELG) 10709 0xD26E 퉮 (HANGUL SYLLABLE TWELM) 10710 0xD26F 퉯 (HANGUL SYLLABLE TWELB) 10711 0xD270 퉰 (HANGUL SYLLABLE TWELS) 10712 0xD271 퉱 (HANGUL SYLLABLE TWELT) 10713 0xD272 퉲 (HANGUL SYLLABLE TWELP) 10714 0xD273 퉳 (HANGUL SYLLABLE TWELH) 10715 0xD274 퉴 (HANGUL SYLLABLE TWEM) 10716 0xD275 퉵 (HANGUL SYLLABLE TWEB) 10717 0xD276 퉶 (HANGUL SYLLABLE TWEBS) 10718 0xD277 퉷 (HANGUL SYLLABLE TWES) 10719 0xD278 퉸 (HANGUL SYLLABLE TWESS) 10720 0xD279 퉹 (HANGUL SYLLABLE TWENG) 10721 0xD27A 퉺 (HANGUL SYLLABLE TWEJ) 10722 0xD27B 퉻 (HANGUL SYLLABLE TWEC) 10723 0xD27C 퉼 (HANGUL SYLLABLE TWEK) 10724 0xD27D 퉽 (HANGUL SYLLABLE TWET) 10725 0xD27E 퉾 (HANGUL SYLLABLE TWEP) 10726 0xD27F 퉿 (HANGUL SYLLABLE TWEH) 10727 0xD282 튂 (HANGUL SYLLABLE TWIGG) 10728 0xD283 튃 (HANGUL SYLLABLE TWIGS) 10729 0xD285 튅 (HANGUL SYLLABLE TWINJ) 10730 0xD286 튆 (HANGUL SYLLABLE TWINH) 10731 0xD287 튇 (HANGUL SYLLABLE TWID) 10732 0xD289 튉 (HANGUL SYLLABLE TWILG) 10733 0xD28A 튊 (HANGUL SYLLABLE TWILM) 10734 0xD28B 튋 (HANGUL SYLLABLE TWILB) 10735 0xD28C 튌 (HANGUL SYLLABLE TWILS) 10736 0xBB00 묀 (HANGUL SYLLABLE MOEN) 10737 0xBB04 묄 (HANGUL SYLLABLE MOEL) 10738 0xBB0D 묍 (HANGUL SYLLABLE MOEB) 10739 0xBB0F 묏 (HANGUL SYLLABLE MOES) 10740 0xBB11 묑 (HANGUL SYLLABLE MOENG) 10741 0xBB18 묘 (HANGUL SYLLABLE MYO) 10742 0xBB1C 묜 (HANGUL SYLLABLE MYON) 10743 0xBB20 묠 (HANGUL SYLLABLE MYOL) 10744 0xBB29 묩 (HANGUL SYLLABLE MYOB) 10745 0xBB2B 묫 (HANGUL SYLLABLE MYOS) 10746 0xBB34 무 (HANGUL SYLLABLE MU) 10747 0xBB35 묵 (HANGUL SYLLABLE MUG) 10748 0xBB36 묶 (HANGUL SYLLABLE MUGG) 10749 0xBB38 문 (HANGUL SYLLABLE MUN) 10750 0xBB3B 묻 (HANGUL SYLLABLE MUD) 10751 0xBB3C 물 (HANGUL SYLLABLE MUL) 10752 0xBB3D 묽 (HANGUL SYLLABLE MULG) 10753 0xBB3E 묾 (HANGUL SYLLABLE MULM) 10754 0xBB44 뭄 (HANGUL SYLLABLE MUM) 10755 0xBB45 뭅 (HANGUL SYLLABLE MUB) 10756 0xBB47 뭇 (HANGUL SYLLABLE MUS) 10757 0xBB49 뭉 (HANGUL SYLLABLE MUNG) 10758 0xBB4D 뭍 (HANGUL SYLLABLE MUT) 10759 0xBB4F 뭏 (HANGUL SYLLABLE MUH) 10760 0xBB50 뭐 (HANGUL SYLLABLE MWEO) 10761 0xBB54 뭔 (HANGUL SYLLABLE MWEON) 10762 0xBB58 뭘 (HANGUL SYLLABLE MWEOL) 10763 0xBB61 뭡 (HANGUL SYLLABLE MWEOB) 10764 0xBB63 뭣 (HANGUL SYLLABLE MWEOS) 10765 0xBB6C 뭬 (HANGUL SYLLABLE MWE) 10766 0xBB88 뮈 (HANGUL SYLLABLE MWI) 10767 0xBB8C 뮌 (HANGUL SYLLABLE MWIN) 10768 0xBB90 뮐 (HANGUL SYLLABLE MWIL) 10769 0xBBA4 뮤 (HANGUL SYLLABLE MYU) 10770 0xBBA8 뮨 (HANGUL SYLLABLE MYUN) 10771 0xBBAC 뮬 (HANGUL SYLLABLE MYUL) 10772 0xBBB4 뮴 (HANGUL SYLLABLE MYUM) 10773 0xBBB7 뮷 (HANGUL SYLLABLE MYUS) 10774 0xBBC0 므 (HANGUL SYLLABLE MEU) 10775 0xBBC4 믄 (HANGUL SYLLABLE MEUN) 10776 0xBBC8 믈 (HANGUL SYLLABLE MEUL) 10777 0xBBD0 믐 (HANGUL SYLLABLE MEUM) 10778 0xBBD3 믓 (HANGUL SYLLABLE MEUS) 10779 0xBBF8 미 (HANGUL SYLLABLE MI) 10780 0xBBF9 믹 (HANGUL SYLLABLE MIG) 10781 0xBBFC 민 (HANGUL SYLLABLE MIN) 10782 0xBBFF 믿 (HANGUL SYLLABLE MID) 10783 0xBC00 밀 (HANGUL SYLLABLE MIL) 10784 0xBC02 밂 (HANGUL SYLLABLE MILM) 10785 0xBC08 밈 (HANGUL SYLLABLE MIM) 10786 0xBC09 밉 (HANGUL SYLLABLE MIB) 10787 0xBC0B 밋 (HANGUL SYLLABLE MIS) 10788 0xBC0C 밌 (HANGUL SYLLABLE MISS) 10789 0xBC0D 밍 (HANGUL SYLLABLE MING) 10790 0xBC0F 및 (HANGUL SYLLABLE MIC) 10791 0xBC11 밑 (HANGUL SYLLABLE MIT) 10792 0xBC14 바 (HANGUL SYLLABLE BA) 10793 0xBC15 박 (HANGUL SYLLABLE BAG) 10794 0xBC16 밖 (HANGUL SYLLABLE BAGG) 10795 0xBC17 밗 (HANGUL SYLLABLE BAGS) 10796 0xBC18 반 (HANGUL SYLLABLE BAN) 10797 0xBC1B 받 (HANGUL SYLLABLE BAD) 10798 0xBC1C 발 (HANGUL SYLLABLE BAL) 10799 0xBC1D 밝 (HANGUL SYLLABLE BALG) 10800 0xBC1E 밞 (HANGUL SYLLABLE BALM) 10801 0xBC1F 밟 (HANGUL SYLLABLE BALB) 10802 0xBC24 밤 (HANGUL SYLLABLE BAM) 10803 0xBC25 밥 (HANGUL SYLLABLE BAB) 10804 0xBC27 밧 (HANGUL SYLLABLE BAS) 10805 0xBC29 방 (HANGUL SYLLABLE BANG) 10806 0xBC2D 밭 (HANGUL SYLLABLE BAT) 10807 0xBC30 배 (HANGUL SYLLABLE BAE) 10808 0xBC31 백 (HANGUL SYLLABLE BAEG) 10809 0xBC34 밴 (HANGUL SYLLABLE BAEN) 10810 0xBC38 밸 (HANGUL SYLLABLE BAEL) 10811 0xBC40 뱀 (HANGUL SYLLABLE BAEM) 10812 0xBC41 뱁 (HANGUL SYLLABLE BAEB) 10813 0xBC43 뱃 (HANGUL SYLLABLE BAES) 10814 0xBC44 뱄 (HANGUL SYLLABLE BAESS) 10815 0xBC45 뱅 (HANGUL SYLLABLE BAENG) 10816 0xBC49 뱉 (HANGUL SYLLABLE BAET) 10817 0xBC4C 뱌 (HANGUL SYLLABLE BYA) 10818 0xBC4D 뱍 (HANGUL SYLLABLE BYAG) 10819 0xBC50 뱐 (HANGUL SYLLABLE BYAN) 10820 0xBC5D 뱝 (HANGUL SYLLABLE BYAB) 10821 0xBC84 버 (HANGUL SYLLABLE BEO) 10822 0xBC85 벅 (HANGUL SYLLABLE BEOG) 10823 0xBC88 번 (HANGUL SYLLABLE BEON) 10824 0xBC8B 벋 (HANGUL SYLLABLE BEOD) 10825 0xBC8C 벌 (HANGUL SYLLABLE BEOL) 10826 0xBC8E 벎 (HANGUL SYLLABLE BEOLM) 10827 0xBC94 범 (HANGUL SYLLABLE BEOM) 10828 0xBC95 법 (HANGUL SYLLABLE BEOB) 10829 0xBC97 벗 (HANGUL SYLLABLE BEOS) 10830 0xD28D 튍 (HANGUL SYLLABLE TWILT) 10831 0xD28E 튎 (HANGUL SYLLABLE TWILP) 10832 0xD28F 튏 (HANGUL SYLLABLE TWILH) 10833 0xD292 튒 (HANGUL SYLLABLE TWIBS) 10834 0xD293 튓 (HANGUL SYLLABLE TWIS) 10835 0xD294 튔 (HANGUL SYLLABLE TWISS) 10836 0xD296 튖 (HANGUL SYLLABLE TWIJ) 10837 0xD297 튗 (HANGUL SYLLABLE TWIC) 10838 0xD298 튘 (HANGUL SYLLABLE TWIK) 10839 0xD299 튙 (HANGUL SYLLABLE TWIT) 10840 0xD29A 튚 (HANGUL SYLLABLE TWIP) 10841 0xD29B 튛 (HANGUL SYLLABLE TWIH) 10842 0xD29D 튝 (HANGUL SYLLABLE TYUG) 10843 0xD29E 튞 (HANGUL SYLLABLE TYUGG) 10844 0xD29F 튟 (HANGUL SYLLABLE TYUGS) 10845 0xD2A1 튡 (HANGUL SYLLABLE TYUNJ) 10846 0xD2A2 튢 (HANGUL SYLLABLE TYUNH) 10847 0xD2A3 튣 (HANGUL SYLLABLE TYUD) 10848 0xD2A5 튥 (HANGUL SYLLABLE TYULG) 10849 0xD2A6 튦 (HANGUL SYLLABLE TYULM) 10850 0xD2A7 튧 (HANGUL SYLLABLE TYULB) 10851 0xD2A8 튨 (HANGUL SYLLABLE TYULS) 10852 0xD2A9 튩 (HANGUL SYLLABLE TYULT) 10853 0xD2AA 튪 (HANGUL SYLLABLE TYULP) 10854 0xD2AB 튫 (HANGUL SYLLABLE TYULH) 10855 0xD2AD 튭 (HANGUL SYLLABLE TYUB) 10862 0xD2AE 튮 (HANGUL SYLLABLE TYUBS) 10863 0xD2AF 튯 (HANGUL SYLLABLE TYUS) 10864 0xD2B0 튰 (HANGUL SYLLABLE TYUSS) 10865 0xD2B2 튲 (HANGUL SYLLABLE TYUJ) 10866 0xD2B3 튳 (HANGUL SYLLABLE TYUC) 10867 0xD2B4 튴 (HANGUL SYLLABLE TYUK) 10868 0xD2B5 튵 (HANGUL SYLLABLE TYUT) 10869 0xD2B6 튶 (HANGUL SYLLABLE TYUP) 10870 0xD2B7 튷 (HANGUL SYLLABLE TYUH) 10871 0xD2BA 튺 (HANGUL SYLLABLE TEUGG) 10872 0xD2BB 튻 (HANGUL SYLLABLE TEUGS) 10873 0xD2BD 튽 (HANGUL SYLLABLE TEUNJ) 10874 0xD2BE 튾 (HANGUL SYLLABLE TEUNH) 10875 0xD2C1 틁 (HANGUL SYLLABLE TEULG) 10876 0xD2C3 틃 (HANGUL SYLLABLE TEULB) 10877 0xD2C4 틄 (HANGUL SYLLABLE TEULS) 10878 0xD2C5 틅 (HANGUL SYLLABLE TEULT) 10879 0xD2C6 틆 (HANGUL SYLLABLE TEULP) 10880 0xD2C7 틇 (HANGUL SYLLABLE TEULH) 10881 0xD2CA 틊 (HANGUL SYLLABLE TEUBS) 10882 0xD2CC 틌 (HANGUL SYLLABLE TEUSS) 10883 0xD2CD 틍 (HANGUL SYLLABLE TEUNG) 10884 0xD2CE 틎 (HANGUL SYLLABLE TEUJ) 10885 0xD2CF 틏 (HANGUL SYLLABLE TEUC) 10886 0xD2D0 틐 (HANGUL SYLLABLE TEUK) 10887 0xD2D1 틑 (HANGUL SYLLABLE TEUT) 10894 0xD2D2 틒 (HANGUL SYLLABLE TEUP) 10895 0xD2D3 틓 (HANGUL SYLLABLE TEUH) 10896 0xD2D5 틕 (HANGUL SYLLABLE TYIG) 10897 0xD2D6 틖 (HANGUL SYLLABLE TYIGG) 10898 0xD2D7 틗 (HANGUL SYLLABLE TYIGS) 10899 0xD2D9 틙 (HANGUL SYLLABLE TYINJ) 10900 0xD2DA 틚 (HANGUL SYLLABLE TYINH) 10901 0xD2DB 틛 (HANGUL SYLLABLE TYID) 10902 0xD2DD 틝 (HANGUL SYLLABLE TYILG) 10903 0xD2DE 틞 (HANGUL SYLLABLE TYILM) 10904 0xD2DF 틟 (HANGUL SYLLABLE TYILB) 10905 0xD2E0 틠 (HANGUL SYLLABLE TYILS) 10906 0xD2E1 틡 (HANGUL SYLLABLE TYILT) 10907 0xD2E2 틢 (HANGUL SYLLABLE TYILP) 10908 0xD2E3 틣 (HANGUL SYLLABLE TYILH) 10909 0xD2E6 틦 (HANGUL SYLLABLE TYIBS) 10910 0xD2E7 틧 (HANGUL SYLLABLE TYIS) 10911 0xD2E8 틨 (HANGUL SYLLABLE TYISS) 10912 0xD2E9 틩 (HANGUL SYLLABLE TYING) 10913 0xD2EA 틪 (HANGUL SYLLABLE TYIJ) 10914 0xD2EB 틫 (HANGUL SYLLABLE TYIC) 10915 0xD2EC 틬 (HANGUL SYLLABLE TYIK) 10916 0xD2ED 틭 (HANGUL SYLLABLE TYIT) 10917 0xD2EE 틮 (HANGUL SYLLABLE TYIP) 10918 0xD2EF 틯 (HANGUL SYLLABLE TYIH) 10919 0xD2F2 틲 (HANGUL SYLLABLE TIGG) 10920 0xD2F3 틳 (HANGUL SYLLABLE TIGS) 10921 0xD2F5 틵 (HANGUL SYLLABLE TINJ) 10922 0xD2F6 틶 (HANGUL SYLLABLE TINH) 10923 0xD2F7 틷 (HANGUL SYLLABLE TID) 10924 0xD2F9 틹 (HANGUL SYLLABLE TILG) 10925 0xD2FA 틺 (HANGUL SYLLABLE TILM) 10926 0xBC99 벙 (HANGUL SYLLABLE BEONG) 10927 0xBC9A 벚 (HANGUL SYLLABLE BEOJ) 10928 0xBCA0 베 (HANGUL SYLLABLE BE) 10929 0xBCA1 벡 (HANGUL SYLLABLE BEG) 10930 0xBCA4 벤 (HANGUL SYLLABLE BEN) 10931 0xBCA7 벧 (HANGUL SYLLABLE BED) 10932 0xBCA8 벨 (HANGUL SYLLABLE BEL) 10933 0xBCB0 벰 (HANGUL SYLLABLE BEM) 10934 0xBCB1 벱 (HANGUL SYLLABLE BEB) 10935 0xBCB3 벳 (HANGUL SYLLABLE BES) 10936 0xBCB4 벴 (HANGUL SYLLABLE BESS) 10937 0xBCB5 벵 (HANGUL SYLLABLE BENG) 10938 0xBCBC 벼 (HANGUL SYLLABLE BYEO) 10939 0xBCBD 벽 (HANGUL SYLLABLE BYEOG) 10940 0xBCC0 변 (HANGUL SYLLABLE BYEON) 10941 0xBCC4 별 (HANGUL SYLLABLE BYEOL) 10942 0xBCCD 볍 (HANGUL SYLLABLE BYEOB) 10943 0xBCCF 볏 (HANGUL SYLLABLE BYEOS) 10944 0xBCD0 볐 (HANGUL SYLLABLE BYEOSS) 10945 0xBCD1 병 (HANGUL SYLLABLE BYEONG) 10946 0xBCD5 볕 (HANGUL SYLLABLE BYEOT) 10947 0xBCD8 볘 (HANGUL SYLLABLE BYE) 10948 0xBCDC 볜 (HANGUL SYLLABLE BYEN) 10949 0xBCF4 보 (HANGUL SYLLABLE BO) 10950 0xBCF5 복 (HANGUL SYLLABLE BOG) 10951 0xBCF6 볶 (HANGUL SYLLABLE BOGG) 10952 0xBCF8 본 (HANGUL SYLLABLE BON) 10953 0xBCFC 볼 (HANGUL SYLLABLE BOL) 10954 0xBD04 봄 (HANGUL SYLLABLE BOM) 10955 0xBD05 봅 (HANGUL SYLLABLE BOB) 10956 0xBD07 봇 (HANGUL SYLLABLE BOS) 10957 0xBD09 봉 (HANGUL SYLLABLE BONG) 10958 0xBD10 봐 (HANGUL SYLLABLE BWA) 10959 0xBD14 봔 (HANGUL SYLLABLE BWAN) 10960 0xBD24 봤 (HANGUL SYLLABLE BWASS) 10961 0xBD2C 봬 (HANGUL SYLLABLE BWAE) 10962 0xBD40 뵀 (HANGUL SYLLABLE BWAESS) 10963 0xBD48 뵈 (HANGUL SYLLABLE BOE) 10964 0xBD49 뵉 (HANGUL SYLLABLE BOEG) 10965 0xBD4C 뵌 (HANGUL SYLLABLE BOEN) 10966 0xBD50 뵐 (HANGUL SYLLABLE BOEL) 10967 0xBD58 뵘 (HANGUL SYLLABLE BOEM) 10968 0xBD59 뵙 (HANGUL SYLLABLE BOEB) 10969 0xBD64 뵤 (HANGUL SYLLABLE BYO) 10970 0xBD68 뵨 (HANGUL SYLLABLE BYON) 10971 0xBD80 부 (HANGUL SYLLABLE BU) 10972 0xBD81 북 (HANGUL SYLLABLE BUG) 10973 0xBD84 분 (HANGUL SYLLABLE BUN) 10974 0xBD87 붇 (HANGUL SYLLABLE BUD) 10975 0xBD88 불 (HANGUL SYLLABLE BUL) 10976 0xBD89 붉 (HANGUL SYLLABLE BULG) 10977 0xBD8A 붊 (HANGUL SYLLABLE BULM) 10978 0xBD90 붐 (HANGUL SYLLABLE BUM) 10979 0xBD91 붑 (HANGUL SYLLABLE BUB) 10980 0xBD93 붓 (HANGUL SYLLABLE BUS) 10981 0xBD95 붕 (HANGUL SYLLABLE BUNG) 10982 0xBD99 붙 (HANGUL SYLLABLE BUT) 10983 0xBD9A 붚 (HANGUL SYLLABLE BUP) 10984 0xBD9C 붜 (HANGUL SYLLABLE BWEO) 10985 0xBDA4 붤 (HANGUL SYLLABLE BWEOL) 10986 0xBDB0 붰 (HANGUL SYLLABLE BWEOSS) 10987 0xBDB8 붸 (HANGUL SYLLABLE BWE) 10988 0xBDD4 뷔 (HANGUL SYLLABLE BWI) 10989 0xBDD5 뷕 (HANGUL SYLLABLE BWIG) 10990 0xBDD8 뷘 (HANGUL SYLLABLE BWIN) 10991 0xBDDC 뷜 (HANGUL SYLLABLE BWIL) 10992 0xBDE9 뷩 (HANGUL SYLLABLE BWING) 10993 0xBDF0 뷰 (HANGUL SYLLABLE BYU) 10994 0xBDF4 뷴 (HANGUL SYLLABLE BYUN) 10995 0xBDF8 뷸 (HANGUL SYLLABLE BYUL) 10996 0xBE00 븀 (HANGUL SYLLABLE BYUM) 10997 0xBE03 븃 (HANGUL SYLLABLE BYUS) 10998 0xBE05 븅 (HANGUL SYLLABLE BYUNG) 10999 0xBE0C 브 (HANGUL SYLLABLE BEU) 11000 0xBE0D 븍 (HANGUL SYLLABLE BEUG) 11001 0xBE10 븐 (HANGUL SYLLABLE BEUN) 11002 0xBE14 블 (HANGUL SYLLABLE BEUL) 11003 0xBE1C 븜 (HANGUL SYLLABLE BEUM) 11004 0xBE1D 븝 (HANGUL SYLLABLE BEUB) 11005 0xBE1F 븟 (HANGUL SYLLABLE BEUS) 11006 0xBE44 비 (HANGUL SYLLABLE BI) 11007 0xBE45 빅 (HANGUL SYLLABLE BIG) 11008 0xBE48 빈 (HANGUL SYLLABLE BIN) 11009 0xBE4C 빌 (HANGUL SYLLABLE BIL) 11010 0xBE4E 빎 (HANGUL SYLLABLE BILM) 11011 0xBE54 빔 (HANGUL SYLLABLE BIM) 11012 0xBE55 빕 (HANGUL SYLLABLE BIB) 11013 0xBE57 빗 (HANGUL SYLLABLE BIS) 11014 0xBE59 빙 (HANGUL SYLLABLE BING) 11015 0xBE5A 빚 (HANGUL SYLLABLE BIJ) 11016 0xBE5B 빛 (HANGUL SYLLABLE BIC) 11017 0xBE60 빠 (HANGUL SYLLABLE BBA) 11018 0xBE61 빡 (HANGUL SYLLABLE BBAG) 11019 0xBE64 빤 (HANGUL SYLLABLE BBAN) 11020 0xD2FB 틻 (HANGUL SYLLABLE TILB) 11021 0xD2FC 틼 (HANGUL SYLLABLE TILS) 11022 0xD2FD 틽 (HANGUL SYLLABLE TILT) 11023 0xD2FE 틾 (HANGUL SYLLABLE TILP) 11024 0xD2FF 틿 (HANGUL SYLLABLE TILH) 11025 0xD302 팂 (HANGUL SYLLABLE TIBS) 11026 0xD304 팄 (HANGUL SYLLABLE TISS) 11027 0xD306 팆 (HANGUL SYLLABLE TIJ) 11028 0xD307 팇 (HANGUL SYLLABLE TIC) 11029 0xD308 팈 (HANGUL SYLLABLE TIK) 11030 0xD309 팉 (HANGUL SYLLABLE TIT) 11031 0xD30A 팊 (HANGUL SYLLABLE TIP) 11032 0xD30B 팋 (HANGUL SYLLABLE TIH) 11033 0xD30F 팏 (HANGUL SYLLABLE PAGS) 11034 0xD311 팑 (HANGUL SYLLABLE PANJ) 11035 0xD312 팒 (HANGUL SYLLABLE PANH) 11036 0xD313 팓 (HANGUL SYLLABLE PAD) 11037 0xD315 팕 (HANGUL SYLLABLE PALG) 11038 0xD317 팗 (HANGUL SYLLABLE PALB) 11039 0xD318 팘 (HANGUL SYLLABLE PALS) 11040 0xD319 팙 (HANGUL SYLLABLE PALT) 11041 0xD31A 팚 (HANGUL SYLLABLE PALP) 11042 0xD31B 팛 (HANGUL SYLLABLE PALH) 11043 0xD31E 팞 (HANGUL SYLLABLE PABS) 11044 0xD322 팢 (HANGUL SYLLABLE PAJ) 11045 0xD323 팣 (HANGUL SYLLABLE PAC) 11052 0xD324 팤 (HANGUL SYLLABLE PAK) 11053 0xD326 팦 (HANGUL SYLLABLE PAP) 11054 0xD327 팧 (HANGUL SYLLABLE PAH) 11055 0xD32A 팪 (HANGUL SYLLABLE PAEGG) 11056 0xD32B 팫 (HANGUL SYLLABLE PAEGS) 11057 0xD32D 팭 (HANGUL SYLLABLE PAENJ) 11058 0xD32E 팮 (HANGUL SYLLABLE PAENH) 11059 0xD32F 팯 (HANGUL SYLLABLE PAED) 11060 0xD331 팱 (HANGUL SYLLABLE PAELG) 11061 0xD332 팲 (HANGUL SYLLABLE PAELM) 11062 0xD333 팳 (HANGUL SYLLABLE PAELB) 11063 0xD334 팴 (HANGUL SYLLABLE PAELS) 11064 0xD335 팵 (HANGUL SYLLABLE PAELT) 11065 0xD336 팶 (HANGUL SYLLABLE PAELP) 11066 0xD337 팷 (HANGUL SYLLABLE PAELH) 11067 0xD33A 팺 (HANGUL SYLLABLE PAEBS) 11068 0xD33E 팾 (HANGUL SYLLABLE PAEJ) 11069 0xD33F 팿 (HANGUL SYLLABLE PAEC) 11070 0xD340 퍀 (HANGUL SYLLABLE PAEK) 11071 0xD341 퍁 (HANGUL SYLLABLE PAET) 11072 0xD342 퍂 (HANGUL SYLLABLE PAEP) 11073 0xD343 퍃 (HANGUL SYLLABLE PAEH) 11074 0xD346 퍆 (HANGUL SYLLABLE PYAGG) 11075 0xD347 퍇 (HANGUL SYLLABLE PYAGS) 11076 0xD348 퍈 (HANGUL SYLLABLE PYAN) 11077 0xD349 퍉 (HANGUL SYLLABLE PYANJ) 11084 0xD34A 퍊 (HANGUL SYLLABLE PYANH) 11085 0xD34B 퍋 (HANGUL SYLLABLE PYAD) 11086 0xD34C 퍌 (HANGUL SYLLABLE PYAL) 11087 0xD34D 퍍 (HANGUL SYLLABLE PYALG) 11088 0xD34E 퍎 (HANGUL SYLLABLE PYALM) 11089 0xD34F 퍏 (HANGUL SYLLABLE PYALB) 11090 0xD350 퍐 (HANGUL SYLLABLE PYALS) 11091 0xD351 퍑 (HANGUL SYLLABLE PYALT) 11092 0xD352 퍒 (HANGUL SYLLABLE PYALP) 11093 0xD353 퍓 (HANGUL SYLLABLE PYALH) 11094 0xD354 퍔 (HANGUL SYLLABLE PYAM) 11095 0xD355 퍕 (HANGUL SYLLABLE PYAB) 11096 0xD356 퍖 (HANGUL SYLLABLE PYABS) 11097 0xD357 퍗 (HANGUL SYLLABLE PYAS) 11098 0xD358 퍘 (HANGUL SYLLABLE PYASS) 11099 0xD359 퍙 (HANGUL SYLLABLE PYANG) 11100 0xD35A 퍚 (HANGUL SYLLABLE PYAJ) 11101 0xD35B 퍛 (HANGUL SYLLABLE PYAC) 11102 0xD35C 퍜 (HANGUL SYLLABLE PYAK) 11103 0xD35D 퍝 (HANGUL SYLLABLE PYAT) 11104 0xD35E 퍞 (HANGUL SYLLABLE PYAP) 11105 0xD35F 퍟 (HANGUL SYLLABLE PYAH) 11106 0xD360 퍠 (HANGUL SYLLABLE PYAE) 11107 0xD361 퍡 (HANGUL SYLLABLE PYAEG) 11108 0xD362 퍢 (HANGUL SYLLABLE PYAEGG) 11109 0xD363 퍣 (HANGUL SYLLABLE PYAEGS) 11110 0xD364 퍤 (HANGUL SYLLABLE PYAEN) 11111 0xD365 퍥 (HANGUL SYLLABLE PYAENJ) 11112 0xD366 퍦 (HANGUL SYLLABLE PYAENH) 11113 0xD367 퍧 (HANGUL SYLLABLE PYAED) 11114 0xD368 퍨 (HANGUL SYLLABLE PYAEL) 11115 0xD369 퍩 (HANGUL SYLLABLE PYAELG) 11116 0xBE68 빨 (HANGUL SYLLABLE BBAL) 11117 0xBE6A 빪 (HANGUL SYLLABLE BBALM) 11118 0xBE70 빰 (HANGUL SYLLABLE BBAM) 11119 0xBE71 빱 (HANGUL SYLLABLE BBAB) 11120 0xBE73 빳 (HANGUL SYLLABLE BBAS) 11121 0xBE74 빴 (HANGUL SYLLABLE BBASS) 11122 0xBE75 빵 (HANGUL SYLLABLE BBANG) 11123 0xBE7B 빻 (HANGUL SYLLABLE BBAH) 11124 0xBE7C 빼 (HANGUL SYLLABLE BBAE) 11125 0xBE7D 빽 (HANGUL SYLLABLE BBAEG) 11126 0xBE80 뺀 (HANGUL SYLLABLE BBAEN) 11127 0xBE84 뺄 (HANGUL SYLLABLE BBAEL) 11128 0xBE8C 뺌 (HANGUL SYLLABLE BBAEM) 11129 0xBE8D 뺍 (HANGUL SYLLABLE BBAEB) 11130 0xBE8F 뺏 (HANGUL SYLLABLE BBAES) 11131 0xBE90 뺐 (HANGUL SYLLABLE BBAESS) 11132 0xBE91 뺑 (HANGUL SYLLABLE BBAENG) 11133 0xBE98 뺘 (HANGUL SYLLABLE BBYA) 11134 0xBE99 뺙 (HANGUL SYLLABLE BBYAG) 11135 0xBEA8 뺨 (HANGUL SYLLABLE BBYAM) 11136 0xBED0 뻐 (HANGUL SYLLABLE BBEO) 11137 0xBED1 뻑 (HANGUL SYLLABLE BBEOG) 11138 0xBED4 뻔 (HANGUL SYLLABLE BBEON) 11139 0xBED7 뻗 (HANGUL SYLLABLE BBEOD) 11140 0xBED8 뻘 (HANGUL SYLLABLE BBEOL) 11141 0xBEE0 뻠 (HANGUL SYLLABLE BBEOM) 11142 0xBEE3 뻣 (HANGUL SYLLABLE BBEOS) 11143 0xBEE4 뻤 (HANGUL SYLLABLE BBEOSS) 11144 0xBEE5 뻥 (HANGUL SYLLABLE BBEONG) 11145 0xBEEC 뻬 (HANGUL SYLLABLE BBE) 11146 0xBF01 뼁 (HANGUL SYLLABLE BBENG) 11147 0xBF08 뼈 (HANGUL SYLLABLE BBYEO) 11148 0xBF09 뼉 (HANGUL SYLLABLE BBYEOG) 11149 0xBF18 뼘 (HANGUL SYLLABLE BBYEOM) 11150 0xBF19 뼙 (HANGUL SYLLABLE BBYEOB) 11151 0xBF1B 뼛 (HANGUL SYLLABLE BBYEOS) 11152 0xBF1C 뼜 (HANGUL SYLLABLE BBYEOSS) 11153 0xBF1D 뼝 (HANGUL SYLLABLE BBYEONG) 11154 0xBF40 뽀 (HANGUL SYLLABLE BBO) 11155 0xBF41 뽁 (HANGUL SYLLABLE BBOG) 11156 0xBF44 뽄 (HANGUL SYLLABLE BBON) 11157 0xBF48 뽈 (HANGUL SYLLABLE BBOL) 11158 0xBF50 뽐 (HANGUL SYLLABLE BBOM) 11159 0xBF51 뽑 (HANGUL SYLLABLE BBOB) 11160 0xBF55 뽕 (HANGUL SYLLABLE BBONG) 11161 0xBF94 뾔 (HANGUL SYLLABLE BBOE) 11162 0xBFB0 뾰 (HANGUL SYLLABLE BBYO) 11163 0xBFC5 뿅 (HANGUL SYLLABLE BBYONG) 11164 0xBFCC 뿌 (HANGUL SYLLABLE BBU) 11165 0xBFCD 뿍 (HANGUL SYLLABLE BBUG) 11166 0xBFD0 뿐 (HANGUL SYLLABLE BBUN) 11167 0xBFD4 뿔 (HANGUL SYLLABLE BBUL) 11168 0xBFDC 뿜 (HANGUL SYLLABLE BBUM) 11169 0xBFDF 뿟 (HANGUL SYLLABLE BBUS) 11170 0xBFE1 뿡 (HANGUL SYLLABLE BBUNG) 11171 0xC03C 쀼 (HANGUL SYLLABLE BBYU) 11172 0xC051 쁑 (HANGUL SYLLABLE BBYUNG) 11173 0xC058 쁘 (HANGUL SYLLABLE BBEU) 11174 0xC05C 쁜 (HANGUL SYLLABLE BBEUN) 11175 0xC060 쁠 (HANGUL SYLLABLE BBEUL) 11176 0xC068 쁨 (HANGUL SYLLABLE BBEUM) 11177 0xC069 쁩 (HANGUL SYLLABLE BBEUB) 11178 0xC090 삐 (HANGUL SYLLABLE BBI) 11179 0xC091 삑 (HANGUL SYLLABLE BBIG) 11180 0xC094 삔 (HANGUL SYLLABLE BBIN) 11181 0xC098 삘 (HANGUL SYLLABLE BBIL) 11182 0xC0A0 삠 (HANGUL SYLLABLE BBIM) 11183 0xC0A1 삡 (HANGUL SYLLABLE BBIB) 11184 0xC0A3 삣 (HANGUL SYLLABLE BBIS) 11185 0xC0A5 삥 (HANGUL SYLLABLE BBING) 11186 0xC0AC 사 (HANGUL SYLLABLE SA) 11187 0xC0AD 삭 (HANGUL SYLLABLE SAG) 11188 0xC0AF 삯 (HANGUL SYLLABLE SAGS) 11189 0xC0B0 산 (HANGUL SYLLABLE SAN) 11190 0xC0B3 삳 (HANGUL SYLLABLE SAD) 11191 0xC0B4 살 (HANGUL SYLLABLE SAL) 11192 0xC0B5 삵 (HANGUL SYLLABLE SALG) 11193 0xC0B6 삶 (HANGUL SYLLABLE SALM) 11194 0xC0BC 삼 (HANGUL SYLLABLE SAM) 11195 0xC0BD 삽 (HANGUL SYLLABLE SAB) 11196 0xC0BF 삿 (HANGUL SYLLABLE SAS) 11197 0xC0C0 샀 (HANGUL SYLLABLE SASS) 11198 0xC0C1 상 (HANGUL SYLLABLE SANG) 11199 0xC0C5 샅 (HANGUL SYLLABLE SAT) 11200 0xC0C8 새 (HANGUL SYLLABLE SAE) 11201 0xC0C9 색 (HANGUL SYLLABLE SAEG) 11202 0xC0CC 샌 (HANGUL SYLLABLE SAEN) 11203 0xC0D0 샐 (HANGUL SYLLABLE SAEL) 11204 0xC0D8 샘 (HANGUL SYLLABLE SAEM) 11205 0xC0D9 샙 (HANGUL SYLLABLE SAEB) 11206 0xC0DB 샛 (HANGUL SYLLABLE SAES) 11207 0xC0DC 샜 (HANGUL SYLLABLE SAESS) 11208 0xC0DD 생 (HANGUL SYLLABLE SAENG) 11209 0xC0E4 샤 (HANGUL SYLLABLE SYA) 11210 0xD36A 퍪 (HANGUL SYLLABLE PYAELM) 11211 0xD36B 퍫 (HANGUL SYLLABLE PYAELB) 11212 0xD36C 퍬 (HANGUL SYLLABLE PYAELS) 11213 0xD36D 퍭 (HANGUL SYLLABLE PYAELT) 11214 0xD36E 퍮 (HANGUL SYLLABLE PYAELP) 11215 0xD36F 퍯 (HANGUL SYLLABLE PYAELH) 11216 0xD370 퍰 (HANGUL SYLLABLE PYAEM) 11217 0xD371 퍱 (HANGUL SYLLABLE PYAEB) 11218 0xD372 퍲 (HANGUL SYLLABLE PYAEBS) 11219 0xD373 퍳 (HANGUL SYLLABLE PYAES) 11220 0xD374 퍴 (HANGUL SYLLABLE PYAESS) 11221 0xD375 퍵 (HANGUL SYLLABLE PYAENG) 11222 0xD376 퍶 (HANGUL SYLLABLE PYAEJ) 11223 0xD377 퍷 (HANGUL SYLLABLE PYAEC) 11224 0xD378 퍸 (HANGUL SYLLABLE PYAEK) 11225 0xD379 퍹 (HANGUL SYLLABLE PYAET) 11226 0xD37A 퍺 (HANGUL SYLLABLE PYAEP) 11227 0xD37B 퍻 (HANGUL SYLLABLE PYAEH) 11228 0xD37E 퍾 (HANGUL SYLLABLE PEOGG) 11229 0xD37F 퍿 (HANGUL SYLLABLE PEOGS) 11230 0xD381 펁 (HANGUL SYLLABLE PEONJ) 11231 0xD382 펂 (HANGUL SYLLABLE PEONH) 11232 0xD383 펃 (HANGUL SYLLABLE PEOD) 11233 0xD385 펅 (HANGUL SYLLABLE PEOLG) 11234 0xD386 펆 (HANGUL SYLLABLE PEOLM) 11235 0xD387 펇 (HANGUL SYLLABLE PEOLB) 11242 0xD388 펈 (HANGUL SYLLABLE PEOLS) 11243 0xD389 펉 (HANGUL SYLLABLE PEOLT) 11244 0xD38A 펊 (HANGUL SYLLABLE PEOLP) 11245 0xD38B 펋 (HANGUL SYLLABLE PEOLH) 11246 0xD38E 펎 (HANGUL SYLLABLE PEOBS) 11247 0xD392 펒 (HANGUL SYLLABLE PEOJ) 11248 0xD393 펓 (HANGUL SYLLABLE PEOC) 11249 0xD394 펔 (HANGUL SYLLABLE PEOK) 11250 0xD395 펕 (HANGUL SYLLABLE PEOT) 11251 0xD396 펖 (HANGUL SYLLABLE PEOP) 11252 0xD397 펗 (HANGUL SYLLABLE PEOH) 11253 0xD39A 펚 (HANGUL SYLLABLE PEGG) 11254 0xD39B 펛 (HANGUL SYLLABLE PEGS) 11255 0xD39D 펝 (HANGUL SYLLABLE PENJ) 11256 0xD39E 펞 (HANGUL SYLLABLE PENH) 11257 0xD39F 펟 (HANGUL SYLLABLE PED) 11258 0xD3A1 펡 (HANGUL SYLLABLE PELG) 11259 0xD3A2 펢 (HANGUL SYLLABLE PELM) 11260 0xD3A3 펣 (HANGUL SYLLABLE PELB) 11261 0xD3A4 펤 (HANGUL SYLLABLE PELS) 11262 0xD3A5 펥 (HANGUL SYLLABLE PELT) 11263 0xD3A6 펦 (HANGUL SYLLABLE PELP) 11264 0xD3A7 펧 (HANGUL SYLLABLE PELH) 11265 0xD3AA 펪 (HANGUL SYLLABLE PEBS) 11266 0xD3AC 펬 (HANGUL SYLLABLE PESS) 11267 0xD3AE 펮 (HANGUL SYLLABLE PEJ) 11274 0xD3AF 펯 (HANGUL SYLLABLE PEC) 11275 0xD3B0 펰 (HANGUL SYLLABLE PEK) 11276 0xD3B1 펱 (HANGUL SYLLABLE PET) 11277 0xD3B2 펲 (HANGUL SYLLABLE PEP) 11278 0xD3B3 펳 (HANGUL SYLLABLE PEH) 11279 0xD3B5 펵 (HANGUL SYLLABLE PYEOG) 11280 0xD3B6 펶 (HANGUL SYLLABLE PYEOGG) 11281 0xD3B7 펷 (HANGUL SYLLABLE PYEOGS) 11282 0xD3B9 펹 (HANGUL SYLLABLE PYEONJ) 11283 0xD3BA 펺 (HANGUL SYLLABLE PYEONH) 11284 0xD3BB 펻 (HANGUL SYLLABLE PYEOD) 11285 0xD3BD 펽 (HANGUL SYLLABLE PYEOLG) 11286 0xD3BE 펾 (HANGUL SYLLABLE PYEOLM) 11287 0xD3BF 펿 (HANGUL SYLLABLE PYEOLB) 11288 0xD3C0 폀 (HANGUL SYLLABLE PYEOLS) 11289 0xD3C1 폁 (HANGUL SYLLABLE PYEOLT) 11290 0xD3C2 폂 (HANGUL SYLLABLE PYEOLP) 11291 0xD3C3 폃 (HANGUL SYLLABLE PYEOLH) 11292 0xD3C6 폆 (HANGUL SYLLABLE PYEOBS) 11293 0xD3C7 폇 (HANGUL SYLLABLE PYEOS) 11294 0xD3CA 폊 (HANGUL SYLLABLE PYEOJ) 11295 0xD3CB 폋 (HANGUL SYLLABLE PYEOC) 11296 0xD3CC 폌 (HANGUL SYLLABLE PYEOK) 11297 0xD3CD 폍 (HANGUL SYLLABLE PYEOT) 11298 0xD3CE 폎 (HANGUL SYLLABLE PYEOP) 11299 0xD3CF 폏 (HANGUL SYLLABLE PYEOH) 11300 0xD3D1 폑 (HANGUL SYLLABLE PYEG) 11301 0xD3D2 폒 (HANGUL SYLLABLE PYEGG) 11302 0xD3D3 폓 (HANGUL SYLLABLE PYEGS) 11303 0xD3D4 폔 (HANGUL SYLLABLE PYEN) 11304 0xD3D5 폕 (HANGUL SYLLABLE PYENJ) 11305 0xD3D6 폖 (HANGUL SYLLABLE PYENH) 11306 0xC0E5 샥 (HANGUL SYLLABLE SYAG) 11307 0xC0E8 샨 (HANGUL SYLLABLE SYAN) 11308 0xC0EC 샬 (HANGUL SYLLABLE SYAL) 11309 0xC0F4 샴 (HANGUL SYLLABLE SYAM) 11310 0xC0F5 샵 (HANGUL SYLLABLE SYAB) 11311 0xC0F7 샷 (HANGUL SYLLABLE SYAS) 11312 0xC0F9 샹 (HANGUL SYLLABLE SYANG) 11313 0xC100 섀 (HANGUL SYLLABLE SYAE) 11314 0xC104 섄 (HANGUL SYLLABLE SYAEN) 11315 0xC108 섈 (HANGUL SYLLABLE SYAEL) 11316 0xC110 섐 (HANGUL SYLLABLE SYAEM) 11317 0xC115 섕 (HANGUL SYLLABLE SYAENG) 11318 0xC11C 서 (HANGUL SYLLABLE SEO) 11319 0xC11D 석 (HANGUL SYLLABLE SEOG) 11320 0xC11E 섞 (HANGUL SYLLABLE SEOGG) 11321 0xC11F 섟 (HANGUL SYLLABLE SEOGS) 11322 0xC120 선 (HANGUL SYLLABLE SEON) 11323 0xC123 섣 (HANGUL SYLLABLE SEOD) 11324 0xC124 설 (HANGUL SYLLABLE SEOL) 11325 0xC126 섦 (HANGUL SYLLABLE SEOLM) 11326 0xC127 섧 (HANGUL SYLLABLE SEOLB) 11327 0xC12C 섬 (HANGUL SYLLABLE SEOM) 11328 0xC12D 섭 (HANGUL SYLLABLE SEOB) 11329 0xC12F 섯 (HANGUL SYLLABLE SEOS) 11330 0xC130 섰 (HANGUL SYLLABLE SEOSS) 11331 0xC131 성 (HANGUL SYLLABLE SEONG) 11332 0xC136 섶 (HANGUL SYLLABLE SEOP) 11333 0xC138 세 (HANGUL SYLLABLE SE) 11334 0xC139 섹 (HANGUL SYLLABLE SEG) 11335 0xC13C 센 (HANGUL SYLLABLE SEN) 11336 0xC140 셀 (HANGUL SYLLABLE SEL) 11337 0xC148 셈 (HANGUL SYLLABLE SEM) 11338 0xC149 셉 (HANGUL SYLLABLE SEB) 11339 0xC14B 셋 (HANGUL SYLLABLE SES) 11340 0xC14C 셌 (HANGUL SYLLABLE SESS) 11341 0xC14D 셍 (HANGUL SYLLABLE SENG) 11342 0xC154 셔 (HANGUL SYLLABLE SYEO) 11343 0xC155 셕 (HANGUL SYLLABLE SYEOG) 11344 0xC158 션 (HANGUL SYLLABLE SYEON) 11345 0xC15C 셜 (HANGUL SYLLABLE SYEOL) 11346 0xC164 셤 (HANGUL SYLLABLE SYEOM) 11347 0xC165 셥 (HANGUL SYLLABLE SYEOB) 11348 0xC167 셧 (HANGUL SYLLABLE SYEOS) 11349 0xC168 셨 (HANGUL SYLLABLE SYEOSS) 11350 0xC169 셩 (HANGUL SYLLABLE SYEONG) 11351 0xC170 셰 (HANGUL SYLLABLE SYE) 11352 0xC174 셴 (HANGUL SYLLABLE SYEN) 11353 0xC178 셸 (HANGUL SYLLABLE SYEL) 11354 0xC185 솅 (HANGUL SYLLABLE SYENG) 11355 0xC18C 소 (HANGUL SYLLABLE SO) 11356 0xC18D 속 (HANGUL SYLLABLE SOG) 11357 0xC18E 솎 (HANGUL SYLLABLE SOGG) 11358 0xC190 손 (HANGUL SYLLABLE SON) 11359 0xC194 솔 (HANGUL SYLLABLE SOL) 11360 0xC196 솖 (HANGUL SYLLABLE SOLM) 11361 0xC19C 솜 (HANGUL SYLLABLE SOM) 11362 0xC19D 솝 (HANGUL SYLLABLE SOB) 11363 0xC19F 솟 (HANGUL SYLLABLE SOS) 11364 0xC1A1 송 (HANGUL SYLLABLE SONG) 11365 0xC1A5 솥 (HANGUL SYLLABLE SOT) 11366 0xC1A8 솨 (HANGUL SYLLABLE SWA) 11367 0xC1A9 솩 (HANGUL SYLLABLE SWAG) 11368 0xC1AC 솬 (HANGUL SYLLABLE SWAN) 11369 0xC1B0 솰 (HANGUL SYLLABLE SWAL) 11370 0xC1BD 솽 (HANGUL SYLLABLE SWANG) 11371 0xC1C4 쇄 (HANGUL SYLLABLE SWAE) 11372 0xC1C8 쇈 (HANGUL SYLLABLE SWAEN) 11373 0xC1CC 쇌 (HANGUL SYLLABLE SWAEL) 11374 0xC1D4 쇔 (HANGUL SYLLABLE SWAEM) 11375 0xC1D7 쇗 (HANGUL SYLLABLE SWAES) 11376 0xC1D8 쇘 (HANGUL SYLLABLE SWAESS) 11377 0xC1E0 쇠 (HANGUL SYLLABLE SOE) 11378 0xC1E4 쇤 (HANGUL SYLLABLE SOEN) 11379 0xC1E8 쇨 (HANGUL SYLLABLE SOEL) 11380 0xC1F0 쇰 (HANGUL SYLLABLE SOEM) 11381 0xC1F1 쇱 (HANGUL SYLLABLE SOEB) 11382 0xC1F3 쇳 (HANGUL SYLLABLE SOES) 11383 0xC1FC 쇼 (HANGUL SYLLABLE SYO) 11384 0xC1FD 쇽 (HANGUL SYLLABLE SYOG) 11385 0xC200 숀 (HANGUL SYLLABLE SYON) 11386 0xC204 숄 (HANGUL SYLLABLE SYOL) 11387 0xC20C 숌 (HANGUL SYLLABLE SYOM) 11388 0xC20D 숍 (HANGUL SYLLABLE SYOB) 11389 0xC20F 숏 (HANGUL SYLLABLE SYOS) 11390 0xC211 숑 (HANGUL SYLLABLE SYONG) 11391 0xC218 수 (HANGUL SYLLABLE SU) 11392 0xC219 숙 (HANGUL SYLLABLE SUG) 11393 0xC21C 순 (HANGUL SYLLABLE SUN) 11394 0xC21F 숟 (HANGUL SYLLABLE SUD) 11395 0xC220 술 (HANGUL SYLLABLE SUL) 11396 0xC228 숨 (HANGUL SYLLABLE SUM) 11397 0xC229 숩 (HANGUL SYLLABLE SUB) 11398 0xC22B 숫 (HANGUL SYLLABLE SUS) 11399 0xC22D 숭 (HANGUL SYLLABLE SUNG) 11400 0xD3D7 폗 (HANGUL SYLLABLE PYED) 11401 0xD3D9 폙 (HANGUL SYLLABLE PYELG) 11402 0xD3DA 폚 (HANGUL SYLLABLE PYELM) 11403 0xD3DB 폛 (HANGUL SYLLABLE PYELB) 11404 0xD3DC 폜 (HANGUL SYLLABLE PYELS) 11405 0xD3DD 폝 (HANGUL SYLLABLE PYELT) 11406 0xD3DE 폞 (HANGUL SYLLABLE PYELP) 11407 0xD3DF 폟 (HANGUL SYLLABLE PYELH) 11408 0xD3E0 폠 (HANGUL SYLLABLE PYEM) 11409 0xD3E2 폢 (HANGUL SYLLABLE PYEBS) 11410 0xD3E4 폤 (HANGUL SYLLABLE PYESS) 11411 0xD3E5 폥 (HANGUL SYLLABLE PYENG) 11412 0xD3E6 폦 (HANGUL SYLLABLE PYEJ) 11413 0xD3E7 폧 (HANGUL SYLLABLE PYEC) 11414 0xD3E8 폨 (HANGUL SYLLABLE PYEK) 11415 0xD3E9 폩 (HANGUL SYLLABLE PYET) 11416 0xD3EA 폪 (HANGUL SYLLABLE PYEP) 11417 0xD3EB 폫 (HANGUL SYLLABLE PYEH) 11418 0xD3EE 폮 (HANGUL SYLLABLE POGG) 11419 0xD3EF 폯 (HANGUL SYLLABLE POGS) 11420 0xD3F1 폱 (HANGUL SYLLABLE PONJ) 11421 0xD3F2 폲 (HANGUL SYLLABLE PONH) 11422 0xD3F3 폳 (HANGUL SYLLABLE POD) 11423 0xD3F5 폵 (HANGUL SYLLABLE POLG) 11424 0xD3F6 폶 (HANGUL SYLLABLE POLM) 11425 0xD3F7 폷 (HANGUL SYLLABLE POLB) 11432 0xD3F8 폸 (HANGUL SYLLABLE POLS) 11433 0xD3F9 폹 (HANGUL SYLLABLE POLT) 11434 0xD3FA 폺 (HANGUL SYLLABLE POLP) 11435 0xD3FB 폻 (HANGUL SYLLABLE POLH) 11436 0xD3FE 폾 (HANGUL SYLLABLE POBS) 11437 0xD400 퐀 (HANGUL SYLLABLE POSS) 11438 0xD402 퐂 (HANGUL SYLLABLE POJ) 11439 0xD403 퐃 (HANGUL SYLLABLE POC) 11440 0xD404 퐄 (HANGUL SYLLABLE POK) 11441 0xD405 퐅 (HANGUL SYLLABLE POT) 11442 0xD406 퐆 (HANGUL SYLLABLE POP) 11443 0xD407 퐇 (HANGUL SYLLABLE POH) 11444 0xD409 퐉 (HANGUL SYLLABLE PWAG) 11445 0xD40A 퐊 (HANGUL SYLLABLE PWAGG) 11446 0xD40B 퐋 (HANGUL SYLLABLE PWAGS) 11447 0xD40C 퐌 (HANGUL SYLLABLE PWAN) 11448 0xD40D 퐍 (HANGUL SYLLABLE PWANJ) 11449 0xD40E 퐎 (HANGUL SYLLABLE PWANH) 11450 0xD40F 퐏 (HANGUL SYLLABLE PWAD) 11451 0xD410 퐐 (HANGUL SYLLABLE PWAL) 11452 0xD411 퐑 (HANGUL SYLLABLE PWALG) 11453 0xD412 퐒 (HANGUL SYLLABLE PWALM) 11454 0xD413 퐓 (HANGUL SYLLABLE PWALB) 11455 0xD414 퐔 (HANGUL SYLLABLE PWALS) 11456 0xD415 퐕 (HANGUL SYLLABLE PWALT) 11457 0xD416 퐖 (HANGUL SYLLABLE PWALP) 11464 0xD417 퐗 (HANGUL SYLLABLE PWALH) 11465 0xD418 퐘 (HANGUL SYLLABLE PWAM) 11466 0xD419 퐙 (HANGUL SYLLABLE PWAB) 11467 0xD41A 퐚 (HANGUL SYLLABLE PWABS) 11468 0xD41B 퐛 (HANGUL SYLLABLE PWAS) 11469 0xD41C 퐜 (HANGUL SYLLABLE PWASS) 11470 0xD41E 퐞 (HANGUL SYLLABLE PWAJ) 11471 0xD41F 퐟 (HANGUL SYLLABLE PWAC) 11472 0xD420 퐠 (HANGUL SYLLABLE PWAK) 11473 0xD421 퐡 (HANGUL SYLLABLE PWAT) 11474 0xD422 퐢 (HANGUL SYLLABLE PWAP) 11475 0xD423 퐣 (HANGUL SYLLABLE PWAH) 11476 0xD424 퐤 (HANGUL SYLLABLE PWAE) 11477 0xD425 퐥 (HANGUL SYLLABLE PWAEG) 11478 0xD426 퐦 (HANGUL SYLLABLE PWAEGG) 11479 0xD427 퐧 (HANGUL SYLLABLE PWAEGS) 11480 0xD428 퐨 (HANGUL SYLLABLE PWAEN) 11481 0xD429 퐩 (HANGUL SYLLABLE PWAENJ) 11482 0xD42A 퐪 (HANGUL SYLLABLE PWAENH) 11483 0xD42B 퐫 (HANGUL SYLLABLE PWAED) 11484 0xD42C 퐬 (HANGUL SYLLABLE PWAEL) 11485 0xD42D 퐭 (HANGUL SYLLABLE PWAELG) 11486 0xD42E 퐮 (HANGUL SYLLABLE PWAELM) 11487 0xD42F 퐯 (HANGUL SYLLABLE PWAELB) 11488 0xD430 퐰 (HANGUL SYLLABLE PWAELS) 11489 0xD431 퐱 (HANGUL SYLLABLE PWAELT) 11490 0xD432 퐲 (HANGUL SYLLABLE PWAELP) 11491 0xD433 퐳 (HANGUL SYLLABLE PWAELH) 11492 0xD434 퐴 (HANGUL SYLLABLE PWAEM) 11493 0xD435 퐵 (HANGUL SYLLABLE PWAEB) 11494 0xD436 퐶 (HANGUL SYLLABLE PWAEBS) 11495 0xD437 퐷 (HANGUL SYLLABLE PWAES) 11496 0xC22F 숯 (HANGUL SYLLABLE SUC) 11497 0xC231 숱 (HANGUL SYLLABLE SUT) 11498 0xC232 숲 (HANGUL SYLLABLE SUP) 11499 0xC234 숴 (HANGUL SYLLABLE SWEO) 11500 0xC248 쉈 (HANGUL SYLLABLE SWEOSS) 11501 0xC250 쉐 (HANGUL SYLLABLE SWE) 11502 0xC251 쉑 (HANGUL SYLLABLE SWEG) 11503 0xC254 쉔 (HANGUL SYLLABLE SWEN) 11504 0xC258 쉘 (HANGUL SYLLABLE SWEL) 11505 0xC260 쉠 (HANGUL SYLLABLE SWEM) 11506 0xC265 쉥 (HANGUL SYLLABLE SWENG) 11507 0xC26C 쉬 (HANGUL SYLLABLE SWI) 11508 0xC26D 쉭 (HANGUL SYLLABLE SWIG) 11509 0xC270 쉰 (HANGUL SYLLABLE SWIN) 11510 0xC274 쉴 (HANGUL SYLLABLE SWIL) 11511 0xC27C 쉼 (HANGUL SYLLABLE SWIM) 11512 0xC27D 쉽 (HANGUL SYLLABLE SWIB) 11513 0xC27F 쉿 (HANGUL SYLLABLE SWIS) 11514 0xC281 슁 (HANGUL SYLLABLE SWING) 11515 0xC288 슈 (HANGUL SYLLABLE SYU) 11516 0xC289 슉 (HANGUL SYLLABLE SYUG) 11517 0xC290 슐 (HANGUL SYLLABLE SYUL) 11518 0xC298 슘 (HANGUL SYLLABLE SYUM) 11519 0xC29B 슛 (HANGUL SYLLABLE SYUS) 11520 0xC29D 슝 (HANGUL SYLLABLE SYUNG) 11521 0xC2A4 스 (HANGUL SYLLABLE SEU) 11522 0xC2A5 슥 (HANGUL SYLLABLE SEUG) 11523 0xC2A8 슨 (HANGUL SYLLABLE SEUN) 11524 0xC2AC 슬 (HANGUL SYLLABLE SEUL) 11525 0xC2AD 슭 (HANGUL SYLLABLE SEULG) 11526 0xC2B4 슴 (HANGUL SYLLABLE SEUM) 11527 0xC2B5 습 (HANGUL SYLLABLE SEUB) 11528 0xC2B7 슷 (HANGUL SYLLABLE SEUS) 11529 0xC2B9 승 (HANGUL SYLLABLE SEUNG) 11530 0xC2DC 시 (HANGUL SYLLABLE SI) 11531 0xC2DD 식 (HANGUL SYLLABLE SIG) 11532 0xC2E0 신 (HANGUL SYLLABLE SIN) 11533 0xC2E3 싣 (HANGUL SYLLABLE SID) 11534 0xC2E4 실 (HANGUL SYLLABLE SIL) 11535 0xC2EB 싫 (HANGUL SYLLABLE SILH) 11536 0xC2EC 심 (HANGUL SYLLABLE SIM) 11537 0xC2ED 십 (HANGUL SYLLABLE SIB) 11538 0xC2EF 싯 (HANGUL SYLLABLE SIS) 11539 0xC2F1 싱 (HANGUL SYLLABLE SING) 11540 0xC2F6 싶 (HANGUL SYLLABLE SIP) 11541 0xC2F8 싸 (HANGUL SYLLABLE SSA) 11542 0xC2F9 싹 (HANGUL SYLLABLE SSAG) 11543 0xC2FB 싻 (HANGUL SYLLABLE SSAGS) 11544 0xC2FC 싼 (HANGUL SYLLABLE SSAN) 11545 0xC300 쌀 (HANGUL SYLLABLE SSAL) 11546 0xC308 쌈 (HANGUL SYLLABLE SSAM) 11547 0xC309 쌉 (HANGUL SYLLABLE SSAB) 11548 0xC30C 쌌 (HANGUL SYLLABLE SSASS) 11549 0xC30D 쌍 (HANGUL SYLLABLE SSANG) 11550 0xC313 쌓 (HANGUL SYLLABLE SSAH) 11551 0xC314 쌔 (HANGUL SYLLABLE SSAE) 11552 0xC315 쌕 (HANGUL SYLLABLE SSAEG) 11553 0xC318 쌘 (HANGUL SYLLABLE SSAEN) 11554 0xC31C 쌜 (HANGUL SYLLABLE SSAEL) 11555 0xC324 쌤 (HANGUL SYLLABLE SSAEM) 11556 0xC325 쌥 (HANGUL SYLLABLE SSAEB) 11557 0xC328 쌨 (HANGUL SYLLABLE SSAESS) 11558 0xC329 쌩 (HANGUL SYLLABLE SSAENG) 11559 0xC345 썅 (HANGUL SYLLABLE SSYANG) 11560 0xC368 써 (HANGUL SYLLABLE SSEO) 11561 0xC369 썩 (HANGUL SYLLABLE SSEOG) 11562 0xC36C 썬 (HANGUL SYLLABLE SSEON) 11563 0xC370 썰 (HANGUL SYLLABLE SSEOL) 11564 0xC372 썲 (HANGUL SYLLABLE SSEOLM) 11565 0xC378 썸 (HANGUL SYLLABLE SSEOM) 11566 0xC379 썹 (HANGUL SYLLABLE SSEOB) 11567 0xC37C 썼 (HANGUL SYLLABLE SSEOSS) 11568 0xC37D 썽 (HANGUL SYLLABLE SSEONG) 11569 0xC384 쎄 (HANGUL SYLLABLE SSE) 11570 0xC388 쎈 (HANGUL SYLLABLE SSEN) 11571 0xC38C 쎌 (HANGUL SYLLABLE SSEL) 11572 0xC3C0 쏀 (HANGUL SYLLABLE SSYEN) 11573 0xC3D8 쏘 (HANGUL SYLLABLE SSO) 11574 0xC3D9 쏙 (HANGUL SYLLABLE SSOG) 11575 0xC3DC 쏜 (HANGUL SYLLABLE SSON) 11576 0xC3DF 쏟 (HANGUL SYLLABLE SSOD) 11577 0xC3E0 쏠 (HANGUL SYLLABLE SSOL) 11578 0xC3E2 쏢 (HANGUL SYLLABLE SSOLM) 11579 0xC3E8 쏨 (HANGUL SYLLABLE SSOM) 11580 0xC3E9 쏩 (HANGUL SYLLABLE SSOB) 11581 0xC3ED 쏭 (HANGUL SYLLABLE SSONG) 11582 0xC3F4 쏴 (HANGUL SYLLABLE SSWA) 11583 0xC3F5 쏵 (HANGUL SYLLABLE SSWAG) 11584 0xC3F8 쏸 (HANGUL SYLLABLE SSWAN) 11585 0xC408 쐈 (HANGUL SYLLABLE SSWASS) 11586 0xC410 쐐 (HANGUL SYLLABLE SSWAE) 11587 0xC424 쐤 (HANGUL SYLLABLE SSWAESS) 11588 0xC42C 쐬 (HANGUL SYLLABLE SSOE) 11589 0xC430 쐰 (HANGUL SYLLABLE SSOEN) 11590 0xD438 퐸 (HANGUL SYLLABLE PWAESS) 11591 0xD439 퐹 (HANGUL SYLLABLE PWAENG) 11592 0xD43A 퐺 (HANGUL SYLLABLE PWAEJ) 11593 0xD43B 퐻 (HANGUL SYLLABLE PWAEC) 11594 0xD43C 퐼 (HANGUL SYLLABLE PWAEK) 11595 0xD43D 퐽 (HANGUL SYLLABLE PWAET) 11596 0xD43E 퐾 (HANGUL SYLLABLE PWAEP) 11597 0xD43F 퐿 (HANGUL SYLLABLE PWAEH) 11598 0xD441 푁 (HANGUL SYLLABLE POEG) 11599 0xD442 푂 (HANGUL SYLLABLE POEGG) 11600 0xD443 푃 (HANGUL SYLLABLE POEGS) 11601 0xD445 푅 (HANGUL SYLLABLE POENJ) 11602 0xD446 푆 (HANGUL SYLLABLE POENH) 11603 0xD447 푇 (HANGUL SYLLABLE POED) 11604 0xD448 푈 (HANGUL SYLLABLE POEL) 11605 0xD449 푉 (HANGUL SYLLABLE POELG) 11606 0xD44A 푊 (HANGUL SYLLABLE POELM) 11607 0xD44B 푋 (HANGUL SYLLABLE POELB) 11608 0xD44C 푌 (HANGUL SYLLABLE POELS) 11609 0xD44D 푍 (HANGUL SYLLABLE POELT) 11610 0xD44E 푎 (HANGUL SYLLABLE POELP) 11611 0xD44F 푏 (HANGUL SYLLABLE POELH) 11612 0xD450 푐 (HANGUL SYLLABLE POEM) 11613 0xD451 푑 (HANGUL SYLLABLE POEB) 11614 0xD452 푒 (HANGUL SYLLABLE POEBS) 11615 0xD453 푓 (HANGUL SYLLABLE POES) 11622 0xD454 푔 (HANGUL SYLLABLE POESS) 11623 0xD455 푕 (HANGUL SYLLABLE POENG) 11624 0xD456 푖 (HANGUL SYLLABLE POEJ) 11625 0xD457 푗 (HANGUL SYLLABLE POEC) 11626 0xD458 푘 (HANGUL SYLLABLE POEK) 11627 0xD459 푙 (HANGUL SYLLABLE POET) 11628 0xD45A 푚 (HANGUL SYLLABLE POEP) 11629 0xD45B 푛 (HANGUL SYLLABLE POEH) 11630 0xD45D 푝 (HANGUL SYLLABLE PYOG) 11631 0xD45E 푞 (HANGUL SYLLABLE PYOGG) 11632 0xD45F 푟 (HANGUL SYLLABLE PYOGS) 11633 0xD461 푡 (HANGUL SYLLABLE PYONJ) 11634 0xD462 푢 (HANGUL SYLLABLE PYONH) 11635 0xD463 푣 (HANGUL SYLLABLE PYOD) 11636 0xD465 푥 (HANGUL SYLLABLE PYOLG) 11637 0xD466 푦 (HANGUL SYLLABLE PYOLM) 11638 0xD467 푧 (HANGUL SYLLABLE PYOLB) 11639 0xD468 푨 (HANGUL SYLLABLE PYOLS) 11640 0xD469 푩 (HANGUL SYLLABLE PYOLT) 11641 0xD46A 푪 (HANGUL SYLLABLE PYOLP) 11642 0xD46B 푫 (HANGUL SYLLABLE PYOLH) 11643 0xD46C 푬 (HANGUL SYLLABLE PYOM) 11644 0xD46E 푮 (HANGUL SYLLABLE PYOBS) 11645 0xD470 푰 (HANGUL SYLLABLE PYOSS) 11646 0xD471 푱 (HANGUL SYLLABLE PYONG) 11647 0xD472 푲 (HANGUL SYLLABLE PYOJ) 11654 0xD473 푳 (HANGUL SYLLABLE PYOC) 11655 0xD474 푴 (HANGUL SYLLABLE PYOK) 11656 0xD475 푵 (HANGUL SYLLABLE PYOT) 11657 0xD476 푶 (HANGUL SYLLABLE PYOP) 11658 0xD477 푷 (HANGUL SYLLABLE PYOH) 11659 0xD47A 푺 (HANGUL SYLLABLE PUGG) 11660 0xD47B 푻 (HANGUL SYLLABLE PUGS) 11661 0xD47D 푽 (HANGUL SYLLABLE PUNJ) 11662 0xD47E 푾 (HANGUL SYLLABLE PUNH) 11663 0xD481 풁 (HANGUL SYLLABLE PULG) 11664 0xD483 풃 (HANGUL SYLLABLE PULB) 11665 0xD484 풄 (HANGUL SYLLABLE PULS) 11666 0xD485 풅 (HANGUL SYLLABLE PULT) 11667 0xD486 풆 (HANGUL SYLLABLE PULP) 11668 0xD487 풇 (HANGUL SYLLABLE PULH) 11669 0xD48A 풊 (HANGUL SYLLABLE PUBS) 11670 0xD48C 풌 (HANGUL SYLLABLE PUSS) 11671 0xD48E 풎 (HANGUL SYLLABLE PUJ) 11672 0xD48F 풏 (HANGUL SYLLABLE PUC) 11673 0xD490 풐 (HANGUL SYLLABLE PUK) 11674 0xD491 풑 (HANGUL SYLLABLE PUT) 11675 0xD492 풒 (HANGUL SYLLABLE PUP) 11676 0xD493 풓 (HANGUL SYLLABLE PUH) 11677 0xD495 풕 (HANGUL SYLLABLE PWEOG) 11678 0xD496 풖 (HANGUL SYLLABLE PWEOGG) 11679 0xD497 풗 (HANGUL SYLLABLE PWEOGS) 11680 0xD498 풘 (HANGUL SYLLABLE PWEON) 11681 0xD499 풙 (HANGUL SYLLABLE PWEONJ) 11682 0xD49A 풚 (HANGUL SYLLABLE PWEONH) 11683 0xD49B 풛 (HANGUL SYLLABLE PWEOD) 11684 0xD49C 풜 (HANGUL SYLLABLE PWEOL) 11685 0xD49D 풝 (HANGUL SYLLABLE PWEOLG) 11686 0xC434 쐴 (HANGUL SYLLABLE SSOEL) 11687 0xC43C 쐼 (HANGUL SYLLABLE SSOEM) 11688 0xC43D 쐽 (HANGUL SYLLABLE SSOEB) 11689 0xC448 쑈 (HANGUL SYLLABLE SSYO) 11690 0xC464 쑤 (HANGUL SYLLABLE SSU) 11691 0xC465 쑥 (HANGUL SYLLABLE SSUG) 11692 0xC468 쑨 (HANGUL SYLLABLE SSUN) 11693 0xC46C 쑬 (HANGUL SYLLABLE SSUL) 11694 0xC474 쑴 (HANGUL SYLLABLE SSUM) 11695 0xC475 쑵 (HANGUL SYLLABLE SSUB) 11696 0xC479 쑹 (HANGUL SYLLABLE SSUNG) 11697 0xC480 쒀 (HANGUL SYLLABLE SSWEO) 11698 0xC494 쒔 (HANGUL SYLLABLE SSWEOSS) 11699 0xC49C 쒜 (HANGUL SYLLABLE SSWE) 11700 0xC4B8 쒸 (HANGUL SYLLABLE SSWI) 11701 0xC4BC 쒼 (HANGUL SYLLABLE SSWIN) 11702 0xC4E9 쓩 (HANGUL SYLLABLE SSYUNG) 11703 0xC4F0 쓰 (HANGUL SYLLABLE SSEU) 11704 0xC4F1 쓱 (HANGUL SYLLABLE SSEUG) 11705 0xC4F4 쓴 (HANGUL SYLLABLE SSEUN) 11706 0xC4F8 쓸 (HANGUL SYLLABLE SSEUL) 11707 0xC4FA 쓺 (HANGUL SYLLABLE SSEULM) 11708 0xC4FF 쓿 (HANGUL SYLLABLE SSEULH) 11709 0xC500 씀 (HANGUL SYLLABLE SSEUM) 11710 0xC501 씁 (HANGUL SYLLABLE SSEUB) 11711 0xC50C 씌 (HANGUL SYLLABLE SSYI) 11712 0xC510 씐 (HANGUL SYLLABLE SSYIN) 11713 0xC514 씔 (HANGUL SYLLABLE SSYIL) 11714 0xC51C 씜 (HANGUL SYLLABLE SSYIM) 11715 0xC528 씨 (HANGUL SYLLABLE SSI) 11716 0xC529 씩 (HANGUL SYLLABLE SSIG) 11717 0xC52C 씬 (HANGUL SYLLABLE SSIN) 11718 0xC530 씰 (HANGUL SYLLABLE SSIL) 11719 0xC538 씸 (HANGUL SYLLABLE SSIM) 11720 0xC539 씹 (HANGUL SYLLABLE SSIB) 11721 0xC53B 씻 (HANGUL SYLLABLE SSIS) 11722 0xC53D 씽 (HANGUL SYLLABLE SSING) 11723 0xC544 아 (HANGUL SYLLABLE A) 11724 0xC545 악 (HANGUL SYLLABLE AG) 11725 0xC548 안 (HANGUL SYLLABLE AN) 11726 0xC549 앉 (HANGUL SYLLABLE ANJ) 11727 0xC54A 않 (HANGUL SYLLABLE ANH) 11728 0xC54C 알 (HANGUL SYLLABLE AL) 11729 0xC54D 앍 (HANGUL SYLLABLE ALG) 11730 0xC54E 앎 (HANGUL SYLLABLE ALM) 11731 0xC553 앓 (HANGUL SYLLABLE ALH) 11732 0xC554 암 (HANGUL SYLLABLE AM) 11733 0xC555 압 (HANGUL SYLLABLE AB) 11734 0xC557 앗 (HANGUL SYLLABLE AS) 11735 0xC558 았 (HANGUL SYLLABLE ASS) 11736 0xC559 앙 (HANGUL SYLLABLE ANG) 11737 0xC55D 앝 (HANGUL SYLLABLE AT) 11738 0xC55E 앞 (HANGUL SYLLABLE AP) 11739 0xC560 애 (HANGUL SYLLABLE AE) 11740 0xC561 액 (HANGUL SYLLABLE AEG) 11741 0xC564 앤 (HANGUL SYLLABLE AEN) 11742 0xC568 앨 (HANGUL SYLLABLE AEL) 11743 0xC570 앰 (HANGUL SYLLABLE AEM) 11744 0xC571 앱 (HANGUL SYLLABLE AEB) 11745 0xC573 앳 (HANGUL SYLLABLE AES) 11746 0xC574 앴 (HANGUL SYLLABLE AESS) 11747 0xC575 앵 (HANGUL SYLLABLE AENG) 11748 0xC57C 야 (HANGUL SYLLABLE YA) 11749 0xC57D 약 (HANGUL SYLLABLE YAG) 11750 0xC580 얀 (HANGUL SYLLABLE YAN) 11751 0xC584 얄 (HANGUL SYLLABLE YAL) 11752 0xC587 얇 (HANGUL SYLLABLE YALB) 11753 0xC58C 얌 (HANGUL SYLLABLE YAM) 11754 0xC58D 얍 (HANGUL SYLLABLE YAB) 11755 0xC58F 얏 (HANGUL SYLLABLE YAS) 11756 0xC591 양 (HANGUL SYLLABLE YANG) 11757 0xC595 얕 (HANGUL SYLLABLE YAT) 11758 0xC597 얗 (HANGUL SYLLABLE YAH) 11759 0xC598 얘 (HANGUL SYLLABLE YAE) 11760 0xC59C 얜 (HANGUL SYLLABLE YAEN) 11761 0xC5A0 얠 (HANGUL SYLLABLE YAEL) 11762 0xC5A9 얩 (HANGUL SYLLABLE YAEB) 11763 0xC5B4 어 (HANGUL SYLLABLE EO) 11764 0xC5B5 억 (HANGUL SYLLABLE EOG) 11765 0xC5B8 언 (HANGUL SYLLABLE EON) 11766 0xC5B9 얹 (HANGUL SYLLABLE EONJ) 11767 0xC5BB 얻 (HANGUL SYLLABLE EOD) 11768 0xC5BC 얼 (HANGUL SYLLABLE EOL) 11769 0xC5BD 얽 (HANGUL SYLLABLE EOLG) 11770 0xC5BE 얾 (HANGUL SYLLABLE EOLM) 11771 0xC5C4 엄 (HANGUL SYLLABLE EOM) 11772 0xC5C5 업 (HANGUL SYLLABLE EOB) 11773 0xC5C6 없 (HANGUL SYLLABLE EOBS) 11774 0xC5C7 엇 (HANGUL SYLLABLE EOS) 11775 0xC5C8 었 (HANGUL SYLLABLE EOSS) 11776 0xC5C9 엉 (HANGUL SYLLABLE EONG) 11777 0xC5CA 엊 (HANGUL SYLLABLE EOJ) 11778 0xC5CC 엌 (HANGUL SYLLABLE EOK) 11779 0xC5CE 엎 (HANGUL SYLLABLE EOP) 11780 0xD49E 풞 (HANGUL SYLLABLE PWEOLM) 11781 0xD49F 풟 (HANGUL SYLLABLE PWEOLB) 11782 0xD4A0 풠 (HANGUL SYLLABLE PWEOLS) 11783 0xD4A1 풡 (HANGUL SYLLABLE PWEOLT) 11784 0xD4A2 풢 (HANGUL SYLLABLE PWEOLP) 11785 0xD4A3 풣 (HANGUL SYLLABLE PWEOLH) 11786 0xD4A4 풤 (HANGUL SYLLABLE PWEOM) 11787 0xD4A5 풥 (HANGUL SYLLABLE PWEOB) 11788 0xD4A6 풦 (HANGUL SYLLABLE PWEOBS) 11789 0xD4A7 풧 (HANGUL SYLLABLE PWEOS) 11790 0xD4A8 풨 (HANGUL SYLLABLE PWEOSS) 11791 0xD4AA 풪 (HANGUL SYLLABLE PWEOJ) 11792 0xD4AB 풫 (HANGUL SYLLABLE PWEOC) 11793 0xD4AC 풬 (HANGUL SYLLABLE PWEOK) 11794 0xD4AD 풭 (HANGUL SYLLABLE PWEOT) 11795 0xD4AE 풮 (HANGUL SYLLABLE PWEOP) 11796 0xD4AF 풯 (HANGUL SYLLABLE PWEOH) 11797 0xD4B0 풰 (HANGUL SYLLABLE PWE) 11798 0xD4B1 풱 (HANGUL SYLLABLE PWEG) 11799 0xD4B2 풲 (HANGUL SYLLABLE PWEGG) 11800 0xD4B3 풳 (HANGUL SYLLABLE PWEGS) 11801 0xD4B4 풴 (HANGUL SYLLABLE PWEN) 11802 0xD4B5 풵 (HANGUL SYLLABLE PWENJ) 11803 0xD4B6 풶 (HANGUL SYLLABLE PWENH) 11804 0xD4B7 풷 (HANGUL SYLLABLE PWED) 11805 0xD4B8 풸 (HANGUL SYLLABLE PWEL) 11812 0xD4B9 풹 (HANGUL SYLLABLE PWELG) 11813 0xD4BA 풺 (HANGUL SYLLABLE PWELM) 11814 0xD4BB 풻 (HANGUL SYLLABLE PWELB) 11815 0xD4BC 풼 (HANGUL SYLLABLE PWELS) 11816 0xD4BD 풽 (HANGUL SYLLABLE PWELT) 11817 0xD4BE 풾 (HANGUL SYLLABLE PWELP) 11818 0xD4BF 풿 (HANGUL SYLLABLE PWELH) 11819 0xD4C0 퓀 (HANGUL SYLLABLE PWEM) 11820 0xD4C1 퓁 (HANGUL SYLLABLE PWEB) 11821 0xD4C2 퓂 (HANGUL SYLLABLE PWEBS) 11822 0xD4C3 퓃 (HANGUL SYLLABLE PWES) 11823 0xD4C4 퓄 (HANGUL SYLLABLE PWESS) 11824 0xD4C5 퓅 (HANGUL SYLLABLE PWENG) 11825 0xD4C6 퓆 (HANGUL SYLLABLE PWEJ) 11826 0xD4C7 퓇 (HANGUL SYLLABLE PWEC) 11827 0xD4C8 퓈 (HANGUL SYLLABLE PWEK) 11828 0xD4C9 퓉 (HANGUL SYLLABLE PWET) 11829 0xD4CA 퓊 (HANGUL SYLLABLE PWEP) 11830 0xD4CB 퓋 (HANGUL SYLLABLE PWEH) 11831 0xD4CD 퓍 (HANGUL SYLLABLE PWIG) 11832 0xD4CE 퓎 (HANGUL SYLLABLE PWIGG) 11833 0xD4CF 퓏 (HANGUL SYLLABLE PWIGS) 11834 0xD4D1 퓑 (HANGUL SYLLABLE PWINJ) 11835 0xD4D2 퓒 (HANGUL SYLLABLE PWINH) 11836 0xD4D3 퓓 (HANGUL SYLLABLE PWID) 11837 0xD4D5 퓕 (HANGUL SYLLABLE PWILG) 11844 0xD4D6 퓖 (HANGUL SYLLABLE PWILM) 11845 0xD4D7 퓗 (HANGUL SYLLABLE PWILB) 11846 0xD4D8 퓘 (HANGUL SYLLABLE PWILS) 11847 0xD4D9 퓙 (HANGUL SYLLABLE PWILT) 11848 0xD4DA 퓚 (HANGUL SYLLABLE PWILP) 11849 0xD4DB 퓛 (HANGUL SYLLABLE PWILH) 11850 0xD4DD 퓝 (HANGUL SYLLABLE PWIB) 11851 0xD4DE 퓞 (HANGUL SYLLABLE PWIBS) 11852 0xD4E0 퓠 (HANGUL SYLLABLE PWISS) 11853 0xD4E1 퓡 (HANGUL SYLLABLE PWING) 11854 0xD4E2 퓢 (HANGUL SYLLABLE PWIJ) 11855 0xD4E3 퓣 (HANGUL SYLLABLE PWIC) 11856 0xD4E4 퓤 (HANGUL SYLLABLE PWIK) 11857 0xD4E5 퓥 (HANGUL SYLLABLE PWIT) 11858 0xD4E6 퓦 (HANGUL SYLLABLE PWIP) 11859 0xD4E7 퓧 (HANGUL SYLLABLE PWIH) 11860 0xD4E9 퓩 (HANGUL SYLLABLE PYUG) 11861 0xD4EA 퓪 (HANGUL SYLLABLE PYUGG) 11862 0xD4EB 퓫 (HANGUL SYLLABLE PYUGS) 11863 0xD4ED 퓭 (HANGUL SYLLABLE PYUNJ) 11864 0xD4EE 퓮 (HANGUL SYLLABLE PYUNH) 11865 0xD4EF 퓯 (HANGUL SYLLABLE PYUD) 11866 0xD4F1 퓱 (HANGUL SYLLABLE PYULG) 11867 0xD4F2 퓲 (HANGUL SYLLABLE PYULM) 11868 0xD4F3 퓳 (HANGUL SYLLABLE PYULB) 11869 0xD4F4 퓴 (HANGUL SYLLABLE PYULS) 11870 0xD4F5 퓵 (HANGUL SYLLABLE PYULT) 11871 0xD4F6 퓶 (HANGUL SYLLABLE PYULP) 11872 0xD4F7 퓷 (HANGUL SYLLABLE PYULH) 11873 0xD4F9 퓹 (HANGUL SYLLABLE PYUB) 11874 0xD4FA 퓺 (HANGUL SYLLABLE PYUBS) 11875 0xD4FC 퓼 (HANGUL SYLLABLE PYUSS) 11876 0xC5D0 에 (HANGUL SYLLABLE E) 11877 0xC5D1 엑 (HANGUL SYLLABLE EG) 11878 0xC5D4 엔 (HANGUL SYLLABLE EN) 11879 0xC5D8 엘 (HANGUL SYLLABLE EL) 11880 0xC5E0 엠 (HANGUL SYLLABLE EM) 11881 0xC5E1 엡 (HANGUL SYLLABLE EB) 11882 0xC5E3 엣 (HANGUL SYLLABLE ES) 11883 0xC5E5 엥 (HANGUL SYLLABLE ENG) 11884 0xC5EC 여 (HANGUL SYLLABLE YEO) 11885 0xC5ED 역 (HANGUL SYLLABLE YEOG) 11886 0xC5EE 엮 (HANGUL SYLLABLE YEOGG) 11887 0xC5F0 연 (HANGUL SYLLABLE YEON) 11888 0xC5F4 열 (HANGUL SYLLABLE YEOL) 11889 0xC5F6 엶 (HANGUL SYLLABLE YEOLM) 11890 0xC5F7 엷 (HANGUL SYLLABLE YEOLB) 11891 0xC5FC 염 (HANGUL SYLLABLE YEOM) 11892 0xC5FD 엽 (HANGUL SYLLABLE YEOB) 11893 0xC5FE 엾 (HANGUL SYLLABLE YEOBS) 11894 0xC5FF 엿 (HANGUL SYLLABLE YEOS) 11895 0xC600 였 (HANGUL SYLLABLE YEOSS) 11896 0xC601 영 (HANGUL SYLLABLE YEONG) 11897 0xC605 옅 (HANGUL SYLLABLE YEOT) 11898 0xC606 옆 (HANGUL SYLLABLE YEOP) 11899 0xC607 옇 (HANGUL SYLLABLE YEOH) 11900 0xC608 예 (HANGUL SYLLABLE YE) 11901 0xC60C 옌 (HANGUL SYLLABLE YEN) 11902 0xC610 옐 (HANGUL SYLLABLE YEL) 11903 0xC618 옘 (HANGUL SYLLABLE YEM) 11904 0xC619 옙 (HANGUL SYLLABLE YEB) 11905 0xC61B 옛 (HANGUL SYLLABLE YES) 11906 0xC61C 옜 (HANGUL SYLLABLE YESS) 11907 0xC624 오 (HANGUL SYLLABLE O) 11908 0xC625 옥 (HANGUL SYLLABLE OG) 11909 0xC628 온 (HANGUL SYLLABLE ON) 11910 0xC62C 올 (HANGUL SYLLABLE OL) 11911 0xC62D 옭 (HANGUL SYLLABLE OLG) 11912 0xC62E 옮 (HANGUL SYLLABLE OLM) 11913 0xC630 옰 (HANGUL SYLLABLE OLS) 11914 0xC633 옳 (HANGUL SYLLABLE OLH) 11915 0xC634 옴 (HANGUL SYLLABLE OM) 11916 0xC635 옵 (HANGUL SYLLABLE OB) 11917 0xC637 옷 (HANGUL SYLLABLE OS) 11918 0xC639 옹 (HANGUL SYLLABLE ONG) 11919 0xC63B 옻 (HANGUL SYLLABLE OC) 11920 0xC640 와 (HANGUL SYLLABLE WA) 11921 0xC641 왁 (HANGUL SYLLABLE WAG) 11922 0xC644 완 (HANGUL SYLLABLE WAN) 11923 0xC648 왈 (HANGUL SYLLABLE WAL) 11924 0xC650 왐 (HANGUL SYLLABLE WAM) 11925 0xC651 왑 (HANGUL SYLLABLE WAB) 11926 0xC653 왓 (HANGUL SYLLABLE WAS) 11927 0xC654 왔 (HANGUL SYLLABLE WASS) 11928 0xC655 왕 (HANGUL SYLLABLE WANG) 11929 0xC65C 왜 (HANGUL SYLLABLE WAE) 11930 0xC65D 왝 (HANGUL SYLLABLE WAEG) 11931 0xC660 왠 (HANGUL SYLLABLE WAEN) 11932 0xC66C 왬 (HANGUL SYLLABLE WAEM) 11933 0xC66F 왯 (HANGUL SYLLABLE WAES) 11934 0xC671 왱 (HANGUL SYLLABLE WAENG) 11935 0xC678 외 (HANGUL SYLLABLE OE) 11936 0xC679 왹 (HANGUL SYLLABLE OEG) 11937 0xC67C 왼 (HANGUL SYLLABLE OEN) 11938 0xC680 욀 (HANGUL SYLLABLE OEL) 11939 0xC688 욈 (HANGUL SYLLABLE OEM) 11940 0xC689 욉 (HANGUL SYLLABLE OEB) 11941 0xC68B 욋 (HANGUL SYLLABLE OES) 11942 0xC68D 욍 (HANGUL SYLLABLE OENG) 11943 0xC694 요 (HANGUL SYLLABLE YO) 11944 0xC695 욕 (HANGUL SYLLABLE YOG) 11945 0xC698 욘 (HANGUL SYLLABLE YON) 11946 0xC69C 욜 (HANGUL SYLLABLE YOL) 11947 0xC6A4 욤 (HANGUL SYLLABLE YOM) 11948 0xC6A5 욥 (HANGUL SYLLABLE YOB) 11949 0xC6A7 욧 (HANGUL SYLLABLE YOS) 11950 0xC6A9 용 (HANGUL SYLLABLE YONG) 11951 0xC6B0 우 (HANGUL SYLLABLE U) 11952 0xC6B1 욱 (HANGUL SYLLABLE UG) 11953 0xC6B4 운 (HANGUL SYLLABLE UN) 11954 0xC6B8 울 (HANGUL SYLLABLE UL) 11955 0xC6B9 욹 (HANGUL SYLLABLE ULG) 11956 0xC6BA 욺 (HANGUL SYLLABLE ULM) 11957 0xC6C0 움 (HANGUL SYLLABLE UM) 11958 0xC6C1 웁 (HANGUL SYLLABLE UB) 11959 0xC6C3 웃 (HANGUL SYLLABLE US) 11960 0xC6C5 웅 (HANGUL SYLLABLE UNG) 11961 0xC6CC 워 (HANGUL SYLLABLE WEO) 11962 0xC6CD 웍 (HANGUL SYLLABLE WEOG) 11963 0xC6D0 원 (HANGUL SYLLABLE WEON) 11964 0xC6D4 월 (HANGUL SYLLABLE WEOL) 11965 0xC6DC 웜 (HANGUL SYLLABLE WEOM) 11966 0xC6DD 웝 (HANGUL SYLLABLE WEOB) 11967 0xC6E0 웠 (HANGUL SYLLABLE WEOSS) 11968 0xC6E1 웡 (HANGUL SYLLABLE WEONG) 11969 0xC6E8 웨 (HANGUL SYLLABLE WE) 11970 0xD4FE 퓾 (HANGUL SYLLABLE PYUJ) 11971 0xD4FF 퓿 (HANGUL SYLLABLE PYUC) 11972 0xD500 픀 (HANGUL SYLLABLE PYUK) 11973 0xD501 픁 (HANGUL SYLLABLE PYUT) 11974 0xD502 픂 (HANGUL SYLLABLE PYUP) 11975 0xD503 픃 (HANGUL SYLLABLE PYUH) 11976 0xD505 픅 (HANGUL SYLLABLE PEUG) 11977 0xD506 픆 (HANGUL SYLLABLE PEUGG) 11978 0xD507 픇 (HANGUL SYLLABLE PEUGS) 11979 0xD509 픉 (HANGUL SYLLABLE PEUNJ) 11980 0xD50A 픊 (HANGUL SYLLABLE PEUNH) 11981 0xD50B 픋 (HANGUL SYLLABLE PEUD) 11982 0xD50D 픍 (HANGUL SYLLABLE PEULG) 11983 0xD50E 픎 (HANGUL SYLLABLE PEULM) 11984 0xD50F 픏 (HANGUL SYLLABLE PEULB) 11985 0xD510 픐 (HANGUL SYLLABLE PEULS) 11986 0xD511 픑 (HANGUL SYLLABLE PEULT) 11987 0xD512 픒 (HANGUL SYLLABLE PEULP) 11988 0xD513 픓 (HANGUL SYLLABLE PEULH) 11989 0xD516 픖 (HANGUL SYLLABLE PEUBS) 11990 0xD518 픘 (HANGUL SYLLABLE PEUSS) 11991 0xD519 픙 (HANGUL SYLLABLE PEUNG) 11992 0xD51A 픚 (HANGUL SYLLABLE PEUJ) 11993 0xD51B 픛 (HANGUL SYLLABLE PEUC) 11994 0xD51C 픜 (HANGUL SYLLABLE PEUK) 11995 0xD51D 픝 (HANGUL SYLLABLE PEUT) 12002 0xD51E 픞 (HANGUL SYLLABLE PEUP) 12003 0xD51F 픟 (HANGUL SYLLABLE PEUH) 12004 0xD520 픠 (HANGUL SYLLABLE PYI) 12005 0xD521 픡 (HANGUL SYLLABLE PYIG) 12006 0xD522 픢 (HANGUL SYLLABLE PYIGG) 12007 0xD523 픣 (HANGUL SYLLABLE PYIGS) 12008 0xD524 픤 (HANGUL SYLLABLE PYIN) 12009 0xD525 픥 (HANGUL SYLLABLE PYINJ) 12010 0xD526 픦 (HANGUL SYLLABLE PYINH) 12011 0xD527 픧 (HANGUL SYLLABLE PYID) 12012 0xD528 픨 (HANGUL SYLLABLE PYIL) 12013 0xD529 픩 (HANGUL SYLLABLE PYILG) 12014 0xD52A 픪 (HANGUL SYLLABLE PYILM) 12015 0xD52B 픫 (HANGUL SYLLABLE PYILB) 12016 0xD52C 픬 (HANGUL SYLLABLE PYILS) 12017 0xD52D 픭 (HANGUL SYLLABLE PYILT) 12018 0xD52E 픮 (HANGUL SYLLABLE PYILP) 12019 0xD52F 픯 (HANGUL SYLLABLE PYILH) 12020 0xD530 픰 (HANGUL SYLLABLE PYIM) 12021 0xD531 픱 (HANGUL SYLLABLE PYIB) 12022 0xD532 픲 (HANGUL SYLLABLE PYIBS) 12023 0xD533 픳 (HANGUL SYLLABLE PYIS) 12024 0xD534 픴 (HANGUL SYLLABLE PYISS) 12025 0xD535 픵 (HANGUL SYLLABLE PYING) 12026 0xD536 픶 (HANGUL SYLLABLE PYIJ) 12027 0xD537 픷 (HANGUL SYLLABLE PYIC) 12034 0xD538 픸 (HANGUL SYLLABLE PYIK) 12035 0xD539 픹 (HANGUL SYLLABLE PYIT) 12036 0xD53A 픺 (HANGUL SYLLABLE PYIP) 12037 0xD53B 픻 (HANGUL SYLLABLE PYIH) 12038 0xD53E 픾 (HANGUL SYLLABLE PIGG) 12039 0xD53F 픿 (HANGUL SYLLABLE PIGS) 12040 0xD541 핁 (HANGUL SYLLABLE PINJ) 12041 0xD542 핂 (HANGUL SYLLABLE PINH) 12042 0xD543 핃 (HANGUL SYLLABLE PID) 12043 0xD545 핅 (HANGUL SYLLABLE PILG) 12044 0xD546 핆 (HANGUL SYLLABLE PILM) 12045 0xD547 핇 (HANGUL SYLLABLE PILB) 12046 0xD548 핈 (HANGUL SYLLABLE PILS) 12047 0xD549 핉 (HANGUL SYLLABLE PILT) 12048 0xD54A 핊 (HANGUL SYLLABLE PILP) 12049 0xD54B 핋 (HANGUL SYLLABLE PILH) 12050 0xD54E 핎 (HANGUL SYLLABLE PIBS) 12051 0xD550 핐 (HANGUL SYLLABLE PISS) 12052 0xD552 핒 (HANGUL SYLLABLE PIJ) 12053 0xD553 핓 (HANGUL SYLLABLE PIC) 12054 0xD554 핔 (HANGUL SYLLABLE PIK) 12055 0xD555 핕 (HANGUL SYLLABLE PIT) 12056 0xD556 핖 (HANGUL SYLLABLE PIP) 12057 0xD557 핗 (HANGUL SYLLABLE PIH) 12058 0xD55A 핚 (HANGUL SYLLABLE HAGG) 12059 0xD55B 핛 (HANGUL SYLLABLE HAGS) 12060 0xD55D 핝 (HANGUL SYLLABLE HANJ) 12061 0xD55E 핞 (HANGUL SYLLABLE HANH) 12062 0xD55F 핟 (HANGUL SYLLABLE HAD) 12063 0xD561 핡 (HANGUL SYLLABLE HALG) 12064 0xD562 핢 (HANGUL SYLLABLE HALM) 12065 0xD563 핣 (HANGUL SYLLABLE HALB) 12066 0xC6E9 웩 (HANGUL SYLLABLE WEG) 12067 0xC6EC 웬 (HANGUL SYLLABLE WEN) 12068 0xC6F0 웰 (HANGUL SYLLABLE WEL) 12069 0xC6F8 웸 (HANGUL SYLLABLE WEM) 12070 0xC6F9 웹 (HANGUL SYLLABLE WEB) 12071 0xC6FD 웽 (HANGUL SYLLABLE WENG) 12072 0xC704 위 (HANGUL SYLLABLE WI) 12073 0xC705 윅 (HANGUL SYLLABLE WIG) 12074 0xC708 윈 (HANGUL SYLLABLE WIN) 12075 0xC70C 윌 (HANGUL SYLLABLE WIL) 12076 0xC714 윔 (HANGUL SYLLABLE WIM) 12077 0xC715 윕 (HANGUL SYLLABLE WIB) 12078 0xC717 윗 (HANGUL SYLLABLE WIS) 12079 0xC719 윙 (HANGUL SYLLABLE WING) 12080 0xC720 유 (HANGUL SYLLABLE YU) 12081 0xC721 육 (HANGUL SYLLABLE YUG) 12082 0xC724 윤 (HANGUL SYLLABLE YUN) 12083 0xC728 율 (HANGUL SYLLABLE YUL) 12084 0xC730 윰 (HANGUL SYLLABLE YUM) 12085 0xC731 윱 (HANGUL SYLLABLE YUB) 12086 0xC733 윳 (HANGUL SYLLABLE YUS) 12087 0xC735 융 (HANGUL SYLLABLE YUNG) 12088 0xC737 윷 (HANGUL SYLLABLE YUC) 12089 0xC73C 으 (HANGUL SYLLABLE EU) 12090 0xC73D 윽 (HANGUL SYLLABLE EUG) 12091 0xC740 은 (HANGUL SYLLABLE EUN) 12092 0xC744 을 (HANGUL SYLLABLE EUL) 12093 0xC74A 읊 (HANGUL SYLLABLE EULP) 12094 0xC74C 음 (HANGUL SYLLABLE EUM) 12095 0xC74D 읍 (HANGUL SYLLABLE EUB) 12096 0xC74F 읏 (HANGUL SYLLABLE EUS) 12097 0xC751 응 (HANGUL SYLLABLE EUNG) 12098 0xC752 읒 (HANGUL SYLLABLE EUJ) 12099 0xC753 읓 (HANGUL SYLLABLE EUC) 12100 0xC754 읔 (HANGUL SYLLABLE EUK) 12101 0xC755 읕 (HANGUL SYLLABLE EUT) 12102 0xC756 읖 (HANGUL SYLLABLE EUP) 12103 0xC757 읗 (HANGUL SYLLABLE EUH) 12104 0xC758 의 (HANGUL SYLLABLE YI) 12105 0xC75C 읜 (HANGUL SYLLABLE YIN) 12106 0xC760 읠 (HANGUL SYLLABLE YIL) 12107 0xC768 읨 (HANGUL SYLLABLE YIM) 12108 0xC76B 읫 (HANGUL SYLLABLE YIS) 12109 0xC774 이 (HANGUL SYLLABLE I) 12110 0xC775 익 (HANGUL SYLLABLE IG) 12111 0xC778 인 (HANGUL SYLLABLE IN) 12112 0xC77C 일 (HANGUL SYLLABLE IL) 12113 0xC77D 읽 (HANGUL SYLLABLE ILG) 12114 0xC77E 읾 (HANGUL SYLLABLE ILM) 12115 0xC783 잃 (HANGUL SYLLABLE ILH) 12116 0xC784 임 (HANGUL SYLLABLE IM) 12117 0xC785 입 (HANGUL SYLLABLE IB) 12118 0xC787 잇 (HANGUL SYLLABLE IS) 12119 0xC788 있 (HANGUL SYLLABLE ISS) 12120 0xC789 잉 (HANGUL SYLLABLE ING) 12121 0xC78A 잊 (HANGUL SYLLABLE IJ) 12122 0xC78E 잎 (HANGUL SYLLABLE IP) 12123 0xC790 자 (HANGUL SYLLABLE JA) 12124 0xC791 작 (HANGUL SYLLABLE JAG) 12125 0xC794 잔 (HANGUL SYLLABLE JAN) 12126 0xC796 잖 (HANGUL SYLLABLE JANH) 12127 0xC797 잗 (HANGUL SYLLABLE JAD) 12128 0xC798 잘 (HANGUL SYLLABLE JAL) 12129 0xC79A 잚 (HANGUL SYLLABLE JALM) 12130 0xC7A0 잠 (HANGUL SYLLABLE JAM) 12131 0xC7A1 잡 (HANGUL SYLLABLE JAB) 12132 0xC7A3 잣 (HANGUL SYLLABLE JAS) 12133 0xC7A4 잤 (HANGUL SYLLABLE JASS) 12134 0xC7A5 장 (HANGUL SYLLABLE JANG) 12135 0xC7A6 잦 (HANGUL SYLLABLE JAJ) 12136 0xC7AC 재 (HANGUL SYLLABLE JAE) 12137 0xC7AD 잭 (HANGUL SYLLABLE JAEG) 12138 0xC7B0 잰 (HANGUL SYLLABLE JAEN) 12139 0xC7B4 잴 (HANGUL SYLLABLE JAEL) 12140 0xC7BC 잼 (HANGUL SYLLABLE JAEM) 12141 0xC7BD 잽 (HANGUL SYLLABLE JAEB) 12142 0xC7BF 잿 (HANGUL SYLLABLE JAES) 12143 0xC7C0 쟀 (HANGUL SYLLABLE JAESS) 12144 0xC7C1 쟁 (HANGUL SYLLABLE JAENG) 12145 0xC7C8 쟈 (HANGUL SYLLABLE JYA) 12146 0xC7C9 쟉 (HANGUL SYLLABLE JYAG) 12147 0xC7CC 쟌 (HANGUL SYLLABLE JYAN) 12148 0xC7CE 쟎 (HANGUL SYLLABLE JYANH) 12149 0xC7D0 쟐 (HANGUL SYLLABLE JYAL) 12150 0xC7D8 쟘 (HANGUL SYLLABLE JYAM) 12151 0xC7DD 쟝 (HANGUL SYLLABLE JYANG) 12152 0xC7E4 쟤 (HANGUL SYLLABLE JYAE) 12153 0xC7E8 쟨 (HANGUL SYLLABLE JYAEN) 12154 0xC7EC 쟬 (HANGUL SYLLABLE JYAEL) 12155 0xC800 저 (HANGUL SYLLABLE JEO) 12156 0xC801 적 (HANGUL SYLLABLE JEOG) 12157 0xC804 전 (HANGUL SYLLABLE JEON) 12158 0xC808 절 (HANGUL SYLLABLE JEOL) 12159 0xC80A 젊 (HANGUL SYLLABLE JEOLM) 12160 0xD564 핤 (HANGUL SYLLABLE HALS) 12161 0xD566 핦 (HANGUL SYLLABLE HALP) 12162 0xD567 핧 (HANGUL SYLLABLE HALH) 12163 0xD56A 핪 (HANGUL SYLLABLE HABS) 12164 0xD56C 핬 (HANGUL SYLLABLE HASS) 12165 0xD56E 핮 (HANGUL SYLLABLE HAJ) 12166 0xD56F 핯 (HANGUL SYLLABLE HAC) 12167 0xD570 핰 (HANGUL SYLLABLE HAK) 12168 0xD571 핱 (HANGUL SYLLABLE HAT) 12169 0xD572 핲 (HANGUL SYLLABLE HAP) 12170 0xD573 핳 (HANGUL SYLLABLE HAH) 12171 0xD576 핶 (HANGUL SYLLABLE HAEGG) 12172 0xD577 핷 (HANGUL SYLLABLE HAEGS) 12173 0xD579 핹 (HANGUL SYLLABLE HAENJ) 12174 0xD57A 핺 (HANGUL SYLLABLE HAENH) 12175 0xD57B 핻 (HANGUL SYLLABLE HAED) 12176 0xD57D 핽 (HANGUL SYLLABLE HAELG) 12177 0xD57E 핾 (HANGUL SYLLABLE HAELM) 12178 0xD57F 핿 (HANGUL SYLLABLE HAELB) 12179 0xD580 햀 (HANGUL SYLLABLE HAELS) 12180 0xD581 햁 (HANGUL SYLLABLE HAELT) 12181 0xD582 햂 (HANGUL SYLLABLE HAELP) 12182 0xD583 햃 (HANGUL SYLLABLE HAELH) 12183 0xD586 햆 (HANGUL SYLLABLE HAEBS) 12184 0xD58A 햊 (HANGUL SYLLABLE HAEJ) 12185 0xD58B 햋 (HANGUL SYLLABLE HAEC) 12192 0xD58C 햌 (HANGUL SYLLABLE HAEK) 12193 0xD58D 햍 (HANGUL SYLLABLE HAET) 12194 0xD58E 햎 (HANGUL SYLLABLE HAEP) 12195 0xD58F 햏 (HANGUL SYLLABLE HAEH) 12196 0xD591 햑 (HANGUL SYLLABLE HYAG) 12197 0xD592 햒 (HANGUL SYLLABLE HYAGG) 12198 0xD593 햓 (HANGUL SYLLABLE HYAGS) 12199 0xD594 햔 (HANGUL SYLLABLE HYAN) 12200 0xD595 햕 (HANGUL SYLLABLE HYANJ) 12201 0xD596 햖 (HANGUL SYLLABLE HYANH) 12202 0xD597 햗 (HANGUL SYLLABLE HYAD) 12203 0xD598 햘 (HANGUL SYLLABLE HYAL) 12204 0xD599 햙 (HANGUL SYLLABLE HYALG) 12205 0xD59A 햚 (HANGUL SYLLABLE HYALM) 12206 0xD59B 햛 (HANGUL SYLLABLE HYALB) 12207 0xD59C 햜 (HANGUL SYLLABLE HYALS) 12208 0xD59D 햝 (HANGUL SYLLABLE HYALT) 12209 0xD59E 햞 (HANGUL SYLLABLE HYALP) 12210 0xD59F 햟 (HANGUL SYLLABLE HYALH) 12211 0xD5A0 햠 (HANGUL SYLLABLE HYAM) 12212 0xD5A1 햡 (HANGUL SYLLABLE HYAB) 12213 0xD5A2 햢 (HANGUL SYLLABLE HYABS) 12214 0xD5A3 햣 (HANGUL SYLLABLE HYAS) 12215 0xD5A4 햤 (HANGUL SYLLABLE HYASS) 12216 0xD5A6 햦 (HANGUL SYLLABLE HYAJ) 12217 0xD5A7 햧 (HANGUL SYLLABLE HYAC) 12224 0xD5A8 햨 (HANGUL SYLLABLE HYAK) 12225 0xD5A9 햩 (HANGUL SYLLABLE HYAT) 12226 0xD5AA 햪 (HANGUL SYLLABLE HYAP) 12227 0xD5AB 햫 (HANGUL SYLLABLE HYAH) 12228 0xD5AC 햬 (HANGUL SYLLABLE HYAE) 12229 0xD5AD 햭 (HANGUL SYLLABLE HYAEG) 12230 0xD5AE 햮 (HANGUL SYLLABLE HYAEGG) 12231 0xD5AF 햯 (HANGUL SYLLABLE HYAEGS) 12232 0xD5B0 햰 (HANGUL SYLLABLE HYAEN) 12233 0xD5B1 햱 (HANGUL SYLLABLE HYAENJ) 12234 0xD5B2 햲 (HANGUL SYLLABLE HYAENH) 12235 0xD5B3 햳 (HANGUL SYLLABLE HYAED) 12236 0xD5B4 햴 (HANGUL SYLLABLE HYAEL) 12237 0xD5B5 햵 (HANGUL SYLLABLE HYAELG) 12238 0xD5B6 햶 (HANGUL SYLLABLE HYAELM) 12239 0xD5B7 햷 (HANGUL SYLLABLE HYAELB) 12240 0xD5B8 햸 (HANGUL SYLLABLE HYAELS) 12241 0xD5B9 햹 (HANGUL SYLLABLE HYAELT) 12242 0xD5BA 햺 (HANGUL SYLLABLE HYAELP) 12243 0xD5BB 햻 (HANGUL SYLLABLE HYAELH) 12244 0xD5BC 햼 (HANGUL SYLLABLE HYAEM) 12245 0xD5BD 햽 (HANGUL SYLLABLE HYAEB) 12246 0xD5BE 햾 (HANGUL SYLLABLE HYAEBS) 12247 0xD5BF 햿 (HANGUL SYLLABLE HYAES) 12248 0xD5C0 헀 (HANGUL SYLLABLE HYAESS) 12249 0xD5C1 헁 (HANGUL SYLLABLE HYAENG) 12250 0xD5C2 헂 (HANGUL SYLLABLE HYAEJ) 12251 0xD5C3 헃 (HANGUL SYLLABLE HYAEC) 12252 0xD5C4 헄 (HANGUL SYLLABLE HYAEK) 12253 0xD5C5 헅 (HANGUL SYLLABLE HYAET) 12254 0xD5C6 헆 (HANGUL SYLLABLE HYAEP) 12255 0xD5C7 헇 (HANGUL SYLLABLE HYAEH) 12256 0xC810 점 (HANGUL SYLLABLE JEOM) 12257 0xC811 접 (HANGUL SYLLABLE JEOB) 12258 0xC813 젓 (HANGUL SYLLABLE JEOS) 12259 0xC815 정 (HANGUL SYLLABLE JEONG) 12260 0xC816 젖 (HANGUL SYLLABLE JEOJ) 12261 0xC81C 제 (HANGUL SYLLABLE JE) 12262 0xC81D 젝 (HANGUL SYLLABLE JEG) 12263 0xC820 젠 (HANGUL SYLLABLE JEN) 12264 0xC824 젤 (HANGUL SYLLABLE JEL) 12265 0xC82C 젬 (HANGUL SYLLABLE JEM) 12266 0xC82D 젭 (HANGUL SYLLABLE JEB) 12267 0xC82F 젯 (HANGUL SYLLABLE JES) 12268 0xC831 젱 (HANGUL SYLLABLE JENG) 12269 0xC838 져 (HANGUL SYLLABLE JYEO) 12270 0xC83C 젼 (HANGUL SYLLABLE JYEON) 12271 0xC840 졀 (HANGUL SYLLABLE JYEOL) 12272 0xC848 졈 (HANGUL SYLLABLE JYEOM) 12273 0xC849 졉 (HANGUL SYLLABLE JYEOB) 12274 0xC84C 졌 (HANGUL SYLLABLE JYEOSS) 12275 0xC84D 졍 (HANGUL SYLLABLE JYEONG) 12276 0xC854 졔 (HANGUL SYLLABLE JYE) 12277 0xC870 조 (HANGUL SYLLABLE JO) 12278 0xC871 족 (HANGUL SYLLABLE JOG) 12279 0xC874 존 (HANGUL SYLLABLE JON) 12280 0xC878 졸 (HANGUL SYLLABLE JOL) 12281 0xC87A 졺 (HANGUL SYLLABLE JOLM) 12282 0xC880 좀 (HANGUL SYLLABLE JOM) 12283 0xC881 좁 (HANGUL SYLLABLE JOB) 12284 0xC883 좃 (HANGUL SYLLABLE JOS) 12285 0xC885 종 (HANGUL SYLLABLE JONG) 12286 0xC886 좆 (HANGUL SYLLABLE JOJ) 12287 0xC887 좇 (HANGUL SYLLABLE JOC) 12288 0xC88B 좋 (HANGUL SYLLABLE JOH) 12289 0xC88C 좌 (HANGUL SYLLABLE JWA) 12290 0xC88D 좍 (HANGUL SYLLABLE JWAG) 12291 0xC894 좔 (HANGUL SYLLABLE JWAL) 12292 0xC89D 좝 (HANGUL SYLLABLE JWAB) 12293 0xC89F 좟 (HANGUL SYLLABLE JWAS) 12294 0xC8A1 좡 (HANGUL SYLLABLE JWANG) 12295 0xC8A8 좨 (HANGUL SYLLABLE JWAE) 12296 0xC8BC 좼 (HANGUL SYLLABLE JWAESS) 12297 0xC8BD 좽 (HANGUL SYLLABLE JWAENG) 12298 0xC8C4 죄 (HANGUL SYLLABLE JOE) 12299 0xC8C8 죈 (HANGUL SYLLABLE JOEN) 12300 0xC8CC 죌 (HANGUL SYLLABLE JOEL) 12301 0xC8D4 죔 (HANGUL SYLLABLE JOEM) 12302 0xC8D5 죕 (HANGUL SYLLABLE JOEB) 12303 0xC8D7 죗 (HANGUL SYLLABLE JOES) 12304 0xC8D9 죙 (HANGUL SYLLABLE JOENG) 12305 0xC8E0 죠 (HANGUL SYLLABLE JYO) 12306 0xC8E1 죡 (HANGUL SYLLABLE JYOG) 12307 0xC8E4 죤 (HANGUL SYLLABLE JYON) 12308 0xC8F5 죵 (HANGUL SYLLABLE JYONG) 12309 0xC8FC 주 (HANGUL SYLLABLE JU) 12310 0xC8FD 죽 (HANGUL SYLLABLE JUG) 12311 0xC900 준 (HANGUL SYLLABLE JUN) 12312 0xC904 줄 (HANGUL SYLLABLE JUL) 12313 0xC905 줅 (HANGUL SYLLABLE JULG) 12314 0xC906 줆 (HANGUL SYLLABLE JULM) 12315 0xC90C 줌 (HANGUL SYLLABLE JUM) 12316 0xC90D 줍 (HANGUL SYLLABLE JUB) 12317 0xC90F 줏 (HANGUL SYLLABLE JUS) 12318 0xC911 중 (HANGUL SYLLABLE JUNG) 12319 0xC918 줘 (HANGUL SYLLABLE JWEO) 12320 0xC92C 줬 (HANGUL SYLLABLE JWEOSS) 12321 0xC934 줴 (HANGUL SYLLABLE JWE) 12322 0xC950 쥐 (HANGUL SYLLABLE JWI) 12323 0xC951 쥑 (HANGUL SYLLABLE JWIG) 12324 0xC954 쥔 (HANGUL SYLLABLE JWIN) 12325 0xC958 쥘 (HANGUL SYLLABLE JWIL) 12326 0xC960 쥠 (HANGUL SYLLABLE JWIM) 12327 0xC961 쥡 (HANGUL SYLLABLE JWIB) 12328 0xC963 쥣 (HANGUL SYLLABLE JWIS) 12329 0xC96C 쥬 (HANGUL SYLLABLE JYU) 12330 0xC970 쥰 (HANGUL SYLLABLE JYUN) 12331 0xC974 쥴 (HANGUL SYLLABLE JYUL) 12332 0xC97C 쥼 (HANGUL SYLLABLE JYUM) 12333 0xC988 즈 (HANGUL SYLLABLE JEU) 12334 0xC989 즉 (HANGUL SYLLABLE JEUG) 12335 0xC98C 즌 (HANGUL SYLLABLE JEUN) 12336 0xC990 즐 (HANGUL SYLLABLE JEUL) 12337 0xC998 즘 (HANGUL SYLLABLE JEUM) 12338 0xC999 즙 (HANGUL SYLLABLE JEUB) 12339 0xC99B 즛 (HANGUL SYLLABLE JEUS) 12340 0xC99D 증 (HANGUL SYLLABLE JEUNG) 12341 0xC9C0 지 (HANGUL SYLLABLE JI) 12342 0xC9C1 직 (HANGUL SYLLABLE JIG) 12343 0xC9C4 진 (HANGUL SYLLABLE JIN) 12344 0xC9C7 짇 (HANGUL SYLLABLE JID) 12345 0xC9C8 질 (HANGUL SYLLABLE JIL) 12346 0xC9CA 짊 (HANGUL SYLLABLE JILM) 12347 0xC9D0 짐 (HANGUL SYLLABLE JIM) 12348 0xC9D1 집 (HANGUL SYLLABLE JIB) 12349 0xC9D3 짓 (HANGUL SYLLABLE JIS) 12350 0xD5CA 헊 (HANGUL SYLLABLE HEOGG) 12351 0xD5CB 헋 (HANGUL SYLLABLE HEOGS) 12352 0xD5CD 헍 (HANGUL SYLLABLE HEONJ) 12353 0xD5CE 헎 (HANGUL SYLLABLE HEONH) 12354 0xD5CF 헏 (HANGUL SYLLABLE HEOD) 12355 0xD5D1 헑 (HANGUL SYLLABLE HEOLG) 12356 0xD5D3 헓 (HANGUL SYLLABLE HEOLB) 12357 0xD5D4 헔 (HANGUL SYLLABLE HEOLS) 12358 0xD5D5 헕 (HANGUL SYLLABLE HEOLT) 12359 0xD5D6 헖 (HANGUL SYLLABLE HEOLP) 12360 0xD5D7 헗 (HANGUL SYLLABLE HEOLH) 12361 0xD5DA 헚 (HANGUL SYLLABLE HEOBS) 12362 0xD5DC 헜 (HANGUL SYLLABLE HEOSS) 12363 0xD5DE 헞 (HANGUL SYLLABLE HEOJ) 12364 0xD5DF 헟 (HANGUL SYLLABLE HEOC) 12365 0xD5E0 헠 (HANGUL SYLLABLE HEOK) 12366 0xD5E1 헡 (HANGUL SYLLABLE HEOT) 12367 0xD5E2 헢 (HANGUL SYLLABLE HEOP) 12368 0xD5E3 헣 (HANGUL SYLLABLE HEOH) 12369 0xD5E6 헦 (HANGUL SYLLABLE HEGG) 12370 0xD5E7 헧 (HANGUL SYLLABLE HEGS) 12371 0xD5E9 헩 (HANGUL SYLLABLE HENJ) 12372 0xD5EA 헪 (HANGUL SYLLABLE HENH) 12373 0xD5EB 헫 (HANGUL SYLLABLE HED) 12374 0xD5ED 헭 (HANGUL SYLLABLE HELG) 12375 0xD5EE 헮 (HANGUL SYLLABLE HELM) 12382 0xD5EF 헯 (HANGUL SYLLABLE HELB) 12383 0xD5F0 헰 (HANGUL SYLLABLE HELS) 12384 0xD5F1 헱 (HANGUL SYLLABLE HELT) 12385 0xD5F2 헲 (HANGUL SYLLABLE HELP) 12386 0xD5F3 헳 (HANGUL SYLLABLE HELH) 12387 0xD5F6 헶 (HANGUL SYLLABLE HEBS) 12388 0xD5F8 헸 (HANGUL SYLLABLE HESS) 12389 0xD5FA 헺 (HANGUL SYLLABLE HEJ) 12390 0xD5FB 헻 (HANGUL SYLLABLE HEC) 12391 0xD5FC 헼 (HANGUL SYLLABLE HEK) 12392 0xD5FD 헽 (HANGUL SYLLABLE HET) 12393 0xD5FE 헾 (HANGUL SYLLABLE HEP) 12394 0xD5FF 헿 (HANGUL SYLLABLE HEH) 12395 0xD602 혂 (HANGUL SYLLABLE HYEOGG) 12396 0xD603 혃 (HANGUL SYLLABLE HYEOGS) 12397 0xD605 혅 (HANGUL SYLLABLE HYEONJ) 12398 0xD606 혆 (HANGUL SYLLABLE HYEONH) 12399 0xD607 혇 (HANGUL SYLLABLE HYEOD) 12400 0xD609 혉 (HANGUL SYLLABLE HYEOLG) 12401 0xD60A 혊 (HANGUL SYLLABLE HYEOLM) 12402 0xD60B 혋 (HANGUL SYLLABLE HYEOLB) 12403 0xD60C 혌 (HANGUL SYLLABLE HYEOLS) 12404 0xD60D 혍 (HANGUL SYLLABLE HYEOLT) 12405 0xD60E 혎 (HANGUL SYLLABLE HYEOLP) 12406 0xD60F 혏 (HANGUL SYLLABLE HYEOLH) 12407 0xD612 혒 (HANGUL SYLLABLE HYEOBS) 12414 0xD616 혖 (HANGUL SYLLABLE HYEOJ) 12415 0xD617 혗 (HANGUL SYLLABLE HYEOC) 12416 0xD618 혘 (HANGUL SYLLABLE HYEOK) 12417 0xD619 혙 (HANGUL SYLLABLE HYEOT) 12418 0xD61A 혚 (HANGUL SYLLABLE HYEOP) 12419 0xD61B 혛 (HANGUL SYLLABLE HYEOH) 12420 0xD61D 혝 (HANGUL SYLLABLE HYEG) 12421 0xD61E 혞 (HANGUL SYLLABLE HYEGG) 12422 0xD61F 혟 (HANGUL SYLLABLE HYEGS) 12423 0xD621 혡 (HANGUL SYLLABLE HYENJ) 12424 0xD622 혢 (HANGUL SYLLABLE HYENH) 12425 0xD623 혣 (HANGUL SYLLABLE HYED) 12426 0xD625 혥 (HANGUL SYLLABLE HYELG) 12427 0xD626 혦 (HANGUL SYLLABLE HYELM) 12428 0xD627 혧 (HANGUL SYLLABLE HYELB) 12429 0xD628 혨 (HANGUL SYLLABLE HYELS) 12430 0xD629 혩 (HANGUL SYLLABLE HYELT) 12431 0xD62A 혪 (HANGUL SYLLABLE HYELP) 12432 0xD62B 혫 (HANGUL SYLLABLE HYELH) 12433 0xD62C 혬 (HANGUL SYLLABLE HYEM) 12434 0xD62E 혮 (HANGUL SYLLABLE HYEBS) 12435 0xD62F 혯 (HANGUL SYLLABLE HYES) 12436 0xD630 혰 (HANGUL SYLLABLE HYESS) 12437 0xD631 혱 (HANGUL SYLLABLE HYENG) 12438 0xD632 혲 (HANGUL SYLLABLE HYEJ) 12439 0xD633 혳 (HANGUL SYLLABLE HYEC) 12440 0xD634 혴 (HANGUL SYLLABLE HYEK) 12441 0xD635 혵 (HANGUL SYLLABLE HYET) 12442 0xD636 혶 (HANGUL SYLLABLE HYEP) 12443 0xD637 혷 (HANGUL SYLLABLE HYEH) 12444 0xD63A 혺 (HANGUL SYLLABLE HOGG) 12445 0xD63B 혻 (HANGUL SYLLABLE HOGS) 12446 0xC9D5 징 (HANGUL SYLLABLE JING) 12447 0xC9D6 짖 (HANGUL SYLLABLE JIJ) 12448 0xC9D9 짙 (HANGUL SYLLABLE JIT) 12449 0xC9DA 짚 (HANGUL SYLLABLE JIP) 12450 0xC9DC 짜 (HANGUL SYLLABLE JJA) 12451 0xC9DD 짝 (HANGUL SYLLABLE JJAG) 12452 0xC9E0 짠 (HANGUL SYLLABLE JJAN) 12453 0xC9E2 짢 (HANGUL SYLLABLE JJANH) 12454 0xC9E4 짤 (HANGUL SYLLABLE JJAL) 12455 0xC9E7 짧 (HANGUL SYLLABLE JJALB) 12456 0xC9EC 짬 (HANGUL SYLLABLE JJAM) 12457 0xC9ED 짭 (HANGUL SYLLABLE JJAB) 12458 0xC9EF 짯 (HANGUL SYLLABLE JJAS) 12459 0xC9F0 짰 (HANGUL SYLLABLE JJASS) 12460 0xC9F1 짱 (HANGUL SYLLABLE JJANG) 12461 0xC9F8 째 (HANGUL SYLLABLE JJAE) 12462 0xC9F9 짹 (HANGUL SYLLABLE JJAEG) 12463 0xC9FC 짼 (HANGUL SYLLABLE JJAEN) 12464 0xCA00 쨀 (HANGUL SYLLABLE JJAEL) 12465 0xCA08 쨈 (HANGUL SYLLABLE JJAEM) 12466 0xCA09 쨉 (HANGUL SYLLABLE JJAEB) 12467 0xCA0B 쨋 (HANGUL SYLLABLE JJAES) 12468 0xCA0C 쨌 (HANGUL SYLLABLE JJAESS) 12469 0xCA0D 쨍 (HANGUL SYLLABLE JJAENG) 12470 0xCA14 쨔 (HANGUL SYLLABLE JJYA) 12471 0xCA18 쨘 (HANGUL SYLLABLE JJYAN) 12472 0xCA29 쨩 (HANGUL SYLLABLE JJYANG) 12473 0xCA4C 쩌 (HANGUL SYLLABLE JJEO) 12474 0xCA4D 쩍 (HANGUL SYLLABLE JJEOG) 12475 0xCA50 쩐 (HANGUL SYLLABLE JJEON) 12476 0xCA54 쩔 (HANGUL SYLLABLE JJEOL) 12477 0xCA5C 쩜 (HANGUL SYLLABLE JJEOM) 12478 0xCA5D 쩝 (HANGUL SYLLABLE JJEOB) 12479 0xCA5F 쩟 (HANGUL SYLLABLE JJEOS) 12480 0xCA60 쩠 (HANGUL SYLLABLE JJEOSS) 12481 0xCA61 쩡 (HANGUL SYLLABLE JJEONG) 12482 0xCA68 쩨 (HANGUL SYLLABLE JJE) 12483 0xCA7D 쩽 (HANGUL SYLLABLE JJENG) 12484 0xCA84 쪄 (HANGUL SYLLABLE JJYEO) 12485 0xCA98 쪘 (HANGUL SYLLABLE JJYEOSS) 12486 0xCABC 쪼 (HANGUL SYLLABLE JJO) 12487 0xCABD 쪽 (HANGUL SYLLABLE JJOG) 12488 0xCAC0 쫀 (HANGUL SYLLABLE JJON) 12489 0xCAC4 쫄 (HANGUL SYLLABLE JJOL) 12490 0xCACC 쫌 (HANGUL SYLLABLE JJOM) 12491 0xCACD 쫍 (HANGUL SYLLABLE JJOB) 12492 0xCACF 쫏 (HANGUL SYLLABLE JJOS) 12493 0xCAD1 쫑 (HANGUL SYLLABLE JJONG) 12494 0xCAD3 쫓 (HANGUL SYLLABLE JJOC) 12495 0xCAD8 쫘 (HANGUL SYLLABLE JJWA) 12496 0xCAD9 쫙 (HANGUL SYLLABLE JJWAG) 12497 0xCAE0 쫠 (HANGUL SYLLABLE JJWAL) 12498 0xCAEC 쫬 (HANGUL SYLLABLE JJWASS) 12499 0xCAF4 쫴 (HANGUL SYLLABLE JJWAE) 12500 0xCB08 쬈 (HANGUL SYLLABLE JJWAESS) 12501 0xCB10 쬐 (HANGUL SYLLABLE JJOE) 12502 0xCB14 쬔 (HANGUL SYLLABLE JJOEN) 12503 0xCB18 쬘 (HANGUL SYLLABLE JJOEL) 12504 0xCB20 쬠 (HANGUL SYLLABLE JJOEM) 12505 0xCB21 쬡 (HANGUL SYLLABLE JJOEB) 12506 0xCB41 쭁 (HANGUL SYLLABLE JJYONG) 12507 0xCB48 쭈 (HANGUL SYLLABLE JJU) 12508 0xCB49 쭉 (HANGUL SYLLABLE JJUG) 12509 0xCB4C 쭌 (HANGUL SYLLABLE JJUN) 12510 0xCB50 쭐 (HANGUL SYLLABLE JJUL) 12511 0xCB58 쭘 (HANGUL SYLLABLE JJUM) 12512 0xCB59 쭙 (HANGUL SYLLABLE JJUB) 12513 0xCB5D 쭝 (HANGUL SYLLABLE JJUNG) 12514 0xCB64 쭤 (HANGUL SYLLABLE JJWEO) 12515 0xCB78 쭸 (HANGUL SYLLABLE JJWEOSS) 12516 0xCB79 쭹 (HANGUL SYLLABLE JJWEONG) 12517 0xCB9C 쮜 (HANGUL SYLLABLE JJWI) 12518 0xCBB8 쮸 (HANGUL SYLLABLE JJYU) 12519 0xCBD4 쯔 (HANGUL SYLLABLE JJEU) 12520 0xCBE4 쯤 (HANGUL SYLLABLE JJEUM) 12521 0xCBE7 쯧 (HANGUL SYLLABLE JJEUS) 12522 0xCBE9 쯩 (HANGUL SYLLABLE JJEUNG) 12523 0xCC0C 찌 (HANGUL SYLLABLE JJI) 12524 0xCC0D 찍 (HANGUL SYLLABLE JJIG) 12525 0xCC10 찐 (HANGUL SYLLABLE JJIN) 12526 0xCC14 찔 (HANGUL SYLLABLE JJIL) 12527 0xCC1C 찜 (HANGUL SYLLABLE JJIM) 12528 0xCC1D 찝 (HANGUL SYLLABLE JJIB) 12529 0xCC21 찡 (HANGUL SYLLABLE JJING) 12530 0xCC22 찢 (HANGUL SYLLABLE JJIJ) 12531 0xCC27 찧 (HANGUL SYLLABLE JJIH) 12532 0xCC28 차 (HANGUL SYLLABLE CA) 12533 0xCC29 착 (HANGUL SYLLABLE CAG) 12534 0xCC2C 찬 (HANGUL SYLLABLE CAN) 12535 0xCC2E 찮 (HANGUL SYLLABLE CANH) 12536 0xCC30 찰 (HANGUL SYLLABLE CAL) 12537 0xCC38 참 (HANGUL SYLLABLE CAM) 12538 0xCC39 찹 (HANGUL SYLLABLE CAB) 12539 0xCC3B 찻 (HANGUL SYLLABLE CAS) 12540 0xD63D 혽 (HANGUL SYLLABLE HONJ) 12541 0xD63E 혾 (HANGUL SYLLABLE HONH) 12542 0xD63F 혿 (HANGUL SYLLABLE HOD) 12543 0xD641 홁 (HANGUL SYLLABLE HOLG) 12544 0xD642 홂 (HANGUL SYLLABLE HOLM) 12545 0xD643 홃 (HANGUL SYLLABLE HOLB) 12546 0xD644 홄 (HANGUL SYLLABLE HOLS) 12547 0xD646 홆 (HANGUL SYLLABLE HOLP) 12548 0xD647 홇 (HANGUL SYLLABLE HOLH) 12549 0xD64A 홊 (HANGUL SYLLABLE HOBS) 12550 0xD64C 홌 (HANGUL SYLLABLE HOSS) 12551 0xD64E 홎 (HANGUL SYLLABLE HOJ) 12552 0xD64F 홏 (HANGUL SYLLABLE HOC) 12553 0xD650 홐 (HANGUL SYLLABLE HOK) 12554 0xD652 홒 (HANGUL SYLLABLE HOP) 12555 0xD653 홓 (HANGUL SYLLABLE HOH) 12556 0xD656 홖 (HANGUL SYLLABLE HWAGG) 12557 0xD657 홗 (HANGUL SYLLABLE HWAGS) 12558 0xD659 홙 (HANGUL SYLLABLE HWANJ) 12559 0xD65A 홚 (HANGUL SYLLABLE HWANH) 12560 0xD65B 홛 (HANGUL SYLLABLE HWAD) 12561 0xD65D 홝 (HANGUL SYLLABLE HWALG) 12562 0xD65E 홞 (HANGUL SYLLABLE HWALM) 12563 0xD65F 홟 (HANGUL SYLLABLE HWALB) 12564 0xD660 홠 (HANGUL SYLLABLE HWALS) 12565 0xD661 홡 (HANGUL SYLLABLE HWALT) 12572 0xD662 홢 (HANGUL SYLLABLE HWALP) 12573 0xD663 홣 (HANGUL SYLLABLE HWALH) 12574 0xD664 홤 (HANGUL SYLLABLE HWAM) 12575 0xD665 홥 (HANGUL SYLLABLE HWAB) 12576 0xD666 홦 (HANGUL SYLLABLE HWABS) 12577 0xD668 홨 (HANGUL SYLLABLE HWASS) 12578 0xD66A 홪 (HANGUL SYLLABLE HWAJ) 12579 0xD66B 홫 (HANGUL SYLLABLE HWAC) 12580 0xD66C 홬 (HANGUL SYLLABLE HWAK) 12581 0xD66D 홭 (HANGUL SYLLABLE HWAT) 12582 0xD66E 홮 (HANGUL SYLLABLE HWAP) 12583 0xD66F 홯 (HANGUL SYLLABLE HWAH) 12584 0xD672 홲 (HANGUL SYLLABLE HWAEGG) 12585 0xD673 홳 (HANGUL SYLLABLE HWAEGS) 12586 0xD675 홵 (HANGUL SYLLABLE HWAENJ) 12587 0xD676 홶 (HANGUL SYLLABLE HWAENH) 12588 0xD677 홷 (HANGUL SYLLABLE HWAED) 12589 0xD678 홸 (HANGUL SYLLABLE HWAEL) 12590 0xD679 홹 (HANGUL SYLLABLE HWAELG) 12591 0xD67A 홺 (HANGUL SYLLABLE HWAELM) 12592 0xD67B 홻 (HANGUL SYLLABLE HWAELB) 12593 0xD67C 홼 (HANGUL SYLLABLE HWAELS) 12594 0xD67D 홽 (HANGUL SYLLABLE HWAELT) 12595 0xD67E 홾 (HANGUL SYLLABLE HWAELP) 12596 0xD67F 홿 (HANGUL SYLLABLE HWAELH) 12597 0xD680 횀 (HANGUL SYLLABLE HWAEM) 12604 0xD681 횁 (HANGUL SYLLABLE HWAEB) 12605 0xD682 횂 (HANGUL SYLLABLE HWAEBS) 12606 0xD684 횄 (HANGUL SYLLABLE HWAESS) 12607 0xD686 횆 (HANGUL SYLLABLE HWAEJ) 12608 0xD687 횇 (HANGUL SYLLABLE HWAEC) 12609 0xD688 횈 (HANGUL SYLLABLE HWAEK) 12610 0xD689 횉 (HANGUL SYLLABLE HWAET) 12611 0xD68A 횊 (HANGUL SYLLABLE HWAEP) 12612 0xD68B 횋 (HANGUL SYLLABLE HWAEH) 12613 0xD68E 횎 (HANGUL SYLLABLE HOEGG) 12614 0xD68F 횏 (HANGUL SYLLABLE HOEGS) 12615 0xD691 횑 (HANGUL SYLLABLE HOENJ) 12616 0xD692 횒 (HANGUL SYLLABLE HOENH) 12617 0xD693 횓 (HANGUL SYLLABLE HOED) 12618 0xD695 횕 (HANGUL SYLLABLE HOELG) 12619 0xD696 횖 (HANGUL SYLLABLE HOELM) 12620 0xD697 횗 (HANGUL SYLLABLE HOELB) 12621 0xD698 횘 (HANGUL SYLLABLE HOELS) 12622 0xD699 횙 (HANGUL SYLLABLE HOELT) 12623 0xD69A 횚 (HANGUL SYLLABLE HOELP) 12624 0xD69B 횛 (HANGUL SYLLABLE HOELH) 12625 0xD69C 횜 (HANGUL SYLLABLE HOEM) 12626 0xD69E 횞 (HANGUL SYLLABLE HOEBS) 12627 0xD6A0 횠 (HANGUL SYLLABLE HOESS) 12628 0xD6A2 횢 (HANGUL SYLLABLE HOEJ) 12629 0xD6A3 횣 (HANGUL SYLLABLE HOEC) 12630 0xD6A4 횤 (HANGUL SYLLABLE HOEK) 12631 0xD6A5 횥 (HANGUL SYLLABLE HOET) 12632 0xD6A6 횦 (HANGUL SYLLABLE HOEP) 12633 0xD6A7 횧 (HANGUL SYLLABLE HOEH) 12634 0xD6A9 횩 (HANGUL SYLLABLE HYOG) 12635 0xD6AA 횪 (HANGUL SYLLABLE HYOGG) 12636 0xCC3C 찼 (HANGUL SYLLABLE CASS) 12637 0xCC3D 창 (HANGUL SYLLABLE CANG) 12638 0xCC3E 찾 (HANGUL SYLLABLE CAJ) 12639 0xCC44 채 (HANGUL SYLLABLE CAE) 12640 0xCC45 책 (HANGUL SYLLABLE CAEG) 12641 0xCC48 챈 (HANGUL SYLLABLE CAEN) 12642 0xCC4C 챌 (HANGUL SYLLABLE CAEL) 12643 0xCC54 챔 (HANGUL SYLLABLE CAEM) 12644 0xCC55 챕 (HANGUL SYLLABLE CAEB) 12645 0xCC57 챗 (HANGUL SYLLABLE CAES) 12646 0xCC58 챘 (HANGUL SYLLABLE CAESS) 12647 0xCC59 챙 (HANGUL SYLLABLE CAENG) 12648 0xCC60 챠 (HANGUL SYLLABLE CYA) 12649 0xCC64 챤 (HANGUL SYLLABLE CYAN) 12650 0xCC66 챦 (HANGUL SYLLABLE CYANH) 12651 0xCC68 챨 (HANGUL SYLLABLE CYAL) 12652 0xCC70 챰 (HANGUL SYLLABLE CYAM) 12653 0xCC75 챵 (HANGUL SYLLABLE CYANG) 12654 0xCC98 처 (HANGUL SYLLABLE CEO) 12655 0xCC99 척 (HANGUL SYLLABLE CEOG) 12656 0xCC9C 천 (HANGUL SYLLABLE CEON) 12657 0xCCA0 철 (HANGUL SYLLABLE CEOL) 12658 0xCCA8 첨 (HANGUL SYLLABLE CEOM) 12659 0xCCA9 첩 (HANGUL SYLLABLE CEOB) 12660 0xCCAB 첫 (HANGUL SYLLABLE CEOS) 12661 0xCCAC 첬 (HANGUL SYLLABLE CEOSS) 12662 0xCCAD 청 (HANGUL SYLLABLE CEONG) 12663 0xCCB4 체 (HANGUL SYLLABLE CE) 12664 0xCCB5 첵 (HANGUL SYLLABLE CEG) 12665 0xCCB8 첸 (HANGUL SYLLABLE CEN) 12666 0xCCBC 첼 (HANGUL SYLLABLE CEL) 12667 0xCCC4 쳄 (HANGUL SYLLABLE CEM) 12668 0xCCC5 쳅 (HANGUL SYLLABLE CEB) 12669 0xCCC7 쳇 (HANGUL SYLLABLE CES) 12670 0xCCC9 쳉 (HANGUL SYLLABLE CENG) 12671 0xCCD0 쳐 (HANGUL SYLLABLE CYEO) 12672 0xCCD4 쳔 (HANGUL SYLLABLE CYEON) 12673 0xCCE4 쳤 (HANGUL SYLLABLE CYEOSS) 12674 0xCCEC 쳬 (HANGUL SYLLABLE CYE) 12675 0xCCF0 쳰 (HANGUL SYLLABLE CYEN) 12676 0xCD01 촁 (HANGUL SYLLABLE CYENG) 12677 0xCD08 초 (HANGUL SYLLABLE CO) 12678 0xCD09 촉 (HANGUL SYLLABLE COG) 12679 0xCD0C 촌 (HANGUL SYLLABLE CON) 12680 0xCD10 촐 (HANGUL SYLLABLE COL) 12681 0xCD18 촘 (HANGUL SYLLABLE COM) 12682 0xCD19 촙 (HANGUL SYLLABLE COB) 12683 0xCD1B 촛 (HANGUL SYLLABLE COS) 12684 0xCD1D 총 (HANGUL SYLLABLE CONG) 12685 0xCD24 촤 (HANGUL SYLLABLE CWA) 12686 0xCD28 촨 (HANGUL SYLLABLE CWAN) 12687 0xCD2C 촬 (HANGUL SYLLABLE CWAL) 12688 0xCD39 촹 (HANGUL SYLLABLE CWANG) 12689 0xCD5C 최 (HANGUL SYLLABLE COE) 12690 0xCD60 쵠 (HANGUL SYLLABLE COEN) 12691 0xCD64 쵤 (HANGUL SYLLABLE COEL) 12692 0xCD6C 쵬 (HANGUL SYLLABLE COEM) 12693 0xCD6D 쵭 (HANGUL SYLLABLE COEB) 12694 0xCD6F 쵯 (HANGUL SYLLABLE COES) 12695 0xCD71 쵱 (HANGUL SYLLABLE COENG) 12696 0xCD78 쵸 (HANGUL SYLLABLE CYO) 12697 0xCD88 춈 (HANGUL SYLLABLE CYOM) 12698 0xCD94 추 (HANGUL SYLLABLE CU) 12699 0xCD95 축 (HANGUL SYLLABLE CUG) 12700 0xCD98 춘 (HANGUL SYLLABLE CUN) 12701 0xCD9C 출 (HANGUL SYLLABLE CUL) 12702 0xCDA4 춤 (HANGUL SYLLABLE CUM) 12703 0xCDA5 춥 (HANGUL SYLLABLE CUB) 12704 0xCDA7 춧 (HANGUL SYLLABLE CUS) 12705 0xCDA9 충 (HANGUL SYLLABLE CUNG) 12706 0xCDB0 춰 (HANGUL SYLLABLE CWEO) 12707 0xCDC4 췄 (HANGUL SYLLABLE CWEOSS) 12708 0xCDCC 췌 (HANGUL SYLLABLE CWE) 12709 0xCDD0 췐 (HANGUL SYLLABLE CWEN) 12710 0xCDE8 취 (HANGUL SYLLABLE CWI) 12711 0xCDEC 췬 (HANGUL SYLLABLE CWIN) 12712 0xCDF0 췰 (HANGUL SYLLABLE CWIL) 12713 0xCDF8 췸 (HANGUL SYLLABLE CWIM) 12714 0xCDF9 췹 (HANGUL SYLLABLE CWIB) 12715 0xCDFB 췻 (HANGUL SYLLABLE CWIS) 12716 0xCDFD 췽 (HANGUL SYLLABLE CWING) 12717 0xCE04 츄 (HANGUL SYLLABLE CYU) 12718 0xCE08 츈 (HANGUL SYLLABLE CYUN) 12719 0xCE0C 츌 (HANGUL SYLLABLE CYUL) 12720 0xCE14 츔 (HANGUL SYLLABLE CYUM) 12721 0xCE19 츙 (HANGUL SYLLABLE CYUNG) 12722 0xCE20 츠 (HANGUL SYLLABLE CEU) 12723 0xCE21 측 (HANGUL SYLLABLE CEUG) 12724 0xCE24 츤 (HANGUL SYLLABLE CEUN) 12725 0xCE28 츨 (HANGUL SYLLABLE CEUL) 12726 0xCE30 츰 (HANGUL SYLLABLE CEUM) 12727 0xCE31 츱 (HANGUL SYLLABLE CEUB) 12728 0xCE33 츳 (HANGUL SYLLABLE CEUS) 12729 0xCE35 층 (HANGUL SYLLABLE CEUNG) 12730 0xD6AB 횫 (HANGUL SYLLABLE HYOGS) 12731 0xD6AD 횭 (HANGUL SYLLABLE HYONJ) 12732 0xD6AE 횮 (HANGUL SYLLABLE HYONH) 12733 0xD6AF 횯 (HANGUL SYLLABLE HYOD) 12734 0xD6B1 횱 (HANGUL SYLLABLE HYOLG) 12735 0xD6B2 횲 (HANGUL SYLLABLE HYOLM) 12736 0xD6B3 횳 (HANGUL SYLLABLE HYOLB) 12737 0xD6B4 횴 (HANGUL SYLLABLE HYOLS) 12738 0xD6B5 횵 (HANGUL SYLLABLE HYOLT) 12739 0xD6B6 횶 (HANGUL SYLLABLE HYOLP) 12740 0xD6B7 횷 (HANGUL SYLLABLE HYOLH) 12741 0xD6B8 횸 (HANGUL SYLLABLE HYOM) 12742 0xD6BA 횺 (HANGUL SYLLABLE HYOBS) 12743 0xD6BC 횼 (HANGUL SYLLABLE HYOSS) 12744 0xD6BD 횽 (HANGUL SYLLABLE HYONG) 12745 0xD6BE 횾 (HANGUL SYLLABLE HYOJ) 12746 0xD6BF 횿 (HANGUL SYLLABLE HYOC) 12747 0xD6C0 훀 (HANGUL SYLLABLE HYOK) 12748 0xD6C1 훁 (HANGUL SYLLABLE HYOT) 12749 0xD6C2 훂 (HANGUL SYLLABLE HYOP) 12750 0xD6C3 훃 (HANGUL SYLLABLE HYOH) 12751 0xD6C6 훆 (HANGUL SYLLABLE HUGG) 12752 0xD6C7 훇 (HANGUL SYLLABLE HUGS) 12753 0xD6C9 훉 (HANGUL SYLLABLE HUNJ) 12754 0xD6CA 훊 (HANGUL SYLLABLE HUNH) 12755 0xD6CB 훋 (HANGUL SYLLABLE HUD) 12762 0xD6CD 훍 (HANGUL SYLLABLE HULG) 12763 0xD6CE 훎 (HANGUL SYLLABLE HULM) 12764 0xD6CF 훏 (HANGUL SYLLABLE HULB) 12765 0xD6D0 훐 (HANGUL SYLLABLE HULS) 12766 0xD6D2 훒 (HANGUL SYLLABLE HULP) 12767 0xD6D3 훓 (HANGUL SYLLABLE HULH) 12768 0xD6D5 훕 (HANGUL SYLLABLE HUB) 12769 0xD6D6 훖 (HANGUL SYLLABLE HUBS) 12770 0xD6D8 훘 (HANGUL SYLLABLE HUSS) 12771 0xD6DA 훚 (HANGUL SYLLABLE HUJ) 12772 0xD6DB 훛 (HANGUL SYLLABLE HUC) 12773 0xD6DC 훜 (HANGUL SYLLABLE HUK) 12774 0xD6DD 훝 (HANGUL SYLLABLE HUT) 12775 0xD6DE 훞 (HANGUL SYLLABLE HUP) 12776 0xD6DF 훟 (HANGUL SYLLABLE HUH) 12777 0xD6E1 훡 (HANGUL SYLLABLE HWEOG) 12778 0xD6E2 훢 (HANGUL SYLLABLE HWEOGG) 12779 0xD6E3 훣 (HANGUL SYLLABLE HWEOGS) 12780 0xD6E5 훥 (HANGUL SYLLABLE HWEONJ) 12781 0xD6E6 훦 (HANGUL SYLLABLE HWEONH) 12782 0xD6E7 훧 (HANGUL SYLLABLE HWEOD) 12783 0xD6E9 훩 (HANGUL SYLLABLE HWEOLG) 12784 0xD6EA 훪 (HANGUL SYLLABLE HWEOLM) 12785 0xD6EB 훫 (HANGUL SYLLABLE HWEOLB) 12786 0xD6EC 훬 (HANGUL SYLLABLE HWEOLS) 12787 0xD6ED 훭 (HANGUL SYLLABLE HWEOLT) 12794 0xD6EE 훮 (HANGUL SYLLABLE HWEOLP) 12795 0xD6EF 훯 (HANGUL SYLLABLE HWEOLH) 12796 0xD6F1 훱 (HANGUL SYLLABLE HWEOB) 12797 0xD6F2 훲 (HANGUL SYLLABLE HWEOBS) 12798 0xD6F3 훳 (HANGUL SYLLABLE HWEOS) 12799 0xD6F4 훴 (HANGUL SYLLABLE HWEOSS) 12800 0xD6F6 훶 (HANGUL SYLLABLE HWEOJ) 12801 0xD6F7 훷 (HANGUL SYLLABLE HWEOC) 12802 0xD6F8 훸 (HANGUL SYLLABLE HWEOK) 12803 0xD6F9 훹 (HANGUL SYLLABLE HWEOT) 12804 0xD6FA 훺 (HANGUL SYLLABLE HWEOP) 12805 0xD6FB 훻 (HANGUL SYLLABLE HWEOH) 12806 0xD6FE 훾 (HANGUL SYLLABLE HWEGG) 12807 0xD6FF 훿 (HANGUL SYLLABLE HWEGS) 12808 0xD701 휁 (HANGUL SYLLABLE HWENJ) 12809 0xD702 휂 (HANGUL SYLLABLE HWENH) 12810 0xD703 휃 (HANGUL SYLLABLE HWED) 12811 0xD705 휅 (HANGUL SYLLABLE HWELG) 12812 0xD706 휆 (HANGUL SYLLABLE HWELM) 12813 0xD707 휇 (HANGUL SYLLABLE HWELB) 12814 0xD708 휈 (HANGUL SYLLABLE HWELS) 12815 0xD709 휉 (HANGUL SYLLABLE HWELT) 12816 0xD70A 휊 (HANGUL SYLLABLE HWELP) 12817 0xD70B 휋 (HANGUL SYLLABLE HWELH) 12818 0xD70C 휌 (HANGUL SYLLABLE HWEM) 12819 0xD70D 휍 (HANGUL SYLLABLE HWEB) 12820 0xD70E 휎 (HANGUL SYLLABLE HWEBS) 12821 0xD70F 휏 (HANGUL SYLLABLE HWES) 12822 0xD710 휐 (HANGUL SYLLABLE HWESS) 12823 0xD712 휒 (HANGUL SYLLABLE HWEJ) 12824 0xD713 휓 (HANGUL SYLLABLE HWEC) 12825 0xD714 휔 (HANGUL SYLLABLE HWEK) 12826 0xCE58 치 (HANGUL SYLLABLE CI) 12827 0xCE59 칙 (HANGUL SYLLABLE CIG) 12828 0xCE5C 친 (HANGUL SYLLABLE CIN) 12829 0xCE5F 칟 (HANGUL SYLLABLE CID) 12830 0xCE60 칠 (HANGUL SYLLABLE CIL) 12831 0xCE61 칡 (HANGUL SYLLABLE CILG) 12832 0xCE68 침 (HANGUL SYLLABLE CIM) 12833 0xCE69 칩 (HANGUL SYLLABLE CIB) 12834 0xCE6B 칫 (HANGUL SYLLABLE CIS) 12835 0xCE6D 칭 (HANGUL SYLLABLE CING) 12836 0xCE74 카 (HANGUL SYLLABLE KA) 12837 0xCE75 칵 (HANGUL SYLLABLE KAG) 12838 0xCE78 칸 (HANGUL SYLLABLE KAN) 12839 0xCE7C 칼 (HANGUL SYLLABLE KAL) 12840 0xCE84 캄 (HANGUL SYLLABLE KAM) 12841 0xCE85 캅 (HANGUL SYLLABLE KAB) 12842 0xCE87 캇 (HANGUL SYLLABLE KAS) 12843 0xCE89 캉 (HANGUL SYLLABLE KANG) 12844 0xCE90 캐 (HANGUL SYLLABLE KAE) 12845 0xCE91 캑 (HANGUL SYLLABLE KAEG) 12846 0xCE94 캔 (HANGUL SYLLABLE KAEN) 12847 0xCE98 캘 (HANGUL SYLLABLE KAEL) 12848 0xCEA0 캠 (HANGUL SYLLABLE KAEM) 12849 0xCEA1 캡 (HANGUL SYLLABLE KAEB) 12850 0xCEA3 캣 (HANGUL SYLLABLE KAES) 12851 0xCEA4 캤 (HANGUL SYLLABLE KAESS) 12852 0xCEA5 캥 (HANGUL SYLLABLE KAENG) 12853 0xCEAC 캬 (HANGUL SYLLABLE KYA) 12854 0xCEAD 캭 (HANGUL SYLLABLE KYAG) 12855 0xCEC1 컁 (HANGUL SYLLABLE KYANG) 12856 0xCEE4 커 (HANGUL SYLLABLE KEO) 12857 0xCEE5 컥 (HANGUL SYLLABLE KEOG) 12858 0xCEE8 컨 (HANGUL SYLLABLE KEON) 12859 0xCEEB 컫 (HANGUL SYLLABLE KEOD) 12860 0xCEEC 컬 (HANGUL SYLLABLE KEOL) 12861 0xCEF4 컴 (HANGUL SYLLABLE KEOM) 12862 0xCEF5 컵 (HANGUL SYLLABLE KEOB) 12863 0xCEF7 컷 (HANGUL SYLLABLE KEOS) 12864 0xCEF8 컸 (HANGUL SYLLABLE KEOSS) 12865 0xCEF9 컹 (HANGUL SYLLABLE KEONG) 12866 0xCF00 케 (HANGUL SYLLABLE KE) 12867 0xCF01 켁 (HANGUL SYLLABLE KEG) 12868 0xCF04 켄 (HANGUL SYLLABLE KEN) 12869 0xCF08 켈 (HANGUL SYLLABLE KEL) 12870 0xCF10 켐 (HANGUL SYLLABLE KEM) 12871 0xCF11 켑 (HANGUL SYLLABLE KEB) 12872 0xCF13 켓 (HANGUL SYLLABLE KES) 12873 0xCF15 켕 (HANGUL SYLLABLE KENG) 12874 0xCF1C 켜 (HANGUL SYLLABLE KYEO) 12875 0xCF20 켠 (HANGUL SYLLABLE KYEON) 12876 0xCF24 켤 (HANGUL SYLLABLE KYEOL) 12877 0xCF2C 켬 (HANGUL SYLLABLE KYEOM) 12878 0xCF2D 켭 (HANGUL SYLLABLE KYEOB) 12879 0xCF2F 켯 (HANGUL SYLLABLE KYEOS) 12880 0xCF30 켰 (HANGUL SYLLABLE KYEOSS) 12881 0xCF31 켱 (HANGUL SYLLABLE KYEONG) 12882 0xCF38 켸 (HANGUL SYLLABLE KYE) 12883 0xCF54 코 (HANGUL SYLLABLE KO) 12884 0xCF55 콕 (HANGUL SYLLABLE KOG) 12885 0xCF58 콘 (HANGUL SYLLABLE KON) 12886 0xCF5C 콜 (HANGUL SYLLABLE KOL) 12887 0xCF64 콤 (HANGUL SYLLABLE KOM) 12888 0xCF65 콥 (HANGUL SYLLABLE KOB) 12889 0xCF67 콧 (HANGUL SYLLABLE KOS) 12890 0xCF69 콩 (HANGUL SYLLABLE KONG) 12891 0xCF70 콰 (HANGUL SYLLABLE KWA) 12892 0xCF71 콱 (HANGUL SYLLABLE KWAG) 12893 0xCF74 콴 (HANGUL SYLLABLE KWAN) 12894 0xCF78 콸 (HANGUL SYLLABLE KWAL) 12895 0xCF80 쾀 (HANGUL SYLLABLE KWAM) 12896 0xCF85 쾅 (HANGUL SYLLABLE KWANG) 12897 0xCF8C 쾌 (HANGUL SYLLABLE KWAE) 12898 0xCFA1 쾡 (HANGUL SYLLABLE KWAENG) 12899 0xCFA8 쾨 (HANGUL SYLLABLE KOE) 12900 0xCFB0 쾰 (HANGUL SYLLABLE KOEL) 12901 0xCFC4 쿄 (HANGUL SYLLABLE KYO) 12902 0xCFE0 쿠 (HANGUL SYLLABLE KU) 12903 0xCFE1 쿡 (HANGUL SYLLABLE KUG) 12904 0xCFE4 쿤 (HANGUL SYLLABLE KUN) 12905 0xCFE8 쿨 (HANGUL SYLLABLE KUL) 12906 0xCFF0 쿰 (HANGUL SYLLABLE KUM) 12907 0xCFF1 쿱 (HANGUL SYLLABLE KUB) 12908 0xCFF3 쿳 (HANGUL SYLLABLE KUS) 12909 0xCFF5 쿵 (HANGUL SYLLABLE KUNG) 12910 0xCFFC 쿼 (HANGUL SYLLABLE KWEO) 12911 0xD000 퀀 (HANGUL SYLLABLE KWEON) 12912 0xD004 퀄 (HANGUL SYLLABLE KWEOL) 12913 0xD011 퀑 (HANGUL SYLLABLE KWEONG) 12914 0xD018 퀘 (HANGUL SYLLABLE KWE) 12915 0xD02D 퀭 (HANGUL SYLLABLE KWENG) 12916 0xD034 퀴 (HANGUL SYLLABLE KWI) 12917 0xD035 퀵 (HANGUL SYLLABLE KWIG) 12918 0xD038 퀸 (HANGUL SYLLABLE KWIN) 12919 0xD03C 퀼 (HANGUL SYLLABLE KWIL) 12920 0xD715 휕 (HANGUL SYLLABLE HWET) 12921 0xD716 휖 (HANGUL SYLLABLE HWEP) 12922 0xD717 휗 (HANGUL SYLLABLE HWEH) 12923 0xD71A 휚 (HANGUL SYLLABLE HWIGG) 12924 0xD71B 휛 (HANGUL SYLLABLE HWIGS) 12925 0xD71D 휝 (HANGUL SYLLABLE HWINJ) 12926 0xD71E 휞 (HANGUL SYLLABLE HWINH) 12927 0xD71F 휟 (HANGUL SYLLABLE HWID) 12928 0xD721 휡 (HANGUL SYLLABLE HWILG) 12929 0xD722 휢 (HANGUL SYLLABLE HWILM) 12930 0xD723 휣 (HANGUL SYLLABLE HWILB) 12931 0xD724 휤 (HANGUL SYLLABLE HWILS) 12932 0xD725 휥 (HANGUL SYLLABLE HWILT) 12933 0xD726 휦 (HANGUL SYLLABLE HWILP) 12934 0xD727 휧 (HANGUL SYLLABLE HWILH) 12935 0xD72A 휪 (HANGUL SYLLABLE HWIBS) 12936 0xD72C 휬 (HANGUL SYLLABLE HWISS) 12937 0xD72E 휮 (HANGUL SYLLABLE HWIJ) 12938 0xD72F 휯 (HANGUL SYLLABLE HWIC) 12939 0xD730 휰 (HANGUL SYLLABLE HWIK) 12940 0xD731 휱 (HANGUL SYLLABLE HWIT) 12941 0xD732 휲 (HANGUL SYLLABLE HWIP) 12942 0xD733 휳 (HANGUL SYLLABLE HWIH) 12943 0xD736 휶 (HANGUL SYLLABLE HYUGG) 12944 0xD737 휷 (HANGUL SYLLABLE HYUGS) 12945 0xD739 휹 (HANGUL SYLLABLE HYUNJ) 12952 0xD73A 휺 (HANGUL SYLLABLE HYUNH) 12953 0xD73B 휻 (HANGUL SYLLABLE HYUD) 12954 0xD73D 휽 (HANGUL SYLLABLE HYULG) 12955 0xD73E 휾 (HANGUL SYLLABLE HYULM) 12956 0xD73F 휿 (HANGUL SYLLABLE HYULB) 12957 0xD740 흀 (HANGUL SYLLABLE HYULS) 12958 0xD741 흁 (HANGUL SYLLABLE HYULT) 12959 0xD742 흂 (HANGUL SYLLABLE HYULP) 12960 0xD743 흃 (HANGUL SYLLABLE HYULH) 12961 0xD745 흅 (HANGUL SYLLABLE HYUB) 12962 0xD746 흆 (HANGUL SYLLABLE HYUBS) 12963 0xD748 흈 (HANGUL SYLLABLE HYUSS) 12964 0xD74A 흊 (HANGUL SYLLABLE HYUJ) 12965 0xD74B 흋 (HANGUL SYLLABLE HYUC) 12966 0xD74C 흌 (HANGUL SYLLABLE HYUK) 12967 0xD74D 흍 (HANGUL SYLLABLE HYUT) 12968 0xD74E 흎 (HANGUL SYLLABLE HYUP) 12969 0xD74F 흏 (HANGUL SYLLABLE HYUH) 12970 0xD752 흒 (HANGUL SYLLABLE HEUGG) 12971 0xD753 흓 (HANGUL SYLLABLE HEUGS) 12972 0xD755 흕 (HANGUL SYLLABLE HEUNJ) 12973 0xD75A 흚 (HANGUL SYLLABLE HEULM) 12974 0xD75B 흛 (HANGUL SYLLABLE HEULB) 12975 0xD75C 흜 (HANGUL SYLLABLE HEULS) 12976 0xD75D 흝 (HANGUL SYLLABLE HEULT) 12977 0xD75E 흞 (HANGUL SYLLABLE HEULP) 12984 0xD75F 흟 (HANGUL SYLLABLE HEULH) 12985 0xD762 흢 (HANGUL SYLLABLE HEUBS) 12986 0xD764 흤 (HANGUL SYLLABLE HEUSS) 12987 0xD766 흦 (HANGUL SYLLABLE HEUJ) 12988 0xD767 흧 (HANGUL SYLLABLE HEUC) 12989 0xD768 흨 (HANGUL SYLLABLE HEUK) 12990 0xD76A 흪 (HANGUL SYLLABLE HEUP) 12991 0xD76B 흫 (HANGUL SYLLABLE HEUH) 12992 0xD76D 흭 (HANGUL SYLLABLE HYIG) 12993 0xD76E 흮 (HANGUL SYLLABLE HYIGG) 12994 0xD76F 흯 (HANGUL SYLLABLE HYIGS) 12995 0xD771 흱 (HANGUL SYLLABLE HYINJ) 12996 0xD772 흲 (HANGUL SYLLABLE HYINH) 12997 0xD773 흳 (HANGUL SYLLABLE HYID) 12998 0xD775 흵 (HANGUL SYLLABLE HYILG) 12999 0xD776 흶 (HANGUL SYLLABLE HYILM) 13000 0xD777 흷 (HANGUL SYLLABLE HYILB) 13001 0xD778 흸 (HANGUL SYLLABLE HYILS) 13002 0xD779 흹 (HANGUL SYLLABLE HYILT) 13003 0xD77A 흺 (HANGUL SYLLABLE HYILP) 13004 0xD77B 흻 (HANGUL SYLLABLE HYILH) 13005 0xD77E 흾 (HANGUL SYLLABLE HYIBS) 13006 0xD77F 흿 (HANGUL SYLLABLE HYIS) 13007 0xD780 힀 (HANGUL SYLLABLE HYISS) 13008 0xD782 힂 (HANGUL SYLLABLE HYIJ) 13009 0xD783 힃 (HANGUL SYLLABLE HYIC) 13010 0xD784 힄 (HANGUL SYLLABLE HYIK) 13011 0xD785 힅 (HANGUL SYLLABLE HYIT) 13012 0xD786 힆 (HANGUL SYLLABLE HYIP) 13013 0xD787 힇 (HANGUL SYLLABLE HYIH) 13014 0xD78A 힊 (HANGUL SYLLABLE HIGG) 13015 0xD78B 힋 (HANGUL SYLLABLE HIGS) 13016 0xD044 큄 (HANGUL SYLLABLE KWIM) 13017 0xD045 큅 (HANGUL SYLLABLE KWIB) 13018 0xD047 큇 (HANGUL SYLLABLE KWIS) 13019 0xD049 큉 (HANGUL SYLLABLE KWING) 13020 0xD050 큐 (HANGUL SYLLABLE KYU) 13021 0xD054 큔 (HANGUL SYLLABLE KYUN) 13022 0xD058 큘 (HANGUL SYLLABLE KYUL) 13023 0xD060 큠 (HANGUL SYLLABLE KYUM) 13024 0xD06C 크 (HANGUL SYLLABLE KEU) 13025 0xD06D 큭 (HANGUL SYLLABLE KEUG) 13026 0xD070 큰 (HANGUL SYLLABLE KEUN) 13027 0xD074 클 (HANGUL SYLLABLE KEUL) 13028 0xD07C 큼 (HANGUL SYLLABLE KEUM) 13029 0xD07D 큽 (HANGUL SYLLABLE KEUB) 13030 0xD081 킁 (HANGUL SYLLABLE KEUNG) 13031 0xD0A4 키 (HANGUL SYLLABLE KI) 13032 0xD0A5 킥 (HANGUL SYLLABLE KIG) 13033 0xD0A8 킨 (HANGUL SYLLABLE KIN) 13034 0xD0AC 킬 (HANGUL SYLLABLE KIL) 13035 0xD0B4 킴 (HANGUL SYLLABLE KIM) 13036 0xD0B5 킵 (HANGUL SYLLABLE KIB) 13037 0xD0B7 킷 (HANGUL SYLLABLE KIS) 13038 0xD0B9 킹 (HANGUL SYLLABLE KING) 13039 0xD0C0 타 (HANGUL SYLLABLE TA) 13040 0xD0C1 탁 (HANGUL SYLLABLE TAG) 13041 0xD0C4 탄 (HANGUL SYLLABLE TAN) 13042 0xD0C8 탈 (HANGUL SYLLABLE TAL) 13043 0xD0C9 탉 (HANGUL SYLLABLE TALG) 13044 0xD0D0 탐 (HANGUL SYLLABLE TAM) 13045 0xD0D1 탑 (HANGUL SYLLABLE TAB) 13046 0xD0D3 탓 (HANGUL SYLLABLE TAS) 13047 0xD0D4 탔 (HANGUL SYLLABLE TASS) 13048 0xD0D5 탕 (HANGUL SYLLABLE TANG) 13049 0xD0DC 태 (HANGUL SYLLABLE TAE) 13050 0xD0DD 택 (HANGUL SYLLABLE TAEG) 13051 0xD0E0 탠 (HANGUL SYLLABLE TAEN) 13052 0xD0E4 탤 (HANGUL SYLLABLE TAEL) 13053 0xD0EC 탬 (HANGUL SYLLABLE TAEM) 13054 0xD0ED 탭 (HANGUL SYLLABLE TAEB) 13055 0xD0EF 탯 (HANGUL SYLLABLE TAES) 13056 0xD0F0 탰 (HANGUL SYLLABLE TAESS) 13057 0xD0F1 탱 (HANGUL SYLLABLE TAENG) 13058 0xD0F8 탸 (HANGUL SYLLABLE TYA) 13059 0xD10D 턍 (HANGUL SYLLABLE TYANG) 13060 0xD130 터 (HANGUL SYLLABLE TEO) 13061 0xD131 턱 (HANGUL SYLLABLE TEOG) 13062 0xD134 턴 (HANGUL SYLLABLE TEON) 13063 0xD138 털 (HANGUL SYLLABLE TEOL) 13064 0xD13A 턺 (HANGUL SYLLABLE TEOLM) 13065 0xD140 텀 (HANGUL SYLLABLE TEOM) 13066 0xD141 텁 (HANGUL SYLLABLE TEOB) 13067 0xD143 텃 (HANGUL SYLLABLE TEOS) 13068 0xD144 텄 (HANGUL SYLLABLE TEOSS) 13069 0xD145 텅 (HANGUL SYLLABLE TEONG) 13070 0xD14C 테 (HANGUL SYLLABLE TE) 13071 0xD14D 텍 (HANGUL SYLLABLE TEG) 13072 0xD150 텐 (HANGUL SYLLABLE TEN) 13073 0xD154 텔 (HANGUL SYLLABLE TEL) 13074 0xD15C 템 (HANGUL SYLLABLE TEM) 13075 0xD15D 텝 (HANGUL SYLLABLE TEB) 13076 0xD15F 텟 (HANGUL SYLLABLE TES) 13077 0xD161 텡 (HANGUL SYLLABLE TENG) 13078 0xD168 텨 (HANGUL SYLLABLE TYEO) 13079 0xD16C 텬 (HANGUL SYLLABLE TYEON) 13080 0xD17C 텼 (HANGUL SYLLABLE TYEOSS) 13081 0xD184 톄 (HANGUL SYLLABLE TYE) 13082 0xD188 톈 (HANGUL SYLLABLE TYEN) 13083 0xD1A0 토 (HANGUL SYLLABLE TO) 13084 0xD1A1 톡 (HANGUL SYLLABLE TOG) 13085 0xD1A4 톤 (HANGUL SYLLABLE TON) 13086 0xD1A8 톨 (HANGUL SYLLABLE TOL) 13087 0xD1B0 톰 (HANGUL SYLLABLE TOM) 13088 0xD1B1 톱 (HANGUL SYLLABLE TOB) 13089 0xD1B3 톳 (HANGUL SYLLABLE TOS) 13090 0xD1B5 통 (HANGUL SYLLABLE TONG) 13091 0xD1BA 톺 (HANGUL SYLLABLE TOP) 13092 0xD1BC 톼 (HANGUL SYLLABLE TWA) 13093 0xD1C0 퇀 (HANGUL SYLLABLE TWAN) 13094 0xD1D8 퇘 (HANGUL SYLLABLE TWAE) 13095 0xD1F4 퇴 (HANGUL SYLLABLE TOE) 13096 0xD1F8 퇸 (HANGUL SYLLABLE TOEN) 13097 0xD207 툇 (HANGUL SYLLABLE TOES) 13098 0xD209 툉 (HANGUL SYLLABLE TOENG) 13099 0xD210 툐 (HANGUL SYLLABLE TYO) 13100 0xD22C 투 (HANGUL SYLLABLE TU) 13101 0xD22D 툭 (HANGUL SYLLABLE TUG) 13102 0xD230 툰 (HANGUL SYLLABLE TUN) 13103 0xD234 툴 (HANGUL SYLLABLE TUL) 13104 0xD23C 툼 (HANGUL SYLLABLE TUM) 13105 0xD23D 툽 (HANGUL SYLLABLE TUB) 13106 0xD23F 툿 (HANGUL SYLLABLE TUS) 13107 0xD241 퉁 (HANGUL SYLLABLE TUNG) 13108 0xD248 퉈 (HANGUL SYLLABLE TWEO) 13109 0xD25C 퉜 (HANGUL SYLLABLE TWEOSS) 13110 0xD78D 힍 (HANGUL SYLLABLE HINJ) 13111 0xD78E 힎 (HANGUL SYLLABLE HINH) 13112 0xD78F 힏 (HANGUL SYLLABLE HID) 13113 0xD791 힑 (HANGUL SYLLABLE HILG) 13114 0xD792 힒 (HANGUL SYLLABLE HILM) 13115 0xD793 힓 (HANGUL SYLLABLE HILB) 13116 0xD794 힔 (HANGUL SYLLABLE HILS) 13117 0xD795 힕 (HANGUL SYLLABLE HILT) 13118 0xD796 힖 (HANGUL SYLLABLE HILP) 13119 0xD797 힗 (HANGUL SYLLABLE HILH) 13120 0xD79A 힚 (HANGUL SYLLABLE HIBS) 13121 0xD79C 힜 (HANGUL SYLLABLE HISS) 13122 0xD79E 힞 (HANGUL SYLLABLE HIJ) 13123 0xD79F 힟 (HANGUL SYLLABLE HIC) 13124 0xD7A0 힠 (HANGUL SYLLABLE HIK) 13125 0xD7A1 힡 (HANGUL SYLLABLE HIT) 13126 0xD7A2 힢 (HANGUL SYLLABLE HIP) 13127 0xD7A3 힣 (HANGUL SYLLABLE HIH) 13206 0xD264 퉤 (HANGUL SYLLABLE TWE) 13207 0xD280 튀 (HANGUL SYLLABLE TWI) 13208 0xD281 튁 (HANGUL SYLLABLE TWIG) 13209 0xD284 튄 (HANGUL SYLLABLE TWIN) 13210 0xD288 튈 (HANGUL SYLLABLE TWIL) 13211 0xD290 튐 (HANGUL SYLLABLE TWIM) 13212 0xD291 튑 (HANGUL SYLLABLE TWIB) 13213 0xD295 튕 (HANGUL SYLLABLE TWING) 13214 0xD29C 튜 (HANGUL SYLLABLE TYU) 13215 0xD2A0 튠 (HANGUL SYLLABLE TYUN) 13216 0xD2A4 튤 (HANGUL SYLLABLE TYUL) 13217 0xD2AC 튬 (HANGUL SYLLABLE TYUM) 13218 0xD2B1 튱 (HANGUL SYLLABLE TYUNG) 13219 0xD2B8 트 (HANGUL SYLLABLE TEU) 13220 0xD2B9 특 (HANGUL SYLLABLE TEUG) 13221 0xD2BC 튼 (HANGUL SYLLABLE TEUN) 13222 0xD2BF 튿 (HANGUL SYLLABLE TEUD) 13223 0xD2C0 틀 (HANGUL SYLLABLE TEUL) 13224 0xD2C2 틂 (HANGUL SYLLABLE TEULM) 13225 0xD2C8 틈 (HANGUL SYLLABLE TEUM) 13226 0xD2C9 틉 (HANGUL SYLLABLE TEUB) 13227 0xD2CB 틋 (HANGUL SYLLABLE TEUS) 13228 0xD2D4 틔 (HANGUL SYLLABLE TYI) 13229 0xD2D8 틘 (HANGUL SYLLABLE TYIN) 13230 0xD2DC 틜 (HANGUL SYLLABLE TYIL) 13231 0xD2E4 틤 (HANGUL SYLLABLE TYIM) 13232 0xD2E5 틥 (HANGUL SYLLABLE TYIB) 13233 0xD2F0 티 (HANGUL SYLLABLE TI) 13234 0xD2F1 틱 (HANGUL SYLLABLE TIG) 13235 0xD2F4 틴 (HANGUL SYLLABLE TIN) 13236 0xD2F8 틸 (HANGUL SYLLABLE TIL) 13237 0xD300 팀 (HANGUL SYLLABLE TIM) 13238 0xD301 팁 (HANGUL SYLLABLE TIB) 13239 0xD303 팃 (HANGUL SYLLABLE TIS) 13240 0xD305 팅 (HANGUL SYLLABLE TING) 13241 0xD30C 파 (HANGUL SYLLABLE PA) 13242 0xD30D 팍 (HANGUL SYLLABLE PAG) 13243 0xD30E 팎 (HANGUL SYLLABLE PAGG) 13244 0xD310 판 (HANGUL SYLLABLE PAN) 13245 0xD314 팔 (HANGUL SYLLABLE PAL) 13246 0xD316 팖 (HANGUL SYLLABLE PALM) 13247 0xD31C 팜 (HANGUL SYLLABLE PAM) 13248 0xD31D 팝 (HANGUL SYLLABLE PAB) 13249 0xD31F 팟 (HANGUL SYLLABLE PAS) 13250 0xD320 팠 (HANGUL SYLLABLE PASS) 13251 0xD321 팡 (HANGUL SYLLABLE PANG) 13252 0xD325 팥 (HANGUL SYLLABLE PAT) 13253 0xD328 패 (HANGUL SYLLABLE PAE) 13254 0xD329 팩 (HANGUL SYLLABLE PAEG) 13255 0xD32C 팬 (HANGUL SYLLABLE PAEN) 13256 0xD330 팰 (HANGUL SYLLABLE PAEL) 13257 0xD338 팸 (HANGUL SYLLABLE PAEM) 13258 0xD339 팹 (HANGUL SYLLABLE PAEB) 13259 0xD33B 팻 (HANGUL SYLLABLE PAES) 13260 0xD33C 팼 (HANGUL SYLLABLE PAESS) 13261 0xD33D 팽 (HANGUL SYLLABLE PAENG) 13262 0xD344 퍄 (HANGUL SYLLABLE PYA) 13263 0xD345 퍅 (HANGUL SYLLABLE PYAG) 13264 0xD37C 퍼 (HANGUL SYLLABLE PEO) 13265 0xD37D 퍽 (HANGUL SYLLABLE PEOG) 13266 0xD380 펀 (HANGUL SYLLABLE PEON) 13267 0xD384 펄 (HANGUL SYLLABLE PEOL) 13268 0xD38C 펌 (HANGUL SYLLABLE PEOM) 13269 0xD38D 펍 (HANGUL SYLLABLE PEOB) 13270 0xD38F 펏 (HANGUL SYLLABLE PEOS) 13271 0xD390 펐 (HANGUL SYLLABLE PEOSS) 13272 0xD391 펑 (HANGUL SYLLABLE PEONG) 13273 0xD398 페 (HANGUL SYLLABLE PE) 13274 0xD399 펙 (HANGUL SYLLABLE PEG) 13275 0xD39C 펜 (HANGUL SYLLABLE PEN) 13276 0xD3A0 펠 (HANGUL SYLLABLE PEL) 13277 0xD3A8 펨 (HANGUL SYLLABLE PEM) 13278 0xD3A9 펩 (HANGUL SYLLABLE PEB) 13279 0xD3AB 펫 (HANGUL SYLLABLE PES) 13280 0xD3AD 펭 (HANGUL SYLLABLE PENG) 13281 0xD3B4 펴 (HANGUL SYLLABLE PYEO) 13282 0xD3B8 편 (HANGUL SYLLABLE PYEON) 13283 0xD3BC 펼 (HANGUL SYLLABLE PYEOL) 13284 0xD3C4 폄 (HANGUL SYLLABLE PYEOM) 13285 0xD3C5 폅 (HANGUL SYLLABLE PYEOB) 13286 0xD3C8 폈 (HANGUL SYLLABLE PYEOSS) 13287 0xD3C9 평 (HANGUL SYLLABLE PYEONG) 13288 0xD3D0 폐 (HANGUL SYLLABLE PYE) 13289 0xD3D8 폘 (HANGUL SYLLABLE PYEL) 13290 0xD3E1 폡 (HANGUL SYLLABLE PYEB) 13291 0xD3E3 폣 (HANGUL SYLLABLE PYES) 13292 0xD3EC 포 (HANGUL SYLLABLE PO) 13293 0xD3ED 폭 (HANGUL SYLLABLE POG) 13294 0xD3F0 폰 (HANGUL SYLLABLE PON) 13295 0xD3F4 폴 (HANGUL SYLLABLE POL) 13296 0xD3FC 폼 (HANGUL SYLLABLE POM) 13297 0xD3FD 폽 (HANGUL SYLLABLE POB) 13298 0xD3FF 폿 (HANGUL SYLLABLE POS) 13299 0xD401 퐁 (HANGUL SYLLABLE PONG) 13396 0xD408 퐈 (HANGUL SYLLABLE PWA) 13397 0xD41D 퐝 (HANGUL SYLLABLE PWANG) 13398 0xD440 푀 (HANGUL SYLLABLE POE) 13399 0xD444 푄 (HANGUL SYLLABLE POEN) 13400 0xD45C 표 (HANGUL SYLLABLE PYO) 13401 0xD460 푠 (HANGUL SYLLABLE PYON) 13402 0xD464 푤 (HANGUL SYLLABLE PYOL) 13403 0xD46D 푭 (HANGUL SYLLABLE PYOB) 13404 0xD46F 푯 (HANGUL SYLLABLE PYOS) 13405 0xD478 푸 (HANGUL SYLLABLE PU) 13406 0xD479 푹 (HANGUL SYLLABLE PUG) 13407 0xD47C 푼 (HANGUL SYLLABLE PUN) 13408 0xD47F 푿 (HANGUL SYLLABLE PUD) 13409 0xD480 풀 (HANGUL SYLLABLE PUL) 13410 0xD482 풂 (HANGUL SYLLABLE PULM) 13411 0xD488 품 (HANGUL SYLLABLE PUM) 13412 0xD489 풉 (HANGUL SYLLABLE PUB) 13413 0xD48B 풋 (HANGUL SYLLABLE PUS) 13414 0xD48D 풍 (HANGUL SYLLABLE PUNG) 13415 0xD494 풔 (HANGUL SYLLABLE PWEO) 13416 0xD4A9 풩 (HANGUL SYLLABLE PWEONG) 13417 0xD4CC 퓌 (HANGUL SYLLABLE PWI) 13418 0xD4D0 퓐 (HANGUL SYLLABLE PWIN) 13419 0xD4D4 퓔 (HANGUL SYLLABLE PWIL) 13420 0xD4DC 퓜 (HANGUL SYLLABLE PWIM) 13421 0xD4DF 퓟 (HANGUL SYLLABLE PWIS) 13422 0xD4E8 퓨 (HANGUL SYLLABLE PYU) 13423 0xD4EC 퓬 (HANGUL SYLLABLE PYUN) 13424 0xD4F0 퓰 (HANGUL SYLLABLE PYUL) 13425 0xD4F8 퓸 (HANGUL SYLLABLE PYUM) 13426 0xD4FB 퓻 (HANGUL SYLLABLE PYUS) 13427 0xD4FD 퓽 (HANGUL SYLLABLE PYUNG) 13428 0xD504 프 (HANGUL SYLLABLE PEU) 13429 0xD508 픈 (HANGUL SYLLABLE PEUN) 13430 0xD50C 플 (HANGUL SYLLABLE PEUL) 13431 0xD514 픔 (HANGUL SYLLABLE PEUM) 13432 0xD515 픕 (HANGUL SYLLABLE PEUB) 13433 0xD517 픗 (HANGUL SYLLABLE PEUS) 13434 0xD53C 피 (HANGUL SYLLABLE PI) 13435 0xD53D 픽 (HANGUL SYLLABLE PIG) 13436 0xD540 핀 (HANGUL SYLLABLE PIN) 13437 0xD544 필 (HANGUL SYLLABLE PIL) 13438 0xD54C 핌 (HANGUL SYLLABLE PIM) 13439 0xD54D 핍 (HANGUL SYLLABLE PIB) 13440 0xD54F 핏 (HANGUL SYLLABLE PIS) 13441 0xD551 핑 (HANGUL SYLLABLE PING) 13442 0xD558 하 (HANGUL SYLLABLE HA) 13443 0xD559 학 (HANGUL SYLLABLE HAG) 13444 0xD55C 한 (HANGUL SYLLABLE HAN) 13445 0xD560 할 (HANGUL SYLLABLE HAL) 13446 0xD565 핥 (HANGUL SYLLABLE HALT) 13447 0xD568 함 (HANGUL SYLLABLE HAM) 13448 0xD569 합 (HANGUL SYLLABLE HAB) 13449 0xD56B 핫 (HANGUL SYLLABLE HAS) 13450 0xD56D 항 (HANGUL SYLLABLE HANG) 13451 0xD574 해 (HANGUL SYLLABLE HAE) 13452 0xD575 핵 (HANGUL SYLLABLE HAEG) 13453 0xD578 핸 (HANGUL SYLLABLE HAEN) 13454 0xD57C 핼 (HANGUL SYLLABLE HAEL) 13455 0xD584 햄 (HANGUL SYLLABLE HAEM) 13456 0xD585 햅 (HANGUL SYLLABLE HAEB) 13457 0xD587 햇 (HANGUL SYLLABLE HAES) 13458 0xD588 했 (HANGUL SYLLABLE HAESS) 13459 0xD589 행 (HANGUL SYLLABLE HAENG) 13460 0xD590 햐 (HANGUL SYLLABLE HYA) 13461 0xD5A5 향 (HANGUL SYLLABLE HYANG) 13462 0xD5C8 허 (HANGUL SYLLABLE HEO) 13463 0xD5C9 헉 (HANGUL SYLLABLE HEOG) 13464 0xD5CC 헌 (HANGUL SYLLABLE HEON) 13465 0xD5D0 헐 (HANGUL SYLLABLE HEOL) 13466 0xD5D2 헒 (HANGUL SYLLABLE HEOLM) 13467 0xD5D8 험 (HANGUL SYLLABLE HEOM) 13468 0xD5D9 헙 (HANGUL SYLLABLE HEOB) 13469 0xD5DB 헛 (HANGUL SYLLABLE HEOS) 13470 0xD5DD 헝 (HANGUL SYLLABLE HEONG) 13471 0xD5E4 헤 (HANGUL SYLLABLE HE) 13472 0xD5E5 헥 (HANGUL SYLLABLE HEG) 13473 0xD5E8 헨 (HANGUL SYLLABLE HEN) 13474 0xD5EC 헬 (HANGUL SYLLABLE HEL) 13475 0xD5F4 헴 (HANGUL SYLLABLE HEM) 13476 0xD5F5 헵 (HANGUL SYLLABLE HEB) 13477 0xD5F7 헷 (HANGUL SYLLABLE HES) 13478 0xD5F9 헹 (HANGUL SYLLABLE HENG) 13479 0xD600 혀 (HANGUL SYLLABLE HYEO) 13480 0xD601 혁 (HANGUL SYLLABLE HYEOG) 13481 0xD604 현 (HANGUL SYLLABLE HYEON) 13482 0xD608 혈 (HANGUL SYLLABLE HYEOL) 13483 0xD610 혐 (HANGUL SYLLABLE HYEOM) 13484 0xD611 협 (HANGUL SYLLABLE HYEOB) 13485 0xD613 혓 (HANGUL SYLLABLE HYEOS) 13486 0xD614 혔 (HANGUL SYLLABLE HYEOSS) 13487 0xD615 형 (HANGUL SYLLABLE HYEONG) 13488 0xD61C 혜 (HANGUL SYLLABLE HYE) 13489 0xD620 혠 (HANGUL SYLLABLE HYEN) 13586 0xD624 혤 (HANGUL SYLLABLE HYEL) 13587 0xD62D 혭 (HANGUL SYLLABLE HYEB) 13588 0xD638 호 (HANGUL SYLLABLE HO) 13589 0xD639 혹 (HANGUL SYLLABLE HOG) 13590 0xD63C 혼 (HANGUL SYLLABLE HON) 13591 0xD640 홀 (HANGUL SYLLABLE HOL) 13592 0xD645 홅 (HANGUL SYLLABLE HOLT) 13593 0xD648 홈 (HANGUL SYLLABLE HOM) 13594 0xD649 홉 (HANGUL SYLLABLE HOB) 13595 0xD64B 홋 (HANGUL SYLLABLE HOS) 13596 0xD64D 홍 (HANGUL SYLLABLE HONG) 13597 0xD651 홑 (HANGUL SYLLABLE HOT) 13598 0xD654 화 (HANGUL SYLLABLE HWA) 13599 0xD655 확 (HANGUL SYLLABLE HWAG) 13600 0xD658 환 (HANGUL SYLLABLE HWAN) 13601 0xD65C 활 (HANGUL SYLLABLE HWAL) 13602 0xD667 홧 (HANGUL SYLLABLE HWAS) 13603 0xD669 황 (HANGUL SYLLABLE HWANG) 13604 0xD670 홰 (HANGUL SYLLABLE HWAE) 13605 0xD671 홱 (HANGUL SYLLABLE HWAEG) 13606 0xD674 홴 (HANGUL SYLLABLE HWAEN) 13607 0xD683 횃 (HANGUL SYLLABLE HWAES) 13608 0xD685 횅 (HANGUL SYLLABLE HWAENG) 13609 0xD68C 회 (HANGUL SYLLABLE HOE) 13610 0xD68D 획 (HANGUL SYLLABLE HOEG) 13611 0xD690 횐 (HANGUL SYLLABLE HOEN) 13612 0xD694 횔 (HANGUL SYLLABLE HOEL) 13613 0xD69D 횝 (HANGUL SYLLABLE HOEB) 13614 0xD69F 횟 (HANGUL SYLLABLE HOES) 13615 0xD6A1 횡 (HANGUL SYLLABLE HOENG) 13616 0xD6A8 효 (HANGUL SYLLABLE HYO) 13617 0xD6AC 횬 (HANGUL SYLLABLE HYON) 13618 0xD6B0 횰 (HANGUL SYLLABLE HYOL) 13619 0xD6B9 횹 (HANGUL SYLLABLE HYOB) 13620 0xD6BB 횻 (HANGUL SYLLABLE HYOS) 13621 0xD6C4 후 (HANGUL SYLLABLE HU) 13622 0xD6C5 훅 (HANGUL SYLLABLE HUG) 13623 0xD6C8 훈 (HANGUL SYLLABLE HUN) 13624 0xD6CC 훌 (HANGUL SYLLABLE HUL) 13625 0xD6D1 훑 (HANGUL SYLLABLE HULT) 13626 0xD6D4 훔 (HANGUL SYLLABLE HUM) 13627 0xD6D7 훗 (HANGUL SYLLABLE HUS) 13628 0xD6D9 훙 (HANGUL SYLLABLE HUNG) 13629 0xD6E0 훠 (HANGUL SYLLABLE HWEO) 13630 0xD6E4 훤 (HANGUL SYLLABLE HWEON) 13631 0xD6E8 훨 (HANGUL SYLLABLE HWEOL) 13632 0xD6F0 훰 (HANGUL SYLLABLE HWEOM) 13633 0xD6F5 훵 (HANGUL SYLLABLE HWEONG) 13634 0xD6FC 훼 (HANGUL SYLLABLE HWE) 13635 0xD6FD 훽 (HANGUL SYLLABLE HWEG) 13636 0xD700 휀 (HANGUL SYLLABLE HWEN) 13637 0xD704 휄 (HANGUL SYLLABLE HWEL) 13638 0xD711 휑 (HANGUL SYLLABLE HWENG) 13639 0xD718 휘 (HANGUL SYLLABLE HWI) 13640 0xD719 휙 (HANGUL SYLLABLE HWIG) 13641 0xD71C 휜 (HANGUL SYLLABLE HWIN) 13642 0xD720 휠 (HANGUL SYLLABLE HWIL) 13643 0xD728 휨 (HANGUL SYLLABLE HWIM) 13644 0xD729 휩 (HANGUL SYLLABLE HWIB) 13645 0xD72B 휫 (HANGUL SYLLABLE HWIS) 13646 0xD72D 휭 (HANGUL SYLLABLE HWING) 13647 0xD734 휴 (HANGUL SYLLABLE HYU) 13648 0xD735 휵 (HANGUL SYLLABLE HYUG) 13649 0xD738 휸 (HANGUL SYLLABLE HYUN) 13650 0xD73C 휼 (HANGUL SYLLABLE HYUL) 13651 0xD744 흄 (HANGUL SYLLABLE HYUM) 13652 0xD747 흇 (HANGUL SYLLABLE HYUS) 13653 0xD749 흉 (HANGUL SYLLABLE HYUNG) 13654 0xD750 흐 (HANGUL SYLLABLE HEU) 13655 0xD751 흑 (HANGUL SYLLABLE HEUG) 13656 0xD754 흔 (HANGUL SYLLABLE HEUN) 13657 0xD756 흖 (HANGUL SYLLABLE HEUNH) 13658 0xD757 흗 (HANGUL SYLLABLE HEUD) 13659 0xD758 흘 (HANGUL SYLLABLE HEUL) 13660 0xD759 흙 (HANGUL SYLLABLE HEULG) 13661 0xD760 흠 (HANGUL SYLLABLE HEUM) 13662 0xD761 흡 (HANGUL SYLLABLE HEUB) 13663 0xD763 흣 (HANGUL SYLLABLE HEUS) 13664 0xD765 흥 (HANGUL SYLLABLE HEUNG) 13665 0xD769 흩 (HANGUL SYLLABLE HEUT) 13666 0xD76C 희 (HANGUL SYLLABLE HYI) 13667 0xD770 흰 (HANGUL SYLLABLE HYIN) 13668 0xD774 흴 (HANGUL SYLLABLE HYIL) 13669 0xD77C 흼 (HANGUL SYLLABLE HYIM) 13670 0xD77D 흽 (HANGUL SYLLABLE HYIB) 13671 0xD781 힁 (HANGUL SYLLABLE HYING) 13672 0xD788 히 (HANGUL SYLLABLE HI) 13673 0xD789 힉 (HANGUL SYLLABLE HIG) 13674 0xD78C 힌 (HANGUL SYLLABLE HIN) 13675 0xD790 힐 (HANGUL SYLLABLE HIL) 13676 0xD798 힘 (HANGUL SYLLABLE HIM) 13677 0xD799 힙 (HANGUL SYLLABLE HIB) 13678 0xD79B 힛 (HANGUL SYLLABLE HIS) 13679 0xD79D 힝 (HANGUL SYLLABLE HING) 13966 0x4F3D 伽 (<CJK Ideograph>) 13967 0x4F73 佳 (<CJK Ideograph>) 13968 0x5047 假 (<CJK Ideograph>) 13969 0x50F9 價 (<CJK Ideograph>) 13970 0x52A0 加 (<CJK Ideograph>) 13971 0x53EF 可 (<CJK Ideograph>) 13972 0x5475 呵 (<CJK Ideograph>) 13973 0x54E5 哥 (<CJK Ideograph>) 13974 0x5609 嘉 (<CJK Ideograph>) 13975 0x5AC1 嫁 (<CJK Ideograph>) 13976 0x5BB6 家 (<CJK Ideograph>) 13977 0x6687 暇 (<CJK Ideograph>) 13978 0x67B6 架 (<CJK Ideograph>) 13979 0x67B7 枷 (<CJK Ideograph>) 13980 0x67EF 柯 (<CJK Ideograph>) 13981 0x6B4C 歌 (<CJK Ideograph>) 13982 0x73C2 珂 (<CJK Ideograph>) 13983 0x75C2 痂 (<CJK Ideograph>) 13984 0x7A3C 稼 (<CJK Ideograph>) 13985 0x82DB 苛 (<CJK Ideograph>) 13986 0x8304 茄 (<CJK Ideograph>) 13987 0x8857 街 (<CJK Ideograph>) 13988 0x8888 袈 (<CJK Ideograph>) 13989 0x8A36 訶 (<CJK Ideograph>) 13990 0x8CC8 賈 (<CJK Ideograph>) 13991 0x8DCF 跏 (<CJK Ideograph>) 13992 0x8EFB 軻 (<CJK Ideograph>) 13993 0x8FE6 迦 (<CJK Ideograph>) 13994 0x99D5 駕 (<CJK Ideograph>) 13995 0x523B 刻 (<CJK Ideograph>) 13996 0x5374 却 (<CJK Ideograph>) 13997 0x5404 各 (<CJK Ideograph>) 13998 0x606A 恪 (<CJK Ideograph>) 13999 0x6164 慤 (<CJK Ideograph>) 14000 0x6BBC 殼 (<CJK Ideograph>) 14001 0x73CF 珏 (<CJK Ideograph>) 14002 0x811A 脚 (<CJK Ideograph>) 14003 0x89BA 覺 (<CJK Ideograph>) 14004 0x89D2 角 (<CJK Ideograph>) 14005 0x95A3 閣 (<CJK Ideograph>) 14006 0x4F83 侃 (<CJK Ideograph>) 14007 0x520A 刊 (<CJK Ideograph>) 14008 0x58BE 墾 (<CJK Ideograph>) 14009 0x5978 奸 (<CJK Ideograph>) 14010 0x59E6 姦 (<CJK Ideograph>) 14011 0x5E72 干 (<CJK Ideograph>) 14012 0x5E79 幹 (<CJK Ideograph>) 14013 0x61C7 懇 (<CJK Ideograph>) 14014 0x63C0 揀 (<CJK Ideograph>) 14015 0x6746 杆 (<CJK Ideograph>) 14016 0x67EC 柬 (<CJK Ideograph>) 14017 0x687F 桿 (<CJK Ideograph>) 14018 0x6F97 澗 (<CJK Ideograph>) 14019 0x764E 癎 (<CJK Ideograph>) 14020 0x770B 看 (<CJK Ideograph>) 14021 0x78F5 磵 (<CJK Ideograph>) 14022 0x7A08 稈 (<CJK Ideograph>) 14023 0x7AFF 竿 (<CJK Ideograph>) 14024 0x7C21 簡 (<CJK Ideograph>) 14025 0x809D 肝 (<CJK Ideograph>) 14026 0x826E 艮 (<CJK Ideograph>) 14027 0x8271 艱 (<CJK Ideograph>) 14028 0x8AEB 諫 (<CJK Ideograph>) 14029 0x9593 間 (<CJK Ideograph>) 14030 0x4E6B 乫 (<CJK Ideograph>) 14031 0x559D 喝 (<CJK Ideograph>) 14032 0x66F7 曷 (<CJK Ideograph>) 14033 0x6E34 渴 (<CJK Ideograph>) 14034 0x78A3 碣 (<CJK Ideograph>) 14035 0x7AED 竭 (<CJK Ideograph>) 14036 0x845B 葛 (<CJK Ideograph>) 14037 0x8910 褐 (<CJK Ideograph>) 14038 0x874E 蝎 (<CJK Ideograph>) 14039 0x97A8 鞨 (<CJK Ideograph>) 14040 0x52D8 勘 (<CJK Ideograph>) 14041 0x574E 坎 (<CJK Ideograph>) 14042 0x582A 堪 (<CJK Ideograph>) 14043 0x5D4C 嵌 (<CJK Ideograph>) 14044 0x611F 感 (<CJK Ideograph>) 14045 0x61BE 憾 (<CJK Ideograph>) 14046 0x6221 戡 (<CJK Ideograph>) 14047 0x6562 敢 (<CJK Ideograph>) 14048 0x67D1 柑 (<CJK Ideograph>) 14049 0x6A44 橄 (<CJK Ideograph>) 14050 0x6E1B 減 (<CJK Ideograph>) 14051 0x7518 甘 (<CJK Ideograph>) 14052 0x75B3 疳 (<CJK Ideograph>) 14053 0x76E3 監 (<CJK Ideograph>) 14054 0x77B0 瞰 (<CJK Ideograph>) 14055 0x7D3A 紺 (<CJK Ideograph>) 14056 0x90AF 邯 (<CJK Ideograph>) 14057 0x9451 鑑 (<CJK Ideograph>) 14058 0x9452 鑒 (<CJK Ideograph>) 14059 0x9F95 龕 (<CJK Ideograph>) 14156 0x5323 匣 (<CJK Ideograph>) 14157 0x5CAC 岬 (<CJK Ideograph>) 14158 0x7532 甲 (<CJK Ideograph>) 14159 0x80DB 胛 (<CJK Ideograph>) 14160 0x9240 鉀 (<CJK Ideograph>) 14161 0x9598 閘 (<CJK Ideograph>) 14162 0x525B 剛 (<CJK Ideograph>) 14163 0x5808 堈 (<CJK Ideograph>) 14164 0x59DC 姜 (<CJK Ideograph>) 14165 0x5CA1 岡 (<CJK Ideograph>) 14166 0x5D17 崗 (<CJK Ideograph>) 14167 0x5EB7 康 (<CJK Ideograph>) 14168 0x5F3A 强 (<CJK Ideograph>) 14169 0x5F4A 彊 (<CJK Ideograph>) 14170 0x6177 慷 (<CJK Ideograph>) 14171 0x6C5F 江 (<CJK Ideograph>) 14172 0x757A 畺 (<CJK Ideograph>) 14173 0x7586 疆 (<CJK Ideograph>) 14174 0x7CE0 糠 (<CJK Ideograph>) 14175 0x7D73 絳 (<CJK Ideograph>) 14176 0x7DB1 綱 (<CJK Ideograph>) 14177 0x7F8C 羌 (<CJK Ideograph>) 14178 0x8154 腔 (<CJK Ideograph>) 14179 0x8221 舡 (<CJK Ideograph>) 14180 0x8591 薑 (<CJK Ideograph>) 14181 0x8941 襁 (<CJK Ideograph>) 14182 0x8B1B 講 (<CJK Ideograph>) 14183 0x92FC 鋼 (<CJK Ideograph>) 14184 0x964D 降 (<CJK Ideograph>) 14185 0x9C47 鱇 (<CJK Ideograph>) 14186 0x4ECB 介 (<CJK Ideograph>) 14187 0x4EF7 价 (<CJK Ideograph>) 14188 0x500B 個 (<CJK Ideograph>) 14189 0x51F1 凱 (<CJK Ideograph>) 14190 0x584F 塏 (<CJK Ideograph>) 14191 0x6137 愷 (<CJK Ideograph>) 14192 0x613E 愾 (<CJK Ideograph>) 14193 0x6168 慨 (<CJK Ideograph>) 14194 0x6539 改 (<CJK Ideograph>) 14195 0x69EA 槪 (<CJK Ideograph>) 14196 0x6F11 漑 (<CJK Ideograph>) 14197 0x75A5 疥 (<CJK Ideograph>) 14198 0x7686 皆 (<CJK Ideograph>) 14199 0x76D6 盖 (<CJK Ideograph>) 14200 0x7B87 箇 (<CJK Ideograph>) 14201 0x82A5 芥 (<CJK Ideograph>) 14202 0x84CB 蓋 (<CJK Ideograph>) 14203 0xF900 豈 (CJK COMPATIBILITY IDEOGRAPH-F900) 14204 0x93A7 鎧 (<CJK Ideograph>) 14205 0x958B 開 (<CJK Ideograph>) 14206 0x5580 喀 (<CJK Ideograph>) 14207 0x5BA2 客 (<CJK Ideograph>) 14208 0x5751 坑 (<CJK Ideograph>) 14209 0xF901 更 (CJK COMPATIBILITY IDEOGRAPH-F901) 14210 0x7CB3 粳 (<CJK Ideograph>) 14211 0x7FB9 羹 (<CJK Ideograph>) 14212 0x91B5 醵 (<CJK Ideograph>) 14213 0x5028 倨 (<CJK Ideograph>) 14214 0x53BB 去 (<CJK Ideograph>) 14215 0x5C45 居 (<CJK Ideograph>) 14216 0x5DE8 巨 (<CJK Ideograph>) 14217 0x62D2 拒 (<CJK Ideograph>) 14218 0x636E 据 (<CJK Ideograph>) 14219 0x64DA 據 (<CJK Ideograph>) 14220 0x64E7 擧 (<CJK Ideograph>) 14221 0x6E20 渠 (<CJK Ideograph>) 14222 0x70AC 炬 (<CJK Ideograph>) 14223 0x795B 祛 (<CJK Ideograph>) 14224 0x8DDD 距 (<CJK Ideograph>) 14225 0x8E1E 踞 (<CJK Ideograph>) 14226 0xF902 車 (CJK COMPATIBILITY IDEOGRAPH-F902) 14227 0x907D 遽 (<CJK Ideograph>) 14228 0x9245 鉅 (<CJK Ideograph>) 14229 0x92F8 鋸 (<CJK Ideograph>) 14230 0x4E7E 乾 (<CJK Ideograph>) 14231 0x4EF6 件 (<CJK Ideograph>) 14232 0x5065 健 (<CJK Ideograph>) 14233 0x5DFE 巾 (<CJK Ideograph>) 14234 0x5EFA 建 (<CJK Ideograph>) 14235 0x6106 愆 (<CJK Ideograph>) 14236 0x6957 楗 (<CJK Ideograph>) 14237 0x8171 腱 (<CJK Ideograph>) 14238 0x8654 虔 (<CJK Ideograph>) 14239 0x8E47 蹇 (<CJK Ideograph>) 14240 0x9375 鍵 (<CJK Ideograph>) 14241 0x9A2B 騫 (<CJK Ideograph>) 14242 0x4E5E 乞 (<CJK Ideograph>) 14243 0x5091 傑 (<CJK Ideograph>) 14244 0x6770 杰 (<CJK Ideograph>) 14245 0x6840 桀 (<CJK Ideograph>) 14246 0x5109 儉 (<CJK Ideograph>) 14247 0x528D 劍 (<CJK Ideograph>) 14248 0x5292 劒 (<CJK Ideograph>) 14249 0x6AA2 檢 (<CJK Ideograph>) 14346 0x77BC 瞼 (<CJK Ideograph>) 14347 0x9210 鈐 (<CJK Ideograph>) 14348 0x9ED4 黔 (<CJK Ideograph>) 14349 0x52AB 劫 (<CJK Ideograph>) 14350 0x602F 怯 (<CJK Ideograph>) 14351 0x8FF2 迲 (<CJK Ideograph>) 14352 0x5048 偈 (<CJK Ideograph>) 14353 0x61A9 憩 (<CJK Ideograph>) 14354 0x63ED 揭 (<CJK Ideograph>) 14355 0x64CA 擊 (<CJK Ideograph>) 14356 0x683C 格 (<CJK Ideograph>) 14357 0x6A84 檄 (<CJK Ideograph>) 14358 0x6FC0 激 (<CJK Ideograph>) 14359 0x8188 膈 (<CJK Ideograph>) 14360 0x89A1 覡 (<CJK Ideograph>) 14361 0x9694 隔 (<CJK Ideograph>) 14362 0x5805 堅 (<CJK Ideograph>) 14363 0x727D 牽 (<CJK Ideograph>) 14364 0x72AC 犬 (<CJK Ideograph>) 14365 0x7504 甄 (<CJK Ideograph>) 14366 0x7D79 絹 (<CJK Ideograph>) 14367 0x7E6D 繭 (<CJK Ideograph>) 14368 0x80A9 肩 (<CJK Ideograph>) 14369 0x898B 見 (<CJK Ideograph>) 14370 0x8B74 譴 (<CJK Ideograph>) 14371 0x9063 遣 (<CJK Ideograph>) 14372 0x9D51 鵑 (<CJK Ideograph>) 14373 0x6289 抉 (<CJK Ideograph>) 14374 0x6C7A 決 (<CJK Ideograph>) 14375 0x6F54 潔 (<CJK Ideograph>) 14376 0x7D50 結 (<CJK Ideograph>) 14377 0x7F3A 缺 (<CJK Ideograph>) 14378 0x8A23 訣 (<CJK Ideograph>) 14379 0x517C 兼 (<CJK Ideograph>) 14380 0x614A 慊 (<CJK Ideograph>) 14381 0x7B9D 箝 (<CJK Ideograph>) 14382 0x8B19 謙 (<CJK Ideograph>) 14383 0x9257 鉗 (<CJK Ideograph>) 14384 0x938C 鎌 (<CJK Ideograph>) 14385 0x4EAC 京 (<CJK Ideograph>) 14386 0x4FD3 俓 (<CJK Ideograph>) 14387 0x501E 倞 (<CJK Ideograph>) 14388 0x50BE 傾 (<CJK Ideograph>) 14389 0x5106 儆 (<CJK Ideograph>) 14390 0x52C1 勁 (<CJK Ideograph>) 14391 0x52CD 勍 (<CJK Ideograph>) 14392 0x537F 卿 (<CJK Ideograph>) 14393 0x5770 坰 (<CJK Ideograph>) 14394 0x5883 境 (<CJK Ideograph>) 14395 0x5E9A 庚 (<CJK Ideograph>) 14396 0x5F91 徑 (<CJK Ideograph>) 14397 0x6176 慶 (<CJK Ideograph>) 14398 0x61AC 憬 (<CJK Ideograph>) 14399 0x64CE 擎 (<CJK Ideograph>) 14400 0x656C 敬 (<CJK Ideograph>) 14401 0x666F 景 (<CJK Ideograph>) 14402 0x66BB 暻 (<CJK Ideograph>) 14403 0x66F4 更 (<CJK Ideograph>) 14404 0x6897 梗 (<CJK Ideograph>) 14405 0x6D87 涇 (<CJK Ideograph>) 14406 0x7085 炅 (<CJK Ideograph>) 14407 0x70F1 烱 (<CJK Ideograph>) 14408 0x749F 璟 (<CJK Ideograph>) 14409 0x74A5 璥 (<CJK Ideograph>) 14410 0x74CA 瓊 (<CJK Ideograph>) 14411 0x75D9 痙 (<CJK Ideograph>) 14412 0x786C 硬 (<CJK Ideograph>) 14413 0x78EC 磬 (<CJK Ideograph>) 14414 0x7ADF 竟 (<CJK Ideograph>) 14415 0x7AF6 競 (<CJK Ideograph>) 14416 0x7D45 絅 (<CJK Ideograph>) 14417 0x7D93 經 (<CJK Ideograph>) 14418 0x8015 耕 (<CJK Ideograph>) 14419 0x803F 耿 (<CJK Ideograph>) 14420 0x811B 脛 (<CJK Ideograph>) 14421 0x8396 莖 (<CJK Ideograph>) 14422 0x8B66 警 (<CJK Ideograph>) 14423 0x8F15 輕 (<CJK Ideograph>) 14424 0x9015 逕 (<CJK Ideograph>) 14425 0x93E1 鏡 (<CJK Ideograph>) 14426 0x9803 頃 (<CJK Ideograph>) 14427 0x9838 頸 (<CJK Ideograph>) 14428 0x9A5A 驚 (<CJK Ideograph>) 14429 0x9BE8 鯨 (<CJK Ideograph>) 14430 0x4FC2 係 (<CJK Ideograph>) 14431 0x5553 啓 (<CJK Ideograph>) 14432 0x583A 堺 (<CJK Ideograph>) 14433 0x5951 契 (<CJK Ideograph>) 14434 0x5B63 季 (<CJK Ideograph>) 14435 0x5C46 屆 (<CJK Ideograph>) 14436 0x60B8 悸 (<CJK Ideograph>) 14437 0x6212 戒 (<CJK Ideograph>) 14438 0x6842 桂 (<CJK Ideograph>) 14439 0x68B0 械 (<CJK Ideograph>) 14536 0x68E8 棨 (<CJK Ideograph>) 14537 0x6EAA 溪 (<CJK Ideograph>) 14538 0x754C 界 (<CJK Ideograph>) 14539 0x7678 癸 (<CJK Ideograph>) 14540 0x78CE 磎 (<CJK Ideograph>) 14541 0x7A3D 稽 (<CJK Ideograph>) 14542 0x7CFB 系 (<CJK Ideograph>) 14543 0x7E6B 繫 (<CJK Ideograph>) 14544 0x7E7C 繼 (<CJK Ideograph>) 14545 0x8A08 計 (<CJK Ideograph>) 14546 0x8AA1 誡 (<CJK Ideograph>) 14547 0x8C3F 谿 (<CJK Ideograph>) 14548 0x968E 階 (<CJK Ideograph>) 14549 0x9DC4 鷄 (<CJK Ideograph>) 14550 0x53E4 古 (<CJK Ideograph>) 14551 0x53E9 叩 (<CJK Ideograph>) 14552 0x544A 告 (<CJK Ideograph>) 14553 0x5471 呱 (<CJK Ideograph>) 14554 0x56FA 固 (<CJK Ideograph>) 14555 0x59D1 姑 (<CJK Ideograph>) 14556 0x5B64 孤 (<CJK Ideograph>) 14557 0x5C3B 尻 (<CJK Ideograph>) 14558 0x5EAB 庫 (<CJK Ideograph>) 14559 0x62F7 拷 (<CJK Ideograph>) 14560 0x6537 攷 (<CJK Ideograph>) 14561 0x6545 故 (<CJK Ideograph>) 14562 0x6572 敲 (<CJK Ideograph>) 14563 0x66A0 暠 (<CJK Ideograph>) 14564 0x67AF 枯 (<CJK Ideograph>) 14565 0x69C1 槁 (<CJK Ideograph>) 14566 0x6CBD 沽 (<CJK Ideograph>) 14567 0x75FC 痼 (<CJK Ideograph>) 14568 0x7690 皐 (<CJK Ideograph>) 14569 0x777E 睾 (<CJK Ideograph>) 14570 0x7A3F 稿 (<CJK Ideograph>) 14571 0x7F94 羔 (<CJK Ideograph>) 14572 0x8003 考 (<CJK Ideograph>) 14573 0x80A1 股 (<CJK Ideograph>) 14574 0x818F 膏 (<CJK Ideograph>) 14575 0x82E6 苦 (<CJK Ideograph>) 14576 0x82FD 苽 (<CJK Ideograph>) 14577 0x83F0 菰 (<CJK Ideograph>) 14578 0x85C1 藁 (<CJK Ideograph>) 14579 0x8831 蠱 (<CJK Ideograph>) 14580 0x88B4 袴 (<CJK Ideograph>) 14581 0x8AA5 誥 (<CJK Ideograph>) 14582 0xF903 賈 (CJK COMPATIBILITY IDEOGRAPH-F903) 14583 0x8F9C 辜 (<CJK Ideograph>) 14584 0x932E 錮 (<CJK Ideograph>) 14585 0x96C7 雇 (<CJK Ideograph>) 14586 0x9867 顧 (<CJK Ideograph>) 14587 0x9AD8 高 (<CJK Ideograph>) 14588 0x9F13 鼓 (<CJK Ideograph>) 14589 0x54ED 哭 (<CJK Ideograph>) 14590 0x659B 斛 (<CJK Ideograph>) 14591 0x66F2 曲 (<CJK Ideograph>) 14592 0x688F 梏 (<CJK Ideograph>) 14593 0x7A40 穀 (<CJK Ideograph>) 14594 0x8C37 谷 (<CJK Ideograph>) 14595 0x9D60 鵠 (<CJK Ideograph>) 14596 0x56F0 困 (<CJK Ideograph>) 14597 0x5764 坤 (<CJK Ideograph>) 14598 0x5D11 崑 (<CJK Ideograph>) 14599 0x6606 昆 (<CJK Ideograph>) 14600 0x68B1 梱 (<CJK Ideograph>) 14601 0x68CD 棍 (<CJK Ideograph>) 14602 0x6EFE 滾 (<CJK Ideograph>) 14603 0x7428 琨 (<CJK Ideograph>) 14604 0x889E 袞 (<CJK Ideograph>) 14605 0x9BE4 鯤 (<CJK Ideograph>) 14606 0x6C68 汨 (<CJK Ideograph>) 14607 0xF904 滑 (CJK COMPATIBILITY IDEOGRAPH-F904) 14608 0x9AA8 骨 (<CJK Ideograph>) 14609 0x4F9B 供 (<CJK Ideograph>) 14610 0x516C 公 (<CJK Ideograph>) 14611 0x5171 共 (<CJK Ideograph>) 14612 0x529F 功 (<CJK Ideograph>) 14613 0x5B54 孔 (<CJK Ideograph>) 14614 0x5DE5 工 (<CJK Ideograph>) 14615 0x6050 恐 (<CJK Ideograph>) 14616 0x606D 恭 (<CJK Ideograph>) 14617 0x62F1 拱 (<CJK Ideograph>) 14618 0x63A7 控 (<CJK Ideograph>) 14619 0x653B 攻 (<CJK Ideograph>) 14620 0x73D9 珙 (<CJK Ideograph>) 14621 0x7A7A 空 (<CJK Ideograph>) 14622 0x86A3 蚣 (<CJK Ideograph>) 14623 0x8CA2 貢 (<CJK Ideograph>) 14624 0x978F 鞏 (<CJK Ideograph>) 14625 0x4E32 串 (<CJK Ideograph>) 14626 0x5BE1 寡 (<CJK Ideograph>) 14627 0x6208 戈 (<CJK Ideograph>) 14628 0x679C 果 (<CJK Ideograph>) 14629 0x74DC 瓜 (<CJK Ideograph>) 14726 0x79D1 科 (<CJK Ideograph>) 14727 0x83D3 菓 (<CJK Ideograph>) 14728 0x8A87 誇 (<CJK Ideograph>) 14729 0x8AB2 課 (<CJK Ideograph>) 14730 0x8DE8 跨 (<CJK Ideograph>) 14731 0x904E 過 (<CJK Ideograph>) 14732 0x934B 鍋 (<CJK Ideograph>) 14733 0x9846 顆 (<CJK Ideograph>) 14734 0x5ED3 廓 (<CJK Ideograph>) 14735 0x69E8 槨 (<CJK Ideograph>) 14736 0x85FF 藿 (<CJK Ideograph>) 14737 0x90ED 郭 (<CJK Ideograph>) 14738 0xF905 串 (CJK COMPATIBILITY IDEOGRAPH-F905) 14739 0x51A0 冠 (<CJK Ideograph>) 14740 0x5B98 官 (<CJK Ideograph>) 14741 0x5BEC 寬 (<CJK Ideograph>) 14742 0x6163 慣 (<CJK Ideograph>) 14743 0x68FA 棺 (<CJK Ideograph>) 14744 0x6B3E 款 (<CJK Ideograph>) 14745 0x704C 灌 (<CJK Ideograph>) 14746 0x742F 琯 (<CJK Ideograph>) 14747 0x74D8 瓘 (<CJK Ideograph>) 14748 0x7BA1 管 (<CJK Ideograph>) 14749 0x7F50 罐 (<CJK Ideograph>) 14750 0x83C5 菅 (<CJK Ideograph>) 14751 0x89C0 觀 (<CJK Ideograph>) 14752 0x8CAB 貫 (<CJK Ideograph>) 14753 0x95DC 關 (<CJK Ideograph>) 14754 0x9928 館 (<CJK Ideograph>) 14755 0x522E 刮 (<CJK Ideograph>) 14756 0x605D 恝 (<CJK Ideograph>) 14757 0x62EC 括 (<CJK Ideograph>) 14758 0x9002 适 (<CJK Ideograph>) 14759 0x4F8A 侊 (<CJK Ideograph>) 14760 0x5149 光 (<CJK Ideograph>) 14761 0x5321 匡 (<CJK Ideograph>) 14762 0x58D9 壙 (<CJK Ideograph>) 14763 0x5EE3 廣 (<CJK Ideograph>) 14764 0x66E0 曠 (<CJK Ideograph>) 14765 0x6D38 洸 (<CJK Ideograph>) 14766 0x709A 炚 (<CJK Ideograph>) 14767 0x72C2 狂 (<CJK Ideograph>) 14768 0x73D6 珖 (<CJK Ideograph>) 14769 0x7B50 筐 (<CJK Ideograph>) 14770 0x80F1 胱 (<CJK Ideograph>) 14771 0x945B 鑛 (<CJK Ideograph>) 14772 0x5366 卦 (<CJK Ideograph>) 14773 0x639B 掛 (<CJK Ideograph>) 14774 0x7F6B 罫 (<CJK Ideograph>) 14775 0x4E56 乖 (<CJK Ideograph>) 14776 0x5080 傀 (<CJK Ideograph>) 14777 0x584A 塊 (<CJK Ideograph>) 14778 0x58DE 壞 (<CJK Ideograph>) 14779 0x602A 怪 (<CJK Ideograph>) 14780 0x6127 愧 (<CJK Ideograph>) 14781 0x62D0 拐 (<CJK Ideograph>) 14782 0x69D0 槐 (<CJK Ideograph>) 14783 0x9B41 魁 (<CJK Ideograph>) 14784 0x5B8F 宏 (<CJK Ideograph>) 14785 0x7D18 紘 (<CJK Ideograph>) 14786 0x80B1 肱 (<CJK Ideograph>) 14787 0x8F5F 轟 (<CJK Ideograph>) 14788 0x4EA4 交 (<CJK Ideograph>) 14789 0x50D1 僑 (<CJK Ideograph>) 14790 0x54AC 咬 (<CJK Ideograph>) 14791 0x55AC 喬 (<CJK Ideograph>) 14792 0x5B0C 嬌 (<CJK Ideograph>) 14793 0x5DA0 嶠 (<CJK Ideograph>) 14794 0x5DE7 巧 (<CJK Ideograph>) 14795 0x652A 攪 (<CJK Ideograph>) 14796 0x654E 敎 (<CJK Ideograph>) 14797 0x6821 校 (<CJK Ideograph>) 14798 0x6A4B 橋 (<CJK Ideograph>) 14799 0x72E1 狡 (<CJK Ideograph>) 14800 0x768E 皎 (<CJK Ideograph>) 14801 0x77EF 矯 (<CJK Ideograph>) 14802 0x7D5E 絞 (<CJK Ideograph>) 14803 0x7FF9 翹 (<CJK Ideograph>) 14804 0x81A0 膠 (<CJK Ideograph>) 14805 0x854E 蕎 (<CJK Ideograph>) 14806 0x86DF 蛟 (<CJK Ideograph>) 14807 0x8F03 較 (<CJK Ideograph>) 14808 0x8F4E 轎 (<CJK Ideograph>) 14809 0x90CA 郊 (<CJK Ideograph>) 14810 0x9903 餃 (<CJK Ideograph>) 14811 0x9A55 驕 (<CJK Ideograph>) 14812 0x9BAB 鮫 (<CJK Ideograph>) 14813 0x4E18 丘 (<CJK Ideograph>) 14814 0x4E45 久 (<CJK Ideograph>) 14815 0x4E5D 九 (<CJK Ideograph>) 14816 0x4EC7 仇 (<CJK Ideograph>) 14817 0x4FF1 俱 (<CJK Ideograph>) 14818 0x5177 具 (<CJK Ideograph>) 14819 0x52FE 勾 (<CJK Ideograph>) 14916 0x5340 區 (<CJK Ideograph>) 14917 0x53E3 口 (<CJK Ideograph>) 14918 0x53E5 句 (<CJK Ideograph>) 14919 0x548E 咎 (<CJK Ideograph>) 14920 0x5614 嘔 (<CJK Ideograph>) 14921 0x5775 坵 (<CJK Ideograph>) 14922 0x57A2 垢 (<CJK Ideograph>) 14923 0x5BC7 寇 (<CJK Ideograph>) 14924 0x5D87 嶇 (<CJK Ideograph>) 14925 0x5ED0 廐 (<CJK Ideograph>) 14926 0x61FC 懼 (<CJK Ideograph>) 14927 0x62D8 拘 (<CJK Ideograph>) 14928 0x6551 救 (<CJK Ideograph>) 14929 0x67B8 枸 (<CJK Ideograph>) 14930 0x67E9 柩 (<CJK Ideograph>) 14931 0x69CB 構 (<CJK Ideograph>) 14932 0x6B50 歐 (<CJK Ideograph>) 14933 0x6BC6 毆 (<CJK Ideograph>) 14934 0x6BEC 毬 (<CJK Ideograph>) 14935 0x6C42 求 (<CJK Ideograph>) 14936 0x6E9D 溝 (<CJK Ideograph>) 14937 0x7078 灸 (<CJK Ideograph>) 14938 0x72D7 狗 (<CJK Ideograph>) 14939 0x7396 玖 (<CJK Ideograph>) 14940 0x7403 球 (<CJK Ideograph>) 14941 0x77BF 瞿 (<CJK Ideograph>) 14942 0x77E9 矩 (<CJK Ideograph>) 14943 0x7A76 究 (<CJK Ideograph>) 14944 0x7D7F 絿 (<CJK Ideograph>) 14945 0x8009 耉 (<CJK Ideograph>) 14946 0x81FC 臼 (<CJK Ideograph>) 14947 0x8205 舅 (<CJK Ideograph>) 14948 0x820A 舊 (<CJK Ideograph>) 14949 0x82DF 苟 (<CJK Ideograph>) 14950 0x8862 衢 (<CJK Ideograph>) 14951 0x8B33 謳 (<CJK Ideograph>) 14952 0x8CFC 購 (<CJK Ideograph>) 14953 0x8EC0 軀 (<CJK Ideograph>) 14954 0x9011 逑 (<CJK Ideograph>) 14955 0x90B1 邱 (<CJK Ideograph>) 14956 0x9264 鉤 (<CJK Ideograph>) 14957 0x92B6 銶 (<CJK Ideograph>) 14958 0x99D2 駒 (<CJK Ideograph>) 14959 0x9A45 驅 (<CJK Ideograph>) 14960 0x9CE9 鳩 (<CJK Ideograph>) 14961 0x9DD7 鷗 (<CJK Ideograph>) 14962 0x9F9C 龜 (<CJK Ideograph>) 14963 0x570B 國 (<CJK Ideograph>) 14964 0x5C40 局 (<CJK Ideograph>) 14965 0x83CA 菊 (<CJK Ideograph>) 14966 0x97A0 鞠 (<CJK Ideograph>) 14967 0x97AB 鞫 (<CJK Ideograph>) 14968 0x9EB4 麴 (<CJK Ideograph>) 14969 0x541B 君 (<CJK Ideograph>) 14970 0x7A98 窘 (<CJK Ideograph>) 14971 0x7FA4 群 (<CJK Ideograph>) 14972 0x88D9 裙 (<CJK Ideograph>) 14973 0x8ECD 軍 (<CJK Ideograph>) 14974 0x90E1 郡 (<CJK Ideograph>) 14975 0x5800 堀 (<CJK Ideograph>) 14976 0x5C48 屈 (<CJK Ideograph>) 14977 0x6398 掘 (<CJK Ideograph>) 14978 0x7A9F 窟 (<CJK Ideograph>) 14979 0x5BAE 宮 (<CJK Ideograph>) 14980 0x5F13 弓 (<CJK Ideograph>) 14981 0x7A79 穹 (<CJK Ideograph>) 14982 0x7AAE 窮 (<CJK Ideograph>) 14983 0x828E 芎 (<CJK Ideograph>) 14984 0x8EAC 躬 (<CJK Ideograph>) 14985 0x5026 倦 (<CJK Ideograph>) 14986 0x5238 券 (<CJK Ideograph>) 14987 0x52F8 勸 (<CJK Ideograph>) 14988 0x5377 卷 (<CJK Ideograph>) 14989 0x5708 圈 (<CJK Ideograph>) 14990 0x62F3 拳 (<CJK Ideograph>) 14991 0x6372 捲 (<CJK Ideograph>) 14992 0x6B0A 權 (<CJK Ideograph>) 14993 0x6DC3 淃 (<CJK Ideograph>) 14994 0x7737 眷 (<CJK Ideograph>) 14995 0x53A5 厥 (<CJK Ideograph>) 14996 0x7357 獗 (<CJK Ideograph>) 14997 0x8568 蕨 (<CJK Ideograph>) 14998 0x8E76 蹶 (<CJK Ideograph>) 14999 0x95D5 闕 (<CJK Ideograph>) 15000 0x673A 机 (<CJK Ideograph>) 15001 0x6AC3 櫃 (<CJK Ideograph>) 15002 0x6F70 潰 (<CJK Ideograph>) 15003 0x8A6D 詭 (<CJK Ideograph>) 15004 0x8ECC 軌 (<CJK Ideograph>) 15005 0x994B 饋 (<CJK Ideograph>) 15006 0xF906 句 (CJK COMPATIBILITY IDEOGRAPH-F906) 15007 0x6677 晷 (<CJK Ideograph>) 15008 0x6B78 歸 (<CJK Ideograph>) 15009 0x8CB4 貴 (<CJK Ideograph>) 15106 0x9B3C 鬼 (<CJK Ideograph>) 15107 0xF907 龜 (CJK COMPATIBILITY IDEOGRAPH-F907) 15108 0x53EB 叫 (<CJK Ideograph>) 15109 0x572D 圭 (<CJK Ideograph>) 15110 0x594E 奎 (<CJK Ideograph>) 15111 0x63C6 揆 (<CJK Ideograph>) 15112 0x69FB 槻 (<CJK Ideograph>) 15113 0x73EA 珪 (<CJK Ideograph>) 15114 0x7845 硅 (<CJK Ideograph>) 15115 0x7ABA 窺 (<CJK Ideograph>) 15116 0x7AC5 竅 (<CJK Ideograph>) 15117 0x7CFE 糾 (<CJK Ideograph>) 15118 0x8475 葵 (<CJK Ideograph>) 15119 0x898F 規 (<CJK Ideograph>) 15120 0x8D73 赳 (<CJK Ideograph>) 15121 0x9035 逵 (<CJK Ideograph>) 15122 0x95A8 閨 (<CJK Ideograph>) 15123 0x52FB 勻 (<CJK Ideograph>) 15124 0x5747 均 (<CJK Ideograph>) 15125 0x7547 畇 (<CJK Ideograph>) 15126 0x7B60 筠 (<CJK Ideograph>) 15127 0x83CC 菌 (<CJK Ideograph>) 15128 0x921E 鈞 (<CJK Ideograph>) 15129 0xF908 龜 (CJK COMPATIBILITY IDEOGRAPH-F908) 15130 0x6A58 橘 (<CJK Ideograph>) 15131 0x514B 克 (<CJK Ideograph>) 15132 0x524B 剋 (<CJK Ideograph>) 15133 0x5287 劇 (<CJK Ideograph>) 15134 0x621F 戟 (<CJK Ideograph>) 15135 0x68D8 棘 (<CJK Ideograph>) 15136 0x6975 極 (<CJK Ideograph>) 15137 0x9699 隙 (<CJK Ideograph>) 15138 0x50C5 僅 (<CJK Ideograph>) 15139 0x52A4 劤 (<CJK Ideograph>) 15140 0x52E4 勤 (<CJK Ideograph>) 15141 0x61C3 懃 (<CJK Ideograph>) 15142 0x65A4 斤 (<CJK Ideograph>) 15143 0x6839 根 (<CJK Ideograph>) 15144 0x69FF 槿 (<CJK Ideograph>) 15145 0x747E 瑾 (<CJK Ideograph>) 15146 0x7B4B 筋 (<CJK Ideograph>) 15147 0x82B9 芹 (<CJK Ideograph>) 15148 0x83EB 菫 (<CJK Ideograph>) 15149 0x89B2 覲 (<CJK Ideograph>) 15150 0x8B39 謹 (<CJK Ideograph>) 15151 0x8FD1 近 (<CJK Ideograph>) 15152 0x9949 饉 (<CJK Ideograph>) 15153 0xF909 契 (CJK COMPATIBILITY IDEOGRAPH-F909) 15154 0x4ECA 今 (<CJK Ideograph>) 15155 0x5997 妗 (<CJK Ideograph>) 15156 0x64D2 擒 (<CJK Ideograph>) 15157 0x6611 昑 (<CJK Ideograph>) 15158 0x6A8E 檎 (<CJK Ideograph>) 15159 0x7434 琴 (<CJK Ideograph>) 15160 0x7981 禁 (<CJK Ideograph>) 15161 0x79BD 禽 (<CJK Ideograph>) 15162 0x82A9 芩 (<CJK Ideograph>) 15163 0x887E 衾 (<CJK Ideograph>) 15164 0x887F 衿 (<CJK Ideograph>) 15165 0x895F 襟 (<CJK Ideograph>) 15166 0xF90A 金 (CJK COMPATIBILITY IDEOGRAPH-F90A) 15167 0x9326 錦 (<CJK Ideograph>) 15168 0x4F0B 伋 (<CJK Ideograph>) 15169 0x53CA 及 (<CJK Ideograph>) 15170 0x6025 急 (<CJK Ideograph>) 15171 0x6271 扱 (<CJK Ideograph>) 15172 0x6C72 汲 (<CJK Ideograph>) 15173 0x7D1A 級 (<CJK Ideograph>) 15174 0x7D66 給 (<CJK Ideograph>) 15175 0x4E98 亘 (<CJK Ideograph>) 15176 0x5162 兢 (<CJK Ideograph>) 15177 0x77DC 矜 (<CJK Ideograph>) 15178 0x80AF 肯 (<CJK Ideograph>) 15179 0x4F01 企 (<CJK Ideograph>) 15180 0x4F0E 伎 (<CJK Ideograph>) 15181 0x5176 其 (<CJK Ideograph>) 15182 0x5180 冀 (<CJK Ideograph>) 15183 0x55DC 嗜 (<CJK Ideograph>) 15184 0x5668 器 (<CJK Ideograph>) 15185 0x573B 圻 (<CJK Ideograph>) 15186 0x57FA 基 (<CJK Ideograph>) 15187 0x57FC 埼 (<CJK Ideograph>) 15188 0x5914 夔 (<CJK Ideograph>) 15189 0x5947 奇 (<CJK Ideograph>) 15190 0x5993 妓 (<CJK Ideograph>) 15191 0x5BC4 寄 (<CJK Ideograph>) 15192 0x5C90 岐 (<CJK Ideograph>) 15193 0x5D0E 崎 (<CJK Ideograph>) 15194 0x5DF1 己 (<CJK Ideograph>) 15195 0x5E7E 幾 (<CJK Ideograph>) 15196 0x5FCC 忌 (<CJK Ideograph>) 15197 0x6280 技 (<CJK Ideograph>) 15198 0x65D7 旗 (<CJK Ideograph>) 15199 0x65E3 旣 (<CJK Ideograph>) 15296 0x671E 朞 (<CJK Ideograph>) 15297 0x671F 期 (<CJK Ideograph>) 15298 0x675E 杞 (<CJK Ideograph>) 15299 0x68CB 棋 (<CJK Ideograph>) 15300 0x68C4 棄 (<CJK Ideograph>) 15301 0x6A5F 機 (<CJK Ideograph>) 15302 0x6B3A 欺 (<CJK Ideograph>) 15303 0x6C23 氣 (<CJK Ideograph>) 15304 0x6C7D 汽 (<CJK Ideograph>) 15305 0x6C82 沂 (<CJK Ideograph>) 15306 0x6DC7 淇 (<CJK Ideograph>) 15307 0x7398 玘 (<CJK Ideograph>) 15308 0x7426 琦 (<CJK Ideograph>) 15309 0x742A 琪 (<CJK Ideograph>) 15310 0x7482 璂 (<CJK Ideograph>) 15311 0x74A3 璣 (<CJK Ideograph>) 15312 0x7578 畸 (<CJK Ideograph>) 15313 0x757F 畿 (<CJK Ideograph>) 15314 0x7881 碁 (<CJK Ideograph>) 15315 0x78EF 磯 (<CJK Ideograph>) 15316 0x7941 祁 (<CJK Ideograph>) 15317 0x7947 祇 (<CJK Ideograph>) 15318 0x7948 祈 (<CJK Ideograph>) 15319 0x797A 祺 (<CJK Ideograph>) 15320 0x7B95 箕 (<CJK Ideograph>) 15321 0x7D00 紀 (<CJK Ideograph>) 15322 0x7DBA 綺 (<CJK Ideograph>) 15323 0x7F88 羈 (<CJK Ideograph>) 15324 0x8006 耆 (<CJK Ideograph>) 15325 0x802D 耭 (<CJK Ideograph>) 15326 0x808C 肌 (<CJK Ideograph>) 15327 0x8A18 記 (<CJK Ideograph>) 15328 0x8B4F 譏 (<CJK Ideograph>) 15329 0x8C48 豈 (<CJK Ideograph>) 15330 0x8D77 起 (<CJK Ideograph>) 15331 0x9321 錡 (<CJK Ideograph>) 15332 0x9324 錤 (<CJK Ideograph>) 15333 0x98E2 飢 (<CJK Ideograph>) 15334 0x9951 饑 (<CJK Ideograph>) 15335 0x9A0E 騎 (<CJK Ideograph>) 15336 0x9A0F 騏 (<CJK Ideograph>) 15337 0x9A65 驥 (<CJK Ideograph>) 15338 0x9E92 麒 (<CJK Ideograph>) 15339 0x7DCA 緊 (<CJK Ideograph>) 15340 0x4F76 佶 (<CJK Ideograph>) 15341 0x5409 吉 (<CJK Ideograph>) 15342 0x62EE 拮 (<CJK Ideograph>) 15343 0x6854 桔 (<CJK Ideograph>) 15344 0x91D1 金 (<CJK Ideograph>) 15345 0x55AB 喫 (<CJK Ideograph>) 15346 0x513A 儺 (<CJK Ideograph>) 15347 0xF90B 喇 (CJK COMPATIBILITY IDEOGRAPH-F90B) 15348 0xF90C 奈 (CJK COMPATIBILITY IDEOGRAPH-F90C) 15349 0x5A1C 娜 (<CJK Ideograph>) 15350 0x61E6 懦 (<CJK Ideograph>) 15351 0xF90D 懶 (CJK COMPATIBILITY IDEOGRAPH-F90D) 15352 0x62CF 拏 (<CJK Ideograph>) 15353 0x62FF 拿 (<CJK Ideograph>) 15354 0xF90E 癩 (CJK COMPATIBILITY IDEOGRAPH-F90E) 15355 0xF90F 羅 (CJK COMPATIBILITY IDEOGRAPH-F90F) 15356 0xF910 蘿 (CJK COMPATIBILITY IDEOGRAPH-F910) 15357 0xF911 螺 (CJK COMPATIBILITY IDEOGRAPH-F911) 15358 0xF912 裸 (CJK COMPATIBILITY IDEOGRAPH-F912) 15359 0xF913 邏 (CJK COMPATIBILITY IDEOGRAPH-F913) 15360 0x90A3 那 (<CJK Ideograph>) 15361 0xF914 樂 (CJK COMPATIBILITY IDEOGRAPH-F914) 15362 0xF915 洛 (CJK COMPATIBILITY IDEOGRAPH-F915) 15363 0xF916 烙 (CJK COMPATIBILITY IDEOGRAPH-F916) 15364 0xF917 珞 (CJK COMPATIBILITY IDEOGRAPH-F917) 15365 0xF918 落 (CJK COMPATIBILITY IDEOGRAPH-F918) 15366 0x8AFE 諾 (<CJK Ideograph>) 15367 0xF919 酪 (CJK COMPATIBILITY IDEOGRAPH-F919) 15368 0xF91A 駱 (CJK COMPATIBILITY IDEOGRAPH-F91A) 15369 0xF91B 亂 (CJK COMPATIBILITY IDEOGRAPH-F91B) 15370 0xF91C 卵 (CJK COMPATIBILITY IDEOGRAPH-F91C) 15371 0x6696 暖 (<CJK Ideograph>) 15372 0xF91D 欄 (CJK COMPATIBILITY IDEOGRAPH-F91D) 15373 0x7156 煖 (<CJK Ideograph>) 15374 0xF91E 爛 (CJK COMPATIBILITY IDEOGRAPH-F91E) 15375 0xF91F 蘭 (CJK COMPATIBILITY IDEOGRAPH-F91F) 15376 0x96E3 難 (<CJK Ideograph>) 15377 0xF920 鸞 (CJK COMPATIBILITY IDEOGRAPH-F920) 15378 0x634F 捏 (<CJK Ideograph>) 15379 0x637A 捺 (<CJK Ideograph>) 15380 0x5357 南 (<CJK Ideograph>) 15381 0xF921 嵐 (CJK COMPATIBILITY IDEOGRAPH-F921) 15382 0x678F 枏 (<CJK Ideograph>) 15383 0x6960 楠 (<CJK Ideograph>) 15384 0x6E73 湳 (<CJK Ideograph>) 15385 0xF922 濫 (CJK COMPATIBILITY IDEOGRAPH-F922) 15386 0x7537 男 (<CJK Ideograph>) 15387 0xF923 藍 (CJK COMPATIBILITY IDEOGRAPH-F923) 15388 0xF924 襤 (CJK COMPATIBILITY IDEOGRAPH-F924) 15389 0xF925 拉 (CJK COMPATIBILITY IDEOGRAPH-F925) 15486 0x7D0D 納 (<CJK Ideograph>) 15487 0xF926 臘 (CJK COMPATIBILITY IDEOGRAPH-F926) 15488 0xF927 蠟 (CJK COMPATIBILITY IDEOGRAPH-F927) 15489 0x8872 衲 (<CJK Ideograph>) 15490 0x56CA 囊 (<CJK Ideograph>) 15491 0x5A18 娘 (<CJK Ideograph>) 15492 0xF928 廊 (CJK COMPATIBILITY IDEOGRAPH-F928) 15493 0xF929 朗 (CJK COMPATIBILITY IDEOGRAPH-F929) 15494 0xF92A 浪 (CJK COMPATIBILITY IDEOGRAPH-F92A) 15495 0xF92B 狼 (CJK COMPATIBILITY IDEOGRAPH-F92B) 15496 0xF92C 郎 (CJK COMPATIBILITY IDEOGRAPH-F92C) 15497 0x4E43 乃 (<CJK Ideograph>) 15498 0xF92D 來 (CJK COMPATIBILITY IDEOGRAPH-F92D) 15499 0x5167 內 (<CJK Ideograph>) 15500 0x5948 奈 (<CJK Ideograph>) 15501 0x67F0 柰 (<CJK Ideograph>) 15502 0x8010 耐 (<CJK Ideograph>) 15503 0xF92E 冷 (CJK COMPATIBILITY IDEOGRAPH-F92E) 15504 0x5973 女 (<CJK Ideograph>) 15505 0x5E74 年 (<CJK Ideograph>) 15506 0x649A 撚 (<CJK Ideograph>) 15507 0x79CA 秊 (<CJK Ideograph>) 15508 0x5FF5 念 (<CJK Ideograph>) 15509 0x606C 恬 (<CJK Ideograph>) 15510 0x62C8 拈 (<CJK Ideograph>) 15511 0x637B 捻 (<CJK Ideograph>) 15512 0x5BE7 寧 (<CJK Ideograph>) 15513 0x5BD7 寗 (<CJK Ideograph>) 15514 0x52AA 努 (<CJK Ideograph>) 15515 0xF92F 勞 (CJK COMPATIBILITY IDEOGRAPH-F92F) 15516 0x5974 奴 (<CJK Ideograph>) 15517 0x5F29 弩 (<CJK Ideograph>) 15518 0x6012 怒 (<CJK Ideograph>) 15519 0xF930 擄 (CJK COMPATIBILITY IDEOGRAPH-F930) 15520 0xF931 櫓 (CJK COMPATIBILITY IDEOGRAPH-F931) 15521 0xF932 爐 (CJK COMPATIBILITY IDEOGRAPH-F932) 15522 0x7459 瑙 (<CJK Ideograph>) 15523 0xF933 盧 (CJK COMPATIBILITY IDEOGRAPH-F933) 15524 0xF934 老 (CJK COMPATIBILITY IDEOGRAPH-F934) 15525 0xF935 蘆 (CJK COMPATIBILITY IDEOGRAPH-F935) 15526 0xF936 虜 (CJK COMPATIBILITY IDEOGRAPH-F936) 15527 0xF937 路 (CJK COMPATIBILITY IDEOGRAPH-F937) 15528 0xF938 露 (CJK COMPATIBILITY IDEOGRAPH-F938) 15529 0x99D1 駑 (<CJK Ideograph>) 15530 0xF939 魯 (CJK COMPATIBILITY IDEOGRAPH-F939) 15531 0xF93A 鷺 (CJK COMPATIBILITY IDEOGRAPH-F93A) 15532 0xF93B 碌 (CJK COMPATIBILITY IDEOGRAPH-F93B) 15533 0xF93C 祿 (CJK COMPATIBILITY IDEOGRAPH-F93C) 15534 0xF93D 綠 (CJK COMPATIBILITY IDEOGRAPH-F93D) 15535 0xF93E 菉 (CJK COMPATIBILITY IDEOGRAPH-F93E) 15536 0xF93F 錄 (CJK COMPATIBILITY IDEOGRAPH-F93F) 15537 0xF940 鹿 (CJK COMPATIBILITY IDEOGRAPH-F940) 15538 0xF941 論 (CJK COMPATIBILITY IDEOGRAPH-F941) 15539 0xF942 壟 (CJK COMPATIBILITY IDEOGRAPH-F942) 15540 0xF943 弄 (CJK COMPATIBILITY IDEOGRAPH-F943) 15541 0x6FC3 濃 (<CJK Ideograph>) 15542 0xF944 籠 (CJK COMPATIBILITY IDEOGRAPH-F944) 15543 0xF945 聾 (CJK COMPATIBILITY IDEOGRAPH-F945) 15544 0x81BF 膿 (<CJK Ideograph>) 15545 0x8FB2 農 (<CJK Ideograph>) 15546 0x60F1 惱 (<CJK Ideograph>) 15547 0xF946 牢 (CJK COMPATIBILITY IDEOGRAPH-F946) 15548 0xF947 磊 (CJK COMPATIBILITY IDEOGRAPH-F947) 15549 0x8166 腦 (<CJK Ideograph>) 15550 0xF948 賂 (CJK COMPATIBILITY IDEOGRAPH-F948) 15551 0xF949 雷 (CJK COMPATIBILITY IDEOGRAPH-F949) 15552 0x5C3F 尿 (<CJK Ideograph>) 15553 0xF94A 壘 (CJK COMPATIBILITY IDEOGRAPH-F94A) 15554 0xF94B 屢 (CJK COMPATIBILITY IDEOGRAPH-F94B) 15555 0xF94C 樓 (CJK COMPATIBILITY IDEOGRAPH-F94C) 15556 0xF94D 淚 (CJK COMPATIBILITY IDEOGRAPH-F94D) 15557 0xF94E 漏 (CJK COMPATIBILITY IDEOGRAPH-F94E) 15558 0xF94F 累 (CJK COMPATIBILITY IDEOGRAPH-F94F) 15559 0xF950 縷 (CJK COMPATIBILITY IDEOGRAPH-F950) 15560 0xF951 陋 (CJK COMPATIBILITY IDEOGRAPH-F951) 15561 0x5AE9 嫩 (<CJK Ideograph>) 15562 0x8A25 訥 (<CJK Ideograph>) 15563 0x677B 杻 (<CJK Ideograph>) 15564 0x7D10 紐 (<CJK Ideograph>) 15565 0xF952 勒 (CJK COMPATIBILITY IDEOGRAPH-F952) 15566 0xF953 肋 (CJK COMPATIBILITY IDEOGRAPH-F953) 15567 0xF954 凜 (CJK COMPATIBILITY IDEOGRAPH-F954) 15568 0xF955 凌 (CJK COMPATIBILITY IDEOGRAPH-F955) 15569 0xF956 稜 (CJK COMPATIBILITY IDEOGRAPH-F956) 15570 0xF957 綾 (CJK COMPATIBILITY IDEOGRAPH-F957) 15571 0x80FD 能 (<CJK Ideograph>) 15572 0xF958 菱 (CJK COMPATIBILITY IDEOGRAPH-F958) 15573 0xF959 陵 (CJK COMPATIBILITY IDEOGRAPH-F959) 15574 0x5C3C 尼 (<CJK Ideograph>) 15575 0x6CE5 泥 (<CJK Ideograph>) 15576 0x533F 匿 (<CJK Ideograph>) 15577 0x6EBA 溺 (<CJK Ideograph>) 15578 0x591A 多 (<CJK Ideograph>) 15579 0x8336 茶 (<CJK Ideograph>) 15676 0x4E39 丹 (<CJK Ideograph>) 15677 0x4EB6 亶 (<CJK Ideograph>) 15678 0x4F46 但 (<CJK Ideograph>) 15679 0x55AE 單 (<CJK Ideograph>) 15680 0x5718 團 (<CJK Ideograph>) 15681 0x58C7 壇 (<CJK Ideograph>) 15682 0x5F56 彖 (<CJK Ideograph>) 15683 0x65B7 斷 (<CJK Ideograph>) 15684 0x65E6 旦 (<CJK Ideograph>) 15685 0x6A80 檀 (<CJK Ideograph>) 15686 0x6BB5 段 (<CJK Ideograph>) 15687 0x6E4D 湍 (<CJK Ideograph>) 15688 0x77ED 短 (<CJK Ideograph>) 15689 0x7AEF 端 (<CJK Ideograph>) 15690 0x7C1E 簞 (<CJK Ideograph>) 15691 0x7DDE 緞 (<CJK Ideograph>) 15692 0x86CB 蛋 (<CJK Ideograph>) 15693 0x8892 袒 (<CJK Ideograph>) 15694 0x9132 鄲 (<CJK Ideograph>) 15695 0x935B 鍛 (<CJK Ideograph>) 15696 0x64BB 撻 (<CJK Ideograph>) 15697 0x6FBE 澾 (<CJK Ideograph>) 15698 0x737A 獺 (<CJK Ideograph>) 15699 0x75B8 疸 (<CJK Ideograph>) 15700 0x9054 達 (<CJK Ideograph>) 15701 0x5556 啖 (<CJK Ideograph>) 15702 0x574D 坍 (<CJK Ideograph>) 15703 0x61BA 憺 (<CJK Ideograph>) 15704 0x64D4 擔 (<CJK Ideograph>) 15705 0x66C7 曇 (<CJK Ideograph>) 15706 0x6DE1 淡 (<CJK Ideograph>) 15707 0x6E5B 湛 (<CJK Ideograph>) 15708 0x6F6D 潭 (<CJK Ideograph>) 15709 0x6FB9 澹 (<CJK Ideograph>) 15710 0x75F0 痰 (<CJK Ideograph>) 15711 0x8043 聃 (<CJK Ideograph>) 15712 0x81BD 膽 (<CJK Ideograph>) 15713 0x8541 蕁 (<CJK Ideograph>) 15714 0x8983 覃 (<CJK Ideograph>) 15715 0x8AC7 談 (<CJK Ideograph>) 15716 0x8B5A 譚 (<CJK Ideograph>) 15717 0x931F 錟 (<CJK Ideograph>) 15718 0x6C93 沓 (<CJK Ideograph>) 15719 0x7553 畓 (<CJK Ideograph>) 15720 0x7B54 答 (<CJK Ideograph>) 15721 0x8E0F 踏 (<CJK Ideograph>) 15722 0x905D 遝 (<CJK Ideograph>) 15723 0x5510 唐 (<CJK Ideograph>) 15724 0x5802 堂 (<CJK Ideograph>) 15725 0x5858 塘 (<CJK Ideograph>) 15726 0x5E62 幢 (<CJK Ideograph>) 15727 0x6207 戇 (<CJK Ideograph>) 15728 0x649E 撞 (<CJK Ideograph>) 15729 0x68E0 棠 (<CJK Ideograph>) 15730 0x7576 當 (<CJK Ideograph>) 15731 0x7CD6 糖 (<CJK Ideograph>) 15732 0x87B3 螳 (<CJK Ideograph>) 15733 0x9EE8 黨 (<CJK Ideograph>) 15734 0x4EE3 代 (<CJK Ideograph>) 15735 0x5788 垈 (<CJK Ideograph>) 15736 0x576E 坮 (<CJK Ideograph>) 15737 0x5927 大 (<CJK Ideograph>) 15738 0x5C0D 對 (<CJK Ideograph>) 15739 0x5CB1 岱 (<CJK Ideograph>) 15740 0x5E36 帶 (<CJK Ideograph>) 15741 0x5F85 待 (<CJK Ideograph>) 15742 0x6234 戴 (<CJK Ideograph>) 15743 0x64E1 擡 (<CJK Ideograph>) 15744 0x73B3 玳 (<CJK Ideograph>) 15745 0x81FA 臺 (<CJK Ideograph>) 15746 0x888B 袋 (<CJK Ideograph>) 15747 0x8CB8 貸 (<CJK Ideograph>) 15748 0x968A 隊 (<CJK Ideograph>) 15749 0x9EDB 黛 (<CJK Ideograph>) 15750 0x5B85 宅 (<CJK Ideograph>) 15751 0x5FB7 德 (<CJK Ideograph>) 15752 0x60B3 悳 (<CJK Ideograph>) 15753 0x5012 倒 (<CJK Ideograph>) 15754 0x5200 刀 (<CJK Ideograph>) 15755 0x5230 到 (<CJK Ideograph>) 15756 0x5716 圖 (<CJK Ideograph>) 15757 0x5835 堵 (<CJK Ideograph>) 15758 0x5857 塗 (<CJK Ideograph>) 15759 0x5C0E 導 (<CJK Ideograph>) 15760 0x5C60 屠 (<CJK Ideograph>) 15761 0x5CF6 島 (<CJK Ideograph>) 15762 0x5D8B 嶋 (<CJK Ideograph>) 15763 0x5EA6 度 (<CJK Ideograph>) 15764 0x5F92 徒 (<CJK Ideograph>) 15765 0x60BC 悼 (<CJK Ideograph>) 15766 0x6311 挑 (<CJK Ideograph>) 15767 0x6389 掉 (<CJK Ideograph>) 15768 0x6417 搗 (<CJK Ideograph>) 15769 0x6843 桃 (<CJK Ideograph>) 15866 0x68F9 棹 (<CJK Ideograph>) 15867 0x6AC2 櫂 (<CJK Ideograph>) 15868 0x6DD8 淘 (<CJK Ideograph>) 15869 0x6E21 渡 (<CJK Ideograph>) 15870 0x6ED4 滔 (<CJK Ideograph>) 15871 0x6FE4 濤 (<CJK Ideograph>) 15872 0x71FE 燾 (<CJK Ideograph>) 15873 0x76DC 盜 (<CJK Ideograph>) 15874 0x7779 睹 (<CJK Ideograph>) 15875 0x79B1 禱 (<CJK Ideograph>) 15876 0x7A3B 稻 (<CJK Ideograph>) 15877 0x8404 萄 (<CJK Ideograph>) 15878 0x89A9 覩 (<CJK Ideograph>) 15879 0x8CED 賭 (<CJK Ideograph>) 15880 0x8DF3 跳 (<CJK Ideograph>) 15881 0x8E48 蹈 (<CJK Ideograph>) 15882 0x9003 逃 (<CJK Ideograph>) 15883 0x9014 途 (<CJK Ideograph>) 15884 0x9053 道 (<CJK Ideograph>) 15885 0x90FD 都 (<CJK Ideograph>) 15886 0x934D 鍍 (<CJK Ideograph>) 15887 0x9676 陶 (<CJK Ideograph>) 15888 0x97DC 韜 (<CJK Ideograph>) 15889 0x6BD2 毒 (<CJK Ideograph>) 15890 0x7006 瀆 (<CJK Ideograph>) 15891 0x7258 牘 (<CJK Ideograph>) 15892 0x72A2 犢 (<CJK Ideograph>) 15893 0x7368 獨 (<CJK Ideograph>) 15894 0x7763 督 (<CJK Ideograph>) 15895 0x79BF 禿 (<CJK Ideograph>) 15896 0x7BE4 篤 (<CJK Ideograph>) 15897 0x7E9B 纛 (<CJK Ideograph>) 15898 0x8B80 讀 (<CJK Ideograph>) 15899 0x58A9 墩 (<CJK Ideograph>) 15900 0x60C7 惇 (<CJK Ideograph>) 15901 0x6566 敦 (<CJK Ideograph>) 15902 0x65FD 旽 (<CJK Ideograph>) 15903 0x66BE 暾 (<CJK Ideograph>) 15904 0x6C8C 沌 (<CJK Ideograph>) 15905 0x711E 焞 (<CJK Ideograph>) 15906 0x71C9 燉 (<CJK Ideograph>) 15907 0x8C5A 豚 (<CJK Ideograph>) 15908 0x9813 頓 (<CJK Ideograph>) 15909 0x4E6D 乭 (<CJK Ideograph>) 15910 0x7A81 突 (<CJK Ideograph>) 15911 0x4EDD 仝 (<CJK Ideograph>) 15912 0x51AC 冬 (<CJK Ideograph>) 15913 0x51CD 凍 (<CJK Ideograph>) 15914 0x52D5 動 (<CJK Ideograph>) 15915 0x540C 同 (<CJK Ideograph>) 15916 0x61A7 憧 (<CJK Ideograph>) 15917 0x6771 東 (<CJK Ideograph>) 15918 0x6850 桐 (<CJK Ideograph>) 15919 0x68DF 棟 (<CJK Ideograph>) 15920 0x6D1E 洞 (<CJK Ideograph>) 15921 0x6F7C 潼 (<CJK Ideograph>) 15922 0x75BC 疼 (<CJK Ideograph>) 15923 0x77B3 瞳 (<CJK Ideograph>) 15924 0x7AE5 童 (<CJK Ideograph>) 15925 0x80F4 胴 (<CJK Ideograph>) 15926 0x8463 董 (<CJK Ideograph>) 15927 0x9285 銅 (<CJK Ideograph>) 15928 0x515C 兜 (<CJK Ideograph>) 15929 0x6597 斗 (<CJK Ideograph>) 15930 0x675C 杜 (<CJK Ideograph>) 15931 0x6793 枓 (<CJK Ideograph>) 15932 0x75D8 痘 (<CJK Ideograph>) 15933 0x7AC7 竇 (<CJK Ideograph>) 15934 0x8373 荳 (<CJK Ideograph>) 15935 0xF95A 讀 (CJK COMPATIBILITY IDEOGRAPH-F95A) 15936 0x8C46 豆 (<CJK Ideograph>) 15937 0x9017 逗 (<CJK Ideograph>) 15938 0x982D 頭 (<CJK Ideograph>) 15939 0x5C6F 屯 (<CJK Ideograph>) 15940 0x81C0 臀 (<CJK Ideograph>) 15941 0x829A 芚 (<CJK Ideograph>) 15942 0x9041 遁 (<CJK Ideograph>) 15943 0x906F 遯 (<CJK Ideograph>) 15944 0x920D 鈍 (<CJK Ideograph>) 15945 0x5F97 得 (<CJK Ideograph>) 15946 0x5D9D 嶝 (<CJK Ideograph>) 15947 0x6A59 橙 (<CJK Ideograph>) 15948 0x71C8 燈 (<CJK Ideograph>) 15949 0x767B 登 (<CJK Ideograph>) 15950 0x7B49 等 (<CJK Ideograph>) 15951 0x85E4 藤 (<CJK Ideograph>) 15952 0x8B04 謄 (<CJK Ideograph>) 15953 0x9127 鄧 (<CJK Ideograph>) 15954 0x9A30 騰 (<CJK Ideograph>) 15955 0x5587 喇 (<CJK Ideograph>) 15956 0x61F6 懶 (<CJK Ideograph>) 15957 0xF95B 拏 (CJK COMPATIBILITY IDEOGRAPH-F95B) 15958 0x7669 癩 (<CJK Ideograph>) 15959 0x7F85 羅 (<CJK Ideograph>) 16056 0x863F 蘿 (<CJK Ideograph>) 16057 0x87BA 螺 (<CJK Ideograph>) 16058 0x88F8 裸 (<CJK Ideograph>) 16059 0x908F 邏 (<CJK Ideograph>) 16060 0xF95C 樂 (CJK COMPATIBILITY IDEOGRAPH-F95C) 16061 0x6D1B 洛 (<CJK Ideograph>) 16062 0x70D9 烙 (<CJK Ideograph>) 16063 0x73DE 珞 (<CJK Ideograph>) 16064 0x7D61 絡 (<CJK Ideograph>) 16065 0x843D 落 (<CJK Ideograph>) 16066 0xF95D 諾 (CJK COMPATIBILITY IDEOGRAPH-F95D) 16067 0x916A 酪 (<CJK Ideograph>) 16068 0x99F1 駱 (<CJK Ideograph>) 16069 0xF95E 丹 (CJK COMPATIBILITY IDEOGRAPH-F95E) 16070 0x4E82 亂 (<CJK Ideograph>) 16071 0x5375 卵 (<CJK Ideograph>) 16072 0x6B04 欄 (<CJK Ideograph>) 16073 0x6B12 欒 (<CJK Ideograph>) 16074 0x703E 瀾 (<CJK Ideograph>) 16075 0x721B 爛 (<CJK Ideograph>) 16076 0x862D 蘭 (<CJK Ideograph>) 16077 0x9E1E 鸞 (<CJK Ideograph>) 16078 0x524C 剌 (<CJK Ideograph>) 16079 0x8FA3 辣 (<CJK Ideograph>) 16080 0x5D50 嵐 (<CJK Ideograph>) 16081 0x64E5 擥 (<CJK Ideograph>) 16082 0x652C 攬 (<CJK Ideograph>) 16083 0x6B16 欖 (<CJK Ideograph>) 16084 0x6FEB 濫 (<CJK Ideograph>) 16085 0x7C43 籃 (<CJK Ideograph>) 16086 0x7E9C 纜 (<CJK Ideograph>) 16087 0x85CD 藍 (<CJK Ideograph>) 16088 0x8964 襤 (<CJK Ideograph>) 16089 0x89BD 覽 (<CJK Ideograph>) 16090 0x62C9 拉 (<CJK Ideograph>) 16091 0x81D8 臘 (<CJK Ideograph>) 16092 0x881F 蠟 (<CJK Ideograph>) 16093 0x5ECA 廊 (<CJK Ideograph>) 16094 0x6717 朗 (<CJK Ideograph>) 16095 0x6D6A 浪 (<CJK Ideograph>) 16096 0x72FC 狼 (<CJK Ideograph>) 16097 0x7405 琅 (<CJK Ideograph>) 16098 0x746F 瑯 (<CJK Ideograph>) 16099 0x8782 螂 (<CJK Ideograph>) 16100 0x90DE 郞 (<CJK Ideograph>) 16101 0x4F86 來 (<CJK Ideograph>) 16102 0x5D0D 崍 (<CJK Ideograph>) 16103 0x5FA0 徠 (<CJK Ideograph>) 16104 0x840A 萊 (<CJK Ideograph>) 16105 0x51B7 冷 (<CJK Ideograph>) 16106 0x63A0 掠 (<CJK Ideograph>) 16107 0x7565 略 (<CJK Ideograph>) 16108 0x4EAE 亮 (<CJK Ideograph>) 16109 0x5006 倆 (<CJK Ideograph>) 16110 0x5169 兩 (<CJK Ideograph>) 16111 0x51C9 凉 (<CJK Ideograph>) 16112 0x6881 梁 (<CJK Ideograph>) 16113 0x6A11 樑 (<CJK Ideograph>) 16114 0x7CAE 粮 (<CJK Ideograph>) 16115 0x7CB1 粱 (<CJK Ideograph>) 16116 0x7CE7 糧 (<CJK Ideograph>) 16117 0x826F 良 (<CJK Ideograph>) 16118 0x8AD2 諒 (<CJK Ideograph>) 16119 0x8F1B 輛 (<CJK Ideograph>) 16120 0x91CF 量 (<CJK Ideograph>) 16121 0x4FB6 侶 (<CJK Ideograph>) 16122 0x5137 儷 (<CJK Ideograph>) 16123 0x52F5 勵 (<CJK Ideograph>) 16124 0x5442 呂 (<CJK Ideograph>) 16125 0x5EEC 廬 (<CJK Ideograph>) 16126 0x616E 慮 (<CJK Ideograph>) 16127 0x623E 戾 (<CJK Ideograph>) 16128 0x65C5 旅 (<CJK Ideograph>) 16129 0x6ADA 櫚 (<CJK Ideograph>) 16130 0x6FFE 濾 (<CJK Ideograph>) 16131 0x792A 礪 (<CJK Ideograph>) 16132 0x85DC 藜 (<CJK Ideograph>) 16133 0x8823 蠣 (<CJK Ideograph>) 16134 0x95AD 閭 (<CJK Ideograph>) 16135 0x9A62 驢 (<CJK Ideograph>) 16136 0x9A6A 驪 (<CJK Ideograph>) 16137 0x9E97 麗 (<CJK Ideograph>) 16138 0x9ECE 黎 (<CJK Ideograph>) 16139 0x529B 力 (<CJK Ideograph>) 16140 0x66C6 曆 (<CJK Ideograph>) 16141 0x6B77 歷 (<CJK Ideograph>) 16142 0x701D 瀝 (<CJK Ideograph>) 16143 0x792B 礫 (<CJK Ideograph>) 16144 0x8F62 轢 (<CJK Ideograph>) 16145 0x9742 靂 (<CJK Ideograph>) 16146 0x6190 憐 (<CJK Ideograph>) 16147 0x6200 戀 (<CJK Ideograph>) 16148 0x6523 攣 (<CJK Ideograph>) 16149 0x6F23 漣 (<CJK Ideograph>) 16246 0x7149 煉 (<CJK Ideograph>) 16247 0x7489 璉 (<CJK Ideograph>) 16248 0x7DF4 練 (<CJK Ideograph>) 16249 0x806F 聯 (<CJK Ideograph>) 16250 0x84EE 蓮 (<CJK Ideograph>) 16251 0x8F26 輦 (<CJK Ideograph>) 16252 0x9023 連 (<CJK Ideograph>) 16253 0x934A 鍊 (<CJK Ideograph>) 16254 0x51BD 冽 (<CJK Ideograph>) 16255 0x5217 列 (<CJK Ideograph>) 16256 0x52A3 劣 (<CJK Ideograph>) 16257 0x6D0C 洌 (<CJK Ideograph>) 16258 0x70C8 烈 (<CJK Ideograph>) 16259 0x88C2 裂 (<CJK Ideograph>) 16260 0x5EC9 廉 (<CJK Ideograph>) 16261 0x6582 斂 (<CJK Ideograph>) 16262 0x6BAE 殮 (<CJK Ideograph>) 16263 0x6FC2 濂 (<CJK Ideograph>) 16264 0x7C3E 簾 (<CJK Ideograph>) 16265 0x7375 獵 (<CJK Ideograph>) 16266 0x4EE4 令 (<CJK Ideograph>) 16267 0x4F36 伶 (<CJK Ideograph>) 16268 0x56F9 囹 (<CJK Ideograph>) 16269 0xF95F 寧 (CJK COMPATIBILITY IDEOGRAPH-F95F) 16270 0x5CBA 岺 (<CJK Ideograph>) 16271 0x5DBA 嶺 (<CJK Ideograph>) 16272 0x601C 怜 (<CJK Ideograph>) 16273 0x73B2 玲 (<CJK Ideograph>) 16274 0x7B2D 笭 (<CJK Ideograph>) 16275 0x7F9A 羚 (<CJK Ideograph>) 16276 0x7FCE 翎 (<CJK Ideograph>) 16277 0x8046 聆 (<CJK Ideograph>) 16278 0x901E 逞 (<CJK Ideograph>) 16279 0x9234 鈴 (<CJK Ideograph>) 16280 0x96F6 零 (<CJK Ideograph>) 16281 0x9748 靈 (<CJK Ideograph>) 16282 0x9818 領 (<CJK Ideograph>) 16283 0x9F61 齡 (<CJK Ideograph>) 16284 0x4F8B 例 (<CJK Ideograph>) 16285 0x6FA7 澧 (<CJK Ideograph>) 16286 0x79AE 禮 (<CJK Ideograph>) 16287 0x91B4 醴 (<CJK Ideograph>) 16288 0x96B7 隷 (<CJK Ideograph>) 16289 0x52DE 勞 (<CJK Ideograph>) 16290 0xF960 怒 (CJK COMPATIBILITY IDEOGRAPH-F960) 16291 0x6488 撈 (<CJK Ideograph>) 16292 0x64C4 擄 (<CJK Ideograph>) 16293 0x6AD3 櫓 (<CJK Ideograph>) 16294 0x6F5E 潞 (<CJK Ideograph>) 16295 0x7018 瀘 (<CJK Ideograph>) 16296 0x7210 爐 (<CJK Ideograph>) 16297 0x76E7 盧 (<CJK Ideograph>) 16298 0x8001 老 (<CJK Ideograph>) 16299 0x8606 蘆 (<CJK Ideograph>) 16300 0x865C 虜 (<CJK Ideograph>) 16301 0x8DEF 路 (<CJK Ideograph>) 16302 0x8F05 輅 (<CJK Ideograph>) 16303 0x9732 露 (<CJK Ideograph>) 16304 0x9B6F 魯 (<CJK Ideograph>) 16305 0x9DFA 鷺 (<CJK Ideograph>) 16306 0x9E75 鹵 (<CJK Ideograph>) 16307 0x788C 碌 (<CJK Ideograph>) 16308 0x797F 祿 (<CJK Ideograph>) 16309 0x7DA0 綠 (<CJK Ideograph>) 16310 0x83C9 菉 (<CJK Ideograph>) 16311 0x9304 錄 (<CJK Ideograph>) 16312 0x9E7F 鹿 (<CJK Ideograph>) 16313 0x9E93 麓 (<CJK Ideograph>) 16314 0x8AD6 論 (<CJK Ideograph>) 16315 0x58DF 壟 (<CJK Ideograph>) 16316 0x5F04 弄 (<CJK Ideograph>) 16317 0x6727 朧 (<CJK Ideograph>) 16318 0x7027 瀧 (<CJK Ideograph>) 16319 0x74CF 瓏 (<CJK Ideograph>) 16320 0x7C60 籠 (<CJK Ideograph>) 16321 0x807E 聾 (<CJK Ideograph>) 16322 0x5121 儡 (<CJK Ideograph>) 16323 0x7028 瀨 (<CJK Ideograph>) 16324 0x7262 牢 (<CJK Ideograph>) 16325 0x78CA 磊 (<CJK Ideograph>) 16326 0x8CC2 賂 (<CJK Ideograph>) 16327 0x8CDA 賚 (<CJK Ideograph>) 16328 0x8CF4 賴 (<CJK Ideograph>) 16329 0x96F7 雷 (<CJK Ideograph>) 16330 0x4E86 了 (<CJK Ideograph>) 16331 0x50DA 僚 (<CJK Ideograph>) 16332 0x5BEE 寮 (<CJK Ideograph>) 16333 0x5ED6 廖 (<CJK Ideograph>) 16334 0x6599 料 (<CJK Ideograph>) 16335 0x71CE 燎 (<CJK Ideograph>) 16336 0x7642 療 (<CJK Ideograph>) 16337 0x77AD 瞭 (<CJK Ideograph>) 16338 0x804A 聊 (<CJK Ideograph>) 16339 0x84FC 蓼 (<CJK Ideograph>) 16436 0x907C 遼 (<CJK Ideograph>) 16437 0x9B27 鬧 (<CJK Ideograph>) 16438 0x9F8D 龍 (<CJK Ideograph>) 16439 0x58D8 壘 (<CJK Ideograph>) 16440 0x5A41 婁 (<CJK Ideograph>) 16441 0x5C62 屢 (<CJK Ideograph>) 16442 0x6A13 樓 (<CJK Ideograph>) 16443 0x6DDA 淚 (<CJK Ideograph>) 16444 0x6F0F 漏 (<CJK Ideograph>) 16445 0x763B 瘻 (<CJK Ideograph>) 16446 0x7D2F 累 (<CJK Ideograph>) 16447 0x7E37 縷 (<CJK Ideograph>) 16448 0x851E 蔞 (<CJK Ideograph>) 16449 0x8938 褸 (<CJK Ideograph>) 16450 0x93E4 鏤 (<CJK Ideograph>) 16451 0x964B 陋 (<CJK Ideograph>) 16452 0x5289 劉 (<CJK Ideograph>) 16453 0x65D2 旒 (<CJK Ideograph>) 16454 0x67F3 柳 (<CJK Ideograph>) 16455 0x69B4 榴 (<CJK Ideograph>) 16456 0x6D41 流 (<CJK Ideograph>) 16457 0x6E9C 溜 (<CJK Ideograph>) 16458 0x700F 瀏 (<CJK Ideograph>) 16459 0x7409 琉 (<CJK Ideograph>) 16460 0x7460 瑠 (<CJK Ideograph>) 16461 0x7559 留 (<CJK Ideograph>) 16462 0x7624 瘤 (<CJK Ideograph>) 16463 0x786B 硫 (<CJK Ideograph>) 16464 0x8B2C 謬 (<CJK Ideograph>) 16465 0x985E 類 (<CJK Ideograph>) 16466 0x516D 六 (<CJK Ideograph>) 16467 0x622E 戮 (<CJK Ideograph>) 16468 0x9678 陸 (<CJK Ideograph>) 16469 0x4F96 侖 (<CJK Ideograph>) 16470 0x502B 倫 (<CJK Ideograph>) 16471 0x5D19 崙 (<CJK Ideograph>) 16472 0x6DEA 淪 (<CJK Ideograph>) 16473 0x7DB8 綸 (<CJK Ideograph>) 16474 0x8F2A 輪 (<CJK Ideograph>) 16475 0x5F8B 律 (<CJK Ideograph>) 16476 0x6144 慄 (<CJK Ideograph>) 16477 0x6817 栗 (<CJK Ideograph>) 16478 0xF961 率 (CJK COMPATIBILITY IDEOGRAPH-F961) 16479 0x9686 隆 (<CJK Ideograph>) 16480 0x52D2 勒 (<CJK Ideograph>) 16481 0x808B 肋 (<CJK Ideograph>) 16482 0x51DC 凜 (<CJK Ideograph>) 16483 0x51CC 凌 (<CJK Ideograph>) 16484 0x695E 楞 (<CJK Ideograph>) 16485 0x7A1C 稜 (<CJK Ideograph>) 16486 0x7DBE 綾 (<CJK Ideograph>) 16487 0x83F1 菱 (<CJK Ideograph>) 16488 0x9675 陵 (<CJK Ideograph>) 16489 0x4FDA 俚 (<CJK Ideograph>) 16490 0x5229 利 (<CJK Ideograph>) 16491 0x5398 厘 (<CJK Ideograph>) 16492 0x540F 吏 (<CJK Ideograph>) 16493 0x550E 唎 (<CJK Ideograph>) 16494 0x5C65 履 (<CJK Ideograph>) 16495 0x60A7 悧 (<CJK Ideograph>) 16496 0x674E 李 (<CJK Ideograph>) 16497 0x68A8 梨 (<CJK Ideograph>) 16498 0x6D6C 浬 (<CJK Ideograph>) 16499 0x7281 犁 (<CJK Ideograph>) 16500 0x72F8 狸 (<CJK Ideograph>) 16501 0x7406 理 (<CJK Ideograph>) 16502 0x7483 璃 (<CJK Ideograph>) 16503 0xF962 異 (CJK COMPATIBILITY IDEOGRAPH-F962) 16504 0x75E2 痢 (<CJK Ideograph>) 16505 0x7C6C 籬 (<CJK Ideograph>) 16506 0x7F79 罹 (<CJK Ideograph>) 16507 0x7FB8 羸 (<CJK Ideograph>) 16508 0x8389 莉 (<CJK Ideograph>) 16509 0x88CF 裏 (<CJK Ideograph>) 16510 0x88E1 裡 (<CJK Ideograph>) 16511 0x91CC 里 (<CJK Ideograph>) 16512 0x91D0 釐 (<CJK Ideograph>) 16513 0x96E2 離 (<CJK Ideograph>) 16514 0x9BC9 鯉 (<CJK Ideograph>) 16515 0x541D 吝 (<CJK Ideograph>) 16516 0x6F7E 潾 (<CJK Ideograph>) 16517 0x71D0 燐 (<CJK Ideograph>) 16518 0x7498 璘 (<CJK Ideograph>) 16519 0x85FA 藺 (<CJK Ideograph>) 16520 0x8EAA 躪 (<CJK Ideograph>) 16521 0x96A3 隣 (<CJK Ideograph>) 16522 0x9C57 鱗 (<CJK Ideograph>) 16523 0x9E9F 麟 (<CJK Ideograph>) 16524 0x6797 林 (<CJK Ideograph>) 16525 0x6DCB 淋 (<CJK Ideograph>) 16526 0x7433 琳 (<CJK Ideograph>) 16527 0x81E8 臨 (<CJK Ideograph>) 16528 0x9716 霖 (<CJK Ideograph>) 16529 0x782C 砬 (<CJK Ideograph>) 16626 0x7ACB 立 (<CJK Ideograph>) 16627 0x7B20 笠 (<CJK Ideograph>) 16628 0x7C92 粒 (<CJK Ideograph>) 16629 0x6469 摩 (<CJK Ideograph>) 16630 0x746A 瑪 (<CJK Ideograph>) 16631 0x75F2 痲 (<CJK Ideograph>) 16632 0x78BC 碼 (<CJK Ideograph>) 16633 0x78E8 磨 (<CJK Ideograph>) 16634 0x99AC 馬 (<CJK Ideograph>) 16635 0x9B54 魔 (<CJK Ideograph>) 16636 0x9EBB 麻 (<CJK Ideograph>) 16637 0x5BDE 寞 (<CJK Ideograph>) 16638 0x5E55 幕 (<CJK Ideograph>) 16639 0x6F20 漠 (<CJK Ideograph>) 16640 0x819C 膜 (<CJK Ideograph>) 16641 0x83AB 莫 (<CJK Ideograph>) 16642 0x9088 邈 (<CJK Ideograph>) 16643 0x4E07 万 (<CJK Ideograph>) 16644 0x534D 卍 (<CJK Ideograph>) 16645 0x5A29 娩 (<CJK Ideograph>) 16646 0x5DD2 巒 (<CJK Ideograph>) 16647 0x5F4E 彎 (<CJK Ideograph>) 16648 0x6162 慢 (<CJK Ideograph>) 16649 0x633D 挽 (<CJK Ideograph>) 16650 0x6669 晩 (<CJK Ideograph>) 16651 0x66FC 曼 (<CJK Ideograph>) 16652 0x6EFF 滿 (<CJK Ideograph>) 16653 0x6F2B 漫 (<CJK Ideograph>) 16654 0x7063 灣 (<CJK Ideograph>) 16655 0x779E 瞞 (<CJK Ideograph>) 16656 0x842C 萬 (<CJK Ideograph>) 16657 0x8513 蔓 (<CJK Ideograph>) 16658 0x883B 蠻 (<CJK Ideograph>) 16659 0x8F13 輓 (<CJK Ideograph>) 16660 0x9945 饅 (<CJK Ideograph>) 16661 0x9C3B 鰻 (<CJK Ideograph>) 16662 0x551C 唜 (<CJK Ideograph>) 16663 0x62B9 抹 (<CJK Ideograph>) 16664 0x672B 末 (<CJK Ideograph>) 16665 0x6CAB 沫 (<CJK Ideograph>) 16666 0x8309 茉 (<CJK Ideograph>) 16667 0x896A 襪 (<CJK Ideograph>) 16668 0x977A 靺 (<CJK Ideograph>) 16669 0x4EA1 亡 (<CJK Ideograph>) 16670 0x5984 妄 (<CJK Ideograph>) 16671 0x5FD8 忘 (<CJK Ideograph>) 16672 0x5FD9 忙 (<CJK Ideograph>) 16673 0x671B 望 (<CJK Ideograph>) 16674 0x7DB2 網 (<CJK Ideograph>) 16675 0x7F54 罔 (<CJK Ideograph>) 16676 0x8292 芒 (<CJK Ideograph>) 16677 0x832B 茫 (<CJK Ideograph>) 16678 0x83BD 莽 (<CJK Ideograph>) 16679 0x8F1E 輞 (<CJK Ideograph>) 16680 0x9099 邙 (<CJK Ideograph>) 16681 0x57CB 埋 (<CJK Ideograph>) 16682 0x59B9 妹 (<CJK Ideograph>) 16683 0x5A92 媒 (<CJK Ideograph>) 16684 0x5BD0 寐 (<CJK Ideograph>) 16685 0x6627 昧 (<CJK Ideograph>) 16686 0x679A 枚 (<CJK Ideograph>) 16687 0x6885 梅 (<CJK Ideograph>) 16688 0x6BCF 每 (<CJK Ideograph>) 16689 0x7164 煤 (<CJK Ideograph>) 16690 0x7F75 罵 (<CJK Ideograph>) 16691 0x8CB7 買 (<CJK Ideograph>) 16692 0x8CE3 賣 (<CJK Ideograph>) 16693 0x9081 邁 (<CJK Ideograph>) 16694 0x9B45 魅 (<CJK Ideograph>) 16695 0x8108 脈 (<CJK Ideograph>) 16696 0x8C8A 貊 (<CJK Ideograph>) 16697 0x964C 陌 (<CJK Ideograph>) 16698 0x9A40 驀 (<CJK Ideograph>) 16699 0x9EA5 麥 (<CJK Ideograph>) 16700 0x5B5F 孟 (<CJK Ideograph>) 16701 0x6C13 氓 (<CJK Ideograph>) 16702 0x731B 猛 (<CJK Ideograph>) 16703 0x76F2 盲 (<CJK Ideograph>) 16704 0x76DF 盟 (<CJK Ideograph>) 16705 0x840C 萌 (<CJK Ideograph>) 16706 0x51AA 冪 (<CJK Ideograph>) 16707 0x8993 覓 (<CJK Ideograph>) 16708 0x514D 免 (<CJK Ideograph>) 16709 0x5195 冕 (<CJK Ideograph>) 16710 0x52C9 勉 (<CJK Ideograph>) 16711 0x68C9 棉 (<CJK Ideograph>) 16712 0x6C94 沔 (<CJK Ideograph>) 16713 0x7704 眄 (<CJK Ideograph>) 16714 0x7720 眠 (<CJK Ideograph>) 16715 0x7DBF 綿 (<CJK Ideograph>) 16716 0x7DEC 緬 (<CJK Ideograph>) 16717 0x9762 面 (<CJK Ideograph>) 16718 0x9EB5 麵 (<CJK Ideograph>) 16719 0x6EC5 滅 (<CJK Ideograph>) 16816 0x8511 蔑 (<CJK Ideograph>) 16817 0x51A5 冥 (<CJK Ideograph>) 16818 0x540D 名 (<CJK Ideograph>) 16819 0x547D 命 (<CJK Ideograph>) 16820 0x660E 明 (<CJK Ideograph>) 16821 0x669D 暝 (<CJK Ideograph>) 16822 0x6927 椧 (<CJK Ideograph>) 16823 0x6E9F 溟 (<CJK Ideograph>) 16824 0x76BF 皿 (<CJK Ideograph>) 16825 0x7791 瞑 (<CJK Ideograph>) 16826 0x8317 茗 (<CJK Ideograph>) 16827 0x84C2 蓂 (<CJK Ideograph>) 16828 0x879F 螟 (<CJK Ideograph>) 16829 0x9169 酩 (<CJK Ideograph>) 16830 0x9298 銘 (<CJK Ideograph>) 16831 0x9CF4 鳴 (<CJK Ideograph>) 16832 0x8882 袂 (<CJK Ideograph>) 16833 0x4FAE 侮 (<CJK Ideograph>) 16834 0x5192 冒 (<CJK Ideograph>) 16835 0x52DF 募 (<CJK Ideograph>) 16836 0x59C6 姆 (<CJK Ideograph>) 16837 0x5E3D 帽 (<CJK Ideograph>) 16838 0x6155 慕 (<CJK Ideograph>) 16839 0x6478 摸 (<CJK Ideograph>) 16840 0x6479 摹 (<CJK Ideograph>) 16841 0x66AE 暮 (<CJK Ideograph>) 16842 0x67D0 某 (<CJK Ideograph>) 16843 0x6A21 模 (<CJK Ideograph>) 16844 0x6BCD 母 (<CJK Ideograph>) 16845 0x6BDB 毛 (<CJK Ideograph>) 16846 0x725F 牟 (<CJK Ideograph>) 16847 0x7261 牡 (<CJK Ideograph>) 16848 0x7441 瑁 (<CJK Ideograph>) 16849 0x7738 眸 (<CJK Ideograph>) 16850 0x77DB 矛 (<CJK Ideograph>) 16851 0x8017 耗 (<CJK Ideograph>) 16852 0x82BC 芼 (<CJK Ideograph>) 16853 0x8305 茅 (<CJK Ideograph>) 16854 0x8B00 謀 (<CJK Ideograph>) 16855 0x8B28 謨 (<CJK Ideograph>) 16856 0x8C8C 貌 (<CJK Ideograph>) 16857 0x6728 木 (<CJK Ideograph>) 16858 0x6C90 沐 (<CJK Ideograph>) 16859 0x7267 牧 (<CJK Ideograph>) 16860 0x76EE 目 (<CJK Ideograph>) 16861 0x7766 睦 (<CJK Ideograph>) 16862 0x7A46 穆 (<CJK Ideograph>) 16863 0x9DA9 鶩 (<CJK Ideograph>) 16864 0x6B7F 歿 (<CJK Ideograph>) 16865 0x6C92 沒 (<CJK Ideograph>) 16866 0x5922 夢 (<CJK Ideograph>) 16867 0x6726 朦 (<CJK Ideograph>) 16868 0x8499 蒙 (<CJK Ideograph>) 16869 0x536F 卯 (<CJK Ideograph>) 16870 0x5893 墓 (<CJK Ideograph>) 16871 0x5999 妙 (<CJK Ideograph>) 16872 0x5EDF 廟 (<CJK Ideograph>) 16873 0x63CF 描 (<CJK Ideograph>) 16874 0x6634 昴 (<CJK Ideograph>) 16875 0x6773 杳 (<CJK Ideograph>) 16876 0x6E3A 渺 (<CJK Ideograph>) 16877 0x732B 猫 (<CJK Ideograph>) 16878 0x7AD7 竗 (<CJK Ideograph>) 16879 0x82D7 苗 (<CJK Ideograph>) 16880 0x9328 錨 (<CJK Ideograph>) 16881 0x52D9 務 (<CJK Ideograph>) 16882 0x5DEB 巫 (<CJK Ideograph>) 16883 0x61AE 憮 (<CJK Ideograph>) 16884 0x61CB 懋 (<CJK Ideograph>) 16885 0x620A 戊 (<CJK Ideograph>) 16886 0x62C7 拇 (<CJK Ideograph>) 16887 0x64AB 撫 (<CJK Ideograph>) 16888 0x65E0 无 (<CJK Ideograph>) 16889 0x6959 楙 (<CJK Ideograph>) 16890 0x6B66 武 (<CJK Ideograph>) 16891 0x6BCB 毋 (<CJK Ideograph>) 16892 0x7121 無 (<CJK Ideograph>) 16893 0x73F7 珷 (<CJK Ideograph>) 16894 0x755D 畝 (<CJK Ideograph>) 16895 0x7E46 繆 (<CJK Ideograph>) 16896 0x821E 舞 (<CJK Ideograph>) 16897 0x8302 茂 (<CJK Ideograph>) 16898 0x856A 蕪 (<CJK Ideograph>) 16899 0x8AA3 誣 (<CJK Ideograph>) 16900 0x8CBF 貿 (<CJK Ideograph>) 16901 0x9727 霧 (<CJK Ideograph>) 16902 0x9D61 鵡 (<CJK Ideograph>) 16903 0x58A8 墨 (<CJK Ideograph>) 16904 0x9ED8 默 (<CJK Ideograph>) 16905 0x5011 們 (<CJK Ideograph>) 16906 0x520E 刎 (<CJK Ideograph>) 16907 0x543B 吻 (<CJK Ideograph>) 16908 0x554F 問 (<CJK Ideograph>) 16909 0x6587 文 (<CJK Ideograph>) 17006 0x6C76 汶 (<CJK Ideograph>) 17007 0x7D0A 紊 (<CJK Ideograph>) 17008 0x7D0B 紋 (<CJK Ideograph>) 17009 0x805E 聞 (<CJK Ideograph>) 17010 0x868A 蚊 (<CJK Ideograph>) 17011 0x9580 門 (<CJK Ideograph>) 17012 0x96EF 雯 (<CJK Ideograph>) 17013 0x52FF 勿 (<CJK Ideograph>) 17014 0x6C95 沕 (<CJK Ideograph>) 17015 0x7269 物 (<CJK Ideograph>) 17016 0x5473 味 (<CJK Ideograph>) 17017 0x5A9A 媚 (<CJK Ideograph>) 17018 0x5C3E 尾 (<CJK Ideograph>) 17019 0x5D4B 嵋 (<CJK Ideograph>) 17020 0x5F4C 彌 (<CJK Ideograph>) 17021 0x5FAE 微 (<CJK Ideograph>) 17022 0x672A 未 (<CJK Ideograph>) 17023 0x68B6 梶 (<CJK Ideograph>) 17024 0x6963 楣 (<CJK Ideograph>) 17025 0x6E3C 渼 (<CJK Ideograph>) 17026 0x6E44 湄 (<CJK Ideograph>) 17027 0x7709 眉 (<CJK Ideograph>) 17028 0x7C73 米 (<CJK Ideograph>) 17029 0x7F8E 美 (<CJK Ideograph>) 17030 0x8587 薇 (<CJK Ideograph>) 17031 0x8B0E 謎 (<CJK Ideograph>) 17032 0x8FF7 迷 (<CJK Ideograph>) 17033 0x9761 靡 (<CJK Ideograph>) 17034 0x9EF4 黴 (<CJK Ideograph>) 17035 0x5CB7 岷 (<CJK Ideograph>) 17036 0x60B6 悶 (<CJK Ideograph>) 17037 0x610D 愍 (<CJK Ideograph>) 17038 0x61AB 憫 (<CJK Ideograph>) 17039 0x654F 敏 (<CJK Ideograph>) 17040 0x65FB 旻 (<CJK Ideograph>) 17041 0x65FC 旼 (<CJK Ideograph>) 17042 0x6C11 民 (<CJK Ideograph>) 17043 0x6CEF 泯 (<CJK Ideograph>) 17044 0x739F 玟 (<CJK Ideograph>) 17045 0x73C9 珉 (<CJK Ideograph>) 17046 0x7DE1 緡 (<CJK Ideograph>) 17047 0x9594 閔 (<CJK Ideograph>) 17048 0x5BC6 密 (<CJK Ideograph>) 17049 0x871C 蜜 (<CJK Ideograph>) 17050 0x8B10 謐 (<CJK Ideograph>) 17051 0x525D 剝 (<CJK Ideograph>) 17052 0x535A 博 (<CJK Ideograph>) 17053 0x62CD 拍 (<CJK Ideograph>) 17054 0x640F 搏 (<CJK Ideograph>) 17055 0x64B2 撲 (<CJK Ideograph>) 17056 0x6734 朴 (<CJK Ideograph>) 17057 0x6A38 樸 (<CJK Ideograph>) 17058 0x6CCA 泊 (<CJK Ideograph>) 17059 0x73C0 珀 (<CJK Ideograph>) 17060 0x749E 璞 (<CJK Ideograph>) 17061 0x7B94 箔 (<CJK Ideograph>) 17062 0x7C95 粕 (<CJK Ideograph>) 17063 0x7E1B 縛 (<CJK Ideograph>) 17064 0x818A 膊 (<CJK Ideograph>) 17065 0x8236 舶 (<CJK Ideograph>) 17066 0x8584 薄 (<CJK Ideograph>) 17067 0x8FEB 迫 (<CJK Ideograph>) 17068 0x96F9 雹 (<CJK Ideograph>) 17069 0x99C1 駁 (<CJK Ideograph>) 17070 0x4F34 伴 (<CJK Ideograph>) 17071 0x534A 半 (<CJK Ideograph>) 17072 0x53CD 反 (<CJK Ideograph>) 17073 0x53DB 叛 (<CJK Ideograph>) 17074 0x62CC 拌 (<CJK Ideograph>) 17075 0x642C 搬 (<CJK Ideograph>) 17076 0x6500 攀 (<CJK Ideograph>) 17077 0x6591 斑 (<CJK Ideograph>) 17078 0x69C3 槃 (<CJK Ideograph>) 17079 0x6CEE 泮 (<CJK Ideograph>) 17080 0x6F58 潘 (<CJK Ideograph>) 17081 0x73ED 班 (<CJK Ideograph>) 17082 0x7554 畔 (<CJK Ideograph>) 17083 0x7622 瘢 (<CJK Ideograph>) 17084 0x76E4 盤 (<CJK Ideograph>) 17085 0x76FC 盼 (<CJK Ideograph>) 17086 0x78D0 磐 (<CJK Ideograph>) 17087 0x78FB 磻 (<CJK Ideograph>) 17088 0x792C 礬 (<CJK Ideograph>) 17089 0x7D46 絆 (<CJK Ideograph>) 17090 0x822C 般 (<CJK Ideograph>) 17091 0x87E0 蟠 (<CJK Ideograph>) 17092 0x8FD4 返 (<CJK Ideograph>) 17093 0x9812 頒 (<CJK Ideograph>) 17094 0x98EF 飯 (<CJK Ideograph>) 17095 0x52C3 勃 (<CJK Ideograph>) 17096 0x62D4 拔 (<CJK Ideograph>) 17097 0x64A5 撥 (<CJK Ideograph>) 17098 0x6E24 渤 (<CJK Ideograph>) 17099 0x6F51 潑 (<CJK Ideograph>) 17196 0x767C 發 (<CJK Ideograph>) 17197 0x8DCB 跋 (<CJK Ideograph>) 17198 0x91B1 醱 (<CJK Ideograph>) 17199 0x9262 鉢 (<CJK Ideograph>) 17200 0x9AEE 髮 (<CJK Ideograph>) 17201 0x9B43 魃 (<CJK Ideograph>) 17202 0x5023 倣 (<CJK Ideograph>) 17203 0x508D 傍 (<CJK Ideograph>) 17204 0x574A 坊 (<CJK Ideograph>) 17205 0x59A8 妨 (<CJK Ideograph>) 17206 0x5C28 尨 (<CJK Ideograph>) 17207 0x5E47 幇 (<CJK Ideograph>) 17208 0x5F77 彷 (<CJK Ideograph>) 17209 0x623F 房 (<CJK Ideograph>) 17210 0x653E 放 (<CJK Ideograph>) 17211 0x65B9 方 (<CJK Ideograph>) 17212 0x65C1 旁 (<CJK Ideograph>) 17213 0x6609 昉 (<CJK Ideograph>) 17214 0x678B 枋 (<CJK Ideograph>) 17215 0x699C 榜 (<CJK Ideograph>) 17216 0x6EC2 滂 (<CJK Ideograph>) 17217 0x78C5 磅 (<CJK Ideograph>) 17218 0x7D21 紡 (<CJK Ideograph>) 17219 0x80AA 肪 (<CJK Ideograph>) 17220 0x8180 膀 (<CJK Ideograph>) 17221 0x822B 舫 (<CJK Ideograph>) 17222 0x82B3 芳 (<CJK Ideograph>) 17223 0x84A1 蒡 (<CJK Ideograph>) 17224 0x868C 蚌 (<CJK Ideograph>) 17225 0x8A2A 訪 (<CJK Ideograph>) 17226 0x8B17 謗 (<CJK Ideograph>) 17227 0x90A6 邦 (<CJK Ideograph>) 17228 0x9632 防 (<CJK Ideograph>) 17229 0x9F90 龐 (<CJK Ideograph>) 17230 0x500D 倍 (<CJK Ideograph>) 17231 0x4FF3 俳 (<CJK Ideograph>) 17232 0xF963 北 (CJK COMPATIBILITY IDEOGRAPH-F963) 17233 0x57F9 培 (<CJK Ideograph>) 17234 0x5F98 徘 (<CJK Ideograph>) 17235 0x62DC 拜 (<CJK Ideograph>) 17236 0x6392 排 (<CJK Ideograph>) 17237 0x676F 杯 (<CJK Ideograph>) 17238 0x6E43 湃 (<CJK Ideograph>) 17239 0x7119 焙 (<CJK Ideograph>) 17240 0x76C3 盃 (<CJK Ideograph>) 17241 0x80CC 背 (<CJK Ideograph>) 17242 0x80DA 胚 (<CJK Ideograph>) 17243 0x88F4 裴 (<CJK Ideograph>) 17244 0x88F5 裵 (<CJK Ideograph>) 17245 0x8919 褙 (<CJK Ideograph>) 17246 0x8CE0 賠 (<CJK Ideograph>) 17247 0x8F29 輩 (<CJK Ideograph>) 17248 0x914D 配 (<CJK Ideograph>) 17249 0x966A 陪 (<CJK Ideograph>) 17250 0x4F2F 伯 (<CJK Ideograph>) 17251 0x4F70 佰 (<CJK Ideograph>) 17252 0x5E1B 帛 (<CJK Ideograph>) 17253 0x67CF 柏 (<CJK Ideograph>) 17254 0x6822 栢 (<CJK Ideograph>) 17255 0x767D 白 (<CJK Ideograph>) 17256 0x767E 百 (<CJK Ideograph>) 17257 0x9B44 魄 (<CJK Ideograph>) 17258 0x5E61 幡 (<CJK Ideograph>) 17259 0x6A0A 樊 (<CJK Ideograph>) 17260 0x7169 煩 (<CJK Ideograph>) 17261 0x71D4 燔 (<CJK Ideograph>) 17262 0x756A 番 (<CJK Ideograph>) 17263 0xF964 磻 (CJK COMPATIBILITY IDEOGRAPH-F964) 17264 0x7E41 繁 (<CJK Ideograph>) 17265 0x8543 蕃 (<CJK Ideograph>) 17266 0x85E9 藩 (<CJK Ideograph>) 17267 0x98DC 飜 (<CJK Ideograph>) 17268 0x4F10 伐 (<CJK Ideograph>) 17269 0x7B4F 筏 (<CJK Ideograph>) 17270 0x7F70 罰 (<CJK Ideograph>) 17271 0x95A5 閥 (<CJK Ideograph>) 17272 0x51E1 凡 (<CJK Ideograph>) 17273 0x5E06 帆 (<CJK Ideograph>) 17274 0x68B5 梵 (<CJK Ideograph>) 17275 0x6C3E 氾 (<CJK Ideograph>) 17276 0x6C4E 汎 (<CJK Ideograph>) 17277 0x6CDB 泛 (<CJK Ideograph>) 17278 0x72AF 犯 (<CJK Ideograph>) 17279 0x7BC4 範 (<CJK Ideograph>) 17280 0x8303 范 (<CJK Ideograph>) 17281 0x6CD5 法 (<CJK Ideograph>) 17282 0x743A 琺 (<CJK Ideograph>) 17283 0x50FB 僻 (<CJK Ideograph>) 17284 0x5288 劈 (<CJK Ideograph>) 17285 0x58C1 壁 (<CJK Ideograph>) 17286 0x64D8 擘 (<CJK Ideograph>) 17287 0x6A97 檗 (<CJK Ideograph>) 17288 0x74A7 璧 (<CJK Ideograph>) 17289 0x7656 癖 (<CJK Ideograph>) 17386 0x78A7 碧 (<CJK Ideograph>) 17387 0x8617 蘗 (<CJK Ideograph>) 17388 0x95E2 闢 (<CJK Ideograph>) 17389 0x9739 霹 (<CJK Ideograph>) 17390 0xF965 便 (CJK COMPATIBILITY IDEOGRAPH-F965) 17391 0x535E 卞 (<CJK Ideograph>) 17392 0x5F01 弁 (<CJK Ideograph>) 17393 0x8B8A 變 (<CJK Ideograph>) 17394 0x8FA8 辨 (<CJK Ideograph>) 17395 0x8FAF 辯 (<CJK Ideograph>) 17396 0x908A 邊 (<CJK Ideograph>) 17397 0x5225 別 (<CJK Ideograph>) 17398 0x77A5 瞥 (<CJK Ideograph>) 17399 0x9C49 鱉 (<CJK Ideograph>) 17400 0x9F08 鼈 (<CJK Ideograph>) 17401 0x4E19 丙 (<CJK Ideograph>) 17402 0x5002 倂 (<CJK Ideograph>) 17403 0x5175 兵 (<CJK Ideograph>) 17404 0x5C5B 屛 (<CJK Ideograph>) 17405 0x5E77 幷 (<CJK Ideograph>) 17406 0x661E 昞 (<CJK Ideograph>) 17407 0x663A 昺 (<CJK Ideograph>) 17408 0x67C4 柄 (<CJK Ideograph>) 17409 0x68C5 棅 (<CJK Ideograph>) 17410 0x70B3 炳 (<CJK Ideograph>) 17411 0x7501 甁 (<CJK Ideograph>) 17412 0x75C5 病 (<CJK Ideograph>) 17413 0x79C9 秉 (<CJK Ideograph>) 17414 0x7ADD 竝 (<CJK Ideograph>) 17415 0x8F27 輧 (<CJK Ideograph>) 17416 0x9920 餠 (<CJK Ideograph>) 17417 0x9A08 騈 (<CJK Ideograph>) 17418 0x4FDD 保 (<CJK Ideograph>) 17419 0x5821 堡 (<CJK Ideograph>) 17420 0x5831 報 (<CJK Ideograph>) 17421 0x5BF6 寶 (<CJK Ideograph>) 17422 0x666E 普 (<CJK Ideograph>) 17423 0x6B65 步 (<CJK Ideograph>) 17424 0x6D11 洑 (<CJK Ideograph>) 17425 0x6E7A 湺 (<CJK Ideograph>) 17426 0x6F7D 潽 (<CJK Ideograph>) 17427 0x73E4 珤 (<CJK Ideograph>) 17428 0x752B 甫 (<CJK Ideograph>) 17429 0x83E9 菩 (<CJK Ideograph>) 17430 0x88DC 補 (<CJK Ideograph>) 17431 0x8913 褓 (<CJK Ideograph>) 17432 0x8B5C 譜 (<CJK Ideograph>) 17433 0x8F14 輔 (<CJK Ideograph>) 17434 0x4F0F 伏 (<CJK Ideograph>) 17435 0x50D5 僕 (<CJK Ideograph>) 17436 0x5310 匐 (<CJK Ideograph>) 17437 0x535C 卜 (<CJK Ideograph>) 17438 0x5B93 宓 (<CJK Ideograph>) 17439 0x5FA9 復 (<CJK Ideograph>) 17440 0x670D 服 (<CJK Ideograph>) 17441 0x798F 福 (<CJK Ideograph>) 17442 0x8179 腹 (<CJK Ideograph>) 17443 0x832F 茯 (<CJK Ideograph>) 17444 0x8514 蔔 (<CJK Ideograph>) 17445 0x8907 複 (<CJK Ideograph>) 17446 0x8986 覆 (<CJK Ideograph>) 17447 0x8F39 輹 (<CJK Ideograph>) 17448 0x8F3B 輻 (<CJK Ideograph>) 17449 0x99A5 馥 (<CJK Ideograph>) 17450 0x9C12 鰒 (<CJK Ideograph>) 17451 0x672C 本 (<CJK Ideograph>) 17452 0x4E76 乶 (<CJK Ideograph>) 17453 0x4FF8 俸 (<CJK Ideograph>) 17454 0x5949 奉 (<CJK Ideograph>) 17455 0x5C01 封 (<CJK Ideograph>) 17456 0x5CEF 峯 (<CJK Ideograph>) 17457 0x5CF0 峰 (<CJK Ideograph>) 17458 0x6367 捧 (<CJK Ideograph>) 17459 0x68D2 棒 (<CJK Ideograph>) 17460 0x70FD 烽 (<CJK Ideograph>) 17461 0x71A2 熢 (<CJK Ideograph>) 17462 0x742B 琫 (<CJK Ideograph>) 17463 0x7E2B 縫 (<CJK Ideograph>) 17464 0x84EC 蓬 (<CJK Ideograph>) 17465 0x8702 蜂 (<CJK Ideograph>) 17466 0x9022 逢 (<CJK Ideograph>) 17467 0x92D2 鋒 (<CJK Ideograph>) 17468 0x9CF3 鳳 (<CJK Ideograph>) 17469 0x4E0D 不 (<CJK Ideograph>) 17470 0x4ED8 付 (<CJK Ideograph>) 17471 0x4FEF 俯 (<CJK Ideograph>) 17472 0x5085 傅 (<CJK Ideograph>) 17473 0x5256 剖 (<CJK Ideograph>) 17474 0x526F 副 (<CJK Ideograph>) 17475 0x5426 否 (<CJK Ideograph>) 17476 0x5490 咐 (<CJK Ideograph>) 17477 0x57E0 埠 (<CJK Ideograph>) 17478 0x592B 夫 (<CJK Ideograph>) 17479 0x5A66 婦 (<CJK Ideograph>) 17576 0x5B5A 孚 (<CJK Ideograph>) 17577 0x5B75 孵 (<CJK Ideograph>) 17578 0x5BCC 富 (<CJK Ideograph>) 17579 0x5E9C 府 (<CJK Ideograph>) 17580 0xF966 復 (CJK COMPATIBILITY IDEOGRAPH-F966) 17581 0x6276 扶 (<CJK Ideograph>) 17582 0x6577 敷 (<CJK Ideograph>) 17583 0x65A7 斧 (<CJK Ideograph>) 17584 0x6D6E 浮 (<CJK Ideograph>) 17585 0x6EA5 溥 (<CJK Ideograph>) 17586 0x7236 父 (<CJK Ideograph>) 17587 0x7B26 符 (<CJK Ideograph>) 17588 0x7C3F 簿 (<CJK Ideograph>) 17589 0x7F36 缶 (<CJK Ideograph>) 17590 0x8150 腐 (<CJK Ideograph>) 17591 0x8151 腑 (<CJK Ideograph>) 17592 0x819A 膚 (<CJK Ideograph>) 17593 0x8240 艀 (<CJK Ideograph>) 17594 0x8299 芙 (<CJK Ideograph>) 17595 0x83A9 莩 (<CJK Ideograph>) 17596 0x8A03 訃 (<CJK Ideograph>) 17597 0x8CA0 負 (<CJK Ideograph>) 17598 0x8CE6 賦 (<CJK Ideograph>) 17599 0x8CFB 賻 (<CJK Ideograph>) 17600 0x8D74 赴 (<CJK Ideograph>) 17601 0x8DBA 趺 (<CJK Ideograph>) 17602 0x90E8 部 (<CJK Ideograph>) 17603 0x91DC 釜 (<CJK Ideograph>) 17604 0x961C 阜 (<CJK Ideograph>) 17605 0x9644 附 (<CJK Ideograph>) 17606 0x99D9 駙 (<CJK Ideograph>) 17607 0x9CE7 鳧 (<CJK Ideograph>) 17608 0x5317 北 (<CJK Ideograph>) 17609 0x5206 分 (<CJK Ideograph>) 17610 0x5429 吩 (<CJK Ideograph>) 17611 0x5674 噴 (<CJK Ideograph>) 17612 0x58B3 墳 (<CJK Ideograph>) 17613 0x5954 奔 (<CJK Ideograph>) 17614 0x596E 奮 (<CJK Ideograph>) 17615 0x5FFF 忿 (<CJK Ideograph>) 17616 0x61A4 憤 (<CJK Ideograph>) 17617 0x626E 扮 (<CJK Ideograph>) 17618 0x6610 昐 (<CJK Ideograph>) 17619 0x6C7E 汾 (<CJK Ideograph>) 17620 0x711A 焚 (<CJK Ideograph>) 17621 0x76C6 盆 (<CJK Ideograph>) 17622 0x7C89 粉 (<CJK Ideograph>) 17623 0x7CDE 糞 (<CJK Ideograph>) 17624 0x7D1B 紛 (<CJK Ideograph>) 17625 0x82AC 芬 (<CJK Ideograph>) 17626 0x8CC1 賁 (<CJK Ideograph>) 17627 0x96F0 雰 (<CJK Ideograph>) 17628 0xF967 不 (CJK COMPATIBILITY IDEOGRAPH-F967) 17629 0x4F5B 佛 (<CJK Ideograph>) 17630 0x5F17 弗 (<CJK Ideograph>) 17631 0x5F7F 彿 (<CJK Ideograph>) 17632 0x62C2 拂 (<CJK Ideograph>) 17633 0x5D29 崩 (<CJK Ideograph>) 17634 0x670B 朋 (<CJK Ideograph>) 17635 0x68DA 棚 (<CJK Ideograph>) 17636 0x787C 硼 (<CJK Ideograph>) 17637 0x7E43 繃 (<CJK Ideograph>) 17638 0x9D6C 鵬 (<CJK Ideograph>) 17639 0x4E15 丕 (<CJK Ideograph>) 17640 0x5099 備 (<CJK Ideograph>) 17641 0x5315 匕 (<CJK Ideograph>) 17642 0x532A 匪 (<CJK Ideograph>) 17643 0x5351 卑 (<CJK Ideograph>) 17644 0x5983 妃 (<CJK Ideograph>) 17645 0x5A62 婢 (<CJK Ideograph>) 17646 0x5E87 庇 (<CJK Ideograph>) 17647 0x60B2 悲 (<CJK Ideograph>) 17648 0x618A 憊 (<CJK Ideograph>) 17649 0x6249 扉 (<CJK Ideograph>) 17650 0x6279 批 (<CJK Ideograph>) 17651 0x6590 斐 (<CJK Ideograph>) 17652 0x6787 枇 (<CJK Ideograph>) 17653 0x69A7 榧 (<CJK Ideograph>) 17654 0x6BD4 比 (<CJK Ideograph>) 17655 0x6BD6 毖 (<CJK Ideograph>) 17656 0x6BD7 毗 (<CJK Ideograph>) 17657 0x6BD8 毘 (<CJK Ideograph>) 17658 0x6CB8 沸 (<CJK Ideograph>) 17659 0xF968 泌 (CJK COMPATIBILITY IDEOGRAPH-F968) 17660 0x7435 琵 (<CJK Ideograph>) 17661 0x75FA 痺 (<CJK Ideograph>) 17662 0x7812 砒 (<CJK Ideograph>) 17663 0x7891 碑 (<CJK Ideograph>) 17664 0x79D5 秕 (<CJK Ideograph>) 17665 0x79D8 秘 (<CJK Ideograph>) 17666 0x7C83 粃 (<CJK Ideograph>) 17667 0x7DCB 緋 (<CJK Ideograph>) 17668 0x7FE1 翡 (<CJK Ideograph>) 17669 0x80A5 肥 (<CJK Ideograph>) 17766 0x813E 脾 (<CJK Ideograph>) 17767 0x81C2 臂 (<CJK Ideograph>) 17768 0x83F2 菲 (<CJK Ideograph>) 17769 0x871A 蜚 (<CJK Ideograph>) 17770 0x88E8 裨 (<CJK Ideograph>) 17771 0x8AB9 誹 (<CJK Ideograph>) 17772 0x8B6C 譬 (<CJK Ideograph>) 17773 0x8CBB 費 (<CJK Ideograph>) 17774 0x9119 鄙 (<CJK Ideograph>) 17775 0x975E 非 (<CJK Ideograph>) 17776 0x98DB 飛 (<CJK Ideograph>) 17777 0x9F3B 鼻 (<CJK Ideograph>) 17778 0x56AC 嚬 (<CJK Ideograph>) 17779 0x5B2A 嬪 (<CJK Ideograph>) 17780 0x5F6C 彬 (<CJK Ideograph>) 17781 0x658C 斌 (<CJK Ideograph>) 17782 0x6AB3 檳 (<CJK Ideograph>) 17783 0x6BAF 殯 (<CJK Ideograph>) 17784 0x6D5C 浜 (<CJK Ideograph>) 17785 0x6FF1 濱 (<CJK Ideograph>) 17786 0x7015 瀕 (<CJK Ideograph>) 17787 0x725D 牝 (<CJK Ideograph>) 17788 0x73AD 玭 (<CJK Ideograph>) 17789 0x8CA7 貧 (<CJK Ideograph>) 17790 0x8CD3 賓 (<CJK Ideograph>) 17791 0x983B 頻 (<CJK Ideograph>) 17792 0x6191 憑 (<CJK Ideograph>) 17793 0x6C37 氷 (<CJK Ideograph>) 17794 0x8058 聘 (<CJK Ideograph>) 17795 0x9A01 騁 (<CJK Ideograph>) 17796 0x4E4D 乍 (<CJK Ideograph>) 17797 0x4E8B 事 (<CJK Ideograph>) 17798 0x4E9B 些 (<CJK Ideograph>) 17799 0x4ED5 仕 (<CJK Ideograph>) 17800 0x4F3A 伺 (<CJK Ideograph>) 17801 0x4F3C 似 (<CJK Ideograph>) 17802 0x4F7F 使 (<CJK Ideograph>) 17803 0x4FDF 俟 (<CJK Ideograph>) 17804 0x50FF 僿 (<CJK Ideograph>) 17805 0x53F2 史 (<CJK Ideograph>) 17806 0x53F8 司 (<CJK Ideograph>) 17807 0x5506 唆 (<CJK Ideograph>) 17808 0x55E3 嗣 (<CJK Ideograph>) 17809 0x56DB 四 (<CJK Ideograph>) 17810 0x58EB 士 (<CJK Ideograph>) 17811 0x5962 奢 (<CJK Ideograph>) 17812 0x5A11 娑 (<CJK Ideograph>) 17813 0x5BEB 寫 (<CJK Ideograph>) 17814 0x5BFA 寺 (<CJK Ideograph>) 17815 0x5C04 射 (<CJK Ideograph>) 17816 0x5DF3 巳 (<CJK Ideograph>) 17817 0x5E2B 師 (<CJK Ideograph>) 17818 0x5F99 徙 (<CJK Ideograph>) 17819 0x601D 思 (<CJK Ideograph>) 17820 0x6368 捨 (<CJK Ideograph>) 17821 0x659C 斜 (<CJK Ideograph>) 17822 0x65AF 斯 (<CJK Ideograph>) 17823 0x67F6 柶 (<CJK Ideograph>) 17824 0x67FB 査 (<CJK Ideograph>) 17825 0x68AD 梭 (<CJK Ideograph>) 17826 0x6B7B 死 (<CJK Ideograph>) 17827 0x6C99 沙 (<CJK Ideograph>) 17828 0x6CD7 泗 (<CJK Ideograph>) 17829 0x6E23 渣 (<CJK Ideograph>) 17830 0x7009 瀉 (<CJK Ideograph>) 17831 0x7345 獅 (<CJK Ideograph>) 17832 0x7802 砂 (<CJK Ideograph>) 17833 0x793E 社 (<CJK Ideograph>) 17834 0x7940 祀 (<CJK Ideograph>) 17835 0x7960 祠 (<CJK Ideograph>) 17836 0x79C1 私 (<CJK Ideograph>) 17837 0x7BE9 篩 (<CJK Ideograph>) 17838 0x7D17 紗 (<CJK Ideograph>) 17839 0x7D72 絲 (<CJK Ideograph>) 17840 0x8086 肆 (<CJK Ideograph>) 17841 0x820D 舍 (<CJK Ideograph>) 17842 0x838E 莎 (<CJK Ideograph>) 17843 0x84D1 蓑 (<CJK Ideograph>) 17844 0x86C7 蛇 (<CJK Ideograph>) 17845 0x88DF 裟 (<CJK Ideograph>) 17846 0x8A50 詐 (<CJK Ideograph>) 17847 0x8A5E 詞 (<CJK Ideograph>) 17848 0x8B1D 謝 (<CJK Ideograph>) 17849 0x8CDC 賜 (<CJK Ideograph>) 17850 0x8D66 赦 (<CJK Ideograph>) 17851 0x8FAD 辭 (<CJK Ideograph>) 17852 0x90AA 邪 (<CJK Ideograph>) 17853 0x98FC 飼 (<CJK Ideograph>) 17854 0x99DF 駟 (<CJK Ideograph>) 17855 0x9E9D 麝 (<CJK Ideograph>) 17856 0x524A 削 (<CJK Ideograph>) 17857 0xF969 數 (CJK COMPATIBILITY IDEOGRAPH-F969) 17858 0x6714 朔 (<CJK Ideograph>) 17859 0xF96A 索 (CJK COMPATIBILITY IDEOGRAPH-F96A) 17956 0x5098 傘 (<CJK Ideograph>) 17957 0x522A 刪 (<CJK Ideograph>) 17958 0x5C71 山 (<CJK Ideograph>) 17959 0x6563 散 (<CJK Ideograph>) 17960 0x6C55 汕 (<CJK Ideograph>) 17961 0x73CA 珊 (<CJK Ideograph>) 17962 0x7523 産 (<CJK Ideograph>) 17963 0x759D 疝 (<CJK Ideograph>) 17964 0x7B97 算 (<CJK Ideograph>) 17965 0x849C 蒜 (<CJK Ideograph>) 17966 0x9178 酸 (<CJK Ideograph>) 17967 0x9730 霰 (<CJK Ideograph>) 17968 0x4E77 乷 (<CJK Ideograph>) 17969 0x6492 撒 (<CJK Ideograph>) 17970 0x6BBA 殺 (<CJK Ideograph>) 17971 0x715E 煞 (<CJK Ideograph>) 17972 0x85A9 薩 (<CJK Ideograph>) 17973 0x4E09 三 (<CJK Ideograph>) 17974 0xF96B 參 (CJK COMPATIBILITY IDEOGRAPH-F96B) 17975 0x6749 杉 (<CJK Ideograph>) 17976 0x68EE 森 (<CJK Ideograph>) 17977 0x6E17 渗 (<CJK Ideograph>) 17978 0x829F 芟 (<CJK Ideograph>) 17979 0x8518 蔘 (<CJK Ideograph>) 17980 0x886B 衫 (<CJK Ideograph>) 17981 0x63F7 揷 (<CJK Ideograph>) 17982 0x6F81 澁 (<CJK Ideograph>) 17983 0x9212 鈒 (<CJK Ideograph>) 17984 0x98AF 颯 (<CJK Ideograph>) 17985 0x4E0A 上 (<CJK Ideograph>) 17986 0x50B7 傷 (<CJK Ideograph>) 17987 0x50CF 像 (<CJK Ideograph>) 17988 0x511F 償 (<CJK Ideograph>) 17989 0x5546 商 (<CJK Ideograph>) 17990 0x55AA 喪 (<CJK Ideograph>) 17991 0x5617 嘗 (<CJK Ideograph>) 17992 0x5B40 孀 (<CJK Ideograph>) 17993 0x5C19 尙 (<CJK Ideograph>) 17994 0x5CE0 峠 (<CJK Ideograph>) 17995 0x5E38 常 (<CJK Ideograph>) 17996 0x5E8A 床 (<CJK Ideograph>) 17997 0x5EA0 庠 (<CJK Ideograph>) 17998 0x5EC2 廂 (<CJK Ideograph>) 17999 0x60F3 想 (<CJK Ideograph>) 18000 0x6851 桑 (<CJK Ideograph>) 18001 0x6A61 橡 (<CJK Ideograph>) 18002 0x6E58 湘 (<CJK Ideograph>) 18003 0x723D 爽 (<CJK Ideograph>) 18004 0x7240 牀 (<CJK Ideograph>) 18005 0x72C0 狀 (<CJK Ideograph>) 18006 0x76F8 相 (<CJK Ideograph>) 18007 0x7965 祥 (<CJK Ideograph>) 18008 0x7BB1 箱 (<CJK Ideograph>) 18009 0x7FD4 翔 (<CJK Ideograph>) 18010 0x88F3 裳 (<CJK Ideograph>) 18011 0x89F4 觴 (<CJK Ideograph>) 18012 0x8A73 詳 (<CJK Ideograph>) 18013 0x8C61 象 (<CJK Ideograph>) 18014 0x8CDE 賞 (<CJK Ideograph>) 18015 0x971C 霜 (<CJK Ideograph>) 18016 0x585E 塞 (<CJK Ideograph>) 18017 0x74BD 璽 (<CJK Ideograph>) 18018 0x8CFD 賽 (<CJK Ideograph>) 18019 0x55C7 嗇 (<CJK Ideograph>) 18020 0xF96C 塞 (CJK COMPATIBILITY IDEOGRAPH-F96C) 18021 0x7A61 穡 (<CJK Ideograph>) 18022 0x7D22 索 (<CJK Ideograph>) 18023 0x8272 色 (<CJK Ideograph>) 18024 0x7272 牲 (<CJK Ideograph>) 18025 0x751F 生 (<CJK Ideograph>) 18026 0x7525 甥 (<CJK Ideograph>) 18027 0xF96D 省 (CJK COMPATIBILITY IDEOGRAPH-F96D) 18028 0x7B19 笙 (<CJK Ideograph>) 18029 0x5885 墅 (<CJK Ideograph>) 18030 0x58FB 壻 (<CJK Ideograph>) 18031 0x5DBC 嶼 (<CJK Ideograph>) 18032 0x5E8F 序 (<CJK Ideograph>) 18033 0x5EB6 庶 (<CJK Ideograph>) 18034 0x5F90 徐 (<CJK Ideograph>) 18035 0x6055 恕 (<CJK Ideograph>) 18036 0x6292 抒 (<CJK Ideograph>) 18037 0x637F 捿 (<CJK Ideograph>) 18038 0x654D 敍 (<CJK Ideograph>) 18039 0x6691 暑 (<CJK Ideograph>) 18040 0x66D9 曙 (<CJK Ideograph>) 18041 0x66F8 書 (<CJK Ideograph>) 18042 0x6816 栖 (<CJK Ideograph>) 18043 0x68F2 棲 (<CJK Ideograph>) 18044 0x7280 犀 (<CJK Ideograph>) 18045 0x745E 瑞 (<CJK Ideograph>) 18046 0x7B6E 筮 (<CJK Ideograph>) 18047 0x7D6E 絮 (<CJK Ideograph>) 18048 0x7DD6 緖 (<CJK Ideograph>) 18049 0x7F72 署 (<CJK Ideograph>) 18146 0x80E5 胥 (<CJK Ideograph>) 18147 0x8212 舒 (<CJK Ideograph>) 18148 0x85AF 薯 (<CJK Ideograph>) 18149 0x897F 西 (<CJK Ideograph>) 18150 0x8A93 誓 (<CJK Ideograph>) 18151 0x901D 逝 (<CJK Ideograph>) 18152 0x92E4 鋤 (<CJK Ideograph>) 18153 0x9ECD 黍 (<CJK Ideograph>) 18154 0x9F20 鼠 (<CJK Ideograph>) 18155 0x5915 夕 (<CJK Ideograph>) 18156 0x596D 奭 (<CJK Ideograph>) 18157 0x5E2D 席 (<CJK Ideograph>) 18158 0x60DC 惜 (<CJK Ideograph>) 18159 0x6614 昔 (<CJK Ideograph>) 18160 0x6673 晳 (<CJK Ideograph>) 18161 0x6790 析 (<CJK Ideograph>) 18162 0x6C50 汐 (<CJK Ideograph>) 18163 0x6DC5 淅 (<CJK Ideograph>) 18164 0x6F5F 潟 (<CJK Ideograph>) 18165 0x77F3 石 (<CJK Ideograph>) 18166 0x78A9 碩 (<CJK Ideograph>) 18167 0x84C6 蓆 (<CJK Ideograph>) 18168 0x91CB 釋 (<CJK Ideograph>) 18169 0x932B 錫 (<CJK Ideograph>) 18170 0x4ED9 仙 (<CJK Ideograph>) 18171 0x50CA 僊 (<CJK Ideograph>) 18172 0x5148 先 (<CJK Ideograph>) 18173 0x5584 善 (<CJK Ideograph>) 18174 0x5B0B 嬋 (<CJK Ideograph>) 18175 0x5BA3 宣 (<CJK Ideograph>) 18176 0x6247 扇 (<CJK Ideograph>) 18177 0x657E 敾 (<CJK Ideograph>) 18178 0x65CB 旋 (<CJK Ideograph>) 18179 0x6E32 渲 (<CJK Ideograph>) 18180 0x717D 煽 (<CJK Ideograph>) 18181 0x7401 琁 (<CJK Ideograph>) 18182 0x7444 瑄 (<CJK Ideograph>) 18183 0x7487 璇 (<CJK Ideograph>) 18184 0x74BF 璿 (<CJK Ideograph>) 18185 0x766C 癬 (<CJK Ideograph>) 18186 0x79AA 禪 (<CJK Ideograph>) 18187 0x7DDA 線 (<CJK Ideograph>) 18188 0x7E55 繕 (<CJK Ideograph>) 18189 0x7FA8 羨 (<CJK Ideograph>) 18190 0x817A 腺 (<CJK Ideograph>) 18191 0x81B3 膳 (<CJK Ideograph>) 18192 0x8239 船 (<CJK Ideograph>) 18193 0x861A 蘚 (<CJK Ideograph>) 18194 0x87EC 蟬 (<CJK Ideograph>) 18195 0x8A75 詵 (<CJK Ideograph>) 18196 0x8DE3 跣 (<CJK Ideograph>) 18197 0x9078 選 (<CJK Ideograph>) 18198 0x9291 銑 (<CJK Ideograph>) 18199 0x9425 鐥 (<CJK Ideograph>) 18200 0x994D 饍 (<CJK Ideograph>) 18201 0x9BAE 鮮 (<CJK Ideograph>) 18202 0x5368 卨 (<CJK Ideograph>) 18203 0x5C51 屑 (<CJK Ideograph>) 18204 0x6954 楔 (<CJK Ideograph>) 18205 0x6CC4 泄 (<CJK Ideograph>) 18206 0x6D29 洩 (<CJK Ideograph>) 18207 0x6E2B 渫 (<CJK Ideograph>) 18208 0x820C 舌 (<CJK Ideograph>) 18209 0x859B 薛 (<CJK Ideograph>) 18210 0x893B 褻 (<CJK Ideograph>) 18211 0x8A2D 設 (<CJK Ideograph>) 18212 0x8AAA 說 (<CJK Ideograph>) 18213 0x96EA 雪 (<CJK Ideograph>) 18214 0x9F67 齧 (<CJK Ideograph>) 18215 0x5261 剡 (<CJK Ideograph>) 18216 0x66B9 暹 (<CJK Ideograph>) 18217 0x6BB2 殲 (<CJK Ideograph>) 18218 0x7E96 纖 (<CJK Ideograph>) 18219 0x87FE 蟾 (<CJK Ideograph>) 18220 0x8D0D 贍 (<CJK Ideograph>) 18221 0x9583 閃 (<CJK Ideograph>) 18222 0x965D 陝 (<CJK Ideograph>) 18223 0x651D 攝 (<CJK Ideograph>) 18224 0x6D89 涉 (<CJK Ideograph>) 18225 0x71EE 燮 (<CJK Ideograph>) 18226 0xF96E 葉 (CJK COMPATIBILITY IDEOGRAPH-F96E) 18227 0x57CE 城 (<CJK Ideograph>) 18228 0x59D3 姓 (<CJK Ideograph>) 18229 0x5BAC 宬 (<CJK Ideograph>) 18230 0x6027 性 (<CJK Ideograph>) 18231 0x60FA 惺 (<CJK Ideograph>) 18232 0x6210 成 (<CJK Ideograph>) 18233 0x661F 星 (<CJK Ideograph>) 18234 0x665F 晟 (<CJK Ideograph>) 18235 0x7329 猩 (<CJK Ideograph>) 18236 0x73F9 珹 (<CJK Ideograph>) 18237 0x76DB 盛 (<CJK Ideograph>) 18238 0x7701 省 (<CJK Ideograph>) 18239 0x7B6C 筬 (<CJK Ideograph>) 18336 0x8056 聖 (<CJK Ideograph>) 18337 0x8072 聲 (<CJK Ideograph>) 18338 0x8165 腥 (<CJK Ideograph>) 18339 0x8AA0 誠 (<CJK Ideograph>) 18340 0x9192 醒 (<CJK Ideograph>) 18341 0x4E16 世 (<CJK Ideograph>) 18342 0x52E2 勢 (<CJK Ideograph>) 18343 0x6B72 歲 (<CJK Ideograph>) 18344 0x6D17 洗 (<CJK Ideograph>) 18345 0x7A05 稅 (<CJK Ideograph>) 18346 0x7B39 笹 (<CJK Ideograph>) 18347 0x7D30 細 (<CJK Ideograph>) 18348 0xF96F 說 (CJK COMPATIBILITY IDEOGRAPH-F96F) 18349 0x8CB0 貰 (<CJK Ideograph>) 18350 0x53EC 召 (<CJK Ideograph>) 18351 0x562F 嘯 (<CJK Ideograph>) 18352 0x5851 塑 (<CJK Ideograph>) 18353 0x5BB5 宵 (<CJK Ideograph>) 18354 0x5C0F 小 (<CJK Ideograph>) 18355 0x5C11 少 (<CJK Ideograph>) 18356 0x5DE2 巢 (<CJK Ideograph>) 18357 0x6240 所 (<CJK Ideograph>) 18358 0x6383 掃 (<CJK Ideograph>) 18359 0x6414 搔 (<CJK Ideograph>) 18360 0x662D 昭 (<CJK Ideograph>) 18361 0x68B3 梳 (<CJK Ideograph>) 18362 0x6CBC 沼 (<CJK Ideograph>) 18363 0x6D88 消 (<CJK Ideograph>) 18364 0x6EAF 溯 (<CJK Ideograph>) 18365 0x701F 瀟 (<CJK Ideograph>) 18366 0x70A4 炤 (<CJK Ideograph>) 18367 0x71D2 燒 (<CJK Ideograph>) 18368 0x7526 甦 (<CJK Ideograph>) 18369 0x758F 疏 (<CJK Ideograph>) 18370 0x758E 疎 (<CJK Ideograph>) 18371 0x7619 瘙 (<CJK Ideograph>) 18372 0x7B11 笑 (<CJK Ideograph>) 18373 0x7BE0 篠 (<CJK Ideograph>) 18374 0x7C2B 簫 (<CJK Ideograph>) 18375 0x7D20 素 (<CJK Ideograph>) 18376 0x7D39 紹 (<CJK Ideograph>) 18377 0x852C 蔬 (<CJK Ideograph>) 18378 0x856D 蕭 (<CJK Ideograph>) 18379 0x8607 蘇 (<CJK Ideograph>) 18380 0x8A34 訴 (<CJK Ideograph>) 18381 0x900D 逍 (<CJK Ideograph>) 18382 0x9061 遡 (<CJK Ideograph>) 18383 0x90B5 邵 (<CJK Ideograph>) 18384 0x92B7 銷 (<CJK Ideograph>) 18385 0x97F6 韶 (<CJK Ideograph>) 18386 0x9A37 騷 (<CJK Ideograph>) 18387 0x4FD7 俗 (<CJK Ideograph>) 18388 0x5C6C 屬 (<CJK Ideograph>) 18389 0x675F 束 (<CJK Ideograph>) 18390 0x6D91 涑 (<CJK Ideograph>) 18391 0x7C9F 粟 (<CJK Ideograph>) 18392 0x7E8C 續 (<CJK Ideograph>) 18393 0x8B16 謖 (<CJK Ideograph>) 18394 0x8D16 贖 (<CJK Ideograph>) 18395 0x901F 速 (<CJK Ideograph>) 18396 0x5B6B 孫 (<CJK Ideograph>) 18397 0x5DFD 巽 (<CJK Ideograph>) 18398 0x640D 損 (<CJK Ideograph>) 18399 0x84C0 蓀 (<CJK Ideograph>) 18400 0x905C 遜 (<CJK Ideograph>) 18401 0x98E1 飡 (<CJK Ideograph>) 18402 0x7387 率 (<CJK Ideograph>) 18403 0x5B8B 宋 (<CJK Ideograph>) 18404 0x609A 悚 (<CJK Ideograph>) 18405 0x677E 松 (<CJK Ideograph>) 18406 0x6DDE 淞 (<CJK Ideograph>) 18407 0x8A1F 訟 (<CJK Ideograph>) 18408 0x8AA6 誦 (<CJK Ideograph>) 18409 0x9001 送 (<CJK Ideograph>) 18410 0x980C 頌 (<CJK Ideograph>) 18411 0x5237 刷 (<CJK Ideograph>) 18412 0xF970 殺 (CJK COMPATIBILITY IDEOGRAPH-F970) 18413 0x7051 灑 (<CJK Ideograph>) 18414 0x788E 碎 (<CJK Ideograph>) 18415 0x9396 鎖 (<CJK Ideograph>) 18416 0x8870 衰 (<CJK Ideograph>) 18417 0x91D7 釗 (<CJK Ideograph>) 18418 0x4FEE 修 (<CJK Ideograph>) 18419 0x53D7 受 (<CJK Ideograph>) 18420 0x55FD 嗽 (<CJK Ideograph>) 18421 0x56DA 囚 (<CJK Ideograph>) 18422 0x5782 垂 (<CJK Ideograph>) 18423 0x58FD 壽 (<CJK Ideograph>) 18424 0x5AC2 嫂 (<CJK Ideograph>) 18425 0x5B88 守 (<CJK Ideograph>) 18426 0x5CAB 岫 (<CJK Ideograph>) 18427 0x5CC0 峀 (<CJK Ideograph>) 18428 0x5E25 帥 (<CJK Ideograph>) 18429 0x6101 愁 (<CJK Ideograph>) 18526 0x620D 戍 (<CJK Ideograph>) 18527 0x624B 手 (<CJK Ideograph>) 18528 0x6388 授 (<CJK Ideograph>) 18529 0x641C 搜 (<CJK Ideograph>) 18530 0x6536 收 (<CJK Ideograph>) 18531 0x6578 數 (<CJK Ideograph>) 18532 0x6A39 樹 (<CJK Ideograph>) 18533 0x6B8A 殊 (<CJK Ideograph>) 18534 0x6C34 水 (<CJK Ideograph>) 18535 0x6D19 洙 (<CJK Ideograph>) 18536 0x6F31 漱 (<CJK Ideograph>) 18537 0x71E7 燧 (<CJK Ideograph>) 18538 0x72E9 狩 (<CJK Ideograph>) 18539 0x7378 獸 (<CJK Ideograph>) 18540 0x7407 琇 (<CJK Ideograph>) 18541 0x74B2 璲 (<CJK Ideograph>) 18542 0x7626 瘦 (<CJK Ideograph>) 18543 0x7761 睡 (<CJK Ideograph>) 18544 0x79C0 秀 (<CJK Ideograph>) 18545 0x7A57 穗 (<CJK Ideograph>) 18546 0x7AEA 竪 (<CJK Ideograph>) 18547 0x7CB9 粹 (<CJK Ideograph>) 18548 0x7D8F 綏 (<CJK Ideograph>) 18549 0x7DAC 綬 (<CJK Ideograph>) 18550 0x7E61 繡 (<CJK Ideograph>) 18551 0x7F9E 羞 (<CJK Ideograph>) 18552 0x8129 脩 (<CJK Ideograph>) 18553 0x8331 茱 (<CJK Ideograph>) 18554 0x8490 蒐 (<CJK Ideograph>) 18555 0x84DA 蓚 (<CJK Ideograph>) 18556 0x85EA 藪 (<CJK Ideograph>) 18557 0x8896 袖 (<CJK Ideograph>) 18558 0x8AB0 誰 (<CJK Ideograph>) 18559 0x8B90 讐 (<CJK Ideograph>) 18560 0x8F38 輸 (<CJK Ideograph>) 18561 0x9042 遂 (<CJK Ideograph>) 18562 0x9083 邃 (<CJK Ideograph>) 18563 0x916C 酬 (<CJK Ideograph>) 18564 0x9296 銖 (<CJK Ideograph>) 18565 0x92B9 銹 (<CJK Ideograph>) 18566 0x968B 隋 (<CJK Ideograph>) 18567 0x96A7 隧 (<CJK Ideograph>) 18568 0x96A8 隨 (<CJK Ideograph>) 18569 0x96D6 雖 (<CJK Ideograph>) 18570 0x9700 需 (<CJK Ideograph>) 18571 0x9808 須 (<CJK Ideograph>) 18572 0x9996 首 (<CJK Ideograph>) 18573 0x9AD3 髓 (<CJK Ideograph>) 18574 0x9B1A 鬚 (<CJK Ideograph>) 18575 0x53D4 叔 (<CJK Ideograph>) 18576 0x587E 塾 (<CJK Ideograph>) 18577 0x5919 夙 (<CJK Ideograph>) 18578 0x5B70 孰 (<CJK Ideograph>) 18579 0x5BBF 宿 (<CJK Ideograph>) 18580 0x6DD1 淑 (<CJK Ideograph>) 18581 0x6F5A 潚 (<CJK Ideograph>) 18582 0x719F 熟 (<CJK Ideograph>) 18583 0x7421 琡 (<CJK Ideograph>) 18584 0x74B9 璹 (<CJK Ideograph>) 18585 0x8085 肅 (<CJK Ideograph>) 18586 0x83FD 菽 (<CJK Ideograph>) 18587 0x5DE1 巡 (<CJK Ideograph>) 18588 0x5F87 徇 (<CJK Ideograph>) 18589 0x5FAA 循 (<CJK Ideograph>) 18590 0x6042 恂 (<CJK Ideograph>) 18591 0x65EC 旬 (<CJK Ideograph>) 18592 0x6812 栒 (<CJK Ideograph>) 18593 0x696F 楯 (<CJK Ideograph>) 18594 0x6A53 橓 (<CJK Ideograph>) 18595 0x6B89 殉 (<CJK Ideograph>) 18596 0x6D35 洵 (<CJK Ideograph>) 18597 0x6DF3 淳 (<CJK Ideograph>) 18598 0x73E3 珣 (<CJK Ideograph>) 18599 0x76FE 盾 (<CJK Ideograph>) 18600 0x77AC 瞬 (<CJK Ideograph>) 18601 0x7B4D 筍 (<CJK Ideograph>) 18602 0x7D14 純 (<CJK Ideograph>) 18603 0x8123 脣 (<CJK Ideograph>) 18604 0x821C 舜 (<CJK Ideograph>) 18605 0x8340 荀 (<CJK Ideograph>) 18606 0x84F4 蓴 (<CJK Ideograph>) 18607 0x8563 蕣 (<CJK Ideograph>) 18608 0x8A62 詢 (<CJK Ideograph>) 18609 0x8AC4 諄 (<CJK Ideograph>) 18610 0x9187 醇 (<CJK Ideograph>) 18611 0x931E 錞 (<CJK Ideograph>) 18612 0x9806 順 (<CJK Ideograph>) 18613 0x99B4 馴 (<CJK Ideograph>) 18614 0x620C 戌 (<CJK Ideograph>) 18615 0x8853 術 (<CJK Ideograph>) 18616 0x8FF0 述 (<CJK Ideograph>) 18617 0x9265 鉥 (<CJK Ideograph>) 18618 0x5D07 崇 (<CJK Ideograph>) 18619 0x5D27 崧 (<CJK Ideograph>) 18716 0x5D69 嵩 (<CJK Ideograph>) 18717 0x745F 瑟 (<CJK Ideograph>) 18718 0x819D 膝 (<CJK Ideograph>) 18719 0x8768 蝨 (<CJK Ideograph>) 18720 0x6FD5 濕 (<CJK Ideograph>) 18721 0x62FE 拾 (<CJK Ideograph>) 18722 0x7FD2 習 (<CJK Ideograph>) 18723 0x8936 褶 (<CJK Ideograph>) 18724 0x8972 襲 (<CJK Ideograph>) 18725 0x4E1E 丞 (<CJK Ideograph>) 18726 0x4E58 乘 (<CJK Ideograph>) 18727 0x50E7 僧 (<CJK Ideograph>) 18728 0x52DD 勝 (<CJK Ideograph>) 18729 0x5347 升 (<CJK Ideograph>) 18730 0x627F 承 (<CJK Ideograph>) 18731 0x6607 昇 (<CJK Ideograph>) 18732 0x7E69 繩 (<CJK Ideograph>) 18733 0x8805 蠅 (<CJK Ideograph>) 18734 0x965E 陞 (<CJK Ideograph>) 18735 0x4F8D 侍 (<CJK Ideograph>) 18736 0x5319 匙 (<CJK Ideograph>) 18737 0x5636 嘶 (<CJK Ideograph>) 18738 0x59CB 始 (<CJK Ideograph>) 18739 0x5AA4 媤 (<CJK Ideograph>) 18740 0x5C38 尸 (<CJK Ideograph>) 18741 0x5C4E 屎 (<CJK Ideograph>) 18742 0x5C4D 屍 (<CJK Ideograph>) 18743 0x5E02 市 (<CJK Ideograph>) 18744 0x5F11 弑 (<CJK Ideograph>) 18745 0x6043 恃 (<CJK Ideograph>) 18746 0x65BD 施 (<CJK Ideograph>) 18747 0x662F 是 (<CJK Ideograph>) 18748 0x6642 時 (<CJK Ideograph>) 18749 0x67BE 枾 (<CJK Ideograph>) 18750 0x67F4 柴 (<CJK Ideograph>) 18751 0x731C 猜 (<CJK Ideograph>) 18752 0x77E2 矢 (<CJK Ideograph>) 18753 0x793A 示 (<CJK Ideograph>) 18754 0x7FC5 翅 (<CJK Ideograph>) 18755 0x8494 蒔 (<CJK Ideograph>) 18756 0x84CD 蓍 (<CJK Ideograph>) 18757 0x8996 視 (<CJK Ideograph>) 18758 0x8A66 試 (<CJK Ideograph>) 18759 0x8A69 詩 (<CJK Ideograph>) 18760 0x8AE1 諡 (<CJK Ideograph>) 18761 0x8C55 豕 (<CJK Ideograph>) 18762 0x8C7A 豺 (<CJK Ideograph>) 18763 0x57F4 埴 (<CJK Ideograph>) 18764 0x5BD4 寔 (<CJK Ideograph>) 18765 0x5F0F 式 (<CJK Ideograph>) 18766 0x606F 息 (<CJK Ideograph>) 18767 0x62ED 拭 (<CJK Ideograph>) 18768 0x690D 植 (<CJK Ideograph>) 18769 0x6B96 殖 (<CJK Ideograph>) 18770 0x6E5C 湜 (<CJK Ideograph>) 18771 0x7184 熄 (<CJK Ideograph>) 18772 0x7BD2 篒 (<CJK Ideograph>) 18773 0x8755 蝕 (<CJK Ideograph>) 18774 0x8B58 識 (<CJK Ideograph>) 18775 0x8EFE 軾 (<CJK Ideograph>) 18776 0x98DF 食 (<CJK Ideograph>) 18777 0x98FE 飾 (<CJK Ideograph>) 18778 0x4F38 伸 (<CJK Ideograph>) 18779 0x4F81 侁 (<CJK Ideograph>) 18780 0x4FE1 信 (<CJK Ideograph>) 18781 0x547B 呻 (<CJK Ideograph>) 18782 0x5A20 娠 (<CJK Ideograph>) 18783 0x5BB8 宸 (<CJK Ideograph>) 18784 0x613C 愼 (<CJK Ideograph>) 18785 0x65B0 新 (<CJK Ideograph>) 18786 0x6668 晨 (<CJK Ideograph>) 18787 0x71FC 燼 (<CJK Ideograph>) 18788 0x7533 申 (<CJK Ideograph>) 18789 0x795E 神 (<CJK Ideograph>) 18790 0x7D33 紳 (<CJK Ideograph>) 18791 0x814E 腎 (<CJK Ideograph>) 18792 0x81E3 臣 (<CJK Ideograph>) 18793 0x8398 莘 (<CJK Ideograph>) 18794 0x85AA 薪 (<CJK Ideograph>) 18795 0x85CE 藎 (<CJK Ideograph>) 18796 0x8703 蜃 (<CJK Ideograph>) 18797 0x8A0A 訊 (<CJK Ideograph>) 18798 0x8EAB 身 (<CJK Ideograph>) 18799 0x8F9B 辛 (<CJK Ideograph>) 18800 0xF971 辰 (CJK COMPATIBILITY IDEOGRAPH-F971) 18801 0x8FC5 迅 (<CJK Ideograph>) 18802 0x5931 失 (<CJK Ideograph>) 18803 0x5BA4 室 (<CJK Ideograph>) 18804 0x5BE6 實 (<CJK Ideograph>) 18805 0x6089 悉 (<CJK Ideograph>) 18806 0x5BE9 審 (<CJK Ideograph>) 18807 0x5C0B 尋 (<CJK Ideograph>) 18808 0x5FC3 心 (<CJK Ideograph>) 18809 0x6C81 沁 (<CJK Ideograph>) 18906 0xF972 沈 (CJK COMPATIBILITY IDEOGRAPH-F972) 18907 0x6DF1 深 (<CJK Ideograph>) 18908 0x700B 瀋 (<CJK Ideograph>) 18909 0x751A 甚 (<CJK Ideograph>) 18910 0x82AF 芯 (<CJK Ideograph>) 18911 0x8AF6 諶 (<CJK Ideograph>) 18912 0x4EC0 什 (<CJK Ideograph>) 18913 0x5341 十 (<CJK Ideograph>) 18914 0xF973 拾 (CJK COMPATIBILITY IDEOGRAPH-F973) 18915 0x96D9 雙 (<CJK Ideograph>) 18916 0x6C0F 氏 (<CJK Ideograph>) 18917 0x4E9E 亞 (<CJK Ideograph>) 18918 0x4FC4 俄 (<CJK Ideograph>) 18919 0x5152 兒 (<CJK Ideograph>) 18920 0x555E 啞 (<CJK Ideograph>) 18921 0x5A25 娥 (<CJK Ideograph>) 18922 0x5CE8 峨 (<CJK Ideograph>) 18923 0x6211 我 (<CJK Ideograph>) 18924 0x7259 牙 (<CJK Ideograph>) 18925 0x82BD 芽 (<CJK Ideograph>) 18926 0x83AA 莪 (<CJK Ideograph>) 18927 0x86FE 蛾 (<CJK Ideograph>) 18928 0x8859 衙 (<CJK Ideograph>) 18929 0x8A1D 訝 (<CJK Ideograph>) 18930 0x963F 阿 (<CJK Ideograph>) 18931 0x96C5 雅 (<CJK Ideograph>) 18932 0x9913 餓 (<CJK Ideograph>) 18933 0x9D09 鴉 (<CJK Ideograph>) 18934 0x9D5D 鵝 (<CJK Ideograph>) 18935 0x580A 堊 (<CJK Ideograph>) 18936 0x5CB3 岳 (<CJK Ideograph>) 18937 0x5DBD 嶽 (<CJK Ideograph>) 18938 0x5E44 幄 (<CJK Ideograph>) 18939 0x60E1 惡 (<CJK Ideograph>) 18940 0x6115 愕 (<CJK Ideograph>) 18941 0x63E1 握 (<CJK Ideograph>) 18942 0x6A02 樂 (<CJK Ideograph>) 18943 0x6E25 渥 (<CJK Ideograph>) 18944 0x9102 鄂 (<CJK Ideograph>) 18945 0x9354 鍔 (<CJK Ideograph>) 18946 0x984E 顎 (<CJK Ideograph>) 18947 0x9C10 鰐 (<CJK Ideograph>) 18948 0x9F77 齷 (<CJK Ideograph>) 18949 0x5B89 安 (<CJK Ideograph>) 18950 0x5CB8 岸 (<CJK Ideograph>) 18951 0x6309 按 (<CJK Ideograph>) 18952 0x664F 晏 (<CJK Ideograph>) 18953 0x6848 案 (<CJK Ideograph>) 18954 0x773C 眼 (<CJK Ideograph>) 18955 0x96C1 雁 (<CJK Ideograph>) 18956 0x978D 鞍 (<CJK Ideograph>) 18957 0x9854 顔 (<CJK Ideograph>) 18958 0x9B9F 鮟 (<CJK Ideograph>) 18959 0x65A1 斡 (<CJK Ideograph>) 18960 0x8B01 謁 (<CJK Ideograph>) 18961 0x8ECB 軋 (<CJK Ideograph>) 18962 0x95BC 閼 (<CJK Ideograph>) 18963 0x5535 唵 (<CJK Ideograph>) 18964 0x5CA9 岩 (<CJK Ideograph>) 18965 0x5DD6 巖 (<CJK Ideograph>) 18966 0x5EB5 庵 (<CJK Ideograph>) 18967 0x6697 暗 (<CJK Ideograph>) 18968 0x764C 癌 (<CJK Ideograph>) 18969 0x83F4 菴 (<CJK Ideograph>) 18970 0x95C7 闇 (<CJK Ideograph>) 18971 0x58D3 壓 (<CJK Ideograph>) 18972 0x62BC 押 (<CJK Ideograph>) 18973 0x72CE 狎 (<CJK Ideograph>) 18974 0x9D28 鴨 (<CJK Ideograph>) 18975 0x4EF0 仰 (<CJK Ideograph>) 18976 0x592E 央 (<CJK Ideograph>) 18977 0x600F 怏 (<CJK Ideograph>) 18978 0x663B 昻 (<CJK Ideograph>) 18979 0x6B83 殃 (<CJK Ideograph>) 18980 0x79E7 秧 (<CJK Ideograph>) 18981 0x9D26 鴦 (<CJK Ideograph>) 18982 0x5393 厓 (<CJK Ideograph>) 18983 0x54C0 哀 (<CJK Ideograph>) 18984 0x57C3 埃 (<CJK Ideograph>) 18985 0x5D16 崖 (<CJK Ideograph>) 18986 0x611B 愛 (<CJK Ideograph>) 18987 0x66D6 曖 (<CJK Ideograph>) 18988 0x6DAF 涯 (<CJK Ideograph>) 18989 0x788D 碍 (<CJK Ideograph>) 18990 0x827E 艾 (<CJK Ideograph>) 18991 0x9698 隘 (<CJK Ideograph>) 18992 0x9744 靄 (<CJK Ideograph>) 18993 0x5384 厄 (<CJK Ideograph>) 18994 0x627C 扼 (<CJK Ideograph>) 18995 0x6396 掖 (<CJK Ideograph>) 18996 0x6DB2 液 (<CJK Ideograph>) 18997 0x7E0A 縊 (<CJK Ideograph>) 18998 0x814B 腋 (<CJK Ideograph>) 18999 0x984D 額 (<CJK Ideograph>) 19096 0x6AFB 櫻 (<CJK Ideograph>) 19097 0x7F4C 罌 (<CJK Ideograph>) 19098 0x9DAF 鶯 (<CJK Ideograph>) 19099 0x9E1A 鸚 (<CJK Ideograph>) 19100 0x4E5F 也 (<CJK Ideograph>) 19101 0x503B 倻 (<CJK Ideograph>) 19102 0x51B6 冶 (<CJK Ideograph>) 19103 0x591C 夜 (<CJK Ideograph>) 19104 0x60F9 惹 (<CJK Ideograph>) 19105 0x63F6 揶 (<CJK Ideograph>) 19106 0x6930 椰 (<CJK Ideograph>) 19107 0x723A 爺 (<CJK Ideograph>) 19108 0x8036 耶 (<CJK Ideograph>) 19109 0xF974 若 (CJK COMPATIBILITY IDEOGRAPH-F974) 19110 0x91CE 野 (<CJK Ideograph>) 19111 0x5F31 弱 (<CJK Ideograph>) 19112 0xF975 掠 (CJK COMPATIBILITY IDEOGRAPH-F975) 19113 0xF976 略 (CJK COMPATIBILITY IDEOGRAPH-F976) 19114 0x7D04 約 (<CJK Ideograph>) 19115 0x82E5 若 (<CJK Ideograph>) 19116 0x846F 葯 (<CJK Ideograph>) 19117 0x84BB 蒻 (<CJK Ideograph>) 19118 0x85E5 藥 (<CJK Ideograph>) 19119 0x8E8D 躍 (<CJK Ideograph>) 19120 0xF977 亮 (CJK COMPATIBILITY IDEOGRAPH-F977) 19121 0x4F6F 佯 (<CJK Ideograph>) 19122 0xF978 兩 (CJK COMPATIBILITY IDEOGRAPH-F978) 19123 0xF979 凉 (CJK COMPATIBILITY IDEOGRAPH-F979) 19124 0x58E4 壤 (<CJK Ideograph>) 19125 0x5B43 孃 (<CJK Ideograph>) 19126 0x6059 恙 (<CJK Ideograph>) 19127 0x63DA 揚 (<CJK Ideograph>) 19128 0x6518 攘 (<CJK Ideograph>) 19129 0x656D 敭 (<CJK Ideograph>) 19130 0x6698 暘 (<CJK Ideograph>) 19131 0xF97A 梁 (CJK COMPATIBILITY IDEOGRAPH-F97A) 19132 0x694A 楊 (<CJK Ideograph>) 19133 0x6A23 樣 (<CJK Ideograph>) 19134 0x6D0B 洋 (<CJK Ideograph>) 19135 0x7001 瀁 (<CJK Ideograph>) 19136 0x716C 煬 (<CJK Ideograph>) 19137 0x75D2 痒 (<CJK Ideograph>) 19138 0x760D 瘍 (<CJK Ideograph>) 19139 0x79B3 禳 (<CJK Ideograph>) 19140 0x7A70 穰 (<CJK Ideograph>) 19141 0xF97B 糧 (CJK COMPATIBILITY IDEOGRAPH-F97B) 19142 0x7F8A 羊 (<CJK Ideograph>) 19143 0xF97C 良 (CJK COMPATIBILITY IDEOGRAPH-F97C) 19144 0x8944 襄 (<CJK Ideograph>) 19145 0xF97D 諒 (CJK COMPATIBILITY IDEOGRAPH-F97D) 19146 0x8B93 讓 (<CJK Ideograph>) 19147 0x91C0 釀 (<CJK Ideograph>) 19148 0x967D 陽 (<CJK Ideograph>) 19149 0xF97E 量 (CJK COMPATIBILITY IDEOGRAPH-F97E) 19150 0x990A 養 (<CJK Ideograph>) 19151 0x5704 圄 (<CJK Ideograph>) 19152 0x5FA1 御 (<CJK Ideograph>) 19153 0x65BC 於 (<CJK Ideograph>) 19154 0x6F01 漁 (<CJK Ideograph>) 19155 0x7600 瘀 (<CJK Ideograph>) 19156 0x79A6 禦 (<CJK Ideograph>) 19157 0x8A9E 語 (<CJK Ideograph>) 19158 0x99AD 馭 (<CJK Ideograph>) 19159 0x9B5A 魚 (<CJK Ideograph>) 19160 0x9F6C 齬 (<CJK Ideograph>) 19161 0x5104 億 (<CJK Ideograph>) 19162 0x61B6 憶 (<CJK Ideograph>) 19163 0x6291 抑 (<CJK Ideograph>) 19164 0x6A8D 檍 (<CJK Ideograph>) 19165 0x81C6 臆 (<CJK Ideograph>) 19166 0x5043 偃 (<CJK Ideograph>) 19167 0x5830 堰 (<CJK Ideograph>) 19168 0x5F66 彦 (<CJK Ideograph>) 19169 0x7109 焉 (<CJK Ideograph>) 19170 0x8A00 言 (<CJK Ideograph>) 19171 0x8AFA 諺 (<CJK Ideograph>) 19172 0x5B7C 孼 (<CJK Ideograph>) 19173 0x8616 蘖 (<CJK Ideograph>) 19174 0x4FFA 俺 (<CJK Ideograph>) 19175 0x513C 儼 (<CJK Ideograph>) 19176 0x56B4 嚴 (<CJK Ideograph>) 19177 0x5944 奄 (<CJK Ideograph>) 19178 0x63A9 掩 (<CJK Ideograph>) 19179 0x6DF9 淹 (<CJK Ideograph>) 19180 0x5DAA 嶪 (<CJK Ideograph>) 19181 0x696D 業 (<CJK Ideograph>) 19182 0x5186 円 (<CJK Ideograph>) 19183 0x4E88 予 (<CJK Ideograph>) 19184 0x4F59 余 (<CJK Ideograph>) 19185 0xF97F 勵 (CJK COMPATIBILITY IDEOGRAPH-F97F) 19186 0xF980 呂 (CJK COMPATIBILITY IDEOGRAPH-F980) 19187 0xF981 女 (CJK COMPATIBILITY IDEOGRAPH-F981) 19188 0x5982 如 (<CJK Ideograph>) 19189 0xF982 廬 (CJK COMPATIBILITY IDEOGRAPH-F982) 19286 0xF983 旅 (CJK COMPATIBILITY IDEOGRAPH-F983) 19287 0x6B5F 歟 (<CJK Ideograph>) 19288 0x6C5D 汝 (<CJK Ideograph>) 19289 0xF984 濾 (CJK COMPATIBILITY IDEOGRAPH-F984) 19290 0x74B5 璵 (<CJK Ideograph>) 19291 0x7916 礖 (<CJK Ideograph>) 19292 0xF985 礪 (CJK COMPATIBILITY IDEOGRAPH-F985) 19293 0x8207 與 (<CJK Ideograph>) 19294 0x8245 艅 (<CJK Ideograph>) 19295 0x8339 茹 (<CJK Ideograph>) 19296 0x8F3F 輿 (<CJK Ideograph>) 19297 0x8F5D 轝 (<CJK Ideograph>) 19298 0xF986 閭 (CJK COMPATIBILITY IDEOGRAPH-F986) 19299 0x9918 餘 (<CJK Ideograph>) 19300 0xF987 驪 (CJK COMPATIBILITY IDEOGRAPH-F987) 19301 0xF988 麗 (CJK COMPATIBILITY IDEOGRAPH-F988) 19302 0xF989 黎 (CJK COMPATIBILITY IDEOGRAPH-F989) 19303 0x4EA6 亦 (<CJK Ideograph>) 19304 0xF98A 力 (CJK COMPATIBILITY IDEOGRAPH-F98A) 19305 0x57DF 域 (<CJK Ideograph>) 19306 0x5F79 役 (<CJK Ideograph>) 19307 0x6613 易 (<CJK Ideograph>) 19308 0xF98B 曆 (CJK COMPATIBILITY IDEOGRAPH-F98B) 19309 0xF98C 歷 (CJK COMPATIBILITY IDEOGRAPH-F98C) 19310 0x75AB 疫 (<CJK Ideograph>) 19311 0x7E79 繹 (<CJK Ideograph>) 19312 0x8B6F 譯 (<CJK Ideograph>) 19313 0xF98D 轢 (CJK COMPATIBILITY IDEOGRAPH-F98D) 19314 0x9006 逆 (<CJK Ideograph>) 19315 0x9A5B 驛 (<CJK Ideograph>) 19316 0x56A5 嚥 (<CJK Ideograph>) 19317 0x5827 堧 (<CJK Ideograph>) 19318 0x59F8 姸 (<CJK Ideograph>) 19319 0x5A1F 娟 (<CJK Ideograph>) 19320 0x5BB4 宴 (<CJK Ideograph>) 19321 0xF98E 年 (CJK COMPATIBILITY IDEOGRAPH-F98E) 19322 0x5EF6 延 (<CJK Ideograph>) 19323 0xF98F 憐 (CJK COMPATIBILITY IDEOGRAPH-F98F) 19324 0xF990 戀 (CJK COMPATIBILITY IDEOGRAPH-F990) 19325 0x6350 捐 (<CJK Ideograph>) 19326 0x633B 挻 (<CJK Ideograph>) 19327 0xF991 撚 (CJK COMPATIBILITY IDEOGRAPH-F991) 19328 0x693D 椽 (<CJK Ideograph>) 19329 0x6C87 沇 (<CJK Ideograph>) 19330 0x6CBF 沿 (<CJK Ideograph>) 19331 0x6D8E 涎 (<CJK Ideograph>) 19332 0x6D93 涓 (<CJK Ideograph>) 19333 0x6DF5 淵 (<CJK Ideograph>) 19334 0x6F14 演 (<CJK Ideograph>) 19335 0xF992 漣 (CJK COMPATIBILITY IDEOGRAPH-F992) 19336 0x70DF 烟 (<CJK Ideograph>) 19337 0x7136 然 (<CJK Ideograph>) 19338 0x7159 煙 (<CJK Ideograph>) 19339 0xF993 煉 (CJK COMPATIBILITY IDEOGRAPH-F993) 19340 0x71C3 燃 (<CJK Ideograph>) 19341 0x71D5 燕 (<CJK Ideograph>) 19342 0xF994 璉 (CJK COMPATIBILITY IDEOGRAPH-F994) 19343 0x784F 硏 (<CJK Ideograph>) 19344 0x786F 硯 (<CJK Ideograph>) 19345 0xF995 秊 (CJK COMPATIBILITY IDEOGRAPH-F995) 19346 0x7B75 筵 (<CJK Ideograph>) 19347 0x7DE3 緣 (<CJK Ideograph>) 19348 0xF996 練 (CJK COMPATIBILITY IDEOGRAPH-F996) 19349 0x7E2F 縯 (<CJK Ideograph>) 19350 0xF997 聯 (CJK COMPATIBILITY IDEOGRAPH-F997) 19351 0x884D 衍 (<CJK Ideograph>) 19352 0x8EDF 軟 (<CJK Ideograph>) 19353 0xF998 輦 (CJK COMPATIBILITY IDEOGRAPH-F998) 19354 0xF999 蓮 (CJK COMPATIBILITY IDEOGRAPH-F999) 19355 0xF99A 連 (CJK COMPATIBILITY IDEOGRAPH-F99A) 19356 0x925B 鉛 (<CJK Ideograph>) 19357 0xF99B 鍊 (CJK COMPATIBILITY IDEOGRAPH-F99B) 19358 0x9CF6 鳶 (<CJK Ideograph>) 19359 0xF99C 列 (CJK COMPATIBILITY IDEOGRAPH-F99C) 19360 0xF99D 劣 (CJK COMPATIBILITY IDEOGRAPH-F99D) 19361 0xF99E 咽 (CJK COMPATIBILITY IDEOGRAPH-F99E) 19362 0x6085 悅 (<CJK Ideograph>) 19363 0x6D85 涅 (<CJK Ideograph>) 19364 0xF99F 烈 (CJK COMPATIBILITY IDEOGRAPH-F99F) 19365 0x71B1 熱 (<CJK Ideograph>) 19366 0xF9A0 裂 (CJK COMPATIBILITY IDEOGRAPH-F9A0) 19367 0xF9A1 說 (CJK COMPATIBILITY IDEOGRAPH-F9A1) 19368 0x95B1 閱 (<CJK Ideograph>) 19369 0x53AD 厭 (<CJK Ideograph>) 19370 0xF9A2 廉 (CJK COMPATIBILITY IDEOGRAPH-F9A2) 19371 0xF9A3 念 (CJK COMPATIBILITY IDEOGRAPH-F9A3) 19372 0xF9A4 捻 (CJK COMPATIBILITY IDEOGRAPH-F9A4) 19373 0x67D3 染 (<CJK Ideograph>) 19374 0xF9A5 殮 (CJK COMPATIBILITY IDEOGRAPH-F9A5) 19375 0x708E 炎 (<CJK Ideograph>) 19376 0x7130 焰 (<CJK Ideograph>) 19377 0x7430 琰 (<CJK Ideograph>) 19378 0x8276 艶 (<CJK Ideograph>) 19379 0x82D2 苒 (<CJK Ideograph>) 19476 0xF9A6 簾 (CJK COMPATIBILITY IDEOGRAPH-F9A6) 19477 0x95BB 閻 (<CJK Ideograph>) 19478 0x9AE5 髥 (<CJK Ideograph>) 19479 0x9E7D 鹽 (<CJK Ideograph>) 19480 0x66C4 曄 (<CJK Ideograph>) 19481 0xF9A7 獵 (CJK COMPATIBILITY IDEOGRAPH-F9A7) 19482 0x71C1 燁 (<CJK Ideograph>) 19483 0x8449 葉 (<CJK Ideograph>) 19484 0xF9A8 令 (CJK COMPATIBILITY IDEOGRAPH-F9A8) 19485 0xF9A9 囹 (CJK COMPATIBILITY IDEOGRAPH-F9A9) 19486 0x584B 塋 (<CJK Ideograph>) 19487 0xF9AA 寧 (CJK COMPATIBILITY IDEOGRAPH-F9AA) 19488 0xF9AB 嶺 (CJK COMPATIBILITY IDEOGRAPH-F9AB) 19489 0x5DB8 嶸 (<CJK Ideograph>) 19490 0x5F71 影 (<CJK Ideograph>) 19491 0xF9AC 怜 (CJK COMPATIBILITY IDEOGRAPH-F9AC) 19492 0x6620 映 (<CJK Ideograph>) 19493 0x668E 暎 (<CJK Ideograph>) 19494 0x6979 楹 (<CJK Ideograph>) 19495 0x69AE 榮 (<CJK Ideograph>) 19496 0x6C38 永 (<CJK Ideograph>) 19497 0x6CF3 泳 (<CJK Ideograph>) 19498 0x6E36 渶 (<CJK Ideograph>) 19499 0x6F41 潁 (<CJK Ideograph>) 19500 0x6FDA 濚 (<CJK Ideograph>) 19501 0x701B 瀛 (<CJK Ideograph>) 19502 0x702F 瀯 (<CJK Ideograph>) 19503 0x7150 煐 (<CJK Ideograph>) 19504 0x71DF 營 (<CJK Ideograph>) 19505 0x7370 獰 (<CJK Ideograph>) 19506 0xF9AD 玲 (CJK COMPATIBILITY IDEOGRAPH-F9AD) 19507 0x745B 瑛 (<CJK Ideograph>) 19508 0xF9AE 瑩 (CJK COMPATIBILITY IDEOGRAPH-F9AE) 19509 0x74D4 瓔 (<CJK Ideograph>) 19510 0x76C8 盈 (<CJK Ideograph>) 19511 0x7A4E 穎 (<CJK Ideograph>) 19512 0x7E93 纓 (<CJK Ideograph>) 19513 0xF9AF 羚 (CJK COMPATIBILITY IDEOGRAPH-F9AF) 19514 0xF9B0 聆 (CJK COMPATIBILITY IDEOGRAPH-F9B0) 19515 0x82F1 英 (<CJK Ideograph>) 19516 0x8A60 詠 (<CJK Ideograph>) 19517 0x8FCE 迎 (<CJK Ideograph>) 19518 0xF9B1 鈴 (CJK COMPATIBILITY IDEOGRAPH-F9B1) 19519 0x9348 鍈 (<CJK Ideograph>) 19520 0xF9B2 零 (CJK COMPATIBILITY IDEOGRAPH-F9B2) 19521 0x9719 霙 (<CJK Ideograph>) 19522 0xF9B3 靈 (CJK COMPATIBILITY IDEOGRAPH-F9B3) 19523 0xF9B4 領 (CJK COMPATIBILITY IDEOGRAPH-F9B4) 19524 0x4E42 乂 (<CJK Ideograph>) 19525 0x502A 倪 (<CJK Ideograph>) 19526 0xF9B5 例 (CJK COMPATIBILITY IDEOGRAPH-F9B5) 19527 0x5208 刈 (<CJK Ideograph>) 19528 0x53E1 叡 (<CJK Ideograph>) 19529 0x66F3 曳 (<CJK Ideograph>) 19530 0x6C6D 汭 (<CJK Ideograph>) 19531 0x6FCA 濊 (<CJK Ideograph>) 19532 0x730A 猊 (<CJK Ideograph>) 19533 0x777F 睿 (<CJK Ideograph>) 19534 0x7A62 穢 (<CJK Ideograph>) 19535 0x82AE 芮 (<CJK Ideograph>) 19536 0x85DD 藝 (<CJK Ideograph>) 19537 0x8602 蘂 (<CJK Ideograph>) 19538 0xF9B6 禮 (CJK COMPATIBILITY IDEOGRAPH-F9B6) 19539 0x88D4 裔 (<CJK Ideograph>) 19540 0x8A63 詣 (<CJK Ideograph>) 19541 0x8B7D 譽 (<CJK Ideograph>) 19542 0x8C6B 豫 (<CJK Ideograph>) 19543 0xF9B7 醴 (CJK COMPATIBILITY IDEOGRAPH-F9B7) 19544 0x92B3 銳 (<CJK Ideograph>) 19545 0xF9B8 隸 (CJK COMPATIBILITY IDEOGRAPH-F9B8) 19546 0x9713 霓 (<CJK Ideograph>) 19547 0x9810 預 (<CJK Ideograph>) 19548 0x4E94 五 (<CJK Ideograph>) 19549 0x4F0D 伍 (<CJK Ideograph>) 19550 0x4FC9 俉 (<CJK Ideograph>) 19551 0x50B2 傲 (<CJK Ideograph>) 19552 0x5348 午 (<CJK Ideograph>) 19553 0x543E 吾 (<CJK Ideograph>) 19554 0x5433 吳 (<CJK Ideograph>) 19555 0x55DA 嗚 (<CJK Ideograph>) 19556 0x5862 塢 (<CJK Ideograph>) 19557 0x58BA 墺 (<CJK Ideograph>) 19558 0x5967 奧 (<CJK Ideograph>) 19559 0x5A1B 娛 (<CJK Ideograph>) 19560 0x5BE4 寤 (<CJK Ideograph>) 19561 0x609F 悟 (<CJK Ideograph>) 19562 0xF9B9 惡 (CJK COMPATIBILITY IDEOGRAPH-F9B9) 19563 0x61CA 懊 (<CJK Ideograph>) 19564 0x6556 敖 (<CJK Ideograph>) 19565 0x65FF 旿 (<CJK Ideograph>) 19566 0x6664 晤 (<CJK Ideograph>) 19567 0x68A7 梧 (<CJK Ideograph>) 19568 0x6C5A 汚 (<CJK Ideograph>) 19569 0x6FB3 澳 (<CJK Ideograph>) 19666 0x70CF 烏 (<CJK Ideograph>) 19667 0x71AC 熬 (<CJK Ideograph>) 19668 0x7352 獒 (<CJK Ideograph>) 19669 0x7B7D 筽 (<CJK Ideograph>) 19670 0x8708 蜈 (<CJK Ideograph>) 19671 0x8AA4 誤 (<CJK Ideograph>) 19672 0x9C32 鰲 (<CJK Ideograph>) 19673 0x9F07 鼇 (<CJK Ideograph>) 19674 0x5C4B 屋 (<CJK Ideograph>) 19675 0x6C83 沃 (<CJK Ideograph>) 19676 0x7344 獄 (<CJK Ideograph>) 19677 0x7389 玉 (<CJK Ideograph>) 19678 0x923A 鈺 (<CJK Ideograph>) 19679 0x6EAB 溫 (<CJK Ideograph>) 19680 0x7465 瑥 (<CJK Ideograph>) 19681 0x761F 瘟 (<CJK Ideograph>) 19682 0x7A69 穩 (<CJK Ideograph>) 19683 0x7E15 縕 (<CJK Ideograph>) 19684 0x860A 蘊 (<CJK Ideograph>) 19685 0x5140 兀 (<CJK Ideograph>) 19686 0x58C5 壅 (<CJK Ideograph>) 19687 0x64C1 擁 (<CJK Ideograph>) 19688 0x74EE 瓮 (<CJK Ideograph>) 19689 0x7515 甕 (<CJK Ideograph>) 19690 0x7670 癰 (<CJK Ideograph>) 19691 0x7FC1 翁 (<CJK Ideograph>) 19692 0x9095 邕 (<CJK Ideograph>) 19693 0x96CD 雍 (<CJK Ideograph>) 19694 0x9954 饔 (<CJK Ideograph>) 19695 0x6E26 渦 (<CJK Ideograph>) 19696 0x74E6 瓦 (<CJK Ideograph>) 19697 0x7AA9 窩 (<CJK Ideograph>) 19698 0x7AAA 窪 (<CJK Ideograph>) 19699 0x81E5 臥 (<CJK Ideograph>) 19700 0x86D9 蛙 (<CJK Ideograph>) 19701 0x8778 蝸 (<CJK Ideograph>) 19702 0x8A1B 訛 (<CJK Ideograph>) 19703 0x5A49 婉 (<CJK Ideograph>) 19704 0x5B8C 完 (<CJK Ideograph>) 19705 0x5B9B 宛 (<CJK Ideograph>) 19706 0x68A1 梡 (<CJK Ideograph>) 19707 0x6900 椀 (<CJK Ideograph>) 19708 0x6D63 浣 (<CJK Ideograph>) 19709 0x73A9 玩 (<CJK Ideograph>) 19710 0x7413 琓 (<CJK Ideograph>) 19711 0x742C 琬 (<CJK Ideograph>) 19712 0x7897 碗 (<CJK Ideograph>) 19713 0x7DE9 緩 (<CJK Ideograph>) 19714 0x7FEB 翫 (<CJK Ideograph>) 19715 0x8118 脘 (<CJK Ideograph>) 19716 0x8155 腕 (<CJK Ideograph>) 19717 0x839E 莞 (<CJK Ideograph>) 19718 0x8C4C 豌 (<CJK Ideograph>) 19719 0x962E 阮 (<CJK Ideograph>) 19720 0x9811 頑 (<CJK Ideograph>) 19721 0x66F0 曰 (<CJK Ideograph>) 19722 0x5F80 往 (<CJK Ideograph>) 19723 0x65FA 旺 (<CJK Ideograph>) 19724 0x6789 枉 (<CJK Ideograph>) 19725 0x6C6A 汪 (<CJK Ideograph>) 19726 0x738B 王 (<CJK Ideograph>) 19727 0x502D 倭 (<CJK Ideograph>) 19728 0x5A03 娃 (<CJK Ideograph>) 19729 0x6B6A 歪 (<CJK Ideograph>) 19730 0x77EE 矮 (<CJK Ideograph>) 19731 0x5916 外 (<CJK Ideograph>) 19732 0x5D6C 嵬 (<CJK Ideograph>) 19733 0x5DCD 巍 (<CJK Ideograph>) 19734 0x7325 猥 (<CJK Ideograph>) 19735 0x754F 畏 (<CJK Ideograph>) 19736 0xF9BA 了 (CJK COMPATIBILITY IDEOGRAPH-F9BA) 19737 0xF9BB 僚 (CJK COMPATIBILITY IDEOGRAPH-F9BB) 19738 0x50E5 僥 (<CJK Ideograph>) 19739 0x51F9 凹 (<CJK Ideograph>) 19740 0x582F 堯 (<CJK Ideograph>) 19741 0x592D 夭 (<CJK Ideograph>) 19742 0x5996 妖 (<CJK Ideograph>) 19743 0x59DA 姚 (<CJK Ideograph>) 19744 0x5BE5 寥 (<CJK Ideograph>) 19745 0xF9BC 寮 (CJK COMPATIBILITY IDEOGRAPH-F9BC) 19746 0xF9BD 尿 (CJK COMPATIBILITY IDEOGRAPH-F9BD) 19747 0x5DA2 嶢 (<CJK Ideograph>) 19748 0x62D7 拗 (<CJK Ideograph>) 19749 0x6416 搖 (<CJK Ideograph>) 19750 0x6493 撓 (<CJK Ideograph>) 19751 0x64FE 擾 (<CJK Ideograph>) 19752 0xF9BE 料 (CJK COMPATIBILITY IDEOGRAPH-F9BE) 19753 0x66DC 曜 (<CJK Ideograph>) 19754 0xF9BF 樂 (CJK COMPATIBILITY IDEOGRAPH-F9BF) 19755 0x6A48 橈 (<CJK Ideograph>) 19756 0xF9C0 燎 (CJK COMPATIBILITY IDEOGRAPH-F9C0) 19757 0x71FF 燿 (<CJK Ideograph>) 19758 0x7464 瑤 (<CJK Ideograph>) 19759 0xF9C1 療 (CJK COMPATIBILITY IDEOGRAPH-F9C1) 19856 0x7A88 窈 (<CJK Ideograph>) 19857 0x7AAF 窯 (<CJK Ideograph>) 19858 0x7E47 繇 (<CJK Ideograph>) 19859 0x7E5E 繞 (<CJK Ideograph>) 19860 0x8000 耀 (<CJK Ideograph>) 19861 0x8170 腰 (<CJK Ideograph>) 19862 0xF9C2 蓼 (CJK COMPATIBILITY IDEOGRAPH-F9C2) 19863 0x87EF 蟯 (<CJK Ideograph>) 19864 0x8981 要 (<CJK Ideograph>) 19865 0x8B20 謠 (<CJK Ideograph>) 19866 0x9059 遙 (<CJK Ideograph>) 19867 0xF9C3 遼 (CJK COMPATIBILITY IDEOGRAPH-F9C3) 19868 0x9080 邀 (<CJK Ideograph>) 19869 0x9952 饒 (<CJK Ideograph>) 19870 0x617E 慾 (<CJK Ideograph>) 19871 0x6B32 欲 (<CJK Ideograph>) 19872 0x6D74 浴 (<CJK Ideograph>) 19873 0x7E1F 縟 (<CJK Ideograph>) 19874 0x8925 褥 (<CJK Ideograph>) 19875 0x8FB1 辱 (<CJK Ideograph>) 19876 0x4FD1 俑 (<CJK Ideograph>) 19877 0x50AD 傭 (<CJK Ideograph>) 19878 0x5197 冗 (<CJK Ideograph>) 19879 0x52C7 勇 (<CJK Ideograph>) 19880 0x57C7 埇 (<CJK Ideograph>) 19881 0x5889 墉 (<CJK Ideograph>) 19882 0x5BB9 容 (<CJK Ideograph>) 19883 0x5EB8 庸 (<CJK Ideograph>) 19884 0x6142 慂 (<CJK Ideograph>) 19885 0x6995 榕 (<CJK Ideograph>) 19886 0x6D8C 涌 (<CJK Ideograph>) 19887 0x6E67 湧 (<CJK Ideograph>) 19888 0x6EB6 溶 (<CJK Ideograph>) 19889 0x7194 熔 (<CJK Ideograph>) 19890 0x7462 瑢 (<CJK Ideograph>) 19891 0x7528 用 (<CJK Ideograph>) 19892 0x752C 甬 (<CJK Ideograph>) 19893 0x8073 聳 (<CJK Ideograph>) 19894 0x8338 茸 (<CJK Ideograph>) 19895 0x84C9 蓉 (<CJK Ideograph>) 19896 0x8E0A 踊 (<CJK Ideograph>) 19897 0x9394 鎔 (<CJK Ideograph>) 19898 0x93DE 鏞 (<CJK Ideograph>) 19899 0xF9C4 龍 (CJK COMPATIBILITY IDEOGRAPH-F9C4) 19900 0x4E8E 于 (<CJK Ideograph>) 19901 0x4F51 佑 (<CJK Ideograph>) 19902 0x5076 偶 (<CJK Ideograph>) 19903 0x512A 優 (<CJK Ideograph>) 19904 0x53C8 又 (<CJK Ideograph>) 19905 0x53CB 友 (<CJK Ideograph>) 19906 0x53F3 右 (<CJK Ideograph>) 19907 0x5B87 宇 (<CJK Ideograph>) 19908 0x5BD3 寓 (<CJK Ideograph>) 19909 0x5C24 尤 (<CJK Ideograph>) 19910 0x611A 愚 (<CJK Ideograph>) 19911 0x6182 憂 (<CJK Ideograph>) 19912 0x65F4 旴 (<CJK Ideograph>) 19913 0x725B 牛 (<CJK Ideograph>) 19914 0x7397 玗 (<CJK Ideograph>) 19915 0x7440 瑀 (<CJK Ideograph>) 19916 0x76C2 盂 (<CJK Ideograph>) 19917 0x7950 祐 (<CJK Ideograph>) 19918 0x7991 禑 (<CJK Ideograph>) 19919 0x79B9 禹 (<CJK Ideograph>) 19920 0x7D06 紆 (<CJK Ideograph>) 19921 0x7FBD 羽 (<CJK Ideograph>) 19922 0x828B 芋 (<CJK Ideograph>) 19923 0x85D5 藕 (<CJK Ideograph>) 19924 0x865E 虞 (<CJK Ideograph>) 19925 0x8FC2 迂 (<CJK Ideograph>) 19926 0x9047 遇 (<CJK Ideograph>) 19927 0x90F5 郵 (<CJK Ideograph>) 19928 0x91EA 釪 (<CJK Ideograph>) 19929 0x9685 隅 (<CJK Ideograph>) 19930 0x96E8 雨 (<CJK Ideograph>) 19931 0x96E9 雩 (<CJK Ideograph>) 19932 0x52D6 勖 (<CJK Ideograph>) 19933 0x5F67 彧 (<CJK Ideograph>) 19934 0x65ED 旭 (<CJK Ideograph>) 19935 0x6631 昱 (<CJK Ideograph>) 19936 0x682F 栯 (<CJK Ideograph>) 19937 0x715C 煜 (<CJK Ideograph>) 19938 0x7A36 稶 (<CJK Ideograph>) 19939 0x90C1 郁 (<CJK Ideograph>) 19940 0x980A 頊 (<CJK Ideograph>) 19941 0x4E91 云 (<CJK Ideograph>) 19942 0xF9C5 暈 (CJK COMPATIBILITY IDEOGRAPH-F9C5) 19943 0x6A52 橒 (<CJK Ideograph>) 19944 0x6B9E 殞 (<CJK Ideograph>) 19945 0x6F90 澐 (<CJK Ideograph>) 19946 0x7189 熉 (<CJK Ideograph>) 19947 0x8018 耘 (<CJK Ideograph>) 19948 0x82B8 芸 (<CJK Ideograph>) 19949 0x8553 蕓 (<CJK Ideograph>) 20046 0x904B 運 (<CJK Ideograph>) 20047 0x9695 隕 (<CJK Ideograph>) 20048 0x96F2 雲 (<CJK Ideograph>) 20049 0x97FB 韻 (<CJK Ideograph>) 20050 0x851A 蔚 (<CJK Ideograph>) 20051 0x9B31 鬱 (<CJK Ideograph>) 20052 0x4E90 亐 (<CJK Ideograph>) 20053 0x718A 熊 (<CJK Ideograph>) 20054 0x96C4 雄 (<CJK Ideograph>) 20055 0x5143 元 (<CJK Ideograph>) 20056 0x539F 原 (<CJK Ideograph>) 20057 0x54E1 員 (<CJK Ideograph>) 20058 0x5713 圓 (<CJK Ideograph>) 20059 0x5712 園 (<CJK Ideograph>) 20060 0x57A3 垣 (<CJK Ideograph>) 20061 0x5A9B 媛 (<CJK Ideograph>) 20062 0x5AC4 嫄 (<CJK Ideograph>) 20063 0x5BC3 寃 (<CJK Ideograph>) 20064 0x6028 怨 (<CJK Ideograph>) 20065 0x613F 愿 (<CJK Ideograph>) 20066 0x63F4 援 (<CJK Ideograph>) 20067 0x6C85 沅 (<CJK Ideograph>) 20068 0x6D39 洹 (<CJK Ideograph>) 20069 0x6E72 湲 (<CJK Ideograph>) 20070 0x6E90 源 (<CJK Ideograph>) 20071 0x7230 爰 (<CJK Ideograph>) 20072 0x733F 猿 (<CJK Ideograph>) 20073 0x7457 瑗 (<CJK Ideograph>) 20074 0x82D1 苑 (<CJK Ideograph>) 20075 0x8881 袁 (<CJK Ideograph>) 20076 0x8F45 轅 (<CJK Ideograph>) 20077 0x9060 遠 (<CJK Ideograph>) 20078 0xF9C6 阮 (CJK COMPATIBILITY IDEOGRAPH-F9C6) 20079 0x9662 院 (<CJK Ideograph>) 20080 0x9858 願 (<CJK Ideograph>) 20081 0x9D1B 鴛 (<CJK Ideograph>) 20082 0x6708 月 (<CJK Ideograph>) 20083 0x8D8A 越 (<CJK Ideograph>) 20084 0x925E 鉞 (<CJK Ideograph>) 20085 0x4F4D 位 (<CJK Ideograph>) 20086 0x5049 偉 (<CJK Ideograph>) 20087 0x50DE 僞 (<CJK Ideograph>) 20088 0x5371 危 (<CJK Ideograph>) 20089 0x570D 圍 (<CJK Ideograph>) 20090 0x59D4 委 (<CJK Ideograph>) 20091 0x5A01 威 (<CJK Ideograph>) 20092 0x5C09 尉 (<CJK Ideograph>) 20093 0x6170 慰 (<CJK Ideograph>) 20094 0x6690 暐 (<CJK Ideograph>) 20095 0x6E2D 渭 (<CJK Ideograph>) 20096 0x7232 爲 (<CJK Ideograph>) 20097 0x744B 瑋 (<CJK Ideograph>) 20098 0x7DEF 緯 (<CJK Ideograph>) 20099 0x80C3 胃 (<CJK Ideograph>) 20100 0x840E 萎 (<CJK Ideograph>) 20101 0x8466 葦 (<CJK Ideograph>) 20102 0x853F 蔿 (<CJK Ideograph>) 20103 0x875F 蝟 (<CJK Ideograph>) 20104 0x885B 衛 (<CJK Ideograph>) 20105 0x8918 褘 (<CJK Ideograph>) 20106 0x8B02 謂 (<CJK Ideograph>) 20107 0x9055 違 (<CJK Ideograph>) 20108 0x97CB 韋 (<CJK Ideograph>) 20109 0x9B4F 魏 (<CJK Ideograph>) 20110 0x4E73 乳 (<CJK Ideograph>) 20111 0x4F91 侑 (<CJK Ideograph>) 20112 0x5112 儒 (<CJK Ideograph>) 20113 0x516A 兪 (<CJK Ideograph>) 20114 0xF9C7 劉 (CJK COMPATIBILITY IDEOGRAPH-F9C7) 20115 0x552F 唯 (<CJK Ideograph>) 20116 0x55A9 喩 (<CJK Ideograph>) 20117 0x5B7A 孺 (<CJK Ideograph>) 20118 0x5BA5 宥 (<CJK Ideograph>) 20119 0x5E7C 幼 (<CJK Ideograph>) 20120 0x5E7D 幽 (<CJK Ideograph>) 20121 0x5EBE 庾 (<CJK Ideograph>) 20122 0x60A0 悠 (<CJK Ideograph>) 20123 0x60DF 惟 (<CJK Ideograph>) 20124 0x6108 愈 (<CJK Ideograph>) 20125 0x6109 愉 (<CJK Ideograph>) 20126 0x63C4 揄 (<CJK Ideograph>) 20127 0x6538 攸 (<CJK Ideograph>) 20128 0x6709 有 (<CJK Ideograph>) 20129 0xF9C8 杻 (CJK COMPATIBILITY IDEOGRAPH-F9C8) 20130 0x67D4 柔 (<CJK Ideograph>) 20131 0x67DA 柚 (<CJK Ideograph>) 20132 0xF9C9 柳 (CJK COMPATIBILITY IDEOGRAPH-F9C9) 20133 0x6961 楡 (<CJK Ideograph>) 20134 0x6962 楢 (<CJK Ideograph>) 20135 0x6CB9 油 (<CJK Ideograph>) 20136 0x6D27 洧 (<CJK Ideograph>) 20137 0xF9CA 流 (CJK COMPATIBILITY IDEOGRAPH-F9CA) 20138 0x6E38 游 (<CJK Ideograph>) 20139 0xF9CB 溜 (CJK COMPATIBILITY IDEOGRAPH-F9CB) 20236 0x6FE1 濡 (<CJK Ideograph>) 20237 0x7336 猶 (<CJK Ideograph>) 20238 0x7337 猷 (<CJK Ideograph>) 20239 0xF9CC 琉 (CJK COMPATIBILITY IDEOGRAPH-F9CC) 20240 0x745C 瑜 (<CJK Ideograph>) 20241 0x7531 由 (<CJK Ideograph>) 20242 0xF9CD 留 (CJK COMPATIBILITY IDEOGRAPH-F9CD) 20243 0x7652 癒 (<CJK Ideograph>) 20244 0xF9CE 硫 (CJK COMPATIBILITY IDEOGRAPH-F9CE) 20245 0xF9CF 紐 (CJK COMPATIBILITY IDEOGRAPH-F9CF) 20246 0x7DAD 維 (<CJK Ideograph>) 20247 0x81FE 臾 (<CJK Ideograph>) 20248 0x8438 萸 (<CJK Ideograph>) 20249 0x88D5 裕 (<CJK Ideograph>) 20250 0x8A98 誘 (<CJK Ideograph>) 20251 0x8ADB 諛 (<CJK Ideograph>) 20252 0x8AED 諭 (<CJK Ideograph>) 20253 0x8E30 踰 (<CJK Ideograph>) 20254 0x8E42 蹂 (<CJK Ideograph>) 20255 0x904A 遊 (<CJK Ideograph>) 20256 0x903E 逾 (<CJK Ideograph>) 20257 0x907A 遺 (<CJK Ideograph>) 20258 0x9149 酉 (<CJK Ideograph>) 20259 0x91C9 釉 (<CJK Ideograph>) 20260 0x936E 鍮 (<CJK Ideograph>) 20261 0xF9D0 類 (CJK COMPATIBILITY IDEOGRAPH-F9D0) 20262 0xF9D1 六 (CJK COMPATIBILITY IDEOGRAPH-F9D1) 20263 0x5809 堉 (<CJK Ideograph>) 20264 0xF9D2 戮 (CJK COMPATIBILITY IDEOGRAPH-F9D2) 20265 0x6BD3 毓 (<CJK Ideograph>) 20266 0x8089 肉 (<CJK Ideograph>) 20267 0x80B2 育 (<CJK Ideograph>) 20268 0xF9D3 陸 (CJK COMPATIBILITY IDEOGRAPH-F9D3) 20269 0xF9D4 倫 (CJK COMPATIBILITY IDEOGRAPH-F9D4) 20270 0x5141 允 (<CJK Ideograph>) 20271 0x596B 奫 (<CJK Ideograph>) 20272 0x5C39 尹 (<CJK Ideograph>) 20273 0xF9D5 崙 (CJK COMPATIBILITY IDEOGRAPH-F9D5) 20274 0xF9D6 淪 (CJK COMPATIBILITY IDEOGRAPH-F9D6) 20275 0x6F64 潤 (<CJK Ideograph>) 20276 0x73A7 玧 (<CJK Ideograph>) 20277 0x80E4 胤 (<CJK Ideograph>) 20278 0x8D07 贇 (<CJK Ideograph>) 20279 0xF9D7 輪 (CJK COMPATIBILITY IDEOGRAPH-F9D7) 20280 0x9217 鈗 (<CJK Ideograph>) 20281 0x958F 閏 (<CJK Ideograph>) 20282 0xF9D8 律 (CJK COMPATIBILITY IDEOGRAPH-F9D8) 20283 0xF9D9 慄 (CJK COMPATIBILITY IDEOGRAPH-F9D9) 20284 0xF9DA 栗 (CJK COMPATIBILITY IDEOGRAPH-F9DA) 20285 0xF9DB 率 (CJK COMPATIBILITY IDEOGRAPH-F9DB) 20286 0x807F 聿 (<CJK Ideograph>) 20287 0x620E 戎 (<CJK Ideograph>) 20288 0x701C 瀜 (<CJK Ideograph>) 20289 0x7D68 絨 (<CJK Ideograph>) 20290 0x878D 融 (<CJK Ideograph>) 20291 0xF9DC 隆 (CJK COMPATIBILITY IDEOGRAPH-F9DC) 20292 0x57A0 垠 (<CJK Ideograph>) 20293 0x6069 恩 (<CJK Ideograph>) 20294 0x6147 慇 (<CJK Ideograph>) 20295 0x6BB7 殷 (<CJK Ideograph>) 20296 0x8ABE 誾 (<CJK Ideograph>) 20297 0x9280 銀 (<CJK Ideograph>) 20298 0x96B1 隱 (<CJK Ideograph>) 20299 0x4E59 乙 (<CJK Ideograph>) 20300 0x541F 吟 (<CJK Ideograph>) 20301 0x6DEB 淫 (<CJK Ideograph>) 20302 0x852D 蔭 (<CJK Ideograph>) 20303 0x9670 陰 (<CJK Ideograph>) 20304 0x97F3 音 (<CJK Ideograph>) 20305 0x98EE 飮 (<CJK Ideograph>) 20306 0x63D6 揖 (<CJK Ideograph>) 20307 0x6CE3 泣 (<CJK Ideograph>) 20308 0x9091 邑 (<CJK Ideograph>) 20309 0x51DD 凝 (<CJK Ideograph>) 20310 0x61C9 應 (<CJK Ideograph>) 20311 0x81BA 膺 (<CJK Ideograph>) 20312 0x9DF9 鷹 (<CJK Ideograph>) 20313 0x4F9D 依 (<CJK Ideograph>) 20314 0x501A 倚 (<CJK Ideograph>) 20315 0x5100 儀 (<CJK Ideograph>) 20316 0x5B9C 宜 (<CJK Ideograph>) 20317 0x610F 意 (<CJK Ideograph>) 20318 0x61FF 懿 (<CJK Ideograph>) 20319 0x64EC 擬 (<CJK Ideograph>) 20320 0x6905 椅 (<CJK Ideograph>) 20321 0x6BC5 毅 (<CJK Ideograph>) 20322 0x7591 疑 (<CJK Ideograph>) 20323 0x77E3 矣 (<CJK Ideograph>) 20324 0x7FA9 義 (<CJK Ideograph>) 20325 0x8264 艤 (<CJK Ideograph>) 20326 0x858F 薏 (<CJK Ideograph>) 20327 0x87FB 蟻 (<CJK Ideograph>) 20328 0x8863 衣 (<CJK Ideograph>) 20329 0x8ABC 誼 (<CJK Ideograph>) 20426 0x8B70 議 (<CJK Ideograph>) 20427 0x91AB 醫 (<CJK Ideograph>) 20428 0x4E8C 二 (<CJK Ideograph>) 20429 0x4EE5 以 (<CJK Ideograph>) 20430 0x4F0A 伊 (<CJK Ideograph>) 20431 0xF9DD 利 (CJK COMPATIBILITY IDEOGRAPH-F9DD) 20432 0xF9DE 吏 (CJK COMPATIBILITY IDEOGRAPH-F9DE) 20433 0x5937 夷 (<CJK Ideograph>) 20434 0x59E8 姨 (<CJK Ideograph>) 20435 0xF9DF 履 (CJK COMPATIBILITY IDEOGRAPH-F9DF) 20436 0x5DF2 已 (<CJK Ideograph>) 20437 0x5F1B 弛 (<CJK Ideograph>) 20438 0x5F5B 彛 (<CJK Ideograph>) 20439 0x6021 怡 (<CJK Ideograph>) 20440 0xF9E0 易 (CJK COMPATIBILITY IDEOGRAPH-F9E0) 20441 0xF9E1 李 (CJK COMPATIBILITY IDEOGRAPH-F9E1) 20442 0xF9E2 梨 (CJK COMPATIBILITY IDEOGRAPH-F9E2) 20443 0xF9E3 泥 (CJK COMPATIBILITY IDEOGRAPH-F9E3) 20444 0x723E 爾 (<CJK Ideograph>) 20445 0x73E5 珥 (<CJK Ideograph>) 20446 0xF9E4 理 (CJK COMPATIBILITY IDEOGRAPH-F9E4) 20447 0x7570 異 (<CJK Ideograph>) 20448 0x75CD 痍 (<CJK Ideograph>) 20449 0xF9E5 痢 (CJK COMPATIBILITY IDEOGRAPH-F9E5) 20450 0x79FB 移 (<CJK Ideograph>) 20451 0xF9E6 罹 (CJK COMPATIBILITY IDEOGRAPH-F9E6) 20452 0x800C 而 (<CJK Ideograph>) 20453 0x8033 耳 (<CJK Ideograph>) 20454 0x8084 肄 (<CJK Ideograph>) 20455 0x82E1 苡 (<CJK Ideograph>) 20456 0x8351 荑 (<CJK Ideograph>) 20457 0xF9E7 裏 (CJK COMPATIBILITY IDEOGRAPH-F9E7) 20458 0xF9E8 裡 (CJK COMPATIBILITY IDEOGRAPH-F9E8) 20459 0x8CBD 貽 (<CJK Ideograph>) 20460 0x8CB3 貳 (<CJK Ideograph>) 20461 0x9087 邇 (<CJK Ideograph>) 20462 0xF9E9 里 (CJK COMPATIBILITY IDEOGRAPH-F9E9) 20463 0xF9EA 離 (CJK COMPATIBILITY IDEOGRAPH-F9EA) 20464 0x98F4 飴 (<CJK Ideograph>) 20465 0x990C 餌 (<CJK Ideograph>) 20466 0xF9EB 匿 (CJK COMPATIBILITY IDEOGRAPH-F9EB) 20467 0xF9EC 溺 (CJK COMPATIBILITY IDEOGRAPH-F9EC) 20468 0x7037 瀷 (<CJK Ideograph>) 20469 0x76CA 益 (<CJK Ideograph>) 20470 0x7FCA 翊 (<CJK Ideograph>) 20471 0x7FCC 翌 (<CJK Ideograph>) 20472 0x7FFC 翼 (<CJK Ideograph>) 20473 0x8B1A 謚 (<CJK Ideograph>) 20474 0x4EBA 人 (<CJK Ideograph>) 20475 0x4EC1 仁 (<CJK Ideograph>) 20476 0x5203 刃 (<CJK Ideograph>) 20477 0x5370 印 (<CJK Ideograph>) 20478 0xF9ED 吝 (CJK COMPATIBILITY IDEOGRAPH-F9ED) 20479 0x54BD 咽 (<CJK Ideograph>) 20480 0x56E0 因 (<CJK Ideograph>) 20481 0x59FB 姻 (<CJK Ideograph>) 20482 0x5BC5 寅 (<CJK Ideograph>) 20483 0x5F15 引 (<CJK Ideograph>) 20484 0x5FCD 忍 (<CJK Ideograph>) 20485 0x6E6E 湮 (<CJK Ideograph>) 20486 0xF9EE 燐 (CJK COMPATIBILITY IDEOGRAPH-F9EE) 20487 0xF9EF 璘 (CJK COMPATIBILITY IDEOGRAPH-F9EF) 20488 0x7D6A 絪 (<CJK Ideograph>) 20489 0x8335 茵 (<CJK Ideograph>) 20490 0xF9F0 藺 (CJK COMPATIBILITY IDEOGRAPH-F9F0) 20491 0x8693 蚓 (<CJK Ideograph>) 20492 0x8A8D 認 (<CJK Ideograph>) 20493 0xF9F1 隣 (CJK COMPATIBILITY IDEOGRAPH-F9F1) 20494 0x976D 靭 (<CJK Ideograph>) 20495 0x9777 靷 (<CJK Ideograph>) 20496 0xF9F2 鱗 (CJK COMPATIBILITY IDEOGRAPH-F9F2) 20497 0xF9F3 麟 (CJK COMPATIBILITY IDEOGRAPH-F9F3) 20498 0x4E00 一 (<CJK Ideograph>) 20499 0x4F5A 佚 (<CJK Ideograph>) 20500 0x4F7E 佾 (<CJK Ideograph>) 20501 0x58F9 壹 (<CJK Ideograph>) 20502 0x65E5 日 (<CJK Ideograph>) 20503 0x6EA2 溢 (<CJK Ideograph>) 20504 0x9038 逸 (<CJK Ideograph>) 20505 0x93B0 鎰 (<CJK Ideograph>) 20506 0x99B9 馹 (<CJK Ideograph>) 20507 0x4EFB 任 (<CJK Ideograph>) 20508 0x58EC 壬 (<CJK Ideograph>) 20509 0x598A 妊 (<CJK Ideograph>) 20510 0x59D9 姙 (<CJK Ideograph>) 20511 0x6041 恁 (<CJK Ideograph>) 20512 0xF9F4 林 (CJK COMPATIBILITY IDEOGRAPH-F9F4) 20513 0xF9F5 淋 (CJK COMPATIBILITY IDEOGRAPH-F9F5) 20514 0x7A14 稔 (<CJK Ideograph>) 20515 0xF9F6 臨 (CJK COMPATIBILITY IDEOGRAPH-F9F6) 20516 0x834F 荏 (<CJK Ideograph>) 20517 0x8CC3 賃 (<CJK Ideograph>) 20518 0x5165 入 (<CJK Ideograph>) 20519 0x5344 卄 (<CJK Ideograph>) 20616 0xF9F7 立 (CJK COMPATIBILITY IDEOGRAPH-F9F7) 20617 0xF9F8 笠 (CJK COMPATIBILITY IDEOGRAPH-F9F8) 20618 0xF9F9 粒 (CJK COMPATIBILITY IDEOGRAPH-F9F9) 20619 0x4ECD 仍 (<CJK Ideograph>) 20620 0x5269 剩 (<CJK Ideograph>) 20621 0x5B55 孕 (<CJK Ideograph>) 20622 0x82BF 芿 (<CJK Ideograph>) 20623 0x4ED4 仔 (<CJK Ideograph>) 20624 0x523A 刺 (<CJK Ideograph>) 20625 0x54A8 咨 (<CJK Ideograph>) 20626 0x59C9 姉 (<CJK Ideograph>) 20627 0x59FF 姿 (<CJK Ideograph>) 20628 0x5B50 子 (<CJK Ideograph>) 20629 0x5B57 字 (<CJK Ideograph>) 20630 0x5B5C 孜 (<CJK Ideograph>) 20631 0x6063 恣 (<CJK Ideograph>) 20632 0x6148 慈 (<CJK Ideograph>) 20633 0x6ECB 滋 (<CJK Ideograph>) 20634 0x7099 炙 (<CJK Ideograph>) 20635 0x716E 煮 (<CJK Ideograph>) 20636 0x7386 玆 (<CJK Ideograph>) 20637 0x74F7 瓷 (<CJK Ideograph>) 20638 0x75B5 疵 (<CJK Ideograph>) 20639 0x78C1 磁 (<CJK Ideograph>) 20640 0x7D2B 紫 (<CJK Ideograph>) 20641 0x8005 者 (<CJK Ideograph>) 20642 0x81EA 自 (<CJK Ideograph>) 20643 0x8328 茨 (<CJK Ideograph>) 20644 0x8517 蔗 (<CJK Ideograph>) 20645 0x85C9 藉 (<CJK Ideograph>) 20646 0x8AEE 諮 (<CJK Ideograph>) 20647 0x8CC7 資 (<CJK Ideograph>) 20648 0x96CC 雌 (<CJK Ideograph>) 20649 0x4F5C 作 (<CJK Ideograph>) 20650 0x52FA 勺 (<CJK Ideograph>) 20651 0x56BC 嚼 (<CJK Ideograph>) 20652 0x65AB 斫 (<CJK Ideograph>) 20653 0x6628 昨 (<CJK Ideograph>) 20654 0x707C 灼 (<CJK Ideograph>) 20655 0x70B8 炸 (<CJK Ideograph>) 20656 0x7235 爵 (<CJK Ideograph>) 20657 0x7DBD 綽 (<CJK Ideograph>) 20658 0x828D 芍 (<CJK Ideograph>) 20659 0x914C 酌 (<CJK Ideograph>) 20660 0x96C0 雀 (<CJK Ideograph>) 20661 0x9D72 鵲 (<CJK Ideograph>) 20662 0x5B71 孱 (<CJK Ideograph>) 20663 0x68E7 棧 (<CJK Ideograph>) 20664 0x6B98 殘 (<CJK Ideograph>) 20665 0x6F7A 潺 (<CJK Ideograph>) 20666 0x76DE 盞 (<CJK Ideograph>) 20667 0x5C91 岑 (<CJK Ideograph>) 20668 0x66AB 暫 (<CJK Ideograph>) 20669 0x6F5B 潛 (<CJK Ideograph>) 20670 0x7BB4 箴 (<CJK Ideograph>) 20671 0x7C2A 簪 (<CJK Ideograph>) 20672 0x8836 蠶 (<CJK Ideograph>) 20673 0x96DC 雜 (<CJK Ideograph>) 20674 0x4E08 丈 (<CJK Ideograph>) 20675 0x4ED7 仗 (<CJK Ideograph>) 20676 0x5320 匠 (<CJK Ideograph>) 20677 0x5834 場 (<CJK Ideograph>) 20678 0x58BB 墻 (<CJK Ideograph>) 20679 0x58EF 壯 (<CJK Ideograph>) 20680 0x596C 奬 (<CJK Ideograph>) 20681 0x5C07 將 (<CJK Ideograph>) 20682 0x5E33 帳 (<CJK Ideograph>) 20683 0x5E84 庄 (<CJK Ideograph>) 20684 0x5F35 張 (<CJK Ideograph>) 20685 0x638C 掌 (<CJK Ideograph>) 20686 0x66B2 暲 (<CJK Ideograph>) 20687 0x6756 杖 (<CJK Ideograph>) 20688 0x6A1F 樟 (<CJK Ideograph>) 20689 0x6AA3 檣 (<CJK Ideograph>) 20690 0x6B0C 欌 (<CJK Ideograph>) 20691 0x6F3F 漿 (<CJK Ideograph>) 20692 0x7246 牆 (<CJK Ideograph>) 20693 0xF9FA 狀 (CJK COMPATIBILITY IDEOGRAPH-F9FA) 20694 0x7350 獐 (<CJK Ideograph>) 20695 0x748B 璋 (<CJK Ideograph>) 20696 0x7AE0 章 (<CJK Ideograph>) 20697 0x7CA7 粧 (<CJK Ideograph>) 20698 0x8178 腸 (<CJK Ideograph>) 20699 0x81DF 臟 (<CJK Ideograph>) 20700 0x81E7 臧 (<CJK Ideograph>) 20701 0x838A 莊 (<CJK Ideograph>) 20702 0x846C 葬 (<CJK Ideograph>) 20703 0x8523 蔣 (<CJK Ideograph>) 20704 0x8594 薔 (<CJK Ideograph>) 20705 0x85CF 藏 (<CJK Ideograph>) 20706 0x88DD 裝 (<CJK Ideograph>) 20707 0x8D13 贓 (<CJK Ideograph>) 20708 0x91AC 醬 (<CJK Ideograph>) 20709 0x9577 長 (<CJK Ideograph>) 20806 0x969C 障 (<CJK Ideograph>) 20807 0x518D 再 (<CJK Ideograph>) 20808 0x54C9 哉 (<CJK Ideograph>) 20809 0x5728 在 (<CJK Ideograph>) 20810 0x5BB0 宰 (<CJK Ideograph>) 20811 0x624D 才 (<CJK Ideograph>) 20812 0x6750 材 (<CJK Ideograph>) 20813 0x683D 栽 (<CJK Ideograph>) 20814 0x6893 梓 (<CJK Ideograph>) 20815 0x6E3D 渽 (<CJK Ideograph>) 20816 0x6ED3 滓 (<CJK Ideograph>) 20817 0x707D 災 (<CJK Ideograph>) 20818 0x7E21 縡 (<CJK Ideograph>) 20819 0x88C1 裁 (<CJK Ideograph>) 20820 0x8CA1 財 (<CJK Ideograph>) 20821 0x8F09 載 (<CJK Ideograph>) 20822 0x9F4B 齋 (<CJK Ideograph>) 20823 0x9F4E 齎 (<CJK Ideograph>) 20824 0x722D 爭 (<CJK Ideograph>) 20825 0x7B8F 箏 (<CJK Ideograph>) 20826 0x8ACD 諍 (<CJK Ideograph>) 20827 0x931A 錚 (<CJK Ideograph>) 20828 0x4F47 佇 (<CJK Ideograph>) 20829 0x4F4E 低 (<CJK Ideograph>) 20830 0x5132 儲 (<CJK Ideograph>) 20831 0x5480 咀 (<CJK Ideograph>) 20832 0x59D0 姐 (<CJK Ideograph>) 20833 0x5E95 底 (<CJK Ideograph>) 20834 0x62B5 抵 (<CJK Ideograph>) 20835 0x6775 杵 (<CJK Ideograph>) 20836 0x696E 楮 (<CJK Ideograph>) 20837 0x6A17 樗 (<CJK Ideograph>) 20838 0x6CAE 沮 (<CJK Ideograph>) 20839 0x6E1A 渚 (<CJK Ideograph>) 20840 0x72D9 狙 (<CJK Ideograph>) 20841 0x732A 猪 (<CJK Ideograph>) 20842 0x75BD 疽 (<CJK Ideograph>) 20843 0x7BB8 箸 (<CJK Ideograph>) 20844 0x7D35 紵 (<CJK Ideograph>) 20845 0x82E7 苧 (<CJK Ideograph>) 20846 0x83F9 菹 (<CJK Ideograph>) 20847 0x8457 著 (<CJK Ideograph>) 20848 0x85F7 藷 (<CJK Ideograph>) 20849 0x8A5B 詛 (<CJK Ideograph>) 20850 0x8CAF 貯 (<CJK Ideograph>) 20851 0x8E87 躇 (<CJK Ideograph>) 20852 0x9019 這 (<CJK Ideograph>) 20853 0x90B8 邸 (<CJK Ideograph>) 20854 0x96CE 雎 (<CJK Ideograph>) 20855 0x9F5F 齟 (<CJK Ideograph>) 20856 0x52E3 勣 (<CJK Ideograph>) 20857 0x540A 吊 (<CJK Ideograph>) 20858 0x5AE1 嫡 (<CJK Ideograph>) 20859 0x5BC2 寂 (<CJK Ideograph>) 20860 0x6458 摘 (<CJK Ideograph>) 20861 0x6575 敵 (<CJK Ideograph>) 20862 0x6EF4 滴 (<CJK Ideograph>) 20863 0x72C4 狄 (<CJK Ideograph>) 20864 0xF9FB 炙 (CJK COMPATIBILITY IDEOGRAPH-F9FB) 20865 0x7684 的 (<CJK Ideograph>) 20866 0x7A4D 積 (<CJK Ideograph>) 20867 0x7B1B 笛 (<CJK Ideograph>) 20868 0x7C4D 籍 (<CJK Ideograph>) 20869 0x7E3E 績 (<CJK Ideograph>) 20870 0x7FDF 翟 (<CJK Ideograph>) 20871 0x837B 荻 (<CJK Ideograph>) 20872 0x8B2B 謫 (<CJK Ideograph>) 20873 0x8CCA 賊 (<CJK Ideograph>) 20874 0x8D64 赤 (<CJK Ideograph>) 20875 0x8DE1 跡 (<CJK Ideograph>) 20876 0x8E5F 蹟 (<CJK Ideograph>) 20877 0x8FEA 迪 (<CJK Ideograph>) 20878 0x8FF9 迹 (<CJK Ideograph>) 20879 0x9069 適 (<CJK Ideograph>) 20880 0x93D1 鏑 (<CJK Ideograph>) 20881 0x4F43 佃 (<CJK Ideograph>) 20882 0x4F7A 佺 (<CJK Ideograph>) 20883 0x50B3 傳 (<CJK Ideograph>) 20884 0x5168 全 (<CJK Ideograph>) 20885 0x5178 典 (<CJK Ideograph>) 20886 0x524D 前 (<CJK Ideograph>) 20887 0x526A 剪 (<CJK Ideograph>) 20888 0x5861 塡 (<CJK Ideograph>) 20889 0x587C 塼 (<CJK Ideograph>) 20890 0x5960 奠 (<CJK Ideograph>) 20891 0x5C08 專 (<CJK Ideograph>) 20892 0x5C55 展 (<CJK Ideograph>) 20893 0x5EDB 廛 (<CJK Ideograph>) 20894 0x609B 悛 (<CJK Ideograph>) 20895 0x6230 戰 (<CJK Ideograph>) 20896 0x6813 栓 (<CJK Ideograph>) 20897 0x6BBF 殿 (<CJK Ideograph>) 20898 0x6C08 氈 (<CJK Ideograph>) 20899 0x6FB1 澱 (<CJK Ideograph>) 20996 0x714E 煎 (<CJK Ideograph>) 20997 0x7420 琠 (<CJK Ideograph>) 20998 0x7530 田 (<CJK Ideograph>) 20999 0x7538 甸 (<CJK Ideograph>) 21000 0x7551 畑 (<CJK Ideograph>) 21001 0x7672 癲 (<CJK Ideograph>) 21002 0x7B4C 筌 (<CJK Ideograph>) 21003 0x7B8B 箋 (<CJK Ideograph>) 21004 0x7BAD 箭 (<CJK Ideograph>) 21005 0x7BC6 篆 (<CJK Ideograph>) 21006 0x7E8F 纏 (<CJK Ideograph>) 21007 0x8A6E 詮 (<CJK Ideograph>) 21008 0x8F3E 輾 (<CJK Ideograph>) 21009 0x8F49 轉 (<CJK Ideograph>) 21010 0x923F 鈿 (<CJK Ideograph>) 21011 0x9293 銓 (<CJK Ideograph>) 21012 0x9322 錢 (<CJK Ideograph>) 21013 0x942B 鐫 (<CJK Ideograph>) 21014 0x96FB 電 (<CJK Ideograph>) 21015 0x985A 顚 (<CJK Ideograph>) 21016 0x986B 顫 (<CJK Ideograph>) 21017 0x991E 餞 (<CJK Ideograph>) 21018 0x5207 切 (<CJK Ideograph>) 21019 0x622A 截 (<CJK Ideograph>) 21020 0x6298 折 (<CJK Ideograph>) 21021 0x6D59 浙 (<CJK Ideograph>) 21022 0x7664 癤 (<CJK Ideograph>) 21023 0x7ACA 竊 (<CJK Ideograph>) 21024 0x7BC0 節 (<CJK Ideograph>) 21025 0x7D76 絶 (<CJK Ideograph>) 21026 0x5360 占 (<CJK Ideograph>) 21027 0x5CBE 岾 (<CJK Ideograph>) 21028 0x5E97 店 (<CJK Ideograph>) 21029 0x6F38 漸 (<CJK Ideograph>) 21030 0x70B9 点 (<CJK Ideograph>) 21031 0x7C98 粘 (<CJK Ideograph>) 21032 0x9711 霑 (<CJK Ideograph>) 21033 0x9B8E 鮎 (<CJK Ideograph>) 21034 0x9EDE 點 (<CJK Ideograph>) 21035 0x63A5 接 (<CJK Ideograph>) 21036 0x647A 摺 (<CJK Ideograph>) 21037 0x8776 蝶 (<CJK Ideograph>) 21038 0x4E01 丁 (<CJK Ideograph>) 21039 0x4E95 井 (<CJK Ideograph>) 21040 0x4EAD 亭 (<CJK Ideograph>) 21041 0x505C 停 (<CJK Ideograph>) 21042 0x5075 偵 (<CJK Ideograph>) 21043 0x5448 呈 (<CJK Ideograph>) 21044 0x59C3 姃 (<CJK Ideograph>) 21045 0x5B9A 定 (<CJK Ideograph>) 21046 0x5E40 幀 (<CJK Ideograph>) 21047 0x5EAD 庭 (<CJK Ideograph>) 21048 0x5EF7 廷 (<CJK Ideograph>) 21049 0x5F81 征 (<CJK Ideograph>) 21050 0x60C5 情 (<CJK Ideograph>) 21051 0x633A 挺 (<CJK Ideograph>) 21052 0x653F 政 (<CJK Ideograph>) 21053 0x6574 整 (<CJK Ideograph>) 21054 0x65CC 旌 (<CJK Ideograph>) 21055 0x6676 晶 (<CJK Ideograph>) 21056 0x6678 晸 (<CJK Ideograph>) 21057 0x67FE 柾 (<CJK Ideograph>) 21058 0x6968 楨 (<CJK Ideograph>) 21059 0x6A89 檉 (<CJK Ideograph>) 21060 0x6B63 正 (<CJK Ideograph>) 21061 0x6C40 汀 (<CJK Ideograph>) 21062 0x6DC0 淀 (<CJK Ideograph>) 21063 0x6DE8 淨 (<CJK Ideograph>) 21064 0x6E1F 渟 (<CJK Ideograph>) 21065 0x6E5E 湞 (<CJK Ideograph>) 21066 0x701E 瀞 (<CJK Ideograph>) 21067 0x70A1 炡 (<CJK Ideograph>) 21068 0x738E 玎 (<CJK Ideograph>) 21069 0x73FD 珽 (<CJK Ideograph>) 21070 0x753A 町 (<CJK Ideograph>) 21071 0x775B 睛 (<CJK Ideograph>) 21072 0x7887 碇 (<CJK Ideograph>) 21073 0x798E 禎 (<CJK Ideograph>) 21074 0x7A0B 程 (<CJK Ideograph>) 21075 0x7A7D 穽 (<CJK Ideograph>) 21076 0x7CBE 精 (<CJK Ideograph>) 21077 0x7D8E 綎 (<CJK Ideograph>) 21078 0x8247 艇 (<CJK Ideograph>) 21079 0x8A02 訂 (<CJK Ideograph>) 21080 0x8AEA 諪 (<CJK Ideograph>) 21081 0x8C9E 貞 (<CJK Ideograph>) 21082 0x912D 鄭 (<CJK Ideograph>) 21083 0x914A 酊 (<CJK Ideograph>) 21084 0x91D8 釘 (<CJK Ideograph>) 21085 0x9266 鉦 (<CJK Ideograph>) 21086 0x92CC 鋌 (<CJK Ideograph>) 21087 0x9320 錠 (<CJK Ideograph>) 21088 0x9706 霆 (<CJK Ideograph>) 21089 0x9756 靖 (<CJK Ideograph>) 21186 0x975C 靜 (<CJK Ideograph>) 21187 0x9802 頂 (<CJK Ideograph>) 21188 0x9F0E 鼎 (<CJK Ideograph>) 21189 0x5236 制 (<CJK Ideograph>) 21190 0x5291 劑 (<CJK Ideograph>) 21191 0x557C 啼 (<CJK Ideograph>) 21192 0x5824 堤 (<CJK Ideograph>) 21193 0x5E1D 帝 (<CJK Ideograph>) 21194 0x5F1F 弟 (<CJK Ideograph>) 21195 0x608C 悌 (<CJK Ideograph>) 21196 0x63D0 提 (<CJK Ideograph>) 21197 0x68AF 梯 (<CJK Ideograph>) 21198 0x6FDF 濟 (<CJK Ideograph>) 21199 0x796D 祭 (<CJK Ideograph>) 21200 0x7B2C 第 (<CJK Ideograph>) 21201 0x81CD 臍 (<CJK Ideograph>) 21202 0x85BA 薺 (<CJK Ideograph>) 21203 0x88FD 製 (<CJK Ideograph>) 21204 0x8AF8 諸 (<CJK Ideograph>) 21205 0x8E44 蹄 (<CJK Ideograph>) 21206 0x918D 醍 (<CJK Ideograph>) 21207 0x9664 除 (<CJK Ideograph>) 21208 0x969B 際 (<CJK Ideograph>) 21209 0x973D 霽 (<CJK Ideograph>) 21210 0x984C 題 (<CJK Ideograph>) 21211 0x9F4A 齊 (<CJK Ideograph>) 21212 0x4FCE 俎 (<CJK Ideograph>) 21213 0x5146 兆 (<CJK Ideograph>) 21214 0x51CB 凋 (<CJK Ideograph>) 21215 0x52A9 助 (<CJK Ideograph>) 21216 0x5632 嘲 (<CJK Ideograph>) 21217 0x5F14 弔 (<CJK Ideograph>) 21218 0x5F6B 彫 (<CJK Ideograph>) 21219 0x63AA 措 (<CJK Ideograph>) 21220 0x64CD 操 (<CJK Ideograph>) 21221 0x65E9 早 (<CJK Ideograph>) 21222 0x6641 晁 (<CJK Ideograph>) 21223 0x66FA 曺 (<CJK Ideograph>) 21224 0x66F9 曹 (<CJK Ideograph>) 21225 0x671D 朝 (<CJK Ideograph>) 21226 0x689D 條 (<CJK Ideograph>) 21227 0x68D7 棗 (<CJK Ideograph>) 21228 0x69FD 槽 (<CJK Ideograph>) 21229 0x6F15 漕 (<CJK Ideograph>) 21230 0x6F6E 潮 (<CJK Ideograph>) 21231 0x7167 照 (<CJK Ideograph>) 21232 0x71E5 燥 (<CJK Ideograph>) 21233 0x722A 爪 (<CJK Ideograph>) 21234 0x74AA 璪 (<CJK Ideograph>) 21235 0x773A 眺 (<CJK Ideograph>) 21236 0x7956 祖 (<CJK Ideograph>) 21237 0x795A 祚 (<CJK Ideograph>) 21238 0x79DF 租 (<CJK Ideograph>) 21239 0x7A20 稠 (<CJK Ideograph>) 21240 0x7A95 窕 (<CJK Ideograph>) 21241 0x7C97 粗 (<CJK Ideograph>) 21242 0x7CDF 糟 (<CJK Ideograph>) 21243 0x7D44 組 (<CJK Ideograph>) 21244 0x7E70 繰 (<CJK Ideograph>) 21245 0x8087 肇 (<CJK Ideograph>) 21246 0x85FB 藻 (<CJK Ideograph>) 21247 0x86A4 蚤 (<CJK Ideograph>) 21248 0x8A54 詔 (<CJK Ideograph>) 21249 0x8ABF 調 (<CJK Ideograph>) 21250 0x8D99 趙 (<CJK Ideograph>) 21251 0x8E81 躁 (<CJK Ideograph>) 21252 0x9020 造 (<CJK Ideograph>) 21253 0x906D 遭 (<CJK Ideograph>) 21254 0x91E3 釣 (<CJK Ideograph>) 21255 0x963B 阻 (<CJK Ideograph>) 21256 0x96D5 雕 (<CJK Ideograph>) 21257 0x9CE5 鳥 (<CJK Ideograph>) 21258 0x65CF 族 (<CJK Ideograph>) 21259 0x7C07 簇 (<CJK Ideograph>) 21260 0x8DB3 足 (<CJK Ideograph>) 21261 0x93C3 鏃 (<CJK Ideograph>) 21262 0x5B58 存 (<CJK Ideograph>) 21263 0x5C0A 尊 (<CJK Ideograph>) 21264 0x5352 卒 (<CJK Ideograph>) 21265 0x62D9 拙 (<CJK Ideograph>) 21266 0x731D 猝 (<CJK Ideograph>) 21267 0x5027 倧 (<CJK Ideograph>) 21268 0x5B97 宗 (<CJK Ideograph>) 21269 0x5F9E 從 (<CJK Ideograph>) 21270 0x60B0 悰 (<CJK Ideograph>) 21271 0x616B 慫 (<CJK Ideograph>) 21272 0x68D5 棕 (<CJK Ideograph>) 21273 0x6DD9 淙 (<CJK Ideograph>) 21274 0x742E 琮 (<CJK Ideograph>) 21275 0x7A2E 種 (<CJK Ideograph>) 21276 0x7D42 終 (<CJK Ideograph>) 21277 0x7D9C 綜 (<CJK Ideograph>) 21278 0x7E31 縱 (<CJK Ideograph>) 21279 0x816B 腫 (<CJK Ideograph>) 21376 0x8E2A 踪 (<CJK Ideograph>) 21377 0x8E35 踵 (<CJK Ideograph>) 21378 0x937E 鍾 (<CJK Ideograph>) 21379 0x9418 鐘 (<CJK Ideograph>) 21380 0x4F50 佐 (<CJK Ideograph>) 21381 0x5750 坐 (<CJK Ideograph>) 21382 0x5DE6 左 (<CJK Ideograph>) 21383 0x5EA7 座 (<CJK Ideograph>) 21384 0x632B 挫 (<CJK Ideograph>) 21385 0x7F6A 罪 (<CJK Ideograph>) 21386 0x4E3B 主 (<CJK Ideograph>) 21387 0x4F4F 住 (<CJK Ideograph>) 21388 0x4F8F 侏 (<CJK Ideograph>) 21389 0x505A 做 (<CJK Ideograph>) 21390 0x59DD 姝 (<CJK Ideograph>) 21391 0x80C4 胄 (<CJK Ideograph>) 21392 0x546A 呪 (<CJK Ideograph>) 21393 0x5468 周 (<CJK Ideograph>) 21394 0x55FE 嗾 (<CJK Ideograph>) 21395 0x594F 奏 (<CJK Ideograph>) 21396 0x5B99 宙 (<CJK Ideograph>) 21397 0x5DDE 州 (<CJK Ideograph>) 21398 0x5EDA 廚 (<CJK Ideograph>) 21399 0x665D 晝 (<CJK Ideograph>) 21400 0x6731 朱 (<CJK Ideograph>) 21401 0x67F1 柱 (<CJK Ideograph>) 21402 0x682A 株 (<CJK Ideograph>) 21403 0x6CE8 注 (<CJK Ideograph>) 21404 0x6D32 洲 (<CJK Ideograph>) 21405 0x6E4A 湊 (<CJK Ideograph>) 21406 0x6F8D 澍 (<CJK Ideograph>) 21407 0x70B7 炷 (<CJK Ideograph>) 21408 0x73E0 珠 (<CJK Ideograph>) 21409 0x7587 疇 (<CJK Ideograph>) 21410 0x7C4C 籌 (<CJK Ideograph>) 21411 0x7D02 紂 (<CJK Ideograph>) 21412 0x7D2C 紬 (<CJK Ideograph>) 21413 0x7DA2 綢 (<CJK Ideograph>) 21414 0x821F 舟 (<CJK Ideograph>) 21415 0x86DB 蛛 (<CJK Ideograph>) 21416 0x8A3B 註 (<CJK Ideograph>) 21417 0x8A85 誅 (<CJK Ideograph>) 21418 0x8D70 走 (<CJK Ideograph>) 21419 0x8E8A 躊 (<CJK Ideograph>) 21420 0x8F33 輳 (<CJK Ideograph>) 21421 0x9031 週 (<CJK Ideograph>) 21422 0x914E 酎 (<CJK Ideograph>) 21423 0x9152 酒 (<CJK Ideograph>) 21424 0x9444 鑄 (<CJK Ideograph>) 21425 0x99D0 駐 (<CJK Ideograph>) 21426 0x7AF9 竹 (<CJK Ideograph>) 21427 0x7CA5 粥 (<CJK Ideograph>) 21428 0x4FCA 俊 (<CJK Ideograph>) 21429 0x5101 儁 (<CJK Ideograph>) 21430 0x51C6 准 (<CJK Ideograph>) 21431 0x57C8 埈 (<CJK Ideograph>) 21432 0x5BEF 寯 (<CJK Ideograph>) 21433 0x5CFB 峻 (<CJK Ideograph>) 21434 0x6659 晙 (<CJK Ideograph>) 21435 0x6A3D 樽 (<CJK Ideograph>) 21436 0x6D5A 浚 (<CJK Ideograph>) 21437 0x6E96 準 (<CJK Ideograph>) 21438 0x6FEC 濬 (<CJK Ideograph>) 21439 0x710C 焌 (<CJK Ideograph>) 21440 0x756F 畯 (<CJK Ideograph>) 21441 0x7AE3 竣 (<CJK Ideograph>) 21442 0x8822 蠢 (<CJK Ideograph>) 21443 0x9021 逡 (<CJK Ideograph>) 21444 0x9075 遵 (<CJK Ideograph>) 21445 0x96CB 雋 (<CJK Ideograph>) 21446 0x99FF 駿 (<CJK Ideograph>) 21447 0x8301 茁 (<CJK Ideograph>) 21448 0x4E2D 中 (<CJK Ideograph>) 21449 0x4EF2 仲 (<CJK Ideograph>) 21450 0x8846 衆 (<CJK Ideograph>) 21451 0x91CD 重 (<CJK Ideograph>) 21452 0x537D 卽 (<CJK Ideograph>) 21453 0x6ADB 櫛 (<CJK Ideograph>) 21454 0x696B 楫 (<CJK Ideograph>) 21455 0x6C41 汁 (<CJK Ideograph>) 21456 0x847A 葺 (<CJK Ideograph>) 21457 0x589E 增 (<CJK Ideograph>) 21458 0x618E 憎 (<CJK Ideograph>) 21459 0x66FE 曾 (<CJK Ideograph>) 21460 0x62EF 拯 (<CJK Ideograph>) 21461 0x70DD 烝 (<CJK Ideograph>) 21462 0x7511 甑 (<CJK Ideograph>) 21463 0x75C7 症 (<CJK Ideograph>) 21464 0x7E52 繒 (<CJK Ideograph>) 21465 0x84B8 蒸 (<CJK Ideograph>) 21466 0x8B49 證 (<CJK Ideograph>) 21467 0x8D08 贈 (<CJK Ideograph>) 21468 0x4E4B 之 (<CJK Ideograph>) 21469 0x53EA 只 (<CJK Ideograph>) 21566 0x54AB 咫 (<CJK Ideograph>) 21567 0x5730 地 (<CJK Ideograph>) 21568 0x5740 址 (<CJK Ideograph>) 21569 0x5FD7 志 (<CJK Ideograph>) 21570 0x6301 持 (<CJK Ideograph>) 21571 0x6307 指 (<CJK Ideograph>) 21572 0x646F 摯 (<CJK Ideograph>) 21573 0x652F 支 (<CJK Ideograph>) 21574 0x65E8 旨 (<CJK Ideograph>) 21575 0x667A 智 (<CJK Ideograph>) 21576 0x679D 枝 (<CJK Ideograph>) 21577 0x67B3 枳 (<CJK Ideograph>) 21578 0x6B62 止 (<CJK Ideograph>) 21579 0x6C60 池 (<CJK Ideograph>) 21580 0x6C9A 沚 (<CJK Ideograph>) 21581 0x6F2C 漬 (<CJK Ideograph>) 21582 0x77E5 知 (<CJK Ideograph>) 21583 0x7825 砥 (<CJK Ideograph>) 21584 0x7949 祉 (<CJK Ideograph>) 21585 0x7957 祗 (<CJK Ideograph>) 21586 0x7D19 紙 (<CJK Ideograph>) 21587 0x80A2 肢 (<CJK Ideograph>) 21588 0x8102 脂 (<CJK Ideograph>) 21589 0x81F3 至 (<CJK Ideograph>) 21590 0x829D 芝 (<CJK Ideograph>) 21591 0x82B7 芷 (<CJK Ideograph>) 21592 0x8718 蜘 (<CJK Ideograph>) 21593 0x8A8C 誌 (<CJK Ideograph>) 21594 0xF9FC 識 (CJK COMPATIBILITY IDEOGRAPH-F9FC) 21595 0x8D04 贄 (<CJK Ideograph>) 21596 0x8DBE 趾 (<CJK Ideograph>) 21597 0x9072 遲 (<CJK Ideograph>) 21598 0x76F4 直 (<CJK Ideograph>) 21599 0x7A19 稙 (<CJK Ideograph>) 21600 0x7A37 稷 (<CJK Ideograph>) 21601 0x7E54 織 (<CJK Ideograph>) 21602 0x8077 職 (<CJK Ideograph>) 21603 0x5507 唇 (<CJK Ideograph>) 21604 0x55D4 嗔 (<CJK Ideograph>) 21605 0x5875 塵 (<CJK Ideograph>) 21606 0x632F 振 (<CJK Ideograph>) 21607 0x6422 搢 (<CJK Ideograph>) 21608 0x6649 晉 (<CJK Ideograph>) 21609 0x664B 晋 (<CJK Ideograph>) 21610 0x686D 桭 (<CJK Ideograph>) 21611 0x699B 榛 (<CJK Ideograph>) 21612 0x6B84 殄 (<CJK Ideograph>) 21613 0x6D25 津 (<CJK Ideograph>) 21614 0x6EB1 溱 (<CJK Ideograph>) 21615 0x73CD 珍 (<CJK Ideograph>) 21616 0x7468 瑨 (<CJK Ideograph>) 21617 0x74A1 璡 (<CJK Ideograph>) 21618 0x755B 畛 (<CJK Ideograph>) 21619 0x75B9 疹 (<CJK Ideograph>) 21620 0x76E1 盡 (<CJK Ideograph>) 21621 0x771E 眞 (<CJK Ideograph>) 21622 0x778B 瞋 (<CJK Ideograph>) 21623 0x79E6 秦 (<CJK Ideograph>) 21624 0x7E09 縉 (<CJK Ideograph>) 21625 0x7E1D 縝 (<CJK Ideograph>) 21626 0x81FB 臻 (<CJK Ideograph>) 21627 0x852F 蔯 (<CJK Ideograph>) 21628 0x8897 袗 (<CJK Ideograph>) 21629 0x8A3A 診 (<CJK Ideograph>) 21630 0x8CD1 賑 (<CJK Ideograph>) 21631 0x8EEB 軫 (<CJK Ideograph>) 21632 0x8FB0 辰 (<CJK Ideograph>) 21633 0x9032 進 (<CJK Ideograph>) 21634 0x93AD 鎭 (<CJK Ideograph>) 21635 0x9663 陣 (<CJK Ideograph>) 21636 0x9673 陳 (<CJK Ideograph>) 21637 0x9707 震 (<CJK Ideograph>) 21638 0x4F84 侄 (<CJK Ideograph>) 21639 0x53F1 叱 (<CJK Ideograph>) 21640 0x59EA 姪 (<CJK Ideograph>) 21641 0x5AC9 嫉 (<CJK Ideograph>) 21642 0x5E19 帙 (<CJK Ideograph>) 21643 0x684E 桎 (<CJK Ideograph>) 21644 0x74C6 瓆 (<CJK Ideograph>) 21645 0x75BE 疾 (<CJK Ideograph>) 21646 0x79E9 秩 (<CJK Ideograph>) 21647 0x7A92 窒 (<CJK Ideograph>) 21648 0x81A3 膣 (<CJK Ideograph>) 21649 0x86ED 蛭 (<CJK Ideograph>) 21650 0x8CEA 質 (<CJK Ideograph>) 21651 0x8DCC 跌 (<CJK Ideograph>) 21652 0x8FED 迭 (<CJK Ideograph>) 21653 0x659F 斟 (<CJK Ideograph>) 21654 0x6715 朕 (<CJK Ideograph>) 21655 0xF9FD 什 (CJK COMPATIBILITY IDEOGRAPH-F9FD) 21656 0x57F7 執 (<CJK Ideograph>) 21657 0x6F57 潗 (<CJK Ideograph>) 21658 0x7DDD 緝 (<CJK Ideograph>) 21659 0x8F2F 輯 (<CJK Ideograph>) 21756 0x93F6 鏶 (<CJK Ideograph>) 21757 0x96C6 集 (<CJK Ideograph>) 21758 0x5FB5 徵 (<CJK Ideograph>) 21759 0x61F2 懲 (<CJK Ideograph>) 21760 0x6F84 澄 (<CJK Ideograph>) 21761 0x4E14 且 (<CJK Ideograph>) 21762 0x4F98 侘 (<CJK Ideograph>) 21763 0x501F 借 (<CJK Ideograph>) 21764 0x53C9 叉 (<CJK Ideograph>) 21765 0x55DF 嗟 (<CJK Ideograph>) 21766 0x5D6F 嵯 (<CJK Ideograph>) 21767 0x5DEE 差 (<CJK Ideograph>) 21768 0x6B21 次 (<CJK Ideograph>) 21769 0x6B64 此 (<CJK Ideograph>) 21770 0x78CB 磋 (<CJK Ideograph>) 21771 0x7B9A 箚 (<CJK Ideograph>) 21772 0xF9FE 茶 (CJK COMPATIBILITY IDEOGRAPH-F9FE) 21773 0x8E49 蹉 (<CJK Ideograph>) 21774 0x8ECA 車 (<CJK Ideograph>) 21775 0x906E 遮 (<CJK Ideograph>) 21776 0x6349 捉 (<CJK Ideograph>) 21777 0x643E 搾 (<CJK Ideograph>) 21778 0x7740 着 (<CJK Ideograph>) 21779 0x7A84 窄 (<CJK Ideograph>) 21780 0x932F 錯 (<CJK Ideograph>) 21781 0x947F 鑿 (<CJK Ideograph>) 21782 0x9F6A 齪 (<CJK Ideograph>) 21783 0x64B0 撰 (<CJK Ideograph>) 21784 0x6FAF 澯 (<CJK Ideograph>) 21785 0x71E6 燦 (<CJK Ideograph>) 21786 0x74A8 璨 (<CJK Ideograph>) 21787 0x74DA 瓚 (<CJK Ideograph>) 21788 0x7AC4 竄 (<CJK Ideograph>) 21789 0x7C12 簒 (<CJK Ideograph>) 21790 0x7E82 纂 (<CJK Ideograph>) 21791 0x7CB2 粲 (<CJK Ideograph>) 21792 0x7E98 纘 (<CJK Ideograph>) 21793 0x8B9A 讚 (<CJK Ideograph>) 21794 0x8D0A 贊 (<CJK Ideograph>) 21795 0x947D 鑽 (<CJK Ideograph>) 21796 0x9910 餐 (<CJK Ideograph>) 21797 0x994C 饌 (<CJK Ideograph>) 21798 0x5239 刹 (<CJK Ideograph>) 21799 0x5BDF 察 (<CJK Ideograph>) 21800 0x64E6 擦 (<CJK Ideograph>) 21801 0x672D 札 (<CJK Ideograph>) 21802 0x7D2E 紮 (<CJK Ideograph>) 21803 0x50ED 僭 (<CJK Ideograph>) 21804 0x53C3 參 (<CJK Ideograph>) 21805 0x5879 塹 (<CJK Ideograph>) 21806 0x6158 慘 (<CJK Ideograph>) 21807 0x6159 慙 (<CJK Ideograph>) 21808 0x61FA 懺 (<CJK Ideograph>) 21809 0x65AC 斬 (<CJK Ideograph>) 21810 0x7AD9 站 (<CJK Ideograph>) 21811 0x8B92 讒 (<CJK Ideograph>) 21812 0x8B96 讖 (<CJK Ideograph>) 21813 0x5009 倉 (<CJK Ideograph>) 21814 0x5021 倡 (<CJK Ideograph>) 21815 0x5275 創 (<CJK Ideograph>) 21816 0x5531 唱 (<CJK Ideograph>) 21817 0x5A3C 娼 (<CJK Ideograph>) 21818 0x5EE0 廠 (<CJK Ideograph>) 21819 0x5F70 彰 (<CJK Ideograph>) 21820 0x6134 愴 (<CJK Ideograph>) 21821 0x655E 敞 (<CJK Ideograph>) 21822 0x660C 昌 (<CJK Ideograph>) 21823 0x6636 昶 (<CJK Ideograph>) 21824 0x66A2 暢 (<CJK Ideograph>) 21825 0x69CD 槍 (<CJK Ideograph>) 21826 0x6EC4 滄 (<CJK Ideograph>) 21827 0x6F32 漲 (<CJK Ideograph>) 21828 0x7316 猖 (<CJK Ideograph>) 21829 0x7621 瘡 (<CJK Ideograph>) 21830 0x7A93 窓 (<CJK Ideograph>) 21831 0x8139 脹 (<CJK Ideograph>) 21832 0x8259 艙 (<CJK Ideograph>) 21833 0x83D6 菖 (<CJK Ideograph>) 21834 0x84BC 蒼 (<CJK Ideograph>) 21835 0x50B5 債 (<CJK Ideograph>) 21836 0x57F0 埰 (<CJK Ideograph>) 21837 0x5BC0 寀 (<CJK Ideograph>) 21838 0x5BE8 寨 (<CJK Ideograph>) 21839 0x5F69 彩 (<CJK Ideograph>) 21840 0x63A1 採 (<CJK Ideograph>) 21841 0x7826 砦 (<CJK Ideograph>) 21842 0x7DB5 綵 (<CJK Ideograph>) 21843 0x83DC 菜 (<CJK Ideograph>) 21844 0x8521 蔡 (<CJK Ideograph>) 21845 0x91C7 采 (<CJK Ideograph>) 21846 0x91F5 釵 (<CJK Ideograph>) 21847 0x518A 冊 (<CJK Ideograph>) 21848 0x67F5 柵 (<CJK Ideograph>) 21849 0x7B56 策 (<CJK Ideograph>) 21946 0x8CAC 責 (<CJK Ideograph>) 21947 0x51C4 凄 (<CJK Ideograph>) 21948 0x59BB 妻 (<CJK Ideograph>) 21949 0x60BD 悽 (<CJK Ideograph>) 21950 0x8655 處 (<CJK Ideograph>) 21951 0x501C 倜 (<CJK Ideograph>) 21952 0xF9FF 刺 (CJK COMPATIBILITY IDEOGRAPH-F9FF) 21953 0x5254 剔 (<CJK Ideograph>) 21954 0x5C3A 尺 (<CJK Ideograph>) 21955 0x617D 慽 (<CJK Ideograph>) 21956 0x621A 戚 (<CJK Ideograph>) 21957 0x62D3 拓 (<CJK Ideograph>) 21958 0x64F2 擲 (<CJK Ideograph>) 21959 0x65A5 斥 (<CJK Ideograph>) 21960 0x6ECC 滌 (<CJK Ideograph>) 21961 0x7620 瘠 (<CJK Ideograph>) 21962 0x810A 脊 (<CJK Ideograph>) 21963 0x8E60 蹠 (<CJK Ideograph>) 21964 0x965F 陟 (<CJK Ideograph>) 21965 0x96BB 隻 (<CJK Ideograph>) 21966 0x4EDF 仟 (<CJK Ideograph>) 21967 0x5343 千 (<CJK Ideograph>) 21968 0x5598 喘 (<CJK Ideograph>) 21969 0x5929 天 (<CJK Ideograph>) 21970 0x5DDD 川 (<CJK Ideograph>) 21971 0x64C5 擅 (<CJK Ideograph>) 21972 0x6CC9 泉 (<CJK Ideograph>) 21973 0x6DFA 淺 (<CJK Ideograph>) 21974 0x7394 玔 (<CJK Ideograph>) 21975 0x7A7F 穿 (<CJK Ideograph>) 21976 0x821B 舛 (<CJK Ideograph>) 21977 0x85A6 薦 (<CJK Ideograph>) 21978 0x8CE4 賤 (<CJK Ideograph>) 21979 0x8E10 踐 (<CJK Ideograph>) 21980 0x9077 遷 (<CJK Ideograph>) 21981 0x91E7 釧 (<CJK Ideograph>) 21982 0x95E1 闡 (<CJK Ideograph>) 21983 0x9621 阡 (<CJK Ideograph>) 21984 0x97C6 韆 (<CJK Ideograph>) 21985 0x51F8 凸 (<CJK Ideograph>) 21986 0x54F2 哲 (<CJK Ideograph>) 21987 0x5586 喆 (<CJK Ideograph>) 21988 0x5FB9 徹 (<CJK Ideograph>) 21989 0x64A4 撤 (<CJK Ideograph>) 21990 0x6F88 澈 (<CJK Ideograph>) 21991 0x7DB4 綴 (<CJK Ideograph>) 21992 0x8F1F 輟 (<CJK Ideograph>) 21993 0x8F4D 轍 (<CJK Ideograph>) 21994 0x9435 鐵 (<CJK Ideograph>) 21995 0x50C9 僉 (<CJK Ideograph>) 21996 0x5C16 尖 (<CJK Ideograph>) 21997 0x6CBE 沾 (<CJK Ideograph>) 21998 0x6DFB 添 (<CJK Ideograph>) 21999 0x751B 甛 (<CJK Ideograph>) 22000 0x77BB 瞻 (<CJK Ideograph>) 22001 0x7C3D 簽 (<CJK Ideograph>) 22002 0x7C64 籤 (<CJK Ideograph>) 22003 0x8A79 詹 (<CJK Ideograph>) 22004 0x8AC2 諂 (<CJK Ideograph>) 22005 0x581E 堞 (<CJK Ideograph>) 22006 0x59BE 妾 (<CJK Ideograph>) 22007 0x5E16 帖 (<CJK Ideograph>) 22008 0x6377 捷 (<CJK Ideograph>) 22009 0x7252 牒 (<CJK Ideograph>) 22010 0x758A 疊 (<CJK Ideograph>) 22011 0x776B 睫 (<CJK Ideograph>) 22012 0x8ADC 諜 (<CJK Ideograph>) 22013 0x8CBC 貼 (<CJK Ideograph>) 22014 0x8F12 輒 (<CJK Ideograph>) 22015 0x5EF3 廳 (<CJK Ideograph>) 22016 0x6674 晴 (<CJK Ideograph>) 22017 0x6DF8 淸 (<CJK Ideograph>) 22018 0x807D 聽 (<CJK Ideograph>) 22019 0x83C1 菁 (<CJK Ideograph>) 22020 0x8ACB 請 (<CJK Ideograph>) 22021 0x9751 靑 (<CJK Ideograph>) 22022 0x9BD6 鯖 (<CJK Ideograph>) 22023 0xFA00 切 (CJK COMPATIBILITY IDEOGRAPH-FA00) 22024 0x5243 剃 (<CJK Ideograph>) 22025 0x66FF 替 (<CJK Ideograph>) 22026 0x6D95 涕 (<CJK Ideograph>) 22027 0x6EEF 滯 (<CJK Ideograph>) 22028 0x7DE0 締 (<CJK Ideograph>) 22029 0x8AE6 諦 (<CJK Ideograph>) 22030 0x902E 逮 (<CJK Ideograph>) 22031 0x905E 遞 (<CJK Ideograph>) 22032 0x9AD4 體 (<CJK Ideograph>) 22033 0x521D 初 (<CJK Ideograph>) 22034 0x527F 剿 (<CJK Ideograph>) 22035 0x54E8 哨 (<CJK Ideograph>) 22036 0x6194 憔 (<CJK Ideograph>) 22037 0x6284 抄 (<CJK Ideograph>) 22038 0x62DB 招 (<CJK Ideograph>) 22039 0x68A2 梢 (<CJK Ideograph>) 22136 0x6912 椒 (<CJK Ideograph>) 22137 0x695A 楚 (<CJK Ideograph>) 22138 0x6A35 樵 (<CJK Ideograph>) 22139 0x7092 炒 (<CJK Ideograph>) 22140 0x7126 焦 (<CJK Ideograph>) 22141 0x785D 硝 (<CJK Ideograph>) 22142 0x7901 礁 (<CJK Ideograph>) 22143 0x790E 礎 (<CJK Ideograph>) 22144 0x79D2 秒 (<CJK Ideograph>) 22145 0x7A0D 稍 (<CJK Ideograph>) 22146 0x8096 肖 (<CJK Ideograph>) 22147 0x8278 艸 (<CJK Ideograph>) 22148 0x82D5 苕 (<CJK Ideograph>) 22149 0x8349 草 (<CJK Ideograph>) 22150 0x8549 蕉 (<CJK Ideograph>) 22151 0x8C82 貂 (<CJK Ideograph>) 22152 0x8D85 超 (<CJK Ideograph>) 22153 0x9162 酢 (<CJK Ideograph>) 22154 0x918B 醋 (<CJK Ideograph>) 22155 0x91AE 醮 (<CJK Ideograph>) 22156 0x4FC3 促 (<CJK Ideograph>) 22157 0x56D1 囑 (<CJK Ideograph>) 22158 0x71ED 燭 (<CJK Ideograph>) 22159 0x77D7 矗 (<CJK Ideograph>) 22160 0x8700 蜀 (<CJK Ideograph>) 22161 0x89F8 觸 (<CJK Ideograph>) 22162 0x5BF8 寸 (<CJK Ideograph>) 22163 0x5FD6 忖 (<CJK Ideograph>) 22164 0x6751 村 (<CJK Ideograph>) 22165 0x90A8 邨 (<CJK Ideograph>) 22166 0x53E2 叢 (<CJK Ideograph>) 22167 0x585A 塚 (<CJK Ideograph>) 22168 0x5BF5 寵 (<CJK Ideograph>) 22169 0x60A4 悤 (<CJK Ideograph>) 22170 0x6181 憁 (<CJK Ideograph>) 22171 0x6460 摠 (<CJK Ideograph>) 22172 0x7E3D 總 (<CJK Ideograph>) 22173 0x8070 聰 (<CJK Ideograph>) 22174 0x8525 蔥 (<CJK Ideograph>) 22175 0x9283 銃 (<CJK Ideograph>) 22176 0x64AE 撮 (<CJK Ideograph>) 22177 0x50AC 催 (<CJK Ideograph>) 22178 0x5D14 崔 (<CJK Ideograph>) 22179 0x6700 最 (<CJK Ideograph>) 22180 0x589C 墜 (<CJK Ideograph>) 22181 0x62BD 抽 (<CJK Ideograph>) 22182 0x63A8 推 (<CJK Ideograph>) 22183 0x690E 椎 (<CJK Ideograph>) 22184 0x6978 楸 (<CJK Ideograph>) 22185 0x6A1E 樞 (<CJK Ideograph>) 22186 0x6E6B 湫 (<CJK Ideograph>) 22187 0x76BA 皺 (<CJK Ideograph>) 22188 0x79CB 秋 (<CJK Ideograph>) 22189 0x82BB 芻 (<CJK Ideograph>) 22190 0x8429 萩 (<CJK Ideograph>) 22191 0x8ACF 諏 (<CJK Ideograph>) 22192 0x8DA8 趨 (<CJK Ideograph>) 22193 0x8FFD 追 (<CJK Ideograph>) 22194 0x9112 鄒 (<CJK Ideograph>) 22195 0x914B 酋 (<CJK Ideograph>) 22196 0x919C 醜 (<CJK Ideograph>) 22197 0x9310 錐 (<CJK Ideograph>) 22198 0x9318 錘 (<CJK Ideograph>) 22199 0x939A 鎚 (<CJK Ideograph>) 22200 0x96DB 雛 (<CJK Ideograph>) 22201 0x9A36 騶 (<CJK Ideograph>) 22202 0x9C0D 鰍 (<CJK Ideograph>) 22203 0x4E11 丑 (<CJK Ideograph>) 22204 0x755C 畜 (<CJK Ideograph>) 22205 0x795D 祝 (<CJK Ideograph>) 22206 0x7AFA 竺 (<CJK Ideograph>) 22207 0x7B51 筑 (<CJK Ideograph>) 22208 0x7BC9 築 (<CJK Ideograph>) 22209 0x7E2E 縮 (<CJK Ideograph>) 22210 0x84C4 蓄 (<CJK Ideograph>) 22211 0x8E59 蹙 (<CJK Ideograph>) 22212 0x8E74 蹴 (<CJK Ideograph>) 22213 0x8EF8 軸 (<CJK Ideograph>) 22214 0x9010 逐 (<CJK Ideograph>) 22215 0x6625 春 (<CJK Ideograph>) 22216 0x693F 椿 (<CJK Ideograph>) 22217 0x7443 瑃 (<CJK Ideograph>) 22218 0x51FA 出 (<CJK Ideograph>) 22219 0x672E 朮 (<CJK Ideograph>) 22220 0x9EDC 黜 (<CJK Ideograph>) 22221 0x5145 充 (<CJK Ideograph>) 22222 0x5FE0 忠 (<CJK Ideograph>) 22223 0x6C96 沖 (<CJK Ideograph>) 22224 0x87F2 蟲 (<CJK Ideograph>) 22225 0x885D 衝 (<CJK Ideograph>) 22226 0x8877 衷 (<CJK Ideograph>) 22227 0x60B4 悴 (<CJK Ideograph>) 22228 0x81B5 膵 (<CJK Ideograph>) 22229 0x8403 萃 (<CJK Ideograph>) 22326 0x8D05 贅 (<CJK Ideograph>) 22327 0x53D6 取 (<CJK Ideograph>) 22328 0x5439 吹 (<CJK Ideograph>) 22329 0x5634 嘴 (<CJK Ideograph>) 22330 0x5A36 娶 (<CJK Ideograph>) 22331 0x5C31 就 (<CJK Ideograph>) 22332 0x708A 炊 (<CJK Ideograph>) 22333 0x7FE0 翠 (<CJK Ideograph>) 22334 0x805A 聚 (<CJK Ideograph>) 22335 0x8106 脆 (<CJK Ideograph>) 22336 0x81ED 臭 (<CJK Ideograph>) 22337 0x8DA3 趣 (<CJK Ideograph>) 22338 0x9189 醉 (<CJK Ideograph>) 22339 0x9A5F 驟 (<CJK Ideograph>) 22340 0x9DF2 鷲 (<CJK Ideograph>) 22341 0x5074 側 (<CJK Ideograph>) 22342 0x4EC4 仄 (<CJK Ideograph>) 22343 0x53A0 厠 (<CJK Ideograph>) 22344 0x60FB 惻 (<CJK Ideograph>) 22345 0x6E2C 測 (<CJK Ideograph>) 22346 0x5C64 層 (<CJK Ideograph>) 22347 0x4F88 侈 (<CJK Ideograph>) 22348 0x5024 値 (<CJK Ideograph>) 22349 0x55E4 嗤 (<CJK Ideograph>) 22350 0x5CD9 峙 (<CJK Ideograph>) 22351 0x5E5F 幟 (<CJK Ideograph>) 22352 0x6065 恥 (<CJK Ideograph>) 22353 0x6894 梔 (<CJK Ideograph>) 22354 0x6CBB 治 (<CJK Ideograph>) 22355 0x6DC4 淄 (<CJK Ideograph>) 22356 0x71BE 熾 (<CJK Ideograph>) 22357 0x75D4 痔 (<CJK Ideograph>) 22358 0x75F4 痴 (<CJK Ideograph>) 22359 0x7661 癡 (<CJK Ideograph>) 22360 0x7A1A 稚 (<CJK Ideograph>) 22361 0x7A49 穉 (<CJK Ideograph>) 22362 0x7DC7 緇 (<CJK Ideograph>) 22363 0x7DFB 緻 (<CJK Ideograph>) 22364 0x7F6E 置 (<CJK Ideograph>) 22365 0x81F4 致 (<CJK Ideograph>) 22366 0x86A9 蚩 (<CJK Ideograph>) 22367 0x8F1C 輜 (<CJK Ideograph>) 22368 0x96C9 雉 (<CJK Ideograph>) 22369 0x99B3 馳 (<CJK Ideograph>) 22370 0x9F52 齒 (<CJK Ideograph>) 22371 0x5247 則 (<CJK Ideograph>) 22372 0x52C5 勅 (<CJK Ideograph>) 22373 0x98ED 飭 (<CJK Ideograph>) 22374 0x89AA 親 (<CJK Ideograph>) 22375 0x4E03 七 (<CJK Ideograph>) 22376 0x67D2 柒 (<CJK Ideograph>) 22377 0x6F06 漆 (<CJK Ideograph>) 22378 0x4FB5 侵 (<CJK Ideograph>) 22379 0x5BE2 寢 (<CJK Ideograph>) 22380 0x6795 枕 (<CJK Ideograph>) 22381 0x6C88 沈 (<CJK Ideograph>) 22382 0x6D78 浸 (<CJK Ideograph>) 22383 0x741B 琛 (<CJK Ideograph>) 22384 0x7827 砧 (<CJK Ideograph>) 22385 0x91DD 針 (<CJK Ideograph>) 22386 0x937C 鍼 (<CJK Ideograph>) 22387 0x87C4 蟄 (<CJK Ideograph>) 22388 0x79E4 秤 (<CJK Ideograph>) 22389 0x7A31 稱 (<CJK Ideograph>) 22390 0x5FEB 快 (<CJK Ideograph>) 22391 0x4ED6 他 (<CJK Ideograph>) 22392 0x54A4 咤 (<CJK Ideograph>) 22393 0x553E 唾 (<CJK Ideograph>) 22394 0x58AE 墮 (<CJK Ideograph>) 22395 0x59A5 妥 (<CJK Ideograph>) 22396 0x60F0 惰 (<CJK Ideograph>) 22397 0x6253 打 (<CJK Ideograph>) 22398 0x62D6 拖 (<CJK Ideograph>) 22399 0x6736 朶 (<CJK Ideograph>) 22400 0x6955 楕 (<CJK Ideograph>) 22401 0x8235 舵 (<CJK Ideograph>) 22402 0x9640 陀 (<CJK Ideograph>) 22403 0x99B1 馱 (<CJK Ideograph>) 22404 0x99DD 駝 (<CJK Ideograph>) 22405 0x502C 倬 (<CJK Ideograph>) 22406 0x5353 卓 (<CJK Ideograph>) 22407 0x5544 啄 (<CJK Ideograph>) 22408 0x577C 坼 (<CJK Ideograph>) 22409 0xFA01 度 (CJK COMPATIBILITY IDEOGRAPH-FA01) 22410 0x6258 托 (<CJK Ideograph>) 22411 0xFA02 拓 (CJK COMPATIBILITY IDEOGRAPH-FA02) 22412 0x64E2 擢 (<CJK Ideograph>) 22413 0x666B 晫 (<CJK Ideograph>) 22414 0x67DD 柝 (<CJK Ideograph>) 22415 0x6FC1 濁 (<CJK Ideograph>) 22416 0x6FEF 濯 (<CJK Ideograph>) 22417 0x7422 琢 (<CJK Ideograph>) 22418 0x7438 琸 (<CJK Ideograph>) 22419 0x8A17 託 (<CJK Ideograph>) 22516 0x9438 鐸 (<CJK Ideograph>) 22517 0x5451 呑 (<CJK Ideograph>) 22518 0x5606 嘆 (<CJK Ideograph>) 22519 0x5766 坦 (<CJK Ideograph>) 22520 0x5F48 彈 (<CJK Ideograph>) 22521 0x619A 憚 (<CJK Ideograph>) 22522 0x6B4E 歎 (<CJK Ideograph>) 22523 0x7058 灘 (<CJK Ideograph>) 22524 0x70AD 炭 (<CJK Ideograph>) 22525 0x7DBB 綻 (<CJK Ideograph>) 22526 0x8A95 誕 (<CJK Ideograph>) 22527 0x596A 奪 (<CJK Ideograph>) 22528 0x812B 脫 (<CJK Ideograph>) 22529 0x63A2 探 (<CJK Ideograph>) 22530 0x7708 眈 (<CJK Ideograph>) 22531 0x803D 耽 (<CJK Ideograph>) 22532 0x8CAA 貪 (<CJK Ideograph>) 22533 0x5854 塔 (<CJK Ideograph>) 22534 0x642D 搭 (<CJK Ideograph>) 22535 0x69BB 榻 (<CJK Ideograph>) 22536 0x5B95 宕 (<CJK Ideograph>) 22537 0x5E11 帑 (<CJK Ideograph>) 22538 0x6E6F 湯 (<CJK Ideograph>) 22539 0xFA03 糖 (CJK COMPATIBILITY IDEOGRAPH-FA03) 22540 0x8569 蕩 (<CJK Ideograph>) 22541 0x514C 兌 (<CJK Ideograph>) 22542 0x53F0 台 (<CJK Ideograph>) 22543 0x592A 太 (<CJK Ideograph>) 22544 0x6020 怠 (<CJK Ideograph>) 22545 0x614B 態 (<CJK Ideograph>) 22546 0x6B86 殆 (<CJK Ideograph>) 22547 0x6C70 汰 (<CJK Ideograph>) 22548 0x6CF0 泰 (<CJK Ideograph>) 22549 0x7B1E 笞 (<CJK Ideograph>) 22550 0x80CE 胎 (<CJK Ideograph>) 22551 0x82D4 苔 (<CJK Ideograph>) 22552 0x8DC6 跆 (<CJK Ideograph>) 22553 0x90B0 邰 (<CJK Ideograph>) 22554 0x98B1 颱 (<CJK Ideograph>) 22555 0xFA04 宅 (CJK COMPATIBILITY IDEOGRAPH-FA04) 22556 0x64C7 擇 (<CJK Ideograph>) 22557 0x6FA4 澤 (<CJK Ideograph>) 22558 0x6491 撑 (<CJK Ideograph>) 22559 0x6504 攄 (<CJK Ideograph>) 22560 0x514E 兎 (<CJK Ideograph>) 22561 0x5410 吐 (<CJK Ideograph>) 22562 0x571F 土 (<CJK Ideograph>) 22563 0x8A0E 討 (<CJK Ideograph>) 22564 0x615F 慟 (<CJK Ideograph>) 22565 0x6876 桶 (<CJK Ideograph>) 22566 0xFA05 洞 (CJK COMPATIBILITY IDEOGRAPH-FA05) 22567 0x75DB 痛 (<CJK Ideograph>) 22568 0x7B52 筒 (<CJK Ideograph>) 22569 0x7D71 統 (<CJK Ideograph>) 22570 0x901A 通 (<CJK Ideograph>) 22571 0x5806 堆 (<CJK Ideograph>) 22572 0x69CC 槌 (<CJK Ideograph>) 22573 0x817F 腿 (<CJK Ideograph>) 22574 0x892A 褪 (<CJK Ideograph>) 22575 0x9000 退 (<CJK Ideograph>) 22576 0x9839 頹 (<CJK Ideograph>) 22577 0x5078 偸 (<CJK Ideograph>) 22578 0x5957 套 (<CJK Ideograph>) 22579 0x59AC 妬 (<CJK Ideograph>) 22580 0x6295 投 (<CJK Ideograph>) 22581 0x900F 透 (<CJK Ideograph>) 22582 0x9B2A 鬪 (<CJK Ideograph>) 22583 0x615D 慝 (<CJK Ideograph>) 22584 0x7279 特 (<CJK Ideograph>) 22585 0x95D6 闖 (<CJK Ideograph>) 22586 0x5761 坡 (<CJK Ideograph>) 22587 0x5A46 婆 (<CJK Ideograph>) 22588 0x5DF4 巴 (<CJK Ideograph>) 22589 0x628A 把 (<CJK Ideograph>) 22590 0x64AD 播 (<CJK Ideograph>) 22591 0x64FA 擺 (<CJK Ideograph>) 22592 0x6777 杷 (<CJK Ideograph>) 22593 0x6CE2 波 (<CJK Ideograph>) 22594 0x6D3E 派 (<CJK Ideograph>) 22595 0x722C 爬 (<CJK Ideograph>) 22596 0x7436 琶 (<CJK Ideograph>) 22597 0x7834 破 (<CJK Ideograph>) 22598 0x7F77 罷 (<CJK Ideograph>) 22599 0x82AD 芭 (<CJK Ideograph>) 22600 0x8DDB 跛 (<CJK Ideograph>) 22601 0x9817 頗 (<CJK Ideograph>) 22602 0x5224 判 (<CJK Ideograph>) 22603 0x5742 坂 (<CJK Ideograph>) 22604 0x677F 板 (<CJK Ideograph>) 22605 0x7248 版 (<CJK Ideograph>) 22606 0x74E3 瓣 (<CJK Ideograph>) 22607 0x8CA9 販 (<CJK Ideograph>) 22608 0x8FA6 辦 (<CJK Ideograph>) 22609 0x9211 鈑 (<CJK Ideograph>) 22706 0x962A 阪 (<CJK Ideograph>) 22707 0x516B 八 (<CJK Ideograph>) 22708 0x53ED 叭 (<CJK Ideograph>) 22709 0x634C 捌 (<CJK Ideograph>) 22710 0x4F69 佩 (<CJK Ideograph>) 22711 0x5504 唄 (<CJK Ideograph>) 22712 0x6096 悖 (<CJK Ideograph>) 22713 0x6557 敗 (<CJK Ideograph>) 22714 0x6C9B 沛 (<CJK Ideograph>) 22715 0x6D7F 浿 (<CJK Ideograph>) 22716 0x724C 牌 (<CJK Ideograph>) 22717 0x72FD 狽 (<CJK Ideograph>) 22718 0x7A17 稗 (<CJK Ideograph>) 22719 0x8987 覇 (<CJK Ideograph>) 22720 0x8C9D 貝 (<CJK Ideograph>) 22721 0x5F6D 彭 (<CJK Ideograph>) 22722 0x6F8E 澎 (<CJK Ideograph>) 22723 0x70F9 烹 (<CJK Ideograph>) 22724 0x81A8 膨 (<CJK Ideograph>) 22725 0x610E 愎 (<CJK Ideograph>) 22726 0x4FBF 便 (<CJK Ideograph>) 22727 0x504F 偏 (<CJK Ideograph>) 22728 0x6241 扁 (<CJK Ideograph>) 22729 0x7247 片 (<CJK Ideograph>) 22730 0x7BC7 篇 (<CJK Ideograph>) 22731 0x7DE8 編 (<CJK Ideograph>) 22732 0x7FE9 翩 (<CJK Ideograph>) 22733 0x904D 遍 (<CJK Ideograph>) 22734 0x97AD 鞭 (<CJK Ideograph>) 22735 0x9A19 騙 (<CJK Ideograph>) 22736 0x8CB6 貶 (<CJK Ideograph>) 22737 0x576A 坪 (<CJK Ideograph>) 22738 0x5E73 平 (<CJK Ideograph>) 22739 0x67B0 枰 (<CJK Ideograph>) 22740 0x840D 萍 (<CJK Ideograph>) 22741 0x8A55 評 (<CJK Ideograph>) 22742 0x5420 吠 (<CJK Ideograph>) 22743 0x5B16 嬖 (<CJK Ideograph>) 22744 0x5E63 幣 (<CJK Ideograph>) 22745 0x5EE2 廢 (<CJK Ideograph>) 22746 0x5F0A 弊 (<CJK Ideograph>) 22747 0x6583 斃 (<CJK Ideograph>) 22748 0x80BA 肺 (<CJK Ideograph>) 22749 0x853D 蔽 (<CJK Ideograph>) 22750 0x9589 閉 (<CJK Ideograph>) 22751 0x965B 陛 (<CJK Ideograph>) 22752 0x4F48 佈 (<CJK Ideograph>) 22753 0x5305 包 (<CJK Ideograph>) 22754 0x530D 匍 (<CJK Ideograph>) 22755 0x530F 匏 (<CJK Ideograph>) 22756 0x5486 咆 (<CJK Ideograph>) 22757 0x54FA 哺 (<CJK Ideograph>) 22758 0x5703 圃 (<CJK Ideograph>) 22759 0x5E03 布 (<CJK Ideograph>) 22760 0x6016 怖 (<CJK Ideograph>) 22761 0x629B 抛 (<CJK Ideograph>) 22762 0x62B1 抱 (<CJK Ideograph>) 22763 0x6355 捕 (<CJK Ideograph>) 22764 0xFA06 暴 (CJK COMPATIBILITY IDEOGRAPH-FA06) 22765 0x6CE1 泡 (<CJK Ideograph>) 22766 0x6D66 浦 (<CJK Ideograph>) 22767 0x75B1 疱 (<CJK Ideograph>) 22768 0x7832 砲 (<CJK Ideograph>) 22769 0x80DE 胞 (<CJK Ideograph>) 22770 0x812F 脯 (<CJK Ideograph>) 22771 0x82DE 苞 (<CJK Ideograph>) 22772 0x8461 葡 (<CJK Ideograph>) 22773 0x84B2 蒲 (<CJK Ideograph>) 22774 0x888D 袍 (<CJK Ideograph>) 22775 0x8912 褒 (<CJK Ideograph>) 22776 0x900B 逋 (<CJK Ideograph>) 22777 0x92EA 鋪 (<CJK Ideograph>) 22778 0x98FD 飽 (<CJK Ideograph>) 22779 0x9B91 鮑 (<CJK Ideograph>) 22780 0x5E45 幅 (<CJK Ideograph>) 22781 0x66B4 暴 (<CJK Ideograph>) 22782 0x66DD 曝 (<CJK Ideograph>) 22783 0x7011 瀑 (<CJK Ideograph>) 22784 0x7206 爆 (<CJK Ideograph>) 22785 0xFA07 輻 (CJK COMPATIBILITY IDEOGRAPH-FA07) 22786 0x4FF5 俵 (<CJK Ideograph>) 22787 0x527D 剽 (<CJK Ideograph>) 22788 0x5F6A 彪 (<CJK Ideograph>) 22789 0x6153 慓 (<CJK Ideograph>) 22790 0x6753 杓 (<CJK Ideograph>) 22791 0x6A19 標 (<CJK Ideograph>) 22792 0x6F02 漂 (<CJK Ideograph>) 22793 0x74E2 瓢 (<CJK Ideograph>) 22794 0x7968 票 (<CJK Ideograph>) 22795 0x8868 表 (<CJK Ideograph>) 22796 0x8C79 豹 (<CJK Ideograph>) 22797 0x98C7 飇 (<CJK Ideograph>) 22798 0x98C4 飄 (<CJK Ideograph>) 22799 0x9A43 驃 (<CJK Ideograph>) 22896 0x54C1 品 (<CJK Ideograph>) 22897 0x7A1F 稟 (<CJK Ideograph>) 22898 0x6953 楓 (<CJK Ideograph>) 22899 0x8AF7 諷 (<CJK Ideograph>) 22900 0x8C4A 豊 (<CJK Ideograph>) 22901 0x98A8 風 (<CJK Ideograph>) 22902 0x99AE 馮 (<CJK Ideograph>) 22903 0x5F7C 彼 (<CJK Ideograph>) 22904 0x62AB 披 (<CJK Ideograph>) 22905 0x75B2 疲 (<CJK Ideograph>) 22906 0x76AE 皮 (<CJK Ideograph>) 22907 0x88AB 被 (<CJK Ideograph>) 22908 0x907F 避 (<CJK Ideograph>) 22909 0x9642 陂 (<CJK Ideograph>) 22910 0x5339 匹 (<CJK Ideograph>) 22911 0x5F3C 弼 (<CJK Ideograph>) 22912 0x5FC5 必 (<CJK Ideograph>) 22913 0x6CCC 泌 (<CJK Ideograph>) 22914 0x73CC 珌 (<CJK Ideograph>) 22915 0x7562 畢 (<CJK Ideograph>) 22916 0x758B 疋 (<CJK Ideograph>) 22917 0x7B46 筆 (<CJK Ideograph>) 22918 0x82FE 苾 (<CJK Ideograph>) 22919 0x999D 馝 (<CJK Ideograph>) 22920 0x4E4F 乏 (<CJK Ideograph>) 22921 0x903C 逼 (<CJK Ideograph>) 22922 0x4E0B 下 (<CJK Ideograph>) 22923 0x4F55 何 (<CJK Ideograph>) 22924 0x53A6 厦 (<CJK Ideograph>) 22925 0x590F 夏 (<CJK Ideograph>) 22926 0x5EC8 廈 (<CJK Ideograph>) 22927 0x6630 昰 (<CJK Ideograph>) 22928 0x6CB3 河 (<CJK Ideograph>) 22929 0x7455 瑕 (<CJK Ideograph>) 22930 0x8377 荷 (<CJK Ideograph>) 22931 0x8766 蝦 (<CJK Ideograph>) 22932 0x8CC0 賀 (<CJK Ideograph>) 22933 0x9050 遐 (<CJK Ideograph>) 22934 0x971E 霞 (<CJK Ideograph>) 22935 0x9C15 鰕 (<CJK Ideograph>) 22936 0x58D1 壑 (<CJK Ideograph>) 22937 0x5B78 學 (<CJK Ideograph>) 22938 0x8650 虐 (<CJK Ideograph>) 22939 0x8B14 謔 (<CJK Ideograph>) 22940 0x9DB4 鶴 (<CJK Ideograph>) 22941 0x5BD2 寒 (<CJK Ideograph>) 22942 0x6068 恨 (<CJK Ideograph>) 22943 0x608D 悍 (<CJK Ideograph>) 22944 0x65F1 旱 (<CJK Ideograph>) 22945 0x6C57 汗 (<CJK Ideograph>) 22946 0x6F22 漢 (<CJK Ideograph>) 22947 0x6FA3 澣 (<CJK Ideograph>) 22948 0x701A 瀚 (<CJK Ideograph>) 22949 0x7F55 罕 (<CJK Ideograph>) 22950 0x7FF0 翰 (<CJK Ideograph>) 22951 0x9591 閑 (<CJK Ideograph>) 22952 0x9592 閒 (<CJK Ideograph>) 22953 0x9650 限 (<CJK Ideograph>) 22954 0x97D3 韓 (<CJK Ideograph>) 22955 0x5272 割 (<CJK Ideograph>) 22956 0x8F44 轄 (<CJK Ideograph>) 22957 0x51FD 函 (<CJK Ideograph>) 22958 0x542B 含 (<CJK Ideograph>) 22959 0x54B8 咸 (<CJK Ideograph>) 22960 0x5563 啣 (<CJK Ideograph>) 22961 0x558A 喊 (<CJK Ideograph>) 22962 0x6ABB 檻 (<CJK Ideograph>) 22963 0x6DB5 涵 (<CJK Ideograph>) 22964 0x7DD8 緘 (<CJK Ideograph>) 22965 0x8266 艦 (<CJK Ideograph>) 22966 0x929C 銜 (<CJK Ideograph>) 22967 0x9677 陷 (<CJK Ideograph>) 22968 0x9E79 鹹 (<CJK Ideograph>) 22969 0x5408 合 (<CJK Ideograph>) 22970 0x54C8 哈 (<CJK Ideograph>) 22971 0x76D2 盒 (<CJK Ideograph>) 22972 0x86E4 蛤 (<CJK Ideograph>) 22973 0x95A4 閤 (<CJK Ideograph>) 22974 0x95D4 闔 (<CJK Ideograph>) 22975 0x965C 陜 (<CJK Ideograph>) 22976 0x4EA2 亢 (<CJK Ideograph>) 22977 0x4F09 伉 (<CJK Ideograph>) 22978 0x59EE 姮 (<CJK Ideograph>) 22979 0x5AE6 嫦 (<CJK Ideograph>) 22980 0x5DF7 巷 (<CJK Ideograph>) 22981 0x6052 恒 (<CJK Ideograph>) 22982 0x6297 抗 (<CJK Ideograph>) 22983 0x676D 杭 (<CJK Ideograph>) 22984 0x6841 桁 (<CJK Ideograph>) 22985 0x6C86 沆 (<CJK Ideograph>) 22986 0x6E2F 港 (<CJK Ideograph>) 22987 0x7F38 缸 (<CJK Ideograph>) 22988 0x809B 肛 (<CJK Ideograph>) 22989 0x822A 航 (<CJK Ideograph>) 23086 0xFA08 行 (CJK COMPATIBILITY IDEOGRAPH-FA08) 23087 0xFA09 降 (CJK COMPATIBILITY IDEOGRAPH-FA09) 23088 0x9805 項 (<CJK Ideograph>) 23089 0x4EA5 亥 (<CJK Ideograph>) 23090 0x5055 偕 (<CJK Ideograph>) 23091 0x54B3 咳 (<CJK Ideograph>) 23092 0x5793 垓 (<CJK Ideograph>) 23093 0x595A 奚 (<CJK Ideograph>) 23094 0x5B69 孩 (<CJK Ideograph>) 23095 0x5BB3 害 (<CJK Ideograph>) 23096 0x61C8 懈 (<CJK Ideograph>) 23097 0x6977 楷 (<CJK Ideograph>) 23098 0x6D77 海 (<CJK Ideograph>) 23099 0x7023 瀣 (<CJK Ideograph>) 23100 0x87F9 蟹 (<CJK Ideograph>) 23101 0x89E3 解 (<CJK Ideograph>) 23102 0x8A72 該 (<CJK Ideograph>) 23103 0x8AE7 諧 (<CJK Ideograph>) 23104 0x9082 邂 (<CJK Ideograph>) 23105 0x99ED 駭 (<CJK Ideograph>) 23106 0x9AB8 骸 (<CJK Ideograph>) 23107 0x52BE 劾 (<CJK Ideograph>) 23108 0x6838 核 (<CJK Ideograph>) 23109 0x5016 倖 (<CJK Ideograph>) 23110 0x5E78 幸 (<CJK Ideograph>) 23111 0x674F 杏 (<CJK Ideograph>) 23112 0x8347 荇 (<CJK Ideograph>) 23113 0x884C 行 (<CJK Ideograph>) 23114 0x4EAB 享 (<CJK Ideograph>) 23115 0x5411 向 (<CJK Ideograph>) 23116 0x56AE 嚮 (<CJK Ideograph>) 23117 0x73E6 珦 (<CJK Ideograph>) 23118 0x9115 鄕 (<CJK Ideograph>) 23119 0x97FF 響 (<CJK Ideograph>) 23120 0x9909 餉 (<CJK Ideograph>) 23121 0x9957 饗 (<CJK Ideograph>) 23122 0x9999 香 (<CJK Ideograph>) 23123 0x5653 噓 (<CJK Ideograph>) 23124 0x589F 墟 (<CJK Ideograph>) 23125 0x865B 虛 (<CJK Ideograph>) 23126 0x8A31 許 (<CJK Ideograph>) 23127 0x61B2 憲 (<CJK Ideograph>) 23128 0x6AF6 櫶 (<CJK Ideograph>) 23129 0x737B 獻 (<CJK Ideograph>) 23130 0x8ED2 軒 (<CJK Ideograph>) 23131 0x6B47 歇 (<CJK Ideograph>) 23132 0x96AA 險 (<CJK Ideograph>) 23133 0x9A57 驗 (<CJK Ideograph>) 23134 0x5955 奕 (<CJK Ideograph>) 23135 0x7200 爀 (<CJK Ideograph>) 23136 0x8D6B 赫 (<CJK Ideograph>) 23137 0x9769 革 (<CJK Ideograph>) 23138 0x4FD4 俔 (<CJK Ideograph>) 23139 0x5CF4 峴 (<CJK Ideograph>) 23140 0x5F26 弦 (<CJK Ideograph>) 23141 0x61F8 懸 (<CJK Ideograph>) 23142 0x665B 晛 (<CJK Ideograph>) 23143 0x6CEB 泫 (<CJK Ideograph>) 23144 0x70AB 炫 (<CJK Ideograph>) 23145 0x7384 玄 (<CJK Ideograph>) 23146 0x73B9 玹 (<CJK Ideograph>) 23147 0x73FE 現 (<CJK Ideograph>) 23148 0x7729 眩 (<CJK Ideograph>) 23149 0x774D 睍 (<CJK Ideograph>) 23150 0x7D43 絃 (<CJK Ideograph>) 23151 0x7D62 絢 (<CJK Ideograph>) 23152 0x7E23 縣 (<CJK Ideograph>) 23153 0x8237 舷 (<CJK Ideograph>) 23154 0x8852 衒 (<CJK Ideograph>) 23155 0xFA0A 見 (CJK COMPATIBILITY IDEOGRAPH-FA0A) 23156 0x8CE2 賢 (<CJK Ideograph>) 23157 0x9249 鉉 (<CJK Ideograph>) 23158 0x986F 顯 (<CJK Ideograph>) 23159 0x5B51 孑 (<CJK Ideograph>) 23160 0x7A74 穴 (<CJK Ideograph>) 23161 0x8840 血 (<CJK Ideograph>) 23162 0x9801 頁 (<CJK Ideograph>) 23163 0x5ACC 嫌 (<CJK Ideograph>) 23164 0x4FE0 俠 (<CJK Ideograph>) 23165 0x5354 協 (<CJK Ideograph>) 23166 0x593E 夾 (<CJK Ideograph>) 23167 0x5CFD 峽 (<CJK Ideograph>) 23168 0x633E 挾 (<CJK Ideograph>) 23169 0x6D79 浹 (<CJK Ideograph>) 23170 0x72F9 狹 (<CJK Ideograph>) 23171 0x8105 脅 (<CJK Ideograph>) 23172 0x8107 脇 (<CJK Ideograph>) 23173 0x83A2 莢 (<CJK Ideograph>) 23174 0x92CF 鋏 (<CJK Ideograph>) 23175 0x9830 頰 (<CJK Ideograph>) 23176 0x4EA8 亨 (<CJK Ideograph>) 23177 0x5144 兄 (<CJK Ideograph>) 23178 0x5211 刑 (<CJK Ideograph>) 23179 0x578B 型 (<CJK Ideograph>) 23276 0x5F62 形 (<CJK Ideograph>) 23277 0x6CC2 泂 (<CJK Ideograph>) 23278 0x6ECE 滎 (<CJK Ideograph>) 23279 0x7005 瀅 (<CJK Ideograph>) 23280 0x7050 灐 (<CJK Ideograph>) 23281 0x70AF 炯 (<CJK Ideograph>) 23282 0x7192 熒 (<CJK Ideograph>) 23283 0x73E9 珩 (<CJK Ideograph>) 23284 0x7469 瑩 (<CJK Ideograph>) 23285 0x834A 荊 (<CJK Ideograph>) 23286 0x87A2 螢 (<CJK Ideograph>) 23287 0x8861 衡 (<CJK Ideograph>) 23288 0x9008 逈 (<CJK Ideograph>) 23289 0x90A2 邢 (<CJK Ideograph>) 23290 0x93A3 鎣 (<CJK Ideograph>) 23291 0x99A8 馨 (<CJK Ideograph>) 23292 0x516E 兮 (<CJK Ideograph>) 23293 0x5F57 彗 (<CJK Ideograph>) 23294 0x60E0 惠 (<CJK Ideograph>) 23295 0x6167 慧 (<CJK Ideograph>) 23296 0x66B3 暳 (<CJK Ideograph>) 23297 0x8559 蕙 (<CJK Ideograph>) 23298 0x8E4A 蹊 (<CJK Ideograph>) 23299 0x91AF 醯 (<CJK Ideograph>) 23300 0x978B 鞋 (<CJK Ideograph>) 23301 0x4E4E 乎 (<CJK Ideograph>) 23302 0x4E92 互 (<CJK Ideograph>) 23303 0x547C 呼 (<CJK Ideograph>) 23304 0x58D5 壕 (<CJK Ideograph>) 23305 0x58FA 壺 (<CJK Ideograph>) 23306 0x597D 好 (<CJK Ideograph>) 23307 0x5CB5 岵 (<CJK Ideograph>) 23308 0x5F27 弧 (<CJK Ideograph>) 23309 0x6236 戶 (<CJK Ideograph>) 23310 0x6248 扈 (<CJK Ideograph>) 23311 0x660A 昊 (<CJK Ideograph>) 23312 0x6667 晧 (<CJK Ideograph>) 23313 0x6BEB 毫 (<CJK Ideograph>) 23314 0x6D69 浩 (<CJK Ideograph>) 23315 0x6DCF 淏 (<CJK Ideograph>) 23316 0x6E56 湖 (<CJK Ideograph>) 23317 0x6EF8 滸 (<CJK Ideograph>) 23318 0x6F94 澔 (<CJK Ideograph>) 23319 0x6FE0 濠 (<CJK Ideograph>) 23320 0x6FE9 濩 (<CJK Ideograph>) 23321 0x705D 灝 (<CJK Ideograph>) 23322 0x72D0 狐 (<CJK Ideograph>) 23323 0x7425 琥 (<CJK Ideograph>) 23324 0x745A 瑚 (<CJK Ideograph>) 23325 0x74E0 瓠 (<CJK Ideograph>) 23326 0x7693 皓 (<CJK Ideograph>) 23327 0x795C 祜 (<CJK Ideograph>) 23328 0x7CCA 糊 (<CJK Ideograph>) 23329 0x7E1E 縞 (<CJK Ideograph>) 23330 0x80E1 胡 (<CJK Ideograph>) 23331 0x82A6 芦 (<CJK Ideograph>) 23332 0x846B 葫 (<CJK Ideograph>) 23333 0x84BF 蒿 (<CJK Ideograph>) 23334 0x864E 虎 (<CJK Ideograph>) 23335 0x865F 號 (<CJK Ideograph>) 23336 0x8774 蝴 (<CJK Ideograph>) 23337 0x8B77 護 (<CJK Ideograph>) 23338 0x8C6A 豪 (<CJK Ideograph>) 23339 0x93AC 鎬 (<CJK Ideograph>) 23340 0x9800 頀 (<CJK Ideograph>) 23341 0x9865 顥 (<CJK Ideograph>) 23342 0x60D1 惑 (<CJK Ideograph>) 23343 0x6216 或 (<CJK Ideograph>) 23344 0x9177 酷 (<CJK Ideograph>) 23345 0x5A5A 婚 (<CJK Ideograph>) 23346 0x660F 昏 (<CJK Ideograph>) 23347 0x6DF7 混 (<CJK Ideograph>) 23348 0x6E3E 渾 (<CJK Ideograph>) 23349 0x743F 琿 (<CJK Ideograph>) 23350 0x9B42 魂 (<CJK Ideograph>) 23351 0x5FFD 忽 (<CJK Ideograph>) 23352 0x60DA 惚 (<CJK Ideograph>) 23353 0x7B0F 笏 (<CJK Ideograph>) 23354 0x54C4 哄 (<CJK Ideograph>) 23355 0x5F18 弘 (<CJK Ideograph>) 23356 0x6C5E 汞 (<CJK Ideograph>) 23357 0x6CD3 泓 (<CJK Ideograph>) 23358 0x6D2A 洪 (<CJK Ideograph>) 23359 0x70D8 烘 (<CJK Ideograph>) 23360 0x7D05 紅 (<CJK Ideograph>) 23361 0x8679 虹 (<CJK Ideograph>) 23362 0x8A0C 訌 (<CJK Ideograph>) 23363 0x9D3B 鴻 (<CJK Ideograph>) 23364 0x5316 化 (<CJK Ideograph>) 23365 0x548C 和 (<CJK Ideograph>) 23366 0x5B05 嬅 (<CJK Ideograph>) 23367 0x6A3A 樺 (<CJK Ideograph>) 23368 0x706B 火 (<CJK Ideograph>) 23369 0x7575 畵 (<CJK Ideograph>) 23466 0x798D 禍 (<CJK Ideograph>) 23467 0x79BE 禾 (<CJK Ideograph>) 23468 0x82B1 花 (<CJK Ideograph>) 23469 0x83EF 華 (<CJK Ideograph>) 23470 0x8A71 話 (<CJK Ideograph>) 23471 0x8B41 譁 (<CJK Ideograph>) 23472 0x8CA8 貨 (<CJK Ideograph>) 23473 0x9774 靴 (<CJK Ideograph>) 23474 0xFA0B 廓 (CJK COMPATIBILITY IDEOGRAPH-FA0B) 23475 0x64F4 擴 (<CJK Ideograph>) 23476 0x652B 攫 (<CJK Ideograph>) 23477 0x78BA 確 (<CJK Ideograph>) 23478 0x78BB 碻 (<CJK Ideograph>) 23479 0x7A6B 穫 (<CJK Ideograph>) 23480 0x4E38 丸 (<CJK Ideograph>) 23481 0x559A 喚 (<CJK Ideograph>) 23482 0x5950 奐 (<CJK Ideograph>) 23483 0x5BA6 宦 (<CJK Ideograph>) 23484 0x5E7B 幻 (<CJK Ideograph>) 23485 0x60A3 患 (<CJK Ideograph>) 23486 0x63DB 換 (<CJK Ideograph>) 23487 0x6B61 歡 (<CJK Ideograph>) 23488 0x6665 晥 (<CJK Ideograph>) 23489 0x6853 桓 (<CJK Ideograph>) 23490 0x6E19 渙 (<CJK Ideograph>) 23491 0x7165 煥 (<CJK Ideograph>) 23492 0x74B0 環 (<CJK Ideograph>) 23493 0x7D08 紈 (<CJK Ideograph>) 23494 0x9084 還 (<CJK Ideograph>) 23495 0x9A69 驩 (<CJK Ideograph>) 23496 0x9C25 鰥 (<CJK Ideograph>) 23497 0x6D3B 活 (<CJK Ideograph>) 23498 0x6ED1 滑 (<CJK Ideograph>) 23499 0x733E 猾 (<CJK Ideograph>) 23500 0x8C41 豁 (<CJK Ideograph>) 23501 0x95CA 闊 (<CJK Ideograph>) 23502 0x51F0 凰 (<CJK Ideograph>) 23503 0x5E4C 幌 (<CJK Ideograph>) 23504 0x5FA8 徨 (<CJK Ideograph>) 23505 0x604D 恍 (<CJK Ideograph>) 23506 0x60F6 惶 (<CJK Ideograph>) 23507 0x6130 愰 (<CJK Ideograph>) 23508 0x614C 慌 (<CJK Ideograph>) 23509 0x6643 晃 (<CJK Ideograph>) 23510 0x6644 晄 (<CJK Ideograph>) 23511 0x69A5 榥 (<CJK Ideograph>) 23512 0x6CC1 況 (<CJK Ideograph>) 23513 0x6E5F 湟 (<CJK Ideograph>) 23514 0x6EC9 滉 (<CJK Ideograph>) 23515 0x6F62 潢 (<CJK Ideograph>) 23516 0x714C 煌 (<CJK Ideograph>) 23517 0x749C 璜 (<CJK Ideograph>) 23518 0x7687 皇 (<CJK Ideograph>) 23519 0x7BC1 篁 (<CJK Ideograph>) 23520 0x7C27 簧 (<CJK Ideograph>) 23521 0x8352 荒 (<CJK Ideograph>) 23522 0x8757 蝗 (<CJK Ideograph>) 23523 0x9051 遑 (<CJK Ideograph>) 23524 0x968D 隍 (<CJK Ideograph>) 23525 0x9EC3 黃 (<CJK Ideograph>) 23526 0x532F 匯 (<CJK Ideograph>) 23527 0x56DE 回 (<CJK Ideograph>) 23528 0x5EFB 廻 (<CJK Ideograph>) 23529 0x5F8A 徊 (<CJK Ideograph>) 23530 0x6062 恢 (<CJK Ideograph>) 23531 0x6094 悔 (<CJK Ideograph>) 23532 0x61F7 懷 (<CJK Ideograph>) 23533 0x6666 晦 (<CJK Ideograph>) 23534 0x6703 會 (<CJK Ideograph>) 23535 0x6A9C 檜 (<CJK Ideograph>) 23536 0x6DEE 淮 (<CJK Ideograph>) 23537 0x6FAE 澮 (<CJK Ideograph>) 23538 0x7070 灰 (<CJK Ideograph>) 23539 0x736A 獪 (<CJK Ideograph>) 23540 0x7E6A 繪 (<CJK Ideograph>) 23541 0x81BE 膾 (<CJK Ideograph>) 23542 0x8334 茴 (<CJK Ideograph>) 23543 0x86D4 蛔 (<CJK Ideograph>) 23544 0x8AA8 誨 (<CJK Ideograph>) 23545 0x8CC4 賄 (<CJK Ideograph>) 23546 0x5283 劃 (<CJK Ideograph>) 23547 0x7372 獲 (<CJK Ideograph>) 23548 0x5B96 宖 (<CJK Ideograph>) 23549 0x6A6B 橫 (<CJK Ideograph>) 23550 0x9404 鐄 (<CJK Ideograph>) 23551 0x54EE 哮 (<CJK Ideograph>) 23552 0x5686 嚆 (<CJK Ideograph>) 23553 0x5B5D 孝 (<CJK Ideograph>) 23554 0x6548 效 (<CJK Ideograph>) 23555 0x6585 斅 (<CJK Ideograph>) 23556 0x66C9 曉 (<CJK Ideograph>) 23557 0x689F 梟 (<CJK Ideograph>) 23558 0x6D8D 涍 (<CJK Ideograph>) 23559 0x6DC6 淆 (<CJK Ideograph>) 23656 0x723B 爻 (<CJK Ideograph>) 23657 0x80B4 肴 (<CJK Ideograph>) 23658 0x9175 酵 (<CJK Ideograph>) 23659 0x9A4D 驍 (<CJK Ideograph>) 23660 0x4FAF 侯 (<CJK Ideograph>) 23661 0x5019 候 (<CJK Ideograph>) 23662 0x539A 厚 (<CJK Ideograph>) 23663 0x540E 后 (<CJK Ideograph>) 23664 0x543C 吼 (<CJK Ideograph>) 23665 0x5589 喉 (<CJK Ideograph>) 23666 0x55C5 嗅 (<CJK Ideograph>) 23667 0x5E3F 帿 (<CJK Ideograph>) 23668 0x5F8C 後 (<CJK Ideograph>) 23669 0x673D 朽 (<CJK Ideograph>) 23670 0x7166 煦 (<CJK Ideograph>) 23671 0x73DD 珝 (<CJK Ideograph>) 23672 0x9005 逅 (<CJK Ideograph>) 23673 0x52DB 勛 (<CJK Ideograph>) 23674 0x52F3 勳 (<CJK Ideograph>) 23675 0x5864 塤 (<CJK Ideograph>) 23676 0x58CE 壎 (<CJK Ideograph>) 23677 0x7104 焄 (<CJK Ideograph>) 23678 0x718F 熏 (<CJK Ideograph>) 23679 0x71FB 燻 (<CJK Ideograph>) 23680 0x85B0 薰 (<CJK Ideograph>) 23681 0x8A13 訓 (<CJK Ideograph>) 23682 0x6688 暈 (<CJK Ideograph>) 23683 0x85A8 薨 (<CJK Ideograph>) 23684 0x55A7 喧 (<CJK Ideograph>) 23685 0x6684 暄 (<CJK Ideograph>) 23686 0x714A 煊 (<CJK Ideograph>) 23687 0x8431 萱 (<CJK Ideograph>) 23688 0x5349 卉 (<CJK Ideograph>) 23689 0x5599 喙 (<CJK Ideograph>) 23690 0x6BC1 毁 (<CJK Ideograph>) 23691 0x5F59 彙 (<CJK Ideograph>) 23692 0x5FBD 徽 (<CJK Ideograph>) 23693 0x63EE 揮 (<CJK Ideograph>) 23694 0x6689 暉 (<CJK Ideograph>) 23695 0x7147 煇 (<CJK Ideograph>) 23696 0x8AF1 諱 (<CJK Ideograph>) 23697 0x8F1D 輝 (<CJK Ideograph>) 23698 0x9EBE 麾 (<CJK Ideograph>) 23699 0x4F11 休 (<CJK Ideograph>) 23700 0x643A 携 (<CJK Ideograph>) 23701 0x70CB 烋 (<CJK Ideograph>) 23702 0x7566 畦 (<CJK Ideograph>) 23703 0x8667 虧 (<CJK Ideograph>) 23704 0x6064 恤 (<CJK Ideograph>) 23705 0x8B4E 譎 (<CJK Ideograph>) 23706 0x9DF8 鷸 (<CJK Ideograph>) 23707 0x5147 兇 (<CJK Ideograph>) 23708 0x51F6 凶 (<CJK Ideograph>) 23709 0x5308 匈 (<CJK Ideograph>) 23710 0x6D36 洶 (<CJK Ideograph>) 23711 0x80F8 胸 (<CJK Ideograph>) 23712 0x9ED1 黑 (<CJK Ideograph>) 23713 0x6615 昕 (<CJK Ideograph>) 23714 0x6B23 欣 (<CJK Ideograph>) 23715 0x7098 炘 (<CJK Ideograph>) 23716 0x75D5 痕 (<CJK Ideograph>) 23717 0x5403 吃 (<CJK Ideograph>) 23718 0x5C79 屹 (<CJK Ideograph>) 23719 0x7D07 紇 (<CJK Ideograph>) 23720 0x8A16 訖 (<CJK Ideograph>) 23721 0x6B20 欠 (<CJK Ideograph>) 23722 0x6B3D 欽 (<CJK Ideograph>) 23723 0x6B46 歆 (<CJK Ideograph>) 23724 0x5438 吸 (<CJK Ideograph>) 23725 0x6070 恰 (<CJK Ideograph>) 23726 0x6D3D 洽 (<CJK Ideograph>) 23727 0x7FD5 翕 (<CJK Ideograph>) 23728 0x8208 興 (<CJK Ideograph>) 23729 0x50D6 僖 (<CJK Ideograph>) 23730 0x51DE 凞 (<CJK Ideograph>) 23731 0x559C 喜 (<CJK Ideograph>) 23732 0x566B 噫 (<CJK Ideograph>) 23733 0x56CD 囍 (<CJK Ideograph>) 23734 0x59EC 姬 (<CJK Ideograph>) 23735 0x5B09 嬉 (<CJK Ideograph>) 23736 0x5E0C 希 (<CJK Ideograph>) 23737 0x6199 憙 (<CJK Ideograph>) 23738 0x6198 憘 (<CJK Ideograph>) 23739 0x6231 戱 (<CJK Ideograph>) 23740 0x665E 晞 (<CJK Ideograph>) 23741 0x66E6 曦 (<CJK Ideograph>) 23742 0x7199 熙 (<CJK Ideograph>) 23743 0x71B9 熹 (<CJK Ideograph>) 23744 0x71BA 熺 (<CJK Ideograph>) 23745 0x72A7 犧 (<CJK Ideograph>) 23746 0x79A7 禧 (<CJK Ideograph>) 23747 0x7A00 稀 (<CJK Ideograph>) 23748 0x7FB2 羲 (<CJK Ideograph>) 23749 0x8A70 詰 (<CJK Ideograph>) ���������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-gb18030-ranges.txt����������������������������������������������������������0000664�0000000�0000000�00000006046�15202323131�0020040�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-gb18030-ranges.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: f963aaa1653f630c523e7b04729fb4e4458f35806c45eb5c179445623138f0c0 # Date: 2018-01-06 0 0x0080 36 0x00A5 38 0x00A9 45 0x00B2 50 0x00B8 81 0x00D8 89 0x00E2 95 0x00EB 96 0x00EE 100 0x00F4 103 0x00F8 104 0x00FB 105 0x00FD 109 0x0102 126 0x0114 133 0x011C 148 0x012C 172 0x0145 175 0x0149 179 0x014E 208 0x016C 306 0x01CF 307 0x01D1 308 0x01D3 309 0x01D5 310 0x01D7 311 0x01D9 312 0x01DB 313 0x01DD 341 0x01FA 428 0x0252 443 0x0262 544 0x02C8 545 0x02CC 558 0x02DA 741 0x03A2 742 0x03AA 749 0x03C2 750 0x03CA 805 0x0402 819 0x0450 820 0x0452 7922 0x2011 7924 0x2017 7925 0x201A 7927 0x201E 7934 0x2027 7943 0x2031 7944 0x2034 7945 0x2036 7950 0x203C 8062 0x20AD 8148 0x2104 8149 0x2106 8152 0x210A 8164 0x2117 8174 0x2122 8236 0x216C 8240 0x217A 8262 0x2194 8264 0x219A 8374 0x2209 8380 0x2210 8381 0x2212 8384 0x2216 8388 0x221B 8390 0x2221 8392 0x2224 8393 0x2226 8394 0x222C 8396 0x222F 8401 0x2238 8406 0x223E 8416 0x2249 8419 0x224D 8424 0x2253 8437 0x2262 8439 0x2268 8445 0x2270 8482 0x2296 8485 0x229A 8496 0x22A6 8521 0x22C0 8603 0x2313 8936 0x246A 8946 0x249C 9046 0x254C 9050 0x2574 9063 0x2590 9066 0x2596 9076 0x25A2 9092 0x25B4 9100 0x25BE 9108 0x25C8 9111 0x25CC 9113 0x25D0 9131 0x25E6 9162 0x2607 9164 0x260A 9218 0x2641 9219 0x2643 11329 0x2E82 11331 0x2E85 11334 0x2E89 11336 0x2E8D 11346 0x2E98 11361 0x2EA8 11363 0x2EAB 11366 0x2EAF 11370 0x2EB4 11372 0x2EB8 11375 0x2EBC 11389 0x2ECB 11682 0x2FFC 11686 0x3004 11687 0x3018 11692 0x301F 11694 0x302A 11714 0x303F 11716 0x3094 11723 0x309F 11725 0x30F7 11730 0x30FF 11736 0x312A 11982 0x322A 11989 0x3232 12102 0x32A4 12336 0x3390 12348 0x339F 12350 0x33A2 12384 0x33C5 12393 0x33CF 12395 0x33D3 12397 0x33D6 12510 0x3448 12553 0x3474 12851 0x359F 12962 0x360F 12973 0x361B 13738 0x3919 13823 0x396F 13919 0x39D1 13933 0x39E0 14080 0x3A74 14298 0x3B4F 14585 0x3C6F 14698 0x3CE1 15583 0x4057 15847 0x4160 16318 0x4338 16434 0x43AD 16438 0x43B2 16481 0x43DE 16729 0x44D7 17102 0x464D 17122 0x4662 17315 0x4724 17320 0x472A 17402 0x477D 17418 0x478E 17859 0x4948 17909 0x497B 17911 0x497E 17915 0x4984 17916 0x4987 17936 0x499C 17939 0x49A0 17961 0x49B8 18664 0x4C78 18703 0x4CA4 18814 0x4D1A 18962 0x4DAF 19043 0x9FA6 33469 0xE76C 33470 0xE7C8 33471 0xE7E7 33484 0xE815 33485 0xE819 33490 0xE81F 33497 0xE827 33501 0xE82D 33505 0xE833 33513 0xE83C 33520 0xE844 33536 0xE856 33550 0xE865 37845 0xF92D 37921 0xF97A 37948 0xF996 38029 0xF9E8 38038 0xF9F2 38064 0xFA10 38065 0xFA12 38066 0xFA15 38069 0xFA19 38075 0xFA22 38076 0xFA25 38078 0xFA2A 39108 0xFE32 39109 0xFE45 39113 0xFE53 39114 0xFE58 39115 0xFE67 39116 0xFE6C 39265 0xFF5F 39394 0xFFE6 189000 0x10000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-gb18030.txt�����������������������������������������������������������������0000664�0000000�0000000�00003157730�15202323131�0016575�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-gb18030.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 715f084846f5c6fc9dd31046d0a4d604bd2d88bfe3a22833cea048415e413c70 # Date: 2018-01-06 # # I updated this with the changes from October '24 manually, because I # do not agree with the license change. Chagashi remains in the Public # Domain. # ~bptato 0 0x4E02 丂 (<CJK Ideograph>) 1 0x4E04 丄 (<CJK Ideograph>) 2 0x4E05 丅 (<CJK Ideograph>) 3 0x4E06 丆 (<CJK Ideograph>) 4 0x4E0F 丏 (<CJK Ideograph>) 5 0x4E12 丒 (<CJK Ideograph>) 6 0x4E17 丗 (<CJK Ideograph>) 7 0x4E1F 丟 (<CJK Ideograph>) 8 0x4E20 丠 (<CJK Ideograph>) 9 0x4E21 両 (<CJK Ideograph>) 10 0x4E23 丣 (<CJK Ideograph>) 11 0x4E26 並 (<CJK Ideograph>) 12 0x4E29 丩 (<CJK Ideograph>) 13 0x4E2E 丮 (<CJK Ideograph>) 14 0x4E2F 丯 (<CJK Ideograph>) 15 0x4E31 丱 (<CJK Ideograph>) 16 0x4E33 丳 (<CJK Ideograph>) 17 0x4E35 丵 (<CJK Ideograph>) 18 0x4E37 丷 (<CJK Ideograph>) 19 0x4E3C 丼 (<CJK Ideograph>) 20 0x4E40 乀 (<CJK Ideograph>) 21 0x4E41 乁 (<CJK Ideograph>) 22 0x4E42 乂 (<CJK Ideograph>) 23 0x4E44 乄 (<CJK Ideograph>) 24 0x4E46 乆 (<CJK Ideograph>) 25 0x4E4A 乊 (<CJK Ideograph>) 26 0x4E51 乑 (<CJK Ideograph>) 27 0x4E55 乕 (<CJK Ideograph>) 28 0x4E57 乗 (<CJK Ideograph>) 29 0x4E5A 乚 (<CJK Ideograph>) 30 0x4E5B 乛 (<CJK Ideograph>) 31 0x4E62 乢 (<CJK Ideograph>) 32 0x4E63 乣 (<CJK Ideograph>) 33 0x4E64 乤 (<CJK Ideograph>) 34 0x4E65 乥 (<CJK Ideograph>) 35 0x4E67 乧 (<CJK Ideograph>) 36 0x4E68 乨 (<CJK Ideograph>) 37 0x4E6A 乪 (<CJK Ideograph>) 38 0x4E6B 乫 (<CJK Ideograph>) 39 0x4E6C 乬 (<CJK Ideograph>) 40 0x4E6D 乭 (<CJK Ideograph>) 41 0x4E6E 乮 (<CJK Ideograph>) 42 0x4E6F 乯 (<CJK Ideograph>) 43 0x4E72 乲 (<CJK Ideograph>) 44 0x4E74 乴 (<CJK Ideograph>) 45 0x4E75 乵 (<CJK Ideograph>) 46 0x4E76 乶 (<CJK Ideograph>) 47 0x4E77 乷 (<CJK Ideograph>) 48 0x4E78 乸 (<CJK Ideograph>) 49 0x4E79 乹 (<CJK Ideograph>) 50 0x4E7A 乺 (<CJK Ideograph>) 51 0x4E7B 乻 (<CJK Ideograph>) 52 0x4E7C 乼 (<CJK Ideograph>) 53 0x4E7D 乽 (<CJK Ideograph>) 54 0x4E7F 乿 (<CJK Ideograph>) 55 0x4E80 亀 (<CJK Ideograph>) 56 0x4E81 亁 (<CJK Ideograph>) 57 0x4E82 亂 (<CJK Ideograph>) 58 0x4E83 亃 (<CJK Ideograph>) 59 0x4E84 亄 (<CJK Ideograph>) 60 0x4E85 亅 (<CJK Ideograph>) 61 0x4E87 亇 (<CJK Ideograph>) 62 0x4E8A 亊 (<CJK Ideograph>) 63 0x4E90 亐 (<CJK Ideograph>) 64 0x4E96 亖 (<CJK Ideograph>) 65 0x4E97 亗 (<CJK Ideograph>) 66 0x4E99 亙 (<CJK Ideograph>) 67 0x4E9C 亜 (<CJK Ideograph>) 68 0x4E9D 亝 (<CJK Ideograph>) 69 0x4E9E 亞 (<CJK Ideograph>) 70 0x4EA3 亣 (<CJK Ideograph>) 71 0x4EAA 亪 (<CJK Ideograph>) 72 0x4EAF 亯 (<CJK Ideograph>) 73 0x4EB0 亰 (<CJK Ideograph>) 74 0x4EB1 亱 (<CJK Ideograph>) 75 0x4EB4 亴 (<CJK Ideograph>) 76 0x4EB6 亶 (<CJK Ideograph>) 77 0x4EB7 亷 (<CJK Ideograph>) 78 0x4EB8 亸 (<CJK Ideograph>) 79 0x4EB9 亹 (<CJK Ideograph>) 80 0x4EBC 亼 (<CJK Ideograph>) 81 0x4EBD 亽 (<CJK Ideograph>) 82 0x4EBE 亾 (<CJK Ideograph>) 83 0x4EC8 仈 (<CJK Ideograph>) 84 0x4ECC 仌 (<CJK Ideograph>) 85 0x4ECF 仏 (<CJK Ideograph>) 86 0x4ED0 仐 (<CJK Ideograph>) 87 0x4ED2 仒 (<CJK Ideograph>) 88 0x4EDA 仚 (<CJK Ideograph>) 89 0x4EDB 仛 (<CJK Ideograph>) 90 0x4EDC 仜 (<CJK Ideograph>) 91 0x4EE0 仠 (<CJK Ideograph>) 92 0x4EE2 仢 (<CJK Ideograph>) 93 0x4EE6 仦 (<CJK Ideograph>) 94 0x4EE7 仧 (<CJK Ideograph>) 95 0x4EE9 仩 (<CJK Ideograph>) 96 0x4EED 仭 (<CJK Ideograph>) 97 0x4EEE 仮 (<CJK Ideograph>) 98 0x4EEF 仯 (<CJK Ideograph>) 99 0x4EF1 仱 (<CJK Ideograph>) 100 0x4EF4 仴 (<CJK Ideograph>) 101 0x4EF8 仸 (<CJK Ideograph>) 102 0x4EF9 仹 (<CJK Ideograph>) 103 0x4EFA 仺 (<CJK Ideograph>) 104 0x4EFC 仼 (<CJK Ideograph>) 105 0x4EFE 仾 (<CJK Ideograph>) 106 0x4F00 伀 (<CJK Ideograph>) 107 0x4F02 伂 (<CJK Ideograph>) 108 0x4F03 伃 (<CJK Ideograph>) 109 0x4F04 伄 (<CJK Ideograph>) 110 0x4F05 伅 (<CJK Ideograph>) 111 0x4F06 伆 (<CJK Ideograph>) 112 0x4F07 伇 (<CJK Ideograph>) 113 0x4F08 伈 (<CJK Ideograph>) 114 0x4F0B 伋 (<CJK Ideograph>) 115 0x4F0C 伌 (<CJK Ideograph>) 116 0x4F12 伒 (<CJK Ideograph>) 117 0x4F13 伓 (<CJK Ideograph>) 118 0x4F14 伔 (<CJK Ideograph>) 119 0x4F15 伕 (<CJK Ideograph>) 120 0x4F16 伖 (<CJK Ideograph>) 121 0x4F1C 伜 (<CJK Ideograph>) 122 0x4F1D 伝 (<CJK Ideograph>) 123 0x4F21 伡 (<CJK Ideograph>) 124 0x4F23 伣 (<CJK Ideograph>) 125 0x4F28 伨 (<CJK Ideograph>) 126 0x4F29 伩 (<CJK Ideograph>) 127 0x4F2C 伬 (<CJK Ideograph>) 128 0x4F2D 伭 (<CJK Ideograph>) 129 0x4F2E 伮 (<CJK Ideograph>) 130 0x4F31 伱 (<CJK Ideograph>) 131 0x4F33 伳 (<CJK Ideograph>) 132 0x4F35 伵 (<CJK Ideograph>) 133 0x4F37 伷 (<CJK Ideograph>) 134 0x4F39 伹 (<CJK Ideograph>) 135 0x4F3B 伻 (<CJK Ideograph>) 136 0x4F3E 伾 (<CJK Ideograph>) 137 0x4F3F 伿 (<CJK Ideograph>) 138 0x4F40 佀 (<CJK Ideograph>) 139 0x4F41 佁 (<CJK Ideograph>) 140 0x4F42 佂 (<CJK Ideograph>) 141 0x4F44 佄 (<CJK Ideograph>) 142 0x4F45 佅 (<CJK Ideograph>) 143 0x4F47 佇 (<CJK Ideograph>) 144 0x4F48 佈 (<CJK Ideograph>) 145 0x4F49 佉 (<CJK Ideograph>) 146 0x4F4A 佊 (<CJK Ideograph>) 147 0x4F4B 佋 (<CJK Ideograph>) 148 0x4F4C 佌 (<CJK Ideograph>) 149 0x4F52 佒 (<CJK Ideograph>) 150 0x4F54 佔 (<CJK Ideograph>) 151 0x4F56 佖 (<CJK Ideograph>) 152 0x4F61 佡 (<CJK Ideograph>) 153 0x4F62 佢 (<CJK Ideograph>) 154 0x4F66 佦 (<CJK Ideograph>) 155 0x4F68 佨 (<CJK Ideograph>) 156 0x4F6A 佪 (<CJK Ideograph>) 157 0x4F6B 佫 (<CJK Ideograph>) 158 0x4F6D 佭 (<CJK Ideograph>) 159 0x4F6E 佮 (<CJK Ideograph>) 160 0x4F71 佱 (<CJK Ideograph>) 161 0x4F72 佲 (<CJK Ideograph>) 162 0x4F75 併 (<CJK Ideograph>) 163 0x4F77 佷 (<CJK Ideograph>) 164 0x4F78 佸 (<CJK Ideograph>) 165 0x4F79 佹 (<CJK Ideograph>) 166 0x4F7A 佺 (<CJK Ideograph>) 167 0x4F7D 佽 (<CJK Ideograph>) 168 0x4F80 侀 (<CJK Ideograph>) 169 0x4F81 侁 (<CJK Ideograph>) 170 0x4F82 侂 (<CJK Ideograph>) 171 0x4F85 侅 (<CJK Ideograph>) 172 0x4F86 來 (<CJK Ideograph>) 173 0x4F87 侇 (<CJK Ideograph>) 174 0x4F8A 侊 (<CJK Ideograph>) 175 0x4F8C 侌 (<CJK Ideograph>) 176 0x4F8E 侎 (<CJK Ideograph>) 177 0x4F90 侐 (<CJK Ideograph>) 178 0x4F92 侒 (<CJK Ideograph>) 179 0x4F93 侓 (<CJK Ideograph>) 180 0x4F95 侕 (<CJK Ideograph>) 181 0x4F96 侖 (<CJK Ideograph>) 182 0x4F98 侘 (<CJK Ideograph>) 183 0x4F99 侙 (<CJK Ideograph>) 184 0x4F9A 侚 (<CJK Ideograph>) 185 0x4F9C 侜 (<CJK Ideograph>) 186 0x4F9E 侞 (<CJK Ideograph>) 187 0x4F9F 侟 (<CJK Ideograph>) 188 0x4FA1 価 (<CJK Ideograph>) 189 0x4FA2 侢 (<CJK Ideograph>) 190 0x4FA4 侤 (<CJK Ideograph>) 191 0x4FAB 侫 (<CJK Ideograph>) 192 0x4FAD 侭 (<CJK Ideograph>) 193 0x4FB0 侰 (<CJK Ideograph>) 194 0x4FB1 侱 (<CJK Ideograph>) 195 0x4FB2 侲 (<CJK Ideograph>) 196 0x4FB3 侳 (<CJK Ideograph>) 197 0x4FB4 侴 (<CJK Ideograph>) 198 0x4FB6 侶 (<CJK Ideograph>) 199 0x4FB7 侷 (<CJK Ideograph>) 200 0x4FB8 侸 (<CJK Ideograph>) 201 0x4FB9 侹 (<CJK Ideograph>) 202 0x4FBA 侺 (<CJK Ideograph>) 203 0x4FBB 侻 (<CJK Ideograph>) 204 0x4FBC 侼 (<CJK Ideograph>) 205 0x4FBD 侽 (<CJK Ideograph>) 206 0x4FBE 侾 (<CJK Ideograph>) 207 0x4FC0 俀 (<CJK Ideograph>) 208 0x4FC1 俁 (<CJK Ideograph>) 209 0x4FC2 係 (<CJK Ideograph>) 210 0x4FC6 俆 (<CJK Ideograph>) 211 0x4FC7 俇 (<CJK Ideograph>) 212 0x4FC8 俈 (<CJK Ideograph>) 213 0x4FC9 俉 (<CJK Ideograph>) 214 0x4FCB 俋 (<CJK Ideograph>) 215 0x4FCC 俌 (<CJK Ideograph>) 216 0x4FCD 俍 (<CJK Ideograph>) 217 0x4FD2 俒 (<CJK Ideograph>) 218 0x4FD3 俓 (<CJK Ideograph>) 219 0x4FD4 俔 (<CJK Ideograph>) 220 0x4FD5 俕 (<CJK Ideograph>) 221 0x4FD6 俖 (<CJK Ideograph>) 222 0x4FD9 俙 (<CJK Ideograph>) 223 0x4FDB 俛 (<CJK Ideograph>) 224 0x4FE0 俠 (<CJK Ideograph>) 225 0x4FE2 俢 (<CJK Ideograph>) 226 0x4FE4 俤 (<CJK Ideograph>) 227 0x4FE5 俥 (<CJK Ideograph>) 228 0x4FE7 俧 (<CJK Ideograph>) 229 0x4FEB 俫 (<CJK Ideograph>) 230 0x4FEC 俬 (<CJK Ideograph>) 231 0x4FF0 俰 (<CJK Ideograph>) 232 0x4FF2 俲 (<CJK Ideograph>) 233 0x4FF4 俴 (<CJK Ideograph>) 234 0x4FF5 俵 (<CJK Ideograph>) 235 0x4FF6 俶 (<CJK Ideograph>) 236 0x4FF7 俷 (<CJK Ideograph>) 237 0x4FF9 俹 (<CJK Ideograph>) 238 0x4FFB 俻 (<CJK Ideograph>) 239 0x4FFC 俼 (<CJK Ideograph>) 240 0x4FFD 俽 (<CJK Ideograph>) 241 0x4FFF 俿 (<CJK Ideograph>) 242 0x5000 倀 (<CJK Ideograph>) 243 0x5001 倁 (<CJK Ideograph>) 244 0x5002 倂 (<CJK Ideograph>) 245 0x5003 倃 (<CJK Ideograph>) 246 0x5004 倄 (<CJK Ideograph>) 247 0x5005 倅 (<CJK Ideograph>) 248 0x5006 倆 (<CJK Ideograph>) 249 0x5007 倇 (<CJK Ideograph>) 250 0x5008 倈 (<CJK Ideograph>) 251 0x5009 倉 (<CJK Ideograph>) 252 0x500A 倊 (<CJK Ideograph>) 253 0x500B 個 (<CJK Ideograph>) 254 0x500E 倎 (<CJK Ideograph>) 255 0x5010 倐 (<CJK Ideograph>) 256 0x5011 們 (<CJK Ideograph>) 257 0x5013 倓 (<CJK Ideograph>) 258 0x5015 倕 (<CJK Ideograph>) 259 0x5016 倖 (<CJK Ideograph>) 260 0x5017 倗 (<CJK Ideograph>) 261 0x501B 倛 (<CJK Ideograph>) 262 0x501D 倝 (<CJK Ideograph>) 263 0x501E 倞 (<CJK Ideograph>) 264 0x5020 倠 (<CJK Ideograph>) 265 0x5022 倢 (<CJK Ideograph>) 266 0x5023 倣 (<CJK Ideograph>) 267 0x5024 値 (<CJK Ideograph>) 268 0x5027 倧 (<CJK Ideograph>) 269 0x502B 倫 (<CJK Ideograph>) 270 0x502F 倯 (<CJK Ideograph>) 271 0x5030 倰 (<CJK Ideograph>) 272 0x5031 倱 (<CJK Ideograph>) 273 0x5032 倲 (<CJK Ideograph>) 274 0x5033 倳 (<CJK Ideograph>) 275 0x5034 倴 (<CJK Ideograph>) 276 0x5035 倵 (<CJK Ideograph>) 277 0x5036 倶 (<CJK Ideograph>) 278 0x5037 倷 (<CJK Ideograph>) 279 0x5038 倸 (<CJK Ideograph>) 280 0x5039 倹 (<CJK Ideograph>) 281 0x503B 倻 (<CJK Ideograph>) 282 0x503D 倽 (<CJK Ideograph>) 283 0x503F 倿 (<CJK Ideograph>) 284 0x5040 偀 (<CJK Ideograph>) 285 0x5041 偁 (<CJK Ideograph>) 286 0x5042 偂 (<CJK Ideograph>) 287 0x5044 偄 (<CJK Ideograph>) 288 0x5045 偅 (<CJK Ideograph>) 289 0x5046 偆 (<CJK Ideograph>) 290 0x5049 偉 (<CJK Ideograph>) 291 0x504A 偊 (<CJK Ideograph>) 292 0x504B 偋 (<CJK Ideograph>) 293 0x504D 偍 (<CJK Ideograph>) 294 0x5050 偐 (<CJK Ideograph>) 295 0x5051 偑 (<CJK Ideograph>) 296 0x5052 偒 (<CJK Ideograph>) 297 0x5053 偓 (<CJK Ideograph>) 298 0x5054 偔 (<CJK Ideograph>) 299 0x5056 偖 (<CJK Ideograph>) 300 0x5057 偗 (<CJK Ideograph>) 301 0x5058 偘 (<CJK Ideograph>) 302 0x5059 偙 (<CJK Ideograph>) 303 0x505B 偛 (<CJK Ideograph>) 304 0x505D 偝 (<CJK Ideograph>) 305 0x505E 偞 (<CJK Ideograph>) 306 0x505F 偟 (<CJK Ideograph>) 307 0x5060 偠 (<CJK Ideograph>) 308 0x5061 偡 (<CJK Ideograph>) 309 0x5062 偢 (<CJK Ideograph>) 310 0x5063 偣 (<CJK Ideograph>) 311 0x5064 偤 (<CJK Ideograph>) 312 0x5066 偦 (<CJK Ideograph>) 313 0x5067 偧 (<CJK Ideograph>) 314 0x5068 偨 (<CJK Ideograph>) 315 0x5069 偩 (<CJK Ideograph>) 316 0x506A 偪 (<CJK Ideograph>) 317 0x506B 偫 (<CJK Ideograph>) 318 0x506D 偭 (<CJK Ideograph>) 319 0x506E 偮 (<CJK Ideograph>) 320 0x506F 偯 (<CJK Ideograph>) 321 0x5070 偰 (<CJK Ideograph>) 322 0x5071 偱 (<CJK Ideograph>) 323 0x5072 偲 (<CJK Ideograph>) 324 0x5073 偳 (<CJK Ideograph>) 325 0x5074 側 (<CJK Ideograph>) 326 0x5075 偵 (<CJK Ideograph>) 327 0x5078 偸 (<CJK Ideograph>) 328 0x5079 偹 (<CJK Ideograph>) 329 0x507A 偺 (<CJK Ideograph>) 330 0x507C 偼 (<CJK Ideograph>) 331 0x507D 偽 (<CJK Ideograph>) 332 0x5081 傁 (<CJK Ideograph>) 333 0x5082 傂 (<CJK Ideograph>) 334 0x5083 傃 (<CJK Ideograph>) 335 0x5084 傄 (<CJK Ideograph>) 336 0x5086 傆 (<CJK Ideograph>) 337 0x5087 傇 (<CJK Ideograph>) 338 0x5089 傉 (<CJK Ideograph>) 339 0x508A 傊 (<CJK Ideograph>) 340 0x508B 傋 (<CJK Ideograph>) 341 0x508C 傌 (<CJK Ideograph>) 342 0x508E 傎 (<CJK Ideograph>) 343 0x508F 傏 (<CJK Ideograph>) 344 0x5090 傐 (<CJK Ideograph>) 345 0x5091 傑 (<CJK Ideograph>) 346 0x5092 傒 (<CJK Ideograph>) 347 0x5093 傓 (<CJK Ideograph>) 348 0x5094 傔 (<CJK Ideograph>) 349 0x5095 傕 (<CJK Ideograph>) 350 0x5096 傖 (<CJK Ideograph>) 351 0x5097 傗 (<CJK Ideograph>) 352 0x5098 傘 (<CJK Ideograph>) 353 0x5099 備 (<CJK Ideograph>) 354 0x509A 傚 (<CJK Ideograph>) 355 0x509B 傛 (<CJK Ideograph>) 356 0x509C 傜 (<CJK Ideograph>) 357 0x509D 傝 (<CJK Ideograph>) 358 0x509E 傞 (<CJK Ideograph>) 359 0x509F 傟 (<CJK Ideograph>) 360 0x50A0 傠 (<CJK Ideograph>) 361 0x50A1 傡 (<CJK Ideograph>) 362 0x50A2 傢 (<CJK Ideograph>) 363 0x50A4 傤 (<CJK Ideograph>) 364 0x50A6 傦 (<CJK Ideograph>) 365 0x50AA 傪 (<CJK Ideograph>) 366 0x50AB 傫 (<CJK Ideograph>) 367 0x50AD 傭 (<CJK Ideograph>) 368 0x50AE 傮 (<CJK Ideograph>) 369 0x50AF 傯 (<CJK Ideograph>) 370 0x50B0 傰 (<CJK Ideograph>) 371 0x50B1 傱 (<CJK Ideograph>) 372 0x50B3 傳 (<CJK Ideograph>) 373 0x50B4 傴 (<CJK Ideograph>) 374 0x50B5 債 (<CJK Ideograph>) 375 0x50B6 傶 (<CJK Ideograph>) 376 0x50B7 傷 (<CJK Ideograph>) 377 0x50B8 傸 (<CJK Ideograph>) 378 0x50B9 傹 (<CJK Ideograph>) 379 0x50BC 傼 (<CJK Ideograph>) 380 0x50BD 傽 (<CJK Ideograph>) 381 0x50BE 傾 (<CJK Ideograph>) 382 0x50BF 傿 (<CJK Ideograph>) 383 0x50C0 僀 (<CJK Ideograph>) 384 0x50C1 僁 (<CJK Ideograph>) 385 0x50C2 僂 (<CJK Ideograph>) 386 0x50C3 僃 (<CJK Ideograph>) 387 0x50C4 僄 (<CJK Ideograph>) 388 0x50C5 僅 (<CJK Ideograph>) 389 0x50C6 僆 (<CJK Ideograph>) 390 0x50C7 僇 (<CJK Ideograph>) 391 0x50C8 僈 (<CJK Ideograph>) 392 0x50C9 僉 (<CJK Ideograph>) 393 0x50CA 僊 (<CJK Ideograph>) 394 0x50CB 僋 (<CJK Ideograph>) 395 0x50CC 僌 (<CJK Ideograph>) 396 0x50CD 働 (<CJK Ideograph>) 397 0x50CE 僎 (<CJK Ideograph>) 398 0x50D0 僐 (<CJK Ideograph>) 399 0x50D1 僑 (<CJK Ideograph>) 400 0x50D2 僒 (<CJK Ideograph>) 401 0x50D3 僓 (<CJK Ideograph>) 402 0x50D4 僔 (<CJK Ideograph>) 403 0x50D5 僕 (<CJK Ideograph>) 404 0x50D7 僗 (<CJK Ideograph>) 405 0x50D8 僘 (<CJK Ideograph>) 406 0x50D9 僙 (<CJK Ideograph>) 407 0x50DB 僛 (<CJK Ideograph>) 408 0x50DC 僜 (<CJK Ideograph>) 409 0x50DD 僝 (<CJK Ideograph>) 410 0x50DE 僞 (<CJK Ideograph>) 411 0x50DF 僟 (<CJK Ideograph>) 412 0x50E0 僠 (<CJK Ideograph>) 413 0x50E1 僡 (<CJK Ideograph>) 414 0x50E2 僢 (<CJK Ideograph>) 415 0x50E3 僣 (<CJK Ideograph>) 416 0x50E4 僤 (<CJK Ideograph>) 417 0x50E5 僥 (<CJK Ideograph>) 418 0x50E8 僨 (<CJK Ideograph>) 419 0x50E9 僩 (<CJK Ideograph>) 420 0x50EA 僪 (<CJK Ideograph>) 421 0x50EB 僫 (<CJK Ideograph>) 422 0x50EF 僯 (<CJK Ideograph>) 423 0x50F0 僰 (<CJK Ideograph>) 424 0x50F1 僱 (<CJK Ideograph>) 425 0x50F2 僲 (<CJK Ideograph>) 426 0x50F4 僴 (<CJK Ideograph>) 427 0x50F6 僶 (<CJK Ideograph>) 428 0x50F7 僷 (<CJK Ideograph>) 429 0x50F8 僸 (<CJK Ideograph>) 430 0x50F9 價 (<CJK Ideograph>) 431 0x50FA 僺 (<CJK Ideograph>) 432 0x50FC 僼 (<CJK Ideograph>) 433 0x50FD 僽 (<CJK Ideograph>) 434 0x50FE 僾 (<CJK Ideograph>) 435 0x50FF 僿 (<CJK Ideograph>) 436 0x5100 儀 (<CJK Ideograph>) 437 0x5101 儁 (<CJK Ideograph>) 438 0x5102 儂 (<CJK Ideograph>) 439 0x5103 儃 (<CJK Ideograph>) 440 0x5104 億 (<CJK Ideograph>) 441 0x5105 儅 (<CJK Ideograph>) 442 0x5108 儈 (<CJK Ideograph>) 443 0x5109 儉 (<CJK Ideograph>) 444 0x510A 儊 (<CJK Ideograph>) 445 0x510C 儌 (<CJK Ideograph>) 446 0x510D 儍 (<CJK Ideograph>) 447 0x510E 儎 (<CJK Ideograph>) 448 0x510F 儏 (<CJK Ideograph>) 449 0x5110 儐 (<CJK Ideograph>) 450 0x5111 儑 (<CJK Ideograph>) 451 0x5113 儓 (<CJK Ideograph>) 452 0x5114 儔 (<CJK Ideograph>) 453 0x5115 儕 (<CJK Ideograph>) 454 0x5116 儖 (<CJK Ideograph>) 455 0x5117 儗 (<CJK Ideograph>) 456 0x5118 儘 (<CJK Ideograph>) 457 0x5119 儙 (<CJK Ideograph>) 458 0x511A 儚 (<CJK Ideograph>) 459 0x511B 儛 (<CJK Ideograph>) 460 0x511C 儜 (<CJK Ideograph>) 461 0x511D 儝 (<CJK Ideograph>) 462 0x511E 儞 (<CJK Ideograph>) 463 0x511F 償 (<CJK Ideograph>) 464 0x5120 儠 (<CJK Ideograph>) 465 0x5122 儢 (<CJK Ideograph>) 466 0x5123 儣 (<CJK Ideograph>) 467 0x5124 儤 (<CJK Ideograph>) 468 0x5125 儥 (<CJK Ideograph>) 469 0x5126 儦 (<CJK Ideograph>) 470 0x5127 儧 (<CJK Ideograph>) 471 0x5128 儨 (<CJK Ideograph>) 472 0x5129 儩 (<CJK Ideograph>) 473 0x512A 優 (<CJK Ideograph>) 474 0x512B 儫 (<CJK Ideograph>) 475 0x512C 儬 (<CJK Ideograph>) 476 0x512D 儭 (<CJK Ideograph>) 477 0x512E 儮 (<CJK Ideograph>) 478 0x512F 儯 (<CJK Ideograph>) 479 0x5130 儰 (<CJK Ideograph>) 480 0x5131 儱 (<CJK Ideograph>) 481 0x5132 儲 (<CJK Ideograph>) 482 0x5133 儳 (<CJK Ideograph>) 483 0x5134 儴 (<CJK Ideograph>) 484 0x5135 儵 (<CJK Ideograph>) 485 0x5136 儶 (<CJK Ideograph>) 486 0x5137 儷 (<CJK Ideograph>) 487 0x5138 儸 (<CJK Ideograph>) 488 0x5139 儹 (<CJK Ideograph>) 489 0x513A 儺 (<CJK Ideograph>) 490 0x513B 儻 (<CJK Ideograph>) 491 0x513C 儼 (<CJK Ideograph>) 492 0x513D 儽 (<CJK Ideograph>) 493 0x513E 儾 (<CJK Ideograph>) 494 0x5142 兂 (<CJK Ideograph>) 495 0x5147 兇 (<CJK Ideograph>) 496 0x514A 兊 (<CJK Ideograph>) 497 0x514C 兌 (<CJK Ideograph>) 498 0x514E 兎 (<CJK Ideograph>) 499 0x514F 兏 (<CJK Ideograph>) 500 0x5150 児 (<CJK Ideograph>) 501 0x5152 兒 (<CJK Ideograph>) 502 0x5153 兓 (<CJK Ideograph>) 503 0x5157 兗 (<CJK Ideograph>) 504 0x5158 兘 (<CJK Ideograph>) 505 0x5159 兙 (<CJK Ideograph>) 506 0x515B 兛 (<CJK Ideograph>) 507 0x515D 兝 (<CJK Ideograph>) 508 0x515E 兞 (<CJK Ideograph>) 509 0x515F 兟 (<CJK Ideograph>) 510 0x5160 兠 (<CJK Ideograph>) 511 0x5161 兡 (<CJK Ideograph>) 512 0x5163 兣 (<CJK Ideograph>) 513 0x5164 兤 (<CJK Ideograph>) 514 0x5166 兦 (<CJK Ideograph>) 515 0x5167 內 (<CJK Ideograph>) 516 0x5169 兩 (<CJK Ideograph>) 517 0x516A 兪 (<CJK Ideograph>) 518 0x516F 兯 (<CJK Ideograph>) 519 0x5172 兲 (<CJK Ideograph>) 520 0x517A 兺 (<CJK Ideograph>) 521 0x517E 兾 (<CJK Ideograph>) 522 0x517F 兿 (<CJK Ideograph>) 523 0x5183 冃 (<CJK Ideograph>) 524 0x5184 冄 (<CJK Ideograph>) 525 0x5186 円 (<CJK Ideograph>) 526 0x5187 冇 (<CJK Ideograph>) 527 0x518A 冊 (<CJK Ideograph>) 528 0x518B 冋 (<CJK Ideograph>) 529 0x518E 冎 (<CJK Ideograph>) 530 0x518F 冏 (<CJK Ideograph>) 531 0x5190 冐 (<CJK Ideograph>) 532 0x5191 冑 (<CJK Ideograph>) 533 0x5193 冓 (<CJK Ideograph>) 534 0x5194 冔 (<CJK Ideograph>) 535 0x5198 冘 (<CJK Ideograph>) 536 0x519A 冚 (<CJK Ideograph>) 537 0x519D 冝 (<CJK Ideograph>) 538 0x519E 冞 (<CJK Ideograph>) 539 0x519F 冟 (<CJK Ideograph>) 540 0x51A1 冡 (<CJK Ideograph>) 541 0x51A3 冣 (<CJK Ideograph>) 542 0x51A6 冦 (<CJK Ideograph>) 543 0x51A7 冧 (<CJK Ideograph>) 544 0x51A8 冨 (<CJK Ideograph>) 545 0x51A9 冩 (<CJK Ideograph>) 546 0x51AA 冪 (<CJK Ideograph>) 547 0x51AD 冭 (<CJK Ideograph>) 548 0x51AE 冮 (<CJK Ideograph>) 549 0x51B4 冴 (<CJK Ideograph>) 550 0x51B8 冸 (<CJK Ideograph>) 551 0x51B9 冹 (<CJK Ideograph>) 552 0x51BA 冺 (<CJK Ideograph>) 553 0x51BE 冾 (<CJK Ideograph>) 554 0x51BF 冿 (<CJK Ideograph>) 555 0x51C1 凁 (<CJK Ideograph>) 556 0x51C2 凂 (<CJK Ideograph>) 557 0x51C3 凃 (<CJK Ideograph>) 558 0x51C5 凅 (<CJK Ideograph>) 559 0x51C8 凈 (<CJK Ideograph>) 560 0x51CA 凊 (<CJK Ideograph>) 561 0x51CD 凍 (<CJK Ideograph>) 562 0x51CE 凎 (<CJK Ideograph>) 563 0x51D0 凐 (<CJK Ideograph>) 564 0x51D2 凒 (<CJK Ideograph>) 565 0x51D3 凓 (<CJK Ideograph>) 566 0x51D4 凔 (<CJK Ideograph>) 567 0x51D5 凕 (<CJK Ideograph>) 568 0x51D6 凖 (<CJK Ideograph>) 569 0x51D7 凗 (<CJK Ideograph>) 570 0x51D8 凘 (<CJK Ideograph>) 571 0x51D9 凙 (<CJK Ideograph>) 572 0x51DA 凚 (<CJK Ideograph>) 573 0x51DC 凜 (<CJK Ideograph>) 574 0x51DE 凞 (<CJK Ideograph>) 575 0x51DF 凟 (<CJK Ideograph>) 576 0x51E2 凢 (<CJK Ideograph>) 577 0x51E3 凣 (<CJK Ideograph>) 578 0x51E5 凥 (<CJK Ideograph>) 579 0x51E6 処 (<CJK Ideograph>) 580 0x51E7 凧 (<CJK Ideograph>) 581 0x51E8 凨 (<CJK Ideograph>) 582 0x51E9 凩 (<CJK Ideograph>) 583 0x51EA 凪 (<CJK Ideograph>) 584 0x51EC 凬 (<CJK Ideograph>) 585 0x51EE 凮 (<CJK Ideograph>) 586 0x51F1 凱 (<CJK Ideograph>) 587 0x51F2 凲 (<CJK Ideograph>) 588 0x51F4 凴 (<CJK Ideograph>) 589 0x51F7 凷 (<CJK Ideograph>) 590 0x51FE 凾 (<CJK Ideograph>) 591 0x5204 刄 (<CJK Ideograph>) 592 0x5205 刅 (<CJK Ideograph>) 593 0x5209 刉 (<CJK Ideograph>) 594 0x520B 刋 (<CJK Ideograph>) 595 0x520C 刌 (<CJK Ideograph>) 596 0x520F 刏 (<CJK Ideograph>) 597 0x5210 刐 (<CJK Ideograph>) 598 0x5213 刓 (<CJK Ideograph>) 599 0x5214 刔 (<CJK Ideograph>) 600 0x5215 刕 (<CJK Ideograph>) 601 0x521C 刜 (<CJK Ideograph>) 602 0x521E 刞 (<CJK Ideograph>) 603 0x521F 刟 (<CJK Ideograph>) 604 0x5221 刡 (<CJK Ideograph>) 605 0x5222 刢 (<CJK Ideograph>) 606 0x5223 刣 (<CJK Ideograph>) 607 0x5225 別 (<CJK Ideograph>) 608 0x5226 刦 (<CJK Ideograph>) 609 0x5227 刧 (<CJK Ideograph>) 610 0x522A 刪 (<CJK Ideograph>) 611 0x522C 刬 (<CJK Ideograph>) 612 0x522F 刯 (<CJK Ideograph>) 613 0x5231 刱 (<CJK Ideograph>) 614 0x5232 刲 (<CJK Ideograph>) 615 0x5234 刴 (<CJK Ideograph>) 616 0x5235 刵 (<CJK Ideograph>) 617 0x523C 刼 (<CJK Ideograph>) 618 0x523E 刾 (<CJK Ideograph>) 619 0x5244 剄 (<CJK Ideograph>) 620 0x5245 剅 (<CJK Ideograph>) 621 0x5246 剆 (<CJK Ideograph>) 622 0x5247 則 (<CJK Ideograph>) 623 0x5248 剈 (<CJK Ideograph>) 624 0x5249 剉 (<CJK Ideograph>) 625 0x524B 剋 (<CJK Ideograph>) 626 0x524E 剎 (<CJK Ideograph>) 627 0x524F 剏 (<CJK Ideograph>) 628 0x5252 剒 (<CJK Ideograph>) 629 0x5253 剓 (<CJK Ideograph>) 630 0x5255 剕 (<CJK Ideograph>) 631 0x5257 剗 (<CJK Ideograph>) 632 0x5258 剘 (<CJK Ideograph>) 633 0x5259 剙 (<CJK Ideograph>) 634 0x525A 剚 (<CJK Ideograph>) 635 0x525B 剛 (<CJK Ideograph>) 636 0x525D 剝 (<CJK Ideograph>) 637 0x525F 剟 (<CJK Ideograph>) 638 0x5260 剠 (<CJK Ideograph>) 639 0x5262 剢 (<CJK Ideograph>) 640 0x5263 剣 (<CJK Ideograph>) 641 0x5264 剤 (<CJK Ideograph>) 642 0x5266 剦 (<CJK Ideograph>) 643 0x5268 剨 (<CJK Ideograph>) 644 0x526B 剫 (<CJK Ideograph>) 645 0x526C 剬 (<CJK Ideograph>) 646 0x526D 剭 (<CJK Ideograph>) 647 0x526E 剮 (<CJK Ideograph>) 648 0x5270 剰 (<CJK Ideograph>) 649 0x5271 剱 (<CJK Ideograph>) 650 0x5273 剳 (<CJK Ideograph>) 651 0x5274 剴 (<CJK Ideograph>) 652 0x5275 創 (<CJK Ideograph>) 653 0x5276 剶 (<CJK Ideograph>) 654 0x5277 剷 (<CJK Ideograph>) 655 0x5278 剸 (<CJK Ideograph>) 656 0x5279 剹 (<CJK Ideograph>) 657 0x527A 剺 (<CJK Ideograph>) 658 0x527B 剻 (<CJK Ideograph>) 659 0x527C 剼 (<CJK Ideograph>) 660 0x527E 剾 (<CJK Ideograph>) 661 0x5280 劀 (<CJK Ideograph>) 662 0x5283 劃 (<CJK Ideograph>) 663 0x5284 劄 (<CJK Ideograph>) 664 0x5285 劅 (<CJK Ideograph>) 665 0x5286 劆 (<CJK Ideograph>) 666 0x5287 劇 (<CJK Ideograph>) 667 0x5289 劉 (<CJK Ideograph>) 668 0x528A 劊 (<CJK Ideograph>) 669 0x528B 劋 (<CJK Ideograph>) 670 0x528C 劌 (<CJK Ideograph>) 671 0x528D 劍 (<CJK Ideograph>) 672 0x528E 劎 (<CJK Ideograph>) 673 0x528F 劏 (<CJK Ideograph>) 674 0x5291 劑 (<CJK Ideograph>) 675 0x5292 劒 (<CJK Ideograph>) 676 0x5294 劔 (<CJK Ideograph>) 677 0x5295 劕 (<CJK Ideograph>) 678 0x5296 劖 (<CJK Ideograph>) 679 0x5297 劗 (<CJK Ideograph>) 680 0x5298 劘 (<CJK Ideograph>) 681 0x5299 劙 (<CJK Ideograph>) 682 0x529A 劚 (<CJK Ideograph>) 683 0x529C 劜 (<CJK Ideograph>) 684 0x52A4 劤 (<CJK Ideograph>) 685 0x52A5 劥 (<CJK Ideograph>) 686 0x52A6 劦 (<CJK Ideograph>) 687 0x52A7 劧 (<CJK Ideograph>) 688 0x52AE 劮 (<CJK Ideograph>) 689 0x52AF 劯 (<CJK Ideograph>) 690 0x52B0 劰 (<CJK Ideograph>) 691 0x52B4 労 (<CJK Ideograph>) 692 0x52B5 劵 (<CJK Ideograph>) 693 0x52B6 劶 (<CJK Ideograph>) 694 0x52B7 劷 (<CJK Ideograph>) 695 0x52B8 劸 (<CJK Ideograph>) 696 0x52B9 効 (<CJK Ideograph>) 697 0x52BA 劺 (<CJK Ideograph>) 698 0x52BB 劻 (<CJK Ideograph>) 699 0x52BC 劼 (<CJK Ideograph>) 700 0x52BD 劽 (<CJK Ideograph>) 701 0x52C0 勀 (<CJK Ideograph>) 702 0x52C1 勁 (<CJK Ideograph>) 703 0x52C2 勂 (<CJK Ideograph>) 704 0x52C4 勄 (<CJK Ideograph>) 705 0x52C5 勅 (<CJK Ideograph>) 706 0x52C6 勆 (<CJK Ideograph>) 707 0x52C8 勈 (<CJK Ideograph>) 708 0x52CA 勊 (<CJK Ideograph>) 709 0x52CC 勌 (<CJK Ideograph>) 710 0x52CD 勍 (<CJK Ideograph>) 711 0x52CE 勎 (<CJK Ideograph>) 712 0x52CF 勏 (<CJK Ideograph>) 713 0x52D1 勑 (<CJK Ideograph>) 714 0x52D3 勓 (<CJK Ideograph>) 715 0x52D4 勔 (<CJK Ideograph>) 716 0x52D5 動 (<CJK Ideograph>) 717 0x52D7 勗 (<CJK Ideograph>) 718 0x52D9 務 (<CJK Ideograph>) 719 0x52DA 勚 (<CJK Ideograph>) 720 0x52DB 勛 (<CJK Ideograph>) 721 0x52DC 勜 (<CJK Ideograph>) 722 0x52DD 勝 (<CJK Ideograph>) 723 0x52DE 勞 (<CJK Ideograph>) 724 0x52E0 勠 (<CJK Ideograph>) 725 0x52E1 勡 (<CJK Ideograph>) 726 0x52E2 勢 (<CJK Ideograph>) 727 0x52E3 勣 (<CJK Ideograph>) 728 0x52E5 勥 (<CJK Ideograph>) 729 0x52E6 勦 (<CJK Ideograph>) 730 0x52E7 勧 (<CJK Ideograph>) 731 0x52E8 勨 (<CJK Ideograph>) 732 0x52E9 勩 (<CJK Ideograph>) 733 0x52EA 勪 (<CJK Ideograph>) 734 0x52EB 勫 (<CJK Ideograph>) 735 0x52EC 勬 (<CJK Ideograph>) 736 0x52ED 勭 (<CJK Ideograph>) 737 0x52EE 勮 (<CJK Ideograph>) 738 0x52EF 勯 (<CJK Ideograph>) 739 0x52F1 勱 (<CJK Ideograph>) 740 0x52F2 勲 (<CJK Ideograph>) 741 0x52F3 勳 (<CJK Ideograph>) 742 0x52F4 勴 (<CJK Ideograph>) 743 0x52F5 勵 (<CJK Ideograph>) 744 0x52F6 勶 (<CJK Ideograph>) 745 0x52F7 勷 (<CJK Ideograph>) 746 0x52F8 勸 (<CJK Ideograph>) 747 0x52FB 勻 (<CJK Ideograph>) 748 0x52FC 勼 (<CJK Ideograph>) 749 0x52FD 勽 (<CJK Ideograph>) 750 0x5301 匁 (<CJK Ideograph>) 751 0x5302 匂 (<CJK Ideograph>) 752 0x5303 匃 (<CJK Ideograph>) 753 0x5304 匄 (<CJK Ideograph>) 754 0x5307 匇 (<CJK Ideograph>) 755 0x5309 匉 (<CJK Ideograph>) 756 0x530A 匊 (<CJK Ideograph>) 757 0x530B 匋 (<CJK Ideograph>) 758 0x530C 匌 (<CJK Ideograph>) 759 0x530E 匎 (<CJK Ideograph>) 760 0x5311 匑 (<CJK Ideograph>) 761 0x5312 匒 (<CJK Ideograph>) 762 0x5313 匓 (<CJK Ideograph>) 763 0x5314 匔 (<CJK Ideograph>) 764 0x5318 匘 (<CJK Ideograph>) 765 0x531B 匛 (<CJK Ideograph>) 766 0x531C 匜 (<CJK Ideograph>) 767 0x531E 匞 (<CJK Ideograph>) 768 0x531F 匟 (<CJK Ideograph>) 769 0x5322 匢 (<CJK Ideograph>) 770 0x5324 匤 (<CJK Ideograph>) 771 0x5325 匥 (<CJK Ideograph>) 772 0x5327 匧 (<CJK Ideograph>) 773 0x5328 匨 (<CJK Ideograph>) 774 0x5329 匩 (<CJK Ideograph>) 775 0x532B 匫 (<CJK Ideograph>) 776 0x532C 匬 (<CJK Ideograph>) 777 0x532D 匭 (<CJK Ideograph>) 778 0x532F 匯 (<CJK Ideograph>) 779 0x5330 匰 (<CJK Ideograph>) 780 0x5331 匱 (<CJK Ideograph>) 781 0x5332 匲 (<CJK Ideograph>) 782 0x5333 匳 (<CJK Ideograph>) 783 0x5334 匴 (<CJK Ideograph>) 784 0x5335 匵 (<CJK Ideograph>) 785 0x5336 匶 (<CJK Ideograph>) 786 0x5337 匷 (<CJK Ideograph>) 787 0x5338 匸 (<CJK Ideograph>) 788 0x533C 匼 (<CJK Ideograph>) 789 0x533D 匽 (<CJK Ideograph>) 790 0x5340 區 (<CJK Ideograph>) 791 0x5342 卂 (<CJK Ideograph>) 792 0x5344 卄 (<CJK Ideograph>) 793 0x5346 卆 (<CJK Ideograph>) 794 0x534B 卋 (<CJK Ideograph>) 795 0x534C 卌 (<CJK Ideograph>) 796 0x534D 卍 (<CJK Ideograph>) 797 0x5350 卐 (<CJK Ideograph>) 798 0x5354 協 (<CJK Ideograph>) 799 0x5358 単 (<CJK Ideograph>) 800 0x5359 卙 (<CJK Ideograph>) 801 0x535B 卛 (<CJK Ideograph>) 802 0x535D 卝 (<CJK Ideograph>) 803 0x5365 卥 (<CJK Ideograph>) 804 0x5368 卨 (<CJK Ideograph>) 805 0x536A 卪 (<CJK Ideograph>) 806 0x536C 卬 (<CJK Ideograph>) 807 0x536D 卭 (<CJK Ideograph>) 808 0x5372 卲 (<CJK Ideograph>) 809 0x5376 卶 (<CJK Ideograph>) 810 0x5379 卹 (<CJK Ideograph>) 811 0x537B 卻 (<CJK Ideograph>) 812 0x537C 卼 (<CJK Ideograph>) 813 0x537D 卽 (<CJK Ideograph>) 814 0x537E 卾 (<CJK Ideograph>) 815 0x5380 厀 (<CJK Ideograph>) 816 0x5381 厁 (<CJK Ideograph>) 817 0x5383 厃 (<CJK Ideograph>) 818 0x5387 厇 (<CJK Ideograph>) 819 0x5388 厈 (<CJK Ideograph>) 820 0x538A 厊 (<CJK Ideograph>) 821 0x538E 厎 (<CJK Ideograph>) 822 0x538F 厏 (<CJK Ideograph>) 823 0x5390 厐 (<CJK Ideograph>) 824 0x5391 厑 (<CJK Ideograph>) 825 0x5392 厒 (<CJK Ideograph>) 826 0x5393 厓 (<CJK Ideograph>) 827 0x5394 厔 (<CJK Ideograph>) 828 0x5396 厖 (<CJK Ideograph>) 829 0x5397 厗 (<CJK Ideograph>) 830 0x5399 厙 (<CJK Ideograph>) 831 0x539B 厛 (<CJK Ideograph>) 832 0x539C 厜 (<CJK Ideograph>) 833 0x539E 厞 (<CJK Ideograph>) 834 0x53A0 厠 (<CJK Ideograph>) 835 0x53A1 厡 (<CJK Ideograph>) 836 0x53A4 厤 (<CJK Ideograph>) 837 0x53A7 厧 (<CJK Ideograph>) 838 0x53AA 厪 (<CJK Ideograph>) 839 0x53AB 厫 (<CJK Ideograph>) 840 0x53AC 厬 (<CJK Ideograph>) 841 0x53AD 厭 (<CJK Ideograph>) 842 0x53AF 厯 (<CJK Ideograph>) 843 0x53B0 厰 (<CJK Ideograph>) 844 0x53B1 厱 (<CJK Ideograph>) 845 0x53B2 厲 (<CJK Ideograph>) 846 0x53B3 厳 (<CJK Ideograph>) 847 0x53B4 厴 (<CJK Ideograph>) 848 0x53B5 厵 (<CJK Ideograph>) 849 0x53B7 厷 (<CJK Ideograph>) 850 0x53B8 厸 (<CJK Ideograph>) 851 0x53B9 厹 (<CJK Ideograph>) 852 0x53BA 厺 (<CJK Ideograph>) 853 0x53BC 厼 (<CJK Ideograph>) 854 0x53BD 厽 (<CJK Ideograph>) 855 0x53BE 厾 (<CJK Ideograph>) 856 0x53C0 叀 (<CJK Ideograph>) 857 0x53C3 參 (<CJK Ideograph>) 858 0x53C4 叄 (<CJK Ideograph>) 859 0x53C5 叅 (<CJK Ideograph>) 860 0x53C6 叆 (<CJK Ideograph>) 861 0x53C7 叇 (<CJK Ideograph>) 862 0x53CE 収 (<CJK Ideograph>) 863 0x53CF 叏 (<CJK Ideograph>) 864 0x53D0 叐 (<CJK Ideograph>) 865 0x53D2 叒 (<CJK Ideograph>) 866 0x53D3 叓 (<CJK Ideograph>) 867 0x53D5 叕 (<CJK Ideograph>) 868 0x53DA 叚 (<CJK Ideograph>) 869 0x53DC 叜 (<CJK Ideograph>) 870 0x53DD 叝 (<CJK Ideograph>) 871 0x53DE 叞 (<CJK Ideograph>) 872 0x53E1 叡 (<CJK Ideograph>) 873 0x53E2 叢 (<CJK Ideograph>) 874 0x53E7 叧 (<CJK Ideograph>) 875 0x53F4 叴 (<CJK Ideograph>) 876 0x53FA 叺 (<CJK Ideograph>) 877 0x53FE 叾 (<CJK Ideograph>) 878 0x53FF 叿 (<CJK Ideograph>) 879 0x5400 吀 (<CJK Ideograph>) 880 0x5402 吂 (<CJK Ideograph>) 881 0x5405 吅 (<CJK Ideograph>) 882 0x5407 吇 (<CJK Ideograph>) 883 0x540B 吋 (<CJK Ideograph>) 884 0x5414 吔 (<CJK Ideograph>) 885 0x5418 吘 (<CJK Ideograph>) 886 0x5419 吙 (<CJK Ideograph>) 887 0x541A 吚 (<CJK Ideograph>) 888 0x541C 吜 (<CJK Ideograph>) 889 0x5422 吢 (<CJK Ideograph>) 890 0x5424 吤 (<CJK Ideograph>) 891 0x5425 吥 (<CJK Ideograph>) 892 0x542A 吪 (<CJK Ideograph>) 893 0x5430 吰 (<CJK Ideograph>) 894 0x5433 吳 (<CJK Ideograph>) 895 0x5436 吶 (<CJK Ideograph>) 896 0x5437 吷 (<CJK Ideograph>) 897 0x543A 吺 (<CJK Ideograph>) 898 0x543D 吽 (<CJK Ideograph>) 899 0x543F 吿 (<CJK Ideograph>) 900 0x5441 呁 (<CJK Ideograph>) 901 0x5442 呂 (<CJK Ideograph>) 902 0x5444 呄 (<CJK Ideograph>) 903 0x5445 呅 (<CJK Ideograph>) 904 0x5447 呇 (<CJK Ideograph>) 905 0x5449 呉 (<CJK Ideograph>) 906 0x544C 呌 (<CJK Ideograph>) 907 0x544D 呍 (<CJK Ideograph>) 908 0x544E 呎 (<CJK Ideograph>) 909 0x544F 呏 (<CJK Ideograph>) 910 0x5451 呑 (<CJK Ideograph>) 911 0x545A 呚 (<CJK Ideograph>) 912 0x545D 呝 (<CJK Ideograph>) 913 0x545E 呞 (<CJK Ideograph>) 914 0x545F 呟 (<CJK Ideograph>) 915 0x5460 呠 (<CJK Ideograph>) 916 0x5461 呡 (<CJK Ideograph>) 917 0x5463 呣 (<CJK Ideograph>) 918 0x5465 呥 (<CJK Ideograph>) 919 0x5467 呧 (<CJK Ideograph>) 920 0x5469 呩 (<CJK Ideograph>) 921 0x546A 呪 (<CJK Ideograph>) 922 0x546B 呫 (<CJK Ideograph>) 923 0x546C 呬 (<CJK Ideograph>) 924 0x546D 呭 (<CJK Ideograph>) 925 0x546E 呮 (<CJK Ideograph>) 926 0x546F 呯 (<CJK Ideograph>) 927 0x5470 呰 (<CJK Ideograph>) 928 0x5474 呴 (<CJK Ideograph>) 929 0x5479 呹 (<CJK Ideograph>) 930 0x547A 呺 (<CJK Ideograph>) 931 0x547E 呾 (<CJK Ideograph>) 932 0x547F 呿 (<CJK Ideograph>) 933 0x5481 咁 (<CJK Ideograph>) 934 0x5483 咃 (<CJK Ideograph>) 935 0x5485 咅 (<CJK Ideograph>) 936 0x5487 咇 (<CJK Ideograph>) 937 0x5488 咈 (<CJK Ideograph>) 938 0x5489 咉 (<CJK Ideograph>) 939 0x548A 咊 (<CJK Ideograph>) 940 0x548D 咍 (<CJK Ideograph>) 941 0x5491 咑 (<CJK Ideograph>) 942 0x5493 咓 (<CJK Ideograph>) 943 0x5497 咗 (<CJK Ideograph>) 944 0x5498 咘 (<CJK Ideograph>) 945 0x549C 咜 (<CJK Ideograph>) 946 0x549E 咞 (<CJK Ideograph>) 947 0x549F 咟 (<CJK Ideograph>) 948 0x54A0 咠 (<CJK Ideograph>) 949 0x54A1 咡 (<CJK Ideograph>) 950 0x54A2 咢 (<CJK Ideograph>) 951 0x54A5 咥 (<CJK Ideograph>) 952 0x54AE 咮 (<CJK Ideograph>) 953 0x54B0 咰 (<CJK Ideograph>) 954 0x54B2 咲 (<CJK Ideograph>) 955 0x54B5 咵 (<CJK Ideograph>) 956 0x54B6 咶 (<CJK Ideograph>) 957 0x54B7 咷 (<CJK Ideograph>) 958 0x54B9 咹 (<CJK Ideograph>) 959 0x54BA 咺 (<CJK Ideograph>) 960 0x54BC 咼 (<CJK Ideograph>) 961 0x54BE 咾 (<CJK Ideograph>) 962 0x54C3 哃 (<CJK Ideograph>) 963 0x54C5 哅 (<CJK Ideograph>) 964 0x54CA 哊 (<CJK Ideograph>) 965 0x54CB 哋 (<CJK Ideograph>) 966 0x54D6 哖 (<CJK Ideograph>) 967 0x54D8 哘 (<CJK Ideograph>) 968 0x54DB 哛 (<CJK Ideograph>) 969 0x54E0 哠 (<CJK Ideograph>) 970 0x54E1 員 (<CJK Ideograph>) 971 0x54E2 哢 (<CJK Ideograph>) 972 0x54E3 哣 (<CJK Ideograph>) 973 0x54E4 哤 (<CJK Ideograph>) 974 0x54EB 哫 (<CJK Ideograph>) 975 0x54EC 哬 (<CJK Ideograph>) 976 0x54EF 哯 (<CJK Ideograph>) 977 0x54F0 哰 (<CJK Ideograph>) 978 0x54F1 哱 (<CJK Ideograph>) 979 0x54F4 哴 (<CJK Ideograph>) 980 0x54F5 哵 (<CJK Ideograph>) 981 0x54F6 哶 (<CJK Ideograph>) 982 0x54F7 哷 (<CJK Ideograph>) 983 0x54F8 哸 (<CJK Ideograph>) 984 0x54F9 哹 (<CJK Ideograph>) 985 0x54FB 哻 (<CJK Ideograph>) 986 0x54FE 哾 (<CJK Ideograph>) 987 0x5500 唀 (<CJK Ideograph>) 988 0x5502 唂 (<CJK Ideograph>) 989 0x5503 唃 (<CJK Ideograph>) 990 0x5504 唄 (<CJK Ideograph>) 991 0x5505 唅 (<CJK Ideograph>) 992 0x5508 唈 (<CJK Ideograph>) 993 0x550A 唊 (<CJK Ideograph>) 994 0x550B 唋 (<CJK Ideograph>) 995 0x550C 唌 (<CJK Ideograph>) 996 0x550D 唍 (<CJK Ideograph>) 997 0x550E 唎 (<CJK Ideograph>) 998 0x5512 唒 (<CJK Ideograph>) 999 0x5513 唓 (<CJK Ideograph>) 1000 0x5515 唕 (<CJK Ideograph>) 1001 0x5516 唖 (<CJK Ideograph>) 1002 0x5517 唗 (<CJK Ideograph>) 1003 0x5518 唘 (<CJK Ideograph>) 1004 0x5519 唙 (<CJK Ideograph>) 1005 0x551A 唚 (<CJK Ideograph>) 1006 0x551C 唜 (<CJK Ideograph>) 1007 0x551D 唝 (<CJK Ideograph>) 1008 0x551E 唞 (<CJK Ideograph>) 1009 0x551F 唟 (<CJK Ideograph>) 1010 0x5521 唡 (<CJK Ideograph>) 1011 0x5525 唥 (<CJK Ideograph>) 1012 0x5526 唦 (<CJK Ideograph>) 1013 0x5528 唨 (<CJK Ideograph>) 1014 0x5529 唩 (<CJK Ideograph>) 1015 0x552B 唫 (<CJK Ideograph>) 1016 0x552D 唭 (<CJK Ideograph>) 1017 0x5532 唲 (<CJK Ideograph>) 1018 0x5534 唴 (<CJK Ideograph>) 1019 0x5535 唵 (<CJK Ideograph>) 1020 0x5536 唶 (<CJK Ideograph>) 1021 0x5538 唸 (<CJK Ideograph>) 1022 0x5539 唹 (<CJK Ideograph>) 1023 0x553A 唺 (<CJK Ideograph>) 1024 0x553B 唻 (<CJK Ideograph>) 1025 0x553D 唽 (<CJK Ideograph>) 1026 0x5540 啀 (<CJK Ideograph>) 1027 0x5542 啂 (<CJK Ideograph>) 1028 0x5545 啅 (<CJK Ideograph>) 1029 0x5547 啇 (<CJK Ideograph>) 1030 0x5548 啈 (<CJK Ideograph>) 1031 0x554B 啋 (<CJK Ideograph>) 1032 0x554C 啌 (<CJK Ideograph>) 1033 0x554D 啍 (<CJK Ideograph>) 1034 0x554E 啎 (<CJK Ideograph>) 1035 0x554F 問 (<CJK Ideograph>) 1036 0x5551 啑 (<CJK Ideograph>) 1037 0x5552 啒 (<CJK Ideograph>) 1038 0x5553 啓 (<CJK Ideograph>) 1039 0x5554 啔 (<CJK Ideograph>) 1040 0x5557 啗 (<CJK Ideograph>) 1041 0x5558 啘 (<CJK Ideograph>) 1042 0x5559 啙 (<CJK Ideograph>) 1043 0x555A 啚 (<CJK Ideograph>) 1044 0x555B 啛 (<CJK Ideograph>) 1045 0x555D 啝 (<CJK Ideograph>) 1046 0x555E 啞 (<CJK Ideograph>) 1047 0x555F 啟 (<CJK Ideograph>) 1048 0x5560 啠 (<CJK Ideograph>) 1049 0x5562 啢 (<CJK Ideograph>) 1050 0x5563 啣 (<CJK Ideograph>) 1051 0x5568 啨 (<CJK Ideograph>) 1052 0x5569 啩 (<CJK Ideograph>) 1053 0x556B 啫 (<CJK Ideograph>) 1054 0x556F 啯 (<CJK Ideograph>) 1055 0x5570 啰 (<CJK Ideograph>) 1056 0x5571 啱 (<CJK Ideograph>) 1057 0x5572 啲 (<CJK Ideograph>) 1058 0x5573 啳 (<CJK Ideograph>) 1059 0x5574 啴 (<CJK Ideograph>) 1060 0x5579 啹 (<CJK Ideograph>) 1061 0x557A 啺 (<CJK Ideograph>) 1062 0x557D 啽 (<CJK Ideograph>) 1063 0x557F 啿 (<CJK Ideograph>) 1064 0x5585 喅 (<CJK Ideograph>) 1065 0x5586 喆 (<CJK Ideograph>) 1066 0x558C 喌 (<CJK Ideograph>) 1067 0x558D 喍 (<CJK Ideograph>) 1068 0x558E 喎 (<CJK Ideograph>) 1069 0x5590 喐 (<CJK Ideograph>) 1070 0x5592 喒 (<CJK Ideograph>) 1071 0x5593 喓 (<CJK Ideograph>) 1072 0x5595 喕 (<CJK Ideograph>) 1073 0x5596 喖 (<CJK Ideograph>) 1074 0x5597 喗 (<CJK Ideograph>) 1075 0x559A 喚 (<CJK Ideograph>) 1076 0x559B 喛 (<CJK Ideograph>) 1077 0x559E 喞 (<CJK Ideograph>) 1078 0x55A0 喠 (<CJK Ideograph>) 1079 0x55A1 喡 (<CJK Ideograph>) 1080 0x55A2 喢 (<CJK Ideograph>) 1081 0x55A3 喣 (<CJK Ideograph>) 1082 0x55A4 喤 (<CJK Ideograph>) 1083 0x55A5 喥 (<CJK Ideograph>) 1084 0x55A6 喦 (<CJK Ideograph>) 1085 0x55A8 喨 (<CJK Ideograph>) 1086 0x55A9 喩 (<CJK Ideograph>) 1087 0x55AA 喪 (<CJK Ideograph>) 1088 0x55AB 喫 (<CJK Ideograph>) 1089 0x55AC 喬 (<CJK Ideograph>) 1090 0x55AD 喭 (<CJK Ideograph>) 1091 0x55AE 單 (<CJK Ideograph>) 1092 0x55AF 喯 (<CJK Ideograph>) 1093 0x55B0 喰 (<CJK Ideograph>) 1094 0x55B2 喲 (<CJK Ideograph>) 1095 0x55B4 喴 (<CJK Ideograph>) 1096 0x55B6 営 (<CJK Ideograph>) 1097 0x55B8 喸 (<CJK Ideograph>) 1098 0x55BA 喺 (<CJK Ideograph>) 1099 0x55BC 喼 (<CJK Ideograph>) 1100 0x55BF 喿 (<CJK Ideograph>) 1101 0x55C0 嗀 (<CJK Ideograph>) 1102 0x55C1 嗁 (<CJK Ideograph>) 1103 0x55C2 嗂 (<CJK Ideograph>) 1104 0x55C3 嗃 (<CJK Ideograph>) 1105 0x55C6 嗆 (<CJK Ideograph>) 1106 0x55C7 嗇 (<CJK Ideograph>) 1107 0x55C8 嗈 (<CJK Ideograph>) 1108 0x55CA 嗊 (<CJK Ideograph>) 1109 0x55CB 嗋 (<CJK Ideograph>) 1110 0x55CE 嗎 (<CJK Ideograph>) 1111 0x55CF 嗏 (<CJK Ideograph>) 1112 0x55D0 嗐 (<CJK Ideograph>) 1113 0x55D5 嗕 (<CJK Ideograph>) 1114 0x55D7 嗗 (<CJK Ideograph>) 1115 0x55D8 嗘 (<CJK Ideograph>) 1116 0x55D9 嗙 (<CJK Ideograph>) 1117 0x55DA 嗚 (<CJK Ideograph>) 1118 0x55DB 嗛 (<CJK Ideograph>) 1119 0x55DE 嗞 (<CJK Ideograph>) 1120 0x55E0 嗠 (<CJK Ideograph>) 1121 0x55E2 嗢 (<CJK Ideograph>) 1122 0x55E7 嗧 (<CJK Ideograph>) 1123 0x55E9 嗩 (<CJK Ideograph>) 1124 0x55ED 嗭 (<CJK Ideograph>) 1125 0x55EE 嗮 (<CJK Ideograph>) 1126 0x55F0 嗰 (<CJK Ideograph>) 1127 0x55F1 嗱 (<CJK Ideograph>) 1128 0x55F4 嗴 (<CJK Ideograph>) 1129 0x55F6 嗶 (<CJK Ideograph>) 1130 0x55F8 嗸 (<CJK Ideograph>) 1131 0x55F9 嗹 (<CJK Ideograph>) 1132 0x55FA 嗺 (<CJK Ideograph>) 1133 0x55FB 嗻 (<CJK Ideograph>) 1134 0x55FC 嗼 (<CJK Ideograph>) 1135 0x55FF 嗿 (<CJK Ideograph>) 1136 0x5602 嘂 (<CJK Ideograph>) 1137 0x5603 嘃 (<CJK Ideograph>) 1138 0x5604 嘄 (<CJK Ideograph>) 1139 0x5605 嘅 (<CJK Ideograph>) 1140 0x5606 嘆 (<CJK Ideograph>) 1141 0x5607 嘇 (<CJK Ideograph>) 1142 0x560A 嘊 (<CJK Ideograph>) 1143 0x560B 嘋 (<CJK Ideograph>) 1144 0x560D 嘍 (<CJK Ideograph>) 1145 0x5610 嘐 (<CJK Ideograph>) 1146 0x5611 嘑 (<CJK Ideograph>) 1147 0x5612 嘒 (<CJK Ideograph>) 1148 0x5613 嘓 (<CJK Ideograph>) 1149 0x5614 嘔 (<CJK Ideograph>) 1150 0x5615 嘕 (<CJK Ideograph>) 1151 0x5616 嘖 (<CJK Ideograph>) 1152 0x5617 嘗 (<CJK Ideograph>) 1153 0x5619 嘙 (<CJK Ideograph>) 1154 0x561A 嘚 (<CJK Ideograph>) 1155 0x561C 嘜 (<CJK Ideograph>) 1156 0x561D 嘝 (<CJK Ideograph>) 1157 0x5620 嘠 (<CJK Ideograph>) 1158 0x5621 嘡 (<CJK Ideograph>) 1159 0x5622 嘢 (<CJK Ideograph>) 1160 0x5625 嘥 (<CJK Ideograph>) 1161 0x5626 嘦 (<CJK Ideograph>) 1162 0x5628 嘨 (<CJK Ideograph>) 1163 0x5629 嘩 (<CJK Ideograph>) 1164 0x562A 嘪 (<CJK Ideograph>) 1165 0x562B 嘫 (<CJK Ideograph>) 1166 0x562E 嘮 (<CJK Ideograph>) 1167 0x562F 嘯 (<CJK Ideograph>) 1168 0x5630 嘰 (<CJK Ideograph>) 1169 0x5633 嘳 (<CJK Ideograph>) 1170 0x5635 嘵 (<CJK Ideograph>) 1171 0x5637 嘷 (<CJK Ideograph>) 1172 0x5638 嘸 (<CJK Ideograph>) 1173 0x563A 嘺 (<CJK Ideograph>) 1174 0x563C 嘼 (<CJK Ideograph>) 1175 0x563D 嘽 (<CJK Ideograph>) 1176 0x563E 嘾 (<CJK Ideograph>) 1177 0x5640 噀 (<CJK Ideograph>) 1178 0x5641 噁 (<CJK Ideograph>) 1179 0x5642 噂 (<CJK Ideograph>) 1180 0x5643 噃 (<CJK Ideograph>) 1181 0x5644 噄 (<CJK Ideograph>) 1182 0x5645 噅 (<CJK Ideograph>) 1183 0x5646 噆 (<CJK Ideograph>) 1184 0x5647 噇 (<CJK Ideograph>) 1185 0x5648 噈 (<CJK Ideograph>) 1186 0x5649 噉 (<CJK Ideograph>) 1187 0x564A 噊 (<CJK Ideograph>) 1188 0x564B 噋 (<CJK Ideograph>) 1189 0x564F 噏 (<CJK Ideograph>) 1190 0x5650 噐 (<CJK Ideograph>) 1191 0x5651 噑 (<CJK Ideograph>) 1192 0x5652 噒 (<CJK Ideograph>) 1193 0x5653 噓 (<CJK Ideograph>) 1194 0x5655 噕 (<CJK Ideograph>) 1195 0x5656 噖 (<CJK Ideograph>) 1196 0x565A 噚 (<CJK Ideograph>) 1197 0x565B 噛 (<CJK Ideograph>) 1198 0x565D 噝 (<CJK Ideograph>) 1199 0x565E 噞 (<CJK Ideograph>) 1200 0x565F 噟 (<CJK Ideograph>) 1201 0x5660 噠 (<CJK Ideograph>) 1202 0x5661 噡 (<CJK Ideograph>) 1203 0x5663 噣 (<CJK Ideograph>) 1204 0x5665 噥 (<CJK Ideograph>) 1205 0x5666 噦 (<CJK Ideograph>) 1206 0x5667 噧 (<CJK Ideograph>) 1207 0x566D 噭 (<CJK Ideograph>) 1208 0x566E 噮 (<CJK Ideograph>) 1209 0x566F 噯 (<CJK Ideograph>) 1210 0x5670 噰 (<CJK Ideograph>) 1211 0x5672 噲 (<CJK Ideograph>) 1212 0x5673 噳 (<CJK Ideograph>) 1213 0x5674 噴 (<CJK Ideograph>) 1214 0x5675 噵 (<CJK Ideograph>) 1215 0x5677 噷 (<CJK Ideograph>) 1216 0x5678 噸 (<CJK Ideograph>) 1217 0x5679 噹 (<CJK Ideograph>) 1218 0x567A 噺 (<CJK Ideograph>) 1219 0x567D 噽 (<CJK Ideograph>) 1220 0x567E 噾 (<CJK Ideograph>) 1221 0x567F 噿 (<CJK Ideograph>) 1222 0x5680 嚀 (<CJK Ideograph>) 1223 0x5681 嚁 (<CJK Ideograph>) 1224 0x5682 嚂 (<CJK Ideograph>) 1225 0x5683 嚃 (<CJK Ideograph>) 1226 0x5684 嚄 (<CJK Ideograph>) 1227 0x5687 嚇 (<CJK Ideograph>) 1228 0x5688 嚈 (<CJK Ideograph>) 1229 0x5689 嚉 (<CJK Ideograph>) 1230 0x568A 嚊 (<CJK Ideograph>) 1231 0x568B 嚋 (<CJK Ideograph>) 1232 0x568C 嚌 (<CJK Ideograph>) 1233 0x568D 嚍 (<CJK Ideograph>) 1234 0x5690 嚐 (<CJK Ideograph>) 1235 0x5691 嚑 (<CJK Ideograph>) 1236 0x5692 嚒 (<CJK Ideograph>) 1237 0x5694 嚔 (<CJK Ideograph>) 1238 0x5695 嚕 (<CJK Ideograph>) 1239 0x5696 嚖 (<CJK Ideograph>) 1240 0x5697 嚗 (<CJK Ideograph>) 1241 0x5698 嚘 (<CJK Ideograph>) 1242 0x5699 嚙 (<CJK Ideograph>) 1243 0x569A 嚚 (<CJK Ideograph>) 1244 0x569B 嚛 (<CJK Ideograph>) 1245 0x569C 嚜 (<CJK Ideograph>) 1246 0x569D 嚝 (<CJK Ideograph>) 1247 0x569E 嚞 (<CJK Ideograph>) 1248 0x569F 嚟 (<CJK Ideograph>) 1249 0x56A0 嚠 (<CJK Ideograph>) 1250 0x56A1 嚡 (<CJK Ideograph>) 1251 0x56A2 嚢 (<CJK Ideograph>) 1252 0x56A4 嚤 (<CJK Ideograph>) 1253 0x56A5 嚥 (<CJK Ideograph>) 1254 0x56A6 嚦 (<CJK Ideograph>) 1255 0x56A7 嚧 (<CJK Ideograph>) 1256 0x56A8 嚨 (<CJK Ideograph>) 1257 0x56A9 嚩 (<CJK Ideograph>) 1258 0x56AA 嚪 (<CJK Ideograph>) 1259 0x56AB 嚫 (<CJK Ideograph>) 1260 0x56AC 嚬 (<CJK Ideograph>) 1261 0x56AD 嚭 (<CJK Ideograph>) 1262 0x56AE 嚮 (<CJK Ideograph>) 1263 0x56B0 嚰 (<CJK Ideograph>) 1264 0x56B1 嚱 (<CJK Ideograph>) 1265 0x56B2 嚲 (<CJK Ideograph>) 1266 0x56B3 嚳 (<CJK Ideograph>) 1267 0x56B4 嚴 (<CJK Ideograph>) 1268 0x56B5 嚵 (<CJK Ideograph>) 1269 0x56B6 嚶 (<CJK Ideograph>) 1270 0x56B8 嚸 (<CJK Ideograph>) 1271 0x56B9 嚹 (<CJK Ideograph>) 1272 0x56BA 嚺 (<CJK Ideograph>) 1273 0x56BB 嚻 (<CJK Ideograph>) 1274 0x56BD 嚽 (<CJK Ideograph>) 1275 0x56BE 嚾 (<CJK Ideograph>) 1276 0x56BF 嚿 (<CJK Ideograph>) 1277 0x56C0 囀 (<CJK Ideograph>) 1278 0x56C1 囁 (<CJK Ideograph>) 1279 0x56C2 囂 (<CJK Ideograph>) 1280 0x56C3 囃 (<CJK Ideograph>) 1281 0x56C4 囄 (<CJK Ideograph>) 1282 0x56C5 囅 (<CJK Ideograph>) 1283 0x56C6 囆 (<CJK Ideograph>) 1284 0x56C7 囇 (<CJK Ideograph>) 1285 0x56C8 囈 (<CJK Ideograph>) 1286 0x56C9 囉 (<CJK Ideograph>) 1287 0x56CB 囋 (<CJK Ideograph>) 1288 0x56CC 囌 (<CJK Ideograph>) 1289 0x56CD 囍 (<CJK Ideograph>) 1290 0x56CE 囎 (<CJK Ideograph>) 1291 0x56CF 囏 (<CJK Ideograph>) 1292 0x56D0 囐 (<CJK Ideograph>) 1293 0x56D1 囑 (<CJK Ideograph>) 1294 0x56D2 囒 (<CJK Ideograph>) 1295 0x56D3 囓 (<CJK Ideograph>) 1296 0x56D5 囕 (<CJK Ideograph>) 1297 0x56D6 囖 (<CJK Ideograph>) 1298 0x56D8 囘 (<CJK Ideograph>) 1299 0x56D9 囙 (<CJK Ideograph>) 1300 0x56DC 囜 (<CJK Ideograph>) 1301 0x56E3 団 (<CJK Ideograph>) 1302 0x56E5 囥 (<CJK Ideograph>) 1303 0x56E6 囦 (<CJK Ideograph>) 1304 0x56E7 囧 (<CJK Ideograph>) 1305 0x56E8 囨 (<CJK Ideograph>) 1306 0x56E9 囩 (<CJK Ideograph>) 1307 0x56EA 囪 (<CJK Ideograph>) 1308 0x56EC 囬 (<CJK Ideograph>) 1309 0x56EE 囮 (<CJK Ideograph>) 1310 0x56EF 囯 (<CJK Ideograph>) 1311 0x56F2 囲 (<CJK Ideograph>) 1312 0x56F3 図 (<CJK Ideograph>) 1313 0x56F6 囶 (<CJK Ideograph>) 1314 0x56F7 囷 (<CJK Ideograph>) 1315 0x56F8 囸 (<CJK Ideograph>) 1316 0x56FB 囻 (<CJK Ideograph>) 1317 0x56FC 囼 (<CJK Ideograph>) 1318 0x5700 圀 (<CJK Ideograph>) 1319 0x5701 圁 (<CJK Ideograph>) 1320 0x5702 圂 (<CJK Ideograph>) 1321 0x5705 圅 (<CJK Ideograph>) 1322 0x5707 圇 (<CJK Ideograph>) 1323 0x570B 國 (<CJK Ideograph>) 1324 0x570C 圌 (<CJK Ideograph>) 1325 0x570D 圍 (<CJK Ideograph>) 1326 0x570E 圎 (<CJK Ideograph>) 1327 0x570F 圏 (<CJK Ideograph>) 1328 0x5710 圐 (<CJK Ideograph>) 1329 0x5711 圑 (<CJK Ideograph>) 1330 0x5712 園 (<CJK Ideograph>) 1331 0x5713 圓 (<CJK Ideograph>) 1332 0x5714 圔 (<CJK Ideograph>) 1333 0x5715 圕 (<CJK Ideograph>) 1334 0x5716 圖 (<CJK Ideograph>) 1335 0x5717 圗 (<CJK Ideograph>) 1336 0x5718 團 (<CJK Ideograph>) 1337 0x5719 圙 (<CJK Ideograph>) 1338 0x571A 圚 (<CJK Ideograph>) 1339 0x571B 圛 (<CJK Ideograph>) 1340 0x571D 圝 (<CJK Ideograph>) 1341 0x571E 圞 (<CJK Ideograph>) 1342 0x5720 圠 (<CJK Ideograph>) 1343 0x5721 圡 (<CJK Ideograph>) 1344 0x5722 圢 (<CJK Ideograph>) 1345 0x5724 圤 (<CJK Ideograph>) 1346 0x5725 圥 (<CJK Ideograph>) 1347 0x5726 圦 (<CJK Ideograph>) 1348 0x5727 圧 (<CJK Ideograph>) 1349 0x572B 圫 (<CJK Ideograph>) 1350 0x5731 圱 (<CJK Ideograph>) 1351 0x5732 圲 (<CJK Ideograph>) 1352 0x5734 圴 (<CJK Ideograph>) 1353 0x5735 圵 (<CJK Ideograph>) 1354 0x5736 圶 (<CJK Ideograph>) 1355 0x5737 圷 (<CJK Ideograph>) 1356 0x5738 圸 (<CJK Ideograph>) 1357 0x573C 圼 (<CJK Ideograph>) 1358 0x573D 圽 (<CJK Ideograph>) 1359 0x573F 圿 (<CJK Ideograph>) 1360 0x5741 坁 (<CJK Ideograph>) 1361 0x5743 坃 (<CJK Ideograph>) 1362 0x5744 坄 (<CJK Ideograph>) 1363 0x5745 坅 (<CJK Ideograph>) 1364 0x5746 坆 (<CJK Ideograph>) 1365 0x5748 坈 (<CJK Ideograph>) 1366 0x5749 坉 (<CJK Ideograph>) 1367 0x574B 坋 (<CJK Ideograph>) 1368 0x5752 坒 (<CJK Ideograph>) 1369 0x5753 坓 (<CJK Ideograph>) 1370 0x5754 坔 (<CJK Ideograph>) 1371 0x5755 坕 (<CJK Ideograph>) 1372 0x5756 坖 (<CJK Ideograph>) 1373 0x5758 坘 (<CJK Ideograph>) 1374 0x5759 坙 (<CJK Ideograph>) 1375 0x5762 坢 (<CJK Ideograph>) 1376 0x5763 坣 (<CJK Ideograph>) 1377 0x5765 坥 (<CJK Ideograph>) 1378 0x5767 坧 (<CJK Ideograph>) 1379 0x576C 坬 (<CJK Ideograph>) 1380 0x576E 坮 (<CJK Ideograph>) 1381 0x5770 坰 (<CJK Ideograph>) 1382 0x5771 坱 (<CJK Ideograph>) 1383 0x5772 坲 (<CJK Ideograph>) 1384 0x5774 坴 (<CJK Ideograph>) 1385 0x5775 坵 (<CJK Ideograph>) 1386 0x5778 坸 (<CJK Ideograph>) 1387 0x5779 坹 (<CJK Ideograph>) 1388 0x577A 坺 (<CJK Ideograph>) 1389 0x577D 坽 (<CJK Ideograph>) 1390 0x577E 坾 (<CJK Ideograph>) 1391 0x577F 坿 (<CJK Ideograph>) 1392 0x5780 垀 (<CJK Ideograph>) 1393 0x5781 垁 (<CJK Ideograph>) 1394 0x5787 垇 (<CJK Ideograph>) 1395 0x5788 垈 (<CJK Ideograph>) 1396 0x5789 垉 (<CJK Ideograph>) 1397 0x578A 垊 (<CJK Ideograph>) 1398 0x578D 垍 (<CJK Ideograph>) 1399 0x578E 垎 (<CJK Ideograph>) 1400 0x578F 垏 (<CJK Ideograph>) 1401 0x5790 垐 (<CJK Ideograph>) 1402 0x5791 垑 (<CJK Ideograph>) 1403 0x5794 垔 (<CJK Ideograph>) 1404 0x5795 垕 (<CJK Ideograph>) 1405 0x5796 垖 (<CJK Ideograph>) 1406 0x5797 垗 (<CJK Ideograph>) 1407 0x5798 垘 (<CJK Ideograph>) 1408 0x5799 垙 (<CJK Ideograph>) 1409 0x579A 垚 (<CJK Ideograph>) 1410 0x579C 垜 (<CJK Ideograph>) 1411 0x579D 垝 (<CJK Ideograph>) 1412 0x579E 垞 (<CJK Ideograph>) 1413 0x579F 垟 (<CJK Ideograph>) 1414 0x57A5 垥 (<CJK Ideograph>) 1415 0x57A8 垨 (<CJK Ideograph>) 1416 0x57AA 垪 (<CJK Ideograph>) 1417 0x57AC 垬 (<CJK Ideograph>) 1418 0x57AF 垯 (<CJK Ideograph>) 1419 0x57B0 垰 (<CJK Ideograph>) 1420 0x57B1 垱 (<CJK Ideograph>) 1421 0x57B3 垳 (<CJK Ideograph>) 1422 0x57B5 垵 (<CJK Ideograph>) 1423 0x57B6 垶 (<CJK Ideograph>) 1424 0x57B7 垷 (<CJK Ideograph>) 1425 0x57B9 垹 (<CJK Ideograph>) 1426 0x57BA 垺 (<CJK Ideograph>) 1427 0x57BB 垻 (<CJK Ideograph>) 1428 0x57BC 垼 (<CJK Ideograph>) 1429 0x57BD 垽 (<CJK Ideograph>) 1430 0x57BE 垾 (<CJK Ideograph>) 1431 0x57BF 垿 (<CJK Ideograph>) 1432 0x57C0 埀 (<CJK Ideograph>) 1433 0x57C1 埁 (<CJK Ideograph>) 1434 0x57C4 埄 (<CJK Ideograph>) 1435 0x57C5 埅 (<CJK Ideograph>) 1436 0x57C6 埆 (<CJK Ideograph>) 1437 0x57C7 埇 (<CJK Ideograph>) 1438 0x57C8 埈 (<CJK Ideograph>) 1439 0x57C9 埉 (<CJK Ideograph>) 1440 0x57CA 埊 (<CJK Ideograph>) 1441 0x57CC 埌 (<CJK Ideograph>) 1442 0x57CD 埍 (<CJK Ideograph>) 1443 0x57D0 埐 (<CJK Ideograph>) 1444 0x57D1 埑 (<CJK Ideograph>) 1445 0x57D3 埓 (<CJK Ideograph>) 1446 0x57D6 埖 (<CJK Ideograph>) 1447 0x57D7 埗 (<CJK Ideograph>) 1448 0x57DB 埛 (<CJK Ideograph>) 1449 0x57DC 埜 (<CJK Ideograph>) 1450 0x57DE 埞 (<CJK Ideograph>) 1451 0x57E1 埡 (<CJK Ideograph>) 1452 0x57E2 埢 (<CJK Ideograph>) 1453 0x57E3 埣 (<CJK Ideograph>) 1454 0x57E5 埥 (<CJK Ideograph>) 1455 0x57E6 埦 (<CJK Ideograph>) 1456 0x57E7 埧 (<CJK Ideograph>) 1457 0x57E8 埨 (<CJK Ideograph>) 1458 0x57E9 埩 (<CJK Ideograph>) 1459 0x57EA 埪 (<CJK Ideograph>) 1460 0x57EB 埫 (<CJK Ideograph>) 1461 0x57EC 埬 (<CJK Ideograph>) 1462 0x57EE 埮 (<CJK Ideograph>) 1463 0x57F0 埰 (<CJK Ideograph>) 1464 0x57F1 埱 (<CJK Ideograph>) 1465 0x57F2 埲 (<CJK Ideograph>) 1466 0x57F3 埳 (<CJK Ideograph>) 1467 0x57F5 埵 (<CJK Ideograph>) 1468 0x57F6 埶 (<CJK Ideograph>) 1469 0x57F7 執 (<CJK Ideograph>) 1470 0x57FB 埻 (<CJK Ideograph>) 1471 0x57FC 埼 (<CJK Ideograph>) 1472 0x57FE 埾 (<CJK Ideograph>) 1473 0x57FF 埿 (<CJK Ideograph>) 1474 0x5801 堁 (<CJK Ideograph>) 1475 0x5803 堃 (<CJK Ideograph>) 1476 0x5804 堄 (<CJK Ideograph>) 1477 0x5805 堅 (<CJK Ideograph>) 1478 0x5808 堈 (<CJK Ideograph>) 1479 0x5809 堉 (<CJK Ideograph>) 1480 0x580A 堊 (<CJK Ideograph>) 1481 0x580C 堌 (<CJK Ideograph>) 1482 0x580E 堎 (<CJK Ideograph>) 1483 0x580F 堏 (<CJK Ideograph>) 1484 0x5810 堐 (<CJK Ideograph>) 1485 0x5812 堒 (<CJK Ideograph>) 1486 0x5813 堓 (<CJK Ideograph>) 1487 0x5814 堔 (<CJK Ideograph>) 1488 0x5816 堖 (<CJK Ideograph>) 1489 0x5817 堗 (<CJK Ideograph>) 1490 0x5818 堘 (<CJK Ideograph>) 1491 0x581A 堚 (<CJK Ideograph>) 1492 0x581B 堛 (<CJK Ideograph>) 1493 0x581C 堜 (<CJK Ideograph>) 1494 0x581D 堝 (<CJK Ideograph>) 1495 0x581F 堟 (<CJK Ideograph>) 1496 0x5822 堢 (<CJK Ideograph>) 1497 0x5823 堣 (<CJK Ideograph>) 1498 0x5825 堥 (<CJK Ideograph>) 1499 0x5826 堦 (<CJK Ideograph>) 1500 0x5827 堧 (<CJK Ideograph>) 1501 0x5828 堨 (<CJK Ideograph>) 1502 0x5829 堩 (<CJK Ideograph>) 1503 0x582B 堫 (<CJK Ideograph>) 1504 0x582C 堬 (<CJK Ideograph>) 1505 0x582D 堭 (<CJK Ideograph>) 1506 0x582E 堮 (<CJK Ideograph>) 1507 0x582F 堯 (<CJK Ideograph>) 1508 0x5831 報 (<CJK Ideograph>) 1509 0x5832 堲 (<CJK Ideograph>) 1510 0x5833 堳 (<CJK Ideograph>) 1511 0x5834 場 (<CJK Ideograph>) 1512 0x5836 堶 (<CJK Ideograph>) 1513 0x5837 堷 (<CJK Ideograph>) 1514 0x5838 堸 (<CJK Ideograph>) 1515 0x5839 堹 (<CJK Ideograph>) 1516 0x583A 堺 (<CJK Ideograph>) 1517 0x583B 堻 (<CJK Ideograph>) 1518 0x583C 堼 (<CJK Ideograph>) 1519 0x583D 堽 (<CJK Ideograph>) 1520 0x583E 堾 (<CJK Ideograph>) 1521 0x583F 堿 (<CJK Ideograph>) 1522 0x5840 塀 (<CJK Ideograph>) 1523 0x5841 塁 (<CJK Ideograph>) 1524 0x5842 塂 (<CJK Ideograph>) 1525 0x5843 塃 (<CJK Ideograph>) 1526 0x5845 塅 (<CJK Ideograph>) 1527 0x5846 塆 (<CJK Ideograph>) 1528 0x5847 塇 (<CJK Ideograph>) 1529 0x5848 塈 (<CJK Ideograph>) 1530 0x5849 塉 (<CJK Ideograph>) 1531 0x584A 塊 (<CJK Ideograph>) 1532 0x584B 塋 (<CJK Ideograph>) 1533 0x584E 塎 (<CJK Ideograph>) 1534 0x584F 塏 (<CJK Ideograph>) 1535 0x5850 塐 (<CJK Ideograph>) 1536 0x5852 塒 (<CJK Ideograph>) 1537 0x5853 塓 (<CJK Ideograph>) 1538 0x5855 塕 (<CJK Ideograph>) 1539 0x5856 塖 (<CJK Ideograph>) 1540 0x5857 塗 (<CJK Ideograph>) 1541 0x5859 塙 (<CJK Ideograph>) 1542 0x585A 塚 (<CJK Ideograph>) 1543 0x585B 塛 (<CJK Ideograph>) 1544 0x585C 塜 (<CJK Ideograph>) 1545 0x585D 塝 (<CJK Ideograph>) 1546 0x585F 塟 (<CJK Ideograph>) 1547 0x5860 塠 (<CJK Ideograph>) 1548 0x5861 塡 (<CJK Ideograph>) 1549 0x5862 塢 (<CJK Ideograph>) 1550 0x5863 塣 (<CJK Ideograph>) 1551 0x5864 塤 (<CJK Ideograph>) 1552 0x5866 塦 (<CJK Ideograph>) 1553 0x5867 塧 (<CJK Ideograph>) 1554 0x5868 塨 (<CJK Ideograph>) 1555 0x5869 塩 (<CJK Ideograph>) 1556 0x586A 塪 (<CJK Ideograph>) 1557 0x586D 塭 (<CJK Ideograph>) 1558 0x586E 塮 (<CJK Ideograph>) 1559 0x586F 塯 (<CJK Ideograph>) 1560 0x5870 塰 (<CJK Ideograph>) 1561 0x5871 塱 (<CJK Ideograph>) 1562 0x5872 塲 (<CJK Ideograph>) 1563 0x5873 塳 (<CJK Ideograph>) 1564 0x5874 塴 (<CJK Ideograph>) 1565 0x5875 塵 (<CJK Ideograph>) 1566 0x5876 塶 (<CJK Ideograph>) 1567 0x5877 塷 (<CJK Ideograph>) 1568 0x5878 塸 (<CJK Ideograph>) 1569 0x5879 塹 (<CJK Ideograph>) 1570 0x587A 塺 (<CJK Ideograph>) 1571 0x587B 塻 (<CJK Ideograph>) 1572 0x587C 塼 (<CJK Ideograph>) 1573 0x587D 塽 (<CJK Ideograph>) 1574 0x587F 塿 (<CJK Ideograph>) 1575 0x5882 墂 (<CJK Ideograph>) 1576 0x5884 墄 (<CJK Ideograph>) 1577 0x5886 墆 (<CJK Ideograph>) 1578 0x5887 墇 (<CJK Ideograph>) 1579 0x5888 墈 (<CJK Ideograph>) 1580 0x588A 墊 (<CJK Ideograph>) 1581 0x588B 墋 (<CJK Ideograph>) 1582 0x588C 墌 (<CJK Ideograph>) 1583 0x588D 墍 (<CJK Ideograph>) 1584 0x588E 墎 (<CJK Ideograph>) 1585 0x588F 墏 (<CJK Ideograph>) 1586 0x5890 墐 (<CJK Ideograph>) 1587 0x5891 墑 (<CJK Ideograph>) 1588 0x5894 墔 (<CJK Ideograph>) 1589 0x5895 墕 (<CJK Ideograph>) 1590 0x5896 墖 (<CJK Ideograph>) 1591 0x5897 増 (<CJK Ideograph>) 1592 0x5898 墘 (<CJK Ideograph>) 1593 0x589B 墛 (<CJK Ideograph>) 1594 0x589C 墜 (<CJK Ideograph>) 1595 0x589D 墝 (<CJK Ideograph>) 1596 0x58A0 墠 (<CJK Ideograph>) 1597 0x58A1 墡 (<CJK Ideograph>) 1598 0x58A2 墢 (<CJK Ideograph>) 1599 0x58A3 墣 (<CJK Ideograph>) 1600 0x58A4 墤 (<CJK Ideograph>) 1601 0x58A5 墥 (<CJK Ideograph>) 1602 0x58A6 墦 (<CJK Ideograph>) 1603 0x58A7 墧 (<CJK Ideograph>) 1604 0x58AA 墪 (<CJK Ideograph>) 1605 0x58AB 墫 (<CJK Ideograph>) 1606 0x58AC 墬 (<CJK Ideograph>) 1607 0x58AD 墭 (<CJK Ideograph>) 1608 0x58AE 墮 (<CJK Ideograph>) 1609 0x58AF 墯 (<CJK Ideograph>) 1610 0x58B0 墰 (<CJK Ideograph>) 1611 0x58B1 墱 (<CJK Ideograph>) 1612 0x58B2 墲 (<CJK Ideograph>) 1613 0x58B3 墳 (<CJK Ideograph>) 1614 0x58B4 墴 (<CJK Ideograph>) 1615 0x58B5 墵 (<CJK Ideograph>) 1616 0x58B6 墶 (<CJK Ideograph>) 1617 0x58B7 墷 (<CJK Ideograph>) 1618 0x58B8 墸 (<CJK Ideograph>) 1619 0x58B9 墹 (<CJK Ideograph>) 1620 0x58BA 墺 (<CJK Ideograph>) 1621 0x58BB 墻 (<CJK Ideograph>) 1622 0x58BD 墽 (<CJK Ideograph>) 1623 0x58BE 墾 (<CJK Ideograph>) 1624 0x58BF 墿 (<CJK Ideograph>) 1625 0x58C0 壀 (<CJK Ideograph>) 1626 0x58C2 壂 (<CJK Ideograph>) 1627 0x58C3 壃 (<CJK Ideograph>) 1628 0x58C4 壄 (<CJK Ideograph>) 1629 0x58C6 壆 (<CJK Ideograph>) 1630 0x58C7 壇 (<CJK Ideograph>) 1631 0x58C8 壈 (<CJK Ideograph>) 1632 0x58C9 壉 (<CJK Ideograph>) 1633 0x58CA 壊 (<CJK Ideograph>) 1634 0x58CB 壋 (<CJK Ideograph>) 1635 0x58CC 壌 (<CJK Ideograph>) 1636 0x58CD 壍 (<CJK Ideograph>) 1637 0x58CE 壎 (<CJK Ideograph>) 1638 0x58CF 壏 (<CJK Ideograph>) 1639 0x58D0 壐 (<CJK Ideograph>) 1640 0x58D2 壒 (<CJK Ideograph>) 1641 0x58D3 壓 (<CJK Ideograph>) 1642 0x58D4 壔 (<CJK Ideograph>) 1643 0x58D6 壖 (<CJK Ideograph>) 1644 0x58D7 壗 (<CJK Ideograph>) 1645 0x58D8 壘 (<CJK Ideograph>) 1646 0x58D9 壙 (<CJK Ideograph>) 1647 0x58DA 壚 (<CJK Ideograph>) 1648 0x58DB 壛 (<CJK Ideograph>) 1649 0x58DC 壜 (<CJK Ideograph>) 1650 0x58DD 壝 (<CJK Ideograph>) 1651 0x58DE 壞 (<CJK Ideograph>) 1652 0x58DF 壟 (<CJK Ideograph>) 1653 0x58E0 壠 (<CJK Ideograph>) 1654 0x58E1 壡 (<CJK Ideograph>) 1655 0x58E2 壢 (<CJK Ideograph>) 1656 0x58E3 壣 (<CJK Ideograph>) 1657 0x58E5 壥 (<CJK Ideograph>) 1658 0x58E6 壦 (<CJK Ideograph>) 1659 0x58E7 壧 (<CJK Ideograph>) 1660 0x58E8 壨 (<CJK Ideograph>) 1661 0x58E9 壩 (<CJK Ideograph>) 1662 0x58EA 壪 (<CJK Ideograph>) 1663 0x58ED 壭 (<CJK Ideograph>) 1664 0x58EF 壯 (<CJK Ideograph>) 1665 0x58F1 壱 (<CJK Ideograph>) 1666 0x58F2 売 (<CJK Ideograph>) 1667 0x58F4 壴 (<CJK Ideograph>) 1668 0x58F5 壵 (<CJK Ideograph>) 1669 0x58F7 壷 (<CJK Ideograph>) 1670 0x58F8 壸 (<CJK Ideograph>) 1671 0x58FA 壺 (<CJK Ideograph>) 1672 0x58FB 壻 (<CJK Ideograph>) 1673 0x58FC 壼 (<CJK Ideograph>) 1674 0x58FD 壽 (<CJK Ideograph>) 1675 0x58FE 壾 (<CJK Ideograph>) 1676 0x58FF 壿 (<CJK Ideograph>) 1677 0x5900 夀 (<CJK Ideograph>) 1678 0x5901 夁 (<CJK Ideograph>) 1679 0x5903 夃 (<CJK Ideograph>) 1680 0x5905 夅 (<CJK Ideograph>) 1681 0x5906 夆 (<CJK Ideograph>) 1682 0x5908 夈 (<CJK Ideograph>) 1683 0x5909 変 (<CJK Ideograph>) 1684 0x590A 夊 (<CJK Ideograph>) 1685 0x590B 夋 (<CJK Ideograph>) 1686 0x590C 夌 (<CJK Ideograph>) 1687 0x590E 夎 (<CJK Ideograph>) 1688 0x5910 夐 (<CJK Ideograph>) 1689 0x5911 夑 (<CJK Ideograph>) 1690 0x5912 夒 (<CJK Ideograph>) 1691 0x5913 夓 (<CJK Ideograph>) 1692 0x5917 夗 (<CJK Ideograph>) 1693 0x5918 夘 (<CJK Ideograph>) 1694 0x591B 夛 (<CJK Ideograph>) 1695 0x591D 夝 (<CJK Ideograph>) 1696 0x591E 夞 (<CJK Ideograph>) 1697 0x5920 夠 (<CJK Ideograph>) 1698 0x5921 夡 (<CJK Ideograph>) 1699 0x5922 夢 (<CJK Ideograph>) 1700 0x5923 夣 (<CJK Ideograph>) 1701 0x5926 夦 (<CJK Ideograph>) 1702 0x5928 夨 (<CJK Ideograph>) 1703 0x592C 夬 (<CJK Ideograph>) 1704 0x5930 夰 (<CJK Ideograph>) 1705 0x5932 夲 (<CJK Ideograph>) 1706 0x5933 夳 (<CJK Ideograph>) 1707 0x5935 夵 (<CJK Ideograph>) 1708 0x5936 夶 (<CJK Ideograph>) 1709 0x593B 夻 (<CJK Ideograph>) 1710 0x593D 夽 (<CJK Ideograph>) 1711 0x593E 夾 (<CJK Ideograph>) 1712 0x593F 夿 (<CJK Ideograph>) 1713 0x5940 奀 (<CJK Ideograph>) 1714 0x5943 奃 (<CJK Ideograph>) 1715 0x5945 奅 (<CJK Ideograph>) 1716 0x5946 奆 (<CJK Ideograph>) 1717 0x594A 奊 (<CJK Ideograph>) 1718 0x594C 奌 (<CJK Ideograph>) 1719 0x594D 奍 (<CJK Ideograph>) 1720 0x5950 奐 (<CJK Ideograph>) 1721 0x5952 奒 (<CJK Ideograph>) 1722 0x5953 奓 (<CJK Ideograph>) 1723 0x5959 奙 (<CJK Ideograph>) 1724 0x595B 奛 (<CJK Ideograph>) 1725 0x595C 奜 (<CJK Ideograph>) 1726 0x595D 奝 (<CJK Ideograph>) 1727 0x595E 奞 (<CJK Ideograph>) 1728 0x595F 奟 (<CJK Ideograph>) 1729 0x5961 奡 (<CJK Ideograph>) 1730 0x5963 奣 (<CJK Ideograph>) 1731 0x5964 奤 (<CJK Ideograph>) 1732 0x5966 奦 (<CJK Ideograph>) 1733 0x5967 奧 (<CJK Ideograph>) 1734 0x5968 奨 (<CJK Ideograph>) 1735 0x5969 奩 (<CJK Ideograph>) 1736 0x596A 奪 (<CJK Ideograph>) 1737 0x596B 奫 (<CJK Ideograph>) 1738 0x596C 奬 (<CJK Ideograph>) 1739 0x596D 奭 (<CJK Ideograph>) 1740 0x596E 奮 (<CJK Ideograph>) 1741 0x596F 奯 (<CJK Ideograph>) 1742 0x5970 奰 (<CJK Ideograph>) 1743 0x5971 奱 (<CJK Ideograph>) 1744 0x5972 奲 (<CJK Ideograph>) 1745 0x5975 奵 (<CJK Ideograph>) 1746 0x5977 奷 (<CJK Ideograph>) 1747 0x597A 奺 (<CJK Ideograph>) 1748 0x597B 奻 (<CJK Ideograph>) 1749 0x597C 奼 (<CJK Ideograph>) 1750 0x597E 奾 (<CJK Ideograph>) 1751 0x597F 奿 (<CJK Ideograph>) 1752 0x5980 妀 (<CJK Ideograph>) 1753 0x5985 妅 (<CJK Ideograph>) 1754 0x5989 妉 (<CJK Ideograph>) 1755 0x598B 妋 (<CJK Ideograph>) 1756 0x598C 妌 (<CJK Ideograph>) 1757 0x598E 妎 (<CJK Ideograph>) 1758 0x598F 妏 (<CJK Ideograph>) 1759 0x5990 妐 (<CJK Ideograph>) 1760 0x5991 妑 (<CJK Ideograph>) 1761 0x5994 妔 (<CJK Ideograph>) 1762 0x5995 妕 (<CJK Ideograph>) 1763 0x5998 妘 (<CJK Ideograph>) 1764 0x599A 妚 (<CJK Ideograph>) 1765 0x599B 妛 (<CJK Ideograph>) 1766 0x599C 妜 (<CJK Ideograph>) 1767 0x599D 妝 (<CJK Ideograph>) 1768 0x599F 妟 (<CJK Ideograph>) 1769 0x59A0 妠 (<CJK Ideograph>) 1770 0x59A1 妡 (<CJK Ideograph>) 1771 0x59A2 妢 (<CJK Ideograph>) 1772 0x59A6 妦 (<CJK Ideograph>) 1773 0x59A7 妧 (<CJK Ideograph>) 1774 0x59AC 妬 (<CJK Ideograph>) 1775 0x59AD 妭 (<CJK Ideograph>) 1776 0x59B0 妰 (<CJK Ideograph>) 1777 0x59B1 妱 (<CJK Ideograph>) 1778 0x59B3 妳 (<CJK Ideograph>) 1779 0x59B4 妴 (<CJK Ideograph>) 1780 0x59B5 妵 (<CJK Ideograph>) 1781 0x59B6 妶 (<CJK Ideograph>) 1782 0x59B7 妷 (<CJK Ideograph>) 1783 0x59B8 妸 (<CJK Ideograph>) 1784 0x59BA 妺 (<CJK Ideograph>) 1785 0x59BC 妼 (<CJK Ideograph>) 1786 0x59BD 妽 (<CJK Ideograph>) 1787 0x59BF 妿 (<CJK Ideograph>) 1788 0x59C0 姀 (<CJK Ideograph>) 1789 0x59C1 姁 (<CJK Ideograph>) 1790 0x59C2 姂 (<CJK Ideograph>) 1791 0x59C3 姃 (<CJK Ideograph>) 1792 0x59C4 姄 (<CJK Ideograph>) 1793 0x59C5 姅 (<CJK Ideograph>) 1794 0x59C7 姇 (<CJK Ideograph>) 1795 0x59C8 姈 (<CJK Ideograph>) 1796 0x59C9 姉 (<CJK Ideograph>) 1797 0x59CC 姌 (<CJK Ideograph>) 1798 0x59CD 姍 (<CJK Ideograph>) 1799 0x59CE 姎 (<CJK Ideograph>) 1800 0x59CF 姏 (<CJK Ideograph>) 1801 0x59D5 姕 (<CJK Ideograph>) 1802 0x59D6 姖 (<CJK Ideograph>) 1803 0x59D9 姙 (<CJK Ideograph>) 1804 0x59DB 姛 (<CJK Ideograph>) 1805 0x59DE 姞 (<CJK Ideograph>) 1806 0x59DF 姟 (<CJK Ideograph>) 1807 0x59E0 姠 (<CJK Ideograph>) 1808 0x59E1 姡 (<CJK Ideograph>) 1809 0x59E2 姢 (<CJK Ideograph>) 1810 0x59E4 姤 (<CJK Ideograph>) 1811 0x59E6 姦 (<CJK Ideograph>) 1812 0x59E7 姧 (<CJK Ideograph>) 1813 0x59E9 姩 (<CJK Ideograph>) 1814 0x59EA 姪 (<CJK Ideograph>) 1815 0x59EB 姫 (<CJK Ideograph>) 1816 0x59ED 姭 (<CJK Ideograph>) 1817 0x59EE 姮 (<CJK Ideograph>) 1818 0x59EF 姯 (<CJK Ideograph>) 1819 0x59F0 姰 (<CJK Ideograph>) 1820 0x59F1 姱 (<CJK Ideograph>) 1821 0x59F2 姲 (<CJK Ideograph>) 1822 0x59F3 姳 (<CJK Ideograph>) 1823 0x59F4 姴 (<CJK Ideograph>) 1824 0x59F5 姵 (<CJK Ideograph>) 1825 0x59F6 姶 (<CJK Ideograph>) 1826 0x59F7 姷 (<CJK Ideograph>) 1827 0x59F8 姸 (<CJK Ideograph>) 1828 0x59FA 姺 (<CJK Ideograph>) 1829 0x59FC 姼 (<CJK Ideograph>) 1830 0x59FD 姽 (<CJK Ideograph>) 1831 0x59FE 姾 (<CJK Ideograph>) 1832 0x5A00 娀 (<CJK Ideograph>) 1833 0x5A02 娂 (<CJK Ideograph>) 1834 0x5A0A 娊 (<CJK Ideograph>) 1835 0x5A0B 娋 (<CJK Ideograph>) 1836 0x5A0D 娍 (<CJK Ideograph>) 1837 0x5A0E 娎 (<CJK Ideograph>) 1838 0x5A0F 娏 (<CJK Ideograph>) 1839 0x5A10 娐 (<CJK Ideograph>) 1840 0x5A12 娒 (<CJK Ideograph>) 1841 0x5A14 娔 (<CJK Ideograph>) 1842 0x5A15 娕 (<CJK Ideograph>) 1843 0x5A16 娖 (<CJK Ideograph>) 1844 0x5A17 娗 (<CJK Ideograph>) 1845 0x5A19 娙 (<CJK Ideograph>) 1846 0x5A1A 娚 (<CJK Ideograph>) 1847 0x5A1B 娛 (<CJK Ideograph>) 1848 0x5A1D 娝 (<CJK Ideograph>) 1849 0x5A1E 娞 (<CJK Ideograph>) 1850 0x5A21 娡 (<CJK Ideograph>) 1851 0x5A22 娢 (<CJK Ideograph>) 1852 0x5A24 娤 (<CJK Ideograph>) 1853 0x5A26 娦 (<CJK Ideograph>) 1854 0x5A27 娧 (<CJK Ideograph>) 1855 0x5A28 娨 (<CJK Ideograph>) 1856 0x5A2A 娪 (<CJK Ideograph>) 1857 0x5A2B 娫 (<CJK Ideograph>) 1858 0x5A2C 娬 (<CJK Ideograph>) 1859 0x5A2D 娭 (<CJK Ideograph>) 1860 0x5A2E 娮 (<CJK Ideograph>) 1861 0x5A2F 娯 (<CJK Ideograph>) 1862 0x5A30 娰 (<CJK Ideograph>) 1863 0x5A33 娳 (<CJK Ideograph>) 1864 0x5A35 娵 (<CJK Ideograph>) 1865 0x5A37 娷 (<CJK Ideograph>) 1866 0x5A38 娸 (<CJK Ideograph>) 1867 0x5A39 娹 (<CJK Ideograph>) 1868 0x5A3A 娺 (<CJK Ideograph>) 1869 0x5A3B 娻 (<CJK Ideograph>) 1870 0x5A3D 娽 (<CJK Ideograph>) 1871 0x5A3E 娾 (<CJK Ideograph>) 1872 0x5A3F 娿 (<CJK Ideograph>) 1873 0x5A41 婁 (<CJK Ideograph>) 1874 0x5A42 婂 (<CJK Ideograph>) 1875 0x5A43 婃 (<CJK Ideograph>) 1876 0x5A44 婄 (<CJK Ideograph>) 1877 0x5A45 婅 (<CJK Ideograph>) 1878 0x5A47 婇 (<CJK Ideograph>) 1879 0x5A48 婈 (<CJK Ideograph>) 1880 0x5A4B 婋 (<CJK Ideograph>) 1881 0x5A4C 婌 (<CJK Ideograph>) 1882 0x5A4D 婍 (<CJK Ideograph>) 1883 0x5A4E 婎 (<CJK Ideograph>) 1884 0x5A4F 婏 (<CJK Ideograph>) 1885 0x5A50 婐 (<CJK Ideograph>) 1886 0x5A51 婑 (<CJK Ideograph>) 1887 0x5A52 婒 (<CJK Ideograph>) 1888 0x5A53 婓 (<CJK Ideograph>) 1889 0x5A54 婔 (<CJK Ideograph>) 1890 0x5A56 婖 (<CJK Ideograph>) 1891 0x5A57 婗 (<CJK Ideograph>) 1892 0x5A58 婘 (<CJK Ideograph>) 1893 0x5A59 婙 (<CJK Ideograph>) 1894 0x5A5B 婛 (<CJK Ideograph>) 1895 0x5A5C 婜 (<CJK Ideograph>) 1896 0x5A5D 婝 (<CJK Ideograph>) 1897 0x5A5E 婞 (<CJK Ideograph>) 1898 0x5A5F 婟 (<CJK Ideograph>) 1899 0x5A60 婠 (<CJK Ideograph>) 1900 0x5A61 婡 (<CJK Ideograph>) 1901 0x5A63 婣 (<CJK Ideograph>) 1902 0x5A64 婤 (<CJK Ideograph>) 1903 0x5A65 婥 (<CJK Ideograph>) 1904 0x5A66 婦 (<CJK Ideograph>) 1905 0x5A68 婨 (<CJK Ideograph>) 1906 0x5A69 婩 (<CJK Ideograph>) 1907 0x5A6B 婫 (<CJK Ideograph>) 1908 0x5A6C 婬 (<CJK Ideograph>) 1909 0x5A6D 婭 (<CJK Ideograph>) 1910 0x5A6E 婮 (<CJK Ideograph>) 1911 0x5A6F 婯 (<CJK Ideograph>) 1912 0x5A70 婰 (<CJK Ideograph>) 1913 0x5A71 婱 (<CJK Ideograph>) 1914 0x5A72 婲 (<CJK Ideograph>) 1915 0x5A73 婳 (<CJK Ideograph>) 1916 0x5A78 婸 (<CJK Ideograph>) 1917 0x5A79 婹 (<CJK Ideograph>) 1918 0x5A7B 婻 (<CJK Ideograph>) 1919 0x5A7C 婼 (<CJK Ideograph>) 1920 0x5A7D 婽 (<CJK Ideograph>) 1921 0x5A7E 婾 (<CJK Ideograph>) 1922 0x5A80 媀 (<CJK Ideograph>) 1923 0x5A81 媁 (<CJK Ideograph>) 1924 0x5A82 媂 (<CJK Ideograph>) 1925 0x5A83 媃 (<CJK Ideograph>) 1926 0x5A84 媄 (<CJK Ideograph>) 1927 0x5A85 媅 (<CJK Ideograph>) 1928 0x5A86 媆 (<CJK Ideograph>) 1929 0x5A87 媇 (<CJK Ideograph>) 1930 0x5A88 媈 (<CJK Ideograph>) 1931 0x5A89 媉 (<CJK Ideograph>) 1932 0x5A8A 媊 (<CJK Ideograph>) 1933 0x5A8B 媋 (<CJK Ideograph>) 1934 0x5A8C 媌 (<CJK Ideograph>) 1935 0x5A8D 媍 (<CJK Ideograph>) 1936 0x5A8E 媎 (<CJK Ideograph>) 1937 0x5A8F 媏 (<CJK Ideograph>) 1938 0x5A90 媐 (<CJK Ideograph>) 1939 0x5A91 媑 (<CJK Ideograph>) 1940 0x5A93 媓 (<CJK Ideograph>) 1941 0x5A94 媔 (<CJK Ideograph>) 1942 0x5A95 媕 (<CJK Ideograph>) 1943 0x5A96 媖 (<CJK Ideograph>) 1944 0x5A97 媗 (<CJK Ideograph>) 1945 0x5A98 媘 (<CJK Ideograph>) 1946 0x5A99 媙 (<CJK Ideograph>) 1947 0x5A9C 媜 (<CJK Ideograph>) 1948 0x5A9D 媝 (<CJK Ideograph>) 1949 0x5A9E 媞 (<CJK Ideograph>) 1950 0x5A9F 媟 (<CJK Ideograph>) 1951 0x5AA0 媠 (<CJK Ideograph>) 1952 0x5AA1 媡 (<CJK Ideograph>) 1953 0x5AA2 媢 (<CJK Ideograph>) 1954 0x5AA3 媣 (<CJK Ideograph>) 1955 0x5AA4 媤 (<CJK Ideograph>) 1956 0x5AA5 媥 (<CJK Ideograph>) 1957 0x5AA6 媦 (<CJK Ideograph>) 1958 0x5AA7 媧 (<CJK Ideograph>) 1959 0x5AA8 媨 (<CJK Ideograph>) 1960 0x5AA9 媩 (<CJK Ideograph>) 1961 0x5AAB 媫 (<CJK Ideograph>) 1962 0x5AAC 媬 (<CJK Ideograph>) 1963 0x5AAD 媭 (<CJK Ideograph>) 1964 0x5AAE 媮 (<CJK Ideograph>) 1965 0x5AAF 媯 (<CJK Ideograph>) 1966 0x5AB0 媰 (<CJK Ideograph>) 1967 0x5AB1 媱 (<CJK Ideograph>) 1968 0x5AB4 媴 (<CJK Ideograph>) 1969 0x5AB6 媶 (<CJK Ideograph>) 1970 0x5AB7 媷 (<CJK Ideograph>) 1971 0x5AB9 媹 (<CJK Ideograph>) 1972 0x5ABA 媺 (<CJK Ideograph>) 1973 0x5ABB 媻 (<CJK Ideograph>) 1974 0x5ABC 媼 (<CJK Ideograph>) 1975 0x5ABD 媽 (<CJK Ideograph>) 1976 0x5ABF 媿 (<CJK Ideograph>) 1977 0x5AC0 嫀 (<CJK Ideograph>) 1978 0x5AC3 嫃 (<CJK Ideograph>) 1979 0x5AC4 嫄 (<CJK Ideograph>) 1980 0x5AC5 嫅 (<CJK Ideograph>) 1981 0x5AC6 嫆 (<CJK Ideograph>) 1982 0x5AC7 嫇 (<CJK Ideograph>) 1983 0x5AC8 嫈 (<CJK Ideograph>) 1984 0x5ACA 嫊 (<CJK Ideograph>) 1985 0x5ACB 嫋 (<CJK Ideograph>) 1986 0x5ACD 嫍 (<CJK Ideograph>) 1987 0x5ACE 嫎 (<CJK Ideograph>) 1988 0x5ACF 嫏 (<CJK Ideograph>) 1989 0x5AD0 嫐 (<CJK Ideograph>) 1990 0x5AD1 嫑 (<CJK Ideograph>) 1991 0x5AD3 嫓 (<CJK Ideograph>) 1992 0x5AD5 嫕 (<CJK Ideograph>) 1993 0x5AD7 嫗 (<CJK Ideograph>) 1994 0x5AD9 嫙 (<CJK Ideograph>) 1995 0x5ADA 嫚 (<CJK Ideograph>) 1996 0x5ADB 嫛 (<CJK Ideograph>) 1997 0x5ADD 嫝 (<CJK Ideograph>) 1998 0x5ADE 嫞 (<CJK Ideograph>) 1999 0x5ADF 嫟 (<CJK Ideograph>) 2000 0x5AE2 嫢 (<CJK Ideograph>) 2001 0x5AE4 嫤 (<CJK Ideograph>) 2002 0x5AE5 嫥 (<CJK Ideograph>) 2003 0x5AE7 嫧 (<CJK Ideograph>) 2004 0x5AE8 嫨 (<CJK Ideograph>) 2005 0x5AEA 嫪 (<CJK Ideograph>) 2006 0x5AEC 嫬 (<CJK Ideograph>) 2007 0x5AED 嫭 (<CJK Ideograph>) 2008 0x5AEE 嫮 (<CJK Ideograph>) 2009 0x5AEF 嫯 (<CJK Ideograph>) 2010 0x5AF0 嫰 (<CJK Ideograph>) 2011 0x5AF2 嫲 (<CJK Ideograph>) 2012 0x5AF3 嫳 (<CJK Ideograph>) 2013 0x5AF4 嫴 (<CJK Ideograph>) 2014 0x5AF5 嫵 (<CJK Ideograph>) 2015 0x5AF6 嫶 (<CJK Ideograph>) 2016 0x5AF7 嫷 (<CJK Ideograph>) 2017 0x5AF8 嫸 (<CJK Ideograph>) 2018 0x5AF9 嫹 (<CJK Ideograph>) 2019 0x5AFA 嫺 (<CJK Ideograph>) 2020 0x5AFB 嫻 (<CJK Ideograph>) 2021 0x5AFC 嫼 (<CJK Ideograph>) 2022 0x5AFD 嫽 (<CJK Ideograph>) 2023 0x5AFE 嫾 (<CJK Ideograph>) 2024 0x5AFF 嫿 (<CJK Ideograph>) 2025 0x5B00 嬀 (<CJK Ideograph>) 2026 0x5B01 嬁 (<CJK Ideograph>) 2027 0x5B02 嬂 (<CJK Ideograph>) 2028 0x5B03 嬃 (<CJK Ideograph>) 2029 0x5B04 嬄 (<CJK Ideograph>) 2030 0x5B05 嬅 (<CJK Ideograph>) 2031 0x5B06 嬆 (<CJK Ideograph>) 2032 0x5B07 嬇 (<CJK Ideograph>) 2033 0x5B08 嬈 (<CJK Ideograph>) 2034 0x5B0A 嬊 (<CJK Ideograph>) 2035 0x5B0B 嬋 (<CJK Ideograph>) 2036 0x5B0C 嬌 (<CJK Ideograph>) 2037 0x5B0D 嬍 (<CJK Ideograph>) 2038 0x5B0E 嬎 (<CJK Ideograph>) 2039 0x5B0F 嬏 (<CJK Ideograph>) 2040 0x5B10 嬐 (<CJK Ideograph>) 2041 0x5B11 嬑 (<CJK Ideograph>) 2042 0x5B12 嬒 (<CJK Ideograph>) 2043 0x5B13 嬓 (<CJK Ideograph>) 2044 0x5B14 嬔 (<CJK Ideograph>) 2045 0x5B15 嬕 (<CJK Ideograph>) 2046 0x5B18 嬘 (<CJK Ideograph>) 2047 0x5B19 嬙 (<CJK Ideograph>) 2048 0x5B1A 嬚 (<CJK Ideograph>) 2049 0x5B1B 嬛 (<CJK Ideograph>) 2050 0x5B1C 嬜 (<CJK Ideograph>) 2051 0x5B1D 嬝 (<CJK Ideograph>) 2052 0x5B1E 嬞 (<CJK Ideograph>) 2053 0x5B1F 嬟 (<CJK Ideograph>) 2054 0x5B20 嬠 (<CJK Ideograph>) 2055 0x5B21 嬡 (<CJK Ideograph>) 2056 0x5B22 嬢 (<CJK Ideograph>) 2057 0x5B23 嬣 (<CJK Ideograph>) 2058 0x5B24 嬤 (<CJK Ideograph>) 2059 0x5B25 嬥 (<CJK Ideograph>) 2060 0x5B26 嬦 (<CJK Ideograph>) 2061 0x5B27 嬧 (<CJK Ideograph>) 2062 0x5B28 嬨 (<CJK Ideograph>) 2063 0x5B29 嬩 (<CJK Ideograph>) 2064 0x5B2A 嬪 (<CJK Ideograph>) 2065 0x5B2B 嬫 (<CJK Ideograph>) 2066 0x5B2C 嬬 (<CJK Ideograph>) 2067 0x5B2D 嬭 (<CJK Ideograph>) 2068 0x5B2E 嬮 (<CJK Ideograph>) 2069 0x5B2F 嬯 (<CJK Ideograph>) 2070 0x5B30 嬰 (<CJK Ideograph>) 2071 0x5B31 嬱 (<CJK Ideograph>) 2072 0x5B33 嬳 (<CJK Ideograph>) 2073 0x5B35 嬵 (<CJK Ideograph>) 2074 0x5B36 嬶 (<CJK Ideograph>) 2075 0x5B38 嬸 (<CJK Ideograph>) 2076 0x5B39 嬹 (<CJK Ideograph>) 2077 0x5B3A 嬺 (<CJK Ideograph>) 2078 0x5B3B 嬻 (<CJK Ideograph>) 2079 0x5B3C 嬼 (<CJK Ideograph>) 2080 0x5B3D 嬽 (<CJK Ideograph>) 2081 0x5B3E 嬾 (<CJK Ideograph>) 2082 0x5B3F 嬿 (<CJK Ideograph>) 2083 0x5B41 孁 (<CJK Ideograph>) 2084 0x5B42 孂 (<CJK Ideograph>) 2085 0x5B43 孃 (<CJK Ideograph>) 2086 0x5B44 孄 (<CJK Ideograph>) 2087 0x5B45 孅 (<CJK Ideograph>) 2088 0x5B46 孆 (<CJK Ideograph>) 2089 0x5B47 孇 (<CJK Ideograph>) 2090 0x5B48 孈 (<CJK Ideograph>) 2091 0x5B49 孉 (<CJK Ideograph>) 2092 0x5B4A 孊 (<CJK Ideograph>) 2093 0x5B4B 孋 (<CJK Ideograph>) 2094 0x5B4C 孌 (<CJK Ideograph>) 2095 0x5B4D 孍 (<CJK Ideograph>) 2096 0x5B4E 孎 (<CJK Ideograph>) 2097 0x5B4F 孏 (<CJK Ideograph>) 2098 0x5B52 孒 (<CJK Ideograph>) 2099 0x5B56 孖 (<CJK Ideograph>) 2100 0x5B5E 孞 (<CJK Ideograph>) 2101 0x5B60 孠 (<CJK Ideograph>) 2102 0x5B61 孡 (<CJK Ideograph>) 2103 0x5B67 孧 (<CJK Ideograph>) 2104 0x5B68 孨 (<CJK Ideograph>) 2105 0x5B6B 孫 (<CJK Ideograph>) 2106 0x5B6D 孭 (<CJK Ideograph>) 2107 0x5B6E 孮 (<CJK Ideograph>) 2108 0x5B6F 孯 (<CJK Ideograph>) 2109 0x5B72 孲 (<CJK Ideograph>) 2110 0x5B74 孴 (<CJK Ideograph>) 2111 0x5B76 孶 (<CJK Ideograph>) 2112 0x5B77 孷 (<CJK Ideograph>) 2113 0x5B78 學 (<CJK Ideograph>) 2114 0x5B79 孹 (<CJK Ideograph>) 2115 0x5B7B 孻 (<CJK Ideograph>) 2116 0x5B7C 孼 (<CJK Ideograph>) 2117 0x5B7E 孾 (<CJK Ideograph>) 2118 0x5B7F 孿 (<CJK Ideograph>) 2119 0x5B82 宂 (<CJK Ideograph>) 2120 0x5B86 宆 (<CJK Ideograph>) 2121 0x5B8A 宊 (<CJK Ideograph>) 2122 0x5B8D 宍 (<CJK Ideograph>) 2123 0x5B8E 宎 (<CJK Ideograph>) 2124 0x5B90 宐 (<CJK Ideograph>) 2125 0x5B91 宑 (<CJK Ideograph>) 2126 0x5B92 宒 (<CJK Ideograph>) 2127 0x5B94 宔 (<CJK Ideograph>) 2128 0x5B96 宖 (<CJK Ideograph>) 2129 0x5B9F 実 (<CJK Ideograph>) 2130 0x5BA7 宧 (<CJK Ideograph>) 2131 0x5BA8 宨 (<CJK Ideograph>) 2132 0x5BA9 宩 (<CJK Ideograph>) 2133 0x5BAC 宬 (<CJK Ideograph>) 2134 0x5BAD 宭 (<CJK Ideograph>) 2135 0x5BAE 宮 (<CJK Ideograph>) 2136 0x5BAF 宯 (<CJK Ideograph>) 2137 0x5BB1 宱 (<CJK Ideograph>) 2138 0x5BB2 宲 (<CJK Ideograph>) 2139 0x5BB7 宷 (<CJK Ideograph>) 2140 0x5BBA 宺 (<CJK Ideograph>) 2141 0x5BBB 宻 (<CJK Ideograph>) 2142 0x5BBC 宼 (<CJK Ideograph>) 2143 0x5BC0 寀 (<CJK Ideograph>) 2144 0x5BC1 寁 (<CJK Ideograph>) 2145 0x5BC3 寃 (<CJK Ideograph>) 2146 0x5BC8 寈 (<CJK Ideograph>) 2147 0x5BC9 寉 (<CJK Ideograph>) 2148 0x5BCA 寊 (<CJK Ideograph>) 2149 0x5BCB 寋 (<CJK Ideograph>) 2150 0x5BCD 寍 (<CJK Ideograph>) 2151 0x5BCE 寎 (<CJK Ideograph>) 2152 0x5BCF 寏 (<CJK Ideograph>) 2153 0x5BD1 寑 (<CJK Ideograph>) 2154 0x5BD4 寔 (<CJK Ideograph>) 2155 0x5BD5 寕 (<CJK Ideograph>) 2156 0x5BD6 寖 (<CJK Ideograph>) 2157 0x5BD7 寗 (<CJK Ideograph>) 2158 0x5BD8 寘 (<CJK Ideograph>) 2159 0x5BD9 寙 (<CJK Ideograph>) 2160 0x5BDA 寚 (<CJK Ideograph>) 2161 0x5BDB 寛 (<CJK Ideograph>) 2162 0x5BDC 寜 (<CJK Ideograph>) 2163 0x5BE0 寠 (<CJK Ideograph>) 2164 0x5BE2 寢 (<CJK Ideograph>) 2165 0x5BE3 寣 (<CJK Ideograph>) 2166 0x5BE6 實 (<CJK Ideograph>) 2167 0x5BE7 寧 (<CJK Ideograph>) 2168 0x5BE9 審 (<CJK Ideograph>) 2169 0x5BEA 寪 (<CJK Ideograph>) 2170 0x5BEB 寫 (<CJK Ideograph>) 2171 0x5BEC 寬 (<CJK Ideograph>) 2172 0x5BED 寭 (<CJK Ideograph>) 2173 0x5BEF 寯 (<CJK Ideograph>) 2174 0x5BF1 寱 (<CJK Ideograph>) 2175 0x5BF2 寲 (<CJK Ideograph>) 2176 0x5BF3 寳 (<CJK Ideograph>) 2177 0x5BF4 寴 (<CJK Ideograph>) 2178 0x5BF5 寵 (<CJK Ideograph>) 2179 0x5BF6 寶 (<CJK Ideograph>) 2180 0x5BF7 寷 (<CJK Ideograph>) 2181 0x5BFD 寽 (<CJK Ideograph>) 2182 0x5BFE 対 (<CJK Ideograph>) 2183 0x5C00 尀 (<CJK Ideograph>) 2184 0x5C02 専 (<CJK Ideograph>) 2185 0x5C03 尃 (<CJK Ideograph>) 2186 0x5C05 尅 (<CJK Ideograph>) 2187 0x5C07 將 (<CJK Ideograph>) 2188 0x5C08 專 (<CJK Ideograph>) 2189 0x5C0B 尋 (<CJK Ideograph>) 2190 0x5C0C 尌 (<CJK Ideograph>) 2191 0x5C0D 對 (<CJK Ideograph>) 2192 0x5C0E 導 (<CJK Ideograph>) 2193 0x5C10 尐 (<CJK Ideograph>) 2194 0x5C12 尒 (<CJK Ideograph>) 2195 0x5C13 尓 (<CJK Ideograph>) 2196 0x5C17 尗 (<CJK Ideograph>) 2197 0x5C19 尙 (<CJK Ideograph>) 2198 0x5C1B 尛 (<CJK Ideograph>) 2199 0x5C1E 尞 (<CJK Ideograph>) 2200 0x5C1F 尟 (<CJK Ideograph>) 2201 0x5C20 尠 (<CJK Ideograph>) 2202 0x5C21 尡 (<CJK Ideograph>) 2203 0x5C23 尣 (<CJK Ideograph>) 2204 0x5C26 尦 (<CJK Ideograph>) 2205 0x5C28 尨 (<CJK Ideograph>) 2206 0x5C29 尩 (<CJK Ideograph>) 2207 0x5C2A 尪 (<CJK Ideograph>) 2208 0x5C2B 尫 (<CJK Ideograph>) 2209 0x5C2D 尭 (<CJK Ideograph>) 2210 0x5C2E 尮 (<CJK Ideograph>) 2211 0x5C2F 尯 (<CJK Ideograph>) 2212 0x5C30 尰 (<CJK Ideograph>) 2213 0x5C32 尲 (<CJK Ideograph>) 2214 0x5C33 尳 (<CJK Ideograph>) 2215 0x5C35 尵 (<CJK Ideograph>) 2216 0x5C36 尶 (<CJK Ideograph>) 2217 0x5C37 尷 (<CJK Ideograph>) 2218 0x5C43 屃 (<CJK Ideograph>) 2219 0x5C44 屄 (<CJK Ideograph>) 2220 0x5C46 屆 (<CJK Ideograph>) 2221 0x5C47 屇 (<CJK Ideograph>) 2222 0x5C4C 屌 (<CJK Ideograph>) 2223 0x5C4D 屍 (<CJK Ideograph>) 2224 0x5C52 屒 (<CJK Ideograph>) 2225 0x5C53 屓 (<CJK Ideograph>) 2226 0x5C54 屔 (<CJK Ideograph>) 2227 0x5C56 屖 (<CJK Ideograph>) 2228 0x5C57 屗 (<CJK Ideograph>) 2229 0x5C58 屘 (<CJK Ideograph>) 2230 0x5C5A 屚 (<CJK Ideograph>) 2231 0x5C5B 屛 (<CJK Ideograph>) 2232 0x5C5C 屜 (<CJK Ideograph>) 2233 0x5C5D 屝 (<CJK Ideograph>) 2234 0x5C5F 屟 (<CJK Ideograph>) 2235 0x5C62 屢 (<CJK Ideograph>) 2236 0x5C64 層 (<CJK Ideograph>) 2237 0x5C67 屧 (<CJK Ideograph>) 2238 0x5C68 屨 (<CJK Ideograph>) 2239 0x5C69 屩 (<CJK Ideograph>) 2240 0x5C6A 屪 (<CJK Ideograph>) 2241 0x5C6B 屫 (<CJK Ideograph>) 2242 0x5C6C 屬 (<CJK Ideograph>) 2243 0x5C6D 屭 (<CJK Ideograph>) 2244 0x5C70 屰 (<CJK Ideograph>) 2245 0x5C72 屲 (<CJK Ideograph>) 2246 0x5C73 屳 (<CJK Ideograph>) 2247 0x5C74 屴 (<CJK Ideograph>) 2248 0x5C75 屵 (<CJK Ideograph>) 2249 0x5C76 屶 (<CJK Ideograph>) 2250 0x5C77 屷 (<CJK Ideograph>) 2251 0x5C78 屸 (<CJK Ideograph>) 2252 0x5C7B 屻 (<CJK Ideograph>) 2253 0x5C7C 屼 (<CJK Ideograph>) 2254 0x5C7D 屽 (<CJK Ideograph>) 2255 0x5C7E 屾 (<CJK Ideograph>) 2256 0x5C80 岀 (<CJK Ideograph>) 2257 0x5C83 岃 (<CJK Ideograph>) 2258 0x5C84 岄 (<CJK Ideograph>) 2259 0x5C85 岅 (<CJK Ideograph>) 2260 0x5C86 岆 (<CJK Ideograph>) 2261 0x5C87 岇 (<CJK Ideograph>) 2262 0x5C89 岉 (<CJK Ideograph>) 2263 0x5C8A 岊 (<CJK Ideograph>) 2264 0x5C8B 岋 (<CJK Ideograph>) 2265 0x5C8E 岎 (<CJK Ideograph>) 2266 0x5C8F 岏 (<CJK Ideograph>) 2267 0x5C92 岒 (<CJK Ideograph>) 2268 0x5C93 岓 (<CJK Ideograph>) 2269 0x5C95 岕 (<CJK Ideograph>) 2270 0x5C9D 岝 (<CJK Ideograph>) 2271 0x5C9E 岞 (<CJK Ideograph>) 2272 0x5C9F 岟 (<CJK Ideograph>) 2273 0x5CA0 岠 (<CJK Ideograph>) 2274 0x5CA1 岡 (<CJK Ideograph>) 2275 0x5CA4 岤 (<CJK Ideograph>) 2276 0x5CA5 岥 (<CJK Ideograph>) 2277 0x5CA6 岦 (<CJK Ideograph>) 2278 0x5CA7 岧 (<CJK Ideograph>) 2279 0x5CA8 岨 (<CJK Ideograph>) 2280 0x5CAA 岪 (<CJK Ideograph>) 2281 0x5CAE 岮 (<CJK Ideograph>) 2282 0x5CAF 岯 (<CJK Ideograph>) 2283 0x5CB0 岰 (<CJK Ideograph>) 2284 0x5CB2 岲 (<CJK Ideograph>) 2285 0x5CB4 岴 (<CJK Ideograph>) 2286 0x5CB6 岶 (<CJK Ideograph>) 2287 0x5CB9 岹 (<CJK Ideograph>) 2288 0x5CBA 岺 (<CJK Ideograph>) 2289 0x5CBB 岻 (<CJK Ideograph>) 2290 0x5CBC 岼 (<CJK Ideograph>) 2291 0x5CBE 岾 (<CJK Ideograph>) 2292 0x5CC0 峀 (<CJK Ideograph>) 2293 0x5CC2 峂 (<CJK Ideograph>) 2294 0x5CC3 峃 (<CJK Ideograph>) 2295 0x5CC5 峅 (<CJK Ideograph>) 2296 0x5CC6 峆 (<CJK Ideograph>) 2297 0x5CC7 峇 (<CJK Ideograph>) 2298 0x5CC8 峈 (<CJK Ideograph>) 2299 0x5CC9 峉 (<CJK Ideograph>) 2300 0x5CCA 峊 (<CJK Ideograph>) 2301 0x5CCC 峌 (<CJK Ideograph>) 2302 0x5CCD 峍 (<CJK Ideograph>) 2303 0x5CCE 峎 (<CJK Ideograph>) 2304 0x5CCF 峏 (<CJK Ideograph>) 2305 0x5CD0 峐 (<CJK Ideograph>) 2306 0x5CD1 峑 (<CJK Ideograph>) 2307 0x5CD3 峓 (<CJK Ideograph>) 2308 0x5CD4 峔 (<CJK Ideograph>) 2309 0x5CD5 峕 (<CJK Ideograph>) 2310 0x5CD6 峖 (<CJK Ideograph>) 2311 0x5CD7 峗 (<CJK Ideograph>) 2312 0x5CD8 峘 (<CJK Ideograph>) 2313 0x5CDA 峚 (<CJK Ideograph>) 2314 0x5CDB 峛 (<CJK Ideograph>) 2315 0x5CDC 峜 (<CJK Ideograph>) 2316 0x5CDD 峝 (<CJK Ideograph>) 2317 0x5CDE 峞 (<CJK Ideograph>) 2318 0x5CDF 峟 (<CJK Ideograph>) 2319 0x5CE0 峠 (<CJK Ideograph>) 2320 0x5CE2 峢 (<CJK Ideograph>) 2321 0x5CE3 峣 (<CJK Ideograph>) 2322 0x5CE7 峧 (<CJK Ideograph>) 2323 0x5CE9 峩 (<CJK Ideograph>) 2324 0x5CEB 峫 (<CJK Ideograph>) 2325 0x5CEC 峬 (<CJK Ideograph>) 2326 0x5CEE 峮 (<CJK Ideograph>) 2327 0x5CEF 峯 (<CJK Ideograph>) 2328 0x5CF1 峱 (<CJK Ideograph>) 2329 0x5CF2 峲 (<CJK Ideograph>) 2330 0x5CF3 峳 (<CJK Ideograph>) 2331 0x5CF4 峴 (<CJK Ideograph>) 2332 0x5CF5 峵 (<CJK Ideograph>) 2333 0x5CF6 島 (<CJK Ideograph>) 2334 0x5CF7 峷 (<CJK Ideograph>) 2335 0x5CF8 峸 (<CJK Ideograph>) 2336 0x5CF9 峹 (<CJK Ideograph>) 2337 0x5CFA 峺 (<CJK Ideograph>) 2338 0x5CFC 峼 (<CJK Ideograph>) 2339 0x5CFD 峽 (<CJK Ideograph>) 2340 0x5CFE 峾 (<CJK Ideograph>) 2341 0x5CFF 峿 (<CJK Ideograph>) 2342 0x5D00 崀 (<CJK Ideograph>) 2343 0x5D01 崁 (<CJK Ideograph>) 2344 0x5D04 崄 (<CJK Ideograph>) 2345 0x5D05 崅 (<CJK Ideograph>) 2346 0x5D08 崈 (<CJK Ideograph>) 2347 0x5D09 崉 (<CJK Ideograph>) 2348 0x5D0A 崊 (<CJK Ideograph>) 2349 0x5D0B 崋 (<CJK Ideograph>) 2350 0x5D0C 崌 (<CJK Ideograph>) 2351 0x5D0D 崍 (<CJK Ideograph>) 2352 0x5D0F 崏 (<CJK Ideograph>) 2353 0x5D10 崐 (<CJK Ideograph>) 2354 0x5D11 崑 (<CJK Ideograph>) 2355 0x5D12 崒 (<CJK Ideograph>) 2356 0x5D13 崓 (<CJK Ideograph>) 2357 0x5D15 崕 (<CJK Ideograph>) 2358 0x5D17 崗 (<CJK Ideograph>) 2359 0x5D18 崘 (<CJK Ideograph>) 2360 0x5D19 崙 (<CJK Ideograph>) 2361 0x5D1A 崚 (<CJK Ideograph>) 2362 0x5D1C 崜 (<CJK Ideograph>) 2363 0x5D1D 崝 (<CJK Ideograph>) 2364 0x5D1F 崟 (<CJK Ideograph>) 2365 0x5D20 崠 (<CJK Ideograph>) 2366 0x5D21 崡 (<CJK Ideograph>) 2367 0x5D22 崢 (<CJK Ideograph>) 2368 0x5D23 崣 (<CJK Ideograph>) 2369 0x5D25 崥 (<CJK Ideograph>) 2370 0x5D28 崨 (<CJK Ideograph>) 2371 0x5D2A 崪 (<CJK Ideograph>) 2372 0x5D2B 崫 (<CJK Ideograph>) 2373 0x5D2C 崬 (<CJK Ideograph>) 2374 0x5D2F 崯 (<CJK Ideograph>) 2375 0x5D30 崰 (<CJK Ideograph>) 2376 0x5D31 崱 (<CJK Ideograph>) 2377 0x5D32 崲 (<CJK Ideograph>) 2378 0x5D33 崳 (<CJK Ideograph>) 2379 0x5D35 崵 (<CJK Ideograph>) 2380 0x5D36 崶 (<CJK Ideograph>) 2381 0x5D37 崷 (<CJK Ideograph>) 2382 0x5D38 崸 (<CJK Ideograph>) 2383 0x5D39 崹 (<CJK Ideograph>) 2384 0x5D3A 崺 (<CJK Ideograph>) 2385 0x5D3B 崻 (<CJK Ideograph>) 2386 0x5D3C 崼 (<CJK Ideograph>) 2387 0x5D3F 崿 (<CJK Ideograph>) 2388 0x5D40 嵀 (<CJK Ideograph>) 2389 0x5D41 嵁 (<CJK Ideograph>) 2390 0x5D42 嵂 (<CJK Ideograph>) 2391 0x5D43 嵃 (<CJK Ideograph>) 2392 0x5D44 嵄 (<CJK Ideograph>) 2393 0x5D45 嵅 (<CJK Ideograph>) 2394 0x5D46 嵆 (<CJK Ideograph>) 2395 0x5D48 嵈 (<CJK Ideograph>) 2396 0x5D49 嵉 (<CJK Ideograph>) 2397 0x5D4D 嵍 (<CJK Ideograph>) 2398 0x5D4E 嵎 (<CJK Ideograph>) 2399 0x5D4F 嵏 (<CJK Ideograph>) 2400 0x5D50 嵐 (<CJK Ideograph>) 2401 0x5D51 嵑 (<CJK Ideograph>) 2402 0x5D52 嵒 (<CJK Ideograph>) 2403 0x5D53 嵓 (<CJK Ideograph>) 2404 0x5D54 嵔 (<CJK Ideograph>) 2405 0x5D55 嵕 (<CJK Ideograph>) 2406 0x5D56 嵖 (<CJK Ideograph>) 2407 0x5D57 嵗 (<CJK Ideograph>) 2408 0x5D59 嵙 (<CJK Ideograph>) 2409 0x5D5A 嵚 (<CJK Ideograph>) 2410 0x5D5C 嵜 (<CJK Ideograph>) 2411 0x5D5E 嵞 (<CJK Ideograph>) 2412 0x5D5F 嵟 (<CJK Ideograph>) 2413 0x5D60 嵠 (<CJK Ideograph>) 2414 0x5D61 嵡 (<CJK Ideograph>) 2415 0x5D62 嵢 (<CJK Ideograph>) 2416 0x5D63 嵣 (<CJK Ideograph>) 2417 0x5D64 嵤 (<CJK Ideograph>) 2418 0x5D65 嵥 (<CJK Ideograph>) 2419 0x5D66 嵦 (<CJK Ideograph>) 2420 0x5D67 嵧 (<CJK Ideograph>) 2421 0x5D68 嵨 (<CJK Ideograph>) 2422 0x5D6A 嵪 (<CJK Ideograph>) 2423 0x5D6D 嵭 (<CJK Ideograph>) 2424 0x5D6E 嵮 (<CJK Ideograph>) 2425 0x5D70 嵰 (<CJK Ideograph>) 2426 0x5D71 嵱 (<CJK Ideograph>) 2427 0x5D72 嵲 (<CJK Ideograph>) 2428 0x5D73 嵳 (<CJK Ideograph>) 2429 0x5D75 嵵 (<CJK Ideograph>) 2430 0x5D76 嵶 (<CJK Ideograph>) 2431 0x5D77 嵷 (<CJK Ideograph>) 2432 0x5D78 嵸 (<CJK Ideograph>) 2433 0x5D79 嵹 (<CJK Ideograph>) 2434 0x5D7A 嵺 (<CJK Ideograph>) 2435 0x5D7B 嵻 (<CJK Ideograph>) 2436 0x5D7C 嵼 (<CJK Ideograph>) 2437 0x5D7D 嵽 (<CJK Ideograph>) 2438 0x5D7E 嵾 (<CJK Ideograph>) 2439 0x5D7F 嵿 (<CJK Ideograph>) 2440 0x5D80 嶀 (<CJK Ideograph>) 2441 0x5D81 嶁 (<CJK Ideograph>) 2442 0x5D83 嶃 (<CJK Ideograph>) 2443 0x5D84 嶄 (<CJK Ideograph>) 2444 0x5D85 嶅 (<CJK Ideograph>) 2445 0x5D86 嶆 (<CJK Ideograph>) 2446 0x5D87 嶇 (<CJK Ideograph>) 2447 0x5D88 嶈 (<CJK Ideograph>) 2448 0x5D89 嶉 (<CJK Ideograph>) 2449 0x5D8A 嶊 (<CJK Ideograph>) 2450 0x5D8B 嶋 (<CJK Ideograph>) 2451 0x5D8C 嶌 (<CJK Ideograph>) 2452 0x5D8D 嶍 (<CJK Ideograph>) 2453 0x5D8E 嶎 (<CJK Ideograph>) 2454 0x5D8F 嶏 (<CJK Ideograph>) 2455 0x5D90 嶐 (<CJK Ideograph>) 2456 0x5D91 嶑 (<CJK Ideograph>) 2457 0x5D92 嶒 (<CJK Ideograph>) 2458 0x5D93 嶓 (<CJK Ideograph>) 2459 0x5D94 嶔 (<CJK Ideograph>) 2460 0x5D95 嶕 (<CJK Ideograph>) 2461 0x5D96 嶖 (<CJK Ideograph>) 2462 0x5D97 嶗 (<CJK Ideograph>) 2463 0x5D98 嶘 (<CJK Ideograph>) 2464 0x5D9A 嶚 (<CJK Ideograph>) 2465 0x5D9B 嶛 (<CJK Ideograph>) 2466 0x5D9C 嶜 (<CJK Ideograph>) 2467 0x5D9E 嶞 (<CJK Ideograph>) 2468 0x5D9F 嶟 (<CJK Ideograph>) 2469 0x5DA0 嶠 (<CJK Ideograph>) 2470 0x5DA1 嶡 (<CJK Ideograph>) 2471 0x5DA2 嶢 (<CJK Ideograph>) 2472 0x5DA3 嶣 (<CJK Ideograph>) 2473 0x5DA4 嶤 (<CJK Ideograph>) 2474 0x5DA5 嶥 (<CJK Ideograph>) 2475 0x5DA6 嶦 (<CJK Ideograph>) 2476 0x5DA7 嶧 (<CJK Ideograph>) 2477 0x5DA8 嶨 (<CJK Ideograph>) 2478 0x5DA9 嶩 (<CJK Ideograph>) 2479 0x5DAA 嶪 (<CJK Ideograph>) 2480 0x5DAB 嶫 (<CJK Ideograph>) 2481 0x5DAC 嶬 (<CJK Ideograph>) 2482 0x5DAD 嶭 (<CJK Ideograph>) 2483 0x5DAE 嶮 (<CJK Ideograph>) 2484 0x5DAF 嶯 (<CJK Ideograph>) 2485 0x5DB0 嶰 (<CJK Ideograph>) 2486 0x5DB1 嶱 (<CJK Ideograph>) 2487 0x5DB2 嶲 (<CJK Ideograph>) 2488 0x5DB3 嶳 (<CJK Ideograph>) 2489 0x5DB4 嶴 (<CJK Ideograph>) 2490 0x5DB5 嶵 (<CJK Ideograph>) 2491 0x5DB6 嶶 (<CJK Ideograph>) 2492 0x5DB8 嶸 (<CJK Ideograph>) 2493 0x5DB9 嶹 (<CJK Ideograph>) 2494 0x5DBA 嶺 (<CJK Ideograph>) 2495 0x5DBB 嶻 (<CJK Ideograph>) 2496 0x5DBC 嶼 (<CJK Ideograph>) 2497 0x5DBD 嶽 (<CJK Ideograph>) 2498 0x5DBE 嶾 (<CJK Ideograph>) 2499 0x5DBF 嶿 (<CJK Ideograph>) 2500 0x5DC0 巀 (<CJK Ideograph>) 2501 0x5DC1 巁 (<CJK Ideograph>) 2502 0x5DC2 巂 (<CJK Ideograph>) 2503 0x5DC3 巃 (<CJK Ideograph>) 2504 0x5DC4 巄 (<CJK Ideograph>) 2505 0x5DC6 巆 (<CJK Ideograph>) 2506 0x5DC7 巇 (<CJK Ideograph>) 2507 0x5DC8 巈 (<CJK Ideograph>) 2508 0x5DC9 巉 (<CJK Ideograph>) 2509 0x5DCA 巊 (<CJK Ideograph>) 2510 0x5DCB 巋 (<CJK Ideograph>) 2511 0x5DCC 巌 (<CJK Ideograph>) 2512 0x5DCE 巎 (<CJK Ideograph>) 2513 0x5DCF 巏 (<CJK Ideograph>) 2514 0x5DD0 巐 (<CJK Ideograph>) 2515 0x5DD1 巑 (<CJK Ideograph>) 2516 0x5DD2 巒 (<CJK Ideograph>) 2517 0x5DD3 巓 (<CJK Ideograph>) 2518 0x5DD4 巔 (<CJK Ideograph>) 2519 0x5DD5 巕 (<CJK Ideograph>) 2520 0x5DD6 巖 (<CJK Ideograph>) 2521 0x5DD7 巗 (<CJK Ideograph>) 2522 0x5DD8 巘 (<CJK Ideograph>) 2523 0x5DD9 巙 (<CJK Ideograph>) 2524 0x5DDA 巚 (<CJK Ideograph>) 2525 0x5DDC 巜 (<CJK Ideograph>) 2526 0x5DDF 巟 (<CJK Ideograph>) 2527 0x5DE0 巠 (<CJK Ideograph>) 2528 0x5DE3 巣 (<CJK Ideograph>) 2529 0x5DE4 巤 (<CJK Ideograph>) 2530 0x5DEA 巪 (<CJK Ideograph>) 2531 0x5DEC 巬 (<CJK Ideograph>) 2532 0x5DED 巭 (<CJK Ideograph>) 2533 0x5DF0 巰 (<CJK Ideograph>) 2534 0x5DF5 巵 (<CJK Ideograph>) 2535 0x5DF6 巶 (<CJK Ideograph>) 2536 0x5DF8 巸 (<CJK Ideograph>) 2537 0x5DF9 巹 (<CJK Ideograph>) 2538 0x5DFA 巺 (<CJK Ideograph>) 2539 0x5DFB 巻 (<CJK Ideograph>) 2540 0x5DFC 巼 (<CJK Ideograph>) 2541 0x5DFF 巿 (<CJK Ideograph>) 2542 0x5E00 帀 (<CJK Ideograph>) 2543 0x5E04 帄 (<CJK Ideograph>) 2544 0x5E07 帇 (<CJK Ideograph>) 2545 0x5E09 帉 (<CJK Ideograph>) 2546 0x5E0A 帊 (<CJK Ideograph>) 2547 0x5E0B 帋 (<CJK Ideograph>) 2548 0x5E0D 帍 (<CJK Ideograph>) 2549 0x5E0E 帎 (<CJK Ideograph>) 2550 0x5E12 帒 (<CJK Ideograph>) 2551 0x5E13 帓 (<CJK Ideograph>) 2552 0x5E17 帗 (<CJK Ideograph>) 2553 0x5E1E 帞 (<CJK Ideograph>) 2554 0x5E1F 帟 (<CJK Ideograph>) 2555 0x5E20 帠 (<CJK Ideograph>) 2556 0x5E21 帡 (<CJK Ideograph>) 2557 0x5E22 帢 (<CJK Ideograph>) 2558 0x5E23 帣 (<CJK Ideograph>) 2559 0x5E24 帤 (<CJK Ideograph>) 2560 0x5E25 帥 (<CJK Ideograph>) 2561 0x5E28 帨 (<CJK Ideograph>) 2562 0x5E29 帩 (<CJK Ideograph>) 2563 0x5E2A 帪 (<CJK Ideograph>) 2564 0x5E2B 師 (<CJK Ideograph>) 2565 0x5E2C 帬 (<CJK Ideograph>) 2566 0x5E2F 帯 (<CJK Ideograph>) 2567 0x5E30 帰 (<CJK Ideograph>) 2568 0x5E32 帲 (<CJK Ideograph>) 2569 0x5E33 帳 (<CJK Ideograph>) 2570 0x5E34 帴 (<CJK Ideograph>) 2571 0x5E35 帵 (<CJK Ideograph>) 2572 0x5E36 帶 (<CJK Ideograph>) 2573 0x5E39 帹 (<CJK Ideograph>) 2574 0x5E3A 帺 (<CJK Ideograph>) 2575 0x5E3E 帾 (<CJK Ideograph>) 2576 0x5E3F 帿 (<CJK Ideograph>) 2577 0x5E40 幀 (<CJK Ideograph>) 2578 0x5E41 幁 (<CJK Ideograph>) 2579 0x5E43 幃 (<CJK Ideograph>) 2580 0x5E46 幆 (<CJK Ideograph>) 2581 0x5E47 幇 (<CJK Ideograph>) 2582 0x5E48 幈 (<CJK Ideograph>) 2583 0x5E49 幉 (<CJK Ideograph>) 2584 0x5E4A 幊 (<CJK Ideograph>) 2585 0x5E4B 幋 (<CJK Ideograph>) 2586 0x5E4D 幍 (<CJK Ideograph>) 2587 0x5E4E 幎 (<CJK Ideograph>) 2588 0x5E4F 幏 (<CJK Ideograph>) 2589 0x5E50 幐 (<CJK Ideograph>) 2590 0x5E51 幑 (<CJK Ideograph>) 2591 0x5E52 幒 (<CJK Ideograph>) 2592 0x5E53 幓 (<CJK Ideograph>) 2593 0x5E56 幖 (<CJK Ideograph>) 2594 0x5E57 幗 (<CJK Ideograph>) 2595 0x5E58 幘 (<CJK Ideograph>) 2596 0x5E59 幙 (<CJK Ideograph>) 2597 0x5E5A 幚 (<CJK Ideograph>) 2598 0x5E5C 幜 (<CJK Ideograph>) 2599 0x5E5D 幝 (<CJK Ideograph>) 2600 0x5E5F 幟 (<CJK Ideograph>) 2601 0x5E60 幠 (<CJK Ideograph>) 2602 0x5E63 幣 (<CJK Ideograph>) 2603 0x5E64 幤 (<CJK Ideograph>) 2604 0x5E65 幥 (<CJK Ideograph>) 2605 0x5E66 幦 (<CJK Ideograph>) 2606 0x5E67 幧 (<CJK Ideograph>) 2607 0x5E68 幨 (<CJK Ideograph>) 2608 0x5E69 幩 (<CJK Ideograph>) 2609 0x5E6A 幪 (<CJK Ideograph>) 2610 0x5E6B 幫 (<CJK Ideograph>) 2611 0x5E6C 幬 (<CJK Ideograph>) 2612 0x5E6D 幭 (<CJK Ideograph>) 2613 0x5E6E 幮 (<CJK Ideograph>) 2614 0x5E6F 幯 (<CJK Ideograph>) 2615 0x5E70 幰 (<CJK Ideograph>) 2616 0x5E71 幱 (<CJK Ideograph>) 2617 0x5E75 幵 (<CJK Ideograph>) 2618 0x5E77 幷 (<CJK Ideograph>) 2619 0x5E79 幹 (<CJK Ideograph>) 2620 0x5E7E 幾 (<CJK Ideograph>) 2621 0x5E81 庁 (<CJK Ideograph>) 2622 0x5E82 庂 (<CJK Ideograph>) 2623 0x5E83 広 (<CJK Ideograph>) 2624 0x5E85 庅 (<CJK Ideograph>) 2625 0x5E88 庈 (<CJK Ideograph>) 2626 0x5E89 庉 (<CJK Ideograph>) 2627 0x5E8C 庌 (<CJK Ideograph>) 2628 0x5E8D 庍 (<CJK Ideograph>) 2629 0x5E8E 庎 (<CJK Ideograph>) 2630 0x5E92 庒 (<CJK Ideograph>) 2631 0x5E98 庘 (<CJK Ideograph>) 2632 0x5E9B 庛 (<CJK Ideograph>) 2633 0x5E9D 庝 (<CJK Ideograph>) 2634 0x5EA1 庡 (<CJK Ideograph>) 2635 0x5EA2 庢 (<CJK Ideograph>) 2636 0x5EA3 庣 (<CJK Ideograph>) 2637 0x5EA4 庤 (<CJK Ideograph>) 2638 0x5EA8 庨 (<CJK Ideograph>) 2639 0x5EA9 庩 (<CJK Ideograph>) 2640 0x5EAA 庪 (<CJK Ideograph>) 2641 0x5EAB 庫 (<CJK Ideograph>) 2642 0x5EAC 庬 (<CJK Ideograph>) 2643 0x5EAE 庮 (<CJK Ideograph>) 2644 0x5EAF 庯 (<CJK Ideograph>) 2645 0x5EB0 庰 (<CJK Ideograph>) 2646 0x5EB1 庱 (<CJK Ideograph>) 2647 0x5EB2 庲 (<CJK Ideograph>) 2648 0x5EB4 庴 (<CJK Ideograph>) 2649 0x5EBA 庺 (<CJK Ideograph>) 2650 0x5EBB 庻 (<CJK Ideograph>) 2651 0x5EBC 庼 (<CJK Ideograph>) 2652 0x5EBD 庽 (<CJK Ideograph>) 2653 0x5EBF 庿 (<CJK Ideograph>) 2654 0x5EC0 廀 (<CJK Ideograph>) 2655 0x5EC1 廁 (<CJK Ideograph>) 2656 0x5EC2 廂 (<CJK Ideograph>) 2657 0x5EC3 廃 (<CJK Ideograph>) 2658 0x5EC4 廄 (<CJK Ideograph>) 2659 0x5EC5 廅 (<CJK Ideograph>) 2660 0x5EC6 廆 (<CJK Ideograph>) 2661 0x5EC7 廇 (<CJK Ideograph>) 2662 0x5EC8 廈 (<CJK Ideograph>) 2663 0x5ECB 廋 (<CJK Ideograph>) 2664 0x5ECC 廌 (<CJK Ideograph>) 2665 0x5ECD 廍 (<CJK Ideograph>) 2666 0x5ECE 廎 (<CJK Ideograph>) 2667 0x5ECF 廏 (<CJK Ideograph>) 2668 0x5ED0 廐 (<CJK Ideograph>) 2669 0x5ED4 廔 (<CJK Ideograph>) 2670 0x5ED5 廕 (<CJK Ideograph>) 2671 0x5ED7 廗 (<CJK Ideograph>) 2672 0x5ED8 廘 (<CJK Ideograph>) 2673 0x5ED9 廙 (<CJK Ideograph>) 2674 0x5EDA 廚 (<CJK Ideograph>) 2675 0x5EDC 廜 (<CJK Ideograph>) 2676 0x5EDD 廝 (<CJK Ideograph>) 2677 0x5EDE 廞 (<CJK Ideograph>) 2678 0x5EDF 廟 (<CJK Ideograph>) 2679 0x5EE0 廠 (<CJK Ideograph>) 2680 0x5EE1 廡 (<CJK Ideograph>) 2681 0x5EE2 廢 (<CJK Ideograph>) 2682 0x5EE3 廣 (<CJK Ideograph>) 2683 0x5EE4 廤 (<CJK Ideograph>) 2684 0x5EE5 廥 (<CJK Ideograph>) 2685 0x5EE6 廦 (<CJK Ideograph>) 2686 0x5EE7 廧 (<CJK Ideograph>) 2687 0x5EE9 廩 (<CJK Ideograph>) 2688 0x5EEB 廫 (<CJK Ideograph>) 2689 0x5EEC 廬 (<CJK Ideograph>) 2690 0x5EED 廭 (<CJK Ideograph>) 2691 0x5EEE 廮 (<CJK Ideograph>) 2692 0x5EEF 廯 (<CJK Ideograph>) 2693 0x5EF0 廰 (<CJK Ideograph>) 2694 0x5EF1 廱 (<CJK Ideograph>) 2695 0x5EF2 廲 (<CJK Ideograph>) 2696 0x5EF3 廳 (<CJK Ideograph>) 2697 0x5EF5 廵 (<CJK Ideograph>) 2698 0x5EF8 廸 (<CJK Ideograph>) 2699 0x5EF9 廹 (<CJK Ideograph>) 2700 0x5EFB 廻 (<CJK Ideograph>) 2701 0x5EFC 廼 (<CJK Ideograph>) 2702 0x5EFD 廽 (<CJK Ideograph>) 2703 0x5F05 弅 (<CJK Ideograph>) 2704 0x5F06 弆 (<CJK Ideograph>) 2705 0x5F07 弇 (<CJK Ideograph>) 2706 0x5F09 弉 (<CJK Ideograph>) 2707 0x5F0C 弌 (<CJK Ideograph>) 2708 0x5F0D 弍 (<CJK Ideograph>) 2709 0x5F0E 弎 (<CJK Ideograph>) 2710 0x5F10 弐 (<CJK Ideograph>) 2711 0x5F12 弒 (<CJK Ideograph>) 2712 0x5F14 弔 (<CJK Ideograph>) 2713 0x5F16 弖 (<CJK Ideograph>) 2714 0x5F19 弙 (<CJK Ideograph>) 2715 0x5F1A 弚 (<CJK Ideograph>) 2716 0x5F1C 弜 (<CJK Ideograph>) 2717 0x5F1D 弝 (<CJK Ideograph>) 2718 0x5F1E 弞 (<CJK Ideograph>) 2719 0x5F21 弡 (<CJK Ideograph>) 2720 0x5F22 弢 (<CJK Ideograph>) 2721 0x5F23 弣 (<CJK Ideograph>) 2722 0x5F24 弤 (<CJK Ideograph>) 2723 0x5F28 弨 (<CJK Ideograph>) 2724 0x5F2B 弫 (<CJK Ideograph>) 2725 0x5F2C 弬 (<CJK Ideograph>) 2726 0x5F2E 弮 (<CJK Ideograph>) 2727 0x5F30 弰 (<CJK Ideograph>) 2728 0x5F32 弲 (<CJK Ideograph>) 2729 0x5F33 弳 (<CJK Ideograph>) 2730 0x5F34 弴 (<CJK Ideograph>) 2731 0x5F35 張 (<CJK Ideograph>) 2732 0x5F36 弶 (<CJK Ideograph>) 2733 0x5F37 強 (<CJK Ideograph>) 2734 0x5F38 弸 (<CJK Ideograph>) 2735 0x5F3B 弻 (<CJK Ideograph>) 2736 0x5F3D 弽 (<CJK Ideograph>) 2737 0x5F3E 弾 (<CJK Ideograph>) 2738 0x5F3F 弿 (<CJK Ideograph>) 2739 0x5F41 彁 (<CJK Ideograph>) 2740 0x5F42 彂 (<CJK Ideograph>) 2741 0x5F43 彃 (<CJK Ideograph>) 2742 0x5F44 彄 (<CJK Ideograph>) 2743 0x5F45 彅 (<CJK Ideograph>) 2744 0x5F46 彆 (<CJK Ideograph>) 2745 0x5F47 彇 (<CJK Ideograph>) 2746 0x5F48 彈 (<CJK Ideograph>) 2747 0x5F49 彉 (<CJK Ideograph>) 2748 0x5F4A 彊 (<CJK Ideograph>) 2749 0x5F4B 彋 (<CJK Ideograph>) 2750 0x5F4C 彌 (<CJK Ideograph>) 2751 0x5F4D 彍 (<CJK Ideograph>) 2752 0x5F4E 彎 (<CJK Ideograph>) 2753 0x5F4F 彏 (<CJK Ideograph>) 2754 0x5F51 彑 (<CJK Ideograph>) 2755 0x5F54 彔 (<CJK Ideograph>) 2756 0x5F59 彙 (<CJK Ideograph>) 2757 0x5F5A 彚 (<CJK Ideograph>) 2758 0x5F5B 彛 (<CJK Ideograph>) 2759 0x5F5C 彜 (<CJK Ideograph>) 2760 0x5F5E 彞 (<CJK Ideograph>) 2761 0x5F5F 彟 (<CJK Ideograph>) 2762 0x5F60 彠 (<CJK Ideograph>) 2763 0x5F63 彣 (<CJK Ideograph>) 2764 0x5F65 彥 (<CJK Ideograph>) 2765 0x5F67 彧 (<CJK Ideograph>) 2766 0x5F68 彨 (<CJK Ideograph>) 2767 0x5F6B 彫 (<CJK Ideograph>) 2768 0x5F6E 彮 (<CJK Ideograph>) 2769 0x5F6F 彯 (<CJK Ideograph>) 2770 0x5F72 彲 (<CJK Ideograph>) 2771 0x5F74 彴 (<CJK Ideograph>) 2772 0x5F75 彵 (<CJK Ideograph>) 2773 0x5F76 彶 (<CJK Ideograph>) 2774 0x5F78 彸 (<CJK Ideograph>) 2775 0x5F7A 彺 (<CJK Ideograph>) 2776 0x5F7D 彽 (<CJK Ideograph>) 2777 0x5F7E 彾 (<CJK Ideograph>) 2778 0x5F7F 彿 (<CJK Ideograph>) 2779 0x5F83 徃 (<CJK Ideograph>) 2780 0x5F86 徆 (<CJK Ideograph>) 2781 0x5F8D 徍 (<CJK Ideograph>) 2782 0x5F8E 徎 (<CJK Ideograph>) 2783 0x5F8F 徏 (<CJK Ideograph>) 2784 0x5F91 徑 (<CJK Ideograph>) 2785 0x5F93 従 (<CJK Ideograph>) 2786 0x5F94 徔 (<CJK Ideograph>) 2787 0x5F96 徖 (<CJK Ideograph>) 2788 0x5F9A 徚 (<CJK Ideograph>) 2789 0x5F9B 徛 (<CJK Ideograph>) 2790 0x5F9D 徝 (<CJK Ideograph>) 2791 0x5F9E 從 (<CJK Ideograph>) 2792 0x5F9F 徟 (<CJK Ideograph>) 2793 0x5FA0 徠 (<CJK Ideograph>) 2794 0x5FA2 徢 (<CJK Ideograph>) 2795 0x5FA3 徣 (<CJK Ideograph>) 2796 0x5FA4 徤 (<CJK Ideograph>) 2797 0x5FA5 徥 (<CJK Ideograph>) 2798 0x5FA6 徦 (<CJK Ideograph>) 2799 0x5FA7 徧 (<CJK Ideograph>) 2800 0x5FA9 復 (<CJK Ideograph>) 2801 0x5FAB 徫 (<CJK Ideograph>) 2802 0x5FAC 徬 (<CJK Ideograph>) 2803 0x5FAF 徯 (<CJK Ideograph>) 2804 0x5FB0 徰 (<CJK Ideograph>) 2805 0x5FB1 徱 (<CJK Ideograph>) 2806 0x5FB2 徲 (<CJK Ideograph>) 2807 0x5FB3 徳 (<CJK Ideograph>) 2808 0x5FB4 徴 (<CJK Ideograph>) 2809 0x5FB6 徶 (<CJK Ideograph>) 2810 0x5FB8 徸 (<CJK Ideograph>) 2811 0x5FB9 徹 (<CJK Ideograph>) 2812 0x5FBA 徺 (<CJK Ideograph>) 2813 0x5FBB 徻 (<CJK Ideograph>) 2814 0x5FBE 徾 (<CJK Ideograph>) 2815 0x5FBF 徿 (<CJK Ideograph>) 2816 0x5FC0 忀 (<CJK Ideograph>) 2817 0x5FC1 忁 (<CJK Ideograph>) 2818 0x5FC2 忂 (<CJK Ideograph>) 2819 0x5FC7 忇 (<CJK Ideograph>) 2820 0x5FC8 忈 (<CJK Ideograph>) 2821 0x5FCA 忊 (<CJK Ideograph>) 2822 0x5FCB 忋 (<CJK Ideograph>) 2823 0x5FCE 忎 (<CJK Ideograph>) 2824 0x5FD3 忓 (<CJK Ideograph>) 2825 0x5FD4 忔 (<CJK Ideograph>) 2826 0x5FD5 忕 (<CJK Ideograph>) 2827 0x5FDA 忚 (<CJK Ideograph>) 2828 0x5FDB 忛 (<CJK Ideograph>) 2829 0x5FDC 応 (<CJK Ideograph>) 2830 0x5FDE 忞 (<CJK Ideograph>) 2831 0x5FDF 忟 (<CJK Ideograph>) 2832 0x5FE2 忢 (<CJK Ideograph>) 2833 0x5FE3 忣 (<CJK Ideograph>) 2834 0x5FE5 忥 (<CJK Ideograph>) 2835 0x5FE6 忦 (<CJK Ideograph>) 2836 0x5FE8 忨 (<CJK Ideograph>) 2837 0x5FE9 忩 (<CJK Ideograph>) 2838 0x5FEC 忬 (<CJK Ideograph>) 2839 0x5FEF 忯 (<CJK Ideograph>) 2840 0x5FF0 忰 (<CJK Ideograph>) 2841 0x5FF2 忲 (<CJK Ideograph>) 2842 0x5FF3 忳 (<CJK Ideograph>) 2843 0x5FF4 忴 (<CJK Ideograph>) 2844 0x5FF6 忶 (<CJK Ideograph>) 2845 0x5FF7 忷 (<CJK Ideograph>) 2846 0x5FF9 忹 (<CJK Ideograph>) 2847 0x5FFA 忺 (<CJK Ideograph>) 2848 0x5FFC 忼 (<CJK Ideograph>) 2849 0x6007 怇 (<CJK Ideograph>) 2850 0x6008 怈 (<CJK Ideograph>) 2851 0x6009 怉 (<CJK Ideograph>) 2852 0x600B 怋 (<CJK Ideograph>) 2853 0x600C 怌 (<CJK Ideograph>) 2854 0x6010 怐 (<CJK Ideograph>) 2855 0x6011 怑 (<CJK Ideograph>) 2856 0x6013 怓 (<CJK Ideograph>) 2857 0x6017 怗 (<CJK Ideograph>) 2858 0x6018 怘 (<CJK Ideograph>) 2859 0x601A 怚 (<CJK Ideograph>) 2860 0x601E 怞 (<CJK Ideograph>) 2861 0x601F 怟 (<CJK Ideograph>) 2862 0x6022 怢 (<CJK Ideograph>) 2863 0x6023 怣 (<CJK Ideograph>) 2864 0x6024 怤 (<CJK Ideograph>) 2865 0x602C 怬 (<CJK Ideograph>) 2866 0x602D 怭 (<CJK Ideograph>) 2867 0x602E 怮 (<CJK Ideograph>) 2868 0x6030 怰 (<CJK Ideograph>) 2869 0x6031 怱 (<CJK Ideograph>) 2870 0x6032 怲 (<CJK Ideograph>) 2871 0x6033 怳 (<CJK Ideograph>) 2872 0x6034 怴 (<CJK Ideograph>) 2873 0x6036 怶 (<CJK Ideograph>) 2874 0x6037 怷 (<CJK Ideograph>) 2875 0x6038 怸 (<CJK Ideograph>) 2876 0x6039 怹 (<CJK Ideograph>) 2877 0x603A 怺 (<CJK Ideograph>) 2878 0x603D 怽 (<CJK Ideograph>) 2879 0x603E 怾 (<CJK Ideograph>) 2880 0x6040 恀 (<CJK Ideograph>) 2881 0x6044 恄 (<CJK Ideograph>) 2882 0x6045 恅 (<CJK Ideograph>) 2883 0x6046 恆 (<CJK Ideograph>) 2884 0x6047 恇 (<CJK Ideograph>) 2885 0x6048 恈 (<CJK Ideograph>) 2886 0x6049 恉 (<CJK Ideograph>) 2887 0x604A 恊 (<CJK Ideograph>) 2888 0x604C 恌 (<CJK Ideograph>) 2889 0x604E 恎 (<CJK Ideograph>) 2890 0x604F 恏 (<CJK Ideograph>) 2891 0x6051 恑 (<CJK Ideograph>) 2892 0x6053 恓 (<CJK Ideograph>) 2893 0x6054 恔 (<CJK Ideograph>) 2894 0x6056 恖 (<CJK Ideograph>) 2895 0x6057 恗 (<CJK Ideograph>) 2896 0x6058 恘 (<CJK Ideograph>) 2897 0x605B 恛 (<CJK Ideograph>) 2898 0x605C 恜 (<CJK Ideograph>) 2899 0x605E 恞 (<CJK Ideograph>) 2900 0x605F 恟 (<CJK Ideograph>) 2901 0x6060 恠 (<CJK Ideograph>) 2902 0x6061 恡 (<CJK Ideograph>) 2903 0x6065 恥 (<CJK Ideograph>) 2904 0x6066 恦 (<CJK Ideograph>) 2905 0x606E 恮 (<CJK Ideograph>) 2906 0x6071 恱 (<CJK Ideograph>) 2907 0x6072 恲 (<CJK Ideograph>) 2908 0x6074 恴 (<CJK Ideograph>) 2909 0x6075 恵 (<CJK Ideograph>) 2910 0x6077 恷 (<CJK Ideograph>) 2911 0x607E 恾 (<CJK Ideograph>) 2912 0x6080 悀 (<CJK Ideograph>) 2913 0x6081 悁 (<CJK Ideograph>) 2914 0x6082 悂 (<CJK Ideograph>) 2915 0x6085 悅 (<CJK Ideograph>) 2916 0x6086 悆 (<CJK Ideograph>) 2917 0x6087 悇 (<CJK Ideograph>) 2918 0x6088 悈 (<CJK Ideograph>) 2919 0x608A 悊 (<CJK Ideograph>) 2920 0x608B 悋 (<CJK Ideograph>) 2921 0x608E 悎 (<CJK Ideograph>) 2922 0x608F 悏 (<CJK Ideograph>) 2923 0x6090 悐 (<CJK Ideograph>) 2924 0x6091 悑 (<CJK Ideograph>) 2925 0x6093 悓 (<CJK Ideograph>) 2926 0x6095 悕 (<CJK Ideograph>) 2927 0x6097 悗 (<CJK Ideograph>) 2928 0x6098 悘 (<CJK Ideograph>) 2929 0x6099 悙 (<CJK Ideograph>) 2930 0x609C 悜 (<CJK Ideograph>) 2931 0x609E 悞 (<CJK Ideograph>) 2932 0x60A1 悡 (<CJK Ideograph>) 2933 0x60A2 悢 (<CJK Ideograph>) 2934 0x60A4 悤 (<CJK Ideograph>) 2935 0x60A5 悥 (<CJK Ideograph>) 2936 0x60A7 悧 (<CJK Ideograph>) 2937 0x60A9 悩 (<CJK Ideograph>) 2938 0x60AA 悪 (<CJK Ideograph>) 2939 0x60AE 悮 (<CJK Ideograph>) 2940 0x60B0 悰 (<CJK Ideograph>) 2941 0x60B3 悳 (<CJK Ideograph>) 2942 0x60B5 悵 (<CJK Ideograph>) 2943 0x60B6 悶 (<CJK Ideograph>) 2944 0x60B7 悷 (<CJK Ideograph>) 2945 0x60B9 悹 (<CJK Ideograph>) 2946 0x60BA 悺 (<CJK Ideograph>) 2947 0x60BD 悽 (<CJK Ideograph>) 2948 0x60BE 悾 (<CJK Ideograph>) 2949 0x60BF 悿 (<CJK Ideograph>) 2950 0x60C0 惀 (<CJK Ideograph>) 2951 0x60C1 惁 (<CJK Ideograph>) 2952 0x60C2 惂 (<CJK Ideograph>) 2953 0x60C3 惃 (<CJK Ideograph>) 2954 0x60C4 惄 (<CJK Ideograph>) 2955 0x60C7 惇 (<CJK Ideograph>) 2956 0x60C8 惈 (<CJK Ideograph>) 2957 0x60C9 惉 (<CJK Ideograph>) 2958 0x60CC 惌 (<CJK Ideograph>) 2959 0x60CD 惍 (<CJK Ideograph>) 2960 0x60CE 惎 (<CJK Ideograph>) 2961 0x60CF 惏 (<CJK Ideograph>) 2962 0x60D0 惐 (<CJK Ideograph>) 2963 0x60D2 惒 (<CJK Ideograph>) 2964 0x60D3 惓 (<CJK Ideograph>) 2965 0x60D4 惔 (<CJK Ideograph>) 2966 0x60D6 惖 (<CJK Ideograph>) 2967 0x60D7 惗 (<CJK Ideograph>) 2968 0x60D9 惙 (<CJK Ideograph>) 2969 0x60DB 惛 (<CJK Ideograph>) 2970 0x60DE 惞 (<CJK Ideograph>) 2971 0x60E1 惡 (<CJK Ideograph>) 2972 0x60E2 惢 (<CJK Ideograph>) 2973 0x60E3 惣 (<CJK Ideograph>) 2974 0x60E4 惤 (<CJK Ideograph>) 2975 0x60E5 惥 (<CJK Ideograph>) 2976 0x60EA 惪 (<CJK Ideograph>) 2977 0x60F1 惱 (<CJK Ideograph>) 2978 0x60F2 惲 (<CJK Ideograph>) 2979 0x60F5 惵 (<CJK Ideograph>) 2980 0x60F7 惷 (<CJK Ideograph>) 2981 0x60F8 惸 (<CJK Ideograph>) 2982 0x60FB 惻 (<CJK Ideograph>) 2983 0x60FC 惼 (<CJK Ideograph>) 2984 0x60FD 惽 (<CJK Ideograph>) 2985 0x60FE 惾 (<CJK Ideograph>) 2986 0x60FF 惿 (<CJK Ideograph>) 2987 0x6102 愂 (<CJK Ideograph>) 2988 0x6103 愃 (<CJK Ideograph>) 2989 0x6104 愄 (<CJK Ideograph>) 2990 0x6105 愅 (<CJK Ideograph>) 2991 0x6107 愇 (<CJK Ideograph>) 2992 0x610A 愊 (<CJK Ideograph>) 2993 0x610B 愋 (<CJK Ideograph>) 2994 0x610C 愌 (<CJK Ideograph>) 2995 0x6110 愐 (<CJK Ideograph>) 2996 0x6111 愑 (<CJK Ideograph>) 2997 0x6112 愒 (<CJK Ideograph>) 2998 0x6113 愓 (<CJK Ideograph>) 2999 0x6114 愔 (<CJK Ideograph>) 3000 0x6116 愖 (<CJK Ideograph>) 3001 0x6117 愗 (<CJK Ideograph>) 3002 0x6118 愘 (<CJK Ideograph>) 3003 0x6119 愙 (<CJK Ideograph>) 3004 0x611B 愛 (<CJK Ideograph>) 3005 0x611C 愜 (<CJK Ideograph>) 3006 0x611D 愝 (<CJK Ideograph>) 3007 0x611E 愞 (<CJK Ideograph>) 3008 0x6121 愡 (<CJK Ideograph>) 3009 0x6122 愢 (<CJK Ideograph>) 3010 0x6125 愥 (<CJK Ideograph>) 3011 0x6128 愨 (<CJK Ideograph>) 3012 0x6129 愩 (<CJK Ideograph>) 3013 0x612A 愪 (<CJK Ideograph>) 3014 0x612C 愬 (<CJK Ideograph>) 3015 0x612D 愭 (<CJK Ideograph>) 3016 0x612E 愮 (<CJK Ideograph>) 3017 0x612F 愯 (<CJK Ideograph>) 3018 0x6130 愰 (<CJK Ideograph>) 3019 0x6131 愱 (<CJK Ideograph>) 3020 0x6132 愲 (<CJK Ideograph>) 3021 0x6133 愳 (<CJK Ideograph>) 3022 0x6134 愴 (<CJK Ideograph>) 3023 0x6135 愵 (<CJK Ideograph>) 3024 0x6136 愶 (<CJK Ideograph>) 3025 0x6137 愷 (<CJK Ideograph>) 3026 0x6138 愸 (<CJK Ideograph>) 3027 0x6139 愹 (<CJK Ideograph>) 3028 0x613A 愺 (<CJK Ideograph>) 3029 0x613B 愻 (<CJK Ideograph>) 3030 0x613C 愼 (<CJK Ideograph>) 3031 0x613D 愽 (<CJK Ideograph>) 3032 0x613E 愾 (<CJK Ideograph>) 3033 0x6140 慀 (<CJK Ideograph>) 3034 0x6141 慁 (<CJK Ideograph>) 3035 0x6142 慂 (<CJK Ideograph>) 3036 0x6143 慃 (<CJK Ideograph>) 3037 0x6144 慄 (<CJK Ideograph>) 3038 0x6145 慅 (<CJK Ideograph>) 3039 0x6146 慆 (<CJK Ideograph>) 3040 0x6147 慇 (<CJK Ideograph>) 3041 0x6149 慉 (<CJK Ideograph>) 3042 0x614B 態 (<CJK Ideograph>) 3043 0x614D 慍 (<CJK Ideograph>) 3044 0x614F 慏 (<CJK Ideograph>) 3045 0x6150 慐 (<CJK Ideograph>) 3046 0x6152 慒 (<CJK Ideograph>) 3047 0x6153 慓 (<CJK Ideograph>) 3048 0x6154 慔 (<CJK Ideograph>) 3049 0x6156 慖 (<CJK Ideograph>) 3050 0x6157 慗 (<CJK Ideograph>) 3051 0x6158 慘 (<CJK Ideograph>) 3052 0x6159 慙 (<CJK Ideograph>) 3053 0x615A 慚 (<CJK Ideograph>) 3054 0x615B 慛 (<CJK Ideograph>) 3055 0x615C 慜 (<CJK Ideograph>) 3056 0x615E 慞 (<CJK Ideograph>) 3057 0x615F 慟 (<CJK Ideograph>) 3058 0x6160 慠 (<CJK Ideograph>) 3059 0x6161 慡 (<CJK Ideograph>) 3060 0x6163 慣 (<CJK Ideograph>) 3061 0x6164 慤 (<CJK Ideograph>) 3062 0x6165 慥 (<CJK Ideograph>) 3063 0x6166 慦 (<CJK Ideograph>) 3064 0x6169 慩 (<CJK Ideograph>) 3065 0x616A 慪 (<CJK Ideograph>) 3066 0x616B 慫 (<CJK Ideograph>) 3067 0x616C 慬 (<CJK Ideograph>) 3068 0x616D 慭 (<CJK Ideograph>) 3069 0x616E 慮 (<CJK Ideograph>) 3070 0x616F 慯 (<CJK Ideograph>) 3071 0x6171 慱 (<CJK Ideograph>) 3072 0x6172 慲 (<CJK Ideograph>) 3073 0x6173 慳 (<CJK Ideograph>) 3074 0x6174 慴 (<CJK Ideograph>) 3075 0x6176 慶 (<CJK Ideograph>) 3076 0x6178 慸 (<CJK Ideograph>) 3077 0x6179 慹 (<CJK Ideograph>) 3078 0x617A 慺 (<CJK Ideograph>) 3079 0x617B 慻 (<CJK Ideograph>) 3080 0x617C 慼 (<CJK Ideograph>) 3081 0x617D 慽 (<CJK Ideograph>) 3082 0x617E 慾 (<CJK Ideograph>) 3083 0x617F 慿 (<CJK Ideograph>) 3084 0x6180 憀 (<CJK Ideograph>) 3085 0x6181 憁 (<CJK Ideograph>) 3086 0x6182 憂 (<CJK Ideograph>) 3087 0x6183 憃 (<CJK Ideograph>) 3088 0x6184 憄 (<CJK Ideograph>) 3089 0x6185 憅 (<CJK Ideograph>) 3090 0x6186 憆 (<CJK Ideograph>) 3091 0x6187 憇 (<CJK Ideograph>) 3092 0x6188 憈 (<CJK Ideograph>) 3093 0x6189 憉 (<CJK Ideograph>) 3094 0x618A 憊 (<CJK Ideograph>) 3095 0x618C 憌 (<CJK Ideograph>) 3096 0x618D 憍 (<CJK Ideograph>) 3097 0x618F 憏 (<CJK Ideograph>) 3098 0x6190 憐 (<CJK Ideograph>) 3099 0x6191 憑 (<CJK Ideograph>) 3100 0x6192 憒 (<CJK Ideograph>) 3101 0x6193 憓 (<CJK Ideograph>) 3102 0x6195 憕 (<CJK Ideograph>) 3103 0x6196 憖 (<CJK Ideograph>) 3104 0x6197 憗 (<CJK Ideograph>) 3105 0x6198 憘 (<CJK Ideograph>) 3106 0x6199 憙 (<CJK Ideograph>) 3107 0x619A 憚 (<CJK Ideograph>) 3108 0x619B 憛 (<CJK Ideograph>) 3109 0x619C 憜 (<CJK Ideograph>) 3110 0x619E 憞 (<CJK Ideograph>) 3111 0x619F 憟 (<CJK Ideograph>) 3112 0x61A0 憠 (<CJK Ideograph>) 3113 0x61A1 憡 (<CJK Ideograph>) 3114 0x61A2 憢 (<CJK Ideograph>) 3115 0x61A3 憣 (<CJK Ideograph>) 3116 0x61A4 憤 (<CJK Ideograph>) 3117 0x61A5 憥 (<CJK Ideograph>) 3118 0x61A6 憦 (<CJK Ideograph>) 3119 0x61AA 憪 (<CJK Ideograph>) 3120 0x61AB 憫 (<CJK Ideograph>) 3121 0x61AD 憭 (<CJK Ideograph>) 3122 0x61AE 憮 (<CJK Ideograph>) 3123 0x61AF 憯 (<CJK Ideograph>) 3124 0x61B0 憰 (<CJK Ideograph>) 3125 0x61B1 憱 (<CJK Ideograph>) 3126 0x61B2 憲 (<CJK Ideograph>) 3127 0x61B3 憳 (<CJK Ideograph>) 3128 0x61B4 憴 (<CJK Ideograph>) 3129 0x61B5 憵 (<CJK Ideograph>) 3130 0x61B6 憶 (<CJK Ideograph>) 3131 0x61B8 憸 (<CJK Ideograph>) 3132 0x61B9 憹 (<CJK Ideograph>) 3133 0x61BA 憺 (<CJK Ideograph>) 3134 0x61BB 憻 (<CJK Ideograph>) 3135 0x61BC 憼 (<CJK Ideograph>) 3136 0x61BD 憽 (<CJK Ideograph>) 3137 0x61BF 憿 (<CJK Ideograph>) 3138 0x61C0 懀 (<CJK Ideograph>) 3139 0x61C1 懁 (<CJK Ideograph>) 3140 0x61C3 懃 (<CJK Ideograph>) 3141 0x61C4 懄 (<CJK Ideograph>) 3142 0x61C5 懅 (<CJK Ideograph>) 3143 0x61C6 懆 (<CJK Ideograph>) 3144 0x61C7 懇 (<CJK Ideograph>) 3145 0x61C9 應 (<CJK Ideograph>) 3146 0x61CC 懌 (<CJK Ideograph>) 3147 0x61CD 懍 (<CJK Ideograph>) 3148 0x61CE 懎 (<CJK Ideograph>) 3149 0x61CF 懏 (<CJK Ideograph>) 3150 0x61D0 懐 (<CJK Ideograph>) 3151 0x61D3 懓 (<CJK Ideograph>) 3152 0x61D5 懕 (<CJK Ideograph>) 3153 0x61D6 懖 (<CJK Ideograph>) 3154 0x61D7 懗 (<CJK Ideograph>) 3155 0x61D8 懘 (<CJK Ideograph>) 3156 0x61D9 懙 (<CJK Ideograph>) 3157 0x61DA 懚 (<CJK Ideograph>) 3158 0x61DB 懛 (<CJK Ideograph>) 3159 0x61DC 懜 (<CJK Ideograph>) 3160 0x61DD 懝 (<CJK Ideograph>) 3161 0x61DE 懞 (<CJK Ideograph>) 3162 0x61DF 懟 (<CJK Ideograph>) 3163 0x61E0 懠 (<CJK Ideograph>) 3164 0x61E1 懡 (<CJK Ideograph>) 3165 0x61E2 懢 (<CJK Ideograph>) 3166 0x61E3 懣 (<CJK Ideograph>) 3167 0x61E4 懤 (<CJK Ideograph>) 3168 0x61E5 懥 (<CJK Ideograph>) 3169 0x61E7 懧 (<CJK Ideograph>) 3170 0x61E8 懨 (<CJK Ideograph>) 3171 0x61E9 懩 (<CJK Ideograph>) 3172 0x61EA 懪 (<CJK Ideograph>) 3173 0x61EB 懫 (<CJK Ideograph>) 3174 0x61EC 懬 (<CJK Ideograph>) 3175 0x61ED 懭 (<CJK Ideograph>) 3176 0x61EE 懮 (<CJK Ideograph>) 3177 0x61EF 懯 (<CJK Ideograph>) 3178 0x61F0 懰 (<CJK Ideograph>) 3179 0x61F1 懱 (<CJK Ideograph>) 3180 0x61F2 懲 (<CJK Ideograph>) 3181 0x61F3 懳 (<CJK Ideograph>) 3182 0x61F4 懴 (<CJK Ideograph>) 3183 0x61F6 懶 (<CJK Ideograph>) 3184 0x61F7 懷 (<CJK Ideograph>) 3185 0x61F8 懸 (<CJK Ideograph>) 3186 0x61F9 懹 (<CJK Ideograph>) 3187 0x61FA 懺 (<CJK Ideograph>) 3188 0x61FB 懻 (<CJK Ideograph>) 3189 0x61FC 懼 (<CJK Ideograph>) 3190 0x61FD 懽 (<CJK Ideograph>) 3191 0x61FE 懾 (<CJK Ideograph>) 3192 0x6200 戀 (<CJK Ideograph>) 3193 0x6201 戁 (<CJK Ideograph>) 3194 0x6202 戂 (<CJK Ideograph>) 3195 0x6203 戃 (<CJK Ideograph>) 3196 0x6204 戄 (<CJK Ideograph>) 3197 0x6205 戅 (<CJK Ideograph>) 3198 0x6207 戇 (<CJK Ideograph>) 3199 0x6209 戉 (<CJK Ideograph>) 3200 0x6213 戓 (<CJK Ideograph>) 3201 0x6214 戔 (<CJK Ideograph>) 3202 0x6219 戙 (<CJK Ideograph>) 3203 0x621C 戜 (<CJK Ideograph>) 3204 0x621D 戝 (<CJK Ideograph>) 3205 0x621E 戞 (<CJK Ideograph>) 3206 0x6220 戠 (<CJK Ideograph>) 3207 0x6223 戣 (<CJK Ideograph>) 3208 0x6226 戦 (<CJK Ideograph>) 3209 0x6227 戧 (<CJK Ideograph>) 3210 0x6228 戨 (<CJK Ideograph>) 3211 0x6229 戩 (<CJK Ideograph>) 3212 0x622B 戫 (<CJK Ideograph>) 3213 0x622D 戭 (<CJK Ideograph>) 3214 0x622F 戯 (<CJK Ideograph>) 3215 0x6230 戰 (<CJK Ideograph>) 3216 0x6231 戱 (<CJK Ideograph>) 3217 0x6232 戲 (<CJK Ideograph>) 3218 0x6235 戵 (<CJK Ideograph>) 3219 0x6236 戶 (<CJK Ideograph>) 3220 0x6238 戸 (<CJK Ideograph>) 3221 0x6239 戹 (<CJK Ideograph>) 3222 0x623A 戺 (<CJK Ideograph>) 3223 0x623B 戻 (<CJK Ideograph>) 3224 0x623C 戼 (<CJK Ideograph>) 3225 0x6242 扂 (<CJK Ideograph>) 3226 0x6244 扄 (<CJK Ideograph>) 3227 0x6245 扅 (<CJK Ideograph>) 3228 0x6246 扆 (<CJK Ideograph>) 3229 0x624A 扊 (<CJK Ideograph>) 3230 0x624F 扏 (<CJK Ideograph>) 3231 0x6250 扐 (<CJK Ideograph>) 3232 0x6255 払 (<CJK Ideograph>) 3233 0x6256 扖 (<CJK Ideograph>) 3234 0x6257 扗 (<CJK Ideograph>) 3235 0x6259 扙 (<CJK Ideograph>) 3236 0x625A 扚 (<CJK Ideograph>) 3237 0x625C 扜 (<CJK Ideograph>) 3238 0x625D 扝 (<CJK Ideograph>) 3239 0x625E 扞 (<CJK Ideograph>) 3240 0x625F 扟 (<CJK Ideograph>) 3241 0x6260 扠 (<CJK Ideograph>) 3242 0x6261 扡 (<CJK Ideograph>) 3243 0x6262 扢 (<CJK Ideograph>) 3244 0x6264 扤 (<CJK Ideograph>) 3245 0x6265 扥 (<CJK Ideograph>) 3246 0x6268 扨 (<CJK Ideograph>) 3247 0x6271 扱 (<CJK Ideograph>) 3248 0x6272 扲 (<CJK Ideograph>) 3249 0x6274 扴 (<CJK Ideograph>) 3250 0x6275 扵 (<CJK Ideograph>) 3251 0x6277 扷 (<CJK Ideograph>) 3252 0x6278 扸 (<CJK Ideograph>) 3253 0x627A 扺 (<CJK Ideograph>) 3254 0x627B 扻 (<CJK Ideograph>) 3255 0x627D 扽 (<CJK Ideograph>) 3256 0x6281 抁 (<CJK Ideograph>) 3257 0x6282 抂 (<CJK Ideograph>) 3258 0x6283 抃 (<CJK Ideograph>) 3259 0x6285 抅 (<CJK Ideograph>) 3260 0x6286 抆 (<CJK Ideograph>) 3261 0x6287 抇 (<CJK Ideograph>) 3262 0x6288 抈 (<CJK Ideograph>) 3263 0x628B 抋 (<CJK Ideograph>) 3264 0x628C 抌 (<CJK Ideograph>) 3265 0x628D 抍 (<CJK Ideograph>) 3266 0x628E 抎 (<CJK Ideograph>) 3267 0x628F 抏 (<CJK Ideograph>) 3268 0x6290 抐 (<CJK Ideograph>) 3269 0x6294 抔 (<CJK Ideograph>) 3270 0x6299 抙 (<CJK Ideograph>) 3271 0x629C 抜 (<CJK Ideograph>) 3272 0x629D 抝 (<CJK Ideograph>) 3273 0x629E 択 (<CJK Ideograph>) 3274 0x62A3 抣 (<CJK Ideograph>) 3275 0x62A6 抦 (<CJK Ideograph>) 3276 0x62A7 抧 (<CJK Ideograph>) 3277 0x62A9 抩 (<CJK Ideograph>) 3278 0x62AA 抪 (<CJK Ideograph>) 3279 0x62AD 抭 (<CJK Ideograph>) 3280 0x62AE 抮 (<CJK Ideograph>) 3281 0x62AF 抯 (<CJK Ideograph>) 3282 0x62B0 抰 (<CJK Ideograph>) 3283 0x62B2 抲 (<CJK Ideograph>) 3284 0x62B3 抳 (<CJK Ideograph>) 3285 0x62B4 抴 (<CJK Ideograph>) 3286 0x62B6 抶 (<CJK Ideograph>) 3287 0x62B7 抷 (<CJK Ideograph>) 3288 0x62B8 抸 (<CJK Ideograph>) 3289 0x62BA 抺 (<CJK Ideograph>) 3290 0x62BE 抾 (<CJK Ideograph>) 3291 0x62C0 拀 (<CJK Ideograph>) 3292 0x62C1 拁 (<CJK Ideograph>) 3293 0x62C3 拃 (<CJK Ideograph>) 3294 0x62CB 拋 (<CJK Ideograph>) 3295 0x62CF 拏 (<CJK Ideograph>) 3296 0x62D1 拑 (<CJK Ideograph>) 3297 0x62D5 拕 (<CJK Ideograph>) 3298 0x62DD 拝 (<CJK Ideograph>) 3299 0x62DE 拞 (<CJK Ideograph>) 3300 0x62E0 拠 (<CJK Ideograph>) 3301 0x62E1 拡 (<CJK Ideograph>) 3302 0x62E4 拤 (<CJK Ideograph>) 3303 0x62EA 拪 (<CJK Ideograph>) 3304 0x62EB 拫 (<CJK Ideograph>) 3305 0x62F0 拰 (<CJK Ideograph>) 3306 0x62F2 拲 (<CJK Ideograph>) 3307 0x62F5 拵 (<CJK Ideograph>) 3308 0x62F8 拸 (<CJK Ideograph>) 3309 0x62F9 拹 (<CJK Ideograph>) 3310 0x62FA 拺 (<CJK Ideograph>) 3311 0x62FB 拻 (<CJK Ideograph>) 3312 0x6300 挀 (<CJK Ideograph>) 3313 0x6303 挃 (<CJK Ideograph>) 3314 0x6304 挄 (<CJK Ideograph>) 3315 0x6305 挅 (<CJK Ideograph>) 3316 0x6306 挆 (<CJK Ideograph>) 3317 0x630A 挊 (<CJK Ideograph>) 3318 0x630B 挋 (<CJK Ideograph>) 3319 0x630C 挌 (<CJK Ideograph>) 3320 0x630D 挍 (<CJK Ideograph>) 3321 0x630F 挏 (<CJK Ideograph>) 3322 0x6310 挐 (<CJK Ideograph>) 3323 0x6312 挒 (<CJK Ideograph>) 3324 0x6313 挓 (<CJK Ideograph>) 3325 0x6314 挔 (<CJK Ideograph>) 3326 0x6315 挕 (<CJK Ideograph>) 3327 0x6317 挗 (<CJK Ideograph>) 3328 0x6318 挘 (<CJK Ideograph>) 3329 0x6319 挙 (<CJK Ideograph>) 3330 0x631C 挜 (<CJK Ideograph>) 3331 0x6326 挦 (<CJK Ideograph>) 3332 0x6327 挧 (<CJK Ideograph>) 3333 0x6329 挩 (<CJK Ideograph>) 3334 0x632C 挬 (<CJK Ideograph>) 3335 0x632D 挭 (<CJK Ideograph>) 3336 0x632E 挮 (<CJK Ideograph>) 3337 0x6330 挰 (<CJK Ideograph>) 3338 0x6331 挱 (<CJK Ideograph>) 3339 0x6333 挳 (<CJK Ideograph>) 3340 0x6334 挴 (<CJK Ideograph>) 3341 0x6335 挵 (<CJK Ideograph>) 3342 0x6336 挶 (<CJK Ideograph>) 3343 0x6337 挷 (<CJK Ideograph>) 3344 0x6338 挸 (<CJK Ideograph>) 3345 0x633B 挻 (<CJK Ideograph>) 3346 0x633C 挼 (<CJK Ideograph>) 3347 0x633E 挾 (<CJK Ideograph>) 3348 0x633F 挿 (<CJK Ideograph>) 3349 0x6340 捀 (<CJK Ideograph>) 3350 0x6341 捁 (<CJK Ideograph>) 3351 0x6344 捄 (<CJK Ideograph>) 3352 0x6347 捇 (<CJK Ideograph>) 3353 0x6348 捈 (<CJK Ideograph>) 3354 0x634A 捊 (<CJK Ideograph>) 3355 0x6351 捑 (<CJK Ideograph>) 3356 0x6352 捒 (<CJK Ideograph>) 3357 0x6353 捓 (<CJK Ideograph>) 3358 0x6354 捔 (<CJK Ideograph>) 3359 0x6356 捖 (<CJK Ideograph>) 3360 0x6357 捗 (<CJK Ideograph>) 3361 0x6358 捘 (<CJK Ideograph>) 3362 0x6359 捙 (<CJK Ideograph>) 3363 0x635A 捚 (<CJK Ideograph>) 3364 0x635B 捛 (<CJK Ideograph>) 3365 0x635C 捜 (<CJK Ideograph>) 3366 0x635D 捝 (<CJK Ideograph>) 3367 0x6360 捠 (<CJK Ideograph>) 3368 0x6364 捤 (<CJK Ideograph>) 3369 0x6365 捥 (<CJK Ideograph>) 3370 0x6366 捦 (<CJK Ideograph>) 3371 0x6368 捨 (<CJK Ideograph>) 3372 0x636A 捪 (<CJK Ideograph>) 3373 0x636B 捫 (<CJK Ideograph>) 3374 0x636C 捬 (<CJK Ideograph>) 3375 0x636F 捯 (<CJK Ideograph>) 3376 0x6370 捰 (<CJK Ideograph>) 3377 0x6372 捲 (<CJK Ideograph>) 3378 0x6373 捳 (<CJK Ideograph>) 3379 0x6374 捴 (<CJK Ideograph>) 3380 0x6375 捵 (<CJK Ideograph>) 3381 0x6378 捸 (<CJK Ideograph>) 3382 0x6379 捹 (<CJK Ideograph>) 3383 0x637C 捼 (<CJK Ideograph>) 3384 0x637D 捽 (<CJK Ideograph>) 3385 0x637E 捾 (<CJK Ideograph>) 3386 0x637F 捿 (<CJK Ideograph>) 3387 0x6381 掁 (<CJK Ideograph>) 3388 0x6383 掃 (<CJK Ideograph>) 3389 0x6384 掄 (<CJK Ideograph>) 3390 0x6385 掅 (<CJK Ideograph>) 3391 0x6386 掆 (<CJK Ideograph>) 3392 0x638B 掋 (<CJK Ideograph>) 3393 0x638D 掍 (<CJK Ideograph>) 3394 0x6391 掑 (<CJK Ideograph>) 3395 0x6393 掓 (<CJK Ideograph>) 3396 0x6394 掔 (<CJK Ideograph>) 3397 0x6395 掕 (<CJK Ideograph>) 3398 0x6397 掗 (<CJK Ideograph>) 3399 0x6399 掙 (<CJK Ideograph>) 3400 0x639A 掚 (<CJK Ideograph>) 3401 0x639B 掛 (<CJK Ideograph>) 3402 0x639C 掜 (<CJK Ideograph>) 3403 0x639D 掝 (<CJK Ideograph>) 3404 0x639E 掞 (<CJK Ideograph>) 3405 0x639F 掟 (<CJK Ideograph>) 3406 0x63A1 採 (<CJK Ideograph>) 3407 0x63A4 掤 (<CJK Ideograph>) 3408 0x63A6 掦 (<CJK Ideograph>) 3409 0x63AB 掫 (<CJK Ideograph>) 3410 0x63AF 掯 (<CJK Ideograph>) 3411 0x63B1 掱 (<CJK Ideograph>) 3412 0x63B2 掲 (<CJK Ideograph>) 3413 0x63B5 掵 (<CJK Ideograph>) 3414 0x63B6 掶 (<CJK Ideograph>) 3415 0x63B9 掹 (<CJK Ideograph>) 3416 0x63BB 掻 (<CJK Ideograph>) 3417 0x63BD 掽 (<CJK Ideograph>) 3418 0x63BF 掿 (<CJK Ideograph>) 3419 0x63C0 揀 (<CJK Ideograph>) 3420 0x63C1 揁 (<CJK Ideograph>) 3421 0x63C2 揂 (<CJK Ideograph>) 3422 0x63C3 揃 (<CJK Ideograph>) 3423 0x63C5 揅 (<CJK Ideograph>) 3424 0x63C7 揇 (<CJK Ideograph>) 3425 0x63C8 揈 (<CJK Ideograph>) 3426 0x63CA 揊 (<CJK Ideograph>) 3427 0x63CB 揋 (<CJK Ideograph>) 3428 0x63CC 揌 (<CJK Ideograph>) 3429 0x63D1 揑 (<CJK Ideograph>) 3430 0x63D3 揓 (<CJK Ideograph>) 3431 0x63D4 揔 (<CJK Ideograph>) 3432 0x63D5 揕 (<CJK Ideograph>) 3433 0x63D7 揗 (<CJK Ideograph>) 3434 0x63D8 揘 (<CJK Ideograph>) 3435 0x63D9 揙 (<CJK Ideograph>) 3436 0x63DA 揚 (<CJK Ideograph>) 3437 0x63DB 換 (<CJK Ideograph>) 3438 0x63DC 揜 (<CJK Ideograph>) 3439 0x63DD 揝 (<CJK Ideograph>) 3440 0x63DF 揟 (<CJK Ideograph>) 3441 0x63E2 揢 (<CJK Ideograph>) 3442 0x63E4 揤 (<CJK Ideograph>) 3443 0x63E5 揥 (<CJK Ideograph>) 3444 0x63E6 揦 (<CJK Ideograph>) 3445 0x63E7 揧 (<CJK Ideograph>) 3446 0x63E8 揨 (<CJK Ideograph>) 3447 0x63EB 揫 (<CJK Ideograph>) 3448 0x63EC 揬 (<CJK Ideograph>) 3449 0x63EE 揮 (<CJK Ideograph>) 3450 0x63EF 揯 (<CJK Ideograph>) 3451 0x63F0 揰 (<CJK Ideograph>) 3452 0x63F1 揱 (<CJK Ideograph>) 3453 0x63F3 揳 (<CJK Ideograph>) 3454 0x63F5 揵 (<CJK Ideograph>) 3455 0x63F7 揷 (<CJK Ideograph>) 3456 0x63F9 揹 (<CJK Ideograph>) 3457 0x63FA 揺 (<CJK Ideograph>) 3458 0x63FB 揻 (<CJK Ideograph>) 3459 0x63FC 揼 (<CJK Ideograph>) 3460 0x63FE 揾 (<CJK Ideograph>) 3461 0x6403 搃 (<CJK Ideograph>) 3462 0x6404 搄 (<CJK Ideograph>) 3463 0x6406 搆 (<CJK Ideograph>) 3464 0x6407 搇 (<CJK Ideograph>) 3465 0x6408 搈 (<CJK Ideograph>) 3466 0x6409 搉 (<CJK Ideograph>) 3467 0x640A 搊 (<CJK Ideograph>) 3468 0x640D 損 (<CJK Ideograph>) 3469 0x640E 搎 (<CJK Ideograph>) 3470 0x6411 搑 (<CJK Ideograph>) 3471 0x6412 搒 (<CJK Ideograph>) 3472 0x6415 搕 (<CJK Ideograph>) 3473 0x6416 搖 (<CJK Ideograph>) 3474 0x6417 搗 (<CJK Ideograph>) 3475 0x6418 搘 (<CJK Ideograph>) 3476 0x6419 搙 (<CJK Ideograph>) 3477 0x641A 搚 (<CJK Ideograph>) 3478 0x641D 搝 (<CJK Ideograph>) 3479 0x641F 搟 (<CJK Ideograph>) 3480 0x6422 搢 (<CJK Ideograph>) 3481 0x6423 搣 (<CJK Ideograph>) 3482 0x6424 搤 (<CJK Ideograph>) 3483 0x6425 搥 (<CJK Ideograph>) 3484 0x6427 搧 (<CJK Ideograph>) 3485 0x6428 搨 (<CJK Ideograph>) 3486 0x6429 搩 (<CJK Ideograph>) 3487 0x642B 搫 (<CJK Ideograph>) 3488 0x642E 搮 (<CJK Ideograph>) 3489 0x642F 搯 (<CJK Ideograph>) 3490 0x6430 搰 (<CJK Ideograph>) 3491 0x6431 搱 (<CJK Ideograph>) 3492 0x6432 搲 (<CJK Ideograph>) 3493 0x6433 搳 (<CJK Ideograph>) 3494 0x6435 搵 (<CJK Ideograph>) 3495 0x6436 搶 (<CJK Ideograph>) 3496 0x6437 搷 (<CJK Ideograph>) 3497 0x6438 搸 (<CJK Ideograph>) 3498 0x6439 搹 (<CJK Ideograph>) 3499 0x643B 搻 (<CJK Ideograph>) 3500 0x643C 搼 (<CJK Ideograph>) 3501 0x643E 搾 (<CJK Ideograph>) 3502 0x6440 摀 (<CJK Ideograph>) 3503 0x6442 摂 (<CJK Ideograph>) 3504 0x6443 摃 (<CJK Ideograph>) 3505 0x6449 摉 (<CJK Ideograph>) 3506 0x644B 摋 (<CJK Ideograph>) 3507 0x644C 摌 (<CJK Ideograph>) 3508 0x644D 摍 (<CJK Ideograph>) 3509 0x644E 摎 (<CJK Ideograph>) 3510 0x644F 摏 (<CJK Ideograph>) 3511 0x6450 摐 (<CJK Ideograph>) 3512 0x6451 摑 (<CJK Ideograph>) 3513 0x6453 摓 (<CJK Ideograph>) 3514 0x6455 摕 (<CJK Ideograph>) 3515 0x6456 摖 (<CJK Ideograph>) 3516 0x6457 摗 (<CJK Ideograph>) 3517 0x6459 摙 (<CJK Ideograph>) 3518 0x645A 摚 (<CJK Ideograph>) 3519 0x645B 摛 (<CJK Ideograph>) 3520 0x645C 摜 (<CJK Ideograph>) 3521 0x645D 摝 (<CJK Ideograph>) 3522 0x645F 摟 (<CJK Ideograph>) 3523 0x6460 摠 (<CJK Ideograph>) 3524 0x6461 摡 (<CJK Ideograph>) 3525 0x6462 摢 (<CJK Ideograph>) 3526 0x6463 摣 (<CJK Ideograph>) 3527 0x6464 摤 (<CJK Ideograph>) 3528 0x6465 摥 (<CJK Ideograph>) 3529 0x6466 摦 (<CJK Ideograph>) 3530 0x6468 摨 (<CJK Ideograph>) 3531 0x646A 摪 (<CJK Ideograph>) 3532 0x646B 摫 (<CJK Ideograph>) 3533 0x646C 摬 (<CJK Ideograph>) 3534 0x646E 摮 (<CJK Ideograph>) 3535 0x646F 摯 (<CJK Ideograph>) 3536 0x6470 摰 (<CJK Ideograph>) 3537 0x6471 摱 (<CJK Ideograph>) 3538 0x6472 摲 (<CJK Ideograph>) 3539 0x6473 摳 (<CJK Ideograph>) 3540 0x6474 摴 (<CJK Ideograph>) 3541 0x6475 摵 (<CJK Ideograph>) 3542 0x6476 摶 (<CJK Ideograph>) 3543 0x6477 摷 (<CJK Ideograph>) 3544 0x647B 摻 (<CJK Ideograph>) 3545 0x647C 摼 (<CJK Ideograph>) 3546 0x647D 摽 (<CJK Ideograph>) 3547 0x647E 摾 (<CJK Ideograph>) 3548 0x647F 摿 (<CJK Ideograph>) 3549 0x6480 撀 (<CJK Ideograph>) 3550 0x6481 撁 (<CJK Ideograph>) 3551 0x6483 撃 (<CJK Ideograph>) 3552 0x6486 撆 (<CJK Ideograph>) 3553 0x6488 撈 (<CJK Ideograph>) 3554 0x6489 撉 (<CJK Ideograph>) 3555 0x648A 撊 (<CJK Ideograph>) 3556 0x648B 撋 (<CJK Ideograph>) 3557 0x648C 撌 (<CJK Ideograph>) 3558 0x648D 撍 (<CJK Ideograph>) 3559 0x648E 撎 (<CJK Ideograph>) 3560 0x648F 撏 (<CJK Ideograph>) 3561 0x6490 撐 (<CJK Ideograph>) 3562 0x6493 撓 (<CJK Ideograph>) 3563 0x6494 撔 (<CJK Ideograph>) 3564 0x6497 撗 (<CJK Ideograph>) 3565 0x6498 撘 (<CJK Ideograph>) 3566 0x649A 撚 (<CJK Ideograph>) 3567 0x649B 撛 (<CJK Ideograph>) 3568 0x649C 撜 (<CJK Ideograph>) 3569 0x649D 撝 (<CJK Ideograph>) 3570 0x649F 撟 (<CJK Ideograph>) 3571 0x64A0 撠 (<CJK Ideograph>) 3572 0x64A1 撡 (<CJK Ideograph>) 3573 0x64A2 撢 (<CJK Ideograph>) 3574 0x64A3 撣 (<CJK Ideograph>) 3575 0x64A5 撥 (<CJK Ideograph>) 3576 0x64A6 撦 (<CJK Ideograph>) 3577 0x64A7 撧 (<CJK Ideograph>) 3578 0x64A8 撨 (<CJK Ideograph>) 3579 0x64AA 撪 (<CJK Ideograph>) 3580 0x64AB 撫 (<CJK Ideograph>) 3581 0x64AF 撯 (<CJK Ideograph>) 3582 0x64B1 撱 (<CJK Ideograph>) 3583 0x64B2 撲 (<CJK Ideograph>) 3584 0x64B3 撳 (<CJK Ideograph>) 3585 0x64B4 撴 (<CJK Ideograph>) 3586 0x64B6 撶 (<CJK Ideograph>) 3587 0x64B9 撹 (<CJK Ideograph>) 3588 0x64BB 撻 (<CJK Ideograph>) 3589 0x64BD 撽 (<CJK Ideograph>) 3590 0x64BE 撾 (<CJK Ideograph>) 3591 0x64BF 撿 (<CJK Ideograph>) 3592 0x64C1 擁 (<CJK Ideograph>) 3593 0x64C3 擃 (<CJK Ideograph>) 3594 0x64C4 擄 (<CJK Ideograph>) 3595 0x64C6 擆 (<CJK Ideograph>) 3596 0x64C7 擇 (<CJK Ideograph>) 3597 0x64C8 擈 (<CJK Ideograph>) 3598 0x64C9 擉 (<CJK Ideograph>) 3599 0x64CA 擊 (<CJK Ideograph>) 3600 0x64CB 擋 (<CJK Ideograph>) 3601 0x64CC 擌 (<CJK Ideograph>) 3602 0x64CF 擏 (<CJK Ideograph>) 3603 0x64D1 擑 (<CJK Ideograph>) 3604 0x64D3 擓 (<CJK Ideograph>) 3605 0x64D4 擔 (<CJK Ideograph>) 3606 0x64D5 擕 (<CJK Ideograph>) 3607 0x64D6 擖 (<CJK Ideograph>) 3608 0x64D9 擙 (<CJK Ideograph>) 3609 0x64DA 據 (<CJK Ideograph>) 3610 0x64DB 擛 (<CJK Ideograph>) 3611 0x64DC 擜 (<CJK Ideograph>) 3612 0x64DD 擝 (<CJK Ideograph>) 3613 0x64DF 擟 (<CJK Ideograph>) 3614 0x64E0 擠 (<CJK Ideograph>) 3615 0x64E1 擡 (<CJK Ideograph>) 3616 0x64E3 擣 (<CJK Ideograph>) 3617 0x64E5 擥 (<CJK Ideograph>) 3618 0x64E7 擧 (<CJK Ideograph>) 3619 0x64E8 擨 (<CJK Ideograph>) 3620 0x64E9 擩 (<CJK Ideograph>) 3621 0x64EA 擪 (<CJK Ideograph>) 3622 0x64EB 擫 (<CJK Ideograph>) 3623 0x64EC 擬 (<CJK Ideograph>) 3624 0x64ED 擭 (<CJK Ideograph>) 3625 0x64EE 擮 (<CJK Ideograph>) 3626 0x64EF 擯 (<CJK Ideograph>) 3627 0x64F0 擰 (<CJK Ideograph>) 3628 0x64F1 擱 (<CJK Ideograph>) 3629 0x64F2 擲 (<CJK Ideograph>) 3630 0x64F3 擳 (<CJK Ideograph>) 3631 0x64F4 擴 (<CJK Ideograph>) 3632 0x64F5 擵 (<CJK Ideograph>) 3633 0x64F6 擶 (<CJK Ideograph>) 3634 0x64F7 擷 (<CJK Ideograph>) 3635 0x64F8 擸 (<CJK Ideograph>) 3636 0x64F9 擹 (<CJK Ideograph>) 3637 0x64FA 擺 (<CJK Ideograph>) 3638 0x64FB 擻 (<CJK Ideograph>) 3639 0x64FC 擼 (<CJK Ideograph>) 3640 0x64FD 擽 (<CJK Ideograph>) 3641 0x64FE 擾 (<CJK Ideograph>) 3642 0x64FF 擿 (<CJK Ideograph>) 3643 0x6501 攁 (<CJK Ideograph>) 3644 0x6502 攂 (<CJK Ideograph>) 3645 0x6503 攃 (<CJK Ideograph>) 3646 0x6504 攄 (<CJK Ideograph>) 3647 0x6505 攅 (<CJK Ideograph>) 3648 0x6506 攆 (<CJK Ideograph>) 3649 0x6507 攇 (<CJK Ideograph>) 3650 0x6508 攈 (<CJK Ideograph>) 3651 0x650A 攊 (<CJK Ideograph>) 3652 0x650B 攋 (<CJK Ideograph>) 3653 0x650C 攌 (<CJK Ideograph>) 3654 0x650D 攍 (<CJK Ideograph>) 3655 0x650E 攎 (<CJK Ideograph>) 3656 0x650F 攏 (<CJK Ideograph>) 3657 0x6510 攐 (<CJK Ideograph>) 3658 0x6511 攑 (<CJK Ideograph>) 3659 0x6513 攓 (<CJK Ideograph>) 3660 0x6514 攔 (<CJK Ideograph>) 3661 0x6515 攕 (<CJK Ideograph>) 3662 0x6516 攖 (<CJK Ideograph>) 3663 0x6517 攗 (<CJK Ideograph>) 3664 0x6519 攙 (<CJK Ideograph>) 3665 0x651A 攚 (<CJK Ideograph>) 3666 0x651B 攛 (<CJK Ideograph>) 3667 0x651C 攜 (<CJK Ideograph>) 3668 0x651D 攝 (<CJK Ideograph>) 3669 0x651E 攞 (<CJK Ideograph>) 3670 0x651F 攟 (<CJK Ideograph>) 3671 0x6520 攠 (<CJK Ideograph>) 3672 0x6521 攡 (<CJK Ideograph>) 3673 0x6522 攢 (<CJK Ideograph>) 3674 0x6523 攣 (<CJK Ideograph>) 3675 0x6524 攤 (<CJK Ideograph>) 3676 0x6526 攦 (<CJK Ideograph>) 3677 0x6527 攧 (<CJK Ideograph>) 3678 0x6528 攨 (<CJK Ideograph>) 3679 0x6529 攩 (<CJK Ideograph>) 3680 0x652A 攪 (<CJK Ideograph>) 3681 0x652C 攬 (<CJK Ideograph>) 3682 0x652D 攭 (<CJK Ideograph>) 3683 0x6530 攰 (<CJK Ideograph>) 3684 0x6531 攱 (<CJK Ideograph>) 3685 0x6532 攲 (<CJK Ideograph>) 3686 0x6533 攳 (<CJK Ideograph>) 3687 0x6537 攷 (<CJK Ideograph>) 3688 0x653A 攺 (<CJK Ideograph>) 3689 0x653C 攼 (<CJK Ideograph>) 3690 0x653D 攽 (<CJK Ideograph>) 3691 0x6540 敀 (<CJK Ideograph>) 3692 0x6541 敁 (<CJK Ideograph>) 3693 0x6542 敂 (<CJK Ideograph>) 3694 0x6543 敃 (<CJK Ideograph>) 3695 0x6544 敄 (<CJK Ideograph>) 3696 0x6546 敆 (<CJK Ideograph>) 3697 0x6547 敇 (<CJK Ideograph>) 3698 0x654A 敊 (<CJK Ideograph>) 3699 0x654B 敋 (<CJK Ideograph>) 3700 0x654D 敍 (<CJK Ideograph>) 3701 0x654E 敎 (<CJK Ideograph>) 3702 0x6550 敐 (<CJK Ideograph>) 3703 0x6552 敒 (<CJK Ideograph>) 3704 0x6553 敓 (<CJK Ideograph>) 3705 0x6554 敔 (<CJK Ideograph>) 3706 0x6557 敗 (<CJK Ideograph>) 3707 0x6558 敘 (<CJK Ideograph>) 3708 0x655A 敚 (<CJK Ideograph>) 3709 0x655C 敜 (<CJK Ideograph>) 3710 0x655F 敟 (<CJK Ideograph>) 3711 0x6560 敠 (<CJK Ideograph>) 3712 0x6561 敡 (<CJK Ideograph>) 3713 0x6564 敤 (<CJK Ideograph>) 3714 0x6565 敥 (<CJK Ideograph>) 3715 0x6567 敧 (<CJK Ideograph>) 3716 0x6568 敨 (<CJK Ideograph>) 3717 0x6569 敩 (<CJK Ideograph>) 3718 0x656A 敪 (<CJK Ideograph>) 3719 0x656D 敭 (<CJK Ideograph>) 3720 0x656E 敮 (<CJK Ideograph>) 3721 0x656F 敯 (<CJK Ideograph>) 3722 0x6571 敱 (<CJK Ideograph>) 3723 0x6573 敳 (<CJK Ideograph>) 3724 0x6575 敵 (<CJK Ideograph>) 3725 0x6576 敶 (<CJK Ideograph>) 3726 0x6578 數 (<CJK Ideograph>) 3727 0x6579 敹 (<CJK Ideograph>) 3728 0x657A 敺 (<CJK Ideograph>) 3729 0x657B 敻 (<CJK Ideograph>) 3730 0x657C 敼 (<CJK Ideograph>) 3731 0x657D 敽 (<CJK Ideograph>) 3732 0x657E 敾 (<CJK Ideograph>) 3733 0x657F 敿 (<CJK Ideograph>) 3734 0x6580 斀 (<CJK Ideograph>) 3735 0x6581 斁 (<CJK Ideograph>) 3736 0x6582 斂 (<CJK Ideograph>) 3737 0x6583 斃 (<CJK Ideograph>) 3738 0x6584 斄 (<CJK Ideograph>) 3739 0x6585 斅 (<CJK Ideograph>) 3740 0x6586 斆 (<CJK Ideograph>) 3741 0x6588 斈 (<CJK Ideograph>) 3742 0x6589 斉 (<CJK Ideograph>) 3743 0x658A 斊 (<CJK Ideograph>) 3744 0x658D 斍 (<CJK Ideograph>) 3745 0x658E 斎 (<CJK Ideograph>) 3746 0x658F 斏 (<CJK Ideograph>) 3747 0x6592 斒 (<CJK Ideograph>) 3748 0x6594 斔 (<CJK Ideograph>) 3749 0x6595 斕 (<CJK Ideograph>) 3750 0x6596 斖 (<CJK Ideograph>) 3751 0x6598 斘 (<CJK Ideograph>) 3752 0x659A 斚 (<CJK Ideograph>) 3753 0x659D 斝 (<CJK Ideograph>) 3754 0x659E 斞 (<CJK Ideograph>) 3755 0x65A0 斠 (<CJK Ideograph>) 3756 0x65A2 斢 (<CJK Ideograph>) 3757 0x65A3 斣 (<CJK Ideograph>) 3758 0x65A6 斦 (<CJK Ideograph>) 3759 0x65A8 斨 (<CJK Ideograph>) 3760 0x65AA 斪 (<CJK Ideograph>) 3761 0x65AC 斬 (<CJK Ideograph>) 3762 0x65AE 斮 (<CJK Ideograph>) 3763 0x65B1 斱 (<CJK Ideograph>) 3764 0x65B2 斲 (<CJK Ideograph>) 3765 0x65B3 斳 (<CJK Ideograph>) 3766 0x65B4 斴 (<CJK Ideograph>) 3767 0x65B5 斵 (<CJK Ideograph>) 3768 0x65B6 斶 (<CJK Ideograph>) 3769 0x65B7 斷 (<CJK Ideograph>) 3770 0x65B8 斸 (<CJK Ideograph>) 3771 0x65BA 斺 (<CJK Ideograph>) 3772 0x65BB 斻 (<CJK Ideograph>) 3773 0x65BE 斾 (<CJK Ideograph>) 3774 0x65BF 斿 (<CJK Ideograph>) 3775 0x65C0 旀 (<CJK Ideograph>) 3776 0x65C2 旂 (<CJK Ideograph>) 3777 0x65C7 旇 (<CJK Ideograph>) 3778 0x65C8 旈 (<CJK Ideograph>) 3779 0x65C9 旉 (<CJK Ideograph>) 3780 0x65CA 旊 (<CJK Ideograph>) 3781 0x65CD 旍 (<CJK Ideograph>) 3782 0x65D0 旐 (<CJK Ideograph>) 3783 0x65D1 旑 (<CJK Ideograph>) 3784 0x65D3 旓 (<CJK Ideograph>) 3785 0x65D4 旔 (<CJK Ideograph>) 3786 0x65D5 旕 (<CJK Ideograph>) 3787 0x65D8 旘 (<CJK Ideograph>) 3788 0x65D9 旙 (<CJK Ideograph>) 3789 0x65DA 旚 (<CJK Ideograph>) 3790 0x65DB 旛 (<CJK Ideograph>) 3791 0x65DC 旜 (<CJK Ideograph>) 3792 0x65DD 旝 (<CJK Ideograph>) 3793 0x65DE 旞 (<CJK Ideograph>) 3794 0x65DF 旟 (<CJK Ideograph>) 3795 0x65E1 旡 (<CJK Ideograph>) 3796 0x65E3 旣 (<CJK Ideograph>) 3797 0x65E4 旤 (<CJK Ideograph>) 3798 0x65EA 旪 (<CJK Ideograph>) 3799 0x65EB 旫 (<CJK Ideograph>) 3800 0x65F2 旲 (<CJK Ideograph>) 3801 0x65F3 旳 (<CJK Ideograph>) 3802 0x65F4 旴 (<CJK Ideograph>) 3803 0x65F5 旵 (<CJK Ideograph>) 3804 0x65F8 旸 (<CJK Ideograph>) 3805 0x65F9 旹 (<CJK Ideograph>) 3806 0x65FB 旻 (<CJK Ideograph>) 3807 0x65FC 旼 (<CJK Ideograph>) 3808 0x65FD 旽 (<CJK Ideograph>) 3809 0x65FE 旾 (<CJK Ideograph>) 3810 0x65FF 旿 (<CJK Ideograph>) 3811 0x6601 昁 (<CJK Ideograph>) 3812 0x6604 昄 (<CJK Ideograph>) 3813 0x6605 昅 (<CJK Ideograph>) 3814 0x6607 昇 (<CJK Ideograph>) 3815 0x6608 昈 (<CJK Ideograph>) 3816 0x6609 昉 (<CJK Ideograph>) 3817 0x660B 昋 (<CJK Ideograph>) 3818 0x660D 昍 (<CJK Ideograph>) 3819 0x6610 昐 (<CJK Ideograph>) 3820 0x6611 昑 (<CJK Ideograph>) 3821 0x6612 昒 (<CJK Ideograph>) 3822 0x6616 昖 (<CJK Ideograph>) 3823 0x6617 昗 (<CJK Ideograph>) 3824 0x6618 昘 (<CJK Ideograph>) 3825 0x661A 昚 (<CJK Ideograph>) 3826 0x661B 昛 (<CJK Ideograph>) 3827 0x661C 昜 (<CJK Ideograph>) 3828 0x661E 昞 (<CJK Ideograph>) 3829 0x6621 昡 (<CJK Ideograph>) 3830 0x6622 昢 (<CJK Ideograph>) 3831 0x6623 昣 (<CJK Ideograph>) 3832 0x6624 昤 (<CJK Ideograph>) 3833 0x6626 昦 (<CJK Ideograph>) 3834 0x6629 昩 (<CJK Ideograph>) 3835 0x662A 昪 (<CJK Ideograph>) 3836 0x662B 昫 (<CJK Ideograph>) 3837 0x662C 昬 (<CJK Ideograph>) 3838 0x662E 昮 (<CJK Ideograph>) 3839 0x6630 昰 (<CJK Ideograph>) 3840 0x6632 昲 (<CJK Ideograph>) 3841 0x6633 昳 (<CJK Ideograph>) 3842 0x6637 昷 (<CJK Ideograph>) 3843 0x6638 昸 (<CJK Ideograph>) 3844 0x6639 昹 (<CJK Ideograph>) 3845 0x663A 昺 (<CJK Ideograph>) 3846 0x663B 昻 (<CJK Ideograph>) 3847 0x663D 昽 (<CJK Ideograph>) 3848 0x663F 昿 (<CJK Ideograph>) 3849 0x6640 晀 (<CJK Ideograph>) 3850 0x6642 時 (<CJK Ideograph>) 3851 0x6644 晄 (<CJK Ideograph>) 3852 0x6645 晅 (<CJK Ideograph>) 3853 0x6646 晆 (<CJK Ideograph>) 3854 0x6647 晇 (<CJK Ideograph>) 3855 0x6648 晈 (<CJK Ideograph>) 3856 0x6649 晉 (<CJK Ideograph>) 3857 0x664A 晊 (<CJK Ideograph>) 3858 0x664D 晍 (<CJK Ideograph>) 3859 0x664E 晎 (<CJK Ideograph>) 3860 0x6650 晐 (<CJK Ideograph>) 3861 0x6651 晑 (<CJK Ideograph>) 3862 0x6658 晘 (<CJK Ideograph>) 3863 0x6659 晙 (<CJK Ideograph>) 3864 0x665B 晛 (<CJK Ideograph>) 3865 0x665C 晜 (<CJK Ideograph>) 3866 0x665D 晝 (<CJK Ideograph>) 3867 0x665E 晞 (<CJK Ideograph>) 3868 0x6660 晠 (<CJK Ideograph>) 3869 0x6662 晢 (<CJK Ideograph>) 3870 0x6663 晣 (<CJK Ideograph>) 3871 0x6665 晥 (<CJK Ideograph>) 3872 0x6667 晧 (<CJK Ideograph>) 3873 0x6669 晩 (<CJK Ideograph>) 3874 0x666A 晪 (<CJK Ideograph>) 3875 0x666B 晫 (<CJK Ideograph>) 3876 0x666C 晬 (<CJK Ideograph>) 3877 0x666D 晭 (<CJK Ideograph>) 3878 0x6671 晱 (<CJK Ideograph>) 3879 0x6672 晲 (<CJK Ideograph>) 3880 0x6673 晳 (<CJK Ideograph>) 3881 0x6675 晵 (<CJK Ideograph>) 3882 0x6678 晸 (<CJK Ideograph>) 3883 0x6679 晹 (<CJK Ideograph>) 3884 0x667B 晻 (<CJK Ideograph>) 3885 0x667C 晼 (<CJK Ideograph>) 3886 0x667D 晽 (<CJK Ideograph>) 3887 0x667F 晿 (<CJK Ideograph>) 3888 0x6680 暀 (<CJK Ideograph>) 3889 0x6681 暁 (<CJK Ideograph>) 3890 0x6683 暃 (<CJK Ideograph>) 3891 0x6685 暅 (<CJK Ideograph>) 3892 0x6686 暆 (<CJK Ideograph>) 3893 0x6688 暈 (<CJK Ideograph>) 3894 0x6689 暉 (<CJK Ideograph>) 3895 0x668A 暊 (<CJK Ideograph>) 3896 0x668B 暋 (<CJK Ideograph>) 3897 0x668D 暍 (<CJK Ideograph>) 3898 0x668E 暎 (<CJK Ideograph>) 3899 0x668F 暏 (<CJK Ideograph>) 3900 0x6690 暐 (<CJK Ideograph>) 3901 0x6692 暒 (<CJK Ideograph>) 3902 0x6693 暓 (<CJK Ideograph>) 3903 0x6694 暔 (<CJK Ideograph>) 3904 0x6695 暕 (<CJK Ideograph>) 3905 0x6698 暘 (<CJK Ideograph>) 3906 0x6699 暙 (<CJK Ideograph>) 3907 0x669A 暚 (<CJK Ideograph>) 3908 0x669B 暛 (<CJK Ideograph>) 3909 0x669C 暜 (<CJK Ideograph>) 3910 0x669E 暞 (<CJK Ideograph>) 3911 0x669F 暟 (<CJK Ideograph>) 3912 0x66A0 暠 (<CJK Ideograph>) 3913 0x66A1 暡 (<CJK Ideograph>) 3914 0x66A2 暢 (<CJK Ideograph>) 3915 0x66A3 暣 (<CJK Ideograph>) 3916 0x66A4 暤 (<CJK Ideograph>) 3917 0x66A5 暥 (<CJK Ideograph>) 3918 0x66A6 暦 (<CJK Ideograph>) 3919 0x66A9 暩 (<CJK Ideograph>) 3920 0x66AA 暪 (<CJK Ideograph>) 3921 0x66AB 暫 (<CJK Ideograph>) 3922 0x66AC 暬 (<CJK Ideograph>) 3923 0x66AD 暭 (<CJK Ideograph>) 3924 0x66AF 暯 (<CJK Ideograph>) 3925 0x66B0 暰 (<CJK Ideograph>) 3926 0x66B1 暱 (<CJK Ideograph>) 3927 0x66B2 暲 (<CJK Ideograph>) 3928 0x66B3 暳 (<CJK Ideograph>) 3929 0x66B5 暵 (<CJK Ideograph>) 3930 0x66B6 暶 (<CJK Ideograph>) 3931 0x66B7 暷 (<CJK Ideograph>) 3932 0x66B8 暸 (<CJK Ideograph>) 3933 0x66BA 暺 (<CJK Ideograph>) 3934 0x66BB 暻 (<CJK Ideograph>) 3935 0x66BC 暼 (<CJK Ideograph>) 3936 0x66BD 暽 (<CJK Ideograph>) 3937 0x66BF 暿 (<CJK Ideograph>) 3938 0x66C0 曀 (<CJK Ideograph>) 3939 0x66C1 曁 (<CJK Ideograph>) 3940 0x66C2 曂 (<CJK Ideograph>) 3941 0x66C3 曃 (<CJK Ideograph>) 3942 0x66C4 曄 (<CJK Ideograph>) 3943 0x66C5 曅 (<CJK Ideograph>) 3944 0x66C6 曆 (<CJK Ideograph>) 3945 0x66C7 曇 (<CJK Ideograph>) 3946 0x66C8 曈 (<CJK Ideograph>) 3947 0x66C9 曉 (<CJK Ideograph>) 3948 0x66CA 曊 (<CJK Ideograph>) 3949 0x66CB 曋 (<CJK Ideograph>) 3950 0x66CC 曌 (<CJK Ideograph>) 3951 0x66CD 曍 (<CJK Ideograph>) 3952 0x66CE 曎 (<CJK Ideograph>) 3953 0x66CF 曏 (<CJK Ideograph>) 3954 0x66D0 曐 (<CJK Ideograph>) 3955 0x66D1 曑 (<CJK Ideograph>) 3956 0x66D2 曒 (<CJK Ideograph>) 3957 0x66D3 曓 (<CJK Ideograph>) 3958 0x66D4 曔 (<CJK Ideograph>) 3959 0x66D5 曕 (<CJK Ideograph>) 3960 0x66D6 曖 (<CJK Ideograph>) 3961 0x66D7 曗 (<CJK Ideograph>) 3962 0x66D8 曘 (<CJK Ideograph>) 3963 0x66DA 曚 (<CJK Ideograph>) 3964 0x66DE 曞 (<CJK Ideograph>) 3965 0x66DF 曟 (<CJK Ideograph>) 3966 0x66E0 曠 (<CJK Ideograph>) 3967 0x66E1 曡 (<CJK Ideograph>) 3968 0x66E2 曢 (<CJK Ideograph>) 3969 0x66E3 曣 (<CJK Ideograph>) 3970 0x66E4 曤 (<CJK Ideograph>) 3971 0x66E5 曥 (<CJK Ideograph>) 3972 0x66E7 曧 (<CJK Ideograph>) 3973 0x66E8 曨 (<CJK Ideograph>) 3974 0x66EA 曪 (<CJK Ideograph>) 3975 0x66EB 曫 (<CJK Ideograph>) 3976 0x66EC 曬 (<CJK Ideograph>) 3977 0x66ED 曭 (<CJK Ideograph>) 3978 0x66EE 曮 (<CJK Ideograph>) 3979 0x66EF 曯 (<CJK Ideograph>) 3980 0x66F1 曱 (<CJK Ideograph>) 3981 0x66F5 曵 (<CJK Ideograph>) 3982 0x66F6 曶 (<CJK Ideograph>) 3983 0x66F8 書 (<CJK Ideograph>) 3984 0x66FA 曺 (<CJK Ideograph>) 3985 0x66FB 曻 (<CJK Ideograph>) 3986 0x66FD 曽 (<CJK Ideograph>) 3987 0x6701 朁 (<CJK Ideograph>) 3988 0x6702 朂 (<CJK Ideograph>) 3989 0x6703 會 (<CJK Ideograph>) 3990 0x6704 朄 (<CJK Ideograph>) 3991 0x6705 朅 (<CJK Ideograph>) 3992 0x6706 朆 (<CJK Ideograph>) 3993 0x6707 朇 (<CJK Ideograph>) 3994 0x670C 朌 (<CJK Ideograph>) 3995 0x670E 朎 (<CJK Ideograph>) 3996 0x670F 朏 (<CJK Ideograph>) 3997 0x6711 朑 (<CJK Ideograph>) 3998 0x6712 朒 (<CJK Ideograph>) 3999 0x6713 朓 (<CJK Ideograph>) 4000 0x6716 朖 (<CJK Ideograph>) 4001 0x6718 朘 (<CJK Ideograph>) 4002 0x6719 朙 (<CJK Ideograph>) 4003 0x671A 朚 (<CJK Ideograph>) 4004 0x671C 朜 (<CJK Ideograph>) 4005 0x671E 朞 (<CJK Ideograph>) 4006 0x6720 朠 (<CJK Ideograph>) 4007 0x6721 朡 (<CJK Ideograph>) 4008 0x6722 朢 (<CJK Ideograph>) 4009 0x6723 朣 (<CJK Ideograph>) 4010 0x6724 朤 (<CJK Ideograph>) 4011 0x6725 朥 (<CJK Ideograph>) 4012 0x6727 朧 (<CJK Ideograph>) 4013 0x6729 朩 (<CJK Ideograph>) 4014 0x672E 朮 (<CJK Ideograph>) 4015 0x6730 朰 (<CJK Ideograph>) 4016 0x6732 朲 (<CJK Ideograph>) 4017 0x6733 朳 (<CJK Ideograph>) 4018 0x6736 朶 (<CJK Ideograph>) 4019 0x6737 朷 (<CJK Ideograph>) 4020 0x6738 朸 (<CJK Ideograph>) 4021 0x6739 朹 (<CJK Ideograph>) 4022 0x673B 朻 (<CJK Ideograph>) 4023 0x673C 朼 (<CJK Ideograph>) 4024 0x673E 朾 (<CJK Ideograph>) 4025 0x673F 朿 (<CJK Ideograph>) 4026 0x6741 杁 (<CJK Ideograph>) 4027 0x6744 杄 (<CJK Ideograph>) 4028 0x6745 杅 (<CJK Ideograph>) 4029 0x6747 杇 (<CJK Ideograph>) 4030 0x674A 杊 (<CJK Ideograph>) 4031 0x674B 杋 (<CJK Ideograph>) 4032 0x674D 杍 (<CJK Ideograph>) 4033 0x6752 杒 (<CJK Ideograph>) 4034 0x6754 杔 (<CJK Ideograph>) 4035 0x6755 杕 (<CJK Ideograph>) 4036 0x6757 杗 (<CJK Ideograph>) 4037 0x6758 杘 (<CJK Ideograph>) 4038 0x6759 杙 (<CJK Ideograph>) 4039 0x675A 杚 (<CJK Ideograph>) 4040 0x675B 杛 (<CJK Ideograph>) 4041 0x675D 杝 (<CJK Ideograph>) 4042 0x6762 杢 (<CJK Ideograph>) 4043 0x6763 杣 (<CJK Ideograph>) 4044 0x6764 杤 (<CJK Ideograph>) 4045 0x6766 杦 (<CJK Ideograph>) 4046 0x6767 杧 (<CJK Ideograph>) 4047 0x676B 杫 (<CJK Ideograph>) 4048 0x676C 杬 (<CJK Ideograph>) 4049 0x676E 杮 (<CJK Ideograph>) 4050 0x6771 東 (<CJK Ideograph>) 4051 0x6774 杴 (<CJK Ideograph>) 4052 0x6776 杶 (<CJK Ideograph>) 4053 0x6778 杸 (<CJK Ideograph>) 4054 0x6779 杹 (<CJK Ideograph>) 4055 0x677A 杺 (<CJK Ideograph>) 4056 0x677B 杻 (<CJK Ideograph>) 4057 0x677D 杽 (<CJK Ideograph>) 4058 0x6780 枀 (<CJK Ideograph>) 4059 0x6782 枂 (<CJK Ideograph>) 4060 0x6783 枃 (<CJK Ideograph>) 4061 0x6785 枅 (<CJK Ideograph>) 4062 0x6786 枆 (<CJK Ideograph>) 4063 0x6788 枈 (<CJK Ideograph>) 4064 0x678A 枊 (<CJK Ideograph>) 4065 0x678C 枌 (<CJK Ideograph>) 4066 0x678D 枍 (<CJK Ideograph>) 4067 0x678E 枎 (<CJK Ideograph>) 4068 0x678F 枏 (<CJK Ideograph>) 4069 0x6791 枑 (<CJK Ideograph>) 4070 0x6792 枒 (<CJK Ideograph>) 4071 0x6793 枓 (<CJK Ideograph>) 4072 0x6794 枔 (<CJK Ideograph>) 4073 0x6796 枖 (<CJK Ideograph>) 4074 0x6799 枙 (<CJK Ideograph>) 4075 0x679B 枛 (<CJK Ideograph>) 4076 0x679F 枟 (<CJK Ideograph>) 4077 0x67A0 枠 (<CJK Ideograph>) 4078 0x67A1 枡 (<CJK Ideograph>) 4079 0x67A4 枤 (<CJK Ideograph>) 4080 0x67A6 枦 (<CJK Ideograph>) 4081 0x67A9 枩 (<CJK Ideograph>) 4082 0x67AC 枬 (<CJK Ideograph>) 4083 0x67AE 枮 (<CJK Ideograph>) 4084 0x67B1 枱 (<CJK Ideograph>) 4085 0x67B2 枲 (<CJK Ideograph>) 4086 0x67B4 枴 (<CJK Ideograph>) 4087 0x67B9 枹 (<CJK Ideograph>) 4088 0x67BA 枺 (<CJK Ideograph>) 4089 0x67BB 枻 (<CJK Ideograph>) 4090 0x67BC 枼 (<CJK Ideograph>) 4091 0x67BD 枽 (<CJK Ideograph>) 4092 0x67BE 枾 (<CJK Ideograph>) 4093 0x67BF 枿 (<CJK Ideograph>) 4094 0x67C0 柀 (<CJK Ideograph>) 4095 0x67C2 柂 (<CJK Ideograph>) 4096 0x67C5 柅 (<CJK Ideograph>) 4097 0x67C6 柆 (<CJK Ideograph>) 4098 0x67C7 柇 (<CJK Ideograph>) 4099 0x67C8 柈 (<CJK Ideograph>) 4100 0x67C9 柉 (<CJK Ideograph>) 4101 0x67CA 柊 (<CJK Ideograph>) 4102 0x67CB 柋 (<CJK Ideograph>) 4103 0x67CC 柌 (<CJK Ideograph>) 4104 0x67CD 柍 (<CJK Ideograph>) 4105 0x67CE 柎 (<CJK Ideograph>) 4106 0x67D5 柕 (<CJK Ideograph>) 4107 0x67D6 柖 (<CJK Ideograph>) 4108 0x67D7 柗 (<CJK Ideograph>) 4109 0x67DB 柛 (<CJK Ideograph>) 4110 0x67DF 柟 (<CJK Ideograph>) 4111 0x67E1 柡 (<CJK Ideograph>) 4112 0x67E3 柣 (<CJK Ideograph>) 4113 0x67E4 柤 (<CJK Ideograph>) 4114 0x67E6 柦 (<CJK Ideograph>) 4115 0x67E7 柧 (<CJK Ideograph>) 4116 0x67E8 柨 (<CJK Ideograph>) 4117 0x67EA 柪 (<CJK Ideograph>) 4118 0x67EB 柫 (<CJK Ideograph>) 4119 0x67ED 柭 (<CJK Ideograph>) 4120 0x67EE 柮 (<CJK Ideograph>) 4121 0x67F2 柲 (<CJK Ideograph>) 4122 0x67F5 柵 (<CJK Ideograph>) 4123 0x67F6 柶 (<CJK Ideograph>) 4124 0x67F7 柷 (<CJK Ideograph>) 4125 0x67F8 柸 (<CJK Ideograph>) 4126 0x67F9 柹 (<CJK Ideograph>) 4127 0x67FA 柺 (<CJK Ideograph>) 4128 0x67FB 査 (<CJK Ideograph>) 4129 0x67FC 柼 (<CJK Ideograph>) 4130 0x67FE 柾 (<CJK Ideograph>) 4131 0x6801 栁 (<CJK Ideograph>) 4132 0x6802 栂 (<CJK Ideograph>) 4133 0x6803 栃 (<CJK Ideograph>) 4134 0x6804 栄 (<CJK Ideograph>) 4135 0x6806 栆 (<CJK Ideograph>) 4136 0x680D 栍 (<CJK Ideograph>) 4137 0x6810 栐 (<CJK Ideograph>) 4138 0x6812 栒 (<CJK Ideograph>) 4139 0x6814 栔 (<CJK Ideograph>) 4140 0x6815 栕 (<CJK Ideograph>) 4141 0x6818 栘 (<CJK Ideograph>) 4142 0x6819 栙 (<CJK Ideograph>) 4143 0x681A 栚 (<CJK Ideograph>) 4144 0x681B 栛 (<CJK Ideograph>) 4145 0x681C 栜 (<CJK Ideograph>) 4146 0x681E 栞 (<CJK Ideograph>) 4147 0x681F 栟 (<CJK Ideograph>) 4148 0x6820 栠 (<CJK Ideograph>) 4149 0x6822 栢 (<CJK Ideograph>) 4150 0x6823 栣 (<CJK Ideograph>) 4151 0x6824 栤 (<CJK Ideograph>) 4152 0x6825 栥 (<CJK Ideograph>) 4153 0x6826 栦 (<CJK Ideograph>) 4154 0x6827 栧 (<CJK Ideograph>) 4155 0x6828 栨 (<CJK Ideograph>) 4156 0x682B 栫 (<CJK Ideograph>) 4157 0x682C 栬 (<CJK Ideograph>) 4158 0x682D 栭 (<CJK Ideograph>) 4159 0x682E 栮 (<CJK Ideograph>) 4160 0x682F 栯 (<CJK Ideograph>) 4161 0x6830 栰 (<CJK Ideograph>) 4162 0x6831 栱 (<CJK Ideograph>) 4163 0x6834 栴 (<CJK Ideograph>) 4164 0x6835 栵 (<CJK Ideograph>) 4165 0x6836 栶 (<CJK Ideograph>) 4166 0x683A 栺 (<CJK Ideograph>) 4167 0x683B 栻 (<CJK Ideograph>) 4168 0x683F 栿 (<CJK Ideograph>) 4169 0x6847 桇 (<CJK Ideograph>) 4170 0x684B 桋 (<CJK Ideograph>) 4171 0x684D 桍 (<CJK Ideograph>) 4172 0x684F 桏 (<CJK Ideograph>) 4173 0x6852 桒 (<CJK Ideograph>) 4174 0x6856 桖 (<CJK Ideograph>) 4175 0x6857 桗 (<CJK Ideograph>) 4176 0x6858 桘 (<CJK Ideograph>) 4177 0x6859 桙 (<CJK Ideograph>) 4178 0x685A 桚 (<CJK Ideograph>) 4179 0x685B 桛 (<CJK Ideograph>) 4180 0x685C 桜 (<CJK Ideograph>) 4181 0x685D 桝 (<CJK Ideograph>) 4182 0x685E 桞 (<CJK Ideograph>) 4183 0x685F 桟 (<CJK Ideograph>) 4184 0x686A 桪 (<CJK Ideograph>) 4185 0x686C 桬 (<CJK Ideograph>) 4186 0x686D 桭 (<CJK Ideograph>) 4187 0x686E 桮 (<CJK Ideograph>) 4188 0x686F 桯 (<CJK Ideograph>) 4189 0x6870 桰 (<CJK Ideograph>) 4190 0x6871 桱 (<CJK Ideograph>) 4191 0x6872 桲 (<CJK Ideograph>) 4192 0x6873 桳 (<CJK Ideograph>) 4193 0x6875 桵 (<CJK Ideograph>) 4194 0x6878 桸 (<CJK Ideograph>) 4195 0x6879 桹 (<CJK Ideograph>) 4196 0x687A 桺 (<CJK Ideograph>) 4197 0x687B 桻 (<CJK Ideograph>) 4198 0x687C 桼 (<CJK Ideograph>) 4199 0x687D 桽 (<CJK Ideograph>) 4200 0x687E 桾 (<CJK Ideograph>) 4201 0x687F 桿 (<CJK Ideograph>) 4202 0x6880 梀 (<CJK Ideograph>) 4203 0x6882 梂 (<CJK Ideograph>) 4204 0x6884 梄 (<CJK Ideograph>) 4205 0x6887 梇 (<CJK Ideograph>) 4206 0x6888 梈 (<CJK Ideograph>) 4207 0x6889 梉 (<CJK Ideograph>) 4208 0x688A 梊 (<CJK Ideograph>) 4209 0x688B 梋 (<CJK Ideograph>) 4210 0x688C 梌 (<CJK Ideograph>) 4211 0x688D 梍 (<CJK Ideograph>) 4212 0x688E 梎 (<CJK Ideograph>) 4213 0x6890 梐 (<CJK Ideograph>) 4214 0x6891 梑 (<CJK Ideograph>) 4215 0x6892 梒 (<CJK Ideograph>) 4216 0x6894 梔 (<CJK Ideograph>) 4217 0x6895 梕 (<CJK Ideograph>) 4218 0x6896 梖 (<CJK Ideograph>) 4219 0x6898 梘 (<CJK Ideograph>) 4220 0x6899 梙 (<CJK Ideograph>) 4221 0x689A 梚 (<CJK Ideograph>) 4222 0x689B 梛 (<CJK Ideograph>) 4223 0x689C 梜 (<CJK Ideograph>) 4224 0x689D 條 (<CJK Ideograph>) 4225 0x689E 梞 (<CJK Ideograph>) 4226 0x689F 梟 (<CJK Ideograph>) 4227 0x68A0 梠 (<CJK Ideograph>) 4228 0x68A1 梡 (<CJK Ideograph>) 4229 0x68A3 梣 (<CJK Ideograph>) 4230 0x68A4 梤 (<CJK Ideograph>) 4231 0x68A5 梥 (<CJK Ideograph>) 4232 0x68A9 梩 (<CJK Ideograph>) 4233 0x68AA 梪 (<CJK Ideograph>) 4234 0x68AB 梫 (<CJK Ideograph>) 4235 0x68AC 梬 (<CJK Ideograph>) 4236 0x68AE 梮 (<CJK Ideograph>) 4237 0x68B1 梱 (<CJK Ideograph>) 4238 0x68B2 梲 (<CJK Ideograph>) 4239 0x68B4 梴 (<CJK Ideograph>) 4240 0x68B6 梶 (<CJK Ideograph>) 4241 0x68B7 梷 (<CJK Ideograph>) 4242 0x68B8 梸 (<CJK Ideograph>) 4243 0x68B9 梹 (<CJK Ideograph>) 4244 0x68BA 梺 (<CJK Ideograph>) 4245 0x68BB 梻 (<CJK Ideograph>) 4246 0x68BC 梼 (<CJK Ideograph>) 4247 0x68BD 梽 (<CJK Ideograph>) 4248 0x68BE 梾 (<CJK Ideograph>) 4249 0x68BF 梿 (<CJK Ideograph>) 4250 0x68C1 棁 (<CJK Ideograph>) 4251 0x68C3 棃 (<CJK Ideograph>) 4252 0x68C4 棄 (<CJK Ideograph>) 4253 0x68C5 棅 (<CJK Ideograph>) 4254 0x68C6 棆 (<CJK Ideograph>) 4255 0x68C7 棇 (<CJK Ideograph>) 4256 0x68C8 棈 (<CJK Ideograph>) 4257 0x68CA 棊 (<CJK Ideograph>) 4258 0x68CC 棌 (<CJK Ideograph>) 4259 0x68CE 棎 (<CJK Ideograph>) 4260 0x68CF 棏 (<CJK Ideograph>) 4261 0x68D0 棐 (<CJK Ideograph>) 4262 0x68D1 棑 (<CJK Ideograph>) 4263 0x68D3 棓 (<CJK Ideograph>) 4264 0x68D4 棔 (<CJK Ideograph>) 4265 0x68D6 棖 (<CJK Ideograph>) 4266 0x68D7 棗 (<CJK Ideograph>) 4267 0x68D9 棙 (<CJK Ideograph>) 4268 0x68DB 棛 (<CJK Ideograph>) 4269 0x68DC 棜 (<CJK Ideograph>) 4270 0x68DD 棝 (<CJK Ideograph>) 4271 0x68DE 棞 (<CJK Ideograph>) 4272 0x68DF 棟 (<CJK Ideograph>) 4273 0x68E1 棡 (<CJK Ideograph>) 4274 0x68E2 棢 (<CJK Ideograph>) 4275 0x68E4 棤 (<CJK Ideograph>) 4276 0x68E5 棥 (<CJK Ideograph>) 4277 0x68E6 棦 (<CJK Ideograph>) 4278 0x68E7 棧 (<CJK Ideograph>) 4279 0x68E8 棨 (<CJK Ideograph>) 4280 0x68E9 棩 (<CJK Ideograph>) 4281 0x68EA 棪 (<CJK Ideograph>) 4282 0x68EB 棫 (<CJK Ideograph>) 4283 0x68EC 棬 (<CJK Ideograph>) 4284 0x68ED 棭 (<CJK Ideograph>) 4285 0x68EF 棯 (<CJK Ideograph>) 4286 0x68F2 棲 (<CJK Ideograph>) 4287 0x68F3 棳 (<CJK Ideograph>) 4288 0x68F4 棴 (<CJK Ideograph>) 4289 0x68F6 棶 (<CJK Ideograph>) 4290 0x68F7 棷 (<CJK Ideograph>) 4291 0x68F8 棸 (<CJK Ideograph>) 4292 0x68FB 棻 (<CJK Ideograph>) 4293 0x68FD 棽 (<CJK Ideograph>) 4294 0x68FE 棾 (<CJK Ideograph>) 4295 0x68FF 棿 (<CJK Ideograph>) 4296 0x6900 椀 (<CJK Ideograph>) 4297 0x6902 椂 (<CJK Ideograph>) 4298 0x6903 椃 (<CJK Ideograph>) 4299 0x6904 椄 (<CJK Ideograph>) 4300 0x6906 椆 (<CJK Ideograph>) 4301 0x6907 椇 (<CJK Ideograph>) 4302 0x6908 椈 (<CJK Ideograph>) 4303 0x6909 椉 (<CJK Ideograph>) 4304 0x690A 椊 (<CJK Ideograph>) 4305 0x690C 椌 (<CJK Ideograph>) 4306 0x690F 椏 (<CJK Ideograph>) 4307 0x6911 椑 (<CJK Ideograph>) 4308 0x6913 椓 (<CJK Ideograph>) 4309 0x6914 椔 (<CJK Ideograph>) 4310 0x6915 椕 (<CJK Ideograph>) 4311 0x6916 椖 (<CJK Ideograph>) 4312 0x6917 椗 (<CJK Ideograph>) 4313 0x6918 椘 (<CJK Ideograph>) 4314 0x6919 椙 (<CJK Ideograph>) 4315 0x691A 椚 (<CJK Ideograph>) 4316 0x691B 椛 (<CJK Ideograph>) 4317 0x691C 検 (<CJK Ideograph>) 4318 0x691D 椝 (<CJK Ideograph>) 4319 0x691E 椞 (<CJK Ideograph>) 4320 0x6921 椡 (<CJK Ideograph>) 4321 0x6922 椢 (<CJK Ideograph>) 4322 0x6923 椣 (<CJK Ideograph>) 4323 0x6925 椥 (<CJK Ideograph>) 4324 0x6926 椦 (<CJK Ideograph>) 4325 0x6927 椧 (<CJK Ideograph>) 4326 0x6928 椨 (<CJK Ideograph>) 4327 0x6929 椩 (<CJK Ideograph>) 4328 0x692A 椪 (<CJK Ideograph>) 4329 0x692B 椫 (<CJK Ideograph>) 4330 0x692C 椬 (<CJK Ideograph>) 4331 0x692E 椮 (<CJK Ideograph>) 4332 0x692F 椯 (<CJK Ideograph>) 4333 0x6931 椱 (<CJK Ideograph>) 4334 0x6932 椲 (<CJK Ideograph>) 4335 0x6933 椳 (<CJK Ideograph>) 4336 0x6935 椵 (<CJK Ideograph>) 4337 0x6936 椶 (<CJK Ideograph>) 4338 0x6937 椷 (<CJK Ideograph>) 4339 0x6938 椸 (<CJK Ideograph>) 4340 0x693A 椺 (<CJK Ideograph>) 4341 0x693B 椻 (<CJK Ideograph>) 4342 0x693C 椼 (<CJK Ideograph>) 4343 0x693E 椾 (<CJK Ideograph>) 4344 0x6940 楀 (<CJK Ideograph>) 4345 0x6941 楁 (<CJK Ideograph>) 4346 0x6943 楃 (<CJK Ideograph>) 4347 0x6944 楄 (<CJK Ideograph>) 4348 0x6945 楅 (<CJK Ideograph>) 4349 0x6946 楆 (<CJK Ideograph>) 4350 0x6947 楇 (<CJK Ideograph>) 4351 0x6948 楈 (<CJK Ideograph>) 4352 0x6949 楉 (<CJK Ideograph>) 4353 0x694A 楊 (<CJK Ideograph>) 4354 0x694B 楋 (<CJK Ideograph>) 4355 0x694C 楌 (<CJK Ideograph>) 4356 0x694D 楍 (<CJK Ideograph>) 4357 0x694E 楎 (<CJK Ideograph>) 4358 0x694F 楏 (<CJK Ideograph>) 4359 0x6950 楐 (<CJK Ideograph>) 4360 0x6951 楑 (<CJK Ideograph>) 4361 0x6952 楒 (<CJK Ideograph>) 4362 0x6953 楓 (<CJK Ideograph>) 4363 0x6955 楕 (<CJK Ideograph>) 4364 0x6956 楖 (<CJK Ideograph>) 4365 0x6958 楘 (<CJK Ideograph>) 4366 0x6959 楙 (<CJK Ideograph>) 4367 0x695B 楛 (<CJK Ideograph>) 4368 0x695C 楜 (<CJK Ideograph>) 4369 0x695F 楟 (<CJK Ideograph>) 4370 0x6961 楡 (<CJK Ideograph>) 4371 0x6962 楢 (<CJK Ideograph>) 4372 0x6964 楤 (<CJK Ideograph>) 4373 0x6965 楥 (<CJK Ideograph>) 4374 0x6967 楧 (<CJK Ideograph>) 4375 0x6968 楨 (<CJK Ideograph>) 4376 0x6969 楩 (<CJK Ideograph>) 4377 0x696A 楪 (<CJK Ideograph>) 4378 0x696C 楬 (<CJK Ideograph>) 4379 0x696D 業 (<CJK Ideograph>) 4380 0x696F 楯 (<CJK Ideograph>) 4381 0x6970 楰 (<CJK Ideograph>) 4382 0x6972 楲 (<CJK Ideograph>) 4383 0x6973 楳 (<CJK Ideograph>) 4384 0x6974 楴 (<CJK Ideograph>) 4385 0x6975 極 (<CJK Ideograph>) 4386 0x6976 楶 (<CJK Ideograph>) 4387 0x697A 楺 (<CJK Ideograph>) 4388 0x697B 楻 (<CJK Ideograph>) 4389 0x697D 楽 (<CJK Ideograph>) 4390 0x697E 楾 (<CJK Ideograph>) 4391 0x697F 楿 (<CJK Ideograph>) 4392 0x6981 榁 (<CJK Ideograph>) 4393 0x6983 榃 (<CJK Ideograph>) 4394 0x6985 榅 (<CJK Ideograph>) 4395 0x698A 榊 (<CJK Ideograph>) 4396 0x698B 榋 (<CJK Ideograph>) 4397 0x698C 榌 (<CJK Ideograph>) 4398 0x698E 榎 (<CJK Ideograph>) 4399 0x698F 榏 (<CJK Ideograph>) 4400 0x6990 榐 (<CJK Ideograph>) 4401 0x6991 榑 (<CJK Ideograph>) 4402 0x6992 榒 (<CJK Ideograph>) 4403 0x6993 榓 (<CJK Ideograph>) 4404 0x6996 榖 (<CJK Ideograph>) 4405 0x6997 榗 (<CJK Ideograph>) 4406 0x6999 榙 (<CJK Ideograph>) 4407 0x699A 榚 (<CJK Ideograph>) 4408 0x699D 榝 (<CJK Ideograph>) 4409 0x699E 榞 (<CJK Ideograph>) 4410 0x699F 榟 (<CJK Ideograph>) 4411 0x69A0 榠 (<CJK Ideograph>) 4412 0x69A1 榡 (<CJK Ideograph>) 4413 0x69A2 榢 (<CJK Ideograph>) 4414 0x69A3 榣 (<CJK Ideograph>) 4415 0x69A4 榤 (<CJK Ideograph>) 4416 0x69A5 榥 (<CJK Ideograph>) 4417 0x69A6 榦 (<CJK Ideograph>) 4418 0x69A9 榩 (<CJK Ideograph>) 4419 0x69AA 榪 (<CJK Ideograph>) 4420 0x69AC 榬 (<CJK Ideograph>) 4421 0x69AE 榮 (<CJK Ideograph>) 4422 0x69AF 榯 (<CJK Ideograph>) 4423 0x69B0 榰 (<CJK Ideograph>) 4424 0x69B2 榲 (<CJK Ideograph>) 4425 0x69B3 榳 (<CJK Ideograph>) 4426 0x69B5 榵 (<CJK Ideograph>) 4427 0x69B6 榶 (<CJK Ideograph>) 4428 0x69B8 榸 (<CJK Ideograph>) 4429 0x69B9 榹 (<CJK Ideograph>) 4430 0x69BA 榺 (<CJK Ideograph>) 4431 0x69BC 榼 (<CJK Ideograph>) 4432 0x69BD 榽 (<CJK Ideograph>) 4433 0x69BE 榾 (<CJK Ideograph>) 4434 0x69BF 榿 (<CJK Ideograph>) 4435 0x69C0 槀 (<CJK Ideograph>) 4436 0x69C2 槂 (<CJK Ideograph>) 4437 0x69C3 槃 (<CJK Ideograph>) 4438 0x69C4 槄 (<CJK Ideograph>) 4439 0x69C5 槅 (<CJK Ideograph>) 4440 0x69C6 槆 (<CJK Ideograph>) 4441 0x69C7 槇 (<CJK Ideograph>) 4442 0x69C8 槈 (<CJK Ideograph>) 4443 0x69C9 槉 (<CJK Ideograph>) 4444 0x69CB 構 (<CJK Ideograph>) 4445 0x69CD 槍 (<CJK Ideograph>) 4446 0x69CF 槏 (<CJK Ideograph>) 4447 0x69D1 槑 (<CJK Ideograph>) 4448 0x69D2 槒 (<CJK Ideograph>) 4449 0x69D3 槓 (<CJK Ideograph>) 4450 0x69D5 槕 (<CJK Ideograph>) 4451 0x69D6 槖 (<CJK Ideograph>) 4452 0x69D7 槗 (<CJK Ideograph>) 4453 0x69D8 様 (<CJK Ideograph>) 4454 0x69D9 槙 (<CJK Ideograph>) 4455 0x69DA 槚 (<CJK Ideograph>) 4456 0x69DC 槜 (<CJK Ideograph>) 4457 0x69DD 槝 (<CJK Ideograph>) 4458 0x69DE 槞 (<CJK Ideograph>) 4459 0x69E1 槡 (<CJK Ideograph>) 4460 0x69E2 槢 (<CJK Ideograph>) 4461 0x69E3 槣 (<CJK Ideograph>) 4462 0x69E4 槤 (<CJK Ideograph>) 4463 0x69E5 槥 (<CJK Ideograph>) 4464 0x69E6 槦 (<CJK Ideograph>) 4465 0x69E7 槧 (<CJK Ideograph>) 4466 0x69E8 槨 (<CJK Ideograph>) 4467 0x69E9 槩 (<CJK Ideograph>) 4468 0x69EA 槪 (<CJK Ideograph>) 4469 0x69EB 槫 (<CJK Ideograph>) 4470 0x69EC 槬 (<CJK Ideograph>) 4471 0x69EE 槮 (<CJK Ideograph>) 4472 0x69EF 槯 (<CJK Ideograph>) 4473 0x69F0 槰 (<CJK Ideograph>) 4474 0x69F1 槱 (<CJK Ideograph>) 4475 0x69F3 槳 (<CJK Ideograph>) 4476 0x69F4 槴 (<CJK Ideograph>) 4477 0x69F5 槵 (<CJK Ideograph>) 4478 0x69F6 槶 (<CJK Ideograph>) 4479 0x69F7 槷 (<CJK Ideograph>) 4480 0x69F8 槸 (<CJK Ideograph>) 4481 0x69F9 槹 (<CJK Ideograph>) 4482 0x69FA 槺 (<CJK Ideograph>) 4483 0x69FB 槻 (<CJK Ideograph>) 4484 0x69FC 槼 (<CJK Ideograph>) 4485 0x69FE 槾 (<CJK Ideograph>) 4486 0x6A00 樀 (<CJK Ideograph>) 4487 0x6A01 樁 (<CJK Ideograph>) 4488 0x6A02 樂 (<CJK Ideograph>) 4489 0x6A03 樃 (<CJK Ideograph>) 4490 0x6A04 樄 (<CJK Ideograph>) 4491 0x6A05 樅 (<CJK Ideograph>) 4492 0x6A06 樆 (<CJK Ideograph>) 4493 0x6A07 樇 (<CJK Ideograph>) 4494 0x6A08 樈 (<CJK Ideograph>) 4495 0x6A09 樉 (<CJK Ideograph>) 4496 0x6A0B 樋 (<CJK Ideograph>) 4497 0x6A0C 樌 (<CJK Ideograph>) 4498 0x6A0D 樍 (<CJK Ideograph>) 4499 0x6A0E 樎 (<CJK Ideograph>) 4500 0x6A0F 樏 (<CJK Ideograph>) 4501 0x6A10 樐 (<CJK Ideograph>) 4502 0x6A11 樑 (<CJK Ideograph>) 4503 0x6A12 樒 (<CJK Ideograph>) 4504 0x6A13 樓 (<CJK Ideograph>) 4505 0x6A14 樔 (<CJK Ideograph>) 4506 0x6A15 樕 (<CJK Ideograph>) 4507 0x6A16 樖 (<CJK Ideograph>) 4508 0x6A19 標 (<CJK Ideograph>) 4509 0x6A1A 樚 (<CJK Ideograph>) 4510 0x6A1B 樛 (<CJK Ideograph>) 4511 0x6A1C 樜 (<CJK Ideograph>) 4512 0x6A1D 樝 (<CJK Ideograph>) 4513 0x6A1E 樞 (<CJK Ideograph>) 4514 0x6A20 樠 (<CJK Ideograph>) 4515 0x6A22 樢 (<CJK Ideograph>) 4516 0x6A23 樣 (<CJK Ideograph>) 4517 0x6A24 樤 (<CJK Ideograph>) 4518 0x6A25 樥 (<CJK Ideograph>) 4519 0x6A26 樦 (<CJK Ideograph>) 4520 0x6A27 樧 (<CJK Ideograph>) 4521 0x6A29 権 (<CJK Ideograph>) 4522 0x6A2B 樫 (<CJK Ideograph>) 4523 0x6A2C 樬 (<CJK Ideograph>) 4524 0x6A2D 樭 (<CJK Ideograph>) 4525 0x6A2E 樮 (<CJK Ideograph>) 4526 0x6A30 樰 (<CJK Ideograph>) 4527 0x6A32 樲 (<CJK Ideograph>) 4528 0x6A33 樳 (<CJK Ideograph>) 4529 0x6A34 樴 (<CJK Ideograph>) 4530 0x6A36 樶 (<CJK Ideograph>) 4531 0x6A37 樷 (<CJK Ideograph>) 4532 0x6A38 樸 (<CJK Ideograph>) 4533 0x6A39 樹 (<CJK Ideograph>) 4534 0x6A3A 樺 (<CJK Ideograph>) 4535 0x6A3B 樻 (<CJK Ideograph>) 4536 0x6A3C 樼 (<CJK Ideograph>) 4537 0x6A3F 樿 (<CJK Ideograph>) 4538 0x6A40 橀 (<CJK Ideograph>) 4539 0x6A41 橁 (<CJK Ideograph>) 4540 0x6A42 橂 (<CJK Ideograph>) 4541 0x6A43 橃 (<CJK Ideograph>) 4542 0x6A45 橅 (<CJK Ideograph>) 4543 0x6A46 橆 (<CJK Ideograph>) 4544 0x6A48 橈 (<CJK Ideograph>) 4545 0x6A49 橉 (<CJK Ideograph>) 4546 0x6A4A 橊 (<CJK Ideograph>) 4547 0x6A4B 橋 (<CJK Ideograph>) 4548 0x6A4C 橌 (<CJK Ideograph>) 4549 0x6A4D 橍 (<CJK Ideograph>) 4550 0x6A4E 橎 (<CJK Ideograph>) 4551 0x6A4F 橏 (<CJK Ideograph>) 4552 0x6A51 橑 (<CJK Ideograph>) 4553 0x6A52 橒 (<CJK Ideograph>) 4554 0x6A53 橓 (<CJK Ideograph>) 4555 0x6A54 橔 (<CJK Ideograph>) 4556 0x6A55 橕 (<CJK Ideograph>) 4557 0x6A56 橖 (<CJK Ideograph>) 4558 0x6A57 橗 (<CJK Ideograph>) 4559 0x6A5A 橚 (<CJK Ideograph>) 4560 0x6A5C 橜 (<CJK Ideograph>) 4561 0x6A5D 橝 (<CJK Ideograph>) 4562 0x6A5E 橞 (<CJK Ideograph>) 4563 0x6A5F 機 (<CJK Ideograph>) 4564 0x6A60 橠 (<CJK Ideograph>) 4565 0x6A62 橢 (<CJK Ideograph>) 4566 0x6A63 橣 (<CJK Ideograph>) 4567 0x6A64 橤 (<CJK Ideograph>) 4568 0x6A66 橦 (<CJK Ideograph>) 4569 0x6A67 橧 (<CJK Ideograph>) 4570 0x6A68 橨 (<CJK Ideograph>) 4571 0x6A69 橩 (<CJK Ideograph>) 4572 0x6A6A 橪 (<CJK Ideograph>) 4573 0x6A6B 橫 (<CJK Ideograph>) 4574 0x6A6C 橬 (<CJK Ideograph>) 4575 0x6A6D 橭 (<CJK Ideograph>) 4576 0x6A6E 橮 (<CJK Ideograph>) 4577 0x6A6F 橯 (<CJK Ideograph>) 4578 0x6A70 橰 (<CJK Ideograph>) 4579 0x6A72 橲 (<CJK Ideograph>) 4580 0x6A73 橳 (<CJK Ideograph>) 4581 0x6A74 橴 (<CJK Ideograph>) 4582 0x6A75 橵 (<CJK Ideograph>) 4583 0x6A76 橶 (<CJK Ideograph>) 4584 0x6A77 橷 (<CJK Ideograph>) 4585 0x6A78 橸 (<CJK Ideograph>) 4586 0x6A7A 橺 (<CJK Ideograph>) 4587 0x6A7B 橻 (<CJK Ideograph>) 4588 0x6A7D 橽 (<CJK Ideograph>) 4589 0x6A7E 橾 (<CJK Ideograph>) 4590 0x6A7F 橿 (<CJK Ideograph>) 4591 0x6A81 檁 (<CJK Ideograph>) 4592 0x6A82 檂 (<CJK Ideograph>) 4593 0x6A83 檃 (<CJK Ideograph>) 4594 0x6A85 檅 (<CJK Ideograph>) 4595 0x6A86 檆 (<CJK Ideograph>) 4596 0x6A87 檇 (<CJK Ideograph>) 4597 0x6A88 檈 (<CJK Ideograph>) 4598 0x6A89 檉 (<CJK Ideograph>) 4599 0x6A8A 檊 (<CJK Ideograph>) 4600 0x6A8B 檋 (<CJK Ideograph>) 4601 0x6A8C 檌 (<CJK Ideograph>) 4602 0x6A8D 檍 (<CJK Ideograph>) 4603 0x6A8F 檏 (<CJK Ideograph>) 4604 0x6A92 檒 (<CJK Ideograph>) 4605 0x6A93 檓 (<CJK Ideograph>) 4606 0x6A94 檔 (<CJK Ideograph>) 4607 0x6A95 檕 (<CJK Ideograph>) 4608 0x6A96 檖 (<CJK Ideograph>) 4609 0x6A98 檘 (<CJK Ideograph>) 4610 0x6A99 檙 (<CJK Ideograph>) 4611 0x6A9A 檚 (<CJK Ideograph>) 4612 0x6A9B 檛 (<CJK Ideograph>) 4613 0x6A9C 檜 (<CJK Ideograph>) 4614 0x6A9D 檝 (<CJK Ideograph>) 4615 0x6A9E 檞 (<CJK Ideograph>) 4616 0x6A9F 檟 (<CJK Ideograph>) 4617 0x6AA1 檡 (<CJK Ideograph>) 4618 0x6AA2 檢 (<CJK Ideograph>) 4619 0x6AA3 檣 (<CJK Ideograph>) 4620 0x6AA4 檤 (<CJK Ideograph>) 4621 0x6AA5 檥 (<CJK Ideograph>) 4622 0x6AA6 檦 (<CJK Ideograph>) 4623 0x6AA7 檧 (<CJK Ideograph>) 4624 0x6AA8 檨 (<CJK Ideograph>) 4625 0x6AAA 檪 (<CJK Ideograph>) 4626 0x6AAD 檭 (<CJK Ideograph>) 4627 0x6AAE 檮 (<CJK Ideograph>) 4628 0x6AAF 檯 (<CJK Ideograph>) 4629 0x6AB0 檰 (<CJK Ideograph>) 4630 0x6AB1 檱 (<CJK Ideograph>) 4631 0x6AB2 檲 (<CJK Ideograph>) 4632 0x6AB3 檳 (<CJK Ideograph>) 4633 0x6AB4 檴 (<CJK Ideograph>) 4634 0x6AB5 檵 (<CJK Ideograph>) 4635 0x6AB6 檶 (<CJK Ideograph>) 4636 0x6AB7 檷 (<CJK Ideograph>) 4637 0x6AB8 檸 (<CJK Ideograph>) 4638 0x6AB9 檹 (<CJK Ideograph>) 4639 0x6ABA 檺 (<CJK Ideograph>) 4640 0x6ABB 檻 (<CJK Ideograph>) 4641 0x6ABC 檼 (<CJK Ideograph>) 4642 0x6ABD 檽 (<CJK Ideograph>) 4643 0x6ABE 檾 (<CJK Ideograph>) 4644 0x6ABF 檿 (<CJK Ideograph>) 4645 0x6AC0 櫀 (<CJK Ideograph>) 4646 0x6AC1 櫁 (<CJK Ideograph>) 4647 0x6AC2 櫂 (<CJK Ideograph>) 4648 0x6AC3 櫃 (<CJK Ideograph>) 4649 0x6AC4 櫄 (<CJK Ideograph>) 4650 0x6AC5 櫅 (<CJK Ideograph>) 4651 0x6AC6 櫆 (<CJK Ideograph>) 4652 0x6AC7 櫇 (<CJK Ideograph>) 4653 0x6AC8 櫈 (<CJK Ideograph>) 4654 0x6AC9 櫉 (<CJK Ideograph>) 4655 0x6ACA 櫊 (<CJK Ideograph>) 4656 0x6ACB 櫋 (<CJK Ideograph>) 4657 0x6ACC 櫌 (<CJK Ideograph>) 4658 0x6ACD 櫍 (<CJK Ideograph>) 4659 0x6ACE 櫎 (<CJK Ideograph>) 4660 0x6ACF 櫏 (<CJK Ideograph>) 4661 0x6AD0 櫐 (<CJK Ideograph>) 4662 0x6AD1 櫑 (<CJK Ideograph>) 4663 0x6AD2 櫒 (<CJK Ideograph>) 4664 0x6AD3 櫓 (<CJK Ideograph>) 4665 0x6AD4 櫔 (<CJK Ideograph>) 4666 0x6AD5 櫕 (<CJK Ideograph>) 4667 0x6AD6 櫖 (<CJK Ideograph>) 4668 0x6AD7 櫗 (<CJK Ideograph>) 4669 0x6AD8 櫘 (<CJK Ideograph>) 4670 0x6AD9 櫙 (<CJK Ideograph>) 4671 0x6ADA 櫚 (<CJK Ideograph>) 4672 0x6ADB 櫛 (<CJK Ideograph>) 4673 0x6ADC 櫜 (<CJK Ideograph>) 4674 0x6ADD 櫝 (<CJK Ideograph>) 4675 0x6ADE 櫞 (<CJK Ideograph>) 4676 0x6ADF 櫟 (<CJK Ideograph>) 4677 0x6AE0 櫠 (<CJK Ideograph>) 4678 0x6AE1 櫡 (<CJK Ideograph>) 4679 0x6AE2 櫢 (<CJK Ideograph>) 4680 0x6AE3 櫣 (<CJK Ideograph>) 4681 0x6AE4 櫤 (<CJK Ideograph>) 4682 0x6AE5 櫥 (<CJK Ideograph>) 4683 0x6AE6 櫦 (<CJK Ideograph>) 4684 0x6AE7 櫧 (<CJK Ideograph>) 4685 0x6AE8 櫨 (<CJK Ideograph>) 4686 0x6AE9 櫩 (<CJK Ideograph>) 4687 0x6AEA 櫪 (<CJK Ideograph>) 4688 0x6AEB 櫫 (<CJK Ideograph>) 4689 0x6AEC 櫬 (<CJK Ideograph>) 4690 0x6AED 櫭 (<CJK Ideograph>) 4691 0x6AEE 櫮 (<CJK Ideograph>) 4692 0x6AEF 櫯 (<CJK Ideograph>) 4693 0x6AF0 櫰 (<CJK Ideograph>) 4694 0x6AF1 櫱 (<CJK Ideograph>) 4695 0x6AF2 櫲 (<CJK Ideograph>) 4696 0x6AF3 櫳 (<CJK Ideograph>) 4697 0x6AF4 櫴 (<CJK Ideograph>) 4698 0x6AF5 櫵 (<CJK Ideograph>) 4699 0x6AF6 櫶 (<CJK Ideograph>) 4700 0x6AF7 櫷 (<CJK Ideograph>) 4701 0x6AF8 櫸 (<CJK Ideograph>) 4702 0x6AF9 櫹 (<CJK Ideograph>) 4703 0x6AFA 櫺 (<CJK Ideograph>) 4704 0x6AFB 櫻 (<CJK Ideograph>) 4705 0x6AFC 櫼 (<CJK Ideograph>) 4706 0x6AFD 櫽 (<CJK Ideograph>) 4707 0x6AFE 櫾 (<CJK Ideograph>) 4708 0x6AFF 櫿 (<CJK Ideograph>) 4709 0x6B00 欀 (<CJK Ideograph>) 4710 0x6B01 欁 (<CJK Ideograph>) 4711 0x6B02 欂 (<CJK Ideograph>) 4712 0x6B03 欃 (<CJK Ideograph>) 4713 0x6B04 欄 (<CJK Ideograph>) 4714 0x6B05 欅 (<CJK Ideograph>) 4715 0x6B06 欆 (<CJK Ideograph>) 4716 0x6B07 欇 (<CJK Ideograph>) 4717 0x6B08 欈 (<CJK Ideograph>) 4718 0x6B09 欉 (<CJK Ideograph>) 4719 0x6B0A 權 (<CJK Ideograph>) 4720 0x6B0B 欋 (<CJK Ideograph>) 4721 0x6B0C 欌 (<CJK Ideograph>) 4722 0x6B0D 欍 (<CJK Ideograph>) 4723 0x6B0E 欎 (<CJK Ideograph>) 4724 0x6B0F 欏 (<CJK Ideograph>) 4725 0x6B10 欐 (<CJK Ideograph>) 4726 0x6B11 欑 (<CJK Ideograph>) 4727 0x6B12 欒 (<CJK Ideograph>) 4728 0x6B13 欓 (<CJK Ideograph>) 4729 0x6B14 欔 (<CJK Ideograph>) 4730 0x6B15 欕 (<CJK Ideograph>) 4731 0x6B16 欖 (<CJK Ideograph>) 4732 0x6B17 欗 (<CJK Ideograph>) 4733 0x6B18 欘 (<CJK Ideograph>) 4734 0x6B19 欙 (<CJK Ideograph>) 4735 0x6B1A 欚 (<CJK Ideograph>) 4736 0x6B1B 欛 (<CJK Ideograph>) 4737 0x6B1C 欜 (<CJK Ideograph>) 4738 0x6B1D 欝 (<CJK Ideograph>) 4739 0x6B1E 欞 (<CJK Ideograph>) 4740 0x6B1F 欟 (<CJK Ideograph>) 4741 0x6B25 欥 (<CJK Ideograph>) 4742 0x6B26 欦 (<CJK Ideograph>) 4743 0x6B28 欨 (<CJK Ideograph>) 4744 0x6B29 欩 (<CJK Ideograph>) 4745 0x6B2A 欪 (<CJK Ideograph>) 4746 0x6B2B 欫 (<CJK Ideograph>) 4747 0x6B2C 欬 (<CJK Ideograph>) 4748 0x6B2D 欭 (<CJK Ideograph>) 4749 0x6B2E 欮 (<CJK Ideograph>) 4750 0x6B2F 欯 (<CJK Ideograph>) 4751 0x6B30 欰 (<CJK Ideograph>) 4752 0x6B31 欱 (<CJK Ideograph>) 4753 0x6B33 欳 (<CJK Ideograph>) 4754 0x6B34 欴 (<CJK Ideograph>) 4755 0x6B35 欵 (<CJK Ideograph>) 4756 0x6B36 欶 (<CJK Ideograph>) 4757 0x6B38 欸 (<CJK Ideograph>) 4758 0x6B3B 欻 (<CJK Ideograph>) 4759 0x6B3C 欼 (<CJK Ideograph>) 4760 0x6B3D 欽 (<CJK Ideograph>) 4761 0x6B3F 欿 (<CJK Ideograph>) 4762 0x6B40 歀 (<CJK Ideograph>) 4763 0x6B41 歁 (<CJK Ideograph>) 4764 0x6B42 歂 (<CJK Ideograph>) 4765 0x6B44 歄 (<CJK Ideograph>) 4766 0x6B45 歅 (<CJK Ideograph>) 4767 0x6B48 歈 (<CJK Ideograph>) 4768 0x6B4A 歊 (<CJK Ideograph>) 4769 0x6B4B 歋 (<CJK Ideograph>) 4770 0x6B4D 歍 (<CJK Ideograph>) 4771 0x6B4E 歎 (<CJK Ideograph>) 4772 0x6B4F 歏 (<CJK Ideograph>) 4773 0x6B50 歐 (<CJK Ideograph>) 4774 0x6B51 歑 (<CJK Ideograph>) 4775 0x6B52 歒 (<CJK Ideograph>) 4776 0x6B53 歓 (<CJK Ideograph>) 4777 0x6B54 歔 (<CJK Ideograph>) 4778 0x6B55 歕 (<CJK Ideograph>) 4779 0x6B56 歖 (<CJK Ideograph>) 4780 0x6B57 歗 (<CJK Ideograph>) 4781 0x6B58 歘 (<CJK Ideograph>) 4782 0x6B5A 歚 (<CJK Ideograph>) 4783 0x6B5B 歛 (<CJK Ideograph>) 4784 0x6B5C 歜 (<CJK Ideograph>) 4785 0x6B5D 歝 (<CJK Ideograph>) 4786 0x6B5E 歞 (<CJK Ideograph>) 4787 0x6B5F 歟 (<CJK Ideograph>) 4788 0x6B60 歠 (<CJK Ideograph>) 4789 0x6B61 歡 (<CJK Ideograph>) 4790 0x6B68 歨 (<CJK Ideograph>) 4791 0x6B69 歩 (<CJK Ideograph>) 4792 0x6B6B 歫 (<CJK Ideograph>) 4793 0x6B6C 歬 (<CJK Ideograph>) 4794 0x6B6D 歭 (<CJK Ideograph>) 4795 0x6B6E 歮 (<CJK Ideograph>) 4796 0x6B6F 歯 (<CJK Ideograph>) 4797 0x6B70 歰 (<CJK Ideograph>) 4798 0x6B71 歱 (<CJK Ideograph>) 4799 0x6B72 歲 (<CJK Ideograph>) 4800 0x6B73 歳 (<CJK Ideograph>) 4801 0x6B74 歴 (<CJK Ideograph>) 4802 0x6B75 歵 (<CJK Ideograph>) 4803 0x6B76 歶 (<CJK Ideograph>) 4804 0x6B77 歷 (<CJK Ideograph>) 4805 0x6B78 歸 (<CJK Ideograph>) 4806 0x6B7A 歺 (<CJK Ideograph>) 4807 0x6B7D 歽 (<CJK Ideograph>) 4808 0x6B7E 歾 (<CJK Ideograph>) 4809 0x6B7F 歿 (<CJK Ideograph>) 4810 0x6B80 殀 (<CJK Ideograph>) 4811 0x6B85 殅 (<CJK Ideograph>) 4812 0x6B88 殈 (<CJK Ideograph>) 4813 0x6B8C 殌 (<CJK Ideograph>) 4814 0x6B8E 殎 (<CJK Ideograph>) 4815 0x6B8F 殏 (<CJK Ideograph>) 4816 0x6B90 殐 (<CJK Ideograph>) 4817 0x6B91 殑 (<CJK Ideograph>) 4818 0x6B94 殔 (<CJK Ideograph>) 4819 0x6B95 殕 (<CJK Ideograph>) 4820 0x6B97 殗 (<CJK Ideograph>) 4821 0x6B98 殘 (<CJK Ideograph>) 4822 0x6B99 殙 (<CJK Ideograph>) 4823 0x6B9C 殜 (<CJK Ideograph>) 4824 0x6B9D 殝 (<CJK Ideograph>) 4825 0x6B9E 殞 (<CJK Ideograph>) 4826 0x6B9F 殟 (<CJK Ideograph>) 4827 0x6BA0 殠 (<CJK Ideograph>) 4828 0x6BA2 殢 (<CJK Ideograph>) 4829 0x6BA3 殣 (<CJK Ideograph>) 4830 0x6BA4 殤 (<CJK Ideograph>) 4831 0x6BA5 殥 (<CJK Ideograph>) 4832 0x6BA6 殦 (<CJK Ideograph>) 4833 0x6BA7 殧 (<CJK Ideograph>) 4834 0x6BA8 殨 (<CJK Ideograph>) 4835 0x6BA9 殩 (<CJK Ideograph>) 4836 0x6BAB 殫 (<CJK Ideograph>) 4837 0x6BAC 殬 (<CJK Ideograph>) 4838 0x6BAD 殭 (<CJK Ideograph>) 4839 0x6BAE 殮 (<CJK Ideograph>) 4840 0x6BAF 殯 (<CJK Ideograph>) 4841 0x6BB0 殰 (<CJK Ideograph>) 4842 0x6BB1 殱 (<CJK Ideograph>) 4843 0x6BB2 殲 (<CJK Ideograph>) 4844 0x6BB6 殶 (<CJK Ideograph>) 4845 0x6BB8 殸 (<CJK Ideograph>) 4846 0x6BB9 殹 (<CJK Ideograph>) 4847 0x6BBA 殺 (<CJK Ideograph>) 4848 0x6BBB 殻 (<CJK Ideograph>) 4849 0x6BBC 殼 (<CJK Ideograph>) 4850 0x6BBD 殽 (<CJK Ideograph>) 4851 0x6BBE 殾 (<CJK Ideograph>) 4852 0x6BC0 毀 (<CJK Ideograph>) 4853 0x6BC3 毃 (<CJK Ideograph>) 4854 0x6BC4 毄 (<CJK Ideograph>) 4855 0x6BC6 毆 (<CJK Ideograph>) 4856 0x6BC7 毇 (<CJK Ideograph>) 4857 0x6BC8 毈 (<CJK Ideograph>) 4858 0x6BC9 毉 (<CJK Ideograph>) 4859 0x6BCA 毊 (<CJK Ideograph>) 4860 0x6BCC 毌 (<CJK Ideograph>) 4861 0x6BCE 毎 (<CJK Ideograph>) 4862 0x6BD0 毐 (<CJK Ideograph>) 4863 0x6BD1 毑 (<CJK Ideograph>) 4864 0x6BD8 毘 (<CJK Ideograph>) 4865 0x6BDA 毚 (<CJK Ideograph>) 4866 0x6BDC 毜 (<CJK Ideograph>) 4867 0x6BDD 毝 (<CJK Ideograph>) 4868 0x6BDE 毞 (<CJK Ideograph>) 4869 0x6BDF 毟 (<CJK Ideograph>) 4870 0x6BE0 毠 (<CJK Ideograph>) 4871 0x6BE2 毢 (<CJK Ideograph>) 4872 0x6BE3 毣 (<CJK Ideograph>) 4873 0x6BE4 毤 (<CJK Ideograph>) 4874 0x6BE5 毥 (<CJK Ideograph>) 4875 0x6BE6 毦 (<CJK Ideograph>) 4876 0x6BE7 毧 (<CJK Ideograph>) 4877 0x6BE8 毨 (<CJK Ideograph>) 4878 0x6BE9 毩 (<CJK Ideograph>) 4879 0x6BEC 毬 (<CJK Ideograph>) 4880 0x6BED 毭 (<CJK Ideograph>) 4881 0x6BEE 毮 (<CJK Ideograph>) 4882 0x6BF0 毰 (<CJK Ideograph>) 4883 0x6BF1 毱 (<CJK Ideograph>) 4884 0x6BF2 毲 (<CJK Ideograph>) 4885 0x6BF4 毴 (<CJK Ideograph>) 4886 0x6BF6 毶 (<CJK Ideograph>) 4887 0x6BF7 毷 (<CJK Ideograph>) 4888 0x6BF8 毸 (<CJK Ideograph>) 4889 0x6BFA 毺 (<CJK Ideograph>) 4890 0x6BFB 毻 (<CJK Ideograph>) 4891 0x6BFC 毼 (<CJK Ideograph>) 4892 0x6BFE 毾 (<CJK Ideograph>) 4893 0x6BFF 毿 (<CJK Ideograph>) 4894 0x6C00 氀 (<CJK Ideograph>) 4895 0x6C01 氁 (<CJK Ideograph>) 4896 0x6C02 氂 (<CJK Ideograph>) 4897 0x6C03 氃 (<CJK Ideograph>) 4898 0x6C04 氄 (<CJK Ideograph>) 4899 0x6C08 氈 (<CJK Ideograph>) 4900 0x6C09 氉 (<CJK Ideograph>) 4901 0x6C0A 氊 (<CJK Ideograph>) 4902 0x6C0B 氋 (<CJK Ideograph>) 4903 0x6C0C 氌 (<CJK Ideograph>) 4904 0x6C0E 氎 (<CJK Ideograph>) 4905 0x6C12 氒 (<CJK Ideograph>) 4906 0x6C17 気 (<CJK Ideograph>) 4907 0x6C1C 氜 (<CJK Ideograph>) 4908 0x6C1D 氝 (<CJK Ideograph>) 4909 0x6C1E 氞 (<CJK Ideograph>) 4910 0x6C20 氠 (<CJK Ideograph>) 4911 0x6C23 氣 (<CJK Ideograph>) 4912 0x6C25 氥 (<CJK Ideograph>) 4913 0x6C2B 氫 (<CJK Ideograph>) 4914 0x6C2C 氬 (<CJK Ideograph>) 4915 0x6C2D 氭 (<CJK Ideograph>) 4916 0x6C31 氱 (<CJK Ideograph>) 4917 0x6C33 氳 (<CJK Ideograph>) 4918 0x6C36 氶 (<CJK Ideograph>) 4919 0x6C37 氷 (<CJK Ideograph>) 4920 0x6C39 氹 (<CJK Ideograph>) 4921 0x6C3A 氺 (<CJK Ideograph>) 4922 0x6C3B 氻 (<CJK Ideograph>) 4923 0x6C3C 氼 (<CJK Ideograph>) 4924 0x6C3E 氾 (<CJK Ideograph>) 4925 0x6C3F 氿 (<CJK Ideograph>) 4926 0x6C43 汃 (<CJK Ideograph>) 4927 0x6C44 汄 (<CJK Ideograph>) 4928 0x6C45 汅 (<CJK Ideograph>) 4929 0x6C48 汈 (<CJK Ideograph>) 4930 0x6C4B 汋 (<CJK Ideograph>) 4931 0x6C4C 汌 (<CJK Ideograph>) 4932 0x6C4D 汍 (<CJK Ideograph>) 4933 0x6C4E 汎 (<CJK Ideograph>) 4934 0x6C4F 汏 (<CJK Ideograph>) 4935 0x6C51 汑 (<CJK Ideograph>) 4936 0x6C52 汒 (<CJK Ideograph>) 4937 0x6C53 汓 (<CJK Ideograph>) 4938 0x6C56 汖 (<CJK Ideograph>) 4939 0x6C58 汘 (<CJK Ideograph>) 4940 0x6C59 汙 (<CJK Ideograph>) 4941 0x6C5A 汚 (<CJK Ideograph>) 4942 0x6C62 汢 (<CJK Ideograph>) 4943 0x6C63 汣 (<CJK Ideograph>) 4944 0x6C65 汥 (<CJK Ideograph>) 4945 0x6C66 汦 (<CJK Ideograph>) 4946 0x6C67 汧 (<CJK Ideograph>) 4947 0x6C6B 汫 (<CJK Ideograph>) 4948 0x6C6C 汬 (<CJK Ideograph>) 4949 0x6C6D 汭 (<CJK Ideograph>) 4950 0x6C6E 汮 (<CJK Ideograph>) 4951 0x6C6F 汯 (<CJK Ideograph>) 4952 0x6C71 汱 (<CJK Ideograph>) 4953 0x6C73 汳 (<CJK Ideograph>) 4954 0x6C75 汵 (<CJK Ideograph>) 4955 0x6C77 汷 (<CJK Ideograph>) 4956 0x6C78 汸 (<CJK Ideograph>) 4957 0x6C7A 決 (<CJK Ideograph>) 4958 0x6C7B 汻 (<CJK Ideograph>) 4959 0x6C7C 汼 (<CJK Ideograph>) 4960 0x6C7F 汿 (<CJK Ideograph>) 4961 0x6C80 沀 (<CJK Ideograph>) 4962 0x6C84 沄 (<CJK Ideograph>) 4963 0x6C87 沇 (<CJK Ideograph>) 4964 0x6C8A 沊 (<CJK Ideograph>) 4965 0x6C8B 沋 (<CJK Ideograph>) 4966 0x6C8D 沍 (<CJK Ideograph>) 4967 0x6C8E 沎 (<CJK Ideograph>) 4968 0x6C91 沑 (<CJK Ideograph>) 4969 0x6C92 沒 (<CJK Ideograph>) 4970 0x6C95 沕 (<CJK Ideograph>) 4971 0x6C96 沖 (<CJK Ideograph>) 4972 0x6C97 沗 (<CJK Ideograph>) 4973 0x6C98 沘 (<CJK Ideograph>) 4974 0x6C9A 沚 (<CJK Ideograph>) 4975 0x6C9C 沜 (<CJK Ideograph>) 4976 0x6C9D 沝 (<CJK Ideograph>) 4977 0x6C9E 沞 (<CJK Ideograph>) 4978 0x6CA0 沠 (<CJK Ideograph>) 4979 0x6CA2 沢 (<CJK Ideograph>) 4980 0x6CA8 沨 (<CJK Ideograph>) 4981 0x6CAC 沬 (<CJK Ideograph>) 4982 0x6CAF 沯 (<CJK Ideograph>) 4983 0x6CB0 沰 (<CJK Ideograph>) 4984 0x6CB4 沴 (<CJK Ideograph>) 4985 0x6CB5 沵 (<CJK Ideograph>) 4986 0x6CB6 沶 (<CJK Ideograph>) 4987 0x6CB7 沷 (<CJK Ideograph>) 4988 0x6CBA 沺 (<CJK Ideograph>) 4989 0x6CC0 泀 (<CJK Ideograph>) 4990 0x6CC1 況 (<CJK Ideograph>) 4991 0x6CC2 泂 (<CJK Ideograph>) 4992 0x6CC3 泃 (<CJK Ideograph>) 4993 0x6CC6 泆 (<CJK Ideograph>) 4994 0x6CC7 泇 (<CJK Ideograph>) 4995 0x6CC8 泈 (<CJK Ideograph>) 4996 0x6CCB 泋 (<CJK Ideograph>) 4997 0x6CCD 泍 (<CJK Ideograph>) 4998 0x6CCE 泎 (<CJK Ideograph>) 4999 0x6CCF 泏 (<CJK Ideograph>) 5000 0x6CD1 泑 (<CJK Ideograph>) 5001 0x6CD2 泒 (<CJK Ideograph>) 5002 0x6CD8 泘 (<CJK Ideograph>) 5003 0x6CD9 泙 (<CJK Ideograph>) 5004 0x6CDA 泚 (<CJK Ideograph>) 5005 0x6CDC 泜 (<CJK Ideograph>) 5006 0x6CDD 泝 (<CJK Ideograph>) 5007 0x6CDF 泟 (<CJK Ideograph>) 5008 0x6CE4 泤 (<CJK Ideograph>) 5009 0x6CE6 泦 (<CJK Ideograph>) 5010 0x6CE7 泧 (<CJK Ideograph>) 5011 0x6CE9 泩 (<CJK Ideograph>) 5012 0x6CEC 泬 (<CJK Ideograph>) 5013 0x6CED 泭 (<CJK Ideograph>) 5014 0x6CF2 泲 (<CJK Ideograph>) 5015 0x6CF4 泴 (<CJK Ideograph>) 5016 0x6CF9 泹 (<CJK Ideograph>) 5017 0x6CFF 泿 (<CJK Ideograph>) 5018 0x6D00 洀 (<CJK Ideograph>) 5019 0x6D02 洂 (<CJK Ideograph>) 5020 0x6D03 洃 (<CJK Ideograph>) 5021 0x6D05 洅 (<CJK Ideograph>) 5022 0x6D06 洆 (<CJK Ideograph>) 5023 0x6D08 洈 (<CJK Ideograph>) 5024 0x6D09 洉 (<CJK Ideograph>) 5025 0x6D0A 洊 (<CJK Ideograph>) 5026 0x6D0D 洍 (<CJK Ideograph>) 5027 0x6D0F 洏 (<CJK Ideograph>) 5028 0x6D10 洐 (<CJK Ideograph>) 5029 0x6D11 洑 (<CJK Ideograph>) 5030 0x6D13 洓 (<CJK Ideograph>) 5031 0x6D14 洔 (<CJK Ideograph>) 5032 0x6D15 洕 (<CJK Ideograph>) 5033 0x6D16 洖 (<CJK Ideograph>) 5034 0x6D18 洘 (<CJK Ideograph>) 5035 0x6D1C 洜 (<CJK Ideograph>) 5036 0x6D1D 洝 (<CJK Ideograph>) 5037 0x6D1F 洟 (<CJK Ideograph>) 5038 0x6D20 洠 (<CJK Ideograph>) 5039 0x6D21 洡 (<CJK Ideograph>) 5040 0x6D22 洢 (<CJK Ideograph>) 5041 0x6D23 洣 (<CJK Ideograph>) 5042 0x6D24 洤 (<CJK Ideograph>) 5043 0x6D26 洦 (<CJK Ideograph>) 5044 0x6D28 洨 (<CJK Ideograph>) 5045 0x6D29 洩 (<CJK Ideograph>) 5046 0x6D2C 洬 (<CJK Ideograph>) 5047 0x6D2D 洭 (<CJK Ideograph>) 5048 0x6D2F 洯 (<CJK Ideograph>) 5049 0x6D30 洰 (<CJK Ideograph>) 5050 0x6D34 洴 (<CJK Ideograph>) 5051 0x6D36 洶 (<CJK Ideograph>) 5052 0x6D37 洷 (<CJK Ideograph>) 5053 0x6D38 洸 (<CJK Ideograph>) 5054 0x6D3A 洺 (<CJK Ideograph>) 5055 0x6D3F 洿 (<CJK Ideograph>) 5056 0x6D40 浀 (<CJK Ideograph>) 5057 0x6D42 浂 (<CJK Ideograph>) 5058 0x6D44 浄 (<CJK Ideograph>) 5059 0x6D49 浉 (<CJK Ideograph>) 5060 0x6D4C 浌 (<CJK Ideograph>) 5061 0x6D50 浐 (<CJK Ideograph>) 5062 0x6D55 浕 (<CJK Ideograph>) 5063 0x6D56 浖 (<CJK Ideograph>) 5064 0x6D57 浗 (<CJK Ideograph>) 5065 0x6D58 浘 (<CJK Ideograph>) 5066 0x6D5B 浛 (<CJK Ideograph>) 5067 0x6D5D 浝 (<CJK Ideograph>) 5068 0x6D5F 浟 (<CJK Ideograph>) 5069 0x6D61 浡 (<CJK Ideograph>) 5070 0x6D62 浢 (<CJK Ideograph>) 5071 0x6D64 浤 (<CJK Ideograph>) 5072 0x6D65 浥 (<CJK Ideograph>) 5073 0x6D67 浧 (<CJK Ideograph>) 5074 0x6D68 浨 (<CJK Ideograph>) 5075 0x6D6B 浫 (<CJK Ideograph>) 5076 0x6D6C 浬 (<CJK Ideograph>) 5077 0x6D6D 浭 (<CJK Ideograph>) 5078 0x6D70 浰 (<CJK Ideograph>) 5079 0x6D71 浱 (<CJK Ideograph>) 5080 0x6D72 浲 (<CJK Ideograph>) 5081 0x6D73 浳 (<CJK Ideograph>) 5082 0x6D75 浵 (<CJK Ideograph>) 5083 0x6D76 浶 (<CJK Ideograph>) 5084 0x6D79 浹 (<CJK Ideograph>) 5085 0x6D7A 浺 (<CJK Ideograph>) 5086 0x6D7B 浻 (<CJK Ideograph>) 5087 0x6D7D 浽 (<CJK Ideograph>) 5088 0x6D7E 浾 (<CJK Ideograph>) 5089 0x6D7F 浿 (<CJK Ideograph>) 5090 0x6D80 涀 (<CJK Ideograph>) 5091 0x6D81 涁 (<CJK Ideograph>) 5092 0x6D83 涃 (<CJK Ideograph>) 5093 0x6D84 涄 (<CJK Ideograph>) 5094 0x6D86 涆 (<CJK Ideograph>) 5095 0x6D87 涇 (<CJK Ideograph>) 5096 0x6D8A 涊 (<CJK Ideograph>) 5097 0x6D8B 涋 (<CJK Ideograph>) 5098 0x6D8D 涍 (<CJK Ideograph>) 5099 0x6D8F 涏 (<CJK Ideograph>) 5100 0x6D90 涐 (<CJK Ideograph>) 5101 0x6D92 涒 (<CJK Ideograph>) 5102 0x6D96 涖 (<CJK Ideograph>) 5103 0x6D97 涗 (<CJK Ideograph>) 5104 0x6D98 涘 (<CJK Ideograph>) 5105 0x6D99 涙 (<CJK Ideograph>) 5106 0x6D9A 涚 (<CJK Ideograph>) 5107 0x6D9C 涜 (<CJK Ideograph>) 5108 0x6DA2 涢 (<CJK Ideograph>) 5109 0x6DA5 涥 (<CJK Ideograph>) 5110 0x6DAC 涬 (<CJK Ideograph>) 5111 0x6DAD 涭 (<CJK Ideograph>) 5112 0x6DB0 涰 (<CJK Ideograph>) 5113 0x6DB1 涱 (<CJK Ideograph>) 5114 0x6DB3 涳 (<CJK Ideograph>) 5115 0x6DB4 涴 (<CJK Ideograph>) 5116 0x6DB6 涶 (<CJK Ideograph>) 5117 0x6DB7 涷 (<CJK Ideograph>) 5118 0x6DB9 涹 (<CJK Ideograph>) 5119 0x6DBA 涺 (<CJK Ideograph>) 5120 0x6DBB 涻 (<CJK Ideograph>) 5121 0x6DBC 涼 (<CJK Ideograph>) 5122 0x6DBD 涽 (<CJK Ideograph>) 5123 0x6DBE 涾 (<CJK Ideograph>) 5124 0x6DC1 淁 (<CJK Ideograph>) 5125 0x6DC2 淂 (<CJK Ideograph>) 5126 0x6DC3 淃 (<CJK Ideograph>) 5127 0x6DC8 淈 (<CJK Ideograph>) 5128 0x6DC9 淉 (<CJK Ideograph>) 5129 0x6DCA 淊 (<CJK Ideograph>) 5130 0x6DCD 淍 (<CJK Ideograph>) 5131 0x6DCE 淎 (<CJK Ideograph>) 5132 0x6DCF 淏 (<CJK Ideograph>) 5133 0x6DD0 淐 (<CJK Ideograph>) 5134 0x6DD2 淒 (<CJK Ideograph>) 5135 0x6DD3 淓 (<CJK Ideograph>) 5136 0x6DD4 淔 (<CJK Ideograph>) 5137 0x6DD5 淕 (<CJK Ideograph>) 5138 0x6DD7 淗 (<CJK Ideograph>) 5139 0x6DDA 淚 (<CJK Ideograph>) 5140 0x6DDB 淛 (<CJK Ideograph>) 5141 0x6DDC 淜 (<CJK Ideograph>) 5142 0x6DDF 淟 (<CJK Ideograph>) 5143 0x6DE2 淢 (<CJK Ideograph>) 5144 0x6DE3 淣 (<CJK Ideograph>) 5145 0x6DE5 淥 (<CJK Ideograph>) 5146 0x6DE7 淧 (<CJK Ideograph>) 5147 0x6DE8 淨 (<CJK Ideograph>) 5148 0x6DE9 淩 (<CJK Ideograph>) 5149 0x6DEA 淪 (<CJK Ideograph>) 5150 0x6DED 淭 (<CJK Ideograph>) 5151 0x6DEF 淯 (<CJK Ideograph>) 5152 0x6DF0 淰 (<CJK Ideograph>) 5153 0x6DF2 淲 (<CJK Ideograph>) 5154 0x6DF4 淴 (<CJK Ideograph>) 5155 0x6DF5 淵 (<CJK Ideograph>) 5156 0x6DF6 淶 (<CJK Ideograph>) 5157 0x6DF8 淸 (<CJK Ideograph>) 5158 0x6DFA 淺 (<CJK Ideograph>) 5159 0x6DFD 淽 (<CJK Ideograph>) 5160 0x6DFE 淾 (<CJK Ideograph>) 5161 0x6DFF 淿 (<CJK Ideograph>) 5162 0x6E00 渀 (<CJK Ideograph>) 5163 0x6E01 渁 (<CJK Ideograph>) 5164 0x6E02 渂 (<CJK Ideograph>) 5165 0x6E03 渃 (<CJK Ideograph>) 5166 0x6E04 渄 (<CJK Ideograph>) 5167 0x6E06 渆 (<CJK Ideograph>) 5168 0x6E07 渇 (<CJK Ideograph>) 5169 0x6E08 済 (<CJK Ideograph>) 5170 0x6E09 渉 (<CJK Ideograph>) 5171 0x6E0B 渋 (<CJK Ideograph>) 5172 0x6E0F 渏 (<CJK Ideograph>) 5173 0x6E12 渒 (<CJK Ideograph>) 5174 0x6E13 渓 (<CJK Ideograph>) 5175 0x6E15 渕 (<CJK Ideograph>) 5176 0x6E18 渘 (<CJK Ideograph>) 5177 0x6E19 渙 (<CJK Ideograph>) 5178 0x6E1B 減 (<CJK Ideograph>) 5179 0x6E1C 渜 (<CJK Ideograph>) 5180 0x6E1E 渞 (<CJK Ideograph>) 5181 0x6E1F 渟 (<CJK Ideograph>) 5182 0x6E22 渢 (<CJK Ideograph>) 5183 0x6E26 渦 (<CJK Ideograph>) 5184 0x6E27 渧 (<CJK Ideograph>) 5185 0x6E28 渨 (<CJK Ideograph>) 5186 0x6E2A 渪 (<CJK Ideograph>) 5187 0x6E2C 測 (<CJK Ideograph>) 5188 0x6E2E 渮 (<CJK Ideograph>) 5189 0x6E30 渰 (<CJK Ideograph>) 5190 0x6E31 渱 (<CJK Ideograph>) 5191 0x6E33 渳 (<CJK Ideograph>) 5192 0x6E35 渵 (<CJK Ideograph>) 5193 0x6E36 渶 (<CJK Ideograph>) 5194 0x6E37 渷 (<CJK Ideograph>) 5195 0x6E39 渹 (<CJK Ideograph>) 5196 0x6E3B 渻 (<CJK Ideograph>) 5197 0x6E3C 渼 (<CJK Ideograph>) 5198 0x6E3D 渽 (<CJK Ideograph>) 5199 0x6E3E 渾 (<CJK Ideograph>) 5200 0x6E3F 渿 (<CJK Ideograph>) 5201 0x6E40 湀 (<CJK Ideograph>) 5202 0x6E41 湁 (<CJK Ideograph>) 5203 0x6E42 湂 (<CJK Ideograph>) 5204 0x6E45 湅 (<CJK Ideograph>) 5205 0x6E46 湆 (<CJK Ideograph>) 5206 0x6E47 湇 (<CJK Ideograph>) 5207 0x6E48 湈 (<CJK Ideograph>) 5208 0x6E49 湉 (<CJK Ideograph>) 5209 0x6E4A 湊 (<CJK Ideograph>) 5210 0x6E4B 湋 (<CJK Ideograph>) 5211 0x6E4C 湌 (<CJK Ideograph>) 5212 0x6E4F 湏 (<CJK Ideograph>) 5213 0x6E50 湐 (<CJK Ideograph>) 5214 0x6E51 湑 (<CJK Ideograph>) 5215 0x6E52 湒 (<CJK Ideograph>) 5216 0x6E55 湕 (<CJK Ideograph>) 5217 0x6E57 湗 (<CJK Ideograph>) 5218 0x6E59 湙 (<CJK Ideograph>) 5219 0x6E5A 湚 (<CJK Ideograph>) 5220 0x6E5C 湜 (<CJK Ideograph>) 5221 0x6E5D 湝 (<CJK Ideograph>) 5222 0x6E5E 湞 (<CJK Ideograph>) 5223 0x6E60 湠 (<CJK Ideograph>) 5224 0x6E61 湡 (<CJK Ideograph>) 5225 0x6E62 湢 (<CJK Ideograph>) 5226 0x6E63 湣 (<CJK Ideograph>) 5227 0x6E64 湤 (<CJK Ideograph>) 5228 0x6E65 湥 (<CJK Ideograph>) 5229 0x6E66 湦 (<CJK Ideograph>) 5230 0x6E67 湧 (<CJK Ideograph>) 5231 0x6E68 湨 (<CJK Ideograph>) 5232 0x6E69 湩 (<CJK Ideograph>) 5233 0x6E6A 湪 (<CJK Ideograph>) 5234 0x6E6C 湬 (<CJK Ideograph>) 5235 0x6E6D 湭 (<CJK Ideograph>) 5236 0x6E6F 湯 (<CJK Ideograph>) 5237 0x6E70 湰 (<CJK Ideograph>) 5238 0x6E71 湱 (<CJK Ideograph>) 5239 0x6E72 湲 (<CJK Ideograph>) 5240 0x6E73 湳 (<CJK Ideograph>) 5241 0x6E74 湴 (<CJK Ideograph>) 5242 0x6E75 湵 (<CJK Ideograph>) 5243 0x6E76 湶 (<CJK Ideograph>) 5244 0x6E77 湷 (<CJK Ideograph>) 5245 0x6E78 湸 (<CJK Ideograph>) 5246 0x6E79 湹 (<CJK Ideograph>) 5247 0x6E7A 湺 (<CJK Ideograph>) 5248 0x6E7B 湻 (<CJK Ideograph>) 5249 0x6E7C 湼 (<CJK Ideograph>) 5250 0x6E7D 湽 (<CJK Ideograph>) 5251 0x6E80 満 (<CJK Ideograph>) 5252 0x6E81 溁 (<CJK Ideograph>) 5253 0x6E82 溂 (<CJK Ideograph>) 5254 0x6E84 溄 (<CJK Ideograph>) 5255 0x6E87 溇 (<CJK Ideograph>) 5256 0x6E88 溈 (<CJK Ideograph>) 5257 0x6E8A 溊 (<CJK Ideograph>) 5258 0x6E8B 溋 (<CJK Ideograph>) 5259 0x6E8C 溌 (<CJK Ideograph>) 5260 0x6E8D 溍 (<CJK Ideograph>) 5261 0x6E8E 溎 (<CJK Ideograph>) 5262 0x6E91 溑 (<CJK Ideograph>) 5263 0x6E92 溒 (<CJK Ideograph>) 5264 0x6E93 溓 (<CJK Ideograph>) 5265 0x6E94 溔 (<CJK Ideograph>) 5266 0x6E95 溕 (<CJK Ideograph>) 5267 0x6E96 準 (<CJK Ideograph>) 5268 0x6E97 溗 (<CJK Ideograph>) 5269 0x6E99 溙 (<CJK Ideograph>) 5270 0x6E9A 溚 (<CJK Ideograph>) 5271 0x6E9B 溛 (<CJK Ideograph>) 5272 0x6E9D 溝 (<CJK Ideograph>) 5273 0x6E9E 溞 (<CJK Ideograph>) 5274 0x6EA0 溠 (<CJK Ideograph>) 5275 0x6EA1 溡 (<CJK Ideograph>) 5276 0x6EA3 溣 (<CJK Ideograph>) 5277 0x6EA4 溤 (<CJK Ideograph>) 5278 0x6EA6 溦 (<CJK Ideograph>) 5279 0x6EA8 溨 (<CJK Ideograph>) 5280 0x6EA9 溩 (<CJK Ideograph>) 5281 0x6EAB 溫 (<CJK Ideograph>) 5282 0x6EAC 溬 (<CJK Ideograph>) 5283 0x6EAD 溭 (<CJK Ideograph>) 5284 0x6EAE 溮 (<CJK Ideograph>) 5285 0x6EB0 溰 (<CJK Ideograph>) 5286 0x6EB3 溳 (<CJK Ideograph>) 5287 0x6EB5 溵 (<CJK Ideograph>) 5288 0x6EB8 溸 (<CJK Ideograph>) 5289 0x6EB9 溹 (<CJK Ideograph>) 5290 0x6EBC 溼 (<CJK Ideograph>) 5291 0x6EBE 溾 (<CJK Ideograph>) 5292 0x6EBF 溿 (<CJK Ideograph>) 5293 0x6EC0 滀 (<CJK Ideograph>) 5294 0x6EC3 滃 (<CJK Ideograph>) 5295 0x6EC4 滄 (<CJK Ideograph>) 5296 0x6EC5 滅 (<CJK Ideograph>) 5297 0x6EC6 滆 (<CJK Ideograph>) 5298 0x6EC8 滈 (<CJK Ideograph>) 5299 0x6EC9 滉 (<CJK Ideograph>) 5300 0x6ECA 滊 (<CJK Ideograph>) 5301 0x6ECC 滌 (<CJK Ideograph>) 5302 0x6ECD 滍 (<CJK Ideograph>) 5303 0x6ECE 滎 (<CJK Ideograph>) 5304 0x6ED0 滐 (<CJK Ideograph>) 5305 0x6ED2 滒 (<CJK Ideograph>) 5306 0x6ED6 滖 (<CJK Ideograph>) 5307 0x6ED8 滘 (<CJK Ideograph>) 5308 0x6ED9 滙 (<CJK Ideograph>) 5309 0x6EDB 滛 (<CJK Ideograph>) 5310 0x6EDC 滜 (<CJK Ideograph>) 5311 0x6EDD 滝 (<CJK Ideograph>) 5312 0x6EE3 滣 (<CJK Ideograph>) 5313 0x6EE7 滧 (<CJK Ideograph>) 5314 0x6EEA 滪 (<CJK Ideograph>) 5315 0x6EEB 滫 (<CJK Ideograph>) 5316 0x6EEC 滬 (<CJK Ideograph>) 5317 0x6EED 滭 (<CJK Ideograph>) 5318 0x6EEE 滮 (<CJK Ideograph>) 5319 0x6EEF 滯 (<CJK Ideograph>) 5320 0x6EF0 滰 (<CJK Ideograph>) 5321 0x6EF1 滱 (<CJK Ideograph>) 5322 0x6EF2 滲 (<CJK Ideograph>) 5323 0x6EF3 滳 (<CJK Ideograph>) 5324 0x6EF5 滵 (<CJK Ideograph>) 5325 0x6EF6 滶 (<CJK Ideograph>) 5326 0x6EF7 滷 (<CJK Ideograph>) 5327 0x6EF8 滸 (<CJK Ideograph>) 5328 0x6EFA 滺 (<CJK Ideograph>) 5329 0x6EFB 滻 (<CJK Ideograph>) 5330 0x6EFC 滼 (<CJK Ideograph>) 5331 0x6EFD 滽 (<CJK Ideograph>) 5332 0x6EFE 滾 (<CJK Ideograph>) 5333 0x6EFF 滿 (<CJK Ideograph>) 5334 0x6F00 漀 (<CJK Ideograph>) 5335 0x6F01 漁 (<CJK Ideograph>) 5336 0x6F03 漃 (<CJK Ideograph>) 5337 0x6F04 漄 (<CJK Ideograph>) 5338 0x6F05 漅 (<CJK Ideograph>) 5339 0x6F07 漇 (<CJK Ideograph>) 5340 0x6F08 漈 (<CJK Ideograph>) 5341 0x6F0A 漊 (<CJK Ideograph>) 5342 0x6F0B 漋 (<CJK Ideograph>) 5343 0x6F0C 漌 (<CJK Ideograph>) 5344 0x6F0D 漍 (<CJK Ideograph>) 5345 0x6F0E 漎 (<CJK Ideograph>) 5346 0x6F10 漐 (<CJK Ideograph>) 5347 0x6F11 漑 (<CJK Ideograph>) 5348 0x6F12 漒 (<CJK Ideograph>) 5349 0x6F16 漖 (<CJK Ideograph>) 5350 0x6F17 漗 (<CJK Ideograph>) 5351 0x6F18 漘 (<CJK Ideograph>) 5352 0x6F19 漙 (<CJK Ideograph>) 5353 0x6F1A 漚 (<CJK Ideograph>) 5354 0x6F1B 漛 (<CJK Ideograph>) 5355 0x6F1C 漜 (<CJK Ideograph>) 5356 0x6F1D 漝 (<CJK Ideograph>) 5357 0x6F1E 漞 (<CJK Ideograph>) 5358 0x6F1F 漟 (<CJK Ideograph>) 5359 0x6F21 漡 (<CJK Ideograph>) 5360 0x6F22 漢 (<CJK Ideograph>) 5361 0x6F23 漣 (<CJK Ideograph>) 5362 0x6F25 漥 (<CJK Ideograph>) 5363 0x6F26 漦 (<CJK Ideograph>) 5364 0x6F27 漧 (<CJK Ideograph>) 5365 0x6F28 漨 (<CJK Ideograph>) 5366 0x6F2C 漬 (<CJK Ideograph>) 5367 0x6F2E 漮 (<CJK Ideograph>) 5368 0x6F30 漰 (<CJK Ideograph>) 5369 0x6F32 漲 (<CJK Ideograph>) 5370 0x6F34 漴 (<CJK Ideograph>) 5371 0x6F35 漵 (<CJK Ideograph>) 5372 0x6F37 漷 (<CJK Ideograph>) 5373 0x6F38 漸 (<CJK Ideograph>) 5374 0x6F39 漹 (<CJK Ideograph>) 5375 0x6F3A 漺 (<CJK Ideograph>) 5376 0x6F3B 漻 (<CJK Ideograph>) 5377 0x6F3C 漼 (<CJK Ideograph>) 5378 0x6F3D 漽 (<CJK Ideograph>) 5379 0x6F3F 漿 (<CJK Ideograph>) 5380 0x6F40 潀 (<CJK Ideograph>) 5381 0x6F41 潁 (<CJK Ideograph>) 5382 0x6F42 潂 (<CJK Ideograph>) 5383 0x6F43 潃 (<CJK Ideograph>) 5384 0x6F44 潄 (<CJK Ideograph>) 5385 0x6F45 潅 (<CJK Ideograph>) 5386 0x6F48 潈 (<CJK Ideograph>) 5387 0x6F49 潉 (<CJK Ideograph>) 5388 0x6F4A 潊 (<CJK Ideograph>) 5389 0x6F4C 潌 (<CJK Ideograph>) 5390 0x6F4E 潎 (<CJK Ideograph>) 5391 0x6F4F 潏 (<CJK Ideograph>) 5392 0x6F50 潐 (<CJK Ideograph>) 5393 0x6F51 潑 (<CJK Ideograph>) 5394 0x6F52 潒 (<CJK Ideograph>) 5395 0x6F53 潓 (<CJK Ideograph>) 5396 0x6F54 潔 (<CJK Ideograph>) 5397 0x6F55 潕 (<CJK Ideograph>) 5398 0x6F56 潖 (<CJK Ideograph>) 5399 0x6F57 潗 (<CJK Ideograph>) 5400 0x6F59 潙 (<CJK Ideograph>) 5401 0x6F5A 潚 (<CJK Ideograph>) 5402 0x6F5B 潛 (<CJK Ideograph>) 5403 0x6F5D 潝 (<CJK Ideograph>) 5404 0x6F5F 潟 (<CJK Ideograph>) 5405 0x6F60 潠 (<CJK Ideograph>) 5406 0x6F61 潡 (<CJK Ideograph>) 5407 0x6F63 潣 (<CJK Ideograph>) 5408 0x6F64 潤 (<CJK Ideograph>) 5409 0x6F65 潥 (<CJK Ideograph>) 5410 0x6F67 潧 (<CJK Ideograph>) 5411 0x6F68 潨 (<CJK Ideograph>) 5412 0x6F69 潩 (<CJK Ideograph>) 5413 0x6F6A 潪 (<CJK Ideograph>) 5414 0x6F6B 潫 (<CJK Ideograph>) 5415 0x6F6C 潬 (<CJK Ideograph>) 5416 0x6F6F 潯 (<CJK Ideograph>) 5417 0x6F70 潰 (<CJK Ideograph>) 5418 0x6F71 潱 (<CJK Ideograph>) 5419 0x6F73 潳 (<CJK Ideograph>) 5420 0x6F75 潵 (<CJK Ideograph>) 5421 0x6F76 潶 (<CJK Ideograph>) 5422 0x6F77 潷 (<CJK Ideograph>) 5423 0x6F79 潹 (<CJK Ideograph>) 5424 0x6F7B 潻 (<CJK Ideograph>) 5425 0x6F7D 潽 (<CJK Ideograph>) 5426 0x6F7E 潾 (<CJK Ideograph>) 5427 0x6F7F 潿 (<CJK Ideograph>) 5428 0x6F80 澀 (<CJK Ideograph>) 5429 0x6F81 澁 (<CJK Ideograph>) 5430 0x6F82 澂 (<CJK Ideograph>) 5431 0x6F83 澃 (<CJK Ideograph>) 5432 0x6F85 澅 (<CJK Ideograph>) 5433 0x6F86 澆 (<CJK Ideograph>) 5434 0x6F87 澇 (<CJK Ideograph>) 5435 0x6F8A 澊 (<CJK Ideograph>) 5436 0x6F8B 澋 (<CJK Ideograph>) 5437 0x6F8F 澏 (<CJK Ideograph>) 5438 0x6F90 澐 (<CJK Ideograph>) 5439 0x6F91 澑 (<CJK Ideograph>) 5440 0x6F92 澒 (<CJK Ideograph>) 5441 0x6F93 澓 (<CJK Ideograph>) 5442 0x6F94 澔 (<CJK Ideograph>) 5443 0x6F95 澕 (<CJK Ideograph>) 5444 0x6F96 澖 (<CJK Ideograph>) 5445 0x6F97 澗 (<CJK Ideograph>) 5446 0x6F98 澘 (<CJK Ideograph>) 5447 0x6F99 澙 (<CJK Ideograph>) 5448 0x6F9A 澚 (<CJK Ideograph>) 5449 0x6F9B 澛 (<CJK Ideograph>) 5450 0x6F9D 澝 (<CJK Ideograph>) 5451 0x6F9E 澞 (<CJK Ideograph>) 5452 0x6F9F 澟 (<CJK Ideograph>) 5453 0x6FA0 澠 (<CJK Ideograph>) 5454 0x6FA2 澢 (<CJK Ideograph>) 5455 0x6FA3 澣 (<CJK Ideograph>) 5456 0x6FA4 澤 (<CJK Ideograph>) 5457 0x6FA5 澥 (<CJK Ideograph>) 5458 0x6FA6 澦 (<CJK Ideograph>) 5459 0x6FA8 澨 (<CJK Ideograph>) 5460 0x6FA9 澩 (<CJK Ideograph>) 5461 0x6FAA 澪 (<CJK Ideograph>) 5462 0x6FAB 澫 (<CJK Ideograph>) 5463 0x6FAC 澬 (<CJK Ideograph>) 5464 0x6FAD 澭 (<CJK Ideograph>) 5465 0x6FAE 澮 (<CJK Ideograph>) 5466 0x6FAF 澯 (<CJK Ideograph>) 5467 0x6FB0 澰 (<CJK Ideograph>) 5468 0x6FB1 澱 (<CJK Ideograph>) 5469 0x6FB2 澲 (<CJK Ideograph>) 5470 0x6FB4 澴 (<CJK Ideograph>) 5471 0x6FB5 澵 (<CJK Ideograph>) 5472 0x6FB7 澷 (<CJK Ideograph>) 5473 0x6FB8 澸 (<CJK Ideograph>) 5474 0x6FBA 澺 (<CJK Ideograph>) 5475 0x6FBB 澻 (<CJK Ideograph>) 5476 0x6FBC 澼 (<CJK Ideograph>) 5477 0x6FBD 澽 (<CJK Ideograph>) 5478 0x6FBE 澾 (<CJK Ideograph>) 5479 0x6FBF 澿 (<CJK Ideograph>) 5480 0x6FC1 濁 (<CJK Ideograph>) 5481 0x6FC3 濃 (<CJK Ideograph>) 5482 0x6FC4 濄 (<CJK Ideograph>) 5483 0x6FC5 濅 (<CJK Ideograph>) 5484 0x6FC6 濆 (<CJK Ideograph>) 5485 0x6FC7 濇 (<CJK Ideograph>) 5486 0x6FC8 濈 (<CJK Ideograph>) 5487 0x6FCA 濊 (<CJK Ideograph>) 5488 0x6FCB 濋 (<CJK Ideograph>) 5489 0x6FCC 濌 (<CJK Ideograph>) 5490 0x6FCD 濍 (<CJK Ideograph>) 5491 0x6FCE 濎 (<CJK Ideograph>) 5492 0x6FCF 濏 (<CJK Ideograph>) 5493 0x6FD0 濐 (<CJK Ideograph>) 5494 0x6FD3 濓 (<CJK Ideograph>) 5495 0x6FD4 濔 (<CJK Ideograph>) 5496 0x6FD5 濕 (<CJK Ideograph>) 5497 0x6FD6 濖 (<CJK Ideograph>) 5498 0x6FD7 濗 (<CJK Ideograph>) 5499 0x6FD8 濘 (<CJK Ideograph>) 5500 0x6FD9 濙 (<CJK Ideograph>) 5501 0x6FDA 濚 (<CJK Ideograph>) 5502 0x6FDB 濛 (<CJK Ideograph>) 5503 0x6FDC 濜 (<CJK Ideograph>) 5504 0x6FDD 濝 (<CJK Ideograph>) 5505 0x6FDF 濟 (<CJK Ideograph>) 5506 0x6FE2 濢 (<CJK Ideograph>) 5507 0x6FE3 濣 (<CJK Ideograph>) 5508 0x6FE4 濤 (<CJK Ideograph>) 5509 0x6FE5 濥 (<CJK Ideograph>) 5510 0x6FE6 濦 (<CJK Ideograph>) 5511 0x6FE7 濧 (<CJK Ideograph>) 5512 0x6FE8 濨 (<CJK Ideograph>) 5513 0x6FE9 濩 (<CJK Ideograph>) 5514 0x6FEA 濪 (<CJK Ideograph>) 5515 0x6FEB 濫 (<CJK Ideograph>) 5516 0x6FEC 濬 (<CJK Ideograph>) 5517 0x6FED 濭 (<CJK Ideograph>) 5518 0x6FF0 濰 (<CJK Ideograph>) 5519 0x6FF1 濱 (<CJK Ideograph>) 5520 0x6FF2 濲 (<CJK Ideograph>) 5521 0x6FF3 濳 (<CJK Ideograph>) 5522 0x6FF4 濴 (<CJK Ideograph>) 5523 0x6FF5 濵 (<CJK Ideograph>) 5524 0x6FF6 濶 (<CJK Ideograph>) 5525 0x6FF7 濷 (<CJK Ideograph>) 5526 0x6FF8 濸 (<CJK Ideograph>) 5527 0x6FF9 濹 (<CJK Ideograph>) 5528 0x6FFA 濺 (<CJK Ideograph>) 5529 0x6FFB 濻 (<CJK Ideograph>) 5530 0x6FFC 濼 (<CJK Ideograph>) 5531 0x6FFD 濽 (<CJK Ideograph>) 5532 0x6FFE 濾 (<CJK Ideograph>) 5533 0x6FFF 濿 (<CJK Ideograph>) 5534 0x7000 瀀 (<CJK Ideograph>) 5535 0x7001 瀁 (<CJK Ideograph>) 5536 0x7002 瀂 (<CJK Ideograph>) 5537 0x7003 瀃 (<CJK Ideograph>) 5538 0x7004 瀄 (<CJK Ideograph>) 5539 0x7005 瀅 (<CJK Ideograph>) 5540 0x7006 瀆 (<CJK Ideograph>) 5541 0x7007 瀇 (<CJK Ideograph>) 5542 0x7008 瀈 (<CJK Ideograph>) 5543 0x7009 瀉 (<CJK Ideograph>) 5544 0x700A 瀊 (<CJK Ideograph>) 5545 0x700B 瀋 (<CJK Ideograph>) 5546 0x700C 瀌 (<CJK Ideograph>) 5547 0x700D 瀍 (<CJK Ideograph>) 5548 0x700E 瀎 (<CJK Ideograph>) 5549 0x700F 瀏 (<CJK Ideograph>) 5550 0x7010 瀐 (<CJK Ideograph>) 5551 0x7012 瀒 (<CJK Ideograph>) 5552 0x7013 瀓 (<CJK Ideograph>) 5553 0x7014 瀔 (<CJK Ideograph>) 5554 0x7015 瀕 (<CJK Ideograph>) 5555 0x7016 瀖 (<CJK Ideograph>) 5556 0x7017 瀗 (<CJK Ideograph>) 5557 0x7018 瀘 (<CJK Ideograph>) 5558 0x7019 瀙 (<CJK Ideograph>) 5559 0x701C 瀜 (<CJK Ideograph>) 5560 0x701D 瀝 (<CJK Ideograph>) 5561 0x701E 瀞 (<CJK Ideograph>) 5562 0x701F 瀟 (<CJK Ideograph>) 5563 0x7020 瀠 (<CJK Ideograph>) 5564 0x7021 瀡 (<CJK Ideograph>) 5565 0x7022 瀢 (<CJK Ideograph>) 5566 0x7024 瀤 (<CJK Ideograph>) 5567 0x7025 瀥 (<CJK Ideograph>) 5568 0x7026 瀦 (<CJK Ideograph>) 5569 0x7027 瀧 (<CJK Ideograph>) 5570 0x7028 瀨 (<CJK Ideograph>) 5571 0x7029 瀩 (<CJK Ideograph>) 5572 0x702A 瀪 (<CJK Ideograph>) 5573 0x702B 瀫 (<CJK Ideograph>) 5574 0x702C 瀬 (<CJK Ideograph>) 5575 0x702D 瀭 (<CJK Ideograph>) 5576 0x702E 瀮 (<CJK Ideograph>) 5577 0x702F 瀯 (<CJK Ideograph>) 5578 0x7030 瀰 (<CJK Ideograph>) 5579 0x7031 瀱 (<CJK Ideograph>) 5580 0x7032 瀲 (<CJK Ideograph>) 5581 0x7033 瀳 (<CJK Ideograph>) 5582 0x7034 瀴 (<CJK Ideograph>) 5583 0x7036 瀶 (<CJK Ideograph>) 5584 0x7037 瀷 (<CJK Ideograph>) 5585 0x7038 瀸 (<CJK Ideograph>) 5586 0x703A 瀺 (<CJK Ideograph>) 5587 0x703B 瀻 (<CJK Ideograph>) 5588 0x703C 瀼 (<CJK Ideograph>) 5589 0x703D 瀽 (<CJK Ideograph>) 5590 0x703E 瀾 (<CJK Ideograph>) 5591 0x703F 瀿 (<CJK Ideograph>) 5592 0x7040 灀 (<CJK Ideograph>) 5593 0x7041 灁 (<CJK Ideograph>) 5594 0x7042 灂 (<CJK Ideograph>) 5595 0x7043 灃 (<CJK Ideograph>) 5596 0x7044 灄 (<CJK Ideograph>) 5597 0x7045 灅 (<CJK Ideograph>) 5598 0x7046 灆 (<CJK Ideograph>) 5599 0x7047 灇 (<CJK Ideograph>) 5600 0x7048 灈 (<CJK Ideograph>) 5601 0x7049 灉 (<CJK Ideograph>) 5602 0x704A 灊 (<CJK Ideograph>) 5603 0x704B 灋 (<CJK Ideograph>) 5604 0x704D 灍 (<CJK Ideograph>) 5605 0x704E 灎 (<CJK Ideograph>) 5606 0x7050 灐 (<CJK Ideograph>) 5607 0x7051 灑 (<CJK Ideograph>) 5608 0x7052 灒 (<CJK Ideograph>) 5609 0x7053 灓 (<CJK Ideograph>) 5610 0x7054 灔 (<CJK Ideograph>) 5611 0x7055 灕 (<CJK Ideograph>) 5612 0x7056 灖 (<CJK Ideograph>) 5613 0x7057 灗 (<CJK Ideograph>) 5614 0x7058 灘 (<CJK Ideograph>) 5615 0x7059 灙 (<CJK Ideograph>) 5616 0x705A 灚 (<CJK Ideograph>) 5617 0x705B 灛 (<CJK Ideograph>) 5618 0x705C 灜 (<CJK Ideograph>) 5619 0x705D 灝 (<CJK Ideograph>) 5620 0x705F 灟 (<CJK Ideograph>) 5621 0x7060 灠 (<CJK Ideograph>) 5622 0x7061 灡 (<CJK Ideograph>) 5623 0x7062 灢 (<CJK Ideograph>) 5624 0x7063 灣 (<CJK Ideograph>) 5625 0x7064 灤 (<CJK Ideograph>) 5626 0x7065 灥 (<CJK Ideograph>) 5627 0x7066 灦 (<CJK Ideograph>) 5628 0x7067 灧 (<CJK Ideograph>) 5629 0x7068 灨 (<CJK Ideograph>) 5630 0x7069 灩 (<CJK Ideograph>) 5631 0x706A 灪 (<CJK Ideograph>) 5632 0x706E 灮 (<CJK Ideograph>) 5633 0x7071 灱 (<CJK Ideograph>) 5634 0x7072 灲 (<CJK Ideograph>) 5635 0x7073 灳 (<CJK Ideograph>) 5636 0x7074 灴 (<CJK Ideograph>) 5637 0x7077 灷 (<CJK Ideograph>) 5638 0x7079 灹 (<CJK Ideograph>) 5639 0x707A 灺 (<CJK Ideograph>) 5640 0x707B 灻 (<CJK Ideograph>) 5641 0x707D 災 (<CJK Ideograph>) 5642 0x7081 炁 (<CJK Ideograph>) 5643 0x7082 炂 (<CJK Ideograph>) 5644 0x7083 炃 (<CJK Ideograph>) 5645 0x7084 炄 (<CJK Ideograph>) 5646 0x7086 炆 (<CJK Ideograph>) 5647 0x7087 炇 (<CJK Ideograph>) 5648 0x7088 炈 (<CJK Ideograph>) 5649 0x708B 炋 (<CJK Ideograph>) 5650 0x708C 炌 (<CJK Ideograph>) 5651 0x708D 炍 (<CJK Ideograph>) 5652 0x708F 炏 (<CJK Ideograph>) 5653 0x7090 炐 (<CJK Ideograph>) 5654 0x7091 炑 (<CJK Ideograph>) 5655 0x7093 炓 (<CJK Ideograph>) 5656 0x7097 炗 (<CJK Ideograph>) 5657 0x7098 炘 (<CJK Ideograph>) 5658 0x709A 炚 (<CJK Ideograph>) 5659 0x709B 炛 (<CJK Ideograph>) 5660 0x709E 炞 (<CJK Ideograph>) 5661 0x709F 炟 (<CJK Ideograph>) 5662 0x70A0 炠 (<CJK Ideograph>) 5663 0x70A1 炡 (<CJK Ideograph>) 5664 0x70A2 炢 (<CJK Ideograph>) 5665 0x70A3 炣 (<CJK Ideograph>) 5666 0x70A4 炤 (<CJK Ideograph>) 5667 0x70A5 炥 (<CJK Ideograph>) 5668 0x70A6 炦 (<CJK Ideograph>) 5669 0x70A7 炧 (<CJK Ideograph>) 5670 0x70A8 炨 (<CJK Ideograph>) 5671 0x70A9 炩 (<CJK Ideograph>) 5672 0x70AA 炪 (<CJK Ideograph>) 5673 0x70B0 炰 (<CJK Ideograph>) 5674 0x70B2 炲 (<CJK Ideograph>) 5675 0x70B4 炴 (<CJK Ideograph>) 5676 0x70B5 炵 (<CJK Ideograph>) 5677 0x70B6 炶 (<CJK Ideograph>) 5678 0x70BA 為 (<CJK Ideograph>) 5679 0x70BE 炾 (<CJK Ideograph>) 5680 0x70BF 炿 (<CJK Ideograph>) 5681 0x70C4 烄 (<CJK Ideograph>) 5682 0x70C5 烅 (<CJK Ideograph>) 5683 0x70C6 烆 (<CJK Ideograph>) 5684 0x70C7 烇 (<CJK Ideograph>) 5685 0x70C9 烉 (<CJK Ideograph>) 5686 0x70CB 烋 (<CJK Ideograph>) 5687 0x70CC 烌 (<CJK Ideograph>) 5688 0x70CD 烍 (<CJK Ideograph>) 5689 0x70CE 烎 (<CJK Ideograph>) 5690 0x70CF 烏 (<CJK Ideograph>) 5691 0x70D0 烐 (<CJK Ideograph>) 5692 0x70D1 烑 (<CJK Ideograph>) 5693 0x70D2 烒 (<CJK Ideograph>) 5694 0x70D3 烓 (<CJK Ideograph>) 5695 0x70D4 烔 (<CJK Ideograph>) 5696 0x70D5 烕 (<CJK Ideograph>) 5697 0x70D6 烖 (<CJK Ideograph>) 5698 0x70D7 烗 (<CJK Ideograph>) 5699 0x70DA 烚 (<CJK Ideograph>) 5700 0x70DC 烜 (<CJK Ideograph>) 5701 0x70DD 烝 (<CJK Ideograph>) 5702 0x70DE 烞 (<CJK Ideograph>) 5703 0x70E0 烠 (<CJK Ideograph>) 5704 0x70E1 烡 (<CJK Ideograph>) 5705 0x70E2 烢 (<CJK Ideograph>) 5706 0x70E3 烣 (<CJK Ideograph>) 5707 0x70E5 烥 (<CJK Ideograph>) 5708 0x70EA 烪 (<CJK Ideograph>) 5709 0x70EE 烮 (<CJK Ideograph>) 5710 0x70F0 烰 (<CJK Ideograph>) 5711 0x70F1 烱 (<CJK Ideograph>) 5712 0x70F2 烲 (<CJK Ideograph>) 5713 0x70F3 烳 (<CJK Ideograph>) 5714 0x70F4 烴 (<CJK Ideograph>) 5715 0x70F5 烵 (<CJK Ideograph>) 5716 0x70F6 烶 (<CJK Ideograph>) 5717 0x70F8 烸 (<CJK Ideograph>) 5718 0x70FA 烺 (<CJK Ideograph>) 5719 0x70FB 烻 (<CJK Ideograph>) 5720 0x70FC 烼 (<CJK Ideograph>) 5721 0x70FE 烾 (<CJK Ideograph>) 5722 0x70FF 烿 (<CJK Ideograph>) 5723 0x7100 焀 (<CJK Ideograph>) 5724 0x7101 焁 (<CJK Ideograph>) 5725 0x7102 焂 (<CJK Ideograph>) 5726 0x7103 焃 (<CJK Ideograph>) 5727 0x7104 焄 (<CJK Ideograph>) 5728 0x7105 焅 (<CJK Ideograph>) 5729 0x7106 焆 (<CJK Ideograph>) 5730 0x7107 焇 (<CJK Ideograph>) 5731 0x7108 焈 (<CJK Ideograph>) 5732 0x710B 焋 (<CJK Ideograph>) 5733 0x710C 焌 (<CJK Ideograph>) 5734 0x710D 焍 (<CJK Ideograph>) 5735 0x710E 焎 (<CJK Ideograph>) 5736 0x710F 焏 (<CJK Ideograph>) 5737 0x7111 焑 (<CJK Ideograph>) 5738 0x7112 焒 (<CJK Ideograph>) 5739 0x7114 焔 (<CJK Ideograph>) 5740 0x7117 焗 (<CJK Ideograph>) 5741 0x711B 焛 (<CJK Ideograph>) 5742 0x711C 焜 (<CJK Ideograph>) 5743 0x711D 焝 (<CJK Ideograph>) 5744 0x711E 焞 (<CJK Ideograph>) 5745 0x711F 焟 (<CJK Ideograph>) 5746 0x7120 焠 (<CJK Ideograph>) 5747 0x7121 無 (<CJK Ideograph>) 5748 0x7122 焢 (<CJK Ideograph>) 5749 0x7123 焣 (<CJK Ideograph>) 5750 0x7124 焤 (<CJK Ideograph>) 5751 0x7125 焥 (<CJK Ideograph>) 5752 0x7127 焧 (<CJK Ideograph>) 5753 0x7128 焨 (<CJK Ideograph>) 5754 0x7129 焩 (<CJK Ideograph>) 5755 0x712A 焪 (<CJK Ideograph>) 5756 0x712B 焫 (<CJK Ideograph>) 5757 0x712C 焬 (<CJK Ideograph>) 5758 0x712D 焭 (<CJK Ideograph>) 5759 0x712E 焮 (<CJK Ideograph>) 5760 0x7132 焲 (<CJK Ideograph>) 5761 0x7133 焳 (<CJK Ideograph>) 5762 0x7134 焴 (<CJK Ideograph>) 5763 0x7135 焵 (<CJK Ideograph>) 5764 0x7137 焷 (<CJK Ideograph>) 5765 0x7138 焸 (<CJK Ideograph>) 5766 0x7139 焹 (<CJK Ideograph>) 5767 0x713A 焺 (<CJK Ideograph>) 5768 0x713B 焻 (<CJK Ideograph>) 5769 0x713C 焼 (<CJK Ideograph>) 5770 0x713D 焽 (<CJK Ideograph>) 5771 0x713E 焾 (<CJK Ideograph>) 5772 0x713F 焿 (<CJK Ideograph>) 5773 0x7140 煀 (<CJK Ideograph>) 5774 0x7141 煁 (<CJK Ideograph>) 5775 0x7142 煂 (<CJK Ideograph>) 5776 0x7143 煃 (<CJK Ideograph>) 5777 0x7144 煄 (<CJK Ideograph>) 5778 0x7146 煆 (<CJK Ideograph>) 5779 0x7147 煇 (<CJK Ideograph>) 5780 0x7148 煈 (<CJK Ideograph>) 5781 0x7149 煉 (<CJK Ideograph>) 5782 0x714B 煋 (<CJK Ideograph>) 5783 0x714D 煍 (<CJK Ideograph>) 5784 0x714F 煏 (<CJK Ideograph>) 5785 0x7150 煐 (<CJK Ideograph>) 5786 0x7151 煑 (<CJK Ideograph>) 5787 0x7152 煒 (<CJK Ideograph>) 5788 0x7153 煓 (<CJK Ideograph>) 5789 0x7154 煔 (<CJK Ideograph>) 5790 0x7155 煕 (<CJK Ideograph>) 5791 0x7156 煖 (<CJK Ideograph>) 5792 0x7157 煗 (<CJK Ideograph>) 5793 0x7158 煘 (<CJK Ideograph>) 5794 0x7159 煙 (<CJK Ideograph>) 5795 0x715A 煚 (<CJK Ideograph>) 5796 0x715B 煛 (<CJK Ideograph>) 5797 0x715D 煝 (<CJK Ideograph>) 5798 0x715F 煟 (<CJK Ideograph>) 5799 0x7160 煠 (<CJK Ideograph>) 5800 0x7161 煡 (<CJK Ideograph>) 5801 0x7162 煢 (<CJK Ideograph>) 5802 0x7163 煣 (<CJK Ideograph>) 5803 0x7165 煥 (<CJK Ideograph>) 5804 0x7169 煩 (<CJK Ideograph>) 5805 0x716A 煪 (<CJK Ideograph>) 5806 0x716B 煫 (<CJK Ideograph>) 5807 0x716C 煬 (<CJK Ideograph>) 5808 0x716D 煭 (<CJK Ideograph>) 5809 0x716F 煯 (<CJK Ideograph>) 5810 0x7170 煰 (<CJK Ideograph>) 5811 0x7171 煱 (<CJK Ideograph>) 5812 0x7174 煴 (<CJK Ideograph>) 5813 0x7175 煵 (<CJK Ideograph>) 5814 0x7176 煶 (<CJK Ideograph>) 5815 0x7177 煷 (<CJK Ideograph>) 5816 0x7179 煹 (<CJK Ideograph>) 5817 0x717B 煻 (<CJK Ideograph>) 5818 0x717C 煼 (<CJK Ideograph>) 5819 0x717E 煾 (<CJK Ideograph>) 5820 0x717F 煿 (<CJK Ideograph>) 5821 0x7180 熀 (<CJK Ideograph>) 5822 0x7181 熁 (<CJK Ideograph>) 5823 0x7182 熂 (<CJK Ideograph>) 5824 0x7183 熃 (<CJK Ideograph>) 5825 0x7185 熅 (<CJK Ideograph>) 5826 0x7186 熆 (<CJK Ideograph>) 5827 0x7187 熇 (<CJK Ideograph>) 5828 0x7188 熈 (<CJK Ideograph>) 5829 0x7189 熉 (<CJK Ideograph>) 5830 0x718B 熋 (<CJK Ideograph>) 5831 0x718C 熌 (<CJK Ideograph>) 5832 0x718D 熍 (<CJK Ideograph>) 5833 0x718E 熎 (<CJK Ideograph>) 5834 0x7190 熐 (<CJK Ideograph>) 5835 0x7191 熑 (<CJK Ideograph>) 5836 0x7192 熒 (<CJK Ideograph>) 5837 0x7193 熓 (<CJK Ideograph>) 5838 0x7195 熕 (<CJK Ideograph>) 5839 0x7196 熖 (<CJK Ideograph>) 5840 0x7197 熗 (<CJK Ideograph>) 5841 0x719A 熚 (<CJK Ideograph>) 5842 0x719B 熛 (<CJK Ideograph>) 5843 0x719C 熜 (<CJK Ideograph>) 5844 0x719D 熝 (<CJK Ideograph>) 5845 0x719E 熞 (<CJK Ideograph>) 5846 0x71A1 熡 (<CJK Ideograph>) 5847 0x71A2 熢 (<CJK Ideograph>) 5848 0x71A3 熣 (<CJK Ideograph>) 5849 0x71A4 熤 (<CJK Ideograph>) 5850 0x71A5 熥 (<CJK Ideograph>) 5851 0x71A6 熦 (<CJK Ideograph>) 5852 0x71A7 熧 (<CJK Ideograph>) 5853 0x71A9 熩 (<CJK Ideograph>) 5854 0x71AA 熪 (<CJK Ideograph>) 5855 0x71AB 熫 (<CJK Ideograph>) 5856 0x71AD 熭 (<CJK Ideograph>) 5857 0x71AE 熮 (<CJK Ideograph>) 5858 0x71AF 熯 (<CJK Ideograph>) 5859 0x71B0 熰 (<CJK Ideograph>) 5860 0x71B1 熱 (<CJK Ideograph>) 5861 0x71B2 熲 (<CJK Ideograph>) 5862 0x71B4 熴 (<CJK Ideograph>) 5863 0x71B6 熶 (<CJK Ideograph>) 5864 0x71B7 熷 (<CJK Ideograph>) 5865 0x71B8 熸 (<CJK Ideograph>) 5866 0x71BA 熺 (<CJK Ideograph>) 5867 0x71BB 熻 (<CJK Ideograph>) 5868 0x71BC 熼 (<CJK Ideograph>) 5869 0x71BD 熽 (<CJK Ideograph>) 5870 0x71BE 熾 (<CJK Ideograph>) 5871 0x71BF 熿 (<CJK Ideograph>) 5872 0x71C0 燀 (<CJK Ideograph>) 5873 0x71C1 燁 (<CJK Ideograph>) 5874 0x71C2 燂 (<CJK Ideograph>) 5875 0x71C4 燄 (<CJK Ideograph>) 5876 0x71C5 燅 (<CJK Ideograph>) 5877 0x71C6 燆 (<CJK Ideograph>) 5878 0x71C7 燇 (<CJK Ideograph>) 5879 0x71C8 燈 (<CJK Ideograph>) 5880 0x71C9 燉 (<CJK Ideograph>) 5881 0x71CA 燊 (<CJK Ideograph>) 5882 0x71CB 燋 (<CJK Ideograph>) 5883 0x71CC 燌 (<CJK Ideograph>) 5884 0x71CD 燍 (<CJK Ideograph>) 5885 0x71CF 燏 (<CJK Ideograph>) 5886 0x71D0 燐 (<CJK Ideograph>) 5887 0x71D1 燑 (<CJK Ideograph>) 5888 0x71D2 燒 (<CJK Ideograph>) 5889 0x71D3 燓 (<CJK Ideograph>) 5890 0x71D6 燖 (<CJK Ideograph>) 5891 0x71D7 燗 (<CJK Ideograph>) 5892 0x71D8 燘 (<CJK Ideograph>) 5893 0x71D9 燙 (<CJK Ideograph>) 5894 0x71DA 燚 (<CJK Ideograph>) 5895 0x71DB 燛 (<CJK Ideograph>) 5896 0x71DC 燜 (<CJK Ideograph>) 5897 0x71DD 燝 (<CJK Ideograph>) 5898 0x71DE 燞 (<CJK Ideograph>) 5899 0x71DF 營 (<CJK Ideograph>) 5900 0x71E1 燡 (<CJK Ideograph>) 5901 0x71E2 燢 (<CJK Ideograph>) 5902 0x71E3 燣 (<CJK Ideograph>) 5903 0x71E4 燤 (<CJK Ideograph>) 5904 0x71E6 燦 (<CJK Ideograph>) 5905 0x71E8 燨 (<CJK Ideograph>) 5906 0x71E9 燩 (<CJK Ideograph>) 5907 0x71EA 燪 (<CJK Ideograph>) 5908 0x71EB 燫 (<CJK Ideograph>) 5909 0x71EC 燬 (<CJK Ideograph>) 5910 0x71ED 燭 (<CJK Ideograph>) 5911 0x71EF 燯 (<CJK Ideograph>) 5912 0x71F0 燰 (<CJK Ideograph>) 5913 0x71F1 燱 (<CJK Ideograph>) 5914 0x71F2 燲 (<CJK Ideograph>) 5915 0x71F3 燳 (<CJK Ideograph>) 5916 0x71F4 燴 (<CJK Ideograph>) 5917 0x71F5 燵 (<CJK Ideograph>) 5918 0x71F6 燶 (<CJK Ideograph>) 5919 0x71F7 燷 (<CJK Ideograph>) 5920 0x71F8 燸 (<CJK Ideograph>) 5921 0x71FA 燺 (<CJK Ideograph>) 5922 0x71FB 燻 (<CJK Ideograph>) 5923 0x71FC 燼 (<CJK Ideograph>) 5924 0x71FD 燽 (<CJK Ideograph>) 5925 0x71FE 燾 (<CJK Ideograph>) 5926 0x71FF 燿 (<CJK Ideograph>) 5927 0x7200 爀 (<CJK Ideograph>) 5928 0x7201 爁 (<CJK Ideograph>) 5929 0x7202 爂 (<CJK Ideograph>) 5930 0x7203 爃 (<CJK Ideograph>) 5931 0x7204 爄 (<CJK Ideograph>) 5932 0x7205 爅 (<CJK Ideograph>) 5933 0x7207 爇 (<CJK Ideograph>) 5934 0x7208 爈 (<CJK Ideograph>) 5935 0x7209 爉 (<CJK Ideograph>) 5936 0x720A 爊 (<CJK Ideograph>) 5937 0x720B 爋 (<CJK Ideograph>) 5938 0x720C 爌 (<CJK Ideograph>) 5939 0x720D 爍 (<CJK Ideograph>) 5940 0x720E 爎 (<CJK Ideograph>) 5941 0x720F 爏 (<CJK Ideograph>) 5942 0x7210 爐 (<CJK Ideograph>) 5943 0x7211 爑 (<CJK Ideograph>) 5944 0x7212 爒 (<CJK Ideograph>) 5945 0x7213 爓 (<CJK Ideograph>) 5946 0x7214 爔 (<CJK Ideograph>) 5947 0x7215 爕 (<CJK Ideograph>) 5948 0x7216 爖 (<CJK Ideograph>) 5949 0x7217 爗 (<CJK Ideograph>) 5950 0x7218 爘 (<CJK Ideograph>) 5951 0x7219 爙 (<CJK Ideograph>) 5952 0x721A 爚 (<CJK Ideograph>) 5953 0x721B 爛 (<CJK Ideograph>) 5954 0x721C 爜 (<CJK Ideograph>) 5955 0x721E 爞 (<CJK Ideograph>) 5956 0x721F 爟 (<CJK Ideograph>) 5957 0x7220 爠 (<CJK Ideograph>) 5958 0x7221 爡 (<CJK Ideograph>) 5959 0x7222 爢 (<CJK Ideograph>) 5960 0x7223 爣 (<CJK Ideograph>) 5961 0x7224 爤 (<CJK Ideograph>) 5962 0x7225 爥 (<CJK Ideograph>) 5963 0x7226 爦 (<CJK Ideograph>) 5964 0x7227 爧 (<CJK Ideograph>) 5965 0x7229 爩 (<CJK Ideograph>) 5966 0x722B 爫 (<CJK Ideograph>) 5967 0x722D 爭 (<CJK Ideograph>) 5968 0x722E 爮 (<CJK Ideograph>) 5969 0x722F 爯 (<CJK Ideograph>) 5970 0x7232 爲 (<CJK Ideograph>) 5971 0x7233 爳 (<CJK Ideograph>) 5972 0x7234 爴 (<CJK Ideograph>) 5973 0x723A 爺 (<CJK Ideograph>) 5974 0x723C 爼 (<CJK Ideograph>) 5975 0x723E 爾 (<CJK Ideograph>) 5976 0x7240 牀 (<CJK Ideograph>) 5977 0x7241 牁 (<CJK Ideograph>) 5978 0x7242 牂 (<CJK Ideograph>) 5979 0x7243 牃 (<CJK Ideograph>) 5980 0x7244 牄 (<CJK Ideograph>) 5981 0x7245 牅 (<CJK Ideograph>) 5982 0x7246 牆 (<CJK Ideograph>) 5983 0x7249 牉 (<CJK Ideograph>) 5984 0x724A 牊 (<CJK Ideograph>) 5985 0x724B 牋 (<CJK Ideograph>) 5986 0x724E 牎 (<CJK Ideograph>) 5987 0x724F 牏 (<CJK Ideograph>) 5988 0x7250 牐 (<CJK Ideograph>) 5989 0x7251 牑 (<CJK Ideograph>) 5990 0x7253 牓 (<CJK Ideograph>) 5991 0x7254 牔 (<CJK Ideograph>) 5992 0x7255 牕 (<CJK Ideograph>) 5993 0x7257 牗 (<CJK Ideograph>) 5994 0x7258 牘 (<CJK Ideograph>) 5995 0x725A 牚 (<CJK Ideograph>) 5996 0x725C 牜 (<CJK Ideograph>) 5997 0x725E 牞 (<CJK Ideograph>) 5998 0x7260 牠 (<CJK Ideograph>) 5999 0x7263 牣 (<CJK Ideograph>) 6000 0x7264 牤 (<CJK Ideograph>) 6001 0x7265 牥 (<CJK Ideograph>) 6002 0x7268 牨 (<CJK Ideograph>) 6003 0x726A 牪 (<CJK Ideograph>) 6004 0x726B 牫 (<CJK Ideograph>) 6005 0x726C 牬 (<CJK Ideograph>) 6006 0x726D 牭 (<CJK Ideograph>) 6007 0x7270 牰 (<CJK Ideograph>) 6008 0x7271 牱 (<CJK Ideograph>) 6009 0x7273 牳 (<CJK Ideograph>) 6010 0x7274 牴 (<CJK Ideograph>) 6011 0x7276 牶 (<CJK Ideograph>) 6012 0x7277 牷 (<CJK Ideograph>) 6013 0x7278 牸 (<CJK Ideograph>) 6014 0x727B 牻 (<CJK Ideograph>) 6015 0x727C 牼 (<CJK Ideograph>) 6016 0x727D 牽 (<CJK Ideograph>) 6017 0x7282 犂 (<CJK Ideograph>) 6018 0x7283 犃 (<CJK Ideograph>) 6019 0x7285 犅 (<CJK Ideograph>) 6020 0x7286 犆 (<CJK Ideograph>) 6021 0x7287 犇 (<CJK Ideograph>) 6022 0x7288 犈 (<CJK Ideograph>) 6023 0x7289 犉 (<CJK Ideograph>) 6024 0x728C 犌 (<CJK Ideograph>) 6025 0x728E 犎 (<CJK Ideograph>) 6026 0x7290 犐 (<CJK Ideograph>) 6027 0x7291 犑 (<CJK Ideograph>) 6028 0x7293 犓 (<CJK Ideograph>) 6029 0x7294 犔 (<CJK Ideograph>) 6030 0x7295 犕 (<CJK Ideograph>) 6031 0x7296 犖 (<CJK Ideograph>) 6032 0x7297 犗 (<CJK Ideograph>) 6033 0x7298 犘 (<CJK Ideograph>) 6034 0x7299 犙 (<CJK Ideograph>) 6035 0x729A 犚 (<CJK Ideograph>) 6036 0x729B 犛 (<CJK Ideograph>) 6037 0x729C 犜 (<CJK Ideograph>) 6038 0x729D 犝 (<CJK Ideograph>) 6039 0x729E 犞 (<CJK Ideograph>) 6040 0x72A0 犠 (<CJK Ideograph>) 6041 0x72A1 犡 (<CJK Ideograph>) 6042 0x72A2 犢 (<CJK Ideograph>) 6043 0x72A3 犣 (<CJK Ideograph>) 6044 0x72A4 犤 (<CJK Ideograph>) 6045 0x72A5 犥 (<CJK Ideograph>) 6046 0x72A6 犦 (<CJK Ideograph>) 6047 0x72A7 犧 (<CJK Ideograph>) 6048 0x72A8 犨 (<CJK Ideograph>) 6049 0x72A9 犩 (<CJK Ideograph>) 6050 0x72AA 犪 (<CJK Ideograph>) 6051 0x72AB 犫 (<CJK Ideograph>) 6052 0x72AE 犮 (<CJK Ideograph>) 6053 0x72B1 犱 (<CJK Ideograph>) 6054 0x72B2 犲 (<CJK Ideograph>) 6055 0x72B3 犳 (<CJK Ideograph>) 6056 0x72B5 犵 (<CJK Ideograph>) 6057 0x72BA 犺 (<CJK Ideograph>) 6058 0x72BB 犻 (<CJK Ideograph>) 6059 0x72BC 犼 (<CJK Ideograph>) 6060 0x72BD 犽 (<CJK Ideograph>) 6061 0x72BE 犾 (<CJK Ideograph>) 6062 0x72BF 犿 (<CJK Ideograph>) 6063 0x72C0 狀 (<CJK Ideograph>) 6064 0x72C5 狅 (<CJK Ideograph>) 6065 0x72C6 狆 (<CJK Ideograph>) 6066 0x72C7 狇 (<CJK Ideograph>) 6067 0x72C9 狉 (<CJK Ideograph>) 6068 0x72CA 狊 (<CJK Ideograph>) 6069 0x72CB 狋 (<CJK Ideograph>) 6070 0x72CC 狌 (<CJK Ideograph>) 6071 0x72CF 狏 (<CJK Ideograph>) 6072 0x72D1 狑 (<CJK Ideograph>) 6073 0x72D3 狓 (<CJK Ideograph>) 6074 0x72D4 狔 (<CJK Ideograph>) 6075 0x72D5 狕 (<CJK Ideograph>) 6076 0x72D6 狖 (<CJK Ideograph>) 6077 0x72D8 狘 (<CJK Ideograph>) 6078 0x72DA 狚 (<CJK Ideograph>) 6079 0x72DB 狛 (<CJK Ideograph>) 6080 0xE4C6  (<Private Use>) 6081 0xE4C7  (<Private Use>) 6082 0xE4C8  (<Private Use>) 6083 0xE4C9  (<Private Use>) 6084 0xE4CA  (<Private Use>) 6085 0xE4CB  (<Private Use>) 6086 0xE4CC  (<Private Use>) 6087 0xE4CD  (<Private Use>) 6088 0xE4CE  (<Private Use>) 6089 0xE4CF  (<Private Use>) 6090 0xE4D0  (<Private Use>) 6091 0xE4D1  (<Private Use>) 6092 0xE4D2  (<Private Use>) 6093 0xE4D3  (<Private Use>) 6094 0xE4D4  (<Private Use>) 6095 0xE4D5  (<Private Use>) 6096 0xE4D6  (<Private Use>) 6097 0xE4D7  (<Private Use>) 6098 0xE4D8  (<Private Use>) 6099 0xE4D9  (<Private Use>) 6100 0xE4DA  (<Private Use>) 6101 0xE4DB  (<Private Use>) 6102 0xE4DC  (<Private Use>) 6103 0xE4DD  (<Private Use>) 6104 0xE4DE  (<Private Use>) 6105 0xE4DF  (<Private Use>) 6106 0xE4E0  (<Private Use>) 6107 0xE4E1  (<Private Use>) 6108 0xE4E2  (<Private Use>) 6109 0xE4E3  (<Private Use>) 6110 0xE4E4  (<Private Use>) 6111 0xE4E5  (<Private Use>) 6112 0xE4E6  (<Private Use>) 6113 0xE4E7  (<Private Use>) 6114 0xE4E8  (<Private Use>) 6115 0xE4E9  (<Private Use>) 6116 0xE4EA  (<Private Use>) 6117 0xE4EB  (<Private Use>) 6118 0xE4EC  (<Private Use>) 6119 0xE4ED  (<Private Use>) 6120 0xE4EE  (<Private Use>) 6121 0xE4EF  (<Private Use>) 6122 0xE4F0  (<Private Use>) 6123 0xE4F1  (<Private Use>) 6124 0xE4F2  (<Private Use>) 6125 0xE4F3  (<Private Use>) 6126 0xE4F4  (<Private Use>) 6127 0xE4F5  (<Private Use>) 6128 0xE4F6  (<Private Use>) 6129 0xE4F7  (<Private Use>) 6130 0xE4F8  (<Private Use>) 6131 0xE4F9  (<Private Use>) 6132 0xE4FA  (<Private Use>) 6133 0xE4FB  (<Private Use>) 6134 0xE4FC  (<Private Use>) 6135 0xE4FD  (<Private Use>) 6136 0xE4FE  (<Private Use>) 6137 0xE4FF  (<Private Use>) 6138 0xE500  (<Private Use>) 6139 0xE501  (<Private Use>) 6140 0xE502  (<Private Use>) 6141 0xE503  (<Private Use>) 6142 0xE504  (<Private Use>) 6143 0xE505  (<Private Use>) 6144 0xE506  (<Private Use>) 6145 0xE507  (<Private Use>) 6146 0xE508  (<Private Use>) 6147 0xE509  (<Private Use>) 6148 0xE50A  (<Private Use>) 6149 0xE50B  (<Private Use>) 6150 0xE50C  (<Private Use>) 6151 0xE50D  (<Private Use>) 6152 0xE50E  (<Private Use>) 6153 0xE50F  (<Private Use>) 6154 0xE510  (<Private Use>) 6155 0xE511  (<Private Use>) 6156 0xE512  (<Private Use>) 6157 0xE513  (<Private Use>) 6158 0xE514  (<Private Use>) 6159 0xE515  (<Private Use>) 6160 0xE516  (<Private Use>) 6161 0xE517  (<Private Use>) 6162 0xE518  (<Private Use>) 6163 0xE519  (<Private Use>) 6164 0xE51A  (<Private Use>) 6165 0xE51B  (<Private Use>) 6166 0xE51C  (<Private Use>) 6167 0xE51D  (<Private Use>) 6168 0xE51E  (<Private Use>) 6169 0xE51F  (<Private Use>) 6170 0xE520  (<Private Use>) 6171 0xE521  (<Private Use>) 6172 0xE522  (<Private Use>) 6173 0xE523  (<Private Use>) 6174 0xE524  (<Private Use>) 6175 0xE525  (<Private Use>) 6176 0x3000   (IDEOGRAPHIC SPACE) 6177 0x3001 、 (IDEOGRAPHIC COMMA) 6178 0x3002 。 (IDEOGRAPHIC FULL STOP) 6179 0x00B7 · (MIDDLE DOT) 6180 0x02C9 ˉ (MODIFIER LETTER MACRON) 6181 0x02C7 ˇ (CARON) 6182 0x00A8 ¨ (DIAERESIS) 6183 0x3003 〃 (DITTO MARK) 6184 0x3005 々 (IDEOGRAPHIC ITERATION MARK) 6185 0x2014 — (EM DASH) 6186 0xFF5E ~ (FULLWIDTH TILDE) 6187 0x2016 ‖ (DOUBLE VERTICAL LINE) 6188 0x2026 … (HORIZONTAL ELLIPSIS) 6189 0x2018 ‘ (LEFT SINGLE QUOTATION MARK) 6190 0x2019 ’ (RIGHT SINGLE QUOTATION MARK) 6191 0x201C “ (LEFT DOUBLE QUOTATION MARK) 6192 0x201D ” (RIGHT DOUBLE QUOTATION MARK) 6193 0x3014 〔 (LEFT TORTOISE SHELL BRACKET) 6194 0x3015 〕 (RIGHT TORTOISE SHELL BRACKET) 6195 0x3008 〈 (LEFT ANGLE BRACKET) 6196 0x3009 〉 (RIGHT ANGLE BRACKET) 6197 0x300A 《 (LEFT DOUBLE ANGLE BRACKET) 6198 0x300B 》 (RIGHT DOUBLE ANGLE BRACKET) 6199 0x300C 「 (LEFT CORNER BRACKET) 6200 0x300D 」 (RIGHT CORNER BRACKET) 6201 0x300E 『 (LEFT WHITE CORNER BRACKET) 6202 0x300F 』 (RIGHT WHITE CORNER BRACKET) 6203 0x3016 〖 (LEFT WHITE LENTICULAR BRACKET) 6204 0x3017 〗 (RIGHT WHITE LENTICULAR BRACKET) 6205 0x3010 【 (LEFT BLACK LENTICULAR BRACKET) 6206 0x3011 】 (RIGHT BLACK LENTICULAR BRACKET) 6207 0x00B1 ± (PLUS-MINUS SIGN) 6208 0x00D7 × (MULTIPLICATION SIGN) 6209 0x00F7 ÷ (DIVISION SIGN) 6210 0x2236 ∶ (RATIO) 6211 0x2227 ∧ (LOGICAL AND) 6212 0x2228 ∨ (LOGICAL OR) 6213 0x2211 ∑ (N-ARY SUMMATION) 6214 0x220F ∏ (N-ARY PRODUCT) 6215 0x222A ∪ (UNION) 6216 0x2229 ∩ (INTERSECTION) 6217 0x2208 ∈ (ELEMENT OF) 6218 0x2237 ∷ (PROPORTION) 6219 0x221A √ (SQUARE ROOT) 6220 0x22A5 ⊥ (UP TACK) 6221 0x2225 ∥ (PARALLEL TO) 6222 0x2220 ∠ (ANGLE) 6223 0x2312 ⌒ (ARC) 6224 0x2299 ⊙ (CIRCLED DOT OPERATOR) 6225 0x222B ∫ (INTEGRAL) 6226 0x222E ∮ (CONTOUR INTEGRAL) 6227 0x2261 ≡ (IDENTICAL TO) 6228 0x224C ≌ (ALL EQUAL TO) 6229 0x2248 ≈ (ALMOST EQUAL TO) 6230 0x223D ∽ (REVERSED TILDE) 6231 0x221D ∝ (PROPORTIONAL TO) 6232 0x2260 ≠ (NOT EQUAL TO) 6233 0x226E ≮ (NOT LESS-THAN) 6234 0x226F ≯ (NOT GREATER-THAN) 6235 0x2264 ≤ (LESS-THAN OR EQUAL TO) 6236 0x2265 ≥ (GREATER-THAN OR EQUAL TO) 6237 0x221E ∞ (INFINITY) 6238 0x2235 ∵ (BECAUSE) 6239 0x2234 ∴ (THEREFORE) 6240 0x2642 ♂ (MALE SIGN) 6241 0x2640 ♀ (FEMALE SIGN) 6242 0x00B0 ° (DEGREE SIGN) 6243 0x2032 ′ (PRIME) 6244 0x2033 ″ (DOUBLE PRIME) 6245 0x2103 ℃ (DEGREE CELSIUS) 6246 0xFF04 $ (FULLWIDTH DOLLAR SIGN) 6247 0x00A4 ¤ (CURRENCY SIGN) 6248 0xFFE0 ¢ (FULLWIDTH CENT SIGN) 6249 0xFFE1 £ (FULLWIDTH POUND SIGN) 6250 0x2030 ‰ (PER MILLE SIGN) 6251 0x00A7 § (SECTION SIGN) 6252 0x2116 № (NUMERO SIGN) 6253 0x2606 ☆ (WHITE STAR) 6254 0x2605 ★ (BLACK STAR) 6255 0x25CB ○ (WHITE CIRCLE) 6256 0x25CF ● (BLACK CIRCLE) 6257 0x25CE ◎ (BULLSEYE) 6258 0x25C7 ◇ (WHITE DIAMOND) 6259 0x25C6 ◆ (BLACK DIAMOND) 6260 0x25A1 □ (WHITE SQUARE) 6261 0x25A0 ■ (BLACK SQUARE) 6262 0x25B3 △ (WHITE UP-POINTING TRIANGLE) 6263 0x25B2 ▲ (BLACK UP-POINTING TRIANGLE) 6264 0x203B ※ (REFERENCE MARK) 6265 0x2192 → (RIGHTWARDS ARROW) 6266 0x2190 ← (LEFTWARDS ARROW) 6267 0x2191 ↑ (UPWARDS ARROW) 6268 0x2193 ↓ (DOWNWARDS ARROW) 6269 0x3013 〓 (GETA MARK) 6270 0xE526  (<Private Use>) 6271 0xE527  (<Private Use>) 6272 0xE528  (<Private Use>) 6273 0xE529  (<Private Use>) 6274 0xE52A  (<Private Use>) 6275 0xE52B  (<Private Use>) 6276 0xE52C  (<Private Use>) 6277 0xE52D  (<Private Use>) 6278 0xE52E  (<Private Use>) 6279 0xE52F  (<Private Use>) 6280 0xE530  (<Private Use>) 6281 0xE531  (<Private Use>) 6282 0xE532  (<Private Use>) 6283 0xE533  (<Private Use>) 6284 0xE534  (<Private Use>) 6285 0xE535  (<Private Use>) 6286 0xE536  (<Private Use>) 6287 0xE537  (<Private Use>) 6288 0xE538  (<Private Use>) 6289 0xE539  (<Private Use>) 6290 0xE53A  (<Private Use>) 6291 0xE53B  (<Private Use>) 6292 0xE53C  (<Private Use>) 6293 0xE53D  (<Private Use>) 6294 0xE53E  (<Private Use>) 6295 0xE53F  (<Private Use>) 6296 0xE540  (<Private Use>) 6297 0xE541  (<Private Use>) 6298 0xE542  (<Private Use>) 6299 0xE543  (<Private Use>) 6300 0xE544  (<Private Use>) 6301 0xE545  (<Private Use>) 6302 0xE546  (<Private Use>) 6303 0xE547  (<Private Use>) 6304 0xE548  (<Private Use>) 6305 0xE549  (<Private Use>) 6306 0xE54A  (<Private Use>) 6307 0xE54B  (<Private Use>) 6308 0xE54C  (<Private Use>) 6309 0xE54D  (<Private Use>) 6310 0xE54E  (<Private Use>) 6311 0xE54F  (<Private Use>) 6312 0xE550  (<Private Use>) 6313 0xE551  (<Private Use>) 6314 0xE552  (<Private Use>) 6315 0xE553  (<Private Use>) 6316 0xE554  (<Private Use>) 6317 0xE555  (<Private Use>) 6318 0xE556  (<Private Use>) 6319 0xE557  (<Private Use>) 6320 0xE558  (<Private Use>) 6321 0xE559  (<Private Use>) 6322 0xE55A  (<Private Use>) 6323 0xE55B  (<Private Use>) 6324 0xE55C  (<Private Use>) 6325 0xE55D  (<Private Use>) 6326 0xE55E  (<Private Use>) 6327 0xE55F  (<Private Use>) 6328 0xE560  (<Private Use>) 6329 0xE561  (<Private Use>) 6330 0xE562  (<Private Use>) 6331 0xE563  (<Private Use>) 6332 0xE564  (<Private Use>) 6333 0xE565  (<Private Use>) 6334 0xE566  (<Private Use>) 6335 0xE567  (<Private Use>) 6336 0xE568  (<Private Use>) 6337 0xE569  (<Private Use>) 6338 0xE56A  (<Private Use>) 6339 0xE56B  (<Private Use>) 6340 0xE56C  (<Private Use>) 6341 0xE56D  (<Private Use>) 6342 0xE56E  (<Private Use>) 6343 0xE56F  (<Private Use>) 6344 0xE570  (<Private Use>) 6345 0xE571  (<Private Use>) 6346 0xE572  (<Private Use>) 6347 0xE573  (<Private Use>) 6348 0xE574  (<Private Use>) 6349 0xE575  (<Private Use>) 6350 0xE576  (<Private Use>) 6351 0xE577  (<Private Use>) 6352 0xE578  (<Private Use>) 6353 0xE579  (<Private Use>) 6354 0xE57A  (<Private Use>) 6355 0xE57B  (<Private Use>) 6356 0xE57C  (<Private Use>) 6357 0xE57D  (<Private Use>) 6358 0xE57E  (<Private Use>) 6359 0xE57F  (<Private Use>) 6360 0xE580  (<Private Use>) 6361 0xE581  (<Private Use>) 6362 0xE582  (<Private Use>) 6363 0xE583  (<Private Use>) 6364 0xE584  (<Private Use>) 6365 0xE585  (<Private Use>) 6366 0x2170 ⅰ (SMALL ROMAN NUMERAL ONE) 6367 0x2171 ⅱ (SMALL ROMAN NUMERAL TWO) 6368 0x2172 ⅲ (SMALL ROMAN NUMERAL THREE) 6369 0x2173 ⅳ (SMALL ROMAN NUMERAL FOUR) 6370 0x2174 ⅴ (SMALL ROMAN NUMERAL FIVE) 6371 0x2175 ⅵ (SMALL ROMAN NUMERAL SIX) 6372 0x2176 ⅶ (SMALL ROMAN NUMERAL SEVEN) 6373 0x2177 ⅷ (SMALL ROMAN NUMERAL EIGHT) 6374 0x2178 ⅸ (SMALL ROMAN NUMERAL NINE) 6375 0x2179 ⅹ (SMALL ROMAN NUMERAL TEN) 6376 0xE766  (<Private Use>) 6377 0xE767  (<Private Use>) 6378 0xE768  (<Private Use>) 6379 0xE769  (<Private Use>) 6380 0xE76A  (<Private Use>) 6381 0xE76B  (<Private Use>) 6382 0x2488 ⒈ (DIGIT ONE FULL STOP) 6383 0x2489 ⒉ (DIGIT TWO FULL STOP) 6384 0x248A ⒊ (DIGIT THREE FULL STOP) 6385 0x248B ⒋ (DIGIT FOUR FULL STOP) 6386 0x248C ⒌ (DIGIT FIVE FULL STOP) 6387 0x248D ⒍ (DIGIT SIX FULL STOP) 6388 0x248E ⒎ (DIGIT SEVEN FULL STOP) 6389 0x248F ⒏ (DIGIT EIGHT FULL STOP) 6390 0x2490 ⒐ (DIGIT NINE FULL STOP) 6391 0x2491 ⒑ (NUMBER TEN FULL STOP) 6392 0x2492 ⒒ (NUMBER ELEVEN FULL STOP) 6393 0x2493 ⒓ (NUMBER TWELVE FULL STOP) 6394 0x2494 ⒔ (NUMBER THIRTEEN FULL STOP) 6395 0x2495 ⒕ (NUMBER FOURTEEN FULL STOP) 6396 0x2496 ⒖ (NUMBER FIFTEEN FULL STOP) 6397 0x2497 ⒗ (NUMBER SIXTEEN FULL STOP) 6398 0x2498 ⒘ (NUMBER SEVENTEEN FULL STOP) 6399 0x2499 ⒙ (NUMBER EIGHTEEN FULL STOP) 6400 0x249A ⒚ (NUMBER NINETEEN FULL STOP) 6401 0x249B ⒛ (NUMBER TWENTY FULL STOP) 6402 0x2474 ⑴ (PARENTHESIZED DIGIT ONE) 6403 0x2475 ⑵ (PARENTHESIZED DIGIT TWO) 6404 0x2476 ⑶ (PARENTHESIZED DIGIT THREE) 6405 0x2477 ⑷ (PARENTHESIZED DIGIT FOUR) 6406 0x2478 ⑸ (PARENTHESIZED DIGIT FIVE) 6407 0x2479 ⑹ (PARENTHESIZED DIGIT SIX) 6408 0x247A ⑺ (PARENTHESIZED DIGIT SEVEN) 6409 0x247B ⑻ (PARENTHESIZED DIGIT EIGHT) 6410 0x247C ⑼ (PARENTHESIZED DIGIT NINE) 6411 0x247D ⑽ (PARENTHESIZED NUMBER TEN) 6412 0x247E ⑾ (PARENTHESIZED NUMBER ELEVEN) 6413 0x247F ⑿ (PARENTHESIZED NUMBER TWELVE) 6414 0x2480 ⒀ (PARENTHESIZED NUMBER THIRTEEN) 6415 0x2481 ⒁ (PARENTHESIZED NUMBER FOURTEEN) 6416 0x2482 ⒂ (PARENTHESIZED NUMBER FIFTEEN) 6417 0x2483 ⒃ (PARENTHESIZED NUMBER SIXTEEN) 6418 0x2484 ⒄ (PARENTHESIZED NUMBER SEVENTEEN) 6419 0x2485 ⒅ (PARENTHESIZED NUMBER EIGHTEEN) 6420 0x2486 ⒆ (PARENTHESIZED NUMBER NINETEEN) 6421 0x2487 ⒇ (PARENTHESIZED NUMBER TWENTY) 6422 0x2460 ① (CIRCLED DIGIT ONE) 6423 0x2461 ② (CIRCLED DIGIT TWO) 6424 0x2462 ③ (CIRCLED DIGIT THREE) 6425 0x2463 ④ (CIRCLED DIGIT FOUR) 6426 0x2464 ⑤ (CIRCLED DIGIT FIVE) 6427 0x2465 ⑥ (CIRCLED DIGIT SIX) 6428 0x2466 ⑦ (CIRCLED DIGIT SEVEN) 6429 0x2467 ⑧ (CIRCLED DIGIT EIGHT) 6430 0x2468 ⑨ (CIRCLED DIGIT NINE) 6431 0x2469 ⑩ (CIRCLED NUMBER TEN) 6432 0x20AC € (EURO SIGN) 6433 0xE76D  (<Private Use>) 6434 0x3220 ㈠ (PARENTHESIZED IDEOGRAPH ONE) 6435 0x3221 ㈡ (PARENTHESIZED IDEOGRAPH TWO) 6436 0x3222 ㈢ (PARENTHESIZED IDEOGRAPH THREE) 6437 0x3223 ㈣ (PARENTHESIZED IDEOGRAPH FOUR) 6438 0x3224 ㈤ (PARENTHESIZED IDEOGRAPH FIVE) 6439 0x3225 ㈥ (PARENTHESIZED IDEOGRAPH SIX) 6440 0x3226 ㈦ (PARENTHESIZED IDEOGRAPH SEVEN) 6441 0x3227 ㈧ (PARENTHESIZED IDEOGRAPH EIGHT) 6442 0x3228 ㈨ (PARENTHESIZED IDEOGRAPH NINE) 6443 0x3229 ㈩ (PARENTHESIZED IDEOGRAPH TEN) 6444 0xE76E  (<Private Use>) 6445 0xE76F  (<Private Use>) 6446 0x2160 Ⅰ (ROMAN NUMERAL ONE) 6447 0x2161 Ⅱ (ROMAN NUMERAL TWO) 6448 0x2162 Ⅲ (ROMAN NUMERAL THREE) 6449 0x2163 Ⅳ (ROMAN NUMERAL FOUR) 6450 0x2164 Ⅴ (ROMAN NUMERAL FIVE) 6451 0x2165 Ⅵ (ROMAN NUMERAL SIX) 6452 0x2166 Ⅶ (ROMAN NUMERAL SEVEN) 6453 0x2167 Ⅷ (ROMAN NUMERAL EIGHT) 6454 0x2168 Ⅸ (ROMAN NUMERAL NINE) 6455 0x2169 Ⅹ (ROMAN NUMERAL TEN) 6456 0x216A Ⅺ (ROMAN NUMERAL ELEVEN) 6457 0x216B Ⅻ (ROMAN NUMERAL TWELVE) 6458 0xE770  (<Private Use>) 6459 0xE771  (<Private Use>) 6460 0xE586  (<Private Use>) 6461 0xE587  (<Private Use>) 6462 0xE588  (<Private Use>) 6463 0xE589  (<Private Use>) 6464 0xE58A  (<Private Use>) 6465 0xE58B  (<Private Use>) 6466 0xE58C  (<Private Use>) 6467 0xE58D  (<Private Use>) 6468 0xE58E  (<Private Use>) 6469 0xE58F  (<Private Use>) 6470 0xE590  (<Private Use>) 6471 0xE591  (<Private Use>) 6472 0xE592  (<Private Use>) 6473 0xE593  (<Private Use>) 6474 0xE594  (<Private Use>) 6475 0xE595  (<Private Use>) 6476 0xE596  (<Private Use>) 6477 0xE597  (<Private Use>) 6478 0xE598  (<Private Use>) 6479 0xE599  (<Private Use>) 6480 0xE59A  (<Private Use>) 6481 0xE59B  (<Private Use>) 6482 0xE59C  (<Private Use>) 6483 0xE59D  (<Private Use>) 6484 0xE59E  (<Private Use>) 6485 0xE59F  (<Private Use>) 6486 0xE5A0  (<Private Use>) 6487 0xE5A1  (<Private Use>) 6488 0xE5A2  (<Private Use>) 6489 0xE5A3  (<Private Use>) 6490 0xE5A4  (<Private Use>) 6491 0xE5A5  (<Private Use>) 6492 0xE5A6  (<Private Use>) 6493 0xE5A7  (<Private Use>) 6494 0xE5A8  (<Private Use>) 6495 0xE5A9  (<Private Use>) 6496 0xE5AA  (<Private Use>) 6497 0xE5AB  (<Private Use>) 6498 0xE5AC  (<Private Use>) 6499 0xE5AD  (<Private Use>) 6500 0xE5AE  (<Private Use>) 6501 0xE5AF  (<Private Use>) 6502 0xE5B0  (<Private Use>) 6503 0xE5B1  (<Private Use>) 6504 0xE5B2  (<Private Use>) 6505 0xE5B3  (<Private Use>) 6506 0xE5B4  (<Private Use>) 6507 0xE5B5  (<Private Use>) 6508 0xE5B6  (<Private Use>) 6509 0xE5B7  (<Private Use>) 6510 0xE5B8  (<Private Use>) 6511 0xE5B9  (<Private Use>) 6512 0xE5BA  (<Private Use>) 6513 0xE5BB  (<Private Use>) 6514 0xE5BC  (<Private Use>) 6515 0xE5BD  (<Private Use>) 6516 0xE5BE  (<Private Use>) 6517 0xE5BF  (<Private Use>) 6518 0xE5C0  (<Private Use>) 6519 0xE5C1  (<Private Use>) 6520 0xE5C2  (<Private Use>) 6521 0xE5C3  (<Private Use>) 6522 0xE5C4  (<Private Use>) 6523 0xE5C5  (<Private Use>) 6524 0xE5C6  (<Private Use>) 6525 0xE5C7  (<Private Use>) 6526 0xE5C8  (<Private Use>) 6527 0xE5C9  (<Private Use>) 6528 0xE5CA  (<Private Use>) 6529 0xE5CB  (<Private Use>) 6530 0xE5CC  (<Private Use>) 6531 0xE5CD  (<Private Use>) 6532 0xE5CE  (<Private Use>) 6533 0xE5CF  (<Private Use>) 6534 0xE5D0  (<Private Use>) 6535 0xE5D1  (<Private Use>) 6536 0xE5D2  (<Private Use>) 6537 0xE5D3  (<Private Use>) 6538 0xE5D4  (<Private Use>) 6539 0xE5D5  (<Private Use>) 6540 0xE5D6  (<Private Use>) 6541 0xE5D7  (<Private Use>) 6542 0xE5D8  (<Private Use>) 6543 0xE5D9  (<Private Use>) 6544 0xE5DA  (<Private Use>) 6545 0xE5DB  (<Private Use>) 6546 0xE5DC  (<Private Use>) 6547 0xE5DD  (<Private Use>) 6548 0xE5DE  (<Private Use>) 6549 0xE5DF  (<Private Use>) 6550 0xE5E0  (<Private Use>) 6551 0xE5E1  (<Private Use>) 6552 0xE5E2  (<Private Use>) 6553 0xE5E3  (<Private Use>) 6554 0xE5E4  (<Private Use>) 6555 0x3000   (IDEOGRAPHIC SPACE) 6556 0xFF01 ! (FULLWIDTH EXCLAMATION MARK) 6557 0xFF02 " (FULLWIDTH QUOTATION MARK) 6558 0xFF03 # (FULLWIDTH NUMBER SIGN) 6559 0xFFE5 ¥ (FULLWIDTH YEN SIGN) 6560 0xFF05 % (FULLWIDTH PERCENT SIGN) 6561 0xFF06 & (FULLWIDTH AMPERSAND) 6562 0xFF07 ' (FULLWIDTH APOSTROPHE) 6563 0xFF08 ( (FULLWIDTH LEFT PARENTHESIS) 6564 0xFF09 ) (FULLWIDTH RIGHT PARENTHESIS) 6565 0xFF0A * (FULLWIDTH ASTERISK) 6566 0xFF0B + (FULLWIDTH PLUS SIGN) 6567 0xFF0C , (FULLWIDTH COMMA) 6568 0xFF0D - (FULLWIDTH HYPHEN-MINUS) 6569 0xFF0E . (FULLWIDTH FULL STOP) 6570 0xFF0F / (FULLWIDTH SOLIDUS) 6571 0xFF10 0 (FULLWIDTH DIGIT ZERO) 6572 0xFF11 1 (FULLWIDTH DIGIT ONE) 6573 0xFF12 2 (FULLWIDTH DIGIT TWO) 6574 0xFF13 3 (FULLWIDTH DIGIT THREE) 6575 0xFF14 4 (FULLWIDTH DIGIT FOUR) 6576 0xFF15 5 (FULLWIDTH DIGIT FIVE) 6577 0xFF16 6 (FULLWIDTH DIGIT SIX) 6578 0xFF17 7 (FULLWIDTH DIGIT SEVEN) 6579 0xFF18 8 (FULLWIDTH DIGIT EIGHT) 6580 0xFF19 9 (FULLWIDTH DIGIT NINE) 6581 0xFF1A : (FULLWIDTH COLON) 6582 0xFF1B ; (FULLWIDTH SEMICOLON) 6583 0xFF1C < (FULLWIDTH LESS-THAN SIGN) 6584 0xFF1D = (FULLWIDTH EQUALS SIGN) 6585 0xFF1E > (FULLWIDTH GREATER-THAN SIGN) 6586 0xFF1F ? (FULLWIDTH QUESTION MARK) 6587 0xFF20 @ (FULLWIDTH COMMERCIAL AT) 6588 0xFF21 A (FULLWIDTH LATIN CAPITAL LETTER A) 6589 0xFF22 B (FULLWIDTH LATIN CAPITAL LETTER B) 6590 0xFF23 C (FULLWIDTH LATIN CAPITAL LETTER C) 6591 0xFF24 D (FULLWIDTH LATIN CAPITAL LETTER D) 6592 0xFF25 E (FULLWIDTH LATIN CAPITAL LETTER E) 6593 0xFF26 F (FULLWIDTH LATIN CAPITAL LETTER F) 6594 0xFF27 G (FULLWIDTH LATIN CAPITAL LETTER G) 6595 0xFF28 H (FULLWIDTH LATIN CAPITAL LETTER H) 6596 0xFF29 I (FULLWIDTH LATIN CAPITAL LETTER I) 6597 0xFF2A J (FULLWIDTH LATIN CAPITAL LETTER J) 6598 0xFF2B K (FULLWIDTH LATIN CAPITAL LETTER K) 6599 0xFF2C L (FULLWIDTH LATIN CAPITAL LETTER L) 6600 0xFF2D M (FULLWIDTH LATIN CAPITAL LETTER M) 6601 0xFF2E N (FULLWIDTH LATIN CAPITAL LETTER N) 6602 0xFF2F O (FULLWIDTH LATIN CAPITAL LETTER O) 6603 0xFF30 P (FULLWIDTH LATIN CAPITAL LETTER P) 6604 0xFF31 Q (FULLWIDTH LATIN CAPITAL LETTER Q) 6605 0xFF32 R (FULLWIDTH LATIN CAPITAL LETTER R) 6606 0xFF33 S (FULLWIDTH LATIN CAPITAL LETTER S) 6607 0xFF34 T (FULLWIDTH LATIN CAPITAL LETTER T) 6608 0xFF35 U (FULLWIDTH LATIN CAPITAL LETTER U) 6609 0xFF36 V (FULLWIDTH LATIN CAPITAL LETTER V) 6610 0xFF37 W (FULLWIDTH LATIN CAPITAL LETTER W) 6611 0xFF38 X (FULLWIDTH LATIN CAPITAL LETTER X) 6612 0xFF39 Y (FULLWIDTH LATIN CAPITAL LETTER Y) 6613 0xFF3A Z (FULLWIDTH LATIN CAPITAL LETTER Z) 6614 0xFF3B [ (FULLWIDTH LEFT SQUARE BRACKET) 6615 0xFF3C \ (FULLWIDTH REVERSE SOLIDUS) 6616 0xFF3D ] (FULLWIDTH RIGHT SQUARE BRACKET) 6617 0xFF3E ^ (FULLWIDTH CIRCUMFLEX ACCENT) 6618 0xFF3F _ (FULLWIDTH LOW LINE) 6619 0xFF40 ` (FULLWIDTH GRAVE ACCENT) 6620 0xFF41 a (FULLWIDTH LATIN SMALL LETTER A) 6621 0xFF42 b (FULLWIDTH LATIN SMALL LETTER B) 6622 0xFF43 c (FULLWIDTH LATIN SMALL LETTER C) 6623 0xFF44 d (FULLWIDTH LATIN SMALL LETTER D) 6624 0xFF45 e (FULLWIDTH LATIN SMALL LETTER E) 6625 0xFF46 f (FULLWIDTH LATIN SMALL LETTER F) 6626 0xFF47 g (FULLWIDTH LATIN SMALL LETTER G) 6627 0xFF48 h (FULLWIDTH LATIN SMALL LETTER H) 6628 0xFF49 i (FULLWIDTH LATIN SMALL LETTER I) 6629 0xFF4A j (FULLWIDTH LATIN SMALL LETTER J) 6630 0xFF4B k (FULLWIDTH LATIN SMALL LETTER K) 6631 0xFF4C l (FULLWIDTH LATIN SMALL LETTER L) 6632 0xFF4D m (FULLWIDTH LATIN SMALL LETTER M) 6633 0xFF4E n (FULLWIDTH LATIN SMALL LETTER N) 6634 0xFF4F o (FULLWIDTH LATIN SMALL LETTER O) 6635 0xFF50 p (FULLWIDTH LATIN SMALL LETTER P) 6636 0xFF51 q (FULLWIDTH LATIN SMALL LETTER Q) 6637 0xFF52 r (FULLWIDTH LATIN SMALL LETTER R) 6638 0xFF53 s (FULLWIDTH LATIN SMALL LETTER S) 6639 0xFF54 t (FULLWIDTH LATIN SMALL LETTER T) 6640 0xFF55 u (FULLWIDTH LATIN SMALL LETTER U) 6641 0xFF56 v (FULLWIDTH LATIN SMALL LETTER V) 6642 0xFF57 w (FULLWIDTH LATIN SMALL LETTER W) 6643 0xFF58 x (FULLWIDTH LATIN SMALL LETTER X) 6644 0xFF59 y (FULLWIDTH LATIN SMALL LETTER Y) 6645 0xFF5A z (FULLWIDTH LATIN SMALL LETTER Z) 6646 0xFF5B { (FULLWIDTH LEFT CURLY BRACKET) 6647 0xFF5C | (FULLWIDTH VERTICAL LINE) 6648 0xFF5D } (FULLWIDTH RIGHT CURLY BRACKET) 6649 0xFFE3  ̄ (FULLWIDTH MACRON) 6650 0xE5E6  (<Private Use>) 6651 0xE5E7  (<Private Use>) 6652 0xE5E8  (<Private Use>) 6653 0xE5E9  (<Private Use>) 6654 0xE5EA  (<Private Use>) 6655 0xE5EB  (<Private Use>) 6656 0xE5EC  (<Private Use>) 6657 0xE5ED  (<Private Use>) 6658 0xE5EE  (<Private Use>) 6659 0xE5EF  (<Private Use>) 6660 0xE5F0  (<Private Use>) 6661 0xE5F1  (<Private Use>) 6662 0xE5F2  (<Private Use>) 6663 0xE5F3  (<Private Use>) 6664 0xE5F4  (<Private Use>) 6665 0xE5F5  (<Private Use>) 6666 0xE5F6  (<Private Use>) 6667 0xE5F7  (<Private Use>) 6668 0xE5F8  (<Private Use>) 6669 0xE5F9  (<Private Use>) 6670 0xE5FA  (<Private Use>) 6671 0xE5FB  (<Private Use>) 6672 0xE5FC  (<Private Use>) 6673 0xE5FD  (<Private Use>) 6674 0xE5FE  (<Private Use>) 6675 0xE5FF  (<Private Use>) 6676 0xE600  (<Private Use>) 6677 0xE601  (<Private Use>) 6678 0xE602  (<Private Use>) 6679 0xE603  (<Private Use>) 6680 0xE604  (<Private Use>) 6681 0xE605  (<Private Use>) 6682 0xE606  (<Private Use>) 6683 0xE607  (<Private Use>) 6684 0xE608  (<Private Use>) 6685 0xE609  (<Private Use>) 6686 0xE60A  (<Private Use>) 6687 0xE60B  (<Private Use>) 6688 0xE60C  (<Private Use>) 6689 0xE60D  (<Private Use>) 6690 0xE60E  (<Private Use>) 6691 0xE60F  (<Private Use>) 6692 0xE610  (<Private Use>) 6693 0xE611  (<Private Use>) 6694 0xE612  (<Private Use>) 6695 0xE613  (<Private Use>) 6696 0xE614  (<Private Use>) 6697 0xE615  (<Private Use>) 6698 0xE616  (<Private Use>) 6699 0xE617  (<Private Use>) 6700 0xE618  (<Private Use>) 6701 0xE619  (<Private Use>) 6702 0xE61A  (<Private Use>) 6703 0xE61B  (<Private Use>) 6704 0xE61C  (<Private Use>) 6705 0xE61D  (<Private Use>) 6706 0xE61E  (<Private Use>) 6707 0xE61F  (<Private Use>) 6708 0xE620  (<Private Use>) 6709 0xE621  (<Private Use>) 6710 0xE622  (<Private Use>) 6711 0xE623  (<Private Use>) 6712 0xE624  (<Private Use>) 6713 0xE625  (<Private Use>) 6714 0xE626  (<Private Use>) 6715 0xE627  (<Private Use>) 6716 0xE628  (<Private Use>) 6717 0xE629  (<Private Use>) 6718 0xE62A  (<Private Use>) 6719 0xE62B  (<Private Use>) 6720 0xE62C  (<Private Use>) 6721 0xE62D  (<Private Use>) 6722 0xE62E  (<Private Use>) 6723 0xE62F  (<Private Use>) 6724 0xE630  (<Private Use>) 6725 0xE631  (<Private Use>) 6726 0xE632  (<Private Use>) 6727 0xE633  (<Private Use>) 6728 0xE634  (<Private Use>) 6729 0xE635  (<Private Use>) 6730 0xE636  (<Private Use>) 6731 0xE637  (<Private Use>) 6732 0xE638  (<Private Use>) 6733 0xE639  (<Private Use>) 6734 0xE63A  (<Private Use>) 6735 0xE63B  (<Private Use>) 6736 0xE63C  (<Private Use>) 6737 0xE63D  (<Private Use>) 6738 0xE63E  (<Private Use>) 6739 0xE63F  (<Private Use>) 6740 0xE640  (<Private Use>) 6741 0xE641  (<Private Use>) 6742 0xE642  (<Private Use>) 6743 0xE643  (<Private Use>) 6744 0xE644  (<Private Use>) 6745 0xE645  (<Private Use>) 6746 0x3041 ぁ (HIRAGANA LETTER SMALL A) 6747 0x3042 あ (HIRAGANA LETTER A) 6748 0x3043 ぃ (HIRAGANA LETTER SMALL I) 6749 0x3044 い (HIRAGANA LETTER I) 6750 0x3045 ぅ (HIRAGANA LETTER SMALL U) 6751 0x3046 う (HIRAGANA LETTER U) 6752 0x3047 ぇ (HIRAGANA LETTER SMALL E) 6753 0x3048 え (HIRAGANA LETTER E) 6754 0x3049 ぉ (HIRAGANA LETTER SMALL O) 6755 0x304A お (HIRAGANA LETTER O) 6756 0x304B か (HIRAGANA LETTER KA) 6757 0x304C が (HIRAGANA LETTER GA) 6758 0x304D き (HIRAGANA LETTER KI) 6759 0x304E ぎ (HIRAGANA LETTER GI) 6760 0x304F く (HIRAGANA LETTER KU) 6761 0x3050 ぐ (HIRAGANA LETTER GU) 6762 0x3051 け (HIRAGANA LETTER KE) 6763 0x3052 げ (HIRAGANA LETTER GE) 6764 0x3053 こ (HIRAGANA LETTER KO) 6765 0x3054 ご (HIRAGANA LETTER GO) 6766 0x3055 さ (HIRAGANA LETTER SA) 6767 0x3056 ざ (HIRAGANA LETTER ZA) 6768 0x3057 し (HIRAGANA LETTER SI) 6769 0x3058 じ (HIRAGANA LETTER ZI) 6770 0x3059 す (HIRAGANA LETTER SU) 6771 0x305A ず (HIRAGANA LETTER ZU) 6772 0x305B せ (HIRAGANA LETTER SE) 6773 0x305C ぜ (HIRAGANA LETTER ZE) 6774 0x305D そ (HIRAGANA LETTER SO) 6775 0x305E ぞ (HIRAGANA LETTER ZO) 6776 0x305F た (HIRAGANA LETTER TA) 6777 0x3060 だ (HIRAGANA LETTER DA) 6778 0x3061 ち (HIRAGANA LETTER TI) 6779 0x3062 ぢ (HIRAGANA LETTER DI) 6780 0x3063 っ (HIRAGANA LETTER SMALL TU) 6781 0x3064 つ (HIRAGANA LETTER TU) 6782 0x3065 づ (HIRAGANA LETTER DU) 6783 0x3066 て (HIRAGANA LETTER TE) 6784 0x3067 で (HIRAGANA LETTER DE) 6785 0x3068 と (HIRAGANA LETTER TO) 6786 0x3069 ど (HIRAGANA LETTER DO) 6787 0x306A な (HIRAGANA LETTER NA) 6788 0x306B に (HIRAGANA LETTER NI) 6789 0x306C ぬ (HIRAGANA LETTER NU) 6790 0x306D ね (HIRAGANA LETTER NE) 6791 0x306E の (HIRAGANA LETTER NO) 6792 0x306F は (HIRAGANA LETTER HA) 6793 0x3070 ば (HIRAGANA LETTER BA) 6794 0x3071 ぱ (HIRAGANA LETTER PA) 6795 0x3072 ひ (HIRAGANA LETTER HI) 6796 0x3073 び (HIRAGANA LETTER BI) 6797 0x3074 ぴ (HIRAGANA LETTER PI) 6798 0x3075 ふ (HIRAGANA LETTER HU) 6799 0x3076 ぶ (HIRAGANA LETTER BU) 6800 0x3077 ぷ (HIRAGANA LETTER PU) 6801 0x3078 へ (HIRAGANA LETTER HE) 6802 0x3079 べ (HIRAGANA LETTER BE) 6803 0x307A ぺ (HIRAGANA LETTER PE) 6804 0x307B ほ (HIRAGANA LETTER HO) 6805 0x307C ぼ (HIRAGANA LETTER BO) 6806 0x307D ぽ (HIRAGANA LETTER PO) 6807 0x307E ま (HIRAGANA LETTER MA) 6808 0x307F み (HIRAGANA LETTER MI) 6809 0x3080 む (HIRAGANA LETTER MU) 6810 0x3081 め (HIRAGANA LETTER ME) 6811 0x3082 も (HIRAGANA LETTER MO) 6812 0x3083 ゃ (HIRAGANA LETTER SMALL YA) 6813 0x3084 や (HIRAGANA LETTER YA) 6814 0x3085 ゅ (HIRAGANA LETTER SMALL YU) 6815 0x3086 ゆ (HIRAGANA LETTER YU) 6816 0x3087 ょ (HIRAGANA LETTER SMALL YO) 6817 0x3088 よ (HIRAGANA LETTER YO) 6818 0x3089 ら (HIRAGANA LETTER RA) 6819 0x308A り (HIRAGANA LETTER RI) 6820 0x308B る (HIRAGANA LETTER RU) 6821 0x308C れ (HIRAGANA LETTER RE) 6822 0x308D ろ (HIRAGANA LETTER RO) 6823 0x308E ゎ (HIRAGANA LETTER SMALL WA) 6824 0x308F わ (HIRAGANA LETTER WA) 6825 0x3090 ゐ (HIRAGANA LETTER WI) 6826 0x3091 ゑ (HIRAGANA LETTER WE) 6827 0x3092 を (HIRAGANA LETTER WO) 6828 0x3093 ん (HIRAGANA LETTER N) 6829 0xE772  (<Private Use>) 6830 0xE773  (<Private Use>) 6831 0xE774  (<Private Use>) 6832 0xE775  (<Private Use>) 6833 0xE776  (<Private Use>) 6834 0xE777  (<Private Use>) 6835 0xE778  (<Private Use>) 6836 0xE779  (<Private Use>) 6837 0xE77A  (<Private Use>) 6838 0xE77B  (<Private Use>) 6839 0xE77C  (<Private Use>) 6840 0xE646  (<Private Use>) 6841 0xE647  (<Private Use>) 6842 0xE648  (<Private Use>) 6843 0xE649  (<Private Use>) 6844 0xE64A  (<Private Use>) 6845 0xE64B  (<Private Use>) 6846 0xE64C  (<Private Use>) 6847 0xE64D  (<Private Use>) 6848 0xE64E  (<Private Use>) 6849 0xE64F  (<Private Use>) 6850 0xE650  (<Private Use>) 6851 0xE651  (<Private Use>) 6852 0xE652  (<Private Use>) 6853 0xE653  (<Private Use>) 6854 0xE654  (<Private Use>) 6855 0xE655  (<Private Use>) 6856 0xE656  (<Private Use>) 6857 0xE657  (<Private Use>) 6858 0xE658  (<Private Use>) 6859 0xE659  (<Private Use>) 6860 0xE65A  (<Private Use>) 6861 0xE65B  (<Private Use>) 6862 0xE65C  (<Private Use>) 6863 0xE65D  (<Private Use>) 6864 0xE65E  (<Private Use>) 6865 0xE65F  (<Private Use>) 6866 0xE660  (<Private Use>) 6867 0xE661  (<Private Use>) 6868 0xE662  (<Private Use>) 6869 0xE663  (<Private Use>) 6870 0xE664  (<Private Use>) 6871 0xE665  (<Private Use>) 6872 0xE666  (<Private Use>) 6873 0xE667  (<Private Use>) 6874 0xE668  (<Private Use>) 6875 0xE669  (<Private Use>) 6876 0xE66A  (<Private Use>) 6877 0xE66B  (<Private Use>) 6878 0xE66C  (<Private Use>) 6879 0xE66D  (<Private Use>) 6880 0xE66E  (<Private Use>) 6881 0xE66F  (<Private Use>) 6882 0xE670  (<Private Use>) 6883 0xE671  (<Private Use>) 6884 0xE672  (<Private Use>) 6885 0xE673  (<Private Use>) 6886 0xE674  (<Private Use>) 6887 0xE675  (<Private Use>) 6888 0xE676  (<Private Use>) 6889 0xE677  (<Private Use>) 6890 0xE678  (<Private Use>) 6891 0xE679  (<Private Use>) 6892 0xE67A  (<Private Use>) 6893 0xE67B  (<Private Use>) 6894 0xE67C  (<Private Use>) 6895 0xE67D  (<Private Use>) 6896 0xE67E  (<Private Use>) 6897 0xE67F  (<Private Use>) 6898 0xE680  (<Private Use>) 6899 0xE681  (<Private Use>) 6900 0xE682  (<Private Use>) 6901 0xE683  (<Private Use>) 6902 0xE684  (<Private Use>) 6903 0xE685  (<Private Use>) 6904 0xE686  (<Private Use>) 6905 0xE687  (<Private Use>) 6906 0xE688  (<Private Use>) 6907 0xE689  (<Private Use>) 6908 0xE68A  (<Private Use>) 6909 0xE68B  (<Private Use>) 6910 0xE68C  (<Private Use>) 6911 0xE68D  (<Private Use>) 6912 0xE68E  (<Private Use>) 6913 0xE68F  (<Private Use>) 6914 0xE690  (<Private Use>) 6915 0xE691  (<Private Use>) 6916 0xE692  (<Private Use>) 6917 0xE693  (<Private Use>) 6918 0xE694  (<Private Use>) 6919 0xE695  (<Private Use>) 6920 0xE696  (<Private Use>) 6921 0xE697  (<Private Use>) 6922 0xE698  (<Private Use>) 6923 0xE699  (<Private Use>) 6924 0xE69A  (<Private Use>) 6925 0xE69B  (<Private Use>) 6926 0xE69C  (<Private Use>) 6927 0xE69D  (<Private Use>) 6928 0xE69E  (<Private Use>) 6929 0xE69F  (<Private Use>) 6930 0xE6A0  (<Private Use>) 6931 0xE6A1  (<Private Use>) 6932 0xE6A2  (<Private Use>) 6933 0xE6A3  (<Private Use>) 6934 0xE6A4  (<Private Use>) 6935 0xE6A5  (<Private Use>) 6936 0x30A1 ァ (KATAKANA LETTER SMALL A) 6937 0x30A2 ア (KATAKANA LETTER A) 6938 0x30A3 ィ (KATAKANA LETTER SMALL I) 6939 0x30A4 イ (KATAKANA LETTER I) 6940 0x30A5 ゥ (KATAKANA LETTER SMALL U) 6941 0x30A6 ウ (KATAKANA LETTER U) 6942 0x30A7 ェ (KATAKANA LETTER SMALL E) 6943 0x30A8 エ (KATAKANA LETTER E) 6944 0x30A9 ォ (KATAKANA LETTER SMALL O) 6945 0x30AA オ (KATAKANA LETTER O) 6946 0x30AB カ (KATAKANA LETTER KA) 6947 0x30AC ガ (KATAKANA LETTER GA) 6948 0x30AD キ (KATAKANA LETTER KI) 6949 0x30AE ギ (KATAKANA LETTER GI) 6950 0x30AF ク (KATAKANA LETTER KU) 6951 0x30B0 グ (KATAKANA LETTER GU) 6952 0x30B1 ケ (KATAKANA LETTER KE) 6953 0x30B2 ゲ (KATAKANA LETTER GE) 6954 0x30B3 コ (KATAKANA LETTER KO) 6955 0x30B4 ゴ (KATAKANA LETTER GO) 6956 0x30B5 サ (KATAKANA LETTER SA) 6957 0x30B6 ザ (KATAKANA LETTER ZA) 6958 0x30B7 シ (KATAKANA LETTER SI) 6959 0x30B8 ジ (KATAKANA LETTER ZI) 6960 0x30B9 ス (KATAKANA LETTER SU) 6961 0x30BA ズ (KATAKANA LETTER ZU) 6962 0x30BB セ (KATAKANA LETTER SE) 6963 0x30BC ゼ (KATAKANA LETTER ZE) 6964 0x30BD ソ (KATAKANA LETTER SO) 6965 0x30BE ゾ (KATAKANA LETTER ZO) 6966 0x30BF タ (KATAKANA LETTER TA) 6967 0x30C0 ダ (KATAKANA LETTER DA) 6968 0x30C1 チ (KATAKANA LETTER TI) 6969 0x30C2 ヂ (KATAKANA LETTER DI) 6970 0x30C3 ッ (KATAKANA LETTER SMALL TU) 6971 0x30C4 ツ (KATAKANA LETTER TU) 6972 0x30C5 ヅ (KATAKANA LETTER DU) 6973 0x30C6 テ (KATAKANA LETTER TE) 6974 0x30C7 デ (KATAKANA LETTER DE) 6975 0x30C8 ト (KATAKANA LETTER TO) 6976 0x30C9 ド (KATAKANA LETTER DO) 6977 0x30CA ナ (KATAKANA LETTER NA) 6978 0x30CB ニ (KATAKANA LETTER NI) 6979 0x30CC ヌ (KATAKANA LETTER NU) 6980 0x30CD ネ (KATAKANA LETTER NE) 6981 0x30CE ノ (KATAKANA LETTER NO) 6982 0x30CF ハ (KATAKANA LETTER HA) 6983 0x30D0 バ (KATAKANA LETTER BA) 6984 0x30D1 パ (KATAKANA LETTER PA) 6985 0x30D2 ヒ (KATAKANA LETTER HI) 6986 0x30D3 ビ (KATAKANA LETTER BI) 6987 0x30D4 ピ (KATAKANA LETTER PI) 6988 0x30D5 フ (KATAKANA LETTER HU) 6989 0x30D6 ブ (KATAKANA LETTER BU) 6990 0x30D7 プ (KATAKANA LETTER PU) 6991 0x30D8 ヘ (KATAKANA LETTER HE) 6992 0x30D9 ベ (KATAKANA LETTER BE) 6993 0x30DA ペ (KATAKANA LETTER PE) 6994 0x30DB ホ (KATAKANA LETTER HO) 6995 0x30DC ボ (KATAKANA LETTER BO) 6996 0x30DD ポ (KATAKANA LETTER PO) 6997 0x30DE マ (KATAKANA LETTER MA) 6998 0x30DF ミ (KATAKANA LETTER MI) 6999 0x30E0 ム (KATAKANA LETTER MU) 7000 0x30E1 メ (KATAKANA LETTER ME) 7001 0x30E2 モ (KATAKANA LETTER MO) 7002 0x30E3 ャ (KATAKANA LETTER SMALL YA) 7003 0x30E4 ヤ (KATAKANA LETTER YA) 7004 0x30E5 ュ (KATAKANA LETTER SMALL YU) 7005 0x30E6 ユ (KATAKANA LETTER YU) 7006 0x30E7 ョ (KATAKANA LETTER SMALL YO) 7007 0x30E8 ヨ (KATAKANA LETTER YO) 7008 0x30E9 ラ (KATAKANA LETTER RA) 7009 0x30EA リ (KATAKANA LETTER RI) 7010 0x30EB ル (KATAKANA LETTER RU) 7011 0x30EC レ (KATAKANA LETTER RE) 7012 0x30ED ロ (KATAKANA LETTER RO) 7013 0x30EE ヮ (KATAKANA LETTER SMALL WA) 7014 0x30EF ワ (KATAKANA LETTER WA) 7015 0x30F0 ヰ (KATAKANA LETTER WI) 7016 0x30F1 ヱ (KATAKANA LETTER WE) 7017 0x30F2 ヲ (KATAKANA LETTER WO) 7018 0x30F3 ン (KATAKANA LETTER N) 7019 0x30F4 ヴ (KATAKANA LETTER VU) 7020 0x30F5 ヵ (KATAKANA LETTER SMALL KA) 7021 0x30F6 ヶ (KATAKANA LETTER SMALL KE) 7022 0xE77D  (<Private Use>) 7023 0xE77E  (<Private Use>) 7024 0xE77F  (<Private Use>) 7025 0xE780  (<Private Use>) 7026 0xE781  (<Private Use>) 7027 0xE782  (<Private Use>) 7028 0xE783  (<Private Use>) 7029 0xE784  (<Private Use>) 7030 0xE6A6  (<Private Use>) 7031 0xE6A7  (<Private Use>) 7032 0xE6A8  (<Private Use>) 7033 0xE6A9  (<Private Use>) 7034 0xE6AA  (<Private Use>) 7035 0xE6AB  (<Private Use>) 7036 0xE6AC  (<Private Use>) 7037 0xE6AD  (<Private Use>) 7038 0xE6AE  (<Private Use>) 7039 0xE6AF  (<Private Use>) 7040 0xE6B0  (<Private Use>) 7041 0xE6B1  (<Private Use>) 7042 0xE6B2  (<Private Use>) 7043 0xE6B3  (<Private Use>) 7044 0xE6B4  (<Private Use>) 7045 0xE6B5  (<Private Use>) 7046 0xE6B6  (<Private Use>) 7047 0xE6B7  (<Private Use>) 7048 0xE6B8  (<Private Use>) 7049 0xE6B9  (<Private Use>) 7050 0xE6BA  (<Private Use>) 7051 0xE6BB  (<Private Use>) 7052 0xE6BC  (<Private Use>) 7053 0xE6BD  (<Private Use>) 7054 0xE6BE  (<Private Use>) 7055 0xE6BF  (<Private Use>) 7056 0xE6C0  (<Private Use>) 7057 0xE6C1  (<Private Use>) 7058 0xE6C2  (<Private Use>) 7059 0xE6C3  (<Private Use>) 7060 0xE6C4  (<Private Use>) 7061 0xE6C5  (<Private Use>) 7062 0xE6C6  (<Private Use>) 7063 0xE6C7  (<Private Use>) 7064 0xE6C8  (<Private Use>) 7065 0xE6C9  (<Private Use>) 7066 0xE6CA  (<Private Use>) 7067 0xE6CB  (<Private Use>) 7068 0xE6CC  (<Private Use>) 7069 0xE6CD  (<Private Use>) 7070 0xE6CE  (<Private Use>) 7071 0xE6CF  (<Private Use>) 7072 0xE6D0  (<Private Use>) 7073 0xE6D1  (<Private Use>) 7074 0xE6D2  (<Private Use>) 7075 0xE6D3  (<Private Use>) 7076 0xE6D4  (<Private Use>) 7077 0xE6D5  (<Private Use>) 7078 0xE6D6  (<Private Use>) 7079 0xE6D7  (<Private Use>) 7080 0xE6D8  (<Private Use>) 7081 0xE6D9  (<Private Use>) 7082 0xE6DA  (<Private Use>) 7083 0xE6DB  (<Private Use>) 7084 0xE6DC  (<Private Use>) 7085 0xE6DD  (<Private Use>) 7086 0xE6DE  (<Private Use>) 7087 0xE6DF  (<Private Use>) 7088 0xE6E0  (<Private Use>) 7089 0xE6E1  (<Private Use>) 7090 0xE6E2  (<Private Use>) 7091 0xE6E3  (<Private Use>) 7092 0xE6E4  (<Private Use>) 7093 0xE6E5  (<Private Use>) 7094 0xE6E6  (<Private Use>) 7095 0xE6E7  (<Private Use>) 7096 0xE6E8  (<Private Use>) 7097 0xE6E9  (<Private Use>) 7098 0xE6EA  (<Private Use>) 7099 0xE6EB  (<Private Use>) 7100 0xE6EC  (<Private Use>) 7101 0xE6ED  (<Private Use>) 7102 0xE6EE  (<Private Use>) 7103 0xE6EF  (<Private Use>) 7104 0xE6F0  (<Private Use>) 7105 0xE6F1  (<Private Use>) 7106 0xE6F2  (<Private Use>) 7107 0xE6F3  (<Private Use>) 7108 0xE6F4  (<Private Use>) 7109 0xE6F5  (<Private Use>) 7110 0xE6F6  (<Private Use>) 7111 0xE6F7  (<Private Use>) 7112 0xE6F8  (<Private Use>) 7113 0xE6F9  (<Private Use>) 7114 0xE6FA  (<Private Use>) 7115 0xE6FB  (<Private Use>) 7116 0xE6FC  (<Private Use>) 7117 0xE6FD  (<Private Use>) 7118 0xE6FE  (<Private Use>) 7119 0xE6FF  (<Private Use>) 7120 0xE700  (<Private Use>) 7121 0xE701  (<Private Use>) 7122 0xE702  (<Private Use>) 7123 0xE703  (<Private Use>) 7124 0xE704  (<Private Use>) 7125 0xE705  (<Private Use>) 7126 0x0391 Α (GREEK CAPITAL LETTER ALPHA) 7127 0x0392 Β (GREEK CAPITAL LETTER BETA) 7128 0x0393 Γ (GREEK CAPITAL LETTER GAMMA) 7129 0x0394 Δ (GREEK CAPITAL LETTER DELTA) 7130 0x0395 Ε (GREEK CAPITAL LETTER EPSILON) 7131 0x0396 Ζ (GREEK CAPITAL LETTER ZETA) 7132 0x0397 Η (GREEK CAPITAL LETTER ETA) 7133 0x0398 Θ (GREEK CAPITAL LETTER THETA) 7134 0x0399 Ι (GREEK CAPITAL LETTER IOTA) 7135 0x039A Κ (GREEK CAPITAL LETTER KAPPA) 7136 0x039B Λ (GREEK CAPITAL LETTER LAMDA) 7137 0x039C Μ (GREEK CAPITAL LETTER MU) 7138 0x039D Ν (GREEK CAPITAL LETTER NU) 7139 0x039E Ξ (GREEK CAPITAL LETTER XI) 7140 0x039F Ο (GREEK CAPITAL LETTER OMICRON) 7141 0x03A0 Π (GREEK CAPITAL LETTER PI) 7142 0x03A1 Ρ (GREEK CAPITAL LETTER RHO) 7143 0x03A3 Σ (GREEK CAPITAL LETTER SIGMA) 7144 0x03A4 Τ (GREEK CAPITAL LETTER TAU) 7145 0x03A5 Υ (GREEK CAPITAL LETTER UPSILON) 7146 0x03A6 Φ (GREEK CAPITAL LETTER PHI) 7147 0x03A7 Χ (GREEK CAPITAL LETTER CHI) 7148 0x03A8 Ψ (GREEK CAPITAL LETTER PSI) 7149 0x03A9 Ω (GREEK CAPITAL LETTER OMEGA) 7150 0xE785  (<Private Use>) 7151 0xE786  (<Private Use>) 7152 0xE787  (<Private Use>) 7153 0xE788  (<Private Use>) 7154 0xE789  (<Private Use>) 7155 0xE78A  (<Private Use>) 7156 0xE78B  (<Private Use>) 7157 0xE78C  (<Private Use>) 7158 0x03B1 α (GREEK SMALL LETTER ALPHA) 7159 0x03B2 β (GREEK SMALL LETTER BETA) 7160 0x03B3 γ (GREEK SMALL LETTER GAMMA) 7161 0x03B4 δ (GREEK SMALL LETTER DELTA) 7162 0x03B5 ε (GREEK SMALL LETTER EPSILON) 7163 0x03B6 ζ (GREEK SMALL LETTER ZETA) 7164 0x03B7 η (GREEK SMALL LETTER ETA) 7165 0x03B8 θ (GREEK SMALL LETTER THETA) 7166 0x03B9 ι (GREEK SMALL LETTER IOTA) 7167 0x03BA κ (GREEK SMALL LETTER KAPPA) 7168 0x03BB λ (GREEK SMALL LETTER LAMDA) 7169 0x03BC μ (GREEK SMALL LETTER MU) 7170 0x03BD ν (GREEK SMALL LETTER NU) 7171 0x03BE ξ (GREEK SMALL LETTER XI) 7172 0x03BF ο (GREEK SMALL LETTER OMICRON) 7173 0x03C0 π (GREEK SMALL LETTER PI) 7174 0x03C1 ρ (GREEK SMALL LETTER RHO) 7175 0x03C3 σ (GREEK SMALL LETTER SIGMA) 7176 0x03C4 τ (GREEK SMALL LETTER TAU) 7177 0x03C5 υ (GREEK SMALL LETTER UPSILON) 7178 0x03C6 φ (GREEK SMALL LETTER PHI) 7179 0x03C7 χ (GREEK SMALL LETTER CHI) 7180 0x03C8 ψ (GREEK SMALL LETTER PSI) 7181 0x03C9 ω (GREEK SMALL LETTER OMEGA) 7182 0xFE10  (2024 update) 7183 0xFE12  (2024 update) 7184 0xFE11  (2024 update) 7185 0xFE13  (2024 update) 7186 0xFE14  (2024 update) 7187 0xFE15  (2024 update) 7188 0xFE16  (2024 update) 7189 0xFE35 ︵ (PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS) 7190 0xFE36 ︶ (PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS) 7191 0xFE39 ︹ (PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET) 7192 0xFE3A ︺ (PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET) 7193 0xFE3F ︿ (PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET) 7194 0xFE40 ﹀ (PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET) 7195 0xFE3D ︽ (PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET) 7196 0xFE3E ︾ (PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET) 7197 0xFE41 ﹁ (PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET) 7198 0xFE42 ﹂ (PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET) 7199 0xFE43 ﹃ (PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET) 7200 0xFE44 ﹄ (PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET) 7201 0xFE17  (2024 update) 7202 0xFE18  (2024 update) 7203 0xFE3B ︻ (PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET) 7204 0xFE3C ︼ (PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET) 7205 0xFE37 ︷ (PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET) 7206 0xFE38 ︸ (PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET) 7207 0xFE31 ︱ (PRESENTATION FORM FOR VERTICAL EM DASH) 7208 0xFE19  (2024 update) 7209 0xFE33 ︳ (PRESENTATION FORM FOR VERTICAL LOW LINE) 7210 0xFE34 ︴ (PRESENTATION FORM FOR VERTICAL WAVY LOW LINE) 7211 0xE797  (<Private Use>) 7212 0xE798  (<Private Use>) 7213 0xE799  (<Private Use>) 7214 0xE79A  (<Private Use>) 7215 0xE79B  (<Private Use>) 7216 0xE79C  (<Private Use>) 7217 0xE79D  (<Private Use>) 7218 0xE79E  (<Private Use>) 7219 0xE79F  (<Private Use>) 7220 0xE706  (<Private Use>) 7221 0xE707  (<Private Use>) 7222 0xE708  (<Private Use>) 7223 0xE709  (<Private Use>) 7224 0xE70A  (<Private Use>) 7225 0xE70B  (<Private Use>) 7226 0xE70C  (<Private Use>) 7227 0xE70D  (<Private Use>) 7228 0xE70E  (<Private Use>) 7229 0xE70F  (<Private Use>) 7230 0xE710  (<Private Use>) 7231 0xE711  (<Private Use>) 7232 0xE712  (<Private Use>) 7233 0xE713  (<Private Use>) 7234 0xE714  (<Private Use>) 7235 0xE715  (<Private Use>) 7236 0xE716  (<Private Use>) 7237 0xE717  (<Private Use>) 7238 0xE718  (<Private Use>) 7239 0xE719  (<Private Use>) 7240 0xE71A  (<Private Use>) 7241 0xE71B  (<Private Use>) 7242 0xE71C  (<Private Use>) 7243 0xE71D  (<Private Use>) 7244 0xE71E  (<Private Use>) 7245 0xE71F  (<Private Use>) 7246 0xE720  (<Private Use>) 7247 0xE721  (<Private Use>) 7248 0xE722  (<Private Use>) 7249 0xE723  (<Private Use>) 7250 0xE724  (<Private Use>) 7251 0xE725  (<Private Use>) 7252 0xE726  (<Private Use>) 7253 0xE727  (<Private Use>) 7254 0xE728  (<Private Use>) 7255 0xE729  (<Private Use>) 7256 0xE72A  (<Private Use>) 7257 0xE72B  (<Private Use>) 7258 0xE72C  (<Private Use>) 7259 0xE72D  (<Private Use>) 7260 0xE72E  (<Private Use>) 7261 0xE72F  (<Private Use>) 7262 0xE730  (<Private Use>) 7263 0xE731  (<Private Use>) 7264 0xE732  (<Private Use>) 7265 0xE733  (<Private Use>) 7266 0xE734  (<Private Use>) 7267 0xE735  (<Private Use>) 7268 0xE736  (<Private Use>) 7269 0xE737  (<Private Use>) 7270 0xE738  (<Private Use>) 7271 0xE739  (<Private Use>) 7272 0xE73A  (<Private Use>) 7273 0xE73B  (<Private Use>) 7274 0xE73C  (<Private Use>) 7275 0xE73D  (<Private Use>) 7276 0xE73E  (<Private Use>) 7277 0xE73F  (<Private Use>) 7278 0xE740  (<Private Use>) 7279 0xE741  (<Private Use>) 7280 0xE742  (<Private Use>) 7281 0xE743  (<Private Use>) 7282 0xE744  (<Private Use>) 7283 0xE745  (<Private Use>) 7284 0xE746  (<Private Use>) 7285 0xE747  (<Private Use>) 7286 0xE748  (<Private Use>) 7287 0xE749  (<Private Use>) 7288 0xE74A  (<Private Use>) 7289 0xE74B  (<Private Use>) 7290 0xE74C  (<Private Use>) 7291 0xE74D  (<Private Use>) 7292 0xE74E  (<Private Use>) 7293 0xE74F  (<Private Use>) 7294 0xE750  (<Private Use>) 7295 0xE751  (<Private Use>) 7296 0xE752  (<Private Use>) 7297 0xE753  (<Private Use>) 7298 0xE754  (<Private Use>) 7299 0xE755  (<Private Use>) 7300 0xE756  (<Private Use>) 7301 0xE757  (<Private Use>) 7302 0xE758  (<Private Use>) 7303 0xE759  (<Private Use>) 7304 0xE75A  (<Private Use>) 7305 0xE75B  (<Private Use>) 7306 0xE75C  (<Private Use>) 7307 0xE75D  (<Private Use>) 7308 0xE75E  (<Private Use>) 7309 0xE75F  (<Private Use>) 7310 0xE760  (<Private Use>) 7311 0xE761  (<Private Use>) 7312 0xE762  (<Private Use>) 7313 0xE763  (<Private Use>) 7314 0xE764  (<Private Use>) 7315 0xE765  (<Private Use>) 7316 0x0410 А (CYRILLIC CAPITAL LETTER A) 7317 0x0411 Б (CYRILLIC CAPITAL LETTER BE) 7318 0x0412 В (CYRILLIC CAPITAL LETTER VE) 7319 0x0413 Г (CYRILLIC CAPITAL LETTER GHE) 7320 0x0414 Д (CYRILLIC CAPITAL LETTER DE) 7321 0x0415 Е (CYRILLIC CAPITAL LETTER IE) 7322 0x0401 Ё (CYRILLIC CAPITAL LETTER IO) 7323 0x0416 Ж (CYRILLIC CAPITAL LETTER ZHE) 7324 0x0417 З (CYRILLIC CAPITAL LETTER ZE) 7325 0x0418 И (CYRILLIC CAPITAL LETTER I) 7326 0x0419 Й (CYRILLIC CAPITAL LETTER SHORT I) 7327 0x041A К (CYRILLIC CAPITAL LETTER KA) 7328 0x041B Л (CYRILLIC CAPITAL LETTER EL) 7329 0x041C М (CYRILLIC CAPITAL LETTER EM) 7330 0x041D Н (CYRILLIC CAPITAL LETTER EN) 7331 0x041E О (CYRILLIC CAPITAL LETTER O) 7332 0x041F П (CYRILLIC CAPITAL LETTER PE) 7333 0x0420 Р (CYRILLIC CAPITAL LETTER ER) 7334 0x0421 С (CYRILLIC CAPITAL LETTER ES) 7335 0x0422 Т (CYRILLIC CAPITAL LETTER TE) 7336 0x0423 У (CYRILLIC CAPITAL LETTER U) 7337 0x0424 Ф (CYRILLIC CAPITAL LETTER EF) 7338 0x0425 Х (CYRILLIC CAPITAL LETTER HA) 7339 0x0426 Ц (CYRILLIC CAPITAL LETTER TSE) 7340 0x0427 Ч (CYRILLIC CAPITAL LETTER CHE) 7341 0x0428 Ш (CYRILLIC CAPITAL LETTER SHA) 7342 0x0429 Щ (CYRILLIC CAPITAL LETTER SHCHA) 7343 0x042A Ъ (CYRILLIC CAPITAL LETTER HARD SIGN) 7344 0x042B Ы (CYRILLIC CAPITAL LETTER YERU) 7345 0x042C Ь (CYRILLIC CAPITAL LETTER SOFT SIGN) 7346 0x042D Э (CYRILLIC CAPITAL LETTER E) 7347 0x042E Ю (CYRILLIC CAPITAL LETTER YU) 7348 0x042F Я (CYRILLIC CAPITAL LETTER YA) 7349 0xE7A0  (<Private Use>) 7350 0xE7A1  (<Private Use>) 7351 0xE7A2  (<Private Use>) 7352 0xE7A3  (<Private Use>) 7353 0xE7A4  (<Private Use>) 7354 0xE7A5  (<Private Use>) 7355 0xE7A6  (<Private Use>) 7356 0xE7A7  (<Private Use>) 7357 0xE7A8  (<Private Use>) 7358 0xE7A9  (<Private Use>) 7359 0xE7AA  (<Private Use>) 7360 0xE7AB  (<Private Use>) 7361 0xE7AC  (<Private Use>) 7362 0xE7AD  (<Private Use>) 7363 0xE7AE  (<Private Use>) 7364 0x0430 а (CYRILLIC SMALL LETTER A) 7365 0x0431 б (CYRILLIC SMALL LETTER BE) 7366 0x0432 в (CYRILLIC SMALL LETTER VE) 7367 0x0433 г (CYRILLIC SMALL LETTER GHE) 7368 0x0434 д (CYRILLIC SMALL LETTER DE) 7369 0x0435 е (CYRILLIC SMALL LETTER IE) 7370 0x0451 ё (CYRILLIC SMALL LETTER IO) 7371 0x0436 ж (CYRILLIC SMALL LETTER ZHE) 7372 0x0437 з (CYRILLIC SMALL LETTER ZE) 7373 0x0438 и (CYRILLIC SMALL LETTER I) 7374 0x0439 й (CYRILLIC SMALL LETTER SHORT I) 7375 0x043A к (CYRILLIC SMALL LETTER KA) 7376 0x043B л (CYRILLIC SMALL LETTER EL) 7377 0x043C м (CYRILLIC SMALL LETTER EM) 7378 0x043D н (CYRILLIC SMALL LETTER EN) 7379 0x043E о (CYRILLIC SMALL LETTER O) 7380 0x043F п (CYRILLIC SMALL LETTER PE) 7381 0x0440 р (CYRILLIC SMALL LETTER ER) 7382 0x0441 с (CYRILLIC SMALL LETTER ES) 7383 0x0442 т (CYRILLIC SMALL LETTER TE) 7384 0x0443 у (CYRILLIC SMALL LETTER U) 7385 0x0444 ф (CYRILLIC SMALL LETTER EF) 7386 0x0445 х (CYRILLIC SMALL LETTER HA) 7387 0x0446 ц (CYRILLIC SMALL LETTER TSE) 7388 0x0447 ч (CYRILLIC SMALL LETTER CHE) 7389 0x0448 ш (CYRILLIC SMALL LETTER SHA) 7390 0x0449 щ (CYRILLIC SMALL LETTER SHCHA) 7391 0x044A ъ (CYRILLIC SMALL LETTER HARD SIGN) 7392 0x044B ы (CYRILLIC SMALL LETTER YERU) 7393 0x044C ь (CYRILLIC SMALL LETTER SOFT SIGN) 7394 0x044D э (CYRILLIC SMALL LETTER E) 7395 0x044E ю (CYRILLIC SMALL LETTER YU) 7396 0x044F я (CYRILLIC SMALL LETTER YA) 7397 0xE7AF  (<Private Use>) 7398 0xE7B0  (<Private Use>) 7399 0xE7B1  (<Private Use>) 7400 0xE7B2  (<Private Use>) 7401 0xE7B3  (<Private Use>) 7402 0xE7B4  (<Private Use>) 7403 0xE7B5  (<Private Use>) 7404 0xE7B6  (<Private Use>) 7405 0xE7B7  (<Private Use>) 7406 0xE7B8  (<Private Use>) 7407 0xE7B9  (<Private Use>) 7408 0xE7BA  (<Private Use>) 7409 0xE7BB  (<Private Use>) 7410 0x02CA ˊ (MODIFIER LETTER ACUTE ACCENT) 7411 0x02CB ˋ (MODIFIER LETTER GRAVE ACCENT) 7412 0x02D9 ˙ (DOT ABOVE) 7413 0x2013 – (EN DASH) 7414 0x2015 ― (HORIZONTAL BAR) 7415 0x2025 ‥ (TWO DOT LEADER) 7416 0x2035 ‵ (REVERSED PRIME) 7417 0x2105 ℅ (CARE OF) 7418 0x2109 ℉ (DEGREE FAHRENHEIT) 7419 0x2196 ↖ (NORTH WEST ARROW) 7420 0x2197 ↗ (NORTH EAST ARROW) 7421 0x2198 ↘ (SOUTH EAST ARROW) 7422 0x2199 ↙ (SOUTH WEST ARROW) 7423 0x2215 ∕ (DIVISION SLASH) 7424 0x221F ∟ (RIGHT ANGLE) 7425 0x2223 ∣ (DIVIDES) 7426 0x2252 ≒ (APPROXIMATELY EQUAL TO OR THE IMAGE OF) 7427 0x2266 ≦ (LESS-THAN OVER EQUAL TO) 7428 0x2267 ≧ (GREATER-THAN OVER EQUAL TO) 7429 0x22BF ⊿ (RIGHT TRIANGLE) 7430 0x2550 ═ (BOX DRAWINGS DOUBLE HORIZONTAL) 7431 0x2551 ║ (BOX DRAWINGS DOUBLE VERTICAL) 7432 0x2552 ╒ (BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE) 7433 0x2553 ╓ (BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE) 7434 0x2554 ╔ (BOX DRAWINGS DOUBLE DOWN AND RIGHT) 7435 0x2555 ╕ (BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE) 7436 0x2556 ╖ (BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE) 7437 0x2557 ╗ (BOX DRAWINGS DOUBLE DOWN AND LEFT) 7438 0x2558 ╘ (BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE) 7439 0x2559 ╙ (BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE) 7440 0x255A ╚ (BOX DRAWINGS DOUBLE UP AND RIGHT) 7441 0x255B ╛ (BOX DRAWINGS UP SINGLE AND LEFT DOUBLE) 7442 0x255C ╜ (BOX DRAWINGS UP DOUBLE AND LEFT SINGLE) 7443 0x255D ╝ (BOX DRAWINGS DOUBLE UP AND LEFT) 7444 0x255E ╞ (BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE) 7445 0x255F ╟ (BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE) 7446 0x2560 ╠ (BOX DRAWINGS DOUBLE VERTICAL AND RIGHT) 7447 0x2561 ╡ (BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE) 7448 0x2562 ╢ (BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE) 7449 0x2563 ╣ (BOX DRAWINGS DOUBLE VERTICAL AND LEFT) 7450 0x2564 ╤ (BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE) 7451 0x2565 ╥ (BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE) 7452 0x2566 ╦ (BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL) 7453 0x2567 ╧ (BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE) 7454 0x2568 ╨ (BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE) 7455 0x2569 ╩ (BOX DRAWINGS DOUBLE UP AND HORIZONTAL) 7456 0x256A ╪ (BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE) 7457 0x256B ╫ (BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE) 7458 0x256C ╬ (BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL) 7459 0x256D ╭ (BOX DRAWINGS LIGHT ARC DOWN AND RIGHT) 7460 0x256E ╮ (BOX DRAWINGS LIGHT ARC DOWN AND LEFT) 7461 0x256F ╯ (BOX DRAWINGS LIGHT ARC UP AND LEFT) 7462 0x2570 ╰ (BOX DRAWINGS LIGHT ARC UP AND RIGHT) 7463 0x2571 ╱ (BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT) 7464 0x2572 ╲ (BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT) 7465 0x2573 ╳ (BOX DRAWINGS LIGHT DIAGONAL CROSS) 7466 0x2581 ▁ (LOWER ONE EIGHTH BLOCK) 7467 0x2582 ▂ (LOWER ONE QUARTER BLOCK) 7468 0x2583 ▃ (LOWER THREE EIGHTHS BLOCK) 7469 0x2584 ▄ (LOWER HALF BLOCK) 7470 0x2585 ▅ (LOWER FIVE EIGHTHS BLOCK) 7471 0x2586 ▆ (LOWER THREE QUARTERS BLOCK) 7472 0x2587 ▇ (LOWER SEVEN EIGHTHS BLOCK) 7473 0x2588 █ (FULL BLOCK) 7474 0x2589 ▉ (LEFT SEVEN EIGHTHS BLOCK) 7475 0x258A ▊ (LEFT THREE QUARTERS BLOCK) 7476 0x258B ▋ (LEFT FIVE EIGHTHS BLOCK) 7477 0x258C ▌ (LEFT HALF BLOCK) 7478 0x258D ▍ (LEFT THREE EIGHTHS BLOCK) 7479 0x258E ▎ (LEFT ONE QUARTER BLOCK) 7480 0x258F ▏ (LEFT ONE EIGHTH BLOCK) 7481 0x2593 ▓ (DARK SHADE) 7482 0x2594 ▔ (UPPER ONE EIGHTH BLOCK) 7483 0x2595 ▕ (RIGHT ONE EIGHTH BLOCK) 7484 0x25BC ▼ (BLACK DOWN-POINTING TRIANGLE) 7485 0x25BD ▽ (WHITE DOWN-POINTING TRIANGLE) 7486 0x25E2 ◢ (BLACK LOWER RIGHT TRIANGLE) 7487 0x25E3 ◣ (BLACK LOWER LEFT TRIANGLE) 7488 0x25E4 ◤ (BLACK UPPER LEFT TRIANGLE) 7489 0x25E5 ◥ (BLACK UPPER RIGHT TRIANGLE) 7490 0x2609 ☉ (SUN) 7491 0x2295 ⊕ (CIRCLED PLUS) 7492 0x3012 〒 (POSTAL MARK) 7493 0x301D 〝 (REVERSED DOUBLE PRIME QUOTATION MARK) 7494 0x301E 〞 (DOUBLE PRIME QUOTATION MARK) 7495 0xE7BC  (<Private Use>) 7496 0xE7BD  (<Private Use>) 7497 0xE7BE  (<Private Use>) 7498 0xE7BF  (<Private Use>) 7499 0xE7C0  (<Private Use>) 7500 0xE7C1  (<Private Use>) 7501 0xE7C2  (<Private Use>) 7502 0xE7C3  (<Private Use>) 7503 0xE7C4  (<Private Use>) 7504 0xE7C5  (<Private Use>) 7505 0xE7C6  (<Private Use>) 7506 0x0101 ā (LATIN SMALL LETTER A WITH MACRON) 7507 0x00E1 á (LATIN SMALL LETTER A WITH ACUTE) 7508 0x01CE ǎ (LATIN SMALL LETTER A WITH CARON) 7509 0x00E0 à (LATIN SMALL LETTER A WITH GRAVE) 7510 0x0113 ē (LATIN SMALL LETTER E WITH MACRON) 7511 0x00E9 é (LATIN SMALL LETTER E WITH ACUTE) 7512 0x011B ě (LATIN SMALL LETTER E WITH CARON) 7513 0x00E8 è (LATIN SMALL LETTER E WITH GRAVE) 7514 0x012B ī (LATIN SMALL LETTER I WITH MACRON) 7515 0x00ED í (LATIN SMALL LETTER I WITH ACUTE) 7516 0x01D0 ǐ (LATIN SMALL LETTER I WITH CARON) 7517 0x00EC ì (LATIN SMALL LETTER I WITH GRAVE) 7518 0x014D ō (LATIN SMALL LETTER O WITH MACRON) 7519 0x00F3 ó (LATIN SMALL LETTER O WITH ACUTE) 7520 0x01D2 ǒ (LATIN SMALL LETTER O WITH CARON) 7521 0x00F2 ò (LATIN SMALL LETTER O WITH GRAVE) 7522 0x016B ū (LATIN SMALL LETTER U WITH MACRON) 7523 0x00FA ú (LATIN SMALL LETTER U WITH ACUTE) 7524 0x01D4 ǔ (LATIN SMALL LETTER U WITH CARON) 7525 0x00F9 ù (LATIN SMALL LETTER U WITH GRAVE) 7526 0x01D6 ǖ (LATIN SMALL LETTER U WITH DIAERESIS AND MACRON) 7527 0x01D8 ǘ (LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE) 7528 0x01DA ǚ (LATIN SMALL LETTER U WITH DIAERESIS AND CARON) 7529 0x01DC ǜ (LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE) 7530 0x00FC ü (LATIN SMALL LETTER U WITH DIAERESIS) 7531 0x00EA ê (LATIN SMALL LETTER E WITH CIRCUMFLEX) 7532 0x0251 ɑ (LATIN SMALL LETTER ALPHA) 7533 0x1E3F ḿ (LATIN SMALL LETTER M WITH ACUTE) 7534 0x0144 ń (LATIN SMALL LETTER N WITH ACUTE) 7535 0x0148 ň (LATIN SMALL LETTER N WITH CARON) 7536 0x01F9 ǹ (LATIN SMALL LETTER N WITH GRAVE) 7537 0x0261 ɡ (LATIN SMALL LETTER SCRIPT G) 7538 0xE7C9  (<Private Use>) 7539 0xE7CA  (<Private Use>) 7540 0xE7CB  (<Private Use>) 7541 0xE7CC  (<Private Use>) 7542 0x3105 ㄅ (BOPOMOFO LETTER B) 7543 0x3106 ㄆ (BOPOMOFO LETTER P) 7544 0x3107 ㄇ (BOPOMOFO LETTER M) 7545 0x3108 ㄈ (BOPOMOFO LETTER F) 7546 0x3109 ㄉ (BOPOMOFO LETTER D) 7547 0x310A ㄊ (BOPOMOFO LETTER T) 7548 0x310B ㄋ (BOPOMOFO LETTER N) 7549 0x310C ㄌ (BOPOMOFO LETTER L) 7550 0x310D ㄍ (BOPOMOFO LETTER G) 7551 0x310E ㄎ (BOPOMOFO LETTER K) 7552 0x310F ㄏ (BOPOMOFO LETTER H) 7553 0x3110 ㄐ (BOPOMOFO LETTER J) 7554 0x3111 ㄑ (BOPOMOFO LETTER Q) 7555 0x3112 ㄒ (BOPOMOFO LETTER X) 7556 0x3113 ㄓ (BOPOMOFO LETTER ZH) 7557 0x3114 ㄔ (BOPOMOFO LETTER CH) 7558 0x3115 ㄕ (BOPOMOFO LETTER SH) 7559 0x3116 ㄖ (BOPOMOFO LETTER R) 7560 0x3117 ㄗ (BOPOMOFO LETTER Z) 7561 0x3118 ㄘ (BOPOMOFO LETTER C) 7562 0x3119 ㄙ (BOPOMOFO LETTER S) 7563 0x311A ㄚ (BOPOMOFO LETTER A) 7564 0x311B ㄛ (BOPOMOFO LETTER O) 7565 0x311C ㄜ (BOPOMOFO LETTER E) 7566 0x311D ㄝ (BOPOMOFO LETTER EH) 7567 0x311E ㄞ (BOPOMOFO LETTER AI) 7568 0x311F ㄟ (BOPOMOFO LETTER EI) 7569 0x3120 ㄠ (BOPOMOFO LETTER AU) 7570 0x3121 ㄡ (BOPOMOFO LETTER OU) 7571 0x3122 ㄢ (BOPOMOFO LETTER AN) 7572 0x3123 ㄣ (BOPOMOFO LETTER EN) 7573 0x3124 ㄤ (BOPOMOFO LETTER ANG) 7574 0x3125 ㄥ (BOPOMOFO LETTER ENG) 7575 0x3126 ㄦ (BOPOMOFO LETTER ER) 7576 0x3127 ㄧ (BOPOMOFO LETTER I) 7577 0x3128 ㄨ (BOPOMOFO LETTER U) 7578 0x3129 ㄩ (BOPOMOFO LETTER IU) 7579 0xE7CD  (<Private Use>) 7580 0xE7CE  (<Private Use>) 7581 0xE7CF  (<Private Use>) 7582 0xE7D0  (<Private Use>) 7583 0xE7D1  (<Private Use>) 7584 0xE7D2  (<Private Use>) 7585 0xE7D3  (<Private Use>) 7586 0xE7D4  (<Private Use>) 7587 0xE7D5  (<Private Use>) 7588 0xE7D6  (<Private Use>) 7589 0xE7D7  (<Private Use>) 7590 0xE7D8  (<Private Use>) 7591 0xE7D9  (<Private Use>) 7592 0xE7DA  (<Private Use>) 7593 0xE7DB  (<Private Use>) 7594 0xE7DC  (<Private Use>) 7595 0xE7DD  (<Private Use>) 7596 0xE7DE  (<Private Use>) 7597 0xE7DF  (<Private Use>) 7598 0xE7E0  (<Private Use>) 7599 0xE7E1  (<Private Use>) 7600 0x3021 〡 (HANGZHOU NUMERAL ONE) 7601 0x3022 〢 (HANGZHOU NUMERAL TWO) 7602 0x3023 〣 (HANGZHOU NUMERAL THREE) 7603 0x3024 〤 (HANGZHOU NUMERAL FOUR) 7604 0x3025 〥 (HANGZHOU NUMERAL FIVE) 7605 0x3026 〦 (HANGZHOU NUMERAL SIX) 7606 0x3027 〧 (HANGZHOU NUMERAL SEVEN) 7607 0x3028 〨 (HANGZHOU NUMERAL EIGHT) 7608 0x3029 〩 (HANGZHOU NUMERAL NINE) 7609 0x32A3 ㊣ (CIRCLED IDEOGRAPH CORRECT) 7610 0x338E ㎎ (SQUARE MG) 7611 0x338F ㎏ (SQUARE KG) 7612 0x339C ㎜ (SQUARE MM) 7613 0x339D ㎝ (SQUARE CM) 7614 0x339E ㎞ (SQUARE KM) 7615 0x33A1 ㎡ (SQUARE M SQUARED) 7616 0x33C4 ㏄ (SQUARE CC) 7617 0x33CE ㏎ (SQUARE KM CAPITAL) 7618 0x33D1 ㏑ (SQUARE LN) 7619 0x33D2 ㏒ (SQUARE LOG) 7620 0x33D5 ㏕ (SQUARE MIL) 7621 0xFE30 ︰ (PRESENTATION FORM FOR VERTICAL TWO DOT LEADER) 7622 0xFFE2 ¬ (FULLWIDTH NOT SIGN) 7623 0xFFE4 ¦ (FULLWIDTH BROKEN BAR) 7624 0xE7E2  (<Private Use>) 7625 0x2121 ℡ (TELEPHONE SIGN) 7626 0x3231 ㈱ (PARENTHESIZED IDEOGRAPH STOCK) 7627 0xE7E3  (<Private Use>) 7628 0x2010 ‐ (HYPHEN) 7629 0xE7E4  (<Private Use>) 7630 0xE7E5  (<Private Use>) 7631 0xE7E6  (<Private Use>) 7632 0x30FC ー (KATAKANA-HIRAGANA PROLONGED SOUND MARK) 7633 0x309B ゛ (KATAKANA-HIRAGANA VOICED SOUND MARK) 7634 0x309C ゜ (KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK) 7635 0x30FD ヽ (KATAKANA ITERATION MARK) 7636 0x30FE ヾ (KATAKANA VOICED ITERATION MARK) 7637 0x3006 〆 (IDEOGRAPHIC CLOSING MARK) 7638 0x309D ゝ (HIRAGANA ITERATION MARK) 7639 0x309E ゞ (HIRAGANA VOICED ITERATION MARK) 7640 0xFE49 ﹉ (DASHED OVERLINE) 7641 0xFE4A ﹊ (CENTRELINE OVERLINE) 7642 0xFE4B ﹋ (WAVY OVERLINE) 7643 0xFE4C ﹌ (DOUBLE WAVY OVERLINE) 7644 0xFE4D ﹍ (DASHED LOW LINE) 7645 0xFE4E ﹎ (CENTRELINE LOW LINE) 7646 0xFE4F ﹏ (WAVY LOW LINE) 7647 0xFE50 ﹐ (SMALL COMMA) 7648 0xFE51 ﹑ (SMALL IDEOGRAPHIC COMMA) 7649 0xFE52 ﹒ (SMALL FULL STOP) 7650 0xFE54 ﹔ (SMALL SEMICOLON) 7651 0xFE55 ﹕ (SMALL COLON) 7652 0xFE56 ﹖ (SMALL QUESTION MARK) 7653 0xFE57 ﹗ (SMALL EXCLAMATION MARK) 7654 0xFE59 ﹙ (SMALL LEFT PARENTHESIS) 7655 0xFE5A ﹚ (SMALL RIGHT PARENTHESIS) 7656 0xFE5B ﹛ (SMALL LEFT CURLY BRACKET) 7657 0xFE5C ﹜ (SMALL RIGHT CURLY BRACKET) 7658 0xFE5D ﹝ (SMALL LEFT TORTOISE SHELL BRACKET) 7659 0xFE5E ﹞ (SMALL RIGHT TORTOISE SHELL BRACKET) 7660 0xFE5F ﹟ (SMALL NUMBER SIGN) 7661 0xFE60 ﹠ (SMALL AMPERSAND) 7662 0xFE61 ﹡ (SMALL ASTERISK) 7663 0xFE62 ﹢ (SMALL PLUS SIGN) 7664 0xFE63 ﹣ (SMALL HYPHEN-MINUS) 7665 0xFE64 ﹤ (SMALL LESS-THAN SIGN) 7666 0xFE65 ﹥ (SMALL GREATER-THAN SIGN) 7667 0xFE66 ﹦ (SMALL EQUALS SIGN) 7668 0xFE68 ﹨ (SMALL REVERSE SOLIDUS) 7669 0xFE69 ﹩ (SMALL DOLLAR SIGN) 7670 0xFE6A ﹪ (SMALL PERCENT SIGN) 7671 0xFE6B ﹫ (SMALL COMMERCIAL AT) 7672 0x303E 〾 (IDEOGRAPHIC VARIATION INDICATOR) 7673 0x2FF0 ⿰ (IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT) 7674 0x2FF1 ⿱ (IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO BELOW) 7675 0x2FF2 ⿲ (IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO MIDDLE AND RIGHT) 7676 0x2FF3 ⿳ (IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO MIDDLE AND BELOW) 7677 0x2FF4 ⿴ (IDEOGRAPHIC DESCRIPTION CHARACTER FULL SURROUND) 7678 0x2FF5 ⿵ (IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM ABOVE) 7679 0x2FF6 ⿶ (IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM BELOW) 7680 0x2FF7 ⿷ (IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LEFT) 7681 0x2FF8 ⿸ (IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER LEFT) 7682 0x2FF9 ⿹ (IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER RIGHT) 7683 0x2FFA ⿺ (IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LOWER LEFT) 7684 0x2FFB ⿻ (IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID) 7685 0x3007 〇 (IDEOGRAPHIC NUMBER ZERO) 7686 0xE7F4  (<Private Use>) 7687 0xE7F5  (<Private Use>) 7688 0xE7F6  (<Private Use>) 7689 0xE7F7  (<Private Use>) 7690 0xE7F8  (<Private Use>) 7691 0xE7F9  (<Private Use>) 7692 0xE7FA  (<Private Use>) 7693 0xE7FB  (<Private Use>) 7694 0xE7FC  (<Private Use>) 7695 0xE7FD  (<Private Use>) 7696 0xE7FE  (<Private Use>) 7697 0xE7FF  (<Private Use>) 7698 0xE800  (<Private Use>) 7699 0x2500 ─ (BOX DRAWINGS LIGHT HORIZONTAL) 7700 0x2501 ━ (BOX DRAWINGS HEAVY HORIZONTAL) 7701 0x2502 │ (BOX DRAWINGS LIGHT VERTICAL) 7702 0x2503 ┃ (BOX DRAWINGS HEAVY VERTICAL) 7703 0x2504 ┄ (BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL) 7704 0x2505 ┅ (BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL) 7705 0x2506 ┆ (BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL) 7706 0x2507 ┇ (BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL) 7707 0x2508 ┈ (BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL) 7708 0x2509 ┉ (BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL) 7709 0x250A ┊ (BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL) 7710 0x250B ┋ (BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL) 7711 0x250C ┌ (BOX DRAWINGS LIGHT DOWN AND RIGHT) 7712 0x250D ┍ (BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY) 7713 0x250E ┎ (BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT) 7714 0x250F ┏ (BOX DRAWINGS HEAVY DOWN AND RIGHT) 7715 0x2510 ┐ (BOX DRAWINGS LIGHT DOWN AND LEFT) 7716 0x2511 ┑ (BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY) 7717 0x2512 ┒ (BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT) 7718 0x2513 ┓ (BOX DRAWINGS HEAVY DOWN AND LEFT) 7719 0x2514 └ (BOX DRAWINGS LIGHT UP AND RIGHT) 7720 0x2515 ┕ (BOX DRAWINGS UP LIGHT AND RIGHT HEAVY) 7721 0x2516 ┖ (BOX DRAWINGS UP HEAVY AND RIGHT LIGHT) 7722 0x2517 ┗ (BOX DRAWINGS HEAVY UP AND RIGHT) 7723 0x2518 ┘ (BOX DRAWINGS LIGHT UP AND LEFT) 7724 0x2519 ┙ (BOX DRAWINGS UP LIGHT AND LEFT HEAVY) 7725 0x251A ┚ (BOX DRAWINGS UP HEAVY AND LEFT LIGHT) 7726 0x251B ┛ (BOX DRAWINGS HEAVY UP AND LEFT) 7727 0x251C ├ (BOX DRAWINGS LIGHT VERTICAL AND RIGHT) 7728 0x251D ┝ (BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY) 7729 0x251E ┞ (BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT) 7730 0x251F ┟ (BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT) 7731 0x2520 ┠ (BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT) 7732 0x2521 ┡ (BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY) 7733 0x2522 ┢ (BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY) 7734 0x2523 ┣ (BOX DRAWINGS HEAVY VERTICAL AND RIGHT) 7735 0x2524 ┤ (BOX DRAWINGS LIGHT VERTICAL AND LEFT) 7736 0x2525 ┥ (BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY) 7737 0x2526 ┦ (BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT) 7738 0x2527 ┧ (BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT) 7739 0x2528 ┨ (BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT) 7740 0x2529 ┩ (BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY) 7741 0x252A ┪ (BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY) 7742 0x252B ┫ (BOX DRAWINGS HEAVY VERTICAL AND LEFT) 7743 0x252C ┬ (BOX DRAWINGS LIGHT DOWN AND HORIZONTAL) 7744 0x252D ┭ (BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT) 7745 0x252E ┮ (BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT) 7746 0x252F ┯ (BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY) 7747 0x2530 ┰ (BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT) 7748 0x2531 ┱ (BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY) 7749 0x2532 ┲ (BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY) 7750 0x2533 ┳ (BOX DRAWINGS HEAVY DOWN AND HORIZONTAL) 7751 0x2534 ┴ (BOX DRAWINGS LIGHT UP AND HORIZONTAL) 7752 0x2535 ┵ (BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT) 7753 0x2536 ┶ (BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT) 7754 0x2537 ┷ (BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY) 7755 0x2538 ┸ (BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT) 7756 0x2539 ┹ (BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY) 7757 0x253A ┺ (BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY) 7758 0x253B ┻ (BOX DRAWINGS HEAVY UP AND HORIZONTAL) 7759 0x253C ┼ (BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL) 7760 0x253D ┽ (BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT) 7761 0x253E ┾ (BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT) 7762 0x253F ┿ (BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY) 7763 0x2540 ╀ (BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT) 7764 0x2541 ╁ (BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT) 7765 0x2542 ╂ (BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT) 7766 0x2543 ╃ (BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT) 7767 0x2544 ╄ (BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT) 7768 0x2545 ╅ (BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT) 7769 0x2546 ╆ (BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT) 7770 0x2547 ╇ (BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY) 7771 0x2548 ╈ (BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY) 7772 0x2549 ╉ (BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY) 7773 0x254A ╊ (BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY) 7774 0x254B ╋ (BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL) 7775 0xE801  (<Private Use>) 7776 0xE802  (<Private Use>) 7777 0xE803  (<Private Use>) 7778 0xE804  (<Private Use>) 7779 0xE805  (<Private Use>) 7780 0xE806  (<Private Use>) 7781 0xE807  (<Private Use>) 7782 0xE808  (<Private Use>) 7783 0xE809  (<Private Use>) 7784 0xE80A  (<Private Use>) 7785 0xE80B  (<Private Use>) 7786 0xE80C  (<Private Use>) 7787 0xE80D  (<Private Use>) 7788 0xE80E  (<Private Use>) 7789 0xE80F  (<Private Use>) 7790 0x72DC 狜 (<CJK Ideograph>) 7791 0x72DD 狝 (<CJK Ideograph>) 7792 0x72DF 狟 (<CJK Ideograph>) 7793 0x72E2 狢 (<CJK Ideograph>) 7794 0x72E3 狣 (<CJK Ideograph>) 7795 0x72E4 狤 (<CJK Ideograph>) 7796 0x72E5 狥 (<CJK Ideograph>) 7797 0x72E6 狦 (<CJK Ideograph>) 7798 0x72E7 狧 (<CJK Ideograph>) 7799 0x72EA 狪 (<CJK Ideograph>) 7800 0x72EB 狫 (<CJK Ideograph>) 7801 0x72F5 狵 (<CJK Ideograph>) 7802 0x72F6 狶 (<CJK Ideograph>) 7803 0x72F9 狹 (<CJK Ideograph>) 7804 0x72FD 狽 (<CJK Ideograph>) 7805 0x72FE 狾 (<CJK Ideograph>) 7806 0x72FF 狿 (<CJK Ideograph>) 7807 0x7300 猀 (<CJK Ideograph>) 7808 0x7302 猂 (<CJK Ideograph>) 7809 0x7304 猄 (<CJK Ideograph>) 7810 0x7305 猅 (<CJK Ideograph>) 7811 0x7306 猆 (<CJK Ideograph>) 7812 0x7307 猇 (<CJK Ideograph>) 7813 0x7308 猈 (<CJK Ideograph>) 7814 0x7309 猉 (<CJK Ideograph>) 7815 0x730B 猋 (<CJK Ideograph>) 7816 0x730C 猌 (<CJK Ideograph>) 7817 0x730D 猍 (<CJK Ideograph>) 7818 0x730F 猏 (<CJK Ideograph>) 7819 0x7310 猐 (<CJK Ideograph>) 7820 0x7311 猑 (<CJK Ideograph>) 7821 0x7312 猒 (<CJK Ideograph>) 7822 0x7314 猔 (<CJK Ideograph>) 7823 0x7318 猘 (<CJK Ideograph>) 7824 0x7319 猙 (<CJK Ideograph>) 7825 0x731A 猚 (<CJK Ideograph>) 7826 0x731F 猟 (<CJK Ideograph>) 7827 0x7320 猠 (<CJK Ideograph>) 7828 0x7323 猣 (<CJK Ideograph>) 7829 0x7324 猤 (<CJK Ideograph>) 7830 0x7326 猦 (<CJK Ideograph>) 7831 0x7327 猧 (<CJK Ideograph>) 7832 0x7328 猨 (<CJK Ideograph>) 7833 0x732D 猭 (<CJK Ideograph>) 7834 0x732F 猯 (<CJK Ideograph>) 7835 0x7330 猰 (<CJK Ideograph>) 7836 0x7332 猲 (<CJK Ideograph>) 7837 0x7333 猳 (<CJK Ideograph>) 7838 0x7335 猵 (<CJK Ideograph>) 7839 0x7336 猶 (<CJK Ideograph>) 7840 0x733A 猺 (<CJK Ideograph>) 7841 0x733B 猻 (<CJK Ideograph>) 7842 0x733C 猼 (<CJK Ideograph>) 7843 0x733D 猽 (<CJK Ideograph>) 7844 0x7340 獀 (<CJK Ideograph>) 7845 0x7341 獁 (<CJK Ideograph>) 7846 0x7342 獂 (<CJK Ideograph>) 7847 0x7343 獃 (<CJK Ideograph>) 7848 0x7344 獄 (<CJK Ideograph>) 7849 0x7345 獅 (<CJK Ideograph>) 7850 0x7346 獆 (<CJK Ideograph>) 7851 0x7347 獇 (<CJK Ideograph>) 7852 0x7348 獈 (<CJK Ideograph>) 7853 0x7349 獉 (<CJK Ideograph>) 7854 0x734A 獊 (<CJK Ideograph>) 7855 0x734B 獋 (<CJK Ideograph>) 7856 0x734C 獌 (<CJK Ideograph>) 7857 0x734E 獎 (<CJK Ideograph>) 7858 0x734F 獏 (<CJK Ideograph>) 7859 0x7351 獑 (<CJK Ideograph>) 7860 0x7353 獓 (<CJK Ideograph>) 7861 0x7354 獔 (<CJK Ideograph>) 7862 0x7355 獕 (<CJK Ideograph>) 7863 0x7356 獖 (<CJK Ideograph>) 7864 0x7358 獘 (<CJK Ideograph>) 7865 0x7359 獙 (<CJK Ideograph>) 7866 0x735A 獚 (<CJK Ideograph>) 7867 0x735B 獛 (<CJK Ideograph>) 7868 0x735C 獜 (<CJK Ideograph>) 7869 0x735D 獝 (<CJK Ideograph>) 7870 0x735E 獞 (<CJK Ideograph>) 7871 0x735F 獟 (<CJK Ideograph>) 7872 0x7361 獡 (<CJK Ideograph>) 7873 0x7362 獢 (<CJK Ideograph>) 7874 0x7363 獣 (<CJK Ideograph>) 7875 0x7364 獤 (<CJK Ideograph>) 7876 0x7365 獥 (<CJK Ideograph>) 7877 0x7366 獦 (<CJK Ideograph>) 7878 0x7367 獧 (<CJK Ideograph>) 7879 0x7368 獨 (<CJK Ideograph>) 7880 0x7369 獩 (<CJK Ideograph>) 7881 0x736A 獪 (<CJK Ideograph>) 7882 0x736B 獫 (<CJK Ideograph>) 7883 0x736E 獮 (<CJK Ideograph>) 7884 0x7370 獰 (<CJK Ideograph>) 7885 0x7371 獱 (<CJK Ideograph>) 7886 0xE000  (<Private Use>) 7887 0xE001  (<Private Use>) 7888 0xE002  (<Private Use>) 7889 0xE003  (<Private Use>) 7890 0xE004  (<Private Use>) 7891 0xE005  (<Private Use>) 7892 0xE006  (<Private Use>) 7893 0xE007  (<Private Use>) 7894 0xE008  (<Private Use>) 7895 0xE009  (<Private Use>) 7896 0xE00A  (<Private Use>) 7897 0xE00B  (<Private Use>) 7898 0xE00C  (<Private Use>) 7899 0xE00D  (<Private Use>) 7900 0xE00E  (<Private Use>) 7901 0xE00F  (<Private Use>) 7902 0xE010  (<Private Use>) 7903 0xE011  (<Private Use>) 7904 0xE012  (<Private Use>) 7905 0xE013  (<Private Use>) 7906 0xE014  (<Private Use>) 7907 0xE015  (<Private Use>) 7908 0xE016  (<Private Use>) 7909 0xE017  (<Private Use>) 7910 0xE018  (<Private Use>) 7911 0xE019  (<Private Use>) 7912 0xE01A  (<Private Use>) 7913 0xE01B  (<Private Use>) 7914 0xE01C  (<Private Use>) 7915 0xE01D  (<Private Use>) 7916 0xE01E  (<Private Use>) 7917 0xE01F  (<Private Use>) 7918 0xE020  (<Private Use>) 7919 0xE021  (<Private Use>) 7920 0xE022  (<Private Use>) 7921 0xE023  (<Private Use>) 7922 0xE024  (<Private Use>) 7923 0xE025  (<Private Use>) 7924 0xE026  (<Private Use>) 7925 0xE027  (<Private Use>) 7926 0xE028  (<Private Use>) 7927 0xE029  (<Private Use>) 7928 0xE02A  (<Private Use>) 7929 0xE02B  (<Private Use>) 7930 0xE02C  (<Private Use>) 7931 0xE02D  (<Private Use>) 7932 0xE02E  (<Private Use>) 7933 0xE02F  (<Private Use>) 7934 0xE030  (<Private Use>) 7935 0xE031  (<Private Use>) 7936 0xE032  (<Private Use>) 7937 0xE033  (<Private Use>) 7938 0xE034  (<Private Use>) 7939 0xE035  (<Private Use>) 7940 0xE036  (<Private Use>) 7941 0xE037  (<Private Use>) 7942 0xE038  (<Private Use>) 7943 0xE039  (<Private Use>) 7944 0xE03A  (<Private Use>) 7945 0xE03B  (<Private Use>) 7946 0xE03C  (<Private Use>) 7947 0xE03D  (<Private Use>) 7948 0xE03E  (<Private Use>) 7949 0xE03F  (<Private Use>) 7950 0xE040  (<Private Use>) 7951 0xE041  (<Private Use>) 7952 0xE042  (<Private Use>) 7953 0xE043  (<Private Use>) 7954 0xE044  (<Private Use>) 7955 0xE045  (<Private Use>) 7956 0xE046  (<Private Use>) 7957 0xE047  (<Private Use>) 7958 0xE048  (<Private Use>) 7959 0xE049  (<Private Use>) 7960 0xE04A  (<Private Use>) 7961 0xE04B  (<Private Use>) 7962 0xE04C  (<Private Use>) 7963 0xE04D  (<Private Use>) 7964 0xE04E  (<Private Use>) 7965 0xE04F  (<Private Use>) 7966 0xE050  (<Private Use>) 7967 0xE051  (<Private Use>) 7968 0xE052  (<Private Use>) 7969 0xE053  (<Private Use>) 7970 0xE054  (<Private Use>) 7971 0xE055  (<Private Use>) 7972 0xE056  (<Private Use>) 7973 0xE057  (<Private Use>) 7974 0xE058  (<Private Use>) 7975 0xE059  (<Private Use>) 7976 0xE05A  (<Private Use>) 7977 0xE05B  (<Private Use>) 7978 0xE05C  (<Private Use>) 7979 0xE05D  (<Private Use>) 7980 0x7372 獲 (<CJK Ideograph>) 7981 0x7373 獳 (<CJK Ideograph>) 7982 0x7374 獴 (<CJK Ideograph>) 7983 0x7375 獵 (<CJK Ideograph>) 7984 0x7376 獶 (<CJK Ideograph>) 7985 0x7377 獷 (<CJK Ideograph>) 7986 0x7378 獸 (<CJK Ideograph>) 7987 0x7379 獹 (<CJK Ideograph>) 7988 0x737A 獺 (<CJK Ideograph>) 7989 0x737B 獻 (<CJK Ideograph>) 7990 0x737C 獼 (<CJK Ideograph>) 7991 0x737D 獽 (<CJK Ideograph>) 7992 0x737F 獿 (<CJK Ideograph>) 7993 0x7380 玀 (<CJK Ideograph>) 7994 0x7381 玁 (<CJK Ideograph>) 7995 0x7382 玂 (<CJK Ideograph>) 7996 0x7383 玃 (<CJK Ideograph>) 7997 0x7385 玅 (<CJK Ideograph>) 7998 0x7386 玆 (<CJK Ideograph>) 7999 0x7388 玈 (<CJK Ideograph>) 8000 0x738A 玊 (<CJK Ideograph>) 8001 0x738C 玌 (<CJK Ideograph>) 8002 0x738D 玍 (<CJK Ideograph>) 8003 0x738F 玏 (<CJK Ideograph>) 8004 0x7390 玐 (<CJK Ideograph>) 8005 0x7392 玒 (<CJK Ideograph>) 8006 0x7393 玓 (<CJK Ideograph>) 8007 0x7394 玔 (<CJK Ideograph>) 8008 0x7395 玕 (<CJK Ideograph>) 8009 0x7397 玗 (<CJK Ideograph>) 8010 0x7398 玘 (<CJK Ideograph>) 8011 0x7399 玙 (<CJK Ideograph>) 8012 0x739A 玚 (<CJK Ideograph>) 8013 0x739C 玜 (<CJK Ideograph>) 8014 0x739D 玝 (<CJK Ideograph>) 8015 0x739E 玞 (<CJK Ideograph>) 8016 0x73A0 玠 (<CJK Ideograph>) 8017 0x73A1 玡 (<CJK Ideograph>) 8018 0x73A3 玣 (<CJK Ideograph>) 8019 0x73A4 玤 (<CJK Ideograph>) 8020 0x73A5 玥 (<CJK Ideograph>) 8021 0x73A6 玦 (<CJK Ideograph>) 8022 0x73A7 玧 (<CJK Ideograph>) 8023 0x73A8 玨 (<CJK Ideograph>) 8024 0x73AA 玪 (<CJK Ideograph>) 8025 0x73AC 玬 (<CJK Ideograph>) 8026 0x73AD 玭 (<CJK Ideograph>) 8027 0x73B1 玱 (<CJK Ideograph>) 8028 0x73B4 玴 (<CJK Ideograph>) 8029 0x73B5 玵 (<CJK Ideograph>) 8030 0x73B6 玶 (<CJK Ideograph>) 8031 0x73B8 玸 (<CJK Ideograph>) 8032 0x73B9 玹 (<CJK Ideograph>) 8033 0x73BC 玼 (<CJK Ideograph>) 8034 0x73BD 玽 (<CJK Ideograph>) 8035 0x73BE 玾 (<CJK Ideograph>) 8036 0x73BF 玿 (<CJK Ideograph>) 8037 0x73C1 珁 (<CJK Ideograph>) 8038 0x73C3 珃 (<CJK Ideograph>) 8039 0x73C4 珄 (<CJK Ideograph>) 8040 0x73C5 珅 (<CJK Ideograph>) 8041 0x73C6 珆 (<CJK Ideograph>) 8042 0x73C7 珇 (<CJK Ideograph>) 8043 0x73CB 珋 (<CJK Ideograph>) 8044 0x73CC 珌 (<CJK Ideograph>) 8045 0x73CE 珎 (<CJK Ideograph>) 8046 0x73D2 珒 (<CJK Ideograph>) 8047 0x73D3 珓 (<CJK Ideograph>) 8048 0x73D4 珔 (<CJK Ideograph>) 8049 0x73D5 珕 (<CJK Ideograph>) 8050 0x73D6 珖 (<CJK Ideograph>) 8051 0x73D7 珗 (<CJK Ideograph>) 8052 0x73D8 珘 (<CJK Ideograph>) 8053 0x73DA 珚 (<CJK Ideograph>) 8054 0x73DB 珛 (<CJK Ideograph>) 8055 0x73DC 珜 (<CJK Ideograph>) 8056 0x73DD 珝 (<CJK Ideograph>) 8057 0x73DF 珟 (<CJK Ideograph>) 8058 0x73E1 珡 (<CJK Ideograph>) 8059 0x73E2 珢 (<CJK Ideograph>) 8060 0x73E3 珣 (<CJK Ideograph>) 8061 0x73E4 珤 (<CJK Ideograph>) 8062 0x73E6 珦 (<CJK Ideograph>) 8063 0x73E8 珨 (<CJK Ideograph>) 8064 0x73EA 珪 (<CJK Ideograph>) 8065 0x73EB 珫 (<CJK Ideograph>) 8066 0x73EC 珬 (<CJK Ideograph>) 8067 0x73EE 珮 (<CJK Ideograph>) 8068 0x73EF 珯 (<CJK Ideograph>) 8069 0x73F0 珰 (<CJK Ideograph>) 8070 0x73F1 珱 (<CJK Ideograph>) 8071 0x73F3 珳 (<CJK Ideograph>) 8072 0x73F4 珴 (<CJK Ideograph>) 8073 0x73F5 珵 (<CJK Ideograph>) 8074 0x73F6 珶 (<CJK Ideograph>) 8075 0x73F7 珷 (<CJK Ideograph>) 8076 0xE05E  (<Private Use>) 8077 0xE05F  (<Private Use>) 8078 0xE060  (<Private Use>) 8079 0xE061  (<Private Use>) 8080 0xE062  (<Private Use>) 8081 0xE063  (<Private Use>) 8082 0xE064  (<Private Use>) 8083 0xE065  (<Private Use>) 8084 0xE066  (<Private Use>) 8085 0xE067  (<Private Use>) 8086 0xE068  (<Private Use>) 8087 0xE069  (<Private Use>) 8088 0xE06A  (<Private Use>) 8089 0xE06B  (<Private Use>) 8090 0xE06C  (<Private Use>) 8091 0xE06D  (<Private Use>) 8092 0xE06E  (<Private Use>) 8093 0xE06F  (<Private Use>) 8094 0xE070  (<Private Use>) 8095 0xE071  (<Private Use>) 8096 0xE072  (<Private Use>) 8097 0xE073  (<Private Use>) 8098 0xE074  (<Private Use>) 8099 0xE075  (<Private Use>) 8100 0xE076  (<Private Use>) 8101 0xE077  (<Private Use>) 8102 0xE078  (<Private Use>) 8103 0xE079  (<Private Use>) 8104 0xE07A  (<Private Use>) 8105 0xE07B  (<Private Use>) 8106 0xE07C  (<Private Use>) 8107 0xE07D  (<Private Use>) 8108 0xE07E  (<Private Use>) 8109 0xE07F  (<Private Use>) 8110 0xE080  (<Private Use>) 8111 0xE081  (<Private Use>) 8112 0xE082  (<Private Use>) 8113 0xE083  (<Private Use>) 8114 0xE084  (<Private Use>) 8115 0xE085  (<Private Use>) 8116 0xE086  (<Private Use>) 8117 0xE087  (<Private Use>) 8118 0xE088  (<Private Use>) 8119 0xE089  (<Private Use>) 8120 0xE08A  (<Private Use>) 8121 0xE08B  (<Private Use>) 8122 0xE08C  (<Private Use>) 8123 0xE08D  (<Private Use>) 8124 0xE08E  (<Private Use>) 8125 0xE08F  (<Private Use>) 8126 0xE090  (<Private Use>) 8127 0xE091  (<Private Use>) 8128 0xE092  (<Private Use>) 8129 0xE093  (<Private Use>) 8130 0xE094  (<Private Use>) 8131 0xE095  (<Private Use>) 8132 0xE096  (<Private Use>) 8133 0xE097  (<Private Use>) 8134 0xE098  (<Private Use>) 8135 0xE099  (<Private Use>) 8136 0xE09A  (<Private Use>) 8137 0xE09B  (<Private Use>) 8138 0xE09C  (<Private Use>) 8139 0xE09D  (<Private Use>) 8140 0xE09E  (<Private Use>) 8141 0xE09F  (<Private Use>) 8142 0xE0A0  (<Private Use>) 8143 0xE0A1  (<Private Use>) 8144 0xE0A2  (<Private Use>) 8145 0xE0A3  (<Private Use>) 8146 0xE0A4  (<Private Use>) 8147 0xE0A5  (<Private Use>) 8148 0xE0A6  (<Private Use>) 8149 0xE0A7  (<Private Use>) 8150 0xE0A8  (<Private Use>) 8151 0xE0A9  (<Private Use>) 8152 0xE0AA  (<Private Use>) 8153 0xE0AB  (<Private Use>) 8154 0xE0AC  (<Private Use>) 8155 0xE0AD  (<Private Use>) 8156 0xE0AE  (<Private Use>) 8157 0xE0AF  (<Private Use>) 8158 0xE0B0  (<Private Use>) 8159 0xE0B1  (<Private Use>) 8160 0xE0B2  (<Private Use>) 8161 0xE0B3  (<Private Use>) 8162 0xE0B4  (<Private Use>) 8163 0xE0B5  (<Private Use>) 8164 0xE0B6  (<Private Use>) 8165 0xE0B7  (<Private Use>) 8166 0xE0B8  (<Private Use>) 8167 0xE0B9  (<Private Use>) 8168 0xE0BA  (<Private Use>) 8169 0xE0BB  (<Private Use>) 8170 0x73F8 珸 (<CJK Ideograph>) 8171 0x73F9 珹 (<CJK Ideograph>) 8172 0x73FA 珺 (<CJK Ideograph>) 8173 0x73FB 珻 (<CJK Ideograph>) 8174 0x73FC 珼 (<CJK Ideograph>) 8175 0x73FD 珽 (<CJK Ideograph>) 8176 0x73FE 現 (<CJK Ideograph>) 8177 0x73FF 珿 (<CJK Ideograph>) 8178 0x7400 琀 (<CJK Ideograph>) 8179 0x7401 琁 (<CJK Ideograph>) 8180 0x7402 琂 (<CJK Ideograph>) 8181 0x7404 琄 (<CJK Ideograph>) 8182 0x7407 琇 (<CJK Ideograph>) 8183 0x7408 琈 (<CJK Ideograph>) 8184 0x740B 琋 (<CJK Ideograph>) 8185 0x740C 琌 (<CJK Ideograph>) 8186 0x740D 琍 (<CJK Ideograph>) 8187 0x740E 琎 (<CJK Ideograph>) 8188 0x7411 琑 (<CJK Ideograph>) 8189 0x7412 琒 (<CJK Ideograph>) 8190 0x7413 琓 (<CJK Ideograph>) 8191 0x7414 琔 (<CJK Ideograph>) 8192 0x7415 琕 (<CJK Ideograph>) 8193 0x7416 琖 (<CJK Ideograph>) 8194 0x7417 琗 (<CJK Ideograph>) 8195 0x7418 琘 (<CJK Ideograph>) 8196 0x7419 琙 (<CJK Ideograph>) 8197 0x741C 琜 (<CJK Ideograph>) 8198 0x741D 琝 (<CJK Ideograph>) 8199 0x741E 琞 (<CJK Ideograph>) 8200 0x741F 琟 (<CJK Ideograph>) 8201 0x7420 琠 (<CJK Ideograph>) 8202 0x7421 琡 (<CJK Ideograph>) 8203 0x7423 琣 (<CJK Ideograph>) 8204 0x7424 琤 (<CJK Ideograph>) 8205 0x7427 琧 (<CJK Ideograph>) 8206 0x7429 琩 (<CJK Ideograph>) 8207 0x742B 琫 (<CJK Ideograph>) 8208 0x742D 琭 (<CJK Ideograph>) 8209 0x742F 琯 (<CJK Ideograph>) 8210 0x7431 琱 (<CJK Ideograph>) 8211 0x7432 琲 (<CJK Ideograph>) 8212 0x7437 琷 (<CJK Ideograph>) 8213 0x7438 琸 (<CJK Ideograph>) 8214 0x7439 琹 (<CJK Ideograph>) 8215 0x743A 琺 (<CJK Ideograph>) 8216 0x743B 琻 (<CJK Ideograph>) 8217 0x743D 琽 (<CJK Ideograph>) 8218 0x743E 琾 (<CJK Ideograph>) 8219 0x743F 琿 (<CJK Ideograph>) 8220 0x7440 瑀 (<CJK Ideograph>) 8221 0x7442 瑂 (<CJK Ideograph>) 8222 0x7443 瑃 (<CJK Ideograph>) 8223 0x7444 瑄 (<CJK Ideograph>) 8224 0x7445 瑅 (<CJK Ideograph>) 8225 0x7446 瑆 (<CJK Ideograph>) 8226 0x7447 瑇 (<CJK Ideograph>) 8227 0x7448 瑈 (<CJK Ideograph>) 8228 0x7449 瑉 (<CJK Ideograph>) 8229 0x744A 瑊 (<CJK Ideograph>) 8230 0x744B 瑋 (<CJK Ideograph>) 8231 0x744C 瑌 (<CJK Ideograph>) 8232 0x744D 瑍 (<CJK Ideograph>) 8233 0x744E 瑎 (<CJK Ideograph>) 8234 0x744F 瑏 (<CJK Ideograph>) 8235 0x7450 瑐 (<CJK Ideograph>) 8236 0x7451 瑑 (<CJK Ideograph>) 8237 0x7452 瑒 (<CJK Ideograph>) 8238 0x7453 瑓 (<CJK Ideograph>) 8239 0x7454 瑔 (<CJK Ideograph>) 8240 0x7456 瑖 (<CJK Ideograph>) 8241 0x7458 瑘 (<CJK Ideograph>) 8242 0x745D 瑝 (<CJK Ideograph>) 8243 0x7460 瑠 (<CJK Ideograph>) 8244 0x7461 瑡 (<CJK Ideograph>) 8245 0x7462 瑢 (<CJK Ideograph>) 8246 0x7463 瑣 (<CJK Ideograph>) 8247 0x7464 瑤 (<CJK Ideograph>) 8248 0x7465 瑥 (<CJK Ideograph>) 8249 0x7466 瑦 (<CJK Ideograph>) 8250 0x7467 瑧 (<CJK Ideograph>) 8251 0x7468 瑨 (<CJK Ideograph>) 8252 0x7469 瑩 (<CJK Ideograph>) 8253 0x746A 瑪 (<CJK Ideograph>) 8254 0x746B 瑫 (<CJK Ideograph>) 8255 0x746C 瑬 (<CJK Ideograph>) 8256 0x746E 瑮 (<CJK Ideograph>) 8257 0x746F 瑯 (<CJK Ideograph>) 8258 0x7471 瑱 (<CJK Ideograph>) 8259 0x7472 瑲 (<CJK Ideograph>) 8260 0x7473 瑳 (<CJK Ideograph>) 8261 0x7474 瑴 (<CJK Ideograph>) 8262 0x7475 瑵 (<CJK Ideograph>) 8263 0x7478 瑸 (<CJK Ideograph>) 8264 0x7479 瑹 (<CJK Ideograph>) 8265 0x747A 瑺 (<CJK Ideograph>) 8266 0xE0BC  (<Private Use>) 8267 0xE0BD  (<Private Use>) 8268 0xE0BE  (<Private Use>) 8269 0xE0BF  (<Private Use>) 8270 0xE0C0  (<Private Use>) 8271 0xE0C1  (<Private Use>) 8272 0xE0C2  (<Private Use>) 8273 0xE0C3  (<Private Use>) 8274 0xE0C4  (<Private Use>) 8275 0xE0C5  (<Private Use>) 8276 0xE0C6  (<Private Use>) 8277 0xE0C7  (<Private Use>) 8278 0xE0C8  (<Private Use>) 8279 0xE0C9  (<Private Use>) 8280 0xE0CA  (<Private Use>) 8281 0xE0CB  (<Private Use>) 8282 0xE0CC  (<Private Use>) 8283 0xE0CD  (<Private Use>) 8284 0xE0CE  (<Private Use>) 8285 0xE0CF  (<Private Use>) 8286 0xE0D0  (<Private Use>) 8287 0xE0D1  (<Private Use>) 8288 0xE0D2  (<Private Use>) 8289 0xE0D3  (<Private Use>) 8290 0xE0D4  (<Private Use>) 8291 0xE0D5  (<Private Use>) 8292 0xE0D6  (<Private Use>) 8293 0xE0D7  (<Private Use>) 8294 0xE0D8  (<Private Use>) 8295 0xE0D9  (<Private Use>) 8296 0xE0DA  (<Private Use>) 8297 0xE0DB  (<Private Use>) 8298 0xE0DC  (<Private Use>) 8299 0xE0DD  (<Private Use>) 8300 0xE0DE  (<Private Use>) 8301 0xE0DF  (<Private Use>) 8302 0xE0E0  (<Private Use>) 8303 0xE0E1  (<Private Use>) 8304 0xE0E2  (<Private Use>) 8305 0xE0E3  (<Private Use>) 8306 0xE0E4  (<Private Use>) 8307 0xE0E5  (<Private Use>) 8308 0xE0E6  (<Private Use>) 8309 0xE0E7  (<Private Use>) 8310 0xE0E8  (<Private Use>) 8311 0xE0E9  (<Private Use>) 8312 0xE0EA  (<Private Use>) 8313 0xE0EB  (<Private Use>) 8314 0xE0EC  (<Private Use>) 8315 0xE0ED  (<Private Use>) 8316 0xE0EE  (<Private Use>) 8317 0xE0EF  (<Private Use>) 8318 0xE0F0  (<Private Use>) 8319 0xE0F1  (<Private Use>) 8320 0xE0F2  (<Private Use>) 8321 0xE0F3  (<Private Use>) 8322 0xE0F4  (<Private Use>) 8323 0xE0F5  (<Private Use>) 8324 0xE0F6  (<Private Use>) 8325 0xE0F7  (<Private Use>) 8326 0xE0F8  (<Private Use>) 8327 0xE0F9  (<Private Use>) 8328 0xE0FA  (<Private Use>) 8329 0xE0FB  (<Private Use>) 8330 0xE0FC  (<Private Use>) 8331 0xE0FD  (<Private Use>) 8332 0xE0FE  (<Private Use>) 8333 0xE0FF  (<Private Use>) 8334 0xE100  (<Private Use>) 8335 0xE101  (<Private Use>) 8336 0xE102  (<Private Use>) 8337 0xE103  (<Private Use>) 8338 0xE104  (<Private Use>) 8339 0xE105  (<Private Use>) 8340 0xE106  (<Private Use>) 8341 0xE107  (<Private Use>) 8342 0xE108  (<Private Use>) 8343 0xE109  (<Private Use>) 8344 0xE10A  (<Private Use>) 8345 0xE10B  (<Private Use>) 8346 0xE10C  (<Private Use>) 8347 0xE10D  (<Private Use>) 8348 0xE10E  (<Private Use>) 8349 0xE10F  (<Private Use>) 8350 0xE110  (<Private Use>) 8351 0xE111  (<Private Use>) 8352 0xE112  (<Private Use>) 8353 0xE113  (<Private Use>) 8354 0xE114  (<Private Use>) 8355 0xE115  (<Private Use>) 8356 0xE116  (<Private Use>) 8357 0xE117  (<Private Use>) 8358 0xE118  (<Private Use>) 8359 0xE119  (<Private Use>) 8360 0x747B 瑻 (<CJK Ideograph>) 8361 0x747C 瑼 (<CJK Ideograph>) 8362 0x747D 瑽 (<CJK Ideograph>) 8363 0x747F 瑿 (<CJK Ideograph>) 8364 0x7482 璂 (<CJK Ideograph>) 8365 0x7484 璄 (<CJK Ideograph>) 8366 0x7485 璅 (<CJK Ideograph>) 8367 0x7486 璆 (<CJK Ideograph>) 8368 0x7488 璈 (<CJK Ideograph>) 8369 0x7489 璉 (<CJK Ideograph>) 8370 0x748A 璊 (<CJK Ideograph>) 8371 0x748C 璌 (<CJK Ideograph>) 8372 0x748D 璍 (<CJK Ideograph>) 8373 0x748F 璏 (<CJK Ideograph>) 8374 0x7491 璑 (<CJK Ideograph>) 8375 0x7492 璒 (<CJK Ideograph>) 8376 0x7493 璓 (<CJK Ideograph>) 8377 0x7494 璔 (<CJK Ideograph>) 8378 0x7495 璕 (<CJK Ideograph>) 8379 0x7496 璖 (<CJK Ideograph>) 8380 0x7497 璗 (<CJK Ideograph>) 8381 0x7498 璘 (<CJK Ideograph>) 8382 0x7499 璙 (<CJK Ideograph>) 8383 0x749A 璚 (<CJK Ideograph>) 8384 0x749B 璛 (<CJK Ideograph>) 8385 0x749D 璝 (<CJK Ideograph>) 8386 0x749F 璟 (<CJK Ideograph>) 8387 0x74A0 璠 (<CJK Ideograph>) 8388 0x74A1 璡 (<CJK Ideograph>) 8389 0x74A2 璢 (<CJK Ideograph>) 8390 0x74A3 璣 (<CJK Ideograph>) 8391 0x74A4 璤 (<CJK Ideograph>) 8392 0x74A5 璥 (<CJK Ideograph>) 8393 0x74A6 璦 (<CJK Ideograph>) 8394 0x74AA 璪 (<CJK Ideograph>) 8395 0x74AB 璫 (<CJK Ideograph>) 8396 0x74AC 璬 (<CJK Ideograph>) 8397 0x74AD 璭 (<CJK Ideograph>) 8398 0x74AE 璮 (<CJK Ideograph>) 8399 0x74AF 璯 (<CJK Ideograph>) 8400 0x74B0 環 (<CJK Ideograph>) 8401 0x74B1 璱 (<CJK Ideograph>) 8402 0x74B2 璲 (<CJK Ideograph>) 8403 0x74B3 璳 (<CJK Ideograph>) 8404 0x74B4 璴 (<CJK Ideograph>) 8405 0x74B5 璵 (<CJK Ideograph>) 8406 0x74B6 璶 (<CJK Ideograph>) 8407 0x74B7 璷 (<CJK Ideograph>) 8408 0x74B8 璸 (<CJK Ideograph>) 8409 0x74B9 璹 (<CJK Ideograph>) 8410 0x74BB 璻 (<CJK Ideograph>) 8411 0x74BC 璼 (<CJK Ideograph>) 8412 0x74BD 璽 (<CJK Ideograph>) 8413 0x74BE 璾 (<CJK Ideograph>) 8414 0x74BF 璿 (<CJK Ideograph>) 8415 0x74C0 瓀 (<CJK Ideograph>) 8416 0x74C1 瓁 (<CJK Ideograph>) 8417 0x74C2 瓂 (<CJK Ideograph>) 8418 0x74C3 瓃 (<CJK Ideograph>) 8419 0x74C4 瓄 (<CJK Ideograph>) 8420 0x74C5 瓅 (<CJK Ideograph>) 8421 0x74C6 瓆 (<CJK Ideograph>) 8422 0x74C7 瓇 (<CJK Ideograph>) 8423 0x74C8 瓈 (<CJK Ideograph>) 8424 0x74C9 瓉 (<CJK Ideograph>) 8425 0x74CA 瓊 (<CJK Ideograph>) 8426 0x74CB 瓋 (<CJK Ideograph>) 8427 0x74CC 瓌 (<CJK Ideograph>) 8428 0x74CD 瓍 (<CJK Ideograph>) 8429 0x74CE 瓎 (<CJK Ideograph>) 8430 0x74CF 瓏 (<CJK Ideograph>) 8431 0x74D0 瓐 (<CJK Ideograph>) 8432 0x74D1 瓑 (<CJK Ideograph>) 8433 0x74D3 瓓 (<CJK Ideograph>) 8434 0x74D4 瓔 (<CJK Ideograph>) 8435 0x74D5 瓕 (<CJK Ideograph>) 8436 0x74D6 瓖 (<CJK Ideograph>) 8437 0x74D7 瓗 (<CJK Ideograph>) 8438 0x74D8 瓘 (<CJK Ideograph>) 8439 0x74D9 瓙 (<CJK Ideograph>) 8440 0x74DA 瓚 (<CJK Ideograph>) 8441 0x74DB 瓛 (<CJK Ideograph>) 8442 0x74DD 瓝 (<CJK Ideograph>) 8443 0x74DF 瓟 (<CJK Ideograph>) 8444 0x74E1 瓡 (<CJK Ideograph>) 8445 0x74E5 瓥 (<CJK Ideograph>) 8446 0x74E7 瓧 (<CJK Ideograph>) 8447 0x74E8 瓨 (<CJK Ideograph>) 8448 0x74E9 瓩 (<CJK Ideograph>) 8449 0x74EA 瓪 (<CJK Ideograph>) 8450 0x74EB 瓫 (<CJK Ideograph>) 8451 0x74EC 瓬 (<CJK Ideograph>) 8452 0x74ED 瓭 (<CJK Ideograph>) 8453 0x74F0 瓰 (<CJK Ideograph>) 8454 0x74F1 瓱 (<CJK Ideograph>) 8455 0x74F2 瓲 (<CJK Ideograph>) 8456 0xE11A  (<Private Use>) 8457 0xE11B  (<Private Use>) 8458 0xE11C  (<Private Use>) 8459 0xE11D  (<Private Use>) 8460 0xE11E  (<Private Use>) 8461 0xE11F  (<Private Use>) 8462 0xE120  (<Private Use>) 8463 0xE121  (<Private Use>) 8464 0xE122  (<Private Use>) 8465 0xE123  (<Private Use>) 8466 0xE124  (<Private Use>) 8467 0xE125  (<Private Use>) 8468 0xE126  (<Private Use>) 8469 0xE127  (<Private Use>) 8470 0xE128  (<Private Use>) 8471 0xE129  (<Private Use>) 8472 0xE12A  (<Private Use>) 8473 0xE12B  (<Private Use>) 8474 0xE12C  (<Private Use>) 8475 0xE12D  (<Private Use>) 8476 0xE12E  (<Private Use>) 8477 0xE12F  (<Private Use>) 8478 0xE130  (<Private Use>) 8479 0xE131  (<Private Use>) 8480 0xE132  (<Private Use>) 8481 0xE133  (<Private Use>) 8482 0xE134  (<Private Use>) 8483 0xE135  (<Private Use>) 8484 0xE136  (<Private Use>) 8485 0xE137  (<Private Use>) 8486 0xE138  (<Private Use>) 8487 0xE139  (<Private Use>) 8488 0xE13A  (<Private Use>) 8489 0xE13B  (<Private Use>) 8490 0xE13C  (<Private Use>) 8491 0xE13D  (<Private Use>) 8492 0xE13E  (<Private Use>) 8493 0xE13F  (<Private Use>) 8494 0xE140  (<Private Use>) 8495 0xE141  (<Private Use>) 8496 0xE142  (<Private Use>) 8497 0xE143  (<Private Use>) 8498 0xE144  (<Private Use>) 8499 0xE145  (<Private Use>) 8500 0xE146  (<Private Use>) 8501 0xE147  (<Private Use>) 8502 0xE148  (<Private Use>) 8503 0xE149  (<Private Use>) 8504 0xE14A  (<Private Use>) 8505 0xE14B  (<Private Use>) 8506 0xE14C  (<Private Use>) 8507 0xE14D  (<Private Use>) 8508 0xE14E  (<Private Use>) 8509 0xE14F  (<Private Use>) 8510 0xE150  (<Private Use>) 8511 0xE151  (<Private Use>) 8512 0xE152  (<Private Use>) 8513 0xE153  (<Private Use>) 8514 0xE154  (<Private Use>) 8515 0xE155  (<Private Use>) 8516 0xE156  (<Private Use>) 8517 0xE157  (<Private Use>) 8518 0xE158  (<Private Use>) 8519 0xE159  (<Private Use>) 8520 0xE15A  (<Private Use>) 8521 0xE15B  (<Private Use>) 8522 0xE15C  (<Private Use>) 8523 0xE15D  (<Private Use>) 8524 0xE15E  (<Private Use>) 8525 0xE15F  (<Private Use>) 8526 0xE160  (<Private Use>) 8527 0xE161  (<Private Use>) 8528 0xE162  (<Private Use>) 8529 0xE163  (<Private Use>) 8530 0xE164  (<Private Use>) 8531 0xE165  (<Private Use>) 8532 0xE166  (<Private Use>) 8533 0xE167  (<Private Use>) 8534 0xE168  (<Private Use>) 8535 0xE169  (<Private Use>) 8536 0xE16A  (<Private Use>) 8537 0xE16B  (<Private Use>) 8538 0xE16C  (<Private Use>) 8539 0xE16D  (<Private Use>) 8540 0xE16E  (<Private Use>) 8541 0xE16F  (<Private Use>) 8542 0xE170  (<Private Use>) 8543 0xE171  (<Private Use>) 8544 0xE172  (<Private Use>) 8545 0xE173  (<Private Use>) 8546 0xE174  (<Private Use>) 8547 0xE175  (<Private Use>) 8548 0xE176  (<Private Use>) 8549 0xE177  (<Private Use>) 8550 0x74F3 瓳 (<CJK Ideograph>) 8551 0x74F5 瓵 (<CJK Ideograph>) 8552 0x74F8 瓸 (<CJK Ideograph>) 8553 0x74F9 瓹 (<CJK Ideograph>) 8554 0x74FA 瓺 (<CJK Ideograph>) 8555 0x74FB 瓻 (<CJK Ideograph>) 8556 0x74FC 瓼 (<CJK Ideograph>) 8557 0x74FD 瓽 (<CJK Ideograph>) 8558 0x74FE 瓾 (<CJK Ideograph>) 8559 0x7500 甀 (<CJK Ideograph>) 8560 0x7501 甁 (<CJK Ideograph>) 8561 0x7502 甂 (<CJK Ideograph>) 8562 0x7503 甃 (<CJK Ideograph>) 8563 0x7505 甅 (<CJK Ideograph>) 8564 0x7506 甆 (<CJK Ideograph>) 8565 0x7507 甇 (<CJK Ideograph>) 8566 0x7508 甈 (<CJK Ideograph>) 8567 0x7509 甉 (<CJK Ideograph>) 8568 0x750A 甊 (<CJK Ideograph>) 8569 0x750B 甋 (<CJK Ideograph>) 8570 0x750C 甌 (<CJK Ideograph>) 8571 0x750E 甎 (<CJK Ideograph>) 8572 0x7510 甐 (<CJK Ideograph>) 8573 0x7512 甒 (<CJK Ideograph>) 8574 0x7514 甔 (<CJK Ideograph>) 8575 0x7515 甕 (<CJK Ideograph>) 8576 0x7516 甖 (<CJK Ideograph>) 8577 0x7517 甗 (<CJK Ideograph>) 8578 0x751B 甛 (<CJK Ideograph>) 8579 0x751D 甝 (<CJK Ideograph>) 8580 0x751E 甞 (<CJK Ideograph>) 8581 0x7520 甠 (<CJK Ideograph>) 8582 0x7521 甡 (<CJK Ideograph>) 8583 0x7522 產 (<CJK Ideograph>) 8584 0x7523 産 (<CJK Ideograph>) 8585 0x7524 甤 (<CJK Ideograph>) 8586 0x7526 甦 (<CJK Ideograph>) 8587 0x7527 甧 (<CJK Ideograph>) 8588 0x752A 甪 (<CJK Ideograph>) 8589 0x752E 甮 (<CJK Ideograph>) 8590 0x7534 甴 (<CJK Ideograph>) 8591 0x7536 甶 (<CJK Ideograph>) 8592 0x7539 甹 (<CJK Ideograph>) 8593 0x753C 甼 (<CJK Ideograph>) 8594 0x753D 甽 (<CJK Ideograph>) 8595 0x753F 甿 (<CJK Ideograph>) 8596 0x7541 畁 (<CJK Ideograph>) 8597 0x7542 畂 (<CJK Ideograph>) 8598 0x7543 畃 (<CJK Ideograph>) 8599 0x7544 畄 (<CJK Ideograph>) 8600 0x7546 畆 (<CJK Ideograph>) 8601 0x7547 畇 (<CJK Ideograph>) 8602 0x7549 畉 (<CJK Ideograph>) 8603 0x754A 畊 (<CJK Ideograph>) 8604 0x754D 畍 (<CJK Ideograph>) 8605 0x7550 畐 (<CJK Ideograph>) 8606 0x7551 畑 (<CJK Ideograph>) 8607 0x7552 畒 (<CJK Ideograph>) 8608 0x7553 畓 (<CJK Ideograph>) 8609 0x7555 畕 (<CJK Ideograph>) 8610 0x7556 畖 (<CJK Ideograph>) 8611 0x7557 畗 (<CJK Ideograph>) 8612 0x7558 畘 (<CJK Ideograph>) 8613 0x755D 畝 (<CJK Ideograph>) 8614 0x755E 畞 (<CJK Ideograph>) 8615 0x755F 畟 (<CJK Ideograph>) 8616 0x7560 畠 (<CJK Ideograph>) 8617 0x7561 畡 (<CJK Ideograph>) 8618 0x7562 畢 (<CJK Ideograph>) 8619 0x7563 畣 (<CJK Ideograph>) 8620 0x7564 畤 (<CJK Ideograph>) 8621 0x7567 畧 (<CJK Ideograph>) 8622 0x7568 畨 (<CJK Ideograph>) 8623 0x7569 畩 (<CJK Ideograph>) 8624 0x756B 畫 (<CJK Ideograph>) 8625 0x756C 畬 (<CJK Ideograph>) 8626 0x756D 畭 (<CJK Ideograph>) 8627 0x756E 畮 (<CJK Ideograph>) 8628 0x756F 畯 (<CJK Ideograph>) 8629 0x7570 異 (<CJK Ideograph>) 8630 0x7571 畱 (<CJK Ideograph>) 8631 0x7573 畳 (<CJK Ideograph>) 8632 0x7575 畵 (<CJK Ideograph>) 8633 0x7576 當 (<CJK Ideograph>) 8634 0x7577 畷 (<CJK Ideograph>) 8635 0x757A 畺 (<CJK Ideograph>) 8636 0x757B 畻 (<CJK Ideograph>) 8637 0x757C 畼 (<CJK Ideograph>) 8638 0x757D 畽 (<CJK Ideograph>) 8639 0x757E 畾 (<CJK Ideograph>) 8640 0x7580 疀 (<CJK Ideograph>) 8641 0x7581 疁 (<CJK Ideograph>) 8642 0x7582 疂 (<CJK Ideograph>) 8643 0x7584 疄 (<CJK Ideograph>) 8644 0x7585 疅 (<CJK Ideograph>) 8645 0x7587 疇 (<CJK Ideograph>) 8646 0xE178  (<Private Use>) 8647 0xE179  (<Private Use>) 8648 0xE17A  (<Private Use>) 8649 0xE17B  (<Private Use>) 8650 0xE17C  (<Private Use>) 8651 0xE17D  (<Private Use>) 8652 0xE17E  (<Private Use>) 8653 0xE17F  (<Private Use>) 8654 0xE180  (<Private Use>) 8655 0xE181  (<Private Use>) 8656 0xE182  (<Private Use>) 8657 0xE183  (<Private Use>) 8658 0xE184  (<Private Use>) 8659 0xE185  (<Private Use>) 8660 0xE186  (<Private Use>) 8661 0xE187  (<Private Use>) 8662 0xE188  (<Private Use>) 8663 0xE189  (<Private Use>) 8664 0xE18A  (<Private Use>) 8665 0xE18B  (<Private Use>) 8666 0xE18C  (<Private Use>) 8667 0xE18D  (<Private Use>) 8668 0xE18E  (<Private Use>) 8669 0xE18F  (<Private Use>) 8670 0xE190  (<Private Use>) 8671 0xE191  (<Private Use>) 8672 0xE192  (<Private Use>) 8673 0xE193  (<Private Use>) 8674 0xE194  (<Private Use>) 8675 0xE195  (<Private Use>) 8676 0xE196  (<Private Use>) 8677 0xE197  (<Private Use>) 8678 0xE198  (<Private Use>) 8679 0xE199  (<Private Use>) 8680 0xE19A  (<Private Use>) 8681 0xE19B  (<Private Use>) 8682 0xE19C  (<Private Use>) 8683 0xE19D  (<Private Use>) 8684 0xE19E  (<Private Use>) 8685 0xE19F  (<Private Use>) 8686 0xE1A0  (<Private Use>) 8687 0xE1A1  (<Private Use>) 8688 0xE1A2  (<Private Use>) 8689 0xE1A3  (<Private Use>) 8690 0xE1A4  (<Private Use>) 8691 0xE1A5  (<Private Use>) 8692 0xE1A6  (<Private Use>) 8693 0xE1A7  (<Private Use>) 8694 0xE1A8  (<Private Use>) 8695 0xE1A9  (<Private Use>) 8696 0xE1AA  (<Private Use>) 8697 0xE1AB  (<Private Use>) 8698 0xE1AC  (<Private Use>) 8699 0xE1AD  (<Private Use>) 8700 0xE1AE  (<Private Use>) 8701 0xE1AF  (<Private Use>) 8702 0xE1B0  (<Private Use>) 8703 0xE1B1  (<Private Use>) 8704 0xE1B2  (<Private Use>) 8705 0xE1B3  (<Private Use>) 8706 0xE1B4  (<Private Use>) 8707 0xE1B5  (<Private Use>) 8708 0xE1B6  (<Private Use>) 8709 0xE1B7  (<Private Use>) 8710 0xE1B8  (<Private Use>) 8711 0xE1B9  (<Private Use>) 8712 0xE1BA  (<Private Use>) 8713 0xE1BB  (<Private Use>) 8714 0xE1BC  (<Private Use>) 8715 0xE1BD  (<Private Use>) 8716 0xE1BE  (<Private Use>) 8717 0xE1BF  (<Private Use>) 8718 0xE1C0  (<Private Use>) 8719 0xE1C1  (<Private Use>) 8720 0xE1C2  (<Private Use>) 8721 0xE1C3  (<Private Use>) 8722 0xE1C4  (<Private Use>) 8723 0xE1C5  (<Private Use>) 8724 0xE1C6  (<Private Use>) 8725 0xE1C7  (<Private Use>) 8726 0xE1C8  (<Private Use>) 8727 0xE1C9  (<Private Use>) 8728 0xE1CA  (<Private Use>) 8729 0xE1CB  (<Private Use>) 8730 0xE1CC  (<Private Use>) 8731 0xE1CD  (<Private Use>) 8732 0xE1CE  (<Private Use>) 8733 0xE1CF  (<Private Use>) 8734 0xE1D0  (<Private Use>) 8735 0xE1D1  (<Private Use>) 8736 0xE1D2  (<Private Use>) 8737 0xE1D3  (<Private Use>) 8738 0xE1D4  (<Private Use>) 8739 0xE1D5  (<Private Use>) 8740 0x7588 疈 (<CJK Ideograph>) 8741 0x7589 疉 (<CJK Ideograph>) 8742 0x758A 疊 (<CJK Ideograph>) 8743 0x758C 疌 (<CJK Ideograph>) 8744 0x758D 疍 (<CJK Ideograph>) 8745 0x758E 疎 (<CJK Ideograph>) 8746 0x7590 疐 (<CJK Ideograph>) 8747 0x7593 疓 (<CJK Ideograph>) 8748 0x7595 疕 (<CJK Ideograph>) 8749 0x7598 疘 (<CJK Ideograph>) 8750 0x759B 疛 (<CJK Ideograph>) 8751 0x759C 疜 (<CJK Ideograph>) 8752 0x759E 疞 (<CJK Ideograph>) 8753 0x75A2 疢 (<CJK Ideograph>) 8754 0x75A6 疦 (<CJK Ideograph>) 8755 0x75A7 疧 (<CJK Ideograph>) 8756 0x75A8 疨 (<CJK Ideograph>) 8757 0x75A9 疩 (<CJK Ideograph>) 8758 0x75AA 疪 (<CJK Ideograph>) 8759 0x75AD 疭 (<CJK Ideograph>) 8760 0x75B6 疶 (<CJK Ideograph>) 8761 0x75B7 疷 (<CJK Ideograph>) 8762 0x75BA 疺 (<CJK Ideograph>) 8763 0x75BB 疻 (<CJK Ideograph>) 8764 0x75BF 疿 (<CJK Ideograph>) 8765 0x75C0 痀 (<CJK Ideograph>) 8766 0x75C1 痁 (<CJK Ideograph>) 8767 0x75C6 痆 (<CJK Ideograph>) 8768 0x75CB 痋 (<CJK Ideograph>) 8769 0x75CC 痌 (<CJK Ideograph>) 8770 0x75CE 痎 (<CJK Ideograph>) 8771 0x75CF 痏 (<CJK Ideograph>) 8772 0x75D0 痐 (<CJK Ideograph>) 8773 0x75D1 痑 (<CJK Ideograph>) 8774 0x75D3 痓 (<CJK Ideograph>) 8775 0x75D7 痗 (<CJK Ideograph>) 8776 0x75D9 痙 (<CJK Ideograph>) 8777 0x75DA 痚 (<CJK Ideograph>) 8778 0x75DC 痜 (<CJK Ideograph>) 8779 0x75DD 痝 (<CJK Ideograph>) 8780 0x75DF 痟 (<CJK Ideograph>) 8781 0x75E0 痠 (<CJK Ideograph>) 8782 0x75E1 痡 (<CJK Ideograph>) 8783 0x75E5 痥 (<CJK Ideograph>) 8784 0x75E9 痩 (<CJK Ideograph>) 8785 0x75EC 痬 (<CJK Ideograph>) 8786 0x75ED 痭 (<CJK Ideograph>) 8787 0x75EE 痮 (<CJK Ideograph>) 8788 0x75EF 痯 (<CJK Ideograph>) 8789 0x75F2 痲 (<CJK Ideograph>) 8790 0x75F3 痳 (<CJK Ideograph>) 8791 0x75F5 痵 (<CJK Ideograph>) 8792 0x75F6 痶 (<CJK Ideograph>) 8793 0x75F7 痷 (<CJK Ideograph>) 8794 0x75F8 痸 (<CJK Ideograph>) 8795 0x75FA 痺 (<CJK Ideograph>) 8796 0x75FB 痻 (<CJK Ideograph>) 8797 0x75FD 痽 (<CJK Ideograph>) 8798 0x75FE 痾 (<CJK Ideograph>) 8799 0x7602 瘂 (<CJK Ideograph>) 8800 0x7604 瘄 (<CJK Ideograph>) 8801 0x7606 瘆 (<CJK Ideograph>) 8802 0x7607 瘇 (<CJK Ideograph>) 8803 0x7608 瘈 (<CJK Ideograph>) 8804 0x7609 瘉 (<CJK Ideograph>) 8805 0x760B 瘋 (<CJK Ideograph>) 8806 0x760D 瘍 (<CJK Ideograph>) 8807 0x760E 瘎 (<CJK Ideograph>) 8808 0x760F 瘏 (<CJK Ideograph>) 8809 0x7611 瘑 (<CJK Ideograph>) 8810 0x7612 瘒 (<CJK Ideograph>) 8811 0x7613 瘓 (<CJK Ideograph>) 8812 0x7614 瘔 (<CJK Ideograph>) 8813 0x7616 瘖 (<CJK Ideograph>) 8814 0x761A 瘚 (<CJK Ideograph>) 8815 0x761C 瘜 (<CJK Ideograph>) 8816 0x761D 瘝 (<CJK Ideograph>) 8817 0x761E 瘞 (<CJK Ideograph>) 8818 0x7621 瘡 (<CJK Ideograph>) 8819 0x7623 瘣 (<CJK Ideograph>) 8820 0x7627 瘧 (<CJK Ideograph>) 8821 0x7628 瘨 (<CJK Ideograph>) 8822 0x762C 瘬 (<CJK Ideograph>) 8823 0x762E 瘮 (<CJK Ideograph>) 8824 0x762F 瘯 (<CJK Ideograph>) 8825 0x7631 瘱 (<CJK Ideograph>) 8826 0x7632 瘲 (<CJK Ideograph>) 8827 0x7636 瘶 (<CJK Ideograph>) 8828 0x7637 瘷 (<CJK Ideograph>) 8829 0x7639 瘹 (<CJK Ideograph>) 8830 0x763A 瘺 (<CJK Ideograph>) 8831 0x763B 瘻 (<CJK Ideograph>) 8832 0x763D 瘽 (<CJK Ideograph>) 8833 0x7641 癁 (<CJK Ideograph>) 8834 0x7642 療 (<CJK Ideograph>) 8835 0x7644 癄 (<CJK Ideograph>) 8836 0xE1D6  (<Private Use>) 8837 0xE1D7  (<Private Use>) 8838 0xE1D8  (<Private Use>) 8839 0xE1D9  (<Private Use>) 8840 0xE1DA  (<Private Use>) 8841 0xE1DB  (<Private Use>) 8842 0xE1DC  (<Private Use>) 8843 0xE1DD  (<Private Use>) 8844 0xE1DE  (<Private Use>) 8845 0xE1DF  (<Private Use>) 8846 0xE1E0  (<Private Use>) 8847 0xE1E1  (<Private Use>) 8848 0xE1E2  (<Private Use>) 8849 0xE1E3  (<Private Use>) 8850 0xE1E4  (<Private Use>) 8851 0xE1E5  (<Private Use>) 8852 0xE1E6  (<Private Use>) 8853 0xE1E7  (<Private Use>) 8854 0xE1E8  (<Private Use>) 8855 0xE1E9  (<Private Use>) 8856 0xE1EA  (<Private Use>) 8857 0xE1EB  (<Private Use>) 8858 0xE1EC  (<Private Use>) 8859 0xE1ED  (<Private Use>) 8860 0xE1EE  (<Private Use>) 8861 0xE1EF  (<Private Use>) 8862 0xE1F0  (<Private Use>) 8863 0xE1F1  (<Private Use>) 8864 0xE1F2  (<Private Use>) 8865 0xE1F3  (<Private Use>) 8866 0xE1F4  (<Private Use>) 8867 0xE1F5  (<Private Use>) 8868 0xE1F6  (<Private Use>) 8869 0xE1F7  (<Private Use>) 8870 0xE1F8  (<Private Use>) 8871 0xE1F9  (<Private Use>) 8872 0xE1FA  (<Private Use>) 8873 0xE1FB  (<Private Use>) 8874 0xE1FC  (<Private Use>) 8875 0xE1FD  (<Private Use>) 8876 0xE1FE  (<Private Use>) 8877 0xE1FF  (<Private Use>) 8878 0xE200  (<Private Use>) 8879 0xE201  (<Private Use>) 8880 0xE202  (<Private Use>) 8881 0xE203  (<Private Use>) 8882 0xE204  (<Private Use>) 8883 0xE205  (<Private Use>) 8884 0xE206  (<Private Use>) 8885 0xE207  (<Private Use>) 8886 0xE208  (<Private Use>) 8887 0xE209  (<Private Use>) 8888 0xE20A  (<Private Use>) 8889 0xE20B  (<Private Use>) 8890 0xE20C  (<Private Use>) 8891 0xE20D  (<Private Use>) 8892 0xE20E  (<Private Use>) 8893 0xE20F  (<Private Use>) 8894 0xE210  (<Private Use>) 8895 0xE211  (<Private Use>) 8896 0xE212  (<Private Use>) 8897 0xE213  (<Private Use>) 8898 0xE214  (<Private Use>) 8899 0xE215  (<Private Use>) 8900 0xE216  (<Private Use>) 8901 0xE217  (<Private Use>) 8902 0xE218  (<Private Use>) 8903 0xE219  (<Private Use>) 8904 0xE21A  (<Private Use>) 8905 0xE21B  (<Private Use>) 8906 0xE21C  (<Private Use>) 8907 0xE21D  (<Private Use>) 8908 0xE21E  (<Private Use>) 8909 0xE21F  (<Private Use>) 8910 0xE220  (<Private Use>) 8911 0xE221  (<Private Use>) 8912 0xE222  (<Private Use>) 8913 0xE223  (<Private Use>) 8914 0xE224  (<Private Use>) 8915 0xE225  (<Private Use>) 8916 0xE226  (<Private Use>) 8917 0xE227  (<Private Use>) 8918 0xE228  (<Private Use>) 8919 0xE229  (<Private Use>) 8920 0xE22A  (<Private Use>) 8921 0xE22B  (<Private Use>) 8922 0xE22C  (<Private Use>) 8923 0xE22D  (<Private Use>) 8924 0xE22E  (<Private Use>) 8925 0xE22F  (<Private Use>) 8926 0xE230  (<Private Use>) 8927 0xE231  (<Private Use>) 8928 0xE232  (<Private Use>) 8929 0xE233  (<Private Use>) 8930 0x7645 癅 (<CJK Ideograph>) 8931 0x7646 癆 (<CJK Ideograph>) 8932 0x7647 癇 (<CJK Ideograph>) 8933 0x7648 癈 (<CJK Ideograph>) 8934 0x7649 癉 (<CJK Ideograph>) 8935 0x764A 癊 (<CJK Ideograph>) 8936 0x764B 癋 (<CJK Ideograph>) 8937 0x764E 癎 (<CJK Ideograph>) 8938 0x764F 癏 (<CJK Ideograph>) 8939 0x7650 癐 (<CJK Ideograph>) 8940 0x7651 癑 (<CJK Ideograph>) 8941 0x7652 癒 (<CJK Ideograph>) 8942 0x7653 癓 (<CJK Ideograph>) 8943 0x7655 癕 (<CJK Ideograph>) 8944 0x7657 癗 (<CJK Ideograph>) 8945 0x7658 癘 (<CJK Ideograph>) 8946 0x7659 癙 (<CJK Ideograph>) 8947 0x765A 癚 (<CJK Ideograph>) 8948 0x765B 癛 (<CJK Ideograph>) 8949 0x765D 癝 (<CJK Ideograph>) 8950 0x765F 癟 (<CJK Ideograph>) 8951 0x7660 癠 (<CJK Ideograph>) 8952 0x7661 癡 (<CJK Ideograph>) 8953 0x7662 癢 (<CJK Ideograph>) 8954 0x7664 癤 (<CJK Ideograph>) 8955 0x7665 癥 (<CJK Ideograph>) 8956 0x7666 癦 (<CJK Ideograph>) 8957 0x7667 癧 (<CJK Ideograph>) 8958 0x7668 癨 (<CJK Ideograph>) 8959 0x7669 癩 (<CJK Ideograph>) 8960 0x766A 癪 (<CJK Ideograph>) 8961 0x766C 癬 (<CJK Ideograph>) 8962 0x766D 癭 (<CJK Ideograph>) 8963 0x766E 癮 (<CJK Ideograph>) 8964 0x7670 癰 (<CJK Ideograph>) 8965 0x7671 癱 (<CJK Ideograph>) 8966 0x7672 癲 (<CJK Ideograph>) 8967 0x7673 癳 (<CJK Ideograph>) 8968 0x7674 癴 (<CJK Ideograph>) 8969 0x7675 癵 (<CJK Ideograph>) 8970 0x7676 癶 (<CJK Ideograph>) 8971 0x7677 癷 (<CJK Ideograph>) 8972 0x7679 癹 (<CJK Ideograph>) 8973 0x767A 発 (<CJK Ideograph>) 8974 0x767C 發 (<CJK Ideograph>) 8975 0x767F 癿 (<CJK Ideograph>) 8976 0x7680 皀 (<CJK Ideograph>) 8977 0x7681 皁 (<CJK Ideograph>) 8978 0x7683 皃 (<CJK Ideograph>) 8979 0x7685 皅 (<CJK Ideograph>) 8980 0x7689 皉 (<CJK Ideograph>) 8981 0x768A 皊 (<CJK Ideograph>) 8982 0x768C 皌 (<CJK Ideograph>) 8983 0x768D 皍 (<CJK Ideograph>) 8984 0x768F 皏 (<CJK Ideograph>) 8985 0x7690 皐 (<CJK Ideograph>) 8986 0x7692 皒 (<CJK Ideograph>) 8987 0x7694 皔 (<CJK Ideograph>) 8988 0x7695 皕 (<CJK Ideograph>) 8989 0x7697 皗 (<CJK Ideograph>) 8990 0x7698 皘 (<CJK Ideograph>) 8991 0x769A 皚 (<CJK Ideograph>) 8992 0x769B 皛 (<CJK Ideograph>) 8993 0x769C 皜 (<CJK Ideograph>) 8994 0x769D 皝 (<CJK Ideograph>) 8995 0x769E 皞 (<CJK Ideograph>) 8996 0x769F 皟 (<CJK Ideograph>) 8997 0x76A0 皠 (<CJK Ideograph>) 8998 0x76A1 皡 (<CJK Ideograph>) 8999 0x76A2 皢 (<CJK Ideograph>) 9000 0x76A3 皣 (<CJK Ideograph>) 9001 0x76A5 皥 (<CJK Ideograph>) 9002 0x76A6 皦 (<CJK Ideograph>) 9003 0x76A7 皧 (<CJK Ideograph>) 9004 0x76A8 皨 (<CJK Ideograph>) 9005 0x76A9 皩 (<CJK Ideograph>) 9006 0x76AA 皪 (<CJK Ideograph>) 9007 0x76AB 皫 (<CJK Ideograph>) 9008 0x76AC 皬 (<CJK Ideograph>) 9009 0x76AD 皭 (<CJK Ideograph>) 9010 0x76AF 皯 (<CJK Ideograph>) 9011 0x76B0 皰 (<CJK Ideograph>) 9012 0x76B3 皳 (<CJK Ideograph>) 9013 0x76B5 皵 (<CJK Ideograph>) 9014 0x76B6 皶 (<CJK Ideograph>) 9015 0x76B7 皷 (<CJK Ideograph>) 9016 0x76B8 皸 (<CJK Ideograph>) 9017 0x76B9 皹 (<CJK Ideograph>) 9018 0x76BA 皺 (<CJK Ideograph>) 9019 0x76BB 皻 (<CJK Ideograph>) 9020 0x76BC 皼 (<CJK Ideograph>) 9021 0x76BD 皽 (<CJK Ideograph>) 9022 0x76BE 皾 (<CJK Ideograph>) 9023 0x76C0 盀 (<CJK Ideograph>) 9024 0x76C1 盁 (<CJK Ideograph>) 9025 0x76C3 盃 (<CJK Ideograph>) 9026 0x554A 啊 (<CJK Ideograph>) 9027 0x963F 阿 (<CJK Ideograph>) 9028 0x57C3 埃 (<CJK Ideograph>) 9029 0x6328 挨 (<CJK Ideograph>) 9030 0x54CE 哎 (<CJK Ideograph>) 9031 0x5509 唉 (<CJK Ideograph>) 9032 0x54C0 哀 (<CJK Ideograph>) 9033 0x7691 皑 (<CJK Ideograph>) 9034 0x764C 癌 (<CJK Ideograph>) 9035 0x853C 蔼 (<CJK Ideograph>) 9036 0x77EE 矮 (<CJK Ideograph>) 9037 0x827E 艾 (<CJK Ideograph>) 9038 0x788D 碍 (<CJK Ideograph>) 9039 0x7231 爱 (<CJK Ideograph>) 9040 0x9698 隘 (<CJK Ideograph>) 9041 0x978D 鞍 (<CJK Ideograph>) 9042 0x6C28 氨 (<CJK Ideograph>) 9043 0x5B89 安 (<CJK Ideograph>) 9044 0x4FFA 俺 (<CJK Ideograph>) 9045 0x6309 按 (<CJK Ideograph>) 9046 0x6697 暗 (<CJK Ideograph>) 9047 0x5CB8 岸 (<CJK Ideograph>) 9048 0x80FA 胺 (<CJK Ideograph>) 9049 0x6848 案 (<CJK Ideograph>) 9050 0x80AE 肮 (<CJK Ideograph>) 9051 0x6602 昂 (<CJK Ideograph>) 9052 0x76CE 盎 (<CJK Ideograph>) 9053 0x51F9 凹 (<CJK Ideograph>) 9054 0x6556 敖 (<CJK Ideograph>) 9055 0x71AC 熬 (<CJK Ideograph>) 9056 0x7FF1 翱 (<CJK Ideograph>) 9057 0x8884 袄 (<CJK Ideograph>) 9058 0x50B2 傲 (<CJK Ideograph>) 9059 0x5965 奥 (<CJK Ideograph>) 9060 0x61CA 懊 (<CJK Ideograph>) 9061 0x6FB3 澳 (<CJK Ideograph>) 9062 0x82AD 芭 (<CJK Ideograph>) 9063 0x634C 捌 (<CJK Ideograph>) 9064 0x6252 扒 (<CJK Ideograph>) 9065 0x53ED 叭 (<CJK Ideograph>) 9066 0x5427 吧 (<CJK Ideograph>) 9067 0x7B06 笆 (<CJK Ideograph>) 9068 0x516B 八 (<CJK Ideograph>) 9069 0x75A4 疤 (<CJK Ideograph>) 9070 0x5DF4 巴 (<CJK Ideograph>) 9071 0x62D4 拔 (<CJK Ideograph>) 9072 0x8DCB 跋 (<CJK Ideograph>) 9073 0x9776 靶 (<CJK Ideograph>) 9074 0x628A 把 (<CJK Ideograph>) 9075 0x8019 耙 (<CJK Ideograph>) 9076 0x575D 坝 (<CJK Ideograph>) 9077 0x9738 霸 (<CJK Ideograph>) 9078 0x7F62 罢 (<CJK Ideograph>) 9079 0x7238 爸 (<CJK Ideograph>) 9080 0x767D 白 (<CJK Ideograph>) 9081 0x67CF 柏 (<CJK Ideograph>) 9082 0x767E 百 (<CJK Ideograph>) 9083 0x6446 摆 (<CJK Ideograph>) 9084 0x4F70 佰 (<CJK Ideograph>) 9085 0x8D25 败 (<CJK Ideograph>) 9086 0x62DC 拜 (<CJK Ideograph>) 9087 0x7A17 稗 (<CJK Ideograph>) 9088 0x6591 斑 (<CJK Ideograph>) 9089 0x73ED 班 (<CJK Ideograph>) 9090 0x642C 搬 (<CJK Ideograph>) 9091 0x6273 扳 (<CJK Ideograph>) 9092 0x822C 般 (<CJK Ideograph>) 9093 0x9881 颁 (<CJK Ideograph>) 9094 0x677F 板 (<CJK Ideograph>) 9095 0x7248 版 (<CJK Ideograph>) 9096 0x626E 扮 (<CJK Ideograph>) 9097 0x62CC 拌 (<CJK Ideograph>) 9098 0x4F34 伴 (<CJK Ideograph>) 9099 0x74E3 瓣 (<CJK Ideograph>) 9100 0x534A 半 (<CJK Ideograph>) 9101 0x529E 办 (<CJK Ideograph>) 9102 0x7ECA 绊 (<CJK Ideograph>) 9103 0x90A6 邦 (<CJK Ideograph>) 9104 0x5E2E 帮 (<CJK Ideograph>) 9105 0x6886 梆 (<CJK Ideograph>) 9106 0x699C 榜 (<CJK Ideograph>) 9107 0x8180 膀 (<CJK Ideograph>) 9108 0x7ED1 绑 (<CJK Ideograph>) 9109 0x68D2 棒 (<CJK Ideograph>) 9110 0x78C5 磅 (<CJK Ideograph>) 9111 0x868C 蚌 (<CJK Ideograph>) 9112 0x9551 镑 (<CJK Ideograph>) 9113 0x508D 傍 (<CJK Ideograph>) 9114 0x8C24 谤 (<CJK Ideograph>) 9115 0x82DE 苞 (<CJK Ideograph>) 9116 0x80DE 胞 (<CJK Ideograph>) 9117 0x5305 包 (<CJK Ideograph>) 9118 0x8912 褒 (<CJK Ideograph>) 9119 0x5265 剥 (<CJK Ideograph>) 9120 0x76C4 盄 (<CJK Ideograph>) 9121 0x76C7 盇 (<CJK Ideograph>) 9122 0x76C9 盉 (<CJK Ideograph>) 9123 0x76CB 盋 (<CJK Ideograph>) 9124 0x76CC 盌 (<CJK Ideograph>) 9125 0x76D3 盓 (<CJK Ideograph>) 9126 0x76D5 盕 (<CJK Ideograph>) 9127 0x76D9 盙 (<CJK Ideograph>) 9128 0x76DA 盚 (<CJK Ideograph>) 9129 0x76DC 盜 (<CJK Ideograph>) 9130 0x76DD 盝 (<CJK Ideograph>) 9131 0x76DE 盞 (<CJK Ideograph>) 9132 0x76E0 盠 (<CJK Ideograph>) 9133 0x76E1 盡 (<CJK Ideograph>) 9134 0x76E2 盢 (<CJK Ideograph>) 9135 0x76E3 監 (<CJK Ideograph>) 9136 0x76E4 盤 (<CJK Ideograph>) 9137 0x76E6 盦 (<CJK Ideograph>) 9138 0x76E7 盧 (<CJK Ideograph>) 9139 0x76E8 盨 (<CJK Ideograph>) 9140 0x76E9 盩 (<CJK Ideograph>) 9141 0x76EA 盪 (<CJK Ideograph>) 9142 0x76EB 盫 (<CJK Ideograph>) 9143 0x76EC 盬 (<CJK Ideograph>) 9144 0x76ED 盭 (<CJK Ideograph>) 9145 0x76F0 盰 (<CJK Ideograph>) 9146 0x76F3 盳 (<CJK Ideograph>) 9147 0x76F5 盵 (<CJK Ideograph>) 9148 0x76F6 盶 (<CJK Ideograph>) 9149 0x76F7 盷 (<CJK Ideograph>) 9150 0x76FA 盺 (<CJK Ideograph>) 9151 0x76FB 盻 (<CJK Ideograph>) 9152 0x76FD 盽 (<CJK Ideograph>) 9153 0x76FF 盿 (<CJK Ideograph>) 9154 0x7700 眀 (<CJK Ideograph>) 9155 0x7702 眂 (<CJK Ideograph>) 9156 0x7703 眃 (<CJK Ideograph>) 9157 0x7705 眅 (<CJK Ideograph>) 9158 0x7706 眆 (<CJK Ideograph>) 9159 0x770A 眊 (<CJK Ideograph>) 9160 0x770C 県 (<CJK Ideograph>) 9161 0x770E 眎 (<CJK Ideograph>) 9162 0x770F 眏 (<CJK Ideograph>) 9163 0x7710 眐 (<CJK Ideograph>) 9164 0x7711 眑 (<CJK Ideograph>) 9165 0x7712 眒 (<CJK Ideograph>) 9166 0x7713 眓 (<CJK Ideograph>) 9167 0x7714 眔 (<CJK Ideograph>) 9168 0x7715 眕 (<CJK Ideograph>) 9169 0x7716 眖 (<CJK Ideograph>) 9170 0x7717 眗 (<CJK Ideograph>) 9171 0x7718 眘 (<CJK Ideograph>) 9172 0x771B 眛 (<CJK Ideograph>) 9173 0x771C 眜 (<CJK Ideograph>) 9174 0x771D 眝 (<CJK Ideograph>) 9175 0x771E 眞 (<CJK Ideograph>) 9176 0x7721 眡 (<CJK Ideograph>) 9177 0x7723 眣 (<CJK Ideograph>) 9178 0x7724 眤 (<CJK Ideograph>) 9179 0x7725 眥 (<CJK Ideograph>) 9180 0x7727 眧 (<CJK Ideograph>) 9181 0x772A 眪 (<CJK Ideograph>) 9182 0x772B 眫 (<CJK Ideograph>) 9183 0x772C 眬 (<CJK Ideograph>) 9184 0x772E 眮 (<CJK Ideograph>) 9185 0x7730 眰 (<CJK Ideograph>) 9186 0x7731 眱 (<CJK Ideograph>) 9187 0x7732 眲 (<CJK Ideograph>) 9188 0x7733 眳 (<CJK Ideograph>) 9189 0x7734 眴 (<CJK Ideograph>) 9190 0x7739 眹 (<CJK Ideograph>) 9191 0x773B 眻 (<CJK Ideograph>) 9192 0x773D 眽 (<CJK Ideograph>) 9193 0x773E 眾 (<CJK Ideograph>) 9194 0x773F 眿 (<CJK Ideograph>) 9195 0x7742 睂 (<CJK Ideograph>) 9196 0x7744 睄 (<CJK Ideograph>) 9197 0x7745 睅 (<CJK Ideograph>) 9198 0x7746 睆 (<CJK Ideograph>) 9199 0x7748 睈 (<CJK Ideograph>) 9200 0x7749 睉 (<CJK Ideograph>) 9201 0x774A 睊 (<CJK Ideograph>) 9202 0x774B 睋 (<CJK Ideograph>) 9203 0x774C 睌 (<CJK Ideograph>) 9204 0x774D 睍 (<CJK Ideograph>) 9205 0x774E 睎 (<CJK Ideograph>) 9206 0x774F 睏 (<CJK Ideograph>) 9207 0x7752 睒 (<CJK Ideograph>) 9208 0x7753 睓 (<CJK Ideograph>) 9209 0x7754 睔 (<CJK Ideograph>) 9210 0x7755 睕 (<CJK Ideograph>) 9211 0x7756 睖 (<CJK Ideograph>) 9212 0x7757 睗 (<CJK Ideograph>) 9213 0x7758 睘 (<CJK Ideograph>) 9214 0x7759 睙 (<CJK Ideograph>) 9215 0x775C 睜 (<CJK Ideograph>) 9216 0x8584 薄 (<CJK Ideograph>) 9217 0x96F9 雹 (<CJK Ideograph>) 9218 0x4FDD 保 (<CJK Ideograph>) 9219 0x5821 堡 (<CJK Ideograph>) 9220 0x9971 饱 (<CJK Ideograph>) 9221 0x5B9D 宝 (<CJK Ideograph>) 9222 0x62B1 抱 (<CJK Ideograph>) 9223 0x62A5 报 (<CJK Ideograph>) 9224 0x66B4 暴 (<CJK Ideograph>) 9225 0x8C79 豹 (<CJK Ideograph>) 9226 0x9C8D 鲍 (<CJK Ideograph>) 9227 0x7206 爆 (<CJK Ideograph>) 9228 0x676F 杯 (<CJK Ideograph>) 9229 0x7891 碑 (<CJK Ideograph>) 9230 0x60B2 悲 (<CJK Ideograph>) 9231 0x5351 卑 (<CJK Ideograph>) 9232 0x5317 北 (<CJK Ideograph>) 9233 0x8F88 辈 (<CJK Ideograph>) 9234 0x80CC 背 (<CJK Ideograph>) 9235 0x8D1D 贝 (<CJK Ideograph>) 9236 0x94A1 钡 (<CJK Ideograph>) 9237 0x500D 倍 (<CJK Ideograph>) 9238 0x72C8 狈 (<CJK Ideograph>) 9239 0x5907 备 (<CJK Ideograph>) 9240 0x60EB 惫 (<CJK Ideograph>) 9241 0x7119 焙 (<CJK Ideograph>) 9242 0x88AB 被 (<CJK Ideograph>) 9243 0x5954 奔 (<CJK Ideograph>) 9244 0x82EF 苯 (<CJK Ideograph>) 9245 0x672C 本 (<CJK Ideograph>) 9246 0x7B28 笨 (<CJK Ideograph>) 9247 0x5D29 崩 (<CJK Ideograph>) 9248 0x7EF7 绷 (<CJK Ideograph>) 9249 0x752D 甭 (<CJK Ideograph>) 9250 0x6CF5 泵 (<CJK Ideograph>) 9251 0x8E66 蹦 (<CJK Ideograph>) 9252 0x8FF8 迸 (<CJK Ideograph>) 9253 0x903C 逼 (<CJK Ideograph>) 9254 0x9F3B 鼻 (<CJK Ideograph>) 9255 0x6BD4 比 (<CJK Ideograph>) 9256 0x9119 鄙 (<CJK Ideograph>) 9257 0x7B14 笔 (<CJK Ideograph>) 9258 0x5F7C 彼 (<CJK Ideograph>) 9259 0x78A7 碧 (<CJK Ideograph>) 9260 0x84D6 蓖 (<CJK Ideograph>) 9261 0x853D 蔽 (<CJK Ideograph>) 9262 0x6BD5 毕 (<CJK Ideograph>) 9263 0x6BD9 毙 (<CJK Ideograph>) 9264 0x6BD6 毖 (<CJK Ideograph>) 9265 0x5E01 币 (<CJK Ideograph>) 9266 0x5E87 庇 (<CJK Ideograph>) 9267 0x75F9 痹 (<CJK Ideograph>) 9268 0x95ED 闭 (<CJK Ideograph>) 9269 0x655D 敝 (<CJK Ideograph>) 9270 0x5F0A 弊 (<CJK Ideograph>) 9271 0x5FC5 必 (<CJK Ideograph>) 9272 0x8F9F 辟 (<CJK Ideograph>) 9273 0x58C1 壁 (<CJK Ideograph>) 9274 0x81C2 臂 (<CJK Ideograph>) 9275 0x907F 避 (<CJK Ideograph>) 9276 0x965B 陛 (<CJK Ideograph>) 9277 0x97AD 鞭 (<CJK Ideograph>) 9278 0x8FB9 边 (<CJK Ideograph>) 9279 0x7F16 编 (<CJK Ideograph>) 9280 0x8D2C 贬 (<CJK Ideograph>) 9281 0x6241 扁 (<CJK Ideograph>) 9282 0x4FBF 便 (<CJK Ideograph>) 9283 0x53D8 变 (<CJK Ideograph>) 9284 0x535E 卞 (<CJK Ideograph>) 9285 0x8FA8 辨 (<CJK Ideograph>) 9286 0x8FA9 辩 (<CJK Ideograph>) 9287 0x8FAB 辫 (<CJK Ideograph>) 9288 0x904D 遍 (<CJK Ideograph>) 9289 0x6807 标 (<CJK Ideograph>) 9290 0x5F6A 彪 (<CJK Ideograph>) 9291 0x8198 膘 (<CJK Ideograph>) 9292 0x8868 表 (<CJK Ideograph>) 9293 0x9CD6 鳖 (<CJK Ideograph>) 9294 0x618B 憋 (<CJK Ideograph>) 9295 0x522B 别 (<CJK Ideograph>) 9296 0x762A 瘪 (<CJK Ideograph>) 9297 0x5F6C 彬 (<CJK Ideograph>) 9298 0x658C 斌 (<CJK Ideograph>) 9299 0x6FD2 濒 (<CJK Ideograph>) 9300 0x6EE8 滨 (<CJK Ideograph>) 9301 0x5BBE 宾 (<CJK Ideograph>) 9302 0x6448 摈 (<CJK Ideograph>) 9303 0x5175 兵 (<CJK Ideograph>) 9304 0x51B0 冰 (<CJK Ideograph>) 9305 0x67C4 柄 (<CJK Ideograph>) 9306 0x4E19 丙 (<CJK Ideograph>) 9307 0x79C9 秉 (<CJK Ideograph>) 9308 0x997C 饼 (<CJK Ideograph>) 9309 0x70B3 炳 (<CJK Ideograph>) 9310 0x775D 睝 (<CJK Ideograph>) 9311 0x775E 睞 (<CJK Ideograph>) 9312 0x775F 睟 (<CJK Ideograph>) 9313 0x7760 睠 (<CJK Ideograph>) 9314 0x7764 睤 (<CJK Ideograph>) 9315 0x7767 睧 (<CJK Ideograph>) 9316 0x7769 睩 (<CJK Ideograph>) 9317 0x776A 睪 (<CJK Ideograph>) 9318 0x776D 睭 (<CJK Ideograph>) 9319 0x776E 睮 (<CJK Ideograph>) 9320 0x776F 睯 (<CJK Ideograph>) 9321 0x7770 睰 (<CJK Ideograph>) 9322 0x7771 睱 (<CJK Ideograph>) 9323 0x7772 睲 (<CJK Ideograph>) 9324 0x7773 睳 (<CJK Ideograph>) 9325 0x7774 睴 (<CJK Ideograph>) 9326 0x7775 睵 (<CJK Ideograph>) 9327 0x7776 睶 (<CJK Ideograph>) 9328 0x7777 睷 (<CJK Ideograph>) 9329 0x7778 睸 (<CJK Ideograph>) 9330 0x777A 睺 (<CJK Ideograph>) 9331 0x777B 睻 (<CJK Ideograph>) 9332 0x777C 睼 (<CJK Ideograph>) 9333 0x7781 瞁 (<CJK Ideograph>) 9334 0x7782 瞂 (<CJK Ideograph>) 9335 0x7783 瞃 (<CJK Ideograph>) 9336 0x7786 瞆 (<CJK Ideograph>) 9337 0x7787 瞇 (<CJK Ideograph>) 9338 0x7788 瞈 (<CJK Ideograph>) 9339 0x7789 瞉 (<CJK Ideograph>) 9340 0x778A 瞊 (<CJK Ideograph>) 9341 0x778B 瞋 (<CJK Ideograph>) 9342 0x778F 瞏 (<CJK Ideograph>) 9343 0x7790 瞐 (<CJK Ideograph>) 9344 0x7793 瞓 (<CJK Ideograph>) 9345 0x7794 瞔 (<CJK Ideograph>) 9346 0x7795 瞕 (<CJK Ideograph>) 9347 0x7796 瞖 (<CJK Ideograph>) 9348 0x7797 瞗 (<CJK Ideograph>) 9349 0x7798 瞘 (<CJK Ideograph>) 9350 0x7799 瞙 (<CJK Ideograph>) 9351 0x779A 瞚 (<CJK Ideograph>) 9352 0x779B 瞛 (<CJK Ideograph>) 9353 0x779C 瞜 (<CJK Ideograph>) 9354 0x779D 瞝 (<CJK Ideograph>) 9355 0x779E 瞞 (<CJK Ideograph>) 9356 0x77A1 瞡 (<CJK Ideograph>) 9357 0x77A3 瞣 (<CJK Ideograph>) 9358 0x77A4 瞤 (<CJK Ideograph>) 9359 0x77A6 瞦 (<CJK Ideograph>) 9360 0x77A8 瞨 (<CJK Ideograph>) 9361 0x77AB 瞫 (<CJK Ideograph>) 9362 0x77AD 瞭 (<CJK Ideograph>) 9363 0x77AE 瞮 (<CJK Ideograph>) 9364 0x77AF 瞯 (<CJK Ideograph>) 9365 0x77B1 瞱 (<CJK Ideograph>) 9366 0x77B2 瞲 (<CJK Ideograph>) 9367 0x77B4 瞴 (<CJK Ideograph>) 9368 0x77B6 瞶 (<CJK Ideograph>) 9369 0x77B7 瞷 (<CJK Ideograph>) 9370 0x77B8 瞸 (<CJK Ideograph>) 9371 0x77B9 瞹 (<CJK Ideograph>) 9372 0x77BA 瞺 (<CJK Ideograph>) 9373 0x77BC 瞼 (<CJK Ideograph>) 9374 0x77BE 瞾 (<CJK Ideograph>) 9375 0x77C0 矀 (<CJK Ideograph>) 9376 0x77C1 矁 (<CJK Ideograph>) 9377 0x77C2 矂 (<CJK Ideograph>) 9378 0x77C3 矃 (<CJK Ideograph>) 9379 0x77C4 矄 (<CJK Ideograph>) 9380 0x77C5 矅 (<CJK Ideograph>) 9381 0x77C6 矆 (<CJK Ideograph>) 9382 0x77C7 矇 (<CJK Ideograph>) 9383 0x77C8 矈 (<CJK Ideograph>) 9384 0x77C9 矉 (<CJK Ideograph>) 9385 0x77CA 矊 (<CJK Ideograph>) 9386 0x77CB 矋 (<CJK Ideograph>) 9387 0x77CC 矌 (<CJK Ideograph>) 9388 0x77CE 矎 (<CJK Ideograph>) 9389 0x77CF 矏 (<CJK Ideograph>) 9390 0x77D0 矐 (<CJK Ideograph>) 9391 0x77D1 矑 (<CJK Ideograph>) 9392 0x77D2 矒 (<CJK Ideograph>) 9393 0x77D3 矓 (<CJK Ideograph>) 9394 0x77D4 矔 (<CJK Ideograph>) 9395 0x77D5 矕 (<CJK Ideograph>) 9396 0x77D6 矖 (<CJK Ideograph>) 9397 0x77D8 矘 (<CJK Ideograph>) 9398 0x77D9 矙 (<CJK Ideograph>) 9399 0x77DA 矚 (<CJK Ideograph>) 9400 0x77DD 矝 (<CJK Ideograph>) 9401 0x77DE 矞 (<CJK Ideograph>) 9402 0x77DF 矟 (<CJK Ideograph>) 9403 0x77E0 矠 (<CJK Ideograph>) 9404 0x77E1 矡 (<CJK Ideograph>) 9405 0x77E4 矤 (<CJK Ideograph>) 9406 0x75C5 病 (<CJK Ideograph>) 9407 0x5E76 并 (<CJK Ideograph>) 9408 0x73BB 玻 (<CJK Ideograph>) 9409 0x83E0 菠 (<CJK Ideograph>) 9410 0x64AD 播 (<CJK Ideograph>) 9411 0x62E8 拨 (<CJK Ideograph>) 9412 0x94B5 钵 (<CJK Ideograph>) 9413 0x6CE2 波 (<CJK Ideograph>) 9414 0x535A 博 (<CJK Ideograph>) 9415 0x52C3 勃 (<CJK Ideograph>) 9416 0x640F 搏 (<CJK Ideograph>) 9417 0x94C2 铂 (<CJK Ideograph>) 9418 0x7B94 箔 (<CJK Ideograph>) 9419 0x4F2F 伯 (<CJK Ideograph>) 9420 0x5E1B 帛 (<CJK Ideograph>) 9421 0x8236 舶 (<CJK Ideograph>) 9422 0x8116 脖 (<CJK Ideograph>) 9423 0x818A 膊 (<CJK Ideograph>) 9424 0x6E24 渤 (<CJK Ideograph>) 9425 0x6CCA 泊 (<CJK Ideograph>) 9426 0x9A73 驳 (<CJK Ideograph>) 9427 0x6355 捕 (<CJK Ideograph>) 9428 0x535C 卜 (<CJK Ideograph>) 9429 0x54FA 哺 (<CJK Ideograph>) 9430 0x8865 补 (<CJK Ideograph>) 9431 0x57E0 埠 (<CJK Ideograph>) 9432 0x4E0D 不 (<CJK Ideograph>) 9433 0x5E03 布 (<CJK Ideograph>) 9434 0x6B65 步 (<CJK Ideograph>) 9435 0x7C3F 簿 (<CJK Ideograph>) 9436 0x90E8 部 (<CJK Ideograph>) 9437 0x6016 怖 (<CJK Ideograph>) 9438 0x64E6 擦 (<CJK Ideograph>) 9439 0x731C 猜 (<CJK Ideograph>) 9440 0x88C1 裁 (<CJK Ideograph>) 9441 0x6750 材 (<CJK Ideograph>) 9442 0x624D 才 (<CJK Ideograph>) 9443 0x8D22 财 (<CJK Ideograph>) 9444 0x776C 睬 (<CJK Ideograph>) 9445 0x8E29 踩 (<CJK Ideograph>) 9446 0x91C7 采 (<CJK Ideograph>) 9447 0x5F69 彩 (<CJK Ideograph>) 9448 0x83DC 菜 (<CJK Ideograph>) 9449 0x8521 蔡 (<CJK Ideograph>) 9450 0x9910 餐 (<CJK Ideograph>) 9451 0x53C2 参 (<CJK Ideograph>) 9452 0x8695 蚕 (<CJK Ideograph>) 9453 0x6B8B 残 (<CJK Ideograph>) 9454 0x60ED 惭 (<CJK Ideograph>) 9455 0x60E8 惨 (<CJK Ideograph>) 9456 0x707F 灿 (<CJK Ideograph>) 9457 0x82CD 苍 (<CJK Ideograph>) 9458 0x8231 舱 (<CJK Ideograph>) 9459 0x4ED3 仓 (<CJK Ideograph>) 9460 0x6CA7 沧 (<CJK Ideograph>) 9461 0x85CF 藏 (<CJK Ideograph>) 9462 0x64CD 操 (<CJK Ideograph>) 9463 0x7CD9 糙 (<CJK Ideograph>) 9464 0x69FD 槽 (<CJK Ideograph>) 9465 0x66F9 曹 (<CJK Ideograph>) 9466 0x8349 草 (<CJK Ideograph>) 9467 0x5395 厕 (<CJK Ideograph>) 9468 0x7B56 策 (<CJK Ideograph>) 9469 0x4FA7 侧 (<CJK Ideograph>) 9470 0x518C 册 (<CJK Ideograph>) 9471 0x6D4B 测 (<CJK Ideograph>) 9472 0x5C42 层 (<CJK Ideograph>) 9473 0x8E6D 蹭 (<CJK Ideograph>) 9474 0x63D2 插 (<CJK Ideograph>) 9475 0x53C9 叉 (<CJK Ideograph>) 9476 0x832C 茬 (<CJK Ideograph>) 9477 0x8336 茶 (<CJK Ideograph>) 9478 0x67E5 查 (<CJK Ideograph>) 9479 0x78B4 碴 (<CJK Ideograph>) 9480 0x643D 搽 (<CJK Ideograph>) 9481 0x5BDF 察 (<CJK Ideograph>) 9482 0x5C94 岔 (<CJK Ideograph>) 9483 0x5DEE 差 (<CJK Ideograph>) 9484 0x8BE7 诧 (<CJK Ideograph>) 9485 0x62C6 拆 (<CJK Ideograph>) 9486 0x67F4 柴 (<CJK Ideograph>) 9487 0x8C7A 豺 (<CJK Ideograph>) 9488 0x6400 搀 (<CJK Ideograph>) 9489 0x63BA 掺 (<CJK Ideograph>) 9490 0x8749 蝉 (<CJK Ideograph>) 9491 0x998B 馋 (<CJK Ideograph>) 9492 0x8C17 谗 (<CJK Ideograph>) 9493 0x7F20 缠 (<CJK Ideograph>) 9494 0x94F2 铲 (<CJK Ideograph>) 9495 0x4EA7 产 (<CJK Ideograph>) 9496 0x9610 阐 (<CJK Ideograph>) 9497 0x98A4 颤 (<CJK Ideograph>) 9498 0x660C 昌 (<CJK Ideograph>) 9499 0x7316 猖 (<CJK Ideograph>) 9500 0x77E6 矦 (<CJK Ideograph>) 9501 0x77E8 矨 (<CJK Ideograph>) 9502 0x77EA 矪 (<CJK Ideograph>) 9503 0x77EF 矯 (<CJK Ideograph>) 9504 0x77F0 矰 (<CJK Ideograph>) 9505 0x77F1 矱 (<CJK Ideograph>) 9506 0x77F2 矲 (<CJK Ideograph>) 9507 0x77F4 矴 (<CJK Ideograph>) 9508 0x77F5 矵 (<CJK Ideograph>) 9509 0x77F7 矷 (<CJK Ideograph>) 9510 0x77F9 矹 (<CJK Ideograph>) 9511 0x77FA 矺 (<CJK Ideograph>) 9512 0x77FB 矻 (<CJK Ideograph>) 9513 0x77FC 矼 (<CJK Ideograph>) 9514 0x7803 砃 (<CJK Ideograph>) 9515 0x7804 砄 (<CJK Ideograph>) 9516 0x7805 砅 (<CJK Ideograph>) 9517 0x7806 砆 (<CJK Ideograph>) 9518 0x7807 砇 (<CJK Ideograph>) 9519 0x7808 砈 (<CJK Ideograph>) 9520 0x780A 砊 (<CJK Ideograph>) 9521 0x780B 砋 (<CJK Ideograph>) 9522 0x780E 砎 (<CJK Ideograph>) 9523 0x780F 砏 (<CJK Ideograph>) 9524 0x7810 砐 (<CJK Ideograph>) 9525 0x7813 砓 (<CJK Ideograph>) 9526 0x7815 砕 (<CJK Ideograph>) 9527 0x7819 砙 (<CJK Ideograph>) 9528 0x781B 砛 (<CJK Ideograph>) 9529 0x781E 砞 (<CJK Ideograph>) 9530 0x7820 砠 (<CJK Ideograph>) 9531 0x7821 砡 (<CJK Ideograph>) 9532 0x7822 砢 (<CJK Ideograph>) 9533 0x7824 砤 (<CJK Ideograph>) 9534 0x7828 砨 (<CJK Ideograph>) 9535 0x782A 砪 (<CJK Ideograph>) 9536 0x782B 砫 (<CJK Ideograph>) 9537 0x782E 砮 (<CJK Ideograph>) 9538 0x782F 砯 (<CJK Ideograph>) 9539 0x7831 砱 (<CJK Ideograph>) 9540 0x7832 砲 (<CJK Ideograph>) 9541 0x7833 砳 (<CJK Ideograph>) 9542 0x7835 砵 (<CJK Ideograph>) 9543 0x7836 砶 (<CJK Ideograph>) 9544 0x783D 砽 (<CJK Ideograph>) 9545 0x783F 砿 (<CJK Ideograph>) 9546 0x7841 硁 (<CJK Ideograph>) 9547 0x7842 硂 (<CJK Ideograph>) 9548 0x7843 硃 (<CJK Ideograph>) 9549 0x7844 硄 (<CJK Ideograph>) 9550 0x7846 硆 (<CJK Ideograph>) 9551 0x7848 硈 (<CJK Ideograph>) 9552 0x7849 硉 (<CJK Ideograph>) 9553 0x784A 硊 (<CJK Ideograph>) 9554 0x784B 硋 (<CJK Ideograph>) 9555 0x784D 硍 (<CJK Ideograph>) 9556 0x784F 硏 (<CJK Ideograph>) 9557 0x7851 硑 (<CJK Ideograph>) 9558 0x7853 硓 (<CJK Ideograph>) 9559 0x7854 硔 (<CJK Ideograph>) 9560 0x7858 硘 (<CJK Ideograph>) 9561 0x7859 硙 (<CJK Ideograph>) 9562 0x785A 硚 (<CJK Ideograph>) 9563 0x785B 硛 (<CJK Ideograph>) 9564 0x785C 硜 (<CJK Ideograph>) 9565 0x785E 硞 (<CJK Ideograph>) 9566 0x785F 硟 (<CJK Ideograph>) 9567 0x7860 硠 (<CJK Ideograph>) 9568 0x7861 硡 (<CJK Ideograph>) 9569 0x7862 硢 (<CJK Ideograph>) 9570 0x7863 硣 (<CJK Ideograph>) 9571 0x7864 硤 (<CJK Ideograph>) 9572 0x7865 硥 (<CJK Ideograph>) 9573 0x7866 硦 (<CJK Ideograph>) 9574 0x7867 硧 (<CJK Ideograph>) 9575 0x7868 硨 (<CJK Ideograph>) 9576 0x7869 硩 (<CJK Ideograph>) 9577 0x786F 硯 (<CJK Ideograph>) 9578 0x7870 硰 (<CJK Ideograph>) 9579 0x7871 硱 (<CJK Ideograph>) 9580 0x7872 硲 (<CJK Ideograph>) 9581 0x7873 硳 (<CJK Ideograph>) 9582 0x7874 硴 (<CJK Ideograph>) 9583 0x7875 硵 (<CJK Ideograph>) 9584 0x7876 硶 (<CJK Ideograph>) 9585 0x7878 硸 (<CJK Ideograph>) 9586 0x7879 硹 (<CJK Ideograph>) 9587 0x787A 硺 (<CJK Ideograph>) 9588 0x787B 硻 (<CJK Ideograph>) 9589 0x787D 硽 (<CJK Ideograph>) 9590 0x787E 硾 (<CJK Ideograph>) 9591 0x787F 硿 (<CJK Ideograph>) 9592 0x7880 碀 (<CJK Ideograph>) 9593 0x7881 碁 (<CJK Ideograph>) 9594 0x7882 碂 (<CJK Ideograph>) 9595 0x7883 碃 (<CJK Ideograph>) 9596 0x573A 场 (<CJK Ideograph>) 9597 0x5C1D 尝 (<CJK Ideograph>) 9598 0x5E38 常 (<CJK Ideograph>) 9599 0x957F 长 (<CJK Ideograph>) 9600 0x507F 偿 (<CJK Ideograph>) 9601 0x80A0 肠 (<CJK Ideograph>) 9602 0x5382 厂 (<CJK Ideograph>) 9603 0x655E 敞 (<CJK Ideograph>) 9604 0x7545 畅 (<CJK Ideograph>) 9605 0x5531 唱 (<CJK Ideograph>) 9606 0x5021 倡 (<CJK Ideograph>) 9607 0x8D85 超 (<CJK Ideograph>) 9608 0x6284 抄 (<CJK Ideograph>) 9609 0x949E 钞 (<CJK Ideograph>) 9610 0x671D 朝 (<CJK Ideograph>) 9611 0x5632 嘲 (<CJK Ideograph>) 9612 0x6F6E 潮 (<CJK Ideograph>) 9613 0x5DE2 巢 (<CJK Ideograph>) 9614 0x5435 吵 (<CJK Ideograph>) 9615 0x7092 炒 (<CJK Ideograph>) 9616 0x8F66 车 (<CJK Ideograph>) 9617 0x626F 扯 (<CJK Ideograph>) 9618 0x64A4 撤 (<CJK Ideograph>) 9619 0x63A3 掣 (<CJK Ideograph>) 9620 0x5F7B 彻 (<CJK Ideograph>) 9621 0x6F88 澈 (<CJK Ideograph>) 9622 0x90F4 郴 (<CJK Ideograph>) 9623 0x81E3 臣 (<CJK Ideograph>) 9624 0x8FB0 辰 (<CJK Ideograph>) 9625 0x5C18 尘 (<CJK Ideograph>) 9626 0x6668 晨 (<CJK Ideograph>) 9627 0x5FF1 忱 (<CJK Ideograph>) 9628 0x6C89 沉 (<CJK Ideograph>) 9629 0x9648 陈 (<CJK Ideograph>) 9630 0x8D81 趁 (<CJK Ideograph>) 9631 0x886C 衬 (<CJK Ideograph>) 9632 0x6491 撑 (<CJK Ideograph>) 9633 0x79F0 称 (<CJK Ideograph>) 9634 0x57CE 城 (<CJK Ideograph>) 9635 0x6A59 橙 (<CJK Ideograph>) 9636 0x6210 成 (<CJK Ideograph>) 9637 0x5448 呈 (<CJK Ideograph>) 9638 0x4E58 乘 (<CJK Ideograph>) 9639 0x7A0B 程 (<CJK Ideograph>) 9640 0x60E9 惩 (<CJK Ideograph>) 9641 0x6F84 澄 (<CJK Ideograph>) 9642 0x8BDA 诚 (<CJK Ideograph>) 9643 0x627F 承 (<CJK Ideograph>) 9644 0x901E 逞 (<CJK Ideograph>) 9645 0x9A8B 骋 (<CJK Ideograph>) 9646 0x79E4 秤 (<CJK Ideograph>) 9647 0x5403 吃 (<CJK Ideograph>) 9648 0x75F4 痴 (<CJK Ideograph>) 9649 0x6301 持 (<CJK Ideograph>) 9650 0x5319 匙 (<CJK Ideograph>) 9651 0x6C60 池 (<CJK Ideograph>) 9652 0x8FDF 迟 (<CJK Ideograph>) 9653 0x5F1B 弛 (<CJK Ideograph>) 9654 0x9A70 驰 (<CJK Ideograph>) 9655 0x803B 耻 (<CJK Ideograph>) 9656 0x9F7F 齿 (<CJK Ideograph>) 9657 0x4F88 侈 (<CJK Ideograph>) 9658 0x5C3A 尺 (<CJK Ideograph>) 9659 0x8D64 赤 (<CJK Ideograph>) 9660 0x7FC5 翅 (<CJK Ideograph>) 9661 0x65A5 斥 (<CJK Ideograph>) 9662 0x70BD 炽 (<CJK Ideograph>) 9663 0x5145 充 (<CJK Ideograph>) 9664 0x51B2 冲 (<CJK Ideograph>) 9665 0x866B 虫 (<CJK Ideograph>) 9666 0x5D07 崇 (<CJK Ideograph>) 9667 0x5BA0 宠 (<CJK Ideograph>) 9668 0x62BD 抽 (<CJK Ideograph>) 9669 0x916C 酬 (<CJK Ideograph>) 9670 0x7574 畴 (<CJK Ideograph>) 9671 0x8E0C 踌 (<CJK Ideograph>) 9672 0x7A20 稠 (<CJK Ideograph>) 9673 0x6101 愁 (<CJK Ideograph>) 9674 0x7B79 筹 (<CJK Ideograph>) 9675 0x4EC7 仇 (<CJK Ideograph>) 9676 0x7EF8 绸 (<CJK Ideograph>) 9677 0x7785 瞅 (<CJK Ideograph>) 9678 0x4E11 丑 (<CJK Ideograph>) 9679 0x81ED 臭 (<CJK Ideograph>) 9680 0x521D 初 (<CJK Ideograph>) 9681 0x51FA 出 (<CJK Ideograph>) 9682 0x6A71 橱 (<CJK Ideograph>) 9683 0x53A8 厨 (<CJK Ideograph>) 9684 0x8E87 躇 (<CJK Ideograph>) 9685 0x9504 锄 (<CJK Ideograph>) 9686 0x96CF 雏 (<CJK Ideograph>) 9687 0x6EC1 滁 (<CJK Ideograph>) 9688 0x9664 除 (<CJK Ideograph>) 9689 0x695A 楚 (<CJK Ideograph>) 9690 0x7884 碄 (<CJK Ideograph>) 9691 0x7885 碅 (<CJK Ideograph>) 9692 0x7886 碆 (<CJK Ideograph>) 9693 0x7888 碈 (<CJK Ideograph>) 9694 0x788A 碊 (<CJK Ideograph>) 9695 0x788B 碋 (<CJK Ideograph>) 9696 0x788F 碏 (<CJK Ideograph>) 9697 0x7890 碐 (<CJK Ideograph>) 9698 0x7892 碒 (<CJK Ideograph>) 9699 0x7894 碔 (<CJK Ideograph>) 9700 0x7895 碕 (<CJK Ideograph>) 9701 0x7896 碖 (<CJK Ideograph>) 9702 0x7899 碙 (<CJK Ideograph>) 9703 0x789D 碝 (<CJK Ideograph>) 9704 0x789E 碞 (<CJK Ideograph>) 9705 0x78A0 碠 (<CJK Ideograph>) 9706 0x78A2 碢 (<CJK Ideograph>) 9707 0x78A4 碤 (<CJK Ideograph>) 9708 0x78A6 碦 (<CJK Ideograph>) 9709 0x78A8 碨 (<CJK Ideograph>) 9710 0x78A9 碩 (<CJK Ideograph>) 9711 0x78AA 碪 (<CJK Ideograph>) 9712 0x78AB 碫 (<CJK Ideograph>) 9713 0x78AC 碬 (<CJK Ideograph>) 9714 0x78AD 碭 (<CJK Ideograph>) 9715 0x78AE 碮 (<CJK Ideograph>) 9716 0x78AF 碯 (<CJK Ideograph>) 9717 0x78B5 碵 (<CJK Ideograph>) 9718 0x78B6 碶 (<CJK Ideograph>) 9719 0x78B7 碷 (<CJK Ideograph>) 9720 0x78B8 碸 (<CJK Ideograph>) 9721 0x78BA 確 (<CJK Ideograph>) 9722 0x78BB 碻 (<CJK Ideograph>) 9723 0x78BC 碼 (<CJK Ideograph>) 9724 0x78BD 碽 (<CJK Ideograph>) 9725 0x78BF 碿 (<CJK Ideograph>) 9726 0x78C0 磀 (<CJK Ideograph>) 9727 0x78C2 磂 (<CJK Ideograph>) 9728 0x78C3 磃 (<CJK Ideograph>) 9729 0x78C4 磄 (<CJK Ideograph>) 9730 0x78C6 磆 (<CJK Ideograph>) 9731 0x78C7 磇 (<CJK Ideograph>) 9732 0x78C8 磈 (<CJK Ideograph>) 9733 0x78CC 磌 (<CJK Ideograph>) 9734 0x78CD 磍 (<CJK Ideograph>) 9735 0x78CE 磎 (<CJK Ideograph>) 9736 0x78CF 磏 (<CJK Ideograph>) 9737 0x78D1 磑 (<CJK Ideograph>) 9738 0x78D2 磒 (<CJK Ideograph>) 9739 0x78D3 磓 (<CJK Ideograph>) 9740 0x78D6 磖 (<CJK Ideograph>) 9741 0x78D7 磗 (<CJK Ideograph>) 9742 0x78D8 磘 (<CJK Ideograph>) 9743 0x78DA 磚 (<CJK Ideograph>) 9744 0x78DB 磛 (<CJK Ideograph>) 9745 0x78DC 磜 (<CJK Ideograph>) 9746 0x78DD 磝 (<CJK Ideograph>) 9747 0x78DE 磞 (<CJK Ideograph>) 9748 0x78DF 磟 (<CJK Ideograph>) 9749 0x78E0 磠 (<CJK Ideograph>) 9750 0x78E1 磡 (<CJK Ideograph>) 9751 0x78E2 磢 (<CJK Ideograph>) 9752 0x78E3 磣 (<CJK Ideograph>) 9753 0x78E4 磤 (<CJK Ideograph>) 9754 0x78E5 磥 (<CJK Ideograph>) 9755 0x78E6 磦 (<CJK Ideograph>) 9756 0x78E7 磧 (<CJK Ideograph>) 9757 0x78E9 磩 (<CJK Ideograph>) 9758 0x78EA 磪 (<CJK Ideograph>) 9759 0x78EB 磫 (<CJK Ideograph>) 9760 0x78ED 磭 (<CJK Ideograph>) 9761 0x78EE 磮 (<CJK Ideograph>) 9762 0x78EF 磯 (<CJK Ideograph>) 9763 0x78F0 磰 (<CJK Ideograph>) 9764 0x78F1 磱 (<CJK Ideograph>) 9765 0x78F3 磳 (<CJK Ideograph>) 9766 0x78F5 磵 (<CJK Ideograph>) 9767 0x78F6 磶 (<CJK Ideograph>) 9768 0x78F8 磸 (<CJK Ideograph>) 9769 0x78F9 磹 (<CJK Ideograph>) 9770 0x78FB 磻 (<CJK Ideograph>) 9771 0x78FC 磼 (<CJK Ideograph>) 9772 0x78FD 磽 (<CJK Ideograph>) 9773 0x78FE 磾 (<CJK Ideograph>) 9774 0x78FF 磿 (<CJK Ideograph>) 9775 0x7900 礀 (<CJK Ideograph>) 9776 0x7902 礂 (<CJK Ideograph>) 9777 0x7903 礃 (<CJK Ideograph>) 9778 0x7904 礄 (<CJK Ideograph>) 9779 0x7906 礆 (<CJK Ideograph>) 9780 0x7907 礇 (<CJK Ideograph>) 9781 0x7908 礈 (<CJK Ideograph>) 9782 0x7909 礉 (<CJK Ideograph>) 9783 0x790A 礊 (<CJK Ideograph>) 9784 0x790B 礋 (<CJK Ideograph>) 9785 0x790C 礌 (<CJK Ideograph>) 9786 0x7840 础 (<CJK Ideograph>) 9787 0x50A8 储 (<CJK Ideograph>) 9788 0x77D7 矗 (<CJK Ideograph>) 9789 0x6410 搐 (<CJK Ideograph>) 9790 0x89E6 触 (<CJK Ideograph>) 9791 0x5904 处 (<CJK Ideograph>) 9792 0x63E3 揣 (<CJK Ideograph>) 9793 0x5DDD 川 (<CJK Ideograph>) 9794 0x7A7F 穿 (<CJK Ideograph>) 9795 0x693D 椽 (<CJK Ideograph>) 9796 0x4F20 传 (<CJK Ideograph>) 9797 0x8239 船 (<CJK Ideograph>) 9798 0x5598 喘 (<CJK Ideograph>) 9799 0x4E32 串 (<CJK Ideograph>) 9800 0x75AE 疮 (<CJK Ideograph>) 9801 0x7A97 窗 (<CJK Ideograph>) 9802 0x5E62 幢 (<CJK Ideograph>) 9803 0x5E8A 床 (<CJK Ideograph>) 9804 0x95EF 闯 (<CJK Ideograph>) 9805 0x521B 创 (<CJK Ideograph>) 9806 0x5439 吹 (<CJK Ideograph>) 9807 0x708A 炊 (<CJK Ideograph>) 9808 0x6376 捶 (<CJK Ideograph>) 9809 0x9524 锤 (<CJK Ideograph>) 9810 0x5782 垂 (<CJK Ideograph>) 9811 0x6625 春 (<CJK Ideograph>) 9812 0x693F 椿 (<CJK Ideograph>) 9813 0x9187 醇 (<CJK Ideograph>) 9814 0x5507 唇 (<CJK Ideograph>) 9815 0x6DF3 淳 (<CJK Ideograph>) 9816 0x7EAF 纯 (<CJK Ideograph>) 9817 0x8822 蠢 (<CJK Ideograph>) 9818 0x6233 戳 (<CJK Ideograph>) 9819 0x7EF0 绰 (<CJK Ideograph>) 9820 0x75B5 疵 (<CJK Ideograph>) 9821 0x8328 茨 (<CJK Ideograph>) 9822 0x78C1 磁 (<CJK Ideograph>) 9823 0x96CC 雌 (<CJK Ideograph>) 9824 0x8F9E 辞 (<CJK Ideograph>) 9825 0x6148 慈 (<CJK Ideograph>) 9826 0x74F7 瓷 (<CJK Ideograph>) 9827 0x8BCD 词 (<CJK Ideograph>) 9828 0x6B64 此 (<CJK Ideograph>) 9829 0x523A 刺 (<CJK Ideograph>) 9830 0x8D50 赐 (<CJK Ideograph>) 9831 0x6B21 次 (<CJK Ideograph>) 9832 0x806A 聪 (<CJK Ideograph>) 9833 0x8471 葱 (<CJK Ideograph>) 9834 0x56F1 囱 (<CJK Ideograph>) 9835 0x5306 匆 (<CJK Ideograph>) 9836 0x4ECE 从 (<CJK Ideograph>) 9837 0x4E1B 丛 (<CJK Ideograph>) 9838 0x51D1 凑 (<CJK Ideograph>) 9839 0x7C97 粗 (<CJK Ideograph>) 9840 0x918B 醋 (<CJK Ideograph>) 9841 0x7C07 簇 (<CJK Ideograph>) 9842 0x4FC3 促 (<CJK Ideograph>) 9843 0x8E7F 蹿 (<CJK Ideograph>) 9844 0x7BE1 篡 (<CJK Ideograph>) 9845 0x7A9C 窜 (<CJK Ideograph>) 9846 0x6467 摧 (<CJK Ideograph>) 9847 0x5D14 崔 (<CJK Ideograph>) 9848 0x50AC 催 (<CJK Ideograph>) 9849 0x8106 脆 (<CJK Ideograph>) 9850 0x7601 瘁 (<CJK Ideograph>) 9851 0x7CB9 粹 (<CJK Ideograph>) 9852 0x6DEC 淬 (<CJK Ideograph>) 9853 0x7FE0 翠 (<CJK Ideograph>) 9854 0x6751 村 (<CJK Ideograph>) 9855 0x5B58 存 (<CJK Ideograph>) 9856 0x5BF8 寸 (<CJK Ideograph>) 9857 0x78CB 磋 (<CJK Ideograph>) 9858 0x64AE 撮 (<CJK Ideograph>) 9859 0x6413 搓 (<CJK Ideograph>) 9860 0x63AA 措 (<CJK Ideograph>) 9861 0x632B 挫 (<CJK Ideograph>) 9862 0x9519 错 (<CJK Ideograph>) 9863 0x642D 搭 (<CJK Ideograph>) 9864 0x8FBE 达 (<CJK Ideograph>) 9865 0x7B54 答 (<CJK Ideograph>) 9866 0x7629 瘩 (<CJK Ideograph>) 9867 0x6253 打 (<CJK Ideograph>) 9868 0x5927 大 (<CJK Ideograph>) 9869 0x5446 呆 (<CJK Ideograph>) 9870 0x6B79 歹 (<CJK Ideograph>) 9871 0x50A3 傣 (<CJK Ideograph>) 9872 0x6234 戴 (<CJK Ideograph>) 9873 0x5E26 带 (<CJK Ideograph>) 9874 0x6B86 殆 (<CJK Ideograph>) 9875 0x4EE3 代 (<CJK Ideograph>) 9876 0x8D37 贷 (<CJK Ideograph>) 9877 0x888B 袋 (<CJK Ideograph>) 9878 0x5F85 待 (<CJK Ideograph>) 9879 0x902E 逮 (<CJK Ideograph>) 9880 0x790D 礍 (<CJK Ideograph>) 9881 0x790E 礎 (<CJK Ideograph>) 9882 0x790F 礏 (<CJK Ideograph>) 9883 0x7910 礐 (<CJK Ideograph>) 9884 0x7911 礑 (<CJK Ideograph>) 9885 0x7912 礒 (<CJK Ideograph>) 9886 0x7914 礔 (<CJK Ideograph>) 9887 0x7915 礕 (<CJK Ideograph>) 9888 0x7916 礖 (<CJK Ideograph>) 9889 0x7917 礗 (<CJK Ideograph>) 9890 0x7918 礘 (<CJK Ideograph>) 9891 0x7919 礙 (<CJK Ideograph>) 9892 0x791A 礚 (<CJK Ideograph>) 9893 0x791B 礛 (<CJK Ideograph>) 9894 0x791C 礜 (<CJK Ideograph>) 9895 0x791D 礝 (<CJK Ideograph>) 9896 0x791F 礟 (<CJK Ideograph>) 9897 0x7920 礠 (<CJK Ideograph>) 9898 0x7921 礡 (<CJK Ideograph>) 9899 0x7922 礢 (<CJK Ideograph>) 9900 0x7923 礣 (<CJK Ideograph>) 9901 0x7925 礥 (<CJK Ideograph>) 9902 0x7926 礦 (<CJK Ideograph>) 9903 0x7927 礧 (<CJK Ideograph>) 9904 0x7928 礨 (<CJK Ideograph>) 9905 0x7929 礩 (<CJK Ideograph>) 9906 0x792A 礪 (<CJK Ideograph>) 9907 0x792B 礫 (<CJK Ideograph>) 9908 0x792C 礬 (<CJK Ideograph>) 9909 0x792D 礭 (<CJK Ideograph>) 9910 0x792E 礮 (<CJK Ideograph>) 9911 0x792F 礯 (<CJK Ideograph>) 9912 0x7930 礰 (<CJK Ideograph>) 9913 0x7931 礱 (<CJK Ideograph>) 9914 0x7932 礲 (<CJK Ideograph>) 9915 0x7933 礳 (<CJK Ideograph>) 9916 0x7935 礵 (<CJK Ideograph>) 9917 0x7936 礶 (<CJK Ideograph>) 9918 0x7937 礷 (<CJK Ideograph>) 9919 0x7938 礸 (<CJK Ideograph>) 9920 0x7939 礹 (<CJK Ideograph>) 9921 0x793D 礽 (<CJK Ideograph>) 9922 0x793F 礿 (<CJK Ideograph>) 9923 0x7942 祂 (<CJK Ideograph>) 9924 0x7943 祃 (<CJK Ideograph>) 9925 0x7944 祄 (<CJK Ideograph>) 9926 0x7945 祅 (<CJK Ideograph>) 9927 0x7947 祇 (<CJK Ideograph>) 9928 0x794A 祊 (<CJK Ideograph>) 9929 0x794B 祋 (<CJK Ideograph>) 9930 0x794C 祌 (<CJK Ideograph>) 9931 0x794D 祍 (<CJK Ideograph>) 9932 0x794E 祎 (<CJK Ideograph>) 9933 0x794F 祏 (<CJK Ideograph>) 9934 0x7950 祐 (<CJK Ideograph>) 9935 0x7951 祑 (<CJK Ideograph>) 9936 0x7952 祒 (<CJK Ideograph>) 9937 0x7954 祔 (<CJK Ideograph>) 9938 0x7955 祕 (<CJK Ideograph>) 9939 0x7958 祘 (<CJK Ideograph>) 9940 0x7959 祙 (<CJK Ideograph>) 9941 0x7961 祡 (<CJK Ideograph>) 9942 0x7963 祣 (<CJK Ideograph>) 9943 0x7964 祤 (<CJK Ideograph>) 9944 0x7966 祦 (<CJK Ideograph>) 9945 0x7969 祩 (<CJK Ideograph>) 9946 0x796A 祪 (<CJK Ideograph>) 9947 0x796B 祫 (<CJK Ideograph>) 9948 0x796C 祬 (<CJK Ideograph>) 9949 0x796E 祮 (<CJK Ideograph>) 9950 0x7970 祰 (<CJK Ideograph>) 9951 0x7971 祱 (<CJK Ideograph>) 9952 0x7972 祲 (<CJK Ideograph>) 9953 0x7973 祳 (<CJK Ideograph>) 9954 0x7974 祴 (<CJK Ideograph>) 9955 0x7975 祵 (<CJK Ideograph>) 9956 0x7976 祶 (<CJK Ideograph>) 9957 0x7979 祹 (<CJK Ideograph>) 9958 0x797B 祻 (<CJK Ideograph>) 9959 0x797C 祼 (<CJK Ideograph>) 9960 0x797D 祽 (<CJK Ideograph>) 9961 0x797E 祾 (<CJK Ideograph>) 9962 0x797F 祿 (<CJK Ideograph>) 9963 0x7982 禂 (<CJK Ideograph>) 9964 0x7983 禃 (<CJK Ideograph>) 9965 0x7986 禆 (<CJK Ideograph>) 9966 0x7987 禇 (<CJK Ideograph>) 9967 0x7988 禈 (<CJK Ideograph>) 9968 0x7989 禉 (<CJK Ideograph>) 9969 0x798B 禋 (<CJK Ideograph>) 9970 0x798C 禌 (<CJK Ideograph>) 9971 0x798D 禍 (<CJK Ideograph>) 9972 0x798E 禎 (<CJK Ideograph>) 9973 0x7990 禐 (<CJK Ideograph>) 9974 0x7991 禑 (<CJK Ideograph>) 9975 0x7992 禒 (<CJK Ideograph>) 9976 0x6020 怠 (<CJK Ideograph>) 9977 0x803D 耽 (<CJK Ideograph>) 9978 0x62C5 担 (<CJK Ideograph>) 9979 0x4E39 丹 (<CJK Ideograph>) 9980 0x5355 单 (<CJK Ideograph>) 9981 0x90F8 郸 (<CJK Ideograph>) 9982 0x63B8 掸 (<CJK Ideograph>) 9983 0x80C6 胆 (<CJK Ideograph>) 9984 0x65E6 旦 (<CJK Ideograph>) 9985 0x6C2E 氮 (<CJK Ideograph>) 9986 0x4F46 但 (<CJK Ideograph>) 9987 0x60EE 惮 (<CJK Ideograph>) 9988 0x6DE1 淡 (<CJK Ideograph>) 9989 0x8BDE 诞 (<CJK Ideograph>) 9990 0x5F39 弹 (<CJK Ideograph>) 9991 0x86CB 蛋 (<CJK Ideograph>) 9992 0x5F53 当 (<CJK Ideograph>) 9993 0x6321 挡 (<CJK Ideograph>) 9994 0x515A 党 (<CJK Ideograph>) 9995 0x8361 荡 (<CJK Ideograph>) 9996 0x6863 档 (<CJK Ideograph>) 9997 0x5200 刀 (<CJK Ideograph>) 9998 0x6363 捣 (<CJK Ideograph>) 9999 0x8E48 蹈 (<CJK Ideograph>) 10000 0x5012 倒 (<CJK Ideograph>) 10001 0x5C9B 岛 (<CJK Ideograph>) 10002 0x7977 祷 (<CJK Ideograph>) 10003 0x5BFC 导 (<CJK Ideograph>) 10004 0x5230 到 (<CJK Ideograph>) 10005 0x7A3B 稻 (<CJK Ideograph>) 10006 0x60BC 悼 (<CJK Ideograph>) 10007 0x9053 道 (<CJK Ideograph>) 10008 0x76D7 盗 (<CJK Ideograph>) 10009 0x5FB7 德 (<CJK Ideograph>) 10010 0x5F97 得 (<CJK Ideograph>) 10011 0x7684 的 (<CJK Ideograph>) 10012 0x8E6C 蹬 (<CJK Ideograph>) 10013 0x706F 灯 (<CJK Ideograph>) 10014 0x767B 登 (<CJK Ideograph>) 10015 0x7B49 等 (<CJK Ideograph>) 10016 0x77AA 瞪 (<CJK Ideograph>) 10017 0x51F3 凳 (<CJK Ideograph>) 10018 0x9093 邓 (<CJK Ideograph>) 10019 0x5824 堤 (<CJK Ideograph>) 10020 0x4F4E 低 (<CJK Ideograph>) 10021 0x6EF4 滴 (<CJK Ideograph>) 10022 0x8FEA 迪 (<CJK Ideograph>) 10023 0x654C 敌 (<CJK Ideograph>) 10024 0x7B1B 笛 (<CJK Ideograph>) 10025 0x72C4 狄 (<CJK Ideograph>) 10026 0x6DA4 涤 (<CJK Ideograph>) 10027 0x7FDF 翟 (<CJK Ideograph>) 10028 0x5AE1 嫡 (<CJK Ideograph>) 10029 0x62B5 抵 (<CJK Ideograph>) 10030 0x5E95 底 (<CJK Ideograph>) 10031 0x5730 地 (<CJK Ideograph>) 10032 0x8482 蒂 (<CJK Ideograph>) 10033 0x7B2C 第 (<CJK Ideograph>) 10034 0x5E1D 帝 (<CJK Ideograph>) 10035 0x5F1F 弟 (<CJK Ideograph>) 10036 0x9012 递 (<CJK Ideograph>) 10037 0x7F14 缔 (<CJK Ideograph>) 10038 0x98A0 颠 (<CJK Ideograph>) 10039 0x6382 掂 (<CJK Ideograph>) 10040 0x6EC7 滇 (<CJK Ideograph>) 10041 0x7898 碘 (<CJK Ideograph>) 10042 0x70B9 点 (<CJK Ideograph>) 10043 0x5178 典 (<CJK Ideograph>) 10044 0x975B 靛 (<CJK Ideograph>) 10045 0x57AB 垫 (<CJK Ideograph>) 10046 0x7535 电 (<CJK Ideograph>) 10047 0x4F43 佃 (<CJK Ideograph>) 10048 0x7538 甸 (<CJK Ideograph>) 10049 0x5E97 店 (<CJK Ideograph>) 10050 0x60E6 惦 (<CJK Ideograph>) 10051 0x5960 奠 (<CJK Ideograph>) 10052 0x6DC0 淀 (<CJK Ideograph>) 10053 0x6BBF 殿 (<CJK Ideograph>) 10054 0x7889 碉 (<CJK Ideograph>) 10055 0x53FC 叼 (<CJK Ideograph>) 10056 0x96D5 雕 (<CJK Ideograph>) 10057 0x51CB 凋 (<CJK Ideograph>) 10058 0x5201 刁 (<CJK Ideograph>) 10059 0x6389 掉 (<CJK Ideograph>) 10060 0x540A 吊 (<CJK Ideograph>) 10061 0x9493 钓 (<CJK Ideograph>) 10062 0x8C03 调 (<CJK Ideograph>) 10063 0x8DCC 跌 (<CJK Ideograph>) 10064 0x7239 爹 (<CJK Ideograph>) 10065 0x789F 碟 (<CJK Ideograph>) 10066 0x8776 蝶 (<CJK Ideograph>) 10067 0x8FED 迭 (<CJK Ideograph>) 10068 0x8C0D 谍 (<CJK Ideograph>) 10069 0x53E0 叠 (<CJK Ideograph>) 10070 0x7993 禓 (<CJK Ideograph>) 10071 0x7994 禔 (<CJK Ideograph>) 10072 0x7995 禕 (<CJK Ideograph>) 10073 0x7996 禖 (<CJK Ideograph>) 10074 0x7997 禗 (<CJK Ideograph>) 10075 0x7998 禘 (<CJK Ideograph>) 10076 0x7999 禙 (<CJK Ideograph>) 10077 0x799B 禛 (<CJK Ideograph>) 10078 0x799C 禜 (<CJK Ideograph>) 10079 0x799D 禝 (<CJK Ideograph>) 10080 0x799E 禞 (<CJK Ideograph>) 10081 0x799F 禟 (<CJK Ideograph>) 10082 0x79A0 禠 (<CJK Ideograph>) 10083 0x79A1 禡 (<CJK Ideograph>) 10084 0x79A2 禢 (<CJK Ideograph>) 10085 0x79A3 禣 (<CJK Ideograph>) 10086 0x79A4 禤 (<CJK Ideograph>) 10087 0x79A5 禥 (<CJK Ideograph>) 10088 0x79A6 禦 (<CJK Ideograph>) 10089 0x79A8 禨 (<CJK Ideograph>) 10090 0x79A9 禩 (<CJK Ideograph>) 10091 0x79AA 禪 (<CJK Ideograph>) 10092 0x79AB 禫 (<CJK Ideograph>) 10093 0x79AC 禬 (<CJK Ideograph>) 10094 0x79AD 禭 (<CJK Ideograph>) 10095 0x79AE 禮 (<CJK Ideograph>) 10096 0x79AF 禯 (<CJK Ideograph>) 10097 0x79B0 禰 (<CJK Ideograph>) 10098 0x79B1 禱 (<CJK Ideograph>) 10099 0x79B2 禲 (<CJK Ideograph>) 10100 0x79B4 禴 (<CJK Ideograph>) 10101 0x79B5 禵 (<CJK Ideograph>) 10102 0x79B6 禶 (<CJK Ideograph>) 10103 0x79B7 禷 (<CJK Ideograph>) 10104 0x79B8 禸 (<CJK Ideograph>) 10105 0x79BC 禼 (<CJK Ideograph>) 10106 0x79BF 禿 (<CJK Ideograph>) 10107 0x79C2 秂 (<CJK Ideograph>) 10108 0x79C4 秄 (<CJK Ideograph>) 10109 0x79C5 秅 (<CJK Ideograph>) 10110 0x79C7 秇 (<CJK Ideograph>) 10111 0x79C8 秈 (<CJK Ideograph>) 10112 0x79CA 秊 (<CJK Ideograph>) 10113 0x79CC 秌 (<CJK Ideograph>) 10114 0x79CE 秎 (<CJK Ideograph>) 10115 0x79CF 秏 (<CJK Ideograph>) 10116 0x79D0 秐 (<CJK Ideograph>) 10117 0x79D3 秓 (<CJK Ideograph>) 10118 0x79D4 秔 (<CJK Ideograph>) 10119 0x79D6 秖 (<CJK Ideograph>) 10120 0x79D7 秗 (<CJK Ideograph>) 10121 0x79D9 秙 (<CJK Ideograph>) 10122 0x79DA 秚 (<CJK Ideograph>) 10123 0x79DB 秛 (<CJK Ideograph>) 10124 0x79DC 秜 (<CJK Ideograph>) 10125 0x79DD 秝 (<CJK Ideograph>) 10126 0x79DE 秞 (<CJK Ideograph>) 10127 0x79E0 秠 (<CJK Ideograph>) 10128 0x79E1 秡 (<CJK Ideograph>) 10129 0x79E2 秢 (<CJK Ideograph>) 10130 0x79E5 秥 (<CJK Ideograph>) 10131 0x79E8 秨 (<CJK Ideograph>) 10132 0x79EA 秪 (<CJK Ideograph>) 10133 0x79EC 秬 (<CJK Ideograph>) 10134 0x79EE 秮 (<CJK Ideograph>) 10135 0x79F1 秱 (<CJK Ideograph>) 10136 0x79F2 秲 (<CJK Ideograph>) 10137 0x79F3 秳 (<CJK Ideograph>) 10138 0x79F4 秴 (<CJK Ideograph>) 10139 0x79F5 秵 (<CJK Ideograph>) 10140 0x79F6 秶 (<CJK Ideograph>) 10141 0x79F7 秷 (<CJK Ideograph>) 10142 0x79F9 秹 (<CJK Ideograph>) 10143 0x79FA 秺 (<CJK Ideograph>) 10144 0x79FC 秼 (<CJK Ideograph>) 10145 0x79FE 秾 (<CJK Ideograph>) 10146 0x79FF 秿 (<CJK Ideograph>) 10147 0x7A01 稁 (<CJK Ideograph>) 10148 0x7A04 稄 (<CJK Ideograph>) 10149 0x7A05 稅 (<CJK Ideograph>) 10150 0x7A07 稇 (<CJK Ideograph>) 10151 0x7A08 稈 (<CJK Ideograph>) 10152 0x7A09 稉 (<CJK Ideograph>) 10153 0x7A0A 稊 (<CJK Ideograph>) 10154 0x7A0C 稌 (<CJK Ideograph>) 10155 0x7A0F 稏 (<CJK Ideograph>) 10156 0x7A10 稐 (<CJK Ideograph>) 10157 0x7A11 稑 (<CJK Ideograph>) 10158 0x7A12 稒 (<CJK Ideograph>) 10159 0x7A13 稓 (<CJK Ideograph>) 10160 0x7A15 稕 (<CJK Ideograph>) 10161 0x7A16 稖 (<CJK Ideograph>) 10162 0x7A18 稘 (<CJK Ideograph>) 10163 0x7A19 稙 (<CJK Ideograph>) 10164 0x7A1B 稛 (<CJK Ideograph>) 10165 0x7A1C 稜 (<CJK Ideograph>) 10166 0x4E01 丁 (<CJK Ideograph>) 10167 0x76EF 盯 (<CJK Ideograph>) 10168 0x53EE 叮 (<CJK Ideograph>) 10169 0x9489 钉 (<CJK Ideograph>) 10170 0x9876 顶 (<CJK Ideograph>) 10171 0x9F0E 鼎 (<CJK Ideograph>) 10172 0x952D 锭 (<CJK Ideograph>) 10173 0x5B9A 定 (<CJK Ideograph>) 10174 0x8BA2 订 (<CJK Ideograph>) 10175 0x4E22 丢 (<CJK Ideograph>) 10176 0x4E1C 东 (<CJK Ideograph>) 10177 0x51AC 冬 (<CJK Ideograph>) 10178 0x8463 董 (<CJK Ideograph>) 10179 0x61C2 懂 (<CJK Ideograph>) 10180 0x52A8 动 (<CJK Ideograph>) 10181 0x680B 栋 (<CJK Ideograph>) 10182 0x4F97 侗 (<CJK Ideograph>) 10183 0x606B 恫 (<CJK Ideograph>) 10184 0x51BB 冻 (<CJK Ideograph>) 10185 0x6D1E 洞 (<CJK Ideograph>) 10186 0x515C 兜 (<CJK Ideograph>) 10187 0x6296 抖 (<CJK Ideograph>) 10188 0x6597 斗 (<CJK Ideograph>) 10189 0x9661 陡 (<CJK Ideograph>) 10190 0x8C46 豆 (<CJK Ideograph>) 10191 0x9017 逗 (<CJK Ideograph>) 10192 0x75D8 痘 (<CJK Ideograph>) 10193 0x90FD 都 (<CJK Ideograph>) 10194 0x7763 督 (<CJK Ideograph>) 10195 0x6BD2 毒 (<CJK Ideograph>) 10196 0x728A 犊 (<CJK Ideograph>) 10197 0x72EC 独 (<CJK Ideograph>) 10198 0x8BFB 读 (<CJK Ideograph>) 10199 0x5835 堵 (<CJK Ideograph>) 10200 0x7779 睹 (<CJK Ideograph>) 10201 0x8D4C 赌 (<CJK Ideograph>) 10202 0x675C 杜 (<CJK Ideograph>) 10203 0x9540 镀 (<CJK Ideograph>) 10204 0x809A 肚 (<CJK Ideograph>) 10205 0x5EA6 度 (<CJK Ideograph>) 10206 0x6E21 渡 (<CJK Ideograph>) 10207 0x5992 妒 (<CJK Ideograph>) 10208 0x7AEF 端 (<CJK Ideograph>) 10209 0x77ED 短 (<CJK Ideograph>) 10210 0x953B 锻 (<CJK Ideograph>) 10211 0x6BB5 段 (<CJK Ideograph>) 10212 0x65AD 断 (<CJK Ideograph>) 10213 0x7F0E 缎 (<CJK Ideograph>) 10214 0x5806 堆 (<CJK Ideograph>) 10215 0x5151 兑 (<CJK Ideograph>) 10216 0x961F 队 (<CJK Ideograph>) 10217 0x5BF9 对 (<CJK Ideograph>) 10218 0x58A9 墩 (<CJK Ideograph>) 10219 0x5428 吨 (<CJK Ideograph>) 10220 0x8E72 蹲 (<CJK Ideograph>) 10221 0x6566 敦 (<CJK Ideograph>) 10222 0x987F 顿 (<CJK Ideograph>) 10223 0x56E4 囤 (<CJK Ideograph>) 10224 0x949D 钝 (<CJK Ideograph>) 10225 0x76FE 盾 (<CJK Ideograph>) 10226 0x9041 遁 (<CJK Ideograph>) 10227 0x6387 掇 (<CJK Ideograph>) 10228 0x54C6 哆 (<CJK Ideograph>) 10229 0x591A 多 (<CJK Ideograph>) 10230 0x593A 夺 (<CJK Ideograph>) 10231 0x579B 垛 (<CJK Ideograph>) 10232 0x8EB2 躲 (<CJK Ideograph>) 10233 0x6735 朵 (<CJK Ideograph>) 10234 0x8DFA 跺 (<CJK Ideograph>) 10235 0x8235 舵 (<CJK Ideograph>) 10236 0x5241 剁 (<CJK Ideograph>) 10237 0x60F0 惰 (<CJK Ideograph>) 10238 0x5815 堕 (<CJK Ideograph>) 10239 0x86FE 蛾 (<CJK Ideograph>) 10240 0x5CE8 峨 (<CJK Ideograph>) 10241 0x9E45 鹅 (<CJK Ideograph>) 10242 0x4FC4 俄 (<CJK Ideograph>) 10243 0x989D 额 (<CJK Ideograph>) 10244 0x8BB9 讹 (<CJK Ideograph>) 10245 0x5A25 娥 (<CJK Ideograph>) 10246 0x6076 恶 (<CJK Ideograph>) 10247 0x5384 厄 (<CJK Ideograph>) 10248 0x627C 扼 (<CJK Ideograph>) 10249 0x904F 遏 (<CJK Ideograph>) 10250 0x9102 鄂 (<CJK Ideograph>) 10251 0x997F 饿 (<CJK Ideograph>) 10252 0x6069 恩 (<CJK Ideograph>) 10253 0x800C 而 (<CJK Ideograph>) 10254 0x513F 儿 (<CJK Ideograph>) 10255 0x8033 耳 (<CJK Ideograph>) 10256 0x5C14 尔 (<CJK Ideograph>) 10257 0x9975 饵 (<CJK Ideograph>) 10258 0x6D31 洱 (<CJK Ideograph>) 10259 0x4E8C 二 (<CJK Ideograph>) 10260 0x7A1D 稝 (<CJK Ideograph>) 10261 0x7A1F 稟 (<CJK Ideograph>) 10262 0x7A21 稡 (<CJK Ideograph>) 10263 0x7A22 稢 (<CJK Ideograph>) 10264 0x7A24 稤 (<CJK Ideograph>) 10265 0x7A25 稥 (<CJK Ideograph>) 10266 0x7A26 稦 (<CJK Ideograph>) 10267 0x7A27 稧 (<CJK Ideograph>) 10268 0x7A28 稨 (<CJK Ideograph>) 10269 0x7A29 稩 (<CJK Ideograph>) 10270 0x7A2A 稪 (<CJK Ideograph>) 10271 0x7A2B 稫 (<CJK Ideograph>) 10272 0x7A2C 稬 (<CJK Ideograph>) 10273 0x7A2D 稭 (<CJK Ideograph>) 10274 0x7A2E 種 (<CJK Ideograph>) 10275 0x7A2F 稯 (<CJK Ideograph>) 10276 0x7A30 稰 (<CJK Ideograph>) 10277 0x7A31 稱 (<CJK Ideograph>) 10278 0x7A32 稲 (<CJK Ideograph>) 10279 0x7A34 稴 (<CJK Ideograph>) 10280 0x7A35 稵 (<CJK Ideograph>) 10281 0x7A36 稶 (<CJK Ideograph>) 10282 0x7A38 稸 (<CJK Ideograph>) 10283 0x7A3A 稺 (<CJK Ideograph>) 10284 0x7A3E 稾 (<CJK Ideograph>) 10285 0x7A40 穀 (<CJK Ideograph>) 10286 0x7A41 穁 (<CJK Ideograph>) 10287 0x7A42 穂 (<CJK Ideograph>) 10288 0x7A43 穃 (<CJK Ideograph>) 10289 0x7A44 穄 (<CJK Ideograph>) 10290 0x7A45 穅 (<CJK Ideograph>) 10291 0x7A47 穇 (<CJK Ideograph>) 10292 0x7A48 穈 (<CJK Ideograph>) 10293 0x7A49 穉 (<CJK Ideograph>) 10294 0x7A4A 穊 (<CJK Ideograph>) 10295 0x7A4B 穋 (<CJK Ideograph>) 10296 0x7A4C 穌 (<CJK Ideograph>) 10297 0x7A4D 積 (<CJK Ideograph>) 10298 0x7A4E 穎 (<CJK Ideograph>) 10299 0x7A4F 穏 (<CJK Ideograph>) 10300 0x7A50 穐 (<CJK Ideograph>) 10301 0x7A52 穒 (<CJK Ideograph>) 10302 0x7A53 穓 (<CJK Ideograph>) 10303 0x7A54 穔 (<CJK Ideograph>) 10304 0x7A55 穕 (<CJK Ideograph>) 10305 0x7A56 穖 (<CJK Ideograph>) 10306 0x7A58 穘 (<CJK Ideograph>) 10307 0x7A59 穙 (<CJK Ideograph>) 10308 0x7A5A 穚 (<CJK Ideograph>) 10309 0x7A5B 穛 (<CJK Ideograph>) 10310 0x7A5C 穜 (<CJK Ideograph>) 10311 0x7A5D 穝 (<CJK Ideograph>) 10312 0x7A5E 穞 (<CJK Ideograph>) 10313 0x7A5F 穟 (<CJK Ideograph>) 10314 0x7A60 穠 (<CJK Ideograph>) 10315 0x7A61 穡 (<CJK Ideograph>) 10316 0x7A62 穢 (<CJK Ideograph>) 10317 0x7A63 穣 (<CJK Ideograph>) 10318 0x7A64 穤 (<CJK Ideograph>) 10319 0x7A65 穥 (<CJK Ideograph>) 10320 0x7A66 穦 (<CJK Ideograph>) 10321 0x7A67 穧 (<CJK Ideograph>) 10322 0x7A68 穨 (<CJK Ideograph>) 10323 0x7A69 穩 (<CJK Ideograph>) 10324 0x7A6A 穪 (<CJK Ideograph>) 10325 0x7A6B 穫 (<CJK Ideograph>) 10326 0x7A6C 穬 (<CJK Ideograph>) 10327 0x7A6D 穭 (<CJK Ideograph>) 10328 0x7A6E 穮 (<CJK Ideograph>) 10329 0x7A6F 穯 (<CJK Ideograph>) 10330 0x7A71 穱 (<CJK Ideograph>) 10331 0x7A72 穲 (<CJK Ideograph>) 10332 0x7A73 穳 (<CJK Ideograph>) 10333 0x7A75 穵 (<CJK Ideograph>) 10334 0x7A7B 穻 (<CJK Ideograph>) 10335 0x7A7C 穼 (<CJK Ideograph>) 10336 0x7A7D 穽 (<CJK Ideograph>) 10337 0x7A7E 穾 (<CJK Ideograph>) 10338 0x7A82 窂 (<CJK Ideograph>) 10339 0x7A85 窅 (<CJK Ideograph>) 10340 0x7A87 窇 (<CJK Ideograph>) 10341 0x7A89 窉 (<CJK Ideograph>) 10342 0x7A8A 窊 (<CJK Ideograph>) 10343 0x7A8B 窋 (<CJK Ideograph>) 10344 0x7A8C 窌 (<CJK Ideograph>) 10345 0x7A8E 窎 (<CJK Ideograph>) 10346 0x7A8F 窏 (<CJK Ideograph>) 10347 0x7A90 窐 (<CJK Ideograph>) 10348 0x7A93 窓 (<CJK Ideograph>) 10349 0x7A94 窔 (<CJK Ideograph>) 10350 0x7A99 窙 (<CJK Ideograph>) 10351 0x7A9A 窚 (<CJK Ideograph>) 10352 0x7A9B 窛 (<CJK Ideograph>) 10353 0x7A9E 窞 (<CJK Ideograph>) 10354 0x7AA1 窡 (<CJK Ideograph>) 10355 0x7AA2 窢 (<CJK Ideograph>) 10356 0x8D30 贰 (<CJK Ideograph>) 10357 0x53D1 发 (<CJK Ideograph>) 10358 0x7F5A 罚 (<CJK Ideograph>) 10359 0x7B4F 筏 (<CJK Ideograph>) 10360 0x4F10 伐 (<CJK Ideograph>) 10361 0x4E4F 乏 (<CJK Ideograph>) 10362 0x9600 阀 (<CJK Ideograph>) 10363 0x6CD5 法 (<CJK Ideograph>) 10364 0x73D0 珐 (<CJK Ideograph>) 10365 0x85E9 藩 (<CJK Ideograph>) 10366 0x5E06 帆 (<CJK Ideograph>) 10367 0x756A 番 (<CJK Ideograph>) 10368 0x7FFB 翻 (<CJK Ideograph>) 10369 0x6A0A 樊 (<CJK Ideograph>) 10370 0x77FE 矾 (<CJK Ideograph>) 10371 0x9492 钒 (<CJK Ideograph>) 10372 0x7E41 繁 (<CJK Ideograph>) 10373 0x51E1 凡 (<CJK Ideograph>) 10374 0x70E6 烦 (<CJK Ideograph>) 10375 0x53CD 反 (<CJK Ideograph>) 10376 0x8FD4 返 (<CJK Ideograph>) 10377 0x8303 范 (<CJK Ideograph>) 10378 0x8D29 贩 (<CJK Ideograph>) 10379 0x72AF 犯 (<CJK Ideograph>) 10380 0x996D 饭 (<CJK Ideograph>) 10381 0x6CDB 泛 (<CJK Ideograph>) 10382 0x574A 坊 (<CJK Ideograph>) 10383 0x82B3 芳 (<CJK Ideograph>) 10384 0x65B9 方 (<CJK Ideograph>) 10385 0x80AA 肪 (<CJK Ideograph>) 10386 0x623F 房 (<CJK Ideograph>) 10387 0x9632 防 (<CJK Ideograph>) 10388 0x59A8 妨 (<CJK Ideograph>) 10389 0x4EFF 仿 (<CJK Ideograph>) 10390 0x8BBF 访 (<CJK Ideograph>) 10391 0x7EBA 纺 (<CJK Ideograph>) 10392 0x653E 放 (<CJK Ideograph>) 10393 0x83F2 菲 (<CJK Ideograph>) 10394 0x975E 非 (<CJK Ideograph>) 10395 0x5561 啡 (<CJK Ideograph>) 10396 0x98DE 飞 (<CJK Ideograph>) 10397 0x80A5 肥 (<CJK Ideograph>) 10398 0x532A 匪 (<CJK Ideograph>) 10399 0x8BFD 诽 (<CJK Ideograph>) 10400 0x5420 吠 (<CJK Ideograph>) 10401 0x80BA 肺 (<CJK Ideograph>) 10402 0x5E9F 废 (<CJK Ideograph>) 10403 0x6CB8 沸 (<CJK Ideograph>) 10404 0x8D39 费 (<CJK Ideograph>) 10405 0x82AC 芬 (<CJK Ideograph>) 10406 0x915A 酚 (<CJK Ideograph>) 10407 0x5429 吩 (<CJK Ideograph>) 10408 0x6C1B 氛 (<CJK Ideograph>) 10409 0x5206 分 (<CJK Ideograph>) 10410 0x7EB7 纷 (<CJK Ideograph>) 10411 0x575F 坟 (<CJK Ideograph>) 10412 0x711A 焚 (<CJK Ideograph>) 10413 0x6C7E 汾 (<CJK Ideograph>) 10414 0x7C89 粉 (<CJK Ideograph>) 10415 0x594B 奋 (<CJK Ideograph>) 10416 0x4EFD 份 (<CJK Ideograph>) 10417 0x5FFF 忿 (<CJK Ideograph>) 10418 0x6124 愤 (<CJK Ideograph>) 10419 0x7CAA 粪 (<CJK Ideograph>) 10420 0x4E30 丰 (<CJK Ideograph>) 10421 0x5C01 封 (<CJK Ideograph>) 10422 0x67AB 枫 (<CJK Ideograph>) 10423 0x8702 蜂 (<CJK Ideograph>) 10424 0x5CF0 峰 (<CJK Ideograph>) 10425 0x950B 锋 (<CJK Ideograph>) 10426 0x98CE 风 (<CJK Ideograph>) 10427 0x75AF 疯 (<CJK Ideograph>) 10428 0x70FD 烽 (<CJK Ideograph>) 10429 0x9022 逢 (<CJK Ideograph>) 10430 0x51AF 冯 (<CJK Ideograph>) 10431 0x7F1D 缝 (<CJK Ideograph>) 10432 0x8BBD 讽 (<CJK Ideograph>) 10433 0x5949 奉 (<CJK Ideograph>) 10434 0x51E4 凤 (<CJK Ideograph>) 10435 0x4F5B 佛 (<CJK Ideograph>) 10436 0x5426 否 (<CJK Ideograph>) 10437 0x592B 夫 (<CJK Ideograph>) 10438 0x6577 敷 (<CJK Ideograph>) 10439 0x80A4 肤 (<CJK Ideograph>) 10440 0x5B75 孵 (<CJK Ideograph>) 10441 0x6276 扶 (<CJK Ideograph>) 10442 0x62C2 拂 (<CJK Ideograph>) 10443 0x8F90 辐 (<CJK Ideograph>) 10444 0x5E45 幅 (<CJK Ideograph>) 10445 0x6C1F 氟 (<CJK Ideograph>) 10446 0x7B26 符 (<CJK Ideograph>) 10447 0x4F0F 伏 (<CJK Ideograph>) 10448 0x4FD8 俘 (<CJK Ideograph>) 10449 0x670D 服 (<CJK Ideograph>) 10450 0x7AA3 窣 (<CJK Ideograph>) 10451 0x7AA4 窤 (<CJK Ideograph>) 10452 0x7AA7 窧 (<CJK Ideograph>) 10453 0x7AA9 窩 (<CJK Ideograph>) 10454 0x7AAA 窪 (<CJK Ideograph>) 10455 0x7AAB 窫 (<CJK Ideograph>) 10456 0x7AAE 窮 (<CJK Ideograph>) 10457 0x7AAF 窯 (<CJK Ideograph>) 10458 0x7AB0 窰 (<CJK Ideograph>) 10459 0x7AB1 窱 (<CJK Ideograph>) 10460 0x7AB2 窲 (<CJK Ideograph>) 10461 0x7AB4 窴 (<CJK Ideograph>) 10462 0x7AB5 窵 (<CJK Ideograph>) 10463 0x7AB6 窶 (<CJK Ideograph>) 10464 0x7AB7 窷 (<CJK Ideograph>) 10465 0x7AB8 窸 (<CJK Ideograph>) 10466 0x7AB9 窹 (<CJK Ideograph>) 10467 0x7ABA 窺 (<CJK Ideograph>) 10468 0x7ABB 窻 (<CJK Ideograph>) 10469 0x7ABC 窼 (<CJK Ideograph>) 10470 0x7ABD 窽 (<CJK Ideograph>) 10471 0x7ABE 窾 (<CJK Ideograph>) 10472 0x7AC0 竀 (<CJK Ideograph>) 10473 0x7AC1 竁 (<CJK Ideograph>) 10474 0x7AC2 竂 (<CJK Ideograph>) 10475 0x7AC3 竃 (<CJK Ideograph>) 10476 0x7AC4 竄 (<CJK Ideograph>) 10477 0x7AC5 竅 (<CJK Ideograph>) 10478 0x7AC6 竆 (<CJK Ideograph>) 10479 0x7AC7 竇 (<CJK Ideograph>) 10480 0x7AC8 竈 (<CJK Ideograph>) 10481 0x7AC9 竉 (<CJK Ideograph>) 10482 0x7ACA 竊 (<CJK Ideograph>) 10483 0x7ACC 竌 (<CJK Ideograph>) 10484 0x7ACD 竍 (<CJK Ideograph>) 10485 0x7ACE 竎 (<CJK Ideograph>) 10486 0x7ACF 竏 (<CJK Ideograph>) 10487 0x7AD0 竐 (<CJK Ideograph>) 10488 0x7AD1 竑 (<CJK Ideograph>) 10489 0x7AD2 竒 (<CJK Ideograph>) 10490 0x7AD3 竓 (<CJK Ideograph>) 10491 0x7AD4 竔 (<CJK Ideograph>) 10492 0x7AD5 竕 (<CJK Ideograph>) 10493 0x7AD7 竗 (<CJK Ideograph>) 10494 0x7AD8 竘 (<CJK Ideograph>) 10495 0x7ADA 竚 (<CJK Ideograph>) 10496 0x7ADB 竛 (<CJK Ideograph>) 10497 0x7ADC 竜 (<CJK Ideograph>) 10498 0x7ADD 竝 (<CJK Ideograph>) 10499 0x7AE1 竡 (<CJK Ideograph>) 10500 0x7AE2 竢 (<CJK Ideograph>) 10501 0x7AE4 竤 (<CJK Ideograph>) 10502 0x7AE7 竧 (<CJK Ideograph>) 10503 0x7AE8 竨 (<CJK Ideograph>) 10504 0x7AE9 竩 (<CJK Ideograph>) 10505 0x7AEA 竪 (<CJK Ideograph>) 10506 0x7AEB 竫 (<CJK Ideograph>) 10507 0x7AEC 竬 (<CJK Ideograph>) 10508 0x7AEE 竮 (<CJK Ideograph>) 10509 0x7AF0 竰 (<CJK Ideograph>) 10510 0x7AF1 竱 (<CJK Ideograph>) 10511 0x7AF2 竲 (<CJK Ideograph>) 10512 0x7AF3 竳 (<CJK Ideograph>) 10513 0x7AF4 竴 (<CJK Ideograph>) 10514 0x7AF5 竵 (<CJK Ideograph>) 10515 0x7AF6 競 (<CJK Ideograph>) 10516 0x7AF7 竷 (<CJK Ideograph>) 10517 0x7AF8 竸 (<CJK Ideograph>) 10518 0x7AFB 竻 (<CJK Ideograph>) 10519 0x7AFC 竼 (<CJK Ideograph>) 10520 0x7AFE 竾 (<CJK Ideograph>) 10521 0x7B00 笀 (<CJK Ideograph>) 10522 0x7B01 笁 (<CJK Ideograph>) 10523 0x7B02 笂 (<CJK Ideograph>) 10524 0x7B05 笅 (<CJK Ideograph>) 10525 0x7B07 笇 (<CJK Ideograph>) 10526 0x7B09 笉 (<CJK Ideograph>) 10527 0x7B0C 笌 (<CJK Ideograph>) 10528 0x7B0D 笍 (<CJK Ideograph>) 10529 0x7B0E 笎 (<CJK Ideograph>) 10530 0x7B10 笐 (<CJK Ideograph>) 10531 0x7B12 笒 (<CJK Ideograph>) 10532 0x7B13 笓 (<CJK Ideograph>) 10533 0x7B16 笖 (<CJK Ideograph>) 10534 0x7B17 笗 (<CJK Ideograph>) 10535 0x7B18 笘 (<CJK Ideograph>) 10536 0x7B1A 笚 (<CJK Ideograph>) 10537 0x7B1C 笜 (<CJK Ideograph>) 10538 0x7B1D 笝 (<CJK Ideograph>) 10539 0x7B1F 笟 (<CJK Ideograph>) 10540 0x7B21 笡 (<CJK Ideograph>) 10541 0x7B22 笢 (<CJK Ideograph>) 10542 0x7B23 笣 (<CJK Ideograph>) 10543 0x7B27 笧 (<CJK Ideograph>) 10544 0x7B29 笩 (<CJK Ideograph>) 10545 0x7B2D 笭 (<CJK Ideograph>) 10546 0x6D6E 浮 (<CJK Ideograph>) 10547 0x6DAA 涪 (<CJK Ideograph>) 10548 0x798F 福 (<CJK Ideograph>) 10549 0x88B1 袱 (<CJK Ideograph>) 10550 0x5F17 弗 (<CJK Ideograph>) 10551 0x752B 甫 (<CJK Ideograph>) 10552 0x629A 抚 (<CJK Ideograph>) 10553 0x8F85 辅 (<CJK Ideograph>) 10554 0x4FEF 俯 (<CJK Ideograph>) 10555 0x91DC 釜 (<CJK Ideograph>) 10556 0x65A7 斧 (<CJK Ideograph>) 10557 0x812F 脯 (<CJK Ideograph>) 10558 0x8151 腑 (<CJK Ideograph>) 10559 0x5E9C 府 (<CJK Ideograph>) 10560 0x8150 腐 (<CJK Ideograph>) 10561 0x8D74 赴 (<CJK Ideograph>) 10562 0x526F 副 (<CJK Ideograph>) 10563 0x8986 覆 (<CJK Ideograph>) 10564 0x8D4B 赋 (<CJK Ideograph>) 10565 0x590D 复 (<CJK Ideograph>) 10566 0x5085 傅 (<CJK Ideograph>) 10567 0x4ED8 付 (<CJK Ideograph>) 10568 0x961C 阜 (<CJK Ideograph>) 10569 0x7236 父 (<CJK Ideograph>) 10570 0x8179 腹 (<CJK Ideograph>) 10571 0x8D1F 负 (<CJK Ideograph>) 10572 0x5BCC 富 (<CJK Ideograph>) 10573 0x8BA3 讣 (<CJK Ideograph>) 10574 0x9644 附 (<CJK Ideograph>) 10575 0x5987 妇 (<CJK Ideograph>) 10576 0x7F1A 缚 (<CJK Ideograph>) 10577 0x5490 咐 (<CJK Ideograph>) 10578 0x5676 噶 (<CJK Ideograph>) 10579 0x560E 嘎 (<CJK Ideograph>) 10580 0x8BE5 该 (<CJK Ideograph>) 10581 0x6539 改 (<CJK Ideograph>) 10582 0x6982 概 (<CJK Ideograph>) 10583 0x9499 钙 (<CJK Ideograph>) 10584 0x76D6 盖 (<CJK Ideograph>) 10585 0x6E89 溉 (<CJK Ideograph>) 10586 0x5E72 干 (<CJK Ideograph>) 10587 0x7518 甘 (<CJK Ideograph>) 10588 0x6746 杆 (<CJK Ideograph>) 10589 0x67D1 柑 (<CJK Ideograph>) 10590 0x7AFF 竿 (<CJK Ideograph>) 10591 0x809D 肝 (<CJK Ideograph>) 10592 0x8D76 赶 (<CJK Ideograph>) 10593 0x611F 感 (<CJK Ideograph>) 10594 0x79C6 秆 (<CJK Ideograph>) 10595 0x6562 敢 (<CJK Ideograph>) 10596 0x8D63 赣 (<CJK Ideograph>) 10597 0x5188 冈 (<CJK Ideograph>) 10598 0x521A 刚 (<CJK Ideograph>) 10599 0x94A2 钢 (<CJK Ideograph>) 10600 0x7F38 缸 (<CJK Ideograph>) 10601 0x809B 肛 (<CJK Ideograph>) 10602 0x7EB2 纲 (<CJK Ideograph>) 10603 0x5C97 岗 (<CJK Ideograph>) 10604 0x6E2F 港 (<CJK Ideograph>) 10605 0x6760 杠 (<CJK Ideograph>) 10606 0x7BD9 篙 (<CJK Ideograph>) 10607 0x768B 皋 (<CJK Ideograph>) 10608 0x9AD8 高 (<CJK Ideograph>) 10609 0x818F 膏 (<CJK Ideograph>) 10610 0x7F94 羔 (<CJK Ideograph>) 10611 0x7CD5 糕 (<CJK Ideograph>) 10612 0x641E 搞 (<CJK Ideograph>) 10613 0x9550 镐 (<CJK Ideograph>) 10614 0x7A3F 稿 (<CJK Ideograph>) 10615 0x544A 告 (<CJK Ideograph>) 10616 0x54E5 哥 (<CJK Ideograph>) 10617 0x6B4C 歌 (<CJK Ideograph>) 10618 0x6401 搁 (<CJK Ideograph>) 10619 0x6208 戈 (<CJK Ideograph>) 10620 0x9E3D 鸽 (<CJK Ideograph>) 10621 0x80F3 胳 (<CJK Ideograph>) 10622 0x7599 疙 (<CJK Ideograph>) 10623 0x5272 割 (<CJK Ideograph>) 10624 0x9769 革 (<CJK Ideograph>) 10625 0x845B 葛 (<CJK Ideograph>) 10626 0x683C 格 (<CJK Ideograph>) 10627 0x86E4 蛤 (<CJK Ideograph>) 10628 0x9601 阁 (<CJK Ideograph>) 10629 0x9694 隔 (<CJK Ideograph>) 10630 0x94EC 铬 (<CJK Ideograph>) 10631 0x4E2A 个 (<CJK Ideograph>) 10632 0x5404 各 (<CJK Ideograph>) 10633 0x7ED9 给 (<CJK Ideograph>) 10634 0x6839 根 (<CJK Ideograph>) 10635 0x8DDF 跟 (<CJK Ideograph>) 10636 0x8015 耕 (<CJK Ideograph>) 10637 0x66F4 更 (<CJK Ideograph>) 10638 0x5E9A 庚 (<CJK Ideograph>) 10639 0x7FB9 羹 (<CJK Ideograph>) 10640 0x7B2F 笯 (<CJK Ideograph>) 10641 0x7B30 笰 (<CJK Ideograph>) 10642 0x7B32 笲 (<CJK Ideograph>) 10643 0x7B34 笴 (<CJK Ideograph>) 10644 0x7B35 笵 (<CJK Ideograph>) 10645 0x7B36 笶 (<CJK Ideograph>) 10646 0x7B37 笷 (<CJK Ideograph>) 10647 0x7B39 笹 (<CJK Ideograph>) 10648 0x7B3B 笻 (<CJK Ideograph>) 10649 0x7B3D 笽 (<CJK Ideograph>) 10650 0x7B3F 笿 (<CJK Ideograph>) 10651 0x7B40 筀 (<CJK Ideograph>) 10652 0x7B41 筁 (<CJK Ideograph>) 10653 0x7B42 筂 (<CJK Ideograph>) 10654 0x7B43 筃 (<CJK Ideograph>) 10655 0x7B44 筄 (<CJK Ideograph>) 10656 0x7B46 筆 (<CJK Ideograph>) 10657 0x7B48 筈 (<CJK Ideograph>) 10658 0x7B4A 筊 (<CJK Ideograph>) 10659 0x7B4D 筍 (<CJK Ideograph>) 10660 0x7B4E 筎 (<CJK Ideograph>) 10661 0x7B53 筓 (<CJK Ideograph>) 10662 0x7B55 筕 (<CJK Ideograph>) 10663 0x7B57 筗 (<CJK Ideograph>) 10664 0x7B59 筙 (<CJK Ideograph>) 10665 0x7B5C 筜 (<CJK Ideograph>) 10666 0x7B5E 筞 (<CJK Ideograph>) 10667 0x7B5F 筟 (<CJK Ideograph>) 10668 0x7B61 筡 (<CJK Ideograph>) 10669 0x7B63 筣 (<CJK Ideograph>) 10670 0x7B64 筤 (<CJK Ideograph>) 10671 0x7B65 筥 (<CJK Ideograph>) 10672 0x7B66 筦 (<CJK Ideograph>) 10673 0x7B67 筧 (<CJK Ideograph>) 10674 0x7B68 筨 (<CJK Ideograph>) 10675 0x7B69 筩 (<CJK Ideograph>) 10676 0x7B6A 筪 (<CJK Ideograph>) 10677 0x7B6B 筫 (<CJK Ideograph>) 10678 0x7B6C 筬 (<CJK Ideograph>) 10679 0x7B6D 筭 (<CJK Ideograph>) 10680 0x7B6F 筯 (<CJK Ideograph>) 10681 0x7B70 筰 (<CJK Ideograph>) 10682 0x7B73 筳 (<CJK Ideograph>) 10683 0x7B74 筴 (<CJK Ideograph>) 10684 0x7B76 筶 (<CJK Ideograph>) 10685 0x7B78 筸 (<CJK Ideograph>) 10686 0x7B7A 筺 (<CJK Ideograph>) 10687 0x7B7C 筼 (<CJK Ideograph>) 10688 0x7B7D 筽 (<CJK Ideograph>) 10689 0x7B7F 筿 (<CJK Ideograph>) 10690 0x7B81 箁 (<CJK Ideograph>) 10691 0x7B82 箂 (<CJK Ideograph>) 10692 0x7B83 箃 (<CJK Ideograph>) 10693 0x7B84 箄 (<CJK Ideograph>) 10694 0x7B86 箆 (<CJK Ideograph>) 10695 0x7B87 箇 (<CJK Ideograph>) 10696 0x7B88 箈 (<CJK Ideograph>) 10697 0x7B89 箉 (<CJK Ideograph>) 10698 0x7B8A 箊 (<CJK Ideograph>) 10699 0x7B8B 箋 (<CJK Ideograph>) 10700 0x7B8C 箌 (<CJK Ideograph>) 10701 0x7B8E 箎 (<CJK Ideograph>) 10702 0x7B8F 箏 (<CJK Ideograph>) 10703 0x7B91 箑 (<CJK Ideograph>) 10704 0x7B92 箒 (<CJK Ideograph>) 10705 0x7B93 箓 (<CJK Ideograph>) 10706 0x7B96 箖 (<CJK Ideograph>) 10707 0x7B98 箘 (<CJK Ideograph>) 10708 0x7B99 箙 (<CJK Ideograph>) 10709 0x7B9A 箚 (<CJK Ideograph>) 10710 0x7B9B 箛 (<CJK Ideograph>) 10711 0x7B9E 箞 (<CJK Ideograph>) 10712 0x7B9F 箟 (<CJK Ideograph>) 10713 0x7BA0 箠 (<CJK Ideograph>) 10714 0x7BA3 箣 (<CJK Ideograph>) 10715 0x7BA4 箤 (<CJK Ideograph>) 10716 0x7BA5 箥 (<CJK Ideograph>) 10717 0x7BAE 箮 (<CJK Ideograph>) 10718 0x7BAF 箯 (<CJK Ideograph>) 10719 0x7BB0 箰 (<CJK Ideograph>) 10720 0x7BB2 箲 (<CJK Ideograph>) 10721 0x7BB3 箳 (<CJK Ideograph>) 10722 0x7BB5 箵 (<CJK Ideograph>) 10723 0x7BB6 箶 (<CJK Ideograph>) 10724 0x7BB7 箷 (<CJK Ideograph>) 10725 0x7BB9 箹 (<CJK Ideograph>) 10726 0x7BBA 箺 (<CJK Ideograph>) 10727 0x7BBB 箻 (<CJK Ideograph>) 10728 0x7BBC 箼 (<CJK Ideograph>) 10729 0x7BBD 箽 (<CJK Ideograph>) 10730 0x7BBE 箾 (<CJK Ideograph>) 10731 0x7BBF 箿 (<CJK Ideograph>) 10732 0x7BC0 節 (<CJK Ideograph>) 10733 0x7BC2 篂 (<CJK Ideograph>) 10734 0x7BC3 篃 (<CJK Ideograph>) 10735 0x7BC4 範 (<CJK Ideograph>) 10736 0x57C2 埂 (<CJK Ideograph>) 10737 0x803F 耿 (<CJK Ideograph>) 10738 0x6897 梗 (<CJK Ideograph>) 10739 0x5DE5 工 (<CJK Ideograph>) 10740 0x653B 攻 (<CJK Ideograph>) 10741 0x529F 功 (<CJK Ideograph>) 10742 0x606D 恭 (<CJK Ideograph>) 10743 0x9F9A 龚 (<CJK Ideograph>) 10744 0x4F9B 供 (<CJK Ideograph>) 10745 0x8EAC 躬 (<CJK Ideograph>) 10746 0x516C 公 (<CJK Ideograph>) 10747 0x5BAB 宫 (<CJK Ideograph>) 10748 0x5F13 弓 (<CJK Ideograph>) 10749 0x5DE9 巩 (<CJK Ideograph>) 10750 0x6C5E 汞 (<CJK Ideograph>) 10751 0x62F1 拱 (<CJK Ideograph>) 10752 0x8D21 贡 (<CJK Ideograph>) 10753 0x5171 共 (<CJK Ideograph>) 10754 0x94A9 钩 (<CJK Ideograph>) 10755 0x52FE 勾 (<CJK Ideograph>) 10756 0x6C9F 沟 (<CJK Ideograph>) 10757 0x82DF 苟 (<CJK Ideograph>) 10758 0x72D7 狗 (<CJK Ideograph>) 10759 0x57A2 垢 (<CJK Ideograph>) 10760 0x6784 构 (<CJK Ideograph>) 10761 0x8D2D 购 (<CJK Ideograph>) 10762 0x591F 够 (<CJK Ideograph>) 10763 0x8F9C 辜 (<CJK Ideograph>) 10764 0x83C7 菇 (<CJK Ideograph>) 10765 0x5495 咕 (<CJK Ideograph>) 10766 0x7B8D 箍 (<CJK Ideograph>) 10767 0x4F30 估 (<CJK Ideograph>) 10768 0x6CBD 沽 (<CJK Ideograph>) 10769 0x5B64 孤 (<CJK Ideograph>) 10770 0x59D1 姑 (<CJK Ideograph>) 10771 0x9F13 鼓 (<CJK Ideograph>) 10772 0x53E4 古 (<CJK Ideograph>) 10773 0x86CA 蛊 (<CJK Ideograph>) 10774 0x9AA8 骨 (<CJK Ideograph>) 10775 0x8C37 谷 (<CJK Ideograph>) 10776 0x80A1 股 (<CJK Ideograph>) 10777 0x6545 故 (<CJK Ideograph>) 10778 0x987E 顾 (<CJK Ideograph>) 10779 0x56FA 固 (<CJK Ideograph>) 10780 0x96C7 雇 (<CJK Ideograph>) 10781 0x522E 刮 (<CJK Ideograph>) 10782 0x74DC 瓜 (<CJK Ideograph>) 10783 0x5250 剐 (<CJK Ideograph>) 10784 0x5BE1 寡 (<CJK Ideograph>) 10785 0x6302 挂 (<CJK Ideograph>) 10786 0x8902 褂 (<CJK Ideograph>) 10787 0x4E56 乖 (<CJK Ideograph>) 10788 0x62D0 拐 (<CJK Ideograph>) 10789 0x602A 怪 (<CJK Ideograph>) 10790 0x68FA 棺 (<CJK Ideograph>) 10791 0x5173 关 (<CJK Ideograph>) 10792 0x5B98 官 (<CJK Ideograph>) 10793 0x51A0 冠 (<CJK Ideograph>) 10794 0x89C2 观 (<CJK Ideograph>) 10795 0x7BA1 管 (<CJK Ideograph>) 10796 0x9986 馆 (<CJK Ideograph>) 10797 0x7F50 罐 (<CJK Ideograph>) 10798 0x60EF 惯 (<CJK Ideograph>) 10799 0x704C 灌 (<CJK Ideograph>) 10800 0x8D2F 贯 (<CJK Ideograph>) 10801 0x5149 光 (<CJK Ideograph>) 10802 0x5E7F 广 (<CJK Ideograph>) 10803 0x901B 逛 (<CJK Ideograph>) 10804 0x7470 瑰 (<CJK Ideograph>) 10805 0x89C4 规 (<CJK Ideograph>) 10806 0x572D 圭 (<CJK Ideograph>) 10807 0x7845 硅 (<CJK Ideograph>) 10808 0x5F52 归 (<CJK Ideograph>) 10809 0x9F9F 龟 (<CJK Ideograph>) 10810 0x95FA 闺 (<CJK Ideograph>) 10811 0x8F68 轨 (<CJK Ideograph>) 10812 0x9B3C 鬼 (<CJK Ideograph>) 10813 0x8BE1 诡 (<CJK Ideograph>) 10814 0x7678 癸 (<CJK Ideograph>) 10815 0x6842 桂 (<CJK Ideograph>) 10816 0x67DC 柜 (<CJK Ideograph>) 10817 0x8DEA 跪 (<CJK Ideograph>) 10818 0x8D35 贵 (<CJK Ideograph>) 10819 0x523D 刽 (<CJK Ideograph>) 10820 0x8F8A 辊 (<CJK Ideograph>) 10821 0x6EDA 滚 (<CJK Ideograph>) 10822 0x68CD 棍 (<CJK Ideograph>) 10823 0x9505 锅 (<CJK Ideograph>) 10824 0x90ED 郭 (<CJK Ideograph>) 10825 0x56FD 国 (<CJK Ideograph>) 10826 0x679C 果 (<CJK Ideograph>) 10827 0x88F9 裹 (<CJK Ideograph>) 10828 0x8FC7 过 (<CJK Ideograph>) 10829 0x54C8 哈 (<CJK Ideograph>) 10830 0x7BC5 篅 (<CJK Ideograph>) 10831 0x7BC8 篈 (<CJK Ideograph>) 10832 0x7BC9 築 (<CJK Ideograph>) 10833 0x7BCA 篊 (<CJK Ideograph>) 10834 0x7BCB 篋 (<CJK Ideograph>) 10835 0x7BCD 篍 (<CJK Ideograph>) 10836 0x7BCE 篎 (<CJK Ideograph>) 10837 0x7BCF 篏 (<CJK Ideograph>) 10838 0x7BD0 篐 (<CJK Ideograph>) 10839 0x7BD2 篒 (<CJK Ideograph>) 10840 0x7BD4 篔 (<CJK Ideograph>) 10841 0x7BD5 篕 (<CJK Ideograph>) 10842 0x7BD6 篖 (<CJK Ideograph>) 10843 0x7BD7 篗 (<CJK Ideograph>) 10844 0x7BD8 篘 (<CJK Ideograph>) 10845 0x7BDB 篛 (<CJK Ideograph>) 10846 0x7BDC 篜 (<CJK Ideograph>) 10847 0x7BDE 篞 (<CJK Ideograph>) 10848 0x7BDF 篟 (<CJK Ideograph>) 10849 0x7BE0 篠 (<CJK Ideograph>) 10850 0x7BE2 篢 (<CJK Ideograph>) 10851 0x7BE3 篣 (<CJK Ideograph>) 10852 0x7BE4 篤 (<CJK Ideograph>) 10853 0x7BE7 篧 (<CJK Ideograph>) 10854 0x7BE8 篨 (<CJK Ideograph>) 10855 0x7BE9 篩 (<CJK Ideograph>) 10856 0x7BEB 篫 (<CJK Ideograph>) 10857 0x7BEC 篬 (<CJK Ideograph>) 10858 0x7BED 篭 (<CJK Ideograph>) 10859 0x7BEF 篯 (<CJK Ideograph>) 10860 0x7BF0 篰 (<CJK Ideograph>) 10861 0x7BF2 篲 (<CJK Ideograph>) 10862 0x7BF3 篳 (<CJK Ideograph>) 10863 0x7BF4 篴 (<CJK Ideograph>) 10864 0x7BF5 篵 (<CJK Ideograph>) 10865 0x7BF6 篶 (<CJK Ideograph>) 10866 0x7BF8 篸 (<CJK Ideograph>) 10867 0x7BF9 篹 (<CJK Ideograph>) 10868 0x7BFA 篺 (<CJK Ideograph>) 10869 0x7BFB 篻 (<CJK Ideograph>) 10870 0x7BFD 篽 (<CJK Ideograph>) 10871 0x7BFF 篿 (<CJK Ideograph>) 10872 0x7C00 簀 (<CJK Ideograph>) 10873 0x7C01 簁 (<CJK Ideograph>) 10874 0x7C02 簂 (<CJK Ideograph>) 10875 0x7C03 簃 (<CJK Ideograph>) 10876 0x7C04 簄 (<CJK Ideograph>) 10877 0x7C05 簅 (<CJK Ideograph>) 10878 0x7C06 簆 (<CJK Ideograph>) 10879 0x7C08 簈 (<CJK Ideograph>) 10880 0x7C09 簉 (<CJK Ideograph>) 10881 0x7C0A 簊 (<CJK Ideograph>) 10882 0x7C0D 簍 (<CJK Ideograph>) 10883 0x7C0E 簎 (<CJK Ideograph>) 10884 0x7C10 簐 (<CJK Ideograph>) 10885 0x7C11 簑 (<CJK Ideograph>) 10886 0x7C12 簒 (<CJK Ideograph>) 10887 0x7C13 簓 (<CJK Ideograph>) 10888 0x7C14 簔 (<CJK Ideograph>) 10889 0x7C15 簕 (<CJK Ideograph>) 10890 0x7C17 簗 (<CJK Ideograph>) 10891 0x7C18 簘 (<CJK Ideograph>) 10892 0x7C19 簙 (<CJK Ideograph>) 10893 0x7C1A 簚 (<CJK Ideograph>) 10894 0x7C1B 簛 (<CJK Ideograph>) 10895 0x7C1C 簜 (<CJK Ideograph>) 10896 0x7C1D 簝 (<CJK Ideograph>) 10897 0x7C1E 簞 (<CJK Ideograph>) 10898 0x7C20 簠 (<CJK Ideograph>) 10899 0x7C21 簡 (<CJK Ideograph>) 10900 0x7C22 簢 (<CJK Ideograph>) 10901 0x7C23 簣 (<CJK Ideograph>) 10902 0x7C24 簤 (<CJK Ideograph>) 10903 0x7C25 簥 (<CJK Ideograph>) 10904 0x7C28 簨 (<CJK Ideograph>) 10905 0x7C29 簩 (<CJK Ideograph>) 10906 0x7C2B 簫 (<CJK Ideograph>) 10907 0x7C2C 簬 (<CJK Ideograph>) 10908 0x7C2D 簭 (<CJK Ideograph>) 10909 0x7C2E 簮 (<CJK Ideograph>) 10910 0x7C2F 簯 (<CJK Ideograph>) 10911 0x7C30 簰 (<CJK Ideograph>) 10912 0x7C31 簱 (<CJK Ideograph>) 10913 0x7C32 簲 (<CJK Ideograph>) 10914 0x7C33 簳 (<CJK Ideograph>) 10915 0x7C34 簴 (<CJK Ideograph>) 10916 0x7C35 簵 (<CJK Ideograph>) 10917 0x7C36 簶 (<CJK Ideograph>) 10918 0x7C37 簷 (<CJK Ideograph>) 10919 0x7C39 簹 (<CJK Ideograph>) 10920 0x7C3A 簺 (<CJK Ideograph>) 10921 0x7C3B 簻 (<CJK Ideograph>) 10922 0x7C3C 簼 (<CJK Ideograph>) 10923 0x7C3D 簽 (<CJK Ideograph>) 10924 0x7C3E 簾 (<CJK Ideograph>) 10925 0x7C42 籂 (<CJK Ideograph>) 10926 0x9AB8 骸 (<CJK Ideograph>) 10927 0x5B69 孩 (<CJK Ideograph>) 10928 0x6D77 海 (<CJK Ideograph>) 10929 0x6C26 氦 (<CJK Ideograph>) 10930 0x4EA5 亥 (<CJK Ideograph>) 10931 0x5BB3 害 (<CJK Ideograph>) 10932 0x9A87 骇 (<CJK Ideograph>) 10933 0x9163 酣 (<CJK Ideograph>) 10934 0x61A8 憨 (<CJK Ideograph>) 10935 0x90AF 邯 (<CJK Ideograph>) 10936 0x97E9 韩 (<CJK Ideograph>) 10937 0x542B 含 (<CJK Ideograph>) 10938 0x6DB5 涵 (<CJK Ideograph>) 10939 0x5BD2 寒 (<CJK Ideograph>) 10940 0x51FD 函 (<CJK Ideograph>) 10941 0x558A 喊 (<CJK Ideograph>) 10942 0x7F55 罕 (<CJK Ideograph>) 10943 0x7FF0 翰 (<CJK Ideograph>) 10944 0x64BC 撼 (<CJK Ideograph>) 10945 0x634D 捍 (<CJK Ideograph>) 10946 0x65F1 旱 (<CJK Ideograph>) 10947 0x61BE 憾 (<CJK Ideograph>) 10948 0x608D 悍 (<CJK Ideograph>) 10949 0x710A 焊 (<CJK Ideograph>) 10950 0x6C57 汗 (<CJK Ideograph>) 10951 0x6C49 汉 (<CJK Ideograph>) 10952 0x592F 夯 (<CJK Ideograph>) 10953 0x676D 杭 (<CJK Ideograph>) 10954 0x822A 航 (<CJK Ideograph>) 10955 0x58D5 壕 (<CJK Ideograph>) 10956 0x568E 嚎 (<CJK Ideograph>) 10957 0x8C6A 豪 (<CJK Ideograph>) 10958 0x6BEB 毫 (<CJK Ideograph>) 10959 0x90DD 郝 (<CJK Ideograph>) 10960 0x597D 好 (<CJK Ideograph>) 10961 0x8017 耗 (<CJK Ideograph>) 10962 0x53F7 号 (<CJK Ideograph>) 10963 0x6D69 浩 (<CJK Ideograph>) 10964 0x5475 呵 (<CJK Ideograph>) 10965 0x559D 喝 (<CJK Ideograph>) 10966 0x8377 荷 (<CJK Ideograph>) 10967 0x83CF 菏 (<CJK Ideograph>) 10968 0x6838 核 (<CJK Ideograph>) 10969 0x79BE 禾 (<CJK Ideograph>) 10970 0x548C 和 (<CJK Ideograph>) 10971 0x4F55 何 (<CJK Ideograph>) 10972 0x5408 合 (<CJK Ideograph>) 10973 0x76D2 盒 (<CJK Ideograph>) 10974 0x8C89 貉 (<CJK Ideograph>) 10975 0x9602 阂 (<CJK Ideograph>) 10976 0x6CB3 河 (<CJK Ideograph>) 10977 0x6DB8 涸 (<CJK Ideograph>) 10978 0x8D6B 赫 (<CJK Ideograph>) 10979 0x8910 褐 (<CJK Ideograph>) 10980 0x9E64 鹤 (<CJK Ideograph>) 10981 0x8D3A 贺 (<CJK Ideograph>) 10982 0x563F 嘿 (<CJK Ideograph>) 10983 0x9ED1 黑 (<CJK Ideograph>) 10984 0x75D5 痕 (<CJK Ideograph>) 10985 0x5F88 很 (<CJK Ideograph>) 10986 0x72E0 狠 (<CJK Ideograph>) 10987 0x6068 恨 (<CJK Ideograph>) 10988 0x54FC 哼 (<CJK Ideograph>) 10989 0x4EA8 亨 (<CJK Ideograph>) 10990 0x6A2A 横 (<CJK Ideograph>) 10991 0x8861 衡 (<CJK Ideograph>) 10992 0x6052 恒 (<CJK Ideograph>) 10993 0x8F70 轰 (<CJK Ideograph>) 10994 0x54C4 哄 (<CJK Ideograph>) 10995 0x70D8 烘 (<CJK Ideograph>) 10996 0x8679 虹 (<CJK Ideograph>) 10997 0x9E3F 鸿 (<CJK Ideograph>) 10998 0x6D2A 洪 (<CJK Ideograph>) 10999 0x5B8F 宏 (<CJK Ideograph>) 11000 0x5F18 弘 (<CJK Ideograph>) 11001 0x7EA2 红 (<CJK Ideograph>) 11002 0x5589 喉 (<CJK Ideograph>) 11003 0x4FAF 侯 (<CJK Ideograph>) 11004 0x7334 猴 (<CJK Ideograph>) 11005 0x543C 吼 (<CJK Ideograph>) 11006 0x539A 厚 (<CJK Ideograph>) 11007 0x5019 候 (<CJK Ideograph>) 11008 0x540E 后 (<CJK Ideograph>) 11009 0x547C 呼 (<CJK Ideograph>) 11010 0x4E4E 乎 (<CJK Ideograph>) 11011 0x5FFD 忽 (<CJK Ideograph>) 11012 0x745A 瑚 (<CJK Ideograph>) 11013 0x58F6 壶 (<CJK Ideograph>) 11014 0x846B 葫 (<CJK Ideograph>) 11015 0x80E1 胡 (<CJK Ideograph>) 11016 0x8774 蝴 (<CJK Ideograph>) 11017 0x72D0 狐 (<CJK Ideograph>) 11018 0x7CCA 糊 (<CJK Ideograph>) 11019 0x6E56 湖 (<CJK Ideograph>) 11020 0x7C43 籃 (<CJK Ideograph>) 11021 0x7C44 籄 (<CJK Ideograph>) 11022 0x7C45 籅 (<CJK Ideograph>) 11023 0x7C46 籆 (<CJK Ideograph>) 11024 0x7C47 籇 (<CJK Ideograph>) 11025 0x7C48 籈 (<CJK Ideograph>) 11026 0x7C49 籉 (<CJK Ideograph>) 11027 0x7C4A 籊 (<CJK Ideograph>) 11028 0x7C4B 籋 (<CJK Ideograph>) 11029 0x7C4C 籌 (<CJK Ideograph>) 11030 0x7C4E 籎 (<CJK Ideograph>) 11031 0x7C4F 籏 (<CJK Ideograph>) 11032 0x7C50 籐 (<CJK Ideograph>) 11033 0x7C51 籑 (<CJK Ideograph>) 11034 0x7C52 籒 (<CJK Ideograph>) 11035 0x7C53 籓 (<CJK Ideograph>) 11036 0x7C54 籔 (<CJK Ideograph>) 11037 0x7C55 籕 (<CJK Ideograph>) 11038 0x7C56 籖 (<CJK Ideograph>) 11039 0x7C57 籗 (<CJK Ideograph>) 11040 0x7C58 籘 (<CJK Ideograph>) 11041 0x7C59 籙 (<CJK Ideograph>) 11042 0x7C5A 籚 (<CJK Ideograph>) 11043 0x7C5B 籛 (<CJK Ideograph>) 11044 0x7C5C 籜 (<CJK Ideograph>) 11045 0x7C5D 籝 (<CJK Ideograph>) 11046 0x7C5E 籞 (<CJK Ideograph>) 11047 0x7C5F 籟 (<CJK Ideograph>) 11048 0x7C60 籠 (<CJK Ideograph>) 11049 0x7C61 籡 (<CJK Ideograph>) 11050 0x7C62 籢 (<CJK Ideograph>) 11051 0x7C63 籣 (<CJK Ideograph>) 11052 0x7C64 籤 (<CJK Ideograph>) 11053 0x7C65 籥 (<CJK Ideograph>) 11054 0x7C66 籦 (<CJK Ideograph>) 11055 0x7C67 籧 (<CJK Ideograph>) 11056 0x7C68 籨 (<CJK Ideograph>) 11057 0x7C69 籩 (<CJK Ideograph>) 11058 0x7C6A 籪 (<CJK Ideograph>) 11059 0x7C6B 籫 (<CJK Ideograph>) 11060 0x7C6C 籬 (<CJK Ideograph>) 11061 0x7C6D 籭 (<CJK Ideograph>) 11062 0x7C6E 籮 (<CJK Ideograph>) 11063 0x7C6F 籯 (<CJK Ideograph>) 11064 0x7C70 籰 (<CJK Ideograph>) 11065 0x7C71 籱 (<CJK Ideograph>) 11066 0x7C72 籲 (<CJK Ideograph>) 11067 0x7C75 籵 (<CJK Ideograph>) 11068 0x7C76 籶 (<CJK Ideograph>) 11069 0x7C77 籷 (<CJK Ideograph>) 11070 0x7C78 籸 (<CJK Ideograph>) 11071 0x7C79 籹 (<CJK Ideograph>) 11072 0x7C7A 籺 (<CJK Ideograph>) 11073 0x7C7E 籾 (<CJK Ideograph>) 11074 0x7C7F 籿 (<CJK Ideograph>) 11075 0x7C80 粀 (<CJK Ideograph>) 11076 0x7C81 粁 (<CJK Ideograph>) 11077 0x7C82 粂 (<CJK Ideograph>) 11078 0x7C83 粃 (<CJK Ideograph>) 11079 0x7C84 粄 (<CJK Ideograph>) 11080 0x7C85 粅 (<CJK Ideograph>) 11081 0x7C86 粆 (<CJK Ideograph>) 11082 0x7C87 粇 (<CJK Ideograph>) 11083 0x7C88 粈 (<CJK Ideograph>) 11084 0x7C8A 粊 (<CJK Ideograph>) 11085 0x7C8B 粋 (<CJK Ideograph>) 11086 0x7C8C 粌 (<CJK Ideograph>) 11087 0x7C8D 粍 (<CJK Ideograph>) 11088 0x7C8E 粎 (<CJK Ideograph>) 11089 0x7C8F 粏 (<CJK Ideograph>) 11090 0x7C90 粐 (<CJK Ideograph>) 11091 0x7C93 粓 (<CJK Ideograph>) 11092 0x7C94 粔 (<CJK Ideograph>) 11093 0x7C96 粖 (<CJK Ideograph>) 11094 0x7C99 粙 (<CJK Ideograph>) 11095 0x7C9A 粚 (<CJK Ideograph>) 11096 0x7C9B 粛 (<CJK Ideograph>) 11097 0x7CA0 粠 (<CJK Ideograph>) 11098 0x7CA1 粡 (<CJK Ideograph>) 11099 0x7CA3 粣 (<CJK Ideograph>) 11100 0x7CA6 粦 (<CJK Ideograph>) 11101 0x7CA7 粧 (<CJK Ideograph>) 11102 0x7CA8 粨 (<CJK Ideograph>) 11103 0x7CA9 粩 (<CJK Ideograph>) 11104 0x7CAB 粫 (<CJK Ideograph>) 11105 0x7CAC 粬 (<CJK Ideograph>) 11106 0x7CAD 粭 (<CJK Ideograph>) 11107 0x7CAF 粯 (<CJK Ideograph>) 11108 0x7CB0 粰 (<CJK Ideograph>) 11109 0x7CB4 粴 (<CJK Ideograph>) 11110 0x7CB5 粵 (<CJK Ideograph>) 11111 0x7CB6 粶 (<CJK Ideograph>) 11112 0x7CB7 粷 (<CJK Ideograph>) 11113 0x7CB8 粸 (<CJK Ideograph>) 11114 0x7CBA 粺 (<CJK Ideograph>) 11115 0x7CBB 粻 (<CJK Ideograph>) 11116 0x5F27 弧 (<CJK Ideograph>) 11117 0x864E 虎 (<CJK Ideograph>) 11118 0x552C 唬 (<CJK Ideograph>) 11119 0x62A4 护 (<CJK Ideograph>) 11120 0x4E92 互 (<CJK Ideograph>) 11121 0x6CAA 沪 (<CJK Ideograph>) 11122 0x6237 户 (<CJK Ideograph>) 11123 0x82B1 花 (<CJK Ideograph>) 11124 0x54D7 哗 (<CJK Ideograph>) 11125 0x534E 华 (<CJK Ideograph>) 11126 0x733E 猾 (<CJK Ideograph>) 11127 0x6ED1 滑 (<CJK Ideograph>) 11128 0x753B 画 (<CJK Ideograph>) 11129 0x5212 划 (<CJK Ideograph>) 11130 0x5316 化 (<CJK Ideograph>) 11131 0x8BDD 话 (<CJK Ideograph>) 11132 0x69D0 槐 (<CJK Ideograph>) 11133 0x5F8A 徊 (<CJK Ideograph>) 11134 0x6000 怀 (<CJK Ideograph>) 11135 0x6DEE 淮 (<CJK Ideograph>) 11136 0x574F 坏 (<CJK Ideograph>) 11137 0x6B22 欢 (<CJK Ideograph>) 11138 0x73AF 环 (<CJK Ideograph>) 11139 0x6853 桓 (<CJK Ideograph>) 11140 0x8FD8 还 (<CJK Ideograph>) 11141 0x7F13 缓 (<CJK Ideograph>) 11142 0x6362 换 (<CJK Ideograph>) 11143 0x60A3 患 (<CJK Ideograph>) 11144 0x5524 唤 (<CJK Ideograph>) 11145 0x75EA 痪 (<CJK Ideograph>) 11146 0x8C62 豢 (<CJK Ideograph>) 11147 0x7115 焕 (<CJK Ideograph>) 11148 0x6DA3 涣 (<CJK Ideograph>) 11149 0x5BA6 宦 (<CJK Ideograph>) 11150 0x5E7B 幻 (<CJK Ideograph>) 11151 0x8352 荒 (<CJK Ideograph>) 11152 0x614C 慌 (<CJK Ideograph>) 11153 0x9EC4 黄 (<CJK Ideograph>) 11154 0x78FA 磺 (<CJK Ideograph>) 11155 0x8757 蝗 (<CJK Ideograph>) 11156 0x7C27 簧 (<CJK Ideograph>) 11157 0x7687 皇 (<CJK Ideograph>) 11158 0x51F0 凰 (<CJK Ideograph>) 11159 0x60F6 惶 (<CJK Ideograph>) 11160 0x714C 煌 (<CJK Ideograph>) 11161 0x6643 晃 (<CJK Ideograph>) 11162 0x5E4C 幌 (<CJK Ideograph>) 11163 0x604D 恍 (<CJK Ideograph>) 11164 0x8C0E 谎 (<CJK Ideograph>) 11165 0x7070 灰 (<CJK Ideograph>) 11166 0x6325 挥 (<CJK Ideograph>) 11167 0x8F89 辉 (<CJK Ideograph>) 11168 0x5FBD 徽 (<CJK Ideograph>) 11169 0x6062 恢 (<CJK Ideograph>) 11170 0x86D4 蛔 (<CJK Ideograph>) 11171 0x56DE 回 (<CJK Ideograph>) 11172 0x6BC1 毁 (<CJK Ideograph>) 11173 0x6094 悔 (<CJK Ideograph>) 11174 0x6167 慧 (<CJK Ideograph>) 11175 0x5349 卉 (<CJK Ideograph>) 11176 0x60E0 惠 (<CJK Ideograph>) 11177 0x6666 晦 (<CJK Ideograph>) 11178 0x8D3F 贿 (<CJK Ideograph>) 11179 0x79FD 秽 (<CJK Ideograph>) 11180 0x4F1A 会 (<CJK Ideograph>) 11181 0x70E9 烩 (<CJK Ideograph>) 11182 0x6C47 汇 (<CJK Ideograph>) 11183 0x8BB3 讳 (<CJK Ideograph>) 11184 0x8BF2 诲 (<CJK Ideograph>) 11185 0x7ED8 绘 (<CJK Ideograph>) 11186 0x8364 荤 (<CJK Ideograph>) 11187 0x660F 昏 (<CJK Ideograph>) 11188 0x5A5A 婚 (<CJK Ideograph>) 11189 0x9B42 魂 (<CJK Ideograph>) 11190 0x6D51 浑 (<CJK Ideograph>) 11191 0x6DF7 混 (<CJK Ideograph>) 11192 0x8C41 豁 (<CJK Ideograph>) 11193 0x6D3B 活 (<CJK Ideograph>) 11194 0x4F19 伙 (<CJK Ideograph>) 11195 0x706B 火 (<CJK Ideograph>) 11196 0x83B7 获 (<CJK Ideograph>) 11197 0x6216 或 (<CJK Ideograph>) 11198 0x60D1 惑 (<CJK Ideograph>) 11199 0x970D 霍 (<CJK Ideograph>) 11200 0x8D27 货 (<CJK Ideograph>) 11201 0x7978 祸 (<CJK Ideograph>) 11202 0x51FB 击 (<CJK Ideograph>) 11203 0x573E 圾 (<CJK Ideograph>) 11204 0x57FA 基 (<CJK Ideograph>) 11205 0x673A 机 (<CJK Ideograph>) 11206 0x7578 畸 (<CJK Ideograph>) 11207 0x7A3D 稽 (<CJK Ideograph>) 11208 0x79EF 积 (<CJK Ideograph>) 11209 0x7B95 箕 (<CJK Ideograph>) 11210 0x7CBF 粿 (<CJK Ideograph>) 11211 0x7CC0 糀 (<CJK Ideograph>) 11212 0x7CC2 糂 (<CJK Ideograph>) 11213 0x7CC3 糃 (<CJK Ideograph>) 11214 0x7CC4 糄 (<CJK Ideograph>) 11215 0x7CC6 糆 (<CJK Ideograph>) 11216 0x7CC9 糉 (<CJK Ideograph>) 11217 0x7CCB 糋 (<CJK Ideograph>) 11218 0x7CCE 糎 (<CJK Ideograph>) 11219 0x7CCF 糏 (<CJK Ideograph>) 11220 0x7CD0 糐 (<CJK Ideograph>) 11221 0x7CD1 糑 (<CJK Ideograph>) 11222 0x7CD2 糒 (<CJK Ideograph>) 11223 0x7CD3 糓 (<CJK Ideograph>) 11224 0x7CD4 糔 (<CJK Ideograph>) 11225 0x7CD8 糘 (<CJK Ideograph>) 11226 0x7CDA 糚 (<CJK Ideograph>) 11227 0x7CDB 糛 (<CJK Ideograph>) 11228 0x7CDD 糝 (<CJK Ideograph>) 11229 0x7CDE 糞 (<CJK Ideograph>) 11230 0x7CE1 糡 (<CJK Ideograph>) 11231 0x7CE2 糢 (<CJK Ideograph>) 11232 0x7CE3 糣 (<CJK Ideograph>) 11233 0x7CE4 糤 (<CJK Ideograph>) 11234 0x7CE5 糥 (<CJK Ideograph>) 11235 0x7CE6 糦 (<CJK Ideograph>) 11236 0x7CE7 糧 (<CJK Ideograph>) 11237 0x7CE9 糩 (<CJK Ideograph>) 11238 0x7CEA 糪 (<CJK Ideograph>) 11239 0x7CEB 糫 (<CJK Ideograph>) 11240 0x7CEC 糬 (<CJK Ideograph>) 11241 0x7CED 糭 (<CJK Ideograph>) 11242 0x7CEE 糮 (<CJK Ideograph>) 11243 0x7CF0 糰 (<CJK Ideograph>) 11244 0x7CF1 糱 (<CJK Ideograph>) 11245 0x7CF2 糲 (<CJK Ideograph>) 11246 0x7CF3 糳 (<CJK Ideograph>) 11247 0x7CF4 糴 (<CJK Ideograph>) 11248 0x7CF5 糵 (<CJK Ideograph>) 11249 0x7CF6 糶 (<CJK Ideograph>) 11250 0x7CF7 糷 (<CJK Ideograph>) 11251 0x7CF9 糹 (<CJK Ideograph>) 11252 0x7CFA 糺 (<CJK Ideograph>) 11253 0x7CFC 糼 (<CJK Ideograph>) 11254 0x7CFD 糽 (<CJK Ideograph>) 11255 0x7CFE 糾 (<CJK Ideograph>) 11256 0x7CFF 糿 (<CJK Ideograph>) 11257 0x7D00 紀 (<CJK Ideograph>) 11258 0x7D01 紁 (<CJK Ideograph>) 11259 0x7D02 紂 (<CJK Ideograph>) 11260 0x7D03 紃 (<CJK Ideograph>) 11261 0x7D04 約 (<CJK Ideograph>) 11262 0x7D05 紅 (<CJK Ideograph>) 11263 0x7D06 紆 (<CJK Ideograph>) 11264 0x7D07 紇 (<CJK Ideograph>) 11265 0x7D08 紈 (<CJK Ideograph>) 11266 0x7D09 紉 (<CJK Ideograph>) 11267 0x7D0B 紋 (<CJK Ideograph>) 11268 0x7D0C 紌 (<CJK Ideograph>) 11269 0x7D0D 納 (<CJK Ideograph>) 11270 0x7D0E 紎 (<CJK Ideograph>) 11271 0x7D0F 紏 (<CJK Ideograph>) 11272 0x7D10 紐 (<CJK Ideograph>) 11273 0x7D11 紑 (<CJK Ideograph>) 11274 0x7D12 紒 (<CJK Ideograph>) 11275 0x7D13 紓 (<CJK Ideograph>) 11276 0x7D14 純 (<CJK Ideograph>) 11277 0x7D15 紕 (<CJK Ideograph>) 11278 0x7D16 紖 (<CJK Ideograph>) 11279 0x7D17 紗 (<CJK Ideograph>) 11280 0x7D18 紘 (<CJK Ideograph>) 11281 0x7D19 紙 (<CJK Ideograph>) 11282 0x7D1A 級 (<CJK Ideograph>) 11283 0x7D1B 紛 (<CJK Ideograph>) 11284 0x7D1C 紜 (<CJK Ideograph>) 11285 0x7D1D 紝 (<CJK Ideograph>) 11286 0x7D1E 紞 (<CJK Ideograph>) 11287 0x7D1F 紟 (<CJK Ideograph>) 11288 0x7D21 紡 (<CJK Ideograph>) 11289 0x7D23 紣 (<CJK Ideograph>) 11290 0x7D24 紤 (<CJK Ideograph>) 11291 0x7D25 紥 (<CJK Ideograph>) 11292 0x7D26 紦 (<CJK Ideograph>) 11293 0x7D28 紨 (<CJK Ideograph>) 11294 0x7D29 紩 (<CJK Ideograph>) 11295 0x7D2A 紪 (<CJK Ideograph>) 11296 0x7D2C 紬 (<CJK Ideograph>) 11297 0x7D2D 紭 (<CJK Ideograph>) 11298 0x7D2E 紮 (<CJK Ideograph>) 11299 0x7D30 細 (<CJK Ideograph>) 11300 0x7D31 紱 (<CJK Ideograph>) 11301 0x7D32 紲 (<CJK Ideograph>) 11302 0x7D33 紳 (<CJK Ideograph>) 11303 0x7D34 紴 (<CJK Ideograph>) 11304 0x7D35 紵 (<CJK Ideograph>) 11305 0x7D36 紶 (<CJK Ideograph>) 11306 0x808C 肌 (<CJK Ideograph>) 11307 0x9965 饥 (<CJK Ideograph>) 11308 0x8FF9 迹 (<CJK Ideograph>) 11309 0x6FC0 激 (<CJK Ideograph>) 11310 0x8BA5 讥 (<CJK Ideograph>) 11311 0x9E21 鸡 (<CJK Ideograph>) 11312 0x59EC 姬 (<CJK Ideograph>) 11313 0x7EE9 绩 (<CJK Ideograph>) 11314 0x7F09 缉 (<CJK Ideograph>) 11315 0x5409 吉 (<CJK Ideograph>) 11316 0x6781 极 (<CJK Ideograph>) 11317 0x68D8 棘 (<CJK Ideograph>) 11318 0x8F91 辑 (<CJK Ideograph>) 11319 0x7C4D 籍 (<CJK Ideograph>) 11320 0x96C6 集 (<CJK Ideograph>) 11321 0x53CA 及 (<CJK Ideograph>) 11322 0x6025 急 (<CJK Ideograph>) 11323 0x75BE 疾 (<CJK Ideograph>) 11324 0x6C72 汲 (<CJK Ideograph>) 11325 0x5373 即 (<CJK Ideograph>) 11326 0x5AC9 嫉 (<CJK Ideograph>) 11327 0x7EA7 级 (<CJK Ideograph>) 11328 0x6324 挤 (<CJK Ideograph>) 11329 0x51E0 几 (<CJK Ideograph>) 11330 0x810A 脊 (<CJK Ideograph>) 11331 0x5DF1 己 (<CJK Ideograph>) 11332 0x84DF 蓟 (<CJK Ideograph>) 11333 0x6280 技 (<CJK Ideograph>) 11334 0x5180 冀 (<CJK Ideograph>) 11335 0x5B63 季 (<CJK Ideograph>) 11336 0x4F0E 伎 (<CJK Ideograph>) 11337 0x796D 祭 (<CJK Ideograph>) 11338 0x5242 剂 (<CJK Ideograph>) 11339 0x60B8 悸 (<CJK Ideograph>) 11340 0x6D4E 济 (<CJK Ideograph>) 11341 0x5BC4 寄 (<CJK Ideograph>) 11342 0x5BC2 寂 (<CJK Ideograph>) 11343 0x8BA1 计 (<CJK Ideograph>) 11344 0x8BB0 记 (<CJK Ideograph>) 11345 0x65E2 既 (<CJK Ideograph>) 11346 0x5FCC 忌 (<CJK Ideograph>) 11347 0x9645 际 (<CJK Ideograph>) 11348 0x5993 妓 (<CJK Ideograph>) 11349 0x7EE7 继 (<CJK Ideograph>) 11350 0x7EAA 纪 (<CJK Ideograph>) 11351 0x5609 嘉 (<CJK Ideograph>) 11352 0x67B7 枷 (<CJK Ideograph>) 11353 0x5939 夹 (<CJK Ideograph>) 11354 0x4F73 佳 (<CJK Ideograph>) 11355 0x5BB6 家 (<CJK Ideograph>) 11356 0x52A0 加 (<CJK Ideograph>) 11357 0x835A 荚 (<CJK Ideograph>) 11358 0x988A 颊 (<CJK Ideograph>) 11359 0x8D3E 贾 (<CJK Ideograph>) 11360 0x7532 甲 (<CJK Ideograph>) 11361 0x94BE 钾 (<CJK Ideograph>) 11362 0x5047 假 (<CJK Ideograph>) 11363 0x7A3C 稼 (<CJK Ideograph>) 11364 0x4EF7 价 (<CJK Ideograph>) 11365 0x67B6 架 (<CJK Ideograph>) 11366 0x9A7E 驾 (<CJK Ideograph>) 11367 0x5AC1 嫁 (<CJK Ideograph>) 11368 0x6B7C 歼 (<CJK Ideograph>) 11369 0x76D1 监 (<CJK Ideograph>) 11370 0x575A 坚 (<CJK Ideograph>) 11371 0x5C16 尖 (<CJK Ideograph>) 11372 0x7B3A 笺 (<CJK Ideograph>) 11373 0x95F4 间 (<CJK Ideograph>) 11374 0x714E 煎 (<CJK Ideograph>) 11375 0x517C 兼 (<CJK Ideograph>) 11376 0x80A9 肩 (<CJK Ideograph>) 11377 0x8270 艰 (<CJK Ideograph>) 11378 0x5978 奸 (<CJK Ideograph>) 11379 0x7F04 缄 (<CJK Ideograph>) 11380 0x8327 茧 (<CJK Ideograph>) 11381 0x68C0 检 (<CJK Ideograph>) 11382 0x67EC 柬 (<CJK Ideograph>) 11383 0x78B1 碱 (<CJK Ideograph>) 11384 0x7877 硷 (<CJK Ideograph>) 11385 0x62E3 拣 (<CJK Ideograph>) 11386 0x6361 捡 (<CJK Ideograph>) 11387 0x7B80 简 (<CJK Ideograph>) 11388 0x4FED 俭 (<CJK Ideograph>) 11389 0x526A 剪 (<CJK Ideograph>) 11390 0x51CF 减 (<CJK Ideograph>) 11391 0x8350 荐 (<CJK Ideograph>) 11392 0x69DB 槛 (<CJK Ideograph>) 11393 0x9274 鉴 (<CJK Ideograph>) 11394 0x8DF5 践 (<CJK Ideograph>) 11395 0x8D31 贱 (<CJK Ideograph>) 11396 0x89C1 见 (<CJK Ideograph>) 11397 0x952E 键 (<CJK Ideograph>) 11398 0x7BAD 箭 (<CJK Ideograph>) 11399 0x4EF6 件 (<CJK Ideograph>) 11400 0x7D37 紷 (<CJK Ideograph>) 11401 0x7D38 紸 (<CJK Ideograph>) 11402 0x7D39 紹 (<CJK Ideograph>) 11403 0x7D3A 紺 (<CJK Ideograph>) 11404 0x7D3B 紻 (<CJK Ideograph>) 11405 0x7D3C 紼 (<CJK Ideograph>) 11406 0x7D3D 紽 (<CJK Ideograph>) 11407 0x7D3E 紾 (<CJK Ideograph>) 11408 0x7D3F 紿 (<CJK Ideograph>) 11409 0x7D40 絀 (<CJK Ideograph>) 11410 0x7D41 絁 (<CJK Ideograph>) 11411 0x7D42 終 (<CJK Ideograph>) 11412 0x7D43 絃 (<CJK Ideograph>) 11413 0x7D44 組 (<CJK Ideograph>) 11414 0x7D45 絅 (<CJK Ideograph>) 11415 0x7D46 絆 (<CJK Ideograph>) 11416 0x7D47 絇 (<CJK Ideograph>) 11417 0x7D48 絈 (<CJK Ideograph>) 11418 0x7D49 絉 (<CJK Ideograph>) 11419 0x7D4A 絊 (<CJK Ideograph>) 11420 0x7D4B 絋 (<CJK Ideograph>) 11421 0x7D4C 経 (<CJK Ideograph>) 11422 0x7D4D 絍 (<CJK Ideograph>) 11423 0x7D4E 絎 (<CJK Ideograph>) 11424 0x7D4F 絏 (<CJK Ideograph>) 11425 0x7D50 結 (<CJK Ideograph>) 11426 0x7D51 絑 (<CJK Ideograph>) 11427 0x7D52 絒 (<CJK Ideograph>) 11428 0x7D53 絓 (<CJK Ideograph>) 11429 0x7D54 絔 (<CJK Ideograph>) 11430 0x7D55 絕 (<CJK Ideograph>) 11431 0x7D56 絖 (<CJK Ideograph>) 11432 0x7D57 絗 (<CJK Ideograph>) 11433 0x7D58 絘 (<CJK Ideograph>) 11434 0x7D59 絙 (<CJK Ideograph>) 11435 0x7D5A 絚 (<CJK Ideograph>) 11436 0x7D5B 絛 (<CJK Ideograph>) 11437 0x7D5C 絜 (<CJK Ideograph>) 11438 0x7D5D 絝 (<CJK Ideograph>) 11439 0x7D5E 絞 (<CJK Ideograph>) 11440 0x7D5F 絟 (<CJK Ideograph>) 11441 0x7D60 絠 (<CJK Ideograph>) 11442 0x7D61 絡 (<CJK Ideograph>) 11443 0x7D62 絢 (<CJK Ideograph>) 11444 0x7D63 絣 (<CJK Ideograph>) 11445 0x7D64 絤 (<CJK Ideograph>) 11446 0x7D65 絥 (<CJK Ideograph>) 11447 0x7D66 給 (<CJK Ideograph>) 11448 0x7D67 絧 (<CJK Ideograph>) 11449 0x7D68 絨 (<CJK Ideograph>) 11450 0x7D69 絩 (<CJK Ideograph>) 11451 0x7D6A 絪 (<CJK Ideograph>) 11452 0x7D6B 絫 (<CJK Ideograph>) 11453 0x7D6C 絬 (<CJK Ideograph>) 11454 0x7D6D 絭 (<CJK Ideograph>) 11455 0x7D6F 絯 (<CJK Ideograph>) 11456 0x7D70 絰 (<CJK Ideograph>) 11457 0x7D71 統 (<CJK Ideograph>) 11458 0x7D72 絲 (<CJK Ideograph>) 11459 0x7D73 絳 (<CJK Ideograph>) 11460 0x7D74 絴 (<CJK Ideograph>) 11461 0x7D75 絵 (<CJK Ideograph>) 11462 0x7D76 絶 (<CJK Ideograph>) 11463 0x7D78 絸 (<CJK Ideograph>) 11464 0x7D79 絹 (<CJK Ideograph>) 11465 0x7D7A 絺 (<CJK Ideograph>) 11466 0x7D7B 絻 (<CJK Ideograph>) 11467 0x7D7C 絼 (<CJK Ideograph>) 11468 0x7D7D 絽 (<CJK Ideograph>) 11469 0x7D7E 絾 (<CJK Ideograph>) 11470 0x7D7F 絿 (<CJK Ideograph>) 11471 0x7D80 綀 (<CJK Ideograph>) 11472 0x7D81 綁 (<CJK Ideograph>) 11473 0x7D82 綂 (<CJK Ideograph>) 11474 0x7D83 綃 (<CJK Ideograph>) 11475 0x7D84 綄 (<CJK Ideograph>) 11476 0x7D85 綅 (<CJK Ideograph>) 11477 0x7D86 綆 (<CJK Ideograph>) 11478 0x7D87 綇 (<CJK Ideograph>) 11479 0x7D88 綈 (<CJK Ideograph>) 11480 0x7D89 綉 (<CJK Ideograph>) 11481 0x7D8A 綊 (<CJK Ideograph>) 11482 0x7D8B 綋 (<CJK Ideograph>) 11483 0x7D8C 綌 (<CJK Ideograph>) 11484 0x7D8D 綍 (<CJK Ideograph>) 11485 0x7D8E 綎 (<CJK Ideograph>) 11486 0x7D8F 綏 (<CJK Ideograph>) 11487 0x7D90 綐 (<CJK Ideograph>) 11488 0x7D91 綑 (<CJK Ideograph>) 11489 0x7D92 綒 (<CJK Ideograph>) 11490 0x7D93 經 (<CJK Ideograph>) 11491 0x7D94 綔 (<CJK Ideograph>) 11492 0x7D95 綕 (<CJK Ideograph>) 11493 0x7D96 綖 (<CJK Ideograph>) 11494 0x7D97 綗 (<CJK Ideograph>) 11495 0x7D98 綘 (<CJK Ideograph>) 11496 0x5065 健 (<CJK Ideograph>) 11497 0x8230 舰 (<CJK Ideograph>) 11498 0x5251 剑 (<CJK Ideograph>) 11499 0x996F 饯 (<CJK Ideograph>) 11500 0x6E10 渐 (<CJK Ideograph>) 11501 0x6E85 溅 (<CJK Ideograph>) 11502 0x6DA7 涧 (<CJK Ideograph>) 11503 0x5EFA 建 (<CJK Ideograph>) 11504 0x50F5 僵 (<CJK Ideograph>) 11505 0x59DC 姜 (<CJK Ideograph>) 11506 0x5C06 将 (<CJK Ideograph>) 11507 0x6D46 浆 (<CJK Ideograph>) 11508 0x6C5F 江 (<CJK Ideograph>) 11509 0x7586 疆 (<CJK Ideograph>) 11510 0x848B 蒋 (<CJK Ideograph>) 11511 0x6868 桨 (<CJK Ideograph>) 11512 0x5956 奖 (<CJK Ideograph>) 11513 0x8BB2 讲 (<CJK Ideograph>) 11514 0x5320 匠 (<CJK Ideograph>) 11515 0x9171 酱 (<CJK Ideograph>) 11516 0x964D 降 (<CJK Ideograph>) 11517 0x8549 蕉 (<CJK Ideograph>) 11518 0x6912 椒 (<CJK Ideograph>) 11519 0x7901 礁 (<CJK Ideograph>) 11520 0x7126 焦 (<CJK Ideograph>) 11521 0x80F6 胶 (<CJK Ideograph>) 11522 0x4EA4 交 (<CJK Ideograph>) 11523 0x90CA 郊 (<CJK Ideograph>) 11524 0x6D47 浇 (<CJK Ideograph>) 11525 0x9A84 骄 (<CJK Ideograph>) 11526 0x5A07 娇 (<CJK Ideograph>) 11527 0x56BC 嚼 (<CJK Ideograph>) 11528 0x6405 搅 (<CJK Ideograph>) 11529 0x94F0 铰 (<CJK Ideograph>) 11530 0x77EB 矫 (<CJK Ideograph>) 11531 0x4FA5 侥 (<CJK Ideograph>) 11532 0x811A 脚 (<CJK Ideograph>) 11533 0x72E1 狡 (<CJK Ideograph>) 11534 0x89D2 角 (<CJK Ideograph>) 11535 0x997A 饺 (<CJK Ideograph>) 11536 0x7F34 缴 (<CJK Ideograph>) 11537 0x7EDE 绞 (<CJK Ideograph>) 11538 0x527F 剿 (<CJK Ideograph>) 11539 0x6559 教 (<CJK Ideograph>) 11540 0x9175 酵 (<CJK Ideograph>) 11541 0x8F7F 轿 (<CJK Ideograph>) 11542 0x8F83 较 (<CJK Ideograph>) 11543 0x53EB 叫 (<CJK Ideograph>) 11544 0x7A96 窖 (<CJK Ideograph>) 11545 0x63ED 揭 (<CJK Ideograph>) 11546 0x63A5 接 (<CJK Ideograph>) 11547 0x7686 皆 (<CJK Ideograph>) 11548 0x79F8 秸 (<CJK Ideograph>) 11549 0x8857 街 (<CJK Ideograph>) 11550 0x9636 阶 (<CJK Ideograph>) 11551 0x622A 截 (<CJK Ideograph>) 11552 0x52AB 劫 (<CJK Ideograph>) 11553 0x8282 节 (<CJK Ideograph>) 11554 0x6854 桔 (<CJK Ideograph>) 11555 0x6770 杰 (<CJK Ideograph>) 11556 0x6377 捷 (<CJK Ideograph>) 11557 0x776B 睫 (<CJK Ideograph>) 11558 0x7AED 竭 (<CJK Ideograph>) 11559 0x6D01 洁 (<CJK Ideograph>) 11560 0x7ED3 结 (<CJK Ideograph>) 11561 0x89E3 解 (<CJK Ideograph>) 11562 0x59D0 姐 (<CJK Ideograph>) 11563 0x6212 戒 (<CJK Ideograph>) 11564 0x85C9 藉 (<CJK Ideograph>) 11565 0x82A5 芥 (<CJK Ideograph>) 11566 0x754C 界 (<CJK Ideograph>) 11567 0x501F 借 (<CJK Ideograph>) 11568 0x4ECB 介 (<CJK Ideograph>) 11569 0x75A5 疥 (<CJK Ideograph>) 11570 0x8BEB 诫 (<CJK Ideograph>) 11571 0x5C4A 届 (<CJK Ideograph>) 11572 0x5DFE 巾 (<CJK Ideograph>) 11573 0x7B4B 筋 (<CJK Ideograph>) 11574 0x65A4 斤 (<CJK Ideograph>) 11575 0x91D1 金 (<CJK Ideograph>) 11576 0x4ECA 今 (<CJK Ideograph>) 11577 0x6D25 津 (<CJK Ideograph>) 11578 0x895F 襟 (<CJK Ideograph>) 11579 0x7D27 紧 (<CJK Ideograph>) 11580 0x9526 锦 (<CJK Ideograph>) 11581 0x4EC5 仅 (<CJK Ideograph>) 11582 0x8C28 谨 (<CJK Ideograph>) 11583 0x8FDB 进 (<CJK Ideograph>) 11584 0x9773 靳 (<CJK Ideograph>) 11585 0x664B 晋 (<CJK Ideograph>) 11586 0x7981 禁 (<CJK Ideograph>) 11587 0x8FD1 近 (<CJK Ideograph>) 11588 0x70EC 烬 (<CJK Ideograph>) 11589 0x6D78 浸 (<CJK Ideograph>) 11590 0x7D99 継 (<CJK Ideograph>) 11591 0x7D9A 続 (<CJK Ideograph>) 11592 0x7D9B 綛 (<CJK Ideograph>) 11593 0x7D9C 綜 (<CJK Ideograph>) 11594 0x7D9D 綝 (<CJK Ideograph>) 11595 0x7D9E 綞 (<CJK Ideograph>) 11596 0x7D9F 綟 (<CJK Ideograph>) 11597 0x7DA0 綠 (<CJK Ideograph>) 11598 0x7DA1 綡 (<CJK Ideograph>) 11599 0x7DA2 綢 (<CJK Ideograph>) 11600 0x7DA3 綣 (<CJK Ideograph>) 11601 0x7DA4 綤 (<CJK Ideograph>) 11602 0x7DA5 綥 (<CJK Ideograph>) 11603 0x7DA7 綧 (<CJK Ideograph>) 11604 0x7DA8 綨 (<CJK Ideograph>) 11605 0x7DA9 綩 (<CJK Ideograph>) 11606 0x7DAA 綪 (<CJK Ideograph>) 11607 0x7DAB 綫 (<CJK Ideograph>) 11608 0x7DAC 綬 (<CJK Ideograph>) 11609 0x7DAD 維 (<CJK Ideograph>) 11610 0x7DAF 綯 (<CJK Ideograph>) 11611 0x7DB0 綰 (<CJK Ideograph>) 11612 0x7DB1 綱 (<CJK Ideograph>) 11613 0x7DB2 網 (<CJK Ideograph>) 11614 0x7DB3 綳 (<CJK Ideograph>) 11615 0x7DB4 綴 (<CJK Ideograph>) 11616 0x7DB5 綵 (<CJK Ideograph>) 11617 0x7DB6 綶 (<CJK Ideograph>) 11618 0x7DB7 綷 (<CJK Ideograph>) 11619 0x7DB8 綸 (<CJK Ideograph>) 11620 0x7DB9 綹 (<CJK Ideograph>) 11621 0x7DBA 綺 (<CJK Ideograph>) 11622 0x7DBB 綻 (<CJK Ideograph>) 11623 0x7DBC 綼 (<CJK Ideograph>) 11624 0x7DBD 綽 (<CJK Ideograph>) 11625 0x7DBE 綾 (<CJK Ideograph>) 11626 0x7DBF 綿 (<CJK Ideograph>) 11627 0x7DC0 緀 (<CJK Ideograph>) 11628 0x7DC1 緁 (<CJK Ideograph>) 11629 0x7DC2 緂 (<CJK Ideograph>) 11630 0x7DC3 緃 (<CJK Ideograph>) 11631 0x7DC4 緄 (<CJK Ideograph>) 11632 0x7DC5 緅 (<CJK Ideograph>) 11633 0x7DC6 緆 (<CJK Ideograph>) 11634 0x7DC7 緇 (<CJK Ideograph>) 11635 0x7DC8 緈 (<CJK Ideograph>) 11636 0x7DC9 緉 (<CJK Ideograph>) 11637 0x7DCA 緊 (<CJK Ideograph>) 11638 0x7DCB 緋 (<CJK Ideograph>) 11639 0x7DCC 緌 (<CJK Ideograph>) 11640 0x7DCD 緍 (<CJK Ideograph>) 11641 0x7DCE 緎 (<CJK Ideograph>) 11642 0x7DCF 総 (<CJK Ideograph>) 11643 0x7DD0 緐 (<CJK Ideograph>) 11644 0x7DD1 緑 (<CJK Ideograph>) 11645 0x7DD2 緒 (<CJK Ideograph>) 11646 0x7DD3 緓 (<CJK Ideograph>) 11647 0x7DD4 緔 (<CJK Ideograph>) 11648 0x7DD5 緕 (<CJK Ideograph>) 11649 0x7DD6 緖 (<CJK Ideograph>) 11650 0x7DD7 緗 (<CJK Ideograph>) 11651 0x7DD8 緘 (<CJK Ideograph>) 11652 0x7DD9 緙 (<CJK Ideograph>) 11653 0x7DDA 線 (<CJK Ideograph>) 11654 0x7DDB 緛 (<CJK Ideograph>) 11655 0x7DDC 緜 (<CJK Ideograph>) 11656 0x7DDD 緝 (<CJK Ideograph>) 11657 0x7DDE 緞 (<CJK Ideograph>) 11658 0x7DDF 緟 (<CJK Ideograph>) 11659 0x7DE0 締 (<CJK Ideograph>) 11660 0x7DE1 緡 (<CJK Ideograph>) 11661 0x7DE2 緢 (<CJK Ideograph>) 11662 0x7DE3 緣 (<CJK Ideograph>) 11663 0x7DE4 緤 (<CJK Ideograph>) 11664 0x7DE5 緥 (<CJK Ideograph>) 11665 0x7DE6 緦 (<CJK Ideograph>) 11666 0x7DE7 緧 (<CJK Ideograph>) 11667 0x7DE8 編 (<CJK Ideograph>) 11668 0x7DE9 緩 (<CJK Ideograph>) 11669 0x7DEA 緪 (<CJK Ideograph>) 11670 0x7DEB 緫 (<CJK Ideograph>) 11671 0x7DEC 緬 (<CJK Ideograph>) 11672 0x7DED 緭 (<CJK Ideograph>) 11673 0x7DEE 緮 (<CJK Ideograph>) 11674 0x7DEF 緯 (<CJK Ideograph>) 11675 0x7DF0 緰 (<CJK Ideograph>) 11676 0x7DF1 緱 (<CJK Ideograph>) 11677 0x7DF2 緲 (<CJK Ideograph>) 11678 0x7DF3 緳 (<CJK Ideograph>) 11679 0x7DF4 練 (<CJK Ideograph>) 11680 0x7DF5 緵 (<CJK Ideograph>) 11681 0x7DF6 緶 (<CJK Ideograph>) 11682 0x7DF7 緷 (<CJK Ideograph>) 11683 0x7DF8 緸 (<CJK Ideograph>) 11684 0x7DF9 緹 (<CJK Ideograph>) 11685 0x7DFA 緺 (<CJK Ideograph>) 11686 0x5C3D 尽 (<CJK Ideograph>) 11687 0x52B2 劲 (<CJK Ideograph>) 11688 0x8346 荆 (<CJK Ideograph>) 11689 0x5162 兢 (<CJK Ideograph>) 11690 0x830E 茎 (<CJK Ideograph>) 11691 0x775B 睛 (<CJK Ideograph>) 11692 0x6676 晶 (<CJK Ideograph>) 11693 0x9CB8 鲸 (<CJK Ideograph>) 11694 0x4EAC 京 (<CJK Ideograph>) 11695 0x60CA 惊 (<CJK Ideograph>) 11696 0x7CBE 精 (<CJK Ideograph>) 11697 0x7CB3 粳 (<CJK Ideograph>) 11698 0x7ECF 经 (<CJK Ideograph>) 11699 0x4E95 井 (<CJK Ideograph>) 11700 0x8B66 警 (<CJK Ideograph>) 11701 0x666F 景 (<CJK Ideograph>) 11702 0x9888 颈 (<CJK Ideograph>) 11703 0x9759 静 (<CJK Ideograph>) 11704 0x5883 境 (<CJK Ideograph>) 11705 0x656C 敬 (<CJK Ideograph>) 11706 0x955C 镜 (<CJK Ideograph>) 11707 0x5F84 径 (<CJK Ideograph>) 11708 0x75C9 痉 (<CJK Ideograph>) 11709 0x9756 靖 (<CJK Ideograph>) 11710 0x7ADF 竟 (<CJK Ideograph>) 11711 0x7ADE 竞 (<CJK Ideograph>) 11712 0x51C0 净 (<CJK Ideograph>) 11713 0x70AF 炯 (<CJK Ideograph>) 11714 0x7A98 窘 (<CJK Ideograph>) 11715 0x63EA 揪 (<CJK Ideograph>) 11716 0x7A76 究 (<CJK Ideograph>) 11717 0x7EA0 纠 (<CJK Ideograph>) 11718 0x7396 玖 (<CJK Ideograph>) 11719 0x97ED 韭 (<CJK Ideograph>) 11720 0x4E45 久 (<CJK Ideograph>) 11721 0x7078 灸 (<CJK Ideograph>) 11722 0x4E5D 九 (<CJK Ideograph>) 11723 0x9152 酒 (<CJK Ideograph>) 11724 0x53A9 厩 (<CJK Ideograph>) 11725 0x6551 救 (<CJK Ideograph>) 11726 0x65E7 旧 (<CJK Ideograph>) 11727 0x81FC 臼 (<CJK Ideograph>) 11728 0x8205 舅 (<CJK Ideograph>) 11729 0x548E 咎 (<CJK Ideograph>) 11730 0x5C31 就 (<CJK Ideograph>) 11731 0x759A 疚 (<CJK Ideograph>) 11732 0x97A0 鞠 (<CJK Ideograph>) 11733 0x62D8 拘 (<CJK Ideograph>) 11734 0x72D9 狙 (<CJK Ideograph>) 11735 0x75BD 疽 (<CJK Ideograph>) 11736 0x5C45 居 (<CJK Ideograph>) 11737 0x9A79 驹 (<CJK Ideograph>) 11738 0x83CA 菊 (<CJK Ideograph>) 11739 0x5C40 局 (<CJK Ideograph>) 11740 0x5480 咀 (<CJK Ideograph>) 11741 0x77E9 矩 (<CJK Ideograph>) 11742 0x4E3E 举 (<CJK Ideograph>) 11743 0x6CAE 沮 (<CJK Ideograph>) 11744 0x805A 聚 (<CJK Ideograph>) 11745 0x62D2 拒 (<CJK Ideograph>) 11746 0x636E 据 (<CJK Ideograph>) 11747 0x5DE8 巨 (<CJK Ideograph>) 11748 0x5177 具 (<CJK Ideograph>) 11749 0x8DDD 距 (<CJK Ideograph>) 11750 0x8E1E 踞 (<CJK Ideograph>) 11751 0x952F 锯 (<CJK Ideograph>) 11752 0x4FF1 俱 (<CJK Ideograph>) 11753 0x53E5 句 (<CJK Ideograph>) 11754 0x60E7 惧 (<CJK Ideograph>) 11755 0x70AC 炬 (<CJK Ideograph>) 11756 0x5267 剧 (<CJK Ideograph>) 11757 0x6350 捐 (<CJK Ideograph>) 11758 0x9E43 鹃 (<CJK Ideograph>) 11759 0x5A1F 娟 (<CJK Ideograph>) 11760 0x5026 倦 (<CJK Ideograph>) 11761 0x7737 眷 (<CJK Ideograph>) 11762 0x5377 卷 (<CJK Ideograph>) 11763 0x7EE2 绢 (<CJK Ideograph>) 11764 0x6485 撅 (<CJK Ideograph>) 11765 0x652B 攫 (<CJK Ideograph>) 11766 0x6289 抉 (<CJK Ideograph>) 11767 0x6398 掘 (<CJK Ideograph>) 11768 0x5014 倔 (<CJK Ideograph>) 11769 0x7235 爵 (<CJK Ideograph>) 11770 0x89C9 觉 (<CJK Ideograph>) 11771 0x51B3 决 (<CJK Ideograph>) 11772 0x8BC0 诀 (<CJK Ideograph>) 11773 0x7EDD 绝 (<CJK Ideograph>) 11774 0x5747 均 (<CJK Ideograph>) 11775 0x83CC 菌 (<CJK Ideograph>) 11776 0x94A7 钧 (<CJK Ideograph>) 11777 0x519B 军 (<CJK Ideograph>) 11778 0x541B 君 (<CJK Ideograph>) 11779 0x5CFB 峻 (<CJK Ideograph>) 11780 0x7DFB 緻 (<CJK Ideograph>) 11781 0x7DFC 緼 (<CJK Ideograph>) 11782 0x7DFD 緽 (<CJK Ideograph>) 11783 0x7DFE 緾 (<CJK Ideograph>) 11784 0x7DFF 緿 (<CJK Ideograph>) 11785 0x7E00 縀 (<CJK Ideograph>) 11786 0x7E01 縁 (<CJK Ideograph>) 11787 0x7E02 縂 (<CJK Ideograph>) 11788 0x7E03 縃 (<CJK Ideograph>) 11789 0x7E04 縄 (<CJK Ideograph>) 11790 0x7E05 縅 (<CJK Ideograph>) 11791 0x7E06 縆 (<CJK Ideograph>) 11792 0x7E07 縇 (<CJK Ideograph>) 11793 0x7E08 縈 (<CJK Ideograph>) 11794 0x7E09 縉 (<CJK Ideograph>) 11795 0x7E0A 縊 (<CJK Ideograph>) 11796 0x7E0B 縋 (<CJK Ideograph>) 11797 0x7E0C 縌 (<CJK Ideograph>) 11798 0x7E0D 縍 (<CJK Ideograph>) 11799 0x7E0E 縎 (<CJK Ideograph>) 11800 0x7E0F 縏 (<CJK Ideograph>) 11801 0x7E10 縐 (<CJK Ideograph>) 11802 0x7E11 縑 (<CJK Ideograph>) 11803 0x7E12 縒 (<CJK Ideograph>) 11804 0x7E13 縓 (<CJK Ideograph>) 11805 0x7E14 縔 (<CJK Ideograph>) 11806 0x7E15 縕 (<CJK Ideograph>) 11807 0x7E16 縖 (<CJK Ideograph>) 11808 0x7E17 縗 (<CJK Ideograph>) 11809 0x7E18 縘 (<CJK Ideograph>) 11810 0x7E19 縙 (<CJK Ideograph>) 11811 0x7E1A 縚 (<CJK Ideograph>) 11812 0x7E1B 縛 (<CJK Ideograph>) 11813 0x7E1C 縜 (<CJK Ideograph>) 11814 0x7E1D 縝 (<CJK Ideograph>) 11815 0x7E1E 縞 (<CJK Ideograph>) 11816 0x7E1F 縟 (<CJK Ideograph>) 11817 0x7E20 縠 (<CJK Ideograph>) 11818 0x7E21 縡 (<CJK Ideograph>) 11819 0x7E22 縢 (<CJK Ideograph>) 11820 0x7E23 縣 (<CJK Ideograph>) 11821 0x7E24 縤 (<CJK Ideograph>) 11822 0x7E25 縥 (<CJK Ideograph>) 11823 0x7E26 縦 (<CJK Ideograph>) 11824 0x7E27 縧 (<CJK Ideograph>) 11825 0x7E28 縨 (<CJK Ideograph>) 11826 0x7E29 縩 (<CJK Ideograph>) 11827 0x7E2A 縪 (<CJK Ideograph>) 11828 0x7E2B 縫 (<CJK Ideograph>) 11829 0x7E2C 縬 (<CJK Ideograph>) 11830 0x7E2D 縭 (<CJK Ideograph>) 11831 0x7E2E 縮 (<CJK Ideograph>) 11832 0x7E2F 縯 (<CJK Ideograph>) 11833 0x7E30 縰 (<CJK Ideograph>) 11834 0x7E31 縱 (<CJK Ideograph>) 11835 0x7E32 縲 (<CJK Ideograph>) 11836 0x7E33 縳 (<CJK Ideograph>) 11837 0x7E34 縴 (<CJK Ideograph>) 11838 0x7E35 縵 (<CJK Ideograph>) 11839 0x7E36 縶 (<CJK Ideograph>) 11840 0x7E37 縷 (<CJK Ideograph>) 11841 0x7E38 縸 (<CJK Ideograph>) 11842 0x7E39 縹 (<CJK Ideograph>) 11843 0x7E3A 縺 (<CJK Ideograph>) 11844 0x7E3C 縼 (<CJK Ideograph>) 11845 0x7E3D 總 (<CJK Ideograph>) 11846 0x7E3E 績 (<CJK Ideograph>) 11847 0x7E3F 縿 (<CJK Ideograph>) 11848 0x7E40 繀 (<CJK Ideograph>) 11849 0x7E42 繂 (<CJK Ideograph>) 11850 0x7E43 繃 (<CJK Ideograph>) 11851 0x7E44 繄 (<CJK Ideograph>) 11852 0x7E45 繅 (<CJK Ideograph>) 11853 0x7E46 繆 (<CJK Ideograph>) 11854 0x7E48 繈 (<CJK Ideograph>) 11855 0x7E49 繉 (<CJK Ideograph>) 11856 0x7E4A 繊 (<CJK Ideograph>) 11857 0x7E4B 繋 (<CJK Ideograph>) 11858 0x7E4C 繌 (<CJK Ideograph>) 11859 0x7E4D 繍 (<CJK Ideograph>) 11860 0x7E4E 繎 (<CJK Ideograph>) 11861 0x7E4F 繏 (<CJK Ideograph>) 11862 0x7E50 繐 (<CJK Ideograph>) 11863 0x7E51 繑 (<CJK Ideograph>) 11864 0x7E52 繒 (<CJK Ideograph>) 11865 0x7E53 繓 (<CJK Ideograph>) 11866 0x7E54 織 (<CJK Ideograph>) 11867 0x7E55 繕 (<CJK Ideograph>) 11868 0x7E56 繖 (<CJK Ideograph>) 11869 0x7E57 繗 (<CJK Ideograph>) 11870 0x7E58 繘 (<CJK Ideograph>) 11871 0x7E59 繙 (<CJK Ideograph>) 11872 0x7E5A 繚 (<CJK Ideograph>) 11873 0x7E5B 繛 (<CJK Ideograph>) 11874 0x7E5C 繜 (<CJK Ideograph>) 11875 0x7E5D 繝 (<CJK Ideograph>) 11876 0x4FCA 俊 (<CJK Ideograph>) 11877 0x7AE3 竣 (<CJK Ideograph>) 11878 0x6D5A 浚 (<CJK Ideograph>) 11879 0x90E1 郡 (<CJK Ideograph>) 11880 0x9A8F 骏 (<CJK Ideograph>) 11881 0x5580 喀 (<CJK Ideograph>) 11882 0x5496 咖 (<CJK Ideograph>) 11883 0x5361 卡 (<CJK Ideograph>) 11884 0x54AF 咯 (<CJK Ideograph>) 11885 0x5F00 开 (<CJK Ideograph>) 11886 0x63E9 揩 (<CJK Ideograph>) 11887 0x6977 楷 (<CJK Ideograph>) 11888 0x51EF 凯 (<CJK Ideograph>) 11889 0x6168 慨 (<CJK Ideograph>) 11890 0x520A 刊 (<CJK Ideograph>) 11891 0x582A 堪 (<CJK Ideograph>) 11892 0x52D8 勘 (<CJK Ideograph>) 11893 0x574E 坎 (<CJK Ideograph>) 11894 0x780D 砍 (<CJK Ideograph>) 11895 0x770B 看 (<CJK Ideograph>) 11896 0x5EB7 康 (<CJK Ideograph>) 11897 0x6177 慷 (<CJK Ideograph>) 11898 0x7CE0 糠 (<CJK Ideograph>) 11899 0x625B 扛 (<CJK Ideograph>) 11900 0x6297 抗 (<CJK Ideograph>) 11901 0x4EA2 亢 (<CJK Ideograph>) 11902 0x7095 炕 (<CJK Ideograph>) 11903 0x8003 考 (<CJK Ideograph>) 11904 0x62F7 拷 (<CJK Ideograph>) 11905 0x70E4 烤 (<CJK Ideograph>) 11906 0x9760 靠 (<CJK Ideograph>) 11907 0x5777 坷 (<CJK Ideograph>) 11908 0x82DB 苛 (<CJK Ideograph>) 11909 0x67EF 柯 (<CJK Ideograph>) 11910 0x68F5 棵 (<CJK Ideograph>) 11911 0x78D5 磕 (<CJK Ideograph>) 11912 0x9897 颗 (<CJK Ideograph>) 11913 0x79D1 科 (<CJK Ideograph>) 11914 0x58F3 壳 (<CJK Ideograph>) 11915 0x54B3 咳 (<CJK Ideograph>) 11916 0x53EF 可 (<CJK Ideograph>) 11917 0x6E34 渴 (<CJK Ideograph>) 11918 0x514B 克 (<CJK Ideograph>) 11919 0x523B 刻 (<CJK Ideograph>) 11920 0x5BA2 客 (<CJK Ideograph>) 11921 0x8BFE 课 (<CJK Ideograph>) 11922 0x80AF 肯 (<CJK Ideograph>) 11923 0x5543 啃 (<CJK Ideograph>) 11924 0x57A6 垦 (<CJK Ideograph>) 11925 0x6073 恳 (<CJK Ideograph>) 11926 0x5751 坑 (<CJK Ideograph>) 11927 0x542D 吭 (<CJK Ideograph>) 11928 0x7A7A 空 (<CJK Ideograph>) 11929 0x6050 恐 (<CJK Ideograph>) 11930 0x5B54 孔 (<CJK Ideograph>) 11931 0x63A7 控 (<CJK Ideograph>) 11932 0x62A0 抠 (<CJK Ideograph>) 11933 0x53E3 口 (<CJK Ideograph>) 11934 0x6263 扣 (<CJK Ideograph>) 11935 0x5BC7 寇 (<CJK Ideograph>) 11936 0x67AF 枯 (<CJK Ideograph>) 11937 0x54ED 哭 (<CJK Ideograph>) 11938 0x7A9F 窟 (<CJK Ideograph>) 11939 0x82E6 苦 (<CJK Ideograph>) 11940 0x9177 酷 (<CJK Ideograph>) 11941 0x5E93 库 (<CJK Ideograph>) 11942 0x88E4 裤 (<CJK Ideograph>) 11943 0x5938 夸 (<CJK Ideograph>) 11944 0x57AE 垮 (<CJK Ideograph>) 11945 0x630E 挎 (<CJK Ideograph>) 11946 0x8DE8 跨 (<CJK Ideograph>) 11947 0x80EF 胯 (<CJK Ideograph>) 11948 0x5757 块 (<CJK Ideograph>) 11949 0x7B77 筷 (<CJK Ideograph>) 11950 0x4FA9 侩 (<CJK Ideograph>) 11951 0x5FEB 快 (<CJK Ideograph>) 11952 0x5BBD 宽 (<CJK Ideograph>) 11953 0x6B3E 款 (<CJK Ideograph>) 11954 0x5321 匡 (<CJK Ideograph>) 11955 0x7B50 筐 (<CJK Ideograph>) 11956 0x72C2 狂 (<CJK Ideograph>) 11957 0x6846 框 (<CJK Ideograph>) 11958 0x77FF 矿 (<CJK Ideograph>) 11959 0x7736 眶 (<CJK Ideograph>) 11960 0x65F7 旷 (<CJK Ideograph>) 11961 0x51B5 况 (<CJK Ideograph>) 11962 0x4E8F 亏 (<CJK Ideograph>) 11963 0x76D4 盔 (<CJK Ideograph>) 11964 0x5CBF 岿 (<CJK Ideograph>) 11965 0x7AA5 窥 (<CJK Ideograph>) 11966 0x8475 葵 (<CJK Ideograph>) 11967 0x594E 奎 (<CJK Ideograph>) 11968 0x9B41 魁 (<CJK Ideograph>) 11969 0x5080 傀 (<CJK Ideograph>) 11970 0x7E5E 繞 (<CJK Ideograph>) 11971 0x7E5F 繟 (<CJK Ideograph>) 11972 0x7E60 繠 (<CJK Ideograph>) 11973 0x7E61 繡 (<CJK Ideograph>) 11974 0x7E62 繢 (<CJK Ideograph>) 11975 0x7E63 繣 (<CJK Ideograph>) 11976 0x7E64 繤 (<CJK Ideograph>) 11977 0x7E65 繥 (<CJK Ideograph>) 11978 0x7E66 繦 (<CJK Ideograph>) 11979 0x7E67 繧 (<CJK Ideograph>) 11980 0x7E68 繨 (<CJK Ideograph>) 11981 0x7E69 繩 (<CJK Ideograph>) 11982 0x7E6A 繪 (<CJK Ideograph>) 11983 0x7E6B 繫 (<CJK Ideograph>) 11984 0x7E6C 繬 (<CJK Ideograph>) 11985 0x7E6D 繭 (<CJK Ideograph>) 11986 0x7E6E 繮 (<CJK Ideograph>) 11987 0x7E6F 繯 (<CJK Ideograph>) 11988 0x7E70 繰 (<CJK Ideograph>) 11989 0x7E71 繱 (<CJK Ideograph>) 11990 0x7E72 繲 (<CJK Ideograph>) 11991 0x7E73 繳 (<CJK Ideograph>) 11992 0x7E74 繴 (<CJK Ideograph>) 11993 0x7E75 繵 (<CJK Ideograph>) 11994 0x7E76 繶 (<CJK Ideograph>) 11995 0x7E77 繷 (<CJK Ideograph>) 11996 0x7E78 繸 (<CJK Ideograph>) 11997 0x7E79 繹 (<CJK Ideograph>) 11998 0x7E7A 繺 (<CJK Ideograph>) 11999 0x7E7B 繻 (<CJK Ideograph>) 12000 0x7E7C 繼 (<CJK Ideograph>) 12001 0x7E7D 繽 (<CJK Ideograph>) 12002 0x7E7E 繾 (<CJK Ideograph>) 12003 0x7E7F 繿 (<CJK Ideograph>) 12004 0x7E80 纀 (<CJK Ideograph>) 12005 0x7E81 纁 (<CJK Ideograph>) 12006 0x7E83 纃 (<CJK Ideograph>) 12007 0x7E84 纄 (<CJK Ideograph>) 12008 0x7E85 纅 (<CJK Ideograph>) 12009 0x7E86 纆 (<CJK Ideograph>) 12010 0x7E87 纇 (<CJK Ideograph>) 12011 0x7E88 纈 (<CJK Ideograph>) 12012 0x7E89 纉 (<CJK Ideograph>) 12013 0x7E8A 纊 (<CJK Ideograph>) 12014 0x7E8B 纋 (<CJK Ideograph>) 12015 0x7E8C 續 (<CJK Ideograph>) 12016 0x7E8D 纍 (<CJK Ideograph>) 12017 0x7E8E 纎 (<CJK Ideograph>) 12018 0x7E8F 纏 (<CJK Ideograph>) 12019 0x7E90 纐 (<CJK Ideograph>) 12020 0x7E91 纑 (<CJK Ideograph>) 12021 0x7E92 纒 (<CJK Ideograph>) 12022 0x7E93 纓 (<CJK Ideograph>) 12023 0x7E94 纔 (<CJK Ideograph>) 12024 0x7E95 纕 (<CJK Ideograph>) 12025 0x7E96 纖 (<CJK Ideograph>) 12026 0x7E97 纗 (<CJK Ideograph>) 12027 0x7E98 纘 (<CJK Ideograph>) 12028 0x7E99 纙 (<CJK Ideograph>) 12029 0x7E9A 纚 (<CJK Ideograph>) 12030 0x7E9C 纜 (<CJK Ideograph>) 12031 0x7E9D 纝 (<CJK Ideograph>) 12032 0x7E9E 纞 (<CJK Ideograph>) 12033 0x7EAE 纮 (<CJK Ideograph>) 12034 0x7EB4 纴 (<CJK Ideograph>) 12035 0x7EBB 纻 (<CJK Ideograph>) 12036 0x7EBC 纼 (<CJK Ideograph>) 12037 0x7ED6 绖 (<CJK Ideograph>) 12038 0x7EE4 绤 (<CJK Ideograph>) 12039 0x7EEC 绬 (<CJK Ideograph>) 12040 0x7EF9 绹 (<CJK Ideograph>) 12041 0x7F0A 缊 (<CJK Ideograph>) 12042 0x7F10 缐 (<CJK Ideograph>) 12043 0x7F1E 缞 (<CJK Ideograph>) 12044 0x7F37 缷 (<CJK Ideograph>) 12045 0x7F39 缹 (<CJK Ideograph>) 12046 0x7F3B 缻 (<CJK Ideograph>) 12047 0x7F3C 缼 (<CJK Ideograph>) 12048 0x7F3D 缽 (<CJK Ideograph>) 12049 0x7F3E 缾 (<CJK Ideograph>) 12050 0x7F3F 缿 (<CJK Ideograph>) 12051 0x7F40 罀 (<CJK Ideograph>) 12052 0x7F41 罁 (<CJK Ideograph>) 12053 0x7F43 罃 (<CJK Ideograph>) 12054 0x7F46 罆 (<CJK Ideograph>) 12055 0x7F47 罇 (<CJK Ideograph>) 12056 0x7F48 罈 (<CJK Ideograph>) 12057 0x7F49 罉 (<CJK Ideograph>) 12058 0x7F4A 罊 (<CJK Ideograph>) 12059 0x7F4B 罋 (<CJK Ideograph>) 12060 0x7F4C 罌 (<CJK Ideograph>) 12061 0x7F4D 罍 (<CJK Ideograph>) 12062 0x7F4E 罎 (<CJK Ideograph>) 12063 0x7F4F 罏 (<CJK Ideograph>) 12064 0x7F52 罒 (<CJK Ideograph>) 12065 0x7F53 罓 (<CJK Ideograph>) 12066 0x9988 馈 (<CJK Ideograph>) 12067 0x6127 愧 (<CJK Ideograph>) 12068 0x6E83 溃 (<CJK Ideograph>) 12069 0x5764 坤 (<CJK Ideograph>) 12070 0x6606 昆 (<CJK Ideograph>) 12071 0x6346 捆 (<CJK Ideograph>) 12072 0x56F0 困 (<CJK Ideograph>) 12073 0x62EC 括 (<CJK Ideograph>) 12074 0x6269 扩 (<CJK Ideograph>) 12075 0x5ED3 廓 (<CJK Ideograph>) 12076 0x9614 阔 (<CJK Ideograph>) 12077 0x5783 垃 (<CJK Ideograph>) 12078 0x62C9 拉 (<CJK Ideograph>) 12079 0x5587 喇 (<CJK Ideograph>) 12080 0x8721 蜡 (<CJK Ideograph>) 12081 0x814A 腊 (<CJK Ideograph>) 12082 0x8FA3 辣 (<CJK Ideograph>) 12083 0x5566 啦 (<CJK Ideograph>) 12084 0x83B1 莱 (<CJK Ideograph>) 12085 0x6765 来 (<CJK Ideograph>) 12086 0x8D56 赖 (<CJK Ideograph>) 12087 0x84DD 蓝 (<CJK Ideograph>) 12088 0x5A6A 婪 (<CJK Ideograph>) 12089 0x680F 栏 (<CJK Ideograph>) 12090 0x62E6 拦 (<CJK Ideograph>) 12091 0x7BEE 篮 (<CJK Ideograph>) 12092 0x9611 阑 (<CJK Ideograph>) 12093 0x5170 兰 (<CJK Ideograph>) 12094 0x6F9C 澜 (<CJK Ideograph>) 12095 0x8C30 谰 (<CJK Ideograph>) 12096 0x63FD 揽 (<CJK Ideograph>) 12097 0x89C8 览 (<CJK Ideograph>) 12098 0x61D2 懒 (<CJK Ideograph>) 12099 0x7F06 缆 (<CJK Ideograph>) 12100 0x70C2 烂 (<CJK Ideograph>) 12101 0x6EE5 滥 (<CJK Ideograph>) 12102 0x7405 琅 (<CJK Ideograph>) 12103 0x6994 榔 (<CJK Ideograph>) 12104 0x72FC 狼 (<CJK Ideograph>) 12105 0x5ECA 廊 (<CJK Ideograph>) 12106 0x90CE 郎 (<CJK Ideograph>) 12107 0x6717 朗 (<CJK Ideograph>) 12108 0x6D6A 浪 (<CJK Ideograph>) 12109 0x635E 捞 (<CJK Ideograph>) 12110 0x52B3 劳 (<CJK Ideograph>) 12111 0x7262 牢 (<CJK Ideograph>) 12112 0x8001 老 (<CJK Ideograph>) 12113 0x4F6C 佬 (<CJK Ideograph>) 12114 0x59E5 姥 (<CJK Ideograph>) 12115 0x916A 酪 (<CJK Ideograph>) 12116 0x70D9 烙 (<CJK Ideograph>) 12117 0x6D9D 涝 (<CJK Ideograph>) 12118 0x52D2 勒 (<CJK Ideograph>) 12119 0x4E50 乐 (<CJK Ideograph>) 12120 0x96F7 雷 (<CJK Ideograph>) 12121 0x956D 镭 (<CJK Ideograph>) 12122 0x857E 蕾 (<CJK Ideograph>) 12123 0x78CA 磊 (<CJK Ideograph>) 12124 0x7D2F 累 (<CJK Ideograph>) 12125 0x5121 儡 (<CJK Ideograph>) 12126 0x5792 垒 (<CJK Ideograph>) 12127 0x64C2 擂 (<CJK Ideograph>) 12128 0x808B 肋 (<CJK Ideograph>) 12129 0x7C7B 类 (<CJK Ideograph>) 12130 0x6CEA 泪 (<CJK Ideograph>) 12131 0x68F1 棱 (<CJK Ideograph>) 12132 0x695E 楞 (<CJK Ideograph>) 12133 0x51B7 冷 (<CJK Ideograph>) 12134 0x5398 厘 (<CJK Ideograph>) 12135 0x68A8 梨 (<CJK Ideograph>) 12136 0x7281 犁 (<CJK Ideograph>) 12137 0x9ECE 黎 (<CJK Ideograph>) 12138 0x7BF1 篱 (<CJK Ideograph>) 12139 0x72F8 狸 (<CJK Ideograph>) 12140 0x79BB 离 (<CJK Ideograph>) 12141 0x6F13 漓 (<CJK Ideograph>) 12142 0x7406 理 (<CJK Ideograph>) 12143 0x674E 李 (<CJK Ideograph>) 12144 0x91CC 里 (<CJK Ideograph>) 12145 0x9CA4 鲤 (<CJK Ideograph>) 12146 0x793C 礼 (<CJK Ideograph>) 12147 0x8389 莉 (<CJK Ideograph>) 12148 0x8354 荔 (<CJK Ideograph>) 12149 0x540F 吏 (<CJK Ideograph>) 12150 0x6817 栗 (<CJK Ideograph>) 12151 0x4E3D 丽 (<CJK Ideograph>) 12152 0x5389 厉 (<CJK Ideograph>) 12153 0x52B1 励 (<CJK Ideograph>) 12154 0x783E 砾 (<CJK Ideograph>) 12155 0x5386 历 (<CJK Ideograph>) 12156 0x5229 利 (<CJK Ideograph>) 12157 0x5088 傈 (<CJK Ideograph>) 12158 0x4F8B 例 (<CJK Ideograph>) 12159 0x4FD0 俐 (<CJK Ideograph>) 12160 0x7F56 罖 (<CJK Ideograph>) 12161 0x7F59 罙 (<CJK Ideograph>) 12162 0x7F5B 罛 (<CJK Ideograph>) 12163 0x7F5C 罜 (<CJK Ideograph>) 12164 0x7F5D 罝 (<CJK Ideograph>) 12165 0x7F5E 罞 (<CJK Ideograph>) 12166 0x7F60 罠 (<CJK Ideograph>) 12167 0x7F63 罣 (<CJK Ideograph>) 12168 0x7F64 罤 (<CJK Ideograph>) 12169 0x7F65 罥 (<CJK Ideograph>) 12170 0x7F66 罦 (<CJK Ideograph>) 12171 0x7F67 罧 (<CJK Ideograph>) 12172 0x7F6B 罫 (<CJK Ideograph>) 12173 0x7F6C 罬 (<CJK Ideograph>) 12174 0x7F6D 罭 (<CJK Ideograph>) 12175 0x7F6F 罯 (<CJK Ideograph>) 12176 0x7F70 罰 (<CJK Ideograph>) 12177 0x7F73 罳 (<CJK Ideograph>) 12178 0x7F75 罵 (<CJK Ideograph>) 12179 0x7F76 罶 (<CJK Ideograph>) 12180 0x7F77 罷 (<CJK Ideograph>) 12181 0x7F78 罸 (<CJK Ideograph>) 12182 0x7F7A 罺 (<CJK Ideograph>) 12183 0x7F7B 罻 (<CJK Ideograph>) 12184 0x7F7C 罼 (<CJK Ideograph>) 12185 0x7F7D 罽 (<CJK Ideograph>) 12186 0x7F7F 罿 (<CJK Ideograph>) 12187 0x7F80 羀 (<CJK Ideograph>) 12188 0x7F82 羂 (<CJK Ideograph>) 12189 0x7F83 羃 (<CJK Ideograph>) 12190 0x7F84 羄 (<CJK Ideograph>) 12191 0x7F85 羅 (<CJK Ideograph>) 12192 0x7F86 羆 (<CJK Ideograph>) 12193 0x7F87 羇 (<CJK Ideograph>) 12194 0x7F88 羈 (<CJK Ideograph>) 12195 0x7F89 羉 (<CJK Ideograph>) 12196 0x7F8B 羋 (<CJK Ideograph>) 12197 0x7F8D 羍 (<CJK Ideograph>) 12198 0x7F8F 羏 (<CJK Ideograph>) 12199 0x7F90 羐 (<CJK Ideograph>) 12200 0x7F91 羑 (<CJK Ideograph>) 12201 0x7F92 羒 (<CJK Ideograph>) 12202 0x7F93 羓 (<CJK Ideograph>) 12203 0x7F95 羕 (<CJK Ideograph>) 12204 0x7F96 羖 (<CJK Ideograph>) 12205 0x7F97 羗 (<CJK Ideograph>) 12206 0x7F98 羘 (<CJK Ideograph>) 12207 0x7F99 羙 (<CJK Ideograph>) 12208 0x7F9B 羛 (<CJK Ideograph>) 12209 0x7F9C 羜 (<CJK Ideograph>) 12210 0x7FA0 羠 (<CJK Ideograph>) 12211 0x7FA2 羢 (<CJK Ideograph>) 12212 0x7FA3 羣 (<CJK Ideograph>) 12213 0x7FA5 羥 (<CJK Ideograph>) 12214 0x7FA6 羦 (<CJK Ideograph>) 12215 0x7FA8 羨 (<CJK Ideograph>) 12216 0x7FA9 義 (<CJK Ideograph>) 12217 0x7FAA 羪 (<CJK Ideograph>) 12218 0x7FAB 羫 (<CJK Ideograph>) 12219 0x7FAC 羬 (<CJK Ideograph>) 12220 0x7FAD 羭 (<CJK Ideograph>) 12221 0x7FAE 羮 (<CJK Ideograph>) 12222 0x7FB1 羱 (<CJK Ideograph>) 12223 0x7FB3 羳 (<CJK Ideograph>) 12224 0x7FB4 羴 (<CJK Ideograph>) 12225 0x7FB5 羵 (<CJK Ideograph>) 12226 0x7FB6 羶 (<CJK Ideograph>) 12227 0x7FB7 羷 (<CJK Ideograph>) 12228 0x7FBA 羺 (<CJK Ideograph>) 12229 0x7FBB 羻 (<CJK Ideograph>) 12230 0x7FBE 羾 (<CJK Ideograph>) 12231 0x7FC0 翀 (<CJK Ideograph>) 12232 0x7FC2 翂 (<CJK Ideograph>) 12233 0x7FC3 翃 (<CJK Ideograph>) 12234 0x7FC4 翄 (<CJK Ideograph>) 12235 0x7FC6 翆 (<CJK Ideograph>) 12236 0x7FC7 翇 (<CJK Ideograph>) 12237 0x7FC8 翈 (<CJK Ideograph>) 12238 0x7FC9 翉 (<CJK Ideograph>) 12239 0x7FCB 翋 (<CJK Ideograph>) 12240 0x7FCD 翍 (<CJK Ideograph>) 12241 0x7FCF 翏 (<CJK Ideograph>) 12242 0x7FD0 翐 (<CJK Ideograph>) 12243 0x7FD1 翑 (<CJK Ideograph>) 12244 0x7FD2 習 (<CJK Ideograph>) 12245 0x7FD3 翓 (<CJK Ideograph>) 12246 0x7FD6 翖 (<CJK Ideograph>) 12247 0x7FD7 翗 (<CJK Ideograph>) 12248 0x7FD9 翙 (<CJK Ideograph>) 12249 0x7FDA 翚 (<CJK Ideograph>) 12250 0x7FDB 翛 (<CJK Ideograph>) 12251 0x7FDC 翜 (<CJK Ideograph>) 12252 0x7FDD 翝 (<CJK Ideograph>) 12253 0x7FDE 翞 (<CJK Ideograph>) 12254 0x7FE2 翢 (<CJK Ideograph>) 12255 0x7FE3 翣 (<CJK Ideograph>) 12256 0x75E2 痢 (<CJK Ideograph>) 12257 0x7ACB 立 (<CJK Ideograph>) 12258 0x7C92 粒 (<CJK Ideograph>) 12259 0x6CA5 沥 (<CJK Ideograph>) 12260 0x96B6 隶 (<CJK Ideograph>) 12261 0x529B 力 (<CJK Ideograph>) 12262 0x7483 璃 (<CJK Ideograph>) 12263 0x54E9 哩 (<CJK Ideograph>) 12264 0x4FE9 俩 (<CJK Ideograph>) 12265 0x8054 联 (<CJK Ideograph>) 12266 0x83B2 莲 (<CJK Ideograph>) 12267 0x8FDE 连 (<CJK Ideograph>) 12268 0x9570 镰 (<CJK Ideograph>) 12269 0x5EC9 廉 (<CJK Ideograph>) 12270 0x601C 怜 (<CJK Ideograph>) 12271 0x6D9F 涟 (<CJK Ideograph>) 12272 0x5E18 帘 (<CJK Ideograph>) 12273 0x655B 敛 (<CJK Ideograph>) 12274 0x8138 脸 (<CJK Ideograph>) 12275 0x94FE 链 (<CJK Ideograph>) 12276 0x604B 恋 (<CJK Ideograph>) 12277 0x70BC 炼 (<CJK Ideograph>) 12278 0x7EC3 练 (<CJK Ideograph>) 12279 0x7CAE 粮 (<CJK Ideograph>) 12280 0x51C9 凉 (<CJK Ideograph>) 12281 0x6881 梁 (<CJK Ideograph>) 12282 0x7CB1 粱 (<CJK Ideograph>) 12283 0x826F 良 (<CJK Ideograph>) 12284 0x4E24 两 (<CJK Ideograph>) 12285 0x8F86 辆 (<CJK Ideograph>) 12286 0x91CF 量 (<CJK Ideograph>) 12287 0x667E 晾 (<CJK Ideograph>) 12288 0x4EAE 亮 (<CJK Ideograph>) 12289 0x8C05 谅 (<CJK Ideograph>) 12290 0x64A9 撩 (<CJK Ideograph>) 12291 0x804A 聊 (<CJK Ideograph>) 12292 0x50DA 僚 (<CJK Ideograph>) 12293 0x7597 疗 (<CJK Ideograph>) 12294 0x71CE 燎 (<CJK Ideograph>) 12295 0x5BE5 寥 (<CJK Ideograph>) 12296 0x8FBD 辽 (<CJK Ideograph>) 12297 0x6F66 潦 (<CJK Ideograph>) 12298 0x4E86 了 (<CJK Ideograph>) 12299 0x6482 撂 (<CJK Ideograph>) 12300 0x9563 镣 (<CJK Ideograph>) 12301 0x5ED6 廖 (<CJK Ideograph>) 12302 0x6599 料 (<CJK Ideograph>) 12303 0x5217 列 (<CJK Ideograph>) 12304 0x88C2 裂 (<CJK Ideograph>) 12305 0x70C8 烈 (<CJK Ideograph>) 12306 0x52A3 劣 (<CJK Ideograph>) 12307 0x730E 猎 (<CJK Ideograph>) 12308 0x7433 琳 (<CJK Ideograph>) 12309 0x6797 林 (<CJK Ideograph>) 12310 0x78F7 磷 (<CJK Ideograph>) 12311 0x9716 霖 (<CJK Ideograph>) 12312 0x4E34 临 (<CJK Ideograph>) 12313 0x90BB 邻 (<CJK Ideograph>) 12314 0x9CDE 鳞 (<CJK Ideograph>) 12315 0x6DCB 淋 (<CJK Ideograph>) 12316 0x51DB 凛 (<CJK Ideograph>) 12317 0x8D41 赁 (<CJK Ideograph>) 12318 0x541D 吝 (<CJK Ideograph>) 12319 0x62CE 拎 (<CJK Ideograph>) 12320 0x73B2 玲 (<CJK Ideograph>) 12321 0x83F1 菱 (<CJK Ideograph>) 12322 0x96F6 零 (<CJK Ideograph>) 12323 0x9F84 龄 (<CJK Ideograph>) 12324 0x94C3 铃 (<CJK Ideograph>) 12325 0x4F36 伶 (<CJK Ideograph>) 12326 0x7F9A 羚 (<CJK Ideograph>) 12327 0x51CC 凌 (<CJK Ideograph>) 12328 0x7075 灵 (<CJK Ideograph>) 12329 0x9675 陵 (<CJK Ideograph>) 12330 0x5CAD 岭 (<CJK Ideograph>) 12331 0x9886 领 (<CJK Ideograph>) 12332 0x53E6 另 (<CJK Ideograph>) 12333 0x4EE4 令 (<CJK Ideograph>) 12334 0x6E9C 溜 (<CJK Ideograph>) 12335 0x7409 琉 (<CJK Ideograph>) 12336 0x69B4 榴 (<CJK Ideograph>) 12337 0x786B 硫 (<CJK Ideograph>) 12338 0x998F 馏 (<CJK Ideograph>) 12339 0x7559 留 (<CJK Ideograph>) 12340 0x5218 刘 (<CJK Ideograph>) 12341 0x7624 瘤 (<CJK Ideograph>) 12342 0x6D41 流 (<CJK Ideograph>) 12343 0x67F3 柳 (<CJK Ideograph>) 12344 0x516D 六 (<CJK Ideograph>) 12345 0x9F99 龙 (<CJK Ideograph>) 12346 0x804B 聋 (<CJK Ideograph>) 12347 0x5499 咙 (<CJK Ideograph>) 12348 0x7B3C 笼 (<CJK Ideograph>) 12349 0x7ABF 窿 (<CJK Ideograph>) 12350 0x7FE4 翤 (<CJK Ideograph>) 12351 0x7FE7 翧 (<CJK Ideograph>) 12352 0x7FE8 翨 (<CJK Ideograph>) 12353 0x7FEA 翪 (<CJK Ideograph>) 12354 0x7FEB 翫 (<CJK Ideograph>) 12355 0x7FEC 翬 (<CJK Ideograph>) 12356 0x7FED 翭 (<CJK Ideograph>) 12357 0x7FEF 翯 (<CJK Ideograph>) 12358 0x7FF2 翲 (<CJK Ideograph>) 12359 0x7FF4 翴 (<CJK Ideograph>) 12360 0x7FF5 翵 (<CJK Ideograph>) 12361 0x7FF6 翶 (<CJK Ideograph>) 12362 0x7FF7 翷 (<CJK Ideograph>) 12363 0x7FF8 翸 (<CJK Ideograph>) 12364 0x7FF9 翹 (<CJK Ideograph>) 12365 0x7FFA 翺 (<CJK Ideograph>) 12366 0x7FFD 翽 (<CJK Ideograph>) 12367 0x7FFE 翾 (<CJK Ideograph>) 12368 0x7FFF 翿 (<CJK Ideograph>) 12369 0x8002 耂 (<CJK Ideograph>) 12370 0x8007 耇 (<CJK Ideograph>) 12371 0x8008 耈 (<CJK Ideograph>) 12372 0x8009 耉 (<CJK Ideograph>) 12373 0x800A 耊 (<CJK Ideograph>) 12374 0x800E 耎 (<CJK Ideograph>) 12375 0x800F 耏 (<CJK Ideograph>) 12376 0x8011 耑 (<CJK Ideograph>) 12377 0x8013 耓 (<CJK Ideograph>) 12378 0x801A 耚 (<CJK Ideograph>) 12379 0x801B 耛 (<CJK Ideograph>) 12380 0x801D 耝 (<CJK Ideograph>) 12381 0x801E 耞 (<CJK Ideograph>) 12382 0x801F 耟 (<CJK Ideograph>) 12383 0x8021 耡 (<CJK Ideograph>) 12384 0x8023 耣 (<CJK Ideograph>) 12385 0x8024 耤 (<CJK Ideograph>) 12386 0x802B 耫 (<CJK Ideograph>) 12387 0x802C 耬 (<CJK Ideograph>) 12388 0x802D 耭 (<CJK Ideograph>) 12389 0x802E 耮 (<CJK Ideograph>) 12390 0x802F 耯 (<CJK Ideograph>) 12391 0x8030 耰 (<CJK Ideograph>) 12392 0x8032 耲 (<CJK Ideograph>) 12393 0x8034 耴 (<CJK Ideograph>) 12394 0x8039 耹 (<CJK Ideograph>) 12395 0x803A 耺 (<CJK Ideograph>) 12396 0x803C 耼 (<CJK Ideograph>) 12397 0x803E 耾 (<CJK Ideograph>) 12398 0x8040 聀 (<CJK Ideograph>) 12399 0x8041 聁 (<CJK Ideograph>) 12400 0x8044 聄 (<CJK Ideograph>) 12401 0x8045 聅 (<CJK Ideograph>) 12402 0x8047 聇 (<CJK Ideograph>) 12403 0x8048 聈 (<CJK Ideograph>) 12404 0x8049 聉 (<CJK Ideograph>) 12405 0x804E 聎 (<CJK Ideograph>) 12406 0x804F 聏 (<CJK Ideograph>) 12407 0x8050 聐 (<CJK Ideograph>) 12408 0x8051 聑 (<CJK Ideograph>) 12409 0x8053 聓 (<CJK Ideograph>) 12410 0x8055 聕 (<CJK Ideograph>) 12411 0x8056 聖 (<CJK Ideograph>) 12412 0x8057 聗 (<CJK Ideograph>) 12413 0x8059 聙 (<CJK Ideograph>) 12414 0x805B 聛 (<CJK Ideograph>) 12415 0x805C 聜 (<CJK Ideograph>) 12416 0x805D 聝 (<CJK Ideograph>) 12417 0x805E 聞 (<CJK Ideograph>) 12418 0x805F 聟 (<CJK Ideograph>) 12419 0x8060 聠 (<CJK Ideograph>) 12420 0x8061 聡 (<CJK Ideograph>) 12421 0x8062 聢 (<CJK Ideograph>) 12422 0x8063 聣 (<CJK Ideograph>) 12423 0x8064 聤 (<CJK Ideograph>) 12424 0x8065 聥 (<CJK Ideograph>) 12425 0x8066 聦 (<CJK Ideograph>) 12426 0x8067 聧 (<CJK Ideograph>) 12427 0x8068 聨 (<CJK Ideograph>) 12428 0x806B 聫 (<CJK Ideograph>) 12429 0x806C 聬 (<CJK Ideograph>) 12430 0x806D 聭 (<CJK Ideograph>) 12431 0x806E 聮 (<CJK Ideograph>) 12432 0x806F 聯 (<CJK Ideograph>) 12433 0x8070 聰 (<CJK Ideograph>) 12434 0x8072 聲 (<CJK Ideograph>) 12435 0x8073 聳 (<CJK Ideograph>) 12436 0x8074 聴 (<CJK Ideograph>) 12437 0x8075 聵 (<CJK Ideograph>) 12438 0x8076 聶 (<CJK Ideograph>) 12439 0x8077 職 (<CJK Ideograph>) 12440 0x8078 聸 (<CJK Ideograph>) 12441 0x8079 聹 (<CJK Ideograph>) 12442 0x807A 聺 (<CJK Ideograph>) 12443 0x807B 聻 (<CJK Ideograph>) 12444 0x807C 聼 (<CJK Ideograph>) 12445 0x807D 聽 (<CJK Ideograph>) 12446 0x9686 隆 (<CJK Ideograph>) 12447 0x5784 垄 (<CJK Ideograph>) 12448 0x62E2 拢 (<CJK Ideograph>) 12449 0x9647 陇 (<CJK Ideograph>) 12450 0x697C 楼 (<CJK Ideograph>) 12451 0x5A04 娄 (<CJK Ideograph>) 12452 0x6402 搂 (<CJK Ideograph>) 12453 0x7BD3 篓 (<CJK Ideograph>) 12454 0x6F0F 漏 (<CJK Ideograph>) 12455 0x964B 陋 (<CJK Ideograph>) 12456 0x82A6 芦 (<CJK Ideograph>) 12457 0x5362 卢 (<CJK Ideograph>) 12458 0x9885 颅 (<CJK Ideograph>) 12459 0x5E90 庐 (<CJK Ideograph>) 12460 0x7089 炉 (<CJK Ideograph>) 12461 0x63B3 掳 (<CJK Ideograph>) 12462 0x5364 卤 (<CJK Ideograph>) 12463 0x864F 虏 (<CJK Ideograph>) 12464 0x9C81 鲁 (<CJK Ideograph>) 12465 0x9E93 麓 (<CJK Ideograph>) 12466 0x788C 碌 (<CJK Ideograph>) 12467 0x9732 露 (<CJK Ideograph>) 12468 0x8DEF 路 (<CJK Ideograph>) 12469 0x8D42 赂 (<CJK Ideograph>) 12470 0x9E7F 鹿 (<CJK Ideograph>) 12471 0x6F5E 潞 (<CJK Ideograph>) 12472 0x7984 禄 (<CJK Ideograph>) 12473 0x5F55 录 (<CJK Ideograph>) 12474 0x9646 陆 (<CJK Ideograph>) 12475 0x622E 戮 (<CJK Ideograph>) 12476 0x9A74 驴 (<CJK Ideograph>) 12477 0x5415 吕 (<CJK Ideograph>) 12478 0x94DD 铝 (<CJK Ideograph>) 12479 0x4FA3 侣 (<CJK Ideograph>) 12480 0x65C5 旅 (<CJK Ideograph>) 12481 0x5C65 履 (<CJK Ideograph>) 12482 0x5C61 屡 (<CJK Ideograph>) 12483 0x7F15 缕 (<CJK Ideograph>) 12484 0x8651 虑 (<CJK Ideograph>) 12485 0x6C2F 氯 (<CJK Ideograph>) 12486 0x5F8B 律 (<CJK Ideograph>) 12487 0x7387 率 (<CJK Ideograph>) 12488 0x6EE4 滤 (<CJK Ideograph>) 12489 0x7EFF 绿 (<CJK Ideograph>) 12490 0x5CE6 峦 (<CJK Ideograph>) 12491 0x631B 挛 (<CJK Ideograph>) 12492 0x5B6A 孪 (<CJK Ideograph>) 12493 0x6EE6 滦 (<CJK Ideograph>) 12494 0x5375 卵 (<CJK Ideograph>) 12495 0x4E71 乱 (<CJK Ideograph>) 12496 0x63A0 掠 (<CJK Ideograph>) 12497 0x7565 略 (<CJK Ideograph>) 12498 0x62A1 抡 (<CJK Ideograph>) 12499 0x8F6E 轮 (<CJK Ideograph>) 12500 0x4F26 伦 (<CJK Ideograph>) 12501 0x4ED1 仑 (<CJK Ideograph>) 12502 0x6CA6 沦 (<CJK Ideograph>) 12503 0x7EB6 纶 (<CJK Ideograph>) 12504 0x8BBA 论 (<CJK Ideograph>) 12505 0x841D 萝 (<CJK Ideograph>) 12506 0x87BA 螺 (<CJK Ideograph>) 12507 0x7F57 罗 (<CJK Ideograph>) 12508 0x903B 逻 (<CJK Ideograph>) 12509 0x9523 锣 (<CJK Ideograph>) 12510 0x7BA9 箩 (<CJK Ideograph>) 12511 0x9AA1 骡 (<CJK Ideograph>) 12512 0x88F8 裸 (<CJK Ideograph>) 12513 0x843D 落 (<CJK Ideograph>) 12514 0x6D1B 洛 (<CJK Ideograph>) 12515 0x9A86 骆 (<CJK Ideograph>) 12516 0x7EDC 络 (<CJK Ideograph>) 12517 0x5988 妈 (<CJK Ideograph>) 12518 0x9EBB 麻 (<CJK Ideograph>) 12519 0x739B 玛 (<CJK Ideograph>) 12520 0x7801 码 (<CJK Ideograph>) 12521 0x8682 蚂 (<CJK Ideograph>) 12522 0x9A6C 马 (<CJK Ideograph>) 12523 0x9A82 骂 (<CJK Ideograph>) 12524 0x561B 嘛 (<CJK Ideograph>) 12525 0x5417 吗 (<CJK Ideograph>) 12526 0x57CB 埋 (<CJK Ideograph>) 12527 0x4E70 买 (<CJK Ideograph>) 12528 0x9EA6 麦 (<CJK Ideograph>) 12529 0x5356 卖 (<CJK Ideograph>) 12530 0x8FC8 迈 (<CJK Ideograph>) 12531 0x8109 脉 (<CJK Ideograph>) 12532 0x7792 瞒 (<CJK Ideograph>) 12533 0x9992 馒 (<CJK Ideograph>) 12534 0x86EE 蛮 (<CJK Ideograph>) 12535 0x6EE1 满 (<CJK Ideograph>) 12536 0x8513 蔓 (<CJK Ideograph>) 12537 0x66FC 曼 (<CJK Ideograph>) 12538 0x6162 慢 (<CJK Ideograph>) 12539 0x6F2B 漫 (<CJK Ideograph>) 12540 0x807E 聾 (<CJK Ideograph>) 12541 0x8081 肁 (<CJK Ideograph>) 12542 0x8082 肂 (<CJK Ideograph>) 12543 0x8085 肅 (<CJK Ideograph>) 12544 0x8088 肈 (<CJK Ideograph>) 12545 0x808A 肊 (<CJK Ideograph>) 12546 0x808D 肍 (<CJK Ideograph>) 12547 0x808E 肎 (<CJK Ideograph>) 12548 0x808F 肏 (<CJK Ideograph>) 12549 0x8090 肐 (<CJK Ideograph>) 12550 0x8091 肑 (<CJK Ideograph>) 12551 0x8092 肒 (<CJK Ideograph>) 12552 0x8094 肔 (<CJK Ideograph>) 12553 0x8095 肕 (<CJK Ideograph>) 12554 0x8097 肗 (<CJK Ideograph>) 12555 0x8099 肙 (<CJK Ideograph>) 12556 0x809E 肞 (<CJK Ideograph>) 12557 0x80A3 肣 (<CJK Ideograph>) 12558 0x80A6 肦 (<CJK Ideograph>) 12559 0x80A7 肧 (<CJK Ideograph>) 12560 0x80A8 肨 (<CJK Ideograph>) 12561 0x80AC 肬 (<CJK Ideograph>) 12562 0x80B0 肰 (<CJK Ideograph>) 12563 0x80B3 肳 (<CJK Ideograph>) 12564 0x80B5 肵 (<CJK Ideograph>) 12565 0x80B6 肶 (<CJK Ideograph>) 12566 0x80B8 肸 (<CJK Ideograph>) 12567 0x80B9 肹 (<CJK Ideograph>) 12568 0x80BB 肻 (<CJK Ideograph>) 12569 0x80C5 胅 (<CJK Ideograph>) 12570 0x80C7 胇 (<CJK Ideograph>) 12571 0x80C8 胈 (<CJK Ideograph>) 12572 0x80C9 胉 (<CJK Ideograph>) 12573 0x80CA 胊 (<CJK Ideograph>) 12574 0x80CB 胋 (<CJK Ideograph>) 12575 0x80CF 胏 (<CJK Ideograph>) 12576 0x80D0 胐 (<CJK Ideograph>) 12577 0x80D1 胑 (<CJK Ideograph>) 12578 0x80D2 胒 (<CJK Ideograph>) 12579 0x80D3 胓 (<CJK Ideograph>) 12580 0x80D4 胔 (<CJK Ideograph>) 12581 0x80D5 胕 (<CJK Ideograph>) 12582 0x80D8 胘 (<CJK Ideograph>) 12583 0x80DF 胟 (<CJK Ideograph>) 12584 0x80E0 胠 (<CJK Ideograph>) 12585 0x80E2 胢 (<CJK Ideograph>) 12586 0x80E3 胣 (<CJK Ideograph>) 12587 0x80E6 胦 (<CJK Ideograph>) 12588 0x80EE 胮 (<CJK Ideograph>) 12589 0x80F5 胵 (<CJK Ideograph>) 12590 0x80F7 胷 (<CJK Ideograph>) 12591 0x80F9 胹 (<CJK Ideograph>) 12592 0x80FB 胻 (<CJK Ideograph>) 12593 0x80FE 胾 (<CJK Ideograph>) 12594 0x80FF 胿 (<CJK Ideograph>) 12595 0x8100 脀 (<CJK Ideograph>) 12596 0x8101 脁 (<CJK Ideograph>) 12597 0x8103 脃 (<CJK Ideograph>) 12598 0x8104 脄 (<CJK Ideograph>) 12599 0x8105 脅 (<CJK Ideograph>) 12600 0x8107 脇 (<CJK Ideograph>) 12601 0x8108 脈 (<CJK Ideograph>) 12602 0x810B 脋 (<CJK Ideograph>) 12603 0x810C 脌 (<CJK Ideograph>) 12604 0x8115 脕 (<CJK Ideograph>) 12605 0x8117 脗 (<CJK Ideograph>) 12606 0x8119 脙 (<CJK Ideograph>) 12607 0x811B 脛 (<CJK Ideograph>) 12608 0x811C 脜 (<CJK Ideograph>) 12609 0x811D 脝 (<CJK Ideograph>) 12610 0x811F 脟 (<CJK Ideograph>) 12611 0x8120 脠 (<CJK Ideograph>) 12612 0x8121 脡 (<CJK Ideograph>) 12613 0x8122 脢 (<CJK Ideograph>) 12614 0x8123 脣 (<CJK Ideograph>) 12615 0x8124 脤 (<CJK Ideograph>) 12616 0x8125 脥 (<CJK Ideograph>) 12617 0x8126 脦 (<CJK Ideograph>) 12618 0x8127 脧 (<CJK Ideograph>) 12619 0x8128 脨 (<CJK Ideograph>) 12620 0x8129 脩 (<CJK Ideograph>) 12621 0x812A 脪 (<CJK Ideograph>) 12622 0x812B 脫 (<CJK Ideograph>) 12623 0x812D 脭 (<CJK Ideograph>) 12624 0x812E 脮 (<CJK Ideograph>) 12625 0x8130 脰 (<CJK Ideograph>) 12626 0x8133 脳 (<CJK Ideograph>) 12627 0x8134 脴 (<CJK Ideograph>) 12628 0x8135 脵 (<CJK Ideograph>) 12629 0x8137 脷 (<CJK Ideograph>) 12630 0x8139 脹 (<CJK Ideograph>) 12631 0x813A 脺 (<CJK Ideograph>) 12632 0x813B 脻 (<CJK Ideograph>) 12633 0x813C 脼 (<CJK Ideograph>) 12634 0x813D 脽 (<CJK Ideograph>) 12635 0x813F 脿 (<CJK Ideograph>) 12636 0x8C29 谩 (<CJK Ideograph>) 12637 0x8292 芒 (<CJK Ideograph>) 12638 0x832B 茫 (<CJK Ideograph>) 12639 0x76F2 盲 (<CJK Ideograph>) 12640 0x6C13 氓 (<CJK Ideograph>) 12641 0x5FD9 忙 (<CJK Ideograph>) 12642 0x83BD 莽 (<CJK Ideograph>) 12643 0x732B 猫 (<CJK Ideograph>) 12644 0x8305 茅 (<CJK Ideograph>) 12645 0x951A 锚 (<CJK Ideograph>) 12646 0x6BDB 毛 (<CJK Ideograph>) 12647 0x77DB 矛 (<CJK Ideograph>) 12648 0x94C6 铆 (<CJK Ideograph>) 12649 0x536F 卯 (<CJK Ideograph>) 12650 0x8302 茂 (<CJK Ideograph>) 12651 0x5192 冒 (<CJK Ideograph>) 12652 0x5E3D 帽 (<CJK Ideograph>) 12653 0x8C8C 貌 (<CJK Ideograph>) 12654 0x8D38 贸 (<CJK Ideograph>) 12655 0x4E48 么 (<CJK Ideograph>) 12656 0x73AB 玫 (<CJK Ideograph>) 12657 0x679A 枚 (<CJK Ideograph>) 12658 0x6885 梅 (<CJK Ideograph>) 12659 0x9176 酶 (<CJK Ideograph>) 12660 0x9709 霉 (<CJK Ideograph>) 12661 0x7164 煤 (<CJK Ideograph>) 12662 0x6CA1 没 (<CJK Ideograph>) 12663 0x7709 眉 (<CJK Ideograph>) 12664 0x5A92 媒 (<CJK Ideograph>) 12665 0x9541 镁 (<CJK Ideograph>) 12666 0x6BCF 每 (<CJK Ideograph>) 12667 0x7F8E 美 (<CJK Ideograph>) 12668 0x6627 昧 (<CJK Ideograph>) 12669 0x5BD0 寐 (<CJK Ideograph>) 12670 0x59B9 妹 (<CJK Ideograph>) 12671 0x5A9A 媚 (<CJK Ideograph>) 12672 0x95E8 门 (<CJK Ideograph>) 12673 0x95F7 闷 (<CJK Ideograph>) 12674 0x4EEC 们 (<CJK Ideograph>) 12675 0x840C 萌 (<CJK Ideograph>) 12676 0x8499 蒙 (<CJK Ideograph>) 12677 0x6AAC 檬 (<CJK Ideograph>) 12678 0x76DF 盟 (<CJK Ideograph>) 12679 0x9530 锰 (<CJK Ideograph>) 12680 0x731B 猛 (<CJK Ideograph>) 12681 0x68A6 梦 (<CJK Ideograph>) 12682 0x5B5F 孟 (<CJK Ideograph>) 12683 0x772F 眯 (<CJK Ideograph>) 12684 0x919A 醚 (<CJK Ideograph>) 12685 0x9761 靡 (<CJK Ideograph>) 12686 0x7CDC 糜 (<CJK Ideograph>) 12687 0x8FF7 迷 (<CJK Ideograph>) 12688 0x8C1C 谜 (<CJK Ideograph>) 12689 0x5F25 弥 (<CJK Ideograph>) 12690 0x7C73 米 (<CJK Ideograph>) 12691 0x79D8 秘 (<CJK Ideograph>) 12692 0x89C5 觅 (<CJK Ideograph>) 12693 0x6CCC 泌 (<CJK Ideograph>) 12694 0x871C 蜜 (<CJK Ideograph>) 12695 0x5BC6 密 (<CJK Ideograph>) 12696 0x5E42 幂 (<CJK Ideograph>) 12697 0x68C9 棉 (<CJK Ideograph>) 12698 0x7720 眠 (<CJK Ideograph>) 12699 0x7EF5 绵 (<CJK Ideograph>) 12700 0x5195 冕 (<CJK Ideograph>) 12701 0x514D 免 (<CJK Ideograph>) 12702 0x52C9 勉 (<CJK Ideograph>) 12703 0x5A29 娩 (<CJK Ideograph>) 12704 0x7F05 缅 (<CJK Ideograph>) 12705 0x9762 面 (<CJK Ideograph>) 12706 0x82D7 苗 (<CJK Ideograph>) 12707 0x63CF 描 (<CJK Ideograph>) 12708 0x7784 瞄 (<CJK Ideograph>) 12709 0x85D0 藐 (<CJK Ideograph>) 12710 0x79D2 秒 (<CJK Ideograph>) 12711 0x6E3A 渺 (<CJK Ideograph>) 12712 0x5E99 庙 (<CJK Ideograph>) 12713 0x5999 妙 (<CJK Ideograph>) 12714 0x8511 蔑 (<CJK Ideograph>) 12715 0x706D 灭 (<CJK Ideograph>) 12716 0x6C11 民 (<CJK Ideograph>) 12717 0x62BF 抿 (<CJK Ideograph>) 12718 0x76BF 皿 (<CJK Ideograph>) 12719 0x654F 敏 (<CJK Ideograph>) 12720 0x60AF 悯 (<CJK Ideograph>) 12721 0x95FD 闽 (<CJK Ideograph>) 12722 0x660E 明 (<CJK Ideograph>) 12723 0x879F 螟 (<CJK Ideograph>) 12724 0x9E23 鸣 (<CJK Ideograph>) 12725 0x94ED 铭 (<CJK Ideograph>) 12726 0x540D 名 (<CJK Ideograph>) 12727 0x547D 命 (<CJK Ideograph>) 12728 0x8C2C 谬 (<CJK Ideograph>) 12729 0x6478 摸 (<CJK Ideograph>) 12730 0x8140 腀 (<CJK Ideograph>) 12731 0x8141 腁 (<CJK Ideograph>) 12732 0x8142 腂 (<CJK Ideograph>) 12733 0x8143 腃 (<CJK Ideograph>) 12734 0x8144 腄 (<CJK Ideograph>) 12735 0x8145 腅 (<CJK Ideograph>) 12736 0x8147 腇 (<CJK Ideograph>) 12737 0x8149 腉 (<CJK Ideograph>) 12738 0x814D 腍 (<CJK Ideograph>) 12739 0x814E 腎 (<CJK Ideograph>) 12740 0x814F 腏 (<CJK Ideograph>) 12741 0x8152 腒 (<CJK Ideograph>) 12742 0x8156 腖 (<CJK Ideograph>) 12743 0x8157 腗 (<CJK Ideograph>) 12744 0x8158 腘 (<CJK Ideograph>) 12745 0x815B 腛 (<CJK Ideograph>) 12746 0x815C 腜 (<CJK Ideograph>) 12747 0x815D 腝 (<CJK Ideograph>) 12748 0x815E 腞 (<CJK Ideograph>) 12749 0x815F 腟 (<CJK Ideograph>) 12750 0x8161 腡 (<CJK Ideograph>) 12751 0x8162 腢 (<CJK Ideograph>) 12752 0x8163 腣 (<CJK Ideograph>) 12753 0x8164 腤 (<CJK Ideograph>) 12754 0x8166 腦 (<CJK Ideograph>) 12755 0x8168 腨 (<CJK Ideograph>) 12756 0x816A 腪 (<CJK Ideograph>) 12757 0x816B 腫 (<CJK Ideograph>) 12758 0x816C 腬 (<CJK Ideograph>) 12759 0x816F 腯 (<CJK Ideograph>) 12760 0x8172 腲 (<CJK Ideograph>) 12761 0x8173 腳 (<CJK Ideograph>) 12762 0x8175 腵 (<CJK Ideograph>) 12763 0x8176 腶 (<CJK Ideograph>) 12764 0x8177 腷 (<CJK Ideograph>) 12765 0x8178 腸 (<CJK Ideograph>) 12766 0x8181 膁 (<CJK Ideograph>) 12767 0x8183 膃 (<CJK Ideograph>) 12768 0x8184 膄 (<CJK Ideograph>) 12769 0x8185 膅 (<CJK Ideograph>) 12770 0x8186 膆 (<CJK Ideograph>) 12771 0x8187 膇 (<CJK Ideograph>) 12772 0x8189 膉 (<CJK Ideograph>) 12773 0x818B 膋 (<CJK Ideograph>) 12774 0x818C 膌 (<CJK Ideograph>) 12775 0x818D 膍 (<CJK Ideograph>) 12776 0x818E 膎 (<CJK Ideograph>) 12777 0x8190 膐 (<CJK Ideograph>) 12778 0x8192 膒 (<CJK Ideograph>) 12779 0x8193 膓 (<CJK Ideograph>) 12780 0x8194 膔 (<CJK Ideograph>) 12781 0x8195 膕 (<CJK Ideograph>) 12782 0x8196 膖 (<CJK Ideograph>) 12783 0x8197 膗 (<CJK Ideograph>) 12784 0x8199 膙 (<CJK Ideograph>) 12785 0x819A 膚 (<CJK Ideograph>) 12786 0x819E 膞 (<CJK Ideograph>) 12787 0x819F 膟 (<CJK Ideograph>) 12788 0x81A0 膠 (<CJK Ideograph>) 12789 0x81A1 膡 (<CJK Ideograph>) 12790 0x81A2 膢 (<CJK Ideograph>) 12791 0x81A4 膤 (<CJK Ideograph>) 12792 0x81A5 膥 (<CJK Ideograph>) 12793 0x81A7 膧 (<CJK Ideograph>) 12794 0x81A9 膩 (<CJK Ideograph>) 12795 0x81AB 膫 (<CJK Ideograph>) 12796 0x81AC 膬 (<CJK Ideograph>) 12797 0x81AD 膭 (<CJK Ideograph>) 12798 0x81AE 膮 (<CJK Ideograph>) 12799 0x81AF 膯 (<CJK Ideograph>) 12800 0x81B0 膰 (<CJK Ideograph>) 12801 0x81B1 膱 (<CJK Ideograph>) 12802 0x81B2 膲 (<CJK Ideograph>) 12803 0x81B4 膴 (<CJK Ideograph>) 12804 0x81B5 膵 (<CJK Ideograph>) 12805 0x81B6 膶 (<CJK Ideograph>) 12806 0x81B7 膷 (<CJK Ideograph>) 12807 0x81B8 膸 (<CJK Ideograph>) 12808 0x81B9 膹 (<CJK Ideograph>) 12809 0x81BC 膼 (<CJK Ideograph>) 12810 0x81BD 膽 (<CJK Ideograph>) 12811 0x81BE 膾 (<CJK Ideograph>) 12812 0x81BF 膿 (<CJK Ideograph>) 12813 0x81C4 臄 (<CJK Ideograph>) 12814 0x81C5 臅 (<CJK Ideograph>) 12815 0x81C7 臇 (<CJK Ideograph>) 12816 0x81C8 臈 (<CJK Ideograph>) 12817 0x81C9 臉 (<CJK Ideograph>) 12818 0x81CB 臋 (<CJK Ideograph>) 12819 0x81CD 臍 (<CJK Ideograph>) 12820 0x81CE 臎 (<CJK Ideograph>) 12821 0x81CF 臏 (<CJK Ideograph>) 12822 0x81D0 臐 (<CJK Ideograph>) 12823 0x81D1 臑 (<CJK Ideograph>) 12824 0x81D2 臒 (<CJK Ideograph>) 12825 0x81D3 臓 (<CJK Ideograph>) 12826 0x6479 摹 (<CJK Ideograph>) 12827 0x8611 蘑 (<CJK Ideograph>) 12828 0x6A21 模 (<CJK Ideograph>) 12829 0x819C 膜 (<CJK Ideograph>) 12830 0x78E8 磨 (<CJK Ideograph>) 12831 0x6469 摩 (<CJK Ideograph>) 12832 0x9B54 魔 (<CJK Ideograph>) 12833 0x62B9 抹 (<CJK Ideograph>) 12834 0x672B 末 (<CJK Ideograph>) 12835 0x83AB 莫 (<CJK Ideograph>) 12836 0x58A8 墨 (<CJK Ideograph>) 12837 0x9ED8 默 (<CJK Ideograph>) 12838 0x6CAB 沫 (<CJK Ideograph>) 12839 0x6F20 漠 (<CJK Ideograph>) 12840 0x5BDE 寞 (<CJK Ideograph>) 12841 0x964C 陌 (<CJK Ideograph>) 12842 0x8C0B 谋 (<CJK Ideograph>) 12843 0x725F 牟 (<CJK Ideograph>) 12844 0x67D0 某 (<CJK Ideograph>) 12845 0x62C7 拇 (<CJK Ideograph>) 12846 0x7261 牡 (<CJK Ideograph>) 12847 0x4EA9 亩 (<CJK Ideograph>) 12848 0x59C6 姆 (<CJK Ideograph>) 12849 0x6BCD 母 (<CJK Ideograph>) 12850 0x5893 墓 (<CJK Ideograph>) 12851 0x66AE 暮 (<CJK Ideograph>) 12852 0x5E55 幕 (<CJK Ideograph>) 12853 0x52DF 募 (<CJK Ideograph>) 12854 0x6155 慕 (<CJK Ideograph>) 12855 0x6728 木 (<CJK Ideograph>) 12856 0x76EE 目 (<CJK Ideograph>) 12857 0x7766 睦 (<CJK Ideograph>) 12858 0x7267 牧 (<CJK Ideograph>) 12859 0x7A46 穆 (<CJK Ideograph>) 12860 0x62FF 拿 (<CJK Ideograph>) 12861 0x54EA 哪 (<CJK Ideograph>) 12862 0x5450 呐 (<CJK Ideograph>) 12863 0x94A0 钠 (<CJK Ideograph>) 12864 0x90A3 那 (<CJK Ideograph>) 12865 0x5A1C 娜 (<CJK Ideograph>) 12866 0x7EB3 纳 (<CJK Ideograph>) 12867 0x6C16 氖 (<CJK Ideograph>) 12868 0x4E43 乃 (<CJK Ideograph>) 12869 0x5976 奶 (<CJK Ideograph>) 12870 0x8010 耐 (<CJK Ideograph>) 12871 0x5948 奈 (<CJK Ideograph>) 12872 0x5357 南 (<CJK Ideograph>) 12873 0x7537 男 (<CJK Ideograph>) 12874 0x96BE 难 (<CJK Ideograph>) 12875 0x56CA 囊 (<CJK Ideograph>) 12876 0x6320 挠 (<CJK Ideograph>) 12877 0x8111 脑 (<CJK Ideograph>) 12878 0x607C 恼 (<CJK Ideograph>) 12879 0x95F9 闹 (<CJK Ideograph>) 12880 0x6DD6 淖 (<CJK Ideograph>) 12881 0x5462 呢 (<CJK Ideograph>) 12882 0x9981 馁 (<CJK Ideograph>) 12883 0x5185 内 (<CJK Ideograph>) 12884 0x5AE9 嫩 (<CJK Ideograph>) 12885 0x80FD 能 (<CJK Ideograph>) 12886 0x59AE 妮 (<CJK Ideograph>) 12887 0x9713 霓 (<CJK Ideograph>) 12888 0x502A 倪 (<CJK Ideograph>) 12889 0x6CE5 泥 (<CJK Ideograph>) 12890 0x5C3C 尼 (<CJK Ideograph>) 12891 0x62DF 拟 (<CJK Ideograph>) 12892 0x4F60 你 (<CJK Ideograph>) 12893 0x533F 匿 (<CJK Ideograph>) 12894 0x817B 腻 (<CJK Ideograph>) 12895 0x9006 逆 (<CJK Ideograph>) 12896 0x6EBA 溺 (<CJK Ideograph>) 12897 0x852B 蔫 (<CJK Ideograph>) 12898 0x62C8 拈 (<CJK Ideograph>) 12899 0x5E74 年 (<CJK Ideograph>) 12900 0x78BE 碾 (<CJK Ideograph>) 12901 0x64B5 撵 (<CJK Ideograph>) 12902 0x637B 捻 (<CJK Ideograph>) 12903 0x5FF5 念 (<CJK Ideograph>) 12904 0x5A18 娘 (<CJK Ideograph>) 12905 0x917F 酿 (<CJK Ideograph>) 12906 0x9E1F 鸟 (<CJK Ideograph>) 12907 0x5C3F 尿 (<CJK Ideograph>) 12908 0x634F 捏 (<CJK Ideograph>) 12909 0x8042 聂 (<CJK Ideograph>) 12910 0x5B7D 孽 (<CJK Ideograph>) 12911 0x556E 啮 (<CJK Ideograph>) 12912 0x954A 镊 (<CJK Ideograph>) 12913 0x954D 镍 (<CJK Ideograph>) 12914 0x6D85 涅 (<CJK Ideograph>) 12915 0x60A8 您 (<CJK Ideograph>) 12916 0x67E0 柠 (<CJK Ideograph>) 12917 0x72DE 狞 (<CJK Ideograph>) 12918 0x51DD 凝 (<CJK Ideograph>) 12919 0x5B81 宁 (<CJK Ideograph>) 12920 0x81D4 臔 (<CJK Ideograph>) 12921 0x81D5 臕 (<CJK Ideograph>) 12922 0x81D6 臖 (<CJK Ideograph>) 12923 0x81D7 臗 (<CJK Ideograph>) 12924 0x81D8 臘 (<CJK Ideograph>) 12925 0x81D9 臙 (<CJK Ideograph>) 12926 0x81DA 臚 (<CJK Ideograph>) 12927 0x81DB 臛 (<CJK Ideograph>) 12928 0x81DC 臜 (<CJK Ideograph>) 12929 0x81DD 臝 (<CJK Ideograph>) 12930 0x81DE 臞 (<CJK Ideograph>) 12931 0x81DF 臟 (<CJK Ideograph>) 12932 0x81E0 臠 (<CJK Ideograph>) 12933 0x81E1 臡 (<CJK Ideograph>) 12934 0x81E2 臢 (<CJK Ideograph>) 12935 0x81E4 臤 (<CJK Ideograph>) 12936 0x81E5 臥 (<CJK Ideograph>) 12937 0x81E6 臦 (<CJK Ideograph>) 12938 0x81E8 臨 (<CJK Ideograph>) 12939 0x81E9 臩 (<CJK Ideograph>) 12940 0x81EB 臫 (<CJK Ideograph>) 12941 0x81EE 臮 (<CJK Ideograph>) 12942 0x81EF 臯 (<CJK Ideograph>) 12943 0x81F0 臰 (<CJK Ideograph>) 12944 0x81F1 臱 (<CJK Ideograph>) 12945 0x81F2 臲 (<CJK Ideograph>) 12946 0x81F5 臵 (<CJK Ideograph>) 12947 0x81F6 臶 (<CJK Ideograph>) 12948 0x81F7 臷 (<CJK Ideograph>) 12949 0x81F8 臸 (<CJK Ideograph>) 12950 0x81F9 臹 (<CJK Ideograph>) 12951 0x81FA 臺 (<CJK Ideograph>) 12952 0x81FD 臽 (<CJK Ideograph>) 12953 0x81FF 臿 (<CJK Ideograph>) 12954 0x8203 舃 (<CJK Ideograph>) 12955 0x8207 與 (<CJK Ideograph>) 12956 0x8208 興 (<CJK Ideograph>) 12957 0x8209 舉 (<CJK Ideograph>) 12958 0x820A 舊 (<CJK Ideograph>) 12959 0x820B 舋 (<CJK Ideograph>) 12960 0x820E 舎 (<CJK Ideograph>) 12961 0x820F 舏 (<CJK Ideograph>) 12962 0x8211 舑 (<CJK Ideograph>) 12963 0x8213 舓 (<CJK Ideograph>) 12964 0x8215 舕 (<CJK Ideograph>) 12965 0x8216 舖 (<CJK Ideograph>) 12966 0x8217 舗 (<CJK Ideograph>) 12967 0x8218 舘 (<CJK Ideograph>) 12968 0x8219 舙 (<CJK Ideograph>) 12969 0x821A 舚 (<CJK Ideograph>) 12970 0x821D 舝 (<CJK Ideograph>) 12971 0x8220 舠 (<CJK Ideograph>) 12972 0x8224 舤 (<CJK Ideograph>) 12973 0x8225 舥 (<CJK Ideograph>) 12974 0x8226 舦 (<CJK Ideograph>) 12975 0x8227 舧 (<CJK Ideograph>) 12976 0x8229 舩 (<CJK Ideograph>) 12977 0x822E 舮 (<CJK Ideograph>) 12978 0x8232 舲 (<CJK Ideograph>) 12979 0x823A 舺 (<CJK Ideograph>) 12980 0x823C 舼 (<CJK Ideograph>) 12981 0x823D 舽 (<CJK Ideograph>) 12982 0x823F 舿 (<CJK Ideograph>) 12983 0x8240 艀 (<CJK Ideograph>) 12984 0x8241 艁 (<CJK Ideograph>) 12985 0x8242 艂 (<CJK Ideograph>) 12986 0x8243 艃 (<CJK Ideograph>) 12987 0x8245 艅 (<CJK Ideograph>) 12988 0x8246 艆 (<CJK Ideograph>) 12989 0x8248 艈 (<CJK Ideograph>) 12990 0x824A 艊 (<CJK Ideograph>) 12991 0x824C 艌 (<CJK Ideograph>) 12992 0x824D 艍 (<CJK Ideograph>) 12993 0x824E 艎 (<CJK Ideograph>) 12994 0x8250 艐 (<CJK Ideograph>) 12995 0x8251 艑 (<CJK Ideograph>) 12996 0x8252 艒 (<CJK Ideograph>) 12997 0x8253 艓 (<CJK Ideograph>) 12998 0x8254 艔 (<CJK Ideograph>) 12999 0x8255 艕 (<CJK Ideograph>) 13000 0x8256 艖 (<CJK Ideograph>) 13001 0x8257 艗 (<CJK Ideograph>) 13002 0x8259 艙 (<CJK Ideograph>) 13003 0x825B 艛 (<CJK Ideograph>) 13004 0x825C 艜 (<CJK Ideograph>) 13005 0x825D 艝 (<CJK Ideograph>) 13006 0x825E 艞 (<CJK Ideograph>) 13007 0x8260 艠 (<CJK Ideograph>) 13008 0x8261 艡 (<CJK Ideograph>) 13009 0x8262 艢 (<CJK Ideograph>) 13010 0x8263 艣 (<CJK Ideograph>) 13011 0x8264 艤 (<CJK Ideograph>) 13012 0x8265 艥 (<CJK Ideograph>) 13013 0x8266 艦 (<CJK Ideograph>) 13014 0x8267 艧 (<CJK Ideograph>) 13015 0x8269 艩 (<CJK Ideograph>) 13016 0x62E7 拧 (<CJK Ideograph>) 13017 0x6CDE 泞 (<CJK Ideograph>) 13018 0x725B 牛 (<CJK Ideograph>) 13019 0x626D 扭 (<CJK Ideograph>) 13020 0x94AE 钮 (<CJK Ideograph>) 13021 0x7EBD 纽 (<CJK Ideograph>) 13022 0x8113 脓 (<CJK Ideograph>) 13023 0x6D53 浓 (<CJK Ideograph>) 13024 0x519C 农 (<CJK Ideograph>) 13025 0x5F04 弄 (<CJK Ideograph>) 13026 0x5974 奴 (<CJK Ideograph>) 13027 0x52AA 努 (<CJK Ideograph>) 13028 0x6012 怒 (<CJK Ideograph>) 13029 0x5973 女 (<CJK Ideograph>) 13030 0x6696 暖 (<CJK Ideograph>) 13031 0x8650 虐 (<CJK Ideograph>) 13032 0x759F 疟 (<CJK Ideograph>) 13033 0x632A 挪 (<CJK Ideograph>) 13034 0x61E6 懦 (<CJK Ideograph>) 13035 0x7CEF 糯 (<CJK Ideograph>) 13036 0x8BFA 诺 (<CJK Ideograph>) 13037 0x54E6 哦 (<CJK Ideograph>) 13038 0x6B27 欧 (<CJK Ideograph>) 13039 0x9E25 鸥 (<CJK Ideograph>) 13040 0x6BB4 殴 (<CJK Ideograph>) 13041 0x85D5 藕 (<CJK Ideograph>) 13042 0x5455 呕 (<CJK Ideograph>) 13043 0x5076 偶 (<CJK Ideograph>) 13044 0x6CA4 沤 (<CJK Ideograph>) 13045 0x556A 啪 (<CJK Ideograph>) 13046 0x8DB4 趴 (<CJK Ideograph>) 13047 0x722C 爬 (<CJK Ideograph>) 13048 0x5E15 帕 (<CJK Ideograph>) 13049 0x6015 怕 (<CJK Ideograph>) 13050 0x7436 琶 (<CJK Ideograph>) 13051 0x62CD 拍 (<CJK Ideograph>) 13052 0x6392 排 (<CJK Ideograph>) 13053 0x724C 牌 (<CJK Ideograph>) 13054 0x5F98 徘 (<CJK Ideograph>) 13055 0x6E43 湃 (<CJK Ideograph>) 13056 0x6D3E 派 (<CJK Ideograph>) 13057 0x6500 攀 (<CJK Ideograph>) 13058 0x6F58 潘 (<CJK Ideograph>) 13059 0x76D8 盘 (<CJK Ideograph>) 13060 0x78D0 磐 (<CJK Ideograph>) 13061 0x76FC 盼 (<CJK Ideograph>) 13062 0x7554 畔 (<CJK Ideograph>) 13063 0x5224 判 (<CJK Ideograph>) 13064 0x53DB 叛 (<CJK Ideograph>) 13065 0x4E53 乓 (<CJK Ideograph>) 13066 0x5E9E 庞 (<CJK Ideograph>) 13067 0x65C1 旁 (<CJK Ideograph>) 13068 0x802A 耪 (<CJK Ideograph>) 13069 0x80D6 胖 (<CJK Ideograph>) 13070 0x629B 抛 (<CJK Ideograph>) 13071 0x5486 咆 (<CJK Ideograph>) 13072 0x5228 刨 (<CJK Ideograph>) 13073 0x70AE 炮 (<CJK Ideograph>) 13074 0x888D 袍 (<CJK Ideograph>) 13075 0x8DD1 跑 (<CJK Ideograph>) 13076 0x6CE1 泡 (<CJK Ideograph>) 13077 0x5478 呸 (<CJK Ideograph>) 13078 0x80DA 胚 (<CJK Ideograph>) 13079 0x57F9 培 (<CJK Ideograph>) 13080 0x88F4 裴 (<CJK Ideograph>) 13081 0x8D54 赔 (<CJK Ideograph>) 13082 0x966A 陪 (<CJK Ideograph>) 13083 0x914D 配 (<CJK Ideograph>) 13084 0x4F69 佩 (<CJK Ideograph>) 13085 0x6C9B 沛 (<CJK Ideograph>) 13086 0x55B7 喷 (<CJK Ideograph>) 13087 0x76C6 盆 (<CJK Ideograph>) 13088 0x7830 砰 (<CJK Ideograph>) 13089 0x62A8 抨 (<CJK Ideograph>) 13090 0x70F9 烹 (<CJK Ideograph>) 13091 0x6F8E 澎 (<CJK Ideograph>) 13092 0x5F6D 彭 (<CJK Ideograph>) 13093 0x84EC 蓬 (<CJK Ideograph>) 13094 0x68DA 棚 (<CJK Ideograph>) 13095 0x787C 硼 (<CJK Ideograph>) 13096 0x7BF7 篷 (<CJK Ideograph>) 13097 0x81A8 膨 (<CJK Ideograph>) 13098 0x670B 朋 (<CJK Ideograph>) 13099 0x9E4F 鹏 (<CJK Ideograph>) 13100 0x6367 捧 (<CJK Ideograph>) 13101 0x78B0 碰 (<CJK Ideograph>) 13102 0x576F 坯 (<CJK Ideograph>) 13103 0x7812 砒 (<CJK Ideograph>) 13104 0x9739 霹 (<CJK Ideograph>) 13105 0x6279 批 (<CJK Ideograph>) 13106 0x62AB 披 (<CJK Ideograph>) 13107 0x5288 劈 (<CJK Ideograph>) 13108 0x7435 琵 (<CJK Ideograph>) 13109 0x6BD7 毗 (<CJK Ideograph>) 13110 0x826A 艪 (<CJK Ideograph>) 13111 0x826B 艫 (<CJK Ideograph>) 13112 0x826C 艬 (<CJK Ideograph>) 13113 0x826D 艭 (<CJK Ideograph>) 13114 0x8271 艱 (<CJK Ideograph>) 13115 0x8275 艵 (<CJK Ideograph>) 13116 0x8276 艶 (<CJK Ideograph>) 13117 0x8277 艷 (<CJK Ideograph>) 13118 0x8278 艸 (<CJK Ideograph>) 13119 0x827B 艻 (<CJK Ideograph>) 13120 0x827C 艼 (<CJK Ideograph>) 13121 0x8280 芀 (<CJK Ideograph>) 13122 0x8281 芁 (<CJK Ideograph>) 13123 0x8283 芃 (<CJK Ideograph>) 13124 0x8285 芅 (<CJK Ideograph>) 13125 0x8286 芆 (<CJK Ideograph>) 13126 0x8287 芇 (<CJK Ideograph>) 13127 0x8289 芉 (<CJK Ideograph>) 13128 0x828C 芌 (<CJK Ideograph>) 13129 0x8290 芐 (<CJK Ideograph>) 13130 0x8293 芓 (<CJK Ideograph>) 13131 0x8294 芔 (<CJK Ideograph>) 13132 0x8295 芕 (<CJK Ideograph>) 13133 0x8296 芖 (<CJK Ideograph>) 13134 0x829A 芚 (<CJK Ideograph>) 13135 0x829B 芛 (<CJK Ideograph>) 13136 0x829E 芞 (<CJK Ideograph>) 13137 0x82A0 芠 (<CJK Ideograph>) 13138 0x82A2 芢 (<CJK Ideograph>) 13139 0x82A3 芣 (<CJK Ideograph>) 13140 0x82A7 芧 (<CJK Ideograph>) 13141 0x82B2 芲 (<CJK Ideograph>) 13142 0x82B5 芵 (<CJK Ideograph>) 13143 0x82B6 芶 (<CJK Ideograph>) 13144 0x82BA 芺 (<CJK Ideograph>) 13145 0x82BB 芻 (<CJK Ideograph>) 13146 0x82BC 芼 (<CJK Ideograph>) 13147 0x82BF 芿 (<CJK Ideograph>) 13148 0x82C0 苀 (<CJK Ideograph>) 13149 0x82C2 苂 (<CJK Ideograph>) 13150 0x82C3 苃 (<CJK Ideograph>) 13151 0x82C5 苅 (<CJK Ideograph>) 13152 0x82C6 苆 (<CJK Ideograph>) 13153 0x82C9 苉 (<CJK Ideograph>) 13154 0x82D0 苐 (<CJK Ideograph>) 13155 0x82D6 苖 (<CJK Ideograph>) 13156 0x82D9 苙 (<CJK Ideograph>) 13157 0x82DA 苚 (<CJK Ideograph>) 13158 0x82DD 苝 (<CJK Ideograph>) 13159 0x82E2 苢 (<CJK Ideograph>) 13160 0x82E7 苧 (<CJK Ideograph>) 13161 0x82E8 苨 (<CJK Ideograph>) 13162 0x82E9 苩 (<CJK Ideograph>) 13163 0x82EA 苪 (<CJK Ideograph>) 13164 0x82EC 苬 (<CJK Ideograph>) 13165 0x82ED 苭 (<CJK Ideograph>) 13166 0x82EE 苮 (<CJK Ideograph>) 13167 0x82F0 苰 (<CJK Ideograph>) 13168 0x82F2 苲 (<CJK Ideograph>) 13169 0x82F3 苳 (<CJK Ideograph>) 13170 0x82F5 苵 (<CJK Ideograph>) 13171 0x82F6 苶 (<CJK Ideograph>) 13172 0x82F8 苸 (<CJK Ideograph>) 13173 0x82FA 苺 (<CJK Ideograph>) 13174 0x82FC 苼 (<CJK Ideograph>) 13175 0x82FD 苽 (<CJK Ideograph>) 13176 0x82FE 苾 (<CJK Ideograph>) 13177 0x82FF 苿 (<CJK Ideograph>) 13178 0x8300 茀 (<CJK Ideograph>) 13179 0x830A 茊 (<CJK Ideograph>) 13180 0x830B 茋 (<CJK Ideograph>) 13181 0x830D 茍 (<CJK Ideograph>) 13182 0x8310 茐 (<CJK Ideograph>) 13183 0x8312 茒 (<CJK Ideograph>) 13184 0x8313 茓 (<CJK Ideograph>) 13185 0x8316 茖 (<CJK Ideograph>) 13186 0x8318 茘 (<CJK Ideograph>) 13187 0x8319 茙 (<CJK Ideograph>) 13188 0x831D 茝 (<CJK Ideograph>) 13189 0x831E 茞 (<CJK Ideograph>) 13190 0x831F 茟 (<CJK Ideograph>) 13191 0x8320 茠 (<CJK Ideograph>) 13192 0x8321 茡 (<CJK Ideograph>) 13193 0x8322 茢 (<CJK Ideograph>) 13194 0x8323 茣 (<CJK Ideograph>) 13195 0x8324 茤 (<CJK Ideograph>) 13196 0x8325 茥 (<CJK Ideograph>) 13197 0x8326 茦 (<CJK Ideograph>) 13198 0x8329 茩 (<CJK Ideograph>) 13199 0x832A 茪 (<CJK Ideograph>) 13200 0x832E 茮 (<CJK Ideograph>) 13201 0x8330 茰 (<CJK Ideograph>) 13202 0x8332 茲 (<CJK Ideograph>) 13203 0x8337 茷 (<CJK Ideograph>) 13204 0x833B 茻 (<CJK Ideograph>) 13205 0x833D 茽 (<CJK Ideograph>) 13206 0x5564 啤 (<CJK Ideograph>) 13207 0x813E 脾 (<CJK Ideograph>) 13208 0x75B2 疲 (<CJK Ideograph>) 13209 0x76AE 皮 (<CJK Ideograph>) 13210 0x5339 匹 (<CJK Ideograph>) 13211 0x75DE 痞 (<CJK Ideograph>) 13212 0x50FB 僻 (<CJK Ideograph>) 13213 0x5C41 屁 (<CJK Ideograph>) 13214 0x8B6C 譬 (<CJK Ideograph>) 13215 0x7BC7 篇 (<CJK Ideograph>) 13216 0x504F 偏 (<CJK Ideograph>) 13217 0x7247 片 (<CJK Ideograph>) 13218 0x9A97 骗 (<CJK Ideograph>) 13219 0x98D8 飘 (<CJK Ideograph>) 13220 0x6F02 漂 (<CJK Ideograph>) 13221 0x74E2 瓢 (<CJK Ideograph>) 13222 0x7968 票 (<CJK Ideograph>) 13223 0x6487 撇 (<CJK Ideograph>) 13224 0x77A5 瞥 (<CJK Ideograph>) 13225 0x62FC 拼 (<CJK Ideograph>) 13226 0x9891 频 (<CJK Ideograph>) 13227 0x8D2B 贫 (<CJK Ideograph>) 13228 0x54C1 品 (<CJK Ideograph>) 13229 0x8058 聘 (<CJK Ideograph>) 13230 0x4E52 乒 (<CJK Ideograph>) 13231 0x576A 坪 (<CJK Ideograph>) 13232 0x82F9 苹 (<CJK Ideograph>) 13233 0x840D 萍 (<CJK Ideograph>) 13234 0x5E73 平 (<CJK Ideograph>) 13235 0x51ED 凭 (<CJK Ideograph>) 13236 0x74F6 瓶 (<CJK Ideograph>) 13237 0x8BC4 评 (<CJK Ideograph>) 13238 0x5C4F 屏 (<CJK Ideograph>) 13239 0x5761 坡 (<CJK Ideograph>) 13240 0x6CFC 泼 (<CJK Ideograph>) 13241 0x9887 颇 (<CJK Ideograph>) 13242 0x5A46 婆 (<CJK Ideograph>) 13243 0x7834 破 (<CJK Ideograph>) 13244 0x9B44 魄 (<CJK Ideograph>) 13245 0x8FEB 迫 (<CJK Ideograph>) 13246 0x7C95 粕 (<CJK Ideograph>) 13247 0x5256 剖 (<CJK Ideograph>) 13248 0x6251 扑 (<CJK Ideograph>) 13249 0x94FA 铺 (<CJK Ideograph>) 13250 0x4EC6 仆 (<CJK Ideograph>) 13251 0x8386 莆 (<CJK Ideograph>) 13252 0x8461 葡 (<CJK Ideograph>) 13253 0x83E9 菩 (<CJK Ideograph>) 13254 0x84B2 蒲 (<CJK Ideograph>) 13255 0x57D4 埔 (<CJK Ideograph>) 13256 0x6734 朴 (<CJK Ideograph>) 13257 0x5703 圃 (<CJK Ideograph>) 13258 0x666E 普 (<CJK Ideograph>) 13259 0x6D66 浦 (<CJK Ideograph>) 13260 0x8C31 谱 (<CJK Ideograph>) 13261 0x66DD 曝 (<CJK Ideograph>) 13262 0x7011 瀑 (<CJK Ideograph>) 13263 0x671F 期 (<CJK Ideograph>) 13264 0x6B3A 欺 (<CJK Ideograph>) 13265 0x6816 栖 (<CJK Ideograph>) 13266 0x621A 戚 (<CJK Ideograph>) 13267 0x59BB 妻 (<CJK Ideograph>) 13268 0x4E03 七 (<CJK Ideograph>) 13269 0x51C4 凄 (<CJK Ideograph>) 13270 0x6F06 漆 (<CJK Ideograph>) 13271 0x67D2 柒 (<CJK Ideograph>) 13272 0x6C8F 沏 (<CJK Ideograph>) 13273 0x5176 其 (<CJK Ideograph>) 13274 0x68CB 棋 (<CJK Ideograph>) 13275 0x5947 奇 (<CJK Ideograph>) 13276 0x6B67 歧 (<CJK Ideograph>) 13277 0x7566 畦 (<CJK Ideograph>) 13278 0x5D0E 崎 (<CJK Ideograph>) 13279 0x8110 脐 (<CJK Ideograph>) 13280 0x9F50 齐 (<CJK Ideograph>) 13281 0x65D7 旗 (<CJK Ideograph>) 13282 0x7948 祈 (<CJK Ideograph>) 13283 0x7941 祁 (<CJK Ideograph>) 13284 0x9A91 骑 (<CJK Ideograph>) 13285 0x8D77 起 (<CJK Ideograph>) 13286 0x5C82 岂 (<CJK Ideograph>) 13287 0x4E5E 乞 (<CJK Ideograph>) 13288 0x4F01 企 (<CJK Ideograph>) 13289 0x542F 启 (<CJK Ideograph>) 13290 0x5951 契 (<CJK Ideograph>) 13291 0x780C 砌 (<CJK Ideograph>) 13292 0x5668 器 (<CJK Ideograph>) 13293 0x6C14 气 (<CJK Ideograph>) 13294 0x8FC4 迄 (<CJK Ideograph>) 13295 0x5F03 弃 (<CJK Ideograph>) 13296 0x6C7D 汽 (<CJK Ideograph>) 13297 0x6CE3 泣 (<CJK Ideograph>) 13298 0x8BAB 讫 (<CJK Ideograph>) 13299 0x6390 掐 (<CJK Ideograph>) 13300 0x833E 茾 (<CJK Ideograph>) 13301 0x833F 茿 (<CJK Ideograph>) 13302 0x8341 荁 (<CJK Ideograph>) 13303 0x8342 荂 (<CJK Ideograph>) 13304 0x8344 荄 (<CJK Ideograph>) 13305 0x8345 荅 (<CJK Ideograph>) 13306 0x8348 荈 (<CJK Ideograph>) 13307 0x834A 荊 (<CJK Ideograph>) 13308 0x834B 荋 (<CJK Ideograph>) 13309 0x834C 荌 (<CJK Ideograph>) 13310 0x834D 荍 (<CJK Ideograph>) 13311 0x834E 荎 (<CJK Ideograph>) 13312 0x8353 荓 (<CJK Ideograph>) 13313 0x8355 荕 (<CJK Ideograph>) 13314 0x8356 荖 (<CJK Ideograph>) 13315 0x8357 荗 (<CJK Ideograph>) 13316 0x8358 荘 (<CJK Ideograph>) 13317 0x8359 荙 (<CJK Ideograph>) 13318 0x835D 荝 (<CJK Ideograph>) 13319 0x8362 荢 (<CJK Ideograph>) 13320 0x8370 荰 (<CJK Ideograph>) 13321 0x8371 荱 (<CJK Ideograph>) 13322 0x8372 荲 (<CJK Ideograph>) 13323 0x8373 荳 (<CJK Ideograph>) 13324 0x8374 荴 (<CJK Ideograph>) 13325 0x8375 荵 (<CJK Ideograph>) 13326 0x8376 荶 (<CJK Ideograph>) 13327 0x8379 荹 (<CJK Ideograph>) 13328 0x837A 荺 (<CJK Ideograph>) 13329 0x837E 荾 (<CJK Ideograph>) 13330 0x837F 荿 (<CJK Ideograph>) 13331 0x8380 莀 (<CJK Ideograph>) 13332 0x8381 莁 (<CJK Ideograph>) 13333 0x8382 莂 (<CJK Ideograph>) 13334 0x8383 莃 (<CJK Ideograph>) 13335 0x8384 莄 (<CJK Ideograph>) 13336 0x8387 莇 (<CJK Ideograph>) 13337 0x8388 莈 (<CJK Ideograph>) 13338 0x838A 莊 (<CJK Ideograph>) 13339 0x838B 莋 (<CJK Ideograph>) 13340 0x838C 莌 (<CJK Ideograph>) 13341 0x838D 莍 (<CJK Ideograph>) 13342 0x838F 莏 (<CJK Ideograph>) 13343 0x8390 莐 (<CJK Ideograph>) 13344 0x8391 莑 (<CJK Ideograph>) 13345 0x8394 莔 (<CJK Ideograph>) 13346 0x8395 莕 (<CJK Ideograph>) 13347 0x8396 莖 (<CJK Ideograph>) 13348 0x8397 莗 (<CJK Ideograph>) 13349 0x8399 莙 (<CJK Ideograph>) 13350 0x839A 莚 (<CJK Ideograph>) 13351 0x839D 莝 (<CJK Ideograph>) 13352 0x839F 莟 (<CJK Ideograph>) 13353 0x83A1 莡 (<CJK Ideograph>) 13354 0x83A2 莢 (<CJK Ideograph>) 13355 0x83A3 莣 (<CJK Ideograph>) 13356 0x83A4 莤 (<CJK Ideograph>) 13357 0x83A5 莥 (<CJK Ideograph>) 13358 0x83A6 莦 (<CJK Ideograph>) 13359 0x83A7 莧 (<CJK Ideograph>) 13360 0x83AC 莬 (<CJK Ideograph>) 13361 0x83AD 莭 (<CJK Ideograph>) 13362 0x83AE 莮 (<CJK Ideograph>) 13363 0x83AF 莯 (<CJK Ideograph>) 13364 0x83B5 莵 (<CJK Ideograph>) 13365 0x83BB 莻 (<CJK Ideograph>) 13366 0x83BE 莾 (<CJK Ideograph>) 13367 0x83BF 莿 (<CJK Ideograph>) 13368 0x83C2 菂 (<CJK Ideograph>) 13369 0x83C3 菃 (<CJK Ideograph>) 13370 0x83C4 菄 (<CJK Ideograph>) 13371 0x83C6 菆 (<CJK Ideograph>) 13372 0x83C8 菈 (<CJK Ideograph>) 13373 0x83C9 菉 (<CJK Ideograph>) 13374 0x83CB 菋 (<CJK Ideograph>) 13375 0x83CD 菍 (<CJK Ideograph>) 13376 0x83CE 菎 (<CJK Ideograph>) 13377 0x83D0 菐 (<CJK Ideograph>) 13378 0x83D1 菑 (<CJK Ideograph>) 13379 0x83D2 菒 (<CJK Ideograph>) 13380 0x83D3 菓 (<CJK Ideograph>) 13381 0x83D5 菕 (<CJK Ideograph>) 13382 0x83D7 菗 (<CJK Ideograph>) 13383 0x83D9 菙 (<CJK Ideograph>) 13384 0x83DA 菚 (<CJK Ideograph>) 13385 0x83DB 菛 (<CJK Ideograph>) 13386 0x83DE 菞 (<CJK Ideograph>) 13387 0x83E2 菢 (<CJK Ideograph>) 13388 0x83E3 菣 (<CJK Ideograph>) 13389 0x83E4 菤 (<CJK Ideograph>) 13390 0x83E6 菦 (<CJK Ideograph>) 13391 0x83E7 菧 (<CJK Ideograph>) 13392 0x83E8 菨 (<CJK Ideograph>) 13393 0x83EB 菫 (<CJK Ideograph>) 13394 0x83EC 菬 (<CJK Ideograph>) 13395 0x83ED 菭 (<CJK Ideograph>) 13396 0x6070 恰 (<CJK Ideograph>) 13397 0x6D3D 洽 (<CJK Ideograph>) 13398 0x7275 牵 (<CJK Ideograph>) 13399 0x6266 扦 (<CJK Ideograph>) 13400 0x948E 钎 (<CJK Ideograph>) 13401 0x94C5 铅 (<CJK Ideograph>) 13402 0x5343 千 (<CJK Ideograph>) 13403 0x8FC1 迁 (<CJK Ideograph>) 13404 0x7B7E 签 (<CJK Ideograph>) 13405 0x4EDF 仟 (<CJK Ideograph>) 13406 0x8C26 谦 (<CJK Ideograph>) 13407 0x4E7E 乾 (<CJK Ideograph>) 13408 0x9ED4 黔 (<CJK Ideograph>) 13409 0x94B1 钱 (<CJK Ideograph>) 13410 0x94B3 钳 (<CJK Ideograph>) 13411 0x524D 前 (<CJK Ideograph>) 13412 0x6F5C 潜 (<CJK Ideograph>) 13413 0x9063 遣 (<CJK Ideograph>) 13414 0x6D45 浅 (<CJK Ideograph>) 13415 0x8C34 谴 (<CJK Ideograph>) 13416 0x5811 堑 (<CJK Ideograph>) 13417 0x5D4C 嵌 (<CJK Ideograph>) 13418 0x6B20 欠 (<CJK Ideograph>) 13419 0x6B49 歉 (<CJK Ideograph>) 13420 0x67AA 枪 (<CJK Ideograph>) 13421 0x545B 呛 (<CJK Ideograph>) 13422 0x8154 腔 (<CJK Ideograph>) 13423 0x7F8C 羌 (<CJK Ideograph>) 13424 0x5899 墙 (<CJK Ideograph>) 13425 0x8537 蔷 (<CJK Ideograph>) 13426 0x5F3A 强 (<CJK Ideograph>) 13427 0x62A2 抢 (<CJK Ideograph>) 13428 0x6A47 橇 (<CJK Ideograph>) 13429 0x9539 锹 (<CJK Ideograph>) 13430 0x6572 敲 (<CJK Ideograph>) 13431 0x6084 悄 (<CJK Ideograph>) 13432 0x6865 桥 (<CJK Ideograph>) 13433 0x77A7 瞧 (<CJK Ideograph>) 13434 0x4E54 乔 (<CJK Ideograph>) 13435 0x4FA8 侨 (<CJK Ideograph>) 13436 0x5DE7 巧 (<CJK Ideograph>) 13437 0x9798 鞘 (<CJK Ideograph>) 13438 0x64AC 撬 (<CJK Ideograph>) 13439 0x7FD8 翘 (<CJK Ideograph>) 13440 0x5CED 峭 (<CJK Ideograph>) 13441 0x4FCF 俏 (<CJK Ideograph>) 13442 0x7A8D 窍 (<CJK Ideograph>) 13443 0x5207 切 (<CJK Ideograph>) 13444 0x8304 茄 (<CJK Ideograph>) 13445 0x4E14 且 (<CJK Ideograph>) 13446 0x602F 怯 (<CJK Ideograph>) 13447 0x7A83 窃 (<CJK Ideograph>) 13448 0x94A6 钦 (<CJK Ideograph>) 13449 0x4FB5 侵 (<CJK Ideograph>) 13450 0x4EB2 亲 (<CJK Ideograph>) 13451 0x79E6 秦 (<CJK Ideograph>) 13452 0x7434 琴 (<CJK Ideograph>) 13453 0x52E4 勤 (<CJK Ideograph>) 13454 0x82B9 芹 (<CJK Ideograph>) 13455 0x64D2 擒 (<CJK Ideograph>) 13456 0x79BD 禽 (<CJK Ideograph>) 13457 0x5BDD 寝 (<CJK Ideograph>) 13458 0x6C81 沁 (<CJK Ideograph>) 13459 0x9752 青 (<CJK Ideograph>) 13460 0x8F7B 轻 (<CJK Ideograph>) 13461 0x6C22 氢 (<CJK Ideograph>) 13462 0x503E 倾 (<CJK Ideograph>) 13463 0x537F 卿 (<CJK Ideograph>) 13464 0x6E05 清 (<CJK Ideograph>) 13465 0x64CE 擎 (<CJK Ideograph>) 13466 0x6674 晴 (<CJK Ideograph>) 13467 0x6C30 氰 (<CJK Ideograph>) 13468 0x60C5 情 (<CJK Ideograph>) 13469 0x9877 顷 (<CJK Ideograph>) 13470 0x8BF7 请 (<CJK Ideograph>) 13471 0x5E86 庆 (<CJK Ideograph>) 13472 0x743C 琼 (<CJK Ideograph>) 13473 0x7A77 穷 (<CJK Ideograph>) 13474 0x79CB 秋 (<CJK Ideograph>) 13475 0x4E18 丘 (<CJK Ideograph>) 13476 0x90B1 邱 (<CJK Ideograph>) 13477 0x7403 球 (<CJK Ideograph>) 13478 0x6C42 求 (<CJK Ideograph>) 13479 0x56DA 囚 (<CJK Ideograph>) 13480 0x914B 酋 (<CJK Ideograph>) 13481 0x6CC5 泅 (<CJK Ideograph>) 13482 0x8D8B 趋 (<CJK Ideograph>) 13483 0x533A 区 (<CJK Ideograph>) 13484 0x86C6 蛆 (<CJK Ideograph>) 13485 0x66F2 曲 (<CJK Ideograph>) 13486 0x8EAF 躯 (<CJK Ideograph>) 13487 0x5C48 屈 (<CJK Ideograph>) 13488 0x9A71 驱 (<CJK Ideograph>) 13489 0x6E20 渠 (<CJK Ideograph>) 13490 0x83EE 菮 (<CJK Ideograph>) 13491 0x83EF 華 (<CJK Ideograph>) 13492 0x83F3 菳 (<CJK Ideograph>) 13493 0x83F4 菴 (<CJK Ideograph>) 13494 0x83F5 菵 (<CJK Ideograph>) 13495 0x83F6 菶 (<CJK Ideograph>) 13496 0x83F7 菷 (<CJK Ideograph>) 13497 0x83FA 菺 (<CJK Ideograph>) 13498 0x83FB 菻 (<CJK Ideograph>) 13499 0x83FC 菼 (<CJK Ideograph>) 13500 0x83FE 菾 (<CJK Ideograph>) 13501 0x83FF 菿 (<CJK Ideograph>) 13502 0x8400 萀 (<CJK Ideograph>) 13503 0x8402 萂 (<CJK Ideograph>) 13504 0x8405 萅 (<CJK Ideograph>) 13505 0x8407 萇 (<CJK Ideograph>) 13506 0x8408 萈 (<CJK Ideograph>) 13507 0x8409 萉 (<CJK Ideograph>) 13508 0x840A 萊 (<CJK Ideograph>) 13509 0x8410 萐 (<CJK Ideograph>) 13510 0x8412 萒 (<CJK Ideograph>) 13511 0x8413 萓 (<CJK Ideograph>) 13512 0x8414 萔 (<CJK Ideograph>) 13513 0x8415 萕 (<CJK Ideograph>) 13514 0x8416 萖 (<CJK Ideograph>) 13515 0x8417 萗 (<CJK Ideograph>) 13516 0x8419 萙 (<CJK Ideograph>) 13517 0x841A 萚 (<CJK Ideograph>) 13518 0x841B 萛 (<CJK Ideograph>) 13519 0x841E 萞 (<CJK Ideograph>) 13520 0x841F 萟 (<CJK Ideograph>) 13521 0x8420 萠 (<CJK Ideograph>) 13522 0x8421 萡 (<CJK Ideograph>) 13523 0x8422 萢 (<CJK Ideograph>) 13524 0x8423 萣 (<CJK Ideograph>) 13525 0x8429 萩 (<CJK Ideograph>) 13526 0x842A 萪 (<CJK Ideograph>) 13527 0x842B 萫 (<CJK Ideograph>) 13528 0x842C 萬 (<CJK Ideograph>) 13529 0x842D 萭 (<CJK Ideograph>) 13530 0x842E 萮 (<CJK Ideograph>) 13531 0x842F 萯 (<CJK Ideograph>) 13532 0x8430 萰 (<CJK Ideograph>) 13533 0x8432 萲 (<CJK Ideograph>) 13534 0x8433 萳 (<CJK Ideograph>) 13535 0x8434 萴 (<CJK Ideograph>) 13536 0x8435 萵 (<CJK Ideograph>) 13537 0x8436 萶 (<CJK Ideograph>) 13538 0x8437 萷 (<CJK Ideograph>) 13539 0x8439 萹 (<CJK Ideograph>) 13540 0x843A 萺 (<CJK Ideograph>) 13541 0x843B 萻 (<CJK Ideograph>) 13542 0x843E 萾 (<CJK Ideograph>) 13543 0x843F 萿 (<CJK Ideograph>) 13544 0x8440 葀 (<CJK Ideograph>) 13545 0x8441 葁 (<CJK Ideograph>) 13546 0x8442 葂 (<CJK Ideograph>) 13547 0x8443 葃 (<CJK Ideograph>) 13548 0x8444 葄 (<CJK Ideograph>) 13549 0x8445 葅 (<CJK Ideograph>) 13550 0x8447 葇 (<CJK Ideograph>) 13551 0x8448 葈 (<CJK Ideograph>) 13552 0x8449 葉 (<CJK Ideograph>) 13553 0x844A 葊 (<CJK Ideograph>) 13554 0x844B 葋 (<CJK Ideograph>) 13555 0x844C 葌 (<CJK Ideograph>) 13556 0x844D 葍 (<CJK Ideograph>) 13557 0x844E 葎 (<CJK Ideograph>) 13558 0x844F 葏 (<CJK Ideograph>) 13559 0x8450 葐 (<CJK Ideograph>) 13560 0x8452 葒 (<CJK Ideograph>) 13561 0x8453 葓 (<CJK Ideograph>) 13562 0x8454 葔 (<CJK Ideograph>) 13563 0x8455 葕 (<CJK Ideograph>) 13564 0x8456 葖 (<CJK Ideograph>) 13565 0x8458 葘 (<CJK Ideograph>) 13566 0x845D 葝 (<CJK Ideograph>) 13567 0x845E 葞 (<CJK Ideograph>) 13568 0x845F 葟 (<CJK Ideograph>) 13569 0x8460 葠 (<CJK Ideograph>) 13570 0x8462 葢 (<CJK Ideograph>) 13571 0x8464 葤 (<CJK Ideograph>) 13572 0x8465 葥 (<CJK Ideograph>) 13573 0x8466 葦 (<CJK Ideograph>) 13574 0x8467 葧 (<CJK Ideograph>) 13575 0x8468 葨 (<CJK Ideograph>) 13576 0x846A 葪 (<CJK Ideograph>) 13577 0x846E 葮 (<CJK Ideograph>) 13578 0x846F 葯 (<CJK Ideograph>) 13579 0x8470 葰 (<CJK Ideograph>) 13580 0x8472 葲 (<CJK Ideograph>) 13581 0x8474 葴 (<CJK Ideograph>) 13582 0x8477 葷 (<CJK Ideograph>) 13583 0x8479 葹 (<CJK Ideograph>) 13584 0x847B 葻 (<CJK Ideograph>) 13585 0x847C 葼 (<CJK Ideograph>) 13586 0x53D6 取 (<CJK Ideograph>) 13587 0x5A36 娶 (<CJK Ideograph>) 13588 0x9F8B 龋 (<CJK Ideograph>) 13589 0x8DA3 趣 (<CJK Ideograph>) 13590 0x53BB 去 (<CJK Ideograph>) 13591 0x5708 圈 (<CJK Ideograph>) 13592 0x98A7 颧 (<CJK Ideograph>) 13593 0x6743 权 (<CJK Ideograph>) 13594 0x919B 醛 (<CJK Ideograph>) 13595 0x6CC9 泉 (<CJK Ideograph>) 13596 0x5168 全 (<CJK Ideograph>) 13597 0x75CA 痊 (<CJK Ideograph>) 13598 0x62F3 拳 (<CJK Ideograph>) 13599 0x72AC 犬 (<CJK Ideograph>) 13600 0x5238 券 (<CJK Ideograph>) 13601 0x529D 劝 (<CJK Ideograph>) 13602 0x7F3A 缺 (<CJK Ideograph>) 13603 0x7094 炔 (<CJK Ideograph>) 13604 0x7638 瘸 (<CJK Ideograph>) 13605 0x5374 却 (<CJK Ideograph>) 13606 0x9E4A 鹊 (<CJK Ideograph>) 13607 0x69B7 榷 (<CJK Ideograph>) 13608 0x786E 确 (<CJK Ideograph>) 13609 0x96C0 雀 (<CJK Ideograph>) 13610 0x88D9 裙 (<CJK Ideograph>) 13611 0x7FA4 群 (<CJK Ideograph>) 13612 0x7136 然 (<CJK Ideograph>) 13613 0x71C3 燃 (<CJK Ideograph>) 13614 0x5189 冉 (<CJK Ideograph>) 13615 0x67D3 染 (<CJK Ideograph>) 13616 0x74E4 瓤 (<CJK Ideograph>) 13617 0x58E4 壤 (<CJK Ideograph>) 13618 0x6518 攘 (<CJK Ideograph>) 13619 0x56B7 嚷 (<CJK Ideograph>) 13620 0x8BA9 让 (<CJK Ideograph>) 13621 0x9976 饶 (<CJK Ideograph>) 13622 0x6270 扰 (<CJK Ideograph>) 13623 0x7ED5 绕 (<CJK Ideograph>) 13624 0x60F9 惹 (<CJK Ideograph>) 13625 0x70ED 热 (<CJK Ideograph>) 13626 0x58EC 壬 (<CJK Ideograph>) 13627 0x4EC1 仁 (<CJK Ideograph>) 13628 0x4EBA 人 (<CJK Ideograph>) 13629 0x5FCD 忍 (<CJK Ideograph>) 13630 0x97E7 韧 (<CJK Ideograph>) 13631 0x4EFB 任 (<CJK Ideograph>) 13632 0x8BA4 认 (<CJK Ideograph>) 13633 0x5203 刃 (<CJK Ideograph>) 13634 0x598A 妊 (<CJK Ideograph>) 13635 0x7EAB 纫 (<CJK Ideograph>) 13636 0x6254 扔 (<CJK Ideograph>) 13637 0x4ECD 仍 (<CJK Ideograph>) 13638 0x65E5 日 (<CJK Ideograph>) 13639 0x620E 戎 (<CJK Ideograph>) 13640 0x8338 茸 (<CJK Ideograph>) 13641 0x84C9 蓉 (<CJK Ideograph>) 13642 0x8363 荣 (<CJK Ideograph>) 13643 0x878D 融 (<CJK Ideograph>) 13644 0x7194 熔 (<CJK Ideograph>) 13645 0x6EB6 溶 (<CJK Ideograph>) 13646 0x5BB9 容 (<CJK Ideograph>) 13647 0x7ED2 绒 (<CJK Ideograph>) 13648 0x5197 冗 (<CJK Ideograph>) 13649 0x63C9 揉 (<CJK Ideograph>) 13650 0x67D4 柔 (<CJK Ideograph>) 13651 0x8089 肉 (<CJK Ideograph>) 13652 0x8339 茹 (<CJK Ideograph>) 13653 0x8815 蠕 (<CJK Ideograph>) 13654 0x5112 儒 (<CJK Ideograph>) 13655 0x5B7A 孺 (<CJK Ideograph>) 13656 0x5982 如 (<CJK Ideograph>) 13657 0x8FB1 辱 (<CJK Ideograph>) 13658 0x4E73 乳 (<CJK Ideograph>) 13659 0x6C5D 汝 (<CJK Ideograph>) 13660 0x5165 入 (<CJK Ideograph>) 13661 0x8925 褥 (<CJK Ideograph>) 13662 0x8F6F 软 (<CJK Ideograph>) 13663 0x962E 阮 (<CJK Ideograph>) 13664 0x854A 蕊 (<CJK Ideograph>) 13665 0x745E 瑞 (<CJK Ideograph>) 13666 0x9510 锐 (<CJK Ideograph>) 13667 0x95F0 闰 (<CJK Ideograph>) 13668 0x6DA6 润 (<CJK Ideograph>) 13669 0x82E5 若 (<CJK Ideograph>) 13670 0x5F31 弱 (<CJK Ideograph>) 13671 0x6492 撒 (<CJK Ideograph>) 13672 0x6D12 洒 (<CJK Ideograph>) 13673 0x8428 萨 (<CJK Ideograph>) 13674 0x816E 腮 (<CJK Ideograph>) 13675 0x9CC3 鳃 (<CJK Ideograph>) 13676 0x585E 塞 (<CJK Ideograph>) 13677 0x8D5B 赛 (<CJK Ideograph>) 13678 0x4E09 三 (<CJK Ideograph>) 13679 0x53C1 叁 (<CJK Ideograph>) 13680 0x847D 葽 (<CJK Ideograph>) 13681 0x847E 葾 (<CJK Ideograph>) 13682 0x847F 葿 (<CJK Ideograph>) 13683 0x8480 蒀 (<CJK Ideograph>) 13684 0x8481 蒁 (<CJK Ideograph>) 13685 0x8483 蒃 (<CJK Ideograph>) 13686 0x8484 蒄 (<CJK Ideograph>) 13687 0x8485 蒅 (<CJK Ideograph>) 13688 0x8486 蒆 (<CJK Ideograph>) 13689 0x848A 蒊 (<CJK Ideograph>) 13690 0x848D 蒍 (<CJK Ideograph>) 13691 0x848F 蒏 (<CJK Ideograph>) 13692 0x8490 蒐 (<CJK Ideograph>) 13693 0x8491 蒑 (<CJK Ideograph>) 13694 0x8492 蒒 (<CJK Ideograph>) 13695 0x8493 蒓 (<CJK Ideograph>) 13696 0x8494 蒔 (<CJK Ideograph>) 13697 0x8495 蒕 (<CJK Ideograph>) 13698 0x8496 蒖 (<CJK Ideograph>) 13699 0x8498 蒘 (<CJK Ideograph>) 13700 0x849A 蒚 (<CJK Ideograph>) 13701 0x849B 蒛 (<CJK Ideograph>) 13702 0x849D 蒝 (<CJK Ideograph>) 13703 0x849E 蒞 (<CJK Ideograph>) 13704 0x849F 蒟 (<CJK Ideograph>) 13705 0x84A0 蒠 (<CJK Ideograph>) 13706 0x84A2 蒢 (<CJK Ideograph>) 13707 0x84A3 蒣 (<CJK Ideograph>) 13708 0x84A4 蒤 (<CJK Ideograph>) 13709 0x84A5 蒥 (<CJK Ideograph>) 13710 0x84A6 蒦 (<CJK Ideograph>) 13711 0x84A7 蒧 (<CJK Ideograph>) 13712 0x84A8 蒨 (<CJK Ideograph>) 13713 0x84A9 蒩 (<CJK Ideograph>) 13714 0x84AA 蒪 (<CJK Ideograph>) 13715 0x84AB 蒫 (<CJK Ideograph>) 13716 0x84AC 蒬 (<CJK Ideograph>) 13717 0x84AD 蒭 (<CJK Ideograph>) 13718 0x84AE 蒮 (<CJK Ideograph>) 13719 0x84B0 蒰 (<CJK Ideograph>) 13720 0x84B1 蒱 (<CJK Ideograph>) 13721 0x84B3 蒳 (<CJK Ideograph>) 13722 0x84B5 蒵 (<CJK Ideograph>) 13723 0x84B6 蒶 (<CJK Ideograph>) 13724 0x84B7 蒷 (<CJK Ideograph>) 13725 0x84BB 蒻 (<CJK Ideograph>) 13726 0x84BC 蒼 (<CJK Ideograph>) 13727 0x84BE 蒾 (<CJK Ideograph>) 13728 0x84C0 蓀 (<CJK Ideograph>) 13729 0x84C2 蓂 (<CJK Ideograph>) 13730 0x84C3 蓃 (<CJK Ideograph>) 13731 0x84C5 蓅 (<CJK Ideograph>) 13732 0x84C6 蓆 (<CJK Ideograph>) 13733 0x84C7 蓇 (<CJK Ideograph>) 13734 0x84C8 蓈 (<CJK Ideograph>) 13735 0x84CB 蓋 (<CJK Ideograph>) 13736 0x84CC 蓌 (<CJK Ideograph>) 13737 0x84CE 蓎 (<CJK Ideograph>) 13738 0x84CF 蓏 (<CJK Ideograph>) 13739 0x84D2 蓒 (<CJK Ideograph>) 13740 0x84D4 蓔 (<CJK Ideograph>) 13741 0x84D5 蓕 (<CJK Ideograph>) 13742 0x84D7 蓗 (<CJK Ideograph>) 13743 0x84D8 蓘 (<CJK Ideograph>) 13744 0x84D9 蓙 (<CJK Ideograph>) 13745 0x84DA 蓚 (<CJK Ideograph>) 13746 0x84DB 蓛 (<CJK Ideograph>) 13747 0x84DC 蓜 (<CJK Ideograph>) 13748 0x84DE 蓞 (<CJK Ideograph>) 13749 0x84E1 蓡 (<CJK Ideograph>) 13750 0x84E2 蓢 (<CJK Ideograph>) 13751 0x84E4 蓤 (<CJK Ideograph>) 13752 0x84E7 蓧 (<CJK Ideograph>) 13753 0x84E8 蓨 (<CJK Ideograph>) 13754 0x84E9 蓩 (<CJK Ideograph>) 13755 0x84EA 蓪 (<CJK Ideograph>) 13756 0x84EB 蓫 (<CJK Ideograph>) 13757 0x84ED 蓭 (<CJK Ideograph>) 13758 0x84EE 蓮 (<CJK Ideograph>) 13759 0x84EF 蓯 (<CJK Ideograph>) 13760 0x84F1 蓱 (<CJK Ideograph>) 13761 0x84F2 蓲 (<CJK Ideograph>) 13762 0x84F3 蓳 (<CJK Ideograph>) 13763 0x84F4 蓴 (<CJK Ideograph>) 13764 0x84F5 蓵 (<CJK Ideograph>) 13765 0x84F6 蓶 (<CJK Ideograph>) 13766 0x84F7 蓷 (<CJK Ideograph>) 13767 0x84F8 蓸 (<CJK Ideograph>) 13768 0x84F9 蓹 (<CJK Ideograph>) 13769 0x84FA 蓺 (<CJK Ideograph>) 13770 0x84FB 蓻 (<CJK Ideograph>) 13771 0x84FD 蓽 (<CJK Ideograph>) 13772 0x84FE 蓾 (<CJK Ideograph>) 13773 0x8500 蔀 (<CJK Ideograph>) 13774 0x8501 蔁 (<CJK Ideograph>) 13775 0x8502 蔂 (<CJK Ideograph>) 13776 0x4F1E 伞 (<CJK Ideograph>) 13777 0x6563 散 (<CJK Ideograph>) 13778 0x6851 桑 (<CJK Ideograph>) 13779 0x55D3 嗓 (<CJK Ideograph>) 13780 0x4E27 丧 (<CJK Ideograph>) 13781 0x6414 搔 (<CJK Ideograph>) 13782 0x9A9A 骚 (<CJK Ideograph>) 13783 0x626B 扫 (<CJK Ideograph>) 13784 0x5AC2 嫂 (<CJK Ideograph>) 13785 0x745F 瑟 (<CJK Ideograph>) 13786 0x8272 色 (<CJK Ideograph>) 13787 0x6DA9 涩 (<CJK Ideograph>) 13788 0x68EE 森 (<CJK Ideograph>) 13789 0x50E7 僧 (<CJK Ideograph>) 13790 0x838E 莎 (<CJK Ideograph>) 13791 0x7802 砂 (<CJK Ideograph>) 13792 0x6740 杀 (<CJK Ideograph>) 13793 0x5239 刹 (<CJK Ideograph>) 13794 0x6C99 沙 (<CJK Ideograph>) 13795 0x7EB1 纱 (<CJK Ideograph>) 13796 0x50BB 傻 (<CJK Ideograph>) 13797 0x5565 啥 (<CJK Ideograph>) 13798 0x715E 煞 (<CJK Ideograph>) 13799 0x7B5B 筛 (<CJK Ideograph>) 13800 0x6652 晒 (<CJK Ideograph>) 13801 0x73CA 珊 (<CJK Ideograph>) 13802 0x82EB 苫 (<CJK Ideograph>) 13803 0x6749 杉 (<CJK Ideograph>) 13804 0x5C71 山 (<CJK Ideograph>) 13805 0x5220 删 (<CJK Ideograph>) 13806 0x717D 煽 (<CJK Ideograph>) 13807 0x886B 衫 (<CJK Ideograph>) 13808 0x95EA 闪 (<CJK Ideograph>) 13809 0x9655 陕 (<CJK Ideograph>) 13810 0x64C5 擅 (<CJK Ideograph>) 13811 0x8D61 赡 (<CJK Ideograph>) 13812 0x81B3 膳 (<CJK Ideograph>) 13813 0x5584 善 (<CJK Ideograph>) 13814 0x6C55 汕 (<CJK Ideograph>) 13815 0x6247 扇 (<CJK Ideograph>) 13816 0x7F2E 缮 (<CJK Ideograph>) 13817 0x5892 墒 (<CJK Ideograph>) 13818 0x4F24 伤 (<CJK Ideograph>) 13819 0x5546 商 (<CJK Ideograph>) 13820 0x8D4F 赏 (<CJK Ideograph>) 13821 0x664C 晌 (<CJK Ideograph>) 13822 0x4E0A 上 (<CJK Ideograph>) 13823 0x5C1A 尚 (<CJK Ideograph>) 13824 0x88F3 裳 (<CJK Ideograph>) 13825 0x68A2 梢 (<CJK Ideograph>) 13826 0x634E 捎 (<CJK Ideograph>) 13827 0x7A0D 稍 (<CJK Ideograph>) 13828 0x70E7 烧 (<CJK Ideograph>) 13829 0x828D 芍 (<CJK Ideograph>) 13830 0x52FA 勺 (<CJK Ideograph>) 13831 0x97F6 韶 (<CJK Ideograph>) 13832 0x5C11 少 (<CJK Ideograph>) 13833 0x54E8 哨 (<CJK Ideograph>) 13834 0x90B5 邵 (<CJK Ideograph>) 13835 0x7ECD 绍 (<CJK Ideograph>) 13836 0x5962 奢 (<CJK Ideograph>) 13837 0x8D4A 赊 (<CJK Ideograph>) 13838 0x86C7 蛇 (<CJK Ideograph>) 13839 0x820C 舌 (<CJK Ideograph>) 13840 0x820D 舍 (<CJK Ideograph>) 13841 0x8D66 赦 (<CJK Ideograph>) 13842 0x6444 摄 (<CJK Ideograph>) 13843 0x5C04 射 (<CJK Ideograph>) 13844 0x6151 慑 (<CJK Ideograph>) 13845 0x6D89 涉 (<CJK Ideograph>) 13846 0x793E 社 (<CJK Ideograph>) 13847 0x8BBE 设 (<CJK Ideograph>) 13848 0x7837 砷 (<CJK Ideograph>) 13849 0x7533 申 (<CJK Ideograph>) 13850 0x547B 呻 (<CJK Ideograph>) 13851 0x4F38 伸 (<CJK Ideograph>) 13852 0x8EAB 身 (<CJK Ideograph>) 13853 0x6DF1 深 (<CJK Ideograph>) 13854 0x5A20 娠 (<CJK Ideograph>) 13855 0x7EC5 绅 (<CJK Ideograph>) 13856 0x795E 神 (<CJK Ideograph>) 13857 0x6C88 沈 (<CJK Ideograph>) 13858 0x5BA1 审 (<CJK Ideograph>) 13859 0x5A76 婶 (<CJK Ideograph>) 13860 0x751A 甚 (<CJK Ideograph>) 13861 0x80BE 肾 (<CJK Ideograph>) 13862 0x614E 慎 (<CJK Ideograph>) 13863 0x6E17 渗 (<CJK Ideograph>) 13864 0x58F0 声 (<CJK Ideograph>) 13865 0x751F 生 (<CJK Ideograph>) 13866 0x7525 甥 (<CJK Ideograph>) 13867 0x7272 牲 (<CJK Ideograph>) 13868 0x5347 升 (<CJK Ideograph>) 13869 0x7EF3 绳 (<CJK Ideograph>) 13870 0x8503 蔃 (<CJK Ideograph>) 13871 0x8504 蔄 (<CJK Ideograph>) 13872 0x8505 蔅 (<CJK Ideograph>) 13873 0x8506 蔆 (<CJK Ideograph>) 13874 0x8507 蔇 (<CJK Ideograph>) 13875 0x8508 蔈 (<CJK Ideograph>) 13876 0x8509 蔉 (<CJK Ideograph>) 13877 0x850A 蔊 (<CJK Ideograph>) 13878 0x850B 蔋 (<CJK Ideograph>) 13879 0x850D 蔍 (<CJK Ideograph>) 13880 0x850E 蔎 (<CJK Ideograph>) 13881 0x850F 蔏 (<CJK Ideograph>) 13882 0x8510 蔐 (<CJK Ideograph>) 13883 0x8512 蔒 (<CJK Ideograph>) 13884 0x8514 蔔 (<CJK Ideograph>) 13885 0x8515 蔕 (<CJK Ideograph>) 13886 0x8516 蔖 (<CJK Ideograph>) 13887 0x8518 蔘 (<CJK Ideograph>) 13888 0x8519 蔙 (<CJK Ideograph>) 13889 0x851B 蔛 (<CJK Ideograph>) 13890 0x851C 蔜 (<CJK Ideograph>) 13891 0x851D 蔝 (<CJK Ideograph>) 13892 0x851E 蔞 (<CJK Ideograph>) 13893 0x8520 蔠 (<CJK Ideograph>) 13894 0x8522 蔢 (<CJK Ideograph>) 13895 0x8523 蔣 (<CJK Ideograph>) 13896 0x8524 蔤 (<CJK Ideograph>) 13897 0x8525 蔥 (<CJK Ideograph>) 13898 0x8526 蔦 (<CJK Ideograph>) 13899 0x8527 蔧 (<CJK Ideograph>) 13900 0x8528 蔨 (<CJK Ideograph>) 13901 0x8529 蔩 (<CJK Ideograph>) 13902 0x852A 蔪 (<CJK Ideograph>) 13903 0x852D 蔭 (<CJK Ideograph>) 13904 0x852E 蔮 (<CJK Ideograph>) 13905 0x852F 蔯 (<CJK Ideograph>) 13906 0x8530 蔰 (<CJK Ideograph>) 13907 0x8531 蔱 (<CJK Ideograph>) 13908 0x8532 蔲 (<CJK Ideograph>) 13909 0x8533 蔳 (<CJK Ideograph>) 13910 0x8534 蔴 (<CJK Ideograph>) 13911 0x8535 蔵 (<CJK Ideograph>) 13912 0x8536 蔶 (<CJK Ideograph>) 13913 0x853E 蔾 (<CJK Ideograph>) 13914 0x853F 蔿 (<CJK Ideograph>) 13915 0x8540 蕀 (<CJK Ideograph>) 13916 0x8541 蕁 (<CJK Ideograph>) 13917 0x8542 蕂 (<CJK Ideograph>) 13918 0x8544 蕄 (<CJK Ideograph>) 13919 0x8545 蕅 (<CJK Ideograph>) 13920 0x8546 蕆 (<CJK Ideograph>) 13921 0x8547 蕇 (<CJK Ideograph>) 13922 0x854B 蕋 (<CJK Ideograph>) 13923 0x854C 蕌 (<CJK Ideograph>) 13924 0x854D 蕍 (<CJK Ideograph>) 13925 0x854E 蕎 (<CJK Ideograph>) 13926 0x854F 蕏 (<CJK Ideograph>) 13927 0x8550 蕐 (<CJK Ideograph>) 13928 0x8551 蕑 (<CJK Ideograph>) 13929 0x8552 蕒 (<CJK Ideograph>) 13930 0x8553 蕓 (<CJK Ideograph>) 13931 0x8554 蕔 (<CJK Ideograph>) 13932 0x8555 蕕 (<CJK Ideograph>) 13933 0x8557 蕗 (<CJK Ideograph>) 13934 0x8558 蕘 (<CJK Ideograph>) 13935 0x855A 蕚 (<CJK Ideograph>) 13936 0x855B 蕛 (<CJK Ideograph>) 13937 0x855C 蕜 (<CJK Ideograph>) 13938 0x855D 蕝 (<CJK Ideograph>) 13939 0x855F 蕟 (<CJK Ideograph>) 13940 0x8560 蕠 (<CJK Ideograph>) 13941 0x8561 蕡 (<CJK Ideograph>) 13942 0x8562 蕢 (<CJK Ideograph>) 13943 0x8563 蕣 (<CJK Ideograph>) 13944 0x8565 蕥 (<CJK Ideograph>) 13945 0x8566 蕦 (<CJK Ideograph>) 13946 0x8567 蕧 (<CJK Ideograph>) 13947 0x8569 蕩 (<CJK Ideograph>) 13948 0x856A 蕪 (<CJK Ideograph>) 13949 0x856B 蕫 (<CJK Ideograph>) 13950 0x856C 蕬 (<CJK Ideograph>) 13951 0x856D 蕭 (<CJK Ideograph>) 13952 0x856E 蕮 (<CJK Ideograph>) 13953 0x856F 蕯 (<CJK Ideograph>) 13954 0x8570 蕰 (<CJK Ideograph>) 13955 0x8571 蕱 (<CJK Ideograph>) 13956 0x8573 蕳 (<CJK Ideograph>) 13957 0x8575 蕵 (<CJK Ideograph>) 13958 0x8576 蕶 (<CJK Ideograph>) 13959 0x8577 蕷 (<CJK Ideograph>) 13960 0x8578 蕸 (<CJK Ideograph>) 13961 0x857C 蕼 (<CJK Ideograph>) 13962 0x857D 蕽 (<CJK Ideograph>) 13963 0x857F 蕿 (<CJK Ideograph>) 13964 0x8580 薀 (<CJK Ideograph>) 13965 0x8581 薁 (<CJK Ideograph>) 13966 0x7701 省 (<CJK Ideograph>) 13967 0x76DB 盛 (<CJK Ideograph>) 13968 0x5269 剩 (<CJK Ideograph>) 13969 0x80DC 胜 (<CJK Ideograph>) 13970 0x5723 圣 (<CJK Ideograph>) 13971 0x5E08 师 (<CJK Ideograph>) 13972 0x5931 失 (<CJK Ideograph>) 13973 0x72EE 狮 (<CJK Ideograph>) 13974 0x65BD 施 (<CJK Ideograph>) 13975 0x6E7F 湿 (<CJK Ideograph>) 13976 0x8BD7 诗 (<CJK Ideograph>) 13977 0x5C38 尸 (<CJK Ideograph>) 13978 0x8671 虱 (<CJK Ideograph>) 13979 0x5341 十 (<CJK Ideograph>) 13980 0x77F3 石 (<CJK Ideograph>) 13981 0x62FE 拾 (<CJK Ideograph>) 13982 0x65F6 时 (<CJK Ideograph>) 13983 0x4EC0 什 (<CJK Ideograph>) 13984 0x98DF 食 (<CJK Ideograph>) 13985 0x8680 蚀 (<CJK Ideograph>) 13986 0x5B9E 实 (<CJK Ideograph>) 13987 0x8BC6 识 (<CJK Ideograph>) 13988 0x53F2 史 (<CJK Ideograph>) 13989 0x77E2 矢 (<CJK Ideograph>) 13990 0x4F7F 使 (<CJK Ideograph>) 13991 0x5C4E 屎 (<CJK Ideograph>) 13992 0x9A76 驶 (<CJK Ideograph>) 13993 0x59CB 始 (<CJK Ideograph>) 13994 0x5F0F 式 (<CJK Ideograph>) 13995 0x793A 示 (<CJK Ideograph>) 13996 0x58EB 士 (<CJK Ideograph>) 13997 0x4E16 世 (<CJK Ideograph>) 13998 0x67FF 柿 (<CJK Ideograph>) 13999 0x4E8B 事 (<CJK Ideograph>) 14000 0x62ED 拭 (<CJK Ideograph>) 14001 0x8A93 誓 (<CJK Ideograph>) 14002 0x901D 逝 (<CJK Ideograph>) 14003 0x52BF 势 (<CJK Ideograph>) 14004 0x662F 是 (<CJK Ideograph>) 14005 0x55DC 嗜 (<CJK Ideograph>) 14006 0x566C 噬 (<CJK Ideograph>) 14007 0x9002 适 (<CJK Ideograph>) 14008 0x4ED5 仕 (<CJK Ideograph>) 14009 0x4F8D 侍 (<CJK Ideograph>) 14010 0x91CA 释 (<CJK Ideograph>) 14011 0x9970 饰 (<CJK Ideograph>) 14012 0x6C0F 氏 (<CJK Ideograph>) 14013 0x5E02 市 (<CJK Ideograph>) 14014 0x6043 恃 (<CJK Ideograph>) 14015 0x5BA4 室 (<CJK Ideograph>) 14016 0x89C6 视 (<CJK Ideograph>) 14017 0x8BD5 试 (<CJK Ideograph>) 14018 0x6536 收 (<CJK Ideograph>) 14019 0x624B 手 (<CJK Ideograph>) 14020 0x9996 首 (<CJK Ideograph>) 14021 0x5B88 守 (<CJK Ideograph>) 14022 0x5BFF 寿 (<CJK Ideograph>) 14023 0x6388 授 (<CJK Ideograph>) 14024 0x552E 售 (<CJK Ideograph>) 14025 0x53D7 受 (<CJK Ideograph>) 14026 0x7626 瘦 (<CJK Ideograph>) 14027 0x517D 兽 (<CJK Ideograph>) 14028 0x852C 蔬 (<CJK Ideograph>) 14029 0x67A2 枢 (<CJK Ideograph>) 14030 0x68B3 梳 (<CJK Ideograph>) 14031 0x6B8A 殊 (<CJK Ideograph>) 14032 0x6292 抒 (<CJK Ideograph>) 14033 0x8F93 输 (<CJK Ideograph>) 14034 0x53D4 叔 (<CJK Ideograph>) 14035 0x8212 舒 (<CJK Ideograph>) 14036 0x6DD1 淑 (<CJK Ideograph>) 14037 0x758F 疏 (<CJK Ideograph>) 14038 0x4E66 书 (<CJK Ideograph>) 14039 0x8D4E 赎 (<CJK Ideograph>) 14040 0x5B70 孰 (<CJK Ideograph>) 14041 0x719F 熟 (<CJK Ideograph>) 14042 0x85AF 薯 (<CJK Ideograph>) 14043 0x6691 暑 (<CJK Ideograph>) 14044 0x66D9 曙 (<CJK Ideograph>) 14045 0x7F72 署 (<CJK Ideograph>) 14046 0x8700 蜀 (<CJK Ideograph>) 14047 0x9ECD 黍 (<CJK Ideograph>) 14048 0x9F20 鼠 (<CJK Ideograph>) 14049 0x5C5E 属 (<CJK Ideograph>) 14050 0x672F 术 (<CJK Ideograph>) 14051 0x8FF0 述 (<CJK Ideograph>) 14052 0x6811 树 (<CJK Ideograph>) 14053 0x675F 束 (<CJK Ideograph>) 14054 0x620D 戍 (<CJK Ideograph>) 14055 0x7AD6 竖 (<CJK Ideograph>) 14056 0x5885 墅 (<CJK Ideograph>) 14057 0x5EB6 庶 (<CJK Ideograph>) 14058 0x6570 数 (<CJK Ideograph>) 14059 0x6F31 漱 (<CJK Ideograph>) 14060 0x8582 薂 (<CJK Ideograph>) 14061 0x8583 薃 (<CJK Ideograph>) 14062 0x8586 薆 (<CJK Ideograph>) 14063 0x8588 薈 (<CJK Ideograph>) 14064 0x8589 薉 (<CJK Ideograph>) 14065 0x858A 薊 (<CJK Ideograph>) 14066 0x858B 薋 (<CJK Ideograph>) 14067 0x858C 薌 (<CJK Ideograph>) 14068 0x858D 薍 (<CJK Ideograph>) 14069 0x858E 薎 (<CJK Ideograph>) 14070 0x8590 薐 (<CJK Ideograph>) 14071 0x8591 薑 (<CJK Ideograph>) 14072 0x8592 薒 (<CJK Ideograph>) 14073 0x8593 薓 (<CJK Ideograph>) 14074 0x8594 薔 (<CJK Ideograph>) 14075 0x8595 薕 (<CJK Ideograph>) 14076 0x8596 薖 (<CJK Ideograph>) 14077 0x8597 薗 (<CJK Ideograph>) 14078 0x8598 薘 (<CJK Ideograph>) 14079 0x8599 薙 (<CJK Ideograph>) 14080 0x859A 薚 (<CJK Ideograph>) 14081 0x859D 薝 (<CJK Ideograph>) 14082 0x859E 薞 (<CJK Ideograph>) 14083 0x859F 薟 (<CJK Ideograph>) 14084 0x85A0 薠 (<CJK Ideograph>) 14085 0x85A1 薡 (<CJK Ideograph>) 14086 0x85A2 薢 (<CJK Ideograph>) 14087 0x85A3 薣 (<CJK Ideograph>) 14088 0x85A5 薥 (<CJK Ideograph>) 14089 0x85A6 薦 (<CJK Ideograph>) 14090 0x85A7 薧 (<CJK Ideograph>) 14091 0x85A9 薩 (<CJK Ideograph>) 14092 0x85AB 薫 (<CJK Ideograph>) 14093 0x85AC 薬 (<CJK Ideograph>) 14094 0x85AD 薭 (<CJK Ideograph>) 14095 0x85B1 薱 (<CJK Ideograph>) 14096 0x85B2 薲 (<CJK Ideograph>) 14097 0x85B3 薳 (<CJK Ideograph>) 14098 0x85B4 薴 (<CJK Ideograph>) 14099 0x85B5 薵 (<CJK Ideograph>) 14100 0x85B6 薶 (<CJK Ideograph>) 14101 0x85B8 薸 (<CJK Ideograph>) 14102 0x85BA 薺 (<CJK Ideograph>) 14103 0x85BB 薻 (<CJK Ideograph>) 14104 0x85BC 薼 (<CJK Ideograph>) 14105 0x85BD 薽 (<CJK Ideograph>) 14106 0x85BE 薾 (<CJK Ideograph>) 14107 0x85BF 薿 (<CJK Ideograph>) 14108 0x85C0 藀 (<CJK Ideograph>) 14109 0x85C2 藂 (<CJK Ideograph>) 14110 0x85C3 藃 (<CJK Ideograph>) 14111 0x85C4 藄 (<CJK Ideograph>) 14112 0x85C5 藅 (<CJK Ideograph>) 14113 0x85C6 藆 (<CJK Ideograph>) 14114 0x85C7 藇 (<CJK Ideograph>) 14115 0x85C8 藈 (<CJK Ideograph>) 14116 0x85CA 藊 (<CJK Ideograph>) 14117 0x85CB 藋 (<CJK Ideograph>) 14118 0x85CC 藌 (<CJK Ideograph>) 14119 0x85CD 藍 (<CJK Ideograph>) 14120 0x85CE 藎 (<CJK Ideograph>) 14121 0x85D1 藑 (<CJK Ideograph>) 14122 0x85D2 藒 (<CJK Ideograph>) 14123 0x85D4 藔 (<CJK Ideograph>) 14124 0x85D6 藖 (<CJK Ideograph>) 14125 0x85D7 藗 (<CJK Ideograph>) 14126 0x85D8 藘 (<CJK Ideograph>) 14127 0x85D9 藙 (<CJK Ideograph>) 14128 0x85DA 藚 (<CJK Ideograph>) 14129 0x85DB 藛 (<CJK Ideograph>) 14130 0x85DD 藝 (<CJK Ideograph>) 14131 0x85DE 藞 (<CJK Ideograph>) 14132 0x85DF 藟 (<CJK Ideograph>) 14133 0x85E0 藠 (<CJK Ideograph>) 14134 0x85E1 藡 (<CJK Ideograph>) 14135 0x85E2 藢 (<CJK Ideograph>) 14136 0x85E3 藣 (<CJK Ideograph>) 14137 0x85E5 藥 (<CJK Ideograph>) 14138 0x85E6 藦 (<CJK Ideograph>) 14139 0x85E7 藧 (<CJK Ideograph>) 14140 0x85E8 藨 (<CJK Ideograph>) 14141 0x85EA 藪 (<CJK Ideograph>) 14142 0x85EB 藫 (<CJK Ideograph>) 14143 0x85EC 藬 (<CJK Ideograph>) 14144 0x85ED 藭 (<CJK Ideograph>) 14145 0x85EE 藮 (<CJK Ideograph>) 14146 0x85EF 藯 (<CJK Ideograph>) 14147 0x85F0 藰 (<CJK Ideograph>) 14148 0x85F1 藱 (<CJK Ideograph>) 14149 0x85F2 藲 (<CJK Ideograph>) 14150 0x85F3 藳 (<CJK Ideograph>) 14151 0x85F4 藴 (<CJK Ideograph>) 14152 0x85F5 藵 (<CJK Ideograph>) 14153 0x85F6 藶 (<CJK Ideograph>) 14154 0x85F7 藷 (<CJK Ideograph>) 14155 0x85F8 藸 (<CJK Ideograph>) 14156 0x6055 恕 (<CJK Ideograph>) 14157 0x5237 刷 (<CJK Ideograph>) 14158 0x800D 耍 (<CJK Ideograph>) 14159 0x6454 摔 (<CJK Ideograph>) 14160 0x8870 衰 (<CJK Ideograph>) 14161 0x7529 甩 (<CJK Ideograph>) 14162 0x5E05 帅 (<CJK Ideograph>) 14163 0x6813 栓 (<CJK Ideograph>) 14164 0x62F4 拴 (<CJK Ideograph>) 14165 0x971C 霜 (<CJK Ideograph>) 14166 0x53CC 双 (<CJK Ideograph>) 14167 0x723D 爽 (<CJK Ideograph>) 14168 0x8C01 谁 (<CJK Ideograph>) 14169 0x6C34 水 (<CJK Ideograph>) 14170 0x7761 睡 (<CJK Ideograph>) 14171 0x7A0E 税 (<CJK Ideograph>) 14172 0x542E 吮 (<CJK Ideograph>) 14173 0x77AC 瞬 (<CJK Ideograph>) 14174 0x987A 顺 (<CJK Ideograph>) 14175 0x821C 舜 (<CJK Ideograph>) 14176 0x8BF4 说 (<CJK Ideograph>) 14177 0x7855 硕 (<CJK Ideograph>) 14178 0x6714 朔 (<CJK Ideograph>) 14179 0x70C1 烁 (<CJK Ideograph>) 14180 0x65AF 斯 (<CJK Ideograph>) 14181 0x6495 撕 (<CJK Ideograph>) 14182 0x5636 嘶 (<CJK Ideograph>) 14183 0x601D 思 (<CJK Ideograph>) 14184 0x79C1 私 (<CJK Ideograph>) 14185 0x53F8 司 (<CJK Ideograph>) 14186 0x4E1D 丝 (<CJK Ideograph>) 14187 0x6B7B 死 (<CJK Ideograph>) 14188 0x8086 肆 (<CJK Ideograph>) 14189 0x5BFA 寺 (<CJK Ideograph>) 14190 0x55E3 嗣 (<CJK Ideograph>) 14191 0x56DB 四 (<CJK Ideograph>) 14192 0x4F3A 伺 (<CJK Ideograph>) 14193 0x4F3C 似 (<CJK Ideograph>) 14194 0x9972 饲 (<CJK Ideograph>) 14195 0x5DF3 巳 (<CJK Ideograph>) 14196 0x677E 松 (<CJK Ideograph>) 14197 0x8038 耸 (<CJK Ideograph>) 14198 0x6002 怂 (<CJK Ideograph>) 14199 0x9882 颂 (<CJK Ideograph>) 14200 0x9001 送 (<CJK Ideograph>) 14201 0x5B8B 宋 (<CJK Ideograph>) 14202 0x8BBC 讼 (<CJK Ideograph>) 14203 0x8BF5 诵 (<CJK Ideograph>) 14204 0x641C 搜 (<CJK Ideograph>) 14205 0x8258 艘 (<CJK Ideograph>) 14206 0x64DE 擞 (<CJK Ideograph>) 14207 0x55FD 嗽 (<CJK Ideograph>) 14208 0x82CF 苏 (<CJK Ideograph>) 14209 0x9165 酥 (<CJK Ideograph>) 14210 0x4FD7 俗 (<CJK Ideograph>) 14211 0x7D20 素 (<CJK Ideograph>) 14212 0x901F 速 (<CJK Ideograph>) 14213 0x7C9F 粟 (<CJK Ideograph>) 14214 0x50F3 僳 (<CJK Ideograph>) 14215 0x5851 塑 (<CJK Ideograph>) 14216 0x6EAF 溯 (<CJK Ideograph>) 14217 0x5BBF 宿 (<CJK Ideograph>) 14218 0x8BC9 诉 (<CJK Ideograph>) 14219 0x8083 肃 (<CJK Ideograph>) 14220 0x9178 酸 (<CJK Ideograph>) 14221 0x849C 蒜 (<CJK Ideograph>) 14222 0x7B97 算 (<CJK Ideograph>) 14223 0x867D 虽 (<CJK Ideograph>) 14224 0x968B 隋 (<CJK Ideograph>) 14225 0x968F 随 (<CJK Ideograph>) 14226 0x7EE5 绥 (<CJK Ideograph>) 14227 0x9AD3 髓 (<CJK Ideograph>) 14228 0x788E 碎 (<CJK Ideograph>) 14229 0x5C81 岁 (<CJK Ideograph>) 14230 0x7A57 穗 (<CJK Ideograph>) 14231 0x9042 遂 (<CJK Ideograph>) 14232 0x96A7 隧 (<CJK Ideograph>) 14233 0x795F 祟 (<CJK Ideograph>) 14234 0x5B59 孙 (<CJK Ideograph>) 14235 0x635F 损 (<CJK Ideograph>) 14236 0x7B0B 笋 (<CJK Ideograph>) 14237 0x84D1 蓑 (<CJK Ideograph>) 14238 0x68AD 梭 (<CJK Ideograph>) 14239 0x5506 唆 (<CJK Ideograph>) 14240 0x7F29 缩 (<CJK Ideograph>) 14241 0x7410 琐 (<CJK Ideograph>) 14242 0x7D22 索 (<CJK Ideograph>) 14243 0x9501 锁 (<CJK Ideograph>) 14244 0x6240 所 (<CJK Ideograph>) 14245 0x584C 塌 (<CJK Ideograph>) 14246 0x4ED6 他 (<CJK Ideograph>) 14247 0x5B83 它 (<CJK Ideograph>) 14248 0x5979 她 (<CJK Ideograph>) 14249 0x5854 塔 (<CJK Ideograph>) 14250 0x85F9 藹 (<CJK Ideograph>) 14251 0x85FA 藺 (<CJK Ideograph>) 14252 0x85FC 藼 (<CJK Ideograph>) 14253 0x85FD 藽 (<CJK Ideograph>) 14254 0x85FE 藾 (<CJK Ideograph>) 14255 0x8600 蘀 (<CJK Ideograph>) 14256 0x8601 蘁 (<CJK Ideograph>) 14257 0x8602 蘂 (<CJK Ideograph>) 14258 0x8603 蘃 (<CJK Ideograph>) 14259 0x8604 蘄 (<CJK Ideograph>) 14260 0x8606 蘆 (<CJK Ideograph>) 14261 0x8607 蘇 (<CJK Ideograph>) 14262 0x8608 蘈 (<CJK Ideograph>) 14263 0x8609 蘉 (<CJK Ideograph>) 14264 0x860A 蘊 (<CJK Ideograph>) 14265 0x860B 蘋 (<CJK Ideograph>) 14266 0x860C 蘌 (<CJK Ideograph>) 14267 0x860D 蘍 (<CJK Ideograph>) 14268 0x860E 蘎 (<CJK Ideograph>) 14269 0x860F 蘏 (<CJK Ideograph>) 14270 0x8610 蘐 (<CJK Ideograph>) 14271 0x8612 蘒 (<CJK Ideograph>) 14272 0x8613 蘓 (<CJK Ideograph>) 14273 0x8614 蘔 (<CJK Ideograph>) 14274 0x8615 蘕 (<CJK Ideograph>) 14275 0x8617 蘗 (<CJK Ideograph>) 14276 0x8618 蘘 (<CJK Ideograph>) 14277 0x8619 蘙 (<CJK Ideograph>) 14278 0x861A 蘚 (<CJK Ideograph>) 14279 0x861B 蘛 (<CJK Ideograph>) 14280 0x861C 蘜 (<CJK Ideograph>) 14281 0x861D 蘝 (<CJK Ideograph>) 14282 0x861E 蘞 (<CJK Ideograph>) 14283 0x861F 蘟 (<CJK Ideograph>) 14284 0x8620 蘠 (<CJK Ideograph>) 14285 0x8621 蘡 (<CJK Ideograph>) 14286 0x8622 蘢 (<CJK Ideograph>) 14287 0x8623 蘣 (<CJK Ideograph>) 14288 0x8624 蘤 (<CJK Ideograph>) 14289 0x8625 蘥 (<CJK Ideograph>) 14290 0x8626 蘦 (<CJK Ideograph>) 14291 0x8628 蘨 (<CJK Ideograph>) 14292 0x862A 蘪 (<CJK Ideograph>) 14293 0x862B 蘫 (<CJK Ideograph>) 14294 0x862C 蘬 (<CJK Ideograph>) 14295 0x862D 蘭 (<CJK Ideograph>) 14296 0x862E 蘮 (<CJK Ideograph>) 14297 0x862F 蘯 (<CJK Ideograph>) 14298 0x8630 蘰 (<CJK Ideograph>) 14299 0x8631 蘱 (<CJK Ideograph>) 14300 0x8632 蘲 (<CJK Ideograph>) 14301 0x8633 蘳 (<CJK Ideograph>) 14302 0x8634 蘴 (<CJK Ideograph>) 14303 0x8635 蘵 (<CJK Ideograph>) 14304 0x8636 蘶 (<CJK Ideograph>) 14305 0x8637 蘷 (<CJK Ideograph>) 14306 0x8639 蘹 (<CJK Ideograph>) 14307 0x863A 蘺 (<CJK Ideograph>) 14308 0x863B 蘻 (<CJK Ideograph>) 14309 0x863D 蘽 (<CJK Ideograph>) 14310 0x863E 蘾 (<CJK Ideograph>) 14311 0x863F 蘿 (<CJK Ideograph>) 14312 0x8640 虀 (<CJK Ideograph>) 14313 0x8641 虁 (<CJK Ideograph>) 14314 0x8642 虂 (<CJK Ideograph>) 14315 0x8643 虃 (<CJK Ideograph>) 14316 0x8644 虄 (<CJK Ideograph>) 14317 0x8645 虅 (<CJK Ideograph>) 14318 0x8646 虆 (<CJK Ideograph>) 14319 0x8647 虇 (<CJK Ideograph>) 14320 0x8648 虈 (<CJK Ideograph>) 14321 0x8649 虉 (<CJK Ideograph>) 14322 0x864A 虊 (<CJK Ideograph>) 14323 0x864B 虋 (<CJK Ideograph>) 14324 0x864C 虌 (<CJK Ideograph>) 14325 0x8652 虒 (<CJK Ideograph>) 14326 0x8653 虓 (<CJK Ideograph>) 14327 0x8655 處 (<CJK Ideograph>) 14328 0x8656 虖 (<CJK Ideograph>) 14329 0x8657 虗 (<CJK Ideograph>) 14330 0x8658 虘 (<CJK Ideograph>) 14331 0x8659 虙 (<CJK Ideograph>) 14332 0x865B 虛 (<CJK Ideograph>) 14333 0x865C 虜 (<CJK Ideograph>) 14334 0x865D 虝 (<CJK Ideograph>) 14335 0x865F 號 (<CJK Ideograph>) 14336 0x8660 虠 (<CJK Ideograph>) 14337 0x8661 虡 (<CJK Ideograph>) 14338 0x8663 虣 (<CJK Ideograph>) 14339 0x8664 虤 (<CJK Ideograph>) 14340 0x8665 虥 (<CJK Ideograph>) 14341 0x8666 虦 (<CJK Ideograph>) 14342 0x8667 虧 (<CJK Ideograph>) 14343 0x8668 虨 (<CJK Ideograph>) 14344 0x8669 虩 (<CJK Ideograph>) 14345 0x866A 虪 (<CJK Ideograph>) 14346 0x736D 獭 (<CJK Ideograph>) 14347 0x631E 挞 (<CJK Ideograph>) 14348 0x8E4B 蹋 (<CJK Ideograph>) 14349 0x8E0F 踏 (<CJK Ideograph>) 14350 0x80CE 胎 (<CJK Ideograph>) 14351 0x82D4 苔 (<CJK Ideograph>) 14352 0x62AC 抬 (<CJK Ideograph>) 14353 0x53F0 台 (<CJK Ideograph>) 14354 0x6CF0 泰 (<CJK Ideograph>) 14355 0x915E 酞 (<CJK Ideograph>) 14356 0x592A 太 (<CJK Ideograph>) 14357 0x6001 态 (<CJK Ideograph>) 14358 0x6C70 汰 (<CJK Ideograph>) 14359 0x574D 坍 (<CJK Ideograph>) 14360 0x644A 摊 (<CJK Ideograph>) 14361 0x8D2A 贪 (<CJK Ideograph>) 14362 0x762B 瘫 (<CJK Ideograph>) 14363 0x6EE9 滩 (<CJK Ideograph>) 14364 0x575B 坛 (<CJK Ideograph>) 14365 0x6A80 檀 (<CJK Ideograph>) 14366 0x75F0 痰 (<CJK Ideograph>) 14367 0x6F6D 潭 (<CJK Ideograph>) 14368 0x8C2D 谭 (<CJK Ideograph>) 14369 0x8C08 谈 (<CJK Ideograph>) 14370 0x5766 坦 (<CJK Ideograph>) 14371 0x6BEF 毯 (<CJK Ideograph>) 14372 0x8892 袒 (<CJK Ideograph>) 14373 0x78B3 碳 (<CJK Ideograph>) 14374 0x63A2 探 (<CJK Ideograph>) 14375 0x53F9 叹 (<CJK Ideograph>) 14376 0x70AD 炭 (<CJK Ideograph>) 14377 0x6C64 汤 (<CJK Ideograph>) 14378 0x5858 塘 (<CJK Ideograph>) 14379 0x642A 搪 (<CJK Ideograph>) 14380 0x5802 堂 (<CJK Ideograph>) 14381 0x68E0 棠 (<CJK Ideograph>) 14382 0x819B 膛 (<CJK Ideograph>) 14383 0x5510 唐 (<CJK Ideograph>) 14384 0x7CD6 糖 (<CJK Ideograph>) 14385 0x5018 倘 (<CJK Ideograph>) 14386 0x8EBA 躺 (<CJK Ideograph>) 14387 0x6DCC 淌 (<CJK Ideograph>) 14388 0x8D9F 趟 (<CJK Ideograph>) 14389 0x70EB 烫 (<CJK Ideograph>) 14390 0x638F 掏 (<CJK Ideograph>) 14391 0x6D9B 涛 (<CJK Ideograph>) 14392 0x6ED4 滔 (<CJK Ideograph>) 14393 0x7EE6 绦 (<CJK Ideograph>) 14394 0x8404 萄 (<CJK Ideograph>) 14395 0x6843 桃 (<CJK Ideograph>) 14396 0x9003 逃 (<CJK Ideograph>) 14397 0x6DD8 淘 (<CJK Ideograph>) 14398 0x9676 陶 (<CJK Ideograph>) 14399 0x8BA8 讨 (<CJK Ideograph>) 14400 0x5957 套 (<CJK Ideograph>) 14401 0x7279 特 (<CJK Ideograph>) 14402 0x85E4 藤 (<CJK Ideograph>) 14403 0x817E 腾 (<CJK Ideograph>) 14404 0x75BC 疼 (<CJK Ideograph>) 14405 0x8A8A 誊 (<CJK Ideograph>) 14406 0x68AF 梯 (<CJK Ideograph>) 14407 0x5254 剔 (<CJK Ideograph>) 14408 0x8E22 踢 (<CJK Ideograph>) 14409 0x9511 锑 (<CJK Ideograph>) 14410 0x63D0 提 (<CJK Ideograph>) 14411 0x9898 题 (<CJK Ideograph>) 14412 0x8E44 蹄 (<CJK Ideograph>) 14413 0x557C 啼 (<CJK Ideograph>) 14414 0x4F53 体 (<CJK Ideograph>) 14415 0x66FF 替 (<CJK Ideograph>) 14416 0x568F 嚏 (<CJK Ideograph>) 14417 0x60D5 惕 (<CJK Ideograph>) 14418 0x6D95 涕 (<CJK Ideograph>) 14419 0x5243 剃 (<CJK Ideograph>) 14420 0x5C49 屉 (<CJK Ideograph>) 14421 0x5929 天 (<CJK Ideograph>) 14422 0x6DFB 添 (<CJK Ideograph>) 14423 0x586B 填 (<CJK Ideograph>) 14424 0x7530 田 (<CJK Ideograph>) 14425 0x751C 甜 (<CJK Ideograph>) 14426 0x606C 恬 (<CJK Ideograph>) 14427 0x8214 舔 (<CJK Ideograph>) 14428 0x8146 腆 (<CJK Ideograph>) 14429 0x6311 挑 (<CJK Ideograph>) 14430 0x6761 条 (<CJK Ideograph>) 14431 0x8FE2 迢 (<CJK Ideograph>) 14432 0x773A 眺 (<CJK Ideograph>) 14433 0x8DF3 跳 (<CJK Ideograph>) 14434 0x8D34 贴 (<CJK Ideograph>) 14435 0x94C1 铁 (<CJK Ideograph>) 14436 0x5E16 帖 (<CJK Ideograph>) 14437 0x5385 厅 (<CJK Ideograph>) 14438 0x542C 听 (<CJK Ideograph>) 14439 0x70C3 烃 (<CJK Ideograph>) 14440 0x866D 虭 (<CJK Ideograph>) 14441 0x866F 虯 (<CJK Ideograph>) 14442 0x8670 虰 (<CJK Ideograph>) 14443 0x8672 虲 (<CJK Ideograph>) 14444 0x8673 虳 (<CJK Ideograph>) 14445 0x8674 虴 (<CJK Ideograph>) 14446 0x8675 虵 (<CJK Ideograph>) 14447 0x8676 虶 (<CJK Ideograph>) 14448 0x8677 虷 (<CJK Ideograph>) 14449 0x8678 虸 (<CJK Ideograph>) 14450 0x8683 蚃 (<CJK Ideograph>) 14451 0x8684 蚄 (<CJK Ideograph>) 14452 0x8685 蚅 (<CJK Ideograph>) 14453 0x8686 蚆 (<CJK Ideograph>) 14454 0x8687 蚇 (<CJK Ideograph>) 14455 0x8688 蚈 (<CJK Ideograph>) 14456 0x8689 蚉 (<CJK Ideograph>) 14457 0x868E 蚎 (<CJK Ideograph>) 14458 0x868F 蚏 (<CJK Ideograph>) 14459 0x8690 蚐 (<CJK Ideograph>) 14460 0x8691 蚑 (<CJK Ideograph>) 14461 0x8692 蚒 (<CJK Ideograph>) 14462 0x8694 蚔 (<CJK Ideograph>) 14463 0x8696 蚖 (<CJK Ideograph>) 14464 0x8697 蚗 (<CJK Ideograph>) 14465 0x8698 蚘 (<CJK Ideograph>) 14466 0x8699 蚙 (<CJK Ideograph>) 14467 0x869A 蚚 (<CJK Ideograph>) 14468 0x869B 蚛 (<CJK Ideograph>) 14469 0x869E 蚞 (<CJK Ideograph>) 14470 0x869F 蚟 (<CJK Ideograph>) 14471 0x86A0 蚠 (<CJK Ideograph>) 14472 0x86A1 蚡 (<CJK Ideograph>) 14473 0x86A2 蚢 (<CJK Ideograph>) 14474 0x86A5 蚥 (<CJK Ideograph>) 14475 0x86A6 蚦 (<CJK Ideograph>) 14476 0x86AB 蚫 (<CJK Ideograph>) 14477 0x86AD 蚭 (<CJK Ideograph>) 14478 0x86AE 蚮 (<CJK Ideograph>) 14479 0x86B2 蚲 (<CJK Ideograph>) 14480 0x86B3 蚳 (<CJK Ideograph>) 14481 0x86B7 蚷 (<CJK Ideograph>) 14482 0x86B8 蚸 (<CJK Ideograph>) 14483 0x86B9 蚹 (<CJK Ideograph>) 14484 0x86BB 蚻 (<CJK Ideograph>) 14485 0x86BC 蚼 (<CJK Ideograph>) 14486 0x86BD 蚽 (<CJK Ideograph>) 14487 0x86BE 蚾 (<CJK Ideograph>) 14488 0x86BF 蚿 (<CJK Ideograph>) 14489 0x86C1 蛁 (<CJK Ideograph>) 14490 0x86C2 蛂 (<CJK Ideograph>) 14491 0x86C3 蛃 (<CJK Ideograph>) 14492 0x86C5 蛅 (<CJK Ideograph>) 14493 0x86C8 蛈 (<CJK Ideograph>) 14494 0x86CC 蛌 (<CJK Ideograph>) 14495 0x86CD 蛍 (<CJK Ideograph>) 14496 0x86D2 蛒 (<CJK Ideograph>) 14497 0x86D3 蛓 (<CJK Ideograph>) 14498 0x86D5 蛕 (<CJK Ideograph>) 14499 0x86D6 蛖 (<CJK Ideograph>) 14500 0x86D7 蛗 (<CJK Ideograph>) 14501 0x86DA 蛚 (<CJK Ideograph>) 14502 0x86DC 蛜 (<CJK Ideograph>) 14503 0x86DD 蛝 (<CJK Ideograph>) 14504 0x86E0 蛠 (<CJK Ideograph>) 14505 0x86E1 蛡 (<CJK Ideograph>) 14506 0x86E2 蛢 (<CJK Ideograph>) 14507 0x86E3 蛣 (<CJK Ideograph>) 14508 0x86E5 蛥 (<CJK Ideograph>) 14509 0x86E6 蛦 (<CJK Ideograph>) 14510 0x86E7 蛧 (<CJK Ideograph>) 14511 0x86E8 蛨 (<CJK Ideograph>) 14512 0x86EA 蛪 (<CJK Ideograph>) 14513 0x86EB 蛫 (<CJK Ideograph>) 14514 0x86EC 蛬 (<CJK Ideograph>) 14515 0x86EF 蛯 (<CJK Ideograph>) 14516 0x86F5 蛵 (<CJK Ideograph>) 14517 0x86F6 蛶 (<CJK Ideograph>) 14518 0x86F7 蛷 (<CJK Ideograph>) 14519 0x86FA 蛺 (<CJK Ideograph>) 14520 0x86FB 蛻 (<CJK Ideograph>) 14521 0x86FC 蛼 (<CJK Ideograph>) 14522 0x86FD 蛽 (<CJK Ideograph>) 14523 0x86FF 蛿 (<CJK Ideograph>) 14524 0x8701 蜁 (<CJK Ideograph>) 14525 0x8704 蜄 (<CJK Ideograph>) 14526 0x8705 蜅 (<CJK Ideograph>) 14527 0x8706 蜆 (<CJK Ideograph>) 14528 0x870B 蜋 (<CJK Ideograph>) 14529 0x870C 蜌 (<CJK Ideograph>) 14530 0x870E 蜎 (<CJK Ideograph>) 14531 0x870F 蜏 (<CJK Ideograph>) 14532 0x8710 蜐 (<CJK Ideograph>) 14533 0x8711 蜑 (<CJK Ideograph>) 14534 0x8714 蜔 (<CJK Ideograph>) 14535 0x8716 蜖 (<CJK Ideograph>) 14536 0x6C40 汀 (<CJK Ideograph>) 14537 0x5EF7 廷 (<CJK Ideograph>) 14538 0x505C 停 (<CJK Ideograph>) 14539 0x4EAD 亭 (<CJK Ideograph>) 14540 0x5EAD 庭 (<CJK Ideograph>) 14541 0x633A 挺 (<CJK Ideograph>) 14542 0x8247 艇 (<CJK Ideograph>) 14543 0x901A 通 (<CJK Ideograph>) 14544 0x6850 桐 (<CJK Ideograph>) 14545 0x916E 酮 (<CJK Ideograph>) 14546 0x77B3 瞳 (<CJK Ideograph>) 14547 0x540C 同 (<CJK Ideograph>) 14548 0x94DC 铜 (<CJK Ideograph>) 14549 0x5F64 彤 (<CJK Ideograph>) 14550 0x7AE5 童 (<CJK Ideograph>) 14551 0x6876 桶 (<CJK Ideograph>) 14552 0x6345 捅 (<CJK Ideograph>) 14553 0x7B52 筒 (<CJK Ideograph>) 14554 0x7EDF 统 (<CJK Ideograph>) 14555 0x75DB 痛 (<CJK Ideograph>) 14556 0x5077 偷 (<CJK Ideograph>) 14557 0x6295 投 (<CJK Ideograph>) 14558 0x5934 头 (<CJK Ideograph>) 14559 0x900F 透 (<CJK Ideograph>) 14560 0x51F8 凸 (<CJK Ideograph>) 14561 0x79C3 秃 (<CJK Ideograph>) 14562 0x7A81 突 (<CJK Ideograph>) 14563 0x56FE 图 (<CJK Ideograph>) 14564 0x5F92 徒 (<CJK Ideograph>) 14565 0x9014 途 (<CJK Ideograph>) 14566 0x6D82 涂 (<CJK Ideograph>) 14567 0x5C60 屠 (<CJK Ideograph>) 14568 0x571F 土 (<CJK Ideograph>) 14569 0x5410 吐 (<CJK Ideograph>) 14570 0x5154 兔 (<CJK Ideograph>) 14571 0x6E4D 湍 (<CJK Ideograph>) 14572 0x56E2 团 (<CJK Ideograph>) 14573 0x63A8 推 (<CJK Ideograph>) 14574 0x9893 颓 (<CJK Ideograph>) 14575 0x817F 腿 (<CJK Ideograph>) 14576 0x8715 蜕 (<CJK Ideograph>) 14577 0x892A 褪 (<CJK Ideograph>) 14578 0x9000 退 (<CJK Ideograph>) 14579 0x541E 吞 (<CJK Ideograph>) 14580 0x5C6F 屯 (<CJK Ideograph>) 14581 0x81C0 臀 (<CJK Ideograph>) 14582 0x62D6 拖 (<CJK Ideograph>) 14583 0x6258 托 (<CJK Ideograph>) 14584 0x8131 脱 (<CJK Ideograph>) 14585 0x9E35 鸵 (<CJK Ideograph>) 14586 0x9640 陀 (<CJK Ideograph>) 14587 0x9A6E 驮 (<CJK Ideograph>) 14588 0x9A7C 驼 (<CJK Ideograph>) 14589 0x692D 椭 (<CJK Ideograph>) 14590 0x59A5 妥 (<CJK Ideograph>) 14591 0x62D3 拓 (<CJK Ideograph>) 14592 0x553E 唾 (<CJK Ideograph>) 14593 0x6316 挖 (<CJK Ideograph>) 14594 0x54C7 哇 (<CJK Ideograph>) 14595 0x86D9 蛙 (<CJK Ideograph>) 14596 0x6D3C 洼 (<CJK Ideograph>) 14597 0x5A03 娃 (<CJK Ideograph>) 14598 0x74E6 瓦 (<CJK Ideograph>) 14599 0x889C 袜 (<CJK Ideograph>) 14600 0x6B6A 歪 (<CJK Ideograph>) 14601 0x5916 外 (<CJK Ideograph>) 14602 0x8C4C 豌 (<CJK Ideograph>) 14603 0x5F2F 弯 (<CJK Ideograph>) 14604 0x6E7E 湾 (<CJK Ideograph>) 14605 0x73A9 玩 (<CJK Ideograph>) 14606 0x987D 顽 (<CJK Ideograph>) 14607 0x4E38 丸 (<CJK Ideograph>) 14608 0x70F7 烷 (<CJK Ideograph>) 14609 0x5B8C 完 (<CJK Ideograph>) 14610 0x7897 碗 (<CJK Ideograph>) 14611 0x633D 挽 (<CJK Ideograph>) 14612 0x665A 晚 (<CJK Ideograph>) 14613 0x7696 皖 (<CJK Ideograph>) 14614 0x60CB 惋 (<CJK Ideograph>) 14615 0x5B9B 宛 (<CJK Ideograph>) 14616 0x5A49 婉 (<CJK Ideograph>) 14617 0x4E07 万 (<CJK Ideograph>) 14618 0x8155 腕 (<CJK Ideograph>) 14619 0x6C6A 汪 (<CJK Ideograph>) 14620 0x738B 王 (<CJK Ideograph>) 14621 0x4EA1 亡 (<CJK Ideograph>) 14622 0x6789 枉 (<CJK Ideograph>) 14623 0x7F51 网 (<CJK Ideograph>) 14624 0x5F80 往 (<CJK Ideograph>) 14625 0x65FA 旺 (<CJK Ideograph>) 14626 0x671B 望 (<CJK Ideograph>) 14627 0x5FD8 忘 (<CJK Ideograph>) 14628 0x5984 妄 (<CJK Ideograph>) 14629 0x5A01 威 (<CJK Ideograph>) 14630 0x8719 蜙 (<CJK Ideograph>) 14631 0x871B 蜛 (<CJK Ideograph>) 14632 0x871D 蜝 (<CJK Ideograph>) 14633 0x871F 蜟 (<CJK Ideograph>) 14634 0x8720 蜠 (<CJK Ideograph>) 14635 0x8724 蜤 (<CJK Ideograph>) 14636 0x8726 蜦 (<CJK Ideograph>) 14637 0x8727 蜧 (<CJK Ideograph>) 14638 0x8728 蜨 (<CJK Ideograph>) 14639 0x872A 蜪 (<CJK Ideograph>) 14640 0x872B 蜫 (<CJK Ideograph>) 14641 0x872C 蜬 (<CJK Ideograph>) 14642 0x872D 蜭 (<CJK Ideograph>) 14643 0x872F 蜯 (<CJK Ideograph>) 14644 0x8730 蜰 (<CJK Ideograph>) 14645 0x8732 蜲 (<CJK Ideograph>) 14646 0x8733 蜳 (<CJK Ideograph>) 14647 0x8735 蜵 (<CJK Ideograph>) 14648 0x8736 蜶 (<CJK Ideograph>) 14649 0x8738 蜸 (<CJK Ideograph>) 14650 0x8739 蜹 (<CJK Ideograph>) 14651 0x873A 蜺 (<CJK Ideograph>) 14652 0x873C 蜼 (<CJK Ideograph>) 14653 0x873D 蜽 (<CJK Ideograph>) 14654 0x8740 蝀 (<CJK Ideograph>) 14655 0x8741 蝁 (<CJK Ideograph>) 14656 0x8742 蝂 (<CJK Ideograph>) 14657 0x8743 蝃 (<CJK Ideograph>) 14658 0x8744 蝄 (<CJK Ideograph>) 14659 0x8745 蝅 (<CJK Ideograph>) 14660 0x8746 蝆 (<CJK Ideograph>) 14661 0x874A 蝊 (<CJK Ideograph>) 14662 0x874B 蝋 (<CJK Ideograph>) 14663 0x874D 蝍 (<CJK Ideograph>) 14664 0x874F 蝏 (<CJK Ideograph>) 14665 0x8750 蝐 (<CJK Ideograph>) 14666 0x8751 蝑 (<CJK Ideograph>) 14667 0x8752 蝒 (<CJK Ideograph>) 14668 0x8754 蝔 (<CJK Ideograph>) 14669 0x8755 蝕 (<CJK Ideograph>) 14670 0x8756 蝖 (<CJK Ideograph>) 14671 0x8758 蝘 (<CJK Ideograph>) 14672 0x875A 蝚 (<CJK Ideograph>) 14673 0x875B 蝛 (<CJK Ideograph>) 14674 0x875C 蝜 (<CJK Ideograph>) 14675 0x875D 蝝 (<CJK Ideograph>) 14676 0x875E 蝞 (<CJK Ideograph>) 14677 0x875F 蝟 (<CJK Ideograph>) 14678 0x8761 蝡 (<CJK Ideograph>) 14679 0x8762 蝢 (<CJK Ideograph>) 14680 0x8766 蝦 (<CJK Ideograph>) 14681 0x8767 蝧 (<CJK Ideograph>) 14682 0x8768 蝨 (<CJK Ideograph>) 14683 0x8769 蝩 (<CJK Ideograph>) 14684 0x876A 蝪 (<CJK Ideograph>) 14685 0x876B 蝫 (<CJK Ideograph>) 14686 0x876C 蝬 (<CJK Ideograph>) 14687 0x876D 蝭 (<CJK Ideograph>) 14688 0x876F 蝯 (<CJK Ideograph>) 14689 0x8771 蝱 (<CJK Ideograph>) 14690 0x8772 蝲 (<CJK Ideograph>) 14691 0x8773 蝳 (<CJK Ideograph>) 14692 0x8775 蝵 (<CJK Ideograph>) 14693 0x8777 蝷 (<CJK Ideograph>) 14694 0x8778 蝸 (<CJK Ideograph>) 14695 0x8779 蝹 (<CJK Ideograph>) 14696 0x877A 蝺 (<CJK Ideograph>) 14697 0x877F 蝿 (<CJK Ideograph>) 14698 0x8780 螀 (<CJK Ideograph>) 14699 0x8781 螁 (<CJK Ideograph>) 14700 0x8784 螄 (<CJK Ideograph>) 14701 0x8786 螆 (<CJK Ideograph>) 14702 0x8787 螇 (<CJK Ideograph>) 14703 0x8789 螉 (<CJK Ideograph>) 14704 0x878A 螊 (<CJK Ideograph>) 14705 0x878C 螌 (<CJK Ideograph>) 14706 0x878E 螎 (<CJK Ideograph>) 14707 0x878F 螏 (<CJK Ideograph>) 14708 0x8790 螐 (<CJK Ideograph>) 14709 0x8791 螑 (<CJK Ideograph>) 14710 0x8792 螒 (<CJK Ideograph>) 14711 0x8794 螔 (<CJK Ideograph>) 14712 0x8795 螕 (<CJK Ideograph>) 14713 0x8796 螖 (<CJK Ideograph>) 14714 0x8798 螘 (<CJK Ideograph>) 14715 0x8799 螙 (<CJK Ideograph>) 14716 0x879A 螚 (<CJK Ideograph>) 14717 0x879B 螛 (<CJK Ideograph>) 14718 0x879C 螜 (<CJK Ideograph>) 14719 0x879D 螝 (<CJK Ideograph>) 14720 0x879E 螞 (<CJK Ideograph>) 14721 0x87A0 螠 (<CJK Ideograph>) 14722 0x87A1 螡 (<CJK Ideograph>) 14723 0x87A2 螢 (<CJK Ideograph>) 14724 0x87A3 螣 (<CJK Ideograph>) 14725 0x87A4 螤 (<CJK Ideograph>) 14726 0x5DCD 巍 (<CJK Ideograph>) 14727 0x5FAE 微 (<CJK Ideograph>) 14728 0x5371 危 (<CJK Ideograph>) 14729 0x97E6 韦 (<CJK Ideograph>) 14730 0x8FDD 违 (<CJK Ideograph>) 14731 0x6845 桅 (<CJK Ideograph>) 14732 0x56F4 围 (<CJK Ideograph>) 14733 0x552F 唯 (<CJK Ideograph>) 14734 0x60DF 惟 (<CJK Ideograph>) 14735 0x4E3A 为 (<CJK Ideograph>) 14736 0x6F4D 潍 (<CJK Ideograph>) 14737 0x7EF4 维 (<CJK Ideograph>) 14738 0x82C7 苇 (<CJK Ideograph>) 14739 0x840E 萎 (<CJK Ideograph>) 14740 0x59D4 委 (<CJK Ideograph>) 14741 0x4F1F 伟 (<CJK Ideograph>) 14742 0x4F2A 伪 (<CJK Ideograph>) 14743 0x5C3E 尾 (<CJK Ideograph>) 14744 0x7EAC 纬 (<CJK Ideograph>) 14745 0x672A 未 (<CJK Ideograph>) 14746 0x851A 蔚 (<CJK Ideograph>) 14747 0x5473 味 (<CJK Ideograph>) 14748 0x754F 畏 (<CJK Ideograph>) 14749 0x80C3 胃 (<CJK Ideograph>) 14750 0x5582 喂 (<CJK Ideograph>) 14751 0x9B4F 魏 (<CJK Ideograph>) 14752 0x4F4D 位 (<CJK Ideograph>) 14753 0x6E2D 渭 (<CJK Ideograph>) 14754 0x8C13 谓 (<CJK Ideograph>) 14755 0x5C09 尉 (<CJK Ideograph>) 14756 0x6170 慰 (<CJK Ideograph>) 14757 0x536B 卫 (<CJK Ideograph>) 14758 0x761F 瘟 (<CJK Ideograph>) 14759 0x6E29 温 (<CJK Ideograph>) 14760 0x868A 蚊 (<CJK Ideograph>) 14761 0x6587 文 (<CJK Ideograph>) 14762 0x95FB 闻 (<CJK Ideograph>) 14763 0x7EB9 纹 (<CJK Ideograph>) 14764 0x543B 吻 (<CJK Ideograph>) 14765 0x7A33 稳 (<CJK Ideograph>) 14766 0x7D0A 紊 (<CJK Ideograph>) 14767 0x95EE 问 (<CJK Ideograph>) 14768 0x55E1 嗡 (<CJK Ideograph>) 14769 0x7FC1 翁 (<CJK Ideograph>) 14770 0x74EE 瓮 (<CJK Ideograph>) 14771 0x631D 挝 (<CJK Ideograph>) 14772 0x8717 蜗 (<CJK Ideograph>) 14773 0x6DA1 涡 (<CJK Ideograph>) 14774 0x7A9D 窝 (<CJK Ideograph>) 14775 0x6211 我 (<CJK Ideograph>) 14776 0x65A1 斡 (<CJK Ideograph>) 14777 0x5367 卧 (<CJK Ideograph>) 14778 0x63E1 握 (<CJK Ideograph>) 14779 0x6C83 沃 (<CJK Ideograph>) 14780 0x5DEB 巫 (<CJK Ideograph>) 14781 0x545C 呜 (<CJK Ideograph>) 14782 0x94A8 钨 (<CJK Ideograph>) 14783 0x4E4C 乌 (<CJK Ideograph>) 14784 0x6C61 污 (<CJK Ideograph>) 14785 0x8BEC 诬 (<CJK Ideograph>) 14786 0x5C4B 屋 (<CJK Ideograph>) 14787 0x65E0 无 (<CJK Ideograph>) 14788 0x829C 芜 (<CJK Ideograph>) 14789 0x68A7 梧 (<CJK Ideograph>) 14790 0x543E 吾 (<CJK Ideograph>) 14791 0x5434 吴 (<CJK Ideograph>) 14792 0x6BCB 毋 (<CJK Ideograph>) 14793 0x6B66 武 (<CJK Ideograph>) 14794 0x4E94 五 (<CJK Ideograph>) 14795 0x6342 捂 (<CJK Ideograph>) 14796 0x5348 午 (<CJK Ideograph>) 14797 0x821E 舞 (<CJK Ideograph>) 14798 0x4F0D 伍 (<CJK Ideograph>) 14799 0x4FAE 侮 (<CJK Ideograph>) 14800 0x575E 坞 (<CJK Ideograph>) 14801 0x620A 戊 (<CJK Ideograph>) 14802 0x96FE 雾 (<CJK Ideograph>) 14803 0x6664 晤 (<CJK Ideograph>) 14804 0x7269 物 (<CJK Ideograph>) 14805 0x52FF 勿 (<CJK Ideograph>) 14806 0x52A1 务 (<CJK Ideograph>) 14807 0x609F 悟 (<CJK Ideograph>) 14808 0x8BEF 误 (<CJK Ideograph>) 14809 0x6614 昔 (<CJK Ideograph>) 14810 0x7199 熙 (<CJK Ideograph>) 14811 0x6790 析 (<CJK Ideograph>) 14812 0x897F 西 (<CJK Ideograph>) 14813 0x7852 硒 (<CJK Ideograph>) 14814 0x77FD 矽 (<CJK Ideograph>) 14815 0x6670 晰 (<CJK Ideograph>) 14816 0x563B 嘻 (<CJK Ideograph>) 14817 0x5438 吸 (<CJK Ideograph>) 14818 0x9521 锡 (<CJK Ideograph>) 14819 0x727A 牺 (<CJK Ideograph>) 14820 0x87A5 螥 (<CJK Ideograph>) 14821 0x87A6 螦 (<CJK Ideograph>) 14822 0x87A7 螧 (<CJK Ideograph>) 14823 0x87A9 螩 (<CJK Ideograph>) 14824 0x87AA 螪 (<CJK Ideograph>) 14825 0x87AE 螮 (<CJK Ideograph>) 14826 0x87B0 螰 (<CJK Ideograph>) 14827 0x87B1 螱 (<CJK Ideograph>) 14828 0x87B2 螲 (<CJK Ideograph>) 14829 0x87B4 螴 (<CJK Ideograph>) 14830 0x87B6 螶 (<CJK Ideograph>) 14831 0x87B7 螷 (<CJK Ideograph>) 14832 0x87B8 螸 (<CJK Ideograph>) 14833 0x87B9 螹 (<CJK Ideograph>) 14834 0x87BB 螻 (<CJK Ideograph>) 14835 0x87BC 螼 (<CJK Ideograph>) 14836 0x87BE 螾 (<CJK Ideograph>) 14837 0x87BF 螿 (<CJK Ideograph>) 14838 0x87C1 蟁 (<CJK Ideograph>) 14839 0x87C2 蟂 (<CJK Ideograph>) 14840 0x87C3 蟃 (<CJK Ideograph>) 14841 0x87C4 蟄 (<CJK Ideograph>) 14842 0x87C5 蟅 (<CJK Ideograph>) 14843 0x87C7 蟇 (<CJK Ideograph>) 14844 0x87C8 蟈 (<CJK Ideograph>) 14845 0x87C9 蟉 (<CJK Ideograph>) 14846 0x87CC 蟌 (<CJK Ideograph>) 14847 0x87CD 蟍 (<CJK Ideograph>) 14848 0x87CE 蟎 (<CJK Ideograph>) 14849 0x87CF 蟏 (<CJK Ideograph>) 14850 0x87D0 蟐 (<CJK Ideograph>) 14851 0x87D4 蟔 (<CJK Ideograph>) 14852 0x87D5 蟕 (<CJK Ideograph>) 14853 0x87D6 蟖 (<CJK Ideograph>) 14854 0x87D7 蟗 (<CJK Ideograph>) 14855 0x87D8 蟘 (<CJK Ideograph>) 14856 0x87D9 蟙 (<CJK Ideograph>) 14857 0x87DA 蟚 (<CJK Ideograph>) 14858 0x87DC 蟜 (<CJK Ideograph>) 14859 0x87DD 蟝 (<CJK Ideograph>) 14860 0x87DE 蟞 (<CJK Ideograph>) 14861 0x87DF 蟟 (<CJK Ideograph>) 14862 0x87E1 蟡 (<CJK Ideograph>) 14863 0x87E2 蟢 (<CJK Ideograph>) 14864 0x87E3 蟣 (<CJK Ideograph>) 14865 0x87E4 蟤 (<CJK Ideograph>) 14866 0x87E6 蟦 (<CJK Ideograph>) 14867 0x87E7 蟧 (<CJK Ideograph>) 14868 0x87E8 蟨 (<CJK Ideograph>) 14869 0x87E9 蟩 (<CJK Ideograph>) 14870 0x87EB 蟫 (<CJK Ideograph>) 14871 0x87EC 蟬 (<CJK Ideograph>) 14872 0x87ED 蟭 (<CJK Ideograph>) 14873 0x87EF 蟯 (<CJK Ideograph>) 14874 0x87F0 蟰 (<CJK Ideograph>) 14875 0x87F1 蟱 (<CJK Ideograph>) 14876 0x87F2 蟲 (<CJK Ideograph>) 14877 0x87F3 蟳 (<CJK Ideograph>) 14878 0x87F4 蟴 (<CJK Ideograph>) 14879 0x87F5 蟵 (<CJK Ideograph>) 14880 0x87F6 蟶 (<CJK Ideograph>) 14881 0x87F7 蟷 (<CJK Ideograph>) 14882 0x87F8 蟸 (<CJK Ideograph>) 14883 0x87FA 蟺 (<CJK Ideograph>) 14884 0x87FB 蟻 (<CJK Ideograph>) 14885 0x87FC 蟼 (<CJK Ideograph>) 14886 0x87FD 蟽 (<CJK Ideograph>) 14887 0x87FF 蟿 (<CJK Ideograph>) 14888 0x8800 蠀 (<CJK Ideograph>) 14889 0x8801 蠁 (<CJK Ideograph>) 14890 0x8802 蠂 (<CJK Ideograph>) 14891 0x8804 蠄 (<CJK Ideograph>) 14892 0x8805 蠅 (<CJK Ideograph>) 14893 0x8806 蠆 (<CJK Ideograph>) 14894 0x8807 蠇 (<CJK Ideograph>) 14895 0x8808 蠈 (<CJK Ideograph>) 14896 0x8809 蠉 (<CJK Ideograph>) 14897 0x880B 蠋 (<CJK Ideograph>) 14898 0x880C 蠌 (<CJK Ideograph>) 14899 0x880D 蠍 (<CJK Ideograph>) 14900 0x880E 蠎 (<CJK Ideograph>) 14901 0x880F 蠏 (<CJK Ideograph>) 14902 0x8810 蠐 (<CJK Ideograph>) 14903 0x8811 蠑 (<CJK Ideograph>) 14904 0x8812 蠒 (<CJK Ideograph>) 14905 0x8814 蠔 (<CJK Ideograph>) 14906 0x8817 蠗 (<CJK Ideograph>) 14907 0x8818 蠘 (<CJK Ideograph>) 14908 0x8819 蠙 (<CJK Ideograph>) 14909 0x881A 蠚 (<CJK Ideograph>) 14910 0x881C 蠜 (<CJK Ideograph>) 14911 0x881D 蠝 (<CJK Ideograph>) 14912 0x881E 蠞 (<CJK Ideograph>) 14913 0x881F 蠟 (<CJK Ideograph>) 14914 0x8820 蠠 (<CJK Ideograph>) 14915 0x8823 蠣 (<CJK Ideograph>) 14916 0x7A00 稀 (<CJK Ideograph>) 14917 0x606F 息 (<CJK Ideograph>) 14918 0x5E0C 希 (<CJK Ideograph>) 14919 0x6089 悉 (<CJK Ideograph>) 14920 0x819D 膝 (<CJK Ideograph>) 14921 0x5915 夕 (<CJK Ideograph>) 14922 0x60DC 惜 (<CJK Ideograph>) 14923 0x7184 熄 (<CJK Ideograph>) 14924 0x70EF 烯 (<CJK Ideograph>) 14925 0x6EAA 溪 (<CJK Ideograph>) 14926 0x6C50 汐 (<CJK Ideograph>) 14927 0x7280 犀 (<CJK Ideograph>) 14928 0x6A84 檄 (<CJK Ideograph>) 14929 0x88AD 袭 (<CJK Ideograph>) 14930 0x5E2D 席 (<CJK Ideograph>) 14931 0x4E60 习 (<CJK Ideograph>) 14932 0x5AB3 媳 (<CJK Ideograph>) 14933 0x559C 喜 (<CJK Ideograph>) 14934 0x94E3 铣 (<CJK Ideograph>) 14935 0x6D17 洗 (<CJK Ideograph>) 14936 0x7CFB 系 (<CJK Ideograph>) 14937 0x9699 隙 (<CJK Ideograph>) 14938 0x620F 戏 (<CJK Ideograph>) 14939 0x7EC6 细 (<CJK Ideograph>) 14940 0x778E 瞎 (<CJK Ideograph>) 14941 0x867E 虾 (<CJK Ideograph>) 14942 0x5323 匣 (<CJK Ideograph>) 14943 0x971E 霞 (<CJK Ideograph>) 14944 0x8F96 辖 (<CJK Ideograph>) 14945 0x6687 暇 (<CJK Ideograph>) 14946 0x5CE1 峡 (<CJK Ideograph>) 14947 0x4FA0 侠 (<CJK Ideograph>) 14948 0x72ED 狭 (<CJK Ideograph>) 14949 0x4E0B 下 (<CJK Ideograph>) 14950 0x53A6 厦 (<CJK Ideograph>) 14951 0x590F 夏 (<CJK Ideograph>) 14952 0x5413 吓 (<CJK Ideograph>) 14953 0x6380 掀 (<CJK Ideograph>) 14954 0x9528 锨 (<CJK Ideograph>) 14955 0x5148 先 (<CJK Ideograph>) 14956 0x4ED9 仙 (<CJK Ideograph>) 14957 0x9C9C 鲜 (<CJK Ideograph>) 14958 0x7EA4 纤 (<CJK Ideograph>) 14959 0x54B8 咸 (<CJK Ideograph>) 14960 0x8D24 贤 (<CJK Ideograph>) 14961 0x8854 衔 (<CJK Ideograph>) 14962 0x8237 舷 (<CJK Ideograph>) 14963 0x95F2 闲 (<CJK Ideograph>) 14964 0x6D8E 涎 (<CJK Ideograph>) 14965 0x5F26 弦 (<CJK Ideograph>) 14966 0x5ACC 嫌 (<CJK Ideograph>) 14967 0x663E 显 (<CJK Ideograph>) 14968 0x9669 险 (<CJK Ideograph>) 14969 0x73B0 现 (<CJK Ideograph>) 14970 0x732E 献 (<CJK Ideograph>) 14971 0x53BF 县 (<CJK Ideograph>) 14972 0x817A 腺 (<CJK Ideograph>) 14973 0x9985 馅 (<CJK Ideograph>) 14974 0x7FA1 羡 (<CJK Ideograph>) 14975 0x5BAA 宪 (<CJK Ideograph>) 14976 0x9677 陷 (<CJK Ideograph>) 14977 0x9650 限 (<CJK Ideograph>) 14978 0x7EBF 线 (<CJK Ideograph>) 14979 0x76F8 相 (<CJK Ideograph>) 14980 0x53A2 厢 (<CJK Ideograph>) 14981 0x9576 镶 (<CJK Ideograph>) 14982 0x9999 香 (<CJK Ideograph>) 14983 0x7BB1 箱 (<CJK Ideograph>) 14984 0x8944 襄 (<CJK Ideograph>) 14985 0x6E58 湘 (<CJK Ideograph>) 14986 0x4E61 乡 (<CJK Ideograph>) 14987 0x7FD4 翔 (<CJK Ideograph>) 14988 0x7965 祥 (<CJK Ideograph>) 14989 0x8BE6 详 (<CJK Ideograph>) 14990 0x60F3 想 (<CJK Ideograph>) 14991 0x54CD 响 (<CJK Ideograph>) 14992 0x4EAB 享 (<CJK Ideograph>) 14993 0x9879 项 (<CJK Ideograph>) 14994 0x5DF7 巷 (<CJK Ideograph>) 14995 0x6A61 橡 (<CJK Ideograph>) 14996 0x50CF 像 (<CJK Ideograph>) 14997 0x5411 向 (<CJK Ideograph>) 14998 0x8C61 象 (<CJK Ideograph>) 14999 0x8427 萧 (<CJK Ideograph>) 15000 0x785D 硝 (<CJK Ideograph>) 15001 0x9704 霄 (<CJK Ideograph>) 15002 0x524A 削 (<CJK Ideograph>) 15003 0x54EE 哮 (<CJK Ideograph>) 15004 0x56A3 嚣 (<CJK Ideograph>) 15005 0x9500 销 (<CJK Ideograph>) 15006 0x6D88 消 (<CJK Ideograph>) 15007 0x5BB5 宵 (<CJK Ideograph>) 15008 0x6DC6 淆 (<CJK Ideograph>) 15009 0x6653 晓 (<CJK Ideograph>) 15010 0x8824 蠤 (<CJK Ideograph>) 15011 0x8825 蠥 (<CJK Ideograph>) 15012 0x8826 蠦 (<CJK Ideograph>) 15013 0x8827 蠧 (<CJK Ideograph>) 15014 0x8828 蠨 (<CJK Ideograph>) 15015 0x8829 蠩 (<CJK Ideograph>) 15016 0x882A 蠪 (<CJK Ideograph>) 15017 0x882B 蠫 (<CJK Ideograph>) 15018 0x882C 蠬 (<CJK Ideograph>) 15019 0x882D 蠭 (<CJK Ideograph>) 15020 0x882E 蠮 (<CJK Ideograph>) 15021 0x882F 蠯 (<CJK Ideograph>) 15022 0x8830 蠰 (<CJK Ideograph>) 15023 0x8831 蠱 (<CJK Ideograph>) 15024 0x8833 蠳 (<CJK Ideograph>) 15025 0x8834 蠴 (<CJK Ideograph>) 15026 0x8835 蠵 (<CJK Ideograph>) 15027 0x8836 蠶 (<CJK Ideograph>) 15028 0x8837 蠷 (<CJK Ideograph>) 15029 0x8838 蠸 (<CJK Ideograph>) 15030 0x883A 蠺 (<CJK Ideograph>) 15031 0x883B 蠻 (<CJK Ideograph>) 15032 0x883D 蠽 (<CJK Ideograph>) 15033 0x883E 蠾 (<CJK Ideograph>) 15034 0x883F 蠿 (<CJK Ideograph>) 15035 0x8841 衁 (<CJK Ideograph>) 15036 0x8842 衂 (<CJK Ideograph>) 15037 0x8843 衃 (<CJK Ideograph>) 15038 0x8846 衆 (<CJK Ideograph>) 15039 0x8847 衇 (<CJK Ideograph>) 15040 0x8848 衈 (<CJK Ideograph>) 15041 0x8849 衉 (<CJK Ideograph>) 15042 0x884A 衊 (<CJK Ideograph>) 15043 0x884B 衋 (<CJK Ideograph>) 15044 0x884E 衎 (<CJK Ideograph>) 15045 0x884F 衏 (<CJK Ideograph>) 15046 0x8850 衐 (<CJK Ideograph>) 15047 0x8851 衑 (<CJK Ideograph>) 15048 0x8852 衒 (<CJK Ideograph>) 15049 0x8853 術 (<CJK Ideograph>) 15050 0x8855 衕 (<CJK Ideograph>) 15051 0x8856 衖 (<CJK Ideograph>) 15052 0x8858 衘 (<CJK Ideograph>) 15053 0x885A 衚 (<CJK Ideograph>) 15054 0x885B 衛 (<CJK Ideograph>) 15055 0x885C 衜 (<CJK Ideograph>) 15056 0x885D 衝 (<CJK Ideograph>) 15057 0x885E 衞 (<CJK Ideograph>) 15058 0x885F 衟 (<CJK Ideograph>) 15059 0x8860 衠 (<CJK Ideograph>) 15060 0x8866 衦 (<CJK Ideograph>) 15061 0x8867 衧 (<CJK Ideograph>) 15062 0x886A 衪 (<CJK Ideograph>) 15063 0x886D 衭 (<CJK Ideograph>) 15064 0x886F 衯 (<CJK Ideograph>) 15065 0x8871 衱 (<CJK Ideograph>) 15066 0x8873 衳 (<CJK Ideograph>) 15067 0x8874 衴 (<CJK Ideograph>) 15068 0x8875 衵 (<CJK Ideograph>) 15069 0x8876 衶 (<CJK Ideograph>) 15070 0x8878 衸 (<CJK Ideograph>) 15071 0x8879 衹 (<CJK Ideograph>) 15072 0x887A 衺 (<CJK Ideograph>) 15073 0x887B 衻 (<CJK Ideograph>) 15074 0x887C 衼 (<CJK Ideograph>) 15075 0x8880 袀 (<CJK Ideograph>) 15076 0x8883 袃 (<CJK Ideograph>) 15077 0x8886 袆 (<CJK Ideograph>) 15078 0x8887 袇 (<CJK Ideograph>) 15079 0x8889 袉 (<CJK Ideograph>) 15080 0x888A 袊 (<CJK Ideograph>) 15081 0x888C 袌 (<CJK Ideograph>) 15082 0x888E 袎 (<CJK Ideograph>) 15083 0x888F 袏 (<CJK Ideograph>) 15084 0x8890 袐 (<CJK Ideograph>) 15085 0x8891 袑 (<CJK Ideograph>) 15086 0x8893 袓 (<CJK Ideograph>) 15087 0x8894 袔 (<CJK Ideograph>) 15088 0x8895 袕 (<CJK Ideograph>) 15089 0x8897 袗 (<CJK Ideograph>) 15090 0x8898 袘 (<CJK Ideograph>) 15091 0x8899 袙 (<CJK Ideograph>) 15092 0x889A 袚 (<CJK Ideograph>) 15093 0x889B 袛 (<CJK Ideograph>) 15094 0x889D 袝 (<CJK Ideograph>) 15095 0x889E 袞 (<CJK Ideograph>) 15096 0x889F 袟 (<CJK Ideograph>) 15097 0x88A0 袠 (<CJK Ideograph>) 15098 0x88A1 袡 (<CJK Ideograph>) 15099 0x88A3 袣 (<CJK Ideograph>) 15100 0x88A5 袥 (<CJK Ideograph>) 15101 0x88A6 袦 (<CJK Ideograph>) 15102 0x88A7 袧 (<CJK Ideograph>) 15103 0x88A8 袨 (<CJK Ideograph>) 15104 0x88A9 袩 (<CJK Ideograph>) 15105 0x88AA 袪 (<CJK Ideograph>) 15106 0x5C0F 小 (<CJK Ideograph>) 15107 0x5B5D 孝 (<CJK Ideograph>) 15108 0x6821 校 (<CJK Ideograph>) 15109 0x8096 肖 (<CJK Ideograph>) 15110 0x5578 啸 (<CJK Ideograph>) 15111 0x7B11 笑 (<CJK Ideograph>) 15112 0x6548 效 (<CJK Ideograph>) 15113 0x6954 楔 (<CJK Ideograph>) 15114 0x4E9B 些 (<CJK Ideograph>) 15115 0x6B47 歇 (<CJK Ideograph>) 15116 0x874E 蝎 (<CJK Ideograph>) 15117 0x978B 鞋 (<CJK Ideograph>) 15118 0x534F 协 (<CJK Ideograph>) 15119 0x631F 挟 (<CJK Ideograph>) 15120 0x643A 携 (<CJK Ideograph>) 15121 0x90AA 邪 (<CJK Ideograph>) 15122 0x659C 斜 (<CJK Ideograph>) 15123 0x80C1 胁 (<CJK Ideograph>) 15124 0x8C10 谐 (<CJK Ideograph>) 15125 0x5199 写 (<CJK Ideograph>) 15126 0x68B0 械 (<CJK Ideograph>) 15127 0x5378 卸 (<CJK Ideograph>) 15128 0x87F9 蟹 (<CJK Ideograph>) 15129 0x61C8 懈 (<CJK Ideograph>) 15130 0x6CC4 泄 (<CJK Ideograph>) 15131 0x6CFB 泻 (<CJK Ideograph>) 15132 0x8C22 谢 (<CJK Ideograph>) 15133 0x5C51 屑 (<CJK Ideograph>) 15134 0x85AA 薪 (<CJK Ideograph>) 15135 0x82AF 芯 (<CJK Ideograph>) 15136 0x950C 锌 (<CJK Ideograph>) 15137 0x6B23 欣 (<CJK Ideograph>) 15138 0x8F9B 辛 (<CJK Ideograph>) 15139 0x65B0 新 (<CJK Ideograph>) 15140 0x5FFB 忻 (<CJK Ideograph>) 15141 0x5FC3 心 (<CJK Ideograph>) 15142 0x4FE1 信 (<CJK Ideograph>) 15143 0x8845 衅 (<CJK Ideograph>) 15144 0x661F 星 (<CJK Ideograph>) 15145 0x8165 腥 (<CJK Ideograph>) 15146 0x7329 猩 (<CJK Ideograph>) 15147 0x60FA 惺 (<CJK Ideograph>) 15148 0x5174 兴 (<CJK Ideograph>) 15149 0x5211 刑 (<CJK Ideograph>) 15150 0x578B 型 (<CJK Ideograph>) 15151 0x5F62 形 (<CJK Ideograph>) 15152 0x90A2 邢 (<CJK Ideograph>) 15153 0x884C 行 (<CJK Ideograph>) 15154 0x9192 醒 (<CJK Ideograph>) 15155 0x5E78 幸 (<CJK Ideograph>) 15156 0x674F 杏 (<CJK Ideograph>) 15157 0x6027 性 (<CJK Ideograph>) 15158 0x59D3 姓 (<CJK Ideograph>) 15159 0x5144 兄 (<CJK Ideograph>) 15160 0x51F6 凶 (<CJK Ideograph>) 15161 0x80F8 胸 (<CJK Ideograph>) 15162 0x5308 匈 (<CJK Ideograph>) 15163 0x6C79 汹 (<CJK Ideograph>) 15164 0x96C4 雄 (<CJK Ideograph>) 15165 0x718A 熊 (<CJK Ideograph>) 15166 0x4F11 休 (<CJK Ideograph>) 15167 0x4FEE 修 (<CJK Ideograph>) 15168 0x7F9E 羞 (<CJK Ideograph>) 15169 0x673D 朽 (<CJK Ideograph>) 15170 0x55C5 嗅 (<CJK Ideograph>) 15171 0x9508 锈 (<CJK Ideograph>) 15172 0x79C0 秀 (<CJK Ideograph>) 15173 0x8896 袖 (<CJK Ideograph>) 15174 0x7EE3 绣 (<CJK Ideograph>) 15175 0x589F 墟 (<CJK Ideograph>) 15176 0x620C 戌 (<CJK Ideograph>) 15177 0x9700 需 (<CJK Ideograph>) 15178 0x865A 虚 (<CJK Ideograph>) 15179 0x5618 嘘 (<CJK Ideograph>) 15180 0x987B 须 (<CJK Ideograph>) 15181 0x5F90 徐 (<CJK Ideograph>) 15182 0x8BB8 许 (<CJK Ideograph>) 15183 0x84C4 蓄 (<CJK Ideograph>) 15184 0x9157 酗 (<CJK Ideograph>) 15185 0x53D9 叙 (<CJK Ideograph>) 15186 0x65ED 旭 (<CJK Ideograph>) 15187 0x5E8F 序 (<CJK Ideograph>) 15188 0x755C 畜 (<CJK Ideograph>) 15189 0x6064 恤 (<CJK Ideograph>) 15190 0x7D6E 絮 (<CJK Ideograph>) 15191 0x5A7F 婿 (<CJK Ideograph>) 15192 0x7EEA 绪 (<CJK Ideograph>) 15193 0x7EED 续 (<CJK Ideograph>) 15194 0x8F69 轩 (<CJK Ideograph>) 15195 0x55A7 喧 (<CJK Ideograph>) 15196 0x5BA3 宣 (<CJK Ideograph>) 15197 0x60AC 悬 (<CJK Ideograph>) 15198 0x65CB 旋 (<CJK Ideograph>) 15199 0x7384 玄 (<CJK Ideograph>) 15200 0x88AC 袬 (<CJK Ideograph>) 15201 0x88AE 袮 (<CJK Ideograph>) 15202 0x88AF 袯 (<CJK Ideograph>) 15203 0x88B0 袰 (<CJK Ideograph>) 15204 0x88B2 袲 (<CJK Ideograph>) 15205 0x88B3 袳 (<CJK Ideograph>) 15206 0x88B4 袴 (<CJK Ideograph>) 15207 0x88B5 袵 (<CJK Ideograph>) 15208 0x88B6 袶 (<CJK Ideograph>) 15209 0x88B8 袸 (<CJK Ideograph>) 15210 0x88B9 袹 (<CJK Ideograph>) 15211 0x88BA 袺 (<CJK Ideograph>) 15212 0x88BB 袻 (<CJK Ideograph>) 15213 0x88BD 袽 (<CJK Ideograph>) 15214 0x88BE 袾 (<CJK Ideograph>) 15215 0x88BF 袿 (<CJK Ideograph>) 15216 0x88C0 裀 (<CJK Ideograph>) 15217 0x88C3 裃 (<CJK Ideograph>) 15218 0x88C4 裄 (<CJK Ideograph>) 15219 0x88C7 裇 (<CJK Ideograph>) 15220 0x88C8 裈 (<CJK Ideograph>) 15221 0x88CA 裊 (<CJK Ideograph>) 15222 0x88CB 裋 (<CJK Ideograph>) 15223 0x88CC 裌 (<CJK Ideograph>) 15224 0x88CD 裍 (<CJK Ideograph>) 15225 0x88CF 裏 (<CJK Ideograph>) 15226 0x88D0 裐 (<CJK Ideograph>) 15227 0x88D1 裑 (<CJK Ideograph>) 15228 0x88D3 裓 (<CJK Ideograph>) 15229 0x88D6 裖 (<CJK Ideograph>) 15230 0x88D7 裗 (<CJK Ideograph>) 15231 0x88DA 裚 (<CJK Ideograph>) 15232 0x88DB 裛 (<CJK Ideograph>) 15233 0x88DC 補 (<CJK Ideograph>) 15234 0x88DD 裝 (<CJK Ideograph>) 15235 0x88DE 裞 (<CJK Ideograph>) 15236 0x88E0 裠 (<CJK Ideograph>) 15237 0x88E1 裡 (<CJK Ideograph>) 15238 0x88E6 裦 (<CJK Ideograph>) 15239 0x88E7 裧 (<CJK Ideograph>) 15240 0x88E9 裩 (<CJK Ideograph>) 15241 0x88EA 裪 (<CJK Ideograph>) 15242 0x88EB 裫 (<CJK Ideograph>) 15243 0x88EC 裬 (<CJK Ideograph>) 15244 0x88ED 裭 (<CJK Ideograph>) 15245 0x88EE 裮 (<CJK Ideograph>) 15246 0x88EF 裯 (<CJK Ideograph>) 15247 0x88F2 裲 (<CJK Ideograph>) 15248 0x88F5 裵 (<CJK Ideograph>) 15249 0x88F6 裶 (<CJK Ideograph>) 15250 0x88F7 裷 (<CJK Ideograph>) 15251 0x88FA 裺 (<CJK Ideograph>) 15252 0x88FB 裻 (<CJK Ideograph>) 15253 0x88FD 製 (<CJK Ideograph>) 15254 0x88FF 裿 (<CJK Ideograph>) 15255 0x8900 褀 (<CJK Ideograph>) 15256 0x8901 褁 (<CJK Ideograph>) 15257 0x8903 褃 (<CJK Ideograph>) 15258 0x8904 褄 (<CJK Ideograph>) 15259 0x8905 褅 (<CJK Ideograph>) 15260 0x8906 褆 (<CJK Ideograph>) 15261 0x8907 複 (<CJK Ideograph>) 15262 0x8908 褈 (<CJK Ideograph>) 15263 0x8909 褉 (<CJK Ideograph>) 15264 0x890B 褋 (<CJK Ideograph>) 15265 0x890C 褌 (<CJK Ideograph>) 15266 0x890D 褍 (<CJK Ideograph>) 15267 0x890E 褎 (<CJK Ideograph>) 15268 0x890F 褏 (<CJK Ideograph>) 15269 0x8911 褑 (<CJK Ideograph>) 15270 0x8914 褔 (<CJK Ideograph>) 15271 0x8915 褕 (<CJK Ideograph>) 15272 0x8916 褖 (<CJK Ideograph>) 15273 0x8917 褗 (<CJK Ideograph>) 15274 0x8918 褘 (<CJK Ideograph>) 15275 0x891C 褜 (<CJK Ideograph>) 15276 0x891D 褝 (<CJK Ideograph>) 15277 0x891E 褞 (<CJK Ideograph>) 15278 0x891F 褟 (<CJK Ideograph>) 15279 0x8920 褠 (<CJK Ideograph>) 15280 0x8922 褢 (<CJK Ideograph>) 15281 0x8923 褣 (<CJK Ideograph>) 15282 0x8924 褤 (<CJK Ideograph>) 15283 0x8926 褦 (<CJK Ideograph>) 15284 0x8927 褧 (<CJK Ideograph>) 15285 0x8928 褨 (<CJK Ideograph>) 15286 0x8929 褩 (<CJK Ideograph>) 15287 0x892C 褬 (<CJK Ideograph>) 15288 0x892D 褭 (<CJK Ideograph>) 15289 0x892E 褮 (<CJK Ideograph>) 15290 0x892F 褯 (<CJK Ideograph>) 15291 0x8931 褱 (<CJK Ideograph>) 15292 0x8932 褲 (<CJK Ideograph>) 15293 0x8933 褳 (<CJK Ideograph>) 15294 0x8935 褵 (<CJK Ideograph>) 15295 0x8937 褷 (<CJK Ideograph>) 15296 0x9009 选 (<CJK Ideograph>) 15297 0x7663 癣 (<CJK Ideograph>) 15298 0x7729 眩 (<CJK Ideograph>) 15299 0x7EDA 绚 (<CJK Ideograph>) 15300 0x9774 靴 (<CJK Ideograph>) 15301 0x859B 薛 (<CJK Ideograph>) 15302 0x5B66 学 (<CJK Ideograph>) 15303 0x7A74 穴 (<CJK Ideograph>) 15304 0x96EA 雪 (<CJK Ideograph>) 15305 0x8840 血 (<CJK Ideograph>) 15306 0x52CB 勋 (<CJK Ideograph>) 15307 0x718F 熏 (<CJK Ideograph>) 15308 0x5FAA 循 (<CJK Ideograph>) 15309 0x65EC 旬 (<CJK Ideograph>) 15310 0x8BE2 询 (<CJK Ideograph>) 15311 0x5BFB 寻 (<CJK Ideograph>) 15312 0x9A6F 驯 (<CJK Ideograph>) 15313 0x5DE1 巡 (<CJK Ideograph>) 15314 0x6B89 殉 (<CJK Ideograph>) 15315 0x6C5B 汛 (<CJK Ideograph>) 15316 0x8BAD 训 (<CJK Ideograph>) 15317 0x8BAF 讯 (<CJK Ideograph>) 15318 0x900A 逊 (<CJK Ideograph>) 15319 0x8FC5 迅 (<CJK Ideograph>) 15320 0x538B 压 (<CJK Ideograph>) 15321 0x62BC 押 (<CJK Ideograph>) 15322 0x9E26 鸦 (<CJK Ideograph>) 15323 0x9E2D 鸭 (<CJK Ideograph>) 15324 0x5440 呀 (<CJK Ideograph>) 15325 0x4E2B 丫 (<CJK Ideograph>) 15326 0x82BD 芽 (<CJK Ideograph>) 15327 0x7259 牙 (<CJK Ideograph>) 15328 0x869C 蚜 (<CJK Ideograph>) 15329 0x5D16 崖 (<CJK Ideograph>) 15330 0x8859 衙 (<CJK Ideograph>) 15331 0x6DAF 涯 (<CJK Ideograph>) 15332 0x96C5 雅 (<CJK Ideograph>) 15333 0x54D1 哑 (<CJK Ideograph>) 15334 0x4E9A 亚 (<CJK Ideograph>) 15335 0x8BB6 讶 (<CJK Ideograph>) 15336 0x7109 焉 (<CJK Ideograph>) 15337 0x54BD 咽 (<CJK Ideograph>) 15338 0x9609 阉 (<CJK Ideograph>) 15339 0x70DF 烟 (<CJK Ideograph>) 15340 0x6DF9 淹 (<CJK Ideograph>) 15341 0x76D0 盐 (<CJK Ideograph>) 15342 0x4E25 严 (<CJK Ideograph>) 15343 0x7814 研 (<CJK Ideograph>) 15344 0x8712 蜒 (<CJK Ideograph>) 15345 0x5CA9 岩 (<CJK Ideograph>) 15346 0x5EF6 延 (<CJK Ideograph>) 15347 0x8A00 言 (<CJK Ideograph>) 15348 0x989C 颜 (<CJK Ideograph>) 15349 0x960E 阎 (<CJK Ideograph>) 15350 0x708E 炎 (<CJK Ideograph>) 15351 0x6CBF 沿 (<CJK Ideograph>) 15352 0x5944 奄 (<CJK Ideograph>) 15353 0x63A9 掩 (<CJK Ideograph>) 15354 0x773C 眼 (<CJK Ideograph>) 15355 0x884D 衍 (<CJK Ideograph>) 15356 0x6F14 演 (<CJK Ideograph>) 15357 0x8273 艳 (<CJK Ideograph>) 15358 0x5830 堰 (<CJK Ideograph>) 15359 0x71D5 燕 (<CJK Ideograph>) 15360 0x538C 厌 (<CJK Ideograph>) 15361 0x781A 砚 (<CJK Ideograph>) 15362 0x96C1 雁 (<CJK Ideograph>) 15363 0x5501 唁 (<CJK Ideograph>) 15364 0x5F66 彦 (<CJK Ideograph>) 15365 0x7130 焰 (<CJK Ideograph>) 15366 0x5BB4 宴 (<CJK Ideograph>) 15367 0x8C1A 谚 (<CJK Ideograph>) 15368 0x9A8C 验 (<CJK Ideograph>) 15369 0x6B83 殃 (<CJK Ideograph>) 15370 0x592E 央 (<CJK Ideograph>) 15371 0x9E2F 鸯 (<CJK Ideograph>) 15372 0x79E7 秧 (<CJK Ideograph>) 15373 0x6768 杨 (<CJK Ideograph>) 15374 0x626C 扬 (<CJK Ideograph>) 15375 0x4F6F 佯 (<CJK Ideograph>) 15376 0x75A1 疡 (<CJK Ideograph>) 15377 0x7F8A 羊 (<CJK Ideograph>) 15378 0x6D0B 洋 (<CJK Ideograph>) 15379 0x9633 阳 (<CJK Ideograph>) 15380 0x6C27 氧 (<CJK Ideograph>) 15381 0x4EF0 仰 (<CJK Ideograph>) 15382 0x75D2 痒 (<CJK Ideograph>) 15383 0x517B 养 (<CJK Ideograph>) 15384 0x6837 样 (<CJK Ideograph>) 15385 0x6F3E 漾 (<CJK Ideograph>) 15386 0x9080 邀 (<CJK Ideograph>) 15387 0x8170 腰 (<CJK Ideograph>) 15388 0x5996 妖 (<CJK Ideograph>) 15389 0x7476 瑶 (<CJK Ideograph>) 15390 0x8938 褸 (<CJK Ideograph>) 15391 0x8939 褹 (<CJK Ideograph>) 15392 0x893A 褺 (<CJK Ideograph>) 15393 0x893B 褻 (<CJK Ideograph>) 15394 0x893C 褼 (<CJK Ideograph>) 15395 0x893D 褽 (<CJK Ideograph>) 15396 0x893E 褾 (<CJK Ideograph>) 15397 0x893F 褿 (<CJK Ideograph>) 15398 0x8940 襀 (<CJK Ideograph>) 15399 0x8942 襂 (<CJK Ideograph>) 15400 0x8943 襃 (<CJK Ideograph>) 15401 0x8945 襅 (<CJK Ideograph>) 15402 0x8946 襆 (<CJK Ideograph>) 15403 0x8947 襇 (<CJK Ideograph>) 15404 0x8948 襈 (<CJK Ideograph>) 15405 0x8949 襉 (<CJK Ideograph>) 15406 0x894A 襊 (<CJK Ideograph>) 15407 0x894B 襋 (<CJK Ideograph>) 15408 0x894C 襌 (<CJK Ideograph>) 15409 0x894D 襍 (<CJK Ideograph>) 15410 0x894E 襎 (<CJK Ideograph>) 15411 0x894F 襏 (<CJK Ideograph>) 15412 0x8950 襐 (<CJK Ideograph>) 15413 0x8951 襑 (<CJK Ideograph>) 15414 0x8952 襒 (<CJK Ideograph>) 15415 0x8953 襓 (<CJK Ideograph>) 15416 0x8954 襔 (<CJK Ideograph>) 15417 0x8955 襕 (<CJK Ideograph>) 15418 0x8956 襖 (<CJK Ideograph>) 15419 0x8957 襗 (<CJK Ideograph>) 15420 0x8958 襘 (<CJK Ideograph>) 15421 0x8959 襙 (<CJK Ideograph>) 15422 0x895A 襚 (<CJK Ideograph>) 15423 0x895B 襛 (<CJK Ideograph>) 15424 0x895C 襜 (<CJK Ideograph>) 15425 0x895D 襝 (<CJK Ideograph>) 15426 0x8960 襠 (<CJK Ideograph>) 15427 0x8961 襡 (<CJK Ideograph>) 15428 0x8962 襢 (<CJK Ideograph>) 15429 0x8963 襣 (<CJK Ideograph>) 15430 0x8964 襤 (<CJK Ideograph>) 15431 0x8965 襥 (<CJK Ideograph>) 15432 0x8967 襧 (<CJK Ideograph>) 15433 0x8968 襨 (<CJK Ideograph>) 15434 0x8969 襩 (<CJK Ideograph>) 15435 0x896A 襪 (<CJK Ideograph>) 15436 0x896B 襫 (<CJK Ideograph>) 15437 0x896C 襬 (<CJK Ideograph>) 15438 0x896D 襭 (<CJK Ideograph>) 15439 0x896E 襮 (<CJK Ideograph>) 15440 0x896F 襯 (<CJK Ideograph>) 15441 0x8970 襰 (<CJK Ideograph>) 15442 0x8971 襱 (<CJK Ideograph>) 15443 0x8972 襲 (<CJK Ideograph>) 15444 0x8973 襳 (<CJK Ideograph>) 15445 0x8974 襴 (<CJK Ideograph>) 15446 0x8975 襵 (<CJK Ideograph>) 15447 0x8976 襶 (<CJK Ideograph>) 15448 0x8977 襷 (<CJK Ideograph>) 15449 0x8978 襸 (<CJK Ideograph>) 15450 0x8979 襹 (<CJK Ideograph>) 15451 0x897A 襺 (<CJK Ideograph>) 15452 0x897C 襼 (<CJK Ideograph>) 15453 0x897D 襽 (<CJK Ideograph>) 15454 0x897E 襾 (<CJK Ideograph>) 15455 0x8980 覀 (<CJK Ideograph>) 15456 0x8982 覂 (<CJK Ideograph>) 15457 0x8984 覄 (<CJK Ideograph>) 15458 0x8985 覅 (<CJK Ideograph>) 15459 0x8987 覇 (<CJK Ideograph>) 15460 0x8988 覈 (<CJK Ideograph>) 15461 0x8989 覉 (<CJK Ideograph>) 15462 0x898A 覊 (<CJK Ideograph>) 15463 0x898B 見 (<CJK Ideograph>) 15464 0x898C 覌 (<CJK Ideograph>) 15465 0x898D 覍 (<CJK Ideograph>) 15466 0x898E 覎 (<CJK Ideograph>) 15467 0x898F 規 (<CJK Ideograph>) 15468 0x8990 覐 (<CJK Ideograph>) 15469 0x8991 覑 (<CJK Ideograph>) 15470 0x8992 覒 (<CJK Ideograph>) 15471 0x8993 覓 (<CJK Ideograph>) 15472 0x8994 覔 (<CJK Ideograph>) 15473 0x8995 覕 (<CJK Ideograph>) 15474 0x8996 視 (<CJK Ideograph>) 15475 0x8997 覗 (<CJK Ideograph>) 15476 0x8998 覘 (<CJK Ideograph>) 15477 0x8999 覙 (<CJK Ideograph>) 15478 0x899A 覚 (<CJK Ideograph>) 15479 0x899B 覛 (<CJK Ideograph>) 15480 0x899C 覜 (<CJK Ideograph>) 15481 0x899D 覝 (<CJK Ideograph>) 15482 0x899E 覞 (<CJK Ideograph>) 15483 0x899F 覟 (<CJK Ideograph>) 15484 0x89A0 覠 (<CJK Ideograph>) 15485 0x89A1 覡 (<CJK Ideograph>) 15486 0x6447 摇 (<CJK Ideograph>) 15487 0x5C27 尧 (<CJK Ideograph>) 15488 0x9065 遥 (<CJK Ideograph>) 15489 0x7A91 窑 (<CJK Ideograph>) 15490 0x8C23 谣 (<CJK Ideograph>) 15491 0x59DA 姚 (<CJK Ideograph>) 15492 0x54AC 咬 (<CJK Ideograph>) 15493 0x8200 舀 (<CJK Ideograph>) 15494 0x836F 药 (<CJK Ideograph>) 15495 0x8981 要 (<CJK Ideograph>) 15496 0x8000 耀 (<CJK Ideograph>) 15497 0x6930 椰 (<CJK Ideograph>) 15498 0x564E 噎 (<CJK Ideograph>) 15499 0x8036 耶 (<CJK Ideograph>) 15500 0x7237 爷 (<CJK Ideograph>) 15501 0x91CE 野 (<CJK Ideograph>) 15502 0x51B6 冶 (<CJK Ideograph>) 15503 0x4E5F 也 (<CJK Ideograph>) 15504 0x9875 页 (<CJK Ideograph>) 15505 0x6396 掖 (<CJK Ideograph>) 15506 0x4E1A 业 (<CJK Ideograph>) 15507 0x53F6 叶 (<CJK Ideograph>) 15508 0x66F3 曳 (<CJK Ideograph>) 15509 0x814B 腋 (<CJK Ideograph>) 15510 0x591C 夜 (<CJK Ideograph>) 15511 0x6DB2 液 (<CJK Ideograph>) 15512 0x4E00 一 (<CJK Ideograph>) 15513 0x58F9 壹 (<CJK Ideograph>) 15514 0x533B 医 (<CJK Ideograph>) 15515 0x63D6 揖 (<CJK Ideograph>) 15516 0x94F1 铱 (<CJK Ideograph>) 15517 0x4F9D 依 (<CJK Ideograph>) 15518 0x4F0A 伊 (<CJK Ideograph>) 15519 0x8863 衣 (<CJK Ideograph>) 15520 0x9890 颐 (<CJK Ideograph>) 15521 0x5937 夷 (<CJK Ideograph>) 15522 0x9057 遗 (<CJK Ideograph>) 15523 0x79FB 移 (<CJK Ideograph>) 15524 0x4EEA 仪 (<CJK Ideograph>) 15525 0x80F0 胰 (<CJK Ideograph>) 15526 0x7591 疑 (<CJK Ideograph>) 15527 0x6C82 沂 (<CJK Ideograph>) 15528 0x5B9C 宜 (<CJK Ideograph>) 15529 0x59E8 姨 (<CJK Ideograph>) 15530 0x5F5D 彝 (<CJK Ideograph>) 15531 0x6905 椅 (<CJK Ideograph>) 15532 0x8681 蚁 (<CJK Ideograph>) 15533 0x501A 倚 (<CJK Ideograph>) 15534 0x5DF2 已 (<CJK Ideograph>) 15535 0x4E59 乙 (<CJK Ideograph>) 15536 0x77E3 矣 (<CJK Ideograph>) 15537 0x4EE5 以 (<CJK Ideograph>) 15538 0x827A 艺 (<CJK Ideograph>) 15539 0x6291 抑 (<CJK Ideograph>) 15540 0x6613 易 (<CJK Ideograph>) 15541 0x9091 邑 (<CJK Ideograph>) 15542 0x5C79 屹 (<CJK Ideograph>) 15543 0x4EBF 亿 (<CJK Ideograph>) 15544 0x5F79 役 (<CJK Ideograph>) 15545 0x81C6 臆 (<CJK Ideograph>) 15546 0x9038 逸 (<CJK Ideograph>) 15547 0x8084 肄 (<CJK Ideograph>) 15548 0x75AB 疫 (<CJK Ideograph>) 15549 0x4EA6 亦 (<CJK Ideograph>) 15550 0x88D4 裔 (<CJK Ideograph>) 15551 0x610F 意 (<CJK Ideograph>) 15552 0x6BC5 毅 (<CJK Ideograph>) 15553 0x5FC6 忆 (<CJK Ideograph>) 15554 0x4E49 义 (<CJK Ideograph>) 15555 0x76CA 益 (<CJK Ideograph>) 15556 0x6EA2 溢 (<CJK Ideograph>) 15557 0x8BE3 诣 (<CJK Ideograph>) 15558 0x8BAE 议 (<CJK Ideograph>) 15559 0x8C0A 谊 (<CJK Ideograph>) 15560 0x8BD1 译 (<CJK Ideograph>) 15561 0x5F02 异 (<CJK Ideograph>) 15562 0x7FFC 翼 (<CJK Ideograph>) 15563 0x7FCC 翌 (<CJK Ideograph>) 15564 0x7ECE 绎 (<CJK Ideograph>) 15565 0x8335 茵 (<CJK Ideograph>) 15566 0x836B 荫 (<CJK Ideograph>) 15567 0x56E0 因 (<CJK Ideograph>) 15568 0x6BB7 殷 (<CJK Ideograph>) 15569 0x97F3 音 (<CJK Ideograph>) 15570 0x9634 阴 (<CJK Ideograph>) 15571 0x59FB 姻 (<CJK Ideograph>) 15572 0x541F 吟 (<CJK Ideograph>) 15573 0x94F6 银 (<CJK Ideograph>) 15574 0x6DEB 淫 (<CJK Ideograph>) 15575 0x5BC5 寅 (<CJK Ideograph>) 15576 0x996E 饮 (<CJK Ideograph>) 15577 0x5C39 尹 (<CJK Ideograph>) 15578 0x5F15 引 (<CJK Ideograph>) 15579 0x9690 隐 (<CJK Ideograph>) 15580 0x89A2 覢 (<CJK Ideograph>) 15581 0x89A3 覣 (<CJK Ideograph>) 15582 0x89A4 覤 (<CJK Ideograph>) 15583 0x89A5 覥 (<CJK Ideograph>) 15584 0x89A6 覦 (<CJK Ideograph>) 15585 0x89A7 覧 (<CJK Ideograph>) 15586 0x89A8 覨 (<CJK Ideograph>) 15587 0x89A9 覩 (<CJK Ideograph>) 15588 0x89AA 親 (<CJK Ideograph>) 15589 0x89AB 覫 (<CJK Ideograph>) 15590 0x89AC 覬 (<CJK Ideograph>) 15591 0x89AD 覭 (<CJK Ideograph>) 15592 0x89AE 覮 (<CJK Ideograph>) 15593 0x89AF 覯 (<CJK Ideograph>) 15594 0x89B0 覰 (<CJK Ideograph>) 15595 0x89B1 覱 (<CJK Ideograph>) 15596 0x89B2 覲 (<CJK Ideograph>) 15597 0x89B3 観 (<CJK Ideograph>) 15598 0x89B4 覴 (<CJK Ideograph>) 15599 0x89B5 覵 (<CJK Ideograph>) 15600 0x89B6 覶 (<CJK Ideograph>) 15601 0x89B7 覷 (<CJK Ideograph>) 15602 0x89B8 覸 (<CJK Ideograph>) 15603 0x89B9 覹 (<CJK Ideograph>) 15604 0x89BA 覺 (<CJK Ideograph>) 15605 0x89BB 覻 (<CJK Ideograph>) 15606 0x89BC 覼 (<CJK Ideograph>) 15607 0x89BD 覽 (<CJK Ideograph>) 15608 0x89BE 覾 (<CJK Ideograph>) 15609 0x89BF 覿 (<CJK Ideograph>) 15610 0x89C0 觀 (<CJK Ideograph>) 15611 0x89C3 觃 (<CJK Ideograph>) 15612 0x89CD 觍 (<CJK Ideograph>) 15613 0x89D3 觓 (<CJK Ideograph>) 15614 0x89D4 觔 (<CJK Ideograph>) 15615 0x89D5 觕 (<CJK Ideograph>) 15616 0x89D7 觗 (<CJK Ideograph>) 15617 0x89D8 觘 (<CJK Ideograph>) 15618 0x89D9 觙 (<CJK Ideograph>) 15619 0x89DB 觛 (<CJK Ideograph>) 15620 0x89DD 觝 (<CJK Ideograph>) 15621 0x89DF 觟 (<CJK Ideograph>) 15622 0x89E0 觠 (<CJK Ideograph>) 15623 0x89E1 觡 (<CJK Ideograph>) 15624 0x89E2 觢 (<CJK Ideograph>) 15625 0x89E4 觤 (<CJK Ideograph>) 15626 0x89E7 觧 (<CJK Ideograph>) 15627 0x89E8 觨 (<CJK Ideograph>) 15628 0x89E9 觩 (<CJK Ideograph>) 15629 0x89EA 觪 (<CJK Ideograph>) 15630 0x89EC 觬 (<CJK Ideograph>) 15631 0x89ED 觭 (<CJK Ideograph>) 15632 0x89EE 觮 (<CJK Ideograph>) 15633 0x89F0 觰 (<CJK Ideograph>) 15634 0x89F1 觱 (<CJK Ideograph>) 15635 0x89F2 觲 (<CJK Ideograph>) 15636 0x89F4 觴 (<CJK Ideograph>) 15637 0x89F5 觵 (<CJK Ideograph>) 15638 0x89F6 觶 (<CJK Ideograph>) 15639 0x89F7 觷 (<CJK Ideograph>) 15640 0x89F8 觸 (<CJK Ideograph>) 15641 0x89F9 觹 (<CJK Ideograph>) 15642 0x89FA 觺 (<CJK Ideograph>) 15643 0x89FB 觻 (<CJK Ideograph>) 15644 0x89FC 觼 (<CJK Ideograph>) 15645 0x89FD 觽 (<CJK Ideograph>) 15646 0x89FE 觾 (<CJK Ideograph>) 15647 0x89FF 觿 (<CJK Ideograph>) 15648 0x8A01 訁 (<CJK Ideograph>) 15649 0x8A02 訂 (<CJK Ideograph>) 15650 0x8A03 訃 (<CJK Ideograph>) 15651 0x8A04 訄 (<CJK Ideograph>) 15652 0x8A05 訅 (<CJK Ideograph>) 15653 0x8A06 訆 (<CJK Ideograph>) 15654 0x8A08 計 (<CJK Ideograph>) 15655 0x8A09 訉 (<CJK Ideograph>) 15656 0x8A0A 訊 (<CJK Ideograph>) 15657 0x8A0B 訋 (<CJK Ideograph>) 15658 0x8A0C 訌 (<CJK Ideograph>) 15659 0x8A0D 訍 (<CJK Ideograph>) 15660 0x8A0E 討 (<CJK Ideograph>) 15661 0x8A0F 訏 (<CJK Ideograph>) 15662 0x8A10 訐 (<CJK Ideograph>) 15663 0x8A11 訑 (<CJK Ideograph>) 15664 0x8A12 訒 (<CJK Ideograph>) 15665 0x8A13 訓 (<CJK Ideograph>) 15666 0x8A14 訔 (<CJK Ideograph>) 15667 0x8A15 訕 (<CJK Ideograph>) 15668 0x8A16 訖 (<CJK Ideograph>) 15669 0x8A17 託 (<CJK Ideograph>) 15670 0x8A18 記 (<CJK Ideograph>) 15671 0x8A19 訙 (<CJK Ideograph>) 15672 0x8A1A 訚 (<CJK Ideograph>) 15673 0x8A1B 訛 (<CJK Ideograph>) 15674 0x8A1C 訜 (<CJK Ideograph>) 15675 0x8A1D 訝 (<CJK Ideograph>) 15676 0x5370 印 (<CJK Ideograph>) 15677 0x82F1 英 (<CJK Ideograph>) 15678 0x6A31 樱 (<CJK Ideograph>) 15679 0x5A74 婴 (<CJK Ideograph>) 15680 0x9E70 鹰 (<CJK Ideograph>) 15681 0x5E94 应 (<CJK Ideograph>) 15682 0x7F28 缨 (<CJK Ideograph>) 15683 0x83B9 莹 (<CJK Ideograph>) 15684 0x8424 萤 (<CJK Ideograph>) 15685 0x8425 营 (<CJK Ideograph>) 15686 0x8367 荧 (<CJK Ideograph>) 15687 0x8747 蝇 (<CJK Ideograph>) 15688 0x8FCE 迎 (<CJK Ideograph>) 15689 0x8D62 赢 (<CJK Ideograph>) 15690 0x76C8 盈 (<CJK Ideograph>) 15691 0x5F71 影 (<CJK Ideograph>) 15692 0x9896 颖 (<CJK Ideograph>) 15693 0x786C 硬 (<CJK Ideograph>) 15694 0x6620 映 (<CJK Ideograph>) 15695 0x54DF 哟 (<CJK Ideograph>) 15696 0x62E5 拥 (<CJK Ideograph>) 15697 0x4F63 佣 (<CJK Ideograph>) 15698 0x81C3 臃 (<CJK Ideograph>) 15699 0x75C8 痈 (<CJK Ideograph>) 15700 0x5EB8 庸 (<CJK Ideograph>) 15701 0x96CD 雍 (<CJK Ideograph>) 15702 0x8E0A 踊 (<CJK Ideograph>) 15703 0x86F9 蛹 (<CJK Ideograph>) 15704 0x548F 咏 (<CJK Ideograph>) 15705 0x6CF3 泳 (<CJK Ideograph>) 15706 0x6D8C 涌 (<CJK Ideograph>) 15707 0x6C38 永 (<CJK Ideograph>) 15708 0x607F 恿 (<CJK Ideograph>) 15709 0x52C7 勇 (<CJK Ideograph>) 15710 0x7528 用 (<CJK Ideograph>) 15711 0x5E7D 幽 (<CJK Ideograph>) 15712 0x4F18 优 (<CJK Ideograph>) 15713 0x60A0 悠 (<CJK Ideograph>) 15714 0x5FE7 忧 (<CJK Ideograph>) 15715 0x5C24 尤 (<CJK Ideograph>) 15716 0x7531 由 (<CJK Ideograph>) 15717 0x90AE 邮 (<CJK Ideograph>) 15718 0x94C0 铀 (<CJK Ideograph>) 15719 0x72B9 犹 (<CJK Ideograph>) 15720 0x6CB9 油 (<CJK Ideograph>) 15721 0x6E38 游 (<CJK Ideograph>) 15722 0x9149 酉 (<CJK Ideograph>) 15723 0x6709 有 (<CJK Ideograph>) 15724 0x53CB 友 (<CJK Ideograph>) 15725 0x53F3 右 (<CJK Ideograph>) 15726 0x4F51 佑 (<CJK Ideograph>) 15727 0x91C9 釉 (<CJK Ideograph>) 15728 0x8BF1 诱 (<CJK Ideograph>) 15729 0x53C8 又 (<CJK Ideograph>) 15730 0x5E7C 幼 (<CJK Ideograph>) 15731 0x8FC2 迂 (<CJK Ideograph>) 15732 0x6DE4 淤 (<CJK Ideograph>) 15733 0x4E8E 于 (<CJK Ideograph>) 15734 0x76C2 盂 (<CJK Ideograph>) 15735 0x6986 榆 (<CJK Ideograph>) 15736 0x865E 虞 (<CJK Ideograph>) 15737 0x611A 愚 (<CJK Ideograph>) 15738 0x8206 舆 (<CJK Ideograph>) 15739 0x4F59 余 (<CJK Ideograph>) 15740 0x4FDE 俞 (<CJK Ideograph>) 15741 0x903E 逾 (<CJK Ideograph>) 15742 0x9C7C 鱼 (<CJK Ideograph>) 15743 0x6109 愉 (<CJK Ideograph>) 15744 0x6E1D 渝 (<CJK Ideograph>) 15745 0x6E14 渔 (<CJK Ideograph>) 15746 0x9685 隅 (<CJK Ideograph>) 15747 0x4E88 予 (<CJK Ideograph>) 15748 0x5A31 娱 (<CJK Ideograph>) 15749 0x96E8 雨 (<CJK Ideograph>) 15750 0x4E0E 与 (<CJK Ideograph>) 15751 0x5C7F 屿 (<CJK Ideograph>) 15752 0x79B9 禹 (<CJK Ideograph>) 15753 0x5B87 宇 (<CJK Ideograph>) 15754 0x8BED 语 (<CJK Ideograph>) 15755 0x7FBD 羽 (<CJK Ideograph>) 15756 0x7389 玉 (<CJK Ideograph>) 15757 0x57DF 域 (<CJK Ideograph>) 15758 0x828B 芋 (<CJK Ideograph>) 15759 0x90C1 郁 (<CJK Ideograph>) 15760 0x5401 吁 (<CJK Ideograph>) 15761 0x9047 遇 (<CJK Ideograph>) 15762 0x55BB 喻 (<CJK Ideograph>) 15763 0x5CEA 峪 (<CJK Ideograph>) 15764 0x5FA1 御 (<CJK Ideograph>) 15765 0x6108 愈 (<CJK Ideograph>) 15766 0x6B32 欲 (<CJK Ideograph>) 15767 0x72F1 狱 (<CJK Ideograph>) 15768 0x80B2 育 (<CJK Ideograph>) 15769 0x8A89 誉 (<CJK Ideograph>) 15770 0x8A1E 訞 (<CJK Ideograph>) 15771 0x8A1F 訟 (<CJK Ideograph>) 15772 0x8A20 訠 (<CJK Ideograph>) 15773 0x8A21 訡 (<CJK Ideograph>) 15774 0x8A22 訢 (<CJK Ideograph>) 15775 0x8A23 訣 (<CJK Ideograph>) 15776 0x8A24 訤 (<CJK Ideograph>) 15777 0x8A25 訥 (<CJK Ideograph>) 15778 0x8A26 訦 (<CJK Ideograph>) 15779 0x8A27 訧 (<CJK Ideograph>) 15780 0x8A28 訨 (<CJK Ideograph>) 15781 0x8A29 訩 (<CJK Ideograph>) 15782 0x8A2A 訪 (<CJK Ideograph>) 15783 0x8A2B 訫 (<CJK Ideograph>) 15784 0x8A2C 訬 (<CJK Ideograph>) 15785 0x8A2D 設 (<CJK Ideograph>) 15786 0x8A2E 訮 (<CJK Ideograph>) 15787 0x8A2F 訯 (<CJK Ideograph>) 15788 0x8A30 訰 (<CJK Ideograph>) 15789 0x8A31 許 (<CJK Ideograph>) 15790 0x8A32 訲 (<CJK Ideograph>) 15791 0x8A33 訳 (<CJK Ideograph>) 15792 0x8A34 訴 (<CJK Ideograph>) 15793 0x8A35 訵 (<CJK Ideograph>) 15794 0x8A36 訶 (<CJK Ideograph>) 15795 0x8A37 訷 (<CJK Ideograph>) 15796 0x8A38 訸 (<CJK Ideograph>) 15797 0x8A39 訹 (<CJK Ideograph>) 15798 0x8A3A 診 (<CJK Ideograph>) 15799 0x8A3B 註 (<CJK Ideograph>) 15800 0x8A3C 証 (<CJK Ideograph>) 15801 0x8A3D 訽 (<CJK Ideograph>) 15802 0x8A3F 訿 (<CJK Ideograph>) 15803 0x8A40 詀 (<CJK Ideograph>) 15804 0x8A41 詁 (<CJK Ideograph>) 15805 0x8A42 詂 (<CJK Ideograph>) 15806 0x8A43 詃 (<CJK Ideograph>) 15807 0x8A44 詄 (<CJK Ideograph>) 15808 0x8A45 詅 (<CJK Ideograph>) 15809 0x8A46 詆 (<CJK Ideograph>) 15810 0x8A47 詇 (<CJK Ideograph>) 15811 0x8A49 詉 (<CJK Ideograph>) 15812 0x8A4A 詊 (<CJK Ideograph>) 15813 0x8A4B 詋 (<CJK Ideograph>) 15814 0x8A4C 詌 (<CJK Ideograph>) 15815 0x8A4D 詍 (<CJK Ideograph>) 15816 0x8A4E 詎 (<CJK Ideograph>) 15817 0x8A4F 詏 (<CJK Ideograph>) 15818 0x8A50 詐 (<CJK Ideograph>) 15819 0x8A51 詑 (<CJK Ideograph>) 15820 0x8A52 詒 (<CJK Ideograph>) 15821 0x8A53 詓 (<CJK Ideograph>) 15822 0x8A54 詔 (<CJK Ideograph>) 15823 0x8A55 評 (<CJK Ideograph>) 15824 0x8A56 詖 (<CJK Ideograph>) 15825 0x8A57 詗 (<CJK Ideograph>) 15826 0x8A58 詘 (<CJK Ideograph>) 15827 0x8A59 詙 (<CJK Ideograph>) 15828 0x8A5A 詚 (<CJK Ideograph>) 15829 0x8A5B 詛 (<CJK Ideograph>) 15830 0x8A5C 詜 (<CJK Ideograph>) 15831 0x8A5D 詝 (<CJK Ideograph>) 15832 0x8A5E 詞 (<CJK Ideograph>) 15833 0x8A5F 詟 (<CJK Ideograph>) 15834 0x8A60 詠 (<CJK Ideograph>) 15835 0x8A61 詡 (<CJK Ideograph>) 15836 0x8A62 詢 (<CJK Ideograph>) 15837 0x8A63 詣 (<CJK Ideograph>) 15838 0x8A64 詤 (<CJK Ideograph>) 15839 0x8A65 詥 (<CJK Ideograph>) 15840 0x8A66 試 (<CJK Ideograph>) 15841 0x8A67 詧 (<CJK Ideograph>) 15842 0x8A68 詨 (<CJK Ideograph>) 15843 0x8A69 詩 (<CJK Ideograph>) 15844 0x8A6A 詪 (<CJK Ideograph>) 15845 0x8A6B 詫 (<CJK Ideograph>) 15846 0x8A6C 詬 (<CJK Ideograph>) 15847 0x8A6D 詭 (<CJK Ideograph>) 15848 0x8A6E 詮 (<CJK Ideograph>) 15849 0x8A6F 詯 (<CJK Ideograph>) 15850 0x8A70 詰 (<CJK Ideograph>) 15851 0x8A71 話 (<CJK Ideograph>) 15852 0x8A72 該 (<CJK Ideograph>) 15853 0x8A73 詳 (<CJK Ideograph>) 15854 0x8A74 詴 (<CJK Ideograph>) 15855 0x8A75 詵 (<CJK Ideograph>) 15856 0x8A76 詶 (<CJK Ideograph>) 15857 0x8A77 詷 (<CJK Ideograph>) 15858 0x8A78 詸 (<CJK Ideograph>) 15859 0x8A7A 詺 (<CJK Ideograph>) 15860 0x8A7B 詻 (<CJK Ideograph>) 15861 0x8A7C 詼 (<CJK Ideograph>) 15862 0x8A7D 詽 (<CJK Ideograph>) 15863 0x8A7E 詾 (<CJK Ideograph>) 15864 0x8A7F 詿 (<CJK Ideograph>) 15865 0x8A80 誀 (<CJK Ideograph>) 15866 0x6D74 浴 (<CJK Ideograph>) 15867 0x5BD3 寓 (<CJK Ideograph>) 15868 0x88D5 裕 (<CJK Ideograph>) 15869 0x9884 预 (<CJK Ideograph>) 15870 0x8C6B 豫 (<CJK Ideograph>) 15871 0x9A6D 驭 (<CJK Ideograph>) 15872 0x9E33 鸳 (<CJK Ideograph>) 15873 0x6E0A 渊 (<CJK Ideograph>) 15874 0x51A4 冤 (<CJK Ideograph>) 15875 0x5143 元 (<CJK Ideograph>) 15876 0x57A3 垣 (<CJK Ideograph>) 15877 0x8881 袁 (<CJK Ideograph>) 15878 0x539F 原 (<CJK Ideograph>) 15879 0x63F4 援 (<CJK Ideograph>) 15880 0x8F95 辕 (<CJK Ideograph>) 15881 0x56ED 园 (<CJK Ideograph>) 15882 0x5458 员 (<CJK Ideograph>) 15883 0x5706 圆 (<CJK Ideograph>) 15884 0x733F 猿 (<CJK Ideograph>) 15885 0x6E90 源 (<CJK Ideograph>) 15886 0x7F18 缘 (<CJK Ideograph>) 15887 0x8FDC 远 (<CJK Ideograph>) 15888 0x82D1 苑 (<CJK Ideograph>) 15889 0x613F 愿 (<CJK Ideograph>) 15890 0x6028 怨 (<CJK Ideograph>) 15891 0x9662 院 (<CJK Ideograph>) 15892 0x66F0 曰 (<CJK Ideograph>) 15893 0x7EA6 约 (<CJK Ideograph>) 15894 0x8D8A 越 (<CJK Ideograph>) 15895 0x8DC3 跃 (<CJK Ideograph>) 15896 0x94A5 钥 (<CJK Ideograph>) 15897 0x5CB3 岳 (<CJK Ideograph>) 15898 0x7CA4 粤 (<CJK Ideograph>) 15899 0x6708 月 (<CJK Ideograph>) 15900 0x60A6 悦 (<CJK Ideograph>) 15901 0x9605 阅 (<CJK Ideograph>) 15902 0x8018 耘 (<CJK Ideograph>) 15903 0x4E91 云 (<CJK Ideograph>) 15904 0x90E7 郧 (<CJK Ideograph>) 15905 0x5300 匀 (<CJK Ideograph>) 15906 0x9668 陨 (<CJK Ideograph>) 15907 0x5141 允 (<CJK Ideograph>) 15908 0x8FD0 运 (<CJK Ideograph>) 15909 0x8574 蕴 (<CJK Ideograph>) 15910 0x915D 酝 (<CJK Ideograph>) 15911 0x6655 晕 (<CJK Ideograph>) 15912 0x97F5 韵 (<CJK Ideograph>) 15913 0x5B55 孕 (<CJK Ideograph>) 15914 0x531D 匝 (<CJK Ideograph>) 15915 0x7838 砸 (<CJK Ideograph>) 15916 0x6742 杂 (<CJK Ideograph>) 15917 0x683D 栽 (<CJK Ideograph>) 15918 0x54C9 哉 (<CJK Ideograph>) 15919 0x707E 灾 (<CJK Ideograph>) 15920 0x5BB0 宰 (<CJK Ideograph>) 15921 0x8F7D 载 (<CJK Ideograph>) 15922 0x518D 再 (<CJK Ideograph>) 15923 0x5728 在 (<CJK Ideograph>) 15924 0x54B1 咱 (<CJK Ideograph>) 15925 0x6512 攒 (<CJK Ideograph>) 15926 0x6682 暂 (<CJK Ideograph>) 15927 0x8D5E 赞 (<CJK Ideograph>) 15928 0x8D43 赃 (<CJK Ideograph>) 15929 0x810F 脏 (<CJK Ideograph>) 15930 0x846C 葬 (<CJK Ideograph>) 15931 0x906D 遭 (<CJK Ideograph>) 15932 0x7CDF 糟 (<CJK Ideograph>) 15933 0x51FF 凿 (<CJK Ideograph>) 15934 0x85FB 藻 (<CJK Ideograph>) 15935 0x67A3 枣 (<CJK Ideograph>) 15936 0x65E9 早 (<CJK Ideograph>) 15937 0x6FA1 澡 (<CJK Ideograph>) 15938 0x86A4 蚤 (<CJK Ideograph>) 15939 0x8E81 躁 (<CJK Ideograph>) 15940 0x566A 噪 (<CJK Ideograph>) 15941 0x9020 造 (<CJK Ideograph>) 15942 0x7682 皂 (<CJK Ideograph>) 15943 0x7076 灶 (<CJK Ideograph>) 15944 0x71E5 燥 (<CJK Ideograph>) 15945 0x8D23 责 (<CJK Ideograph>) 15946 0x62E9 择 (<CJK Ideograph>) 15947 0x5219 则 (<CJK Ideograph>) 15948 0x6CFD 泽 (<CJK Ideograph>) 15949 0x8D3C 贼 (<CJK Ideograph>) 15950 0x600E 怎 (<CJK Ideograph>) 15951 0x589E 增 (<CJK Ideograph>) 15952 0x618E 憎 (<CJK Ideograph>) 15953 0x66FE 曾 (<CJK Ideograph>) 15954 0x8D60 赠 (<CJK Ideograph>) 15955 0x624E 扎 (<CJK Ideograph>) 15956 0x55B3 喳 (<CJK Ideograph>) 15957 0x6E23 渣 (<CJK Ideograph>) 15958 0x672D 札 (<CJK Ideograph>) 15959 0x8F67 轧 (<CJK Ideograph>) 15960 0x8A81 誁 (<CJK Ideograph>) 15961 0x8A82 誂 (<CJK Ideograph>) 15962 0x8A83 誃 (<CJK Ideograph>) 15963 0x8A84 誄 (<CJK Ideograph>) 15964 0x8A85 誅 (<CJK Ideograph>) 15965 0x8A86 誆 (<CJK Ideograph>) 15966 0x8A87 誇 (<CJK Ideograph>) 15967 0x8A88 誈 (<CJK Ideograph>) 15968 0x8A8B 誋 (<CJK Ideograph>) 15969 0x8A8C 誌 (<CJK Ideograph>) 15970 0x8A8D 認 (<CJK Ideograph>) 15971 0x8A8E 誎 (<CJK Ideograph>) 15972 0x8A8F 誏 (<CJK Ideograph>) 15973 0x8A90 誐 (<CJK Ideograph>) 15974 0x8A91 誑 (<CJK Ideograph>) 15975 0x8A92 誒 (<CJK Ideograph>) 15976 0x8A94 誔 (<CJK Ideograph>) 15977 0x8A95 誕 (<CJK Ideograph>) 15978 0x8A96 誖 (<CJK Ideograph>) 15979 0x8A97 誗 (<CJK Ideograph>) 15980 0x8A98 誘 (<CJK Ideograph>) 15981 0x8A99 誙 (<CJK Ideograph>) 15982 0x8A9A 誚 (<CJK Ideograph>) 15983 0x8A9B 誛 (<CJK Ideograph>) 15984 0x8A9C 誜 (<CJK Ideograph>) 15985 0x8A9D 誝 (<CJK Ideograph>) 15986 0x8A9E 語 (<CJK Ideograph>) 15987 0x8A9F 誟 (<CJK Ideograph>) 15988 0x8AA0 誠 (<CJK Ideograph>) 15989 0x8AA1 誡 (<CJK Ideograph>) 15990 0x8AA2 誢 (<CJK Ideograph>) 15991 0x8AA3 誣 (<CJK Ideograph>) 15992 0x8AA4 誤 (<CJK Ideograph>) 15993 0x8AA5 誥 (<CJK Ideograph>) 15994 0x8AA6 誦 (<CJK Ideograph>) 15995 0x8AA7 誧 (<CJK Ideograph>) 15996 0x8AA8 誨 (<CJK Ideograph>) 15997 0x8AA9 誩 (<CJK Ideograph>) 15998 0x8AAA 說 (<CJK Ideograph>) 15999 0x8AAB 誫 (<CJK Ideograph>) 16000 0x8AAC 説 (<CJK Ideograph>) 16001 0x8AAD 読 (<CJK Ideograph>) 16002 0x8AAE 誮 (<CJK Ideograph>) 16003 0x8AAF 誯 (<CJK Ideograph>) 16004 0x8AB0 誰 (<CJK Ideograph>) 16005 0x8AB1 誱 (<CJK Ideograph>) 16006 0x8AB2 課 (<CJK Ideograph>) 16007 0x8AB3 誳 (<CJK Ideograph>) 16008 0x8AB4 誴 (<CJK Ideograph>) 16009 0x8AB5 誵 (<CJK Ideograph>) 16010 0x8AB6 誶 (<CJK Ideograph>) 16011 0x8AB7 誷 (<CJK Ideograph>) 16012 0x8AB8 誸 (<CJK Ideograph>) 16013 0x8AB9 誹 (<CJK Ideograph>) 16014 0x8ABA 誺 (<CJK Ideograph>) 16015 0x8ABB 誻 (<CJK Ideograph>) 16016 0x8ABC 誼 (<CJK Ideograph>) 16017 0x8ABD 誽 (<CJK Ideograph>) 16018 0x8ABE 誾 (<CJK Ideograph>) 16019 0x8ABF 調 (<CJK Ideograph>) 16020 0x8AC0 諀 (<CJK Ideograph>) 16021 0x8AC1 諁 (<CJK Ideograph>) 16022 0x8AC2 諂 (<CJK Ideograph>) 16023 0x8AC3 諃 (<CJK Ideograph>) 16024 0x8AC4 諄 (<CJK Ideograph>) 16025 0x8AC5 諅 (<CJK Ideograph>) 16026 0x8AC6 諆 (<CJK Ideograph>) 16027 0x8AC7 談 (<CJK Ideograph>) 16028 0x8AC8 諈 (<CJK Ideograph>) 16029 0x8AC9 諉 (<CJK Ideograph>) 16030 0x8ACA 諊 (<CJK Ideograph>) 16031 0x8ACB 請 (<CJK Ideograph>) 16032 0x8ACC 諌 (<CJK Ideograph>) 16033 0x8ACD 諍 (<CJK Ideograph>) 16034 0x8ACE 諎 (<CJK Ideograph>) 16035 0x8ACF 諏 (<CJK Ideograph>) 16036 0x8AD0 諐 (<CJK Ideograph>) 16037 0x8AD1 諑 (<CJK Ideograph>) 16038 0x8AD2 諒 (<CJK Ideograph>) 16039 0x8AD3 諓 (<CJK Ideograph>) 16040 0x8AD4 諔 (<CJK Ideograph>) 16041 0x8AD5 諕 (<CJK Ideograph>) 16042 0x8AD6 論 (<CJK Ideograph>) 16043 0x8AD7 諗 (<CJK Ideograph>) 16044 0x8AD8 諘 (<CJK Ideograph>) 16045 0x8AD9 諙 (<CJK Ideograph>) 16046 0x8ADA 諚 (<CJK Ideograph>) 16047 0x8ADB 諛 (<CJK Ideograph>) 16048 0x8ADC 諜 (<CJK Ideograph>) 16049 0x8ADD 諝 (<CJK Ideograph>) 16050 0x8ADE 諞 (<CJK Ideograph>) 16051 0x8ADF 諟 (<CJK Ideograph>) 16052 0x8AE0 諠 (<CJK Ideograph>) 16053 0x8AE1 諡 (<CJK Ideograph>) 16054 0x8AE2 諢 (<CJK Ideograph>) 16055 0x8AE3 諣 (<CJK Ideograph>) 16056 0x94E1 铡 (<CJK Ideograph>) 16057 0x95F8 闸 (<CJK Ideograph>) 16058 0x7728 眨 (<CJK Ideograph>) 16059 0x6805 栅 (<CJK Ideograph>) 16060 0x69A8 榨 (<CJK Ideograph>) 16061 0x548B 咋 (<CJK Ideograph>) 16062 0x4E4D 乍 (<CJK Ideograph>) 16063 0x70B8 炸 (<CJK Ideograph>) 16064 0x8BC8 诈 (<CJK Ideograph>) 16065 0x6458 摘 (<CJK Ideograph>) 16066 0x658B 斋 (<CJK Ideograph>) 16067 0x5B85 宅 (<CJK Ideograph>) 16068 0x7A84 窄 (<CJK Ideograph>) 16069 0x503A 债 (<CJK Ideograph>) 16070 0x5BE8 寨 (<CJK Ideograph>) 16071 0x77BB 瞻 (<CJK Ideograph>) 16072 0x6BE1 毡 (<CJK Ideograph>) 16073 0x8A79 詹 (<CJK Ideograph>) 16074 0x7C98 粘 (<CJK Ideograph>) 16075 0x6CBE 沾 (<CJK Ideograph>) 16076 0x76CF 盏 (<CJK Ideograph>) 16077 0x65A9 斩 (<CJK Ideograph>) 16078 0x8F97 辗 (<CJK Ideograph>) 16079 0x5D2D 崭 (<CJK Ideograph>) 16080 0x5C55 展 (<CJK Ideograph>) 16081 0x8638 蘸 (<CJK Ideograph>) 16082 0x6808 栈 (<CJK Ideograph>) 16083 0x5360 占 (<CJK Ideograph>) 16084 0x6218 战 (<CJK Ideograph>) 16085 0x7AD9 站 (<CJK Ideograph>) 16086 0x6E5B 湛 (<CJK Ideograph>) 16087 0x7EFD 绽 (<CJK Ideograph>) 16088 0x6A1F 樟 (<CJK Ideograph>) 16089 0x7AE0 章 (<CJK Ideograph>) 16090 0x5F70 彰 (<CJK Ideograph>) 16091 0x6F33 漳 (<CJK Ideograph>) 16092 0x5F20 张 (<CJK Ideograph>) 16093 0x638C 掌 (<CJK Ideograph>) 16094 0x6DA8 涨 (<CJK Ideograph>) 16095 0x6756 杖 (<CJK Ideograph>) 16096 0x4E08 丈 (<CJK Ideograph>) 16097 0x5E10 帐 (<CJK Ideograph>) 16098 0x8D26 账 (<CJK Ideograph>) 16099 0x4ED7 仗 (<CJK Ideograph>) 16100 0x80C0 胀 (<CJK Ideograph>) 16101 0x7634 瘴 (<CJK Ideograph>) 16102 0x969C 障 (<CJK Ideograph>) 16103 0x62DB 招 (<CJK Ideograph>) 16104 0x662D 昭 (<CJK Ideograph>) 16105 0x627E 找 (<CJK Ideograph>) 16106 0x6CBC 沼 (<CJK Ideograph>) 16107 0x8D75 赵 (<CJK Ideograph>) 16108 0x7167 照 (<CJK Ideograph>) 16109 0x7F69 罩 (<CJK Ideograph>) 16110 0x5146 兆 (<CJK Ideograph>) 16111 0x8087 肇 (<CJK Ideograph>) 16112 0x53EC 召 (<CJK Ideograph>) 16113 0x906E 遮 (<CJK Ideograph>) 16114 0x6298 折 (<CJK Ideograph>) 16115 0x54F2 哲 (<CJK Ideograph>) 16116 0x86F0 蛰 (<CJK Ideograph>) 16117 0x8F99 辙 (<CJK Ideograph>) 16118 0x8005 者 (<CJK Ideograph>) 16119 0x9517 锗 (<CJK Ideograph>) 16120 0x8517 蔗 (<CJK Ideograph>) 16121 0x8FD9 这 (<CJK Ideograph>) 16122 0x6D59 浙 (<CJK Ideograph>) 16123 0x73CD 珍 (<CJK Ideograph>) 16124 0x659F 斟 (<CJK Ideograph>) 16125 0x771F 真 (<CJK Ideograph>) 16126 0x7504 甄 (<CJK Ideograph>) 16127 0x7827 砧 (<CJK Ideograph>) 16128 0x81FB 臻 (<CJK Ideograph>) 16129 0x8D1E 贞 (<CJK Ideograph>) 16130 0x9488 针 (<CJK Ideograph>) 16131 0x4FA6 侦 (<CJK Ideograph>) 16132 0x6795 枕 (<CJK Ideograph>) 16133 0x75B9 疹 (<CJK Ideograph>) 16134 0x8BCA 诊 (<CJK Ideograph>) 16135 0x9707 震 (<CJK Ideograph>) 16136 0x632F 振 (<CJK Ideograph>) 16137 0x9547 镇 (<CJK Ideograph>) 16138 0x9635 阵 (<CJK Ideograph>) 16139 0x84B8 蒸 (<CJK Ideograph>) 16140 0x6323 挣 (<CJK Ideograph>) 16141 0x7741 睁 (<CJK Ideograph>) 16142 0x5F81 征 (<CJK Ideograph>) 16143 0x72F0 狰 (<CJK Ideograph>) 16144 0x4E89 争 (<CJK Ideograph>) 16145 0x6014 怔 (<CJK Ideograph>) 16146 0x6574 整 (<CJK Ideograph>) 16147 0x62EF 拯 (<CJK Ideograph>) 16148 0x6B63 正 (<CJK Ideograph>) 16149 0x653F 政 (<CJK Ideograph>) 16150 0x8AE4 諤 (<CJK Ideograph>) 16151 0x8AE5 諥 (<CJK Ideograph>) 16152 0x8AE6 諦 (<CJK Ideograph>) 16153 0x8AE7 諧 (<CJK Ideograph>) 16154 0x8AE8 諨 (<CJK Ideograph>) 16155 0x8AE9 諩 (<CJK Ideograph>) 16156 0x8AEA 諪 (<CJK Ideograph>) 16157 0x8AEB 諫 (<CJK Ideograph>) 16158 0x8AEC 諬 (<CJK Ideograph>) 16159 0x8AED 諭 (<CJK Ideograph>) 16160 0x8AEE 諮 (<CJK Ideograph>) 16161 0x8AEF 諯 (<CJK Ideograph>) 16162 0x8AF0 諰 (<CJK Ideograph>) 16163 0x8AF1 諱 (<CJK Ideograph>) 16164 0x8AF2 諲 (<CJK Ideograph>) 16165 0x8AF3 諳 (<CJK Ideograph>) 16166 0x8AF4 諴 (<CJK Ideograph>) 16167 0x8AF5 諵 (<CJK Ideograph>) 16168 0x8AF6 諶 (<CJK Ideograph>) 16169 0x8AF7 諷 (<CJK Ideograph>) 16170 0x8AF8 諸 (<CJK Ideograph>) 16171 0x8AF9 諹 (<CJK Ideograph>) 16172 0x8AFA 諺 (<CJK Ideograph>) 16173 0x8AFB 諻 (<CJK Ideograph>) 16174 0x8AFC 諼 (<CJK Ideograph>) 16175 0x8AFD 諽 (<CJK Ideograph>) 16176 0x8AFE 諾 (<CJK Ideograph>) 16177 0x8AFF 諿 (<CJK Ideograph>) 16178 0x8B00 謀 (<CJK Ideograph>) 16179 0x8B01 謁 (<CJK Ideograph>) 16180 0x8B02 謂 (<CJK Ideograph>) 16181 0x8B03 謃 (<CJK Ideograph>) 16182 0x8B04 謄 (<CJK Ideograph>) 16183 0x8B05 謅 (<CJK Ideograph>) 16184 0x8B06 謆 (<CJK Ideograph>) 16185 0x8B08 謈 (<CJK Ideograph>) 16186 0x8B09 謉 (<CJK Ideograph>) 16187 0x8B0A 謊 (<CJK Ideograph>) 16188 0x8B0B 謋 (<CJK Ideograph>) 16189 0x8B0C 謌 (<CJK Ideograph>) 16190 0x8B0D 謍 (<CJK Ideograph>) 16191 0x8B0E 謎 (<CJK Ideograph>) 16192 0x8B0F 謏 (<CJK Ideograph>) 16193 0x8B10 謐 (<CJK Ideograph>) 16194 0x8B11 謑 (<CJK Ideograph>) 16195 0x8B12 謒 (<CJK Ideograph>) 16196 0x8B13 謓 (<CJK Ideograph>) 16197 0x8B14 謔 (<CJK Ideograph>) 16198 0x8B15 謕 (<CJK Ideograph>) 16199 0x8B16 謖 (<CJK Ideograph>) 16200 0x8B17 謗 (<CJK Ideograph>) 16201 0x8B18 謘 (<CJK Ideograph>) 16202 0x8B19 謙 (<CJK Ideograph>) 16203 0x8B1A 謚 (<CJK Ideograph>) 16204 0x8B1B 講 (<CJK Ideograph>) 16205 0x8B1C 謜 (<CJK Ideograph>) 16206 0x8B1D 謝 (<CJK Ideograph>) 16207 0x8B1E 謞 (<CJK Ideograph>) 16208 0x8B1F 謟 (<CJK Ideograph>) 16209 0x8B20 謠 (<CJK Ideograph>) 16210 0x8B21 謡 (<CJK Ideograph>) 16211 0x8B22 謢 (<CJK Ideograph>) 16212 0x8B23 謣 (<CJK Ideograph>) 16213 0x8B24 謤 (<CJK Ideograph>) 16214 0x8B25 謥 (<CJK Ideograph>) 16215 0x8B27 謧 (<CJK Ideograph>) 16216 0x8B28 謨 (<CJK Ideograph>) 16217 0x8B29 謩 (<CJK Ideograph>) 16218 0x8B2A 謪 (<CJK Ideograph>) 16219 0x8B2B 謫 (<CJK Ideograph>) 16220 0x8B2C 謬 (<CJK Ideograph>) 16221 0x8B2D 謭 (<CJK Ideograph>) 16222 0x8B2E 謮 (<CJK Ideograph>) 16223 0x8B2F 謯 (<CJK Ideograph>) 16224 0x8B30 謰 (<CJK Ideograph>) 16225 0x8B31 謱 (<CJK Ideograph>) 16226 0x8B32 謲 (<CJK Ideograph>) 16227 0x8B33 謳 (<CJK Ideograph>) 16228 0x8B34 謴 (<CJK Ideograph>) 16229 0x8B35 謵 (<CJK Ideograph>) 16230 0x8B36 謶 (<CJK Ideograph>) 16231 0x8B37 謷 (<CJK Ideograph>) 16232 0x8B38 謸 (<CJK Ideograph>) 16233 0x8B39 謹 (<CJK Ideograph>) 16234 0x8B3A 謺 (<CJK Ideograph>) 16235 0x8B3B 謻 (<CJK Ideograph>) 16236 0x8B3C 謼 (<CJK Ideograph>) 16237 0x8B3D 謽 (<CJK Ideograph>) 16238 0x8B3E 謾 (<CJK Ideograph>) 16239 0x8B3F 謿 (<CJK Ideograph>) 16240 0x8B40 譀 (<CJK Ideograph>) 16241 0x8B41 譁 (<CJK Ideograph>) 16242 0x8B42 譂 (<CJK Ideograph>) 16243 0x8B43 譃 (<CJK Ideograph>) 16244 0x8B44 譄 (<CJK Ideograph>) 16245 0x8B45 譅 (<CJK Ideograph>) 16246 0x5E27 帧 (<CJK Ideograph>) 16247 0x75C7 症 (<CJK Ideograph>) 16248 0x90D1 郑 (<CJK Ideograph>) 16249 0x8BC1 证 (<CJK Ideograph>) 16250 0x829D 芝 (<CJK Ideograph>) 16251 0x679D 枝 (<CJK Ideograph>) 16252 0x652F 支 (<CJK Ideograph>) 16253 0x5431 吱 (<CJK Ideograph>) 16254 0x8718 蜘 (<CJK Ideograph>) 16255 0x77E5 知 (<CJK Ideograph>) 16256 0x80A2 肢 (<CJK Ideograph>) 16257 0x8102 脂 (<CJK Ideograph>) 16258 0x6C41 汁 (<CJK Ideograph>) 16259 0x4E4B 之 (<CJK Ideograph>) 16260 0x7EC7 织 (<CJK Ideograph>) 16261 0x804C 职 (<CJK Ideograph>) 16262 0x76F4 直 (<CJK Ideograph>) 16263 0x690D 植 (<CJK Ideograph>) 16264 0x6B96 殖 (<CJK Ideograph>) 16265 0x6267 执 (<CJK Ideograph>) 16266 0x503C 值 (<CJK Ideograph>) 16267 0x4F84 侄 (<CJK Ideograph>) 16268 0x5740 址 (<CJK Ideograph>) 16269 0x6307 指 (<CJK Ideograph>) 16270 0x6B62 止 (<CJK Ideograph>) 16271 0x8DBE 趾 (<CJK Ideograph>) 16272 0x53EA 只 (<CJK Ideograph>) 16273 0x65E8 旨 (<CJK Ideograph>) 16274 0x7EB8 纸 (<CJK Ideograph>) 16275 0x5FD7 志 (<CJK Ideograph>) 16276 0x631A 挚 (<CJK Ideograph>) 16277 0x63B7 掷 (<CJK Ideograph>) 16278 0x81F3 至 (<CJK Ideograph>) 16279 0x81F4 致 (<CJK Ideograph>) 16280 0x7F6E 置 (<CJK Ideograph>) 16281 0x5E1C 帜 (<CJK Ideograph>) 16282 0x5CD9 峙 (<CJK Ideograph>) 16283 0x5236 制 (<CJK Ideograph>) 16284 0x667A 智 (<CJK Ideograph>) 16285 0x79E9 秩 (<CJK Ideograph>) 16286 0x7A1A 稚 (<CJK Ideograph>) 16287 0x8D28 质 (<CJK Ideograph>) 16288 0x7099 炙 (<CJK Ideograph>) 16289 0x75D4 痔 (<CJK Ideograph>) 16290 0x6EDE 滞 (<CJK Ideograph>) 16291 0x6CBB 治 (<CJK Ideograph>) 16292 0x7A92 窒 (<CJK Ideograph>) 16293 0x4E2D 中 (<CJK Ideograph>) 16294 0x76C5 盅 (<CJK Ideograph>) 16295 0x5FE0 忠 (<CJK Ideograph>) 16296 0x949F 钟 (<CJK Ideograph>) 16297 0x8877 衷 (<CJK Ideograph>) 16298 0x7EC8 终 (<CJK Ideograph>) 16299 0x79CD 种 (<CJK Ideograph>) 16300 0x80BF 肿 (<CJK Ideograph>) 16301 0x91CD 重 (<CJK Ideograph>) 16302 0x4EF2 仲 (<CJK Ideograph>) 16303 0x4F17 众 (<CJK Ideograph>) 16304 0x821F 舟 (<CJK Ideograph>) 16305 0x5468 周 (<CJK Ideograph>) 16306 0x5DDE 州 (<CJK Ideograph>) 16307 0x6D32 洲 (<CJK Ideograph>) 16308 0x8BCC 诌 (<CJK Ideograph>) 16309 0x7CA5 粥 (<CJK Ideograph>) 16310 0x8F74 轴 (<CJK Ideograph>) 16311 0x8098 肘 (<CJK Ideograph>) 16312 0x5E1A 帚 (<CJK Ideograph>) 16313 0x5492 咒 (<CJK Ideograph>) 16314 0x76B1 皱 (<CJK Ideograph>) 16315 0x5B99 宙 (<CJK Ideograph>) 16316 0x663C 昼 (<CJK Ideograph>) 16317 0x9AA4 骤 (<CJK Ideograph>) 16318 0x73E0 珠 (<CJK Ideograph>) 16319 0x682A 株 (<CJK Ideograph>) 16320 0x86DB 蛛 (<CJK Ideograph>) 16321 0x6731 朱 (<CJK Ideograph>) 16322 0x732A 猪 (<CJK Ideograph>) 16323 0x8BF8 诸 (<CJK Ideograph>) 16324 0x8BDB 诛 (<CJK Ideograph>) 16325 0x9010 逐 (<CJK Ideograph>) 16326 0x7AF9 竹 (<CJK Ideograph>) 16327 0x70DB 烛 (<CJK Ideograph>) 16328 0x716E 煮 (<CJK Ideograph>) 16329 0x62C4 拄 (<CJK Ideograph>) 16330 0x77A9 瞩 (<CJK Ideograph>) 16331 0x5631 嘱 (<CJK Ideograph>) 16332 0x4E3B 主 (<CJK Ideograph>) 16333 0x8457 著 (<CJK Ideograph>) 16334 0x67F1 柱 (<CJK Ideograph>) 16335 0x52A9 助 (<CJK Ideograph>) 16336 0x86C0 蛀 (<CJK Ideograph>) 16337 0x8D2E 贮 (<CJK Ideograph>) 16338 0x94F8 铸 (<CJK Ideograph>) 16339 0x7B51 筑 (<CJK Ideograph>) 16340 0x8B46 譆 (<CJK Ideograph>) 16341 0x8B47 譇 (<CJK Ideograph>) 16342 0x8B48 譈 (<CJK Ideograph>) 16343 0x8B49 證 (<CJK Ideograph>) 16344 0x8B4A 譊 (<CJK Ideograph>) 16345 0x8B4B 譋 (<CJK Ideograph>) 16346 0x8B4C 譌 (<CJK Ideograph>) 16347 0x8B4D 譍 (<CJK Ideograph>) 16348 0x8B4E 譎 (<CJK Ideograph>) 16349 0x8B4F 譏 (<CJK Ideograph>) 16350 0x8B50 譐 (<CJK Ideograph>) 16351 0x8B51 譑 (<CJK Ideograph>) 16352 0x8B52 譒 (<CJK Ideograph>) 16353 0x8B53 譓 (<CJK Ideograph>) 16354 0x8B54 譔 (<CJK Ideograph>) 16355 0x8B55 譕 (<CJK Ideograph>) 16356 0x8B56 譖 (<CJK Ideograph>) 16357 0x8B57 譗 (<CJK Ideograph>) 16358 0x8B58 識 (<CJK Ideograph>) 16359 0x8B59 譙 (<CJK Ideograph>) 16360 0x8B5A 譚 (<CJK Ideograph>) 16361 0x8B5B 譛 (<CJK Ideograph>) 16362 0x8B5C 譜 (<CJK Ideograph>) 16363 0x8B5D 譝 (<CJK Ideograph>) 16364 0x8B5E 譞 (<CJK Ideograph>) 16365 0x8B5F 譟 (<CJK Ideograph>) 16366 0x8B60 譠 (<CJK Ideograph>) 16367 0x8B61 譡 (<CJK Ideograph>) 16368 0x8B62 譢 (<CJK Ideograph>) 16369 0x8B63 譣 (<CJK Ideograph>) 16370 0x8B64 譤 (<CJK Ideograph>) 16371 0x8B65 譥 (<CJK Ideograph>) 16372 0x8B67 譧 (<CJK Ideograph>) 16373 0x8B68 譨 (<CJK Ideograph>) 16374 0x8B69 譩 (<CJK Ideograph>) 16375 0x8B6A 譪 (<CJK Ideograph>) 16376 0x8B6B 譫 (<CJK Ideograph>) 16377 0x8B6D 譭 (<CJK Ideograph>) 16378 0x8B6E 譮 (<CJK Ideograph>) 16379 0x8B6F 譯 (<CJK Ideograph>) 16380 0x8B70 議 (<CJK Ideograph>) 16381 0x8B71 譱 (<CJK Ideograph>) 16382 0x8B72 譲 (<CJK Ideograph>) 16383 0x8B73 譳 (<CJK Ideograph>) 16384 0x8B74 譴 (<CJK Ideograph>) 16385 0x8B75 譵 (<CJK Ideograph>) 16386 0x8B76 譶 (<CJK Ideograph>) 16387 0x8B77 護 (<CJK Ideograph>) 16388 0x8B78 譸 (<CJK Ideograph>) 16389 0x8B79 譹 (<CJK Ideograph>) 16390 0x8B7A 譺 (<CJK Ideograph>) 16391 0x8B7B 譻 (<CJK Ideograph>) 16392 0x8B7C 譼 (<CJK Ideograph>) 16393 0x8B7D 譽 (<CJK Ideograph>) 16394 0x8B7E 譾 (<CJK Ideograph>) 16395 0x8B7F 譿 (<CJK Ideograph>) 16396 0x8B80 讀 (<CJK Ideograph>) 16397 0x8B81 讁 (<CJK Ideograph>) 16398 0x8B82 讂 (<CJK Ideograph>) 16399 0x8B83 讃 (<CJK Ideograph>) 16400 0x8B84 讄 (<CJK Ideograph>) 16401 0x8B85 讅 (<CJK Ideograph>) 16402 0x8B86 讆 (<CJK Ideograph>) 16403 0x8B87 讇 (<CJK Ideograph>) 16404 0x8B88 讈 (<CJK Ideograph>) 16405 0x8B89 讉 (<CJK Ideograph>) 16406 0x8B8A 變 (<CJK Ideograph>) 16407 0x8B8B 讋 (<CJK Ideograph>) 16408 0x8B8C 讌 (<CJK Ideograph>) 16409 0x8B8D 讍 (<CJK Ideograph>) 16410 0x8B8E 讎 (<CJK Ideograph>) 16411 0x8B8F 讏 (<CJK Ideograph>) 16412 0x8B90 讐 (<CJK Ideograph>) 16413 0x8B91 讑 (<CJK Ideograph>) 16414 0x8B92 讒 (<CJK Ideograph>) 16415 0x8B93 讓 (<CJK Ideograph>) 16416 0x8B94 讔 (<CJK Ideograph>) 16417 0x8B95 讕 (<CJK Ideograph>) 16418 0x8B96 讖 (<CJK Ideograph>) 16419 0x8B97 讗 (<CJK Ideograph>) 16420 0x8B98 讘 (<CJK Ideograph>) 16421 0x8B99 讙 (<CJK Ideograph>) 16422 0x8B9A 讚 (<CJK Ideograph>) 16423 0x8B9B 讛 (<CJK Ideograph>) 16424 0x8B9C 讜 (<CJK Ideograph>) 16425 0x8B9D 讝 (<CJK Ideograph>) 16426 0x8B9E 讞 (<CJK Ideograph>) 16427 0x8B9F 讟 (<CJK Ideograph>) 16428 0x8BAC 讬 (<CJK Ideograph>) 16429 0x8BB1 讱 (<CJK Ideograph>) 16430 0x8BBB 讻 (<CJK Ideograph>) 16431 0x8BC7 诇 (<CJK Ideograph>) 16432 0x8BD0 诐 (<CJK Ideograph>) 16433 0x8BEA 诪 (<CJK Ideograph>) 16434 0x8C09 谉 (<CJK Ideograph>) 16435 0x8C1E 谞 (<CJK Ideograph>) 16436 0x4F4F 住 (<CJK Ideograph>) 16437 0x6CE8 注 (<CJK Ideograph>) 16438 0x795D 祝 (<CJK Ideograph>) 16439 0x9A7B 驻 (<CJK Ideograph>) 16440 0x6293 抓 (<CJK Ideograph>) 16441 0x722A 爪 (<CJK Ideograph>) 16442 0x62FD 拽 (<CJK Ideograph>) 16443 0x4E13 专 (<CJK Ideograph>) 16444 0x7816 砖 (<CJK Ideograph>) 16445 0x8F6C 转 (<CJK Ideograph>) 16446 0x64B0 撰 (<CJK Ideograph>) 16447 0x8D5A 赚 (<CJK Ideograph>) 16448 0x7BC6 篆 (<CJK Ideograph>) 16449 0x6869 桩 (<CJK Ideograph>) 16450 0x5E84 庄 (<CJK Ideograph>) 16451 0x88C5 装 (<CJK Ideograph>) 16452 0x5986 妆 (<CJK Ideograph>) 16453 0x649E 撞 (<CJK Ideograph>) 16454 0x58EE 壮 (<CJK Ideograph>) 16455 0x72B6 状 (<CJK Ideograph>) 16456 0x690E 椎 (<CJK Ideograph>) 16457 0x9525 锥 (<CJK Ideograph>) 16458 0x8FFD 追 (<CJK Ideograph>) 16459 0x8D58 赘 (<CJK Ideograph>) 16460 0x5760 坠 (<CJK Ideograph>) 16461 0x7F00 缀 (<CJK Ideograph>) 16462 0x8C06 谆 (<CJK Ideograph>) 16463 0x51C6 准 (<CJK Ideograph>) 16464 0x6349 捉 (<CJK Ideograph>) 16465 0x62D9 拙 (<CJK Ideograph>) 16466 0x5353 卓 (<CJK Ideograph>) 16467 0x684C 桌 (<CJK Ideograph>) 16468 0x7422 琢 (<CJK Ideograph>) 16469 0x8301 茁 (<CJK Ideograph>) 16470 0x914C 酌 (<CJK Ideograph>) 16471 0x5544 啄 (<CJK Ideograph>) 16472 0x7740 着 (<CJK Ideograph>) 16473 0x707C 灼 (<CJK Ideograph>) 16474 0x6D4A 浊 (<CJK Ideograph>) 16475 0x5179 兹 (<CJK Ideograph>) 16476 0x54A8 咨 (<CJK Ideograph>) 16477 0x8D44 资 (<CJK Ideograph>) 16478 0x59FF 姿 (<CJK Ideograph>) 16479 0x6ECB 滋 (<CJK Ideograph>) 16480 0x6DC4 淄 (<CJK Ideograph>) 16481 0x5B5C 孜 (<CJK Ideograph>) 16482 0x7D2B 紫 (<CJK Ideograph>) 16483 0x4ED4 仔 (<CJK Ideograph>) 16484 0x7C7D 籽 (<CJK Ideograph>) 16485 0x6ED3 滓 (<CJK Ideograph>) 16486 0x5B50 子 (<CJK Ideograph>) 16487 0x81EA 自 (<CJK Ideograph>) 16488 0x6E0D 渍 (<CJK Ideograph>) 16489 0x5B57 字 (<CJK Ideograph>) 16490 0x9B03 鬃 (<CJK Ideograph>) 16491 0x68D5 棕 (<CJK Ideograph>) 16492 0x8E2A 踪 (<CJK Ideograph>) 16493 0x5B97 宗 (<CJK Ideograph>) 16494 0x7EFC 综 (<CJK Ideograph>) 16495 0x603B 总 (<CJK Ideograph>) 16496 0x7EB5 纵 (<CJK Ideograph>) 16497 0x90B9 邹 (<CJK Ideograph>) 16498 0x8D70 走 (<CJK Ideograph>) 16499 0x594F 奏 (<CJK Ideograph>) 16500 0x63CD 揍 (<CJK Ideograph>) 16501 0x79DF 租 (<CJK Ideograph>) 16502 0x8DB3 足 (<CJK Ideograph>) 16503 0x5352 卒 (<CJK Ideograph>) 16504 0x65CF 族 (<CJK Ideograph>) 16505 0x7956 祖 (<CJK Ideograph>) 16506 0x8BC5 诅 (<CJK Ideograph>) 16507 0x963B 阻 (<CJK Ideograph>) 16508 0x7EC4 组 (<CJK Ideograph>) 16509 0x94BB 钻 (<CJK Ideograph>) 16510 0x7E82 纂 (<CJK Ideograph>) 16511 0x5634 嘴 (<CJK Ideograph>) 16512 0x9189 醉 (<CJK Ideograph>) 16513 0x6700 最 (<CJK Ideograph>) 16514 0x7F6A 罪 (<CJK Ideograph>) 16515 0x5C0A 尊 (<CJK Ideograph>) 16516 0x9075 遵 (<CJK Ideograph>) 16517 0x6628 昨 (<CJK Ideograph>) 16518 0x5DE6 左 (<CJK Ideograph>) 16519 0x4F50 佐 (<CJK Ideograph>) 16520 0x67DE 柞 (<CJK Ideograph>) 16521 0x505A 做 (<CJK Ideograph>) 16522 0x4F5C 作 (<CJK Ideograph>) 16523 0x5750 坐 (<CJK Ideograph>) 16524 0x5EA7 座 (<CJK Ideograph>) 16525 0xE810  (<Private Use>) 16526 0xE811  (<Private Use>) 16527 0xE812  (<Private Use>) 16528 0xE813  (<Private Use>) 16529 0xE814  (<Private Use>) 16530 0x8C38 谸 (<CJK Ideograph>) 16531 0x8C39 谹 (<CJK Ideograph>) 16532 0x8C3A 谺 (<CJK Ideograph>) 16533 0x8C3B 谻 (<CJK Ideograph>) 16534 0x8C3C 谼 (<CJK Ideograph>) 16535 0x8C3D 谽 (<CJK Ideograph>) 16536 0x8C3E 谾 (<CJK Ideograph>) 16537 0x8C3F 谿 (<CJK Ideograph>) 16538 0x8C40 豀 (<CJK Ideograph>) 16539 0x8C42 豂 (<CJK Ideograph>) 16540 0x8C43 豃 (<CJK Ideograph>) 16541 0x8C44 豄 (<CJK Ideograph>) 16542 0x8C45 豅 (<CJK Ideograph>) 16543 0x8C48 豈 (<CJK Ideograph>) 16544 0x8C4A 豊 (<CJK Ideograph>) 16545 0x8C4B 豋 (<CJK Ideograph>) 16546 0x8C4D 豍 (<CJK Ideograph>) 16547 0x8C4E 豎 (<CJK Ideograph>) 16548 0x8C4F 豏 (<CJK Ideograph>) 16549 0x8C50 豐 (<CJK Ideograph>) 16550 0x8C51 豑 (<CJK Ideograph>) 16551 0x8C52 豒 (<CJK Ideograph>) 16552 0x8C53 豓 (<CJK Ideograph>) 16553 0x8C54 豔 (<CJK Ideograph>) 16554 0x8C56 豖 (<CJK Ideograph>) 16555 0x8C57 豗 (<CJK Ideograph>) 16556 0x8C58 豘 (<CJK Ideograph>) 16557 0x8C59 豙 (<CJK Ideograph>) 16558 0x8C5B 豛 (<CJK Ideograph>) 16559 0x8C5C 豜 (<CJK Ideograph>) 16560 0x8C5D 豝 (<CJK Ideograph>) 16561 0x8C5E 豞 (<CJK Ideograph>) 16562 0x8C5F 豟 (<CJK Ideograph>) 16563 0x8C60 豠 (<CJK Ideograph>) 16564 0x8C63 豣 (<CJK Ideograph>) 16565 0x8C64 豤 (<CJK Ideograph>) 16566 0x8C65 豥 (<CJK Ideograph>) 16567 0x8C66 豦 (<CJK Ideograph>) 16568 0x8C67 豧 (<CJK Ideograph>) 16569 0x8C68 豨 (<CJK Ideograph>) 16570 0x8C69 豩 (<CJK Ideograph>) 16571 0x8C6C 豬 (<CJK Ideograph>) 16572 0x8C6D 豭 (<CJK Ideograph>) 16573 0x8C6E 豮 (<CJK Ideograph>) 16574 0x8C6F 豯 (<CJK Ideograph>) 16575 0x8C70 豰 (<CJK Ideograph>) 16576 0x8C71 豱 (<CJK Ideograph>) 16577 0x8C72 豲 (<CJK Ideograph>) 16578 0x8C74 豴 (<CJK Ideograph>) 16579 0x8C75 豵 (<CJK Ideograph>) 16580 0x8C76 豶 (<CJK Ideograph>) 16581 0x8C77 豷 (<CJK Ideograph>) 16582 0x8C7B 豻 (<CJK Ideograph>) 16583 0x8C7C 豼 (<CJK Ideograph>) 16584 0x8C7D 豽 (<CJK Ideograph>) 16585 0x8C7E 豾 (<CJK Ideograph>) 16586 0x8C7F 豿 (<CJK Ideograph>) 16587 0x8C80 貀 (<CJK Ideograph>) 16588 0x8C81 貁 (<CJK Ideograph>) 16589 0x8C83 貃 (<CJK Ideograph>) 16590 0x8C84 貄 (<CJK Ideograph>) 16591 0x8C86 貆 (<CJK Ideograph>) 16592 0x8C87 貇 (<CJK Ideograph>) 16593 0x8C88 貈 (<CJK Ideograph>) 16594 0x8C8B 貋 (<CJK Ideograph>) 16595 0x8C8D 貍 (<CJK Ideograph>) 16596 0x8C8E 貎 (<CJK Ideograph>) 16597 0x8C8F 貏 (<CJK Ideograph>) 16598 0x8C90 貐 (<CJK Ideograph>) 16599 0x8C91 貑 (<CJK Ideograph>) 16600 0x8C92 貒 (<CJK Ideograph>) 16601 0x8C93 貓 (<CJK Ideograph>) 16602 0x8C95 貕 (<CJK Ideograph>) 16603 0x8C96 貖 (<CJK Ideograph>) 16604 0x8C97 貗 (<CJK Ideograph>) 16605 0x8C99 貙 (<CJK Ideograph>) 16606 0x8C9A 貚 (<CJK Ideograph>) 16607 0x8C9B 貛 (<CJK Ideograph>) 16608 0x8C9C 貜 (<CJK Ideograph>) 16609 0x8C9D 貝 (<CJK Ideograph>) 16610 0x8C9E 貞 (<CJK Ideograph>) 16611 0x8C9F 貟 (<CJK Ideograph>) 16612 0x8CA0 負 (<CJK Ideograph>) 16613 0x8CA1 財 (<CJK Ideograph>) 16614 0x8CA2 貢 (<CJK Ideograph>) 16615 0x8CA3 貣 (<CJK Ideograph>) 16616 0x8CA4 貤 (<CJK Ideograph>) 16617 0x8CA5 貥 (<CJK Ideograph>) 16618 0x8CA6 貦 (<CJK Ideograph>) 16619 0x8CA7 貧 (<CJK Ideograph>) 16620 0x8CA8 貨 (<CJK Ideograph>) 16621 0x8CA9 販 (<CJK Ideograph>) 16622 0x8CAA 貪 (<CJK Ideograph>) 16623 0x8CAB 貫 (<CJK Ideograph>) 16624 0x8CAC 責 (<CJK Ideograph>) 16625 0x8CAD 貭 (<CJK Ideograph>) 16626 0x4E8D 亍 (<CJK Ideograph>) 16627 0x4E0C 丌 (<CJK Ideograph>) 16628 0x5140 兀 (<CJK Ideograph>) 16629 0x4E10 丐 (<CJK Ideograph>) 16630 0x5EFF 廿 (<CJK Ideograph>) 16631 0x5345 卅 (<CJK Ideograph>) 16632 0x4E15 丕 (<CJK Ideograph>) 16633 0x4E98 亘 (<CJK Ideograph>) 16634 0x4E1E 丞 (<CJK Ideograph>) 16635 0x9B32 鬲 (<CJK Ideograph>) 16636 0x5B6C 孬 (<CJK Ideograph>) 16637 0x5669 噩 (<CJK Ideograph>) 16638 0x4E28 丨 (<CJK Ideograph>) 16639 0x79BA 禺 (<CJK Ideograph>) 16640 0x4E3F 丿 (<CJK Ideograph>) 16641 0x5315 匕 (<CJK Ideograph>) 16642 0x4E47 乇 (<CJK Ideograph>) 16643 0x592D 夭 (<CJK Ideograph>) 16644 0x723B 爻 (<CJK Ideograph>) 16645 0x536E 卮 (<CJK Ideograph>) 16646 0x6C10 氐 (<CJK Ideograph>) 16647 0x56DF 囟 (<CJK Ideograph>) 16648 0x80E4 胤 (<CJK Ideograph>) 16649 0x9997 馗 (<CJK Ideograph>) 16650 0x6BD3 毓 (<CJK Ideograph>) 16651 0x777E 睾 (<CJK Ideograph>) 16652 0x9F17 鼗 (<CJK Ideograph>) 16653 0x4E36 丶 (<CJK Ideograph>) 16654 0x4E9F 亟 (<CJK Ideograph>) 16655 0x9F10 鼐 (<CJK Ideograph>) 16656 0x4E5C 乜 (<CJK Ideograph>) 16657 0x4E69 乩 (<CJK Ideograph>) 16658 0x4E93 亓 (<CJK Ideograph>) 16659 0x8288 芈 (<CJK Ideograph>) 16660 0x5B5B 孛 (<CJK Ideograph>) 16661 0x556C 啬 (<CJK Ideograph>) 16662 0x560F 嘏 (<CJK Ideograph>) 16663 0x4EC4 仄 (<CJK Ideograph>) 16664 0x538D 厍 (<CJK Ideograph>) 16665 0x539D 厝 (<CJK Ideograph>) 16666 0x53A3 厣 (<CJK Ideograph>) 16667 0x53A5 厥 (<CJK Ideograph>) 16668 0x53AE 厮 (<CJK Ideograph>) 16669 0x9765 靥 (<CJK Ideograph>) 16670 0x8D5D 赝 (<CJK Ideograph>) 16671 0x531A 匚 (<CJK Ideograph>) 16672 0x53F5 叵 (<CJK Ideograph>) 16673 0x5326 匦 (<CJK Ideograph>) 16674 0x532E 匮 (<CJK Ideograph>) 16675 0x533E 匾 (<CJK Ideograph>) 16676 0x8D5C 赜 (<CJK Ideograph>) 16677 0x5366 卦 (<CJK Ideograph>) 16678 0x5363 卣 (<CJK Ideograph>) 16679 0x5202 刂 (<CJK Ideograph>) 16680 0x5208 刈 (<CJK Ideograph>) 16681 0x520E 刎 (<CJK Ideograph>) 16682 0x522D 刭 (<CJK Ideograph>) 16683 0x5233 刳 (<CJK Ideograph>) 16684 0x523F 刿 (<CJK Ideograph>) 16685 0x5240 剀 (<CJK Ideograph>) 16686 0x524C 剌 (<CJK Ideograph>) 16687 0x525E 剞 (<CJK Ideograph>) 16688 0x5261 剡 (<CJK Ideograph>) 16689 0x525C 剜 (<CJK Ideograph>) 16690 0x84AF 蒯 (<CJK Ideograph>) 16691 0x527D 剽 (<CJK Ideograph>) 16692 0x5282 劂 (<CJK Ideograph>) 16693 0x5281 劁 (<CJK Ideograph>) 16694 0x5290 劐 (<CJK Ideograph>) 16695 0x5293 劓 (<CJK Ideograph>) 16696 0x5182 冂 (<CJK Ideograph>) 16697 0x7F54 罔 (<CJK Ideograph>) 16698 0x4EBB 亻 (<CJK Ideograph>) 16699 0x4EC3 仃 (<CJK Ideograph>) 16700 0x4EC9 仉 (<CJK Ideograph>) 16701 0x4EC2 仂 (<CJK Ideograph>) 16702 0x4EE8 仨 (<CJK Ideograph>) 16703 0x4EE1 仡 (<CJK Ideograph>) 16704 0x4EEB 仫 (<CJK Ideograph>) 16705 0x4EDE 仞 (<CJK Ideograph>) 16706 0x4F1B 伛 (<CJK Ideograph>) 16707 0x4EF3 仳 (<CJK Ideograph>) 16708 0x4F22 伢 (<CJK Ideograph>) 16709 0x4F64 佤 (<CJK Ideograph>) 16710 0x4EF5 仵 (<CJK Ideograph>) 16711 0x4F25 伥 (<CJK Ideograph>) 16712 0x4F27 伧 (<CJK Ideograph>) 16713 0x4F09 伉 (<CJK Ideograph>) 16714 0x4F2B 伫 (<CJK Ideograph>) 16715 0x4F5E 佞 (<CJK Ideograph>) 16716 0x4F67 佧 (<CJK Ideograph>) 16717 0x6538 攸 (<CJK Ideograph>) 16718 0x4F5A 佚 (<CJK Ideograph>) 16719 0x4F5D 佝 (<CJK Ideograph>) 16720 0x8CAE 貮 (<CJK Ideograph>) 16721 0x8CAF 貯 (<CJK Ideograph>) 16722 0x8CB0 貰 (<CJK Ideograph>) 16723 0x8CB1 貱 (<CJK Ideograph>) 16724 0x8CB2 貲 (<CJK Ideograph>) 16725 0x8CB3 貳 (<CJK Ideograph>) 16726 0x8CB4 貴 (<CJK Ideograph>) 16727 0x8CB5 貵 (<CJK Ideograph>) 16728 0x8CB6 貶 (<CJK Ideograph>) 16729 0x8CB7 買 (<CJK Ideograph>) 16730 0x8CB8 貸 (<CJK Ideograph>) 16731 0x8CB9 貹 (<CJK Ideograph>) 16732 0x8CBA 貺 (<CJK Ideograph>) 16733 0x8CBB 費 (<CJK Ideograph>) 16734 0x8CBC 貼 (<CJK Ideograph>) 16735 0x8CBD 貽 (<CJK Ideograph>) 16736 0x8CBE 貾 (<CJK Ideograph>) 16737 0x8CBF 貿 (<CJK Ideograph>) 16738 0x8CC0 賀 (<CJK Ideograph>) 16739 0x8CC1 賁 (<CJK Ideograph>) 16740 0x8CC2 賂 (<CJK Ideograph>) 16741 0x8CC3 賃 (<CJK Ideograph>) 16742 0x8CC4 賄 (<CJK Ideograph>) 16743 0x8CC5 賅 (<CJK Ideograph>) 16744 0x8CC6 賆 (<CJK Ideograph>) 16745 0x8CC7 資 (<CJK Ideograph>) 16746 0x8CC8 賈 (<CJK Ideograph>) 16747 0x8CC9 賉 (<CJK Ideograph>) 16748 0x8CCA 賊 (<CJK Ideograph>) 16749 0x8CCB 賋 (<CJK Ideograph>) 16750 0x8CCC 賌 (<CJK Ideograph>) 16751 0x8CCD 賍 (<CJK Ideograph>) 16752 0x8CCE 賎 (<CJK Ideograph>) 16753 0x8CCF 賏 (<CJK Ideograph>) 16754 0x8CD0 賐 (<CJK Ideograph>) 16755 0x8CD1 賑 (<CJK Ideograph>) 16756 0x8CD2 賒 (<CJK Ideograph>) 16757 0x8CD3 賓 (<CJK Ideograph>) 16758 0x8CD4 賔 (<CJK Ideograph>) 16759 0x8CD5 賕 (<CJK Ideograph>) 16760 0x8CD6 賖 (<CJK Ideograph>) 16761 0x8CD7 賗 (<CJK Ideograph>) 16762 0x8CD8 賘 (<CJK Ideograph>) 16763 0x8CD9 賙 (<CJK Ideograph>) 16764 0x8CDA 賚 (<CJK Ideograph>) 16765 0x8CDB 賛 (<CJK Ideograph>) 16766 0x8CDC 賜 (<CJK Ideograph>) 16767 0x8CDD 賝 (<CJK Ideograph>) 16768 0x8CDE 賞 (<CJK Ideograph>) 16769 0x8CDF 賟 (<CJK Ideograph>) 16770 0x8CE0 賠 (<CJK Ideograph>) 16771 0x8CE1 賡 (<CJK Ideograph>) 16772 0x8CE2 賢 (<CJK Ideograph>) 16773 0x8CE3 賣 (<CJK Ideograph>) 16774 0x8CE4 賤 (<CJK Ideograph>) 16775 0x8CE5 賥 (<CJK Ideograph>) 16776 0x8CE6 賦 (<CJK Ideograph>) 16777 0x8CE7 賧 (<CJK Ideograph>) 16778 0x8CE8 賨 (<CJK Ideograph>) 16779 0x8CE9 賩 (<CJK Ideograph>) 16780 0x8CEA 質 (<CJK Ideograph>) 16781 0x8CEB 賫 (<CJK Ideograph>) 16782 0x8CEC 賬 (<CJK Ideograph>) 16783 0x8CED 賭 (<CJK Ideograph>) 16784 0x8CEE 賮 (<CJK Ideograph>) 16785 0x8CEF 賯 (<CJK Ideograph>) 16786 0x8CF0 賰 (<CJK Ideograph>) 16787 0x8CF1 賱 (<CJK Ideograph>) 16788 0x8CF2 賲 (<CJK Ideograph>) 16789 0x8CF3 賳 (<CJK Ideograph>) 16790 0x8CF4 賴 (<CJK Ideograph>) 16791 0x8CF5 賵 (<CJK Ideograph>) 16792 0x8CF6 賶 (<CJK Ideograph>) 16793 0x8CF7 賷 (<CJK Ideograph>) 16794 0x8CF8 賸 (<CJK Ideograph>) 16795 0x8CF9 賹 (<CJK Ideograph>) 16796 0x8CFA 賺 (<CJK Ideograph>) 16797 0x8CFB 賻 (<CJK Ideograph>) 16798 0x8CFC 購 (<CJK Ideograph>) 16799 0x8CFD 賽 (<CJK Ideograph>) 16800 0x8CFE 賾 (<CJK Ideograph>) 16801 0x8CFF 賿 (<CJK Ideograph>) 16802 0x8D00 贀 (<CJK Ideograph>) 16803 0x8D01 贁 (<CJK Ideograph>) 16804 0x8D02 贂 (<CJK Ideograph>) 16805 0x8D03 贃 (<CJK Ideograph>) 16806 0x8D04 贄 (<CJK Ideograph>) 16807 0x8D05 贅 (<CJK Ideograph>) 16808 0x8D06 贆 (<CJK Ideograph>) 16809 0x8D07 贇 (<CJK Ideograph>) 16810 0x8D08 贈 (<CJK Ideograph>) 16811 0x8D09 贉 (<CJK Ideograph>) 16812 0x8D0A 贊 (<CJK Ideograph>) 16813 0x8D0B 贋 (<CJK Ideograph>) 16814 0x8D0C 贌 (<CJK Ideograph>) 16815 0x8D0D 贍 (<CJK Ideograph>) 16816 0x4F5F 佟 (<CJK Ideograph>) 16817 0x4F57 佗 (<CJK Ideograph>) 16818 0x4F32 伲 (<CJK Ideograph>) 16819 0x4F3D 伽 (<CJK Ideograph>) 16820 0x4F76 佶 (<CJK Ideograph>) 16821 0x4F74 佴 (<CJK Ideograph>) 16822 0x4F91 侑 (<CJK Ideograph>) 16823 0x4F89 侉 (<CJK Ideograph>) 16824 0x4F83 侃 (<CJK Ideograph>) 16825 0x4F8F 侏 (<CJK Ideograph>) 16826 0x4F7E 佾 (<CJK Ideograph>) 16827 0x4F7B 佻 (<CJK Ideograph>) 16828 0x4FAA 侪 (<CJK Ideograph>) 16829 0x4F7C 佼 (<CJK Ideograph>) 16830 0x4FAC 侬 (<CJK Ideograph>) 16831 0x4F94 侔 (<CJK Ideograph>) 16832 0x4FE6 俦 (<CJK Ideograph>) 16833 0x4FE8 俨 (<CJK Ideograph>) 16834 0x4FEA 俪 (<CJK Ideograph>) 16835 0x4FC5 俅 (<CJK Ideograph>) 16836 0x4FDA 俚 (<CJK Ideograph>) 16837 0x4FE3 俣 (<CJK Ideograph>) 16838 0x4FDC 俜 (<CJK Ideograph>) 16839 0x4FD1 俑 (<CJK Ideograph>) 16840 0x4FDF 俟 (<CJK Ideograph>) 16841 0x4FF8 俸 (<CJK Ideograph>) 16842 0x5029 倩 (<CJK Ideograph>) 16843 0x504C 偌 (<CJK Ideograph>) 16844 0x4FF3 俳 (<CJK Ideograph>) 16845 0x502C 倬 (<CJK Ideograph>) 16846 0x500F 倏 (<CJK Ideograph>) 16847 0x502E 倮 (<CJK Ideograph>) 16848 0x502D 倭 (<CJK Ideograph>) 16849 0x4FFE 俾 (<CJK Ideograph>) 16850 0x501C 倜 (<CJK Ideograph>) 16851 0x500C 倌 (<CJK Ideograph>) 16852 0x5025 倥 (<CJK Ideograph>) 16853 0x5028 倨 (<CJK Ideograph>) 16854 0x507E 偾 (<CJK Ideograph>) 16855 0x5043 偃 (<CJK Ideograph>) 16856 0x5055 偕 (<CJK Ideograph>) 16857 0x5048 偈 (<CJK Ideograph>) 16858 0x504E 偎 (<CJK Ideograph>) 16859 0x506C 偬 (<CJK Ideograph>) 16860 0x507B 偻 (<CJK Ideograph>) 16861 0x50A5 傥 (<CJK Ideograph>) 16862 0x50A7 傧 (<CJK Ideograph>) 16863 0x50A9 傩 (<CJK Ideograph>) 16864 0x50BA 傺 (<CJK Ideograph>) 16865 0x50D6 僖 (<CJK Ideograph>) 16866 0x5106 儆 (<CJK Ideograph>) 16867 0x50ED 僭 (<CJK Ideograph>) 16868 0x50EC 僬 (<CJK Ideograph>) 16869 0x50E6 僦 (<CJK Ideograph>) 16870 0x50EE 僮 (<CJK Ideograph>) 16871 0x5107 儇 (<CJK Ideograph>) 16872 0x510B 儋 (<CJK Ideograph>) 16873 0x4EDD 仝 (<CJK Ideograph>) 16874 0x6C3D 氽 (<CJK Ideograph>) 16875 0x4F58 佘 (<CJK Ideograph>) 16876 0x4F65 佥 (<CJK Ideograph>) 16877 0x4FCE 俎 (<CJK Ideograph>) 16878 0x9FA0 龠 (<CJK Ideograph>) 16879 0x6C46 汆 (<CJK Ideograph>) 16880 0x7C74 籴 (<CJK Ideograph>) 16881 0x516E 兮 (<CJK Ideograph>) 16882 0x5DFD 巽 (<CJK Ideograph>) 16883 0x9EC9 黉 (<CJK Ideograph>) 16884 0x9998 馘 (<CJK Ideograph>) 16885 0x5181 冁 (<CJK Ideograph>) 16886 0x5914 夔 (<CJK Ideograph>) 16887 0x52F9 勹 (<CJK Ideograph>) 16888 0x530D 匍 (<CJK Ideograph>) 16889 0x8A07 訇 (<CJK Ideograph>) 16890 0x5310 匐 (<CJK Ideograph>) 16891 0x51EB 凫 (<CJK Ideograph>) 16892 0x5919 夙 (<CJK Ideograph>) 16893 0x5155 兕 (<CJK Ideograph>) 16894 0x4EA0 亠 (<CJK Ideograph>) 16895 0x5156 兖 (<CJK Ideograph>) 16896 0x4EB3 亳 (<CJK Ideograph>) 16897 0x886E 衮 (<CJK Ideograph>) 16898 0x88A4 袤 (<CJK Ideograph>) 16899 0x4EB5 亵 (<CJK Ideograph>) 16900 0x8114 脔 (<CJK Ideograph>) 16901 0x88D2 裒 (<CJK Ideograph>) 16902 0x7980 禀 (<CJK Ideograph>) 16903 0x5B34 嬴 (<CJK Ideograph>) 16904 0x8803 蠃 (<CJK Ideograph>) 16905 0x7FB8 羸 (<CJK Ideograph>) 16906 0x51AB 冫 (<CJK Ideograph>) 16907 0x51B1 冱 (<CJK Ideograph>) 16908 0x51BD 冽 (<CJK Ideograph>) 16909 0x51BC 冼 (<CJK Ideograph>) 16910 0x8D0E 贎 (<CJK Ideograph>) 16911 0x8D0F 贏 (<CJK Ideograph>) 16912 0x8D10 贐 (<CJK Ideograph>) 16913 0x8D11 贑 (<CJK Ideograph>) 16914 0x8D12 贒 (<CJK Ideograph>) 16915 0x8D13 贓 (<CJK Ideograph>) 16916 0x8D14 贔 (<CJK Ideograph>) 16917 0x8D15 贕 (<CJK Ideograph>) 16918 0x8D16 贖 (<CJK Ideograph>) 16919 0x8D17 贗 (<CJK Ideograph>) 16920 0x8D18 贘 (<CJK Ideograph>) 16921 0x8D19 贙 (<CJK Ideograph>) 16922 0x8D1A 贚 (<CJK Ideograph>) 16923 0x8D1B 贛 (<CJK Ideograph>) 16924 0x8D1C 贜 (<CJK Ideograph>) 16925 0x8D20 贠 (<CJK Ideograph>) 16926 0x8D51 赑 (<CJK Ideograph>) 16927 0x8D52 赒 (<CJK Ideograph>) 16928 0x8D57 赗 (<CJK Ideograph>) 16929 0x8D5F 赟 (<CJK Ideograph>) 16930 0x8D65 赥 (<CJK Ideograph>) 16931 0x8D68 赨 (<CJK Ideograph>) 16932 0x8D69 赩 (<CJK Ideograph>) 16933 0x8D6A 赪 (<CJK Ideograph>) 16934 0x8D6C 赬 (<CJK Ideograph>) 16935 0x8D6E 赮 (<CJK Ideograph>) 16936 0x8D6F 赯 (<CJK Ideograph>) 16937 0x8D71 赱 (<CJK Ideograph>) 16938 0x8D72 赲 (<CJK Ideograph>) 16939 0x8D78 赸 (<CJK Ideograph>) 16940 0x8D79 赹 (<CJK Ideograph>) 16941 0x8D7A 赺 (<CJK Ideograph>) 16942 0x8D7B 赻 (<CJK Ideograph>) 16943 0x8D7C 赼 (<CJK Ideograph>) 16944 0x8D7D 赽 (<CJK Ideograph>) 16945 0x8D7E 赾 (<CJK Ideograph>) 16946 0x8D7F 赿 (<CJK Ideograph>) 16947 0x8D80 趀 (<CJK Ideograph>) 16948 0x8D82 趂 (<CJK Ideograph>) 16949 0x8D83 趃 (<CJK Ideograph>) 16950 0x8D86 趆 (<CJK Ideograph>) 16951 0x8D87 趇 (<CJK Ideograph>) 16952 0x8D88 趈 (<CJK Ideograph>) 16953 0x8D89 趉 (<CJK Ideograph>) 16954 0x8D8C 趌 (<CJK Ideograph>) 16955 0x8D8D 趍 (<CJK Ideograph>) 16956 0x8D8E 趎 (<CJK Ideograph>) 16957 0x8D8F 趏 (<CJK Ideograph>) 16958 0x8D90 趐 (<CJK Ideograph>) 16959 0x8D92 趒 (<CJK Ideograph>) 16960 0x8D93 趓 (<CJK Ideograph>) 16961 0x8D95 趕 (<CJK Ideograph>) 16962 0x8D96 趖 (<CJK Ideograph>) 16963 0x8D97 趗 (<CJK Ideograph>) 16964 0x8D98 趘 (<CJK Ideograph>) 16965 0x8D99 趙 (<CJK Ideograph>) 16966 0x8D9A 趚 (<CJK Ideograph>) 16967 0x8D9B 趛 (<CJK Ideograph>) 16968 0x8D9C 趜 (<CJK Ideograph>) 16969 0x8D9D 趝 (<CJK Ideograph>) 16970 0x8D9E 趞 (<CJK Ideograph>) 16971 0x8DA0 趠 (<CJK Ideograph>) 16972 0x8DA1 趡 (<CJK Ideograph>) 16973 0x8DA2 趢 (<CJK Ideograph>) 16974 0x8DA4 趤 (<CJK Ideograph>) 16975 0x8DA5 趥 (<CJK Ideograph>) 16976 0x8DA6 趦 (<CJK Ideograph>) 16977 0x8DA7 趧 (<CJK Ideograph>) 16978 0x8DA8 趨 (<CJK Ideograph>) 16979 0x8DA9 趩 (<CJK Ideograph>) 16980 0x8DAA 趪 (<CJK Ideograph>) 16981 0x8DAB 趫 (<CJK Ideograph>) 16982 0x8DAC 趬 (<CJK Ideograph>) 16983 0x8DAD 趭 (<CJK Ideograph>) 16984 0x8DAE 趮 (<CJK Ideograph>) 16985 0x8DAF 趯 (<CJK Ideograph>) 16986 0x8DB0 趰 (<CJK Ideograph>) 16987 0x8DB2 趲 (<CJK Ideograph>) 16988 0x8DB6 趶 (<CJK Ideograph>) 16989 0x8DB7 趷 (<CJK Ideograph>) 16990 0x8DB9 趹 (<CJK Ideograph>) 16991 0x8DBB 趻 (<CJK Ideograph>) 16992 0x8DBD 趽 (<CJK Ideograph>) 16993 0x8DC0 跀 (<CJK Ideograph>) 16994 0x8DC1 跁 (<CJK Ideograph>) 16995 0x8DC2 跂 (<CJK Ideograph>) 16996 0x8DC5 跅 (<CJK Ideograph>) 16997 0x8DC7 跇 (<CJK Ideograph>) 16998 0x8DC8 跈 (<CJK Ideograph>) 16999 0x8DC9 跉 (<CJK Ideograph>) 17000 0x8DCA 跊 (<CJK Ideograph>) 17001 0x8DCD 跍 (<CJK Ideograph>) 17002 0x8DD0 跐 (<CJK Ideograph>) 17003 0x8DD2 跒 (<CJK Ideograph>) 17004 0x8DD3 跓 (<CJK Ideograph>) 17005 0x8DD4 跔 (<CJK Ideograph>) 17006 0x51C7 凇 (<CJK Ideograph>) 17007 0x5196 冖 (<CJK Ideograph>) 17008 0x51A2 冢 (<CJK Ideograph>) 17009 0x51A5 冥 (<CJK Ideograph>) 17010 0x8BA0 讠 (<CJK Ideograph>) 17011 0x8BA6 讦 (<CJK Ideograph>) 17012 0x8BA7 讧 (<CJK Ideograph>) 17013 0x8BAA 讪 (<CJK Ideograph>) 17014 0x8BB4 讴 (<CJK Ideograph>) 17015 0x8BB5 讵 (<CJK Ideograph>) 17016 0x8BB7 讷 (<CJK Ideograph>) 17017 0x8BC2 诂 (<CJK Ideograph>) 17018 0x8BC3 诃 (<CJK Ideograph>) 17019 0x8BCB 诋 (<CJK Ideograph>) 17020 0x8BCF 诏 (<CJK Ideograph>) 17021 0x8BCE 诎 (<CJK Ideograph>) 17022 0x8BD2 诒 (<CJK Ideograph>) 17023 0x8BD3 诓 (<CJK Ideograph>) 17024 0x8BD4 诔 (<CJK Ideograph>) 17025 0x8BD6 诖 (<CJK Ideograph>) 17026 0x8BD8 诘 (<CJK Ideograph>) 17027 0x8BD9 诙 (<CJK Ideograph>) 17028 0x8BDC 诜 (<CJK Ideograph>) 17029 0x8BDF 诟 (<CJK Ideograph>) 17030 0x8BE0 诠 (<CJK Ideograph>) 17031 0x8BE4 诤 (<CJK Ideograph>) 17032 0x8BE8 诨 (<CJK Ideograph>) 17033 0x8BE9 诩 (<CJK Ideograph>) 17034 0x8BEE 诮 (<CJK Ideograph>) 17035 0x8BF0 诰 (<CJK Ideograph>) 17036 0x8BF3 诳 (<CJK Ideograph>) 17037 0x8BF6 诶 (<CJK Ideograph>) 17038 0x8BF9 诹 (<CJK Ideograph>) 17039 0x8BFC 诼 (<CJK Ideograph>) 17040 0x8BFF 诿 (<CJK Ideograph>) 17041 0x8C00 谀 (<CJK Ideograph>) 17042 0x8C02 谂 (<CJK Ideograph>) 17043 0x8C04 谄 (<CJK Ideograph>) 17044 0x8C07 谇 (<CJK Ideograph>) 17045 0x8C0C 谌 (<CJK Ideograph>) 17046 0x8C0F 谏 (<CJK Ideograph>) 17047 0x8C11 谑 (<CJK Ideograph>) 17048 0x8C12 谒 (<CJK Ideograph>) 17049 0x8C14 谔 (<CJK Ideograph>) 17050 0x8C15 谕 (<CJK Ideograph>) 17051 0x8C16 谖 (<CJK Ideograph>) 17052 0x8C19 谙 (<CJK Ideograph>) 17053 0x8C1B 谛 (<CJK Ideograph>) 17054 0x8C18 谘 (<CJK Ideograph>) 17055 0x8C1D 谝 (<CJK Ideograph>) 17056 0x8C1F 谟 (<CJK Ideograph>) 17057 0x8C20 谠 (<CJK Ideograph>) 17058 0x8C21 谡 (<CJK Ideograph>) 17059 0x8C25 谥 (<CJK Ideograph>) 17060 0x8C27 谧 (<CJK Ideograph>) 17061 0x8C2A 谪 (<CJK Ideograph>) 17062 0x8C2B 谫 (<CJK Ideograph>) 17063 0x8C2E 谮 (<CJK Ideograph>) 17064 0x8C2F 谯 (<CJK Ideograph>) 17065 0x8C32 谲 (<CJK Ideograph>) 17066 0x8C33 谳 (<CJK Ideograph>) 17067 0x8C35 谵 (<CJK Ideograph>) 17068 0x8C36 谶 (<CJK Ideograph>) 17069 0x5369 卩 (<CJK Ideograph>) 17070 0x537A 卺 (<CJK Ideograph>) 17071 0x961D 阝 (<CJK Ideograph>) 17072 0x9622 阢 (<CJK Ideograph>) 17073 0x9621 阡 (<CJK Ideograph>) 17074 0x9631 阱 (<CJK Ideograph>) 17075 0x962A 阪 (<CJK Ideograph>) 17076 0x963D 阽 (<CJK Ideograph>) 17077 0x963C 阼 (<CJK Ideograph>) 17078 0x9642 陂 (<CJK Ideograph>) 17079 0x9649 陉 (<CJK Ideograph>) 17080 0x9654 陔 (<CJK Ideograph>) 17081 0x965F 陟 (<CJK Ideograph>) 17082 0x9667 陧 (<CJK Ideograph>) 17083 0x966C 陬 (<CJK Ideograph>) 17084 0x9672 陲 (<CJK Ideograph>) 17085 0x9674 陴 (<CJK Ideograph>) 17086 0x9688 隈 (<CJK Ideograph>) 17087 0x968D 隍 (<CJK Ideograph>) 17088 0x9697 隗 (<CJK Ideograph>) 17089 0x96B0 隰 (<CJK Ideograph>) 17090 0x9097 邗 (<CJK Ideograph>) 17091 0x909B 邛 (<CJK Ideograph>) 17092 0x909D 邝 (<CJK Ideograph>) 17093 0x9099 邙 (<CJK Ideograph>) 17094 0x90AC 邬 (<CJK Ideograph>) 17095 0x90A1 邡 (<CJK Ideograph>) 17096 0x90B4 邴 (<CJK Ideograph>) 17097 0x90B3 邳 (<CJK Ideograph>) 17098 0x90B6 邶 (<CJK Ideograph>) 17099 0x90BA 邺 (<CJK Ideograph>) 17100 0x8DD5 跕 (<CJK Ideograph>) 17101 0x8DD8 跘 (<CJK Ideograph>) 17102 0x8DD9 跙 (<CJK Ideograph>) 17103 0x8DDC 跜 (<CJK Ideograph>) 17104 0x8DE0 跠 (<CJK Ideograph>) 17105 0x8DE1 跡 (<CJK Ideograph>) 17106 0x8DE2 跢 (<CJK Ideograph>) 17107 0x8DE5 跥 (<CJK Ideograph>) 17108 0x8DE6 跦 (<CJK Ideograph>) 17109 0x8DE7 跧 (<CJK Ideograph>) 17110 0x8DE9 跩 (<CJK Ideograph>) 17111 0x8DED 跭 (<CJK Ideograph>) 17112 0x8DEE 跮 (<CJK Ideograph>) 17113 0x8DF0 跰 (<CJK Ideograph>) 17114 0x8DF1 跱 (<CJK Ideograph>) 17115 0x8DF2 跲 (<CJK Ideograph>) 17116 0x8DF4 跴 (<CJK Ideograph>) 17117 0x8DF6 跶 (<CJK Ideograph>) 17118 0x8DFC 跼 (<CJK Ideograph>) 17119 0x8DFE 跾 (<CJK Ideograph>) 17120 0x8DFF 跿 (<CJK Ideograph>) 17121 0x8E00 踀 (<CJK Ideograph>) 17122 0x8E01 踁 (<CJK Ideograph>) 17123 0x8E02 踂 (<CJK Ideograph>) 17124 0x8E03 踃 (<CJK Ideograph>) 17125 0x8E04 踄 (<CJK Ideograph>) 17126 0x8E06 踆 (<CJK Ideograph>) 17127 0x8E07 踇 (<CJK Ideograph>) 17128 0x8E08 踈 (<CJK Ideograph>) 17129 0x8E0B 踋 (<CJK Ideograph>) 17130 0x8E0D 踍 (<CJK Ideograph>) 17131 0x8E0E 踎 (<CJK Ideograph>) 17132 0x8E10 踐 (<CJK Ideograph>) 17133 0x8E11 踑 (<CJK Ideograph>) 17134 0x8E12 踒 (<CJK Ideograph>) 17135 0x8E13 踓 (<CJK Ideograph>) 17136 0x8E15 踕 (<CJK Ideograph>) 17137 0x8E16 踖 (<CJK Ideograph>) 17138 0x8E17 踗 (<CJK Ideograph>) 17139 0x8E18 踘 (<CJK Ideograph>) 17140 0x8E19 踙 (<CJK Ideograph>) 17141 0x8E1A 踚 (<CJK Ideograph>) 17142 0x8E1B 踛 (<CJK Ideograph>) 17143 0x8E1C 踜 (<CJK Ideograph>) 17144 0x8E20 踠 (<CJK Ideograph>) 17145 0x8E21 踡 (<CJK Ideograph>) 17146 0x8E24 踤 (<CJK Ideograph>) 17147 0x8E25 踥 (<CJK Ideograph>) 17148 0x8E26 踦 (<CJK Ideograph>) 17149 0x8E27 踧 (<CJK Ideograph>) 17150 0x8E28 踨 (<CJK Ideograph>) 17151 0x8E2B 踫 (<CJK Ideograph>) 17152 0x8E2D 踭 (<CJK Ideograph>) 17153 0x8E30 踰 (<CJK Ideograph>) 17154 0x8E32 踲 (<CJK Ideograph>) 17155 0x8E33 踳 (<CJK Ideograph>) 17156 0x8E34 踴 (<CJK Ideograph>) 17157 0x8E36 踶 (<CJK Ideograph>) 17158 0x8E37 踷 (<CJK Ideograph>) 17159 0x8E38 踸 (<CJK Ideograph>) 17160 0x8E3B 踻 (<CJK Ideograph>) 17161 0x8E3C 踼 (<CJK Ideograph>) 17162 0x8E3E 踾 (<CJK Ideograph>) 17163 0x8E3F 踿 (<CJK Ideograph>) 17164 0x8E43 蹃 (<CJK Ideograph>) 17165 0x8E45 蹅 (<CJK Ideograph>) 17166 0x8E46 蹆 (<CJK Ideograph>) 17167 0x8E4C 蹌 (<CJK Ideograph>) 17168 0x8E4D 蹍 (<CJK Ideograph>) 17169 0x8E4E 蹎 (<CJK Ideograph>) 17170 0x8E4F 蹏 (<CJK Ideograph>) 17171 0x8E50 蹐 (<CJK Ideograph>) 17172 0x8E53 蹓 (<CJK Ideograph>) 17173 0x8E54 蹔 (<CJK Ideograph>) 17174 0x8E55 蹕 (<CJK Ideograph>) 17175 0x8E56 蹖 (<CJK Ideograph>) 17176 0x8E57 蹗 (<CJK Ideograph>) 17177 0x8E58 蹘 (<CJK Ideograph>) 17178 0x8E5A 蹚 (<CJK Ideograph>) 17179 0x8E5B 蹛 (<CJK Ideograph>) 17180 0x8E5C 蹜 (<CJK Ideograph>) 17181 0x8E5D 蹝 (<CJK Ideograph>) 17182 0x8E5E 蹞 (<CJK Ideograph>) 17183 0x8E5F 蹟 (<CJK Ideograph>) 17184 0x8E60 蹠 (<CJK Ideograph>) 17185 0x8E61 蹡 (<CJK Ideograph>) 17186 0x8E62 蹢 (<CJK Ideograph>) 17187 0x8E63 蹣 (<CJK Ideograph>) 17188 0x8E64 蹤 (<CJK Ideograph>) 17189 0x8E65 蹥 (<CJK Ideograph>) 17190 0x8E67 蹧 (<CJK Ideograph>) 17191 0x8E68 蹨 (<CJK Ideograph>) 17192 0x8E6A 蹪 (<CJK Ideograph>) 17193 0x8E6B 蹫 (<CJK Ideograph>) 17194 0x8E6E 蹮 (<CJK Ideograph>) 17195 0x8E71 蹱 (<CJK Ideograph>) 17196 0x90B8 邸 (<CJK Ideograph>) 17197 0x90B0 邰 (<CJK Ideograph>) 17198 0x90CF 郏 (<CJK Ideograph>) 17199 0x90C5 郅 (<CJK Ideograph>) 17200 0x90BE 邾 (<CJK Ideograph>) 17201 0x90D0 郐 (<CJK Ideograph>) 17202 0x90C4 郄 (<CJK Ideograph>) 17203 0x90C7 郇 (<CJK Ideograph>) 17204 0x90D3 郓 (<CJK Ideograph>) 17205 0x90E6 郦 (<CJK Ideograph>) 17206 0x90E2 郢 (<CJK Ideograph>) 17207 0x90DC 郜 (<CJK Ideograph>) 17208 0x90D7 郗 (<CJK Ideograph>) 17209 0x90DB 郛 (<CJK Ideograph>) 17210 0x90EB 郫 (<CJK Ideograph>) 17211 0x90EF 郯 (<CJK Ideograph>) 17212 0x90FE 郾 (<CJK Ideograph>) 17213 0x9104 鄄 (<CJK Ideograph>) 17214 0x9122 鄢 (<CJK Ideograph>) 17215 0x911E 鄞 (<CJK Ideograph>) 17216 0x9123 鄣 (<CJK Ideograph>) 17217 0x9131 鄱 (<CJK Ideograph>) 17218 0x912F 鄯 (<CJK Ideograph>) 17219 0x9139 鄹 (<CJK Ideograph>) 17220 0x9143 酃 (<CJK Ideograph>) 17221 0x9146 酆 (<CJK Ideograph>) 17222 0x520D 刍 (<CJK Ideograph>) 17223 0x5942 奂 (<CJK Ideograph>) 17224 0x52A2 劢 (<CJK Ideograph>) 17225 0x52AC 劬 (<CJK Ideograph>) 17226 0x52AD 劭 (<CJK Ideograph>) 17227 0x52BE 劾 (<CJK Ideograph>) 17228 0x54FF 哿 (<CJK Ideograph>) 17229 0x52D0 勐 (<CJK Ideograph>) 17230 0x52D6 勖 (<CJK Ideograph>) 17231 0x52F0 勰 (<CJK Ideograph>) 17232 0x53DF 叟 (<CJK Ideograph>) 17233 0x71EE 燮 (<CJK Ideograph>) 17234 0x77CD 矍 (<CJK Ideograph>) 17235 0x5EF4 廴 (<CJK Ideograph>) 17236 0x51F5 凵 (<CJK Ideograph>) 17237 0x51FC 凼 (<CJK Ideograph>) 17238 0x9B2F 鬯 (<CJK Ideograph>) 17239 0x53B6 厶 (<CJK Ideograph>) 17240 0x5F01 弁 (<CJK Ideograph>) 17241 0x755A 畚 (<CJK Ideograph>) 17242 0x5DEF 巯 (<CJK Ideograph>) 17243 0x574C 坌 (<CJK Ideograph>) 17244 0x57A9 垩 (<CJK Ideograph>) 17245 0x57A1 垡 (<CJK Ideograph>) 17246 0x587E 塾 (<CJK Ideograph>) 17247 0x58BC 墼 (<CJK Ideograph>) 17248 0x58C5 壅 (<CJK Ideograph>) 17249 0x58D1 壑 (<CJK Ideograph>) 17250 0x5729 圩 (<CJK Ideograph>) 17251 0x572C 圬 (<CJK Ideograph>) 17252 0x572A 圪 (<CJK Ideograph>) 17253 0x5733 圳 (<CJK Ideograph>) 17254 0x5739 圹 (<CJK Ideograph>) 17255 0x572E 圮 (<CJK Ideograph>) 17256 0x572F 圯 (<CJK Ideograph>) 17257 0x575C 坜 (<CJK Ideograph>) 17258 0x573B 圻 (<CJK Ideograph>) 17259 0x5742 坂 (<CJK Ideograph>) 17260 0x5769 坩 (<CJK Ideograph>) 17261 0x5785 垅 (<CJK Ideograph>) 17262 0x576B 坫 (<CJK Ideograph>) 17263 0x5786 垆 (<CJK Ideograph>) 17264 0x577C 坼 (<CJK Ideograph>) 17265 0x577B 坻 (<CJK Ideograph>) 17266 0x5768 坨 (<CJK Ideograph>) 17267 0x576D 坭 (<CJK Ideograph>) 17268 0x5776 坶 (<CJK Ideograph>) 17269 0x5773 坳 (<CJK Ideograph>) 17270 0x57AD 垭 (<CJK Ideograph>) 17271 0x57A4 垤 (<CJK Ideograph>) 17272 0x578C 垌 (<CJK Ideograph>) 17273 0x57B2 垲 (<CJK Ideograph>) 17274 0x57CF 埏 (<CJK Ideograph>) 17275 0x57A7 垧 (<CJK Ideograph>) 17276 0x57B4 垴 (<CJK Ideograph>) 17277 0x5793 垓 (<CJK Ideograph>) 17278 0x57A0 垠 (<CJK Ideograph>) 17279 0x57D5 埕 (<CJK Ideograph>) 17280 0x57D8 埘 (<CJK Ideograph>) 17281 0x57DA 埚 (<CJK Ideograph>) 17282 0x57D9 埙 (<CJK Ideograph>) 17283 0x57D2 埒 (<CJK Ideograph>) 17284 0x57B8 垸 (<CJK Ideograph>) 17285 0x57F4 埴 (<CJK Ideograph>) 17286 0x57EF 埯 (<CJK Ideograph>) 17287 0x57F8 埸 (<CJK Ideograph>) 17288 0x57E4 埤 (<CJK Ideograph>) 17289 0x57DD 埝 (<CJK Ideograph>) 17290 0x8E73 蹳 (<CJK Ideograph>) 17291 0x8E75 蹵 (<CJK Ideograph>) 17292 0x8E77 蹷 (<CJK Ideograph>) 17293 0x8E78 蹸 (<CJK Ideograph>) 17294 0x8E79 蹹 (<CJK Ideograph>) 17295 0x8E7A 蹺 (<CJK Ideograph>) 17296 0x8E7B 蹻 (<CJK Ideograph>) 17297 0x8E7D 蹽 (<CJK Ideograph>) 17298 0x8E7E 蹾 (<CJK Ideograph>) 17299 0x8E80 躀 (<CJK Ideograph>) 17300 0x8E82 躂 (<CJK Ideograph>) 17301 0x8E83 躃 (<CJK Ideograph>) 17302 0x8E84 躄 (<CJK Ideograph>) 17303 0x8E86 躆 (<CJK Ideograph>) 17304 0x8E88 躈 (<CJK Ideograph>) 17305 0x8E89 躉 (<CJK Ideograph>) 17306 0x8E8A 躊 (<CJK Ideograph>) 17307 0x8E8B 躋 (<CJK Ideograph>) 17308 0x8E8C 躌 (<CJK Ideograph>) 17309 0x8E8D 躍 (<CJK Ideograph>) 17310 0x8E8E 躎 (<CJK Ideograph>) 17311 0x8E91 躑 (<CJK Ideograph>) 17312 0x8E92 躒 (<CJK Ideograph>) 17313 0x8E93 躓 (<CJK Ideograph>) 17314 0x8E95 躕 (<CJK Ideograph>) 17315 0x8E96 躖 (<CJK Ideograph>) 17316 0x8E97 躗 (<CJK Ideograph>) 17317 0x8E98 躘 (<CJK Ideograph>) 17318 0x8E99 躙 (<CJK Ideograph>) 17319 0x8E9A 躚 (<CJK Ideograph>) 17320 0x8E9B 躛 (<CJK Ideograph>) 17321 0x8E9D 躝 (<CJK Ideograph>) 17322 0x8E9F 躟 (<CJK Ideograph>) 17323 0x8EA0 躠 (<CJK Ideograph>) 17324 0x8EA1 躡 (<CJK Ideograph>) 17325 0x8EA2 躢 (<CJK Ideograph>) 17326 0x8EA3 躣 (<CJK Ideograph>) 17327 0x8EA4 躤 (<CJK Ideograph>) 17328 0x8EA5 躥 (<CJK Ideograph>) 17329 0x8EA6 躦 (<CJK Ideograph>) 17330 0x8EA7 躧 (<CJK Ideograph>) 17331 0x8EA8 躨 (<CJK Ideograph>) 17332 0x8EA9 躩 (<CJK Ideograph>) 17333 0x8EAA 躪 (<CJK Ideograph>) 17334 0x8EAD 躭 (<CJK Ideograph>) 17335 0x8EAE 躮 (<CJK Ideograph>) 17336 0x8EB0 躰 (<CJK Ideograph>) 17337 0x8EB1 躱 (<CJK Ideograph>) 17338 0x8EB3 躳 (<CJK Ideograph>) 17339 0x8EB4 躴 (<CJK Ideograph>) 17340 0x8EB5 躵 (<CJK Ideograph>) 17341 0x8EB6 躶 (<CJK Ideograph>) 17342 0x8EB7 躷 (<CJK Ideograph>) 17343 0x8EB8 躸 (<CJK Ideograph>) 17344 0x8EB9 躹 (<CJK Ideograph>) 17345 0x8EBB 躻 (<CJK Ideograph>) 17346 0x8EBC 躼 (<CJK Ideograph>) 17347 0x8EBD 躽 (<CJK Ideograph>) 17348 0x8EBE 躾 (<CJK Ideograph>) 17349 0x8EBF 躿 (<CJK Ideograph>) 17350 0x8EC0 軀 (<CJK Ideograph>) 17351 0x8EC1 軁 (<CJK Ideograph>) 17352 0x8EC2 軂 (<CJK Ideograph>) 17353 0x8EC3 軃 (<CJK Ideograph>) 17354 0x8EC4 軄 (<CJK Ideograph>) 17355 0x8EC5 軅 (<CJK Ideograph>) 17356 0x8EC6 軆 (<CJK Ideograph>) 17357 0x8EC7 軇 (<CJK Ideograph>) 17358 0x8EC8 軈 (<CJK Ideograph>) 17359 0x8EC9 軉 (<CJK Ideograph>) 17360 0x8ECA 車 (<CJK Ideograph>) 17361 0x8ECB 軋 (<CJK Ideograph>) 17362 0x8ECC 軌 (<CJK Ideograph>) 17363 0x8ECD 軍 (<CJK Ideograph>) 17364 0x8ECF 軏 (<CJK Ideograph>) 17365 0x8ED0 軐 (<CJK Ideograph>) 17366 0x8ED1 軑 (<CJK Ideograph>) 17367 0x8ED2 軒 (<CJK Ideograph>) 17368 0x8ED3 軓 (<CJK Ideograph>) 17369 0x8ED4 軔 (<CJK Ideograph>) 17370 0x8ED5 軕 (<CJK Ideograph>) 17371 0x8ED6 軖 (<CJK Ideograph>) 17372 0x8ED7 軗 (<CJK Ideograph>) 17373 0x8ED8 軘 (<CJK Ideograph>) 17374 0x8ED9 軙 (<CJK Ideograph>) 17375 0x8EDA 軚 (<CJK Ideograph>) 17376 0x8EDB 軛 (<CJK Ideograph>) 17377 0x8EDC 軜 (<CJK Ideograph>) 17378 0x8EDD 軝 (<CJK Ideograph>) 17379 0x8EDE 軞 (<CJK Ideograph>) 17380 0x8EDF 軟 (<CJK Ideograph>) 17381 0x8EE0 軠 (<CJK Ideograph>) 17382 0x8EE1 軡 (<CJK Ideograph>) 17383 0x8EE2 転 (<CJK Ideograph>) 17384 0x8EE3 軣 (<CJK Ideograph>) 17385 0x8EE4 軤 (<CJK Ideograph>) 17386 0x580B 堋 (<CJK Ideograph>) 17387 0x580D 堍 (<CJK Ideograph>) 17388 0x57FD 埽 (<CJK Ideograph>) 17389 0x57ED 埭 (<CJK Ideograph>) 17390 0x5800 堀 (<CJK Ideograph>) 17391 0x581E 堞 (<CJK Ideograph>) 17392 0x5819 堙 (<CJK Ideograph>) 17393 0x5844 塄 (<CJK Ideograph>) 17394 0x5820 堠 (<CJK Ideograph>) 17395 0x5865 塥 (<CJK Ideograph>) 17396 0x586C 塬 (<CJK Ideograph>) 17397 0x5881 墁 (<CJK Ideograph>) 17398 0x5889 墉 (<CJK Ideograph>) 17399 0x589A 墚 (<CJK Ideograph>) 17400 0x5880 墀 (<CJK Ideograph>) 17401 0x99A8 馨 (<CJK Ideograph>) 17402 0x9F19 鼙 (<CJK Ideograph>) 17403 0x61FF 懿 (<CJK Ideograph>) 17404 0x8279 艹 (<CJK Ideograph>) 17405 0x827D 艽 (<CJK Ideograph>) 17406 0x827F 艿 (<CJK Ideograph>) 17407 0x828F 芏 (<CJK Ideograph>) 17408 0x828A 芊 (<CJK Ideograph>) 17409 0x82A8 芨 (<CJK Ideograph>) 17410 0x8284 芄 (<CJK Ideograph>) 17411 0x828E 芎 (<CJK Ideograph>) 17412 0x8291 芑 (<CJK Ideograph>) 17413 0x8297 芗 (<CJK Ideograph>) 17414 0x8299 芙 (<CJK Ideograph>) 17415 0x82AB 芫 (<CJK Ideograph>) 17416 0x82B8 芸 (<CJK Ideograph>) 17417 0x82BE 芾 (<CJK Ideograph>) 17418 0x82B0 芰 (<CJK Ideograph>) 17419 0x82C8 苈 (<CJK Ideograph>) 17420 0x82CA 苊 (<CJK Ideograph>) 17421 0x82E3 苣 (<CJK Ideograph>) 17422 0x8298 芘 (<CJK Ideograph>) 17423 0x82B7 芷 (<CJK Ideograph>) 17424 0x82AE 芮 (<CJK Ideograph>) 17425 0x82CB 苋 (<CJK Ideograph>) 17426 0x82CC 苌 (<CJK Ideograph>) 17427 0x82C1 苁 (<CJK Ideograph>) 17428 0x82A9 芩 (<CJK Ideograph>) 17429 0x82B4 芴 (<CJK Ideograph>) 17430 0x82A1 芡 (<CJK Ideograph>) 17431 0x82AA 芪 (<CJK Ideograph>) 17432 0x829F 芟 (<CJK Ideograph>) 17433 0x82C4 苄 (<CJK Ideograph>) 17434 0x82CE 苎 (<CJK Ideograph>) 17435 0x82A4 芤 (<CJK Ideograph>) 17436 0x82E1 苡 (<CJK Ideograph>) 17437 0x8309 茉 (<CJK Ideograph>) 17438 0x82F7 苷 (<CJK Ideograph>) 17439 0x82E4 苤 (<CJK Ideograph>) 17440 0x830F 茏 (<CJK Ideograph>) 17441 0x8307 茇 (<CJK Ideograph>) 17442 0x82DC 苜 (<CJK Ideograph>) 17443 0x82F4 苴 (<CJK Ideograph>) 17444 0x82D2 苒 (<CJK Ideograph>) 17445 0x82D8 苘 (<CJK Ideograph>) 17446 0x830C 茌 (<CJK Ideograph>) 17447 0x82FB 苻 (<CJK Ideograph>) 17448 0x82D3 苓 (<CJK Ideograph>) 17449 0x8311 茑 (<CJK Ideograph>) 17450 0x831A 茚 (<CJK Ideograph>) 17451 0x8306 茆 (<CJK Ideograph>) 17452 0x8314 茔 (<CJK Ideograph>) 17453 0x8315 茕 (<CJK Ideograph>) 17454 0x82E0 苠 (<CJK Ideograph>) 17455 0x82D5 苕 (<CJK Ideograph>) 17456 0x831C 茜 (<CJK Ideograph>) 17457 0x8351 荑 (<CJK Ideograph>) 17458 0x835B 荛 (<CJK Ideograph>) 17459 0x835C 荜 (<CJK Ideograph>) 17460 0x8308 茈 (<CJK Ideograph>) 17461 0x8392 莒 (<CJK Ideograph>) 17462 0x833C 茼 (<CJK Ideograph>) 17463 0x8334 茴 (<CJK Ideograph>) 17464 0x8331 茱 (<CJK Ideograph>) 17465 0x839B 莛 (<CJK Ideograph>) 17466 0x835E 荞 (<CJK Ideograph>) 17467 0x832F 茯 (<CJK Ideograph>) 17468 0x834F 荏 (<CJK Ideograph>) 17469 0x8347 荇 (<CJK Ideograph>) 17470 0x8343 荃 (<CJK Ideograph>) 17471 0x835F 荟 (<CJK Ideograph>) 17472 0x8340 荀 (<CJK Ideograph>) 17473 0x8317 茗 (<CJK Ideograph>) 17474 0x8360 荠 (<CJK Ideograph>) 17475 0x832D 茭 (<CJK Ideograph>) 17476 0x833A 茺 (<CJK Ideograph>) 17477 0x8333 茳 (<CJK Ideograph>) 17478 0x8366 荦 (<CJK Ideograph>) 17479 0x8365 荥 (<CJK Ideograph>) 17480 0x8EE5 軥 (<CJK Ideograph>) 17481 0x8EE6 軦 (<CJK Ideograph>) 17482 0x8EE7 軧 (<CJK Ideograph>) 17483 0x8EE8 軨 (<CJK Ideograph>) 17484 0x8EE9 軩 (<CJK Ideograph>) 17485 0x8EEA 軪 (<CJK Ideograph>) 17486 0x8EEB 軫 (<CJK Ideograph>) 17487 0x8EEC 軬 (<CJK Ideograph>) 17488 0x8EED 軭 (<CJK Ideograph>) 17489 0x8EEE 軮 (<CJK Ideograph>) 17490 0x8EEF 軯 (<CJK Ideograph>) 17491 0x8EF0 軰 (<CJK Ideograph>) 17492 0x8EF1 軱 (<CJK Ideograph>) 17493 0x8EF2 軲 (<CJK Ideograph>) 17494 0x8EF3 軳 (<CJK Ideograph>) 17495 0x8EF4 軴 (<CJK Ideograph>) 17496 0x8EF5 軵 (<CJK Ideograph>) 17497 0x8EF6 軶 (<CJK Ideograph>) 17498 0x8EF7 軷 (<CJK Ideograph>) 17499 0x8EF8 軸 (<CJK Ideograph>) 17500 0x8EF9 軹 (<CJK Ideograph>) 17501 0x8EFA 軺 (<CJK Ideograph>) 17502 0x8EFB 軻 (<CJK Ideograph>) 17503 0x8EFC 軼 (<CJK Ideograph>) 17504 0x8EFD 軽 (<CJK Ideograph>) 17505 0x8EFE 軾 (<CJK Ideograph>) 17506 0x8EFF 軿 (<CJK Ideograph>) 17507 0x8F00 輀 (<CJK Ideograph>) 17508 0x8F01 輁 (<CJK Ideograph>) 17509 0x8F02 輂 (<CJK Ideograph>) 17510 0x8F03 較 (<CJK Ideograph>) 17511 0x8F04 輄 (<CJK Ideograph>) 17512 0x8F05 輅 (<CJK Ideograph>) 17513 0x8F06 輆 (<CJK Ideograph>) 17514 0x8F07 輇 (<CJK Ideograph>) 17515 0x8F08 輈 (<CJK Ideograph>) 17516 0x8F09 載 (<CJK Ideograph>) 17517 0x8F0A 輊 (<CJK Ideograph>) 17518 0x8F0B 輋 (<CJK Ideograph>) 17519 0x8F0C 輌 (<CJK Ideograph>) 17520 0x8F0D 輍 (<CJK Ideograph>) 17521 0x8F0E 輎 (<CJK Ideograph>) 17522 0x8F0F 輏 (<CJK Ideograph>) 17523 0x8F10 輐 (<CJK Ideograph>) 17524 0x8F11 輑 (<CJK Ideograph>) 17525 0x8F12 輒 (<CJK Ideograph>) 17526 0x8F13 輓 (<CJK Ideograph>) 17527 0x8F14 輔 (<CJK Ideograph>) 17528 0x8F15 輕 (<CJK Ideograph>) 17529 0x8F16 輖 (<CJK Ideograph>) 17530 0x8F17 輗 (<CJK Ideograph>) 17531 0x8F18 輘 (<CJK Ideograph>) 17532 0x8F19 輙 (<CJK Ideograph>) 17533 0x8F1A 輚 (<CJK Ideograph>) 17534 0x8F1B 輛 (<CJK Ideograph>) 17535 0x8F1C 輜 (<CJK Ideograph>) 17536 0x8F1D 輝 (<CJK Ideograph>) 17537 0x8F1E 輞 (<CJK Ideograph>) 17538 0x8F1F 輟 (<CJK Ideograph>) 17539 0x8F20 輠 (<CJK Ideograph>) 17540 0x8F21 輡 (<CJK Ideograph>) 17541 0x8F22 輢 (<CJK Ideograph>) 17542 0x8F23 輣 (<CJK Ideograph>) 17543 0x8F24 輤 (<CJK Ideograph>) 17544 0x8F25 輥 (<CJK Ideograph>) 17545 0x8F26 輦 (<CJK Ideograph>) 17546 0x8F27 輧 (<CJK Ideograph>) 17547 0x8F28 輨 (<CJK Ideograph>) 17548 0x8F29 輩 (<CJK Ideograph>) 17549 0x8F2A 輪 (<CJK Ideograph>) 17550 0x8F2B 輫 (<CJK Ideograph>) 17551 0x8F2C 輬 (<CJK Ideograph>) 17552 0x8F2D 輭 (<CJK Ideograph>) 17553 0x8F2E 輮 (<CJK Ideograph>) 17554 0x8F2F 輯 (<CJK Ideograph>) 17555 0x8F30 輰 (<CJK Ideograph>) 17556 0x8F31 輱 (<CJK Ideograph>) 17557 0x8F32 輲 (<CJK Ideograph>) 17558 0x8F33 輳 (<CJK Ideograph>) 17559 0x8F34 輴 (<CJK Ideograph>) 17560 0x8F35 輵 (<CJK Ideograph>) 17561 0x8F36 輶 (<CJK Ideograph>) 17562 0x8F37 輷 (<CJK Ideograph>) 17563 0x8F38 輸 (<CJK Ideograph>) 17564 0x8F39 輹 (<CJK Ideograph>) 17565 0x8F3A 輺 (<CJK Ideograph>) 17566 0x8F3B 輻 (<CJK Ideograph>) 17567 0x8F3C 輼 (<CJK Ideograph>) 17568 0x8F3D 輽 (<CJK Ideograph>) 17569 0x8F3E 輾 (<CJK Ideograph>) 17570 0x8F3F 輿 (<CJK Ideograph>) 17571 0x8F40 轀 (<CJK Ideograph>) 17572 0x8F41 轁 (<CJK Ideograph>) 17573 0x8F42 轂 (<CJK Ideograph>) 17574 0x8F43 轃 (<CJK Ideograph>) 17575 0x8F44 轄 (<CJK Ideograph>) 17576 0x8368 荨 (<CJK Ideograph>) 17577 0x831B 茛 (<CJK Ideograph>) 17578 0x8369 荩 (<CJK Ideograph>) 17579 0x836C 荬 (<CJK Ideograph>) 17580 0x836A 荪 (<CJK Ideograph>) 17581 0x836D 荭 (<CJK Ideograph>) 17582 0x836E 荮 (<CJK Ideograph>) 17583 0x83B0 莰 (<CJK Ideograph>) 17584 0x8378 荸 (<CJK Ideograph>) 17585 0x83B3 莳 (<CJK Ideograph>) 17586 0x83B4 莴 (<CJK Ideograph>) 17587 0x83A0 莠 (<CJK Ideograph>) 17588 0x83AA 莪 (<CJK Ideograph>) 17589 0x8393 莓 (<CJK Ideograph>) 17590 0x839C 莜 (<CJK Ideograph>) 17591 0x8385 莅 (<CJK Ideograph>) 17592 0x837C 荼 (<CJK Ideograph>) 17593 0x83B6 莶 (<CJK Ideograph>) 17594 0x83A9 莩 (<CJK Ideograph>) 17595 0x837D 荽 (<CJK Ideograph>) 17596 0x83B8 莸 (<CJK Ideograph>) 17597 0x837B 荻 (<CJK Ideograph>) 17598 0x8398 莘 (<CJK Ideograph>) 17599 0x839E 莞 (<CJK Ideograph>) 17600 0x83A8 莨 (<CJK Ideograph>) 17601 0x83BA 莺 (<CJK Ideograph>) 17602 0x83BC 莼 (<CJK Ideograph>) 17603 0x83C1 菁 (<CJK Ideograph>) 17604 0x8401 萁 (<CJK Ideograph>) 17605 0x83E5 菥 (<CJK Ideograph>) 17606 0x83D8 菘 (<CJK Ideograph>) 17607 0x5807 堇 (<CJK Ideograph>) 17608 0x8418 萘 (<CJK Ideograph>) 17609 0x840B 萋 (<CJK Ideograph>) 17610 0x83DD 菝 (<CJK Ideograph>) 17611 0x83FD 菽 (<CJK Ideograph>) 17612 0x83D6 菖 (<CJK Ideograph>) 17613 0x841C 萜 (<CJK Ideograph>) 17614 0x8438 萸 (<CJK Ideograph>) 17615 0x8411 萑 (<CJK Ideograph>) 17616 0x8406 萆 (<CJK Ideograph>) 17617 0x83D4 菔 (<CJK Ideograph>) 17618 0x83DF 菟 (<CJK Ideograph>) 17619 0x840F 萏 (<CJK Ideograph>) 17620 0x8403 萃 (<CJK Ideograph>) 17621 0x83F8 菸 (<CJK Ideograph>) 17622 0x83F9 菹 (<CJK Ideograph>) 17623 0x83EA 菪 (<CJK Ideograph>) 17624 0x83C5 菅 (<CJK Ideograph>) 17625 0x83C0 菀 (<CJK Ideograph>) 17626 0x8426 萦 (<CJK Ideograph>) 17627 0x83F0 菰 (<CJK Ideograph>) 17628 0x83E1 菡 (<CJK Ideograph>) 17629 0x845C 葜 (<CJK Ideograph>) 17630 0x8451 葑 (<CJK Ideograph>) 17631 0x845A 葚 (<CJK Ideograph>) 17632 0x8459 葙 (<CJK Ideograph>) 17633 0x8473 葳 (<CJK Ideograph>) 17634 0x8487 蒇 (<CJK Ideograph>) 17635 0x8488 蒈 (<CJK Ideograph>) 17636 0x847A 葺 (<CJK Ideograph>) 17637 0x8489 蒉 (<CJK Ideograph>) 17638 0x8478 葸 (<CJK Ideograph>) 17639 0x843C 萼 (<CJK Ideograph>) 17640 0x8446 葆 (<CJK Ideograph>) 17641 0x8469 葩 (<CJK Ideograph>) 17642 0x8476 葶 (<CJK Ideograph>) 17643 0x848C 蒌 (<CJK Ideograph>) 17644 0x848E 蒎 (<CJK Ideograph>) 17645 0x8431 萱 (<CJK Ideograph>) 17646 0x846D 葭 (<CJK Ideograph>) 17647 0x84C1 蓁 (<CJK Ideograph>) 17648 0x84CD 蓍 (<CJK Ideograph>) 17649 0x84D0 蓐 (<CJK Ideograph>) 17650 0x84E6 蓦 (<CJK Ideograph>) 17651 0x84BD 蒽 (<CJK Ideograph>) 17652 0x84D3 蓓 (<CJK Ideograph>) 17653 0x84CA 蓊 (<CJK Ideograph>) 17654 0x84BF 蒿 (<CJK Ideograph>) 17655 0x84BA 蒺 (<CJK Ideograph>) 17656 0x84E0 蓠 (<CJK Ideograph>) 17657 0x84A1 蒡 (<CJK Ideograph>) 17658 0x84B9 蒹 (<CJK Ideograph>) 17659 0x84B4 蒴 (<CJK Ideograph>) 17660 0x8497 蒗 (<CJK Ideograph>) 17661 0x84E5 蓥 (<CJK Ideograph>) 17662 0x84E3 蓣 (<CJK Ideograph>) 17663 0x850C 蔌 (<CJK Ideograph>) 17664 0x750D 甍 (<CJK Ideograph>) 17665 0x8538 蔸 (<CJK Ideograph>) 17666 0x84F0 蓰 (<CJK Ideograph>) 17667 0x8539 蔹 (<CJK Ideograph>) 17668 0x851F 蔟 (<CJK Ideograph>) 17669 0x853A 蔺 (<CJK Ideograph>) 17670 0x8F45 轅 (<CJK Ideograph>) 17671 0x8F46 轆 (<CJK Ideograph>) 17672 0x8F47 轇 (<CJK Ideograph>) 17673 0x8F48 轈 (<CJK Ideograph>) 17674 0x8F49 轉 (<CJK Ideograph>) 17675 0x8F4A 轊 (<CJK Ideograph>) 17676 0x8F4B 轋 (<CJK Ideograph>) 17677 0x8F4C 轌 (<CJK Ideograph>) 17678 0x8F4D 轍 (<CJK Ideograph>) 17679 0x8F4E 轎 (<CJK Ideograph>) 17680 0x8F4F 轏 (<CJK Ideograph>) 17681 0x8F50 轐 (<CJK Ideograph>) 17682 0x8F51 轑 (<CJK Ideograph>) 17683 0x8F52 轒 (<CJK Ideograph>) 17684 0x8F53 轓 (<CJK Ideograph>) 17685 0x8F54 轔 (<CJK Ideograph>) 17686 0x8F55 轕 (<CJK Ideograph>) 17687 0x8F56 轖 (<CJK Ideograph>) 17688 0x8F57 轗 (<CJK Ideograph>) 17689 0x8F58 轘 (<CJK Ideograph>) 17690 0x8F59 轙 (<CJK Ideograph>) 17691 0x8F5A 轚 (<CJK Ideograph>) 17692 0x8F5B 轛 (<CJK Ideograph>) 17693 0x8F5C 轜 (<CJK Ideograph>) 17694 0x8F5D 轝 (<CJK Ideograph>) 17695 0x8F5E 轞 (<CJK Ideograph>) 17696 0x8F5F 轟 (<CJK Ideograph>) 17697 0x8F60 轠 (<CJK Ideograph>) 17698 0x8F61 轡 (<CJK Ideograph>) 17699 0x8F62 轢 (<CJK Ideograph>) 17700 0x8F63 轣 (<CJK Ideograph>) 17701 0x8F64 轤 (<CJK Ideograph>) 17702 0x8F65 轥 (<CJK Ideograph>) 17703 0x8F6A 轪 (<CJK Ideograph>) 17704 0x8F80 辀 (<CJK Ideograph>) 17705 0x8F8C 辌 (<CJK Ideograph>) 17706 0x8F92 辒 (<CJK Ideograph>) 17707 0x8F9D 辝 (<CJK Ideograph>) 17708 0x8FA0 辠 (<CJK Ideograph>) 17709 0x8FA1 辡 (<CJK Ideograph>) 17710 0x8FA2 辢 (<CJK Ideograph>) 17711 0x8FA4 辤 (<CJK Ideograph>) 17712 0x8FA5 辥 (<CJK Ideograph>) 17713 0x8FA6 辦 (<CJK Ideograph>) 17714 0x8FA7 辧 (<CJK Ideograph>) 17715 0x8FAA 辪 (<CJK Ideograph>) 17716 0x8FAC 辬 (<CJK Ideograph>) 17717 0x8FAD 辭 (<CJK Ideograph>) 17718 0x8FAE 辮 (<CJK Ideograph>) 17719 0x8FAF 辯 (<CJK Ideograph>) 17720 0x8FB2 農 (<CJK Ideograph>) 17721 0x8FB3 辳 (<CJK Ideograph>) 17722 0x8FB4 辴 (<CJK Ideograph>) 17723 0x8FB5 辵 (<CJK Ideograph>) 17724 0x8FB7 辷 (<CJK Ideograph>) 17725 0x8FB8 辸 (<CJK Ideograph>) 17726 0x8FBA 辺 (<CJK Ideograph>) 17727 0x8FBB 辻 (<CJK Ideograph>) 17728 0x8FBC 込 (<CJK Ideograph>) 17729 0x8FBF 辿 (<CJK Ideograph>) 17730 0x8FC0 迀 (<CJK Ideograph>) 17731 0x8FC3 迃 (<CJK Ideograph>) 17732 0x8FC6 迆 (<CJK Ideograph>) 17733 0x8FC9 迉 (<CJK Ideograph>) 17734 0x8FCA 迊 (<CJK Ideograph>) 17735 0x8FCB 迋 (<CJK Ideograph>) 17736 0x8FCC 迌 (<CJK Ideograph>) 17737 0x8FCD 迍 (<CJK Ideograph>) 17738 0x8FCF 迏 (<CJK Ideograph>) 17739 0x8FD2 迒 (<CJK Ideograph>) 17740 0x8FD6 迖 (<CJK Ideograph>) 17741 0x8FD7 迗 (<CJK Ideograph>) 17742 0x8FDA 迚 (<CJK Ideograph>) 17743 0x8FE0 迠 (<CJK Ideograph>) 17744 0x8FE1 迡 (<CJK Ideograph>) 17745 0x8FE3 迣 (<CJK Ideograph>) 17746 0x8FE7 迧 (<CJK Ideograph>) 17747 0x8FEC 迬 (<CJK Ideograph>) 17748 0x8FEF 迯 (<CJK Ideograph>) 17749 0x8FF1 迱 (<CJK Ideograph>) 17750 0x8FF2 迲 (<CJK Ideograph>) 17751 0x8FF4 迴 (<CJK Ideograph>) 17752 0x8FF5 迵 (<CJK Ideograph>) 17753 0x8FF6 迶 (<CJK Ideograph>) 17754 0x8FFA 迺 (<CJK Ideograph>) 17755 0x8FFB 迻 (<CJK Ideograph>) 17756 0x8FFC 迼 (<CJK Ideograph>) 17757 0x8FFE 迾 (<CJK Ideograph>) 17758 0x8FFF 迿 (<CJK Ideograph>) 17759 0x9007 逇 (<CJK Ideograph>) 17760 0x9008 逈 (<CJK Ideograph>) 17761 0x900C 逌 (<CJK Ideograph>) 17762 0x900E 逎 (<CJK Ideograph>) 17763 0x9013 逓 (<CJK Ideograph>) 17764 0x9015 逕 (<CJK Ideograph>) 17765 0x9018 逘 (<CJK Ideograph>) 17766 0x8556 蕖 (<CJK Ideograph>) 17767 0x853B 蔻 (<CJK Ideograph>) 17768 0x84FF 蓿 (<CJK Ideograph>) 17769 0x84FC 蓼 (<CJK Ideograph>) 17770 0x8559 蕙 (<CJK Ideograph>) 17771 0x8548 蕈 (<CJK Ideograph>) 17772 0x8568 蕨 (<CJK Ideograph>) 17773 0x8564 蕤 (<CJK Ideograph>) 17774 0x855E 蕞 (<CJK Ideograph>) 17775 0x857A 蕺 (<CJK Ideograph>) 17776 0x77A2 瞢 (<CJK Ideograph>) 17777 0x8543 蕃 (<CJK Ideograph>) 17778 0x8572 蕲 (<CJK Ideograph>) 17779 0x857B 蕻 (<CJK Ideograph>) 17780 0x85A4 薤 (<CJK Ideograph>) 17781 0x85A8 薨 (<CJK Ideograph>) 17782 0x8587 薇 (<CJK Ideograph>) 17783 0x858F 薏 (<CJK Ideograph>) 17784 0x8579 蕹 (<CJK Ideograph>) 17785 0x85AE 薮 (<CJK Ideograph>) 17786 0x859C 薜 (<CJK Ideograph>) 17787 0x8585 薅 (<CJK Ideograph>) 17788 0x85B9 薹 (<CJK Ideograph>) 17789 0x85B7 薷 (<CJK Ideograph>) 17790 0x85B0 薰 (<CJK Ideograph>) 17791 0x85D3 藓 (<CJK Ideograph>) 17792 0x85C1 藁 (<CJK Ideograph>) 17793 0x85DC 藜 (<CJK Ideograph>) 17794 0x85FF 藿 (<CJK Ideograph>) 17795 0x8627 蘧 (<CJK Ideograph>) 17796 0x8605 蘅 (<CJK Ideograph>) 17797 0x8629 蘩 (<CJK Ideograph>) 17798 0x8616 蘖 (<CJK Ideograph>) 17799 0x863C 蘼 (<CJK Ideograph>) 17800 0x5EFE 廾 (<CJK Ideograph>) 17801 0x5F08 弈 (<CJK Ideograph>) 17802 0x593C 夼 (<CJK Ideograph>) 17803 0x5941 奁 (<CJK Ideograph>) 17804 0x8037 耷 (<CJK Ideograph>) 17805 0x5955 奕 (<CJK Ideograph>) 17806 0x595A 奚 (<CJK Ideograph>) 17807 0x5958 奘 (<CJK Ideograph>) 17808 0x530F 匏 (<CJK Ideograph>) 17809 0x5C22 尢 (<CJK Ideograph>) 17810 0x5C25 尥 (<CJK Ideograph>) 17811 0x5C2C 尬 (<CJK Ideograph>) 17812 0x5C34 尴 (<CJK Ideograph>) 17813 0x624C 扌 (<CJK Ideograph>) 17814 0x626A 扪 (<CJK Ideograph>) 17815 0x629F 抟 (<CJK Ideograph>) 17816 0x62BB 抻 (<CJK Ideograph>) 17817 0x62CA 拊 (<CJK Ideograph>) 17818 0x62DA 拚 (<CJK Ideograph>) 17819 0x62D7 拗 (<CJK Ideograph>) 17820 0x62EE 拮 (<CJK Ideograph>) 17821 0x6322 挢 (<CJK Ideograph>) 17822 0x62F6 拶 (<CJK Ideograph>) 17823 0x6339 挹 (<CJK Ideograph>) 17824 0x634B 捋 (<CJK Ideograph>) 17825 0x6343 捃 (<CJK Ideograph>) 17826 0x63AD 掭 (<CJK Ideograph>) 17827 0x63F6 揶 (<CJK Ideograph>) 17828 0x6371 捱 (<CJK Ideograph>) 17829 0x637A 捺 (<CJK Ideograph>) 17830 0x638E 掎 (<CJK Ideograph>) 17831 0x63B4 掴 (<CJK Ideograph>) 17832 0x636D 捭 (<CJK Ideograph>) 17833 0x63AC 掬 (<CJK Ideograph>) 17834 0x638A 掊 (<CJK Ideograph>) 17835 0x6369 捩 (<CJK Ideograph>) 17836 0x63AE 掮 (<CJK Ideograph>) 17837 0x63BC 掼 (<CJK Ideograph>) 17838 0x63F2 揲 (<CJK Ideograph>) 17839 0x63F8 揸 (<CJK Ideograph>) 17840 0x63E0 揠 (<CJK Ideograph>) 17841 0x63FF 揿 (<CJK Ideograph>) 17842 0x63C4 揄 (<CJK Ideograph>) 17843 0x63DE 揞 (<CJK Ideograph>) 17844 0x63CE 揎 (<CJK Ideograph>) 17845 0x6452 摒 (<CJK Ideograph>) 17846 0x63C6 揆 (<CJK Ideograph>) 17847 0x63BE 掾 (<CJK Ideograph>) 17848 0x6445 摅 (<CJK Ideograph>) 17849 0x6441 摁 (<CJK Ideograph>) 17850 0x640B 搋 (<CJK Ideograph>) 17851 0x641B 搛 (<CJK Ideograph>) 17852 0x6420 搠 (<CJK Ideograph>) 17853 0x640C 搌 (<CJK Ideograph>) 17854 0x6426 搦 (<CJK Ideograph>) 17855 0x6421 搡 (<CJK Ideograph>) 17856 0x645E 摞 (<CJK Ideograph>) 17857 0x6484 撄 (<CJK Ideograph>) 17858 0x646D 摭 (<CJK Ideograph>) 17859 0x6496 撖 (<CJK Ideograph>) 17860 0x9019 這 (<CJK Ideograph>) 17861 0x901C 逜 (<CJK Ideograph>) 17862 0x9023 連 (<CJK Ideograph>) 17863 0x9024 逤 (<CJK Ideograph>) 17864 0x9025 逥 (<CJK Ideograph>) 17865 0x9027 逧 (<CJK Ideograph>) 17866 0x9028 逨 (<CJK Ideograph>) 17867 0x9029 逩 (<CJK Ideograph>) 17868 0x902A 逪 (<CJK Ideograph>) 17869 0x902B 逫 (<CJK Ideograph>) 17870 0x902C 逬 (<CJK Ideograph>) 17871 0x9030 逰 (<CJK Ideograph>) 17872 0x9031 週 (<CJK Ideograph>) 17873 0x9032 進 (<CJK Ideograph>) 17874 0x9033 逳 (<CJK Ideograph>) 17875 0x9034 逴 (<CJK Ideograph>) 17876 0x9037 逷 (<CJK Ideograph>) 17877 0x9039 逹 (<CJK Ideograph>) 17878 0x903A 逺 (<CJK Ideograph>) 17879 0x903D 逽 (<CJK Ideograph>) 17880 0x903F 逿 (<CJK Ideograph>) 17881 0x9040 遀 (<CJK Ideograph>) 17882 0x9043 遃 (<CJK Ideograph>) 17883 0x9045 遅 (<CJK Ideograph>) 17884 0x9046 遆 (<CJK Ideograph>) 17885 0x9048 遈 (<CJK Ideograph>) 17886 0x9049 遉 (<CJK Ideograph>) 17887 0x904A 遊 (<CJK Ideograph>) 17888 0x904B 運 (<CJK Ideograph>) 17889 0x904C 遌 (<CJK Ideograph>) 17890 0x904E 過 (<CJK Ideograph>) 17891 0x9054 達 (<CJK Ideograph>) 17892 0x9055 違 (<CJK Ideograph>) 17893 0x9056 遖 (<CJK Ideograph>) 17894 0x9059 遙 (<CJK Ideograph>) 17895 0x905A 遚 (<CJK Ideograph>) 17896 0x905C 遜 (<CJK Ideograph>) 17897 0x905D 遝 (<CJK Ideograph>) 17898 0x905E 遞 (<CJK Ideograph>) 17899 0x905F 遟 (<CJK Ideograph>) 17900 0x9060 遠 (<CJK Ideograph>) 17901 0x9061 遡 (<CJK Ideograph>) 17902 0x9064 遤 (<CJK Ideograph>) 17903 0x9066 遦 (<CJK Ideograph>) 17904 0x9067 遧 (<CJK Ideograph>) 17905 0x9069 適 (<CJK Ideograph>) 17906 0x906A 遪 (<CJK Ideograph>) 17907 0x906B 遫 (<CJK Ideograph>) 17908 0x906C 遬 (<CJK Ideograph>) 17909 0x906F 遯 (<CJK Ideograph>) 17910 0x9070 遰 (<CJK Ideograph>) 17911 0x9071 遱 (<CJK Ideograph>) 17912 0x9072 遲 (<CJK Ideograph>) 17913 0x9073 遳 (<CJK Ideograph>) 17914 0x9076 遶 (<CJK Ideograph>) 17915 0x9077 遷 (<CJK Ideograph>) 17916 0x9078 選 (<CJK Ideograph>) 17917 0x9079 遹 (<CJK Ideograph>) 17918 0x907A 遺 (<CJK Ideograph>) 17919 0x907B 遻 (<CJK Ideograph>) 17920 0x907C 遼 (<CJK Ideograph>) 17921 0x907E 遾 (<CJK Ideograph>) 17922 0x9081 邁 (<CJK Ideograph>) 17923 0x9084 還 (<CJK Ideograph>) 17924 0x9085 邅 (<CJK Ideograph>) 17925 0x9086 邆 (<CJK Ideograph>) 17926 0x9087 邇 (<CJK Ideograph>) 17927 0x9089 邉 (<CJK Ideograph>) 17928 0x908A 邊 (<CJK Ideograph>) 17929 0x908C 邌 (<CJK Ideograph>) 17930 0x908D 邍 (<CJK Ideograph>) 17931 0x908E 邎 (<CJK Ideograph>) 17932 0x908F 邏 (<CJK Ideograph>) 17933 0x9090 邐 (<CJK Ideograph>) 17934 0x9092 邒 (<CJK Ideograph>) 17935 0x9094 邔 (<CJK Ideograph>) 17936 0x9096 邖 (<CJK Ideograph>) 17937 0x9098 邘 (<CJK Ideograph>) 17938 0x909A 邚 (<CJK Ideograph>) 17939 0x909C 邜 (<CJK Ideograph>) 17940 0x909E 邞 (<CJK Ideograph>) 17941 0x909F 邟 (<CJK Ideograph>) 17942 0x90A0 邠 (<CJK Ideograph>) 17943 0x90A4 邤 (<CJK Ideograph>) 17944 0x90A5 邥 (<CJK Ideograph>) 17945 0x90A7 邧 (<CJK Ideograph>) 17946 0x90A8 邨 (<CJK Ideograph>) 17947 0x90A9 邩 (<CJK Ideograph>) 17948 0x90AB 邫 (<CJK Ideograph>) 17949 0x90AD 邭 (<CJK Ideograph>) 17950 0x90B2 邲 (<CJK Ideograph>) 17951 0x90B7 邷 (<CJK Ideograph>) 17952 0x90BC 邼 (<CJK Ideograph>) 17953 0x90BD 邽 (<CJK Ideograph>) 17954 0x90BF 邿 (<CJK Ideograph>) 17955 0x90C0 郀 (<CJK Ideograph>) 17956 0x647A 摺 (<CJK Ideograph>) 17957 0x64B7 撷 (<CJK Ideograph>) 17958 0x64B8 撸 (<CJK Ideograph>) 17959 0x6499 撙 (<CJK Ideograph>) 17960 0x64BA 撺 (<CJK Ideograph>) 17961 0x64C0 擀 (<CJK Ideograph>) 17962 0x64D0 擐 (<CJK Ideograph>) 17963 0x64D7 擗 (<CJK Ideograph>) 17964 0x64E4 擤 (<CJK Ideograph>) 17965 0x64E2 擢 (<CJK Ideograph>) 17966 0x6509 攉 (<CJK Ideograph>) 17967 0x6525 攥 (<CJK Ideograph>) 17968 0x652E 攮 (<CJK Ideograph>) 17969 0x5F0B 弋 (<CJK Ideograph>) 17970 0x5FD2 忒 (<CJK Ideograph>) 17971 0x7519 甙 (<CJK Ideograph>) 17972 0x5F11 弑 (<CJK Ideograph>) 17973 0x535F 卟 (<CJK Ideograph>) 17974 0x53F1 叱 (<CJK Ideograph>) 17975 0x53FD 叽 (<CJK Ideograph>) 17976 0x53E9 叩 (<CJK Ideograph>) 17977 0x53E8 叨 (<CJK Ideograph>) 17978 0x53FB 叻 (<CJK Ideograph>) 17979 0x5412 吒 (<CJK Ideograph>) 17980 0x5416 吖 (<CJK Ideograph>) 17981 0x5406 吆 (<CJK Ideograph>) 17982 0x544B 呋 (<CJK Ideograph>) 17983 0x5452 呒 (<CJK Ideograph>) 17984 0x5453 呓 (<CJK Ideograph>) 17985 0x5454 呔 (<CJK Ideograph>) 17986 0x5456 呖 (<CJK Ideograph>) 17987 0x5443 呃 (<CJK Ideograph>) 17988 0x5421 吡 (<CJK Ideograph>) 17989 0x5457 呗 (<CJK Ideograph>) 17990 0x5459 呙 (<CJK Ideograph>) 17991 0x5423 吣 (<CJK Ideograph>) 17992 0x5432 吲 (<CJK Ideograph>) 17993 0x5482 咂 (<CJK Ideograph>) 17994 0x5494 咔 (<CJK Ideograph>) 17995 0x5477 呷 (<CJK Ideograph>) 17996 0x5471 呱 (<CJK Ideograph>) 17997 0x5464 呤 (<CJK Ideograph>) 17998 0x549A 咚 (<CJK Ideograph>) 17999 0x549B 咛 (<CJK Ideograph>) 18000 0x5484 咄 (<CJK Ideograph>) 18001 0x5476 呶 (<CJK Ideograph>) 18002 0x5466 呦 (<CJK Ideograph>) 18003 0x549D 咝 (<CJK Ideograph>) 18004 0x54D0 哐 (<CJK Ideograph>) 18005 0x54AD 咭 (<CJK Ideograph>) 18006 0x54C2 哂 (<CJK Ideograph>) 18007 0x54B4 咴 (<CJK Ideograph>) 18008 0x54D2 哒 (<CJK Ideograph>) 18009 0x54A7 咧 (<CJK Ideograph>) 18010 0x54A6 咦 (<CJK Ideograph>) 18011 0x54D3 哓 (<CJK Ideograph>) 18012 0x54D4 哔 (<CJK Ideograph>) 18013 0x5472 呲 (<CJK Ideograph>) 18014 0x54A3 咣 (<CJK Ideograph>) 18015 0x54D5 哕 (<CJK Ideograph>) 18016 0x54BB 咻 (<CJK Ideograph>) 18017 0x54BF 咿 (<CJK Ideograph>) 18018 0x54CC 哌 (<CJK Ideograph>) 18019 0x54D9 哙 (<CJK Ideograph>) 18020 0x54DA 哚 (<CJK Ideograph>) 18021 0x54DC 哜 (<CJK Ideograph>) 18022 0x54A9 咩 (<CJK Ideograph>) 18023 0x54AA 咪 (<CJK Ideograph>) 18024 0x54A4 咤 (<CJK Ideograph>) 18025 0x54DD 哝 (<CJK Ideograph>) 18026 0x54CF 哏 (<CJK Ideograph>) 18027 0x54DE 哞 (<CJK Ideograph>) 18028 0x551B 唛 (<CJK Ideograph>) 18029 0x54E7 哧 (<CJK Ideograph>) 18030 0x5520 唠 (<CJK Ideograph>) 18031 0x54FD 哽 (<CJK Ideograph>) 18032 0x5514 唔 (<CJK Ideograph>) 18033 0x54F3 哳 (<CJK Ideograph>) 18034 0x5522 唢 (<CJK Ideograph>) 18035 0x5523 唣 (<CJK Ideograph>) 18036 0x550F 唏 (<CJK Ideograph>) 18037 0x5511 唑 (<CJK Ideograph>) 18038 0x5527 唧 (<CJK Ideograph>) 18039 0x552A 唪 (<CJK Ideograph>) 18040 0x5567 啧 (<CJK Ideograph>) 18041 0x558F 喏 (<CJK Ideograph>) 18042 0x55B5 喵 (<CJK Ideograph>) 18043 0x5549 啉 (<CJK Ideograph>) 18044 0x556D 啭 (<CJK Ideograph>) 18045 0x5541 啁 (<CJK Ideograph>) 18046 0x5555 啕 (<CJK Ideograph>) 18047 0x553F 唿 (<CJK Ideograph>) 18048 0x5550 啐 (<CJK Ideograph>) 18049 0x553C 唼 (<CJK Ideograph>) 18050 0x90C2 郂 (<CJK Ideograph>) 18051 0x90C3 郃 (<CJK Ideograph>) 18052 0x90C6 郆 (<CJK Ideograph>) 18053 0x90C8 郈 (<CJK Ideograph>) 18054 0x90C9 郉 (<CJK Ideograph>) 18055 0x90CB 郋 (<CJK Ideograph>) 18056 0x90CC 郌 (<CJK Ideograph>) 18057 0x90CD 郍 (<CJK Ideograph>) 18058 0x90D2 郒 (<CJK Ideograph>) 18059 0x90D4 郔 (<CJK Ideograph>) 18060 0x90D5 郕 (<CJK Ideograph>) 18061 0x90D6 郖 (<CJK Ideograph>) 18062 0x90D8 郘 (<CJK Ideograph>) 18063 0x90D9 郙 (<CJK Ideograph>) 18064 0x90DA 郚 (<CJK Ideograph>) 18065 0x90DE 郞 (<CJK Ideograph>) 18066 0x90DF 郟 (<CJK Ideograph>) 18067 0x90E0 郠 (<CJK Ideograph>) 18068 0x90E3 郣 (<CJK Ideograph>) 18069 0x90E4 郤 (<CJK Ideograph>) 18070 0x90E5 郥 (<CJK Ideograph>) 18071 0x90E9 郩 (<CJK Ideograph>) 18072 0x90EA 郪 (<CJK Ideograph>) 18073 0x90EC 郬 (<CJK Ideograph>) 18074 0x90EE 郮 (<CJK Ideograph>) 18075 0x90F0 郰 (<CJK Ideograph>) 18076 0x90F1 郱 (<CJK Ideograph>) 18077 0x90F2 郲 (<CJK Ideograph>) 18078 0x90F3 郳 (<CJK Ideograph>) 18079 0x90F5 郵 (<CJK Ideograph>) 18080 0x90F6 郶 (<CJK Ideograph>) 18081 0x90F7 郷 (<CJK Ideograph>) 18082 0x90F9 郹 (<CJK Ideograph>) 18083 0x90FA 郺 (<CJK Ideograph>) 18084 0x90FB 郻 (<CJK Ideograph>) 18085 0x90FC 郼 (<CJK Ideograph>) 18086 0x90FF 郿 (<CJK Ideograph>) 18087 0x9100 鄀 (<CJK Ideograph>) 18088 0x9101 鄁 (<CJK Ideograph>) 18089 0x9103 鄃 (<CJK Ideograph>) 18090 0x9105 鄅 (<CJK Ideograph>) 18091 0x9106 鄆 (<CJK Ideograph>) 18092 0x9107 鄇 (<CJK Ideograph>) 18093 0x9108 鄈 (<CJK Ideograph>) 18094 0x9109 鄉 (<CJK Ideograph>) 18095 0x910A 鄊 (<CJK Ideograph>) 18096 0x910B 鄋 (<CJK Ideograph>) 18097 0x910C 鄌 (<CJK Ideograph>) 18098 0x910D 鄍 (<CJK Ideograph>) 18099 0x910E 鄎 (<CJK Ideograph>) 18100 0x910F 鄏 (<CJK Ideograph>) 18101 0x9110 鄐 (<CJK Ideograph>) 18102 0x9111 鄑 (<CJK Ideograph>) 18103 0x9112 鄒 (<CJK Ideograph>) 18104 0x9113 鄓 (<CJK Ideograph>) 18105 0x9114 鄔 (<CJK Ideograph>) 18106 0x9115 鄕 (<CJK Ideograph>) 18107 0x9116 鄖 (<CJK Ideograph>) 18108 0x9117 鄗 (<CJK Ideograph>) 18109 0x9118 鄘 (<CJK Ideograph>) 18110 0x911A 鄚 (<CJK Ideograph>) 18111 0x911B 鄛 (<CJK Ideograph>) 18112 0x911C 鄜 (<CJK Ideograph>) 18113 0x911D 鄝 (<CJK Ideograph>) 18114 0x911F 鄟 (<CJK Ideograph>) 18115 0x9120 鄠 (<CJK Ideograph>) 18116 0x9121 鄡 (<CJK Ideograph>) 18117 0x9124 鄤 (<CJK Ideograph>) 18118 0x9125 鄥 (<CJK Ideograph>) 18119 0x9126 鄦 (<CJK Ideograph>) 18120 0x9127 鄧 (<CJK Ideograph>) 18121 0x9128 鄨 (<CJK Ideograph>) 18122 0x9129 鄩 (<CJK Ideograph>) 18123 0x912A 鄪 (<CJK Ideograph>) 18124 0x912B 鄫 (<CJK Ideograph>) 18125 0x912C 鄬 (<CJK Ideograph>) 18126 0x912D 鄭 (<CJK Ideograph>) 18127 0x912E 鄮 (<CJK Ideograph>) 18128 0x9130 鄰 (<CJK Ideograph>) 18129 0x9132 鄲 (<CJK Ideograph>) 18130 0x9133 鄳 (<CJK Ideograph>) 18131 0x9134 鄴 (<CJK Ideograph>) 18132 0x9135 鄵 (<CJK Ideograph>) 18133 0x9136 鄶 (<CJK Ideograph>) 18134 0x9137 鄷 (<CJK Ideograph>) 18135 0x9138 鄸 (<CJK Ideograph>) 18136 0x913A 鄺 (<CJK Ideograph>) 18137 0x913B 鄻 (<CJK Ideograph>) 18138 0x913C 鄼 (<CJK Ideograph>) 18139 0x913D 鄽 (<CJK Ideograph>) 18140 0x913E 鄾 (<CJK Ideograph>) 18141 0x913F 鄿 (<CJK Ideograph>) 18142 0x9140 酀 (<CJK Ideograph>) 18143 0x9141 酁 (<CJK Ideograph>) 18144 0x9142 酂 (<CJK Ideograph>) 18145 0x9144 酄 (<CJK Ideograph>) 18146 0x5537 唷 (<CJK Ideograph>) 18147 0x5556 啖 (<CJK Ideograph>) 18148 0x5575 啵 (<CJK Ideograph>) 18149 0x5576 啶 (<CJK Ideograph>) 18150 0x5577 啷 (<CJK Ideograph>) 18151 0x5533 唳 (<CJK Ideograph>) 18152 0x5530 唰 (<CJK Ideograph>) 18153 0x555C 啜 (<CJK Ideograph>) 18154 0x558B 喋 (<CJK Ideograph>) 18155 0x55D2 嗒 (<CJK Ideograph>) 18156 0x5583 喃 (<CJK Ideograph>) 18157 0x55B1 喱 (<CJK Ideograph>) 18158 0x55B9 喹 (<CJK Ideograph>) 18159 0x5588 喈 (<CJK Ideograph>) 18160 0x5581 喁 (<CJK Ideograph>) 18161 0x559F 喟 (<CJK Ideograph>) 18162 0x557E 啾 (<CJK Ideograph>) 18163 0x55D6 嗖 (<CJK Ideograph>) 18164 0x5591 喑 (<CJK Ideograph>) 18165 0x557B 啻 (<CJK Ideograph>) 18166 0x55DF 嗟 (<CJK Ideograph>) 18167 0x55BD 喽 (<CJK Ideograph>) 18168 0x55BE 喾 (<CJK Ideograph>) 18169 0x5594 喔 (<CJK Ideograph>) 18170 0x5599 喙 (<CJK Ideograph>) 18171 0x55EA 嗪 (<CJK Ideograph>) 18172 0x55F7 嗷 (<CJK Ideograph>) 18173 0x55C9 嗉 (<CJK Ideograph>) 18174 0x561F 嘟 (<CJK Ideograph>) 18175 0x55D1 嗑 (<CJK Ideograph>) 18176 0x55EB 嗫 (<CJK Ideograph>) 18177 0x55EC 嗬 (<CJK Ideograph>) 18178 0x55D4 嗔 (<CJK Ideograph>) 18179 0x55E6 嗦 (<CJK Ideograph>) 18180 0x55DD 嗝 (<CJK Ideograph>) 18181 0x55C4 嗄 (<CJK Ideograph>) 18182 0x55EF 嗯 (<CJK Ideograph>) 18183 0x55E5 嗥 (<CJK Ideograph>) 18184 0x55F2 嗲 (<CJK Ideograph>) 18185 0x55F3 嗳 (<CJK Ideograph>) 18186 0x55CC 嗌 (<CJK Ideograph>) 18187 0x55CD 嗍 (<CJK Ideograph>) 18188 0x55E8 嗨 (<CJK Ideograph>) 18189 0x55F5 嗵 (<CJK Ideograph>) 18190 0x55E4 嗤 (<CJK Ideograph>) 18191 0x8F94 辔 (<CJK Ideograph>) 18192 0x561E 嘞 (<CJK Ideograph>) 18193 0x5608 嘈 (<CJK Ideograph>) 18194 0x560C 嘌 (<CJK Ideograph>) 18195 0x5601 嘁 (<CJK Ideograph>) 18196 0x5624 嘤 (<CJK Ideograph>) 18197 0x5623 嘣 (<CJK Ideograph>) 18198 0x55FE 嗾 (<CJK Ideograph>) 18199 0x5600 嘀 (<CJK Ideograph>) 18200 0x5627 嘧 (<CJK Ideograph>) 18201 0x562D 嘭 (<CJK Ideograph>) 18202 0x5658 噘 (<CJK Ideograph>) 18203 0x5639 嘹 (<CJK Ideograph>) 18204 0x5657 噗 (<CJK Ideograph>) 18205 0x562C 嘬 (<CJK Ideograph>) 18206 0x564D 噍 (<CJK Ideograph>) 18207 0x5662 噢 (<CJK Ideograph>) 18208 0x5659 噙 (<CJK Ideograph>) 18209 0x565C 噜 (<CJK Ideograph>) 18210 0x564C 噌 (<CJK Ideograph>) 18211 0x5654 噔 (<CJK Ideograph>) 18212 0x5686 嚆 (<CJK Ideograph>) 18213 0x5664 噤 (<CJK Ideograph>) 18214 0x5671 噱 (<CJK Ideograph>) 18215 0x566B 噫 (<CJK Ideograph>) 18216 0x567B 噻 (<CJK Ideograph>) 18217 0x567C 噼 (<CJK Ideograph>) 18218 0x5685 嚅 (<CJK Ideograph>) 18219 0x5693 嚓 (<CJK Ideograph>) 18220 0x56AF 嚯 (<CJK Ideograph>) 18221 0x56D4 囔 (<CJK Ideograph>) 18222 0x56D7 囗 (<CJK Ideograph>) 18223 0x56DD 囝 (<CJK Ideograph>) 18224 0x56E1 囡 (<CJK Ideograph>) 18225 0x56F5 囵 (<CJK Ideograph>) 18226 0x56EB 囫 (<CJK Ideograph>) 18227 0x56F9 囹 (<CJK Ideograph>) 18228 0x56FF 囿 (<CJK Ideograph>) 18229 0x5704 圄 (<CJK Ideograph>) 18230 0x570A 圊 (<CJK Ideograph>) 18231 0x5709 圉 (<CJK Ideograph>) 18232 0x571C 圜 (<CJK Ideograph>) 18233 0x5E0F 帏 (<CJK Ideograph>) 18234 0x5E19 帙 (<CJK Ideograph>) 18235 0x5E14 帔 (<CJK Ideograph>) 18236 0x5E11 帑 (<CJK Ideograph>) 18237 0x5E31 帱 (<CJK Ideograph>) 18238 0x5E3B 帻 (<CJK Ideograph>) 18239 0x5E3C 帼 (<CJK Ideograph>) 18240 0x9145 酅 (<CJK Ideograph>) 18241 0x9147 酇 (<CJK Ideograph>) 18242 0x9148 酈 (<CJK Ideograph>) 18243 0x9151 酑 (<CJK Ideograph>) 18244 0x9153 酓 (<CJK Ideograph>) 18245 0x9154 酔 (<CJK Ideograph>) 18246 0x9155 酕 (<CJK Ideograph>) 18247 0x9156 酖 (<CJK Ideograph>) 18248 0x9158 酘 (<CJK Ideograph>) 18249 0x9159 酙 (<CJK Ideograph>) 18250 0x915B 酛 (<CJK Ideograph>) 18251 0x915C 酜 (<CJK Ideograph>) 18252 0x915F 酟 (<CJK Ideograph>) 18253 0x9160 酠 (<CJK Ideograph>) 18254 0x9166 酦 (<CJK Ideograph>) 18255 0x9167 酧 (<CJK Ideograph>) 18256 0x9168 酨 (<CJK Ideograph>) 18257 0x916B 酫 (<CJK Ideograph>) 18258 0x916D 酭 (<CJK Ideograph>) 18259 0x9173 酳 (<CJK Ideograph>) 18260 0x917A 酺 (<CJK Ideograph>) 18261 0x917B 酻 (<CJK Ideograph>) 18262 0x917C 酼 (<CJK Ideograph>) 18263 0x9180 醀 (<CJK Ideograph>) 18264 0x9181 醁 (<CJK Ideograph>) 18265 0x9182 醂 (<CJK Ideograph>) 18266 0x9183 醃 (<CJK Ideograph>) 18267 0x9184 醄 (<CJK Ideograph>) 18268 0x9186 醆 (<CJK Ideograph>) 18269 0x9188 醈 (<CJK Ideograph>) 18270 0x918A 醊 (<CJK Ideograph>) 18271 0x918E 醎 (<CJK Ideograph>) 18272 0x918F 醏 (<CJK Ideograph>) 18273 0x9193 醓 (<CJK Ideograph>) 18274 0x9194 醔 (<CJK Ideograph>) 18275 0x9195 醕 (<CJK Ideograph>) 18276 0x9196 醖 (<CJK Ideograph>) 18277 0x9197 醗 (<CJK Ideograph>) 18278 0x9198 醘 (<CJK Ideograph>) 18279 0x9199 醙 (<CJK Ideograph>) 18280 0x919C 醜 (<CJK Ideograph>) 18281 0x919D 醝 (<CJK Ideograph>) 18282 0x919E 醞 (<CJK Ideograph>) 18283 0x919F 醟 (<CJK Ideograph>) 18284 0x91A0 醠 (<CJK Ideograph>) 18285 0x91A1 醡 (<CJK Ideograph>) 18286 0x91A4 醤 (<CJK Ideograph>) 18287 0x91A5 醥 (<CJK Ideograph>) 18288 0x91A6 醦 (<CJK Ideograph>) 18289 0x91A7 醧 (<CJK Ideograph>) 18290 0x91A8 醨 (<CJK Ideograph>) 18291 0x91A9 醩 (<CJK Ideograph>) 18292 0x91AB 醫 (<CJK Ideograph>) 18293 0x91AC 醬 (<CJK Ideograph>) 18294 0x91B0 醰 (<CJK Ideograph>) 18295 0x91B1 醱 (<CJK Ideograph>) 18296 0x91B2 醲 (<CJK Ideograph>) 18297 0x91B3 醳 (<CJK Ideograph>) 18298 0x91B6 醶 (<CJK Ideograph>) 18299 0x91B7 醷 (<CJK Ideograph>) 18300 0x91B8 醸 (<CJK Ideograph>) 18301 0x91B9 醹 (<CJK Ideograph>) 18302 0x91BB 醻 (<CJK Ideograph>) 18303 0x91BC 醼 (<CJK Ideograph>) 18304 0x91BD 醽 (<CJK Ideograph>) 18305 0x91BE 醾 (<CJK Ideograph>) 18306 0x91BF 醿 (<CJK Ideograph>) 18307 0x91C0 釀 (<CJK Ideograph>) 18308 0x91C1 釁 (<CJK Ideograph>) 18309 0x91C2 釂 (<CJK Ideograph>) 18310 0x91C3 釃 (<CJK Ideograph>) 18311 0x91C4 釄 (<CJK Ideograph>) 18312 0x91C5 釅 (<CJK Ideograph>) 18313 0x91C6 釆 (<CJK Ideograph>) 18314 0x91C8 釈 (<CJK Ideograph>) 18315 0x91CB 釋 (<CJK Ideograph>) 18316 0x91D0 釐 (<CJK Ideograph>) 18317 0x91D2 釒 (<CJK Ideograph>) 18318 0x91D3 釓 (<CJK Ideograph>) 18319 0x91D4 釔 (<CJK Ideograph>) 18320 0x91D5 釕 (<CJK Ideograph>) 18321 0x91D6 釖 (<CJK Ideograph>) 18322 0x91D7 釗 (<CJK Ideograph>) 18323 0x91D8 釘 (<CJK Ideograph>) 18324 0x91D9 釙 (<CJK Ideograph>) 18325 0x91DA 釚 (<CJK Ideograph>) 18326 0x91DB 釛 (<CJK Ideograph>) 18327 0x91DD 針 (<CJK Ideograph>) 18328 0x91DE 釞 (<CJK Ideograph>) 18329 0x91DF 釟 (<CJK Ideograph>) 18330 0x91E0 釠 (<CJK Ideograph>) 18331 0x91E1 釡 (<CJK Ideograph>) 18332 0x91E2 釢 (<CJK Ideograph>) 18333 0x91E3 釣 (<CJK Ideograph>) 18334 0x91E4 釤 (<CJK Ideograph>) 18335 0x91E5 釥 (<CJK Ideograph>) 18336 0x5E37 帷 (<CJK Ideograph>) 18337 0x5E44 幄 (<CJK Ideograph>) 18338 0x5E54 幔 (<CJK Ideograph>) 18339 0x5E5B 幛 (<CJK Ideograph>) 18340 0x5E5E 幞 (<CJK Ideograph>) 18341 0x5E61 幡 (<CJK Ideograph>) 18342 0x5C8C 岌 (<CJK Ideograph>) 18343 0x5C7A 屺 (<CJK Ideograph>) 18344 0x5C8D 岍 (<CJK Ideograph>) 18345 0x5C90 岐 (<CJK Ideograph>) 18346 0x5C96 岖 (<CJK Ideograph>) 18347 0x5C88 岈 (<CJK Ideograph>) 18348 0x5C98 岘 (<CJK Ideograph>) 18349 0x5C99 岙 (<CJK Ideograph>) 18350 0x5C91 岑 (<CJK Ideograph>) 18351 0x5C9A 岚 (<CJK Ideograph>) 18352 0x5C9C 岜 (<CJK Ideograph>) 18353 0x5CB5 岵 (<CJK Ideograph>) 18354 0x5CA2 岢 (<CJK Ideograph>) 18355 0x5CBD 岽 (<CJK Ideograph>) 18356 0x5CAC 岬 (<CJK Ideograph>) 18357 0x5CAB 岫 (<CJK Ideograph>) 18358 0x5CB1 岱 (<CJK Ideograph>) 18359 0x5CA3 岣 (<CJK Ideograph>) 18360 0x5CC1 峁 (<CJK Ideograph>) 18361 0x5CB7 岷 (<CJK Ideograph>) 18362 0x5CC4 峄 (<CJK Ideograph>) 18363 0x5CD2 峒 (<CJK Ideograph>) 18364 0x5CE4 峤 (<CJK Ideograph>) 18365 0x5CCB 峋 (<CJK Ideograph>) 18366 0x5CE5 峥 (<CJK Ideograph>) 18367 0x5D02 崂 (<CJK Ideograph>) 18368 0x5D03 崃 (<CJK Ideograph>) 18369 0x5D27 崧 (<CJK Ideograph>) 18370 0x5D26 崦 (<CJK Ideograph>) 18371 0x5D2E 崮 (<CJK Ideograph>) 18372 0x5D24 崤 (<CJK Ideograph>) 18373 0x5D1E 崞 (<CJK Ideograph>) 18374 0x5D06 崆 (<CJK Ideograph>) 18375 0x5D1B 崛 (<CJK Ideograph>) 18376 0x5D58 嵘 (<CJK Ideograph>) 18377 0x5D3E 崾 (<CJK Ideograph>) 18378 0x5D34 崴 (<CJK Ideograph>) 18379 0x5D3D 崽 (<CJK Ideograph>) 18380 0x5D6C 嵬 (<CJK Ideograph>) 18381 0x5D5B 嵛 (<CJK Ideograph>) 18382 0x5D6F 嵯 (<CJK Ideograph>) 18383 0x5D5D 嵝 (<CJK Ideograph>) 18384 0x5D6B 嵫 (<CJK Ideograph>) 18385 0x5D4B 嵋 (<CJK Ideograph>) 18386 0x5D4A 嵊 (<CJK Ideograph>) 18387 0x5D69 嵩 (<CJK Ideograph>) 18388 0x5D74 嵴 (<CJK Ideograph>) 18389 0x5D82 嶂 (<CJK Ideograph>) 18390 0x5D99 嶙 (<CJK Ideograph>) 18391 0x5D9D 嶝 (<CJK Ideograph>) 18392 0x8C73 豳 (<CJK Ideograph>) 18393 0x5DB7 嶷 (<CJK Ideograph>) 18394 0x5DC5 巅 (<CJK Ideograph>) 18395 0x5F73 彳 (<CJK Ideograph>) 18396 0x5F77 彷 (<CJK Ideograph>) 18397 0x5F82 徂 (<CJK Ideograph>) 18398 0x5F87 徇 (<CJK Ideograph>) 18399 0x5F89 徉 (<CJK Ideograph>) 18400 0x5F8C 後 (<CJK Ideograph>) 18401 0x5F95 徕 (<CJK Ideograph>) 18402 0x5F99 徙 (<CJK Ideograph>) 18403 0x5F9C 徜 (<CJK Ideograph>) 18404 0x5FA8 徨 (<CJK Ideograph>) 18405 0x5FAD 徭 (<CJK Ideograph>) 18406 0x5FB5 徵 (<CJK Ideograph>) 18407 0x5FBC 徼 (<CJK Ideograph>) 18408 0x8862 衢 (<CJK Ideograph>) 18409 0x5F61 彡 (<CJK Ideograph>) 18410 0x72AD 犭 (<CJK Ideograph>) 18411 0x72B0 犰 (<CJK Ideograph>) 18412 0x72B4 犴 (<CJK Ideograph>) 18413 0x72B7 犷 (<CJK Ideograph>) 18414 0x72B8 犸 (<CJK Ideograph>) 18415 0x72C3 狃 (<CJK Ideograph>) 18416 0x72C1 狁 (<CJK Ideograph>) 18417 0x72CE 狎 (<CJK Ideograph>) 18418 0x72CD 狍 (<CJK Ideograph>) 18419 0x72D2 狒 (<CJK Ideograph>) 18420 0x72E8 狨 (<CJK Ideograph>) 18421 0x72EF 狯 (<CJK Ideograph>) 18422 0x72E9 狩 (<CJK Ideograph>) 18423 0x72F2 狲 (<CJK Ideograph>) 18424 0x72F4 狴 (<CJK Ideograph>) 18425 0x72F7 狷 (<CJK Ideograph>) 18426 0x7301 猁 (<CJK Ideograph>) 18427 0x72F3 狳 (<CJK Ideograph>) 18428 0x7303 猃 (<CJK Ideograph>) 18429 0x72FA 狺 (<CJK Ideograph>) 18430 0x91E6 釦 (<CJK Ideograph>) 18431 0x91E7 釧 (<CJK Ideograph>) 18432 0x91E8 釨 (<CJK Ideograph>) 18433 0x91E9 釩 (<CJK Ideograph>) 18434 0x91EA 釪 (<CJK Ideograph>) 18435 0x91EB 釫 (<CJK Ideograph>) 18436 0x91EC 釬 (<CJK Ideograph>) 18437 0x91ED 釭 (<CJK Ideograph>) 18438 0x91EE 釮 (<CJK Ideograph>) 18439 0x91EF 釯 (<CJK Ideograph>) 18440 0x91F0 釰 (<CJK Ideograph>) 18441 0x91F1 釱 (<CJK Ideograph>) 18442 0x91F2 釲 (<CJK Ideograph>) 18443 0x91F3 釳 (<CJK Ideograph>) 18444 0x91F4 釴 (<CJK Ideograph>) 18445 0x91F5 釵 (<CJK Ideograph>) 18446 0x91F6 釶 (<CJK Ideograph>) 18447 0x91F7 釷 (<CJK Ideograph>) 18448 0x91F8 釸 (<CJK Ideograph>) 18449 0x91F9 釹 (<CJK Ideograph>) 18450 0x91FA 釺 (<CJK Ideograph>) 18451 0x91FB 釻 (<CJK Ideograph>) 18452 0x91FC 釼 (<CJK Ideograph>) 18453 0x91FD 釽 (<CJK Ideograph>) 18454 0x91FE 釾 (<CJK Ideograph>) 18455 0x91FF 釿 (<CJK Ideograph>) 18456 0x9200 鈀 (<CJK Ideograph>) 18457 0x9201 鈁 (<CJK Ideograph>) 18458 0x9202 鈂 (<CJK Ideograph>) 18459 0x9203 鈃 (<CJK Ideograph>) 18460 0x9204 鈄 (<CJK Ideograph>) 18461 0x9205 鈅 (<CJK Ideograph>) 18462 0x9206 鈆 (<CJK Ideograph>) 18463 0x9207 鈇 (<CJK Ideograph>) 18464 0x9208 鈈 (<CJK Ideograph>) 18465 0x9209 鈉 (<CJK Ideograph>) 18466 0x920A 鈊 (<CJK Ideograph>) 18467 0x920B 鈋 (<CJK Ideograph>) 18468 0x920C 鈌 (<CJK Ideograph>) 18469 0x920D 鈍 (<CJK Ideograph>) 18470 0x920E 鈎 (<CJK Ideograph>) 18471 0x920F 鈏 (<CJK Ideograph>) 18472 0x9210 鈐 (<CJK Ideograph>) 18473 0x9211 鈑 (<CJK Ideograph>) 18474 0x9212 鈒 (<CJK Ideograph>) 18475 0x9213 鈓 (<CJK Ideograph>) 18476 0x9214 鈔 (<CJK Ideograph>) 18477 0x9215 鈕 (<CJK Ideograph>) 18478 0x9216 鈖 (<CJK Ideograph>) 18479 0x9217 鈗 (<CJK Ideograph>) 18480 0x9218 鈘 (<CJK Ideograph>) 18481 0x9219 鈙 (<CJK Ideograph>) 18482 0x921A 鈚 (<CJK Ideograph>) 18483 0x921B 鈛 (<CJK Ideograph>) 18484 0x921C 鈜 (<CJK Ideograph>) 18485 0x921D 鈝 (<CJK Ideograph>) 18486 0x921E 鈞 (<CJK Ideograph>) 18487 0x921F 鈟 (<CJK Ideograph>) 18488 0x9220 鈠 (<CJK Ideograph>) 18489 0x9221 鈡 (<CJK Ideograph>) 18490 0x9222 鈢 (<CJK Ideograph>) 18491 0x9223 鈣 (<CJK Ideograph>) 18492 0x9224 鈤 (<CJK Ideograph>) 18493 0x9225 鈥 (<CJK Ideograph>) 18494 0x9226 鈦 (<CJK Ideograph>) 18495 0x9227 鈧 (<CJK Ideograph>) 18496 0x9228 鈨 (<CJK Ideograph>) 18497 0x9229 鈩 (<CJK Ideograph>) 18498 0x922A 鈪 (<CJK Ideograph>) 18499 0x922B 鈫 (<CJK Ideograph>) 18500 0x922C 鈬 (<CJK Ideograph>) 18501 0x922D 鈭 (<CJK Ideograph>) 18502 0x922E 鈮 (<CJK Ideograph>) 18503 0x922F 鈯 (<CJK Ideograph>) 18504 0x9230 鈰 (<CJK Ideograph>) 18505 0x9231 鈱 (<CJK Ideograph>) 18506 0x9232 鈲 (<CJK Ideograph>) 18507 0x9233 鈳 (<CJK Ideograph>) 18508 0x9234 鈴 (<CJK Ideograph>) 18509 0x9235 鈵 (<CJK Ideograph>) 18510 0x9236 鈶 (<CJK Ideograph>) 18511 0x9237 鈷 (<CJK Ideograph>) 18512 0x9238 鈸 (<CJK Ideograph>) 18513 0x9239 鈹 (<CJK Ideograph>) 18514 0x923A 鈺 (<CJK Ideograph>) 18515 0x923B 鈻 (<CJK Ideograph>) 18516 0x923C 鈼 (<CJK Ideograph>) 18517 0x923D 鈽 (<CJK Ideograph>) 18518 0x923E 鈾 (<CJK Ideograph>) 18519 0x923F 鈿 (<CJK Ideograph>) 18520 0x9240 鉀 (<CJK Ideograph>) 18521 0x9241 鉁 (<CJK Ideograph>) 18522 0x9242 鉂 (<CJK Ideograph>) 18523 0x9243 鉃 (<CJK Ideograph>) 18524 0x9244 鉄 (<CJK Ideograph>) 18525 0x9245 鉅 (<CJK Ideograph>) 18526 0x72FB 狻 (<CJK Ideograph>) 18527 0x7317 猗 (<CJK Ideograph>) 18528 0x7313 猓 (<CJK Ideograph>) 18529 0x7321 猡 (<CJK Ideograph>) 18530 0x730A 猊 (<CJK Ideograph>) 18531 0x731E 猞 (<CJK Ideograph>) 18532 0x731D 猝 (<CJK Ideograph>) 18533 0x7315 猕 (<CJK Ideograph>) 18534 0x7322 猢 (<CJK Ideograph>) 18535 0x7339 猹 (<CJK Ideograph>) 18536 0x7325 猥 (<CJK Ideograph>) 18537 0x732C 猬 (<CJK Ideograph>) 18538 0x7338 猸 (<CJK Ideograph>) 18539 0x7331 猱 (<CJK Ideograph>) 18540 0x7350 獐 (<CJK Ideograph>) 18541 0x734D 獍 (<CJK Ideograph>) 18542 0x7357 獗 (<CJK Ideograph>) 18543 0x7360 獠 (<CJK Ideograph>) 18544 0x736C 獬 (<CJK Ideograph>) 18545 0x736F 獯 (<CJK Ideograph>) 18546 0x737E 獾 (<CJK Ideograph>) 18547 0x821B 舛 (<CJK Ideograph>) 18548 0x5925 夥 (<CJK Ideograph>) 18549 0x98E7 飧 (<CJK Ideograph>) 18550 0x5924 夤 (<CJK Ideograph>) 18551 0x5902 夂 (<CJK Ideograph>) 18552 0x9963 饣 (<CJK Ideograph>) 18553 0x9967 饧 (<CJK Ideograph>) 18554 0x9968 饨 (<CJK Ideograph>) 18555 0x9969 饩 (<CJK Ideograph>) 18556 0x996A 饪 (<CJK Ideograph>) 18557 0x996B 饫 (<CJK Ideograph>) 18558 0x996C 饬 (<CJK Ideograph>) 18559 0x9974 饴 (<CJK Ideograph>) 18560 0x9977 饷 (<CJK Ideograph>) 18561 0x997D 饽 (<CJK Ideograph>) 18562 0x9980 馀 (<CJK Ideograph>) 18563 0x9984 馄 (<CJK Ideograph>) 18564 0x9987 馇 (<CJK Ideograph>) 18565 0x998A 馊 (<CJK Ideograph>) 18566 0x998D 馍 (<CJK Ideograph>) 18567 0x9990 馐 (<CJK Ideograph>) 18568 0x9991 馑 (<CJK Ideograph>) 18569 0x9993 馓 (<CJK Ideograph>) 18570 0x9994 馔 (<CJK Ideograph>) 18571 0x9995 馕 (<CJK Ideograph>) 18572 0x5E80 庀 (<CJK Ideograph>) 18573 0x5E91 庑 (<CJK Ideograph>) 18574 0x5E8B 庋 (<CJK Ideograph>) 18575 0x5E96 庖 (<CJK Ideograph>) 18576 0x5EA5 庥 (<CJK Ideograph>) 18577 0x5EA0 庠 (<CJK Ideograph>) 18578 0x5EB9 庹 (<CJK Ideograph>) 18579 0x5EB5 庵 (<CJK Ideograph>) 18580 0x5EBE 庾 (<CJK Ideograph>) 18581 0x5EB3 庳 (<CJK Ideograph>) 18582 0x8D53 赓 (<CJK Ideograph>) 18583 0x5ED2 廒 (<CJK Ideograph>) 18584 0x5ED1 廑 (<CJK Ideograph>) 18585 0x5EDB 廛 (<CJK Ideograph>) 18586 0x5EE8 廨 (<CJK Ideograph>) 18587 0x5EEA 廪 (<CJK Ideograph>) 18588 0x81BA 膺 (<CJK Ideograph>) 18589 0x5FC4 忄 (<CJK Ideograph>) 18590 0x5FC9 忉 (<CJK Ideograph>) 18591 0x5FD6 忖 (<CJK Ideograph>) 18592 0x5FCF 忏 (<CJK Ideograph>) 18593 0x6003 怃 (<CJK Ideograph>) 18594 0x5FEE 忮 (<CJK Ideograph>) 18595 0x6004 怄 (<CJK Ideograph>) 18596 0x5FE1 忡 (<CJK Ideograph>) 18597 0x5FE4 忤 (<CJK Ideograph>) 18598 0x5FFE 忾 (<CJK Ideograph>) 18599 0x6005 怅 (<CJK Ideograph>) 18600 0x6006 怆 (<CJK Ideograph>) 18601 0x5FEA 忪 (<CJK Ideograph>) 18602 0x5FED 忭 (<CJK Ideograph>) 18603 0x5FF8 忸 (<CJK Ideograph>) 18604 0x6019 怙 (<CJK Ideograph>) 18605 0x6035 怵 (<CJK Ideograph>) 18606 0x6026 怦 (<CJK Ideograph>) 18607 0x601B 怛 (<CJK Ideograph>) 18608 0x600F 怏 (<CJK Ideograph>) 18609 0x600D 怍 (<CJK Ideograph>) 18610 0x6029 怩 (<CJK Ideograph>) 18611 0x602B 怫 (<CJK Ideograph>) 18612 0x600A 怊 (<CJK Ideograph>) 18613 0x603F 怿 (<CJK Ideograph>) 18614 0x6021 怡 (<CJK Ideograph>) 18615 0x6078 恸 (<CJK Ideograph>) 18616 0x6079 恹 (<CJK Ideograph>) 18617 0x607B 恻 (<CJK Ideograph>) 18618 0x607A 恺 (<CJK Ideograph>) 18619 0x6042 恂 (<CJK Ideograph>) 18620 0x9246 鉆 (<CJK Ideograph>) 18621 0x9247 鉇 (<CJK Ideograph>) 18622 0x9248 鉈 (<CJK Ideograph>) 18623 0x9249 鉉 (<CJK Ideograph>) 18624 0x924A 鉊 (<CJK Ideograph>) 18625 0x924B 鉋 (<CJK Ideograph>) 18626 0x924C 鉌 (<CJK Ideograph>) 18627 0x924D 鉍 (<CJK Ideograph>) 18628 0x924E 鉎 (<CJK Ideograph>) 18629 0x924F 鉏 (<CJK Ideograph>) 18630 0x9250 鉐 (<CJK Ideograph>) 18631 0x9251 鉑 (<CJK Ideograph>) 18632 0x9252 鉒 (<CJK Ideograph>) 18633 0x9253 鉓 (<CJK Ideograph>) 18634 0x9254 鉔 (<CJK Ideograph>) 18635 0x9255 鉕 (<CJK Ideograph>) 18636 0x9256 鉖 (<CJK Ideograph>) 18637 0x9257 鉗 (<CJK Ideograph>) 18638 0x9258 鉘 (<CJK Ideograph>) 18639 0x9259 鉙 (<CJK Ideograph>) 18640 0x925A 鉚 (<CJK Ideograph>) 18641 0x925B 鉛 (<CJK Ideograph>) 18642 0x925C 鉜 (<CJK Ideograph>) 18643 0x925D 鉝 (<CJK Ideograph>) 18644 0x925E 鉞 (<CJK Ideograph>) 18645 0x925F 鉟 (<CJK Ideograph>) 18646 0x9260 鉠 (<CJK Ideograph>) 18647 0x9261 鉡 (<CJK Ideograph>) 18648 0x9262 鉢 (<CJK Ideograph>) 18649 0x9263 鉣 (<CJK Ideograph>) 18650 0x9264 鉤 (<CJK Ideograph>) 18651 0x9265 鉥 (<CJK Ideograph>) 18652 0x9266 鉦 (<CJK Ideograph>) 18653 0x9267 鉧 (<CJK Ideograph>) 18654 0x9268 鉨 (<CJK Ideograph>) 18655 0x9269 鉩 (<CJK Ideograph>) 18656 0x926A 鉪 (<CJK Ideograph>) 18657 0x926B 鉫 (<CJK Ideograph>) 18658 0x926C 鉬 (<CJK Ideograph>) 18659 0x926D 鉭 (<CJK Ideograph>) 18660 0x926E 鉮 (<CJK Ideograph>) 18661 0x926F 鉯 (<CJK Ideograph>) 18662 0x9270 鉰 (<CJK Ideograph>) 18663 0x9271 鉱 (<CJK Ideograph>) 18664 0x9272 鉲 (<CJK Ideograph>) 18665 0x9273 鉳 (<CJK Ideograph>) 18666 0x9275 鉵 (<CJK Ideograph>) 18667 0x9276 鉶 (<CJK Ideograph>) 18668 0x9277 鉷 (<CJK Ideograph>) 18669 0x9278 鉸 (<CJK Ideograph>) 18670 0x9279 鉹 (<CJK Ideograph>) 18671 0x927A 鉺 (<CJK Ideograph>) 18672 0x927B 鉻 (<CJK Ideograph>) 18673 0x927C 鉼 (<CJK Ideograph>) 18674 0x927D 鉽 (<CJK Ideograph>) 18675 0x927E 鉾 (<CJK Ideograph>) 18676 0x927F 鉿 (<CJK Ideograph>) 18677 0x9280 銀 (<CJK Ideograph>) 18678 0x9281 銁 (<CJK Ideograph>) 18679 0x9282 銂 (<CJK Ideograph>) 18680 0x9283 銃 (<CJK Ideograph>) 18681 0x9284 銄 (<CJK Ideograph>) 18682 0x9285 銅 (<CJK Ideograph>) 18683 0x9286 銆 (<CJK Ideograph>) 18684 0x9287 銇 (<CJK Ideograph>) 18685 0x9288 銈 (<CJK Ideograph>) 18686 0x9289 銉 (<CJK Ideograph>) 18687 0x928A 銊 (<CJK Ideograph>) 18688 0x928B 銋 (<CJK Ideograph>) 18689 0x928C 銌 (<CJK Ideograph>) 18690 0x928D 銍 (<CJK Ideograph>) 18691 0x928F 銏 (<CJK Ideograph>) 18692 0x9290 銐 (<CJK Ideograph>) 18693 0x9291 銑 (<CJK Ideograph>) 18694 0x9292 銒 (<CJK Ideograph>) 18695 0x9293 銓 (<CJK Ideograph>) 18696 0x9294 銔 (<CJK Ideograph>) 18697 0x9295 銕 (<CJK Ideograph>) 18698 0x9296 銖 (<CJK Ideograph>) 18699 0x9297 銗 (<CJK Ideograph>) 18700 0x9298 銘 (<CJK Ideograph>) 18701 0x9299 銙 (<CJK Ideograph>) 18702 0x929A 銚 (<CJK Ideograph>) 18703 0x929B 銛 (<CJK Ideograph>) 18704 0x929C 銜 (<CJK Ideograph>) 18705 0x929D 銝 (<CJK Ideograph>) 18706 0x929E 銞 (<CJK Ideograph>) 18707 0x929F 銟 (<CJK Ideograph>) 18708 0x92A0 銠 (<CJK Ideograph>) 18709 0x92A1 銡 (<CJK Ideograph>) 18710 0x92A2 銢 (<CJK Ideograph>) 18711 0x92A3 銣 (<CJK Ideograph>) 18712 0x92A4 銤 (<CJK Ideograph>) 18713 0x92A5 銥 (<CJK Ideograph>) 18714 0x92A6 銦 (<CJK Ideograph>) 18715 0x92A7 銧 (<CJK Ideograph>) 18716 0x606A 恪 (<CJK Ideograph>) 18717 0x607D 恽 (<CJK Ideograph>) 18718 0x6096 悖 (<CJK Ideograph>) 18719 0x609A 悚 (<CJK Ideograph>) 18720 0x60AD 悭 (<CJK Ideograph>) 18721 0x609D 悝 (<CJK Ideograph>) 18722 0x6083 悃 (<CJK Ideograph>) 18723 0x6092 悒 (<CJK Ideograph>) 18724 0x608C 悌 (<CJK Ideograph>) 18725 0x609B 悛 (<CJK Ideograph>) 18726 0x60EC 惬 (<CJK Ideograph>) 18727 0x60BB 悻 (<CJK Ideograph>) 18728 0x60B1 悱 (<CJK Ideograph>) 18729 0x60DD 惝 (<CJK Ideograph>) 18730 0x60D8 惘 (<CJK Ideograph>) 18731 0x60C6 惆 (<CJK Ideograph>) 18732 0x60DA 惚 (<CJK Ideograph>) 18733 0x60B4 悴 (<CJK Ideograph>) 18734 0x6120 愠 (<CJK Ideograph>) 18735 0x6126 愦 (<CJK Ideograph>) 18736 0x6115 愕 (<CJK Ideograph>) 18737 0x6123 愣 (<CJK Ideograph>) 18738 0x60F4 惴 (<CJK Ideograph>) 18739 0x6100 愀 (<CJK Ideograph>) 18740 0x610E 愎 (<CJK Ideograph>) 18741 0x612B 愫 (<CJK Ideograph>) 18742 0x614A 慊 (<CJK Ideograph>) 18743 0x6175 慵 (<CJK Ideograph>) 18744 0x61AC 憬 (<CJK Ideograph>) 18745 0x6194 憔 (<CJK Ideograph>) 18746 0x61A7 憧 (<CJK Ideograph>) 18747 0x61B7 憷 (<CJK Ideograph>) 18748 0x61D4 懔 (<CJK Ideograph>) 18749 0x61F5 懵 (<CJK Ideograph>) 18750 0x5FDD 忝 (<CJK Ideograph>) 18751 0x96B3 隳 (<CJK Ideograph>) 18752 0x95E9 闩 (<CJK Ideograph>) 18753 0x95EB 闫 (<CJK Ideograph>) 18754 0x95F1 闱 (<CJK Ideograph>) 18755 0x95F3 闳 (<CJK Ideograph>) 18756 0x95F5 闵 (<CJK Ideograph>) 18757 0x95F6 闶 (<CJK Ideograph>) 18758 0x95FC 闼 (<CJK Ideograph>) 18759 0x95FE 闾 (<CJK Ideograph>) 18760 0x9603 阃 (<CJK Ideograph>) 18761 0x9604 阄 (<CJK Ideograph>) 18762 0x9606 阆 (<CJK Ideograph>) 18763 0x9608 阈 (<CJK Ideograph>) 18764 0x960A 阊 (<CJK Ideograph>) 18765 0x960B 阋 (<CJK Ideograph>) 18766 0x960C 阌 (<CJK Ideograph>) 18767 0x960D 阍 (<CJK Ideograph>) 18768 0x960F 阏 (<CJK Ideograph>) 18769 0x9612 阒 (<CJK Ideograph>) 18770 0x9615 阕 (<CJK Ideograph>) 18771 0x9616 阖 (<CJK Ideograph>) 18772 0x9617 阗 (<CJK Ideograph>) 18773 0x9619 阙 (<CJK Ideograph>) 18774 0x961A 阚 (<CJK Ideograph>) 18775 0x4E2C 丬 (<CJK Ideograph>) 18776 0x723F 爿 (<CJK Ideograph>) 18777 0x6215 戕 (<CJK Ideograph>) 18778 0x6C35 氵 (<CJK Ideograph>) 18779 0x6C54 汔 (<CJK Ideograph>) 18780 0x6C5C 汜 (<CJK Ideograph>) 18781 0x6C4A 汊 (<CJK Ideograph>) 18782 0x6CA3 沣 (<CJK Ideograph>) 18783 0x6C85 沅 (<CJK Ideograph>) 18784 0x6C90 沐 (<CJK Ideograph>) 18785 0x6C94 沔 (<CJK Ideograph>) 18786 0x6C8C 沌 (<CJK Ideograph>) 18787 0x6C68 汨 (<CJK Ideograph>) 18788 0x6C69 汩 (<CJK Ideograph>) 18789 0x6C74 汴 (<CJK Ideograph>) 18790 0x6C76 汶 (<CJK Ideograph>) 18791 0x6C86 沆 (<CJK Ideograph>) 18792 0x6CA9 沩 (<CJK Ideograph>) 18793 0x6CD0 泐 (<CJK Ideograph>) 18794 0x6CD4 泔 (<CJK Ideograph>) 18795 0x6CAD 沭 (<CJK Ideograph>) 18796 0x6CF7 泷 (<CJK Ideograph>) 18797 0x6CF8 泸 (<CJK Ideograph>) 18798 0x6CF1 泱 (<CJK Ideograph>) 18799 0x6CD7 泗 (<CJK Ideograph>) 18800 0x6CB2 沲 (<CJK Ideograph>) 18801 0x6CE0 泠 (<CJK Ideograph>) 18802 0x6CD6 泖 (<CJK Ideograph>) 18803 0x6CFA 泺 (<CJK Ideograph>) 18804 0x6CEB 泫 (<CJK Ideograph>) 18805 0x6CEE 泮 (<CJK Ideograph>) 18806 0x6CB1 沱 (<CJK Ideograph>) 18807 0x6CD3 泓 (<CJK Ideograph>) 18808 0x6CEF 泯 (<CJK Ideograph>) 18809 0x6CFE 泾 (<CJK Ideograph>) 18810 0x92A8 銨 (<CJK Ideograph>) 18811 0x92A9 銩 (<CJK Ideograph>) 18812 0x92AA 銪 (<CJK Ideograph>) 18813 0x92AB 銫 (<CJK Ideograph>) 18814 0x92AC 銬 (<CJK Ideograph>) 18815 0x92AD 銭 (<CJK Ideograph>) 18816 0x92AF 銯 (<CJK Ideograph>) 18817 0x92B0 銰 (<CJK Ideograph>) 18818 0x92B1 銱 (<CJK Ideograph>) 18819 0x92B2 銲 (<CJK Ideograph>) 18820 0x92B3 銳 (<CJK Ideograph>) 18821 0x92B4 銴 (<CJK Ideograph>) 18822 0x92B5 銵 (<CJK Ideograph>) 18823 0x92B6 銶 (<CJK Ideograph>) 18824 0x92B7 銷 (<CJK Ideograph>) 18825 0x92B8 銸 (<CJK Ideograph>) 18826 0x92B9 銹 (<CJK Ideograph>) 18827 0x92BA 銺 (<CJK Ideograph>) 18828 0x92BB 銻 (<CJK Ideograph>) 18829 0x92BC 銼 (<CJK Ideograph>) 18830 0x92BD 銽 (<CJK Ideograph>) 18831 0x92BE 銾 (<CJK Ideograph>) 18832 0x92BF 銿 (<CJK Ideograph>) 18833 0x92C0 鋀 (<CJK Ideograph>) 18834 0x92C1 鋁 (<CJK Ideograph>) 18835 0x92C2 鋂 (<CJK Ideograph>) 18836 0x92C3 鋃 (<CJK Ideograph>) 18837 0x92C4 鋄 (<CJK Ideograph>) 18838 0x92C5 鋅 (<CJK Ideograph>) 18839 0x92C6 鋆 (<CJK Ideograph>) 18840 0x92C7 鋇 (<CJK Ideograph>) 18841 0x92C9 鋉 (<CJK Ideograph>) 18842 0x92CA 鋊 (<CJK Ideograph>) 18843 0x92CB 鋋 (<CJK Ideograph>) 18844 0x92CC 鋌 (<CJK Ideograph>) 18845 0x92CD 鋍 (<CJK Ideograph>) 18846 0x92CE 鋎 (<CJK Ideograph>) 18847 0x92CF 鋏 (<CJK Ideograph>) 18848 0x92D0 鋐 (<CJK Ideograph>) 18849 0x92D1 鋑 (<CJK Ideograph>) 18850 0x92D2 鋒 (<CJK Ideograph>) 18851 0x92D3 鋓 (<CJK Ideograph>) 18852 0x92D4 鋔 (<CJK Ideograph>) 18853 0x92D5 鋕 (<CJK Ideograph>) 18854 0x92D6 鋖 (<CJK Ideograph>) 18855 0x92D7 鋗 (<CJK Ideograph>) 18856 0x92D8 鋘 (<CJK Ideograph>) 18857 0x92D9 鋙 (<CJK Ideograph>) 18858 0x92DA 鋚 (<CJK Ideograph>) 18859 0x92DB 鋛 (<CJK Ideograph>) 18860 0x92DC 鋜 (<CJK Ideograph>) 18861 0x92DD 鋝 (<CJK Ideograph>) 18862 0x92DE 鋞 (<CJK Ideograph>) 18863 0x92DF 鋟 (<CJK Ideograph>) 18864 0x92E0 鋠 (<CJK Ideograph>) 18865 0x92E1 鋡 (<CJK Ideograph>) 18866 0x92E2 鋢 (<CJK Ideograph>) 18867 0x92E3 鋣 (<CJK Ideograph>) 18868 0x92E4 鋤 (<CJK Ideograph>) 18869 0x92E5 鋥 (<CJK Ideograph>) 18870 0x92E6 鋦 (<CJK Ideograph>) 18871 0x92E7 鋧 (<CJK Ideograph>) 18872 0x92E8 鋨 (<CJK Ideograph>) 18873 0x92E9 鋩 (<CJK Ideograph>) 18874 0x92EA 鋪 (<CJK Ideograph>) 18875 0x92EB 鋫 (<CJK Ideograph>) 18876 0x92EC 鋬 (<CJK Ideograph>) 18877 0x92ED 鋭 (<CJK Ideograph>) 18878 0x92EE 鋮 (<CJK Ideograph>) 18879 0x92EF 鋯 (<CJK Ideograph>) 18880 0x92F0 鋰 (<CJK Ideograph>) 18881 0x92F1 鋱 (<CJK Ideograph>) 18882 0x92F2 鋲 (<CJK Ideograph>) 18883 0x92F3 鋳 (<CJK Ideograph>) 18884 0x92F4 鋴 (<CJK Ideograph>) 18885 0x92F5 鋵 (<CJK Ideograph>) 18886 0x92F6 鋶 (<CJK Ideograph>) 18887 0x92F7 鋷 (<CJK Ideograph>) 18888 0x92F8 鋸 (<CJK Ideograph>) 18889 0x92F9 鋹 (<CJK Ideograph>) 18890 0x92FA 鋺 (<CJK Ideograph>) 18891 0x92FB 鋻 (<CJK Ideograph>) 18892 0x92FC 鋼 (<CJK Ideograph>) 18893 0x92FD 鋽 (<CJK Ideograph>) 18894 0x92FE 鋾 (<CJK Ideograph>) 18895 0x92FF 鋿 (<CJK Ideograph>) 18896 0x9300 錀 (<CJK Ideograph>) 18897 0x9301 錁 (<CJK Ideograph>) 18898 0x9302 錂 (<CJK Ideograph>) 18899 0x9303 錃 (<CJK Ideograph>) 18900 0x9304 錄 (<CJK Ideograph>) 18901 0x9305 錅 (<CJK Ideograph>) 18902 0x9306 錆 (<CJK Ideograph>) 18903 0x9307 錇 (<CJK Ideograph>) 18904 0x9308 錈 (<CJK Ideograph>) 18905 0x9309 錉 (<CJK Ideograph>) 18906 0x6D39 洹 (<CJK Ideograph>) 18907 0x6D27 洧 (<CJK Ideograph>) 18908 0x6D0C 洌 (<CJK Ideograph>) 18909 0x6D43 浃 (<CJK Ideograph>) 18910 0x6D48 浈 (<CJK Ideograph>) 18911 0x6D07 洇 (<CJK Ideograph>) 18912 0x6D04 洄 (<CJK Ideograph>) 18913 0x6D19 洙 (<CJK Ideograph>) 18914 0x6D0E 洎 (<CJK Ideograph>) 18915 0x6D2B 洫 (<CJK Ideograph>) 18916 0x6D4D 浍 (<CJK Ideograph>) 18917 0x6D2E 洮 (<CJK Ideograph>) 18918 0x6D35 洵 (<CJK Ideograph>) 18919 0x6D1A 洚 (<CJK Ideograph>) 18920 0x6D4F 浏 (<CJK Ideograph>) 18921 0x6D52 浒 (<CJK Ideograph>) 18922 0x6D54 浔 (<CJK Ideograph>) 18923 0x6D33 洳 (<CJK Ideograph>) 18924 0x6D91 涑 (<CJK Ideograph>) 18925 0x6D6F 浯 (<CJK Ideograph>) 18926 0x6D9E 涞 (<CJK Ideograph>) 18927 0x6DA0 涠 (<CJK Ideograph>) 18928 0x6D5E 浞 (<CJK Ideograph>) 18929 0x6D93 涓 (<CJK Ideograph>) 18930 0x6D94 涔 (<CJK Ideograph>) 18931 0x6D5C 浜 (<CJK Ideograph>) 18932 0x6D60 浠 (<CJK Ideograph>) 18933 0x6D7C 浼 (<CJK Ideograph>) 18934 0x6D63 浣 (<CJK Ideograph>) 18935 0x6E1A 渚 (<CJK Ideograph>) 18936 0x6DC7 淇 (<CJK Ideograph>) 18937 0x6DC5 淅 (<CJK Ideograph>) 18938 0x6DDE 淞 (<CJK Ideograph>) 18939 0x6E0E 渎 (<CJK Ideograph>) 18940 0x6DBF 涿 (<CJK Ideograph>) 18941 0x6DE0 淠 (<CJK Ideograph>) 18942 0x6E11 渑 (<CJK Ideograph>) 18943 0x6DE6 淦 (<CJK Ideograph>) 18944 0x6DDD 淝 (<CJK Ideograph>) 18945 0x6DD9 淙 (<CJK Ideograph>) 18946 0x6E16 渖 (<CJK Ideograph>) 18947 0x6DAB 涫 (<CJK Ideograph>) 18948 0x6E0C 渌 (<CJK Ideograph>) 18949 0x6DAE 涮 (<CJK Ideograph>) 18950 0x6E2B 渫 (<CJK Ideograph>) 18951 0x6E6E 湮 (<CJK Ideograph>) 18952 0x6E4E 湎 (<CJK Ideograph>) 18953 0x6E6B 湫 (<CJK Ideograph>) 18954 0x6EB2 溲 (<CJK Ideograph>) 18955 0x6E5F 湟 (<CJK Ideograph>) 18956 0x6E86 溆 (<CJK Ideograph>) 18957 0x6E53 湓 (<CJK Ideograph>) 18958 0x6E54 湔 (<CJK Ideograph>) 18959 0x6E32 渲 (<CJK Ideograph>) 18960 0x6E25 渥 (<CJK Ideograph>) 18961 0x6E44 湄 (<CJK Ideograph>) 18962 0x6EDF 滟 (<CJK Ideograph>) 18963 0x6EB1 溱 (<CJK Ideograph>) 18964 0x6E98 溘 (<CJK Ideograph>) 18965 0x6EE0 滠 (<CJK Ideograph>) 18966 0x6F2D 漭 (<CJK Ideograph>) 18967 0x6EE2 滢 (<CJK Ideograph>) 18968 0x6EA5 溥 (<CJK Ideograph>) 18969 0x6EA7 溧 (<CJK Ideograph>) 18970 0x6EBD 溽 (<CJK Ideograph>) 18971 0x6EBB 溻 (<CJK Ideograph>) 18972 0x6EB7 溷 (<CJK Ideograph>) 18973 0x6ED7 滗 (<CJK Ideograph>) 18974 0x6EB4 溴 (<CJK Ideograph>) 18975 0x6ECF 滏 (<CJK Ideograph>) 18976 0x6E8F 溏 (<CJK Ideograph>) 18977 0x6EC2 滂 (<CJK Ideograph>) 18978 0x6E9F 溟 (<CJK Ideograph>) 18979 0x6F62 潢 (<CJK Ideograph>) 18980 0x6F46 潆 (<CJK Ideograph>) 18981 0x6F47 潇 (<CJK Ideograph>) 18982 0x6F24 漤 (<CJK Ideograph>) 18983 0x6F15 漕 (<CJK Ideograph>) 18984 0x6EF9 滹 (<CJK Ideograph>) 18985 0x6F2F 漯 (<CJK Ideograph>) 18986 0x6F36 漶 (<CJK Ideograph>) 18987 0x6F4B 潋 (<CJK Ideograph>) 18988 0x6F74 潴 (<CJK Ideograph>) 18989 0x6F2A 漪 (<CJK Ideograph>) 18990 0x6F09 漉 (<CJK Ideograph>) 18991 0x6F29 漩 (<CJK Ideograph>) 18992 0x6F89 澉 (<CJK Ideograph>) 18993 0x6F8D 澍 (<CJK Ideograph>) 18994 0x6F8C 澌 (<CJK Ideograph>) 18995 0x6F78 潸 (<CJK Ideograph>) 18996 0x6F72 潲 (<CJK Ideograph>) 18997 0x6F7C 潼 (<CJK Ideograph>) 18998 0x6F7A 潺 (<CJK Ideograph>) 18999 0x6FD1 濑 (<CJK Ideograph>) 19000 0x930A 錊 (<CJK Ideograph>) 19001 0x930B 錋 (<CJK Ideograph>) 19002 0x930C 錌 (<CJK Ideograph>) 19003 0x930D 錍 (<CJK Ideograph>) 19004 0x930E 錎 (<CJK Ideograph>) 19005 0x930F 錏 (<CJK Ideograph>) 19006 0x9310 錐 (<CJK Ideograph>) 19007 0x9311 錑 (<CJK Ideograph>) 19008 0x9312 錒 (<CJK Ideograph>) 19009 0x9313 錓 (<CJK Ideograph>) 19010 0x9314 錔 (<CJK Ideograph>) 19011 0x9315 錕 (<CJK Ideograph>) 19012 0x9316 錖 (<CJK Ideograph>) 19013 0x9317 錗 (<CJK Ideograph>) 19014 0x9318 錘 (<CJK Ideograph>) 19015 0x9319 錙 (<CJK Ideograph>) 19016 0x931A 錚 (<CJK Ideograph>) 19017 0x931B 錛 (<CJK Ideograph>) 19018 0x931C 錜 (<CJK Ideograph>) 19019 0x931D 錝 (<CJK Ideograph>) 19020 0x931E 錞 (<CJK Ideograph>) 19021 0x931F 錟 (<CJK Ideograph>) 19022 0x9320 錠 (<CJK Ideograph>) 19023 0x9321 錡 (<CJK Ideograph>) 19024 0x9322 錢 (<CJK Ideograph>) 19025 0x9323 錣 (<CJK Ideograph>) 19026 0x9324 錤 (<CJK Ideograph>) 19027 0x9325 錥 (<CJK Ideograph>) 19028 0x9326 錦 (<CJK Ideograph>) 19029 0x9327 錧 (<CJK Ideograph>) 19030 0x9328 錨 (<CJK Ideograph>) 19031 0x9329 錩 (<CJK Ideograph>) 19032 0x932A 錪 (<CJK Ideograph>) 19033 0x932B 錫 (<CJK Ideograph>) 19034 0x932C 錬 (<CJK Ideograph>) 19035 0x932D 錭 (<CJK Ideograph>) 19036 0x932E 錮 (<CJK Ideograph>) 19037 0x932F 錯 (<CJK Ideograph>) 19038 0x9330 錰 (<CJK Ideograph>) 19039 0x9331 錱 (<CJK Ideograph>) 19040 0x9332 録 (<CJK Ideograph>) 19041 0x9333 錳 (<CJK Ideograph>) 19042 0x9334 錴 (<CJK Ideograph>) 19043 0x9335 錵 (<CJK Ideograph>) 19044 0x9336 錶 (<CJK Ideograph>) 19045 0x9337 錷 (<CJK Ideograph>) 19046 0x9338 錸 (<CJK Ideograph>) 19047 0x9339 錹 (<CJK Ideograph>) 19048 0x933A 錺 (<CJK Ideograph>) 19049 0x933B 錻 (<CJK Ideograph>) 19050 0x933C 錼 (<CJK Ideograph>) 19051 0x933D 錽 (<CJK Ideograph>) 19052 0x933F 錿 (<CJK Ideograph>) 19053 0x9340 鍀 (<CJK Ideograph>) 19054 0x9341 鍁 (<CJK Ideograph>) 19055 0x9342 鍂 (<CJK Ideograph>) 19056 0x9343 鍃 (<CJK Ideograph>) 19057 0x9344 鍄 (<CJK Ideograph>) 19058 0x9345 鍅 (<CJK Ideograph>) 19059 0x9346 鍆 (<CJK Ideograph>) 19060 0x9347 鍇 (<CJK Ideograph>) 19061 0x9348 鍈 (<CJK Ideograph>) 19062 0x9349 鍉 (<CJK Ideograph>) 19063 0x934A 鍊 (<CJK Ideograph>) 19064 0x934B 鍋 (<CJK Ideograph>) 19065 0x934C 鍌 (<CJK Ideograph>) 19066 0x934D 鍍 (<CJK Ideograph>) 19067 0x934E 鍎 (<CJK Ideograph>) 19068 0x934F 鍏 (<CJK Ideograph>) 19069 0x9350 鍐 (<CJK Ideograph>) 19070 0x9351 鍑 (<CJK Ideograph>) 19071 0x9352 鍒 (<CJK Ideograph>) 19072 0x9353 鍓 (<CJK Ideograph>) 19073 0x9354 鍔 (<CJK Ideograph>) 19074 0x9355 鍕 (<CJK Ideograph>) 19075 0x9356 鍖 (<CJK Ideograph>) 19076 0x9357 鍗 (<CJK Ideograph>) 19077 0x9358 鍘 (<CJK Ideograph>) 19078 0x9359 鍙 (<CJK Ideograph>) 19079 0x935A 鍚 (<CJK Ideograph>) 19080 0x935B 鍛 (<CJK Ideograph>) 19081 0x935C 鍜 (<CJK Ideograph>) 19082 0x935D 鍝 (<CJK Ideograph>) 19083 0x935E 鍞 (<CJK Ideograph>) 19084 0x935F 鍟 (<CJK Ideograph>) 19085 0x9360 鍠 (<CJK Ideograph>) 19086 0x9361 鍡 (<CJK Ideograph>) 19087 0x9362 鍢 (<CJK Ideograph>) 19088 0x9363 鍣 (<CJK Ideograph>) 19089 0x9364 鍤 (<CJK Ideograph>) 19090 0x9365 鍥 (<CJK Ideograph>) 19091 0x9366 鍦 (<CJK Ideograph>) 19092 0x9367 鍧 (<CJK Ideograph>) 19093 0x9368 鍨 (<CJK Ideograph>) 19094 0x9369 鍩 (<CJK Ideograph>) 19095 0x936B 鍫 (<CJK Ideograph>) 19096 0x6FC9 濉 (<CJK Ideograph>) 19097 0x6FA7 澧 (<CJK Ideograph>) 19098 0x6FB9 澹 (<CJK Ideograph>) 19099 0x6FB6 澶 (<CJK Ideograph>) 19100 0x6FC2 濂 (<CJK Ideograph>) 19101 0x6FE1 濡 (<CJK Ideograph>) 19102 0x6FEE 濮 (<CJK Ideograph>) 19103 0x6FDE 濞 (<CJK Ideograph>) 19104 0x6FE0 濠 (<CJK Ideograph>) 19105 0x6FEF 濯 (<CJK Ideograph>) 19106 0x701A 瀚 (<CJK Ideograph>) 19107 0x7023 瀣 (<CJK Ideograph>) 19108 0x701B 瀛 (<CJK Ideograph>) 19109 0x7039 瀹 (<CJK Ideograph>) 19110 0x7035 瀵 (<CJK Ideograph>) 19111 0x704F 灏 (<CJK Ideograph>) 19112 0x705E 灞 (<CJK Ideograph>) 19113 0x5B80 宀 (<CJK Ideograph>) 19114 0x5B84 宄 (<CJK Ideograph>) 19115 0x5B95 宕 (<CJK Ideograph>) 19116 0x5B93 宓 (<CJK Ideograph>) 19117 0x5BA5 宥 (<CJK Ideograph>) 19118 0x5BB8 宸 (<CJK Ideograph>) 19119 0x752F 甯 (<CJK Ideograph>) 19120 0x9A9E 骞 (<CJK Ideograph>) 19121 0x6434 搴 (<CJK Ideograph>) 19122 0x5BE4 寤 (<CJK Ideograph>) 19123 0x5BEE 寮 (<CJK Ideograph>) 19124 0x8930 褰 (<CJK Ideograph>) 19125 0x5BF0 寰 (<CJK Ideograph>) 19126 0x8E47 蹇 (<CJK Ideograph>) 19127 0x8B07 謇 (<CJK Ideograph>) 19128 0x8FB6 辶 (<CJK Ideograph>) 19129 0x8FD3 迓 (<CJK Ideograph>) 19130 0x8FD5 迕 (<CJK Ideograph>) 19131 0x8FE5 迥 (<CJK Ideograph>) 19132 0x8FEE 迮 (<CJK Ideograph>) 19133 0x8FE4 迤 (<CJK Ideograph>) 19134 0x8FE9 迩 (<CJK Ideograph>) 19135 0x8FE6 迦 (<CJK Ideograph>) 19136 0x8FF3 迳 (<CJK Ideograph>) 19137 0x8FE8 迨 (<CJK Ideograph>) 19138 0x9005 逅 (<CJK Ideograph>) 19139 0x9004 逄 (<CJK Ideograph>) 19140 0x900B 逋 (<CJK Ideograph>) 19141 0x9026 逦 (<CJK Ideograph>) 19142 0x9011 逑 (<CJK Ideograph>) 19143 0x900D 逍 (<CJK Ideograph>) 19144 0x9016 逖 (<CJK Ideograph>) 19145 0x9021 逡 (<CJK Ideograph>) 19146 0x9035 逵 (<CJK Ideograph>) 19147 0x9036 逶 (<CJK Ideograph>) 19148 0x902D 逭 (<CJK Ideograph>) 19149 0x902F 逯 (<CJK Ideograph>) 19150 0x9044 遄 (<CJK Ideograph>) 19151 0x9051 遑 (<CJK Ideograph>) 19152 0x9052 遒 (<CJK Ideograph>) 19153 0x9050 遐 (<CJK Ideograph>) 19154 0x9068 遨 (<CJK Ideograph>) 19155 0x9058 遘 (<CJK Ideograph>) 19156 0x9062 遢 (<CJK Ideograph>) 19157 0x905B 遛 (<CJK Ideograph>) 19158 0x66B9 暹 (<CJK Ideograph>) 19159 0x9074 遴 (<CJK Ideograph>) 19160 0x907D 遽 (<CJK Ideograph>) 19161 0x9082 邂 (<CJK Ideograph>) 19162 0x9088 邈 (<CJK Ideograph>) 19163 0x9083 邃 (<CJK Ideograph>) 19164 0x908B 邋 (<CJK Ideograph>) 19165 0x5F50 彐 (<CJK Ideograph>) 19166 0x5F57 彗 (<CJK Ideograph>) 19167 0x5F56 彖 (<CJK Ideograph>) 19168 0x5F58 彘 (<CJK Ideograph>) 19169 0x5C3B 尻 (<CJK Ideograph>) 19170 0x54AB 咫 (<CJK Ideograph>) 19171 0x5C50 屐 (<CJK Ideograph>) 19172 0x5C59 屙 (<CJK Ideograph>) 19173 0x5B71 孱 (<CJK Ideograph>) 19174 0x5C63 屣 (<CJK Ideograph>) 19175 0x5C66 屦 (<CJK Ideograph>) 19176 0x7FBC 羼 (<CJK Ideograph>) 19177 0x5F2A 弪 (<CJK Ideograph>) 19178 0x5F29 弩 (<CJK Ideograph>) 19179 0x5F2D 弭 (<CJK Ideograph>) 19180 0x8274 艴 (<CJK Ideograph>) 19181 0x5F3C 弼 (<CJK Ideograph>) 19182 0x9B3B 鬻 (<CJK Ideograph>) 19183 0x5C6E 屮 (<CJK Ideograph>) 19184 0x5981 妁 (<CJK Ideograph>) 19185 0x5983 妃 (<CJK Ideograph>) 19186 0x598D 妍 (<CJK Ideograph>) 19187 0x59A9 妩 (<CJK Ideograph>) 19188 0x59AA 妪 (<CJK Ideograph>) 19189 0x59A3 妣 (<CJK Ideograph>) 19190 0x936C 鍬 (<CJK Ideograph>) 19191 0x936D 鍭 (<CJK Ideograph>) 19192 0x936E 鍮 (<CJK Ideograph>) 19193 0x936F 鍯 (<CJK Ideograph>) 19194 0x9370 鍰 (<CJK Ideograph>) 19195 0x9371 鍱 (<CJK Ideograph>) 19196 0x9372 鍲 (<CJK Ideograph>) 19197 0x9373 鍳 (<CJK Ideograph>) 19198 0x9374 鍴 (<CJK Ideograph>) 19199 0x9375 鍵 (<CJK Ideograph>) 19200 0x9376 鍶 (<CJK Ideograph>) 19201 0x9377 鍷 (<CJK Ideograph>) 19202 0x9378 鍸 (<CJK Ideograph>) 19203 0x9379 鍹 (<CJK Ideograph>) 19204 0x937A 鍺 (<CJK Ideograph>) 19205 0x937B 鍻 (<CJK Ideograph>) 19206 0x937C 鍼 (<CJK Ideograph>) 19207 0x937D 鍽 (<CJK Ideograph>) 19208 0x937E 鍾 (<CJK Ideograph>) 19209 0x937F 鍿 (<CJK Ideograph>) 19210 0x9380 鎀 (<CJK Ideograph>) 19211 0x9381 鎁 (<CJK Ideograph>) 19212 0x9382 鎂 (<CJK Ideograph>) 19213 0x9383 鎃 (<CJK Ideograph>) 19214 0x9384 鎄 (<CJK Ideograph>) 19215 0x9385 鎅 (<CJK Ideograph>) 19216 0x9386 鎆 (<CJK Ideograph>) 19217 0x9387 鎇 (<CJK Ideograph>) 19218 0x9388 鎈 (<CJK Ideograph>) 19219 0x9389 鎉 (<CJK Ideograph>) 19220 0x938A 鎊 (<CJK Ideograph>) 19221 0x938B 鎋 (<CJK Ideograph>) 19222 0x938C 鎌 (<CJK Ideograph>) 19223 0x938D 鎍 (<CJK Ideograph>) 19224 0x938E 鎎 (<CJK Ideograph>) 19225 0x9390 鎐 (<CJK Ideograph>) 19226 0x9391 鎑 (<CJK Ideograph>) 19227 0x9392 鎒 (<CJK Ideograph>) 19228 0x9393 鎓 (<CJK Ideograph>) 19229 0x9394 鎔 (<CJK Ideograph>) 19230 0x9395 鎕 (<CJK Ideograph>) 19231 0x9396 鎖 (<CJK Ideograph>) 19232 0x9397 鎗 (<CJK Ideograph>) 19233 0x9398 鎘 (<CJK Ideograph>) 19234 0x9399 鎙 (<CJK Ideograph>) 19235 0x939A 鎚 (<CJK Ideograph>) 19236 0x939B 鎛 (<CJK Ideograph>) 19237 0x939C 鎜 (<CJK Ideograph>) 19238 0x939D 鎝 (<CJK Ideograph>) 19239 0x939E 鎞 (<CJK Ideograph>) 19240 0x939F 鎟 (<CJK Ideograph>) 19241 0x93A0 鎠 (<CJK Ideograph>) 19242 0x93A1 鎡 (<CJK Ideograph>) 19243 0x93A2 鎢 (<CJK Ideograph>) 19244 0x93A3 鎣 (<CJK Ideograph>) 19245 0x93A4 鎤 (<CJK Ideograph>) 19246 0x93A5 鎥 (<CJK Ideograph>) 19247 0x93A6 鎦 (<CJK Ideograph>) 19248 0x93A7 鎧 (<CJK Ideograph>) 19249 0x93A8 鎨 (<CJK Ideograph>) 19250 0x93A9 鎩 (<CJK Ideograph>) 19251 0x93AA 鎪 (<CJK Ideograph>) 19252 0x93AB 鎫 (<CJK Ideograph>) 19253 0x93AC 鎬 (<CJK Ideograph>) 19254 0x93AD 鎭 (<CJK Ideograph>) 19255 0x93AE 鎮 (<CJK Ideograph>) 19256 0x93AF 鎯 (<CJK Ideograph>) 19257 0x93B0 鎰 (<CJK Ideograph>) 19258 0x93B1 鎱 (<CJK Ideograph>) 19259 0x93B2 鎲 (<CJK Ideograph>) 19260 0x93B3 鎳 (<CJK Ideograph>) 19261 0x93B4 鎴 (<CJK Ideograph>) 19262 0x93B5 鎵 (<CJK Ideograph>) 19263 0x93B6 鎶 (<CJK Ideograph>) 19264 0x93B7 鎷 (<CJK Ideograph>) 19265 0x93B8 鎸 (<CJK Ideograph>) 19266 0x93B9 鎹 (<CJK Ideograph>) 19267 0x93BA 鎺 (<CJK Ideograph>) 19268 0x93BB 鎻 (<CJK Ideograph>) 19269 0x93BC 鎼 (<CJK Ideograph>) 19270 0x93BD 鎽 (<CJK Ideograph>) 19271 0x93BE 鎾 (<CJK Ideograph>) 19272 0x93BF 鎿 (<CJK Ideograph>) 19273 0x93C0 鏀 (<CJK Ideograph>) 19274 0x93C1 鏁 (<CJK Ideograph>) 19275 0x93C2 鏂 (<CJK Ideograph>) 19276 0x93C3 鏃 (<CJK Ideograph>) 19277 0x93C4 鏄 (<CJK Ideograph>) 19278 0x93C5 鏅 (<CJK Ideograph>) 19279 0x93C6 鏆 (<CJK Ideograph>) 19280 0x93C7 鏇 (<CJK Ideograph>) 19281 0x93C8 鏈 (<CJK Ideograph>) 19282 0x93C9 鏉 (<CJK Ideograph>) 19283 0x93CB 鏋 (<CJK Ideograph>) 19284 0x93CC 鏌 (<CJK Ideograph>) 19285 0x93CD 鏍 (<CJK Ideograph>) 19286 0x5997 妗 (<CJK Ideograph>) 19287 0x59CA 姊 (<CJK Ideograph>) 19288 0x59AB 妫 (<CJK Ideograph>) 19289 0x599E 妞 (<CJK Ideograph>) 19290 0x59A4 妤 (<CJK Ideograph>) 19291 0x59D2 姒 (<CJK Ideograph>) 19292 0x59B2 妲 (<CJK Ideograph>) 19293 0x59AF 妯 (<CJK Ideograph>) 19294 0x59D7 姗 (<CJK Ideograph>) 19295 0x59BE 妾 (<CJK Ideograph>) 19296 0x5A05 娅 (<CJK Ideograph>) 19297 0x5A06 娆 (<CJK Ideograph>) 19298 0x59DD 姝 (<CJK Ideograph>) 19299 0x5A08 娈 (<CJK Ideograph>) 19300 0x59E3 姣 (<CJK Ideograph>) 19301 0x59D8 姘 (<CJK Ideograph>) 19302 0x59F9 姹 (<CJK Ideograph>) 19303 0x5A0C 娌 (<CJK Ideograph>) 19304 0x5A09 娉 (<CJK Ideograph>) 19305 0x5A32 娲 (<CJK Ideograph>) 19306 0x5A34 娴 (<CJK Ideograph>) 19307 0x5A11 娑 (<CJK Ideograph>) 19308 0x5A23 娣 (<CJK Ideograph>) 19309 0x5A13 娓 (<CJK Ideograph>) 19310 0x5A40 婀 (<CJK Ideograph>) 19311 0x5A67 婧 (<CJK Ideograph>) 19312 0x5A4A 婊 (<CJK Ideograph>) 19313 0x5A55 婕 (<CJK Ideograph>) 19314 0x5A3C 娼 (<CJK Ideograph>) 19315 0x5A62 婢 (<CJK Ideograph>) 19316 0x5A75 婵 (<CJK Ideograph>) 19317 0x80EC 胬 (<CJK Ideograph>) 19318 0x5AAA 媪 (<CJK Ideograph>) 19319 0x5A9B 媛 (<CJK Ideograph>) 19320 0x5A77 婷 (<CJK Ideograph>) 19321 0x5A7A 婺 (<CJK Ideograph>) 19322 0x5ABE 媾 (<CJK Ideograph>) 19323 0x5AEB 嫫 (<CJK Ideograph>) 19324 0x5AB2 媲 (<CJK Ideograph>) 19325 0x5AD2 嫒 (<CJK Ideograph>) 19326 0x5AD4 嫔 (<CJK Ideograph>) 19327 0x5AB8 媸 (<CJK Ideograph>) 19328 0x5AE0 嫠 (<CJK Ideograph>) 19329 0x5AE3 嫣 (<CJK Ideograph>) 19330 0x5AF1 嫱 (<CJK Ideograph>) 19331 0x5AD6 嫖 (<CJK Ideograph>) 19332 0x5AE6 嫦 (<CJK Ideograph>) 19333 0x5AD8 嫘 (<CJK Ideograph>) 19334 0x5ADC 嫜 (<CJK Ideograph>) 19335 0x5B09 嬉 (<CJK Ideograph>) 19336 0x5B17 嬗 (<CJK Ideograph>) 19337 0x5B16 嬖 (<CJK Ideograph>) 19338 0x5B32 嬲 (<CJK Ideograph>) 19339 0x5B37 嬷 (<CJK Ideograph>) 19340 0x5B40 孀 (<CJK Ideograph>) 19341 0x5C15 尕 (<CJK Ideograph>) 19342 0x5C1C 尜 (<CJK Ideograph>) 19343 0x5B5A 孚 (<CJK Ideograph>) 19344 0x5B65 孥 (<CJK Ideograph>) 19345 0x5B73 孳 (<CJK Ideograph>) 19346 0x5B51 孑 (<CJK Ideograph>) 19347 0x5B53 孓 (<CJK Ideograph>) 19348 0x5B62 孢 (<CJK Ideograph>) 19349 0x9A75 驵 (<CJK Ideograph>) 19350 0x9A77 驷 (<CJK Ideograph>) 19351 0x9A78 驸 (<CJK Ideograph>) 19352 0x9A7A 驺 (<CJK Ideograph>) 19353 0x9A7F 驿 (<CJK Ideograph>) 19354 0x9A7D 驽 (<CJK Ideograph>) 19355 0x9A80 骀 (<CJK Ideograph>) 19356 0x9A81 骁 (<CJK Ideograph>) 19357 0x9A85 骅 (<CJK Ideograph>) 19358 0x9A88 骈 (<CJK Ideograph>) 19359 0x9A8A 骊 (<CJK Ideograph>) 19360 0x9A90 骐 (<CJK Ideograph>) 19361 0x9A92 骒 (<CJK Ideograph>) 19362 0x9A93 骓 (<CJK Ideograph>) 19363 0x9A96 骖 (<CJK Ideograph>) 19364 0x9A98 骘 (<CJK Ideograph>) 19365 0x9A9B 骛 (<CJK Ideograph>) 19366 0x9A9C 骜 (<CJK Ideograph>) 19367 0x9A9D 骝 (<CJK Ideograph>) 19368 0x9A9F 骟 (<CJK Ideograph>) 19369 0x9AA0 骠 (<CJK Ideograph>) 19370 0x9AA2 骢 (<CJK Ideograph>) 19371 0x9AA3 骣 (<CJK Ideograph>) 19372 0x9AA5 骥 (<CJK Ideograph>) 19373 0x9AA7 骧 (<CJK Ideograph>) 19374 0x7E9F 纟 (<CJK Ideograph>) 19375 0x7EA1 纡 (<CJK Ideograph>) 19376 0x7EA3 纣 (<CJK Ideograph>) 19377 0x7EA5 纥 (<CJK Ideograph>) 19378 0x7EA8 纨 (<CJK Ideograph>) 19379 0x7EA9 纩 (<CJK Ideograph>) 19380 0x93CE 鏎 (<CJK Ideograph>) 19381 0x93CF 鏏 (<CJK Ideograph>) 19382 0x93D0 鏐 (<CJK Ideograph>) 19383 0x93D1 鏑 (<CJK Ideograph>) 19384 0x93D2 鏒 (<CJK Ideograph>) 19385 0x93D3 鏓 (<CJK Ideograph>) 19386 0x93D4 鏔 (<CJK Ideograph>) 19387 0x93D5 鏕 (<CJK Ideograph>) 19388 0x93D7 鏗 (<CJK Ideograph>) 19389 0x93D8 鏘 (<CJK Ideograph>) 19390 0x93D9 鏙 (<CJK Ideograph>) 19391 0x93DA 鏚 (<CJK Ideograph>) 19392 0x93DB 鏛 (<CJK Ideograph>) 19393 0x93DC 鏜 (<CJK Ideograph>) 19394 0x93DD 鏝 (<CJK Ideograph>) 19395 0x93DE 鏞 (<CJK Ideograph>) 19396 0x93DF 鏟 (<CJK Ideograph>) 19397 0x93E0 鏠 (<CJK Ideograph>) 19398 0x93E1 鏡 (<CJK Ideograph>) 19399 0x93E2 鏢 (<CJK Ideograph>) 19400 0x93E3 鏣 (<CJK Ideograph>) 19401 0x93E4 鏤 (<CJK Ideograph>) 19402 0x93E5 鏥 (<CJK Ideograph>) 19403 0x93E6 鏦 (<CJK Ideograph>) 19404 0x93E7 鏧 (<CJK Ideograph>) 19405 0x93E8 鏨 (<CJK Ideograph>) 19406 0x93E9 鏩 (<CJK Ideograph>) 19407 0x93EA 鏪 (<CJK Ideograph>) 19408 0x93EB 鏫 (<CJK Ideograph>) 19409 0x93EC 鏬 (<CJK Ideograph>) 19410 0x93ED 鏭 (<CJK Ideograph>) 19411 0x93EE 鏮 (<CJK Ideograph>) 19412 0x93EF 鏯 (<CJK Ideograph>) 19413 0x93F0 鏰 (<CJK Ideograph>) 19414 0x93F1 鏱 (<CJK Ideograph>) 19415 0x93F2 鏲 (<CJK Ideograph>) 19416 0x93F3 鏳 (<CJK Ideograph>) 19417 0x93F4 鏴 (<CJK Ideograph>) 19418 0x93F5 鏵 (<CJK Ideograph>) 19419 0x93F6 鏶 (<CJK Ideograph>) 19420 0x93F7 鏷 (<CJK Ideograph>) 19421 0x93F8 鏸 (<CJK Ideograph>) 19422 0x93F9 鏹 (<CJK Ideograph>) 19423 0x93FA 鏺 (<CJK Ideograph>) 19424 0x93FB 鏻 (<CJK Ideograph>) 19425 0x93FC 鏼 (<CJK Ideograph>) 19426 0x93FD 鏽 (<CJK Ideograph>) 19427 0x93FE 鏾 (<CJK Ideograph>) 19428 0x93FF 鏿 (<CJK Ideograph>) 19429 0x9400 鐀 (<CJK Ideograph>) 19430 0x9401 鐁 (<CJK Ideograph>) 19431 0x9402 鐂 (<CJK Ideograph>) 19432 0x9403 鐃 (<CJK Ideograph>) 19433 0x9404 鐄 (<CJK Ideograph>) 19434 0x9405 鐅 (<CJK Ideograph>) 19435 0x9406 鐆 (<CJK Ideograph>) 19436 0x9407 鐇 (<CJK Ideograph>) 19437 0x9408 鐈 (<CJK Ideograph>) 19438 0x9409 鐉 (<CJK Ideograph>) 19439 0x940A 鐊 (<CJK Ideograph>) 19440 0x940B 鐋 (<CJK Ideograph>) 19441 0x940C 鐌 (<CJK Ideograph>) 19442 0x940D 鐍 (<CJK Ideograph>) 19443 0x940E 鐎 (<CJK Ideograph>) 19444 0x940F 鐏 (<CJK Ideograph>) 19445 0x9410 鐐 (<CJK Ideograph>) 19446 0x9411 鐑 (<CJK Ideograph>) 19447 0x9412 鐒 (<CJK Ideograph>) 19448 0x9413 鐓 (<CJK Ideograph>) 19449 0x9414 鐔 (<CJK Ideograph>) 19450 0x9415 鐕 (<CJK Ideograph>) 19451 0x9416 鐖 (<CJK Ideograph>) 19452 0x9417 鐗 (<CJK Ideograph>) 19453 0x9418 鐘 (<CJK Ideograph>) 19454 0x9419 鐙 (<CJK Ideograph>) 19455 0x941A 鐚 (<CJK Ideograph>) 19456 0x941B 鐛 (<CJK Ideograph>) 19457 0x941C 鐜 (<CJK Ideograph>) 19458 0x941D 鐝 (<CJK Ideograph>) 19459 0x941E 鐞 (<CJK Ideograph>) 19460 0x941F 鐟 (<CJK Ideograph>) 19461 0x9420 鐠 (<CJK Ideograph>) 19462 0x9421 鐡 (<CJK Ideograph>) 19463 0x9422 鐢 (<CJK Ideograph>) 19464 0x9423 鐣 (<CJK Ideograph>) 19465 0x9424 鐤 (<CJK Ideograph>) 19466 0x9425 鐥 (<CJK Ideograph>) 19467 0x9426 鐦 (<CJK Ideograph>) 19468 0x9427 鐧 (<CJK Ideograph>) 19469 0x9428 鐨 (<CJK Ideograph>) 19470 0x9429 鐩 (<CJK Ideograph>) 19471 0x942A 鐪 (<CJK Ideograph>) 19472 0x942B 鐫 (<CJK Ideograph>) 19473 0x942C 鐬 (<CJK Ideograph>) 19474 0x942D 鐭 (<CJK Ideograph>) 19475 0x942E 鐮 (<CJK Ideograph>) 19476 0x7EAD 纭 (<CJK Ideograph>) 19477 0x7EB0 纰 (<CJK Ideograph>) 19478 0x7EBE 纾 (<CJK Ideograph>) 19479 0x7EC0 绀 (<CJK Ideograph>) 19480 0x7EC1 绁 (<CJK Ideograph>) 19481 0x7EC2 绂 (<CJK Ideograph>) 19482 0x7EC9 绉 (<CJK Ideograph>) 19483 0x7ECB 绋 (<CJK Ideograph>) 19484 0x7ECC 绌 (<CJK Ideograph>) 19485 0x7ED0 绐 (<CJK Ideograph>) 19486 0x7ED4 绔 (<CJK Ideograph>) 19487 0x7ED7 绗 (<CJK Ideograph>) 19488 0x7EDB 绛 (<CJK Ideograph>) 19489 0x7EE0 绠 (<CJK Ideograph>) 19490 0x7EE1 绡 (<CJK Ideograph>) 19491 0x7EE8 绨 (<CJK Ideograph>) 19492 0x7EEB 绫 (<CJK Ideograph>) 19493 0x7EEE 绮 (<CJK Ideograph>) 19494 0x7EEF 绯 (<CJK Ideograph>) 19495 0x7EF1 绱 (<CJK Ideograph>) 19496 0x7EF2 绲 (<CJK Ideograph>) 19497 0x7F0D 缍 (<CJK Ideograph>) 19498 0x7EF6 绶 (<CJK Ideograph>) 19499 0x7EFA 绺 (<CJK Ideograph>) 19500 0x7EFB 绻 (<CJK Ideograph>) 19501 0x7EFE 绾 (<CJK Ideograph>) 19502 0x7F01 缁 (<CJK Ideograph>) 19503 0x7F02 缂 (<CJK Ideograph>) 19504 0x7F03 缃 (<CJK Ideograph>) 19505 0x7F07 缇 (<CJK Ideograph>) 19506 0x7F08 缈 (<CJK Ideograph>) 19507 0x7F0B 缋 (<CJK Ideograph>) 19508 0x7F0C 缌 (<CJK Ideograph>) 19509 0x7F0F 缏 (<CJK Ideograph>) 19510 0x7F11 缑 (<CJK Ideograph>) 19511 0x7F12 缒 (<CJK Ideograph>) 19512 0x7F17 缗 (<CJK Ideograph>) 19513 0x7F19 缙 (<CJK Ideograph>) 19514 0x7F1C 缜 (<CJK Ideograph>) 19515 0x7F1B 缛 (<CJK Ideograph>) 19516 0x7F1F 缟 (<CJK Ideograph>) 19517 0x7F21 缡 (<CJK Ideograph>) 19518 0x7F22 缢 (<CJK Ideograph>) 19519 0x7F23 缣 (<CJK Ideograph>) 19520 0x7F24 缤 (<CJK Ideograph>) 19521 0x7F25 缥 (<CJK Ideograph>) 19522 0x7F26 缦 (<CJK Ideograph>) 19523 0x7F27 缧 (<CJK Ideograph>) 19524 0x7F2A 缪 (<CJK Ideograph>) 19525 0x7F2B 缫 (<CJK Ideograph>) 19526 0x7F2C 缬 (<CJK Ideograph>) 19527 0x7F2D 缭 (<CJK Ideograph>) 19528 0x7F2F 缯 (<CJK Ideograph>) 19529 0x7F30 缰 (<CJK Ideograph>) 19530 0x7F31 缱 (<CJK Ideograph>) 19531 0x7F32 缲 (<CJK Ideograph>) 19532 0x7F33 缳 (<CJK Ideograph>) 19533 0x7F35 缵 (<CJK Ideograph>) 19534 0x5E7A 幺 (<CJK Ideograph>) 19535 0x757F 畿 (<CJK Ideograph>) 19536 0x5DDB 巛 (<CJK Ideograph>) 19537 0x753E 甾 (<CJK Ideograph>) 19538 0x9095 邕 (<CJK Ideograph>) 19539 0x738E 玎 (<CJK Ideograph>) 19540 0x7391 玑 (<CJK Ideograph>) 19541 0x73AE 玮 (<CJK Ideograph>) 19542 0x73A2 玢 (<CJK Ideograph>) 19543 0x739F 玟 (<CJK Ideograph>) 19544 0x73CF 珏 (<CJK Ideograph>) 19545 0x73C2 珂 (<CJK Ideograph>) 19546 0x73D1 珑 (<CJK Ideograph>) 19547 0x73B7 玷 (<CJK Ideograph>) 19548 0x73B3 玳 (<CJK Ideograph>) 19549 0x73C0 珀 (<CJK Ideograph>) 19550 0x73C9 珉 (<CJK Ideograph>) 19551 0x73C8 珈 (<CJK Ideograph>) 19552 0x73E5 珥 (<CJK Ideograph>) 19553 0x73D9 珙 (<CJK Ideograph>) 19554 0x987C 顼 (<CJK Ideograph>) 19555 0x740A 琊 (<CJK Ideograph>) 19556 0x73E9 珩 (<CJK Ideograph>) 19557 0x73E7 珧 (<CJK Ideograph>) 19558 0x73DE 珞 (<CJK Ideograph>) 19559 0x73BA 玺 (<CJK Ideograph>) 19560 0x73F2 珲 (<CJK Ideograph>) 19561 0x740F 琏 (<CJK Ideograph>) 19562 0x742A 琪 (<CJK Ideograph>) 19563 0x745B 瑛 (<CJK Ideograph>) 19564 0x7426 琦 (<CJK Ideograph>) 19565 0x7425 琥 (<CJK Ideograph>) 19566 0x7428 琨 (<CJK Ideograph>) 19567 0x7430 琰 (<CJK Ideograph>) 19568 0x742E 琮 (<CJK Ideograph>) 19569 0x742C 琬 (<CJK Ideograph>) 19570 0x942F 鐯 (<CJK Ideograph>) 19571 0x9430 鐰 (<CJK Ideograph>) 19572 0x9431 鐱 (<CJK Ideograph>) 19573 0x9432 鐲 (<CJK Ideograph>) 19574 0x9433 鐳 (<CJK Ideograph>) 19575 0x9434 鐴 (<CJK Ideograph>) 19576 0x9435 鐵 (<CJK Ideograph>) 19577 0x9436 鐶 (<CJK Ideograph>) 19578 0x9437 鐷 (<CJK Ideograph>) 19579 0x9438 鐸 (<CJK Ideograph>) 19580 0x9439 鐹 (<CJK Ideograph>) 19581 0x943A 鐺 (<CJK Ideograph>) 19582 0x943B 鐻 (<CJK Ideograph>) 19583 0x943C 鐼 (<CJK Ideograph>) 19584 0x943D 鐽 (<CJK Ideograph>) 19585 0x943F 鐿 (<CJK Ideograph>) 19586 0x9440 鑀 (<CJK Ideograph>) 19587 0x9441 鑁 (<CJK Ideograph>) 19588 0x9442 鑂 (<CJK Ideograph>) 19589 0x9443 鑃 (<CJK Ideograph>) 19590 0x9444 鑄 (<CJK Ideograph>) 19591 0x9445 鑅 (<CJK Ideograph>) 19592 0x9446 鑆 (<CJK Ideograph>) 19593 0x9447 鑇 (<CJK Ideograph>) 19594 0x9448 鑈 (<CJK Ideograph>) 19595 0x9449 鑉 (<CJK Ideograph>) 19596 0x944A 鑊 (<CJK Ideograph>) 19597 0x944B 鑋 (<CJK Ideograph>) 19598 0x944C 鑌 (<CJK Ideograph>) 19599 0x944D 鑍 (<CJK Ideograph>) 19600 0x944E 鑎 (<CJK Ideograph>) 19601 0x944F 鑏 (<CJK Ideograph>) 19602 0x9450 鑐 (<CJK Ideograph>) 19603 0x9451 鑑 (<CJK Ideograph>) 19604 0x9452 鑒 (<CJK Ideograph>) 19605 0x9453 鑓 (<CJK Ideograph>) 19606 0x9454 鑔 (<CJK Ideograph>) 19607 0x9455 鑕 (<CJK Ideograph>) 19608 0x9456 鑖 (<CJK Ideograph>) 19609 0x9457 鑗 (<CJK Ideograph>) 19610 0x9458 鑘 (<CJK Ideograph>) 19611 0x9459 鑙 (<CJK Ideograph>) 19612 0x945A 鑚 (<CJK Ideograph>) 19613 0x945B 鑛 (<CJK Ideograph>) 19614 0x945C 鑜 (<CJK Ideograph>) 19615 0x945D 鑝 (<CJK Ideograph>) 19616 0x945E 鑞 (<CJK Ideograph>) 19617 0x945F 鑟 (<CJK Ideograph>) 19618 0x9460 鑠 (<CJK Ideograph>) 19619 0x9461 鑡 (<CJK Ideograph>) 19620 0x9462 鑢 (<CJK Ideograph>) 19621 0x9463 鑣 (<CJK Ideograph>) 19622 0x9464 鑤 (<CJK Ideograph>) 19623 0x9465 鑥 (<CJK Ideograph>) 19624 0x9466 鑦 (<CJK Ideograph>) 19625 0x9467 鑧 (<CJK Ideograph>) 19626 0x9468 鑨 (<CJK Ideograph>) 19627 0x9469 鑩 (<CJK Ideograph>) 19628 0x946A 鑪 (<CJK Ideograph>) 19629 0x946C 鑬 (<CJK Ideograph>) 19630 0x946D 鑭 (<CJK Ideograph>) 19631 0x946E 鑮 (<CJK Ideograph>) 19632 0x946F 鑯 (<CJK Ideograph>) 19633 0x9470 鑰 (<CJK Ideograph>) 19634 0x9471 鑱 (<CJK Ideograph>) 19635 0x9472 鑲 (<CJK Ideograph>) 19636 0x9473 鑳 (<CJK Ideograph>) 19637 0x9474 鑴 (<CJK Ideograph>) 19638 0x9475 鑵 (<CJK Ideograph>) 19639 0x9476 鑶 (<CJK Ideograph>) 19640 0x9477 鑷 (<CJK Ideograph>) 19641 0x9478 鑸 (<CJK Ideograph>) 19642 0x9479 鑹 (<CJK Ideograph>) 19643 0x947A 鑺 (<CJK Ideograph>) 19644 0x947B 鑻 (<CJK Ideograph>) 19645 0x947C 鑼 (<CJK Ideograph>) 19646 0x947D 鑽 (<CJK Ideograph>) 19647 0x947E 鑾 (<CJK Ideograph>) 19648 0x947F 鑿 (<CJK Ideograph>) 19649 0x9480 钀 (<CJK Ideograph>) 19650 0x9481 钁 (<CJK Ideograph>) 19651 0x9482 钂 (<CJK Ideograph>) 19652 0x9483 钃 (<CJK Ideograph>) 19653 0x9484 钄 (<CJK Ideograph>) 19654 0x9491 钑 (<CJK Ideograph>) 19655 0x9496 钖 (<CJK Ideograph>) 19656 0x9498 钘 (<CJK Ideograph>) 19657 0x94C7 铇 (<CJK Ideograph>) 19658 0x94CF 铏 (<CJK Ideograph>) 19659 0x94D3 铓 (<CJK Ideograph>) 19660 0x94D4 铔 (<CJK Ideograph>) 19661 0x94DA 铚 (<CJK Ideograph>) 19662 0x94E6 铦 (<CJK Ideograph>) 19663 0x94FB 铻 (<CJK Ideograph>) 19664 0x951C 锜 (<CJK Ideograph>) 19665 0x9520 锠 (<CJK Ideograph>) 19666 0x741B 琛 (<CJK Ideograph>) 19667 0x741A 琚 (<CJK Ideograph>) 19668 0x7441 瑁 (<CJK Ideograph>) 19669 0x745C 瑜 (<CJK Ideograph>) 19670 0x7457 瑗 (<CJK Ideograph>) 19671 0x7455 瑕 (<CJK Ideograph>) 19672 0x7459 瑙 (<CJK Ideograph>) 19673 0x7477 瑷 (<CJK Ideograph>) 19674 0x746D 瑭 (<CJK Ideograph>) 19675 0x747E 瑾 (<CJK Ideograph>) 19676 0x749C 璜 (<CJK Ideograph>) 19677 0x748E 璎 (<CJK Ideograph>) 19678 0x7480 璀 (<CJK Ideograph>) 19679 0x7481 璁 (<CJK Ideograph>) 19680 0x7487 璇 (<CJK Ideograph>) 19681 0x748B 璋 (<CJK Ideograph>) 19682 0x749E 璞 (<CJK Ideograph>) 19683 0x74A8 璨 (<CJK Ideograph>) 19684 0x74A9 璩 (<CJK Ideograph>) 19685 0x7490 璐 (<CJK Ideograph>) 19686 0x74A7 璧 (<CJK Ideograph>) 19687 0x74D2 瓒 (<CJK Ideograph>) 19688 0x74BA 璺 (<CJK Ideograph>) 19689 0x97EA 韪 (<CJK Ideograph>) 19690 0x97EB 韫 (<CJK Ideograph>) 19691 0x97EC 韬 (<CJK Ideograph>) 19692 0x674C 杌 (<CJK Ideograph>) 19693 0x6753 杓 (<CJK Ideograph>) 19694 0x675E 杞 (<CJK Ideograph>) 19695 0x6748 杈 (<CJK Ideograph>) 19696 0x6769 杩 (<CJK Ideograph>) 19697 0x67A5 枥 (<CJK Ideograph>) 19698 0x6787 枇 (<CJK Ideograph>) 19699 0x676A 杪 (<CJK Ideograph>) 19700 0x6773 杳 (<CJK Ideograph>) 19701 0x6798 枘 (<CJK Ideograph>) 19702 0x67A7 枧 (<CJK Ideograph>) 19703 0x6775 杵 (<CJK Ideograph>) 19704 0x67A8 枨 (<CJK Ideograph>) 19705 0x679E 枞 (<CJK Ideograph>) 19706 0x67AD 枭 (<CJK Ideograph>) 19707 0x678B 枋 (<CJK Ideograph>) 19708 0x6777 杷 (<CJK Ideograph>) 19709 0x677C 杼 (<CJK Ideograph>) 19710 0x67F0 柰 (<CJK Ideograph>) 19711 0x6809 栉 (<CJK Ideograph>) 19712 0x67D8 柘 (<CJK Ideograph>) 19713 0x680A 栊 (<CJK Ideograph>) 19714 0x67E9 柩 (<CJK Ideograph>) 19715 0x67B0 枰 (<CJK Ideograph>) 19716 0x680C 栌 (<CJK Ideograph>) 19717 0x67D9 柙 (<CJK Ideograph>) 19718 0x67B5 枵 (<CJK Ideograph>) 19719 0x67DA 柚 (<CJK Ideograph>) 19720 0x67B3 枳 (<CJK Ideograph>) 19721 0x67DD 柝 (<CJK Ideograph>) 19722 0x6800 栀 (<CJK Ideograph>) 19723 0x67C3 柃 (<CJK Ideograph>) 19724 0x67B8 枸 (<CJK Ideograph>) 19725 0x67E2 柢 (<CJK Ideograph>) 19726 0x680E 栎 (<CJK Ideograph>) 19727 0x67C1 柁 (<CJK Ideograph>) 19728 0x67FD 柽 (<CJK Ideograph>) 19729 0x6832 栲 (<CJK Ideograph>) 19730 0x6833 栳 (<CJK Ideograph>) 19731 0x6860 桠 (<CJK Ideograph>) 19732 0x6861 桡 (<CJK Ideograph>) 19733 0x684E 桎 (<CJK Ideograph>) 19734 0x6862 桢 (<CJK Ideograph>) 19735 0x6844 桄 (<CJK Ideograph>) 19736 0x6864 桤 (<CJK Ideograph>) 19737 0x6883 梃 (<CJK Ideograph>) 19738 0x681D 栝 (<CJK Ideograph>) 19739 0x6855 桕 (<CJK Ideograph>) 19740 0x6866 桦 (<CJK Ideograph>) 19741 0x6841 桁 (<CJK Ideograph>) 19742 0x6867 桧 (<CJK Ideograph>) 19743 0x6840 桀 (<CJK Ideograph>) 19744 0x683E 栾 (<CJK Ideograph>) 19745 0x684A 桊 (<CJK Ideograph>) 19746 0x6849 桉 (<CJK Ideograph>) 19747 0x6829 栩 (<CJK Ideograph>) 19748 0x68B5 梵 (<CJK Ideograph>) 19749 0x688F 梏 (<CJK Ideograph>) 19750 0x6874 桴 (<CJK Ideograph>) 19751 0x6877 桷 (<CJK Ideograph>) 19752 0x6893 梓 (<CJK Ideograph>) 19753 0x686B 桫 (<CJK Ideograph>) 19754 0x68C2 棂 (<CJK Ideograph>) 19755 0x696E 楮 (<CJK Ideograph>) 19756 0x68FC 棼 (<CJK Ideograph>) 19757 0x691F 椟 (<CJK Ideograph>) 19758 0x6920 椠 (<CJK Ideograph>) 19759 0x68F9 棹 (<CJK Ideograph>) 19760 0x9527 锧 (<CJK Ideograph>) 19761 0x9533 锳 (<CJK Ideograph>) 19762 0x953D 锽 (<CJK Ideograph>) 19763 0x9543 镃 (<CJK Ideograph>) 19764 0x9548 镈 (<CJK Ideograph>) 19765 0x954B 镋 (<CJK Ideograph>) 19766 0x9555 镕 (<CJK Ideograph>) 19767 0x955A 镚 (<CJK Ideograph>) 19768 0x9560 镠 (<CJK Ideograph>) 19769 0x956E 镮 (<CJK Ideograph>) 19770 0x9574 镴 (<CJK Ideograph>) 19771 0x9575 镵 (<CJK Ideograph>) 19772 0x9577 長 (<CJK Ideograph>) 19773 0x9578 镸 (<CJK Ideograph>) 19774 0x9579 镹 (<CJK Ideograph>) 19775 0x957A 镺 (<CJK Ideograph>) 19776 0x957B 镻 (<CJK Ideograph>) 19777 0x957C 镼 (<CJK Ideograph>) 19778 0x957D 镽 (<CJK Ideograph>) 19779 0x957E 镾 (<CJK Ideograph>) 19780 0x9580 門 (<CJK Ideograph>) 19781 0x9581 閁 (<CJK Ideograph>) 19782 0x9582 閂 (<CJK Ideograph>) 19783 0x9583 閃 (<CJK Ideograph>) 19784 0x9584 閄 (<CJK Ideograph>) 19785 0x9585 閅 (<CJK Ideograph>) 19786 0x9586 閆 (<CJK Ideograph>) 19787 0x9587 閇 (<CJK Ideograph>) 19788 0x9588 閈 (<CJK Ideograph>) 19789 0x9589 閉 (<CJK Ideograph>) 19790 0x958A 閊 (<CJK Ideograph>) 19791 0x958B 開 (<CJK Ideograph>) 19792 0x958C 閌 (<CJK Ideograph>) 19793 0x958D 閍 (<CJK Ideograph>) 19794 0x958E 閎 (<CJK Ideograph>) 19795 0x958F 閏 (<CJK Ideograph>) 19796 0x9590 閐 (<CJK Ideograph>) 19797 0x9591 閑 (<CJK Ideograph>) 19798 0x9592 閒 (<CJK Ideograph>) 19799 0x9593 間 (<CJK Ideograph>) 19800 0x9594 閔 (<CJK Ideograph>) 19801 0x9595 閕 (<CJK Ideograph>) 19802 0x9596 閖 (<CJK Ideograph>) 19803 0x9597 閗 (<CJK Ideograph>) 19804 0x9598 閘 (<CJK Ideograph>) 19805 0x9599 閙 (<CJK Ideograph>) 19806 0x959A 閚 (<CJK Ideograph>) 19807 0x959B 閛 (<CJK Ideograph>) 19808 0x959C 閜 (<CJK Ideograph>) 19809 0x959D 閝 (<CJK Ideograph>) 19810 0x959E 閞 (<CJK Ideograph>) 19811 0x959F 閟 (<CJK Ideograph>) 19812 0x95A0 閠 (<CJK Ideograph>) 19813 0x95A1 閡 (<CJK Ideograph>) 19814 0x95A2 関 (<CJK Ideograph>) 19815 0x95A3 閣 (<CJK Ideograph>) 19816 0x95A4 閤 (<CJK Ideograph>) 19817 0x95A5 閥 (<CJK Ideograph>) 19818 0x95A6 閦 (<CJK Ideograph>) 19819 0x95A7 閧 (<CJK Ideograph>) 19820 0x95A8 閨 (<CJK Ideograph>) 19821 0x95A9 閩 (<CJK Ideograph>) 19822 0x95AA 閪 (<CJK Ideograph>) 19823 0x95AB 閫 (<CJK Ideograph>) 19824 0x95AC 閬 (<CJK Ideograph>) 19825 0x95AD 閭 (<CJK Ideograph>) 19826 0x95AE 閮 (<CJK Ideograph>) 19827 0x95AF 閯 (<CJK Ideograph>) 19828 0x95B0 閰 (<CJK Ideograph>) 19829 0x95B1 閱 (<CJK Ideograph>) 19830 0x95B2 閲 (<CJK Ideograph>) 19831 0x95B3 閳 (<CJK Ideograph>) 19832 0x95B4 閴 (<CJK Ideograph>) 19833 0x95B5 閵 (<CJK Ideograph>) 19834 0x95B6 閶 (<CJK Ideograph>) 19835 0x95B7 閷 (<CJK Ideograph>) 19836 0x95B8 閸 (<CJK Ideograph>) 19837 0x95B9 閹 (<CJK Ideograph>) 19838 0x95BA 閺 (<CJK Ideograph>) 19839 0x95BB 閻 (<CJK Ideograph>) 19840 0x95BC 閼 (<CJK Ideograph>) 19841 0x95BD 閽 (<CJK Ideograph>) 19842 0x95BE 閾 (<CJK Ideograph>) 19843 0x95BF 閿 (<CJK Ideograph>) 19844 0x95C0 闀 (<CJK Ideograph>) 19845 0x95C1 闁 (<CJK Ideograph>) 19846 0x95C2 闂 (<CJK Ideograph>) 19847 0x95C3 闃 (<CJK Ideograph>) 19848 0x95C4 闄 (<CJK Ideograph>) 19849 0x95C5 闅 (<CJK Ideograph>) 19850 0x95C6 闆 (<CJK Ideograph>) 19851 0x95C7 闇 (<CJK Ideograph>) 19852 0x95C8 闈 (<CJK Ideograph>) 19853 0x95C9 闉 (<CJK Ideograph>) 19854 0x95CA 闊 (<CJK Ideograph>) 19855 0x95CB 闋 (<CJK Ideograph>) 19856 0x6924 椤 (<CJK Ideograph>) 19857 0x68F0 棰 (<CJK Ideograph>) 19858 0x690B 椋 (<CJK Ideograph>) 19859 0x6901 椁 (<CJK Ideograph>) 19860 0x6957 楗 (<CJK Ideograph>) 19861 0x68E3 棣 (<CJK Ideograph>) 19862 0x6910 椐 (<CJK Ideograph>) 19863 0x6971 楱 (<CJK Ideograph>) 19864 0x6939 椹 (<CJK Ideograph>) 19865 0x6960 楠 (<CJK Ideograph>) 19866 0x6942 楂 (<CJK Ideograph>) 19867 0x695D 楝 (<CJK Ideograph>) 19868 0x6984 榄 (<CJK Ideograph>) 19869 0x696B 楫 (<CJK Ideograph>) 19870 0x6980 榀 (<CJK Ideograph>) 19871 0x6998 榘 (<CJK Ideograph>) 19872 0x6978 楸 (<CJK Ideograph>) 19873 0x6934 椴 (<CJK Ideograph>) 19874 0x69CC 槌 (<CJK Ideograph>) 19875 0x6987 榇 (<CJK Ideograph>) 19876 0x6988 榈 (<CJK Ideograph>) 19877 0x69CE 槎 (<CJK Ideograph>) 19878 0x6989 榉 (<CJK Ideograph>) 19879 0x6966 楦 (<CJK Ideograph>) 19880 0x6963 楣 (<CJK Ideograph>) 19881 0x6979 楹 (<CJK Ideograph>) 19882 0x699B 榛 (<CJK Ideograph>) 19883 0x69A7 榧 (<CJK Ideograph>) 19884 0x69BB 榻 (<CJK Ideograph>) 19885 0x69AB 榫 (<CJK Ideograph>) 19886 0x69AD 榭 (<CJK Ideograph>) 19887 0x69D4 槔 (<CJK Ideograph>) 19888 0x69B1 榱 (<CJK Ideograph>) 19889 0x69C1 槁 (<CJK Ideograph>) 19890 0x69CA 槊 (<CJK Ideograph>) 19891 0x69DF 槟 (<CJK Ideograph>) 19892 0x6995 榕 (<CJK Ideograph>) 19893 0x69E0 槠 (<CJK Ideograph>) 19894 0x698D 榍 (<CJK Ideograph>) 19895 0x69FF 槿 (<CJK Ideograph>) 19896 0x6A2F 樯 (<CJK Ideograph>) 19897 0x69ED 槭 (<CJK Ideograph>) 19898 0x6A17 樗 (<CJK Ideograph>) 19899 0x6A18 樘 (<CJK Ideograph>) 19900 0x6A65 橥 (<CJK Ideograph>) 19901 0x69F2 槲 (<CJK Ideograph>) 19902 0x6A44 橄 (<CJK Ideograph>) 19903 0x6A3E 樾 (<CJK Ideograph>) 19904 0x6AA0 檠 (<CJK Ideograph>) 19905 0x6A50 橐 (<CJK Ideograph>) 19906 0x6A5B 橛 (<CJK Ideograph>) 19907 0x6A35 樵 (<CJK Ideograph>) 19908 0x6A8E 檎 (<CJK Ideograph>) 19909 0x6A79 橹 (<CJK Ideograph>) 19910 0x6A3D 樽 (<CJK Ideograph>) 19911 0x6A28 樨 (<CJK Ideograph>) 19912 0x6A58 橘 (<CJK Ideograph>) 19913 0x6A7C 橼 (<CJK Ideograph>) 19914 0x6A91 檑 (<CJK Ideograph>) 19915 0x6A90 檐 (<CJK Ideograph>) 19916 0x6AA9 檩 (<CJK Ideograph>) 19917 0x6A97 檗 (<CJK Ideograph>) 19918 0x6AAB 檫 (<CJK Ideograph>) 19919 0x7337 猷 (<CJK Ideograph>) 19920 0x7352 獒 (<CJK Ideograph>) 19921 0x6B81 殁 (<CJK Ideograph>) 19922 0x6B82 殂 (<CJK Ideograph>) 19923 0x6B87 殇 (<CJK Ideograph>) 19924 0x6B84 殄 (<CJK Ideograph>) 19925 0x6B92 殒 (<CJK Ideograph>) 19926 0x6B93 殓 (<CJK Ideograph>) 19927 0x6B8D 殍 (<CJK Ideograph>) 19928 0x6B9A 殚 (<CJK Ideograph>) 19929 0x6B9B 殛 (<CJK Ideograph>) 19930 0x6BA1 殡 (<CJK Ideograph>) 19931 0x6BAA 殪 (<CJK Ideograph>) 19932 0x8F6B 轫 (<CJK Ideograph>) 19933 0x8F6D 轭 (<CJK Ideograph>) 19934 0x8F71 轱 (<CJK Ideograph>) 19935 0x8F72 轲 (<CJK Ideograph>) 19936 0x8F73 轳 (<CJK Ideograph>) 19937 0x8F75 轵 (<CJK Ideograph>) 19938 0x8F76 轶 (<CJK Ideograph>) 19939 0x8F78 轸 (<CJK Ideograph>) 19940 0x8F77 轷 (<CJK Ideograph>) 19941 0x8F79 轹 (<CJK Ideograph>) 19942 0x8F7A 轺 (<CJK Ideograph>) 19943 0x8F7C 轼 (<CJK Ideograph>) 19944 0x8F7E 轾 (<CJK Ideograph>) 19945 0x8F81 辁 (<CJK Ideograph>) 19946 0x8F82 辂 (<CJK Ideograph>) 19947 0x8F84 辄 (<CJK Ideograph>) 19948 0x8F87 辇 (<CJK Ideograph>) 19949 0x8F8B 辋 (<CJK Ideograph>) 19950 0x95CC 闌 (<CJK Ideograph>) 19951 0x95CD 闍 (<CJK Ideograph>) 19952 0x95CE 闎 (<CJK Ideograph>) 19953 0x95CF 闏 (<CJK Ideograph>) 19954 0x95D0 闐 (<CJK Ideograph>) 19955 0x95D1 闑 (<CJK Ideograph>) 19956 0x95D2 闒 (<CJK Ideograph>) 19957 0x95D3 闓 (<CJK Ideograph>) 19958 0x95D4 闔 (<CJK Ideograph>) 19959 0x95D5 闕 (<CJK Ideograph>) 19960 0x95D6 闖 (<CJK Ideograph>) 19961 0x95D7 闗 (<CJK Ideograph>) 19962 0x95D8 闘 (<CJK Ideograph>) 19963 0x95D9 闙 (<CJK Ideograph>) 19964 0x95DA 闚 (<CJK Ideograph>) 19965 0x95DB 闛 (<CJK Ideograph>) 19966 0x95DC 關 (<CJK Ideograph>) 19967 0x95DD 闝 (<CJK Ideograph>) 19968 0x95DE 闞 (<CJK Ideograph>) 19969 0x95DF 闟 (<CJK Ideograph>) 19970 0x95E0 闠 (<CJK Ideograph>) 19971 0x95E1 闡 (<CJK Ideograph>) 19972 0x95E2 闢 (<CJK Ideograph>) 19973 0x95E3 闣 (<CJK Ideograph>) 19974 0x95E4 闤 (<CJK Ideograph>) 19975 0x95E5 闥 (<CJK Ideograph>) 19976 0x95E6 闦 (<CJK Ideograph>) 19977 0x95E7 闧 (<CJK Ideograph>) 19978 0x95EC 闬 (<CJK Ideograph>) 19979 0x95FF 闿 (<CJK Ideograph>) 19980 0x9607 阇 (<CJK Ideograph>) 19981 0x9613 阓 (<CJK Ideograph>) 19982 0x9618 阘 (<CJK Ideograph>) 19983 0x961B 阛 (<CJK Ideograph>) 19984 0x961E 阞 (<CJK Ideograph>) 19985 0x9620 阠 (<CJK Ideograph>) 19986 0x9623 阣 (<CJK Ideograph>) 19987 0x9624 阤 (<CJK Ideograph>) 19988 0x9625 阥 (<CJK Ideograph>) 19989 0x9626 阦 (<CJK Ideograph>) 19990 0x9627 阧 (<CJK Ideograph>) 19991 0x9628 阨 (<CJK Ideograph>) 19992 0x9629 阩 (<CJK Ideograph>) 19993 0x962B 阫 (<CJK Ideograph>) 19994 0x962C 阬 (<CJK Ideograph>) 19995 0x962D 阭 (<CJK Ideograph>) 19996 0x962F 阯 (<CJK Ideograph>) 19997 0x9630 阰 (<CJK Ideograph>) 19998 0x9637 阷 (<CJK Ideograph>) 19999 0x9638 阸 (<CJK Ideograph>) 20000 0x9639 阹 (<CJK Ideograph>) 20001 0x963A 阺 (<CJK Ideograph>) 20002 0x963E 阾 (<CJK Ideograph>) 20003 0x9641 陁 (<CJK Ideograph>) 20004 0x9643 陃 (<CJK Ideograph>) 20005 0x964A 陊 (<CJK Ideograph>) 20006 0x964E 陎 (<CJK Ideograph>) 20007 0x964F 陏 (<CJK Ideograph>) 20008 0x9651 陑 (<CJK Ideograph>) 20009 0x9652 陒 (<CJK Ideograph>) 20010 0x9653 陓 (<CJK Ideograph>) 20011 0x9656 陖 (<CJK Ideograph>) 20012 0x9657 陗 (<CJK Ideograph>) 20013 0x9658 陘 (<CJK Ideograph>) 20014 0x9659 陙 (<CJK Ideograph>) 20015 0x965A 陚 (<CJK Ideograph>) 20016 0x965C 陜 (<CJK Ideograph>) 20017 0x965D 陝 (<CJK Ideograph>) 20018 0x965E 陞 (<CJK Ideograph>) 20019 0x9660 陠 (<CJK Ideograph>) 20020 0x9663 陣 (<CJK Ideograph>) 20021 0x9665 陥 (<CJK Ideograph>) 20022 0x9666 陦 (<CJK Ideograph>) 20023 0x966B 陫 (<CJK Ideograph>) 20024 0x966D 陭 (<CJK Ideograph>) 20025 0x966E 陮 (<CJK Ideograph>) 20026 0x966F 陯 (<CJK Ideograph>) 20027 0x9670 陰 (<CJK Ideograph>) 20028 0x9671 陱 (<CJK Ideograph>) 20029 0x9673 陳 (<CJK Ideograph>) 20030 0x9678 陸 (<CJK Ideograph>) 20031 0x9679 陹 (<CJK Ideograph>) 20032 0x967A 険 (<CJK Ideograph>) 20033 0x967B 陻 (<CJK Ideograph>) 20034 0x967C 陼 (<CJK Ideograph>) 20035 0x967D 陽 (<CJK Ideograph>) 20036 0x967E 陾 (<CJK Ideograph>) 20037 0x967F 陿 (<CJK Ideograph>) 20038 0x9680 隀 (<CJK Ideograph>) 20039 0x9681 隁 (<CJK Ideograph>) 20040 0x9682 隂 (<CJK Ideograph>) 20041 0x9683 隃 (<CJK Ideograph>) 20042 0x9684 隄 (<CJK Ideograph>) 20043 0x9687 隇 (<CJK Ideograph>) 20044 0x9689 隉 (<CJK Ideograph>) 20045 0x968A 隊 (<CJK Ideograph>) 20046 0x8F8D 辍 (<CJK Ideograph>) 20047 0x8F8E 辎 (<CJK Ideograph>) 20048 0x8F8F 辏 (<CJK Ideograph>) 20049 0x8F98 辘 (<CJK Ideograph>) 20050 0x8F9A 辚 (<CJK Ideograph>) 20051 0x8ECE 軎 (<CJK Ideograph>) 20052 0x620B 戋 (<CJK Ideograph>) 20053 0x6217 戗 (<CJK Ideograph>) 20054 0x621B 戛 (<CJK Ideograph>) 20055 0x621F 戟 (<CJK Ideograph>) 20056 0x6222 戢 (<CJK Ideograph>) 20057 0x6221 戡 (<CJK Ideograph>) 20058 0x6225 戥 (<CJK Ideograph>) 20059 0x6224 戤 (<CJK Ideograph>) 20060 0x622C 戬 (<CJK Ideograph>) 20061 0x81E7 臧 (<CJK Ideograph>) 20062 0x74EF 瓯 (<CJK Ideograph>) 20063 0x74F4 瓴 (<CJK Ideograph>) 20064 0x74FF 瓿 (<CJK Ideograph>) 20065 0x750F 甏 (<CJK Ideograph>) 20066 0x7511 甑 (<CJK Ideograph>) 20067 0x7513 甓 (<CJK Ideograph>) 20068 0x6534 攴 (<CJK Ideograph>) 20069 0x65EE 旮 (<CJK Ideograph>) 20070 0x65EF 旯 (<CJK Ideograph>) 20071 0x65F0 旰 (<CJK Ideograph>) 20072 0x660A 昊 (<CJK Ideograph>) 20073 0x6619 昙 (<CJK Ideograph>) 20074 0x6772 杲 (<CJK Ideograph>) 20075 0x6603 昃 (<CJK Ideograph>) 20076 0x6615 昕 (<CJK Ideograph>) 20077 0x6600 昀 (<CJK Ideograph>) 20078 0x7085 炅 (<CJK Ideograph>) 20079 0x66F7 曷 (<CJK Ideograph>) 20080 0x661D 昝 (<CJK Ideograph>) 20081 0x6634 昴 (<CJK Ideograph>) 20082 0x6631 昱 (<CJK Ideograph>) 20083 0x6636 昶 (<CJK Ideograph>) 20084 0x6635 昵 (<CJK Ideograph>) 20085 0x8006 耆 (<CJK Ideograph>) 20086 0x665F 晟 (<CJK Ideograph>) 20087 0x6654 晔 (<CJK Ideograph>) 20088 0x6641 晁 (<CJK Ideograph>) 20089 0x664F 晏 (<CJK Ideograph>) 20090 0x6656 晖 (<CJK Ideograph>) 20091 0x6661 晡 (<CJK Ideograph>) 20092 0x6657 晗 (<CJK Ideograph>) 20093 0x6677 晷 (<CJK Ideograph>) 20094 0x6684 暄 (<CJK Ideograph>) 20095 0x668C 暌 (<CJK Ideograph>) 20096 0x66A7 暧 (<CJK Ideograph>) 20097 0x669D 暝 (<CJK Ideograph>) 20098 0x66BE 暾 (<CJK Ideograph>) 20099 0x66DB 曛 (<CJK Ideograph>) 20100 0x66DC 曜 (<CJK Ideograph>) 20101 0x66E6 曦 (<CJK Ideograph>) 20102 0x66E9 曩 (<CJK Ideograph>) 20103 0x8D32 贲 (<CJK Ideograph>) 20104 0x8D33 贳 (<CJK Ideograph>) 20105 0x8D36 贶 (<CJK Ideograph>) 20106 0x8D3B 贻 (<CJK Ideograph>) 20107 0x8D3D 贽 (<CJK Ideograph>) 20108 0x8D40 赀 (<CJK Ideograph>) 20109 0x8D45 赅 (<CJK Ideograph>) 20110 0x8D46 赆 (<CJK Ideograph>) 20111 0x8D48 赈 (<CJK Ideograph>) 20112 0x8D49 赉 (<CJK Ideograph>) 20113 0x8D47 赇 (<CJK Ideograph>) 20114 0x8D4D 赍 (<CJK Ideograph>) 20115 0x8D55 赕 (<CJK Ideograph>) 20116 0x8D59 赙 (<CJK Ideograph>) 20117 0x89C7 觇 (<CJK Ideograph>) 20118 0x89CA 觊 (<CJK Ideograph>) 20119 0x89CB 觋 (<CJK Ideograph>) 20120 0x89CC 觌 (<CJK Ideograph>) 20121 0x89CE 觎 (<CJK Ideograph>) 20122 0x89CF 觏 (<CJK Ideograph>) 20123 0x89D0 觐 (<CJK Ideograph>) 20124 0x89D1 觑 (<CJK Ideograph>) 20125 0x726E 牮 (<CJK Ideograph>) 20126 0x729F 犟 (<CJK Ideograph>) 20127 0x725D 牝 (<CJK Ideograph>) 20128 0x7266 牦 (<CJK Ideograph>) 20129 0x726F 牯 (<CJK Ideograph>) 20130 0x727E 牾 (<CJK Ideograph>) 20131 0x727F 牿 (<CJK Ideograph>) 20132 0x7284 犄 (<CJK Ideograph>) 20133 0x728B 犋 (<CJK Ideograph>) 20134 0x728D 犍 (<CJK Ideograph>) 20135 0x728F 犏 (<CJK Ideograph>) 20136 0x7292 犒 (<CJK Ideograph>) 20137 0x6308 挈 (<CJK Ideograph>) 20138 0x6332 挲 (<CJK Ideograph>) 20139 0x63B0 掰 (<CJK Ideograph>) 20140 0x968C 隌 (<CJK Ideograph>) 20141 0x968E 階 (<CJK Ideograph>) 20142 0x9691 隑 (<CJK Ideograph>) 20143 0x9692 隒 (<CJK Ideograph>) 20144 0x9693 隓 (<CJK Ideograph>) 20145 0x9695 隕 (<CJK Ideograph>) 20146 0x9696 隖 (<CJK Ideograph>) 20147 0x969A 隚 (<CJK Ideograph>) 20148 0x969B 際 (<CJK Ideograph>) 20149 0x969D 隝 (<CJK Ideograph>) 20150 0x969E 隞 (<CJK Ideograph>) 20151 0x969F 隟 (<CJK Ideograph>) 20152 0x96A0 隠 (<CJK Ideograph>) 20153 0x96A1 隡 (<CJK Ideograph>) 20154 0x96A2 隢 (<CJK Ideograph>) 20155 0x96A3 隣 (<CJK Ideograph>) 20156 0x96A4 隤 (<CJK Ideograph>) 20157 0x96A5 隥 (<CJK Ideograph>) 20158 0x96A6 隦 (<CJK Ideograph>) 20159 0x96A8 隨 (<CJK Ideograph>) 20160 0x96A9 隩 (<CJK Ideograph>) 20161 0x96AA 險 (<CJK Ideograph>) 20162 0x96AB 隫 (<CJK Ideograph>) 20163 0x96AC 隬 (<CJK Ideograph>) 20164 0x96AD 隭 (<CJK Ideograph>) 20165 0x96AE 隮 (<CJK Ideograph>) 20166 0x96AF 隯 (<CJK Ideograph>) 20167 0x96B1 隱 (<CJK Ideograph>) 20168 0x96B2 隲 (<CJK Ideograph>) 20169 0x96B4 隴 (<CJK Ideograph>) 20170 0x96B5 隵 (<CJK Ideograph>) 20171 0x96B7 隷 (<CJK Ideograph>) 20172 0x96B8 隸 (<CJK Ideograph>) 20173 0x96BA 隺 (<CJK Ideograph>) 20174 0x96BB 隻 (<CJK Ideograph>) 20175 0x96BF 隿 (<CJK Ideograph>) 20176 0x96C2 雂 (<CJK Ideograph>) 20177 0x96C3 雃 (<CJK Ideograph>) 20178 0x96C8 雈 (<CJK Ideograph>) 20179 0x96CA 雊 (<CJK Ideograph>) 20180 0x96CB 雋 (<CJK Ideograph>) 20181 0x96D0 雐 (<CJK Ideograph>) 20182 0x96D1 雑 (<CJK Ideograph>) 20183 0x96D3 雓 (<CJK Ideograph>) 20184 0x96D4 雔 (<CJK Ideograph>) 20185 0x96D6 雖 (<CJK Ideograph>) 20186 0x96D7 雗 (<CJK Ideograph>) 20187 0x96D8 雘 (<CJK Ideograph>) 20188 0x96D9 雙 (<CJK Ideograph>) 20189 0x96DA 雚 (<CJK Ideograph>) 20190 0x96DB 雛 (<CJK Ideograph>) 20191 0x96DC 雜 (<CJK Ideograph>) 20192 0x96DD 雝 (<CJK Ideograph>) 20193 0x96DE 雞 (<CJK Ideograph>) 20194 0x96DF 雟 (<CJK Ideograph>) 20195 0x96E1 雡 (<CJK Ideograph>) 20196 0x96E2 離 (<CJK Ideograph>) 20197 0x96E3 難 (<CJK Ideograph>) 20198 0x96E4 雤 (<CJK Ideograph>) 20199 0x96E5 雥 (<CJK Ideograph>) 20200 0x96E6 雦 (<CJK Ideograph>) 20201 0x96E7 雧 (<CJK Ideograph>) 20202 0x96EB 雫 (<CJK Ideograph>) 20203 0x96EC 雬 (<CJK Ideograph>) 20204 0x96ED 雭 (<CJK Ideograph>) 20205 0x96EE 雮 (<CJK Ideograph>) 20206 0x96F0 雰 (<CJK Ideograph>) 20207 0x96F1 雱 (<CJK Ideograph>) 20208 0x96F2 雲 (<CJK Ideograph>) 20209 0x96F4 雴 (<CJK Ideograph>) 20210 0x96F5 雵 (<CJK Ideograph>) 20211 0x96F8 雸 (<CJK Ideograph>) 20212 0x96FA 雺 (<CJK Ideograph>) 20213 0x96FB 電 (<CJK Ideograph>) 20214 0x96FC 雼 (<CJK Ideograph>) 20215 0x96FD 雽 (<CJK Ideograph>) 20216 0x96FF 雿 (<CJK Ideograph>) 20217 0x9702 霂 (<CJK Ideograph>) 20218 0x9703 霃 (<CJK Ideograph>) 20219 0x9705 霅 (<CJK Ideograph>) 20220 0x970A 霊 (<CJK Ideograph>) 20221 0x970B 霋 (<CJK Ideograph>) 20222 0x970C 霌 (<CJK Ideograph>) 20223 0x9710 霐 (<CJK Ideograph>) 20224 0x9711 霑 (<CJK Ideograph>) 20225 0x9712 霒 (<CJK Ideograph>) 20226 0x9714 霔 (<CJK Ideograph>) 20227 0x9715 霕 (<CJK Ideograph>) 20228 0x9717 霗 (<CJK Ideograph>) 20229 0x9718 霘 (<CJK Ideograph>) 20230 0x9719 霙 (<CJK Ideograph>) 20231 0x971A 霚 (<CJK Ideograph>) 20232 0x971B 霛 (<CJK Ideograph>) 20233 0x971D 霝 (<CJK Ideograph>) 20234 0x971F 霟 (<CJK Ideograph>) 20235 0x9720 霠 (<CJK Ideograph>) 20236 0x643F 搿 (<CJK Ideograph>) 20237 0x64D8 擘 (<CJK Ideograph>) 20238 0x8004 耄 (<CJK Ideograph>) 20239 0x6BEA 毪 (<CJK Ideograph>) 20240 0x6BF3 毳 (<CJK Ideograph>) 20241 0x6BFD 毽 (<CJK Ideograph>) 20242 0x6BF5 毵 (<CJK Ideograph>) 20243 0x6BF9 毹 (<CJK Ideograph>) 20244 0x6C05 氅 (<CJK Ideograph>) 20245 0x6C07 氇 (<CJK Ideograph>) 20246 0x6C06 氆 (<CJK Ideograph>) 20247 0x6C0D 氍 (<CJK Ideograph>) 20248 0x6C15 氕 (<CJK Ideograph>) 20249 0x6C18 氘 (<CJK Ideograph>) 20250 0x6C19 氙 (<CJK Ideograph>) 20251 0x6C1A 氚 (<CJK Ideograph>) 20252 0x6C21 氡 (<CJK Ideograph>) 20253 0x6C29 氩 (<CJK Ideograph>) 20254 0x6C24 氤 (<CJK Ideograph>) 20255 0x6C2A 氪 (<CJK Ideograph>) 20256 0x6C32 氲 (<CJK Ideograph>) 20257 0x6535 攵 (<CJK Ideograph>) 20258 0x6555 敕 (<CJK Ideograph>) 20259 0x656B 敫 (<CJK Ideograph>) 20260 0x724D 牍 (<CJK Ideograph>) 20261 0x7252 牒 (<CJK Ideograph>) 20262 0x7256 牖 (<CJK Ideograph>) 20263 0x7230 爰 (<CJK Ideograph>) 20264 0x8662 虢 (<CJK Ideograph>) 20265 0x5216 刖 (<CJK Ideograph>) 20266 0x809F 肟 (<CJK Ideograph>) 20267 0x809C 肜 (<CJK Ideograph>) 20268 0x8093 肓 (<CJK Ideograph>) 20269 0x80BC 肼 (<CJK Ideograph>) 20270 0x670A 朊 (<CJK Ideograph>) 20271 0x80BD 肽 (<CJK Ideograph>) 20272 0x80B1 肱 (<CJK Ideograph>) 20273 0x80AB 肫 (<CJK Ideograph>) 20274 0x80AD 肭 (<CJK Ideograph>) 20275 0x80B4 肴 (<CJK Ideograph>) 20276 0x80B7 肷 (<CJK Ideograph>) 20277 0x80E7 胧 (<CJK Ideograph>) 20278 0x80E8 胨 (<CJK Ideograph>) 20279 0x80E9 胩 (<CJK Ideograph>) 20280 0x80EA 胪 (<CJK Ideograph>) 20281 0x80DB 胛 (<CJK Ideograph>) 20282 0x80C2 胂 (<CJK Ideograph>) 20283 0x80C4 胄 (<CJK Ideograph>) 20284 0x80D9 胙 (<CJK Ideograph>) 20285 0x80CD 胍 (<CJK Ideograph>) 20286 0x80D7 胗 (<CJK Ideograph>) 20287 0x6710 朐 (<CJK Ideograph>) 20288 0x80DD 胝 (<CJK Ideograph>) 20289 0x80EB 胫 (<CJK Ideograph>) 20290 0x80F1 胱 (<CJK Ideograph>) 20291 0x80F4 胴 (<CJK Ideograph>) 20292 0x80ED 胭 (<CJK Ideograph>) 20293 0x810D 脍 (<CJK Ideograph>) 20294 0x810E 脎 (<CJK Ideograph>) 20295 0x80F2 胲 (<CJK Ideograph>) 20296 0x80FC 胼 (<CJK Ideograph>) 20297 0x6715 朕 (<CJK Ideograph>) 20298 0x8112 脒 (<CJK Ideograph>) 20299 0x8C5A 豚 (<CJK Ideograph>) 20300 0x8136 脶 (<CJK Ideograph>) 20301 0x811E 脞 (<CJK Ideograph>) 20302 0x812C 脬 (<CJK Ideograph>) 20303 0x8118 脘 (<CJK Ideograph>) 20304 0x8132 脲 (<CJK Ideograph>) 20305 0x8148 腈 (<CJK Ideograph>) 20306 0x814C 腌 (<CJK Ideograph>) 20307 0x8153 腓 (<CJK Ideograph>) 20308 0x8174 腴 (<CJK Ideograph>) 20309 0x8159 腙 (<CJK Ideograph>) 20310 0x815A 腚 (<CJK Ideograph>) 20311 0x8171 腱 (<CJK Ideograph>) 20312 0x8160 腠 (<CJK Ideograph>) 20313 0x8169 腩 (<CJK Ideograph>) 20314 0x817C 腼 (<CJK Ideograph>) 20315 0x817D 腽 (<CJK Ideograph>) 20316 0x816D 腭 (<CJK Ideograph>) 20317 0x8167 腧 (<CJK Ideograph>) 20318 0x584D 塍 (<CJK Ideograph>) 20319 0x5AB5 媵 (<CJK Ideograph>) 20320 0x8188 膈 (<CJK Ideograph>) 20321 0x8182 膂 (<CJK Ideograph>) 20322 0x8191 膑 (<CJK Ideograph>) 20323 0x6ED5 滕 (<CJK Ideograph>) 20324 0x81A3 膣 (<CJK Ideograph>) 20325 0x81AA 膪 (<CJK Ideograph>) 20326 0x81CC 臌 (<CJK Ideograph>) 20327 0x6726 朦 (<CJK Ideograph>) 20328 0x81CA 臊 (<CJK Ideograph>) 20329 0x81BB 膻 (<CJK Ideograph>) 20330 0x9721 霡 (<CJK Ideograph>) 20331 0x9722 霢 (<CJK Ideograph>) 20332 0x9723 霣 (<CJK Ideograph>) 20333 0x9724 霤 (<CJK Ideograph>) 20334 0x9725 霥 (<CJK Ideograph>) 20335 0x9726 霦 (<CJK Ideograph>) 20336 0x9727 霧 (<CJK Ideograph>) 20337 0x9728 霨 (<CJK Ideograph>) 20338 0x9729 霩 (<CJK Ideograph>) 20339 0x972B 霫 (<CJK Ideograph>) 20340 0x972C 霬 (<CJK Ideograph>) 20341 0x972E 霮 (<CJK Ideograph>) 20342 0x972F 霯 (<CJK Ideograph>) 20343 0x9731 霱 (<CJK Ideograph>) 20344 0x9733 霳 (<CJK Ideograph>) 20345 0x9734 霴 (<CJK Ideograph>) 20346 0x9735 霵 (<CJK Ideograph>) 20347 0x9736 霶 (<CJK Ideograph>) 20348 0x9737 霷 (<CJK Ideograph>) 20349 0x973A 霺 (<CJK Ideograph>) 20350 0x973B 霻 (<CJK Ideograph>) 20351 0x973C 霼 (<CJK Ideograph>) 20352 0x973D 霽 (<CJK Ideograph>) 20353 0x973F 霿 (<CJK Ideograph>) 20354 0x9740 靀 (<CJK Ideograph>) 20355 0x9741 靁 (<CJK Ideograph>) 20356 0x9742 靂 (<CJK Ideograph>) 20357 0x9743 靃 (<CJK Ideograph>) 20358 0x9744 靄 (<CJK Ideograph>) 20359 0x9745 靅 (<CJK Ideograph>) 20360 0x9746 靆 (<CJK Ideograph>) 20361 0x9747 靇 (<CJK Ideograph>) 20362 0x9748 靈 (<CJK Ideograph>) 20363 0x9749 靉 (<CJK Ideograph>) 20364 0x974A 靊 (<CJK Ideograph>) 20365 0x974B 靋 (<CJK Ideograph>) 20366 0x974C 靌 (<CJK Ideograph>) 20367 0x974D 靍 (<CJK Ideograph>) 20368 0x974E 靎 (<CJK Ideograph>) 20369 0x974F 靏 (<CJK Ideograph>) 20370 0x9750 靐 (<CJK Ideograph>) 20371 0x9751 靑 (<CJK Ideograph>) 20372 0x9754 靔 (<CJK Ideograph>) 20373 0x9755 靕 (<CJK Ideograph>) 20374 0x9757 靗 (<CJK Ideograph>) 20375 0x9758 靘 (<CJK Ideograph>) 20376 0x975A 靚 (<CJK Ideograph>) 20377 0x975C 靜 (<CJK Ideograph>) 20378 0x975D 靝 (<CJK Ideograph>) 20379 0x975F 靟 (<CJK Ideograph>) 20380 0x9763 靣 (<CJK Ideograph>) 20381 0x9764 靤 (<CJK Ideograph>) 20382 0x9766 靦 (<CJK Ideograph>) 20383 0x9767 靧 (<CJK Ideograph>) 20384 0x9768 靨 (<CJK Ideograph>) 20385 0x976A 靪 (<CJK Ideograph>) 20386 0x976B 靫 (<CJK Ideograph>) 20387 0x976C 靬 (<CJK Ideograph>) 20388 0x976D 靭 (<CJK Ideograph>) 20389 0x976E 靮 (<CJK Ideograph>) 20390 0x976F 靯 (<CJK Ideograph>) 20391 0x9770 靰 (<CJK Ideograph>) 20392 0x9771 靱 (<CJK Ideograph>) 20393 0x9772 靲 (<CJK Ideograph>) 20394 0x9775 靵 (<CJK Ideograph>) 20395 0x9777 靷 (<CJK Ideograph>) 20396 0x9778 靸 (<CJK Ideograph>) 20397 0x9779 靹 (<CJK Ideograph>) 20398 0x977A 靺 (<CJK Ideograph>) 20399 0x977B 靻 (<CJK Ideograph>) 20400 0x977D 靽 (<CJK Ideograph>) 20401 0x977E 靾 (<CJK Ideograph>) 20402 0x977F 靿 (<CJK Ideograph>) 20403 0x9780 鞀 (<CJK Ideograph>) 20404 0x9781 鞁 (<CJK Ideograph>) 20405 0x9782 鞂 (<CJK Ideograph>) 20406 0x9783 鞃 (<CJK Ideograph>) 20407 0x9784 鞄 (<CJK Ideograph>) 20408 0x9786 鞆 (<CJK Ideograph>) 20409 0x9787 鞇 (<CJK Ideograph>) 20410 0x9788 鞈 (<CJK Ideograph>) 20411 0x9789 鞉 (<CJK Ideograph>) 20412 0x978A 鞊 (<CJK Ideograph>) 20413 0x978C 鞌 (<CJK Ideograph>) 20414 0x978E 鞎 (<CJK Ideograph>) 20415 0x978F 鞏 (<CJK Ideograph>) 20416 0x9790 鞐 (<CJK Ideograph>) 20417 0x9793 鞓 (<CJK Ideograph>) 20418 0x9795 鞕 (<CJK Ideograph>) 20419 0x9796 鞖 (<CJK Ideograph>) 20420 0x9797 鞗 (<CJK Ideograph>) 20421 0x9799 鞙 (<CJK Ideograph>) 20422 0x979A 鞚 (<CJK Ideograph>) 20423 0x979B 鞛 (<CJK Ideograph>) 20424 0x979C 鞜 (<CJK Ideograph>) 20425 0x979D 鞝 (<CJK Ideograph>) 20426 0x81C1 臁 (<CJK Ideograph>) 20427 0x81A6 膦 (<CJK Ideograph>) 20428 0x6B24 欤 (<CJK Ideograph>) 20429 0x6B37 欷 (<CJK Ideograph>) 20430 0x6B39 欹 (<CJK Ideograph>) 20431 0x6B43 歃 (<CJK Ideograph>) 20432 0x6B46 歆 (<CJK Ideograph>) 20433 0x6B59 歙 (<CJK Ideograph>) 20434 0x98D1 飑 (<CJK Ideograph>) 20435 0x98D2 飒 (<CJK Ideograph>) 20436 0x98D3 飓 (<CJK Ideograph>) 20437 0x98D5 飕 (<CJK Ideograph>) 20438 0x98D9 飙 (<CJK Ideograph>) 20439 0x98DA 飚 (<CJK Ideograph>) 20440 0x6BB3 殳 (<CJK Ideograph>) 20441 0x5F40 彀 (<CJK Ideograph>) 20442 0x6BC2 毂 (<CJK Ideograph>) 20443 0x89F3 觳 (<CJK Ideograph>) 20444 0x6590 斐 (<CJK Ideograph>) 20445 0x9F51 齑 (<CJK Ideograph>) 20446 0x6593 斓 (<CJK Ideograph>) 20447 0x65BC 於 (<CJK Ideograph>) 20448 0x65C6 旆 (<CJK Ideograph>) 20449 0x65C4 旄 (<CJK Ideograph>) 20450 0x65C3 旃 (<CJK Ideograph>) 20451 0x65CC 旌 (<CJK Ideograph>) 20452 0x65CE 旎 (<CJK Ideograph>) 20453 0x65D2 旒 (<CJK Ideograph>) 20454 0x65D6 旖 (<CJK Ideograph>) 20455 0x7080 炀 (<CJK Ideograph>) 20456 0x709C 炜 (<CJK Ideograph>) 20457 0x7096 炖 (<CJK Ideograph>) 20458 0x709D 炝 (<CJK Ideograph>) 20459 0x70BB 炻 (<CJK Ideograph>) 20460 0x70C0 烀 (<CJK Ideograph>) 20461 0x70B7 炷 (<CJK Ideograph>) 20462 0x70AB 炫 (<CJK Ideograph>) 20463 0x70B1 炱 (<CJK Ideograph>) 20464 0x70E8 烨 (<CJK Ideograph>) 20465 0x70CA 烊 (<CJK Ideograph>) 20466 0x7110 焐 (<CJK Ideograph>) 20467 0x7113 焓 (<CJK Ideograph>) 20468 0x7116 焖 (<CJK Ideograph>) 20469 0x712F 焯 (<CJK Ideograph>) 20470 0x7131 焱 (<CJK Ideograph>) 20471 0x7173 煳 (<CJK Ideograph>) 20472 0x715C 煜 (<CJK Ideograph>) 20473 0x7168 煨 (<CJK Ideograph>) 20474 0x7145 煅 (<CJK Ideograph>) 20475 0x7172 煲 (<CJK Ideograph>) 20476 0x714A 煊 (<CJK Ideograph>) 20477 0x7178 煸 (<CJK Ideograph>) 20478 0x717A 煺 (<CJK Ideograph>) 20479 0x7198 熘 (<CJK Ideograph>) 20480 0x71B3 熳 (<CJK Ideograph>) 20481 0x71B5 熵 (<CJK Ideograph>) 20482 0x71A8 熨 (<CJK Ideograph>) 20483 0x71A0 熠 (<CJK Ideograph>) 20484 0x71E0 燠 (<CJK Ideograph>) 20485 0x71D4 燔 (<CJK Ideograph>) 20486 0x71E7 燧 (<CJK Ideograph>) 20487 0x71F9 燹 (<CJK Ideograph>) 20488 0x721D 爝 (<CJK Ideograph>) 20489 0x7228 爨 (<CJK Ideograph>) 20490 0x706C 灬 (<CJK Ideograph>) 20491 0x7118 焘 (<CJK Ideograph>) 20492 0x7166 煦 (<CJK Ideograph>) 20493 0x71B9 熹 (<CJK Ideograph>) 20494 0x623E 戾 (<CJK Ideograph>) 20495 0x623D 戽 (<CJK Ideograph>) 20496 0x6243 扃 (<CJK Ideograph>) 20497 0x6248 扈 (<CJK Ideograph>) 20498 0x6249 扉 (<CJK Ideograph>) 20499 0x793B 礻 (<CJK Ideograph>) 20500 0x7940 祀 (<CJK Ideograph>) 20501 0x7946 祆 (<CJK Ideograph>) 20502 0x7949 祉 (<CJK Ideograph>) 20503 0x795B 祛 (<CJK Ideograph>) 20504 0x795C 祜 (<CJK Ideograph>) 20505 0x7953 祓 (<CJK Ideograph>) 20506 0x795A 祚 (<CJK Ideograph>) 20507 0x7962 祢 (<CJK Ideograph>) 20508 0x7957 祗 (<CJK Ideograph>) 20509 0x7960 祠 (<CJK Ideograph>) 20510 0x796F 祯 (<CJK Ideograph>) 20511 0x7967 祧 (<CJK Ideograph>) 20512 0x797A 祺 (<CJK Ideograph>) 20513 0x7985 禅 (<CJK Ideograph>) 20514 0x798A 禊 (<CJK Ideograph>) 20515 0x799A 禚 (<CJK Ideograph>) 20516 0x79A7 禧 (<CJK Ideograph>) 20517 0x79B3 禳 (<CJK Ideograph>) 20518 0x5FD1 忑 (<CJK Ideograph>) 20519 0x5FD0 忐 (<CJK Ideograph>) 20520 0x979E 鞞 (<CJK Ideograph>) 20521 0x979F 鞟 (<CJK Ideograph>) 20522 0x97A1 鞡 (<CJK Ideograph>) 20523 0x97A2 鞢 (<CJK Ideograph>) 20524 0x97A4 鞤 (<CJK Ideograph>) 20525 0x97A5 鞥 (<CJK Ideograph>) 20526 0x97A6 鞦 (<CJK Ideograph>) 20527 0x97A7 鞧 (<CJK Ideograph>) 20528 0x97A8 鞨 (<CJK Ideograph>) 20529 0x97A9 鞩 (<CJK Ideograph>) 20530 0x97AA 鞪 (<CJK Ideograph>) 20531 0x97AC 鞬 (<CJK Ideograph>) 20532 0x97AE 鞮 (<CJK Ideograph>) 20533 0x97B0 鞰 (<CJK Ideograph>) 20534 0x97B1 鞱 (<CJK Ideograph>) 20535 0x97B3 鞳 (<CJK Ideograph>) 20536 0x97B5 鞵 (<CJK Ideograph>) 20537 0x97B6 鞶 (<CJK Ideograph>) 20538 0x97B7 鞷 (<CJK Ideograph>) 20539 0x97B8 鞸 (<CJK Ideograph>) 20540 0x97B9 鞹 (<CJK Ideograph>) 20541 0x97BA 鞺 (<CJK Ideograph>) 20542 0x97BB 鞻 (<CJK Ideograph>) 20543 0x97BC 鞼 (<CJK Ideograph>) 20544 0x97BD 鞽 (<CJK Ideograph>) 20545 0x97BE 鞾 (<CJK Ideograph>) 20546 0x97BF 鞿 (<CJK Ideograph>) 20547 0x97C0 韀 (<CJK Ideograph>) 20548 0x97C1 韁 (<CJK Ideograph>) 20549 0x97C2 韂 (<CJK Ideograph>) 20550 0x97C3 韃 (<CJK Ideograph>) 20551 0x97C4 韄 (<CJK Ideograph>) 20552 0x97C5 韅 (<CJK Ideograph>) 20553 0x97C6 韆 (<CJK Ideograph>) 20554 0x97C7 韇 (<CJK Ideograph>) 20555 0x97C8 韈 (<CJK Ideograph>) 20556 0x97C9 韉 (<CJK Ideograph>) 20557 0x97CA 韊 (<CJK Ideograph>) 20558 0x97CB 韋 (<CJK Ideograph>) 20559 0x97CC 韌 (<CJK Ideograph>) 20560 0x97CD 韍 (<CJK Ideograph>) 20561 0x97CE 韎 (<CJK Ideograph>) 20562 0x97CF 韏 (<CJK Ideograph>) 20563 0x97D0 韐 (<CJK Ideograph>) 20564 0x97D1 韑 (<CJK Ideograph>) 20565 0x97D2 韒 (<CJK Ideograph>) 20566 0x97D3 韓 (<CJK Ideograph>) 20567 0x97D4 韔 (<CJK Ideograph>) 20568 0x97D5 韕 (<CJK Ideograph>) 20569 0x97D6 韖 (<CJK Ideograph>) 20570 0x97D7 韗 (<CJK Ideograph>) 20571 0x97D8 韘 (<CJK Ideograph>) 20572 0x97D9 韙 (<CJK Ideograph>) 20573 0x97DA 韚 (<CJK Ideograph>) 20574 0x97DB 韛 (<CJK Ideograph>) 20575 0x97DC 韜 (<CJK Ideograph>) 20576 0x97DD 韝 (<CJK Ideograph>) 20577 0x97DE 韞 (<CJK Ideograph>) 20578 0x97DF 韟 (<CJK Ideograph>) 20579 0x97E0 韠 (<CJK Ideograph>) 20580 0x97E1 韡 (<CJK Ideograph>) 20581 0x97E2 韢 (<CJK Ideograph>) 20582 0x97E3 韣 (<CJK Ideograph>) 20583 0x97E4 韤 (<CJK Ideograph>) 20584 0x97E5 韥 (<CJK Ideograph>) 20585 0x97E8 韨 (<CJK Ideograph>) 20586 0x97EE 韮 (<CJK Ideograph>) 20587 0x97EF 韯 (<CJK Ideograph>) 20588 0x97F0 韰 (<CJK Ideograph>) 20589 0x97F1 韱 (<CJK Ideograph>) 20590 0x97F2 韲 (<CJK Ideograph>) 20591 0x97F4 韴 (<CJK Ideograph>) 20592 0x97F7 韷 (<CJK Ideograph>) 20593 0x97F8 韸 (<CJK Ideograph>) 20594 0x97F9 韹 (<CJK Ideograph>) 20595 0x97FA 韺 (<CJK Ideograph>) 20596 0x97FB 韻 (<CJK Ideograph>) 20597 0x97FC 韼 (<CJK Ideograph>) 20598 0x97FD 韽 (<CJK Ideograph>) 20599 0x97FE 韾 (<CJK Ideograph>) 20600 0x97FF 響 (<CJK Ideograph>) 20601 0x9800 頀 (<CJK Ideograph>) 20602 0x9801 頁 (<CJK Ideograph>) 20603 0x9802 頂 (<CJK Ideograph>) 20604 0x9803 頃 (<CJK Ideograph>) 20605 0x9804 頄 (<CJK Ideograph>) 20606 0x9805 項 (<CJK Ideograph>) 20607 0x9806 順 (<CJK Ideograph>) 20608 0x9807 頇 (<CJK Ideograph>) 20609 0x9808 須 (<CJK Ideograph>) 20610 0x9809 頉 (<CJK Ideograph>) 20611 0x980A 頊 (<CJK Ideograph>) 20612 0x980B 頋 (<CJK Ideograph>) 20613 0x980C 頌 (<CJK Ideograph>) 20614 0x980D 頍 (<CJK Ideograph>) 20615 0x980E 頎 (<CJK Ideograph>) 20616 0x603C 怼 (<CJK Ideograph>) 20617 0x605D 恝 (<CJK Ideograph>) 20618 0x605A 恚 (<CJK Ideograph>) 20619 0x6067 恧 (<CJK Ideograph>) 20620 0x6041 恁 (<CJK Ideograph>) 20621 0x6059 恙 (<CJK Ideograph>) 20622 0x6063 恣 (<CJK Ideograph>) 20623 0x60AB 悫 (<CJK Ideograph>) 20624 0x6106 愆 (<CJK Ideograph>) 20625 0x610D 愍 (<CJK Ideograph>) 20626 0x615D 慝 (<CJK Ideograph>) 20627 0x61A9 憩 (<CJK Ideograph>) 20628 0x619D 憝 (<CJK Ideograph>) 20629 0x61CB 懋 (<CJK Ideograph>) 20630 0x61D1 懑 (<CJK Ideograph>) 20631 0x6206 戆 (<CJK Ideograph>) 20632 0x8080 肀 (<CJK Ideograph>) 20633 0x807F 聿 (<CJK Ideograph>) 20634 0x6C93 沓 (<CJK Ideograph>) 20635 0x6CF6 泶 (<CJK Ideograph>) 20636 0x6DFC 淼 (<CJK Ideograph>) 20637 0x77F6 矶 (<CJK Ideograph>) 20638 0x77F8 矸 (<CJK Ideograph>) 20639 0x7800 砀 (<CJK Ideograph>) 20640 0x7809 砉 (<CJK Ideograph>) 20641 0x7817 砗 (<CJK Ideograph>) 20642 0x7818 砘 (<CJK Ideograph>) 20643 0x7811 砑 (<CJK Ideograph>) 20644 0x65AB 斫 (<CJK Ideograph>) 20645 0x782D 砭 (<CJK Ideograph>) 20646 0x781C 砜 (<CJK Ideograph>) 20647 0x781D 砝 (<CJK Ideograph>) 20648 0x7839 砹 (<CJK Ideograph>) 20649 0x783A 砺 (<CJK Ideograph>) 20650 0x783B 砻 (<CJK Ideograph>) 20651 0x781F 砟 (<CJK Ideograph>) 20652 0x783C 砼 (<CJK Ideograph>) 20653 0x7825 砥 (<CJK Ideograph>) 20654 0x782C 砬 (<CJK Ideograph>) 20655 0x7823 砣 (<CJK Ideograph>) 20656 0x7829 砩 (<CJK Ideograph>) 20657 0x784E 硎 (<CJK Ideograph>) 20658 0x786D 硭 (<CJK Ideograph>) 20659 0x7856 硖 (<CJK Ideograph>) 20660 0x7857 硗 (<CJK Ideograph>) 20661 0x7826 砦 (<CJK Ideograph>) 20662 0x7850 硐 (<CJK Ideograph>) 20663 0x7847 硇 (<CJK Ideograph>) 20664 0x784C 硌 (<CJK Ideograph>) 20665 0x786A 硪 (<CJK Ideograph>) 20666 0x789B 碛 (<CJK Ideograph>) 20667 0x7893 碓 (<CJK Ideograph>) 20668 0x789A 碚 (<CJK Ideograph>) 20669 0x7887 碇 (<CJK Ideograph>) 20670 0x789C 碜 (<CJK Ideograph>) 20671 0x78A1 碡 (<CJK Ideograph>) 20672 0x78A3 碣 (<CJK Ideograph>) 20673 0x78B2 碲 (<CJK Ideograph>) 20674 0x78B9 碹 (<CJK Ideograph>) 20675 0x78A5 碥 (<CJK Ideograph>) 20676 0x78D4 磔 (<CJK Ideograph>) 20677 0x78D9 磙 (<CJK Ideograph>) 20678 0x78C9 磉 (<CJK Ideograph>) 20679 0x78EC 磬 (<CJK Ideograph>) 20680 0x78F2 磲 (<CJK Ideograph>) 20681 0x7905 礅 (<CJK Ideograph>) 20682 0x78F4 磴 (<CJK Ideograph>) 20683 0x7913 礓 (<CJK Ideograph>) 20684 0x7924 礤 (<CJK Ideograph>) 20685 0x791E 礞 (<CJK Ideograph>) 20686 0x7934 礴 (<CJK Ideograph>) 20687 0x9F9B 龛 (<CJK Ideograph>) 20688 0x9EF9 黹 (<CJK Ideograph>) 20689 0x9EFB 黻 (<CJK Ideograph>) 20690 0x9EFC 黼 (<CJK Ideograph>) 20691 0x76F1 盱 (<CJK Ideograph>) 20692 0x7704 眄 (<CJK Ideograph>) 20693 0x770D 眍 (<CJK Ideograph>) 20694 0x76F9 盹 (<CJK Ideograph>) 20695 0x7707 眇 (<CJK Ideograph>) 20696 0x7708 眈 (<CJK Ideograph>) 20697 0x771A 眚 (<CJK Ideograph>) 20698 0x7722 眢 (<CJK Ideograph>) 20699 0x7719 眙 (<CJK Ideograph>) 20700 0x772D 眭 (<CJK Ideograph>) 20701 0x7726 眦 (<CJK Ideograph>) 20702 0x7735 眵 (<CJK Ideograph>) 20703 0x7738 眸 (<CJK Ideograph>) 20704 0x7750 睐 (<CJK Ideograph>) 20705 0x7751 睑 (<CJK Ideograph>) 20706 0x7747 睇 (<CJK Ideograph>) 20707 0x7743 睃 (<CJK Ideograph>) 20708 0x775A 睚 (<CJK Ideograph>) 20709 0x7768 睨 (<CJK Ideograph>) 20710 0x980F 頏 (<CJK Ideograph>) 20711 0x9810 預 (<CJK Ideograph>) 20712 0x9811 頑 (<CJK Ideograph>) 20713 0x9812 頒 (<CJK Ideograph>) 20714 0x9813 頓 (<CJK Ideograph>) 20715 0x9814 頔 (<CJK Ideograph>) 20716 0x9815 頕 (<CJK Ideograph>) 20717 0x9816 頖 (<CJK Ideograph>) 20718 0x9817 頗 (<CJK Ideograph>) 20719 0x9818 領 (<CJK Ideograph>) 20720 0x9819 頙 (<CJK Ideograph>) 20721 0x981A 頚 (<CJK Ideograph>) 20722 0x981B 頛 (<CJK Ideograph>) 20723 0x981C 頜 (<CJK Ideograph>) 20724 0x981D 頝 (<CJK Ideograph>) 20725 0x981E 頞 (<CJK Ideograph>) 20726 0x981F 頟 (<CJK Ideograph>) 20727 0x9820 頠 (<CJK Ideograph>) 20728 0x9821 頡 (<CJK Ideograph>) 20729 0x9822 頢 (<CJK Ideograph>) 20730 0x9823 頣 (<CJK Ideograph>) 20731 0x9824 頤 (<CJK Ideograph>) 20732 0x9825 頥 (<CJK Ideograph>) 20733 0x9826 頦 (<CJK Ideograph>) 20734 0x9827 頧 (<CJK Ideograph>) 20735 0x9828 頨 (<CJK Ideograph>) 20736 0x9829 頩 (<CJK Ideograph>) 20737 0x982A 頪 (<CJK Ideograph>) 20738 0x982B 頫 (<CJK Ideograph>) 20739 0x982C 頬 (<CJK Ideograph>) 20740 0x982D 頭 (<CJK Ideograph>) 20741 0x982E 頮 (<CJK Ideograph>) 20742 0x982F 頯 (<CJK Ideograph>) 20743 0x9830 頰 (<CJK Ideograph>) 20744 0x9831 頱 (<CJK Ideograph>) 20745 0x9832 頲 (<CJK Ideograph>) 20746 0x9833 頳 (<CJK Ideograph>) 20747 0x9834 頴 (<CJK Ideograph>) 20748 0x9835 頵 (<CJK Ideograph>) 20749 0x9836 頶 (<CJK Ideograph>) 20750 0x9837 頷 (<CJK Ideograph>) 20751 0x9838 頸 (<CJK Ideograph>) 20752 0x9839 頹 (<CJK Ideograph>) 20753 0x983A 頺 (<CJK Ideograph>) 20754 0x983B 頻 (<CJK Ideograph>) 20755 0x983C 頼 (<CJK Ideograph>) 20756 0x983D 頽 (<CJK Ideograph>) 20757 0x983E 頾 (<CJK Ideograph>) 20758 0x983F 頿 (<CJK Ideograph>) 20759 0x9840 顀 (<CJK Ideograph>) 20760 0x9841 顁 (<CJK Ideograph>) 20761 0x9842 顂 (<CJK Ideograph>) 20762 0x9843 顃 (<CJK Ideograph>) 20763 0x9844 顄 (<CJK Ideograph>) 20764 0x9845 顅 (<CJK Ideograph>) 20765 0x9846 顆 (<CJK Ideograph>) 20766 0x9847 顇 (<CJK Ideograph>) 20767 0x9848 顈 (<CJK Ideograph>) 20768 0x9849 顉 (<CJK Ideograph>) 20769 0x984A 顊 (<CJK Ideograph>) 20770 0x984B 顋 (<CJK Ideograph>) 20771 0x984C 題 (<CJK Ideograph>) 20772 0x984D 額 (<CJK Ideograph>) 20773 0x984E 顎 (<CJK Ideograph>) 20774 0x984F 顏 (<CJK Ideograph>) 20775 0x9850 顐 (<CJK Ideograph>) 20776 0x9851 顑 (<CJK Ideograph>) 20777 0x9852 顒 (<CJK Ideograph>) 20778 0x9853 顓 (<CJK Ideograph>) 20779 0x9854 顔 (<CJK Ideograph>) 20780 0x9855 顕 (<CJK Ideograph>) 20781 0x9856 顖 (<CJK Ideograph>) 20782 0x9857 顗 (<CJK Ideograph>) 20783 0x9858 願 (<CJK Ideograph>) 20784 0x9859 顙 (<CJK Ideograph>) 20785 0x985A 顚 (<CJK Ideograph>) 20786 0x985B 顛 (<CJK Ideograph>) 20787 0x985C 顜 (<CJK Ideograph>) 20788 0x985D 顝 (<CJK Ideograph>) 20789 0x985E 類 (<CJK Ideograph>) 20790 0x985F 顟 (<CJK Ideograph>) 20791 0x9860 顠 (<CJK Ideograph>) 20792 0x9861 顡 (<CJK Ideograph>) 20793 0x9862 顢 (<CJK Ideograph>) 20794 0x9863 顣 (<CJK Ideograph>) 20795 0x9864 顤 (<CJK Ideograph>) 20796 0x9865 顥 (<CJK Ideograph>) 20797 0x9866 顦 (<CJK Ideograph>) 20798 0x9867 顧 (<CJK Ideograph>) 20799 0x9868 顨 (<CJK Ideograph>) 20800 0x9869 顩 (<CJK Ideograph>) 20801 0x986A 顪 (<CJK Ideograph>) 20802 0x986B 顫 (<CJK Ideograph>) 20803 0x986C 顬 (<CJK Ideograph>) 20804 0x986D 顭 (<CJK Ideograph>) 20805 0x986E 顮 (<CJK Ideograph>) 20806 0x7762 睢 (<CJK Ideograph>) 20807 0x7765 睥 (<CJK Ideograph>) 20808 0x777F 睿 (<CJK Ideograph>) 20809 0x778D 瞍 (<CJK Ideograph>) 20810 0x777D 睽 (<CJK Ideograph>) 20811 0x7780 瞀 (<CJK Ideograph>) 20812 0x778C 瞌 (<CJK Ideograph>) 20813 0x7791 瞑 (<CJK Ideograph>) 20814 0x779F 瞟 (<CJK Ideograph>) 20815 0x77A0 瞠 (<CJK Ideograph>) 20816 0x77B0 瞰 (<CJK Ideograph>) 20817 0x77B5 瞵 (<CJK Ideograph>) 20818 0x77BD 瞽 (<CJK Ideograph>) 20819 0x753A 町 (<CJK Ideograph>) 20820 0x7540 畀 (<CJK Ideograph>) 20821 0x754E 畎 (<CJK Ideograph>) 20822 0x754B 畋 (<CJK Ideograph>) 20823 0x7548 畈 (<CJK Ideograph>) 20824 0x755B 畛 (<CJK Ideograph>) 20825 0x7572 畲 (<CJK Ideograph>) 20826 0x7579 畹 (<CJK Ideograph>) 20827 0x7583 疃 (<CJK Ideograph>) 20828 0x7F58 罘 (<CJK Ideograph>) 20829 0x7F61 罡 (<CJK Ideograph>) 20830 0x7F5F 罟 (<CJK Ideograph>) 20831 0x8A48 詈 (<CJK Ideograph>) 20832 0x7F68 罨 (<CJK Ideograph>) 20833 0x7F74 罴 (<CJK Ideograph>) 20834 0x7F71 罱 (<CJK Ideograph>) 20835 0x7F79 罹 (<CJK Ideograph>) 20836 0x7F81 羁 (<CJK Ideograph>) 20837 0x7F7E 罾 (<CJK Ideograph>) 20838 0x76CD 盍 (<CJK Ideograph>) 20839 0x76E5 盥 (<CJK Ideograph>) 20840 0x8832 蠲 (<CJK Ideograph>) 20841 0x9485 钅 (<CJK Ideograph>) 20842 0x9486 钆 (<CJK Ideograph>) 20843 0x9487 钇 (<CJK Ideograph>) 20844 0x948B 钋 (<CJK Ideograph>) 20845 0x948A 钊 (<CJK Ideograph>) 20846 0x948C 钌 (<CJK Ideograph>) 20847 0x948D 钍 (<CJK Ideograph>) 20848 0x948F 钏 (<CJK Ideograph>) 20849 0x9490 钐 (<CJK Ideograph>) 20850 0x9494 钔 (<CJK Ideograph>) 20851 0x9497 钗 (<CJK Ideograph>) 20852 0x9495 钕 (<CJK Ideograph>) 20853 0x949A 钚 (<CJK Ideograph>) 20854 0x949B 钛 (<CJK Ideograph>) 20855 0x949C 钜 (<CJK Ideograph>) 20856 0x94A3 钣 (<CJK Ideograph>) 20857 0x94A4 钤 (<CJK Ideograph>) 20858 0x94AB 钫 (<CJK Ideograph>) 20859 0x94AA 钪 (<CJK Ideograph>) 20860 0x94AD 钭 (<CJK Ideograph>) 20861 0x94AC 钬 (<CJK Ideograph>) 20862 0x94AF 钯 (<CJK Ideograph>) 20863 0x94B0 钰 (<CJK Ideograph>) 20864 0x94B2 钲 (<CJK Ideograph>) 20865 0x94B4 钴 (<CJK Ideograph>) 20866 0x94B6 钶 (<CJK Ideograph>) 20867 0x94B7 钷 (<CJK Ideograph>) 20868 0x94B8 钸 (<CJK Ideograph>) 20869 0x94B9 钹 (<CJK Ideograph>) 20870 0x94BA 钺 (<CJK Ideograph>) 20871 0x94BC 钼 (<CJK Ideograph>) 20872 0x94BD 钽 (<CJK Ideograph>) 20873 0x94BF 钿 (<CJK Ideograph>) 20874 0x94C4 铄 (<CJK Ideograph>) 20875 0x94C8 铈 (<CJK Ideograph>) 20876 0x94C9 铉 (<CJK Ideograph>) 20877 0x94CA 铊 (<CJK Ideograph>) 20878 0x94CB 铋 (<CJK Ideograph>) 20879 0x94CC 铌 (<CJK Ideograph>) 20880 0x94CD 铍 (<CJK Ideograph>) 20881 0x94CE 铎 (<CJK Ideograph>) 20882 0x94D0 铐 (<CJK Ideograph>) 20883 0x94D1 铑 (<CJK Ideograph>) 20884 0x94D2 铒 (<CJK Ideograph>) 20885 0x94D5 铕 (<CJK Ideograph>) 20886 0x94D6 铖 (<CJK Ideograph>) 20887 0x94D7 铗 (<CJK Ideograph>) 20888 0x94D9 铙 (<CJK Ideograph>) 20889 0x94D8 铘 (<CJK Ideograph>) 20890 0x94DB 铛 (<CJK Ideograph>) 20891 0x94DE 铞 (<CJK Ideograph>) 20892 0x94DF 铟 (<CJK Ideograph>) 20893 0x94E0 铠 (<CJK Ideograph>) 20894 0x94E2 铢 (<CJK Ideograph>) 20895 0x94E4 铤 (<CJK Ideograph>) 20896 0x94E5 铥 (<CJK Ideograph>) 20897 0x94E7 铧 (<CJK Ideograph>) 20898 0x94E8 铨 (<CJK Ideograph>) 20899 0x94EA 铪 (<CJK Ideograph>) 20900 0x986F 顯 (<CJK Ideograph>) 20901 0x9870 顰 (<CJK Ideograph>) 20902 0x9871 顱 (<CJK Ideograph>) 20903 0x9872 顲 (<CJK Ideograph>) 20904 0x9873 顳 (<CJK Ideograph>) 20905 0x9874 顴 (<CJK Ideograph>) 20906 0x988B 颋 (<CJK Ideograph>) 20907 0x988E 颎 (<CJK Ideograph>) 20908 0x9892 颒 (<CJK Ideograph>) 20909 0x9895 颕 (<CJK Ideograph>) 20910 0x9899 颙 (<CJK Ideograph>) 20911 0x98A3 颣 (<CJK Ideograph>) 20912 0x98A8 風 (<CJK Ideograph>) 20913 0x98A9 颩 (<CJK Ideograph>) 20914 0x98AA 颪 (<CJK Ideograph>) 20915 0x98AB 颫 (<CJK Ideograph>) 20916 0x98AC 颬 (<CJK Ideograph>) 20917 0x98AD 颭 (<CJK Ideograph>) 20918 0x98AE 颮 (<CJK Ideograph>) 20919 0x98AF 颯 (<CJK Ideograph>) 20920 0x98B0 颰 (<CJK Ideograph>) 20921 0x98B1 颱 (<CJK Ideograph>) 20922 0x98B2 颲 (<CJK Ideograph>) 20923 0x98B3 颳 (<CJK Ideograph>) 20924 0x98B4 颴 (<CJK Ideograph>) 20925 0x98B5 颵 (<CJK Ideograph>) 20926 0x98B6 颶 (<CJK Ideograph>) 20927 0x98B7 颷 (<CJK Ideograph>) 20928 0x98B8 颸 (<CJK Ideograph>) 20929 0x98B9 颹 (<CJK Ideograph>) 20930 0x98BA 颺 (<CJK Ideograph>) 20931 0x98BB 颻 (<CJK Ideograph>) 20932 0x98BC 颼 (<CJK Ideograph>) 20933 0x98BD 颽 (<CJK Ideograph>) 20934 0x98BE 颾 (<CJK Ideograph>) 20935 0x98BF 颿 (<CJK Ideograph>) 20936 0x98C0 飀 (<CJK Ideograph>) 20937 0x98C1 飁 (<CJK Ideograph>) 20938 0x98C2 飂 (<CJK Ideograph>) 20939 0x98C3 飃 (<CJK Ideograph>) 20940 0x98C4 飄 (<CJK Ideograph>) 20941 0x98C5 飅 (<CJK Ideograph>) 20942 0x98C6 飆 (<CJK Ideograph>) 20943 0x98C7 飇 (<CJK Ideograph>) 20944 0x98C8 飈 (<CJK Ideograph>) 20945 0x98C9 飉 (<CJK Ideograph>) 20946 0x98CA 飊 (<CJK Ideograph>) 20947 0x98CB 飋 (<CJK Ideograph>) 20948 0x98CC 飌 (<CJK Ideograph>) 20949 0x98CD 飍 (<CJK Ideograph>) 20950 0x98CF 飏 (<CJK Ideograph>) 20951 0x98D0 飐 (<CJK Ideograph>) 20952 0x98D4 飔 (<CJK Ideograph>) 20953 0x98D6 飖 (<CJK Ideograph>) 20954 0x98D7 飗 (<CJK Ideograph>) 20955 0x98DB 飛 (<CJK Ideograph>) 20956 0x98DC 飜 (<CJK Ideograph>) 20957 0x98DD 飝 (<CJK Ideograph>) 20958 0x98E0 飠 (<CJK Ideograph>) 20959 0x98E1 飡 (<CJK Ideograph>) 20960 0x98E2 飢 (<CJK Ideograph>) 20961 0x98E3 飣 (<CJK Ideograph>) 20962 0x98E4 飤 (<CJK Ideograph>) 20963 0x98E5 飥 (<CJK Ideograph>) 20964 0x98E6 飦 (<CJK Ideograph>) 20965 0x98E9 飩 (<CJK Ideograph>) 20966 0x98EA 飪 (<CJK Ideograph>) 20967 0x98EB 飫 (<CJK Ideograph>) 20968 0x98EC 飬 (<CJK Ideograph>) 20969 0x98ED 飭 (<CJK Ideograph>) 20970 0x98EE 飮 (<CJK Ideograph>) 20971 0x98EF 飯 (<CJK Ideograph>) 20972 0x98F0 飰 (<CJK Ideograph>) 20973 0x98F1 飱 (<CJK Ideograph>) 20974 0x98F2 飲 (<CJK Ideograph>) 20975 0x98F3 飳 (<CJK Ideograph>) 20976 0x98F4 飴 (<CJK Ideograph>) 20977 0x98F5 飵 (<CJK Ideograph>) 20978 0x98F6 飶 (<CJK Ideograph>) 20979 0x98F7 飷 (<CJK Ideograph>) 20980 0x98F8 飸 (<CJK Ideograph>) 20981 0x98F9 飹 (<CJK Ideograph>) 20982 0x98FA 飺 (<CJK Ideograph>) 20983 0x98FB 飻 (<CJK Ideograph>) 20984 0x98FC 飼 (<CJK Ideograph>) 20985 0x98FD 飽 (<CJK Ideograph>) 20986 0x98FE 飾 (<CJK Ideograph>) 20987 0x98FF 飿 (<CJK Ideograph>) 20988 0x9900 餀 (<CJK Ideograph>) 20989 0x9901 餁 (<CJK Ideograph>) 20990 0x9902 餂 (<CJK Ideograph>) 20991 0x9903 餃 (<CJK Ideograph>) 20992 0x9904 餄 (<CJK Ideograph>) 20993 0x9905 餅 (<CJK Ideograph>) 20994 0x9906 餆 (<CJK Ideograph>) 20995 0x9907 餇 (<CJK Ideograph>) 20996 0x94E9 铩 (<CJK Ideograph>) 20997 0x94EB 铫 (<CJK Ideograph>) 20998 0x94EE 铮 (<CJK Ideograph>) 20999 0x94EF 铯 (<CJK Ideograph>) 21000 0x94F3 铳 (<CJK Ideograph>) 21001 0x94F4 铴 (<CJK Ideograph>) 21002 0x94F5 铵 (<CJK Ideograph>) 21003 0x94F7 铷 (<CJK Ideograph>) 21004 0x94F9 铹 (<CJK Ideograph>) 21005 0x94FC 铼 (<CJK Ideograph>) 21006 0x94FD 铽 (<CJK Ideograph>) 21007 0x94FF 铿 (<CJK Ideograph>) 21008 0x9503 锃 (<CJK Ideograph>) 21009 0x9502 锂 (<CJK Ideograph>) 21010 0x9506 锆 (<CJK Ideograph>) 21011 0x9507 锇 (<CJK Ideograph>) 21012 0x9509 锉 (<CJK Ideograph>) 21013 0x950A 锊 (<CJK Ideograph>) 21014 0x950D 锍 (<CJK Ideograph>) 21015 0x950E 锎 (<CJK Ideograph>) 21016 0x950F 锏 (<CJK Ideograph>) 21017 0x9512 锒 (<CJK Ideograph>) 21018 0x9513 锓 (<CJK Ideograph>) 21019 0x9514 锔 (<CJK Ideograph>) 21020 0x9515 锕 (<CJK Ideograph>) 21021 0x9516 锖 (<CJK Ideograph>) 21022 0x9518 锘 (<CJK Ideograph>) 21023 0x951B 锛 (<CJK Ideograph>) 21024 0x951D 锝 (<CJK Ideograph>) 21025 0x951E 锞 (<CJK Ideograph>) 21026 0x951F 锟 (<CJK Ideograph>) 21027 0x9522 锢 (<CJK Ideograph>) 21028 0x952A 锪 (<CJK Ideograph>) 21029 0x952B 锫 (<CJK Ideograph>) 21030 0x9529 锩 (<CJK Ideograph>) 21031 0x952C 锬 (<CJK Ideograph>) 21032 0x9531 锱 (<CJK Ideograph>) 21033 0x9532 锲 (<CJK Ideograph>) 21034 0x9534 锴 (<CJK Ideograph>) 21035 0x9536 锶 (<CJK Ideograph>) 21036 0x9537 锷 (<CJK Ideograph>) 21037 0x9538 锸 (<CJK Ideograph>) 21038 0x953C 锼 (<CJK Ideograph>) 21039 0x953E 锾 (<CJK Ideograph>) 21040 0x953F 锿 (<CJK Ideograph>) 21041 0x9542 镂 (<CJK Ideograph>) 21042 0x9535 锵 (<CJK Ideograph>) 21043 0x9544 镄 (<CJK Ideograph>) 21044 0x9545 镅 (<CJK Ideograph>) 21045 0x9546 镆 (<CJK Ideograph>) 21046 0x9549 镉 (<CJK Ideograph>) 21047 0x954C 镌 (<CJK Ideograph>) 21048 0x954E 镎 (<CJK Ideograph>) 21049 0x954F 镏 (<CJK Ideograph>) 21050 0x9552 镒 (<CJK Ideograph>) 21051 0x9553 镓 (<CJK Ideograph>) 21052 0x9554 镔 (<CJK Ideograph>) 21053 0x9556 镖 (<CJK Ideograph>) 21054 0x9557 镗 (<CJK Ideograph>) 21055 0x9558 镘 (<CJK Ideograph>) 21056 0x9559 镙 (<CJK Ideograph>) 21057 0x955B 镛 (<CJK Ideograph>) 21058 0x955E 镞 (<CJK Ideograph>) 21059 0x955F 镟 (<CJK Ideograph>) 21060 0x955D 镝 (<CJK Ideograph>) 21061 0x9561 镡 (<CJK Ideograph>) 21062 0x9562 镢 (<CJK Ideograph>) 21063 0x9564 镤 (<CJK Ideograph>) 21064 0x9565 镥 (<CJK Ideograph>) 21065 0x9566 镦 (<CJK Ideograph>) 21066 0x9567 镧 (<CJK Ideograph>) 21067 0x9568 镨 (<CJK Ideograph>) 21068 0x9569 镩 (<CJK Ideograph>) 21069 0x956A 镪 (<CJK Ideograph>) 21070 0x956B 镫 (<CJK Ideograph>) 21071 0x956C 镬 (<CJK Ideograph>) 21072 0x956F 镯 (<CJK Ideograph>) 21073 0x9571 镱 (<CJK Ideograph>) 21074 0x9572 镲 (<CJK Ideograph>) 21075 0x9573 镳 (<CJK Ideograph>) 21076 0x953A 锺 (<CJK Ideograph>) 21077 0x77E7 矧 (<CJK Ideograph>) 21078 0x77EC 矬 (<CJK Ideograph>) 21079 0x96C9 雉 (<CJK Ideograph>) 21080 0x79D5 秕 (<CJK Ideograph>) 21081 0x79ED 秭 (<CJK Ideograph>) 21082 0x79E3 秣 (<CJK Ideograph>) 21083 0x79EB 秫 (<CJK Ideograph>) 21084 0x7A06 稆 (<CJK Ideograph>) 21085 0x5D47 嵇 (<CJK Ideograph>) 21086 0x7A03 稃 (<CJK Ideograph>) 21087 0x7A02 稂 (<CJK Ideograph>) 21088 0x7A1E 稞 (<CJK Ideograph>) 21089 0x7A14 稔 (<CJK Ideograph>) 21090 0x9908 餈 (<CJK Ideograph>) 21091 0x9909 餉 (<CJK Ideograph>) 21092 0x990A 養 (<CJK Ideograph>) 21093 0x990B 餋 (<CJK Ideograph>) 21094 0x990C 餌 (<CJK Ideograph>) 21095 0x990E 餎 (<CJK Ideograph>) 21096 0x990F 餏 (<CJK Ideograph>) 21097 0x9911 餑 (<CJK Ideograph>) 21098 0x9912 餒 (<CJK Ideograph>) 21099 0x9913 餓 (<CJK Ideograph>) 21100 0x9914 餔 (<CJK Ideograph>) 21101 0x9915 餕 (<CJK Ideograph>) 21102 0x9916 餖 (<CJK Ideograph>) 21103 0x9917 餗 (<CJK Ideograph>) 21104 0x9918 餘 (<CJK Ideograph>) 21105 0x9919 餙 (<CJK Ideograph>) 21106 0x991A 餚 (<CJK Ideograph>) 21107 0x991B 餛 (<CJK Ideograph>) 21108 0x991C 餜 (<CJK Ideograph>) 21109 0x991D 餝 (<CJK Ideograph>) 21110 0x991E 餞 (<CJK Ideograph>) 21111 0x991F 餟 (<CJK Ideograph>) 21112 0x9920 餠 (<CJK Ideograph>) 21113 0x9921 餡 (<CJK Ideograph>) 21114 0x9922 餢 (<CJK Ideograph>) 21115 0x9923 餣 (<CJK Ideograph>) 21116 0x9924 餤 (<CJK Ideograph>) 21117 0x9925 餥 (<CJK Ideograph>) 21118 0x9926 餦 (<CJK Ideograph>) 21119 0x9927 餧 (<CJK Ideograph>) 21120 0x9928 館 (<CJK Ideograph>) 21121 0x9929 餩 (<CJK Ideograph>) 21122 0x992A 餪 (<CJK Ideograph>) 21123 0x992B 餫 (<CJK Ideograph>) 21124 0x992C 餬 (<CJK Ideograph>) 21125 0x992D 餭 (<CJK Ideograph>) 21126 0x992F 餯 (<CJK Ideograph>) 21127 0x9930 餰 (<CJK Ideograph>) 21128 0x9931 餱 (<CJK Ideograph>) 21129 0x9932 餲 (<CJK Ideograph>) 21130 0x9933 餳 (<CJK Ideograph>) 21131 0x9934 餴 (<CJK Ideograph>) 21132 0x9935 餵 (<CJK Ideograph>) 21133 0x9936 餶 (<CJK Ideograph>) 21134 0x9937 餷 (<CJK Ideograph>) 21135 0x9938 餸 (<CJK Ideograph>) 21136 0x9939 餹 (<CJK Ideograph>) 21137 0x993A 餺 (<CJK Ideograph>) 21138 0x993B 餻 (<CJK Ideograph>) 21139 0x993C 餼 (<CJK Ideograph>) 21140 0x993D 餽 (<CJK Ideograph>) 21141 0x993E 餾 (<CJK Ideograph>) 21142 0x993F 餿 (<CJK Ideograph>) 21143 0x9940 饀 (<CJK Ideograph>) 21144 0x9941 饁 (<CJK Ideograph>) 21145 0x9942 饂 (<CJK Ideograph>) 21146 0x9943 饃 (<CJK Ideograph>) 21147 0x9944 饄 (<CJK Ideograph>) 21148 0x9945 饅 (<CJK Ideograph>) 21149 0x9946 饆 (<CJK Ideograph>) 21150 0x9947 饇 (<CJK Ideograph>) 21151 0x9948 饈 (<CJK Ideograph>) 21152 0x9949 饉 (<CJK Ideograph>) 21153 0x994A 饊 (<CJK Ideograph>) 21154 0x994B 饋 (<CJK Ideograph>) 21155 0x994C 饌 (<CJK Ideograph>) 21156 0x994D 饍 (<CJK Ideograph>) 21157 0x994E 饎 (<CJK Ideograph>) 21158 0x994F 饏 (<CJK Ideograph>) 21159 0x9950 饐 (<CJK Ideograph>) 21160 0x9951 饑 (<CJK Ideograph>) 21161 0x9952 饒 (<CJK Ideograph>) 21162 0x9953 饓 (<CJK Ideograph>) 21163 0x9956 饖 (<CJK Ideograph>) 21164 0x9957 饗 (<CJK Ideograph>) 21165 0x9958 饘 (<CJK Ideograph>) 21166 0x9959 饙 (<CJK Ideograph>) 21167 0x995A 饚 (<CJK Ideograph>) 21168 0x995B 饛 (<CJK Ideograph>) 21169 0x995C 饜 (<CJK Ideograph>) 21170 0x995D 饝 (<CJK Ideograph>) 21171 0x995E 饞 (<CJK Ideograph>) 21172 0x995F 饟 (<CJK Ideograph>) 21173 0x9960 饠 (<CJK Ideograph>) 21174 0x9961 饡 (<CJK Ideograph>) 21175 0x9962 饢 (<CJK Ideograph>) 21176 0x9964 饤 (<CJK Ideograph>) 21177 0x9966 饦 (<CJK Ideograph>) 21178 0x9973 饳 (<CJK Ideograph>) 21179 0x9978 饸 (<CJK Ideograph>) 21180 0x9979 饹 (<CJK Ideograph>) 21181 0x997B 饻 (<CJK Ideograph>) 21182 0x997E 饾 (<CJK Ideograph>) 21183 0x9982 馂 (<CJK Ideograph>) 21184 0x9983 馃 (<CJK Ideograph>) 21185 0x9989 馉 (<CJK Ideograph>) 21186 0x7A39 稹 (<CJK Ideograph>) 21187 0x7A37 稷 (<CJK Ideograph>) 21188 0x7A51 穑 (<CJK Ideograph>) 21189 0x9ECF 黏 (<CJK Ideograph>) 21190 0x99A5 馥 (<CJK Ideograph>) 21191 0x7A70 穰 (<CJK Ideograph>) 21192 0x7688 皈 (<CJK Ideograph>) 21193 0x768E 皎 (<CJK Ideograph>) 21194 0x7693 皓 (<CJK Ideograph>) 21195 0x7699 皙 (<CJK Ideograph>) 21196 0x76A4 皤 (<CJK Ideograph>) 21197 0x74DE 瓞 (<CJK Ideograph>) 21198 0x74E0 瓠 (<CJK Ideograph>) 21199 0x752C 甬 (<CJK Ideograph>) 21200 0x9E20 鸠 (<CJK Ideograph>) 21201 0x9E22 鸢 (<CJK Ideograph>) 21202 0x9E28 鸨 (<CJK Ideograph>) 21203 0x9E29 鸩 (<CJK Ideograph>) 21204 0x9E2A 鸪 (<CJK Ideograph>) 21205 0x9E2B 鸫 (<CJK Ideograph>) 21206 0x9E2C 鸬 (<CJK Ideograph>) 21207 0x9E32 鸲 (<CJK Ideograph>) 21208 0x9E31 鸱 (<CJK Ideograph>) 21209 0x9E36 鸶 (<CJK Ideograph>) 21210 0x9E38 鸸 (<CJK Ideograph>) 21211 0x9E37 鸷 (<CJK Ideograph>) 21212 0x9E39 鸹 (<CJK Ideograph>) 21213 0x9E3A 鸺 (<CJK Ideograph>) 21214 0x9E3E 鸾 (<CJK Ideograph>) 21215 0x9E41 鹁 (<CJK Ideograph>) 21216 0x9E42 鹂 (<CJK Ideograph>) 21217 0x9E44 鹄 (<CJK Ideograph>) 21218 0x9E46 鹆 (<CJK Ideograph>) 21219 0x9E47 鹇 (<CJK Ideograph>) 21220 0x9E48 鹈 (<CJK Ideograph>) 21221 0x9E49 鹉 (<CJK Ideograph>) 21222 0x9E4B 鹋 (<CJK Ideograph>) 21223 0x9E4C 鹌 (<CJK Ideograph>) 21224 0x9E4E 鹎 (<CJK Ideograph>) 21225 0x9E51 鹑 (<CJK Ideograph>) 21226 0x9E55 鹕 (<CJK Ideograph>) 21227 0x9E57 鹗 (<CJK Ideograph>) 21228 0x9E5A 鹚 (<CJK Ideograph>) 21229 0x9E5B 鹛 (<CJK Ideograph>) 21230 0x9E5C 鹜 (<CJK Ideograph>) 21231 0x9E5E 鹞 (<CJK Ideograph>) 21232 0x9E63 鹣 (<CJK Ideograph>) 21233 0x9E66 鹦 (<CJK Ideograph>) 21234 0x9E67 鹧 (<CJK Ideograph>) 21235 0x9E68 鹨 (<CJK Ideograph>) 21236 0x9E69 鹩 (<CJK Ideograph>) 21237 0x9E6A 鹪 (<CJK Ideograph>) 21238 0x9E6B 鹫 (<CJK Ideograph>) 21239 0x9E6C 鹬 (<CJK Ideograph>) 21240 0x9E71 鹱 (<CJK Ideograph>) 21241 0x9E6D 鹭 (<CJK Ideograph>) 21242 0x9E73 鹳 (<CJK Ideograph>) 21243 0x7592 疒 (<CJK Ideograph>) 21244 0x7594 疔 (<CJK Ideograph>) 21245 0x7596 疖 (<CJK Ideograph>) 21246 0x75A0 疠 (<CJK Ideograph>) 21247 0x759D 疝 (<CJK Ideograph>) 21248 0x75AC 疬 (<CJK Ideograph>) 21249 0x75A3 疣 (<CJK Ideograph>) 21250 0x75B3 疳 (<CJK Ideograph>) 21251 0x75B4 疴 (<CJK Ideograph>) 21252 0x75B8 疸 (<CJK Ideograph>) 21253 0x75C4 痄 (<CJK Ideograph>) 21254 0x75B1 疱 (<CJK Ideograph>) 21255 0x75B0 疰 (<CJK Ideograph>) 21256 0x75C3 痃 (<CJK Ideograph>) 21257 0x75C2 痂 (<CJK Ideograph>) 21258 0x75D6 痖 (<CJK Ideograph>) 21259 0x75CD 痍 (<CJK Ideograph>) 21260 0x75E3 痣 (<CJK Ideograph>) 21261 0x75E8 痨 (<CJK Ideograph>) 21262 0x75E6 痦 (<CJK Ideograph>) 21263 0x75E4 痤 (<CJK Ideograph>) 21264 0x75EB 痫 (<CJK Ideograph>) 21265 0x75E7 痧 (<CJK Ideograph>) 21266 0x7603 瘃 (<CJK Ideograph>) 21267 0x75F1 痱 (<CJK Ideograph>) 21268 0x75FC 痼 (<CJK Ideograph>) 21269 0x75FF 痿 (<CJK Ideograph>) 21270 0x7610 瘐 (<CJK Ideograph>) 21271 0x7600 瘀 (<CJK Ideograph>) 21272 0x7605 瘅 (<CJK Ideograph>) 21273 0x760C 瘌 (<CJK Ideograph>) 21274 0x7617 瘗 (<CJK Ideograph>) 21275 0x760A 瘊 (<CJK Ideograph>) 21276 0x7625 瘥 (<CJK Ideograph>) 21277 0x7618 瘘 (<CJK Ideograph>) 21278 0x7615 瘕 (<CJK Ideograph>) 21279 0x7619 瘙 (<CJK Ideograph>) 21280 0x998C 馌 (<CJK Ideograph>) 21281 0x998E 馎 (<CJK Ideograph>) 21282 0x999A 馚 (<CJK Ideograph>) 21283 0x999B 馛 (<CJK Ideograph>) 21284 0x999C 馜 (<CJK Ideograph>) 21285 0x999D 馝 (<CJK Ideograph>) 21286 0x999E 馞 (<CJK Ideograph>) 21287 0x999F 馟 (<CJK Ideograph>) 21288 0x99A0 馠 (<CJK Ideograph>) 21289 0x99A1 馡 (<CJK Ideograph>) 21290 0x99A2 馢 (<CJK Ideograph>) 21291 0x99A3 馣 (<CJK Ideograph>) 21292 0x99A4 馤 (<CJK Ideograph>) 21293 0x99A6 馦 (<CJK Ideograph>) 21294 0x99A7 馧 (<CJK Ideograph>) 21295 0x99A9 馩 (<CJK Ideograph>) 21296 0x99AA 馪 (<CJK Ideograph>) 21297 0x99AB 馫 (<CJK Ideograph>) 21298 0x99AC 馬 (<CJK Ideograph>) 21299 0x99AD 馭 (<CJK Ideograph>) 21300 0x99AE 馮 (<CJK Ideograph>) 21301 0x99AF 馯 (<CJK Ideograph>) 21302 0x99B0 馰 (<CJK Ideograph>) 21303 0x99B1 馱 (<CJK Ideograph>) 21304 0x99B2 馲 (<CJK Ideograph>) 21305 0x99B3 馳 (<CJK Ideograph>) 21306 0x99B4 馴 (<CJK Ideograph>) 21307 0x99B5 馵 (<CJK Ideograph>) 21308 0x99B6 馶 (<CJK Ideograph>) 21309 0x99B7 馷 (<CJK Ideograph>) 21310 0x99B8 馸 (<CJK Ideograph>) 21311 0x99B9 馹 (<CJK Ideograph>) 21312 0x99BA 馺 (<CJK Ideograph>) 21313 0x99BB 馻 (<CJK Ideograph>) 21314 0x99BC 馼 (<CJK Ideograph>) 21315 0x99BD 馽 (<CJK Ideograph>) 21316 0x99BE 馾 (<CJK Ideograph>) 21317 0x99BF 馿 (<CJK Ideograph>) 21318 0x99C0 駀 (<CJK Ideograph>) 21319 0x99C1 駁 (<CJK Ideograph>) 21320 0x99C2 駂 (<CJK Ideograph>) 21321 0x99C3 駃 (<CJK Ideograph>) 21322 0x99C4 駄 (<CJK Ideograph>) 21323 0x99C5 駅 (<CJK Ideograph>) 21324 0x99C6 駆 (<CJK Ideograph>) 21325 0x99C7 駇 (<CJK Ideograph>) 21326 0x99C8 駈 (<CJK Ideograph>) 21327 0x99C9 駉 (<CJK Ideograph>) 21328 0x99CA 駊 (<CJK Ideograph>) 21329 0x99CB 駋 (<CJK Ideograph>) 21330 0x99CC 駌 (<CJK Ideograph>) 21331 0x99CD 駍 (<CJK Ideograph>) 21332 0x99CE 駎 (<CJK Ideograph>) 21333 0x99CF 駏 (<CJK Ideograph>) 21334 0x99D0 駐 (<CJK Ideograph>) 21335 0x99D1 駑 (<CJK Ideograph>) 21336 0x99D2 駒 (<CJK Ideograph>) 21337 0x99D3 駓 (<CJK Ideograph>) 21338 0x99D4 駔 (<CJK Ideograph>) 21339 0x99D5 駕 (<CJK Ideograph>) 21340 0x99D6 駖 (<CJK Ideograph>) 21341 0x99D7 駗 (<CJK Ideograph>) 21342 0x99D8 駘 (<CJK Ideograph>) 21343 0x99D9 駙 (<CJK Ideograph>) 21344 0x99DA 駚 (<CJK Ideograph>) 21345 0x99DB 駛 (<CJK Ideograph>) 21346 0x99DC 駜 (<CJK Ideograph>) 21347 0x99DD 駝 (<CJK Ideograph>) 21348 0x99DE 駞 (<CJK Ideograph>) 21349 0x99DF 駟 (<CJK Ideograph>) 21350 0x99E0 駠 (<CJK Ideograph>) 21351 0x99E1 駡 (<CJK Ideograph>) 21352 0x99E2 駢 (<CJK Ideograph>) 21353 0x99E3 駣 (<CJK Ideograph>) 21354 0x99E4 駤 (<CJK Ideograph>) 21355 0x99E5 駥 (<CJK Ideograph>) 21356 0x99E6 駦 (<CJK Ideograph>) 21357 0x99E7 駧 (<CJK Ideograph>) 21358 0x99E8 駨 (<CJK Ideograph>) 21359 0x99E9 駩 (<CJK Ideograph>) 21360 0x99EA 駪 (<CJK Ideograph>) 21361 0x99EB 駫 (<CJK Ideograph>) 21362 0x99EC 駬 (<CJK Ideograph>) 21363 0x99ED 駭 (<CJK Ideograph>) 21364 0x99EE 駮 (<CJK Ideograph>) 21365 0x99EF 駯 (<CJK Ideograph>) 21366 0x99F0 駰 (<CJK Ideograph>) 21367 0x99F1 駱 (<CJK Ideograph>) 21368 0x99F2 駲 (<CJK Ideograph>) 21369 0x99F3 駳 (<CJK Ideograph>) 21370 0x99F4 駴 (<CJK Ideograph>) 21371 0x99F5 駵 (<CJK Ideograph>) 21372 0x99F6 駶 (<CJK Ideograph>) 21373 0x99F7 駷 (<CJK Ideograph>) 21374 0x99F8 駸 (<CJK Ideograph>) 21375 0x99F9 駹 (<CJK Ideograph>) 21376 0x761B 瘛 (<CJK Ideograph>) 21377 0x763C 瘼 (<CJK Ideograph>) 21378 0x7622 瘢 (<CJK Ideograph>) 21379 0x7620 瘠 (<CJK Ideograph>) 21380 0x7640 癀 (<CJK Ideograph>) 21381 0x762D 瘭 (<CJK Ideograph>) 21382 0x7630 瘰 (<CJK Ideograph>) 21383 0x763F 瘿 (<CJK Ideograph>) 21384 0x7635 瘵 (<CJK Ideograph>) 21385 0x7643 癃 (<CJK Ideograph>) 21386 0x763E 瘾 (<CJK Ideograph>) 21387 0x7633 瘳 (<CJK Ideograph>) 21388 0x764D 癍 (<CJK Ideograph>) 21389 0x765E 癞 (<CJK Ideograph>) 21390 0x7654 癔 (<CJK Ideograph>) 21391 0x765C 癜 (<CJK Ideograph>) 21392 0x7656 癖 (<CJK Ideograph>) 21393 0x766B 癫 (<CJK Ideograph>) 21394 0x766F 癯 (<CJK Ideograph>) 21395 0x7FCA 翊 (<CJK Ideograph>) 21396 0x7AE6 竦 (<CJK Ideograph>) 21397 0x7A78 穸 (<CJK Ideograph>) 21398 0x7A79 穹 (<CJK Ideograph>) 21399 0x7A80 窀 (<CJK Ideograph>) 21400 0x7A86 窆 (<CJK Ideograph>) 21401 0x7A88 窈 (<CJK Ideograph>) 21402 0x7A95 窕 (<CJK Ideograph>) 21403 0x7AA6 窦 (<CJK Ideograph>) 21404 0x7AA0 窠 (<CJK Ideograph>) 21405 0x7AAC 窬 (<CJK Ideograph>) 21406 0x7AA8 窨 (<CJK Ideograph>) 21407 0x7AAD 窭 (<CJK Ideograph>) 21408 0x7AB3 窳 (<CJK Ideograph>) 21409 0x8864 衤 (<CJK Ideograph>) 21410 0x8869 衩 (<CJK Ideograph>) 21411 0x8872 衲 (<CJK Ideograph>) 21412 0x887D 衽 (<CJK Ideograph>) 21413 0x887F 衿 (<CJK Ideograph>) 21414 0x8882 袂 (<CJK Ideograph>) 21415 0x88A2 袢 (<CJK Ideograph>) 21416 0x88C6 裆 (<CJK Ideograph>) 21417 0x88B7 袷 (<CJK Ideograph>) 21418 0x88BC 袼 (<CJK Ideograph>) 21419 0x88C9 裉 (<CJK Ideograph>) 21420 0x88E2 裢 (<CJK Ideograph>) 21421 0x88CE 裎 (<CJK Ideograph>) 21422 0x88E3 裣 (<CJK Ideograph>) 21423 0x88E5 裥 (<CJK Ideograph>) 21424 0x88F1 裱 (<CJK Ideograph>) 21425 0x891A 褚 (<CJK Ideograph>) 21426 0x88FC 裼 (<CJK Ideograph>) 21427 0x88E8 裨 (<CJK Ideograph>) 21428 0x88FE 裾 (<CJK Ideograph>) 21429 0x88F0 裰 (<CJK Ideograph>) 21430 0x8921 褡 (<CJK Ideograph>) 21431 0x8919 褙 (<CJK Ideograph>) 21432 0x8913 褓 (<CJK Ideograph>) 21433 0x891B 褛 (<CJK Ideograph>) 21434 0x890A 褊 (<CJK Ideograph>) 21435 0x8934 褴 (<CJK Ideograph>) 21436 0x892B 褫 (<CJK Ideograph>) 21437 0x8936 褶 (<CJK Ideograph>) 21438 0x8941 襁 (<CJK Ideograph>) 21439 0x8966 襦 (<CJK Ideograph>) 21440 0x897B 襻 (<CJK Ideograph>) 21441 0x758B 疋 (<CJK Ideograph>) 21442 0x80E5 胥 (<CJK Ideograph>) 21443 0x76B2 皲 (<CJK Ideograph>) 21444 0x76B4 皴 (<CJK Ideograph>) 21445 0x77DC 矜 (<CJK Ideograph>) 21446 0x8012 耒 (<CJK Ideograph>) 21447 0x8014 耔 (<CJK Ideograph>) 21448 0x8016 耖 (<CJK Ideograph>) 21449 0x801C 耜 (<CJK Ideograph>) 21450 0x8020 耠 (<CJK Ideograph>) 21451 0x8022 耢 (<CJK Ideograph>) 21452 0x8025 耥 (<CJK Ideograph>) 21453 0x8026 耦 (<CJK Ideograph>) 21454 0x8027 耧 (<CJK Ideograph>) 21455 0x8029 耩 (<CJK Ideograph>) 21456 0x8028 耨 (<CJK Ideograph>) 21457 0x8031 耱 (<CJK Ideograph>) 21458 0x800B 耋 (<CJK Ideograph>) 21459 0x8035 耵 (<CJK Ideograph>) 21460 0x8043 聃 (<CJK Ideograph>) 21461 0x8046 聆 (<CJK Ideograph>) 21462 0x804D 聍 (<CJK Ideograph>) 21463 0x8052 聒 (<CJK Ideograph>) 21464 0x8069 聩 (<CJK Ideograph>) 21465 0x8071 聱 (<CJK Ideograph>) 21466 0x8983 覃 (<CJK Ideograph>) 21467 0x9878 顸 (<CJK Ideograph>) 21468 0x9880 颀 (<CJK Ideograph>) 21469 0x9883 颃 (<CJK Ideograph>) 21470 0x99FA 駺 (<CJK Ideograph>) 21471 0x99FB 駻 (<CJK Ideograph>) 21472 0x99FC 駼 (<CJK Ideograph>) 21473 0x99FD 駽 (<CJK Ideograph>) 21474 0x99FE 駾 (<CJK Ideograph>) 21475 0x99FF 駿 (<CJK Ideograph>) 21476 0x9A00 騀 (<CJK Ideograph>) 21477 0x9A01 騁 (<CJK Ideograph>) 21478 0x9A02 騂 (<CJK Ideograph>) 21479 0x9A03 騃 (<CJK Ideograph>) 21480 0x9A04 騄 (<CJK Ideograph>) 21481 0x9A05 騅 (<CJK Ideograph>) 21482 0x9A06 騆 (<CJK Ideograph>) 21483 0x9A07 騇 (<CJK Ideograph>) 21484 0x9A08 騈 (<CJK Ideograph>) 21485 0x9A09 騉 (<CJK Ideograph>) 21486 0x9A0A 騊 (<CJK Ideograph>) 21487 0x9A0B 騋 (<CJK Ideograph>) 21488 0x9A0C 騌 (<CJK Ideograph>) 21489 0x9A0D 騍 (<CJK Ideograph>) 21490 0x9A0E 騎 (<CJK Ideograph>) 21491 0x9A0F 騏 (<CJK Ideograph>) 21492 0x9A10 騐 (<CJK Ideograph>) 21493 0x9A11 騑 (<CJK Ideograph>) 21494 0x9A12 騒 (<CJK Ideograph>) 21495 0x9A13 験 (<CJK Ideograph>) 21496 0x9A14 騔 (<CJK Ideograph>) 21497 0x9A15 騕 (<CJK Ideograph>) 21498 0x9A16 騖 (<CJK Ideograph>) 21499 0x9A17 騗 (<CJK Ideograph>) 21500 0x9A18 騘 (<CJK Ideograph>) 21501 0x9A19 騙 (<CJK Ideograph>) 21502 0x9A1A 騚 (<CJK Ideograph>) 21503 0x9A1B 騛 (<CJK Ideograph>) 21504 0x9A1C 騜 (<CJK Ideograph>) 21505 0x9A1D 騝 (<CJK Ideograph>) 21506 0x9A1E 騞 (<CJK Ideograph>) 21507 0x9A1F 騟 (<CJK Ideograph>) 21508 0x9A20 騠 (<CJK Ideograph>) 21509 0x9A21 騡 (<CJK Ideograph>) 21510 0x9A22 騢 (<CJK Ideograph>) 21511 0x9A23 騣 (<CJK Ideograph>) 21512 0x9A24 騤 (<CJK Ideograph>) 21513 0x9A25 騥 (<CJK Ideograph>) 21514 0x9A26 騦 (<CJK Ideograph>) 21515 0x9A27 騧 (<CJK Ideograph>) 21516 0x9A28 騨 (<CJK Ideograph>) 21517 0x9A29 騩 (<CJK Ideograph>) 21518 0x9A2A 騪 (<CJK Ideograph>) 21519 0x9A2B 騫 (<CJK Ideograph>) 21520 0x9A2C 騬 (<CJK Ideograph>) 21521 0x9A2D 騭 (<CJK Ideograph>) 21522 0x9A2E 騮 (<CJK Ideograph>) 21523 0x9A2F 騯 (<CJK Ideograph>) 21524 0x9A30 騰 (<CJK Ideograph>) 21525 0x9A31 騱 (<CJK Ideograph>) 21526 0x9A32 騲 (<CJK Ideograph>) 21527 0x9A33 騳 (<CJK Ideograph>) 21528 0x9A34 騴 (<CJK Ideograph>) 21529 0x9A35 騵 (<CJK Ideograph>) 21530 0x9A36 騶 (<CJK Ideograph>) 21531 0x9A37 騷 (<CJK Ideograph>) 21532 0x9A38 騸 (<CJK Ideograph>) 21533 0x9A39 騹 (<CJK Ideograph>) 21534 0x9A3A 騺 (<CJK Ideograph>) 21535 0x9A3B 騻 (<CJK Ideograph>) 21536 0x9A3C 騼 (<CJK Ideograph>) 21537 0x9A3D 騽 (<CJK Ideograph>) 21538 0x9A3E 騾 (<CJK Ideograph>) 21539 0x9A3F 騿 (<CJK Ideograph>) 21540 0x9A40 驀 (<CJK Ideograph>) 21541 0x9A41 驁 (<CJK Ideograph>) 21542 0x9A42 驂 (<CJK Ideograph>) 21543 0x9A43 驃 (<CJK Ideograph>) 21544 0x9A44 驄 (<CJK Ideograph>) 21545 0x9A45 驅 (<CJK Ideograph>) 21546 0x9A46 驆 (<CJK Ideograph>) 21547 0x9A47 驇 (<CJK Ideograph>) 21548 0x9A48 驈 (<CJK Ideograph>) 21549 0x9A49 驉 (<CJK Ideograph>) 21550 0x9A4A 驊 (<CJK Ideograph>) 21551 0x9A4B 驋 (<CJK Ideograph>) 21552 0x9A4C 驌 (<CJK Ideograph>) 21553 0x9A4D 驍 (<CJK Ideograph>) 21554 0x9A4E 驎 (<CJK Ideograph>) 21555 0x9A4F 驏 (<CJK Ideograph>) 21556 0x9A50 驐 (<CJK Ideograph>) 21557 0x9A51 驑 (<CJK Ideograph>) 21558 0x9A52 驒 (<CJK Ideograph>) 21559 0x9A53 驓 (<CJK Ideograph>) 21560 0x9A54 驔 (<CJK Ideograph>) 21561 0x9A55 驕 (<CJK Ideograph>) 21562 0x9A56 驖 (<CJK Ideograph>) 21563 0x9A57 驗 (<CJK Ideograph>) 21564 0x9A58 驘 (<CJK Ideograph>) 21565 0x9A59 驙 (<CJK Ideograph>) 21566 0x9889 颉 (<CJK Ideograph>) 21567 0x988C 颌 (<CJK Ideograph>) 21568 0x988D 颍 (<CJK Ideograph>) 21569 0x988F 颏 (<CJK Ideograph>) 21570 0x9894 颔 (<CJK Ideograph>) 21571 0x989A 颚 (<CJK Ideograph>) 21572 0x989B 颛 (<CJK Ideograph>) 21573 0x989E 颞 (<CJK Ideograph>) 21574 0x989F 颟 (<CJK Ideograph>) 21575 0x98A1 颡 (<CJK Ideograph>) 21576 0x98A2 颢 (<CJK Ideograph>) 21577 0x98A5 颥 (<CJK Ideograph>) 21578 0x98A6 颦 (<CJK Ideograph>) 21579 0x864D 虍 (<CJK Ideograph>) 21580 0x8654 虔 (<CJK Ideograph>) 21581 0x866C 虬 (<CJK Ideograph>) 21582 0x866E 虮 (<CJK Ideograph>) 21583 0x867F 虿 (<CJK Ideograph>) 21584 0x867A 虺 (<CJK Ideograph>) 21585 0x867C 虼 (<CJK Ideograph>) 21586 0x867B 虻 (<CJK Ideograph>) 21587 0x86A8 蚨 (<CJK Ideograph>) 21588 0x868D 蚍 (<CJK Ideograph>) 21589 0x868B 蚋 (<CJK Ideograph>) 21590 0x86AC 蚬 (<CJK Ideograph>) 21591 0x869D 蚝 (<CJK Ideograph>) 21592 0x86A7 蚧 (<CJK Ideograph>) 21593 0x86A3 蚣 (<CJK Ideograph>) 21594 0x86AA 蚪 (<CJK Ideograph>) 21595 0x8693 蚓 (<CJK Ideograph>) 21596 0x86A9 蚩 (<CJK Ideograph>) 21597 0x86B6 蚶 (<CJK Ideograph>) 21598 0x86C4 蛄 (<CJK Ideograph>) 21599 0x86B5 蚵 (<CJK Ideograph>) 21600 0x86CE 蛎 (<CJK Ideograph>) 21601 0x86B0 蚰 (<CJK Ideograph>) 21602 0x86BA 蚺 (<CJK Ideograph>) 21603 0x86B1 蚱 (<CJK Ideograph>) 21604 0x86AF 蚯 (<CJK Ideograph>) 21605 0x86C9 蛉 (<CJK Ideograph>) 21606 0x86CF 蛏 (<CJK Ideograph>) 21607 0x86B4 蚴 (<CJK Ideograph>) 21608 0x86E9 蛩 (<CJK Ideograph>) 21609 0x86F1 蛱 (<CJK Ideograph>) 21610 0x86F2 蛲 (<CJK Ideograph>) 21611 0x86ED 蛭 (<CJK Ideograph>) 21612 0x86F3 蛳 (<CJK Ideograph>) 21613 0x86D0 蛐 (<CJK Ideograph>) 21614 0x8713 蜓 (<CJK Ideograph>) 21615 0x86DE 蛞 (<CJK Ideograph>) 21616 0x86F4 蛴 (<CJK Ideograph>) 21617 0x86DF 蛟 (<CJK Ideograph>) 21618 0x86D8 蛘 (<CJK Ideograph>) 21619 0x86D1 蛑 (<CJK Ideograph>) 21620 0x8703 蜃 (<CJK Ideograph>) 21621 0x8707 蜇 (<CJK Ideograph>) 21622 0x86F8 蛸 (<CJK Ideograph>) 21623 0x8708 蜈 (<CJK Ideograph>) 21624 0x870A 蜊 (<CJK Ideograph>) 21625 0x870D 蜍 (<CJK Ideograph>) 21626 0x8709 蜉 (<CJK Ideograph>) 21627 0x8723 蜣 (<CJK Ideograph>) 21628 0x873B 蜻 (<CJK Ideograph>) 21629 0x871E 蜞 (<CJK Ideograph>) 21630 0x8725 蜥 (<CJK Ideograph>) 21631 0x872E 蜮 (<CJK Ideograph>) 21632 0x871A 蜚 (<CJK Ideograph>) 21633 0x873E 蜾 (<CJK Ideograph>) 21634 0x8748 蝈 (<CJK Ideograph>) 21635 0x8734 蜴 (<CJK Ideograph>) 21636 0x8731 蜱 (<CJK Ideograph>) 21637 0x8729 蜩 (<CJK Ideograph>) 21638 0x8737 蜷 (<CJK Ideograph>) 21639 0x873F 蜿 (<CJK Ideograph>) 21640 0x8782 螂 (<CJK Ideograph>) 21641 0x8722 蜢 (<CJK Ideograph>) 21642 0x877D 蝽 (<CJK Ideograph>) 21643 0x877E 蝾 (<CJK Ideograph>) 21644 0x877B 蝻 (<CJK Ideograph>) 21645 0x8760 蝠 (<CJK Ideograph>) 21646 0x8770 蝰 (<CJK Ideograph>) 21647 0x874C 蝌 (<CJK Ideograph>) 21648 0x876E 蝮 (<CJK Ideograph>) 21649 0x878B 螋 (<CJK Ideograph>) 21650 0x8753 蝓 (<CJK Ideograph>) 21651 0x8763 蝣 (<CJK Ideograph>) 21652 0x877C 蝼 (<CJK Ideograph>) 21653 0x8764 蝤 (<CJK Ideograph>) 21654 0x8759 蝙 (<CJK Ideograph>) 21655 0x8765 蝥 (<CJK Ideograph>) 21656 0x8793 螓 (<CJK Ideograph>) 21657 0x87AF 螯 (<CJK Ideograph>) 21658 0x87A8 螨 (<CJK Ideograph>) 21659 0x87D2 蟒 (<CJK Ideograph>) 21660 0x9A5A 驚 (<CJK Ideograph>) 21661 0x9A5B 驛 (<CJK Ideograph>) 21662 0x9A5C 驜 (<CJK Ideograph>) 21663 0x9A5D 驝 (<CJK Ideograph>) 21664 0x9A5E 驞 (<CJK Ideograph>) 21665 0x9A5F 驟 (<CJK Ideograph>) 21666 0x9A60 驠 (<CJK Ideograph>) 21667 0x9A61 驡 (<CJK Ideograph>) 21668 0x9A62 驢 (<CJK Ideograph>) 21669 0x9A63 驣 (<CJK Ideograph>) 21670 0x9A64 驤 (<CJK Ideograph>) 21671 0x9A65 驥 (<CJK Ideograph>) 21672 0x9A66 驦 (<CJK Ideograph>) 21673 0x9A67 驧 (<CJK Ideograph>) 21674 0x9A68 驨 (<CJK Ideograph>) 21675 0x9A69 驩 (<CJK Ideograph>) 21676 0x9A6A 驪 (<CJK Ideograph>) 21677 0x9A6B 驫 (<CJK Ideograph>) 21678 0x9A72 驲 (<CJK Ideograph>) 21679 0x9A83 骃 (<CJK Ideograph>) 21680 0x9A89 骉 (<CJK Ideograph>) 21681 0x9A8D 骍 (<CJK Ideograph>) 21682 0x9A8E 骎 (<CJK Ideograph>) 21683 0x9A94 骔 (<CJK Ideograph>) 21684 0x9A95 骕 (<CJK Ideograph>) 21685 0x9A99 骙 (<CJK Ideograph>) 21686 0x9AA6 骦 (<CJK Ideograph>) 21687 0x9AA9 骩 (<CJK Ideograph>) 21688 0x9AAA 骪 (<CJK Ideograph>) 21689 0x9AAB 骫 (<CJK Ideograph>) 21690 0x9AAC 骬 (<CJK Ideograph>) 21691 0x9AAD 骭 (<CJK Ideograph>) 21692 0x9AAE 骮 (<CJK Ideograph>) 21693 0x9AAF 骯 (<CJK Ideograph>) 21694 0x9AB2 骲 (<CJK Ideograph>) 21695 0x9AB3 骳 (<CJK Ideograph>) 21696 0x9AB4 骴 (<CJK Ideograph>) 21697 0x9AB5 骵 (<CJK Ideograph>) 21698 0x9AB9 骹 (<CJK Ideograph>) 21699 0x9ABB 骻 (<CJK Ideograph>) 21700 0x9ABD 骽 (<CJK Ideograph>) 21701 0x9ABE 骾 (<CJK Ideograph>) 21702 0x9ABF 骿 (<CJK Ideograph>) 21703 0x9AC3 髃 (<CJK Ideograph>) 21704 0x9AC4 髄 (<CJK Ideograph>) 21705 0x9AC6 髆 (<CJK Ideograph>) 21706 0x9AC7 髇 (<CJK Ideograph>) 21707 0x9AC8 髈 (<CJK Ideograph>) 21708 0x9AC9 髉 (<CJK Ideograph>) 21709 0x9ACA 髊 (<CJK Ideograph>) 21710 0x9ACD 髍 (<CJK Ideograph>) 21711 0x9ACE 髎 (<CJK Ideograph>) 21712 0x9ACF 髏 (<CJK Ideograph>) 21713 0x9AD0 髐 (<CJK Ideograph>) 21714 0x9AD2 髒 (<CJK Ideograph>) 21715 0x9AD4 體 (<CJK Ideograph>) 21716 0x9AD5 髕 (<CJK Ideograph>) 21717 0x9AD6 髖 (<CJK Ideograph>) 21718 0x9AD7 髗 (<CJK Ideograph>) 21719 0x9AD9 髙 (<CJK Ideograph>) 21720 0x9ADA 髚 (<CJK Ideograph>) 21721 0x9ADB 髛 (<CJK Ideograph>) 21722 0x9ADC 髜 (<CJK Ideograph>) 21723 0x9ADD 髝 (<CJK Ideograph>) 21724 0x9ADE 髞 (<CJK Ideograph>) 21725 0x9AE0 髠 (<CJK Ideograph>) 21726 0x9AE2 髢 (<CJK Ideograph>) 21727 0x9AE3 髣 (<CJK Ideograph>) 21728 0x9AE4 髤 (<CJK Ideograph>) 21729 0x9AE5 髥 (<CJK Ideograph>) 21730 0x9AE7 髧 (<CJK Ideograph>) 21731 0x9AE8 髨 (<CJK Ideograph>) 21732 0x9AE9 髩 (<CJK Ideograph>) 21733 0x9AEA 髪 (<CJK Ideograph>) 21734 0x9AEC 髬 (<CJK Ideograph>) 21735 0x9AEE 髮 (<CJK Ideograph>) 21736 0x9AF0 髰 (<CJK Ideograph>) 21737 0x9AF1 髱 (<CJK Ideograph>) 21738 0x9AF2 髲 (<CJK Ideograph>) 21739 0x9AF3 髳 (<CJK Ideograph>) 21740 0x9AF4 髴 (<CJK Ideograph>) 21741 0x9AF5 髵 (<CJK Ideograph>) 21742 0x9AF6 髶 (<CJK Ideograph>) 21743 0x9AF7 髷 (<CJK Ideograph>) 21744 0x9AF8 髸 (<CJK Ideograph>) 21745 0x9AFA 髺 (<CJK Ideograph>) 21746 0x9AFC 髼 (<CJK Ideograph>) 21747 0x9AFD 髽 (<CJK Ideograph>) 21748 0x9AFE 髾 (<CJK Ideograph>) 21749 0x9AFF 髿 (<CJK Ideograph>) 21750 0x9B00 鬀 (<CJK Ideograph>) 21751 0x9B01 鬁 (<CJK Ideograph>) 21752 0x9B02 鬂 (<CJK Ideograph>) 21753 0x9B04 鬄 (<CJK Ideograph>) 21754 0x9B05 鬅 (<CJK Ideograph>) 21755 0x9B06 鬆 (<CJK Ideograph>) 21756 0x87C6 蟆 (<CJK Ideograph>) 21757 0x8788 螈 (<CJK Ideograph>) 21758 0x8785 螅 (<CJK Ideograph>) 21759 0x87AD 螭 (<CJK Ideograph>) 21760 0x8797 螗 (<CJK Ideograph>) 21761 0x8783 螃 (<CJK Ideograph>) 21762 0x87AB 螫 (<CJK Ideograph>) 21763 0x87E5 蟥 (<CJK Ideograph>) 21764 0x87AC 螬 (<CJK Ideograph>) 21765 0x87B5 螵 (<CJK Ideograph>) 21766 0x87B3 螳 (<CJK Ideograph>) 21767 0x87CB 蟋 (<CJK Ideograph>) 21768 0x87D3 蟓 (<CJK Ideograph>) 21769 0x87BD 螽 (<CJK Ideograph>) 21770 0x87D1 蟑 (<CJK Ideograph>) 21771 0x87C0 蟀 (<CJK Ideograph>) 21772 0x87CA 蟊 (<CJK Ideograph>) 21773 0x87DB 蟛 (<CJK Ideograph>) 21774 0x87EA 蟪 (<CJK Ideograph>) 21775 0x87E0 蟠 (<CJK Ideograph>) 21776 0x87EE 蟮 (<CJK Ideograph>) 21777 0x8816 蠖 (<CJK Ideograph>) 21778 0x8813 蠓 (<CJK Ideograph>) 21779 0x87FE 蟾 (<CJK Ideograph>) 21780 0x880A 蠊 (<CJK Ideograph>) 21781 0x881B 蠛 (<CJK Ideograph>) 21782 0x8821 蠡 (<CJK Ideograph>) 21783 0x8839 蠹 (<CJK Ideograph>) 21784 0x883C 蠼 (<CJK Ideograph>) 21785 0x7F36 缶 (<CJK Ideograph>) 21786 0x7F42 罂 (<CJK Ideograph>) 21787 0x7F44 罄 (<CJK Ideograph>) 21788 0x7F45 罅 (<CJK Ideograph>) 21789 0x8210 舐 (<CJK Ideograph>) 21790 0x7AFA 竺 (<CJK Ideograph>) 21791 0x7AFD 竽 (<CJK Ideograph>) 21792 0x7B08 笈 (<CJK Ideograph>) 21793 0x7B03 笃 (<CJK Ideograph>) 21794 0x7B04 笄 (<CJK Ideograph>) 21795 0x7B15 笕 (<CJK Ideograph>) 21796 0x7B0A 笊 (<CJK Ideograph>) 21797 0x7B2B 笫 (<CJK Ideograph>) 21798 0x7B0F 笏 (<CJK Ideograph>) 21799 0x7B47 筇 (<CJK Ideograph>) 21800 0x7B38 笸 (<CJK Ideograph>) 21801 0x7B2A 笪 (<CJK Ideograph>) 21802 0x7B19 笙 (<CJK Ideograph>) 21803 0x7B2E 笮 (<CJK Ideograph>) 21804 0x7B31 笱 (<CJK Ideograph>) 21805 0x7B20 笠 (<CJK Ideograph>) 21806 0x7B25 笥 (<CJK Ideograph>) 21807 0x7B24 笤 (<CJK Ideograph>) 21808 0x7B33 笳 (<CJK Ideograph>) 21809 0x7B3E 笾 (<CJK Ideograph>) 21810 0x7B1E 笞 (<CJK Ideograph>) 21811 0x7B58 筘 (<CJK Ideograph>) 21812 0x7B5A 筚 (<CJK Ideograph>) 21813 0x7B45 筅 (<CJK Ideograph>) 21814 0x7B75 筵 (<CJK Ideograph>) 21815 0x7B4C 筌 (<CJK Ideograph>) 21816 0x7B5D 筝 (<CJK Ideograph>) 21817 0x7B60 筠 (<CJK Ideograph>) 21818 0x7B6E 筮 (<CJK Ideograph>) 21819 0x7B7B 筻 (<CJK Ideograph>) 21820 0x7B62 筢 (<CJK Ideograph>) 21821 0x7B72 筲 (<CJK Ideograph>) 21822 0x7B71 筱 (<CJK Ideograph>) 21823 0x7B90 箐 (<CJK Ideograph>) 21824 0x7BA6 箦 (<CJK Ideograph>) 21825 0x7BA7 箧 (<CJK Ideograph>) 21826 0x7BB8 箸 (<CJK Ideograph>) 21827 0x7BAC 箬 (<CJK Ideograph>) 21828 0x7B9D 箝 (<CJK Ideograph>) 21829 0x7BA8 箨 (<CJK Ideograph>) 21830 0x7B85 箅 (<CJK Ideograph>) 21831 0x7BAA 箪 (<CJK Ideograph>) 21832 0x7B9C 箜 (<CJK Ideograph>) 21833 0x7BA2 箢 (<CJK Ideograph>) 21834 0x7BAB 箫 (<CJK Ideograph>) 21835 0x7BB4 箴 (<CJK Ideograph>) 21836 0x7BD1 篑 (<CJK Ideograph>) 21837 0x7BC1 篁 (<CJK Ideograph>) 21838 0x7BCC 篌 (<CJK Ideograph>) 21839 0x7BDD 篝 (<CJK Ideograph>) 21840 0x7BDA 篚 (<CJK Ideograph>) 21841 0x7BE5 篥 (<CJK Ideograph>) 21842 0x7BE6 篦 (<CJK Ideograph>) 21843 0x7BEA 篪 (<CJK Ideograph>) 21844 0x7C0C 簌 (<CJK Ideograph>) 21845 0x7BFE 篾 (<CJK Ideograph>) 21846 0x7BFC 篼 (<CJK Ideograph>) 21847 0x7C0F 簏 (<CJK Ideograph>) 21848 0x7C16 簖 (<CJK Ideograph>) 21849 0x7C0B 簋 (<CJK Ideograph>) 21850 0x9B07 鬇 (<CJK Ideograph>) 21851 0x9B09 鬉 (<CJK Ideograph>) 21852 0x9B0A 鬊 (<CJK Ideograph>) 21853 0x9B0B 鬋 (<CJK Ideograph>) 21854 0x9B0C 鬌 (<CJK Ideograph>) 21855 0x9B0D 鬍 (<CJK Ideograph>) 21856 0x9B0E 鬎 (<CJK Ideograph>) 21857 0x9B10 鬐 (<CJK Ideograph>) 21858 0x9B11 鬑 (<CJK Ideograph>) 21859 0x9B12 鬒 (<CJK Ideograph>) 21860 0x9B14 鬔 (<CJK Ideograph>) 21861 0x9B15 鬕 (<CJK Ideograph>) 21862 0x9B16 鬖 (<CJK Ideograph>) 21863 0x9B17 鬗 (<CJK Ideograph>) 21864 0x9B18 鬘 (<CJK Ideograph>) 21865 0x9B19 鬙 (<CJK Ideograph>) 21866 0x9B1A 鬚 (<CJK Ideograph>) 21867 0x9B1B 鬛 (<CJK Ideograph>) 21868 0x9B1C 鬜 (<CJK Ideograph>) 21869 0x9B1D 鬝 (<CJK Ideograph>) 21870 0x9B1E 鬞 (<CJK Ideograph>) 21871 0x9B20 鬠 (<CJK Ideograph>) 21872 0x9B21 鬡 (<CJK Ideograph>) 21873 0x9B22 鬢 (<CJK Ideograph>) 21874 0x9B24 鬤 (<CJK Ideograph>) 21875 0x9B25 鬥 (<CJK Ideograph>) 21876 0x9B26 鬦 (<CJK Ideograph>) 21877 0x9B27 鬧 (<CJK Ideograph>) 21878 0x9B28 鬨 (<CJK Ideograph>) 21879 0x9B29 鬩 (<CJK Ideograph>) 21880 0x9B2A 鬪 (<CJK Ideograph>) 21881 0x9B2B 鬫 (<CJK Ideograph>) 21882 0x9B2C 鬬 (<CJK Ideograph>) 21883 0x9B2D 鬭 (<CJK Ideograph>) 21884 0x9B2E 鬮 (<CJK Ideograph>) 21885 0x9B30 鬰 (<CJK Ideograph>) 21886 0x9B31 鬱 (<CJK Ideograph>) 21887 0x9B33 鬳 (<CJK Ideograph>) 21888 0x9B34 鬴 (<CJK Ideograph>) 21889 0x9B35 鬵 (<CJK Ideograph>) 21890 0x9B36 鬶 (<CJK Ideograph>) 21891 0x9B37 鬷 (<CJK Ideograph>) 21892 0x9B38 鬸 (<CJK Ideograph>) 21893 0x9B39 鬹 (<CJK Ideograph>) 21894 0x9B3A 鬺 (<CJK Ideograph>) 21895 0x9B3D 鬽 (<CJK Ideograph>) 21896 0x9B3E 鬾 (<CJK Ideograph>) 21897 0x9B3F 鬿 (<CJK Ideograph>) 21898 0x9B40 魀 (<CJK Ideograph>) 21899 0x9B46 魆 (<CJK Ideograph>) 21900 0x9B4A 魊 (<CJK Ideograph>) 21901 0x9B4B 魋 (<CJK Ideograph>) 21902 0x9B4C 魌 (<CJK Ideograph>) 21903 0x9B4E 魎 (<CJK Ideograph>) 21904 0x9B50 魐 (<CJK Ideograph>) 21905 0x9B52 魒 (<CJK Ideograph>) 21906 0x9B53 魓 (<CJK Ideograph>) 21907 0x9B55 魕 (<CJK Ideograph>) 21908 0x9B56 魖 (<CJK Ideograph>) 21909 0x9B57 魗 (<CJK Ideograph>) 21910 0x9B58 魘 (<CJK Ideograph>) 21911 0x9B59 魙 (<CJK Ideograph>) 21912 0x9B5A 魚 (<CJK Ideograph>) 21913 0x9B5B 魛 (<CJK Ideograph>) 21914 0x9B5C 魜 (<CJK Ideograph>) 21915 0x9B5D 魝 (<CJK Ideograph>) 21916 0x9B5E 魞 (<CJK Ideograph>) 21917 0x9B5F 魟 (<CJK Ideograph>) 21918 0x9B60 魠 (<CJK Ideograph>) 21919 0x9B61 魡 (<CJK Ideograph>) 21920 0x9B62 魢 (<CJK Ideograph>) 21921 0x9B63 魣 (<CJK Ideograph>) 21922 0x9B64 魤 (<CJK Ideograph>) 21923 0x9B65 魥 (<CJK Ideograph>) 21924 0x9B66 魦 (<CJK Ideograph>) 21925 0x9B67 魧 (<CJK Ideograph>) 21926 0x9B68 魨 (<CJK Ideograph>) 21927 0x9B69 魩 (<CJK Ideograph>) 21928 0x9B6A 魪 (<CJK Ideograph>) 21929 0x9B6B 魫 (<CJK Ideograph>) 21930 0x9B6C 魬 (<CJK Ideograph>) 21931 0x9B6D 魭 (<CJK Ideograph>) 21932 0x9B6E 魮 (<CJK Ideograph>) 21933 0x9B6F 魯 (<CJK Ideograph>) 21934 0x9B70 魰 (<CJK Ideograph>) 21935 0x9B71 魱 (<CJK Ideograph>) 21936 0x9B72 魲 (<CJK Ideograph>) 21937 0x9B73 魳 (<CJK Ideograph>) 21938 0x9B74 魴 (<CJK Ideograph>) 21939 0x9B75 魵 (<CJK Ideograph>) 21940 0x9B76 魶 (<CJK Ideograph>) 21941 0x9B77 魷 (<CJK Ideograph>) 21942 0x9B78 魸 (<CJK Ideograph>) 21943 0x9B79 魹 (<CJK Ideograph>) 21944 0x9B7A 魺 (<CJK Ideograph>) 21945 0x9B7B 魻 (<CJK Ideograph>) 21946 0x7C1F 簟 (<CJK Ideograph>) 21947 0x7C2A 簪 (<CJK Ideograph>) 21948 0x7C26 簦 (<CJK Ideograph>) 21949 0x7C38 簸 (<CJK Ideograph>) 21950 0x7C41 籁 (<CJK Ideograph>) 21951 0x7C40 籀 (<CJK Ideograph>) 21952 0x81FE 臾 (<CJK Ideograph>) 21953 0x8201 舁 (<CJK Ideograph>) 21954 0x8202 舂 (<CJK Ideograph>) 21955 0x8204 舄 (<CJK Ideograph>) 21956 0x81EC 臬 (<CJK Ideograph>) 21957 0x8844 衄 (<CJK Ideograph>) 21958 0x8221 舡 (<CJK Ideograph>) 21959 0x8222 舢 (<CJK Ideograph>) 21960 0x8223 舣 (<CJK Ideograph>) 21961 0x822D 舭 (<CJK Ideograph>) 21962 0x822F 舯 (<CJK Ideograph>) 21963 0x8228 舨 (<CJK Ideograph>) 21964 0x822B 舫 (<CJK Ideograph>) 21965 0x8238 舸 (<CJK Ideograph>) 21966 0x823B 舻 (<CJK Ideograph>) 21967 0x8233 舳 (<CJK Ideograph>) 21968 0x8234 舴 (<CJK Ideograph>) 21969 0x823E 舾 (<CJK Ideograph>) 21970 0x8244 艄 (<CJK Ideograph>) 21971 0x8249 艉 (<CJK Ideograph>) 21972 0x824B 艋 (<CJK Ideograph>) 21973 0x824F 艏 (<CJK Ideograph>) 21974 0x825A 艚 (<CJK Ideograph>) 21975 0x825F 艟 (<CJK Ideograph>) 21976 0x8268 艨 (<CJK Ideograph>) 21977 0x887E 衾 (<CJK Ideograph>) 21978 0x8885 袅 (<CJK Ideograph>) 21979 0x8888 袈 (<CJK Ideograph>) 21980 0x88D8 裘 (<CJK Ideograph>) 21981 0x88DF 裟 (<CJK Ideograph>) 21982 0x895E 襞 (<CJK Ideograph>) 21983 0x7F9D 羝 (<CJK Ideograph>) 21984 0x7F9F 羟 (<CJK Ideograph>) 21985 0x7FA7 羧 (<CJK Ideograph>) 21986 0x7FAF 羯 (<CJK Ideograph>) 21987 0x7FB0 羰 (<CJK Ideograph>) 21988 0x7FB2 羲 (<CJK Ideograph>) 21989 0x7C7C 籼 (<CJK Ideograph>) 21990 0x6549 敉 (<CJK Ideograph>) 21991 0x7C91 粑 (<CJK Ideograph>) 21992 0x7C9D 粝 (<CJK Ideograph>) 21993 0x7C9C 粜 (<CJK Ideograph>) 21994 0x7C9E 粞 (<CJK Ideograph>) 21995 0x7CA2 粢 (<CJK Ideograph>) 21996 0x7CB2 粲 (<CJK Ideograph>) 21997 0x7CBC 粼 (<CJK Ideograph>) 21998 0x7CBD 粽 (<CJK Ideograph>) 21999 0x7CC1 糁 (<CJK Ideograph>) 22000 0x7CC7 糇 (<CJK Ideograph>) 22001 0x7CCC 糌 (<CJK Ideograph>) 22002 0x7CCD 糍 (<CJK Ideograph>) 22003 0x7CC8 糈 (<CJK Ideograph>) 22004 0x7CC5 糅 (<CJK Ideograph>) 22005 0x7CD7 糗 (<CJK Ideograph>) 22006 0x7CE8 糨 (<CJK Ideograph>) 22007 0x826E 艮 (<CJK Ideograph>) 22008 0x66A8 暨 (<CJK Ideograph>) 22009 0x7FBF 羿 (<CJK Ideograph>) 22010 0x7FCE 翎 (<CJK Ideograph>) 22011 0x7FD5 翕 (<CJK Ideograph>) 22012 0x7FE5 翥 (<CJK Ideograph>) 22013 0x7FE1 翡 (<CJK Ideograph>) 22014 0x7FE6 翦 (<CJK Ideograph>) 22015 0x7FE9 翩 (<CJK Ideograph>) 22016 0x7FEE 翮 (<CJK Ideograph>) 22017 0x7FF3 翳 (<CJK Ideograph>) 22018 0x7CF8 糸 (<CJK Ideograph>) 22019 0x7D77 絷 (<CJK Ideograph>) 22020 0x7DA6 綦 (<CJK Ideograph>) 22021 0x7DAE 綮 (<CJK Ideograph>) 22022 0x7E47 繇 (<CJK Ideograph>) 22023 0x7E9B 纛 (<CJK Ideograph>) 22024 0x9EB8 麸 (<CJK Ideograph>) 22025 0x9EB4 麴 (<CJK Ideograph>) 22026 0x8D73 赳 (<CJK Ideograph>) 22027 0x8D84 趄 (<CJK Ideograph>) 22028 0x8D94 趔 (<CJK Ideograph>) 22029 0x8D91 趑 (<CJK Ideograph>) 22030 0x8DB1 趱 (<CJK Ideograph>) 22031 0x8D67 赧 (<CJK Ideograph>) 22032 0x8D6D 赭 (<CJK Ideograph>) 22033 0x8C47 豇 (<CJK Ideograph>) 22034 0x8C49 豉 (<CJK Ideograph>) 22035 0x914A 酊 (<CJK Ideograph>) 22036 0x9150 酐 (<CJK Ideograph>) 22037 0x914E 酎 (<CJK Ideograph>) 22038 0x914F 酏 (<CJK Ideograph>) 22039 0x9164 酤 (<CJK Ideograph>) 22040 0x9B7C 魼 (<CJK Ideograph>) 22041 0x9B7D 魽 (<CJK Ideograph>) 22042 0x9B7E 魾 (<CJK Ideograph>) 22043 0x9B7F 魿 (<CJK Ideograph>) 22044 0x9B80 鮀 (<CJK Ideograph>) 22045 0x9B81 鮁 (<CJK Ideograph>) 22046 0x9B82 鮂 (<CJK Ideograph>) 22047 0x9B83 鮃 (<CJK Ideograph>) 22048 0x9B84 鮄 (<CJK Ideograph>) 22049 0x9B85 鮅 (<CJK Ideograph>) 22050 0x9B86 鮆 (<CJK Ideograph>) 22051 0x9B87 鮇 (<CJK Ideograph>) 22052 0x9B88 鮈 (<CJK Ideograph>) 22053 0x9B89 鮉 (<CJK Ideograph>) 22054 0x9B8A 鮊 (<CJK Ideograph>) 22055 0x9B8B 鮋 (<CJK Ideograph>) 22056 0x9B8C 鮌 (<CJK Ideograph>) 22057 0x9B8D 鮍 (<CJK Ideograph>) 22058 0x9B8E 鮎 (<CJK Ideograph>) 22059 0x9B8F 鮏 (<CJK Ideograph>) 22060 0x9B90 鮐 (<CJK Ideograph>) 22061 0x9B91 鮑 (<CJK Ideograph>) 22062 0x9B92 鮒 (<CJK Ideograph>) 22063 0x9B93 鮓 (<CJK Ideograph>) 22064 0x9B94 鮔 (<CJK Ideograph>) 22065 0x9B95 鮕 (<CJK Ideograph>) 22066 0x9B96 鮖 (<CJK Ideograph>) 22067 0x9B97 鮗 (<CJK Ideograph>) 22068 0x9B98 鮘 (<CJK Ideograph>) 22069 0x9B99 鮙 (<CJK Ideograph>) 22070 0x9B9A 鮚 (<CJK Ideograph>) 22071 0x9B9B 鮛 (<CJK Ideograph>) 22072 0x9B9C 鮜 (<CJK Ideograph>) 22073 0x9B9D 鮝 (<CJK Ideograph>) 22074 0x9B9E 鮞 (<CJK Ideograph>) 22075 0x9B9F 鮟 (<CJK Ideograph>) 22076 0x9BA0 鮠 (<CJK Ideograph>) 22077 0x9BA1 鮡 (<CJK Ideograph>) 22078 0x9BA2 鮢 (<CJK Ideograph>) 22079 0x9BA3 鮣 (<CJK Ideograph>) 22080 0x9BA4 鮤 (<CJK Ideograph>) 22081 0x9BA5 鮥 (<CJK Ideograph>) 22082 0x9BA6 鮦 (<CJK Ideograph>) 22083 0x9BA7 鮧 (<CJK Ideograph>) 22084 0x9BA8 鮨 (<CJK Ideograph>) 22085 0x9BA9 鮩 (<CJK Ideograph>) 22086 0x9BAA 鮪 (<CJK Ideograph>) 22087 0x9BAB 鮫 (<CJK Ideograph>) 22088 0x9BAC 鮬 (<CJK Ideograph>) 22089 0x9BAD 鮭 (<CJK Ideograph>) 22090 0x9BAE 鮮 (<CJK Ideograph>) 22091 0x9BAF 鮯 (<CJK Ideograph>) 22092 0x9BB0 鮰 (<CJK Ideograph>) 22093 0x9BB1 鮱 (<CJK Ideograph>) 22094 0x9BB2 鮲 (<CJK Ideograph>) 22095 0x9BB3 鮳 (<CJK Ideograph>) 22096 0x9BB4 鮴 (<CJK Ideograph>) 22097 0x9BB5 鮵 (<CJK Ideograph>) 22098 0x9BB6 鮶 (<CJK Ideograph>) 22099 0x9BB7 鮷 (<CJK Ideograph>) 22100 0x9BB8 鮸 (<CJK Ideograph>) 22101 0x9BB9 鮹 (<CJK Ideograph>) 22102 0x9BBA 鮺 (<CJK Ideograph>) 22103 0x9BBB 鮻 (<CJK Ideograph>) 22104 0x9BBC 鮼 (<CJK Ideograph>) 22105 0x9BBD 鮽 (<CJK Ideograph>) 22106 0x9BBE 鮾 (<CJK Ideograph>) 22107 0x9BBF 鮿 (<CJK Ideograph>) 22108 0x9BC0 鯀 (<CJK Ideograph>) 22109 0x9BC1 鯁 (<CJK Ideograph>) 22110 0x9BC2 鯂 (<CJK Ideograph>) 22111 0x9BC3 鯃 (<CJK Ideograph>) 22112 0x9BC4 鯄 (<CJK Ideograph>) 22113 0x9BC5 鯅 (<CJK Ideograph>) 22114 0x9BC6 鯆 (<CJK Ideograph>) 22115 0x9BC7 鯇 (<CJK Ideograph>) 22116 0x9BC8 鯈 (<CJK Ideograph>) 22117 0x9BC9 鯉 (<CJK Ideograph>) 22118 0x9BCA 鯊 (<CJK Ideograph>) 22119 0x9BCB 鯋 (<CJK Ideograph>) 22120 0x9BCC 鯌 (<CJK Ideograph>) 22121 0x9BCD 鯍 (<CJK Ideograph>) 22122 0x9BCE 鯎 (<CJK Ideograph>) 22123 0x9BCF 鯏 (<CJK Ideograph>) 22124 0x9BD0 鯐 (<CJK Ideograph>) 22125 0x9BD1 鯑 (<CJK Ideograph>) 22126 0x9BD2 鯒 (<CJK Ideograph>) 22127 0x9BD3 鯓 (<CJK Ideograph>) 22128 0x9BD4 鯔 (<CJK Ideograph>) 22129 0x9BD5 鯕 (<CJK Ideograph>) 22130 0x9BD6 鯖 (<CJK Ideograph>) 22131 0x9BD7 鯗 (<CJK Ideograph>) 22132 0x9BD8 鯘 (<CJK Ideograph>) 22133 0x9BD9 鯙 (<CJK Ideograph>) 22134 0x9BDA 鯚 (<CJK Ideograph>) 22135 0x9BDB 鯛 (<CJK Ideograph>) 22136 0x9162 酢 (<CJK Ideograph>) 22137 0x9161 酡 (<CJK Ideograph>) 22138 0x9170 酰 (<CJK Ideograph>) 22139 0x9169 酩 (<CJK Ideograph>) 22140 0x916F 酯 (<CJK Ideograph>) 22141 0x917D 酽 (<CJK Ideograph>) 22142 0x917E 酾 (<CJK Ideograph>) 22143 0x9172 酲 (<CJK Ideograph>) 22144 0x9174 酴 (<CJK Ideograph>) 22145 0x9179 酹 (<CJK Ideograph>) 22146 0x918C 醌 (<CJK Ideograph>) 22147 0x9185 醅 (<CJK Ideograph>) 22148 0x9190 醐 (<CJK Ideograph>) 22149 0x918D 醍 (<CJK Ideograph>) 22150 0x9191 醑 (<CJK Ideograph>) 22151 0x91A2 醢 (<CJK Ideograph>) 22152 0x91A3 醣 (<CJK Ideograph>) 22153 0x91AA 醪 (<CJK Ideograph>) 22154 0x91AD 醭 (<CJK Ideograph>) 22155 0x91AE 醮 (<CJK Ideograph>) 22156 0x91AF 醯 (<CJK Ideograph>) 22157 0x91B5 醵 (<CJK Ideograph>) 22158 0x91B4 醴 (<CJK Ideograph>) 22159 0x91BA 醺 (<CJK Ideograph>) 22160 0x8C55 豕 (<CJK Ideograph>) 22161 0x9E7E 鹾 (<CJK Ideograph>) 22162 0x8DB8 趸 (<CJK Ideograph>) 22163 0x8DEB 跫 (<CJK Ideograph>) 22164 0x8E05 踅 (<CJK Ideograph>) 22165 0x8E59 蹙 (<CJK Ideograph>) 22166 0x8E69 蹩 (<CJK Ideograph>) 22167 0x8DB5 趵 (<CJK Ideograph>) 22168 0x8DBF 趿 (<CJK Ideograph>) 22169 0x8DBC 趼 (<CJK Ideograph>) 22170 0x8DBA 趺 (<CJK Ideograph>) 22171 0x8DC4 跄 (<CJK Ideograph>) 22172 0x8DD6 跖 (<CJK Ideograph>) 22173 0x8DD7 跗 (<CJK Ideograph>) 22174 0x8DDA 跚 (<CJK Ideograph>) 22175 0x8DDE 跞 (<CJK Ideograph>) 22176 0x8DCE 跎 (<CJK Ideograph>) 22177 0x8DCF 跏 (<CJK Ideograph>) 22178 0x8DDB 跛 (<CJK Ideograph>) 22179 0x8DC6 跆 (<CJK Ideograph>) 22180 0x8DEC 跬 (<CJK Ideograph>) 22181 0x8DF7 跷 (<CJK Ideograph>) 22182 0x8DF8 跸 (<CJK Ideograph>) 22183 0x8DE3 跣 (<CJK Ideograph>) 22184 0x8DF9 跹 (<CJK Ideograph>) 22185 0x8DFB 跻 (<CJK Ideograph>) 22186 0x8DE4 跤 (<CJK Ideograph>) 22187 0x8E09 踉 (<CJK Ideograph>) 22188 0x8DFD 跽 (<CJK Ideograph>) 22189 0x8E14 踔 (<CJK Ideograph>) 22190 0x8E1D 踝 (<CJK Ideograph>) 22191 0x8E1F 踟 (<CJK Ideograph>) 22192 0x8E2C 踬 (<CJK Ideograph>) 22193 0x8E2E 踮 (<CJK Ideograph>) 22194 0x8E23 踣 (<CJK Ideograph>) 22195 0x8E2F 踯 (<CJK Ideograph>) 22196 0x8E3A 踺 (<CJK Ideograph>) 22197 0x8E40 蹀 (<CJK Ideograph>) 22198 0x8E39 踹 (<CJK Ideograph>) 22199 0x8E35 踵 (<CJK Ideograph>) 22200 0x8E3D 踽 (<CJK Ideograph>) 22201 0x8E31 踱 (<CJK Ideograph>) 22202 0x8E49 蹉 (<CJK Ideograph>) 22203 0x8E41 蹁 (<CJK Ideograph>) 22204 0x8E42 蹂 (<CJK Ideograph>) 22205 0x8E51 蹑 (<CJK Ideograph>) 22206 0x8E52 蹒 (<CJK Ideograph>) 22207 0x8E4A 蹊 (<CJK Ideograph>) 22208 0x8E70 蹰 (<CJK Ideograph>) 22209 0x8E76 蹶 (<CJK Ideograph>) 22210 0x8E7C 蹼 (<CJK Ideograph>) 22211 0x8E6F 蹯 (<CJK Ideograph>) 22212 0x8E74 蹴 (<CJK Ideograph>) 22213 0x8E85 躅 (<CJK Ideograph>) 22214 0x8E8F 躏 (<CJK Ideograph>) 22215 0x8E94 躔 (<CJK Ideograph>) 22216 0x8E90 躐 (<CJK Ideograph>) 22217 0x8E9C 躜 (<CJK Ideograph>) 22218 0x8E9E 躞 (<CJK Ideograph>) 22219 0x8C78 豸 (<CJK Ideograph>) 22220 0x8C82 貂 (<CJK Ideograph>) 22221 0x8C8A 貊 (<CJK Ideograph>) 22222 0x8C85 貅 (<CJK Ideograph>) 22223 0x8C98 貘 (<CJK Ideograph>) 22224 0x8C94 貔 (<CJK Ideograph>) 22225 0x659B 斛 (<CJK Ideograph>) 22226 0x89D6 觖 (<CJK Ideograph>) 22227 0x89DE 觞 (<CJK Ideograph>) 22228 0x89DA 觚 (<CJK Ideograph>) 22229 0x89DC 觜 (<CJK Ideograph>) 22230 0x9BDC 鯜 (<CJK Ideograph>) 22231 0x9BDD 鯝 (<CJK Ideograph>) 22232 0x9BDE 鯞 (<CJK Ideograph>) 22233 0x9BDF 鯟 (<CJK Ideograph>) 22234 0x9BE0 鯠 (<CJK Ideograph>) 22235 0x9BE1 鯡 (<CJK Ideograph>) 22236 0x9BE2 鯢 (<CJK Ideograph>) 22237 0x9BE3 鯣 (<CJK Ideograph>) 22238 0x9BE4 鯤 (<CJK Ideograph>) 22239 0x9BE5 鯥 (<CJK Ideograph>) 22240 0x9BE6 鯦 (<CJK Ideograph>) 22241 0x9BE7 鯧 (<CJK Ideograph>) 22242 0x9BE8 鯨 (<CJK Ideograph>) 22243 0x9BE9 鯩 (<CJK Ideograph>) 22244 0x9BEA 鯪 (<CJK Ideograph>) 22245 0x9BEB 鯫 (<CJK Ideograph>) 22246 0x9BEC 鯬 (<CJK Ideograph>) 22247 0x9BED 鯭 (<CJK Ideograph>) 22248 0x9BEE 鯮 (<CJK Ideograph>) 22249 0x9BEF 鯯 (<CJK Ideograph>) 22250 0x9BF0 鯰 (<CJK Ideograph>) 22251 0x9BF1 鯱 (<CJK Ideograph>) 22252 0x9BF2 鯲 (<CJK Ideograph>) 22253 0x9BF3 鯳 (<CJK Ideograph>) 22254 0x9BF4 鯴 (<CJK Ideograph>) 22255 0x9BF5 鯵 (<CJK Ideograph>) 22256 0x9BF6 鯶 (<CJK Ideograph>) 22257 0x9BF7 鯷 (<CJK Ideograph>) 22258 0x9BF8 鯸 (<CJK Ideograph>) 22259 0x9BF9 鯹 (<CJK Ideograph>) 22260 0x9BFA 鯺 (<CJK Ideograph>) 22261 0x9BFB 鯻 (<CJK Ideograph>) 22262 0x9BFC 鯼 (<CJK Ideograph>) 22263 0x9BFD 鯽 (<CJK Ideograph>) 22264 0x9BFE 鯾 (<CJK Ideograph>) 22265 0x9BFF 鯿 (<CJK Ideograph>) 22266 0x9C00 鰀 (<CJK Ideograph>) 22267 0x9C01 鰁 (<CJK Ideograph>) 22268 0x9C02 鰂 (<CJK Ideograph>) 22269 0x9C03 鰃 (<CJK Ideograph>) 22270 0x9C04 鰄 (<CJK Ideograph>) 22271 0x9C05 鰅 (<CJK Ideograph>) 22272 0x9C06 鰆 (<CJK Ideograph>) 22273 0x9C07 鰇 (<CJK Ideograph>) 22274 0x9C08 鰈 (<CJK Ideograph>) 22275 0x9C09 鰉 (<CJK Ideograph>) 22276 0x9C0A 鰊 (<CJK Ideograph>) 22277 0x9C0B 鰋 (<CJK Ideograph>) 22278 0x9C0C 鰌 (<CJK Ideograph>) 22279 0x9C0D 鰍 (<CJK Ideograph>) 22280 0x9C0E 鰎 (<CJK Ideograph>) 22281 0x9C0F 鰏 (<CJK Ideograph>) 22282 0x9C10 鰐 (<CJK Ideograph>) 22283 0x9C11 鰑 (<CJK Ideograph>) 22284 0x9C12 鰒 (<CJK Ideograph>) 22285 0x9C13 鰓 (<CJK Ideograph>) 22286 0x9C14 鰔 (<CJK Ideograph>) 22287 0x9C15 鰕 (<CJK Ideograph>) 22288 0x9C16 鰖 (<CJK Ideograph>) 22289 0x9C17 鰗 (<CJK Ideograph>) 22290 0x9C18 鰘 (<CJK Ideograph>) 22291 0x9C19 鰙 (<CJK Ideograph>) 22292 0x9C1A 鰚 (<CJK Ideograph>) 22293 0x9C1B 鰛 (<CJK Ideograph>) 22294 0x9C1C 鰜 (<CJK Ideograph>) 22295 0x9C1D 鰝 (<CJK Ideograph>) 22296 0x9C1E 鰞 (<CJK Ideograph>) 22297 0x9C1F 鰟 (<CJK Ideograph>) 22298 0x9C20 鰠 (<CJK Ideograph>) 22299 0x9C21 鰡 (<CJK Ideograph>) 22300 0x9C22 鰢 (<CJK Ideograph>) 22301 0x9C23 鰣 (<CJK Ideograph>) 22302 0x9C24 鰤 (<CJK Ideograph>) 22303 0x9C25 鰥 (<CJK Ideograph>) 22304 0x9C26 鰦 (<CJK Ideograph>) 22305 0x9C27 鰧 (<CJK Ideograph>) 22306 0x9C28 鰨 (<CJK Ideograph>) 22307 0x9C29 鰩 (<CJK Ideograph>) 22308 0x9C2A 鰪 (<CJK Ideograph>) 22309 0x9C2B 鰫 (<CJK Ideograph>) 22310 0x9C2C 鰬 (<CJK Ideograph>) 22311 0x9C2D 鰭 (<CJK Ideograph>) 22312 0x9C2E 鰮 (<CJK Ideograph>) 22313 0x9C2F 鰯 (<CJK Ideograph>) 22314 0x9C30 鰰 (<CJK Ideograph>) 22315 0x9C31 鰱 (<CJK Ideograph>) 22316 0x9C32 鰲 (<CJK Ideograph>) 22317 0x9C33 鰳 (<CJK Ideograph>) 22318 0x9C34 鰴 (<CJK Ideograph>) 22319 0x9C35 鰵 (<CJK Ideograph>) 22320 0x9C36 鰶 (<CJK Ideograph>) 22321 0x9C37 鰷 (<CJK Ideograph>) 22322 0x9C38 鰸 (<CJK Ideograph>) 22323 0x9C39 鰹 (<CJK Ideograph>) 22324 0x9C3A 鰺 (<CJK Ideograph>) 22325 0x9C3B 鰻 (<CJK Ideograph>) 22326 0x89E5 觥 (<CJK Ideograph>) 22327 0x89EB 觫 (<CJK Ideograph>) 22328 0x89EF 觯 (<CJK Ideograph>) 22329 0x8A3E 訾 (<CJK Ideograph>) 22330 0x8B26 謦 (<CJK Ideograph>) 22331 0x9753 靓 (<CJK Ideograph>) 22332 0x96E9 雩 (<CJK Ideograph>) 22333 0x96F3 雳 (<CJK Ideograph>) 22334 0x96EF 雯 (<CJK Ideograph>) 22335 0x9706 霆 (<CJK Ideograph>) 22336 0x9701 霁 (<CJK Ideograph>) 22337 0x9708 霈 (<CJK Ideograph>) 22338 0x970F 霏 (<CJK Ideograph>) 22339 0x970E 霎 (<CJK Ideograph>) 22340 0x972A 霪 (<CJK Ideograph>) 22341 0x972D 霭 (<CJK Ideograph>) 22342 0x9730 霰 (<CJK Ideograph>) 22343 0x973E 霾 (<CJK Ideograph>) 22344 0x9F80 龀 (<CJK Ideograph>) 22345 0x9F83 龃 (<CJK Ideograph>) 22346 0x9F85 龅 (<CJK Ideograph>) 22347 0x9F86 龆 (<CJK Ideograph>) 22348 0x9F87 龇 (<CJK Ideograph>) 22349 0x9F88 龈 (<CJK Ideograph>) 22350 0x9F89 龉 (<CJK Ideograph>) 22351 0x9F8A 龊 (<CJK Ideograph>) 22352 0x9F8C 龌 (<CJK Ideograph>) 22353 0x9EFE 黾 (<CJK Ideograph>) 22354 0x9F0B 鼋 (<CJK Ideograph>) 22355 0x9F0D 鼍 (<CJK Ideograph>) 22356 0x96B9 隹 (<CJK Ideograph>) 22357 0x96BC 隼 (<CJK Ideograph>) 22358 0x96BD 隽 (<CJK Ideograph>) 22359 0x96CE 雎 (<CJK Ideograph>) 22360 0x96D2 雒 (<CJK Ideograph>) 22361 0x77BF 瞿 (<CJK Ideograph>) 22362 0x96E0 雠 (<CJK Ideograph>) 22363 0x928E 銎 (<CJK Ideograph>) 22364 0x92AE 銮 (<CJK Ideograph>) 22365 0x92C8 鋈 (<CJK Ideograph>) 22366 0x933E 錾 (<CJK Ideograph>) 22367 0x936A 鍪 (<CJK Ideograph>) 22368 0x93CA 鏊 (<CJK Ideograph>) 22369 0x938F 鎏 (<CJK Ideograph>) 22370 0x943E 鐾 (<CJK Ideograph>) 22371 0x946B 鑫 (<CJK Ideograph>) 22372 0x9C7F 鱿 (<CJK Ideograph>) 22373 0x9C82 鲂 (<CJK Ideograph>) 22374 0x9C85 鲅 (<CJK Ideograph>) 22375 0x9C86 鲆 (<CJK Ideograph>) 22376 0x9C87 鲇 (<CJK Ideograph>) 22377 0x9C88 鲈 (<CJK Ideograph>) 22378 0x7A23 稣 (<CJK Ideograph>) 22379 0x9C8B 鲋 (<CJK Ideograph>) 22380 0x9C8E 鲎 (<CJK Ideograph>) 22381 0x9C90 鲐 (<CJK Ideograph>) 22382 0x9C91 鲑 (<CJK Ideograph>) 22383 0x9C92 鲒 (<CJK Ideograph>) 22384 0x9C94 鲔 (<CJK Ideograph>) 22385 0x9C95 鲕 (<CJK Ideograph>) 22386 0x9C9A 鲚 (<CJK Ideograph>) 22387 0x9C9B 鲛 (<CJK Ideograph>) 22388 0x9C9E 鲞 (<CJK Ideograph>) 22389 0x9C9F 鲟 (<CJK Ideograph>) 22390 0x9CA0 鲠 (<CJK Ideograph>) 22391 0x9CA1 鲡 (<CJK Ideograph>) 22392 0x9CA2 鲢 (<CJK Ideograph>) 22393 0x9CA3 鲣 (<CJK Ideograph>) 22394 0x9CA5 鲥 (<CJK Ideograph>) 22395 0x9CA6 鲦 (<CJK Ideograph>) 22396 0x9CA7 鲧 (<CJK Ideograph>) 22397 0x9CA8 鲨 (<CJK Ideograph>) 22398 0x9CA9 鲩 (<CJK Ideograph>) 22399 0x9CAB 鲫 (<CJK Ideograph>) 22400 0x9CAD 鲭 (<CJK Ideograph>) 22401 0x9CAE 鲮 (<CJK Ideograph>) 22402 0x9CB0 鲰 (<CJK Ideograph>) 22403 0x9CB1 鲱 (<CJK Ideograph>) 22404 0x9CB2 鲲 (<CJK Ideograph>) 22405 0x9CB3 鲳 (<CJK Ideograph>) 22406 0x9CB4 鲴 (<CJK Ideograph>) 22407 0x9CB5 鲵 (<CJK Ideograph>) 22408 0x9CB6 鲶 (<CJK Ideograph>) 22409 0x9CB7 鲷 (<CJK Ideograph>) 22410 0x9CBA 鲺 (<CJK Ideograph>) 22411 0x9CBB 鲻 (<CJK Ideograph>) 22412 0x9CBC 鲼 (<CJK Ideograph>) 22413 0x9CBD 鲽 (<CJK Ideograph>) 22414 0x9CC4 鳄 (<CJK Ideograph>) 22415 0x9CC5 鳅 (<CJK Ideograph>) 22416 0x9CC6 鳆 (<CJK Ideograph>) 22417 0x9CC7 鳇 (<CJK Ideograph>) 22418 0x9CCA 鳊 (<CJK Ideograph>) 22419 0x9CCB 鳋 (<CJK Ideograph>) 22420 0x9C3C 鰼 (<CJK Ideograph>) 22421 0x9C3D 鰽 (<CJK Ideograph>) 22422 0x9C3E 鰾 (<CJK Ideograph>) 22423 0x9C3F 鰿 (<CJK Ideograph>) 22424 0x9C40 鱀 (<CJK Ideograph>) 22425 0x9C41 鱁 (<CJK Ideograph>) 22426 0x9C42 鱂 (<CJK Ideograph>) 22427 0x9C43 鱃 (<CJK Ideograph>) 22428 0x9C44 鱄 (<CJK Ideograph>) 22429 0x9C45 鱅 (<CJK Ideograph>) 22430 0x9C46 鱆 (<CJK Ideograph>) 22431 0x9C47 鱇 (<CJK Ideograph>) 22432 0x9C48 鱈 (<CJK Ideograph>) 22433 0x9C49 鱉 (<CJK Ideograph>) 22434 0x9C4A 鱊 (<CJK Ideograph>) 22435 0x9C4B 鱋 (<CJK Ideograph>) 22436 0x9C4C 鱌 (<CJK Ideograph>) 22437 0x9C4D 鱍 (<CJK Ideograph>) 22438 0x9C4E 鱎 (<CJK Ideograph>) 22439 0x9C4F 鱏 (<CJK Ideograph>) 22440 0x9C50 鱐 (<CJK Ideograph>) 22441 0x9C51 鱑 (<CJK Ideograph>) 22442 0x9C52 鱒 (<CJK Ideograph>) 22443 0x9C53 鱓 (<CJK Ideograph>) 22444 0x9C54 鱔 (<CJK Ideograph>) 22445 0x9C55 鱕 (<CJK Ideograph>) 22446 0x9C56 鱖 (<CJK Ideograph>) 22447 0x9C57 鱗 (<CJK Ideograph>) 22448 0x9C58 鱘 (<CJK Ideograph>) 22449 0x9C59 鱙 (<CJK Ideograph>) 22450 0x9C5A 鱚 (<CJK Ideograph>) 22451 0x9C5B 鱛 (<CJK Ideograph>) 22452 0x9C5C 鱜 (<CJK Ideograph>) 22453 0x9C5D 鱝 (<CJK Ideograph>) 22454 0x9C5E 鱞 (<CJK Ideograph>) 22455 0x9C5F 鱟 (<CJK Ideograph>) 22456 0x9C60 鱠 (<CJK Ideograph>) 22457 0x9C61 鱡 (<CJK Ideograph>) 22458 0x9C62 鱢 (<CJK Ideograph>) 22459 0x9C63 鱣 (<CJK Ideograph>) 22460 0x9C64 鱤 (<CJK Ideograph>) 22461 0x9C65 鱥 (<CJK Ideograph>) 22462 0x9C66 鱦 (<CJK Ideograph>) 22463 0x9C67 鱧 (<CJK Ideograph>) 22464 0x9C68 鱨 (<CJK Ideograph>) 22465 0x9C69 鱩 (<CJK Ideograph>) 22466 0x9C6A 鱪 (<CJK Ideograph>) 22467 0x9C6B 鱫 (<CJK Ideograph>) 22468 0x9C6C 鱬 (<CJK Ideograph>) 22469 0x9C6D 鱭 (<CJK Ideograph>) 22470 0x9C6E 鱮 (<CJK Ideograph>) 22471 0x9C6F 鱯 (<CJK Ideograph>) 22472 0x9C70 鱰 (<CJK Ideograph>) 22473 0x9C71 鱱 (<CJK Ideograph>) 22474 0x9C72 鱲 (<CJK Ideograph>) 22475 0x9C73 鱳 (<CJK Ideograph>) 22476 0x9C74 鱴 (<CJK Ideograph>) 22477 0x9C75 鱵 (<CJK Ideograph>) 22478 0x9C76 鱶 (<CJK Ideograph>) 22479 0x9C77 鱷 (<CJK Ideograph>) 22480 0x9C78 鱸 (<CJK Ideograph>) 22481 0x9C79 鱹 (<CJK Ideograph>) 22482 0x9C7A 鱺 (<CJK Ideograph>) 22483 0x9C7B 鱻 (<CJK Ideograph>) 22484 0x9C7D 鱽 (<CJK Ideograph>) 22485 0x9C7E 鱾 (<CJK Ideograph>) 22486 0x9C80 鲀 (<CJK Ideograph>) 22487 0x9C83 鲃 (<CJK Ideograph>) 22488 0x9C84 鲄 (<CJK Ideograph>) 22489 0x9C89 鲉 (<CJK Ideograph>) 22490 0x9C8A 鲊 (<CJK Ideograph>) 22491 0x9C8C 鲌 (<CJK Ideograph>) 22492 0x9C8F 鲏 (<CJK Ideograph>) 22493 0x9C93 鲓 (<CJK Ideograph>) 22494 0x9C96 鲖 (<CJK Ideograph>) 22495 0x9C97 鲗 (<CJK Ideograph>) 22496 0x9C98 鲘 (<CJK Ideograph>) 22497 0x9C99 鲙 (<CJK Ideograph>) 22498 0x9C9D 鲝 (<CJK Ideograph>) 22499 0x9CAA 鲪 (<CJK Ideograph>) 22500 0x9CAC 鲬 (<CJK Ideograph>) 22501 0x9CAF 鲯 (<CJK Ideograph>) 22502 0x9CB9 鲹 (<CJK Ideograph>) 22503 0x9CBE 鲾 (<CJK Ideograph>) 22504 0x9CBF 鲿 (<CJK Ideograph>) 22505 0x9CC0 鳀 (<CJK Ideograph>) 22506 0x9CC1 鳁 (<CJK Ideograph>) 22507 0x9CC2 鳂 (<CJK Ideograph>) 22508 0x9CC8 鳈 (<CJK Ideograph>) 22509 0x9CC9 鳉 (<CJK Ideograph>) 22510 0x9CD1 鳑 (<CJK Ideograph>) 22511 0x9CD2 鳒 (<CJK Ideograph>) 22512 0x9CDA 鳚 (<CJK Ideograph>) 22513 0x9CDB 鳛 (<CJK Ideograph>) 22514 0x9CE0 鳠 (<CJK Ideograph>) 22515 0x9CE1 鳡 (<CJK Ideograph>) 22516 0x9CCC 鳌 (<CJK Ideograph>) 22517 0x9CCD 鳍 (<CJK Ideograph>) 22518 0x9CCE 鳎 (<CJK Ideograph>) 22519 0x9CCF 鳏 (<CJK Ideograph>) 22520 0x9CD0 鳐 (<CJK Ideograph>) 22521 0x9CD3 鳓 (<CJK Ideograph>) 22522 0x9CD4 鳔 (<CJK Ideograph>) 22523 0x9CD5 鳕 (<CJK Ideograph>) 22524 0x9CD7 鳗 (<CJK Ideograph>) 22525 0x9CD8 鳘 (<CJK Ideograph>) 22526 0x9CD9 鳙 (<CJK Ideograph>) 22527 0x9CDC 鳜 (<CJK Ideograph>) 22528 0x9CDD 鳝 (<CJK Ideograph>) 22529 0x9CDF 鳟 (<CJK Ideograph>) 22530 0x9CE2 鳢 (<CJK Ideograph>) 22531 0x977C 靼 (<CJK Ideograph>) 22532 0x9785 鞅 (<CJK Ideograph>) 22533 0x9791 鞑 (<CJK Ideograph>) 22534 0x9792 鞒 (<CJK Ideograph>) 22535 0x9794 鞔 (<CJK Ideograph>) 22536 0x97AF 鞯 (<CJK Ideograph>) 22537 0x97AB 鞫 (<CJK Ideograph>) 22538 0x97A3 鞣 (<CJK Ideograph>) 22539 0x97B2 鞲 (<CJK Ideograph>) 22540 0x97B4 鞴 (<CJK Ideograph>) 22541 0x9AB1 骱 (<CJK Ideograph>) 22542 0x9AB0 骰 (<CJK Ideograph>) 22543 0x9AB7 骷 (<CJK Ideograph>) 22544 0x9E58 鹘 (<CJK Ideograph>) 22545 0x9AB6 骶 (<CJK Ideograph>) 22546 0x9ABA 骺 (<CJK Ideograph>) 22547 0x9ABC 骼 (<CJK Ideograph>) 22548 0x9AC1 髁 (<CJK Ideograph>) 22549 0x9AC0 髀 (<CJK Ideograph>) 22550 0x9AC5 髅 (<CJK Ideograph>) 22551 0x9AC2 髂 (<CJK Ideograph>) 22552 0x9ACB 髋 (<CJK Ideograph>) 22553 0x9ACC 髌 (<CJK Ideograph>) 22554 0x9AD1 髑 (<CJK Ideograph>) 22555 0x9B45 魅 (<CJK Ideograph>) 22556 0x9B43 魃 (<CJK Ideograph>) 22557 0x9B47 魇 (<CJK Ideograph>) 22558 0x9B49 魉 (<CJK Ideograph>) 22559 0x9B48 魈 (<CJK Ideograph>) 22560 0x9B4D 魍 (<CJK Ideograph>) 22561 0x9B51 魑 (<CJK Ideograph>) 22562 0x98E8 飨 (<CJK Ideograph>) 22563 0x990D 餍 (<CJK Ideograph>) 22564 0x992E 餮 (<CJK Ideograph>) 22565 0x9955 饕 (<CJK Ideograph>) 22566 0x9954 饔 (<CJK Ideograph>) 22567 0x9ADF 髟 (<CJK Ideograph>) 22568 0x9AE1 髡 (<CJK Ideograph>) 22569 0x9AE6 髦 (<CJK Ideograph>) 22570 0x9AEF 髯 (<CJK Ideograph>) 22571 0x9AEB 髫 (<CJK Ideograph>) 22572 0x9AFB 髻 (<CJK Ideograph>) 22573 0x9AED 髭 (<CJK Ideograph>) 22574 0x9AF9 髹 (<CJK Ideograph>) 22575 0x9B08 鬈 (<CJK Ideograph>) 22576 0x9B0F 鬏 (<CJK Ideograph>) 22577 0x9B13 鬓 (<CJK Ideograph>) 22578 0x9B1F 鬟 (<CJK Ideograph>) 22579 0x9B23 鬣 (<CJK Ideograph>) 22580 0x9EBD 麽 (<CJK Ideograph>) 22581 0x9EBE 麾 (<CJK Ideograph>) 22582 0x7E3B 縻 (<CJK Ideograph>) 22583 0x9E82 麂 (<CJK Ideograph>) 22584 0x9E87 麇 (<CJK Ideograph>) 22585 0x9E88 麈 (<CJK Ideograph>) 22586 0x9E8B 麋 (<CJK Ideograph>) 22587 0x9E92 麒 (<CJK Ideograph>) 22588 0x93D6 鏖 (<CJK Ideograph>) 22589 0x9E9D 麝 (<CJK Ideograph>) 22590 0x9E9F 麟 (<CJK Ideograph>) 22591 0x9EDB 黛 (<CJK Ideograph>) 22592 0x9EDC 黜 (<CJK Ideograph>) 22593 0x9EDD 黝 (<CJK Ideograph>) 22594 0x9EE0 黠 (<CJK Ideograph>) 22595 0x9EDF 黟 (<CJK Ideograph>) 22596 0x9EE2 黢 (<CJK Ideograph>) 22597 0x9EE9 黩 (<CJK Ideograph>) 22598 0x9EE7 黧 (<CJK Ideograph>) 22599 0x9EE5 黥 (<CJK Ideograph>) 22600 0x9EEA 黪 (<CJK Ideograph>) 22601 0x9EEF 黯 (<CJK Ideograph>) 22602 0x9F22 鼢 (<CJK Ideograph>) 22603 0x9F2C 鼬 (<CJK Ideograph>) 22604 0x9F2F 鼯 (<CJK Ideograph>) 22605 0x9F39 鼹 (<CJK Ideograph>) 22606 0x9F37 鼷 (<CJK Ideograph>) 22607 0x9F3D 鼽 (<CJK Ideograph>) 22608 0x9F3E 鼾 (<CJK Ideograph>) 22609 0x9F44 齄 (<CJK Ideograph>) 22610 0x9CE3 鳣 (<CJK Ideograph>) 22611 0x9CE4 鳤 (<CJK Ideograph>) 22612 0x9CE5 鳥 (<CJK Ideograph>) 22613 0x9CE6 鳦 (<CJK Ideograph>) 22614 0x9CE7 鳧 (<CJK Ideograph>) 22615 0x9CE8 鳨 (<CJK Ideograph>) 22616 0x9CE9 鳩 (<CJK Ideograph>) 22617 0x9CEA 鳪 (<CJK Ideograph>) 22618 0x9CEB 鳫 (<CJK Ideograph>) 22619 0x9CEC 鳬 (<CJK Ideograph>) 22620 0x9CED 鳭 (<CJK Ideograph>) 22621 0x9CEE 鳮 (<CJK Ideograph>) 22622 0x9CEF 鳯 (<CJK Ideograph>) 22623 0x9CF0 鳰 (<CJK Ideograph>) 22624 0x9CF1 鳱 (<CJK Ideograph>) 22625 0x9CF2 鳲 (<CJK Ideograph>) 22626 0x9CF3 鳳 (<CJK Ideograph>) 22627 0x9CF4 鳴 (<CJK Ideograph>) 22628 0x9CF5 鳵 (<CJK Ideograph>) 22629 0x9CF6 鳶 (<CJK Ideograph>) 22630 0x9CF7 鳷 (<CJK Ideograph>) 22631 0x9CF8 鳸 (<CJK Ideograph>) 22632 0x9CF9 鳹 (<CJK Ideograph>) 22633 0x9CFA 鳺 (<CJK Ideograph>) 22634 0x9CFB 鳻 (<CJK Ideograph>) 22635 0x9CFC 鳼 (<CJK Ideograph>) 22636 0x9CFD 鳽 (<CJK Ideograph>) 22637 0x9CFE 鳾 (<CJK Ideograph>) 22638 0x9CFF 鳿 (<CJK Ideograph>) 22639 0x9D00 鴀 (<CJK Ideograph>) 22640 0x9D01 鴁 (<CJK Ideograph>) 22641 0x9D02 鴂 (<CJK Ideograph>) 22642 0x9D03 鴃 (<CJK Ideograph>) 22643 0x9D04 鴄 (<CJK Ideograph>) 22644 0x9D05 鴅 (<CJK Ideograph>) 22645 0x9D06 鴆 (<CJK Ideograph>) 22646 0x9D07 鴇 (<CJK Ideograph>) 22647 0x9D08 鴈 (<CJK Ideograph>) 22648 0x9D09 鴉 (<CJK Ideograph>) 22649 0x9D0A 鴊 (<CJK Ideograph>) 22650 0x9D0B 鴋 (<CJK Ideograph>) 22651 0x9D0C 鴌 (<CJK Ideograph>) 22652 0x9D0D 鴍 (<CJK Ideograph>) 22653 0x9D0E 鴎 (<CJK Ideograph>) 22654 0x9D0F 鴏 (<CJK Ideograph>) 22655 0x9D10 鴐 (<CJK Ideograph>) 22656 0x9D11 鴑 (<CJK Ideograph>) 22657 0x9D12 鴒 (<CJK Ideograph>) 22658 0x9D13 鴓 (<CJK Ideograph>) 22659 0x9D14 鴔 (<CJK Ideograph>) 22660 0x9D15 鴕 (<CJK Ideograph>) 22661 0x9D16 鴖 (<CJK Ideograph>) 22662 0x9D17 鴗 (<CJK Ideograph>) 22663 0x9D18 鴘 (<CJK Ideograph>) 22664 0x9D19 鴙 (<CJK Ideograph>) 22665 0x9D1A 鴚 (<CJK Ideograph>) 22666 0x9D1B 鴛 (<CJK Ideograph>) 22667 0x9D1C 鴜 (<CJK Ideograph>) 22668 0x9D1D 鴝 (<CJK Ideograph>) 22669 0x9D1E 鴞 (<CJK Ideograph>) 22670 0x9D1F 鴟 (<CJK Ideograph>) 22671 0x9D20 鴠 (<CJK Ideograph>) 22672 0x9D21 鴡 (<CJK Ideograph>) 22673 0x9D22 鴢 (<CJK Ideograph>) 22674 0x9D23 鴣 (<CJK Ideograph>) 22675 0x9D24 鴤 (<CJK Ideograph>) 22676 0x9D25 鴥 (<CJK Ideograph>) 22677 0x9D26 鴦 (<CJK Ideograph>) 22678 0x9D27 鴧 (<CJK Ideograph>) 22679 0x9D28 鴨 (<CJK Ideograph>) 22680 0x9D29 鴩 (<CJK Ideograph>) 22681 0x9D2A 鴪 (<CJK Ideograph>) 22682 0x9D2B 鴫 (<CJK Ideograph>) 22683 0x9D2C 鴬 (<CJK Ideograph>) 22684 0x9D2D 鴭 (<CJK Ideograph>) 22685 0x9D2E 鴮 (<CJK Ideograph>) 22686 0x9D2F 鴯 (<CJK Ideograph>) 22687 0x9D30 鴰 (<CJK Ideograph>) 22688 0x9D31 鴱 (<CJK Ideograph>) 22689 0x9D32 鴲 (<CJK Ideograph>) 22690 0x9D33 鴳 (<CJK Ideograph>) 22691 0x9D34 鴴 (<CJK Ideograph>) 22692 0x9D35 鴵 (<CJK Ideograph>) 22693 0x9D36 鴶 (<CJK Ideograph>) 22694 0x9D37 鴷 (<CJK Ideograph>) 22695 0x9D38 鴸 (<CJK Ideograph>) 22696 0x9D39 鴹 (<CJK Ideograph>) 22697 0x9D3A 鴺 (<CJK Ideograph>) 22698 0x9D3B 鴻 (<CJK Ideograph>) 22699 0x9D3C 鴼 (<CJK Ideograph>) 22700 0x9D3D 鴽 (<CJK Ideograph>) 22701 0x9D3E 鴾 (<CJK Ideograph>) 22702 0x9D3F 鴿 (<CJK Ideograph>) 22703 0x9D40 鵀 (<CJK Ideograph>) 22704 0x9D41 鵁 (<CJK Ideograph>) 22705 0x9D42 鵂 (<CJK Ideograph>) 22706 0xE234  (<Private Use>) 22707 0xE235  (<Private Use>) 22708 0xE236  (<Private Use>) 22709 0xE237  (<Private Use>) 22710 0xE238  (<Private Use>) 22711 0xE239  (<Private Use>) 22712 0xE23A  (<Private Use>) 22713 0xE23B  (<Private Use>) 22714 0xE23C  (<Private Use>) 22715 0xE23D  (<Private Use>) 22716 0xE23E  (<Private Use>) 22717 0xE23F  (<Private Use>) 22718 0xE240  (<Private Use>) 22719 0xE241  (<Private Use>) 22720 0xE242  (<Private Use>) 22721 0xE243  (<Private Use>) 22722 0xE244  (<Private Use>) 22723 0xE245  (<Private Use>) 22724 0xE246  (<Private Use>) 22725 0xE247  (<Private Use>) 22726 0xE248  (<Private Use>) 22727 0xE249  (<Private Use>) 22728 0xE24A  (<Private Use>) 22729 0xE24B  (<Private Use>) 22730 0xE24C  (<Private Use>) 22731 0xE24D  (<Private Use>) 22732 0xE24E  (<Private Use>) 22733 0xE24F  (<Private Use>) 22734 0xE250  (<Private Use>) 22735 0xE251  (<Private Use>) 22736 0xE252  (<Private Use>) 22737 0xE253  (<Private Use>) 22738 0xE254  (<Private Use>) 22739 0xE255  (<Private Use>) 22740 0xE256  (<Private Use>) 22741 0xE257  (<Private Use>) 22742 0xE258  (<Private Use>) 22743 0xE259  (<Private Use>) 22744 0xE25A  (<Private Use>) 22745 0xE25B  (<Private Use>) 22746 0xE25C  (<Private Use>) 22747 0xE25D  (<Private Use>) 22748 0xE25E  (<Private Use>) 22749 0xE25F  (<Private Use>) 22750 0xE260  (<Private Use>) 22751 0xE261  (<Private Use>) 22752 0xE262  (<Private Use>) 22753 0xE263  (<Private Use>) 22754 0xE264  (<Private Use>) 22755 0xE265  (<Private Use>) 22756 0xE266  (<Private Use>) 22757 0xE267  (<Private Use>) 22758 0xE268  (<Private Use>) 22759 0xE269  (<Private Use>) 22760 0xE26A  (<Private Use>) 22761 0xE26B  (<Private Use>) 22762 0xE26C  (<Private Use>) 22763 0xE26D  (<Private Use>) 22764 0xE26E  (<Private Use>) 22765 0xE26F  (<Private Use>) 22766 0xE270  (<Private Use>) 22767 0xE271  (<Private Use>) 22768 0xE272  (<Private Use>) 22769 0xE273  (<Private Use>) 22770 0xE274  (<Private Use>) 22771 0xE275  (<Private Use>) 22772 0xE276  (<Private Use>) 22773 0xE277  (<Private Use>) 22774 0xE278  (<Private Use>) 22775 0xE279  (<Private Use>) 22776 0xE27A  (<Private Use>) 22777 0xE27B  (<Private Use>) 22778 0xE27C  (<Private Use>) 22779 0xE27D  (<Private Use>) 22780 0xE27E  (<Private Use>) 22781 0xE27F  (<Private Use>) 22782 0xE280  (<Private Use>) 22783 0xE281  (<Private Use>) 22784 0xE282  (<Private Use>) 22785 0xE283  (<Private Use>) 22786 0xE284  (<Private Use>) 22787 0xE285  (<Private Use>) 22788 0xE286  (<Private Use>) 22789 0xE287  (<Private Use>) 22790 0xE288  (<Private Use>) 22791 0xE289  (<Private Use>) 22792 0xE28A  (<Private Use>) 22793 0xE28B  (<Private Use>) 22794 0xE28C  (<Private Use>) 22795 0xE28D  (<Private Use>) 22796 0xE28E  (<Private Use>) 22797 0xE28F  (<Private Use>) 22798 0xE290  (<Private Use>) 22799 0xE291  (<Private Use>) 22800 0x9D43 鵃 (<CJK Ideograph>) 22801 0x9D44 鵄 (<CJK Ideograph>) 22802 0x9D45 鵅 (<CJK Ideograph>) 22803 0x9D46 鵆 (<CJK Ideograph>) 22804 0x9D47 鵇 (<CJK Ideograph>) 22805 0x9D48 鵈 (<CJK Ideograph>) 22806 0x9D49 鵉 (<CJK Ideograph>) 22807 0x9D4A 鵊 (<CJK Ideograph>) 22808 0x9D4B 鵋 (<CJK Ideograph>) 22809 0x9D4C 鵌 (<CJK Ideograph>) 22810 0x9D4D 鵍 (<CJK Ideograph>) 22811 0x9D4E 鵎 (<CJK Ideograph>) 22812 0x9D4F 鵏 (<CJK Ideograph>) 22813 0x9D50 鵐 (<CJK Ideograph>) 22814 0x9D51 鵑 (<CJK Ideograph>) 22815 0x9D52 鵒 (<CJK Ideograph>) 22816 0x9D53 鵓 (<CJK Ideograph>) 22817 0x9D54 鵔 (<CJK Ideograph>) 22818 0x9D55 鵕 (<CJK Ideograph>) 22819 0x9D56 鵖 (<CJK Ideograph>) 22820 0x9D57 鵗 (<CJK Ideograph>) 22821 0x9D58 鵘 (<CJK Ideograph>) 22822 0x9D59 鵙 (<CJK Ideograph>) 22823 0x9D5A 鵚 (<CJK Ideograph>) 22824 0x9D5B 鵛 (<CJK Ideograph>) 22825 0x9D5C 鵜 (<CJK Ideograph>) 22826 0x9D5D 鵝 (<CJK Ideograph>) 22827 0x9D5E 鵞 (<CJK Ideograph>) 22828 0x9D5F 鵟 (<CJK Ideograph>) 22829 0x9D60 鵠 (<CJK Ideograph>) 22830 0x9D61 鵡 (<CJK Ideograph>) 22831 0x9D62 鵢 (<CJK Ideograph>) 22832 0x9D63 鵣 (<CJK Ideograph>) 22833 0x9D64 鵤 (<CJK Ideograph>) 22834 0x9D65 鵥 (<CJK Ideograph>) 22835 0x9D66 鵦 (<CJK Ideograph>) 22836 0x9D67 鵧 (<CJK Ideograph>) 22837 0x9D68 鵨 (<CJK Ideograph>) 22838 0x9D69 鵩 (<CJK Ideograph>) 22839 0x9D6A 鵪 (<CJK Ideograph>) 22840 0x9D6B 鵫 (<CJK Ideograph>) 22841 0x9D6C 鵬 (<CJK Ideograph>) 22842 0x9D6D 鵭 (<CJK Ideograph>) 22843 0x9D6E 鵮 (<CJK Ideograph>) 22844 0x9D6F 鵯 (<CJK Ideograph>) 22845 0x9D70 鵰 (<CJK Ideograph>) 22846 0x9D71 鵱 (<CJK Ideograph>) 22847 0x9D72 鵲 (<CJK Ideograph>) 22848 0x9D73 鵳 (<CJK Ideograph>) 22849 0x9D74 鵴 (<CJK Ideograph>) 22850 0x9D75 鵵 (<CJK Ideograph>) 22851 0x9D76 鵶 (<CJK Ideograph>) 22852 0x9D77 鵷 (<CJK Ideograph>) 22853 0x9D78 鵸 (<CJK Ideograph>) 22854 0x9D79 鵹 (<CJK Ideograph>) 22855 0x9D7A 鵺 (<CJK Ideograph>) 22856 0x9D7B 鵻 (<CJK Ideograph>) 22857 0x9D7C 鵼 (<CJK Ideograph>) 22858 0x9D7D 鵽 (<CJK Ideograph>) 22859 0x9D7E 鵾 (<CJK Ideograph>) 22860 0x9D7F 鵿 (<CJK Ideograph>) 22861 0x9D80 鶀 (<CJK Ideograph>) 22862 0x9D81 鶁 (<CJK Ideograph>) 22863 0x9D82 鶂 (<CJK Ideograph>) 22864 0x9D83 鶃 (<CJK Ideograph>) 22865 0x9D84 鶄 (<CJK Ideograph>) 22866 0x9D85 鶅 (<CJK Ideograph>) 22867 0x9D86 鶆 (<CJK Ideograph>) 22868 0x9D87 鶇 (<CJK Ideograph>) 22869 0x9D88 鶈 (<CJK Ideograph>) 22870 0x9D89 鶉 (<CJK Ideograph>) 22871 0x9D8A 鶊 (<CJK Ideograph>) 22872 0x9D8B 鶋 (<CJK Ideograph>) 22873 0x9D8C 鶌 (<CJK Ideograph>) 22874 0x9D8D 鶍 (<CJK Ideograph>) 22875 0x9D8E 鶎 (<CJK Ideograph>) 22876 0x9D8F 鶏 (<CJK Ideograph>) 22877 0x9D90 鶐 (<CJK Ideograph>) 22878 0x9D91 鶑 (<CJK Ideograph>) 22879 0x9D92 鶒 (<CJK Ideograph>) 22880 0x9D93 鶓 (<CJK Ideograph>) 22881 0x9D94 鶔 (<CJK Ideograph>) 22882 0x9D95 鶕 (<CJK Ideograph>) 22883 0x9D96 鶖 (<CJK Ideograph>) 22884 0x9D97 鶗 (<CJK Ideograph>) 22885 0x9D98 鶘 (<CJK Ideograph>) 22886 0x9D99 鶙 (<CJK Ideograph>) 22887 0x9D9A 鶚 (<CJK Ideograph>) 22888 0x9D9B 鶛 (<CJK Ideograph>) 22889 0x9D9C 鶜 (<CJK Ideograph>) 22890 0x9D9D 鶝 (<CJK Ideograph>) 22891 0x9D9E 鶞 (<CJK Ideograph>) 22892 0x9D9F 鶟 (<CJK Ideograph>) 22893 0x9DA0 鶠 (<CJK Ideograph>) 22894 0x9DA1 鶡 (<CJK Ideograph>) 22895 0x9DA2 鶢 (<CJK Ideograph>) 22896 0xE292  (<Private Use>) 22897 0xE293  (<Private Use>) 22898 0xE294  (<Private Use>) 22899 0xE295  (<Private Use>) 22900 0xE296  (<Private Use>) 22901 0xE297  (<Private Use>) 22902 0xE298  (<Private Use>) 22903 0xE299  (<Private Use>) 22904 0xE29A  (<Private Use>) 22905 0xE29B  (<Private Use>) 22906 0xE29C  (<Private Use>) 22907 0xE29D  (<Private Use>) 22908 0xE29E  (<Private Use>) 22909 0xE29F  (<Private Use>) 22910 0xE2A0  (<Private Use>) 22911 0xE2A1  (<Private Use>) 22912 0xE2A2  (<Private Use>) 22913 0xE2A3  (<Private Use>) 22914 0xE2A4  (<Private Use>) 22915 0xE2A5  (<Private Use>) 22916 0xE2A6  (<Private Use>) 22917 0xE2A7  (<Private Use>) 22918 0xE2A8  (<Private Use>) 22919 0xE2A9  (<Private Use>) 22920 0xE2AA  (<Private Use>) 22921 0xE2AB  (<Private Use>) 22922 0xE2AC  (<Private Use>) 22923 0xE2AD  (<Private Use>) 22924 0xE2AE  (<Private Use>) 22925 0xE2AF  (<Private Use>) 22926 0xE2B0  (<Private Use>) 22927 0xE2B1  (<Private Use>) 22928 0xE2B2  (<Private Use>) 22929 0xE2B3  (<Private Use>) 22930 0xE2B4  (<Private Use>) 22931 0xE2B5  (<Private Use>) 22932 0xE2B6  (<Private Use>) 22933 0xE2B7  (<Private Use>) 22934 0xE2B8  (<Private Use>) 22935 0xE2B9  (<Private Use>) 22936 0xE2BA  (<Private Use>) 22937 0xE2BB  (<Private Use>) 22938 0xE2BC  (<Private Use>) 22939 0xE2BD  (<Private Use>) 22940 0xE2BE  (<Private Use>) 22941 0xE2BF  (<Private Use>) 22942 0xE2C0  (<Private Use>) 22943 0xE2C1  (<Private Use>) 22944 0xE2C2  (<Private Use>) 22945 0xE2C3  (<Private Use>) 22946 0xE2C4  (<Private Use>) 22947 0xE2C5  (<Private Use>) 22948 0xE2C6  (<Private Use>) 22949 0xE2C7  (<Private Use>) 22950 0xE2C8  (<Private Use>) 22951 0xE2C9  (<Private Use>) 22952 0xE2CA  (<Private Use>) 22953 0xE2CB  (<Private Use>) 22954 0xE2CC  (<Private Use>) 22955 0xE2CD  (<Private Use>) 22956 0xE2CE  (<Private Use>) 22957 0xE2CF  (<Private Use>) 22958 0xE2D0  (<Private Use>) 22959 0xE2D1  (<Private Use>) 22960 0xE2D2  (<Private Use>) 22961 0xE2D3  (<Private Use>) 22962 0xE2D4  (<Private Use>) 22963 0xE2D5  (<Private Use>) 22964 0xE2D6  (<Private Use>) 22965 0xE2D7  (<Private Use>) 22966 0xE2D8  (<Private Use>) 22967 0xE2D9  (<Private Use>) 22968 0xE2DA  (<Private Use>) 22969 0xE2DB  (<Private Use>) 22970 0xE2DC  (<Private Use>) 22971 0xE2DD  (<Private Use>) 22972 0xE2DE  (<Private Use>) 22973 0xE2DF  (<Private Use>) 22974 0xE2E0  (<Private Use>) 22975 0xE2E1  (<Private Use>) 22976 0xE2E2  (<Private Use>) 22977 0xE2E3  (<Private Use>) 22978 0xE2E4  (<Private Use>) 22979 0xE2E5  (<Private Use>) 22980 0xE2E6  (<Private Use>) 22981 0xE2E7  (<Private Use>) 22982 0xE2E8  (<Private Use>) 22983 0xE2E9  (<Private Use>) 22984 0xE2EA  (<Private Use>) 22985 0xE2EB  (<Private Use>) 22986 0xE2EC  (<Private Use>) 22987 0xE2ED  (<Private Use>) 22988 0xE2EE  (<Private Use>) 22989 0xE2EF  (<Private Use>) 22990 0x9DA3 鶣 (<CJK Ideograph>) 22991 0x9DA4 鶤 (<CJK Ideograph>) 22992 0x9DA5 鶥 (<CJK Ideograph>) 22993 0x9DA6 鶦 (<CJK Ideograph>) 22994 0x9DA7 鶧 (<CJK Ideograph>) 22995 0x9DA8 鶨 (<CJK Ideograph>) 22996 0x9DA9 鶩 (<CJK Ideograph>) 22997 0x9DAA 鶪 (<CJK Ideograph>) 22998 0x9DAB 鶫 (<CJK Ideograph>) 22999 0x9DAC 鶬 (<CJK Ideograph>) 23000 0x9DAD 鶭 (<CJK Ideograph>) 23001 0x9DAE 鶮 (<CJK Ideograph>) 23002 0x9DAF 鶯 (<CJK Ideograph>) 23003 0x9DB0 鶰 (<CJK Ideograph>) 23004 0x9DB1 鶱 (<CJK Ideograph>) 23005 0x9DB2 鶲 (<CJK Ideograph>) 23006 0x9DB3 鶳 (<CJK Ideograph>) 23007 0x9DB4 鶴 (<CJK Ideograph>) 23008 0x9DB5 鶵 (<CJK Ideograph>) 23009 0x9DB6 鶶 (<CJK Ideograph>) 23010 0x9DB7 鶷 (<CJK Ideograph>) 23011 0x9DB8 鶸 (<CJK Ideograph>) 23012 0x9DB9 鶹 (<CJK Ideograph>) 23013 0x9DBA 鶺 (<CJK Ideograph>) 23014 0x9DBB 鶻 (<CJK Ideograph>) 23015 0x9DBC 鶼 (<CJK Ideograph>) 23016 0x9DBD 鶽 (<CJK Ideograph>) 23017 0x9DBE 鶾 (<CJK Ideograph>) 23018 0x9DBF 鶿 (<CJK Ideograph>) 23019 0x9DC0 鷀 (<CJK Ideograph>) 23020 0x9DC1 鷁 (<CJK Ideograph>) 23021 0x9DC2 鷂 (<CJK Ideograph>) 23022 0x9DC3 鷃 (<CJK Ideograph>) 23023 0x9DC4 鷄 (<CJK Ideograph>) 23024 0x9DC5 鷅 (<CJK Ideograph>) 23025 0x9DC6 鷆 (<CJK Ideograph>) 23026 0x9DC7 鷇 (<CJK Ideograph>) 23027 0x9DC8 鷈 (<CJK Ideograph>) 23028 0x9DC9 鷉 (<CJK Ideograph>) 23029 0x9DCA 鷊 (<CJK Ideograph>) 23030 0x9DCB 鷋 (<CJK Ideograph>) 23031 0x9DCC 鷌 (<CJK Ideograph>) 23032 0x9DCD 鷍 (<CJK Ideograph>) 23033 0x9DCE 鷎 (<CJK Ideograph>) 23034 0x9DCF 鷏 (<CJK Ideograph>) 23035 0x9DD0 鷐 (<CJK Ideograph>) 23036 0x9DD1 鷑 (<CJK Ideograph>) 23037 0x9DD2 鷒 (<CJK Ideograph>) 23038 0x9DD3 鷓 (<CJK Ideograph>) 23039 0x9DD4 鷔 (<CJK Ideograph>) 23040 0x9DD5 鷕 (<CJK Ideograph>) 23041 0x9DD6 鷖 (<CJK Ideograph>) 23042 0x9DD7 鷗 (<CJK Ideograph>) 23043 0x9DD8 鷘 (<CJK Ideograph>) 23044 0x9DD9 鷙 (<CJK Ideograph>) 23045 0x9DDA 鷚 (<CJK Ideograph>) 23046 0x9DDB 鷛 (<CJK Ideograph>) 23047 0x9DDC 鷜 (<CJK Ideograph>) 23048 0x9DDD 鷝 (<CJK Ideograph>) 23049 0x9DDE 鷞 (<CJK Ideograph>) 23050 0x9DDF 鷟 (<CJK Ideograph>) 23051 0x9DE0 鷠 (<CJK Ideograph>) 23052 0x9DE1 鷡 (<CJK Ideograph>) 23053 0x9DE2 鷢 (<CJK Ideograph>) 23054 0x9DE3 鷣 (<CJK Ideograph>) 23055 0x9DE4 鷤 (<CJK Ideograph>) 23056 0x9DE5 鷥 (<CJK Ideograph>) 23057 0x9DE6 鷦 (<CJK Ideograph>) 23058 0x9DE7 鷧 (<CJK Ideograph>) 23059 0x9DE8 鷨 (<CJK Ideograph>) 23060 0x9DE9 鷩 (<CJK Ideograph>) 23061 0x9DEA 鷪 (<CJK Ideograph>) 23062 0x9DEB 鷫 (<CJK Ideograph>) 23063 0x9DEC 鷬 (<CJK Ideograph>) 23064 0x9DED 鷭 (<CJK Ideograph>) 23065 0x9DEE 鷮 (<CJK Ideograph>) 23066 0x9DEF 鷯 (<CJK Ideograph>) 23067 0x9DF0 鷰 (<CJK Ideograph>) 23068 0x9DF1 鷱 (<CJK Ideograph>) 23069 0x9DF2 鷲 (<CJK Ideograph>) 23070 0x9DF3 鷳 (<CJK Ideograph>) 23071 0x9DF4 鷴 (<CJK Ideograph>) 23072 0x9DF5 鷵 (<CJK Ideograph>) 23073 0x9DF6 鷶 (<CJK Ideograph>) 23074 0x9DF7 鷷 (<CJK Ideograph>) 23075 0x9DF8 鷸 (<CJK Ideograph>) 23076 0x9DF9 鷹 (<CJK Ideograph>) 23077 0x9DFA 鷺 (<CJK Ideograph>) 23078 0x9DFB 鷻 (<CJK Ideograph>) 23079 0x9DFC 鷼 (<CJK Ideograph>) 23080 0x9DFD 鷽 (<CJK Ideograph>) 23081 0x9DFE 鷾 (<CJK Ideograph>) 23082 0x9DFF 鷿 (<CJK Ideograph>) 23083 0x9E00 鸀 (<CJK Ideograph>) 23084 0x9E01 鸁 (<CJK Ideograph>) 23085 0x9E02 鸂 (<CJK Ideograph>) 23086 0xE2F0  (<Private Use>) 23087 0xE2F1  (<Private Use>) 23088 0xE2F2  (<Private Use>) 23089 0xE2F3  (<Private Use>) 23090 0xE2F4  (<Private Use>) 23091 0xE2F5  (<Private Use>) 23092 0xE2F6  (<Private Use>) 23093 0xE2F7  (<Private Use>) 23094 0xE2F8  (<Private Use>) 23095 0xE2F9  (<Private Use>) 23096 0xE2FA  (<Private Use>) 23097 0xE2FB  (<Private Use>) 23098 0xE2FC  (<Private Use>) 23099 0xE2FD  (<Private Use>) 23100 0xE2FE  (<Private Use>) 23101 0xE2FF  (<Private Use>) 23102 0xE300  (<Private Use>) 23103 0xE301  (<Private Use>) 23104 0xE302  (<Private Use>) 23105 0xE303  (<Private Use>) 23106 0xE304  (<Private Use>) 23107 0xE305  (<Private Use>) 23108 0xE306  (<Private Use>) 23109 0xE307  (<Private Use>) 23110 0xE308  (<Private Use>) 23111 0xE309  (<Private Use>) 23112 0xE30A  (<Private Use>) 23113 0xE30B  (<Private Use>) 23114 0xE30C  (<Private Use>) 23115 0xE30D  (<Private Use>) 23116 0xE30E  (<Private Use>) 23117 0xE30F  (<Private Use>) 23118 0xE310  (<Private Use>) 23119 0xE311  (<Private Use>) 23120 0xE312  (<Private Use>) 23121 0xE313  (<Private Use>) 23122 0xE314  (<Private Use>) 23123 0xE315  (<Private Use>) 23124 0xE316  (<Private Use>) 23125 0xE317  (<Private Use>) 23126 0xE318  (<Private Use>) 23127 0xE319  (<Private Use>) 23128 0xE31A  (<Private Use>) 23129 0xE31B  (<Private Use>) 23130 0xE31C  (<Private Use>) 23131 0xE31D  (<Private Use>) 23132 0xE31E  (<Private Use>) 23133 0xE31F  (<Private Use>) 23134 0xE320  (<Private Use>) 23135 0xE321  (<Private Use>) 23136 0xE322  (<Private Use>) 23137 0xE323  (<Private Use>) 23138 0xE324  (<Private Use>) 23139 0xE325  (<Private Use>) 23140 0xE326  (<Private Use>) 23141 0xE327  (<Private Use>) 23142 0xE328  (<Private Use>) 23143 0xE329  (<Private Use>) 23144 0xE32A  (<Private Use>) 23145 0xE32B  (<Private Use>) 23146 0xE32C  (<Private Use>) 23147 0xE32D  (<Private Use>) 23148 0xE32E  (<Private Use>) 23149 0xE32F  (<Private Use>) 23150 0xE330  (<Private Use>) 23151 0xE331  (<Private Use>) 23152 0xE332  (<Private Use>) 23153 0xE333  (<Private Use>) 23154 0xE334  (<Private Use>) 23155 0xE335  (<Private Use>) 23156 0xE336  (<Private Use>) 23157 0xE337  (<Private Use>) 23158 0xE338  (<Private Use>) 23159 0xE339  (<Private Use>) 23160 0xE33A  (<Private Use>) 23161 0xE33B  (<Private Use>) 23162 0xE33C  (<Private Use>) 23163 0xE33D  (<Private Use>) 23164 0xE33E  (<Private Use>) 23165 0xE33F  (<Private Use>) 23166 0xE340  (<Private Use>) 23167 0xE341  (<Private Use>) 23168 0xE342  (<Private Use>) 23169 0xE343  (<Private Use>) 23170 0xE344  (<Private Use>) 23171 0xE345  (<Private Use>) 23172 0xE346  (<Private Use>) 23173 0xE347  (<Private Use>) 23174 0xE348  (<Private Use>) 23175 0xE349  (<Private Use>) 23176 0xE34A  (<Private Use>) 23177 0xE34B  (<Private Use>) 23178 0xE34C  (<Private Use>) 23179 0xE34D  (<Private Use>) 23180 0x9E03 鸃 (<CJK Ideograph>) 23181 0x9E04 鸄 (<CJK Ideograph>) 23182 0x9E05 鸅 (<CJK Ideograph>) 23183 0x9E06 鸆 (<CJK Ideograph>) 23184 0x9E07 鸇 (<CJK Ideograph>) 23185 0x9E08 鸈 (<CJK Ideograph>) 23186 0x9E09 鸉 (<CJK Ideograph>) 23187 0x9E0A 鸊 (<CJK Ideograph>) 23188 0x9E0B 鸋 (<CJK Ideograph>) 23189 0x9E0C 鸌 (<CJK Ideograph>) 23190 0x9E0D 鸍 (<CJK Ideograph>) 23191 0x9E0E 鸎 (<CJK Ideograph>) 23192 0x9E0F 鸏 (<CJK Ideograph>) 23193 0x9E10 鸐 (<CJK Ideograph>) 23194 0x9E11 鸑 (<CJK Ideograph>) 23195 0x9E12 鸒 (<CJK Ideograph>) 23196 0x9E13 鸓 (<CJK Ideograph>) 23197 0x9E14 鸔 (<CJK Ideograph>) 23198 0x9E15 鸕 (<CJK Ideograph>) 23199 0x9E16 鸖 (<CJK Ideograph>) 23200 0x9E17 鸗 (<CJK Ideograph>) 23201 0x9E18 鸘 (<CJK Ideograph>) 23202 0x9E19 鸙 (<CJK Ideograph>) 23203 0x9E1A 鸚 (<CJK Ideograph>) 23204 0x9E1B 鸛 (<CJK Ideograph>) 23205 0x9E1C 鸜 (<CJK Ideograph>) 23206 0x9E1D 鸝 (<CJK Ideograph>) 23207 0x9E1E 鸞 (<CJK Ideograph>) 23208 0x9E24 鸤 (<CJK Ideograph>) 23209 0x9E27 鸧 (<CJK Ideograph>) 23210 0x9E2E 鸮 (<CJK Ideograph>) 23211 0x9E30 鸰 (<CJK Ideograph>) 23212 0x9E34 鸴 (<CJK Ideograph>) 23213 0x9E3B 鸻 (<CJK Ideograph>) 23214 0x9E3C 鸼 (<CJK Ideograph>) 23215 0x9E40 鹀 (<CJK Ideograph>) 23216 0x9E4D 鹍 (<CJK Ideograph>) 23217 0x9E50 鹐 (<CJK Ideograph>) 23218 0x9E52 鹒 (<CJK Ideograph>) 23219 0x9E53 鹓 (<CJK Ideograph>) 23220 0x9E54 鹔 (<CJK Ideograph>) 23221 0x9E56 鹖 (<CJK Ideograph>) 23222 0x9E59 鹙 (<CJK Ideograph>) 23223 0x9E5D 鹝 (<CJK Ideograph>) 23224 0x9E5F 鹟 (<CJK Ideograph>) 23225 0x9E60 鹠 (<CJK Ideograph>) 23226 0x9E61 鹡 (<CJK Ideograph>) 23227 0x9E62 鹢 (<CJK Ideograph>) 23228 0x9E65 鹥 (<CJK Ideograph>) 23229 0x9E6E 鹮 (<CJK Ideograph>) 23230 0x9E6F 鹯 (<CJK Ideograph>) 23231 0x9E72 鹲 (<CJK Ideograph>) 23232 0x9E74 鹴 (<CJK Ideograph>) 23233 0x9E75 鹵 (<CJK Ideograph>) 23234 0x9E76 鹶 (<CJK Ideograph>) 23235 0x9E77 鹷 (<CJK Ideograph>) 23236 0x9E78 鹸 (<CJK Ideograph>) 23237 0x9E79 鹹 (<CJK Ideograph>) 23238 0x9E7A 鹺 (<CJK Ideograph>) 23239 0x9E7B 鹻 (<CJK Ideograph>) 23240 0x9E7C 鹼 (<CJK Ideograph>) 23241 0x9E7D 鹽 (<CJK Ideograph>) 23242 0x9E80 麀 (<CJK Ideograph>) 23243 0x9E81 麁 (<CJK Ideograph>) 23244 0x9E83 麃 (<CJK Ideograph>) 23245 0x9E84 麄 (<CJK Ideograph>) 23246 0x9E85 麅 (<CJK Ideograph>) 23247 0x9E86 麆 (<CJK Ideograph>) 23248 0x9E89 麉 (<CJK Ideograph>) 23249 0x9E8A 麊 (<CJK Ideograph>) 23250 0x9E8C 麌 (<CJK Ideograph>) 23251 0x9E8D 麍 (<CJK Ideograph>) 23252 0x9E8E 麎 (<CJK Ideograph>) 23253 0x9E8F 麏 (<CJK Ideograph>) 23254 0x9E90 麐 (<CJK Ideograph>) 23255 0x9E91 麑 (<CJK Ideograph>) 23256 0x9E94 麔 (<CJK Ideograph>) 23257 0x9E95 麕 (<CJK Ideograph>) 23258 0x9E96 麖 (<CJK Ideograph>) 23259 0x9E97 麗 (<CJK Ideograph>) 23260 0x9E98 麘 (<CJK Ideograph>) 23261 0x9E99 麙 (<CJK Ideograph>) 23262 0x9E9A 麚 (<CJK Ideograph>) 23263 0x9E9B 麛 (<CJK Ideograph>) 23264 0x9E9C 麜 (<CJK Ideograph>) 23265 0x9E9E 麞 (<CJK Ideograph>) 23266 0x9EA0 麠 (<CJK Ideograph>) 23267 0x9EA1 麡 (<CJK Ideograph>) 23268 0x9EA2 麢 (<CJK Ideograph>) 23269 0x9EA3 麣 (<CJK Ideograph>) 23270 0x9EA4 麤 (<CJK Ideograph>) 23271 0x9EA5 麥 (<CJK Ideograph>) 23272 0x9EA7 麧 (<CJK Ideograph>) 23273 0x9EA8 麨 (<CJK Ideograph>) 23274 0x9EA9 麩 (<CJK Ideograph>) 23275 0x9EAA 麪 (<CJK Ideograph>) 23276 0xE34E  (<Private Use>) 23277 0xE34F  (<Private Use>) 23278 0xE350  (<Private Use>) 23279 0xE351  (<Private Use>) 23280 0xE352  (<Private Use>) 23281 0xE353  (<Private Use>) 23282 0xE354  (<Private Use>) 23283 0xE355  (<Private Use>) 23284 0xE356  (<Private Use>) 23285 0xE357  (<Private Use>) 23286 0xE358  (<Private Use>) 23287 0xE359  (<Private Use>) 23288 0xE35A  (<Private Use>) 23289 0xE35B  (<Private Use>) 23290 0xE35C  (<Private Use>) 23291 0xE35D  (<Private Use>) 23292 0xE35E  (<Private Use>) 23293 0xE35F  (<Private Use>) 23294 0xE360  (<Private Use>) 23295 0xE361  (<Private Use>) 23296 0xE362  (<Private Use>) 23297 0xE363  (<Private Use>) 23298 0xE364  (<Private Use>) 23299 0xE365  (<Private Use>) 23300 0xE366  (<Private Use>) 23301 0xE367  (<Private Use>) 23302 0xE368  (<Private Use>) 23303 0xE369  (<Private Use>) 23304 0xE36A  (<Private Use>) 23305 0xE36B  (<Private Use>) 23306 0xE36C  (<Private Use>) 23307 0xE36D  (<Private Use>) 23308 0xE36E  (<Private Use>) 23309 0xE36F  (<Private Use>) 23310 0xE370  (<Private Use>) 23311 0xE371  (<Private Use>) 23312 0xE372  (<Private Use>) 23313 0xE373  (<Private Use>) 23314 0xE374  (<Private Use>) 23315 0xE375  (<Private Use>) 23316 0xE376  (<Private Use>) 23317 0xE377  (<Private Use>) 23318 0xE378  (<Private Use>) 23319 0xE379  (<Private Use>) 23320 0xE37A  (<Private Use>) 23321 0xE37B  (<Private Use>) 23322 0xE37C  (<Private Use>) 23323 0xE37D  (<Private Use>) 23324 0xE37E  (<Private Use>) 23325 0xE37F  (<Private Use>) 23326 0xE380  (<Private Use>) 23327 0xE381  (<Private Use>) 23328 0xE382  (<Private Use>) 23329 0xE383  (<Private Use>) 23330 0xE384  (<Private Use>) 23331 0xE385  (<Private Use>) 23332 0xE386  (<Private Use>) 23333 0xE387  (<Private Use>) 23334 0xE388  (<Private Use>) 23335 0xE389  (<Private Use>) 23336 0xE38A  (<Private Use>) 23337 0xE38B  (<Private Use>) 23338 0xE38C  (<Private Use>) 23339 0xE38D  (<Private Use>) 23340 0xE38E  (<Private Use>) 23341 0xE38F  (<Private Use>) 23342 0xE390  (<Private Use>) 23343 0xE391  (<Private Use>) 23344 0xE392  (<Private Use>) 23345 0xE393  (<Private Use>) 23346 0xE394  (<Private Use>) 23347 0xE395  (<Private Use>) 23348 0xE396  (<Private Use>) 23349 0xE397  (<Private Use>) 23350 0xE398  (<Private Use>) 23351 0xE399  (<Private Use>) 23352 0xE39A  (<Private Use>) 23353 0xE39B  (<Private Use>) 23354 0xE39C  (<Private Use>) 23355 0xE39D  (<Private Use>) 23356 0xE39E  (<Private Use>) 23357 0xE39F  (<Private Use>) 23358 0xE3A0  (<Private Use>) 23359 0xE3A1  (<Private Use>) 23360 0xE3A2  (<Private Use>) 23361 0xE3A3  (<Private Use>) 23362 0xE3A4  (<Private Use>) 23363 0xE3A5  (<Private Use>) 23364 0xE3A6  (<Private Use>) 23365 0xE3A7  (<Private Use>) 23366 0xE3A8  (<Private Use>) 23367 0xE3A9  (<Private Use>) 23368 0xE3AA  (<Private Use>) 23369 0xE3AB  (<Private Use>) 23370 0x9EAB 麫 (<CJK Ideograph>) 23371 0x9EAC 麬 (<CJK Ideograph>) 23372 0x9EAD 麭 (<CJK Ideograph>) 23373 0x9EAE 麮 (<CJK Ideograph>) 23374 0x9EAF 麯 (<CJK Ideograph>) 23375 0x9EB0 麰 (<CJK Ideograph>) 23376 0x9EB1 麱 (<CJK Ideograph>) 23377 0x9EB2 麲 (<CJK Ideograph>) 23378 0x9EB3 麳 (<CJK Ideograph>) 23379 0x9EB5 麵 (<CJK Ideograph>) 23380 0x9EB6 麶 (<CJK Ideograph>) 23381 0x9EB7 麷 (<CJK Ideograph>) 23382 0x9EB9 麹 (<CJK Ideograph>) 23383 0x9EBA 麺 (<CJK Ideograph>) 23384 0x9EBC 麼 (<CJK Ideograph>) 23385 0x9EBF 麿 (<CJK Ideograph>) 23386 0x9EC0 黀 (<CJK Ideograph>) 23387 0x9EC1 黁 (<CJK Ideograph>) 23388 0x9EC2 黂 (<CJK Ideograph>) 23389 0x9EC3 黃 (<CJK Ideograph>) 23390 0x9EC5 黅 (<CJK Ideograph>) 23391 0x9EC6 黆 (<CJK Ideograph>) 23392 0x9EC7 黇 (<CJK Ideograph>) 23393 0x9EC8 黈 (<CJK Ideograph>) 23394 0x9ECA 黊 (<CJK Ideograph>) 23395 0x9ECB 黋 (<CJK Ideograph>) 23396 0x9ECC 黌 (<CJK Ideograph>) 23397 0x9ED0 黐 (<CJK Ideograph>) 23398 0x9ED2 黒 (<CJK Ideograph>) 23399 0x9ED3 黓 (<CJK Ideograph>) 23400 0x9ED5 黕 (<CJK Ideograph>) 23401 0x9ED6 黖 (<CJK Ideograph>) 23402 0x9ED7 黗 (<CJK Ideograph>) 23403 0x9ED9 黙 (<CJK Ideograph>) 23404 0x9EDA 黚 (<CJK Ideograph>) 23405 0x9EDE 點 (<CJK Ideograph>) 23406 0x9EE1 黡 (<CJK Ideograph>) 23407 0x9EE3 黣 (<CJK Ideograph>) 23408 0x9EE4 黤 (<CJK Ideograph>) 23409 0x9EE6 黦 (<CJK Ideograph>) 23410 0x9EE8 黨 (<CJK Ideograph>) 23411 0x9EEB 黫 (<CJK Ideograph>) 23412 0x9EEC 黬 (<CJK Ideograph>) 23413 0x9EED 黭 (<CJK Ideograph>) 23414 0x9EEE 黮 (<CJK Ideograph>) 23415 0x9EF0 黰 (<CJK Ideograph>) 23416 0x9EF1 黱 (<CJK Ideograph>) 23417 0x9EF2 黲 (<CJK Ideograph>) 23418 0x9EF3 黳 (<CJK Ideograph>) 23419 0x9EF4 黴 (<CJK Ideograph>) 23420 0x9EF5 黵 (<CJK Ideograph>) 23421 0x9EF6 黶 (<CJK Ideograph>) 23422 0x9EF7 黷 (<CJK Ideograph>) 23423 0x9EF8 黸 (<CJK Ideograph>) 23424 0x9EFA 黺 (<CJK Ideograph>) 23425 0x9EFD 黽 (<CJK Ideograph>) 23426 0x9EFF 黿 (<CJK Ideograph>) 23427 0x9F00 鼀 (<CJK Ideograph>) 23428 0x9F01 鼁 (<CJK Ideograph>) 23429 0x9F02 鼂 (<CJK Ideograph>) 23430 0x9F03 鼃 (<CJK Ideograph>) 23431 0x9F04 鼄 (<CJK Ideograph>) 23432 0x9F05 鼅 (<CJK Ideograph>) 23433 0x9F06 鼆 (<CJK Ideograph>) 23434 0x9F07 鼇 (<CJK Ideograph>) 23435 0x9F08 鼈 (<CJK Ideograph>) 23436 0x9F09 鼉 (<CJK Ideograph>) 23437 0x9F0A 鼊 (<CJK Ideograph>) 23438 0x9F0C 鼌 (<CJK Ideograph>) 23439 0x9F0F 鼏 (<CJK Ideograph>) 23440 0x9F11 鼑 (<CJK Ideograph>) 23441 0x9F12 鼒 (<CJK Ideograph>) 23442 0x9F14 鼔 (<CJK Ideograph>) 23443 0x9F15 鼕 (<CJK Ideograph>) 23444 0x9F16 鼖 (<CJK Ideograph>) 23445 0x9F18 鼘 (<CJK Ideograph>) 23446 0x9F1A 鼚 (<CJK Ideograph>) 23447 0x9F1B 鼛 (<CJK Ideograph>) 23448 0x9F1C 鼜 (<CJK Ideograph>) 23449 0x9F1D 鼝 (<CJK Ideograph>) 23450 0x9F1E 鼞 (<CJK Ideograph>) 23451 0x9F1F 鼟 (<CJK Ideograph>) 23452 0x9F21 鼡 (<CJK Ideograph>) 23453 0x9F23 鼣 (<CJK Ideograph>) 23454 0x9F24 鼤 (<CJK Ideograph>) 23455 0x9F25 鼥 (<CJK Ideograph>) 23456 0x9F26 鼦 (<CJK Ideograph>) 23457 0x9F27 鼧 (<CJK Ideograph>) 23458 0x9F28 鼨 (<CJK Ideograph>) 23459 0x9F29 鼩 (<CJK Ideograph>) 23460 0x9F2A 鼪 (<CJK Ideograph>) 23461 0x9F2B 鼫 (<CJK Ideograph>) 23462 0x9F2D 鼭 (<CJK Ideograph>) 23463 0x9F2E 鼮 (<CJK Ideograph>) 23464 0x9F30 鼰 (<CJK Ideograph>) 23465 0x9F31 鼱 (<CJK Ideograph>) 23466 0xE3AC  (<Private Use>) 23467 0xE3AD  (<Private Use>) 23468 0xE3AE  (<Private Use>) 23469 0xE3AF  (<Private Use>) 23470 0xE3B0  (<Private Use>) 23471 0xE3B1  (<Private Use>) 23472 0xE3B2  (<Private Use>) 23473 0xE3B3  (<Private Use>) 23474 0xE3B4  (<Private Use>) 23475 0xE3B5  (<Private Use>) 23476 0xE3B6  (<Private Use>) 23477 0xE3B7  (<Private Use>) 23478 0xE3B8  (<Private Use>) 23479 0xE3B9  (<Private Use>) 23480 0xE3BA  (<Private Use>) 23481 0xE3BB  (<Private Use>) 23482 0xE3BC  (<Private Use>) 23483 0xE3BD  (<Private Use>) 23484 0xE3BE  (<Private Use>) 23485 0xE3BF  (<Private Use>) 23486 0xE3C0  (<Private Use>) 23487 0xE3C1  (<Private Use>) 23488 0xE3C2  (<Private Use>) 23489 0xE3C3  (<Private Use>) 23490 0xE3C4  (<Private Use>) 23491 0xE3C5  (<Private Use>) 23492 0xE3C6  (<Private Use>) 23493 0xE3C7  (<Private Use>) 23494 0xE3C8  (<Private Use>) 23495 0xE3C9  (<Private Use>) 23496 0xE3CA  (<Private Use>) 23497 0xE3CB  (<Private Use>) 23498 0xE3CC  (<Private Use>) 23499 0xE3CD  (<Private Use>) 23500 0xE3CE  (<Private Use>) 23501 0xE3CF  (<Private Use>) 23502 0xE3D0  (<Private Use>) 23503 0xE3D1  (<Private Use>) 23504 0xE3D2  (<Private Use>) 23505 0xE3D3  (<Private Use>) 23506 0xE3D4  (<Private Use>) 23507 0xE3D5  (<Private Use>) 23508 0xE3D6  (<Private Use>) 23509 0xE3D7  (<Private Use>) 23510 0xE3D8  (<Private Use>) 23511 0xE3D9  (<Private Use>) 23512 0xE3DA  (<Private Use>) 23513 0xE3DB  (<Private Use>) 23514 0xE3DC  (<Private Use>) 23515 0xE3DD  (<Private Use>) 23516 0xE3DE  (<Private Use>) 23517 0xE3DF  (<Private Use>) 23518 0xE3E0  (<Private Use>) 23519 0xE3E1  (<Private Use>) 23520 0xE3E2  (<Private Use>) 23521 0xE3E3  (<Private Use>) 23522 0xE3E4  (<Private Use>) 23523 0xE3E5  (<Private Use>) 23524 0xE3E6  (<Private Use>) 23525 0xE3E7  (<Private Use>) 23526 0xE3E8  (<Private Use>) 23527 0xE3E9  (<Private Use>) 23528 0xE3EA  (<Private Use>) 23529 0xE3EB  (<Private Use>) 23530 0xE3EC  (<Private Use>) 23531 0xE3ED  (<Private Use>) 23532 0xE3EE  (<Private Use>) 23533 0xE3EF  (<Private Use>) 23534 0xE3F0  (<Private Use>) 23535 0xE3F1  (<Private Use>) 23536 0xE3F2  (<Private Use>) 23537 0xE3F3  (<Private Use>) 23538 0xE3F4  (<Private Use>) 23539 0xE3F5  (<Private Use>) 23540 0xE3F6  (<Private Use>) 23541 0xE3F7  (<Private Use>) 23542 0xE3F8  (<Private Use>) 23543 0xE3F9  (<Private Use>) 23544 0xE3FA  (<Private Use>) 23545 0xE3FB  (<Private Use>) 23546 0xE3FC  (<Private Use>) 23547 0xE3FD  (<Private Use>) 23548 0xE3FE  (<Private Use>) 23549 0xE3FF  (<Private Use>) 23550 0xE400  (<Private Use>) 23551 0xE401  (<Private Use>) 23552 0xE402  (<Private Use>) 23553 0xE403  (<Private Use>) 23554 0xE404  (<Private Use>) 23555 0xE405  (<Private Use>) 23556 0xE406  (<Private Use>) 23557 0xE407  (<Private Use>) 23558 0xE408  (<Private Use>) 23559 0xE409  (<Private Use>) 23560 0x9F32 鼲 (<CJK Ideograph>) 23561 0x9F33 鼳 (<CJK Ideograph>) 23562 0x9F34 鼴 (<CJK Ideograph>) 23563 0x9F35 鼵 (<CJK Ideograph>) 23564 0x9F36 鼶 (<CJK Ideograph>) 23565 0x9F38 鼸 (<CJK Ideograph>) 23566 0x9F3A 鼺 (<CJK Ideograph>) 23567 0x9F3C 鼼 (<CJK Ideograph>) 23568 0x9F3F 鼿 (<CJK Ideograph>) 23569 0x9F40 齀 (<CJK Ideograph>) 23570 0x9F41 齁 (<CJK Ideograph>) 23571 0x9F42 齂 (<CJK Ideograph>) 23572 0x9F43 齃 (<CJK Ideograph>) 23573 0x9F45 齅 (<CJK Ideograph>) 23574 0x9F46 齆 (<CJK Ideograph>) 23575 0x9F47 齇 (<CJK Ideograph>) 23576 0x9F48 齈 (<CJK Ideograph>) 23577 0x9F49 齉 (<CJK Ideograph>) 23578 0x9F4A 齊 (<CJK Ideograph>) 23579 0x9F4B 齋 (<CJK Ideograph>) 23580 0x9F4C 齌 (<CJK Ideograph>) 23581 0x9F4D 齍 (<CJK Ideograph>) 23582 0x9F4E 齎 (<CJK Ideograph>) 23583 0x9F4F 齏 (<CJK Ideograph>) 23584 0x9F52 齒 (<CJK Ideograph>) 23585 0x9F53 齓 (<CJK Ideograph>) 23586 0x9F54 齔 (<CJK Ideograph>) 23587 0x9F55 齕 (<CJK Ideograph>) 23588 0x9F56 齖 (<CJK Ideograph>) 23589 0x9F57 齗 (<CJK Ideograph>) 23590 0x9F58 齘 (<CJK Ideograph>) 23591 0x9F59 齙 (<CJK Ideograph>) 23592 0x9F5A 齚 (<CJK Ideograph>) 23593 0x9F5B 齛 (<CJK Ideograph>) 23594 0x9F5C 齜 (<CJK Ideograph>) 23595 0x9F5D 齝 (<CJK Ideograph>) 23596 0x9F5E 齞 (<CJK Ideograph>) 23597 0x9F5F 齟 (<CJK Ideograph>) 23598 0x9F60 齠 (<CJK Ideograph>) 23599 0x9F61 齡 (<CJK Ideograph>) 23600 0x9F62 齢 (<CJK Ideograph>) 23601 0x9F63 齣 (<CJK Ideograph>) 23602 0x9F64 齤 (<CJK Ideograph>) 23603 0x9F65 齥 (<CJK Ideograph>) 23604 0x9F66 齦 (<CJK Ideograph>) 23605 0x9F67 齧 (<CJK Ideograph>) 23606 0x9F68 齨 (<CJK Ideograph>) 23607 0x9F69 齩 (<CJK Ideograph>) 23608 0x9F6A 齪 (<CJK Ideograph>) 23609 0x9F6B 齫 (<CJK Ideograph>) 23610 0x9F6C 齬 (<CJK Ideograph>) 23611 0x9F6D 齭 (<CJK Ideograph>) 23612 0x9F6E 齮 (<CJK Ideograph>) 23613 0x9F6F 齯 (<CJK Ideograph>) 23614 0x9F70 齰 (<CJK Ideograph>) 23615 0x9F71 齱 (<CJK Ideograph>) 23616 0x9F72 齲 (<CJK Ideograph>) 23617 0x9F73 齳 (<CJK Ideograph>) 23618 0x9F74 齴 (<CJK Ideograph>) 23619 0x9F75 齵 (<CJK Ideograph>) 23620 0x9F76 齶 (<CJK Ideograph>) 23621 0x9F77 齷 (<CJK Ideograph>) 23622 0x9F78 齸 (<CJK Ideograph>) 23623 0x9F79 齹 (<CJK Ideograph>) 23624 0x9F7A 齺 (<CJK Ideograph>) 23625 0x9F7B 齻 (<CJK Ideograph>) 23626 0x9F7C 齼 (<CJK Ideograph>) 23627 0x9F7D 齽 (<CJK Ideograph>) 23628 0x9F7E 齾 (<CJK Ideograph>) 23629 0x9F81 龁 (<CJK Ideograph>) 23630 0x9F82 龂 (<CJK Ideograph>) 23631 0x9F8D 龍 (<CJK Ideograph>) 23632 0x9F8E 龎 (<CJK Ideograph>) 23633 0x9F8F 龏 (<CJK Ideograph>) 23634 0x9F90 龐 (<CJK Ideograph>) 23635 0x9F91 龑 (<CJK Ideograph>) 23636 0x9F92 龒 (<CJK Ideograph>) 23637 0x9F93 龓 (<CJK Ideograph>) 23638 0x9F94 龔 (<CJK Ideograph>) 23639 0x9F95 龕 (<CJK Ideograph>) 23640 0x9F96 龖 (<CJK Ideograph>) 23641 0x9F97 龗 (<CJK Ideograph>) 23642 0x9F98 龘 (<CJK Ideograph>) 23643 0x9F9C 龜 (<CJK Ideograph>) 23644 0x9F9D 龝 (<CJK Ideograph>) 23645 0x9F9E 龞 (<CJK Ideograph>) 23646 0x9FA1 龡 (<CJK Ideograph>) 23647 0x9FA2 龢 (<CJK Ideograph>) 23648 0x9FA3 龣 (<CJK Ideograph>) 23649 0x9FA4 龤 (<CJK Ideograph>) 23650 0x9FA5 龥 (<CJK Ideograph>) 23651 0xF92C 郎 (CJK COMPATIBILITY IDEOGRAPH-F92C) 23652 0xF979 凉 (CJK COMPATIBILITY IDEOGRAPH-F979) 23653 0xF995 秊 (CJK COMPATIBILITY IDEOGRAPH-F995) 23654 0xF9E7 裏 (CJK COMPATIBILITY IDEOGRAPH-F9E7) 23655 0xF9F1 隣 (CJK COMPATIBILITY IDEOGRAPH-F9F1) 23656 0xE40A  (<Private Use>) 23657 0xE40B  (<Private Use>) 23658 0xE40C  (<Private Use>) 23659 0xE40D  (<Private Use>) 23660 0xE40E  (<Private Use>) 23661 0xE40F  (<Private Use>) 23662 0xE410  (<Private Use>) 23663 0xE411  (<Private Use>) 23664 0xE412  (<Private Use>) 23665 0xE413  (<Private Use>) 23666 0xE414  (<Private Use>) 23667 0xE415  (<Private Use>) 23668 0xE416  (<Private Use>) 23669 0xE417  (<Private Use>) 23670 0xE418  (<Private Use>) 23671 0xE419  (<Private Use>) 23672 0xE41A  (<Private Use>) 23673 0xE41B  (<Private Use>) 23674 0xE41C  (<Private Use>) 23675 0xE41D  (<Private Use>) 23676 0xE41E  (<Private Use>) 23677 0xE41F  (<Private Use>) 23678 0xE420  (<Private Use>) 23679 0xE421  (<Private Use>) 23680 0xE422  (<Private Use>) 23681 0xE423  (<Private Use>) 23682 0xE424  (<Private Use>) 23683 0xE425  (<Private Use>) 23684 0xE426  (<Private Use>) 23685 0xE427  (<Private Use>) 23686 0xE428  (<Private Use>) 23687 0xE429  (<Private Use>) 23688 0xE42A  (<Private Use>) 23689 0xE42B  (<Private Use>) 23690 0xE42C  (<Private Use>) 23691 0xE42D  (<Private Use>) 23692 0xE42E  (<Private Use>) 23693 0xE42F  (<Private Use>) 23694 0xE430  (<Private Use>) 23695 0xE431  (<Private Use>) 23696 0xE432  (<Private Use>) 23697 0xE433  (<Private Use>) 23698 0xE434  (<Private Use>) 23699 0xE435  (<Private Use>) 23700 0xE436  (<Private Use>) 23701 0xE437  (<Private Use>) 23702 0xE438  (<Private Use>) 23703 0xE439  (<Private Use>) 23704 0xE43A  (<Private Use>) 23705 0xE43B  (<Private Use>) 23706 0xE43C  (<Private Use>) 23707 0xE43D  (<Private Use>) 23708 0xE43E  (<Private Use>) 23709 0xE43F  (<Private Use>) 23710 0xE440  (<Private Use>) 23711 0xE441  (<Private Use>) 23712 0xE442  (<Private Use>) 23713 0xE443  (<Private Use>) 23714 0xE444  (<Private Use>) 23715 0xE445  (<Private Use>) 23716 0xE446  (<Private Use>) 23717 0xE447  (<Private Use>) 23718 0xE448  (<Private Use>) 23719 0xE449  (<Private Use>) 23720 0xE44A  (<Private Use>) 23721 0xE44B  (<Private Use>) 23722 0xE44C  (<Private Use>) 23723 0xE44D  (<Private Use>) 23724 0xE44E  (<Private Use>) 23725 0xE44F  (<Private Use>) 23726 0xE450  (<Private Use>) 23727 0xE451  (<Private Use>) 23728 0xE452  (<Private Use>) 23729 0xE453  (<Private Use>) 23730 0xE454  (<Private Use>) 23731 0xE455  (<Private Use>) 23732 0xE456  (<Private Use>) 23733 0xE457  (<Private Use>) 23734 0xE458  (<Private Use>) 23735 0xE459  (<Private Use>) 23736 0xE45A  (<Private Use>) 23737 0xE45B  (<Private Use>) 23738 0xE45C  (<Private Use>) 23739 0xE45D  (<Private Use>) 23740 0xE45E  (<Private Use>) 23741 0xE45F  (<Private Use>) 23742 0xE460  (<Private Use>) 23743 0xE461  (<Private Use>) 23744 0xE462  (<Private Use>) 23745 0xE463  (<Private Use>) 23746 0xE464  (<Private Use>) 23747 0xE465  (<Private Use>) 23748 0xE466  (<Private Use>) 23749 0xE467  (<Private Use>) 23750 0xFA0C 兀 (CJK COMPATIBILITY IDEOGRAPH-FA0C) 23751 0xFA0D 嗀 (CJK COMPATIBILITY IDEOGRAPH-FA0D) 23752 0xFA0E 﨎 (CJK COMPATIBILITY IDEOGRAPH-FA0E) 23753 0xFA0F 﨏 (CJK COMPATIBILITY IDEOGRAPH-FA0F) 23754 0xFA11 﨑 (CJK COMPATIBILITY IDEOGRAPH-FA11) 23755 0xFA13 﨓 (CJK COMPATIBILITY IDEOGRAPH-FA13) 23756 0xFA14 﨔 (CJK COMPATIBILITY IDEOGRAPH-FA14) 23757 0xFA18 礼 (CJK COMPATIBILITY IDEOGRAPH-FA18) 23758 0xFA1F 﨟 (CJK COMPATIBILITY IDEOGRAPH-FA1F) 23759 0xFA20 蘒 (CJK COMPATIBILITY IDEOGRAPH-FA20) 23760 0xFA21 﨡 (CJK COMPATIBILITY IDEOGRAPH-FA21) 23761 0xFA23 﨣 (CJK COMPATIBILITY IDEOGRAPH-FA23) 23762 0xFA24 﨤 (CJK COMPATIBILITY IDEOGRAPH-FA24) 23763 0xFA27 﨧 (CJK COMPATIBILITY IDEOGRAPH-FA27) 23764 0xFA28 﨨 (CJK COMPATIBILITY IDEOGRAPH-FA28) 23765 0xFA29 﨩 (CJK COMPATIBILITY IDEOGRAPH-FA29) 23766 0x2E81 ⺁ (CJK RADICAL CLIFF) 23767 0xE816  (<Private Use>) 23768 0xE817  (<Private Use>) 23769 0xE818  (<Private Use>) 23770 0x2E84 ⺄ (CJK RADICAL SECOND THREE) 23771 0x3473 㑳 (<CJK Ideograph Extension A>) 23772 0x3447 㑇 (<CJK Ideograph Extension A>) 23773 0x2E88 ⺈ (CJK RADICAL KNIFE ONE) 23774 0x2E8B ⺋ (CJK RADICAL SEAL) 23775 0x9FB4  (2024 update) 23776 0x359E 㖞 (<CJK Ideograph Extension A>) 23777 0x361A 㘚 (<CJK Ideograph Extension A>) 23778 0x360E 㘎 (<CJK Ideograph Extension A>) 23779 0x2E8C ⺌ (CJK RADICAL SMALL ONE) 23780 0x2E97 ⺗ (CJK RADICAL HEART TWO) 23781 0x396E 㥮 (<CJK Ideograph Extension A>) 23782 0x3918 㤘 (<CJK Ideograph Extension A>) 23783 0x9FB5  (2024 update) 23784 0x39CF 㧏 (<CJK Ideograph Extension A>) 23785 0x39DF 㧟 (<CJK Ideograph Extension A>) 23786 0x3A73 㩳 (<CJK Ideograph Extension A>) 23787 0x39D0 㧐 (<CJK Ideograph Extension A>) 23788 0x9FB6  (2024 update) 23789 0x9FB7  (2024 update) 23790 0x3B4E 㭎 (<CJK Ideograph Extension A>) 23791 0x3C6E 㱮 (<CJK Ideograph Extension A>) 23792 0x3CE0 㳠 (<CJK Ideograph Extension A>) 23793 0x2EA7 ⺧ (CJK RADICAL COW) 23794 0xE831  (<Private Use>) 23795 0x9FB8  (2024 update) 23796 0x2EAA ⺪ (CJK RADICAL BOLT OF CLOTH) 23797 0x4056 䁖 (<CJK Ideograph Extension A>) 23798 0x415F 䅟 (<CJK Ideograph Extension A>) 23799 0x2EAE ⺮ (CJK RADICAL BAMBOO) 23800 0x4337 䌷 (<CJK Ideograph Extension A>) 23801 0x2EB3 ⺳ (CJK RADICAL NET THREE) 23802 0x2EB6 ⺶ (CJK RADICAL SHEEP) 23803 0x2EB7 ⺷ (CJK RADICAL RAM) 23804 0xE83B  (<Private Use>) 23805 0x43B1 䎱 (<CJK Ideograph Extension A>) 23806 0x43AC 䎬 (<CJK Ideograph Extension A>) 23807 0x2EBB ⺻ (CJK RADICAL BRUSH TWO) 23808 0x43DD 䏝 (<CJK Ideograph Extension A>) 23809 0x44D6 䓖 (<CJK Ideograph Extension A>) 23810 0x4661 䙡 (<CJK Ideograph Extension A>) 23811 0x464C 䙌 (<CJK Ideograph Extension A>) 23812 0x9FB9  (2024 update) 23813 0x4723 䜣 (<CJK Ideograph Extension A>) 23814 0x4729 䜩 (<CJK Ideograph Extension A>) 23815 0x477C 䝼 (<CJK Ideograph Extension A>) 23816 0x478D 䞍 (<CJK Ideograph Extension A>) 23817 0x2ECA ⻊ (CJK RADICAL FOOT) 23818 0x4947 䥇 (<CJK Ideograph Extension A>) 23819 0x497A 䥺 (<CJK Ideograph Extension A>) 23820 0x497D 䥽 (<CJK Ideograph Extension A>) 23821 0x4982 䦂 (<CJK Ideograph Extension A>) 23822 0x4983 䦃 (<CJK Ideograph Extension A>) 23823 0x4985 䦅 (<CJK Ideograph Extension A>) 23824 0x4986 䦆 (<CJK Ideograph Extension A>) 23825 0x499F 䦟 (<CJK Ideograph Extension A>) 23826 0x499B 䦛 (<CJK Ideograph Extension A>) 23827 0x49B7 䦷 (<CJK Ideograph Extension A>) 23828 0x49B6 䦶 (<CJK Ideograph Extension A>) 23829 0x9FBA  (2024 update) 23830 0xE855  (<Private Use>) 23831 0x4CA3 䲣 (<CJK Ideograph Extension A>) 23832 0x4C9F 䲟 (<CJK Ideograph Extension A>) 23833 0x4CA0 䲠 (<CJK Ideograph Extension A>) 23834 0x4CA1 䲡 (<CJK Ideograph Extension A>) 23835 0x4C77 䱷 (<CJK Ideograph Extension A>) 23836 0x4CA2 䲢 (<CJK Ideograph Extension A>) 23837 0x4D13 䴓 (<CJK Ideograph Extension A>) 23838 0x4D14 䴔 (<CJK Ideograph Extension A>) 23839 0x4D15 䴕 (<CJK Ideograph Extension A>) 23840 0x4D16 䴖 (<CJK Ideograph Extension A>) 23841 0x4D17 䴗 (<CJK Ideograph Extension A>) 23842 0x4D18 䴘 (<CJK Ideograph Extension A>) 23843 0x4D19 䴙 (<CJK Ideograph Extension A>) 23844 0x4DAE 䶮 (<CJK Ideograph Extension A>) 23845 0x9FBB  (2024 update) 23846 0xE468  (<Private Use>) 23847 0xE469  (<Private Use>) 23848 0xE46A  (<Private Use>) 23849 0xE46B  (<Private Use>) 23850 0xE46C  (<Private Use>) 23851 0xE46D  (<Private Use>) 23852 0xE46E  (<Private Use>) 23853 0xE46F  (<Private Use>) 23854 0xE470  (<Private Use>) 23855 0xE471  (<Private Use>) 23856 0xE472  (<Private Use>) 23857 0xE473  (<Private Use>) 23858 0xE474  (<Private Use>) 23859 0xE475  (<Private Use>) 23860 0xE476  (<Private Use>) 23861 0xE477  (<Private Use>) 23862 0xE478  (<Private Use>) 23863 0xE479  (<Private Use>) 23864 0xE47A  (<Private Use>) 23865 0xE47B  (<Private Use>) 23866 0xE47C  (<Private Use>) 23867 0xE47D  (<Private Use>) 23868 0xE47E  (<Private Use>) 23869 0xE47F  (<Private Use>) 23870 0xE480  (<Private Use>) 23871 0xE481  (<Private Use>) 23872 0xE482  (<Private Use>) 23873 0xE483  (<Private Use>) 23874 0xE484  (<Private Use>) 23875 0xE485  (<Private Use>) 23876 0xE486  (<Private Use>) 23877 0xE487  (<Private Use>) 23878 0xE488  (<Private Use>) 23879 0xE489  (<Private Use>) 23880 0xE48A  (<Private Use>) 23881 0xE48B  (<Private Use>) 23882 0xE48C  (<Private Use>) 23883 0xE48D  (<Private Use>) 23884 0xE48E  (<Private Use>) 23885 0xE48F  (<Private Use>) 23886 0xE490  (<Private Use>) 23887 0xE491  (<Private Use>) 23888 0xE492  (<Private Use>) 23889 0xE493  (<Private Use>) 23890 0xE494  (<Private Use>) 23891 0xE495  (<Private Use>) 23892 0xE496  (<Private Use>) 23893 0xE497  (<Private Use>) 23894 0xE498  (<Private Use>) 23895 0xE499  (<Private Use>) 23896 0xE49A  (<Private Use>) 23897 0xE49B  (<Private Use>) 23898 0xE49C  (<Private Use>) 23899 0xE49D  (<Private Use>) 23900 0xE49E  (<Private Use>) 23901 0xE49F  (<Private Use>) 23902 0xE4A0  (<Private Use>) 23903 0xE4A1  (<Private Use>) 23904 0xE4A2  (<Private Use>) 23905 0xE4A3  (<Private Use>) 23906 0xE4A4  (<Private Use>) 23907 0xE4A5  (<Private Use>) 23908 0xE4A6  (<Private Use>) 23909 0xE4A7  (<Private Use>) 23910 0xE4A8  (<Private Use>) 23911 0xE4A9  (<Private Use>) 23912 0xE4AA  (<Private Use>) 23913 0xE4AB  (<Private Use>) 23914 0xE4AC  (<Private Use>) 23915 0xE4AD  (<Private Use>) 23916 0xE4AE  (<Private Use>) 23917 0xE4AF  (<Private Use>) 23918 0xE4B0  (<Private Use>) 23919 0xE4B1  (<Private Use>) 23920 0xE4B2  (<Private Use>) 23921 0xE4B3  (<Private Use>) 23922 0xE4B4  (<Private Use>) 23923 0xE4B5  (<Private Use>) 23924 0xE4B6  (<Private Use>) 23925 0xE4B7  (<Private Use>) 23926 0xE4B8  (<Private Use>) 23927 0xE4B9  (<Private Use>) 23928 0xE4BA  (<Private Use>) 23929 0xE4BB  (<Private Use>) 23930 0xE4BC  (<Private Use>) 23931 0xE4BD  (<Private Use>) 23932 0xE4BE  (<Private Use>) 23933 0xE4BF  (<Private Use>) 23934 0xE4C0  (<Private Use>) 23935 0xE4C1  (<Private Use>) 23936 0xE4C2  (<Private Use>) 23937 0xE4C3  (<Private Use>) 23938 0xE4C4  (<Private Use>) 23939 0xE4C5  (<Private Use>) ����������������������������������������chawan-v0.4.0/res/index-ibm866.txt������������������������������������������������������������������0000664�0000000�0000000�00000013627�15202323131�0016615�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-ibm866.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: db6fe14a559d1601a7667338d83704773d5708dbc641e1ad3c5e21405770f05e # Date: 2018-01-06 0 0x0410 А (CYRILLIC CAPITAL LETTER A) 1 0x0411 Б (CYRILLIC CAPITAL LETTER BE) 2 0x0412 В (CYRILLIC CAPITAL LETTER VE) 3 0x0413 Г (CYRILLIC CAPITAL LETTER GHE) 4 0x0414 Д (CYRILLIC CAPITAL LETTER DE) 5 0x0415 Е (CYRILLIC CAPITAL LETTER IE) 6 0x0416 Ж (CYRILLIC CAPITAL LETTER ZHE) 7 0x0417 З (CYRILLIC CAPITAL LETTER ZE) 8 0x0418 И (CYRILLIC CAPITAL LETTER I) 9 0x0419 Й (CYRILLIC CAPITAL LETTER SHORT I) 10 0x041A К (CYRILLIC CAPITAL LETTER KA) 11 0x041B Л (CYRILLIC CAPITAL LETTER EL) 12 0x041C М (CYRILLIC CAPITAL LETTER EM) 13 0x041D Н (CYRILLIC CAPITAL LETTER EN) 14 0x041E О (CYRILLIC CAPITAL LETTER O) 15 0x041F П (CYRILLIC CAPITAL LETTER PE) 16 0x0420 Р (CYRILLIC CAPITAL LETTER ER) 17 0x0421 С (CYRILLIC CAPITAL LETTER ES) 18 0x0422 Т (CYRILLIC CAPITAL LETTER TE) 19 0x0423 У (CYRILLIC CAPITAL LETTER U) 20 0x0424 Ф (CYRILLIC CAPITAL LETTER EF) 21 0x0425 Х (CYRILLIC CAPITAL LETTER HA) 22 0x0426 Ц (CYRILLIC CAPITAL LETTER TSE) 23 0x0427 Ч (CYRILLIC CAPITAL LETTER CHE) 24 0x0428 Ш (CYRILLIC CAPITAL LETTER SHA) 25 0x0429 Щ (CYRILLIC CAPITAL LETTER SHCHA) 26 0x042A Ъ (CYRILLIC CAPITAL LETTER HARD SIGN) 27 0x042B Ы (CYRILLIC CAPITAL LETTER YERU) 28 0x042C Ь (CYRILLIC CAPITAL LETTER SOFT SIGN) 29 0x042D Э (CYRILLIC CAPITAL LETTER E) 30 0x042E Ю (CYRILLIC CAPITAL LETTER YU) 31 0x042F Я (CYRILLIC CAPITAL LETTER YA) 32 0x0430 а (CYRILLIC SMALL LETTER A) 33 0x0431 б (CYRILLIC SMALL LETTER BE) 34 0x0432 в (CYRILLIC SMALL LETTER VE) 35 0x0433 г (CYRILLIC SMALL LETTER GHE) 36 0x0434 д (CYRILLIC SMALL LETTER DE) 37 0x0435 е (CYRILLIC SMALL LETTER IE) 38 0x0436 ж (CYRILLIC SMALL LETTER ZHE) 39 0x0437 з (CYRILLIC SMALL LETTER ZE) 40 0x0438 и (CYRILLIC SMALL LETTER I) 41 0x0439 й (CYRILLIC SMALL LETTER SHORT I) 42 0x043A к (CYRILLIC SMALL LETTER KA) 43 0x043B л (CYRILLIC SMALL LETTER EL) 44 0x043C м (CYRILLIC SMALL LETTER EM) 45 0x043D н (CYRILLIC SMALL LETTER EN) 46 0x043E о (CYRILLIC SMALL LETTER O) 47 0x043F п (CYRILLIC SMALL LETTER PE) 48 0x2591 ░ (LIGHT SHADE) 49 0x2592 ▒ (MEDIUM SHADE) 50 0x2593 ▓ (DARK SHADE) 51 0x2502 │ (BOX DRAWINGS LIGHT VERTICAL) 52 0x2524 ┤ (BOX DRAWINGS LIGHT VERTICAL AND LEFT) 53 0x2561 ╡ (BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE) 54 0x2562 ╢ (BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE) 55 0x2556 ╖ (BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE) 56 0x2555 ╕ (BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE) 57 0x2563 ╣ (BOX DRAWINGS DOUBLE VERTICAL AND LEFT) 58 0x2551 ║ (BOX DRAWINGS DOUBLE VERTICAL) 59 0x2557 ╗ (BOX DRAWINGS DOUBLE DOWN AND LEFT) 60 0x255D ╝ (BOX DRAWINGS DOUBLE UP AND LEFT) 61 0x255C ╜ (BOX DRAWINGS UP DOUBLE AND LEFT SINGLE) 62 0x255B ╛ (BOX DRAWINGS UP SINGLE AND LEFT DOUBLE) 63 0x2510 ┐ (BOX DRAWINGS LIGHT DOWN AND LEFT) 64 0x2514 └ (BOX DRAWINGS LIGHT UP AND RIGHT) 65 0x2534 ┴ (BOX DRAWINGS LIGHT UP AND HORIZONTAL) 66 0x252C ┬ (BOX DRAWINGS LIGHT DOWN AND HORIZONTAL) 67 0x251C ├ (BOX DRAWINGS LIGHT VERTICAL AND RIGHT) 68 0x2500 ─ (BOX DRAWINGS LIGHT HORIZONTAL) 69 0x253C ┼ (BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL) 70 0x255E ╞ (BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE) 71 0x255F ╟ (BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE) 72 0x255A ╚ (BOX DRAWINGS DOUBLE UP AND RIGHT) 73 0x2554 ╔ (BOX DRAWINGS DOUBLE DOWN AND RIGHT) 74 0x2569 ╩ (BOX DRAWINGS DOUBLE UP AND HORIZONTAL) 75 0x2566 ╦ (BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL) 76 0x2560 ╠ (BOX DRAWINGS DOUBLE VERTICAL AND RIGHT) 77 0x2550 ═ (BOX DRAWINGS DOUBLE HORIZONTAL) 78 0x256C ╬ (BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL) 79 0x2567 ╧ (BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE) 80 0x2568 ╨ (BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE) 81 0x2564 ╤ (BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE) 82 0x2565 ╥ (BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE) 83 0x2559 ╙ (BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE) 84 0x2558 ╘ (BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE) 85 0x2552 ╒ (BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE) 86 0x2553 ╓ (BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE) 87 0x256B ╫ (BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE) 88 0x256A ╪ (BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE) 89 0x2518 ┘ (BOX DRAWINGS LIGHT UP AND LEFT) 90 0x250C ┌ (BOX DRAWINGS LIGHT DOWN AND RIGHT) 91 0x2588 █ (FULL BLOCK) 92 0x2584 ▄ (LOWER HALF BLOCK) 93 0x258C ▌ (LEFT HALF BLOCK) 94 0x2590 ▐ (RIGHT HALF BLOCK) 95 0x2580 ▀ (UPPER HALF BLOCK) 96 0x0440 р (CYRILLIC SMALL LETTER ER) 97 0x0441 с (CYRILLIC SMALL LETTER ES) 98 0x0442 т (CYRILLIC SMALL LETTER TE) 99 0x0443 у (CYRILLIC SMALL LETTER U) 100 0x0444 ф (CYRILLIC SMALL LETTER EF) 101 0x0445 х (CYRILLIC SMALL LETTER HA) 102 0x0446 ц (CYRILLIC SMALL LETTER TSE) 103 0x0447 ч (CYRILLIC SMALL LETTER CHE) 104 0x0448 ш (CYRILLIC SMALL LETTER SHA) 105 0x0449 щ (CYRILLIC SMALL LETTER SHCHA) 106 0x044A ъ (CYRILLIC SMALL LETTER HARD SIGN) 107 0x044B ы (CYRILLIC SMALL LETTER YERU) 108 0x044C ь (CYRILLIC SMALL LETTER SOFT SIGN) 109 0x044D э (CYRILLIC SMALL LETTER E) 110 0x044E ю (CYRILLIC SMALL LETTER YU) 111 0x044F я (CYRILLIC SMALL LETTER YA) 112 0x0401 Ё (CYRILLIC CAPITAL LETTER IO) 113 0x0451 ё (CYRILLIC SMALL LETTER IO) 114 0x0404 Є (CYRILLIC CAPITAL LETTER UKRAINIAN IE) 115 0x0454 є (CYRILLIC SMALL LETTER UKRAINIAN IE) 116 0x0407 Ї (CYRILLIC CAPITAL LETTER YI) 117 0x0457 ї (CYRILLIC SMALL LETTER YI) 118 0x040E Ў (CYRILLIC CAPITAL LETTER SHORT U) 119 0x045E ў (CYRILLIC SMALL LETTER SHORT U) 120 0x00B0 ° (DEGREE SIGN) 121 0x2219 ∙ (BULLET OPERATOR) 122 0x00B7 · (MIDDLE DOT) 123 0x221A √ (SQUARE ROOT) 124 0x2116 № (NUMERO SIGN) 125 0x00A4 ¤ (CURRENCY SIGN) 126 0x25A0 ■ (BLACK SQUARE) 127 0x00A0   (NO-BREAK SPACE) ���������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-iso-2022-jp-katakana.txt����������������������������������������������������0000664�0000000�0000000�00000004742�15202323131�0021135�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-iso-2022-jp-katakana.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 6ffc12c11f6eab1ccb3dada740d9b0db096ef0b0783c3bd5ec951dcb4a44b95e # Date: 2018-01-06 0 0x3002 。 (IDEOGRAPHIC FULL STOP) 1 0x300C 「 (LEFT CORNER BRACKET) 2 0x300D 」 (RIGHT CORNER BRACKET) 3 0x3001 、 (IDEOGRAPHIC COMMA) 4 0x30FB ・ (KATAKANA MIDDLE DOT) 5 0x30F2 ヲ (KATAKANA LETTER WO) 6 0x30A1 ァ (KATAKANA LETTER SMALL A) 7 0x30A3 ィ (KATAKANA LETTER SMALL I) 8 0x30A5 ゥ (KATAKANA LETTER SMALL U) 9 0x30A7 ェ (KATAKANA LETTER SMALL E) 10 0x30A9 ォ (KATAKANA LETTER SMALL O) 11 0x30E3 ャ (KATAKANA LETTER SMALL YA) 12 0x30E5 ュ (KATAKANA LETTER SMALL YU) 13 0x30E7 ョ (KATAKANA LETTER SMALL YO) 14 0x30C3 ッ (KATAKANA LETTER SMALL TU) 15 0x30FC ー (KATAKANA-HIRAGANA PROLONGED SOUND MARK) 16 0x30A2 ア (KATAKANA LETTER A) 17 0x30A4 イ (KATAKANA LETTER I) 18 0x30A6 ウ (KATAKANA LETTER U) 19 0x30A8 エ (KATAKANA LETTER E) 20 0x30AA オ (KATAKANA LETTER O) 21 0x30AB カ (KATAKANA LETTER KA) 22 0x30AD キ (KATAKANA LETTER KI) 23 0x30AF ク (KATAKANA LETTER KU) 24 0x30B1 ケ (KATAKANA LETTER KE) 25 0x30B3 コ (KATAKANA LETTER KO) 26 0x30B5 サ (KATAKANA LETTER SA) 27 0x30B7 シ (KATAKANA LETTER SI) 28 0x30B9 ス (KATAKANA LETTER SU) 29 0x30BB セ (KATAKANA LETTER SE) 30 0x30BD ソ (KATAKANA LETTER SO) 31 0x30BF タ (KATAKANA LETTER TA) 32 0x30C1 チ (KATAKANA LETTER TI) 33 0x30C4 ツ (KATAKANA LETTER TU) 34 0x30C6 テ (KATAKANA LETTER TE) 35 0x30C8 ト (KATAKANA LETTER TO) 36 0x30CA ナ (KATAKANA LETTER NA) 37 0x30CB ニ (KATAKANA LETTER NI) 38 0x30CC ヌ (KATAKANA LETTER NU) 39 0x30CD ネ (KATAKANA LETTER NE) 40 0x30CE ノ (KATAKANA LETTER NO) 41 0x30CF ハ (KATAKANA LETTER HA) 42 0x30D2 ヒ (KATAKANA LETTER HI) 43 0x30D5 フ (KATAKANA LETTER HU) 44 0x30D8 ヘ (KATAKANA LETTER HE) 45 0x30DB ホ (KATAKANA LETTER HO) 46 0x30DE マ (KATAKANA LETTER MA) 47 0x30DF ミ (KATAKANA LETTER MI) 48 0x30E0 ム (KATAKANA LETTER MU) 49 0x30E1 メ (KATAKANA LETTER ME) 50 0x30E2 モ (KATAKANA LETTER MO) 51 0x30E4 ヤ (KATAKANA LETTER YA) 52 0x30E6 ユ (KATAKANA LETTER YU) 53 0x30E8 ヨ (KATAKANA LETTER YO) 54 0x30E9 ラ (KATAKANA LETTER RA) 55 0x30EA リ (KATAKANA LETTER RI) 56 0x30EB ル (KATAKANA LETTER RU) 57 0x30EC レ (KATAKANA LETTER RE) 58 0x30ED ロ (KATAKANA LETTER RO) 59 0x30EF ワ (KATAKANA LETTER WA) 60 0x30F3 ン (KATAKANA LETTER N) 61 0x309B ゛ (KATAKANA-HIRAGANA VOICED SOUND MARK) 62 0x309C ゜ (KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK) ������������������������������chawan-v0.4.0/res/index-iso-8859-10.txt�������������������������������������������������������������0000664�0000000�0000000�00000013055�15202323131�0017220�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-iso-8859-10.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 02c2b5590d8ccda9931008c471f6ee2c590b2c8fe5e6ccb3b08638115d778507 # Date: 2018-01-06 0 0x0080 € (<control>) 1 0x0081  (<control>) 2 0x0082 ‚ (<control>) 3 0x0083 ƒ (<control>) 4 0x0084 „ (<control>) 5 0x0085 … (<control>) 6 0x0086 † (<control>) 7 0x0087 ‡ (<control>) 8 0x0088 ˆ (<control>) 9 0x0089 ‰ (<control>) 10 0x008A Š (<control>) 11 0x008B ‹ (<control>) 12 0x008C Œ (<control>) 13 0x008D  (<control>) 14 0x008E Ž (<control>) 15 0x008F  (<control>) 16 0x0090  (<control>) 17 0x0091 ‘ (<control>) 18 0x0092 ’ (<control>) 19 0x0093 “ (<control>) 20 0x0094 ” (<control>) 21 0x0095 • (<control>) 22 0x0096 – (<control>) 23 0x0097 — (<control>) 24 0x0098 ˜ (<control>) 25 0x0099 ™ (<control>) 26 0x009A š (<control>) 27 0x009B › (<control>) 28 0x009C œ (<control>) 29 0x009D  (<control>) 30 0x009E ž (<control>) 31 0x009F Ÿ (<control>) 32 0x00A0   (NO-BREAK SPACE) 33 0x0104 Ą (LATIN CAPITAL LETTER A WITH OGONEK) 34 0x0112 Ē (LATIN CAPITAL LETTER E WITH MACRON) 35 0x0122 Ģ (LATIN CAPITAL LETTER G WITH CEDILLA) 36 0x012A Ī (LATIN CAPITAL LETTER I WITH MACRON) 37 0x0128 Ĩ (LATIN CAPITAL LETTER I WITH TILDE) 38 0x0136 Ķ (LATIN CAPITAL LETTER K WITH CEDILLA) 39 0x00A7 § (SECTION SIGN) 40 0x013B Ļ (LATIN CAPITAL LETTER L WITH CEDILLA) 41 0x0110 Đ (LATIN CAPITAL LETTER D WITH STROKE) 42 0x0160 Š (LATIN CAPITAL LETTER S WITH CARON) 43 0x0166 Ŧ (LATIN CAPITAL LETTER T WITH STROKE) 44 0x017D Ž (LATIN CAPITAL LETTER Z WITH CARON) 45 0x00AD ­ (SOFT HYPHEN) 46 0x016A Ū (LATIN CAPITAL LETTER U WITH MACRON) 47 0x014A Ŋ (LATIN CAPITAL LETTER ENG) 48 0x00B0 ° (DEGREE SIGN) 49 0x0105 ą (LATIN SMALL LETTER A WITH OGONEK) 50 0x0113 ē (LATIN SMALL LETTER E WITH MACRON) 51 0x0123 ģ (LATIN SMALL LETTER G WITH CEDILLA) 52 0x012B ī (LATIN SMALL LETTER I WITH MACRON) 53 0x0129 ĩ (LATIN SMALL LETTER I WITH TILDE) 54 0x0137 ķ (LATIN SMALL LETTER K WITH CEDILLA) 55 0x00B7 · (MIDDLE DOT) 56 0x013C ļ (LATIN SMALL LETTER L WITH CEDILLA) 57 0x0111 đ (LATIN SMALL LETTER D WITH STROKE) 58 0x0161 š (LATIN SMALL LETTER S WITH CARON) 59 0x0167 ŧ (LATIN SMALL LETTER T WITH STROKE) 60 0x017E ž (LATIN SMALL LETTER Z WITH CARON) 61 0x2015 ― (HORIZONTAL BAR) 62 0x016B ū (LATIN SMALL LETTER U WITH MACRON) 63 0x014B ŋ (LATIN SMALL LETTER ENG) 64 0x0100 Ā (LATIN CAPITAL LETTER A WITH MACRON) 65 0x00C1 Á (LATIN CAPITAL LETTER A WITH ACUTE) 66 0x00C2  (LATIN CAPITAL LETTER A WITH CIRCUMFLEX) 67 0x00C3 à (LATIN CAPITAL LETTER A WITH TILDE) 68 0x00C4 Ä (LATIN CAPITAL LETTER A WITH DIAERESIS) 69 0x00C5 Å (LATIN CAPITAL LETTER A WITH RING ABOVE) 70 0x00C6 Æ (LATIN CAPITAL LETTER AE) 71 0x012E Į (LATIN CAPITAL LETTER I WITH OGONEK) 72 0x010C Č (LATIN CAPITAL LETTER C WITH CARON) 73 0x00C9 É (LATIN CAPITAL LETTER E WITH ACUTE) 74 0x0118 Ę (LATIN CAPITAL LETTER E WITH OGONEK) 75 0x00CB Ë (LATIN CAPITAL LETTER E WITH DIAERESIS) 76 0x0116 Ė (LATIN CAPITAL LETTER E WITH DOT ABOVE) 77 0x00CD Í (LATIN CAPITAL LETTER I WITH ACUTE) 78 0x00CE Î (LATIN CAPITAL LETTER I WITH CIRCUMFLEX) 79 0x00CF Ï (LATIN CAPITAL LETTER I WITH DIAERESIS) 80 0x00D0 Ð (LATIN CAPITAL LETTER ETH) 81 0x0145 Ņ (LATIN CAPITAL LETTER N WITH CEDILLA) 82 0x014C Ō (LATIN CAPITAL LETTER O WITH MACRON) 83 0x00D3 Ó (LATIN CAPITAL LETTER O WITH ACUTE) 84 0x00D4 Ô (LATIN CAPITAL LETTER O WITH CIRCUMFLEX) 85 0x00D5 Õ (LATIN CAPITAL LETTER O WITH TILDE) 86 0x00D6 Ö (LATIN CAPITAL LETTER O WITH DIAERESIS) 87 0x0168 Ũ (LATIN CAPITAL LETTER U WITH TILDE) 88 0x00D8 Ø (LATIN CAPITAL LETTER O WITH STROKE) 89 0x0172 Ų (LATIN CAPITAL LETTER U WITH OGONEK) 90 0x00DA Ú (LATIN CAPITAL LETTER U WITH ACUTE) 91 0x00DB Û (LATIN CAPITAL LETTER U WITH CIRCUMFLEX) 92 0x00DC Ü (LATIN CAPITAL LETTER U WITH DIAERESIS) 93 0x00DD Ý (LATIN CAPITAL LETTER Y WITH ACUTE) 94 0x00DE Þ (LATIN CAPITAL LETTER THORN) 95 0x00DF ß (LATIN SMALL LETTER SHARP S) 96 0x0101 ā (LATIN SMALL LETTER A WITH MACRON) 97 0x00E1 á (LATIN SMALL LETTER A WITH ACUTE) 98 0x00E2 â (LATIN SMALL LETTER A WITH CIRCUMFLEX) 99 0x00E3 ã (LATIN SMALL LETTER A WITH TILDE) 100 0x00E4 ä (LATIN SMALL LETTER A WITH DIAERESIS) 101 0x00E5 å (LATIN SMALL LETTER A WITH RING ABOVE) 102 0x00E6 æ (LATIN SMALL LETTER AE) 103 0x012F į (LATIN SMALL LETTER I WITH OGONEK) 104 0x010D č (LATIN SMALL LETTER C WITH CARON) 105 0x00E9 é (LATIN SMALL LETTER E WITH ACUTE) 106 0x0119 ę (LATIN SMALL LETTER E WITH OGONEK) 107 0x00EB ë (LATIN SMALL LETTER E WITH DIAERESIS) 108 0x0117 ė (LATIN SMALL LETTER E WITH DOT ABOVE) 109 0x00ED í (LATIN SMALL LETTER I WITH ACUTE) 110 0x00EE î (LATIN SMALL LETTER I WITH CIRCUMFLEX) 111 0x00EF ï (LATIN SMALL LETTER I WITH DIAERESIS) 112 0x00F0 ð (LATIN SMALL LETTER ETH) 113 0x0146 ņ (LATIN SMALL LETTER N WITH CEDILLA) 114 0x014D ō (LATIN SMALL LETTER O WITH MACRON) 115 0x00F3 ó (LATIN SMALL LETTER O WITH ACUTE) 116 0x00F4 ô (LATIN SMALL LETTER O WITH CIRCUMFLEX) 117 0x00F5 õ (LATIN SMALL LETTER O WITH TILDE) 118 0x00F6 ö (LATIN SMALL LETTER O WITH DIAERESIS) 119 0x0169 ũ (LATIN SMALL LETTER U WITH TILDE) 120 0x00F8 ø (LATIN SMALL LETTER O WITH STROKE) 121 0x0173 ų (LATIN SMALL LETTER U WITH OGONEK) 122 0x00FA ú (LATIN SMALL LETTER U WITH ACUTE) 123 0x00FB û (LATIN SMALL LETTER U WITH CIRCUMFLEX) 124 0x00FC ü (LATIN SMALL LETTER U WITH DIAERESIS) 125 0x00FD ý (LATIN SMALL LETTER Y WITH ACUTE) 126 0x00FE þ (LATIN SMALL LETTER THORN) 127 0x0138 ĸ (LATIN SMALL LETTER KRA) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-iso-8859-13.txt�������������������������������������������������������������0000664�0000000�0000000�00000012442�15202323131�0017222�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-iso-8859-13.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 40736338e964ab520407cebcb01329f8d450abf6ce12bf88b74b655b60e43300 # Date: 2018-01-06 0 0x0080 € (<control>) 1 0x0081  (<control>) 2 0x0082 ‚ (<control>) 3 0x0083 ƒ (<control>) 4 0x0084 „ (<control>) 5 0x0085 … (<control>) 6 0x0086 † (<control>) 7 0x0087 ‡ (<control>) 8 0x0088 ˆ (<control>) 9 0x0089 ‰ (<control>) 10 0x008A Š (<control>) 11 0x008B ‹ (<control>) 12 0x008C Œ (<control>) 13 0x008D  (<control>) 14 0x008E Ž (<control>) 15 0x008F  (<control>) 16 0x0090  (<control>) 17 0x0091 ‘ (<control>) 18 0x0092 ’ (<control>) 19 0x0093 “ (<control>) 20 0x0094 ” (<control>) 21 0x0095 • (<control>) 22 0x0096 – (<control>) 23 0x0097 — (<control>) 24 0x0098 ˜ (<control>) 25 0x0099 ™ (<control>) 26 0x009A š (<control>) 27 0x009B › (<control>) 28 0x009C œ (<control>) 29 0x009D  (<control>) 30 0x009E ž (<control>) 31 0x009F Ÿ (<control>) 32 0x00A0   (NO-BREAK SPACE) 33 0x201D ” (RIGHT DOUBLE QUOTATION MARK) 34 0x00A2 ¢ (CENT SIGN) 35 0x00A3 £ (POUND SIGN) 36 0x00A4 ¤ (CURRENCY SIGN) 37 0x201E „ (DOUBLE LOW-9 QUOTATION MARK) 38 0x00A6 ¦ (BROKEN BAR) 39 0x00A7 § (SECTION SIGN) 40 0x00D8 Ø (LATIN CAPITAL LETTER O WITH STROKE) 41 0x00A9 © (COPYRIGHT SIGN) 42 0x0156 Ŗ (LATIN CAPITAL LETTER R WITH CEDILLA) 43 0x00AB « (LEFT-POINTING DOUBLE ANGLE QUOTATION MARK) 44 0x00AC ¬ (NOT SIGN) 45 0x00AD ­ (SOFT HYPHEN) 46 0x00AE ® (REGISTERED SIGN) 47 0x00C6 Æ (LATIN CAPITAL LETTER AE) 48 0x00B0 ° (DEGREE SIGN) 49 0x00B1 ± (PLUS-MINUS SIGN) 50 0x00B2 ² (SUPERSCRIPT TWO) 51 0x00B3 ³ (SUPERSCRIPT THREE) 52 0x201C “ (LEFT DOUBLE QUOTATION MARK) 53 0x00B5 µ (MICRO SIGN) 54 0x00B6 ¶ (PILCROW SIGN) 55 0x00B7 · (MIDDLE DOT) 56 0x00F8 ø (LATIN SMALL LETTER O WITH STROKE) 57 0x00B9 ¹ (SUPERSCRIPT ONE) 58 0x0157 ŗ (LATIN SMALL LETTER R WITH CEDILLA) 59 0x00BB » (RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK) 60 0x00BC ¼ (VULGAR FRACTION ONE QUARTER) 61 0x00BD ½ (VULGAR FRACTION ONE HALF) 62 0x00BE ¾ (VULGAR FRACTION THREE QUARTERS) 63 0x00E6 æ (LATIN SMALL LETTER AE) 64 0x0104 Ą (LATIN CAPITAL LETTER A WITH OGONEK) 65 0x012E Į (LATIN CAPITAL LETTER I WITH OGONEK) 66 0x0100 Ā (LATIN CAPITAL LETTER A WITH MACRON) 67 0x0106 Ć (LATIN CAPITAL LETTER C WITH ACUTE) 68 0x00C4 Ä (LATIN CAPITAL LETTER A WITH DIAERESIS) 69 0x00C5 Å (LATIN CAPITAL LETTER A WITH RING ABOVE) 70 0x0118 Ę (LATIN CAPITAL LETTER E WITH OGONEK) 71 0x0112 Ē (LATIN CAPITAL LETTER E WITH MACRON) 72 0x010C Č (LATIN CAPITAL LETTER C WITH CARON) 73 0x00C9 É (LATIN CAPITAL LETTER E WITH ACUTE) 74 0x0179 Ź (LATIN CAPITAL LETTER Z WITH ACUTE) 75 0x0116 Ė (LATIN CAPITAL LETTER E WITH DOT ABOVE) 76 0x0122 Ģ (LATIN CAPITAL LETTER G WITH CEDILLA) 77 0x0136 Ķ (LATIN CAPITAL LETTER K WITH CEDILLA) 78 0x012A Ī (LATIN CAPITAL LETTER I WITH MACRON) 79 0x013B Ļ (LATIN CAPITAL LETTER L WITH CEDILLA) 80 0x0160 Š (LATIN CAPITAL LETTER S WITH CARON) 81 0x0143 Ń (LATIN CAPITAL LETTER N WITH ACUTE) 82 0x0145 Ņ (LATIN CAPITAL LETTER N WITH CEDILLA) 83 0x00D3 Ó (LATIN CAPITAL LETTER O WITH ACUTE) 84 0x014C Ō (LATIN CAPITAL LETTER O WITH MACRON) 85 0x00D5 Õ (LATIN CAPITAL LETTER O WITH TILDE) 86 0x00D6 Ö (LATIN CAPITAL LETTER O WITH DIAERESIS) 87 0x00D7 × (MULTIPLICATION SIGN) 88 0x0172 Ų (LATIN CAPITAL LETTER U WITH OGONEK) 89 0x0141 Ł (LATIN CAPITAL LETTER L WITH STROKE) 90 0x015A Ś (LATIN CAPITAL LETTER S WITH ACUTE) 91 0x016A Ū (LATIN CAPITAL LETTER U WITH MACRON) 92 0x00DC Ü (LATIN CAPITAL LETTER U WITH DIAERESIS) 93 0x017B Ż (LATIN CAPITAL LETTER Z WITH DOT ABOVE) 94 0x017D Ž (LATIN CAPITAL LETTER Z WITH CARON) 95 0x00DF ß (LATIN SMALL LETTER SHARP S) 96 0x0105 ą (LATIN SMALL LETTER A WITH OGONEK) 97 0x012F į (LATIN SMALL LETTER I WITH OGONEK) 98 0x0101 ā (LATIN SMALL LETTER A WITH MACRON) 99 0x0107 ć (LATIN SMALL LETTER C WITH ACUTE) 100 0x00E4 ä (LATIN SMALL LETTER A WITH DIAERESIS) 101 0x00E5 å (LATIN SMALL LETTER A WITH RING ABOVE) 102 0x0119 ę (LATIN SMALL LETTER E WITH OGONEK) 103 0x0113 ē (LATIN SMALL LETTER E WITH MACRON) 104 0x010D č (LATIN SMALL LETTER C WITH CARON) 105 0x00E9 é (LATIN SMALL LETTER E WITH ACUTE) 106 0x017A ź (LATIN SMALL LETTER Z WITH ACUTE) 107 0x0117 ė (LATIN SMALL LETTER E WITH DOT ABOVE) 108 0x0123 ģ (LATIN SMALL LETTER G WITH CEDILLA) 109 0x0137 ķ (LATIN SMALL LETTER K WITH CEDILLA) 110 0x012B ī (LATIN SMALL LETTER I WITH MACRON) 111 0x013C ļ (LATIN SMALL LETTER L WITH CEDILLA) 112 0x0161 š (LATIN SMALL LETTER S WITH CARON) 113 0x0144 ń (LATIN SMALL LETTER N WITH ACUTE) 114 0x0146 ņ (LATIN SMALL LETTER N WITH CEDILLA) 115 0x00F3 ó (LATIN SMALL LETTER O WITH ACUTE) 116 0x014D ō (LATIN SMALL LETTER O WITH MACRON) 117 0x00F5 õ (LATIN SMALL LETTER O WITH TILDE) 118 0x00F6 ö (LATIN SMALL LETTER O WITH DIAERESIS) 119 0x00F7 ÷ (DIVISION SIGN) 120 0x0173 ų (LATIN SMALL LETTER U WITH OGONEK) 121 0x0142 ł (LATIN SMALL LETTER L WITH STROKE) 122 0x015B ś (LATIN SMALL LETTER S WITH ACUTE) 123 0x016B ū (LATIN SMALL LETTER U WITH MACRON) 124 0x00FC ü (LATIN SMALL LETTER U WITH DIAERESIS) 125 0x017C ż (LATIN SMALL LETTER Z WITH DOT ABOVE) 126 0x017E ž (LATIN SMALL LETTER Z WITH CARON) 127 0x2019 ’ (RIGHT SINGLE QUOTATION MARK) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-iso-8859-14.txt�������������������������������������������������������������0000664�0000000�0000000�00000013272�15202323131�0017225�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-iso-8859-14.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 2c8651cfc08b1f35b17919ee5379f2fa006af3ec809f11b3b7f470785580542b # Date: 2018-01-06 0 0x0080 € (<control>) 1 0x0081  (<control>) 2 0x0082 ‚ (<control>) 3 0x0083 ƒ (<control>) 4 0x0084 „ (<control>) 5 0x0085 … (<control>) 6 0x0086 † (<control>) 7 0x0087 ‡ (<control>) 8 0x0088 ˆ (<control>) 9 0x0089 ‰ (<control>) 10 0x008A Š (<control>) 11 0x008B ‹ (<control>) 12 0x008C Œ (<control>) 13 0x008D  (<control>) 14 0x008E Ž (<control>) 15 0x008F  (<control>) 16 0x0090  (<control>) 17 0x0091 ‘ (<control>) 18 0x0092 ’ (<control>) 19 0x0093 “ (<control>) 20 0x0094 ” (<control>) 21 0x0095 • (<control>) 22 0x0096 – (<control>) 23 0x0097 — (<control>) 24 0x0098 ˜ (<control>) 25 0x0099 ™ (<control>) 26 0x009A š (<control>) 27 0x009B › (<control>) 28 0x009C œ (<control>) 29 0x009D  (<control>) 30 0x009E ž (<control>) 31 0x009F Ÿ (<control>) 32 0x00A0   (NO-BREAK SPACE) 33 0x1E02 Ḃ (LATIN CAPITAL LETTER B WITH DOT ABOVE) 34 0x1E03 ḃ (LATIN SMALL LETTER B WITH DOT ABOVE) 35 0x00A3 £ (POUND SIGN) 36 0x010A Ċ (LATIN CAPITAL LETTER C WITH DOT ABOVE) 37 0x010B ċ (LATIN SMALL LETTER C WITH DOT ABOVE) 38 0x1E0A Ḋ (LATIN CAPITAL LETTER D WITH DOT ABOVE) 39 0x00A7 § (SECTION SIGN) 40 0x1E80 Ẁ (LATIN CAPITAL LETTER W WITH GRAVE) 41 0x00A9 © (COPYRIGHT SIGN) 42 0x1E82 Ẃ (LATIN CAPITAL LETTER W WITH ACUTE) 43 0x1E0B ḋ (LATIN SMALL LETTER D WITH DOT ABOVE) 44 0x1EF2 Ỳ (LATIN CAPITAL LETTER Y WITH GRAVE) 45 0x00AD ­ (SOFT HYPHEN) 46 0x00AE ® (REGISTERED SIGN) 47 0x0178 Ÿ (LATIN CAPITAL LETTER Y WITH DIAERESIS) 48 0x1E1E Ḟ (LATIN CAPITAL LETTER F WITH DOT ABOVE) 49 0x1E1F ḟ (LATIN SMALL LETTER F WITH DOT ABOVE) 50 0x0120 Ġ (LATIN CAPITAL LETTER G WITH DOT ABOVE) 51 0x0121 ġ (LATIN SMALL LETTER G WITH DOT ABOVE) 52 0x1E40 Ṁ (LATIN CAPITAL LETTER M WITH DOT ABOVE) 53 0x1E41 ṁ (LATIN SMALL LETTER M WITH DOT ABOVE) 54 0x00B6 ¶ (PILCROW SIGN) 55 0x1E56 Ṗ (LATIN CAPITAL LETTER P WITH DOT ABOVE) 56 0x1E81 ẁ (LATIN SMALL LETTER W WITH GRAVE) 57 0x1E57 ṗ (LATIN SMALL LETTER P WITH DOT ABOVE) 58 0x1E83 ẃ (LATIN SMALL LETTER W WITH ACUTE) 59 0x1E60 Ṡ (LATIN CAPITAL LETTER S WITH DOT ABOVE) 60 0x1EF3 ỳ (LATIN SMALL LETTER Y WITH GRAVE) 61 0x1E84 Ẅ (LATIN CAPITAL LETTER W WITH DIAERESIS) 62 0x1E85 ẅ (LATIN SMALL LETTER W WITH DIAERESIS) 63 0x1E61 ṡ (LATIN SMALL LETTER S WITH DOT ABOVE) 64 0x00C0 À (LATIN CAPITAL LETTER A WITH GRAVE) 65 0x00C1 Á (LATIN CAPITAL LETTER A WITH ACUTE) 66 0x00C2  (LATIN CAPITAL LETTER A WITH CIRCUMFLEX) 67 0x00C3 à (LATIN CAPITAL LETTER A WITH TILDE) 68 0x00C4 Ä (LATIN CAPITAL LETTER A WITH DIAERESIS) 69 0x00C5 Å (LATIN CAPITAL LETTER A WITH RING ABOVE) 70 0x00C6 Æ (LATIN CAPITAL LETTER AE) 71 0x00C7 Ç (LATIN CAPITAL LETTER C WITH CEDILLA) 72 0x00C8 È (LATIN CAPITAL LETTER E WITH GRAVE) 73 0x00C9 É (LATIN CAPITAL LETTER E WITH ACUTE) 74 0x00CA Ê (LATIN CAPITAL LETTER E WITH CIRCUMFLEX) 75 0x00CB Ë (LATIN CAPITAL LETTER E WITH DIAERESIS) 76 0x00CC Ì (LATIN CAPITAL LETTER I WITH GRAVE) 77 0x00CD Í (LATIN CAPITAL LETTER I WITH ACUTE) 78 0x00CE Î (LATIN CAPITAL LETTER I WITH CIRCUMFLEX) 79 0x00CF Ï (LATIN CAPITAL LETTER I WITH DIAERESIS) 80 0x0174 Ŵ (LATIN CAPITAL LETTER W WITH CIRCUMFLEX) 81 0x00D1 Ñ (LATIN CAPITAL LETTER N WITH TILDE) 82 0x00D2 Ò (LATIN CAPITAL LETTER O WITH GRAVE) 83 0x00D3 Ó (LATIN CAPITAL LETTER O WITH ACUTE) 84 0x00D4 Ô (LATIN CAPITAL LETTER O WITH CIRCUMFLEX) 85 0x00D5 Õ (LATIN CAPITAL LETTER O WITH TILDE) 86 0x00D6 Ö (LATIN CAPITAL LETTER O WITH DIAERESIS) 87 0x1E6A Ṫ (LATIN CAPITAL LETTER T WITH DOT ABOVE) 88 0x00D8 Ø (LATIN CAPITAL LETTER O WITH STROKE) 89 0x00D9 Ù (LATIN CAPITAL LETTER U WITH GRAVE) 90 0x00DA Ú (LATIN CAPITAL LETTER U WITH ACUTE) 91 0x00DB Û (LATIN CAPITAL LETTER U WITH CIRCUMFLEX) 92 0x00DC Ü (LATIN CAPITAL LETTER U WITH DIAERESIS) 93 0x00DD Ý (LATIN CAPITAL LETTER Y WITH ACUTE) 94 0x0176 Ŷ (LATIN CAPITAL LETTER Y WITH CIRCUMFLEX) 95 0x00DF ß (LATIN SMALL LETTER SHARP S) 96 0x00E0 à (LATIN SMALL LETTER A WITH GRAVE) 97 0x00E1 á (LATIN SMALL LETTER A WITH ACUTE) 98 0x00E2 â (LATIN SMALL LETTER A WITH CIRCUMFLEX) 99 0x00E3 ã (LATIN SMALL LETTER A WITH TILDE) 100 0x00E4 ä (LATIN SMALL LETTER A WITH DIAERESIS) 101 0x00E5 å (LATIN SMALL LETTER A WITH RING ABOVE) 102 0x00E6 æ (LATIN SMALL LETTER AE) 103 0x00E7 ç (LATIN SMALL LETTER C WITH CEDILLA) 104 0x00E8 è (LATIN SMALL LETTER E WITH GRAVE) 105 0x00E9 é (LATIN SMALL LETTER E WITH ACUTE) 106 0x00EA ê (LATIN SMALL LETTER E WITH CIRCUMFLEX) 107 0x00EB ë (LATIN SMALL LETTER E WITH DIAERESIS) 108 0x00EC ì (LATIN SMALL LETTER I WITH GRAVE) 109 0x00ED í (LATIN SMALL LETTER I WITH ACUTE) 110 0x00EE î (LATIN SMALL LETTER I WITH CIRCUMFLEX) 111 0x00EF ï (LATIN SMALL LETTER I WITH DIAERESIS) 112 0x0175 ŵ (LATIN SMALL LETTER W WITH CIRCUMFLEX) 113 0x00F1 ñ (LATIN SMALL LETTER N WITH TILDE) 114 0x00F2 ò (LATIN SMALL LETTER O WITH GRAVE) 115 0x00F3 ó (LATIN SMALL LETTER O WITH ACUTE) 116 0x00F4 ô (LATIN SMALL LETTER O WITH CIRCUMFLEX) 117 0x00F5 õ (LATIN SMALL LETTER O WITH TILDE) 118 0x00F6 ö (LATIN SMALL LETTER O WITH DIAERESIS) 119 0x1E6B ṫ (LATIN SMALL LETTER T WITH DOT ABOVE) 120 0x00F8 ø (LATIN SMALL LETTER O WITH STROKE) 121 0x00F9 ù (LATIN SMALL LETTER U WITH GRAVE) 122 0x00FA ú (LATIN SMALL LETTER U WITH ACUTE) 123 0x00FB û (LATIN SMALL LETTER U WITH CIRCUMFLEX) 124 0x00FC ü (LATIN SMALL LETTER U WITH DIAERESIS) 125 0x00FD ý (LATIN SMALL LETTER Y WITH ACUTE) 126 0x0177 ŷ (LATIN SMALL LETTER Y WITH CIRCUMFLEX) 127 0x00FF ÿ (LATIN SMALL LETTER Y WITH DIAERESIS) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-iso-8859-15.txt�������������������������������������������������������������0000664�0000000�0000000�00000012355�15202323131�0017227�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-iso-8859-15.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: a560aba47bccd7510a6ac77f671fe75dca3800f05cf6d676910c311a8f8ff079 # Date: 2018-01-06 0 0x0080 € (<control>) 1 0x0081  (<control>) 2 0x0082 ‚ (<control>) 3 0x0083 ƒ (<control>) 4 0x0084 „ (<control>) 5 0x0085 … (<control>) 6 0x0086 † (<control>) 7 0x0087 ‡ (<control>) 8 0x0088 ˆ (<control>) 9 0x0089 ‰ (<control>) 10 0x008A Š (<control>) 11 0x008B ‹ (<control>) 12 0x008C Œ (<control>) 13 0x008D  (<control>) 14 0x008E Ž (<control>) 15 0x008F  (<control>) 16 0x0090  (<control>) 17 0x0091 ‘ (<control>) 18 0x0092 ’ (<control>) 19 0x0093 “ (<control>) 20 0x0094 ” (<control>) 21 0x0095 • (<control>) 22 0x0096 – (<control>) 23 0x0097 — (<control>) 24 0x0098 ˜ (<control>) 25 0x0099 ™ (<control>) 26 0x009A š (<control>) 27 0x009B › (<control>) 28 0x009C œ (<control>) 29 0x009D  (<control>) 30 0x009E ž (<control>) 31 0x009F Ÿ (<control>) 32 0x00A0   (NO-BREAK SPACE) 33 0x00A1 ¡ (INVERTED EXCLAMATION MARK) 34 0x00A2 ¢ (CENT SIGN) 35 0x00A3 £ (POUND SIGN) 36 0x20AC € (EURO SIGN) 37 0x00A5 ¥ (YEN SIGN) 38 0x0160 Š (LATIN CAPITAL LETTER S WITH CARON) 39 0x00A7 § (SECTION SIGN) 40 0x0161 š (LATIN SMALL LETTER S WITH CARON) 41 0x00A9 © (COPYRIGHT SIGN) 42 0x00AA ª (FEMININE ORDINAL INDICATOR) 43 0x00AB « (LEFT-POINTING DOUBLE ANGLE QUOTATION MARK) 44 0x00AC ¬ (NOT SIGN) 45 0x00AD ­ (SOFT HYPHEN) 46 0x00AE ® (REGISTERED SIGN) 47 0x00AF ¯ (MACRON) 48 0x00B0 ° (DEGREE SIGN) 49 0x00B1 ± (PLUS-MINUS SIGN) 50 0x00B2 ² (SUPERSCRIPT TWO) 51 0x00B3 ³ (SUPERSCRIPT THREE) 52 0x017D Ž (LATIN CAPITAL LETTER Z WITH CARON) 53 0x00B5 µ (MICRO SIGN) 54 0x00B6 ¶ (PILCROW SIGN) 55 0x00B7 · (MIDDLE DOT) 56 0x017E ž (LATIN SMALL LETTER Z WITH CARON) 57 0x00B9 ¹ (SUPERSCRIPT ONE) 58 0x00BA º (MASCULINE ORDINAL INDICATOR) 59 0x00BB » (RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK) 60 0x0152 Œ (LATIN CAPITAL LIGATURE OE) 61 0x0153 œ (LATIN SMALL LIGATURE OE) 62 0x0178 Ÿ (LATIN CAPITAL LETTER Y WITH DIAERESIS) 63 0x00BF ¿ (INVERTED QUESTION MARK) 64 0x00C0 À (LATIN CAPITAL LETTER A WITH GRAVE) 65 0x00C1 Á (LATIN CAPITAL LETTER A WITH ACUTE) 66 0x00C2  (LATIN CAPITAL LETTER A WITH CIRCUMFLEX) 67 0x00C3 à (LATIN CAPITAL LETTER A WITH TILDE) 68 0x00C4 Ä (LATIN CAPITAL LETTER A WITH DIAERESIS) 69 0x00C5 Å (LATIN CAPITAL LETTER A WITH RING ABOVE) 70 0x00C6 Æ (LATIN CAPITAL LETTER AE) 71 0x00C7 Ç (LATIN CAPITAL LETTER C WITH CEDILLA) 72 0x00C8 È (LATIN CAPITAL LETTER E WITH GRAVE) 73 0x00C9 É (LATIN CAPITAL LETTER E WITH ACUTE) 74 0x00CA Ê (LATIN CAPITAL LETTER E WITH CIRCUMFLEX) 75 0x00CB Ë (LATIN CAPITAL LETTER E WITH DIAERESIS) 76 0x00CC Ì (LATIN CAPITAL LETTER I WITH GRAVE) 77 0x00CD Í (LATIN CAPITAL LETTER I WITH ACUTE) 78 0x00CE Î (LATIN CAPITAL LETTER I WITH CIRCUMFLEX) 79 0x00CF Ï (LATIN CAPITAL LETTER I WITH DIAERESIS) 80 0x00D0 Ð (LATIN CAPITAL LETTER ETH) 81 0x00D1 Ñ (LATIN CAPITAL LETTER N WITH TILDE) 82 0x00D2 Ò (LATIN CAPITAL LETTER O WITH GRAVE) 83 0x00D3 Ó (LATIN CAPITAL LETTER O WITH ACUTE) 84 0x00D4 Ô (LATIN CAPITAL LETTER O WITH CIRCUMFLEX) 85 0x00D5 Õ (LATIN CAPITAL LETTER O WITH TILDE) 86 0x00D6 Ö (LATIN CAPITAL LETTER O WITH DIAERESIS) 87 0x00D7 × (MULTIPLICATION SIGN) 88 0x00D8 Ø (LATIN CAPITAL LETTER O WITH STROKE) 89 0x00D9 Ù (LATIN CAPITAL LETTER U WITH GRAVE) 90 0x00DA Ú (LATIN CAPITAL LETTER U WITH ACUTE) 91 0x00DB Û (LATIN CAPITAL LETTER U WITH CIRCUMFLEX) 92 0x00DC Ü (LATIN CAPITAL LETTER U WITH DIAERESIS) 93 0x00DD Ý (LATIN CAPITAL LETTER Y WITH ACUTE) 94 0x00DE Þ (LATIN CAPITAL LETTER THORN) 95 0x00DF ß (LATIN SMALL LETTER SHARP S) 96 0x00E0 à (LATIN SMALL LETTER A WITH GRAVE) 97 0x00E1 á (LATIN SMALL LETTER A WITH ACUTE) 98 0x00E2 â (LATIN SMALL LETTER A WITH CIRCUMFLEX) 99 0x00E3 ã (LATIN SMALL LETTER A WITH TILDE) 100 0x00E4 ä (LATIN SMALL LETTER A WITH DIAERESIS) 101 0x00E5 å (LATIN SMALL LETTER A WITH RING ABOVE) 102 0x00E6 æ (LATIN SMALL LETTER AE) 103 0x00E7 ç (LATIN SMALL LETTER C WITH CEDILLA) 104 0x00E8 è (LATIN SMALL LETTER E WITH GRAVE) 105 0x00E9 é (LATIN SMALL LETTER E WITH ACUTE) 106 0x00EA ê (LATIN SMALL LETTER E WITH CIRCUMFLEX) 107 0x00EB ë (LATIN SMALL LETTER E WITH DIAERESIS) 108 0x00EC ì (LATIN SMALL LETTER I WITH GRAVE) 109 0x00ED í (LATIN SMALL LETTER I WITH ACUTE) 110 0x00EE î (LATIN SMALL LETTER I WITH CIRCUMFLEX) 111 0x00EF ï (LATIN SMALL LETTER I WITH DIAERESIS) 112 0x00F0 ð (LATIN SMALL LETTER ETH) 113 0x00F1 ñ (LATIN SMALL LETTER N WITH TILDE) 114 0x00F2 ò (LATIN SMALL LETTER O WITH GRAVE) 115 0x00F3 ó (LATIN SMALL LETTER O WITH ACUTE) 116 0x00F4 ô (LATIN SMALL LETTER O WITH CIRCUMFLEX) 117 0x00F5 õ (LATIN SMALL LETTER O WITH TILDE) 118 0x00F6 ö (LATIN SMALL LETTER O WITH DIAERESIS) 119 0x00F7 ÷ (DIVISION SIGN) 120 0x00F8 ø (LATIN SMALL LETTER O WITH STROKE) 121 0x00F9 ù (LATIN SMALL LETTER U WITH GRAVE) 122 0x00FA ú (LATIN SMALL LETTER U WITH ACUTE) 123 0x00FB û (LATIN SMALL LETTER U WITH CIRCUMFLEX) 124 0x00FC ü (LATIN SMALL LETTER U WITH DIAERESIS) 125 0x00FD ý (LATIN SMALL LETTER Y WITH ACUTE) 126 0x00FE þ (LATIN SMALL LETTER THORN) 127 0x00FF ÿ (LATIN SMALL LETTER Y WITH DIAERESIS) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-iso-8859-16.txt�������������������������������������������������������������0000664�0000000�0000000�00000013110�15202323131�0017216�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-iso-8859-16.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 55676320d2d1b6e6909f5b3d741a7cf0cefc84e920aa4474afc091459111c2e3 # Date: 2018-01-06 0 0x0080 € (<control>) 1 0x0081  (<control>) 2 0x0082 ‚ (<control>) 3 0x0083 ƒ (<control>) 4 0x0084 „ (<control>) 5 0x0085 … (<control>) 6 0x0086 † (<control>) 7 0x0087 ‡ (<control>) 8 0x0088 ˆ (<control>) 9 0x0089 ‰ (<control>) 10 0x008A Š (<control>) 11 0x008B ‹ (<control>) 12 0x008C Œ (<control>) 13 0x008D  (<control>) 14 0x008E Ž (<control>) 15 0x008F  (<control>) 16 0x0090  (<control>) 17 0x0091 ‘ (<control>) 18 0x0092 ’ (<control>) 19 0x0093 “ (<control>) 20 0x0094 ” (<control>) 21 0x0095 • (<control>) 22 0x0096 – (<control>) 23 0x0097 — (<control>) 24 0x0098 ˜ (<control>) 25 0x0099 ™ (<control>) 26 0x009A š (<control>) 27 0x009B › (<control>) 28 0x009C œ (<control>) 29 0x009D  (<control>) 30 0x009E ž (<control>) 31 0x009F Ÿ (<control>) 32 0x00A0   (NO-BREAK SPACE) 33 0x0104 Ą (LATIN CAPITAL LETTER A WITH OGONEK) 34 0x0105 ą (LATIN SMALL LETTER A WITH OGONEK) 35 0x0141 Ł (LATIN CAPITAL LETTER L WITH STROKE) 36 0x20AC € (EURO SIGN) 37 0x201E „ (DOUBLE LOW-9 QUOTATION MARK) 38 0x0160 Š (LATIN CAPITAL LETTER S WITH CARON) 39 0x00A7 § (SECTION SIGN) 40 0x0161 š (LATIN SMALL LETTER S WITH CARON) 41 0x00A9 © (COPYRIGHT SIGN) 42 0x0218 Ș (LATIN CAPITAL LETTER S WITH COMMA BELOW) 43 0x00AB « (LEFT-POINTING DOUBLE ANGLE QUOTATION MARK) 44 0x0179 Ź (LATIN CAPITAL LETTER Z WITH ACUTE) 45 0x00AD ­ (SOFT HYPHEN) 46 0x017A ź (LATIN SMALL LETTER Z WITH ACUTE) 47 0x017B Ż (LATIN CAPITAL LETTER Z WITH DOT ABOVE) 48 0x00B0 ° (DEGREE SIGN) 49 0x00B1 ± (PLUS-MINUS SIGN) 50 0x010C Č (LATIN CAPITAL LETTER C WITH CARON) 51 0x0142 ł (LATIN SMALL LETTER L WITH STROKE) 52 0x017D Ž (LATIN CAPITAL LETTER Z WITH CARON) 53 0x201D ” (RIGHT DOUBLE QUOTATION MARK) 54 0x00B6 ¶ (PILCROW SIGN) 55 0x00B7 · (MIDDLE DOT) 56 0x017E ž (LATIN SMALL LETTER Z WITH CARON) 57 0x010D č (LATIN SMALL LETTER C WITH CARON) 58 0x0219 ș (LATIN SMALL LETTER S WITH COMMA BELOW) 59 0x00BB » (RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK) 60 0x0152 Œ (LATIN CAPITAL LIGATURE OE) 61 0x0153 œ (LATIN SMALL LIGATURE OE) 62 0x0178 Ÿ (LATIN CAPITAL LETTER Y WITH DIAERESIS) 63 0x017C ż (LATIN SMALL LETTER Z WITH DOT ABOVE) 64 0x00C0 À (LATIN CAPITAL LETTER A WITH GRAVE) 65 0x00C1 Á (LATIN CAPITAL LETTER A WITH ACUTE) 66 0x00C2  (LATIN CAPITAL LETTER A WITH CIRCUMFLEX) 67 0x0102 Ă (LATIN CAPITAL LETTER A WITH BREVE) 68 0x00C4 Ä (LATIN CAPITAL LETTER A WITH DIAERESIS) 69 0x0106 Ć (LATIN CAPITAL LETTER C WITH ACUTE) 70 0x00C6 Æ (LATIN CAPITAL LETTER AE) 71 0x00C7 Ç (LATIN CAPITAL LETTER C WITH CEDILLA) 72 0x00C8 È (LATIN CAPITAL LETTER E WITH GRAVE) 73 0x00C9 É (LATIN CAPITAL LETTER E WITH ACUTE) 74 0x00CA Ê (LATIN CAPITAL LETTER E WITH CIRCUMFLEX) 75 0x00CB Ë (LATIN CAPITAL LETTER E WITH DIAERESIS) 76 0x00CC Ì (LATIN CAPITAL LETTER I WITH GRAVE) 77 0x00CD Í (LATIN CAPITAL LETTER I WITH ACUTE) 78 0x00CE Î (LATIN CAPITAL LETTER I WITH CIRCUMFLEX) 79 0x00CF Ï (LATIN CAPITAL LETTER I WITH DIAERESIS) 80 0x0110 Đ (LATIN CAPITAL LETTER D WITH STROKE) 81 0x0143 Ń (LATIN CAPITAL LETTER N WITH ACUTE) 82 0x00D2 Ò (LATIN CAPITAL LETTER O WITH GRAVE) 83 0x00D3 Ó (LATIN CAPITAL LETTER O WITH ACUTE) 84 0x00D4 Ô (LATIN CAPITAL LETTER O WITH CIRCUMFLEX) 85 0x0150 Ő (LATIN CAPITAL LETTER O WITH DOUBLE ACUTE) 86 0x00D6 Ö (LATIN CAPITAL LETTER O WITH DIAERESIS) 87 0x015A Ś (LATIN CAPITAL LETTER S WITH ACUTE) 88 0x0170 Ű (LATIN CAPITAL LETTER U WITH DOUBLE ACUTE) 89 0x00D9 Ù (LATIN CAPITAL LETTER U WITH GRAVE) 90 0x00DA Ú (LATIN CAPITAL LETTER U WITH ACUTE) 91 0x00DB Û (LATIN CAPITAL LETTER U WITH CIRCUMFLEX) 92 0x00DC Ü (LATIN CAPITAL LETTER U WITH DIAERESIS) 93 0x0118 Ę (LATIN CAPITAL LETTER E WITH OGONEK) 94 0x021A Ț (LATIN CAPITAL LETTER T WITH COMMA BELOW) 95 0x00DF ß (LATIN SMALL LETTER SHARP S) 96 0x00E0 à (LATIN SMALL LETTER A WITH GRAVE) 97 0x00E1 á (LATIN SMALL LETTER A WITH ACUTE) 98 0x00E2 â (LATIN SMALL LETTER A WITH CIRCUMFLEX) 99 0x0103 ă (LATIN SMALL LETTER A WITH BREVE) 100 0x00E4 ä (LATIN SMALL LETTER A WITH DIAERESIS) 101 0x0107 ć (LATIN SMALL LETTER C WITH ACUTE) 102 0x00E6 æ (LATIN SMALL LETTER AE) 103 0x00E7 ç (LATIN SMALL LETTER C WITH CEDILLA) 104 0x00E8 è (LATIN SMALL LETTER E WITH GRAVE) 105 0x00E9 é (LATIN SMALL LETTER E WITH ACUTE) 106 0x00EA ê (LATIN SMALL LETTER E WITH CIRCUMFLEX) 107 0x00EB ë (LATIN SMALL LETTER E WITH DIAERESIS) 108 0x00EC ì (LATIN SMALL LETTER I WITH GRAVE) 109 0x00ED í (LATIN SMALL LETTER I WITH ACUTE) 110 0x00EE î (LATIN SMALL LETTER I WITH CIRCUMFLEX) 111 0x00EF ï (LATIN SMALL LETTER I WITH DIAERESIS) 112 0x0111 đ (LATIN SMALL LETTER D WITH STROKE) 113 0x0144 ń (LATIN SMALL LETTER N WITH ACUTE) 114 0x00F2 ò (LATIN SMALL LETTER O WITH GRAVE) 115 0x00F3 ó (LATIN SMALL LETTER O WITH ACUTE) 116 0x00F4 ô (LATIN SMALL LETTER O WITH CIRCUMFLEX) 117 0x0151 ő (LATIN SMALL LETTER O WITH DOUBLE ACUTE) 118 0x00F6 ö (LATIN SMALL LETTER O WITH DIAERESIS) 119 0x015B ś (LATIN SMALL LETTER S WITH ACUTE) 120 0x0171 ű (LATIN SMALL LETTER U WITH DOUBLE ACUTE) 121 0x00F9 ù (LATIN SMALL LETTER U WITH GRAVE) 122 0x00FA ú (LATIN SMALL LETTER U WITH ACUTE) 123 0x00FB û (LATIN SMALL LETTER U WITH CIRCUMFLEX) 124 0x00FC ü (LATIN SMALL LETTER U WITH DIAERESIS) 125 0x0119 ę (LATIN SMALL LETTER E WITH OGONEK) 126 0x021B ț (LATIN SMALL LETTER T WITH COMMA BELOW) 127 0x00FF ÿ (LATIN SMALL LETTER Y WITH DIAERESIS) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-iso-8859-2.txt��������������������������������������������������������������0000664�0000000�0000000�00000012656�15202323131�0017147�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-iso-8859-2.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 9569c67f22d0b57790e1c407c6eecf227e4562322dc296de43cdab7a0152ec73 # Date: 2018-01-06 0 0x0080 € (<control>) 1 0x0081  (<control>) 2 0x0082 ‚ (<control>) 3 0x0083 ƒ (<control>) 4 0x0084 „ (<control>) 5 0x0085 … (<control>) 6 0x0086 † (<control>) 7 0x0087 ‡ (<control>) 8 0x0088 ˆ (<control>) 9 0x0089 ‰ (<control>) 10 0x008A Š (<control>) 11 0x008B ‹ (<control>) 12 0x008C Œ (<control>) 13 0x008D  (<control>) 14 0x008E Ž (<control>) 15 0x008F  (<control>) 16 0x0090  (<control>) 17 0x0091 ‘ (<control>) 18 0x0092 ’ (<control>) 19 0x0093 “ (<control>) 20 0x0094 ” (<control>) 21 0x0095 • (<control>) 22 0x0096 – (<control>) 23 0x0097 — (<control>) 24 0x0098 ˜ (<control>) 25 0x0099 ™ (<control>) 26 0x009A š (<control>) 27 0x009B › (<control>) 28 0x009C œ (<control>) 29 0x009D  (<control>) 30 0x009E ž (<control>) 31 0x009F Ÿ (<control>) 32 0x00A0   (NO-BREAK SPACE) 33 0x0104 Ą (LATIN CAPITAL LETTER A WITH OGONEK) 34 0x02D8 ˘ (BREVE) 35 0x0141 Ł (LATIN CAPITAL LETTER L WITH STROKE) 36 0x00A4 ¤ (CURRENCY SIGN) 37 0x013D Ľ (LATIN CAPITAL LETTER L WITH CARON) 38 0x015A Ś (LATIN CAPITAL LETTER S WITH ACUTE) 39 0x00A7 § (SECTION SIGN) 40 0x00A8 ¨ (DIAERESIS) 41 0x0160 Š (LATIN CAPITAL LETTER S WITH CARON) 42 0x015E Ş (LATIN CAPITAL LETTER S WITH CEDILLA) 43 0x0164 Ť (LATIN CAPITAL LETTER T WITH CARON) 44 0x0179 Ź (LATIN CAPITAL LETTER Z WITH ACUTE) 45 0x00AD ­ (SOFT HYPHEN) 46 0x017D Ž (LATIN CAPITAL LETTER Z WITH CARON) 47 0x017B Ż (LATIN CAPITAL LETTER Z WITH DOT ABOVE) 48 0x00B0 ° (DEGREE SIGN) 49 0x0105 ą (LATIN SMALL LETTER A WITH OGONEK) 50 0x02DB ˛ (OGONEK) 51 0x0142 ł (LATIN SMALL LETTER L WITH STROKE) 52 0x00B4 ´ (ACUTE ACCENT) 53 0x013E ľ (LATIN SMALL LETTER L WITH CARON) 54 0x015B ś (LATIN SMALL LETTER S WITH ACUTE) 55 0x02C7 ˇ (CARON) 56 0x00B8 ¸ (CEDILLA) 57 0x0161 š (LATIN SMALL LETTER S WITH CARON) 58 0x015F ş (LATIN SMALL LETTER S WITH CEDILLA) 59 0x0165 ť (LATIN SMALL LETTER T WITH CARON) 60 0x017A ź (LATIN SMALL LETTER Z WITH ACUTE) 61 0x02DD ˝ (DOUBLE ACUTE ACCENT) 62 0x017E ž (LATIN SMALL LETTER Z WITH CARON) 63 0x017C ż (LATIN SMALL LETTER Z WITH DOT ABOVE) 64 0x0154 Ŕ (LATIN CAPITAL LETTER R WITH ACUTE) 65 0x00C1 Á (LATIN CAPITAL LETTER A WITH ACUTE) 66 0x00C2  (LATIN CAPITAL LETTER A WITH CIRCUMFLEX) 67 0x0102 Ă (LATIN CAPITAL LETTER A WITH BREVE) 68 0x00C4 Ä (LATIN CAPITAL LETTER A WITH DIAERESIS) 69 0x0139 Ĺ (LATIN CAPITAL LETTER L WITH ACUTE) 70 0x0106 Ć (LATIN CAPITAL LETTER C WITH ACUTE) 71 0x00C7 Ç (LATIN CAPITAL LETTER C WITH CEDILLA) 72 0x010C Č (LATIN CAPITAL LETTER C WITH CARON) 73 0x00C9 É (LATIN CAPITAL LETTER E WITH ACUTE) 74 0x0118 Ę (LATIN CAPITAL LETTER E WITH OGONEK) 75 0x00CB Ë (LATIN CAPITAL LETTER E WITH DIAERESIS) 76 0x011A Ě (LATIN CAPITAL LETTER E WITH CARON) 77 0x00CD Í (LATIN CAPITAL LETTER I WITH ACUTE) 78 0x00CE Î (LATIN CAPITAL LETTER I WITH CIRCUMFLEX) 79 0x010E Ď (LATIN CAPITAL LETTER D WITH CARON) 80 0x0110 Đ (LATIN CAPITAL LETTER D WITH STROKE) 81 0x0143 Ń (LATIN CAPITAL LETTER N WITH ACUTE) 82 0x0147 Ň (LATIN CAPITAL LETTER N WITH CARON) 83 0x00D3 Ó (LATIN CAPITAL LETTER O WITH ACUTE) 84 0x00D4 Ô (LATIN CAPITAL LETTER O WITH CIRCUMFLEX) 85 0x0150 Ő (LATIN CAPITAL LETTER O WITH DOUBLE ACUTE) 86 0x00D6 Ö (LATIN CAPITAL LETTER O WITH DIAERESIS) 87 0x00D7 × (MULTIPLICATION SIGN) 88 0x0158 Ř (LATIN CAPITAL LETTER R WITH CARON) 89 0x016E Ů (LATIN CAPITAL LETTER U WITH RING ABOVE) 90 0x00DA Ú (LATIN CAPITAL LETTER U WITH ACUTE) 91 0x0170 Ű (LATIN CAPITAL LETTER U WITH DOUBLE ACUTE) 92 0x00DC Ü (LATIN CAPITAL LETTER U WITH DIAERESIS) 93 0x00DD Ý (LATIN CAPITAL LETTER Y WITH ACUTE) 94 0x0162 Ţ (LATIN CAPITAL LETTER T WITH CEDILLA) 95 0x00DF ß (LATIN SMALL LETTER SHARP S) 96 0x0155 ŕ (LATIN SMALL LETTER R WITH ACUTE) 97 0x00E1 á (LATIN SMALL LETTER A WITH ACUTE) 98 0x00E2 â (LATIN SMALL LETTER A WITH CIRCUMFLEX) 99 0x0103 ă (LATIN SMALL LETTER A WITH BREVE) 100 0x00E4 ä (LATIN SMALL LETTER A WITH DIAERESIS) 101 0x013A ĺ (LATIN SMALL LETTER L WITH ACUTE) 102 0x0107 ć (LATIN SMALL LETTER C WITH ACUTE) 103 0x00E7 ç (LATIN SMALL LETTER C WITH CEDILLA) 104 0x010D č (LATIN SMALL LETTER C WITH CARON) 105 0x00E9 é (LATIN SMALL LETTER E WITH ACUTE) 106 0x0119 ę (LATIN SMALL LETTER E WITH OGONEK) 107 0x00EB ë (LATIN SMALL LETTER E WITH DIAERESIS) 108 0x011B ě (LATIN SMALL LETTER E WITH CARON) 109 0x00ED í (LATIN SMALL LETTER I WITH ACUTE) 110 0x00EE î (LATIN SMALL LETTER I WITH CIRCUMFLEX) 111 0x010F ď (LATIN SMALL LETTER D WITH CARON) 112 0x0111 đ (LATIN SMALL LETTER D WITH STROKE) 113 0x0144 ń (LATIN SMALL LETTER N WITH ACUTE) 114 0x0148 ň (LATIN SMALL LETTER N WITH CARON) 115 0x00F3 ó (LATIN SMALL LETTER O WITH ACUTE) 116 0x00F4 ô (LATIN SMALL LETTER O WITH CIRCUMFLEX) 117 0x0151 ő (LATIN SMALL LETTER O WITH DOUBLE ACUTE) 118 0x00F6 ö (LATIN SMALL LETTER O WITH DIAERESIS) 119 0x00F7 ÷ (DIVISION SIGN) 120 0x0159 ř (LATIN SMALL LETTER R WITH CARON) 121 0x016F ů (LATIN SMALL LETTER U WITH RING ABOVE) 122 0x00FA ú (LATIN SMALL LETTER U WITH ACUTE) 123 0x0171 ű (LATIN SMALL LETTER U WITH DOUBLE ACUTE) 124 0x00FC ü (LATIN SMALL LETTER U WITH DIAERESIS) 125 0x00FD ý (LATIN SMALL LETTER Y WITH ACUTE) 126 0x0163 ţ (LATIN SMALL LETTER T WITH CEDILLA) 127 0x02D9 ˙ (DOT ABOVE) ����������������������������������������������������������������������������������chawan-v0.4.0/res/index-iso-8859-3.txt��������������������������������������������������������������0000664�0000000�0000000�00000012136�15202323131�0017141�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-iso-8859-3.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: af8f1e12df79b768322b5e83613698cdc619438270a2fc359554331c805054a3 # Date: 2018-01-06 0 0x0080 € (<control>) 1 0x0081  (<control>) 2 0x0082 ‚ (<control>) 3 0x0083 ƒ (<control>) 4 0x0084 „ (<control>) 5 0x0085 … (<control>) 6 0x0086 † (<control>) 7 0x0087 ‡ (<control>) 8 0x0088 ˆ (<control>) 9 0x0089 ‰ (<control>) 10 0x008A Š (<control>) 11 0x008B ‹ (<control>) 12 0x008C Œ (<control>) 13 0x008D  (<control>) 14 0x008E Ž (<control>) 15 0x008F  (<control>) 16 0x0090  (<control>) 17 0x0091 ‘ (<control>) 18 0x0092 ’ (<control>) 19 0x0093 “ (<control>) 20 0x0094 ” (<control>) 21 0x0095 • (<control>) 22 0x0096 – (<control>) 23 0x0097 — (<control>) 24 0x0098 ˜ (<control>) 25 0x0099 ™ (<control>) 26 0x009A š (<control>) 27 0x009B › (<control>) 28 0x009C œ (<control>) 29 0x009D  (<control>) 30 0x009E ž (<control>) 31 0x009F Ÿ (<control>) 32 0x00A0   (NO-BREAK SPACE) 33 0x0126 Ħ (LATIN CAPITAL LETTER H WITH STROKE) 34 0x02D8 ˘ (BREVE) 35 0x00A3 £ (POUND SIGN) 36 0x00A4 ¤ (CURRENCY SIGN) 38 0x0124 Ĥ (LATIN CAPITAL LETTER H WITH CIRCUMFLEX) 39 0x00A7 § (SECTION SIGN) 40 0x00A8 ¨ (DIAERESIS) 41 0x0130 İ (LATIN CAPITAL LETTER I WITH DOT ABOVE) 42 0x015E Ş (LATIN CAPITAL LETTER S WITH CEDILLA) 43 0x011E Ğ (LATIN CAPITAL LETTER G WITH BREVE) 44 0x0134 Ĵ (LATIN CAPITAL LETTER J WITH CIRCUMFLEX) 45 0x00AD ­ (SOFT HYPHEN) 47 0x017B Ż (LATIN CAPITAL LETTER Z WITH DOT ABOVE) 48 0x00B0 ° (DEGREE SIGN) 49 0x0127 ħ (LATIN SMALL LETTER H WITH STROKE) 50 0x00B2 ² (SUPERSCRIPT TWO) 51 0x00B3 ³ (SUPERSCRIPT THREE) 52 0x00B4 ´ (ACUTE ACCENT) 53 0x00B5 µ (MICRO SIGN) 54 0x0125 ĥ (LATIN SMALL LETTER H WITH CIRCUMFLEX) 55 0x00B7 · (MIDDLE DOT) 56 0x00B8 ¸ (CEDILLA) 57 0x0131 ı (LATIN SMALL LETTER DOTLESS I) 58 0x015F ş (LATIN SMALL LETTER S WITH CEDILLA) 59 0x011F ğ (LATIN SMALL LETTER G WITH BREVE) 60 0x0135 ĵ (LATIN SMALL LETTER J WITH CIRCUMFLEX) 61 0x00BD ½ (VULGAR FRACTION ONE HALF) 63 0x017C ż (LATIN SMALL LETTER Z WITH DOT ABOVE) 64 0x00C0 À (LATIN CAPITAL LETTER A WITH GRAVE) 65 0x00C1 Á (LATIN CAPITAL LETTER A WITH ACUTE) 66 0x00C2  (LATIN CAPITAL LETTER A WITH CIRCUMFLEX) 68 0x00C4 Ä (LATIN CAPITAL LETTER A WITH DIAERESIS) 69 0x010A Ċ (LATIN CAPITAL LETTER C WITH DOT ABOVE) 70 0x0108 Ĉ (LATIN CAPITAL LETTER C WITH CIRCUMFLEX) 71 0x00C7 Ç (LATIN CAPITAL LETTER C WITH CEDILLA) 72 0x00C8 È (LATIN CAPITAL LETTER E WITH GRAVE) 73 0x00C9 É (LATIN CAPITAL LETTER E WITH ACUTE) 74 0x00CA Ê (LATIN CAPITAL LETTER E WITH CIRCUMFLEX) 75 0x00CB Ë (LATIN CAPITAL LETTER E WITH DIAERESIS) 76 0x00CC Ì (LATIN CAPITAL LETTER I WITH GRAVE) 77 0x00CD Í (LATIN CAPITAL LETTER I WITH ACUTE) 78 0x00CE Î (LATIN CAPITAL LETTER I WITH CIRCUMFLEX) 79 0x00CF Ï (LATIN CAPITAL LETTER I WITH DIAERESIS) 81 0x00D1 Ñ (LATIN CAPITAL LETTER N WITH TILDE) 82 0x00D2 Ò (LATIN CAPITAL LETTER O WITH GRAVE) 83 0x00D3 Ó (LATIN CAPITAL LETTER O WITH ACUTE) 84 0x00D4 Ô (LATIN CAPITAL LETTER O WITH CIRCUMFLEX) 85 0x0120 Ġ (LATIN CAPITAL LETTER G WITH DOT ABOVE) 86 0x00D6 Ö (LATIN CAPITAL LETTER O WITH DIAERESIS) 87 0x00D7 × (MULTIPLICATION SIGN) 88 0x011C Ĝ (LATIN CAPITAL LETTER G WITH CIRCUMFLEX) 89 0x00D9 Ù (LATIN CAPITAL LETTER U WITH GRAVE) 90 0x00DA Ú (LATIN CAPITAL LETTER U WITH ACUTE) 91 0x00DB Û (LATIN CAPITAL LETTER U WITH CIRCUMFLEX) 92 0x00DC Ü (LATIN CAPITAL LETTER U WITH DIAERESIS) 93 0x016C Ŭ (LATIN CAPITAL LETTER U WITH BREVE) 94 0x015C Ŝ (LATIN CAPITAL LETTER S WITH CIRCUMFLEX) 95 0x00DF ß (LATIN SMALL LETTER SHARP S) 96 0x00E0 à (LATIN SMALL LETTER A WITH GRAVE) 97 0x00E1 á (LATIN SMALL LETTER A WITH ACUTE) 98 0x00E2 â (LATIN SMALL LETTER A WITH CIRCUMFLEX) 100 0x00E4 ä (LATIN SMALL LETTER A WITH DIAERESIS) 101 0x010B ċ (LATIN SMALL LETTER C WITH DOT ABOVE) 102 0x0109 ĉ (LATIN SMALL LETTER C WITH CIRCUMFLEX) 103 0x00E7 ç (LATIN SMALL LETTER C WITH CEDILLA) 104 0x00E8 è (LATIN SMALL LETTER E WITH GRAVE) 105 0x00E9 é (LATIN SMALL LETTER E WITH ACUTE) 106 0x00EA ê (LATIN SMALL LETTER E WITH CIRCUMFLEX) 107 0x00EB ë (LATIN SMALL LETTER E WITH DIAERESIS) 108 0x00EC ì (LATIN SMALL LETTER I WITH GRAVE) 109 0x00ED í (LATIN SMALL LETTER I WITH ACUTE) 110 0x00EE î (LATIN SMALL LETTER I WITH CIRCUMFLEX) 111 0x00EF ï (LATIN SMALL LETTER I WITH DIAERESIS) 113 0x00F1 ñ (LATIN SMALL LETTER N WITH TILDE) 114 0x00F2 ò (LATIN SMALL LETTER O WITH GRAVE) 115 0x00F3 ó (LATIN SMALL LETTER O WITH ACUTE) 116 0x00F4 ô (LATIN SMALL LETTER O WITH CIRCUMFLEX) 117 0x0121 ġ (LATIN SMALL LETTER G WITH DOT ABOVE) 118 0x00F6 ö (LATIN SMALL LETTER O WITH DIAERESIS) 119 0x00F7 ÷ (DIVISION SIGN) 120 0x011D ĝ (LATIN SMALL LETTER G WITH CIRCUMFLEX) 121 0x00F9 ù (LATIN SMALL LETTER U WITH GRAVE) 122 0x00FA ú (LATIN SMALL LETTER U WITH ACUTE) 123 0x00FB û (LATIN SMALL LETTER U WITH CIRCUMFLEX) 124 0x00FC ü (LATIN SMALL LETTER U WITH DIAERESIS) 125 0x016D ŭ (LATIN SMALL LETTER U WITH BREVE) 126 0x015D ŝ (LATIN SMALL LETTER S WITH CIRCUMFLEX) 127 0x02D9 ˙ (DOT ABOVE) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-iso-8859-4.txt��������������������������������������������������������������0000664�0000000�0000000�00000012622�15202323131�0017142�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-iso-8859-4.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 72f29c92344d351fe9e74a946e7e0468d76d542c6894ff82982cb652ebe0feb7 # Date: 2018-01-06 0 0x0080 € (<control>) 1 0x0081  (<control>) 2 0x0082 ‚ (<control>) 3 0x0083 ƒ (<control>) 4 0x0084 „ (<control>) 5 0x0085 … (<control>) 6 0x0086 † (<control>) 7 0x0087 ‡ (<control>) 8 0x0088 ˆ (<control>) 9 0x0089 ‰ (<control>) 10 0x008A Š (<control>) 11 0x008B ‹ (<control>) 12 0x008C Œ (<control>) 13 0x008D  (<control>) 14 0x008E Ž (<control>) 15 0x008F  (<control>) 16 0x0090  (<control>) 17 0x0091 ‘ (<control>) 18 0x0092 ’ (<control>) 19 0x0093 “ (<control>) 20 0x0094 ” (<control>) 21 0x0095 • (<control>) 22 0x0096 – (<control>) 23 0x0097 — (<control>) 24 0x0098 ˜ (<control>) 25 0x0099 ™ (<control>) 26 0x009A š (<control>) 27 0x009B › (<control>) 28 0x009C œ (<control>) 29 0x009D  (<control>) 30 0x009E ž (<control>) 31 0x009F Ÿ (<control>) 32 0x00A0   (NO-BREAK SPACE) 33 0x0104 Ą (LATIN CAPITAL LETTER A WITH OGONEK) 34 0x0138 ĸ (LATIN SMALL LETTER KRA) 35 0x0156 Ŗ (LATIN CAPITAL LETTER R WITH CEDILLA) 36 0x00A4 ¤ (CURRENCY SIGN) 37 0x0128 Ĩ (LATIN CAPITAL LETTER I WITH TILDE) 38 0x013B Ļ (LATIN CAPITAL LETTER L WITH CEDILLA) 39 0x00A7 § (SECTION SIGN) 40 0x00A8 ¨ (DIAERESIS) 41 0x0160 Š (LATIN CAPITAL LETTER S WITH CARON) 42 0x0112 Ē (LATIN CAPITAL LETTER E WITH MACRON) 43 0x0122 Ģ (LATIN CAPITAL LETTER G WITH CEDILLA) 44 0x0166 Ŧ (LATIN CAPITAL LETTER T WITH STROKE) 45 0x00AD ­ (SOFT HYPHEN) 46 0x017D Ž (LATIN CAPITAL LETTER Z WITH CARON) 47 0x00AF ¯ (MACRON) 48 0x00B0 ° (DEGREE SIGN) 49 0x0105 ą (LATIN SMALL LETTER A WITH OGONEK) 50 0x02DB ˛ (OGONEK) 51 0x0157 ŗ (LATIN SMALL LETTER R WITH CEDILLA) 52 0x00B4 ´ (ACUTE ACCENT) 53 0x0129 ĩ (LATIN SMALL LETTER I WITH TILDE) 54 0x013C ļ (LATIN SMALL LETTER L WITH CEDILLA) 55 0x02C7 ˇ (CARON) 56 0x00B8 ¸ (CEDILLA) 57 0x0161 š (LATIN SMALL LETTER S WITH CARON) 58 0x0113 ē (LATIN SMALL LETTER E WITH MACRON) 59 0x0123 ģ (LATIN SMALL LETTER G WITH CEDILLA) 60 0x0167 ŧ (LATIN SMALL LETTER T WITH STROKE) 61 0x014A Ŋ (LATIN CAPITAL LETTER ENG) 62 0x017E ž (LATIN SMALL LETTER Z WITH CARON) 63 0x014B ŋ (LATIN SMALL LETTER ENG) 64 0x0100 Ā (LATIN CAPITAL LETTER A WITH MACRON) 65 0x00C1 Á (LATIN CAPITAL LETTER A WITH ACUTE) 66 0x00C2  (LATIN CAPITAL LETTER A WITH CIRCUMFLEX) 67 0x00C3 à (LATIN CAPITAL LETTER A WITH TILDE) 68 0x00C4 Ä (LATIN CAPITAL LETTER A WITH DIAERESIS) 69 0x00C5 Å (LATIN CAPITAL LETTER A WITH RING ABOVE) 70 0x00C6 Æ (LATIN CAPITAL LETTER AE) 71 0x012E Į (LATIN CAPITAL LETTER I WITH OGONEK) 72 0x010C Č (LATIN CAPITAL LETTER C WITH CARON) 73 0x00C9 É (LATIN CAPITAL LETTER E WITH ACUTE) 74 0x0118 Ę (LATIN CAPITAL LETTER E WITH OGONEK) 75 0x00CB Ë (LATIN CAPITAL LETTER E WITH DIAERESIS) 76 0x0116 Ė (LATIN CAPITAL LETTER E WITH DOT ABOVE) 77 0x00CD Í (LATIN CAPITAL LETTER I WITH ACUTE) 78 0x00CE Î (LATIN CAPITAL LETTER I WITH CIRCUMFLEX) 79 0x012A Ī (LATIN CAPITAL LETTER I WITH MACRON) 80 0x0110 Đ (LATIN CAPITAL LETTER D WITH STROKE) 81 0x0145 Ņ (LATIN CAPITAL LETTER N WITH CEDILLA) 82 0x014C Ō (LATIN CAPITAL LETTER O WITH MACRON) 83 0x0136 Ķ (LATIN CAPITAL LETTER K WITH CEDILLA) 84 0x00D4 Ô (LATIN CAPITAL LETTER O WITH CIRCUMFLEX) 85 0x00D5 Õ (LATIN CAPITAL LETTER O WITH TILDE) 86 0x00D6 Ö (LATIN CAPITAL LETTER O WITH DIAERESIS) 87 0x00D7 × (MULTIPLICATION SIGN) 88 0x00D8 Ø (LATIN CAPITAL LETTER O WITH STROKE) 89 0x0172 Ų (LATIN CAPITAL LETTER U WITH OGONEK) 90 0x00DA Ú (LATIN CAPITAL LETTER U WITH ACUTE) 91 0x00DB Û (LATIN CAPITAL LETTER U WITH CIRCUMFLEX) 92 0x00DC Ü (LATIN CAPITAL LETTER U WITH DIAERESIS) 93 0x0168 Ũ (LATIN CAPITAL LETTER U WITH TILDE) 94 0x016A Ū (LATIN CAPITAL LETTER U WITH MACRON) 95 0x00DF ß (LATIN SMALL LETTER SHARP S) 96 0x0101 ā (LATIN SMALL LETTER A WITH MACRON) 97 0x00E1 á (LATIN SMALL LETTER A WITH ACUTE) 98 0x00E2 â (LATIN SMALL LETTER A WITH CIRCUMFLEX) 99 0x00E3 ã (LATIN SMALL LETTER A WITH TILDE) 100 0x00E4 ä (LATIN SMALL LETTER A WITH DIAERESIS) 101 0x00E5 å (LATIN SMALL LETTER A WITH RING ABOVE) 102 0x00E6 æ (LATIN SMALL LETTER AE) 103 0x012F į (LATIN SMALL LETTER I WITH OGONEK) 104 0x010D č (LATIN SMALL LETTER C WITH CARON) 105 0x00E9 é (LATIN SMALL LETTER E WITH ACUTE) 106 0x0119 ę (LATIN SMALL LETTER E WITH OGONEK) 107 0x00EB ë (LATIN SMALL LETTER E WITH DIAERESIS) 108 0x0117 ė (LATIN SMALL LETTER E WITH DOT ABOVE) 109 0x00ED í (LATIN SMALL LETTER I WITH ACUTE) 110 0x00EE î (LATIN SMALL LETTER I WITH CIRCUMFLEX) 111 0x012B ī (LATIN SMALL LETTER I WITH MACRON) 112 0x0111 đ (LATIN SMALL LETTER D WITH STROKE) 113 0x0146 ņ (LATIN SMALL LETTER N WITH CEDILLA) 114 0x014D ō (LATIN SMALL LETTER O WITH MACRON) 115 0x0137 ķ (LATIN SMALL LETTER K WITH CEDILLA) 116 0x00F4 ô (LATIN SMALL LETTER O WITH CIRCUMFLEX) 117 0x00F5 õ (LATIN SMALL LETTER O WITH TILDE) 118 0x00F6 ö (LATIN SMALL LETTER O WITH DIAERESIS) 119 0x00F7 ÷ (DIVISION SIGN) 120 0x00F8 ø (LATIN SMALL LETTER O WITH STROKE) 121 0x0173 ų (LATIN SMALL LETTER U WITH OGONEK) 122 0x00FA ú (LATIN SMALL LETTER U WITH ACUTE) 123 0x00FB û (LATIN SMALL LETTER U WITH CIRCUMFLEX) 124 0x00FC ü (LATIN SMALL LETTER U WITH DIAERESIS) 125 0x0169 ũ (LATIN SMALL LETTER U WITH TILDE) 126 0x016B ū (LATIN SMALL LETTER U WITH MACRON) 127 0x02D9 ˙ (DOT ABOVE) ��������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-iso-8859-5.txt��������������������������������������������������������������0000664�0000000�0000000�00000012052�15202323131�0017140�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-iso-8859-5.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: fa9b1f3f5242df43e2e7bca80e9b6997c67944f20a4af91ee06bacc4e132d9c9 # Date: 2018-01-06 0 0x0080 € (<control>) 1 0x0081  (<control>) 2 0x0082 ‚ (<control>) 3 0x0083 ƒ (<control>) 4 0x0084 „ (<control>) 5 0x0085 … (<control>) 6 0x0086 † (<control>) 7 0x0087 ‡ (<control>) 8 0x0088 ˆ (<control>) 9 0x0089 ‰ (<control>) 10 0x008A Š (<control>) 11 0x008B ‹ (<control>) 12 0x008C Œ (<control>) 13 0x008D  (<control>) 14 0x008E Ž (<control>) 15 0x008F  (<control>) 16 0x0090  (<control>) 17 0x0091 ‘ (<control>) 18 0x0092 ’ (<control>) 19 0x0093 “ (<control>) 20 0x0094 ” (<control>) 21 0x0095 • (<control>) 22 0x0096 – (<control>) 23 0x0097 — (<control>) 24 0x0098 ˜ (<control>) 25 0x0099 ™ (<control>) 26 0x009A š (<control>) 27 0x009B › (<control>) 28 0x009C œ (<control>) 29 0x009D  (<control>) 30 0x009E ž (<control>) 31 0x009F Ÿ (<control>) 32 0x00A0   (NO-BREAK SPACE) 33 0x0401 Ё (CYRILLIC CAPITAL LETTER IO) 34 0x0402 Ђ (CYRILLIC CAPITAL LETTER DJE) 35 0x0403 Ѓ (CYRILLIC CAPITAL LETTER GJE) 36 0x0404 Є (CYRILLIC CAPITAL LETTER UKRAINIAN IE) 37 0x0405 Ѕ (CYRILLIC CAPITAL LETTER DZE) 38 0x0406 І (CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I) 39 0x0407 Ї (CYRILLIC CAPITAL LETTER YI) 40 0x0408 Ј (CYRILLIC CAPITAL LETTER JE) 41 0x0409 Љ (CYRILLIC CAPITAL LETTER LJE) 42 0x040A Њ (CYRILLIC CAPITAL LETTER NJE) 43 0x040B Ћ (CYRILLIC CAPITAL LETTER TSHE) 44 0x040C Ќ (CYRILLIC CAPITAL LETTER KJE) 45 0x00AD ­ (SOFT HYPHEN) 46 0x040E Ў (CYRILLIC CAPITAL LETTER SHORT U) 47 0x040F Џ (CYRILLIC CAPITAL LETTER DZHE) 48 0x0410 А (CYRILLIC CAPITAL LETTER A) 49 0x0411 Б (CYRILLIC CAPITAL LETTER BE) 50 0x0412 В (CYRILLIC CAPITAL LETTER VE) 51 0x0413 Г (CYRILLIC CAPITAL LETTER GHE) 52 0x0414 Д (CYRILLIC CAPITAL LETTER DE) 53 0x0415 Е (CYRILLIC CAPITAL LETTER IE) 54 0x0416 Ж (CYRILLIC CAPITAL LETTER ZHE) 55 0x0417 З (CYRILLIC CAPITAL LETTER ZE) 56 0x0418 И (CYRILLIC CAPITAL LETTER I) 57 0x0419 Й (CYRILLIC CAPITAL LETTER SHORT I) 58 0x041A К (CYRILLIC CAPITAL LETTER KA) 59 0x041B Л (CYRILLIC CAPITAL LETTER EL) 60 0x041C М (CYRILLIC CAPITAL LETTER EM) 61 0x041D Н (CYRILLIC CAPITAL LETTER EN) 62 0x041E О (CYRILLIC CAPITAL LETTER O) 63 0x041F П (CYRILLIC CAPITAL LETTER PE) 64 0x0420 Р (CYRILLIC CAPITAL LETTER ER) 65 0x0421 С (CYRILLIC CAPITAL LETTER ES) 66 0x0422 Т (CYRILLIC CAPITAL LETTER TE) 67 0x0423 У (CYRILLIC CAPITAL LETTER U) 68 0x0424 Ф (CYRILLIC CAPITAL LETTER EF) 69 0x0425 Х (CYRILLIC CAPITAL LETTER HA) 70 0x0426 Ц (CYRILLIC CAPITAL LETTER TSE) 71 0x0427 Ч (CYRILLIC CAPITAL LETTER CHE) 72 0x0428 Ш (CYRILLIC CAPITAL LETTER SHA) 73 0x0429 Щ (CYRILLIC CAPITAL LETTER SHCHA) 74 0x042A Ъ (CYRILLIC CAPITAL LETTER HARD SIGN) 75 0x042B Ы (CYRILLIC CAPITAL LETTER YERU) 76 0x042C Ь (CYRILLIC CAPITAL LETTER SOFT SIGN) 77 0x042D Э (CYRILLIC CAPITAL LETTER E) 78 0x042E Ю (CYRILLIC CAPITAL LETTER YU) 79 0x042F Я (CYRILLIC CAPITAL LETTER YA) 80 0x0430 а (CYRILLIC SMALL LETTER A) 81 0x0431 б (CYRILLIC SMALL LETTER BE) 82 0x0432 в (CYRILLIC SMALL LETTER VE) 83 0x0433 г (CYRILLIC SMALL LETTER GHE) 84 0x0434 д (CYRILLIC SMALL LETTER DE) 85 0x0435 е (CYRILLIC SMALL LETTER IE) 86 0x0436 ж (CYRILLIC SMALL LETTER ZHE) 87 0x0437 з (CYRILLIC SMALL LETTER ZE) 88 0x0438 и (CYRILLIC SMALL LETTER I) 89 0x0439 й (CYRILLIC SMALL LETTER SHORT I) 90 0x043A к (CYRILLIC SMALL LETTER KA) 91 0x043B л (CYRILLIC SMALL LETTER EL) 92 0x043C м (CYRILLIC SMALL LETTER EM) 93 0x043D н (CYRILLIC SMALL LETTER EN) 94 0x043E о (CYRILLIC SMALL LETTER O) 95 0x043F п (CYRILLIC SMALL LETTER PE) 96 0x0440 р (CYRILLIC SMALL LETTER ER) 97 0x0441 с (CYRILLIC SMALL LETTER ES) 98 0x0442 т (CYRILLIC SMALL LETTER TE) 99 0x0443 у (CYRILLIC SMALL LETTER U) 100 0x0444 ф (CYRILLIC SMALL LETTER EF) 101 0x0445 х (CYRILLIC SMALL LETTER HA) 102 0x0446 ц (CYRILLIC SMALL LETTER TSE) 103 0x0447 ч (CYRILLIC SMALL LETTER CHE) 104 0x0448 ш (CYRILLIC SMALL LETTER SHA) 105 0x0449 щ (CYRILLIC SMALL LETTER SHCHA) 106 0x044A ъ (CYRILLIC SMALL LETTER HARD SIGN) 107 0x044B ы (CYRILLIC SMALL LETTER YERU) 108 0x044C ь (CYRILLIC SMALL LETTER SOFT SIGN) 109 0x044D э (CYRILLIC SMALL LETTER E) 110 0x044E ю (CYRILLIC SMALL LETTER YU) 111 0x044F я (CYRILLIC SMALL LETTER YA) 112 0x2116 № (NUMERO SIGN) 113 0x0451 ё (CYRILLIC SMALL LETTER IO) 114 0x0452 ђ (CYRILLIC SMALL LETTER DJE) 115 0x0453 ѓ (CYRILLIC SMALL LETTER GJE) 116 0x0454 є (CYRILLIC SMALL LETTER UKRAINIAN IE) 117 0x0455 ѕ (CYRILLIC SMALL LETTER DZE) 118 0x0456 і (CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I) 119 0x0457 ї (CYRILLIC SMALL LETTER YI) 120 0x0458 ј (CYRILLIC SMALL LETTER JE) 121 0x0459 љ (CYRILLIC SMALL LETTER LJE) 122 0x045A њ (CYRILLIC SMALL LETTER NJE) 123 0x045B ћ (CYRILLIC SMALL LETTER TSHE) 124 0x045C ќ (CYRILLIC SMALL LETTER KJE) 125 0x00A7 § (SECTION SIGN) 126 0x045E ў (CYRILLIC SMALL LETTER SHORT U) 127 0x045F џ (CYRILLIC SMALL LETTER DZHE) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-iso-8859-6.txt��������������������������������������������������������������0000664�0000000�0000000�00000005434�15202323131�0017147�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-iso-8859-6.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 85bb7b5c2dc75975afebe5743935ba4ed5a09c1e9e34e9bfb2ff80293f5d8bbc # Date: 2018-01-06 0 0x0080 € (<control>) 1 0x0081  (<control>) 2 0x0082 ‚ (<control>) 3 0x0083 ƒ (<control>) 4 0x0084 „ (<control>) 5 0x0085 … (<control>) 6 0x0086 † (<control>) 7 0x0087 ‡ (<control>) 8 0x0088 ˆ (<control>) 9 0x0089 ‰ (<control>) 10 0x008A Š (<control>) 11 0x008B ‹ (<control>) 12 0x008C Œ (<control>) 13 0x008D  (<control>) 14 0x008E Ž (<control>) 15 0x008F  (<control>) 16 0x0090  (<control>) 17 0x0091 ‘ (<control>) 18 0x0092 ’ (<control>) 19 0x0093 “ (<control>) 20 0x0094 ” (<control>) 21 0x0095 • (<control>) 22 0x0096 – (<control>) 23 0x0097 — (<control>) 24 0x0098 ˜ (<control>) 25 0x0099 ™ (<control>) 26 0x009A š (<control>) 27 0x009B › (<control>) 28 0x009C œ (<control>) 29 0x009D  (<control>) 30 0x009E ž (<control>) 31 0x009F Ÿ (<control>) 32 0x00A0   (NO-BREAK SPACE) 36 0x00A4 ¤ (CURRENCY SIGN) 44 0x060C ، (ARABIC COMMA) 45 0x00AD ­ (SOFT HYPHEN) 59 0x061B ؛ (ARABIC SEMICOLON) 63 0x061F ؟ (ARABIC QUESTION MARK) 65 0x0621 ء (ARABIC LETTER HAMZA) 66 0x0622 آ (ARABIC LETTER ALEF WITH MADDA ABOVE) 67 0x0623 أ (ARABIC LETTER ALEF WITH HAMZA ABOVE) 68 0x0624 ؤ (ARABIC LETTER WAW WITH HAMZA ABOVE) 69 0x0625 إ (ARABIC LETTER ALEF WITH HAMZA BELOW) 70 0x0626 ئ (ARABIC LETTER YEH WITH HAMZA ABOVE) 71 0x0627 ا (ARABIC LETTER ALEF) 72 0x0628 ب (ARABIC LETTER BEH) 73 0x0629 ة (ARABIC LETTER TEH MARBUTA) 74 0x062A ت (ARABIC LETTER TEH) 75 0x062B ث (ARABIC LETTER THEH) 76 0x062C ج (ARABIC LETTER JEEM) 77 0x062D ح (ARABIC LETTER HAH) 78 0x062E خ (ARABIC LETTER KHAH) 79 0x062F د (ARABIC LETTER DAL) 80 0x0630 ذ (ARABIC LETTER THAL) 81 0x0631 ر (ARABIC LETTER REH) 82 0x0632 ز (ARABIC LETTER ZAIN) 83 0x0633 س (ARABIC LETTER SEEN) 84 0x0634 ش (ARABIC LETTER SHEEN) 85 0x0635 ص (ARABIC LETTER SAD) 86 0x0636 ض (ARABIC LETTER DAD) 87 0x0637 ط (ARABIC LETTER TAH) 88 0x0638 ظ (ARABIC LETTER ZAH) 89 0x0639 ع (ARABIC LETTER AIN) 90 0x063A غ (ARABIC LETTER GHAIN) 96 0x0640 ـ (ARABIC TATWEEL) 97 0x0641 ف (ARABIC LETTER FEH) 98 0x0642 ق (ARABIC LETTER QAF) 99 0x0643 ك (ARABIC LETTER KAF) 100 0x0644 ل (ARABIC LETTER LAM) 101 0x0645 م (ARABIC LETTER MEEM) 102 0x0646 ن (ARABIC LETTER NOON) 103 0x0647 ه (ARABIC LETTER HEH) 104 0x0648 و (ARABIC LETTER WAW) 105 0x0649 ى (ARABIC LETTER ALEF MAKSURA) 106 0x064A ي (ARABIC LETTER YEH) 107 0x064B ً (ARABIC FATHATAN) 108 0x064C ٌ (ARABIC DAMMATAN) 109 0x064D ٍ (ARABIC KASRATAN) 110 0x064E َ (ARABIC FATHA) 111 0x064F ُ (ARABIC DAMMA) 112 0x0650 ِ (ARABIC KASRA) 113 0x0651 ّ (ARABIC SHADDA) 114 0x0652 ْ (ARABIC SUKUN) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-iso-8859-7.txt��������������������������������������������������������������0000664�0000000�0000000�00000011572�15202323131�0017150�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-iso-8859-7.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: f53d8aeba36314ef950eef02ffcf11dff540638ce27dfe7a86b6ccc6875afb24 # Date: 2018-01-06 0 0x0080 € (<control>) 1 0x0081  (<control>) 2 0x0082 ‚ (<control>) 3 0x0083 ƒ (<control>) 4 0x0084 „ (<control>) 5 0x0085 … (<control>) 6 0x0086 † (<control>) 7 0x0087 ‡ (<control>) 8 0x0088 ˆ (<control>) 9 0x0089 ‰ (<control>) 10 0x008A Š (<control>) 11 0x008B ‹ (<control>) 12 0x008C Œ (<control>) 13 0x008D  (<control>) 14 0x008E Ž (<control>) 15 0x008F  (<control>) 16 0x0090  (<control>) 17 0x0091 ‘ (<control>) 18 0x0092 ’ (<control>) 19 0x0093 “ (<control>) 20 0x0094 ” (<control>) 21 0x0095 • (<control>) 22 0x0096 – (<control>) 23 0x0097 — (<control>) 24 0x0098 ˜ (<control>) 25 0x0099 ™ (<control>) 26 0x009A š (<control>) 27 0x009B › (<control>) 28 0x009C œ (<control>) 29 0x009D  (<control>) 30 0x009E ž (<control>) 31 0x009F Ÿ (<control>) 32 0x00A0   (NO-BREAK SPACE) 33 0x2018 ‘ (LEFT SINGLE QUOTATION MARK) 34 0x2019 ’ (RIGHT SINGLE QUOTATION MARK) 35 0x00A3 £ (POUND SIGN) 36 0x20AC € (EURO SIGN) 37 0x20AF ₯ (DRACHMA SIGN) 38 0x00A6 ¦ (BROKEN BAR) 39 0x00A7 § (SECTION SIGN) 40 0x00A8 ¨ (DIAERESIS) 41 0x00A9 © (COPYRIGHT SIGN) 42 0x037A ͺ (GREEK YPOGEGRAMMENI) 43 0x00AB « (LEFT-POINTING DOUBLE ANGLE QUOTATION MARK) 44 0x00AC ¬ (NOT SIGN) 45 0x00AD ­ (SOFT HYPHEN) 47 0x2015 ― (HORIZONTAL BAR) 48 0x00B0 ° (DEGREE SIGN) 49 0x00B1 ± (PLUS-MINUS SIGN) 50 0x00B2 ² (SUPERSCRIPT TWO) 51 0x00B3 ³ (SUPERSCRIPT THREE) 52 0x0384 ΄ (GREEK TONOS) 53 0x0385 ΅ (GREEK DIALYTIKA TONOS) 54 0x0386 Ά (GREEK CAPITAL LETTER ALPHA WITH TONOS) 55 0x00B7 · (MIDDLE DOT) 56 0x0388 Έ (GREEK CAPITAL LETTER EPSILON WITH TONOS) 57 0x0389 Ή (GREEK CAPITAL LETTER ETA WITH TONOS) 58 0x038A Ί (GREEK CAPITAL LETTER IOTA WITH TONOS) 59 0x00BB » (RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK) 60 0x038C Ό (GREEK CAPITAL LETTER OMICRON WITH TONOS) 61 0x00BD ½ (VULGAR FRACTION ONE HALF) 62 0x038E Ύ (GREEK CAPITAL LETTER UPSILON WITH TONOS) 63 0x038F Ώ (GREEK CAPITAL LETTER OMEGA WITH TONOS) 64 0x0390 ΐ (GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS) 65 0x0391 Α (GREEK CAPITAL LETTER ALPHA) 66 0x0392 Β (GREEK CAPITAL LETTER BETA) 67 0x0393 Γ (GREEK CAPITAL LETTER GAMMA) 68 0x0394 Δ (GREEK CAPITAL LETTER DELTA) 69 0x0395 Ε (GREEK CAPITAL LETTER EPSILON) 70 0x0396 Ζ (GREEK CAPITAL LETTER ZETA) 71 0x0397 Η (GREEK CAPITAL LETTER ETA) 72 0x0398 Θ (GREEK CAPITAL LETTER THETA) 73 0x0399 Ι (GREEK CAPITAL LETTER IOTA) 74 0x039A Κ (GREEK CAPITAL LETTER KAPPA) 75 0x039B Λ (GREEK CAPITAL LETTER LAMDA) 76 0x039C Μ (GREEK CAPITAL LETTER MU) 77 0x039D Ν (GREEK CAPITAL LETTER NU) 78 0x039E Ξ (GREEK CAPITAL LETTER XI) 79 0x039F Ο (GREEK CAPITAL LETTER OMICRON) 80 0x03A0 Π (GREEK CAPITAL LETTER PI) 81 0x03A1 Ρ (GREEK CAPITAL LETTER RHO) 83 0x03A3 Σ (GREEK CAPITAL LETTER SIGMA) 84 0x03A4 Τ (GREEK CAPITAL LETTER TAU) 85 0x03A5 Υ (GREEK CAPITAL LETTER UPSILON) 86 0x03A6 Φ (GREEK CAPITAL LETTER PHI) 87 0x03A7 Χ (GREEK CAPITAL LETTER CHI) 88 0x03A8 Ψ (GREEK CAPITAL LETTER PSI) 89 0x03A9 Ω (GREEK CAPITAL LETTER OMEGA) 90 0x03AA Ϊ (GREEK CAPITAL LETTER IOTA WITH DIALYTIKA) 91 0x03AB Ϋ (GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA) 92 0x03AC ά (GREEK SMALL LETTER ALPHA WITH TONOS) 93 0x03AD έ (GREEK SMALL LETTER EPSILON WITH TONOS) 94 0x03AE ή (GREEK SMALL LETTER ETA WITH TONOS) 95 0x03AF ί (GREEK SMALL LETTER IOTA WITH TONOS) 96 0x03B0 ΰ (GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS) 97 0x03B1 α (GREEK SMALL LETTER ALPHA) 98 0x03B2 β (GREEK SMALL LETTER BETA) 99 0x03B3 γ (GREEK SMALL LETTER GAMMA) 100 0x03B4 δ (GREEK SMALL LETTER DELTA) 101 0x03B5 ε (GREEK SMALL LETTER EPSILON) 102 0x03B6 ζ (GREEK SMALL LETTER ZETA) 103 0x03B7 η (GREEK SMALL LETTER ETA) 104 0x03B8 θ (GREEK SMALL LETTER THETA) 105 0x03B9 ι (GREEK SMALL LETTER IOTA) 106 0x03BA κ (GREEK SMALL LETTER KAPPA) 107 0x03BB λ (GREEK SMALL LETTER LAMDA) 108 0x03BC μ (GREEK SMALL LETTER MU) 109 0x03BD ν (GREEK SMALL LETTER NU) 110 0x03BE ξ (GREEK SMALL LETTER XI) 111 0x03BF ο (GREEK SMALL LETTER OMICRON) 112 0x03C0 π (GREEK SMALL LETTER PI) 113 0x03C1 ρ (GREEK SMALL LETTER RHO) 114 0x03C2 ς (GREEK SMALL LETTER FINAL SIGMA) 115 0x03C3 σ (GREEK SMALL LETTER SIGMA) 116 0x03C4 τ (GREEK SMALL LETTER TAU) 117 0x03C5 υ (GREEK SMALL LETTER UPSILON) 118 0x03C6 φ (GREEK SMALL LETTER PHI) 119 0x03C7 χ (GREEK SMALL LETTER CHI) 120 0x03C8 ψ (GREEK SMALL LETTER PSI) 121 0x03C9 ω (GREEK SMALL LETTER OMEGA) 122 0x03CA ϊ (GREEK SMALL LETTER IOTA WITH DIALYTIKA) 123 0x03CB ϋ (GREEK SMALL LETTER UPSILON WITH DIALYTIKA) 124 0x03CC ό (GREEK SMALL LETTER OMICRON WITH TONOS) 125 0x03CD ύ (GREEK SMALL LETTER UPSILON WITH TONOS) 126 0x03CE ώ (GREEK SMALL LETTER OMEGA WITH TONOS) ��������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-iso-8859-8.txt��������������������������������������������������������������0000664�0000000�0000000�00000006005�15202323131�0017144�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-iso-8859-8.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 7657a9ca3fa875990da960d3f812eea28dcd0ae6ed55a18d5394303c86f5484b # Date: 2018-01-06 0 0x0080 € (<control>) 1 0x0081  (<control>) 2 0x0082 ‚ (<control>) 3 0x0083 ƒ (<control>) 4 0x0084 „ (<control>) 5 0x0085 … (<control>) 6 0x0086 † (<control>) 7 0x0087 ‡ (<control>) 8 0x0088 ˆ (<control>) 9 0x0089 ‰ (<control>) 10 0x008A Š (<control>) 11 0x008B ‹ (<control>) 12 0x008C Œ (<control>) 13 0x008D  (<control>) 14 0x008E Ž (<control>) 15 0x008F  (<control>) 16 0x0090  (<control>) 17 0x0091 ‘ (<control>) 18 0x0092 ’ (<control>) 19 0x0093 “ (<control>) 20 0x0094 ” (<control>) 21 0x0095 • (<control>) 22 0x0096 – (<control>) 23 0x0097 — (<control>) 24 0x0098 ˜ (<control>) 25 0x0099 ™ (<control>) 26 0x009A š (<control>) 27 0x009B › (<control>) 28 0x009C œ (<control>) 29 0x009D  (<control>) 30 0x009E ž (<control>) 31 0x009F Ÿ (<control>) 32 0x00A0   (NO-BREAK SPACE) 34 0x00A2 ¢ (CENT SIGN) 35 0x00A3 £ (POUND SIGN) 36 0x00A4 ¤ (CURRENCY SIGN) 37 0x00A5 ¥ (YEN SIGN) 38 0x00A6 ¦ (BROKEN BAR) 39 0x00A7 § (SECTION SIGN) 40 0x00A8 ¨ (DIAERESIS) 41 0x00A9 © (COPYRIGHT SIGN) 42 0x00D7 × (MULTIPLICATION SIGN) 43 0x00AB « (LEFT-POINTING DOUBLE ANGLE QUOTATION MARK) 44 0x00AC ¬ (NOT SIGN) 45 0x00AD ­ (SOFT HYPHEN) 46 0x00AE ® (REGISTERED SIGN) 47 0x00AF ¯ (MACRON) 48 0x00B0 ° (DEGREE SIGN) 49 0x00B1 ± (PLUS-MINUS SIGN) 50 0x00B2 ² (SUPERSCRIPT TWO) 51 0x00B3 ³ (SUPERSCRIPT THREE) 52 0x00B4 ´ (ACUTE ACCENT) 53 0x00B5 µ (MICRO SIGN) 54 0x00B6 ¶ (PILCROW SIGN) 55 0x00B7 · (MIDDLE DOT) 56 0x00B8 ¸ (CEDILLA) 57 0x00B9 ¹ (SUPERSCRIPT ONE) 58 0x00F7 ÷ (DIVISION SIGN) 59 0x00BB » (RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK) 60 0x00BC ¼ (VULGAR FRACTION ONE QUARTER) 61 0x00BD ½ (VULGAR FRACTION ONE HALF) 62 0x00BE ¾ (VULGAR FRACTION THREE QUARTERS) 95 0x2017 ‗ (DOUBLE LOW LINE) 96 0x05D0 א (HEBREW LETTER ALEF) 97 0x05D1 ב (HEBREW LETTER BET) 98 0x05D2 ג (HEBREW LETTER GIMEL) 99 0x05D3 ד (HEBREW LETTER DALET) 100 0x05D4 ה (HEBREW LETTER HE) 101 0x05D5 ו (HEBREW LETTER VAV) 102 0x05D6 ז (HEBREW LETTER ZAYIN) 103 0x05D7 ח (HEBREW LETTER HET) 104 0x05D8 ט (HEBREW LETTER TET) 105 0x05D9 י (HEBREW LETTER YOD) 106 0x05DA ך (HEBREW LETTER FINAL KAF) 107 0x05DB כ (HEBREW LETTER KAF) 108 0x05DC ל (HEBREW LETTER LAMED) 109 0x05DD ם (HEBREW LETTER FINAL MEM) 110 0x05DE מ (HEBREW LETTER MEM) 111 0x05DF ן (HEBREW LETTER FINAL NUN) 112 0x05E0 נ (HEBREW LETTER NUN) 113 0x05E1 ס (HEBREW LETTER SAMEKH) 114 0x05E2 ע (HEBREW LETTER AYIN) 115 0x05E3 ף (HEBREW LETTER FINAL PE) 116 0x05E4 פ (HEBREW LETTER PE) 117 0x05E5 ץ (HEBREW LETTER FINAL TSADI) 118 0x05E6 צ (HEBREW LETTER TSADI) 119 0x05E7 ק (HEBREW LETTER QOF) 120 0x05E8 ר (HEBREW LETTER RESH) 121 0x05E9 ש (HEBREW LETTER SHIN) 122 0x05EA ת (HEBREW LETTER TAV) 125 0x200E ‎ (LEFT-TO-RIGHT MARK) 126 0x200F ‏ (RIGHT-TO-LEFT MARK) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-jis0208.txt�����������������������������������������������������������������0000664�0000000�0000000�00001032470�15202323131�0016677�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-jis0208.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: cbaa91f3deb7d0841faf5c33041fc15a285da0e87e64ab802c4bf04b7c4da861 # Date: 2018-01-06 0 0x3000   (IDEOGRAPHIC SPACE) 1 0x3001 、 (IDEOGRAPHIC COMMA) 2 0x3002 。 (IDEOGRAPHIC FULL STOP) 3 0xFF0C , (FULLWIDTH COMMA) 4 0xFF0E . (FULLWIDTH FULL STOP) 5 0x30FB ・ (KATAKANA MIDDLE DOT) 6 0xFF1A : (FULLWIDTH COLON) 7 0xFF1B ; (FULLWIDTH SEMICOLON) 8 0xFF1F ? (FULLWIDTH QUESTION MARK) 9 0xFF01 ! (FULLWIDTH EXCLAMATION MARK) 10 0x309B ゛ (KATAKANA-HIRAGANA VOICED SOUND MARK) 11 0x309C ゜ (KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK) 12 0x00B4 ´ (ACUTE ACCENT) 13 0xFF40 ` (FULLWIDTH GRAVE ACCENT) 14 0x00A8 ¨ (DIAERESIS) 15 0xFF3E ^ (FULLWIDTH CIRCUMFLEX ACCENT) 16 0xFFE3  ̄ (FULLWIDTH MACRON) 17 0xFF3F _ (FULLWIDTH LOW LINE) 18 0x30FD ヽ (KATAKANA ITERATION MARK) 19 0x30FE ヾ (KATAKANA VOICED ITERATION MARK) 20 0x309D ゝ (HIRAGANA ITERATION MARK) 21 0x309E ゞ (HIRAGANA VOICED ITERATION MARK) 22 0x3003 〃 (DITTO MARK) 23 0x4EDD 仝 (<CJK Ideograph>) 24 0x3005 々 (IDEOGRAPHIC ITERATION MARK) 25 0x3006 〆 (IDEOGRAPHIC CLOSING MARK) 26 0x3007 〇 (IDEOGRAPHIC NUMBER ZERO) 27 0x30FC ー (KATAKANA-HIRAGANA PROLONGED SOUND MARK) 28 0x2015 ― (HORIZONTAL BAR) 29 0x2010 ‐ (HYPHEN) 30 0xFF0F / (FULLWIDTH SOLIDUS) 31 0xFF3C \ (FULLWIDTH REVERSE SOLIDUS) 32 0xFF5E ~ (FULLWIDTH TILDE) 33 0x2225 ∥ (PARALLEL TO) 34 0xFF5C | (FULLWIDTH VERTICAL LINE) 35 0x2026 … (HORIZONTAL ELLIPSIS) 36 0x2025 ‥ (TWO DOT LEADER) 37 0x2018 ‘ (LEFT SINGLE QUOTATION MARK) 38 0x2019 ’ (RIGHT SINGLE QUOTATION MARK) 39 0x201C “ (LEFT DOUBLE QUOTATION MARK) 40 0x201D ” (RIGHT DOUBLE QUOTATION MARK) 41 0xFF08 ( (FULLWIDTH LEFT PARENTHESIS) 42 0xFF09 ) (FULLWIDTH RIGHT PARENTHESIS) 43 0x3014 〔 (LEFT TORTOISE SHELL BRACKET) 44 0x3015 〕 (RIGHT TORTOISE SHELL BRACKET) 45 0xFF3B [ (FULLWIDTH LEFT SQUARE BRACKET) 46 0xFF3D ] (FULLWIDTH RIGHT SQUARE BRACKET) 47 0xFF5B { (FULLWIDTH LEFT CURLY BRACKET) 48 0xFF5D } (FULLWIDTH RIGHT CURLY BRACKET) 49 0x3008 〈 (LEFT ANGLE BRACKET) 50 0x3009 〉 (RIGHT ANGLE BRACKET) 51 0x300A 《 (LEFT DOUBLE ANGLE BRACKET) 52 0x300B 》 (RIGHT DOUBLE ANGLE BRACKET) 53 0x300C 「 (LEFT CORNER BRACKET) 54 0x300D 」 (RIGHT CORNER BRACKET) 55 0x300E 『 (LEFT WHITE CORNER BRACKET) 56 0x300F 』 (RIGHT WHITE CORNER BRACKET) 57 0x3010 【 (LEFT BLACK LENTICULAR BRACKET) 58 0x3011 】 (RIGHT BLACK LENTICULAR BRACKET) 59 0xFF0B + (FULLWIDTH PLUS SIGN) 60 0xFF0D - (FULLWIDTH HYPHEN-MINUS) 61 0x00B1 ± (PLUS-MINUS SIGN) 62 0x00D7 × (MULTIPLICATION SIGN) 63 0x00F7 ÷ (DIVISION SIGN) 64 0xFF1D = (FULLWIDTH EQUALS SIGN) 65 0x2260 ≠ (NOT EQUAL TO) 66 0xFF1C < (FULLWIDTH LESS-THAN SIGN) 67 0xFF1E > (FULLWIDTH GREATER-THAN SIGN) 68 0x2266 ≦ (LESS-THAN OVER EQUAL TO) 69 0x2267 ≧ (GREATER-THAN OVER EQUAL TO) 70 0x221E ∞ (INFINITY) 71 0x2234 ∴ (THEREFORE) 72 0x2642 ♂ (MALE SIGN) 73 0x2640 ♀ (FEMALE SIGN) 74 0x00B0 ° (DEGREE SIGN) 75 0x2032 ′ (PRIME) 76 0x2033 ″ (DOUBLE PRIME) 77 0x2103 ℃ (DEGREE CELSIUS) 78 0xFFE5 ¥ (FULLWIDTH YEN SIGN) 79 0xFF04 $ (FULLWIDTH DOLLAR SIGN) 80 0xFFE0 ¢ (FULLWIDTH CENT SIGN) 81 0xFFE1 £ (FULLWIDTH POUND SIGN) 82 0xFF05 % (FULLWIDTH PERCENT SIGN) 83 0xFF03 # (FULLWIDTH NUMBER SIGN) 84 0xFF06 & (FULLWIDTH AMPERSAND) 85 0xFF0A * (FULLWIDTH ASTERISK) 86 0xFF20 @ (FULLWIDTH COMMERCIAL AT) 87 0x00A7 § (SECTION SIGN) 88 0x2606 ☆ (WHITE STAR) 89 0x2605 ★ (BLACK STAR) 90 0x25CB ○ (WHITE CIRCLE) 91 0x25CF ● (BLACK CIRCLE) 92 0x25CE ◎ (BULLSEYE) 93 0x25C7 ◇ (WHITE DIAMOND) 94 0x25C6 ◆ (BLACK DIAMOND) 95 0x25A1 □ (WHITE SQUARE) 96 0x25A0 ■ (BLACK SQUARE) 97 0x25B3 △ (WHITE UP-POINTING TRIANGLE) 98 0x25B2 ▲ (BLACK UP-POINTING TRIANGLE) 99 0x25BD ▽ (WHITE DOWN-POINTING TRIANGLE) 100 0x25BC ▼ (BLACK DOWN-POINTING TRIANGLE) 101 0x203B ※ (REFERENCE MARK) 102 0x3012 〒 (POSTAL MARK) 103 0x2192 → (RIGHTWARDS ARROW) 104 0x2190 ← (LEFTWARDS ARROW) 105 0x2191 ↑ (UPWARDS ARROW) 106 0x2193 ↓ (DOWNWARDS ARROW) 107 0x3013 〓 (GETA MARK) 119 0x2208 ∈ (ELEMENT OF) 120 0x220B ∋ (CONTAINS AS MEMBER) 121 0x2286 ⊆ (SUBSET OF OR EQUAL TO) 122 0x2287 ⊇ (SUPERSET OF OR EQUAL TO) 123 0x2282 ⊂ (SUBSET OF) 124 0x2283 ⊃ (SUPERSET OF) 125 0x222A ∪ (UNION) 126 0x2229 ∩ (INTERSECTION) 135 0x2227 ∧ (LOGICAL AND) 136 0x2228 ∨ (LOGICAL OR) 137 0xFFE2 ¬ (FULLWIDTH NOT SIGN) 138 0x21D2 ⇒ (RIGHTWARDS DOUBLE ARROW) 139 0x21D4 ⇔ (LEFT RIGHT DOUBLE ARROW) 140 0x2200 ∀ (FOR ALL) 141 0x2203 ∃ (THERE EXISTS) 153 0x2220 ∠ (ANGLE) 154 0x22A5 ⊥ (UP TACK) 155 0x2312 ⌒ (ARC) 156 0x2202 ∂ (PARTIAL DIFFERENTIAL) 157 0x2207 ∇ (NABLA) 158 0x2261 ≡ (IDENTICAL TO) 159 0x2252 ≒ (APPROXIMATELY EQUAL TO OR THE IMAGE OF) 160 0x226A ≪ (MUCH LESS-THAN) 161 0x226B ≫ (MUCH GREATER-THAN) 162 0x221A √ (SQUARE ROOT) 163 0x223D ∽ (REVERSED TILDE) 164 0x221D ∝ (PROPORTIONAL TO) 165 0x2235 ∵ (BECAUSE) 166 0x222B ∫ (INTEGRAL) 167 0x222C ∬ (DOUBLE INTEGRAL) 175 0x212B Å (ANGSTROM SIGN) 176 0x2030 ‰ (PER MILLE SIGN) 177 0x266F ♯ (MUSIC SHARP SIGN) 178 0x266D ♭ (MUSIC FLAT SIGN) 179 0x266A ♪ (EIGHTH NOTE) 180 0x2020 † (DAGGER) 181 0x2021 ‡ (DOUBLE DAGGER) 182 0x00B6 ¶ (PILCROW SIGN) 187 0x25EF ◯ (LARGE CIRCLE) 203 0xFF10 0 (FULLWIDTH DIGIT ZERO) 204 0xFF11 1 (FULLWIDTH DIGIT ONE) 205 0xFF12 2 (FULLWIDTH DIGIT TWO) 206 0xFF13 3 (FULLWIDTH DIGIT THREE) 207 0xFF14 4 (FULLWIDTH DIGIT FOUR) 208 0xFF15 5 (FULLWIDTH DIGIT FIVE) 209 0xFF16 6 (FULLWIDTH DIGIT SIX) 210 0xFF17 7 (FULLWIDTH DIGIT SEVEN) 211 0xFF18 8 (FULLWIDTH DIGIT EIGHT) 212 0xFF19 9 (FULLWIDTH DIGIT NINE) 220 0xFF21 A (FULLWIDTH LATIN CAPITAL LETTER A) 221 0xFF22 B (FULLWIDTH LATIN CAPITAL LETTER B) 222 0xFF23 C (FULLWIDTH LATIN CAPITAL LETTER C) 223 0xFF24 D (FULLWIDTH LATIN CAPITAL LETTER D) 224 0xFF25 E (FULLWIDTH LATIN CAPITAL LETTER E) 225 0xFF26 F (FULLWIDTH LATIN CAPITAL LETTER F) 226 0xFF27 G (FULLWIDTH LATIN CAPITAL LETTER G) 227 0xFF28 H (FULLWIDTH LATIN CAPITAL LETTER H) 228 0xFF29 I (FULLWIDTH LATIN CAPITAL LETTER I) 229 0xFF2A J (FULLWIDTH LATIN CAPITAL LETTER J) 230 0xFF2B K (FULLWIDTH LATIN CAPITAL LETTER K) 231 0xFF2C L (FULLWIDTH LATIN CAPITAL LETTER L) 232 0xFF2D M (FULLWIDTH LATIN CAPITAL LETTER M) 233 0xFF2E N (FULLWIDTH LATIN CAPITAL LETTER N) 234 0xFF2F O (FULLWIDTH LATIN CAPITAL LETTER O) 235 0xFF30 P (FULLWIDTH LATIN CAPITAL LETTER P) 236 0xFF31 Q (FULLWIDTH LATIN CAPITAL LETTER Q) 237 0xFF32 R (FULLWIDTH LATIN CAPITAL LETTER R) 238 0xFF33 S (FULLWIDTH LATIN CAPITAL LETTER S) 239 0xFF34 T (FULLWIDTH LATIN CAPITAL LETTER T) 240 0xFF35 U (FULLWIDTH LATIN CAPITAL LETTER U) 241 0xFF36 V (FULLWIDTH LATIN CAPITAL LETTER V) 242 0xFF37 W (FULLWIDTH LATIN CAPITAL LETTER W) 243 0xFF38 X (FULLWIDTH LATIN CAPITAL LETTER X) 244 0xFF39 Y (FULLWIDTH LATIN CAPITAL LETTER Y) 245 0xFF3A Z (FULLWIDTH LATIN CAPITAL LETTER Z) 252 0xFF41 a (FULLWIDTH LATIN SMALL LETTER A) 253 0xFF42 b (FULLWIDTH LATIN SMALL LETTER B) 254 0xFF43 c (FULLWIDTH LATIN SMALL LETTER C) 255 0xFF44 d (FULLWIDTH LATIN SMALL LETTER D) 256 0xFF45 e (FULLWIDTH LATIN SMALL LETTER E) 257 0xFF46 f (FULLWIDTH LATIN SMALL LETTER F) 258 0xFF47 g (FULLWIDTH LATIN SMALL LETTER G) 259 0xFF48 h (FULLWIDTH LATIN SMALL LETTER H) 260 0xFF49 i (FULLWIDTH LATIN SMALL LETTER I) 261 0xFF4A j (FULLWIDTH LATIN SMALL LETTER J) 262 0xFF4B k (FULLWIDTH LATIN SMALL LETTER K) 263 0xFF4C l (FULLWIDTH LATIN SMALL LETTER L) 264 0xFF4D m (FULLWIDTH LATIN SMALL LETTER M) 265 0xFF4E n (FULLWIDTH LATIN SMALL LETTER N) 266 0xFF4F o (FULLWIDTH LATIN SMALL LETTER O) 267 0xFF50 p (FULLWIDTH LATIN SMALL LETTER P) 268 0xFF51 q (FULLWIDTH LATIN SMALL LETTER Q) 269 0xFF52 r (FULLWIDTH LATIN SMALL LETTER R) 270 0xFF53 s (FULLWIDTH LATIN SMALL LETTER S) 271 0xFF54 t (FULLWIDTH LATIN SMALL LETTER T) 272 0xFF55 u (FULLWIDTH LATIN SMALL LETTER U) 273 0xFF56 v (FULLWIDTH LATIN SMALL LETTER V) 274 0xFF57 w (FULLWIDTH LATIN SMALL LETTER W) 275 0xFF58 x (FULLWIDTH LATIN SMALL LETTER X) 276 0xFF59 y (FULLWIDTH LATIN SMALL LETTER Y) 277 0xFF5A z (FULLWIDTH LATIN SMALL LETTER Z) 282 0x3041 ぁ (HIRAGANA LETTER SMALL A) 283 0x3042 あ (HIRAGANA LETTER A) 284 0x3043 ぃ (HIRAGANA LETTER SMALL I) 285 0x3044 い (HIRAGANA LETTER I) 286 0x3045 ぅ (HIRAGANA LETTER SMALL U) 287 0x3046 う (HIRAGANA LETTER U) 288 0x3047 ぇ (HIRAGANA LETTER SMALL E) 289 0x3048 え (HIRAGANA LETTER E) 290 0x3049 ぉ (HIRAGANA LETTER SMALL O) 291 0x304A お (HIRAGANA LETTER O) 292 0x304B か (HIRAGANA LETTER KA) 293 0x304C が (HIRAGANA LETTER GA) 294 0x304D き (HIRAGANA LETTER KI) 295 0x304E ぎ (HIRAGANA LETTER GI) 296 0x304F く (HIRAGANA LETTER KU) 297 0x3050 ぐ (HIRAGANA LETTER GU) 298 0x3051 け (HIRAGANA LETTER KE) 299 0x3052 げ (HIRAGANA LETTER GE) 300 0x3053 こ (HIRAGANA LETTER KO) 301 0x3054 ご (HIRAGANA LETTER GO) 302 0x3055 さ (HIRAGANA LETTER SA) 303 0x3056 ざ (HIRAGANA LETTER ZA) 304 0x3057 し (HIRAGANA LETTER SI) 305 0x3058 じ (HIRAGANA LETTER ZI) 306 0x3059 す (HIRAGANA LETTER SU) 307 0x305A ず (HIRAGANA LETTER ZU) 308 0x305B せ (HIRAGANA LETTER SE) 309 0x305C ぜ (HIRAGANA LETTER ZE) 310 0x305D そ (HIRAGANA LETTER SO) 311 0x305E ぞ (HIRAGANA LETTER ZO) 312 0x305F た (HIRAGANA LETTER TA) 313 0x3060 だ (HIRAGANA LETTER DA) 314 0x3061 ち (HIRAGANA LETTER TI) 315 0x3062 ぢ (HIRAGANA LETTER DI) 316 0x3063 っ (HIRAGANA LETTER SMALL TU) 317 0x3064 つ (HIRAGANA LETTER TU) 318 0x3065 づ (HIRAGANA LETTER DU) 319 0x3066 て (HIRAGANA LETTER TE) 320 0x3067 で (HIRAGANA LETTER DE) 321 0x3068 と (HIRAGANA LETTER TO) 322 0x3069 ど (HIRAGANA LETTER DO) 323 0x306A な (HIRAGANA LETTER NA) 324 0x306B に (HIRAGANA LETTER NI) 325 0x306C ぬ (HIRAGANA LETTER NU) 326 0x306D ね (HIRAGANA LETTER NE) 327 0x306E の (HIRAGANA LETTER NO) 328 0x306F は (HIRAGANA LETTER HA) 329 0x3070 ば (HIRAGANA LETTER BA) 330 0x3071 ぱ (HIRAGANA LETTER PA) 331 0x3072 ひ (HIRAGANA LETTER HI) 332 0x3073 び (HIRAGANA LETTER BI) 333 0x3074 ぴ (HIRAGANA LETTER PI) 334 0x3075 ふ (HIRAGANA LETTER HU) 335 0x3076 ぶ (HIRAGANA LETTER BU) 336 0x3077 ぷ (HIRAGANA LETTER PU) 337 0x3078 へ (HIRAGANA LETTER HE) 338 0x3079 べ (HIRAGANA LETTER BE) 339 0x307A ぺ (HIRAGANA LETTER PE) 340 0x307B ほ (HIRAGANA LETTER HO) 341 0x307C ぼ (HIRAGANA LETTER BO) 342 0x307D ぽ (HIRAGANA LETTER PO) 343 0x307E ま (HIRAGANA LETTER MA) 344 0x307F み (HIRAGANA LETTER MI) 345 0x3080 む (HIRAGANA LETTER MU) 346 0x3081 め (HIRAGANA LETTER ME) 347 0x3082 も (HIRAGANA LETTER MO) 348 0x3083 ゃ (HIRAGANA LETTER SMALL YA) 349 0x3084 や (HIRAGANA LETTER YA) 350 0x3085 ゅ (HIRAGANA LETTER SMALL YU) 351 0x3086 ゆ (HIRAGANA LETTER YU) 352 0x3087 ょ (HIRAGANA LETTER SMALL YO) 353 0x3088 よ (HIRAGANA LETTER YO) 354 0x3089 ら (HIRAGANA LETTER RA) 355 0x308A り (HIRAGANA LETTER RI) 356 0x308B る (HIRAGANA LETTER RU) 357 0x308C れ (HIRAGANA LETTER RE) 358 0x308D ろ (HIRAGANA LETTER RO) 359 0x308E ゎ (HIRAGANA LETTER SMALL WA) 360 0x308F わ (HIRAGANA LETTER WA) 361 0x3090 ゐ (HIRAGANA LETTER WI) 362 0x3091 ゑ (HIRAGANA LETTER WE) 363 0x3092 を (HIRAGANA LETTER WO) 364 0x3093 ん (HIRAGANA LETTER N) 376 0x30A1 ァ (KATAKANA LETTER SMALL A) 377 0x30A2 ア (KATAKANA LETTER A) 378 0x30A3 ィ (KATAKANA LETTER SMALL I) 379 0x30A4 イ (KATAKANA LETTER I) 380 0x30A5 ゥ (KATAKANA LETTER SMALL U) 381 0x30A6 ウ (KATAKANA LETTER U) 382 0x30A7 ェ (KATAKANA LETTER SMALL E) 383 0x30A8 エ (KATAKANA LETTER E) 384 0x30A9 ォ (KATAKANA LETTER SMALL O) 385 0x30AA オ (KATAKANA LETTER O) 386 0x30AB カ (KATAKANA LETTER KA) 387 0x30AC ガ (KATAKANA LETTER GA) 388 0x30AD キ (KATAKANA LETTER KI) 389 0x30AE ギ (KATAKANA LETTER GI) 390 0x30AF ク (KATAKANA LETTER KU) 391 0x30B0 グ (KATAKANA LETTER GU) 392 0x30B1 ケ (KATAKANA LETTER KE) 393 0x30B2 ゲ (KATAKANA LETTER GE) 394 0x30B3 コ (KATAKANA LETTER KO) 395 0x30B4 ゴ (KATAKANA LETTER GO) 396 0x30B5 サ (KATAKANA LETTER SA) 397 0x30B6 ザ (KATAKANA LETTER ZA) 398 0x30B7 シ (KATAKANA LETTER SI) 399 0x30B8 ジ (KATAKANA LETTER ZI) 400 0x30B9 ス (KATAKANA LETTER SU) 401 0x30BA ズ (KATAKANA LETTER ZU) 402 0x30BB セ (KATAKANA LETTER SE) 403 0x30BC ゼ (KATAKANA LETTER ZE) 404 0x30BD ソ (KATAKANA LETTER SO) 405 0x30BE ゾ (KATAKANA LETTER ZO) 406 0x30BF タ (KATAKANA LETTER TA) 407 0x30C0 ダ (KATAKANA LETTER DA) 408 0x30C1 チ (KATAKANA LETTER TI) 409 0x30C2 ヂ (KATAKANA LETTER DI) 410 0x30C3 ッ (KATAKANA LETTER SMALL TU) 411 0x30C4 ツ (KATAKANA LETTER TU) 412 0x30C5 ヅ (KATAKANA LETTER DU) 413 0x30C6 テ (KATAKANA LETTER TE) 414 0x30C7 デ (KATAKANA LETTER DE) 415 0x30C8 ト (KATAKANA LETTER TO) 416 0x30C9 ド (KATAKANA LETTER DO) 417 0x30CA ナ (KATAKANA LETTER NA) 418 0x30CB ニ (KATAKANA LETTER NI) 419 0x30CC ヌ (KATAKANA LETTER NU) 420 0x30CD ネ (KATAKANA LETTER NE) 421 0x30CE ノ (KATAKANA LETTER NO) 422 0x30CF ハ (KATAKANA LETTER HA) 423 0x30D0 バ (KATAKANA LETTER BA) 424 0x30D1 パ (KATAKANA LETTER PA) 425 0x30D2 ヒ (KATAKANA LETTER HI) 426 0x30D3 ビ (KATAKANA LETTER BI) 427 0x30D4 ピ (KATAKANA LETTER PI) 428 0x30D5 フ (KATAKANA LETTER HU) 429 0x30D6 ブ (KATAKANA LETTER BU) 430 0x30D7 プ (KATAKANA LETTER PU) 431 0x30D8 ヘ (KATAKANA LETTER HE) 432 0x30D9 ベ (KATAKANA LETTER BE) 433 0x30DA ペ (KATAKANA LETTER PE) 434 0x30DB ホ (KATAKANA LETTER HO) 435 0x30DC ボ (KATAKANA LETTER BO) 436 0x30DD ポ (KATAKANA LETTER PO) 437 0x30DE マ (KATAKANA LETTER MA) 438 0x30DF ミ (KATAKANA LETTER MI) 439 0x30E0 ム (KATAKANA LETTER MU) 440 0x30E1 メ (KATAKANA LETTER ME) 441 0x30E2 モ (KATAKANA LETTER MO) 442 0x30E3 ャ (KATAKANA LETTER SMALL YA) 443 0x30E4 ヤ (KATAKANA LETTER YA) 444 0x30E5 ュ (KATAKANA LETTER SMALL YU) 445 0x30E6 ユ (KATAKANA LETTER YU) 446 0x30E7 ョ (KATAKANA LETTER SMALL YO) 447 0x30E8 ヨ (KATAKANA LETTER YO) 448 0x30E9 ラ (KATAKANA LETTER RA) 449 0x30EA リ (KATAKANA LETTER RI) 450 0x30EB ル (KATAKANA LETTER RU) 451 0x30EC レ (KATAKANA LETTER RE) 452 0x30ED ロ (KATAKANA LETTER RO) 453 0x30EE ヮ (KATAKANA LETTER SMALL WA) 454 0x30EF ワ (KATAKANA LETTER WA) 455 0x30F0 ヰ (KATAKANA LETTER WI) 456 0x30F1 ヱ (KATAKANA LETTER WE) 457 0x30F2 ヲ (KATAKANA LETTER WO) 458 0x30F3 ン (KATAKANA LETTER N) 459 0x30F4 ヴ (KATAKANA LETTER VU) 460 0x30F5 ヵ (KATAKANA LETTER SMALL KA) 461 0x30F6 ヶ (KATAKANA LETTER SMALL KE) 470 0x0391 Α (GREEK CAPITAL LETTER ALPHA) 471 0x0392 Β (GREEK CAPITAL LETTER BETA) 472 0x0393 Γ (GREEK CAPITAL LETTER GAMMA) 473 0x0394 Δ (GREEK CAPITAL LETTER DELTA) 474 0x0395 Ε (GREEK CAPITAL LETTER EPSILON) 475 0x0396 Ζ (GREEK CAPITAL LETTER ZETA) 476 0x0397 Η (GREEK CAPITAL LETTER ETA) 477 0x0398 Θ (GREEK CAPITAL LETTER THETA) 478 0x0399 Ι (GREEK CAPITAL LETTER IOTA) 479 0x039A Κ (GREEK CAPITAL LETTER KAPPA) 480 0x039B Λ (GREEK CAPITAL LETTER LAMDA) 481 0x039C Μ (GREEK CAPITAL LETTER MU) 482 0x039D Ν (GREEK CAPITAL LETTER NU) 483 0x039E Ξ (GREEK CAPITAL LETTER XI) 484 0x039F Ο (GREEK CAPITAL LETTER OMICRON) 485 0x03A0 Π (GREEK CAPITAL LETTER PI) 486 0x03A1 Ρ (GREEK CAPITAL LETTER RHO) 487 0x03A3 Σ (GREEK CAPITAL LETTER SIGMA) 488 0x03A4 Τ (GREEK CAPITAL LETTER TAU) 489 0x03A5 Υ (GREEK CAPITAL LETTER UPSILON) 490 0x03A6 Φ (GREEK CAPITAL LETTER PHI) 491 0x03A7 Χ (GREEK CAPITAL LETTER CHI) 492 0x03A8 Ψ (GREEK CAPITAL LETTER PSI) 493 0x03A9 Ω (GREEK CAPITAL LETTER OMEGA) 502 0x03B1 α (GREEK SMALL LETTER ALPHA) 503 0x03B2 β (GREEK SMALL LETTER BETA) 504 0x03B3 γ (GREEK SMALL LETTER GAMMA) 505 0x03B4 δ (GREEK SMALL LETTER DELTA) 506 0x03B5 ε (GREEK SMALL LETTER EPSILON) 507 0x03B6 ζ (GREEK SMALL LETTER ZETA) 508 0x03B7 η (GREEK SMALL LETTER ETA) 509 0x03B8 θ (GREEK SMALL LETTER THETA) 510 0x03B9 ι (GREEK SMALL LETTER IOTA) 511 0x03BA κ (GREEK SMALL LETTER KAPPA) 512 0x03BB λ (GREEK SMALL LETTER LAMDA) 513 0x03BC μ (GREEK SMALL LETTER MU) 514 0x03BD ν (GREEK SMALL LETTER NU) 515 0x03BE ξ (GREEK SMALL LETTER XI) 516 0x03BF ο (GREEK SMALL LETTER OMICRON) 517 0x03C0 π (GREEK SMALL LETTER PI) 518 0x03C1 ρ (GREEK SMALL LETTER RHO) 519 0x03C3 σ (GREEK SMALL LETTER SIGMA) 520 0x03C4 τ (GREEK SMALL LETTER TAU) 521 0x03C5 υ (GREEK SMALL LETTER UPSILON) 522 0x03C6 φ (GREEK SMALL LETTER PHI) 523 0x03C7 χ (GREEK SMALL LETTER CHI) 524 0x03C8 ψ (GREEK SMALL LETTER PSI) 525 0x03C9 ω (GREEK SMALL LETTER OMEGA) 564 0x0410 А (CYRILLIC CAPITAL LETTER A) 565 0x0411 Б (CYRILLIC CAPITAL LETTER BE) 566 0x0412 В (CYRILLIC CAPITAL LETTER VE) 567 0x0413 Г (CYRILLIC CAPITAL LETTER GHE) 568 0x0414 Д (CYRILLIC CAPITAL LETTER DE) 569 0x0415 Е (CYRILLIC CAPITAL LETTER IE) 570 0x0401 Ё (CYRILLIC CAPITAL LETTER IO) 571 0x0416 Ж (CYRILLIC CAPITAL LETTER ZHE) 572 0x0417 З (CYRILLIC CAPITAL LETTER ZE) 573 0x0418 И (CYRILLIC CAPITAL LETTER I) 574 0x0419 Й (CYRILLIC CAPITAL LETTER SHORT I) 575 0x041A К (CYRILLIC CAPITAL LETTER KA) 576 0x041B Л (CYRILLIC CAPITAL LETTER EL) 577 0x041C М (CYRILLIC CAPITAL LETTER EM) 578 0x041D Н (CYRILLIC CAPITAL LETTER EN) 579 0x041E О (CYRILLIC CAPITAL LETTER O) 580 0x041F П (CYRILLIC CAPITAL LETTER PE) 581 0x0420 Р (CYRILLIC CAPITAL LETTER ER) 582 0x0421 С (CYRILLIC CAPITAL LETTER ES) 583 0x0422 Т (CYRILLIC CAPITAL LETTER TE) 584 0x0423 У (CYRILLIC CAPITAL LETTER U) 585 0x0424 Ф (CYRILLIC CAPITAL LETTER EF) 586 0x0425 Х (CYRILLIC CAPITAL LETTER HA) 587 0x0426 Ц (CYRILLIC CAPITAL LETTER TSE) 588 0x0427 Ч (CYRILLIC CAPITAL LETTER CHE) 589 0x0428 Ш (CYRILLIC CAPITAL LETTER SHA) 590 0x0429 Щ (CYRILLIC CAPITAL LETTER SHCHA) 591 0x042A Ъ (CYRILLIC CAPITAL LETTER HARD SIGN) 592 0x042B Ы (CYRILLIC CAPITAL LETTER YERU) 593 0x042C Ь (CYRILLIC CAPITAL LETTER SOFT SIGN) 594 0x042D Э (CYRILLIC CAPITAL LETTER E) 595 0x042E Ю (CYRILLIC CAPITAL LETTER YU) 596 0x042F Я (CYRILLIC CAPITAL LETTER YA) 612 0x0430 а (CYRILLIC SMALL LETTER A) 613 0x0431 б (CYRILLIC SMALL LETTER BE) 614 0x0432 в (CYRILLIC SMALL LETTER VE) 615 0x0433 г (CYRILLIC SMALL LETTER GHE) 616 0x0434 д (CYRILLIC SMALL LETTER DE) 617 0x0435 е (CYRILLIC SMALL LETTER IE) 618 0x0451 ё (CYRILLIC SMALL LETTER IO) 619 0x0436 ж (CYRILLIC SMALL LETTER ZHE) 620 0x0437 з (CYRILLIC SMALL LETTER ZE) 621 0x0438 и (CYRILLIC SMALL LETTER I) 622 0x0439 й (CYRILLIC SMALL LETTER SHORT I) 623 0x043A к (CYRILLIC SMALL LETTER KA) 624 0x043B л (CYRILLIC SMALL LETTER EL) 625 0x043C м (CYRILLIC SMALL LETTER EM) 626 0x043D н (CYRILLIC SMALL LETTER EN) 627 0x043E о (CYRILLIC SMALL LETTER O) 628 0x043F п (CYRILLIC SMALL LETTER PE) 629 0x0440 р (CYRILLIC SMALL LETTER ER) 630 0x0441 с (CYRILLIC SMALL LETTER ES) 631 0x0442 т (CYRILLIC SMALL LETTER TE) 632 0x0443 у (CYRILLIC SMALL LETTER U) 633 0x0444 ф (CYRILLIC SMALL LETTER EF) 634 0x0445 х (CYRILLIC SMALL LETTER HA) 635 0x0446 ц (CYRILLIC SMALL LETTER TSE) 636 0x0447 ч (CYRILLIC SMALL LETTER CHE) 637 0x0448 ш (CYRILLIC SMALL LETTER SHA) 638 0x0449 щ (CYRILLIC SMALL LETTER SHCHA) 639 0x044A ъ (CYRILLIC SMALL LETTER HARD SIGN) 640 0x044B ы (CYRILLIC SMALL LETTER YERU) 641 0x044C ь (CYRILLIC SMALL LETTER SOFT SIGN) 642 0x044D э (CYRILLIC SMALL LETTER E) 643 0x044E ю (CYRILLIC SMALL LETTER YU) 644 0x044F я (CYRILLIC SMALL LETTER YA) 658 0x2500 ─ (BOX DRAWINGS LIGHT HORIZONTAL) 659 0x2502 │ (BOX DRAWINGS LIGHT VERTICAL) 660 0x250C ┌ (BOX DRAWINGS LIGHT DOWN AND RIGHT) 661 0x2510 ┐ (BOX DRAWINGS LIGHT DOWN AND LEFT) 662 0x2518 ┘ (BOX DRAWINGS LIGHT UP AND LEFT) 663 0x2514 └ (BOX DRAWINGS LIGHT UP AND RIGHT) 664 0x251C ├ (BOX DRAWINGS LIGHT VERTICAL AND RIGHT) 665 0x252C ┬ (BOX DRAWINGS LIGHT DOWN AND HORIZONTAL) 666 0x2524 ┤ (BOX DRAWINGS LIGHT VERTICAL AND LEFT) 667 0x2534 ┴ (BOX DRAWINGS LIGHT UP AND HORIZONTAL) 668 0x253C ┼ (BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL) 669 0x2501 ━ (BOX DRAWINGS HEAVY HORIZONTAL) 670 0x2503 ┃ (BOX DRAWINGS HEAVY VERTICAL) 671 0x250F ┏ (BOX DRAWINGS HEAVY DOWN AND RIGHT) 672 0x2513 ┓ (BOX DRAWINGS HEAVY DOWN AND LEFT) 673 0x251B ┛ (BOX DRAWINGS HEAVY UP AND LEFT) 674 0x2517 ┗ (BOX DRAWINGS HEAVY UP AND RIGHT) 675 0x2523 ┣ (BOX DRAWINGS HEAVY VERTICAL AND RIGHT) 676 0x2533 ┳ (BOX DRAWINGS HEAVY DOWN AND HORIZONTAL) 677 0x252B ┫ (BOX DRAWINGS HEAVY VERTICAL AND LEFT) 678 0x253B ┻ (BOX DRAWINGS HEAVY UP AND HORIZONTAL) 679 0x254B ╋ (BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL) 680 0x2520 ┠ (BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT) 681 0x252F ┯ (BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY) 682 0x2528 ┨ (BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT) 683 0x2537 ┷ (BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY) 684 0x253F ┿ (BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY) 685 0x251D ┝ (BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY) 686 0x2530 ┰ (BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT) 687 0x2525 ┥ (BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY) 688 0x2538 ┸ (BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT) 689 0x2542 ╂ (BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT) 1128 0x2460 ① (CIRCLED DIGIT ONE) 1129 0x2461 ② (CIRCLED DIGIT TWO) 1130 0x2462 ③ (CIRCLED DIGIT THREE) 1131 0x2463 ④ (CIRCLED DIGIT FOUR) 1132 0x2464 ⑤ (CIRCLED DIGIT FIVE) 1133 0x2465 ⑥ (CIRCLED DIGIT SIX) 1134 0x2466 ⑦ (CIRCLED DIGIT SEVEN) 1135 0x2467 ⑧ (CIRCLED DIGIT EIGHT) 1136 0x2468 ⑨ (CIRCLED DIGIT NINE) 1137 0x2469 ⑩ (CIRCLED NUMBER TEN) 1138 0x246A ⑪ (CIRCLED NUMBER ELEVEN) 1139 0x246B ⑫ (CIRCLED NUMBER TWELVE) 1140 0x246C ⑬ (CIRCLED NUMBER THIRTEEN) 1141 0x246D ⑭ (CIRCLED NUMBER FOURTEEN) 1142 0x246E ⑮ (CIRCLED NUMBER FIFTEEN) 1143 0x246F ⑯ (CIRCLED NUMBER SIXTEEN) 1144 0x2470 ⑰ (CIRCLED NUMBER SEVENTEEN) 1145 0x2471 ⑱ (CIRCLED NUMBER EIGHTEEN) 1146 0x2472 ⑲ (CIRCLED NUMBER NINETEEN) 1147 0x2473 ⑳ (CIRCLED NUMBER TWENTY) 1148 0x2160 Ⅰ (ROMAN NUMERAL ONE) 1149 0x2161 Ⅱ (ROMAN NUMERAL TWO) 1150 0x2162 Ⅲ (ROMAN NUMERAL THREE) 1151 0x2163 Ⅳ (ROMAN NUMERAL FOUR) 1152 0x2164 Ⅴ (ROMAN NUMERAL FIVE) 1153 0x2165 Ⅵ (ROMAN NUMERAL SIX) 1154 0x2166 Ⅶ (ROMAN NUMERAL SEVEN) 1155 0x2167 Ⅷ (ROMAN NUMERAL EIGHT) 1156 0x2168 Ⅸ (ROMAN NUMERAL NINE) 1157 0x2169 Ⅹ (ROMAN NUMERAL TEN) 1159 0x3349 ㍉ (SQUARE MIRI) 1160 0x3314 ㌔ (SQUARE KIRO) 1161 0x3322 ㌢ (SQUARE SENTI) 1162 0x334D ㍍ (SQUARE MEETORU) 1163 0x3318 ㌘ (SQUARE GURAMU) 1164 0x3327 ㌧ (SQUARE TON) 1165 0x3303 ㌃ (SQUARE AARU) 1166 0x3336 ㌶ (SQUARE HEKUTAARU) 1167 0x3351 ㍑ (SQUARE RITTORU) 1168 0x3357 ㍗ (SQUARE WATTO) 1169 0x330D ㌍ (SQUARE KARORII) 1170 0x3326 ㌦ (SQUARE DORU) 1171 0x3323 ㌣ (SQUARE SENTO) 1172 0x332B ㌫ (SQUARE PAASENTO) 1173 0x334A ㍊ (SQUARE MIRIBAARU) 1174 0x333B ㌻ (SQUARE PEEZI) 1175 0x339C ㎜ (SQUARE MM) 1176 0x339D ㎝ (SQUARE CM) 1177 0x339E ㎞ (SQUARE KM) 1178 0x338E ㎎ (SQUARE MG) 1179 0x338F ㎏ (SQUARE KG) 1180 0x33C4 ㏄ (SQUARE CC) 1181 0x33A1 ㎡ (SQUARE M SQUARED) 1190 0x337B ㍻ (SQUARE ERA NAME HEISEI) 1191 0x301D 〝 (REVERSED DOUBLE PRIME QUOTATION MARK) 1192 0x301F 〟 (LOW DOUBLE PRIME QUOTATION MARK) 1193 0x2116 № (NUMERO SIGN) 1194 0x33CD ㏍ (SQUARE KK) 1195 0x2121 ℡ (TELEPHONE SIGN) 1196 0x32A4 ㊤ (CIRCLED IDEOGRAPH HIGH) 1197 0x32A5 ㊥ (CIRCLED IDEOGRAPH CENTRE) 1198 0x32A6 ㊦ (CIRCLED IDEOGRAPH LOW) 1199 0x32A7 ㊧ (CIRCLED IDEOGRAPH LEFT) 1200 0x32A8 ㊨ (CIRCLED IDEOGRAPH RIGHT) 1201 0x3231 ㈱ (PARENTHESIZED IDEOGRAPH STOCK) 1202 0x3232 ㈲ (PARENTHESIZED IDEOGRAPH HAVE) 1203 0x3239 ㈹ (PARENTHESIZED IDEOGRAPH REPRESENT) 1204 0x337E ㍾ (SQUARE ERA NAME MEIZI) 1205 0x337D ㍽ (SQUARE ERA NAME TAISYOU) 1206 0x337C ㍼ (SQUARE ERA NAME SYOUWA) 1207 0x2252 ≒ (APPROXIMATELY EQUAL TO OR THE IMAGE OF) 1208 0x2261 ≡ (IDENTICAL TO) 1209 0x222B ∫ (INTEGRAL) 1210 0x222E ∮ (CONTOUR INTEGRAL) 1211 0x2211 ∑ (N-ARY SUMMATION) 1212 0x221A √ (SQUARE ROOT) 1213 0x22A5 ⊥ (UP TACK) 1214 0x2220 ∠ (ANGLE) 1215 0x221F ∟ (RIGHT ANGLE) 1216 0x22BF ⊿ (RIGHT TRIANGLE) 1217 0x2235 ∵ (BECAUSE) 1218 0x2229 ∩ (INTERSECTION) 1219 0x222A ∪ (UNION) 1410 0x4E9C 亜 (<CJK Ideograph>) 1411 0x5516 唖 (<CJK Ideograph>) 1412 0x5A03 娃 (<CJK Ideograph>) 1413 0x963F 阿 (<CJK Ideograph>) 1414 0x54C0 哀 (<CJK Ideograph>) 1415 0x611B 愛 (<CJK Ideograph>) 1416 0x6328 挨 (<CJK Ideograph>) 1417 0x59F6 姶 (<CJK Ideograph>) 1418 0x9022 逢 (<CJK Ideograph>) 1419 0x8475 葵 (<CJK Ideograph>) 1420 0x831C 茜 (<CJK Ideograph>) 1421 0x7A50 穐 (<CJK Ideograph>) 1422 0x60AA 悪 (<CJK Ideograph>) 1423 0x63E1 握 (<CJK Ideograph>) 1424 0x6E25 渥 (<CJK Ideograph>) 1425 0x65ED 旭 (<CJK Ideograph>) 1426 0x8466 葦 (<CJK Ideograph>) 1427 0x82A6 芦 (<CJK Ideograph>) 1428 0x9BF5 鯵 (<CJK Ideograph>) 1429 0x6893 梓 (<CJK Ideograph>) 1430 0x5727 圧 (<CJK Ideograph>) 1431 0x65A1 斡 (<CJK Ideograph>) 1432 0x6271 扱 (<CJK Ideograph>) 1433 0x5B9B 宛 (<CJK Ideograph>) 1434 0x59D0 姐 (<CJK Ideograph>) 1435 0x867B 虻 (<CJK Ideograph>) 1436 0x98F4 飴 (<CJK Ideograph>) 1437 0x7D62 絢 (<CJK Ideograph>) 1438 0x7DBE 綾 (<CJK Ideograph>) 1439 0x9B8E 鮎 (<CJK Ideograph>) 1440 0x6216 或 (<CJK Ideograph>) 1441 0x7C9F 粟 (<CJK Ideograph>) 1442 0x88B7 袷 (<CJK Ideograph>) 1443 0x5B89 安 (<CJK Ideograph>) 1444 0x5EB5 庵 (<CJK Ideograph>) 1445 0x6309 按 (<CJK Ideograph>) 1446 0x6697 暗 (<CJK Ideograph>) 1447 0x6848 案 (<CJK Ideograph>) 1448 0x95C7 闇 (<CJK Ideograph>) 1449 0x978D 鞍 (<CJK Ideograph>) 1450 0x674F 杏 (<CJK Ideograph>) 1451 0x4EE5 以 (<CJK Ideograph>) 1452 0x4F0A 伊 (<CJK Ideograph>) 1453 0x4F4D 位 (<CJK Ideograph>) 1454 0x4F9D 依 (<CJK Ideograph>) 1455 0x5049 偉 (<CJK Ideograph>) 1456 0x56F2 囲 (<CJK Ideograph>) 1457 0x5937 夷 (<CJK Ideograph>) 1458 0x59D4 委 (<CJK Ideograph>) 1459 0x5A01 威 (<CJK Ideograph>) 1460 0x5C09 尉 (<CJK Ideograph>) 1461 0x60DF 惟 (<CJK Ideograph>) 1462 0x610F 意 (<CJK Ideograph>) 1463 0x6170 慰 (<CJK Ideograph>) 1464 0x6613 易 (<CJK Ideograph>) 1465 0x6905 椅 (<CJK Ideograph>) 1466 0x70BA 為 (<CJK Ideograph>) 1467 0x754F 畏 (<CJK Ideograph>) 1468 0x7570 異 (<CJK Ideograph>) 1469 0x79FB 移 (<CJK Ideograph>) 1470 0x7DAD 維 (<CJK Ideograph>) 1471 0x7DEF 緯 (<CJK Ideograph>) 1472 0x80C3 胃 (<CJK Ideograph>) 1473 0x840E 萎 (<CJK Ideograph>) 1474 0x8863 衣 (<CJK Ideograph>) 1475 0x8B02 謂 (<CJK Ideograph>) 1476 0x9055 違 (<CJK Ideograph>) 1477 0x907A 遺 (<CJK Ideograph>) 1478 0x533B 医 (<CJK Ideograph>) 1479 0x4E95 井 (<CJK Ideograph>) 1480 0x4EA5 亥 (<CJK Ideograph>) 1481 0x57DF 域 (<CJK Ideograph>) 1482 0x80B2 育 (<CJK Ideograph>) 1483 0x90C1 郁 (<CJK Ideograph>) 1484 0x78EF 磯 (<CJK Ideograph>) 1485 0x4E00 一 (<CJK Ideograph>) 1486 0x58F1 壱 (<CJK Ideograph>) 1487 0x6EA2 溢 (<CJK Ideograph>) 1488 0x9038 逸 (<CJK Ideograph>) 1489 0x7A32 稲 (<CJK Ideograph>) 1490 0x8328 茨 (<CJK Ideograph>) 1491 0x828B 芋 (<CJK Ideograph>) 1492 0x9C2F 鰯 (<CJK Ideograph>) 1493 0x5141 允 (<CJK Ideograph>) 1494 0x5370 印 (<CJK Ideograph>) 1495 0x54BD 咽 (<CJK Ideograph>) 1496 0x54E1 員 (<CJK Ideograph>) 1497 0x56E0 因 (<CJK Ideograph>) 1498 0x59FB 姻 (<CJK Ideograph>) 1499 0x5F15 引 (<CJK Ideograph>) 1500 0x98F2 飲 (<CJK Ideograph>) 1501 0x6DEB 淫 (<CJK Ideograph>) 1502 0x80E4 胤 (<CJK Ideograph>) 1503 0x852D 蔭 (<CJK Ideograph>) 1504 0x9662 院 (<CJK Ideograph>) 1505 0x9670 陰 (<CJK Ideograph>) 1506 0x96A0 隠 (<CJK Ideograph>) 1507 0x97FB 韻 (<CJK Ideograph>) 1508 0x540B 吋 (<CJK Ideograph>) 1509 0x53F3 右 (<CJK Ideograph>) 1510 0x5B87 宇 (<CJK Ideograph>) 1511 0x70CF 烏 (<CJK Ideograph>) 1512 0x7FBD 羽 (<CJK Ideograph>) 1513 0x8FC2 迂 (<CJK Ideograph>) 1514 0x96E8 雨 (<CJK Ideograph>) 1515 0x536F 卯 (<CJK Ideograph>) 1516 0x9D5C 鵜 (<CJK Ideograph>) 1517 0x7ABA 窺 (<CJK Ideograph>) 1518 0x4E11 丑 (<CJK Ideograph>) 1519 0x7893 碓 (<CJK Ideograph>) 1520 0x81FC 臼 (<CJK Ideograph>) 1521 0x6E26 渦 (<CJK Ideograph>) 1522 0x5618 嘘 (<CJK Ideograph>) 1523 0x5504 唄 (<CJK Ideograph>) 1524 0x6B1D 欝 (<CJK Ideograph>) 1525 0x851A 蔚 (<CJK Ideograph>) 1526 0x9C3B 鰻 (<CJK Ideograph>) 1527 0x59E5 姥 (<CJK Ideograph>) 1528 0x53A9 厩 (<CJK Ideograph>) 1529 0x6D66 浦 (<CJK Ideograph>) 1530 0x74DC 瓜 (<CJK Ideograph>) 1531 0x958F 閏 (<CJK Ideograph>) 1532 0x5642 噂 (<CJK Ideograph>) 1533 0x4E91 云 (<CJK Ideograph>) 1534 0x904B 運 (<CJK Ideograph>) 1535 0x96F2 雲 (<CJK Ideograph>) 1536 0x834F 荏 (<CJK Ideograph>) 1537 0x990C 餌 (<CJK Ideograph>) 1538 0x53E1 叡 (<CJK Ideograph>) 1539 0x55B6 営 (<CJK Ideograph>) 1540 0x5B30 嬰 (<CJK Ideograph>) 1541 0x5F71 影 (<CJK Ideograph>) 1542 0x6620 映 (<CJK Ideograph>) 1543 0x66F3 曳 (<CJK Ideograph>) 1544 0x6804 栄 (<CJK Ideograph>) 1545 0x6C38 永 (<CJK Ideograph>) 1546 0x6CF3 泳 (<CJK Ideograph>) 1547 0x6D29 洩 (<CJK Ideograph>) 1548 0x745B 瑛 (<CJK Ideograph>) 1549 0x76C8 盈 (<CJK Ideograph>) 1550 0x7A4E 穎 (<CJK Ideograph>) 1551 0x9834 頴 (<CJK Ideograph>) 1552 0x82F1 英 (<CJK Ideograph>) 1553 0x885B 衛 (<CJK Ideograph>) 1554 0x8A60 詠 (<CJK Ideograph>) 1555 0x92ED 鋭 (<CJK Ideograph>) 1556 0x6DB2 液 (<CJK Ideograph>) 1557 0x75AB 疫 (<CJK Ideograph>) 1558 0x76CA 益 (<CJK Ideograph>) 1559 0x99C5 駅 (<CJK Ideograph>) 1560 0x60A6 悦 (<CJK Ideograph>) 1561 0x8B01 謁 (<CJK Ideograph>) 1562 0x8D8A 越 (<CJK Ideograph>) 1563 0x95B2 閲 (<CJK Ideograph>) 1564 0x698E 榎 (<CJK Ideograph>) 1565 0x53AD 厭 (<CJK Ideograph>) 1566 0x5186 円 (<CJK Ideograph>) 1567 0x5712 園 (<CJK Ideograph>) 1568 0x5830 堰 (<CJK Ideograph>) 1569 0x5944 奄 (<CJK Ideograph>) 1570 0x5BB4 宴 (<CJK Ideograph>) 1571 0x5EF6 延 (<CJK Ideograph>) 1572 0x6028 怨 (<CJK Ideograph>) 1573 0x63A9 掩 (<CJK Ideograph>) 1574 0x63F4 援 (<CJK Ideograph>) 1575 0x6CBF 沿 (<CJK Ideograph>) 1576 0x6F14 演 (<CJK Ideograph>) 1577 0x708E 炎 (<CJK Ideograph>) 1578 0x7114 焔 (<CJK Ideograph>) 1579 0x7159 煙 (<CJK Ideograph>) 1580 0x71D5 燕 (<CJK Ideograph>) 1581 0x733F 猿 (<CJK Ideograph>) 1582 0x7E01 縁 (<CJK Ideograph>) 1583 0x8276 艶 (<CJK Ideograph>) 1584 0x82D1 苑 (<CJK Ideograph>) 1585 0x8597 薗 (<CJK Ideograph>) 1586 0x9060 遠 (<CJK Ideograph>) 1587 0x925B 鉛 (<CJK Ideograph>) 1588 0x9D1B 鴛 (<CJK Ideograph>) 1589 0x5869 塩 (<CJK Ideograph>) 1590 0x65BC 於 (<CJK Ideograph>) 1591 0x6C5A 汚 (<CJK Ideograph>) 1592 0x7525 甥 (<CJK Ideograph>) 1593 0x51F9 凹 (<CJK Ideograph>) 1594 0x592E 央 (<CJK Ideograph>) 1595 0x5965 奥 (<CJK Ideograph>) 1596 0x5F80 往 (<CJK Ideograph>) 1597 0x5FDC 応 (<CJK Ideograph>) 1598 0x62BC 押 (<CJK Ideograph>) 1599 0x65FA 旺 (<CJK Ideograph>) 1600 0x6A2A 横 (<CJK Ideograph>) 1601 0x6B27 欧 (<CJK Ideograph>) 1602 0x6BB4 殴 (<CJK Ideograph>) 1603 0x738B 王 (<CJK Ideograph>) 1604 0x7FC1 翁 (<CJK Ideograph>) 1605 0x8956 襖 (<CJK Ideograph>) 1606 0x9D2C 鴬 (<CJK Ideograph>) 1607 0x9D0E 鴎 (<CJK Ideograph>) 1608 0x9EC4 黄 (<CJK Ideograph>) 1609 0x5CA1 岡 (<CJK Ideograph>) 1610 0x6C96 沖 (<CJK Ideograph>) 1611 0x837B 荻 (<CJK Ideograph>) 1612 0x5104 億 (<CJK Ideograph>) 1613 0x5C4B 屋 (<CJK Ideograph>) 1614 0x61B6 憶 (<CJK Ideograph>) 1615 0x81C6 臆 (<CJK Ideograph>) 1616 0x6876 桶 (<CJK Ideograph>) 1617 0x7261 牡 (<CJK Ideograph>) 1618 0x4E59 乙 (<CJK Ideograph>) 1619 0x4FFA 俺 (<CJK Ideograph>) 1620 0x5378 卸 (<CJK Ideograph>) 1621 0x6069 恩 (<CJK Ideograph>) 1622 0x6E29 温 (<CJK Ideograph>) 1623 0x7A4F 穏 (<CJK Ideograph>) 1624 0x97F3 音 (<CJK Ideograph>) 1625 0x4E0B 下 (<CJK Ideograph>) 1626 0x5316 化 (<CJK Ideograph>) 1627 0x4EEE 仮 (<CJK Ideograph>) 1628 0x4F55 何 (<CJK Ideograph>) 1629 0x4F3D 伽 (<CJK Ideograph>) 1630 0x4FA1 価 (<CJK Ideograph>) 1631 0x4F73 佳 (<CJK Ideograph>) 1632 0x52A0 加 (<CJK Ideograph>) 1633 0x53EF 可 (<CJK Ideograph>) 1634 0x5609 嘉 (<CJK Ideograph>) 1635 0x590F 夏 (<CJK Ideograph>) 1636 0x5AC1 嫁 (<CJK Ideograph>) 1637 0x5BB6 家 (<CJK Ideograph>) 1638 0x5BE1 寡 (<CJK Ideograph>) 1639 0x79D1 科 (<CJK Ideograph>) 1640 0x6687 暇 (<CJK Ideograph>) 1641 0x679C 果 (<CJK Ideograph>) 1642 0x67B6 架 (<CJK Ideograph>) 1643 0x6B4C 歌 (<CJK Ideograph>) 1644 0x6CB3 河 (<CJK Ideograph>) 1645 0x706B 火 (<CJK Ideograph>) 1646 0x73C2 珂 (<CJK Ideograph>) 1647 0x798D 禍 (<CJK Ideograph>) 1648 0x79BE 禾 (<CJK Ideograph>) 1649 0x7A3C 稼 (<CJK Ideograph>) 1650 0x7B87 箇 (<CJK Ideograph>) 1651 0x82B1 花 (<CJK Ideograph>) 1652 0x82DB 苛 (<CJK Ideograph>) 1653 0x8304 茄 (<CJK Ideograph>) 1654 0x8377 荷 (<CJK Ideograph>) 1655 0x83EF 華 (<CJK Ideograph>) 1656 0x83D3 菓 (<CJK Ideograph>) 1657 0x8766 蝦 (<CJK Ideograph>) 1658 0x8AB2 課 (<CJK Ideograph>) 1659 0x5629 嘩 (<CJK Ideograph>) 1660 0x8CA8 貨 (<CJK Ideograph>) 1661 0x8FE6 迦 (<CJK Ideograph>) 1662 0x904E 過 (<CJK Ideograph>) 1663 0x971E 霞 (<CJK Ideograph>) 1664 0x868A 蚊 (<CJK Ideograph>) 1665 0x4FC4 俄 (<CJK Ideograph>) 1666 0x5CE8 峨 (<CJK Ideograph>) 1667 0x6211 我 (<CJK Ideograph>) 1668 0x7259 牙 (<CJK Ideograph>) 1669 0x753B 画 (<CJK Ideograph>) 1670 0x81E5 臥 (<CJK Ideograph>) 1671 0x82BD 芽 (<CJK Ideograph>) 1672 0x86FE 蛾 (<CJK Ideograph>) 1673 0x8CC0 賀 (<CJK Ideograph>) 1674 0x96C5 雅 (<CJK Ideograph>) 1675 0x9913 餓 (<CJK Ideograph>) 1676 0x99D5 駕 (<CJK Ideograph>) 1677 0x4ECB 介 (<CJK Ideograph>) 1678 0x4F1A 会 (<CJK Ideograph>) 1679 0x89E3 解 (<CJK Ideograph>) 1680 0x56DE 回 (<CJK Ideograph>) 1681 0x584A 塊 (<CJK Ideograph>) 1682 0x58CA 壊 (<CJK Ideograph>) 1683 0x5EFB 廻 (<CJK Ideograph>) 1684 0x5FEB 快 (<CJK Ideograph>) 1685 0x602A 怪 (<CJK Ideograph>) 1686 0x6094 悔 (<CJK Ideograph>) 1687 0x6062 恢 (<CJK Ideograph>) 1688 0x61D0 懐 (<CJK Ideograph>) 1689 0x6212 戒 (<CJK Ideograph>) 1690 0x62D0 拐 (<CJK Ideograph>) 1691 0x6539 改 (<CJK Ideograph>) 1692 0x9B41 魁 (<CJK Ideograph>) 1693 0x6666 晦 (<CJK Ideograph>) 1694 0x68B0 械 (<CJK Ideograph>) 1695 0x6D77 海 (<CJK Ideograph>) 1696 0x7070 灰 (<CJK Ideograph>) 1697 0x754C 界 (<CJK Ideograph>) 1698 0x7686 皆 (<CJK Ideograph>) 1699 0x7D75 絵 (<CJK Ideograph>) 1700 0x82A5 芥 (<CJK Ideograph>) 1701 0x87F9 蟹 (<CJK Ideograph>) 1702 0x958B 開 (<CJK Ideograph>) 1703 0x968E 階 (<CJK Ideograph>) 1704 0x8C9D 貝 (<CJK Ideograph>) 1705 0x51F1 凱 (<CJK Ideograph>) 1706 0x52BE 劾 (<CJK Ideograph>) 1707 0x5916 外 (<CJK Ideograph>) 1708 0x54B3 咳 (<CJK Ideograph>) 1709 0x5BB3 害 (<CJK Ideograph>) 1710 0x5D16 崖 (<CJK Ideograph>) 1711 0x6168 慨 (<CJK Ideograph>) 1712 0x6982 概 (<CJK Ideograph>) 1713 0x6DAF 涯 (<CJK Ideograph>) 1714 0x788D 碍 (<CJK Ideograph>) 1715 0x84CB 蓋 (<CJK Ideograph>) 1716 0x8857 街 (<CJK Ideograph>) 1717 0x8A72 該 (<CJK Ideograph>) 1718 0x93A7 鎧 (<CJK Ideograph>) 1719 0x9AB8 骸 (<CJK Ideograph>) 1720 0x6D6C 浬 (<CJK Ideograph>) 1721 0x99A8 馨 (<CJK Ideograph>) 1722 0x86D9 蛙 (<CJK Ideograph>) 1723 0x57A3 垣 (<CJK Ideograph>) 1724 0x67FF 柿 (<CJK Ideograph>) 1725 0x86CE 蛎 (<CJK Ideograph>) 1726 0x920E 鈎 (<CJK Ideograph>) 1727 0x5283 劃 (<CJK Ideograph>) 1728 0x5687 嚇 (<CJK Ideograph>) 1729 0x5404 各 (<CJK Ideograph>) 1730 0x5ED3 廓 (<CJK Ideograph>) 1731 0x62E1 拡 (<CJK Ideograph>) 1732 0x64B9 撹 (<CJK Ideograph>) 1733 0x683C 格 (<CJK Ideograph>) 1734 0x6838 核 (<CJK Ideograph>) 1735 0x6BBB 殻 (<CJK Ideograph>) 1736 0x7372 獲 (<CJK Ideograph>) 1737 0x78BA 確 (<CJK Ideograph>) 1738 0x7A6B 穫 (<CJK Ideograph>) 1739 0x899A 覚 (<CJK Ideograph>) 1740 0x89D2 角 (<CJK Ideograph>) 1741 0x8D6B 赫 (<CJK Ideograph>) 1742 0x8F03 較 (<CJK Ideograph>) 1743 0x90ED 郭 (<CJK Ideograph>) 1744 0x95A3 閣 (<CJK Ideograph>) 1745 0x9694 隔 (<CJK Ideograph>) 1746 0x9769 革 (<CJK Ideograph>) 1747 0x5B66 学 (<CJK Ideograph>) 1748 0x5CB3 岳 (<CJK Ideograph>) 1749 0x697D 楽 (<CJK Ideograph>) 1750 0x984D 額 (<CJK Ideograph>) 1751 0x984E 顎 (<CJK Ideograph>) 1752 0x639B 掛 (<CJK Ideograph>) 1753 0x7B20 笠 (<CJK Ideograph>) 1754 0x6A2B 樫 (<CJK Ideograph>) 1755 0x6A7F 橿 (<CJK Ideograph>) 1756 0x68B6 梶 (<CJK Ideograph>) 1757 0x9C0D 鰍 (<CJK Ideograph>) 1758 0x6F5F 潟 (<CJK Ideograph>) 1759 0x5272 割 (<CJK Ideograph>) 1760 0x559D 喝 (<CJK Ideograph>) 1761 0x6070 恰 (<CJK Ideograph>) 1762 0x62EC 括 (<CJK Ideograph>) 1763 0x6D3B 活 (<CJK Ideograph>) 1764 0x6E07 渇 (<CJK Ideograph>) 1765 0x6ED1 滑 (<CJK Ideograph>) 1766 0x845B 葛 (<CJK Ideograph>) 1767 0x8910 褐 (<CJK Ideograph>) 1768 0x8F44 轄 (<CJK Ideograph>) 1769 0x4E14 且 (<CJK Ideograph>) 1770 0x9C39 鰹 (<CJK Ideograph>) 1771 0x53F6 叶 (<CJK Ideograph>) 1772 0x691B 椛 (<CJK Ideograph>) 1773 0x6A3A 樺 (<CJK Ideograph>) 1774 0x9784 鞄 (<CJK Ideograph>) 1775 0x682A 株 (<CJK Ideograph>) 1776 0x515C 兜 (<CJK Ideograph>) 1777 0x7AC3 竃 (<CJK Ideograph>) 1778 0x84B2 蒲 (<CJK Ideograph>) 1779 0x91DC 釜 (<CJK Ideograph>) 1780 0x938C 鎌 (<CJK Ideograph>) 1781 0x565B 噛 (<CJK Ideograph>) 1782 0x9D28 鴨 (<CJK Ideograph>) 1783 0x6822 栢 (<CJK Ideograph>) 1784 0x8305 茅 (<CJK Ideograph>) 1785 0x8431 萱 (<CJK Ideograph>) 1786 0x7CA5 粥 (<CJK Ideograph>) 1787 0x5208 刈 (<CJK Ideograph>) 1788 0x82C5 苅 (<CJK Ideograph>) 1789 0x74E6 瓦 (<CJK Ideograph>) 1790 0x4E7E 乾 (<CJK Ideograph>) 1791 0x4F83 侃 (<CJK Ideograph>) 1792 0x51A0 冠 (<CJK Ideograph>) 1793 0x5BD2 寒 (<CJK Ideograph>) 1794 0x520A 刊 (<CJK Ideograph>) 1795 0x52D8 勘 (<CJK Ideograph>) 1796 0x52E7 勧 (<CJK Ideograph>) 1797 0x5DFB 巻 (<CJK Ideograph>) 1798 0x559A 喚 (<CJK Ideograph>) 1799 0x582A 堪 (<CJK Ideograph>) 1800 0x59E6 姦 (<CJK Ideograph>) 1801 0x5B8C 完 (<CJK Ideograph>) 1802 0x5B98 官 (<CJK Ideograph>) 1803 0x5BDB 寛 (<CJK Ideograph>) 1804 0x5E72 干 (<CJK Ideograph>) 1805 0x5E79 幹 (<CJK Ideograph>) 1806 0x60A3 患 (<CJK Ideograph>) 1807 0x611F 感 (<CJK Ideograph>) 1808 0x6163 慣 (<CJK Ideograph>) 1809 0x61BE 憾 (<CJK Ideograph>) 1810 0x63DB 換 (<CJK Ideograph>) 1811 0x6562 敢 (<CJK Ideograph>) 1812 0x67D1 柑 (<CJK Ideograph>) 1813 0x6853 桓 (<CJK Ideograph>) 1814 0x68FA 棺 (<CJK Ideograph>) 1815 0x6B3E 款 (<CJK Ideograph>) 1816 0x6B53 歓 (<CJK Ideograph>) 1817 0x6C57 汗 (<CJK Ideograph>) 1818 0x6F22 漢 (<CJK Ideograph>) 1819 0x6F97 澗 (<CJK Ideograph>) 1820 0x6F45 潅 (<CJK Ideograph>) 1821 0x74B0 環 (<CJK Ideograph>) 1822 0x7518 甘 (<CJK Ideograph>) 1823 0x76E3 監 (<CJK Ideograph>) 1824 0x770B 看 (<CJK Ideograph>) 1825 0x7AFF 竿 (<CJK Ideograph>) 1826 0x7BA1 管 (<CJK Ideograph>) 1827 0x7C21 簡 (<CJK Ideograph>) 1828 0x7DE9 緩 (<CJK Ideograph>) 1829 0x7F36 缶 (<CJK Ideograph>) 1830 0x7FF0 翰 (<CJK Ideograph>) 1831 0x809D 肝 (<CJK Ideograph>) 1832 0x8266 艦 (<CJK Ideograph>) 1833 0x839E 莞 (<CJK Ideograph>) 1834 0x89B3 観 (<CJK Ideograph>) 1835 0x8ACC 諌 (<CJK Ideograph>) 1836 0x8CAB 貫 (<CJK Ideograph>) 1837 0x9084 還 (<CJK Ideograph>) 1838 0x9451 鑑 (<CJK Ideograph>) 1839 0x9593 間 (<CJK Ideograph>) 1840 0x9591 閑 (<CJK Ideograph>) 1841 0x95A2 関 (<CJK Ideograph>) 1842 0x9665 陥 (<CJK Ideograph>) 1843 0x97D3 韓 (<CJK Ideograph>) 1844 0x9928 館 (<CJK Ideograph>) 1845 0x8218 舘 (<CJK Ideograph>) 1846 0x4E38 丸 (<CJK Ideograph>) 1847 0x542B 含 (<CJK Ideograph>) 1848 0x5CB8 岸 (<CJK Ideograph>) 1849 0x5DCC 巌 (<CJK Ideograph>) 1850 0x73A9 玩 (<CJK Ideograph>) 1851 0x764C 癌 (<CJK Ideograph>) 1852 0x773C 眼 (<CJK Ideograph>) 1853 0x5CA9 岩 (<CJK Ideograph>) 1854 0x7FEB 翫 (<CJK Ideograph>) 1855 0x8D0B 贋 (<CJK Ideograph>) 1856 0x96C1 雁 (<CJK Ideograph>) 1857 0x9811 頑 (<CJK Ideograph>) 1858 0x9854 顔 (<CJK Ideograph>) 1859 0x9858 願 (<CJK Ideograph>) 1860 0x4F01 企 (<CJK Ideograph>) 1861 0x4F0E 伎 (<CJK Ideograph>) 1862 0x5371 危 (<CJK Ideograph>) 1863 0x559C 喜 (<CJK Ideograph>) 1864 0x5668 器 (<CJK Ideograph>) 1865 0x57FA 基 (<CJK Ideograph>) 1866 0x5947 奇 (<CJK Ideograph>) 1867 0x5B09 嬉 (<CJK Ideograph>) 1868 0x5BC4 寄 (<CJK Ideograph>) 1869 0x5C90 岐 (<CJK Ideograph>) 1870 0x5E0C 希 (<CJK Ideograph>) 1871 0x5E7E 幾 (<CJK Ideograph>) 1872 0x5FCC 忌 (<CJK Ideograph>) 1873 0x63EE 揮 (<CJK Ideograph>) 1874 0x673A 机 (<CJK Ideograph>) 1875 0x65D7 旗 (<CJK Ideograph>) 1876 0x65E2 既 (<CJK Ideograph>) 1877 0x671F 期 (<CJK Ideograph>) 1878 0x68CB 棋 (<CJK Ideograph>) 1879 0x68C4 棄 (<CJK Ideograph>) 1880 0x6A5F 機 (<CJK Ideograph>) 1881 0x5E30 帰 (<CJK Ideograph>) 1882 0x6BC5 毅 (<CJK Ideograph>) 1883 0x6C17 気 (<CJK Ideograph>) 1884 0x6C7D 汽 (<CJK Ideograph>) 1885 0x757F 畿 (<CJK Ideograph>) 1886 0x7948 祈 (<CJK Ideograph>) 1887 0x5B63 季 (<CJK Ideograph>) 1888 0x7A00 稀 (<CJK Ideograph>) 1889 0x7D00 紀 (<CJK Ideograph>) 1890 0x5FBD 徽 (<CJK Ideograph>) 1891 0x898F 規 (<CJK Ideograph>) 1892 0x8A18 記 (<CJK Ideograph>) 1893 0x8CB4 貴 (<CJK Ideograph>) 1894 0x8D77 起 (<CJK Ideograph>) 1895 0x8ECC 軌 (<CJK Ideograph>) 1896 0x8F1D 輝 (<CJK Ideograph>) 1897 0x98E2 飢 (<CJK Ideograph>) 1898 0x9A0E 騎 (<CJK Ideograph>) 1899 0x9B3C 鬼 (<CJK Ideograph>) 1900 0x4E80 亀 (<CJK Ideograph>) 1901 0x507D 偽 (<CJK Ideograph>) 1902 0x5100 儀 (<CJK Ideograph>) 1903 0x5993 妓 (<CJK Ideograph>) 1904 0x5B9C 宜 (<CJK Ideograph>) 1905 0x622F 戯 (<CJK Ideograph>) 1906 0x6280 技 (<CJK Ideograph>) 1907 0x64EC 擬 (<CJK Ideograph>) 1908 0x6B3A 欺 (<CJK Ideograph>) 1909 0x72A0 犠 (<CJK Ideograph>) 1910 0x7591 疑 (<CJK Ideograph>) 1911 0x7947 祇 (<CJK Ideograph>) 1912 0x7FA9 義 (<CJK Ideograph>) 1913 0x87FB 蟻 (<CJK Ideograph>) 1914 0x8ABC 誼 (<CJK Ideograph>) 1915 0x8B70 議 (<CJK Ideograph>) 1916 0x63AC 掬 (<CJK Ideograph>) 1917 0x83CA 菊 (<CJK Ideograph>) 1918 0x97A0 鞠 (<CJK Ideograph>) 1919 0x5409 吉 (<CJK Ideograph>) 1920 0x5403 吃 (<CJK Ideograph>) 1921 0x55AB 喫 (<CJK Ideograph>) 1922 0x6854 桔 (<CJK Ideograph>) 1923 0x6A58 橘 (<CJK Ideograph>) 1924 0x8A70 詰 (<CJK Ideograph>) 1925 0x7827 砧 (<CJK Ideograph>) 1926 0x6775 杵 (<CJK Ideograph>) 1927 0x9ECD 黍 (<CJK Ideograph>) 1928 0x5374 却 (<CJK Ideograph>) 1929 0x5BA2 客 (<CJK Ideograph>) 1930 0x811A 脚 (<CJK Ideograph>) 1931 0x8650 虐 (<CJK Ideograph>) 1932 0x9006 逆 (<CJK Ideograph>) 1933 0x4E18 丘 (<CJK Ideograph>) 1934 0x4E45 久 (<CJK Ideograph>) 1935 0x4EC7 仇 (<CJK Ideograph>) 1936 0x4F11 休 (<CJK Ideograph>) 1937 0x53CA 及 (<CJK Ideograph>) 1938 0x5438 吸 (<CJK Ideograph>) 1939 0x5BAE 宮 (<CJK Ideograph>) 1940 0x5F13 弓 (<CJK Ideograph>) 1941 0x6025 急 (<CJK Ideograph>) 1942 0x6551 救 (<CJK Ideograph>) 1943 0x673D 朽 (<CJK Ideograph>) 1944 0x6C42 求 (<CJK Ideograph>) 1945 0x6C72 汲 (<CJK Ideograph>) 1946 0x6CE3 泣 (<CJK Ideograph>) 1947 0x7078 灸 (<CJK Ideograph>) 1948 0x7403 球 (<CJK Ideograph>) 1949 0x7A76 究 (<CJK Ideograph>) 1950 0x7AAE 窮 (<CJK Ideograph>) 1951 0x7B08 笈 (<CJK Ideograph>) 1952 0x7D1A 級 (<CJK Ideograph>) 1953 0x7CFE 糾 (<CJK Ideograph>) 1954 0x7D66 給 (<CJK Ideograph>) 1955 0x65E7 旧 (<CJK Ideograph>) 1956 0x725B 牛 (<CJK Ideograph>) 1957 0x53BB 去 (<CJK Ideograph>) 1958 0x5C45 居 (<CJK Ideograph>) 1959 0x5DE8 巨 (<CJK Ideograph>) 1960 0x62D2 拒 (<CJK Ideograph>) 1961 0x62E0 拠 (<CJK Ideograph>) 1962 0x6319 挙 (<CJK Ideograph>) 1963 0x6E20 渠 (<CJK Ideograph>) 1964 0x865A 虚 (<CJK Ideograph>) 1965 0x8A31 許 (<CJK Ideograph>) 1966 0x8DDD 距 (<CJK Ideograph>) 1967 0x92F8 鋸 (<CJK Ideograph>) 1968 0x6F01 漁 (<CJK Ideograph>) 1969 0x79A6 禦 (<CJK Ideograph>) 1970 0x9B5A 魚 (<CJK Ideograph>) 1971 0x4EA8 亨 (<CJK Ideograph>) 1972 0x4EAB 享 (<CJK Ideograph>) 1973 0x4EAC 京 (<CJK Ideograph>) 1974 0x4F9B 供 (<CJK Ideograph>) 1975 0x4FA0 侠 (<CJK Ideograph>) 1976 0x50D1 僑 (<CJK Ideograph>) 1977 0x5147 兇 (<CJK Ideograph>) 1978 0x7AF6 競 (<CJK Ideograph>) 1979 0x5171 共 (<CJK Ideograph>) 1980 0x51F6 凶 (<CJK Ideograph>) 1981 0x5354 協 (<CJK Ideograph>) 1982 0x5321 匡 (<CJK Ideograph>) 1983 0x537F 卿 (<CJK Ideograph>) 1984 0x53EB 叫 (<CJK Ideograph>) 1985 0x55AC 喬 (<CJK Ideograph>) 1986 0x5883 境 (<CJK Ideograph>) 1987 0x5CE1 峡 (<CJK Ideograph>) 1988 0x5F37 強 (<CJK Ideograph>) 1989 0x5F4A 彊 (<CJK Ideograph>) 1990 0x602F 怯 (<CJK Ideograph>) 1991 0x6050 恐 (<CJK Ideograph>) 1992 0x606D 恭 (<CJK Ideograph>) 1993 0x631F 挟 (<CJK Ideograph>) 1994 0x6559 教 (<CJK Ideograph>) 1995 0x6A4B 橋 (<CJK Ideograph>) 1996 0x6CC1 況 (<CJK Ideograph>) 1997 0x72C2 狂 (<CJK Ideograph>) 1998 0x72ED 狭 (<CJK Ideograph>) 1999 0x77EF 矯 (<CJK Ideograph>) 2000 0x80F8 胸 (<CJK Ideograph>) 2001 0x8105 脅 (<CJK Ideograph>) 2002 0x8208 興 (<CJK Ideograph>) 2003 0x854E 蕎 (<CJK Ideograph>) 2004 0x90F7 郷 (<CJK Ideograph>) 2005 0x93E1 鏡 (<CJK Ideograph>) 2006 0x97FF 響 (<CJK Ideograph>) 2007 0x9957 饗 (<CJK Ideograph>) 2008 0x9A5A 驚 (<CJK Ideograph>) 2009 0x4EF0 仰 (<CJK Ideograph>) 2010 0x51DD 凝 (<CJK Ideograph>) 2011 0x5C2D 尭 (<CJK Ideograph>) 2012 0x6681 暁 (<CJK Ideograph>) 2013 0x696D 業 (<CJK Ideograph>) 2014 0x5C40 局 (<CJK Ideograph>) 2015 0x66F2 曲 (<CJK Ideograph>) 2016 0x6975 極 (<CJK Ideograph>) 2017 0x7389 玉 (<CJK Ideograph>) 2018 0x6850 桐 (<CJK Ideograph>) 2019 0x7C81 粁 (<CJK Ideograph>) 2020 0x50C5 僅 (<CJK Ideograph>) 2021 0x52E4 勤 (<CJK Ideograph>) 2022 0x5747 均 (<CJK Ideograph>) 2023 0x5DFE 巾 (<CJK Ideograph>) 2024 0x9326 錦 (<CJK Ideograph>) 2025 0x65A4 斤 (<CJK Ideograph>) 2026 0x6B23 欣 (<CJK Ideograph>) 2027 0x6B3D 欽 (<CJK Ideograph>) 2028 0x7434 琴 (<CJK Ideograph>) 2029 0x7981 禁 (<CJK Ideograph>) 2030 0x79BD 禽 (<CJK Ideograph>) 2031 0x7B4B 筋 (<CJK Ideograph>) 2032 0x7DCA 緊 (<CJK Ideograph>) 2033 0x82B9 芹 (<CJK Ideograph>) 2034 0x83CC 菌 (<CJK Ideograph>) 2035 0x887F 衿 (<CJK Ideograph>) 2036 0x895F 襟 (<CJK Ideograph>) 2037 0x8B39 謹 (<CJK Ideograph>) 2038 0x8FD1 近 (<CJK Ideograph>) 2039 0x91D1 金 (<CJK Ideograph>) 2040 0x541F 吟 (<CJK Ideograph>) 2041 0x9280 銀 (<CJK Ideograph>) 2042 0x4E5D 九 (<CJK Ideograph>) 2043 0x5036 倶 (<CJK Ideograph>) 2044 0x53E5 句 (<CJK Ideograph>) 2045 0x533A 区 (<CJK Ideograph>) 2046 0x72D7 狗 (<CJK Ideograph>) 2047 0x7396 玖 (<CJK Ideograph>) 2048 0x77E9 矩 (<CJK Ideograph>) 2049 0x82E6 苦 (<CJK Ideograph>) 2050 0x8EAF 躯 (<CJK Ideograph>) 2051 0x99C6 駆 (<CJK Ideograph>) 2052 0x99C8 駈 (<CJK Ideograph>) 2053 0x99D2 駒 (<CJK Ideograph>) 2054 0x5177 具 (<CJK Ideograph>) 2055 0x611A 愚 (<CJK Ideograph>) 2056 0x865E 虞 (<CJK Ideograph>) 2057 0x55B0 喰 (<CJK Ideograph>) 2058 0x7A7A 空 (<CJK Ideograph>) 2059 0x5076 偶 (<CJK Ideograph>) 2060 0x5BD3 寓 (<CJK Ideograph>) 2061 0x9047 遇 (<CJK Ideograph>) 2062 0x9685 隅 (<CJK Ideograph>) 2063 0x4E32 串 (<CJK Ideograph>) 2064 0x6ADB 櫛 (<CJK Ideograph>) 2065 0x91E7 釧 (<CJK Ideograph>) 2066 0x5C51 屑 (<CJK Ideograph>) 2067 0x5C48 屈 (<CJK Ideograph>) 2068 0x6398 掘 (<CJK Ideograph>) 2069 0x7A9F 窟 (<CJK Ideograph>) 2070 0x6C93 沓 (<CJK Ideograph>) 2071 0x9774 靴 (<CJK Ideograph>) 2072 0x8F61 轡 (<CJK Ideograph>) 2073 0x7AAA 窪 (<CJK Ideograph>) 2074 0x718A 熊 (<CJK Ideograph>) 2075 0x9688 隈 (<CJK Ideograph>) 2076 0x7C82 粂 (<CJK Ideograph>) 2077 0x6817 栗 (<CJK Ideograph>) 2078 0x7E70 繰 (<CJK Ideograph>) 2079 0x6851 桑 (<CJK Ideograph>) 2080 0x936C 鍬 (<CJK Ideograph>) 2081 0x52F2 勲 (<CJK Ideograph>) 2082 0x541B 君 (<CJK Ideograph>) 2083 0x85AB 薫 (<CJK Ideograph>) 2084 0x8A13 訓 (<CJK Ideograph>) 2085 0x7FA4 群 (<CJK Ideograph>) 2086 0x8ECD 軍 (<CJK Ideograph>) 2087 0x90E1 郡 (<CJK Ideograph>) 2088 0x5366 卦 (<CJK Ideograph>) 2089 0x8888 袈 (<CJK Ideograph>) 2090 0x7941 祁 (<CJK Ideograph>) 2091 0x4FC2 係 (<CJK Ideograph>) 2092 0x50BE 傾 (<CJK Ideograph>) 2093 0x5211 刑 (<CJK Ideograph>) 2094 0x5144 兄 (<CJK Ideograph>) 2095 0x5553 啓 (<CJK Ideograph>) 2096 0x572D 圭 (<CJK Ideograph>) 2097 0x73EA 珪 (<CJK Ideograph>) 2098 0x578B 型 (<CJK Ideograph>) 2099 0x5951 契 (<CJK Ideograph>) 2100 0x5F62 形 (<CJK Ideograph>) 2101 0x5F84 径 (<CJK Ideograph>) 2102 0x6075 恵 (<CJK Ideograph>) 2103 0x6176 慶 (<CJK Ideograph>) 2104 0x6167 慧 (<CJK Ideograph>) 2105 0x61A9 憩 (<CJK Ideograph>) 2106 0x63B2 掲 (<CJK Ideograph>) 2107 0x643A 携 (<CJK Ideograph>) 2108 0x656C 敬 (<CJK Ideograph>) 2109 0x666F 景 (<CJK Ideograph>) 2110 0x6842 桂 (<CJK Ideograph>) 2111 0x6E13 渓 (<CJK Ideograph>) 2112 0x7566 畦 (<CJK Ideograph>) 2113 0x7A3D 稽 (<CJK Ideograph>) 2114 0x7CFB 系 (<CJK Ideograph>) 2115 0x7D4C 経 (<CJK Ideograph>) 2116 0x7D99 継 (<CJK Ideograph>) 2117 0x7E4B 繋 (<CJK Ideograph>) 2118 0x7F6B 罫 (<CJK Ideograph>) 2119 0x830E 茎 (<CJK Ideograph>) 2120 0x834A 荊 (<CJK Ideograph>) 2121 0x86CD 蛍 (<CJK Ideograph>) 2122 0x8A08 計 (<CJK Ideograph>) 2123 0x8A63 詣 (<CJK Ideograph>) 2124 0x8B66 警 (<CJK Ideograph>) 2125 0x8EFD 軽 (<CJK Ideograph>) 2126 0x981A 頚 (<CJK Ideograph>) 2127 0x9D8F 鶏 (<CJK Ideograph>) 2128 0x82B8 芸 (<CJK Ideograph>) 2129 0x8FCE 迎 (<CJK Ideograph>) 2130 0x9BE8 鯨 (<CJK Ideograph>) 2131 0x5287 劇 (<CJK Ideograph>) 2132 0x621F 戟 (<CJK Ideograph>) 2133 0x6483 撃 (<CJK Ideograph>) 2134 0x6FC0 激 (<CJK Ideograph>) 2135 0x9699 隙 (<CJK Ideograph>) 2136 0x6841 桁 (<CJK Ideograph>) 2137 0x5091 傑 (<CJK Ideograph>) 2138 0x6B20 欠 (<CJK Ideograph>) 2139 0x6C7A 決 (<CJK Ideograph>) 2140 0x6F54 潔 (<CJK Ideograph>) 2141 0x7A74 穴 (<CJK Ideograph>) 2142 0x7D50 結 (<CJK Ideograph>) 2143 0x8840 血 (<CJK Ideograph>) 2144 0x8A23 訣 (<CJK Ideograph>) 2145 0x6708 月 (<CJK Ideograph>) 2146 0x4EF6 件 (<CJK Ideograph>) 2147 0x5039 倹 (<CJK Ideograph>) 2148 0x5026 倦 (<CJK Ideograph>) 2149 0x5065 健 (<CJK Ideograph>) 2150 0x517C 兼 (<CJK Ideograph>) 2151 0x5238 券 (<CJK Ideograph>) 2152 0x5263 剣 (<CJK Ideograph>) 2153 0x55A7 喧 (<CJK Ideograph>) 2154 0x570F 圏 (<CJK Ideograph>) 2155 0x5805 堅 (<CJK Ideograph>) 2156 0x5ACC 嫌 (<CJK Ideograph>) 2157 0x5EFA 建 (<CJK Ideograph>) 2158 0x61B2 憲 (<CJK Ideograph>) 2159 0x61F8 懸 (<CJK Ideograph>) 2160 0x62F3 拳 (<CJK Ideograph>) 2161 0x6372 捲 (<CJK Ideograph>) 2162 0x691C 検 (<CJK Ideograph>) 2163 0x6A29 権 (<CJK Ideograph>) 2164 0x727D 牽 (<CJK Ideograph>) 2165 0x72AC 犬 (<CJK Ideograph>) 2166 0x732E 献 (<CJK Ideograph>) 2167 0x7814 研 (<CJK Ideograph>) 2168 0x786F 硯 (<CJK Ideograph>) 2169 0x7D79 絹 (<CJK Ideograph>) 2170 0x770C 県 (<CJK Ideograph>) 2171 0x80A9 肩 (<CJK Ideograph>) 2172 0x898B 見 (<CJK Ideograph>) 2173 0x8B19 謙 (<CJK Ideograph>) 2174 0x8CE2 賢 (<CJK Ideograph>) 2175 0x8ED2 軒 (<CJK Ideograph>) 2176 0x9063 遣 (<CJK Ideograph>) 2177 0x9375 鍵 (<CJK Ideograph>) 2178 0x967A 険 (<CJK Ideograph>) 2179 0x9855 顕 (<CJK Ideograph>) 2180 0x9A13 験 (<CJK Ideograph>) 2181 0x9E78 鹸 (<CJK Ideograph>) 2182 0x5143 元 (<CJK Ideograph>) 2183 0x539F 原 (<CJK Ideograph>) 2184 0x53B3 厳 (<CJK Ideograph>) 2185 0x5E7B 幻 (<CJK Ideograph>) 2186 0x5F26 弦 (<CJK Ideograph>) 2187 0x6E1B 減 (<CJK Ideograph>) 2188 0x6E90 源 (<CJK Ideograph>) 2189 0x7384 玄 (<CJK Ideograph>) 2190 0x73FE 現 (<CJK Ideograph>) 2191 0x7D43 絃 (<CJK Ideograph>) 2192 0x8237 舷 (<CJK Ideograph>) 2193 0x8A00 言 (<CJK Ideograph>) 2194 0x8AFA 諺 (<CJK Ideograph>) 2195 0x9650 限 (<CJK Ideograph>) 2196 0x4E4E 乎 (<CJK Ideograph>) 2197 0x500B 個 (<CJK Ideograph>) 2198 0x53E4 古 (<CJK Ideograph>) 2199 0x547C 呼 (<CJK Ideograph>) 2200 0x56FA 固 (<CJK Ideograph>) 2201 0x59D1 姑 (<CJK Ideograph>) 2202 0x5B64 孤 (<CJK Ideograph>) 2203 0x5DF1 己 (<CJK Ideograph>) 2204 0x5EAB 庫 (<CJK Ideograph>) 2205 0x5F27 弧 (<CJK Ideograph>) 2206 0x6238 戸 (<CJK Ideograph>) 2207 0x6545 故 (<CJK Ideograph>) 2208 0x67AF 枯 (<CJK Ideograph>) 2209 0x6E56 湖 (<CJK Ideograph>) 2210 0x72D0 狐 (<CJK Ideograph>) 2211 0x7CCA 糊 (<CJK Ideograph>) 2212 0x88B4 袴 (<CJK Ideograph>) 2213 0x80A1 股 (<CJK Ideograph>) 2214 0x80E1 胡 (<CJK Ideograph>) 2215 0x83F0 菰 (<CJK Ideograph>) 2216 0x864E 虎 (<CJK Ideograph>) 2217 0x8A87 誇 (<CJK Ideograph>) 2218 0x8DE8 跨 (<CJK Ideograph>) 2219 0x9237 鈷 (<CJK Ideograph>) 2220 0x96C7 雇 (<CJK Ideograph>) 2221 0x9867 顧 (<CJK Ideograph>) 2222 0x9F13 鼓 (<CJK Ideograph>) 2223 0x4E94 五 (<CJK Ideograph>) 2224 0x4E92 互 (<CJK Ideograph>) 2225 0x4F0D 伍 (<CJK Ideograph>) 2226 0x5348 午 (<CJK Ideograph>) 2227 0x5449 呉 (<CJK Ideograph>) 2228 0x543E 吾 (<CJK Ideograph>) 2229 0x5A2F 娯 (<CJK Ideograph>) 2230 0x5F8C 後 (<CJK Ideograph>) 2231 0x5FA1 御 (<CJK Ideograph>) 2232 0x609F 悟 (<CJK Ideograph>) 2233 0x68A7 梧 (<CJK Ideograph>) 2234 0x6A8E 檎 (<CJK Ideograph>) 2235 0x745A 瑚 (<CJK Ideograph>) 2236 0x7881 碁 (<CJK Ideograph>) 2237 0x8A9E 語 (<CJK Ideograph>) 2238 0x8AA4 誤 (<CJK Ideograph>) 2239 0x8B77 護 (<CJK Ideograph>) 2240 0x9190 醐 (<CJK Ideograph>) 2241 0x4E5E 乞 (<CJK Ideograph>) 2242 0x9BC9 鯉 (<CJK Ideograph>) 2243 0x4EA4 交 (<CJK Ideograph>) 2244 0x4F7C 佼 (<CJK Ideograph>) 2245 0x4FAF 侯 (<CJK Ideograph>) 2246 0x5019 候 (<CJK Ideograph>) 2247 0x5016 倖 (<CJK Ideograph>) 2248 0x5149 光 (<CJK Ideograph>) 2249 0x516C 公 (<CJK Ideograph>) 2250 0x529F 功 (<CJK Ideograph>) 2251 0x52B9 効 (<CJK Ideograph>) 2252 0x52FE 勾 (<CJK Ideograph>) 2253 0x539A 厚 (<CJK Ideograph>) 2254 0x53E3 口 (<CJK Ideograph>) 2255 0x5411 向 (<CJK Ideograph>) 2256 0x540E 后 (<CJK Ideograph>) 2257 0x5589 喉 (<CJK Ideograph>) 2258 0x5751 坑 (<CJK Ideograph>) 2259 0x57A2 垢 (<CJK Ideograph>) 2260 0x597D 好 (<CJK Ideograph>) 2261 0x5B54 孔 (<CJK Ideograph>) 2262 0x5B5D 孝 (<CJK Ideograph>) 2263 0x5B8F 宏 (<CJK Ideograph>) 2264 0x5DE5 工 (<CJK Ideograph>) 2265 0x5DE7 巧 (<CJK Ideograph>) 2266 0x5DF7 巷 (<CJK Ideograph>) 2267 0x5E78 幸 (<CJK Ideograph>) 2268 0x5E83 広 (<CJK Ideograph>) 2269 0x5E9A 庚 (<CJK Ideograph>) 2270 0x5EB7 康 (<CJK Ideograph>) 2271 0x5F18 弘 (<CJK Ideograph>) 2272 0x6052 恒 (<CJK Ideograph>) 2273 0x614C 慌 (<CJK Ideograph>) 2274 0x6297 抗 (<CJK Ideograph>) 2275 0x62D8 拘 (<CJK Ideograph>) 2276 0x63A7 控 (<CJK Ideograph>) 2277 0x653B 攻 (<CJK Ideograph>) 2278 0x6602 昂 (<CJK Ideograph>) 2279 0x6643 晃 (<CJK Ideograph>) 2280 0x66F4 更 (<CJK Ideograph>) 2281 0x676D 杭 (<CJK Ideograph>) 2282 0x6821 校 (<CJK Ideograph>) 2283 0x6897 梗 (<CJK Ideograph>) 2284 0x69CB 構 (<CJK Ideograph>) 2285 0x6C5F 江 (<CJK Ideograph>) 2286 0x6D2A 洪 (<CJK Ideograph>) 2287 0x6D69 浩 (<CJK Ideograph>) 2288 0x6E2F 港 (<CJK Ideograph>) 2289 0x6E9D 溝 (<CJK Ideograph>) 2290 0x7532 甲 (<CJK Ideograph>) 2291 0x7687 皇 (<CJK Ideograph>) 2292 0x786C 硬 (<CJK Ideograph>) 2293 0x7A3F 稿 (<CJK Ideograph>) 2294 0x7CE0 糠 (<CJK Ideograph>) 2295 0x7D05 紅 (<CJK Ideograph>) 2296 0x7D18 紘 (<CJK Ideograph>) 2297 0x7D5E 絞 (<CJK Ideograph>) 2298 0x7DB1 綱 (<CJK Ideograph>) 2299 0x8015 耕 (<CJK Ideograph>) 2300 0x8003 考 (<CJK Ideograph>) 2301 0x80AF 肯 (<CJK Ideograph>) 2302 0x80B1 肱 (<CJK Ideograph>) 2303 0x8154 腔 (<CJK Ideograph>) 2304 0x818F 膏 (<CJK Ideograph>) 2305 0x822A 航 (<CJK Ideograph>) 2306 0x8352 荒 (<CJK Ideograph>) 2307 0x884C 行 (<CJK Ideograph>) 2308 0x8861 衡 (<CJK Ideograph>) 2309 0x8B1B 講 (<CJK Ideograph>) 2310 0x8CA2 貢 (<CJK Ideograph>) 2311 0x8CFC 購 (<CJK Ideograph>) 2312 0x90CA 郊 (<CJK Ideograph>) 2313 0x9175 酵 (<CJK Ideograph>) 2314 0x9271 鉱 (<CJK Ideograph>) 2315 0x783F 砿 (<CJK Ideograph>) 2316 0x92FC 鋼 (<CJK Ideograph>) 2317 0x95A4 閤 (<CJK Ideograph>) 2318 0x964D 降 (<CJK Ideograph>) 2319 0x9805 項 (<CJK Ideograph>) 2320 0x9999 香 (<CJK Ideograph>) 2321 0x9AD8 高 (<CJK Ideograph>) 2322 0x9D3B 鴻 (<CJK Ideograph>) 2323 0x525B 剛 (<CJK Ideograph>) 2324 0x52AB 劫 (<CJK Ideograph>) 2325 0x53F7 号 (<CJK Ideograph>) 2326 0x5408 合 (<CJK Ideograph>) 2327 0x58D5 壕 (<CJK Ideograph>) 2328 0x62F7 拷 (<CJK Ideograph>) 2329 0x6FE0 濠 (<CJK Ideograph>) 2330 0x8C6A 豪 (<CJK Ideograph>) 2331 0x8F5F 轟 (<CJK Ideograph>) 2332 0x9EB9 麹 (<CJK Ideograph>) 2333 0x514B 克 (<CJK Ideograph>) 2334 0x523B 刻 (<CJK Ideograph>) 2335 0x544A 告 (<CJK Ideograph>) 2336 0x56FD 国 (<CJK Ideograph>) 2337 0x7A40 穀 (<CJK Ideograph>) 2338 0x9177 酷 (<CJK Ideograph>) 2339 0x9D60 鵠 (<CJK Ideograph>) 2340 0x9ED2 黒 (<CJK Ideograph>) 2341 0x7344 獄 (<CJK Ideograph>) 2342 0x6F09 漉 (<CJK Ideograph>) 2343 0x8170 腰 (<CJK Ideograph>) 2344 0x7511 甑 (<CJK Ideograph>) 2345 0x5FFD 忽 (<CJK Ideograph>) 2346 0x60DA 惚 (<CJK Ideograph>) 2347 0x9AA8 骨 (<CJK Ideograph>) 2348 0x72DB 狛 (<CJK Ideograph>) 2349 0x8FBC 込 (<CJK Ideograph>) 2350 0x6B64 此 (<CJK Ideograph>) 2351 0x9803 頃 (<CJK Ideograph>) 2352 0x4ECA 今 (<CJK Ideograph>) 2353 0x56F0 困 (<CJK Ideograph>) 2354 0x5764 坤 (<CJK Ideograph>) 2355 0x58BE 墾 (<CJK Ideograph>) 2356 0x5A5A 婚 (<CJK Ideograph>) 2357 0x6068 恨 (<CJK Ideograph>) 2358 0x61C7 懇 (<CJK Ideograph>) 2359 0x660F 昏 (<CJK Ideograph>) 2360 0x6606 昆 (<CJK Ideograph>) 2361 0x6839 根 (<CJK Ideograph>) 2362 0x68B1 梱 (<CJK Ideograph>) 2363 0x6DF7 混 (<CJK Ideograph>) 2364 0x75D5 痕 (<CJK Ideograph>) 2365 0x7D3A 紺 (<CJK Ideograph>) 2366 0x826E 艮 (<CJK Ideograph>) 2367 0x9B42 魂 (<CJK Ideograph>) 2368 0x4E9B 些 (<CJK Ideograph>) 2369 0x4F50 佐 (<CJK Ideograph>) 2370 0x53C9 叉 (<CJK Ideograph>) 2371 0x5506 唆 (<CJK Ideograph>) 2372 0x5D6F 嵯 (<CJK Ideograph>) 2373 0x5DE6 左 (<CJK Ideograph>) 2374 0x5DEE 差 (<CJK Ideograph>) 2375 0x67FB 査 (<CJK Ideograph>) 2376 0x6C99 沙 (<CJK Ideograph>) 2377 0x7473 瑳 (<CJK Ideograph>) 2378 0x7802 砂 (<CJK Ideograph>) 2379 0x8A50 詐 (<CJK Ideograph>) 2380 0x9396 鎖 (<CJK Ideograph>) 2381 0x88DF 裟 (<CJK Ideograph>) 2382 0x5750 坐 (<CJK Ideograph>) 2383 0x5EA7 座 (<CJK Ideograph>) 2384 0x632B 挫 (<CJK Ideograph>) 2385 0x50B5 債 (<CJK Ideograph>) 2386 0x50AC 催 (<CJK Ideograph>) 2387 0x518D 再 (<CJK Ideograph>) 2388 0x6700 最 (<CJK Ideograph>) 2389 0x54C9 哉 (<CJK Ideograph>) 2390 0x585E 塞 (<CJK Ideograph>) 2391 0x59BB 妻 (<CJK Ideograph>) 2392 0x5BB0 宰 (<CJK Ideograph>) 2393 0x5F69 彩 (<CJK Ideograph>) 2394 0x624D 才 (<CJK Ideograph>) 2395 0x63A1 採 (<CJK Ideograph>) 2396 0x683D 栽 (<CJK Ideograph>) 2397 0x6B73 歳 (<CJK Ideograph>) 2398 0x6E08 済 (<CJK Ideograph>) 2399 0x707D 災 (<CJK Ideograph>) 2400 0x91C7 采 (<CJK Ideograph>) 2401 0x7280 犀 (<CJK Ideograph>) 2402 0x7815 砕 (<CJK Ideograph>) 2403 0x7826 砦 (<CJK Ideograph>) 2404 0x796D 祭 (<CJK Ideograph>) 2405 0x658E 斎 (<CJK Ideograph>) 2406 0x7D30 細 (<CJK Ideograph>) 2407 0x83DC 菜 (<CJK Ideograph>) 2408 0x88C1 裁 (<CJK Ideograph>) 2409 0x8F09 載 (<CJK Ideograph>) 2410 0x969B 際 (<CJK Ideograph>) 2411 0x5264 剤 (<CJK Ideograph>) 2412 0x5728 在 (<CJK Ideograph>) 2413 0x6750 材 (<CJK Ideograph>) 2414 0x7F6A 罪 (<CJK Ideograph>) 2415 0x8CA1 財 (<CJK Ideograph>) 2416 0x51B4 冴 (<CJK Ideograph>) 2417 0x5742 坂 (<CJK Ideograph>) 2418 0x962A 阪 (<CJK Ideograph>) 2419 0x583A 堺 (<CJK Ideograph>) 2420 0x698A 榊 (<CJK Ideograph>) 2421 0x80B4 肴 (<CJK Ideograph>) 2422 0x54B2 咲 (<CJK Ideograph>) 2423 0x5D0E 崎 (<CJK Ideograph>) 2424 0x57FC 埼 (<CJK Ideograph>) 2425 0x7895 碕 (<CJK Ideograph>) 2426 0x9DFA 鷺 (<CJK Ideograph>) 2427 0x4F5C 作 (<CJK Ideograph>) 2428 0x524A 削 (<CJK Ideograph>) 2429 0x548B 咋 (<CJK Ideograph>) 2430 0x643E 搾 (<CJK Ideograph>) 2431 0x6628 昨 (<CJK Ideograph>) 2432 0x6714 朔 (<CJK Ideograph>) 2433 0x67F5 柵 (<CJK Ideograph>) 2434 0x7A84 窄 (<CJK Ideograph>) 2435 0x7B56 策 (<CJK Ideograph>) 2436 0x7D22 索 (<CJK Ideograph>) 2437 0x932F 錯 (<CJK Ideograph>) 2438 0x685C 桜 (<CJK Ideograph>) 2439 0x9BAD 鮭 (<CJK Ideograph>) 2440 0x7B39 笹 (<CJK Ideograph>) 2441 0x5319 匙 (<CJK Ideograph>) 2442 0x518A 冊 (<CJK Ideograph>) 2443 0x5237 刷 (<CJK Ideograph>) 2444 0x5BDF 察 (<CJK Ideograph>) 2445 0x62F6 拶 (<CJK Ideograph>) 2446 0x64AE 撮 (<CJK Ideograph>) 2447 0x64E6 擦 (<CJK Ideograph>) 2448 0x672D 札 (<CJK Ideograph>) 2449 0x6BBA 殺 (<CJK Ideograph>) 2450 0x85A9 薩 (<CJK Ideograph>) 2451 0x96D1 雑 (<CJK Ideograph>) 2452 0x7690 皐 (<CJK Ideograph>) 2453 0x9BD6 鯖 (<CJK Ideograph>) 2454 0x634C 捌 (<CJK Ideograph>) 2455 0x9306 錆 (<CJK Ideograph>) 2456 0x9BAB 鮫 (<CJK Ideograph>) 2457 0x76BF 皿 (<CJK Ideograph>) 2458 0x6652 晒 (<CJK Ideograph>) 2459 0x4E09 三 (<CJK Ideograph>) 2460 0x5098 傘 (<CJK Ideograph>) 2461 0x53C2 参 (<CJK Ideograph>) 2462 0x5C71 山 (<CJK Ideograph>) 2463 0x60E8 惨 (<CJK Ideograph>) 2464 0x6492 撒 (<CJK Ideograph>) 2465 0x6563 散 (<CJK Ideograph>) 2466 0x685F 桟 (<CJK Ideograph>) 2467 0x71E6 燦 (<CJK Ideograph>) 2468 0x73CA 珊 (<CJK Ideograph>) 2469 0x7523 産 (<CJK Ideograph>) 2470 0x7B97 算 (<CJK Ideograph>) 2471 0x7E82 纂 (<CJK Ideograph>) 2472 0x8695 蚕 (<CJK Ideograph>) 2473 0x8B83 讃 (<CJK Ideograph>) 2474 0x8CDB 賛 (<CJK Ideograph>) 2475 0x9178 酸 (<CJK Ideograph>) 2476 0x9910 餐 (<CJK Ideograph>) 2477 0x65AC 斬 (<CJK Ideograph>) 2478 0x66AB 暫 (<CJK Ideograph>) 2479 0x6B8B 残 (<CJK Ideograph>) 2480 0x4ED5 仕 (<CJK Ideograph>) 2481 0x4ED4 仔 (<CJK Ideograph>) 2482 0x4F3A 伺 (<CJK Ideograph>) 2483 0x4F7F 使 (<CJK Ideograph>) 2484 0x523A 刺 (<CJK Ideograph>) 2485 0x53F8 司 (<CJK Ideograph>) 2486 0x53F2 史 (<CJK Ideograph>) 2487 0x55E3 嗣 (<CJK Ideograph>) 2488 0x56DB 四 (<CJK Ideograph>) 2489 0x58EB 士 (<CJK Ideograph>) 2490 0x59CB 始 (<CJK Ideograph>) 2491 0x59C9 姉 (<CJK Ideograph>) 2492 0x59FF 姿 (<CJK Ideograph>) 2493 0x5B50 子 (<CJK Ideograph>) 2494 0x5C4D 屍 (<CJK Ideograph>) 2495 0x5E02 市 (<CJK Ideograph>) 2496 0x5E2B 師 (<CJK Ideograph>) 2497 0x5FD7 志 (<CJK Ideograph>) 2498 0x601D 思 (<CJK Ideograph>) 2499 0x6307 指 (<CJK Ideograph>) 2500 0x652F 支 (<CJK Ideograph>) 2501 0x5B5C 孜 (<CJK Ideograph>) 2502 0x65AF 斯 (<CJK Ideograph>) 2503 0x65BD 施 (<CJK Ideograph>) 2504 0x65E8 旨 (<CJK Ideograph>) 2505 0x679D 枝 (<CJK Ideograph>) 2506 0x6B62 止 (<CJK Ideograph>) 2507 0x6B7B 死 (<CJK Ideograph>) 2508 0x6C0F 氏 (<CJK Ideograph>) 2509 0x7345 獅 (<CJK Ideograph>) 2510 0x7949 祉 (<CJK Ideograph>) 2511 0x79C1 私 (<CJK Ideograph>) 2512 0x7CF8 糸 (<CJK Ideograph>) 2513 0x7D19 紙 (<CJK Ideograph>) 2514 0x7D2B 紫 (<CJK Ideograph>) 2515 0x80A2 肢 (<CJK Ideograph>) 2516 0x8102 脂 (<CJK Ideograph>) 2517 0x81F3 至 (<CJK Ideograph>) 2518 0x8996 視 (<CJK Ideograph>) 2519 0x8A5E 詞 (<CJK Ideograph>) 2520 0x8A69 詩 (<CJK Ideograph>) 2521 0x8A66 試 (<CJK Ideograph>) 2522 0x8A8C 誌 (<CJK Ideograph>) 2523 0x8AEE 諮 (<CJK Ideograph>) 2524 0x8CC7 資 (<CJK Ideograph>) 2525 0x8CDC 賜 (<CJK Ideograph>) 2526 0x96CC 雌 (<CJK Ideograph>) 2527 0x98FC 飼 (<CJK Ideograph>) 2528 0x6B6F 歯 (<CJK Ideograph>) 2529 0x4E8B 事 (<CJK Ideograph>) 2530 0x4F3C 似 (<CJK Ideograph>) 2531 0x4F8D 侍 (<CJK Ideograph>) 2532 0x5150 児 (<CJK Ideograph>) 2533 0x5B57 字 (<CJK Ideograph>) 2534 0x5BFA 寺 (<CJK Ideograph>) 2535 0x6148 慈 (<CJK Ideograph>) 2536 0x6301 持 (<CJK Ideograph>) 2537 0x6642 時 (<CJK Ideograph>) 2538 0x6B21 次 (<CJK Ideograph>) 2539 0x6ECB 滋 (<CJK Ideograph>) 2540 0x6CBB 治 (<CJK Ideograph>) 2541 0x723E 爾 (<CJK Ideograph>) 2542 0x74BD 璽 (<CJK Ideograph>) 2543 0x75D4 痔 (<CJK Ideograph>) 2544 0x78C1 磁 (<CJK Ideograph>) 2545 0x793A 示 (<CJK Ideograph>) 2546 0x800C 而 (<CJK Ideograph>) 2547 0x8033 耳 (<CJK Ideograph>) 2548 0x81EA 自 (<CJK Ideograph>) 2549 0x8494 蒔 (<CJK Ideograph>) 2550 0x8F9E 辞 (<CJK Ideograph>) 2551 0x6C50 汐 (<CJK Ideograph>) 2552 0x9E7F 鹿 (<CJK Ideograph>) 2553 0x5F0F 式 (<CJK Ideograph>) 2554 0x8B58 識 (<CJK Ideograph>) 2555 0x9D2B 鴫 (<CJK Ideograph>) 2556 0x7AFA 竺 (<CJK Ideograph>) 2557 0x8EF8 軸 (<CJK Ideograph>) 2558 0x5B8D 宍 (<CJK Ideograph>) 2559 0x96EB 雫 (<CJK Ideograph>) 2560 0x4E03 七 (<CJK Ideograph>) 2561 0x53F1 叱 (<CJK Ideograph>) 2562 0x57F7 執 (<CJK Ideograph>) 2563 0x5931 失 (<CJK Ideograph>) 2564 0x5AC9 嫉 (<CJK Ideograph>) 2565 0x5BA4 室 (<CJK Ideograph>) 2566 0x6089 悉 (<CJK Ideograph>) 2567 0x6E7F 湿 (<CJK Ideograph>) 2568 0x6F06 漆 (<CJK Ideograph>) 2569 0x75BE 疾 (<CJK Ideograph>) 2570 0x8CEA 質 (<CJK Ideograph>) 2571 0x5B9F 実 (<CJK Ideograph>) 2572 0x8500 蔀 (<CJK Ideograph>) 2573 0x7BE0 篠 (<CJK Ideograph>) 2574 0x5072 偲 (<CJK Ideograph>) 2575 0x67F4 柴 (<CJK Ideograph>) 2576 0x829D 芝 (<CJK Ideograph>) 2577 0x5C61 屡 (<CJK Ideograph>) 2578 0x854A 蕊 (<CJK Ideograph>) 2579 0x7E1E 縞 (<CJK Ideograph>) 2580 0x820E 舎 (<CJK Ideograph>) 2581 0x5199 写 (<CJK Ideograph>) 2582 0x5C04 射 (<CJK Ideograph>) 2583 0x6368 捨 (<CJK Ideograph>) 2584 0x8D66 赦 (<CJK Ideograph>) 2585 0x659C 斜 (<CJK Ideograph>) 2586 0x716E 煮 (<CJK Ideograph>) 2587 0x793E 社 (<CJK Ideograph>) 2588 0x7D17 紗 (<CJK Ideograph>) 2589 0x8005 者 (<CJK Ideograph>) 2590 0x8B1D 謝 (<CJK Ideograph>) 2591 0x8ECA 車 (<CJK Ideograph>) 2592 0x906E 遮 (<CJK Ideograph>) 2593 0x86C7 蛇 (<CJK Ideograph>) 2594 0x90AA 邪 (<CJK Ideograph>) 2595 0x501F 借 (<CJK Ideograph>) 2596 0x52FA 勺 (<CJK Ideograph>) 2597 0x5C3A 尺 (<CJK Ideograph>) 2598 0x6753 杓 (<CJK Ideograph>) 2599 0x707C 灼 (<CJK Ideograph>) 2600 0x7235 爵 (<CJK Ideograph>) 2601 0x914C 酌 (<CJK Ideograph>) 2602 0x91C8 釈 (<CJK Ideograph>) 2603 0x932B 錫 (<CJK Ideograph>) 2604 0x82E5 若 (<CJK Ideograph>) 2605 0x5BC2 寂 (<CJK Ideograph>) 2606 0x5F31 弱 (<CJK Ideograph>) 2607 0x60F9 惹 (<CJK Ideograph>) 2608 0x4E3B 主 (<CJK Ideograph>) 2609 0x53D6 取 (<CJK Ideograph>) 2610 0x5B88 守 (<CJK Ideograph>) 2611 0x624B 手 (<CJK Ideograph>) 2612 0x6731 朱 (<CJK Ideograph>) 2613 0x6B8A 殊 (<CJK Ideograph>) 2614 0x72E9 狩 (<CJK Ideograph>) 2615 0x73E0 珠 (<CJK Ideograph>) 2616 0x7A2E 種 (<CJK Ideograph>) 2617 0x816B 腫 (<CJK Ideograph>) 2618 0x8DA3 趣 (<CJK Ideograph>) 2619 0x9152 酒 (<CJK Ideograph>) 2620 0x9996 首 (<CJK Ideograph>) 2621 0x5112 儒 (<CJK Ideograph>) 2622 0x53D7 受 (<CJK Ideograph>) 2623 0x546A 呪 (<CJK Ideograph>) 2624 0x5BFF 寿 (<CJK Ideograph>) 2625 0x6388 授 (<CJK Ideograph>) 2626 0x6A39 樹 (<CJK Ideograph>) 2627 0x7DAC 綬 (<CJK Ideograph>) 2628 0x9700 需 (<CJK Ideograph>) 2629 0x56DA 囚 (<CJK Ideograph>) 2630 0x53CE 収 (<CJK Ideograph>) 2631 0x5468 周 (<CJK Ideograph>) 2632 0x5B97 宗 (<CJK Ideograph>) 2633 0x5C31 就 (<CJK Ideograph>) 2634 0x5DDE 州 (<CJK Ideograph>) 2635 0x4FEE 修 (<CJK Ideograph>) 2636 0x6101 愁 (<CJK Ideograph>) 2637 0x62FE 拾 (<CJK Ideograph>) 2638 0x6D32 洲 (<CJK Ideograph>) 2639 0x79C0 秀 (<CJK Ideograph>) 2640 0x79CB 秋 (<CJK Ideograph>) 2641 0x7D42 終 (<CJK Ideograph>) 2642 0x7E4D 繍 (<CJK Ideograph>) 2643 0x7FD2 習 (<CJK Ideograph>) 2644 0x81ED 臭 (<CJK Ideograph>) 2645 0x821F 舟 (<CJK Ideograph>) 2646 0x8490 蒐 (<CJK Ideograph>) 2647 0x8846 衆 (<CJK Ideograph>) 2648 0x8972 襲 (<CJK Ideograph>) 2649 0x8B90 讐 (<CJK Ideograph>) 2650 0x8E74 蹴 (<CJK Ideograph>) 2651 0x8F2F 輯 (<CJK Ideograph>) 2652 0x9031 週 (<CJK Ideograph>) 2653 0x914B 酋 (<CJK Ideograph>) 2654 0x916C 酬 (<CJK Ideograph>) 2655 0x96C6 集 (<CJK Ideograph>) 2656 0x919C 醜 (<CJK Ideograph>) 2657 0x4EC0 什 (<CJK Ideograph>) 2658 0x4F4F 住 (<CJK Ideograph>) 2659 0x5145 充 (<CJK Ideograph>) 2660 0x5341 十 (<CJK Ideograph>) 2661 0x5F93 従 (<CJK Ideograph>) 2662 0x620E 戎 (<CJK Ideograph>) 2663 0x67D4 柔 (<CJK Ideograph>) 2664 0x6C41 汁 (<CJK Ideograph>) 2665 0x6E0B 渋 (<CJK Ideograph>) 2666 0x7363 獣 (<CJK Ideograph>) 2667 0x7E26 縦 (<CJK Ideograph>) 2668 0x91CD 重 (<CJK Ideograph>) 2669 0x9283 銃 (<CJK Ideograph>) 2670 0x53D4 叔 (<CJK Ideograph>) 2671 0x5919 夙 (<CJK Ideograph>) 2672 0x5BBF 宿 (<CJK Ideograph>) 2673 0x6DD1 淑 (<CJK Ideograph>) 2674 0x795D 祝 (<CJK Ideograph>) 2675 0x7E2E 縮 (<CJK Ideograph>) 2676 0x7C9B 粛 (<CJK Ideograph>) 2677 0x587E 塾 (<CJK Ideograph>) 2678 0x719F 熟 (<CJK Ideograph>) 2679 0x51FA 出 (<CJK Ideograph>) 2680 0x8853 術 (<CJK Ideograph>) 2681 0x8FF0 述 (<CJK Ideograph>) 2682 0x4FCA 俊 (<CJK Ideograph>) 2683 0x5CFB 峻 (<CJK Ideograph>) 2684 0x6625 春 (<CJK Ideograph>) 2685 0x77AC 瞬 (<CJK Ideograph>) 2686 0x7AE3 竣 (<CJK Ideograph>) 2687 0x821C 舜 (<CJK Ideograph>) 2688 0x99FF 駿 (<CJK Ideograph>) 2689 0x51C6 准 (<CJK Ideograph>) 2690 0x5FAA 循 (<CJK Ideograph>) 2691 0x65EC 旬 (<CJK Ideograph>) 2692 0x696F 楯 (<CJK Ideograph>) 2693 0x6B89 殉 (<CJK Ideograph>) 2694 0x6DF3 淳 (<CJK Ideograph>) 2695 0x6E96 準 (<CJK Ideograph>) 2696 0x6F64 潤 (<CJK Ideograph>) 2697 0x76FE 盾 (<CJK Ideograph>) 2698 0x7D14 純 (<CJK Ideograph>) 2699 0x5DE1 巡 (<CJK Ideograph>) 2700 0x9075 遵 (<CJK Ideograph>) 2701 0x9187 醇 (<CJK Ideograph>) 2702 0x9806 順 (<CJK Ideograph>) 2703 0x51E6 処 (<CJK Ideograph>) 2704 0x521D 初 (<CJK Ideograph>) 2705 0x6240 所 (<CJK Ideograph>) 2706 0x6691 暑 (<CJK Ideograph>) 2707 0x66D9 曙 (<CJK Ideograph>) 2708 0x6E1A 渚 (<CJK Ideograph>) 2709 0x5EB6 庶 (<CJK Ideograph>) 2710 0x7DD2 緒 (<CJK Ideograph>) 2711 0x7F72 署 (<CJK Ideograph>) 2712 0x66F8 書 (<CJK Ideograph>) 2713 0x85AF 薯 (<CJK Ideograph>) 2714 0x85F7 藷 (<CJK Ideograph>) 2715 0x8AF8 諸 (<CJK Ideograph>) 2716 0x52A9 助 (<CJK Ideograph>) 2717 0x53D9 叙 (<CJK Ideograph>) 2718 0x5973 女 (<CJK Ideograph>) 2719 0x5E8F 序 (<CJK Ideograph>) 2720 0x5F90 徐 (<CJK Ideograph>) 2721 0x6055 恕 (<CJK Ideograph>) 2722 0x92E4 鋤 (<CJK Ideograph>) 2723 0x9664 除 (<CJK Ideograph>) 2724 0x50B7 傷 (<CJK Ideograph>) 2725 0x511F 償 (<CJK Ideograph>) 2726 0x52DD 勝 (<CJK Ideograph>) 2727 0x5320 匠 (<CJK Ideograph>) 2728 0x5347 升 (<CJK Ideograph>) 2729 0x53EC 召 (<CJK Ideograph>) 2730 0x54E8 哨 (<CJK Ideograph>) 2731 0x5546 商 (<CJK Ideograph>) 2732 0x5531 唱 (<CJK Ideograph>) 2733 0x5617 嘗 (<CJK Ideograph>) 2734 0x5968 奨 (<CJK Ideograph>) 2735 0x59BE 妾 (<CJK Ideograph>) 2736 0x5A3C 娼 (<CJK Ideograph>) 2737 0x5BB5 宵 (<CJK Ideograph>) 2738 0x5C06 将 (<CJK Ideograph>) 2739 0x5C0F 小 (<CJK Ideograph>) 2740 0x5C11 少 (<CJK Ideograph>) 2741 0x5C1A 尚 (<CJK Ideograph>) 2742 0x5E84 庄 (<CJK Ideograph>) 2743 0x5E8A 床 (<CJK Ideograph>) 2744 0x5EE0 廠 (<CJK Ideograph>) 2745 0x5F70 彰 (<CJK Ideograph>) 2746 0x627F 承 (<CJK Ideograph>) 2747 0x6284 抄 (<CJK Ideograph>) 2748 0x62DB 招 (<CJK Ideograph>) 2749 0x638C 掌 (<CJK Ideograph>) 2750 0x6377 捷 (<CJK Ideograph>) 2751 0x6607 昇 (<CJK Ideograph>) 2752 0x660C 昌 (<CJK Ideograph>) 2753 0x662D 昭 (<CJK Ideograph>) 2754 0x6676 晶 (<CJK Ideograph>) 2755 0x677E 松 (<CJK Ideograph>) 2756 0x68A2 梢 (<CJK Ideograph>) 2757 0x6A1F 樟 (<CJK Ideograph>) 2758 0x6A35 樵 (<CJK Ideograph>) 2759 0x6CBC 沼 (<CJK Ideograph>) 2760 0x6D88 消 (<CJK Ideograph>) 2761 0x6E09 渉 (<CJK Ideograph>) 2762 0x6E58 湘 (<CJK Ideograph>) 2763 0x713C 焼 (<CJK Ideograph>) 2764 0x7126 焦 (<CJK Ideograph>) 2765 0x7167 照 (<CJK Ideograph>) 2766 0x75C7 症 (<CJK Ideograph>) 2767 0x7701 省 (<CJK Ideograph>) 2768 0x785D 硝 (<CJK Ideograph>) 2769 0x7901 礁 (<CJK Ideograph>) 2770 0x7965 祥 (<CJK Ideograph>) 2771 0x79F0 称 (<CJK Ideograph>) 2772 0x7AE0 章 (<CJK Ideograph>) 2773 0x7B11 笑 (<CJK Ideograph>) 2774 0x7CA7 粧 (<CJK Ideograph>) 2775 0x7D39 紹 (<CJK Ideograph>) 2776 0x8096 肖 (<CJK Ideograph>) 2777 0x83D6 菖 (<CJK Ideograph>) 2778 0x848B 蒋 (<CJK Ideograph>) 2779 0x8549 蕉 (<CJK Ideograph>) 2780 0x885D 衝 (<CJK Ideograph>) 2781 0x88F3 裳 (<CJK Ideograph>) 2782 0x8A1F 訟 (<CJK Ideograph>) 2783 0x8A3C 証 (<CJK Ideograph>) 2784 0x8A54 詔 (<CJK Ideograph>) 2785 0x8A73 詳 (<CJK Ideograph>) 2786 0x8C61 象 (<CJK Ideograph>) 2787 0x8CDE 賞 (<CJK Ideograph>) 2788 0x91A4 醤 (<CJK Ideograph>) 2789 0x9266 鉦 (<CJK Ideograph>) 2790 0x937E 鍾 (<CJK Ideograph>) 2791 0x9418 鐘 (<CJK Ideograph>) 2792 0x969C 障 (<CJK Ideograph>) 2793 0x9798 鞘 (<CJK Ideograph>) 2794 0x4E0A 上 (<CJK Ideograph>) 2795 0x4E08 丈 (<CJK Ideograph>) 2796 0x4E1E 丞 (<CJK Ideograph>) 2797 0x4E57 乗 (<CJK Ideograph>) 2798 0x5197 冗 (<CJK Ideograph>) 2799 0x5270 剰 (<CJK Ideograph>) 2800 0x57CE 城 (<CJK Ideograph>) 2801 0x5834 場 (<CJK Ideograph>) 2802 0x58CC 壌 (<CJK Ideograph>) 2803 0x5B22 嬢 (<CJK Ideograph>) 2804 0x5E38 常 (<CJK Ideograph>) 2805 0x60C5 情 (<CJK Ideograph>) 2806 0x64FE 擾 (<CJK Ideograph>) 2807 0x6761 条 (<CJK Ideograph>) 2808 0x6756 杖 (<CJK Ideograph>) 2809 0x6D44 浄 (<CJK Ideograph>) 2810 0x72B6 状 (<CJK Ideograph>) 2811 0x7573 畳 (<CJK Ideograph>) 2812 0x7A63 穣 (<CJK Ideograph>) 2813 0x84B8 蒸 (<CJK Ideograph>) 2814 0x8B72 譲 (<CJK Ideograph>) 2815 0x91B8 醸 (<CJK Ideograph>) 2816 0x9320 錠 (<CJK Ideograph>) 2817 0x5631 嘱 (<CJK Ideograph>) 2818 0x57F4 埴 (<CJK Ideograph>) 2819 0x98FE 飾 (<CJK Ideograph>) 2820 0x62ED 拭 (<CJK Ideograph>) 2821 0x690D 植 (<CJK Ideograph>) 2822 0x6B96 殖 (<CJK Ideograph>) 2823 0x71ED 燭 (<CJK Ideograph>) 2824 0x7E54 織 (<CJK Ideograph>) 2825 0x8077 職 (<CJK Ideograph>) 2826 0x8272 色 (<CJK Ideograph>) 2827 0x89E6 触 (<CJK Ideograph>) 2828 0x98DF 食 (<CJK Ideograph>) 2829 0x8755 蝕 (<CJK Ideograph>) 2830 0x8FB1 辱 (<CJK Ideograph>) 2831 0x5C3B 尻 (<CJK Ideograph>) 2832 0x4F38 伸 (<CJK Ideograph>) 2833 0x4FE1 信 (<CJK Ideograph>) 2834 0x4FB5 侵 (<CJK Ideograph>) 2835 0x5507 唇 (<CJK Ideograph>) 2836 0x5A20 娠 (<CJK Ideograph>) 2837 0x5BDD 寝 (<CJK Ideograph>) 2838 0x5BE9 審 (<CJK Ideograph>) 2839 0x5FC3 心 (<CJK Ideograph>) 2840 0x614E 慎 (<CJK Ideograph>) 2841 0x632F 振 (<CJK Ideograph>) 2842 0x65B0 新 (<CJK Ideograph>) 2843 0x664B 晋 (<CJK Ideograph>) 2844 0x68EE 森 (<CJK Ideograph>) 2845 0x699B 榛 (<CJK Ideograph>) 2846 0x6D78 浸 (<CJK Ideograph>) 2847 0x6DF1 深 (<CJK Ideograph>) 2848 0x7533 申 (<CJK Ideograph>) 2849 0x75B9 疹 (<CJK Ideograph>) 2850 0x771F 真 (<CJK Ideograph>) 2851 0x795E 神 (<CJK Ideograph>) 2852 0x79E6 秦 (<CJK Ideograph>) 2853 0x7D33 紳 (<CJK Ideograph>) 2854 0x81E3 臣 (<CJK Ideograph>) 2855 0x82AF 芯 (<CJK Ideograph>) 2856 0x85AA 薪 (<CJK Ideograph>) 2857 0x89AA 親 (<CJK Ideograph>) 2858 0x8A3A 診 (<CJK Ideograph>) 2859 0x8EAB 身 (<CJK Ideograph>) 2860 0x8F9B 辛 (<CJK Ideograph>) 2861 0x9032 進 (<CJK Ideograph>) 2862 0x91DD 針 (<CJK Ideograph>) 2863 0x9707 震 (<CJK Ideograph>) 2864 0x4EBA 人 (<CJK Ideograph>) 2865 0x4EC1 仁 (<CJK Ideograph>) 2866 0x5203 刃 (<CJK Ideograph>) 2867 0x5875 塵 (<CJK Ideograph>) 2868 0x58EC 壬 (<CJK Ideograph>) 2869 0x5C0B 尋 (<CJK Ideograph>) 2870 0x751A 甚 (<CJK Ideograph>) 2871 0x5C3D 尽 (<CJK Ideograph>) 2872 0x814E 腎 (<CJK Ideograph>) 2873 0x8A0A 訊 (<CJK Ideograph>) 2874 0x8FC5 迅 (<CJK Ideograph>) 2875 0x9663 陣 (<CJK Ideograph>) 2876 0x976D 靭 (<CJK Ideograph>) 2877 0x7B25 笥 (<CJK Ideograph>) 2878 0x8ACF 諏 (<CJK Ideograph>) 2879 0x9808 須 (<CJK Ideograph>) 2880 0x9162 酢 (<CJK Ideograph>) 2881 0x56F3 図 (<CJK Ideograph>) 2882 0x53A8 厨 (<CJK Ideograph>) 2883 0x9017 逗 (<CJK Ideograph>) 2884 0x5439 吹 (<CJK Ideograph>) 2885 0x5782 垂 (<CJK Ideograph>) 2886 0x5E25 帥 (<CJK Ideograph>) 2887 0x63A8 推 (<CJK Ideograph>) 2888 0x6C34 水 (<CJK Ideograph>) 2889 0x708A 炊 (<CJK Ideograph>) 2890 0x7761 睡 (<CJK Ideograph>) 2891 0x7C8B 粋 (<CJK Ideograph>) 2892 0x7FE0 翠 (<CJK Ideograph>) 2893 0x8870 衰 (<CJK Ideograph>) 2894 0x9042 遂 (<CJK Ideograph>) 2895 0x9154 酔 (<CJK Ideograph>) 2896 0x9310 錐 (<CJK Ideograph>) 2897 0x9318 錘 (<CJK Ideograph>) 2898 0x968F 随 (<CJK Ideograph>) 2899 0x745E 瑞 (<CJK Ideograph>) 2900 0x9AC4 髄 (<CJK Ideograph>) 2901 0x5D07 崇 (<CJK Ideograph>) 2902 0x5D69 嵩 (<CJK Ideograph>) 2903 0x6570 数 (<CJK Ideograph>) 2904 0x67A2 枢 (<CJK Ideograph>) 2905 0x8DA8 趨 (<CJK Ideograph>) 2906 0x96DB 雛 (<CJK Ideograph>) 2907 0x636E 据 (<CJK Ideograph>) 2908 0x6749 杉 (<CJK Ideograph>) 2909 0x6919 椙 (<CJK Ideograph>) 2910 0x83C5 菅 (<CJK Ideograph>) 2911 0x9817 頗 (<CJK Ideograph>) 2912 0x96C0 雀 (<CJK Ideograph>) 2913 0x88FE 裾 (<CJK Ideograph>) 2914 0x6F84 澄 (<CJK Ideograph>) 2915 0x647A 摺 (<CJK Ideograph>) 2916 0x5BF8 寸 (<CJK Ideograph>) 2917 0x4E16 世 (<CJK Ideograph>) 2918 0x702C 瀬 (<CJK Ideograph>) 2919 0x755D 畝 (<CJK Ideograph>) 2920 0x662F 是 (<CJK Ideograph>) 2921 0x51C4 凄 (<CJK Ideograph>) 2922 0x5236 制 (<CJK Ideograph>) 2923 0x52E2 勢 (<CJK Ideograph>) 2924 0x59D3 姓 (<CJK Ideograph>) 2925 0x5F81 征 (<CJK Ideograph>) 2926 0x6027 性 (<CJK Ideograph>) 2927 0x6210 成 (<CJK Ideograph>) 2928 0x653F 政 (<CJK Ideograph>) 2929 0x6574 整 (<CJK Ideograph>) 2930 0x661F 星 (<CJK Ideograph>) 2931 0x6674 晴 (<CJK Ideograph>) 2932 0x68F2 棲 (<CJK Ideograph>) 2933 0x6816 栖 (<CJK Ideograph>) 2934 0x6B63 正 (<CJK Ideograph>) 2935 0x6E05 清 (<CJK Ideograph>) 2936 0x7272 牲 (<CJK Ideograph>) 2937 0x751F 生 (<CJK Ideograph>) 2938 0x76DB 盛 (<CJK Ideograph>) 2939 0x7CBE 精 (<CJK Ideograph>) 2940 0x8056 聖 (<CJK Ideograph>) 2941 0x58F0 声 (<CJK Ideograph>) 2942 0x88FD 製 (<CJK Ideograph>) 2943 0x897F 西 (<CJK Ideograph>) 2944 0x8AA0 誠 (<CJK Ideograph>) 2945 0x8A93 誓 (<CJK Ideograph>) 2946 0x8ACB 請 (<CJK Ideograph>) 2947 0x901D 逝 (<CJK Ideograph>) 2948 0x9192 醒 (<CJK Ideograph>) 2949 0x9752 青 (<CJK Ideograph>) 2950 0x9759 静 (<CJK Ideograph>) 2951 0x6589 斉 (<CJK Ideograph>) 2952 0x7A0E 税 (<CJK Ideograph>) 2953 0x8106 脆 (<CJK Ideograph>) 2954 0x96BB 隻 (<CJK Ideograph>) 2955 0x5E2D 席 (<CJK Ideograph>) 2956 0x60DC 惜 (<CJK Ideograph>) 2957 0x621A 戚 (<CJK Ideograph>) 2958 0x65A5 斥 (<CJK Ideograph>) 2959 0x6614 昔 (<CJK Ideograph>) 2960 0x6790 析 (<CJK Ideograph>) 2961 0x77F3 石 (<CJK Ideograph>) 2962 0x7A4D 積 (<CJK Ideograph>) 2963 0x7C4D 籍 (<CJK Ideograph>) 2964 0x7E3E 績 (<CJK Ideograph>) 2965 0x810A 脊 (<CJK Ideograph>) 2966 0x8CAC 責 (<CJK Ideograph>) 2967 0x8D64 赤 (<CJK Ideograph>) 2968 0x8DE1 跡 (<CJK Ideograph>) 2969 0x8E5F 蹟 (<CJK Ideograph>) 2970 0x78A9 碩 (<CJK Ideograph>) 2971 0x5207 切 (<CJK Ideograph>) 2972 0x62D9 拙 (<CJK Ideograph>) 2973 0x63A5 接 (<CJK Ideograph>) 2974 0x6442 摂 (<CJK Ideograph>) 2975 0x6298 折 (<CJK Ideograph>) 2976 0x8A2D 設 (<CJK Ideograph>) 2977 0x7A83 窃 (<CJK Ideograph>) 2978 0x7BC0 節 (<CJK Ideograph>) 2979 0x8AAC 説 (<CJK Ideograph>) 2980 0x96EA 雪 (<CJK Ideograph>) 2981 0x7D76 絶 (<CJK Ideograph>) 2982 0x820C 舌 (<CJK Ideograph>) 2983 0x8749 蝉 (<CJK Ideograph>) 2984 0x4ED9 仙 (<CJK Ideograph>) 2985 0x5148 先 (<CJK Ideograph>) 2986 0x5343 千 (<CJK Ideograph>) 2987 0x5360 占 (<CJK Ideograph>) 2988 0x5BA3 宣 (<CJK Ideograph>) 2989 0x5C02 専 (<CJK Ideograph>) 2990 0x5C16 尖 (<CJK Ideograph>) 2991 0x5DDD 川 (<CJK Ideograph>) 2992 0x6226 戦 (<CJK Ideograph>) 2993 0x6247 扇 (<CJK Ideograph>) 2994 0x64B0 撰 (<CJK Ideograph>) 2995 0x6813 栓 (<CJK Ideograph>) 2996 0x6834 栴 (<CJK Ideograph>) 2997 0x6CC9 泉 (<CJK Ideograph>) 2998 0x6D45 浅 (<CJK Ideograph>) 2999 0x6D17 洗 (<CJK Ideograph>) 3000 0x67D3 染 (<CJK Ideograph>) 3001 0x6F5C 潜 (<CJK Ideograph>) 3002 0x714E 煎 (<CJK Ideograph>) 3003 0x717D 煽 (<CJK Ideograph>) 3004 0x65CB 旋 (<CJK Ideograph>) 3005 0x7A7F 穿 (<CJK Ideograph>) 3006 0x7BAD 箭 (<CJK Ideograph>) 3007 0x7DDA 線 (<CJK Ideograph>) 3008 0x7E4A 繊 (<CJK Ideograph>) 3009 0x7FA8 羨 (<CJK Ideograph>) 3010 0x817A 腺 (<CJK Ideograph>) 3011 0x821B 舛 (<CJK Ideograph>) 3012 0x8239 船 (<CJK Ideograph>) 3013 0x85A6 薦 (<CJK Ideograph>) 3014 0x8A6E 詮 (<CJK Ideograph>) 3015 0x8CCE 賎 (<CJK Ideograph>) 3016 0x8DF5 践 (<CJK Ideograph>) 3017 0x9078 選 (<CJK Ideograph>) 3018 0x9077 遷 (<CJK Ideograph>) 3019 0x92AD 銭 (<CJK Ideograph>) 3020 0x9291 銑 (<CJK Ideograph>) 3021 0x9583 閃 (<CJK Ideograph>) 3022 0x9BAE 鮮 (<CJK Ideograph>) 3023 0x524D 前 (<CJK Ideograph>) 3024 0x5584 善 (<CJK Ideograph>) 3025 0x6F38 漸 (<CJK Ideograph>) 3026 0x7136 然 (<CJK Ideograph>) 3027 0x5168 全 (<CJK Ideograph>) 3028 0x7985 禅 (<CJK Ideograph>) 3029 0x7E55 繕 (<CJK Ideograph>) 3030 0x81B3 膳 (<CJK Ideograph>) 3031 0x7CCE 糎 (<CJK Ideograph>) 3032 0x564C 噌 (<CJK Ideograph>) 3033 0x5851 塑 (<CJK Ideograph>) 3034 0x5CA8 岨 (<CJK Ideograph>) 3035 0x63AA 措 (<CJK Ideograph>) 3036 0x66FE 曾 (<CJK Ideograph>) 3037 0x66FD 曽 (<CJK Ideograph>) 3038 0x695A 楚 (<CJK Ideograph>) 3039 0x72D9 狙 (<CJK Ideograph>) 3040 0x758F 疏 (<CJK Ideograph>) 3041 0x758E 疎 (<CJK Ideograph>) 3042 0x790E 礎 (<CJK Ideograph>) 3043 0x7956 祖 (<CJK Ideograph>) 3044 0x79DF 租 (<CJK Ideograph>) 3045 0x7C97 粗 (<CJK Ideograph>) 3046 0x7D20 素 (<CJK Ideograph>) 3047 0x7D44 組 (<CJK Ideograph>) 3048 0x8607 蘇 (<CJK Ideograph>) 3049 0x8A34 訴 (<CJK Ideograph>) 3050 0x963B 阻 (<CJK Ideograph>) 3051 0x9061 遡 (<CJK Ideograph>) 3052 0x9F20 鼠 (<CJK Ideograph>) 3053 0x50E7 僧 (<CJK Ideograph>) 3054 0x5275 創 (<CJK Ideograph>) 3055 0x53CC 双 (<CJK Ideograph>) 3056 0x53E2 叢 (<CJK Ideograph>) 3057 0x5009 倉 (<CJK Ideograph>) 3058 0x55AA 喪 (<CJK Ideograph>) 3059 0x58EE 壮 (<CJK Ideograph>) 3060 0x594F 奏 (<CJK Ideograph>) 3061 0x723D 爽 (<CJK Ideograph>) 3062 0x5B8B 宋 (<CJK Ideograph>) 3063 0x5C64 層 (<CJK Ideograph>) 3064 0x531D 匝 (<CJK Ideograph>) 3065 0x60E3 惣 (<CJK Ideograph>) 3066 0x60F3 想 (<CJK Ideograph>) 3067 0x635C 捜 (<CJK Ideograph>) 3068 0x6383 掃 (<CJK Ideograph>) 3069 0x633F 挿 (<CJK Ideograph>) 3070 0x63BB 掻 (<CJK Ideograph>) 3071 0x64CD 操 (<CJK Ideograph>) 3072 0x65E9 早 (<CJK Ideograph>) 3073 0x66F9 曹 (<CJK Ideograph>) 3074 0x5DE3 巣 (<CJK Ideograph>) 3075 0x69CD 槍 (<CJK Ideograph>) 3076 0x69FD 槽 (<CJK Ideograph>) 3077 0x6F15 漕 (<CJK Ideograph>) 3078 0x71E5 燥 (<CJK Ideograph>) 3079 0x4E89 争 (<CJK Ideograph>) 3080 0x75E9 痩 (<CJK Ideograph>) 3081 0x76F8 相 (<CJK Ideograph>) 3082 0x7A93 窓 (<CJK Ideograph>) 3083 0x7CDF 糟 (<CJK Ideograph>) 3084 0x7DCF 総 (<CJK Ideograph>) 3085 0x7D9C 綜 (<CJK Ideograph>) 3086 0x8061 聡 (<CJK Ideograph>) 3087 0x8349 草 (<CJK Ideograph>) 3088 0x8358 荘 (<CJK Ideograph>) 3089 0x846C 葬 (<CJK Ideograph>) 3090 0x84BC 蒼 (<CJK Ideograph>) 3091 0x85FB 藻 (<CJK Ideograph>) 3092 0x88C5 装 (<CJK Ideograph>) 3093 0x8D70 走 (<CJK Ideograph>) 3094 0x9001 送 (<CJK Ideograph>) 3095 0x906D 遭 (<CJK Ideograph>) 3096 0x9397 鎗 (<CJK Ideograph>) 3097 0x971C 霜 (<CJK Ideograph>) 3098 0x9A12 騒 (<CJK Ideograph>) 3099 0x50CF 像 (<CJK Ideograph>) 3100 0x5897 増 (<CJK Ideograph>) 3101 0x618E 憎 (<CJK Ideograph>) 3102 0x81D3 臓 (<CJK Ideograph>) 3103 0x8535 蔵 (<CJK Ideograph>) 3104 0x8D08 贈 (<CJK Ideograph>) 3105 0x9020 造 (<CJK Ideograph>) 3106 0x4FC3 促 (<CJK Ideograph>) 3107 0x5074 側 (<CJK Ideograph>) 3108 0x5247 則 (<CJK Ideograph>) 3109 0x5373 即 (<CJK Ideograph>) 3110 0x606F 息 (<CJK Ideograph>) 3111 0x6349 捉 (<CJK Ideograph>) 3112 0x675F 束 (<CJK Ideograph>) 3113 0x6E2C 測 (<CJK Ideograph>) 3114 0x8DB3 足 (<CJK Ideograph>) 3115 0x901F 速 (<CJK Ideograph>) 3116 0x4FD7 俗 (<CJK Ideograph>) 3117 0x5C5E 属 (<CJK Ideograph>) 3118 0x8CCA 賊 (<CJK Ideograph>) 3119 0x65CF 族 (<CJK Ideograph>) 3120 0x7D9A 続 (<CJK Ideograph>) 3121 0x5352 卒 (<CJK Ideograph>) 3122 0x8896 袖 (<CJK Ideograph>) 3123 0x5176 其 (<CJK Ideograph>) 3124 0x63C3 揃 (<CJK Ideograph>) 3125 0x5B58 存 (<CJK Ideograph>) 3126 0x5B6B 孫 (<CJK Ideograph>) 3127 0x5C0A 尊 (<CJK Ideograph>) 3128 0x640D 損 (<CJK Ideograph>) 3129 0x6751 村 (<CJK Ideograph>) 3130 0x905C 遜 (<CJK Ideograph>) 3131 0x4ED6 他 (<CJK Ideograph>) 3132 0x591A 多 (<CJK Ideograph>) 3133 0x592A 太 (<CJK Ideograph>) 3134 0x6C70 汰 (<CJK Ideograph>) 3135 0x8A51 詑 (<CJK Ideograph>) 3136 0x553E 唾 (<CJK Ideograph>) 3137 0x5815 堕 (<CJK Ideograph>) 3138 0x59A5 妥 (<CJK Ideograph>) 3139 0x60F0 惰 (<CJK Ideograph>) 3140 0x6253 打 (<CJK Ideograph>) 3141 0x67C1 柁 (<CJK Ideograph>) 3142 0x8235 舵 (<CJK Ideograph>) 3143 0x6955 楕 (<CJK Ideograph>) 3144 0x9640 陀 (<CJK Ideograph>) 3145 0x99C4 駄 (<CJK Ideograph>) 3146 0x9A28 騨 (<CJK Ideograph>) 3147 0x4F53 体 (<CJK Ideograph>) 3148 0x5806 堆 (<CJK Ideograph>) 3149 0x5BFE 対 (<CJK Ideograph>) 3150 0x8010 耐 (<CJK Ideograph>) 3151 0x5CB1 岱 (<CJK Ideograph>) 3152 0x5E2F 帯 (<CJK Ideograph>) 3153 0x5F85 待 (<CJK Ideograph>) 3154 0x6020 怠 (<CJK Ideograph>) 3155 0x614B 態 (<CJK Ideograph>) 3156 0x6234 戴 (<CJK Ideograph>) 3157 0x66FF 替 (<CJK Ideograph>) 3158 0x6CF0 泰 (<CJK Ideograph>) 3159 0x6EDE 滞 (<CJK Ideograph>) 3160 0x80CE 胎 (<CJK Ideograph>) 3161 0x817F 腿 (<CJK Ideograph>) 3162 0x82D4 苔 (<CJK Ideograph>) 3163 0x888B 袋 (<CJK Ideograph>) 3164 0x8CB8 貸 (<CJK Ideograph>) 3165 0x9000 退 (<CJK Ideograph>) 3166 0x902E 逮 (<CJK Ideograph>) 3167 0x968A 隊 (<CJK Ideograph>) 3168 0x9EDB 黛 (<CJK Ideograph>) 3169 0x9BDB 鯛 (<CJK Ideograph>) 3170 0x4EE3 代 (<CJK Ideograph>) 3171 0x53F0 台 (<CJK Ideograph>) 3172 0x5927 大 (<CJK Ideograph>) 3173 0x7B2C 第 (<CJK Ideograph>) 3174 0x918D 醍 (<CJK Ideograph>) 3175 0x984C 題 (<CJK Ideograph>) 3176 0x9DF9 鷹 (<CJK Ideograph>) 3177 0x6EDD 滝 (<CJK Ideograph>) 3178 0x7027 瀧 (<CJK Ideograph>) 3179 0x5353 卓 (<CJK Ideograph>) 3180 0x5544 啄 (<CJK Ideograph>) 3181 0x5B85 宅 (<CJK Ideograph>) 3182 0x6258 托 (<CJK Ideograph>) 3183 0x629E 択 (<CJK Ideograph>) 3184 0x62D3 拓 (<CJK Ideograph>) 3185 0x6CA2 沢 (<CJK Ideograph>) 3186 0x6FEF 濯 (<CJK Ideograph>) 3187 0x7422 琢 (<CJK Ideograph>) 3188 0x8A17 託 (<CJK Ideograph>) 3189 0x9438 鐸 (<CJK Ideograph>) 3190 0x6FC1 濁 (<CJK Ideograph>) 3191 0x8AFE 諾 (<CJK Ideograph>) 3192 0x8338 茸 (<CJK Ideograph>) 3193 0x51E7 凧 (<CJK Ideograph>) 3194 0x86F8 蛸 (<CJK Ideograph>) 3195 0x53EA 只 (<CJK Ideograph>) 3196 0x53E9 叩 (<CJK Ideograph>) 3197 0x4F46 但 (<CJK Ideograph>) 3198 0x9054 達 (<CJK Ideograph>) 3199 0x8FB0 辰 (<CJK Ideograph>) 3200 0x596A 奪 (<CJK Ideograph>) 3201 0x8131 脱 (<CJK Ideograph>) 3202 0x5DFD 巽 (<CJK Ideograph>) 3203 0x7AEA 竪 (<CJK Ideograph>) 3204 0x8FBF 辿 (<CJK Ideograph>) 3205 0x68DA 棚 (<CJK Ideograph>) 3206 0x8C37 谷 (<CJK Ideograph>) 3207 0x72F8 狸 (<CJK Ideograph>) 3208 0x9C48 鱈 (<CJK Ideograph>) 3209 0x6A3D 樽 (<CJK Ideograph>) 3210 0x8AB0 誰 (<CJK Ideograph>) 3211 0x4E39 丹 (<CJK Ideograph>) 3212 0x5358 単 (<CJK Ideograph>) 3213 0x5606 嘆 (<CJK Ideograph>) 3214 0x5766 坦 (<CJK Ideograph>) 3215 0x62C5 担 (<CJK Ideograph>) 3216 0x63A2 探 (<CJK Ideograph>) 3217 0x65E6 旦 (<CJK Ideograph>) 3218 0x6B4E 歎 (<CJK Ideograph>) 3219 0x6DE1 淡 (<CJK Ideograph>) 3220 0x6E5B 湛 (<CJK Ideograph>) 3221 0x70AD 炭 (<CJK Ideograph>) 3222 0x77ED 短 (<CJK Ideograph>) 3223 0x7AEF 端 (<CJK Ideograph>) 3224 0x7BAA 箪 (<CJK Ideograph>) 3225 0x7DBB 綻 (<CJK Ideograph>) 3226 0x803D 耽 (<CJK Ideograph>) 3227 0x80C6 胆 (<CJK Ideograph>) 3228 0x86CB 蛋 (<CJK Ideograph>) 3229 0x8A95 誕 (<CJK Ideograph>) 3230 0x935B 鍛 (<CJK Ideograph>) 3231 0x56E3 団 (<CJK Ideograph>) 3232 0x58C7 壇 (<CJK Ideograph>) 3233 0x5F3E 弾 (<CJK Ideograph>) 3234 0x65AD 断 (<CJK Ideograph>) 3235 0x6696 暖 (<CJK Ideograph>) 3236 0x6A80 檀 (<CJK Ideograph>) 3237 0x6BB5 段 (<CJK Ideograph>) 3238 0x7537 男 (<CJK Ideograph>) 3239 0x8AC7 談 (<CJK Ideograph>) 3240 0x5024 値 (<CJK Ideograph>) 3241 0x77E5 知 (<CJK Ideograph>) 3242 0x5730 地 (<CJK Ideograph>) 3243 0x5F1B 弛 (<CJK Ideograph>) 3244 0x6065 恥 (<CJK Ideograph>) 3245 0x667A 智 (<CJK Ideograph>) 3246 0x6C60 池 (<CJK Ideograph>) 3247 0x75F4 痴 (<CJK Ideograph>) 3248 0x7A1A 稚 (<CJK Ideograph>) 3249 0x7F6E 置 (<CJK Ideograph>) 3250 0x81F4 致 (<CJK Ideograph>) 3251 0x8718 蜘 (<CJK Ideograph>) 3252 0x9045 遅 (<CJK Ideograph>) 3253 0x99B3 馳 (<CJK Ideograph>) 3254 0x7BC9 築 (<CJK Ideograph>) 3255 0x755C 畜 (<CJK Ideograph>) 3256 0x7AF9 竹 (<CJK Ideograph>) 3257 0x7B51 筑 (<CJK Ideograph>) 3258 0x84C4 蓄 (<CJK Ideograph>) 3259 0x9010 逐 (<CJK Ideograph>) 3260 0x79E9 秩 (<CJK Ideograph>) 3261 0x7A92 窒 (<CJK Ideograph>) 3262 0x8336 茶 (<CJK Ideograph>) 3263 0x5AE1 嫡 (<CJK Ideograph>) 3264 0x7740 着 (<CJK Ideograph>) 3265 0x4E2D 中 (<CJK Ideograph>) 3266 0x4EF2 仲 (<CJK Ideograph>) 3267 0x5B99 宙 (<CJK Ideograph>) 3268 0x5FE0 忠 (<CJK Ideograph>) 3269 0x62BD 抽 (<CJK Ideograph>) 3270 0x663C 昼 (<CJK Ideograph>) 3271 0x67F1 柱 (<CJK Ideograph>) 3272 0x6CE8 注 (<CJK Ideograph>) 3273 0x866B 虫 (<CJK Ideograph>) 3274 0x8877 衷 (<CJK Ideograph>) 3275 0x8A3B 註 (<CJK Ideograph>) 3276 0x914E 酎 (<CJK Ideograph>) 3277 0x92F3 鋳 (<CJK Ideograph>) 3278 0x99D0 駐 (<CJK Ideograph>) 3279 0x6A17 樗 (<CJK Ideograph>) 3280 0x7026 瀦 (<CJK Ideograph>) 3281 0x732A 猪 (<CJK Ideograph>) 3282 0x82E7 苧 (<CJK Ideograph>) 3283 0x8457 著 (<CJK Ideograph>) 3284 0x8CAF 貯 (<CJK Ideograph>) 3285 0x4E01 丁 (<CJK Ideograph>) 3286 0x5146 兆 (<CJK Ideograph>) 3287 0x51CB 凋 (<CJK Ideograph>) 3288 0x558B 喋 (<CJK Ideograph>) 3289 0x5BF5 寵 (<CJK Ideograph>) 3290 0x5E16 帖 (<CJK Ideograph>) 3291 0x5E33 帳 (<CJK Ideograph>) 3292 0x5E81 庁 (<CJK Ideograph>) 3293 0x5F14 弔 (<CJK Ideograph>) 3294 0x5F35 張 (<CJK Ideograph>) 3295 0x5F6B 彫 (<CJK Ideograph>) 3296 0x5FB4 徴 (<CJK Ideograph>) 3297 0x61F2 懲 (<CJK Ideograph>) 3298 0x6311 挑 (<CJK Ideograph>) 3299 0x66A2 暢 (<CJK Ideograph>) 3300 0x671D 朝 (<CJK Ideograph>) 3301 0x6F6E 潮 (<CJK Ideograph>) 3302 0x7252 牒 (<CJK Ideograph>) 3303 0x753A 町 (<CJK Ideograph>) 3304 0x773A 眺 (<CJK Ideograph>) 3305 0x8074 聴 (<CJK Ideograph>) 3306 0x8139 脹 (<CJK Ideograph>) 3307 0x8178 腸 (<CJK Ideograph>) 3308 0x8776 蝶 (<CJK Ideograph>) 3309 0x8ABF 調 (<CJK Ideograph>) 3310 0x8ADC 諜 (<CJK Ideograph>) 3311 0x8D85 超 (<CJK Ideograph>) 3312 0x8DF3 跳 (<CJK Ideograph>) 3313 0x929A 銚 (<CJK Ideograph>) 3314 0x9577 長 (<CJK Ideograph>) 3315 0x9802 頂 (<CJK Ideograph>) 3316 0x9CE5 鳥 (<CJK Ideograph>) 3317 0x52C5 勅 (<CJK Ideograph>) 3318 0x6357 捗 (<CJK Ideograph>) 3319 0x76F4 直 (<CJK Ideograph>) 3320 0x6715 朕 (<CJK Ideograph>) 3321 0x6C88 沈 (<CJK Ideograph>) 3322 0x73CD 珍 (<CJK Ideograph>) 3323 0x8CC3 賃 (<CJK Ideograph>) 3324 0x93AE 鎮 (<CJK Ideograph>) 3325 0x9673 陳 (<CJK Ideograph>) 3326 0x6D25 津 (<CJK Ideograph>) 3327 0x589C 墜 (<CJK Ideograph>) 3328 0x690E 椎 (<CJK Ideograph>) 3329 0x69CC 槌 (<CJK Ideograph>) 3330 0x8FFD 追 (<CJK Ideograph>) 3331 0x939A 鎚 (<CJK Ideograph>) 3332 0x75DB 痛 (<CJK Ideograph>) 3333 0x901A 通 (<CJK Ideograph>) 3334 0x585A 塚 (<CJK Ideograph>) 3335 0x6802 栂 (<CJK Ideograph>) 3336 0x63B4 掴 (<CJK Ideograph>) 3337 0x69FB 槻 (<CJK Ideograph>) 3338 0x4F43 佃 (<CJK Ideograph>) 3339 0x6F2C 漬 (<CJK Ideograph>) 3340 0x67D8 柘 (<CJK Ideograph>) 3341 0x8FBB 辻 (<CJK Ideograph>) 3342 0x8526 蔦 (<CJK Ideograph>) 3343 0x7DB4 綴 (<CJK Ideograph>) 3344 0x9354 鍔 (<CJK Ideograph>) 3345 0x693F 椿 (<CJK Ideograph>) 3346 0x6F70 潰 (<CJK Ideograph>) 3347 0x576A 坪 (<CJK Ideograph>) 3348 0x58F7 壷 (<CJK Ideograph>) 3349 0x5B2C 嬬 (<CJK Ideograph>) 3350 0x7D2C 紬 (<CJK Ideograph>) 3351 0x722A 爪 (<CJK Ideograph>) 3352 0x540A 吊 (<CJK Ideograph>) 3353 0x91E3 釣 (<CJK Ideograph>) 3354 0x9DB4 鶴 (<CJK Ideograph>) 3355 0x4EAD 亭 (<CJK Ideograph>) 3356 0x4F4E 低 (<CJK Ideograph>) 3357 0x505C 停 (<CJK Ideograph>) 3358 0x5075 偵 (<CJK Ideograph>) 3359 0x5243 剃 (<CJK Ideograph>) 3360 0x8C9E 貞 (<CJK Ideograph>) 3361 0x5448 呈 (<CJK Ideograph>) 3362 0x5824 堤 (<CJK Ideograph>) 3363 0x5B9A 定 (<CJK Ideograph>) 3364 0x5E1D 帝 (<CJK Ideograph>) 3365 0x5E95 底 (<CJK Ideograph>) 3366 0x5EAD 庭 (<CJK Ideograph>) 3367 0x5EF7 廷 (<CJK Ideograph>) 3368 0x5F1F 弟 (<CJK Ideograph>) 3369 0x608C 悌 (<CJK Ideograph>) 3370 0x62B5 抵 (<CJK Ideograph>) 3371 0x633A 挺 (<CJK Ideograph>) 3372 0x63D0 提 (<CJK Ideograph>) 3373 0x68AF 梯 (<CJK Ideograph>) 3374 0x6C40 汀 (<CJK Ideograph>) 3375 0x7887 碇 (<CJK Ideograph>) 3376 0x798E 禎 (<CJK Ideograph>) 3377 0x7A0B 程 (<CJK Ideograph>) 3378 0x7DE0 締 (<CJK Ideograph>) 3379 0x8247 艇 (<CJK Ideograph>) 3380 0x8A02 訂 (<CJK Ideograph>) 3381 0x8AE6 諦 (<CJK Ideograph>) 3382 0x8E44 蹄 (<CJK Ideograph>) 3383 0x9013 逓 (<CJK Ideograph>) 3384 0x90B8 邸 (<CJK Ideograph>) 3385 0x912D 鄭 (<CJK Ideograph>) 3386 0x91D8 釘 (<CJK Ideograph>) 3387 0x9F0E 鼎 (<CJK Ideograph>) 3388 0x6CE5 泥 (<CJK Ideograph>) 3389 0x6458 摘 (<CJK Ideograph>) 3390 0x64E2 擢 (<CJK Ideograph>) 3391 0x6575 敵 (<CJK Ideograph>) 3392 0x6EF4 滴 (<CJK Ideograph>) 3393 0x7684 的 (<CJK Ideograph>) 3394 0x7B1B 笛 (<CJK Ideograph>) 3395 0x9069 適 (<CJK Ideograph>) 3396 0x93D1 鏑 (<CJK Ideograph>) 3397 0x6EBA 溺 (<CJK Ideograph>) 3398 0x54F2 哲 (<CJK Ideograph>) 3399 0x5FB9 徹 (<CJK Ideograph>) 3400 0x64A4 撤 (<CJK Ideograph>) 3401 0x8F4D 轍 (<CJK Ideograph>) 3402 0x8FED 迭 (<CJK Ideograph>) 3403 0x9244 鉄 (<CJK Ideograph>) 3404 0x5178 典 (<CJK Ideograph>) 3405 0x586B 填 (<CJK Ideograph>) 3406 0x5929 天 (<CJK Ideograph>) 3407 0x5C55 展 (<CJK Ideograph>) 3408 0x5E97 店 (<CJK Ideograph>) 3409 0x6DFB 添 (<CJK Ideograph>) 3410 0x7E8F 纏 (<CJK Ideograph>) 3411 0x751C 甜 (<CJK Ideograph>) 3412 0x8CBC 貼 (<CJK Ideograph>) 3413 0x8EE2 転 (<CJK Ideograph>) 3414 0x985B 顛 (<CJK Ideograph>) 3415 0x70B9 点 (<CJK Ideograph>) 3416 0x4F1D 伝 (<CJK Ideograph>) 3417 0x6BBF 殿 (<CJK Ideograph>) 3418 0x6FB1 澱 (<CJK Ideograph>) 3419 0x7530 田 (<CJK Ideograph>) 3420 0x96FB 電 (<CJK Ideograph>) 3421 0x514E 兎 (<CJK Ideograph>) 3422 0x5410 吐 (<CJK Ideograph>) 3423 0x5835 堵 (<CJK Ideograph>) 3424 0x5857 塗 (<CJK Ideograph>) 3425 0x59AC 妬 (<CJK Ideograph>) 3426 0x5C60 屠 (<CJK Ideograph>) 3427 0x5F92 徒 (<CJK Ideograph>) 3428 0x6597 斗 (<CJK Ideograph>) 3429 0x675C 杜 (<CJK Ideograph>) 3430 0x6E21 渡 (<CJK Ideograph>) 3431 0x767B 登 (<CJK Ideograph>) 3432 0x83DF 菟 (<CJK Ideograph>) 3433 0x8CED 賭 (<CJK Ideograph>) 3434 0x9014 途 (<CJK Ideograph>) 3435 0x90FD 都 (<CJK Ideograph>) 3436 0x934D 鍍 (<CJK Ideograph>) 3437 0x7825 砥 (<CJK Ideograph>) 3438 0x783A 砺 (<CJK Ideograph>) 3439 0x52AA 努 (<CJK Ideograph>) 3440 0x5EA6 度 (<CJK Ideograph>) 3441 0x571F 土 (<CJK Ideograph>) 3442 0x5974 奴 (<CJK Ideograph>) 3443 0x6012 怒 (<CJK Ideograph>) 3444 0x5012 倒 (<CJK Ideograph>) 3445 0x515A 党 (<CJK Ideograph>) 3446 0x51AC 冬 (<CJK Ideograph>) 3447 0x51CD 凍 (<CJK Ideograph>) 3448 0x5200 刀 (<CJK Ideograph>) 3449 0x5510 唐 (<CJK Ideograph>) 3450 0x5854 塔 (<CJK Ideograph>) 3451 0x5858 塘 (<CJK Ideograph>) 3452 0x5957 套 (<CJK Ideograph>) 3453 0x5B95 宕 (<CJK Ideograph>) 3454 0x5CF6 島 (<CJK Ideograph>) 3455 0x5D8B 嶋 (<CJK Ideograph>) 3456 0x60BC 悼 (<CJK Ideograph>) 3457 0x6295 投 (<CJK Ideograph>) 3458 0x642D 搭 (<CJK Ideograph>) 3459 0x6771 東 (<CJK Ideograph>) 3460 0x6843 桃 (<CJK Ideograph>) 3461 0x68BC 梼 (<CJK Ideograph>) 3462 0x68DF 棟 (<CJK Ideograph>) 3463 0x76D7 盗 (<CJK Ideograph>) 3464 0x6DD8 淘 (<CJK Ideograph>) 3465 0x6E6F 湯 (<CJK Ideograph>) 3466 0x6D9B 涛 (<CJK Ideograph>) 3467 0x706F 灯 (<CJK Ideograph>) 3468 0x71C8 燈 (<CJK Ideograph>) 3469 0x5F53 当 (<CJK Ideograph>) 3470 0x75D8 痘 (<CJK Ideograph>) 3471 0x7977 祷 (<CJK Ideograph>) 3472 0x7B49 等 (<CJK Ideograph>) 3473 0x7B54 答 (<CJK Ideograph>) 3474 0x7B52 筒 (<CJK Ideograph>) 3475 0x7CD6 糖 (<CJK Ideograph>) 3476 0x7D71 統 (<CJK Ideograph>) 3477 0x5230 到 (<CJK Ideograph>) 3478 0x8463 董 (<CJK Ideograph>) 3479 0x8569 蕩 (<CJK Ideograph>) 3480 0x85E4 藤 (<CJK Ideograph>) 3481 0x8A0E 討 (<CJK Ideograph>) 3482 0x8B04 謄 (<CJK Ideograph>) 3483 0x8C46 豆 (<CJK Ideograph>) 3484 0x8E0F 踏 (<CJK Ideograph>) 3485 0x9003 逃 (<CJK Ideograph>) 3486 0x900F 透 (<CJK Ideograph>) 3487 0x9419 鐙 (<CJK Ideograph>) 3488 0x9676 陶 (<CJK Ideograph>) 3489 0x982D 頭 (<CJK Ideograph>) 3490 0x9A30 騰 (<CJK Ideograph>) 3491 0x95D8 闘 (<CJK Ideograph>) 3492 0x50CD 働 (<CJK Ideograph>) 3493 0x52D5 動 (<CJK Ideograph>) 3494 0x540C 同 (<CJK Ideograph>) 3495 0x5802 堂 (<CJK Ideograph>) 3496 0x5C0E 導 (<CJK Ideograph>) 3497 0x61A7 憧 (<CJK Ideograph>) 3498 0x649E 撞 (<CJK Ideograph>) 3499 0x6D1E 洞 (<CJK Ideograph>) 3500 0x77B3 瞳 (<CJK Ideograph>) 3501 0x7AE5 童 (<CJK Ideograph>) 3502 0x80F4 胴 (<CJK Ideograph>) 3503 0x8404 萄 (<CJK Ideograph>) 3504 0x9053 道 (<CJK Ideograph>) 3505 0x9285 銅 (<CJK Ideograph>) 3506 0x5CE0 峠 (<CJK Ideograph>) 3507 0x9D07 鴇 (<CJK Ideograph>) 3508 0x533F 匿 (<CJK Ideograph>) 3509 0x5F97 得 (<CJK Ideograph>) 3510 0x5FB3 徳 (<CJK Ideograph>) 3511 0x6D9C 涜 (<CJK Ideograph>) 3512 0x7279 特 (<CJK Ideograph>) 3513 0x7763 督 (<CJK Ideograph>) 3514 0x79BF 禿 (<CJK Ideograph>) 3515 0x7BE4 篤 (<CJK Ideograph>) 3516 0x6BD2 毒 (<CJK Ideograph>) 3517 0x72EC 独 (<CJK Ideograph>) 3518 0x8AAD 読 (<CJK Ideograph>) 3519 0x6803 栃 (<CJK Ideograph>) 3520 0x6A61 橡 (<CJK Ideograph>) 3521 0x51F8 凸 (<CJK Ideograph>) 3522 0x7A81 突 (<CJK Ideograph>) 3523 0x6934 椴 (<CJK Ideograph>) 3524 0x5C4A 届 (<CJK Ideograph>) 3525 0x9CF6 鳶 (<CJK Ideograph>) 3526 0x82EB 苫 (<CJK Ideograph>) 3527 0x5BC5 寅 (<CJK Ideograph>) 3528 0x9149 酉 (<CJK Ideograph>) 3529 0x701E 瀞 (<CJK Ideograph>) 3530 0x5678 噸 (<CJK Ideograph>) 3531 0x5C6F 屯 (<CJK Ideograph>) 3532 0x60C7 惇 (<CJK Ideograph>) 3533 0x6566 敦 (<CJK Ideograph>) 3534 0x6C8C 沌 (<CJK Ideograph>) 3535 0x8C5A 豚 (<CJK Ideograph>) 3536 0x9041 遁 (<CJK Ideograph>) 3537 0x9813 頓 (<CJK Ideograph>) 3538 0x5451 呑 (<CJK Ideograph>) 3539 0x66C7 曇 (<CJK Ideograph>) 3540 0x920D 鈍 (<CJK Ideograph>) 3541 0x5948 奈 (<CJK Ideograph>) 3542 0x90A3 那 (<CJK Ideograph>) 3543 0x5185 内 (<CJK Ideograph>) 3544 0x4E4D 乍 (<CJK Ideograph>) 3545 0x51EA 凪 (<CJK Ideograph>) 3546 0x8599 薙 (<CJK Ideograph>) 3547 0x8B0E 謎 (<CJK Ideograph>) 3548 0x7058 灘 (<CJK Ideograph>) 3549 0x637A 捺 (<CJK Ideograph>) 3550 0x934B 鍋 (<CJK Ideograph>) 3551 0x6962 楢 (<CJK Ideograph>) 3552 0x99B4 馴 (<CJK Ideograph>) 3553 0x7E04 縄 (<CJK Ideograph>) 3554 0x7577 畷 (<CJK Ideograph>) 3555 0x5357 南 (<CJK Ideograph>) 3556 0x6960 楠 (<CJK Ideograph>) 3557 0x8EDF 軟 (<CJK Ideograph>) 3558 0x96E3 難 (<CJK Ideograph>) 3559 0x6C5D 汝 (<CJK Ideograph>) 3560 0x4E8C 二 (<CJK Ideograph>) 3561 0x5C3C 尼 (<CJK Ideograph>) 3562 0x5F10 弐 (<CJK Ideograph>) 3563 0x8FE9 迩 (<CJK Ideograph>) 3564 0x5302 匂 (<CJK Ideograph>) 3565 0x8CD1 賑 (<CJK Ideograph>) 3566 0x8089 肉 (<CJK Ideograph>) 3567 0x8679 虹 (<CJK Ideograph>) 3568 0x5EFF 廿 (<CJK Ideograph>) 3569 0x65E5 日 (<CJK Ideograph>) 3570 0x4E73 乳 (<CJK Ideograph>) 3571 0x5165 入 (<CJK Ideograph>) 3572 0x5982 如 (<CJK Ideograph>) 3573 0x5C3F 尿 (<CJK Ideograph>) 3574 0x97EE 韮 (<CJK Ideograph>) 3575 0x4EFB 任 (<CJK Ideograph>) 3576 0x598A 妊 (<CJK Ideograph>) 3577 0x5FCD 忍 (<CJK Ideograph>) 3578 0x8A8D 認 (<CJK Ideograph>) 3579 0x6FE1 濡 (<CJK Ideograph>) 3580 0x79B0 禰 (<CJK Ideograph>) 3581 0x7962 祢 (<CJK Ideograph>) 3582 0x5BE7 寧 (<CJK Ideograph>) 3583 0x8471 葱 (<CJK Ideograph>) 3584 0x732B 猫 (<CJK Ideograph>) 3585 0x71B1 熱 (<CJK Ideograph>) 3586 0x5E74 年 (<CJK Ideograph>) 3587 0x5FF5 念 (<CJK Ideograph>) 3588 0x637B 捻 (<CJK Ideograph>) 3589 0x649A 撚 (<CJK Ideograph>) 3590 0x71C3 燃 (<CJK Ideograph>) 3591 0x7C98 粘 (<CJK Ideograph>) 3592 0x4E43 乃 (<CJK Ideograph>) 3593 0x5EFC 廼 (<CJK Ideograph>) 3594 0x4E4B 之 (<CJK Ideograph>) 3595 0x57DC 埜 (<CJK Ideograph>) 3596 0x56A2 嚢 (<CJK Ideograph>) 3597 0x60A9 悩 (<CJK Ideograph>) 3598 0x6FC3 濃 (<CJK Ideograph>) 3599 0x7D0D 納 (<CJK Ideograph>) 3600 0x80FD 能 (<CJK Ideograph>) 3601 0x8133 脳 (<CJK Ideograph>) 3602 0x81BF 膿 (<CJK Ideograph>) 3603 0x8FB2 農 (<CJK Ideograph>) 3604 0x8997 覗 (<CJK Ideograph>) 3605 0x86A4 蚤 (<CJK Ideograph>) 3606 0x5DF4 巴 (<CJK Ideograph>) 3607 0x628A 把 (<CJK Ideograph>) 3608 0x64AD 播 (<CJK Ideograph>) 3609 0x8987 覇 (<CJK Ideograph>) 3610 0x6777 杷 (<CJK Ideograph>) 3611 0x6CE2 波 (<CJK Ideograph>) 3612 0x6D3E 派 (<CJK Ideograph>) 3613 0x7436 琶 (<CJK Ideograph>) 3614 0x7834 破 (<CJK Ideograph>) 3615 0x5A46 婆 (<CJK Ideograph>) 3616 0x7F75 罵 (<CJK Ideograph>) 3617 0x82AD 芭 (<CJK Ideograph>) 3618 0x99AC 馬 (<CJK Ideograph>) 3619 0x4FF3 俳 (<CJK Ideograph>) 3620 0x5EC3 廃 (<CJK Ideograph>) 3621 0x62DD 拝 (<CJK Ideograph>) 3622 0x6392 排 (<CJK Ideograph>) 3623 0x6557 敗 (<CJK Ideograph>) 3624 0x676F 杯 (<CJK Ideograph>) 3625 0x76C3 盃 (<CJK Ideograph>) 3626 0x724C 牌 (<CJK Ideograph>) 3627 0x80CC 背 (<CJK Ideograph>) 3628 0x80BA 肺 (<CJK Ideograph>) 3629 0x8F29 輩 (<CJK Ideograph>) 3630 0x914D 配 (<CJK Ideograph>) 3631 0x500D 倍 (<CJK Ideograph>) 3632 0x57F9 培 (<CJK Ideograph>) 3633 0x5A92 媒 (<CJK Ideograph>) 3634 0x6885 梅 (<CJK Ideograph>) 3635 0x6973 楳 (<CJK Ideograph>) 3636 0x7164 煤 (<CJK Ideograph>) 3637 0x72FD 狽 (<CJK Ideograph>) 3638 0x8CB7 買 (<CJK Ideograph>) 3639 0x58F2 売 (<CJK Ideograph>) 3640 0x8CE0 賠 (<CJK Ideograph>) 3641 0x966A 陪 (<CJK Ideograph>) 3642 0x9019 這 (<CJK Ideograph>) 3643 0x877F 蝿 (<CJK Ideograph>) 3644 0x79E4 秤 (<CJK Ideograph>) 3645 0x77E7 矧 (<CJK Ideograph>) 3646 0x8429 萩 (<CJK Ideograph>) 3647 0x4F2F 伯 (<CJK Ideograph>) 3648 0x5265 剥 (<CJK Ideograph>) 3649 0x535A 博 (<CJK Ideograph>) 3650 0x62CD 拍 (<CJK Ideograph>) 3651 0x67CF 柏 (<CJK Ideograph>) 3652 0x6CCA 泊 (<CJK Ideograph>) 3653 0x767D 白 (<CJK Ideograph>) 3654 0x7B94 箔 (<CJK Ideograph>) 3655 0x7C95 粕 (<CJK Ideograph>) 3656 0x8236 舶 (<CJK Ideograph>) 3657 0x8584 薄 (<CJK Ideograph>) 3658 0x8FEB 迫 (<CJK Ideograph>) 3659 0x66DD 曝 (<CJK Ideograph>) 3660 0x6F20 漠 (<CJK Ideograph>) 3661 0x7206 爆 (<CJK Ideograph>) 3662 0x7E1B 縛 (<CJK Ideograph>) 3663 0x83AB 莫 (<CJK Ideograph>) 3664 0x99C1 駁 (<CJK Ideograph>) 3665 0x9EA6 麦 (<CJK Ideograph>) 3666 0x51FD 函 (<CJK Ideograph>) 3667 0x7BB1 箱 (<CJK Ideograph>) 3668 0x7872 硲 (<CJK Ideograph>) 3669 0x7BB8 箸 (<CJK Ideograph>) 3670 0x8087 肇 (<CJK Ideograph>) 3671 0x7B48 筈 (<CJK Ideograph>) 3672 0x6AE8 櫨 (<CJK Ideograph>) 3673 0x5E61 幡 (<CJK Ideograph>) 3674 0x808C 肌 (<CJK Ideograph>) 3675 0x7551 畑 (<CJK Ideograph>) 3676 0x7560 畠 (<CJK Ideograph>) 3677 0x516B 八 (<CJK Ideograph>) 3678 0x9262 鉢 (<CJK Ideograph>) 3679 0x6E8C 溌 (<CJK Ideograph>) 3680 0x767A 発 (<CJK Ideograph>) 3681 0x9197 醗 (<CJK Ideograph>) 3682 0x9AEA 髪 (<CJK Ideograph>) 3683 0x4F10 伐 (<CJK Ideograph>) 3684 0x7F70 罰 (<CJK Ideograph>) 3685 0x629C 抜 (<CJK Ideograph>) 3686 0x7B4F 筏 (<CJK Ideograph>) 3687 0x95A5 閥 (<CJK Ideograph>) 3688 0x9CE9 鳩 (<CJK Ideograph>) 3689 0x567A 噺 (<CJK Ideograph>) 3690 0x5859 塙 (<CJK Ideograph>) 3691 0x86E4 蛤 (<CJK Ideograph>) 3692 0x96BC 隼 (<CJK Ideograph>) 3693 0x4F34 伴 (<CJK Ideograph>) 3694 0x5224 判 (<CJK Ideograph>) 3695 0x534A 半 (<CJK Ideograph>) 3696 0x53CD 反 (<CJK Ideograph>) 3697 0x53DB 叛 (<CJK Ideograph>) 3698 0x5E06 帆 (<CJK Ideograph>) 3699 0x642C 搬 (<CJK Ideograph>) 3700 0x6591 斑 (<CJK Ideograph>) 3701 0x677F 板 (<CJK Ideograph>) 3702 0x6C3E 氾 (<CJK Ideograph>) 3703 0x6C4E 汎 (<CJK Ideograph>) 3704 0x7248 版 (<CJK Ideograph>) 3705 0x72AF 犯 (<CJK Ideograph>) 3706 0x73ED 班 (<CJK Ideograph>) 3707 0x7554 畔 (<CJK Ideograph>) 3708 0x7E41 繁 (<CJK Ideograph>) 3709 0x822C 般 (<CJK Ideograph>) 3710 0x85E9 藩 (<CJK Ideograph>) 3711 0x8CA9 販 (<CJK Ideograph>) 3712 0x7BC4 範 (<CJK Ideograph>) 3713 0x91C6 釆 (<CJK Ideograph>) 3714 0x7169 煩 (<CJK Ideograph>) 3715 0x9812 頒 (<CJK Ideograph>) 3716 0x98EF 飯 (<CJK Ideograph>) 3717 0x633D 挽 (<CJK Ideograph>) 3718 0x6669 晩 (<CJK Ideograph>) 3719 0x756A 番 (<CJK Ideograph>) 3720 0x76E4 盤 (<CJK Ideograph>) 3721 0x78D0 磐 (<CJK Ideograph>) 3722 0x8543 蕃 (<CJK Ideograph>) 3723 0x86EE 蛮 (<CJK Ideograph>) 3724 0x532A 匪 (<CJK Ideograph>) 3725 0x5351 卑 (<CJK Ideograph>) 3726 0x5426 否 (<CJK Ideograph>) 3727 0x5983 妃 (<CJK Ideograph>) 3728 0x5E87 庇 (<CJK Ideograph>) 3729 0x5F7C 彼 (<CJK Ideograph>) 3730 0x60B2 悲 (<CJK Ideograph>) 3731 0x6249 扉 (<CJK Ideograph>) 3732 0x6279 批 (<CJK Ideograph>) 3733 0x62AB 披 (<CJK Ideograph>) 3734 0x6590 斐 (<CJK Ideograph>) 3735 0x6BD4 比 (<CJK Ideograph>) 3736 0x6CCC 泌 (<CJK Ideograph>) 3737 0x75B2 疲 (<CJK Ideograph>) 3738 0x76AE 皮 (<CJK Ideograph>) 3739 0x7891 碑 (<CJK Ideograph>) 3740 0x79D8 秘 (<CJK Ideograph>) 3741 0x7DCB 緋 (<CJK Ideograph>) 3742 0x7F77 罷 (<CJK Ideograph>) 3743 0x80A5 肥 (<CJK Ideograph>) 3744 0x88AB 被 (<CJK Ideograph>) 3745 0x8AB9 誹 (<CJK Ideograph>) 3746 0x8CBB 費 (<CJK Ideograph>) 3747 0x907F 避 (<CJK Ideograph>) 3748 0x975E 非 (<CJK Ideograph>) 3749 0x98DB 飛 (<CJK Ideograph>) 3750 0x6A0B 樋 (<CJK Ideograph>) 3751 0x7C38 簸 (<CJK Ideograph>) 3752 0x5099 備 (<CJK Ideograph>) 3753 0x5C3E 尾 (<CJK Ideograph>) 3754 0x5FAE 微 (<CJK Ideograph>) 3755 0x6787 枇 (<CJK Ideograph>) 3756 0x6BD8 毘 (<CJK Ideograph>) 3757 0x7435 琵 (<CJK Ideograph>) 3758 0x7709 眉 (<CJK Ideograph>) 3759 0x7F8E 美 (<CJK Ideograph>) 3760 0x9F3B 鼻 (<CJK Ideograph>) 3761 0x67CA 柊 (<CJK Ideograph>) 3762 0x7A17 稗 (<CJK Ideograph>) 3763 0x5339 匹 (<CJK Ideograph>) 3764 0x758B 疋 (<CJK Ideograph>) 3765 0x9AED 髭 (<CJK Ideograph>) 3766 0x5F66 彦 (<CJK Ideograph>) 3767 0x819D 膝 (<CJK Ideograph>) 3768 0x83F1 菱 (<CJK Ideograph>) 3769 0x8098 肘 (<CJK Ideograph>) 3770 0x5F3C 弼 (<CJK Ideograph>) 3771 0x5FC5 必 (<CJK Ideograph>) 3772 0x7562 畢 (<CJK Ideograph>) 3773 0x7B46 筆 (<CJK Ideograph>) 3774 0x903C 逼 (<CJK Ideograph>) 3775 0x6867 桧 (<CJK Ideograph>) 3776 0x59EB 姫 (<CJK Ideograph>) 3777 0x5A9B 媛 (<CJK Ideograph>) 3778 0x7D10 紐 (<CJK Ideograph>) 3779 0x767E 百 (<CJK Ideograph>) 3780 0x8B2C 謬 (<CJK Ideograph>) 3781 0x4FF5 俵 (<CJK Ideograph>) 3782 0x5F6A 彪 (<CJK Ideograph>) 3783 0x6A19 標 (<CJK Ideograph>) 3784 0x6C37 氷 (<CJK Ideograph>) 3785 0x6F02 漂 (<CJK Ideograph>) 3786 0x74E2 瓢 (<CJK Ideograph>) 3787 0x7968 票 (<CJK Ideograph>) 3788 0x8868 表 (<CJK Ideograph>) 3789 0x8A55 評 (<CJK Ideograph>) 3790 0x8C79 豹 (<CJK Ideograph>) 3791 0x5EDF 廟 (<CJK Ideograph>) 3792 0x63CF 描 (<CJK Ideograph>) 3793 0x75C5 病 (<CJK Ideograph>) 3794 0x79D2 秒 (<CJK Ideograph>) 3795 0x82D7 苗 (<CJK Ideograph>) 3796 0x9328 錨 (<CJK Ideograph>) 3797 0x92F2 鋲 (<CJK Ideograph>) 3798 0x849C 蒜 (<CJK Ideograph>) 3799 0x86ED 蛭 (<CJK Ideograph>) 3800 0x9C2D 鰭 (<CJK Ideograph>) 3801 0x54C1 品 (<CJK Ideograph>) 3802 0x5F6C 彬 (<CJK Ideograph>) 3803 0x658C 斌 (<CJK Ideograph>) 3804 0x6D5C 浜 (<CJK Ideograph>) 3805 0x7015 瀕 (<CJK Ideograph>) 3806 0x8CA7 貧 (<CJK Ideograph>) 3807 0x8CD3 賓 (<CJK Ideograph>) 3808 0x983B 頻 (<CJK Ideograph>) 3809 0x654F 敏 (<CJK Ideograph>) 3810 0x74F6 瓶 (<CJK Ideograph>) 3811 0x4E0D 不 (<CJK Ideograph>) 3812 0x4ED8 付 (<CJK Ideograph>) 3813 0x57E0 埠 (<CJK Ideograph>) 3814 0x592B 夫 (<CJK Ideograph>) 3815 0x5A66 婦 (<CJK Ideograph>) 3816 0x5BCC 富 (<CJK Ideograph>) 3817 0x51A8 冨 (<CJK Ideograph>) 3818 0x5E03 布 (<CJK Ideograph>) 3819 0x5E9C 府 (<CJK Ideograph>) 3820 0x6016 怖 (<CJK Ideograph>) 3821 0x6276 扶 (<CJK Ideograph>) 3822 0x6577 敷 (<CJK Ideograph>) 3823 0x65A7 斧 (<CJK Ideograph>) 3824 0x666E 普 (<CJK Ideograph>) 3825 0x6D6E 浮 (<CJK Ideograph>) 3826 0x7236 父 (<CJK Ideograph>) 3827 0x7B26 符 (<CJK Ideograph>) 3828 0x8150 腐 (<CJK Ideograph>) 3829 0x819A 膚 (<CJK Ideograph>) 3830 0x8299 芙 (<CJK Ideograph>) 3831 0x8B5C 譜 (<CJK Ideograph>) 3832 0x8CA0 負 (<CJK Ideograph>) 3833 0x8CE6 賦 (<CJK Ideograph>) 3834 0x8D74 赴 (<CJK Ideograph>) 3835 0x961C 阜 (<CJK Ideograph>) 3836 0x9644 附 (<CJK Ideograph>) 3837 0x4FAE 侮 (<CJK Ideograph>) 3838 0x64AB 撫 (<CJK Ideograph>) 3839 0x6B66 武 (<CJK Ideograph>) 3840 0x821E 舞 (<CJK Ideograph>) 3841 0x8461 葡 (<CJK Ideograph>) 3842 0x856A 蕪 (<CJK Ideograph>) 3843 0x90E8 部 (<CJK Ideograph>) 3844 0x5C01 封 (<CJK Ideograph>) 3845 0x6953 楓 (<CJK Ideograph>) 3846 0x98A8 風 (<CJK Ideograph>) 3847 0x847A 葺 (<CJK Ideograph>) 3848 0x8557 蕗 (<CJK Ideograph>) 3849 0x4F0F 伏 (<CJK Ideograph>) 3850 0x526F 副 (<CJK Ideograph>) 3851 0x5FA9 復 (<CJK Ideograph>) 3852 0x5E45 幅 (<CJK Ideograph>) 3853 0x670D 服 (<CJK Ideograph>) 3854 0x798F 福 (<CJK Ideograph>) 3855 0x8179 腹 (<CJK Ideograph>) 3856 0x8907 複 (<CJK Ideograph>) 3857 0x8986 覆 (<CJK Ideograph>) 3858 0x6DF5 淵 (<CJK Ideograph>) 3859 0x5F17 弗 (<CJK Ideograph>) 3860 0x6255 払 (<CJK Ideograph>) 3861 0x6CB8 沸 (<CJK Ideograph>) 3862 0x4ECF 仏 (<CJK Ideograph>) 3863 0x7269 物 (<CJK Ideograph>) 3864 0x9B92 鮒 (<CJK Ideograph>) 3865 0x5206 分 (<CJK Ideograph>) 3866 0x543B 吻 (<CJK Ideograph>) 3867 0x5674 噴 (<CJK Ideograph>) 3868 0x58B3 墳 (<CJK Ideograph>) 3869 0x61A4 憤 (<CJK Ideograph>) 3870 0x626E 扮 (<CJK Ideograph>) 3871 0x711A 焚 (<CJK Ideograph>) 3872 0x596E 奮 (<CJK Ideograph>) 3873 0x7C89 粉 (<CJK Ideograph>) 3874 0x7CDE 糞 (<CJK Ideograph>) 3875 0x7D1B 紛 (<CJK Ideograph>) 3876 0x96F0 雰 (<CJK Ideograph>) 3877 0x6587 文 (<CJK Ideograph>) 3878 0x805E 聞 (<CJK Ideograph>) 3879 0x4E19 丙 (<CJK Ideograph>) 3880 0x4F75 併 (<CJK Ideograph>) 3881 0x5175 兵 (<CJK Ideograph>) 3882 0x5840 塀 (<CJK Ideograph>) 3883 0x5E63 幣 (<CJK Ideograph>) 3884 0x5E73 平 (<CJK Ideograph>) 3885 0x5F0A 弊 (<CJK Ideograph>) 3886 0x67C4 柄 (<CJK Ideograph>) 3887 0x4E26 並 (<CJK Ideograph>) 3888 0x853D 蔽 (<CJK Ideograph>) 3889 0x9589 閉 (<CJK Ideograph>) 3890 0x965B 陛 (<CJK Ideograph>) 3891 0x7C73 米 (<CJK Ideograph>) 3892 0x9801 頁 (<CJK Ideograph>) 3893 0x50FB 僻 (<CJK Ideograph>) 3894 0x58C1 壁 (<CJK Ideograph>) 3895 0x7656 癖 (<CJK Ideograph>) 3896 0x78A7 碧 (<CJK Ideograph>) 3897 0x5225 別 (<CJK Ideograph>) 3898 0x77A5 瞥 (<CJK Ideograph>) 3899 0x8511 蔑 (<CJK Ideograph>) 3900 0x7B86 箆 (<CJK Ideograph>) 3901 0x504F 偏 (<CJK Ideograph>) 3902 0x5909 変 (<CJK Ideograph>) 3903 0x7247 片 (<CJK Ideograph>) 3904 0x7BC7 篇 (<CJK Ideograph>) 3905 0x7DE8 編 (<CJK Ideograph>) 3906 0x8FBA 辺 (<CJK Ideograph>) 3907 0x8FD4 返 (<CJK Ideograph>) 3908 0x904D 遍 (<CJK Ideograph>) 3909 0x4FBF 便 (<CJK Ideograph>) 3910 0x52C9 勉 (<CJK Ideograph>) 3911 0x5A29 娩 (<CJK Ideograph>) 3912 0x5F01 弁 (<CJK Ideograph>) 3913 0x97AD 鞭 (<CJK Ideograph>) 3914 0x4FDD 保 (<CJK Ideograph>) 3915 0x8217 舗 (<CJK Ideograph>) 3916 0x92EA 鋪 (<CJK Ideograph>) 3917 0x5703 圃 (<CJK Ideograph>) 3918 0x6355 捕 (<CJK Ideograph>) 3919 0x6B69 歩 (<CJK Ideograph>) 3920 0x752B 甫 (<CJK Ideograph>) 3921 0x88DC 補 (<CJK Ideograph>) 3922 0x8F14 輔 (<CJK Ideograph>) 3923 0x7A42 穂 (<CJK Ideograph>) 3924 0x52DF 募 (<CJK Ideograph>) 3925 0x5893 墓 (<CJK Ideograph>) 3926 0x6155 慕 (<CJK Ideograph>) 3927 0x620A 戊 (<CJK Ideograph>) 3928 0x66AE 暮 (<CJK Ideograph>) 3929 0x6BCD 母 (<CJK Ideograph>) 3930 0x7C3F 簿 (<CJK Ideograph>) 3931 0x83E9 菩 (<CJK Ideograph>) 3932 0x5023 倣 (<CJK Ideograph>) 3933 0x4FF8 俸 (<CJK Ideograph>) 3934 0x5305 包 (<CJK Ideograph>) 3935 0x5446 呆 (<CJK Ideograph>) 3936 0x5831 報 (<CJK Ideograph>) 3937 0x5949 奉 (<CJK Ideograph>) 3938 0x5B9D 宝 (<CJK Ideograph>) 3939 0x5CF0 峰 (<CJK Ideograph>) 3940 0x5CEF 峯 (<CJK Ideograph>) 3941 0x5D29 崩 (<CJK Ideograph>) 3942 0x5E96 庖 (<CJK Ideograph>) 3943 0x62B1 抱 (<CJK Ideograph>) 3944 0x6367 捧 (<CJK Ideograph>) 3945 0x653E 放 (<CJK Ideograph>) 3946 0x65B9 方 (<CJK Ideograph>) 3947 0x670B 朋 (<CJK Ideograph>) 3948 0x6CD5 法 (<CJK Ideograph>) 3949 0x6CE1 泡 (<CJK Ideograph>) 3950 0x70F9 烹 (<CJK Ideograph>) 3951 0x7832 砲 (<CJK Ideograph>) 3952 0x7E2B 縫 (<CJK Ideograph>) 3953 0x80DE 胞 (<CJK Ideograph>) 3954 0x82B3 芳 (<CJK Ideograph>) 3955 0x840C 萌 (<CJK Ideograph>) 3956 0x84EC 蓬 (<CJK Ideograph>) 3957 0x8702 蜂 (<CJK Ideograph>) 3958 0x8912 褒 (<CJK Ideograph>) 3959 0x8A2A 訪 (<CJK Ideograph>) 3960 0x8C4A 豊 (<CJK Ideograph>) 3961 0x90A6 邦 (<CJK Ideograph>) 3962 0x92D2 鋒 (<CJK Ideograph>) 3963 0x98FD 飽 (<CJK Ideograph>) 3964 0x9CF3 鳳 (<CJK Ideograph>) 3965 0x9D6C 鵬 (<CJK Ideograph>) 3966 0x4E4F 乏 (<CJK Ideograph>) 3967 0x4EA1 亡 (<CJK Ideograph>) 3968 0x508D 傍 (<CJK Ideograph>) 3969 0x5256 剖 (<CJK Ideograph>) 3970 0x574A 坊 (<CJK Ideograph>) 3971 0x59A8 妨 (<CJK Ideograph>) 3972 0x5E3D 帽 (<CJK Ideograph>) 3973 0x5FD8 忘 (<CJK Ideograph>) 3974 0x5FD9 忙 (<CJK Ideograph>) 3975 0x623F 房 (<CJK Ideograph>) 3976 0x66B4 暴 (<CJK Ideograph>) 3977 0x671B 望 (<CJK Ideograph>) 3978 0x67D0 某 (<CJK Ideograph>) 3979 0x68D2 棒 (<CJK Ideograph>) 3980 0x5192 冒 (<CJK Ideograph>) 3981 0x7D21 紡 (<CJK Ideograph>) 3982 0x80AA 肪 (<CJK Ideograph>) 3983 0x81A8 膨 (<CJK Ideograph>) 3984 0x8B00 謀 (<CJK Ideograph>) 3985 0x8C8C 貌 (<CJK Ideograph>) 3986 0x8CBF 貿 (<CJK Ideograph>) 3987 0x927E 鉾 (<CJK Ideograph>) 3988 0x9632 防 (<CJK Ideograph>) 3989 0x5420 吠 (<CJK Ideograph>) 3990 0x982C 頬 (<CJK Ideograph>) 3991 0x5317 北 (<CJK Ideograph>) 3992 0x50D5 僕 (<CJK Ideograph>) 3993 0x535C 卜 (<CJK Ideograph>) 3994 0x58A8 墨 (<CJK Ideograph>) 3995 0x64B2 撲 (<CJK Ideograph>) 3996 0x6734 朴 (<CJK Ideograph>) 3997 0x7267 牧 (<CJK Ideograph>) 3998 0x7766 睦 (<CJK Ideograph>) 3999 0x7A46 穆 (<CJK Ideograph>) 4000 0x91E6 釦 (<CJK Ideograph>) 4001 0x52C3 勃 (<CJK Ideograph>) 4002 0x6CA1 没 (<CJK Ideograph>) 4003 0x6B86 殆 (<CJK Ideograph>) 4004 0x5800 堀 (<CJK Ideograph>) 4005 0x5E4C 幌 (<CJK Ideograph>) 4006 0x5954 奔 (<CJK Ideograph>) 4007 0x672C 本 (<CJK Ideograph>) 4008 0x7FFB 翻 (<CJK Ideograph>) 4009 0x51E1 凡 (<CJK Ideograph>) 4010 0x76C6 盆 (<CJK Ideograph>) 4011 0x6469 摩 (<CJK Ideograph>) 4012 0x78E8 磨 (<CJK Ideograph>) 4013 0x9B54 魔 (<CJK Ideograph>) 4014 0x9EBB 麻 (<CJK Ideograph>) 4015 0x57CB 埋 (<CJK Ideograph>) 4016 0x59B9 妹 (<CJK Ideograph>) 4017 0x6627 昧 (<CJK Ideograph>) 4018 0x679A 枚 (<CJK Ideograph>) 4019 0x6BCE 毎 (<CJK Ideograph>) 4020 0x54E9 哩 (<CJK Ideograph>) 4021 0x69D9 槙 (<CJK Ideograph>) 4022 0x5E55 幕 (<CJK Ideograph>) 4023 0x819C 膜 (<CJK Ideograph>) 4024 0x6795 枕 (<CJK Ideograph>) 4025 0x9BAA 鮪 (<CJK Ideograph>) 4026 0x67FE 柾 (<CJK Ideograph>) 4027 0x9C52 鱒 (<CJK Ideograph>) 4028 0x685D 桝 (<CJK Ideograph>) 4029 0x4EA6 亦 (<CJK Ideograph>) 4030 0x4FE3 俣 (<CJK Ideograph>) 4031 0x53C8 又 (<CJK Ideograph>) 4032 0x62B9 抹 (<CJK Ideograph>) 4033 0x672B 末 (<CJK Ideograph>) 4034 0x6CAB 沫 (<CJK Ideograph>) 4035 0x8FC4 迄 (<CJK Ideograph>) 4036 0x4FAD 侭 (<CJK Ideograph>) 4037 0x7E6D 繭 (<CJK Ideograph>) 4038 0x9EBF 麿 (<CJK Ideograph>) 4039 0x4E07 万 (<CJK Ideograph>) 4040 0x6162 慢 (<CJK Ideograph>) 4041 0x6E80 満 (<CJK Ideograph>) 4042 0x6F2B 漫 (<CJK Ideograph>) 4043 0x8513 蔓 (<CJK Ideograph>) 4044 0x5473 味 (<CJK Ideograph>) 4045 0x672A 未 (<CJK Ideograph>) 4046 0x9B45 魅 (<CJK Ideograph>) 4047 0x5DF3 巳 (<CJK Ideograph>) 4048 0x7B95 箕 (<CJK Ideograph>) 4049 0x5CAC 岬 (<CJK Ideograph>) 4050 0x5BC6 密 (<CJK Ideograph>) 4051 0x871C 蜜 (<CJK Ideograph>) 4052 0x6E4A 湊 (<CJK Ideograph>) 4053 0x84D1 蓑 (<CJK Ideograph>) 4054 0x7A14 稔 (<CJK Ideograph>) 4055 0x8108 脈 (<CJK Ideograph>) 4056 0x5999 妙 (<CJK Ideograph>) 4057 0x7C8D 粍 (<CJK Ideograph>) 4058 0x6C11 民 (<CJK Ideograph>) 4059 0x7720 眠 (<CJK Ideograph>) 4060 0x52D9 務 (<CJK Ideograph>) 4061 0x5922 夢 (<CJK Ideograph>) 4062 0x7121 無 (<CJK Ideograph>) 4063 0x725F 牟 (<CJK Ideograph>) 4064 0x77DB 矛 (<CJK Ideograph>) 4065 0x9727 霧 (<CJK Ideograph>) 4066 0x9D61 鵡 (<CJK Ideograph>) 4067 0x690B 椋 (<CJK Ideograph>) 4068 0x5A7F 婿 (<CJK Ideograph>) 4069 0x5A18 娘 (<CJK Ideograph>) 4070 0x51A5 冥 (<CJK Ideograph>) 4071 0x540D 名 (<CJK Ideograph>) 4072 0x547D 命 (<CJK Ideograph>) 4073 0x660E 明 (<CJK Ideograph>) 4074 0x76DF 盟 (<CJK Ideograph>) 4075 0x8FF7 迷 (<CJK Ideograph>) 4076 0x9298 銘 (<CJK Ideograph>) 4077 0x9CF4 鳴 (<CJK Ideograph>) 4078 0x59EA 姪 (<CJK Ideograph>) 4079 0x725D 牝 (<CJK Ideograph>) 4080 0x6EC5 滅 (<CJK Ideograph>) 4081 0x514D 免 (<CJK Ideograph>) 4082 0x68C9 棉 (<CJK Ideograph>) 4083 0x7DBF 綿 (<CJK Ideograph>) 4084 0x7DEC 緬 (<CJK Ideograph>) 4085 0x9762 面 (<CJK Ideograph>) 4086 0x9EBA 麺 (<CJK Ideograph>) 4087 0x6478 摸 (<CJK Ideograph>) 4088 0x6A21 模 (<CJK Ideograph>) 4089 0x8302 茂 (<CJK Ideograph>) 4090 0x5984 妄 (<CJK Ideograph>) 4091 0x5B5F 孟 (<CJK Ideograph>) 4092 0x6BDB 毛 (<CJK Ideograph>) 4093 0x731B 猛 (<CJK Ideograph>) 4094 0x76F2 盲 (<CJK Ideograph>) 4095 0x7DB2 網 (<CJK Ideograph>) 4096 0x8017 耗 (<CJK Ideograph>) 4097 0x8499 蒙 (<CJK Ideograph>) 4098 0x5132 儲 (<CJK Ideograph>) 4099 0x6728 木 (<CJK Ideograph>) 4100 0x9ED9 黙 (<CJK Ideograph>) 4101 0x76EE 目 (<CJK Ideograph>) 4102 0x6762 杢 (<CJK Ideograph>) 4103 0x52FF 勿 (<CJK Ideograph>) 4104 0x9905 餅 (<CJK Ideograph>) 4105 0x5C24 尤 (<CJK Ideograph>) 4106 0x623B 戻 (<CJK Ideograph>) 4107 0x7C7E 籾 (<CJK Ideograph>) 4108 0x8CB0 貰 (<CJK Ideograph>) 4109 0x554F 問 (<CJK Ideograph>) 4110 0x60B6 悶 (<CJK Ideograph>) 4111 0x7D0B 紋 (<CJK Ideograph>) 4112 0x9580 門 (<CJK Ideograph>) 4113 0x5301 匁 (<CJK Ideograph>) 4114 0x4E5F 也 (<CJK Ideograph>) 4115 0x51B6 冶 (<CJK Ideograph>) 4116 0x591C 夜 (<CJK Ideograph>) 4117 0x723A 爺 (<CJK Ideograph>) 4118 0x8036 耶 (<CJK Ideograph>) 4119 0x91CE 野 (<CJK Ideograph>) 4120 0x5F25 弥 (<CJK Ideograph>) 4121 0x77E2 矢 (<CJK Ideograph>) 4122 0x5384 厄 (<CJK Ideograph>) 4123 0x5F79 役 (<CJK Ideograph>) 4124 0x7D04 約 (<CJK Ideograph>) 4125 0x85AC 薬 (<CJK Ideograph>) 4126 0x8A33 訳 (<CJK Ideograph>) 4127 0x8E8D 躍 (<CJK Ideograph>) 4128 0x9756 靖 (<CJK Ideograph>) 4129 0x67F3 柳 (<CJK Ideograph>) 4130 0x85AE 薮 (<CJK Ideograph>) 4131 0x9453 鑓 (<CJK Ideograph>) 4132 0x6109 愉 (<CJK Ideograph>) 4133 0x6108 愈 (<CJK Ideograph>) 4134 0x6CB9 油 (<CJK Ideograph>) 4135 0x7652 癒 (<CJK Ideograph>) 4136 0x8AED 諭 (<CJK Ideograph>) 4137 0x8F38 輸 (<CJK Ideograph>) 4138 0x552F 唯 (<CJK Ideograph>) 4139 0x4F51 佑 (<CJK Ideograph>) 4140 0x512A 優 (<CJK Ideograph>) 4141 0x52C7 勇 (<CJK Ideograph>) 4142 0x53CB 友 (<CJK Ideograph>) 4143 0x5BA5 宥 (<CJK Ideograph>) 4144 0x5E7D 幽 (<CJK Ideograph>) 4145 0x60A0 悠 (<CJK Ideograph>) 4146 0x6182 憂 (<CJK Ideograph>) 4147 0x63D6 揖 (<CJK Ideograph>) 4148 0x6709 有 (<CJK Ideograph>) 4149 0x67DA 柚 (<CJK Ideograph>) 4150 0x6E67 湧 (<CJK Ideograph>) 4151 0x6D8C 涌 (<CJK Ideograph>) 4152 0x7336 猶 (<CJK Ideograph>) 4153 0x7337 猷 (<CJK Ideograph>) 4154 0x7531 由 (<CJK Ideograph>) 4155 0x7950 祐 (<CJK Ideograph>) 4156 0x88D5 裕 (<CJK Ideograph>) 4157 0x8A98 誘 (<CJK Ideograph>) 4158 0x904A 遊 (<CJK Ideograph>) 4159 0x9091 邑 (<CJK Ideograph>) 4160 0x90F5 郵 (<CJK Ideograph>) 4161 0x96C4 雄 (<CJK Ideograph>) 4162 0x878D 融 (<CJK Ideograph>) 4163 0x5915 夕 (<CJK Ideograph>) 4164 0x4E88 予 (<CJK Ideograph>) 4165 0x4F59 余 (<CJK Ideograph>) 4166 0x4E0E 与 (<CJK Ideograph>) 4167 0x8A89 誉 (<CJK Ideograph>) 4168 0x8F3F 輿 (<CJK Ideograph>) 4169 0x9810 預 (<CJK Ideograph>) 4170 0x50AD 傭 (<CJK Ideograph>) 4171 0x5E7C 幼 (<CJK Ideograph>) 4172 0x5996 妖 (<CJK Ideograph>) 4173 0x5BB9 容 (<CJK Ideograph>) 4174 0x5EB8 庸 (<CJK Ideograph>) 4175 0x63DA 揚 (<CJK Ideograph>) 4176 0x63FA 揺 (<CJK Ideograph>) 4177 0x64C1 擁 (<CJK Ideograph>) 4178 0x66DC 曜 (<CJK Ideograph>) 4179 0x694A 楊 (<CJK Ideograph>) 4180 0x69D8 様 (<CJK Ideograph>) 4181 0x6D0B 洋 (<CJK Ideograph>) 4182 0x6EB6 溶 (<CJK Ideograph>) 4183 0x7194 熔 (<CJK Ideograph>) 4184 0x7528 用 (<CJK Ideograph>) 4185 0x7AAF 窯 (<CJK Ideograph>) 4186 0x7F8A 羊 (<CJK Ideograph>) 4187 0x8000 耀 (<CJK Ideograph>) 4188 0x8449 葉 (<CJK Ideograph>) 4189 0x84C9 蓉 (<CJK Ideograph>) 4190 0x8981 要 (<CJK Ideograph>) 4191 0x8B21 謡 (<CJK Ideograph>) 4192 0x8E0A 踊 (<CJK Ideograph>) 4193 0x9065 遥 (<CJK Ideograph>) 4194 0x967D 陽 (<CJK Ideograph>) 4195 0x990A 養 (<CJK Ideograph>) 4196 0x617E 慾 (<CJK Ideograph>) 4197 0x6291 抑 (<CJK Ideograph>) 4198 0x6B32 欲 (<CJK Ideograph>) 4199 0x6C83 沃 (<CJK Ideograph>) 4200 0x6D74 浴 (<CJK Ideograph>) 4201 0x7FCC 翌 (<CJK Ideograph>) 4202 0x7FFC 翼 (<CJK Ideograph>) 4203 0x6DC0 淀 (<CJK Ideograph>) 4204 0x7F85 羅 (<CJK Ideograph>) 4205 0x87BA 螺 (<CJK Ideograph>) 4206 0x88F8 裸 (<CJK Ideograph>) 4207 0x6765 来 (<CJK Ideograph>) 4208 0x83B1 莱 (<CJK Ideograph>) 4209 0x983C 頼 (<CJK Ideograph>) 4210 0x96F7 雷 (<CJK Ideograph>) 4211 0x6D1B 洛 (<CJK Ideograph>) 4212 0x7D61 絡 (<CJK Ideograph>) 4213 0x843D 落 (<CJK Ideograph>) 4214 0x916A 酪 (<CJK Ideograph>) 4215 0x4E71 乱 (<CJK Ideograph>) 4216 0x5375 卵 (<CJK Ideograph>) 4217 0x5D50 嵐 (<CJK Ideograph>) 4218 0x6B04 欄 (<CJK Ideograph>) 4219 0x6FEB 濫 (<CJK Ideograph>) 4220 0x85CD 藍 (<CJK Ideograph>) 4221 0x862D 蘭 (<CJK Ideograph>) 4222 0x89A7 覧 (<CJK Ideograph>) 4223 0x5229 利 (<CJK Ideograph>) 4224 0x540F 吏 (<CJK Ideograph>) 4225 0x5C65 履 (<CJK Ideograph>) 4226 0x674E 李 (<CJK Ideograph>) 4227 0x68A8 梨 (<CJK Ideograph>) 4228 0x7406 理 (<CJK Ideograph>) 4229 0x7483 璃 (<CJK Ideograph>) 4230 0x75E2 痢 (<CJK Ideograph>) 4231 0x88CF 裏 (<CJK Ideograph>) 4232 0x88E1 裡 (<CJK Ideograph>) 4233 0x91CC 里 (<CJK Ideograph>) 4234 0x96E2 離 (<CJK Ideograph>) 4235 0x9678 陸 (<CJK Ideograph>) 4236 0x5F8B 律 (<CJK Ideograph>) 4237 0x7387 率 (<CJK Ideograph>) 4238 0x7ACB 立 (<CJK Ideograph>) 4239 0x844E 葎 (<CJK Ideograph>) 4240 0x63A0 掠 (<CJK Ideograph>) 4241 0x7565 略 (<CJK Ideograph>) 4242 0x5289 劉 (<CJK Ideograph>) 4243 0x6D41 流 (<CJK Ideograph>) 4244 0x6E9C 溜 (<CJK Ideograph>) 4245 0x7409 琉 (<CJK Ideograph>) 4246 0x7559 留 (<CJK Ideograph>) 4247 0x786B 硫 (<CJK Ideograph>) 4248 0x7C92 粒 (<CJK Ideograph>) 4249 0x9686 隆 (<CJK Ideograph>) 4250 0x7ADC 竜 (<CJK Ideograph>) 4251 0x9F8D 龍 (<CJK Ideograph>) 4252 0x4FB6 侶 (<CJK Ideograph>) 4253 0x616E 慮 (<CJK Ideograph>) 4254 0x65C5 旅 (<CJK Ideograph>) 4255 0x865C 虜 (<CJK Ideograph>) 4256 0x4E86 了 (<CJK Ideograph>) 4257 0x4EAE 亮 (<CJK Ideograph>) 4258 0x50DA 僚 (<CJK Ideograph>) 4259 0x4E21 両 (<CJK Ideograph>) 4260 0x51CC 凌 (<CJK Ideograph>) 4261 0x5BEE 寮 (<CJK Ideograph>) 4262 0x6599 料 (<CJK Ideograph>) 4263 0x6881 梁 (<CJK Ideograph>) 4264 0x6DBC 涼 (<CJK Ideograph>) 4265 0x731F 猟 (<CJK Ideograph>) 4266 0x7642 療 (<CJK Ideograph>) 4267 0x77AD 瞭 (<CJK Ideograph>) 4268 0x7A1C 稜 (<CJK Ideograph>) 4269 0x7CE7 糧 (<CJK Ideograph>) 4270 0x826F 良 (<CJK Ideograph>) 4271 0x8AD2 諒 (<CJK Ideograph>) 4272 0x907C 遼 (<CJK Ideograph>) 4273 0x91CF 量 (<CJK Ideograph>) 4274 0x9675 陵 (<CJK Ideograph>) 4275 0x9818 領 (<CJK Ideograph>) 4276 0x529B 力 (<CJK Ideograph>) 4277 0x7DD1 緑 (<CJK Ideograph>) 4278 0x502B 倫 (<CJK Ideograph>) 4279 0x5398 厘 (<CJK Ideograph>) 4280 0x6797 林 (<CJK Ideograph>) 4281 0x6DCB 淋 (<CJK Ideograph>) 4282 0x71D0 燐 (<CJK Ideograph>) 4283 0x7433 琳 (<CJK Ideograph>) 4284 0x81E8 臨 (<CJK Ideograph>) 4285 0x8F2A 輪 (<CJK Ideograph>) 4286 0x96A3 隣 (<CJK Ideograph>) 4287 0x9C57 鱗 (<CJK Ideograph>) 4288 0x9E9F 麟 (<CJK Ideograph>) 4289 0x7460 瑠 (<CJK Ideograph>) 4290 0x5841 塁 (<CJK Ideograph>) 4291 0x6D99 涙 (<CJK Ideograph>) 4292 0x7D2F 累 (<CJK Ideograph>) 4293 0x985E 類 (<CJK Ideograph>) 4294 0x4EE4 令 (<CJK Ideograph>) 4295 0x4F36 伶 (<CJK Ideograph>) 4296 0x4F8B 例 (<CJK Ideograph>) 4297 0x51B7 冷 (<CJK Ideograph>) 4298 0x52B1 励 (<CJK Ideograph>) 4299 0x5DBA 嶺 (<CJK Ideograph>) 4300 0x601C 怜 (<CJK Ideograph>) 4301 0x73B2 玲 (<CJK Ideograph>) 4302 0x793C 礼 (<CJK Ideograph>) 4303 0x82D3 苓 (<CJK Ideograph>) 4304 0x9234 鈴 (<CJK Ideograph>) 4305 0x96B7 隷 (<CJK Ideograph>) 4306 0x96F6 零 (<CJK Ideograph>) 4307 0x970A 霊 (<CJK Ideograph>) 4308 0x9E97 麗 (<CJK Ideograph>) 4309 0x9F62 齢 (<CJK Ideograph>) 4310 0x66A6 暦 (<CJK Ideograph>) 4311 0x6B74 歴 (<CJK Ideograph>) 4312 0x5217 列 (<CJK Ideograph>) 4313 0x52A3 劣 (<CJK Ideograph>) 4314 0x70C8 烈 (<CJK Ideograph>) 4315 0x88C2 裂 (<CJK Ideograph>) 4316 0x5EC9 廉 (<CJK Ideograph>) 4317 0x604B 恋 (<CJK Ideograph>) 4318 0x6190 憐 (<CJK Ideograph>) 4319 0x6F23 漣 (<CJK Ideograph>) 4320 0x7149 煉 (<CJK Ideograph>) 4321 0x7C3E 簾 (<CJK Ideograph>) 4322 0x7DF4 練 (<CJK Ideograph>) 4323 0x806F 聯 (<CJK Ideograph>) 4324 0x84EE 蓮 (<CJK Ideograph>) 4325 0x9023 連 (<CJK Ideograph>) 4326 0x932C 錬 (<CJK Ideograph>) 4327 0x5442 呂 (<CJK Ideograph>) 4328 0x9B6F 魯 (<CJK Ideograph>) 4329 0x6AD3 櫓 (<CJK Ideograph>) 4330 0x7089 炉 (<CJK Ideograph>) 4331 0x8CC2 賂 (<CJK Ideograph>) 4332 0x8DEF 路 (<CJK Ideograph>) 4333 0x9732 露 (<CJK Ideograph>) 4334 0x52B4 労 (<CJK Ideograph>) 4335 0x5A41 婁 (<CJK Ideograph>) 4336 0x5ECA 廊 (<CJK Ideograph>) 4337 0x5F04 弄 (<CJK Ideograph>) 4338 0x6717 朗 (<CJK Ideograph>) 4339 0x697C 楼 (<CJK Ideograph>) 4340 0x6994 榔 (<CJK Ideograph>) 4341 0x6D6A 浪 (<CJK Ideograph>) 4342 0x6F0F 漏 (<CJK Ideograph>) 4343 0x7262 牢 (<CJK Ideograph>) 4344 0x72FC 狼 (<CJK Ideograph>) 4345 0x7BED 篭 (<CJK Ideograph>) 4346 0x8001 老 (<CJK Ideograph>) 4347 0x807E 聾 (<CJK Ideograph>) 4348 0x874B 蝋 (<CJK Ideograph>) 4349 0x90CE 郎 (<CJK Ideograph>) 4350 0x516D 六 (<CJK Ideograph>) 4351 0x9E93 麓 (<CJK Ideograph>) 4352 0x7984 禄 (<CJK Ideograph>) 4353 0x808B 肋 (<CJK Ideograph>) 4354 0x9332 録 (<CJK Ideograph>) 4355 0x8AD6 論 (<CJK Ideograph>) 4356 0x502D 倭 (<CJK Ideograph>) 4357 0x548C 和 (<CJK Ideograph>) 4358 0x8A71 話 (<CJK Ideograph>) 4359 0x6B6A 歪 (<CJK Ideograph>) 4360 0x8CC4 賄 (<CJK Ideograph>) 4361 0x8107 脇 (<CJK Ideograph>) 4362 0x60D1 惑 (<CJK Ideograph>) 4363 0x67A0 枠 (<CJK Ideograph>) 4364 0x9DF2 鷲 (<CJK Ideograph>) 4365 0x4E99 亙 (<CJK Ideograph>) 4366 0x4E98 亘 (<CJK Ideograph>) 4367 0x9C10 鰐 (<CJK Ideograph>) 4368 0x8A6B 詫 (<CJK Ideograph>) 4369 0x85C1 藁 (<CJK Ideograph>) 4370 0x8568 蕨 (<CJK Ideograph>) 4371 0x6900 椀 (<CJK Ideograph>) 4372 0x6E7E 湾 (<CJK Ideograph>) 4373 0x7897 碗 (<CJK Ideograph>) 4374 0x8155 腕 (<CJK Ideograph>) 4418 0x5F0C 弌 (<CJK Ideograph>) 4419 0x4E10 丐 (<CJK Ideograph>) 4420 0x4E15 丕 (<CJK Ideograph>) 4421 0x4E2A 个 (<CJK Ideograph>) 4422 0x4E31 丱 (<CJK Ideograph>) 4423 0x4E36 丶 (<CJK Ideograph>) 4424 0x4E3C 丼 (<CJK Ideograph>) 4425 0x4E3F 丿 (<CJK Ideograph>) 4426 0x4E42 乂 (<CJK Ideograph>) 4427 0x4E56 乖 (<CJK Ideograph>) 4428 0x4E58 乘 (<CJK Ideograph>) 4429 0x4E82 亂 (<CJK Ideograph>) 4430 0x4E85 亅 (<CJK Ideograph>) 4431 0x8C6B 豫 (<CJK Ideograph>) 4432 0x4E8A 亊 (<CJK Ideograph>) 4433 0x8212 舒 (<CJK Ideograph>) 4434 0x5F0D 弍 (<CJK Ideograph>) 4435 0x4E8E 于 (<CJK Ideograph>) 4436 0x4E9E 亞 (<CJK Ideograph>) 4437 0x4E9F 亟 (<CJK Ideograph>) 4438 0x4EA0 亠 (<CJK Ideograph>) 4439 0x4EA2 亢 (<CJK Ideograph>) 4440 0x4EB0 亰 (<CJK Ideograph>) 4441 0x4EB3 亳 (<CJK Ideograph>) 4442 0x4EB6 亶 (<CJK Ideograph>) 4443 0x4ECE 从 (<CJK Ideograph>) 4444 0x4ECD 仍 (<CJK Ideograph>) 4445 0x4EC4 仄 (<CJK Ideograph>) 4446 0x4EC6 仆 (<CJK Ideograph>) 4447 0x4EC2 仂 (<CJK Ideograph>) 4448 0x4ED7 仗 (<CJK Ideograph>) 4449 0x4EDE 仞 (<CJK Ideograph>) 4450 0x4EED 仭 (<CJK Ideograph>) 4451 0x4EDF 仟 (<CJK Ideograph>) 4452 0x4EF7 价 (<CJK Ideograph>) 4453 0x4F09 伉 (<CJK Ideograph>) 4454 0x4F5A 佚 (<CJK Ideograph>) 4455 0x4F30 估 (<CJK Ideograph>) 4456 0x4F5B 佛 (<CJK Ideograph>) 4457 0x4F5D 佝 (<CJK Ideograph>) 4458 0x4F57 佗 (<CJK Ideograph>) 4459 0x4F47 佇 (<CJK Ideograph>) 4460 0x4F76 佶 (<CJK Ideograph>) 4461 0x4F88 侈 (<CJK Ideograph>) 4462 0x4F8F 侏 (<CJK Ideograph>) 4463 0x4F98 侘 (<CJK Ideograph>) 4464 0x4F7B 佻 (<CJK Ideograph>) 4465 0x4F69 佩 (<CJK Ideograph>) 4466 0x4F70 佰 (<CJK Ideograph>) 4467 0x4F91 侑 (<CJK Ideograph>) 4468 0x4F6F 佯 (<CJK Ideograph>) 4469 0x4F86 來 (<CJK Ideograph>) 4470 0x4F96 侖 (<CJK Ideograph>) 4471 0x5118 儘 (<CJK Ideograph>) 4472 0x4FD4 俔 (<CJK Ideograph>) 4473 0x4FDF 俟 (<CJK Ideograph>) 4474 0x4FCE 俎 (<CJK Ideograph>) 4475 0x4FD8 俘 (<CJK Ideograph>) 4476 0x4FDB 俛 (<CJK Ideograph>) 4477 0x4FD1 俑 (<CJK Ideograph>) 4478 0x4FDA 俚 (<CJK Ideograph>) 4479 0x4FD0 俐 (<CJK Ideograph>) 4480 0x4FE4 俤 (<CJK Ideograph>) 4481 0x4FE5 俥 (<CJK Ideograph>) 4482 0x501A 倚 (<CJK Ideograph>) 4483 0x5028 倨 (<CJK Ideograph>) 4484 0x5014 倔 (<CJK Ideograph>) 4485 0x502A 倪 (<CJK Ideograph>) 4486 0x5025 倥 (<CJK Ideograph>) 4487 0x5005 倅 (<CJK Ideograph>) 4488 0x4F1C 伜 (<CJK Ideograph>) 4489 0x4FF6 俶 (<CJK Ideograph>) 4490 0x5021 倡 (<CJK Ideograph>) 4491 0x5029 倩 (<CJK Ideograph>) 4492 0x502C 倬 (<CJK Ideograph>) 4493 0x4FFE 俾 (<CJK Ideograph>) 4494 0x4FEF 俯 (<CJK Ideograph>) 4495 0x5011 們 (<CJK Ideograph>) 4496 0x5006 倆 (<CJK Ideograph>) 4497 0x5043 偃 (<CJK Ideograph>) 4498 0x5047 假 (<CJK Ideograph>) 4499 0x6703 會 (<CJK Ideograph>) 4500 0x5055 偕 (<CJK Ideograph>) 4501 0x5050 偐 (<CJK Ideograph>) 4502 0x5048 偈 (<CJK Ideograph>) 4503 0x505A 做 (<CJK Ideograph>) 4504 0x5056 偖 (<CJK Ideograph>) 4505 0x506C 偬 (<CJK Ideograph>) 4506 0x5078 偸 (<CJK Ideograph>) 4507 0x5080 傀 (<CJK Ideograph>) 4508 0x509A 傚 (<CJK Ideograph>) 4509 0x5085 傅 (<CJK Ideograph>) 4510 0x50B4 傴 (<CJK Ideograph>) 4511 0x50B2 傲 (<CJK Ideograph>) 4512 0x50C9 僉 (<CJK Ideograph>) 4513 0x50CA 僊 (<CJK Ideograph>) 4514 0x50B3 傳 (<CJK Ideograph>) 4515 0x50C2 僂 (<CJK Ideograph>) 4516 0x50D6 僖 (<CJK Ideograph>) 4517 0x50DE 僞 (<CJK Ideograph>) 4518 0x50E5 僥 (<CJK Ideograph>) 4519 0x50ED 僭 (<CJK Ideograph>) 4520 0x50E3 僣 (<CJK Ideograph>) 4521 0x50EE 僮 (<CJK Ideograph>) 4522 0x50F9 價 (<CJK Ideograph>) 4523 0x50F5 僵 (<CJK Ideograph>) 4524 0x5109 儉 (<CJK Ideograph>) 4525 0x5101 儁 (<CJK Ideograph>) 4526 0x5102 儂 (<CJK Ideograph>) 4527 0x5116 儖 (<CJK Ideograph>) 4528 0x5115 儕 (<CJK Ideograph>) 4529 0x5114 儔 (<CJK Ideograph>) 4530 0x511A 儚 (<CJK Ideograph>) 4531 0x5121 儡 (<CJK Ideograph>) 4532 0x513A 儺 (<CJK Ideograph>) 4533 0x5137 儷 (<CJK Ideograph>) 4534 0x513C 儼 (<CJK Ideograph>) 4535 0x513B 儻 (<CJK Ideograph>) 4536 0x513F 儿 (<CJK Ideograph>) 4537 0x5140 兀 (<CJK Ideograph>) 4538 0x5152 兒 (<CJK Ideograph>) 4539 0x514C 兌 (<CJK Ideograph>) 4540 0x5154 兔 (<CJK Ideograph>) 4541 0x5162 兢 (<CJK Ideograph>) 4542 0x7AF8 竸 (<CJK Ideograph>) 4543 0x5169 兩 (<CJK Ideograph>) 4544 0x516A 兪 (<CJK Ideograph>) 4545 0x516E 兮 (<CJK Ideograph>) 4546 0x5180 冀 (<CJK Ideograph>) 4547 0x5182 冂 (<CJK Ideograph>) 4548 0x56D8 囘 (<CJK Ideograph>) 4549 0x518C 册 (<CJK Ideograph>) 4550 0x5189 冉 (<CJK Ideograph>) 4551 0x518F 冏 (<CJK Ideograph>) 4552 0x5191 冑 (<CJK Ideograph>) 4553 0x5193 冓 (<CJK Ideograph>) 4554 0x5195 冕 (<CJK Ideograph>) 4555 0x5196 冖 (<CJK Ideograph>) 4556 0x51A4 冤 (<CJK Ideograph>) 4557 0x51A6 冦 (<CJK Ideograph>) 4558 0x51A2 冢 (<CJK Ideograph>) 4559 0x51A9 冩 (<CJK Ideograph>) 4560 0x51AA 冪 (<CJK Ideograph>) 4561 0x51AB 冫 (<CJK Ideograph>) 4562 0x51B3 决 (<CJK Ideograph>) 4563 0x51B1 冱 (<CJK Ideograph>) 4564 0x51B2 冲 (<CJK Ideograph>) 4565 0x51B0 冰 (<CJK Ideograph>) 4566 0x51B5 况 (<CJK Ideograph>) 4567 0x51BD 冽 (<CJK Ideograph>) 4568 0x51C5 凅 (<CJK Ideograph>) 4569 0x51C9 凉 (<CJK Ideograph>) 4570 0x51DB 凛 (<CJK Ideograph>) 4571 0x51E0 几 (<CJK Ideograph>) 4572 0x8655 處 (<CJK Ideograph>) 4573 0x51E9 凩 (<CJK Ideograph>) 4574 0x51ED 凭 (<CJK Ideograph>) 4575 0x51F0 凰 (<CJK Ideograph>) 4576 0x51F5 凵 (<CJK Ideograph>) 4577 0x51FE 凾 (<CJK Ideograph>) 4578 0x5204 刄 (<CJK Ideograph>) 4579 0x520B 刋 (<CJK Ideograph>) 4580 0x5214 刔 (<CJK Ideograph>) 4581 0x520E 刎 (<CJK Ideograph>) 4582 0x5227 刧 (<CJK Ideograph>) 4583 0x522A 刪 (<CJK Ideograph>) 4584 0x522E 刮 (<CJK Ideograph>) 4585 0x5233 刳 (<CJK Ideograph>) 4586 0x5239 刹 (<CJK Ideograph>) 4587 0x524F 剏 (<CJK Ideograph>) 4588 0x5244 剄 (<CJK Ideograph>) 4589 0x524B 剋 (<CJK Ideograph>) 4590 0x524C 剌 (<CJK Ideograph>) 4591 0x525E 剞 (<CJK Ideograph>) 4592 0x5254 剔 (<CJK Ideograph>) 4593 0x526A 剪 (<CJK Ideograph>) 4594 0x5274 剴 (<CJK Ideograph>) 4595 0x5269 剩 (<CJK Ideograph>) 4596 0x5273 剳 (<CJK Ideograph>) 4597 0x527F 剿 (<CJK Ideograph>) 4598 0x527D 剽 (<CJK Ideograph>) 4599 0x528D 劍 (<CJK Ideograph>) 4600 0x5294 劔 (<CJK Ideograph>) 4601 0x5292 劒 (<CJK Ideograph>) 4602 0x5271 剱 (<CJK Ideograph>) 4603 0x5288 劈 (<CJK Ideograph>) 4604 0x5291 劑 (<CJK Ideograph>) 4605 0x8FA8 辨 (<CJK Ideograph>) 4606 0x8FA7 辧 (<CJK Ideograph>) 4607 0x52AC 劬 (<CJK Ideograph>) 4608 0x52AD 劭 (<CJK Ideograph>) 4609 0x52BC 劼 (<CJK Ideograph>) 4610 0x52B5 劵 (<CJK Ideograph>) 4611 0x52C1 勁 (<CJK Ideograph>) 4612 0x52CD 勍 (<CJK Ideograph>) 4613 0x52D7 勗 (<CJK Ideograph>) 4614 0x52DE 勞 (<CJK Ideograph>) 4615 0x52E3 勣 (<CJK Ideograph>) 4616 0x52E6 勦 (<CJK Ideograph>) 4617 0x98ED 飭 (<CJK Ideograph>) 4618 0x52E0 勠 (<CJK Ideograph>) 4619 0x52F3 勳 (<CJK Ideograph>) 4620 0x52F5 勵 (<CJK Ideograph>) 4621 0x52F8 勸 (<CJK Ideograph>) 4622 0x52F9 勹 (<CJK Ideograph>) 4623 0x5306 匆 (<CJK Ideograph>) 4624 0x5308 匈 (<CJK Ideograph>) 4625 0x7538 甸 (<CJK Ideograph>) 4626 0x530D 匍 (<CJK Ideograph>) 4627 0x5310 匐 (<CJK Ideograph>) 4628 0x530F 匏 (<CJK Ideograph>) 4629 0x5315 匕 (<CJK Ideograph>) 4630 0x531A 匚 (<CJK Ideograph>) 4631 0x5323 匣 (<CJK Ideograph>) 4632 0x532F 匯 (<CJK Ideograph>) 4633 0x5331 匱 (<CJK Ideograph>) 4634 0x5333 匳 (<CJK Ideograph>) 4635 0x5338 匸 (<CJK Ideograph>) 4636 0x5340 區 (<CJK Ideograph>) 4637 0x5346 卆 (<CJK Ideograph>) 4638 0x5345 卅 (<CJK Ideograph>) 4639 0x4E17 丗 (<CJK Ideograph>) 4640 0x5349 卉 (<CJK Ideograph>) 4641 0x534D 卍 (<CJK Ideograph>) 4642 0x51D6 凖 (<CJK Ideograph>) 4643 0x535E 卞 (<CJK Ideograph>) 4644 0x5369 卩 (<CJK Ideograph>) 4645 0x536E 卮 (<CJK Ideograph>) 4646 0x5918 夘 (<CJK Ideograph>) 4647 0x537B 卻 (<CJK Ideograph>) 4648 0x5377 卷 (<CJK Ideograph>) 4649 0x5382 厂 (<CJK Ideograph>) 4650 0x5396 厖 (<CJK Ideograph>) 4651 0x53A0 厠 (<CJK Ideograph>) 4652 0x53A6 厦 (<CJK Ideograph>) 4653 0x53A5 厥 (<CJK Ideograph>) 4654 0x53AE 厮 (<CJK Ideograph>) 4655 0x53B0 厰 (<CJK Ideograph>) 4656 0x53B6 厶 (<CJK Ideograph>) 4657 0x53C3 參 (<CJK Ideograph>) 4658 0x7C12 簒 (<CJK Ideograph>) 4659 0x96D9 雙 (<CJK Ideograph>) 4660 0x53DF 叟 (<CJK Ideograph>) 4661 0x66FC 曼 (<CJK Ideograph>) 4662 0x71EE 燮 (<CJK Ideograph>) 4663 0x53EE 叮 (<CJK Ideograph>) 4664 0x53E8 叨 (<CJK Ideograph>) 4665 0x53ED 叭 (<CJK Ideograph>) 4666 0x53FA 叺 (<CJK Ideograph>) 4667 0x5401 吁 (<CJK Ideograph>) 4668 0x543D 吽 (<CJK Ideograph>) 4669 0x5440 呀 (<CJK Ideograph>) 4670 0x542C 听 (<CJK Ideograph>) 4671 0x542D 吭 (<CJK Ideograph>) 4672 0x543C 吼 (<CJK Ideograph>) 4673 0x542E 吮 (<CJK Ideograph>) 4674 0x5436 吶 (<CJK Ideograph>) 4675 0x5429 吩 (<CJK Ideograph>) 4676 0x541D 吝 (<CJK Ideograph>) 4677 0x544E 呎 (<CJK Ideograph>) 4678 0x548F 咏 (<CJK Ideograph>) 4679 0x5475 呵 (<CJK Ideograph>) 4680 0x548E 咎 (<CJK Ideograph>) 4681 0x545F 呟 (<CJK Ideograph>) 4682 0x5471 呱 (<CJK Ideograph>) 4683 0x5477 呷 (<CJK Ideograph>) 4684 0x5470 呰 (<CJK Ideograph>) 4685 0x5492 咒 (<CJK Ideograph>) 4686 0x547B 呻 (<CJK Ideograph>) 4687 0x5480 咀 (<CJK Ideograph>) 4688 0x5476 呶 (<CJK Ideograph>) 4689 0x5484 咄 (<CJK Ideograph>) 4690 0x5490 咐 (<CJK Ideograph>) 4691 0x5486 咆 (<CJK Ideograph>) 4692 0x54C7 哇 (<CJK Ideograph>) 4693 0x54A2 咢 (<CJK Ideograph>) 4694 0x54B8 咸 (<CJK Ideograph>) 4695 0x54A5 咥 (<CJK Ideograph>) 4696 0x54AC 咬 (<CJK Ideograph>) 4697 0x54C4 哄 (<CJK Ideograph>) 4698 0x54C8 哈 (<CJK Ideograph>) 4699 0x54A8 咨 (<CJK Ideograph>) 4700 0x54AB 咫 (<CJK Ideograph>) 4701 0x54C2 哂 (<CJK Ideograph>) 4702 0x54A4 咤 (<CJK Ideograph>) 4703 0x54BE 咾 (<CJK Ideograph>) 4704 0x54BC 咼 (<CJK Ideograph>) 4705 0x54D8 哘 (<CJK Ideograph>) 4706 0x54E5 哥 (<CJK Ideograph>) 4707 0x54E6 哦 (<CJK Ideograph>) 4708 0x550F 唏 (<CJK Ideograph>) 4709 0x5514 唔 (<CJK Ideograph>) 4710 0x54FD 哽 (<CJK Ideograph>) 4711 0x54EE 哮 (<CJK Ideograph>) 4712 0x54ED 哭 (<CJK Ideograph>) 4713 0x54FA 哺 (<CJK Ideograph>) 4714 0x54E2 哢 (<CJK Ideograph>) 4715 0x5539 唹 (<CJK Ideograph>) 4716 0x5540 啀 (<CJK Ideograph>) 4717 0x5563 啣 (<CJK Ideograph>) 4718 0x554C 啌 (<CJK Ideograph>) 4719 0x552E 售 (<CJK Ideograph>) 4720 0x555C 啜 (<CJK Ideograph>) 4721 0x5545 啅 (<CJK Ideograph>) 4722 0x5556 啖 (<CJK Ideograph>) 4723 0x5557 啗 (<CJK Ideograph>) 4724 0x5538 唸 (<CJK Ideograph>) 4725 0x5533 唳 (<CJK Ideograph>) 4726 0x555D 啝 (<CJK Ideograph>) 4727 0x5599 喙 (<CJK Ideograph>) 4728 0x5580 喀 (<CJK Ideograph>) 4729 0x54AF 咯 (<CJK Ideograph>) 4730 0x558A 喊 (<CJK Ideograph>) 4731 0x559F 喟 (<CJK Ideograph>) 4732 0x557B 啻 (<CJK Ideograph>) 4733 0x557E 啾 (<CJK Ideograph>) 4734 0x5598 喘 (<CJK Ideograph>) 4735 0x559E 喞 (<CJK Ideograph>) 4736 0x55AE 單 (<CJK Ideograph>) 4737 0x557C 啼 (<CJK Ideograph>) 4738 0x5583 喃 (<CJK Ideograph>) 4739 0x55A9 喩 (<CJK Ideograph>) 4740 0x5587 喇 (<CJK Ideograph>) 4741 0x55A8 喨 (<CJK Ideograph>) 4742 0x55DA 嗚 (<CJK Ideograph>) 4743 0x55C5 嗅 (<CJK Ideograph>) 4744 0x55DF 嗟 (<CJK Ideograph>) 4745 0x55C4 嗄 (<CJK Ideograph>) 4746 0x55DC 嗜 (<CJK Ideograph>) 4747 0x55E4 嗤 (<CJK Ideograph>) 4748 0x55D4 嗔 (<CJK Ideograph>) 4749 0x5614 嘔 (<CJK Ideograph>) 4750 0x55F7 嗷 (<CJK Ideograph>) 4751 0x5616 嘖 (<CJK Ideograph>) 4752 0x55FE 嗾 (<CJK Ideograph>) 4753 0x55FD 嗽 (<CJK Ideograph>) 4754 0x561B 嘛 (<CJK Ideograph>) 4755 0x55F9 嗹 (<CJK Ideograph>) 4756 0x564E 噎 (<CJK Ideograph>) 4757 0x5650 噐 (<CJK Ideograph>) 4758 0x71DF 營 (<CJK Ideograph>) 4759 0x5634 嘴 (<CJK Ideograph>) 4760 0x5636 嘶 (<CJK Ideograph>) 4761 0x5632 嘲 (<CJK Ideograph>) 4762 0x5638 嘸 (<CJK Ideograph>) 4763 0x566B 噫 (<CJK Ideograph>) 4764 0x5664 噤 (<CJK Ideograph>) 4765 0x562F 嘯 (<CJK Ideograph>) 4766 0x566C 噬 (<CJK Ideograph>) 4767 0x566A 噪 (<CJK Ideograph>) 4768 0x5686 嚆 (<CJK Ideograph>) 4769 0x5680 嚀 (<CJK Ideograph>) 4770 0x568A 嚊 (<CJK Ideograph>) 4771 0x56A0 嚠 (<CJK Ideograph>) 4772 0x5694 嚔 (<CJK Ideograph>) 4773 0x568F 嚏 (<CJK Ideograph>) 4774 0x56A5 嚥 (<CJK Ideograph>) 4775 0x56AE 嚮 (<CJK Ideograph>) 4776 0x56B6 嚶 (<CJK Ideograph>) 4777 0x56B4 嚴 (<CJK Ideograph>) 4778 0x56C2 囂 (<CJK Ideograph>) 4779 0x56BC 嚼 (<CJK Ideograph>) 4780 0x56C1 囁 (<CJK Ideograph>) 4781 0x56C3 囃 (<CJK Ideograph>) 4782 0x56C0 囀 (<CJK Ideograph>) 4783 0x56C8 囈 (<CJK Ideograph>) 4784 0x56CE 囎 (<CJK Ideograph>) 4785 0x56D1 囑 (<CJK Ideograph>) 4786 0x56D3 囓 (<CJK Ideograph>) 4787 0x56D7 囗 (<CJK Ideograph>) 4788 0x56EE 囮 (<CJK Ideograph>) 4789 0x56F9 囹 (<CJK Ideograph>) 4790 0x5700 圀 (<CJK Ideograph>) 4791 0x56FF 囿 (<CJK Ideograph>) 4792 0x5704 圄 (<CJK Ideograph>) 4793 0x5709 圉 (<CJK Ideograph>) 4794 0x5708 圈 (<CJK Ideograph>) 4795 0x570B 國 (<CJK Ideograph>) 4796 0x570D 圍 (<CJK Ideograph>) 4797 0x5713 圓 (<CJK Ideograph>) 4798 0x5718 團 (<CJK Ideograph>) 4799 0x5716 圖 (<CJK Ideograph>) 4800 0x55C7 嗇 (<CJK Ideograph>) 4801 0x571C 圜 (<CJK Ideograph>) 4802 0x5726 圦 (<CJK Ideograph>) 4803 0x5737 圷 (<CJK Ideograph>) 4804 0x5738 圸 (<CJK Ideograph>) 4805 0x574E 坎 (<CJK Ideograph>) 4806 0x573B 圻 (<CJK Ideograph>) 4807 0x5740 址 (<CJK Ideograph>) 4808 0x574F 坏 (<CJK Ideograph>) 4809 0x5769 坩 (<CJK Ideograph>) 4810 0x57C0 埀 (<CJK Ideograph>) 4811 0x5788 垈 (<CJK Ideograph>) 4812 0x5761 坡 (<CJK Ideograph>) 4813 0x577F 坿 (<CJK Ideograph>) 4814 0x5789 垉 (<CJK Ideograph>) 4815 0x5793 垓 (<CJK Ideograph>) 4816 0x57A0 垠 (<CJK Ideograph>) 4817 0x57B3 垳 (<CJK Ideograph>) 4818 0x57A4 垤 (<CJK Ideograph>) 4819 0x57AA 垪 (<CJK Ideograph>) 4820 0x57B0 垰 (<CJK Ideograph>) 4821 0x57C3 埃 (<CJK Ideograph>) 4822 0x57C6 埆 (<CJK Ideograph>) 4823 0x57D4 埔 (<CJK Ideograph>) 4824 0x57D2 埒 (<CJK Ideograph>) 4825 0x57D3 埓 (<CJK Ideograph>) 4826 0x580A 堊 (<CJK Ideograph>) 4827 0x57D6 埖 (<CJK Ideograph>) 4828 0x57E3 埣 (<CJK Ideograph>) 4829 0x580B 堋 (<CJK Ideograph>) 4830 0x5819 堙 (<CJK Ideograph>) 4831 0x581D 堝 (<CJK Ideograph>) 4832 0x5872 塲 (<CJK Ideograph>) 4833 0x5821 堡 (<CJK Ideograph>) 4834 0x5862 塢 (<CJK Ideograph>) 4835 0x584B 塋 (<CJK Ideograph>) 4836 0x5870 塰 (<CJK Ideograph>) 4837 0x6BC0 毀 (<CJK Ideograph>) 4838 0x5852 塒 (<CJK Ideograph>) 4839 0x583D 堽 (<CJK Ideograph>) 4840 0x5879 塹 (<CJK Ideograph>) 4841 0x5885 墅 (<CJK Ideograph>) 4842 0x58B9 墹 (<CJK Ideograph>) 4843 0x589F 墟 (<CJK Ideograph>) 4844 0x58AB 墫 (<CJK Ideograph>) 4845 0x58BA 墺 (<CJK Ideograph>) 4846 0x58DE 壞 (<CJK Ideograph>) 4847 0x58BB 墻 (<CJK Ideograph>) 4848 0x58B8 墸 (<CJK Ideograph>) 4849 0x58AE 墮 (<CJK Ideograph>) 4850 0x58C5 壅 (<CJK Ideograph>) 4851 0x58D3 壓 (<CJK Ideograph>) 4852 0x58D1 壑 (<CJK Ideograph>) 4853 0x58D7 壗 (<CJK Ideograph>) 4854 0x58D9 壙 (<CJK Ideograph>) 4855 0x58D8 壘 (<CJK Ideograph>) 4856 0x58E5 壥 (<CJK Ideograph>) 4857 0x58DC 壜 (<CJK Ideograph>) 4858 0x58E4 壤 (<CJK Ideograph>) 4859 0x58DF 壟 (<CJK Ideograph>) 4860 0x58EF 壯 (<CJK Ideograph>) 4861 0x58FA 壺 (<CJK Ideograph>) 4862 0x58F9 壹 (<CJK Ideograph>) 4863 0x58FB 壻 (<CJK Ideograph>) 4864 0x58FC 壼 (<CJK Ideograph>) 4865 0x58FD 壽 (<CJK Ideograph>) 4866 0x5902 夂 (<CJK Ideograph>) 4867 0x590A 夊 (<CJK Ideograph>) 4868 0x5910 夐 (<CJK Ideograph>) 4869 0x591B 夛 (<CJK Ideograph>) 4870 0x68A6 梦 (<CJK Ideograph>) 4871 0x5925 夥 (<CJK Ideograph>) 4872 0x592C 夬 (<CJK Ideograph>) 4873 0x592D 夭 (<CJK Ideograph>) 4874 0x5932 夲 (<CJK Ideograph>) 4875 0x5938 夸 (<CJK Ideograph>) 4876 0x593E 夾 (<CJK Ideograph>) 4877 0x7AD2 竒 (<CJK Ideograph>) 4878 0x5955 奕 (<CJK Ideograph>) 4879 0x5950 奐 (<CJK Ideograph>) 4880 0x594E 奎 (<CJK Ideograph>) 4881 0x595A 奚 (<CJK Ideograph>) 4882 0x5958 奘 (<CJK Ideograph>) 4883 0x5962 奢 (<CJK Ideograph>) 4884 0x5960 奠 (<CJK Ideograph>) 4885 0x5967 奧 (<CJK Ideograph>) 4886 0x596C 奬 (<CJK Ideograph>) 4887 0x5969 奩 (<CJK Ideograph>) 4888 0x5978 奸 (<CJK Ideograph>) 4889 0x5981 妁 (<CJK Ideograph>) 4890 0x599D 妝 (<CJK Ideograph>) 4891 0x4F5E 佞 (<CJK Ideograph>) 4892 0x4FAB 侫 (<CJK Ideograph>) 4893 0x59A3 妣 (<CJK Ideograph>) 4894 0x59B2 妲 (<CJK Ideograph>) 4895 0x59C6 姆 (<CJK Ideograph>) 4896 0x59E8 姨 (<CJK Ideograph>) 4897 0x59DC 姜 (<CJK Ideograph>) 4898 0x598D 妍 (<CJK Ideograph>) 4899 0x59D9 姙 (<CJK Ideograph>) 4900 0x59DA 姚 (<CJK Ideograph>) 4901 0x5A25 娥 (<CJK Ideograph>) 4902 0x5A1F 娟 (<CJK Ideograph>) 4903 0x5A11 娑 (<CJK Ideograph>) 4904 0x5A1C 娜 (<CJK Ideograph>) 4905 0x5A09 娉 (<CJK Ideograph>) 4906 0x5A1A 娚 (<CJK Ideograph>) 4907 0x5A40 婀 (<CJK Ideograph>) 4908 0x5A6C 婬 (<CJK Ideograph>) 4909 0x5A49 婉 (<CJK Ideograph>) 4910 0x5A35 娵 (<CJK Ideograph>) 4911 0x5A36 娶 (<CJK Ideograph>) 4912 0x5A62 婢 (<CJK Ideograph>) 4913 0x5A6A 婪 (<CJK Ideograph>) 4914 0x5A9A 媚 (<CJK Ideograph>) 4915 0x5ABC 媼 (<CJK Ideograph>) 4916 0x5ABE 媾 (<CJK Ideograph>) 4917 0x5ACB 嫋 (<CJK Ideograph>) 4918 0x5AC2 嫂 (<CJK Ideograph>) 4919 0x5ABD 媽 (<CJK Ideograph>) 4920 0x5AE3 嫣 (<CJK Ideograph>) 4921 0x5AD7 嫗 (<CJK Ideograph>) 4922 0x5AE6 嫦 (<CJK Ideograph>) 4923 0x5AE9 嫩 (<CJK Ideograph>) 4924 0x5AD6 嫖 (<CJK Ideograph>) 4925 0x5AFA 嫺 (<CJK Ideograph>) 4926 0x5AFB 嫻 (<CJK Ideograph>) 4927 0x5B0C 嬌 (<CJK Ideograph>) 4928 0x5B0B 嬋 (<CJK Ideograph>) 4929 0x5B16 嬖 (<CJK Ideograph>) 4930 0x5B32 嬲 (<CJK Ideograph>) 4931 0x5AD0 嫐 (<CJK Ideograph>) 4932 0x5B2A 嬪 (<CJK Ideograph>) 4933 0x5B36 嬶 (<CJK Ideograph>) 4934 0x5B3E 嬾 (<CJK Ideograph>) 4935 0x5B43 孃 (<CJK Ideograph>) 4936 0x5B45 孅 (<CJK Ideograph>) 4937 0x5B40 孀 (<CJK Ideograph>) 4938 0x5B51 孑 (<CJK Ideograph>) 4939 0x5B55 孕 (<CJK Ideograph>) 4940 0x5B5A 孚 (<CJK Ideograph>) 4941 0x5B5B 孛 (<CJK Ideograph>) 4942 0x5B65 孥 (<CJK Ideograph>) 4943 0x5B69 孩 (<CJK Ideograph>) 4944 0x5B70 孰 (<CJK Ideograph>) 4945 0x5B73 孳 (<CJK Ideograph>) 4946 0x5B75 孵 (<CJK Ideograph>) 4947 0x5B78 學 (<CJK Ideograph>) 4948 0x6588 斈 (<CJK Ideograph>) 4949 0x5B7A 孺 (<CJK Ideograph>) 4950 0x5B80 宀 (<CJK Ideograph>) 4951 0x5B83 它 (<CJK Ideograph>) 4952 0x5BA6 宦 (<CJK Ideograph>) 4953 0x5BB8 宸 (<CJK Ideograph>) 4954 0x5BC3 寃 (<CJK Ideograph>) 4955 0x5BC7 寇 (<CJK Ideograph>) 4956 0x5BC9 寉 (<CJK Ideograph>) 4957 0x5BD4 寔 (<CJK Ideograph>) 4958 0x5BD0 寐 (<CJK Ideograph>) 4959 0x5BE4 寤 (<CJK Ideograph>) 4960 0x5BE6 實 (<CJK Ideograph>) 4961 0x5BE2 寢 (<CJK Ideograph>) 4962 0x5BDE 寞 (<CJK Ideograph>) 4963 0x5BE5 寥 (<CJK Ideograph>) 4964 0x5BEB 寫 (<CJK Ideograph>) 4965 0x5BF0 寰 (<CJK Ideograph>) 4966 0x5BF6 寶 (<CJK Ideograph>) 4967 0x5BF3 寳 (<CJK Ideograph>) 4968 0x5C05 尅 (<CJK Ideograph>) 4969 0x5C07 將 (<CJK Ideograph>) 4970 0x5C08 專 (<CJK Ideograph>) 4971 0x5C0D 對 (<CJK Ideograph>) 4972 0x5C13 尓 (<CJK Ideograph>) 4973 0x5C20 尠 (<CJK Ideograph>) 4974 0x5C22 尢 (<CJK Ideograph>) 4975 0x5C28 尨 (<CJK Ideograph>) 4976 0x5C38 尸 (<CJK Ideograph>) 4977 0x5C39 尹 (<CJK Ideograph>) 4978 0x5C41 屁 (<CJK Ideograph>) 4979 0x5C46 屆 (<CJK Ideograph>) 4980 0x5C4E 屎 (<CJK Ideograph>) 4981 0x5C53 屓 (<CJK Ideograph>) 4982 0x5C50 屐 (<CJK Ideograph>) 4983 0x5C4F 屏 (<CJK Ideograph>) 4984 0x5B71 孱 (<CJK Ideograph>) 4985 0x5C6C 屬 (<CJK Ideograph>) 4986 0x5C6E 屮 (<CJK Ideograph>) 4987 0x4E62 乢 (<CJK Ideograph>) 4988 0x5C76 屶 (<CJK Ideograph>) 4989 0x5C79 屹 (<CJK Ideograph>) 4990 0x5C8C 岌 (<CJK Ideograph>) 4991 0x5C91 岑 (<CJK Ideograph>) 4992 0x5C94 岔 (<CJK Ideograph>) 4993 0x599B 妛 (<CJK Ideograph>) 4994 0x5CAB 岫 (<CJK Ideograph>) 4995 0x5CBB 岻 (<CJK Ideograph>) 4996 0x5CB6 岶 (<CJK Ideograph>) 4997 0x5CBC 岼 (<CJK Ideograph>) 4998 0x5CB7 岷 (<CJK Ideograph>) 4999 0x5CC5 峅 (<CJK Ideograph>) 5000 0x5CBE 岾 (<CJK Ideograph>) 5001 0x5CC7 峇 (<CJK Ideograph>) 5002 0x5CD9 峙 (<CJK Ideograph>) 5003 0x5CE9 峩 (<CJK Ideograph>) 5004 0x5CFD 峽 (<CJK Ideograph>) 5005 0x5CFA 峺 (<CJK Ideograph>) 5006 0x5CED 峭 (<CJK Ideograph>) 5007 0x5D8C 嶌 (<CJK Ideograph>) 5008 0x5CEA 峪 (<CJK Ideograph>) 5009 0x5D0B 崋 (<CJK Ideograph>) 5010 0x5D15 崕 (<CJK Ideograph>) 5011 0x5D17 崗 (<CJK Ideograph>) 5012 0x5D5C 嵜 (<CJK Ideograph>) 5013 0x5D1F 崟 (<CJK Ideograph>) 5014 0x5D1B 崛 (<CJK Ideograph>) 5015 0x5D11 崑 (<CJK Ideograph>) 5016 0x5D14 崔 (<CJK Ideograph>) 5017 0x5D22 崢 (<CJK Ideograph>) 5018 0x5D1A 崚 (<CJK Ideograph>) 5019 0x5D19 崙 (<CJK Ideograph>) 5020 0x5D18 崘 (<CJK Ideograph>) 5021 0x5D4C 嵌 (<CJK Ideograph>) 5022 0x5D52 嵒 (<CJK Ideograph>) 5023 0x5D4E 嵎 (<CJK Ideograph>) 5024 0x5D4B 嵋 (<CJK Ideograph>) 5025 0x5D6C 嵬 (<CJK Ideograph>) 5026 0x5D73 嵳 (<CJK Ideograph>) 5027 0x5D76 嵶 (<CJK Ideograph>) 5028 0x5D87 嶇 (<CJK Ideograph>) 5029 0x5D84 嶄 (<CJK Ideograph>) 5030 0x5D82 嶂 (<CJK Ideograph>) 5031 0x5DA2 嶢 (<CJK Ideograph>) 5032 0x5D9D 嶝 (<CJK Ideograph>) 5033 0x5DAC 嶬 (<CJK Ideograph>) 5034 0x5DAE 嶮 (<CJK Ideograph>) 5035 0x5DBD 嶽 (<CJK Ideograph>) 5036 0x5D90 嶐 (<CJK Ideograph>) 5037 0x5DB7 嶷 (<CJK Ideograph>) 5038 0x5DBC 嶼 (<CJK Ideograph>) 5039 0x5DC9 巉 (<CJK Ideograph>) 5040 0x5DCD 巍 (<CJK Ideograph>) 5041 0x5DD3 巓 (<CJK Ideograph>) 5042 0x5DD2 巒 (<CJK Ideograph>) 5043 0x5DD6 巖 (<CJK Ideograph>) 5044 0x5DDB 巛 (<CJK Ideograph>) 5045 0x5DEB 巫 (<CJK Ideograph>) 5046 0x5DF2 已 (<CJK Ideograph>) 5047 0x5DF5 巵 (<CJK Ideograph>) 5048 0x5E0B 帋 (<CJK Ideograph>) 5049 0x5E1A 帚 (<CJK Ideograph>) 5050 0x5E19 帙 (<CJK Ideograph>) 5051 0x5E11 帑 (<CJK Ideograph>) 5052 0x5E1B 帛 (<CJK Ideograph>) 5053 0x5E36 帶 (<CJK Ideograph>) 5054 0x5E37 帷 (<CJK Ideograph>) 5055 0x5E44 幄 (<CJK Ideograph>) 5056 0x5E43 幃 (<CJK Ideograph>) 5057 0x5E40 幀 (<CJK Ideograph>) 5058 0x5E4E 幎 (<CJK Ideograph>) 5059 0x5E57 幗 (<CJK Ideograph>) 5060 0x5E54 幔 (<CJK Ideograph>) 5061 0x5E5F 幟 (<CJK Ideograph>) 5062 0x5E62 幢 (<CJK Ideograph>) 5063 0x5E64 幤 (<CJK Ideograph>) 5064 0x5E47 幇 (<CJK Ideograph>) 5065 0x5E75 幵 (<CJK Ideograph>) 5066 0x5E76 并 (<CJK Ideograph>) 5067 0x5E7A 幺 (<CJK Ideograph>) 5068 0x9EBC 麼 (<CJK Ideograph>) 5069 0x5E7F 广 (<CJK Ideograph>) 5070 0x5EA0 庠 (<CJK Ideograph>) 5071 0x5EC1 廁 (<CJK Ideograph>) 5072 0x5EC2 廂 (<CJK Ideograph>) 5073 0x5EC8 廈 (<CJK Ideograph>) 5074 0x5ED0 廐 (<CJK Ideograph>) 5075 0x5ECF 廏 (<CJK Ideograph>) 5076 0x5ED6 廖 (<CJK Ideograph>) 5077 0x5EE3 廣 (<CJK Ideograph>) 5078 0x5EDD 廝 (<CJK Ideograph>) 5079 0x5EDA 廚 (<CJK Ideograph>) 5080 0x5EDB 廛 (<CJK Ideograph>) 5081 0x5EE2 廢 (<CJK Ideograph>) 5082 0x5EE1 廡 (<CJK Ideograph>) 5083 0x5EE8 廨 (<CJK Ideograph>) 5084 0x5EE9 廩 (<CJK Ideograph>) 5085 0x5EEC 廬 (<CJK Ideograph>) 5086 0x5EF1 廱 (<CJK Ideograph>) 5087 0x5EF3 廳 (<CJK Ideograph>) 5088 0x5EF0 廰 (<CJK Ideograph>) 5089 0x5EF4 廴 (<CJK Ideograph>) 5090 0x5EF8 廸 (<CJK Ideograph>) 5091 0x5EFE 廾 (<CJK Ideograph>) 5092 0x5F03 弃 (<CJK Ideograph>) 5093 0x5F09 弉 (<CJK Ideograph>) 5094 0x5F5D 彝 (<CJK Ideograph>) 5095 0x5F5C 彜 (<CJK Ideograph>) 5096 0x5F0B 弋 (<CJK Ideograph>) 5097 0x5F11 弑 (<CJK Ideograph>) 5098 0x5F16 弖 (<CJK Ideograph>) 5099 0x5F29 弩 (<CJK Ideograph>) 5100 0x5F2D 弭 (<CJK Ideograph>) 5101 0x5F38 弸 (<CJK Ideograph>) 5102 0x5F41 彁 (<CJK Ideograph>) 5103 0x5F48 彈 (<CJK Ideograph>) 5104 0x5F4C 彌 (<CJK Ideograph>) 5105 0x5F4E 彎 (<CJK Ideograph>) 5106 0x5F2F 弯 (<CJK Ideograph>) 5107 0x5F51 彑 (<CJK Ideograph>) 5108 0x5F56 彖 (<CJK Ideograph>) 5109 0x5F57 彗 (<CJK Ideograph>) 5110 0x5F59 彙 (<CJK Ideograph>) 5111 0x5F61 彡 (<CJK Ideograph>) 5112 0x5F6D 彭 (<CJK Ideograph>) 5113 0x5F73 彳 (<CJK Ideograph>) 5114 0x5F77 彷 (<CJK Ideograph>) 5115 0x5F83 徃 (<CJK Ideograph>) 5116 0x5F82 徂 (<CJK Ideograph>) 5117 0x5F7F 彿 (<CJK Ideograph>) 5118 0x5F8A 徊 (<CJK Ideograph>) 5119 0x5F88 很 (<CJK Ideograph>) 5120 0x5F91 徑 (<CJK Ideograph>) 5121 0x5F87 徇 (<CJK Ideograph>) 5122 0x5F9E 從 (<CJK Ideograph>) 5123 0x5F99 徙 (<CJK Ideograph>) 5124 0x5F98 徘 (<CJK Ideograph>) 5125 0x5FA0 徠 (<CJK Ideograph>) 5126 0x5FA8 徨 (<CJK Ideograph>) 5127 0x5FAD 徭 (<CJK Ideograph>) 5128 0x5FBC 徼 (<CJK Ideograph>) 5129 0x5FD6 忖 (<CJK Ideograph>) 5130 0x5FFB 忻 (<CJK Ideograph>) 5131 0x5FE4 忤 (<CJK Ideograph>) 5132 0x5FF8 忸 (<CJK Ideograph>) 5133 0x5FF1 忱 (<CJK Ideograph>) 5134 0x5FDD 忝 (<CJK Ideograph>) 5135 0x60B3 悳 (<CJK Ideograph>) 5136 0x5FFF 忿 (<CJK Ideograph>) 5137 0x6021 怡 (<CJK Ideograph>) 5138 0x6060 恠 (<CJK Ideograph>) 5139 0x6019 怙 (<CJK Ideograph>) 5140 0x6010 怐 (<CJK Ideograph>) 5141 0x6029 怩 (<CJK Ideograph>) 5142 0x600E 怎 (<CJK Ideograph>) 5143 0x6031 怱 (<CJK Ideograph>) 5144 0x601B 怛 (<CJK Ideograph>) 5145 0x6015 怕 (<CJK Ideograph>) 5146 0x602B 怫 (<CJK Ideograph>) 5147 0x6026 怦 (<CJK Ideograph>) 5148 0x600F 怏 (<CJK Ideograph>) 5149 0x603A 怺 (<CJK Ideograph>) 5150 0x605A 恚 (<CJK Ideograph>) 5151 0x6041 恁 (<CJK Ideograph>) 5152 0x606A 恪 (<CJK Ideograph>) 5153 0x6077 恷 (<CJK Ideograph>) 5154 0x605F 恟 (<CJK Ideograph>) 5155 0x604A 恊 (<CJK Ideograph>) 5156 0x6046 恆 (<CJK Ideograph>) 5157 0x604D 恍 (<CJK Ideograph>) 5158 0x6063 恣 (<CJK Ideograph>) 5159 0x6043 恃 (<CJK Ideograph>) 5160 0x6064 恤 (<CJK Ideograph>) 5161 0x6042 恂 (<CJK Ideograph>) 5162 0x606C 恬 (<CJK Ideograph>) 5163 0x606B 恫 (<CJK Ideograph>) 5164 0x6059 恙 (<CJK Ideograph>) 5165 0x6081 悁 (<CJK Ideograph>) 5166 0x608D 悍 (<CJK Ideograph>) 5167 0x60E7 惧 (<CJK Ideograph>) 5168 0x6083 悃 (<CJK Ideograph>) 5169 0x609A 悚 (<CJK Ideograph>) 5170 0x6084 悄 (<CJK Ideograph>) 5171 0x609B 悛 (<CJK Ideograph>) 5172 0x6096 悖 (<CJK Ideograph>) 5173 0x6097 悗 (<CJK Ideograph>) 5174 0x6092 悒 (<CJK Ideograph>) 5175 0x60A7 悧 (<CJK Ideograph>) 5176 0x608B 悋 (<CJK Ideograph>) 5177 0x60E1 惡 (<CJK Ideograph>) 5178 0x60B8 悸 (<CJK Ideograph>) 5179 0x60E0 惠 (<CJK Ideograph>) 5180 0x60D3 惓 (<CJK Ideograph>) 5181 0x60B4 悴 (<CJK Ideograph>) 5182 0x5FF0 忰 (<CJK Ideograph>) 5183 0x60BD 悽 (<CJK Ideograph>) 5184 0x60C6 惆 (<CJK Ideograph>) 5185 0x60B5 悵 (<CJK Ideograph>) 5186 0x60D8 惘 (<CJK Ideograph>) 5187 0x614D 慍 (<CJK Ideograph>) 5188 0x6115 愕 (<CJK Ideograph>) 5189 0x6106 愆 (<CJK Ideograph>) 5190 0x60F6 惶 (<CJK Ideograph>) 5191 0x60F7 惷 (<CJK Ideograph>) 5192 0x6100 愀 (<CJK Ideograph>) 5193 0x60F4 惴 (<CJK Ideograph>) 5194 0x60FA 惺 (<CJK Ideograph>) 5195 0x6103 愃 (<CJK Ideograph>) 5196 0x6121 愡 (<CJK Ideograph>) 5197 0x60FB 惻 (<CJK Ideograph>) 5198 0x60F1 惱 (<CJK Ideograph>) 5199 0x610D 愍 (<CJK Ideograph>) 5200 0x610E 愎 (<CJK Ideograph>) 5201 0x6147 慇 (<CJK Ideograph>) 5202 0x613E 愾 (<CJK Ideograph>) 5203 0x6128 愨 (<CJK Ideograph>) 5204 0x6127 愧 (<CJK Ideograph>) 5205 0x614A 慊 (<CJK Ideograph>) 5206 0x613F 愿 (<CJK Ideograph>) 5207 0x613C 愼 (<CJK Ideograph>) 5208 0x612C 愬 (<CJK Ideograph>) 5209 0x6134 愴 (<CJK Ideograph>) 5210 0x613D 愽 (<CJK Ideograph>) 5211 0x6142 慂 (<CJK Ideograph>) 5212 0x6144 慄 (<CJK Ideograph>) 5213 0x6173 慳 (<CJK Ideograph>) 5214 0x6177 慷 (<CJK Ideograph>) 5215 0x6158 慘 (<CJK Ideograph>) 5216 0x6159 慙 (<CJK Ideograph>) 5217 0x615A 慚 (<CJK Ideograph>) 5218 0x616B 慫 (<CJK Ideograph>) 5219 0x6174 慴 (<CJK Ideograph>) 5220 0x616F 慯 (<CJK Ideograph>) 5221 0x6165 慥 (<CJK Ideograph>) 5222 0x6171 慱 (<CJK Ideograph>) 5223 0x615F 慟 (<CJK Ideograph>) 5224 0x615D 慝 (<CJK Ideograph>) 5225 0x6153 慓 (<CJK Ideograph>) 5226 0x6175 慵 (<CJK Ideograph>) 5227 0x6199 憙 (<CJK Ideograph>) 5228 0x6196 憖 (<CJK Ideograph>) 5229 0x6187 憇 (<CJK Ideograph>) 5230 0x61AC 憬 (<CJK Ideograph>) 5231 0x6194 憔 (<CJK Ideograph>) 5232 0x619A 憚 (<CJK Ideograph>) 5233 0x618A 憊 (<CJK Ideograph>) 5234 0x6191 憑 (<CJK Ideograph>) 5235 0x61AB 憫 (<CJK Ideograph>) 5236 0x61AE 憮 (<CJK Ideograph>) 5237 0x61CC 懌 (<CJK Ideograph>) 5238 0x61CA 懊 (<CJK Ideograph>) 5239 0x61C9 應 (<CJK Ideograph>) 5240 0x61F7 懷 (<CJK Ideograph>) 5241 0x61C8 懈 (<CJK Ideograph>) 5242 0x61C3 懃 (<CJK Ideograph>) 5243 0x61C6 懆 (<CJK Ideograph>) 5244 0x61BA 憺 (<CJK Ideograph>) 5245 0x61CB 懋 (<CJK Ideograph>) 5246 0x7F79 罹 (<CJK Ideograph>) 5247 0x61CD 懍 (<CJK Ideograph>) 5248 0x61E6 懦 (<CJK Ideograph>) 5249 0x61E3 懣 (<CJK Ideograph>) 5250 0x61F6 懶 (<CJK Ideograph>) 5251 0x61FA 懺 (<CJK Ideograph>) 5252 0x61F4 懴 (<CJK Ideograph>) 5253 0x61FF 懿 (<CJK Ideograph>) 5254 0x61FD 懽 (<CJK Ideograph>) 5255 0x61FC 懼 (<CJK Ideograph>) 5256 0x61FE 懾 (<CJK Ideograph>) 5257 0x6200 戀 (<CJK Ideograph>) 5258 0x6208 戈 (<CJK Ideograph>) 5259 0x6209 戉 (<CJK Ideograph>) 5260 0x620D 戍 (<CJK Ideograph>) 5261 0x620C 戌 (<CJK Ideograph>) 5262 0x6214 戔 (<CJK Ideograph>) 5263 0x621B 戛 (<CJK Ideograph>) 5264 0x621E 戞 (<CJK Ideograph>) 5265 0x6221 戡 (<CJK Ideograph>) 5266 0x622A 截 (<CJK Ideograph>) 5267 0x622E 戮 (<CJK Ideograph>) 5268 0x6230 戰 (<CJK Ideograph>) 5269 0x6232 戲 (<CJK Ideograph>) 5270 0x6233 戳 (<CJK Ideograph>) 5271 0x6241 扁 (<CJK Ideograph>) 5272 0x624E 扎 (<CJK Ideograph>) 5273 0x625E 扞 (<CJK Ideograph>) 5274 0x6263 扣 (<CJK Ideograph>) 5275 0x625B 扛 (<CJK Ideograph>) 5276 0x6260 扠 (<CJK Ideograph>) 5277 0x6268 扨 (<CJK Ideograph>) 5278 0x627C 扼 (<CJK Ideograph>) 5279 0x6282 抂 (<CJK Ideograph>) 5280 0x6289 抉 (<CJK Ideograph>) 5281 0x627E 找 (<CJK Ideograph>) 5282 0x6292 抒 (<CJK Ideograph>) 5283 0x6293 抓 (<CJK Ideograph>) 5284 0x6296 抖 (<CJK Ideograph>) 5285 0x62D4 拔 (<CJK Ideograph>) 5286 0x6283 抃 (<CJK Ideograph>) 5287 0x6294 抔 (<CJK Ideograph>) 5288 0x62D7 拗 (<CJK Ideograph>) 5289 0x62D1 拑 (<CJK Ideograph>) 5290 0x62BB 抻 (<CJK Ideograph>) 5291 0x62CF 拏 (<CJK Ideograph>) 5292 0x62FF 拿 (<CJK Ideograph>) 5293 0x62C6 拆 (<CJK Ideograph>) 5294 0x64D4 擔 (<CJK Ideograph>) 5295 0x62C8 拈 (<CJK Ideograph>) 5296 0x62DC 拜 (<CJK Ideograph>) 5297 0x62CC 拌 (<CJK Ideograph>) 5298 0x62CA 拊 (<CJK Ideograph>) 5299 0x62C2 拂 (<CJK Ideograph>) 5300 0x62C7 拇 (<CJK Ideograph>) 5301 0x629B 抛 (<CJK Ideograph>) 5302 0x62C9 拉 (<CJK Ideograph>) 5303 0x630C 挌 (<CJK Ideograph>) 5304 0x62EE 拮 (<CJK Ideograph>) 5305 0x62F1 拱 (<CJK Ideograph>) 5306 0x6327 挧 (<CJK Ideograph>) 5307 0x6302 挂 (<CJK Ideograph>) 5308 0x6308 挈 (<CJK Ideograph>) 5309 0x62EF 拯 (<CJK Ideograph>) 5310 0x62F5 拵 (<CJK Ideograph>) 5311 0x6350 捐 (<CJK Ideograph>) 5312 0x633E 挾 (<CJK Ideograph>) 5313 0x634D 捍 (<CJK Ideograph>) 5314 0x641C 搜 (<CJK Ideograph>) 5315 0x634F 捏 (<CJK Ideograph>) 5316 0x6396 掖 (<CJK Ideograph>) 5317 0x638E 掎 (<CJK Ideograph>) 5318 0x6380 掀 (<CJK Ideograph>) 5319 0x63AB 掫 (<CJK Ideograph>) 5320 0x6376 捶 (<CJK Ideograph>) 5321 0x63A3 掣 (<CJK Ideograph>) 5322 0x638F 掏 (<CJK Ideograph>) 5323 0x6389 掉 (<CJK Ideograph>) 5324 0x639F 掟 (<CJK Ideograph>) 5325 0x63B5 掵 (<CJK Ideograph>) 5326 0x636B 捫 (<CJK Ideograph>) 5327 0x6369 捩 (<CJK Ideograph>) 5328 0x63BE 掾 (<CJK Ideograph>) 5329 0x63E9 揩 (<CJK Ideograph>) 5330 0x63C0 揀 (<CJK Ideograph>) 5331 0x63C6 揆 (<CJK Ideograph>) 5332 0x63E3 揣 (<CJK Ideograph>) 5333 0x63C9 揉 (<CJK Ideograph>) 5334 0x63D2 插 (<CJK Ideograph>) 5335 0x63F6 揶 (<CJK Ideograph>) 5336 0x63C4 揄 (<CJK Ideograph>) 5337 0x6416 搖 (<CJK Ideograph>) 5338 0x6434 搴 (<CJK Ideograph>) 5339 0x6406 搆 (<CJK Ideograph>) 5340 0x6413 搓 (<CJK Ideograph>) 5341 0x6426 搦 (<CJK Ideograph>) 5342 0x6436 搶 (<CJK Ideograph>) 5343 0x651D 攝 (<CJK Ideograph>) 5344 0x6417 搗 (<CJK Ideograph>) 5345 0x6428 搨 (<CJK Ideograph>) 5346 0x640F 搏 (<CJK Ideograph>) 5347 0x6467 摧 (<CJK Ideograph>) 5348 0x646F 摯 (<CJK Ideograph>) 5349 0x6476 摶 (<CJK Ideograph>) 5350 0x644E 摎 (<CJK Ideograph>) 5351 0x652A 攪 (<CJK Ideograph>) 5352 0x6495 撕 (<CJK Ideograph>) 5353 0x6493 撓 (<CJK Ideograph>) 5354 0x64A5 撥 (<CJK Ideograph>) 5355 0x64A9 撩 (<CJK Ideograph>) 5356 0x6488 撈 (<CJK Ideograph>) 5357 0x64BC 撼 (<CJK Ideograph>) 5358 0x64DA 據 (<CJK Ideograph>) 5359 0x64D2 擒 (<CJK Ideograph>) 5360 0x64C5 擅 (<CJK Ideograph>) 5361 0x64C7 擇 (<CJK Ideograph>) 5362 0x64BB 撻 (<CJK Ideograph>) 5363 0x64D8 擘 (<CJK Ideograph>) 5364 0x64C2 擂 (<CJK Ideograph>) 5365 0x64F1 擱 (<CJK Ideograph>) 5366 0x64E7 擧 (<CJK Ideograph>) 5367 0x8209 舉 (<CJK Ideograph>) 5368 0x64E0 擠 (<CJK Ideograph>) 5369 0x64E1 擡 (<CJK Ideograph>) 5370 0x62AC 抬 (<CJK Ideograph>) 5371 0x64E3 擣 (<CJK Ideograph>) 5372 0x64EF 擯 (<CJK Ideograph>) 5373 0x652C 攬 (<CJK Ideograph>) 5374 0x64F6 擶 (<CJK Ideograph>) 5375 0x64F4 擴 (<CJK Ideograph>) 5376 0x64F2 擲 (<CJK Ideograph>) 5377 0x64FA 擺 (<CJK Ideograph>) 5378 0x6500 攀 (<CJK Ideograph>) 5379 0x64FD 擽 (<CJK Ideograph>) 5380 0x6518 攘 (<CJK Ideograph>) 5381 0x651C 攜 (<CJK Ideograph>) 5382 0x6505 攅 (<CJK Ideograph>) 5383 0x6524 攤 (<CJK Ideograph>) 5384 0x6523 攣 (<CJK Ideograph>) 5385 0x652B 攫 (<CJK Ideograph>) 5386 0x6534 攴 (<CJK Ideograph>) 5387 0x6535 攵 (<CJK Ideograph>) 5388 0x6537 攷 (<CJK Ideograph>) 5389 0x6536 收 (<CJK Ideograph>) 5390 0x6538 攸 (<CJK Ideograph>) 5391 0x754B 畋 (<CJK Ideograph>) 5392 0x6548 效 (<CJK Ideograph>) 5393 0x6556 敖 (<CJK Ideograph>) 5394 0x6555 敕 (<CJK Ideograph>) 5395 0x654D 敍 (<CJK Ideograph>) 5396 0x6558 敘 (<CJK Ideograph>) 5397 0x655E 敞 (<CJK Ideograph>) 5398 0x655D 敝 (<CJK Ideograph>) 5399 0x6572 敲 (<CJK Ideograph>) 5400 0x6578 數 (<CJK Ideograph>) 5401 0x6582 斂 (<CJK Ideograph>) 5402 0x6583 斃 (<CJK Ideograph>) 5403 0x8B8A 變 (<CJK Ideograph>) 5404 0x659B 斛 (<CJK Ideograph>) 5405 0x659F 斟 (<CJK Ideograph>) 5406 0x65AB 斫 (<CJK Ideograph>) 5407 0x65B7 斷 (<CJK Ideograph>) 5408 0x65C3 旃 (<CJK Ideograph>) 5409 0x65C6 旆 (<CJK Ideograph>) 5410 0x65C1 旁 (<CJK Ideograph>) 5411 0x65C4 旄 (<CJK Ideograph>) 5412 0x65CC 旌 (<CJK Ideograph>) 5413 0x65D2 旒 (<CJK Ideograph>) 5414 0x65DB 旛 (<CJK Ideograph>) 5415 0x65D9 旙 (<CJK Ideograph>) 5416 0x65E0 无 (<CJK Ideograph>) 5417 0x65E1 旡 (<CJK Ideograph>) 5418 0x65F1 旱 (<CJK Ideograph>) 5419 0x6772 杲 (<CJK Ideograph>) 5420 0x660A 昊 (<CJK Ideograph>) 5421 0x6603 昃 (<CJK Ideograph>) 5422 0x65FB 旻 (<CJK Ideograph>) 5423 0x6773 杳 (<CJK Ideograph>) 5424 0x6635 昵 (<CJK Ideograph>) 5425 0x6636 昶 (<CJK Ideograph>) 5426 0x6634 昴 (<CJK Ideograph>) 5427 0x661C 昜 (<CJK Ideograph>) 5428 0x664F 晏 (<CJK Ideograph>) 5429 0x6644 晄 (<CJK Ideograph>) 5430 0x6649 晉 (<CJK Ideograph>) 5431 0x6641 晁 (<CJK Ideograph>) 5432 0x665E 晞 (<CJK Ideograph>) 5433 0x665D 晝 (<CJK Ideograph>) 5434 0x6664 晤 (<CJK Ideograph>) 5435 0x6667 晧 (<CJK Ideograph>) 5436 0x6668 晨 (<CJK Ideograph>) 5437 0x665F 晟 (<CJK Ideograph>) 5438 0x6662 晢 (<CJK Ideograph>) 5439 0x6670 晰 (<CJK Ideograph>) 5440 0x6683 暃 (<CJK Ideograph>) 5441 0x6688 暈 (<CJK Ideograph>) 5442 0x668E 暎 (<CJK Ideograph>) 5443 0x6689 暉 (<CJK Ideograph>) 5444 0x6684 暄 (<CJK Ideograph>) 5445 0x6698 暘 (<CJK Ideograph>) 5446 0x669D 暝 (<CJK Ideograph>) 5447 0x66C1 曁 (<CJK Ideograph>) 5448 0x66B9 暹 (<CJK Ideograph>) 5449 0x66C9 曉 (<CJK Ideograph>) 5450 0x66BE 暾 (<CJK Ideograph>) 5451 0x66BC 暼 (<CJK Ideograph>) 5452 0x66C4 曄 (<CJK Ideograph>) 5453 0x66B8 暸 (<CJK Ideograph>) 5454 0x66D6 曖 (<CJK Ideograph>) 5455 0x66DA 曚 (<CJK Ideograph>) 5456 0x66E0 曠 (<CJK Ideograph>) 5457 0x663F 昿 (<CJK Ideograph>) 5458 0x66E6 曦 (<CJK Ideograph>) 5459 0x66E9 曩 (<CJK Ideograph>) 5460 0x66F0 曰 (<CJK Ideograph>) 5461 0x66F5 曵 (<CJK Ideograph>) 5462 0x66F7 曷 (<CJK Ideograph>) 5463 0x670F 朏 (<CJK Ideograph>) 5464 0x6716 朖 (<CJK Ideograph>) 5465 0x671E 朞 (<CJK Ideograph>) 5466 0x6726 朦 (<CJK Ideograph>) 5467 0x6727 朧 (<CJK Ideograph>) 5468 0x9738 霸 (<CJK Ideograph>) 5469 0x672E 朮 (<CJK Ideograph>) 5470 0x673F 朿 (<CJK Ideograph>) 5471 0x6736 朶 (<CJK Ideograph>) 5472 0x6741 杁 (<CJK Ideograph>) 5473 0x6738 朸 (<CJK Ideograph>) 5474 0x6737 朷 (<CJK Ideograph>) 5475 0x6746 杆 (<CJK Ideograph>) 5476 0x675E 杞 (<CJK Ideograph>) 5477 0x6760 杠 (<CJK Ideograph>) 5478 0x6759 杙 (<CJK Ideograph>) 5479 0x6763 杣 (<CJK Ideograph>) 5480 0x6764 杤 (<CJK Ideograph>) 5481 0x6789 枉 (<CJK Ideograph>) 5482 0x6770 杰 (<CJK Ideograph>) 5483 0x67A9 枩 (<CJK Ideograph>) 5484 0x677C 杼 (<CJK Ideograph>) 5485 0x676A 杪 (<CJK Ideograph>) 5486 0x678C 枌 (<CJK Ideograph>) 5487 0x678B 枋 (<CJK Ideograph>) 5488 0x67A6 枦 (<CJK Ideograph>) 5489 0x67A1 枡 (<CJK Ideograph>) 5490 0x6785 枅 (<CJK Ideograph>) 5491 0x67B7 枷 (<CJK Ideograph>) 5492 0x67EF 柯 (<CJK Ideograph>) 5493 0x67B4 枴 (<CJK Ideograph>) 5494 0x67EC 柬 (<CJK Ideograph>) 5495 0x67B3 枳 (<CJK Ideograph>) 5496 0x67E9 柩 (<CJK Ideograph>) 5497 0x67B8 枸 (<CJK Ideograph>) 5498 0x67E4 柤 (<CJK Ideograph>) 5499 0x67DE 柞 (<CJK Ideograph>) 5500 0x67DD 柝 (<CJK Ideograph>) 5501 0x67E2 柢 (<CJK Ideograph>) 5502 0x67EE 柮 (<CJK Ideograph>) 5503 0x67B9 枹 (<CJK Ideograph>) 5504 0x67CE 柎 (<CJK Ideograph>) 5505 0x67C6 柆 (<CJK Ideograph>) 5506 0x67E7 柧 (<CJK Ideograph>) 5507 0x6A9C 檜 (<CJK Ideograph>) 5508 0x681E 栞 (<CJK Ideograph>) 5509 0x6846 框 (<CJK Ideograph>) 5510 0x6829 栩 (<CJK Ideograph>) 5511 0x6840 桀 (<CJK Ideograph>) 5512 0x684D 桍 (<CJK Ideograph>) 5513 0x6832 栲 (<CJK Ideograph>) 5514 0x684E 桎 (<CJK Ideograph>) 5515 0x68B3 梳 (<CJK Ideograph>) 5516 0x682B 栫 (<CJK Ideograph>) 5517 0x6859 桙 (<CJK Ideograph>) 5518 0x6863 档 (<CJK Ideograph>) 5519 0x6877 桷 (<CJK Ideograph>) 5520 0x687F 桿 (<CJK Ideograph>) 5521 0x689F 梟 (<CJK Ideograph>) 5522 0x688F 梏 (<CJK Ideograph>) 5523 0x68AD 梭 (<CJK Ideograph>) 5524 0x6894 梔 (<CJK Ideograph>) 5525 0x689D 條 (<CJK Ideograph>) 5526 0x689B 梛 (<CJK Ideograph>) 5527 0x6883 梃 (<CJK Ideograph>) 5528 0x6AAE 檮 (<CJK Ideograph>) 5529 0x68B9 梹 (<CJK Ideograph>) 5530 0x6874 桴 (<CJK Ideograph>) 5531 0x68B5 梵 (<CJK Ideograph>) 5532 0x68A0 梠 (<CJK Ideograph>) 5533 0x68BA 梺 (<CJK Ideograph>) 5534 0x690F 椏 (<CJK Ideograph>) 5535 0x688D 梍 (<CJK Ideograph>) 5536 0x687E 桾 (<CJK Ideograph>) 5537 0x6901 椁 (<CJK Ideograph>) 5538 0x68CA 棊 (<CJK Ideograph>) 5539 0x6908 椈 (<CJK Ideograph>) 5540 0x68D8 棘 (<CJK Ideograph>) 5541 0x6922 椢 (<CJK Ideograph>) 5542 0x6926 椦 (<CJK Ideograph>) 5543 0x68E1 棡 (<CJK Ideograph>) 5544 0x690C 椌 (<CJK Ideograph>) 5545 0x68CD 棍 (<CJK Ideograph>) 5546 0x68D4 棔 (<CJK Ideograph>) 5547 0x68E7 棧 (<CJK Ideograph>) 5548 0x68D5 棕 (<CJK Ideograph>) 5549 0x6936 椶 (<CJK Ideograph>) 5550 0x6912 椒 (<CJK Ideograph>) 5551 0x6904 椄 (<CJK Ideograph>) 5552 0x68D7 棗 (<CJK Ideograph>) 5553 0x68E3 棣 (<CJK Ideograph>) 5554 0x6925 椥 (<CJK Ideograph>) 5555 0x68F9 棹 (<CJK Ideograph>) 5556 0x68E0 棠 (<CJK Ideograph>) 5557 0x68EF 棯 (<CJK Ideograph>) 5558 0x6928 椨 (<CJK Ideograph>) 5559 0x692A 椪 (<CJK Ideograph>) 5560 0x691A 椚 (<CJK Ideograph>) 5561 0x6923 椣 (<CJK Ideograph>) 5562 0x6921 椡 (<CJK Ideograph>) 5563 0x68C6 棆 (<CJK Ideograph>) 5564 0x6979 楹 (<CJK Ideograph>) 5565 0x6977 楷 (<CJK Ideograph>) 5566 0x695C 楜 (<CJK Ideograph>) 5567 0x6978 楸 (<CJK Ideograph>) 5568 0x696B 楫 (<CJK Ideograph>) 5569 0x6954 楔 (<CJK Ideograph>) 5570 0x697E 楾 (<CJK Ideograph>) 5571 0x696E 楮 (<CJK Ideograph>) 5572 0x6939 椹 (<CJK Ideograph>) 5573 0x6974 楴 (<CJK Ideograph>) 5574 0x693D 椽 (<CJK Ideograph>) 5575 0x6959 楙 (<CJK Ideograph>) 5576 0x6930 椰 (<CJK Ideograph>) 5577 0x6961 楡 (<CJK Ideograph>) 5578 0x695E 楞 (<CJK Ideograph>) 5579 0x695D 楝 (<CJK Ideograph>) 5580 0x6981 榁 (<CJK Ideograph>) 5581 0x696A 楪 (<CJK Ideograph>) 5582 0x69B2 榲 (<CJK Ideograph>) 5583 0x69AE 榮 (<CJK Ideograph>) 5584 0x69D0 槐 (<CJK Ideograph>) 5585 0x69BF 榿 (<CJK Ideograph>) 5586 0x69C1 槁 (<CJK Ideograph>) 5587 0x69D3 槓 (<CJK Ideograph>) 5588 0x69BE 榾 (<CJK Ideograph>) 5589 0x69CE 槎 (<CJK Ideograph>) 5590 0x5BE8 寨 (<CJK Ideograph>) 5591 0x69CA 槊 (<CJK Ideograph>) 5592 0x69DD 槝 (<CJK Ideograph>) 5593 0x69BB 榻 (<CJK Ideograph>) 5594 0x69C3 槃 (<CJK Ideograph>) 5595 0x69A7 榧 (<CJK Ideograph>) 5596 0x6A2E 樮 (<CJK Ideograph>) 5597 0x6991 榑 (<CJK Ideograph>) 5598 0x69A0 榠 (<CJK Ideograph>) 5599 0x699C 榜 (<CJK Ideograph>) 5600 0x6995 榕 (<CJK Ideograph>) 5601 0x69B4 榴 (<CJK Ideograph>) 5602 0x69DE 槞 (<CJK Ideograph>) 5603 0x69E8 槨 (<CJK Ideograph>) 5604 0x6A02 樂 (<CJK Ideograph>) 5605 0x6A1B 樛 (<CJK Ideograph>) 5606 0x69FF 槿 (<CJK Ideograph>) 5607 0x6B0A 權 (<CJK Ideograph>) 5608 0x69F9 槹 (<CJK Ideograph>) 5609 0x69F2 槲 (<CJK Ideograph>) 5610 0x69E7 槧 (<CJK Ideograph>) 5611 0x6A05 樅 (<CJK Ideograph>) 5612 0x69B1 榱 (<CJK Ideograph>) 5613 0x6A1E 樞 (<CJK Ideograph>) 5614 0x69ED 槭 (<CJK Ideograph>) 5615 0x6A14 樔 (<CJK Ideograph>) 5616 0x69EB 槫 (<CJK Ideograph>) 5617 0x6A0A 樊 (<CJK Ideograph>) 5618 0x6A12 樒 (<CJK Ideograph>) 5619 0x6AC1 櫁 (<CJK Ideograph>) 5620 0x6A23 樣 (<CJK Ideograph>) 5621 0x6A13 樓 (<CJK Ideograph>) 5622 0x6A44 橄 (<CJK Ideograph>) 5623 0x6A0C 樌 (<CJK Ideograph>) 5624 0x6A72 橲 (<CJK Ideograph>) 5625 0x6A36 樶 (<CJK Ideograph>) 5626 0x6A78 橸 (<CJK Ideograph>) 5627 0x6A47 橇 (<CJK Ideograph>) 5628 0x6A62 橢 (<CJK Ideograph>) 5629 0x6A59 橙 (<CJK Ideograph>) 5630 0x6A66 橦 (<CJK Ideograph>) 5631 0x6A48 橈 (<CJK Ideograph>) 5632 0x6A38 樸 (<CJK Ideograph>) 5633 0x6A22 樢 (<CJK Ideograph>) 5634 0x6A90 檐 (<CJK Ideograph>) 5635 0x6A8D 檍 (<CJK Ideograph>) 5636 0x6AA0 檠 (<CJK Ideograph>) 5637 0x6A84 檄 (<CJK Ideograph>) 5638 0x6AA2 檢 (<CJK Ideograph>) 5639 0x6AA3 檣 (<CJK Ideograph>) 5640 0x6A97 檗 (<CJK Ideograph>) 5641 0x8617 蘗 (<CJK Ideograph>) 5642 0x6ABB 檻 (<CJK Ideograph>) 5643 0x6AC3 櫃 (<CJK Ideograph>) 5644 0x6AC2 櫂 (<CJK Ideograph>) 5645 0x6AB8 檸 (<CJK Ideograph>) 5646 0x6AB3 檳 (<CJK Ideograph>) 5647 0x6AAC 檬 (<CJK Ideograph>) 5648 0x6ADE 櫞 (<CJK Ideograph>) 5649 0x6AD1 櫑 (<CJK Ideograph>) 5650 0x6ADF 櫟 (<CJK Ideograph>) 5651 0x6AAA 檪 (<CJK Ideograph>) 5652 0x6ADA 櫚 (<CJK Ideograph>) 5653 0x6AEA 櫪 (<CJK Ideograph>) 5654 0x6AFB 櫻 (<CJK Ideograph>) 5655 0x6B05 欅 (<CJK Ideograph>) 5656 0x8616 蘖 (<CJK Ideograph>) 5657 0x6AFA 櫺 (<CJK Ideograph>) 5658 0x6B12 欒 (<CJK Ideograph>) 5659 0x6B16 欖 (<CJK Ideograph>) 5660 0x9B31 鬱 (<CJK Ideograph>) 5661 0x6B1F 欟 (<CJK Ideograph>) 5662 0x6B38 欸 (<CJK Ideograph>) 5663 0x6B37 欷 (<CJK Ideograph>) 5664 0x76DC 盜 (<CJK Ideograph>) 5665 0x6B39 欹 (<CJK Ideograph>) 5666 0x98EE 飮 (<CJK Ideograph>) 5667 0x6B47 歇 (<CJK Ideograph>) 5668 0x6B43 歃 (<CJK Ideograph>) 5669 0x6B49 歉 (<CJK Ideograph>) 5670 0x6B50 歐 (<CJK Ideograph>) 5671 0x6B59 歙 (<CJK Ideograph>) 5672 0x6B54 歔 (<CJK Ideograph>) 5673 0x6B5B 歛 (<CJK Ideograph>) 5674 0x6B5F 歟 (<CJK Ideograph>) 5675 0x6B61 歡 (<CJK Ideograph>) 5676 0x6B78 歸 (<CJK Ideograph>) 5677 0x6B79 歹 (<CJK Ideograph>) 5678 0x6B7F 歿 (<CJK Ideograph>) 5679 0x6B80 殀 (<CJK Ideograph>) 5680 0x6B84 殄 (<CJK Ideograph>) 5681 0x6B83 殃 (<CJK Ideograph>) 5682 0x6B8D 殍 (<CJK Ideograph>) 5683 0x6B98 殘 (<CJK Ideograph>) 5684 0x6B95 殕 (<CJK Ideograph>) 5685 0x6B9E 殞 (<CJK Ideograph>) 5686 0x6BA4 殤 (<CJK Ideograph>) 5687 0x6BAA 殪 (<CJK Ideograph>) 5688 0x6BAB 殫 (<CJK Ideograph>) 5689 0x6BAF 殯 (<CJK Ideograph>) 5690 0x6BB2 殲 (<CJK Ideograph>) 5691 0x6BB1 殱 (<CJK Ideograph>) 5692 0x6BB3 殳 (<CJK Ideograph>) 5693 0x6BB7 殷 (<CJK Ideograph>) 5694 0x6BBC 殼 (<CJK Ideograph>) 5695 0x6BC6 毆 (<CJK Ideograph>) 5696 0x6BCB 毋 (<CJK Ideograph>) 5697 0x6BD3 毓 (<CJK Ideograph>) 5698 0x6BDF 毟 (<CJK Ideograph>) 5699 0x6BEC 毬 (<CJK Ideograph>) 5700 0x6BEB 毫 (<CJK Ideograph>) 5701 0x6BF3 毳 (<CJK Ideograph>) 5702 0x6BEF 毯 (<CJK Ideograph>) 5703 0x9EBE 麾 (<CJK Ideograph>) 5704 0x6C08 氈 (<CJK Ideograph>) 5705 0x6C13 氓 (<CJK Ideograph>) 5706 0x6C14 气 (<CJK Ideograph>) 5707 0x6C1B 氛 (<CJK Ideograph>) 5708 0x6C24 氤 (<CJK Ideograph>) 5709 0x6C23 氣 (<CJK Ideograph>) 5710 0x6C5E 汞 (<CJK Ideograph>) 5711 0x6C55 汕 (<CJK Ideograph>) 5712 0x6C62 汢 (<CJK Ideograph>) 5713 0x6C6A 汪 (<CJK Ideograph>) 5714 0x6C82 沂 (<CJK Ideograph>) 5715 0x6C8D 沍 (<CJK Ideograph>) 5716 0x6C9A 沚 (<CJK Ideograph>) 5717 0x6C81 沁 (<CJK Ideograph>) 5718 0x6C9B 沛 (<CJK Ideograph>) 5719 0x6C7E 汾 (<CJK Ideograph>) 5720 0x6C68 汨 (<CJK Ideograph>) 5721 0x6C73 汳 (<CJK Ideograph>) 5722 0x6C92 沒 (<CJK Ideograph>) 5723 0x6C90 沐 (<CJK Ideograph>) 5724 0x6CC4 泄 (<CJK Ideograph>) 5725 0x6CF1 泱 (<CJK Ideograph>) 5726 0x6CD3 泓 (<CJK Ideograph>) 5727 0x6CBD 沽 (<CJK Ideograph>) 5728 0x6CD7 泗 (<CJK Ideograph>) 5729 0x6CC5 泅 (<CJK Ideograph>) 5730 0x6CDD 泝 (<CJK Ideograph>) 5731 0x6CAE 沮 (<CJK Ideograph>) 5732 0x6CB1 沱 (<CJK Ideograph>) 5733 0x6CBE 沾 (<CJK Ideograph>) 5734 0x6CBA 沺 (<CJK Ideograph>) 5735 0x6CDB 泛 (<CJK Ideograph>) 5736 0x6CEF 泯 (<CJK Ideograph>) 5737 0x6CD9 泙 (<CJK Ideograph>) 5738 0x6CEA 泪 (<CJK Ideograph>) 5739 0x6D1F 洟 (<CJK Ideograph>) 5740 0x884D 衍 (<CJK Ideograph>) 5741 0x6D36 洶 (<CJK Ideograph>) 5742 0x6D2B 洫 (<CJK Ideograph>) 5743 0x6D3D 洽 (<CJK Ideograph>) 5744 0x6D38 洸 (<CJK Ideograph>) 5745 0x6D19 洙 (<CJK Ideograph>) 5746 0x6D35 洵 (<CJK Ideograph>) 5747 0x6D33 洳 (<CJK Ideograph>) 5748 0x6D12 洒 (<CJK Ideograph>) 5749 0x6D0C 洌 (<CJK Ideograph>) 5750 0x6D63 浣 (<CJK Ideograph>) 5751 0x6D93 涓 (<CJK Ideograph>) 5752 0x6D64 浤 (<CJK Ideograph>) 5753 0x6D5A 浚 (<CJK Ideograph>) 5754 0x6D79 浹 (<CJK Ideograph>) 5755 0x6D59 浙 (<CJK Ideograph>) 5756 0x6D8E 涎 (<CJK Ideograph>) 5757 0x6D95 涕 (<CJK Ideograph>) 5758 0x6FE4 濤 (<CJK Ideograph>) 5759 0x6D85 涅 (<CJK Ideograph>) 5760 0x6DF9 淹 (<CJK Ideograph>) 5761 0x6E15 渕 (<CJK Ideograph>) 5762 0x6E0A 渊 (<CJK Ideograph>) 5763 0x6DB5 涵 (<CJK Ideograph>) 5764 0x6DC7 淇 (<CJK Ideograph>) 5765 0x6DE6 淦 (<CJK Ideograph>) 5766 0x6DB8 涸 (<CJK Ideograph>) 5767 0x6DC6 淆 (<CJK Ideograph>) 5768 0x6DEC 淬 (<CJK Ideograph>) 5769 0x6DDE 淞 (<CJK Ideograph>) 5770 0x6DCC 淌 (<CJK Ideograph>) 5771 0x6DE8 淨 (<CJK Ideograph>) 5772 0x6DD2 淒 (<CJK Ideograph>) 5773 0x6DC5 淅 (<CJK Ideograph>) 5774 0x6DFA 淺 (<CJK Ideograph>) 5775 0x6DD9 淙 (<CJK Ideograph>) 5776 0x6DE4 淤 (<CJK Ideograph>) 5777 0x6DD5 淕 (<CJK Ideograph>) 5778 0x6DEA 淪 (<CJK Ideograph>) 5779 0x6DEE 淮 (<CJK Ideograph>) 5780 0x6E2D 渭 (<CJK Ideograph>) 5781 0x6E6E 湮 (<CJK Ideograph>) 5782 0x6E2E 渮 (<CJK Ideograph>) 5783 0x6E19 渙 (<CJK Ideograph>) 5784 0x6E72 湲 (<CJK Ideograph>) 5785 0x6E5F 湟 (<CJK Ideograph>) 5786 0x6E3E 渾 (<CJK Ideograph>) 5787 0x6E23 渣 (<CJK Ideograph>) 5788 0x6E6B 湫 (<CJK Ideograph>) 5789 0x6E2B 渫 (<CJK Ideograph>) 5790 0x6E76 湶 (<CJK Ideograph>) 5791 0x6E4D 湍 (<CJK Ideograph>) 5792 0x6E1F 渟 (<CJK Ideograph>) 5793 0x6E43 湃 (<CJK Ideograph>) 5794 0x6E3A 渺 (<CJK Ideograph>) 5795 0x6E4E 湎 (<CJK Ideograph>) 5796 0x6E24 渤 (<CJK Ideograph>) 5797 0x6EFF 滿 (<CJK Ideograph>) 5798 0x6E1D 渝 (<CJK Ideograph>) 5799 0x6E38 游 (<CJK Ideograph>) 5800 0x6E82 溂 (<CJK Ideograph>) 5801 0x6EAA 溪 (<CJK Ideograph>) 5802 0x6E98 溘 (<CJK Ideograph>) 5803 0x6EC9 滉 (<CJK Ideograph>) 5804 0x6EB7 溷 (<CJK Ideograph>) 5805 0x6ED3 滓 (<CJK Ideograph>) 5806 0x6EBD 溽 (<CJK Ideograph>) 5807 0x6EAF 溯 (<CJK Ideograph>) 5808 0x6EC4 滄 (<CJK Ideograph>) 5809 0x6EB2 溲 (<CJK Ideograph>) 5810 0x6ED4 滔 (<CJK Ideograph>) 5811 0x6ED5 滕 (<CJK Ideograph>) 5812 0x6E8F 溏 (<CJK Ideograph>) 5813 0x6EA5 溥 (<CJK Ideograph>) 5814 0x6EC2 滂 (<CJK Ideograph>) 5815 0x6E9F 溟 (<CJK Ideograph>) 5816 0x6F41 潁 (<CJK Ideograph>) 5817 0x6F11 漑 (<CJK Ideograph>) 5818 0x704C 灌 (<CJK Ideograph>) 5819 0x6EEC 滬 (<CJK Ideograph>) 5820 0x6EF8 滸 (<CJK Ideograph>) 5821 0x6EFE 滾 (<CJK Ideograph>) 5822 0x6F3F 漿 (<CJK Ideograph>) 5823 0x6EF2 滲 (<CJK Ideograph>) 5824 0x6F31 漱 (<CJK Ideograph>) 5825 0x6EEF 滯 (<CJK Ideograph>) 5826 0x6F32 漲 (<CJK Ideograph>) 5827 0x6ECC 滌 (<CJK Ideograph>) 5828 0x6F3E 漾 (<CJK Ideograph>) 5829 0x6F13 漓 (<CJK Ideograph>) 5830 0x6EF7 滷 (<CJK Ideograph>) 5831 0x6F86 澆 (<CJK Ideograph>) 5832 0x6F7A 潺 (<CJK Ideograph>) 5833 0x6F78 潸 (<CJK Ideograph>) 5834 0x6F81 澁 (<CJK Ideograph>) 5835 0x6F80 澀 (<CJK Ideograph>) 5836 0x6F6F 潯 (<CJK Ideograph>) 5837 0x6F5B 潛 (<CJK Ideograph>) 5838 0x6FF3 濳 (<CJK Ideograph>) 5839 0x6F6D 潭 (<CJK Ideograph>) 5840 0x6F82 澂 (<CJK Ideograph>) 5841 0x6F7C 潼 (<CJK Ideograph>) 5842 0x6F58 潘 (<CJK Ideograph>) 5843 0x6F8E 澎 (<CJK Ideograph>) 5844 0x6F91 澑 (<CJK Ideograph>) 5845 0x6FC2 濂 (<CJK Ideograph>) 5846 0x6F66 潦 (<CJK Ideograph>) 5847 0x6FB3 澳 (<CJK Ideograph>) 5848 0x6FA3 澣 (<CJK Ideograph>) 5849 0x6FA1 澡 (<CJK Ideograph>) 5850 0x6FA4 澤 (<CJK Ideograph>) 5851 0x6FB9 澹 (<CJK Ideograph>) 5852 0x6FC6 濆 (<CJK Ideograph>) 5853 0x6FAA 澪 (<CJK Ideograph>) 5854 0x6FDF 濟 (<CJK Ideograph>) 5855 0x6FD5 濕 (<CJK Ideograph>) 5856 0x6FEC 濬 (<CJK Ideograph>) 5857 0x6FD4 濔 (<CJK Ideograph>) 5858 0x6FD8 濘 (<CJK Ideograph>) 5859 0x6FF1 濱 (<CJK Ideograph>) 5860 0x6FEE 濮 (<CJK Ideograph>) 5861 0x6FDB 濛 (<CJK Ideograph>) 5862 0x7009 瀉 (<CJK Ideograph>) 5863 0x700B 瀋 (<CJK Ideograph>) 5864 0x6FFA 濺 (<CJK Ideograph>) 5865 0x7011 瀑 (<CJK Ideograph>) 5866 0x7001 瀁 (<CJK Ideograph>) 5867 0x700F 瀏 (<CJK Ideograph>) 5868 0x6FFE 濾 (<CJK Ideograph>) 5869 0x701B 瀛 (<CJK Ideograph>) 5870 0x701A 瀚 (<CJK Ideograph>) 5871 0x6F74 潴 (<CJK Ideograph>) 5872 0x701D 瀝 (<CJK Ideograph>) 5873 0x7018 瀘 (<CJK Ideograph>) 5874 0x701F 瀟 (<CJK Ideograph>) 5875 0x7030 瀰 (<CJK Ideograph>) 5876 0x703E 瀾 (<CJK Ideograph>) 5877 0x7032 瀲 (<CJK Ideograph>) 5878 0x7051 灑 (<CJK Ideograph>) 5879 0x7063 灣 (<CJK Ideograph>) 5880 0x7099 炙 (<CJK Ideograph>) 5881 0x7092 炒 (<CJK Ideograph>) 5882 0x70AF 炯 (<CJK Ideograph>) 5883 0x70F1 烱 (<CJK Ideograph>) 5884 0x70AC 炬 (<CJK Ideograph>) 5885 0x70B8 炸 (<CJK Ideograph>) 5886 0x70B3 炳 (<CJK Ideograph>) 5887 0x70AE 炮 (<CJK Ideograph>) 5888 0x70DF 烟 (<CJK Ideograph>) 5889 0x70CB 烋 (<CJK Ideograph>) 5890 0x70DD 烝 (<CJK Ideograph>) 5891 0x70D9 烙 (<CJK Ideograph>) 5892 0x7109 焉 (<CJK Ideograph>) 5893 0x70FD 烽 (<CJK Ideograph>) 5894 0x711C 焜 (<CJK Ideograph>) 5895 0x7119 焙 (<CJK Ideograph>) 5896 0x7165 煥 (<CJK Ideograph>) 5897 0x7155 煕 (<CJK Ideograph>) 5898 0x7188 熈 (<CJK Ideograph>) 5899 0x7166 煦 (<CJK Ideograph>) 5900 0x7162 煢 (<CJK Ideograph>) 5901 0x714C 煌 (<CJK Ideograph>) 5902 0x7156 煖 (<CJK Ideograph>) 5903 0x716C 煬 (<CJK Ideograph>) 5904 0x718F 熏 (<CJK Ideograph>) 5905 0x71FB 燻 (<CJK Ideograph>) 5906 0x7184 熄 (<CJK Ideograph>) 5907 0x7195 熕 (<CJK Ideograph>) 5908 0x71A8 熨 (<CJK Ideograph>) 5909 0x71AC 熬 (<CJK Ideograph>) 5910 0x71D7 燗 (<CJK Ideograph>) 5911 0x71B9 熹 (<CJK Ideograph>) 5912 0x71BE 熾 (<CJK Ideograph>) 5913 0x71D2 燒 (<CJK Ideograph>) 5914 0x71C9 燉 (<CJK Ideograph>) 5915 0x71D4 燔 (<CJK Ideograph>) 5916 0x71CE 燎 (<CJK Ideograph>) 5917 0x71E0 燠 (<CJK Ideograph>) 5918 0x71EC 燬 (<CJK Ideograph>) 5919 0x71E7 燧 (<CJK Ideograph>) 5920 0x71F5 燵 (<CJK Ideograph>) 5921 0x71FC 燼 (<CJK Ideograph>) 5922 0x71F9 燹 (<CJK Ideograph>) 5923 0x71FF 燿 (<CJK Ideograph>) 5924 0x720D 爍 (<CJK Ideograph>) 5925 0x7210 爐 (<CJK Ideograph>) 5926 0x721B 爛 (<CJK Ideograph>) 5927 0x7228 爨 (<CJK Ideograph>) 5928 0x722D 爭 (<CJK Ideograph>) 5929 0x722C 爬 (<CJK Ideograph>) 5930 0x7230 爰 (<CJK Ideograph>) 5931 0x7232 爲 (<CJK Ideograph>) 5932 0x723B 爻 (<CJK Ideograph>) 5933 0x723C 爼 (<CJK Ideograph>) 5934 0x723F 爿 (<CJK Ideograph>) 5935 0x7240 牀 (<CJK Ideograph>) 5936 0x7246 牆 (<CJK Ideograph>) 5937 0x724B 牋 (<CJK Ideograph>) 5938 0x7258 牘 (<CJK Ideograph>) 5939 0x7274 牴 (<CJK Ideograph>) 5940 0x727E 牾 (<CJK Ideograph>) 5941 0x7282 犂 (<CJK Ideograph>) 5942 0x7281 犁 (<CJK Ideograph>) 5943 0x7287 犇 (<CJK Ideograph>) 5944 0x7292 犒 (<CJK Ideograph>) 5945 0x7296 犖 (<CJK Ideograph>) 5946 0x72A2 犢 (<CJK Ideograph>) 5947 0x72A7 犧 (<CJK Ideograph>) 5948 0x72B9 犹 (<CJK Ideograph>) 5949 0x72B2 犲 (<CJK Ideograph>) 5950 0x72C3 狃 (<CJK Ideograph>) 5951 0x72C6 狆 (<CJK Ideograph>) 5952 0x72C4 狄 (<CJK Ideograph>) 5953 0x72CE 狎 (<CJK Ideograph>) 5954 0x72D2 狒 (<CJK Ideograph>) 5955 0x72E2 狢 (<CJK Ideograph>) 5956 0x72E0 狠 (<CJK Ideograph>) 5957 0x72E1 狡 (<CJK Ideograph>) 5958 0x72F9 狹 (<CJK Ideograph>) 5959 0x72F7 狷 (<CJK Ideograph>) 5960 0x500F 倏 (<CJK Ideograph>) 5961 0x7317 猗 (<CJK Ideograph>) 5962 0x730A 猊 (<CJK Ideograph>) 5963 0x731C 猜 (<CJK Ideograph>) 5964 0x7316 猖 (<CJK Ideograph>) 5965 0x731D 猝 (<CJK Ideograph>) 5966 0x7334 猴 (<CJK Ideograph>) 5967 0x732F 猯 (<CJK Ideograph>) 5968 0x7329 猩 (<CJK Ideograph>) 5969 0x7325 猥 (<CJK Ideograph>) 5970 0x733E 猾 (<CJK Ideograph>) 5971 0x734E 獎 (<CJK Ideograph>) 5972 0x734F 獏 (<CJK Ideograph>) 5973 0x9ED8 默 (<CJK Ideograph>) 5974 0x7357 獗 (<CJK Ideograph>) 5975 0x736A 獪 (<CJK Ideograph>) 5976 0x7368 獨 (<CJK Ideograph>) 5977 0x7370 獰 (<CJK Ideograph>) 5978 0x7378 獸 (<CJK Ideograph>) 5979 0x7375 獵 (<CJK Ideograph>) 5980 0x737B 獻 (<CJK Ideograph>) 5981 0x737A 獺 (<CJK Ideograph>) 5982 0x73C8 珈 (<CJK Ideograph>) 5983 0x73B3 玳 (<CJK Ideograph>) 5984 0x73CE 珎 (<CJK Ideograph>) 5985 0x73BB 玻 (<CJK Ideograph>) 5986 0x73C0 珀 (<CJK Ideograph>) 5987 0x73E5 珥 (<CJK Ideograph>) 5988 0x73EE 珮 (<CJK Ideograph>) 5989 0x73DE 珞 (<CJK Ideograph>) 5990 0x74A2 璢 (<CJK Ideograph>) 5991 0x7405 琅 (<CJK Ideograph>) 5992 0x746F 瑯 (<CJK Ideograph>) 5993 0x7425 琥 (<CJK Ideograph>) 5994 0x73F8 珸 (<CJK Ideograph>) 5995 0x7432 琲 (<CJK Ideograph>) 5996 0x743A 琺 (<CJK Ideograph>) 5997 0x7455 瑕 (<CJK Ideograph>) 5998 0x743F 琿 (<CJK Ideograph>) 5999 0x745F 瑟 (<CJK Ideograph>) 6000 0x7459 瑙 (<CJK Ideograph>) 6001 0x7441 瑁 (<CJK Ideograph>) 6002 0x745C 瑜 (<CJK Ideograph>) 6003 0x7469 瑩 (<CJK Ideograph>) 6004 0x7470 瑰 (<CJK Ideograph>) 6005 0x7463 瑣 (<CJK Ideograph>) 6006 0x746A 瑪 (<CJK Ideograph>) 6007 0x7476 瑶 (<CJK Ideograph>) 6008 0x747E 瑾 (<CJK Ideograph>) 6009 0x748B 璋 (<CJK Ideograph>) 6010 0x749E 璞 (<CJK Ideograph>) 6011 0x74A7 璧 (<CJK Ideograph>) 6012 0x74CA 瓊 (<CJK Ideograph>) 6013 0x74CF 瓏 (<CJK Ideograph>) 6014 0x74D4 瓔 (<CJK Ideograph>) 6015 0x73F1 珱 (<CJK Ideograph>) 6016 0x74E0 瓠 (<CJK Ideograph>) 6017 0x74E3 瓣 (<CJK Ideograph>) 6018 0x74E7 瓧 (<CJK Ideograph>) 6019 0x74E9 瓩 (<CJK Ideograph>) 6020 0x74EE 瓮 (<CJK Ideograph>) 6021 0x74F2 瓲 (<CJK Ideograph>) 6022 0x74F0 瓰 (<CJK Ideograph>) 6023 0x74F1 瓱 (<CJK Ideograph>) 6024 0x74F8 瓸 (<CJK Ideograph>) 6025 0x74F7 瓷 (<CJK Ideograph>) 6026 0x7504 甄 (<CJK Ideograph>) 6027 0x7503 甃 (<CJK Ideograph>) 6028 0x7505 甅 (<CJK Ideograph>) 6029 0x750C 甌 (<CJK Ideograph>) 6030 0x750E 甎 (<CJK Ideograph>) 6031 0x750D 甍 (<CJK Ideograph>) 6032 0x7515 甕 (<CJK Ideograph>) 6033 0x7513 甓 (<CJK Ideograph>) 6034 0x751E 甞 (<CJK Ideograph>) 6035 0x7526 甦 (<CJK Ideograph>) 6036 0x752C 甬 (<CJK Ideograph>) 6037 0x753C 甼 (<CJK Ideograph>) 6038 0x7544 畄 (<CJK Ideograph>) 6039 0x754D 畍 (<CJK Ideograph>) 6040 0x754A 畊 (<CJK Ideograph>) 6041 0x7549 畉 (<CJK Ideograph>) 6042 0x755B 畛 (<CJK Ideograph>) 6043 0x7546 畆 (<CJK Ideograph>) 6044 0x755A 畚 (<CJK Ideograph>) 6045 0x7569 畩 (<CJK Ideograph>) 6046 0x7564 畤 (<CJK Ideograph>) 6047 0x7567 畧 (<CJK Ideograph>) 6048 0x756B 畫 (<CJK Ideograph>) 6049 0x756D 畭 (<CJK Ideograph>) 6050 0x7578 畸 (<CJK Ideograph>) 6051 0x7576 當 (<CJK Ideograph>) 6052 0x7586 疆 (<CJK Ideograph>) 6053 0x7587 疇 (<CJK Ideograph>) 6054 0x7574 畴 (<CJK Ideograph>) 6055 0x758A 疊 (<CJK Ideograph>) 6056 0x7589 疉 (<CJK Ideograph>) 6057 0x7582 疂 (<CJK Ideograph>) 6058 0x7594 疔 (<CJK Ideograph>) 6059 0x759A 疚 (<CJK Ideograph>) 6060 0x759D 疝 (<CJK Ideograph>) 6061 0x75A5 疥 (<CJK Ideograph>) 6062 0x75A3 疣 (<CJK Ideograph>) 6063 0x75C2 痂 (<CJK Ideograph>) 6064 0x75B3 疳 (<CJK Ideograph>) 6065 0x75C3 痃 (<CJK Ideograph>) 6066 0x75B5 疵 (<CJK Ideograph>) 6067 0x75BD 疽 (<CJK Ideograph>) 6068 0x75B8 疸 (<CJK Ideograph>) 6069 0x75BC 疼 (<CJK Ideograph>) 6070 0x75B1 疱 (<CJK Ideograph>) 6071 0x75CD 痍 (<CJK Ideograph>) 6072 0x75CA 痊 (<CJK Ideograph>) 6073 0x75D2 痒 (<CJK Ideograph>) 6074 0x75D9 痙 (<CJK Ideograph>) 6075 0x75E3 痣 (<CJK Ideograph>) 6076 0x75DE 痞 (<CJK Ideograph>) 6077 0x75FE 痾 (<CJK Ideograph>) 6078 0x75FF 痿 (<CJK Ideograph>) 6079 0x75FC 痼 (<CJK Ideograph>) 6080 0x7601 瘁 (<CJK Ideograph>) 6081 0x75F0 痰 (<CJK Ideograph>) 6082 0x75FA 痺 (<CJK Ideograph>) 6083 0x75F2 痲 (<CJK Ideograph>) 6084 0x75F3 痳 (<CJK Ideograph>) 6085 0x760B 瘋 (<CJK Ideograph>) 6086 0x760D 瘍 (<CJK Ideograph>) 6087 0x7609 瘉 (<CJK Ideograph>) 6088 0x761F 瘟 (<CJK Ideograph>) 6089 0x7627 瘧 (<CJK Ideograph>) 6090 0x7620 瘠 (<CJK Ideograph>) 6091 0x7621 瘡 (<CJK Ideograph>) 6092 0x7622 瘢 (<CJK Ideograph>) 6093 0x7624 瘤 (<CJK Ideograph>) 6094 0x7634 瘴 (<CJK Ideograph>) 6095 0x7630 瘰 (<CJK Ideograph>) 6096 0x763B 瘻 (<CJK Ideograph>) 6097 0x7647 癇 (<CJK Ideograph>) 6098 0x7648 癈 (<CJK Ideograph>) 6099 0x7646 癆 (<CJK Ideograph>) 6100 0x765C 癜 (<CJK Ideograph>) 6101 0x7658 癘 (<CJK Ideograph>) 6102 0x7661 癡 (<CJK Ideograph>) 6103 0x7662 癢 (<CJK Ideograph>) 6104 0x7668 癨 (<CJK Ideograph>) 6105 0x7669 癩 (<CJK Ideograph>) 6106 0x766A 癪 (<CJK Ideograph>) 6107 0x7667 癧 (<CJK Ideograph>) 6108 0x766C 癬 (<CJK Ideograph>) 6109 0x7670 癰 (<CJK Ideograph>) 6110 0x7672 癲 (<CJK Ideograph>) 6111 0x7676 癶 (<CJK Ideograph>) 6112 0x7678 癸 (<CJK Ideograph>) 6113 0x767C 發 (<CJK Ideograph>) 6114 0x7680 皀 (<CJK Ideograph>) 6115 0x7683 皃 (<CJK Ideograph>) 6116 0x7688 皈 (<CJK Ideograph>) 6117 0x768B 皋 (<CJK Ideograph>) 6118 0x768E 皎 (<CJK Ideograph>) 6119 0x7696 皖 (<CJK Ideograph>) 6120 0x7693 皓 (<CJK Ideograph>) 6121 0x7699 皙 (<CJK Ideograph>) 6122 0x769A 皚 (<CJK Ideograph>) 6123 0x76B0 皰 (<CJK Ideograph>) 6124 0x76B4 皴 (<CJK Ideograph>) 6125 0x76B8 皸 (<CJK Ideograph>) 6126 0x76B9 皹 (<CJK Ideograph>) 6127 0x76BA 皺 (<CJK Ideograph>) 6128 0x76C2 盂 (<CJK Ideograph>) 6129 0x76CD 盍 (<CJK Ideograph>) 6130 0x76D6 盖 (<CJK Ideograph>) 6131 0x76D2 盒 (<CJK Ideograph>) 6132 0x76DE 盞 (<CJK Ideograph>) 6133 0x76E1 盡 (<CJK Ideograph>) 6134 0x76E5 盥 (<CJK Ideograph>) 6135 0x76E7 盧 (<CJK Ideograph>) 6136 0x76EA 盪 (<CJK Ideograph>) 6137 0x862F 蘯 (<CJK Ideograph>) 6138 0x76FB 盻 (<CJK Ideograph>) 6139 0x7708 眈 (<CJK Ideograph>) 6140 0x7707 眇 (<CJK Ideograph>) 6141 0x7704 眄 (<CJK Ideograph>) 6142 0x7729 眩 (<CJK Ideograph>) 6143 0x7724 眤 (<CJK Ideograph>) 6144 0x771E 眞 (<CJK Ideograph>) 6145 0x7725 眥 (<CJK Ideograph>) 6146 0x7726 眦 (<CJK Ideograph>) 6147 0x771B 眛 (<CJK Ideograph>) 6148 0x7737 眷 (<CJK Ideograph>) 6149 0x7738 眸 (<CJK Ideograph>) 6150 0x7747 睇 (<CJK Ideograph>) 6151 0x775A 睚 (<CJK Ideograph>) 6152 0x7768 睨 (<CJK Ideograph>) 6153 0x776B 睫 (<CJK Ideograph>) 6154 0x775B 睛 (<CJK Ideograph>) 6155 0x7765 睥 (<CJK Ideograph>) 6156 0x777F 睿 (<CJK Ideograph>) 6157 0x777E 睾 (<CJK Ideograph>) 6158 0x7779 睹 (<CJK Ideograph>) 6159 0x778E 瞎 (<CJK Ideograph>) 6160 0x778B 瞋 (<CJK Ideograph>) 6161 0x7791 瞑 (<CJK Ideograph>) 6162 0x77A0 瞠 (<CJK Ideograph>) 6163 0x779E 瞞 (<CJK Ideograph>) 6164 0x77B0 瞰 (<CJK Ideograph>) 6165 0x77B6 瞶 (<CJK Ideograph>) 6166 0x77B9 瞹 (<CJK Ideograph>) 6167 0x77BF 瞿 (<CJK Ideograph>) 6168 0x77BC 瞼 (<CJK Ideograph>) 6169 0x77BD 瞽 (<CJK Ideograph>) 6170 0x77BB 瞻 (<CJK Ideograph>) 6171 0x77C7 矇 (<CJK Ideograph>) 6172 0x77CD 矍 (<CJK Ideograph>) 6173 0x77D7 矗 (<CJK Ideograph>) 6174 0x77DA 矚 (<CJK Ideograph>) 6175 0x77DC 矜 (<CJK Ideograph>) 6176 0x77E3 矣 (<CJK Ideograph>) 6177 0x77EE 矮 (<CJK Ideograph>) 6178 0x77FC 矼 (<CJK Ideograph>) 6179 0x780C 砌 (<CJK Ideograph>) 6180 0x7812 砒 (<CJK Ideograph>) 6181 0x7926 礦 (<CJK Ideograph>) 6182 0x7820 砠 (<CJK Ideograph>) 6183 0x792A 礪 (<CJK Ideograph>) 6184 0x7845 硅 (<CJK Ideograph>) 6185 0x788E 碎 (<CJK Ideograph>) 6186 0x7874 硴 (<CJK Ideograph>) 6187 0x7886 碆 (<CJK Ideograph>) 6188 0x787C 硼 (<CJK Ideograph>) 6189 0x789A 碚 (<CJK Ideograph>) 6190 0x788C 碌 (<CJK Ideograph>) 6191 0x78A3 碣 (<CJK Ideograph>) 6192 0x78B5 碵 (<CJK Ideograph>) 6193 0x78AA 碪 (<CJK Ideograph>) 6194 0x78AF 碯 (<CJK Ideograph>) 6195 0x78D1 磑 (<CJK Ideograph>) 6196 0x78C6 磆 (<CJK Ideograph>) 6197 0x78CB 磋 (<CJK Ideograph>) 6198 0x78D4 磔 (<CJK Ideograph>) 6199 0x78BE 碾 (<CJK Ideograph>) 6200 0x78BC 碼 (<CJK Ideograph>) 6201 0x78C5 磅 (<CJK Ideograph>) 6202 0x78CA 磊 (<CJK Ideograph>) 6203 0x78EC 磬 (<CJK Ideograph>) 6204 0x78E7 磧 (<CJK Ideograph>) 6205 0x78DA 磚 (<CJK Ideograph>) 6206 0x78FD 磽 (<CJK Ideograph>) 6207 0x78F4 磴 (<CJK Ideograph>) 6208 0x7907 礇 (<CJK Ideograph>) 6209 0x7912 礒 (<CJK Ideograph>) 6210 0x7911 礑 (<CJK Ideograph>) 6211 0x7919 礙 (<CJK Ideograph>) 6212 0x792C 礬 (<CJK Ideograph>) 6213 0x792B 礫 (<CJK Ideograph>) 6214 0x7940 祀 (<CJK Ideograph>) 6215 0x7960 祠 (<CJK Ideograph>) 6216 0x7957 祗 (<CJK Ideograph>) 6217 0x795F 祟 (<CJK Ideograph>) 6218 0x795A 祚 (<CJK Ideograph>) 6219 0x7955 祕 (<CJK Ideograph>) 6220 0x7953 祓 (<CJK Ideograph>) 6221 0x797A 祺 (<CJK Ideograph>) 6222 0x797F 祿 (<CJK Ideograph>) 6223 0x798A 禊 (<CJK Ideograph>) 6224 0x799D 禝 (<CJK Ideograph>) 6225 0x79A7 禧 (<CJK Ideograph>) 6226 0x9F4B 齋 (<CJK Ideograph>) 6227 0x79AA 禪 (<CJK Ideograph>) 6228 0x79AE 禮 (<CJK Ideograph>) 6229 0x79B3 禳 (<CJK Ideograph>) 6230 0x79B9 禹 (<CJK Ideograph>) 6231 0x79BA 禺 (<CJK Ideograph>) 6232 0x79C9 秉 (<CJK Ideograph>) 6233 0x79D5 秕 (<CJK Ideograph>) 6234 0x79E7 秧 (<CJK Ideograph>) 6235 0x79EC 秬 (<CJK Ideograph>) 6236 0x79E1 秡 (<CJK Ideograph>) 6237 0x79E3 秣 (<CJK Ideograph>) 6238 0x7A08 稈 (<CJK Ideograph>) 6239 0x7A0D 稍 (<CJK Ideograph>) 6240 0x7A18 稘 (<CJK Ideograph>) 6241 0x7A19 稙 (<CJK Ideograph>) 6242 0x7A20 稠 (<CJK Ideograph>) 6243 0x7A1F 稟 (<CJK Ideograph>) 6244 0x7980 禀 (<CJK Ideograph>) 6245 0x7A31 稱 (<CJK Ideograph>) 6246 0x7A3B 稻 (<CJK Ideograph>) 6247 0x7A3E 稾 (<CJK Ideograph>) 6248 0x7A37 稷 (<CJK Ideograph>) 6249 0x7A43 穃 (<CJK Ideograph>) 6250 0x7A57 穗 (<CJK Ideograph>) 6251 0x7A49 穉 (<CJK Ideograph>) 6252 0x7A61 穡 (<CJK Ideograph>) 6253 0x7A62 穢 (<CJK Ideograph>) 6254 0x7A69 穩 (<CJK Ideograph>) 6255 0x9F9D 龝 (<CJK Ideograph>) 6256 0x7A70 穰 (<CJK Ideograph>) 6257 0x7A79 穹 (<CJK Ideograph>) 6258 0x7A7D 穽 (<CJK Ideograph>) 6259 0x7A88 窈 (<CJK Ideograph>) 6260 0x7A97 窗 (<CJK Ideograph>) 6261 0x7A95 窕 (<CJK Ideograph>) 6262 0x7A98 窘 (<CJK Ideograph>) 6263 0x7A96 窖 (<CJK Ideograph>) 6264 0x7AA9 窩 (<CJK Ideograph>) 6265 0x7AC8 竈 (<CJK Ideograph>) 6266 0x7AB0 窰 (<CJK Ideograph>) 6267 0x7AB6 窶 (<CJK Ideograph>) 6268 0x7AC5 竅 (<CJK Ideograph>) 6269 0x7AC4 竄 (<CJK Ideograph>) 6270 0x7ABF 窿 (<CJK Ideograph>) 6271 0x9083 邃 (<CJK Ideograph>) 6272 0x7AC7 竇 (<CJK Ideograph>) 6273 0x7ACA 竊 (<CJK Ideograph>) 6274 0x7ACD 竍 (<CJK Ideograph>) 6275 0x7ACF 竏 (<CJK Ideograph>) 6276 0x7AD5 竕 (<CJK Ideograph>) 6277 0x7AD3 竓 (<CJK Ideograph>) 6278 0x7AD9 站 (<CJK Ideograph>) 6279 0x7ADA 竚 (<CJK Ideograph>) 6280 0x7ADD 竝 (<CJK Ideograph>) 6281 0x7AE1 竡 (<CJK Ideograph>) 6282 0x7AE2 竢 (<CJK Ideograph>) 6283 0x7AE6 竦 (<CJK Ideograph>) 6284 0x7AED 竭 (<CJK Ideograph>) 6285 0x7AF0 竰 (<CJK Ideograph>) 6286 0x7B02 笂 (<CJK Ideograph>) 6287 0x7B0F 笏 (<CJK Ideograph>) 6288 0x7B0A 笊 (<CJK Ideograph>) 6289 0x7B06 笆 (<CJK Ideograph>) 6290 0x7B33 笳 (<CJK Ideograph>) 6291 0x7B18 笘 (<CJK Ideograph>) 6292 0x7B19 笙 (<CJK Ideograph>) 6293 0x7B1E 笞 (<CJK Ideograph>) 6294 0x7B35 笵 (<CJK Ideograph>) 6295 0x7B28 笨 (<CJK Ideograph>) 6296 0x7B36 笶 (<CJK Ideograph>) 6297 0x7B50 筐 (<CJK Ideograph>) 6298 0x7B7A 筺 (<CJK Ideograph>) 6299 0x7B04 笄 (<CJK Ideograph>) 6300 0x7B4D 筍 (<CJK Ideograph>) 6301 0x7B0B 笋 (<CJK Ideograph>) 6302 0x7B4C 筌 (<CJK Ideograph>) 6303 0x7B45 筅 (<CJK Ideograph>) 6304 0x7B75 筵 (<CJK Ideograph>) 6305 0x7B65 筥 (<CJK Ideograph>) 6306 0x7B74 筴 (<CJK Ideograph>) 6307 0x7B67 筧 (<CJK Ideograph>) 6308 0x7B70 筰 (<CJK Ideograph>) 6309 0x7B71 筱 (<CJK Ideograph>) 6310 0x7B6C 筬 (<CJK Ideograph>) 6311 0x7B6E 筮 (<CJK Ideograph>) 6312 0x7B9D 箝 (<CJK Ideograph>) 6313 0x7B98 箘 (<CJK Ideograph>) 6314 0x7B9F 箟 (<CJK Ideograph>) 6315 0x7B8D 箍 (<CJK Ideograph>) 6316 0x7B9C 箜 (<CJK Ideograph>) 6317 0x7B9A 箚 (<CJK Ideograph>) 6318 0x7B8B 箋 (<CJK Ideograph>) 6319 0x7B92 箒 (<CJK Ideograph>) 6320 0x7B8F 箏 (<CJK Ideograph>) 6321 0x7B5D 筝 (<CJK Ideograph>) 6322 0x7B99 箙 (<CJK Ideograph>) 6323 0x7BCB 篋 (<CJK Ideograph>) 6324 0x7BC1 篁 (<CJK Ideograph>) 6325 0x7BCC 篌 (<CJK Ideograph>) 6326 0x7BCF 篏 (<CJK Ideograph>) 6327 0x7BB4 箴 (<CJK Ideograph>) 6328 0x7BC6 篆 (<CJK Ideograph>) 6329 0x7BDD 篝 (<CJK Ideograph>) 6330 0x7BE9 篩 (<CJK Ideograph>) 6331 0x7C11 簑 (<CJK Ideograph>) 6332 0x7C14 簔 (<CJK Ideograph>) 6333 0x7BE6 篦 (<CJK Ideograph>) 6334 0x7BE5 篥 (<CJK Ideograph>) 6335 0x7C60 籠 (<CJK Ideograph>) 6336 0x7C00 簀 (<CJK Ideograph>) 6337 0x7C07 簇 (<CJK Ideograph>) 6338 0x7C13 簓 (<CJK Ideograph>) 6339 0x7BF3 篳 (<CJK Ideograph>) 6340 0x7BF7 篷 (<CJK Ideograph>) 6341 0x7C17 簗 (<CJK Ideograph>) 6342 0x7C0D 簍 (<CJK Ideograph>) 6343 0x7BF6 篶 (<CJK Ideograph>) 6344 0x7C23 簣 (<CJK Ideograph>) 6345 0x7C27 簧 (<CJK Ideograph>) 6346 0x7C2A 簪 (<CJK Ideograph>) 6347 0x7C1F 簟 (<CJK Ideograph>) 6348 0x7C37 簷 (<CJK Ideograph>) 6349 0x7C2B 簫 (<CJK Ideograph>) 6350 0x7C3D 簽 (<CJK Ideograph>) 6351 0x7C4C 籌 (<CJK Ideograph>) 6352 0x7C43 籃 (<CJK Ideograph>) 6353 0x7C54 籔 (<CJK Ideograph>) 6354 0x7C4F 籏 (<CJK Ideograph>) 6355 0x7C40 籀 (<CJK Ideograph>) 6356 0x7C50 籐 (<CJK Ideograph>) 6357 0x7C58 籘 (<CJK Ideograph>) 6358 0x7C5F 籟 (<CJK Ideograph>) 6359 0x7C64 籤 (<CJK Ideograph>) 6360 0x7C56 籖 (<CJK Ideograph>) 6361 0x7C65 籥 (<CJK Ideograph>) 6362 0x7C6C 籬 (<CJK Ideograph>) 6363 0x7C75 籵 (<CJK Ideograph>) 6364 0x7C83 粃 (<CJK Ideograph>) 6365 0x7C90 粐 (<CJK Ideograph>) 6366 0x7CA4 粤 (<CJK Ideograph>) 6367 0x7CAD 粭 (<CJK Ideograph>) 6368 0x7CA2 粢 (<CJK Ideograph>) 6369 0x7CAB 粫 (<CJK Ideograph>) 6370 0x7CA1 粡 (<CJK Ideograph>) 6371 0x7CA8 粨 (<CJK Ideograph>) 6372 0x7CB3 粳 (<CJK Ideograph>) 6373 0x7CB2 粲 (<CJK Ideograph>) 6374 0x7CB1 粱 (<CJK Ideograph>) 6375 0x7CAE 粮 (<CJK Ideograph>) 6376 0x7CB9 粹 (<CJK Ideograph>) 6377 0x7CBD 粽 (<CJK Ideograph>) 6378 0x7CC0 糀 (<CJK Ideograph>) 6379 0x7CC5 糅 (<CJK Ideograph>) 6380 0x7CC2 糂 (<CJK Ideograph>) 6381 0x7CD8 糘 (<CJK Ideograph>) 6382 0x7CD2 糒 (<CJK Ideograph>) 6383 0x7CDC 糜 (<CJK Ideograph>) 6384 0x7CE2 糢 (<CJK Ideograph>) 6385 0x9B3B 鬻 (<CJK Ideograph>) 6386 0x7CEF 糯 (<CJK Ideograph>) 6387 0x7CF2 糲 (<CJK Ideograph>) 6388 0x7CF4 糴 (<CJK Ideograph>) 6389 0x7CF6 糶 (<CJK Ideograph>) 6390 0x7CFA 糺 (<CJK Ideograph>) 6391 0x7D06 紆 (<CJK Ideograph>) 6392 0x7D02 紂 (<CJK Ideograph>) 6393 0x7D1C 紜 (<CJK Ideograph>) 6394 0x7D15 紕 (<CJK Ideograph>) 6395 0x7D0A 紊 (<CJK Ideograph>) 6396 0x7D45 絅 (<CJK Ideograph>) 6397 0x7D4B 絋 (<CJK Ideograph>) 6398 0x7D2E 紮 (<CJK Ideograph>) 6399 0x7D32 紲 (<CJK Ideograph>) 6400 0x7D3F 紿 (<CJK Ideograph>) 6401 0x7D35 紵 (<CJK Ideograph>) 6402 0x7D46 絆 (<CJK Ideograph>) 6403 0x7D73 絳 (<CJK Ideograph>) 6404 0x7D56 絖 (<CJK Ideograph>) 6405 0x7D4E 絎 (<CJK Ideograph>) 6406 0x7D72 絲 (<CJK Ideograph>) 6407 0x7D68 絨 (<CJK Ideograph>) 6408 0x7D6E 絮 (<CJK Ideograph>) 6409 0x7D4F 絏 (<CJK Ideograph>) 6410 0x7D63 絣 (<CJK Ideograph>) 6411 0x7D93 經 (<CJK Ideograph>) 6412 0x7D89 綉 (<CJK Ideograph>) 6413 0x7D5B 絛 (<CJK Ideograph>) 6414 0x7D8F 綏 (<CJK Ideograph>) 6415 0x7D7D 絽 (<CJK Ideograph>) 6416 0x7D9B 綛 (<CJK Ideograph>) 6417 0x7DBA 綺 (<CJK Ideograph>) 6418 0x7DAE 綮 (<CJK Ideograph>) 6419 0x7DA3 綣 (<CJK Ideograph>) 6420 0x7DB5 綵 (<CJK Ideograph>) 6421 0x7DC7 緇 (<CJK Ideograph>) 6422 0x7DBD 綽 (<CJK Ideograph>) 6423 0x7DAB 綫 (<CJK Ideograph>) 6424 0x7E3D 總 (<CJK Ideograph>) 6425 0x7DA2 綢 (<CJK Ideograph>) 6426 0x7DAF 綯 (<CJK Ideograph>) 6427 0x7DDC 緜 (<CJK Ideograph>) 6428 0x7DB8 綸 (<CJK Ideograph>) 6429 0x7D9F 綟 (<CJK Ideograph>) 6430 0x7DB0 綰 (<CJK Ideograph>) 6431 0x7DD8 緘 (<CJK Ideograph>) 6432 0x7DDD 緝 (<CJK Ideograph>) 6433 0x7DE4 緤 (<CJK Ideograph>) 6434 0x7DDE 緞 (<CJK Ideograph>) 6435 0x7DFB 緻 (<CJK Ideograph>) 6436 0x7DF2 緲 (<CJK Ideograph>) 6437 0x7DE1 緡 (<CJK Ideograph>) 6438 0x7E05 縅 (<CJK Ideograph>) 6439 0x7E0A 縊 (<CJK Ideograph>) 6440 0x7E23 縣 (<CJK Ideograph>) 6441 0x7E21 縡 (<CJK Ideograph>) 6442 0x7E12 縒 (<CJK Ideograph>) 6443 0x7E31 縱 (<CJK Ideograph>) 6444 0x7E1F 縟 (<CJK Ideograph>) 6445 0x7E09 縉 (<CJK Ideograph>) 6446 0x7E0B 縋 (<CJK Ideograph>) 6447 0x7E22 縢 (<CJK Ideograph>) 6448 0x7E46 繆 (<CJK Ideograph>) 6449 0x7E66 繦 (<CJK Ideograph>) 6450 0x7E3B 縻 (<CJK Ideograph>) 6451 0x7E35 縵 (<CJK Ideograph>) 6452 0x7E39 縹 (<CJK Ideograph>) 6453 0x7E43 繃 (<CJK Ideograph>) 6454 0x7E37 縷 (<CJK Ideograph>) 6455 0x7E32 縲 (<CJK Ideograph>) 6456 0x7E3A 縺 (<CJK Ideograph>) 6457 0x7E67 繧 (<CJK Ideograph>) 6458 0x7E5D 繝 (<CJK Ideograph>) 6459 0x7E56 繖 (<CJK Ideograph>) 6460 0x7E5E 繞 (<CJK Ideograph>) 6461 0x7E59 繙 (<CJK Ideograph>) 6462 0x7E5A 繚 (<CJK Ideograph>) 6463 0x7E79 繹 (<CJK Ideograph>) 6464 0x7E6A 繪 (<CJK Ideograph>) 6465 0x7E69 繩 (<CJK Ideograph>) 6466 0x7E7C 繼 (<CJK Ideograph>) 6467 0x7E7B 繻 (<CJK Ideograph>) 6468 0x7E83 纃 (<CJK Ideograph>) 6469 0x7DD5 緕 (<CJK Ideograph>) 6470 0x7E7D 繽 (<CJK Ideograph>) 6471 0x8FAE 辮 (<CJK Ideograph>) 6472 0x7E7F 繿 (<CJK Ideograph>) 6473 0x7E88 纈 (<CJK Ideograph>) 6474 0x7E89 纉 (<CJK Ideograph>) 6475 0x7E8C 續 (<CJK Ideograph>) 6476 0x7E92 纒 (<CJK Ideograph>) 6477 0x7E90 纐 (<CJK Ideograph>) 6478 0x7E93 纓 (<CJK Ideograph>) 6479 0x7E94 纔 (<CJK Ideograph>) 6480 0x7E96 纖 (<CJK Ideograph>) 6481 0x7E8E 纎 (<CJK Ideograph>) 6482 0x7E9B 纛 (<CJK Ideograph>) 6483 0x7E9C 纜 (<CJK Ideograph>) 6484 0x7F38 缸 (<CJK Ideograph>) 6485 0x7F3A 缺 (<CJK Ideograph>) 6486 0x7F45 罅 (<CJK Ideograph>) 6487 0x7F4C 罌 (<CJK Ideograph>) 6488 0x7F4D 罍 (<CJK Ideograph>) 6489 0x7F4E 罎 (<CJK Ideograph>) 6490 0x7F50 罐 (<CJK Ideograph>) 6491 0x7F51 网 (<CJK Ideograph>) 6492 0x7F55 罕 (<CJK Ideograph>) 6493 0x7F54 罔 (<CJK Ideograph>) 6494 0x7F58 罘 (<CJK Ideograph>) 6495 0x7F5F 罟 (<CJK Ideograph>) 6496 0x7F60 罠 (<CJK Ideograph>) 6497 0x7F68 罨 (<CJK Ideograph>) 6498 0x7F69 罩 (<CJK Ideograph>) 6499 0x7F67 罧 (<CJK Ideograph>) 6500 0x7F78 罸 (<CJK Ideograph>) 6501 0x7F82 羂 (<CJK Ideograph>) 6502 0x7F86 羆 (<CJK Ideograph>) 6503 0x7F83 羃 (<CJK Ideograph>) 6504 0x7F88 羈 (<CJK Ideograph>) 6505 0x7F87 羇 (<CJK Ideograph>) 6506 0x7F8C 羌 (<CJK Ideograph>) 6507 0x7F94 羔 (<CJK Ideograph>) 6508 0x7F9E 羞 (<CJK Ideograph>) 6509 0x7F9D 羝 (<CJK Ideograph>) 6510 0x7F9A 羚 (<CJK Ideograph>) 6511 0x7FA3 羣 (<CJK Ideograph>) 6512 0x7FAF 羯 (<CJK Ideograph>) 6513 0x7FB2 羲 (<CJK Ideograph>) 6514 0x7FB9 羹 (<CJK Ideograph>) 6515 0x7FAE 羮 (<CJK Ideograph>) 6516 0x7FB6 羶 (<CJK Ideograph>) 6517 0x7FB8 羸 (<CJK Ideograph>) 6518 0x8B71 譱 (<CJK Ideograph>) 6519 0x7FC5 翅 (<CJK Ideograph>) 6520 0x7FC6 翆 (<CJK Ideograph>) 6521 0x7FCA 翊 (<CJK Ideograph>) 6522 0x7FD5 翕 (<CJK Ideograph>) 6523 0x7FD4 翔 (<CJK Ideograph>) 6524 0x7FE1 翡 (<CJK Ideograph>) 6525 0x7FE6 翦 (<CJK Ideograph>) 6526 0x7FE9 翩 (<CJK Ideograph>) 6527 0x7FF3 翳 (<CJK Ideograph>) 6528 0x7FF9 翹 (<CJK Ideograph>) 6529 0x98DC 飜 (<CJK Ideograph>) 6530 0x8006 耆 (<CJK Ideograph>) 6531 0x8004 耄 (<CJK Ideograph>) 6532 0x800B 耋 (<CJK Ideograph>) 6533 0x8012 耒 (<CJK Ideograph>) 6534 0x8018 耘 (<CJK Ideograph>) 6535 0x8019 耙 (<CJK Ideograph>) 6536 0x801C 耜 (<CJK Ideograph>) 6537 0x8021 耡 (<CJK Ideograph>) 6538 0x8028 耨 (<CJK Ideograph>) 6539 0x803F 耿 (<CJK Ideograph>) 6540 0x803B 耻 (<CJK Ideograph>) 6541 0x804A 聊 (<CJK Ideograph>) 6542 0x8046 聆 (<CJK Ideograph>) 6543 0x8052 聒 (<CJK Ideograph>) 6544 0x8058 聘 (<CJK Ideograph>) 6545 0x805A 聚 (<CJK Ideograph>) 6546 0x805F 聟 (<CJK Ideograph>) 6547 0x8062 聢 (<CJK Ideograph>) 6548 0x8068 聨 (<CJK Ideograph>) 6549 0x8073 聳 (<CJK Ideograph>) 6550 0x8072 聲 (<CJK Ideograph>) 6551 0x8070 聰 (<CJK Ideograph>) 6552 0x8076 聶 (<CJK Ideograph>) 6553 0x8079 聹 (<CJK Ideograph>) 6554 0x807D 聽 (<CJK Ideograph>) 6555 0x807F 聿 (<CJK Ideograph>) 6556 0x8084 肄 (<CJK Ideograph>) 6557 0x8086 肆 (<CJK Ideograph>) 6558 0x8085 肅 (<CJK Ideograph>) 6559 0x809B 肛 (<CJK Ideograph>) 6560 0x8093 肓 (<CJK Ideograph>) 6561 0x809A 肚 (<CJK Ideograph>) 6562 0x80AD 肭 (<CJK Ideograph>) 6563 0x5190 冐 (<CJK Ideograph>) 6564 0x80AC 肬 (<CJK Ideograph>) 6565 0x80DB 胛 (<CJK Ideograph>) 6566 0x80E5 胥 (<CJK Ideograph>) 6567 0x80D9 胙 (<CJK Ideograph>) 6568 0x80DD 胝 (<CJK Ideograph>) 6569 0x80C4 胄 (<CJK Ideograph>) 6570 0x80DA 胚 (<CJK Ideograph>) 6571 0x80D6 胖 (<CJK Ideograph>) 6572 0x8109 脉 (<CJK Ideograph>) 6573 0x80EF 胯 (<CJK Ideograph>) 6574 0x80F1 胱 (<CJK Ideograph>) 6575 0x811B 脛 (<CJK Ideograph>) 6576 0x8129 脩 (<CJK Ideograph>) 6577 0x8123 脣 (<CJK Ideograph>) 6578 0x812F 脯 (<CJK Ideograph>) 6579 0x814B 腋 (<CJK Ideograph>) 6580 0x968B 隋 (<CJK Ideograph>) 6581 0x8146 腆 (<CJK Ideograph>) 6582 0x813E 脾 (<CJK Ideograph>) 6583 0x8153 腓 (<CJK Ideograph>) 6584 0x8151 腑 (<CJK Ideograph>) 6585 0x80FC 胼 (<CJK Ideograph>) 6586 0x8171 腱 (<CJK Ideograph>) 6587 0x816E 腮 (<CJK Ideograph>) 6588 0x8165 腥 (<CJK Ideograph>) 6589 0x8166 腦 (<CJK Ideograph>) 6590 0x8174 腴 (<CJK Ideograph>) 6591 0x8183 膃 (<CJK Ideograph>) 6592 0x8188 膈 (<CJK Ideograph>) 6593 0x818A 膊 (<CJK Ideograph>) 6594 0x8180 膀 (<CJK Ideograph>) 6595 0x8182 膂 (<CJK Ideograph>) 6596 0x81A0 膠 (<CJK Ideograph>) 6597 0x8195 膕 (<CJK Ideograph>) 6598 0x81A4 膤 (<CJK Ideograph>) 6599 0x81A3 膣 (<CJK Ideograph>) 6600 0x815F 腟 (<CJK Ideograph>) 6601 0x8193 膓 (<CJK Ideograph>) 6602 0x81A9 膩 (<CJK Ideograph>) 6603 0x81B0 膰 (<CJK Ideograph>) 6604 0x81B5 膵 (<CJK Ideograph>) 6605 0x81BE 膾 (<CJK Ideograph>) 6606 0x81B8 膸 (<CJK Ideograph>) 6607 0x81BD 膽 (<CJK Ideograph>) 6608 0x81C0 臀 (<CJK Ideograph>) 6609 0x81C2 臂 (<CJK Ideograph>) 6610 0x81BA 膺 (<CJK Ideograph>) 6611 0x81C9 臉 (<CJK Ideograph>) 6612 0x81CD 臍 (<CJK Ideograph>) 6613 0x81D1 臑 (<CJK Ideograph>) 6614 0x81D9 臙 (<CJK Ideograph>) 6615 0x81D8 臘 (<CJK Ideograph>) 6616 0x81C8 臈 (<CJK Ideograph>) 6617 0x81DA 臚 (<CJK Ideograph>) 6618 0x81DF 臟 (<CJK Ideograph>) 6619 0x81E0 臠 (<CJK Ideograph>) 6620 0x81E7 臧 (<CJK Ideograph>) 6621 0x81FA 臺 (<CJK Ideograph>) 6622 0x81FB 臻 (<CJK Ideograph>) 6623 0x81FE 臾 (<CJK Ideograph>) 6624 0x8201 舁 (<CJK Ideograph>) 6625 0x8202 舂 (<CJK Ideograph>) 6626 0x8205 舅 (<CJK Ideograph>) 6627 0x8207 與 (<CJK Ideograph>) 6628 0x820A 舊 (<CJK Ideograph>) 6629 0x820D 舍 (<CJK Ideograph>) 6630 0x8210 舐 (<CJK Ideograph>) 6631 0x8216 舖 (<CJK Ideograph>) 6632 0x8229 舩 (<CJK Ideograph>) 6633 0x822B 舫 (<CJK Ideograph>) 6634 0x8238 舸 (<CJK Ideograph>) 6635 0x8233 舳 (<CJK Ideograph>) 6636 0x8240 艀 (<CJK Ideograph>) 6637 0x8259 艙 (<CJK Ideograph>) 6638 0x8258 艘 (<CJK Ideograph>) 6639 0x825D 艝 (<CJK Ideograph>) 6640 0x825A 艚 (<CJK Ideograph>) 6641 0x825F 艟 (<CJK Ideograph>) 6642 0x8264 艤 (<CJK Ideograph>) 6643 0x8262 艢 (<CJK Ideograph>) 6644 0x8268 艨 (<CJK Ideograph>) 6645 0x826A 艪 (<CJK Ideograph>) 6646 0x826B 艫 (<CJK Ideograph>) 6647 0x822E 舮 (<CJK Ideograph>) 6648 0x8271 艱 (<CJK Ideograph>) 6649 0x8277 艷 (<CJK Ideograph>) 6650 0x8278 艸 (<CJK Ideograph>) 6651 0x827E 艾 (<CJK Ideograph>) 6652 0x828D 芍 (<CJK Ideograph>) 6653 0x8292 芒 (<CJK Ideograph>) 6654 0x82AB 芫 (<CJK Ideograph>) 6655 0x829F 芟 (<CJK Ideograph>) 6656 0x82BB 芻 (<CJK Ideograph>) 6657 0x82AC 芬 (<CJK Ideograph>) 6658 0x82E1 苡 (<CJK Ideograph>) 6659 0x82E3 苣 (<CJK Ideograph>) 6660 0x82DF 苟 (<CJK Ideograph>) 6661 0x82D2 苒 (<CJK Ideograph>) 6662 0x82F4 苴 (<CJK Ideograph>) 6663 0x82F3 苳 (<CJK Ideograph>) 6664 0x82FA 苺 (<CJK Ideograph>) 6665 0x8393 莓 (<CJK Ideograph>) 6666 0x8303 范 (<CJK Ideograph>) 6667 0x82FB 苻 (<CJK Ideograph>) 6668 0x82F9 苹 (<CJK Ideograph>) 6669 0x82DE 苞 (<CJK Ideograph>) 6670 0x8306 茆 (<CJK Ideograph>) 6671 0x82DC 苜 (<CJK Ideograph>) 6672 0x8309 茉 (<CJK Ideograph>) 6673 0x82D9 苙 (<CJK Ideograph>) 6674 0x8335 茵 (<CJK Ideograph>) 6675 0x8334 茴 (<CJK Ideograph>) 6676 0x8316 茖 (<CJK Ideograph>) 6677 0x8332 茲 (<CJK Ideograph>) 6678 0x8331 茱 (<CJK Ideograph>) 6679 0x8340 荀 (<CJK Ideograph>) 6680 0x8339 茹 (<CJK Ideograph>) 6681 0x8350 荐 (<CJK Ideograph>) 6682 0x8345 荅 (<CJK Ideograph>) 6683 0x832F 茯 (<CJK Ideograph>) 6684 0x832B 茫 (<CJK Ideograph>) 6685 0x8317 茗 (<CJK Ideograph>) 6686 0x8318 茘 (<CJK Ideograph>) 6687 0x8385 莅 (<CJK Ideograph>) 6688 0x839A 莚 (<CJK Ideograph>) 6689 0x83AA 莪 (<CJK Ideograph>) 6690 0x839F 莟 (<CJK Ideograph>) 6691 0x83A2 莢 (<CJK Ideograph>) 6692 0x8396 莖 (<CJK Ideograph>) 6693 0x8323 茣 (<CJK Ideograph>) 6694 0x838E 莎 (<CJK Ideograph>) 6695 0x8387 莇 (<CJK Ideograph>) 6696 0x838A 莊 (<CJK Ideograph>) 6697 0x837C 荼 (<CJK Ideograph>) 6698 0x83B5 莵 (<CJK Ideograph>) 6699 0x8373 荳 (<CJK Ideograph>) 6700 0x8375 荵 (<CJK Ideograph>) 6701 0x83A0 莠 (<CJK Ideograph>) 6702 0x8389 莉 (<CJK Ideograph>) 6703 0x83A8 莨 (<CJK Ideograph>) 6704 0x83F4 菴 (<CJK Ideograph>) 6705 0x8413 萓 (<CJK Ideograph>) 6706 0x83EB 菫 (<CJK Ideograph>) 6707 0x83CE 菎 (<CJK Ideograph>) 6708 0x83FD 菽 (<CJK Ideograph>) 6709 0x8403 萃 (<CJK Ideograph>) 6710 0x83D8 菘 (<CJK Ideograph>) 6711 0x840B 萋 (<CJK Ideograph>) 6712 0x83C1 菁 (<CJK Ideograph>) 6713 0x83F7 菷 (<CJK Ideograph>) 6714 0x8407 萇 (<CJK Ideograph>) 6715 0x83E0 菠 (<CJK Ideograph>) 6716 0x83F2 菲 (<CJK Ideograph>) 6717 0x840D 萍 (<CJK Ideograph>) 6718 0x8422 萢 (<CJK Ideograph>) 6719 0x8420 萠 (<CJK Ideograph>) 6720 0x83BD 莽 (<CJK Ideograph>) 6721 0x8438 萸 (<CJK Ideograph>) 6722 0x8506 蔆 (<CJK Ideograph>) 6723 0x83FB 菻 (<CJK Ideograph>) 6724 0x846D 葭 (<CJK Ideograph>) 6725 0x842A 萪 (<CJK Ideograph>) 6726 0x843C 萼 (<CJK Ideograph>) 6727 0x855A 蕚 (<CJK Ideograph>) 6728 0x8484 蒄 (<CJK Ideograph>) 6729 0x8477 葷 (<CJK Ideograph>) 6730 0x846B 葫 (<CJK Ideograph>) 6731 0x84AD 蒭 (<CJK Ideograph>) 6732 0x846E 葮 (<CJK Ideograph>) 6733 0x8482 蒂 (<CJK Ideograph>) 6734 0x8469 葩 (<CJK Ideograph>) 6735 0x8446 葆 (<CJK Ideograph>) 6736 0x842C 萬 (<CJK Ideograph>) 6737 0x846F 葯 (<CJK Ideograph>) 6738 0x8479 葹 (<CJK Ideograph>) 6739 0x8435 萵 (<CJK Ideograph>) 6740 0x84CA 蓊 (<CJK Ideograph>) 6741 0x8462 葢 (<CJK Ideograph>) 6742 0x84B9 蒹 (<CJK Ideograph>) 6743 0x84BF 蒿 (<CJK Ideograph>) 6744 0x849F 蒟 (<CJK Ideograph>) 6745 0x84D9 蓙 (<CJK Ideograph>) 6746 0x84CD 蓍 (<CJK Ideograph>) 6747 0x84BB 蒻 (<CJK Ideograph>) 6748 0x84DA 蓚 (<CJK Ideograph>) 6749 0x84D0 蓐 (<CJK Ideograph>) 6750 0x84C1 蓁 (<CJK Ideograph>) 6751 0x84C6 蓆 (<CJK Ideograph>) 6752 0x84D6 蓖 (<CJK Ideograph>) 6753 0x84A1 蒡 (<CJK Ideograph>) 6754 0x8521 蔡 (<CJK Ideograph>) 6755 0x84FF 蓿 (<CJK Ideograph>) 6756 0x84F4 蓴 (<CJK Ideograph>) 6757 0x8517 蔗 (<CJK Ideograph>) 6758 0x8518 蔘 (<CJK Ideograph>) 6759 0x852C 蔬 (<CJK Ideograph>) 6760 0x851F 蔟 (<CJK Ideograph>) 6761 0x8515 蔕 (<CJK Ideograph>) 6762 0x8514 蔔 (<CJK Ideograph>) 6763 0x84FC 蓼 (<CJK Ideograph>) 6764 0x8540 蕀 (<CJK Ideograph>) 6765 0x8563 蕣 (<CJK Ideograph>) 6766 0x8558 蕘 (<CJK Ideograph>) 6767 0x8548 蕈 (<CJK Ideograph>) 6768 0x8541 蕁 (<CJK Ideograph>) 6769 0x8602 蘂 (<CJK Ideograph>) 6770 0x854B 蕋 (<CJK Ideograph>) 6771 0x8555 蕕 (<CJK Ideograph>) 6772 0x8580 薀 (<CJK Ideograph>) 6773 0x85A4 薤 (<CJK Ideograph>) 6774 0x8588 薈 (<CJK Ideograph>) 6775 0x8591 薑 (<CJK Ideograph>) 6776 0x858A 薊 (<CJK Ideograph>) 6777 0x85A8 薨 (<CJK Ideograph>) 6778 0x856D 蕭 (<CJK Ideograph>) 6779 0x8594 薔 (<CJK Ideograph>) 6780 0x859B 薛 (<CJK Ideograph>) 6781 0x85EA 藪 (<CJK Ideograph>) 6782 0x8587 薇 (<CJK Ideograph>) 6783 0x859C 薜 (<CJK Ideograph>) 6784 0x8577 蕷 (<CJK Ideograph>) 6785 0x857E 蕾 (<CJK Ideograph>) 6786 0x8590 薐 (<CJK Ideograph>) 6787 0x85C9 藉 (<CJK Ideograph>) 6788 0x85BA 薺 (<CJK Ideograph>) 6789 0x85CF 藏 (<CJK Ideograph>) 6790 0x85B9 薹 (<CJK Ideograph>) 6791 0x85D0 藐 (<CJK Ideograph>) 6792 0x85D5 藕 (<CJK Ideograph>) 6793 0x85DD 藝 (<CJK Ideograph>) 6794 0x85E5 藥 (<CJK Ideograph>) 6795 0x85DC 藜 (<CJK Ideograph>) 6796 0x85F9 藹 (<CJK Ideograph>) 6797 0x860A 蘊 (<CJK Ideograph>) 6798 0x8613 蘓 (<CJK Ideograph>) 6799 0x860B 蘋 (<CJK Ideograph>) 6800 0x85FE 藾 (<CJK Ideograph>) 6801 0x85FA 藺 (<CJK Ideograph>) 6802 0x8606 蘆 (<CJK Ideograph>) 6803 0x8622 蘢 (<CJK Ideograph>) 6804 0x861A 蘚 (<CJK Ideograph>) 6805 0x8630 蘰 (<CJK Ideograph>) 6806 0x863F 蘿 (<CJK Ideograph>) 6807 0x864D 虍 (<CJK Ideograph>) 6808 0x4E55 乕 (<CJK Ideograph>) 6809 0x8654 虔 (<CJK Ideograph>) 6810 0x865F 號 (<CJK Ideograph>) 6811 0x8667 虧 (<CJK Ideograph>) 6812 0x8671 虱 (<CJK Ideograph>) 6813 0x8693 蚓 (<CJK Ideograph>) 6814 0x86A3 蚣 (<CJK Ideograph>) 6815 0x86A9 蚩 (<CJK Ideograph>) 6816 0x86AA 蚪 (<CJK Ideograph>) 6817 0x868B 蚋 (<CJK Ideograph>) 6818 0x868C 蚌 (<CJK Ideograph>) 6819 0x86B6 蚶 (<CJK Ideograph>) 6820 0x86AF 蚯 (<CJK Ideograph>) 6821 0x86C4 蛄 (<CJK Ideograph>) 6822 0x86C6 蛆 (<CJK Ideograph>) 6823 0x86B0 蚰 (<CJK Ideograph>) 6824 0x86C9 蛉 (<CJK Ideograph>) 6825 0x8823 蠣 (<CJK Ideograph>) 6826 0x86AB 蚫 (<CJK Ideograph>) 6827 0x86D4 蛔 (<CJK Ideograph>) 6828 0x86DE 蛞 (<CJK Ideograph>) 6829 0x86E9 蛩 (<CJK Ideograph>) 6830 0x86EC 蛬 (<CJK Ideograph>) 6831 0x86DF 蛟 (<CJK Ideograph>) 6832 0x86DB 蛛 (<CJK Ideograph>) 6833 0x86EF 蛯 (<CJK Ideograph>) 6834 0x8712 蜒 (<CJK Ideograph>) 6835 0x8706 蜆 (<CJK Ideograph>) 6836 0x8708 蜈 (<CJK Ideograph>) 6837 0x8700 蜀 (<CJK Ideograph>) 6838 0x8703 蜃 (<CJK Ideograph>) 6839 0x86FB 蛻 (<CJK Ideograph>) 6840 0x8711 蜑 (<CJK Ideograph>) 6841 0x8709 蜉 (<CJK Ideograph>) 6842 0x870D 蜍 (<CJK Ideograph>) 6843 0x86F9 蛹 (<CJK Ideograph>) 6844 0x870A 蜊 (<CJK Ideograph>) 6845 0x8734 蜴 (<CJK Ideograph>) 6846 0x873F 蜿 (<CJK Ideograph>) 6847 0x8737 蜷 (<CJK Ideograph>) 6848 0x873B 蜻 (<CJK Ideograph>) 6849 0x8725 蜥 (<CJK Ideograph>) 6850 0x8729 蜩 (<CJK Ideograph>) 6851 0x871A 蜚 (<CJK Ideograph>) 6852 0x8760 蝠 (<CJK Ideograph>) 6853 0x875F 蝟 (<CJK Ideograph>) 6854 0x8778 蝸 (<CJK Ideograph>) 6855 0x874C 蝌 (<CJK Ideograph>) 6856 0x874E 蝎 (<CJK Ideograph>) 6857 0x8774 蝴 (<CJK Ideograph>) 6858 0x8757 蝗 (<CJK Ideograph>) 6859 0x8768 蝨 (<CJK Ideograph>) 6860 0x876E 蝮 (<CJK Ideograph>) 6861 0x8759 蝙 (<CJK Ideograph>) 6862 0x8753 蝓 (<CJK Ideograph>) 6863 0x8763 蝣 (<CJK Ideograph>) 6864 0x876A 蝪 (<CJK Ideograph>) 6865 0x8805 蠅 (<CJK Ideograph>) 6866 0x87A2 螢 (<CJK Ideograph>) 6867 0x879F 螟 (<CJK Ideograph>) 6868 0x8782 螂 (<CJK Ideograph>) 6869 0x87AF 螯 (<CJK Ideograph>) 6870 0x87CB 蟋 (<CJK Ideograph>) 6871 0x87BD 螽 (<CJK Ideograph>) 6872 0x87C0 蟀 (<CJK Ideograph>) 6873 0x87D0 蟐 (<CJK Ideograph>) 6874 0x96D6 雖 (<CJK Ideograph>) 6875 0x87AB 螫 (<CJK Ideograph>) 6876 0x87C4 蟄 (<CJK Ideograph>) 6877 0x87B3 螳 (<CJK Ideograph>) 6878 0x87C7 蟇 (<CJK Ideograph>) 6879 0x87C6 蟆 (<CJK Ideograph>) 6880 0x87BB 螻 (<CJK Ideograph>) 6881 0x87EF 蟯 (<CJK Ideograph>) 6882 0x87F2 蟲 (<CJK Ideograph>) 6883 0x87E0 蟠 (<CJK Ideograph>) 6884 0x880F 蠏 (<CJK Ideograph>) 6885 0x880D 蠍 (<CJK Ideograph>) 6886 0x87FE 蟾 (<CJK Ideograph>) 6887 0x87F6 蟶 (<CJK Ideograph>) 6888 0x87F7 蟷 (<CJK Ideograph>) 6889 0x880E 蠎 (<CJK Ideograph>) 6890 0x87D2 蟒 (<CJK Ideograph>) 6891 0x8811 蠑 (<CJK Ideograph>) 6892 0x8816 蠖 (<CJK Ideograph>) 6893 0x8815 蠕 (<CJK Ideograph>) 6894 0x8822 蠢 (<CJK Ideograph>) 6895 0x8821 蠡 (<CJK Ideograph>) 6896 0x8831 蠱 (<CJK Ideograph>) 6897 0x8836 蠶 (<CJK Ideograph>) 6898 0x8839 蠹 (<CJK Ideograph>) 6899 0x8827 蠧 (<CJK Ideograph>) 6900 0x883B 蠻 (<CJK Ideograph>) 6901 0x8844 衄 (<CJK Ideograph>) 6902 0x8842 衂 (<CJK Ideograph>) 6903 0x8852 衒 (<CJK Ideograph>) 6904 0x8859 衙 (<CJK Ideograph>) 6905 0x885E 衞 (<CJK Ideograph>) 6906 0x8862 衢 (<CJK Ideograph>) 6907 0x886B 衫 (<CJK Ideograph>) 6908 0x8881 袁 (<CJK Ideograph>) 6909 0x887E 衾 (<CJK Ideograph>) 6910 0x889E 袞 (<CJK Ideograph>) 6911 0x8875 衵 (<CJK Ideograph>) 6912 0x887D 衽 (<CJK Ideograph>) 6913 0x88B5 袵 (<CJK Ideograph>) 6914 0x8872 衲 (<CJK Ideograph>) 6915 0x8882 袂 (<CJK Ideograph>) 6916 0x8897 袗 (<CJK Ideograph>) 6917 0x8892 袒 (<CJK Ideograph>) 6918 0x88AE 袮 (<CJK Ideograph>) 6919 0x8899 袙 (<CJK Ideograph>) 6920 0x88A2 袢 (<CJK Ideograph>) 6921 0x888D 袍 (<CJK Ideograph>) 6922 0x88A4 袤 (<CJK Ideograph>) 6923 0x88B0 袰 (<CJK Ideograph>) 6924 0x88BF 袿 (<CJK Ideograph>) 6925 0x88B1 袱 (<CJK Ideograph>) 6926 0x88C3 裃 (<CJK Ideograph>) 6927 0x88C4 裄 (<CJK Ideograph>) 6928 0x88D4 裔 (<CJK Ideograph>) 6929 0x88D8 裘 (<CJK Ideograph>) 6930 0x88D9 裙 (<CJK Ideograph>) 6931 0x88DD 裝 (<CJK Ideograph>) 6932 0x88F9 裹 (<CJK Ideograph>) 6933 0x8902 褂 (<CJK Ideograph>) 6934 0x88FC 裼 (<CJK Ideograph>) 6935 0x88F4 裴 (<CJK Ideograph>) 6936 0x88E8 裨 (<CJK Ideograph>) 6937 0x88F2 裲 (<CJK Ideograph>) 6938 0x8904 褄 (<CJK Ideograph>) 6939 0x890C 褌 (<CJK Ideograph>) 6940 0x890A 褊 (<CJK Ideograph>) 6941 0x8913 褓 (<CJK Ideograph>) 6942 0x8943 襃 (<CJK Ideograph>) 6943 0x891E 褞 (<CJK Ideograph>) 6944 0x8925 褥 (<CJK Ideograph>) 6945 0x892A 褪 (<CJK Ideograph>) 6946 0x892B 褫 (<CJK Ideograph>) 6947 0x8941 襁 (<CJK Ideograph>) 6948 0x8944 襄 (<CJK Ideograph>) 6949 0x893B 褻 (<CJK Ideograph>) 6950 0x8936 褶 (<CJK Ideograph>) 6951 0x8938 褸 (<CJK Ideograph>) 6952 0x894C 襌 (<CJK Ideograph>) 6953 0x891D 褝 (<CJK Ideograph>) 6954 0x8960 襠 (<CJK Ideograph>) 6955 0x895E 襞 (<CJK Ideograph>) 6956 0x8966 襦 (<CJK Ideograph>) 6957 0x8964 襤 (<CJK Ideograph>) 6958 0x896D 襭 (<CJK Ideograph>) 6959 0x896A 襪 (<CJK Ideograph>) 6960 0x896F 襯 (<CJK Ideograph>) 6961 0x8974 襴 (<CJK Ideograph>) 6962 0x8977 襷 (<CJK Ideograph>) 6963 0x897E 襾 (<CJK Ideograph>) 6964 0x8983 覃 (<CJK Ideograph>) 6965 0x8988 覈 (<CJK Ideograph>) 6966 0x898A 覊 (<CJK Ideograph>) 6967 0x8993 覓 (<CJK Ideograph>) 6968 0x8998 覘 (<CJK Ideograph>) 6969 0x89A1 覡 (<CJK Ideograph>) 6970 0x89A9 覩 (<CJK Ideograph>) 6971 0x89A6 覦 (<CJK Ideograph>) 6972 0x89AC 覬 (<CJK Ideograph>) 6973 0x89AF 覯 (<CJK Ideograph>) 6974 0x89B2 覲 (<CJK Ideograph>) 6975 0x89BA 覺 (<CJK Ideograph>) 6976 0x89BD 覽 (<CJK Ideograph>) 6977 0x89BF 覿 (<CJK Ideograph>) 6978 0x89C0 觀 (<CJK Ideograph>) 6979 0x89DA 觚 (<CJK Ideograph>) 6980 0x89DC 觜 (<CJK Ideograph>) 6981 0x89DD 觝 (<CJK Ideograph>) 6982 0x89E7 觧 (<CJK Ideograph>) 6983 0x89F4 觴 (<CJK Ideograph>) 6984 0x89F8 觸 (<CJK Ideograph>) 6985 0x8A03 訃 (<CJK Ideograph>) 6986 0x8A16 訖 (<CJK Ideograph>) 6987 0x8A10 訐 (<CJK Ideograph>) 6988 0x8A0C 訌 (<CJK Ideograph>) 6989 0x8A1B 訛 (<CJK Ideograph>) 6990 0x8A1D 訝 (<CJK Ideograph>) 6991 0x8A25 訥 (<CJK Ideograph>) 6992 0x8A36 訶 (<CJK Ideograph>) 6993 0x8A41 詁 (<CJK Ideograph>) 6994 0x8A5B 詛 (<CJK Ideograph>) 6995 0x8A52 詒 (<CJK Ideograph>) 6996 0x8A46 詆 (<CJK Ideograph>) 6997 0x8A48 詈 (<CJK Ideograph>) 6998 0x8A7C 詼 (<CJK Ideograph>) 6999 0x8A6D 詭 (<CJK Ideograph>) 7000 0x8A6C 詬 (<CJK Ideograph>) 7001 0x8A62 詢 (<CJK Ideograph>) 7002 0x8A85 誅 (<CJK Ideograph>) 7003 0x8A82 誂 (<CJK Ideograph>) 7004 0x8A84 誄 (<CJK Ideograph>) 7005 0x8AA8 誨 (<CJK Ideograph>) 7006 0x8AA1 誡 (<CJK Ideograph>) 7007 0x8A91 誑 (<CJK Ideograph>) 7008 0x8AA5 誥 (<CJK Ideograph>) 7009 0x8AA6 誦 (<CJK Ideograph>) 7010 0x8A9A 誚 (<CJK Ideograph>) 7011 0x8AA3 誣 (<CJK Ideograph>) 7012 0x8AC4 諄 (<CJK Ideograph>) 7013 0x8ACD 諍 (<CJK Ideograph>) 7014 0x8AC2 諂 (<CJK Ideograph>) 7015 0x8ADA 諚 (<CJK Ideograph>) 7016 0x8AEB 諫 (<CJK Ideograph>) 7017 0x8AF3 諳 (<CJK Ideograph>) 7018 0x8AE7 諧 (<CJK Ideograph>) 7019 0x8AE4 諤 (<CJK Ideograph>) 7020 0x8AF1 諱 (<CJK Ideograph>) 7021 0x8B14 謔 (<CJK Ideograph>) 7022 0x8AE0 諠 (<CJK Ideograph>) 7023 0x8AE2 諢 (<CJK Ideograph>) 7024 0x8AF7 諷 (<CJK Ideograph>) 7025 0x8ADE 諞 (<CJK Ideograph>) 7026 0x8ADB 諛 (<CJK Ideograph>) 7027 0x8B0C 謌 (<CJK Ideograph>) 7028 0x8B07 謇 (<CJK Ideograph>) 7029 0x8B1A 謚 (<CJK Ideograph>) 7030 0x8AE1 諡 (<CJK Ideograph>) 7031 0x8B16 謖 (<CJK Ideograph>) 7032 0x8B10 謐 (<CJK Ideograph>) 7033 0x8B17 謗 (<CJK Ideograph>) 7034 0x8B20 謠 (<CJK Ideograph>) 7035 0x8B33 謳 (<CJK Ideograph>) 7036 0x97AB 鞫 (<CJK Ideograph>) 7037 0x8B26 謦 (<CJK Ideograph>) 7038 0x8B2B 謫 (<CJK Ideograph>) 7039 0x8B3E 謾 (<CJK Ideograph>) 7040 0x8B28 謨 (<CJK Ideograph>) 7041 0x8B41 譁 (<CJK Ideograph>) 7042 0x8B4C 譌 (<CJK Ideograph>) 7043 0x8B4F 譏 (<CJK Ideograph>) 7044 0x8B4E 譎 (<CJK Ideograph>) 7045 0x8B49 證 (<CJK Ideograph>) 7046 0x8B56 譖 (<CJK Ideograph>) 7047 0x8B5B 譛 (<CJK Ideograph>) 7048 0x8B5A 譚 (<CJK Ideograph>) 7049 0x8B6B 譫 (<CJK Ideograph>) 7050 0x8B5F 譟 (<CJK Ideograph>) 7051 0x8B6C 譬 (<CJK Ideograph>) 7052 0x8B6F 譯 (<CJK Ideograph>) 7053 0x8B74 譴 (<CJK Ideograph>) 7054 0x8B7D 譽 (<CJK Ideograph>) 7055 0x8B80 讀 (<CJK Ideograph>) 7056 0x8B8C 讌 (<CJK Ideograph>) 7057 0x8B8E 讎 (<CJK Ideograph>) 7058 0x8B92 讒 (<CJK Ideograph>) 7059 0x8B93 讓 (<CJK Ideograph>) 7060 0x8B96 讖 (<CJK Ideograph>) 7061 0x8B99 讙 (<CJK Ideograph>) 7062 0x8B9A 讚 (<CJK Ideograph>) 7063 0x8C3A 谺 (<CJK Ideograph>) 7064 0x8C41 豁 (<CJK Ideograph>) 7065 0x8C3F 谿 (<CJK Ideograph>) 7066 0x8C48 豈 (<CJK Ideograph>) 7067 0x8C4C 豌 (<CJK Ideograph>) 7068 0x8C4E 豎 (<CJK Ideograph>) 7069 0x8C50 豐 (<CJK Ideograph>) 7070 0x8C55 豕 (<CJK Ideograph>) 7071 0x8C62 豢 (<CJK Ideograph>) 7072 0x8C6C 豬 (<CJK Ideograph>) 7073 0x8C78 豸 (<CJK Ideograph>) 7074 0x8C7A 豺 (<CJK Ideograph>) 7075 0x8C82 貂 (<CJK Ideograph>) 7076 0x8C89 貉 (<CJK Ideograph>) 7077 0x8C85 貅 (<CJK Ideograph>) 7078 0x8C8A 貊 (<CJK Ideograph>) 7079 0x8C8D 貍 (<CJK Ideograph>) 7080 0x8C8E 貎 (<CJK Ideograph>) 7081 0x8C94 貔 (<CJK Ideograph>) 7082 0x8C7C 豼 (<CJK Ideograph>) 7083 0x8C98 貘 (<CJK Ideograph>) 7084 0x621D 戝 (<CJK Ideograph>) 7085 0x8CAD 貭 (<CJK Ideograph>) 7086 0x8CAA 貪 (<CJK Ideograph>) 7087 0x8CBD 貽 (<CJK Ideograph>) 7088 0x8CB2 貲 (<CJK Ideograph>) 7089 0x8CB3 貳 (<CJK Ideograph>) 7090 0x8CAE 貮 (<CJK Ideograph>) 7091 0x8CB6 貶 (<CJK Ideograph>) 7092 0x8CC8 賈 (<CJK Ideograph>) 7093 0x8CC1 賁 (<CJK Ideograph>) 7094 0x8CE4 賤 (<CJK Ideograph>) 7095 0x8CE3 賣 (<CJK Ideograph>) 7096 0x8CDA 賚 (<CJK Ideograph>) 7097 0x8CFD 賽 (<CJK Ideograph>) 7098 0x8CFA 賺 (<CJK Ideograph>) 7099 0x8CFB 賻 (<CJK Ideograph>) 7100 0x8D04 贄 (<CJK Ideograph>) 7101 0x8D05 贅 (<CJK Ideograph>) 7102 0x8D0A 贊 (<CJK Ideograph>) 7103 0x8D07 贇 (<CJK Ideograph>) 7104 0x8D0F 贏 (<CJK Ideograph>) 7105 0x8D0D 贍 (<CJK Ideograph>) 7106 0x8D10 贐 (<CJK Ideograph>) 7107 0x9F4E 齎 (<CJK Ideograph>) 7108 0x8D13 贓 (<CJK Ideograph>) 7109 0x8CCD 賍 (<CJK Ideograph>) 7110 0x8D14 贔 (<CJK Ideograph>) 7111 0x8D16 贖 (<CJK Ideograph>) 7112 0x8D67 赧 (<CJK Ideograph>) 7113 0x8D6D 赭 (<CJK Ideograph>) 7114 0x8D71 赱 (<CJK Ideograph>) 7115 0x8D73 赳 (<CJK Ideograph>) 7116 0x8D81 趁 (<CJK Ideograph>) 7117 0x8D99 趙 (<CJK Ideograph>) 7118 0x8DC2 跂 (<CJK Ideograph>) 7119 0x8DBE 趾 (<CJK Ideograph>) 7120 0x8DBA 趺 (<CJK Ideograph>) 7121 0x8DCF 跏 (<CJK Ideograph>) 7122 0x8DDA 跚 (<CJK Ideograph>) 7123 0x8DD6 跖 (<CJK Ideograph>) 7124 0x8DCC 跌 (<CJK Ideograph>) 7125 0x8DDB 跛 (<CJK Ideograph>) 7126 0x8DCB 跋 (<CJK Ideograph>) 7127 0x8DEA 跪 (<CJK Ideograph>) 7128 0x8DEB 跫 (<CJK Ideograph>) 7129 0x8DDF 跟 (<CJK Ideograph>) 7130 0x8DE3 跣 (<CJK Ideograph>) 7131 0x8DFC 跼 (<CJK Ideograph>) 7132 0x8E08 踈 (<CJK Ideograph>) 7133 0x8E09 踉 (<CJK Ideograph>) 7134 0x8DFF 跿 (<CJK Ideograph>) 7135 0x8E1D 踝 (<CJK Ideograph>) 7136 0x8E1E 踞 (<CJK Ideograph>) 7137 0x8E10 踐 (<CJK Ideograph>) 7138 0x8E1F 踟 (<CJK Ideograph>) 7139 0x8E42 蹂 (<CJK Ideograph>) 7140 0x8E35 踵 (<CJK Ideograph>) 7141 0x8E30 踰 (<CJK Ideograph>) 7142 0x8E34 踴 (<CJK Ideograph>) 7143 0x8E4A 蹊 (<CJK Ideograph>) 7144 0x8E47 蹇 (<CJK Ideograph>) 7145 0x8E49 蹉 (<CJK Ideograph>) 7146 0x8E4C 蹌 (<CJK Ideograph>) 7147 0x8E50 蹐 (<CJK Ideograph>) 7148 0x8E48 蹈 (<CJK Ideograph>) 7149 0x8E59 蹙 (<CJK Ideograph>) 7150 0x8E64 蹤 (<CJK Ideograph>) 7151 0x8E60 蹠 (<CJK Ideograph>) 7152 0x8E2A 踪 (<CJK Ideograph>) 7153 0x8E63 蹣 (<CJK Ideograph>) 7154 0x8E55 蹕 (<CJK Ideograph>) 7155 0x8E76 蹶 (<CJK Ideograph>) 7156 0x8E72 蹲 (<CJK Ideograph>) 7157 0x8E7C 蹼 (<CJK Ideograph>) 7158 0x8E81 躁 (<CJK Ideograph>) 7159 0x8E87 躇 (<CJK Ideograph>) 7160 0x8E85 躅 (<CJK Ideograph>) 7161 0x8E84 躄 (<CJK Ideograph>) 7162 0x8E8B 躋 (<CJK Ideograph>) 7163 0x8E8A 躊 (<CJK Ideograph>) 7164 0x8E93 躓 (<CJK Ideograph>) 7165 0x8E91 躑 (<CJK Ideograph>) 7166 0x8E94 躔 (<CJK Ideograph>) 7167 0x8E99 躙 (<CJK Ideograph>) 7168 0x8EAA 躪 (<CJK Ideograph>) 7169 0x8EA1 躡 (<CJK Ideograph>) 7170 0x8EAC 躬 (<CJK Ideograph>) 7171 0x8EB0 躰 (<CJK Ideograph>) 7172 0x8EC6 軆 (<CJK Ideograph>) 7173 0x8EB1 躱 (<CJK Ideograph>) 7174 0x8EBE 躾 (<CJK Ideograph>) 7175 0x8EC5 軅 (<CJK Ideograph>) 7176 0x8EC8 軈 (<CJK Ideograph>) 7177 0x8ECB 軋 (<CJK Ideograph>) 7178 0x8EDB 軛 (<CJK Ideograph>) 7179 0x8EE3 軣 (<CJK Ideograph>) 7180 0x8EFC 軼 (<CJK Ideograph>) 7181 0x8EFB 軻 (<CJK Ideograph>) 7182 0x8EEB 軫 (<CJK Ideograph>) 7183 0x8EFE 軾 (<CJK Ideograph>) 7184 0x8F0A 輊 (<CJK Ideograph>) 7185 0x8F05 輅 (<CJK Ideograph>) 7186 0x8F15 輕 (<CJK Ideograph>) 7187 0x8F12 輒 (<CJK Ideograph>) 7188 0x8F19 輙 (<CJK Ideograph>) 7189 0x8F13 輓 (<CJK Ideograph>) 7190 0x8F1C 輜 (<CJK Ideograph>) 7191 0x8F1F 輟 (<CJK Ideograph>) 7192 0x8F1B 輛 (<CJK Ideograph>) 7193 0x8F0C 輌 (<CJK Ideograph>) 7194 0x8F26 輦 (<CJK Ideograph>) 7195 0x8F33 輳 (<CJK Ideograph>) 7196 0x8F3B 輻 (<CJK Ideograph>) 7197 0x8F39 輹 (<CJK Ideograph>) 7198 0x8F45 轅 (<CJK Ideograph>) 7199 0x8F42 轂 (<CJK Ideograph>) 7200 0x8F3E 輾 (<CJK Ideograph>) 7201 0x8F4C 轌 (<CJK Ideograph>) 7202 0x8F49 轉 (<CJK Ideograph>) 7203 0x8F46 轆 (<CJK Ideograph>) 7204 0x8F4E 轎 (<CJK Ideograph>) 7205 0x8F57 轗 (<CJK Ideograph>) 7206 0x8F5C 轜 (<CJK Ideograph>) 7207 0x8F62 轢 (<CJK Ideograph>) 7208 0x8F63 轣 (<CJK Ideograph>) 7209 0x8F64 轤 (<CJK Ideograph>) 7210 0x8F9C 辜 (<CJK Ideograph>) 7211 0x8F9F 辟 (<CJK Ideograph>) 7212 0x8FA3 辣 (<CJK Ideograph>) 7213 0x8FAD 辭 (<CJK Ideograph>) 7214 0x8FAF 辯 (<CJK Ideograph>) 7215 0x8FB7 辷 (<CJK Ideograph>) 7216 0x8FDA 迚 (<CJK Ideograph>) 7217 0x8FE5 迥 (<CJK Ideograph>) 7218 0x8FE2 迢 (<CJK Ideograph>) 7219 0x8FEA 迪 (<CJK Ideograph>) 7220 0x8FEF 迯 (<CJK Ideograph>) 7221 0x9087 邇 (<CJK Ideograph>) 7222 0x8FF4 迴 (<CJK Ideograph>) 7223 0x9005 逅 (<CJK Ideograph>) 7224 0x8FF9 迹 (<CJK Ideograph>) 7225 0x8FFA 迺 (<CJK Ideograph>) 7226 0x9011 逑 (<CJK Ideograph>) 7227 0x9015 逕 (<CJK Ideograph>) 7228 0x9021 逡 (<CJK Ideograph>) 7229 0x900D 逍 (<CJK Ideograph>) 7230 0x901E 逞 (<CJK Ideograph>) 7231 0x9016 逖 (<CJK Ideograph>) 7232 0x900B 逋 (<CJK Ideograph>) 7233 0x9027 逧 (<CJK Ideograph>) 7234 0x9036 逶 (<CJK Ideograph>) 7235 0x9035 逵 (<CJK Ideograph>) 7236 0x9039 逹 (<CJK Ideograph>) 7237 0x8FF8 迸 (<CJK Ideograph>) 7238 0x904F 遏 (<CJK Ideograph>) 7239 0x9050 遐 (<CJK Ideograph>) 7240 0x9051 遑 (<CJK Ideograph>) 7241 0x9052 遒 (<CJK Ideograph>) 7242 0x900E 逎 (<CJK Ideograph>) 7243 0x9049 遉 (<CJK Ideograph>) 7244 0x903E 逾 (<CJK Ideograph>) 7245 0x9056 遖 (<CJK Ideograph>) 7246 0x9058 遘 (<CJK Ideograph>) 7247 0x905E 遞 (<CJK Ideograph>) 7248 0x9068 遨 (<CJK Ideograph>) 7249 0x906F 遯 (<CJK Ideograph>) 7250 0x9076 遶 (<CJK Ideograph>) 7251 0x96A8 隨 (<CJK Ideograph>) 7252 0x9072 遲 (<CJK Ideograph>) 7253 0x9082 邂 (<CJK Ideograph>) 7254 0x907D 遽 (<CJK Ideograph>) 7255 0x9081 邁 (<CJK Ideograph>) 7256 0x9080 邀 (<CJK Ideograph>) 7257 0x908A 邊 (<CJK Ideograph>) 7258 0x9089 邉 (<CJK Ideograph>) 7259 0x908F 邏 (<CJK Ideograph>) 7260 0x90A8 邨 (<CJK Ideograph>) 7261 0x90AF 邯 (<CJK Ideograph>) 7262 0x90B1 邱 (<CJK Ideograph>) 7263 0x90B5 邵 (<CJK Ideograph>) 7264 0x90E2 郢 (<CJK Ideograph>) 7265 0x90E4 郤 (<CJK Ideograph>) 7266 0x6248 扈 (<CJK Ideograph>) 7267 0x90DB 郛 (<CJK Ideograph>) 7268 0x9102 鄂 (<CJK Ideograph>) 7269 0x9112 鄒 (<CJK Ideograph>) 7270 0x9119 鄙 (<CJK Ideograph>) 7271 0x9132 鄲 (<CJK Ideograph>) 7272 0x9130 鄰 (<CJK Ideograph>) 7273 0x914A 酊 (<CJK Ideograph>) 7274 0x9156 酖 (<CJK Ideograph>) 7275 0x9158 酘 (<CJK Ideograph>) 7276 0x9163 酣 (<CJK Ideograph>) 7277 0x9165 酥 (<CJK Ideograph>) 7278 0x9169 酩 (<CJK Ideograph>) 7279 0x9173 酳 (<CJK Ideograph>) 7280 0x9172 酲 (<CJK Ideograph>) 7281 0x918B 醋 (<CJK Ideograph>) 7282 0x9189 醉 (<CJK Ideograph>) 7283 0x9182 醂 (<CJK Ideograph>) 7284 0x91A2 醢 (<CJK Ideograph>) 7285 0x91AB 醫 (<CJK Ideograph>) 7286 0x91AF 醯 (<CJK Ideograph>) 7287 0x91AA 醪 (<CJK Ideograph>) 7288 0x91B5 醵 (<CJK Ideograph>) 7289 0x91B4 醴 (<CJK Ideograph>) 7290 0x91BA 醺 (<CJK Ideograph>) 7291 0x91C0 釀 (<CJK Ideograph>) 7292 0x91C1 釁 (<CJK Ideograph>) 7293 0x91C9 釉 (<CJK Ideograph>) 7294 0x91CB 釋 (<CJK Ideograph>) 7295 0x91D0 釐 (<CJK Ideograph>) 7296 0x91D6 釖 (<CJK Ideograph>) 7297 0x91DF 釟 (<CJK Ideograph>) 7298 0x91E1 釡 (<CJK Ideograph>) 7299 0x91DB 釛 (<CJK Ideograph>) 7300 0x91FC 釼 (<CJK Ideograph>) 7301 0x91F5 釵 (<CJK Ideograph>) 7302 0x91F6 釶 (<CJK Ideograph>) 7303 0x921E 鈞 (<CJK Ideograph>) 7304 0x91FF 釿 (<CJK Ideograph>) 7305 0x9214 鈔 (<CJK Ideograph>) 7306 0x922C 鈬 (<CJK Ideograph>) 7307 0x9215 鈕 (<CJK Ideograph>) 7308 0x9211 鈑 (<CJK Ideograph>) 7309 0x925E 鉞 (<CJK Ideograph>) 7310 0x9257 鉗 (<CJK Ideograph>) 7311 0x9245 鉅 (<CJK Ideograph>) 7312 0x9249 鉉 (<CJK Ideograph>) 7313 0x9264 鉤 (<CJK Ideograph>) 7314 0x9248 鉈 (<CJK Ideograph>) 7315 0x9295 銕 (<CJK Ideograph>) 7316 0x923F 鈿 (<CJK Ideograph>) 7317 0x924B 鉋 (<CJK Ideograph>) 7318 0x9250 鉐 (<CJK Ideograph>) 7319 0x929C 銜 (<CJK Ideograph>) 7320 0x9296 銖 (<CJK Ideograph>) 7321 0x9293 銓 (<CJK Ideograph>) 7322 0x929B 銛 (<CJK Ideograph>) 7323 0x925A 鉚 (<CJK Ideograph>) 7324 0x92CF 鋏 (<CJK Ideograph>) 7325 0x92B9 銹 (<CJK Ideograph>) 7326 0x92B7 銷 (<CJK Ideograph>) 7327 0x92E9 鋩 (<CJK Ideograph>) 7328 0x930F 錏 (<CJK Ideograph>) 7329 0x92FA 鋺 (<CJK Ideograph>) 7330 0x9344 鍄 (<CJK Ideograph>) 7331 0x932E 錮 (<CJK Ideograph>) 7332 0x9319 錙 (<CJK Ideograph>) 7333 0x9322 錢 (<CJK Ideograph>) 7334 0x931A 錚 (<CJK Ideograph>) 7335 0x9323 錣 (<CJK Ideograph>) 7336 0x933A 錺 (<CJK Ideograph>) 7337 0x9335 錵 (<CJK Ideograph>) 7338 0x933B 錻 (<CJK Ideograph>) 7339 0x935C 鍜 (<CJK Ideograph>) 7340 0x9360 鍠 (<CJK Ideograph>) 7341 0x937C 鍼 (<CJK Ideograph>) 7342 0x936E 鍮 (<CJK Ideograph>) 7343 0x9356 鍖 (<CJK Ideograph>) 7344 0x93B0 鎰 (<CJK Ideograph>) 7345 0x93AC 鎬 (<CJK Ideograph>) 7346 0x93AD 鎭 (<CJK Ideograph>) 7347 0x9394 鎔 (<CJK Ideograph>) 7348 0x93B9 鎹 (<CJK Ideograph>) 7349 0x93D6 鏖 (<CJK Ideograph>) 7350 0x93D7 鏗 (<CJK Ideograph>) 7351 0x93E8 鏨 (<CJK Ideograph>) 7352 0x93E5 鏥 (<CJK Ideograph>) 7353 0x93D8 鏘 (<CJK Ideograph>) 7354 0x93C3 鏃 (<CJK Ideograph>) 7355 0x93DD 鏝 (<CJK Ideograph>) 7356 0x93D0 鏐 (<CJK Ideograph>) 7357 0x93C8 鏈 (<CJK Ideograph>) 7358 0x93E4 鏤 (<CJK Ideograph>) 7359 0x941A 鐚 (<CJK Ideograph>) 7360 0x9414 鐔 (<CJK Ideograph>) 7361 0x9413 鐓 (<CJK Ideograph>) 7362 0x9403 鐃 (<CJK Ideograph>) 7363 0x9407 鐇 (<CJK Ideograph>) 7364 0x9410 鐐 (<CJK Ideograph>) 7365 0x9436 鐶 (<CJK Ideograph>) 7366 0x942B 鐫 (<CJK Ideograph>) 7367 0x9435 鐵 (<CJK Ideograph>) 7368 0x9421 鐡 (<CJK Ideograph>) 7369 0x943A 鐺 (<CJK Ideograph>) 7370 0x9441 鑁 (<CJK Ideograph>) 7371 0x9452 鑒 (<CJK Ideograph>) 7372 0x9444 鑄 (<CJK Ideograph>) 7373 0x945B 鑛 (<CJK Ideograph>) 7374 0x9460 鑠 (<CJK Ideograph>) 7375 0x9462 鑢 (<CJK Ideograph>) 7376 0x945E 鑞 (<CJK Ideograph>) 7377 0x946A 鑪 (<CJK Ideograph>) 7378 0x9229 鈩 (<CJK Ideograph>) 7379 0x9470 鑰 (<CJK Ideograph>) 7380 0x9475 鑵 (<CJK Ideograph>) 7381 0x9477 鑷 (<CJK Ideograph>) 7382 0x947D 鑽 (<CJK Ideograph>) 7383 0x945A 鑚 (<CJK Ideograph>) 7384 0x947C 鑼 (<CJK Ideograph>) 7385 0x947E 鑾 (<CJK Ideograph>) 7386 0x9481 钁 (<CJK Ideograph>) 7387 0x947F 鑿 (<CJK Ideograph>) 7388 0x9582 閂 (<CJK Ideograph>) 7389 0x9587 閇 (<CJK Ideograph>) 7390 0x958A 閊 (<CJK Ideograph>) 7391 0x9594 閔 (<CJK Ideograph>) 7392 0x9596 閖 (<CJK Ideograph>) 7393 0x9598 閘 (<CJK Ideograph>) 7394 0x9599 閙 (<CJK Ideograph>) 7395 0x95A0 閠 (<CJK Ideograph>) 7396 0x95A8 閨 (<CJK Ideograph>) 7397 0x95A7 閧 (<CJK Ideograph>) 7398 0x95AD 閭 (<CJK Ideograph>) 7399 0x95BC 閼 (<CJK Ideograph>) 7400 0x95BB 閻 (<CJK Ideograph>) 7401 0x95B9 閹 (<CJK Ideograph>) 7402 0x95BE 閾 (<CJK Ideograph>) 7403 0x95CA 闊 (<CJK Ideograph>) 7404 0x6FF6 濶 (<CJK Ideograph>) 7405 0x95C3 闃 (<CJK Ideograph>) 7406 0x95CD 闍 (<CJK Ideograph>) 7407 0x95CC 闌 (<CJK Ideograph>) 7408 0x95D5 闕 (<CJK Ideograph>) 7409 0x95D4 闔 (<CJK Ideograph>) 7410 0x95D6 闖 (<CJK Ideograph>) 7411 0x95DC 關 (<CJK Ideograph>) 7412 0x95E1 闡 (<CJK Ideograph>) 7413 0x95E5 闥 (<CJK Ideograph>) 7414 0x95E2 闢 (<CJK Ideograph>) 7415 0x9621 阡 (<CJK Ideograph>) 7416 0x9628 阨 (<CJK Ideograph>) 7417 0x962E 阮 (<CJK Ideograph>) 7418 0x962F 阯 (<CJK Ideograph>) 7419 0x9642 陂 (<CJK Ideograph>) 7420 0x964C 陌 (<CJK Ideograph>) 7421 0x964F 陏 (<CJK Ideograph>) 7422 0x964B 陋 (<CJK Ideograph>) 7423 0x9677 陷 (<CJK Ideograph>) 7424 0x965C 陜 (<CJK Ideograph>) 7425 0x965E 陞 (<CJK Ideograph>) 7426 0x965D 陝 (<CJK Ideograph>) 7427 0x965F 陟 (<CJK Ideograph>) 7428 0x9666 陦 (<CJK Ideograph>) 7429 0x9672 陲 (<CJK Ideograph>) 7430 0x966C 陬 (<CJK Ideograph>) 7431 0x968D 隍 (<CJK Ideograph>) 7432 0x9698 隘 (<CJK Ideograph>) 7433 0x9695 隕 (<CJK Ideograph>) 7434 0x9697 隗 (<CJK Ideograph>) 7435 0x96AA 險 (<CJK Ideograph>) 7436 0x96A7 隧 (<CJK Ideograph>) 7437 0x96B1 隱 (<CJK Ideograph>) 7438 0x96B2 隲 (<CJK Ideograph>) 7439 0x96B0 隰 (<CJK Ideograph>) 7440 0x96B4 隴 (<CJK Ideograph>) 7441 0x96B6 隶 (<CJK Ideograph>) 7442 0x96B8 隸 (<CJK Ideograph>) 7443 0x96B9 隹 (<CJK Ideograph>) 7444 0x96CE 雎 (<CJK Ideograph>) 7445 0x96CB 雋 (<CJK Ideograph>) 7446 0x96C9 雉 (<CJK Ideograph>) 7447 0x96CD 雍 (<CJK Ideograph>) 7448 0x894D 襍 (<CJK Ideograph>) 7449 0x96DC 雜 (<CJK Ideograph>) 7450 0x970D 霍 (<CJK Ideograph>) 7451 0x96D5 雕 (<CJK Ideograph>) 7452 0x96F9 雹 (<CJK Ideograph>) 7453 0x9704 霄 (<CJK Ideograph>) 7454 0x9706 霆 (<CJK Ideograph>) 7455 0x9708 霈 (<CJK Ideograph>) 7456 0x9713 霓 (<CJK Ideograph>) 7457 0x970E 霎 (<CJK Ideograph>) 7458 0x9711 霑 (<CJK Ideograph>) 7459 0x970F 霏 (<CJK Ideograph>) 7460 0x9716 霖 (<CJK Ideograph>) 7461 0x9719 霙 (<CJK Ideograph>) 7462 0x9724 霤 (<CJK Ideograph>) 7463 0x972A 霪 (<CJK Ideograph>) 7464 0x9730 霰 (<CJK Ideograph>) 7465 0x9739 霹 (<CJK Ideograph>) 7466 0x973D 霽 (<CJK Ideograph>) 7467 0x973E 霾 (<CJK Ideograph>) 7468 0x9744 靄 (<CJK Ideograph>) 7469 0x9746 靆 (<CJK Ideograph>) 7470 0x9748 靈 (<CJK Ideograph>) 7471 0x9742 靂 (<CJK Ideograph>) 7472 0x9749 靉 (<CJK Ideograph>) 7473 0x975C 靜 (<CJK Ideograph>) 7474 0x9760 靠 (<CJK Ideograph>) 7475 0x9764 靤 (<CJK Ideograph>) 7476 0x9766 靦 (<CJK Ideograph>) 7477 0x9768 靨 (<CJK Ideograph>) 7478 0x52D2 勒 (<CJK Ideograph>) 7479 0x976B 靫 (<CJK Ideograph>) 7480 0x9771 靱 (<CJK Ideograph>) 7481 0x9779 靹 (<CJK Ideograph>) 7482 0x9785 鞅 (<CJK Ideograph>) 7483 0x977C 靼 (<CJK Ideograph>) 7484 0x9781 鞁 (<CJK Ideograph>) 7485 0x977A 靺 (<CJK Ideograph>) 7486 0x9786 鞆 (<CJK Ideograph>) 7487 0x978B 鞋 (<CJK Ideograph>) 7488 0x978F 鞏 (<CJK Ideograph>) 7489 0x9790 鞐 (<CJK Ideograph>) 7490 0x979C 鞜 (<CJK Ideograph>) 7491 0x97A8 鞨 (<CJK Ideograph>) 7492 0x97A6 鞦 (<CJK Ideograph>) 7493 0x97A3 鞣 (<CJK Ideograph>) 7494 0x97B3 鞳 (<CJK Ideograph>) 7495 0x97B4 鞴 (<CJK Ideograph>) 7496 0x97C3 韃 (<CJK Ideograph>) 7497 0x97C6 韆 (<CJK Ideograph>) 7498 0x97C8 韈 (<CJK Ideograph>) 7499 0x97CB 韋 (<CJK Ideograph>) 7500 0x97DC 韜 (<CJK Ideograph>) 7501 0x97ED 韭 (<CJK Ideograph>) 7502 0x9F4F 齏 (<CJK Ideograph>) 7503 0x97F2 韲 (<CJK Ideograph>) 7504 0x7ADF 竟 (<CJK Ideograph>) 7505 0x97F6 韶 (<CJK Ideograph>) 7506 0x97F5 韵 (<CJK Ideograph>) 7507 0x980F 頏 (<CJK Ideograph>) 7508 0x980C 頌 (<CJK Ideograph>) 7509 0x9838 頸 (<CJK Ideograph>) 7510 0x9824 頤 (<CJK Ideograph>) 7511 0x9821 頡 (<CJK Ideograph>) 7512 0x9837 頷 (<CJK Ideograph>) 7513 0x983D 頽 (<CJK Ideograph>) 7514 0x9846 顆 (<CJK Ideograph>) 7515 0x984F 顏 (<CJK Ideograph>) 7516 0x984B 顋 (<CJK Ideograph>) 7517 0x986B 顫 (<CJK Ideograph>) 7518 0x986F 顯 (<CJK Ideograph>) 7519 0x9870 顰 (<CJK Ideograph>) 7520 0x9871 顱 (<CJK Ideograph>) 7521 0x9874 顴 (<CJK Ideograph>) 7522 0x9873 顳 (<CJK Ideograph>) 7523 0x98AA 颪 (<CJK Ideograph>) 7524 0x98AF 颯 (<CJK Ideograph>) 7525 0x98B1 颱 (<CJK Ideograph>) 7526 0x98B6 颶 (<CJK Ideograph>) 7527 0x98C4 飄 (<CJK Ideograph>) 7528 0x98C3 飃 (<CJK Ideograph>) 7529 0x98C6 飆 (<CJK Ideograph>) 7530 0x98E9 飩 (<CJK Ideograph>) 7531 0x98EB 飫 (<CJK Ideograph>) 7532 0x9903 餃 (<CJK Ideograph>) 7533 0x9909 餉 (<CJK Ideograph>) 7534 0x9912 餒 (<CJK Ideograph>) 7535 0x9914 餔 (<CJK Ideograph>) 7536 0x9918 餘 (<CJK Ideograph>) 7537 0x9921 餡 (<CJK Ideograph>) 7538 0x991D 餝 (<CJK Ideograph>) 7539 0x991E 餞 (<CJK Ideograph>) 7540 0x9924 餤 (<CJK Ideograph>) 7541 0x9920 餠 (<CJK Ideograph>) 7542 0x992C 餬 (<CJK Ideograph>) 7543 0x992E 餮 (<CJK Ideograph>) 7544 0x993D 餽 (<CJK Ideograph>) 7545 0x993E 餾 (<CJK Ideograph>) 7546 0x9942 饂 (<CJK Ideograph>) 7547 0x9949 饉 (<CJK Ideograph>) 7548 0x9945 饅 (<CJK Ideograph>) 7549 0x9950 饐 (<CJK Ideograph>) 7550 0x994B 饋 (<CJK Ideograph>) 7551 0x9951 饑 (<CJK Ideograph>) 7552 0x9952 饒 (<CJK Ideograph>) 7553 0x994C 饌 (<CJK Ideograph>) 7554 0x9955 饕 (<CJK Ideograph>) 7555 0x9997 馗 (<CJK Ideograph>) 7556 0x9998 馘 (<CJK Ideograph>) 7557 0x99A5 馥 (<CJK Ideograph>) 7558 0x99AD 馭 (<CJK Ideograph>) 7559 0x99AE 馮 (<CJK Ideograph>) 7560 0x99BC 馼 (<CJK Ideograph>) 7561 0x99DF 駟 (<CJK Ideograph>) 7562 0x99DB 駛 (<CJK Ideograph>) 7563 0x99DD 駝 (<CJK Ideograph>) 7564 0x99D8 駘 (<CJK Ideograph>) 7565 0x99D1 駑 (<CJK Ideograph>) 7566 0x99ED 駭 (<CJK Ideograph>) 7567 0x99EE 駮 (<CJK Ideograph>) 7568 0x99F1 駱 (<CJK Ideograph>) 7569 0x99F2 駲 (<CJK Ideograph>) 7570 0x99FB 駻 (<CJK Ideograph>) 7571 0x99F8 駸 (<CJK Ideograph>) 7572 0x9A01 騁 (<CJK Ideograph>) 7573 0x9A0F 騏 (<CJK Ideograph>) 7574 0x9A05 騅 (<CJK Ideograph>) 7575 0x99E2 駢 (<CJK Ideograph>) 7576 0x9A19 騙 (<CJK Ideograph>) 7577 0x9A2B 騫 (<CJK Ideograph>) 7578 0x9A37 騷 (<CJK Ideograph>) 7579 0x9A45 驅 (<CJK Ideograph>) 7580 0x9A42 驂 (<CJK Ideograph>) 7581 0x9A40 驀 (<CJK Ideograph>) 7582 0x9A43 驃 (<CJK Ideograph>) 7583 0x9A3E 騾 (<CJK Ideograph>) 7584 0x9A55 驕 (<CJK Ideograph>) 7585 0x9A4D 驍 (<CJK Ideograph>) 7586 0x9A5B 驛 (<CJK Ideograph>) 7587 0x9A57 驗 (<CJK Ideograph>) 7588 0x9A5F 驟 (<CJK Ideograph>) 7589 0x9A62 驢 (<CJK Ideograph>) 7590 0x9A65 驥 (<CJK Ideograph>) 7591 0x9A64 驤 (<CJK Ideograph>) 7592 0x9A69 驩 (<CJK Ideograph>) 7593 0x9A6B 驫 (<CJK Ideograph>) 7594 0x9A6A 驪 (<CJK Ideograph>) 7595 0x9AAD 骭 (<CJK Ideograph>) 7596 0x9AB0 骰 (<CJK Ideograph>) 7597 0x9ABC 骼 (<CJK Ideograph>) 7598 0x9AC0 髀 (<CJK Ideograph>) 7599 0x9ACF 髏 (<CJK Ideograph>) 7600 0x9AD1 髑 (<CJK Ideograph>) 7601 0x9AD3 髓 (<CJK Ideograph>) 7602 0x9AD4 體 (<CJK Ideograph>) 7603 0x9ADE 髞 (<CJK Ideograph>) 7604 0x9ADF 髟 (<CJK Ideograph>) 7605 0x9AE2 髢 (<CJK Ideograph>) 7606 0x9AE3 髣 (<CJK Ideograph>) 7607 0x9AE6 髦 (<CJK Ideograph>) 7608 0x9AEF 髯 (<CJK Ideograph>) 7609 0x9AEB 髫 (<CJK Ideograph>) 7610 0x9AEE 髮 (<CJK Ideograph>) 7611 0x9AF4 髴 (<CJK Ideograph>) 7612 0x9AF1 髱 (<CJK Ideograph>) 7613 0x9AF7 髷 (<CJK Ideograph>) 7614 0x9AFB 髻 (<CJK Ideograph>) 7615 0x9B06 鬆 (<CJK Ideograph>) 7616 0x9B18 鬘 (<CJK Ideograph>) 7617 0x9B1A 鬚 (<CJK Ideograph>) 7618 0x9B1F 鬟 (<CJK Ideograph>) 7619 0x9B22 鬢 (<CJK Ideograph>) 7620 0x9B23 鬣 (<CJK Ideograph>) 7621 0x9B25 鬥 (<CJK Ideograph>) 7622 0x9B27 鬧 (<CJK Ideograph>) 7623 0x9B28 鬨 (<CJK Ideograph>) 7624 0x9B29 鬩 (<CJK Ideograph>) 7625 0x9B2A 鬪 (<CJK Ideograph>) 7626 0x9B2E 鬮 (<CJK Ideograph>) 7627 0x9B2F 鬯 (<CJK Ideograph>) 7628 0x9B32 鬲 (<CJK Ideograph>) 7629 0x9B44 魄 (<CJK Ideograph>) 7630 0x9B43 魃 (<CJK Ideograph>) 7631 0x9B4F 魏 (<CJK Ideograph>) 7632 0x9B4D 魍 (<CJK Ideograph>) 7633 0x9B4E 魎 (<CJK Ideograph>) 7634 0x9B51 魑 (<CJK Ideograph>) 7635 0x9B58 魘 (<CJK Ideograph>) 7636 0x9B74 魴 (<CJK Ideograph>) 7637 0x9B93 鮓 (<CJK Ideograph>) 7638 0x9B83 鮃 (<CJK Ideograph>) 7639 0x9B91 鮑 (<CJK Ideograph>) 7640 0x9B96 鮖 (<CJK Ideograph>) 7641 0x9B97 鮗 (<CJK Ideograph>) 7642 0x9B9F 鮟 (<CJK Ideograph>) 7643 0x9BA0 鮠 (<CJK Ideograph>) 7644 0x9BA8 鮨 (<CJK Ideograph>) 7645 0x9BB4 鮴 (<CJK Ideograph>) 7646 0x9BC0 鯀 (<CJK Ideograph>) 7647 0x9BCA 鯊 (<CJK Ideograph>) 7648 0x9BB9 鮹 (<CJK Ideograph>) 7649 0x9BC6 鯆 (<CJK Ideograph>) 7650 0x9BCF 鯏 (<CJK Ideograph>) 7651 0x9BD1 鯑 (<CJK Ideograph>) 7652 0x9BD2 鯒 (<CJK Ideograph>) 7653 0x9BE3 鯣 (<CJK Ideograph>) 7654 0x9BE2 鯢 (<CJK Ideograph>) 7655 0x9BE4 鯤 (<CJK Ideograph>) 7656 0x9BD4 鯔 (<CJK Ideograph>) 7657 0x9BE1 鯡 (<CJK Ideograph>) 7658 0x9C3A 鰺 (<CJK Ideograph>) 7659 0x9BF2 鯲 (<CJK Ideograph>) 7660 0x9BF1 鯱 (<CJK Ideograph>) 7661 0x9BF0 鯰 (<CJK Ideograph>) 7662 0x9C15 鰕 (<CJK Ideograph>) 7663 0x9C14 鰔 (<CJK Ideograph>) 7664 0x9C09 鰉 (<CJK Ideograph>) 7665 0x9C13 鰓 (<CJK Ideograph>) 7666 0x9C0C 鰌 (<CJK Ideograph>) 7667 0x9C06 鰆 (<CJK Ideograph>) 7668 0x9C08 鰈 (<CJK Ideograph>) 7669 0x9C12 鰒 (<CJK Ideograph>) 7670 0x9C0A 鰊 (<CJK Ideograph>) 7671 0x9C04 鰄 (<CJK Ideograph>) 7672 0x9C2E 鰮 (<CJK Ideograph>) 7673 0x9C1B 鰛 (<CJK Ideograph>) 7674 0x9C25 鰥 (<CJK Ideograph>) 7675 0x9C24 鰤 (<CJK Ideograph>) 7676 0x9C21 鰡 (<CJK Ideograph>) 7677 0x9C30 鰰 (<CJK Ideograph>) 7678 0x9C47 鱇 (<CJK Ideograph>) 7679 0x9C32 鰲 (<CJK Ideograph>) 7680 0x9C46 鱆 (<CJK Ideograph>) 7681 0x9C3E 鰾 (<CJK Ideograph>) 7682 0x9C5A 鱚 (<CJK Ideograph>) 7683 0x9C60 鱠 (<CJK Ideograph>) 7684 0x9C67 鱧 (<CJK Ideograph>) 7685 0x9C76 鱶 (<CJK Ideograph>) 7686 0x9C78 鱸 (<CJK Ideograph>) 7687 0x9CE7 鳧 (<CJK Ideograph>) 7688 0x9CEC 鳬 (<CJK Ideograph>) 7689 0x9CF0 鳰 (<CJK Ideograph>) 7690 0x9D09 鴉 (<CJK Ideograph>) 7691 0x9D08 鴈 (<CJK Ideograph>) 7692 0x9CEB 鳫 (<CJK Ideograph>) 7693 0x9D03 鴃 (<CJK Ideograph>) 7694 0x9D06 鴆 (<CJK Ideograph>) 7695 0x9D2A 鴪 (<CJK Ideograph>) 7696 0x9D26 鴦 (<CJK Ideograph>) 7697 0x9DAF 鶯 (<CJK Ideograph>) 7698 0x9D23 鴣 (<CJK Ideograph>) 7699 0x9D1F 鴟 (<CJK Ideograph>) 7700 0x9D44 鵄 (<CJK Ideograph>) 7701 0x9D15 鴕 (<CJK Ideograph>) 7702 0x9D12 鴒 (<CJK Ideograph>) 7703 0x9D41 鵁 (<CJK Ideograph>) 7704 0x9D3F 鴿 (<CJK Ideograph>) 7705 0x9D3E 鴾 (<CJK Ideograph>) 7706 0x9D46 鵆 (<CJK Ideograph>) 7707 0x9D48 鵈 (<CJK Ideograph>) 7708 0x9D5D 鵝 (<CJK Ideograph>) 7709 0x9D5E 鵞 (<CJK Ideograph>) 7710 0x9D64 鵤 (<CJK Ideograph>) 7711 0x9D51 鵑 (<CJK Ideograph>) 7712 0x9D50 鵐 (<CJK Ideograph>) 7713 0x9D59 鵙 (<CJK Ideograph>) 7714 0x9D72 鵲 (<CJK Ideograph>) 7715 0x9D89 鶉 (<CJK Ideograph>) 7716 0x9D87 鶇 (<CJK Ideograph>) 7717 0x9DAB 鶫 (<CJK Ideograph>) 7718 0x9D6F 鵯 (<CJK Ideograph>) 7719 0x9D7A 鵺 (<CJK Ideograph>) 7720 0x9D9A 鶚 (<CJK Ideograph>) 7721 0x9DA4 鶤 (<CJK Ideograph>) 7722 0x9DA9 鶩 (<CJK Ideograph>) 7723 0x9DB2 鶲 (<CJK Ideograph>) 7724 0x9DC4 鷄 (<CJK Ideograph>) 7725 0x9DC1 鷁 (<CJK Ideograph>) 7726 0x9DBB 鶻 (<CJK Ideograph>) 7727 0x9DB8 鶸 (<CJK Ideograph>) 7728 0x9DBA 鶺 (<CJK Ideograph>) 7729 0x9DC6 鷆 (<CJK Ideograph>) 7730 0x9DCF 鷏 (<CJK Ideograph>) 7731 0x9DC2 鷂 (<CJK Ideograph>) 7732 0x9DD9 鷙 (<CJK Ideograph>) 7733 0x9DD3 鷓 (<CJK Ideograph>) 7734 0x9DF8 鷸 (<CJK Ideograph>) 7735 0x9DE6 鷦 (<CJK Ideograph>) 7736 0x9DED 鷭 (<CJK Ideograph>) 7737 0x9DEF 鷯 (<CJK Ideograph>) 7738 0x9DFD 鷽 (<CJK Ideograph>) 7739 0x9E1A 鸚 (<CJK Ideograph>) 7740 0x9E1B 鸛 (<CJK Ideograph>) 7741 0x9E1E 鸞 (<CJK Ideograph>) 7742 0x9E75 鹵 (<CJK Ideograph>) 7743 0x9E79 鹹 (<CJK Ideograph>) 7744 0x9E7D 鹽 (<CJK Ideograph>) 7745 0x9E81 麁 (<CJK Ideograph>) 7746 0x9E88 麈 (<CJK Ideograph>) 7747 0x9E8B 麋 (<CJK Ideograph>) 7748 0x9E8C 麌 (<CJK Ideograph>) 7749 0x9E92 麒 (<CJK Ideograph>) 7750 0x9E95 麕 (<CJK Ideograph>) 7751 0x9E91 麑 (<CJK Ideograph>) 7752 0x9E9D 麝 (<CJK Ideograph>) 7753 0x9EA5 麥 (<CJK Ideograph>) 7754 0x9EA9 麩 (<CJK Ideograph>) 7755 0x9EB8 麸 (<CJK Ideograph>) 7756 0x9EAA 麪 (<CJK Ideograph>) 7757 0x9EAD 麭 (<CJK Ideograph>) 7758 0x9761 靡 (<CJK Ideograph>) 7759 0x9ECC 黌 (<CJK Ideograph>) 7760 0x9ECE 黎 (<CJK Ideograph>) 7761 0x9ECF 黏 (<CJK Ideograph>) 7762 0x9ED0 黐 (<CJK Ideograph>) 7763 0x9ED4 黔 (<CJK Ideograph>) 7764 0x9EDC 黜 (<CJK Ideograph>) 7765 0x9EDE 點 (<CJK Ideograph>) 7766 0x9EDD 黝 (<CJK Ideograph>) 7767 0x9EE0 黠 (<CJK Ideograph>) 7768 0x9EE5 黥 (<CJK Ideograph>) 7769 0x9EE8 黨 (<CJK Ideograph>) 7770 0x9EEF 黯 (<CJK Ideograph>) 7771 0x9EF4 黴 (<CJK Ideograph>) 7772 0x9EF6 黶 (<CJK Ideograph>) 7773 0x9EF7 黷 (<CJK Ideograph>) 7774 0x9EF9 黹 (<CJK Ideograph>) 7775 0x9EFB 黻 (<CJK Ideograph>) 7776 0x9EFC 黼 (<CJK Ideograph>) 7777 0x9EFD 黽 (<CJK Ideograph>) 7778 0x9F07 鼇 (<CJK Ideograph>) 7779 0x9F08 鼈 (<CJK Ideograph>) 7780 0x76B7 皷 (<CJK Ideograph>) 7781 0x9F15 鼕 (<CJK Ideograph>) 7782 0x9F21 鼡 (<CJK Ideograph>) 7783 0x9F2C 鼬 (<CJK Ideograph>) 7784 0x9F3E 鼾 (<CJK Ideograph>) 7785 0x9F4A 齊 (<CJK Ideograph>) 7786 0x9F52 齒 (<CJK Ideograph>) 7787 0x9F54 齔 (<CJK Ideograph>) 7788 0x9F63 齣 (<CJK Ideograph>) 7789 0x9F5F 齟 (<CJK Ideograph>) 7790 0x9F60 齠 (<CJK Ideograph>) 7791 0x9F61 齡 (<CJK Ideograph>) 7792 0x9F66 齦 (<CJK Ideograph>) 7793 0x9F67 齧 (<CJK Ideograph>) 7794 0x9F6C 齬 (<CJK Ideograph>) 7795 0x9F6A 齪 (<CJK Ideograph>) 7796 0x9F77 齷 (<CJK Ideograph>) 7797 0x9F72 齲 (<CJK Ideograph>) 7798 0x9F76 齶 (<CJK Ideograph>) 7799 0x9F95 龕 (<CJK Ideograph>) 7800 0x9F9C 龜 (<CJK Ideograph>) 7801 0x9FA0 龠 (<CJK Ideograph>) 7802 0x582F 堯 (<CJK Ideograph>) 7803 0x69C7 槇 (<CJK Ideograph>) 7804 0x9059 遙 (<CJK Ideograph>) 7805 0x7464 瑤 (<CJK Ideograph>) 7806 0x51DC 凜 (<CJK Ideograph>) 7807 0x7199 熙 (<CJK Ideograph>) 8272 0x7E8A 纊 (<CJK Ideograph>) 8273 0x891C 褜 (<CJK Ideograph>) 8274 0x9348 鍈 (<CJK Ideograph>) 8275 0x9288 銈 (<CJK Ideograph>) 8276 0x84DC 蓜 (<CJK Ideograph>) 8277 0x4FC9 俉 (<CJK Ideograph>) 8278 0x70BB 炻 (<CJK Ideograph>) 8279 0x6631 昱 (<CJK Ideograph>) 8280 0x68C8 棈 (<CJK Ideograph>) 8281 0x92F9 鋹 (<CJK Ideograph>) 8282 0x66FB 曻 (<CJK Ideograph>) 8283 0x5F45 彅 (<CJK Ideograph>) 8284 0x4E28 丨 (<CJK Ideograph>) 8285 0x4EE1 仡 (<CJK Ideograph>) 8286 0x4EFC 仼 (<CJK Ideograph>) 8287 0x4F00 伀 (<CJK Ideograph>) 8288 0x4F03 伃 (<CJK Ideograph>) 8289 0x4F39 伹 (<CJK Ideograph>) 8290 0x4F56 佖 (<CJK Ideograph>) 8291 0x4F92 侒 (<CJK Ideograph>) 8292 0x4F8A 侊 (<CJK Ideograph>) 8293 0x4F9A 侚 (<CJK Ideograph>) 8294 0x4F94 侔 (<CJK Ideograph>) 8295 0x4FCD 俍 (<CJK Ideograph>) 8296 0x5040 偀 (<CJK Ideograph>) 8297 0x5022 倢 (<CJK Ideograph>) 8298 0x4FFF 俿 (<CJK Ideograph>) 8299 0x501E 倞 (<CJK Ideograph>) 8300 0x5046 偆 (<CJK Ideograph>) 8301 0x5070 偰 (<CJK Ideograph>) 8302 0x5042 偂 (<CJK Ideograph>) 8303 0x5094 傔 (<CJK Ideograph>) 8304 0x50F4 僴 (<CJK Ideograph>) 8305 0x50D8 僘 (<CJK Ideograph>) 8306 0x514A 兊 (<CJK Ideograph>) 8307 0x5164 兤 (<CJK Ideograph>) 8308 0x519D 冝 (<CJK Ideograph>) 8309 0x51BE 冾 (<CJK Ideograph>) 8310 0x51EC 凬 (<CJK Ideograph>) 8311 0x5215 刕 (<CJK Ideograph>) 8312 0x529C 劜 (<CJK Ideograph>) 8313 0x52A6 劦 (<CJK Ideograph>) 8314 0x52C0 勀 (<CJK Ideograph>) 8315 0x52DB 勛 (<CJK Ideograph>) 8316 0x5300 匀 (<CJK Ideograph>) 8317 0x5307 匇 (<CJK Ideograph>) 8318 0x5324 匤 (<CJK Ideograph>) 8319 0x5372 卲 (<CJK Ideograph>) 8320 0x5393 厓 (<CJK Ideograph>) 8321 0x53B2 厲 (<CJK Ideograph>) 8322 0x53DD 叝 (<CJK Ideograph>) 8323 0xFA0E 﨎 (CJK COMPATIBILITY IDEOGRAPH-FA0E) 8324 0x549C 咜 (<CJK Ideograph>) 8325 0x548A 咊 (<CJK Ideograph>) 8326 0x54A9 咩 (<CJK Ideograph>) 8327 0x54FF 哿 (<CJK Ideograph>) 8328 0x5586 喆 (<CJK Ideograph>) 8329 0x5759 坙 (<CJK Ideograph>) 8330 0x5765 坥 (<CJK Ideograph>) 8331 0x57AC 垬 (<CJK Ideograph>) 8332 0x57C8 埈 (<CJK Ideograph>) 8333 0x57C7 埇 (<CJK Ideograph>) 8334 0xFA0F 﨏 (CJK COMPATIBILITY IDEOGRAPH-FA0F) 8335 0xFA10 塚 (CJK COMPATIBILITY IDEOGRAPH-FA10) 8336 0x589E 增 (<CJK Ideograph>) 8337 0x58B2 墲 (<CJK Ideograph>) 8338 0x590B 夋 (<CJK Ideograph>) 8339 0x5953 奓 (<CJK Ideograph>) 8340 0x595B 奛 (<CJK Ideograph>) 8341 0x595D 奝 (<CJK Ideograph>) 8342 0x5963 奣 (<CJK Ideograph>) 8343 0x59A4 妤 (<CJK Ideograph>) 8344 0x59BA 妺 (<CJK Ideograph>) 8345 0x5B56 孖 (<CJK Ideograph>) 8346 0x5BC0 寀 (<CJK Ideograph>) 8347 0x752F 甯 (<CJK Ideograph>) 8348 0x5BD8 寘 (<CJK Ideograph>) 8349 0x5BEC 寬 (<CJK Ideograph>) 8350 0x5C1E 尞 (<CJK Ideograph>) 8351 0x5CA6 岦 (<CJK Ideograph>) 8352 0x5CBA 岺 (<CJK Ideograph>) 8353 0x5CF5 峵 (<CJK Ideograph>) 8354 0x5D27 崧 (<CJK Ideograph>) 8355 0x5D53 嵓 (<CJK Ideograph>) 8356 0xFA11 﨑 (CJK COMPATIBILITY IDEOGRAPH-FA11) 8357 0x5D42 嵂 (<CJK Ideograph>) 8358 0x5D6D 嵭 (<CJK Ideograph>) 8359 0x5DB8 嶸 (<CJK Ideograph>) 8360 0x5DB9 嶹 (<CJK Ideograph>) 8361 0x5DD0 巐 (<CJK Ideograph>) 8362 0x5F21 弡 (<CJK Ideograph>) 8363 0x5F34 弴 (<CJK Ideograph>) 8364 0x5F67 彧 (<CJK Ideograph>) 8365 0x5FB7 德 (<CJK Ideograph>) 8366 0x5FDE 忞 (<CJK Ideograph>) 8367 0x605D 恝 (<CJK Ideograph>) 8368 0x6085 悅 (<CJK Ideograph>) 8369 0x608A 悊 (<CJK Ideograph>) 8370 0x60DE 惞 (<CJK Ideograph>) 8371 0x60D5 惕 (<CJK Ideograph>) 8372 0x6120 愠 (<CJK Ideograph>) 8373 0x60F2 惲 (<CJK Ideograph>) 8374 0x6111 愑 (<CJK Ideograph>) 8375 0x6137 愷 (<CJK Ideograph>) 8376 0x6130 愰 (<CJK Ideograph>) 8377 0x6198 憘 (<CJK Ideograph>) 8378 0x6213 戓 (<CJK Ideograph>) 8379 0x62A6 抦 (<CJK Ideograph>) 8380 0x63F5 揵 (<CJK Ideograph>) 8381 0x6460 摠 (<CJK Ideograph>) 8382 0x649D 撝 (<CJK Ideograph>) 8383 0x64CE 擎 (<CJK Ideograph>) 8384 0x654E 敎 (<CJK Ideograph>) 8385 0x6600 昀 (<CJK Ideograph>) 8386 0x6615 昕 (<CJK Ideograph>) 8387 0x663B 昻 (<CJK Ideograph>) 8388 0x6609 昉 (<CJK Ideograph>) 8389 0x662E 昮 (<CJK Ideograph>) 8390 0x661E 昞 (<CJK Ideograph>) 8391 0x6624 昤 (<CJK Ideograph>) 8392 0x6665 晥 (<CJK Ideograph>) 8393 0x6657 晗 (<CJK Ideograph>) 8394 0x6659 晙 (<CJK Ideograph>) 8395 0xFA12 晴 (CJK COMPATIBILITY IDEOGRAPH-FA12) 8396 0x6673 晳 (<CJK Ideograph>) 8397 0x6699 暙 (<CJK Ideograph>) 8398 0x66A0 暠 (<CJK Ideograph>) 8399 0x66B2 暲 (<CJK Ideograph>) 8400 0x66BF 暿 (<CJK Ideograph>) 8401 0x66FA 曺 (<CJK Ideograph>) 8402 0x670E 朎 (<CJK Ideograph>) 8403 0xF929 朗 (CJK COMPATIBILITY IDEOGRAPH-F929) 8404 0x6766 杦 (<CJK Ideograph>) 8405 0x67BB 枻 (<CJK Ideograph>) 8406 0x6852 桒 (<CJK Ideograph>) 8407 0x67C0 柀 (<CJK Ideograph>) 8408 0x6801 栁 (<CJK Ideograph>) 8409 0x6844 桄 (<CJK Ideograph>) 8410 0x68CF 棏 (<CJK Ideograph>) 8411 0xFA13 﨓 (CJK COMPATIBILITY IDEOGRAPH-FA13) 8412 0x6968 楨 (<CJK Ideograph>) 8413 0xFA14 﨔 (CJK COMPATIBILITY IDEOGRAPH-FA14) 8414 0x6998 榘 (<CJK Ideograph>) 8415 0x69E2 槢 (<CJK Ideograph>) 8416 0x6A30 樰 (<CJK Ideograph>) 8417 0x6A6B 橫 (<CJK Ideograph>) 8418 0x6A46 橆 (<CJK Ideograph>) 8419 0x6A73 橳 (<CJK Ideograph>) 8420 0x6A7E 橾 (<CJK Ideograph>) 8421 0x6AE2 櫢 (<CJK Ideograph>) 8422 0x6AE4 櫤 (<CJK Ideograph>) 8423 0x6BD6 毖 (<CJK Ideograph>) 8424 0x6C3F 氿 (<CJK Ideograph>) 8425 0x6C5C 汜 (<CJK Ideograph>) 8426 0x6C86 沆 (<CJK Ideograph>) 8427 0x6C6F 汯 (<CJK Ideograph>) 8428 0x6CDA 泚 (<CJK Ideograph>) 8429 0x6D04 洄 (<CJK Ideograph>) 8430 0x6D87 涇 (<CJK Ideograph>) 8431 0x6D6F 浯 (<CJK Ideograph>) 8432 0x6D96 涖 (<CJK Ideograph>) 8433 0x6DAC 涬 (<CJK Ideograph>) 8434 0x6DCF 淏 (<CJK Ideograph>) 8435 0x6DF8 淸 (<CJK Ideograph>) 8436 0x6DF2 淲 (<CJK Ideograph>) 8437 0x6DFC 淼 (<CJK Ideograph>) 8438 0x6E39 渹 (<CJK Ideograph>) 8439 0x6E5C 湜 (<CJK Ideograph>) 8440 0x6E27 渧 (<CJK Ideograph>) 8441 0x6E3C 渼 (<CJK Ideograph>) 8442 0x6EBF 溿 (<CJK Ideograph>) 8443 0x6F88 澈 (<CJK Ideograph>) 8444 0x6FB5 澵 (<CJK Ideograph>) 8445 0x6FF5 濵 (<CJK Ideograph>) 8446 0x7005 瀅 (<CJK Ideograph>) 8447 0x7007 瀇 (<CJK Ideograph>) 8448 0x7028 瀨 (<CJK Ideograph>) 8449 0x7085 炅 (<CJK Ideograph>) 8450 0x70AB 炫 (<CJK Ideograph>) 8451 0x710F 焏 (<CJK Ideograph>) 8452 0x7104 焄 (<CJK Ideograph>) 8453 0x715C 煜 (<CJK Ideograph>) 8454 0x7146 煆 (<CJK Ideograph>) 8455 0x7147 煇 (<CJK Ideograph>) 8456 0xFA15 凞 (CJK COMPATIBILITY IDEOGRAPH-FA15) 8457 0x71C1 燁 (<CJK Ideograph>) 8458 0x71FE 燾 (<CJK Ideograph>) 8459 0x72B1 犱 (<CJK Ideograph>) 8460 0x72BE 犾 (<CJK Ideograph>) 8461 0x7324 猤 (<CJK Ideograph>) 8462 0xFA16 猪 (CJK COMPATIBILITY IDEOGRAPH-FA16) 8463 0x7377 獷 (<CJK Ideograph>) 8464 0x73BD 玽 (<CJK Ideograph>) 8465 0x73C9 珉 (<CJK Ideograph>) 8466 0x73D6 珖 (<CJK Ideograph>) 8467 0x73E3 珣 (<CJK Ideograph>) 8468 0x73D2 珒 (<CJK Ideograph>) 8469 0x7407 琇 (<CJK Ideograph>) 8470 0x73F5 珵 (<CJK Ideograph>) 8471 0x7426 琦 (<CJK Ideograph>) 8472 0x742A 琪 (<CJK Ideograph>) 8473 0x7429 琩 (<CJK Ideograph>) 8474 0x742E 琮 (<CJK Ideograph>) 8475 0x7462 瑢 (<CJK Ideograph>) 8476 0x7489 璉 (<CJK Ideograph>) 8477 0x749F 璟 (<CJK Ideograph>) 8478 0x7501 甁 (<CJK Ideograph>) 8479 0x756F 畯 (<CJK Ideograph>) 8480 0x7682 皂 (<CJK Ideograph>) 8481 0x769C 皜 (<CJK Ideograph>) 8482 0x769E 皞 (<CJK Ideograph>) 8483 0x769B 皛 (<CJK Ideograph>) 8484 0x76A6 皦 (<CJK Ideograph>) 8485 0xFA17 益 (CJK COMPATIBILITY IDEOGRAPH-FA17) 8486 0x7746 睆 (<CJK Ideograph>) 8487 0x52AF 劯 (<CJK Ideograph>) 8488 0x7821 砡 (<CJK Ideograph>) 8489 0x784E 硎 (<CJK Ideograph>) 8490 0x7864 硤 (<CJK Ideograph>) 8491 0x787A 硺 (<CJK Ideograph>) 8492 0x7930 礰 (<CJK Ideograph>) 8493 0xFA18 礼 (CJK COMPATIBILITY IDEOGRAPH-FA18) 8494 0xFA19 神 (CJK COMPATIBILITY IDEOGRAPH-FA19) 8495 0xFA1A 祥 (CJK COMPATIBILITY IDEOGRAPH-FA1A) 8496 0x7994 禔 (<CJK Ideograph>) 8497 0xFA1B 福 (CJK COMPATIBILITY IDEOGRAPH-FA1B) 8498 0x799B 禛 (<CJK Ideograph>) 8499 0x7AD1 竑 (<CJK Ideograph>) 8500 0x7AE7 竧 (<CJK Ideograph>) 8501 0xFA1C 靖 (CJK COMPATIBILITY IDEOGRAPH-FA1C) 8502 0x7AEB 竫 (<CJK Ideograph>) 8503 0x7B9E 箞 (<CJK Ideograph>) 8504 0xFA1D 精 (CJK COMPATIBILITY IDEOGRAPH-FA1D) 8505 0x7D48 絈 (<CJK Ideograph>) 8506 0x7D5C 絜 (<CJK Ideograph>) 8507 0x7DB7 綷 (<CJK Ideograph>) 8508 0x7DA0 綠 (<CJK Ideograph>) 8509 0x7DD6 緖 (<CJK Ideograph>) 8510 0x7E52 繒 (<CJK Ideograph>) 8511 0x7F47 罇 (<CJK Ideograph>) 8512 0x7FA1 羡 (<CJK Ideograph>) 8513 0xFA1E 羽 (CJK COMPATIBILITY IDEOGRAPH-FA1E) 8514 0x8301 茁 (<CJK Ideograph>) 8515 0x8362 荢 (<CJK Ideograph>) 8516 0x837F 荿 (<CJK Ideograph>) 8517 0x83C7 菇 (<CJK Ideograph>) 8518 0x83F6 菶 (<CJK Ideograph>) 8519 0x8448 葈 (<CJK Ideograph>) 8520 0x84B4 蒴 (<CJK Ideograph>) 8521 0x8553 蕓 (<CJK Ideograph>) 8522 0x8559 蕙 (<CJK Ideograph>) 8523 0x856B 蕫 (<CJK Ideograph>) 8524 0xFA1F 﨟 (CJK COMPATIBILITY IDEOGRAPH-FA1F) 8525 0x85B0 薰 (<CJK Ideograph>) 8526 0xFA20 蘒 (CJK COMPATIBILITY IDEOGRAPH-FA20) 8527 0xFA21 﨡 (CJK COMPATIBILITY IDEOGRAPH-FA21) 8528 0x8807 蠇 (<CJK Ideograph>) 8529 0x88F5 裵 (<CJK Ideograph>) 8530 0x8A12 訒 (<CJK Ideograph>) 8531 0x8A37 訷 (<CJK Ideograph>) 8532 0x8A79 詹 (<CJK Ideograph>) 8533 0x8AA7 誧 (<CJK Ideograph>) 8534 0x8ABE 誾 (<CJK Ideograph>) 8535 0x8ADF 諟 (<CJK Ideograph>) 8536 0xFA22 諸 (CJK COMPATIBILITY IDEOGRAPH-FA22) 8537 0x8AF6 諶 (<CJK Ideograph>) 8538 0x8B53 譓 (<CJK Ideograph>) 8539 0x8B7F 譿 (<CJK Ideograph>) 8540 0x8CF0 賰 (<CJK Ideograph>) 8541 0x8CF4 賴 (<CJK Ideograph>) 8542 0x8D12 贒 (<CJK Ideograph>) 8543 0x8D76 赶 (<CJK Ideograph>) 8544 0xFA23 﨣 (CJK COMPATIBILITY IDEOGRAPH-FA23) 8545 0x8ECF 軏 (<CJK Ideograph>) 8546 0xFA24 﨤 (CJK COMPATIBILITY IDEOGRAPH-FA24) 8547 0xFA25 逸 (CJK COMPATIBILITY IDEOGRAPH-FA25) 8548 0x9067 遧 (<CJK Ideograph>) 8549 0x90DE 郞 (<CJK Ideograph>) 8550 0xFA26 都 (CJK COMPATIBILITY IDEOGRAPH-FA26) 8551 0x9115 鄕 (<CJK Ideograph>) 8552 0x9127 鄧 (<CJK Ideograph>) 8553 0x91DA 釚 (<CJK Ideograph>) 8554 0x91D7 釗 (<CJK Ideograph>) 8555 0x91DE 釞 (<CJK Ideograph>) 8556 0x91ED 釭 (<CJK Ideograph>) 8557 0x91EE 釮 (<CJK Ideograph>) 8558 0x91E4 釤 (<CJK Ideograph>) 8559 0x91E5 釥 (<CJK Ideograph>) 8560 0x9206 鈆 (<CJK Ideograph>) 8561 0x9210 鈐 (<CJK Ideograph>) 8562 0x920A 鈊 (<CJK Ideograph>) 8563 0x923A 鈺 (<CJK Ideograph>) 8564 0x9240 鉀 (<CJK Ideograph>) 8565 0x923C 鈼 (<CJK Ideograph>) 8566 0x924E 鉎 (<CJK Ideograph>) 8567 0x9259 鉙 (<CJK Ideograph>) 8568 0x9251 鉑 (<CJK Ideograph>) 8569 0x9239 鈹 (<CJK Ideograph>) 8570 0x9267 鉧 (<CJK Ideograph>) 8571 0x92A7 銧 (<CJK Ideograph>) 8572 0x9277 鉷 (<CJK Ideograph>) 8573 0x9278 鉸 (<CJK Ideograph>) 8574 0x92E7 鋧 (<CJK Ideograph>) 8575 0x92D7 鋗 (<CJK Ideograph>) 8576 0x92D9 鋙 (<CJK Ideograph>) 8577 0x92D0 鋐 (<CJK Ideograph>) 8578 0xFA27 﨧 (CJK COMPATIBILITY IDEOGRAPH-FA27) 8579 0x92D5 鋕 (<CJK Ideograph>) 8580 0x92E0 鋠 (<CJK Ideograph>) 8581 0x92D3 鋓 (<CJK Ideograph>) 8582 0x9325 錥 (<CJK Ideograph>) 8583 0x9321 錡 (<CJK Ideograph>) 8584 0x92FB 鋻 (<CJK Ideograph>) 8585 0xFA28 﨨 (CJK COMPATIBILITY IDEOGRAPH-FA28) 8586 0x931E 錞 (<CJK Ideograph>) 8587 0x92FF 鋿 (<CJK Ideograph>) 8588 0x931D 錝 (<CJK Ideograph>) 8589 0x9302 錂 (<CJK Ideograph>) 8590 0x9370 鍰 (<CJK Ideograph>) 8591 0x9357 鍗 (<CJK Ideograph>) 8592 0x93A4 鎤 (<CJK Ideograph>) 8593 0x93C6 鏆 (<CJK Ideograph>) 8594 0x93DE 鏞 (<CJK Ideograph>) 8595 0x93F8 鏸 (<CJK Ideograph>) 8596 0x9431 鐱 (<CJK Ideograph>) 8597 0x9445 鑅 (<CJK Ideograph>) 8598 0x9448 鑈 (<CJK Ideograph>) 8599 0x9592 閒 (<CJK Ideograph>) 8600 0xF9DC 隆 (CJK COMPATIBILITY IDEOGRAPH-F9DC) 8601 0xFA29 﨩 (CJK COMPATIBILITY IDEOGRAPH-FA29) 8602 0x969D 隝 (<CJK Ideograph>) 8603 0x96AF 隯 (<CJK Ideograph>) 8604 0x9733 霳 (<CJK Ideograph>) 8605 0x973B 霻 (<CJK Ideograph>) 8606 0x9743 靃 (<CJK Ideograph>) 8607 0x974D 靍 (<CJK Ideograph>) 8608 0x974F 靏 (<CJK Ideograph>) 8609 0x9751 靑 (<CJK Ideograph>) 8610 0x9755 靕 (<CJK Ideograph>) 8611 0x9857 顗 (<CJK Ideograph>) 8612 0x9865 顥 (<CJK Ideograph>) 8613 0xFA2A 飯 (CJK COMPATIBILITY IDEOGRAPH-FA2A) 8614 0xFA2B 飼 (CJK COMPATIBILITY IDEOGRAPH-FA2B) 8615 0x9927 餧 (<CJK Ideograph>) 8616 0xFA2C 館 (CJK COMPATIBILITY IDEOGRAPH-FA2C) 8617 0x999E 馞 (<CJK Ideograph>) 8618 0x9A4E 驎 (<CJK Ideograph>) 8619 0x9AD9 髙 (<CJK Ideograph>) 8620 0x9ADC 髜 (<CJK Ideograph>) 8621 0x9B75 魵 (<CJK Ideograph>) 8622 0x9B72 魲 (<CJK Ideograph>) 8623 0x9B8F 鮏 (<CJK Ideograph>) 8624 0x9BB1 鮱 (<CJK Ideograph>) 8625 0x9BBB 鮻 (<CJK Ideograph>) 8626 0x9C00 鰀 (<CJK Ideograph>) 8627 0x9D70 鵰 (<CJK Ideograph>) 8628 0x9D6B 鵫 (<CJK Ideograph>) 8629 0xFA2D 鶴 (CJK COMPATIBILITY IDEOGRAPH-FA2D) 8630 0x9E19 鸙 (<CJK Ideograph>) 8631 0x9ED1 黑 (<CJK Ideograph>) 8634 0x2170 ⅰ (SMALL ROMAN NUMERAL ONE) 8635 0x2171 ⅱ (SMALL ROMAN NUMERAL TWO) 8636 0x2172 ⅲ (SMALL ROMAN NUMERAL THREE) 8637 0x2173 ⅳ (SMALL ROMAN NUMERAL FOUR) 8638 0x2174 ⅴ (SMALL ROMAN NUMERAL FIVE) 8639 0x2175 ⅵ (SMALL ROMAN NUMERAL SIX) 8640 0x2176 ⅶ (SMALL ROMAN NUMERAL SEVEN) 8641 0x2177 ⅷ (SMALL ROMAN NUMERAL EIGHT) 8642 0x2178 ⅸ (SMALL ROMAN NUMERAL NINE) 8643 0x2179 ⅹ (SMALL ROMAN NUMERAL TEN) 8644 0xFFE2 ¬ (FULLWIDTH NOT SIGN) 8645 0xFFE4 ¦ (FULLWIDTH BROKEN BAR) 8646 0xFF07 ' (FULLWIDTH APOSTROPHE) 8647 0xFF02 " (FULLWIDTH QUOTATION MARK) 10716 0x2170 ⅰ (SMALL ROMAN NUMERAL ONE) 10717 0x2171 ⅱ (SMALL ROMAN NUMERAL TWO) 10718 0x2172 ⅲ (SMALL ROMAN NUMERAL THREE) 10719 0x2173 ⅳ (SMALL ROMAN NUMERAL FOUR) 10720 0x2174 ⅴ (SMALL ROMAN NUMERAL FIVE) 10721 0x2175 ⅵ (SMALL ROMAN NUMERAL SIX) 10722 0x2176 ⅶ (SMALL ROMAN NUMERAL SEVEN) 10723 0x2177 ⅷ (SMALL ROMAN NUMERAL EIGHT) 10724 0x2178 ⅸ (SMALL ROMAN NUMERAL NINE) 10725 0x2179 ⅹ (SMALL ROMAN NUMERAL TEN) 10726 0x2160 Ⅰ (ROMAN NUMERAL ONE) 10727 0x2161 Ⅱ (ROMAN NUMERAL TWO) 10728 0x2162 Ⅲ (ROMAN NUMERAL THREE) 10729 0x2163 Ⅳ (ROMAN NUMERAL FOUR) 10730 0x2164 Ⅴ (ROMAN NUMERAL FIVE) 10731 0x2165 Ⅵ (ROMAN NUMERAL SIX) 10732 0x2166 Ⅶ (ROMAN NUMERAL SEVEN) 10733 0x2167 Ⅷ (ROMAN NUMERAL EIGHT) 10734 0x2168 Ⅸ (ROMAN NUMERAL NINE) 10735 0x2169 Ⅹ (ROMAN NUMERAL TEN) 10736 0xFFE2 ¬ (FULLWIDTH NOT SIGN) 10737 0xFFE4 ¦ (FULLWIDTH BROKEN BAR) 10738 0xFF07 ' (FULLWIDTH APOSTROPHE) 10739 0xFF02 " (FULLWIDTH QUOTATION MARK) 10740 0x3231 ㈱ (PARENTHESIZED IDEOGRAPH STOCK) 10741 0x2116 № (NUMERO SIGN) 10742 0x2121 ℡ (TELEPHONE SIGN) 10743 0x2235 ∵ (BECAUSE) 10744 0x7E8A 纊 (<CJK Ideograph>) 10745 0x891C 褜 (<CJK Ideograph>) 10746 0x9348 鍈 (<CJK Ideograph>) 10747 0x9288 銈 (<CJK Ideograph>) 10748 0x84DC 蓜 (<CJK Ideograph>) 10749 0x4FC9 俉 (<CJK Ideograph>) 10750 0x70BB 炻 (<CJK Ideograph>) 10751 0x6631 昱 (<CJK Ideograph>) 10752 0x68C8 棈 (<CJK Ideograph>) 10753 0x92F9 鋹 (<CJK Ideograph>) 10754 0x66FB 曻 (<CJK Ideograph>) 10755 0x5F45 彅 (<CJK Ideograph>) 10756 0x4E28 丨 (<CJK Ideograph>) 10757 0x4EE1 仡 (<CJK Ideograph>) 10758 0x4EFC 仼 (<CJK Ideograph>) 10759 0x4F00 伀 (<CJK Ideograph>) 10760 0x4F03 伃 (<CJK Ideograph>) 10761 0x4F39 伹 (<CJK Ideograph>) 10762 0x4F56 佖 (<CJK Ideograph>) 10763 0x4F92 侒 (<CJK Ideograph>) 10764 0x4F8A 侊 (<CJK Ideograph>) 10765 0x4F9A 侚 (<CJK Ideograph>) 10766 0x4F94 侔 (<CJK Ideograph>) 10767 0x4FCD 俍 (<CJK Ideograph>) 10768 0x5040 偀 (<CJK Ideograph>) 10769 0x5022 倢 (<CJK Ideograph>) 10770 0x4FFF 俿 (<CJK Ideograph>) 10771 0x501E 倞 (<CJK Ideograph>) 10772 0x5046 偆 (<CJK Ideograph>) 10773 0x5070 偰 (<CJK Ideograph>) 10774 0x5042 偂 (<CJK Ideograph>) 10775 0x5094 傔 (<CJK Ideograph>) 10776 0x50F4 僴 (<CJK Ideograph>) 10777 0x50D8 僘 (<CJK Ideograph>) 10778 0x514A 兊 (<CJK Ideograph>) 10779 0x5164 兤 (<CJK Ideograph>) 10780 0x519D 冝 (<CJK Ideograph>) 10781 0x51BE 冾 (<CJK Ideograph>) 10782 0x51EC 凬 (<CJK Ideograph>) 10783 0x5215 刕 (<CJK Ideograph>) 10784 0x529C 劜 (<CJK Ideograph>) 10785 0x52A6 劦 (<CJK Ideograph>) 10786 0x52C0 勀 (<CJK Ideograph>) 10787 0x52DB 勛 (<CJK Ideograph>) 10788 0x5300 匀 (<CJK Ideograph>) 10789 0x5307 匇 (<CJK Ideograph>) 10790 0x5324 匤 (<CJK Ideograph>) 10791 0x5372 卲 (<CJK Ideograph>) 10792 0x5393 厓 (<CJK Ideograph>) 10793 0x53B2 厲 (<CJK Ideograph>) 10794 0x53DD 叝 (<CJK Ideograph>) 10795 0xFA0E 﨎 (CJK COMPATIBILITY IDEOGRAPH-FA0E) 10796 0x549C 咜 (<CJK Ideograph>) 10797 0x548A 咊 (<CJK Ideograph>) 10798 0x54A9 咩 (<CJK Ideograph>) 10799 0x54FF 哿 (<CJK Ideograph>) 10800 0x5586 喆 (<CJK Ideograph>) 10801 0x5759 坙 (<CJK Ideograph>) 10802 0x5765 坥 (<CJK Ideograph>) 10803 0x57AC 垬 (<CJK Ideograph>) 10804 0x57C8 埈 (<CJK Ideograph>) 10805 0x57C7 埇 (<CJK Ideograph>) 10806 0xFA0F 﨏 (CJK COMPATIBILITY IDEOGRAPH-FA0F) 10807 0xFA10 塚 (CJK COMPATIBILITY IDEOGRAPH-FA10) 10808 0x589E 增 (<CJK Ideograph>) 10809 0x58B2 墲 (<CJK Ideograph>) 10810 0x590B 夋 (<CJK Ideograph>) 10811 0x5953 奓 (<CJK Ideograph>) 10812 0x595B 奛 (<CJK Ideograph>) 10813 0x595D 奝 (<CJK Ideograph>) 10814 0x5963 奣 (<CJK Ideograph>) 10815 0x59A4 妤 (<CJK Ideograph>) 10816 0x59BA 妺 (<CJK Ideograph>) 10817 0x5B56 孖 (<CJK Ideograph>) 10818 0x5BC0 寀 (<CJK Ideograph>) 10819 0x752F 甯 (<CJK Ideograph>) 10820 0x5BD8 寘 (<CJK Ideograph>) 10821 0x5BEC 寬 (<CJK Ideograph>) 10822 0x5C1E 尞 (<CJK Ideograph>) 10823 0x5CA6 岦 (<CJK Ideograph>) 10824 0x5CBA 岺 (<CJK Ideograph>) 10825 0x5CF5 峵 (<CJK Ideograph>) 10826 0x5D27 崧 (<CJK Ideograph>) 10827 0x5D53 嵓 (<CJK Ideograph>) 10828 0xFA11 﨑 (CJK COMPATIBILITY IDEOGRAPH-FA11) 10829 0x5D42 嵂 (<CJK Ideograph>) 10830 0x5D6D 嵭 (<CJK Ideograph>) 10831 0x5DB8 嶸 (<CJK Ideograph>) 10832 0x5DB9 嶹 (<CJK Ideograph>) 10833 0x5DD0 巐 (<CJK Ideograph>) 10834 0x5F21 弡 (<CJK Ideograph>) 10835 0x5F34 弴 (<CJK Ideograph>) 10836 0x5F67 彧 (<CJK Ideograph>) 10837 0x5FB7 德 (<CJK Ideograph>) 10838 0x5FDE 忞 (<CJK Ideograph>) 10839 0x605D 恝 (<CJK Ideograph>) 10840 0x6085 悅 (<CJK Ideograph>) 10841 0x608A 悊 (<CJK Ideograph>) 10842 0x60DE 惞 (<CJK Ideograph>) 10843 0x60D5 惕 (<CJK Ideograph>) 10844 0x6120 愠 (<CJK Ideograph>) 10845 0x60F2 惲 (<CJK Ideograph>) 10846 0x6111 愑 (<CJK Ideograph>) 10847 0x6137 愷 (<CJK Ideograph>) 10848 0x6130 愰 (<CJK Ideograph>) 10849 0x6198 憘 (<CJK Ideograph>) 10850 0x6213 戓 (<CJK Ideograph>) 10851 0x62A6 抦 (<CJK Ideograph>) 10852 0x63F5 揵 (<CJK Ideograph>) 10853 0x6460 摠 (<CJK Ideograph>) 10854 0x649D 撝 (<CJK Ideograph>) 10855 0x64CE 擎 (<CJK Ideograph>) 10856 0x654E 敎 (<CJK Ideograph>) 10857 0x6600 昀 (<CJK Ideograph>) 10858 0x6615 昕 (<CJK Ideograph>) 10859 0x663B 昻 (<CJK Ideograph>) 10860 0x6609 昉 (<CJK Ideograph>) 10861 0x662E 昮 (<CJK Ideograph>) 10862 0x661E 昞 (<CJK Ideograph>) 10863 0x6624 昤 (<CJK Ideograph>) 10864 0x6665 晥 (<CJK Ideograph>) 10865 0x6657 晗 (<CJK Ideograph>) 10866 0x6659 晙 (<CJK Ideograph>) 10867 0xFA12 晴 (CJK COMPATIBILITY IDEOGRAPH-FA12) 10868 0x6673 晳 (<CJK Ideograph>) 10869 0x6699 暙 (<CJK Ideograph>) 10870 0x66A0 暠 (<CJK Ideograph>) 10871 0x66B2 暲 (<CJK Ideograph>) 10872 0x66BF 暿 (<CJK Ideograph>) 10873 0x66FA 曺 (<CJK Ideograph>) 10874 0x670E 朎 (<CJK Ideograph>) 10875 0xF929 朗 (CJK COMPATIBILITY IDEOGRAPH-F929) 10876 0x6766 杦 (<CJK Ideograph>) 10877 0x67BB 枻 (<CJK Ideograph>) 10878 0x6852 桒 (<CJK Ideograph>) 10879 0x67C0 柀 (<CJK Ideograph>) 10880 0x6801 栁 (<CJK Ideograph>) 10881 0x6844 桄 (<CJK Ideograph>) 10882 0x68CF 棏 (<CJK Ideograph>) 10883 0xFA13 﨓 (CJK COMPATIBILITY IDEOGRAPH-FA13) 10884 0x6968 楨 (<CJK Ideograph>) 10885 0xFA14 﨔 (CJK COMPATIBILITY IDEOGRAPH-FA14) 10886 0x6998 榘 (<CJK Ideograph>) 10887 0x69E2 槢 (<CJK Ideograph>) 10888 0x6A30 樰 (<CJK Ideograph>) 10889 0x6A6B 橫 (<CJK Ideograph>) 10890 0x6A46 橆 (<CJK Ideograph>) 10891 0x6A73 橳 (<CJK Ideograph>) 10892 0x6A7E 橾 (<CJK Ideograph>) 10893 0x6AE2 櫢 (<CJK Ideograph>) 10894 0x6AE4 櫤 (<CJK Ideograph>) 10895 0x6BD6 毖 (<CJK Ideograph>) 10896 0x6C3F 氿 (<CJK Ideograph>) 10897 0x6C5C 汜 (<CJK Ideograph>) 10898 0x6C86 沆 (<CJK Ideograph>) 10899 0x6C6F 汯 (<CJK Ideograph>) 10900 0x6CDA 泚 (<CJK Ideograph>) 10901 0x6D04 洄 (<CJK Ideograph>) 10902 0x6D87 涇 (<CJK Ideograph>) 10903 0x6D6F 浯 (<CJK Ideograph>) 10904 0x6D96 涖 (<CJK Ideograph>) 10905 0x6DAC 涬 (<CJK Ideograph>) 10906 0x6DCF 淏 (<CJK Ideograph>) 10907 0x6DF8 淸 (<CJK Ideograph>) 10908 0x6DF2 淲 (<CJK Ideograph>) 10909 0x6DFC 淼 (<CJK Ideograph>) 10910 0x6E39 渹 (<CJK Ideograph>) 10911 0x6E5C 湜 (<CJK Ideograph>) 10912 0x6E27 渧 (<CJK Ideograph>) 10913 0x6E3C 渼 (<CJK Ideograph>) 10914 0x6EBF 溿 (<CJK Ideograph>) 10915 0x6F88 澈 (<CJK Ideograph>) 10916 0x6FB5 澵 (<CJK Ideograph>) 10917 0x6FF5 濵 (<CJK Ideograph>) 10918 0x7005 瀅 (<CJK Ideograph>) 10919 0x7007 瀇 (<CJK Ideograph>) 10920 0x7028 瀨 (<CJK Ideograph>) 10921 0x7085 炅 (<CJK Ideograph>) 10922 0x70AB 炫 (<CJK Ideograph>) 10923 0x710F 焏 (<CJK Ideograph>) 10924 0x7104 焄 (<CJK Ideograph>) 10925 0x715C 煜 (<CJK Ideograph>) 10926 0x7146 煆 (<CJK Ideograph>) 10927 0x7147 煇 (<CJK Ideograph>) 10928 0xFA15 凞 (CJK COMPATIBILITY IDEOGRAPH-FA15) 10929 0x71C1 燁 (<CJK Ideograph>) 10930 0x71FE 燾 (<CJK Ideograph>) 10931 0x72B1 犱 (<CJK Ideograph>) 10932 0x72BE 犾 (<CJK Ideograph>) 10933 0x7324 猤 (<CJK Ideograph>) 10934 0xFA16 猪 (CJK COMPATIBILITY IDEOGRAPH-FA16) 10935 0x7377 獷 (<CJK Ideograph>) 10936 0x73BD 玽 (<CJK Ideograph>) 10937 0x73C9 珉 (<CJK Ideograph>) 10938 0x73D6 珖 (<CJK Ideograph>) 10939 0x73E3 珣 (<CJK Ideograph>) 10940 0x73D2 珒 (<CJK Ideograph>) 10941 0x7407 琇 (<CJK Ideograph>) 10942 0x73F5 珵 (<CJK Ideograph>) 10943 0x7426 琦 (<CJK Ideograph>) 10944 0x742A 琪 (<CJK Ideograph>) 10945 0x7429 琩 (<CJK Ideograph>) 10946 0x742E 琮 (<CJK Ideograph>) 10947 0x7462 瑢 (<CJK Ideograph>) 10948 0x7489 璉 (<CJK Ideograph>) 10949 0x749F 璟 (<CJK Ideograph>) 10950 0x7501 甁 (<CJK Ideograph>) 10951 0x756F 畯 (<CJK Ideograph>) 10952 0x7682 皂 (<CJK Ideograph>) 10953 0x769C 皜 (<CJK Ideograph>) 10954 0x769E 皞 (<CJK Ideograph>) 10955 0x769B 皛 (<CJK Ideograph>) 10956 0x76A6 皦 (<CJK Ideograph>) 10957 0xFA17 益 (CJK COMPATIBILITY IDEOGRAPH-FA17) 10958 0x7746 睆 (<CJK Ideograph>) 10959 0x52AF 劯 (<CJK Ideograph>) 10960 0x7821 砡 (<CJK Ideograph>) 10961 0x784E 硎 (<CJK Ideograph>) 10962 0x7864 硤 (<CJK Ideograph>) 10963 0x787A 硺 (<CJK Ideograph>) 10964 0x7930 礰 (<CJK Ideograph>) 10965 0xFA18 礼 (CJK COMPATIBILITY IDEOGRAPH-FA18) 10966 0xFA19 神 (CJK COMPATIBILITY IDEOGRAPH-FA19) 10967 0xFA1A 祥 (CJK COMPATIBILITY IDEOGRAPH-FA1A) 10968 0x7994 禔 (<CJK Ideograph>) 10969 0xFA1B 福 (CJK COMPATIBILITY IDEOGRAPH-FA1B) 10970 0x799B 禛 (<CJK Ideograph>) 10971 0x7AD1 竑 (<CJK Ideograph>) 10972 0x7AE7 竧 (<CJK Ideograph>) 10973 0xFA1C 靖 (CJK COMPATIBILITY IDEOGRAPH-FA1C) 10974 0x7AEB 竫 (<CJK Ideograph>) 10975 0x7B9E 箞 (<CJK Ideograph>) 10976 0xFA1D 精 (CJK COMPATIBILITY IDEOGRAPH-FA1D) 10977 0x7D48 絈 (<CJK Ideograph>) 10978 0x7D5C 絜 (<CJK Ideograph>) 10979 0x7DB7 綷 (<CJK Ideograph>) 10980 0x7DA0 綠 (<CJK Ideograph>) 10981 0x7DD6 緖 (<CJK Ideograph>) 10982 0x7E52 繒 (<CJK Ideograph>) 10983 0x7F47 罇 (<CJK Ideograph>) 10984 0x7FA1 羡 (<CJK Ideograph>) 10985 0xFA1E 羽 (CJK COMPATIBILITY IDEOGRAPH-FA1E) 10986 0x8301 茁 (<CJK Ideograph>) 10987 0x8362 荢 (<CJK Ideograph>) 10988 0x837F 荿 (<CJK Ideograph>) 10989 0x83C7 菇 (<CJK Ideograph>) 10990 0x83F6 菶 (<CJK Ideograph>) 10991 0x8448 葈 (<CJK Ideograph>) 10992 0x84B4 蒴 (<CJK Ideograph>) 10993 0x8553 蕓 (<CJK Ideograph>) 10994 0x8559 蕙 (<CJK Ideograph>) 10995 0x856B 蕫 (<CJK Ideograph>) 10996 0xFA1F 﨟 (CJK COMPATIBILITY IDEOGRAPH-FA1F) 10997 0x85B0 薰 (<CJK Ideograph>) 10998 0xFA20 蘒 (CJK COMPATIBILITY IDEOGRAPH-FA20) 10999 0xFA21 﨡 (CJK COMPATIBILITY IDEOGRAPH-FA21) 11000 0x8807 蠇 (<CJK Ideograph>) 11001 0x88F5 裵 (<CJK Ideograph>) 11002 0x8A12 訒 (<CJK Ideograph>) 11003 0x8A37 訷 (<CJK Ideograph>) 11004 0x8A79 詹 (<CJK Ideograph>) 11005 0x8AA7 誧 (<CJK Ideograph>) 11006 0x8ABE 誾 (<CJK Ideograph>) 11007 0x8ADF 諟 (<CJK Ideograph>) 11008 0xFA22 諸 (CJK COMPATIBILITY IDEOGRAPH-FA22) 11009 0x8AF6 諶 (<CJK Ideograph>) 11010 0x8B53 譓 (<CJK Ideograph>) 11011 0x8B7F 譿 (<CJK Ideograph>) 11012 0x8CF0 賰 (<CJK Ideograph>) 11013 0x8CF4 賴 (<CJK Ideograph>) 11014 0x8D12 贒 (<CJK Ideograph>) 11015 0x8D76 赶 (<CJK Ideograph>) 11016 0xFA23 﨣 (CJK COMPATIBILITY IDEOGRAPH-FA23) 11017 0x8ECF 軏 (<CJK Ideograph>) 11018 0xFA24 﨤 (CJK COMPATIBILITY IDEOGRAPH-FA24) 11019 0xFA25 逸 (CJK COMPATIBILITY IDEOGRAPH-FA25) 11020 0x9067 遧 (<CJK Ideograph>) 11021 0x90DE 郞 (<CJK Ideograph>) 11022 0xFA26 都 (CJK COMPATIBILITY IDEOGRAPH-FA26) 11023 0x9115 鄕 (<CJK Ideograph>) 11024 0x9127 鄧 (<CJK Ideograph>) 11025 0x91DA 釚 (<CJK Ideograph>) 11026 0x91D7 釗 (<CJK Ideograph>) 11027 0x91DE 釞 (<CJK Ideograph>) 11028 0x91ED 釭 (<CJK Ideograph>) 11029 0x91EE 釮 (<CJK Ideograph>) 11030 0x91E4 釤 (<CJK Ideograph>) 11031 0x91E5 釥 (<CJK Ideograph>) 11032 0x9206 鈆 (<CJK Ideograph>) 11033 0x9210 鈐 (<CJK Ideograph>) 11034 0x920A 鈊 (<CJK Ideograph>) 11035 0x923A 鈺 (<CJK Ideograph>) 11036 0x9240 鉀 (<CJK Ideograph>) 11037 0x923C 鈼 (<CJK Ideograph>) 11038 0x924E 鉎 (<CJK Ideograph>) 11039 0x9259 鉙 (<CJK Ideograph>) 11040 0x9251 鉑 (<CJK Ideograph>) 11041 0x9239 鈹 (<CJK Ideograph>) 11042 0x9267 鉧 (<CJK Ideograph>) 11043 0x92A7 銧 (<CJK Ideograph>) 11044 0x9277 鉷 (<CJK Ideograph>) 11045 0x9278 鉸 (<CJK Ideograph>) 11046 0x92E7 鋧 (<CJK Ideograph>) 11047 0x92D7 鋗 (<CJK Ideograph>) 11048 0x92D9 鋙 (<CJK Ideograph>) 11049 0x92D0 鋐 (<CJK Ideograph>) 11050 0xFA27 﨧 (CJK COMPATIBILITY IDEOGRAPH-FA27) 11051 0x92D5 鋕 (<CJK Ideograph>) 11052 0x92E0 鋠 (<CJK Ideograph>) 11053 0x92D3 鋓 (<CJK Ideograph>) 11054 0x9325 錥 (<CJK Ideograph>) 11055 0x9321 錡 (<CJK Ideograph>) 11056 0x92FB 鋻 (<CJK Ideograph>) 11057 0xFA28 﨨 (CJK COMPATIBILITY IDEOGRAPH-FA28) 11058 0x931E 錞 (<CJK Ideograph>) 11059 0x92FF 鋿 (<CJK Ideograph>) 11060 0x931D 錝 (<CJK Ideograph>) 11061 0x9302 錂 (<CJK Ideograph>) 11062 0x9370 鍰 (<CJK Ideograph>) 11063 0x9357 鍗 (<CJK Ideograph>) 11064 0x93A4 鎤 (<CJK Ideograph>) 11065 0x93C6 鏆 (<CJK Ideograph>) 11066 0x93DE 鏞 (<CJK Ideograph>) 11067 0x93F8 鏸 (<CJK Ideograph>) 11068 0x9431 鐱 (<CJK Ideograph>) 11069 0x9445 鑅 (<CJK Ideograph>) 11070 0x9448 鑈 (<CJK Ideograph>) 11071 0x9592 閒 (<CJK Ideograph>) 11072 0xF9DC 隆 (CJK COMPATIBILITY IDEOGRAPH-F9DC) 11073 0xFA29 﨩 (CJK COMPATIBILITY IDEOGRAPH-FA29) 11074 0x969D 隝 (<CJK Ideograph>) 11075 0x96AF 隯 (<CJK Ideograph>) 11076 0x9733 霳 (<CJK Ideograph>) 11077 0x973B 霻 (<CJK Ideograph>) 11078 0x9743 靃 (<CJK Ideograph>) 11079 0x974D 靍 (<CJK Ideograph>) 11080 0x974F 靏 (<CJK Ideograph>) 11081 0x9751 靑 (<CJK Ideograph>) 11082 0x9755 靕 (<CJK Ideograph>) 11083 0x9857 顗 (<CJK Ideograph>) 11084 0x9865 顥 (<CJK Ideograph>) 11085 0xFA2A 飯 (CJK COMPATIBILITY IDEOGRAPH-FA2A) 11086 0xFA2B 飼 (CJK COMPATIBILITY IDEOGRAPH-FA2B) 11087 0x9927 餧 (<CJK Ideograph>) 11088 0xFA2C 館 (CJK COMPATIBILITY IDEOGRAPH-FA2C) 11089 0x999E 馞 (<CJK Ideograph>) 11090 0x9A4E 驎 (<CJK Ideograph>) 11091 0x9AD9 髙 (<CJK Ideograph>) 11092 0x9ADC 髜 (<CJK Ideograph>) 11093 0x9B75 魵 (<CJK Ideograph>) 11094 0x9B72 魲 (<CJK Ideograph>) 11095 0x9B8F 鮏 (<CJK Ideograph>) 11096 0x9BB1 鮱 (<CJK Ideograph>) 11097 0x9BBB 鮻 (<CJK Ideograph>) 11098 0x9C00 鰀 (<CJK Ideograph>) 11099 0x9D70 鵰 (<CJK Ideograph>) 11100 0x9D6B 鵫 (<CJK Ideograph>) 11101 0xFA2D 鶴 (CJK COMPATIBILITY IDEOGRAPH-FA2D) 11102 0x9E19 鸙 (<CJK Ideograph>) 11103 0x9ED1 黑 (<CJK Ideograph>) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-jis0212.txt�����������������������������������������������������������������0000664�0000000�0000000�00000633456�15202323131�0016704�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-jis0212.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 83bf90dd1c591a4355730d8c4567efc499d74da7490531019ef22a879991cfb7 # Date: 2018-01-06 108 0x02D8 ˘ (BREVE) 109 0x02C7 ˇ (CARON) 110 0x00B8 ¸ (CEDILLA) 111 0x02D9 ˙ (DOT ABOVE) 112 0x02DD ˝ (DOUBLE ACUTE ACCENT) 113 0x00AF ¯ (MACRON) 114 0x02DB ˛ (OGONEK) 115 0x02DA ˚ (RING ABOVE) 116 0xFF5E ~ (FULLWIDTH TILDE) 117 0x0384 ΄ (GREEK TONOS) 118 0x0385 ΅ (GREEK DIALYTIKA TONOS) 127 0x00A1 ¡ (INVERTED EXCLAMATION MARK) 128 0x00A6 ¦ (BROKEN BAR) 129 0x00BF ¿ (INVERTED QUESTION MARK) 168 0x00BA º (MASCULINE ORDINAL INDICATOR) 169 0x00AA ª (FEMININE ORDINAL INDICATOR) 170 0x00A9 © (COPYRIGHT SIGN) 171 0x00AE ® (REGISTERED SIGN) 172 0x2122 ™ (TRADE MARK SIGN) 173 0x00A4 ¤ (CURRENCY SIGN) 174 0x2116 № (NUMERO SIGN) 534 0x0386 Ά (GREEK CAPITAL LETTER ALPHA WITH TONOS) 535 0x0388 Έ (GREEK CAPITAL LETTER EPSILON WITH TONOS) 536 0x0389 Ή (GREEK CAPITAL LETTER ETA WITH TONOS) 537 0x038A Ί (GREEK CAPITAL LETTER IOTA WITH TONOS) 538 0x03AA Ϊ (GREEK CAPITAL LETTER IOTA WITH DIALYTIKA) 540 0x038C Ό (GREEK CAPITAL LETTER OMICRON WITH TONOS) 542 0x038E Ύ (GREEK CAPITAL LETTER UPSILON WITH TONOS) 543 0x03AB Ϋ (GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA) 545 0x038F Ώ (GREEK CAPITAL LETTER OMEGA WITH TONOS) 550 0x03AC ά (GREEK SMALL LETTER ALPHA WITH TONOS) 551 0x03AD έ (GREEK SMALL LETTER EPSILON WITH TONOS) 552 0x03AE ή (GREEK SMALL LETTER ETA WITH TONOS) 553 0x03AF ί (GREEK SMALL LETTER IOTA WITH TONOS) 554 0x03CA ϊ (GREEK SMALL LETTER IOTA WITH DIALYTIKA) 555 0x0390 ΐ (GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS) 556 0x03CC ό (GREEK SMALL LETTER OMICRON WITH TONOS) 557 0x03C2 ς (GREEK SMALL LETTER FINAL SIGMA) 558 0x03CD ύ (GREEK SMALL LETTER UPSILON WITH TONOS) 559 0x03CB ϋ (GREEK SMALL LETTER UPSILON WITH DIALYTIKA) 560 0x03B0 ΰ (GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS) 561 0x03CE ώ (GREEK SMALL LETTER OMEGA WITH TONOS) 597 0x0402 Ђ (CYRILLIC CAPITAL LETTER DJE) 598 0x0403 Ѓ (CYRILLIC CAPITAL LETTER GJE) 599 0x0404 Є (CYRILLIC CAPITAL LETTER UKRAINIAN IE) 600 0x0405 Ѕ (CYRILLIC CAPITAL LETTER DZE) 601 0x0406 І (CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I) 602 0x0407 Ї (CYRILLIC CAPITAL LETTER YI) 603 0x0408 Ј (CYRILLIC CAPITAL LETTER JE) 604 0x0409 Љ (CYRILLIC CAPITAL LETTER LJE) 605 0x040A Њ (CYRILLIC CAPITAL LETTER NJE) 606 0x040B Ћ (CYRILLIC CAPITAL LETTER TSHE) 607 0x040C Ќ (CYRILLIC CAPITAL LETTER KJE) 608 0x040E Ў (CYRILLIC CAPITAL LETTER SHORT U) 609 0x040F Џ (CYRILLIC CAPITAL LETTER DZHE) 645 0x0452 ђ (CYRILLIC SMALL LETTER DJE) 646 0x0453 ѓ (CYRILLIC SMALL LETTER GJE) 647 0x0454 є (CYRILLIC SMALL LETTER UKRAINIAN IE) 648 0x0455 ѕ (CYRILLIC SMALL LETTER DZE) 649 0x0456 і (CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I) 650 0x0457 ї (CYRILLIC SMALL LETTER YI) 651 0x0458 ј (CYRILLIC SMALL LETTER JE) 652 0x0459 љ (CYRILLIC SMALL LETTER LJE) 653 0x045A њ (CYRILLIC SMALL LETTER NJE) 654 0x045B ћ (CYRILLIC SMALL LETTER TSHE) 655 0x045C ќ (CYRILLIC SMALL LETTER KJE) 656 0x045E ў (CYRILLIC SMALL LETTER SHORT U) 657 0x045F џ (CYRILLIC SMALL LETTER DZHE) 752 0x00C6 Æ (LATIN CAPITAL LETTER AE) 753 0x0110 Đ (LATIN CAPITAL LETTER D WITH STROKE) 755 0x0126 Ħ (LATIN CAPITAL LETTER H WITH STROKE) 757 0x0132 IJ (LATIN CAPITAL LIGATURE IJ) 759 0x0141 Ł (LATIN CAPITAL LETTER L WITH STROKE) 760 0x013F Ŀ (LATIN CAPITAL LETTER L WITH MIDDLE DOT) 762 0x014A Ŋ (LATIN CAPITAL LETTER ENG) 763 0x00D8 Ø (LATIN CAPITAL LETTER O WITH STROKE) 764 0x0152 Œ (LATIN CAPITAL LIGATURE OE) 766 0x0166 Ŧ (LATIN CAPITAL LETTER T WITH STROKE) 767 0x00DE Þ (LATIN CAPITAL LETTER THORN) 784 0x00E6 æ (LATIN SMALL LETTER AE) 785 0x0111 đ (LATIN SMALL LETTER D WITH STROKE) 786 0x00F0 ð (LATIN SMALL LETTER ETH) 787 0x0127 ħ (LATIN SMALL LETTER H WITH STROKE) 788 0x0131 ı (LATIN SMALL LETTER DOTLESS I) 789 0x0133 ij (LATIN SMALL LIGATURE IJ) 790 0x0138 ĸ (LATIN SMALL LETTER KRA) 791 0x0142 ł (LATIN SMALL LETTER L WITH STROKE) 792 0x0140 ŀ (LATIN SMALL LETTER L WITH MIDDLE DOT) 793 0x0149 ʼn (LATIN SMALL LETTER N PRECEDED BY APOSTROPHE) 794 0x014B ŋ (LATIN SMALL LETTER ENG) 795 0x00F8 ø (LATIN SMALL LETTER O WITH STROKE) 796 0x0153 œ (LATIN SMALL LIGATURE OE) 797 0x00DF ß (LATIN SMALL LETTER SHARP S) 798 0x0167 ŧ (LATIN SMALL LETTER T WITH STROKE) 799 0x00FE þ (LATIN SMALL LETTER THORN) 846 0x00C1 Á (LATIN CAPITAL LETTER A WITH ACUTE) 847 0x00C0 À (LATIN CAPITAL LETTER A WITH GRAVE) 848 0x00C4 Ä (LATIN CAPITAL LETTER A WITH DIAERESIS) 849 0x00C2  (LATIN CAPITAL LETTER A WITH CIRCUMFLEX) 850 0x0102 Ă (LATIN CAPITAL LETTER A WITH BREVE) 851 0x01CD Ǎ (LATIN CAPITAL LETTER A WITH CARON) 852 0x0100 Ā (LATIN CAPITAL LETTER A WITH MACRON) 853 0x0104 Ą (LATIN CAPITAL LETTER A WITH OGONEK) 854 0x00C5 Å (LATIN CAPITAL LETTER A WITH RING ABOVE) 855 0x00C3 à (LATIN CAPITAL LETTER A WITH TILDE) 856 0x0106 Ć (LATIN CAPITAL LETTER C WITH ACUTE) 857 0x0108 Ĉ (LATIN CAPITAL LETTER C WITH CIRCUMFLEX) 858 0x010C Č (LATIN CAPITAL LETTER C WITH CARON) 859 0x00C7 Ç (LATIN CAPITAL LETTER C WITH CEDILLA) 860 0x010A Ċ (LATIN CAPITAL LETTER C WITH DOT ABOVE) 861 0x010E Ď (LATIN CAPITAL LETTER D WITH CARON) 862 0x00C9 É (LATIN CAPITAL LETTER E WITH ACUTE) 863 0x00C8 È (LATIN CAPITAL LETTER E WITH GRAVE) 864 0x00CB Ë (LATIN CAPITAL LETTER E WITH DIAERESIS) 865 0x00CA Ê (LATIN CAPITAL LETTER E WITH CIRCUMFLEX) 866 0x011A Ě (LATIN CAPITAL LETTER E WITH CARON) 867 0x0116 Ė (LATIN CAPITAL LETTER E WITH DOT ABOVE) 868 0x0112 Ē (LATIN CAPITAL LETTER E WITH MACRON) 869 0x0118 Ę (LATIN CAPITAL LETTER E WITH OGONEK) 871 0x011C Ĝ (LATIN CAPITAL LETTER G WITH CIRCUMFLEX) 872 0x011E Ğ (LATIN CAPITAL LETTER G WITH BREVE) 873 0x0122 Ģ (LATIN CAPITAL LETTER G WITH CEDILLA) 874 0x0120 Ġ (LATIN CAPITAL LETTER G WITH DOT ABOVE) 875 0x0124 Ĥ (LATIN CAPITAL LETTER H WITH CIRCUMFLEX) 876 0x00CD Í (LATIN CAPITAL LETTER I WITH ACUTE) 877 0x00CC Ì (LATIN CAPITAL LETTER I WITH GRAVE) 878 0x00CF Ï (LATIN CAPITAL LETTER I WITH DIAERESIS) 879 0x00CE Î (LATIN CAPITAL LETTER I WITH CIRCUMFLEX) 880 0x01CF Ǐ (LATIN CAPITAL LETTER I WITH CARON) 881 0x0130 İ (LATIN CAPITAL LETTER I WITH DOT ABOVE) 882 0x012A Ī (LATIN CAPITAL LETTER I WITH MACRON) 883 0x012E Į (LATIN CAPITAL LETTER I WITH OGONEK) 884 0x0128 Ĩ (LATIN CAPITAL LETTER I WITH TILDE) 885 0x0134 Ĵ (LATIN CAPITAL LETTER J WITH CIRCUMFLEX) 886 0x0136 Ķ (LATIN CAPITAL LETTER K WITH CEDILLA) 887 0x0139 Ĺ (LATIN CAPITAL LETTER L WITH ACUTE) 888 0x013D Ľ (LATIN CAPITAL LETTER L WITH CARON) 889 0x013B Ļ (LATIN CAPITAL LETTER L WITH CEDILLA) 890 0x0143 Ń (LATIN CAPITAL LETTER N WITH ACUTE) 891 0x0147 Ň (LATIN CAPITAL LETTER N WITH CARON) 892 0x0145 Ņ (LATIN CAPITAL LETTER N WITH CEDILLA) 893 0x00D1 Ñ (LATIN CAPITAL LETTER N WITH TILDE) 894 0x00D3 Ó (LATIN CAPITAL LETTER O WITH ACUTE) 895 0x00D2 Ò (LATIN CAPITAL LETTER O WITH GRAVE) 896 0x00D6 Ö (LATIN CAPITAL LETTER O WITH DIAERESIS) 897 0x00D4 Ô (LATIN CAPITAL LETTER O WITH CIRCUMFLEX) 898 0x01D1 Ǒ (LATIN CAPITAL LETTER O WITH CARON) 899 0x0150 Ő (LATIN CAPITAL LETTER O WITH DOUBLE ACUTE) 900 0x014C Ō (LATIN CAPITAL LETTER O WITH MACRON) 901 0x00D5 Õ (LATIN CAPITAL LETTER O WITH TILDE) 902 0x0154 Ŕ (LATIN CAPITAL LETTER R WITH ACUTE) 903 0x0158 Ř (LATIN CAPITAL LETTER R WITH CARON) 904 0x0156 Ŗ (LATIN CAPITAL LETTER R WITH CEDILLA) 905 0x015A Ś (LATIN CAPITAL LETTER S WITH ACUTE) 906 0x015C Ŝ (LATIN CAPITAL LETTER S WITH CIRCUMFLEX) 907 0x0160 Š (LATIN CAPITAL LETTER S WITH CARON) 908 0x015E Ş (LATIN CAPITAL LETTER S WITH CEDILLA) 909 0x0164 Ť (LATIN CAPITAL LETTER T WITH CARON) 910 0x0162 Ţ (LATIN CAPITAL LETTER T WITH CEDILLA) 911 0x00DA Ú (LATIN CAPITAL LETTER U WITH ACUTE) 912 0x00D9 Ù (LATIN CAPITAL LETTER U WITH GRAVE) 913 0x00DC Ü (LATIN CAPITAL LETTER U WITH DIAERESIS) 914 0x00DB Û (LATIN CAPITAL LETTER U WITH CIRCUMFLEX) 915 0x016C Ŭ (LATIN CAPITAL LETTER U WITH BREVE) 916 0x01D3 Ǔ (LATIN CAPITAL LETTER U WITH CARON) 917 0x0170 Ű (LATIN CAPITAL LETTER U WITH DOUBLE ACUTE) 918 0x016A Ū (LATIN CAPITAL LETTER U WITH MACRON) 919 0x0172 Ų (LATIN CAPITAL LETTER U WITH OGONEK) 920 0x016E Ů (LATIN CAPITAL LETTER U WITH RING ABOVE) 921 0x0168 Ũ (LATIN CAPITAL LETTER U WITH TILDE) 922 0x01D7 Ǘ (LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE) 923 0x01DB Ǜ (LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE) 924 0x01D9 Ǚ (LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON) 925 0x01D5 Ǖ (LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON) 926 0x0174 Ŵ (LATIN CAPITAL LETTER W WITH CIRCUMFLEX) 927 0x00DD Ý (LATIN CAPITAL LETTER Y WITH ACUTE) 928 0x0178 Ÿ (LATIN CAPITAL LETTER Y WITH DIAERESIS) 929 0x0176 Ŷ (LATIN CAPITAL LETTER Y WITH CIRCUMFLEX) 930 0x0179 Ź (LATIN CAPITAL LETTER Z WITH ACUTE) 931 0x017D Ž (LATIN CAPITAL LETTER Z WITH CARON) 932 0x017B Ż (LATIN CAPITAL LETTER Z WITH DOT ABOVE) 940 0x00E1 á (LATIN SMALL LETTER A WITH ACUTE) 941 0x00E0 à (LATIN SMALL LETTER A WITH GRAVE) 942 0x00E4 ä (LATIN SMALL LETTER A WITH DIAERESIS) 943 0x00E2 â (LATIN SMALL LETTER A WITH CIRCUMFLEX) 944 0x0103 ă (LATIN SMALL LETTER A WITH BREVE) 945 0x01CE ǎ (LATIN SMALL LETTER A WITH CARON) 946 0x0101 ā (LATIN SMALL LETTER A WITH MACRON) 947 0x0105 ą (LATIN SMALL LETTER A WITH OGONEK) 948 0x00E5 å (LATIN SMALL LETTER A WITH RING ABOVE) 949 0x00E3 ã (LATIN SMALL LETTER A WITH TILDE) 950 0x0107 ć (LATIN SMALL LETTER C WITH ACUTE) 951 0x0109 ĉ (LATIN SMALL LETTER C WITH CIRCUMFLEX) 952 0x010D č (LATIN SMALL LETTER C WITH CARON) 953 0x00E7 ç (LATIN SMALL LETTER C WITH CEDILLA) 954 0x010B ċ (LATIN SMALL LETTER C WITH DOT ABOVE) 955 0x010F ď (LATIN SMALL LETTER D WITH CARON) 956 0x00E9 é (LATIN SMALL LETTER E WITH ACUTE) 957 0x00E8 è (LATIN SMALL LETTER E WITH GRAVE) 958 0x00EB ë (LATIN SMALL LETTER E WITH DIAERESIS) 959 0x00EA ê (LATIN SMALL LETTER E WITH CIRCUMFLEX) 960 0x011B ě (LATIN SMALL LETTER E WITH CARON) 961 0x0117 ė (LATIN SMALL LETTER E WITH DOT ABOVE) 962 0x0113 ē (LATIN SMALL LETTER E WITH MACRON) 963 0x0119 ę (LATIN SMALL LETTER E WITH OGONEK) 964 0x01F5 ǵ (LATIN SMALL LETTER G WITH ACUTE) 965 0x011D ĝ (LATIN SMALL LETTER G WITH CIRCUMFLEX) 966 0x011F ğ (LATIN SMALL LETTER G WITH BREVE) 968 0x0121 ġ (LATIN SMALL LETTER G WITH DOT ABOVE) 969 0x0125 ĥ (LATIN SMALL LETTER H WITH CIRCUMFLEX) 970 0x00ED í (LATIN SMALL LETTER I WITH ACUTE) 971 0x00EC ì (LATIN SMALL LETTER I WITH GRAVE) 972 0x00EF ï (LATIN SMALL LETTER I WITH DIAERESIS) 973 0x00EE î (LATIN SMALL LETTER I WITH CIRCUMFLEX) 974 0x01D0 ǐ (LATIN SMALL LETTER I WITH CARON) 976 0x012B ī (LATIN SMALL LETTER I WITH MACRON) 977 0x012F į (LATIN SMALL LETTER I WITH OGONEK) 978 0x0129 ĩ (LATIN SMALL LETTER I WITH TILDE) 979 0x0135 ĵ (LATIN SMALL LETTER J WITH CIRCUMFLEX) 980 0x0137 ķ (LATIN SMALL LETTER K WITH CEDILLA) 981 0x013A ĺ (LATIN SMALL LETTER L WITH ACUTE) 982 0x013E ľ (LATIN SMALL LETTER L WITH CARON) 983 0x013C ļ (LATIN SMALL LETTER L WITH CEDILLA) 984 0x0144 ń (LATIN SMALL LETTER N WITH ACUTE) 985 0x0148 ň (LATIN SMALL LETTER N WITH CARON) 986 0x0146 ņ (LATIN SMALL LETTER N WITH CEDILLA) 987 0x00F1 ñ (LATIN SMALL LETTER N WITH TILDE) 988 0x00F3 ó (LATIN SMALL LETTER O WITH ACUTE) 989 0x00F2 ò (LATIN SMALL LETTER O WITH GRAVE) 990 0x00F6 ö (LATIN SMALL LETTER O WITH DIAERESIS) 991 0x00F4 ô (LATIN SMALL LETTER O WITH CIRCUMFLEX) 992 0x01D2 ǒ (LATIN SMALL LETTER O WITH CARON) 993 0x0151 ő (LATIN SMALL LETTER O WITH DOUBLE ACUTE) 994 0x014D ō (LATIN SMALL LETTER O WITH MACRON) 995 0x00F5 õ (LATIN SMALL LETTER O WITH TILDE) 996 0x0155 ŕ (LATIN SMALL LETTER R WITH ACUTE) 997 0x0159 ř (LATIN SMALL LETTER R WITH CARON) 998 0x0157 ŗ (LATIN SMALL LETTER R WITH CEDILLA) 999 0x015B ś (LATIN SMALL LETTER S WITH ACUTE) 1000 0x015D ŝ (LATIN SMALL LETTER S WITH CIRCUMFLEX) 1001 0x0161 š (LATIN SMALL LETTER S WITH CARON) 1002 0x015F ş (LATIN SMALL LETTER S WITH CEDILLA) 1003 0x0165 ť (LATIN SMALL LETTER T WITH CARON) 1004 0x0163 ţ (LATIN SMALL LETTER T WITH CEDILLA) 1005 0x00FA ú (LATIN SMALL LETTER U WITH ACUTE) 1006 0x00F9 ù (LATIN SMALL LETTER U WITH GRAVE) 1007 0x00FC ü (LATIN SMALL LETTER U WITH DIAERESIS) 1008 0x00FB û (LATIN SMALL LETTER U WITH CIRCUMFLEX) 1009 0x016D ŭ (LATIN SMALL LETTER U WITH BREVE) 1010 0x01D4 ǔ (LATIN SMALL LETTER U WITH CARON) 1011 0x0171 ű (LATIN SMALL LETTER U WITH DOUBLE ACUTE) 1012 0x016B ū (LATIN SMALL LETTER U WITH MACRON) 1013 0x0173 ų (LATIN SMALL LETTER U WITH OGONEK) 1014 0x016F ů (LATIN SMALL LETTER U WITH RING ABOVE) 1015 0x0169 ũ (LATIN SMALL LETTER U WITH TILDE) 1016 0x01D8 ǘ (LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE) 1017 0x01DC ǜ (LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE) 1018 0x01DA ǚ (LATIN SMALL LETTER U WITH DIAERESIS AND CARON) 1019 0x01D6 ǖ (LATIN SMALL LETTER U WITH DIAERESIS AND MACRON) 1020 0x0175 ŵ (LATIN SMALL LETTER W WITH CIRCUMFLEX) 1021 0x00FD ý (LATIN SMALL LETTER Y WITH ACUTE) 1022 0x00FF ÿ (LATIN SMALL LETTER Y WITH DIAERESIS) 1023 0x0177 ŷ (LATIN SMALL LETTER Y WITH CIRCUMFLEX) 1024 0x017A ź (LATIN SMALL LETTER Z WITH ACUTE) 1025 0x017E ž (LATIN SMALL LETTER Z WITH CARON) 1026 0x017C ż (LATIN SMALL LETTER Z WITH DOT ABOVE) 1410 0x4E02 丂 (<CJK Ideograph>) 1411 0x4E04 丄 (<CJK Ideograph>) 1412 0x4E05 丅 (<CJK Ideograph>) 1413 0x4E0C 丌 (<CJK Ideograph>) 1414 0x4E12 丒 (<CJK Ideograph>) 1415 0x4E1F 丟 (<CJK Ideograph>) 1416 0x4E23 丣 (<CJK Ideograph>) 1417 0x4E24 两 (<CJK Ideograph>) 1418 0x4E28 丨 (<CJK Ideograph>) 1419 0x4E2B 丫 (<CJK Ideograph>) 1420 0x4E2E 丮 (<CJK Ideograph>) 1421 0x4E2F 丯 (<CJK Ideograph>) 1422 0x4E30 丰 (<CJK Ideograph>) 1423 0x4E35 丵 (<CJK Ideograph>) 1424 0x4E40 乀 (<CJK Ideograph>) 1425 0x4E41 乁 (<CJK Ideograph>) 1426 0x4E44 乄 (<CJK Ideograph>) 1427 0x4E47 乇 (<CJK Ideograph>) 1428 0x4E51 乑 (<CJK Ideograph>) 1429 0x4E5A 乚 (<CJK Ideograph>) 1430 0x4E5C 乜 (<CJK Ideograph>) 1431 0x4E63 乣 (<CJK Ideograph>) 1432 0x4E68 乨 (<CJK Ideograph>) 1433 0x4E69 乩 (<CJK Ideograph>) 1434 0x4E74 乴 (<CJK Ideograph>) 1435 0x4E75 乵 (<CJK Ideograph>) 1436 0x4E79 乹 (<CJK Ideograph>) 1437 0x4E7F 乿 (<CJK Ideograph>) 1438 0x4E8D 亍 (<CJK Ideograph>) 1439 0x4E96 亖 (<CJK Ideograph>) 1440 0x4E97 亗 (<CJK Ideograph>) 1441 0x4E9D 亝 (<CJK Ideograph>) 1442 0x4EAF 亯 (<CJK Ideograph>) 1443 0x4EB9 亹 (<CJK Ideograph>) 1444 0x4EC3 仃 (<CJK Ideograph>) 1445 0x4ED0 仐 (<CJK Ideograph>) 1446 0x4EDA 仚 (<CJK Ideograph>) 1447 0x4EDB 仛 (<CJK Ideograph>) 1448 0x4EE0 仠 (<CJK Ideograph>) 1449 0x4EE1 仡 (<CJK Ideograph>) 1450 0x4EE2 仢 (<CJK Ideograph>) 1451 0x4EE8 仨 (<CJK Ideograph>) 1452 0x4EEF 仯 (<CJK Ideograph>) 1453 0x4EF1 仱 (<CJK Ideograph>) 1454 0x4EF3 仳 (<CJK Ideograph>) 1455 0x4EF5 仵 (<CJK Ideograph>) 1456 0x4EFD 份 (<CJK Ideograph>) 1457 0x4EFE 仾 (<CJK Ideograph>) 1458 0x4EFF 仿 (<CJK Ideograph>) 1459 0x4F00 伀 (<CJK Ideograph>) 1460 0x4F02 伂 (<CJK Ideograph>) 1461 0x4F03 伃 (<CJK Ideograph>) 1462 0x4F08 伈 (<CJK Ideograph>) 1463 0x4F0B 伋 (<CJK Ideograph>) 1464 0x4F0C 伌 (<CJK Ideograph>) 1465 0x4F12 伒 (<CJK Ideograph>) 1466 0x4F15 伕 (<CJK Ideograph>) 1467 0x4F16 伖 (<CJK Ideograph>) 1468 0x4F17 众 (<CJK Ideograph>) 1469 0x4F19 伙 (<CJK Ideograph>) 1470 0x4F2E 伮 (<CJK Ideograph>) 1471 0x4F31 伱 (<CJK Ideograph>) 1472 0x4F60 你 (<CJK Ideograph>) 1473 0x4F33 伳 (<CJK Ideograph>) 1474 0x4F35 伵 (<CJK Ideograph>) 1475 0x4F37 伷 (<CJK Ideograph>) 1476 0x4F39 伹 (<CJK Ideograph>) 1477 0x4F3B 伻 (<CJK Ideograph>) 1478 0x4F3E 伾 (<CJK Ideograph>) 1479 0x4F40 佀 (<CJK Ideograph>) 1480 0x4F42 佂 (<CJK Ideograph>) 1481 0x4F48 佈 (<CJK Ideograph>) 1482 0x4F49 佉 (<CJK Ideograph>) 1483 0x4F4B 佋 (<CJK Ideograph>) 1484 0x4F4C 佌 (<CJK Ideograph>) 1485 0x4F52 佒 (<CJK Ideograph>) 1486 0x4F54 佔 (<CJK Ideograph>) 1487 0x4F56 佖 (<CJK Ideograph>) 1488 0x4F58 佘 (<CJK Ideograph>) 1489 0x4F5F 佟 (<CJK Ideograph>) 1490 0x4F63 佣 (<CJK Ideograph>) 1491 0x4F6A 佪 (<CJK Ideograph>) 1492 0x4F6C 佬 (<CJK Ideograph>) 1493 0x4F6E 佮 (<CJK Ideograph>) 1494 0x4F71 佱 (<CJK Ideograph>) 1495 0x4F77 佷 (<CJK Ideograph>) 1496 0x4F78 佸 (<CJK Ideograph>) 1497 0x4F79 佹 (<CJK Ideograph>) 1498 0x4F7A 佺 (<CJK Ideograph>) 1499 0x4F7D 佽 (<CJK Ideograph>) 1500 0x4F7E 佾 (<CJK Ideograph>) 1501 0x4F81 侁 (<CJK Ideograph>) 1502 0x4F82 侂 (<CJK Ideograph>) 1503 0x4F84 侄 (<CJK Ideograph>) 1504 0x4F85 侅 (<CJK Ideograph>) 1505 0x4F89 侉 (<CJK Ideograph>) 1506 0x4F8A 侊 (<CJK Ideograph>) 1507 0x4F8C 侌 (<CJK Ideograph>) 1508 0x4F8E 侎 (<CJK Ideograph>) 1509 0x4F90 侐 (<CJK Ideograph>) 1510 0x4F92 侒 (<CJK Ideograph>) 1511 0x4F93 侓 (<CJK Ideograph>) 1512 0x4F94 侔 (<CJK Ideograph>) 1513 0x4F97 侗 (<CJK Ideograph>) 1514 0x4F99 侙 (<CJK Ideograph>) 1515 0x4F9A 侚 (<CJK Ideograph>) 1516 0x4F9E 侞 (<CJK Ideograph>) 1517 0x4F9F 侟 (<CJK Ideograph>) 1518 0x4FB2 侲 (<CJK Ideograph>) 1519 0x4FB7 侷 (<CJK Ideograph>) 1520 0x4FB9 侹 (<CJK Ideograph>) 1521 0x4FBB 侻 (<CJK Ideograph>) 1522 0x4FBC 侼 (<CJK Ideograph>) 1523 0x4FBD 侽 (<CJK Ideograph>) 1524 0x4FBE 侾 (<CJK Ideograph>) 1525 0x4FC0 俀 (<CJK Ideograph>) 1526 0x4FC1 俁 (<CJK Ideograph>) 1527 0x4FC5 俅 (<CJK Ideograph>) 1528 0x4FC6 俆 (<CJK Ideograph>) 1529 0x4FC8 俈 (<CJK Ideograph>) 1530 0x4FC9 俉 (<CJK Ideograph>) 1531 0x4FCB 俋 (<CJK Ideograph>) 1532 0x4FCC 俌 (<CJK Ideograph>) 1533 0x4FCD 俍 (<CJK Ideograph>) 1534 0x4FCF 俏 (<CJK Ideograph>) 1535 0x4FD2 俒 (<CJK Ideograph>) 1536 0x4FDC 俜 (<CJK Ideograph>) 1537 0x4FE0 俠 (<CJK Ideograph>) 1538 0x4FE2 俢 (<CJK Ideograph>) 1539 0x4FF0 俰 (<CJK Ideograph>) 1540 0x4FF2 俲 (<CJK Ideograph>) 1541 0x4FFC 俼 (<CJK Ideograph>) 1542 0x4FFD 俽 (<CJK Ideograph>) 1543 0x4FFF 俿 (<CJK Ideograph>) 1544 0x5000 倀 (<CJK Ideograph>) 1545 0x5001 倁 (<CJK Ideograph>) 1546 0x5004 倄 (<CJK Ideograph>) 1547 0x5007 倇 (<CJK Ideograph>) 1548 0x500A 倊 (<CJK Ideograph>) 1549 0x500C 倌 (<CJK Ideograph>) 1550 0x500E 倎 (<CJK Ideograph>) 1551 0x5010 倐 (<CJK Ideograph>) 1552 0x5013 倓 (<CJK Ideograph>) 1553 0x5017 倗 (<CJK Ideograph>) 1554 0x5018 倘 (<CJK Ideograph>) 1555 0x501B 倛 (<CJK Ideograph>) 1556 0x501C 倜 (<CJK Ideograph>) 1557 0x501D 倝 (<CJK Ideograph>) 1558 0x501E 倞 (<CJK Ideograph>) 1559 0x5022 倢 (<CJK Ideograph>) 1560 0x5027 倧 (<CJK Ideograph>) 1561 0x502E 倮 (<CJK Ideograph>) 1562 0x5030 倰 (<CJK Ideograph>) 1563 0x5032 倲 (<CJK Ideograph>) 1564 0x5033 倳 (<CJK Ideograph>) 1565 0x5035 倵 (<CJK Ideograph>) 1566 0x5040 偀 (<CJK Ideograph>) 1567 0x5041 偁 (<CJK Ideograph>) 1568 0x5042 偂 (<CJK Ideograph>) 1569 0x5045 偅 (<CJK Ideograph>) 1570 0x5046 偆 (<CJK Ideograph>) 1571 0x504A 偊 (<CJK Ideograph>) 1572 0x504C 偌 (<CJK Ideograph>) 1573 0x504E 偎 (<CJK Ideograph>) 1574 0x5051 偑 (<CJK Ideograph>) 1575 0x5052 偒 (<CJK Ideograph>) 1576 0x5053 偓 (<CJK Ideograph>) 1577 0x5057 偗 (<CJK Ideograph>) 1578 0x5059 偙 (<CJK Ideograph>) 1579 0x505F 偟 (<CJK Ideograph>) 1580 0x5060 偠 (<CJK Ideograph>) 1581 0x5062 偢 (<CJK Ideograph>) 1582 0x5063 偣 (<CJK Ideograph>) 1583 0x5066 偦 (<CJK Ideograph>) 1584 0x5067 偧 (<CJK Ideograph>) 1585 0x506A 偪 (<CJK Ideograph>) 1586 0x506D 偭 (<CJK Ideograph>) 1587 0x5070 偰 (<CJK Ideograph>) 1588 0x5071 偱 (<CJK Ideograph>) 1589 0x503B 倻 (<CJK Ideograph>) 1590 0x5081 傁 (<CJK Ideograph>) 1591 0x5083 傃 (<CJK Ideograph>) 1592 0x5084 傄 (<CJK Ideograph>) 1593 0x5086 傆 (<CJK Ideograph>) 1594 0x508A 傊 (<CJK Ideograph>) 1595 0x508E 傎 (<CJK Ideograph>) 1596 0x508F 傏 (<CJK Ideograph>) 1597 0x5090 傐 (<CJK Ideograph>) 1598 0x5092 傒 (<CJK Ideograph>) 1599 0x5093 傓 (<CJK Ideograph>) 1600 0x5094 傔 (<CJK Ideograph>) 1601 0x5096 傖 (<CJK Ideograph>) 1602 0x509B 傛 (<CJK Ideograph>) 1603 0x509C 傜 (<CJK Ideograph>) 1604 0x509E 傞 (<CJK Ideograph>) 1605 0x509F 傟 (<CJK Ideograph>) 1606 0x50A0 傠 (<CJK Ideograph>) 1607 0x50A1 傡 (<CJK Ideograph>) 1608 0x50A2 傢 (<CJK Ideograph>) 1609 0x50AA 傪 (<CJK Ideograph>) 1610 0x50AF 傯 (<CJK Ideograph>) 1611 0x50B0 傰 (<CJK Ideograph>) 1612 0x50B9 傹 (<CJK Ideograph>) 1613 0x50BA 傺 (<CJK Ideograph>) 1614 0x50BD 傽 (<CJK Ideograph>) 1615 0x50C0 僀 (<CJK Ideograph>) 1616 0x50C3 僃 (<CJK Ideograph>) 1617 0x50C4 僄 (<CJK Ideograph>) 1618 0x50C7 僇 (<CJK Ideograph>) 1619 0x50CC 僌 (<CJK Ideograph>) 1620 0x50CE 僎 (<CJK Ideograph>) 1621 0x50D0 僐 (<CJK Ideograph>) 1622 0x50D3 僓 (<CJK Ideograph>) 1623 0x50D4 僔 (<CJK Ideograph>) 1624 0x50D8 僘 (<CJK Ideograph>) 1625 0x50DC 僜 (<CJK Ideograph>) 1626 0x50DD 僝 (<CJK Ideograph>) 1627 0x50DF 僟 (<CJK Ideograph>) 1628 0x50E2 僢 (<CJK Ideograph>) 1629 0x50E4 僤 (<CJK Ideograph>) 1630 0x50E6 僦 (<CJK Ideograph>) 1631 0x50E8 僨 (<CJK Ideograph>) 1632 0x50E9 僩 (<CJK Ideograph>) 1633 0x50EF 僯 (<CJK Ideograph>) 1634 0x50F1 僱 (<CJK Ideograph>) 1635 0x50F6 僶 (<CJK Ideograph>) 1636 0x50FA 僺 (<CJK Ideograph>) 1637 0x50FE 僾 (<CJK Ideograph>) 1638 0x5103 儃 (<CJK Ideograph>) 1639 0x5106 儆 (<CJK Ideograph>) 1640 0x5107 儇 (<CJK Ideograph>) 1641 0x5108 儈 (<CJK Ideograph>) 1642 0x510B 儋 (<CJK Ideograph>) 1643 0x510C 儌 (<CJK Ideograph>) 1644 0x510D 儍 (<CJK Ideograph>) 1645 0x510E 儎 (<CJK Ideograph>) 1646 0x50F2 僲 (<CJK Ideograph>) 1647 0x5110 儐 (<CJK Ideograph>) 1648 0x5117 儗 (<CJK Ideograph>) 1649 0x5119 儙 (<CJK Ideograph>) 1650 0x511B 儛 (<CJK Ideograph>) 1651 0x511C 儜 (<CJK Ideograph>) 1652 0x511D 儝 (<CJK Ideograph>) 1653 0x511E 儞 (<CJK Ideograph>) 1654 0x5123 儣 (<CJK Ideograph>) 1655 0x5127 儧 (<CJK Ideograph>) 1656 0x5128 儨 (<CJK Ideograph>) 1657 0x512C 儬 (<CJK Ideograph>) 1658 0x512D 儭 (<CJK Ideograph>) 1659 0x512F 儯 (<CJK Ideograph>) 1660 0x5131 儱 (<CJK Ideograph>) 1661 0x5133 儳 (<CJK Ideograph>) 1662 0x5134 儴 (<CJK Ideograph>) 1663 0x5135 儵 (<CJK Ideograph>) 1664 0x5138 儸 (<CJK Ideograph>) 1665 0x5139 儹 (<CJK Ideograph>) 1666 0x5142 兂 (<CJK Ideograph>) 1667 0x514A 兊 (<CJK Ideograph>) 1668 0x514F 兏 (<CJK Ideograph>) 1669 0x5153 兓 (<CJK Ideograph>) 1670 0x5155 兕 (<CJK Ideograph>) 1671 0x5157 兗 (<CJK Ideograph>) 1672 0x5158 兘 (<CJK Ideograph>) 1673 0x515F 兟 (<CJK Ideograph>) 1674 0x5164 兤 (<CJK Ideograph>) 1675 0x5166 兦 (<CJK Ideograph>) 1676 0x517E 兾 (<CJK Ideograph>) 1677 0x5183 冃 (<CJK Ideograph>) 1678 0x5184 冄 (<CJK Ideograph>) 1679 0x518B 冋 (<CJK Ideograph>) 1680 0x518E 冎 (<CJK Ideograph>) 1681 0x5198 冘 (<CJK Ideograph>) 1682 0x519D 冝 (<CJK Ideograph>) 1683 0x51A1 冡 (<CJK Ideograph>) 1684 0x51A3 冣 (<CJK Ideograph>) 1685 0x51AD 冭 (<CJK Ideograph>) 1686 0x51B8 冸 (<CJK Ideograph>) 1687 0x51BA 冺 (<CJK Ideograph>) 1688 0x51BC 冼 (<CJK Ideograph>) 1689 0x51BE 冾 (<CJK Ideograph>) 1690 0x51BF 冿 (<CJK Ideograph>) 1691 0x51C2 凂 (<CJK Ideograph>) 1692 0x51C8 凈 (<CJK Ideograph>) 1693 0x51CF 减 (<CJK Ideograph>) 1694 0x51D1 凑 (<CJK Ideograph>) 1695 0x51D2 凒 (<CJK Ideograph>) 1696 0x51D3 凓 (<CJK Ideograph>) 1697 0x51D5 凕 (<CJK Ideograph>) 1698 0x51D8 凘 (<CJK Ideograph>) 1699 0x51DE 凞 (<CJK Ideograph>) 1700 0x51E2 凢 (<CJK Ideograph>) 1701 0x51E5 凥 (<CJK Ideograph>) 1702 0x51EE 凮 (<CJK Ideograph>) 1703 0x51F2 凲 (<CJK Ideograph>) 1704 0x51F3 凳 (<CJK Ideograph>) 1705 0x51F4 凴 (<CJK Ideograph>) 1706 0x51F7 凷 (<CJK Ideograph>) 1707 0x5201 刁 (<CJK Ideograph>) 1708 0x5202 刂 (<CJK Ideograph>) 1709 0x5205 刅 (<CJK Ideograph>) 1710 0x5212 划 (<CJK Ideograph>) 1711 0x5213 刓 (<CJK Ideograph>) 1712 0x5215 刕 (<CJK Ideograph>) 1713 0x5216 刖 (<CJK Ideograph>) 1714 0x5218 刘 (<CJK Ideograph>) 1715 0x5222 刢 (<CJK Ideograph>) 1716 0x5228 刨 (<CJK Ideograph>) 1717 0x5231 刱 (<CJK Ideograph>) 1718 0x5232 刲 (<CJK Ideograph>) 1719 0x5235 刵 (<CJK Ideograph>) 1720 0x523C 刼 (<CJK Ideograph>) 1721 0x5245 剅 (<CJK Ideograph>) 1722 0x5249 剉 (<CJK Ideograph>) 1723 0x5255 剕 (<CJK Ideograph>) 1724 0x5257 剗 (<CJK Ideograph>) 1725 0x5258 剘 (<CJK Ideograph>) 1726 0x525A 剚 (<CJK Ideograph>) 1727 0x525C 剜 (<CJK Ideograph>) 1728 0x525F 剟 (<CJK Ideograph>) 1729 0x5260 剠 (<CJK Ideograph>) 1730 0x5261 剡 (<CJK Ideograph>) 1731 0x5266 剦 (<CJK Ideograph>) 1732 0x526E 剮 (<CJK Ideograph>) 1733 0x5277 剷 (<CJK Ideograph>) 1734 0x5278 剸 (<CJK Ideograph>) 1735 0x5279 剹 (<CJK Ideograph>) 1736 0x5280 劀 (<CJK Ideograph>) 1737 0x5282 劂 (<CJK Ideograph>) 1738 0x5285 劅 (<CJK Ideograph>) 1739 0x528A 劊 (<CJK Ideograph>) 1740 0x528C 劌 (<CJK Ideograph>) 1741 0x5293 劓 (<CJK Ideograph>) 1742 0x5295 劕 (<CJK Ideograph>) 1743 0x5296 劖 (<CJK Ideograph>) 1744 0x5297 劗 (<CJK Ideograph>) 1745 0x5298 劘 (<CJK Ideograph>) 1746 0x529A 劚 (<CJK Ideograph>) 1747 0x529C 劜 (<CJK Ideograph>) 1748 0x52A4 劤 (<CJK Ideograph>) 1749 0x52A5 劥 (<CJK Ideograph>) 1750 0x52A6 劦 (<CJK Ideograph>) 1751 0x52A7 劧 (<CJK Ideograph>) 1752 0x52AF 劯 (<CJK Ideograph>) 1753 0x52B0 劰 (<CJK Ideograph>) 1754 0x52B6 劶 (<CJK Ideograph>) 1755 0x52B7 劷 (<CJK Ideograph>) 1756 0x52B8 劸 (<CJK Ideograph>) 1757 0x52BA 劺 (<CJK Ideograph>) 1758 0x52BB 劻 (<CJK Ideograph>) 1759 0x52BD 劽 (<CJK Ideograph>) 1760 0x52C0 勀 (<CJK Ideograph>) 1761 0x52C4 勄 (<CJK Ideograph>) 1762 0x52C6 勆 (<CJK Ideograph>) 1763 0x52C8 勈 (<CJK Ideograph>) 1764 0x52CC 勌 (<CJK Ideograph>) 1765 0x52CF 勏 (<CJK Ideograph>) 1766 0x52D1 勑 (<CJK Ideograph>) 1767 0x52D4 勔 (<CJK Ideograph>) 1768 0x52D6 勖 (<CJK Ideograph>) 1769 0x52DB 勛 (<CJK Ideograph>) 1770 0x52DC 勜 (<CJK Ideograph>) 1771 0x52E1 勡 (<CJK Ideograph>) 1772 0x52E5 勥 (<CJK Ideograph>) 1773 0x52E8 勨 (<CJK Ideograph>) 1774 0x52E9 勩 (<CJK Ideograph>) 1775 0x52EA 勪 (<CJK Ideograph>) 1776 0x52EC 勬 (<CJK Ideograph>) 1777 0x52F0 勰 (<CJK Ideograph>) 1778 0x52F1 勱 (<CJK Ideograph>) 1779 0x52F4 勴 (<CJK Ideograph>) 1780 0x52F6 勶 (<CJK Ideograph>) 1781 0x52F7 勷 (<CJK Ideograph>) 1782 0x5300 匀 (<CJK Ideograph>) 1783 0x5303 匃 (<CJK Ideograph>) 1784 0x530A 匊 (<CJK Ideograph>) 1785 0x530B 匋 (<CJK Ideograph>) 1786 0x530C 匌 (<CJK Ideograph>) 1787 0x5311 匑 (<CJK Ideograph>) 1788 0x5313 匓 (<CJK Ideograph>) 1789 0x5318 匘 (<CJK Ideograph>) 1790 0x531B 匛 (<CJK Ideograph>) 1791 0x531C 匜 (<CJK Ideograph>) 1792 0x531E 匞 (<CJK Ideograph>) 1793 0x531F 匟 (<CJK Ideograph>) 1794 0x5325 匥 (<CJK Ideograph>) 1795 0x5327 匧 (<CJK Ideograph>) 1796 0x5328 匨 (<CJK Ideograph>) 1797 0x5329 匩 (<CJK Ideograph>) 1798 0x532B 匫 (<CJK Ideograph>) 1799 0x532C 匬 (<CJK Ideograph>) 1800 0x532D 匭 (<CJK Ideograph>) 1801 0x5330 匰 (<CJK Ideograph>) 1802 0x5332 匲 (<CJK Ideograph>) 1803 0x5335 匵 (<CJK Ideograph>) 1804 0x533C 匼 (<CJK Ideograph>) 1805 0x533D 匽 (<CJK Ideograph>) 1806 0x533E 匾 (<CJK Ideograph>) 1807 0x5342 卂 (<CJK Ideograph>) 1808 0x534C 卌 (<CJK Ideograph>) 1809 0x534B 卋 (<CJK Ideograph>) 1810 0x5359 卙 (<CJK Ideograph>) 1811 0x535B 卛 (<CJK Ideograph>) 1812 0x5361 卡 (<CJK Ideograph>) 1813 0x5363 卣 (<CJK Ideograph>) 1814 0x5365 卥 (<CJK Ideograph>) 1815 0x536C 卬 (<CJK Ideograph>) 1816 0x536D 卭 (<CJK Ideograph>) 1817 0x5372 卲 (<CJK Ideograph>) 1818 0x5379 卹 (<CJK Ideograph>) 1819 0x537E 卾 (<CJK Ideograph>) 1820 0x5383 厃 (<CJK Ideograph>) 1821 0x5387 厇 (<CJK Ideograph>) 1822 0x5388 厈 (<CJK Ideograph>) 1823 0x538E 厎 (<CJK Ideograph>) 1824 0x5393 厓 (<CJK Ideograph>) 1825 0x5394 厔 (<CJK Ideograph>) 1826 0x5399 厙 (<CJK Ideograph>) 1827 0x539D 厝 (<CJK Ideograph>) 1828 0x53A1 厡 (<CJK Ideograph>) 1829 0x53A4 厤 (<CJK Ideograph>) 1830 0x53AA 厪 (<CJK Ideograph>) 1831 0x53AB 厫 (<CJK Ideograph>) 1832 0x53AF 厯 (<CJK Ideograph>) 1833 0x53B2 厲 (<CJK Ideograph>) 1834 0x53B4 厴 (<CJK Ideograph>) 1835 0x53B5 厵 (<CJK Ideograph>) 1836 0x53B7 厷 (<CJK Ideograph>) 1837 0x53B8 厸 (<CJK Ideograph>) 1838 0x53BA 厺 (<CJK Ideograph>) 1839 0x53BD 厽 (<CJK Ideograph>) 1840 0x53C0 叀 (<CJK Ideograph>) 1841 0x53C5 叅 (<CJK Ideograph>) 1842 0x53CF 叏 (<CJK Ideograph>) 1843 0x53D2 叒 (<CJK Ideograph>) 1844 0x53D3 叓 (<CJK Ideograph>) 1845 0x53D5 叕 (<CJK Ideograph>) 1846 0x53DA 叚 (<CJK Ideograph>) 1847 0x53DD 叝 (<CJK Ideograph>) 1848 0x53DE 叞 (<CJK Ideograph>) 1849 0x53E0 叠 (<CJK Ideograph>) 1850 0x53E6 另 (<CJK Ideograph>) 1851 0x53E7 叧 (<CJK Ideograph>) 1852 0x53F5 叵 (<CJK Ideograph>) 1853 0x5402 吂 (<CJK Ideograph>) 1854 0x5413 吓 (<CJK Ideograph>) 1855 0x541A 吚 (<CJK Ideograph>) 1856 0x5421 吡 (<CJK Ideograph>) 1857 0x5427 吧 (<CJK Ideograph>) 1858 0x5428 吨 (<CJK Ideograph>) 1859 0x542A 吪 (<CJK Ideograph>) 1860 0x542F 启 (<CJK Ideograph>) 1861 0x5431 吱 (<CJK Ideograph>) 1862 0x5434 吴 (<CJK Ideograph>) 1863 0x5435 吵 (<CJK Ideograph>) 1864 0x5443 呃 (<CJK Ideograph>) 1865 0x5444 呄 (<CJK Ideograph>) 1866 0x5447 呇 (<CJK Ideograph>) 1867 0x544D 呍 (<CJK Ideograph>) 1868 0x544F 呏 (<CJK Ideograph>) 1869 0x545E 呞 (<CJK Ideograph>) 1870 0x5462 呢 (<CJK Ideograph>) 1871 0x5464 呤 (<CJK Ideograph>) 1872 0x5466 呦 (<CJK Ideograph>) 1873 0x5467 呧 (<CJK Ideograph>) 1874 0x5469 呩 (<CJK Ideograph>) 1875 0x546B 呫 (<CJK Ideograph>) 1876 0x546D 呭 (<CJK Ideograph>) 1877 0x546E 呮 (<CJK Ideograph>) 1878 0x5474 呴 (<CJK Ideograph>) 1879 0x547F 呿 (<CJK Ideograph>) 1880 0x5481 咁 (<CJK Ideograph>) 1881 0x5483 咃 (<CJK Ideograph>) 1882 0x5485 咅 (<CJK Ideograph>) 1883 0x5488 咈 (<CJK Ideograph>) 1884 0x5489 咉 (<CJK Ideograph>) 1885 0x548D 咍 (<CJK Ideograph>) 1886 0x5491 咑 (<CJK Ideograph>) 1887 0x5495 咕 (<CJK Ideograph>) 1888 0x5496 咖 (<CJK Ideograph>) 1889 0x549C 咜 (<CJK Ideograph>) 1890 0x549F 咟 (<CJK Ideograph>) 1891 0x54A1 咡 (<CJK Ideograph>) 1892 0x54A6 咦 (<CJK Ideograph>) 1893 0x54A7 咧 (<CJK Ideograph>) 1894 0x54A9 咩 (<CJK Ideograph>) 1895 0x54AA 咪 (<CJK Ideograph>) 1896 0x54AD 咭 (<CJK Ideograph>) 1897 0x54AE 咮 (<CJK Ideograph>) 1898 0x54B1 咱 (<CJK Ideograph>) 1899 0x54B7 咷 (<CJK Ideograph>) 1900 0x54B9 咹 (<CJK Ideograph>) 1901 0x54BA 咺 (<CJK Ideograph>) 1902 0x54BB 咻 (<CJK Ideograph>) 1903 0x54BF 咿 (<CJK Ideograph>) 1904 0x54C6 哆 (<CJK Ideograph>) 1905 0x54CA 哊 (<CJK Ideograph>) 1906 0x54CD 响 (<CJK Ideograph>) 1907 0x54CE 哎 (<CJK Ideograph>) 1908 0x54E0 哠 (<CJK Ideograph>) 1909 0x54EA 哪 (<CJK Ideograph>) 1910 0x54EC 哬 (<CJK Ideograph>) 1911 0x54EF 哯 (<CJK Ideograph>) 1912 0x54F6 哶 (<CJK Ideograph>) 1913 0x54FC 哼 (<CJK Ideograph>) 1914 0x54FE 哾 (<CJK Ideograph>) 1915 0x54FF 哿 (<CJK Ideograph>) 1916 0x5500 唀 (<CJK Ideograph>) 1917 0x5501 唁 (<CJK Ideograph>) 1918 0x5505 唅 (<CJK Ideograph>) 1919 0x5508 唈 (<CJK Ideograph>) 1920 0x5509 唉 (<CJK Ideograph>) 1921 0x550C 唌 (<CJK Ideograph>) 1922 0x550D 唍 (<CJK Ideograph>) 1923 0x550E 唎 (<CJK Ideograph>) 1924 0x5515 唕 (<CJK Ideograph>) 1925 0x552A 唪 (<CJK Ideograph>) 1926 0x552B 唫 (<CJK Ideograph>) 1927 0x5532 唲 (<CJK Ideograph>) 1928 0x5535 唵 (<CJK Ideograph>) 1929 0x5536 唶 (<CJK Ideograph>) 1930 0x553B 唻 (<CJK Ideograph>) 1931 0x553C 唼 (<CJK Ideograph>) 1932 0x553D 唽 (<CJK Ideograph>) 1933 0x5541 啁 (<CJK Ideograph>) 1934 0x5547 啇 (<CJK Ideograph>) 1935 0x5549 啉 (<CJK Ideograph>) 1936 0x554A 啊 (<CJK Ideograph>) 1937 0x554D 啍 (<CJK Ideograph>) 1938 0x5550 啐 (<CJK Ideograph>) 1939 0x5551 啑 (<CJK Ideograph>) 1940 0x5558 啘 (<CJK Ideograph>) 1941 0x555A 啚 (<CJK Ideograph>) 1942 0x555B 啛 (<CJK Ideograph>) 1943 0x555E 啞 (<CJK Ideograph>) 1944 0x5560 啠 (<CJK Ideograph>) 1945 0x5561 啡 (<CJK Ideograph>) 1946 0x5564 啤 (<CJK Ideograph>) 1947 0x5566 啦 (<CJK Ideograph>) 1948 0x557F 啿 (<CJK Ideograph>) 1949 0x5581 喁 (<CJK Ideograph>) 1950 0x5582 喂 (<CJK Ideograph>) 1951 0x5586 喆 (<CJK Ideograph>) 1952 0x5588 喈 (<CJK Ideograph>) 1953 0x558E 喎 (<CJK Ideograph>) 1954 0x558F 喏 (<CJK Ideograph>) 1955 0x5591 喑 (<CJK Ideograph>) 1956 0x5592 喒 (<CJK Ideograph>) 1957 0x5593 喓 (<CJK Ideograph>) 1958 0x5594 喔 (<CJK Ideograph>) 1959 0x5597 喗 (<CJK Ideograph>) 1960 0x55A3 喣 (<CJK Ideograph>) 1961 0x55A4 喤 (<CJK Ideograph>) 1962 0x55AD 喭 (<CJK Ideograph>) 1963 0x55B2 喲 (<CJK Ideograph>) 1964 0x55BF 喿 (<CJK Ideograph>) 1965 0x55C1 嗁 (<CJK Ideograph>) 1966 0x55C3 嗃 (<CJK Ideograph>) 1967 0x55C6 嗆 (<CJK Ideograph>) 1968 0x55C9 嗉 (<CJK Ideograph>) 1969 0x55CB 嗋 (<CJK Ideograph>) 1970 0x55CC 嗌 (<CJK Ideograph>) 1971 0x55CE 嗎 (<CJK Ideograph>) 1972 0x55D1 嗑 (<CJK Ideograph>) 1973 0x55D2 嗒 (<CJK Ideograph>) 1974 0x55D3 嗓 (<CJK Ideograph>) 1975 0x55D7 嗗 (<CJK Ideograph>) 1976 0x55D8 嗘 (<CJK Ideograph>) 1977 0x55DB 嗛 (<CJK Ideograph>) 1978 0x55DE 嗞 (<CJK Ideograph>) 1979 0x55E2 嗢 (<CJK Ideograph>) 1980 0x55E9 嗩 (<CJK Ideograph>) 1981 0x55F6 嗶 (<CJK Ideograph>) 1982 0x55FF 嗿 (<CJK Ideograph>) 1983 0x5605 嘅 (<CJK Ideograph>) 1984 0x5608 嘈 (<CJK Ideograph>) 1985 0x560A 嘊 (<CJK Ideograph>) 1986 0x560D 嘍 (<CJK Ideograph>) 1987 0x560E 嘎 (<CJK Ideograph>) 1988 0x560F 嘏 (<CJK Ideograph>) 1989 0x5610 嘐 (<CJK Ideograph>) 1990 0x5611 嘑 (<CJK Ideograph>) 1991 0x5612 嘒 (<CJK Ideograph>) 1992 0x5619 嘙 (<CJK Ideograph>) 1993 0x562C 嘬 (<CJK Ideograph>) 1994 0x5630 嘰 (<CJK Ideograph>) 1995 0x5633 嘳 (<CJK Ideograph>) 1996 0x5635 嘵 (<CJK Ideograph>) 1997 0x5637 嘷 (<CJK Ideograph>) 1998 0x5639 嘹 (<CJK Ideograph>) 1999 0x563B 嘻 (<CJK Ideograph>) 2000 0x563C 嘼 (<CJK Ideograph>) 2001 0x563D 嘽 (<CJK Ideograph>) 2002 0x563F 嘿 (<CJK Ideograph>) 2003 0x5640 噀 (<CJK Ideograph>) 2004 0x5641 噁 (<CJK Ideograph>) 2005 0x5643 噃 (<CJK Ideograph>) 2006 0x5644 噄 (<CJK Ideograph>) 2007 0x5646 噆 (<CJK Ideograph>) 2008 0x5649 噉 (<CJK Ideograph>) 2009 0x564B 噋 (<CJK Ideograph>) 2010 0x564D 噍 (<CJK Ideograph>) 2011 0x564F 噏 (<CJK Ideograph>) 2012 0x5654 噔 (<CJK Ideograph>) 2013 0x565E 噞 (<CJK Ideograph>) 2014 0x5660 噠 (<CJK Ideograph>) 2015 0x5661 噡 (<CJK Ideograph>) 2016 0x5662 噢 (<CJK Ideograph>) 2017 0x5663 噣 (<CJK Ideograph>) 2018 0x5666 噦 (<CJK Ideograph>) 2019 0x5669 噩 (<CJK Ideograph>) 2020 0x566D 噭 (<CJK Ideograph>) 2021 0x566F 噯 (<CJK Ideograph>) 2022 0x5671 噱 (<CJK Ideograph>) 2023 0x5672 噲 (<CJK Ideograph>) 2024 0x5675 噵 (<CJK Ideograph>) 2025 0x5684 嚄 (<CJK Ideograph>) 2026 0x5685 嚅 (<CJK Ideograph>) 2027 0x5688 嚈 (<CJK Ideograph>) 2028 0x568B 嚋 (<CJK Ideograph>) 2029 0x568C 嚌 (<CJK Ideograph>) 2030 0x5695 嚕 (<CJK Ideograph>) 2031 0x5699 嚙 (<CJK Ideograph>) 2032 0x569A 嚚 (<CJK Ideograph>) 2033 0x569D 嚝 (<CJK Ideograph>) 2034 0x569E 嚞 (<CJK Ideograph>) 2035 0x569F 嚟 (<CJK Ideograph>) 2036 0x56A6 嚦 (<CJK Ideograph>) 2037 0x56A7 嚧 (<CJK Ideograph>) 2038 0x56A8 嚨 (<CJK Ideograph>) 2039 0x56A9 嚩 (<CJK Ideograph>) 2040 0x56AB 嚫 (<CJK Ideograph>) 2041 0x56AC 嚬 (<CJK Ideograph>) 2042 0x56AD 嚭 (<CJK Ideograph>) 2043 0x56B1 嚱 (<CJK Ideograph>) 2044 0x56B3 嚳 (<CJK Ideograph>) 2045 0x56B7 嚷 (<CJK Ideograph>) 2046 0x56BE 嚾 (<CJK Ideograph>) 2047 0x56C5 囅 (<CJK Ideograph>) 2048 0x56C9 囉 (<CJK Ideograph>) 2049 0x56CA 囊 (<CJK Ideograph>) 2050 0x56CB 囋 (<CJK Ideograph>) 2051 0x56CF 囏 (<CJK Ideograph>) 2052 0x56D0 囐 (<CJK Ideograph>) 2053 0x56CC 囌 (<CJK Ideograph>) 2054 0x56CD 囍 (<CJK Ideograph>) 2055 0x56D9 囙 (<CJK Ideograph>) 2056 0x56DC 囜 (<CJK Ideograph>) 2057 0x56DD 囝 (<CJK Ideograph>) 2058 0x56DF 囟 (<CJK Ideograph>) 2059 0x56E1 囡 (<CJK Ideograph>) 2060 0x56E4 囤 (<CJK Ideograph>) 2061 0x56E5 囥 (<CJK Ideograph>) 2062 0x56E6 囦 (<CJK Ideograph>) 2063 0x56E7 囧 (<CJK Ideograph>) 2064 0x56E8 囨 (<CJK Ideograph>) 2065 0x56F1 囱 (<CJK Ideograph>) 2066 0x56EB 囫 (<CJK Ideograph>) 2067 0x56ED 园 (<CJK Ideograph>) 2068 0x56F6 囶 (<CJK Ideograph>) 2069 0x56F7 囷 (<CJK Ideograph>) 2070 0x5701 圁 (<CJK Ideograph>) 2071 0x5702 圂 (<CJK Ideograph>) 2072 0x5707 圇 (<CJK Ideograph>) 2073 0x570A 圊 (<CJK Ideograph>) 2074 0x570C 圌 (<CJK Ideograph>) 2075 0x5711 圑 (<CJK Ideograph>) 2076 0x5715 圕 (<CJK Ideograph>) 2077 0x571A 圚 (<CJK Ideograph>) 2078 0x571B 圛 (<CJK Ideograph>) 2079 0x571D 圝 (<CJK Ideograph>) 2080 0x5720 圠 (<CJK Ideograph>) 2081 0x5722 圢 (<CJK Ideograph>) 2082 0x5723 圣 (<CJK Ideograph>) 2083 0x5724 圤 (<CJK Ideograph>) 2084 0x5725 圥 (<CJK Ideograph>) 2085 0x5729 圩 (<CJK Ideograph>) 2086 0x572A 圪 (<CJK Ideograph>) 2087 0x572C 圬 (<CJK Ideograph>) 2088 0x572E 圮 (<CJK Ideograph>) 2089 0x572F 圯 (<CJK Ideograph>) 2090 0x5733 圳 (<CJK Ideograph>) 2091 0x5734 圴 (<CJK Ideograph>) 2092 0x573D 圽 (<CJK Ideograph>) 2093 0x573E 圾 (<CJK Ideograph>) 2094 0x573F 圿 (<CJK Ideograph>) 2095 0x5745 坅 (<CJK Ideograph>) 2096 0x5746 坆 (<CJK Ideograph>) 2097 0x574C 坌 (<CJK Ideograph>) 2098 0x574D 坍 (<CJK Ideograph>) 2099 0x5752 坒 (<CJK Ideograph>) 2100 0x5762 坢 (<CJK Ideograph>) 2101 0x5765 坥 (<CJK Ideograph>) 2102 0x5767 坧 (<CJK Ideograph>) 2103 0x5768 坨 (<CJK Ideograph>) 2104 0x576B 坫 (<CJK Ideograph>) 2105 0x576D 坭 (<CJK Ideograph>) 2106 0x576E 坮 (<CJK Ideograph>) 2107 0x576F 坯 (<CJK Ideograph>) 2108 0x5770 坰 (<CJK Ideograph>) 2109 0x5771 坱 (<CJK Ideograph>) 2110 0x5773 坳 (<CJK Ideograph>) 2111 0x5774 坴 (<CJK Ideograph>) 2112 0x5775 坵 (<CJK Ideograph>) 2113 0x5777 坷 (<CJK Ideograph>) 2114 0x5779 坹 (<CJK Ideograph>) 2115 0x577A 坺 (<CJK Ideograph>) 2116 0x577B 坻 (<CJK Ideograph>) 2117 0x577C 坼 (<CJK Ideograph>) 2118 0x577E 坾 (<CJK Ideograph>) 2119 0x5781 垁 (<CJK Ideograph>) 2120 0x5783 垃 (<CJK Ideograph>) 2121 0x578C 垌 (<CJK Ideograph>) 2122 0x5794 垔 (<CJK Ideograph>) 2123 0x5797 垗 (<CJK Ideograph>) 2124 0x5799 垙 (<CJK Ideograph>) 2125 0x579A 垚 (<CJK Ideograph>) 2126 0x579C 垜 (<CJK Ideograph>) 2127 0x579D 垝 (<CJK Ideograph>) 2128 0x579E 垞 (<CJK Ideograph>) 2129 0x579F 垟 (<CJK Ideograph>) 2130 0x57A1 垡 (<CJK Ideograph>) 2131 0x5795 垕 (<CJK Ideograph>) 2132 0x57A7 垧 (<CJK Ideograph>) 2133 0x57A8 垨 (<CJK Ideograph>) 2134 0x57A9 垩 (<CJK Ideograph>) 2135 0x57AC 垬 (<CJK Ideograph>) 2136 0x57B8 垸 (<CJK Ideograph>) 2137 0x57BD 垽 (<CJK Ideograph>) 2138 0x57C7 埇 (<CJK Ideograph>) 2139 0x57C8 埈 (<CJK Ideograph>) 2140 0x57CC 埌 (<CJK Ideograph>) 2141 0x57CF 埏 (<CJK Ideograph>) 2142 0x57D5 埕 (<CJK Ideograph>) 2143 0x57DD 埝 (<CJK Ideograph>) 2144 0x57DE 埞 (<CJK Ideograph>) 2145 0x57E4 埤 (<CJK Ideograph>) 2146 0x57E6 埦 (<CJK Ideograph>) 2147 0x57E7 埧 (<CJK Ideograph>) 2148 0x57E9 埩 (<CJK Ideograph>) 2149 0x57ED 埭 (<CJK Ideograph>) 2150 0x57F0 埰 (<CJK Ideograph>) 2151 0x57F5 埵 (<CJK Ideograph>) 2152 0x57F6 埶 (<CJK Ideograph>) 2153 0x57F8 埸 (<CJK Ideograph>) 2154 0x57FD 埽 (<CJK Ideograph>) 2155 0x57FE 埾 (<CJK Ideograph>) 2156 0x57FF 埿 (<CJK Ideograph>) 2157 0x5803 堃 (<CJK Ideograph>) 2158 0x5804 堄 (<CJK Ideograph>) 2159 0x5808 堈 (<CJK Ideograph>) 2160 0x5809 堉 (<CJK Ideograph>) 2161 0x57E1 埡 (<CJK Ideograph>) 2162 0x580C 堌 (<CJK Ideograph>) 2163 0x580D 堍 (<CJK Ideograph>) 2164 0x581B 堛 (<CJK Ideograph>) 2165 0x581E 堞 (<CJK Ideograph>) 2166 0x581F 堟 (<CJK Ideograph>) 2167 0x5820 堠 (<CJK Ideograph>) 2168 0x5826 堦 (<CJK Ideograph>) 2169 0x5827 堧 (<CJK Ideograph>) 2170 0x582D 堭 (<CJK Ideograph>) 2171 0x5832 堲 (<CJK Ideograph>) 2172 0x5839 堹 (<CJK Ideograph>) 2173 0x583F 堿 (<CJK Ideograph>) 2174 0x5849 塉 (<CJK Ideograph>) 2175 0x584C 塌 (<CJK Ideograph>) 2176 0x584D 塍 (<CJK Ideograph>) 2177 0x584F 塏 (<CJK Ideograph>) 2178 0x5850 塐 (<CJK Ideograph>) 2179 0x5855 塕 (<CJK Ideograph>) 2180 0x585F 塟 (<CJK Ideograph>) 2181 0x5861 塡 (<CJK Ideograph>) 2182 0x5864 塤 (<CJK Ideograph>) 2183 0x5867 塧 (<CJK Ideograph>) 2184 0x5868 塨 (<CJK Ideograph>) 2185 0x5878 塸 (<CJK Ideograph>) 2186 0x587C 塼 (<CJK Ideograph>) 2187 0x587F 塿 (<CJK Ideograph>) 2188 0x5880 墀 (<CJK Ideograph>) 2189 0x5881 墁 (<CJK Ideograph>) 2190 0x5887 墇 (<CJK Ideograph>) 2191 0x5888 墈 (<CJK Ideograph>) 2192 0x5889 墉 (<CJK Ideograph>) 2193 0x588A 墊 (<CJK Ideograph>) 2194 0x588C 墌 (<CJK Ideograph>) 2195 0x588D 墍 (<CJK Ideograph>) 2196 0x588F 墏 (<CJK Ideograph>) 2197 0x5890 墐 (<CJK Ideograph>) 2198 0x5894 墔 (<CJK Ideograph>) 2199 0x5896 墖 (<CJK Ideograph>) 2200 0x589D 墝 (<CJK Ideograph>) 2201 0x58A0 墠 (<CJK Ideograph>) 2202 0x58A1 墡 (<CJK Ideograph>) 2203 0x58A2 墢 (<CJK Ideograph>) 2204 0x58A6 墦 (<CJK Ideograph>) 2205 0x58A9 墩 (<CJK Ideograph>) 2206 0x58B1 墱 (<CJK Ideograph>) 2207 0x58B2 墲 (<CJK Ideograph>) 2208 0x58C4 壄 (<CJK Ideograph>) 2209 0x58BC 墼 (<CJK Ideograph>) 2210 0x58C2 壂 (<CJK Ideograph>) 2211 0x58C8 壈 (<CJK Ideograph>) 2212 0x58CD 壍 (<CJK Ideograph>) 2213 0x58CE 壎 (<CJK Ideograph>) 2214 0x58D0 壐 (<CJK Ideograph>) 2215 0x58D2 壒 (<CJK Ideograph>) 2216 0x58D4 壔 (<CJK Ideograph>) 2217 0x58D6 壖 (<CJK Ideograph>) 2218 0x58DA 壚 (<CJK Ideograph>) 2219 0x58DD 壝 (<CJK Ideograph>) 2220 0x58E1 壡 (<CJK Ideograph>) 2221 0x58E2 壢 (<CJK Ideograph>) 2222 0x58E9 壩 (<CJK Ideograph>) 2223 0x58F3 壳 (<CJK Ideograph>) 2224 0x5905 夅 (<CJK Ideograph>) 2225 0x5906 夆 (<CJK Ideograph>) 2226 0x590B 夋 (<CJK Ideograph>) 2227 0x590C 夌 (<CJK Ideograph>) 2228 0x5912 夒 (<CJK Ideograph>) 2229 0x5913 夓 (<CJK Ideograph>) 2230 0x5914 夔 (<CJK Ideograph>) 2231 0x8641 虁 (<CJK Ideograph>) 2232 0x591D 夝 (<CJK Ideograph>) 2233 0x5921 夡 (<CJK Ideograph>) 2234 0x5923 夣 (<CJK Ideograph>) 2235 0x5924 夤 (<CJK Ideograph>) 2236 0x5928 夨 (<CJK Ideograph>) 2237 0x592F 夯 (<CJK Ideograph>) 2238 0x5930 夰 (<CJK Ideograph>) 2239 0x5933 夳 (<CJK Ideograph>) 2240 0x5935 夵 (<CJK Ideograph>) 2241 0x5936 夶 (<CJK Ideograph>) 2242 0x593F 夿 (<CJK Ideograph>) 2243 0x5943 奃 (<CJK Ideograph>) 2244 0x5946 奆 (<CJK Ideograph>) 2245 0x5952 奒 (<CJK Ideograph>) 2246 0x5953 奓 (<CJK Ideograph>) 2247 0x5959 奙 (<CJK Ideograph>) 2248 0x595B 奛 (<CJK Ideograph>) 2249 0x595D 奝 (<CJK Ideograph>) 2250 0x595E 奞 (<CJK Ideograph>) 2251 0x595F 奟 (<CJK Ideograph>) 2252 0x5961 奡 (<CJK Ideograph>) 2253 0x5963 奣 (<CJK Ideograph>) 2254 0x596B 奫 (<CJK Ideograph>) 2255 0x596D 奭 (<CJK Ideograph>) 2256 0x596F 奯 (<CJK Ideograph>) 2257 0x5972 奲 (<CJK Ideograph>) 2258 0x5975 奵 (<CJK Ideograph>) 2259 0x5976 奶 (<CJK Ideograph>) 2260 0x5979 她 (<CJK Ideograph>) 2261 0x597B 奻 (<CJK Ideograph>) 2262 0x597C 奼 (<CJK Ideograph>) 2263 0x598B 妋 (<CJK Ideograph>) 2264 0x598C 妌 (<CJK Ideograph>) 2265 0x598E 妎 (<CJK Ideograph>) 2266 0x5992 妒 (<CJK Ideograph>) 2267 0x5995 妕 (<CJK Ideograph>) 2268 0x5997 妗 (<CJK Ideograph>) 2269 0x599F 妟 (<CJK Ideograph>) 2270 0x59A4 妤 (<CJK Ideograph>) 2271 0x59A7 妧 (<CJK Ideograph>) 2272 0x59AD 妭 (<CJK Ideograph>) 2273 0x59AE 妮 (<CJK Ideograph>) 2274 0x59AF 妯 (<CJK Ideograph>) 2275 0x59B0 妰 (<CJK Ideograph>) 2276 0x59B3 妳 (<CJK Ideograph>) 2277 0x59B7 妷 (<CJK Ideograph>) 2278 0x59BA 妺 (<CJK Ideograph>) 2279 0x59BC 妼 (<CJK Ideograph>) 2280 0x59C1 姁 (<CJK Ideograph>) 2281 0x59C3 姃 (<CJK Ideograph>) 2282 0x59C4 姄 (<CJK Ideograph>) 2283 0x59C8 姈 (<CJK Ideograph>) 2284 0x59CA 姊 (<CJK Ideograph>) 2285 0x59CD 姍 (<CJK Ideograph>) 2286 0x59D2 姒 (<CJK Ideograph>) 2287 0x59DD 姝 (<CJK Ideograph>) 2288 0x59DE 姞 (<CJK Ideograph>) 2289 0x59DF 姟 (<CJK Ideograph>) 2290 0x59E3 姣 (<CJK Ideograph>) 2291 0x59E4 姤 (<CJK Ideograph>) 2292 0x59E7 姧 (<CJK Ideograph>) 2293 0x59EE 姮 (<CJK Ideograph>) 2294 0x59EF 姯 (<CJK Ideograph>) 2295 0x59F1 姱 (<CJK Ideograph>) 2296 0x59F2 姲 (<CJK Ideograph>) 2297 0x59F4 姴 (<CJK Ideograph>) 2298 0x59F7 姷 (<CJK Ideograph>) 2299 0x5A00 娀 (<CJK Ideograph>) 2300 0x5A04 娄 (<CJK Ideograph>) 2301 0x5A0C 娌 (<CJK Ideograph>) 2302 0x5A0D 娍 (<CJK Ideograph>) 2303 0x5A0E 娎 (<CJK Ideograph>) 2304 0x5A12 娒 (<CJK Ideograph>) 2305 0x5A13 娓 (<CJK Ideograph>) 2306 0x5A1E 娞 (<CJK Ideograph>) 2307 0x5A23 娣 (<CJK Ideograph>) 2308 0x5A24 娤 (<CJK Ideograph>) 2309 0x5A27 娧 (<CJK Ideograph>) 2310 0x5A28 娨 (<CJK Ideograph>) 2311 0x5A2A 娪 (<CJK Ideograph>) 2312 0x5A2D 娭 (<CJK Ideograph>) 2313 0x5A30 娰 (<CJK Ideograph>) 2314 0x5A44 婄 (<CJK Ideograph>) 2315 0x5A45 婅 (<CJK Ideograph>) 2316 0x5A47 婇 (<CJK Ideograph>) 2317 0x5A48 婈 (<CJK Ideograph>) 2318 0x5A4C 婌 (<CJK Ideograph>) 2319 0x5A50 婐 (<CJK Ideograph>) 2320 0x5A55 婕 (<CJK Ideograph>) 2321 0x5A5E 婞 (<CJK Ideograph>) 2322 0x5A63 婣 (<CJK Ideograph>) 2323 0x5A65 婥 (<CJK Ideograph>) 2324 0x5A67 婧 (<CJK Ideograph>) 2325 0x5A6D 婭 (<CJK Ideograph>) 2326 0x5A77 婷 (<CJK Ideograph>) 2327 0x5A7A 婺 (<CJK Ideograph>) 2328 0x5A7B 婻 (<CJK Ideograph>) 2329 0x5A7E 婾 (<CJK Ideograph>) 2330 0x5A8B 媋 (<CJK Ideograph>) 2331 0x5A90 媐 (<CJK Ideograph>) 2332 0x5A93 媓 (<CJK Ideograph>) 2333 0x5A96 媖 (<CJK Ideograph>) 2334 0x5A99 媙 (<CJK Ideograph>) 2335 0x5A9C 媜 (<CJK Ideograph>) 2336 0x5A9E 媞 (<CJK Ideograph>) 2337 0x5A9F 媟 (<CJK Ideograph>) 2338 0x5AA0 媠 (<CJK Ideograph>) 2339 0x5AA2 媢 (<CJK Ideograph>) 2340 0x5AA7 媧 (<CJK Ideograph>) 2341 0x5AAC 媬 (<CJK Ideograph>) 2342 0x5AB1 媱 (<CJK Ideograph>) 2343 0x5AB2 媲 (<CJK Ideograph>) 2344 0x5AB3 媳 (<CJK Ideograph>) 2345 0x5AB5 媵 (<CJK Ideograph>) 2346 0x5AB8 媸 (<CJK Ideograph>) 2347 0x5ABA 媺 (<CJK Ideograph>) 2348 0x5ABB 媻 (<CJK Ideograph>) 2349 0x5ABF 媿 (<CJK Ideograph>) 2350 0x5AC4 嫄 (<CJK Ideograph>) 2351 0x5AC6 嫆 (<CJK Ideograph>) 2352 0x5AC8 嫈 (<CJK Ideograph>) 2353 0x5ACF 嫏 (<CJK Ideograph>) 2354 0x5ADA 嫚 (<CJK Ideograph>) 2355 0x5ADC 嫜 (<CJK Ideograph>) 2356 0x5AE0 嫠 (<CJK Ideograph>) 2357 0x5AE5 嫥 (<CJK Ideograph>) 2358 0x5AEA 嫪 (<CJK Ideograph>) 2359 0x5AEE 嫮 (<CJK Ideograph>) 2360 0x5AF5 嫵 (<CJK Ideograph>) 2361 0x5AF6 嫶 (<CJK Ideograph>) 2362 0x5AFD 嫽 (<CJK Ideograph>) 2363 0x5B00 嬀 (<CJK Ideograph>) 2364 0x5B01 嬁 (<CJK Ideograph>) 2365 0x5B08 嬈 (<CJK Ideograph>) 2366 0x5B17 嬗 (<CJK Ideograph>) 2367 0x5B34 嬴 (<CJK Ideograph>) 2368 0x5B19 嬙 (<CJK Ideograph>) 2369 0x5B1B 嬛 (<CJK Ideograph>) 2370 0x5B1D 嬝 (<CJK Ideograph>) 2371 0x5B21 嬡 (<CJK Ideograph>) 2372 0x5B25 嬥 (<CJK Ideograph>) 2373 0x5B2D 嬭 (<CJK Ideograph>) 2374 0x5B38 嬸 (<CJK Ideograph>) 2375 0x5B41 孁 (<CJK Ideograph>) 2376 0x5B4B 孋 (<CJK Ideograph>) 2377 0x5B4C 孌 (<CJK Ideograph>) 2378 0x5B52 孒 (<CJK Ideograph>) 2379 0x5B56 孖 (<CJK Ideograph>) 2380 0x5B5E 孞 (<CJK Ideograph>) 2381 0x5B68 孨 (<CJK Ideograph>) 2382 0x5B6E 孮 (<CJK Ideograph>) 2383 0x5B6F 孯 (<CJK Ideograph>) 2384 0x5B7C 孼 (<CJK Ideograph>) 2385 0x5B7D 孽 (<CJK Ideograph>) 2386 0x5B7E 孾 (<CJK Ideograph>) 2387 0x5B7F 孿 (<CJK Ideograph>) 2388 0x5B81 宁 (<CJK Ideograph>) 2389 0x5B84 宄 (<CJK Ideograph>) 2390 0x5B86 宆 (<CJK Ideograph>) 2391 0x5B8A 宊 (<CJK Ideograph>) 2392 0x5B8E 宎 (<CJK Ideograph>) 2393 0x5B90 宐 (<CJK Ideograph>) 2394 0x5B91 宑 (<CJK Ideograph>) 2395 0x5B93 宓 (<CJK Ideograph>) 2396 0x5B94 宔 (<CJK Ideograph>) 2397 0x5B96 宖 (<CJK Ideograph>) 2398 0x5BA8 宨 (<CJK Ideograph>) 2399 0x5BA9 宩 (<CJK Ideograph>) 2400 0x5BAC 宬 (<CJK Ideograph>) 2401 0x5BAD 宭 (<CJK Ideograph>) 2402 0x5BAF 宯 (<CJK Ideograph>) 2403 0x5BB1 宱 (<CJK Ideograph>) 2404 0x5BB2 宲 (<CJK Ideograph>) 2405 0x5BB7 宷 (<CJK Ideograph>) 2406 0x5BBA 宺 (<CJK Ideograph>) 2407 0x5BBC 宼 (<CJK Ideograph>) 2408 0x5BC0 寀 (<CJK Ideograph>) 2409 0x5BC1 寁 (<CJK Ideograph>) 2410 0x5BCD 寍 (<CJK Ideograph>) 2411 0x5BCF 寏 (<CJK Ideograph>) 2412 0x5BD6 寖 (<CJK Ideograph>) 2413 0x5BD7 寗 (<CJK Ideograph>) 2414 0x5BD8 寘 (<CJK Ideograph>) 2415 0x5BD9 寙 (<CJK Ideograph>) 2416 0x5BDA 寚 (<CJK Ideograph>) 2417 0x5BE0 寠 (<CJK Ideograph>) 2418 0x5BEF 寯 (<CJK Ideograph>) 2419 0x5BF1 寱 (<CJK Ideograph>) 2420 0x5BF4 寴 (<CJK Ideograph>) 2421 0x5BFD 寽 (<CJK Ideograph>) 2422 0x5C0C 尌 (<CJK Ideograph>) 2423 0x5C17 尗 (<CJK Ideograph>) 2424 0x5C1E 尞 (<CJK Ideograph>) 2425 0x5C1F 尟 (<CJK Ideograph>) 2426 0x5C23 尣 (<CJK Ideograph>) 2427 0x5C26 尦 (<CJK Ideograph>) 2428 0x5C29 尩 (<CJK Ideograph>) 2429 0x5C2B 尫 (<CJK Ideograph>) 2430 0x5C2C 尬 (<CJK Ideograph>) 2431 0x5C2E 尮 (<CJK Ideograph>) 2432 0x5C30 尰 (<CJK Ideograph>) 2433 0x5C32 尲 (<CJK Ideograph>) 2434 0x5C35 尵 (<CJK Ideograph>) 2435 0x5C36 尶 (<CJK Ideograph>) 2436 0x5C59 屙 (<CJK Ideograph>) 2437 0x5C5A 屚 (<CJK Ideograph>) 2438 0x5C5C 屜 (<CJK Ideograph>) 2439 0x5C62 屢 (<CJK Ideograph>) 2440 0x5C63 屣 (<CJK Ideograph>) 2441 0x5C67 屧 (<CJK Ideograph>) 2442 0x5C68 屨 (<CJK Ideograph>) 2443 0x5C69 屩 (<CJK Ideograph>) 2444 0x5C6D 屭 (<CJK Ideograph>) 2445 0x5C70 屰 (<CJK Ideograph>) 2446 0x5C74 屴 (<CJK Ideograph>) 2447 0x5C75 屵 (<CJK Ideograph>) 2448 0x5C7A 屺 (<CJK Ideograph>) 2449 0x5C7B 屻 (<CJK Ideograph>) 2450 0x5C7C 屼 (<CJK Ideograph>) 2451 0x5C7D 屽 (<CJK Ideograph>) 2452 0x5C87 岇 (<CJK Ideograph>) 2453 0x5C88 岈 (<CJK Ideograph>) 2454 0x5C8A 岊 (<CJK Ideograph>) 2455 0x5C8F 岏 (<CJK Ideograph>) 2456 0x5C92 岒 (<CJK Ideograph>) 2457 0x5C9D 岝 (<CJK Ideograph>) 2458 0x5C9F 岟 (<CJK Ideograph>) 2459 0x5CA0 岠 (<CJK Ideograph>) 2460 0x5CA2 岢 (<CJK Ideograph>) 2461 0x5CA3 岣 (<CJK Ideograph>) 2462 0x5CA6 岦 (<CJK Ideograph>) 2463 0x5CAA 岪 (<CJK Ideograph>) 2464 0x5CB2 岲 (<CJK Ideograph>) 2465 0x5CB4 岴 (<CJK Ideograph>) 2466 0x5CB5 岵 (<CJK Ideograph>) 2467 0x5CBA 岺 (<CJK Ideograph>) 2468 0x5CC9 峉 (<CJK Ideograph>) 2469 0x5CCB 峋 (<CJK Ideograph>) 2470 0x5CD2 峒 (<CJK Ideograph>) 2471 0x5CDD 峝 (<CJK Ideograph>) 2472 0x5CD7 峗 (<CJK Ideograph>) 2473 0x5CEE 峮 (<CJK Ideograph>) 2474 0x5CF1 峱 (<CJK Ideograph>) 2475 0x5CF2 峲 (<CJK Ideograph>) 2476 0x5CF4 峴 (<CJK Ideograph>) 2477 0x5D01 崁 (<CJK Ideograph>) 2478 0x5D06 崆 (<CJK Ideograph>) 2479 0x5D0D 崍 (<CJK Ideograph>) 2480 0x5D12 崒 (<CJK Ideograph>) 2481 0x5D2B 崫 (<CJK Ideograph>) 2482 0x5D23 崣 (<CJK Ideograph>) 2483 0x5D24 崤 (<CJK Ideograph>) 2484 0x5D26 崦 (<CJK Ideograph>) 2485 0x5D27 崧 (<CJK Ideograph>) 2486 0x5D31 崱 (<CJK Ideograph>) 2487 0x5D34 崴 (<CJK Ideograph>) 2488 0x5D39 崹 (<CJK Ideograph>) 2489 0x5D3D 崽 (<CJK Ideograph>) 2490 0x5D3F 崿 (<CJK Ideograph>) 2491 0x5D42 嵂 (<CJK Ideograph>) 2492 0x5D43 嵃 (<CJK Ideograph>) 2493 0x5D46 嵆 (<CJK Ideograph>) 2494 0x5D48 嵈 (<CJK Ideograph>) 2495 0x5D55 嵕 (<CJK Ideograph>) 2496 0x5D51 嵑 (<CJK Ideograph>) 2497 0x5D59 嵙 (<CJK Ideograph>) 2498 0x5D4A 嵊 (<CJK Ideograph>) 2499 0x5D5F 嵟 (<CJK Ideograph>) 2500 0x5D60 嵠 (<CJK Ideograph>) 2501 0x5D61 嵡 (<CJK Ideograph>) 2502 0x5D62 嵢 (<CJK Ideograph>) 2503 0x5D64 嵤 (<CJK Ideograph>) 2504 0x5D6A 嵪 (<CJK Ideograph>) 2505 0x5D6D 嵭 (<CJK Ideograph>) 2506 0x5D70 嵰 (<CJK Ideograph>) 2507 0x5D79 嵹 (<CJK Ideograph>) 2508 0x5D7A 嵺 (<CJK Ideograph>) 2509 0x5D7E 嵾 (<CJK Ideograph>) 2510 0x5D7F 嵿 (<CJK Ideograph>) 2511 0x5D81 嶁 (<CJK Ideograph>) 2512 0x5D83 嶃 (<CJK Ideograph>) 2513 0x5D88 嶈 (<CJK Ideograph>) 2514 0x5D8A 嶊 (<CJK Ideograph>) 2515 0x5D92 嶒 (<CJK Ideograph>) 2516 0x5D93 嶓 (<CJK Ideograph>) 2517 0x5D94 嶔 (<CJK Ideograph>) 2518 0x5D95 嶕 (<CJK Ideograph>) 2519 0x5D99 嶙 (<CJK Ideograph>) 2520 0x5D9B 嶛 (<CJK Ideograph>) 2521 0x5D9F 嶟 (<CJK Ideograph>) 2522 0x5DA0 嶠 (<CJK Ideograph>) 2523 0x5DA7 嶧 (<CJK Ideograph>) 2524 0x5DAB 嶫 (<CJK Ideograph>) 2525 0x5DB0 嶰 (<CJK Ideograph>) 2526 0x5DB4 嶴 (<CJK Ideograph>) 2527 0x5DB8 嶸 (<CJK Ideograph>) 2528 0x5DB9 嶹 (<CJK Ideograph>) 2529 0x5DC3 巃 (<CJK Ideograph>) 2530 0x5DC7 巇 (<CJK Ideograph>) 2531 0x5DCB 巋 (<CJK Ideograph>) 2532 0x5DD0 巐 (<CJK Ideograph>) 2533 0x5DCE 巎 (<CJK Ideograph>) 2534 0x5DD8 巘 (<CJK Ideograph>) 2535 0x5DD9 巙 (<CJK Ideograph>) 2536 0x5DE0 巠 (<CJK Ideograph>) 2537 0x5DE4 巤 (<CJK Ideograph>) 2538 0x5DE9 巩 (<CJK Ideograph>) 2539 0x5DF8 巸 (<CJK Ideograph>) 2540 0x5DF9 巹 (<CJK Ideograph>) 2541 0x5E00 帀 (<CJK Ideograph>) 2542 0x5E07 帇 (<CJK Ideograph>) 2543 0x5E0D 帍 (<CJK Ideograph>) 2544 0x5E12 帒 (<CJK Ideograph>) 2545 0x5E14 帔 (<CJK Ideograph>) 2546 0x5E15 帕 (<CJK Ideograph>) 2547 0x5E18 帘 (<CJK Ideograph>) 2548 0x5E1F 帟 (<CJK Ideograph>) 2549 0x5E20 帠 (<CJK Ideograph>) 2550 0x5E2E 帮 (<CJK Ideograph>) 2551 0x5E28 帨 (<CJK Ideograph>) 2552 0x5E32 帲 (<CJK Ideograph>) 2553 0x5E35 帵 (<CJK Ideograph>) 2554 0x5E3E 帾 (<CJK Ideograph>) 2555 0x5E4B 幋 (<CJK Ideograph>) 2556 0x5E50 幐 (<CJK Ideograph>) 2557 0x5E49 幉 (<CJK Ideograph>) 2558 0x5E51 幑 (<CJK Ideograph>) 2559 0x5E56 幖 (<CJK Ideograph>) 2560 0x5E58 幘 (<CJK Ideograph>) 2561 0x5E5B 幛 (<CJK Ideograph>) 2562 0x5E5C 幜 (<CJK Ideograph>) 2563 0x5E5E 幞 (<CJK Ideograph>) 2564 0x5E68 幨 (<CJK Ideograph>) 2565 0x5E6A 幪 (<CJK Ideograph>) 2566 0x5E6B 幫 (<CJK Ideograph>) 2567 0x5E6C 幬 (<CJK Ideograph>) 2568 0x5E6D 幭 (<CJK Ideograph>) 2569 0x5E6E 幮 (<CJK Ideograph>) 2570 0x5E70 幰 (<CJK Ideograph>) 2571 0x5E80 庀 (<CJK Ideograph>) 2572 0x5E8B 庋 (<CJK Ideograph>) 2573 0x5E8E 庎 (<CJK Ideograph>) 2574 0x5EA2 庢 (<CJK Ideograph>) 2575 0x5EA4 庤 (<CJK Ideograph>) 2576 0x5EA5 庥 (<CJK Ideograph>) 2577 0x5EA8 庨 (<CJK Ideograph>) 2578 0x5EAA 庪 (<CJK Ideograph>) 2579 0x5EAC 庬 (<CJK Ideograph>) 2580 0x5EB1 庱 (<CJK Ideograph>) 2581 0x5EB3 庳 (<CJK Ideograph>) 2582 0x5EBD 庽 (<CJK Ideograph>) 2583 0x5EBE 庾 (<CJK Ideograph>) 2584 0x5EBF 庿 (<CJK Ideograph>) 2585 0x5EC6 廆 (<CJK Ideograph>) 2586 0x5ECC 廌 (<CJK Ideograph>) 2587 0x5ECB 廋 (<CJK Ideograph>) 2588 0x5ECE 廎 (<CJK Ideograph>) 2589 0x5ED1 廑 (<CJK Ideograph>) 2590 0x5ED2 廒 (<CJK Ideograph>) 2591 0x5ED4 廔 (<CJK Ideograph>) 2592 0x5ED5 廕 (<CJK Ideograph>) 2593 0x5EDC 廜 (<CJK Ideograph>) 2594 0x5EDE 廞 (<CJK Ideograph>) 2595 0x5EE5 廥 (<CJK Ideograph>) 2596 0x5EEB 廫 (<CJK Ideograph>) 2597 0x5F02 异 (<CJK Ideograph>) 2598 0x5F06 弆 (<CJK Ideograph>) 2599 0x5F07 弇 (<CJK Ideograph>) 2600 0x5F08 弈 (<CJK Ideograph>) 2601 0x5F0E 弎 (<CJK Ideograph>) 2602 0x5F19 弙 (<CJK Ideograph>) 2603 0x5F1C 弜 (<CJK Ideograph>) 2604 0x5F1D 弝 (<CJK Ideograph>) 2605 0x5F21 弡 (<CJK Ideograph>) 2606 0x5F22 弢 (<CJK Ideograph>) 2607 0x5F23 弣 (<CJK Ideograph>) 2608 0x5F24 弤 (<CJK Ideograph>) 2609 0x5F28 弨 (<CJK Ideograph>) 2610 0x5F2B 弫 (<CJK Ideograph>) 2611 0x5F2C 弬 (<CJK Ideograph>) 2612 0x5F2E 弮 (<CJK Ideograph>) 2613 0x5F30 弰 (<CJK Ideograph>) 2614 0x5F34 弴 (<CJK Ideograph>) 2615 0x5F36 弶 (<CJK Ideograph>) 2616 0x5F3B 弻 (<CJK Ideograph>) 2617 0x5F3D 弽 (<CJK Ideograph>) 2618 0x5F3F 弿 (<CJK Ideograph>) 2619 0x5F40 彀 (<CJK Ideograph>) 2620 0x5F44 彄 (<CJK Ideograph>) 2621 0x5F45 彅 (<CJK Ideograph>) 2622 0x5F47 彇 (<CJK Ideograph>) 2623 0x5F4D 彍 (<CJK Ideograph>) 2624 0x5F50 彐 (<CJK Ideograph>) 2625 0x5F54 彔 (<CJK Ideograph>) 2626 0x5F58 彘 (<CJK Ideograph>) 2627 0x5F5B 彛 (<CJK Ideograph>) 2628 0x5F60 彠 (<CJK Ideograph>) 2629 0x5F63 彣 (<CJK Ideograph>) 2630 0x5F64 彤 (<CJK Ideograph>) 2631 0x5F67 彧 (<CJK Ideograph>) 2632 0x5F6F 彯 (<CJK Ideograph>) 2633 0x5F72 彲 (<CJK Ideograph>) 2634 0x5F74 彴 (<CJK Ideograph>) 2635 0x5F75 彵 (<CJK Ideograph>) 2636 0x5F78 彸 (<CJK Ideograph>) 2637 0x5F7A 彺 (<CJK Ideograph>) 2638 0x5F7D 彽 (<CJK Ideograph>) 2639 0x5F7E 彾 (<CJK Ideograph>) 2640 0x5F89 徉 (<CJK Ideograph>) 2641 0x5F8D 徍 (<CJK Ideograph>) 2642 0x5F8F 徏 (<CJK Ideograph>) 2643 0x5F96 徖 (<CJK Ideograph>) 2644 0x5F9C 徜 (<CJK Ideograph>) 2645 0x5F9D 徝 (<CJK Ideograph>) 2646 0x5FA2 徢 (<CJK Ideograph>) 2647 0x5FA7 徧 (<CJK Ideograph>) 2648 0x5FAB 徫 (<CJK Ideograph>) 2649 0x5FA4 徤 (<CJK Ideograph>) 2650 0x5FAC 徬 (<CJK Ideograph>) 2651 0x5FAF 徯 (<CJK Ideograph>) 2652 0x5FB0 徰 (<CJK Ideograph>) 2653 0x5FB1 徱 (<CJK Ideograph>) 2654 0x5FB8 徸 (<CJK Ideograph>) 2655 0x5FC4 忄 (<CJK Ideograph>) 2656 0x5FC7 忇 (<CJK Ideograph>) 2657 0x5FC8 忈 (<CJK Ideograph>) 2658 0x5FC9 忉 (<CJK Ideograph>) 2659 0x5FCB 忋 (<CJK Ideograph>) 2660 0x5FD0 忐 (<CJK Ideograph>) 2661 0x5FD1 忑 (<CJK Ideograph>) 2662 0x5FD2 忒 (<CJK Ideograph>) 2663 0x5FD3 忓 (<CJK Ideograph>) 2664 0x5FD4 忔 (<CJK Ideograph>) 2665 0x5FDE 忞 (<CJK Ideograph>) 2666 0x5FE1 忡 (<CJK Ideograph>) 2667 0x5FE2 忢 (<CJK Ideograph>) 2668 0x5FE8 忨 (<CJK Ideograph>) 2669 0x5FE9 忩 (<CJK Ideograph>) 2670 0x5FEA 忪 (<CJK Ideograph>) 2671 0x5FEC 忬 (<CJK Ideograph>) 2672 0x5FED 忭 (<CJK Ideograph>) 2673 0x5FEE 忮 (<CJK Ideograph>) 2674 0x5FEF 忯 (<CJK Ideograph>) 2675 0x5FF2 忲 (<CJK Ideograph>) 2676 0x5FF3 忳 (<CJK Ideograph>) 2677 0x5FF6 忶 (<CJK Ideograph>) 2678 0x5FFA 忺 (<CJK Ideograph>) 2679 0x5FFC 忼 (<CJK Ideograph>) 2680 0x6007 怇 (<CJK Ideograph>) 2681 0x600A 怊 (<CJK Ideograph>) 2682 0x600D 怍 (<CJK Ideograph>) 2683 0x6013 怓 (<CJK Ideograph>) 2684 0x6014 怔 (<CJK Ideograph>) 2685 0x6017 怗 (<CJK Ideograph>) 2686 0x6018 怘 (<CJK Ideograph>) 2687 0x601A 怚 (<CJK Ideograph>) 2688 0x601F 怟 (<CJK Ideograph>) 2689 0x6024 怤 (<CJK Ideograph>) 2690 0x602D 怭 (<CJK Ideograph>) 2691 0x6033 怳 (<CJK Ideograph>) 2692 0x6035 怵 (<CJK Ideograph>) 2693 0x6040 恀 (<CJK Ideograph>) 2694 0x6047 恇 (<CJK Ideograph>) 2695 0x6048 恈 (<CJK Ideograph>) 2696 0x6049 恉 (<CJK Ideograph>) 2697 0x604C 恌 (<CJK Ideograph>) 2698 0x6051 恑 (<CJK Ideograph>) 2699 0x6054 恔 (<CJK Ideograph>) 2700 0x6056 恖 (<CJK Ideograph>) 2701 0x6057 恗 (<CJK Ideograph>) 2702 0x605D 恝 (<CJK Ideograph>) 2703 0x6061 恡 (<CJK Ideograph>) 2704 0x6067 恧 (<CJK Ideograph>) 2705 0x6071 恱 (<CJK Ideograph>) 2706 0x607E 恾 (<CJK Ideograph>) 2707 0x607F 恿 (<CJK Ideograph>) 2708 0x6082 悂 (<CJK Ideograph>) 2709 0x6086 悆 (<CJK Ideograph>) 2710 0x6088 悈 (<CJK Ideograph>) 2711 0x608A 悊 (<CJK Ideograph>) 2712 0x608E 悎 (<CJK Ideograph>) 2713 0x6091 悑 (<CJK Ideograph>) 2714 0x6093 悓 (<CJK Ideograph>) 2715 0x6095 悕 (<CJK Ideograph>) 2716 0x6098 悘 (<CJK Ideograph>) 2717 0x609D 悝 (<CJK Ideograph>) 2718 0x609E 悞 (<CJK Ideograph>) 2719 0x60A2 悢 (<CJK Ideograph>) 2720 0x60A4 悤 (<CJK Ideograph>) 2721 0x60A5 悥 (<CJK Ideograph>) 2722 0x60A8 您 (<CJK Ideograph>) 2723 0x60B0 悰 (<CJK Ideograph>) 2724 0x60B1 悱 (<CJK Ideograph>) 2725 0x60B7 悷 (<CJK Ideograph>) 2726 0x60BB 悻 (<CJK Ideograph>) 2727 0x60BE 悾 (<CJK Ideograph>) 2728 0x60C2 惂 (<CJK Ideograph>) 2729 0x60C4 惄 (<CJK Ideograph>) 2730 0x60C8 惈 (<CJK Ideograph>) 2731 0x60C9 惉 (<CJK Ideograph>) 2732 0x60CA 惊 (<CJK Ideograph>) 2733 0x60CB 惋 (<CJK Ideograph>) 2734 0x60CE 惎 (<CJK Ideograph>) 2735 0x60CF 惏 (<CJK Ideograph>) 2736 0x60D4 惔 (<CJK Ideograph>) 2737 0x60D5 惕 (<CJK Ideograph>) 2738 0x60D9 惙 (<CJK Ideograph>) 2739 0x60DB 惛 (<CJK Ideograph>) 2740 0x60DD 惝 (<CJK Ideograph>) 2741 0x60DE 惞 (<CJK Ideograph>) 2742 0x60E2 惢 (<CJK Ideograph>) 2743 0x60E5 惥 (<CJK Ideograph>) 2744 0x60F2 惲 (<CJK Ideograph>) 2745 0x60F5 惵 (<CJK Ideograph>) 2746 0x60F8 惸 (<CJK Ideograph>) 2747 0x60FC 惼 (<CJK Ideograph>) 2748 0x60FD 惽 (<CJK Ideograph>) 2749 0x6102 愂 (<CJK Ideograph>) 2750 0x6107 愇 (<CJK Ideograph>) 2751 0x610A 愊 (<CJK Ideograph>) 2752 0x610C 愌 (<CJK Ideograph>) 2753 0x6110 愐 (<CJK Ideograph>) 2754 0x6111 愑 (<CJK Ideograph>) 2755 0x6112 愒 (<CJK Ideograph>) 2756 0x6113 愓 (<CJK Ideograph>) 2757 0x6114 愔 (<CJK Ideograph>) 2758 0x6116 愖 (<CJK Ideograph>) 2759 0x6117 愗 (<CJK Ideograph>) 2760 0x6119 愙 (<CJK Ideograph>) 2761 0x611C 愜 (<CJK Ideograph>) 2762 0x611E 愞 (<CJK Ideograph>) 2763 0x6122 愢 (<CJK Ideograph>) 2764 0x612A 愪 (<CJK Ideograph>) 2765 0x612B 愫 (<CJK Ideograph>) 2766 0x6130 愰 (<CJK Ideograph>) 2767 0x6131 愱 (<CJK Ideograph>) 2768 0x6135 愵 (<CJK Ideograph>) 2769 0x6136 愶 (<CJK Ideograph>) 2770 0x6137 愷 (<CJK Ideograph>) 2771 0x6139 愹 (<CJK Ideograph>) 2772 0x6141 慁 (<CJK Ideograph>) 2773 0x6145 慅 (<CJK Ideograph>) 2774 0x6146 慆 (<CJK Ideograph>) 2775 0x6149 慉 (<CJK Ideograph>) 2776 0x615E 慞 (<CJK Ideograph>) 2777 0x6160 慠 (<CJK Ideograph>) 2778 0x616C 慬 (<CJK Ideograph>) 2779 0x6172 慲 (<CJK Ideograph>) 2780 0x6178 慸 (<CJK Ideograph>) 2781 0x617B 慻 (<CJK Ideograph>) 2782 0x617C 慼 (<CJK Ideograph>) 2783 0x617F 慿 (<CJK Ideograph>) 2784 0x6180 憀 (<CJK Ideograph>) 2785 0x6181 憁 (<CJK Ideograph>) 2786 0x6183 憃 (<CJK Ideograph>) 2787 0x6184 憄 (<CJK Ideograph>) 2788 0x618B 憋 (<CJK Ideograph>) 2789 0x618D 憍 (<CJK Ideograph>) 2790 0x6192 憒 (<CJK Ideograph>) 2791 0x6193 憓 (<CJK Ideograph>) 2792 0x6197 憗 (<CJK Ideograph>) 2793 0x6198 憘 (<CJK Ideograph>) 2794 0x619C 憜 (<CJK Ideograph>) 2795 0x619D 憝 (<CJK Ideograph>) 2796 0x619F 憟 (<CJK Ideograph>) 2797 0x61A0 憠 (<CJK Ideograph>) 2798 0x61A5 憥 (<CJK Ideograph>) 2799 0x61A8 憨 (<CJK Ideograph>) 2800 0x61AA 憪 (<CJK Ideograph>) 2801 0x61AD 憭 (<CJK Ideograph>) 2802 0x61B8 憸 (<CJK Ideograph>) 2803 0x61B9 憹 (<CJK Ideograph>) 2804 0x61BC 憼 (<CJK Ideograph>) 2805 0x61C0 懀 (<CJK Ideograph>) 2806 0x61C1 懁 (<CJK Ideograph>) 2807 0x61C2 懂 (<CJK Ideograph>) 2808 0x61CE 懎 (<CJK Ideograph>) 2809 0x61CF 懏 (<CJK Ideograph>) 2810 0x61D5 懕 (<CJK Ideograph>) 2811 0x61DC 懜 (<CJK Ideograph>) 2812 0x61DD 懝 (<CJK Ideograph>) 2813 0x61DE 懞 (<CJK Ideograph>) 2814 0x61DF 懟 (<CJK Ideograph>) 2815 0x61E1 懡 (<CJK Ideograph>) 2816 0x61E2 懢 (<CJK Ideograph>) 2817 0x61E7 懧 (<CJK Ideograph>) 2818 0x61E9 懩 (<CJK Ideograph>) 2819 0x61E5 懥 (<CJK Ideograph>) 2820 0x61EC 懬 (<CJK Ideograph>) 2821 0x61ED 懭 (<CJK Ideograph>) 2822 0x61EF 懯 (<CJK Ideograph>) 2823 0x6201 戁 (<CJK Ideograph>) 2824 0x6203 戃 (<CJK Ideograph>) 2825 0x6204 戄 (<CJK Ideograph>) 2826 0x6207 戇 (<CJK Ideograph>) 2827 0x6213 戓 (<CJK Ideograph>) 2828 0x6215 戕 (<CJK Ideograph>) 2829 0x621C 戜 (<CJK Ideograph>) 2830 0x6220 戠 (<CJK Ideograph>) 2831 0x6222 戢 (<CJK Ideograph>) 2832 0x6223 戣 (<CJK Ideograph>) 2833 0x6227 戧 (<CJK Ideograph>) 2834 0x6229 戩 (<CJK Ideograph>) 2835 0x622B 戫 (<CJK Ideograph>) 2836 0x6239 戹 (<CJK Ideograph>) 2837 0x623D 戽 (<CJK Ideograph>) 2838 0x6242 扂 (<CJK Ideograph>) 2839 0x6243 扃 (<CJK Ideograph>) 2840 0x6244 扄 (<CJK Ideograph>) 2841 0x6246 扆 (<CJK Ideograph>) 2842 0x624C 扌 (<CJK Ideograph>) 2843 0x6250 扐 (<CJK Ideograph>) 2844 0x6251 扑 (<CJK Ideograph>) 2845 0x6252 扒 (<CJK Ideograph>) 2846 0x6254 扔 (<CJK Ideograph>) 2847 0x6256 扖 (<CJK Ideograph>) 2848 0x625A 扚 (<CJK Ideograph>) 2849 0x625C 扜 (<CJK Ideograph>) 2850 0x6264 扤 (<CJK Ideograph>) 2851 0x626D 扭 (<CJK Ideograph>) 2852 0x626F 扯 (<CJK Ideograph>) 2853 0x6273 扳 (<CJK Ideograph>) 2854 0x627A 扺 (<CJK Ideograph>) 2855 0x627D 扽 (<CJK Ideograph>) 2856 0x628D 抍 (<CJK Ideograph>) 2857 0x628E 抎 (<CJK Ideograph>) 2858 0x628F 抏 (<CJK Ideograph>) 2859 0x6290 抐 (<CJK Ideograph>) 2860 0x62A6 抦 (<CJK Ideograph>) 2861 0x62A8 抨 (<CJK Ideograph>) 2862 0x62B3 抳 (<CJK Ideograph>) 2863 0x62B6 抶 (<CJK Ideograph>) 2864 0x62B7 抷 (<CJK Ideograph>) 2865 0x62BA 抺 (<CJK Ideograph>) 2866 0x62BE 抾 (<CJK Ideograph>) 2867 0x62BF 抿 (<CJK Ideograph>) 2868 0x62C4 拄 (<CJK Ideograph>) 2869 0x62CE 拎 (<CJK Ideograph>) 2870 0x62D5 拕 (<CJK Ideograph>) 2871 0x62D6 拖 (<CJK Ideograph>) 2872 0x62DA 拚 (<CJK Ideograph>) 2873 0x62EA 拪 (<CJK Ideograph>) 2874 0x62F2 拲 (<CJK Ideograph>) 2875 0x62F4 拴 (<CJK Ideograph>) 2876 0x62FC 拼 (<CJK Ideograph>) 2877 0x62FD 拽 (<CJK Ideograph>) 2878 0x6303 挃 (<CJK Ideograph>) 2879 0x6304 挄 (<CJK Ideograph>) 2880 0x630A 挊 (<CJK Ideograph>) 2881 0x630B 挋 (<CJK Ideograph>) 2882 0x630D 挍 (<CJK Ideograph>) 2883 0x6310 挐 (<CJK Ideograph>) 2884 0x6313 挓 (<CJK Ideograph>) 2885 0x6316 挖 (<CJK Ideograph>) 2886 0x6318 挘 (<CJK Ideograph>) 2887 0x6329 挩 (<CJK Ideograph>) 2888 0x632A 挪 (<CJK Ideograph>) 2889 0x632D 挭 (<CJK Ideograph>) 2890 0x6335 挵 (<CJK Ideograph>) 2891 0x6336 挶 (<CJK Ideograph>) 2892 0x6339 挹 (<CJK Ideograph>) 2893 0x633C 挼 (<CJK Ideograph>) 2894 0x6341 捁 (<CJK Ideograph>) 2895 0x6342 捂 (<CJK Ideograph>) 2896 0x6343 捃 (<CJK Ideograph>) 2897 0x6344 捄 (<CJK Ideograph>) 2898 0x6346 捆 (<CJK Ideograph>) 2899 0x634A 捊 (<CJK Ideograph>) 2900 0x634B 捋 (<CJK Ideograph>) 2901 0x634E 捎 (<CJK Ideograph>) 2902 0x6352 捒 (<CJK Ideograph>) 2903 0x6353 捓 (<CJK Ideograph>) 2904 0x6354 捔 (<CJK Ideograph>) 2905 0x6358 捘 (<CJK Ideograph>) 2906 0x635B 捛 (<CJK Ideograph>) 2907 0x6365 捥 (<CJK Ideograph>) 2908 0x6366 捦 (<CJK Ideograph>) 2909 0x636C 捬 (<CJK Ideograph>) 2910 0x636D 捭 (<CJK Ideograph>) 2911 0x6371 捱 (<CJK Ideograph>) 2912 0x6374 捴 (<CJK Ideograph>) 2913 0x6375 捵 (<CJK Ideograph>) 2914 0x6378 捸 (<CJK Ideograph>) 2915 0x637C 捼 (<CJK Ideograph>) 2916 0x637D 捽 (<CJK Ideograph>) 2917 0x637F 捿 (<CJK Ideograph>) 2918 0x6382 掂 (<CJK Ideograph>) 2919 0x6384 掄 (<CJK Ideograph>) 2920 0x6387 掇 (<CJK Ideograph>) 2921 0x638A 掊 (<CJK Ideograph>) 2922 0x6390 掐 (<CJK Ideograph>) 2923 0x6394 掔 (<CJK Ideograph>) 2924 0x6395 掕 (<CJK Ideograph>) 2925 0x6399 掙 (<CJK Ideograph>) 2926 0x639A 掚 (<CJK Ideograph>) 2927 0x639E 掞 (<CJK Ideograph>) 2928 0x63A4 掤 (<CJK Ideograph>) 2929 0x63A6 掦 (<CJK Ideograph>) 2930 0x63AD 掭 (<CJK Ideograph>) 2931 0x63AE 掮 (<CJK Ideograph>) 2932 0x63AF 掯 (<CJK Ideograph>) 2933 0x63BD 掽 (<CJK Ideograph>) 2934 0x63C1 揁 (<CJK Ideograph>) 2935 0x63C5 揅 (<CJK Ideograph>) 2936 0x63C8 揈 (<CJK Ideograph>) 2937 0x63CE 揎 (<CJK Ideograph>) 2938 0x63D1 揑 (<CJK Ideograph>) 2939 0x63D3 揓 (<CJK Ideograph>) 2940 0x63D4 揔 (<CJK Ideograph>) 2941 0x63D5 揕 (<CJK Ideograph>) 2942 0x63DC 揜 (<CJK Ideograph>) 2943 0x63E0 揠 (<CJK Ideograph>) 2944 0x63E5 揥 (<CJK Ideograph>) 2945 0x63EA 揪 (<CJK Ideograph>) 2946 0x63EC 揬 (<CJK Ideograph>) 2947 0x63F2 揲 (<CJK Ideograph>) 2948 0x63F3 揳 (<CJK Ideograph>) 2949 0x63F5 揵 (<CJK Ideograph>) 2950 0x63F8 揸 (<CJK Ideograph>) 2951 0x63F9 揹 (<CJK Ideograph>) 2952 0x6409 搉 (<CJK Ideograph>) 2953 0x640A 搊 (<CJK Ideograph>) 2954 0x6410 搐 (<CJK Ideograph>) 2955 0x6412 搒 (<CJK Ideograph>) 2956 0x6414 搔 (<CJK Ideograph>) 2957 0x6418 搘 (<CJK Ideograph>) 2958 0x641E 搞 (<CJK Ideograph>) 2959 0x6420 搠 (<CJK Ideograph>) 2960 0x6422 搢 (<CJK Ideograph>) 2961 0x6424 搤 (<CJK Ideograph>) 2962 0x6425 搥 (<CJK Ideograph>) 2963 0x6429 搩 (<CJK Ideograph>) 2964 0x642A 搪 (<CJK Ideograph>) 2965 0x642F 搯 (<CJK Ideograph>) 2966 0x6430 搰 (<CJK Ideograph>) 2967 0x6435 搵 (<CJK Ideograph>) 2968 0x643D 搽 (<CJK Ideograph>) 2969 0x643F 搿 (<CJK Ideograph>) 2970 0x644B 摋 (<CJK Ideograph>) 2971 0x644F 摏 (<CJK Ideograph>) 2972 0x6451 摑 (<CJK Ideograph>) 2973 0x6452 摒 (<CJK Ideograph>) 2974 0x6453 摓 (<CJK Ideograph>) 2975 0x6454 摔 (<CJK Ideograph>) 2976 0x645A 摚 (<CJK Ideograph>) 2977 0x645B 摛 (<CJK Ideograph>) 2978 0x645C 摜 (<CJK Ideograph>) 2979 0x645D 摝 (<CJK Ideograph>) 2980 0x645F 摟 (<CJK Ideograph>) 2981 0x6460 摠 (<CJK Ideograph>) 2982 0x6461 摡 (<CJK Ideograph>) 2983 0x6463 摣 (<CJK Ideograph>) 2984 0x646D 摭 (<CJK Ideograph>) 2985 0x6473 摳 (<CJK Ideograph>) 2986 0x6474 摴 (<CJK Ideograph>) 2987 0x647B 摻 (<CJK Ideograph>) 2988 0x647D 摽 (<CJK Ideograph>) 2989 0x6485 撅 (<CJK Ideograph>) 2990 0x6487 撇 (<CJK Ideograph>) 2991 0x648F 撏 (<CJK Ideograph>) 2992 0x6490 撐 (<CJK Ideograph>) 2993 0x6491 撑 (<CJK Ideograph>) 2994 0x6498 撘 (<CJK Ideograph>) 2995 0x6499 撙 (<CJK Ideograph>) 2996 0x649B 撛 (<CJK Ideograph>) 2997 0x649D 撝 (<CJK Ideograph>) 2998 0x649F 撟 (<CJK Ideograph>) 2999 0x64A1 撡 (<CJK Ideograph>) 3000 0x64A3 撣 (<CJK Ideograph>) 3001 0x64A6 撦 (<CJK Ideograph>) 3002 0x64A8 撨 (<CJK Ideograph>) 3003 0x64AC 撬 (<CJK Ideograph>) 3004 0x64B3 撳 (<CJK Ideograph>) 3005 0x64BD 撽 (<CJK Ideograph>) 3006 0x64BE 撾 (<CJK Ideograph>) 3007 0x64BF 撿 (<CJK Ideograph>) 3008 0x64C4 擄 (<CJK Ideograph>) 3009 0x64C9 擉 (<CJK Ideograph>) 3010 0x64CA 擊 (<CJK Ideograph>) 3011 0x64CB 擋 (<CJK Ideograph>) 3012 0x64CC 擌 (<CJK Ideograph>) 3013 0x64CE 擎 (<CJK Ideograph>) 3014 0x64D0 擐 (<CJK Ideograph>) 3015 0x64D1 擑 (<CJK Ideograph>) 3016 0x64D5 擕 (<CJK Ideograph>) 3017 0x64D7 擗 (<CJK Ideograph>) 3018 0x64E4 擤 (<CJK Ideograph>) 3019 0x64E5 擥 (<CJK Ideograph>) 3020 0x64E9 擩 (<CJK Ideograph>) 3021 0x64EA 擪 (<CJK Ideograph>) 3022 0x64ED 擭 (<CJK Ideograph>) 3023 0x64F0 擰 (<CJK Ideograph>) 3024 0x64F5 擵 (<CJK Ideograph>) 3025 0x64F7 擷 (<CJK Ideograph>) 3026 0x64FB 擻 (<CJK Ideograph>) 3027 0x64FF 擿 (<CJK Ideograph>) 3028 0x6501 攁 (<CJK Ideograph>) 3029 0x6504 攄 (<CJK Ideograph>) 3030 0x6508 攈 (<CJK Ideograph>) 3031 0x6509 攉 (<CJK Ideograph>) 3032 0x650A 攊 (<CJK Ideograph>) 3033 0x650F 攏 (<CJK Ideograph>) 3034 0x6513 攓 (<CJK Ideograph>) 3035 0x6514 攔 (<CJK Ideograph>) 3036 0x6516 攖 (<CJK Ideograph>) 3037 0x6519 攙 (<CJK Ideograph>) 3038 0x651B 攛 (<CJK Ideograph>) 3039 0x651E 攞 (<CJK Ideograph>) 3040 0x651F 攟 (<CJK Ideograph>) 3041 0x6522 攢 (<CJK Ideograph>) 3042 0x6526 攦 (<CJK Ideograph>) 3043 0x6529 攩 (<CJK Ideograph>) 3044 0x652E 攮 (<CJK Ideograph>) 3045 0x6531 攱 (<CJK Ideograph>) 3046 0x653A 攺 (<CJK Ideograph>) 3047 0x653C 攼 (<CJK Ideograph>) 3048 0x653D 攽 (<CJK Ideograph>) 3049 0x6543 敃 (<CJK Ideograph>) 3050 0x6547 敇 (<CJK Ideograph>) 3051 0x6549 敉 (<CJK Ideograph>) 3052 0x6550 敐 (<CJK Ideograph>) 3053 0x6552 敒 (<CJK Ideograph>) 3054 0x6554 敔 (<CJK Ideograph>) 3055 0x655F 敟 (<CJK Ideograph>) 3056 0x6560 敠 (<CJK Ideograph>) 3057 0x6567 敧 (<CJK Ideograph>) 3058 0x656B 敫 (<CJK Ideograph>) 3059 0x657A 敺 (<CJK Ideograph>) 3060 0x657D 敽 (<CJK Ideograph>) 3061 0x6581 斁 (<CJK Ideograph>) 3062 0x6585 斅 (<CJK Ideograph>) 3063 0x658A 斊 (<CJK Ideograph>) 3064 0x6592 斒 (<CJK Ideograph>) 3065 0x6595 斕 (<CJK Ideograph>) 3066 0x6598 斘 (<CJK Ideograph>) 3067 0x659D 斝 (<CJK Ideograph>) 3068 0x65A0 斠 (<CJK Ideograph>) 3069 0x65A3 斣 (<CJK Ideograph>) 3070 0x65A6 斦 (<CJK Ideograph>) 3071 0x65AE 斮 (<CJK Ideograph>) 3072 0x65B2 斲 (<CJK Ideograph>) 3073 0x65B3 斳 (<CJK Ideograph>) 3074 0x65B4 斴 (<CJK Ideograph>) 3075 0x65BF 斿 (<CJK Ideograph>) 3076 0x65C2 旂 (<CJK Ideograph>) 3077 0x65C8 旈 (<CJK Ideograph>) 3078 0x65C9 旉 (<CJK Ideograph>) 3079 0x65CE 旎 (<CJK Ideograph>) 3080 0x65D0 旐 (<CJK Ideograph>) 3081 0x65D4 旔 (<CJK Ideograph>) 3082 0x65D6 旖 (<CJK Ideograph>) 3083 0x65D8 旘 (<CJK Ideograph>) 3084 0x65DF 旟 (<CJK Ideograph>) 3085 0x65F0 旰 (<CJK Ideograph>) 3086 0x65F2 旲 (<CJK Ideograph>) 3087 0x65F4 旴 (<CJK Ideograph>) 3088 0x65F5 旵 (<CJK Ideograph>) 3089 0x65F9 旹 (<CJK Ideograph>) 3090 0x65FE 旾 (<CJK Ideograph>) 3091 0x65FF 旿 (<CJK Ideograph>) 3092 0x6600 昀 (<CJK Ideograph>) 3093 0x6604 昄 (<CJK Ideograph>) 3094 0x6608 昈 (<CJK Ideograph>) 3095 0x6609 昉 (<CJK Ideograph>) 3096 0x660D 昍 (<CJK Ideograph>) 3097 0x6611 昑 (<CJK Ideograph>) 3098 0x6612 昒 (<CJK Ideograph>) 3099 0x6615 昕 (<CJK Ideograph>) 3100 0x6616 昖 (<CJK Ideograph>) 3101 0x661D 昝 (<CJK Ideograph>) 3102 0x661E 昞 (<CJK Ideograph>) 3103 0x6621 昡 (<CJK Ideograph>) 3104 0x6622 昢 (<CJK Ideograph>) 3105 0x6623 昣 (<CJK Ideograph>) 3106 0x6624 昤 (<CJK Ideograph>) 3107 0x6626 昦 (<CJK Ideograph>) 3108 0x6629 昩 (<CJK Ideograph>) 3109 0x662A 昪 (<CJK Ideograph>) 3110 0x662B 昫 (<CJK Ideograph>) 3111 0x662C 昬 (<CJK Ideograph>) 3112 0x662E 昮 (<CJK Ideograph>) 3113 0x6630 昰 (<CJK Ideograph>) 3114 0x6631 昱 (<CJK Ideograph>) 3115 0x6633 昳 (<CJK Ideograph>) 3116 0x6639 昹 (<CJK Ideograph>) 3117 0x6637 昷 (<CJK Ideograph>) 3118 0x6640 晀 (<CJK Ideograph>) 3119 0x6645 晅 (<CJK Ideograph>) 3120 0x6646 晆 (<CJK Ideograph>) 3121 0x664A 晊 (<CJK Ideograph>) 3122 0x664C 晌 (<CJK Ideograph>) 3123 0x6651 晑 (<CJK Ideograph>) 3124 0x664E 晎 (<CJK Ideograph>) 3125 0x6657 晗 (<CJK Ideograph>) 3126 0x6658 晘 (<CJK Ideograph>) 3127 0x6659 晙 (<CJK Ideograph>) 3128 0x665B 晛 (<CJK Ideograph>) 3129 0x665C 晜 (<CJK Ideograph>) 3130 0x6660 晠 (<CJK Ideograph>) 3131 0x6661 晡 (<CJK Ideograph>) 3132 0x66FB 曻 (<CJK Ideograph>) 3133 0x666A 晪 (<CJK Ideograph>) 3134 0x666B 晫 (<CJK Ideograph>) 3135 0x666C 晬 (<CJK Ideograph>) 3136 0x667E 晾 (<CJK Ideograph>) 3137 0x6673 晳 (<CJK Ideograph>) 3138 0x6675 晵 (<CJK Ideograph>) 3139 0x667F 晿 (<CJK Ideograph>) 3140 0x6677 晷 (<CJK Ideograph>) 3141 0x6678 晸 (<CJK Ideograph>) 3142 0x6679 晹 (<CJK Ideograph>) 3143 0x667B 晻 (<CJK Ideograph>) 3144 0x6680 暀 (<CJK Ideograph>) 3145 0x667C 晼 (<CJK Ideograph>) 3146 0x668B 暋 (<CJK Ideograph>) 3147 0x668C 暌 (<CJK Ideograph>) 3148 0x668D 暍 (<CJK Ideograph>) 3149 0x6690 暐 (<CJK Ideograph>) 3150 0x6692 暒 (<CJK Ideograph>) 3151 0x6699 暙 (<CJK Ideograph>) 3152 0x669A 暚 (<CJK Ideograph>) 3153 0x669B 暛 (<CJK Ideograph>) 3154 0x669C 暜 (<CJK Ideograph>) 3155 0x669F 暟 (<CJK Ideograph>) 3156 0x66A0 暠 (<CJK Ideograph>) 3157 0x66A4 暤 (<CJK Ideograph>) 3158 0x66AD 暭 (<CJK Ideograph>) 3159 0x66B1 暱 (<CJK Ideograph>) 3160 0x66B2 暲 (<CJK Ideograph>) 3161 0x66B5 暵 (<CJK Ideograph>) 3162 0x66BB 暻 (<CJK Ideograph>) 3163 0x66BF 暿 (<CJK Ideograph>) 3164 0x66C0 曀 (<CJK Ideograph>) 3165 0x66C2 曂 (<CJK Ideograph>) 3166 0x66C3 曃 (<CJK Ideograph>) 3167 0x66C8 曈 (<CJK Ideograph>) 3168 0x66CC 曌 (<CJK Ideograph>) 3169 0x66CE 曎 (<CJK Ideograph>) 3170 0x66CF 曏 (<CJK Ideograph>) 3171 0x66D4 曔 (<CJK Ideograph>) 3172 0x66DB 曛 (<CJK Ideograph>) 3173 0x66DF 曟 (<CJK Ideograph>) 3174 0x66E8 曨 (<CJK Ideograph>) 3175 0x66EB 曫 (<CJK Ideograph>) 3176 0x66EC 曬 (<CJK Ideograph>) 3177 0x66EE 曮 (<CJK Ideograph>) 3178 0x66FA 曺 (<CJK Ideograph>) 3179 0x6705 朅 (<CJK Ideograph>) 3180 0x6707 朇 (<CJK Ideograph>) 3181 0x670E 朎 (<CJK Ideograph>) 3182 0x6713 朓 (<CJK Ideograph>) 3183 0x6719 朙 (<CJK Ideograph>) 3184 0x671C 朜 (<CJK Ideograph>) 3185 0x6720 朠 (<CJK Ideograph>) 3186 0x6722 朢 (<CJK Ideograph>) 3187 0x6733 朳 (<CJK Ideograph>) 3188 0x673E 朾 (<CJK Ideograph>) 3189 0x6745 杅 (<CJK Ideograph>) 3190 0x6747 杇 (<CJK Ideograph>) 3191 0x6748 杈 (<CJK Ideograph>) 3192 0x674C 杌 (<CJK Ideograph>) 3193 0x6754 杔 (<CJK Ideograph>) 3194 0x6755 杕 (<CJK Ideograph>) 3195 0x675D 杝 (<CJK Ideograph>) 3196 0x6766 杦 (<CJK Ideograph>) 3197 0x676C 杬 (<CJK Ideograph>) 3198 0x676E 杮 (<CJK Ideograph>) 3199 0x6774 杴 (<CJK Ideograph>) 3200 0x6776 杶 (<CJK Ideograph>) 3201 0x677B 杻 (<CJK Ideograph>) 3202 0x6781 极 (<CJK Ideograph>) 3203 0x6784 构 (<CJK Ideograph>) 3204 0x678E 枎 (<CJK Ideograph>) 3205 0x678F 枏 (<CJK Ideograph>) 3206 0x6791 枑 (<CJK Ideograph>) 3207 0x6793 枓 (<CJK Ideograph>) 3208 0x6796 枖 (<CJK Ideograph>) 3209 0x6798 枘 (<CJK Ideograph>) 3210 0x6799 枙 (<CJK Ideograph>) 3211 0x679B 枛 (<CJK Ideograph>) 3212 0x67B0 枰 (<CJK Ideograph>) 3213 0x67B1 枱 (<CJK Ideograph>) 3214 0x67B2 枲 (<CJK Ideograph>) 3215 0x67B5 枵 (<CJK Ideograph>) 3216 0x67BB 枻 (<CJK Ideograph>) 3217 0x67BC 枼 (<CJK Ideograph>) 3218 0x67BD 枽 (<CJK Ideograph>) 3219 0x67F9 柹 (<CJK Ideograph>) 3220 0x67C0 柀 (<CJK Ideograph>) 3221 0x67C2 柂 (<CJK Ideograph>) 3222 0x67C3 柃 (<CJK Ideograph>) 3223 0x67C5 柅 (<CJK Ideograph>) 3224 0x67C8 柈 (<CJK Ideograph>) 3225 0x67C9 柉 (<CJK Ideograph>) 3226 0x67D2 柒 (<CJK Ideograph>) 3227 0x67D7 柗 (<CJK Ideograph>) 3228 0x67D9 柙 (<CJK Ideograph>) 3229 0x67DC 柜 (<CJK Ideograph>) 3230 0x67E1 柡 (<CJK Ideograph>) 3231 0x67E6 柦 (<CJK Ideograph>) 3232 0x67F0 柰 (<CJK Ideograph>) 3233 0x67F2 柲 (<CJK Ideograph>) 3234 0x67F6 柶 (<CJK Ideograph>) 3235 0x67F7 柷 (<CJK Ideograph>) 3236 0x6852 桒 (<CJK Ideograph>) 3237 0x6814 栔 (<CJK Ideograph>) 3238 0x6819 栙 (<CJK Ideograph>) 3239 0x681D 栝 (<CJK Ideograph>) 3240 0x681F 栟 (<CJK Ideograph>) 3241 0x6828 栨 (<CJK Ideograph>) 3242 0x6827 栧 (<CJK Ideograph>) 3243 0x682C 栬 (<CJK Ideograph>) 3244 0x682D 栭 (<CJK Ideograph>) 3245 0x682F 栯 (<CJK Ideograph>) 3246 0x6830 栰 (<CJK Ideograph>) 3247 0x6831 栱 (<CJK Ideograph>) 3248 0x6833 栳 (<CJK Ideograph>) 3249 0x683B 栻 (<CJK Ideograph>) 3250 0x683F 栿 (<CJK Ideograph>) 3251 0x6844 桄 (<CJK Ideograph>) 3252 0x6845 桅 (<CJK Ideograph>) 3253 0x684A 桊 (<CJK Ideograph>) 3254 0x684C 桌 (<CJK Ideograph>) 3255 0x6855 桕 (<CJK Ideograph>) 3256 0x6857 桗 (<CJK Ideograph>) 3257 0x6858 桘 (<CJK Ideograph>) 3258 0x685B 桛 (<CJK Ideograph>) 3259 0x686B 桫 (<CJK Ideograph>) 3260 0x686E 桮 (<CJK Ideograph>) 3261 0x686F 桯 (<CJK Ideograph>) 3262 0x6870 桰 (<CJK Ideograph>) 3263 0x6871 桱 (<CJK Ideograph>) 3264 0x6872 桲 (<CJK Ideograph>) 3265 0x6875 桵 (<CJK Ideograph>) 3266 0x6879 桹 (<CJK Ideograph>) 3267 0x687A 桺 (<CJK Ideograph>) 3268 0x687B 桻 (<CJK Ideograph>) 3269 0x687C 桼 (<CJK Ideograph>) 3270 0x6882 梂 (<CJK Ideograph>) 3271 0x6884 梄 (<CJK Ideograph>) 3272 0x6886 梆 (<CJK Ideograph>) 3273 0x6888 梈 (<CJK Ideograph>) 3274 0x6896 梖 (<CJK Ideograph>) 3275 0x6898 梘 (<CJK Ideograph>) 3276 0x689A 梚 (<CJK Ideograph>) 3277 0x689C 梜 (<CJK Ideograph>) 3278 0x68A1 梡 (<CJK Ideograph>) 3279 0x68A3 梣 (<CJK Ideograph>) 3280 0x68A5 梥 (<CJK Ideograph>) 3281 0x68A9 梩 (<CJK Ideograph>) 3282 0x68AA 梪 (<CJK Ideograph>) 3283 0x68AE 梮 (<CJK Ideograph>) 3284 0x68B2 梲 (<CJK Ideograph>) 3285 0x68BB 梻 (<CJK Ideograph>) 3286 0x68C5 棅 (<CJK Ideograph>) 3287 0x68C8 棈 (<CJK Ideograph>) 3288 0x68CC 棌 (<CJK Ideograph>) 3289 0x68CF 棏 (<CJK Ideograph>) 3290 0x68D0 棐 (<CJK Ideograph>) 3291 0x68D1 棑 (<CJK Ideograph>) 3292 0x68D3 棓 (<CJK Ideograph>) 3293 0x68D6 棖 (<CJK Ideograph>) 3294 0x68D9 棙 (<CJK Ideograph>) 3295 0x68DC 棜 (<CJK Ideograph>) 3296 0x68DD 棝 (<CJK Ideograph>) 3297 0x68E5 棥 (<CJK Ideograph>) 3298 0x68E8 棨 (<CJK Ideograph>) 3299 0x68EA 棪 (<CJK Ideograph>) 3300 0x68EB 棫 (<CJK Ideograph>) 3301 0x68EC 棬 (<CJK Ideograph>) 3302 0x68ED 棭 (<CJK Ideograph>) 3303 0x68F0 棰 (<CJK Ideograph>) 3304 0x68F1 棱 (<CJK Ideograph>) 3305 0x68F5 棵 (<CJK Ideograph>) 3306 0x68F6 棶 (<CJK Ideograph>) 3307 0x68FB 棻 (<CJK Ideograph>) 3308 0x68FC 棼 (<CJK Ideograph>) 3309 0x68FD 棽 (<CJK Ideograph>) 3310 0x6906 椆 (<CJK Ideograph>) 3311 0x6909 椉 (<CJK Ideograph>) 3312 0x690A 椊 (<CJK Ideograph>) 3313 0x6910 椐 (<CJK Ideograph>) 3314 0x6911 椑 (<CJK Ideograph>) 3315 0x6913 椓 (<CJK Ideograph>) 3316 0x6916 椖 (<CJK Ideograph>) 3317 0x6917 椗 (<CJK Ideograph>) 3318 0x6931 椱 (<CJK Ideograph>) 3319 0x6933 椳 (<CJK Ideograph>) 3320 0x6935 椵 (<CJK Ideograph>) 3321 0x6938 椸 (<CJK Ideograph>) 3322 0x693B 椻 (<CJK Ideograph>) 3323 0x6942 楂 (<CJK Ideograph>) 3324 0x6945 楅 (<CJK Ideograph>) 3325 0x6949 楉 (<CJK Ideograph>) 3326 0x694E 楎 (<CJK Ideograph>) 3327 0x6957 楗 (<CJK Ideograph>) 3328 0x695B 楛 (<CJK Ideograph>) 3329 0x6963 楣 (<CJK Ideograph>) 3330 0x6964 楤 (<CJK Ideograph>) 3331 0x6965 楥 (<CJK Ideograph>) 3332 0x6966 楦 (<CJK Ideograph>) 3333 0x6968 楨 (<CJK Ideograph>) 3334 0x6969 楩 (<CJK Ideograph>) 3335 0x696C 楬 (<CJK Ideograph>) 3336 0x6970 楰 (<CJK Ideograph>) 3337 0x6971 楱 (<CJK Ideograph>) 3338 0x6972 楲 (<CJK Ideograph>) 3339 0x697A 楺 (<CJK Ideograph>) 3340 0x697B 楻 (<CJK Ideograph>) 3341 0x697F 楿 (<CJK Ideograph>) 3342 0x6980 榀 (<CJK Ideograph>) 3343 0x698D 榍 (<CJK Ideograph>) 3344 0x6992 榒 (<CJK Ideograph>) 3345 0x6996 榖 (<CJK Ideograph>) 3346 0x6998 榘 (<CJK Ideograph>) 3347 0x69A1 榡 (<CJK Ideograph>) 3348 0x69A5 榥 (<CJK Ideograph>) 3349 0x69A6 榦 (<CJK Ideograph>) 3350 0x69A8 榨 (<CJK Ideograph>) 3351 0x69AB 榫 (<CJK Ideograph>) 3352 0x69AD 榭 (<CJK Ideograph>) 3353 0x69AF 榯 (<CJK Ideograph>) 3354 0x69B7 榷 (<CJK Ideograph>) 3355 0x69B8 榸 (<CJK Ideograph>) 3356 0x69BA 榺 (<CJK Ideograph>) 3357 0x69BC 榼 (<CJK Ideograph>) 3358 0x69C5 槅 (<CJK Ideograph>) 3359 0x69C8 槈 (<CJK Ideograph>) 3360 0x69D1 槑 (<CJK Ideograph>) 3361 0x69D6 槖 (<CJK Ideograph>) 3362 0x69D7 槗 (<CJK Ideograph>) 3363 0x69E2 槢 (<CJK Ideograph>) 3364 0x69E5 槥 (<CJK Ideograph>) 3365 0x69EE 槮 (<CJK Ideograph>) 3366 0x69EF 槯 (<CJK Ideograph>) 3367 0x69F1 槱 (<CJK Ideograph>) 3368 0x69F3 槳 (<CJK Ideograph>) 3369 0x69F5 槵 (<CJK Ideograph>) 3370 0x69FE 槾 (<CJK Ideograph>) 3371 0x6A00 樀 (<CJK Ideograph>) 3372 0x6A01 樁 (<CJK Ideograph>) 3373 0x6A03 樃 (<CJK Ideograph>) 3374 0x6A0F 樏 (<CJK Ideograph>) 3375 0x6A11 樑 (<CJK Ideograph>) 3376 0x6A15 樕 (<CJK Ideograph>) 3377 0x6A1A 樚 (<CJK Ideograph>) 3378 0x6A1D 樝 (<CJK Ideograph>) 3379 0x6A20 樠 (<CJK Ideograph>) 3380 0x6A24 樤 (<CJK Ideograph>) 3381 0x6A28 樨 (<CJK Ideograph>) 3382 0x6A30 樰 (<CJK Ideograph>) 3383 0x6A32 樲 (<CJK Ideograph>) 3384 0x6A34 樴 (<CJK Ideograph>) 3385 0x6A37 樷 (<CJK Ideograph>) 3386 0x6A3B 樻 (<CJK Ideograph>) 3387 0x6A3E 樾 (<CJK Ideograph>) 3388 0x6A3F 樿 (<CJK Ideograph>) 3389 0x6A45 橅 (<CJK Ideograph>) 3390 0x6A46 橆 (<CJK Ideograph>) 3391 0x6A49 橉 (<CJK Ideograph>) 3392 0x6A4A 橊 (<CJK Ideograph>) 3393 0x6A4E 橎 (<CJK Ideograph>) 3394 0x6A50 橐 (<CJK Ideograph>) 3395 0x6A51 橑 (<CJK Ideograph>) 3396 0x6A52 橒 (<CJK Ideograph>) 3397 0x6A55 橕 (<CJK Ideograph>) 3398 0x6A56 橖 (<CJK Ideograph>) 3399 0x6A5B 橛 (<CJK Ideograph>) 3400 0x6A64 橤 (<CJK Ideograph>) 3401 0x6A67 橧 (<CJK Ideograph>) 3402 0x6A6A 橪 (<CJK Ideograph>) 3403 0x6A71 橱 (<CJK Ideograph>) 3404 0x6A73 橳 (<CJK Ideograph>) 3405 0x6A7E 橾 (<CJK Ideograph>) 3406 0x6A81 檁 (<CJK Ideograph>) 3407 0x6A83 檃 (<CJK Ideograph>) 3408 0x6A86 檆 (<CJK Ideograph>) 3409 0x6A87 檇 (<CJK Ideograph>) 3410 0x6A89 檉 (<CJK Ideograph>) 3411 0x6A8B 檋 (<CJK Ideograph>) 3412 0x6A91 檑 (<CJK Ideograph>) 3413 0x6A9B 檛 (<CJK Ideograph>) 3414 0x6A9D 檝 (<CJK Ideograph>) 3415 0x6A9E 檞 (<CJK Ideograph>) 3416 0x6A9F 檟 (<CJK Ideograph>) 3417 0x6AA5 檥 (<CJK Ideograph>) 3418 0x6AAB 檫 (<CJK Ideograph>) 3419 0x6AAF 檯 (<CJK Ideograph>) 3420 0x6AB0 檰 (<CJK Ideograph>) 3421 0x6AB1 檱 (<CJK Ideograph>) 3422 0x6AB4 檴 (<CJK Ideograph>) 3423 0x6ABD 檽 (<CJK Ideograph>) 3424 0x6ABE 檾 (<CJK Ideograph>) 3425 0x6ABF 檿 (<CJK Ideograph>) 3426 0x6AC6 櫆 (<CJK Ideograph>) 3427 0x6AC9 櫉 (<CJK Ideograph>) 3428 0x6AC8 櫈 (<CJK Ideograph>) 3429 0x6ACC 櫌 (<CJK Ideograph>) 3430 0x6AD0 櫐 (<CJK Ideograph>) 3431 0x6AD4 櫔 (<CJK Ideograph>) 3432 0x6AD5 櫕 (<CJK Ideograph>) 3433 0x6AD6 櫖 (<CJK Ideograph>) 3434 0x6ADC 櫜 (<CJK Ideograph>) 3435 0x6ADD 櫝 (<CJK Ideograph>) 3436 0x6AE4 櫤 (<CJK Ideograph>) 3437 0x6AE7 櫧 (<CJK Ideograph>) 3438 0x6AEC 櫬 (<CJK Ideograph>) 3439 0x6AF0 櫰 (<CJK Ideograph>) 3440 0x6AF1 櫱 (<CJK Ideograph>) 3441 0x6AF2 櫲 (<CJK Ideograph>) 3442 0x6AFC 櫼 (<CJK Ideograph>) 3443 0x6AFD 櫽 (<CJK Ideograph>) 3444 0x6B02 欂 (<CJK Ideograph>) 3445 0x6B03 欃 (<CJK Ideograph>) 3446 0x6B06 欆 (<CJK Ideograph>) 3447 0x6B07 欇 (<CJK Ideograph>) 3448 0x6B09 欉 (<CJK Ideograph>) 3449 0x6B0F 欏 (<CJK Ideograph>) 3450 0x6B10 欐 (<CJK Ideograph>) 3451 0x6B11 欑 (<CJK Ideograph>) 3452 0x6B17 欗 (<CJK Ideograph>) 3453 0x6B1B 欛 (<CJK Ideograph>) 3454 0x6B1E 欞 (<CJK Ideograph>) 3455 0x6B24 欤 (<CJK Ideograph>) 3456 0x6B28 欨 (<CJK Ideograph>) 3457 0x6B2B 欫 (<CJK Ideograph>) 3458 0x6B2C 欬 (<CJK Ideograph>) 3459 0x6B2F 欯 (<CJK Ideograph>) 3460 0x6B35 欵 (<CJK Ideograph>) 3461 0x6B36 欶 (<CJK Ideograph>) 3462 0x6B3B 欻 (<CJK Ideograph>) 3463 0x6B3F 欿 (<CJK Ideograph>) 3464 0x6B46 歆 (<CJK Ideograph>) 3465 0x6B4A 歊 (<CJK Ideograph>) 3466 0x6B4D 歍 (<CJK Ideograph>) 3467 0x6B52 歒 (<CJK Ideograph>) 3468 0x6B56 歖 (<CJK Ideograph>) 3469 0x6B58 歘 (<CJK Ideograph>) 3470 0x6B5D 歝 (<CJK Ideograph>) 3471 0x6B60 歠 (<CJK Ideograph>) 3472 0x6B67 歧 (<CJK Ideograph>) 3473 0x6B6B 歫 (<CJK Ideograph>) 3474 0x6B6E 歮 (<CJK Ideograph>) 3475 0x6B70 歰 (<CJK Ideograph>) 3476 0x6B75 歵 (<CJK Ideograph>) 3477 0x6B7D 歽 (<CJK Ideograph>) 3478 0x6B7E 歾 (<CJK Ideograph>) 3479 0x6B82 殂 (<CJK Ideograph>) 3480 0x6B85 殅 (<CJK Ideograph>) 3481 0x6B97 殗 (<CJK Ideograph>) 3482 0x6B9B 殛 (<CJK Ideograph>) 3483 0x6B9F 殟 (<CJK Ideograph>) 3484 0x6BA0 殠 (<CJK Ideograph>) 3485 0x6BA2 殢 (<CJK Ideograph>) 3486 0x6BA3 殣 (<CJK Ideograph>) 3487 0x6BA8 殨 (<CJK Ideograph>) 3488 0x6BA9 殩 (<CJK Ideograph>) 3489 0x6BAC 殬 (<CJK Ideograph>) 3490 0x6BAD 殭 (<CJK Ideograph>) 3491 0x6BAE 殮 (<CJK Ideograph>) 3492 0x6BB0 殰 (<CJK Ideograph>) 3493 0x6BB8 殸 (<CJK Ideograph>) 3494 0x6BB9 殹 (<CJK Ideograph>) 3495 0x6BBD 殽 (<CJK Ideograph>) 3496 0x6BBE 殾 (<CJK Ideograph>) 3497 0x6BC3 毃 (<CJK Ideograph>) 3498 0x6BC4 毄 (<CJK Ideograph>) 3499 0x6BC9 毉 (<CJK Ideograph>) 3500 0x6BCC 毌 (<CJK Ideograph>) 3501 0x6BD6 毖 (<CJK Ideograph>) 3502 0x6BDA 毚 (<CJK Ideograph>) 3503 0x6BE1 毡 (<CJK Ideograph>) 3504 0x6BE3 毣 (<CJK Ideograph>) 3505 0x6BE6 毦 (<CJK Ideograph>) 3506 0x6BE7 毧 (<CJK Ideograph>) 3507 0x6BEE 毮 (<CJK Ideograph>) 3508 0x6BF1 毱 (<CJK Ideograph>) 3509 0x6BF7 毷 (<CJK Ideograph>) 3510 0x6BF9 毹 (<CJK Ideograph>) 3511 0x6BFF 毿 (<CJK Ideograph>) 3512 0x6C02 氂 (<CJK Ideograph>) 3513 0x6C04 氄 (<CJK Ideograph>) 3514 0x6C05 氅 (<CJK Ideograph>) 3515 0x6C09 氉 (<CJK Ideograph>) 3516 0x6C0D 氍 (<CJK Ideograph>) 3517 0x6C0E 氎 (<CJK Ideograph>) 3518 0x6C10 氐 (<CJK Ideograph>) 3519 0x6C12 氒 (<CJK Ideograph>) 3520 0x6C19 氙 (<CJK Ideograph>) 3521 0x6C1F 氟 (<CJK Ideograph>) 3522 0x6C26 氦 (<CJK Ideograph>) 3523 0x6C27 氧 (<CJK Ideograph>) 3524 0x6C28 氨 (<CJK Ideograph>) 3525 0x6C2C 氬 (<CJK Ideograph>) 3526 0x6C2E 氮 (<CJK Ideograph>) 3527 0x6C33 氳 (<CJK Ideograph>) 3528 0x6C35 氵 (<CJK Ideograph>) 3529 0x6C36 氶 (<CJK Ideograph>) 3530 0x6C3A 氺 (<CJK Ideograph>) 3531 0x6C3B 氻 (<CJK Ideograph>) 3532 0x6C3F 氿 (<CJK Ideograph>) 3533 0x6C4A 汊 (<CJK Ideograph>) 3534 0x6C4B 汋 (<CJK Ideograph>) 3535 0x6C4D 汍 (<CJK Ideograph>) 3536 0x6C4F 汏 (<CJK Ideograph>) 3537 0x6C52 汒 (<CJK Ideograph>) 3538 0x6C54 汔 (<CJK Ideograph>) 3539 0x6C59 汙 (<CJK Ideograph>) 3540 0x6C5B 汛 (<CJK Ideograph>) 3541 0x6C5C 汜 (<CJK Ideograph>) 3542 0x6C6B 汫 (<CJK Ideograph>) 3543 0x6C6D 汭 (<CJK Ideograph>) 3544 0x6C6F 汯 (<CJK Ideograph>) 3545 0x6C74 汴 (<CJK Ideograph>) 3546 0x6C76 汶 (<CJK Ideograph>) 3547 0x6C78 汸 (<CJK Ideograph>) 3548 0x6C79 汹 (<CJK Ideograph>) 3549 0x6C7B 汻 (<CJK Ideograph>) 3550 0x6C85 沅 (<CJK Ideograph>) 3551 0x6C86 沆 (<CJK Ideograph>) 3552 0x6C87 沇 (<CJK Ideograph>) 3553 0x6C89 沉 (<CJK Ideograph>) 3554 0x6C94 沔 (<CJK Ideograph>) 3555 0x6C95 沕 (<CJK Ideograph>) 3556 0x6C97 沗 (<CJK Ideograph>) 3557 0x6C98 沘 (<CJK Ideograph>) 3558 0x6C9C 沜 (<CJK Ideograph>) 3559 0x6C9F 沟 (<CJK Ideograph>) 3560 0x6CB0 沰 (<CJK Ideograph>) 3561 0x6CB2 沲 (<CJK Ideograph>) 3562 0x6CB4 沴 (<CJK Ideograph>) 3563 0x6CC2 泂 (<CJK Ideograph>) 3564 0x6CC6 泆 (<CJK Ideograph>) 3565 0x6CCD 泍 (<CJK Ideograph>) 3566 0x6CCF 泏 (<CJK Ideograph>) 3567 0x6CD0 泐 (<CJK Ideograph>) 3568 0x6CD1 泑 (<CJK Ideograph>) 3569 0x6CD2 泒 (<CJK Ideograph>) 3570 0x6CD4 泔 (<CJK Ideograph>) 3571 0x6CD6 泖 (<CJK Ideograph>) 3572 0x6CDA 泚 (<CJK Ideograph>) 3573 0x6CDC 泜 (<CJK Ideograph>) 3574 0x6CE0 泠 (<CJK Ideograph>) 3575 0x6CE7 泧 (<CJK Ideograph>) 3576 0x6CE9 泩 (<CJK Ideograph>) 3577 0x6CEB 泫 (<CJK Ideograph>) 3578 0x6CEC 泬 (<CJK Ideograph>) 3579 0x6CEE 泮 (<CJK Ideograph>) 3580 0x6CF2 泲 (<CJK Ideograph>) 3581 0x6CF4 泴 (<CJK Ideograph>) 3582 0x6D04 洄 (<CJK Ideograph>) 3583 0x6D07 洇 (<CJK Ideograph>) 3584 0x6D0A 洊 (<CJK Ideograph>) 3585 0x6D0E 洎 (<CJK Ideograph>) 3586 0x6D0F 洏 (<CJK Ideograph>) 3587 0x6D11 洑 (<CJK Ideograph>) 3588 0x6D13 洓 (<CJK Ideograph>) 3589 0x6D1A 洚 (<CJK Ideograph>) 3590 0x6D26 洦 (<CJK Ideograph>) 3591 0x6D27 洧 (<CJK Ideograph>) 3592 0x6D28 洨 (<CJK Ideograph>) 3593 0x6C67 汧 (<CJK Ideograph>) 3594 0x6D2E 洮 (<CJK Ideograph>) 3595 0x6D2F 洯 (<CJK Ideograph>) 3596 0x6D31 洱 (<CJK Ideograph>) 3597 0x6D39 洹 (<CJK Ideograph>) 3598 0x6D3C 洼 (<CJK Ideograph>) 3599 0x6D3F 洿 (<CJK Ideograph>) 3600 0x6D57 浗 (<CJK Ideograph>) 3601 0x6D5E 浞 (<CJK Ideograph>) 3602 0x6D5F 浟 (<CJK Ideograph>) 3603 0x6D61 浡 (<CJK Ideograph>) 3604 0x6D65 浥 (<CJK Ideograph>) 3605 0x6D67 浧 (<CJK Ideograph>) 3606 0x6D6F 浯 (<CJK Ideograph>) 3607 0x6D70 浰 (<CJK Ideograph>) 3608 0x6D7C 浼 (<CJK Ideograph>) 3609 0x6D82 涂 (<CJK Ideograph>) 3610 0x6D87 涇 (<CJK Ideograph>) 3611 0x6D91 涑 (<CJK Ideograph>) 3612 0x6D92 涒 (<CJK Ideograph>) 3613 0x6D94 涔 (<CJK Ideograph>) 3614 0x6D96 涖 (<CJK Ideograph>) 3615 0x6D97 涗 (<CJK Ideograph>) 3616 0x6D98 涘 (<CJK Ideograph>) 3617 0x6DAA 涪 (<CJK Ideograph>) 3618 0x6DAC 涬 (<CJK Ideograph>) 3619 0x6DB4 涴 (<CJK Ideograph>) 3620 0x6DB7 涷 (<CJK Ideograph>) 3621 0x6DB9 涹 (<CJK Ideograph>) 3622 0x6DBD 涽 (<CJK Ideograph>) 3623 0x6DBF 涿 (<CJK Ideograph>) 3624 0x6DC4 淄 (<CJK Ideograph>) 3625 0x6DC8 淈 (<CJK Ideograph>) 3626 0x6DCA 淊 (<CJK Ideograph>) 3627 0x6DCE 淎 (<CJK Ideograph>) 3628 0x6DCF 淏 (<CJK Ideograph>) 3629 0x6DD6 淖 (<CJK Ideograph>) 3630 0x6DDB 淛 (<CJK Ideograph>) 3631 0x6DDD 淝 (<CJK Ideograph>) 3632 0x6DDF 淟 (<CJK Ideograph>) 3633 0x6DE0 淠 (<CJK Ideograph>) 3634 0x6DE2 淢 (<CJK Ideograph>) 3635 0x6DE5 淥 (<CJK Ideograph>) 3636 0x6DE9 淩 (<CJK Ideograph>) 3637 0x6DEF 淯 (<CJK Ideograph>) 3638 0x6DF0 淰 (<CJK Ideograph>) 3639 0x6DF4 淴 (<CJK Ideograph>) 3640 0x6DF6 淶 (<CJK Ideograph>) 3641 0x6DFC 淼 (<CJK Ideograph>) 3642 0x6E00 渀 (<CJK Ideograph>) 3643 0x6E04 渄 (<CJK Ideograph>) 3644 0x6E1E 渞 (<CJK Ideograph>) 3645 0x6E22 渢 (<CJK Ideograph>) 3646 0x6E27 渧 (<CJK Ideograph>) 3647 0x6E32 渲 (<CJK Ideograph>) 3648 0x6E36 渶 (<CJK Ideograph>) 3649 0x6E39 渹 (<CJK Ideograph>) 3650 0x6E3B 渻 (<CJK Ideograph>) 3651 0x6E3C 渼 (<CJK Ideograph>) 3652 0x6E44 湄 (<CJK Ideograph>) 3653 0x6E45 湅 (<CJK Ideograph>) 3654 0x6E48 湈 (<CJK Ideograph>) 3655 0x6E49 湉 (<CJK Ideograph>) 3656 0x6E4B 湋 (<CJK Ideograph>) 3657 0x6E4F 湏 (<CJK Ideograph>) 3658 0x6E51 湑 (<CJK Ideograph>) 3659 0x6E52 湒 (<CJK Ideograph>) 3660 0x6E53 湓 (<CJK Ideograph>) 3661 0x6E54 湔 (<CJK Ideograph>) 3662 0x6E57 湗 (<CJK Ideograph>) 3663 0x6E5C 湜 (<CJK Ideograph>) 3664 0x6E5D 湝 (<CJK Ideograph>) 3665 0x6E5E 湞 (<CJK Ideograph>) 3666 0x6E62 湢 (<CJK Ideograph>) 3667 0x6E63 湣 (<CJK Ideograph>) 3668 0x6E68 湨 (<CJK Ideograph>) 3669 0x6E73 湳 (<CJK Ideograph>) 3670 0x6E7B 湻 (<CJK Ideograph>) 3671 0x6E7D 湽 (<CJK Ideograph>) 3672 0x6E8D 溍 (<CJK Ideograph>) 3673 0x6E93 溓 (<CJK Ideograph>) 3674 0x6E99 溙 (<CJK Ideograph>) 3675 0x6EA0 溠 (<CJK Ideograph>) 3676 0x6EA7 溧 (<CJK Ideograph>) 3677 0x6EAD 溭 (<CJK Ideograph>) 3678 0x6EAE 溮 (<CJK Ideograph>) 3679 0x6EB1 溱 (<CJK Ideograph>) 3680 0x6EB3 溳 (<CJK Ideograph>) 3681 0x6EBB 溻 (<CJK Ideograph>) 3682 0x6EBF 溿 (<CJK Ideograph>) 3683 0x6EC0 滀 (<CJK Ideograph>) 3684 0x6EC1 滁 (<CJK Ideograph>) 3685 0x6EC3 滃 (<CJK Ideograph>) 3686 0x6EC7 滇 (<CJK Ideograph>) 3687 0x6EC8 滈 (<CJK Ideograph>) 3688 0x6ECA 滊 (<CJK Ideograph>) 3689 0x6ECD 滍 (<CJK Ideograph>) 3690 0x6ECE 滎 (<CJK Ideograph>) 3691 0x6ECF 滏 (<CJK Ideograph>) 3692 0x6EEB 滫 (<CJK Ideograph>) 3693 0x6EED 滭 (<CJK Ideograph>) 3694 0x6EEE 滮 (<CJK Ideograph>) 3695 0x6EF9 滹 (<CJK Ideograph>) 3696 0x6EFB 滻 (<CJK Ideograph>) 3697 0x6EFD 滽 (<CJK Ideograph>) 3698 0x6F04 漄 (<CJK Ideograph>) 3699 0x6F08 漈 (<CJK Ideograph>) 3700 0x6F0A 漊 (<CJK Ideograph>) 3701 0x6F0C 漌 (<CJK Ideograph>) 3702 0x6F0D 漍 (<CJK Ideograph>) 3703 0x6F16 漖 (<CJK Ideograph>) 3704 0x6F18 漘 (<CJK Ideograph>) 3705 0x6F1A 漚 (<CJK Ideograph>) 3706 0x6F1B 漛 (<CJK Ideograph>) 3707 0x6F26 漦 (<CJK Ideograph>) 3708 0x6F29 漩 (<CJK Ideograph>) 3709 0x6F2A 漪 (<CJK Ideograph>) 3710 0x6F2F 漯 (<CJK Ideograph>) 3711 0x6F30 漰 (<CJK Ideograph>) 3712 0x6F33 漳 (<CJK Ideograph>) 3713 0x6F36 漶 (<CJK Ideograph>) 3714 0x6F3B 漻 (<CJK Ideograph>) 3715 0x6F3C 漼 (<CJK Ideograph>) 3716 0x6F2D 漭 (<CJK Ideograph>) 3717 0x6F4F 潏 (<CJK Ideograph>) 3718 0x6F51 潑 (<CJK Ideograph>) 3719 0x6F52 潒 (<CJK Ideograph>) 3720 0x6F53 潓 (<CJK Ideograph>) 3721 0x6F57 潗 (<CJK Ideograph>) 3722 0x6F59 潙 (<CJK Ideograph>) 3723 0x6F5A 潚 (<CJK Ideograph>) 3724 0x6F5D 潝 (<CJK Ideograph>) 3725 0x6F5E 潞 (<CJK Ideograph>) 3726 0x6F61 潡 (<CJK Ideograph>) 3727 0x6F62 潢 (<CJK Ideograph>) 3728 0x6F68 潨 (<CJK Ideograph>) 3729 0x6F6C 潬 (<CJK Ideograph>) 3730 0x6F7D 潽 (<CJK Ideograph>) 3731 0x6F7E 潾 (<CJK Ideograph>) 3732 0x6F83 澃 (<CJK Ideograph>) 3733 0x6F87 澇 (<CJK Ideograph>) 3734 0x6F88 澈 (<CJK Ideograph>) 3735 0x6F8B 澋 (<CJK Ideograph>) 3736 0x6F8C 澌 (<CJK Ideograph>) 3737 0x6F8D 澍 (<CJK Ideograph>) 3738 0x6F90 澐 (<CJK Ideograph>) 3739 0x6F92 澒 (<CJK Ideograph>) 3740 0x6F93 澓 (<CJK Ideograph>) 3741 0x6F94 澔 (<CJK Ideograph>) 3742 0x6F96 澖 (<CJK Ideograph>) 3743 0x6F9A 澚 (<CJK Ideograph>) 3744 0x6F9F 澟 (<CJK Ideograph>) 3745 0x6FA0 澠 (<CJK Ideograph>) 3746 0x6FA5 澥 (<CJK Ideograph>) 3747 0x6FA6 澦 (<CJK Ideograph>) 3748 0x6FA7 澧 (<CJK Ideograph>) 3749 0x6FA8 澨 (<CJK Ideograph>) 3750 0x6FAE 澮 (<CJK Ideograph>) 3751 0x6FAF 澯 (<CJK Ideograph>) 3752 0x6FB0 澰 (<CJK Ideograph>) 3753 0x6FB5 澵 (<CJK Ideograph>) 3754 0x6FB6 澶 (<CJK Ideograph>) 3755 0x6FBC 澼 (<CJK Ideograph>) 3756 0x6FC5 濅 (<CJK Ideograph>) 3757 0x6FC7 濇 (<CJK Ideograph>) 3758 0x6FC8 濈 (<CJK Ideograph>) 3759 0x6FCA 濊 (<CJK Ideograph>) 3760 0x6FDA 濚 (<CJK Ideograph>) 3761 0x6FDE 濞 (<CJK Ideograph>) 3762 0x6FE8 濨 (<CJK Ideograph>) 3763 0x6FE9 濩 (<CJK Ideograph>) 3764 0x6FF0 濰 (<CJK Ideograph>) 3765 0x6FF5 濵 (<CJK Ideograph>) 3766 0x6FF9 濹 (<CJK Ideograph>) 3767 0x6FFC 濼 (<CJK Ideograph>) 3768 0x6FFD 濽 (<CJK Ideograph>) 3769 0x7000 瀀 (<CJK Ideograph>) 3770 0x7005 瀅 (<CJK Ideograph>) 3771 0x7006 瀆 (<CJK Ideograph>) 3772 0x7007 瀇 (<CJK Ideograph>) 3773 0x700D 瀍 (<CJK Ideograph>) 3774 0x7017 瀗 (<CJK Ideograph>) 3775 0x7020 瀠 (<CJK Ideograph>) 3776 0x7023 瀣 (<CJK Ideograph>) 3777 0x702F 瀯 (<CJK Ideograph>) 3778 0x7034 瀴 (<CJK Ideograph>) 3779 0x7037 瀷 (<CJK Ideograph>) 3780 0x7039 瀹 (<CJK Ideograph>) 3781 0x703C 瀼 (<CJK Ideograph>) 3782 0x7043 灃 (<CJK Ideograph>) 3783 0x7044 灄 (<CJK Ideograph>) 3784 0x7048 灈 (<CJK Ideograph>) 3785 0x7049 灉 (<CJK Ideograph>) 3786 0x704A 灊 (<CJK Ideograph>) 3787 0x704B 灋 (<CJK Ideograph>) 3788 0x7054 灔 (<CJK Ideograph>) 3789 0x7055 灕 (<CJK Ideograph>) 3790 0x705D 灝 (<CJK Ideograph>) 3791 0x705E 灞 (<CJK Ideograph>) 3792 0x704E 灎 (<CJK Ideograph>) 3793 0x7064 灤 (<CJK Ideograph>) 3794 0x7065 灥 (<CJK Ideograph>) 3795 0x706C 灬 (<CJK Ideograph>) 3796 0x706E 灮 (<CJK Ideograph>) 3797 0x7075 灵 (<CJK Ideograph>) 3798 0x7076 灶 (<CJK Ideograph>) 3799 0x707E 灾 (<CJK Ideograph>) 3800 0x7081 炁 (<CJK Ideograph>) 3801 0x7085 炅 (<CJK Ideograph>) 3802 0x7086 炆 (<CJK Ideograph>) 3803 0x7094 炔 (<CJK Ideograph>) 3804 0x7095 炕 (<CJK Ideograph>) 3805 0x7096 炖 (<CJK Ideograph>) 3806 0x7097 炗 (<CJK Ideograph>) 3807 0x7098 炘 (<CJK Ideograph>) 3808 0x709B 炛 (<CJK Ideograph>) 3809 0x70A4 炤 (<CJK Ideograph>) 3810 0x70AB 炫 (<CJK Ideograph>) 3811 0x70B0 炰 (<CJK Ideograph>) 3812 0x70B1 炱 (<CJK Ideograph>) 3813 0x70B4 炴 (<CJK Ideograph>) 3814 0x70B7 炷 (<CJK Ideograph>) 3815 0x70CA 烊 (<CJK Ideograph>) 3816 0x70D1 烑 (<CJK Ideograph>) 3817 0x70D3 烓 (<CJK Ideograph>) 3818 0x70D4 烔 (<CJK Ideograph>) 3819 0x70D5 烕 (<CJK Ideograph>) 3820 0x70D6 烖 (<CJK Ideograph>) 3821 0x70D8 烘 (<CJK Ideograph>) 3822 0x70DC 烜 (<CJK Ideograph>) 3823 0x70E4 烤 (<CJK Ideograph>) 3824 0x70FA 烺 (<CJK Ideograph>) 3825 0x7103 焃 (<CJK Ideograph>) 3826 0x7104 焄 (<CJK Ideograph>) 3827 0x7105 焅 (<CJK Ideograph>) 3828 0x7106 焆 (<CJK Ideograph>) 3829 0x7107 焇 (<CJK Ideograph>) 3830 0x710B 焋 (<CJK Ideograph>) 3831 0x710C 焌 (<CJK Ideograph>) 3832 0x710F 焏 (<CJK Ideograph>) 3833 0x711E 焞 (<CJK Ideograph>) 3834 0x7120 焠 (<CJK Ideograph>) 3835 0x712B 焫 (<CJK Ideograph>) 3836 0x712D 焭 (<CJK Ideograph>) 3837 0x712F 焯 (<CJK Ideograph>) 3838 0x7130 焰 (<CJK Ideograph>) 3839 0x7131 焱 (<CJK Ideograph>) 3840 0x7138 焸 (<CJK Ideograph>) 3841 0x7141 煁 (<CJK Ideograph>) 3842 0x7145 煅 (<CJK Ideograph>) 3843 0x7146 煆 (<CJK Ideograph>) 3844 0x7147 煇 (<CJK Ideograph>) 3845 0x714A 煊 (<CJK Ideograph>) 3846 0x714B 煋 (<CJK Ideograph>) 3847 0x7150 煐 (<CJK Ideograph>) 3848 0x7152 煒 (<CJK Ideograph>) 3849 0x7157 煗 (<CJK Ideograph>) 3850 0x715A 煚 (<CJK Ideograph>) 3851 0x715C 煜 (<CJK Ideograph>) 3852 0x715E 煞 (<CJK Ideograph>) 3853 0x7160 煠 (<CJK Ideograph>) 3854 0x7168 煨 (<CJK Ideograph>) 3855 0x7179 煹 (<CJK Ideograph>) 3856 0x7180 熀 (<CJK Ideograph>) 3857 0x7185 熅 (<CJK Ideograph>) 3858 0x7187 熇 (<CJK Ideograph>) 3859 0x718C 熌 (<CJK Ideograph>) 3860 0x7192 熒 (<CJK Ideograph>) 3861 0x719A 熚 (<CJK Ideograph>) 3862 0x719B 熛 (<CJK Ideograph>) 3863 0x71A0 熠 (<CJK Ideograph>) 3864 0x71A2 熢 (<CJK Ideograph>) 3865 0x71AF 熯 (<CJK Ideograph>) 3866 0x71B0 熰 (<CJK Ideograph>) 3867 0x71B2 熲 (<CJK Ideograph>) 3868 0x71B3 熳 (<CJK Ideograph>) 3869 0x71BA 熺 (<CJK Ideograph>) 3870 0x71BF 熿 (<CJK Ideograph>) 3871 0x71C0 燀 (<CJK Ideograph>) 3872 0x71C1 燁 (<CJK Ideograph>) 3873 0x71C4 燄 (<CJK Ideograph>) 3874 0x71CB 燋 (<CJK Ideograph>) 3875 0x71CC 燌 (<CJK Ideograph>) 3876 0x71D3 燓 (<CJK Ideograph>) 3877 0x71D6 燖 (<CJK Ideograph>) 3878 0x71D9 燙 (<CJK Ideograph>) 3879 0x71DA 燚 (<CJK Ideograph>) 3880 0x71DC 燜 (<CJK Ideograph>) 3881 0x71F8 燸 (<CJK Ideograph>) 3882 0x71FE 燾 (<CJK Ideograph>) 3883 0x7200 爀 (<CJK Ideograph>) 3884 0x7207 爇 (<CJK Ideograph>) 3885 0x7208 爈 (<CJK Ideograph>) 3886 0x7209 爉 (<CJK Ideograph>) 3887 0x7213 爓 (<CJK Ideograph>) 3888 0x7217 爗 (<CJK Ideograph>) 3889 0x721A 爚 (<CJK Ideograph>) 3890 0x721D 爝 (<CJK Ideograph>) 3891 0x721F 爟 (<CJK Ideograph>) 3892 0x7224 爤 (<CJK Ideograph>) 3893 0x722B 爫 (<CJK Ideograph>) 3894 0x722F 爯 (<CJK Ideograph>) 3895 0x7234 爴 (<CJK Ideograph>) 3896 0x7238 爸 (<CJK Ideograph>) 3897 0x7239 爹 (<CJK Ideograph>) 3898 0x7241 牁 (<CJK Ideograph>) 3899 0x7242 牂 (<CJK Ideograph>) 3900 0x7243 牃 (<CJK Ideograph>) 3901 0x7245 牅 (<CJK Ideograph>) 3902 0x724E 牎 (<CJK Ideograph>) 3903 0x724F 牏 (<CJK Ideograph>) 3904 0x7250 牐 (<CJK Ideograph>) 3905 0x7253 牓 (<CJK Ideograph>) 3906 0x7255 牕 (<CJK Ideograph>) 3907 0x7256 牖 (<CJK Ideograph>) 3908 0x725A 牚 (<CJK Ideograph>) 3909 0x725C 牜 (<CJK Ideograph>) 3910 0x725E 牞 (<CJK Ideograph>) 3911 0x7260 牠 (<CJK Ideograph>) 3912 0x7263 牣 (<CJK Ideograph>) 3913 0x7268 牨 (<CJK Ideograph>) 3914 0x726B 牫 (<CJK Ideograph>) 3915 0x726E 牮 (<CJK Ideograph>) 3916 0x726F 牯 (<CJK Ideograph>) 3917 0x7271 牱 (<CJK Ideograph>) 3918 0x7277 牷 (<CJK Ideograph>) 3919 0x7278 牸 (<CJK Ideograph>) 3920 0x727B 牻 (<CJK Ideograph>) 3921 0x727C 牼 (<CJK Ideograph>) 3922 0x727F 牿 (<CJK Ideograph>) 3923 0x7284 犄 (<CJK Ideograph>) 3924 0x7289 犉 (<CJK Ideograph>) 3925 0x728D 犍 (<CJK Ideograph>) 3926 0x728E 犎 (<CJK Ideograph>) 3927 0x7293 犓 (<CJK Ideograph>) 3928 0x729B 犛 (<CJK Ideograph>) 3929 0x72A8 犨 (<CJK Ideograph>) 3930 0x72AD 犭 (<CJK Ideograph>) 3931 0x72AE 犮 (<CJK Ideograph>) 3932 0x72B1 犱 (<CJK Ideograph>) 3933 0x72B4 犴 (<CJK Ideograph>) 3934 0x72BE 犾 (<CJK Ideograph>) 3935 0x72C1 狁 (<CJK Ideograph>) 3936 0x72C7 狇 (<CJK Ideograph>) 3937 0x72C9 狉 (<CJK Ideograph>) 3938 0x72CC 狌 (<CJK Ideograph>) 3939 0x72D5 狕 (<CJK Ideograph>) 3940 0x72D6 狖 (<CJK Ideograph>) 3941 0x72D8 狘 (<CJK Ideograph>) 3942 0x72DF 狟 (<CJK Ideograph>) 3943 0x72E5 狥 (<CJK Ideograph>) 3944 0x72F3 狳 (<CJK Ideograph>) 3945 0x72F4 狴 (<CJK Ideograph>) 3946 0x72FA 狺 (<CJK Ideograph>) 3947 0x72FB 狻 (<CJK Ideograph>) 3948 0x72FE 狾 (<CJK Ideograph>) 3949 0x7302 猂 (<CJK Ideograph>) 3950 0x7304 猄 (<CJK Ideograph>) 3951 0x7305 猅 (<CJK Ideograph>) 3952 0x7307 猇 (<CJK Ideograph>) 3953 0x730B 猋 (<CJK Ideograph>) 3954 0x730D 猍 (<CJK Ideograph>) 3955 0x7312 猒 (<CJK Ideograph>) 3956 0x7313 猓 (<CJK Ideograph>) 3957 0x7318 猘 (<CJK Ideograph>) 3958 0x7319 猙 (<CJK Ideograph>) 3959 0x731E 猞 (<CJK Ideograph>) 3960 0x7322 猢 (<CJK Ideograph>) 3961 0x7324 猤 (<CJK Ideograph>) 3962 0x7327 猧 (<CJK Ideograph>) 3963 0x7328 猨 (<CJK Ideograph>) 3964 0x732C 猬 (<CJK Ideograph>) 3965 0x7331 猱 (<CJK Ideograph>) 3966 0x7332 猲 (<CJK Ideograph>) 3967 0x7335 猵 (<CJK Ideograph>) 3968 0x733A 猺 (<CJK Ideograph>) 3969 0x733B 猻 (<CJK Ideograph>) 3970 0x733D 猽 (<CJK Ideograph>) 3971 0x7343 獃 (<CJK Ideograph>) 3972 0x734D 獍 (<CJK Ideograph>) 3973 0x7350 獐 (<CJK Ideograph>) 3974 0x7352 獒 (<CJK Ideograph>) 3975 0x7356 獖 (<CJK Ideograph>) 3976 0x7358 獘 (<CJK Ideograph>) 3977 0x735D 獝 (<CJK Ideograph>) 3978 0x735E 獞 (<CJK Ideograph>) 3979 0x735F 獟 (<CJK Ideograph>) 3980 0x7360 獠 (<CJK Ideograph>) 3981 0x7366 獦 (<CJK Ideograph>) 3982 0x7367 獧 (<CJK Ideograph>) 3983 0x7369 獩 (<CJK Ideograph>) 3984 0x736B 獫 (<CJK Ideograph>) 3985 0x736C 獬 (<CJK Ideograph>) 3986 0x736E 獮 (<CJK Ideograph>) 3987 0x736F 獯 (<CJK Ideograph>) 3988 0x7371 獱 (<CJK Ideograph>) 3989 0x7377 獷 (<CJK Ideograph>) 3990 0x7379 獹 (<CJK Ideograph>) 3991 0x737C 獼 (<CJK Ideograph>) 3992 0x7380 玀 (<CJK Ideograph>) 3993 0x7381 玁 (<CJK Ideograph>) 3994 0x7383 玃 (<CJK Ideograph>) 3995 0x7385 玅 (<CJK Ideograph>) 3996 0x7386 玆 (<CJK Ideograph>) 3997 0x738E 玎 (<CJK Ideograph>) 3998 0x7390 玐 (<CJK Ideograph>) 3999 0x7393 玓 (<CJK Ideograph>) 4000 0x7395 玕 (<CJK Ideograph>) 4001 0x7397 玗 (<CJK Ideograph>) 4002 0x7398 玘 (<CJK Ideograph>) 4003 0x739C 玜 (<CJK Ideograph>) 4004 0x739E 玞 (<CJK Ideograph>) 4005 0x739F 玟 (<CJK Ideograph>) 4006 0x73A0 玠 (<CJK Ideograph>) 4007 0x73A2 玢 (<CJK Ideograph>) 4008 0x73A5 玥 (<CJK Ideograph>) 4009 0x73A6 玦 (<CJK Ideograph>) 4010 0x73AA 玪 (<CJK Ideograph>) 4011 0x73AB 玫 (<CJK Ideograph>) 4012 0x73AD 玭 (<CJK Ideograph>) 4013 0x73B5 玵 (<CJK Ideograph>) 4014 0x73B7 玷 (<CJK Ideograph>) 4015 0x73B9 玹 (<CJK Ideograph>) 4016 0x73BC 玼 (<CJK Ideograph>) 4017 0x73BD 玽 (<CJK Ideograph>) 4018 0x73BF 玿 (<CJK Ideograph>) 4019 0x73C5 珅 (<CJK Ideograph>) 4020 0x73C6 珆 (<CJK Ideograph>) 4021 0x73C9 珉 (<CJK Ideograph>) 4022 0x73CB 珋 (<CJK Ideograph>) 4023 0x73CC 珌 (<CJK Ideograph>) 4024 0x73CF 珏 (<CJK Ideograph>) 4025 0x73D2 珒 (<CJK Ideograph>) 4026 0x73D3 珓 (<CJK Ideograph>) 4027 0x73D6 珖 (<CJK Ideograph>) 4028 0x73D9 珙 (<CJK Ideograph>) 4029 0x73DD 珝 (<CJK Ideograph>) 4030 0x73E1 珡 (<CJK Ideograph>) 4031 0x73E3 珣 (<CJK Ideograph>) 4032 0x73E6 珦 (<CJK Ideograph>) 4033 0x73E7 珧 (<CJK Ideograph>) 4034 0x73E9 珩 (<CJK Ideograph>) 4035 0x73F4 珴 (<CJK Ideograph>) 4036 0x73F5 珵 (<CJK Ideograph>) 4037 0x73F7 珷 (<CJK Ideograph>) 4038 0x73F9 珹 (<CJK Ideograph>) 4039 0x73FA 珺 (<CJK Ideograph>) 4040 0x73FB 珻 (<CJK Ideograph>) 4041 0x73FD 珽 (<CJK Ideograph>) 4042 0x73FF 珿 (<CJK Ideograph>) 4043 0x7400 琀 (<CJK Ideograph>) 4044 0x7401 琁 (<CJK Ideograph>) 4045 0x7404 琄 (<CJK Ideograph>) 4046 0x7407 琇 (<CJK Ideograph>) 4047 0x740A 琊 (<CJK Ideograph>) 4048 0x7411 琑 (<CJK Ideograph>) 4049 0x741A 琚 (<CJK Ideograph>) 4050 0x741B 琛 (<CJK Ideograph>) 4051 0x7424 琤 (<CJK Ideograph>) 4052 0x7426 琦 (<CJK Ideograph>) 4053 0x7428 琨 (<CJK Ideograph>) 4054 0x7429 琩 (<CJK Ideograph>) 4055 0x742A 琪 (<CJK Ideograph>) 4056 0x742B 琫 (<CJK Ideograph>) 4057 0x742C 琬 (<CJK Ideograph>) 4058 0x742D 琭 (<CJK Ideograph>) 4059 0x742E 琮 (<CJK Ideograph>) 4060 0x742F 琯 (<CJK Ideograph>) 4061 0x7430 琰 (<CJK Ideograph>) 4062 0x7431 琱 (<CJK Ideograph>) 4063 0x7439 琹 (<CJK Ideograph>) 4064 0x7440 瑀 (<CJK Ideograph>) 4065 0x7443 瑃 (<CJK Ideograph>) 4066 0x7444 瑄 (<CJK Ideograph>) 4067 0x7446 瑆 (<CJK Ideograph>) 4068 0x7447 瑇 (<CJK Ideograph>) 4069 0x744B 瑋 (<CJK Ideograph>) 4070 0x744D 瑍 (<CJK Ideograph>) 4071 0x7451 瑑 (<CJK Ideograph>) 4072 0x7452 瑒 (<CJK Ideograph>) 4073 0x7457 瑗 (<CJK Ideograph>) 4074 0x745D 瑝 (<CJK Ideograph>) 4075 0x7462 瑢 (<CJK Ideograph>) 4076 0x7466 瑦 (<CJK Ideograph>) 4077 0x7467 瑧 (<CJK Ideograph>) 4078 0x7468 瑨 (<CJK Ideograph>) 4079 0x746B 瑫 (<CJK Ideograph>) 4080 0x746D 瑭 (<CJK Ideograph>) 4081 0x746E 瑮 (<CJK Ideograph>) 4082 0x7471 瑱 (<CJK Ideograph>) 4083 0x7472 瑲 (<CJK Ideograph>) 4084 0x7480 璀 (<CJK Ideograph>) 4085 0x7481 璁 (<CJK Ideograph>) 4086 0x7485 璅 (<CJK Ideograph>) 4087 0x7486 璆 (<CJK Ideograph>) 4088 0x7487 璇 (<CJK Ideograph>) 4089 0x7489 璉 (<CJK Ideograph>) 4090 0x748F 璏 (<CJK Ideograph>) 4091 0x7490 璐 (<CJK Ideograph>) 4092 0x7491 璑 (<CJK Ideograph>) 4093 0x7492 璒 (<CJK Ideograph>) 4094 0x7498 璘 (<CJK Ideograph>) 4095 0x7499 璙 (<CJK Ideograph>) 4096 0x749A 璚 (<CJK Ideograph>) 4097 0x749C 璜 (<CJK Ideograph>) 4098 0x749F 璟 (<CJK Ideograph>) 4099 0x74A0 璠 (<CJK Ideograph>) 4100 0x74A1 璡 (<CJK Ideograph>) 4101 0x74A3 璣 (<CJK Ideograph>) 4102 0x74A6 璦 (<CJK Ideograph>) 4103 0x74A8 璨 (<CJK Ideograph>) 4104 0x74A9 璩 (<CJK Ideograph>) 4105 0x74AA 璪 (<CJK Ideograph>) 4106 0x74AB 璫 (<CJK Ideograph>) 4107 0x74AE 璮 (<CJK Ideograph>) 4108 0x74AF 璯 (<CJK Ideograph>) 4109 0x74B1 璱 (<CJK Ideograph>) 4110 0x74B2 璲 (<CJK Ideograph>) 4111 0x74B5 璵 (<CJK Ideograph>) 4112 0x74B9 璹 (<CJK Ideograph>) 4113 0x74BB 璻 (<CJK Ideograph>) 4114 0x74BF 璿 (<CJK Ideograph>) 4115 0x74C8 瓈 (<CJK Ideograph>) 4116 0x74C9 瓉 (<CJK Ideograph>) 4117 0x74CC 瓌 (<CJK Ideograph>) 4118 0x74D0 瓐 (<CJK Ideograph>) 4119 0x74D3 瓓 (<CJK Ideograph>) 4120 0x74D8 瓘 (<CJK Ideograph>) 4121 0x74DA 瓚 (<CJK Ideograph>) 4122 0x74DB 瓛 (<CJK Ideograph>) 4123 0x74DE 瓞 (<CJK Ideograph>) 4124 0x74DF 瓟 (<CJK Ideograph>) 4125 0x74E4 瓤 (<CJK Ideograph>) 4126 0x74E8 瓨 (<CJK Ideograph>) 4127 0x74EA 瓪 (<CJK Ideograph>) 4128 0x74EB 瓫 (<CJK Ideograph>) 4129 0x74EF 瓯 (<CJK Ideograph>) 4130 0x74F4 瓴 (<CJK Ideograph>) 4131 0x74FA 瓺 (<CJK Ideograph>) 4132 0x74FB 瓻 (<CJK Ideograph>) 4133 0x74FC 瓼 (<CJK Ideograph>) 4134 0x74FF 瓿 (<CJK Ideograph>) 4135 0x7506 甆 (<CJK Ideograph>) 4136 0x7512 甒 (<CJK Ideograph>) 4137 0x7516 甖 (<CJK Ideograph>) 4138 0x7517 甗 (<CJK Ideograph>) 4139 0x7520 甠 (<CJK Ideograph>) 4140 0x7521 甡 (<CJK Ideograph>) 4141 0x7524 甤 (<CJK Ideograph>) 4142 0x7527 甧 (<CJK Ideograph>) 4143 0x7529 甩 (<CJK Ideograph>) 4144 0x752A 甪 (<CJK Ideograph>) 4145 0x752F 甯 (<CJK Ideograph>) 4146 0x7536 甶 (<CJK Ideograph>) 4147 0x7539 甹 (<CJK Ideograph>) 4148 0x753D 甽 (<CJK Ideograph>) 4149 0x753E 甾 (<CJK Ideograph>) 4150 0x753F 甿 (<CJK Ideograph>) 4151 0x7540 畀 (<CJK Ideograph>) 4152 0x7543 畃 (<CJK Ideograph>) 4153 0x7547 畇 (<CJK Ideograph>) 4154 0x7548 畈 (<CJK Ideograph>) 4155 0x754E 畎 (<CJK Ideograph>) 4156 0x7550 畐 (<CJK Ideograph>) 4157 0x7552 畒 (<CJK Ideograph>) 4158 0x7557 畗 (<CJK Ideograph>) 4159 0x755E 畞 (<CJK Ideograph>) 4160 0x755F 畟 (<CJK Ideograph>) 4161 0x7561 畡 (<CJK Ideograph>) 4162 0x756F 畯 (<CJK Ideograph>) 4163 0x7571 畱 (<CJK Ideograph>) 4164 0x7579 畹 (<CJK Ideograph>) 4165 0x757A 畺 (<CJK Ideograph>) 4166 0x757B 畻 (<CJK Ideograph>) 4167 0x757C 畼 (<CJK Ideograph>) 4168 0x757D 畽 (<CJK Ideograph>) 4169 0x757E 畾 (<CJK Ideograph>) 4170 0x7581 疁 (<CJK Ideograph>) 4171 0x7585 疅 (<CJK Ideograph>) 4172 0x7590 疐 (<CJK Ideograph>) 4173 0x7592 疒 (<CJK Ideograph>) 4174 0x7593 疓 (<CJK Ideograph>) 4175 0x7595 疕 (<CJK Ideograph>) 4176 0x7599 疙 (<CJK Ideograph>) 4177 0x759C 疜 (<CJK Ideograph>) 4178 0x75A2 疢 (<CJK Ideograph>) 4179 0x75A4 疤 (<CJK Ideograph>) 4180 0x75B4 疴 (<CJK Ideograph>) 4181 0x75BA 疺 (<CJK Ideograph>) 4182 0x75BF 疿 (<CJK Ideograph>) 4183 0x75C0 痀 (<CJK Ideograph>) 4184 0x75C1 痁 (<CJK Ideograph>) 4185 0x75C4 痄 (<CJK Ideograph>) 4186 0x75C6 痆 (<CJK Ideograph>) 4187 0x75CC 痌 (<CJK Ideograph>) 4188 0x75CE 痎 (<CJK Ideograph>) 4189 0x75CF 痏 (<CJK Ideograph>) 4190 0x75D7 痗 (<CJK Ideograph>) 4191 0x75DC 痜 (<CJK Ideograph>) 4192 0x75DF 痟 (<CJK Ideograph>) 4193 0x75E0 痠 (<CJK Ideograph>) 4194 0x75E1 痡 (<CJK Ideograph>) 4195 0x75E4 痤 (<CJK Ideograph>) 4196 0x75E7 痧 (<CJK Ideograph>) 4197 0x75EC 痬 (<CJK Ideograph>) 4198 0x75EE 痮 (<CJK Ideograph>) 4199 0x75EF 痯 (<CJK Ideograph>) 4200 0x75F1 痱 (<CJK Ideograph>) 4201 0x75F9 痹 (<CJK Ideograph>) 4202 0x7600 瘀 (<CJK Ideograph>) 4203 0x7602 瘂 (<CJK Ideograph>) 4204 0x7603 瘃 (<CJK Ideograph>) 4205 0x7604 瘄 (<CJK Ideograph>) 4206 0x7607 瘇 (<CJK Ideograph>) 4207 0x7608 瘈 (<CJK Ideograph>) 4208 0x760A 瘊 (<CJK Ideograph>) 4209 0x760C 瘌 (<CJK Ideograph>) 4210 0x760F 瘏 (<CJK Ideograph>) 4211 0x7612 瘒 (<CJK Ideograph>) 4212 0x7613 瘓 (<CJK Ideograph>) 4213 0x7615 瘕 (<CJK Ideograph>) 4214 0x7616 瘖 (<CJK Ideograph>) 4215 0x7619 瘙 (<CJK Ideograph>) 4216 0x761B 瘛 (<CJK Ideograph>) 4217 0x761C 瘜 (<CJK Ideograph>) 4218 0x761D 瘝 (<CJK Ideograph>) 4219 0x761E 瘞 (<CJK Ideograph>) 4220 0x7623 瘣 (<CJK Ideograph>) 4221 0x7625 瘥 (<CJK Ideograph>) 4222 0x7626 瘦 (<CJK Ideograph>) 4223 0x7629 瘩 (<CJK Ideograph>) 4224 0x762D 瘭 (<CJK Ideograph>) 4225 0x7632 瘲 (<CJK Ideograph>) 4226 0x7633 瘳 (<CJK Ideograph>) 4227 0x7635 瘵 (<CJK Ideograph>) 4228 0x7638 瘸 (<CJK Ideograph>) 4229 0x7639 瘹 (<CJK Ideograph>) 4230 0x763A 瘺 (<CJK Ideograph>) 4231 0x763C 瘼 (<CJK Ideograph>) 4232 0x764A 癊 (<CJK Ideograph>) 4233 0x7640 癀 (<CJK Ideograph>) 4234 0x7641 癁 (<CJK Ideograph>) 4235 0x7643 癃 (<CJK Ideograph>) 4236 0x7644 癄 (<CJK Ideograph>) 4237 0x7645 癅 (<CJK Ideograph>) 4238 0x7649 癉 (<CJK Ideograph>) 4239 0x764B 癋 (<CJK Ideograph>) 4240 0x7655 癕 (<CJK Ideograph>) 4241 0x7659 癙 (<CJK Ideograph>) 4242 0x765F 癟 (<CJK Ideograph>) 4243 0x7664 癤 (<CJK Ideograph>) 4244 0x7665 癥 (<CJK Ideograph>) 4245 0x766D 癭 (<CJK Ideograph>) 4246 0x766E 癮 (<CJK Ideograph>) 4247 0x766F 癯 (<CJK Ideograph>) 4248 0x7671 癱 (<CJK Ideograph>) 4249 0x7674 癴 (<CJK Ideograph>) 4250 0x7681 皁 (<CJK Ideograph>) 4251 0x7685 皅 (<CJK Ideograph>) 4252 0x768C 皌 (<CJK Ideograph>) 4253 0x768D 皍 (<CJK Ideograph>) 4254 0x7695 皕 (<CJK Ideograph>) 4255 0x769B 皛 (<CJK Ideograph>) 4256 0x769C 皜 (<CJK Ideograph>) 4257 0x769D 皝 (<CJK Ideograph>) 4258 0x769F 皟 (<CJK Ideograph>) 4259 0x76A0 皠 (<CJK Ideograph>) 4260 0x76A2 皢 (<CJK Ideograph>) 4261 0x76A3 皣 (<CJK Ideograph>) 4262 0x76A4 皤 (<CJK Ideograph>) 4263 0x76A5 皥 (<CJK Ideograph>) 4264 0x76A6 皦 (<CJK Ideograph>) 4265 0x76A7 皧 (<CJK Ideograph>) 4266 0x76A8 皨 (<CJK Ideograph>) 4267 0x76AA 皪 (<CJK Ideograph>) 4268 0x76AD 皭 (<CJK Ideograph>) 4269 0x76BD 皽 (<CJK Ideograph>) 4270 0x76C1 盁 (<CJK Ideograph>) 4271 0x76C5 盅 (<CJK Ideograph>) 4272 0x76C9 盉 (<CJK Ideograph>) 4273 0x76CB 盋 (<CJK Ideograph>) 4274 0x76CC 盌 (<CJK Ideograph>) 4275 0x76CE 盎 (<CJK Ideograph>) 4276 0x76D4 盔 (<CJK Ideograph>) 4277 0x76D9 盙 (<CJK Ideograph>) 4278 0x76E0 盠 (<CJK Ideograph>) 4279 0x76E6 盦 (<CJK Ideograph>) 4280 0x76E8 盨 (<CJK Ideograph>) 4281 0x76EC 盬 (<CJK Ideograph>) 4282 0x76F0 盰 (<CJK Ideograph>) 4283 0x76F1 盱 (<CJK Ideograph>) 4284 0x76F6 盶 (<CJK Ideograph>) 4285 0x76F9 盹 (<CJK Ideograph>) 4286 0x76FC 盼 (<CJK Ideograph>) 4287 0x7700 眀 (<CJK Ideograph>) 4288 0x7706 眆 (<CJK Ideograph>) 4289 0x770A 眊 (<CJK Ideograph>) 4290 0x770E 眎 (<CJK Ideograph>) 4291 0x7712 眒 (<CJK Ideograph>) 4292 0x7714 眔 (<CJK Ideograph>) 4293 0x7715 眕 (<CJK Ideograph>) 4294 0x7717 眗 (<CJK Ideograph>) 4295 0x7719 眙 (<CJK Ideograph>) 4296 0x771A 眚 (<CJK Ideograph>) 4297 0x771C 眜 (<CJK Ideograph>) 4298 0x7722 眢 (<CJK Ideograph>) 4299 0x7728 眨 (<CJK Ideograph>) 4300 0x772D 眭 (<CJK Ideograph>) 4301 0x772E 眮 (<CJK Ideograph>) 4302 0x772F 眯 (<CJK Ideograph>) 4303 0x7734 眴 (<CJK Ideograph>) 4304 0x7735 眵 (<CJK Ideograph>) 4305 0x7736 眶 (<CJK Ideograph>) 4306 0x7739 眹 (<CJK Ideograph>) 4307 0x773D 眽 (<CJK Ideograph>) 4308 0x773E 眾 (<CJK Ideograph>) 4309 0x7742 睂 (<CJK Ideograph>) 4310 0x7745 睅 (<CJK Ideograph>) 4311 0x7746 睆 (<CJK Ideograph>) 4312 0x774A 睊 (<CJK Ideograph>) 4313 0x774D 睍 (<CJK Ideograph>) 4314 0x774E 睎 (<CJK Ideograph>) 4315 0x774F 睏 (<CJK Ideograph>) 4316 0x7752 睒 (<CJK Ideograph>) 4317 0x7756 睖 (<CJK Ideograph>) 4318 0x7757 睗 (<CJK Ideograph>) 4319 0x775C 睜 (<CJK Ideograph>) 4320 0x775E 睞 (<CJK Ideograph>) 4321 0x775F 睟 (<CJK Ideograph>) 4322 0x7760 睠 (<CJK Ideograph>) 4323 0x7762 睢 (<CJK Ideograph>) 4324 0x7764 睤 (<CJK Ideograph>) 4325 0x7767 睧 (<CJK Ideograph>) 4326 0x776A 睪 (<CJK Ideograph>) 4327 0x776C 睬 (<CJK Ideograph>) 4328 0x7770 睰 (<CJK Ideograph>) 4329 0x7772 睲 (<CJK Ideograph>) 4330 0x7773 睳 (<CJK Ideograph>) 4331 0x7774 睴 (<CJK Ideograph>) 4332 0x777A 睺 (<CJK Ideograph>) 4333 0x777D 睽 (<CJK Ideograph>) 4334 0x7780 瞀 (<CJK Ideograph>) 4335 0x7784 瞄 (<CJK Ideograph>) 4336 0x778C 瞌 (<CJK Ideograph>) 4337 0x778D 瞍 (<CJK Ideograph>) 4338 0x7794 瞔 (<CJK Ideograph>) 4339 0x7795 瞕 (<CJK Ideograph>) 4340 0x7796 瞖 (<CJK Ideograph>) 4341 0x779A 瞚 (<CJK Ideograph>) 4342 0x779F 瞟 (<CJK Ideograph>) 4343 0x77A2 瞢 (<CJK Ideograph>) 4344 0x77A7 瞧 (<CJK Ideograph>) 4345 0x77AA 瞪 (<CJK Ideograph>) 4346 0x77AE 瞮 (<CJK Ideograph>) 4347 0x77AF 瞯 (<CJK Ideograph>) 4348 0x77B1 瞱 (<CJK Ideograph>) 4349 0x77B5 瞵 (<CJK Ideograph>) 4350 0x77BE 瞾 (<CJK Ideograph>) 4351 0x77C3 矃 (<CJK Ideograph>) 4352 0x77C9 矉 (<CJK Ideograph>) 4353 0x77D1 矑 (<CJK Ideograph>) 4354 0x77D2 矒 (<CJK Ideograph>) 4355 0x77D5 矕 (<CJK Ideograph>) 4356 0x77D9 矙 (<CJK Ideograph>) 4357 0x77DE 矞 (<CJK Ideograph>) 4358 0x77DF 矟 (<CJK Ideograph>) 4359 0x77E0 矠 (<CJK Ideograph>) 4360 0x77E4 矤 (<CJK Ideograph>) 4361 0x77E6 矦 (<CJK Ideograph>) 4362 0x77EA 矪 (<CJK Ideograph>) 4363 0x77EC 矬 (<CJK Ideograph>) 4364 0x77F0 矰 (<CJK Ideograph>) 4365 0x77F1 矱 (<CJK Ideograph>) 4366 0x77F4 矴 (<CJK Ideograph>) 4367 0x77F8 矸 (<CJK Ideograph>) 4368 0x77FB 矻 (<CJK Ideograph>) 4369 0x7805 砅 (<CJK Ideograph>) 4370 0x7806 砆 (<CJK Ideograph>) 4371 0x7809 砉 (<CJK Ideograph>) 4372 0x780D 砍 (<CJK Ideograph>) 4373 0x780E 砎 (<CJK Ideograph>) 4374 0x7811 砑 (<CJK Ideograph>) 4375 0x781D 砝 (<CJK Ideograph>) 4376 0x7821 砡 (<CJK Ideograph>) 4377 0x7822 砢 (<CJK Ideograph>) 4378 0x7823 砣 (<CJK Ideograph>) 4379 0x782D 砭 (<CJK Ideograph>) 4380 0x782E 砮 (<CJK Ideograph>) 4381 0x7830 砰 (<CJK Ideograph>) 4382 0x7835 砵 (<CJK Ideograph>) 4383 0x7837 砷 (<CJK Ideograph>) 4384 0x7843 硃 (<CJK Ideograph>) 4385 0x7844 硄 (<CJK Ideograph>) 4386 0x7847 硇 (<CJK Ideograph>) 4387 0x7848 硈 (<CJK Ideograph>) 4388 0x784C 硌 (<CJK Ideograph>) 4389 0x784E 硎 (<CJK Ideograph>) 4390 0x7852 硒 (<CJK Ideograph>) 4391 0x785C 硜 (<CJK Ideograph>) 4392 0x785E 硞 (<CJK Ideograph>) 4393 0x7860 硠 (<CJK Ideograph>) 4394 0x7861 硡 (<CJK Ideograph>) 4395 0x7863 硣 (<CJK Ideograph>) 4396 0x7864 硤 (<CJK Ideograph>) 4397 0x7868 硨 (<CJK Ideograph>) 4398 0x786A 硪 (<CJK Ideograph>) 4399 0x786E 确 (<CJK Ideograph>) 4400 0x787A 硺 (<CJK Ideograph>) 4401 0x787E 硾 (<CJK Ideograph>) 4402 0x788A 碊 (<CJK Ideograph>) 4403 0x788F 碏 (<CJK Ideograph>) 4404 0x7894 碔 (<CJK Ideograph>) 4405 0x7898 碘 (<CJK Ideograph>) 4406 0x78A1 碡 (<CJK Ideograph>) 4407 0x789D 碝 (<CJK Ideograph>) 4408 0x789E 碞 (<CJK Ideograph>) 4409 0x789F 碟 (<CJK Ideograph>) 4410 0x78A4 碤 (<CJK Ideograph>) 4411 0x78A8 碨 (<CJK Ideograph>) 4412 0x78AC 碬 (<CJK Ideograph>) 4413 0x78AD 碭 (<CJK Ideograph>) 4414 0x78B0 碰 (<CJK Ideograph>) 4415 0x78B1 碱 (<CJK Ideograph>) 4416 0x78B2 碲 (<CJK Ideograph>) 4417 0x78B3 碳 (<CJK Ideograph>) 4418 0x78BB 碻 (<CJK Ideograph>) 4419 0x78BD 碽 (<CJK Ideograph>) 4420 0x78BF 碿 (<CJK Ideograph>) 4421 0x78C7 磇 (<CJK Ideograph>) 4422 0x78C8 磈 (<CJK Ideograph>) 4423 0x78C9 磉 (<CJK Ideograph>) 4424 0x78CC 磌 (<CJK Ideograph>) 4425 0x78CE 磎 (<CJK Ideograph>) 4426 0x78D2 磒 (<CJK Ideograph>) 4427 0x78D3 磓 (<CJK Ideograph>) 4428 0x78D5 磕 (<CJK Ideograph>) 4429 0x78D6 磖 (<CJK Ideograph>) 4430 0x78E4 磤 (<CJK Ideograph>) 4431 0x78DB 磛 (<CJK Ideograph>) 4432 0x78DF 磟 (<CJK Ideograph>) 4433 0x78E0 磠 (<CJK Ideograph>) 4434 0x78E1 磡 (<CJK Ideograph>) 4435 0x78E6 磦 (<CJK Ideograph>) 4436 0x78EA 磪 (<CJK Ideograph>) 4437 0x78F2 磲 (<CJK Ideograph>) 4438 0x78F3 磳 (<CJK Ideograph>) 4439 0x7900 礀 (<CJK Ideograph>) 4440 0x78F6 磶 (<CJK Ideograph>) 4441 0x78F7 磷 (<CJK Ideograph>) 4442 0x78FA 磺 (<CJK Ideograph>) 4443 0x78FB 磻 (<CJK Ideograph>) 4444 0x78FF 磿 (<CJK Ideograph>) 4445 0x7906 礆 (<CJK Ideograph>) 4446 0x790C 礌 (<CJK Ideograph>) 4447 0x7910 礐 (<CJK Ideograph>) 4448 0x791A 礚 (<CJK Ideograph>) 4449 0x791C 礜 (<CJK Ideograph>) 4450 0x791E 礞 (<CJK Ideograph>) 4451 0x791F 礟 (<CJK Ideograph>) 4452 0x7920 礠 (<CJK Ideograph>) 4453 0x7925 礥 (<CJK Ideograph>) 4454 0x7927 礧 (<CJK Ideograph>) 4455 0x7929 礩 (<CJK Ideograph>) 4456 0x792D 礭 (<CJK Ideograph>) 4457 0x7931 礱 (<CJK Ideograph>) 4458 0x7934 礴 (<CJK Ideograph>) 4459 0x7935 礵 (<CJK Ideograph>) 4460 0x793B 礻 (<CJK Ideograph>) 4461 0x793D 礽 (<CJK Ideograph>) 4462 0x793F 礿 (<CJK Ideograph>) 4463 0x7944 祄 (<CJK Ideograph>) 4464 0x7945 祅 (<CJK Ideograph>) 4465 0x7946 祆 (<CJK Ideograph>) 4466 0x794A 祊 (<CJK Ideograph>) 4467 0x794B 祋 (<CJK Ideograph>) 4468 0x794F 祏 (<CJK Ideograph>) 4469 0x7951 祑 (<CJK Ideograph>) 4470 0x7954 祔 (<CJK Ideograph>) 4471 0x7958 祘 (<CJK Ideograph>) 4472 0x795B 祛 (<CJK Ideograph>) 4473 0x795C 祜 (<CJK Ideograph>) 4474 0x7967 祧 (<CJK Ideograph>) 4475 0x7969 祩 (<CJK Ideograph>) 4476 0x796B 祫 (<CJK Ideograph>) 4477 0x7972 祲 (<CJK Ideograph>) 4478 0x7979 祹 (<CJK Ideograph>) 4479 0x797B 祻 (<CJK Ideograph>) 4480 0x797C 祼 (<CJK Ideograph>) 4481 0x797E 祾 (<CJK Ideograph>) 4482 0x798B 禋 (<CJK Ideograph>) 4483 0x798C 禌 (<CJK Ideograph>) 4484 0x7991 禑 (<CJK Ideograph>) 4485 0x7993 禓 (<CJK Ideograph>) 4486 0x7994 禔 (<CJK Ideograph>) 4487 0x7995 禕 (<CJK Ideograph>) 4488 0x7996 禖 (<CJK Ideograph>) 4489 0x7998 禘 (<CJK Ideograph>) 4490 0x799B 禛 (<CJK Ideograph>) 4491 0x799C 禜 (<CJK Ideograph>) 4492 0x79A1 禡 (<CJK Ideograph>) 4493 0x79A8 禨 (<CJK Ideograph>) 4494 0x79A9 禩 (<CJK Ideograph>) 4495 0x79AB 禫 (<CJK Ideograph>) 4496 0x79AF 禯 (<CJK Ideograph>) 4497 0x79B1 禱 (<CJK Ideograph>) 4498 0x79B4 禴 (<CJK Ideograph>) 4499 0x79B8 禸 (<CJK Ideograph>) 4500 0x79BB 离 (<CJK Ideograph>) 4501 0x79C2 秂 (<CJK Ideograph>) 4502 0x79C4 秄 (<CJK Ideograph>) 4503 0x79C7 秇 (<CJK Ideograph>) 4504 0x79C8 秈 (<CJK Ideograph>) 4505 0x79CA 秊 (<CJK Ideograph>) 4506 0x79CF 秏 (<CJK Ideograph>) 4507 0x79D4 秔 (<CJK Ideograph>) 4508 0x79D6 秖 (<CJK Ideograph>) 4509 0x79DA 秚 (<CJK Ideograph>) 4510 0x79DD 秝 (<CJK Ideograph>) 4511 0x79DE 秞 (<CJK Ideograph>) 4512 0x79E0 秠 (<CJK Ideograph>) 4513 0x79E2 秢 (<CJK Ideograph>) 4514 0x79E5 秥 (<CJK Ideograph>) 4515 0x79EA 秪 (<CJK Ideograph>) 4516 0x79EB 秫 (<CJK Ideograph>) 4517 0x79ED 秭 (<CJK Ideograph>) 4518 0x79F1 秱 (<CJK Ideograph>) 4519 0x79F8 秸 (<CJK Ideograph>) 4520 0x79FC 秼 (<CJK Ideograph>) 4521 0x7A02 稂 (<CJK Ideograph>) 4522 0x7A03 稃 (<CJK Ideograph>) 4523 0x7A07 稇 (<CJK Ideograph>) 4524 0x7A09 稉 (<CJK Ideograph>) 4525 0x7A0A 稊 (<CJK Ideograph>) 4526 0x7A0C 稌 (<CJK Ideograph>) 4527 0x7A11 稑 (<CJK Ideograph>) 4528 0x7A15 稕 (<CJK Ideograph>) 4529 0x7A1B 稛 (<CJK Ideograph>) 4530 0x7A1E 稞 (<CJK Ideograph>) 4531 0x7A21 稡 (<CJK Ideograph>) 4532 0x7A27 稧 (<CJK Ideograph>) 4533 0x7A2B 稫 (<CJK Ideograph>) 4534 0x7A2D 稭 (<CJK Ideograph>) 4535 0x7A2F 稯 (<CJK Ideograph>) 4536 0x7A30 稰 (<CJK Ideograph>) 4537 0x7A34 稴 (<CJK Ideograph>) 4538 0x7A35 稵 (<CJK Ideograph>) 4539 0x7A38 稸 (<CJK Ideograph>) 4540 0x7A39 稹 (<CJK Ideograph>) 4541 0x7A3A 稺 (<CJK Ideograph>) 4542 0x7A44 穄 (<CJK Ideograph>) 4543 0x7A45 穅 (<CJK Ideograph>) 4544 0x7A47 穇 (<CJK Ideograph>) 4545 0x7A48 穈 (<CJK Ideograph>) 4546 0x7A4C 穌 (<CJK Ideograph>) 4547 0x7A55 穕 (<CJK Ideograph>) 4548 0x7A56 穖 (<CJK Ideograph>) 4549 0x7A59 穙 (<CJK Ideograph>) 4550 0x7A5C 穜 (<CJK Ideograph>) 4551 0x7A5D 穝 (<CJK Ideograph>) 4552 0x7A5F 穟 (<CJK Ideograph>) 4553 0x7A60 穠 (<CJK Ideograph>) 4554 0x7A65 穥 (<CJK Ideograph>) 4555 0x7A67 穧 (<CJK Ideograph>) 4556 0x7A6A 穪 (<CJK Ideograph>) 4557 0x7A6D 穭 (<CJK Ideograph>) 4558 0x7A75 穵 (<CJK Ideograph>) 4559 0x7A78 穸 (<CJK Ideograph>) 4560 0x7A7E 穾 (<CJK Ideograph>) 4561 0x7A80 窀 (<CJK Ideograph>) 4562 0x7A82 窂 (<CJK Ideograph>) 4563 0x7A85 窅 (<CJK Ideograph>) 4564 0x7A86 窆 (<CJK Ideograph>) 4565 0x7A8A 窊 (<CJK Ideograph>) 4566 0x7A8B 窋 (<CJK Ideograph>) 4567 0x7A90 窐 (<CJK Ideograph>) 4568 0x7A91 窑 (<CJK Ideograph>) 4569 0x7A94 窔 (<CJK Ideograph>) 4570 0x7A9E 窞 (<CJK Ideograph>) 4571 0x7AA0 窠 (<CJK Ideograph>) 4572 0x7AA3 窣 (<CJK Ideograph>) 4573 0x7AAC 窬 (<CJK Ideograph>) 4574 0x7AB3 窳 (<CJK Ideograph>) 4575 0x7AB5 窵 (<CJK Ideograph>) 4576 0x7AB9 窹 (<CJK Ideograph>) 4577 0x7ABB 窻 (<CJK Ideograph>) 4578 0x7ABC 窼 (<CJK Ideograph>) 4579 0x7AC6 竆 (<CJK Ideograph>) 4580 0x7AC9 竉 (<CJK Ideograph>) 4581 0x7ACC 竌 (<CJK Ideograph>) 4582 0x7ACE 竎 (<CJK Ideograph>) 4583 0x7AD1 竑 (<CJK Ideograph>) 4584 0x7ADB 竛 (<CJK Ideograph>) 4585 0x7AE8 竨 (<CJK Ideograph>) 4586 0x7AE9 竩 (<CJK Ideograph>) 4587 0x7AEB 竫 (<CJK Ideograph>) 4588 0x7AEC 竬 (<CJK Ideograph>) 4589 0x7AF1 竱 (<CJK Ideograph>) 4590 0x7AF4 竴 (<CJK Ideograph>) 4591 0x7AFB 竻 (<CJK Ideograph>) 4592 0x7AFD 竽 (<CJK Ideograph>) 4593 0x7AFE 竾 (<CJK Ideograph>) 4594 0x7B07 笇 (<CJK Ideograph>) 4595 0x7B14 笔 (<CJK Ideograph>) 4596 0x7B1F 笟 (<CJK Ideograph>) 4597 0x7B23 笣 (<CJK Ideograph>) 4598 0x7B27 笧 (<CJK Ideograph>) 4599 0x7B29 笩 (<CJK Ideograph>) 4600 0x7B2A 笪 (<CJK Ideograph>) 4601 0x7B2B 笫 (<CJK Ideograph>) 4602 0x7B2D 笭 (<CJK Ideograph>) 4603 0x7B2E 笮 (<CJK Ideograph>) 4604 0x7B2F 笯 (<CJK Ideograph>) 4605 0x7B30 笰 (<CJK Ideograph>) 4606 0x7B31 笱 (<CJK Ideograph>) 4607 0x7B34 笴 (<CJK Ideograph>) 4608 0x7B3D 笽 (<CJK Ideograph>) 4609 0x7B3F 笿 (<CJK Ideograph>) 4610 0x7B40 筀 (<CJK Ideograph>) 4611 0x7B41 筁 (<CJK Ideograph>) 4612 0x7B47 筇 (<CJK Ideograph>) 4613 0x7B4E 筎 (<CJK Ideograph>) 4614 0x7B55 筕 (<CJK Ideograph>) 4615 0x7B60 筠 (<CJK Ideograph>) 4616 0x7B64 筤 (<CJK Ideograph>) 4617 0x7B66 筦 (<CJK Ideograph>) 4618 0x7B69 筩 (<CJK Ideograph>) 4619 0x7B6A 筪 (<CJK Ideograph>) 4620 0x7B6D 筭 (<CJK Ideograph>) 4621 0x7B6F 筯 (<CJK Ideograph>) 4622 0x7B72 筲 (<CJK Ideograph>) 4623 0x7B73 筳 (<CJK Ideograph>) 4624 0x7B77 筷 (<CJK Ideograph>) 4625 0x7B84 箄 (<CJK Ideograph>) 4626 0x7B89 箉 (<CJK Ideograph>) 4627 0x7B8E 箎 (<CJK Ideograph>) 4628 0x7B90 箐 (<CJK Ideograph>) 4629 0x7B91 箑 (<CJK Ideograph>) 4630 0x7B96 箖 (<CJK Ideograph>) 4631 0x7B9B 箛 (<CJK Ideograph>) 4632 0x7B9E 箞 (<CJK Ideograph>) 4633 0x7BA0 箠 (<CJK Ideograph>) 4634 0x7BA5 箥 (<CJK Ideograph>) 4635 0x7BAC 箬 (<CJK Ideograph>) 4636 0x7BAF 箯 (<CJK Ideograph>) 4637 0x7BB0 箰 (<CJK Ideograph>) 4638 0x7BB2 箲 (<CJK Ideograph>) 4639 0x7BB5 箵 (<CJK Ideograph>) 4640 0x7BB6 箶 (<CJK Ideograph>) 4641 0x7BBA 箺 (<CJK Ideograph>) 4642 0x7BBB 箻 (<CJK Ideograph>) 4643 0x7BBC 箼 (<CJK Ideograph>) 4644 0x7BBD 箽 (<CJK Ideograph>) 4645 0x7BC2 篂 (<CJK Ideograph>) 4646 0x7BC5 篅 (<CJK Ideograph>) 4647 0x7BC8 篈 (<CJK Ideograph>) 4648 0x7BCA 篊 (<CJK Ideograph>) 4649 0x7BD4 篔 (<CJK Ideograph>) 4650 0x7BD6 篖 (<CJK Ideograph>) 4651 0x7BD7 篗 (<CJK Ideograph>) 4652 0x7BD9 篙 (<CJK Ideograph>) 4653 0x7BDA 篚 (<CJK Ideograph>) 4654 0x7BDB 篛 (<CJK Ideograph>) 4655 0x7BE8 篨 (<CJK Ideograph>) 4656 0x7BEA 篪 (<CJK Ideograph>) 4657 0x7BF2 篲 (<CJK Ideograph>) 4658 0x7BF4 篴 (<CJK Ideograph>) 4659 0x7BF5 篵 (<CJK Ideograph>) 4660 0x7BF8 篸 (<CJK Ideograph>) 4661 0x7BF9 篹 (<CJK Ideograph>) 4662 0x7BFA 篺 (<CJK Ideograph>) 4663 0x7BFC 篼 (<CJK Ideograph>) 4664 0x7BFE 篾 (<CJK Ideograph>) 4665 0x7C01 簁 (<CJK Ideograph>) 4666 0x7C02 簂 (<CJK Ideograph>) 4667 0x7C03 簃 (<CJK Ideograph>) 4668 0x7C04 簄 (<CJK Ideograph>) 4669 0x7C06 簆 (<CJK Ideograph>) 4670 0x7C09 簉 (<CJK Ideograph>) 4671 0x7C0B 簋 (<CJK Ideograph>) 4672 0x7C0C 簌 (<CJK Ideograph>) 4673 0x7C0E 簎 (<CJK Ideograph>) 4674 0x7C0F 簏 (<CJK Ideograph>) 4675 0x7C19 簙 (<CJK Ideograph>) 4676 0x7C1B 簛 (<CJK Ideograph>) 4677 0x7C20 簠 (<CJK Ideograph>) 4678 0x7C25 簥 (<CJK Ideograph>) 4679 0x7C26 簦 (<CJK Ideograph>) 4680 0x7C28 簨 (<CJK Ideograph>) 4681 0x7C2C 簬 (<CJK Ideograph>) 4682 0x7C31 簱 (<CJK Ideograph>) 4683 0x7C33 簳 (<CJK Ideograph>) 4684 0x7C34 簴 (<CJK Ideograph>) 4685 0x7C36 簶 (<CJK Ideograph>) 4686 0x7C39 簹 (<CJK Ideograph>) 4687 0x7C3A 簺 (<CJK Ideograph>) 4688 0x7C46 籆 (<CJK Ideograph>) 4689 0x7C4A 籊 (<CJK Ideograph>) 4690 0x7C55 籕 (<CJK Ideograph>) 4691 0x7C51 籑 (<CJK Ideograph>) 4692 0x7C52 籒 (<CJK Ideograph>) 4693 0x7C53 籓 (<CJK Ideograph>) 4694 0x7C59 籙 (<CJK Ideograph>) 4695 0x7C5A 籚 (<CJK Ideograph>) 4696 0x7C5B 籛 (<CJK Ideograph>) 4697 0x7C5C 籜 (<CJK Ideograph>) 4698 0x7C5D 籝 (<CJK Ideograph>) 4699 0x7C5E 籞 (<CJK Ideograph>) 4700 0x7C61 籡 (<CJK Ideograph>) 4701 0x7C63 籣 (<CJK Ideograph>) 4702 0x7C67 籧 (<CJK Ideograph>) 4703 0x7C69 籩 (<CJK Ideograph>) 4704 0x7C6D 籭 (<CJK Ideograph>) 4705 0x7C6E 籮 (<CJK Ideograph>) 4706 0x7C70 籰 (<CJK Ideograph>) 4707 0x7C72 籲 (<CJK Ideograph>) 4708 0x7C79 籹 (<CJK Ideograph>) 4709 0x7C7C 籼 (<CJK Ideograph>) 4710 0x7C7D 籽 (<CJK Ideograph>) 4711 0x7C86 粆 (<CJK Ideograph>) 4712 0x7C87 粇 (<CJK Ideograph>) 4713 0x7C8F 粏 (<CJK Ideograph>) 4714 0x7C94 粔 (<CJK Ideograph>) 4715 0x7C9E 粞 (<CJK Ideograph>) 4716 0x7CA0 粠 (<CJK Ideograph>) 4717 0x7CA6 粦 (<CJK Ideograph>) 4718 0x7CB0 粰 (<CJK Ideograph>) 4719 0x7CB6 粶 (<CJK Ideograph>) 4720 0x7CB7 粷 (<CJK Ideograph>) 4721 0x7CBA 粺 (<CJK Ideograph>) 4722 0x7CBB 粻 (<CJK Ideograph>) 4723 0x7CBC 粼 (<CJK Ideograph>) 4724 0x7CBF 粿 (<CJK Ideograph>) 4725 0x7CC4 糄 (<CJK Ideograph>) 4726 0x7CC7 糇 (<CJK Ideograph>) 4727 0x7CC8 糈 (<CJK Ideograph>) 4728 0x7CC9 糉 (<CJK Ideograph>) 4729 0x7CCD 糍 (<CJK Ideograph>) 4730 0x7CCF 糏 (<CJK Ideograph>) 4731 0x7CD3 糓 (<CJK Ideograph>) 4732 0x7CD4 糔 (<CJK Ideograph>) 4733 0x7CD5 糕 (<CJK Ideograph>) 4734 0x7CD7 糗 (<CJK Ideograph>) 4735 0x7CD9 糙 (<CJK Ideograph>) 4736 0x7CDA 糚 (<CJK Ideograph>) 4737 0x7CDD 糝 (<CJK Ideograph>) 4738 0x7CE6 糦 (<CJK Ideograph>) 4739 0x7CE9 糩 (<CJK Ideograph>) 4740 0x7CEB 糫 (<CJK Ideograph>) 4741 0x7CF5 糵 (<CJK Ideograph>) 4742 0x7D03 紃 (<CJK Ideograph>) 4743 0x7D07 紇 (<CJK Ideograph>) 4744 0x7D08 紈 (<CJK Ideograph>) 4745 0x7D09 紉 (<CJK Ideograph>) 4746 0x7D0F 紏 (<CJK Ideograph>) 4747 0x7D11 紑 (<CJK Ideograph>) 4748 0x7D12 紒 (<CJK Ideograph>) 4749 0x7D13 紓 (<CJK Ideograph>) 4750 0x7D16 紖 (<CJK Ideograph>) 4751 0x7D1D 紝 (<CJK Ideograph>) 4752 0x7D1E 紞 (<CJK Ideograph>) 4753 0x7D23 紣 (<CJK Ideograph>) 4754 0x7D26 紦 (<CJK Ideograph>) 4755 0x7D2A 紪 (<CJK Ideograph>) 4756 0x7D2D 紭 (<CJK Ideograph>) 4757 0x7D31 紱 (<CJK Ideograph>) 4758 0x7D3C 紼 (<CJK Ideograph>) 4759 0x7D3D 紽 (<CJK Ideograph>) 4760 0x7D3E 紾 (<CJK Ideograph>) 4761 0x7D40 絀 (<CJK Ideograph>) 4762 0x7D41 絁 (<CJK Ideograph>) 4763 0x7D47 絇 (<CJK Ideograph>) 4764 0x7D48 絈 (<CJK Ideograph>) 4765 0x7D4D 絍 (<CJK Ideograph>) 4766 0x7D51 絑 (<CJK Ideograph>) 4767 0x7D53 絓 (<CJK Ideograph>) 4768 0x7D57 絗 (<CJK Ideograph>) 4769 0x7D59 絙 (<CJK Ideograph>) 4770 0x7D5A 絚 (<CJK Ideograph>) 4771 0x7D5C 絜 (<CJK Ideograph>) 4772 0x7D5D 絝 (<CJK Ideograph>) 4773 0x7D65 絥 (<CJK Ideograph>) 4774 0x7D67 絧 (<CJK Ideograph>) 4775 0x7D6A 絪 (<CJK Ideograph>) 4776 0x7D70 絰 (<CJK Ideograph>) 4777 0x7D78 絸 (<CJK Ideograph>) 4778 0x7D7A 絺 (<CJK Ideograph>) 4779 0x7D7B 絻 (<CJK Ideograph>) 4780 0x7D7F 絿 (<CJK Ideograph>) 4781 0x7D81 綁 (<CJK Ideograph>) 4782 0x7D82 綂 (<CJK Ideograph>) 4783 0x7D83 綃 (<CJK Ideograph>) 4784 0x7D85 綅 (<CJK Ideograph>) 4785 0x7D86 綆 (<CJK Ideograph>) 4786 0x7D88 綈 (<CJK Ideograph>) 4787 0x7D8B 綋 (<CJK Ideograph>) 4788 0x7D8C 綌 (<CJK Ideograph>) 4789 0x7D8D 綍 (<CJK Ideograph>) 4790 0x7D91 綑 (<CJK Ideograph>) 4791 0x7D96 綖 (<CJK Ideograph>) 4792 0x7D97 綗 (<CJK Ideograph>) 4793 0x7D9D 綝 (<CJK Ideograph>) 4794 0x7D9E 綞 (<CJK Ideograph>) 4795 0x7DA6 綦 (<CJK Ideograph>) 4796 0x7DA7 綧 (<CJK Ideograph>) 4797 0x7DAA 綪 (<CJK Ideograph>) 4798 0x7DB3 綳 (<CJK Ideograph>) 4799 0x7DB6 綶 (<CJK Ideograph>) 4800 0x7DB7 綷 (<CJK Ideograph>) 4801 0x7DB9 綹 (<CJK Ideograph>) 4802 0x7DC2 緂 (<CJK Ideograph>) 4803 0x7DC3 緃 (<CJK Ideograph>) 4804 0x7DC4 緄 (<CJK Ideograph>) 4805 0x7DC5 緅 (<CJK Ideograph>) 4806 0x7DC6 緆 (<CJK Ideograph>) 4807 0x7DCC 緌 (<CJK Ideograph>) 4808 0x7DCD 緍 (<CJK Ideograph>) 4809 0x7DCE 緎 (<CJK Ideograph>) 4810 0x7DD7 緗 (<CJK Ideograph>) 4811 0x7DD9 緙 (<CJK Ideograph>) 4812 0x7E00 縀 (<CJK Ideograph>) 4813 0x7DE2 緢 (<CJK Ideograph>) 4814 0x7DE5 緥 (<CJK Ideograph>) 4815 0x7DE6 緦 (<CJK Ideograph>) 4816 0x7DEA 緪 (<CJK Ideograph>) 4817 0x7DEB 緫 (<CJK Ideograph>) 4818 0x7DED 緭 (<CJK Ideograph>) 4819 0x7DF1 緱 (<CJK Ideograph>) 4820 0x7DF5 緵 (<CJK Ideograph>) 4821 0x7DF6 緶 (<CJK Ideograph>) 4822 0x7DF9 緹 (<CJK Ideograph>) 4823 0x7DFA 緺 (<CJK Ideograph>) 4824 0x7E08 縈 (<CJK Ideograph>) 4825 0x7E10 縐 (<CJK Ideograph>) 4826 0x7E11 縑 (<CJK Ideograph>) 4827 0x7E15 縕 (<CJK Ideograph>) 4828 0x7E17 縗 (<CJK Ideograph>) 4829 0x7E1C 縜 (<CJK Ideograph>) 4830 0x7E1D 縝 (<CJK Ideograph>) 4831 0x7E20 縠 (<CJK Ideograph>) 4832 0x7E27 縧 (<CJK Ideograph>) 4833 0x7E28 縨 (<CJK Ideograph>) 4834 0x7E2C 縬 (<CJK Ideograph>) 4835 0x7E2D 縭 (<CJK Ideograph>) 4836 0x7E2F 縯 (<CJK Ideograph>) 4837 0x7E33 縳 (<CJK Ideograph>) 4838 0x7E36 縶 (<CJK Ideograph>) 4839 0x7E3F 縿 (<CJK Ideograph>) 4840 0x7E44 繄 (<CJK Ideograph>) 4841 0x7E45 繅 (<CJK Ideograph>) 4842 0x7E47 繇 (<CJK Ideograph>) 4843 0x7E4E 繎 (<CJK Ideograph>) 4844 0x7E50 繐 (<CJK Ideograph>) 4845 0x7E52 繒 (<CJK Ideograph>) 4846 0x7E58 繘 (<CJK Ideograph>) 4847 0x7E5F 繟 (<CJK Ideograph>) 4848 0x7E61 繡 (<CJK Ideograph>) 4849 0x7E62 繢 (<CJK Ideograph>) 4850 0x7E65 繥 (<CJK Ideograph>) 4851 0x7E6B 繫 (<CJK Ideograph>) 4852 0x7E6E 繮 (<CJK Ideograph>) 4853 0x7E6F 繯 (<CJK Ideograph>) 4854 0x7E73 繳 (<CJK Ideograph>) 4855 0x7E78 繸 (<CJK Ideograph>) 4856 0x7E7E 繾 (<CJK Ideograph>) 4857 0x7E81 纁 (<CJK Ideograph>) 4858 0x7E86 纆 (<CJK Ideograph>) 4859 0x7E87 纇 (<CJK Ideograph>) 4860 0x7E8A 纊 (<CJK Ideograph>) 4861 0x7E8D 纍 (<CJK Ideograph>) 4862 0x7E91 纑 (<CJK Ideograph>) 4863 0x7E95 纕 (<CJK Ideograph>) 4864 0x7E98 纘 (<CJK Ideograph>) 4865 0x7E9A 纚 (<CJK Ideograph>) 4866 0x7E9D 纝 (<CJK Ideograph>) 4867 0x7E9E 纞 (<CJK Ideograph>) 4868 0x7F3C 缼 (<CJK Ideograph>) 4869 0x7F3B 缻 (<CJK Ideograph>) 4870 0x7F3D 缽 (<CJK Ideograph>) 4871 0x7F3E 缾 (<CJK Ideograph>) 4872 0x7F3F 缿 (<CJK Ideograph>) 4873 0x7F43 罃 (<CJK Ideograph>) 4874 0x7F44 罄 (<CJK Ideograph>) 4875 0x7F47 罇 (<CJK Ideograph>) 4876 0x7F4F 罏 (<CJK Ideograph>) 4877 0x7F52 罒 (<CJK Ideograph>) 4878 0x7F53 罓 (<CJK Ideograph>) 4879 0x7F5B 罛 (<CJK Ideograph>) 4880 0x7F5C 罜 (<CJK Ideograph>) 4881 0x7F5D 罝 (<CJK Ideograph>) 4882 0x7F61 罡 (<CJK Ideograph>) 4883 0x7F63 罣 (<CJK Ideograph>) 4884 0x7F64 罤 (<CJK Ideograph>) 4885 0x7F65 罥 (<CJK Ideograph>) 4886 0x7F66 罦 (<CJK Ideograph>) 4887 0x7F6D 罭 (<CJK Ideograph>) 4888 0x7F71 罱 (<CJK Ideograph>) 4889 0x7F7D 罽 (<CJK Ideograph>) 4890 0x7F7E 罾 (<CJK Ideograph>) 4891 0x7F7F 罿 (<CJK Ideograph>) 4892 0x7F80 羀 (<CJK Ideograph>) 4893 0x7F8B 羋 (<CJK Ideograph>) 4894 0x7F8D 羍 (<CJK Ideograph>) 4895 0x7F8F 羏 (<CJK Ideograph>) 4896 0x7F90 羐 (<CJK Ideograph>) 4897 0x7F91 羑 (<CJK Ideograph>) 4898 0x7F96 羖 (<CJK Ideograph>) 4899 0x7F97 羗 (<CJK Ideograph>) 4900 0x7F9C 羜 (<CJK Ideograph>) 4901 0x7FA1 羡 (<CJK Ideograph>) 4902 0x7FA2 羢 (<CJK Ideograph>) 4903 0x7FA6 羦 (<CJK Ideograph>) 4904 0x7FAA 羪 (<CJK Ideograph>) 4905 0x7FAD 羭 (<CJK Ideograph>) 4906 0x7FB4 羴 (<CJK Ideograph>) 4907 0x7FBC 羼 (<CJK Ideograph>) 4908 0x7FBF 羿 (<CJK Ideograph>) 4909 0x7FC0 翀 (<CJK Ideograph>) 4910 0x7FC3 翃 (<CJK Ideograph>) 4911 0x7FC8 翈 (<CJK Ideograph>) 4912 0x7FCE 翎 (<CJK Ideograph>) 4913 0x7FCF 翏 (<CJK Ideograph>) 4914 0x7FDB 翛 (<CJK Ideograph>) 4915 0x7FDF 翟 (<CJK Ideograph>) 4916 0x7FE3 翣 (<CJK Ideograph>) 4917 0x7FE5 翥 (<CJK Ideograph>) 4918 0x7FE8 翨 (<CJK Ideograph>) 4919 0x7FEC 翬 (<CJK Ideograph>) 4920 0x7FEE 翮 (<CJK Ideograph>) 4921 0x7FEF 翯 (<CJK Ideograph>) 4922 0x7FF2 翲 (<CJK Ideograph>) 4923 0x7FFA 翺 (<CJK Ideograph>) 4924 0x7FFD 翽 (<CJK Ideograph>) 4925 0x7FFE 翾 (<CJK Ideograph>) 4926 0x7FFF 翿 (<CJK Ideograph>) 4927 0x8007 耇 (<CJK Ideograph>) 4928 0x8008 耈 (<CJK Ideograph>) 4929 0x800A 耊 (<CJK Ideograph>) 4930 0x800D 耍 (<CJK Ideograph>) 4931 0x800E 耎 (<CJK Ideograph>) 4932 0x800F 耏 (<CJK Ideograph>) 4933 0x8011 耑 (<CJK Ideograph>) 4934 0x8013 耓 (<CJK Ideograph>) 4935 0x8014 耔 (<CJK Ideograph>) 4936 0x8016 耖 (<CJK Ideograph>) 4937 0x801D 耝 (<CJK Ideograph>) 4938 0x801E 耞 (<CJK Ideograph>) 4939 0x801F 耟 (<CJK Ideograph>) 4940 0x8020 耠 (<CJK Ideograph>) 4941 0x8024 耤 (<CJK Ideograph>) 4942 0x8026 耦 (<CJK Ideograph>) 4943 0x802C 耬 (<CJK Ideograph>) 4944 0x802E 耮 (<CJK Ideograph>) 4945 0x8030 耰 (<CJK Ideograph>) 4946 0x8034 耴 (<CJK Ideograph>) 4947 0x8035 耵 (<CJK Ideograph>) 4948 0x8037 耷 (<CJK Ideograph>) 4949 0x8039 耹 (<CJK Ideograph>) 4950 0x803A 耺 (<CJK Ideograph>) 4951 0x803C 耼 (<CJK Ideograph>) 4952 0x803E 耾 (<CJK Ideograph>) 4953 0x8040 聀 (<CJK Ideograph>) 4954 0x8044 聄 (<CJK Ideograph>) 4955 0x8060 聠 (<CJK Ideograph>) 4956 0x8064 聤 (<CJK Ideograph>) 4957 0x8066 聦 (<CJK Ideograph>) 4958 0x806D 聭 (<CJK Ideograph>) 4959 0x8071 聱 (<CJK Ideograph>) 4960 0x8075 聵 (<CJK Ideograph>) 4961 0x8081 肁 (<CJK Ideograph>) 4962 0x8088 肈 (<CJK Ideograph>) 4963 0x808E 肎 (<CJK Ideograph>) 4964 0x809C 肜 (<CJK Ideograph>) 4965 0x809E 肞 (<CJK Ideograph>) 4966 0x80A6 肦 (<CJK Ideograph>) 4967 0x80A7 肧 (<CJK Ideograph>) 4968 0x80AB 肫 (<CJK Ideograph>) 4969 0x80B8 肸 (<CJK Ideograph>) 4970 0x80B9 肹 (<CJK Ideograph>) 4971 0x80C8 胈 (<CJK Ideograph>) 4972 0x80CD 胍 (<CJK Ideograph>) 4973 0x80CF 胏 (<CJK Ideograph>) 4974 0x80D2 胒 (<CJK Ideograph>) 4975 0x80D4 胔 (<CJK Ideograph>) 4976 0x80D5 胕 (<CJK Ideograph>) 4977 0x80D7 胗 (<CJK Ideograph>) 4978 0x80D8 胘 (<CJK Ideograph>) 4979 0x80E0 胠 (<CJK Ideograph>) 4980 0x80ED 胭 (<CJK Ideograph>) 4981 0x80EE 胮 (<CJK Ideograph>) 4982 0x80F0 胰 (<CJK Ideograph>) 4983 0x80F2 胲 (<CJK Ideograph>) 4984 0x80F3 胳 (<CJK Ideograph>) 4985 0x80F6 胶 (<CJK Ideograph>) 4986 0x80F9 胹 (<CJK Ideograph>) 4987 0x80FA 胺 (<CJK Ideograph>) 4988 0x80FE 胾 (<CJK Ideograph>) 4989 0x8103 脃 (<CJK Ideograph>) 4990 0x810B 脋 (<CJK Ideograph>) 4991 0x8116 脖 (<CJK Ideograph>) 4992 0x8117 脗 (<CJK Ideograph>) 4993 0x8118 脘 (<CJK Ideograph>) 4994 0x811C 脜 (<CJK Ideograph>) 4995 0x811E 脞 (<CJK Ideograph>) 4996 0x8120 脠 (<CJK Ideograph>) 4997 0x8124 脤 (<CJK Ideograph>) 4998 0x8127 脧 (<CJK Ideograph>) 4999 0x812C 脬 (<CJK Ideograph>) 5000 0x8130 脰 (<CJK Ideograph>) 5001 0x8135 脵 (<CJK Ideograph>) 5002 0x813A 脺 (<CJK Ideograph>) 5003 0x813C 脼 (<CJK Ideograph>) 5004 0x8145 腅 (<CJK Ideograph>) 5005 0x8147 腇 (<CJK Ideograph>) 5006 0x814A 腊 (<CJK Ideograph>) 5007 0x814C 腌 (<CJK Ideograph>) 5008 0x8152 腒 (<CJK Ideograph>) 5009 0x8157 腗 (<CJK Ideograph>) 5010 0x8160 腠 (<CJK Ideograph>) 5011 0x8161 腡 (<CJK Ideograph>) 5012 0x8167 腧 (<CJK Ideograph>) 5013 0x8168 腨 (<CJK Ideograph>) 5014 0x8169 腩 (<CJK Ideograph>) 5015 0x816D 腭 (<CJK Ideograph>) 5016 0x816F 腯 (<CJK Ideograph>) 5017 0x8177 腷 (<CJK Ideograph>) 5018 0x8181 膁 (<CJK Ideograph>) 5019 0x8190 膐 (<CJK Ideograph>) 5020 0x8184 膄 (<CJK Ideograph>) 5021 0x8185 膅 (<CJK Ideograph>) 5022 0x8186 膆 (<CJK Ideograph>) 5023 0x818B 膋 (<CJK Ideograph>) 5024 0x818E 膎 (<CJK Ideograph>) 5025 0x8196 膖 (<CJK Ideograph>) 5026 0x8198 膘 (<CJK Ideograph>) 5027 0x819B 膛 (<CJK Ideograph>) 5028 0x819E 膞 (<CJK Ideograph>) 5029 0x81A2 膢 (<CJK Ideograph>) 5030 0x81AE 膮 (<CJK Ideograph>) 5031 0x81B2 膲 (<CJK Ideograph>) 5032 0x81B4 膴 (<CJK Ideograph>) 5033 0x81BB 膻 (<CJK Ideograph>) 5034 0x81CB 臋 (<CJK Ideograph>) 5035 0x81C3 臃 (<CJK Ideograph>) 5036 0x81C5 臅 (<CJK Ideograph>) 5037 0x81CA 臊 (<CJK Ideograph>) 5038 0x81CE 臎 (<CJK Ideograph>) 5039 0x81CF 臏 (<CJK Ideograph>) 5040 0x81D5 臕 (<CJK Ideograph>) 5041 0x81D7 臗 (<CJK Ideograph>) 5042 0x81DB 臛 (<CJK Ideograph>) 5043 0x81DD 臝 (<CJK Ideograph>) 5044 0x81DE 臞 (<CJK Ideograph>) 5045 0x81E1 臡 (<CJK Ideograph>) 5046 0x81E4 臤 (<CJK Ideograph>) 5047 0x81EB 臫 (<CJK Ideograph>) 5048 0x81EC 臬 (<CJK Ideograph>) 5049 0x81F0 臰 (<CJK Ideograph>) 5050 0x81F1 臱 (<CJK Ideograph>) 5051 0x81F2 臲 (<CJK Ideograph>) 5052 0x81F5 臵 (<CJK Ideograph>) 5053 0x81F6 臶 (<CJK Ideograph>) 5054 0x81F8 臸 (<CJK Ideograph>) 5055 0x81F9 臹 (<CJK Ideograph>) 5056 0x81FD 臽 (<CJK Ideograph>) 5057 0x81FF 臿 (<CJK Ideograph>) 5058 0x8200 舀 (<CJK Ideograph>) 5059 0x8203 舃 (<CJK Ideograph>) 5060 0x820F 舏 (<CJK Ideograph>) 5061 0x8213 舓 (<CJK Ideograph>) 5062 0x8214 舔 (<CJK Ideograph>) 5063 0x8219 舙 (<CJK Ideograph>) 5064 0x821A 舚 (<CJK Ideograph>) 5065 0x821D 舝 (<CJK Ideograph>) 5066 0x8221 舡 (<CJK Ideograph>) 5067 0x8222 舢 (<CJK Ideograph>) 5068 0x8228 舨 (<CJK Ideograph>) 5069 0x8232 舲 (<CJK Ideograph>) 5070 0x8234 舴 (<CJK Ideograph>) 5071 0x823A 舺 (<CJK Ideograph>) 5072 0x8243 艃 (<CJK Ideograph>) 5073 0x8244 艄 (<CJK Ideograph>) 5074 0x8245 艅 (<CJK Ideograph>) 5075 0x8246 艆 (<CJK Ideograph>) 5076 0x824B 艋 (<CJK Ideograph>) 5077 0x824E 艎 (<CJK Ideograph>) 5078 0x824F 艏 (<CJK Ideograph>) 5079 0x8251 艑 (<CJK Ideograph>) 5080 0x8256 艖 (<CJK Ideograph>) 5081 0x825C 艜 (<CJK Ideograph>) 5082 0x8260 艠 (<CJK Ideograph>) 5083 0x8263 艣 (<CJK Ideograph>) 5084 0x8267 艧 (<CJK Ideograph>) 5085 0x826D 艭 (<CJK Ideograph>) 5086 0x8274 艴 (<CJK Ideograph>) 5087 0x827B 艻 (<CJK Ideograph>) 5088 0x827D 艽 (<CJK Ideograph>) 5089 0x827F 艿 (<CJK Ideograph>) 5090 0x8280 芀 (<CJK Ideograph>) 5091 0x8281 芁 (<CJK Ideograph>) 5092 0x8283 芃 (<CJK Ideograph>) 5093 0x8284 芄 (<CJK Ideograph>) 5094 0x8287 芇 (<CJK Ideograph>) 5095 0x8289 芉 (<CJK Ideograph>) 5096 0x828A 芊 (<CJK Ideograph>) 5097 0x828E 芎 (<CJK Ideograph>) 5098 0x8291 芑 (<CJK Ideograph>) 5099 0x8294 芔 (<CJK Ideograph>) 5100 0x8296 芖 (<CJK Ideograph>) 5101 0x8298 芘 (<CJK Ideograph>) 5102 0x829A 芚 (<CJK Ideograph>) 5103 0x829B 芛 (<CJK Ideograph>) 5104 0x82A0 芠 (<CJK Ideograph>) 5105 0x82A1 芡 (<CJK Ideograph>) 5106 0x82A3 芣 (<CJK Ideograph>) 5107 0x82A4 芤 (<CJK Ideograph>) 5108 0x82A7 芧 (<CJK Ideograph>) 5109 0x82A8 芨 (<CJK Ideograph>) 5110 0x82A9 芩 (<CJK Ideograph>) 5111 0x82AA 芪 (<CJK Ideograph>) 5112 0x82AE 芮 (<CJK Ideograph>) 5113 0x82B0 芰 (<CJK Ideograph>) 5114 0x82B2 芲 (<CJK Ideograph>) 5115 0x82B4 芴 (<CJK Ideograph>) 5116 0x82B7 芷 (<CJK Ideograph>) 5117 0x82BA 芺 (<CJK Ideograph>) 5118 0x82BC 芼 (<CJK Ideograph>) 5119 0x82BE 芾 (<CJK Ideograph>) 5120 0x82BF 芿 (<CJK Ideograph>) 5121 0x82C6 苆 (<CJK Ideograph>) 5122 0x82D0 苐 (<CJK Ideograph>) 5123 0x82D5 苕 (<CJK Ideograph>) 5124 0x82DA 苚 (<CJK Ideograph>) 5125 0x82E0 苠 (<CJK Ideograph>) 5126 0x82E2 苢 (<CJK Ideograph>) 5127 0x82E4 苤 (<CJK Ideograph>) 5128 0x82E8 苨 (<CJK Ideograph>) 5129 0x82EA 苪 (<CJK Ideograph>) 5130 0x82ED 苭 (<CJK Ideograph>) 5131 0x82EF 苯 (<CJK Ideograph>) 5132 0x82F6 苶 (<CJK Ideograph>) 5133 0x82F7 苷 (<CJK Ideograph>) 5134 0x82FD 苽 (<CJK Ideograph>) 5135 0x82FE 苾 (<CJK Ideograph>) 5136 0x8300 茀 (<CJK Ideograph>) 5137 0x8301 茁 (<CJK Ideograph>) 5138 0x8307 茇 (<CJK Ideograph>) 5139 0x8308 茈 (<CJK Ideograph>) 5140 0x830A 茊 (<CJK Ideograph>) 5141 0x830B 茋 (<CJK Ideograph>) 5142 0x8354 荔 (<CJK Ideograph>) 5143 0x831B 茛 (<CJK Ideograph>) 5144 0x831D 茝 (<CJK Ideograph>) 5145 0x831E 茞 (<CJK Ideograph>) 5146 0x831F 茟 (<CJK Ideograph>) 5147 0x8321 茡 (<CJK Ideograph>) 5148 0x8322 茢 (<CJK Ideograph>) 5149 0x832C 茬 (<CJK Ideograph>) 5150 0x832D 茭 (<CJK Ideograph>) 5151 0x832E 茮 (<CJK Ideograph>) 5152 0x8330 茰 (<CJK Ideograph>) 5153 0x8333 茳 (<CJK Ideograph>) 5154 0x8337 茷 (<CJK Ideograph>) 5155 0x833A 茺 (<CJK Ideograph>) 5156 0x833C 茼 (<CJK Ideograph>) 5157 0x833D 茽 (<CJK Ideograph>) 5158 0x8342 荂 (<CJK Ideograph>) 5159 0x8343 荃 (<CJK Ideograph>) 5160 0x8344 荄 (<CJK Ideograph>) 5161 0x8347 荇 (<CJK Ideograph>) 5162 0x834D 荍 (<CJK Ideograph>) 5163 0x834E 荎 (<CJK Ideograph>) 5164 0x8351 荑 (<CJK Ideograph>) 5165 0x8355 荕 (<CJK Ideograph>) 5166 0x8356 荖 (<CJK Ideograph>) 5167 0x8357 荗 (<CJK Ideograph>) 5168 0x8370 荰 (<CJK Ideograph>) 5169 0x8378 荸 (<CJK Ideograph>) 5170 0x837D 荽 (<CJK Ideograph>) 5171 0x837F 荿 (<CJK Ideograph>) 5172 0x8380 莀 (<CJK Ideograph>) 5173 0x8382 莂 (<CJK Ideograph>) 5174 0x8384 莄 (<CJK Ideograph>) 5175 0x8386 莆 (<CJK Ideograph>) 5176 0x838D 莍 (<CJK Ideograph>) 5177 0x8392 莒 (<CJK Ideograph>) 5178 0x8394 莔 (<CJK Ideograph>) 5179 0x8395 莕 (<CJK Ideograph>) 5180 0x8398 莘 (<CJK Ideograph>) 5181 0x8399 莙 (<CJK Ideograph>) 5182 0x839B 莛 (<CJK Ideograph>) 5183 0x839C 莜 (<CJK Ideograph>) 5184 0x839D 莝 (<CJK Ideograph>) 5185 0x83A6 莦 (<CJK Ideograph>) 5186 0x83A7 莧 (<CJK Ideograph>) 5187 0x83A9 莩 (<CJK Ideograph>) 5188 0x83AC 莬 (<CJK Ideograph>) 5189 0x83BE 莾 (<CJK Ideograph>) 5190 0x83BF 莿 (<CJK Ideograph>) 5191 0x83C0 菀 (<CJK Ideograph>) 5192 0x83C7 菇 (<CJK Ideograph>) 5193 0x83C9 菉 (<CJK Ideograph>) 5194 0x83CF 菏 (<CJK Ideograph>) 5195 0x83D0 菐 (<CJK Ideograph>) 5196 0x83D1 菑 (<CJK Ideograph>) 5197 0x83D4 菔 (<CJK Ideograph>) 5198 0x83DD 菝 (<CJK Ideograph>) 5199 0x8353 荓 (<CJK Ideograph>) 5200 0x83E8 菨 (<CJK Ideograph>) 5201 0x83EA 菪 (<CJK Ideograph>) 5202 0x83F6 菶 (<CJK Ideograph>) 5203 0x83F8 菸 (<CJK Ideograph>) 5204 0x83F9 菹 (<CJK Ideograph>) 5205 0x83FC 菼 (<CJK Ideograph>) 5206 0x8401 萁 (<CJK Ideograph>) 5207 0x8406 萆 (<CJK Ideograph>) 5208 0x840A 萊 (<CJK Ideograph>) 5209 0x840F 萏 (<CJK Ideograph>) 5210 0x8411 萑 (<CJK Ideograph>) 5211 0x8415 萕 (<CJK Ideograph>) 5212 0x8419 萙 (<CJK Ideograph>) 5213 0x83AD 莭 (<CJK Ideograph>) 5214 0x842F 萯 (<CJK Ideograph>) 5215 0x8439 萹 (<CJK Ideograph>) 5216 0x8445 葅 (<CJK Ideograph>) 5217 0x8447 葇 (<CJK Ideograph>) 5218 0x8448 葈 (<CJK Ideograph>) 5219 0x844A 葊 (<CJK Ideograph>) 5220 0x844D 葍 (<CJK Ideograph>) 5221 0x844F 葏 (<CJK Ideograph>) 5222 0x8451 葑 (<CJK Ideograph>) 5223 0x8452 葒 (<CJK Ideograph>) 5224 0x8456 葖 (<CJK Ideograph>) 5225 0x8458 葘 (<CJK Ideograph>) 5226 0x8459 葙 (<CJK Ideograph>) 5227 0x845A 葚 (<CJK Ideograph>) 5228 0x845C 葜 (<CJK Ideograph>) 5229 0x8460 葠 (<CJK Ideograph>) 5230 0x8464 葤 (<CJK Ideograph>) 5231 0x8465 葥 (<CJK Ideograph>) 5232 0x8467 葧 (<CJK Ideograph>) 5233 0x846A 葪 (<CJK Ideograph>) 5234 0x8470 葰 (<CJK Ideograph>) 5235 0x8473 葳 (<CJK Ideograph>) 5236 0x8474 葴 (<CJK Ideograph>) 5237 0x8476 葶 (<CJK Ideograph>) 5238 0x8478 葸 (<CJK Ideograph>) 5239 0x847C 葼 (<CJK Ideograph>) 5240 0x847D 葽 (<CJK Ideograph>) 5241 0x8481 蒁 (<CJK Ideograph>) 5242 0x8485 蒅 (<CJK Ideograph>) 5243 0x8492 蒒 (<CJK Ideograph>) 5244 0x8493 蒓 (<CJK Ideograph>) 5245 0x8495 蒕 (<CJK Ideograph>) 5246 0x849E 蒞 (<CJK Ideograph>) 5247 0x84A6 蒦 (<CJK Ideograph>) 5248 0x84A8 蒨 (<CJK Ideograph>) 5249 0x84A9 蒩 (<CJK Ideograph>) 5250 0x84AA 蒪 (<CJK Ideograph>) 5251 0x84AF 蒯 (<CJK Ideograph>) 5252 0x84B1 蒱 (<CJK Ideograph>) 5253 0x84B4 蒴 (<CJK Ideograph>) 5254 0x84BA 蒺 (<CJK Ideograph>) 5255 0x84BD 蒽 (<CJK Ideograph>) 5256 0x84BE 蒾 (<CJK Ideograph>) 5257 0x84C0 蓀 (<CJK Ideograph>) 5258 0x84C2 蓂 (<CJK Ideograph>) 5259 0x84C7 蓇 (<CJK Ideograph>) 5260 0x84C8 蓈 (<CJK Ideograph>) 5261 0x84CC 蓌 (<CJK Ideograph>) 5262 0x84CF 蓏 (<CJK Ideograph>) 5263 0x84D3 蓓 (<CJK Ideograph>) 5264 0x84DC 蓜 (<CJK Ideograph>) 5265 0x84E7 蓧 (<CJK Ideograph>) 5266 0x84EA 蓪 (<CJK Ideograph>) 5267 0x84EF 蓯 (<CJK Ideograph>) 5268 0x84F0 蓰 (<CJK Ideograph>) 5269 0x84F1 蓱 (<CJK Ideograph>) 5270 0x84F2 蓲 (<CJK Ideograph>) 5271 0x84F7 蓷 (<CJK Ideograph>) 5272 0x8532 蔲 (<CJK Ideograph>) 5273 0x84FA 蓺 (<CJK Ideograph>) 5274 0x84FB 蓻 (<CJK Ideograph>) 5275 0x84FD 蓽 (<CJK Ideograph>) 5276 0x8502 蔂 (<CJK Ideograph>) 5277 0x8503 蔃 (<CJK Ideograph>) 5278 0x8507 蔇 (<CJK Ideograph>) 5279 0x850C 蔌 (<CJK Ideograph>) 5280 0x850E 蔎 (<CJK Ideograph>) 5281 0x8510 蔐 (<CJK Ideograph>) 5282 0x851C 蔜 (<CJK Ideograph>) 5283 0x851E 蔞 (<CJK Ideograph>) 5284 0x8522 蔢 (<CJK Ideograph>) 5285 0x8523 蔣 (<CJK Ideograph>) 5286 0x8524 蔤 (<CJK Ideograph>) 5287 0x8525 蔥 (<CJK Ideograph>) 5288 0x8527 蔧 (<CJK Ideograph>) 5289 0x852A 蔪 (<CJK Ideograph>) 5290 0x852B 蔫 (<CJK Ideograph>) 5291 0x852F 蔯 (<CJK Ideograph>) 5292 0x8533 蔳 (<CJK Ideograph>) 5293 0x8534 蔴 (<CJK Ideograph>) 5294 0x8536 蔶 (<CJK Ideograph>) 5295 0x853F 蔿 (<CJK Ideograph>) 5296 0x8546 蕆 (<CJK Ideograph>) 5297 0x854F 蕏 (<CJK Ideograph>) 5298 0x8550 蕐 (<CJK Ideograph>) 5299 0x8551 蕑 (<CJK Ideograph>) 5300 0x8552 蕒 (<CJK Ideograph>) 5301 0x8553 蕓 (<CJK Ideograph>) 5302 0x8556 蕖 (<CJK Ideograph>) 5303 0x8559 蕙 (<CJK Ideograph>) 5304 0x855C 蕜 (<CJK Ideograph>) 5305 0x855D 蕝 (<CJK Ideograph>) 5306 0x855E 蕞 (<CJK Ideograph>) 5307 0x855F 蕟 (<CJK Ideograph>) 5308 0x8560 蕠 (<CJK Ideograph>) 5309 0x8561 蕡 (<CJK Ideograph>) 5310 0x8562 蕢 (<CJK Ideograph>) 5311 0x8564 蕤 (<CJK Ideograph>) 5312 0x856B 蕫 (<CJK Ideograph>) 5313 0x856F 蕯 (<CJK Ideograph>) 5314 0x8579 蕹 (<CJK Ideograph>) 5315 0x857A 蕺 (<CJK Ideograph>) 5316 0x857B 蕻 (<CJK Ideograph>) 5317 0x857D 蕽 (<CJK Ideograph>) 5318 0x857F 蕿 (<CJK Ideograph>) 5319 0x8581 薁 (<CJK Ideograph>) 5320 0x8585 薅 (<CJK Ideograph>) 5321 0x8586 薆 (<CJK Ideograph>) 5322 0x8589 薉 (<CJK Ideograph>) 5323 0x858B 薋 (<CJK Ideograph>) 5324 0x858C 薌 (<CJK Ideograph>) 5325 0x858F 薏 (<CJK Ideograph>) 5326 0x8593 薓 (<CJK Ideograph>) 5327 0x8598 薘 (<CJK Ideograph>) 5328 0x859D 薝 (<CJK Ideograph>) 5329 0x859F 薟 (<CJK Ideograph>) 5330 0x85A0 薠 (<CJK Ideograph>) 5331 0x85A2 薢 (<CJK Ideograph>) 5332 0x85A5 薥 (<CJK Ideograph>) 5333 0x85A7 薧 (<CJK Ideograph>) 5334 0x85B4 薴 (<CJK Ideograph>) 5335 0x85B6 薶 (<CJK Ideograph>) 5336 0x85B7 薷 (<CJK Ideograph>) 5337 0x85B8 薸 (<CJK Ideograph>) 5338 0x85BC 薼 (<CJK Ideograph>) 5339 0x85BD 薽 (<CJK Ideograph>) 5340 0x85BE 薾 (<CJK Ideograph>) 5341 0x85BF 薿 (<CJK Ideograph>) 5342 0x85C2 藂 (<CJK Ideograph>) 5343 0x85C7 藇 (<CJK Ideograph>) 5344 0x85CA 藊 (<CJK Ideograph>) 5345 0x85CB 藋 (<CJK Ideograph>) 5346 0x85CE 藎 (<CJK Ideograph>) 5347 0x85AD 薭 (<CJK Ideograph>) 5348 0x85D8 藘 (<CJK Ideograph>) 5349 0x85DA 藚 (<CJK Ideograph>) 5350 0x85DF 藟 (<CJK Ideograph>) 5351 0x85E0 藠 (<CJK Ideograph>) 5352 0x85E6 藦 (<CJK Ideograph>) 5353 0x85E8 藨 (<CJK Ideograph>) 5354 0x85ED 藭 (<CJK Ideograph>) 5355 0x85F3 藳 (<CJK Ideograph>) 5356 0x85F6 藶 (<CJK Ideograph>) 5357 0x85FC 藼 (<CJK Ideograph>) 5358 0x85FF 藿 (<CJK Ideograph>) 5359 0x8600 蘀 (<CJK Ideograph>) 5360 0x8604 蘄 (<CJK Ideograph>) 5361 0x8605 蘅 (<CJK Ideograph>) 5362 0x860D 蘍 (<CJK Ideograph>) 5363 0x860E 蘎 (<CJK Ideograph>) 5364 0x8610 蘐 (<CJK Ideograph>) 5365 0x8611 蘑 (<CJK Ideograph>) 5366 0x8612 蘒 (<CJK Ideograph>) 5367 0x8618 蘘 (<CJK Ideograph>) 5368 0x8619 蘙 (<CJK Ideograph>) 5369 0x861B 蘛 (<CJK Ideograph>) 5370 0x861E 蘞 (<CJK Ideograph>) 5371 0x8621 蘡 (<CJK Ideograph>) 5372 0x8627 蘧 (<CJK Ideograph>) 5373 0x8629 蘩 (<CJK Ideograph>) 5374 0x8636 蘶 (<CJK Ideograph>) 5375 0x8638 蘸 (<CJK Ideograph>) 5376 0x863A 蘺 (<CJK Ideograph>) 5377 0x863C 蘼 (<CJK Ideograph>) 5378 0x863D 蘽 (<CJK Ideograph>) 5379 0x8640 虀 (<CJK Ideograph>) 5380 0x8642 虂 (<CJK Ideograph>) 5381 0x8646 虆 (<CJK Ideograph>) 5382 0x8652 虒 (<CJK Ideograph>) 5383 0x8653 虓 (<CJK Ideograph>) 5384 0x8656 虖 (<CJK Ideograph>) 5385 0x8657 虗 (<CJK Ideograph>) 5386 0x8658 虘 (<CJK Ideograph>) 5387 0x8659 虙 (<CJK Ideograph>) 5388 0x865D 虝 (<CJK Ideograph>) 5389 0x8660 虠 (<CJK Ideograph>) 5390 0x8661 虡 (<CJK Ideograph>) 5391 0x8662 虢 (<CJK Ideograph>) 5392 0x8663 虣 (<CJK Ideograph>) 5393 0x8664 虤 (<CJK Ideograph>) 5394 0x8669 虩 (<CJK Ideograph>) 5395 0x866C 虬 (<CJK Ideograph>) 5396 0x866F 虯 (<CJK Ideograph>) 5397 0x8675 虵 (<CJK Ideograph>) 5398 0x8676 虶 (<CJK Ideograph>) 5399 0x8677 虷 (<CJK Ideograph>) 5400 0x867A 虺 (<CJK Ideograph>) 5401 0x868D 蚍 (<CJK Ideograph>) 5402 0x8691 蚑 (<CJK Ideograph>) 5403 0x8696 蚖 (<CJK Ideograph>) 5404 0x8698 蚘 (<CJK Ideograph>) 5405 0x869A 蚚 (<CJK Ideograph>) 5406 0x869C 蚜 (<CJK Ideograph>) 5407 0x86A1 蚡 (<CJK Ideograph>) 5408 0x86A6 蚦 (<CJK Ideograph>) 5409 0x86A7 蚧 (<CJK Ideograph>) 5410 0x86A8 蚨 (<CJK Ideograph>) 5411 0x86AD 蚭 (<CJK Ideograph>) 5412 0x86B1 蚱 (<CJK Ideograph>) 5413 0x86B3 蚳 (<CJK Ideograph>) 5414 0x86B4 蚴 (<CJK Ideograph>) 5415 0x86B5 蚵 (<CJK Ideograph>) 5416 0x86B7 蚷 (<CJK Ideograph>) 5417 0x86B8 蚸 (<CJK Ideograph>) 5418 0x86B9 蚹 (<CJK Ideograph>) 5419 0x86BF 蚿 (<CJK Ideograph>) 5420 0x86C0 蛀 (<CJK Ideograph>) 5421 0x86C1 蛁 (<CJK Ideograph>) 5422 0x86C3 蛃 (<CJK Ideograph>) 5423 0x86C5 蛅 (<CJK Ideograph>) 5424 0x86D1 蛑 (<CJK Ideograph>) 5425 0x86D2 蛒 (<CJK Ideograph>) 5426 0x86D5 蛕 (<CJK Ideograph>) 5427 0x86D7 蛗 (<CJK Ideograph>) 5428 0x86DA 蛚 (<CJK Ideograph>) 5429 0x86DC 蛜 (<CJK Ideograph>) 5430 0x86E0 蛠 (<CJK Ideograph>) 5431 0x86E3 蛣 (<CJK Ideograph>) 5432 0x86E5 蛥 (<CJK Ideograph>) 5433 0x86E7 蛧 (<CJK Ideograph>) 5434 0x8688 蚈 (<CJK Ideograph>) 5435 0x86FA 蛺 (<CJK Ideograph>) 5436 0x86FC 蛼 (<CJK Ideograph>) 5437 0x86FD 蛽 (<CJK Ideograph>) 5438 0x8704 蜄 (<CJK Ideograph>) 5439 0x8705 蜅 (<CJK Ideograph>) 5440 0x8707 蜇 (<CJK Ideograph>) 5441 0x870B 蜋 (<CJK Ideograph>) 5442 0x870E 蜎 (<CJK Ideograph>) 5443 0x870F 蜏 (<CJK Ideograph>) 5444 0x8710 蜐 (<CJK Ideograph>) 5445 0x8713 蜓 (<CJK Ideograph>) 5446 0x8714 蜔 (<CJK Ideograph>) 5447 0x8719 蜙 (<CJK Ideograph>) 5448 0x871E 蜞 (<CJK Ideograph>) 5449 0x871F 蜟 (<CJK Ideograph>) 5450 0x8721 蜡 (<CJK Ideograph>) 5451 0x8723 蜣 (<CJK Ideograph>) 5452 0x8728 蜨 (<CJK Ideograph>) 5453 0x872E 蜮 (<CJK Ideograph>) 5454 0x872F 蜯 (<CJK Ideograph>) 5455 0x8731 蜱 (<CJK Ideograph>) 5456 0x8732 蜲 (<CJK Ideograph>) 5457 0x8739 蜹 (<CJK Ideograph>) 5458 0x873A 蜺 (<CJK Ideograph>) 5459 0x873C 蜼 (<CJK Ideograph>) 5460 0x873D 蜽 (<CJK Ideograph>) 5461 0x873E 蜾 (<CJK Ideograph>) 5462 0x8740 蝀 (<CJK Ideograph>) 5463 0x8743 蝃 (<CJK Ideograph>) 5464 0x8745 蝅 (<CJK Ideograph>) 5465 0x874D 蝍 (<CJK Ideograph>) 5466 0x8758 蝘 (<CJK Ideograph>) 5467 0x875D 蝝 (<CJK Ideograph>) 5468 0x8761 蝡 (<CJK Ideograph>) 5469 0x8764 蝤 (<CJK Ideograph>) 5470 0x8765 蝥 (<CJK Ideograph>) 5471 0x876F 蝯 (<CJK Ideograph>) 5472 0x8771 蝱 (<CJK Ideograph>) 5473 0x8772 蝲 (<CJK Ideograph>) 5474 0x877B 蝻 (<CJK Ideograph>) 5475 0x8783 螃 (<CJK Ideograph>) 5476 0x8784 螄 (<CJK Ideograph>) 5477 0x8785 螅 (<CJK Ideograph>) 5478 0x8786 螆 (<CJK Ideograph>) 5479 0x8787 螇 (<CJK Ideograph>) 5480 0x8788 螈 (<CJK Ideograph>) 5481 0x8789 螉 (<CJK Ideograph>) 5482 0x878B 螋 (<CJK Ideograph>) 5483 0x878C 螌 (<CJK Ideograph>) 5484 0x8790 螐 (<CJK Ideograph>) 5485 0x8793 螓 (<CJK Ideograph>) 5486 0x8795 螕 (<CJK Ideograph>) 5487 0x8797 螗 (<CJK Ideograph>) 5488 0x8798 螘 (<CJK Ideograph>) 5489 0x8799 螙 (<CJK Ideograph>) 5490 0x879E 螞 (<CJK Ideograph>) 5491 0x87A0 螠 (<CJK Ideograph>) 5492 0x87A3 螣 (<CJK Ideograph>) 5493 0x87A7 螧 (<CJK Ideograph>) 5494 0x87AC 螬 (<CJK Ideograph>) 5495 0x87AD 螭 (<CJK Ideograph>) 5496 0x87AE 螮 (<CJK Ideograph>) 5497 0x87B1 螱 (<CJK Ideograph>) 5498 0x87B5 螵 (<CJK Ideograph>) 5499 0x87BE 螾 (<CJK Ideograph>) 5500 0x87BF 螿 (<CJK Ideograph>) 5501 0x87C1 蟁 (<CJK Ideograph>) 5502 0x87C8 蟈 (<CJK Ideograph>) 5503 0x87C9 蟉 (<CJK Ideograph>) 5504 0x87CA 蟊 (<CJK Ideograph>) 5505 0x87CE 蟎 (<CJK Ideograph>) 5506 0x87D5 蟕 (<CJK Ideograph>) 5507 0x87D6 蟖 (<CJK Ideograph>) 5508 0x87D9 蟙 (<CJK Ideograph>) 5509 0x87DA 蟚 (<CJK Ideograph>) 5510 0x87DC 蟜 (<CJK Ideograph>) 5511 0x87DF 蟟 (<CJK Ideograph>) 5512 0x87E2 蟢 (<CJK Ideograph>) 5513 0x87E3 蟣 (<CJK Ideograph>) 5514 0x87E4 蟤 (<CJK Ideograph>) 5515 0x87EA 蟪 (<CJK Ideograph>) 5516 0x87EB 蟫 (<CJK Ideograph>) 5517 0x87ED 蟭 (<CJK Ideograph>) 5518 0x87F1 蟱 (<CJK Ideograph>) 5519 0x87F3 蟳 (<CJK Ideograph>) 5520 0x87F8 蟸 (<CJK Ideograph>) 5521 0x87FA 蟺 (<CJK Ideograph>) 5522 0x87FF 蟿 (<CJK Ideograph>) 5523 0x8801 蠁 (<CJK Ideograph>) 5524 0x8803 蠃 (<CJK Ideograph>) 5525 0x8806 蠆 (<CJK Ideograph>) 5526 0x8809 蠉 (<CJK Ideograph>) 5527 0x880A 蠊 (<CJK Ideograph>) 5528 0x880B 蠋 (<CJK Ideograph>) 5529 0x8810 蠐 (<CJK Ideograph>) 5530 0x8819 蠙 (<CJK Ideograph>) 5531 0x8812 蠒 (<CJK Ideograph>) 5532 0x8813 蠓 (<CJK Ideograph>) 5533 0x8814 蠔 (<CJK Ideograph>) 5534 0x8818 蠘 (<CJK Ideograph>) 5535 0x881A 蠚 (<CJK Ideograph>) 5536 0x881B 蠛 (<CJK Ideograph>) 5537 0x881C 蠜 (<CJK Ideograph>) 5538 0x881E 蠞 (<CJK Ideograph>) 5539 0x881F 蠟 (<CJK Ideograph>) 5540 0x8828 蠨 (<CJK Ideograph>) 5541 0x882D 蠭 (<CJK Ideograph>) 5542 0x882E 蠮 (<CJK Ideograph>) 5543 0x8830 蠰 (<CJK Ideograph>) 5544 0x8832 蠲 (<CJK Ideograph>) 5545 0x8835 蠵 (<CJK Ideograph>) 5546 0x883A 蠺 (<CJK Ideograph>) 5547 0x883C 蠼 (<CJK Ideograph>) 5548 0x8841 衁 (<CJK Ideograph>) 5549 0x8843 衃 (<CJK Ideograph>) 5550 0x8845 衅 (<CJK Ideograph>) 5551 0x8848 衈 (<CJK Ideograph>) 5552 0x8849 衉 (<CJK Ideograph>) 5553 0x884A 衊 (<CJK Ideograph>) 5554 0x884B 衋 (<CJK Ideograph>) 5555 0x884E 衎 (<CJK Ideograph>) 5556 0x8851 衑 (<CJK Ideograph>) 5557 0x8855 衕 (<CJK Ideograph>) 5558 0x8856 衖 (<CJK Ideograph>) 5559 0x8858 衘 (<CJK Ideograph>) 5560 0x885A 衚 (<CJK Ideograph>) 5561 0x885C 衜 (<CJK Ideograph>) 5562 0x885F 衟 (<CJK Ideograph>) 5563 0x8860 衠 (<CJK Ideograph>) 5564 0x8864 衤 (<CJK Ideograph>) 5565 0x8869 衩 (<CJK Ideograph>) 5566 0x8871 衱 (<CJK Ideograph>) 5567 0x8879 衹 (<CJK Ideograph>) 5568 0x887B 衻 (<CJK Ideograph>) 5569 0x8880 袀 (<CJK Ideograph>) 5570 0x8898 袘 (<CJK Ideograph>) 5571 0x889A 袚 (<CJK Ideograph>) 5572 0x889B 袛 (<CJK Ideograph>) 5573 0x889C 袜 (<CJK Ideograph>) 5574 0x889F 袟 (<CJK Ideograph>) 5575 0x88A0 袠 (<CJK Ideograph>) 5576 0x88A8 袨 (<CJK Ideograph>) 5577 0x88AA 袪 (<CJK Ideograph>) 5578 0x88BA 袺 (<CJK Ideograph>) 5579 0x88BD 袽 (<CJK Ideograph>) 5580 0x88BE 袾 (<CJK Ideograph>) 5581 0x88C0 裀 (<CJK Ideograph>) 5582 0x88CA 裊 (<CJK Ideograph>) 5583 0x88CB 裋 (<CJK Ideograph>) 5584 0x88CC 裌 (<CJK Ideograph>) 5585 0x88CD 裍 (<CJK Ideograph>) 5586 0x88CE 裎 (<CJK Ideograph>) 5587 0x88D1 裑 (<CJK Ideograph>) 5588 0x88D2 裒 (<CJK Ideograph>) 5589 0x88D3 裓 (<CJK Ideograph>) 5590 0x88DB 裛 (<CJK Ideograph>) 5591 0x88DE 裞 (<CJK Ideograph>) 5592 0x88E7 裧 (<CJK Ideograph>) 5593 0x88EF 裯 (<CJK Ideograph>) 5594 0x88F0 裰 (<CJK Ideograph>) 5595 0x88F1 裱 (<CJK Ideograph>) 5596 0x88F5 裵 (<CJK Ideograph>) 5597 0x88F7 裷 (<CJK Ideograph>) 5598 0x8901 褁 (<CJK Ideograph>) 5599 0x8906 褆 (<CJK Ideograph>) 5600 0x890D 褍 (<CJK Ideograph>) 5601 0x890E 褎 (<CJK Ideograph>) 5602 0x890F 褏 (<CJK Ideograph>) 5603 0x8915 褕 (<CJK Ideograph>) 5604 0x8916 褖 (<CJK Ideograph>) 5605 0x8918 褘 (<CJK Ideograph>) 5606 0x8919 褙 (<CJK Ideograph>) 5607 0x891A 褚 (<CJK Ideograph>) 5608 0x891C 褜 (<CJK Ideograph>) 5609 0x8920 褠 (<CJK Ideograph>) 5610 0x8926 褦 (<CJK Ideograph>) 5611 0x8927 褧 (<CJK Ideograph>) 5612 0x8928 褨 (<CJK Ideograph>) 5613 0x8930 褰 (<CJK Ideograph>) 5614 0x8931 褱 (<CJK Ideograph>) 5615 0x8932 褲 (<CJK Ideograph>) 5616 0x8935 褵 (<CJK Ideograph>) 5617 0x8939 褹 (<CJK Ideograph>) 5618 0x893A 褺 (<CJK Ideograph>) 5619 0x893E 褾 (<CJK Ideograph>) 5620 0x8940 襀 (<CJK Ideograph>) 5621 0x8942 襂 (<CJK Ideograph>) 5622 0x8945 襅 (<CJK Ideograph>) 5623 0x8946 襆 (<CJK Ideograph>) 5624 0x8949 襉 (<CJK Ideograph>) 5625 0x894F 襏 (<CJK Ideograph>) 5626 0x8952 襒 (<CJK Ideograph>) 5627 0x8957 襗 (<CJK Ideograph>) 5628 0x895A 襚 (<CJK Ideograph>) 5629 0x895B 襛 (<CJK Ideograph>) 5630 0x895C 襜 (<CJK Ideograph>) 5631 0x8961 襡 (<CJK Ideograph>) 5632 0x8962 襢 (<CJK Ideograph>) 5633 0x8963 襣 (<CJK Ideograph>) 5634 0x896B 襫 (<CJK Ideograph>) 5635 0x896E 襮 (<CJK Ideograph>) 5636 0x8970 襰 (<CJK Ideograph>) 5637 0x8973 襳 (<CJK Ideograph>) 5638 0x8975 襵 (<CJK Ideograph>) 5639 0x897A 襺 (<CJK Ideograph>) 5640 0x897B 襻 (<CJK Ideograph>) 5641 0x897C 襼 (<CJK Ideograph>) 5642 0x897D 襽 (<CJK Ideograph>) 5643 0x8989 覉 (<CJK Ideograph>) 5644 0x898D 覍 (<CJK Ideograph>) 5645 0x8990 覐 (<CJK Ideograph>) 5646 0x8994 覔 (<CJK Ideograph>) 5647 0x8995 覕 (<CJK Ideograph>) 5648 0x899B 覛 (<CJK Ideograph>) 5649 0x899C 覜 (<CJK Ideograph>) 5650 0x899F 覟 (<CJK Ideograph>) 5651 0x89A0 覠 (<CJK Ideograph>) 5652 0x89A5 覥 (<CJK Ideograph>) 5653 0x89B0 覰 (<CJK Ideograph>) 5654 0x89B4 覴 (<CJK Ideograph>) 5655 0x89B5 覵 (<CJK Ideograph>) 5656 0x89B6 覶 (<CJK Ideograph>) 5657 0x89B7 覷 (<CJK Ideograph>) 5658 0x89BC 覼 (<CJK Ideograph>) 5659 0x89D4 觔 (<CJK Ideograph>) 5660 0x89D5 觕 (<CJK Ideograph>) 5661 0x89D6 觖 (<CJK Ideograph>) 5662 0x89D7 觗 (<CJK Ideograph>) 5663 0x89D8 觘 (<CJK Ideograph>) 5664 0x89E5 觥 (<CJK Ideograph>) 5665 0x89E9 觩 (<CJK Ideograph>) 5666 0x89EB 觫 (<CJK Ideograph>) 5667 0x89ED 觭 (<CJK Ideograph>) 5668 0x89F1 觱 (<CJK Ideograph>) 5669 0x89F3 觳 (<CJK Ideograph>) 5670 0x89F6 觶 (<CJK Ideograph>) 5671 0x89F9 觹 (<CJK Ideograph>) 5672 0x89FD 觽 (<CJK Ideograph>) 5673 0x89FF 觿 (<CJK Ideograph>) 5674 0x8A04 訄 (<CJK Ideograph>) 5675 0x8A05 訅 (<CJK Ideograph>) 5676 0x8A07 訇 (<CJK Ideograph>) 5677 0x8A0F 訏 (<CJK Ideograph>) 5678 0x8A11 訑 (<CJK Ideograph>) 5679 0x8A12 訒 (<CJK Ideograph>) 5680 0x8A14 訔 (<CJK Ideograph>) 5681 0x8A15 訕 (<CJK Ideograph>) 5682 0x8A1E 訞 (<CJK Ideograph>) 5683 0x8A20 訠 (<CJK Ideograph>) 5684 0x8A22 訢 (<CJK Ideograph>) 5685 0x8A24 訤 (<CJK Ideograph>) 5686 0x8A26 訦 (<CJK Ideograph>) 5687 0x8A2B 訫 (<CJK Ideograph>) 5688 0x8A2C 訬 (<CJK Ideograph>) 5689 0x8A2F 訯 (<CJK Ideograph>) 5690 0x8A35 訵 (<CJK Ideograph>) 5691 0x8A37 訷 (<CJK Ideograph>) 5692 0x8A3D 訽 (<CJK Ideograph>) 5693 0x8A3E 訾 (<CJK Ideograph>) 5694 0x8A40 詀 (<CJK Ideograph>) 5695 0x8A43 詃 (<CJK Ideograph>) 5696 0x8A45 詅 (<CJK Ideograph>) 5697 0x8A47 詇 (<CJK Ideograph>) 5698 0x8A49 詉 (<CJK Ideograph>) 5699 0x8A4D 詍 (<CJK Ideograph>) 5700 0x8A4E 詎 (<CJK Ideograph>) 5701 0x8A53 詓 (<CJK Ideograph>) 5702 0x8A56 詖 (<CJK Ideograph>) 5703 0x8A57 詗 (<CJK Ideograph>) 5704 0x8A58 詘 (<CJK Ideograph>) 5705 0x8A5C 詜 (<CJK Ideograph>) 5706 0x8A5D 詝 (<CJK Ideograph>) 5707 0x8A61 詡 (<CJK Ideograph>) 5708 0x8A65 詥 (<CJK Ideograph>) 5709 0x8A67 詧 (<CJK Ideograph>) 5710 0x8A75 詵 (<CJK Ideograph>) 5711 0x8A76 詶 (<CJK Ideograph>) 5712 0x8A77 詷 (<CJK Ideograph>) 5713 0x8A79 詹 (<CJK Ideograph>) 5714 0x8A7A 詺 (<CJK Ideograph>) 5715 0x8A7B 詻 (<CJK Ideograph>) 5716 0x8A7E 詾 (<CJK Ideograph>) 5717 0x8A7F 詿 (<CJK Ideograph>) 5718 0x8A80 誀 (<CJK Ideograph>) 5719 0x8A83 誃 (<CJK Ideograph>) 5720 0x8A86 誆 (<CJK Ideograph>) 5721 0x8A8B 誋 (<CJK Ideograph>) 5722 0x8A8F 誏 (<CJK Ideograph>) 5723 0x8A90 誐 (<CJK Ideograph>) 5724 0x8A92 誒 (<CJK Ideograph>) 5725 0x8A96 誖 (<CJK Ideograph>) 5726 0x8A97 誗 (<CJK Ideograph>) 5727 0x8A99 誙 (<CJK Ideograph>) 5728 0x8A9F 誟 (<CJK Ideograph>) 5729 0x8AA7 誧 (<CJK Ideograph>) 5730 0x8AA9 誩 (<CJK Ideograph>) 5731 0x8AAE 誮 (<CJK Ideograph>) 5732 0x8AAF 誯 (<CJK Ideograph>) 5733 0x8AB3 誳 (<CJK Ideograph>) 5734 0x8AB6 誶 (<CJK Ideograph>) 5735 0x8AB7 誷 (<CJK Ideograph>) 5736 0x8ABB 誻 (<CJK Ideograph>) 5737 0x8ABE 誾 (<CJK Ideograph>) 5738 0x8AC3 諃 (<CJK Ideograph>) 5739 0x8AC6 諆 (<CJK Ideograph>) 5740 0x8AC8 諈 (<CJK Ideograph>) 5741 0x8AC9 諉 (<CJK Ideograph>) 5742 0x8ACA 諊 (<CJK Ideograph>) 5743 0x8AD1 諑 (<CJK Ideograph>) 5744 0x8AD3 諓 (<CJK Ideograph>) 5745 0x8AD4 諔 (<CJK Ideograph>) 5746 0x8AD5 諕 (<CJK Ideograph>) 5747 0x8AD7 諗 (<CJK Ideograph>) 5748 0x8ADD 諝 (<CJK Ideograph>) 5749 0x8ADF 諟 (<CJK Ideograph>) 5750 0x8AEC 諬 (<CJK Ideograph>) 5751 0x8AF0 諰 (<CJK Ideograph>) 5752 0x8AF4 諴 (<CJK Ideograph>) 5753 0x8AF5 諵 (<CJK Ideograph>) 5754 0x8AF6 諶 (<CJK Ideograph>) 5755 0x8AFC 諼 (<CJK Ideograph>) 5756 0x8AFF 諿 (<CJK Ideograph>) 5757 0x8B05 謅 (<CJK Ideograph>) 5758 0x8B06 謆 (<CJK Ideograph>) 5759 0x8B0B 謋 (<CJK Ideograph>) 5760 0x8B11 謑 (<CJK Ideograph>) 5761 0x8B1C 謜 (<CJK Ideograph>) 5762 0x8B1E 謞 (<CJK Ideograph>) 5763 0x8B1F 謟 (<CJK Ideograph>) 5764 0x8B0A 謊 (<CJK Ideograph>) 5765 0x8B2D 謭 (<CJK Ideograph>) 5766 0x8B30 謰 (<CJK Ideograph>) 5767 0x8B37 謷 (<CJK Ideograph>) 5768 0x8B3C 謼 (<CJK Ideograph>) 5769 0x8B42 譂 (<CJK Ideograph>) 5770 0x8B43 譃 (<CJK Ideograph>) 5771 0x8B44 譄 (<CJK Ideograph>) 5772 0x8B45 譅 (<CJK Ideograph>) 5773 0x8B46 譆 (<CJK Ideograph>) 5774 0x8B48 譈 (<CJK Ideograph>) 5775 0x8B52 譒 (<CJK Ideograph>) 5776 0x8B53 譓 (<CJK Ideograph>) 5777 0x8B54 譔 (<CJK Ideograph>) 5778 0x8B59 譙 (<CJK Ideograph>) 5779 0x8B4D 譍 (<CJK Ideograph>) 5780 0x8B5E 譞 (<CJK Ideograph>) 5781 0x8B63 譣 (<CJK Ideograph>) 5782 0x8B6D 譭 (<CJK Ideograph>) 5783 0x8B76 譶 (<CJK Ideograph>) 5784 0x8B78 譸 (<CJK Ideograph>) 5785 0x8B79 譹 (<CJK Ideograph>) 5786 0x8B7C 譼 (<CJK Ideograph>) 5787 0x8B7E 譾 (<CJK Ideograph>) 5788 0x8B81 讁 (<CJK Ideograph>) 5789 0x8B84 讄 (<CJK Ideograph>) 5790 0x8B85 讅 (<CJK Ideograph>) 5791 0x8B8B 讋 (<CJK Ideograph>) 5792 0x8B8D 讍 (<CJK Ideograph>) 5793 0x8B8F 讏 (<CJK Ideograph>) 5794 0x8B94 讔 (<CJK Ideograph>) 5795 0x8B95 讕 (<CJK Ideograph>) 5796 0x8B9C 讜 (<CJK Ideograph>) 5797 0x8B9E 讞 (<CJK Ideograph>) 5798 0x8B9F 讟 (<CJK Ideograph>) 5799 0x8C38 谸 (<CJK Ideograph>) 5800 0x8C39 谹 (<CJK Ideograph>) 5801 0x8C3D 谽 (<CJK Ideograph>) 5802 0x8C3E 谾 (<CJK Ideograph>) 5803 0x8C45 豅 (<CJK Ideograph>) 5804 0x8C47 豇 (<CJK Ideograph>) 5805 0x8C49 豉 (<CJK Ideograph>) 5806 0x8C4B 豋 (<CJK Ideograph>) 5807 0x8C4F 豏 (<CJK Ideograph>) 5808 0x8C51 豑 (<CJK Ideograph>) 5809 0x8C53 豓 (<CJK Ideograph>) 5810 0x8C54 豔 (<CJK Ideograph>) 5811 0x8C57 豗 (<CJK Ideograph>) 5812 0x8C58 豘 (<CJK Ideograph>) 5813 0x8C5B 豛 (<CJK Ideograph>) 5814 0x8C5D 豝 (<CJK Ideograph>) 5815 0x8C59 豙 (<CJK Ideograph>) 5816 0x8C63 豣 (<CJK Ideograph>) 5817 0x8C64 豤 (<CJK Ideograph>) 5818 0x8C66 豦 (<CJK Ideograph>) 5819 0x8C68 豨 (<CJK Ideograph>) 5820 0x8C69 豩 (<CJK Ideograph>) 5821 0x8C6D 豭 (<CJK Ideograph>) 5822 0x8C73 豳 (<CJK Ideograph>) 5823 0x8C75 豵 (<CJK Ideograph>) 5824 0x8C76 豶 (<CJK Ideograph>) 5825 0x8C7B 豻 (<CJK Ideograph>) 5826 0x8C7E 豾 (<CJK Ideograph>) 5827 0x8C86 貆 (<CJK Ideograph>) 5828 0x8C87 貇 (<CJK Ideograph>) 5829 0x8C8B 貋 (<CJK Ideograph>) 5830 0x8C90 貐 (<CJK Ideograph>) 5831 0x8C92 貒 (<CJK Ideograph>) 5832 0x8C93 貓 (<CJK Ideograph>) 5833 0x8C99 貙 (<CJK Ideograph>) 5834 0x8C9B 貛 (<CJK Ideograph>) 5835 0x8C9C 貜 (<CJK Ideograph>) 5836 0x8CA4 貤 (<CJK Ideograph>) 5837 0x8CB9 貹 (<CJK Ideograph>) 5838 0x8CBA 貺 (<CJK Ideograph>) 5839 0x8CC5 賅 (<CJK Ideograph>) 5840 0x8CC6 賆 (<CJK Ideograph>) 5841 0x8CC9 賉 (<CJK Ideograph>) 5842 0x8CCB 賋 (<CJK Ideograph>) 5843 0x8CCF 賏 (<CJK Ideograph>) 5844 0x8CD6 賖 (<CJK Ideograph>) 5845 0x8CD5 賕 (<CJK Ideograph>) 5846 0x8CD9 賙 (<CJK Ideograph>) 5847 0x8CDD 賝 (<CJK Ideograph>) 5848 0x8CE1 賡 (<CJK Ideograph>) 5849 0x8CE8 賨 (<CJK Ideograph>) 5850 0x8CEC 賬 (<CJK Ideograph>) 5851 0x8CEF 賯 (<CJK Ideograph>) 5852 0x8CF0 賰 (<CJK Ideograph>) 5853 0x8CF2 賲 (<CJK Ideograph>) 5854 0x8CF5 賵 (<CJK Ideograph>) 5855 0x8CF7 賷 (<CJK Ideograph>) 5856 0x8CF8 賸 (<CJK Ideograph>) 5857 0x8CFE 賾 (<CJK Ideograph>) 5858 0x8CFF 賿 (<CJK Ideograph>) 5859 0x8D01 贁 (<CJK Ideograph>) 5860 0x8D03 贃 (<CJK Ideograph>) 5861 0x8D09 贉 (<CJK Ideograph>) 5862 0x8D12 贒 (<CJK Ideograph>) 5863 0x8D17 贗 (<CJK Ideograph>) 5864 0x8D1B 贛 (<CJK Ideograph>) 5865 0x8D65 赥 (<CJK Ideograph>) 5866 0x8D69 赩 (<CJK Ideograph>) 5867 0x8D6C 赬 (<CJK Ideograph>) 5868 0x8D6E 赮 (<CJK Ideograph>) 5869 0x8D7F 赿 (<CJK Ideograph>) 5870 0x8D82 趂 (<CJK Ideograph>) 5871 0x8D84 趄 (<CJK Ideograph>) 5872 0x8D88 趈 (<CJK Ideograph>) 5873 0x8D8D 趍 (<CJK Ideograph>) 5874 0x8D90 趐 (<CJK Ideograph>) 5875 0x8D91 趑 (<CJK Ideograph>) 5876 0x8D95 趕 (<CJK Ideograph>) 5877 0x8D9E 趞 (<CJK Ideograph>) 5878 0x8D9F 趟 (<CJK Ideograph>) 5879 0x8DA0 趠 (<CJK Ideograph>) 5880 0x8DA6 趦 (<CJK Ideograph>) 5881 0x8DAB 趫 (<CJK Ideograph>) 5882 0x8DAC 趬 (<CJK Ideograph>) 5883 0x8DAF 趯 (<CJK Ideograph>) 5884 0x8DB2 趲 (<CJK Ideograph>) 5885 0x8DB5 趵 (<CJK Ideograph>) 5886 0x8DB7 趷 (<CJK Ideograph>) 5887 0x8DB9 趹 (<CJK Ideograph>) 5888 0x8DBB 趻 (<CJK Ideograph>) 5889 0x8DC0 跀 (<CJK Ideograph>) 5890 0x8DC5 跅 (<CJK Ideograph>) 5891 0x8DC6 跆 (<CJK Ideograph>) 5892 0x8DC7 跇 (<CJK Ideograph>) 5893 0x8DC8 跈 (<CJK Ideograph>) 5894 0x8DCA 跊 (<CJK Ideograph>) 5895 0x8DCE 跎 (<CJK Ideograph>) 5896 0x8DD1 跑 (<CJK Ideograph>) 5897 0x8DD4 跔 (<CJK Ideograph>) 5898 0x8DD5 跕 (<CJK Ideograph>) 5899 0x8DD7 跗 (<CJK Ideograph>) 5900 0x8DD9 跙 (<CJK Ideograph>) 5901 0x8DE4 跤 (<CJK Ideograph>) 5902 0x8DE5 跥 (<CJK Ideograph>) 5903 0x8DE7 跧 (<CJK Ideograph>) 5904 0x8DEC 跬 (<CJK Ideograph>) 5905 0x8DF0 跰 (<CJK Ideograph>) 5906 0x8DBC 趼 (<CJK Ideograph>) 5907 0x8DF1 跱 (<CJK Ideograph>) 5908 0x8DF2 跲 (<CJK Ideograph>) 5909 0x8DF4 跴 (<CJK Ideograph>) 5910 0x8DFD 跽 (<CJK Ideograph>) 5911 0x8E01 踁 (<CJK Ideograph>) 5912 0x8E04 踄 (<CJK Ideograph>) 5913 0x8E05 踅 (<CJK Ideograph>) 5914 0x8E06 踆 (<CJK Ideograph>) 5915 0x8E0B 踋 (<CJK Ideograph>) 5916 0x8E11 踑 (<CJK Ideograph>) 5917 0x8E14 踔 (<CJK Ideograph>) 5918 0x8E16 踖 (<CJK Ideograph>) 5919 0x8E20 踠 (<CJK Ideograph>) 5920 0x8E21 踡 (<CJK Ideograph>) 5921 0x8E22 踢 (<CJK Ideograph>) 5922 0x8E23 踣 (<CJK Ideograph>) 5923 0x8E26 踦 (<CJK Ideograph>) 5924 0x8E27 踧 (<CJK Ideograph>) 5925 0x8E31 踱 (<CJK Ideograph>) 5926 0x8E33 踳 (<CJK Ideograph>) 5927 0x8E36 踶 (<CJK Ideograph>) 5928 0x8E37 踷 (<CJK Ideograph>) 5929 0x8E38 踸 (<CJK Ideograph>) 5930 0x8E39 踹 (<CJK Ideograph>) 5931 0x8E3D 踽 (<CJK Ideograph>) 5932 0x8E40 蹀 (<CJK Ideograph>) 5933 0x8E41 蹁 (<CJK Ideograph>) 5934 0x8E4B 蹋 (<CJK Ideograph>) 5935 0x8E4D 蹍 (<CJK Ideograph>) 5936 0x8E4E 蹎 (<CJK Ideograph>) 5937 0x8E4F 蹏 (<CJK Ideograph>) 5938 0x8E54 蹔 (<CJK Ideograph>) 5939 0x8E5B 蹛 (<CJK Ideograph>) 5940 0x8E5C 蹜 (<CJK Ideograph>) 5941 0x8E5D 蹝 (<CJK Ideograph>) 5942 0x8E5E 蹞 (<CJK Ideograph>) 5943 0x8E61 蹡 (<CJK Ideograph>) 5944 0x8E62 蹢 (<CJK Ideograph>) 5945 0x8E69 蹩 (<CJK Ideograph>) 5946 0x8E6C 蹬 (<CJK Ideograph>) 5947 0x8E6D 蹭 (<CJK Ideograph>) 5948 0x8E6F 蹯 (<CJK Ideograph>) 5949 0x8E70 蹰 (<CJK Ideograph>) 5950 0x8E71 蹱 (<CJK Ideograph>) 5951 0x8E79 蹹 (<CJK Ideograph>) 5952 0x8E7A 蹺 (<CJK Ideograph>) 5953 0x8E7B 蹻 (<CJK Ideograph>) 5954 0x8E82 躂 (<CJK Ideograph>) 5955 0x8E83 躃 (<CJK Ideograph>) 5956 0x8E89 躉 (<CJK Ideograph>) 5957 0x8E90 躐 (<CJK Ideograph>) 5958 0x8E92 躒 (<CJK Ideograph>) 5959 0x8E95 躕 (<CJK Ideograph>) 5960 0x8E9A 躚 (<CJK Ideograph>) 5961 0x8E9B 躛 (<CJK Ideograph>) 5962 0x8E9D 躝 (<CJK Ideograph>) 5963 0x8E9E 躞 (<CJK Ideograph>) 5964 0x8EA2 躢 (<CJK Ideograph>) 5965 0x8EA7 躧 (<CJK Ideograph>) 5966 0x8EA9 躩 (<CJK Ideograph>) 5967 0x8EAD 躭 (<CJK Ideograph>) 5968 0x8EAE 躮 (<CJK Ideograph>) 5969 0x8EB3 躳 (<CJK Ideograph>) 5970 0x8EB5 躵 (<CJK Ideograph>) 5971 0x8EBA 躺 (<CJK Ideograph>) 5972 0x8EBB 躻 (<CJK Ideograph>) 5973 0x8EC0 軀 (<CJK Ideograph>) 5974 0x8EC1 軁 (<CJK Ideograph>) 5975 0x8EC3 軃 (<CJK Ideograph>) 5976 0x8EC4 軄 (<CJK Ideograph>) 5977 0x8EC7 軇 (<CJK Ideograph>) 5978 0x8ECF 軏 (<CJK Ideograph>) 5979 0x8ED1 軑 (<CJK Ideograph>) 5980 0x8ED4 軔 (<CJK Ideograph>) 5981 0x8EDC 軜 (<CJK Ideograph>) 5982 0x8EE8 軨 (<CJK Ideograph>) 5983 0x8EEE 軮 (<CJK Ideograph>) 5984 0x8EF0 軰 (<CJK Ideograph>) 5985 0x8EF1 軱 (<CJK Ideograph>) 5986 0x8EF7 軷 (<CJK Ideograph>) 5987 0x8EF9 軹 (<CJK Ideograph>) 5988 0x8EFA 軺 (<CJK Ideograph>) 5989 0x8EED 軭 (<CJK Ideograph>) 5990 0x8F00 輀 (<CJK Ideograph>) 5991 0x8F02 輂 (<CJK Ideograph>) 5992 0x8F07 輇 (<CJK Ideograph>) 5993 0x8F08 輈 (<CJK Ideograph>) 5994 0x8F0F 輏 (<CJK Ideograph>) 5995 0x8F10 輐 (<CJK Ideograph>) 5996 0x8F16 輖 (<CJK Ideograph>) 5997 0x8F17 輗 (<CJK Ideograph>) 5998 0x8F18 輘 (<CJK Ideograph>) 5999 0x8F1E 輞 (<CJK Ideograph>) 6000 0x8F20 輠 (<CJK Ideograph>) 6001 0x8F21 輡 (<CJK Ideograph>) 6002 0x8F23 輣 (<CJK Ideograph>) 6003 0x8F25 輥 (<CJK Ideograph>) 6004 0x8F27 輧 (<CJK Ideograph>) 6005 0x8F28 輨 (<CJK Ideograph>) 6006 0x8F2C 輬 (<CJK Ideograph>) 6007 0x8F2D 輭 (<CJK Ideograph>) 6008 0x8F2E 輮 (<CJK Ideograph>) 6009 0x8F34 輴 (<CJK Ideograph>) 6010 0x8F35 輵 (<CJK Ideograph>) 6011 0x8F36 輶 (<CJK Ideograph>) 6012 0x8F37 輷 (<CJK Ideograph>) 6013 0x8F3A 輺 (<CJK Ideograph>) 6014 0x8F40 轀 (<CJK Ideograph>) 6015 0x8F41 轁 (<CJK Ideograph>) 6016 0x8F43 轃 (<CJK Ideograph>) 6017 0x8F47 轇 (<CJK Ideograph>) 6018 0x8F4F 轏 (<CJK Ideograph>) 6019 0x8F51 轑 (<CJK Ideograph>) 6020 0x8F52 轒 (<CJK Ideograph>) 6021 0x8F53 轓 (<CJK Ideograph>) 6022 0x8F54 轔 (<CJK Ideograph>) 6023 0x8F55 轕 (<CJK Ideograph>) 6024 0x8F58 轘 (<CJK Ideograph>) 6025 0x8F5D 轝 (<CJK Ideograph>) 6026 0x8F5E 轞 (<CJK Ideograph>) 6027 0x8F65 轥 (<CJK Ideograph>) 6028 0x8F9D 辝 (<CJK Ideograph>) 6029 0x8FA0 辠 (<CJK Ideograph>) 6030 0x8FA1 辡 (<CJK Ideograph>) 6031 0x8FA4 辤 (<CJK Ideograph>) 6032 0x8FA5 辥 (<CJK Ideograph>) 6033 0x8FA6 辦 (<CJK Ideograph>) 6034 0x8FB5 辵 (<CJK Ideograph>) 6035 0x8FB6 辶 (<CJK Ideograph>) 6036 0x8FB8 辸 (<CJK Ideograph>) 6037 0x8FBE 达 (<CJK Ideograph>) 6038 0x8FC0 迀 (<CJK Ideograph>) 6039 0x8FC1 迁 (<CJK Ideograph>) 6040 0x8FC6 迆 (<CJK Ideograph>) 6041 0x8FCA 迊 (<CJK Ideograph>) 6042 0x8FCB 迋 (<CJK Ideograph>) 6043 0x8FCD 迍 (<CJK Ideograph>) 6044 0x8FD0 运 (<CJK Ideograph>) 6045 0x8FD2 迒 (<CJK Ideograph>) 6046 0x8FD3 迓 (<CJK Ideograph>) 6047 0x8FD5 迕 (<CJK Ideograph>) 6048 0x8FE0 迠 (<CJK Ideograph>) 6049 0x8FE3 迣 (<CJK Ideograph>) 6050 0x8FE4 迤 (<CJK Ideograph>) 6051 0x8FE8 迨 (<CJK Ideograph>) 6052 0x8FEE 迮 (<CJK Ideograph>) 6053 0x8FF1 迱 (<CJK Ideograph>) 6054 0x8FF5 迵 (<CJK Ideograph>) 6055 0x8FF6 迶 (<CJK Ideograph>) 6056 0x8FFB 迻 (<CJK Ideograph>) 6057 0x8FFE 迾 (<CJK Ideograph>) 6058 0x9002 适 (<CJK Ideograph>) 6059 0x9004 逄 (<CJK Ideograph>) 6060 0x9008 逈 (<CJK Ideograph>) 6061 0x900C 逌 (<CJK Ideograph>) 6062 0x9018 逘 (<CJK Ideograph>) 6063 0x901B 逛 (<CJK Ideograph>) 6064 0x9028 逨 (<CJK Ideograph>) 6065 0x9029 逩 (<CJK Ideograph>) 6066 0x902F 逯 (<CJK Ideograph>) 6067 0x902A 逪 (<CJK Ideograph>) 6068 0x902C 逬 (<CJK Ideograph>) 6069 0x902D 逭 (<CJK Ideograph>) 6070 0x9033 逳 (<CJK Ideograph>) 6071 0x9034 逴 (<CJK Ideograph>) 6072 0x9037 逷 (<CJK Ideograph>) 6073 0x903F 逿 (<CJK Ideograph>) 6074 0x9043 遃 (<CJK Ideograph>) 6075 0x9044 遄 (<CJK Ideograph>) 6076 0x904C 遌 (<CJK Ideograph>) 6077 0x905B 遛 (<CJK Ideograph>) 6078 0x905D 遝 (<CJK Ideograph>) 6079 0x9062 遢 (<CJK Ideograph>) 6080 0x9066 遦 (<CJK Ideograph>) 6081 0x9067 遧 (<CJK Ideograph>) 6082 0x906C 遬 (<CJK Ideograph>) 6083 0x9070 遰 (<CJK Ideograph>) 6084 0x9074 遴 (<CJK Ideograph>) 6085 0x9079 遹 (<CJK Ideograph>) 6086 0x9085 邅 (<CJK Ideograph>) 6087 0x9088 邈 (<CJK Ideograph>) 6088 0x908B 邋 (<CJK Ideograph>) 6089 0x908C 邌 (<CJK Ideograph>) 6090 0x908E 邎 (<CJK Ideograph>) 6091 0x9090 邐 (<CJK Ideograph>) 6092 0x9095 邕 (<CJK Ideograph>) 6093 0x9097 邗 (<CJK Ideograph>) 6094 0x9098 邘 (<CJK Ideograph>) 6095 0x9099 邙 (<CJK Ideograph>) 6096 0x909B 邛 (<CJK Ideograph>) 6097 0x90A0 邠 (<CJK Ideograph>) 6098 0x90A1 邡 (<CJK Ideograph>) 6099 0x90A2 邢 (<CJK Ideograph>) 6100 0x90A5 邥 (<CJK Ideograph>) 6101 0x90B0 邰 (<CJK Ideograph>) 6102 0x90B2 邲 (<CJK Ideograph>) 6103 0x90B3 邳 (<CJK Ideograph>) 6104 0x90B4 邴 (<CJK Ideograph>) 6105 0x90B6 邶 (<CJK Ideograph>) 6106 0x90BD 邽 (<CJK Ideograph>) 6107 0x90CC 郌 (<CJK Ideograph>) 6108 0x90BE 邾 (<CJK Ideograph>) 6109 0x90C3 郃 (<CJK Ideograph>) 6110 0x90C4 郄 (<CJK Ideograph>) 6111 0x90C5 郅 (<CJK Ideograph>) 6112 0x90C7 郇 (<CJK Ideograph>) 6113 0x90C8 郈 (<CJK Ideograph>) 6114 0x90D5 郕 (<CJK Ideograph>) 6115 0x90D7 郗 (<CJK Ideograph>) 6116 0x90D8 郘 (<CJK Ideograph>) 6117 0x90D9 郙 (<CJK Ideograph>) 6118 0x90DC 郜 (<CJK Ideograph>) 6119 0x90DD 郝 (<CJK Ideograph>) 6120 0x90DF 郟 (<CJK Ideograph>) 6121 0x90E5 郥 (<CJK Ideograph>) 6122 0x90D2 郒 (<CJK Ideograph>) 6123 0x90F6 郶 (<CJK Ideograph>) 6124 0x90EB 郫 (<CJK Ideograph>) 6125 0x90EF 郯 (<CJK Ideograph>) 6126 0x90F0 郰 (<CJK Ideograph>) 6127 0x90F4 郴 (<CJK Ideograph>) 6128 0x90FE 郾 (<CJK Ideograph>) 6129 0x90FF 郿 (<CJK Ideograph>) 6130 0x9100 鄀 (<CJK Ideograph>) 6131 0x9104 鄄 (<CJK Ideograph>) 6132 0x9105 鄅 (<CJK Ideograph>) 6133 0x9106 鄆 (<CJK Ideograph>) 6134 0x9108 鄈 (<CJK Ideograph>) 6135 0x910D 鄍 (<CJK Ideograph>) 6136 0x9110 鄐 (<CJK Ideograph>) 6137 0x9114 鄔 (<CJK Ideograph>) 6138 0x9116 鄖 (<CJK Ideograph>) 6139 0x9117 鄗 (<CJK Ideograph>) 6140 0x9118 鄘 (<CJK Ideograph>) 6141 0x911A 鄚 (<CJK Ideograph>) 6142 0x911C 鄜 (<CJK Ideograph>) 6143 0x911E 鄞 (<CJK Ideograph>) 6144 0x9120 鄠 (<CJK Ideograph>) 6145 0x9125 鄥 (<CJK Ideograph>) 6146 0x9122 鄢 (<CJK Ideograph>) 6147 0x9123 鄣 (<CJK Ideograph>) 6148 0x9127 鄧 (<CJK Ideograph>) 6149 0x9129 鄩 (<CJK Ideograph>) 6150 0x912E 鄮 (<CJK Ideograph>) 6151 0x912F 鄯 (<CJK Ideograph>) 6152 0x9131 鄱 (<CJK Ideograph>) 6153 0x9134 鄴 (<CJK Ideograph>) 6154 0x9136 鄶 (<CJK Ideograph>) 6155 0x9137 鄷 (<CJK Ideograph>) 6156 0x9139 鄹 (<CJK Ideograph>) 6157 0x913A 鄺 (<CJK Ideograph>) 6158 0x913C 鄼 (<CJK Ideograph>) 6159 0x913D 鄽 (<CJK Ideograph>) 6160 0x9143 酃 (<CJK Ideograph>) 6161 0x9147 酇 (<CJK Ideograph>) 6162 0x9148 酈 (<CJK Ideograph>) 6163 0x914F 酏 (<CJK Ideograph>) 6164 0x9153 酓 (<CJK Ideograph>) 6165 0x9157 酗 (<CJK Ideograph>) 6166 0x9159 酙 (<CJK Ideograph>) 6167 0x915A 酚 (<CJK Ideograph>) 6168 0x915B 酛 (<CJK Ideograph>) 6169 0x9161 酡 (<CJK Ideograph>) 6170 0x9164 酤 (<CJK Ideograph>) 6171 0x9167 酧 (<CJK Ideograph>) 6172 0x916D 酭 (<CJK Ideograph>) 6173 0x9174 酴 (<CJK Ideograph>) 6174 0x9179 酹 (<CJK Ideograph>) 6175 0x917A 酺 (<CJK Ideograph>) 6176 0x917B 酻 (<CJK Ideograph>) 6177 0x9181 醁 (<CJK Ideograph>) 6178 0x9183 醃 (<CJK Ideograph>) 6179 0x9185 醅 (<CJK Ideograph>) 6180 0x9186 醆 (<CJK Ideograph>) 6181 0x918A 醊 (<CJK Ideograph>) 6182 0x918E 醎 (<CJK Ideograph>) 6183 0x9191 醑 (<CJK Ideograph>) 6184 0x9193 醓 (<CJK Ideograph>) 6185 0x9194 醔 (<CJK Ideograph>) 6186 0x9195 醕 (<CJK Ideograph>) 6187 0x9198 醘 (<CJK Ideograph>) 6188 0x919E 醞 (<CJK Ideograph>) 6189 0x91A1 醡 (<CJK Ideograph>) 6190 0x91A6 醦 (<CJK Ideograph>) 6191 0x91A8 醨 (<CJK Ideograph>) 6192 0x91AC 醬 (<CJK Ideograph>) 6193 0x91AD 醭 (<CJK Ideograph>) 6194 0x91AE 醮 (<CJK Ideograph>) 6195 0x91B0 醰 (<CJK Ideograph>) 6196 0x91B1 醱 (<CJK Ideograph>) 6197 0x91B2 醲 (<CJK Ideograph>) 6198 0x91B3 醳 (<CJK Ideograph>) 6199 0x91B6 醶 (<CJK Ideograph>) 6200 0x91BB 醻 (<CJK Ideograph>) 6201 0x91BC 醼 (<CJK Ideograph>) 6202 0x91BD 醽 (<CJK Ideograph>) 6203 0x91BF 醿 (<CJK Ideograph>) 6204 0x91C2 釂 (<CJK Ideograph>) 6205 0x91C3 釃 (<CJK Ideograph>) 6206 0x91C5 釅 (<CJK Ideograph>) 6207 0x91D3 釓 (<CJK Ideograph>) 6208 0x91D4 釔 (<CJK Ideograph>) 6209 0x91D7 釗 (<CJK Ideograph>) 6210 0x91D9 釙 (<CJK Ideograph>) 6211 0x91DA 釚 (<CJK Ideograph>) 6212 0x91DE 釞 (<CJK Ideograph>) 6213 0x91E4 釤 (<CJK Ideograph>) 6214 0x91E5 釥 (<CJK Ideograph>) 6215 0x91E9 釩 (<CJK Ideograph>) 6216 0x91EA 釪 (<CJK Ideograph>) 6217 0x91EC 釬 (<CJK Ideograph>) 6218 0x91ED 釭 (<CJK Ideograph>) 6219 0x91EE 釮 (<CJK Ideograph>) 6220 0x91EF 釯 (<CJK Ideograph>) 6221 0x91F0 釰 (<CJK Ideograph>) 6222 0x91F1 釱 (<CJK Ideograph>) 6223 0x91F7 釷 (<CJK Ideograph>) 6224 0x91F9 釹 (<CJK Ideograph>) 6225 0x91FB 釻 (<CJK Ideograph>) 6226 0x91FD 釽 (<CJK Ideograph>) 6227 0x9200 鈀 (<CJK Ideograph>) 6228 0x9201 鈁 (<CJK Ideograph>) 6229 0x9204 鈄 (<CJK Ideograph>) 6230 0x9205 鈅 (<CJK Ideograph>) 6231 0x9206 鈆 (<CJK Ideograph>) 6232 0x9207 鈇 (<CJK Ideograph>) 6233 0x9209 鈉 (<CJK Ideograph>) 6234 0x920A 鈊 (<CJK Ideograph>) 6235 0x920C 鈌 (<CJK Ideograph>) 6236 0x9210 鈐 (<CJK Ideograph>) 6237 0x9212 鈒 (<CJK Ideograph>) 6238 0x9213 鈓 (<CJK Ideograph>) 6239 0x9216 鈖 (<CJK Ideograph>) 6240 0x9218 鈘 (<CJK Ideograph>) 6241 0x921C 鈜 (<CJK Ideograph>) 6242 0x921D 鈝 (<CJK Ideograph>) 6243 0x9223 鈣 (<CJK Ideograph>) 6244 0x9224 鈤 (<CJK Ideograph>) 6245 0x9225 鈥 (<CJK Ideograph>) 6246 0x9226 鈦 (<CJK Ideograph>) 6247 0x9228 鈨 (<CJK Ideograph>) 6248 0x922E 鈮 (<CJK Ideograph>) 6249 0x922F 鈯 (<CJK Ideograph>) 6250 0x9230 鈰 (<CJK Ideograph>) 6251 0x9233 鈳 (<CJK Ideograph>) 6252 0x9235 鈵 (<CJK Ideograph>) 6253 0x9236 鈶 (<CJK Ideograph>) 6254 0x9238 鈸 (<CJK Ideograph>) 6255 0x9239 鈹 (<CJK Ideograph>) 6256 0x923A 鈺 (<CJK Ideograph>) 6257 0x923C 鈼 (<CJK Ideograph>) 6258 0x923E 鈾 (<CJK Ideograph>) 6259 0x9240 鉀 (<CJK Ideograph>) 6260 0x9242 鉂 (<CJK Ideograph>) 6261 0x9243 鉃 (<CJK Ideograph>) 6262 0x9246 鉆 (<CJK Ideograph>) 6263 0x9247 鉇 (<CJK Ideograph>) 6264 0x924A 鉊 (<CJK Ideograph>) 6265 0x924D 鉍 (<CJK Ideograph>) 6266 0x924E 鉎 (<CJK Ideograph>) 6267 0x924F 鉏 (<CJK Ideograph>) 6268 0x9251 鉑 (<CJK Ideograph>) 6269 0x9258 鉘 (<CJK Ideograph>) 6270 0x9259 鉙 (<CJK Ideograph>) 6271 0x925C 鉜 (<CJK Ideograph>) 6272 0x925D 鉝 (<CJK Ideograph>) 6273 0x9260 鉠 (<CJK Ideograph>) 6274 0x9261 鉡 (<CJK Ideograph>) 6275 0x9265 鉥 (<CJK Ideograph>) 6276 0x9267 鉧 (<CJK Ideograph>) 6277 0x9268 鉨 (<CJK Ideograph>) 6278 0x9269 鉩 (<CJK Ideograph>) 6279 0x926E 鉮 (<CJK Ideograph>) 6280 0x926F 鉯 (<CJK Ideograph>) 6281 0x9270 鉰 (<CJK Ideograph>) 6282 0x9275 鉵 (<CJK Ideograph>) 6283 0x9276 鉶 (<CJK Ideograph>) 6284 0x9277 鉷 (<CJK Ideograph>) 6285 0x9278 鉸 (<CJK Ideograph>) 6286 0x9279 鉹 (<CJK Ideograph>) 6287 0x927B 鉻 (<CJK Ideograph>) 6288 0x927C 鉼 (<CJK Ideograph>) 6289 0x927D 鉽 (<CJK Ideograph>) 6290 0x927F 鉿 (<CJK Ideograph>) 6291 0x9288 銈 (<CJK Ideograph>) 6292 0x9289 銉 (<CJK Ideograph>) 6293 0x928A 銊 (<CJK Ideograph>) 6294 0x928D 銍 (<CJK Ideograph>) 6295 0x928E 銎 (<CJK Ideograph>) 6296 0x9292 銒 (<CJK Ideograph>) 6297 0x9297 銗 (<CJK Ideograph>) 6298 0x9299 銙 (<CJK Ideograph>) 6299 0x929F 銟 (<CJK Ideograph>) 6300 0x92A0 銠 (<CJK Ideograph>) 6301 0x92A4 銤 (<CJK Ideograph>) 6302 0x92A5 銥 (<CJK Ideograph>) 6303 0x92A7 銧 (<CJK Ideograph>) 6304 0x92A8 銨 (<CJK Ideograph>) 6305 0x92AB 銫 (<CJK Ideograph>) 6306 0x92AF 銯 (<CJK Ideograph>) 6307 0x92B2 銲 (<CJK Ideograph>) 6308 0x92B6 銶 (<CJK Ideograph>) 6309 0x92B8 銸 (<CJK Ideograph>) 6310 0x92BA 銺 (<CJK Ideograph>) 6311 0x92BB 銻 (<CJK Ideograph>) 6312 0x92BC 銼 (<CJK Ideograph>) 6313 0x92BD 銽 (<CJK Ideograph>) 6314 0x92BF 銿 (<CJK Ideograph>) 6315 0x92C0 鋀 (<CJK Ideograph>) 6316 0x92C1 鋁 (<CJK Ideograph>) 6317 0x92C2 鋂 (<CJK Ideograph>) 6318 0x92C3 鋃 (<CJK Ideograph>) 6319 0x92C5 鋅 (<CJK Ideograph>) 6320 0x92C6 鋆 (<CJK Ideograph>) 6321 0x92C7 鋇 (<CJK Ideograph>) 6322 0x92C8 鋈 (<CJK Ideograph>) 6323 0x92CB 鋋 (<CJK Ideograph>) 6324 0x92CC 鋌 (<CJK Ideograph>) 6325 0x92CD 鋍 (<CJK Ideograph>) 6326 0x92CE 鋎 (<CJK Ideograph>) 6327 0x92D0 鋐 (<CJK Ideograph>) 6328 0x92D3 鋓 (<CJK Ideograph>) 6329 0x92D5 鋕 (<CJK Ideograph>) 6330 0x92D7 鋗 (<CJK Ideograph>) 6331 0x92D8 鋘 (<CJK Ideograph>) 6332 0x92D9 鋙 (<CJK Ideograph>) 6333 0x92DC 鋜 (<CJK Ideograph>) 6334 0x92DD 鋝 (<CJK Ideograph>) 6335 0x92DF 鋟 (<CJK Ideograph>) 6336 0x92E0 鋠 (<CJK Ideograph>) 6337 0x92E1 鋡 (<CJK Ideograph>) 6338 0x92E3 鋣 (<CJK Ideograph>) 6339 0x92E5 鋥 (<CJK Ideograph>) 6340 0x92E7 鋧 (<CJK Ideograph>) 6341 0x92E8 鋨 (<CJK Ideograph>) 6342 0x92EC 鋬 (<CJK Ideograph>) 6343 0x92EE 鋮 (<CJK Ideograph>) 6344 0x92F0 鋰 (<CJK Ideograph>) 6345 0x92F9 鋹 (<CJK Ideograph>) 6346 0x92FB 鋻 (<CJK Ideograph>) 6347 0x92FF 鋿 (<CJK Ideograph>) 6348 0x9300 錀 (<CJK Ideograph>) 6349 0x9302 錂 (<CJK Ideograph>) 6350 0x9308 錈 (<CJK Ideograph>) 6351 0x930D 錍 (<CJK Ideograph>) 6352 0x9311 錑 (<CJK Ideograph>) 6353 0x9314 錔 (<CJK Ideograph>) 6354 0x9315 錕 (<CJK Ideograph>) 6355 0x931C 錜 (<CJK Ideograph>) 6356 0x931D 錝 (<CJK Ideograph>) 6357 0x931E 錞 (<CJK Ideograph>) 6358 0x931F 錟 (<CJK Ideograph>) 6359 0x9321 錡 (<CJK Ideograph>) 6360 0x9324 錤 (<CJK Ideograph>) 6361 0x9325 錥 (<CJK Ideograph>) 6362 0x9327 錧 (<CJK Ideograph>) 6363 0x9329 錩 (<CJK Ideograph>) 6364 0x932A 錪 (<CJK Ideograph>) 6365 0x9333 錳 (<CJK Ideograph>) 6366 0x9334 錴 (<CJK Ideograph>) 6367 0x9336 錶 (<CJK Ideograph>) 6368 0x9337 錷 (<CJK Ideograph>) 6369 0x9347 鍇 (<CJK Ideograph>) 6370 0x9348 鍈 (<CJK Ideograph>) 6371 0x9349 鍉 (<CJK Ideograph>) 6372 0x9350 鍐 (<CJK Ideograph>) 6373 0x9351 鍑 (<CJK Ideograph>) 6374 0x9352 鍒 (<CJK Ideograph>) 6375 0x9355 鍕 (<CJK Ideograph>) 6376 0x9357 鍗 (<CJK Ideograph>) 6377 0x9358 鍘 (<CJK Ideograph>) 6378 0x935A 鍚 (<CJK Ideograph>) 6379 0x935E 鍞 (<CJK Ideograph>) 6380 0x9364 鍤 (<CJK Ideograph>) 6381 0x9365 鍥 (<CJK Ideograph>) 6382 0x9367 鍧 (<CJK Ideograph>) 6383 0x9369 鍩 (<CJK Ideograph>) 6384 0x936A 鍪 (<CJK Ideograph>) 6385 0x936D 鍭 (<CJK Ideograph>) 6386 0x936F 鍯 (<CJK Ideograph>) 6387 0x9370 鍰 (<CJK Ideograph>) 6388 0x9371 鍱 (<CJK Ideograph>) 6389 0x9373 鍳 (<CJK Ideograph>) 6390 0x9374 鍴 (<CJK Ideograph>) 6391 0x9376 鍶 (<CJK Ideograph>) 6392 0x937A 鍺 (<CJK Ideograph>) 6393 0x937D 鍽 (<CJK Ideograph>) 6394 0x937F 鍿 (<CJK Ideograph>) 6395 0x9380 鎀 (<CJK Ideograph>) 6396 0x9381 鎁 (<CJK Ideograph>) 6397 0x9382 鎂 (<CJK Ideograph>) 6398 0x9388 鎈 (<CJK Ideograph>) 6399 0x938A 鎊 (<CJK Ideograph>) 6400 0x938B 鎋 (<CJK Ideograph>) 6401 0x938D 鎍 (<CJK Ideograph>) 6402 0x938F 鎏 (<CJK Ideograph>) 6403 0x9392 鎒 (<CJK Ideograph>) 6404 0x9395 鎕 (<CJK Ideograph>) 6405 0x9398 鎘 (<CJK Ideograph>) 6406 0x939B 鎛 (<CJK Ideograph>) 6407 0x939E 鎞 (<CJK Ideograph>) 6408 0x93A1 鎡 (<CJK Ideograph>) 6409 0x93A3 鎣 (<CJK Ideograph>) 6410 0x93A4 鎤 (<CJK Ideograph>) 6411 0x93A6 鎦 (<CJK Ideograph>) 6412 0x93A8 鎨 (<CJK Ideograph>) 6413 0x93AB 鎫 (<CJK Ideograph>) 6414 0x93B4 鎴 (<CJK Ideograph>) 6415 0x93B5 鎵 (<CJK Ideograph>) 6416 0x93B6 鎶 (<CJK Ideograph>) 6417 0x93BA 鎺 (<CJK Ideograph>) 6418 0x93A9 鎩 (<CJK Ideograph>) 6419 0x93C1 鏁 (<CJK Ideograph>) 6420 0x93C4 鏄 (<CJK Ideograph>) 6421 0x93C5 鏅 (<CJK Ideograph>) 6422 0x93C6 鏆 (<CJK Ideograph>) 6423 0x93C7 鏇 (<CJK Ideograph>) 6424 0x93C9 鏉 (<CJK Ideograph>) 6425 0x93CA 鏊 (<CJK Ideograph>) 6426 0x93CB 鏋 (<CJK Ideograph>) 6427 0x93CC 鏌 (<CJK Ideograph>) 6428 0x93CD 鏍 (<CJK Ideograph>) 6429 0x93D3 鏓 (<CJK Ideograph>) 6430 0x93D9 鏙 (<CJK Ideograph>) 6431 0x93DC 鏜 (<CJK Ideograph>) 6432 0x93DE 鏞 (<CJK Ideograph>) 6433 0x93DF 鏟 (<CJK Ideograph>) 6434 0x93E2 鏢 (<CJK Ideograph>) 6435 0x93E6 鏦 (<CJK Ideograph>) 6436 0x93E7 鏧 (<CJK Ideograph>) 6437 0x93F9 鏹 (<CJK Ideograph>) 6438 0x93F7 鏷 (<CJK Ideograph>) 6439 0x93F8 鏸 (<CJK Ideograph>) 6440 0x93FA 鏺 (<CJK Ideograph>) 6441 0x93FB 鏻 (<CJK Ideograph>) 6442 0x93FD 鏽 (<CJK Ideograph>) 6443 0x9401 鐁 (<CJK Ideograph>) 6444 0x9402 鐂 (<CJK Ideograph>) 6445 0x9404 鐄 (<CJK Ideograph>) 6446 0x9408 鐈 (<CJK Ideograph>) 6447 0x9409 鐉 (<CJK Ideograph>) 6448 0x940D 鐍 (<CJK Ideograph>) 6449 0x940E 鐎 (<CJK Ideograph>) 6450 0x940F 鐏 (<CJK Ideograph>) 6451 0x9415 鐕 (<CJK Ideograph>) 6452 0x9416 鐖 (<CJK Ideograph>) 6453 0x9417 鐗 (<CJK Ideograph>) 6454 0x941F 鐟 (<CJK Ideograph>) 6455 0x942E 鐮 (<CJK Ideograph>) 6456 0x942F 鐯 (<CJK Ideograph>) 6457 0x9431 鐱 (<CJK Ideograph>) 6458 0x9432 鐲 (<CJK Ideograph>) 6459 0x9433 鐳 (<CJK Ideograph>) 6460 0x9434 鐴 (<CJK Ideograph>) 6461 0x943B 鐻 (<CJK Ideograph>) 6462 0x943F 鐿 (<CJK Ideograph>) 6463 0x943D 鐽 (<CJK Ideograph>) 6464 0x9443 鑃 (<CJK Ideograph>) 6465 0x9445 鑅 (<CJK Ideograph>) 6466 0x9448 鑈 (<CJK Ideograph>) 6467 0x944A 鑊 (<CJK Ideograph>) 6468 0x944C 鑌 (<CJK Ideograph>) 6469 0x9455 鑕 (<CJK Ideograph>) 6470 0x9459 鑙 (<CJK Ideograph>) 6471 0x945C 鑜 (<CJK Ideograph>) 6472 0x945F 鑟 (<CJK Ideograph>) 6473 0x9461 鑡 (<CJK Ideograph>) 6474 0x9463 鑣 (<CJK Ideograph>) 6475 0x9468 鑨 (<CJK Ideograph>) 6476 0x946B 鑫 (<CJK Ideograph>) 6477 0x946D 鑭 (<CJK Ideograph>) 6478 0x946E 鑮 (<CJK Ideograph>) 6479 0x946F 鑯 (<CJK Ideograph>) 6480 0x9471 鑱 (<CJK Ideograph>) 6481 0x9472 鑲 (<CJK Ideograph>) 6482 0x9484 钄 (<CJK Ideograph>) 6483 0x9483 钃 (<CJK Ideograph>) 6484 0x9578 镸 (<CJK Ideograph>) 6485 0x9579 镹 (<CJK Ideograph>) 6486 0x957E 镾 (<CJK Ideograph>) 6487 0x9584 閄 (<CJK Ideograph>) 6488 0x9588 閈 (<CJK Ideograph>) 6489 0x958C 閌 (<CJK Ideograph>) 6490 0x958D 閍 (<CJK Ideograph>) 6491 0x958E 閎 (<CJK Ideograph>) 6492 0x959D 閝 (<CJK Ideograph>) 6493 0x959E 閞 (<CJK Ideograph>) 6494 0x959F 閟 (<CJK Ideograph>) 6495 0x95A1 閡 (<CJK Ideograph>) 6496 0x95A6 閦 (<CJK Ideograph>) 6497 0x95A9 閩 (<CJK Ideograph>) 6498 0x95AB 閫 (<CJK Ideograph>) 6499 0x95AC 閬 (<CJK Ideograph>) 6500 0x95B4 閴 (<CJK Ideograph>) 6501 0x95B6 閶 (<CJK Ideograph>) 6502 0x95BA 閺 (<CJK Ideograph>) 6503 0x95BD 閽 (<CJK Ideograph>) 6504 0x95BF 閿 (<CJK Ideograph>) 6505 0x95C6 闆 (<CJK Ideograph>) 6506 0x95C8 闈 (<CJK Ideograph>) 6507 0x95C9 闉 (<CJK Ideograph>) 6508 0x95CB 闋 (<CJK Ideograph>) 6509 0x95D0 闐 (<CJK Ideograph>) 6510 0x95D1 闑 (<CJK Ideograph>) 6511 0x95D2 闒 (<CJK Ideograph>) 6512 0x95D3 闓 (<CJK Ideograph>) 6513 0x95D9 闙 (<CJK Ideograph>) 6514 0x95DA 闚 (<CJK Ideograph>) 6515 0x95DD 闝 (<CJK Ideograph>) 6516 0x95DE 闞 (<CJK Ideograph>) 6517 0x95DF 闟 (<CJK Ideograph>) 6518 0x95E0 闠 (<CJK Ideograph>) 6519 0x95E4 闤 (<CJK Ideograph>) 6520 0x95E6 闦 (<CJK Ideograph>) 6521 0x961D 阝 (<CJK Ideograph>) 6522 0x961E 阞 (<CJK Ideograph>) 6523 0x9622 阢 (<CJK Ideograph>) 6524 0x9624 阤 (<CJK Ideograph>) 6525 0x9625 阥 (<CJK Ideograph>) 6526 0x9626 阦 (<CJK Ideograph>) 6527 0x962C 阬 (<CJK Ideograph>) 6528 0x9631 阱 (<CJK Ideograph>) 6529 0x9633 阳 (<CJK Ideograph>) 6530 0x9637 阷 (<CJK Ideograph>) 6531 0x9638 阸 (<CJK Ideograph>) 6532 0x9639 阹 (<CJK Ideograph>) 6533 0x963A 阺 (<CJK Ideograph>) 6534 0x963C 阼 (<CJK Ideograph>) 6535 0x963D 阽 (<CJK Ideograph>) 6536 0x9641 陁 (<CJK Ideograph>) 6537 0x9652 陒 (<CJK Ideograph>) 6538 0x9654 陔 (<CJK Ideograph>) 6539 0x9656 陖 (<CJK Ideograph>) 6540 0x9657 陗 (<CJK Ideograph>) 6541 0x9658 陘 (<CJK Ideograph>) 6542 0x9661 陡 (<CJK Ideograph>) 6543 0x966E 陮 (<CJK Ideograph>) 6544 0x9674 陴 (<CJK Ideograph>) 6545 0x967B 陻 (<CJK Ideograph>) 6546 0x967C 陼 (<CJK Ideograph>) 6547 0x967E 陾 (<CJK Ideograph>) 6548 0x967F 陿 (<CJK Ideograph>) 6549 0x9681 隁 (<CJK Ideograph>) 6550 0x9682 隂 (<CJK Ideograph>) 6551 0x9683 隃 (<CJK Ideograph>) 6552 0x9684 隄 (<CJK Ideograph>) 6553 0x9689 隉 (<CJK Ideograph>) 6554 0x9691 隑 (<CJK Ideograph>) 6555 0x9696 隖 (<CJK Ideograph>) 6556 0x969A 隚 (<CJK Ideograph>) 6557 0x969D 隝 (<CJK Ideograph>) 6558 0x969F 隟 (<CJK Ideograph>) 6559 0x96A4 隤 (<CJK Ideograph>) 6560 0x96A5 隥 (<CJK Ideograph>) 6561 0x96A6 隦 (<CJK Ideograph>) 6562 0x96A9 隩 (<CJK Ideograph>) 6563 0x96AE 隮 (<CJK Ideograph>) 6564 0x96AF 隯 (<CJK Ideograph>) 6565 0x96B3 隳 (<CJK Ideograph>) 6566 0x96BA 隺 (<CJK Ideograph>) 6567 0x96CA 雊 (<CJK Ideograph>) 6568 0x96D2 雒 (<CJK Ideograph>) 6569 0x5DB2 嶲 (<CJK Ideograph>) 6570 0x96D8 雘 (<CJK Ideograph>) 6571 0x96DA 雚 (<CJK Ideograph>) 6572 0x96DD 雝 (<CJK Ideograph>) 6573 0x96DE 雞 (<CJK Ideograph>) 6574 0x96DF 雟 (<CJK Ideograph>) 6575 0x96E9 雩 (<CJK Ideograph>) 6576 0x96EF 雯 (<CJK Ideograph>) 6577 0x96F1 雱 (<CJK Ideograph>) 6578 0x96FA 雺 (<CJK Ideograph>) 6579 0x9702 霂 (<CJK Ideograph>) 6580 0x9703 霃 (<CJK Ideograph>) 6581 0x9705 霅 (<CJK Ideograph>) 6582 0x9709 霉 (<CJK Ideograph>) 6583 0x971A 霚 (<CJK Ideograph>) 6584 0x971B 霛 (<CJK Ideograph>) 6585 0x971D 霝 (<CJK Ideograph>) 6586 0x9721 霡 (<CJK Ideograph>) 6587 0x9722 霢 (<CJK Ideograph>) 6588 0x9723 霣 (<CJK Ideograph>) 6589 0x9728 霨 (<CJK Ideograph>) 6590 0x9731 霱 (<CJK Ideograph>) 6591 0x9733 霳 (<CJK Ideograph>) 6592 0x9741 靁 (<CJK Ideograph>) 6593 0x9743 靃 (<CJK Ideograph>) 6594 0x974A 靊 (<CJK Ideograph>) 6595 0x974E 靎 (<CJK Ideograph>) 6596 0x974F 靏 (<CJK Ideograph>) 6597 0x9755 靕 (<CJK Ideograph>) 6598 0x9757 靗 (<CJK Ideograph>) 6599 0x9758 靘 (<CJK Ideograph>) 6600 0x975A 靚 (<CJK Ideograph>) 6601 0x975B 靛 (<CJK Ideograph>) 6602 0x9763 靣 (<CJK Ideograph>) 6603 0x9767 靧 (<CJK Ideograph>) 6604 0x976A 靪 (<CJK Ideograph>) 6605 0x976E 靮 (<CJK Ideograph>) 6606 0x9773 靳 (<CJK Ideograph>) 6607 0x9776 靶 (<CJK Ideograph>) 6608 0x9777 靷 (<CJK Ideograph>) 6609 0x9778 靸 (<CJK Ideograph>) 6610 0x977B 靻 (<CJK Ideograph>) 6611 0x977D 靽 (<CJK Ideograph>) 6612 0x977F 靿 (<CJK Ideograph>) 6613 0x9780 鞀 (<CJK Ideograph>) 6614 0x9789 鞉 (<CJK Ideograph>) 6615 0x9795 鞕 (<CJK Ideograph>) 6616 0x9796 鞖 (<CJK Ideograph>) 6617 0x9797 鞗 (<CJK Ideograph>) 6618 0x9799 鞙 (<CJK Ideograph>) 6619 0x979A 鞚 (<CJK Ideograph>) 6620 0x979E 鞞 (<CJK Ideograph>) 6621 0x979F 鞟 (<CJK Ideograph>) 6622 0x97A2 鞢 (<CJK Ideograph>) 6623 0x97AC 鞬 (<CJK Ideograph>) 6624 0x97AE 鞮 (<CJK Ideograph>) 6625 0x97B1 鞱 (<CJK Ideograph>) 6626 0x97B2 鞲 (<CJK Ideograph>) 6627 0x97B5 鞵 (<CJK Ideograph>) 6628 0x97B6 鞶 (<CJK Ideograph>) 6629 0x97B8 鞸 (<CJK Ideograph>) 6630 0x97B9 鞹 (<CJK Ideograph>) 6631 0x97BA 鞺 (<CJK Ideograph>) 6632 0x97BC 鞼 (<CJK Ideograph>) 6633 0x97BE 鞾 (<CJK Ideograph>) 6634 0x97BF 鞿 (<CJK Ideograph>) 6635 0x97C1 韁 (<CJK Ideograph>) 6636 0x97C4 韄 (<CJK Ideograph>) 6637 0x97C5 韅 (<CJK Ideograph>) 6638 0x97C7 韇 (<CJK Ideograph>) 6639 0x97C9 韉 (<CJK Ideograph>) 6640 0x97CA 韊 (<CJK Ideograph>) 6641 0x97CC 韌 (<CJK Ideograph>) 6642 0x97CD 韍 (<CJK Ideograph>) 6643 0x97CE 韎 (<CJK Ideograph>) 6644 0x97D0 韐 (<CJK Ideograph>) 6645 0x97D1 韑 (<CJK Ideograph>) 6646 0x97D4 韔 (<CJK Ideograph>) 6647 0x97D7 韗 (<CJK Ideograph>) 6648 0x97D8 韘 (<CJK Ideograph>) 6649 0x97D9 韙 (<CJK Ideograph>) 6650 0x97DD 韝 (<CJK Ideograph>) 6651 0x97DE 韞 (<CJK Ideograph>) 6652 0x97E0 韠 (<CJK Ideograph>) 6653 0x97DB 韛 (<CJK Ideograph>) 6654 0x97E1 韡 (<CJK Ideograph>) 6655 0x97E4 韤 (<CJK Ideograph>) 6656 0x97EF 韯 (<CJK Ideograph>) 6657 0x97F1 韱 (<CJK Ideograph>) 6658 0x97F4 韴 (<CJK Ideograph>) 6659 0x97F7 韷 (<CJK Ideograph>) 6660 0x97F8 韸 (<CJK Ideograph>) 6661 0x97FA 韺 (<CJK Ideograph>) 6662 0x9807 頇 (<CJK Ideograph>) 6663 0x980A 頊 (<CJK Ideograph>) 6664 0x9819 頙 (<CJK Ideograph>) 6665 0x980D 頍 (<CJK Ideograph>) 6666 0x980E 頎 (<CJK Ideograph>) 6667 0x9814 頔 (<CJK Ideograph>) 6668 0x9816 頖 (<CJK Ideograph>) 6669 0x981C 頜 (<CJK Ideograph>) 6670 0x981E 頞 (<CJK Ideograph>) 6671 0x9820 頠 (<CJK Ideograph>) 6672 0x9823 頣 (<CJK Ideograph>) 6673 0x9826 頦 (<CJK Ideograph>) 6674 0x982B 頫 (<CJK Ideograph>) 6675 0x982E 頮 (<CJK Ideograph>) 6676 0x982F 頯 (<CJK Ideograph>) 6677 0x9830 頰 (<CJK Ideograph>) 6678 0x9832 頲 (<CJK Ideograph>) 6679 0x9833 頳 (<CJK Ideograph>) 6680 0x9835 頵 (<CJK Ideograph>) 6681 0x9825 頥 (<CJK Ideograph>) 6682 0x983E 頾 (<CJK Ideograph>) 6683 0x9844 顄 (<CJK Ideograph>) 6684 0x9847 顇 (<CJK Ideograph>) 6685 0x984A 顊 (<CJK Ideograph>) 6686 0x9851 顑 (<CJK Ideograph>) 6687 0x9852 顒 (<CJK Ideograph>) 6688 0x9853 顓 (<CJK Ideograph>) 6689 0x9856 顖 (<CJK Ideograph>) 6690 0x9857 顗 (<CJK Ideograph>) 6691 0x9859 顙 (<CJK Ideograph>) 6692 0x985A 顚 (<CJK Ideograph>) 6693 0x9862 顢 (<CJK Ideograph>) 6694 0x9863 顣 (<CJK Ideograph>) 6695 0x9865 顥 (<CJK Ideograph>) 6696 0x9866 顦 (<CJK Ideograph>) 6697 0x986A 顪 (<CJK Ideograph>) 6698 0x986C 顬 (<CJK Ideograph>) 6699 0x98AB 颫 (<CJK Ideograph>) 6700 0x98AD 颭 (<CJK Ideograph>) 6701 0x98AE 颮 (<CJK Ideograph>) 6702 0x98B0 颰 (<CJK Ideograph>) 6703 0x98B4 颴 (<CJK Ideograph>) 6704 0x98B7 颷 (<CJK Ideograph>) 6705 0x98B8 颸 (<CJK Ideograph>) 6706 0x98BA 颺 (<CJK Ideograph>) 6707 0x98BB 颻 (<CJK Ideograph>) 6708 0x98BF 颿 (<CJK Ideograph>) 6709 0x98C2 飂 (<CJK Ideograph>) 6710 0x98C5 飅 (<CJK Ideograph>) 6711 0x98C8 飈 (<CJK Ideograph>) 6712 0x98CC 飌 (<CJK Ideograph>) 6713 0x98E1 飡 (<CJK Ideograph>) 6714 0x98E3 飣 (<CJK Ideograph>) 6715 0x98E5 飥 (<CJK Ideograph>) 6716 0x98E6 飦 (<CJK Ideograph>) 6717 0x98E7 飧 (<CJK Ideograph>) 6718 0x98EA 飪 (<CJK Ideograph>) 6719 0x98F3 飳 (<CJK Ideograph>) 6720 0x98F6 飶 (<CJK Ideograph>) 6721 0x9902 餂 (<CJK Ideograph>) 6722 0x9907 餇 (<CJK Ideograph>) 6723 0x9908 餈 (<CJK Ideograph>) 6724 0x9911 餑 (<CJK Ideograph>) 6725 0x9915 餕 (<CJK Ideograph>) 6726 0x9916 餖 (<CJK Ideograph>) 6727 0x9917 餗 (<CJK Ideograph>) 6728 0x991A 餚 (<CJK Ideograph>) 6729 0x991B 餛 (<CJK Ideograph>) 6730 0x991C 餜 (<CJK Ideograph>) 6731 0x991F 餟 (<CJK Ideograph>) 6732 0x9922 餢 (<CJK Ideograph>) 6733 0x9926 餦 (<CJK Ideograph>) 6734 0x9927 餧 (<CJK Ideograph>) 6735 0x992B 餫 (<CJK Ideograph>) 6736 0x9931 餱 (<CJK Ideograph>) 6737 0x9932 餲 (<CJK Ideograph>) 6738 0x9933 餳 (<CJK Ideograph>) 6739 0x9934 餴 (<CJK Ideograph>) 6740 0x9935 餵 (<CJK Ideograph>) 6741 0x9939 餹 (<CJK Ideograph>) 6742 0x993A 餺 (<CJK Ideograph>) 6743 0x993B 餻 (<CJK Ideograph>) 6744 0x993C 餼 (<CJK Ideograph>) 6745 0x9940 饀 (<CJK Ideograph>) 6746 0x9941 饁 (<CJK Ideograph>) 6747 0x9946 饆 (<CJK Ideograph>) 6748 0x9947 饇 (<CJK Ideograph>) 6749 0x9948 饈 (<CJK Ideograph>) 6750 0x994D 饍 (<CJK Ideograph>) 6751 0x994E 饎 (<CJK Ideograph>) 6752 0x9954 饔 (<CJK Ideograph>) 6753 0x9958 饘 (<CJK Ideograph>) 6754 0x9959 饙 (<CJK Ideograph>) 6755 0x995B 饛 (<CJK Ideograph>) 6756 0x995C 饜 (<CJK Ideograph>) 6757 0x995E 饞 (<CJK Ideograph>) 6758 0x995F 饟 (<CJK Ideograph>) 6759 0x9960 饠 (<CJK Ideograph>) 6760 0x999B 馛 (<CJK Ideograph>) 6761 0x999D 馝 (<CJK Ideograph>) 6762 0x999F 馟 (<CJK Ideograph>) 6763 0x99A6 馦 (<CJK Ideograph>) 6764 0x99B0 馰 (<CJK Ideograph>) 6765 0x99B1 馱 (<CJK Ideograph>) 6766 0x99B2 馲 (<CJK Ideograph>) 6767 0x99B5 馵 (<CJK Ideograph>) 6768 0x99B9 馹 (<CJK Ideograph>) 6769 0x99BA 馺 (<CJK Ideograph>) 6770 0x99BD 馽 (<CJK Ideograph>) 6771 0x99BF 馿 (<CJK Ideograph>) 6772 0x99C3 駃 (<CJK Ideograph>) 6773 0x99C9 駉 (<CJK Ideograph>) 6774 0x99D3 駓 (<CJK Ideograph>) 6775 0x99D4 駔 (<CJK Ideograph>) 6776 0x99D9 駙 (<CJK Ideograph>) 6777 0x99DA 駚 (<CJK Ideograph>) 6778 0x99DC 駜 (<CJK Ideograph>) 6779 0x99DE 駞 (<CJK Ideograph>) 6780 0x99E7 駧 (<CJK Ideograph>) 6781 0x99EA 駪 (<CJK Ideograph>) 6782 0x99EB 駫 (<CJK Ideograph>) 6783 0x99EC 駬 (<CJK Ideograph>) 6784 0x99F0 駰 (<CJK Ideograph>) 6785 0x99F4 駴 (<CJK Ideograph>) 6786 0x99F5 駵 (<CJK Ideograph>) 6787 0x99F9 駹 (<CJK Ideograph>) 6788 0x99FD 駽 (<CJK Ideograph>) 6789 0x99FE 駾 (<CJK Ideograph>) 6790 0x9A02 騂 (<CJK Ideograph>) 6791 0x9A03 騃 (<CJK Ideograph>) 6792 0x9A04 騄 (<CJK Ideograph>) 6793 0x9A0B 騋 (<CJK Ideograph>) 6794 0x9A0C 騌 (<CJK Ideograph>) 6795 0x9A10 騐 (<CJK Ideograph>) 6796 0x9A11 騑 (<CJK Ideograph>) 6797 0x9A16 騖 (<CJK Ideograph>) 6798 0x9A1E 騞 (<CJK Ideograph>) 6799 0x9A20 騠 (<CJK Ideograph>) 6800 0x9A22 騢 (<CJK Ideograph>) 6801 0x9A23 騣 (<CJK Ideograph>) 6802 0x9A24 騤 (<CJK Ideograph>) 6803 0x9A27 騧 (<CJK Ideograph>) 6804 0x9A2D 騭 (<CJK Ideograph>) 6805 0x9A2E 騮 (<CJK Ideograph>) 6806 0x9A33 騳 (<CJK Ideograph>) 6807 0x9A35 騵 (<CJK Ideograph>) 6808 0x9A36 騶 (<CJK Ideograph>) 6809 0x9A38 騸 (<CJK Ideograph>) 6810 0x9A47 驇 (<CJK Ideograph>) 6811 0x9A41 驁 (<CJK Ideograph>) 6812 0x9A44 驄 (<CJK Ideograph>) 6813 0x9A4A 驊 (<CJK Ideograph>) 6814 0x9A4B 驋 (<CJK Ideograph>) 6815 0x9A4C 驌 (<CJK Ideograph>) 6816 0x9A4E 驎 (<CJK Ideograph>) 6817 0x9A51 驑 (<CJK Ideograph>) 6818 0x9A54 驔 (<CJK Ideograph>) 6819 0x9A56 驖 (<CJK Ideograph>) 6820 0x9A5D 驝 (<CJK Ideograph>) 6821 0x9AAA 骪 (<CJK Ideograph>) 6822 0x9AAC 骬 (<CJK Ideograph>) 6823 0x9AAE 骮 (<CJK Ideograph>) 6824 0x9AAF 骯 (<CJK Ideograph>) 6825 0x9AB2 骲 (<CJK Ideograph>) 6826 0x9AB4 骴 (<CJK Ideograph>) 6827 0x9AB5 骵 (<CJK Ideograph>) 6828 0x9AB6 骶 (<CJK Ideograph>) 6829 0x9AB9 骹 (<CJK Ideograph>) 6830 0x9ABB 骻 (<CJK Ideograph>) 6831 0x9ABE 骾 (<CJK Ideograph>) 6832 0x9ABF 骿 (<CJK Ideograph>) 6833 0x9AC1 髁 (<CJK Ideograph>) 6834 0x9AC3 髃 (<CJK Ideograph>) 6835 0x9AC6 髆 (<CJK Ideograph>) 6836 0x9AC8 髈 (<CJK Ideograph>) 6837 0x9ACE 髎 (<CJK Ideograph>) 6838 0x9AD0 髐 (<CJK Ideograph>) 6839 0x9AD2 髒 (<CJK Ideograph>) 6840 0x9AD5 髕 (<CJK Ideograph>) 6841 0x9AD6 髖 (<CJK Ideograph>) 6842 0x9AD7 髗 (<CJK Ideograph>) 6843 0x9ADB 髛 (<CJK Ideograph>) 6844 0x9ADC 髜 (<CJK Ideograph>) 6845 0x9AE0 髠 (<CJK Ideograph>) 6846 0x9AE4 髤 (<CJK Ideograph>) 6847 0x9AE5 髥 (<CJK Ideograph>) 6848 0x9AE7 髧 (<CJK Ideograph>) 6849 0x9AE9 髩 (<CJK Ideograph>) 6850 0x9AEC 髬 (<CJK Ideograph>) 6851 0x9AF2 髲 (<CJK Ideograph>) 6852 0x9AF3 髳 (<CJK Ideograph>) 6853 0x9AF5 髵 (<CJK Ideograph>) 6854 0x9AF9 髹 (<CJK Ideograph>) 6855 0x9AFA 髺 (<CJK Ideograph>) 6856 0x9AFD 髽 (<CJK Ideograph>) 6857 0x9AFF 髿 (<CJK Ideograph>) 6858 0x9B00 鬀 (<CJK Ideograph>) 6859 0x9B01 鬁 (<CJK Ideograph>) 6860 0x9B02 鬂 (<CJK Ideograph>) 6861 0x9B03 鬃 (<CJK Ideograph>) 6862 0x9B04 鬄 (<CJK Ideograph>) 6863 0x9B05 鬅 (<CJK Ideograph>) 6864 0x9B08 鬈 (<CJK Ideograph>) 6865 0x9B09 鬉 (<CJK Ideograph>) 6866 0x9B0B 鬋 (<CJK Ideograph>) 6867 0x9B0C 鬌 (<CJK Ideograph>) 6868 0x9B0D 鬍 (<CJK Ideograph>) 6869 0x9B0E 鬎 (<CJK Ideograph>) 6870 0x9B10 鬐 (<CJK Ideograph>) 6871 0x9B12 鬒 (<CJK Ideograph>) 6872 0x9B16 鬖 (<CJK Ideograph>) 6873 0x9B19 鬙 (<CJK Ideograph>) 6874 0x9B1B 鬛 (<CJK Ideograph>) 6875 0x9B1C 鬜 (<CJK Ideograph>) 6876 0x9B20 鬠 (<CJK Ideograph>) 6877 0x9B26 鬦 (<CJK Ideograph>) 6878 0x9B2B 鬫 (<CJK Ideograph>) 6879 0x9B2D 鬭 (<CJK Ideograph>) 6880 0x9B33 鬳 (<CJK Ideograph>) 6881 0x9B34 鬴 (<CJK Ideograph>) 6882 0x9B35 鬵 (<CJK Ideograph>) 6883 0x9B37 鬷 (<CJK Ideograph>) 6884 0x9B39 鬹 (<CJK Ideograph>) 6885 0x9B3A 鬺 (<CJK Ideograph>) 6886 0x9B3D 鬽 (<CJK Ideograph>) 6887 0x9B48 魈 (<CJK Ideograph>) 6888 0x9B4B 魋 (<CJK Ideograph>) 6889 0x9B4C 魌 (<CJK Ideograph>) 6890 0x9B55 魕 (<CJK Ideograph>) 6891 0x9B56 魖 (<CJK Ideograph>) 6892 0x9B57 魗 (<CJK Ideograph>) 6893 0x9B5B 魛 (<CJK Ideograph>) 6894 0x9B5E 魞 (<CJK Ideograph>) 6895 0x9B61 魡 (<CJK Ideograph>) 6896 0x9B63 魣 (<CJK Ideograph>) 6897 0x9B65 魥 (<CJK Ideograph>) 6898 0x9B66 魦 (<CJK Ideograph>) 6899 0x9B68 魨 (<CJK Ideograph>) 6900 0x9B6A 魪 (<CJK Ideograph>) 6901 0x9B6B 魫 (<CJK Ideograph>) 6902 0x9B6C 魬 (<CJK Ideograph>) 6903 0x9B6D 魭 (<CJK Ideograph>) 6904 0x9B6E 魮 (<CJK Ideograph>) 6905 0x9B73 魳 (<CJK Ideograph>) 6906 0x9B75 魵 (<CJK Ideograph>) 6907 0x9B77 魷 (<CJK Ideograph>) 6908 0x9B78 魸 (<CJK Ideograph>) 6909 0x9B79 魹 (<CJK Ideograph>) 6910 0x9B7F 魿 (<CJK Ideograph>) 6911 0x9B80 鮀 (<CJK Ideograph>) 6912 0x9B84 鮄 (<CJK Ideograph>) 6913 0x9B85 鮅 (<CJK Ideograph>) 6914 0x9B86 鮆 (<CJK Ideograph>) 6915 0x9B87 鮇 (<CJK Ideograph>) 6916 0x9B89 鮉 (<CJK Ideograph>) 6917 0x9B8A 鮊 (<CJK Ideograph>) 6918 0x9B8B 鮋 (<CJK Ideograph>) 6919 0x9B8D 鮍 (<CJK Ideograph>) 6920 0x9B8F 鮏 (<CJK Ideograph>) 6921 0x9B90 鮐 (<CJK Ideograph>) 6922 0x9B94 鮔 (<CJK Ideograph>) 6923 0x9B9A 鮚 (<CJK Ideograph>) 6924 0x9B9D 鮝 (<CJK Ideograph>) 6925 0x9B9E 鮞 (<CJK Ideograph>) 6926 0x9BA6 鮦 (<CJK Ideograph>) 6927 0x9BA7 鮧 (<CJK Ideograph>) 6928 0x9BA9 鮩 (<CJK Ideograph>) 6929 0x9BAC 鮬 (<CJK Ideograph>) 6930 0x9BB0 鮰 (<CJK Ideograph>) 6931 0x9BB1 鮱 (<CJK Ideograph>) 6932 0x9BB2 鮲 (<CJK Ideograph>) 6933 0x9BB7 鮷 (<CJK Ideograph>) 6934 0x9BB8 鮸 (<CJK Ideograph>) 6935 0x9BBB 鮻 (<CJK Ideograph>) 6936 0x9BBC 鮼 (<CJK Ideograph>) 6937 0x9BBE 鮾 (<CJK Ideograph>) 6938 0x9BBF 鮿 (<CJK Ideograph>) 6939 0x9BC1 鯁 (<CJK Ideograph>) 6940 0x9BC7 鯇 (<CJK Ideograph>) 6941 0x9BC8 鯈 (<CJK Ideograph>) 6942 0x9BCE 鯎 (<CJK Ideograph>) 6943 0x9BD0 鯐 (<CJK Ideograph>) 6944 0x9BD7 鯗 (<CJK Ideograph>) 6945 0x9BD8 鯘 (<CJK Ideograph>) 6946 0x9BDD 鯝 (<CJK Ideograph>) 6947 0x9BDF 鯟 (<CJK Ideograph>) 6948 0x9BE5 鯥 (<CJK Ideograph>) 6949 0x9BE7 鯧 (<CJK Ideograph>) 6950 0x9BEA 鯪 (<CJK Ideograph>) 6951 0x9BEB 鯫 (<CJK Ideograph>) 6952 0x9BEF 鯯 (<CJK Ideograph>) 6953 0x9BF3 鯳 (<CJK Ideograph>) 6954 0x9BF7 鯷 (<CJK Ideograph>) 6955 0x9BF8 鯸 (<CJK Ideograph>) 6956 0x9BF9 鯹 (<CJK Ideograph>) 6957 0x9BFA 鯺 (<CJK Ideograph>) 6958 0x9BFD 鯽 (<CJK Ideograph>) 6959 0x9BFF 鯿 (<CJK Ideograph>) 6960 0x9C00 鰀 (<CJK Ideograph>) 6961 0x9C02 鰂 (<CJK Ideograph>) 6962 0x9C0B 鰋 (<CJK Ideograph>) 6963 0x9C0F 鰏 (<CJK Ideograph>) 6964 0x9C11 鰑 (<CJK Ideograph>) 6965 0x9C16 鰖 (<CJK Ideograph>) 6966 0x9C18 鰘 (<CJK Ideograph>) 6967 0x9C19 鰙 (<CJK Ideograph>) 6968 0x9C1A 鰚 (<CJK Ideograph>) 6969 0x9C1C 鰜 (<CJK Ideograph>) 6970 0x9C1E 鰞 (<CJK Ideograph>) 6971 0x9C22 鰢 (<CJK Ideograph>) 6972 0x9C23 鰣 (<CJK Ideograph>) 6973 0x9C26 鰦 (<CJK Ideograph>) 6974 0x9C27 鰧 (<CJK Ideograph>) 6975 0x9C28 鰨 (<CJK Ideograph>) 6976 0x9C29 鰩 (<CJK Ideograph>) 6977 0x9C2A 鰪 (<CJK Ideograph>) 6978 0x9C31 鰱 (<CJK Ideograph>) 6979 0x9C35 鰵 (<CJK Ideograph>) 6980 0x9C36 鰶 (<CJK Ideograph>) 6981 0x9C37 鰷 (<CJK Ideograph>) 6982 0x9C3D 鰽 (<CJK Ideograph>) 6983 0x9C41 鱁 (<CJK Ideograph>) 6984 0x9C43 鱃 (<CJK Ideograph>) 6985 0x9C44 鱄 (<CJK Ideograph>) 6986 0x9C45 鱅 (<CJK Ideograph>) 6987 0x9C49 鱉 (<CJK Ideograph>) 6988 0x9C4A 鱊 (<CJK Ideograph>) 6989 0x9C4E 鱎 (<CJK Ideograph>) 6990 0x9C4F 鱏 (<CJK Ideograph>) 6991 0x9C50 鱐 (<CJK Ideograph>) 6992 0x9C53 鱓 (<CJK Ideograph>) 6993 0x9C54 鱔 (<CJK Ideograph>) 6994 0x9C56 鱖 (<CJK Ideograph>) 6995 0x9C58 鱘 (<CJK Ideograph>) 6996 0x9C5B 鱛 (<CJK Ideograph>) 6997 0x9C5D 鱝 (<CJK Ideograph>) 6998 0x9C5E 鱞 (<CJK Ideograph>) 6999 0x9C5F 鱟 (<CJK Ideograph>) 7000 0x9C63 鱣 (<CJK Ideograph>) 7001 0x9C69 鱩 (<CJK Ideograph>) 7002 0x9C6A 鱪 (<CJK Ideograph>) 7003 0x9C5C 鱜 (<CJK Ideograph>) 7004 0x9C6B 鱫 (<CJK Ideograph>) 7005 0x9C68 鱨 (<CJK Ideograph>) 7006 0x9C6E 鱮 (<CJK Ideograph>) 7007 0x9C70 鱰 (<CJK Ideograph>) 7008 0x9C72 鱲 (<CJK Ideograph>) 7009 0x9C75 鱵 (<CJK Ideograph>) 7010 0x9C77 鱷 (<CJK Ideograph>) 7011 0x9C7B 鱻 (<CJK Ideograph>) 7012 0x9CE6 鳦 (<CJK Ideograph>) 7013 0x9CF2 鳲 (<CJK Ideograph>) 7014 0x9CF7 鳷 (<CJK Ideograph>) 7015 0x9CF9 鳹 (<CJK Ideograph>) 7016 0x9D0B 鴋 (<CJK Ideograph>) 7017 0x9D02 鴂 (<CJK Ideograph>) 7018 0x9D11 鴑 (<CJK Ideograph>) 7019 0x9D17 鴗 (<CJK Ideograph>) 7020 0x9D18 鴘 (<CJK Ideograph>) 7021 0x9D1C 鴜 (<CJK Ideograph>) 7022 0x9D1D 鴝 (<CJK Ideograph>) 7023 0x9D1E 鴞 (<CJK Ideograph>) 7024 0x9D2F 鴯 (<CJK Ideograph>) 7025 0x9D30 鴰 (<CJK Ideograph>) 7026 0x9D32 鴲 (<CJK Ideograph>) 7027 0x9D33 鴳 (<CJK Ideograph>) 7028 0x9D34 鴴 (<CJK Ideograph>) 7029 0x9D3A 鴺 (<CJK Ideograph>) 7030 0x9D3C 鴼 (<CJK Ideograph>) 7031 0x9D45 鵅 (<CJK Ideograph>) 7032 0x9D3D 鴽 (<CJK Ideograph>) 7033 0x9D42 鵂 (<CJK Ideograph>) 7034 0x9D43 鵃 (<CJK Ideograph>) 7035 0x9D47 鵇 (<CJK Ideograph>) 7036 0x9D4A 鵊 (<CJK Ideograph>) 7037 0x9D53 鵓 (<CJK Ideograph>) 7038 0x9D54 鵔 (<CJK Ideograph>) 7039 0x9D5F 鵟 (<CJK Ideograph>) 7040 0x9D63 鵣 (<CJK Ideograph>) 7041 0x9D62 鵢 (<CJK Ideograph>) 7042 0x9D65 鵥 (<CJK Ideograph>) 7043 0x9D69 鵩 (<CJK Ideograph>) 7044 0x9D6A 鵪 (<CJK Ideograph>) 7045 0x9D6B 鵫 (<CJK Ideograph>) 7046 0x9D70 鵰 (<CJK Ideograph>) 7047 0x9D76 鵶 (<CJK Ideograph>) 7048 0x9D77 鵷 (<CJK Ideograph>) 7049 0x9D7B 鵻 (<CJK Ideograph>) 7050 0x9D7C 鵼 (<CJK Ideograph>) 7051 0x9D7E 鵾 (<CJK Ideograph>) 7052 0x9D83 鶃 (<CJK Ideograph>) 7053 0x9D84 鶄 (<CJK Ideograph>) 7054 0x9D86 鶆 (<CJK Ideograph>) 7055 0x9D8A 鶊 (<CJK Ideograph>) 7056 0x9D8D 鶍 (<CJK Ideograph>) 7057 0x9D8E 鶎 (<CJK Ideograph>) 7058 0x9D92 鶒 (<CJK Ideograph>) 7059 0x9D93 鶓 (<CJK Ideograph>) 7060 0x9D95 鶕 (<CJK Ideograph>) 7061 0x9D96 鶖 (<CJK Ideograph>) 7062 0x9D97 鶗 (<CJK Ideograph>) 7063 0x9D98 鶘 (<CJK Ideograph>) 7064 0x9DA1 鶡 (<CJK Ideograph>) 7065 0x9DAA 鶪 (<CJK Ideograph>) 7066 0x9DAC 鶬 (<CJK Ideograph>) 7067 0x9DAE 鶮 (<CJK Ideograph>) 7068 0x9DB1 鶱 (<CJK Ideograph>) 7069 0x9DB5 鶵 (<CJK Ideograph>) 7070 0x9DB9 鶹 (<CJK Ideograph>) 7071 0x9DBC 鶼 (<CJK Ideograph>) 7072 0x9DBF 鶿 (<CJK Ideograph>) 7073 0x9DC3 鷃 (<CJK Ideograph>) 7074 0x9DC7 鷇 (<CJK Ideograph>) 7075 0x9DC9 鷉 (<CJK Ideograph>) 7076 0x9DCA 鷊 (<CJK Ideograph>) 7077 0x9DD4 鷔 (<CJK Ideograph>) 7078 0x9DD5 鷕 (<CJK Ideograph>) 7079 0x9DD6 鷖 (<CJK Ideograph>) 7080 0x9DD7 鷗 (<CJK Ideograph>) 7081 0x9DDA 鷚 (<CJK Ideograph>) 7082 0x9DDE 鷞 (<CJK Ideograph>) 7083 0x9DDF 鷟 (<CJK Ideograph>) 7084 0x9DE0 鷠 (<CJK Ideograph>) 7085 0x9DE5 鷥 (<CJK Ideograph>) 7086 0x9DE7 鷧 (<CJK Ideograph>) 7087 0x9DE9 鷩 (<CJK Ideograph>) 7088 0x9DEB 鷫 (<CJK Ideograph>) 7089 0x9DEE 鷮 (<CJK Ideograph>) 7090 0x9DF0 鷰 (<CJK Ideograph>) 7091 0x9DF3 鷳 (<CJK Ideograph>) 7092 0x9DF4 鷴 (<CJK Ideograph>) 7093 0x9DFE 鷾 (<CJK Ideograph>) 7094 0x9E0A 鸊 (<CJK Ideograph>) 7095 0x9E02 鸂 (<CJK Ideograph>) 7096 0x9E07 鸇 (<CJK Ideograph>) 7097 0x9E0E 鸎 (<CJK Ideograph>) 7098 0x9E10 鸐 (<CJK Ideograph>) 7099 0x9E11 鸑 (<CJK Ideograph>) 7100 0x9E12 鸒 (<CJK Ideograph>) 7101 0x9E15 鸕 (<CJK Ideograph>) 7102 0x9E16 鸖 (<CJK Ideograph>) 7103 0x9E19 鸙 (<CJK Ideograph>) 7104 0x9E1C 鸜 (<CJK Ideograph>) 7105 0x9E1D 鸝 (<CJK Ideograph>) 7106 0x9E7A 鹺 (<CJK Ideograph>) 7107 0x9E7B 鹻 (<CJK Ideograph>) 7108 0x9E7C 鹼 (<CJK Ideograph>) 7109 0x9E80 麀 (<CJK Ideograph>) 7110 0x9E82 麂 (<CJK Ideograph>) 7111 0x9E83 麃 (<CJK Ideograph>) 7112 0x9E84 麄 (<CJK Ideograph>) 7113 0x9E85 麅 (<CJK Ideograph>) 7114 0x9E87 麇 (<CJK Ideograph>) 7115 0x9E8E 麎 (<CJK Ideograph>) 7116 0x9E8F 麏 (<CJK Ideograph>) 7117 0x9E96 麖 (<CJK Ideograph>) 7118 0x9E98 麘 (<CJK Ideograph>) 7119 0x9E9B 麛 (<CJK Ideograph>) 7120 0x9E9E 麞 (<CJK Ideograph>) 7121 0x9EA4 麤 (<CJK Ideograph>) 7122 0x9EA8 麨 (<CJK Ideograph>) 7123 0x9EAC 麬 (<CJK Ideograph>) 7124 0x9EAE 麮 (<CJK Ideograph>) 7125 0x9EAF 麯 (<CJK Ideograph>) 7126 0x9EB0 麰 (<CJK Ideograph>) 7127 0x9EB3 麳 (<CJK Ideograph>) 7128 0x9EB4 麴 (<CJK Ideograph>) 7129 0x9EB5 麵 (<CJK Ideograph>) 7130 0x9EC6 黆 (<CJK Ideograph>) 7131 0x9EC8 黈 (<CJK Ideograph>) 7132 0x9ECB 黋 (<CJK Ideograph>) 7133 0x9ED5 黕 (<CJK Ideograph>) 7134 0x9EDF 黟 (<CJK Ideograph>) 7135 0x9EE4 黤 (<CJK Ideograph>) 7136 0x9EE7 黧 (<CJK Ideograph>) 7137 0x9EEC 黬 (<CJK Ideograph>) 7138 0x9EED 黭 (<CJK Ideograph>) 7139 0x9EEE 黮 (<CJK Ideograph>) 7140 0x9EF0 黰 (<CJK Ideograph>) 7141 0x9EF1 黱 (<CJK Ideograph>) 7142 0x9EF2 黲 (<CJK Ideograph>) 7143 0x9EF5 黵 (<CJK Ideograph>) 7144 0x9EF8 黸 (<CJK Ideograph>) 7145 0x9EFF 黿 (<CJK Ideograph>) 7146 0x9F02 鼂 (<CJK Ideograph>) 7147 0x9F03 鼃 (<CJK Ideograph>) 7148 0x9F09 鼉 (<CJK Ideograph>) 7149 0x9F0F 鼏 (<CJK Ideograph>) 7150 0x9F10 鼐 (<CJK Ideograph>) 7151 0x9F11 鼑 (<CJK Ideograph>) 7152 0x9F12 鼒 (<CJK Ideograph>) 7153 0x9F14 鼔 (<CJK Ideograph>) 7154 0x9F16 鼖 (<CJK Ideograph>) 7155 0x9F17 鼗 (<CJK Ideograph>) 7156 0x9F19 鼙 (<CJK Ideograph>) 7157 0x9F1A 鼚 (<CJK Ideograph>) 7158 0x9F1B 鼛 (<CJK Ideograph>) 7159 0x9F1F 鼟 (<CJK Ideograph>) 7160 0x9F22 鼢 (<CJK Ideograph>) 7161 0x9F26 鼦 (<CJK Ideograph>) 7162 0x9F2A 鼪 (<CJK Ideograph>) 7163 0x9F2B 鼫 (<CJK Ideograph>) 7164 0x9F2F 鼯 (<CJK Ideograph>) 7165 0x9F31 鼱 (<CJK Ideograph>) 7166 0x9F32 鼲 (<CJK Ideograph>) 7167 0x9F34 鼴 (<CJK Ideograph>) 7168 0x9F37 鼷 (<CJK Ideograph>) 7169 0x9F39 鼹 (<CJK Ideograph>) 7170 0x9F3A 鼺 (<CJK Ideograph>) 7171 0x9F3C 鼼 (<CJK Ideograph>) 7172 0x9F3D 鼽 (<CJK Ideograph>) 7173 0x9F3F 鼿 (<CJK Ideograph>) 7174 0x9F41 齁 (<CJK Ideograph>) 7175 0x9F43 齃 (<CJK Ideograph>) 7176 0x9F44 齄 (<CJK Ideograph>) 7177 0x9F45 齅 (<CJK Ideograph>) 7178 0x9F46 齆 (<CJK Ideograph>) 7179 0x9F47 齇 (<CJK Ideograph>) 7180 0x9F53 齓 (<CJK Ideograph>) 7181 0x9F55 齕 (<CJK Ideograph>) 7182 0x9F56 齖 (<CJK Ideograph>) 7183 0x9F57 齗 (<CJK Ideograph>) 7184 0x9F58 齘 (<CJK Ideograph>) 7185 0x9F5A 齚 (<CJK Ideograph>) 7186 0x9F5D 齝 (<CJK Ideograph>) 7187 0x9F5E 齞 (<CJK Ideograph>) 7188 0x9F68 齨 (<CJK Ideograph>) 7189 0x9F69 齩 (<CJK Ideograph>) 7190 0x9F6D 齭 (<CJK Ideograph>) 7191 0x9F6E 齮 (<CJK Ideograph>) 7192 0x9F6F 齯 (<CJK Ideograph>) 7193 0x9F70 齰 (<CJK Ideograph>) 7194 0x9F71 齱 (<CJK Ideograph>) 7195 0x9F73 齳 (<CJK Ideograph>) 7196 0x9F75 齵 (<CJK Ideograph>) 7197 0x9F7A 齺 (<CJK Ideograph>) 7198 0x9F7D 齽 (<CJK Ideograph>) 7199 0x9F8F 龏 (<CJK Ideograph>) 7200 0x9F90 龐 (<CJK Ideograph>) 7201 0x9F91 龑 (<CJK Ideograph>) 7202 0x9F92 龒 (<CJK Ideograph>) 7203 0x9F94 龔 (<CJK Ideograph>) 7204 0x9F96 龖 (<CJK Ideograph>) 7205 0x9F97 龗 (<CJK Ideograph>) 7206 0x9F9E 龞 (<CJK Ideograph>) 7207 0x9FA1 龡 (<CJK Ideograph>) 7208 0x9FA2 龢 (<CJK Ideograph>) 7209 0x9FA3 龣 (<CJK Ideograph>) 7210 0x9FA5 龥 (<CJK Ideograph>) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-koi8-r.txt������������������������������������������������������������������0000664�0000000�0000000�00000013532�15202323131�0016706�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-koi8-r.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: c5497cd9071cb352c0e56b219154e539badf63de40b71578f09e2e11fe7d50ae # Date: 2018-01-06 0 0x2500 ─ (BOX DRAWINGS LIGHT HORIZONTAL) 1 0x2502 │ (BOX DRAWINGS LIGHT VERTICAL) 2 0x250C ┌ (BOX DRAWINGS LIGHT DOWN AND RIGHT) 3 0x2510 ┐ (BOX DRAWINGS LIGHT DOWN AND LEFT) 4 0x2514 └ (BOX DRAWINGS LIGHT UP AND RIGHT) 5 0x2518 ┘ (BOX DRAWINGS LIGHT UP AND LEFT) 6 0x251C ├ (BOX DRAWINGS LIGHT VERTICAL AND RIGHT) 7 0x2524 ┤ (BOX DRAWINGS LIGHT VERTICAL AND LEFT) 8 0x252C ┬ (BOX DRAWINGS LIGHT DOWN AND HORIZONTAL) 9 0x2534 ┴ (BOX DRAWINGS LIGHT UP AND HORIZONTAL) 10 0x253C ┼ (BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL) 11 0x2580 ▀ (UPPER HALF BLOCK) 12 0x2584 ▄ (LOWER HALF BLOCK) 13 0x2588 █ (FULL BLOCK) 14 0x258C ▌ (LEFT HALF BLOCK) 15 0x2590 ▐ (RIGHT HALF BLOCK) 16 0x2591 ░ (LIGHT SHADE) 17 0x2592 ▒ (MEDIUM SHADE) 18 0x2593 ▓ (DARK SHADE) 19 0x2320 ⌠ (TOP HALF INTEGRAL) 20 0x25A0 ■ (BLACK SQUARE) 21 0x2219 ∙ (BULLET OPERATOR) 22 0x221A √ (SQUARE ROOT) 23 0x2248 ≈ (ALMOST EQUAL TO) 24 0x2264 ≤ (LESS-THAN OR EQUAL TO) 25 0x2265 ≥ (GREATER-THAN OR EQUAL TO) 26 0x00A0   (NO-BREAK SPACE) 27 0x2321 ⌡ (BOTTOM HALF INTEGRAL) 28 0x00B0 ° (DEGREE SIGN) 29 0x00B2 ² (SUPERSCRIPT TWO) 30 0x00B7 · (MIDDLE DOT) 31 0x00F7 ÷ (DIVISION SIGN) 32 0x2550 ═ (BOX DRAWINGS DOUBLE HORIZONTAL) 33 0x2551 ║ (BOX DRAWINGS DOUBLE VERTICAL) 34 0x2552 ╒ (BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE) 35 0x0451 ё (CYRILLIC SMALL LETTER IO) 36 0x2553 ╓ (BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE) 37 0x2554 ╔ (BOX DRAWINGS DOUBLE DOWN AND RIGHT) 38 0x2555 ╕ (BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE) 39 0x2556 ╖ (BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE) 40 0x2557 ╗ (BOX DRAWINGS DOUBLE DOWN AND LEFT) 41 0x2558 ╘ (BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE) 42 0x2559 ╙ (BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE) 43 0x255A ╚ (BOX DRAWINGS DOUBLE UP AND RIGHT) 44 0x255B ╛ (BOX DRAWINGS UP SINGLE AND LEFT DOUBLE) 45 0x255C ╜ (BOX DRAWINGS UP DOUBLE AND LEFT SINGLE) 46 0x255D ╝ (BOX DRAWINGS DOUBLE UP AND LEFT) 47 0x255E ╞ (BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE) 48 0x255F ╟ (BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE) 49 0x2560 ╠ (BOX DRAWINGS DOUBLE VERTICAL AND RIGHT) 50 0x2561 ╡ (BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE) 51 0x0401 Ё (CYRILLIC CAPITAL LETTER IO) 52 0x2562 ╢ (BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE) 53 0x2563 ╣ (BOX DRAWINGS DOUBLE VERTICAL AND LEFT) 54 0x2564 ╤ (BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE) 55 0x2565 ╥ (BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE) 56 0x2566 ╦ (BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL) 57 0x2567 ╧ (BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE) 58 0x2568 ╨ (BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE) 59 0x2569 ╩ (BOX DRAWINGS DOUBLE UP AND HORIZONTAL) 60 0x256A ╪ (BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE) 61 0x256B ╫ (BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE) 62 0x256C ╬ (BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL) 63 0x00A9 © (COPYRIGHT SIGN) 64 0x044E ю (CYRILLIC SMALL LETTER YU) 65 0x0430 а (CYRILLIC SMALL LETTER A) 66 0x0431 б (CYRILLIC SMALL LETTER BE) 67 0x0446 ц (CYRILLIC SMALL LETTER TSE) 68 0x0434 д (CYRILLIC SMALL LETTER DE) 69 0x0435 е (CYRILLIC SMALL LETTER IE) 70 0x0444 ф (CYRILLIC SMALL LETTER EF) 71 0x0433 г (CYRILLIC SMALL LETTER GHE) 72 0x0445 х (CYRILLIC SMALL LETTER HA) 73 0x0438 и (CYRILLIC SMALL LETTER I) 74 0x0439 й (CYRILLIC SMALL LETTER SHORT I) 75 0x043A к (CYRILLIC SMALL LETTER KA) 76 0x043B л (CYRILLIC SMALL LETTER EL) 77 0x043C м (CYRILLIC SMALL LETTER EM) 78 0x043D н (CYRILLIC SMALL LETTER EN) 79 0x043E о (CYRILLIC SMALL LETTER O) 80 0x043F п (CYRILLIC SMALL LETTER PE) 81 0x044F я (CYRILLIC SMALL LETTER YA) 82 0x0440 р (CYRILLIC SMALL LETTER ER) 83 0x0441 с (CYRILLIC SMALL LETTER ES) 84 0x0442 т (CYRILLIC SMALL LETTER TE) 85 0x0443 у (CYRILLIC SMALL LETTER U) 86 0x0436 ж (CYRILLIC SMALL LETTER ZHE) 87 0x0432 в (CYRILLIC SMALL LETTER VE) 88 0x044C ь (CYRILLIC SMALL LETTER SOFT SIGN) 89 0x044B ы (CYRILLIC SMALL LETTER YERU) 90 0x0437 з (CYRILLIC SMALL LETTER ZE) 91 0x0448 ш (CYRILLIC SMALL LETTER SHA) 92 0x044D э (CYRILLIC SMALL LETTER E) 93 0x0449 щ (CYRILLIC SMALL LETTER SHCHA) 94 0x0447 ч (CYRILLIC SMALL LETTER CHE) 95 0x044A ъ (CYRILLIC SMALL LETTER HARD SIGN) 96 0x042E Ю (CYRILLIC CAPITAL LETTER YU) 97 0x0410 А (CYRILLIC CAPITAL LETTER A) 98 0x0411 Б (CYRILLIC CAPITAL LETTER BE) 99 0x0426 Ц (CYRILLIC CAPITAL LETTER TSE) 100 0x0414 Д (CYRILLIC CAPITAL LETTER DE) 101 0x0415 Е (CYRILLIC CAPITAL LETTER IE) 102 0x0424 Ф (CYRILLIC CAPITAL LETTER EF) 103 0x0413 Г (CYRILLIC CAPITAL LETTER GHE) 104 0x0425 Х (CYRILLIC CAPITAL LETTER HA) 105 0x0418 И (CYRILLIC CAPITAL LETTER I) 106 0x0419 Й (CYRILLIC CAPITAL LETTER SHORT I) 107 0x041A К (CYRILLIC CAPITAL LETTER KA) 108 0x041B Л (CYRILLIC CAPITAL LETTER EL) 109 0x041C М (CYRILLIC CAPITAL LETTER EM) 110 0x041D Н (CYRILLIC CAPITAL LETTER EN) 111 0x041E О (CYRILLIC CAPITAL LETTER O) 112 0x041F П (CYRILLIC CAPITAL LETTER PE) 113 0x042F Я (CYRILLIC CAPITAL LETTER YA) 114 0x0420 Р (CYRILLIC CAPITAL LETTER ER) 115 0x0421 С (CYRILLIC CAPITAL LETTER ES) 116 0x0422 Т (CYRILLIC CAPITAL LETTER TE) 117 0x0423 У (CYRILLIC CAPITAL LETTER U) 118 0x0416 Ж (CYRILLIC CAPITAL LETTER ZHE) 119 0x0412 В (CYRILLIC CAPITAL LETTER VE) 120 0x042C Ь (CYRILLIC CAPITAL LETTER SOFT SIGN) 121 0x042B Ы (CYRILLIC CAPITAL LETTER YERU) 122 0x0417 З (CYRILLIC CAPITAL LETTER ZE) 123 0x0428 Ш (CYRILLIC CAPITAL LETTER SHA) 124 0x042D Э (CYRILLIC CAPITAL LETTER E) 125 0x0429 Щ (CYRILLIC CAPITAL LETTER SHCHA) 126 0x0427 Ч (CYRILLIC CAPITAL LETTER CHE) 127 0x042A Ъ (CYRILLIC CAPITAL LETTER HARD SIGN) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-koi8-u.txt������������������������������������������������������������������0000664�0000000�0000000�00000013413�15202323131�0016707�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-koi8-u.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 19a4da2c3f245118bbc8019326f45a07832949938ff903f03d62ac4da1f61f40 # Date: 2018-01-06 0 0x2500 ─ (BOX DRAWINGS LIGHT HORIZONTAL) 1 0x2502 │ (BOX DRAWINGS LIGHT VERTICAL) 2 0x250C ┌ (BOX DRAWINGS LIGHT DOWN AND RIGHT) 3 0x2510 ┐ (BOX DRAWINGS LIGHT DOWN AND LEFT) 4 0x2514 └ (BOX DRAWINGS LIGHT UP AND RIGHT) 5 0x2518 ┘ (BOX DRAWINGS LIGHT UP AND LEFT) 6 0x251C ├ (BOX DRAWINGS LIGHT VERTICAL AND RIGHT) 7 0x2524 ┤ (BOX DRAWINGS LIGHT VERTICAL AND LEFT) 8 0x252C ┬ (BOX DRAWINGS LIGHT DOWN AND HORIZONTAL) 9 0x2534 ┴ (BOX DRAWINGS LIGHT UP AND HORIZONTAL) 10 0x253C ┼ (BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL) 11 0x2580 ▀ (UPPER HALF BLOCK) 12 0x2584 ▄ (LOWER HALF BLOCK) 13 0x2588 █ (FULL BLOCK) 14 0x258C ▌ (LEFT HALF BLOCK) 15 0x2590 ▐ (RIGHT HALF BLOCK) 16 0x2591 ░ (LIGHT SHADE) 17 0x2592 ▒ (MEDIUM SHADE) 18 0x2593 ▓ (DARK SHADE) 19 0x2320 ⌠ (TOP HALF INTEGRAL) 20 0x25A0 ■ (BLACK SQUARE) 21 0x2219 ∙ (BULLET OPERATOR) 22 0x221A √ (SQUARE ROOT) 23 0x2248 ≈ (ALMOST EQUAL TO) 24 0x2264 ≤ (LESS-THAN OR EQUAL TO) 25 0x2265 ≥ (GREATER-THAN OR EQUAL TO) 26 0x00A0   (NO-BREAK SPACE) 27 0x2321 ⌡ (BOTTOM HALF INTEGRAL) 28 0x00B0 ° (DEGREE SIGN) 29 0x00B2 ² (SUPERSCRIPT TWO) 30 0x00B7 · (MIDDLE DOT) 31 0x00F7 ÷ (DIVISION SIGN) 32 0x2550 ═ (BOX DRAWINGS DOUBLE HORIZONTAL) 33 0x2551 ║ (BOX DRAWINGS DOUBLE VERTICAL) 34 0x2552 ╒ (BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE) 35 0x0451 ё (CYRILLIC SMALL LETTER IO) 36 0x0454 є (CYRILLIC SMALL LETTER UKRAINIAN IE) 37 0x2554 ╔ (BOX DRAWINGS DOUBLE DOWN AND RIGHT) 38 0x0456 і (CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I) 39 0x0457 ї (CYRILLIC SMALL LETTER YI) 40 0x2557 ╗ (BOX DRAWINGS DOUBLE DOWN AND LEFT) 41 0x2558 ╘ (BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE) 42 0x2559 ╙ (BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE) 43 0x255A ╚ (BOX DRAWINGS DOUBLE UP AND RIGHT) 44 0x255B ╛ (BOX DRAWINGS UP SINGLE AND LEFT DOUBLE) 45 0x0491 ґ (CYRILLIC SMALL LETTER GHE WITH UPTURN) 46 0x045E ў (CYRILLIC SMALL LETTER SHORT U) 47 0x255E ╞ (BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE) 48 0x255F ╟ (BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE) 49 0x2560 ╠ (BOX DRAWINGS DOUBLE VERTICAL AND RIGHT) 50 0x2561 ╡ (BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE) 51 0x0401 Ё (CYRILLIC CAPITAL LETTER IO) 52 0x0404 Є (CYRILLIC CAPITAL LETTER UKRAINIAN IE) 53 0x2563 ╣ (BOX DRAWINGS DOUBLE VERTICAL AND LEFT) 54 0x0406 І (CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I) 55 0x0407 Ї (CYRILLIC CAPITAL LETTER YI) 56 0x2566 ╦ (BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL) 57 0x2567 ╧ (BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE) 58 0x2568 ╨ (BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE) 59 0x2569 ╩ (BOX DRAWINGS DOUBLE UP AND HORIZONTAL) 60 0x256A ╪ (BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE) 61 0x0490 Ґ (CYRILLIC CAPITAL LETTER GHE WITH UPTURN) 62 0x040E Ў (CYRILLIC CAPITAL LETTER SHORT U) 63 0x00A9 © (COPYRIGHT SIGN) 64 0x044E ю (CYRILLIC SMALL LETTER YU) 65 0x0430 а (CYRILLIC SMALL LETTER A) 66 0x0431 б (CYRILLIC SMALL LETTER BE) 67 0x0446 ц (CYRILLIC SMALL LETTER TSE) 68 0x0434 д (CYRILLIC SMALL LETTER DE) 69 0x0435 е (CYRILLIC SMALL LETTER IE) 70 0x0444 ф (CYRILLIC SMALL LETTER EF) 71 0x0433 г (CYRILLIC SMALL LETTER GHE) 72 0x0445 х (CYRILLIC SMALL LETTER HA) 73 0x0438 и (CYRILLIC SMALL LETTER I) 74 0x0439 й (CYRILLIC SMALL LETTER SHORT I) 75 0x043A к (CYRILLIC SMALL LETTER KA) 76 0x043B л (CYRILLIC SMALL LETTER EL) 77 0x043C м (CYRILLIC SMALL LETTER EM) 78 0x043D н (CYRILLIC SMALL LETTER EN) 79 0x043E о (CYRILLIC SMALL LETTER O) 80 0x043F п (CYRILLIC SMALL LETTER PE) 81 0x044F я (CYRILLIC SMALL LETTER YA) 82 0x0440 р (CYRILLIC SMALL LETTER ER) 83 0x0441 с (CYRILLIC SMALL LETTER ES) 84 0x0442 т (CYRILLIC SMALL LETTER TE) 85 0x0443 у (CYRILLIC SMALL LETTER U) 86 0x0436 ж (CYRILLIC SMALL LETTER ZHE) 87 0x0432 в (CYRILLIC SMALL LETTER VE) 88 0x044C ь (CYRILLIC SMALL LETTER SOFT SIGN) 89 0x044B ы (CYRILLIC SMALL LETTER YERU) 90 0x0437 з (CYRILLIC SMALL LETTER ZE) 91 0x0448 ш (CYRILLIC SMALL LETTER SHA) 92 0x044D э (CYRILLIC SMALL LETTER E) 93 0x0449 щ (CYRILLIC SMALL LETTER SHCHA) 94 0x0447 ч (CYRILLIC SMALL LETTER CHE) 95 0x044A ъ (CYRILLIC SMALL LETTER HARD SIGN) 96 0x042E Ю (CYRILLIC CAPITAL LETTER YU) 97 0x0410 А (CYRILLIC CAPITAL LETTER A) 98 0x0411 Б (CYRILLIC CAPITAL LETTER BE) 99 0x0426 Ц (CYRILLIC CAPITAL LETTER TSE) 100 0x0414 Д (CYRILLIC CAPITAL LETTER DE) 101 0x0415 Е (CYRILLIC CAPITAL LETTER IE) 102 0x0424 Ф (CYRILLIC CAPITAL LETTER EF) 103 0x0413 Г (CYRILLIC CAPITAL LETTER GHE) 104 0x0425 Х (CYRILLIC CAPITAL LETTER HA) 105 0x0418 И (CYRILLIC CAPITAL LETTER I) 106 0x0419 Й (CYRILLIC CAPITAL LETTER SHORT I) 107 0x041A К (CYRILLIC CAPITAL LETTER KA) 108 0x041B Л (CYRILLIC CAPITAL LETTER EL) 109 0x041C М (CYRILLIC CAPITAL LETTER EM) 110 0x041D Н (CYRILLIC CAPITAL LETTER EN) 111 0x041E О (CYRILLIC CAPITAL LETTER O) 112 0x041F П (CYRILLIC CAPITAL LETTER PE) 113 0x042F Я (CYRILLIC CAPITAL LETTER YA) 114 0x0420 Р (CYRILLIC CAPITAL LETTER ER) 115 0x0421 С (CYRILLIC CAPITAL LETTER ES) 116 0x0422 Т (CYRILLIC CAPITAL LETTER TE) 117 0x0423 У (CYRILLIC CAPITAL LETTER U) 118 0x0416 Ж (CYRILLIC CAPITAL LETTER ZHE) 119 0x0412 В (CYRILLIC CAPITAL LETTER VE) 120 0x042C Ь (CYRILLIC CAPITAL LETTER SOFT SIGN) 121 0x042B Ы (CYRILLIC CAPITAL LETTER YERU) 122 0x0417 З (CYRILLIC CAPITAL LETTER ZE) 123 0x0428 Ш (CYRILLIC CAPITAL LETTER SHA) 124 0x042D Э (CYRILLIC CAPITAL LETTER E) 125 0x0429 Щ (CYRILLIC CAPITAL LETTER SHCHA) 126 0x0427 Ч (CYRILLIC CAPITAL LETTER CHE) 127 0x042A Ъ (CYRILLIC CAPITAL LETTER HARD SIGN) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-macintosh.txt���������������������������������������������������������������0000664�0000000�0000000�00000012633�15202323131�0017563�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-macintosh.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: f2c6a4f6406b3e86a50a5dba4d2b7dd48e2e33c0d82aefe764535c934ec11764 # Date: 2018-01-06 0 0x00C4 Ä (LATIN CAPITAL LETTER A WITH DIAERESIS) 1 0x00C5 Å (LATIN CAPITAL LETTER A WITH RING ABOVE) 2 0x00C7 Ç (LATIN CAPITAL LETTER C WITH CEDILLA) 3 0x00C9 É (LATIN CAPITAL LETTER E WITH ACUTE) 4 0x00D1 Ñ (LATIN CAPITAL LETTER N WITH TILDE) 5 0x00D6 Ö (LATIN CAPITAL LETTER O WITH DIAERESIS) 6 0x00DC Ü (LATIN CAPITAL LETTER U WITH DIAERESIS) 7 0x00E1 á (LATIN SMALL LETTER A WITH ACUTE) 8 0x00E0 à (LATIN SMALL LETTER A WITH GRAVE) 9 0x00E2 â (LATIN SMALL LETTER A WITH CIRCUMFLEX) 10 0x00E4 ä (LATIN SMALL LETTER A WITH DIAERESIS) 11 0x00E3 ã (LATIN SMALL LETTER A WITH TILDE) 12 0x00E5 å (LATIN SMALL LETTER A WITH RING ABOVE) 13 0x00E7 ç (LATIN SMALL LETTER C WITH CEDILLA) 14 0x00E9 é (LATIN SMALL LETTER E WITH ACUTE) 15 0x00E8 è (LATIN SMALL LETTER E WITH GRAVE) 16 0x00EA ê (LATIN SMALL LETTER E WITH CIRCUMFLEX) 17 0x00EB ë (LATIN SMALL LETTER E WITH DIAERESIS) 18 0x00ED í (LATIN SMALL LETTER I WITH ACUTE) 19 0x00EC ì (LATIN SMALL LETTER I WITH GRAVE) 20 0x00EE î (LATIN SMALL LETTER I WITH CIRCUMFLEX) 21 0x00EF ï (LATIN SMALL LETTER I WITH DIAERESIS) 22 0x00F1 ñ (LATIN SMALL LETTER N WITH TILDE) 23 0x00F3 ó (LATIN SMALL LETTER O WITH ACUTE) 24 0x00F2 ò (LATIN SMALL LETTER O WITH GRAVE) 25 0x00F4 ô (LATIN SMALL LETTER O WITH CIRCUMFLEX) 26 0x00F6 ö (LATIN SMALL LETTER O WITH DIAERESIS) 27 0x00F5 õ (LATIN SMALL LETTER O WITH TILDE) 28 0x00FA ú (LATIN SMALL LETTER U WITH ACUTE) 29 0x00F9 ù (LATIN SMALL LETTER U WITH GRAVE) 30 0x00FB û (LATIN SMALL LETTER U WITH CIRCUMFLEX) 31 0x00FC ü (LATIN SMALL LETTER U WITH DIAERESIS) 32 0x2020 † (DAGGER) 33 0x00B0 ° (DEGREE SIGN) 34 0x00A2 ¢ (CENT SIGN) 35 0x00A3 £ (POUND SIGN) 36 0x00A7 § (SECTION SIGN) 37 0x2022 • (BULLET) 38 0x00B6 ¶ (PILCROW SIGN) 39 0x00DF ß (LATIN SMALL LETTER SHARP S) 40 0x00AE ® (REGISTERED SIGN) 41 0x00A9 © (COPYRIGHT SIGN) 42 0x2122 ™ (TRADE MARK SIGN) 43 0x00B4 ´ (ACUTE ACCENT) 44 0x00A8 ¨ (DIAERESIS) 45 0x2260 ≠ (NOT EQUAL TO) 46 0x00C6 Æ (LATIN CAPITAL LETTER AE) 47 0x00D8 Ø (LATIN CAPITAL LETTER O WITH STROKE) 48 0x221E ∞ (INFINITY) 49 0x00B1 ± (PLUS-MINUS SIGN) 50 0x2264 ≤ (LESS-THAN OR EQUAL TO) 51 0x2265 ≥ (GREATER-THAN OR EQUAL TO) 52 0x00A5 ¥ (YEN SIGN) 53 0x00B5 µ (MICRO SIGN) 54 0x2202 ∂ (PARTIAL DIFFERENTIAL) 55 0x2211 ∑ (N-ARY SUMMATION) 56 0x220F ∏ (N-ARY PRODUCT) 57 0x03C0 π (GREEK SMALL LETTER PI) 58 0x222B ∫ (INTEGRAL) 59 0x00AA ª (FEMININE ORDINAL INDICATOR) 60 0x00BA º (MASCULINE ORDINAL INDICATOR) 61 0x03A9 Ω (GREEK CAPITAL LETTER OMEGA) 62 0x00E6 æ (LATIN SMALL LETTER AE) 63 0x00F8 ø (LATIN SMALL LETTER O WITH STROKE) 64 0x00BF ¿ (INVERTED QUESTION MARK) 65 0x00A1 ¡ (INVERTED EXCLAMATION MARK) 66 0x00AC ¬ (NOT SIGN) 67 0x221A √ (SQUARE ROOT) 68 0x0192 ƒ (LATIN SMALL LETTER F WITH HOOK) 69 0x2248 ≈ (ALMOST EQUAL TO) 70 0x2206 ∆ (INCREMENT) 71 0x00AB « (LEFT-POINTING DOUBLE ANGLE QUOTATION MARK) 72 0x00BB » (RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK) 73 0x2026 … (HORIZONTAL ELLIPSIS) 74 0x00A0   (NO-BREAK SPACE) 75 0x00C0 À (LATIN CAPITAL LETTER A WITH GRAVE) 76 0x00C3 à (LATIN CAPITAL LETTER A WITH TILDE) 77 0x00D5 Õ (LATIN CAPITAL LETTER O WITH TILDE) 78 0x0152 Œ (LATIN CAPITAL LIGATURE OE) 79 0x0153 œ (LATIN SMALL LIGATURE OE) 80 0x2013 – (EN DASH) 81 0x2014 — (EM DASH) 82 0x201C “ (LEFT DOUBLE QUOTATION MARK) 83 0x201D ” (RIGHT DOUBLE QUOTATION MARK) 84 0x2018 ‘ (LEFT SINGLE QUOTATION MARK) 85 0x2019 ’ (RIGHT SINGLE QUOTATION MARK) 86 0x00F7 ÷ (DIVISION SIGN) 87 0x25CA ◊ (LOZENGE) 88 0x00FF ÿ (LATIN SMALL LETTER Y WITH DIAERESIS) 89 0x0178 Ÿ (LATIN CAPITAL LETTER Y WITH DIAERESIS) 90 0x2044 ⁄ (FRACTION SLASH) 91 0x20AC € (EURO SIGN) 92 0x2039 ‹ (SINGLE LEFT-POINTING ANGLE QUOTATION MARK) 93 0x203A › (SINGLE RIGHT-POINTING ANGLE QUOTATION MARK) 94 0xFB01 fi (LATIN SMALL LIGATURE FI) 95 0xFB02 fl (LATIN SMALL LIGATURE FL) 96 0x2021 ‡ (DOUBLE DAGGER) 97 0x00B7 · (MIDDLE DOT) 98 0x201A ‚ (SINGLE LOW-9 QUOTATION MARK) 99 0x201E „ (DOUBLE LOW-9 QUOTATION MARK) 100 0x2030 ‰ (PER MILLE SIGN) 101 0x00C2  (LATIN CAPITAL LETTER A WITH CIRCUMFLEX) 102 0x00CA Ê (LATIN CAPITAL LETTER E WITH CIRCUMFLEX) 103 0x00C1 Á (LATIN CAPITAL LETTER A WITH ACUTE) 104 0x00CB Ë (LATIN CAPITAL LETTER E WITH DIAERESIS) 105 0x00C8 È (LATIN CAPITAL LETTER E WITH GRAVE) 106 0x00CD Í (LATIN CAPITAL LETTER I WITH ACUTE) 107 0x00CE Î (LATIN CAPITAL LETTER I WITH CIRCUMFLEX) 108 0x00CF Ï (LATIN CAPITAL LETTER I WITH DIAERESIS) 109 0x00CC Ì (LATIN CAPITAL LETTER I WITH GRAVE) 110 0x00D3 Ó (LATIN CAPITAL LETTER O WITH ACUTE) 111 0x00D4 Ô (LATIN CAPITAL LETTER O WITH CIRCUMFLEX) 112 0xF8FF  (<Private Use>) 113 0x00D2 Ò (LATIN CAPITAL LETTER O WITH GRAVE) 114 0x00DA Ú (LATIN CAPITAL LETTER U WITH ACUTE) 115 0x00DB Û (LATIN CAPITAL LETTER U WITH CIRCUMFLEX) 116 0x00D9 Ù (LATIN CAPITAL LETTER U WITH GRAVE) 117 0x0131 ı (LATIN SMALL LETTER DOTLESS I) 118 0x02C6 ˆ (MODIFIER LETTER CIRCUMFLEX ACCENT) 119 0x02DC ˜ (SMALL TILDE) 120 0x00AF ¯ (MACRON) 121 0x02D8 ˘ (BREVE) 122 0x02D9 ˙ (DOT ABOVE) 123 0x02DA ˚ (RING ABOVE) 124 0x00B8 ¸ (CEDILLA) 125 0x02DD ˝ (DOUBLE ACUTE ACCENT) 126 0x02DB ˛ (OGONEK) 127 0x02C7 ˇ (CARON) �����������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-windows-1250.txt������������������������������������������������������������0000664�0000000�0000000�00000013322�15202323131�0017651�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-windows-1250.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 0669455a7a1c70ba6003ea737991e8ee9adc455125c13cfe6705a361358de5fa # Date: 2018-01-06 0 0x20AC € (EURO SIGN) 1 0x0081  (<control>) 2 0x201A ‚ (SINGLE LOW-9 QUOTATION MARK) 3 0x0083 ƒ (<control>) 4 0x201E „ (DOUBLE LOW-9 QUOTATION MARK) 5 0x2026 … (HORIZONTAL ELLIPSIS) 6 0x2020 † (DAGGER) 7 0x2021 ‡ (DOUBLE DAGGER) 8 0x0088 ˆ (<control>) 9 0x2030 ‰ (PER MILLE SIGN) 10 0x0160 Š (LATIN CAPITAL LETTER S WITH CARON) 11 0x2039 ‹ (SINGLE LEFT-POINTING ANGLE QUOTATION MARK) 12 0x015A Ś (LATIN CAPITAL LETTER S WITH ACUTE) 13 0x0164 Ť (LATIN CAPITAL LETTER T WITH CARON) 14 0x017D Ž (LATIN CAPITAL LETTER Z WITH CARON) 15 0x0179 Ź (LATIN CAPITAL LETTER Z WITH ACUTE) 16 0x0090  (<control>) 17 0x2018 ‘ (LEFT SINGLE QUOTATION MARK) 18 0x2019 ’ (RIGHT SINGLE QUOTATION MARK) 19 0x201C “ (LEFT DOUBLE QUOTATION MARK) 20 0x201D ” (RIGHT DOUBLE QUOTATION MARK) 21 0x2022 • (BULLET) 22 0x2013 – (EN DASH) 23 0x2014 — (EM DASH) 24 0x0098 ˜ (<control>) 25 0x2122 ™ (TRADE MARK SIGN) 26 0x0161 š (LATIN SMALL LETTER S WITH CARON) 27 0x203A › (SINGLE RIGHT-POINTING ANGLE QUOTATION MARK) 28 0x015B ś (LATIN SMALL LETTER S WITH ACUTE) 29 0x0165 ť (LATIN SMALL LETTER T WITH CARON) 30 0x017E ž (LATIN SMALL LETTER Z WITH CARON) 31 0x017A ź (LATIN SMALL LETTER Z WITH ACUTE) 32 0x00A0   (NO-BREAK SPACE) 33 0x02C7 ˇ (CARON) 34 0x02D8 ˘ (BREVE) 35 0x0141 Ł (LATIN CAPITAL LETTER L WITH STROKE) 36 0x00A4 ¤ (CURRENCY SIGN) 37 0x0104 Ą (LATIN CAPITAL LETTER A WITH OGONEK) 38 0x00A6 ¦ (BROKEN BAR) 39 0x00A7 § (SECTION SIGN) 40 0x00A8 ¨ (DIAERESIS) 41 0x00A9 © (COPYRIGHT SIGN) 42 0x015E Ş (LATIN CAPITAL LETTER S WITH CEDILLA) 43 0x00AB « (LEFT-POINTING DOUBLE ANGLE QUOTATION MARK) 44 0x00AC ¬ (NOT SIGN) 45 0x00AD ­ (SOFT HYPHEN) 46 0x00AE ® (REGISTERED SIGN) 47 0x017B Ż (LATIN CAPITAL LETTER Z WITH DOT ABOVE) 48 0x00B0 ° (DEGREE SIGN) 49 0x00B1 ± (PLUS-MINUS SIGN) 50 0x02DB ˛ (OGONEK) 51 0x0142 ł (LATIN SMALL LETTER L WITH STROKE) 52 0x00B4 ´ (ACUTE ACCENT) 53 0x00B5 µ (MICRO SIGN) 54 0x00B6 ¶ (PILCROW SIGN) 55 0x00B7 · (MIDDLE DOT) 56 0x00B8 ¸ (CEDILLA) 57 0x0105 ą (LATIN SMALL LETTER A WITH OGONEK) 58 0x015F ş (LATIN SMALL LETTER S WITH CEDILLA) 59 0x00BB » (RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK) 60 0x013D Ľ (LATIN CAPITAL LETTER L WITH CARON) 61 0x02DD ˝ (DOUBLE ACUTE ACCENT) 62 0x013E ľ (LATIN SMALL LETTER L WITH CARON) 63 0x017C ż (LATIN SMALL LETTER Z WITH DOT ABOVE) 64 0x0154 Ŕ (LATIN CAPITAL LETTER R WITH ACUTE) 65 0x00C1 Á (LATIN CAPITAL LETTER A WITH ACUTE) 66 0x00C2  (LATIN CAPITAL LETTER A WITH CIRCUMFLEX) 67 0x0102 Ă (LATIN CAPITAL LETTER A WITH BREVE) 68 0x00C4 Ä (LATIN CAPITAL LETTER A WITH DIAERESIS) 69 0x0139 Ĺ (LATIN CAPITAL LETTER L WITH ACUTE) 70 0x0106 Ć (LATIN CAPITAL LETTER C WITH ACUTE) 71 0x00C7 Ç (LATIN CAPITAL LETTER C WITH CEDILLA) 72 0x010C Č (LATIN CAPITAL LETTER C WITH CARON) 73 0x00C9 É (LATIN CAPITAL LETTER E WITH ACUTE) 74 0x0118 Ę (LATIN CAPITAL LETTER E WITH OGONEK) 75 0x00CB Ë (LATIN CAPITAL LETTER E WITH DIAERESIS) 76 0x011A Ě (LATIN CAPITAL LETTER E WITH CARON) 77 0x00CD Í (LATIN CAPITAL LETTER I WITH ACUTE) 78 0x00CE Î (LATIN CAPITAL LETTER I WITH CIRCUMFLEX) 79 0x010E Ď (LATIN CAPITAL LETTER D WITH CARON) 80 0x0110 Đ (LATIN CAPITAL LETTER D WITH STROKE) 81 0x0143 Ń (LATIN CAPITAL LETTER N WITH ACUTE) 82 0x0147 Ň (LATIN CAPITAL LETTER N WITH CARON) 83 0x00D3 Ó (LATIN CAPITAL LETTER O WITH ACUTE) 84 0x00D4 Ô (LATIN CAPITAL LETTER O WITH CIRCUMFLEX) 85 0x0150 Ő (LATIN CAPITAL LETTER O WITH DOUBLE ACUTE) 86 0x00D6 Ö (LATIN CAPITAL LETTER O WITH DIAERESIS) 87 0x00D7 × (MULTIPLICATION SIGN) 88 0x0158 Ř (LATIN CAPITAL LETTER R WITH CARON) 89 0x016E Ů (LATIN CAPITAL LETTER U WITH RING ABOVE) 90 0x00DA Ú (LATIN CAPITAL LETTER U WITH ACUTE) 91 0x0170 Ű (LATIN CAPITAL LETTER U WITH DOUBLE ACUTE) 92 0x00DC Ü (LATIN CAPITAL LETTER U WITH DIAERESIS) 93 0x00DD Ý (LATIN CAPITAL LETTER Y WITH ACUTE) 94 0x0162 Ţ (LATIN CAPITAL LETTER T WITH CEDILLA) 95 0x00DF ß (LATIN SMALL LETTER SHARP S) 96 0x0155 ŕ (LATIN SMALL LETTER R WITH ACUTE) 97 0x00E1 á (LATIN SMALL LETTER A WITH ACUTE) 98 0x00E2 â (LATIN SMALL LETTER A WITH CIRCUMFLEX) 99 0x0103 ă (LATIN SMALL LETTER A WITH BREVE) 100 0x00E4 ä (LATIN SMALL LETTER A WITH DIAERESIS) 101 0x013A ĺ (LATIN SMALL LETTER L WITH ACUTE) 102 0x0107 ć (LATIN SMALL LETTER C WITH ACUTE) 103 0x00E7 ç (LATIN SMALL LETTER C WITH CEDILLA) 104 0x010D č (LATIN SMALL LETTER C WITH CARON) 105 0x00E9 é (LATIN SMALL LETTER E WITH ACUTE) 106 0x0119 ę (LATIN SMALL LETTER E WITH OGONEK) 107 0x00EB ë (LATIN SMALL LETTER E WITH DIAERESIS) 108 0x011B ě (LATIN SMALL LETTER E WITH CARON) 109 0x00ED í (LATIN SMALL LETTER I WITH ACUTE) 110 0x00EE î (LATIN SMALL LETTER I WITH CIRCUMFLEX) 111 0x010F ď (LATIN SMALL LETTER D WITH CARON) 112 0x0111 đ (LATIN SMALL LETTER D WITH STROKE) 113 0x0144 ń (LATIN SMALL LETTER N WITH ACUTE) 114 0x0148 ň (LATIN SMALL LETTER N WITH CARON) 115 0x00F3 ó (LATIN SMALL LETTER O WITH ACUTE) 116 0x00F4 ô (LATIN SMALL LETTER O WITH CIRCUMFLEX) 117 0x0151 ő (LATIN SMALL LETTER O WITH DOUBLE ACUTE) 118 0x00F6 ö (LATIN SMALL LETTER O WITH DIAERESIS) 119 0x00F7 ÷ (DIVISION SIGN) 120 0x0159 ř (LATIN SMALL LETTER R WITH CARON) 121 0x016F ů (LATIN SMALL LETTER U WITH RING ABOVE) 122 0x00FA ú (LATIN SMALL LETTER U WITH ACUTE) 123 0x0171 ű (LATIN SMALL LETTER U WITH DOUBLE ACUTE) 124 0x00FC ü (LATIN SMALL LETTER U WITH DIAERESIS) 125 0x00FD ý (LATIN SMALL LETTER Y WITH ACUTE) 126 0x0163 ţ (LATIN SMALL LETTER T WITH CEDILLA) 127 0x02D9 ˙ (DOT ABOVE) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-windows-1251.txt������������������������������������������������������������0000664�0000000�0000000�00000012616�15202323131�0017657�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-windows-1251.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 7592ef921679ba168b00a9e9afa3b4eebd67bf13dc7e84c4b6e120de856826e0 # Date: 2018-01-06 0 0x0402 Ђ (CYRILLIC CAPITAL LETTER DJE) 1 0x0403 Ѓ (CYRILLIC CAPITAL LETTER GJE) 2 0x201A ‚ (SINGLE LOW-9 QUOTATION MARK) 3 0x0453 ѓ (CYRILLIC SMALL LETTER GJE) 4 0x201E „ (DOUBLE LOW-9 QUOTATION MARK) 5 0x2026 … (HORIZONTAL ELLIPSIS) 6 0x2020 † (DAGGER) 7 0x2021 ‡ (DOUBLE DAGGER) 8 0x20AC € (EURO SIGN) 9 0x2030 ‰ (PER MILLE SIGN) 10 0x0409 Љ (CYRILLIC CAPITAL LETTER LJE) 11 0x2039 ‹ (SINGLE LEFT-POINTING ANGLE QUOTATION MARK) 12 0x040A Њ (CYRILLIC CAPITAL LETTER NJE) 13 0x040C Ќ (CYRILLIC CAPITAL LETTER KJE) 14 0x040B Ћ (CYRILLIC CAPITAL LETTER TSHE) 15 0x040F Џ (CYRILLIC CAPITAL LETTER DZHE) 16 0x0452 ђ (CYRILLIC SMALL LETTER DJE) 17 0x2018 ‘ (LEFT SINGLE QUOTATION MARK) 18 0x2019 ’ (RIGHT SINGLE QUOTATION MARK) 19 0x201C “ (LEFT DOUBLE QUOTATION MARK) 20 0x201D ” (RIGHT DOUBLE QUOTATION MARK) 21 0x2022 • (BULLET) 22 0x2013 – (EN DASH) 23 0x2014 — (EM DASH) 24 0x0098 ˜ (<control>) 25 0x2122 ™ (TRADE MARK SIGN) 26 0x0459 љ (CYRILLIC SMALL LETTER LJE) 27 0x203A › (SINGLE RIGHT-POINTING ANGLE QUOTATION MARK) 28 0x045A њ (CYRILLIC SMALL LETTER NJE) 29 0x045C ќ (CYRILLIC SMALL LETTER KJE) 30 0x045B ћ (CYRILLIC SMALL LETTER TSHE) 31 0x045F џ (CYRILLIC SMALL LETTER DZHE) 32 0x00A0   (NO-BREAK SPACE) 33 0x040E Ў (CYRILLIC CAPITAL LETTER SHORT U) 34 0x045E ў (CYRILLIC SMALL LETTER SHORT U) 35 0x0408 Ј (CYRILLIC CAPITAL LETTER JE) 36 0x00A4 ¤ (CURRENCY SIGN) 37 0x0490 Ґ (CYRILLIC CAPITAL LETTER GHE WITH UPTURN) 38 0x00A6 ¦ (BROKEN BAR) 39 0x00A7 § (SECTION SIGN) 40 0x0401 Ё (CYRILLIC CAPITAL LETTER IO) 41 0x00A9 © (COPYRIGHT SIGN) 42 0x0404 Є (CYRILLIC CAPITAL LETTER UKRAINIAN IE) 43 0x00AB « (LEFT-POINTING DOUBLE ANGLE QUOTATION MARK) 44 0x00AC ¬ (NOT SIGN) 45 0x00AD ­ (SOFT HYPHEN) 46 0x00AE ® (REGISTERED SIGN) 47 0x0407 Ї (CYRILLIC CAPITAL LETTER YI) 48 0x00B0 ° (DEGREE SIGN) 49 0x00B1 ± (PLUS-MINUS SIGN) 50 0x0406 І (CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I) 51 0x0456 і (CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I) 52 0x0491 ґ (CYRILLIC SMALL LETTER GHE WITH UPTURN) 53 0x00B5 µ (MICRO SIGN) 54 0x00B6 ¶ (PILCROW SIGN) 55 0x00B7 · (MIDDLE DOT) 56 0x0451 ё (CYRILLIC SMALL LETTER IO) 57 0x2116 № (NUMERO SIGN) 58 0x0454 є (CYRILLIC SMALL LETTER UKRAINIAN IE) 59 0x00BB » (RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK) 60 0x0458 ј (CYRILLIC SMALL LETTER JE) 61 0x0405 Ѕ (CYRILLIC CAPITAL LETTER DZE) 62 0x0455 ѕ (CYRILLIC SMALL LETTER DZE) 63 0x0457 ї (CYRILLIC SMALL LETTER YI) 64 0x0410 А (CYRILLIC CAPITAL LETTER A) 65 0x0411 Б (CYRILLIC CAPITAL LETTER BE) 66 0x0412 В (CYRILLIC CAPITAL LETTER VE) 67 0x0413 Г (CYRILLIC CAPITAL LETTER GHE) 68 0x0414 Д (CYRILLIC CAPITAL LETTER DE) 69 0x0415 Е (CYRILLIC CAPITAL LETTER IE) 70 0x0416 Ж (CYRILLIC CAPITAL LETTER ZHE) 71 0x0417 З (CYRILLIC CAPITAL LETTER ZE) 72 0x0418 И (CYRILLIC CAPITAL LETTER I) 73 0x0419 Й (CYRILLIC CAPITAL LETTER SHORT I) 74 0x041A К (CYRILLIC CAPITAL LETTER KA) 75 0x041B Л (CYRILLIC CAPITAL LETTER EL) 76 0x041C М (CYRILLIC CAPITAL LETTER EM) 77 0x041D Н (CYRILLIC CAPITAL LETTER EN) 78 0x041E О (CYRILLIC CAPITAL LETTER O) 79 0x041F П (CYRILLIC CAPITAL LETTER PE) 80 0x0420 Р (CYRILLIC CAPITAL LETTER ER) 81 0x0421 С (CYRILLIC CAPITAL LETTER ES) 82 0x0422 Т (CYRILLIC CAPITAL LETTER TE) 83 0x0423 У (CYRILLIC CAPITAL LETTER U) 84 0x0424 Ф (CYRILLIC CAPITAL LETTER EF) 85 0x0425 Х (CYRILLIC CAPITAL LETTER HA) 86 0x0426 Ц (CYRILLIC CAPITAL LETTER TSE) 87 0x0427 Ч (CYRILLIC CAPITAL LETTER CHE) 88 0x0428 Ш (CYRILLIC CAPITAL LETTER SHA) 89 0x0429 Щ (CYRILLIC CAPITAL LETTER SHCHA) 90 0x042A Ъ (CYRILLIC CAPITAL LETTER HARD SIGN) 91 0x042B Ы (CYRILLIC CAPITAL LETTER YERU) 92 0x042C Ь (CYRILLIC CAPITAL LETTER SOFT SIGN) 93 0x042D Э (CYRILLIC CAPITAL LETTER E) 94 0x042E Ю (CYRILLIC CAPITAL LETTER YU) 95 0x042F Я (CYRILLIC CAPITAL LETTER YA) 96 0x0430 а (CYRILLIC SMALL LETTER A) 97 0x0431 б (CYRILLIC SMALL LETTER BE) 98 0x0432 в (CYRILLIC SMALL LETTER VE) 99 0x0433 г (CYRILLIC SMALL LETTER GHE) 100 0x0434 д (CYRILLIC SMALL LETTER DE) 101 0x0435 е (CYRILLIC SMALL LETTER IE) 102 0x0436 ж (CYRILLIC SMALL LETTER ZHE) 103 0x0437 з (CYRILLIC SMALL LETTER ZE) 104 0x0438 и (CYRILLIC SMALL LETTER I) 105 0x0439 й (CYRILLIC SMALL LETTER SHORT I) 106 0x043A к (CYRILLIC SMALL LETTER KA) 107 0x043B л (CYRILLIC SMALL LETTER EL) 108 0x043C м (CYRILLIC SMALL LETTER EM) 109 0x043D н (CYRILLIC SMALL LETTER EN) 110 0x043E о (CYRILLIC SMALL LETTER O) 111 0x043F п (CYRILLIC SMALL LETTER PE) 112 0x0440 р (CYRILLIC SMALL LETTER ER) 113 0x0441 с (CYRILLIC SMALL LETTER ES) 114 0x0442 т (CYRILLIC SMALL LETTER TE) 115 0x0443 у (CYRILLIC SMALL LETTER U) 116 0x0444 ф (CYRILLIC SMALL LETTER EF) 117 0x0445 х (CYRILLIC SMALL LETTER HA) 118 0x0446 ц (CYRILLIC SMALL LETTER TSE) 119 0x0447 ч (CYRILLIC SMALL LETTER CHE) 120 0x0448 ш (CYRILLIC SMALL LETTER SHA) 121 0x0449 щ (CYRILLIC SMALL LETTER SHCHA) 122 0x044A ъ (CYRILLIC SMALL LETTER HARD SIGN) 123 0x044B ы (CYRILLIC SMALL LETTER YERU) 124 0x044C ь (CYRILLIC SMALL LETTER SOFT SIGN) 125 0x044D э (CYRILLIC SMALL LETTER E) 126 0x044E ю (CYRILLIC SMALL LETTER YU) 127 0x044F я (CYRILLIC SMALL LETTER YA) ������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-windows-1252.txt������������������������������������������������������������0000664�0000000�0000000�00000013043�15202323131�0017653�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-windows-1252.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: e56d49d9176e9a412283cf29ac9bd613f5620462f2a080a84eceaf974cfa18b7 # Date: 2018-01-06 0 0x20AC € (EURO SIGN) 1 0x0081  (<control>) 2 0x201A ‚ (SINGLE LOW-9 QUOTATION MARK) 3 0x0192 ƒ (LATIN SMALL LETTER F WITH HOOK) 4 0x201E „ (DOUBLE LOW-9 QUOTATION MARK) 5 0x2026 … (HORIZONTAL ELLIPSIS) 6 0x2020 † (DAGGER) 7 0x2021 ‡ (DOUBLE DAGGER) 8 0x02C6 ˆ (MODIFIER LETTER CIRCUMFLEX ACCENT) 9 0x2030 ‰ (PER MILLE SIGN) 10 0x0160 Š (LATIN CAPITAL LETTER S WITH CARON) 11 0x2039 ‹ (SINGLE LEFT-POINTING ANGLE QUOTATION MARK) 12 0x0152 Œ (LATIN CAPITAL LIGATURE OE) 13 0x008D  (<control>) 14 0x017D Ž (LATIN CAPITAL LETTER Z WITH CARON) 15 0x008F  (<control>) 16 0x0090  (<control>) 17 0x2018 ‘ (LEFT SINGLE QUOTATION MARK) 18 0x2019 ’ (RIGHT SINGLE QUOTATION MARK) 19 0x201C “ (LEFT DOUBLE QUOTATION MARK) 20 0x201D ” (RIGHT DOUBLE QUOTATION MARK) 21 0x2022 • (BULLET) 22 0x2013 – (EN DASH) 23 0x2014 — (EM DASH) 24 0x02DC ˜ (SMALL TILDE) 25 0x2122 ™ (TRADE MARK SIGN) 26 0x0161 š (LATIN SMALL LETTER S WITH CARON) 27 0x203A › (SINGLE RIGHT-POINTING ANGLE QUOTATION MARK) 28 0x0153 œ (LATIN SMALL LIGATURE OE) 29 0x009D  (<control>) 30 0x017E ž (LATIN SMALL LETTER Z WITH CARON) 31 0x0178 Ÿ (LATIN CAPITAL LETTER Y WITH DIAERESIS) 32 0x00A0   (NO-BREAK SPACE) 33 0x00A1 ¡ (INVERTED EXCLAMATION MARK) 34 0x00A2 ¢ (CENT SIGN) 35 0x00A3 £ (POUND SIGN) 36 0x00A4 ¤ (CURRENCY SIGN) 37 0x00A5 ¥ (YEN SIGN) 38 0x00A6 ¦ (BROKEN BAR) 39 0x00A7 § (SECTION SIGN) 40 0x00A8 ¨ (DIAERESIS) 41 0x00A9 © (COPYRIGHT SIGN) 42 0x00AA ª (FEMININE ORDINAL INDICATOR) 43 0x00AB « (LEFT-POINTING DOUBLE ANGLE QUOTATION MARK) 44 0x00AC ¬ (NOT SIGN) 45 0x00AD ­ (SOFT HYPHEN) 46 0x00AE ® (REGISTERED SIGN) 47 0x00AF ¯ (MACRON) 48 0x00B0 ° (DEGREE SIGN) 49 0x00B1 ± (PLUS-MINUS SIGN) 50 0x00B2 ² (SUPERSCRIPT TWO) 51 0x00B3 ³ (SUPERSCRIPT THREE) 52 0x00B4 ´ (ACUTE ACCENT) 53 0x00B5 µ (MICRO SIGN) 54 0x00B6 ¶ (PILCROW SIGN) 55 0x00B7 · (MIDDLE DOT) 56 0x00B8 ¸ (CEDILLA) 57 0x00B9 ¹ (SUPERSCRIPT ONE) 58 0x00BA º (MASCULINE ORDINAL INDICATOR) 59 0x00BB » (RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK) 60 0x00BC ¼ (VULGAR FRACTION ONE QUARTER) 61 0x00BD ½ (VULGAR FRACTION ONE HALF) 62 0x00BE ¾ (VULGAR FRACTION THREE QUARTERS) 63 0x00BF ¿ (INVERTED QUESTION MARK) 64 0x00C0 À (LATIN CAPITAL LETTER A WITH GRAVE) 65 0x00C1 Á (LATIN CAPITAL LETTER A WITH ACUTE) 66 0x00C2  (LATIN CAPITAL LETTER A WITH CIRCUMFLEX) 67 0x00C3 à (LATIN CAPITAL LETTER A WITH TILDE) 68 0x00C4 Ä (LATIN CAPITAL LETTER A WITH DIAERESIS) 69 0x00C5 Å (LATIN CAPITAL LETTER A WITH RING ABOVE) 70 0x00C6 Æ (LATIN CAPITAL LETTER AE) 71 0x00C7 Ç (LATIN CAPITAL LETTER C WITH CEDILLA) 72 0x00C8 È (LATIN CAPITAL LETTER E WITH GRAVE) 73 0x00C9 É (LATIN CAPITAL LETTER E WITH ACUTE) 74 0x00CA Ê (LATIN CAPITAL LETTER E WITH CIRCUMFLEX) 75 0x00CB Ë (LATIN CAPITAL LETTER E WITH DIAERESIS) 76 0x00CC Ì (LATIN CAPITAL LETTER I WITH GRAVE) 77 0x00CD Í (LATIN CAPITAL LETTER I WITH ACUTE) 78 0x00CE Î (LATIN CAPITAL LETTER I WITH CIRCUMFLEX) 79 0x00CF Ï (LATIN CAPITAL LETTER I WITH DIAERESIS) 80 0x00D0 Ð (LATIN CAPITAL LETTER ETH) 81 0x00D1 Ñ (LATIN CAPITAL LETTER N WITH TILDE) 82 0x00D2 Ò (LATIN CAPITAL LETTER O WITH GRAVE) 83 0x00D3 Ó (LATIN CAPITAL LETTER O WITH ACUTE) 84 0x00D4 Ô (LATIN CAPITAL LETTER O WITH CIRCUMFLEX) 85 0x00D5 Õ (LATIN CAPITAL LETTER O WITH TILDE) 86 0x00D6 Ö (LATIN CAPITAL LETTER O WITH DIAERESIS) 87 0x00D7 × (MULTIPLICATION SIGN) 88 0x00D8 Ø (LATIN CAPITAL LETTER O WITH STROKE) 89 0x00D9 Ù (LATIN CAPITAL LETTER U WITH GRAVE) 90 0x00DA Ú (LATIN CAPITAL LETTER U WITH ACUTE) 91 0x00DB Û (LATIN CAPITAL LETTER U WITH CIRCUMFLEX) 92 0x00DC Ü (LATIN CAPITAL LETTER U WITH DIAERESIS) 93 0x00DD Ý (LATIN CAPITAL LETTER Y WITH ACUTE) 94 0x00DE Þ (LATIN CAPITAL LETTER THORN) 95 0x00DF ß (LATIN SMALL LETTER SHARP S) 96 0x00E0 à (LATIN SMALL LETTER A WITH GRAVE) 97 0x00E1 á (LATIN SMALL LETTER A WITH ACUTE) 98 0x00E2 â (LATIN SMALL LETTER A WITH CIRCUMFLEX) 99 0x00E3 ã (LATIN SMALL LETTER A WITH TILDE) 100 0x00E4 ä (LATIN SMALL LETTER A WITH DIAERESIS) 101 0x00E5 å (LATIN SMALL LETTER A WITH RING ABOVE) 102 0x00E6 æ (LATIN SMALL LETTER AE) 103 0x00E7 ç (LATIN SMALL LETTER C WITH CEDILLA) 104 0x00E8 è (LATIN SMALL LETTER E WITH GRAVE) 105 0x00E9 é (LATIN SMALL LETTER E WITH ACUTE) 106 0x00EA ê (LATIN SMALL LETTER E WITH CIRCUMFLEX) 107 0x00EB ë (LATIN SMALL LETTER E WITH DIAERESIS) 108 0x00EC ì (LATIN SMALL LETTER I WITH GRAVE) 109 0x00ED í (LATIN SMALL LETTER I WITH ACUTE) 110 0x00EE î (LATIN SMALL LETTER I WITH CIRCUMFLEX) 111 0x00EF ï (LATIN SMALL LETTER I WITH DIAERESIS) 112 0x00F0 ð (LATIN SMALL LETTER ETH) 113 0x00F1 ñ (LATIN SMALL LETTER N WITH TILDE) 114 0x00F2 ò (LATIN SMALL LETTER O WITH GRAVE) 115 0x00F3 ó (LATIN SMALL LETTER O WITH ACUTE) 116 0x00F4 ô (LATIN SMALL LETTER O WITH CIRCUMFLEX) 117 0x00F5 õ (LATIN SMALL LETTER O WITH TILDE) 118 0x00F6 ö (LATIN SMALL LETTER O WITH DIAERESIS) 119 0x00F7 ÷ (DIVISION SIGN) 120 0x00F8 ø (LATIN SMALL LETTER O WITH STROKE) 121 0x00F9 ù (LATIN SMALL LETTER U WITH GRAVE) 122 0x00FA ú (LATIN SMALL LETTER U WITH ACUTE) 123 0x00FB û (LATIN SMALL LETTER U WITH CIRCUMFLEX) 124 0x00FC ü (LATIN SMALL LETTER U WITH DIAERESIS) 125 0x00FD ý (LATIN SMALL LETTER Y WITH ACUTE) 126 0x00FE þ (LATIN SMALL LETTER THORN) 127 0x00FF ÿ (LATIN SMALL LETTER Y WITH DIAERESIS) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-windows-1253.txt������������������������������������������������������������0000664�0000000�0000000�00000012065�15202323131�0017657�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-windows-1253.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 49fdc881a3488904dd1e8dfba9aef3258454249958b611bcded1d4c981ab5561 # Date: 2018-01-06 0 0x20AC € (EURO SIGN) 1 0x0081  (<control>) 2 0x201A ‚ (SINGLE LOW-9 QUOTATION MARK) 3 0x0192 ƒ (LATIN SMALL LETTER F WITH HOOK) 4 0x201E „ (DOUBLE LOW-9 QUOTATION MARK) 5 0x2026 … (HORIZONTAL ELLIPSIS) 6 0x2020 † (DAGGER) 7 0x2021 ‡ (DOUBLE DAGGER) 8 0x0088 ˆ (<control>) 9 0x2030 ‰ (PER MILLE SIGN) 10 0x008A Š (<control>) 11 0x2039 ‹ (SINGLE LEFT-POINTING ANGLE QUOTATION MARK) 12 0x008C Œ (<control>) 13 0x008D  (<control>) 14 0x008E Ž (<control>) 15 0x008F  (<control>) 16 0x0090  (<control>) 17 0x2018 ‘ (LEFT SINGLE QUOTATION MARK) 18 0x2019 ’ (RIGHT SINGLE QUOTATION MARK) 19 0x201C “ (LEFT DOUBLE QUOTATION MARK) 20 0x201D ” (RIGHT DOUBLE QUOTATION MARK) 21 0x2022 • (BULLET) 22 0x2013 – (EN DASH) 23 0x2014 — (EM DASH) 24 0x0098 ˜ (<control>) 25 0x2122 ™ (TRADE MARK SIGN) 26 0x009A š (<control>) 27 0x203A › (SINGLE RIGHT-POINTING ANGLE QUOTATION MARK) 28 0x009C œ (<control>) 29 0x009D  (<control>) 30 0x009E ž (<control>) 31 0x009F Ÿ (<control>) 32 0x00A0   (NO-BREAK SPACE) 33 0x0385 ΅ (GREEK DIALYTIKA TONOS) 34 0x0386 Ά (GREEK CAPITAL LETTER ALPHA WITH TONOS) 35 0x00A3 £ (POUND SIGN) 36 0x00A4 ¤ (CURRENCY SIGN) 37 0x00A5 ¥ (YEN SIGN) 38 0x00A6 ¦ (BROKEN BAR) 39 0x00A7 § (SECTION SIGN) 40 0x00A8 ¨ (DIAERESIS) 41 0x00A9 © (COPYRIGHT SIGN) 43 0x00AB « (LEFT-POINTING DOUBLE ANGLE QUOTATION MARK) 44 0x00AC ¬ (NOT SIGN) 45 0x00AD ­ (SOFT HYPHEN) 46 0x00AE ® (REGISTERED SIGN) 47 0x2015 ― (HORIZONTAL BAR) 48 0x00B0 ° (DEGREE SIGN) 49 0x00B1 ± (PLUS-MINUS SIGN) 50 0x00B2 ² (SUPERSCRIPT TWO) 51 0x00B3 ³ (SUPERSCRIPT THREE) 52 0x0384 ΄ (GREEK TONOS) 53 0x00B5 µ (MICRO SIGN) 54 0x00B6 ¶ (PILCROW SIGN) 55 0x00B7 · (MIDDLE DOT) 56 0x0388 Έ (GREEK CAPITAL LETTER EPSILON WITH TONOS) 57 0x0389 Ή (GREEK CAPITAL LETTER ETA WITH TONOS) 58 0x038A Ί (GREEK CAPITAL LETTER IOTA WITH TONOS) 59 0x00BB » (RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK) 60 0x038C Ό (GREEK CAPITAL LETTER OMICRON WITH TONOS) 61 0x00BD ½ (VULGAR FRACTION ONE HALF) 62 0x038E Ύ (GREEK CAPITAL LETTER UPSILON WITH TONOS) 63 0x038F Ώ (GREEK CAPITAL LETTER OMEGA WITH TONOS) 64 0x0390 ΐ (GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS) 65 0x0391 Α (GREEK CAPITAL LETTER ALPHA) 66 0x0392 Β (GREEK CAPITAL LETTER BETA) 67 0x0393 Γ (GREEK CAPITAL LETTER GAMMA) 68 0x0394 Δ (GREEK CAPITAL LETTER DELTA) 69 0x0395 Ε (GREEK CAPITAL LETTER EPSILON) 70 0x0396 Ζ (GREEK CAPITAL LETTER ZETA) 71 0x0397 Η (GREEK CAPITAL LETTER ETA) 72 0x0398 Θ (GREEK CAPITAL LETTER THETA) 73 0x0399 Ι (GREEK CAPITAL LETTER IOTA) 74 0x039A Κ (GREEK CAPITAL LETTER KAPPA) 75 0x039B Λ (GREEK CAPITAL LETTER LAMDA) 76 0x039C Μ (GREEK CAPITAL LETTER MU) 77 0x039D Ν (GREEK CAPITAL LETTER NU) 78 0x039E Ξ (GREEK CAPITAL LETTER XI) 79 0x039F Ο (GREEK CAPITAL LETTER OMICRON) 80 0x03A0 Π (GREEK CAPITAL LETTER PI) 81 0x03A1 Ρ (GREEK CAPITAL LETTER RHO) 83 0x03A3 Σ (GREEK CAPITAL LETTER SIGMA) 84 0x03A4 Τ (GREEK CAPITAL LETTER TAU) 85 0x03A5 Υ (GREEK CAPITAL LETTER UPSILON) 86 0x03A6 Φ (GREEK CAPITAL LETTER PHI) 87 0x03A7 Χ (GREEK CAPITAL LETTER CHI) 88 0x03A8 Ψ (GREEK CAPITAL LETTER PSI) 89 0x03A9 Ω (GREEK CAPITAL LETTER OMEGA) 90 0x03AA Ϊ (GREEK CAPITAL LETTER IOTA WITH DIALYTIKA) 91 0x03AB Ϋ (GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA) 92 0x03AC ά (GREEK SMALL LETTER ALPHA WITH TONOS) 93 0x03AD έ (GREEK SMALL LETTER EPSILON WITH TONOS) 94 0x03AE ή (GREEK SMALL LETTER ETA WITH TONOS) 95 0x03AF ί (GREEK SMALL LETTER IOTA WITH TONOS) 96 0x03B0 ΰ (GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS) 97 0x03B1 α (GREEK SMALL LETTER ALPHA) 98 0x03B2 β (GREEK SMALL LETTER BETA) 99 0x03B3 γ (GREEK SMALL LETTER GAMMA) 100 0x03B4 δ (GREEK SMALL LETTER DELTA) 101 0x03B5 ε (GREEK SMALL LETTER EPSILON) 102 0x03B6 ζ (GREEK SMALL LETTER ZETA) 103 0x03B7 η (GREEK SMALL LETTER ETA) 104 0x03B8 θ (GREEK SMALL LETTER THETA) 105 0x03B9 ι (GREEK SMALL LETTER IOTA) 106 0x03BA κ (GREEK SMALL LETTER KAPPA) 107 0x03BB λ (GREEK SMALL LETTER LAMDA) 108 0x03BC μ (GREEK SMALL LETTER MU) 109 0x03BD ν (GREEK SMALL LETTER NU) 110 0x03BE ξ (GREEK SMALL LETTER XI) 111 0x03BF ο (GREEK SMALL LETTER OMICRON) 112 0x03C0 π (GREEK SMALL LETTER PI) 113 0x03C1 ρ (GREEK SMALL LETTER RHO) 114 0x03C2 ς (GREEK SMALL LETTER FINAL SIGMA) 115 0x03C3 σ (GREEK SMALL LETTER SIGMA) 116 0x03C4 τ (GREEK SMALL LETTER TAU) 117 0x03C5 υ (GREEK SMALL LETTER UPSILON) 118 0x03C6 φ (GREEK SMALL LETTER PHI) 119 0x03C7 χ (GREEK SMALL LETTER CHI) 120 0x03C8 ψ (GREEK SMALL LETTER PSI) 121 0x03C9 ω (GREEK SMALL LETTER OMEGA) 122 0x03CA ϊ (GREEK SMALL LETTER IOTA WITH DIALYTIKA) 123 0x03CB ϋ (GREEK SMALL LETTER UPSILON WITH DIALYTIKA) 124 0x03CC ό (GREEK SMALL LETTER OMICRON WITH TONOS) 125 0x03CD ύ (GREEK SMALL LETTER UPSILON WITH TONOS) 126 0x03CE ώ (GREEK SMALL LETTER OMEGA WITH TONOS) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-windows-1254.txt������������������������������������������������������������0000664�0000000�0000000�00000013032�15202323131�0017653�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-windows-1254.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: e80a27adf377438be8ba5bd223875ea56d6a4d47f958cce1c957a2c446825caa # Date: 2018-01-06 0 0x20AC € (EURO SIGN) 1 0x0081  (<control>) 2 0x201A ‚ (SINGLE LOW-9 QUOTATION MARK) 3 0x0192 ƒ (LATIN SMALL LETTER F WITH HOOK) 4 0x201E „ (DOUBLE LOW-9 QUOTATION MARK) 5 0x2026 … (HORIZONTAL ELLIPSIS) 6 0x2020 † (DAGGER) 7 0x2021 ‡ (DOUBLE DAGGER) 8 0x02C6 ˆ (MODIFIER LETTER CIRCUMFLEX ACCENT) 9 0x2030 ‰ (PER MILLE SIGN) 10 0x0160 Š (LATIN CAPITAL LETTER S WITH CARON) 11 0x2039 ‹ (SINGLE LEFT-POINTING ANGLE QUOTATION MARK) 12 0x0152 Œ (LATIN CAPITAL LIGATURE OE) 13 0x008D  (<control>) 14 0x008E Ž (<control>) 15 0x008F  (<control>) 16 0x0090  (<control>) 17 0x2018 ‘ (LEFT SINGLE QUOTATION MARK) 18 0x2019 ’ (RIGHT SINGLE QUOTATION MARK) 19 0x201C “ (LEFT DOUBLE QUOTATION MARK) 20 0x201D ” (RIGHT DOUBLE QUOTATION MARK) 21 0x2022 • (BULLET) 22 0x2013 – (EN DASH) 23 0x2014 — (EM DASH) 24 0x02DC ˜ (SMALL TILDE) 25 0x2122 ™ (TRADE MARK SIGN) 26 0x0161 š (LATIN SMALL LETTER S WITH CARON) 27 0x203A › (SINGLE RIGHT-POINTING ANGLE QUOTATION MARK) 28 0x0153 œ (LATIN SMALL LIGATURE OE) 29 0x009D  (<control>) 30 0x009E ž (<control>) 31 0x0178 Ÿ (LATIN CAPITAL LETTER Y WITH DIAERESIS) 32 0x00A0   (NO-BREAK SPACE) 33 0x00A1 ¡ (INVERTED EXCLAMATION MARK) 34 0x00A2 ¢ (CENT SIGN) 35 0x00A3 £ (POUND SIGN) 36 0x00A4 ¤ (CURRENCY SIGN) 37 0x00A5 ¥ (YEN SIGN) 38 0x00A6 ¦ (BROKEN BAR) 39 0x00A7 § (SECTION SIGN) 40 0x00A8 ¨ (DIAERESIS) 41 0x00A9 © (COPYRIGHT SIGN) 42 0x00AA ª (FEMININE ORDINAL INDICATOR) 43 0x00AB « (LEFT-POINTING DOUBLE ANGLE QUOTATION MARK) 44 0x00AC ¬ (NOT SIGN) 45 0x00AD ­ (SOFT HYPHEN) 46 0x00AE ® (REGISTERED SIGN) 47 0x00AF ¯ (MACRON) 48 0x00B0 ° (DEGREE SIGN) 49 0x00B1 ± (PLUS-MINUS SIGN) 50 0x00B2 ² (SUPERSCRIPT TWO) 51 0x00B3 ³ (SUPERSCRIPT THREE) 52 0x00B4 ´ (ACUTE ACCENT) 53 0x00B5 µ (MICRO SIGN) 54 0x00B6 ¶ (PILCROW SIGN) 55 0x00B7 · (MIDDLE DOT) 56 0x00B8 ¸ (CEDILLA) 57 0x00B9 ¹ (SUPERSCRIPT ONE) 58 0x00BA º (MASCULINE ORDINAL INDICATOR) 59 0x00BB » (RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK) 60 0x00BC ¼ (VULGAR FRACTION ONE QUARTER) 61 0x00BD ½ (VULGAR FRACTION ONE HALF) 62 0x00BE ¾ (VULGAR FRACTION THREE QUARTERS) 63 0x00BF ¿ (INVERTED QUESTION MARK) 64 0x00C0 À (LATIN CAPITAL LETTER A WITH GRAVE) 65 0x00C1 Á (LATIN CAPITAL LETTER A WITH ACUTE) 66 0x00C2  (LATIN CAPITAL LETTER A WITH CIRCUMFLEX) 67 0x00C3 à (LATIN CAPITAL LETTER A WITH TILDE) 68 0x00C4 Ä (LATIN CAPITAL LETTER A WITH DIAERESIS) 69 0x00C5 Å (LATIN CAPITAL LETTER A WITH RING ABOVE) 70 0x00C6 Æ (LATIN CAPITAL LETTER AE) 71 0x00C7 Ç (LATIN CAPITAL LETTER C WITH CEDILLA) 72 0x00C8 È (LATIN CAPITAL LETTER E WITH GRAVE) 73 0x00C9 É (LATIN CAPITAL LETTER E WITH ACUTE) 74 0x00CA Ê (LATIN CAPITAL LETTER E WITH CIRCUMFLEX) 75 0x00CB Ë (LATIN CAPITAL LETTER E WITH DIAERESIS) 76 0x00CC Ì (LATIN CAPITAL LETTER I WITH GRAVE) 77 0x00CD Í (LATIN CAPITAL LETTER I WITH ACUTE) 78 0x00CE Î (LATIN CAPITAL LETTER I WITH CIRCUMFLEX) 79 0x00CF Ï (LATIN CAPITAL LETTER I WITH DIAERESIS) 80 0x011E Ğ (LATIN CAPITAL LETTER G WITH BREVE) 81 0x00D1 Ñ (LATIN CAPITAL LETTER N WITH TILDE) 82 0x00D2 Ò (LATIN CAPITAL LETTER O WITH GRAVE) 83 0x00D3 Ó (LATIN CAPITAL LETTER O WITH ACUTE) 84 0x00D4 Ô (LATIN CAPITAL LETTER O WITH CIRCUMFLEX) 85 0x00D5 Õ (LATIN CAPITAL LETTER O WITH TILDE) 86 0x00D6 Ö (LATIN CAPITAL LETTER O WITH DIAERESIS) 87 0x00D7 × (MULTIPLICATION SIGN) 88 0x00D8 Ø (LATIN CAPITAL LETTER O WITH STROKE) 89 0x00D9 Ù (LATIN CAPITAL LETTER U WITH GRAVE) 90 0x00DA Ú (LATIN CAPITAL LETTER U WITH ACUTE) 91 0x00DB Û (LATIN CAPITAL LETTER U WITH CIRCUMFLEX) 92 0x00DC Ü (LATIN CAPITAL LETTER U WITH DIAERESIS) 93 0x0130 İ (LATIN CAPITAL LETTER I WITH DOT ABOVE) 94 0x015E Ş (LATIN CAPITAL LETTER S WITH CEDILLA) 95 0x00DF ß (LATIN SMALL LETTER SHARP S) 96 0x00E0 à (LATIN SMALL LETTER A WITH GRAVE) 97 0x00E1 á (LATIN SMALL LETTER A WITH ACUTE) 98 0x00E2 â (LATIN SMALL LETTER A WITH CIRCUMFLEX) 99 0x00E3 ã (LATIN SMALL LETTER A WITH TILDE) 100 0x00E4 ä (LATIN SMALL LETTER A WITH DIAERESIS) 101 0x00E5 å (LATIN SMALL LETTER A WITH RING ABOVE) 102 0x00E6 æ (LATIN SMALL LETTER AE) 103 0x00E7 ç (LATIN SMALL LETTER C WITH CEDILLA) 104 0x00E8 è (LATIN SMALL LETTER E WITH GRAVE) 105 0x00E9 é (LATIN SMALL LETTER E WITH ACUTE) 106 0x00EA ê (LATIN SMALL LETTER E WITH CIRCUMFLEX) 107 0x00EB ë (LATIN SMALL LETTER E WITH DIAERESIS) 108 0x00EC ì (LATIN SMALL LETTER I WITH GRAVE) 109 0x00ED í (LATIN SMALL LETTER I WITH ACUTE) 110 0x00EE î (LATIN SMALL LETTER I WITH CIRCUMFLEX) 111 0x00EF ï (LATIN SMALL LETTER I WITH DIAERESIS) 112 0x011F ğ (LATIN SMALL LETTER G WITH BREVE) 113 0x00F1 ñ (LATIN SMALL LETTER N WITH TILDE) 114 0x00F2 ò (LATIN SMALL LETTER O WITH GRAVE) 115 0x00F3 ó (LATIN SMALL LETTER O WITH ACUTE) 116 0x00F4 ô (LATIN SMALL LETTER O WITH CIRCUMFLEX) 117 0x00F5 õ (LATIN SMALL LETTER O WITH TILDE) 118 0x00F6 ö (LATIN SMALL LETTER O WITH DIAERESIS) 119 0x00F7 ÷ (DIVISION SIGN) 120 0x00F8 ø (LATIN SMALL LETTER O WITH STROKE) 121 0x00F9 ù (LATIN SMALL LETTER U WITH GRAVE) 122 0x00FA ú (LATIN SMALL LETTER U WITH ACUTE) 123 0x00FB û (LATIN SMALL LETTER U WITH CIRCUMFLEX) 124 0x00FC ü (LATIN SMALL LETTER U WITH DIAERESIS) 125 0x0131 ı (LATIN SMALL LETTER DOTLESS I) 126 0x015F ş (LATIN SMALL LETTER S WITH CEDILLA) 127 0x00FF ÿ (LATIN SMALL LETTER Y WITH DIAERESIS) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-windows-1255.txt������������������������������������������������������������0000664�0000000�0000000�00000010444�15202323131�0017660�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-windows-1255.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: cd7fb43c97eefa1651084d92d02af53ad668bd848528c18c3b1af5c06b499651 # Date: 2018-01-06 0 0x20AC € (EURO SIGN) 1 0x0081  (<control>) 2 0x201A ‚ (SINGLE LOW-9 QUOTATION MARK) 3 0x0192 ƒ (LATIN SMALL LETTER F WITH HOOK) 4 0x201E „ (DOUBLE LOW-9 QUOTATION MARK) 5 0x2026 … (HORIZONTAL ELLIPSIS) 6 0x2020 † (DAGGER) 7 0x2021 ‡ (DOUBLE DAGGER) 8 0x02C6 ˆ (MODIFIER LETTER CIRCUMFLEX ACCENT) 9 0x2030 ‰ (PER MILLE SIGN) 10 0x008A Š (<control>) 11 0x2039 ‹ (SINGLE LEFT-POINTING ANGLE QUOTATION MARK) 12 0x008C Œ (<control>) 13 0x008D  (<control>) 14 0x008E Ž (<control>) 15 0x008F  (<control>) 16 0x0090  (<control>) 17 0x2018 ‘ (LEFT SINGLE QUOTATION MARK) 18 0x2019 ’ (RIGHT SINGLE QUOTATION MARK) 19 0x201C “ (LEFT DOUBLE QUOTATION MARK) 20 0x201D ” (RIGHT DOUBLE QUOTATION MARK) 21 0x2022 • (BULLET) 22 0x2013 – (EN DASH) 23 0x2014 — (EM DASH) 24 0x02DC ˜ (SMALL TILDE) 25 0x2122 ™ (TRADE MARK SIGN) 26 0x009A š (<control>) 27 0x203A › (SINGLE RIGHT-POINTING ANGLE QUOTATION MARK) 28 0x009C œ (<control>) 29 0x009D  (<control>) 30 0x009E ž (<control>) 31 0x009F Ÿ (<control>) 32 0x00A0   (NO-BREAK SPACE) 33 0x00A1 ¡ (INVERTED EXCLAMATION MARK) 34 0x00A2 ¢ (CENT SIGN) 35 0x00A3 £ (POUND SIGN) 36 0x20AA ₪ (NEW SHEQEL SIGN) 37 0x00A5 ¥ (YEN SIGN) 38 0x00A6 ¦ (BROKEN BAR) 39 0x00A7 § (SECTION SIGN) 40 0x00A8 ¨ (DIAERESIS) 41 0x00A9 © (COPYRIGHT SIGN) 42 0x00D7 × (MULTIPLICATION SIGN) 43 0x00AB « (LEFT-POINTING DOUBLE ANGLE QUOTATION MARK) 44 0x00AC ¬ (NOT SIGN) 45 0x00AD ­ (SOFT HYPHEN) 46 0x00AE ® (REGISTERED SIGN) 47 0x00AF ¯ (MACRON) 48 0x00B0 ° (DEGREE SIGN) 49 0x00B1 ± (PLUS-MINUS SIGN) 50 0x00B2 ² (SUPERSCRIPT TWO) 51 0x00B3 ³ (SUPERSCRIPT THREE) 52 0x00B4 ´ (ACUTE ACCENT) 53 0x00B5 µ (MICRO SIGN) 54 0x00B6 ¶ (PILCROW SIGN) 55 0x00B7 · (MIDDLE DOT) 56 0x00B8 ¸ (CEDILLA) 57 0x00B9 ¹ (SUPERSCRIPT ONE) 58 0x00F7 ÷ (DIVISION SIGN) 59 0x00BB » (RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK) 60 0x00BC ¼ (VULGAR FRACTION ONE QUARTER) 61 0x00BD ½ (VULGAR FRACTION ONE HALF) 62 0x00BE ¾ (VULGAR FRACTION THREE QUARTERS) 63 0x00BF ¿ (INVERTED QUESTION MARK) 64 0x05B0 ְ (HEBREW POINT SHEVA) 65 0x05B1 ֱ (HEBREW POINT HATAF SEGOL) 66 0x05B2 ֲ (HEBREW POINT HATAF PATAH) 67 0x05B3 ֳ (HEBREW POINT HATAF QAMATS) 68 0x05B4 ִ (HEBREW POINT HIRIQ) 69 0x05B5 ֵ (HEBREW POINT TSERE) 70 0x05B6 ֶ (HEBREW POINT SEGOL) 71 0x05B7 ַ (HEBREW POINT PATAH) 72 0x05B8 ָ (HEBREW POINT QAMATS) 73 0x05B9 ֹ (HEBREW POINT HOLAM) 74 0x05BA ֺ (HEBREW POINT HOLAM HASER FOR VAV) 75 0x05BB ֻ (HEBREW POINT QUBUTS) 76 0x05BC ּ (HEBREW POINT DAGESH OR MAPIQ) 77 0x05BD ֽ (HEBREW POINT METEG) 78 0x05BE ־ (HEBREW PUNCTUATION MAQAF) 79 0x05BF ֿ (HEBREW POINT RAFE) 80 0x05C0 ׀ (HEBREW PUNCTUATION PASEQ) 81 0x05C1 ׁ (HEBREW POINT SHIN DOT) 82 0x05C2 ׂ (HEBREW POINT SIN DOT) 83 0x05C3 ׃ (HEBREW PUNCTUATION SOF PASUQ) 84 0x05F0 װ (HEBREW LIGATURE YIDDISH DOUBLE VAV) 85 0x05F1 ױ (HEBREW LIGATURE YIDDISH VAV YOD) 86 0x05F2 ײ (HEBREW LIGATURE YIDDISH DOUBLE YOD) 87 0x05F3 ׳ (HEBREW PUNCTUATION GERESH) 88 0x05F4 ״ (HEBREW PUNCTUATION GERSHAYIM) 96 0x05D0 א (HEBREW LETTER ALEF) 97 0x05D1 ב (HEBREW LETTER BET) 98 0x05D2 ג (HEBREW LETTER GIMEL) 99 0x05D3 ד (HEBREW LETTER DALET) 100 0x05D4 ה (HEBREW LETTER HE) 101 0x05D5 ו (HEBREW LETTER VAV) 102 0x05D6 ז (HEBREW LETTER ZAYIN) 103 0x05D7 ח (HEBREW LETTER HET) 104 0x05D8 ט (HEBREW LETTER TET) 105 0x05D9 י (HEBREW LETTER YOD) 106 0x05DA ך (HEBREW LETTER FINAL KAF) 107 0x05DB כ (HEBREW LETTER KAF) 108 0x05DC ל (HEBREW LETTER LAMED) 109 0x05DD ם (HEBREW LETTER FINAL MEM) 110 0x05DE מ (HEBREW LETTER MEM) 111 0x05DF ן (HEBREW LETTER FINAL NUN) 112 0x05E0 נ (HEBREW LETTER NUN) 113 0x05E1 ס (HEBREW LETTER SAMEKH) 114 0x05E2 ע (HEBREW LETTER AYIN) 115 0x05E3 ף (HEBREW LETTER FINAL PE) 116 0x05E4 פ (HEBREW LETTER PE) 117 0x05E5 ץ (HEBREW LETTER FINAL TSADI) 118 0x05E6 צ (HEBREW LETTER TSADI) 119 0x05E7 ק (HEBREW LETTER QOF) 120 0x05E8 ר (HEBREW LETTER RESH) 121 0x05E9 ש (HEBREW LETTER SHIN) 122 0x05EA ת (HEBREW LETTER TAV) 125 0x200E ‎ (LEFT-TO-RIGHT MARK) 126 0x200F ‏ (RIGHT-TO-LEFT MARK) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-windows-1256.txt������������������������������������������������������������0000664�0000000�0000000�00000011556�15202323131�0017666�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-windows-1256.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 161bdb381f16408e8bebcc8f5310c4190af0e359de8d9bbaa3628ce2f0875509 # Date: 2018-01-06 0 0x20AC € (EURO SIGN) 1 0x067E پ (ARABIC LETTER PEH) 2 0x201A ‚ (SINGLE LOW-9 QUOTATION MARK) 3 0x0192 ƒ (LATIN SMALL LETTER F WITH HOOK) 4 0x201E „ (DOUBLE LOW-9 QUOTATION MARK) 5 0x2026 … (HORIZONTAL ELLIPSIS) 6 0x2020 † (DAGGER) 7 0x2021 ‡ (DOUBLE DAGGER) 8 0x02C6 ˆ (MODIFIER LETTER CIRCUMFLEX ACCENT) 9 0x2030 ‰ (PER MILLE SIGN) 10 0x0679 ٹ (ARABIC LETTER TTEH) 11 0x2039 ‹ (SINGLE LEFT-POINTING ANGLE QUOTATION MARK) 12 0x0152 Œ (LATIN CAPITAL LIGATURE OE) 13 0x0686 چ (ARABIC LETTER TCHEH) 14 0x0698 ژ (ARABIC LETTER JEH) 15 0x0688 ڈ (ARABIC LETTER DDAL) 16 0x06AF گ (ARABIC LETTER GAF) 17 0x2018 ‘ (LEFT SINGLE QUOTATION MARK) 18 0x2019 ’ (RIGHT SINGLE QUOTATION MARK) 19 0x201C “ (LEFT DOUBLE QUOTATION MARK) 20 0x201D ” (RIGHT DOUBLE QUOTATION MARK) 21 0x2022 • (BULLET) 22 0x2013 – (EN DASH) 23 0x2014 — (EM DASH) 24 0x06A9 ک (ARABIC LETTER KEHEH) 25 0x2122 ™ (TRADE MARK SIGN) 26 0x0691 ڑ (ARABIC LETTER RREH) 27 0x203A › (SINGLE RIGHT-POINTING ANGLE QUOTATION MARK) 28 0x0153 œ (LATIN SMALL LIGATURE OE) 29 0x200C ‌ (ZERO WIDTH NON-JOINER) 30 0x200D ‍ (ZERO WIDTH JOINER) 31 0x06BA ں (ARABIC LETTER NOON GHUNNA) 32 0x00A0   (NO-BREAK SPACE) 33 0x060C ، (ARABIC COMMA) 34 0x00A2 ¢ (CENT SIGN) 35 0x00A3 £ (POUND SIGN) 36 0x00A4 ¤ (CURRENCY SIGN) 37 0x00A5 ¥ (YEN SIGN) 38 0x00A6 ¦ (BROKEN BAR) 39 0x00A7 § (SECTION SIGN) 40 0x00A8 ¨ (DIAERESIS) 41 0x00A9 © (COPYRIGHT SIGN) 42 0x06BE ھ (ARABIC LETTER HEH DOACHASHMEE) 43 0x00AB « (LEFT-POINTING DOUBLE ANGLE QUOTATION MARK) 44 0x00AC ¬ (NOT SIGN) 45 0x00AD ­ (SOFT HYPHEN) 46 0x00AE ® (REGISTERED SIGN) 47 0x00AF ¯ (MACRON) 48 0x00B0 ° (DEGREE SIGN) 49 0x00B1 ± (PLUS-MINUS SIGN) 50 0x00B2 ² (SUPERSCRIPT TWO) 51 0x00B3 ³ (SUPERSCRIPT THREE) 52 0x00B4 ´ (ACUTE ACCENT) 53 0x00B5 µ (MICRO SIGN) 54 0x00B6 ¶ (PILCROW SIGN) 55 0x00B7 · (MIDDLE DOT) 56 0x00B8 ¸ (CEDILLA) 57 0x00B9 ¹ (SUPERSCRIPT ONE) 58 0x061B ؛ (ARABIC SEMICOLON) 59 0x00BB » (RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK) 60 0x00BC ¼ (VULGAR FRACTION ONE QUARTER) 61 0x00BD ½ (VULGAR FRACTION ONE HALF) 62 0x00BE ¾ (VULGAR FRACTION THREE QUARTERS) 63 0x061F ؟ (ARABIC QUESTION MARK) 64 0x06C1 ہ (ARABIC LETTER HEH GOAL) 65 0x0621 ء (ARABIC LETTER HAMZA) 66 0x0622 آ (ARABIC LETTER ALEF WITH MADDA ABOVE) 67 0x0623 أ (ARABIC LETTER ALEF WITH HAMZA ABOVE) 68 0x0624 ؤ (ARABIC LETTER WAW WITH HAMZA ABOVE) 69 0x0625 إ (ARABIC LETTER ALEF WITH HAMZA BELOW) 70 0x0626 ئ (ARABIC LETTER YEH WITH HAMZA ABOVE) 71 0x0627 ا (ARABIC LETTER ALEF) 72 0x0628 ب (ARABIC LETTER BEH) 73 0x0629 ة (ARABIC LETTER TEH MARBUTA) 74 0x062A ت (ARABIC LETTER TEH) 75 0x062B ث (ARABIC LETTER THEH) 76 0x062C ج (ARABIC LETTER JEEM) 77 0x062D ح (ARABIC LETTER HAH) 78 0x062E خ (ARABIC LETTER KHAH) 79 0x062F د (ARABIC LETTER DAL) 80 0x0630 ذ (ARABIC LETTER THAL) 81 0x0631 ر (ARABIC LETTER REH) 82 0x0632 ز (ARABIC LETTER ZAIN) 83 0x0633 س (ARABIC LETTER SEEN) 84 0x0634 ش (ARABIC LETTER SHEEN) 85 0x0635 ص (ARABIC LETTER SAD) 86 0x0636 ض (ARABIC LETTER DAD) 87 0x00D7 × (MULTIPLICATION SIGN) 88 0x0637 ط (ARABIC LETTER TAH) 89 0x0638 ظ (ARABIC LETTER ZAH) 90 0x0639 ع (ARABIC LETTER AIN) 91 0x063A غ (ARABIC LETTER GHAIN) 92 0x0640 ـ (ARABIC TATWEEL) 93 0x0641 ف (ARABIC LETTER FEH) 94 0x0642 ق (ARABIC LETTER QAF) 95 0x0643 ك (ARABIC LETTER KAF) 96 0x00E0 à (LATIN SMALL LETTER A WITH GRAVE) 97 0x0644 ل (ARABIC LETTER LAM) 98 0x00E2 â (LATIN SMALL LETTER A WITH CIRCUMFLEX) 99 0x0645 م (ARABIC LETTER MEEM) 100 0x0646 ن (ARABIC LETTER NOON) 101 0x0647 ه (ARABIC LETTER HEH) 102 0x0648 و (ARABIC LETTER WAW) 103 0x00E7 ç (LATIN SMALL LETTER C WITH CEDILLA) 104 0x00E8 è (LATIN SMALL LETTER E WITH GRAVE) 105 0x00E9 é (LATIN SMALL LETTER E WITH ACUTE) 106 0x00EA ê (LATIN SMALL LETTER E WITH CIRCUMFLEX) 107 0x00EB ë (LATIN SMALL LETTER E WITH DIAERESIS) 108 0x0649 ى (ARABIC LETTER ALEF MAKSURA) 109 0x064A ي (ARABIC LETTER YEH) 110 0x00EE î (LATIN SMALL LETTER I WITH CIRCUMFLEX) 111 0x00EF ï (LATIN SMALL LETTER I WITH DIAERESIS) 112 0x064B ً (ARABIC FATHATAN) 113 0x064C ٌ (ARABIC DAMMATAN) 114 0x064D ٍ (ARABIC KASRATAN) 115 0x064E َ (ARABIC FATHA) 116 0x00F4 ô (LATIN SMALL LETTER O WITH CIRCUMFLEX) 117 0x064F ُ (ARABIC DAMMA) 118 0x0650 ِ (ARABIC KASRA) 119 0x00F7 ÷ (DIVISION SIGN) 120 0x0651 ّ (ARABIC SHADDA) 121 0x00F9 ù (LATIN SMALL LETTER U WITH GRAVE) 122 0x0652 ْ (ARABIC SUKUN) 123 0x00FB û (LATIN SMALL LETTER U WITH CIRCUMFLEX) 124 0x00FC ü (LATIN SMALL LETTER U WITH DIAERESIS) 125 0x200E ‎ (LEFT-TO-RIGHT MARK) 126 0x200F ‏ (RIGHT-TO-LEFT MARK) 127 0x06D2 ے (ARABIC LETTER YEH BARREE) ��������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-windows-1257.txt������������������������������������������������������������0000664�0000000�0000000�00000012546�15202323131�0017667�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-windows-1257.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: cc7256bdd10a5b8dc7fb6f994659f307dfcae60def9aa6c29d811f85e2842c47 # Date: 2018-01-06 0 0x20AC € (EURO SIGN) 1 0x0081  (<control>) 2 0x201A ‚ (SINGLE LOW-9 QUOTATION MARK) 3 0x0083 ƒ (<control>) 4 0x201E „ (DOUBLE LOW-9 QUOTATION MARK) 5 0x2026 … (HORIZONTAL ELLIPSIS) 6 0x2020 † (DAGGER) 7 0x2021 ‡ (DOUBLE DAGGER) 8 0x0088 ˆ (<control>) 9 0x2030 ‰ (PER MILLE SIGN) 10 0x008A Š (<control>) 11 0x2039 ‹ (SINGLE LEFT-POINTING ANGLE QUOTATION MARK) 12 0x008C Œ (<control>) 13 0x00A8 ¨ (DIAERESIS) 14 0x02C7 ˇ (CARON) 15 0x00B8 ¸ (CEDILLA) 16 0x0090  (<control>) 17 0x2018 ‘ (LEFT SINGLE QUOTATION MARK) 18 0x2019 ’ (RIGHT SINGLE QUOTATION MARK) 19 0x201C “ (LEFT DOUBLE QUOTATION MARK) 20 0x201D ” (RIGHT DOUBLE QUOTATION MARK) 21 0x2022 • (BULLET) 22 0x2013 – (EN DASH) 23 0x2014 — (EM DASH) 24 0x0098 ˜ (<control>) 25 0x2122 ™ (TRADE MARK SIGN) 26 0x009A š (<control>) 27 0x203A › (SINGLE RIGHT-POINTING ANGLE QUOTATION MARK) 28 0x009C œ (<control>) 29 0x00AF ¯ (MACRON) 30 0x02DB ˛ (OGONEK) 31 0x009F Ÿ (<control>) 32 0x00A0   (NO-BREAK SPACE) 34 0x00A2 ¢ (CENT SIGN) 35 0x00A3 £ (POUND SIGN) 36 0x00A4 ¤ (CURRENCY SIGN) 38 0x00A6 ¦ (BROKEN BAR) 39 0x00A7 § (SECTION SIGN) 40 0x00D8 Ø (LATIN CAPITAL LETTER O WITH STROKE) 41 0x00A9 © (COPYRIGHT SIGN) 42 0x0156 Ŗ (LATIN CAPITAL LETTER R WITH CEDILLA) 43 0x00AB « (LEFT-POINTING DOUBLE ANGLE QUOTATION MARK) 44 0x00AC ¬ (NOT SIGN) 45 0x00AD ­ (SOFT HYPHEN) 46 0x00AE ® (REGISTERED SIGN) 47 0x00C6 Æ (LATIN CAPITAL LETTER AE) 48 0x00B0 ° (DEGREE SIGN) 49 0x00B1 ± (PLUS-MINUS SIGN) 50 0x00B2 ² (SUPERSCRIPT TWO) 51 0x00B3 ³ (SUPERSCRIPT THREE) 52 0x00B4 ´ (ACUTE ACCENT) 53 0x00B5 µ (MICRO SIGN) 54 0x00B6 ¶ (PILCROW SIGN) 55 0x00B7 · (MIDDLE DOT) 56 0x00F8 ø (LATIN SMALL LETTER O WITH STROKE) 57 0x00B9 ¹ (SUPERSCRIPT ONE) 58 0x0157 ŗ (LATIN SMALL LETTER R WITH CEDILLA) 59 0x00BB » (RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK) 60 0x00BC ¼ (VULGAR FRACTION ONE QUARTER) 61 0x00BD ½ (VULGAR FRACTION ONE HALF) 62 0x00BE ¾ (VULGAR FRACTION THREE QUARTERS) 63 0x00E6 æ (LATIN SMALL LETTER AE) 64 0x0104 Ą (LATIN CAPITAL LETTER A WITH OGONEK) 65 0x012E Į (LATIN CAPITAL LETTER I WITH OGONEK) 66 0x0100 Ā (LATIN CAPITAL LETTER A WITH MACRON) 67 0x0106 Ć (LATIN CAPITAL LETTER C WITH ACUTE) 68 0x00C4 Ä (LATIN CAPITAL LETTER A WITH DIAERESIS) 69 0x00C5 Å (LATIN CAPITAL LETTER A WITH RING ABOVE) 70 0x0118 Ę (LATIN CAPITAL LETTER E WITH OGONEK) 71 0x0112 Ē (LATIN CAPITAL LETTER E WITH MACRON) 72 0x010C Č (LATIN CAPITAL LETTER C WITH CARON) 73 0x00C9 É (LATIN CAPITAL LETTER E WITH ACUTE) 74 0x0179 Ź (LATIN CAPITAL LETTER Z WITH ACUTE) 75 0x0116 Ė (LATIN CAPITAL LETTER E WITH DOT ABOVE) 76 0x0122 Ģ (LATIN CAPITAL LETTER G WITH CEDILLA) 77 0x0136 Ķ (LATIN CAPITAL LETTER K WITH CEDILLA) 78 0x012A Ī (LATIN CAPITAL LETTER I WITH MACRON) 79 0x013B Ļ (LATIN CAPITAL LETTER L WITH CEDILLA) 80 0x0160 Š (LATIN CAPITAL LETTER S WITH CARON) 81 0x0143 Ń (LATIN CAPITAL LETTER N WITH ACUTE) 82 0x0145 Ņ (LATIN CAPITAL LETTER N WITH CEDILLA) 83 0x00D3 Ó (LATIN CAPITAL LETTER O WITH ACUTE) 84 0x014C Ō (LATIN CAPITAL LETTER O WITH MACRON) 85 0x00D5 Õ (LATIN CAPITAL LETTER O WITH TILDE) 86 0x00D6 Ö (LATIN CAPITAL LETTER O WITH DIAERESIS) 87 0x00D7 × (MULTIPLICATION SIGN) 88 0x0172 Ų (LATIN CAPITAL LETTER U WITH OGONEK) 89 0x0141 Ł (LATIN CAPITAL LETTER L WITH STROKE) 90 0x015A Ś (LATIN CAPITAL LETTER S WITH ACUTE) 91 0x016A Ū (LATIN CAPITAL LETTER U WITH MACRON) 92 0x00DC Ü (LATIN CAPITAL LETTER U WITH DIAERESIS) 93 0x017B Ż (LATIN CAPITAL LETTER Z WITH DOT ABOVE) 94 0x017D Ž (LATIN CAPITAL LETTER Z WITH CARON) 95 0x00DF ß (LATIN SMALL LETTER SHARP S) 96 0x0105 ą (LATIN SMALL LETTER A WITH OGONEK) 97 0x012F į (LATIN SMALL LETTER I WITH OGONEK) 98 0x0101 ā (LATIN SMALL LETTER A WITH MACRON) 99 0x0107 ć (LATIN SMALL LETTER C WITH ACUTE) 100 0x00E4 ä (LATIN SMALL LETTER A WITH DIAERESIS) 101 0x00E5 å (LATIN SMALL LETTER A WITH RING ABOVE) 102 0x0119 ę (LATIN SMALL LETTER E WITH OGONEK) 103 0x0113 ē (LATIN SMALL LETTER E WITH MACRON) 104 0x010D č (LATIN SMALL LETTER C WITH CARON) 105 0x00E9 é (LATIN SMALL LETTER E WITH ACUTE) 106 0x017A ź (LATIN SMALL LETTER Z WITH ACUTE) 107 0x0117 ė (LATIN SMALL LETTER E WITH DOT ABOVE) 108 0x0123 ģ (LATIN SMALL LETTER G WITH CEDILLA) 109 0x0137 ķ (LATIN SMALL LETTER K WITH CEDILLA) 110 0x012B ī (LATIN SMALL LETTER I WITH MACRON) 111 0x013C ļ (LATIN SMALL LETTER L WITH CEDILLA) 112 0x0161 š (LATIN SMALL LETTER S WITH CARON) 113 0x0144 ń (LATIN SMALL LETTER N WITH ACUTE) 114 0x0146 ņ (LATIN SMALL LETTER N WITH CEDILLA) 115 0x00F3 ó (LATIN SMALL LETTER O WITH ACUTE) 116 0x014D ō (LATIN SMALL LETTER O WITH MACRON) 117 0x00F5 õ (LATIN SMALL LETTER O WITH TILDE) 118 0x00F6 ö (LATIN SMALL LETTER O WITH DIAERESIS) 119 0x00F7 ÷ (DIVISION SIGN) 120 0x0173 ų (LATIN SMALL LETTER U WITH OGONEK) 121 0x0142 ł (LATIN SMALL LETTER L WITH STROKE) 122 0x015B ś (LATIN SMALL LETTER S WITH ACUTE) 123 0x016B ū (LATIN SMALL LETTER U WITH MACRON) 124 0x00FC ü (LATIN SMALL LETTER U WITH DIAERESIS) 125 0x017C ż (LATIN SMALL LETTER Z WITH DOT ABOVE) 126 0x017E ž (LATIN SMALL LETTER Z WITH CARON) 127 0x02D9 ˙ (DOT ABOVE) ����������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-windows-1258.txt������������������������������������������������������������0000664�0000000�0000000�00000012621�15202323131�0017662�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-windows-1258.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 198bacedfcf24390e219240a7b776b6cec34cff070330b08a601a69c67f7eb24 # Date: 2018-01-06 0 0x20AC € (EURO SIGN) 1 0x0081  (<control>) 2 0x201A ‚ (SINGLE LOW-9 QUOTATION MARK) 3 0x0192 ƒ (LATIN SMALL LETTER F WITH HOOK) 4 0x201E „ (DOUBLE LOW-9 QUOTATION MARK) 5 0x2026 … (HORIZONTAL ELLIPSIS) 6 0x2020 † (DAGGER) 7 0x2021 ‡ (DOUBLE DAGGER) 8 0x02C6 ˆ (MODIFIER LETTER CIRCUMFLEX ACCENT) 9 0x2030 ‰ (PER MILLE SIGN) 10 0x008A Š (<control>) 11 0x2039 ‹ (SINGLE LEFT-POINTING ANGLE QUOTATION MARK) 12 0x0152 Œ (LATIN CAPITAL LIGATURE OE) 13 0x008D  (<control>) 14 0x008E Ž (<control>) 15 0x008F  (<control>) 16 0x0090  (<control>) 17 0x2018 ‘ (LEFT SINGLE QUOTATION MARK) 18 0x2019 ’ (RIGHT SINGLE QUOTATION MARK) 19 0x201C “ (LEFT DOUBLE QUOTATION MARK) 20 0x201D ” (RIGHT DOUBLE QUOTATION MARK) 21 0x2022 • (BULLET) 22 0x2013 – (EN DASH) 23 0x2014 — (EM DASH) 24 0x02DC ˜ (SMALL TILDE) 25 0x2122 ™ (TRADE MARK SIGN) 26 0x009A š (<control>) 27 0x203A › (SINGLE RIGHT-POINTING ANGLE QUOTATION MARK) 28 0x0153 œ (LATIN SMALL LIGATURE OE) 29 0x009D  (<control>) 30 0x009E ž (<control>) 31 0x0178 Ÿ (LATIN CAPITAL LETTER Y WITH DIAERESIS) 32 0x00A0   (NO-BREAK SPACE) 33 0x00A1 ¡ (INVERTED EXCLAMATION MARK) 34 0x00A2 ¢ (CENT SIGN) 35 0x00A3 £ (POUND SIGN) 36 0x00A4 ¤ (CURRENCY SIGN) 37 0x00A5 ¥ (YEN SIGN) 38 0x00A6 ¦ (BROKEN BAR) 39 0x00A7 § (SECTION SIGN) 40 0x00A8 ¨ (DIAERESIS) 41 0x00A9 © (COPYRIGHT SIGN) 42 0x00AA ª (FEMININE ORDINAL INDICATOR) 43 0x00AB « (LEFT-POINTING DOUBLE ANGLE QUOTATION MARK) 44 0x00AC ¬ (NOT SIGN) 45 0x00AD ­ (SOFT HYPHEN) 46 0x00AE ® (REGISTERED SIGN) 47 0x00AF ¯ (MACRON) 48 0x00B0 ° (DEGREE SIGN) 49 0x00B1 ± (PLUS-MINUS SIGN) 50 0x00B2 ² (SUPERSCRIPT TWO) 51 0x00B3 ³ (SUPERSCRIPT THREE) 52 0x00B4 ´ (ACUTE ACCENT) 53 0x00B5 µ (MICRO SIGN) 54 0x00B6 ¶ (PILCROW SIGN) 55 0x00B7 · (MIDDLE DOT) 56 0x00B8 ¸ (CEDILLA) 57 0x00B9 ¹ (SUPERSCRIPT ONE) 58 0x00BA º (MASCULINE ORDINAL INDICATOR) 59 0x00BB » (RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK) 60 0x00BC ¼ (VULGAR FRACTION ONE QUARTER) 61 0x00BD ½ (VULGAR FRACTION ONE HALF) 62 0x00BE ¾ (VULGAR FRACTION THREE QUARTERS) 63 0x00BF ¿ (INVERTED QUESTION MARK) 64 0x00C0 À (LATIN CAPITAL LETTER A WITH GRAVE) 65 0x00C1 Á (LATIN CAPITAL LETTER A WITH ACUTE) 66 0x00C2  (LATIN CAPITAL LETTER A WITH CIRCUMFLEX) 67 0x0102 Ă (LATIN CAPITAL LETTER A WITH BREVE) 68 0x00C4 Ä (LATIN CAPITAL LETTER A WITH DIAERESIS) 69 0x00C5 Å (LATIN CAPITAL LETTER A WITH RING ABOVE) 70 0x00C6 Æ (LATIN CAPITAL LETTER AE) 71 0x00C7 Ç (LATIN CAPITAL LETTER C WITH CEDILLA) 72 0x00C8 È (LATIN CAPITAL LETTER E WITH GRAVE) 73 0x00C9 É (LATIN CAPITAL LETTER E WITH ACUTE) 74 0x00CA Ê (LATIN CAPITAL LETTER E WITH CIRCUMFLEX) 75 0x00CB Ë (LATIN CAPITAL LETTER E WITH DIAERESIS) 76 0x0300 ̀ (COMBINING GRAVE ACCENT) 77 0x00CD Í (LATIN CAPITAL LETTER I WITH ACUTE) 78 0x00CE Î (LATIN CAPITAL LETTER I WITH CIRCUMFLEX) 79 0x00CF Ï (LATIN CAPITAL LETTER I WITH DIAERESIS) 80 0x0110 Đ (LATIN CAPITAL LETTER D WITH STROKE) 81 0x00D1 Ñ (LATIN CAPITAL LETTER N WITH TILDE) 82 0x0309 ̉ (COMBINING HOOK ABOVE) 83 0x00D3 Ó (LATIN CAPITAL LETTER O WITH ACUTE) 84 0x00D4 Ô (LATIN CAPITAL LETTER O WITH CIRCUMFLEX) 85 0x01A0 Ơ (LATIN CAPITAL LETTER O WITH HORN) 86 0x00D6 Ö (LATIN CAPITAL LETTER O WITH DIAERESIS) 87 0x00D7 × (MULTIPLICATION SIGN) 88 0x00D8 Ø (LATIN CAPITAL LETTER O WITH STROKE) 89 0x00D9 Ù (LATIN CAPITAL LETTER U WITH GRAVE) 90 0x00DA Ú (LATIN CAPITAL LETTER U WITH ACUTE) 91 0x00DB Û (LATIN CAPITAL LETTER U WITH CIRCUMFLEX) 92 0x00DC Ü (LATIN CAPITAL LETTER U WITH DIAERESIS) 93 0x01AF Ư (LATIN CAPITAL LETTER U WITH HORN) 94 0x0303 ̃ (COMBINING TILDE) 95 0x00DF ß (LATIN SMALL LETTER SHARP S) 96 0x00E0 à (LATIN SMALL LETTER A WITH GRAVE) 97 0x00E1 á (LATIN SMALL LETTER A WITH ACUTE) 98 0x00E2 â (LATIN SMALL LETTER A WITH CIRCUMFLEX) 99 0x0103 ă (LATIN SMALL LETTER A WITH BREVE) 100 0x00E4 ä (LATIN SMALL LETTER A WITH DIAERESIS) 101 0x00E5 å (LATIN SMALL LETTER A WITH RING ABOVE) 102 0x00E6 æ (LATIN SMALL LETTER AE) 103 0x00E7 ç (LATIN SMALL LETTER C WITH CEDILLA) 104 0x00E8 è (LATIN SMALL LETTER E WITH GRAVE) 105 0x00E9 é (LATIN SMALL LETTER E WITH ACUTE) 106 0x00EA ê (LATIN SMALL LETTER E WITH CIRCUMFLEX) 107 0x00EB ë (LATIN SMALL LETTER E WITH DIAERESIS) 108 0x0301 ́ (COMBINING ACUTE ACCENT) 109 0x00ED í (LATIN SMALL LETTER I WITH ACUTE) 110 0x00EE î (LATIN SMALL LETTER I WITH CIRCUMFLEX) 111 0x00EF ï (LATIN SMALL LETTER I WITH DIAERESIS) 112 0x0111 đ (LATIN SMALL LETTER D WITH STROKE) 113 0x00F1 ñ (LATIN SMALL LETTER N WITH TILDE) 114 0x0323 ̣ (COMBINING DOT BELOW) 115 0x00F3 ó (LATIN SMALL LETTER O WITH ACUTE) 116 0x00F4 ô (LATIN SMALL LETTER O WITH CIRCUMFLEX) 117 0x01A1 ơ (LATIN SMALL LETTER O WITH HORN) 118 0x00F6 ö (LATIN SMALL LETTER O WITH DIAERESIS) 119 0x00F7 ÷ (DIVISION SIGN) 120 0x00F8 ø (LATIN SMALL LETTER O WITH STROKE) 121 0x00F9 ù (LATIN SMALL LETTER U WITH GRAVE) 122 0x00FA ú (LATIN SMALL LETTER U WITH ACUTE) 123 0x00FB û (LATIN SMALL LETTER U WITH CIRCUMFLEX) 124 0x00FC ü (LATIN SMALL LETTER U WITH DIAERESIS) 125 0x01B0 ư (LATIN SMALL LETTER U WITH HORN) 126 0x20AB ₫ (DONG SIGN) 127 0x00FF ÿ (LATIN SMALL LETTER Y WITH DIAERESIS) ���������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-windows-874.txt�������������������������������������������������������������0000664�0000000�0000000�00000011020�15202323131�0017575�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-windows-874.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: b416583ce125e38474381b31b401a98b19ecf2e57e0998e78a1e18b14894905d # Date: 2018-01-06 0 0x20AC € (EURO SIGN) 1 0x0081  (<control>) 2 0x0082 ‚ (<control>) 3 0x0083 ƒ (<control>) 4 0x0084 „ (<control>) 5 0x2026 … (HORIZONTAL ELLIPSIS) 6 0x0086 † (<control>) 7 0x0087 ‡ (<control>) 8 0x0088 ˆ (<control>) 9 0x0089 ‰ (<control>) 10 0x008A Š (<control>) 11 0x008B ‹ (<control>) 12 0x008C Œ (<control>) 13 0x008D  (<control>) 14 0x008E Ž (<control>) 15 0x008F  (<control>) 16 0x0090  (<control>) 17 0x2018 ‘ (LEFT SINGLE QUOTATION MARK) 18 0x2019 ’ (RIGHT SINGLE QUOTATION MARK) 19 0x201C “ (LEFT DOUBLE QUOTATION MARK) 20 0x201D ” (RIGHT DOUBLE QUOTATION MARK) 21 0x2022 • (BULLET) 22 0x2013 – (EN DASH) 23 0x2014 — (EM DASH) 24 0x0098 ˜ (<control>) 25 0x0099 ™ (<control>) 26 0x009A š (<control>) 27 0x009B › (<control>) 28 0x009C œ (<control>) 29 0x009D  (<control>) 30 0x009E ž (<control>) 31 0x009F Ÿ (<control>) 32 0x00A0   (NO-BREAK SPACE) 33 0x0E01 ก (THAI CHARACTER KO KAI) 34 0x0E02 ข (THAI CHARACTER KHO KHAI) 35 0x0E03 ฃ (THAI CHARACTER KHO KHUAT) 36 0x0E04 ค (THAI CHARACTER KHO KHWAI) 37 0x0E05 ฅ (THAI CHARACTER KHO KHON) 38 0x0E06 ฆ (THAI CHARACTER KHO RAKHANG) 39 0x0E07 ง (THAI CHARACTER NGO NGU) 40 0x0E08 จ (THAI CHARACTER CHO CHAN) 41 0x0E09 ฉ (THAI CHARACTER CHO CHING) 42 0x0E0A ช (THAI CHARACTER CHO CHANG) 43 0x0E0B ซ (THAI CHARACTER SO SO) 44 0x0E0C ฌ (THAI CHARACTER CHO CHOE) 45 0x0E0D ญ (THAI CHARACTER YO YING) 46 0x0E0E ฎ (THAI CHARACTER DO CHADA) 47 0x0E0F ฏ (THAI CHARACTER TO PATAK) 48 0x0E10 ฐ (THAI CHARACTER THO THAN) 49 0x0E11 ฑ (THAI CHARACTER THO NANGMONTHO) 50 0x0E12 ฒ (THAI CHARACTER THO PHUTHAO) 51 0x0E13 ณ (THAI CHARACTER NO NEN) 52 0x0E14 ด (THAI CHARACTER DO DEK) 53 0x0E15 ต (THAI CHARACTER TO TAO) 54 0x0E16 ถ (THAI CHARACTER THO THUNG) 55 0x0E17 ท (THAI CHARACTER THO THAHAN) 56 0x0E18 ธ (THAI CHARACTER THO THONG) 57 0x0E19 น (THAI CHARACTER NO NU) 58 0x0E1A บ (THAI CHARACTER BO BAIMAI) 59 0x0E1B ป (THAI CHARACTER PO PLA) 60 0x0E1C ผ (THAI CHARACTER PHO PHUNG) 61 0x0E1D ฝ (THAI CHARACTER FO FA) 62 0x0E1E พ (THAI CHARACTER PHO PHAN) 63 0x0E1F ฟ (THAI CHARACTER FO FAN) 64 0x0E20 ภ (THAI CHARACTER PHO SAMPHAO) 65 0x0E21 ม (THAI CHARACTER MO MA) 66 0x0E22 ย (THAI CHARACTER YO YAK) 67 0x0E23 ร (THAI CHARACTER RO RUA) 68 0x0E24 ฤ (THAI CHARACTER RU) 69 0x0E25 ล (THAI CHARACTER LO LING) 70 0x0E26 ฦ (THAI CHARACTER LU) 71 0x0E27 ว (THAI CHARACTER WO WAEN) 72 0x0E28 ศ (THAI CHARACTER SO SALA) 73 0x0E29 ษ (THAI CHARACTER SO RUSI) 74 0x0E2A ส (THAI CHARACTER SO SUA) 75 0x0E2B ห (THAI CHARACTER HO HIP) 76 0x0E2C ฬ (THAI CHARACTER LO CHULA) 77 0x0E2D อ (THAI CHARACTER O ANG) 78 0x0E2E ฮ (THAI CHARACTER HO NOKHUK) 79 0x0E2F ฯ (THAI CHARACTER PAIYANNOI) 80 0x0E30 ะ (THAI CHARACTER SARA A) 81 0x0E31 ั (THAI CHARACTER MAI HAN-AKAT) 82 0x0E32 า (THAI CHARACTER SARA AA) 83 0x0E33 ำ (THAI CHARACTER SARA AM) 84 0x0E34 ิ (THAI CHARACTER SARA I) 85 0x0E35 ี (THAI CHARACTER SARA II) 86 0x0E36 ึ (THAI CHARACTER SARA UE) 87 0x0E37 ื (THAI CHARACTER SARA UEE) 88 0x0E38 ุ (THAI CHARACTER SARA U) 89 0x0E39 ู (THAI CHARACTER SARA UU) 90 0x0E3A ฺ (THAI CHARACTER PHINTHU) 95 0x0E3F ฿ (THAI CURRENCY SYMBOL BAHT) 96 0x0E40 เ (THAI CHARACTER SARA E) 97 0x0E41 แ (THAI CHARACTER SARA AE) 98 0x0E42 โ (THAI CHARACTER SARA O) 99 0x0E43 ใ (THAI CHARACTER SARA AI MAIMUAN) 100 0x0E44 ไ (THAI CHARACTER SARA AI MAIMALAI) 101 0x0E45 ๅ (THAI CHARACTER LAKKHANGYAO) 102 0x0E46 ๆ (THAI CHARACTER MAIYAMOK) 103 0x0E47 ็ (THAI CHARACTER MAITAIKHU) 104 0x0E48 ่ (THAI CHARACTER MAI EK) 105 0x0E49 ้ (THAI CHARACTER MAI THO) 106 0x0E4A ๊ (THAI CHARACTER MAI TRI) 107 0x0E4B ๋ (THAI CHARACTER MAI CHATTAWA) 108 0x0E4C ์ (THAI CHARACTER THANTHAKHAT) 109 0x0E4D ํ (THAI CHARACTER NIKHAHIT) 110 0x0E4E ๎ (THAI CHARACTER YAMAKKAN) 111 0x0E4F ๏ (THAI CHARACTER FONGMAN) 112 0x0E50 ๐ (THAI DIGIT ZERO) 113 0x0E51 ๑ (THAI DIGIT ONE) 114 0x0E52 ๒ (THAI DIGIT TWO) 115 0x0E53 ๓ (THAI DIGIT THREE) 116 0x0E54 ๔ (THAI DIGIT FOUR) 117 0x0E55 ๕ (THAI DIGIT FIVE) 118 0x0E56 ๖ (THAI DIGIT SIX) 119 0x0E57 ๗ (THAI DIGIT SEVEN) 120 0x0E58 ๘ (THAI DIGIT EIGHT) 121 0x0E59 ๙ (THAI DIGIT NINE) 122 0x0E5A ๚ (THAI CHARACTER ANGKHANKHU) 123 0x0E5B ๛ (THAI CHARACTER KHOMUT) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/index-x-mac-cyrillic.txt����������������������������������������������������������0000664�0000000�0000000�00000012555�15202323131�0020416�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# For details on index index-x-mac-cyrillic.txt see the Encoding Standard # https://encoding.spec.whatwg.org/ # # Identifier: 73e8e7642c6fa9de29d42819b47fba55b58666fb1e339faeb4a89a0bd7c24d43 # Date: 2018-01-06 0 0x0410 А (CYRILLIC CAPITAL LETTER A) 1 0x0411 Б (CYRILLIC CAPITAL LETTER BE) 2 0x0412 В (CYRILLIC CAPITAL LETTER VE) 3 0x0413 Г (CYRILLIC CAPITAL LETTER GHE) 4 0x0414 Д (CYRILLIC CAPITAL LETTER DE) 5 0x0415 Е (CYRILLIC CAPITAL LETTER IE) 6 0x0416 Ж (CYRILLIC CAPITAL LETTER ZHE) 7 0x0417 З (CYRILLIC CAPITAL LETTER ZE) 8 0x0418 И (CYRILLIC CAPITAL LETTER I) 9 0x0419 Й (CYRILLIC CAPITAL LETTER SHORT I) 10 0x041A К (CYRILLIC CAPITAL LETTER KA) 11 0x041B Л (CYRILLIC CAPITAL LETTER EL) 12 0x041C М (CYRILLIC CAPITAL LETTER EM) 13 0x041D Н (CYRILLIC CAPITAL LETTER EN) 14 0x041E О (CYRILLIC CAPITAL LETTER O) 15 0x041F П (CYRILLIC CAPITAL LETTER PE) 16 0x0420 Р (CYRILLIC CAPITAL LETTER ER) 17 0x0421 С (CYRILLIC CAPITAL LETTER ES) 18 0x0422 Т (CYRILLIC CAPITAL LETTER TE) 19 0x0423 У (CYRILLIC CAPITAL LETTER U) 20 0x0424 Ф (CYRILLIC CAPITAL LETTER EF) 21 0x0425 Х (CYRILLIC CAPITAL LETTER HA) 22 0x0426 Ц (CYRILLIC CAPITAL LETTER TSE) 23 0x0427 Ч (CYRILLIC CAPITAL LETTER CHE) 24 0x0428 Ш (CYRILLIC CAPITAL LETTER SHA) 25 0x0429 Щ (CYRILLIC CAPITAL LETTER SHCHA) 26 0x042A Ъ (CYRILLIC CAPITAL LETTER HARD SIGN) 27 0x042B Ы (CYRILLIC CAPITAL LETTER YERU) 28 0x042C Ь (CYRILLIC CAPITAL LETTER SOFT SIGN) 29 0x042D Э (CYRILLIC CAPITAL LETTER E) 30 0x042E Ю (CYRILLIC CAPITAL LETTER YU) 31 0x042F Я (CYRILLIC CAPITAL LETTER YA) 32 0x2020 † (DAGGER) 33 0x00B0 ° (DEGREE SIGN) 34 0x0490 Ґ (CYRILLIC CAPITAL LETTER GHE WITH UPTURN) 35 0x00A3 £ (POUND SIGN) 36 0x00A7 § (SECTION SIGN) 37 0x2022 • (BULLET) 38 0x00B6 ¶ (PILCROW SIGN) 39 0x0406 І (CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I) 40 0x00AE ® (REGISTERED SIGN) 41 0x00A9 © (COPYRIGHT SIGN) 42 0x2122 ™ (TRADE MARK SIGN) 43 0x0402 Ђ (CYRILLIC CAPITAL LETTER DJE) 44 0x0452 ђ (CYRILLIC SMALL LETTER DJE) 45 0x2260 ≠ (NOT EQUAL TO) 46 0x0403 Ѓ (CYRILLIC CAPITAL LETTER GJE) 47 0x0453 ѓ (CYRILLIC SMALL LETTER GJE) 48 0x221E ∞ (INFINITY) 49 0x00B1 ± (PLUS-MINUS SIGN) 50 0x2264 ≤ (LESS-THAN OR EQUAL TO) 51 0x2265 ≥ (GREATER-THAN OR EQUAL TO) 52 0x0456 і (CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I) 53 0x00B5 µ (MICRO SIGN) 54 0x0491 ґ (CYRILLIC SMALL LETTER GHE WITH UPTURN) 55 0x0408 Ј (CYRILLIC CAPITAL LETTER JE) 56 0x0404 Є (CYRILLIC CAPITAL LETTER UKRAINIAN IE) 57 0x0454 є (CYRILLIC SMALL LETTER UKRAINIAN IE) 58 0x0407 Ї (CYRILLIC CAPITAL LETTER YI) 59 0x0457 ї (CYRILLIC SMALL LETTER YI) 60 0x0409 Љ (CYRILLIC CAPITAL LETTER LJE) 61 0x0459 љ (CYRILLIC SMALL LETTER LJE) 62 0x040A Њ (CYRILLIC CAPITAL LETTER NJE) 63 0x045A њ (CYRILLIC SMALL LETTER NJE) 64 0x0458 ј (CYRILLIC SMALL LETTER JE) 65 0x0405 Ѕ (CYRILLIC CAPITAL LETTER DZE) 66 0x00AC ¬ (NOT SIGN) 67 0x221A √ (SQUARE ROOT) 68 0x0192 ƒ (LATIN SMALL LETTER F WITH HOOK) 69 0x2248 ≈ (ALMOST EQUAL TO) 70 0x2206 ∆ (INCREMENT) 71 0x00AB « (LEFT-POINTING DOUBLE ANGLE QUOTATION MARK) 72 0x00BB » (RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK) 73 0x2026 … (HORIZONTAL ELLIPSIS) 74 0x00A0   (NO-BREAK SPACE) 75 0x040B Ћ (CYRILLIC CAPITAL LETTER TSHE) 76 0x045B ћ (CYRILLIC SMALL LETTER TSHE) 77 0x040C Ќ (CYRILLIC CAPITAL LETTER KJE) 78 0x045C ќ (CYRILLIC SMALL LETTER KJE) 79 0x0455 ѕ (CYRILLIC SMALL LETTER DZE) 80 0x2013 – (EN DASH) 81 0x2014 — (EM DASH) 82 0x201C “ (LEFT DOUBLE QUOTATION MARK) 83 0x201D ” (RIGHT DOUBLE QUOTATION MARK) 84 0x2018 ‘ (LEFT SINGLE QUOTATION MARK) 85 0x2019 ’ (RIGHT SINGLE QUOTATION MARK) 86 0x00F7 ÷ (DIVISION SIGN) 87 0x201E „ (DOUBLE LOW-9 QUOTATION MARK) 88 0x040E Ў (CYRILLIC CAPITAL LETTER SHORT U) 89 0x045E ў (CYRILLIC SMALL LETTER SHORT U) 90 0x040F Џ (CYRILLIC CAPITAL LETTER DZHE) 91 0x045F џ (CYRILLIC SMALL LETTER DZHE) 92 0x2116 № (NUMERO SIGN) 93 0x0401 Ё (CYRILLIC CAPITAL LETTER IO) 94 0x0451 ё (CYRILLIC SMALL LETTER IO) 95 0x044F я (CYRILLIC SMALL LETTER YA) 96 0x0430 а (CYRILLIC SMALL LETTER A) 97 0x0431 б (CYRILLIC SMALL LETTER BE) 98 0x0432 в (CYRILLIC SMALL LETTER VE) 99 0x0433 г (CYRILLIC SMALL LETTER GHE) 100 0x0434 д (CYRILLIC SMALL LETTER DE) 101 0x0435 е (CYRILLIC SMALL LETTER IE) 102 0x0436 ж (CYRILLIC SMALL LETTER ZHE) 103 0x0437 з (CYRILLIC SMALL LETTER ZE) 104 0x0438 и (CYRILLIC SMALL LETTER I) 105 0x0439 й (CYRILLIC SMALL LETTER SHORT I) 106 0x043A к (CYRILLIC SMALL LETTER KA) 107 0x043B л (CYRILLIC SMALL LETTER EL) 108 0x043C м (CYRILLIC SMALL LETTER EM) 109 0x043D н (CYRILLIC SMALL LETTER EN) 110 0x043E о (CYRILLIC SMALL LETTER O) 111 0x043F п (CYRILLIC SMALL LETTER PE) 112 0x0440 р (CYRILLIC SMALL LETTER ER) 113 0x0441 с (CYRILLIC SMALL LETTER ES) 114 0x0442 т (CYRILLIC SMALL LETTER TE) 115 0x0443 у (CYRILLIC SMALL LETTER U) 116 0x0444 ф (CYRILLIC SMALL LETTER EF) 117 0x0445 х (CYRILLIC SMALL LETTER HA) 118 0x0446 ц (CYRILLIC SMALL LETTER TSE) 119 0x0447 ч (CYRILLIC SMALL LETTER CHE) 120 0x0448 ш (CYRILLIC SMALL LETTER SHA) 121 0x0449 щ (CYRILLIC SMALL LETTER SHCHA) 122 0x044A ъ (CYRILLIC SMALL LETTER HARD SIGN) 123 0x044B ы (CYRILLIC SMALL LETTER YERU) 124 0x044C ь (CYRILLIC SMALL LETTER SOFT SIGN) 125 0x044D э (CYRILLIC SMALL LETTER E) 126 0x044E ю (CYRILLIC SMALL LETTER YU) 127 0x20AC € (EURO SIGN) ���������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/kanamap.tab�����������������������������������������������������������������������0000664�0000000�0000000�00000000731�15202323131�0016024�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ぁ あ ぃ い ぅ う ぇ え ぉ お ゕ か ゖ け 𛄲 こ っ つ ゃ や ゅ ゆ ょ よ ゎ わ 𛅐 ゐ 𛅑 ゑ 𛅒 を ァ ア ィ イ ゥ ウ ェ エ ォ オ ヵ カ ㇰ ク ヶ ケ 𛅕 コ ㇱ シ ㇲ ス ッ ツ ㇳ ト ㇴ ヌ ㇵ ハ ㇶ ヒ ㇷ フ ㇸ ヘ ㇹ ホ ㇺ ム ャ ヤ ュ ユ ョ ヨ ㇻ ラ ㇼ リ ㇽ ル ㇾ レ ㇿ ロ ヮ ワ 𛅤 ヰ 𛅥 ヱ 𛅦 ヲ 𛅧 ン ァ ア ィ イ ゥ ウ ェ エ ォ オ ッ ツ ャ ヤ ュ ユ ョ ヨ ���������������������������������������chawan-v0.4.0/res/license.md������������������������������������������������������������������������0000664�0000000�0000000�00000024731�15202323131�0015676�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<title>Licensing</title> # Licensing terms of Chawan Chawan itself is dedicated to the public domain; this applies to all files included in this repository unless explicitly noted otherwise (either in the file itself, or this document). Chawan also contains and depends on projects with different licensing terms. This document attempts to list such projects included in this repository. Usually, the Chawan executables are also dynamically linked against your copy of libssh2, OpenSSL or LibreSSL, libbrotlidec, and your C library. For licensing terms of these, please consult the appropriate library's documentation. Also, Chawan is statically linked to parts of the Nim standard library, available (at the time of writing) under terms of the MIT license. Table of contents: * [Chawan](#chawan) * [STB image](#stb-image) * [tinfl](#tinfl) * [JebP](#jebp) * [NanoSVG](#nanosvg) * [QuickJS](#quickjs) * [GNU Unifont](#gnu-unifont) ## Chawan ``` This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to <http://unlicense.org/> ``` ## STB image The stb_image, stb_image_write and stb_image_resize libraries by Sean Barrett et al. are used for image transcoding. These libraries are dedicated to the public domain, and are distributed under the same terms as Chawan. ## tinfl tinfl.h is an inflate implementation in a single function by Rich Geldreich, used in the HTTP/s client. This library is dedicated to the public domain, and is distributed under the same terms as Chawan. (Notably, this is based on the old public domain miniz v1.16 beta release, not the more recent MIT version. In practice, there are no substantial differences between the two.) ## JebP A slightly modified version of the JebP library by Jasmine Minter is used for decoding WebP images. This library is distributed under the following license: ``` MIT No Attribution Copyright 2022 Jasmine Minter Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` ## NanoSVG This copy of NanoSVG includes modifications that are not part of the original source file. (<- for compliance with the license below.) ``` Copyright (c) 2013-14 Mikko Mononen memon@inside.org This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ``` ## QuickJS Note that our vendored copy is not identical to upstream, as we include some patches for integration of the QuickJS and Nim runtimes. Also note that we include some patches from QuickJS-NG, maintained by Ben Noordhuis and Saúl Ibarra Corretgé. Special thanks to zamfofex, Bo Yao and Nick Vatamaniuc for their patches which we used in the past. ``` QuickJS Javascript Engine Copyright (c) 2017-2025 Fabrice Bellard Copyright (c) 2017-2025 Charlie Gordon Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` ## GNU Unifont GNU Unifont 15.0.05 is embedded in the canvas rasterizer ("canvas" binary in libexec/cgi-bin.) This font is available under the SIL Open Font License 1.1: ``` ----------------------------------------------------------- SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ----------------------------------------------------------- PREAMBLE The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. DEFINITIONS "Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. "Reserved Font Name" refers to any names specified as such after the copyright statement(s). "Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). "Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. "Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. PERMISSION & CONDITIONS Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. TERMINATION This license becomes null and void if any of the above conditions are not met. DISCLAIMER THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. ``` ���������������������������������������chawan-v0.4.0/res/quirk.css�������������������������������������������������������������������������0000664�0000000�0000000�00000000306�15202323131�0015567�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������table { font-weight: initial; font-style: initial; line-height: initial; white-space: initial; text-align: initial } td > :is(p, h1, h2, h3, h4, h5, h6, pre):-cha-first-node { margin-top: 0 } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/ua.css����������������������������������������������������������������������������0000664�0000000�0000000�00000021270�15202323131�0015044�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������:root { display: block !important } area, base, basefont, datalist, head, link, meta, noembed, param, rp, script, style, template, title, noframes { display: none } address, article, aside, blockquote, body, center, dd, details, dialog, dir, div, dl, dt, figcaption, figure, footer, form, h1, h2, h3, h4, h5, h6, header, hgroup, hr, html, legend, listing, main, menu, nav, noscript, ol, p, plaintext, pre, search, section, ul, xmp, frame { display: block } br[clear=left i] { clear: left } br[clear=right i] { clear: right } br[clear=all i], br[clear=both i] { clear: both } fieldset { display: flow-root } code { text-decoration: -cha-reverse } pre code { text-decoration: none } @media (scripting: enabled) { noscript { display: none } } textarea, iframe, input, canvas, progress { display: inline-block } ol, ul, menu, dir { padding-left: 4ch; margin: 1em 0 } ol > li:nth-child(n+100) { margin-left: 1ch } ol > li:nth-child(n+1000) { margin-left: 2ch } ol > li:nth-child(n+10000) { margin-left: 3ch } :is(ol, ul, menu, dir) :is(ol, ul, menu, dir) { margin-top: unset; margin-bottom: unset } blockquote { margin: 1em } progress[value] { height: 0 !important; width: 20ch; border-top-style: -cha-hash } hr { border-bottom-style: outset; margin: 0 auto } hr[align=left i] { margin-left: 0; margin-right: auto } hr[align=right i] { margin-left: auto; margin-right: 0 } hr[align=center i] { margin-left: auto; margin-right: auto } hr:is([color], [noshade]) { border-bottom-style: solid } q::before { content: open-quote } q::after { content: close-quote } table { display: table; border-spacing: 0.5ch 0; padding-left: 0.5ch; padding-right: 0.5ch; box-sizing: border-box } table:-cha-border-nonzero, table:-cha-border-nonzero > tr > :is(td, th), table:-cha-border-nonzero > :is(thead, tbody, tfoot) > tr > :is(td, th) { border-style: solid } tbody { display: table-row-group; vertical-align: middle } thead { display: table-header-group } tfoot { display: table-footer-group; } colgroup { display: table-column-group; } tr { display: table-row; vertical-align: inherit } col { display: table-column } th { display: table-cell; font-weight: bold; vertical-align: inherit; text-align: -cha-center } td { display: table-cell; text-align: unset; vertical-align: inherit } caption { display: table-caption; text-align: center } caption[align=top] { caption-side: top } caption[align=bottom] { caption-side: bottom } input { margin-right: 1ch; padding: 0 !important; white-space: pre !important; color: -cha-ansi(red) !important; text-decoration: underline; overflow-x: hidden !important; text-align: left !important; border-style: none -cha-bracket -cha-bracket !important; border-color: -cha-ansi(default) -cha-ansi(default) -cha-ansi(red) !important; height: 1em !important } input::before, input::after { content: '' !important } input[type=hidden i] { display: none !important } input:is([type=radio i], [type=checkbox i]) { text-decoration: none; border-style: none -cha-bracket !important } input:is([type=submit i], [type=button i], [type=reset i]) { text-decoration: none; border-style: none !important } input:is([type=submit i], [type=button i], [type=reset i])::before { content: '[' !important } input:is([type=submit i], [type=button i], [type=reset i])::after { content: ']' !important } input[type=radio i] { border-style: none -cha-paren !important } input:is([type=submit i], [type=button i], [type=reset i]), button { color: -cha-ansi(red) } textarea { color: -cha-ansi(red); white-space: pre } li, summary { display: list-item } i, em, address, cite { font-style: italic } b, strong { font-weight: bold } u, ins { text-decoration: underline } h1, h2, h3, h4, h5, h6 { margin: 1em 0; font-weight: bold } body > :is(p, h1, h2, h3, h4, h5, h6):-cha-first-node { margin-top: 0 } pre, xmp { margin: 1em 0; white-space: pre } plaintext { white-space: pre } nobr { white-space: nowrap } p { margin: 1em 0 } @media (prefers-color-scheme: light) { a[href] { color: -cha-ansi(blue) } } @media (prefers-color-scheme: dark) { a[href] { color: -cha-ansi(yellow) } } @media (monochrome) { a[href] { text-decoration: underline } a[href]:hover { font-weight: bold } } a[href]::-cha-link-marker { counter-increment: -cha-link-counter; content: '[' counter(-cha-link-counter) ']'; white-space: pre } ::-cha-link-hint { all: initial; position: absolute; background: -cha-ansi(bright-magenta); counter-increment: -cha-hint-counter; content: counter(-cha-hint-counter, -cha-hint) } video, audio, iframe, frame { color: -cha-ansi(red) } :is(a[href], video, audio, iframe, frame):hover { text-decoration: underline } sup::before { content: '^' } sub::before { content: '~' } :is(ol, ul, menu, dir) ul { list-style-type: circle } :is(ol, ul, menu, dir) :is(ol, ul, menu, dir) ul { list-style-type: square } dl { margin: 1em 0 } :is(ul, ol, dir, menu, dl) dl { margin-bottom: unset } dt { font-weight: bold } dd { margin-left: 4ch } dl[compact] dt + br { display: none } select, optgroup { display: inline-flex !important; white-space: nowrap !important } select { height: 1em !important; border-style: none -cha-bracket !important; border-color: initial } :is(select, select > optgroup) > option { display: none } :is(select, select > optgroup) > option:checked { height: 1em !important; overflow: hidden; display: block; color: -cha-ansi(red) } select[multiple] { overflow: auto; display: flow-root !important; margin-top: 1em } select[multiple] { border-style: none !important } select[multiple] > optgroup { display: flow-root !important } :is(select[multiple], select[multiple] > optgroup) > option { display: flex !important; color: initial } center { text-align: -cha-center } blink { text-decoration: blink } del, s, strike { text-decoration: line-through } rt::before { content: '(' } rt::after { content: ')' } img[align=left i] { float: left } img[align=right i] { float: right } img[align=top i] { vertical-align: top } img[align=middle i], img[align=center i] { vertical-align: middle } img[align=bottom i] { vertical-align: bottom } table[align=left i] { float: left } table[align=right i] { float: right } table[align=center i] { margin-left: auto; margin-right: auto } :is(div, p, td, th, thead, tbody, tfoot, tr, h1, h2, h3, h4, h5, h6)[align=left i] { text-align: -cha-left } :is(div, p, td, th, thead, tbody, tfoot, tr, h1, h2, h3, h4, h5, h6)[align=center i] { text-align: -cha-center } :is(div, p, td, th, thead, tbody, tfoot, tr, h1, h2, h3, h4, h5, h6)[align=middle i] { text-align: -cha-center } :is(div, p, td, th, thead, tbody, tfoot, tr, h1, h2, h3, h4, h5, h6)[align=right i] { text-align: -cha-right } :is(td, th, thead, tbody, tfoot, tr)[valign=top i] { vertical-align: top } :is(td, th, thead, tbody, tfoot, tr)[valign=middle i] { vertical-align: middle } :is(td, th, thead, tbody, tfoot, tr)[valign=bottom i] { vertical-align: bottom } :is(td, th, thead, tbody, tfoot, tr)[valign=baseline i] { vertical-align: baseline } ol { list-style-type: decimal; counter-reset: list-item 0 } ol[type="1"] { list-style-type: decimal } ol[type=a s] { list-style-type: lower-alpha } ol[type=A s] { list-style-type: upper-alpha } ol[type=i s] { list-style-type: lower-roman } ol[type=I s] { list-style-type: upper-roman } ul { list-style-type: disc; counter-reset: list-item 0 } ul[type=none i] { list-style-type: none } ul[type=disc i] { list-style-type: disc } ul[type=circle i] { list-style-type: circle } ul[type=square i] { list-style-type: square } @media (-cha-content-type: "text/gemini") { a { display: block } body { white-space: pre-line } a, pre, ul, blockquote, li, h1, h2, h3 { margin-top: 0; margin-bottom: 0 } } @media (-cha-content-type: "text/x-ansi") { pre { margin: 0 } } @media (-cha-content-type: "text/gopher") { a[item-type]::before { content: "[unsupported] " } a[item-type='0']::before { content: "[text file] " } a[item-type='1']::before { content: "[directory] " } a[item-type='3']::before { content: "[error] " } a[item-type='5']::before { content: "[DOS binary] " } a[item-type='7']::before { content: "[search] " } a[item-type='m']::before { content: "[message] " } a:is([item-type='s'], [item-type='>'])::before { content: "[sound] " } a[item-type='g']::before { content: "[gif] " } a[item-type='h']::before { content: "[HTML] " } a[item-type='I']::before { content: "[image] " } a[item-type='9']::before { content: "[binary] " } a[item-type='p']::before { content: "[png] " } a[item-type=';']::before { content: "[video] " } } @media (-cha-content-type: "text/x-dirlist") { pre, h1 { margin-top: 0 } table { padding: 0; border-spacing: 0 } hr { border-bottom-style: -cha-period; min-width: 20ch; margin-right: 1ch } a[href] { margin-top: -1em; display: block; margin-right: 1ch } a[first] { margin: 0 } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/unifont_jp-15.0.05.png������������������������������������������������������������0000664�0000000�0000000�00003324536�15202323131�0017430�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR�� ��@������� cHRM��z&���������u0��`��:��pQ<���bKGD�݊��� pHYs��t��tfx���tIME9 ���IDATxty'1rl<wr:ʾ=>=Qy +Ox&y{wuݣ譴2xu =}Ź le  ɉU 2 񠁌EXȱWKѠDf tLĨ?6~m?츟; q|;`8w@)L^j񧝼܀ 9m&g踏/Q?(Y"?ON=ډ!g@!d&L 0 t>*,Ts?96:OҦsɟv?"s4g 8 '%0NG~n@"Ti8l tk}2܀ !Ҧ@ٟv?"s @ 4`1{&[ <mxA0)y.32T+vphi7x]u`юq; q; q; q|;`8w@v; q|;`8w@v 7ٹv`v`:u|;׹ g<xbxZEJqn7e$5v"lx|3W2Ik3a+= 8u*['Y[a+wwZ}a+}{pvIk/^ ,O٦l7++o_M2P8 ~m= 84]''WG_Ox@d(ũ:O9H_I=}<=^ ?!^LTT^9^~E? ~\x@qc¸b8nLt<AG =a_nu:#r߬n6DJ(㩩:Oٴ|6N @|OQ ͽ�xbfov} ]z}8u:}:eɟu_*(&UX%d]!L~y<~b8ɣehOG?Nqvv  yM/0f_Η֡daR!_ːuH8fbM&(eC6n}uqkQv<tv  yMQ*~ o}~/ǯ_?2G81 �N' JHE {UNVN�),~Zvz'O,'THE n{NN�Кvt'Ou�m>cu�B2_6:G-̉Q8:N{f8S>sqk3'gN'E@_KLC!O"Tu"= =TIrov@0hytnt}lGG`[v|�@0lGCR�+9Ύvn�J0b%H=� wknm|(9R/e=}X�(Qu`8=J󛽿`vدӶi�9R/u]G nͮ٩go(ѳi;n`*AP&721dSVM0gi;nb b W= ()*,2\n͞ov] )2U972ExP',DQ)ㄱK$Y=\/L_n?N`<ҿ7fuE,&X{$8B<* Q1GKʗ(惺 ШLP uaS 8*A#D7y~뛥ͮCwLMu Eܰ7N sP;q| 0B;,I`N Ktr~J XaB#g�u; 0 %C[WQpeE>u 0`sbkg̞}l'g˰ O@q�R}XP'CIJL_Fv,a"8"L m+'hhphh;XiWѼMd9ONCr?ww` oq?nq?׎n3qsfsߜ/ +/eĞ5D5<O7ͷ . @<=k=; 1ݘ5foΣ+Q7vmvϊlиeܜh.ŖپDN )IQ?6V`La\(KVӠoR+˯|su> WJ:S̙޾5%goK0!S%7uUX*ѱ2Vk}<-<&r녳) p +.L@| hI S:qK(Ƅb&Mnó}H?@0۟6sK\rpcǿ}_YXc)ٳ=:2G'7Wߜ9_ՅšҐ }3iZ_@r4<rY ĺdʛ>t̷I>+C0?oW.ӓ;/OO}|~Kp,?zbʞ+x?2iʽXZ˃W],?דpoR_xST8{ 5RFJrwVq?'y]ؗN 8xvW. |6?=_8 gAbs%ʚ�ŠՉ2S~$P-íV˰1 ez'F}.Xbw/{J~x]JG{{l]:{.ccƌ5) i,%��Ah%Ŧ%Pv�A2L0+bSЌ/g`\.ŕ'?>7P=',ν_]ۓ<s[<W:'@DU Wi R@!@K �}1\:QA*T ńOߍ�,]}?3A _7ϿrN뙣#GJpW<Po_cwokSG*s_ZǾM*[4pG85�5�X+�N_}L|҅{} Hl<?hi "Qn�ׯ?:zDPQ#H bǐ5Xw-?ɑP;㏎Fb0{6<`ݔܺɯ@0NKT/B(Ft}&Yy %Y A0"DfHtYDw,I�~b[߃4Q#>OeߓguO<GzԌ&b(IJe/g}r b ]{YЌ ;W�>,}`ʯr �q Л'<yoM<0 7 G2C=*x ƿ9ɋ92_*RV`"HFl(?-[% ($q ByW�t�" ˉ/zx8ks7C<GS7tyS?C?X{ؑe:B9-A/UA?5%)ڊ>Hs#>}a 89X(# atA ()3@x1:V HG?Ed{AaQ@s)7ߕ P\uY<; �*4 %m'' ^y @F0E<R|R@t@`pXA` k~݂qS2\g T6�_UkW*11 f kQP$ȴ"E.ϻ P<E"NdSyUI1݉.YZ M{1YDQvpMt{e: O> H@@0Jk>*P8~G ݊/ӗ7/J("XsI1 <42CD MD xELOsE8*ĖBmn %09 qW @}k E^Apr@wQLn<ڷNvwjxc)[w01l}eE9=0<N +:k6.e/-{ަܶt^6M·ķ dG8ܷ?<ך6ʺF*20J2=]^}LeL_Ί o\x5Nj|QnBzjM!M"?Yiz"8o,a.c0Asre opqQ/AMBBe}1'LܡEWY_vRl0_XE*n)y"9qgѽVYڲn9 Ӓx.B 0we]M4a/݋+-ZPkz1 hAq3n;:7M H S(r0$x}|WEOT<H @(: (qŖxEOu.K Էޟ4~y3+ Cw//X}Xܛ,UJȡiWyb+ҙ^˸e6cIad eҏ wE9`N'6즘tU9O{Sn%}4]{?դtB,�^cmm\0Hq?uN}u�oHJg#av*p`|Sj<1MiL,'w U#@`?0]HP>t tmƽSwŻDx$+g08XtiaKA5qKv7niZ,Mӑ ITy)o}�-_UC48c=)hz1BB 2dP �>1 IiJAeb/U{4 xLP ۼzC yeexMh1!G]D|(Q[i;rqK{"| 4+Ub["$|T3\Ht$iL�!AOh[A13gU)\'[~h$L)I㐾hScJ`@"xѓ4~x7ſ߂#&Ո(Lh~zKRDrR1ki*aC]DXG7li~/ !tœ (I 1H(<<H&D ?۔Dmo bmb+@gR y) IvlJa?  _Os42M) #XQk~)jMo|T=t IĬS:T84 $]oiJAǃca HP H5HHښ`$6E f6B(_PBQ|>b�>`'͈ʃIE> /�m`JJ CBY9Z!]J0� _Zȫ^$Sw,J aS%`B- B5mB�mi.7AFDj C<jڴm9xdiyH il+FH 0)& PQ5gi,xQ1H  P6TC5u#ҙ#`B k [kJ`XccmZ7O 0H,6?2! HK\%&J8 ; 55ACPM ج9 1%nõqI GưFö1R$O64 ms4íPk^ (]a^ vA2@"ݥ5BtcSq'-YIO !bk@%&}Ϝ%X!A1L` o�e a  Ȳ}-6;^3b _U**sST xi@pQXK+옏A0A9 ,G()XڸP,iELedLq!ri <H聠1&5 E ͂- qD5Z}:v Рԥ+(k.Ø4(Nb9 6KOfmSot?8{^i+UߢփW2.K<"rXh5e2}j#~a-j9'5C32 /y֝z&!EZ.fK*ZHlၸJ1:oIω߇p$}Pߢ rl@WNBEy6D]m%l%-÷6 aJ/6D<>!l"n s "fG@sս߅7=S ~X=Wl {ea\ 25 Zƕ|;%qՓh[1[\E/\Wmh?f啍Y 'Vtނ.-hoө1>d%'E.K̶l: zgm<]ď ]v.@Zi)OK3v ܉)%d[L(>EJtʡQ^|N"=;SnRuYgP纯$^o-3gD0wE@!,b&䗨7M7ɚCQN9zMR϶cPmSIPO|�/*.7FYRIs*L?|_q3R $_+t [GȦ* <EeiaޯFDWyysb?GiO4L"-"#征*/K T 4Y[U2i'�(y+ (8C(/P>C(8z')ZV;HK r0xW&)J% zI < 1*!MN3$D=#D„h0AmЗ4Iί84yT9I!u P傴)\A4+ܣ@P\m4O_:}%ȡ˂k6 8KH-BepSo y>F¢49I2p1xv-R³(g%i}F ~*A ?O�ـ΂'闶SPN)MTScԌ@W~< ]Bc)E�@.S3s+: :DUf>-( c%Q(Y}#TJ~_o_d^eQ4%9? ~d]4osA?@ÒEOFPH;$Y%$r/G@Ԡ$APF_ KHt+> i<0J#V)MxEk$'xҢ@RH'�>\jYˆK8&)kh%x] nBZ0=]'%WJ~I~V4 x #Ŀ+).}@rU)�sDȳ@p37K>Ą ]!w�z] |{p3k&2J\J OO{ Sq `_em7(Z=ąynz˸B@?)Amڕޫz7YD(`̥y .eQ 1a`@@0΅4he"m#%HːE�JQr)i뒼o͙cJ  X!t 1 %)�ʖ TT�%Wi9N<(�g'@P`ʕ�h`% Pn<{~� yLި|f?/r@4\Xgرh+tk H vJn< x=2c(B i}4L Gm#čaw @ H \Y&)LAz/@#M R57 R?%@)Ap'Pz _Iyx6`E8C u \] չD]Dːjwu>Ć-ýO@ոR fhn%WƠYwWL""3?saZ3Cʨ4]+ s, Q,m AxPQ6RY*o[OID\%ΦJ2IS3g04W=w vO�hޓ"uuSqeDK-pKV{!GjCee.% U>V\gh@� ]1x ᦠ=DT7!,QHO|Yu�$g rb :nmO cYE@ؼ;V !N~ *6`A`LRҦ 糀EÅ}Ѝ]>l;y-d6M- ZHq["U<˗~̇fKSE*RAOg`/siB:Ed7][`=⾭z%Z5(|喔yE DGg7o|! Ν^ ԈxW4(V8V8 f%p4N]THjk=BрPݲ8Te+74(@ \F&_Mi -[m: dQ 7N (_uE!�=@pAgJTJ0wdo9zΙF?Wl`*LXؾ~W#}mw*B6 OMc%="WKҌ9=7O*a~g(E1IU4uEEc#`?EU/rakMؠup>a@)̣P\=hCג."P9 ~7lMX0@TDX.%3|ٛm*3/В)+ 84C4}�]jq5kvԧh  KlP{)`9%BK}SO{I<$  JVeK>$L>K 'web zq%gt |5YB@#%tZz12E2!cP srZ!2 a v$7޸ߐlHK}# AD T@}-Ұ!Tu-qZNJ]zw1 IJ 4hpk fH; 8f9Fb&zZΤ,ۊjB 8E`s&-~IY*ɝjp)@7^%M (x%Y!T<KZA|p\%Ѝu#RGO1+AS?APj�AlF^y+!݀4sN g%PdΉi1#N#ZF \s,�}ݢ9#5L90Bz .@0.)uj*S(&f\!NCedL @h@(LT rX"Lr[@Xw  Hl2.AAFۼ~< Dlj?F:F+kF:0}',7i)Ք@@3g�1�+| %އ x@p ^EzNL (AZ es^ԥXZ6`4 8 |lcUs3; (AIEJ4IM-M} E V `iS! 5 >JA%(frO+A Dg]~gmzwe+Þ129|W'*XU@ jE Aj�!vA0`eA&)RrlSTz@sl"ĆJE O-Z;RdQ*ax (*81*Bm]8OPHAX0O0 =K dLozT<`@0 C<ԹB,RKenf/ eLU>X tJBUW/RwP)RVBxeJƳ�ݵ s2Euoh{C&URүIEV0XPbCAyޥc:w!gJ~?= ނ+J2|oݲ՝pռ(W:T{Z6К6#:hXM?&ߒtߪ} ٶ>%Mˆ"X2 Fk!Kpʚbǚ#( @ ~%6|6uY_ >,#5aߐBCNE6Z X?Yz` pQ* ?w5Nqiͺ *)uyо1o!᯶N*`p, ^" Ҳ{ܿxI�)pjUԅ{0 pp hݜVZ.1mƶW�.)̅Gl&(9'}O~bfCd| Z\5-!EVuܨ'XJA˹b ӺX?- ncMJ.-2(WH$uH&$-d&X?ԧ\3ts:"H[+xvvNB%Id/XaBf&M@Z\iQy輪&e\o?Ȫ.}65SrT}]w2!c\ݡEw- {;D}Jw ,L:r)펢IA^;@A0K!I==09 6f@o2Ae^� 2rU۠*Yal ŕq}{Dd(W6켨IⓥϩsKBh2F3k1G@pL <�AAGM HJ�GHI%y(I%%.3R%hI9%^P־DI�wr.f=OWu[@NյO`붎q#%',if#el---cp߅ȳ ^^S @ 9]:ͧKWipRB[oAŤu &eyxmiBm}r$qҔB=�4\ L Px:@IgyZjSqO#:K&@0Ah_ ٺh$mh<zJ |'ht9N 0hU(!Qi2؏-|($U ( @x1*R"TZpw$%`~^t.i[ߕר@DU?`IG.*qifh¥7�Q~SA%h1hBLWM19x*@()|Yq21oV X`ºyRdEG@0`IX(RJEUr 0IbRS Վ;2ҲH#§MlR<%A O#&JxL+$pDz~@UI2%+Dd^Q"a JFUem oły``;A {&"-xE�pu. Js:_?,R dhyRr>Ry(-ц�oH00C XgJ$<B* Qi:8mi P8m? '�G>`P:VTA6dgF'ADc> [hFF)}E:B)*<<TM (|lR3rgź }@50%^ W$YLJ@s𲄁9Hʲ҂pPMK9iƸ.-3I1QbM�t*P|U@0|  H`17) �ƑjԜ]8'P@0V|2C%#\^$ЗH?P@lw}3ҁT'b@`}?. BRD Q%wL&MwC?+} h%6bU៥Iv!%L5x&.RnS xM>{1={/IoA` 4PJ(y_Z&4ĕI{~{wTYDL7d&|E MRr{MdRe$4,+ x3-W6T,J_mW By&0C]W3wU>=~ mAFXFx*im,8(u4qWE*K3nu]jqk"h"Kb"/s |Q_zC87V2V_=h/,n7CQ̸'p0\VhqSP eqeƴs!$(o֋a (Ć 㳾 A/LoȟCV P;=AʰV+%<iƅ >:LjTv nS0щ曻Jѥ}$ غbC0&J$IJ7$aD#T85JḚ+%!Inj]]AG? oml݆4{rCKJ#%081>]>VH2x'#՝6@7~1 O PlȇFmn}F1W8]ixG}&DQ�h' I PG`3Q 7}|#67Yx2a@C3L(|aȓ0l1.d}TۨL Y9>7ҝt9vֵ'Ţ]y5CՋ4Oϒ]Uɑ a-kH%"y!"ʉšuA)e1|#{<AZ!W=h~ O,<T PvdGI7Q;=YRR�ٛC)rAP-%hJdP̿U3fP\QF;#�$0J:YY H �SJc)i$ܪW,,(& ~}$M_ �}$xh4gƍ .<NhYx2k;Cg,myV2q GF+qdZe\8>ECB8X,Ns ><C%Z)(sVIX<KK\e.s6GMa =i=\B2{]r+of Ncb}wzDZU%.l˗cF%e. 6V(.2aI˜Ig/1ĉGZv8f/@'-%Sŕ'֑-.q[4!L'RH恠DrSri Y/"$8lZ?Msg W$)M) X|u{7(| X s �zZ�Z?& -%e :U& -%Qu�. +߈ M@Hy%@_"VyJ%J38i?%)MJƟ9RvA&,IJ\7̓?˽e?6T (H5? ȑ\0":IZ%z"zd:_V5#A@ rr=�Ї/ Dџ|H>CkEKMȌ/RF%ExoEVREVyuuF(C[ `MܛA`kq//((w)~C]Ca~M֋d :wn(%m/&D *ko Mä<E-%JˏRB~f.d�:qi@ @OtzV P3 9V<}<wyPfXdѢy?06,`O AU"%T(kT]bHy4g%Pu|EnԲf<�4)WJiX`_%з a9h& L`L�%8;u)2<UݧNwa!t9tLg!tߙg]?E Pm HI(I7~Lj1��K@NDK.X46)APaH6s"'8B H@I I"Q_QODŽ}FȢ!(X)k Ej71RT 0]B@J 0;'he ʻhW~} u_q3(GJq~1?+A SE}S^" ~ ~fJ[J]YRYPebIiW=xV`/'&>"O`4U�4PS_$4@<AJ恠@c3d#CC68�} iAغ Aف"EꚱP=.=G> xmW8a^mNMHE"P۾H6O,#&HM &ȤF 1[c4y%bvVH^ٙ{aO  Zj+vA2c\V;*4ICXwY/ it'fbG Hu埑waHĺ$-8jy+lm;\Xŕ3p+]ō]AAf+%"nα.36m T62D(;,O@qxPxa։,6ɹ9h L)wà)ێ*ߎw6 ݡ1ATo󱟱45Ux]riùm-Ntz4ۜ`\sTE9؍mrŸekFX'Go {A! ? I9u7zi4_D֚2ZEYX:ZutA.[[�A+7m-v'A_vjT2D S=aCZPר"Js 9'ĺ 4[$/q_J 92R`-gFŒk0tU-%$<[Sh]&'@E#je؝P|#3%/F"MTAQM\ЌEyn9|_f!6IeʅqړW"7(эkIYLz{_9*N>(\43%5p/4-\aJW_![ VhNl{#,KqZ=�|(~?Ғxk{y=>Ţ|!ʧs4G >VF^Z4҇e J&pۗ~fV@ڼU#1a4\$kR-x[rb3W|.$ήrcH#0Zq-y8͖̻96ܔ2ʃr{!VbRb\I?REM7&(*ᶹ&JG&ElRbXE/HbkʘIZؒ!Acp.Uw4ŠR#iscr+L^rn։(ΫȢ|NA|[9pےUcpfg B́AkqVZoh$TYݬ"!)$ ,j5丣90~k?%FM)o)A+]Υlk\s,JNgys?Y$_u'Y[y@ ǡذ^#9z a{b~Dp1*Qi^$AA 4j\;43ļWv cY}Ϻ /&-n#/ V㳠1sRwh2TӐskM%pf4ZAS{D2pvjt)h4x-0^W*wғ4*@0ImJ, ^A aXAJB$C,ɵXŖ꟯P̼C`J*OO lq>&Ϗ|ɿ#Pqq'i@p]1yϵ�[>Jؔ .WM\w&/rE;DrQEOɁtq/D*vmp5-З@2!%LpaD@1} @籦iAF Y u |ޭ ӘfxiW ~O¶@Y$ OB~?� ٰ|0틐X@3o?֯WC ڨVpW ;\~3ʜ{"[R^WaJk )&UmQ I P1{䦛FѥN֛ %y$4+(.#poፍҁy:O:F($YiCղށ--ONSkbL7W` sm%MUPew=vDxNe-EE6ŐVR T= < 7݅풤co "uIWES15!F8SOu$KrEj9>sK " 51fgkϸGn>%Mؚ~a/WX˿*ZO]{ ^ 'Z%!ۜ$6 (0+Qd(%HҐO糲QorX{fDvoHJ$i<EoxrZ� j }.K K15* 1s#zeW,@%e=(`2}+*�/50kE26F+¬RR3%| Qj>S~lgkԴvs[,Qrj%3(7 AhG~Nh|fĭܷjΆTg|fm0T $O \&@ 6tO\?!DLE߿}:qom^Ő\LG66#Fmx_K cѻ k rX#nMލtTrw2R*åFWJ˜%38%gj?F܄/P$Z3WxmwWr+rF7 Q`"iW@JBPb~7 7rAy Cjjǵ]d>Ř=> fl2Y&&yusCF[<ʀո"~e!ڴly)p /*Ey QKe.H`и{ǰ=1lHnHbzLG|`oyo&N`Œlۯj52vNd<X]I+FpuW@2I 4=I+Hˤ�7�'Ơy8;#+|_k/LZ$fץ<1 4HeT]3YT_|3i(?r@?>�*љ|;ZLiE2٢^z*ncaa3y�ݸ;`<%h2] {1% *TX@Dnɭ榕S'Z.EmAF@jD莍zYKɬGc�m xo[/Gxmzwu[*blq:Rvnxvੁ:Ӗw;5x诱W^;p4D![Hz "HIk�AH5D@*E"E+r!Q2肉Qxܴ(2 VRT ɖ @М WfA btG??їk"ZBK@5Ѻȿk5�A1﮷IrnLٻ$W+eb$Wd|ڂ4K.N= ,U%n$K!.#$4Kjvl/qKNÐUg+J۰w&`5c@ Ӎ+ %BA8,nsEixZ8cbrv9K}�tz' |h@լjd>Vۆfk(0eBpϸt]<̆Y {Iؤ˘%Br`3ZE@CU:kb\(, 0OfIE�иohEP)a3r(ŒpazEZR HC\$QMA .b?`8*ylz,OlnMkz$JR F %ٯoL HAfٿ'I'FXiD[4$e۸nGE H#I#O%Y+P5PpO*Kp=ua@.|O~:?[n\=%-0ʵ~!ULRlX76G >R|#ge\EZa T2x"}]S#<UW�++D"azApJžLn _VWpVMX Q20'_pJI| !riAc(=%iץ2\ .n=0o.býD�AF2ŠB 9@xA'A�H+泃صo@<ڰK;W0rg+km}<MoͳJjXW$ VGT?Ͽc[1~|l}::6QƿC:~u?Q8B-T1*8`ކ[r:R j /)�[ E͓%G4I%Bp#"}!}zHk.W @pkrd92kzmm+5_6\oNt8Tb"SjNJHK\uAfP /tim4K�w% f]bhSxtçm# S Ć uC vΠqE 8�@}+f'"j)P~a'Gne?D׉"ƫ2KKRH gѐYYϐN(x F BKt<"YH@H/%cGZTL߀AXaUn { Rف1 !AwT}}w٢ Xվ�? � \h)02{uRV=A NtEWnkrQ Jԏh|1`蚵<GE-~_ !%Ÿ/oVJ18tu ]pЗE :zgoʹSGϹ 灞 l;Flu91Qm?sثq(apD3RI^4:˻^eUzj(#p œK6'w7NEܭ'̦E뷠|۲ WfѮ# \6뺏 Q5>z:吕""9'xG z\w'GP" D"d37:duq�r)lc7n*Ry*|ͧ}%"lAm)q>ib68Xl{ƨpFף~d=zOח~x(I)2E Y%FJ G.Y�;v5żf ёfqMkFh# ?K)T/\aEH|tV80# ��,%;UѰxCfE}x~۹Us )LG pq%J*K)8p('@%%QydS*/9!4.&4Lő`ܵztjim$ū›B 0`LIo}v/o*1.>0ut�bgIX^crr?N߳�Q<^#)7?w^S8xt o!}> M>id%ɮɛU;5GO ư% sqh+jxJψ#p1pt1e];z*Ec2S= d#y̴Ft/}Xᯅ5+L$y?%haĈ3ϛ5'T_WD5.4$`5]p$e:q_9Y ]z4/1~[[445|82�nL^qU%KrS4WVzPLn%-f雯�.r P햓g9 9wX%2N[^ _e0Lf@ d1$ t'/ʩ5Y(+hE0` }<&bYY$> 1.D HZm;g>rL% o:=q+Vڝ^ZS:ZkGI�r|d^X۟o`c|* ~=J= jch:І]uͶ.g6fip ț:UcPjX$YyA/5�bh5-9QyX1F <J namI|)T( R!5san$ |Mw>-4`cVԊ-&hcR<fiwNG}B^ްWZ s7z#\%X:P! G껡)L-ܜ6˰;Q/nҒh  mfiQP1Z ?腖eT\<fU�_\ zK(m8R'f~9bk?V Y�[n7,s+#{ ~ڙnSd-b_5Exw,4ȖA_.(J{bdt eA%JaE^k�kwi7#m*a61o)5UąD@ P8Ӗ HVp ȹi}FG>FɴuE 0ɊikH x'V0yuN!~d1t)>Iȋ' JNug4pYx+P�5iǗqA<~}| O?&HI h2O-t9$"F}ՈB-E~4d{{zx}l'X[e,L+fEl}Ͱf Gٺ!6s\I cxa·,}znAi9mw[Zˮḁu u UZć5o$ZJJЅ`{ B25{&\z+)H^�ܛN<E)yMrѠu!f@U3f3@P Ucq&|D 2@:{)AZ_vT>pL8Ġ'O1pY#9p^ʒ:ȣ@ bJ�K_= DƅmŤTkD6 Ze.Պ ſLܠMW72KEP[t `ڧۗ1R Wѷ  6YLB!O`}m.CzEжVmwy-@ <^ �_%%-Nr,4+/)yfD2��tl W]E'z8O/׃6 U5YV2>s5�TV\wUͽ?v . AZb"nM4 <!i"$jdYƷrkv7 Yf ߻?~Jkq!CLw7><:" \mJ$d%ÙINԢDG-LFxԁBiιE8&WPԧ _Ecu�7CTz[3R7 9htwCTt:vd'ŪMSȹL{"Ҳ6q[4Ualːy\q7t ?F/Jj7Q4/ uWp8‹ s> &H4[;֡ MUX1oo!U56Ё( < ǽ@Ԝ(YЊBƦ6t(:iGom"R33h,5),alqz~ X 2uVa~mMM�c+ӷM6[m^^ӷm*pG~4w]:rFsmn _qV V.{N>ҁyW.d)'mT筄VwS×oGf~t A)?pyOD1۔Bwl`_.؅0 _^k8Dbfc:&p0 GKpVȤ{ɴyęScf1B%};$a0Y&JŨ1f~ cԉ3rO\ �u4̛(᭦M1Xȼ34Fx5W�ert{,&eZ1$4NOB4Q[~�MBYA3gu31rpaӬbP,&׌ {^stL!urGMl#Pjp)hQB@9!#SLvL'XU l&UE&r@ X 80 $M&H$A`b𶑽xzF9&K14iBYBlXVΌ [,tiɑ~jT c(~Z]=B@0i -3( @$N `GFҰ1=̘k[nʽkw̉[|͌Y?Ph5;mpez>/ -i:jicpU s�ߊ )ŞT8uAP*g@`ԑ `{i2qX3V{I'lG�-H.tHEˆ3XHA5蔛zyhObiN|pmVmW <`14Zo 촫'.iRɀ>@ S7PN܉װW8 RG(AgK,ZW / _>NvA97Rd1m`oZfY6\"* %kR7Uu< ѭPZHķ[X-^+J�ak @!<<娙0A%[C]\~rI~N2+3e*I'5׌r5I;Ne?jj΁&fZK ;5&9y? I) |]kخڻ pePΦe�|L$Dkj&Z 6 Q\ȝ{Nc!}*ئy3G/֘edͰ6CoEDN@_k<-35tð 4V!EG SU$<`s& pDxp ҝ$76q_c,or*<檹d %hNB{wr֌ @1cV],�V4\j6(A@`e6.B~ğ@i_.*ފAJ9 h Ѕb4\b�Nl> I' x`ڭ ¯@"@Ӝ%0ϬR3 jrmfVT<je걊`Ē[SE*q|k04>J--PjQ FR1ǘ v�;w'hΚ1=  vCeOBa�i.tdu)})@xьM8$Ͽ5=d%!ϳome�zb!Hu6WJPVf $lbP'4:tm.GI@ j,<H҄S -A�gY($1W,jl@:3}-xU&! @@8qlD eGU X7WrJ!ٝΑ#{L>Y6:9@` ( ]5GO>~yīfUW@(s=y5͏A8FY~O)<uP=^"W*ePcP1hSd͑nh`c<":1JMeA &pI k*7ieT bf&0]b&KSFJEZ÷<dfߥ- 0w"r9)`,tWd;[c]kٵоn(Af�hCg^+jQLٗzf.a? 9E3}x'\Pzw>郧#v;o:໠wp܋1~ �Y7!`V>]Bjuݹǹgeɉ@D=aR!$<U5D46Gw@A�5�*JU#LJ5!,6~%&a1NtEiH7bV]k6|}d/Qb$OWc5vb߉CP&8tX,s;UQaq`/e>EbQ9[鴷}�ooJP!5᩽(MP�`'V*tURtCUa ohЯag)DcJIFfW"G;"%s1<>^*'!g w,=bɢ@Ic"Otr-}I7g8@q+9 򹆑jrk4"Zn9Eh!Is+1P/Bm=M O6_<1D3[ yv+H3BHns.K6tO&}i$ t>2˻ R@"a ~X+;A7pK}6Xla2xNR+ T5Z^ՎjV&SBdk~(./hI?t}k;7~H/4}Q訒UZ@лKbi;y;Tb oŅC?(d$N6 $qg?P%zT 6 ө[pMBq=  Q' 3dqx-I n Q39ldM6ujEZ_ E͚A_5[-AIU:AS%^Fk'4=aTh%@I^4t׌Wpolrmq=n m m B.J0m4?%�Fm5vͶ>_3-0@hK['мk'tTcdes8;"3 �*"uno-:'7S.nϋ|+l1c&u߫1*ۗ5Kgz{=:>ݎoV{Pk7&aHw{h^11gbtUlL/ 5usmfUbTQn9cNpgA btx_f ,͞?%s^*Ge!8ޗ�g>e)?%`̰š2 WnR 8zvpq*hO@HJ34)Ɔ+*&i@@)ȅ(eFl=<l48 s,|L/(5ٜQ6JxJqLn#ېY3N3 Q9ԛA!A!A|cJ:<r&o,STdȥ pÃbz}){½aoQ\غe$h" `@0H m1Gi|:u[c 5MR+1#x?I: } 7悠¡8a`Za`C5;C; E<#]Sz= r 1qǁk| fdoչ_ڧd01x,+q3fqCC(D>Ő>){w-}ݧӖ2tXހ2[nGG|{-G۝'Y,"w۫;v~n齻M1V;ps{W fY7n/A@-5ÁӖuwlЧ3ۆaڻkCv+ Hj8^$S,:c-^f6V �BaF CN6Q KF*{vpW2t&j:�l%x}%B=ΩwOG ]Ӹ>:Ϸ/cUxj:Վ .T񫝫D L!V=ry,d*, ,16C괺ƌz{@Tۧ# +F.45݌2,a 1?d<h ufs3[Kd`|EM+BW'(C[b, 0@,v@< }*+?p-QX\ >Qg})EݯiH\>g~lc݌e6X4fҼ'(fЙiۏ`~e3P?LGٙ".hy<J˺Ũ~?cxn?iBy1s]\܏~a?�eT 4cxVˑȊOW7ej@Z8v eh^c[c~Ũ t#Lm@p@P> Ũ:Fg1mQ?<Ax(f8ں'h^/aX>"p=}FBpp"@ H�2R4 "լ^n(mXֈHlL �(yHQdH h"(ۆ :l؋ 8qފj]y9w4rQB& ޔ 81!+u&w "ZC 4XC0n+W!om+FuuW]rœr2?bhEcZ>}c lXQ*Is#+r16 _z4uPO'h^/tbг2@Pr$K,uJt@�eK({X1bwʝVE B^#MAkÌ;X.1<0f}ȨMڇ,#wxd.X J wnmŌs%S ,L)cq<B^?vǺ;X< ДrU."ey7W yN "YhVC?�{ꛜ;M=I>\{L7rTPـ>Zbt4'35W? (Pe/-.쑽hZgmŮ@Z[Pp`k[Ql8Uh*3ǜi*9zf'tzĉ5K5 LCǤ= 8DwpbJR1NPMLk^q�뒉Ot<'v",St\1&=ZЀPLip>Az w=akGh`�t1<H@P;NwX[uD_!T#'Q9|totlLX-0<FT"<W@N!y O*>Ai9_!7Oڴ;/ b(PCXT8&/W.A|]OCaWN nX/R_R@U‰:$<N(!|~@oR +x&b39,td5)@'x»l\= h9nA5XgZCH!? 9+T[`ѵ3%H~} 3:!_Zrda ';NPjV1y@3&"-XV u n^x7w~[p!/]}l nO˟Rr"omۑfSh4v GX.dMkLuxC|x55Juysst\`TH',%j|.$bl\ع?Tj}<^=qnfq)f{-7#/F`G9j|_0I;--Ld4q})J<<!>Dnq8#o #jOnOx<n8,QS}nE@9R4ITh"~|DgҲVזW)d ފϖe3wǸ8-k5l#]U%V|tt;h}wO{3aM:÷⛔5qD,S)0y'Gfj>oT1;+omh>ExuwuLD?} 0w~7nfh-WsE݋ [뿆dы<e+·_yG[,imS-GPgm:, uLnYE�4ȹfcYcYcXV‡X>fUQU€P}ӌ#X@b116t2Nڬ�h\]�j r5K#)f%a(1 }Q(I0f^cy=c8+ 1475dxI;SIu(M݌[`RBLv["|]A{iHI'l]y@JnD l=p c5^0[hK|jeO .1^=؅ ЍC7t,[Unū:[˚aE֘\CjV763~:`@<,˲(ҙQɖ܉1<= o~ҕC(ţ}XRxJ3҄7Q}2sl9ƪQg(J5)J]ո֖b m;&dDax @ _]5tX`MX*5K'v;J3X1=.9oD)Az1,_Ѥ^~ OP`�nLS�YQ�@Ю3N~|Q1�6EoJ,yJ4ػGp>\yz9Pw~>QTgV|!lѽ xhMU2+SAښv-9 1;c{"|-DR!# |'i~uNŔV p[si.rT}I+%K$hJzQEV[[y ?XZ7ƍQB˔!OhW(|ݖx 7ӗbKPX&boծϣ@+оwW7<izOܧrztWN[MEmfWco2bJLXVӮwW+c@Nw\4> v2tН~j?t}USo4*c@0N%?,H2z>=?uS@Jӑ˘ޝ6!ӟFLKhcz Jv__ӯaEABbzev حVǪ�NgY~n XY8/ߙtW;]>AH fLOpn J纋YL)^@}VP؉QE�fXoBo'y>?1ט\/AI= b:~z(ƸH}1!7#4�$`"7<|Xu u u?_ԇ?R}B f>}^Zch�t-=?X`eK~9΁G.G ^&k_zOO/x}t '?6ػbl�6!, ?1iemNO'Vem VB@IL~IOO[Oz2YvԎ<8ofIYĄ֬O0y`b :ttddxl<9=&i�Hw F~@*IW"C|x ` ǓG+) tҘ;}ߍ_O~} (Ә΁y*@0иxy ,z~}{zOV C%%Wc�)UlE^#u^%_azۼ~ ڊ`$؟YgC6Խ|m. "Y!R@ҕR-·cJi~NOIx4;P? m@@C.'.' \`hڧ˅D9̈́옏ѡs#+l:j헳.(3%@2IӥlqOpZ>x>_ѦvOt~:Lm$N>2/AxA!tDQo肢^L N7B'0[cq8'@�M y[ïmmԵ:5N%c~aV>C !yvd+#db-% }cNg>o'yӃTZS˦*yso-OW>.(9 nNh;kM'_*vVIt?( hI?X-DU=ɤ 04<X\'ӱwH]Su4H# D� AvjXߊ%e)}�/U@cRr pJ+sZ2'cYŁc\!Fsni|υ{X=}KN O _JNޙJg `zR?ƃ" zaRy:x] ^n~ۚ>Vu#@{n'Ý|>2{?<T[;?tuJZCx&<ʩ5OܚUƆҦ+l)qgF]Ճ͕ϖ<!W-_K-MZ?j .^E~Yo^Ģ8iֻ4} Ip~a|aKٚk`l}MM@ONGXC}ywz628ҿBĻ8Jt$tUhs5Z͍f'cVM@}޺"p4pξGHzN-h;p\t*Nq)(}t<h~bd`o 2x~GGC`ez5îPX}+%0J#ּ0*L #|���IDAT45\/q-Ţ̄`roG+/Iʅ%ҋpX YaA/C -UW<*U٢O$f Kޅ/C\tȷվ?F'*Y-V+3QebI 04KLɢVȡ64Tî{X?q<wP%}- |؏JdPw,754BjL)C9^9luL$QŏTʻMp7h^}H!M&f~< 07Nٝ(w"pfk%6hDl>iL.9r11r?+|tŘfڞ�E[8!<NC_}&T@#hϴ7] q/{ 頽C 0 �<2+2XǎImzH/J<V&3Yp["[񶞄ۀRNQ{X)f2ŗ48\卢j4qΉBrIrjM f<<^i#kҹmM&]pjMjyHt.B,w59rde.1-%B2+F퍾t5pF_XVBl ȍJ"GϭSkP8J^a%m-g2pyOk b=3.'/  mJKLdoǪ,E*מئ/LƓd_??eð-"kb|-a$?jZ/ofüԽ ?çzO?5b42Ew%O(zM' F4l31[ 74qvJ( 'I(k؝"7&\\Ĵ=s×(৚R0d^/Z ْOpG/ Lp#o h[As=mt -%jsK_84"$9h:x !)|Nx24xƞ+o7m.~3'ɱ9N f#ox"~`0ԆC. ́c\x!ɵ0& :=ac<c,e�"75laFyDz)`_{wP;+8mwaq GZ2>QyR:i@ !eI%A% 92 `:`N ., R`R0G YF>A.|XB C@!i\VO7d~@Djj~5!")'#vuMv,ӈe ȲzAm|9FGP A`1s(SY Pd࿁)tL[}G䟭hsc]Ǵ`BPbs7'$k\ d|\ost='Yx?BۏÓU _kxeVs+J`W]y>n|s<| tD LjAL~y$2wc:.-;I >F)=�Ɣ٣i fiԶ9nL9:re�\@# +s`&f|r{h?>^'{{=.'@qd)}>blop9| B%p6F:g H<b._dK($@_0Ns*^8p�#2n3K+4O`Ս&' a�U>A}{e0llw~>1@34%C'Ā�x)O#%0&>F:q#Ş%h0G.% &{MYnsGJ1TPKO?lĬP e"har/u~'q;k~G _D(Y2 Z^ Nw < 2us2#Fu#DW?6H%06; ,<}-k蹃4}5AboG+:DXUOPW5`sUt?'H4ޏV|[=2gcA:ݏua! ub8 סs{" vde2`D!DlmbH6R?3XFC O%p;3\2_5uG:<Z% Jp=@}wO`pw=uV W#ˉzt11VmFW'})xdr7ܠݏS!WD <l o1ÏȯhtJ<h'8q EϊeO{{wԣEe7%*#!_ k&#l+w ;*ӵZPs;ؽg@RO[jZPp &רOp9i{b'9 lȂ Z.ϥ>A3?q'�Oo=7YV 6? 8C?�OvP[�PL"FBPsh'h]_[\s 5.[ݠZ>I&lE \mX J�gA pV5vVkꬢiZ_ ?b:!3]ZT7 Yu;|q!bmlⵇ\_i͍l nniPŌ#͉q>],ym ~/YԿ7ZYj//.B,_ %}6d'ZG7c͊y!Jv'W6Aܦs̝{ϊ EL&4|_dM8/VLPQh;0ژl"L|TPԔO8Xl 4V<~J4�[36lZi֌t8_<p,vQu^Α*p=hg#{�\<QyrcGnX(c itd); s6G r*DP,,{i\* A~2'-_^d̈́F*矖5 ѯ-1ʝ~qsumySE\0;QxJ^+ ^Fr|QY0z#Li"Dt C'3Z6㵄Jj᫫EA{/+V뼈 Qq]0X;+Oz<c_<Ysɪ!`(?S+z5jV{휖拳CъVO㘰&t'hh,VHb1%WXQ_U ; n̯1S H1άECA0H|Vp=_yWZKZ_3s~xv~8{4G;|ἥ!}zY4?WIcגSix=~-ikj%9ŭ'LG@>ք.쑎80OTbx%+% R2m^z>ji؛s5, ]嚝,8~z~"㥘iq;%F:|Y4*Wivbp"-߁ن}Yȝ?uqi˸Wpyt]adZWAؐbD&d؍ ?NӻS0ѩG +jzvfZ@<{f�s..fYi�S}4dg=PHG!E)?,LAUϑANɠ �mU8jGyN v=ZVѩOO=<Ucqv-i f?_HN%  }ܓ}cZ q9JF�AjL]pl.gG)e˱rs9Lr>YO;CeFKG^t8~c8s{|-ohi:0sX=Ә1 hcT̯Xh9ԺN9GGkoIFeV\+ @ap/+X|7[zU׌oV<s] qy^*.ٻ/>I3u~]OfVz&  |j,G%QCBC $%p\o>P;f♸bK�w fVGTjL!Zn3bsI�R%Yl"9ĉ ZG=6}ݥӗ#^<?/(G9>OEZxR?ͰO _8t"|4ߌo.Ёd2'u'~҉2wW!qM #e8Rf)Z {k8_<P Gч;\Z̠C_'X%h}=pe "$q= +NMYGO d/N=R +J9kJl 6F5 X2*\׌s=sV@uA:Vn}W vO.@f%޳S]$$)>q{x opiGV;W[wC"-,g$Pec;Ef CGdΪd=*RF'Qܻk̺X`RUTX@Y`HRzk. i$ sϟoO (A (=䲶F =/c\$7t#hOAp*�JP2 =�| @h#%H@}s? 0ƕ>@)Q qB@l %X��e�"!hyhn!p%x WPezވdsvpa- �cVx�;0v` SE�XsBI@)�@gC7cނ猞A%\ġuSHJk-VE}< @%؅DQT^^ydk}U)4$@òf{"`c&>Sy})d1o28Cp@ a.O0A<C }';�J`1[Ɛ L 6#O0"8KuG@0<9iJR{aGvO ]{tOƏ!㇅/|-0 wU~Sw_H@ Ʊ @Iðe6k@ p9Hg4R bõܐX IhWħsڥz=O5hsa\#wƖ6'A5.4@zʨcǮ^.OM\NvҊ]+{֢+5ö]It1ݶ]oU?lKFlMvW#E<w0 ]D ㅸ'gptNۦ"yv[|Ӝ/W3jCd,^18a'm#W+y=m{/FZJ\V?rjd83#UCg$_h_h ϱȬVնekPoGwchΕȡn'Z#h jU~r謾 1-J>҃I%N5OyWU]u^h>"JJybf}p[OM >%XApbKű>AXRW-9|)e8^Mu&_ƹ}{[6MP؄!z@mcFh|u>V<Q坭 pf# ?O/pO�ה>A#<yq8'JMg34 ;'xM m�r'@dlw4Oe˹ȂV t_<�)Vf @ʾ,6'`@i [�i�4E7-H!F}p+Moi^`p ~J~Pݺ ߃1W 牛M&7iۏ'%Άs}-p_*nj>Z׊gh:>cy 7El `э(5H>_ߐ3Wy+V*hbMy0`:TVmiby/b .wYؾM7ИVy}%10ZzhBiP*2, ;<ͻ+ &\^ dktt>FK,e}/bφo 1x,G,˦y1%746_% s[fi> Etim_T}-deX7=/bA)pr8 j pRS ˊے/﷪p(؛%x=| ^+;~YL7lu@)eJکVh *`[Q8l <A?GP] pt3^K2dϠp�ҝz֦J<. LW-UZעB&! x6�#Pl'x҉0= | v_\|?ygW?WǗ; Lwiź|P!``k,'L :"=~s__uq<s5 ;_} Uc& 8pt=*Ap� |@ӽl )3 O~i(N Sf0N �ܺARл>xG.a:E~Y(t|7?b{>6> 5?0yK/߻k4͡MS M)s zYJ$DrK쒼 ջ/q2/C6 (ğA�XP3jTNSA]ird "t�:o),YB~c('A _Rc1li:gJGw(K@M rJS< {pg $i$RUhqy]l.sx�lDKo56o.- Z^A~9<O,OC҅DD? `EexUI_s6?߆IIO`Hu "PiY6N F:G x' :N?#P7H g ? �A0|n+)_&/'҃ ٛ ӏU .%lҤB!<M@D S(2fNӧ9}A`G%PA<",]'P,e/+ ykgEC_PСPg0@kA!\O�a}8nZ� x`(8A1eH@ 8,�Y~2?ׅ\Hqt#J�@ ?݅L@p A=Bf"J`NQ#Oiv< 8KLeųX>prQ"k-R.CzFR7G}+b� yZ{.v*Yjφ@<=ґ`r? 44, @+_?@ *FJ ,?`եI<_ L_`4Xm"vDwVB##PP#]-H@Hoo<]r XmW@<^H �;@%xKgm]mU U&:_#@GcGz* 3r3O>!C :$%)o|wC';z|Pt z@Y9odcW8+.OnLEpH ^xqszH" zq�OIdX+Ÿ- mnmTV fe *k 1PGylȵ͜-LBGȥ 8]9Ff?$7,Kb}V7+}G&}&Ds=2Um}$Î)s0B7&R0@jT]τ>{<�ol+E?�VIws\UyQጋY*2*_i더Vb9[kdnjw?o7  g*ʪ\ 밼BO0ȏ]o j�-4fI ^gO]LK@tfy/c tOC3*<?![�|g2/ /!% : N 1N"D9ҳE⺡)Nd;hy'�[J 6| P�*'dD=d�̤D.\ulޓ G09U#Htb-zϚϠ*5& ge }h儜/\2W\۲n%K+g Tr⺞�X;  %q˴)h^g? 5()Y%.'#QtX)8A;uIA{Pm1 `)VS&i} C//__K{lS7 [@ !^=1o[:&aU)%64Ei4c4|riL%<)A�LkySg&ف~ nfK (ACcnؾa2*T$|*.sIJdw_ X�@HK�~8:!}hbޝp׷�: rM1�>;NWfBl7�;`XKc_;z,=xi(Q�Ӧv 3.^dm,T.Lw8../1/KM,牣~N <>"@`~:?D;+h>qm'OA \25-0|*~ Qз :7B5-]*4t E9|U�<$vcB)RyGK\s׾T:~ EiH+V.f8%@X�e�sKֵLIcT6b8*:]ܐK""掾d8N(<w$CؾuG0i,K@kW!8pbl\'wl?}w>!} ɟ{΀\\tq:~ 8^:A3gZV׌7|vG ޤD)XKo)&l,'?OX[!),!=mA%%֙(+Ԥd " ׭zAO#YZW0,:7%>P UqeZV>߄ : ^1SĎb/{Ĥ^5Wz`\1M/AXxd\1&?Ӆ�u~o-Fn,GJக 0BUF L wFWR#Of0ҵS|'\O˻_tG<^tE7V>aqT ~AiVjh#?atS?5_T ?�@7)'?i8ǘ�B2/,0?f;݁02TPW 4⭚~iHBȩAJǶؘi'DKب51(9E {6ҽy+r rI@Z+Wtm}*;J~d\Sij q+G=!m&pJ@Mb\/BI Lǔ~ q/JN%Sg]' :w� .-'k\؄#i�]?hUnĉqAx" o%/, o<>Z"5}y7B[)f҇\LMS{B7!6\/:5ȹ\oV5[+f `nM9(Auv17O@ 8e X"w!.XxaaG%YJ�ICM=EW@^f *]+3<-VFSq*<p+tT<˚d] y_5 d9hx8[h́%eIVC4]rW eWmU@ZvE,ԐB@ '\ Gwy)&õ.塀̯iI8[{oF(4 pWo[;MTd}qsS7Qضlw &^+![ο2Zx3)DBє̭Oƃ]ՃԠdw檻7N/[-KtWݚݭ }c4i26h}̐7;֩|.CJƤJF.wm- o#7Tnֻ[ d�AN~yM矁w}@,s)EM58-@ߺ`k7@;6pMyq|qVkA g@匱.%0�:? ק$��n2B)AֱP񭿍+Eh;5ʋLN6; ᪏ 0K\< �dݫÁ39�G{O5̱?ട! qZ ./I)�ǠP1D<1͠2%c"J/'HdAq]W  q;;_Hc?W`_xlyY=]+\G2y92v|=Qr?l%Z= fpOCI^s)E =@~յ*,75Wjj3iVמK(#(@j eTU�LH/VJ* Ns6Pa8SSt#)%A Iܬ X`LDFϓ4Ԇ}@P9PEJBiVQ$;iGqMgS{B{[1;Mgg?]m;Zye(Uqv>sjX[pk&y{ҁ-:/*‷\.;u VoR~ix Wսq¥F8Pq8 %Uj�.A $ܖ ڿј-}̭l!o_wA`I Ь@ t. }h)!� sXsжd3%%H#FY/1zn:67)95ۚ- }#or1g\JT@߀ R|Yh?3s6�S'MAþ\v {ltEN !l sV-n懻ia79;˜=<pҠMM4%&;.\a$LQsށ)#^#~4* 4FIuQ4]7 <g49. sQ Pj X�PP[~G�YէGN+LX7R+h@� 0/fx"OAC:(6xw NxFH Xa|ֹ>Oqժj#aRw d؆͏T1MkI TEA0 6J9Kcm$Иy�ST?O?qA0FB يHKp j\U ql<X%<W^�`)S[$�@[٣EA4k= x\X(rA Д>^ccQl;Y?<\J dd)-)l l8n�h< 8L>v<<'O4.\&�W:p 5-/ !;O( 9  X$,~ TfI³45 <F 3hA-�O9zy(* uioCk/AcU3;.O0O=3P@P<W$ [܏ '}ؾlo0J9 OnuG@BxFczBM\`/ATA ӇL Z5ݦ6| P",8,7 y؞!](EX8OPFZe\!VI~I'R G=g nc_{φ8םv/dC(Aw J%y�}@U5\6Xۏùתa{T@8Pzp {J(/ LHCO˥%ߡ�Vj 1 K{ )�H\F M2] bܕ!NwVMLI] ^z4C?x61F`*y[#yZץ, 2@LuzxH.zǍPV*mĞFdo&jrFÙ15l< $$h~S3 hm E,\@"Ā ܓD D^@UsT61Ih~rC.HTm̓Ek6d[ .T-K geF-cc{�(ZuaMwM{U ~Yk#dyV +A0 E:6,\`pK. @Z#Op(C La2$"D( ~0f)i xxh}�;o;lF %u!Y.9)2Dwwl-�Ar󙍭@7ذJD#… fRZ.-*u!RTShZ p.'.Vo:/5ju<M.o <Dy++hm ףbL^p(YĔdz�>MwCUtG 8xjFC4X5\ _#C̃ oIƍEg2 wm*@Z,BmU5v}ඝB7K&6Y k]p2Ɋ7MkPs 7R3.8]/谱'& qM'*Ȍ[peHa,կdVfV+欱2 gfv:"_|ζb3~6E#h۸< GRo>CfS`IcX2>~K > 'liCP Iߏ4J::a33BҦ:x<�@X[n, W� HY%Bsnu^FPΗX9U6p+s+ţ�tdƚ=K)]:,'f~ XJ  Vi`(&@�!E _)RC߰lݶ*Y3 } f039@ L(ҁu4뺩Id�q�A)N~KmæA `lذ  'o q+-[&) xQZ5S RU~U+{m&'Ώ?Rȁ`ZɧVS;x ͭ&k5VVLw)K (R۝5csZJT=ZrFCC,V0YƳp(@ y XB׾^x vA`Bga~EL0ؗyJ_Ye"O0ϧ{ 0$`X?v&œh= ۯK.ʳP)-EȊE<Afpq7)fFeb�쬑&(ġ9Oͧ }fjL ޔpnP`I2bن[Y1Af]!iy"B՞ ݶv!Wo]aZQEo$( XR%8EC춎M 7 \،VƘW�)ǴZ;zt'|Y�`LO]cӇő�MDs@H ~4zj=0ttct˻I򉔅b5OB Q-RT]=9M" 4a3nw~Nkn ^4Sa n3T)I {6m*=g=ja3r2vZ m͘Ao Kr{s[O9 Z?]W/5jޑn}Nt.g]N9 4�-xC߂9A#z"J9Ydھ<,nj;-/ o[HT-VBYzN<6z_ YW~< _I3\<OA_.Gpl0 o6+hqv-L~炘S3ذ:j9|@rt(@ &<Bm[ ]xMΙ$Dc:mљoؚ=VoCA�OȻؖyz`˰j-,MjWKi@7{ : /t*}]H;@̴tӴR6tj�[J-Vo7S.IVgaӡv6quqCZݣ߱ >Cmt:N`l!a*hAPmCJ`w)1R8 ӏhB(A_r Yo&73D m8V+AO /K @V qê? UjEQk ؛7`Lb4Y `%C68%J�tB_-cD t};=%COFr<)Lh|&UΥ++\*,)lc\՗Քi(KҘN &Jp (A@؇M@ _< 4}!xEv%_Q y\whL Opcد %x863+gS'3f)+l x x3H J�p?o䵛*?s϶{O; :E.#r89~ڹlNν{6<<\.-3xٻ^n[+2no»ѣBZT)BU;ZG1Df54pEr֫@<6835t �UWWWꫯoݢnUo=]A.ݿn-s$g]u\@LW[GC#Mj+@[Y]O2 Ƶk'N.0#h;<D_A->+ހ}MhƮ璸L/.% Q~Dd}+VA,>t 8N/~)Ӄ7Ix#8ፋ,c1&`k=&_�Fii(0 cOs?>od&zvI'Kb@,NNv#8+:qř8o9IFN>>L.@�?-@B F_1@Z ;i6Il:]}66-В ﷴEY!> Oc[-tO>_h퍸x;kTY5d'($"Γ4)UVltAƓN-� 6y 8O 8S/?ufWk%[okZMkĶ q;rA.~q- 89Xby Xm7d[HpsDXдU hhG JX37=I5R䁠9cco?;As|$%(%Vz&.ˬ2 P X$va0e(<.%=:̕X�APEPI:WKZIkmMCP,6 c䁠R|CC,nE@-^&dl >�9^ȸR_ tr ,Hn[}Xq+շojW 7b]}/SZ% E% @@K_Att8i뗾a-ŧy+6UqWsjT[иdU2b^~aA ؾ[ 1NW)woioiߍ/ލKP(OfVJ o@L֡q T�\�xzuv h`7K$'@곪T@YDg%0@ c NI13_!+<'ܾ[9 8qA[9rHhf"PAMhZBBw!Cc#G`\YT׺81\2WJH*̮q{5w5W+= =JW |_-vpx!flag~?vO@|Z  �* `wp]'B+ u/Gkc nE`3{{- |滓؎M0R-t!'pmO ܲɅ $x? ?PDCk P@S6QFg7^uz0~l9d,'zr @rp_%rkZkߵx~+tC֜lN֏Kw${z/ck1Pj!< jyG(@ yP_vסD\lClT޽||=o%/o'f{MEħc5+�G%VEo (vAS IJ8 vϵ{1S\$ H ^t$ ?݃ PA@z]|AK/y�QY(f=/ B M 'B XKe:ODPG h&H@]d\u �>Hl .怲@%0..gOcrF6¹"x~aJk{䂠jC[ch|XCy| w/TOp+A@#@s=VS�c BO)!E9ٌa_O-B-lƠ{`K>wt^[_ 8�?8#@ .%EzFfJG?:OhzO @ xZ*C*O19שS"PXNG!|8u,{\ 5xZI lB_i2+@R6?<_=[ű{b s>ŏ 8@g =@Ҿ 29F 83v9C}x2ډQ); NLv *"/~_�(gm6$@{ 8_&@/$vR 嶹61ڃo6p8\3 P,z.ȿK}W>ñB>繙ф͙& .ZE̖pbs.JWP(-h`ߋQHw|5Xt| "{7-o+>9#n:ځΰCZ2!%ˠ*K}T ?|kXp4tt(:k'6?*hߝ{;O^@!u9삾W�O{po�%kFr.׃ \Fss1 9I`]L6nh5Aa�) ɏ�7~�7s>?l Ob8B�uw7kV񕶻 b6:G䰮rXbL՚ w�|ngwN 4l�vh]u)$(̽GW/pą'@ph5Tp GE 8 �J ~v=qB|LQ Gqv x \`QP}X~>hi(<Gź.}WRqE 1v})>ߏL{B.R{.=A xnB,;L �7e=~Ww>/~A_O %O@h-*z '@ vO @0RH YW "<CѻI P\@'' 80r}9̏/Z`5R+4P#Z6~BHC.#)-<Q=&֫<Ax]D4VYުu*:_-/|~9UKt]<Enԩqw\. $^͵?~[[](}FZ h|</?n W,Ħq܊q*CB>`Ӿ}Ceџ p% ;ao  =NˬaJ:j)'hlTR@RI q`,ӱX8C fxSsA8PFF%ĄHÍBC7r:#J<Q.Y/a1 -E.A,>$[8r'�!f h){~ F lE8jpd^cMy TP(*EM>N/|da! X[)RkamߎKZ_ٷcߎ@K!&n$-hJ XB_!  :_qpAh =\R<H 5b x)~q&f>Uc:ż>7@wCTf7G-c$RBZ8ךpvɕEڿWAl,r# o͐2aw^&('N \*F]^8qQ7CvL.?<J�f6 شoDP*-DP7rl\KK%!`Q[gGubG~W!/A.e S"~2p`~02Dw{Z1q֌Wc6M=<M<<ȕZ\/!MQIMX5ZRy4e0×H%P'xb <K/qh&•A3 GgğN=eRi lsƽ\ sO &@!k ,B p:!wzaR3k# kkcIwKR3)&5Wp+]U �Iy9 Q5_J1%Jg1k$1߽6b+1<B uJ^؆q}.i_ ~[MxSxao,mHM ]Pkm~@ 4 $+l%NϽ@9 Tj^XҤڞ,�%Jaz= i> ,mD>@0ѹ X9$ ?B ;gwNc- )8]ۍ`q1+�`A-@u?h #M{m75LpgAkI*"D)f�@qy;[pȹ^g?Aج *CLz$ij*r$#)Fe o&b< C #ۤ3IvMy ?A/Q^ANE" 4İA*(_:)t?'n>\R ޙgw33NgVYl⼦$)qkIQgZL@C)�˥ Lp �a1)kx޽Qk4<`l`R丹KxW}No+IJbp pT5/A0<G 6SG/@n@ I(a'<gIj'@K|T(ҀI~ �0),@A-.~#An}nfm7u18ZY13iqRlqq^$q1V$ya-\_ C繐y (5''i"ES-h"$?cc}rI{k )s$]a;p?k O %(rPX`8<#TIf r~@| { ͟%,} 4MM0}# 7Ȟ ^ĿŧI|��}LJ=P({&4H\JYa(r+!kkV@C#N XG @̂Z$K_6WRط)Th&v_]/$#̓CݼP c@ړ-pT ػ W4O$]t>CvF{,JAtޖb Wr)-x6ob4{ޤ CN^8^њ3cp- +` @AdŅ| Ipu}C6Õ z~q//__kOCaMGyv{$y)- I_ M^J\� +R8Q=$7/!%w}B85 8S ط K>6K1r.j8U>d7gQF-.,w%&/+n+|V@X# O@ h Wi<qY%_d1A@p dc.(|@� �ʛ|Y`"x@vݐ% g_l8Bܶ܇mE<%�\@yyzq[3�=A1B k*vW X"v=X@o�@=Y]Pȑ 'F_Q�T(">~]^@p']m)AY[ BeIw " 8R2 _ sQqZ-NnAG (Gs~#؄�A<๠( MZt)A-YMxv#8XT^hcpG zl1Rop)u3y'K@~A-*?p&9C\'m`/;%: @!(gS^DYF] <N&ABMɾST6Ol}0 ,E @ɤE8=ϻɿÖ%CGXwQp̡$8&W3 4�2:S^$=$avz(m@:xaU )Ws?z-m�qy ?\$=iK}z2~ronrۭ.!U@ Kb}^+i|Tuvd8~;Uyt7eA.՜W@5Zng 7(? Gp>b]dFx]㻹@&];IAu@,TOin}NROI(΀[!^!E u yZ T w>8ÊJ K\y>@?e6@ Y˒34hrV6Y^=0nTW/֢ݜ060}bYf»(Q�qQ5Ī\H딽s\ h1wrx5ʚ|&2@f 6hw^LaN}#J!-h-h}B Y ĥ^e@OB?[w4 Qߝ21; W . E`((wqi ~. 8F[CѨZ~G*[&A@0Aj,*3YʳVIDQĵ&Z &Ch@`d&ZTd(<7 t @UAUKҤ}Ի dc  &Q8NjQx+kEۄoiƞqE!1/A@-^:g1qyA:+}`Z&K[$$O4.b+UNv%T%oK6:@`WqƇ)lkNN߻7-9 H4&a *5E HH)uHo$$dG{tİa4Xđ+4.@U6*n/ D%_6,z NwO[A0#@`|m B�T/p Q/tw_fnFy*){ŇK(^Y?ha8 K ` @!*$-zk(({3`FZU }jp.8I6GOMSc[V~0b)@'<Ft-0,Jtxg!sZZo oRh( BB`sTAD5ݑ4G9P69"A5k*m__&I12sRB.^_s ; }Z.cn4HB#LpǂEFFIyC1kr2m%)@`Tƹer XKUG1A4~ȍ;bn!12 ̵@p+8ʛxfA`t�kzcpt\{ $tllD'u`kݎ#|w,sݬ�߫v1npQu vW �,GAu$u[@|#@3:ԟQ6[00^󁠷sW0Ҁ0)5Xoۚ a `"%lE8>gn/w}c"(L@UL/87lJ^"jֽUzKf:<"Gh[ nqĝ%ߠ O;U>'OX˭rU#w.mMJ\HK%okvݭ5EKEo'vq +7Bi&nU˯m&9'E9X㫀@N e"K(@P5:7X9$ٺ#7 Js97&$jo9jw:_ߺN>ظIG#{(^SvPiLGz(ۼhaiBiЅszk{di7k4<䈨د)[Nb?XEC0ǁ_x..kOȷ ,RߵI}lFP+>*[Me̬UcWYΝ(Ѣ4"Qm</N7kEcO|�z*9^$M2T# / i#,@'b[d,*yMOCh#!Gt/ۈ1 5LV*194bR ɜb7cO� : $Vc@eB0 ۠A@_7)A2GldAEĠFHh˚3 #M] b\6ʹW#hrJU9v5)Za$ȣL34F,>.icֳRriQ@11Qh|#`#U KSKHl*㩲Ebi tY:3V<ty3�A!! Ťc[:&9E.a-<p�R�KDI x _;;A`qAP" /4e (C3sVɈLd6+}8Y$J$`v')}BB,-֝T) er{PfXP/ѱǖnjS~ @cX15lU :h2,SwOY*;L\,.`*}27ށ}U`BkCQ -1̩V[rQd~AIn @J &A�B:q@1A^5�๙y1c4rbD\\J`Bc_`9j +PpOjceiW̖Jbxѧ@p`mV3]`e͚M6SZ~7$ïi}&)tG!\(y~8j_G((P,א0 İ#- )آ('*L n D$9l?Nn Jm {D.SRl:& B(�Eg(0[*[%X[ÔPW>Q mBUaֿ 5HuZ;\ 9<줯!O9!:>pA H 0(XZHd93 *yI>!T�h! 'v$ zB x=QH %@* @j@dsecP<{<0j&J t\n\K`B)^LwA G0w_@ 0UNjr *>zs @|hQ9<8@p }k _; aZuGH@�L!�Y O1xT`EWx\@:C1#O0ext뉺R\�y|y@`ʦ@MlR]Fs (q[[9lmrƁM0*#+eI+Y|NĶ UAа - ggXCP uR]D[Q]pjw| Ew^uE,$<A!񧯹;A7'듢hmyT,RƝU ¦& HBmF`&e5�˨ax.7E1`Rz9FHI  yK qh 4b m)&XA p� p,c5X@ V#c4QҫRI < o8ɱx $G4ng_u6~e?n :έGsH1wv+u n; $d_~SP&_sdR/f=8RQYCFejd!{mOuIz ʉx?='bpxIvT9_َw.cOqp:pR}+'.@}[_T893q 3Tp. (Ay*Vb!'IA ;# 1~9 H`qxfiXPayG܊t+Z15>|'T;_[;l H M@?>( y~?$��臦i{*֗!4 X\9{ixPP)p= H8bY8R sr3.ҭ<6V(m"rܗ}Ab7cxGdnF!3&VEEg#@fjx4GVRKywmM�) '|  y|ɠB-A"(NҒ3ʠ f pO ;9kt28ecw z,B[(&>1fNqRnv3( #W3f^525/d߻9Xߌ+p,\:΅ݵ4rJW =K<u:F'sy6xc22x.w,]Qۅ`dhJj(6q~O!bTQ b%[12K:lIAB0{!&brW6+) ZFs |Ai>νadjmΕ^g8& U%,y8JY%K&z zzPgd㧖 Z`WL0ѱ 1q|G#.@o7NoWGH zp+8yP `GYAfA烙}RQ%J.?% P0)�U vf=Y yx (sc(H442bTht$HB?V6#L^eJ/0Y7 ţMyU/$O S � Rt,Eg�,OqUS-UX16ܔs6l볰/%C;XNPsóTਡ4!W$)(!*6 d֗Hg1KL`꒤LW=�,lR2�U2 oo 8(i\]| hI, V[Ģ3KvA#is;K0,BK_G@Ys6'*bWYw`11S8o3z8ֻEv ;Qh@JmM~Bv3Py`5xsh,qy Đ#/bjՙ ` .%82ux[P*NqĈD`,,591s+Yph_Di˟ 0A Jk$}c+(ӣx(A%cE .'.'%@[Q{�M{QH 6_Ku}n @pށĩq 5P7Q\ES:&njr'@" H!xYjfe\'$ 8]`@VP7@ @YlH[p IEUl/A3^uϘ .ޑm(xOM5bޏx]5O�Z{<V\Y"O$`Cs%@8 =kAwoE/3a@�CX=Q%*pl�+tEwj ҉1@K) {]Xw4f�aDyuwyϔy Щ؁+`MdpKpoQ.hZb qb PWXWZςOyyͷlZJ_^P7`;K:Ӟ}t[3uY;� ejRX )<N0H C`�M2=!xwg1"8:|th]P]]DX@lRfdžA9܂&}1r{&誋lXieSX?FD#Iz` X;nl,aqTqvNwOvJ@ %p)Y`d`Sށ7iV~%͜xlL2VE2Z|$>k 9ڇl'fٯG`xwTbv}Jjվ ;.䜀`QgD;1D't7l<ώȫrv3*2?԰q8l {hHI rΈM'B=Bl |]]tyF&;zAH� A0E ,�=>p |>.j˽ܓ宅-2h-`$n[ֵ@.�1a"R7>[5Mz5E{43oD-V^;9p+eZ138ъZ+o9-_Z)~Mo vA`\=7#S=[R [gDhKE2_`aB>mMo,I1c5:N9њ= Q2TE– kTqﯻ98)ؚ_c|QA|_ġX}`zc<LNrHzY+Koį5Oe?o?mU\@Z+9CMOIj5ur$I4׋8E{' h\pU}&f"etiXtn L˺c0fYMkPt;;tJY:}eg7a4M4[qndKk$8w?2[,^i.BYd=gnZ^_,5ao 4 7xlƤ7bV_9I/ Ktî[D2L^Q?@.G忏 R[ h t< ˆY1? m/Icw-0zjd|b?7P.N"Pc!ka֘5 ,]҉ }OSQ Omҫ qUY>QeU!{LL stFy=b'yNphI p"FubH{�tW_Q'|D#fBZ #A໏z \UfV 6iޙQJكw_-1b:MڊGpFǀ?!mpZp�@M6438ȱ7ϙ9@Ef:<gօ cȥ} d:hSOL+^WR8BE(~�pdRnxrSdynvc\Lsbs9s9FѩѩiBhv4PY@ \i,QV{1#q@Ojm�֕]ڴUmIqeiTyk=m< o7 6ȴ m34Ӝ/0E iC;gǀjyF!s߅&g%z j6eݧYO4R8Nyg<=(8NlL^ʙu^0di#|-VOP^bem%1iԘyVFKF+ntA0h2fSB:\NE/ȅQ]7_^*|ݐdM6 0f�)(d);@,iNeALP(f'`*Mt."@`@!}+*Y @PL(*7P5 F@0�*3�gTWNHJᅝz�T܏�o5QM6,W&),VoK� f&?kX1ta= hL e`A[#>K4b\'F yq% V(s(V/#@!:pBvt^hF^7fiy5}[SCv@AGQU2 e5o$+|9/RЅՏ X; i5T A` Χc }\$ S �mM@yc:Т㛻Z` Aw1S"إ/�VLAj1�R>s`AR&$Z@ i n6ؒY �chǻR;/ 9I:"8u:,`/- ?O<4(]l@ 7)p-}N.1\?o2+@q-`@p""n">z&T6zMz_ȼ'ÔJ�^3Qҗ1(O2=ճnڿRA�{sr"?wa%[b]-K )!,Mu(UNSodVX D<eȇ �măa$O@<  I*g@l><?`ds}?I/BD: 00Zs>h(t* @Jпo׾Dž R �:�cB)e:փ;:/u~k 7P Z-@Bb�Q xC:>) -P 2s1ztr]v)աBuK�b`83w_Y%`%8!,�kLXi�7BP XhZ\nw HɽM=4th4hB|Ɩ/&KU&4FW4:WV^duB%vAb׾M4Y3A3q&�lZC܀k.@.@@  )/"( HKCv5ޙc& w=O:kƐ=d1KlZږK9hjZV>Y7Q5K^k8w"Wn/Z[Z1x҈XSs K8N L{"%hī@// Zkz@R&hix>oB]f.uxSa]ryU_at{|wQm &F<́!q1PÏml뱡v@~,lR*%܋92M⒣GH<$5Xc/x<\OOP @//?:q|DP?|$xd::8Or‹<0ԜAqE $ :wzd-k>֗9A٭$*ҙOW?n׋d̟ZW,w466~3:P{]M⏿kf M+n/7vX@;pk%b[#/#5"̤IG<.A=/}乖j-|;}m=+hPڗrtr$tE5_ˠ�~8í}{W'<yw|hc׏}Z7E }\}U֣ )eT]=9L?+8 rIhѹ?'欈샎\1^BH Z;`>gx{'pDʩBRW%9~@ba\ @I7iѽK"}4B\XhpESīMO].Rͮ2f�u/ 59|>YphW%Xr84<$WoXܤ^Q sqeZ6-<{!(5-I)'c2xFKy#pWL=TtA$8b?@�5p M= :鋑b:HՂ58)S{> =4 * !e 4`sסB~}(s?S€k ޔF2h4p[#%}Lbϑ~;S޷Va[(%f2Gn e�A?L"};U :hT0;'A��h*&*eF A >H2ݩׁӽ*j_$�JJC9 C���IDATZ#A_Hzr(BP%?FEP.vj.]zG9u'Ub *| XR,-6pX/�S:c%? 'G@e (Xtn S2ApBN% A@uNs?6\3PvA©.7>ǯʃAfvH>2CŹ"G|f{Wq^0M> xaErr!-SC t| xVTSYZg FJ8'Xj;"j="Yt{>set?wyXЮޅ =E$U࢟M[9*_FފCLzxoh Re|eקE}>;9k_ӦӋ@!xyg,^|/W7 s ETo,;=3į- :4'qS_߈߸{Rk}N{=~=]1/~F ̈́ Wxz:@MJXxjhN:3 N �c%C@;0�V 'sM@ ':HŤ�i"!%60xq YuDw?@ L'�xj !H X/KXF�DE0Tl{�-ۑ/U \(ehIwPsu6C /fI!N\YX%X9(VuA%A { \T}:_m2~c;CdξDYWͅXdg THl0۪eZEL]Y%&e} x*'@o|OL:eʯUMh'R_O1L)DK7`lEZ9I5'h'L|H/ƽ ,'85FJdǀv12%רp1At�xVj"w'VeF| KyT@= 0W `|P jjv\ T (c֬DE@U2g-V7ʤDv-UIxai;0|g1Z@pC 2vRM HA9VC_9kz!_pz=DO! m̸7 +9ȃݧ9Tc:`?A bJw.bZz󫥽NB-󆕅0:u@A֊TY?B[/f*@ײbT#A .IO9/@6 F-m J3bhd ,ڱi|E�'r#YF$)-(4T|U֔esQ9!A`^Th `ENC> g|tk~oX6X1BɚoX.IP%<�(2"W09@5UxU$4 X:A,dOSq/_EFhrbT: ~CpUMA\O _,~4 U|Y_4 VXu .c V(5+f?%w @;VmK/PF 6fXpn&Alg]?i^~uv&x|ԉ7,ObhjI8 SZ`^-q{X]C#N&t*+0Nt,UG'P#�ĸ[SJ (m,*z%bA aPxh4 q ϼj^V{ i8NTk3|'ŋ [[#$HP(eLSKٕW'~hag^!YLhx8s @Rj*6u�AD{syh.Ų#u~9'ovt/E?Aw3:̏µOjZXyg gsm+5fYa5Mʹ ۘ 9A͒y:'+ux;M/J^_Q:Lƃoz]7GKZXNNL ⲁ` =m?Ǹ^-ξgȊϴbʮZ طuZryʴ65%]wR7Jjtuoo]6) e:,&/: Sى[b YToL!/U Fh_'lA6ha'8pƴ?71..x4Sjjw6%vcOsk'{G-5R"Z]gl!fdlL4ךNbr5SGMy Ɗ^2'/ϛV|.3w⹓Usi3Ժy) Z ;3)v?GxA/ۇӹY+FC΀x@[zӸHHK, 0u#@M!}-EAkg6ۊWu<^] бkě>8[W9}oHY:,NW)T, q%Π1^#EfiW۶@8v*g /Nb -* [/*[Җ4[7 S?JDIJExO`�FPvFuO Щ A x% Y w+L)\XUHa4[}SD!Qd8XF1ܤ=T3eWYRw-;Q:P7ThnOPq UOp1Xi3S0~aiTVOb5«Ӽs|^C!>o;éUA%,4(^�59 b@hD qK �6r)?Rp)y}L^؇g`l)"� jc_Ӥ+je.(Tws{6s//R4k91jscTYu,ް)Y&&QcԱLWы @8LqNMaM8d=]R>IǷ|LMqa0SHOy*Ϯ+�:54dX'_:YHKS+KPp\lAky왛|A"{h}٭vܭ]hwi\MxQJ?'AٷI~x3ttwlM(º KpA)Enc_ =lwo)p `i/M R p{ŮpAݻpٞWg3U[FTy"ACP5gӸ[J 0p|O �ޠy `{] e$-K_S!{{EC ܭ)AE�I\) oao.%!J`XmjAU6B 0} 0} xo�PJ SAؔv!cQ]HS\7u=(&1$]in@J^͕iJ?>! jCAXAAPA�h`2+lB=Fm?ըfK�+L�(udZ|` ܀m;<J4 )@Aŏ<fy8#e-F\U| q rZ-d3O3�gY͘zË؃ޅ$`A#8'9gt@��0 _C"H7~}OA8p|MRKozhӡM)QT-M??!@Go6Z?A1W-ξż jt?d#{qezwP +& M6t;wF8kFqQ pjk+aA*N> )% p]=ޅ$� 8KO�x3\!0 *'k8E|ߐ=gǡW<s}Qf7C0ZK"%1@;?e ;(?: o@(+CQv: ֝3Kk!{KM׶2C'}ekݼޅ$u50 <�s[_蟞i�5,ѠbJA W>nd9gLT5щ݌5)AKkks%Z>Jx`砈QBm2:@ N x@Mzc}O ZȥwYsFx+rAiif8]η4Y/G .Ft˫t!q>G~N}|]IOwCmkeIYhH= F AOR YTSam+wr~eY2mP8,Ϥ kO @i / �et6ݺd]Ve9E偠�-,i _daZR"@`M<gDV\<Fp_bB&p4 @ꌻ@?#;Y*#K3rCX\^uѽ A?3sTwFwFM:Ԑ]Í>3}V☝kh7wOx;ъϻ>{ܓIO®; [l}{"cFM._CFIQ~ Ni{h** !%IŃH2}t!<-cl椼TkA{@}h!#CB-BX^wmgO hV<G7=ARG@|.:R;[�a[njtu| = <u{4`,(QKKW Rl1u)eh`1k^$=yc ss3Ч f};)I 824> 0u|cz@APu 9+G<`١">feh'dai}\�no ZrZHECZk6` Ǣ@NM93%XVoۑ r\ @`y̺ߎҐ[ID<D PӱFQޛʛ >ġvbGܭ`vA9G%HY_0&[[ koxJk<:q[s<'.Hp5 gV<q8Z9'oE׉ݘlvZ lp2!"cr?"G$i v@yI;i%qG)X gaZK9VZ15{ޑ_rHDh5(i= JXFӰY-݇p&R}pWۦWR #q[ڬ+J.SۗTdjT�m JIZЦ[1 &忏 (vr@.x~ߊbAW 8cԤ>usji~S\3-4`ͬy 8>^[k rd3DQҳh\M 喰spk-)gYf/,8 :Mk+ڢQ;UɎpԹX,A b @ڂm4zl H 4#A`%@ئI #aW©GWwڈq?�oEx9A@E@G*aś�8 (T$'4VŨaߊ`@Q,nDPolS>'pY�Ee#(D #)'rCOP`vE< HGS㊵ J E @ b A-Q#9?/@�<AD">8!t|[p>fZElEً8C9v_J6Sa n3GJj)2R{Po?'p �.xٶZ%wRwOX!`LjkEO(<0'H�7 B Q<7Sh m]ުbm�Or]wP?@%�/߭?*O~[~Ozbhq=y ]2g-Rі�� @tj[By<5pmCVN` %[pr@cixI -ph}7>G̊Fd@UOz r=lTQ Ё!ԣ`C�EJv܎zỴַt %|hȪ!(jy!8J4��@J:v@`jV$d�P$ԈN04*l[jmL [JreԒSwZhU¾igp>\`FC=:&_|i/g&Iy{>Fl& ]6(fᢶX>ৗJq^N_2 }BnPQg;" ]59$J%<e$ ]D Km],q 0|sA0r�{ 4vx@¼p)g?{[V UnD@L{젙J`I?AtٚL[GG: k} '|_ _l%rx dVt.5noJJu5Vx;BLY{KۗtZ0A` q T<Ϭ;Xױ']]:`X:c|YOԴ@C{Weע A<QL2\' m]M6987Z @:0υٔ`sй(A-iv8å\ -cs2+o*NNڽ"Rt|[09 TG֝=;9A- r,D{n|:J.]|7кNZ= Ҽ{HK;#∷7, . LuKS7tT# 8!/ļ@KŐ]ѣۣ_F=`69lR1b27_ ,#,q qI9MsĬt܆CW]D-;QQR}C < ?8Np{n{Oadn8:?˻/^N3jγ;.'/'c_j̜d>dی{ ;H<z}yۋ\f0\@]>)AqKz6Gk1\hSgO 0xf2N/Vh x p[1g jCm;Zx3㭯K-b„to#ȅ)A9ekUI?,K`f< u‰ƉϕO 981xb05?~rb>ݜOf~>U~}~Tj>9Ҋ4{ssrz>Bm'`JP<ԉJs@UV<κR3rD0� =Ao{+y?XFյ+9avZxǁH;K}5DYVw4F/ 85ϯØ]-8"*qUVmq:<4l�M |fvɜ8b_.-Wse|z̬/̿͸93e%i2Z^ao,Ys[I+sq<ZE_:Ź9kޚ7S/qP+=f:[IC|P4 )x`2L~ G6}-A_v}g3bƝC}S+E++qH( ڛ׎.Z"^ `Ke*qQܳ�%2-b4푖"CA_NYz O@9VkAq%O/%J ٽKf@ϵ\T@}v$N9sŹ==7oؽ++?H=OK  7LL�h(w =Q`s5cƀmhhk&6Z2Us \d1۷P$K֞l2 vn0a!Іy`N32GH0ڢNU]Ǯg A-cU65�Y &�;oߣ@p'}7jmf7KV[ʕβLggO{bevAXv�˃T \\yP jj@�_ .[yPF3oNꪋX.[ iluAeAmBk I٭RN[}� A{I9!OuKa2s@lVP~?`IA&,&77| fi/%1 #^I/Y#kJ�c �!"2>GM^M zHr欁X^^wӀ~^WLN'1HĸaVn4Fq'~i{l.f_Ut󈹽1JV~Wk[Wy2t-RVT'RוLVAdu0,Z7 <3inb <P m ]4: 4W _e8+- _WDf93Z<זQނAOP) 3TA{˨k3 �BȓF*?cs0 u50† H2uyb9p@"ɁH ̄JCs0 +_ˠ}jKQ3TJ%V"|КqAz5)β srٞIXK`PIROg?<3A`g`Яpxx�XcK+:αFRͨ%&9Wh][AOy-?.c9h*vZ#>qֻSJR @cƑ9qCQ7y.~ gQI$kKyI'Hʔem=<�y^YUg2@% p=<lj+h+ppjͯ!>D�!+.'cphVN榌Wџ&6\;tt*_?5: qjdy;@cF!>?@oB ׁiB]Y$kAW5e,.^6/>1!Uຐ=RKE gL_>Xup4՜/# |?}Mf]9p"q"ٽC{F uJ֒Ȅ^ZZ$uy۳*y]ml[ˉrW8VX^%I :8$k[2ͻ�|WeSUӠnb>:)q͜4'>bWbJmA0}}Ko|5䇣FVq3pO&*ֿ\;<g(ͺZy\lX6:=lń.# кU Vr }6۸N> ֆ~1(sIw#d6Ya ܴ|cIyA jX'?3ˏ]W!;!-3E2 4MLCU8e0~Zhp{,Đ7(e_WӓkuѴ?'N7d�"UR /~a+:LkPvhKq* ?'NӠRY>KaOo4EyE{i?w>Oa )w$@4]x u>4z]V58zR2;dx<>GQ wb˜g 3[ػW)*7�vɥA4x&ns>&6p>mq g :? x]I/Bͯ3|� E/{&<q PH2}S ybѹ6NWRTj g)jdNO 8tWߠsFS M1,a=Ƒ3c04 \ q]KX-+QlLD4 ;Z-4ePi| M8< ݂;= zǪVwwӟg5 w,h ڻF 5 >ְ#pD Hö:Y*n<K|4#{KsРaHw;t2} X% uE,jA1g&YJje.SmܾJE5aW{Oj:qD KG5.d I/~6iiǂ䚥5kq42mhC״%M^1i(|+v^C{skaYf-L+�5W3\CKҋ2SiAA_{TD*xF4B HáY6M ?6oR @`b9e7-JPfo%xZ uGWށ{!%Pvh9*V~#ժXpi:`E35 Жu@uC*)(A(W(nFBqs<_֯օ>J[xݵs"<xU'*~�\PwStjojA 2p<HG \Nd)F׺ Lh_#~dA _ AP"Xl޿wʲ9(<@(sn9/e"x &QcMdphh2'B]+v-Dt׊2`XB}:^Wsֈu�J}b6`:f1m0ցF>�4~U;d$MGKwBfK)w .�q;5?E()jP&FgoBÀ"_%zPk' [ɑnbbV<p Z!Em|pOAp53l,A ɠ~P=.Dv_&Jk1 Z!*x(kEW J�KZj}ڛlVG-kh8cgXHr+i8*k`yxq$ cd�(%,1> y)AmIHof 2&XT޽' bT݈O<>?`< q qFHՈT pѰܢl㋰EM2F pRRwJf}�wt)(FRh2G*~5�Af'*�/잣Ϗ=$5Y Ji*t 4 rE~ېRs 0uA0O[a~�Qع}F LI r4 [!�,p%3~(xV5:wk;6o Pr&@6 JDP8.&#IࢨrC7)Pf (<ĽdL] :v+ 58>sTEQ AF <A l/eiAql1\vXr"OгX#RK�n$ĖnK4b( ݥP]+ M%{'8,#4b,l}Ek(g(Y |cCo k<[i\Hl1JW2ҵ~7(J;hyeU85kxЦ{ x-PB#Ӿe:UpM n'aE+@-@r) 'rpt:%T{0<q=W޿u^_b(>J6j5F_s, |:v4:961ΣYu`Xƅ~j!| 3E.' 8aŦP =6=GObCcUZGHQ=wH;pyh,&."$Y=p@MyF^ :;rb7(hufLBa6B( "QIJiP G6c^2y=ATb>� `БO~<M'/ 8C \ydz!z[<n|Rd!?"3tDx5 L)1Y:gDsP )ྚkJ)4~{lEF P/h́%]љ%s0<Cɸ&n΅˞r V'ۅ%<ԠSM`J2|Ь_XC3yy|_>wT<' 6"qh4rT]F(-8 ߒ 'ˆ>I} `j+U~{<~fV7O# mӐ:G현WLdK;P,H `@�~@ =1fJ>Mݜ8*E<]7'@}XAgd8Og8jv?G;S&B OC|aq�gM8ASADs` XB"0 MA\G$EDasF{L<!9 _BJ�N !b47YE䓳$C:3~g @VSg_QՂc'45Y=x-vy6F}FLl63\&;6bL(AG 0#=1B7CS1z( 47KEf  23<J/CP� ӰG_GB݉Er=(y1HEzV=%9Ai)@i1#Hx ( b;̈M3H OG ȐOa[<#E-y} ~% (&S@PvA �x2!d$24}lP>/ޙy$@&oAz2xZUќ/V^ 2e)A:`DiB6saؖ)i)�2DޛR! 5{%ơ7R-v@pBJϧ,�ad`F'$&$^^:8 wϹY y 'h 7r?6 D{ٿqld* jdF`&]a[ sL!ނ!AJsh'#9;}P$>JP gYu@q(dqRB-P=:wk&CCc}aФﳒ^`ɏӐ 6䯂%Vx9+su 2;b 5@?/`\bGs\޸%l6x δ5I�θ (H@@- PW[ M"A0˷ ?bA3ym^<� ĿAU7!o<x%8jN9ET2zamP!^ `f)k{`?%Ap[1<Y!0EEh%v@Yϲcx@T&K2�& 4単.S}m2t{dF}I?vv <;Oy P_)cD7is&~:_#d|MOrqAuD]خ_! �8m^usN??Y+nLݹв1w nL\Ya1ud^L,Bh}.ŋ\VQS*as蘭~PN')Z`fZbqz.ޤ3-kRmϥ a0ݟߊo~wnRխu.2R_/rǢ/\KF{˽۫+"uyh}T `Xæ_!ipwXby-j7t7~6>o ɕx[3d:@O60i6*o&S 4 H f~<zFI &2i")A'3 2?;7 s4h WAwQfnxd/Nfk;�mS TiOcZJ㳴;sPČ&Jc\3%{B&v �yOU %eV-;dgT Nap:y~et0ZT5t]yGr uQ e9͓|cPq #K2~<z'CD湠|^0o!*〉4LUgӚEfr8Vatma:3 j?+(Թ^fh)A#=^P^1?^NAG# Yyۖ&*KgSy\R /Ee/S2mRxLOJAA` Ip*W y9Kp 6)/Sp) y%2n zLv(<{Hxs,7DlUzVeZPQFېuSL)˽;C~٩bY*$و{*LW@}y/+mAp`t/e|qpp( w1xD:a-OQȸGLyj@w3TTCd}:}-T@Wܫ�,¡ Es> Rpc?/MAp '=h/c!*]&5*dd= HBok$]Pt#d�q8oĿ8'k8,ApbI] '"W2lݟA*AmRp?Xz[X %P hggP,7`{ 3%ꂕ&"L(@+K`z4(8͌|'Pϸ(W~wJ"i>PfkALEњGz1) x4b7R֢!:~@Hɕ ؑ5kAnj Ϸ3)^+}Z@P>ha^1gnP Ҝ'6t$<wAp6"+> a.d Jr1WorE7iϺ?l x32 B4s03�1b =sk 8F=�Nj]SC&;P@o4'e^e]"s>1Jǩ!G훀Ώ 3r8xE^iv6'~\* 3!Ctm&›$xaRλ!+VõW$NQ]h|{uQ*fkf>)Ja#ëb;O9y^qgC3:&R\=5}C*(`zk.kvia�64@e[;CsqΤ*WFCiVN^qG�ᗚ+S3ekܛW(ZT~<%mdpy{zEfBϷNNχSߛ pXmRD\vG"ֶnv- 8[ l|WF;k?KJmi{ӴFW.O;oRonHRsC&a+Xۺ?Q0(C(w/܎35ŒSLEcӤWW0,q0{Q$ OHI@4ʗ!b sNORuix?I"N/Z 0`Q(|)Db `֔uYWŒ^!2mxpRJ`&S4S!]PꜦk)}<[*s0CWw /ĠvI<IWK}<3{0"IkT9m{dG .i̐J8TՈohߐ˄_0kД/GI L=:}_']T|M0ԞJhVLi={0 HشU"'*#-qDWh>AJ]ad~|IX?s/~Q )/b3j}-/v-5EᴪSga ǘ'=Ly`�x |ʇ> L00nLadB)ƿݿ_.]e;Lkc+55z^AZx 5i�ӂ{<F "jxv.!S!Z$=_}ŷh]e*r|*(ޔ[A! ?߅ }{>\H!Ύ*ʁ0W J XW|_x(?íX>Nne';,dQۊ4O�ݏ,C[;4|-[M~|?QH,_W|_ 88*]%8?o=3RF@;$:_-CBm?_p!B%g*j^D}_CaJ`@D7^t_V'<F;X9t>t;Ap|y[.%��jA9仁�A}?%�̀�(G]JPvEiA1\Mܷk].]{ CM Ƿ�~V+?AXcMa0M]AЦn 8&DP '6(Oa} ]I?n{W|xoXN`B^uUZT<cj~-p0~o8<Apvta)@3r.H>CRۂH < +.*ga.*m0]Ї)W?o9xZ6CČyY7[yZL;pn'O)mS0(|f{G5*7Q/s "ϋUB uz3ހ,vnU[F[C^pwVЭ9p\3;W42[@ϣn.8a7Zjj#mt`98Q+V/S.+/07CB-o;ƿ"u|=[omZ{݄o@Љ"N^<ڋsm['MGű�Gܳ>J]@`>\\$"5vZxnOq)Qn~{ڻK}GZA\.&꤁|BjGEMr{wuGf>w gȣ W<J ȕts,Ёo~T V@A pG`ffP!Qӿu՟O厺X^40Ex\> %#U94!(p1)`BR]Y3_z6j|6wU&U ewu~R\[i�2K ?OҤҏ.V%C9i1q3^O'F1)6L6纝ZhWw=?h>>NU%90y)�Ƃ ~x0&<LH3& oW\9|X%xk<p˅ghO=l46{&(K]OvNkk x0Ti$IcOMp< 'c4H `-fY 1mK?86wGG#J`h);*H7N 9 B�&tA!Ig f2%E$=`~B:}LܑV7@bm_u:$cCfhu@Q@Mw@ i3�A`Kl GQ{-D9fB eOn^s{ 4uoG՗пt@0Gs[j;/fO4# ~ZZ׹ɕ"WA2L@0je# P `2+c lɞi5CY)3,1񭳳�O''oI |hU&BP�&�TYtތרν2%ZՁ- ְ-(iz k, U|w}z6NSIo0j+8܉ă̼JZ}t~Cw/PQ]>6y _5jfɂ`NRc2sS�?߁ l%ڐ$;MT"v1UA;،Z]B0RZ!3s Y3 :#⫕e_q (OOL^~{LOe\#**"T,/=ȱHR񗸘+@p+#H  ^}꣯nzụ3bvW4K ҔSLs\(rG/ ` [)`%JphiH`{@U .G @*TdJ2ۭҹ<yw} JPw7]Ja+0L j4mjzM |wVvV.h=R1f;TSk@ x̚&%x?ѯ: h2?e>=@?wM)= GC~(<ςGBXUh5 }.%8IO '>,lҪy'q { *}<>{: A0 . J �HeK J4N`.AK ޟq|d^raX8b:Dsq`HGhRZɶCj{O g\ cz$@`$4Ol~bt<D4X"R.zA ez.9?V::tl�CqؓH Pa6O A jG J=gJ,Á.'H�%8I}u5?|y|>XcAv<=`M2Pbo?Vs?Ee7>^> 8A]F(~XK_SEaF91N`"Qn\?`QJH;% Me_ 5 u_s@ `1o;ɇc·<`3R dž:�INEd%O/4Kz @,>N x|m|h+r^ƛD1 `#shD]ry. P#(9H6 f2Jʲ [[#a|E  xVwg}W] "ntacAZIvMS#f yiS'\k Ybn`nEvF` =I!)N s]wev;3M u6\7: Uw1sٵ4,sDSWs>Jqu7v{y\bX֕߾ ]XLmn=f%>.H<Ax`muYBo[z㛅DehXUS:m;FU<W!.~8 Ew~c9EW̮.q]Pu_ n:]/ޭ+\yD>A02^"4X\e_=.E@^^$-_$T"SSIxNZqA Ee}WRcR{ xbD{6?nO.>C:M46K&Z\ct8?N"=F~1',M6_#�qL5*;/ /%%fQS 4)ܒd ?G|4)s'wKdWyhi<!CK<IB$#̭LAO! G ͖ySya~+9,}+,**r1D!}p\y74O  w@Qֲ!,ŻO^'6 opb0).}8c\nU�gh~ qχfz xy( f"E['�A՗;hz#S�D;g%߆p@$ryux#j!jBos�r)@0[1$¿o|71GT h<%"1(IPЙ A xTD́Mtl�(M(<#(rrK%'P\8JPwAM Y@1eAЈYx<pejSOX"</H\dFW7Iq!J!AXfԒ<J(,GVIWF!h4j(TAP@.Ԏo}T6p=Ŏ|`gIP'r8[YOӓU�uBf*\#{+^_LzQp&͘cm9ǒi3up*gBWDeb`�\%Tԫuohi6GY@pR�A</sCiû<$@d�}/|Rj�|c˲iX; o)<M x%0+.J rH?I<s'(HB?xb^":L9M2iq$WC.}RK@KxKΑ2٧?i}['Z%\B*Mx!|H,. OH!oJ�`$ ɶ^"|@$߁ W�YC@@Y:ws@0LS"Iy, K)k@@\-RF7 1HU8`�!A̵Q Qxߤ �)A ?ɍA SM1bMy`Jk|;{8 %'y5)ݭC8*L Fxc{og~)ulKywlÆc=h ! ys"f6CMb45=mjy@iw ImI )ApAJ'&x%U�ъ}h9b ޖ^MҦ 6ax  *ľ�*@!Ҝ�%# Oi j,5ɦ;Ҕ܀ )GHa)VQd J ^S"c,tAPE)@0 #ԉRݢyVNOV<IPp%" X6ʩAH5eb  BA@0;z`Hsײ%sd�"*)g1ظGlRWqpw*n?Op{LQ, nQSn\�@ֿDQ^ׁ=^ p? BF ʓZTh>0 6>8{pe.R;�% 0\ 0 ,k;@(x[r." qE "oP&Eg=6uҼ=si1;P4Clez4N$ ZaY jB ˘'eE(�(Ix 4i1o$= T,Iw%RtK?X\yLBP Z\wmϢц i�VsrH Ýo!]E34X#B P!~͌#;-};OAusc'0�q<΅OhH@aVWBoۯgby}}.�i5Qw!M7/8 bq :E[RNF17:-оNo ;k@&|mՋq]} `Ot4]K|mnI=tvQx\'hwzuu]  avs&v-m1%QB9=IO #~VHW }nq>SaQNN6CǩCwxu4m~WS=}�"kKʠ<tC+Ew[}Wjn v#Hj?DMK!X8hiIm"&ix@_Zm:`<)i)OTy%T$%-X\AP7KrTT|;@`8et:J\Y*^ (ͅ%?ޢv}>.)OkP ;s�A&!A`poCe6 Z�[E#"s1K`ʧ5I61N(AW3 �X?P*eZ4F~騝<* ~AP)4'�K&!ϟ\fo WfF w710OT>*PTei˅X+7Cyԏ)~p%I̺ @\N@4kf`zcqc1rfܦy$2S:�EdӴpL%KrbKi~TN1C @[eHQШ\=W&7]V<cTG!LP T rDLT#PA4'eU&1 29K'C .H25N ҉A 0A> 9xK+ =JRz K]( pҵq݀1vᙦ q²+|E0e$1M?N K4* 34@6 G2g)% s$eDD^wP1N2*3!ʧ\QDWYXNS гeR%4 h)&ђL|AQi(3VzAp <l,ä Pg*86@*9W%3C[}F$i-ҩ,8vG)`ȑ($~[؄Y_sYVsaFp4,QP [ Gatlc@keZkq+# %`$@ sw)eԶA7wl7B́碛޸54 H J@QyHiy4E -@~(`cBN(AY P@X_ 2o46](eȉ x^R"'0HnY b-11lR.h.+VjVD<=dEZZd0mP{2< c o+O`RN!XCx;yh˸yLJ+_%Iy�@ISS>(.7N"7b#sP0B& 8A EYkfvc<.`q3ؽwc,b\zfcHmB 6ML֕6FS 8tIm @w3m<u]WVh6z΃!8NgA:GS2ޤ mAALAɳ> EIq,jց0%ròxfi4{*SK*@}7l~>F38kwh=z(7<ﺛ!iܫFl@]'{qv '}Ѷg[!#qO_Q9K6ombďMFc%cJ$x&Љək>q4\I2 ߉O[񖨩:3p(P <A+i� N`Y-2w@\VkD;d<6O2&%cg3`,"nki5Ei&YzQ:l�AAIqT^A`<\ "z^c=ۊc"@Rhbb jmp2(!S2tv]>WkA/'r\r" =/Š?By P5-Ad-, ,|ay/5T$IV|k]A` * hv�mGZqk� ;76+Ba1{_+Y+'*TeZ\+$Dѷt`k{5b?jƦԒ@IQ D)[z.r>ۤ&S8\M 7gMD7%zk_%'Qrc Ra+D^CR 20]MQrix$ЀsRqg'@9"@E ƔK)zId2LC$;|l/Lf6[bk0e3i,ź Я Wj52C͖VMYSKcUy �_j)Ô@dGPH# 0&1sĸ!H2G) y"?( L�Bӏ@P&+& b21ҧ3dU 4I g'o N`\Oip ؚ0/XgFfg `> �nwh JK".X[lR#ވy^J_1yݤG,ӽK_9> hi>KDi U�(%4_H @1:7 p S(%8zj爤 (ں $q1 qIw_ Fż8Ns)3B+fprB3s@`7t> @P_zv%`˺DCy~p�l-bH (x+^cO�A g\i2#)AABǧ� 3P0IJ>ǗL&( @YpI`5ǡQP bj#)� P!z2%ery hbâ+ cd̨tpB2Uez.'ms@`J?cXSoJSD!`g�̫Ow*QMv�CzJ<g&Oմ�*G$R=J>I "S@ $lC 6z2֑<bUsln6> "Sc0')A`# RSL>G2)VOB0a@+hB.;3 KG�%T#9攡k1�(A&Q8_+% 9=LwA`ب@Z]WȈq1 ̱VsX7'Bq3^Ck @[\|@q"la4N 2rf*&èDsp( �OpA3t\L*I8$ o'@ wN$S 8` �QA9 hNZA%f~JpKH &''3 EA VA1>ɅŅYpYB$k@89 J0  }-M`rA0C<,Y QwaK y*$wP1GnLꓺmPlMwu%MFecM)[_�<jCAᯜxCTm`%SB;O0ɿn=jivfd}Aԁ7P ]DA 0̍1H;0Os`@�x^ ;8'z\u‹5'ʎCTQvY9 SQWpoԠ,E?TM=|Bȭ[~9A `SܴLļ^Hb`}?S -t �9ͅz}Љ."b+ za\M\(Ôy7b8*�5%1#?cuͻ.Dc+;لԟ'U=Ŋξgs"Z%g33Ӛ%@z0ݻqz< '4qƠtL3O;4SqF F ݡ58- ;@T9);еܚ㾝N_d5%;i$6xw4 "ˉBٚL/;�$nzԈpZ_+|EW>'<hG'c}}$Jy@8J&P~Dɭx+hNH\OZo}9ZYy_ʭniuc (Q)- nU[ʯY(~`i z  xtv?>`[gzy}Ż бi#7r|ģ?x/]Z2P ƬvkS֋Ɣf2d&2A a:ݺ:<;eMzPSx'܎1A!)jfHb;BHXԑ+#ypy`x}fS3oh kx $3XxVex&gXyM 6,_{y-;B郴fD-}D,z�==C /�BSx/ޝkgտtKvwU_<zuww_?u[zBޫ}W'Z<8ș= sWytdeځ-(Ix,F$ O`?ldG#e+{ž\( ٓ2lz{!<|=~xMx%/\i9�ya^ JJ!|xpvbO= G=[92P߁@~m'PϜ'o~S?{r/З/О4iTT~*MgO?ͪz04 F}vt_ߞg~,c*iz/Mu-@@>XQ<gt>BV H< 3GWчWFO&lSd;_Ηxyp :Ck;_܉_Tq��8[aQ )@0d#wFG*wF<'K/=WX=]7|;u[Jw9sP\WLOKw}ṣW$J[r\站~J$ �pϯ#GF_R�gNc# vNd_ѳP|w%^M<iyء'� `>XUY5L,1(\lQ _~&|:YL;> xAQGQ88_O�';-A<b Jɏ\W <9_|7?Ň.UeA G&R2RA;a#%0O3+@ 7K'cVOg3@)A`҂M�D" 2Q{ ` ,6H tA �%xD `pGki5'`վ*pGI"/*vm,~Qm;<�= " tx'B`8z)QlH#= x#;�� <�R)` 94h/]W' h&jbfr_8%>ykKҾ![Ub]]2 VLJ�ѭd{讣xa+0|tX~ke~hÇ0.-~5H6E Ţp4 ^@0` W�75l pA t?�@F^S;= ~@��~q+6 0;�(^FGB<S\{@6I�!'�N@pbOJ[*ۭpu<k?/v'/)RZƟVi񻟬^Z"Nlof‘ofp#P6bkq]h�^ 0F2@A<I lh| ㌯wp7WٻbJg9=U8>=9Lz:/%6%ccwK;m" LJn:5񡃻n>8L6[~ >A@Ľa`u}n}e(4NC@�tM,z-x  OAA 2j� ,bኮ`FtqFtx{]v!?ͬwඁ K.5f�aS'J(AkwI"224dG#£W 쿤@`*hlP@tț#ݰq3/w, vj*vy9AM g3b 6{fxME<.'蟕 s] axo[7?ZG:lR -86ѽcᎉ;/]_ l p +#'>xҏJSYyb,p!"s>O\kib)x|K L9<;rʔofϣWBg^:ʡxʮ\#ܛQrԎ |#ὼǠqx'|3}q|_hҌaT9O@&s_|A"{|=k]M )_Y3]JA^Pyx _S|=[>ѨE `Ç>msRA,(O@p{)҄Xȏ("Gdԣ<o?1:\Ѐ+pLk/8¯Al6@Lz*8.q,pAbwreF 7I KjrzrHXQ*E&Y�GT/z x@֑Hfo_7mE{\ӹ!fxtXheTt1IdM"`_B,^X<_ S1wsǴZ3OgiA]ߖzϚ4n)Zq=֛i_~?| [tSTVq҅|VuRa,Iib8A_Kp  5¾> m𾨵&]+ѳt@@ su_ opL%hhG,*( jat}>5yGfw?V 'yq((ÌkF`@ T Sp:-+E2cP+k@| hB@_4y/swjy*I7@Qn <GdW5=p( ^PH %#5ȕX)b(dH+kpl؊|@ĈH&i 2ops޽ `sjEUmT�x-9WX>+@1Sf=N x�q#YR-@HB J O x j/WATaAk@4yE:zHYYI!@p@Ĺ\ nDnͭ6N^̪@LMw&j  ' X QE` ҬEnf,�> VAHl%JA]v @D kڴ+Uo'J{bw>H׊Hy67Czs\ޖ4vrXS" \/tyJ<-w~nO>^-=mET:%5u!ܫղej*^iPm䗵cu]]G)~"#JJkJ_?)y4g'LU[AGc-=ƏN=f0{M\YkLL4� �?! [!ĝ8!@4[D} }dfX7@sໍRsU|zIjPdžAؕJkt{`6b7+_NP`T~',:̤WP.0E)}8:~{:CCWIo_ݿ?p$sXAYo|g-[#EN0Ab7`U(ZV|qGar3Gpp}|z"p&̌O')p iP*]$.3 C.5 [F |phԻeFHKڪZ{~v㽞Zַ]\-"(ҟ}Z2־\&@0V X~?Z.δBuvugr&^T~xe.,:اRx7D 0|,iUMUA|pQOo BeO|Y!Tc[QwT`"LM�_]]/bQqgE[m>bagi( oPΰeJ//_,nR] cZYqzd1lQlN1޸r"xˡ'-CF5]Y~ypB1@fU}|~nF?nu*D,+؎ ^DNQK2ub!oW?J[:40\2@ׄ>@еRR,N[APxy-W,MOz P oAL祟 ROk)0G$wt[`cs s{[���IDATc`^[ :3Ͽ9oWEٛuӷi/T!!)6x#`'W:c4D~f+ QhسKZjkYa/R7!G$፹zYۑxaB |i�2kstzQEZwjX}T:YJ~OsYz6jwmq;%X%d_;许lXNwJ .}S7P=6/0J<jҐoW"Eu¿|ST* S γb(AAs8"O: ILAzm׮}>ؼe5t~M(@<>hA#7./x}1Th#?.! :0 G׫',eT߾᠕i[Cf qjf"lGW|\ "Xv+U3[l^GN<VCt5GEIͺOnRI XdUbW6+W5?Le@[i )}_#JBEޯK}E󔆓/_VS 8'%JxYd_?cfx$cA>�lWA|!w<Y>-OiOӨZ{#7ul%(䂹 F;!A4?;1}fQ]h@dOPP' -瘿f>L|>%~52~YkVN(NziY=GgX&>dT9cev-ҕʆ@8IΨ#\W75hњ+d7癤: OtꤲF<Bm٧cqVE r9jLG|!j3mX LA{^>S;{ �yJYNJ4CTZQY3(AlgTB;g@33:~a_dH?cgnm2,`@ph+_.RgCX)9Fzp�Kݮsd[,w֙ytP#heCԽ1$mhuY|.hyۅELt9$�A05kmNЕfim([*`vyAdĥF}c:~j }gasz/VWοIt7#$S?5/ PEN^{C/r&<<B$'dԈ'9=V'<Ew)Azkq g5_XJ(: xj641)^-DU@&hI_5DDG ]6k,I\[(H0D'xl߾j>;}-OiGD4X#9UDW3Fj^3D>UV߉~kFߩ@& :S-  dwF T55bsJ\NfYD[( I�AǦe׆L`˗~ xy@pۯ%bS^,6uyv;{tm摯W ʽ;Nˣ,GPgrB:z~ fUskGڿs+gZJ&f �cZ,V$@~ 4,{VB &6]/ၷ1<! ™u^K)�Ah(u:diòHڛ_d]`ÎdM|TfoG+I s@傎̅nO":Qb.rqG|͆J6Y} w2U _E ^_~$5KA]c-5%Q[Ns5_S4RF*3&`A a@ӻI?yd5OgbLᑛ!@ fKܳ#}4X>lk)[-MhYmzH# xrw�BB)V<̩Gv>SH*SŔv Gk,>nW(K}J�* C.@Ќ'+6jXJ Fʣ2M-d<޴kڷXXP nw#9-vΰPhcR]&J-og:D?CB@ NJ� R堜b7&CFԡ7S{"JLƕ]ywvކpD `-h % -(�AKb@$OY絇_{~~gjAD}" 첰tqkU "~v`j+@qmW֮aՊEN0�&0I.FtG V OŊD|Է_ D)94m|`ws 觞�5g\LJ&O-wϋI-QIy"p`28\ >kE�e7# GJd(q3[d0w`8ӷ陑tГ " Z4RQ 0%ha1BĚYL<CkјjL%ښŰX s:IT\lE|!#HJHJZ$)-<` N k5 jxX?,~]xr,$1ц^l@`;PXxHl"@k~ls*�z@@&wz.mi I,s(ǞBM@|'D&|)_u~S&$j3X<%~Ƙr|</R`D++8"GG*a)^#?yvyRzpvQ+U9k$>_D.}[\,uQ#~)r~Qmj"Z9s>u&BzU pH3Yw0H7_TЮԭœeߎJ17vBo:'VB�v8U::�6szE3.@\8@\ +i.bo?Z~HD(/lAĊ*=H f1%*i1S=KT15=}AGsHD @j>txhH6Gj+iF^ hFV|ȉ"Wp;zv+[N_v; Z@3x+ Ih@LN_975U[?W\8[@4#aY>&>Gӹ)#5^],j57HOO컁 pL% gp # ׸RխT :q.u/oUchGwCw~ksOtwFk[w~귮j&* ӵ4&=|4f$R h�Dt>U6z9+06lɩIڕf\On6r157885}jvD`f%,_Qv,+62J2>{jbNbV_Z808B)U V΃ZV)ր�Hka|W´t|iG'3s\>䷴>g@AB"`58LpzT%|gD !89J/>3(+BXG%UE;=H 5 Mjol ĖT9`Bl\㳓;'>w8�0{cL& �ӽrwV C8J^B (C �o( \!9�qS-(ŚDp+Aؓj;5mqZ^õc-^tC"<ڍ5_x l$ 'HXE͛oKZm?bX -]:W5 H.$+g:Z(_ .y֡ŏb 65j2 \Hvp B =(F#Kf͈@郀d@`r%W'{) �,@矙FzľvtՎ$cFn-T3.Hf:!Y,ED Hd⊉ˤHjB[zD\%N9eMVTa*NN?g0TDL0`3N |ZbHTb*ʶa[>p[O3XumX61:EqkBohz62ndtྑED栋q (g>H~$phi"j5D^(^z6e\[sI:7r~lf_MM 7o9pe}l/'K?}w~9HB \0)@FH -�uB?�O&Gok7#7p^`#AiyuH`$8Ie$h&B *)'Ylmpі}oɇs1Vp*8ن�Il2!80Ѵx ˵RVꃀNs@hkA�j�vc kl5l Z&e;w"Nt$j G|D =r<<Z`dIQlA "5H@s lmq%[a{@xai~5fhݖhSǴ8@@I_ElFd*X]r-c?+6h7`20s!*#0@p;z󖛷h|�|  ᅑ|(^ :H@F'Bu¡5*9Qj~n%д+8kJ1Ŗpng:/^/ryNIb މF;Mt>@DCv-ڎ%RRL4X\[ z# L̍.@GK<y((aEсk?|JsNI[l^)G \K Wo\ JpaE �E kO :BA;ڍ&�r�A�hn (Ll͠` _f D@B }J #pM0@[%,i6ao$J cVn^ Vb}J`l&2u)A6zCwD@ h% o S X=cͬO 8'qtb|,=~{A-3w˥t0# oG}@i/^]- o?ި27 |M>Vn%L/2BZ�t  $d7ï7 @I0Icv@��5};dDְL@OKRF{2B.-jb*SlL N''X_&0u]Դz] fw^nvL�( F3֗ xE*l,Hͼo.0GcCwvrlfasJ ځB;(C*;ה3ځ,B13ln2<YvpWvpnґ}JAl|XDm* _\L `":JyځqO9čxZpX; P[A% @ Rvdt$&# HL_;X,dd--<@ȍzY:]@}Jb\Ťpxy6 N˾3>N*�v)J{~P(^xᲗ^gNp'&NGN+㾝P'nߔr2:e)cD}%z!@㇝� On3Bg,|r`jnF ^޳@=砝 'ϲR ΅ey"Lߐ9;> 򕭂Cق'WᶤUkbJY#.z (m`'`5zAA!'[eZՒ-Dҙ>C>N a* �î(Vmxؗ}a~jŰ fbVb(Dk_TFJ��3S)u v!ðwx|b86C޼֌c8 nN"E@L(`A p,`}QmA_E$ȐxG978oS±2;ՆX kУPdJQj\mp�K߰ e㹃vtlj!jsPUS8f QuFNvy o,>6Gݤl=L6ILzR~%Pv)cQ%<h,J܁o6Eˣjo=jޱ<j`԰ "Z^bED/~Q,b'ڟELJC &fy`l oqxE)Co6~oP\�^fs6tA擟nӶOA)_vky_?,M_In?ٍA`2xAn~s#>ShU&mf?ir'q|S=ᓑW{dߋO}+E'{^nݼ ?O ~¥'e'\~ 巿A?~Tۺ`h!R l/]>C OO-|x4{<^zn|<{+GP־ G *C{5#e&j ;Pjo).%4 {Ż%}�׼ / zZ=֚ߪo?ޛx _7rE':GX?kt{Uy#Vw!;t=0l�E0/˴,wzY,"mse-aAj+TP*rJ7gޫރ.B۵:Z.]bjGJLNᖺ$]R TdktA8Ěr{*O :sF' óX`lDiX*09Pf �?T [NI >vPu3cevVꙺW{!NױDJB16JގwFMq-na:lrd?"XWٟ@e/~uUj'wGߪ- �@ϗ ѥ]T} bֹMOxPFjф�]+n\Ih]ێ%,`H{;ul$6kg%8jlP6\ߑ\ pP@!oNaUV\ZaQD+hʑź,s ~k] 1JLBV%-FVJ̝j!Zǃ�m;]'ahni*8bnή߈ʀWv;ueM[E65Q9"[Zxy`q*ehDr\pH=6zkgZ s!TL3,ƧU~w̸UZe}52ձh{X-9,FζQ\IׅG ˎo w&,)@З T`rqeu}z Tx@P@;e <aF4k#"  Ɔ\׭FOi[$.mZxWhr4arݩml{ALuw}wÝ/L<S leE4HFdՒ$g A~55X+oh]J6 v01 ?;%e"#T05Y7\VHz0@bL%/E9")hp0RŻE-uV@# _yBըs-9I>qxuKHgENU Nr DEzc{E4D}fkikKrað,w# VZ*EHG6([  �A%��{%`qz!\9r^ܴ%�.d8��tWa`dEn=/ZEhz<J ξv`9} S(GтAJ0)Ajѡ2i-5$4| <,ߖa֨O ԚtVN\]b8|+v]q0 + qeSUZ*XS%e?S/:rf lMk%2H ]VZV`"ȔXW&8gx%$C: 6,ȳf/[3}TdD v Ake-xR4҈l=#S"Ց*`3 �Ũ/NSҭBlxO}�Z0(:*azu(e5+Jۆ@VJ%k1R%P xlsy@?y% 2 %02 HM;�S"d3 6\ٶvP7L,BkHjKw�wG ?Jnt4jKW,`=` R�4 cA'�*A](GeuGL:hF\YLP" mLIZ~?) ԅ@�+Fs) Ȑ4 XG<E &Lq}ywJ"Tqܻ[Z᷈q:ZM (8M.TB !B8<�@kB7$D#|�2؂�b:@dIAjdĎ0WUk1Y^X&R]MAXNl �!)YJR@ދ{U兌EFA57jB6CP7 )Ǖ@Ȓv[ve8и2ǁ�z+o'vPuh; 8l²[bX; zI}:ouGg)pׂ em)v]ą@ÞR:0`6v0{` 2JwQ`#vzOz#>9"ٸ9 ;�EK.zve]&9'l(6 WUeNAPb;Ab ZD"#ځ[.l&'/Gh!ä0[y&B~#[\f_pf^~6~X ׁ>Uujl3jQw2 UTt*.Xݍ'cs;o]J{@?h0@pےy߆hzud-53"mbO<O֏V4:~b@*Wþp5qx7j*GJl?@٧m);Jy�JJ>(f·=@Y X?,59һzk Mʄ}!Mr:UϟUy: -E?֌|A|OgD52uՖp9&o`hf]/\n{7*Zڧ偑2Yʰhg{^㠛M߭5UJ8eGb[9Pw~$3"+>nB]m'8J8*;Lp|W/6,D>Bڦo/`�E" UeOtEWWS -o>XowO53[qo%(Br>�V[ư߈Ў-RNcy>KL w2]•g%AP Vq)IC5:χKKN۵lێ}˰\�%/ -JJq04a6v-|k~@@7<Vwr:  ?{%l[Y;(EAm ǎ *�v22,jY -j{+t>}ewN] ݛ^i@B튮g,VZ?4l Rf0>VexT Xf 5&Zd2LPYD3x"#F�!pݎQ@%k}h|vUۊ*P^M 𺣷q| x`Zϐ@ HK#pQ[+~`:Rt.>[hVP.2عx@�T�2xZ=}A(<40S-3N0J  4ta5<3ԴZAGAWAvJ +ˮX =@`rZ۬cNJ{c0^Y�jCg5 qa@R""-?L j^lR~/49yaa#Rcz/vx7H߱PMEnI;wrumU/0S1hwįkݫ;cԽh@`@P̅Swz (xs }~w^\JP@@e]K ?ɓI  b[ ?9{.ݰW0qY4ˋIYN�ԗG@P4 ;�]5&~Sbt6\A| BO +�ǧR�T�賘)9-4Pk� 3y)j@, jPAJUoޠLˎ\@0IQ,m+㮶l�7@ N P@2%蕀p2]JLCD;||\(*?o`vH>A F;FxC8S & Rf StK>%}{ڠ6P2�vPa;( Y&8#V ddl0$OᾇœҜs%Iɔl1lL C 8+Ը/ೃ:2(Ӷ=O=gTs`'z u�Z]gy fR vj2aw Nl,FN/ϐE�ZР{ J�1D<oZ|E/`st�,eO&wE}JR`ћFH_&14nw|w UľvCv&e;(oP&8I_7|s]LCg΍asMu>ܕ'%�EL�+$W`ؑFtX:E;؆cB,2ePAzSȿ+N5>`y/r$Cd5>28PO&I$dY׀@ loTeFυ%OE,{v4'^pkZ<.*eWPRImd 峆 |Jp)(Aߊ!{v#-,̽*"�ц�<O Rf=ju[w| (9[7jаvN ֐( vFߥ,+a[kGa$]8[(VƢEvkv%wg!'ȡnlyTo#Jx%^&q\F�셰E/bxS- XG"y3ݧGSHz?`xl̚kDb@Ee_Cg(�yL6UAP@ 6;(p07 ;h$ߕp['ZZhww?u5"P)ؽ $C"/ֻy3nϫWS5<7'S :>^<J{ Xz w?|b(uO 5Õ^mϛ@6ﻢ o,,SG[W~]@On\xS6u%cw+M.guĆyZ2Vo7G9v, }Pk]Xڻk5;d9<v˱[ mj;%,CBm`by}vtDZ.=U' s+yA ja/Zoxq޸Px pIE d;b]S|?% 4  Rh)?~GA#uZlFThmzjoN};qHa"5lR=]^* ƕt j᭮v`IWUENȷ"Xp1trlF46٢ b<0WJ0t ӌ! Wg!OPho1h(ZG[T%0:^~~sמ{4 @)[B( D]^LR0yu0y7m4GFˆ$z˞D{H*V+b 4nq{ 5GgW^zPfLMK*ʊ%[Nh"ݶK\aa.Bv{o>(c<vyGZC{y S+ܔ]fv` ۱X͈ P@j&FNhkP1Si.{Pؖ=\ThrٵN DZAThFsc.yɅnMeKzb))cUhPTBO!L(cAЎ8*"+A0IX>*dͪkn%Z{SG\#Ԉ jOh辂-m+:;jG5#`R ༀ`[vQǨ70%@ bĺ8"QBpq1Wmȅ)919tYg"eɇԢX-,`Fq5䪉̏|o]r^bu5.V'h=9\>F&} hږHN(LdZ�tN@w*JxaUjYgֱl$$T&,@�J).}v�TA%$Jjw 7ߧͰ-8dH 3؃ xY/Yt-tkw)VrYٍ Fļ4QJPTO?uV>,^D*lQzTE ښ c�遀*↭LP%m8>HNUˊ֪aW\:/D5Z-l łSE,sr$rfؑi[XEZIE[.ն}H Hu- 76v.DቹJAՖ}Jfke N(5Nd"P#Pe uEm9>%?V6�A'�##U &G&B22qidb 0bIX 'ˇ@mH/DHe ^߻"<7uY; <e9O@eޢh4,J'E ؅h@0%qDx$A0Drz ̠-z`e쎡~@0gGM1&#C2ɫFhd ]_*u4]_XgJiJg<J8=2 xqvQL <]Vhn ;(fsA,<&rO2SO @e^ L :qKG-i1@@ :@0H T@ O }qG)@AJ@�h<z>CD EfȎt'P%�� A)+XYXk"3�aO=LƛR1ܨԐa@++ѯluJ@DA<$c�n+f`�,| �PPjI PŮ"ƾAG �$/*%zŋ jU[Y NLZXȊ峃#OA  ݾ@ dc;p49.۲AׄL M rP&s\,u\Xu$_FZxAT"v\ \Г \�u�K��tlp(T€D`@ 0SRVfvo8؃t@jk !TBS 08m !@.vP@XXMn�?O TT@H@s/N;RHAځ,"�Iژqͺ* bkN�/VKa"ng)@�,V^PBmKi"@`y L|T){XpET4'$ڞ B !0˰\tLP!Q# ѿ5n[O $g}D;rL07r!b3 LvcveLƔVV`O6=v l;E3S9  <C붘/ᯨ-P7$Qgno@E�lg S@>/,AЎqS% *Ħy`)0;$p2]- jX^:QzV:^+�PPQkt< r5h+mlLh, #Pk%J u5퀮JAkކL0@ x4(}AP\б0 V;hQA�vpCePþCXgbX$i>7~n|p� Iw~ΏaE{y2A;1ԞB*.=jf:0QT7Py � C F0)ANЎku<,xJn3ؕTCb T+wыwm]a08d&(TDL7S@*G6%wd1TDD6i {谋;d0 psģYBF:Y4^8Fp_BYMވ"v@Td0ƥ^rD~uSY߇A�<k}&c|nGIr NEBXhfyg3%U- l!xD ~ "E耪S'cFg[s&A H=33@@@5׍A •3";䑳1xӧo]5{Z=C}TQ4ƹSe EO mwnH>XP�OjQz𶾅o�{_'MJ݈\&%/ k8fg:,g(~x ~\7dkmK^-X{-#x1S{j cx 0.aOEcZoڻ}Ś;xu<ZFCT~<Q:E<ڀ<Jd34+ &fx^n3&YcߦE´(T%<E$u9؂ten8K/ho~cYt�&NC>+.Kd/"=#^kp)& ;j=KO1sގ:-xǻR[^9聀>Hs۱~Yy* IcYt$']wA\wqEv:%AWde?AG铩뱒^1zk}8 W^\SL 8}/ qWklkֽwoj Yd-k�s9"Jz۸[U >L YYj|# @pXcL X`$#AĭFZ' .5' to$4ҧ4h,Ci蜣t Q< Dt,Ehe @p7=t0]E0yu?G h3tr fX]`q\hK<t'6E^MG_C;L;ػAu3{h т1Bx�c yzI^zmbp$ Uo/NRWjN f?e \�zuzPWD 8dR}9?q2h 6ɥ9m,Z9=)٣4MYCi=,.a5gLiLfKE<EM@z ʯ3=͢&@f<X6?+dn:F =t"|s^(\P$*P x+%yZ^Vw}i6 w_G &1۽ z}9\-}u3^tQdž?FFM Ru.p;+ti>M,>&+" xB^+?AtW###:;44{{ ^{FQ1x(qp'd 37q4xY&p[LuܜYM_1 шK\`&͍]UN>=B0@NSLѱIs)IK|L[E0ڧ+V/S :a�`vj P˃A"pdj~L U`t";c$Iى2ҥwRQ�{S�IS_G_ *SK*JM({$S)4 "yye@6 {X>$tg8}J09�<~@0#s`%yg8476kt_} r4ƜCwD(aV�cT ZM<X')< en&iT7k@f&dٟU} '[^o�9 `Gv4WFh؁ f`/ttSEi�9َ*)2ȊH2٣1M{@F^��BI>-{NwEH`e㪯rg(5o2<�y ({lD Х~Ae1ޜ{c s \_5*>.&nl�qٓ pX{vA(A,ǩc&s>~JƢ#nw `NKx5T _DH\u ;2O8EK|>Ufxd=~= ylY(XLݿ,/1@ >f~ =Y\i|2h0*E02{`:hR<vP v Y9@#βx@�5Qg2G͑`m驈DS"""Bt9_ֻ>.<f'8ӗ uf@ M mn>`H{ZunԨ1>�DKuK“ZCnsAdPğPA,XU].u& ۤϠ\ 񃂡} *pQ&8l@͂Wc> jw +-1#ąEX`j l,cG\>ɹ)ן~NP[,@E\dQPj~A9:)*P~$K�%y|2̤Tt=4kATD?>F4  "*,]>&(Z`J ^?Ok@0IcyʑLFu{  "@8 O8pU|<;{6uox{JxW/1s @ g{a. <5}3fyPXzMY0z~5nx'ޗ?F^#s+Ӫ\ƶ.fC=�c- ;]m?J^wt5,->G1Ԧ,k̖:bTqoUٮsksض.| �$;í`)pY{6|*ނ֏Br$^ jo+'4/"J5*;:X*=5GJ8ム|AIl{"�`͟*rML#lM|/,)xU퐊iwץΙh*5ε*\8Dw|Bõ]FY,M;4}W˱[>]hnZWD:uw|AZ"`́sRyiF}W` �"ظ?89enhUNDst5T;  %G:Bz)|woy-4bu13ox}o}Hxܾc1ҧ t~|٣=vP9E <Ͽ.5&9>PJ�,04UXr>Fxl_;,/~0.}2w/ Nr9SOK<[X[\Z@A=QZOQ? ^'rl�2}lW\ׯxc;PM~Y1dA zUIn9&3' Gx*H-TA�8�^L :Aj{�MU/x~Q:ה( YD_JOu0^Mu?Xn5 gG2O{%B3 ׸gbU"nzQth5UWU١EVn`\#^ @`w\@&P$`kE@ V0r�S4O@jZ^P&(˦x>zE1f=gpyXvDIvULP %޶cnﵮht얷oBx.])]ⵚZJ~iFpю'`N ~ߏAT*G(ӡHO"L6[}G0!zWQ{'fuzm~ .kew]ףd^Q�ntDS#5DRΉ~]~[;vWXnEZ&/~S+E2=PWoS[h<oq|+q_Oc*/w0IA /z4k6(~Sl3_5V e{uA[CIy?ܜx: :s0&\6Ͽ9A8LP'I{ PRpi{AV^]^Q`D-{sOGHQKEu<WRD`,AN>0oCB; ס|'׷ob@P\}W v<+F(kc/ huU*]ˎٱ+1 8 Z�r>vZrjGɳU;Ŝ$i̍=9@7)%& _lFt\K<$x7|**~ׯ�K>t~Kq_G,uitRt@L&S]D؁ NAȁƶ><rEhx}Ch!W \ׇ}՛yS 0@}5 x px!n͹K@#Q*㏱ 1p;vИۯTvG^W .Z,JOwN@pwW} 2 @vW#{A~tO-~jiKݮ@ׯ磊x lW@*{?Mr.t pAr�y] `i±[lPymR^ V@@�vgz2(@G PY*7S ة2f#WgηqK8pՈOp-*|q_s^R@ kLVI}D%U>t-A!Ib+٢N;vsyשk�_VS\ڿzmkvk-ԕ!oFﹴEy M1{/waJ-VAx#@ gG#j$*72 Ƃ ,h/$:%kfD5 fmhyʎ;?N;wosXe Y G`A&qD?>ڧ$ogG 8 q!I9QI(`Q70:3x[{hn �@-yo-ШjEٌq35R*SP3gIAE7 28<P$J&;`S} سZAUDJ;$*g[`qgۓ � ve!wނw^E ~5V QiY58~AҧrYU޿#N =_Xt ydMA}H SC yQ '| eV/ +ojB@h{]CQ@TEK޲S潋 V;H]P;[q"q^7@j>Du&?C߫k_]Zsy* [^ `[ ҋ_۞]x@|vQ_}ۏSw ,er٢wkiJz&5j)*dTg-]9 rlf_CȹnD0+w(D`.<e|j&"0ظ [; vs;ڮq�7r^ -m\O }4bRHv9%r @#{dI3,k3 r96wݒ*g7$>y9ox+.uvp5U8즮 PABBͨa[+sn@&e}BpMi6RQ8oDj6'S X8,ra;ʗ.jb6x##[_ @G3X㎑ۊH 9܌cе**eKxy.©lj}OT?Xa!UG,JF`#e ʻ֒~7Ӽދ܃*MBc!fU^E7xG۞QC/^F;t9Ɲ+|TI<mNMIЌX6V:!Irư/dݵ(J  2{0% _OKiYi 켍>;u�"ʅß`y۞$EAb#,3sCs'+8 ?a2%RB[ւP J0$ Uq,SG' ɼ=o_' P=mDu SWI] ay C`DLw,L 4`TQP%!i~zZfe�Sa=?]W0y1դ@`d::y ;`Zf>(Fn0 F]}1A_sKWC}�as$[,t4*N0-{+A2^:>,Sd?ci<I�#! I06@!ԩrEAbxEX&@@qG%C2&j6BTG=cgS l_QdxX[ ,ֺ@=)ٔNlbP8S $EʁU|(2u1! ~c5tCeKj|żI΀�\A&pl/K E4Ir- J@#A%#N!hv#0VRRф2]w }˭Td.1pߣG"e lÒƃ^%v x=DI" P`A�D�rኆ(1b3jD1dOTXdZc7 <n1&B0-@:(f(X 2S c%/twĴ!J^(VO@X`/`qk)A%~(uHX'דT٣G�AEYQ8L& *A @ ar~( 'H,&"(;>L*u9E"ٰWbJv<S8]N)T = _(BXePHatv#5@uFĭg^3+`�:K@L)+M^/h7:))/{CU/;2i# ޿6u$:E0H({2A/)J =Pev~)]u!c:�r; A D~TjYk^�C:^ G�R1[> z #y|񘷒h) @�)ՙs4+A3f3;~p6_ݍ=?'k}P&({:-:@V((EcK?¢͎{Vz \ HE Nsa8V% (Ea3%HS9^1n q^y.l pyu+@@< k`1XSQ*˅@{BfH eTE}&2.X%hxcL�Ƣ%ܪzj AT#;\z�x rǎ q.>*@4%X�`@4kD΍CDɇ Z%c2=Cډ/;kXQ%H@`22{ F.CA.P$a'$:Q>!<+JɅcJb XF F|c7`Aqf:553fR@,%T� pF;~ˎ{?>Op/.O�Kr,rmڴ[D%S ;,2,Xt謓e\ {+ (~hm^Kļ]+Q+YU*9(Qʜ"$n;X;x5S*]H,eJЋO{(G6]� -ݞ cņ G}0L 4>hI4HrP X幃 @��f,7U'�,`j>= Q|}bcD^YEV]@G'vYjC&x21\h @STƪ\ӝO, 1ϳȚ]e7f"@Je'[�EX Û3ު7s[ ;os:wP X0 |yaZYaVҁuo"ݑ&}mDݫڋ縵'X~r p%QB&0w`jz )[s[uI-!ݝmu]@�Ke']^@;p|kۜl&֚~|nWGTL-D9RCXwE?GF&0<70<"4%R,7 QG[cTˎ,ab 6E2- _ [G ?Πb, SL-Z0Cm9]MM! ᪾$Pӥj]&[ѵRDx\S8y͹;7=T *Gt Jyg5qIN'JɁ`ls$]vN2!ct/Z@,eH4T ,4[L4C׃�Gudv3EI Eᬧ崰\U9=a~Ɠ;ܫ F42U WsD0~Ʌ*/p@H̓)TTSD24$ T>폚kQw o[bZj`m&p%H^[um ȸŕDz\rDl}W0_ u1Ew)Pq<L)]e#zT01 6Z3"U ߩ=Z3EJ6ҫ]v- .wtgZ7.Ov;L"a3nnTzԩV!ؤ;K_bpc_N E (dr6F=(,{#Cu)<bbq,1.SSI'٣X"&\ӷܵ["Uh]3*58pmg`ey<bnѦZ:QFȽ:KԿ0\fE #`бL'1.&R\(hdv ÓE{T %"5&3$U uصr_| &&mZ}?s#]͍g5%fjO'~@j0A`W A% uQ#k {A "] `g(XGGSNԙ}Я*KKQ6uhX�XF:Q�@1:4bdƩ󵉀.g&#\Zքm!nM%Zsm 'E+  5 MN;pʮ.=s4D`] C۾pEf ]#K|\P3fl$K x3 V}1؟@qE P ;0o|il:6q@GFfB uD0X0wD} �@@Jis�^ נڸEnt.߽dH h%Y+ hy\(yIg| ˟ &59Q$ąL AwL.@]lc+͐z%D9 @C00@ 4vB&pIPo\!NכܙyzMPW#:@x3r_7%!8 ׮*oH{v'4o*m@S ݘg@@?o�Up*H0Iv#9E]K`u�Եya:!5VtE̐8iXjPW7A+.P84bIkYmfi29L%ȩ-"<5c;w_. RD(baH J u}ƺgDD՘w �ibJ Dӷo2f*larމI"F,9Ǜ%0~ߏ&čq!?ǰuaA`8+@@Q�J]mj%*&E Lzsa3L@aFRٞ`v� J% a66+ !bFM:?>g2t\k HFUҐ2fsVT� qZ`TpiCnXf x>53�)V&8":48x~HR. ̽ް-'!܆K@\ЍAAVꘝ@o@iny$Y"kO-:ՆmW.`7K.K.(v㓞LcO�l`@0 E᳃e P"R:1b$b~(jȶ%UPJW0;k-;&F<5 zseCJx+ݘp&I)�~K@ Z%@X'v<m*D  (VUh+ %�1 mޮJX4ɳAa_O&.mxڐ]Bx&n 2iR#3]�A\+yQ(fޓ;^'bC *@b`za[<a�A.(Y\iq:dyhD ᖅtdAPC 0K�aE5i`t-N( g�@n/!a8vPO_-wkϓ t @zm;L%�(E-J`%H6ïGŸMZ Vg҈%B"ۼ]h ĝJŘmZ% !tR&Æc h..f%uv*D ɬjagњYH]vk>;XO@`y&@W#YցK ( BLƬEy G ( ! yIȲK%C hq`j1t2<.-tG v+ CJ&J!mH\uX|tFE\OtVN,+x =M3XV|`\ ! 퐒I߶ͻ˅9 ʸ CՉJP% i|:11bc#%8@5n1!nNG:rxjyW _;L@`؟]5oi9 p[v>; B%S 0#9@ET l3kਮ ҉ R{K<K$L0; @iI^⋉i8KfU]aJ@1hJ5g qŽ %Xv8:$J`-oQh*urfN_L7IX ښL7\ N$Si~W? И(BP"Hr9UQ3oASic1%8Le[>99-뺙>S5͟BрC0<wx Xul&@�ۆMB 87^l" K#֎[>hv[Xx1 qMXTJ%iYaNV $Z6ITԻn=+-טRXA0@P-X "" PWHUz(µ1+q\Me-A9"kZwJiH'S46=Dh`r,AI'/Ԛr٤?ސ/]W˥;(AnSgS* {/{�}n])|�)_>Ɵge%؉.*Q2K &8ݎIv (4 V-h=`TqCAe-EH 5 \ݒ+UY r1.`@P3Uua,L-B43o)&Me: �)q{:`èTx@hMQy), \#NJϾ)*qSd~+WʸAb衪Zl"@5_jԗSNy/(իμzyoi=>*սnY(/�E2j= ϗ2_g`}`П7yd<E]YRCEAL˂jIe]TC KJs*:+":A$00uCs!N)_m ٖť* !E1T$*+ṧT]~٭VgWk6JݾК<;Iøq:VBV]rl\*aёHvX$fY5_ŴUi12*䫘^Q<`݈nѾo+ѳr@5 0?fjjளR^Z2j30hMϦ@&_:=]5%b5a\AkU7Y33H"sL'lE(LJ`+}1@Ȧ')OGC4&Spa쁠?"2Zx8u4!eۂ$o v ]4ЌcZD-:ӭ%dZBADEZQ=0M%b D�W+A/'u /` ֢.$?PdxJ4i0'ZZ\-jFx/MV^` y⫮)(!qwvU:Fd-bmvj2kʪ DpfMlf>DJ )A3~mcDM྾v0^tT_VE,ԱRv(<h�~s+ d{C9�hG Gnٯl./p>~{>z&kw{:_t60Z= =Er"ء G)H]#pRjDL0nvvS9Gr<W7EQ98wՋWeuQ7`+oBsbϨ3:h\)Mٶ;Z;:6eJ{nk�yh ?]UρS\}X$9sLFs1c+IOѻSB޺aϖX@r9`p tF]zA쁠e` ST6xq٫.! pU#-vMu@@Yo6 Rj;Ҿ/sCst u4W+Q#Ԛ  &-XF =w5 �hQ7FH۲U9u3xfEq"f @<^M�^l oJJh�$R�7)wN z%6\ L*t՜o;ڮԚq^ ϻ,Q㥡ݐ7D[kǻ F(/^]n@Ѝ̳<UVBRlU p@նUyzR@I#q-$SP7SXhA 0Յ+(Z Gm1]W1%8@By NՃ{ S4CUn(A/6 |l ӾtXQm(v@ �X4;> A^ǵCWC;X!}j0vuy#w`qJ(d!6DH74[ `⭰=z|`>Lȩ`]<.\0Zy'''XrB]gF;E"9*0s�rf08^ gʙ?^?dB :D?0>Ũ�D�{/2p<8i|t{@еz W p5C�!ؙRBa, jn!jsf8Rۉ06uIݼ7i_ p6|6pJJ`% &Ij.B~Z̎IO�PrAu[:gu܇A.C'v9˥%[\m�2WG ,ۢہ6"V9 %}} sNZ`v Tj 6r)"{AW@҅rֵA;%~{G;wx@|- rq쀭 ͥt0%H5vZϷw[g 2hN&-7杤){Ewm)ܯ,;]G[+ħVAzFEvƫUW\�965_ M- pHO!5y d k x .9Ĝp@�<g~O˙v(`vɢ h;>*5  *vf+ kr;Zz7*ACY@FmCQ~7C;G= B2#̏A:!%A�q'kATm!(=F~#¬GN;-G$<.p^8)eI&Xn:=LT'5ĐnTFW;q.4sZ7ECŻ&OQ+"k-Ws c@@E`ڼ,_;B,A sy}.l�CRژx2 ;r| %K0V8b�;9jz!i@@\67AJо}  Zd N0*p)gP]VbbGt) mWi_vܺ9jθTrY]bUm3Ǧkv-AS0X|'~WxZ6"qU P ZsI&jS,XᰳTm`!`5CUnApҮuKs֗ ˑ^iCŃ qГ I ^Չ,gD7JJa4hQ'J2Q[cU6,')*w @@ث[eL&*nR,dlG\"`] mH/S9-` (re?PX@kI=f၀f XvCv`GaV慎|1#�߽+염DJݞjk/z|ҽ ꖵ TՃݫ;V@�"czQ]>5Avg3F9Z83 05%FBe-` զX:5LWw bu3xLd 4%Z &5+M9NSVsE _$PXtu-vD5=KͲԠk#ڊ}�,8B(g'PGlBY 2/杖γRI@(4bWc;3ĔW$7fQv\[xJVꁀ*�eN>mFj~=Uw.c4 7eYDZi8P[kFn<C7sSZ'ng w0(92o}h1 G'{ZMz,tA.TFD)U4]P ("P-Xc"2)i倱ACf#AQZEJY PA H&HElLǶt ci b7<IUCK4oe,O//(gQTEq]쫎ËH3숸 f캴WWK |w0p˟@2.:gK)D9�b@朊RRpp=ZêTU@xU�l[UC%6V[, 'w$Hł$9u}l,r P [[[<|V!d]9&F_հ ZhXsvYQ/ 2<e]F$Mq?rZNs~A5nnjul(DQu:dǩVᡤߊ,.;N6~ШeC 0쭒gM[Ө;@B$Ҁʧ;mGeV=}VXԆ8콑;U LP6:L:yיE@)hތ\gLG(۹5԰ۛ@ٙ.(bˎPYcI a!YDZyN\:]RE|&UyѺݏNK<b^Yc+`l[=z>SLWwdkQ|o)㼩T8�贔ozÁ:* y㝿?hy\Tg >f0e17 yl>;w^F:~V֏ VG1_BsI=/$~-nUr_7>7(M[^a³J^T*^um퇓G _[Km~* ׋ԫUoLe75K !A؟/2>yȥ~aՄXY ڹ@v%2)b|098a0U b7D\z]myS!7[0_U~u zъ4%ӿ )ծ;d|ejzU"7a3DV���IDATsZU+i�A-VZe@}3|~~׻RA]B%XEi,<H8\. _^ΓU h䈉0jɅrpJiicbX#v|U=k'RgK$Y=kSm_FwH>v%Ӧ^]: _עۢVT٭IDZG>4nmd/~ZZqm­$S䋅\el~&_�GFS* R>XC8*BIjk8):Efwan$ M�쁀JMT~.yRpi62qr`=e+2h䂘p*G+G2�Q Х`.8!ا0-ư19"79, ,ļ%HA:HO bv'ʝRkHp\2qHw<ω@H$c]IL8s=i'VF\mnNh<Xݺ\ C=JЌj@E%ȅ�[냀Zl[ՠC `E�|ꁀ; LJipe~.}K*�6t{9;v b@ Ĕ!y;)p큀( Em.{Œ7t7^RyaMDC7Ăl'Mhx�9;vYQ]X%;'}U͒Y#Ȍ? ݁ kZ6kq+f&FrL� rQܤDl#J`KBlt7!5#fYg-բY]6:遀ȄeVYD ߏn#WdF^6l^vдCt b0qC0;E}QtjX]X.Fώh %` 5 lD(A薱)eUh4ϗAL;AP fM}48*@061"VL^p4jy3ȍ@Tgy~s⁠A<fzΓN6V57FX x TsH n.s p1: %l~0"} c0cEZ  mPh7*�NCS:a`nkH' ݲҊbę6 '&�~$k,s+`!}v w;М3fύLڝr# yzpf#0$@oIwZkIkrA`Y6jF-[+y Hc lkE{ft(&a0CQ6=9�j f6D�Nc�*&`3Xd@ %/A1L Ag̑ \|W-t[~idVj! |  T (њ#c$-0l*  mMX7J$gG J9L[L@ԠͩPMLuG 31bF(Aԥuɴney|A`[>@>bzdhob@W2 "i+&"HW f4iG\o2 \:}0wp! *}Ap<3M,yz7]n DQϔ/DjbYjcj#BL_ѳ\6"ϖ{ @H *Gbdly6f!=dj`m\0H\}y'9P)S$Sلq2?c @p"{":4 0vA+N;osي]˜ ٖ7g&%ɴ"fy^^%LЭ.I<<d)j,T',Hgb06OP^q/L(qU*B8JMй.@M pKb&Ūpyρ|l`~{`}l\شgƟ՟:uDal됊hx,OYl`s#X%k1[/͞տ <Eff_=enμ>Of�| X"I+Son]¾U A4IjA ӏE5\ckNI4e{PC )_n мGe6gc%< itNA`A049Ty'(a�"?qL*TIm־A+U#uQذ~EC vusbb[#RY& YX pa-$p vvRk P%DnD$䟨?ғyLFvmqTįwXlP~˻ L<6b_KU.FE|oqJ x0k2 P]M@`(e9s@B-$(>9ʬ_[Ct̛!p�W[eų /%ـY \\pl l.B!=,`?M4(e<f %ɔ v4e_�\b2s6Q,{?};%  8'ϥE~vzBBNaXAxCjAi$&K]9@ J7Hx qǍRCBS-C9#›~nPCo܆X~%gMFZ ,lyW['zl<wПV߆9)a$N%% ? Vժv5K #0%XXB9N" UYBl2w^Z֮de&Ma 6c6 W>BdW6ʣ肔@mÓ /psQ()yQ {s@Vz(%@0l{js} <$UI`RHqkHJ5iz)f= y']ß޲X?|`&OvcTVe_^ %89\BAJdux=ٿRȍHʵ%۔7ᏪXE\7.XD=rӔ՞ux֙u&NF:i]w%knHyztLPC%4\r".TJ(BlJ-+:.eL); s rL{]YN9c8{z5v56o_EJ>kYA+,(, >\[3njYsߜpn<pA%8޼g6Ų_ۛoJ%>?]߳<Mny,ә7ų "hWvo/w6% 2@8 yq6>qI}"џ?^ dmj&:<Yg7A-A \ЈwC/x/�(:~X6׍'%8T͏m֩lx6=i=1GM||`AwG@kg6YAB>9nfݦo5c]'tlDlllO,{xv~3vTv߽^Mr؍u>Y o' ?odY3Xr}c' 7ۦFOҦtܽ~5Od ֻmM􊝞|fy[6]K"ԄhI j94L[KcpY~} SZe??+U#,(@=ð0Ӧ~3̉-O}1wHZ=Q'rͷ| ؟2u omyb|KԬo>3{&\N3r=Tv=O=G؞Ğ7Utqphcc Tk c?6Dzy l_N/Inc~w}t7^v'R$v3om̟Ȗ_̊ntKzW]֗.+^R M2mU2c%fVA >JiS~#fiw MyՈ'4}GpjؑZ1K 0|3_Q|1>_J^/-^⷏yc_^lʞ­Y;R)nNX2ϥ:X#~?_hD%e@ܫ>X_Z9Ygmz׭+7Hm&$nܝI-Onپ''=i:ך:ܽL Hл)=J`g%هfǜlY.y1t\ΖK.?v97*~yX)igeO^n8ic _(@@�:f4b6a"&anL?4Y*c^S7|fF| >;m 7oM}>+/6iٽ%Vuזo~"~ @ЊcC^HlJܝ؜}oӾ7T?:Wė\U1]�_W6+=mgpLjg @@ϗ<@W4%r}ݽo_'{uz#^f6owgu �I^r&n׳^~@\/gNt %Y΃,0  g'/~/(P5,V7F7\TI3qBDT njv79JD2f6H{ƾhCڬ>7o4;'4mxT7~)zbY_٬AfOf_Gwˆh7tS~q,=x<ͷĶ2;tMF3n| ӿ2uڿ7wǗu8= @�@V`2W ju}iē<mOq Q 3ve�!F0ʺNzZ/dAc B#fu3C\+*)=% mCT�}̌3%@#jb||yˮgm^_߹`=Fz-qwͷhtD"AW%}bM.iO.3�$߯ HGG;'?v׿~S=aY@O ;?[~7ZVE {G =2 I;=H,@;,糱Kʓ�s:mw: 1n3 t<Fgg O01@uF\]_&@@<M>A,߈iVY87"~KHݛ_@@#)Ꮏ?ij_k`x=Z=3Q@ 6Sw?c]c@@"aE'@L{+!P_SxQ�8`|9[O_'?6|0}7dz X>flϧ,זAh*t%%!%0tj&,V=V:D$?5?C+dcBU[I%)qWX.DX; UMJM|4Atj-)5e27|r:x:?59vS~ %c $}8+Pg\<n?)]P7ލfk2~Y6A]ouDFc ~_ټeGk҉X;�Ff&?ߓ[tl+Dn>5Я %unfY +~grf3 7~e+8 EJ=@ڧG=Wl407.5OE04wYun1CM_n:{5~ӍZe >_z|kkE=ރ3Z5*:Ч9L/V >yIc~Վ%hݍBA^=>;]w3m�Y-h=Qc][//?1o##>@_/TF_;XܵfمůXfsjٖķLǪnֻ1`&}c6W ?ZuM >"H{彂_˟6OOȸ #@'gqo\JpׯwwnS;GYS-2&FJC NX\az-kڢ|`x9DoH�Y64<"`iB|罅U4NwI"J . z n T }S7ZW[9G;l mM?A,5&SpLܾ)}顼ܤ^71g-$d^qFm\X"UC5@`w-Ws/&xÙѿ0E~FW\05F!Q(k뷗4O۸c^$5g*W .co샭dę*9|FK>bP9& [nk{]feo-Rv{swC8VDu]pmW$T9zg&g/K^\_;oXN/XYy#뢞<a6Oh̬m.ȓ Ѻ^nڕ5Q4Nxx:[o+NkNȵdNj׌HfצW^+̸i(We` fW 0歲(�P,|cio{c(D]8W R2nwwO94a$geKkq,Am٧ѵ O E \mA""բeCQE\NtA⠓H* 6Ә @3Z 8@cxQp8V2+3I86j:5x,O'eq.Q7 xJep̤v崒bݩg3fMʐB&qM3y;IAV9CQagΎg[MbX$)Mv+ivJ$N%O%A`zW:fI>j-ztn[Jy \,tzD<{Xs(Yp]?5r ,l6XJ>I0(k&knͨ XP@sw]˃֭T[ F<_4}| H,ŪEDvP=xsN&(%Ӊ'ɺtٟa3v՞vUD Uk@zs c& gSQ:U[Tz!fkXv#bj{㲿9Sy@:%OZS)%] -gZ]:�'c2SP�E(ibTNӢۂDZl A&G<;#k-%hjL-v� tӻ gs_Ay@0uA@ bpy+u}|r}@]Y)tI;DږT&3Ey')tzW<#$-?{ VDPPc�稰-'mqU Yx^T-ګ(J MJ2ua0 O:3v0A8>v ,n(7uAǿ/ATJ8΢>\\ׂ2󧢇A`10I`hfI\&) 'eø?fYLy̕WBSUE*j 3j]!"N!F-:۲E}jȄ,.pe捎iai<~ڛO=;gfJ<4o<{Wk|O q=}@pw!ᐙl<6&,ool)[0w󛋟~W|/GW~[O}e}h7J<3'LZv=$W/,G]m}yʊMN ^y>mWݙν\L蟭!yS�㍺봉1zg< TuDϧ&yu̅u[ ](n:p|U}FI.|:MȞ5_Oeoٳ3Ozjwm?aN9H޽GC5hd=kpkۮy%Ȝ<3Y?9KUۅX]=s*߾5gx#;LgGjz {b~>o/ؾ}! mftKli7Ѯm3]T2}xڬ}5$|6 >5HSxqdwj<r ݈~2)g 2H,Ji#Qoq^^VELit9e8RK|a[5x6"Fg( [}+"XfqHc9f|6sƺ1;ؕ L<"MFr&9dOLvײ 89[uvr f2esIc,36K»i|rس;oµƌuxlL{{g'H È t,Mĉ3kSq⦑1ʩk sA 2uE 4<w AS) XR fJv)B&qT~tADw:#Nә ii[5Y>Cҹ$K!+4m! ,9yZWe 4I▽ b.yl}{1X+A`LY-%9z(fd]}fgmrLLg4@eL{ @0 + RyrϿ;;O7 3t4@0:�Q1Aa<#$m&N�A@PA\>垺0q|6A<.g@fu6z)䵨n 8)]'NbU>uhj9[vI+pbfGR/V&a /u9? V~uD4K57cմ-f%d L2<vۍ'YRNAjG^ =a&fW&*b{/@f)؝O@po!Jp+w9S6j%%c4kْKJW%s2ܕK| :@0[3�To(ܴ:]): ɔ무rSuS$+tF~W^fk?[eyX.OfgG\k1,D2i[N]/>+|WdbZP*6RK ub4 _q]KzZ:Iiפy`=!Q> =L@`$`ڛfGOՏA{ y Bz+~n[REMҊHr#[3[gƶ&2FO�}jzA0gS 2v} W iuhd.D\dMw}jE7{RMPGXfRkݭAPX+e3.YjIW ]*[I}5 F?%ArY/oF(?q-oJ}wWPHhlLm@3NyO2%d^5z@pe\ÕWYyTC @}!Ihƾty<|S}c1"gдYĭ}_9s+uѸ7I0|sxdDû!ll_mN|* F�Yk^&]S�ALTz=n- cѷ_`cDԢěIDRZ/'We6rY|oHtf-mu,)M7AИ"AJPGibg\Ê'rx7e2J>#fC;>9SyO3SS>;;w(=%HEyv׳S+' t@WDb69|6y7?h0j}*ߺb "@؅wJ첦ukמ[wMSٙ);@GO~_8s΁>>w] .KKƟ~igK&~μ=u~; Y œNY)eoł)%f=x:}pv!}x0 \jUA*xFv5)I{' !4tI}XlN[Ǥ0U: !t7ۑBت~ιnC0|�Oϲ,.п&<@ 5{F+٠ 2CĪBVw&wthG;9AhwG~#`O/Gyn ?NN5;{c :iUYWPZqc@I6ʂ_HSC~~m쎱;~kcSǿ6FǾ3 O"#nrCӆ9{�λMR_dC 3Ux>6O-q`00Q$e[eѕ*b!#W7ȆRbֆ:яh9J\;cX5ouDB@`JἂJH eU" YF&m3vm`Q{+NQzbɆ-tAgYhF z 6ok`zX5RE|Eh.#@ww@$$azݰh~!Ck :'L_o)7HG_#v<<bqK8{]9T @̠DhjVʆ@2 d|# jBKK_ x'hfoPH{ Fn�]b.B؆K�VWo|o ur*ߊI(7Nb];2ut81#u99Y xϏGnsiG<WRDH1VD-:rD˔B]@,;BM#Kjv6MM]uɡ/ w@Y7m V~UD\Kʪ 2tk;\muL(/+j\*TP_+]RV JIat/km'h_d=N:ʲҭn w1!�8U0'42>sq>G^Wx */uIuAMl�JDQLI'"=pEq%qG GO 4 ޑjգG**&@l'Z* &8 BtAPQ=P"a,^">4Vڇ]APrEp -,"6ŰptGA At;zv-*PbUT.L�B^tE*jۼ wUZsIlV2c o] P�mn{fPj/(Ԑ]l+:L^$�X@ ~>X0PN" WQ\B_ԍQ-(4, bq"yU*e1`QTXm?o(՞ 1<Pリ˷?(7=p 10"aGRz5NБ(8WKޓt׀f6S�pd&]jެJqyYPJD(3(@j }�4흺v"o $ՃU�OY< s10-$ Y-kWCTB2G(+,'aùrv^_$M*X+ἐ/o ,}[gR-hg6u!sA HSZ?H ΧI**qs_tvA ]SvώC-,j8bؤa] 3JiS ΋ hy]a1̫ ٍ NJuF|R$iNl҂� I`8Il eblqWO]@h(*#3qПH_4Μ@PDi2*K'G7'Xx'(е~.]-Ps2={@0cC\PRqVט>.vYZVB@dU/I-A��3f Z6AeY EzY^zv/ 4cc jjvs[4{-O4CAA�>Y�2ٱזP?IPkj#WIR"? X CRq^軚2A$'Ix NϼwUkm~tupipb6ȏ@4#V,w52Iviŷ5M#v']YNaPuIW5,uAdt1Ϻ;RTWbEi T?O%2 :#'ӂYo)3q?)ƘJȷ5k@{2Mt2fC)Cy{U[3i)w>vĦ)`VdMo+3Orf蔀{}ӌ nk0އ/CġC[;8<<d?JaTmCC'?Pƿ R|g4K,M-,:Kߵ5@ d;J܍9Pxj/\U0vz TUU]U19iƩs h_$FA&nL@ɴ$[&2Mr \-ATjaB3PQƒW_xN䧗8"g J<P0QT~RCӢe̸3T~BAL3#m[immcvoU9"!vC/v|M :-U@LSb0=מzK}lZ}|_ @;@Aoo�4{C3 ϣvTʡm?~ĞkhTz*/7w<&dI}YM ݵ;+</\PV�\~ &A?0 O/y}pS`#= 0IɗA-PP4 $H>6�Fx=Ȣ:9dF{ WZw>_.* h:txb@K"+_Z�Ap*kkmGգZ2 tTأd,; dz,Q鍕l:]2nFU,y#(d2K냦 n{@mY_Ll9z*ʊwP W- {@%GQJLMgԲx;꽩A2h?`۲nGQr M0J=h?<083rf3 |вj2yoO>g)l'=/WH$Xz^w;mk4v&b}H/sz,L>aCW6 �{;�:< *'f98Ae't566o@`Y�>CGԦOKBpsiv[Q_6̝G뺧9 }Ti9{.z M/d ZL=DW\4 Ql40ѻ# iܣ_<= GϥM%d{M`W8$x{O;h#;QwU#Z@`^,z{&OssBߣ3&5";1y+]w*xB*Jm8*&y�ʭeREڢ =^_@R$7o`_���4A 4jxL$`b �6pچkjdXT`kS |}]v'loYb%~;0en;E�Ѹ pQKq `B ZP$bՀ~*D$rLy}v s߉A�G<Mⴳ <xh9T {|gen-�f孡 ;|<&0_>I4HT5l[ farv*i�b&xlOc.(4qۛI\n}g~6ۉϵ~wzivgx Xm@Y�@PHp{~''yTjp7ve'}>y=8$"طe Zcf4`B#6س "* ݞP 360A@[8yz`B'$Aϱ%?=̂tE̗�BO`� 3 ີB\DI]&Ulkp. ˃6Sw]#-m*8n*M.h *x54TX9-dF>0pT�An aMPTLP% cVu{ ̚>o)pTX 5ⴌ3w� mt0EDq1~`*(+A@0 Cc\Փ>kx@D@;)CMv!}1H̽t @HL$fbD:Z(N-r೻AtTq#F7  2|:�i>coc&�̑=#k^eBl@|,o_; 4ұl=`6v^PY|&6K D"ir2LB4iqt,jx)*,klqd` q;b3O8GTA07w*p&ȏz'¯V ThO`<Thz�=sp98ہu@@98%XzkrIt{hI$>zw�2{1LWNo;0 RoQ+CDA2`�H @`{ % [ QbA6P!\l#~t`ZiY =_.o!̦ Zh[ ꉳTu`VLsa'}oĤ1,H-o NK/m^j.h$GMxY0l ^٧(3_vf> L�hPP pKj*l;X$!"8NSc%|L WB1y;_ϗkh?v=E�/ *8?zg~WrN\ ;:'(Ԃ?42>v?T Y\_ 1�AvAO`Kp}gs:w^ڛ Aη Sb3 @hIRa)"F�&s^,CwLyiϸ,l~o7qMC{梷a;:׎^&�*&)x+DsFTAwAB��~g̽9x � �\5)AN�i w reqD(.ok˷/}AJ:CŢ PqIhُ+kT0L'^͘?)Yr W} :vd ˡ Pa^ ؚKkv@giYeh5eū# ܆ IJrbw<XE`=,RY"�9wa׬0`4Y%'T>�&ngxTE̛W�h'fcm7,wRsg r&s^W}+6)oCq*8^p|1f7ɳ3{i[ m"ru>uIb0c3EU)yV۝Do{ExY]m_b6fcx{D{O{o[k{Tvhk_O@\zQW=/iU]BJ832g�|BhG,Z 9ÉH%`˃v Gw*jS" $qA:`^<Mkژ+{8 wXb� gCl|Kn@C߅{㝅͠=.x."^_оp 2F2G:O8�.G&cryW5c8gAKkݩLy<Xv9 a߼Ç0C ǒ[yy? ur!?r`prjL__A3,׀\XAFWN-UEɨq Cʖ@˴N1q6zX'SDB]AĄM`)Gٯ~fW)/Bta&|c?8NA+tv.T-h< 8ͧk31hw!9PƩa~I8]h,T:px"lgq1eľ.nf#iX⩸t!p$|zX2`q]lRҋL?!(&#7,IB{N&E=0%Vkb'Au?}X)Q򯁀�KG sTk= 56`觏^t(~"*y S  e2~V̈́e^g%RIta:T 8 \W]b̆v$';f+[%]W8Y討!8S먘&.◊Y^^3zi�n`oa",ѮPJ 'kXWKa{3q],¾j49R@ wb"IY%\Y=U $#P^Viŭ�Elw"}=w{-]}(ؓV"1Ԃힼ[QEâգA4BKXnt �oNuZMF"}0^:KI^ӕuodwB}M":r6])Q`_ 7xV L AJ:{%&YW8�O5⎸1/+(#6&Z92bЈ'ˉu9 cOz@pRTі: ('=Ho; 7 Jui�Odx2~ym_VG N|z@I7BIO7pN`9oTG6W;[nӊmR:{޼}$o7ϤuOŻw=H ,4x,=M =NƔ»q. 2}Z0EVOJ�p8uLCǴc-r9R+89v˝|ؚ0Μń26i'Xκ-L-=ړqI@P56ǔݪ(6 kܚjKuZ*h۶UY#pܲibX^%Gaݠ;5slkMI(eOtLlU{p3wZj\ĘGp̮VjZBxʺmMn.<t3๪<eձo{za]yac%S+H&{_xZyt9I^ǔ7;&ڮwzDl3{ǃޑvE.CR܍i7&[TF18xJN%*W{t]!!;=lV_^=ʢv9kwW3Քm�<RÿP *JްO YP'B|'"@O!Z61(t8K|DqaC<T+:8!Q@Ģ �bޯUK箓1l3؇jCcZU t=m�5-+طQr|~gمUGa6j갚m6=i[k*Qڙj:ּl5sLy8)*sh^=[I.#wܗCZ7ԉR$SmNu~V_ph,ڨ<}3,I xM^MO2d}y '3 #)P8ᇆI4=Z{H|'G`= F�.sBy~iu GSp ęU;tV!lnZ fU`Fj蜺J+p/:"v1l.^kjy=o3[@[A� %m][ L�L@1o:sjTn� XE&Qj]dJj2Tj�|إҿN;a@�Q zjGI|d"@gs/>{(8k^=u ɧTh_5z4aS#wL&ǔFcV ϰ})1Z1Ό΃kZn-Id�'c>J_$7+3ݛ.ػ+~�zʑ.x {1!k~q*Wj$;wobS$Da1Q7l8W{=8v1n UʻLг` Im@p�1gw¼NrB%vO'KK ᗝMhjM}SWTTm�>lW|\bc_ 2"`Wv*R7^*)pLoI궬~/(Wdc[m*9xLC #4p_"SԪrwUcCS-`;_=:� ]r6udTmסlobxz Vփ}G՗EUޤjVN$rA&(nI_0Y+Oo)щ-=/J `L!� eD7 7!p8'6<cohW-A:e@G=.qx X!yOkﺾ5 6uI&U /?fe` 5?Z{ m ! D ]l5: 7 U"�+`qUY Ȗq(?BkL3@ԛv53fA-^xhGgl#{aX'QŴ`oL{TՋ%-q#dKB6%}S'^aU xיSw*ʔA^Opf͖b�* LnY NUoAf7 \rLۑ+yb•jVj^^Pjvu9E5okXęb"%Y#F4̫#'Nl[PloQd@HfkGo{, ㊯KΥ;g@˟.6n;-.L^xݗ@`2@M�YRÇ}gWM ༓AFuБ&�[`lS0j\4rjڪx :}ϲ9>rt#[ɚ::`Ek'lOVkE[~ @pdg]E�EwܴK`"W$Zlн?!p\� |3^P!Y%l�uBM{]YQ:4b&VP@6-{t2;'|~Ơ2Taeg= d~m�@KGآ0pzM--ca# v>8d uڨ9 6�uB�];ZFmL0K36&"W{ ^;^M܉UdvS_&0m͖sg7~6�羖;1۟ҚR}T6X$`{u=˃IhyD#2~N˭4R| Jslyz?6AŪWƀ4*]dY){uP_2 &h\s0tAKk'2&72N`2@&b&p{M:v\EB5z  !vfhΫDa7bl'ʤ.8V<Moe6X)ȸ s�d@C:O7O��6.Uo3~;WWW>t&MP۟yi{GSx_4oOi`}:`9;>ݯO}݈hVwPP.OÞԭßncj߱S K>_[ ~@z{ xO3 Tp(9fd]&(? (2 )/j[Zq sL$�iο*E-A~ 5au0p//.yE|)FUa(A0ko^~B!]Np.@0N6 '�@{5\dQԂ{�jm?]LjCu�n&=K2 {kLhc+I@+I}{ͫVe&4<FUUkZeо{"6BcL9wGǂS`؟Bk?bs#w } ԁo 6iQ@hc׽1>cM0ݛD&謮pM_.7Qܘ~gDd cN=[ `2\ti6ԣTFnz¡/qCQ=3 lKM)Ƌ.` :|s )W1U\HYV8?6p} uQ i-׷KzE9=Lq h`\U;$Q%t@m8`v zӸJC)+Yy3h눨.H*"a̟FN<pr]RDǒ*jUvhT҈gnRƢ|daEs= /iW{ ^ZעY+5IeWw^kw,ʣ5q5O󜓡r-Бh k8w< o;@n1ȝ+QvMN<Ȝ& LW\]wP @#p] .w]jnyN={yð Km2'gr?&Aġ*VǑ>T a"*."/Ɋ|DD@�{*pc<# 0z+#+ � VG-% A2caO; K""~<y[q Vk8:"b2a�J9-زXj_D{'=g{tOd xto|Yk�k�Ȏ,jZ̖v&)WxYnVUz`$7:S̚&yaF#M6dhNl;ܑ'JG?z Rxeڢ*%%tA꺯/(o{/(uu]PuM_Z[PD͐pj4~9wpiQ㗅2ꬰ"2FFUQ/.3kڲ>Yvpq +1P)95q^tȘ mY*L<qE{N""~I2�]94f�!D|O:K*7֕u;"XgW˝t<UUT:m|Rr#z|a+053 )壇`Μ(�jsMfVZtF4K`cTs類MI~,RWn_.fCNĞ�=L Pmvۙ` 6 Okw E4~A<sc$W^`__* F](P}( WB/gE<\]`L פ['Yw4N@>JCKęS'(\7 _1#W$.ˬO,O*x ax_#LjJ񘥔gr aitJ PrD 9uD:zPȄ pF |NPFi\rQԁvb8ʩ;`=Ww՝vHwjY#`D�b-I qp(&X?ZAqU�Gp� 0 3*' p J3iKGZ'?2 8 {-> \Qc^ k1pA<u}UfqHї~;Dm㥶ݨ§N7R7Zh ExZy֭x ̹Tڂ'b-s,Wl|5q3M X?4*ѱK5Z Ǫwu^ m]HdzV_&|PfƲ\QT sCڐ]*lAƺ :ny `*jȳSabYV IPdBs\svA[PDyKRcvb L&Ytj.hiJ tϣyYpߑoEG?~ XPf l qX/O)!tC[(YVv*KP™u*™JgP/o" Y*WT[d?$8[KZry_ieĸ5Lݟ3_o5\ֈfr;ɍ~N#띟KIv`׷;އAК dE�2lOo? T̫ Dmqi @ Bh~^ iMh :e^^O@Uߣ gP̓ DBDž̏Z �c+R*6Fb#dD8nuI+'??-KV�ąvw,<_A)bb,sZ� 2 _,b}\x J$F= iS jC бvX, o 0%x`/(teAA0v7x(/gP-˦y-کh];2dGձi; B ynE�AВ"x�B 2;d| D -v�:"vB%,�&XLTY Bb}1A+ : @`/ _LJWtRG<0&i;g,h[ph oPNx^mn.qbNI@RQ <} l�`K�6PF GQ0: ؆[P!?d B ꂀA(!d'&-K< ߫rݭ1QԣG%t{ydWI, ^3wl& < jP`­AeTM@/X�-l_p|NYPC)(n>vajc0lM~兑9~6l۸~'Tv>V z0WA&h^S$\ bi쁏 ��׳=lj2�ϛUWUjAռJ5cP -7ܡ68뭨ߙ6P 6m $Q]USAU5>nP|6?TR5QPA{AUXo دݰYMݸspgCUҟho`x^QrATګl^pժT*u.3nkJ喵#[SլL{dc9Sє뼰 A0>g9QYT ?׽Ryj抮A/f y uCp u6!fP*T7(P[Y�p ͎͞!ÙEZ kéIj!A9^k7͎3{-6NcOڥĝ`նipf�ҩgF7u"qe_/,$%6)~FYM5ΜWo&LO7KdɚJ$8GAIrmI;j>3 @STMN*M2w^iw(9"G382O0طlOY̶ Lp}A/?oXGvje}WKS'/9 }6j뷢Qv @> )Wvɿ׏_-5Ii /VbY`h0BI I pm=BAVj9J=D:� sk\i|ּʖ`; 8> w͍dQ //&+6Fażٶ3ۏs;j?ݶ 5ڧ(?~o"yb�](L~YIީYtH@Ɉ4g^;^ J5�^y6M6 !Hu/5PoʙAF3>| bM`1aNlWs��P;U8 lm�{~H6,nI&]&8ݑ<̇R9d'_[LWHߎ*6>6C`Dn< |(6A;][ec|-Thz.�^QY�6OF�xr!�ۍ86</sʄԹyfQ+ &T?8Yer,FW)Ĝ:boa1EP!5>M'4oBb/qZ `>v8�j*]if=5I3Eir  (438-A }Nf4I!X7_ܣP # `h_lJ26Tx>Aރ'FR)#{TMܻ΀#SFyuܣJ2y{7h?ioh ݝ K)˄aXG @*!خz=м4sq"3.`&˄Y5�y�jJidSl 7 ro,쎅CZ,7e'WcϼJ,yEp}Icl" ݫ YXֆgkL@_9]쵛>вW#_کfEluõFMsh h O_SR:IC%м?L�&nw^+86zn.@ �Cm �>j{@:�NwǔA VjlkIP{>L`_f*6&uݕ, q �&xfv_AO2' "#.q�Ak@- hM[O u: ;&z}wLN \? m'gسf+~}@Cϱ_kqב I?�͛`O`k_6q1+{N8`:3D)' 3TZLIԶ킭{m۲jdz̟k09#gmf6,dUdM!j*\> b[ni (z_ķMp ZEp\{[dHs{a?ërx,`55174-Woc7o[V6=9OdS}2"o n]7wKY;v0 =9H~ e Zum~Zoc\YKP�j=yf!@1A1(-H͇Bzۤ%@%?9m.@ ZK`֟m'#Nׁ W|F5dFr`"4#%pg8`l q}G1{@Xw8÷ⓙf+ӣ.l<ӞG`˞J^cNL;<'F\џFQ<Ω+(w`[{;XZP\4</PQQ"Tz>G*9h:UFJΦs"pU*Q%爕?M~ݵ6<7ohzMVjEI-+e[*6G1ʟ 1GDZcGv&']gϢ_9/ع9 f 9#r{NSg9<GߴKmGV~qM//L#LlMсs[9!Y޴~?f<ϔ7S?LhiRͿ5).&~M?~_N*gwK_l3f3.ۊ GP;J2+h=LZx;yC> =@Uhc5~M s k`E+ѕ,dN`oB` 8.;-#D5<P hoCу; LꃩG)?vAP.)Q2"ݎm>2$^JJsã,h*E˱5s~zkt[7ſV{mb tGgp෣~q) p[pҟ&VrIwsum6DV6y{+M{w>BPv-pĺ?|}m…6jgo8yeBͮުz/oeS?GnI[*X@S11;fߪX%n>Nf'y`ζ^4*Ӥsn;6L{~彜W}wsiω)3GϹs g yZ ۆǽ{z\ӧS$Eg!gW5s&hF۽{owTN*)\%,`&`i2ux>AdK7 /G 5 ]W{'7 8ŦeWeDϮlw;]a;VG9uaaoӃwިGH4pI=8uNNM'u}}9o(upGTW(ힺqZNq\C:r]!u;ǁOvjo5 g;?3h! x�cr�>xÕ%N̼1pd_{^W'wrl8K58u;pv ruoE4t\8&jz"-~z0`o_jcW+'(s5pM?5N#Ϲս݃*8A~w_9.]1"ȼOWb] l[5SW WRR� �zȓhsY.="a @C_WuE\^t9R(2tu!RLᎉN;ZYE#"?j@iEyG]u֕3=*Yk>4 9rҎת%u6(8o('K=vx3ϯ3O'd~_>N{r~] f{5\9zjկߕR:S<)P܃{\ŦD]JO}ޕOFO'EuePVPGY^hcp&D>o},z@ yFp,/8+u6Y rkoD8 W! XǹFqNM\� J E,e8?ؿty]e8&H~:Wd8 ès;. �Oq'^ ǰ= aKT򪲬H]Wo5u._vI|~ ~S>C` uwA^YF<<P�;BK;J64;pM2:Mƙ~* 4:pe8&Ś<Kg"\ ǮEC֯O2gQR2_IxN`A *,4_4fgqƎx <Ƕk3Tz<Tx c$L4ZZ\ \*:cVFh= qZ*7N(?mH0>@wsuG׃w3:ig4-9/^#p>g_JW]Qhv-寂cd]ͮ^|iL#f�PgHbl?v[. qqSNϮ,~`߈8Ư@0̩1^7Q:\CW<Y%NPA`4UY0Ek/(R#~.ͭgk \`VwMpÁҢZ`T٠0{!0c'ݚP8"Y4p1H,kcne#V??Z փ'8YZ|"qD(,;ޘωz㋅ဘ™8dP5Xj<-V`̢0,_P-�yC8Ýő_ @pQ TZj{o*!n(1q8f)53W'!im_H3)Tne9?\�xa\ܵSa fTQ#vx^Ƣ~Q)**.iTdqLн2༭g{ *:ugAmV^PLGP[W@ ޢ [A`@Ŋ, pG,(�2o. 3ag;~12 aDq2Q#dpo\W!>�[foj), x=W#@#CŷH4m~k] "G�WT<݅#, /O܌L-n5 V*%{h7v~$\+ꊱv{}ˍ7/ѓIw\х!pLߩKHvBG&�<T"9g!P ` (--_o\YH@@wZA<A>?sW�ҘN�#Ɩc݆}%h<1Q܆+'4/Nmq`kAO>1F;A#/Lj۟ڮE JPR]UݠΆUt[Z>鳽7' wrOٽ7ɇg{ %>77h^ug7,n }?`%,"Ő� ($|D!A 75ϓi0վ7[L[Q֣"`.v{UR <xsyڹ h8b Y&)ฃ>!6͟B bGA`U3PT&B@>%v)eyy̖JʤO\)$l6~Nei̠-喹I`][,)tY-<RfёUO >Z0&ݭޗj`v*fR#M2썝4fWAjRk|.MAy6qU^ԘRSl9YѮdJTj1U~2F6Wq :VScV%2KVOn&x-n A9)e|:c$*$zR UbNhO_R1NoellbiB#ՁN]u&Y(VM=ER8/CIm xԻ+QO<:4lűCY_/$ 儜 &Rr[.<Yo8@ Q}(LIZp.+o )8f,r .pSnT)?| g%̀ѐM(}7z( @  J"ENRl6-IP v e3>?>Bm\²mCMhxviLjʇ0wͮY5WP0f i;pRCulU5jxI;vW6׎AtQ('/RjH^6_ڏs< y ,pffYL4N8m=rTQJ.jN$ÙYIE4Q*AbJ 洹u,8Y}OQ�ZKjt<ڻ.`,V?uM3{lƜlů K2$*&v.þ TXTV@ vW^I@p|&0K2|rEY=2_T* ɰ�0LoGU�A @O[M&{]S.H MW!Ϋlrl\-03mFhdS6]3窕W鑁@Eh^eMh鸢nl&^~]jcpQ1 �˿h�0cL.K~*U䅤,j infSSb3�a1qc($@?5&+`X_CDZ'Wӡ{stϙsK)C֜5mD.  Ϙ/`�ݷ>6f2OUO7G٢@D∂VQ3K`N/{1t)�\2;Lݗ_M ])ԈrQR%;xHݺAy/8ME.0yz&=@ Z7vjAu0'L�J) c"j'fSk;%xlLkJND7q!ƙ&+`W4S]iA5Iͫ y%wLf{J4 Pu^nMy'ԚR?I)0c̐:i`R2,p8seF1k8]&Gj=P'G <Iq"Q^9IlbO(3^dE=�{vɚKx{ZXhyxx@@s(8owiԄS4u8W֗_vY@V+{-Vk 5~G{ʢ6)APkIjARLfvk樂[8m.S08$4]C.(#S$2) {w\ԞL"fo*>;lɜ]kX ödkL@T9mޱG-ڏfk,ZwG#wT%*lΦ֞=ڣjDG?EJjl6"WEpB���IDATPܻݩ cl?Bv)NC.<<7C9c[&0'ʢ6ac}q'nQ>TD@p5ʿۼi97'm03TZ2'v!@w8d-]nPy>Z|�q'ͨ Tr  #=ג^F(30z Ali:ИYHIKn l �Y8И?f ]?z0#4rGǏ(GwG)�L'L29N {?tԷٌۣT췕iSJ)"В+ieT;朩\s\1*9VysaU-~dT:,S`bMGRG+,qDr*=*zQ5⸟œ8uC;DbqO�;�$l/hqqbbV{˚K{eE࠵EQ X�6?Wߥ#jjyf?UϼtZ=M:g ;� :/g2t] @� AppycQeP�8QF�Sإַ`SHm'D쓱w� ;m$c K %%fR`:pJL�lCvݲFwl:𸿏Ib$` xpA !0I0F q XPX K|Xo~e �`/�Q7m\1.dTKk=MBՀ 8BR*I',l ȯ C9}1{jb!rFk\MM, d7٤vІf7#GT? ^'�0<Sg4Jϙ)r{yЖ}Frh|bn 2T'ߢ;h¾%�q//^/e| �^`ܶ0{Q؆sKE//6^lEQT 0X?e_|EP) cv;;^qLT#__8V(wͻMU`Wb/{4s4iA9w*jg̓xGbƜxxi}{|cMY1g:If9l`@०Ŀ4OqieJ4 b$LO uy7l`+9z !paPoE^`pPy-?Œ;aGaSH�= hȽyW憼hn`=>͙^d0-=ӎ3D[n}%E_P �>ců RhC�Cn#LCB:!s!9y(s|ġ6K4c#?=x?p˻\\7q)ѩspSYmsm)-<'/yX[g>gnC0׈y䄬]/T#G3qDZ۱ι8"~"5nϜ(936﨩W'X[ii Ŷ eɟ 5LjdL}/FMcs9#WlppMe49 0`րL6:4�[�a 3 GEӿ,f|Wu:+IsvvfՆuve3ѯJvTlG8.}WC6{an?8yg(kܵ7lf `&wkM&q*&CAu1NGZ8&;`qHtb\#p !xs3Aб# h2FTr C8B?dwvʕ/=Jހm%qvJy#>B 5xoFIjb}J?TVlؘGg6J;>>!˯5SV]X�s#kLۺ&h`*▾4sM.1i=0w"A3h,͜;xUpj2-Ց#ؕ%0 eGåk-esA9~q8g7yPdD՗Ku_wӎg%q/' y~\ͫST7?m4(\v=g'4;N5, ף�-tD<z3K2{Gb'0>XWdD͝Q*3 %�Q~;fi^}@m\�؄ɋs;jGYk~tGًLhUGDf $('kGrIĐppD䩈CQ|?.#gynԟTO*Ցߕ+:XwXtHԞܷo䩓C}W$3~޿ H9q�.dn\ZÜ 0Ad�K=<3,QwzihëeCdBb Չ?Wo_>|�<[ /7 Oz~".4ߥ+H8AJ= ''X xnٍ$3R"5t䚈er(qq{w5'pp/_)`K=W1#$עnHhH78c;J3,H#xx3|>hBRmvM$&Yw%N1z0m<?֕7iF<0k2qmRNOn& jwXk}2]yg0p<`]lq律 !c(F@%x>r1*nUǩV1fP'8P>K~� |qxA K&_BA-9Ti mh`[q8s\Rx uZZ�8Q3STJR-dܽ>-Aeո!t t<.,*@6Pc"$= `3)Tϧ/D+x淇jHn΅?[E3RPnxJ-P5%nP5[Z FoPJ)짟x 4nP>}7lɾ,W$`?uqU^@Ƹ 4OBrA-zhc*72 sp EկPR⨸?@) ۖM"fo\̻bぃLbWtl#c+-!e�JRB2k^  /q̆,~Ej'[ػ4'$wKnw�}O(h $.:B]0BAD OA ,k*ԤHuؓPP] `4)bNw8_\4w`@7,ס%cg-8aȃʲD )~2. u&�x+NQVMofB 8 <[K`G ˛/߂~8 PG"B%dI-%ZJ w23-Y)Oɧ[%\a<l>ȸbൽgROВS~4f}{*ݫyR8736M*W5Xhİ6OA.*83�F3 %NW?YE{x;@U"VUQ[&`RtW:)pcU +Թ##y4>m>glڝ֧TE1{:[P_W6K}ݨq&#&SՏAc{bIa&s %5ryl¼6S ڍ.ղ*JL&-Lbee6ӠisoIҐ%*gﺏWAc,Ω 0QVMLGY(ٜ7 1#Q.˲ KeO>\LQ̴&fjf7٥nn՟ܥLuW<!z5 I B׺3�ԓpm=6#Bhf![ 1|2ϯUASCw_U:*Pt |5/� %t <WU CϢȩ^4.VdnNbj_cJձ鷍bݵ;~dg PpS6?�JVRLeqK ,']ʽ]ʰJ0Fk)#LGA%I:ݻ]deWbkn)KI~OL4/O�ZK͞^21t25{ŇR+,_�ƲKEIen?畕=oԤI:[MflG)#嚩TRNMB)j8$L p:;sr> o1l4aTgVW9r’ψy<9<[UgY ܩj;<dR^e|r;TxZ9@F&8@VG" Q?:NFRO7nQ21 w Aq:++kA+9N?>qҶl `|rre CuH{d ãB9U邀˔$}yCۭ*v21lw/wG{oII_S2%jr?3A�L2ݑLɽ\Kz_*JhQY_Z3Ӌ[&}%*i*&~'φ^"J&P2I87%Nص=i62ۭ6,/̙f},EwW'v{̮;v=M&3Zᩒ+0m|!A MtA'iϠ6^L4ΠN%q}Ӧ؈yɅWrƜb-:?$SBZ ~�ӟ-wh >O帊s &tՂ5ogWeqqy>1To Mfn(M IJWC B39Ll(=yc�@7ȱ@=5bϗBq(@2,/HԳ۸dݤ${A 'K%{S+ |Zޛ[,)3T 7%sj]u)h0=A&C{64%`Z_.n6| ( 6KMH#8zLʍd0Ք^H޼\#Ee.|6[`ٞ -`:f5̲V5t ,0%0&Xi=8߱ F%PyǴtֱ @ WJ AQ:b4ĭ׻ / 8C>v sJRvټ.f;V!goFi:#YM֞ϱ)Li2U2gR>笰>4\9h{o3v~2&nL]wIbGn2`$NY,|T]&2AJ&{UڍW e0'~.&APv_!WqC0xD7S堬> fWIs|VS8&o&P"-I`O}LaA@(]gആ#&T >G&xK'v#"[>?hyYϘIX+}q!2FMq poθY><.qg `PyuPmdȋ @1aQ˵2bJ֒Qb1MVmqeT,[QFɨȴSige7oKak`msw@I &@oc%b0v+fۇJji'dD tWV=HMtLksA,Z`k 5Ʉ @&0 lL@L&�<T6̎D&;e|Ep�`͕, 3_ەL=J@Kl`+&�c<q`{,e͇) yx5Q$&F=�Q �n@@�ޏs@=@Вq`>>E&6^^><<uMxJݿƇ`3;:V᳍.E#y5})]ߣίʣ7۾J9iY{'rgѴZ!4>#Ywb.w1qc&8 -ۏG{oeR SͻSn*_V9r&JE3CIڼJ?Z @! Z|3-�q6Њ#x_@&Od愆LÓ;p% twkIbcR'],\~<@uBq8Xy' !pj<qo%>KiO̫s9U B4e5ZA@lḦ { ]V׼FzU ABv n\#"RVJ=F;FIxܙ7~.xL>hd6P~=O3>�P P ~1E[nh]eǾW'6 }W2GMU%cʯ(8>wOg֣|lEދKj_M5U+_ݯ:!.!ŀ%X=d/9HE%%%n_ H~zub <U+w9^/ѯ/"y)1vѿPpW& 5y ʁ-5@%ּڲ,F"`k"Hzn)5[o} cڴ:ڣIIy+�� J * �Eʅ!~pU�h4.5F:Pxt;}@ 6b˛|;@G֙F8dF 1^MƏ, 7qiYƎw hiٻXP1;{SdOn;CXCZ;Qݾ-Cs`:x}C۲?wZxGcgDT2O洼Z=|p$<6|›R`oÈ'+/-:b++TThK K>m4O')po[6uHNq;N:we;k!_]ă6L@6׷6~5E3s`ׄ:zotuy.@`]1 {$ =Aŷ^# <`�⷇x*�$) \RF{5QE e#Lw� A�84x;1'ԣN2A0 STt=0/yx[q7]_%a-jĻʔۆkc&t$.J]S;FQzL6GWZ~w..!.`�k:|НA0dAe;%߁�7I l| \–n*mTh J :<JH wXw;s8:�JQiqj^�3rrvQl+߽>$62ގV~J Zٻ!Dי6`\,7 �—5zɁV}i�x8fs~R:ೀM06mx  `of)A;G{B 0X7"8_\.ZYWV3;*6֭(fCoږūhfB^XQ~l ʤ*>3Yo;e[1by`mv]ag veaJ85 n*` H|y_3~lj3`v'<04Txo*7q0/o*u+qYp,<#^WArqdvG}p^Fkʷmfډ++k(8%FAZѵceOl]dޣ@\;cUFqn&4ي?e\s._V*c{"nL WFe <Љ`w`#�J,n_T60%&7 fm+{sxnU8I:}9/�m8Mo BҀ:g?Q>#w0u;?T]$~^Rn_vK]8|8D_3/ކaa2rKH^.mvpyv�{�MIɅp8KRbcZȹ/Hľb ᎜Y+qsb˹ K^B$yJND 04$s&V?3!KáE7BD88B }! )Fahʇܵq℁YSuJjfmGKQj�sP[ R/eN,a kXʳ8Wx/�f�ط>*jn||74OY` ^g/`8V%^_0d2ߑ#c9n įÄwϓ5quxz=c�Q %.%t #ƹ 8Npq #ŏS68;'+݀a\"[$�sZ yC�S{o7qI\iH{ҖȉL"vq�}qx7_Bw~Ωs(\`^8K^ո�z%5_(L 8q=x'zc#]V9xJ@@P)A5.\N<֋q)ѣ ieeU.nV26uO!/1n?Ֆ7÷~<丐DNO\e#` n3*`_hh!!g\J, :9W T&"%yu5e�ԝ˛Cu~eXV¶ߞX|V!l RYeGw`G-XoKhK&˓b3OTq<WvT,bN@bX8w#06y'5>ܼ2J\u7*s+`#Wu/;";\bZGXc~ A�+\謂Q1y5@7 f@d;! ¢ VG/k$F5`7Ntr8(UZ�P=msEmdVcT},S16"7B~9 r�4g {*pA,t[&IY>o?p4^*yJ^0ʺ&].:.R!.$*x3⺀�dl;Y孔,xGzWI)`å D-hpa?, 4v ŜA"zZZC, im .D:{ B�D׉sr0<ǕhMl OoK2bTw]qW%a1[r\_NZ֗hDwM9T>Ȳ:SKR!�AHN;K4pH*�#qdZqOO6{G'H((L�Dag^֨X>JR y<48)c~/NX>k:Ma<vnNM4f2^(շB7t[;HګsW`YJ*G@@` &nç f%�(нM %),sH@R yD A'qfٸ  .$A&z+#K%ZTK^fKV _KeZ>Oޏ+V\S{L/)<^4&]r_=]8|~XʼoeJ6'lҲmK^3i3O{YY;Tp8|}"&/nv^=oof_�ޠ*&%IפTx:56OW[3ΫI{ij{7RyxRܮ* xK#U?"SwRNJoƽ?֎vYJ۵˘Ե;uyIp?}7٠nPJU7Γ`fJ{#EA99/ 8ޠbA~/*gLV8섡4 {SLkn0"GnL* et(3Qa8ffB}ebO GYujB[!(=t*ZVLwDikG,<+}~6Sq˵ܤrr<^J%eLTSwh̖S+Y P*rT)dLx}Gye򰩿u{/–PJPL'WW D<ׄ{*>W9bx/ƩϖҿU9ҎN?}tk: �$Ѓ0~$(zM)`(tCwgLbQtDUd1;>zBW8S 6hl$ih�>2N ZxQ e'�yM NBJLcĉCҁ`fM */: B‡>/QՒŞ6e6HFb 1hΨԱe&Q~9uhRq56Aj<-YXŲ;<ot:Wңt*IQ}6Fʨv*piJQKk5mTmFx(P*~cAApl03 wOY`_XД<RɸJ}l!˲7etJ't}w<87sdT3"<9m ьz0`_R仏D5�Pw0<miL['SOy 6^i�l!<9GҦ,AǰOqa8ehbqBX^p ٳ.v=@w L K%,?ꀈ*v/S%+ ( -@bਢ"dG],&(shN:t}ϡܡC{TGգ8HeGtmQn只>gQQWrbѴKQ'+樓|%0EQiz(Sy8Tn^L<(<~4GKQ*gҲ֑9:5wRy ޟУ�=x<gdkN(дy͕ʼQP}<$ot0c&ӓ' F|[`61 @{\B[p@m Ttت\E&?D/j:/k&.fESd全 6ŕqQ^pO^$U z'z~=،.Wu]t5BO*K1BDρ]ʹ*c?)/%kjn/Sh,= >;h wO*9{!\Tm�,&{TYFQ:.XP�?φjvt=!9أ\[_g{p^P\ HGALyIX`uLp*Qz>ȸ0/}#ՏA ,W$�$f5a s9 XUy]/-MR}F_"SE95x>-ʥҴ grKpy|_i缹(y$sK#8XK3`7=3]B3lz, e8@.2EY#x 8`f'Ho[{^ v`0Ƕ`mNjĩPL[ܢ!xAv2UTU.$<p+Q]P�*Ls’.ƢJrcLJpuP7HgZŭͭY hwyI/Xip4(n*۞:36Cm4wl$I}.w[r^TSc[�?3_34 &3əwy7Sק[[L)# Nr9<7gR[7M[;qXp(-?C}68immmmeZLfi| ~2#@G`?*.;q~=`OÞ x8h44|�%V$Agkdj\hd؋DB~GppGd>'fl 4,'C:�Mp8gOzQEK,�mJwMxYH-;O幭ełLB}AKB3INjպWj/KvmYeyp>I7�A_D/Hꝛ; �6UI3>Sߺbyb+<ٚ7[[m?[bO>϶Z-ք'3n@n'٭$y8v>/<yg-8< e/alPM~d `0F@`yŎ F.] $s(TgX A`DW| e_Z"6~>l߆#ЎE6(�4&J'i8%F>>O=|:Ȍf Ʀ+.ς.c,|Ѐ;xk`-@3xI-mw~ D:#�ǷTp�̬sg~nmd!pB}C6R2n,7-hM]-;2o Go> ~3�x 4Sc2cA: Lg mb_M 3�06c&E?$p W8\rA�<T |RA` t=;!_) p$ǘ'qXwA0!0`u<%aɸ@3Fo;-Z [.Sv2frkcX6AGV2kv0b,p BSp^(IE7I& @Xc8Gvv΄ D%Z#,+-@0oP||3Squ)ϛ3 hYANԩK </7tԥ\ ST.Auԃ|Π ^ Ϙ(l@`KQ (-mhgV¦�ALX8`C88D"H,5A}Lv�bYH ۸ j�i\AwAaV JKd4`Pb[3n67> GH3� >Φ�ç>|�qTK|0E18kÁ9\'+oSURH?3Y;` O" ڴmAtc`ܘ |]D"`o@Qf|ko/[v~ vGdצ *NO$DH4UrjդنC@bč~Y� 0jA`B�` l�L! fg�PT9C'f IwXpmxgD�BG14�/ˬouM9a3PBX"hj%~l+tIJ5_P�Z .JRi8 9ls, |a/lہ1niqA W?ȄeՆ^VfɄ;ɐr+_O\=,'$2-i4� >Q`b׭!o�vNN5gGu0W]XjƎyo}=^?Ǐ}xcyTR%*EGۖg,,{Si 3>g2\|M#Gk[క?+A3+'}29ھ&Ypܷ25Y7YQ1''Rë8O?XkCy p''yj%X>!Ļ۲]J`,n Z\axy4peV_;{7- k41]« ] Ab8Mԝ[#@˟!cq,NFc322%lvFhf$n̮luh8Fhƛ br=rہ!ezqx<زۉؤietdA%Hl8 YZ@}4l~'`wuuOuꜪS/] !30=HðƊsз |xyǧ?\"C9me ؑ8Q\q*R x8%S'+""H8эsy YOc[NI*+UL_P;[)za՘bpLUeC5NCUA@&` 8JiZz5 XJuNq:04(!Ksu9v8dνU*TXLF#P8ʫ]J/4kUq =p j]UZ P`?bUz] iscUUB gU, <NȇȐ'ddnau<wYs7i$=МW+c@F`FC '!U<6 Osf289L (*o|e?dFpT+]a/w AP8Q )vO0F0_VA. p8=bBχjAWЄv0VTL8ozOoV+o YHƒ>j`�OisJqUa[܂ %bvy+D2--o/lbTU ;)ȵ]ET&hWAp4~ �~} cN.r"2  -o&jbH c70zGY=mSA A! r8ZYbu\kҦFLi&Cs0oD΢0m*[%x@Ī$ {D@ 쯕Ġj)=D9 �u�1h" H>T{ ;W`IK:^p6P6D :]?,t( **_DX@{^ 'N `E}{HїԆ  : Uޒp֋ J;U# {x�Z{D HQ�G=vthBOa!mJ)-oUjkvHlq[\ARFHBeX?%=ko|1ma,^hCpc zNo{TQգk{!( ںzeow $?9|%rhca@,`y6(Ц߀jsD$X%@ҕL?7v!'MǍMYu\ocMV04&&'Πy~{ŅjÖ3ZMg]q6Z U uI%ͯSwȓS%MDaMd, =p=tmzpZN{R O8. ao:ifZ 3깡垖{:[D i v;<db5{�Q<dqZ B'&c4T )~l�MB$ u"(</0[7H<%@ϷB6k=؞jf8z#%*`Ћqz ZȮZZ5T3'ӯIT_+i)A~՚k-^C(-jZ\9ɵ~|Mк#6kص\s(_kJF[[\[]T\[5f&ht m/Vo (T֮5EЏЊ{zލٵ;[cHsAnȮkݏ-q ؠ»q؂x4DtKXv H]8$zB`rG6v?{@(; P} C=8 :AA%tmO;=tKkSD»Da\@NP_DQ4PU︲,+a$_;qydwAxA`G 0A@평88GzuC'I\gUTl~‘qJL:k=+_�c|@K1/aP^+<fX9Q#5:Cb|~{1buU ل:X^?Ngtˍ{^#~n|픆J!lNp6T,TcIA@, +qdv*|%QFĿ4a�ϋ C!}_I_I/S,SNv4ccg.!>4̈́qVtCIpr;56 �`$#JP: W($*Qk% ]v~/pqPIn%קWG˛i`@DZJKFK#/0t{txlS"1Jɞ_pz,C5?W\TB1 ՗ Z<l'?= UVB^6j^ J2BBR/[,:R#UgaSy0e#sĦqZöT<%vu6C%T}HAD ڼ)?{ Om v037ӷ̚4`@YϕDa#cegTٓڰ"U@x: )dƆ=}LCXA9a!@mT]:BG7U[vH˦`V/`GVf%OWZ-ob5`ɼ6jjγQ>j6=b59Rulp! {yϨ955:ѵyϞgnړqr.8S~kMXYm|asiyJmިnI�pq*a&SfLZQ>pLwS<e9ZߡV Ay`O;w|^ P(%Tjގ,' Zt4)q;-d&Z=h/CD3Qs6mэ4ZD[7jv? ,&"NvD N@F+rǓrDa"5;"_e#է\q-kW݁:OQ1 D,Gɣ4{.o:s+(a!9�v$YΣ:JZH5^3?B{w?J5u?\cp~.x^^@j#2r8EIg_`g3 i]xȘ:#h\ƖY9Nۿ&6_ kzNt د15f \s7htL(_A7RXc;ܛ73qlp?y&84xNGENY8R7El;go Tm ]A6e\i#sZ`㰍2EZdRFc]el!qwL|ðijt+eDf:X$/bWU(ecR-FټmP'lTWyPHj ,P8y c16xTyxcQP yui1>&oZ{ָhOkclgRw=ia9oi[ɳ-%ul0TM6onֶcʹܶ>[j,3wqqM7ѳr|< ~~~rט\oZ;}R]qklOӛXbh#x(W)ɛun(_?K?~l#7=Q?kKfSɸn[<4K@W;�( � W!^ v�Hz=PR %;>nDl=�ז9Tj޶vh_C}*�Y�8ڑI p+%*P>j'zj0FCK+i c'hMo!34pu\Hs @1\&J,{݅@}Zn**OC`"TļK9زo+lUZ[O#lo3EYbiFB~QFp-ΧׁO?#P ߁(ܮD*Ƨy%[-^%&g'%Rb?#dely ʶ&r!RMC2VSZy?ͶWQ,l/L%w}h a6N6˭BܕBˠkn)i3�Eqq? 6@p*gng$9nX;b@'�;@�L0t! ̙a'[\Z; H#3}S{(zYyBa8h"}4xEG'�"t4&" R'' 4'5|sbA*,$y_S `#UL8'*PEq=1Ey{ZbN]@?01 by;{*B5Zjt&4TEj^d~k%S̳<9 'qx%΁Qv w | @{4w^5ˠ?qϸ-r%QT HcwC3nFCm rwHگkh\B0"[dMJ=LYwGQ !Y*.HDŚ`e2 PA[8(eI߼hU 5ӻZZDe֣ĕ{+<ƄgB$"AȁU Puكbus+ ؆ '> U[A'p  5ŪY_W2@wgJ]5K_gy${.bB/?_"b~]8gUn$bՄ9%6 *mp&-J~WͅLQǫ\hBV;e@?!*=EE |8l > )%.$@ mHHZe  W( MIL`e@fVQ�A'BP`/X{ O,lRzy6jcPkk2X BɚytICuaW4& |uOo[*/q^} R=`n)u=+kH\ zEIJ �HߋʚoT}0:SH&HyWAé5L V^5_$ =\a�\$:E,ܩNVP:s{qxwߊJ۳�V\|evJ"dҽ6ܼu%u�PKd)HwZx aК#;2hsA( ZtZ+*Z5$RQӅNz@`~E[ LN0U�>ݫ`Q%FuN 2 1b|B|@J 4 arqͮhmvr0 h7Na~ Hf斌C\a2Iu$ĸ'N.a~3==P5 ?=Ls%Q?`$jw4z2igt2^4f̮;M. ;wүwEo+|ΎDKwһ w.R[og7|t5yMݶǠp v^L_mC/٠|]@w+&3h$]0>Gb]JD~u{.ETNMoaX'iA1/.?l5ZO;O. ;^atbX\l*L7ƿ^Q >:-D8d4[Rwˆ ]*tq@5[u5*'sX & ǜOEye r)U<9…L<&C߆ݰ7kJ58'bQI8\ I/K]QWp+m+HUYۡBIŇ1²yDgH夯mМȑj'[1ꨟr#gǭ:xl_wb4WLYE@{Q:T=yVS*5AjOI5^JNT9lir6ᕫzaυ# d/RӵpI::ї%9Ar`Y6)U)=bj|]<(uRÿë*3 eE%C|ItSFpCt11nI�WUN#h`KmgW'":m Ň& !>ؔYK$a+L.5? DM�T9ަl~!tQ =™y|k`~u5=v]](ڕp;AG <u˫:c]nuP6Fhr$  :qt aʷ VB>߯e\]>5]2< =5_{1;W?|UYaxgdd^Dt%C O:<5a(P-2^uTUO8B �}:*8\^Pi/. BJB>Yk+m�za� F W6a` z!lI&F뗌#X/`D^ Xhj}!i y^_D~ iۆ Es&<6Vp:W4=L<̃!p!8AV#=- v1pe}aSSC+Ȼ *v7r+ ELB'tUy}0H&Ce\3!27Q:>\n]+"sJU42 wPzE[롫 {ѫSTs A(=UI/8; 7-^-X#<=뮟W=JBնF5Ȑv %Gv=X&XJ0^yBfE a3Gn+lZB4'hAoF .\=2AKcH8^R|ۑL8(6hV@ř d>#c 8RY`uA.>\R3�}RJ PφHɌ&0.cɻYcux\u^� -o+Eh9ZqeC%[s-612}Wt6y 'a{WՇYb15az(pM'WU-/ieЫ>¹UIpdAZ J yZX·Ea)ͣ$ 󇾏q3$,~][$c\~Lj%*JjEDiO- PAJxq|J0! £ԋE#tQ q\Anc̏bLB;B) ehzz.:}WŮ.u/�z�EKvN˽u 뮏oeWTz]u�)%AygEyLa7bzN"e>Q6l&pXV%'-h57:*F x mœ VqxBքЧI-]!)uCUIyQ@T++zls>2BBݛ #~oɃ$(![X fuYRP0}RX%LMGl&W�W/55=MbNrM_~ف5+אRk p4Ƈ"klZ};ƀsBIZ\Idz׀| in"VqpkzךkJx/k=Ak6UM^;L!'COz8nZ\cƚ[oMuC ְVgQgLRV_ sz~ԕV z{Y)k>k@Cf֮!^k-*^Յlr!VY;1 "(U(CѣC@'(V"f%Z~_f^rͅ-~H8 m[ݔmͯhU90@߇:*En䫷}OBAL$@ؒ'bw;e*3^\v$: bAk|g !1z0%П6_Apn88ק69&nݨ? w<Ѫ�ȏ+Q {᠎bJ}ڲ3oD?-u Z %&]Om >2o{ၲ> :>2ELcjk(oF2R~nVe~ZvQm 4t\8pR4|pQW1#>FxBT/T},ȘI}*p-}!aWZcԟo&?oףX9Mơ;,&YbcG7c]cѳr,1>/c�h: 8WY #cgqAeY,69vј;Ŝo^SH~;pj.3ęY 2c88y&q&ՙ'gb%ϴ(;t&v;>z`来gןrg{bS7j74;~7&Ghpf+(MVY6}bL7OQs=UcV[M<~vscْe.O6YٜΊh3E7v6l*?s&ןom,9GI1?aipK[)-rFqpR̶.0x,'uRfzᵵ}}G飷&> o3 k|n0tEc RdY<O%+j5}M{7MZ=:EG9ϾF)x5&ʨ)kROo~=v)6//89q<{79^gQ_FAz'ӧƨ/~ F7ӣ]7K)QPS>yTֈ?7SmțuMzZO?tNO;Na+MvKȓ<NO=0;:56~jT'@}AWb4aF]S>2G^OөZ:�kd?yV?sx~$y=PZ=R`*л'P'Xa,f@3yT=]p~5 s=r6<z@l!ݾ7щ3mFu[*d%V!G<�:H{HȕtP7Ma�<>ǀ7|+e(CB\?p~?r x?co~@+aZ#=+ˣm/Obx o=y~Y=&?=-/ u@LӁ~ [\KYzilrG'~p*Wk[W% ;~<b/Q?9_2?دHrodaq j񵆾ٟa2$U+p-CZP?ڜ!gvթdKס J�X P] d~wA&ݖJu*y(T}0em+NPp_8B<<? o#j_#1ګ*^1�g h*u.;kDq0�Pɬ89n:_Atr~2̬HX?͹wupF6:@zX\"G^c )jfj,mh8).ur1]L@q!FLiI.-Fs?�(Z3'f8&Wyd(*Sh+wn~t܅4"T3]4ߠcKّN:WrߠwzwCqD;!s-9wnsä+"ïmɣZN \.0 ؝h% UJC chX7s &Qr?kyr4v"y}لqt óNv荔w=$j-=k@w*KN˲4ĽO$jH߮e-a"Kx:8ݜY-n $Fg,6fhxBf� v[@F"V&᪉8h~OY(g(ӽtw)u)SSU&x<BvZ J֑0Dt0]p'۽|Q('ջWQ~Bhw+Mvs趦rΠ+ݹ6D-1(%HFws#藍/zɑN<w@a/)�o3Nb(4أD�BwǏ'* T`{,*|{}߆^߷M1p|۷>#Nwm �pR"F3t\)q.hv@k�@xiuI5�!q}݃bDpmq m^ziJۣV$8$гy7|~y~H~~.E<;`z�?c.txIr_ I:.~Wܡ S`y|Q}ިA| 4*QD(o\c nubIOw36U՚,:3kU, Z9Ra|ՅQ'*#o}-DZ:x6-:<=ui8b o˼{Q{Z&Hs1*HPiɏb}1y앏~5߱/]"sy6eGczQEzCgHn ̓ @3` HV@CbP˼EU@=+dFǁZ�@}H%`UxBWYr(1Z="x/ �Zσ9W| ?v޺CҐgD`NH@,"9MDeau N04#u\$-WЭp vu[9�E~C|L`"�\ -Ћ5@sH%t_TX%sĪD 2xy<bS7=E*e笪~ҳE{% &d>Pz#t౔y Kd0hW%AQQr{{#GiFwp:+aa۵:�t>s`#> �= ~U pY|/aL ca�h�܄d|W9_`H�[kɒ�(9bCOLy6c}$C"X&*�=ݳ�ZC ePv}(Bq+$P鷡;޼ c�OaO VEReq٩U-='  h%wٙ#p+@:#WlLB+r0`/zt@.QCI_@KܽB|~GӮ e vY4eSh+Z#jO7@4i5moXk e3q il&dHK uA' 0I %vpǎ] : )WA�{5cH7Zp[OO׎0:RE/!wIHzmBז뾟R־^# sƖyDvϮ�Jϑ & +L}㩭r{Й؟_ZB"eVtI=0u߱>A-jZ 56. >˲!qj�frP\R{/|e5Ƣ ҜGaLp3SGLڌ!f%/,tmq26..9R*?O$XiVH35%,l��ѐ@ rA8ٔT򊴃\8 G-pyoʆbs;VH+;|u^_= ͳ?{mNTm~C! j!{=@!ꍚ#RNC] x8m /dRe8q;$Jf(A�(ɐg<R";P< qsy` 2"<z*倔}5# ֨/O-Q8{$Ac3lcihp..\@' Wm\dιŪ E/^9?$ "N/ .jwqN%%ą/?D.<O)83]>NVWS&,�mU&:x+%yb*]1qE%[=ЩBteֻTW8ŀq_ }#A!}I|آ7WAY-|(ѣ[VOX)$yʛPiQAC&�~uE)ދJKIp�#B�$H�᫤ < '\ ܾ҅PPD@W|I�=5B��'W]Dҡ ޥo & ?p{\!j>hC>|gW QMY50E92"lÂdA}<ؑ֕A.UjեqM A!z:%9qV+8Aqm-]Jv]_�܃m# ;պC w;0:PʯhWFaQxMC&$lp/hqp?Tjbtqgf\)733w?Xr[Zߙ__kc3iO,v̰žŖ׭ Ԟ*hr 4xMdCV)l.G"P#)pRNA㏓*seڄfjF\wv"qQTeJ{k3[ c<SVs弒vhyDy[7x!5KzAt�_\54�:<K{^C[A +t{I'C5iY"q:4Pޒ58׮{-]Cq1 HՊ^ /K_v iʹz^ya( b9YKi KJ{ǝ>>blL}Fo}?n@76¹ׇ? "=ك37� D`x0v@wE],h {$ǥ`?ygbHqk+"ji߂nMȗ~0Ghm[ Zx.TxhW8eOW nFc3ny6<LTU^KV$^Yo3'ols2{=δd F&K7[gnɨON7 谗2= a=b&톼t!AlU>R ZL 8.! J'I&3 LzʼǸ';} `}fbv2pZ-cAX׉//bA3(\-At.>ȋ)Zm]F89*!=XU͞F9#Zb"(~}>΢"A0Nj zs }syH9::X^z*><G;+GbnS]"vkYh#Zg44gh% YTZdb+U;Y,hvb{&=ș }�pNC= Nj-C]*IV]\xD*2S}0w+J!0"�) 0{HBꟵ\@ X鈃јzCHבvЗK-%b?YQ_]hr{pi̋kIt#܁L')ޙ{ Ҡ(JtJ&퇶"N!ޙVt+~<BHउ"i'm5#<޺|0R J|IvRte+#/&.=by'[oa.+}' 4jYoJrkx&ז:X LR%$K>ܗlI\PܓLN,v`ߠג^~=39=ngl=p{! %y$)WL_*%{j+>Gן IБQF0FWS_*{z5: 52Unxq=,gv&<s/;fFG޵gy׭#=3GF#'j=2C93# 'GLvv!#i{$)Σ333?nӶqp~~oPMhCvyJ) h - HN1jې/NN$Pk(cϟx c1zTXb%A 95(ñʹd ð2?xtx*Vmpvyju>-o? [ڛ dϾ}C9> IȋN( xL(Gx N<ITf[d �!;P:h1=翩Q4Wuh{M5`$pO(;i'x޷ asu#MG8!Nܞ9Fl=pR'(yx{ OFW% ?)U/Ij^ߗ0) ˦^p_U}E Z@'7~v rwmoC(%,Pᬾ " +'ԗye}R#uiIK/̶oEѲZ GF+8y 9JO zTwc򶕀3+dص',bc4z@<Y{|ߒao,hO':GSw?"?Srw~k_ODg8>T*zt3S џ�T 7q4!Š$2P5- 18s{@6a $O͏�/ -9[OY$Mt':>:Lk4K7E1di$b<< m`wCz~x:@wY>^ޕ~/ S#�̋^Kc\KWKJKï|PseQrP5{"Bb)Ҵj~q.18:9wr ]J2,y]&_u}温˘=,bg$FMa0G;okOb?9gG(9 PHIUO m9@ ptzad誣bX �=y -uE0 􃶜�$SSɧ?I33gO7/l~?cON8OO^ղMl_B؃";ِ&v>$-��ÈjSm'JEأ6}|F{VK~ҳg+i"a)j`gS i9-1-&�GE)jB-Tb~@aU.({Z@X_B/]hKO`q,�P1\nzlt;_+cw˻2p0]7ھE6I7;p �D-A�A[Դ�H<gaHZ]$Z3{BG C|wdN^EԵ2H$p1Nر Fk}wwcoWrgSߥ$f (OZ wշo*S�T~@ H%6=Lwמa3]yF%3!5r#3 9]R-ddk:~#H鞑gB`&-%˦< {oϵqm^LS@:AVcܩG]7�d_5Wο_MV0rRj>8E`$l)1I<ٲ1NV'E;;h;c)Ҧ&].w. [п,\u%�se: nUmۯ@Bܸ]bvC3V{H6#Zo�^Kd dr]/r�ĖeҷG`J@#zX Q.bfI,EipM/;t=Z]nk/ؾ`?طf[hoK5d__;g7Ċ}t:Җ0m@ hwړ|j`n!]pdcnc޵7b @`C]}߬m n{FcP !߽0>F6'6oָ7"$s6$nye ۯxn}jre*uCoL>;NpjJK﹠Wn*P5$fZGdM­37$lB?w�%wf?bg\kqq$xcO 9<LRw -o|sy!B@@͏~C|S/#,|~C`o^GF ^$z)ϟDI�;GvqOy9X4#�y w&v=[\>7ϋ5G;372{<;8Uy׫ESLj.;^s#6a#%q0f2-q\gzL?}o\A߹/UiRnLVN/; Veɪzк9u=ny.Лk^.]s=AZEQ\"^dkV$@f͸CĖV%A#}>sSxy cˋ(A.]#pʈJ,V{|᜘N+U7-z_C.#5#FMJ-LQMHK7zTZNy~[^l1J�Ai@?TϽ� 8>CHH#4@%lp�U CWpziVsx'�(`Ѫ$xn�Wѷj Ņ1xe ǬneRfzVEʾb۶g3oݳ}3ݴpIަr==Qv.ڮ^ v> ={!4P���IDATַN^Վ+J6~E}C<½SUjs@erҘ\T"'p kJsa_97$I`jd5D�@4z4i<UͼZ<u/ť?oу%'Ϸ5� Wfz*9ZE \`TOW7�ث `%lXgEEUpQk WoΓ-^c>{APy޹H|Oz\uXmx:ٸ?u8܊S+ ܮy8{dN'ܞ\Jd tm`-vT4 p]ybm'&s`Ұ/nm.bhG[fuj7Ś1RiL9۝ؠG|{IAwRmG?I^^!1dBiv۾vQ^I_rJd!L^$'"M_$O l#@1Lf|nzAyoOw@nޠF9++Up^972x e5Ob9TXucצH5Ulګ @ąJA0ɿwؔ6 wJ�Ty�%`S%ي�?8 bj"9VL㼕'ϭT/*wx#\lR߇˸0li)!RN_0}QFT j$S^OIR)7)ig 7IZ$e:VԞ G=HG^#:llj%z$H4ONPzOjD!C7)|?U•O ukpj4:o^唇TE`Նi΢"b">Ou-"D-D[l4xž uJ B₆$ VQ,.ť)fY4LFnv`g!*E D�2+HPoϭ4:!x m`+!pylXot{z%3(4+/k7rt; 8Vx* lHȀ80%U6�}pOS88bMup)Bom ]9WWA| Mmu>`T}&N;-E$3]Ů@ݦW,PM badahpnzgFf+1:{" Kj: Wa Bu_dP+&`{9ou&Q ƨDZ~$FPa8-G!2D0pyx:�u[ǫ IS?* "zp@?K((]GƁ;BkmjG"E y@Ho>4R afQӯ$ʻx\lBG)I}?g =Oie)2J*# sj.&1Yro?pwYT\G۠kޑW+$=?XÙIkbF7|K5`M) =a췾ivS&9{rSG|ٚ~! t�yp)=b]PCmzWAϷ_;k,y0!:{NGobv_p7,Ƨa:;Ze+WB[�cYzV9 >ZcM #d{1.Fspڸ2G|͑9*ZcnPs((|G<J%޷ܜ>GkA-R3v"8Zh-gs̑m oxb[/kB[->wu1Tf 5MoN6G} &#1G3 O8AH }A]e6^" [Е&sJZ[D78+(vVh,_ExNg5/RqzG⾼) G:2WTTz‰ZABdvI8 dia76 4)<V D=<&T5aRL$/<U4RN,+AHk̋9ҏd*y{4C}{bmo◻�ɺ(N]jR">9 aη @!jA(<x`y J)Sj_32Ws|2AmN iM { 3wO-^]/�<’sЂVFMzZ'WZz8UKsaoR&}*;}H/hRǼP}Ҹr'D+ ,TɭE=uO-y7)znqEnmD} �hc@pM{@@K{j6c>@~`w5c{y$ohM pZ=EH/fVuDy-]N.a :v8TOv|ݯҦyψ`$r!Pv/L?G>!r1xh#MnpO#$H;tj:؃^*vnz1]~홵Lw=DiJLdQ`հӍlJbZ]v7ݿ)%wd{N -e%ǡ|DKmj!9$ʬS|F$~w#.*}{OMYm$n]vT^q䙥ዑMMD+W2>wn.~Ow>Bb*N pdwE{VC?3'暢2/D >;OŀY/"4N PbH c/lٕ8a^CH8/k%}QcaC=K4h4ӿ'Q ^ ~cnk?(`=HFNKggOjۋ`⑶,e+'38܉W`Ҏ%ʊ}fXJgbpLYE͏u:8A Ʊ]" c攝`Yœ[тe'5G $II]c'{"{d=#'_<&9]qNjGk=g5џu?/(aN?י"Iڅ_w|CqQ٨IDЗ]lϝuxVL:�/ 6r~:oXAfj2럈g}vlME^UEƃC�͵Hgy[)V3@tHo1H8^ DІ:WˉpBL8lXխ,Q`rz@!CKp莢"zQlEOGhkm+8㤖 }l&T>ٟY@.ȓ8yyc[ >t"_ E FQd!LuT+h_7(dR*Ws3,1jIOl�y,cI~ A棠F'pf]b}.O~zx"Q|G6:rY괭 'i:{e]c4x#rqpf*e14{qO̾T&t&�h5io3&r` 0 'rxÁ.}qT!;v9c�tk93wA;L@d 9L!'3ZmNZ3+r|cϿoD|^k4yv9 r~C1~o P굚Z%:v/y{YN Zk@ҵ g~͑{f?D|t@rɚgL5Γ%y![P'pߴpMWm[J|%Ç' ohM{sxAu rga?2]b%jėyפMc6N^U &Y;W󦒵s hیg/n`EK51a}u?Ix FZۥn3+ˣ i K8n /7.pn.amnY@»tnbn ]OdWFBαIK3D 3wϻX7]war'H3GKumn9Pa!@ ,|vݐV+D ߚίCB.cL #,ꠟ_:z3U yk`μ1img͙jCp<7*O\̷!W|yAl(mvmv)ur~,p.*zL/BD'kG6' H-ߴh hMg*b܆)1g;dɝV޸uB9:lOɝswv>Iz a6U!>~H>Fa.Tη!_Z]S_ )pΆ6[Q}n Uز/jYؼ@&s 7To=,ԉcY U` fq:'"p-$@Bznc[u~y3h6}<s)A(\0%%s,d-Шm* slxėY4;Đ㘇+y<qL0챹Pj|W>.ʬ{)sǧڹ\ 'Xիl0&PK,3<@/]3LNG%O;V\g}S+:s<^9F嶓mOS3;+zb\)z4`{2tlԑTE>^<҂#�Yu0 fGbU m =BW ڃ24Սi6_?5tW7| C z8%ڑ~ŵT�J'Hm\;˷2bY 5u_nY Sn hMdCd}uortaMzO4.7v;$7ڍѿ\lr/OnIl>I>ۨ߬Dw77 S=l47n-?1./rܱ>vM׵;Ǻ rYkڭܿ];gkp5&YYې\o7%<;O7 ֭cyg{O?^;IfzIzcǿڵF'7A_cq )37fo/8\k-H3qv|nR$?wiֳ @| /)%B=H�$A%[+aTog~x=q�2sLzqqʻ9r2@lEa؂=hJ0XsrQ:6K֦y;kqpQ#Uo{A[\@)P,P?^zggH"e^le1OX&KzUyvETMOڔ6Q+~d[9ҥcqbSZU_I2ݛ8w48\ͪc x{ %27I O0}-H})Sy wZЭ/PKUns"T37 m\Pql;``gySC]U$r9~&@sM`l &pDX?p] \^]mʍx];AKI' 6aL4!Tr^k&anL#&2E.7DJ@ 2!/K|g Wy!t`t*:qKh"U1P� "DUT8TS:n+E_"E0VOh{Aū^jxBYgy+*Y#fx5_0]*KܪY1uV<9f�=yŹc %Ó‹`pO+g#B$``<Y]'RKpv)·,Ϸu:^ϻ;th OSvN"�W8/\\ w{<窱frJuU}tϣ*I +o3q+ FC7+,l%+A%G�,/yi+ qe^.PpJ+5ddǔ7h%4Sf3JW2 4W(V:le6$L//]1@ r`Q5]\�.*��\/;py0U)?:9Z)Z^ 3@ X^ó~ `"p;Y*y= *ҫ~VRv$q*6kTpPCIPqUy`=\͘`lg{5�<0A2"n OU {,e+`{ްBqYvwt)rkV\ZT[ BC0lazhʜ‰J${ó8.ȅ'e 8i\ٺzypC"m{'<z n`ڐV\*z 2+6;~DӒHC6g ?I_9͋KJ8]E^a' \9QNac,.CH~ƬJT29; VYr�OMQPXL"f>C;(r)jUŽ&F#vV@qdo1>j.)o׼6h;+i2qU[Ql5� T3aWfMiPkr h0} lksǡe '69u;�) bw`x2]J12?xCں<6NrEp_fOX\fCR=͎^~vlP8KE'_;Ͷ4,7IgZAw0pjc'ISvpOҦcEh8]]mڙ116 sC!t<WkEM?/=2{dar.vn �1)\ HJiI[`:_-54�%˖\5) سiT8+ g{VWWb7)b�аoQ"<$8ApɆ (;|)Wӟ[Z7 %i06R7Qlv=.gʥKJZ�JUё%C>Y%dg/|X>rS |i4<Qޥ_b^??,+"1ca 'H+;V`/پi=SfA:hIIF*h_L{siL9ov{.%AV"$ImK;ITCiCX郳HII(9h_#Z)Iʗr1GZ~9]v-NC;H %t %ӪD8<^ @i�gKI,o`#4Wĸj\VαËyF pZlq ᇎr4VOĘS>꿢zd0 iW@GFHS T3h 2wZB0zCmW(.ir hS6f?oYBp<p~˟)\/3VL9C*СQ^!cA�= 0&m+;!\HDztPj "I5j+@[U0@!z~>ȸjAJ(p<=/ :õFقB nBψiV EraG  .H8v\&K=m؎ n$ >Am9}lGCn='CݥODлt~9A[~.8};ӏmu݉>r߮sI8nM;LT E^9A U+ P%KpE#W+CaU+v5r #W6A6�UXM 24 tC^daOojF`pFPrE[ b e::*R]c%?bk6}" `x+ 7�L>@̈́e$c';>DLݤVҴ'ZIJfR\f d>L&FLkMA-[e66:s@Sn14ԒF AcM`_'wn%?N˄n-XIS!&jlI0ey䲇\_2~ ,:^/tr$k (e j5'EN!S;h ֈ=]浒kگT[C`+PNyk5klZsk_|Z v&n&qobyv=z6M APj'\GMOm窾y9=XIHKLX@Оm[f| C MݲȀ2)ٓI6LE8]\W2v #\g.b*\n5V#$ yT7uՂо@jQC E*dCC\&Cq3$hXXØ 1C a!ը`$jNU9 ol+byA0M)!㈰0(gN2!�,,9ݜ:RA.8#=dVxO{:OAJY^މ (%=;c!/M*<뚧x(+n Ap}!Hߗ!eʺ;ྨM܎#`>/Y(�,b@*İ;8J $3|/ˤWf>0eU{^YUtGz}!5hqf}b̚{YV; \dU{xh|BL(^뼴@ 4z :dCZ3|�91yk&hp>j PNr2jF(J\̅Ѧw6#4$0GrS?=3%r?Kw@ B00�5\Պ X C8 T9ukRyrks0suj^r#bty<RfέA3^Kr^]w}q|&3},1`QL}@AFzh0*j9ݦ_Y R&ʹGacX&éP$ޜaw$]6�o.V�6 f1ar+KZ3%y1�y^ <b-YaĮcvca,kYN<벸T<ǢiwQa9Hg% ,ouKA 4֙o' PO#s-~v~.$=J&n3/HubѻwnJ8wm⬣##ऐNVt^z , ~N:"?c()2 ԛqx� �*E{2Pu(u.l{@*}e,3ʳS[FЪZ2Mvv@2/m+We龤y�AiCZJVOOo>X.rꘞ<!j'λ,V"}A!01tSz2*,}&%;ͿI; 0V7Hh s㫒?($U`#{:R胴f? o= {>" |ru }7}NBWD=HAGt AUrE}w 5:{sϗ݅ _,ݰel2ke,:ީ`g߾mԃt/hmkdA'W@0 !" ^yŹVr{%+zVooTH,V]j4kٵY}Rd5IWۦ6gZ^⚫ R.M`51lHDoLoH{)c&֤ A#'A:IZJu\|M<!Gt0I"rK #}۷b}n/p?sh PJ,lYOKnIL2Nv@ʥeI<Y5.&, Y2s W:KEY` K%O3BE3u<]P^oR]`m_'*9y% wn.,b.RoA: E�tDD^\G:AcpB}=Pl5Np-V4 y[W_�#g#\\ ;=i5x<KY2wqz @֡̃^yK74j<Vr\K?�sj#q̾Xoc^>?FDR|E.[e}Q$~(cF˖ջwAHg{?7/hx3]K&]޻me9/3}uC)tV{Cq\`n;{kYuzty^ W̪1ίɬ9`+^ug 4k7vE䝞$xK{*eqF37~vEZzkY} C< !Q�|f0Hu)"} x@tБ2[( ~|588q\͠Ƨ4P'iα;��"SGdh ~CI:H1NZJNlj'+5locl+&2B_w:1ƒGпB߉2]k1_4zvjӵŶLm\O7nu۸ c#5UvV93_^׊꭭g/5>}r6?5CsWB#Q3aAML@#9=fMZ&l>';1OC3sJjYw ?t)s(׌2Ɓ#9ё~?vU1>t1c.("=j< * `Fx>"*4";&]I�:9{*W pJP?c@$@PM\qNyC)70 -%RGN<e Jۄ7e,8@"+b-^+ZZ*�zA3w|My^m,5z[L[yni&-VU zQ`V}Cau abRX)+cT-;K6Xޯ9N>]Ê8/ j.DW.(GQq(fb1(GܯEx>r?-mf?w:נͯ-h�7+ VCPUk" oV@D$*޺$HJ@F|�>h]D0b�!n3E< 9<6ɦi(Vyn[&(g_Rl|pt x] Ev3t<O#"Uw0.G�~maU8R)\$挪0N�XPFXU Bz^Vvue?(q\ fT %O絨n}&c}Gw{6ȃ�)qu_#OK "2pG~D(0 ]-~x7NN;]@H{zHѧi. ^=x4tX]v̀.tStkL]6Ëw]|6z9빙)zǫ3}GNYBgZ@/kdy=.}KNzVFA\}m}IJ/:ݬB_(4.itF!t@�]epnQ!<3wªUnU 9r *h$2m"@ٕҲ�հrD `J$@"-πb(KxRW%[}.Kɗ:r,_f|W,u֢X2}A_ouP0�<#SUFT߿@_o&mA&7|&nб H||7njw$(|C׌z7Lb#൛np}Ҙ,8m 6xΛrhY߱1iS(˼D=v~kZu(5TphPd1PwNn:A!P`'R0m+`A4տI`'m_=+^9{([U4d8΀ h!~V ^|h@8 qcy BD觗[ rj_ohz yU+6 Ey&ݵh,5S%sݥ"Y�%qy2cbl֫u.!j�_ ޹qbl tY @Wt 8{rcAG)1= l}`9(Idvr>5ő6bò,;AQ nScɓ Ŋp-0c'I!pǽٱp{ؠ_dc1!mHf->B{YIOO qЯz!H> @�/-k[(ֻK]( 0N�Sf�%t## .$2%Ab0pN &c ;:-æ9@/&ьL,Fq82 oh&7z!39#zh!m蝱{3wt0WuEMPBwNq|worN+ŕC,.U�+7g=a!Ҩ l3hH? f>(]` QOҀ4TYS`X^5k`[l6i嫮R8a/۲ LTݼW& ipZO gTT//N{C/.J\1MU]lJ2T7/u? _{M%Z P5J^v5h.7Z 0m=Uo1@3lTL4x4U5}kYjP -z+ aOV =ey4p3^ T'{0;7�euLU9Y- ;IDx|ۅCЫbJ8M )e#j6p?P"6;,8[!5b)*\iJx, z 9y J4@BjzO%dM:sX{lpY�6u56zu56tUp?<W9 D*}!"բb`o)mM(dFbC{W|zZ |)5|A`%R;\loxW9W?mꧩ>HaY=翥dc:8OKuI`s_ض VY�Tm/6,�ht4B̈~ gEkϘj&>hj*io2K |@ק{(_qA0͊l,8ؐ*0-l Z=Gώm2Q0n,YQo JTzZC_ZBV ]WY!|[I/93o/A -_=:LL0}5E"0ktAC%"!vD&@ãp }5ēײ֎kH-אQ׉u}z F}*Xws;I#͂tSzlg dAZԜ;Y'ˉÃs ǹ5:°oz<%cVtyNxdRG8uyefU6]{O۞=˯PMdIYZZ)a)Zv /?>C~Ü zV(ˡ ,dv@rp ! P`'=9E/Wf1"k@i"\ll]ti!@q}z6yEKY3B"%E )]ȴ AtD:՜z a,$�8 L;P rj60؍'3@!4ߺ~ޅ.hsF~J1x?5OG@ %rC|755za$YwFznTns'H 0<BWWc!A9Tt5IơGt|5a<'Z)88/(wMgwA½Ѳ G^5>³:`,k\BYBQ9l=F}f_1%:`+=vV fF]&"Qf}VGFi �U@�`Țf6IEHAx1ScStJq"qAP6Gp`l.Ho4\:g �w2IIys C۠&e3`*|?^bq@aEƬG#=bDH1P 1$|}pf"n?ϡ%>M}< uumHG~(aӄso{:tkZb4nOclJE׼qs< g_qez;nQUo}]3wܷcoNv]WhtZS],L/۲ɼ,hVB=lmiw2Y0fWB/;.ⅬAzM0 ?9^뀖M O #Y�FLj wB3xeLz^wWoW-Roz{F{F蕽Fﰛ38%)=_T ~1C=^Y %$@l2:ۏGazH$y5!mq{6`FΑ)sXE9> _/7u+mZCaNm@]_!`|:ϐvD> sЗ41w3tl-ϐÐ;gaWNv7뜾AIaہrwiϐ쌲7_ȷ]o֞_=C~D<Vߓ:#?"?TdHG$8Y=J`yw4721#v͍]'X'pcX^o.C? :=uW@I $HYو =nX̚˜lֆŸpKVR6Rb܂C;1˰068V5 V.[s YQm]VǠ '~J͐fYn ֏e.)eٵ-ƓFi\+5G3[٬ ZoHKÚ|0ͩDrV.# *@⠓#!݈±ZN>p[N60?6�#<G B 47CO=(GѧiJrgϴ@SQצ\O6%@dzB2 b=`xz4$D|NPPGiA,Ѭ-W%�$ JA"anقT!?Ap8kqX" \ B*b/P2AOsVqa2k5 @\B6XªV(E sܰӐ̀$pO�(),(5cY lbHv r/:rYoHwF;,U %#<Tn)Spi皕5ۇ}&}}_ԠE!Oݏ9|so{pCO0yW}zЯk1q,~[5}kN'0漟E9:eQ?V_%Κ~mK8co삞3oN0q;=>R9j!l#e@'GXowd"iư6\(F3`e:/qXHOj<ݘe*2~�AL~2HSuߊG|ld"ÑHRH?\DB PE¡CBtB>0\uDx;<p O<ĕ:0 Ώ8o?h8JYc= �|+н~֑ؐ:5"Da<Kǜ1gΎ~yK; k?Q[ZY;#OO21 z::D< 6DNۧ%}δƵ 6DΊXg!GςrFrz>:ydž4jo7ūگ̍[Gd:PO #RA<ߓ-ӟ~s@c|OOk荔 f5',bPԈ6U�'E2-v(esS9\{4^'zgqC> +ˢ9�,Uw >={{gޛ|{_{[_ #|Z^ {{sVn8DQKT'#[X\_zgM=y9wss3YB&z986gȞH-me@KlM4kE6iJ,SFkHɝ<ATW7~#?m%|~ }_'bf :�A6/}Z4}W}lQM 5MRH?P�; .\_ܑ7Ev?3Rya:  7oJKK og.ƞ;̎XU,_!g&w|_}!Kgw{^<?beF\n9K?xo6?H[{W*Β?SeIUK8zH%J0J$ LR,Y6IN&Kjo7'()MYPO[ g @`+88޼H[6h=4lFƌq>o3^�0oأց5qp76o4g1ۦT XM3G)H*5a �  EܾoXF }b ݔI:QM X@J,#%:)zHKw%evd筺M!3eAKxn7T7rԶhp\>z׃2&&=__<I_ pJvdҮjE]- ӄ{֎og@Wl_wX?e@iGmDhoaȧyv"OEhЀ`*9/UjVQgv^Hzq.&;2R ڧKiW {̸yۆ' pm~b9;k>#zG/�Sjwi 35̔i"m&A;V6[ J$!霶䬅w^v׬%:޾rQAӰ\T9Gi5OȊU3뼚ozgMRUoSj0_3f)- 2flngVݬwAxÃ;:^ e/Ymf+vj<3Ve=6g9rf67$i~H-g(NċdT�@xJ�vMv �3a܇S$̾D Mo_n[?_7ynuV}犭99ϛ/l5I.J?gee? Y;7G>W9疹7ǽq@_f܋}7ZyTS\h}ٳJ2ZCe&%YՌl"wȇw"SfEuw, L9+àl#Hߎ/} ሌ~ %i8R;E.*/xkqfoc'͟k tƛw& 50SgrNlMc+\a|U,�lD4_=yho hztM1Q͝B;%[tkNꗺ#rAaIX\Da-~+Lr p(AQ lHзc! |Sp={ކ`6l8nyaC>*6o{=v>�tc*'�53-1MP߸IcA#Zs t0$w_9 a^r5�JJ5̧cW?@?q.~@ H aG}"T8{?MO6^?Z:W1|+ʇ}ywKt7jxE3cqd`ɣُ"l9fV)1``L~+e }El|="2gӃ5Yr(�<`B7T(Wr{+~+xcޠWŌ! Qn!0t//OO''_^;8Ft;w.unM*|SpBۀRnaNw_ww!wO:s¥xaV/dRw6vPgłW-%Mj\m,k5Ax^-vuU650*J5<2&m2?C^xn;<׍TN4)U_ќC|e:Dd 88>M<|Ե>K-HtX!tI1Jr_X[ɶc*w|~}+zl2!qE{=rWs}y(J!;Xj+өΘ3y:)rI99⤞IL9-!R5*u)=wlî7Bv]\Yi^8Q–ZiqoNjdoJ ȨJR^ŊrzD=bC$`h\A C�*QKJ4.jAe@d^if00.<+tz*dF"-vͨe4ܴ^y~ⶕLPixP]-w] z}d bWa$m 54"]d] VvT n`}N/Aݏ=D}xe`<PT:P'=4b WH {zzφ]' ԼkCC9j=p#?(Cdʦ{~=[f7Iy6h\Q7ks1||4�"DT3|.\=BV6Dè(MwyyT l5R m6w<D z++&63j戰 7z;zp&EPj_{>C]u^(唈*4kǛЃ<Jd-L j1JnݫMǒFZ6 a_]1/#,k-usHĨTEU&‡z+>U,)Q =Kn"YG~3n*269 m,B_ǡh>>\Qz*6BigLstZIT6 /'W C5H ndI= ަ|pkҬ4AWAft@lQQL�X=$m*ǯ?ю �Ó]%KOբѥ̈Jp*3Izw({ qu&(wF{Af5Qz{h=a#�cը^B_i?UӇv֝%EO|!}o.6AՇt'C!>1>A<i::b7M6Cjح }C-OA:vA8kbI !ɾɾA{cдCr ? CAf= Bo Cj tdrw965ȆnV@A#}΁ADA6(&bGG]wRcdzY[3{ʩ0nOi*ġS;PY4h x~u7pVꡆ4 W3+(ie4YtR㫾P5h *ZPKSl$-zb5U6b}# =91~_жjmGȍYM6s5 T+Y֭1>B> ?R H'|d=<(qg#裮Qe[/ք(*S9(-6qoLټQCclEϰbPō2c^dp^T%pM)MEuGɃV E jlb-^>E@(=DF=Hm`kE{a} yxNĉh-xТ :]^!<2"_$bڲF-/fyV.g;ײ#0III=@wdu»ha"vt:70�O�ߍag:/5Q(hzX䕠rz:VӇ}}sckҰ:E#�h#~7 +b\RQP71"k@<͋iH#!8NcZ @)A@0Y܊NjTdA:A�Mkh_$E/҂f}v̖Z>;vѤDQ5lGc?}6Tw)ԂKʋ@ x](uE:HuWnaBI<HG%h&RRc5:;;#ls;mqK@D8M왹XݩS}�[N�EUVW  _Qۆy*N P? `p()W :ЀU-Q+ۿwgW$H~;|sS]Ta(.ԩ�Q7.\[FT]Ivx ԲgA&jӷDg~gV 6٤4b(CFvlP& T5A:ztـzk9Zl\y9'=Mֈ��ԀwG,%Le?0o jnTxvkA/:`p ڍΠD{kԚ}O@w&@@gIIu|LK&S ;yn\8]Ǡqv�RTvOF*lsYt*̩<ʡ(ӕ%_ 8sY哕2N( p\sUt?{TXr<p wi{e#F"tͧ:K5nq0�WvbThi+ ۪+"Gn/u{EG]n/eÍ{yS2m|ɏ7p=kNɺW7�Hv}q:@ο\1D F^JL\}2hkpŐr)XhR/h@ PnwYCB=)g^7t -+tJOW})A|e% Zy+vRX:CO85eL12ŧ܍fm19Fm- zcbǂ>sҟy{*ΩTfP;F[wc`4u)z<w3! 5~!>%PÀ1Pֱ0O<&{V)5Љ]7s`߰| J<~r?X'q~U/ŮnzcQ輗\mB׺1:wkI8GC5 B4#@1*ߺNॗH ^,Qb Uv|KEU5t2ņ/J npc!(8c %n O^-?MFS}(p,�e[dQGiK)rwUI.^c'DV4}[/iOg<ets)VR>ڠ}>^:﨟+@KGoߐ^ y 6^/ ܽy̽sT|_ ?M BF͂}g/o}L=|^`ԨoI ݟHᝣv߈Z,Ɲqz\�43yʶRcE`gׅcdJ~@e5ځ�#),|?!7[vӁp0j#;P#J&el0kpl0�} kjS !.VM88Ao^o4C?r 9}gЌv`sеU7Q8dV萗s֒G~zsB#魵TPqn %upr^>r43 ^o/k@΍3ڛt^P4l{ y{ݍ^!ii7ܧ|A@ ݻs/m^Yf?mħ#Oq֞{,0WmTmȋZNS?T[?޳ʹ^LpΉAJj'uO:qx(AVs[J`QgV. ô�΅Qc 8bpD \ (_PLk$Jv\,[ SHB<2E @ńƍXHG&cg" d�jiE@<PP-=T '?xO*$%iXҀ1YnDQ7>HR";Io@/Y^# 4<uS$$FwM5Rп}'צf&SEдF (nHZKkN& f}60(kZSP&5 O ?aL, *=lv]9>s)vhkY`^wYoy[ }/>P<\\7r;)nt/>] 7|[q %0@cGl�AMv@MGbvIß9 K*dAPkƙ^B� UHt1TQƀffaPD`YDLS6 _-8Bbb�1bBSHiWȶ" SRO?t7<\E R/韒�CփH:\;[k[}!APEӖ.,Di,4/eYcYy|63RE!PZYqG׳$.{vq|QB5~9( l2^0MBB%2+r�B_)@.:HˠA/;f)Gd.ie@TDyK^p;?yd$@pҿAMihHT6$hlw(Z-xv"RbMB8PЋBtEPa? 6B�jGv).}fǀ|j^rQIcQdg~5J8{�$GJ+m?r;*@PJpx>"g٠fA8iH��D#̿iD! 9凙^xfN09�B9nKtPv@0 H0^&�ZF,S,\%r8DБFA7zie'߷i;733x\kD}ܾP6P+ $x6=IJ,ig@&@3b>E_9 A&ր3dC5�2P(; d*\l@Yܭ5)�>! AkЃZ!5b@H tI#!u�`  bg, R 2nC7=>�- �nxz6P#0f6ET�}͘rҙ@C21cʇup 8glT 7OǦcr{? 7N@ C)hlm7C֣>gSnkoPH+z~c@R]oPb}=͆S=mZa^`AtQ/�J>E_# w@+QF2Q�JpԏC Gv�4@|XC)hGF!@B q@v`S_윁^rm~ Y>?Vy@' T 0.Q4:@@B):A&0:MQm+Pޭߕہ|2;ˤFFPؑPH ߽OoQMGj@ L0L;k63F \m #bB7C &} žv`+b@'W�2RL32X v}:颟΃R A(;~{~H-)w2p0\0ljJ5I UpD(4bA�; QN(D{\]Q3B\^ bWRug*5)AC[UyTu; %ɫ*JԶ j4_>p* ʸ"3!ŁTN0wb q=_>zGxۍUr%yg3h| ;"]:NWi=b]T%P.|vs+JP!A#/iܸDuY)\9%sCJH<@ҧ* ӜWhGBs[? o- g Wnw WO`|]vIGڕ ~0ts蕩/a\ZnA@}{x΀pr: `p LZ�_8:=r1Ĺ͹j9xNksnqyI h'ʯyN9>_sBV�@`eru%LƧ=W5'\ P^"r\ly絠S3ppe2T+{߹DD4Xfyɤ3AF <_SD)l("{C4«m:\]2 Si%7c0zK 9܈`n!jw�KZY(t>OӫD MʏEXcKp8/9F :J1X4xd摩ɀC(~1:(r)tu,jf`[c\Z丏]8I K]b  ȯ؃-|, FtE&:2kJZyk/hwr2 uQ #~4ԧ8Ft,дZR}SdvD^f KCXͰQtn lNbl-&k=p7kkrM LCLw:+$ S-GU\>B,7#UĤZ B}EޤEwQ].E&-\\~O9M&`+3.lʛ폓75GU]L7KdXڼftalE5Fy8% &F z9{?'oC-oN^4%mǵqq:sK/o/E/.׏NxҖqFB!R] gq D_xsi0@cxN Kc"]h_bE:hp_`@'ϐ`ewm;l1!)aI7TLĠZ#V71.ҵFKk n MekC85 bXk_+Ӱo u}mpJbZ0ײk zàmrc*V,9M`\w[w-_e;mr(󛿽gh 0,I¶(o6O܊6k[Yo[@ˬ5fs~Mif.Z3i58m-ǔI"\_JșL]brblc#m@;i/k) R�0ONhsiDQlpG蘳cF[Z DArֈq8$[5' ҇(㪮M~o&)>;cR7f4^WT\k\6Gp肭c *([$/MA+V6F̓NeF~4Z<5.#"e; e- mt?U*ėeLx $^2}׼ڶ,;")ІR@Hףt73SHq1{g1ABhi83"@\X5&tfbk<"@_j!&=(G|nT(iCo6(  BM&,R>5Y@,,3_gΑ WU?tV  YU* 2s 4vf&Yz]J8w.jEk ` ? ~`FQ٠=%VD6[h ҏdȵPk ^bj"v8@G6EMKÍ^^4s5^Lk)iQRz;@^|ؔ-AI)4rJSetjfiǛ52S&ꋭգfThe?J'hgXk42p^O`5 =Z=MEZmD6kAkhZooU#][h[jB` 0}Rmz@Ks f<=ψebs4}tBey]NPiu;H_QW "`|v;w@ 6}x14h*̱KH4i]2*7b82>�VvbHoKD21ʨ[$bwa=D%2;  e/g�-c)&;L2vQD\�E1z[jv-> a`@ϙ"U�FPKь\cϳ UkzD&Շ1 90k(AAe@aǹuOVP5{BS/ i&(jR=IQNmfN/ "[*$C$:cC8ގ�Ch6_E%pIP]ZՅF]<&\dc^ q8{g8OD'= 'I+' =2A^eǃSP5z829=^̴<E&OOϿO;Oo;Ne\tQĴ:zpÙ)8M 49M_-z˜VӉSiz)pMS4)w~zN{cP> ?' yOz*O_ \{BO%k4+m(k`)Ws1XyR#է2olxg+.#S- ;ԑ A6 v8{Q&q/җ@!0;R�xBPm�^iaݕ�V �A LkZTCslدo1A0n=r4wų59"GBs s82U.o7JV:ىqvF.'OñM+U-}N'v7a&ͫv�?^p&<i^p\W?2PI8�28N~N�Iu<8NUl�'9g_W$}\;�p?!G̓ 7~8C@Dgn]$>*uQ{\ߚFJiKƄVhr y d޾;?J2aMHVJ4a9(_EnG)|4P�=bCiAS/g:=ZM#qonK�]@%8mgxBc3SnoNީ;:vzߺv!28ʡo}<N:݄+Rzv[.3|dn:3Iömzf:WqEO雩y0a|ў_SיE1~&$o�@c9 k9ߋmL(@x@�`9 r;K5�J1Q˛$/]B SfR]T|2GvA9ڟm%Aq @ lOnH քoɏ/x)\hL'ƌ,=[,V=tdujQ2.+mTN[uldSZ?2x ܁I E+0H0BTd/ׇd+fUhɅm U3n N2p4RB:xh }`|Y_փ/o- @`鹘`N3{8,afaNo�P與˴_l7\ G.S_�2Ag `�2jr隙\;D ,%K)"(9eJ_ nZ?i༬."3H ڹvߡ[+ jq[ mzyCyr{D>ZW[3&d8Uxj#|+#J[b[<]ܕ]qFI@ak7B5]@-|�QI�7J (tVaCQS<O[mܯ̀>myEpA3={tn =3]u˶uCOw]\Oוm ^]AWKzd/*˃Bt;W5zLһT"].%D׼ntS]j`]!] JzV]]vSu`"-R]4W:-x&]t(*CUp Bm٣ "l]垕;Pyw xfwЍQC>::_ �Ş̢(G0Odz-&G(� j%^$(WG( $J,4 Quaj8p1A9+m NWdQgP$@3�ǵf&@\غ׺1Xf@ lv= (W,S;#QS a (0ϟJ1=3T_S+.H]qaW}pGXlQ 2} t}*@P0qH݁׏k^- {Z{#u\ L$X?+%Թu=0͆Zx-mPW:@1,E"-ſi}'l{m]@ OhUSW�X0E2./87 좐 Ͼi!mjBk 0Օ2e>'oL8P:pu�z5Z;4”H]ZqP8O({6(ZAJP\.5!o@�e0M̈ � ߚ%u"@/�x6c.1&k c,-Z2@-x__p߲ R=ű 1{9wPoMO8` PGD@8H`]a+;-y^;3;mt] fcňW>{Y%Jn+?^hۈ+>ܶ= /A{oܜ6 %_t H:y`NZ㳘}h+T 񿁢 p~5hazRNFzۤ:$.&X}uZP� Zv0k (�V6erUtH`FOSYsj^} jLBD9`]X-5]>w. �j_*.AILY'>q�)`QoCcTuӼid.CtZh̫&ZP m߆ 8kj~(<G\Q�Lp`H (Z�V0nO_`;#&f\ sn#juQrf+G=VA?է%wB\3b@qs<,I4'MqB�\~%S@VDE|z~reĿwҿ:ܞ9s_ %�% {GNjZȯA7za]B LZ|cGk2`**f2MJP QV\sIq- ~ 5JU߁+~=ppyQ5QLّ DtgcᰗSu�0^FvakWYF{]; N%$/+'&? ڢ j_ [y89;"Gw#f8wq}}eWA!pPPO{6( f`~&dǣR52͌fwC;~'cF#V0}IF D̓G]ŖHxOkz:p BHL=0^C7Aļn{oqX?̇-YćZ%sYU�@Bn1 r!Ak=]^Rr&:&Sc_~*?*S)*8?[0J"#Ѽ3:cNȀ~ vZpmq艚$*hp2mj־5O  T%@p^@X'z۟߷B= fIa DZ&$KO~p;ΎhiKsw^ p0c�;pO AFH2uz b[ٳdueѴUfzB0flB-*rYr@j TC'֛)i6>k"Sz da\Cd;t A\#?\,D^ i}�]xpL5۞e;gǸn~ e?xZgsgZgѢ] t{βC;v aA]tR.Nn۝:Ag3=%<;+Yf,%KlgA4GS+AW8&B!R�K<z xJuz'ˬ Nl %HbIYTa V_f::X�]xbko-bvxsWquNqOiFnqFu;t,2foqon~oĮ<oG֙VPv J]G1/Ȕd4~>MfcВ6>338CMK���IDATu=T.ΑVrrȑ\0&p`w-ΖjXHc$L }i;,Gw_*3[5p"^Q0Lkr*7CeЯ*G?H2xYz%j K=Cf\Gfˬ 35P2̘$`ɲ8KJU?r7FgFGdyD12h!G B6j,(61!GT`R B#^ mu%`871T^{jtZŌ)C.ީkNl~N 7C/E4aɕ ^z1VR9 Dvz0LJ:>BK@k. ^ϋ3Ayy~z9cj�>=OW5<=`J?OagH?v|H [Fz^0;ӕi+=/<ĝ1mu8* #ct:>;\cr$Q lcw=p^d6Gc!QSnl^9wb1;k^H_ޏ7ڕ>A:a,#i_[dwX Kcs) AӠ)A/ja2М 4鞚 :zI/p[7-:hQ#zC ţqJ`nN8{ z\(^�,bfўJ8)t6;J=)Um㢗H^xR4 2�sެ H 'Jw 7@TѿYf"OHS&"I1}mnq4{ɬ\E4ek 8h*hSMMjޚ@CO-jFhBV[Mڂ'Zj5m޻LfZzWj븁諰U/iytV&k37ǃֲ(>L>vp~u) JCW8LmLQ)'4pR[ƒ08E):^Bһa]ÌQR %}.Xr.B--hBSXu ^Z2Nhe`V{3g ^um&} cg q*bFC&}o3>ᭂ=n t}ieԹm$_}3B[մ- [1VC6_f*f@-J$\]:ZP[&W=IȪ!>9iFnuELfu.Ώ9 LFXCܓ:O]QP S%X ΛUC5| E bcPC}oݍmџ`isJ/ͤG:U4?)y 9=?."SÁq+4E/pgZ07s -\ \{Q}Vdk0`sN 2wޛ~;%b>tbǬEIW̱/jq:tA:BQL>Sbݗ'՝$[�~Rm*fst:Oyc4 Yytizzx>]i iL$VVЃ!͒ ?Mg&Siv~3bVۧlRG[e0\Hg׹^DrYU|N|Pp,0 3p@�-1F~|BAKZ3,.*hJ>5Ӊb& *d__�K(L.�y ǃ΋ÕlB[2 i#BudDf,3Ǚ5�1E5}z2 HqS Ay$ e&42?ͦNbjV)Ҕ{Wɦ5z7qUewY54;:Ԝ+I`o}/v qq8L89NO_C?<QlBN , ry8g?>ggp 8{̯W;_9z%gXa'ǬWC.2iF wm9˽E> tы^4vܦhjmQ?ccӲS4`cpJ`f> Wsh Aa'n%V0mL#J-!yAro4P Y xp4P(4<+H9OW߈!%Up'O))jАn~`wwGt|D'�"+%I*vpl@lLwe7-K''^Ya7TNYg08U J,:>bfw3H;0LA`d.P9f'sàuBh O't]<<Q=H^2?_?' ș?'6d]vj(zVb;X0#nPϡf+VʴzMh x5І[MjR$ kY[YIS*-[̴fUFOڪv* Rt"ޥcoqrGn MAWЭgn џP!S3h(KU1zip#(M:=;4v乕"]. s59Q%o$٢W�q6kjKQcbM8QkKێ:< o;G{>gp^U&dc@ &&&6/4ApD&h/ �"@>@8Ӕǡ]l/vԅ\6dcʙ} XXWX`z_11^+"0 r s+ݸ*WR>H^ʽP[T^,pGAw@%ؾBsꊳ_}ircCd- MfХ8!H5fxɮUWf+h<* H9h�O;gn{Ʃ@A&Yвj-mM_xBdM&@xq^zP=EGŋ$Ԩ7X <Y}ߩ3\F#o"; 7RoNC}ؤ]?}V95x _qu躞@;]'b]vWFt|%ET%[6":gۥEQh2TDS1{{%VLYQ)LT6� �5wgCF[\%Tp ObxP [IJlp_T]ׇa#E#{\m *g5 %bAE rK" nX \^,QWs$NRLKU]Ĺœ SCT-U7 "2CCrE$Nw=Jb&dzYybz"#QY.";U)~/S1EZȻ\zK!^򣰝F^ z+‚G;- ^]~uTWAET6)DP!9<r95-iF2Sya@ɉI`PRtBjȂ--RE{A;>0ʼLU#9)WDw-쾶hȫ-G'-NR%mt=$&s5s5�@Zt:t!3۔v:RZP1g^$<& mЇ�(AI<zx�҈N9]ċl:a6Qg{V ).`@uvyeUgH Xem/U={>[hR&uj(� xgGa;j>®M nv{VE R~"QC߇CIcqaT~@v+抨7s.AX4�@Պ^2R5:�`I2Qzכ o0UzA{bBS5dA_;1wh=H)]8<{q[xU5>ZZH *&vz>8\Ht@W9$?mƼ^J͜F�% Qd, GՒƣ'{í5=&@SH jB'<I;83||| yDfA?xo+Yow">":@{y�y՞!,z��)tuTFGY_*/3[o@8U7Ըk 9=U7wd/e.+>Vٵz ]$}d]K] .益vLǻj%PەE{j*\~˗mg]ޓYwґ?AX{%ض&aپPK aWV2{7E1='wVar3Ǖw@nCSh2@޽1ߺv0(KPɉG{*p\וwGY>ɹ"@iez#0t6$&?@M>scB%Lv{qeXn.ɦTJ|Xu `W 8燞j|n#Mb|P|n|*Am_\x=Rϳj> fz(b=}o{ԅB%`ĂkQzR%y-DĐ7 Ǹ 8}#>$7_N6J!eȆӜl~Z-B/(72V"ԅ\h->u3dH]e"| ^u;>\{͵0y ``[9I~H*=W\{hqWE�%D-7樕(fU RMOJ D{ ;%4P4:~.F ;`a1@=lWu3=^{&<xtvl Qܼ[%;,) I\DD{.ҡe5b >apG,lk9up6`F3{) 4і@jz4 % Bo>n^s-FǙ(SF\b{te6] 黩T~[}rM%qwMُț,ɹI|$MC7oneMLljHw  @6Ւm[p E{@ZAH{j%D4hJSkLcԱ[2Q@]>YC|N) KNM5#C#t\<Ɔcct7S^- 0n͆ Y:K*4Kph2gïw yLB3Y~b~JN`'7l%ٻg/X@T7P[^dC%.E Oڧ f;9ネ^H^eys+, <= rwCM8>2;Y߃3e:>q?y@AXw݅Ba4�A4$ aT;͞qrI]z̖m0@]1M?ou *X ͗4f0r;�(hVNGP'Cl9 g12~1`zq%LZl09{Ldlճ n(a?Kg^3yf3zڜ:hfgܳ33[߀;8o&zfƠ3ʿKm&ѽ ^~-[TwO`vG$~qC_&K5&Lj%$)'|kʨ.hUqn5[-)׀Y�A֩1\'?cB� mM[z! %^գZFɷfoV['4@2ћ(JP m)YA}D<18FiVp "tY"h lQi`~4bu,{X3cDz IkftEDvQ9/JFۥoQX`tt2/<c{ ֡lusG+hG]6yc>] `t1=M1!fÌ@D .3v(cZ>iz sAk%О,6�'f 4sW'ż/șesɽf<7EHߌg^7Rq?\E.ՐRRՇ?A0"JLU}n) փl|ypf{;D8c~z!ݕ A'<gIFD (L1�2v9 W$e _JS( "yPZ?G7ꆛW7KkiLb֍yڍ76"-ލέZ~[gUƼbƿ2nX3y]{oLhu7vXߴg-֭] _B1Lsh[EVm*z e<!lӷ84h&B>aD�h6eFSH al �fx"j&LI�KWٛOOטbr>~JjtTΏo1~|Ok?M?~_OPMj2c@ A5ć!{ 1y\�bH"+pYvwD D8T^F_4"оr 8 6MFl`&� g! 9M>&Sn1US%Jj w%P&� !Ad3L:Ñ䎳tJujx-|AԲ?A* a US9:9)`?^Y8.m͆F91[ֈF 3jݠSt~QNj4| �VB  5g=Sv-Wbq^P 1.fl:k~mA[~5C?m.�O}a~) Ys50o,DE`ϬUn'~VY2aINK 4\@%EX";0ɗH7G-ā)0t:"lctNqWϮ*oG.h ei8ǙicL7쀗mxY`|eQjqhǗy,g{.D/3(J :Gvk؆Yw^W^Dѫ@Xd^Ϭ{+AK@π+AE9_Vc!͏iC]$5^DJdurF F" zDN&b|.Ь }DTt<,tc<~zhDS5E(A.@ ~ID."s̿M:0CUR,~<ut"-ek&KP*A 1(kK :A+)c(�?P`�[;=bz CbEv9�@0ͧ/"uv�#FAX 2/$a sA&6߉F;m|~f{pv)FԆBLZ!@5p 7uQ$QL`@|H+>1TJF5nyњ]2G!uU ĵƙ)uq )P*Y(#u3 #h,@@]qkzW0 fY/OmG6^ā_C =V -Med{T5yT2y8+Mj߾0 6|Z?JD%+8VBJތT_k aG-E(GoƷ~ OVםǰHq�F(AY+0<cNh G H$z @@a.\ I e3mtF0n*oKR` HBs5 dUP.3*6%3mB1!3TKVjPjd�B* YWN@kgWR826_m39kL TSN<ãyW\38'|֣qH=I=(O{zb&h-hhs皾j'v͕Z;P{:{zg}={&~~|cߓ̞P={?ɮ1}}T":j''Х99a1u7I��$/ċfnfv7v�Dlu6 VD2ЦIkʈdylTi6Ut@OAX#ƠyL } 1C_Y>̔ q=JV&~M S8Pq%BR~̩+DYG}p&@[دe"Rė_5h__?+4oYjsuAiR޵Dɇ%Q:i�@WZ^((bjO�cn^mD'V<wcBK'=,rS4EժuRӷ̡RC}slߗ:[ܾ//=K`_L}K/ʚZ@}s)v|ͩkkI{?)O@^s^{5e/_N_l~7懍0Leк:Eځ,0<Ɗ(m]~v`2a'i$(SEzCs(@7+/*_}AܜVm}(;1c*jτme޼J2B6UOHh5H+<|0ހv^TI*]%a"4A@JV5\l3M&%h!up =*} ̞ӄ2x6}'BYupq'q"C@~v̟/7#s QK8Xtg>9G<(��P<;unfri4FHɜe#?sMgĐi⃏b0As ۠K H𽃷X 6ՏG"apD;-�U^N(�1Uay�V@qKxf� Ƒ�9 imqLm{n ¢ h}f =&M9J$T*ۦLH~ci[H"҉xwo߼@Mmś࢜/]L~Ò,? Ϻu˟M '*rt� *zZu3,[y<<U@w805P�AO 8~E=�J98TΚ%?vUS[zZ|1t.mOOK~:miOmaQM|nL=z f}�K QN'8_`asGc<^(Dj�94<(qK`_BŏD:Ѝa "<jȸJfbֶِcmlH]f:|"ۼS6Y[佩-<~=.>mAl/}v->��DozkTV]G̀} ZqX9t98.m@D!S>q۝"͍RkKG@Н &}7!R�f�Ji>P9*ECFc~b? i'H/rr鶥`_e&{0 w ˉ%kh9c5;oN*JLȜ1 Ïc>` ۲(Q cc(cC٢LjSMJ]Aѓ]]Fu$}D׿>m±`_v;J]=6EzPLz='>uEBiᥙW@{#AAW.^{4,Ź w_j">Duņ?sqa %p2?v�>z$ܱT+vDS5Gw-$Θ˙vƿ=A&8_M8ex s1~az%wU_!ӂ @;VkFS}Ag`LE0iK^hrhtٍcedi2]ZͥS)hvfCA +lj&;(2Abzj᫙�SC/M䪅uP d=~iT_߹84lF ./b}_\3O1Gy3ߴ)j ZOy-?0ߣoE?9s!H�2G)!<E@,F >˗h` r_ Ot<y<{B�%'=i wӋiW#23̨p.I;J92eږ]p1w3m0pW8FUʉȌjGc{߁R~yaE'A̖Wd˴e)e|yze_ w\d#ܭ ;mP݋UVnmXΉrG##0 C~ 6hm"IEz|�kߒ݋Վ)Zlůۘq 4E <hڥ1}Z,u!2s3:bm=r#E@=LD۴}_7J �Dv aG=xpd%zF4r1xf8 %f,jȯK)z$mhq%@(s84D\dW.㎋seN%po�6]?zmxg?Xz]Q]o:Md=F2Sb*[�0|1YSCuqjuCƔPStS'CؐRXbSCʻv#Q^dٽ"C&ࣟ'Cd ?<c '4 k\=1=봢qL11M&ZUQsf THʹ #|[sQ\,"q@мtZ|,f|5f63`M\YKXh\e!dr0s-JH18Gʲ]҄طQR.K:PR fFGˬH 9{ q(ZR,ݣlB]}~u[Q8TVt? s[r>NKqg'O'5Lf,&欑'dr2kMpL�'{h=n4pdo5t +KhK֣~ [ޖUw%~MwYل c˿of�X 2q`",G$13^)-p`0}>z*)Fafʴe9 J/t0*4'J|!ou6=]2|]7 X q^p|lt-iQt6R1F 236)7G׍E: !>Sak1[h/5 )Jмc4""*,nVjCn^g'v#p.N;XcFV$�Z#3@ QZVhuED3(}(e8 J,bZ8ytRLXgwE/<uB%(z�Dދ;iMԁ0JSb_b~2Nٿ)?Ep}s{Sp O'3=!şOf~<QسI so+"'1Q39C ^�J.G mĖHXnJE@(36K z6AM G8=h[J0t2" Q5׎X#)T1Ls-eO0>?wxY6IYAs|Fr(F{D;;8u,`CrTԠ7y2AM1w0>>s̞,M1u�qdkǂc}p2&HٚjRS돑AIvNA>X|c/dRM�wi耿{o {NiPfst >L`^חs$ZjvhҾV }]93LzyÙf9>#f/6?f/ds3"Gf{3[fy~`xOA4Ԥ%`$7+nn㚯g9ռhK'1ҸR1iV?r8h#Qc6c ]ePulT9Co9-T4 UѠܔr'(FQ sp y8 Bw.lXd6է-hZ@'12| -H&<<]Ve2εn"Q/AA)ш5ufFggOTav` L@8 e(-xxE<mA.e:%YdKvg `Ɵyvf2iX9;ojT~KN(ۊP. l%f>[ۜ4}&I2O Gbs ?�\Vk9fjC 7,M7Qemvn &4 or>KCq`BZh 8[.饩/ցյq@B{#Ã\?r6A`7eV1 'q$hh<G/#.f1˥faƈ]V$<yA\yy{ m P$ i5l^f{9RGv. n8zohQU:pŇ[/%&;JWr J}K3|[$!G @Mx+'-Oҭ8>47D;W[WRZrm VjS�JV- AVTu)rl)sZ#S j8!ͱM8ETkghPT,ʞчU-{&"qUu tg:=?. 5/M~4iǠ"6s1fNi4)f}�N#b~YBڋ -irX֡ÁMu @GX�.L�`Pu@+r1JMQh4E h 15@�c|`b!vň{t$222t@uY" Y`|,zG~W_cdgOJ><~hf/fmD#J d(@렇bL�A(M#>=}<"YdysBq(*obm-ԧ.A ^q@8qAW W -;dsLf-2<I�d7NlPl ;Nc@ccbhxJՆ|X�T|xO& )Ql \LeJS@ujR� ǘzbOMY-@KvqK8Nr>/+X w�%��`0zp1m@, _S)�^y ^r*5?krљ޾Sfڊ>:,A! S{.P*"*: .v7J q5?f p�A4%OQD*fRrY|>}%:%,aXB[!ҁ|I`D^[EJ&5[ݴ}Q (qPI#ЊObK$[*,k&r/ko!}6PL) XV'(S~yz:yP pU гŁ-qr�EEm3(Aw1(H <AGlR\)^F?&rMJpxȋ,[QmN-G?Rbz4<9 ;9(4aԏ9sdL*WO3[x&?QD' fq3f3>x8i.`  O5�42{ǃb$t9M̡ñA0543/hkϊxi괐G˨|Ss稚1&�j<;6E@iKLKrBvKoꣽvEʈT7_fzzM"ovb<  =| aVbip :mD @:Q,Bg֋\��-j Pd6 @ @x*Jhċ(2S689|Fg$}.�D@yA'm}z 3gIgHo<`ğw^yu/9w Nf@0iE%jjSnAr+G"Aw3Jp4@ *q#+nC]dFp&˩q, -ٜOX Tv.v =3;k$x o|LIY+z-h\9:^Re54A}(xz�_H0bU('eqv? (z@ ,v?NMX"Y[ Xf4�e~ڀ$l+C_ϡO"(]l  ܣҋ{@JKjf4IK⌈dT3>h5h5)cc3p ʀLLyۚ㴍>gE~-ظ.aףJ=~I`jӜCmdd3bt4 szA}n_b$|hP AD9Qh0Js1&- W}�Õ[ 4-.yƯ11O(N|.x` qnt0BQ@gԸaGij@P08�ba <XcjbQ1Ƙ3N-/UZ@}->Gh8qpJ. 9V1,|I  ,c&$ηZsp"`('Gi}�Mb~ma{*cn(^?Ӫ<El+!’S2`I9dV<']R6/+�A T@�Yd@8A�8w @# &l�~Y9kD �M9t8G߂34TU6)yE2 k ᒀ0< �AN \K]GY.;.t LWZ8#| d)]jx]γ#JBӳ;QQ.|R0B x7i3nʂ2R.LMzP5;iHp@ / %X*܌rSG歅㰅Ur R2 I;Eg9k O%s:9'%R1+xE$lA+53jBsA1; }Ǒf'0ml+ÝLr VҤLfIxKp+*E0?B8yZ `n(.?9OX)?2IUaN߁y �* +vo.P^tSoۘ=BBqgBby y?;jJtzS-Wyu4 l{"Cls w=@mJL<ghWD vnjG--ٽqP҆|P%~7o3w߂VjpOfX.o }"V{z&Wavѣnwحz6yna<"w.lz`1w\NRN6r[o9 o;o~-Ԥ540/*=We0M7gHiDE.0Ȁ*h .YwxF4*{F1S<t߃FѬw7z {1BKͯXk\~F̴:\X8j?JeվXJKQh_|sN6VM(M+w\>xaqiMۢsOK^?G%>dƉx> ÓE f @/LRZ\A=^pez()&DuUIO0n~E]SCMQ=mAQ KQC_`]h߬ӫ`,<;nre?PQT+n%"yQH _h=@[Er9[M[u+uuj<܊u7_^w/3ۨn򡽆Ђ mmh.&.K _p/Acv!wbDG\Zx=�t�qFw3E?)0Z4�g"�lmŬՄ{Ȉ{@@KLnm[DX],ƘKs-B,Ģ0�B|Yg-Mq}w{EVڹ>K8F Z}N-?`ƭmlX;rhu~k u|_rdDn:ЮwPoYXoQx}s[l3Ocpن)C2;ADUP#)cFí3_�R9;j7SXXQ/mF]ʅ6%B`Cp&Txd"mF:RqZ+}O&А5 iAɻ V*b7+T�rcgN%Df(-jۤ~pu5{5V4hL \GV-8>jlc!k:`U<g|{Hsԅlf%~pw7_SёK_-3w`r酶`Dc5;|jHy쥎#73A&#dBX?A,wpL'vY J/+[.`"kgV 4^GgO[H%46J;RvHVu e(ܬOݛj_NjZoD[j}Z=o?۟[m~̵۪}5Խz*Yj-Sq#?ֹ U-cض p ( [ybCV8fipQB-p\R ˘EC/úb !8 6{5 oFeuwH35g1M.|, ;@S1eyf8scqQlJ&B{?:[h"ܪUc7/ ,MIEZEʲV@rf:VB*:0EhVb/ Oɳ_P"*'LLd"HGAq)M-P倚VrT9 cF7- AA'5r; hb0-8`B$[cz|}D"nE<_acd 7K t.%?xv Ƿ[}5on 4n11>A^Z /?KAh<NfVU{%_ب&,y3w)J<As: #HO"AFD:.ɬ`~03JBD zOʩ3Ȝ@Ȣ£@VOOǿb+ٹX+zN6k3 ٬uUS*)RK<2s[e�WR'$ݪ3B5ISs1*Js\{ʩ/:@KC/eR}[hQiy#k^@#Zn('r9KC Ǡroc u+K<aj9zY̜w.i҄A5P c_I?%&13Oyܮrv=[Xo M[ؖ / 1To瀈 Z=s& ^Ő�Ѯ|obDQ ȔP*ZtIW$ptM&gQ^[Bܪ)R&kv&ϳ$m9arjm~hEmTuj jݛje2Ӫ;.C&Ztg4yƃ mRٟofsZU&I EY6sAC:p�dd&h@ړ_/o{gSb<!hzC&ɉpfy.A9K@`2B[A< al'#r4R+ct8HrSFԠ=[νP&#A%},G 6HdL4"r${, >gpo %P~omnW1|uwe`u肄g W5Џ1"yw&AF1Ќ^7aYwj]:u1`ŁQy4)c! PϞ,Lx+VquFmFؼ|VY觾Y %@QJg|fk@mwԺ]jJ<rk</]^C.h5?+5%\tVm4 FN9;]&2` Z#v|g8fQ#k98ьjDz{z>g5rY{r_5?LmqLk}ی$>�C 0̭&7wrM]$\oZvI.2J;@ -{p M/T<~VSs%]&<fu4\ jiE R+r.VhˁɳES褛߾+i)?.V^xV}#꬚>:j 2۴g,+*.WZZ35 h襭ݣə#w�fhؑ+ruZy*L ;Ԝ_rBz6f/li :VT/:=C^gK#g ҽ\}B&Cyg[7P gփ`6=7X]"Axm+ ,o($Ǿ WF_VujǕ5X?mK"Z_]6!]&ST-ou�aYޖ?CVݹȪVGI/QM;.Mߊ(pVnwZd8F6}~(�۹<Ԓ=2Ӌ~ebtޚƃyv/L`=qR\dmhL#4QS։I_k˾ Uct(!i`{=ƔEodOy\~kT"#i2CTQ^_O25K8 IљYޙji,:gT\wlW#2,6"aVz$=.f &戀#f%^RVCuh#E+25Vy~;!۾.G~vVd[q'NFمfsǎuuu_|!#t:Wmw]f�3)ԃ}I;X eε,h E[5\H1q(a Э?k�-U=z@ ^G}QM>* =ʦ*+zEŜ}-h8;a5a+1(6MMiڄOg8\*8:x:@pVwŸ(b$18 I $h%LLKŕirzѬ41@֨ ԻANyyӧ_7n]{iZ货`Rr^_3޽ !?T~7jӥlceڡ"]ѕsjEui6͂ K{K"):$B5Ib>sM:"+ MWl:q1x3zt^'aD!on$F'Yp'X;g%uSDܷJ` m%6Fg}ξgaQ4 nI[4sM*<7꺓J!W;mV^/Hr 7h.vZnYgl s wq AS nI^DZD6Z^CxJYA$s+b\Wb02fˠO}7/(9P%më1H`~$[<!Kr.!/g!2"DĆj� s�LfK(ҋpn`uAg Sptxo4RCM.jbDzhkuixIIJ~VŜQ)sH,ђmЙ.{d 0‹f6 ⶆy\\ yi7juǠ1u7fhfH/.Ҧ ZVNыpiN\?w]RM0�'zoi:yKH@/Tl6iZWՔ6Hmoepj\W^jEg>!ŏ[k}c0‹޴,p\Pn4nhyGDBO kx>cDOvIѢGm"�״#o�bƹhU75O$0O$WT&0HBaV= Jq p6-B:N@(!eLO4d�E  @]s3`W, D�J#>)|Pm ~!#{mVk^o1do9sr.9û| '[-Ν;oS"wAree󉷼[}˟7#I|b<x%}aӧoΫ8�& 2_85/T2|8ȫ:xWzas?,g M'O[ǫ&ʠ0Wˎ@r@_PUHb;Pxt3%e۷uT5q}ZN_;1bvEwZ u�d`q~n}:mG5֋=pLޏ,* p kv[W˗f Q1 q;E9aw4phnodN1߲Rr,gTO B{>^|RuVkYҟp5O@z _!w _㮉|-Vٚ*ZŻޭj5OO5.\V?ᬆ&V|zjU*5. :M*$'Ieȭ[_!aqzmp]Go:!]Y=a[ Q',�L|Iɠz<qy'5.¸'*[ERfFkxAtg`4,- ›MmP9f'X/㔬lX䨧Uۏ!91y-2 O ,@H=GA&xUS[\a|;8.UF{JhWnzNX͉/[eRTyeqrXĚdK/kc^V'hd'73lkneCB6uK@%UˮƭU1u»Uew@ r w tmUe@.Do5ftun^XRn>ܡfIJu[{ -l%,V#X›�$1Ҹz.t۫2qQrcK ^| i{sl!5qK50=,ȵuO 7J'ʬ RIZ zxuypϳ 8.[Α'}+x[:JToRi=RKW@J=yOZ^ޖ˅K .vN@zgKy\X ǖC5M8 }+Υ`!~,%Ծ/u 2E 8M oRpOsI]1zB 4oZytNsѱ>^NOkQ,'TNrٛJgsA23DUs&oz p˹ o{AdF'iL7(w fjΖC~.OaHH59>w$媫ZQƛY :^<np4VJ7X ȥzۍp\>[@03ns8"m:z8Ĺc+x}{ {vnx=~:n»Ѷw ΍dot?]M__"8sEi+g6:[ 5 і-y:3FEGCP �gЯH㤒pڠ0t # ޲׎NY/;Z$-G/cP׿8(0n@z)DEM-DލKŻmՃ輲->* @Vڷ�> Sq*B4O jB igV RVҞh)ŴiaC6ixlXl,o8DZ' jbXI,xZ*v+ gp@V82IUDV \jMۃwb., reB;xw8ux}o?ڋ7ѓ `Ϯj<-oޚ3>x%-9m̻3/N\r_ .%Iiv Gw jp61z>["D? nl^#N �4!`-rxHbt0/:!$ U]'X. 8&M2~m`?ـUIV2,h1D}a˰k_f+,0;IOAqy<iF8?[1d~k֘^ʎGƁ4t-- O*. 6vkвs|$xF3iIGeƒ;D9mxZN TT0- i ' +Spķ{ BDQ; bTsTPq3vf{eL/o< >A9U۸ܜP>CK/#}2f Y92�BBz+排wn\Ȥo1@>D;Dc Gϩ_VD?M#z7y/7[;@BG貵+H�MT DI֒t}`J\6@І$S<Mnc5&.e߉9[/륑cg7#$HpqmGI0'IT.9W) PIr< IfS[Pg>ǔ}D m1яk'ɾ8P=ׁN@sNShzhpaڑٚb;Sч_v>ʋ�3-/WU�ɫ\%<yӊ\yB)z !_/DRDPD&/W"i|nІ\^T ;\amx-@vhT^=~^<O׊ĕWt"e_<55:fbP݉t�f-=I`׀%KTOiq`̄iqVh&Yi͕gT؉Vb8^\`Lw|v[\MC2d 0BjѹWǫWys .Iv@]%`#븙#\|L2`uH~{P"#~tx*/(RW>U]=l >2 a(1d^BɖC^_-Էz+9a_26uOb+r6kgx !ZέnWp=@ZQ]H_*tvsJ2m=>\_,ŵϯhő� �3Ʌ)AƼHfYhCƽ0&�s IR$9.Z&)&)Iߤ洜i2$rNN̚%sj肿ǚ9oIjv͑qUDshfyj1]1|N ^t*ܶ1(79#c44)+ldL9c>crL} {p<%G1t8 {졝"2\6<9M;9~{*NnqJ&dm/_w٩*Wo3meu:-q'Ef+zj Lmz&OΝ)΋=0{#>\$M񼻖'3ag{$X Jp�@uE }; U:) _$ BhC2 ԣ3: y=e ?^Ou;ÄϻAq尌Qʒ8N{GG}88{$2De]ɝz=hHPUջ1$ .B}@&@i*@9(@ &ߵ~L?*å*xnv۰t5szO']yZH|yzyCz+__4?$;ל{+NQ#)yzkڏi{朒;Uގ+HC+6}ݝ2v<|mIF_}⿓S^ #;@;ŰWf>N3ZE %Z^iU ̠m60 X . ޴hYq ׬yC;tS'yZeB!麾]=]lԢѭ00)0nǀȶ-- dqF7hb< OFFcQw `LܘWIDWFqqlp}}jhcF<F;|0&Ƈƍ1 Jǭ=AW:e٪ƻ?lp DʟWސ5˃s:9E ?7:AGWP% RD;:KA/<=.u~P?qCDϯ>OIw꿯{^{o?q~ ?<_/O`ϓn` HpBj`xՒ4@ƺee@: � T%T%7$u5jvM֠ ᚧ:ȋ۞k5̭P]nL� \Y <@J| d `l.C] >8nOa.hhg)$�Uw;Z蘼;,}+ޥSkg" ut jmJZ5||4I~J|U^orxĢ!fSP7;Di$[r_"e3zxo >77 fxo=Mm'>\e%7bwdNv#V7oX] =_yf|̨_7/l M8S9\-˷ŸTwM-y*:&K@�*@.@ OA Kdʤn͘캬:׷I: <|B"9Wcv ƽ 1 g;fفLx湎6 !D#:Hcny AHk4 po:GOtMƲ@FEFG?6hu!.="g"1`]ut]yMyt/&w-sq{ #ʋ6phqw#jy{kPx| G<z^t%mw"ɇZ]gBkĉZG6#ivVhK/[�"mEKf,Rכ[ho!Q;hi. X4xd6[X�jy8v^5Iuv5OH˯yIshdʭS,}eZdEa1,!%S2Ό *KyŁgF3 13Iyn@nVѵ5ɲgeyaj%^ زrD_1NKG^.~䂩d Ϳh[TS\3}o*oV@@nd<s᥶0bpe&}m4Uv5?-"S7@1�]=qFޗ@"g׶Ffֻ3K|uVqV8j0 7ռN\ Avןn"6z�$0 Foƨ k{vP$oOj$ksvfgkfdlbhLIZܰ6\F{9K{=w7hN`)�3 8{׉*H:_'ݸT3^b6L D_",+ZW VJ ʭjn7c^3yAUix^zDH0yu_?;8|ᨳ~f=ڶhi-U@U` E2~dhR^rDDpGN8kYt8-w vR9 ZwD8m@gQ J+fֵc]bwZDpa਑ߛ�"ڟv܃cؙUG ~a0#o놞v %` ͼp�o7:0B߄Hv"8bԀ =$`zq! 7@c[,U~A(=$0-u3 |N@&A_+VDiT7]@ÌU�D/ [$F5W� VeBj:zޜ-A#8MalmVƢ!~{ X%oNA7_z@rL=@- $P-t؃\ŀ00[_ Zqc}̛ͨ+^j:ӼIyă=OTǯϝgqTq&J&RT-_rK?,y,m I\+ϓ$K+<|噼SgA7 $qԓgq/55 \N0 ˵q85NzKƚc~ΝTF$1?k&A&}U q_ @;q7j0:2ꌻXk:WGYsFqǿ2i錴R尺-thLfIu :2lv.DPCn]Z<H.N�L ϒvvjpnZmꐙ3ކw�).kip/Uol bƋ3ϵˎĔ{|^<cg8E;f6fS S x_&,>Jn|jJ lɆnw(ۮWrJ5 _q;#K9;U=]?ᾼ:R dWѶxTKLclcY4WM/U|'̭Њ_b,V*-}b :/gْ(9A WcKYt+ @~Ӯ`+-L2m JJܜXRQZ+nT ;PżDe$�ʎSPެ7cve_93P ."hVgqI&:qM\4;mov O(w.5/}cEiuF7]n #d#mG[>wdry^EM\Lz|^%M&NB6.}HʒVZե%oK`{})O.U- ֖ gvwK K[ڗ*Х'}r =[$%k[['[vS=\zM.-= `YrS~J׹am Utz--~f ,x]:gM)_^QvmIrw:=O%VomLs+Op\\p[3լ‘՗)\Fh{#xռ7L_x`^{{(2 ,H b#` u 2,/f˽ik\u/[p-#%.sŨ `#(ƇX /5\jA,.gyqzy\,ϻg 1l\Vm%\Wz mqy x1>k®8-^G_'ūաo "nM;:3Q볈k0ۤNL�>s|+~l!]xEGk%TX|N ai; X82R23p|!p4 rb1z4 ~A}[ɰ}l R~L'xi.i͚RKr/ h}-C55 {1"Wǵ{2FrNo9ֳ'{_t2 63'0__'tvaBj qf+ų'=8! o<63v.l&4q"~6YcRgD)SS Q(?a�7ж9?v krMl]S": ]\#sEvnii\#RXmN'YUȵUU:n{!0KOٵ\$p.Un IT^L:YvԵwMeU]^`@w _'֩U)MoaiG% LV$ xͺB@bA-=N_cɒd];)e"heZ5 :?.E"�#A$⡟ l/-$\ bé5 Ac:ɪ @WP['ZZ.RP 0e2P/!1a6(S@CiGׅHyijllȬ2/ dDI gvFwVxTw;q샺edO,#J8~QQu^mˆh�"pdxgH̩f%SgRC*(K52H(౪VD sh-چwhzH~x*ԫee_W :9Td)2M|UeY?x%ʬ8 \Hk֕ "`(,^Ja܀h$ԤsbtpLj,KrRqlŲ2M @1�edzb Z2h9Xp vO3sڭ$ܶkAz^q( tE82$u S2+ <9�'p 60@eW\^.D\GvgS|ԃרwNk Cû9F�)�. h8纴;V[0"H湖| ? ~-ٰpӨ*Zj)~HGOҝ=r85}}gh?**R4q~uRERlQ3ԢW`~ 9f5s�YvB�?5FI6&~pˑd>3(S4kt|=:S�zQqGʀD=н$@-ReNdq0:  0(@[Y@eM z\ ],D"u#J:>V/ p:@~58a1h@6+vUE\LVL]yz($?1g;J.~I/F:n%cY!ۚOJ1:FGW>V2{WPfk({6& OJ=&%I0a%q9i;]5k2RxϜ s6Ӌ&]ߋO.5) hΏG+ ֠ 1N#0 qKHh�ra _OtI8/ъG?X& ۱ G &t <u ӯz ^Ѝ@7@N!|%}0= $[D*@W܃xCI8_$5SDma�3[Z\€�:9>ܒ6ĵ.E%�A@&"'sV& --OR^'q-vrXIC$0tK8ߤkt;�T7C0SsV_].2q!|rXV>B֬B>�Ϻ 8�%@8]Y!qؗ3ĜbB3� !9%_)g&8zeשR~XsowSUe"%YR>ݟ@fqr 8ud%U�]XȤCe0:2P@ !Jb'BXd(}N'Q>Jd'Ioul& o6QF4IHHIzҧ9pNX}5XAeݤ s}pw.ӕa #0hv[N&vI.x`jfEt ?l" շkbI�Dh=|B$ȉI:9�17v+yZqcژ3F>4oDJU(=W~pœMn6Mzt*}: 3i.lPxNJT ǐ:/:u_/Čckz .a/:I01`<P߀n<(Q} G4Z0ùx24Qӟm1`0ȳ'YBS4m_j�6\G. @ = @� EavUM r~ƶɫU/x:~MC"FMb mD2p{=aw["jDno�1;\"8P3A~jB%d36ڗ\#Z R;9jtߧvj4`.C?~Q >|t d qCk9PW'qAz:`uG(z5 8GO̩?a?B+yL }<_韐?%ӆq3bMzuiVw:oi6s1!**{Y@tNE9E1%0ZHHZwWIxRwb^tP&y ܔGmC;maaS(2;eG!QA?٢۠"ڴ;5gLgvUn8ymWU -AG1`SG쀱~Ql0!Uɖ a�sq;8�[f<Y}^lr\edgF;1pe\,@Cm=yt4]"<3Hp81 3}+0d�C~)0Td2C1'YG|?3诱gO־F_??I���IDAT+ϙ|&ڟ3?+p[?'/}Y?Ě` � ~aW@#"$�"+](W+ }Q xy|y'cUtla@NDkcPaA0;jP1v&ł͎dQ7܂^tհ@H!]v,/#b;rkQ/ZhaH#=MfEH@o&J7 #jD{a# J%k]gbعv g&;mڂ "?6XvtMZlRVOaaȚ"Fe_R/Ԫ_>ZѲކkgd 9u~U@ q);<3DY!8&%, XOi_yBu*l8tdzw̋NӼhw8_"︚#P H';<\2ڤuxHQS6��`th'=V@:"8<kMwgsp6y_ )v6 ivvٳwi gف0\@@lgp|xwVOJF~th\ nZ"t'Aq0 N0NaO)8p7Tc] Hpb&i,[<o(3J9an7#]S1lR b҇汵QRzH1,.u'N})!/*d iӶQ2`G�2/ Lmy6Aʢgggg=<^Hp =g.O<6ϻ1æin�;Qӊ%6 2d2!54kK�F0jU  07!V_Le 3t;R �תP7ؽĈ}VaL4n 6�I(t!iW aЌAE?@f`$ڿKtYLk+~`� JGH#E D[8?]7;8txN D!\4 0M "=".~bD $ A Qn{P:[�`( AzG{]Ac;3,1?G3>Gg垄ʗsvu1cE x.V ģ;@Qzsl;zg u'Gv4qZ- NhB{ H\HELiZ `.LAz!i a[-CRث6~Nwp^-~]Iv�/ X6�I0�;1v`@;YpCQ&�VϗAĘ2~[!uFqEZH}M@8/Z(ot�`#b(ƊW nK 6A&(l"|Kf# Y>n%cE7F[xd< `td\]> 2ø2Y:2:m כ‡q'G~@1Iq{FKB7b@ҺH� q8S{<uZՅ-Fgz`aU;sP^^=<J|g?%W2ޔq2q0"܂4À~3vtA(U14G (3~G3-'|H⶝ΐH='۽A$S䳝C泭mڳ[=kc$guٍҶw5ۛggY7ς7` 5AwP;}isi _c )}췦mbnw5Pd ݿ暞=ab&(3>eT"4u=at|)]bx!V*"hVroJ#f0vsJ'.(jY9q[u¿؛dMeRIpAՍ9N{ U[4ڶ>R F^|.Lyg{*s:NR%SaH1҂ViIRl$YMdv# hVhSuI~fR7RP i\{Dnr~;C3: E98,-<mK,mW6G߸rXI9m[5"@H Sß$12-^[˞` <қzHxI_Hg;KXu\sI*HǗnǿ(h5/-(8oKtmKK~J`;٩v+R[_Z i ;-qy <NrnHt$LΑN@]}IEt'tJL e/"�'/-]/ bOz~;5H`~I+N<?=*դ*G%&1/ӽ\F$8~qxxݿtMuL/7lVkd]u#`q}_ o{ci~:0WH<{A !{a" >ڀRr>5"ns^us f(H7z˩=sn @[HtP>s){=q1|ƨ\3vk4D;:I =SiC GޘCk޻�<=s ^ z jлC7WpJ?ՖM;Me&/.ީ u{3V#E25*VZs͑nhP41`TMheyj'C~J5喓ɱ7x7Ư يy^�8 n4ٵ <D`"zDjcz|%$C -D5yvHݢŁ LRdqmi˙]L̐wMq*2?ޅ:.ϭUf\k6DC'$f dr*jŅs[:{3 q2'Q'zR@0iZfe6jek^Mh7AkP)銦)-\`?՜Mk.{Ц2\rԼɵ7miS{έ\+  % Ai'tOhSh8`yb,n$-jx"`Ѳ&gFҕNVKT/y#, fֹ{{Jmĩ̄�b/*fB{V<ܟ~Lz b@ZFBj "hֵ`DD"@kA! Й)@GU1/4$v{tUסALg"4*H[kxP괩ŕBP۶h?5m6??8"MD-egQiY[-H22+w ţn$H/Z!Q/5P~х<k rt[ns'$k2J*c*c34Tv/(@M1͌[wY솆<bC w+;wgέwۼt:Jv:RkmcBUr-="F)v9Q$\j;A̒_Y2>꟒}`@ɟҋ-ӊ{֖$|T:e2E3Iھ>B-'`9}VC}q=~CA%O]I9hSHa�5h}dcU.AY{nE݁UgȻG-`DN yB?G[1`T3ڙMNMָS;w^\3dr+4@fiR6MV EfLz;N3ʛuNjZ&h3k'kN8(GtD_q-[RD0?Ms t|hԎbgn3^w# GD7UD )+i:3%DNˊ%QJ1Za QW;R"nr\[ ŝ9Z>H]أ .Lq2:¸R#Ʉ& p oڝ6sh~ˀDww:G]wvan<<�DxYdG(u_B߼F}v5P|+:O|0~Wub]h/%5ū^Q)?' 7cN2Nf:Z5cQ\80aqMMxs!&Z7ь35cgtT6Λ\wShhEqc[e܌>IƁdNICI"a8! .>訛sH帚[σL`h|Κ;op&W$2;24wjR7^+N<1o�~4 $Op9Q@\=N*Tinjqd@$=;9KzE_ݨM" h]ϑ k(q~lmgh_~K'jSL;A.w?^^Ҧ|d;ϯ9tD.ͫ u( iW;^.YWNfQEvúڵ3FѶB ZɿIg{_l;zij' &+' mh]vӳfށHXCaP Ӱ|؄e kMˆ+mp(!H 0T�A5Ԓ[";{>NE9wz dO.nQC/La])[$ۂn ÀNd9K[זjLհ6t+LJw. a=;hw…0yyX`xna-OޗKay8&Y"~T̤kI^tMd k&rYf#ʯ:!7+n7v-}RYk9`|<:[YVGn+9Hz[=@7n� 2Pa{fr9pF;5`!D )׏9gh:9Z,=d#o D@- xsy7 H8^ 3"xw_`6jZwBG"Q}W =cN<ҞϠogFo˖u̾n=,0QI!d#HuSܞLp b@4 @L`ks߭HCT k_h mHf,"GnC$X.r/<Cu`5c )|hVEfl2 ͊I:mN%P}Q$tX~[*|Qiq~ l:P3AיUڴEm.&MAo=4.}, @&F"X>2@&`N/HG:_qDp�H/:J3j槠y@q^ɀtP=AafIhcTmF@!_ﶭ"=�r~s?=bj؏vb(1υ^ pP k_h;mR A uJL1,/HP$纪'1 I Om8ϯ? N� (@шP .1]{y}R $С~h=$"6 /%t'wMzb$99 ~Ȣ2v<'Œ@"p=!zkw5@yT.2s,.O.[޻% L&�{l2םf?ZہwfY ԇ2 LP6>PvˠcLAwvbwa"`NC{X| GH =[zN15Fkn8GHq_[ܛ8BE؅Ie+xQޫKB s}r?RIc @wJZ}~#sTK�  �WաKۃHpnVC9ak|YwdF~8=+<G2kќ:\} LAXNG\FL͓@gtuRTmD�Yzŭi?gVLx=>-ΐsuB3]f79xtQy 1"N@J#<; PED{-2 wh(P'꺞[*d\uh부xq2w:;;~7ۼ۾[&w gޭ}ʷ Mw HI5`nzEZhMbb3p-J`8"sl`W-jCza1U_#sټl~2z9;ۅkM$=Lt l Ѫ_!퀬_ũ$"* |㣮3~ta�C>+0,ήҷg+]nnd]J^2Q~3J@8Fp@,R# /D@OnHkQ=<sZp"q#^idPxUYl*[3t<0B){@e 5! $){&D>EJISvj vJjRf*S,B|T*�#!uCve{0޿,D zGA2 PSPІԢe}C0S_1dQ+X<=WnMAɦ4.ҋR^Oz"mҺ%& /Mbd,j!/J pgO#+#Q8EUNP}d56S4fszq"T.xj3l %@K_ ~L�DV]ט+\s$HBʻT"Z=稭"3;vC88m.4ONEs&䤒?}tio/O83pZwzB>s>|TDT[%_'6m%:S /4rm9`-z I#q@ya0t}Pt #h{( c!@Y;f>l$H~ǘqI:GtfFf|'yl-@$~]D:ziQv+@e#qB�yDpEOV�  E L)rYRv`,iel"N$@'[-B6 o�10tqjj ~36Ywk6"sFSg4s~0}a`l8ci۳?gLȆüfɨe[d ҙ]PRϬj[{vt9p'Dsra܋Tƾ`H#_:RqH@ܼm4ns5H%$mq@TA6b{65/H~mn4nz[iLV@ 2ovAsw?_{3ٕj :b�:�p_ `A) \``q;h=`@X Abh=@Z#m`84$qY抆sQ�mܾƵh"mi,[6e{%8ͫ Ú$0$r1< qE,>,n {W,7[M^İj XeZԙT&8+v[MK+=Jy}^2^n@<f1B" D �Fo DP ~n=A RR="ۚi٩Rt5a)tA.]:h mXwm vha ]M;5'N\6aLlI,܊1J\ԯԘ<e_%P=/X]3We+%j-SA/M} 5 zP@yW4Cp]mcpj"4%o# veë {jϹ)xMUΦ 7;H7nL@&PuOWDBJ[qC3|XrQ�e[G9lw*<cw]k=]>y`?d\6/pswՍEf.\\"s8}ZfjIFG#BZ#Qўa\ItߑLKN*:\#\Wzq>ʪ{-l=\$=W:W.yj*\@*l}BV W..d3D'J;ܦ125h KZ% w>5%2-;xom՜Q>txɁKⒿ/?WCWwm�n0-)=+՛�hߧiwq*B²R>O ý,zo&>U `' Aej 1!' B$ A*Ձ݅29! � RIHqHA۞= |\4#c^3vבf=RwM\/`~ <p![�DčFz1Af960:BWh;;M MAWT9TDṒ'o`b[` x {4–N&/9DXsuv[%4-믻dЎ_[yTH/na[ϟBS{Y 2 L#0OUؕ%`ȉ&' kueœ } Q\bNޱ|r?-? MD"~4X!6N^#hE"%Wt .m;'tgI ✿]Ź?jY` svv-j\CYfkk]M,C[ip% �ϟ18 7BͨY5R'UMc]e?O@ '{&I*kqKK?%k_!Φ4cʨ Y 'xhVu\V2*Vf,L"0 sD0M0h4gɴf;6lPU[sd$j7qͧ:>O™i:=e4>Oىi{iz xdy5LkL;W` 0#kz-y3S T_&iSi=o) ƹv- U Px>RV \S&#pևޥ)z2 {SW[??$'rP!Ds0t|d xW W�xA@VQ0Aܫ8^m30W!%dV1\vk(If:Pт#%+" "6lEzx6!ٞy͠U4tN9l3 W;W۞}6_xTϜŸ%3-e/1CA3dƟK(Sg0;̘-6C^<ch7'>Ӛ 5:JKf^LT K\N9;iK8F;ヤGf>{l1%T_"m9pwxp!5Ҵ^Z_KD%QrhxN`[f@'x?[ q)SLCS!e8 iZ VrAyUMY S=Lʃ%yd@UVV=8+~\8 YM]#rA2,eqHt2 mRpED4!Q`b/#; 2&fh5918Ѳ;!SUo,4۷0!MʵJF>I't+f`P`jl ߚKxo&m\5g%j\ڿd_~n|Ah!@*Ro ߦO'}O*O/VmX&,:фq)kO? ''9;~!4yHe7LНH4a e ےDpL,0, ZeZv 97yy[´_3Qr3Vt+TH-0b#~/Na^D_5b>pa6 NYX{ {Dp,a5L.wzDz،lsO>=/8_ 7m_o>><ʺ/}!wr4 9gn%_ c>\;/QNr_~ܓt̎3:¶s}AOzܺv+ٶkTo=.cK~;m]<:wFO Ӆ1oxm]Lw{&}<=N#5ұy~Z,y8q=}X>/lvbu/t l'Eǰ`m> % >-:^oؖ`Gwde$ 4'YQߣ~ {s>J{+H!)OK!bTŽuvNF@# OC<·lxb\<8֖q!煁qxIzhChn"if}YHw7�  Ww#3Lr?Bq 3Opϔ*n:>+ Jq;3cP�.]Ct!9총8'n|aCƳ`0+^X]^QvػL]j$ o @v|>^Xwwc#Lj\HW18[=EyA(G4w�짍a$  `0c=F![7d8rϪENB g/ۢ29{k�@ xQUa K~9=e�6Rd hDRH x zi=]h [iUKE y+DzF)vF`FooMܙҾ{ۜͺ±.ӆt gVxAP ҭ_Թ)b6dd 0F3jܺ $g ر&t d#R! ffL?td/=�4AB>\�*"@N~s)m7R (c mɣDvP4VB+- c ]!b{WǜI ?a'D%DBP˚hO�} fZ8@S*<@Cx7;<Ak}-< t4GHAJ+PG"6g.LIjв/;C+N}:GI6]n"WSrEơ/}_~̭T/oWܔ%)N %eOǕJ27]N~y2}٪[F)jr\V?[FD>";Xބ`UV @~ �uD F6 Fe}+t`^�6tlHOO!t& m9aGZѲDBM~"\ƌRΒZ,hcv[A&/Jvs/&׉M%ďHM%dbNߝMu(־%擊U5DUR:Elq�}m z-Y]&FYfmкx/m\jq.K]:cic{prަַ�$u nsF`۶.mP9@w~TZy>4Z`J!׏>zܝ:b% N$7TC tر/.EM'C;SM, E$_\v^+G$�=(h HTh9 ^D`蕬 t/R逊(: cLvL&�Gb%tdIIGz6m)ʀV]*|Vj\IݝJ{SMSZ* vRp)-/Q|{VbK)f{?o2Jufnڱ -;|z32׎mu0ѕg"&ɯb S7WێseYQ_mMZOGꝯB4W/ԭzM+.\a�iHNr?e@"ni�|O$+�{ێ2dYX{Wbp|`E �zH�e{o~a\/"׉`}+V$zU1u&&{ XAU|D&{EYWdDetgN';wȎwJw}NL6l]%XID_gR\ UIlLÄ?83reM%bBM=lO*ˏ69P{0v(qt(qЇ?4A?9sy:ϕ9H_V>ɏʃCAzʏ>GWR?/mGA_oOkѕ'l䋝nR~%(%f_0ט�m5"@kѲB u& K1j+Q? 8"{f٩׋-BCy�@Ƀmx'N3]Nɡ#`wHNhB%C..nVGQ-ſC w#Q>xEKHU]8M-`RRԆT�HTlą"I1um~kHoEačIDb:@ n ^]6a7]@Ջ-#|PiWN*QCpG_w'gvve肪'2cNJc6?ns)lk}u=1<@Ii~_f(-E3dun;9ݬN/葀yRw ıA,Pfd<;1DV@? ;b3� ` H��^S`'2xL cPQDHX{]]C_Vv!aE⨥{p3J#bS O3"/b;dY/ӍuMH:%zD`:"H `MLV>) RH)Ƥ-G}1Mx572x˟s\[tNw=/؇֜W_1^'WSy>+[sS7.gIe>^X\urIFPö#?_y│WT^SWkWW^ )m6|]N?lC78Y0A/1d((1X9W @a @Ynq}[2hz/Z8~,Βo%Qxb³@-R[VTݪ_9ղL,6]_ehVdRCΉoM8'b|zVGQ% i �!泌d ,>tx:_ q{D믓1g.w?r sK[n!5؃lM-kvC k81Cd^~ &$?i 1\=4o#ß$5*׸y[ṱNnA*ammmt]9fhM}u~;mS/|Bk:o)l8?^埼kMdus3}3Kk5%(%h]j۶6`;FtR: iZyԙ +1:Fm+;/,=J G-6AN Mi�5ܹN,ۢtBz'r W-1^mykc'+vU{XML@<֜O'\+NYwZ*S#f:X V{iNrZڳt � dRop>O)6⤶8 A 75h{~s*z%%'p=5bR2 ?[\ntET~JX'-xC9 ':^<Ps"$+T;ת/f^Z|V3<"Β֡t'$|H|h/|L4ZuvkGĜup<q ;7L؎?e)o|\~ -Yo*e @Rշ@҉IhkB+&Չ-'  t,vBuMO6?\;FO 754Ei?p Xnd|Kenk fd~RFqq.f ei#/nc8<:t`eJ{6@A+S$i#h~@vI4Gq�-zR4 sx/gy 6{.pހ z /&A»//C9Mpn]!ܟ0H PzM^�#?ܸ;^7d'-B�A sөYm ^sLa>\A ۿI;gč m㦦4V[ `Y%q9nP :h7t|@K@Ƹip8f`|Z9BmZ?&FM uQtL * &z+B LfDptڷ *Zm*xhުks40jY@ywAy!!:)g3o&).%Oe5hW#gj8"!ͬ !jjn w& NfSg_&2#Mm G3M%L/Z;ʘ T::ۿ7=Fw_?ݷ\ p)`םOdE M`9!Mxþj7!G)j&e(ՒROJcyL}Z\F(ܝ mZ}:UY貵J"+4;+2!mA1-#9_kw%QUQa 4i1Mb{dQ <'UKUxM!1Q"P~w" a\hE*#\0q'<ie@-C ]ty2&jϳJV[L1*P$faf)_W@ ǟ֫-Ca eٍDžyr{>9g9gw<ԃ4̺WhҲ#v` dFꛠIAC #+t` oڜv+Z hA+H)ݴδlBLkBƞptg:nz9IGPG! 3b4R�ÒJeqT}@<T@ +;y /x7 oy89jg`wykp E8A ۡ=' O0> d%xh+BeIT={QW%re˅ͣHbi\"^˶ޖljqD٫WUW p a&s[YNM9:=SUq{jJS e9%O_pRWM2>OЂmS_aϘPJf-ɫo37kF۩rCZ?$\XI\v K2o i|liYs()P(*Y6eiF}F!?hͤSkj.l7ikZuml7E5z6PʚW"mi]7hOՎԞ]ttlo8Pxym:o%JF͊a&O<e^_rqXq +¸jhdId8pp~tд\2AX :afa~1}DۆpK{5OvK UF'X"7x_$4P\s oڤmG<nBk<]BPlrwa qcם!2zPR{;݄oiF8)ڠpYriVlڞ&mg$v2�Cd'i&ILVKVS b Z02Td5YCjLv ֻ<I-'{%p .|чᡲ_b%fWlCξ:}DIl*[16m䷶#3T 7ʡv!<C~ɷ7@LmSl JޥW)y]ml�ΜZ@$xW�$@ l8pdgV\+jɌpk9g9N.?;{ 6~7 MrdنZ9st9g@YZ3Á ]jl}E6Y+uhdԒ%O|'r'+b +B@DJ$vq%G^"p^U&@XA듏x o1MM _s g (4T" @pu5G yp<27оx3n4{K{Ɗ\s^+'8*!ỉfB$b' sƘǼ'3 Pw& 2tOHKԼ\~iU;WJe ¾ '. Lؽڽ{F5Ow彤y<ͷ\'$_;yCwޥs>I鰮;:ށryy_yhiU Eݰ0+*C/eUVpNuCȄl1-r.*2?^ѥ4 5iC*Y؁!gk@ M? }O�i-E]:ph/l o* IBЪVf5A155<=ɚhRޜxnw~_4]$. I3c2̒ ܵ>Gaƌa$ą~".״@y k@ kBjB_(2[S2mbo@0'� p&-Fv7^*  .߂.LJ^�=DD2"PaU(p5Z @WP= 7c<{B={p5Aðv@Uadݞ&ՕGQ@͙5O�dMvA R� Y]ef;X y,+K$ضLBx&X m @�!e-4D� ,a.|˗BH�! ȗߓ/ :JlԲ+;ݬ@]q.Lu=q-Lпq70m@X Q2>ȓ"cZ-R;7KHq](agDClFZ4GDnt ۯf!A? �Y7gg.[ AYVZ' \-{@~fG^N϶x:vo7A ".@z> H`dz6_qP F$Ct:4# ТY b`^�Ϧ ZVT(n$aK@}H گUk&WaHfm+6PfmMZ~Mյy@Mܯl[kN;({A~[^e2.Od a:u$hI[ iז5+(,˓ ><ߒ Ae �=T wGq8בswoA^~o A5e@:XQ9P=CD:^n8 Q7F!۶uk0z ]\\ x?>@~5svmnC6M2\0ϕ@&$߾J :p T  AL  a+ܼ7s B 6AE A_6 =i2{BC(-dl@cokՓ@ @F窅<C~+<v0aa%},M?Hiל05sj1l+MԉJT_MGe0){xb~db˂!mR);-(3Uzqӛ~0,G5@;E`XFP}W#Iby!kX9X^JJCBQ=nu}&U7 ^%dy Sh^x/� EPX{H�|^\qr93 dm!. -00F+~:00`&rv|`J@w2 _eYhWCu`A~0.4@,P D ˏa`!F$Ɓq1ÅgxH!4W*+*''+傲 da>.mL koHp>"om xtE^ L8jfL*M69��_ϼE?O'ʟ)yO=yLouN"lG?[C'v@ J t ^"̆(Fi0 m!{>,]8a 3Po VF=<+ K0zm6$pG̔«׌=QyΈ o/n`鳇 ?HRNσ"�C&^}`zY+hu\DG�BM; :AAu` Y~)kyvfCM'OyDߤkk]j{{-kd^NzFkdWvNv@*DILU1(dWAˌ"ĊO*doY].(gEZ%kFܺ"H�X6ʸ?Q&G'w">C:JK PψV=^xYim"PtM$۬B"Z.ouY ӺdVVg&B}11![r6wu6cuvfE T@&F8ۓ RHA&$ꅁRljb4̎Y#!<|ә=zqyTU@S߬Ja)AtBydUv̲�iKm:LRtg@zh夙m~^{eתݜ, Ա2Ֆ!;=oXOم RlRaP.T7D)&ľ&z6y81ݖ2馧[]zF 90w ")? 2oِ?O|TN* p^kzh(bc ['۴\wmvɆqm|Pzw:zI6(f̒zRw=7uV=Hn@f(x# N$H8[O\B;@YIw4:2᧓V2m74߃tCvqF`~VX 'vք�y(kW -8X}d~8’Usf5yĀ_;Z7/hGbMLϥ:KpX*=ݖS巷'-uɞo, 01#6P ,)Sw\U<NΝV_kN*0ޝ{yKҸc!/n Ο /uRpN?$n]Nu[]ד^x,ʦӥ:i-[7)%Ud[:� ,.>w7?W;m`b O 竧g)kMjfgwnf_{Is,l_yn .HIe7h`&0i+ t';]pv }/thNg#\E;Ua@  BIoh=ʐXt><PImt| CƟ'1pZ+;)t~ч%Mz 7AMm_ 4$y0fpb<ޜ<h؁0%Tً~#{t)AḤ!ea]?~1ɠ\@hgryoӬ{0"X߳]h^LL*?xG~Yy�GVpNф~0o˓C+ZB5xӟ%=AL࿱~f 7ן5I 7 44of344L-H f@G6lG}ZpT&Ν#^!9s4L~FC:0({d�6 ^Aͩ‘kbeI/]\ ;vl`] [2؄/q>Uxd泪Ɍib+˳NVdl+KYQ ܲRbY,ck$+QӒih\Q? f尌 _F•2{x-/GfŹ6*)ڒK AohI؍IdD6~L(DDd%__zSDq5Dش?aWaJǵiJT8jLerUAtJ+;{ p[kMj%6IshnkfzA/dSiٴinƛd^E Ц, ,ǁїN؁ Nj]fouM(vn6CDhw%կ-Mr# ʁ35-mi<;5lY30<e$W3 OWPx ' õ& >cȻGȰj ScͰ~ s3UյC)7F*d$n b `Ob86+!JJYv#.DapӃ"U_l{BC{98 覗/їXK(I/GK NĴǎ*V^r/3[ ?e %Z، )-Dg i%[;MbЖ3<qTSufsMr/sdKI342#u8 ef18o8.kp] [#?{ZF 0 8⍌$pF6 <da qic# .(Ih! A* eiH %I*;ݖc0l\,+˖Oem%)iF& :(* 7૊g#fҠc|&ig;۬mmlb=Ɵl3%bxߖ6*V&t۽. Hl{ٽAi-Ԋ܆gmYi6m;pV:v+iYM>] $.\YdaZL'8Z==7 a/D \n#d^pТ=";B8Y^`ERКU/`j0]-QgGB[!E>EQ)(jU%2=5 DSlUa榕}3 #4_,(L #PGM24qH@Lj* Rm^aK@#=\2 Mwqa1\fdh߰5e@OK dT:A?U؄#u6d^<C%ovn?S:+[hQ`-dgr?AE'YXaRu ӣuEG.PEt=L_/>:�#*ݷ[a$c&YruSW0&'Qُ_)[-è\b򖛸t cT}PRA(iE*ђBꜲ^}7`>$Y5$3"0"-�xyV-C$@i٣0Y+  DΆ2+aײLKRZ4KrۖGIM/XRQ&/,O\#J(a3 Q3% ϼK8'*Q#dH_Vg=I Pq$ F}hˁ;OrN7XeEF<{vE^9 %2!"Ɉ.s<"9]]!gΖʯ꤇PtoH XdhE %i\f!2b]вQγ㴤 Z'/e2=cԀҧ>Z1�v,cJ)lc(9\Y{.-kɚ`IaQ;@$/rӤeaL?�OX A+bw@&P< HWw�Ea@"A(A`fԗ0EC@p| ea^[xƖpIRJ Z~\ m2~S.d*֥)ʔOA)K[;OZ FɁ^nR =69;oܺ4#/<g % /@C�mԜc?S5#;k$dOΫG-R?hnBy6s=hWhlTL਀4cr=`Y?3fѭDr̐Q}\VmcdlPT O;  ]!d~P`ǠI"P.bkt11vqR=ʡ@suމØLdlu]WeYI^WW7mjL2OIiו/� +4Vc׊M;$2G &ؚCFmDBCacR\KWppsAZr[0?y>?sAfFbłzi gQVVP7+'T׎}3fv+i]8vQ|,9Z"zY_.066TTz.Jm9xַ hAP{M{{%@[ oEq!Z)Er%h<@'n{#}5rg@|¡2g ܁k ӌhis=Fլn F(H|xݳ\/<z-{aA9h_W*u}XCg N(=XꅵZaJΐakX҆05]rW1b-˨-l9q@!])n7B|J+wMp^0wYN)枔ߏou\HORf\so WtCt DN 8k0~g;Ozy[2ndj"u"`ސV�8?uM(FAaY X^e,ߎt|K+TJ/Z#o\?[WA%}7z}| Uzv:}A6W֡�xdQ֨tYاUJn'.{aU=-i{/}.qJWK@/86fǞD9X ?up'RM=a@� N@#:8x_|zBۚd@-wSN)9&qjRk11[:J#SFK\bbgtl\-.Ĺ8q ,*c=֮qGY+n >{߻^{h .N`UjC4R}mX M XsO~+\b(q*3V/PX?!#RrVlJ%U< B^ ukj|p2b85PIu0@@8XΦDz6[1Y=-0c=8b<kG4FHʶG {ҫY#bD9[<VG(ا#Z般<�)gY)TG6 NR*f Juɗr&UI݇r7֝/,MADZj8?kкl|ܔ>X*؊dTmN|''3r:?oua+mi>&80xBF3Ƞd͌F/Vd?*4'thr#5!8KhoV\ɓPUw{yEǔX>>"�m/_ ˱].8I^u NtziJ b#frZ_Ě?E!ek5ޚ1V$%ZFAQT}Q M&%&zr 75 cL32*l=P (s42Ψc)-4*Ʊ #�e˥*)i05בԝZ=;[w?T-yՊ999t4OÊhxZy}4ʝKwT\X8F|q8ϭ[vXOCjYEWQx7ֲN4=xQUKJ\Q^ 5\-ӻWoq[){ج2n22&ws-†A=j{('SG"6ԋuJ Q*Vo:8w) $e<6^ TB]ߎ9Lq8Y-^F ~]Po0t�A(<E/ qի8L9hBjv8FOmN]]9 'ȃIy<48A}m{F)gP歹SC8A0ˣVgXeU $P�/߯SzyN[}V=Q007?*~M I'"?=0evm?ЗLܕk2?YwM:#?L9qM&!Z&9^ g2=ɱ8rH(oop,:)ta!F(7o ktI} PoVy7ˁ&:I:Ybp+f <WkbU(_+^^`ە G?|:.`~?b P~-(3f Y| A [uS̳F#.m]sCG?_xQyv>Qja*5m )])NeOU$8*Vjh>s VQD[~s (s4w;{zrƹe^DPki9ma/cew &sةƸ5>Fqm|;k3qs?˞ x6{qs\;lrM3*7)gϺsW.m=_*~ѧk&RW [WXsZW-}~5/{ ElWþg|k놯- l_uk8a]Þþ5'a~_omXħ74'uϜqj~1>3]dX/4N\0/.w7of H* G9_8\Ǖ"i}uux)Ŵ#Z73X&~pQz(́n,ћ77]%h`sSڹz\rcQ(*o0k:rOomf֬σaEVy$a^/ږFT sI 'ؐ" 5  Bn r{r4x=b͋"3g=(w 7q墈Ry<7;&"y!Ea"RQ \Doƣsϖ7\rC4f|LZ XC{đ=i sexr )睗N,s?]Lup&mNpwe,g)|ۓm=yz4 !3lpKr9 wIoZݞ v{a"h~,9r+R>J`Rrd�F8y%x Xf꺶S)W9ewaMza&3hJUִk&K]:bVS.ӧl(E4,@(#9lf{18&]p5qzߔ@XR(#b*}uP\Pa/M`vZaNRszs\MtNu ``4el(fOkTA7oCOd~5Y#P0%U)v=m*h.I&Фm4̦ h{U"7Rke6{k7]�JMk6K `]Sl Ѭ 4?f5ܞdu=%vE)HċHKv. WDP(,اb6F3u{cċ]ӻoSd: V))쒽\, d2;c9ś ?f/e˕P 䣚T:4*u)\]~iv< xKx'JhSL_]BSXzW /OZvXhfŭcqT?ZVJ[<{EQw+=;UNJܣGQV)}v4vbGGjOR_ݼh>щ{矐G'',ep+ "%I~4W{t+G<=/iO {Џ厾1v}'nz򦿺hNiJmF/e?D^z>ttR'tu}[H5 }XoԽAEb:XSw|V ZF-AT9u%Kv5EG2rzJ?u;*.U(_aEzK q`VW;v53ˆ6^kZ^,~0ze󬏙5xihZa6r)i$4#DzLƤSJM3 Ý1d4󉴩,{غiD,i&+fiv- /ǔbSw%G|#c >q_\0u<g̡Lo63L8y*),{r΢7i.iOTf2[шHXsSF4#׽<bypDtto@:EO'3y f]w(TU湕 G Ka|&_Tiy7-΄O+[L<lVQ-5뗶g+ۭ[/9@0>׫ zVS]؛,?B+55=W9D۟2vr٬ճ!\%kz1On7TI:3\N:/óh==ùTCٻh9++^f;t?C6Ymiܳrlּ֜ e?r;|(j)fJ%; rz6}{̗ʔ{CqlE/:־(O^(>|#Jf97EG?2I'�#KtW!* t{@'Z[+Uq™_,W8(BE]VAL/ eBt1XU9o_}Q򀙕0RJTɦwj}cPb/*z/_(%K+=r^4y6b,QJW,+8LTh}Q9W *)+|9[y3MWCN>%+Y BzS]e@G>iVr|S˻n+xvñ OwgETJ kWjcoh^;uc{rD ጡ7X' *NFŹz%InڜksI C4V,>m[2ߴf]$E# T-vgGn1J(EKЫmrI똻+Qz{]rGF6v%*N jE! pa3`X<]IրJwifUn$jM<l X677pI^4|UGf<ijƃ' :vb!yyW5g<e|p N/W  zk:ζ*UeU~Bܗdփ ܪqx1r6iC>fWрvTʐ˱Q= WT d%C:z~:J%Ѵ5!h 1gz9@'8 ayz,tU--dXسˮ^H8kݧM=05xb-g!*f%]ֿDqɕ9>f|7mDg=s۬gȗv;A €[ҡ<4Pai+mdK?yH8Wupeo�>b[~5O 8)t-^4so5NѤ6dU˞Y#d ,_ʬv 1!Vʨwj*J62;�`@r݆<-=ĩj*A^ wנN`Pnk٢SM [I<<rWddžV{Oɱ8ڿ2L%\aC#o{%Z A+zvm0,_F+~{@)+EuYqY45;kMY\HKŢ}&WrL~s-;$;I A^% j5cM{eI5t)h -ح}VҪ"+wK=e D8mq@![&JRV ҫ=*p,' ҕդpUTLA+0PJBS q@iRl_+ki܂'}z3*վ{0X ; ^ߵ+WIqc|$vW"'>}3d)86%٬h0rKi&Gq)_ǡXtEdzWyZ][>z42:[+wv7QSw6\Nie+<v_Y]Yِi<ݬ Q^ѪXr㝷 U\,+l< ǣ-9DsSdܰg*͎eg{d(e74%KFrx?MRMҍOmͻ4vSm8Fr%p!|p=܁"jz@(aNtjj 7L/'u 8+u3㐳FvTo T*DTp6mN0qpw'83n#{E*Fbx�A-T>c$M^5ߜԽr8A88,b' > ~D m�'E;?!'2aRWbѾt^f=ΐ].ҕnuua8Rft_YÚusF meT.a7O.$ L%-i�Hrw&хn,2 (sɲ~y:?-OvMR%kҙLqe4@`   J(}�{  M8՛  An&f@ 4Ht#5֫$ܨ c� whh<pJ�(wan';uA4|e' ͉ڜF 6'v6 @8.KwX3r~8* hdd;=_';!;VYKЕ284)Xƞ́2唩ˇʕːS)A'!W~qWʒ)2`  }Ƶ=Ee47~o?Nce))ߧ=e/jOiO<"0nYwR!;?MX,k~Pyq! J4X}*w rKFY_/V>�WjAJcc]]3=U7]{+n_%q� Nm+]?J0p7gKeWgҍ8'㡸˴NL/{^&/9݉cg˱Z׌8It4vV)#S Md˱{qe {2c=` ^=(Vь 1'Na| GT9.. =W6'hu�"O_7;h2o2+z;LnIc9LG]:y|EdG]sϧ~kUb;xy9.MzȂVsi-WdkMڭ<'LvQZҤr!烸8ӓtf!R]q,L0@j!WVEVq^'8ba_5.i\wq_vwiU']Fha=zdvfAp4R 'HuS{RKÇSNeRSz-u!&CK!,A3J99;T9*<pSPp@f5OԺR1R7+UJDp1&)ʼ{98āT%``W79qp_?`o68wj+W6XA ,-@c}šc3NigKT>RvT *0 R_LyX$V9SYj+U8h4+N=)J^OKZ825aKq:XT Op?u %îTH}44SgG{) p?ֺM,8OS0AX;ܩ J[L=E nDJiX?GLn:�42@*:xs `QeXTqyKs|j| *&Ȯ@ +l%ff:6jǾ#ؕ}՞a\5s#ZKՐ %gj@XMnCT:X*7tjr|0Y<Q=H@!]*H'[c}&E_HKO=Cyp*t#"f|kً)6tU:薨yzJ*^)} 0܃rkZ'n߱hp~<.#z9^MǓ֤cm{PHL֩XCT\(JA8uwոpA[/ވW'qj9[7BgHêZq/6>26RZ'8z.Y'ܺ;?z/o~kkџ~GO>XcǬ}e)?2Fʼnt���IDAT^%_4~!7=mr\ݪ[nI);Hc2RbP 6؟B7㺥^g2{VTW5mzr/4mުG /VޖnuGcoK֣oTJE9p;9& v&kEioqxragrm@%#*dpJl,[[co>: wYkbڑ7x^g1q=k‘7k㲄}k^9L%*,=IA6BH*Qcs&S* )L 46Xzg^?/ы6|X F[Trz5cӦ reֶs IZCͭBCA ￐+UXZTE8 )] +p;?&\)jg6YK^6 !O*g÷ KYG{{:J6DvdJA,npgTJ5+EX vHM)'@QLE}(+`hr.P/ՎA@/g=1?ƞI'ozK$ fk`v5X;j̤-,X4hohڷ)|˭$KZ'ʉu Nw*LhL WX4KبVS[J^ V+@شxU}EbǶP$-rdRE땊=8pcoJJDEJV|u^-J3:<OX E0ѫcLĚZ0ĘM4JG"@}u{Ph vݒT2p3vf(]]:3Ōm߯j7]S HO -z_g9ϑ4K|<?kK5)t_//Y/1,嗜k//y�ۍbľ4{'m 3U B>a<%SvL>){-s'pGSnN2ƨ>npZÿfekjn̤1)@Ќxʰ&}2a~Y9Ǟ N`L,չD9}Žߎ^{|B=VJߞKnb?~O&8;>`}V)Wnon*ߔ+nŬ䘣W*}GZc89c;ϪUup|i_/qf j5MSJyev s3m9s,Yksϼڵ~ۏl8ʴO kvN^ NO|8.ӆUI/7Ǖ$πs=w湥 L%|q<P7́@ T&70#޺  ehcp\{�S9ɟ~@/;grX/M/'}}z=wqs}}n#j,~S-Htz ] K <Y9ST4Sj9/&$aXZ t59ZJAZ7]D6EǨ}]6m|?wp5p@Z9KY/v-ܬ _(TZ% ϧUfڄj+jw~]|=IG_ϼ}]~3$ ӱ~w}׵K°{wi4wI#m;MC`FqGA1K,cD|w*yD !!37A$8A-_7AO+;Y>SF?n7w˻XTJrouN|ֹYM9˩8;OOfxX|X|;\p\l'_߯{?ߣ;U<ABj7JP\Jw+]_?=y8`;{_FQ*5Df5  lb.ĿH1|/O*9#GRʥ a\iNX)1fL8*ӳl?%MfeebHeE3][֚3 TX)-6{Z ΀P ^w3Ѱ4Gi$]`ORwb-S]n+F])-UHݚ7 T+QVZ:ҡx 컚kvkևm&U=bk20YՀ=DOGrrwwGnsQ}@/4ɒ`/,.ds,3_8#Ov&}F;sLf}3rMzeA1t+KAk^S44A&I-%ym}�a!)~;O% x6n<bYB+C+`wÈ$5IF {Ef5(I&R]>+ZXuޮ}{÷Kݮn~]ۥ2/'>/ݔp8`ul.7fl^yvM^WzkիrEsǵzT?އs|;dKvTY'<u=C1M6694iM֠8ʯ#'e+ 3Fa!}ư>E(68 P^ exc`XS79d' ,FnPn'H b\~ ֟%[]ek(dLmۚ2KFx!=R#ƈ;bT6dA>őӅ|PpP׵ VRx}{KYM 멁Ku+q&g\(>O� yۊ_�'UtY!�;JLTp҂~|寎n^~ӿN?8 8 kn8;j52XZ f7c 3twub?.wgj?Z7zou#g49p.ā�mղOPEqέy,9[X˂B hb=ߛ4~u,9dYlhfݛ3rU2e4>>*v*18A>R猒[KJB?:�۴B\:>om$I hə6M¿ ~V/c\/9rO'(A^(K-8-i $<sYq->HAB86_M_2=y6ogƼ=fޙ/6O'Oy>_9usӽ ߷N7o|? +(9VZa cɁ W٪kA}u g`>3[ywװo kd}[ _p70FPx: N`;<AH/8呝j >&ASz9<o 4YFəҊ y~4|5nE,ppb-F<'c7_:F #vqwgg;9&�GL' 3}9^7jx֛{J;O [)rJߡsOSz�;c,g~`}: ɨuxn'ZD,v%i`m٩uV~}_vtV$҃&6݄V7[}2Q, bACr qC Lu+Xt@ǒqI}ju`>|B |,gZnnxͯΑY{%~Y{d&rR'K<:~\NLM&RC%E߮]|f}>fpvLFd02gT(t,4~W.].+eȮsW{hItvŹ@?w خQx2*AtąA'X{x4-+ɸV|\\'2ɲC|[f(,Hi}&1fft{W__&" ՞oƖu{Po7?S/&-�g):5c{_'#&gLyޤ<�{REꍁ9I*rx@X;lV-[ϾH%ݤ~5)>p%!օf% *uFpںdS`yKȁo μ6sbeXG##^F<C38A*tT*CjR%%ՒWk#cvE컜Bi:J'xX+ Nal^"^^د]A+~0~<?]~db'zv]C)Pli<:;e7y8 ?oo\QޮCaǿv_ɯ}*g U`ު5TB t ?pxjL-hVuת/l{%^v^>le-冿;~.oc>-æFoSMx[s))֏5 3=9SSÑ~ j8 V6ؠ^3jA 9Porbh-w~;պ*]h]Cv@+s979yc<b?bfkWɒ{fؓIIdמʯEOz{t m'zjO~ϧV=mQ6kupr]jB\}Ji[=rʿN:kb-VX+>ZX֞~t֐kG8Zr-()BF-=o]\z'Cg{>x$yB>v~-p~l'}{}y{_c <'{-ةSEʓC׳fr}͘IocMZWSϸf�3](Jq5-̟Ʈ%xmN\-oڿ\B^yuZyi/_[%v搧pV=c-QV9Ǐm[QœƊ,w{E;ь y$I.i~ݟ|mO)v}ٱsT(m6R_^yPT- Eu^-VEUR]߈SwkZluBQ XN.j3W]GN6)L'EyX㬵="+mDi?(D_ұq?޹Bm5(ESGxv|-Խ#^؎hZ3[7(2y\^}A8T낸ZQ3luSw)\> 6hQzICJjIJǨ&r�$+I: O)5,k p6VMxB HgCrJ+;#zR-3C!:ӯm$H(1'cz i4.- nvRKE=,у _hbɹ(WXu8&z ;tNB=A0+ ܿ56(v@lI@QMO6PnN˭jon)4 z&6! he�*V .f툗t*ٲ)-@󈘢 "u@0=1S 5iR0v&[99R&m˄o.9 @:QײELa+[PؑoPʷbt˱=p>Xl.'ۜz!H&KlqEH;"+A5bYkQ'i7jID;&APЗ日pm S/m\N0)6@?\k4Ɖk hٗ *  zԧ \^'u\95HO~�H�ς VDa4! (uK fZ@,"puyXKQ]@[{)luPH2^qy_.YЛDng?o:‡ц 䣝՞n`vs"&T[7ろ̲mpd=ܤ礷 ><S5T^چNBrm ݃DVD�q)oxH$υD?8_aݦEǖmNPlMö&D B[/B&6[搉xq%A&.VtE5; hCo׸dx Qݲ߳侖}zmT 7pzctaoJmAA{ Ψ! PS"*bqO#�s/s\3^< cc:[MM*@Sp* {4jt犊$!?'_[MBP&%Ӷ@ *S}h$ kk m4ʋlj6]\#< n(XG)γHW bPEAp 5=0zVf͚mz5>A6gP VQ(,H )Jty{996b5:! (jɛ2Gwt׏HK<b$W-S1HDOIE/8YSz|61KtF묭�rB?uЏ;Zt �ei:"Ht.CѨB�4<yݴDC6 [l4r_}9pnQ2bTr  )c >/ps‰a{4 >ǣF>^ƽqwBggaiyllt\@ ؇A+Fq͗C,dF3h dNCjQ< #;բLQˑN@J"7BJE(SנӃ)7ed&l)Qy(V@/q-1t&fe[A'˭�NzFQDhXc*1D}U<RO@`yR"B(i-=&@is67xt@�56};pG/v8A *mʭݧGeq vd^S pިj ޿u|%? BmR2 8YH gi W2�z5?^BUuMDt`jf%ՎVlQ4gaNM 1ܳ|ӯ EʹA�k3AP%F84I69%y9HX[" f>ib)ф2ùJFz#i([c�A DJՋn�;dxU`vŧzzdz:O�+őaJ'(H9`Plk@{kM"p/\n[dly\(@;:-nًE_ZΜK*dKݼ{st !tZ=8xA m0Y;76#;R1n ^MQ=,o+PETK>8q6,_̷A~-1ris7O5h yhŹ9({m5*_2HTr_YBC"p=!7%nf6l�t\L͘'dog4^U[Rb[-$N'pᚧ'�^m@y %k!NBx$)p-%ZBy,A ֔N?4UPEU \sO˂β<PE0+vL/�A^V�RGinIvH! *? Y%5�}"&DjǕ p|#FXb HhP@$1EZdql,k&nlD&5d5{ =d8!J#6^8EQmFqB::(u:bhp�mY)EC)Hf<oc 6`zжޖz)jjYx 엁:DnihR'=)tc(:Ɍ>O$`C77 ߷I9M@~inѸ@�@}4@@@3@H1DG)";k)&'N:`dAY&{nm6c~; PJ9@ "݁$Er`v> �&k0d\ͪt߳@�6Jk |[{uRq܀"L0{i0/A 3ז?J -uT8�*u8e?g'z sgmk@뤑6' N Oeכ>xnWn�(,x"]Y=@�(q Mz @9� Q &9? ��4<$ȷ8AL _$}@�0T#y98ԫM%6q>EIj/"DY Nhh�:L) @@5 V|E  l0ٓ�A -F1A6'G<@cYُ oC;n.hG</rπWv@@ J+ fGp/.Ȓ itU=9J܌FsBO.01*0�0|dq@a˳BI^uj0nhf!ߋ QC+K4A&!9`@ P:а[3APRlKR"uaAXe]lDX(mN@;i4DL"%VF.#k42+KR#f1$O~]|  UjjM nV{A*FVQx}[EoSnFw$~b{: Ը^g l{S FBoei�\vV[M^,YߒEt4R"$_86@a<b [ji4agHlȇhl+to`GP"6%MoXcHz/ @F&a0{A\Eb\W4b@ X#(ӊ8>$R3|{sdXPh1 j/( "G [B4##6X+HL3 +:(6k4[ `Ë�A?7ÆCqVu68 p+9| $"̃.N +Z v@ja1�Mxɒ=2p~uxm"; ac-zP l6'3j`ԦUrzYho⥷eވ bk%_) P-(VCHm4n@hأUE,IM<W+ǫ=]I1�JQ 1g,ZXe9OueIU?W%q ZJPcdؙKF5F[%Txw_*%ߩ1tX)0)8Xܢ+~+$mr E+1MϬ|D"#-!+nxOlxI ү&|<lI`~ B/6ݒmoߒ;nf.ڿm 7~nv{}~w.E!ҬS/[[e_Vt?9־PqS]_񶳻/}qJ<΂縞^o_G:m~^߷IG|VqŘ;woEbmƎZ5S%Ŷo<Yroݟ-O.n [ԺkmZ7Ķn kqe3ԂʗN'skǗj#,Ftt0"JĖP)a;_gt" cRMEj!ߢzkeu!:Wl{UPۉpŽ;-SwLv \Ty&tT*!6r-$6 7F]vYYXXl@w@I@l^7Pbus@Pjn$q:@ 4O N ܱ} iol�Dڒ`UGmDTuZ] m) cuIQn{M{}YD wU}%`a/CzE|<5虼LK|:\;[M"yy5mo1Aa]r%fcV#p g{ J-G}Q6; ȓN/"jlT8F<_o7`ѹ`+/7aO&b#z7@PQHAvE7hƾyAA$ \N AR$"Y><.mkz 7Z d`հՄˉ)(t&5P'<z :s6'�1qq@}>Cg�Jw]r݌@O+\]wQt#ZJ_-P!p=TEg$j-PE5&D!~{Z#X"!Vw)ntHjKv)ϯ-'?zvmz<;^J9ѐF+ZDSY\F\B3kҞBh&gn:lEܝ[ٱbE#ro;?hG 7I x`=tfy%w- 9=, "L<F~/hh鬸 6̱ 2z"0?5)_p~'xve]tsrZ" mr8QHrg[}p=NT�o #`<Vn}^|"ႢL=kjAoj ^y_6>{Zn ;xʕ &ỷ j0r/IԘ#z tOX3AU'z,Q+i"#�9wr#[A7S <=51\D#[ Ǯ GS,,@Ю HoeM' Ԗb0^?GvMZt&'4FZ(` ৠ@ xҝ`4  !(DoKa$WMNxJnl*.ۨc6 ~>U@mcz4 X\٣h nnMj<G&8@@ eފ &<qvͳKlx m<ܕg3n 1^kE+6z&8ε'qq6a4_㉨Q<l\_x!ǽqo"و'qwcѸ&D9ra˝9jPlƱpF5β׵lFܽ>D݊ ZO4z}vgŜ?Dz+xv"ާss~_}=+ 1Xxፍԃ'({ksOK>kft>rsqC}:r\<9u.vODX k73}sZC?F_$*&t\S߄y%~Y/߅h|gC?R3gRCQզ,>LxY9!k7XϝLk6 h5qʭޤ`�Jȳ<:t51@PU6!jDUǣs VU O$Nj56&gdFShjFi5fdn?nGǭAq?:ܰO$&~\6M -Qa+^˾5FU߮>ޯ鵻jZv-z{8Dk�7^ FfZc\<k��D)y*A!)i2_ h(sɚ jq9] ]yv~0 ^ 8kr/kU=3qkrAYF|2>`A-oYy'/>z=1ڹFLZ? 8TśUj'ռ^%Yam' ^+[Uv I?4C~R'A^ A<Efӵ9KI A l (Z4Y6(NaI*>HPpET0 NY�p-t(mb`u` נ Bs Vq ;>F>6^w4qTitڻqfZ:=}r:TB4ɵqO/۟|Ad&W5{4"cBCV$'/ p 䥭+#D{Hៀ =x1 /~_ UNXZ q8͏ZS\5Oy2qOS�AҵkgC!1&VNX;x0=Y[ʌo,62f:dbQ2ا:.^jRMs@pHHRVC=#Q4v~ e%3 r+Zf9UʢR ]fg"f#a1kgApM(IZLɃnit& F*nε7 \2,Y;b^JbZ.#V3G#zVf##ӗ\}>٬-^ޚ<{$y(-^4OrY�iXaYDɋ[M Q3}Fُ)*a%AT)G>f9s9=Վp@H2#f@݌ hP pI/Ǥ@A]颠Ghc):.`ѳ j� (: k5 6.>And!m:4ր̸@1LOA5hldHA2Hc r@@-ǰ?`g qCDZVAMrPw@yQ2)%}%j+σ@p&[T ȷMk9V;EKP*#䖹 NӺ_ ,_\"+?XK)vA.O{%9@#krkb8ѓPElr1,z6 4EԚw +%r*鋋UG½,tٕ:TU<(|$@N@(�ArgdP - Q�,{ gHcQ`8; h;OM+-�2aE&tËQV䠇n\KS `I5�'t]qK$R)lAu :8̴"V{A,r"tYJ.m&#jg47zS=cmDb(fQ'^nd@y^SElǽj~]5 @k�gd52n9H�OüOO(, 0k3o3 _a֖M@JuP @_=o _yP|u`Z腼.^Hhh"t+!(BA�L`"oDݡ@Uo&"_)'FhU;<c< GMK*PmY'(25N0 1dl3:߾(R| gˣFCP(NK51 `nEa@$S&^Epe@x&VBN^#?qm4G]6;L9Z7C š VM śg]_vI'#u?h1zA РQ n/:>v\v@ 1_!^'Rv= E+"=_I#3J_'Q4X5Ѡ(�<<TG&_u *d@()Yt6 Ht[ (`oH##=o3�(KSlG򭋳J8sڶ8HAܙ8868 {< Xx)xJg6nt zn\@TW4CAgPj=S]D-&GMfShC<j | 8mF50ㅫ$=@�@B>ْcM|^n<Ԉ6e6-k Xh/Ҹ5,ַ&# 5u9V`u@AB H�Ċw@9A8D v Ns ?ބc"P#@p6iW+/{h:4- Vp4�@�6(>?\m+mPPIgߤmZP ?"}Dnڷ44X  =8ASQKNy':;+<_ŕ2.RC�ɏVF`ޏ"]\XH)$l`N |l: Ft^Ш4~ 獼YL$ 059\.Hv@z4\8KVOcg.awBkqJIkpm$.(Ő^•L6}e Ҷ ~h\|:IJ艕" F|AjJ@K|4ĝ|b˯[8\� q�m0 9h{/8?cK!i>s3H'Y XJK%ma٤NfSP#˂ bIt')W h.VF&Ga87L ( FśͷyAr{Q.*ľo} lqާYپ"䷖M!Ŷۍ]ƕc=F׻oGt݉|v~ol jUlڻW9El�##DoeEs !K_=/q�tmJi- BFZܢt]zHb}-V/$#&U@VS_y-r* h1紏nքf"f Pm9q(%c _4m?:We~rCdU8]%$m_~qCӂjoߕʓ!xJQ�TCtcjfg$b^\R.u&`nml@&WcB'/QOFQ=t M[\Gmlyc$*ΖPxQj%َ@GbZez iT1F"C'x cH+NyWD~UNI"sYTV[: H~Yw@Х50t\$/6,NWIӹEӨ~S0YN1 #]m}EE68,7ļ yY#jT˚o-+ʨ[}oP�rzK|L[µ!W|^]u QG j3HP tȒ;rw+�WMzmT%= :iںXM,D=bI\~7 wrr=ި^NM2_J[suho#|(!K/n!9IUCb�ј,5rx;`Cn{E?n y! G(ZFǗi/8UpYN7pWq<4&:4%:63.߁:WU] 5pEn׸Za# K&.n޺o%<CY4DmU 3]-撾Eߠ,=4\^|Y_7j :j)N!m-inKjƍGWEzZud >tF -Zٷ.kϬֺ�49_K: XdE{sDܲ&Jr!|: eI" P{oX<kXȮhnǚObBkN kIS һ=#|ts7^߆ACA[9FcZRwCulh~o(Fl7b6%{afdx (::+T&$m^i1qPzj]*i(#VUF TW|A繕 @e?2P-PyFgsǸMf.@'  v!.ŋ>Bs~?ioqcm&4X9ܹX[bw%=HkءtY]O,c8w~ʻ)d.1チ+XsCYY//!ybɗ<e砰 &{�fǵ٤[t7wa+\(#p8KɈTBsF<g~7�jFa`<텺VB@?ZΧ=7q/mn|~~Z?3h%A4 MПae ,XRa&J+*͍$Bק:|'�>wB&X 3Ano%$=vFW lM.Va$H <'1&gcP O :̝^] fo�fI Щ,4j6c 7͎d޳G eAo&?w- $l5d$C)8<3gK:@Pb4k lw�.pCwA。1% qdB<%osr\M(llK5qz紳sqoODd\Xo&t8w[CNDex~7_&q1Pйujd)ܽg~Q{})pexzT<w㢑U'N/߁{g:gODFxoCٸ/x45pCՈڗ9ְ޳9 5璯'Da_u'}nB4KN$%lԞg׵u>}39\ĺ 1< v<;?:~7:ip?3E_/h|b_KWA]m{3ǣg :[;F}9yx֯93A{VQE<<sO?/^Gi>(kGNժBL O|53nF!`k% ) {Aq"QU~"Qwl{@e3'5ki? ԪVj䏧)y:?6.<ڄy\_Ch~=;�DoH_(WOx4? N׸YUryćz;)c0~NYu9qR{VFf>ng%*O$u?~BhsLt6~Ng5<\%}<=(WHs3%t˧嗵{:W3\Vl'|IARlDCejj={qO:x%Vw<z :_&3^;ǣAs_ j}FZlrpoV+Kg:]'8g./mqst/kKA#RL۽İ ,$I!+e �0$tM|dfi ̋hĪS<ĕ[^V#3\*ԤQO@'8We E=zC?=䟗${PTRqgU^ڬjiF=r#>Lxf}<L.il5κEo<ʬ@ I}g5tW'P?dr0-7y_df(f> t&%N&/nf-'@O@wr]t:'==tǴIƬ+Տe4tn\Rbqvz[7|9̙ 1~|R4N-ȏ'RY{|SJ>&3j'5Du*E:Ag ˑF3a@NѡZ G I)56Źw̅VChYћ<븒;Ҕ e^ZJdGOYyHL㞙J5)`E<=|z YѭQXɬ8f9ge>?|B:i4AgOi~7ԁlSf.<FĬBNNwd>goPK8�e_M&6J' 7ї@v[ȈecjxE[..E/3F y$<{r6ɲlvj{x׌38Pi6BC1j~<u!;W)0  x T,Vn%p~"4aL^e+g˳�/(=ͤ@H *]hd#=&kbF!w\ke@n1gɦ.f.F^r9h5�#KB=֖y7{J4BLi9Sց\ÿjfKgW:=D𘊎(ent>3++yu/k3z/J _&=>cy_c{tnh_@RfNYk ;'ͯ(N,V Lu4 hLf% @KNzr<MN 8zp(f@N/yZ K@$' )Xad)-?!F M5 }[G)6(6&2āEUߟo 4s<c߽u 7uO�6EAmQ(P?*N<zww <> )<G (^p-OaQHn&y:A#,L`fw_*PV,.˻@4IM'L֌k D:J_00wp ߃ݑglQh^e<7G)>}@q˞Vqshpt0"NN)n t]ey͋I XzQ}ǩ(�:I|}dՠP0ā_ \p m  J'@wܙ7kd(VYO Ny̾` 4ME---z_ 2ܸCFe@ ߬x�Xl8 =8I'K �q%kb8SGalAr1a"N��hƧ káhUJ,kzнn_xUq[1y<O0�y:8ޕ!ӗ4vrA1<YK p8l2drCho.j"Ը5`.g@w=6 ^I2FP, <t_Bq7a~({rf7t `^~!7=A7 x s+Be%LACB-6icqO[ @.0"E�f˳*e=I7Qpbwc3XG4|8%p-;̮DPܴ gRz!`l97P|46aL'OK{r+E@-)6'@^5e{X= ? CI'L]f=8'P&<'t:5CpV>#(F˜['LwmoNA0^s,P|͙6'Xeד9}N@u 5Ч N\P eb x y2ǔ=|(Mm|�#7bW#/*"" 2|v׃5@PU =Ƭk@ޥoS  .2L /C'`Z Lko&|OEnGyӧ�o⛞MEf]=SGф8`eND/ȈuP[~7:95yJz u�ɀCP\Ee|ur+Ӡh~ 5%h2| =/:&?/o^>C|H4_*Cmk>rBCp=עkN|f=Ȳ/}Lb% %~)[NK+[|$�Qeϵp_? S(Tgԛv6q5gܤ;a.wCajk@kVv:a^"qtb! 5+'q8^bM=s`"|քvΏ.^@' |ڒ}2qFEL$, m3 DY /ւ^?g.@V0 2+7G?Xٜ -l[KgyRbB ;g礄> /(o6)!M A&lX \r߀])qp%қn,vj~㵩ט`=S u H)_=~oO{'^ptCxG.E(-sQNP]ؼA�$v_{O+~$԰lܮ%}lypJ-8m_y/qp1Z{t֏.MmE \ŀx }4(v@H/)+/܍E[NMz ~aP ؉ixcs'ڇ(nU,C&&O:՞b҃`Cl^'w)$Ot`ҋN)G>r[^Wk;T1got}#Pr1SZ;+Ze3o<wr 8&/%glʕ)U$(* S~Ak>7?Zo:(J5;õvןvI Q5u{E2+)w)#}-rSa-t2VedVy&9]Nަ[ݴIA{ܕܡͣWӳ�^Syu]wީ7t_[MPpIJAczq..`*ltp~mN jΗemK;7ܥ}h1+%Z%璫I<R>QJ#F&C]-Y֮$Oa+L5BxI8өmlM@% b߲UHRSe 䔀?ⱸ/┕RSq=ůh4hrӄZ*m67RoNRfQM)!%Qy2vsMe.2,}ku}OmI_b ;HY$p*M}U9˲ #P5/]bI324?a;ZKf:F@ ZJge <ck*PFjbލG7]:!U(s%m=ngXM.dDB,6 ֈM"sijUX#Xo* II) ۙ #EG|vcn\1"{4. fGıg$sjo*xSƔLِJ-GF)qnSDls6IƎN 2cY!ّ cǡ'T,(R9(I6.WQR;Vk b S@ Y\d96t 385;Dm:6xt<j++HLC0wL(fQ6hdۓv2E&keu[oI+Q`_k'`dC\{,%ʅnLIhHleõx-_i)/~+MUB\<̊ [ h<jK#gWtQIoOBkUrkKe) &MU83VaeB >/8l9H,7䔟yt=MѤi"FA/Ds5x0s[vF5 \@YEM u~%x)ʯtĖ.sq$rYcE/քڀrhِ9΢Vs=lMȊ 4Ln&;״q/O+mfh°Wcvd6xd`\g障p`T5`DKݕ0u-%AV+_AylMqsq|2,i}v|zTՉ-O/cFfհ s<2%]Kh�`4뎨�7 H6= RbU8wW4P=98ǒĀ`)L֫aWo\z4}#\!QcӅXtrg(- kE_HǬmiW߱WӐzKw-%XV[ɫZ \P[w+B3-P{G1@-Z7GǮlx+p+ k` tx Igs}:=~w=yN{_KO9 y6a<{"xlxnӎ{jL9Y۞s`gSOڐ_N<2%a^@CI[M)o(#N|ʭť%R|K+UB -V  lCc: 8.v'4jIY = TDPH͆V@]6():?W:X.!�A+%zH6(甿)% wJ/jغlE`8^N+4Mv-] F|EQzI< o9 u8uf0efKM-_�}]NՠZj¨?'jj(V7j޴7_˓A>^}F,je0ꗥ[>{F?VK| ~"\W_A_TJSҜ": .e we&]9`Dtug꧌wja(ܽCۖmP'q0> uV�HX^篷J"y׽ju6M&u<qj0ZbW~C6Z)Z]I@h!Vt%{a]~JPf�N]U p-D4-ڜ-_ItA@T )q�7h@X)d?>vju[@z.oRx{ ^.? ?Ǵݧ?Tc?Y/j~6T?A=w59wϥc!jfiL ` 8##HgYH LUZ6@L3H h=.| GK^:.};ڹo)6Uq#΀wZ6'`kk^7u" -JSʡPݰ/fI6_=n9+IJs-´qK[d nn�Forn t]`�A}$YQcز@-+ _Rlr,cVgs3UGL2^1jZ}3IP4Q&*/^HpCZ/vi/(jkA%)ȯup8~͗_\ʯ Ѳ̲?g+28r9LfN49GNv4B,jJ%s÷^5AI"flqhXM9nZDma.Oy(ݞEu> Q;Ƞn@zy<l&~M>8,|�s~N @]N NA'٩6'W8څ[`p+LNm ;Bkf v 0z#wQ,$>Csr3]͟JcI'}><{Z?ß P3Y_<Ǧ6bmo/MJH#K,]IyI+>t)p�ʶ,Nf\fD,FѴ}Ѷ8ܣksP*x߶N@@yɥ ,PO@l;4?,4(sjIEiwF!@@iIpC_X{,8h6oufuڿF7?{:Mc俻w#:dgі{ح=莗s]N�) ˹N)gnpSueZrЯ;5\b6 ZѧEpAاǀԅ0`+O*@Í$/6x]N9t\.pPNk$EinE֞NoBFiZ}4# W|g fT䂦ّ"vb-� ͂Y_\l 9tRNFcnvIkœu+P ;hm?84_<FóJC ?(�|k:d#{;-A<.%#+$Cu\Ξy!=v$uI}gߢz N �ǜ1p1PH;a x޷> p >t&w49zu+Ql:+Ǘ N �|3il(.XN|h{`rjR2?8g? ˟m 6sO4=@Yh'A- Ljz& |45͠ M] Qg̼oEbUmƭ8m"Ґ'hĐjF%MI?zg xOCeCnPݛ<!1+ۭy–'(ȣYc=M)<>&/BCR A'5})13`w8M!=wcWެ@u"v5W:#5N`G; 8}OFH >| eoZQ/(v\o< -0�. "O-8; Lf.>3`N_V&D8|sH'XJLMG4ՒM@aDW:x)UȌ)GDM7̺ a=^~CN:B"+xa׫wGո!ͷMl zA-%a\f@N *,nӠfF(,kּ#fbG3FK-yEq&h͘}^hcG-BY7fnLkF.v oP7y6C'k8e]n)O\ϗͫԌ_yMw̫iiL| {Wc :vAFV赪3_pz9;9i?T oo9 > -L@&t55X4rz=~,2+Nv͂op,BK5~՞EG. hZӊx G�_6X\MF h[iHt/rm5Ͻf6p@0@= @@5#:@ۛ�Akc[趎PjH/nw}h&z8hRvFEb =jUa5G"3?`55w%zXxC pҀl5effJ{f#WVx9\]JUՐ6W hA@+^p>Xqmyך"f6#ȭWʾQ.] ^[z MM -}GNjrr){i,GM?9ZXocjOhךVo}O֏QZu볯jt(˄ֿQcؕ>V`266_`.�}> sIqFD3f)ђ{[2.Kjlr:-yfmd=+6+Jdgk_%yy Oko6,j SuYg%{.[aon|O5s{TT+3':T~fԘȯZ9Ӡ~O~9y/lb\&G?uhO=(űcRIUo'i}YJ[ZϵgBoMJ^[UoTi�ȅ8Ɣ3A6_Wϣm}:M;z[S|ُ<l1]}o;I["qKS^e㬺J1پ[ܡ^JT;hx+pOA3Bc*JCF4]QLp5wd,Կ&ͻ8UDc5RRмMu[0"p`WV%]'n0Mᬮűn3nQjb84v~Ja@1:Ku.hVtP5UsƓ)j,147KQD4 J!œjΈu<:KyÝI05WB#E@eBlR@-R;X|\*Cs[Ci*Ve|d*y(XTNEm K h|-FF>W- QŽ5_(mh<Z(J鸔/ (EZ: cSW+[G( ;euXq@ MfP DlX\JıUͣ�7yn᪺v"YSw F !FoR{i,__flQvA͈v {YTGK,muAdsX Di^ʮ!VEZtפQJDϘA3=Gy<F~ZfGoy%[ @kZ ;ZL&V;V7#?{23Pr,HhMCu࣡h$̈ꌑ^$0=|Futg6<Ќe*qoI[@+ uF\N[ĽvuW#D~]J7Da; �=VG"YjN\ˎ� wkq r 0Ǧ{G|I@a0A=Jz 8wlqՄG 7Y„8ͲL+8  �Rv4[ʖY1WmHg奻v]0&0-F|GslN0p@`RCDtWx¼s`TrU\VL @żM]b/Wmn 7 DzqT({M7tBr7J)Kn}]\S7p=wUt\;2awe܌Ľ�wS%Д?gu;A+a7Ն`]?FMټ)KӪS?80o!XHSv!XE<6uGb!qgh1 3ۨ2i;B̞P  �gg E;}sr(/w[M~{;l`.ѽ m<Y.K7K2UNWW}9wVj?MN3?n+*looyu: AP@6DBx5Wn [ ъ7tJ#;袪nrl~xp9\a!kjxcջ;LZ {` �k7X5<ªiw8^dp{x26f39z[3i;nE[҈Ak O:. `bֽ +o %OL]~2@ I|B �i7 !qmtI較.xaxy�W: Kt MӔKL Zդ Tr f56DΕ. Wc�v=_~XM&.KdsE{~?X Wvћ`_L?879=ƶ\@>0)=B+Z)[(ݰ*zux) L Gxc/Ƅ6 m[?=\MV.\R~uX螾2,s႖P4!3us߬~ݘ훺{ñ$ [#39,~ҝO3:c<7?hiz� x{Y3_;LmFU� IIy u<@/#&ȁ0ݹ~b~� դN4K.;X?}O�9˽`W7Jo>K΢7  `WV PR|$H$1"ޭ{djs%jnw}ޟ[*vM,%@N -S#]î!Q s}h9 (ˡt­֜ݻ;c0$뾛vy&4@ܦ?ߒj$yYΚ䆛|ҭ>a0ۚ5ra'Ǜc0xedE; 6 .uе~H5q͹2.p@p7-3n"G @ݫ0nt,ϯj�(r}E{8%~Y / K2W'<wt5yGO z7)tŽO' ``T* `fkU`�9'm?bO[trKj_~.>ɏ&?@``yj�gekvG T5%d3T&[FsetUmGp0OHd pNBϝ\,b}#QVUeX潃|㖩fD% @t v@evx^wnVbb@qpBzr@zCcD5bq?('ឨF 1B>lG�C_PqO| t|Q^N՝KR@,UFE#76QwU6jD}}2_~x'91Ao^vɅ!2`y,F \Kmǥ~bkƇEiϋ<4 v{Em@W׿Qgtom(w8@֪>wE?΀KT?|d'kiܱ!L'xSAЖB'd !'c{70J|U'�U }{s\ tf?-Nlqi-?'b R2Ctj+N `e>(|]hyՌj._܇29 14Ќ$b.$sː~ko@t?sg}8P{~%\?8+cm?Ohٯ9(%3i~ p ZޡU@�  g@ |V﮽߫[ʿkCyL;_GMʂ0�@ /9v0TBfFd xA 1؄?k^J6 ?- h- qh @ZAt5~҈oAke6dU8-M[Eg {$xw,t5߳\tb)GHH1v>y :{?AW{./$/AIp0'/F6?{]:QC"&r%i[Q>2 >7b/%*~?w2ZiynUr2& KZgCD_H%kuXbdb"*4@@i6 xLb7 &eE ``KC�v'=&P: Q >D 8@ j_Cd u# OAuxn*n-uʹ oɝKT+X#хU@`=XgE ${D^;&k}UМHPCAr$i+lZ�NLC*`& f9-w!1A@$W% \h$RY-y�p_QC`g]@/Fā~.mo?)$Ƭ�dq'3z 4Z^;Qf,*b@n4�oAĠ$D2'l@%@�#B h[AtIɠ ]P*T`4y0;r{]'&?v\w� Cg*Hi1� *xf�A\ܯCCDM̺A34è*3ХD"7S\g%<ޭ@.}:I̯P!\td�x&Z8šoiDQȺf{ vfv+<aK�J>y8,8@�`x<ۮjYUo>cDq +ޟ`ؑj.^;lr'�/Փɏ*KL4Aaa�`#=L& Ab([*^P!Pd2uiT*)u)N,#�lfdC'2 feEp\tmO#%!9C"rm a<ys(Q­�@IתlܡC-<2 V+eC.a {jyLq6T|D7ПrT.+g~4*A0TfӞMύOܡdrCRydE:L ՐT� 8k%`>X_gTV-VE RwF%mtSr300+ٴg ۳f{ pOE2}.~?h"4p4=&0=ܣY~K9#ѬdpK- &`s@@tZ_ϙ!e=x0T@шސeUT2fˬ�!;2h!�Րf?LEZ 63ty yxxlfPBD �Sill&C%u]Y)k[tPz=NoWkͼ~+�*N`W3!rJւߔv>6 ^ӳ`?y'z.'$G{Uf@TL}Zd`|:d0:}$ 44YA])fszC+ `qX&C �jzVD7e{8Yx7l~~;bc���IDAT„o\<: ph\H {Eg:(Wfo;5W#gWG^}uա3xo,9z'dڔ:RcP7nV7v_wsu5=`rutsɚY7Wx?# L[ʣCyKG꫍Gmi5קm#`9j|k($z#/6s#Ǐ<rgzsi&z/6Vsկ83?GVGӃɹ\su9cz}?*QW컸<DkA-XY{t'jbG?XǗ'EzdQ^ǯݗ[|t}V>Bڙ5'6V]|4?*_fsG_f{ы/\po䑖<}iܝ]]UPoe\OtvOWM^5~CD6]wC2Sc+QןeJ7~NgR =Ggw}W7܅2'u!}J}ySl+;'ExwQZ.L e11-\H2{^k�lDxg أ+!~+{ =i=skMpʴ}c| ~o<:^jǨ e#7>" Ď?~t f$S ?9O,Q8veR!,:+s?kIsN( B!yK:cwP܁JTc h7~jt#`0NvһȎZN}vFZݺmaE)ߘ!~Da*ٝVxko[e7{'y>r1VGuVl.v@ЦUYHl]5;sAtx4o-ٍgdB5 mjY1ZPM:j1s:c7g)2,Fݴ"EFʆjFo*Fz@0BZG:+*뀠65E =nn@Vf\(ui:-&O3-̮%`<b=*eh PÎV͜l%մCuraٓT>5p%ٌ*A{f7x P]S.ZH"ұX'b#Fjf!-TYt. _^bW=Rό ~>r ;r9^&FN\΍x50WV і0Tg笧�StT{|sэK]w@P wF>FLv<u`QA3X�2Qo1msس}!bZSٜ3#<ΊaA!z|edh%>bJyb@PE i%G^1Ɵ#hƒ*[Ѣ;0=*lVXP#k :ܥUӊ'sq?"6WI6RSHU5;eZQ  %ghЩ["Kkyr:b} l=&0\g@u@�јA^Цǝ kUWn{9;'gaM,FQdWԅzgGSc,dkե:bB|qg.iwťM`Ϫ5`QQ/ڟ$pU HӶ͕!2%vg֜P nܪC"q36fvCgcIYEv`�VnpNN{Puϋ̿n[V~343qfYK8^<?^NSvYv L@ pB@XgA@VLfo&HNئ@ofu8Y}4bֲ�zGS~Ul򬝶EF.=~Iix 6�~isz-sk_K_xӽ @&ԬK)|إW4ń_J_z adAR,aсbµ\ ʲfQG "Sո+5KJ=#`νrϰ~SnAJ V Ჲ@E 9@` 9u%w{'3ҙjW:3λAqq'Pr q6I k'u+d_DV 8Oo:&8sq۠k G7vdk0E[@:WN#q|Hhv) 72FL0yX^ztuY=vnK AsY ,K/h/`,@T .;੤+/uՏ^fۻonjnM_jmNhJ݅R iLnrXۚjv@Ў{v#N ak.'o,,Rּ< <ԭ#r 2A# dk&2˶7�Vġ#$b 7a3ʾ+̼{ePA1V[K[i&bN>GMԜ+5qcu^/M]QWq~D'+S*ʄNgk+:\gL0J!Ԣhk"k)j^P_Hш ƿj]Aq.%: xK�w|6c~rי~⥻+]Q\j"}e^GhՏ^Jtd 6X$irOM#lv| /\;.-a�k S_^ٓ�H,k xZap-k p@O ~[k3ooT?s e߽-{EY�ZJP@zς6}B@'8GR7Td-> ʟXY; xP"}b.^H1DMѾ"4>=Pye ዺ 1ﵳǶˆLt51c~@e9^8kKaU%&Yq ,u> BA\lzҀkedz ୑ ,\ o/%}OP<=@ ,gq@щKÀZp[n9!ߌH +6m&ָԮs`v@Y3 Xje/@Plow@ !1/~Z^_{{~``ȼ%<vHN*tAAqV6Ԍa樳&jl(E~*~&hA]\u@pi.drKy!Z .6E5硻N/:Au(�9L^b 6oDB]�N P}ݚ%Z10|<|/ibK9׮9y&}n=9}X#\9(&wyG..]\h]vfoZܭj] k>jXje'NfC͖rqJܶHҲ;@1!jJ tl\ϴ qǷK\EGku`v@V ^^b &0ȓ`eO jW �>nE] A f(hT"8p{wCp#Π1xV5c@; Qy�Aþ� wr IKAPU(uAa?]zVm�0{6A�_.iCgyI@}lFL9&G]JRhH1$qpxkӅ},;}!tP<WņWj40[c`'r}U-n "0 8R) \XYmJKa|b} 'Œ�~+ +?8X=3{ TnA@0]i} p 46qvI1<OL`ZsLKLJZ ~`?N̊AYjI &Xf6HF"Z"`j/@tr%^x6)ȥz~~@�n9r~˫1k8]ĉ˺@0Mg-r%]:=;r)>KihP�kkgpN I3=G/ȷ2vn SJOjdbQコ� 9wtwrC >�$ɛȊ "1&I1$l+:ЛCXxn9g 9$FXtA{(x~sr{:2vC1 Cq% Ol1ë5:+\Iإx1[aE(v foFQc $mI �:`BI1RW.V-y 6`+XV-M \M:uՙ [_zvnAD B(#Yzab@~7:sϭg�`NT7Z4lIfyIsԥmdmRRѲtݖ/UWzX+f@Js�hA5u8ȚZk \[fI P9[`@=ydLDlZΤFQ2yiAl/ʵE%{W mȕtcv͆8�ީ ƗNHڌ+gm~ˤd> u6OЅ3:_&@ ~uNh1-p ^ic&wdVyWJ#[%,gEy6Z Ѭg>@0Ed%K"4{Is%L`ٕ+yT8[i~zNZ2gVw l♣gJitҳ<? 8Fo|t^rJv-ʹY ݆IlR)Jj/<9t#QD;= PJx{lO2A4)@0)�EL Ow05 -?pVsm7EE<qn}5eѤqigf[,:Ơ=~r~f3֙6i ]$`y06EA!ԝh٧pd0tՔ�?MAD/wsN:dCBgaNqf6d*ҁi{'ɬ̟ѭA[La^N*J}JjC0'8lϪpS-- eC%9fYYiւà=GZ_oa % Xx#BYc+�uA˵ijsk$ܽZmZVkԦcUFΝ͝e'ojo:Fk8P\yw Jjn8{!YLtO iv"#U9َv])~Fk ;Ql6^צ KK'5Kdg3Ε3z#6Y<8Ӕ@OWs2^4hTҢc$0.>u{{fR)O̅ Z8s9W*,JTWԊJ~+.n]:j.nmK7>x|KF}|L0=2 h-%W␙Y\ύlTP[6ڍ߹�b׿w;:?OEN}'>k% ==Uע: למ}yߍJ_JGE;qMќu拳*FvO!}BQ!Z^ Hq-�q#qg�~?Y]Z[=_H lD3m뇬xDv Ddt@L_K>{=8ÿ=S@(u\ɻgxG\UBN\σwЀw?3D8bׯӘםTm o OW:Zv*BHuey=崤)?łNΩ|,-,XZ,wr`ÝrGf <Fߦ*4AC3ҍDFͯ)!RK#uvݣ{To[x"Pn`y|[z4ҭ B8A0mv7eߎ7tϿ#K64BUݾXOu@{7{ݝkR<RK#ގU{@q ':=gh[JB"w@pcyhPcp[CZNϳvOux^;uCnAijٍhcZH$LtG|VJ4،? 6Si$Ci =(eX{Bm6q5V@T6iJ~>zyr(ofO`6ԥ&qrTם<| FG>ii2ot7˗Az k@j*FNLz2J<s|v [c4"bwx2 C #Wct@;Ǵ3Fͯ'?0y.G1;cX6jZo!TZ^>|l<ۺHߏ11ؘW*唧6;uT*Pu%yt%gQJ}`K˧G:ALiTN4>:``$})RܐW /R#(Ql1}-O=c175y`۟?u < gckǴcpvc镋:JWg"YX &�PD54lVp1э4i&o5VfgT]8`xSҒ 62\ZNY&m`2LG3f򱘕.ks0o %Gt!KV֭�w9cr i03h{ KRp=0-k7=R;gp5UFKGY oi͔e X5+2XH+gJɳQm,5a iSXY Ǵ[%NV2@X<V 6Ю,-~{PuJ|\:/AMm} m>,]Q'5!#3@1z 5w@`7@Xt?ۻn3D 1r$(#fgbhX?2V*jt?4cfFܫo-+mHDC>|1FDÈ F F^�=l )q˻-gJ@PCYF`{"T; 0]z{?"ĔH_4={,a% 3Ybe& L@7@ ݖ^6KZ \Y{ JAYRd>4[@0hG#3xpТ ^��2Vz0S a<7-V֊Y2iz˦\̸z+ZfpgM:1 2 2A hj`J՛0\ %5Laŧ>BLbT: @�iigl4J߹nAR @�c@CHYiѩE]m~�"&(Dn RgMO:'â5ʁ)nQkiiBc6c]4X޿S}̽,K"i8@eYe<G hW۹xC=qĀpMkoZ_9e@rbf`Sf $"&0;uXL�$V-*t+\^/쀠H @2KaA9tRC 8r@nI R6+aw*7qM8J[醎n"ƸwZ6o*ǬL#n/�*Kv$�bF ǨR4щb� "PC\}n x�| uډ�F,Ic44tH~Oק-5DOYH 2:C4Ej<F] t �nH xͷEݣòXxtN� zxF$ 0_ ^*V<:#|N.:JHL4S.g%5^ɔS:#^a`6*tD;_�yQ-4]H:x$nFw5~"-n=fI4f١xWE L�Җ"� hFAcejQ"J؎Np@@ �;:`f A97; f+jex1y@2&q ڀ�% KbW Q> `^4/XW`xIX?Ȯ"x(� `NN;ұ>~tUh ʏāŊE}�3$F:�X붵$%">Q 4(H: JK$C󨎊@0 ;Hh6H:R~iOPbv�`RSQHH%F hDTلXB>5en X9| X}@@RxD\A9Y`<g}MU$H�VvDy 3) d D~x6Q{T{G$b=~b0@`"(UI⿋Ng!? Qè TWNP�A@�0 '0FA:H0$>0\@?�t4J|%^庫+:8_щ$&K c(tyo-TۍkŠ& U8w�+G_A1\'R�8PFK2d?@`@0 <mutYuoH�SB2DpAg\vz @Vd:YBė%> 7 Q^#\ JSb$M"n#j,&�xYj]4W-XX`e<T<M 8ߤ}wbÊ,r HaHPh-F�32.@ \YoUkf߁| ./GңJ{�1Klf y>VލASFkV)2`[ˤᄰair8?}Ihnc�A%3R+1>C8 lsrp4{=BW1LXF -+'>VX9dPU1>V31`/;Vϰ| p3G m+蒱HL9F:A:8BcPj"y/^TW; `gKGZGX%]ooJԠmrL'&@,kcgcl蜆9c\1 3hB A *F v@0 �5: F)A\Fs1bU4bzt@(Ƅ+A% Ap 6�>:6q3m Ci  4QM.lf�Ww̓ >%iTNJ?F$)IA^>7X ? AQ/?#*ca hpM1EᘔW V2vO NhE[0jSuטn&]3Ɵgh06wuT]_)> ̡Hܔ0=>#, c,ȳK&{6ر3Ϲ?1A 1Ő6wGӊ< 6jZ9!@͍3v)2B(h TP�F$P6$J"0 5@A"anȅ"%B/tey,WB +(͐U |D[S~5X_#=XE3uBb{IFh?`f~A�a[j@pnWv(Gg<ZIɇ`3VQ>6aҮ+*yMr_5aC 9B9T¦]TPV je"(<FBP}K2jq|~ �\ZPZY#B}J[,za$@PPBKǯ ZsǣU3jA!`Ö^q:Ԁ-A; ,-E+yWH.A@ 2#QUIh+Hx-h׃(-v% '~Tr)+1ڢ3�DT@@ EZp"^A(/P-on ԯ+;zrxі�f6-<=gȩaiA@t@yV0 5 U5^YIR0tNlp E0*B?tȮit1:бbH~C6[UU@ i[M}Sk+"J#"eL50銐ri`:/.]\ j Zߐa{I-nnH'ȅU:,ƷVb?%@M|jn6j!E7Pjêy;mrQjkgo9j`u3݄fNzLR8Z\zBM i":kk+ڌq9܎,1w@pu6h�%ה_ڊ^УX`U56ckm٤6QSjPJ[eڊsH'g`jFoU}f6&`^p r�@0DU~|KMmnuavImճ7mޒ{-DxNq?ñJUm{^5g '�T-:@n]h<FLk%JF`\:"iM Ьhe2ыD \[nQS$)̵ŵzq:mwa̫N)؍%jֶoN=θ3eEB;u o]h #ZSQ:[\e7RFQ(n);~r1eExD+OEq\nI}Q ֩Dv\YyCyD#i<h;]7; j~й&5)L3͐<)ꎰ)Å2ٰEwȢ.wTS}p+r3/SɆn-;vwHDW! @:; kS%XNR&TZ靐p"{ȣN˻U%|:*:s^"CQ.Rto %\L7ټ'}1�뀀"^aOQ6<LZ 9,sлq )b^Y(JOEKVIVQ67DX ] 59oDH1iojy�yaZ<rv-ѕ3+Ic$E@'ytȻOݝEI)ƁNY wXO[6쉮Tw[:re3YՑt֩*QQ; @@=X�ԣL6ұr~b# /RJy^ޢ߬Η1ݣ1LDݢ1xc*AjOwQjcԔ3U-ӟ ;܆M`>m<0-kstY2-=7qevg`CM|vcQ9&fl1ds7cUm Jʞc{VGY+;ǂ[|isb P\rz(j9AZs\Re-JV[P22Ls-!xGu;L߅z@U"O=&ME9b=cڍc1@$/Oh=_ߢ^m~>&nBni73{KX=(U h ڑWsI7yVdZowVmr-o)N4!-v*ѤHĄk蘱¬O#vLNY֧`3=8hpRͤI:$/ Y( W# 933Og? d =IxP7FȽj7]ң3u #1\9Ey*6V21ef|RДXfm%nM:Ɔ(DZ~CҍdS=n@#אnW,i)HIt4QŬAْM7mM1&Z>X,6*[ iIrf3~7{kk>7\I0Sk yn ɏNVL7wєc9M괕bʌO MNZe=iQuLmhɇxY:RHd}@ (kMYԭf@åM4Tft}2oFZ=7\#i"J\e~s_V,~O XY[� q*K'Z/d@s龜<-”F5ix^Mj $,Lpj'bnBش2F) eËfJ7F_ݦW{u!D `*hӼM#MI&Z9XkR}]_IR艁XS(pԨ}8~.߫_[{Ps<@tӝ/Zl>@Kb=5@ sR .8n?Te)C pɝ4jj7FT签TV;e^8j_1hXS#t]eHmO̚5jFqO6S(H[usMcuB >0)#&X*S�#G*߉1"�R'Ј (3<R+wZ,h(c"bY~)4r@1 Jĭ4qM!Nu[n+]IqrY}GH=0LC;WL 7ѧ4=Za4M2t<YS e3�I L'&t+x&~bzZ1 nLԭh<TG6 8?DX#H#Yk/[A42oJ.0i(qίi�kN�&XΑM�Az=s"(N8 @%LyB3Zt1Lɯ.ږ& |@-币+':Nd+jāqLm0{V˱4u1 W5@.e叠 (*%&xr"ozoU.S>OVl[?>R|В%T'rr%MDYC1I #cAlf7E&Y eX8Kk㉄ k&ws:.8/ie# ܇v"�DH5 ; `N9e{`(inV($a+h G `8 d' x؅6)h\CV ^b NO po`R%��6�KMG5'?>Z0NRꄅ%AE (.h>q(L_e L;pw~R# IlqH;^?g1Lc�+ t FPW-{H7 X &'] CzzxЍԃN&'1 ѳ' >ht&@"2/{\|LXƁr P}u+<`اѣՇ_?i|W8=-FD <34,qЈNPY*b_@}\M\2W>S荂1uMGӏOƘ 3U5? )ON2bBgdը>1((OYSNA4DFLk(X,̯DNÑH,)tV ?ۋ+Z̈́h9q҃ hچtC `떭lc#@4r€4O 7^mGLp�IZq%f%In-5aރ[V3,{EL 'R'Ucݳwā<u�uNM_G8%EaFgW=Կ& 鸖4PPȕ;u^qtp/j`6O% @vŽ4e}Bv@fTX8$` ~!�8)`B^9,A�4iN,_A ?�<FHP. &&o^Yw!&30H,k1<ãxWVbda"w)š `\ 1 \5 ~' (xP/eGQp't:u܇Hu<NL`bK2+U)k9OqC1uO:A:N2@LP١fFL04b�{(,cq 9Ol6ڗOV4eMxZ7j/3v17ܢaȧ?mx*fS`L QnQigsӅo$cd=0\C7132w:<u쏌xy2;݉t^lohrQ}hģL@T^y+I#8�X}G_0kQwt7V*1qOF=U˳Q;TX@4q94͞OF|U[=G yOG,S=jye}Ų\ь[̨0cZ~�`gƴ+Ѣ`cݢAO/t;O얙e7gYUc|4g _IP7p/ukX1dy&S`Ee{F2�h^LԠByFwYrێY6F8 f=q6z^܌ӰYr"c{~g$hi,<Rlײ2cS�A>m'kT&2̸k=cfJZJLRe#sRic.=1# ߗ1HS$xi4/K4OtEV"۪ ɧ-?d%mBi$ qP ĄԮj#53n&&MN rژLTGxU`~~, Mi&'F~)M9܌D{(N-wȴ~rt5tl!rN6b8'gZZA'#KrQT0yhrJo\eDijUwm+S2AR"0U'zD�5q%ߞ\v|m_1M Ag"sfͶ{UsjhqҁPXB&f;l׶G 2A%(5wV!WwR"_" {Ҟt{WGZE-CLm`赵 &cIp}}stu$A;,y@l!@ پ%Mq <CN]mJby/J@d y%eŃ4,@3E<B!y)Dvj|[ 5ւ>ZQ통||9h:g'hV: F x{ |{ Uh*/ ץR낺 XkHt@xC8 #DAPsq @@])"p "P|gڇ(dK% N"Z(_F 8h�AEz]ly( (E%#4ɭVtP7#GI *MS| ̕^``!}P9m?g1vMݦ6�xMR+|TZbփ*rW C%t0LlfUzÓx4m,͆j[md5@>pUWMk3x{iݿ-g*븿ɶ*l6|w,Xo@xSl lCw3&aLnMU`KvL `XjQA %IofW݌솎|gi7v|{\#!m-6ijVA!@gmr&ҒlģirvJ|aֶLM|[q>. }MoWj ),#ZFoǶVO^\kEE+8f[VaEo Tz$CMz@#68BWVF`b c__Y?6Q5�&XhJ،r6,O-[5/ ӸV൐}ո,oLqy4~ ۿnA{km˛ f}5/ӱa\N<'D( in8 Jܩ"S,qT+kZ-"e (,آOH*pa,*<Y:/hms[.kOƘH구uNnyY @sC0]Qk*7KhoE1U0 Kk'28*#|fmfNhD$ɭw?8Ϊk;tݹOW Ht~bv*َ: u#g|uA1$MRNk ;pg/Z~I-_;s $qwDU Q�}m!yg9; D}À m3\Yo!i?s( UkBPRp:4andk!\䊦Rov'wX_|_PQ7c* EZ+U#;)Foq5 ?ѠG !^;@mCvP^^<Qyv?mAwlރ{h=$u�PGl&lnX�gnSMx Zҍm}s7} uUW {1@۵wQf p?]A@wPT{Q&tMۢyiK#Л6_%wݲM}6q~pͻ(t,nj4F۩XjwhܦwYFOn_ټ#9WN;N\;k 9MDt>w~#ܢV6*Io[Uؽc坖"Yh.wnӞ7JOeC'~1{}[3Mofl8xя3A1wccf7Ee<32Z̗FT4r9qLPrL䭧/>0p=} gv}ͱGڳ݇\ÙcZ?z`y"!8$S|}TZPBW棽٧~ڽq';nu+jvҞHFy>_ToX#Y9Ez&NM{<;vLJOb#~=%i<nڇӺsWjO|N++}JMTQѤHY &؞OipY멾| G:ANs(;+tU0-+鶴m>W|?-;OOtOѓA#f'2,|ڔ(ONNm˚FG<sr,3Ra>)Dos>L`SI~:={7OiS7ӴvdRҲKUgMhDҞY>!b%Y}҉de SUWW۞USڠmtJ|zt8i YZY{)E;~L/͜L!p07ƮSwXV^eRL=8&_ѭ)H<ό_ BgSh4k p{OO|YЎçȧ'(FWf<X1Sm>g?JxElLgЬshϕjfXM;uS|%^ܫ]FAUcC ѭ$@02DVdś@!,h:8" :1ljb5ĩfo-"L6QjtLd1ݯOڅt﬽rO:PBLx`Њ<pRL*`y[XįIZPHM#9?h#SLөo}zJ͌Wp49K/Y,I0{MhFB9n~$Fcd޲TtOŊDaB?O;�QiJfj}) KjޒuDLŬx9uKÐ~8oSj 6rl o!maqL{&|[ocgWdK_HJd(٩2agO0}}e^ V9u|'mRg&&$q5uJƩ mJmOgUCƂ&3ݻ7|4<*W4Zm&őS}dےŠOا-NN"z Lp yމ+k'WLQOǤH ѼIY+8ʒM'baw:y5(xtht#?LF~ԏRLMeuktUv" EXt8LA//> #08|1r<f2/[dlb{M v}%~$ڼJrkH#_GHX̀p-=8kTLL{)ǰ&h lƋ)0jϼQ|)})o6S &b4ssaffϹ NImbr>_'w_Ꚗ'wyj2~k,9>ծ3 M˗9Ur-w:8mWȕ<h&PT\j)Z5F`|5_*K=ϟ>ḕ.$&\aR$uO7."b}i@&iݤ5Ty5x*axIV֒J+=nSNj/H7zx^O?b{y&BҌ>djpSʅJMW/?-9)rv?TX!AҀF<MnrSOXWw&N?ȃ6~TQj+)L}vF_,^b%Kw=[0ݒsW?=y;gM{ބ9̄VH~SwNlcL`<(5�Y퓻OZ#q@Q̜݅d@'Т੏cB怊@Y7[ {CM(}DO} A>ES}_N  mEFA'LxᯒrֿstKR �0#x82Jc恠C2ɾ=]J3c `6h?)˘1z R%>Qତ &0Eqpbo`x_Sڃ ~>r#o]|.\nq7{�-<j~wc^k8~ҟ9V~pvj;DBC ZWS=kE޾aVx|1ޛ9+6az3%#qm"0@{\z ~ؙ+E9,|;뗺L`R:ͩ= ڧ �Ԝ wt ԦP >ĸō/׊b>{DwԬ{EZtRtYJFrl3.iqfT*r  ;5Q])HT$/5NTn@:tEKszrN ~NȔ5_TjEZAIr'S`FI2/ Q\qA2HHL(B~Ee@ MJ?MXhn^xqFz8ԊG h~S+$'ق1[3!+޻ 5b}'cHN2dUh^ݫWL%yS{43d` ls4 ]9كD aS @Ékݖ{} 0+ogO~MB^aEz�=iDL:1 RvGlb:WнASO2K=xO,;ZR&zxo_ʙ}Eh7U$&F>nV;!-zZ VHڟR'&JhWz[I'0<@6(B+"S:mRQ́(Iߛn q/59k{ŜЖn Er `+n2䟟?b>n$+\nbm9|Ai2L+g36@0ݴmm+c9Ov9gi&%m?/4,vg;A.6>k~17/?5[[sԓ}V|?=\swyԁgg-UcG݃O:F2YFMЊQ|bß[sY_3s1AwF1w#nnx[-jE>w;6tL得z̓�gi`zTߤ>c݊ƴgFcZ3= vqej?ϤS`f=m>_7O姟a` 9ztpNIeϬmrͧS_}g1xԡBr}j־[$N{VU&uk]Ocߌ&2ve< k�a?_Zd"�eC;$uprPdA]a'یi}hsw4L ?}0&*b̧GIzݦ>)Nϋ,Qo3fCl 5yg}/1M*K9xpZoQYoߨe<kcr013b TG[i<1f3ԃZy/4oV/F{Gm;ǤgBsWoRzp,fbā}$w)m,x%5{ eʙhPOUjb#I91;. 3z?mg*,^3rFҗE>=W E'^_c,>W}%zC~J?ffuOiSZQ|LXXMYN%Sꀠg4O0D:A%g]{ݟ.jtY+ ^oB 0o+"Bs"<)).zU(m;te L &m9 dz}>XO&,-< *e*o6qk;)uz0x~6j@ ~~+뽡j@ 6 ?,I\`ВOSc/6mOT!t<Ԃu#gC ~&+h!A[K.xp_ &>ōfpt*s{zpp}ulaMKdy\(Anze=Ӿ\uWbK;y2}퇵v|e3YTz?|Jsv[oT"X.4=Js /˗oO=uqrfoXɮ~3'R^ }ei0hU$ V=O &b(el^Jk z2ƃ]rMe^=TPYR3ƹI3*ТX=CܱL>g|'2[ v2õb[_oHK#صo<K{SOӕhJ3V׶/ArAз`< ,!Hm g_T 3qڅ 2B߫>gV:;K"L)ePj7W|W- {B[ϢZ槻ewuiJ4 "hLΌsôqۙVhtfgX6[k7ܥVjivs^ZY9 {�cU'wI;,l;jmM]xF E5%O~E=&^ 5|'/o`= s~ flPLnƂA61[GĆ+B"&uƷ-y"XobS9۸oͶVzXpUMh8@/ϭ6Z.Է ]k9y֪kgZ-oM/-^ ? ׂf>�&Cc7zṲ̋uRCᠺ> ^Pކ~}vaS[+t߃Vot ];gH7\@i9;Gʮ:z/rJ-|D.M!i9^u-k}Bo%{?JSpm\w{G6ǣR"ym1R%ږ_M 2Q,@8tƣNjJ0n GToPx|gd<9^G?㝽 fWj?gHyv7uo Ǚ]_+MBZ& e~b"zrk(WGv:;>;gǁOJSy_sNo;h,0B NtJ"j:g;wpNO5چŋN` ^f'sZ{T S.<GGO>=m@' 7t64gTK _u tO1Lh'*CN8ub;5rB�_j.bْtҰT8R]q*[EJ|'j;ӆ7iXCiw9MWH:vr!c5XԄ54Jt~?:5h@1UؒO4V\@$:uqᯆ t[^1~wW-u5J+Ug@ XKX4@ U(˼Ղl#Qe[tx\W",kx<>JVO=Zݭ( ?ϝܑ ݶzhA뀀th*. 8).R=ڲƜj75}Nm-uS~4ʠ3ȶ\ת:qsQ'k@_; 3yX+]*IcAp@@AKύۉ'\ҩ8Qԇ"u:mH23`j' 9)Ovlo; XP9a`[;Z=y R-19gylY@(Ce1I4@Y-xtZhe _ c$PU\T%rOc' w5On^ Xm }5&V H\Ź.#at2'H-E)hPX~pKN'Pp) r,Zx$eVr8|'Z3siOx…>J�RukiĖ`(%c 䭷9ͷ@Wc=3lQ5Q J4M S{+gCc9s& j pS{"w4u:Q\"zh0@@c&5QgQ(:2QHW#p5s8o@m@^-ǯE @Nr8R@ TtT�'xY(+j+�@e]I&-'" X-yQ@`y{ACZքE @Cq ?GLEPFsSO8u2T`@h_Y~5n\| :0̠nD�4ևkֹ՛+ H(fhQ26Nvu Ԟ=ldd9͓]�CN|Swɇ01@@tw@d:O?=RC+U~M@O'&;')b- �::h9:-E @C=0$@$| @γ'GȃU}RkO,kORhıRaUmYo1W/=t<�Z^J< &A@0R9{m❞ 5<96uLp@|)hhPol\ ,E?v;c{"IuчUmNd4\m!fVG<LGA\-|sXl!~,K5}һx^? WOʑLgDIWki&#/'*64?3T{̾J9|O77[մ,~Y{\āCFSsNm:5[-M݌�,.]Жuյ >].wvP,Benq ]. oЊ튷NUfYWjKZ0ⴛA ~Y yuXI*`nGҮu)KĆu8zOL,|U\4K<'Ηc':P?.KI5ٛ-lYTw]W.=nemNWOMqm'?B/R7}5pPK.]I벸ͰWA{qsxH n@pˑILx#KДA 4D‚#(Jڿט`m: X#Y�Wݎ8!:C"&?`ĩBC�|Vw<V&AtmFy:- HUF@I2xtH%4=mX|=c8́` µjt_U_TX4j@|;Po7|�l?2l刂Y;˚`$DJ'b xPZ+-} 8M#‬Wu_"t(uCݖ8w%;|h#B< *M:|U4r}iZ.t=$"H14Gu+ ]?ȺtUȡ ,L8WF p>uw^:֪pPZdˇZNx<}aU" )!2vt(�+A ScP4Ŝi)mJ:9@5-A�q��@\uˤF)zhT'KZ= .H< Bq,T#d ^o%M+X ˙IzcF:oN U:RyxTgWcWc.mRǑv4iw*rC�|'( _Novotd9ےo]Z>\'iGv n@nTlgk1zy޺8CH@xEVuIlR: hm1>DɼuTVtjnY3Bw_[o~ FO:ta~5Y"2qo3\'@Cwy\}q5VAZq} 0i)+)>#IAX2u@"&Hzl!f~8F.`ty? f/uIǣ1?u&|0b>sgD s#j I o&I}BgSCu{iN\8+1/T5�I{Ƃ_oQm\$u*'[iiB} : !�-!7C*.O3٪[6KRO`!EoalC 65"G \֙V$;~_+d�Me5|Ww/+&p`[; Q㖻_7} � .9_k]B%?M lr+0l/,{n)(Z=sn~��´GLPTt$~OD,cE4O&2[uLķ'MoZ��.K-%F;> ]K-ܣ΋,w@;5"m,:ۣ?ʾ-< ҭ -.R`P:ITt>�Q^t�Şڋto/D3. PyK"~{ ցjU8-.,T'-i Pw+ۀ͡VpźGC]$SKϻi 1l,.[㌥.)?~;` %|񾿆jM]w ޖ"Gk"X`{I> YHsoFBLEL0'z{^Q٥ ~hK�4ͮRDԻEw<\Z`=} b/"SC`g_t6y?}{,]m񂾘9ό-sKl/m� E\d~S ]HC,cҪ@8ߖkIo/;q8 <?t\(=ûqu!񷇎(V/.ޅ!STT_3ߎ 7gk%jo' ϼ >5[e?{؅_qžCmSO\G %Wl|'MMf ㏽ sW7t:+ܗ2$lH}szS),;vG<)loj/Dy}S];@AO =Bzhsvfaڴ=3c=0Wn_P> ۅR>x T{3=֯t d'Zg�,5M.%n-)NBW4%{bDO G:{>0A <^DP9(4n0H.iY,ۇ:퓊툜Iq9G9Q}Mʓa=g@Y�'%{JhCP:xh#/C; #k]W)GM=l_>)J<L `'tŹv+3\cn|;gBw|ԑ st@!srwiiS68bN*tf i 4TVF)K"`ӆ}g ڱ;"/_6D x]3Ne'a;i�;+iNzنnTJMmK0<' *'lK U 1*~@@( g$@C SA*H9JD;NYdi,Z'PD u':59<8p;ѺH?5M[ziTNP*iPM|x[; сtnYs"@x STðiLWQ5\TLȹ2,n,I֔i&ҡXVKmբ\UWb`͘v%f?  N Ő2VbJWU3 Lcj(v6G-EU=^ G.FI/łuڷ!JpL bڧi/?|,Z\U 6hJfGMu1m.ʯH7cd qys[6jVU}-E|?̪ږM v@'8DEͭPȦԂupPlIeh6cϵV^GT44=D,;~gڛ '!t;Ky;ڗ@ HqMg(էC E7\KQvJ{g%o/@WC)W!yc<{?~!=n(WMe]tF</L'ސn;}A@ D=-26Zh& at}z4sQP"9:kϼb0rVxa$p'ͅ+a*i3aYR_֤:yɳ,e0u{؅Cw6pT5ySWvdp!ϮV#/bG55)PA;av:gg cbeQ}ϳ J�)Ru!Cg9R[lD54ȉ�Xͯ0%Su읾{ ͙$':LQ=wMgʅ*: { lCC#"Ұ|aѫszi0rem䆤*[#z}sN˧�l;Tv9&ͬyTKV7, _`.  xvؒc.Y|pe˱9}Nni.ku#8 :FZ=ڜ֊ݭȲx^5FPXr1R-}]Wg>aƪw]9A굹y|/-`g0 ct<sE-u[-!Qw,|i[Wcs\8ǖ{jͻ[J(` λOOxcj}5X6tqw� �y)\֖]мk׻~%bnjYxʇ!Mnثl Yin1V<X^*W⾚{^45Rְh"M] z5rڰۗBK{W&'(1l  pYO bڇtAq.?MehւfhtWɭt[K%�KK\5rK:;̀]{*ME<</�3T'7u`A(e1As2.\Z`4<&f9V/]`y [S�r\d̻Wc-ֈqi\̂~  EEWcβv|YZ14Qn_9O @KaVE,?`b4mzlC_Ki–j<UP@sA[$S$s4?"`Oz%- rw7BmG .<1z|K듺G,T-i 6<^#)EPx A ur4.LJg\׵-r4{j:o4<^u{' ZxzxW?-7gR`o]w{ `N'(᎜^oWTNkb0>|13k'GL=$Xp7\a-rKM.s1@s8&1U6[&PW�g#uoA#:4@&q .u 69m$=l'srI|2(\BaĤhYv<=Fe9>tGpuYcr^o,Y$I ݯfԛ/Ь@|}ǰO{ϪY{}` Qo Vű-}opEv{e^d^q$37&)%G&:暏_ svg<^K]*9 r<K%Lc~^ 6\g4<{o$=ZmYZt⠡1nܵoidQ>ws{|wxVM\.ߡsMڏm.]Ҭijd<'uvEso|Ubo|ڕ]wOKv+zJa=z]:^b7:tԃN� gugV oһκ]H"CvGOJgn3KM aIM񛴀,<ORK]65FL�ț겫KAwY.]CI Wczs˱?? #ȋZ !\w1=B%ix%lD7Mp؞[]_zw\ߛS;7Aqҟ]~2nGn]6)@rܫjMˏ;Lc__ &[O? 3Wb߃0E�PV $t�ݵV{Wq0kliuE�s56iΖZ?M} ҵ~0A]˱yD5R[u+&9*^mqˑF�CG^̽# �в~UouKc�:zݒoqbTz7& �8EA/k'|_AM>uKI+̹߆AHϓ/r7a(R?�kjwצcPߪ>^k՘tItUZ-?|ۏ`pO.@WD_׃ aG'/B'Wc?JƯ֚i?YwS0l  VrO3@,�?֣݊@K�$g[:)=n[S� k$۠�3gyQ�_hi dH</*бon#o0!']XKXqҰ I4 VRVqjɟ�ހbvN,@8(С@~ jlŽJ6r+%[ɷ>K] aDn*<:9qzɚ͌y]ѕOX=#v:μ:{ˇ/ <_j'ܔ;:t = 5o?in-:dZ0:<e;w.:f"&\7f5q*8̽:Ggo: h4焴SevK] Z+PCP<_#\֫/8Y4VU2[ aPK cr~z}%2ah)bYL,^0h>({WjЖRjn샅2g$XROJFgy>F9o} F<` X6 3+r^;pWQҟBƮE)\'ׯyօMLhF�A 4 J70  &3-퍗{k`vX�ǖgaԼ; 1)Halɴ:✘L˹;[g] 2_|O oAaWm'_2j`>f%X<Cnh4]pd*Vٯ P0"�-,.7mu2ߌ*?~?Y.DV_c-z+���IDAT w:|3OoŖ�(+oHӷ64U!sYnxsbi_5h r00wu ja<.sw.̼ `^ )~r Sܗ�7b4M]&ڭP Yj &°`h7wcKjf,WZ@|07 .v�  КAb)}l`.F "$X�[@QZ[wKVyp`wx3m@c`!)ƚ�r.FHV+qLO:緫8~ͯkӊ-돜ڎ% >%L%04>Ǟ='#ZܬIA1-N2+355]CAaM޽JJ{<Oݺ{iRj mJg5&�}G!O"' xt/T_"%m�#@0| ';_} _+; 6KL{{2 J/-IX˻1/ ԟ̖ܵʜzK7f[;;湸X&*/0ruY(y+_Z B+uclGu^xKtXpiʳ9<^&FHlgٖoH=l^B)"b#Էo꿌#٧(.w^#45J/ЖC.#?UЙש'&^יExߞ(uΖU5rlv;)ۿwSoJU=)& �Ӂ KNt|J- Z:yYD 8\N.$.tKCqҏ8ٗʵ`_F09{[f?!˓.ϢݼRӧkKgrx|M +SٗOObw>cJd;ŏʾ%O>y?efZ_6^F~4sѩ{Ϗ!WTOz6Sh݉+c?B!ydޗJ/2~'e]7v^H>HOWb/~p0_C/%~Z{4s//1sro)K ~Oyl3(%̞%G38oOFy=N~y5PggɏڏC*/g؏͹ط'J࢈zV2^9zZN|� _?L~F |O]ge7;9j);b';D8z#Uٝc;BKUN>P~#lDJyyw|@)xl7W ʝD%lb#ƈ`W߁wȌ|t}eg�inuvzX@(T4Z;=|Nw>u}9r;>GPN}d,Ϙm_u&9s/%d3ryN ]ʨC}]I8wqt<>A%~#Lw&6ɈrDAU9 T)#o�!umgA’0nkDw7`k?*)߸{rg9))EKk[ii d5j0A_U@`jJpmTjD!Q/>KPThYzCN*B4QigP;T5*2@® -ʬtTY9�Bm(Kd :<9k>|W=xd@07<t4x/A-g/W@*=އ$, R٪0ͺb Ūa5:2!m�U gn�&8 :gcpDg cgU&DYUÕ�a-fat7#(GQy2N(.(3YM 8’r֓_@*>sGٿztZ*y[DEv^u!C'٫(nD4"WsZ~^N[ץ74rɐcu :P`p~9-a(j^W]t>N75!?]PEn^^6j׵P3}tJM,m׆kibPvGFDm䦚8w%Wa}gUØ :C6In]NK'_d5)f'<[ WYNQi79o0M:ݱ hpŀ7gg!Z%H&ol"76!1V k eY<^%x}]ijCMU ߄xoB%}m4P^՛DGmSyBA:Xsܫy؎wmȕ~=8H"ʼ1lҀG*pzMO4ޡ`Qfgy+={Xm9[:wtCV ۺ| etX(Dim[(|eazQj S[Q@VplvCj.92BqU34nOokkbvMp|({[oۍ5u*nF@w>8;G(~3?Q6^`$FlgE}vǔWBm+-Zl$Oۊ]GGQy-mv<: tm/<! \׷_@RD[XrX>8aea@ TuiN7H/p۬+<'(V* <l=b2ܓbPmɐqi# EDŽ Aʨ|غ7ڕG7LE91x7e^VC(U~;<� xtn< 3jڗ @}u:SOA)V# Fn i} Cpy౛øn*:f9_3� < a7@l1\i iPVq#2O:h/!И5(kEy(1Hb|�`]&toD EFս€|n@$eDbr^6FF(@-vgF $zl=: )9Wcx#I=8sxl�O[69VضYV8,C2DJ<[hsZmȉ5%4 ߔygWjCCȥ_Az}pIF-'Z#kh C �0V 5c K g@>t1y@7ģ"ݢNA9}\^hlMaP]/W4Jxtʺ)HiEhal-Hp�)oG Rv>/= dWamIKm?ckhbp�[l|P aom`Ufl;b$!V*�0$4/;!sQ ݐ~ʑVր1^`j{ 鐋9Ս^G:^U7zrL^8* ["gj|CZBG<n)H>9#T~C %.7s`�G�`UN:EmC nL͗9ԓy<.Dt^ȧj䕃Ը; I^<(<@*p d @�@Ψx:ڟL#{aevu:~q_XWK_P Xu`g$kh&1娪SD  (ao,v+SFnÁ}J!}Ҁ3zVMl'#)7!x߇֜{ro;^!:Y ת>@g.wn젾纂+4ԭEMJP;k~qb,F|Ci#M]Cno뾷 kDdT+'Jԏ;$}-<zǓC vG|| C\#@|}Gr7Bb⎕'tǷw;ص`EXEDRͬx]Da|CK׶_)0Ly!Ol+3h=sۖ,K(JwzQ&bw; wVc;\xpz ځ #>uG7)&^Ƿ8Ϸu/t^&7Nj[SNϏ@`QhM}G#딹M~"rh&_޴Z(sj)5USX([pYNӍ~~vn);cQdͻ|Ui@ֈg/*)SM(߯~'MJc|OvMiR&PeB!]wWYAt={G!i4nlZ!MWT26Nr(Ҷ}. u˓˓7;W>J&J_siכ`iw_=$OB[αT0�p ybawko5G_0;ߕ_< (@Zs0mo< T;d�~t#[hOl\U=jg$�*GܳW4AS 8Ai"h[ &].{MҢԒ�U@@.V4́|<i�&4~2lk_fMA�5ڤ}U)�0n�P-M򮦾>+D\! e$䫀~ wS?HC/=AC@o�[{Lʒ=8~^fr5`z3P2nqnSe!*2Rx;lSOl9G@~b3^毢zcOohtzUh 7/۸:-p/pG9He_CҀXax|3Mń'E-^3A# W ^v�k0"%t5۩wī62 ן R 7< r<pyyK�pYxUt7 4](WWio LqڦFz_hb^lNT?e<BS¨7|44c d}<A>)#<iBn5fsP 5M'ALٛw M`P([RJJ/Y-U '6ylu^Vەߎ Vcl -6ÝBJۤ;nNo emo8= 2�ّfVbd . m#OЇq[uc suҹS#㄀@`8 =8:Zv * P);tN5j#:vJGs")]�A !B$E= \zԦ8L&> DEaT@@gx�P &(� Z j@ ~Y3@6:>A�ly" (B:Lh\ )8EMGu$kL>C)WJ}cA͇\ ie5 tQhh. :;bPPW~i[V5a< 0<@h;r S 'F鍬4R,lFٕ�hZ XZ_A8}q4ž~ي$fE/ِ[!, p ]Ze˙2):uu G_2rte Y�ki>Ṫ5* )VӘF&45͠VI�E@ֳ@⧉:@`LaN� ֤|݂c0DS:xކJ[)IzӧNJ5ܴmhW-h5[�pe Ǘ9h O1 al~'/KwjE(Tw(PCJwָ_F!z!d5R ;h:D?N$SO@4e u[<CJeqX܍+U�O/:H\q&8 prך#rIMDV2N>eHu Z 5pJיuOr`Cenj›?%T^tb : 9QmP]w=EDN{jAQqV&52L$8Czc"=ztԦ s"iTMC<5F}1q F�y {J)btvnꩆ[m = +nhd.$@:Q�\�kYtnF_1@ȫPj]W*}O1Cohk3~@D?0NU)Ct, T dYv5 Pn.!!"qZ`P�N%uoG�W 0uuDZ{.J?{x?s{w<^n(=l{F]2+wr\n""T!bgW?Hq$rf*[!<٫0oB {n2\ +a}8n2ޟ^sz^]bO^d/"'SS}$8:<C(5^k镽<L0X$4O+AvQFp:P{a {0~^tXѲ1.`n)5%Fp :9v p=+t:~o}P\U$JxN&Yx^rg>ȅL?F`�PSw6Bvy 섨aO yRP�,$_@J.Wb%tox~ h3>Z?F\hۮ@ ҍpEnÇgmW?>C ߯6F:1{ (|AWS ߻=(1맢eǿWiȕ:A&H\,; WGq9ϟ} 4hpK5|+癛^v_i+}Өlu vΑݽGPÅ^gc~|lv}?kDùØW Qa`�8vV/ |T8^d,feK±@9ApsOq5NBp \BB1An8dg[vo~ pu oX$OU6 fτ3sY t;*pȲ#@ f0lmfF0{F [9ó�anmcs~&<!3(f3>T5jťj;3ll3 wm؂x*6[ǫqZLو`@I3UKeÛuњc3f@}\xiCc%qo*3f8f|e`f<pߞ[}xecϢ JO+&''V'O۸v<Yh/)S sͳde]y 6te5~^TU Ǔ -6VN;6߹U9+7ḥu\益N-\Wz7Y ׅ뻵zg~~srM|3PgrG2j;mg2+pO)'wn `n2>;dpGΤIU\O> 7^ z{k +Lɧhك'H:8[sN; & Ɯ ܛ12<ޭn@鱳CYMB4#foۀ$PlߙsjMQ |VsIorVZi2zo<XU?{mDsܔN"9zrGֿ޽by{;OnpK*i!E6wSm7rVaܭxQQv]Kܭg6XT*%w|72 l ϲ\V]# 5YY8Q0\&Ud18ߺy[v =3A֛a-eh3TIa<' [%"J\6 f(p8m'S=5ҬoщzkT'*e^ΣK,/TkDuC 5^{p%L@7@ޖ~-PS? 6}EUe Iѳr`0ȿ9X?j \P?73рz>hguycrA9h[QL. "I#Dm4*ܶQi'Y5@eȻz/A ڌ܄3% r Ww7Ú=YȲc[TT7�Uf%@ 6Fb8FQCy#|AX,x a HW];Y'*\ZACZjƒ u/' zCczk�# X,Wg�6 T"BkZx%2籹%1v wM�t =Dc ^@s�gren6,з@4b [_hŠ s0-ޗ1:g4ٚO|Q} F/ܽy J&FѮﵘe94_|h^S?5e5-7�Fv %OXmɧ/> w#Dq"2KH$Tx?TbD˂PԼiHMҽ†G[R `*)m;@ p s{k 8B<KA39K_ ]xj<OԀI%)8A-7Qu^^f ܫ.xU64Fn <ϓ�8<C :!@;%^w9B'"P K$|-$-IZoz<"N Y,_M-KoL2;� (@<?yV�.`xFWbi)=_ |f-^ԃF�0C|:�D#, o> Hbh[4,y�Aa? gTrOztt7eK ဎ;*+FZ0Sw=i-\"ƛ#JЅ8"`l;_ȣ4y 0%2!,O]3Cy�Ah:OFqsx/��@"3h `,oTEW5^tH>7,3y.�j"Y@xb̳/f>XSo �%?/SG90d<ǖtZa8[rC?͞G},'sB{Qx-&LGq/'3YhMw+#%A{goK:}#3\׉~p&O"m#wPןkadWwHt3b|N]Gn;5-v݀r;t#0!t_1͢]]ߡFrK\ Huu3'cmА/WK;ww趽t (3VO쀼=ҷkCUFbm]۠6pfC^j˺QP3"2|m#p󓱔=v>d_;~5fnB=(֝cjHP{ |Hf~-s[αkᆭcԐ렷 YwGʏ_v;s+ڎԽfX7qإAIPZ F/ OƵ_:KШD%-p6YI6q{):d)& )hϢ~)j> )*{kb=I7OIv'ǟai:ܤf]/v:5]iRJEUi9.sNIPw۔^mR+A X)߷"\Z$׼JX 4+<D=ԔG6aZDN~a: |hZ*[%QiBJVQjꋄS|)+cT<>3. +;9M_aaΩ;g,ry+YhM+eZu:5q-okk, >nk1U yY׺+Z ) �u?XŪL\ך[&ԱDSDN n CѪ#LSϣƊvBҺ�. Y:tBFt޴J� 12&i"bq߁l@`mN�QtdA`Ku(躻δ~ʚOܻ%j442єV4<bsu)7ͦ)-C×4H*%[9 �R+R1D5k􊹢!t^kcjRc]_8y:MNi=nWBm mZT:M!<[E ?}@�rsZ4PeV߯ǥS6ix/h9(tUł^"ВǕz*W�\ 8' o8J=͋yɵ�ߺYˢip5<w2vGT3$FCf;{7 Z^&= ]e9^(^(x鄕=�4CJ<զԃq$�_[ln6�#.aTԓ/z~ET$5(]z)s; hF#,i*lMnĆ =k >S[jzQ7т�(bz6L*<U�wu*ϼe{C=2} o`o:f /WLmdӱJ Y|o{yxxiބ֭M鄋nj6?]1/G�.Q.Sv td4ifE - ǧ[OPe]x8@{5Ǜ~$i uQJPcjP55(o4|v/@5u�A5b6@}PҴ rQ&0i` #bi2}}ձy(ui̢>Wj.B /*&W7c:iY#]A:?c7͆ὀ55�V#J� <e[ |и <w?t<1֔ihOh J43}G t%C}UF|TTRE=:-جT\IJ?MN9tLB lj;�>0 06t_6̽�R`֧hC>PKwaq:,`ڗ 䃳g⏒b´؜i? Qib.�09xq g@PYwinCӄjubLb&<#ӜZplY|O0iXN;JXƗӻ <ֿDRֲI+vy?̽WuAm|*Ey P-&jOu [^&9mN6 B߃O\VN:;ERNNKzߢ,dULsZO|9F=<<AIc@CThP5��@ϧ̗z;;ߔ_49@mP! JcP?إT RrpnACuDJZvW͢|HkZs�m{MF`ɸƴ%=.P?-(!9?E&dkH6A u4%t nٝlHl32!/Sц>qQ#%2a]_H\HHT7S/47|ɝ8zk*y܆ޝqGh4Rˆ;rj"US.4\\<ᆚO]O 2l ƽOi.fT)([ EkKݧ?'5jOhɜHC>n9OpS!/<4q`bDF#O sg~@\b|j$ c[2/%{Bk;˥'q� (;' )~J re:5>\ΖO? UYo˞Ҟ*v&؞xjrӠoKisateSF%xËXpS?9@%ԑ"/5 qQ3K_ި z-r%#m;%Q=k@s~ 5oh޽{aKEM%i_A_dr٥)Oex>L4஀DK`_};ʣA=`i ~C%<M@` H!b *!?t^ƫ;O0泥{{zRL\뙁:BKto\o ZkG$7fzamJlڭtCް5ҋSJLۃYBBe&, 0}ݳ)cr+rv1]Wu|F޸70/ߋ=ˑ7f 욉+usԑ/;.괍‘4. kM6hY?2=JCS Ðϖݔ(}2\g܃?rA߹5j~kPC(ŅƝv0̟VÊ([^vS~BM-~.�eC^^E3a[).K"Ze<7}A< Cŗ݄o4n4 ((sn(iq^JP w\}fj=~Q_cu˜`?~Wf/tv׍y(`~/rGK \\UЎF8o\e.μj7+z5ek /5$t{Ϳǵ ~nzR E kje|XH/\DJ̌d|3 2oYxŻ=٬?lV`'xgp-N#ӼH23?Qfd%[yoƙZTmXO[g<v򃧼p}oFڶ*R<3S][,՚ZY %a2{ʔ B1Q-UB�̌ vfJp؛YXvd%Dͽ5+t[M܀Yҝ-9\ WgmJf2fR3Y֔@eL~E^el9/;,9Sjp>o,V<참WdV0}_F fi܀8`&gJVj-5CK Vi5U^f6eLPNrF~?oߺV5mhgogf3pVM~dޤj̮,kg<AfgD#O'ޛ=iV]\O翶qfq+Ռܰ?u[d2f=CzZg'qv=b7>Tz\&T=dt&}!OϥP-W܈’?sCf #rso+d@̧M냹^+t1�(\̃ڒ#2{bo'fo4q e}נm,19 qgΧLwg7OHTފ!'笏Dwb{g5gJu1ۙ}ttlr`Nq�gWks O?;$ӣI7qzOYckoF^)h-V)6fW$hDeP}z_ 4r`B�bbx]6/7N}pK.�\dFFf^Qw<˲uc>Tvm#)ޏJ=IM嬼(蘏e(~M=)yx0</З>jԟZIΠ~]e6xmi,pXw8K{[f E-}?#"FyGdjj9feΝՔVh~e+A5c?޶ Vn}ãN_fS݂ mPO 60FMi؝\{-t1yn>s40±34[knjk C=t--cڀpig1 @[GgK.t C΂=tos19PA;Yh+ "{CgNN7m:sYmB)* awkol˧Bx3)sy{5e;gyoκvoE6m$:Cce`Tv(*WQ+.|iybi$ח1R7Zz-Űw`߰nR {@[\c - i(YKӋ?i@SYr╂WPB/Q� zO.c56/vGWX.�V(5`<=d>-rP)"np})?AmϾw'}oOg9vK|\h;nnG{ږK� VDiG(׭Xmxx K,]a:1 PYZJTnXܽdGԼ3PlԀ/ s^hyp.̅@f9^ʛ H 聥XqQ _v-b)f�Hv%O@uъFBׁUT1&F9uS9;bpB=oB)i kQ}|IO(kw'|%UrtM,1 sAV!s={NBΡ@f�ڀ1s/{:Ϳw<J,S8J`L'7U#!c-بC@>5ƵBE U=]nqN<˰.T^@�ҮAW !|4\2*+sNMvKgM5*Hb<6 5y#\Ua\eoe^$]oP LЄ1%ϝ}Aug*lpa{8:olyD<oOW -o=y[ w+achaȂ�Ses,~IӌsCs¹>9W}F8 \)A;wjaW~Wu_umdI'cO] ]ջ'n7ḛY^k5maժ޸? JqW] _!廆_yصmj* Y!s.y0�~=f_2 <VzQ a2<1Y(hp-?./օG熗y`IiKwج̢{%2YiiЬlyC##2izD.Bw, ygeVꂔGz,cpgNzx5;>yG!'s.2WV;>/ e/߭W6='"+ o;6;1LS. '@UmтHDjM v,"^1<MhE4t W钮^m%.&M<zbwSNV+JRy~:vXy ҵ+?AN@<ڿb$E;uӦ1MQN~T%q-P"',xvGʯUJ_T]y.)B]$NcP> H_C:׃F : tzݥ]P;kLnt쫅[RH2j7CJ]Y1ZX^p^Zz(³5 pC-oh2 cX; Wp7 5PQBՓ w]X)6.{o*֝@~R2硻Kr±8p0l;'7JH%Aʻ˥nwiJĽEV< MӬ^#v9_^[ (hU+�.ĩkx0G+NtFQkwuouz4;bB*%@dToMB1 IFz3Mry$7/]ڜruMvL\ otl<mO/&Z%j"3&lUEQ5!8 L -0*k6Yܖ{8Hu4&!|&f}x53[O"nz0j)B#[>� Vq0ynՆ!e Xg*M􋈻5tJWcŔuIeDr l4jAE< 4?5q;G (wjZo>T9B4yOULi}Z̦YEɸy2-N?D/�]YtǞ5YD;k/.ɇj*6BG*cJU/TwŔvS-_)!z-)lqe^NmF;G^elf;ez!s+!_)Y#{Dtڱpmb "3t#HD Q@.ΉubX ^-gX#! ΀;W8FV_0ݯ(]#Y_<K9>E dG-EׁtAx~.vQt AbB'VS #\I_Xr%kCﺳ~5vhۓ(Ga]Ip�AM.P o&*9WjN'7ɴnMXp(%qU7\6otU{Z~=}ǻ:D,~RBJ0 eT{^ ڦz)g:aώ5nͬj( +{JD^?nș]!yWҸ�iUMx~-�~{�vR+@1Xj APe0n&Ict =Q?=\#H i`s3!M:ف$h\ m$$]W0n*�gEDNG� xPZQpÀ�M]EG6p弡UD8[?t45jHCt<#OV9n0P3)!=ؓus.J0.fW)Ls4Ɯd86Z)r'ہoMGvIC;K /y_"5-9*jQ%]j#ߺC$6"Eٮ'~K~Ao}=63ymvhKd 2A$|BG jfLZ}GaNP a1SUhp*zM]܀Y@~GƔF|6nH"@ \ 5h1Zj z_-ʒZo@an}\c/ v&H `>ʶКk��8F n<ٿ JMyJ6r!'TO'-6SUnt~姞�yDٿ~�c|Yw~F&{5rj]}A*ϑ <uOwy+OX8zOʥRN+[*ŷ@E7<\ެߴ,uP{{R�FblA渥y{q- l0t(A%[e!t-}=t<[W,a7^`r0*KE;FSk bA]| tSېRt>u�5X mqtgڲp.`^_bP!B8UPr7G*z �#0LV\D pM%W\- 3P$HٖwbK,n}_f46R|zSឱHb|+ԱCEO,йB@<T(ha/ޯKy7lf&[gizqoh =V"/N>\`LiOУbלpZjADܣk(9zhqk>:@`}=Q SZHatL)t1D[1Ƴ%QD mhp@94zt ר<�8 2OSXN]9s `h4h%H#?]ƺeNϷaכI!/W}.%P8|]DA..T(/o!},;>_�2k3,%|Zy]܃l^7+/6ąD=c_^"gN{D0Kz֊FzEILrP\Lͧ.@^*o{a肷yG QnQNb N@t=SOO$P,>4BX{!Z=k}'Pr8˅\fA7+gǑ5@.ĬvC\ocG׀Slk̃so)! 6LcJ G8?fɕغb00Z"Thg e||[צF7AYa0WWoe|E˕�s%NJc63Ggt(ˠsij1;fffj k?2Oegz 3bwX̴qTӂӴ5 fgi6lW|fziX-dKi;+XfMYSi]{pWz�%�?;pn8CmU �7{0֝ %nPwٻNÍL/8GK�a ^Ć2qS;AVg/vx-|Lfʲ;m)x} `ZH tAs >(}<~JM˙=aG={9-&٫=/l3]o:Qp~ec{{Yi,m]wjg7O돛ih4jYXGv[W:uf&'鉌}1oS{e')Ί"0%9l{勒|m#36D%xI\I֮?.2nͬt╟>HGW/_T )ڹfLNr,rΕuYiicDߋpsEj*<~]mfyG,~$rϱbγ_<@ `zj뛫pcEybΣ?Y6Lh8hμ=GTgxӥ1([b}S<w옭f7лj2:mnf=y60ԞBO蓪 3x*;--PGd襟T1〱[|$szkžM@�8"~@俔2GdZ'ȯ6J0*\V ?@+22C޾yf|mgg^�ct0ꇷgllA:L˿3�n;Io^Q,G*}Pysgq[@QbE&"[;<d_[mbѭζA!4QzDjݮ Ŷ"S.&U<@}Te;Ș2po]KwEl.Ҡ~acKu)$dA�~j+:@+th މ6ՖGƥ'#?H w=ʋm`@Au#D5E/S["BzB e�Z/( bFSы;@\\vЄ0PQ[ @�Mb<9�Q,Kk�X>R @�\ +3KtbxFC VGi[F5QGi~op(?-gBA%06v�(�6-\2?j�Vtu(iƐ=ZC�<2~lX n+" cv9`? ~*4-t \#Yҍ]rd5ό>x?Aƭ�ꋵ@3j��, jFQ.DB�.4ejd@4B`ln! ͲkKsMg"_MK}E/}x<TipNy=4&G<db} /No}?v"@lLĠk1έL#,F5ŦĀx{&[ P>E DF6҂pֽ �]ݧy@�W(>b(]oG @ N`4�J+Y18V ocŀhG`@D p ȜxKC%xYz#dm yF:*\qn+̠^xkŪae,Ky }W`?аʷ$v�P9 En'tD@jdt�A�@2Ay^KY t =&/(8o#�` En&j1ՠ[j8^7/`�0FtQa>&3Y^ NjPfY4blS$+wɧ#cw:yYCΉ\-a>sM%z"TN>JEi;D6w^�RO kzwTKwkw@#9wn=$LLt;> %\x…tteT_ P%TZtƮfdEeQӉccQ¯ 2*kf?VmY2#{Rt ~<,ȉiTwbh nfOhŰR�FCep1_Gb4c:&LXnZ'A2A b l[)pϑa5Wf!)ω#<:?@O.e<LGYdRP@&F]�A=7w͆H=S`B?v?GwL[Cف(N灵c$,,&^xs[H[[}kO7iSk4�W%6h �6-1M}мf$0@"r PQ, )u,v)5#NJI)"Ь$�y禎NN}硃ۋ2AkQg,C6y,  @^ZqB۰r| $3󃖽\N8Ɓ3�Nn#*DJ�)a,ݯ/#FvjVqȬd ?gJw��6YנQ!Bcs55/7檆4riMT&7~u/ e`3gQmB ][b.ؒ -cWjSwEZg/mQm|byG4-g0R ҃F5M_ i/¸>$.E*1BC}A¤CAL]��5ޗ伨 |r�ӱ_'4?hZE}c>ɴhiht~h$�StAqU1Cu^p7u Tn�ĢaO }bqD!-,!%hM(J/gIf%GaVw "8oK^ע2%p q3%pK1EXao-@¹V;+*) mW% sω] z¹?QӂJ@_Ho�'4٧%4%�q>\d!CL˔3)rf@`Re P|4*}O6Rid4kf@@ L Ii|D eN/q'PGM/E_0 >R,GP6AYԶOfR8@EȾ|Q#J�bF+zD <J/�_hBVn461(}QޛBBo.0A�[ pZ?VOن>�A{[07z' stC\[Sm|ݗH 聀{lQ,WnڗKź/0[uumR_hoMbLLC"J qYP @� �m�>i;0 \.r tAi flMvMi'0fM`rA T߹OhkH,H촉 T;j/&K�Fn&t htЙoӋ&R=Ὰ H L洓8W_6YG �L 8-O�?Twk]W^T ynn]W!)y !0DZzwp Q7-�H P(wtQ3@o 7`Ɨg ]A�}^Ց�׭,rpeAJ�Pī[yvQ94(%W.m~`-h+ -:y  YE+MkjԘzE3'6T׆Dho�ɜ� ,#sl!LN \C jfOlN|c<Q`)u ܌Ӝ@`\oOl,:rO<~<l ZA+YG SOx)niX61)]i]QbN9G"o`@5 j1 M^0g# ~u?E "j:XC;yL}@[ AuQgM-`[vdݢ>Xv1p-}y\A @.ߵKCsGqjЄ,E Ho$][ pWc&�Be)- $ʐ3wV[ 0("vAt-PN܋!�m @J"pDis ?MtP$ 63fÜs�KNѵajuy=T�kwbM(t�/leC&!=XLC>.<pRq DN 6_QI+;0%44 DpvEJk0uq.ey[.Ӆ9ހԍrnC5,mJUYj-IY (ǩViVb dUav^//^9 =矫rӯȗ,vv/@ =Q,޾p@@| RYW8;F1 zm؃8Ə_H<qQ0 0aR13ZOB]B qAψcd\GeVge'y1 9&Ufc9@cFX8{1sS71Aנ +ǡǠ%Mc1=+GAB3, >u[☌  ^tYPitHaTΑٰ,4Y$k0GN=K\̆LκC?@~l+-:]/sĚ)~#H�} vɺjK4l^%6yc4~%hU[*yVU~Wږ² Ӵ3OUpY`*;  <ԑ~heУW=�p~Ԙˣ�lP"/{T<#Ϥu@@+Y;) Pi lu?�G3GgY(~9�6o*~4XQ6Q3�B_ w ;0Է|4nLR6נ(]rݙgQGYѧ};cP( MF- \>B~NHr,C-�HwpgΘ1w% iAF骱*hj3iX!c8~~Tl:VhJ^::-j^~*Yq+ްpGp�WY%_c[ DU[ɪZl˿eάw'kC?1)ē );iMTw~7�і2 \8 @ЗaA[ ካ ؀nlG>kj.^+Wp+J"%@}4]Nw #8[yW< pAӔ믨rgVm 7VPjNV{P�U"\awZbv Q՟l�TlAXW7;P @:|V|x~c9T;,1@ho)�FˮM dIɩZ=U{%ճڬG7~Hf_$VB<w0gsS^u~~FZr]_%/$ց[vwn>Fg#r}3= e&:g7'_^mcfnVw'E{q쨩$*Е uWe�/iti/op77`P#�xЯŜ A_/#m}S[YvCi >f>esH'+U�D~lex&`jo+#9}ә{Ve66!:8XM2~A~d=}J.36V%Q0Z ^jok>'bGף 6GEql5G wn[CSݺ52ea*1qp^v_9@w :q>o>o=ޮv w) 2Fx cmq u%Q2~vp"j= q؊z0MSm' j/:ghZpH({[ya\9ފM "y&& Gj2[yԖc(|6M><s- $~3gK+KЏ&5| 7!|tx [pUԤRd`":5[QNWR6G5h\H28R(3/9f)|z JCus+ 9 D ?2*8̓fR1U 6hC�OEjah `xli׀ec*҂.t ƾIi�Q~#(pދ'VF 2&"Ѹ_ tdp-RZmy侂wԓyv'g j=xc=- A-Ž#29W0Juh+#Qy> ]]cjE?Z,ڋbrB xǁ6\مi^+½Q| :{xp2 VbgC=W7N㎟%S]+b {!,m%Yj1/~p�"YX|lI[rGI C[CMTlNP9P),WPv!&p-o|^lY}fH^c;A 1x9OUR#+a0 ?v%0pJ1O0@A2~'sz;(� +!viMCUo@^Mv[p5%tsUgZ�< KA\" �#ishHV'w`P*<W+uՈ<#0szˌF('юVg.`l\,.{aҮ-O@irzw;#Q0M%ɜxFT5" 8.E�8ـ@i7I+^[a2$D[FeƢݓm y!#k@<ج( @M< @A ʡz F J#0M0\nMkLhŠFzq.9yĺrn)n| H$NeK,ɹ允lCSbfb|w@Ml-߻酃R<P9QHD|}ix-2RS+ښ.zi<ZA'6n2t{1|pZajA k[j]1Jd4=ͽ<j WWbP܃(XO-p8myYͲmĽ pP{^V?L$QbYQ"olޏ/aN(Ԍ}\*[$qHh UskS,RWkjufH!{ X@t)7E$~L,3I6t0KfBY ܜLԌtub[K%Hh\Cc |hT9w7^NJbƧŇzBܿG:[Ċ(?X$ e)^4 E,00Ȯ[E&hvf:ŵGO܇+ݧ{r<UԅsxŽ泞xmwjyKBY x|5/y^`㡅*6F1Qh<ڦpT#B Ȁd[}4GVQ$#H0:x^!Wq@`6L G͸*I4xޫPU �iA nU/L �Ew ^ X2x>a�8wzS5H5�خg$`x|?v؉t;5&1+L8ExhMln2AyN8<W)*OjQ3~-3q33G I|O1Yzk$aL5GGqUOL/7~DsnafŽqLKqAw.eꛁfM3ʼn=+0�AC;B`@7Eh^᪛6 X+=b!W6n['$tGO�D֡`R"qBۏ64$ uH y 3-ۃɉA#$N�K0*;Jyr"Q7W/ZW 3;7'9@&< R<L~A)ip8y2]$9!~� <f )ri(Y.c2RTN!AAJ0L>En'H L 2"<.N�q?nQZ)SYGN4ߜ(Eb%�`D6߭X,t`O"uV / ⣩& ȾDCRds_9">0F8&.Sڞw!v^@Weg^CqibJۨl!q ;n:n90m�oP$ S%�@ M$EIs'=D$Z#0jP\AH1h p0HmS Nċ\Ղq]$'9.y޻80W S/v0E$7~h\ir`:<?(FgH^`l#0?7J?9PuBTTU<bF'@[s(nɡ<ƊYX9&y"]T'�0u8f6 ؅{}&6zǪ>+ۆ+q�*$z6ޕe+lJRypwn0|]ج* {߰)3 [UfB Q5X´�j�,=[ sĴt|J %0i"[~N7A_*ІX�) 49� -ae qsajŀ=�anHxaN/Q@ `j_yÑ6]. ~ϝ9-UYȇ(PK&(-؈=r? m⣵+H i VԀ'ynH@ȱxY~度j_l-?X,UF bJ`fe*b\Cb}MGy6�%0,;^o%=o^(zbxf_<Fr(ڟ.2ݱo��Xt>`xpj[@%>=1bR`ΟEG 4/~;<<K01D%DO'q9}e2�A@~JQhr@hNyV<PʯbudD'Eo.Zouxy3=KϑY ](#)~jӁ�Fq\˜|/;4QϿzvBRH%�Q>5S'~,`h{O@ GdW8xΒ\ @"= MgZ[Cӑ|(-:2!B<g&}-܍QNz~?6:R}}Vj* ŭ`"#^])Eno8 hA�ALI�=3{0xԟ'] rus'pۺn�%HFtLyw*8}`^":Z�qEYwp6gIfXh$ BǑ148$TH ďq^6z&?V,k"Я6$0/�DڬO0zy;FBu`,�8A<J90z='W7}K]x)?Dt )$M (ϑ0+ƍ}z8`π\b  H0N:\UͮV췁 L|<q8?[eUi!}'4P[K1J0n}O(\ ϑqݲqƀ\7uI^%ӏB>u4:;fqv4qi?`<xs[b@}cʶu4ă0){?#8_g?1~L?Mp|3"28/gu1rpS1z*GO쓣QbטK/ڡ3/cz h!cmu81R'4\q�1`_`/䎕p%WL-CJJ;9ͺNOP<>k{{\>{wPG_(8:pY aAJ�0ʳw�P�FKU3RYU}`rў穑Gz3rӞn,;?*nP`ݬ$>RE=EK֪e%8:WCM>]%Ϝ뫏Ih$OO)fKaAj>3-?#/es�I|gg�GxC?*T;d+GGʾ#ϜQqTWu#4w7ˮ0aM܇Nm3Q1Q: xBg<Bk3T>S3Kpn�3TMbo~wc5kSs~(G}B~8ZH:@ PGRϹbB^m!T#( Xŀg+qta>@ZUiNBX,}�lcVd]Zog* h[!.AdxO7 Lή`BgVZM)i*zyz-9�̶-@uPXݣIQRoxz2~:}9y'OA^s$U)Yv1hTC)Axˢ(gr>*Qr ~@ uC;0o:}fB]!㌧׿H<(7I7tl!,kn_nw0)j-}sHMY*e*oVި4j*ɯM=FTaґr^LJ tN(BWT7IF_̢9Az___&̑*IMuuI&Q#m'_A;khq@_$9sFn773|A> )�pδ5M|PsO@M֗'5`:ꃛXq\!͍P#I._o�aMYX譓еcQ{$uUN)w$kvONٳGwV,+OfR8/ bb]2MX52o>mSw{ԍ]AB硖_w~foܼ3հDmhӓIܨ~j:u#p֯#QMh.̷ؙ\܆[ussZqSol@#ކ%@[ r[Y/L0f?q)GO t3ȇ\v禌𩽛HqKK/o~}}C ~xڐaV%ȣ٨Zw7Ra]5y ]ZCFMjm{<C5G/<T:ůF]#¿u|Fʕ4ɻP eq#1TW3}dsl`cڃjf_O?/ToO;DCmY6 Pt1ؕNNTfy3 hˑ˨]T EAq>#5s W,pQpâ]-5?x+,@w%S|\Po0D!0 <1XkQX+@#7;vmSyY X~L~Gȿ-;]oykpn9w'owc?uγ1[-%hI_$!w3q.5#  qO-4fT5@96c D{ ^[!9 ^KQ92Qع 74 cz-K0ˮp�DABj?}vXkO!G36\iܓ5;b{3R9o=}u\UOQGq6Nn@es* w 5}�Dq -sNY\5r5Z̜l4P0停V:\-F.SA? N�u EΓ+. \"Vih+XCu� H+mE�-(J�鴫Z=7Y%BH;r.@>racsEf[g{ 8U[uHqF鷎V㉷ߩ=OKzV,rslGê+_: ���IDAT u;-F)}<@$CB/Fgr!p-p\+87WȈqt `t'k dc^H|@H*Sz 7\ 1g( tH@Ο9d$z.=$Af < qz(諱qmM([>TʑB`ܞ6 1 j|ɍbBfh 6:h\+S^a'Z;p ZѵVNm)\t^4EY`gw \duH F;[<*M-X=P1U#�0_T/.~=u5<x9 Ra~8S 3!Ekt @lP[G4ʹ(?UL=&+9u(Cn:>2ۥC`f5)fY0CJj0r_ H- _ƾ>uA."f(ݧ Misr|/i!E >eeE mz,M eSō$JTT;Uۅ `N2]<!Sލ䭎_Z)Fݼz^g: 45F�t[ <-B- �ZjAokXN 5\xqaabA_)e@s+J,[ڮ؂[@jΖ1-ߴ<xPڢYT pW.Lʷ3"' ?)9z`}1^25$e\ 0^B n^hԸ?ZA7j=Exg"eN+jy@ &< kݸ*3gY3_ &#&P�MfB~L{MgI}4siHQ23&pWY*pL8[@� D:dqdb1]-2 �iRSQ'7(Lp*N19hI#ݬ/˃r QHtQk/&݆ŲnIbh!!GѰ7"^HE}MyPJ)zg5fwQ݌ѭrC@L~ `U JOUrZD h ŦI�AuYӡ+n> `OeN+J5G ¸# D*ϑ|k?pEB}<{:#GX0x\w#*'i0Z40xZ4� Mp b}PV4QP:-!Vuy®_?u;@oE@pI9‚9nq8iQ:ԆN7ErԽ.s$a"Y>ߢ%n'&g1v(g-$^B0QO,U @BFK'xAiʽ@˯'.o0Xfy]^�Jpa<4rRO崛çV~Z nMG iZ*B';A:T Y a aF ^;9%pdgRX4eKt:p:()a5U^6Ӊ,-C_i T'=stcE(G&Ф!=pr]=. Wi�AgЍWa$! Sst@O@p7ta47T4i5bMF~kCH`F�lU)\^t�@YOn[x 4ЅDצ}tiЅX퀛tW 4N߇%hgU?,K~ �HHeWn# /uHzZ頩$TJkOn]w@` 8@aQGO8)QѶ~Ic^V"Z0OysJ,ciK,S�ZיS8WIob9|U\s@ Z4?XH/qyݸV/6`:gÔՄkŏo@ r u4ìo�p"0ިL- l?4*vmeӁk�% @9'$F^Mp4#^W@(mE 3FǺp$p:hM_FF5PE@-\ã cb1ρ$i[֢Xn:@Ke=P7qVkZU7�0O?m`m8�04Mm MB7Rf-Bs|5hWWD{z_= 4v*ʢ ~ WBM*A\/'LyƱUBϠ'n[M9Rc#JPߏGq%~ )AV+V"JO42Z0-!\:w\(N WvU 19Wu�4Y^9 y^N\ݝ Ø/#%hȦl R7 G�2_Х*|<=RQݼk%4^6i,&RK^bE�`s�nI/_g \6Ng 8L7)i3ca ~EB x LbVz5Cy{89`7 (jz:@/ǭ⇏4'Lg?dvJ`z_N;Op<~�\=q (L|BFҁ}3W3;�@##T�R(|[orjNH2OȽs-mNwgQf �@aXqrY' X6"J 0zk�Tbp#J:0 P�W `�7@R(L1HӴ @Aب[ b_|eҵC�qAp�@pD 8 =%f.=:*贊<qX1q<`}p<!OOڱ%?M]+ڧ_٣z;[@FlY-v|uL>08|-|3zr%sߜ<BÇU`=|=nZ@ 8ݴC%Ym)Z^.0Rϓ@7ιS59bj˼U"05{)Ak/嗨fdY gR>N{ aݚh{u٥X/&ۦﻐ0 _5w,v*VX0*O.7Hq-poEI 诡/ ͖ "yF`<Б\ / [<ȿA g ˠy'i9r ɍ@;B< @C-I--jQ\Cd ǂCM,l w5[&"poOxlO/\zcm@0Qy`OUV]v[VZ>d0rUx8l˨o YUidFǦEN94-H=˧U5bEI<l6SkmT0Ӵw/?@VǫXc/薰N{@: T>Mi>Pq?p:�Kܼk}9Q R'cEt檎BaQ W]CsW71q(ǶxS~B*"=XU P+ۊ1Go珰)n �(�xZV eiR?yJG@bs�6x$_Z�rkAJӐ{dpsz :›r{r'6A(*gv�*We|q,יgq 0l՛> 0r_;ߟZҶ"{_80[Y+y̶pŵʧ8ӳmgd&,y2؞m5|q9#ӗĘcց?J5Ym\W(RBv:j[/=#SܴG(ny$tЌW;MCH ;0 PĤmw(_B%!r ,0J,9 :2D�QuP-GTx̛Uw/C5?8ӑw)3>:דol1sEx 4_~~ExL еu%OaH_dkVAu2rMK5(? ('<Og[cI'C(%QYfz<qL8qߣGV*#5F)_E0hyتl<<Fd^%/YbTYߓpIII>WtW0M$Ǿ_Wnm]Snhq48XzyQȍ[ȋV</of6Ş+B$E]K[O?״Ϻյ[jSXu闥)sjeiT*}qOne:vi1[չHwOiC|ou&S{LjHO)Fԭŝk"ghĂǨg64bsdEF*.!,zUR|dw5n(+M 7tW^Tt;=Xʝ|�K?7|8=}pu Ӆ;9)hH~I{й"f ~)ĹU 6w{0A ؑջ I݀) ?n"w24!=/2_xjT exc \_ٍhrVd`7[\úb۰'7M`[g†G ,gdwn HÀ7f"?S!z/HúՁ%?#DKm݂|2 ZhffplD {@0-9b (i 7/ܵwC^�’Z+>&KRLQ$xWyNZmr obQDwGa2<K2&/Ǿ67"A42̘�ֺȟn`%cN4JO(Aἀ@R_:**`Jɭ�2'Tr^Rm}/ڗ#ݣfzĨhܫlޣCJ?|8ܬ6_}ÇCNF}mlVQSc}Kۣɗ(%Lfk `[B(緢T[*mB=H;o%^-T�ǯv Tel(hN5$2ƒF#P YQ]~JI`,4|/I2A]U/|A|'j2wc˜DcvFF{ �S7@�ețYyf#0*A�A Bq0|jMeI4Q *`QdLzkN`oAj9HbR6 R_8!`_,EV'o_JP{f>ck貶rܽbהͿ= /њ�&LAdX D9;] (` E!:8OdGRnPH"  GUFiԺ D9ptB40bP#: C,(M_]SA1#4)^?S(g"JvaeddLKc*m'‹N?"lxh!V@cTAx{$CC d"rr@�F TW4`FZ"Apu�a� Bd  -2pzzuQ_E2&05ªGJHERAd Ȉ CV-Vn �L|/pr#/+*_�Tr#Ȼy]u{qe FsR Y`l;.lYDܱL3gdղUªc30]f@|{Ҋo4% zQX]Qb%Gm!U'U_ b~,r`(o2þS> Ə^3 _' <Aؙ;܌6Ž"<LYT E|2p` Ɂ!V�.<uv q+ Сjj&tËL8H{ŠQPxhExd`mDS 0ͳ/@Yabg!�YY5@idw%lo ~}.؇T?W�-ɘ# P݇~s'c"uʻۑ1Ib8ccҮɀ[*롛^ۃKmS39\62{ w: O`be{<7VwQACYAFuaa$ .KSGXP6~}vMȈڝ�hsHU &kʿjZS"7[$D%Bdže +dU6_)_%zX+,ͪNr"k8NH/\Z`$QBRMT_j&/7JAٮ e W>ZɬEdEIj1s #/cX.3`z**2>�Ay[e7xE=d}W!d>,}p?%)Ǝ~J~їx3(o;7:N!:\yԃ毵dg2C;$. $g@h 75nN'C?"< 'C;Cx Al%XepBmJ=5-#}Q)t+t[Y1,"\*Fݜk6{;>Ia{dZmj9ƍZkmkmZV+= 7A q)!n7d�R.IdӃ&v,w&.l.~0'LZp;u֒?]2d_7W$2�AXˌd)j] ]Rq94�sb0m38pizTX)8R@:G݉Y+$)4m uFe,`U˗GoN {m`Dj9#%�|]sDvTi�YWBYVMl|D2>='<8D0fBOfw*U>[pEՋ0q!Q6j"@&.{bexrC�`Šd>\D|lM!EyIF'�<L=^E�GMV/:dy=52C�@6L\>LaWp$/A1)U6@;K1eZ X9wF_3IEѪbe;;{z):hΔ͚Jf=@ %Dօy1[ (�>"**`Tؖ0~]RgMUHG3+`7h v#A8NDYWĬ6z<XVGiN{ ~ )D>QV{yɦo\-g&.6B?>lf9 cKR:B@`HYQd::9uKƻs+CMEuX)jEzQ|R'Gxx1Vv٢sLLNGŸȩ@̜b(!2g&m?pOŏE< Hg #0~fb$\ p2KrXӓ[!`z@)2k/ 6f"ƠMkNX %l-Y(IO qaOL}!3/7` 5R!-D0%oڰZ厲!Ap6bV 77_�9`G~Zh՟i}CŔ\Ա.Ibs"= ZG 'hᅧ k=D'z<5v4r _ Rhݰ8:qu2o!X7c.I>>;|- x!.(C�Jh{RyL}<R^~<{L{8|L-/vmTO|"ׅO�"a5Ng�Lkpf5i 4i>KtZ9afBSxH\3̽*p7�Zڬ4m86@tB@0!,C/՗bAX,`*QfZj^%%\1qC T!E;/c el; vQQ}k)Zitj*= +VUb<tŽI2h?HǦ,wA_@(|K<Gk`[�i5nD3[#`kgۮ�F{3P"> iw\9ow n\Vi!K;y_<OL~7zb]$cL|6l[ ҁoFd�K0,ZE*..d*6@F63.#Wo[ȏK#`)"tI)"¦b)Z@@^i³r-VJX8n~ 8!m/c}SQRPn"-%O'n}-%@�=䘿G_] /j=;#4PV̦:Guqb>rZ�cH@@E`E?Fe]jXi� g}3ۮ�ԀhC9Xb̮=XbLFd7^iE�AO6@ Үss.Ω%�AuD_M *ӗva@XZW;-o=`V -AHNz#$%%3%DA:+ L�D@ebI./#"+ )A�w,Ecb߶U� qۗ<;6O`+8PcŶ .PRZIt�<$ n/S7/Y z~tt� 9k*2c;`)/�&u4@.+�6K.~8 A`l6JAzG| \  EĚ3W8rO*Ԙ"H hz@ M7ST߰ IOOGWlxO\1j"tldHTI�Abg5=nhf$O7b.[.V=k~/Lž0ͼ< pW\^j¤+PJ~@�An*Q8L<31/ݾ 2 @m;9YȻJ!zO>esŕ�dL"[!^ ~a] \32A9y;0ldhSA桙w5@`\`�%0m& Q ]@ YO1]r5ŷWP柵OW{\ qa-ǰ }{@ Yb6Zg'@ Jj?(Au{8�Vzcsq >}t)_nA�RCo#h(Hp]g2hGGU\"og>svo?_:ۼg<,�Aϱ}+%@@`�Y0=x]epۃk $Rc/LTϝ#}edf�CY6xux/%>ƒ[ u?>F۰GA R at=v4D,E[p;]Z@ `8>Uߚ(鷾Mg%(XMYV()wA_q|6@`|[c^g@R�AtƜZBPFJM�1t{7a@pc"HU>Lxh3 b@LK(FnMD2))ozn9U{G sM;7'bb$ lq2`7R9O 7E G~b_%Y}@sO]K56}$oN9ܜ-Z3_8~=3c~d,_cx8|+j)IhVSHV,;6lnq2ݪy{XK-R.a=G[!+ŭ�w jv٦K( jKP(u9_"Z>/bܧыd7~gWܹ皗砞htC53_`sVt4zBo-1!?U~s@pս:v�lFF>y.j -(iu4fْe$߻ D,+BF,@[`BY뎾E>�4(1%MKƾ[on\N_ηOW[ޫ9Ǝm5Ofwwۋi6z`5ԷB6q8^aN)$]F=7F&~.nw_ws7-n|c͡\Q(%;WFIlwJy@$|!K7&Qj"V FF{å !MVr2z@C[/󍣋&0TAC6 ۃEڠ``^Hݘq'넌�[/47Q9� CGMz¿cm�r N$&C=n"ȫnhIctR v~cVl] E<65fWIoaF DMl/oh R! cbNp+ƪl2I42^5l /L-FB;z*2,4n1(W^A,f*A`I�Y $raR0+6eֻ-w@PC6>Ԩp0H w@'j̴ %G&<݄[! ͨ'ͨ n?[D% VA(_= - 0 #pQ_HX FybXO 8L2bvMB-. G| P"SQT}�PCuf @gt)%o "KJ9}^ C -(@ -7趨"g(Qx< �`QRhm]n)&X%E6*V[`r-P^isWp,$)!Ycv<ƎA,-㦤\ QrT'X[ kdug%1؍)Oe�AbCE�!>hnzѥh!Q�&:@f13z <X!2hlCJt|X;@KR<A5^?�J=xYlVh$&"x_.,^&9"�\e�SP jg'b6@4@�MLJdBexDC ��A@ W l;AbqݩAl<X G*InS@}}>03$0-A,N`Ap@蟦 Xi4@7 �9ǰm]ɔ"h)s&PyBAExJ)V`f$^\Mywyb ^0 {&)^xoAufMj$�E7h$4B-�B%`t*LӓchhƔ2l~,,KFӆ Ė�>@ FCO?0Yk>@ټ7j !}y[uRzD^ˑ^JTQ+^k� Dؠ2a^VtCkU7}:*pӞwZr-fW5k\ O*z4Ǯ nR;&\W* &e 2f_f=}=r˞B4ֶhIIh.7+ݑk;:z٪ZDE͒Bsr|g<ϯ`I=y;UFGʩף ur P-95gA3bb=P*ym]7nEd(|w0Jn/)눑S-B <#UVq"&HjsI|b<yߠZ5y0,ckߪ,,{xN)9;[% ·d^[ ZEu:Z?T 'լuXqck'ȥ]'_bK:KrN{8WIFA?hd߉œ)-|>A֪sR9"')g/'h;9d$KtD8ڃO: *~iP9R8e> ^#}j kwN$֫9T`'> ٫"%0pru"Y7٬2-RNSϠMbYv%O 7ɐ WzrvA~>9wtKs(R!?k͑,l/Jt@'$UiEqDN8'l|p*^:A^u㎧Bj4(2ߙ3O'qMWlGPnPL)r\Yd(I;; ڧ ϟ!@^0 u[IT4='Z97jDo NS1ީeԋ9%K8b9>/,Pf,EO9Y:t6M|ɆM9fU{Yntlu5dw ѕd,R\vmڕҺs*Pi֭9=>�q-vr0�� ll4$ߩ0I_l5>zZ'P3h9ڤA2D4F&~0r*Ԝ.YdMMSI}L +(ZG>?Aj젰B `HF`7rKI҂:rv'k 6Zq̓0ꔟ51{XbPIƟkѩم6*%rq& ׋ g1)Mœ6Q%Ʉ4CvYC`@0)!sC�AMpeOZw}2Ň`U곉 5P~ҩ_`;Q=E, `r8~˪n-\x6tRZxVaYr0{ѺdNu}\82T@J֫dzZ6uwápE�luOHBag3A;8$5KǨ,H$_C@WƉZ<+5mPZ)^iu}N㏩SCʠA9->ҧ',v5kNVR g@ q0ѽ@ *ͱv :R#m92 ؏ {VG'{-Ń(qS'YbUg;9bDN'H5 `%�t2R-B''#q-iۺLx\2쪓-CH9c{ս01Ӻ ^SOD(DQ| xOxUS斃\wrE=I9HH$KǀUK ' �A^QQ=%8 wm9Ȑ{"�O>$)'}-0Etku˚7K.+ Et#�JFj@>mVx<HgK1J`4h}>-Փ{{s!eh^ }5wqc"u<?Xq4NiSps^`ne5 tX^G=Ȝi(Ϭ& L2Lup + mPC%@TN*?6KQQ ,Q�V^PE۱�p{iL`&f:4a/ey|Y�x7 IPC>rC5AZf2)&YTnGL0ڔ^qtb>F 58S@Oՙ,Ft>qh(_Ew$5M x!CnΩUQDDyP`1PFH41Y[0d n#OyQC;.ÈpBh;<">/Y-Rx7)d 8JgDDL}Bwhƴ@=헦ke= !P $�R9}=LHIjXս[CmH  0p"ܤ<K`HeOI:&\nBMO1E/-ee n @ùJ^T:&@fճ&�zݎ`ru?ѝ1Q�ߋRy?%+1MX01VP ILfi{?? /ønt+̘Vy{ڬ 0Kb}vu&XQX,-P4|TOAO|3;Ї-[I�] kE5AF˨)$$PA ť:L盉e~)AP̒<Tj/,9iCW 4AgΡP6RޞVѡA7b ^� )Xq7h3ؒ:&�qK0_zXS0H&2RiYD-hSJ ^m tq0i DWx +" pGB͓5~Fr`�#,O kZ'1zԎA~}ٿ=Gq9_mzWС_{vS)(u7(1J�%`@kq: uw<y,#A) C�A4+P@_+�e̒F]w%Q dd4d{=Jg)1F֖85]4`6(̞ep,@ 6 .p8mГ^"?(;��C}]6( 'r~܄;8lv]eyĥ:><:Fge#N묋\u{`]MR9�E5BH[k4�ߪ0߆JQ˜?^XRPR 3Y  ciq@ < І|6"DkN!6@qgrV�Av A7;+ ~90n4Z 4Iboz*\(�T:֕n_05/`80=7p4+><�n�DgSk0y�`{Z wx ۸%B<d TlI_uV�x"ADA)we<=d!RiҹmrZ܃KR =, %ʶne &&-\�[KvmhehpY d^` @fg'|\0E,Z@?uM�iK{b]<R㭢f45RXD4GPFi5ŵGQ  @rY(]^\bn>_qQcs@^{U:ԅ=譚1`iT=} mfYFT >\n�5et3(^bxgtʿ}˅6r7"LQևm$]6t~5皽QՀbQ95lF#2`Z<%~fͺQXK6J^#eCaoo7 kX\2hM}}V z~"g`Dz`UȞӊAʿəaQO.u6pI}C/R*Pvfzzl }ʁ0YQC %~oa ]4Kݭs[VB\rmnH%tkqۊVTc 녿rKo |zFYi]}Xs[מ綒G9'qSw+EmUA v6Lˠ4q#E 8c[�0 +6 GJLl ݵc>b [*1Խd66XuvUp ,De^h ^d ~:vO2Fh� )wqhtTAÖ,iR"(�Rq _51\``NAYPG@]Ƙ‘q4ƋԳ^%|I&i.A0ނ h J[ Rh;g۰f8R]h0ve-2c#: R[FIbM e\d lv`P~:dޟ@7(4IfnK$| Ũ;'gF<E 썴?U Qug.Gx WAbŘ1~3X5{_ċga,]y 9YZ)LdZ<9ǾEBWpeK+$=lA@ׁ4$GxBAgFQP`g=ҙHFFo>ֳ[X ǞU%cJ)$S:̹Pv]cvL"2;>�*kK&F1f:d�>{` oqA'y{&Rk @�,Bj2J:BQt_Sf o; "Z?0=mGuyo qZg ɢYb>V^Ԯ2C*D�g`@IQ2h*ߏz{@J&˃ d0}`-|Y7|bTL}h�#Q1q"8Zc=^4?�2sv; ah A,oPrn?��,K!cxfL9]%9 T3iA:22CJ�B>65$X.O@wI7b`˙1JzX`�pD5[uLއ!&{=+8N,)f1a0cqI $zL2D N+ё1?�鏼Hϙ1tT|˽L/_.|^0]6!ޢ@-$ -6^9͒e`d kN u7ַ�}evPL2XT԰_xʼn !RU很!泌}? ?gVB+aǞgdqFN,9Tȁ`ٚbL*^tkZ2qcD=2Cb$c4ɢ2C4ăBR~]ƒ08]KPC 'oP)"aMjLZ<~rq2[ǻgjŢsvR<q#8M*Y);HꏩY.a"W`V"wv-_><c^i,|n2Dg?_ v=;Nn?=JMף+Jх +˩%A;ھ1U̐ ESdBTʄ>jԸʼ9APr̒}bʾЭ YC` ʣlHvW^w > Er\V'8`y%* WM^uEq쉔O1Ovw@T@I-FgP}S1p ̟zW߂(aƜWӚ=kWf n5]4\7k8u2Pn{l.js\W"] ?ҧ(Ϸs!upEhuq4r猢R:ɽn,9%5n,/$%v1ZוPJO1v~q!̖;~W[+ёolRO攓joCi w+a1|C*8˧q ߳#]S})B#LwX:"D'7k rD*GN*c}SE~b?ʏs(AG][JcW1 SD_vFj~ʌ]Qgtv#O*3lwW,JZ_uџ:`7]_T _N$%Iw)Q.bT(;~4vrRiOgqN@ C}_J_}961-9=%rNWY틉%rB<}ǕWN5JX/]j!mI2{9>$ǵ/>|Ry|K)9}+0&CAu~ė_SSoڻL._Nv:=mQgFE՟mG7spjhVՌEfN]O>St. & +ʠks|(SZdwgjעC)'ɩCɈWzSlS= g;s橞I Z)]T<Jc'#c{0%x@?֞)e)TGEN= }<bFJs_U:W'>u%$}rqc?rDu-N5zrڭ4%<O.>Ho'Cm]<+vbS!e詜 &Q^ec_v;iX#'Gi,SB?ʾɧx1 c}JAnZ=tK��Z6ޙ?NvsEFcj'P˟dtQ vr ccj6ǔ/*IJ}rL!,`9#gg1w#/嗨vz*m "e 75'>"cguohPS_hnjHMX9Huryʿ^2<@:0AeJ Fрfg48o2Oqg <} (WJ}cнrC]ɩOt> Tg\9J5(Ճ֩[Y{4`Ƨ\R33gImtn/A{Gxyr^q1w \ u�X|,- n粏c <W p22R,=qttcۺoYM[>2Sڢ 1v-{OC_ڡCJv/-h~''3d4F:z"CϟQO1x˓ȯ�A34^wTBt~(P3JMٻPg/ȉPd/nEI<CqɿO=p}�ð w܏&9~b/Iݹp Sh0Z k p=WkyLcC=.-�J.kbfU`|=z𲓢Ta6pG<W1]S&qg9EO c ew~lL7}J<E QnjxGJ:MVtEwrkѺSwu#}ypJ({{ y<S3%�MHs. %kb61ΎiB qt ,,q1:4ESv꽊>vvt8F<hG2 }D,% 1Ϫ_ThPJ>ņ�'9]'){m_QT 9^vEpMv)} ?!в!Ϊ)ltI!(Z?Tvo;hÓO0Eb낣ZUC;h;`S:,e𜀮>NB(tI 6F3{|ɘg/ˎg WJ; >v r{Rp7ZL4AVgWݕѲx\E{߱>SB3o~"ޘa=Pqѣ_"T˨3fF'e,Qgq #z,~vr~,1W|v6tY^F ]ځ/ȕ3V?tN1J3٨@X8캲\fP{+%͂O><"?"p{IԳ"]ILLw5@ESt(&t@R?WoE'W-QQ'fQߞDfG8gf^ԋ$O0,ʺibDs(ε-+1W?+8q<54F/&VHf48qlݔrgxmut(ݭ1mw7=q�piH^tԲE:1f1&f7.*fU/˟a i;Na'jt Vxd&5x[�O Nj3#XӏH%]2Z;U#p?CZgkFP>Fz3<17^p־e <tȴ~֤2e :̨-yL _c$])3xĶR !94V6ZT-� \O9w,;@ͶH5.44^wXҷ+"kr2m @e^c-DF=] 0uO|y8qb@aش+o=;Ip͆w8xSxn{EWU$ njfke-$j eB}A!iZ$,7Zb^ʻHKˈ茒їgFlv 8vXugvIlt514(qMȌ s}sE#v(EHFg! GjPxg3 tE,{7JD1)AbUZqC4+h,KB/<}/%<n} z˦@�@b}d.tZ8h]�rWF߅8b}5k*jāH:; J DIסi{|/҂itIJ.nj8 #XNqrDnj5z0xɺsp4p?KZ=>禘B;i7LѶk$/QK %(r0�c{KO?bbq,h]'v}1`UHMv31EfPm1.Ɠ>'�\t (h~˺&P@tNS&B<Qga.;Zqe ?ݡN'hg�tЃݦ @}hqA@A}n/өbWY {cU:(2g);ƞˣ,0(�j2B8I1麽ئC F@}�eR{"ܳ@@aXkPo(MaT@+9;6%іaR[g%GYւ,:{^FNB>3oPl! do'л+xYDV%NWfCW+3m;Y2MaA,l4�0 #Ĥb/L [1=gv鰗K,ʺfm1ÍLab:K-6;>ju5fƣQz -|~ O@g>G|QvSkg67D-(Y%8.n}WP[LfݰFk.Gq56zl(΢;ͣQ F? Qow�x ܷfWRR Z皿))2Skg>ĞS5LWQ?[ :h= "]loA%lFb�m|sG&3Q_zaMθNtA5έIk�c.0A:kFKeb4:\x3czWwٌeAߦ&ދuv1lNPx3Sb{=FϨ&cr)[SYg@LJ$i%w;50l J2kP,]E^]nh �nSՙpث^иEu`TÖqoxwlCnOi0%|ih߳Rl}/5_ O$w64_ָYQ(JVj2Bo4l 3ثwky^F�6�5 _ :^Oo _u@ VmNTz3(5.DzزK wِl`s[|L J⠲QzƋ0Z sc<52" :<svЍ*v1ŎW=:Ի-:X�B;Fp##? /߅m l\%læUFPh<؆=ayLuƝ2gq-m[Ν*1rM`B "m솼od#oLÝ`2~e-5uFJj`}/F{8XiQU@;]Yf%%H=+ƴR֩Dz^ ~\:1eJx2Ɯ)7|B -vCL7w_/_Ǘ[vTZm똈BQ{EeOAWd =D5>j IFk�#DiLiwt_O�@#C=YHgx9}ʰa ȁƔQ@oJW6"aaa6@Mg-iԉ@Z|P @ʏx6=ʿ�;,IJ vӰEQA �@H�o NVI/Ie!z%A`ɇ-؎ 1 L㠛z̴t]fmZFi$~9TӀ]B"xA 0IA*| U=�F|KҤ<h~�`="`J`.pZ^߈!∍G\94q%A.14EǬ)G~߰v` d18JӀtK!4_U]82+]FxDG|?5�- @8PI͞bɌ$k¸H,O7˂7aU)*ED PD*L.(D&%WIAAC0}Va w$N%d%҉gږ ´6 &:�s W!,{Ry?$@KPɞdYE=5|w@H #d֓t)Z0Ѓ 440OIhxZ[-RFo~A@la @c2vWY\ L.j:}2ºVdpW6i^'h(4$f*A!`�R P)*)Cw5':?ąDjSaebak ' ¹ U A_~{p vqQ,.4ŀ  8ea,�C&Y U�!`Y +C65oR3/DGTgmRN8`MIljQɦhI4jZ}恠/ª5x&[R@JDMA#΁PMn }QCbrӡv`␢Z37A}IW{}o샡7MAIU-V:ZQMZ⛬C!;S2Mn?9n RDoXׇƒ1_4zc=MU4(]({I(!hJ)ty9bģ,<HV8\F8Af6b3Ҁ1km`\4e?O1Z@'h+AD_a@fX[!)<IF" ,ɫF JwwUY+JD#@*$%H3hGr6V}j, M%嚕mWQ]`@ɣǂ_1r!k̻{f m!Fkq4XLn w UXU2N⽬A kAS\70R(cͩX蚒`;XPl폩9L<  3- Ȋ#̵xTazvr4T(0Rj:if㇨j! 1tE5*fTT#]h+ENL\  @w 1 q wA�+љEaf}|<  @RvI9L{$KBud+@B[CZu!Uw6Z@`,;)5|j.S2V*hʾ�z&~^y(J;47hܧZb=퀸]>q'@a=]<J]^Q/ɓ\ %X˺ۗ%>N |bctq1;W1̀l11*`UTU:H ێt@hf`'tۥVwYPU5IOR>9v1N܄kr pN݂i x]par\qQ'\݇,9/ScomM�0zSAД5�8YeH1M@RT ok֕Jz�5 *\M9B5eUrB�e#X4@Դ ֧M79RW%w]dbêzuJ6X}.~?]H̳] 9z˔*Px٤SV >w~.�J�^w}4ce[+@GL7@MX% e܇ (d>LT7T=`8U�KK\rWSs9J6Α"9}Uv-KTǪ0sA5>g#QկUJW "f.s-PǶjr!\G^LVmޙssה9>ƯG] س@Մ;Mt]Y/9QL\d |yc7ueܬ2(u3Mhafksr A 2^ ,smFQ?9'n@9 lI1v]-Z hwd.1'J J5Y^|g孱 (A!u@:�(A_:+Xj䗂/9[)e"[|f"xϛ, ݜɖ݌ͩ}}naћ3T>W CR0kLL]Je"KiT?Hbj 5ɀUL l m@H-ER5A1(Lx$b]L1^&k�pI(#8!|=E-Y&;Hy XHPJ##lB(MXN �;qDiKE啭Ƅqqz0P8켢8~m`ozE9ۇBý?ȑEz ?:9b ?BʀR>LV~d氽T$mG 4$:=C9ʑNd~?l~j?}DƆ) Af [G ,<2ܒ A >%A0սnA<_⾛4\*JrfGq> ?urPeڃ6l*ļ YzŜYV~,N` S%wȸpr'mǷ!'hp;h`{'0mN\ |6ڐVfCS]V5oMڠxr@pmc;h뢝T)LbgomO߆Mk'o#惻v8CV::NJ`;`{6Cj {8[ lc(%h/=5RdlΠnfgنZYlЋKw~<nhɐvPiE4pJTѕ8-E8Q]]KЦbSIc|dSS  VY峼3|k՞L.{ B%]値&(?-ͮ`xXg %t7@  @lHܡD�+R<+�PtdXizd.%j9a= עV=g�ݻLB8=%}:|.<A,y+ @W)�mAǹyXxjL9o0>q8FA!�X Y i4-U0렘7( ҧ%%Pa{FϮaಿ06.>k4?"F >gYX/s -+o</ÙzP_v^ ȤyA[?ey�c7F&{cuxaDG X� Iэo<y_n�FR;fǫ8e̒tszM7 # _ϥ[{8Њ �4$KR_BIdzྼ#oし! pۚ<8̋4@`Hư+V'* 0 Ϧi4 iCxZP̨2.ˬH>|M;ѷ-F*L7o~koog[<;6[YgN7 3>=_r7~x/Sdj$Z4+zYY GYn;~8Xϓ<Hv!IC0MR �`Hc!ttSUݼ<KTHQ{O n} 8Ɛ`P .hLЧ+.F`unF<E})qj>$@7N V? vC_9jcIU)IPp�1T[timP!v;16Q~nFhn7[x~Zh^<vZOto^uή?JOC{H=m=맗ONJ7{odNW: _X1 +MksV7bznmmu-}յZz}ϹvC+c֋[ևb!,+ KvH~<,fteB_Չz bdx1q_q 4VehbAZ oi7.FK\uޟυڍ2-"Vny%{BZu]G)+r -IڄDD/ic_So'l/ZrQRVjLGGxM|dbPt+ks#/*@IE_\lI #;]']֐{~B)PVmR&9}Ы:S'Ե=nko}}77/Vkw z&/w?/=_״\DŽSB�mx_!NdCO=_NFG4",4r.8!pglp%$ pn3$-#u+ vHH71b *[<XF#t7zD7C{5jYNP~ziaǠwE6H?N3$ЍCO $if\I13*;ZvGW }?ܸ&dlNnow4%:wٸ6~AO}l}WO/b`C/߰2'"R5>{lՍ:R�(B,uև&bC=M hƬ_4Tq] dg X 7۰Ho(E-1/X~O I7][>H Ui*q9)k4^o[,A+A =| ij~xjak7G+7c JMvPMG}2{ >;BCU릷C ڈ-AzVݘZjg )$6 (w9 6dT5=O6L-qf8ĥ 3o(%0('y�NPqˈc1�#F&^`�0& G -$x;W (܉  qg=+5)F)4G7@H Jѯ@g)Ӫfp'g鰴9TkUţUOwgΆFP kq,4X9@4Mz{=W:R0Ldƥ-6.4vY @NsDݾ enӚ }`8N 2>$)dcxMA Á-?+b̑S�?ۼs,6 xL0CT䜽`|&AVƉC{c0+}e@1t0^^K[ضF6ch5q>1yv[26^9 jN+0O!lr޼TlЍ.?OЧ*:SPw17r)N;`7f /@t@"Iq Z0 i G^<&0 fhNgAFiT6?G0�YaF~C>/ eWEiB橖A=h]\:*!"G7(FX|倂DC@F˦R[�"H>:79<Eb(hyo \0(RjЃXf*>}XlZEmzIWg}# 93?6M)TM\MnRnWWQEUo2Vlbp}O6MYV&U{MG7ٛfwz@=^% ;g"$q)86Mvv('dKwkC%u@BnXkJޣpO <ed&OQMJtѾTMKR f(�M6A_ֱfw?&{D ~=MZrSA/)}(Jƺ84{{5c%?~)h&Emڧ&h&@ M'M~_VC{Jp>JH _o6lO+c7}yưCm*ۤ6H{`"o=;R`=@ñ2K̶2 yFkӸwyO zSm*dZP4e#Ŵ~x.PF݁ЄYTk: H䐚 J �ɞUpjq&!fgav{`Q7ovH Q8ROf%Lv{OAiuj[p;hSLMS@G6D:B`DjJGgvP9 !$iw&hD'O!`o7 h^G.:4@ "/婹9HJp퇕LKP/i>MiOˣRw/ҷ& X_`9$M. |_in1<4QSIo`X@GPNOv�ZSd;Bvߦi0/mn0.ʰօҸCQyԂ]AvNߎ!we7EZ$A�۴E1R={2M!';}4�nlzG0OҀ z!-=HaX}_diH: G T}ftq`$As/ !tvP@`gߐS8aCR\ u<b{şOyovzŬZx/@oc8KUO'=A]oDcy&RcEa?`IU]vֹ/}+moʹ{z,/]5xugnPWqcõ\vpGhǬU0Ryi] ףUFtQۤ{. Y .Sb\ɛSBWyӋ\v*y.wTQFvyzdSJ̜+J�ńu~)x M|1@ۋ:l#*/A8Mo0prSm&]Ȯ];Zp]4oDy[=B ecTvKEOA+A,.XE[Pk>,hMyN_6J!ZzTvKFnKqW])Jn>U"s5EzMK͑`aߜy^]oiEk!�STHWDAwJ*8?ucT_^#|\ <j\WVKUkr!Uf̙וy&@*9^Vկ+ .*[dAהyN'Ծ;ySAԪ`/jr¾wТye.^en̋Jќ^Q^6ϑ6k̕(kAU+KQi!FƄ<>5+Ug*\V-a 0u 7]8=ȸuՙ[5<[?ZM; x||k4T J8`|`=RP~0QXk[kW<v]%Uji!ڄzU_ZJ<]5}y";>Sh5wJ-aLkƟERt^Q*z9@.*cmN67Pé9<R$HO(| 9q;?0PrSG6cىlk#m6VvtN[Y$(E:aOn鹿6~Jd"x9<ݖ8>^~M#6)&0^ QwO` $0 h3=m`t",&8:W �N;~p@j|x@aG#[qAa^Y:<~X?N'ԝEf"8<2QT_Q&?yX; lŭ߉f};8@qDmU;Չ�zjuӇqWG?I} vڕ=߉a' u|,[tv'$v<Piւf{tJesN)zw$v6m9m ̣6A ci 5tC1 d6Smn#6V v4Ԑj^jꅬ6;%mc y�Nyh6?.�=O(Y6"d'FV26d6X+> Av,PRI t]D~bdڒ?I%PRm oN(먨(F9Sъۓ} ֪i?֤X `; Ѵ:m0Ne%@h u/\3ESmi(3ةt*y?Ù,WZ0X3Yufov;%76xYcDVdh06H* J9ApJ~ Y*Up7'T^&u8Be?\g:Hc4糆}�Glc&lM˳CVX���IDAT~#*'3 ng[1H/Ž <AMq{. < c<Cn0L, NL((_E 1c44 C7 aNKw@.] 3@2<qRS$cg̞Q ewcq�^`UJTa+歝QyRrKNGݦo!cXWЊB#:J (8 hȩ2R⸸:q puYzh+:b-3%"b&ej a M$iP&7YEq)Dq5aR�u vq"jEB m}D$k0[md3u c!@� O`@PG,9]�R�A;ۼ&TDze p$T8y�)GCap9줢+vk-՝nha }Ec&�SlEw~ RM/p�)k]HH)H J.ʾa3>@Ё „5R0PjS 0q YubBYi H fh$FH7<]= exXJC2N=fR_rV � uchQ}:uJ �1A �3K$ m@ՁbL36tؽch7%N߄ɺ")A$}q`dBirm$' limY4Y%n\!v,ø x:Y&A$:g 0L8@_ ux8mLmJeU}ejڰXgMyl8lFnH]xK-/,ŖG纒 .έoҡd{QRd9Kc:KFKBL|vHju}g]ND&z.V$XgNP-cлU^}[R8'uҙЦƯh7.sɢ5 XVSZ o- )pzq-^Q|JgE%dP))?srŇtSO_l' 7r6Wҹxqx3]=z-@ڕ\pPDVv>ԻbX瞰NtknG]`Y6usE=u1RܣC͹k>M.~.?ʅ >?yNCqm⩷ys8w7uwM(Oh'Q\-NeHYX[㕢69hKǕlgT:MiO`[wꨓenh-Ц#iLucx4!0Q˘¾QJ|É {~x&snnlbr3(evUBFF-7 0W`6C"7ާ3o8!'%;xZEEI (s'0N7/QxqG/D޹SQoe(}Uܵah$4E^ryՐ1{ B+| 6N@Czu߱B0 )"e4jgi]Z9z7GB^,^uae9A) ;dcO@Fl +?1] LRWFKjf*Z U=y:"%"xmְ3_`¤y=۸'0ip='ZuTPd慆�¥i5$i\whC4óG.2q 0L:B09iwD{9�q G$ [] n UANaAc2.Iv ȥZPlP4v0 ME ax7@\Cf|1C gENKun_å._~ AOQV{� V݄ ۆaP3q(7!@*Kc-yܥ>JvA-2}u A`KHq:>0 =xT"N 1G#"P+xXr^d~OV3g'TF}0cG(NvF # L -+ռA2J�oׂV azJVf1/:q8JGz6 eDQ̂�R`|E-92~d*Ѱ='v'RrRq; ސj8 6Sƣ $rUU#7uaPͻ9() 6jcNAeJ/hZqaz`Z's, /R-ZC> xω^ۭ©>1 %@�b 0|beΓy/WyY*<0 _qQsRgIdd}~ҎQzZĻJ>x:HЗ)jW9P0A5*.77 l%@ P0_c0$4YڑiPia>3%btvzONڎM33\t7MM5_!nuױMG@67Nc6s7랑 -'-yyQjҫw,ɿ4a~^ uTe5E:_]VY  ԍڡ.fm2%@ zIw;N+詋Х8 =V^Qv peF-A[ 4X`͸ OF(pѭY|79sDV*z͌).Gi @L ?Eʦwz`GڧJ#¼%`s~nW3-%0y>ӭm̉6H| g�[ed$,� sӟ.M�9#=- chG},Zȃ"l^Quc.$l?-&RWAc'JTg [=Aiiz{U8ObVI =-RD-U?ƦQDҟ 5OzO?µbv% ?Uvr0y@ ~ɾGT{)zO_|S"D4v`)z(GķQLU;>{$bz9ܣEhjߔ|ڣ h쌢<<7l_RaWn6hv<&^ggp?ڤك#T"WjN I!zpyRE< 5P6ҠA#&@F쾄VI[Lz0l2캇r(g"mK<|M־-fzq rlG?}ewF'(D+o_V{z{(ІNQ X_R/q M%7)ޔe@*[070[̃݇.;w<U fm[(o'm*�]TUX5E~env Ԫ#9Yđ`eKVXCb%c<j�=(-}ٰ ր*a->ELӭhjFqk˥PgZeFJ'S�c'Ж�#6]td z?ڽnn̰GjlU@j[Xa $W;0Qsj垞+,cv:ܕC7?ǜVl.,=n7@ "SF̉z _Uh#YCJP1N= m�`8;[gO|G;p)ؾK3S_]FS&ؒ0'vUɚc^ =t1,fu6},]KGitdrY1f4螘&Yl4*L+SEZilwBD00SirbUn}d1$NjUr9sWp>G m;n^Y GI7:A00lKErx=2h,=#溽Ն ic#HK8M-ؓ@e) gHgsв! t9 "J;(,'[ ƳZWT Ia1w>yjctvf uS1 W ,/7waFţW=ۦ4 Swv vR4KOOOx,DwqVf =pa&whTȥBPjLnG}ӵ/s];mu5`0j=p@J0_~2uE59c\dOɷX}hʘ[&-36A! Y]ϟ?[% bcY2WM]Rji>SS'cDKqh3@<a qNJ,N4S05z>UKm|xEsuōOwy> B4aRW]]k.,n߁�7;taSUn8.P$r XE"ו K�y^ꥂf~cwMǦbxoIΧvsZ{Lnn}Qݿ3 )AJ!Z+ZUq]wk|b~q-xRG k]W"v!6'.Åޅ7.+UdrU|'PB.\"w BP &*pԋǍ~k!]w8F/ƕj̉- \`|\Ňw@{[+8j:GWDĮ~dA=u^P*y oӿ:/l�EU:?(* o?xQEZ'sgΫ'9bt![y avZ(fq^Մ{?kb^\C5Y$ |}k-zz$o F/B*,%oۯSEq/-^l^U~|Ջ]ln6x) ѹ?UaD^ߺ8K:zQ;Eb wbGw}t{uD_THeGD9Nʱ>Q'O'ԗyxB#HyP`m{?�;+}Eb &`EcB}EXUE=ubݟ|0zG aȶ"9mO)_K--"aގʞ^-߶D'WvS}9 M<:~Jxzjâ-w]WW~8-]h:|tWt˱Wapؖ~1 `DzGVm|0wBy9); Z^pmRe߉vD{cV]ߞ r$Ⱦ|v8־jZl/>@#?A4]:%be`J6lMb 5r DUFMm;m6\e _ Ps.[n߉掉6_THVC(jd[>} $W4`7f=jSOk# }I(mgPoݙB~iϦ)O�OZ&'QNŋb Z&?ݵі;C DN}'V2{uQ? J3&D1 s+tĐ*Á %Nu\z%]̂OQ�r(h0%Bd=KAŨӊFDbd>\t;FEWjm(FR盧Q =V[2z}oz׊| liJ(3S> rS3Gs 0G8Ei_NWW$ c&(D)f)@M Sv T`cN[jbY !3YJh wf`@^a֌A;Q/H|vP̢1LX피B wzfy9N}~^VEad! a mzQf3>gV{|%0nm'?f8 Z*juA +QMʻ!`Z]?kcS{/1}iCX<�457ճ p:J '`q9fwZFwvx%X=OiFcSҟT?i Het"D!mNK;4ޅ̦{a@h@-su?.U�( * e"���0dL:b#ofhYwpt yM/gMLBSLwceg(tϔ|⶯ 4a axl �$i:]nSg@0r)p4ߠNk9F'KeG`ìۏNuuÝY)0hӝ$TfJ0{E2GDTG& 4V 3{]nϳ1S�ng-{m`{VT;eZJ`x4kSFgОӰ`zpF賔n'`ƥ!i_e q`r˿4FK#JzA=0_ڲ(2.M2I6 FHo m; (nA.K~= 6PVW�B= +cI J+O nSC/ Hir첛Q̸ %h*A>_t^ж<Rǘ<okx^jlϧ:iEj稃L.fͲ4ouƝS4va)⬰Hm {^7j@ ^aA@kP1Y`&s7f|;4:|qEi#>Aױ'z;zt"+ v֮.*:ϕ&"?{Ro,z[`|  Il_$pdB=\Tr ۑS_TJ.r,HxtnuYYM'G:N:O O gNʦr},[֜X߳.rOw#zj)hzzB@kڡuEO< [u cnaAc[?-͹A]F hWt x1ic˹[9]}k-feqz<ZE=={_(\TPZN-S@kE{c }@_CWb/*|b:Z=ؕkzׅ[o] ]*ӱïE iO`1_ ]byaS aJ62݆.囤? Ӳ~C\v׿8j7< jEL.hp+ߗNk! `6mYyX,,"iԔ[wm>.+WBC%hԟV+=aV=iYozM&gw7ǠawL/FP?i[新5{Afh 7=yzDC+; K .zU¨NIа-ag~[ ]HK;Fn?bj-Hmxwy#ش ĮMu|C1u1ja `,ވ*PmT83bhԀj='&^ r6+9̼@(~v3F)U`)i V LɁG(̹xB똽Cb`` خ8g\(֡-tCU/W !4ih-Lni79Zy u#+37`wApgټ4Pkzú{^Fn6jx' ִRvӾ2m)3_4z1_׀٘V@&+?Nsyæe$S4@{}>($߁YfGM�fh/Y9}geBl :�eca+(h^&F�# QHpIVZ"~~a2@PHr=CBFўA˨7W0  02Xs+1zw‘U9rB<KK@0I`f7 ;1ׂ"RVKѥR=T^X*0QZS571!Ҡ<էۜ;MًqjN?ڽ6H5~$.;9&e+V3 d2LJ l &Ѧ0ĺW#0E:Fф1C#>9peG'߆Kkdh>99{|9 zڄX%[ 8fhxc+ڍ"Ӳ_V4fZ9 DC4fO]a `޽=$`Tݺ-z._$J@�N@mb�ܔgXN�04uw~c/G_/?Ȍ .N!Bitĥ/{)�(>Pm])Qp+ybgu'ɚV6lW?cۅ7RJ DAꪹ#?x?)|eCCk3t 2 ~ bo |^r4[Z`,0$ҺHJd,I3'I0Z?'l ɣ:I܁3z ?ѮJv$Ś-AE$4snn5-fN,FI`'zD4k [8;q/z\x2vm03bq 5=FNDϏ ;blޛgS88w{B|$umܵ5_c|ԈUp vMU ^!�yCk)ZΉwG $}uo5uNHɜᚖt @/M&˧&�;l5Mw+bQ*Jq#ń F= M�V$+0Rt5}<Dts''<HcMg>z:AIK:~f9Q5pY @TjKhD}^7B14~ )"b(xdEr%-.+u_u4oԂ#^☹'))fD1,uJA =z>S6b&2Wd<-zU157Ekzn:8he.чtnY a?_0;=Ǿ8XqRtd@،x 0}׳xWLό �A! @p8y;sLsґ9WjA-E?78ϾhTb"9TIt#=8ͪ+HUQ#F^򃻒.P?e|Kg=brF, �/$Xx/;gw>H$ H%$pk 7 ݵYiXf4FtY AA;UL� @׀ϔ:~)C.h&^eV^9>^={e=; H:q=KD[h�@@ A7{ /蹄)A\'RnsW׿3掚[x ;_Ԋ0~3'M`+ҹXkNkFr_k^;qz-9U'PD%"QQJ.!jis,Z-pY_ʰN7$Y I0{-Y( [I`%rf! 0+] 9i{Y5 SKM\}D޹sή?'8egWZnƗf)�s, W֕d`/6-梽hlG93𙒷[ӹ3DY/˯+{_lKL{z ]>, I#dI[^7J;!ɒp:W6a K]=|٥{;edQ|avJ׼D!)֙o5*Ԅv&~Θ76Bbuţ G+q'3ĚsWve~9BV5@_2͹D%,x kk#5sVˢ% [B"1KQuˑ]Px}40Fu_o'3pmYYƔrYZ U7هyh'ʿ|ʋ֢$,w"+_ns)Z&V;^pxM&y],+͵GkzЕ^dmOuQ9=~ =sF(Aޞ0y;3a|5 :Ê/_ʙ y!q}j[0.O >)Jąfy^?3k]OӔP+63,/nDyrj5]3aXjGsos&]qaFs5߄qvn t.؎6(?9oKK99WNm*}ַ{ pElƮG�X-镽^A$A2r Զ] &v/'×vm;[lxv{q}qJ,yƵqoB47RlBxŗ@6[܉քq Вr|֣s`1if.)]jL@ wQ(3L#)m)08>@LGO~9A/~n$2ro�2&NݵpR%?k[Coqd391לIk^oŻⷬ[g`$ٽ7! %AB˷kfn+xV`9>g:نNj^PlQQcJNTsbҸj2;n*/}4FW u�_ :!W8ˠ+! MΙ\,Mxwm:ޔ;/..g &I߄?~y7}H$'wޱ[w;'>4xlH>5tM~6X=_ϛ7*7U]3"FVTlꌝ1nmI3Ͼ�X64Pk3�|d1b{q jLP6a= ró ]FJpo\G.e ş& t<sA\mMꕜVA[iތ./Thz=?bW7Aw�9vù[�3)$p^sDS2xԜW>ss礛dι48'1Zɗ�XPP Kk1xTSs  X n/O$\ l;kw46ͭ-^qp%e46Wyl {JVu?{7�Nm�4B+`[Ƃfje&3ӟn3ävdjNS4 S52p}ς3c]1R ōW 䱟oA3&Д2aRƕҘM$] 7w[甔4GNM/_c FI uzTs4OW&xn:&d̟*@37%Ǭaw$AoT9@y7eA& <ū5/ ڪA\ (3Y.0&f%"sdU}ᡕCM6K6wm�Hsg%3+ 5= Tu$�ܡ'$yR9J:EH62e:0#Ԁ̦IsCF<�A @Is4glHCRHПa<n@\rzNY߾bA\B3|ZیEyZۚ3*e4'ȓftf^α8�!)c`�$Aޔ? 9Lf̫G; `s9wAPT&pۡWʜOtvaPLinz�|�0l(i#:Ȳz0� C ՁO4U# Ņӭ\g©_8|m[ 7{8oڲXݹ30y2sӻ]4XUn-ur-J/9]W1vA$u㰡ygAY6US]!Е`M,:1 w70{4:PQ rwo&MwK]C EPԳ]{j@? `Pja}hӭvN7ƶ˞lףI0 {vĴvMzԁnD-�Aܜm55=o,NXg',r= t+lm`8Z*k6a$ca%$e_ٰ74ˇ8̂0rϪS$H$0,34 ,[eHVtĉ9sY ˒q"`u|J.]^F{}/ <|㽝~1[yp ôu/J7*&ߡ-VV+tA*t C=fCn]fg1ٷ vigfqZ^70ڔmLnMpX3u_ nX+ƫ+1H-+; 2 �z ϚXk3*wx)| 9*z,ۚRqP"A�Q aƀPQ.YW\g^4Me=Y Nm_a,RULΊ\kTi]V~gŠ.YO3 GҥK:̆&| :9q �|V+w%CU{Ր?mM^Vھ-~<NG?O\mro3ٌ~k7JCS4KW]X)\\8gZqWⰼ>+1~7?66]/}ͳ^]^~^[,zgEWg񼥿GO?7?GgP>֑7_t0:秣úxE~%~5ܣj(^ gM~y5Вl}6D =B#ؾA`q,`w@ol^Qފ4{) foNdr(w3WN)t<ʛBR֛+axs3e'32O W"D4oV0? CC1N|| c7|λVB&W|֚߻2O-08y44){W_iD(3d]w~ww@MccBLփwh[~=xs WC_y lv|8,<g3g88C#=r釟Gxp7{;=W[Mp'0 BQfڝX}U.߹;!w-%?epG9?|KÛz?82\e`¿sϟx1?v' �nMwc! 7C;`o� akhn\X-Fxa$,1a|؝kl7 dGBJp?bxZ;QGH#>h#HJ()N87hPȑz:ɡ+<']["ͅ4,#_m 5BOBX;[}BLTP+;xN%x^~ k_ ^B( Y4Z-7>K<1 "Vάu^C4.!!4@(D#u c͆$ࠤ)µ|]'$NuJP*.at<褿^:Hkx"�Qź jb :vIA @=sus% :DKP@pc0@Unb;(v|.ǡCYq` e;)[x;uu�PbA@}]֥M1)c+q Smnu"w@)0U13�al)rukG �"xZn 8˸ȽX?Cϼ>hFh,I}тODhO{qigTO<c%3_J~Y2p}DOQ WLnOׇ'~0q-GJ<xv#3|'xHP_x/<G5^41IyGOOѣ`6dx>/.2<'M ??"zg<(E` ȃGx' I<qm|GR@:}/nhpҳBwzw7$'BZ)h 0[+;>!, VBҲ3W�G!`0Arq㚌  0z<$ Ip$a4Ot9$8#ס<M,k9cT+ہ1-FigII35Zg}HB4̾\`k69qAۃq x~g,?#RvƳ }}GzLX$�{]~7lJHz7J(kM$MրrҪh]},^0)RgbYU4y7rG3krAʴwCڐe{rʐ F^>\ψgI5$AJX8򺨵'N gv)H]CeX8_9@gb,@$0{'8@] $'y A@l;�`o?K> @уsY-� 瓘$кPGN<gͷ5Lˣ� P.!93'dM~h٣B~Z-g=]G=`%aw䤬ggle"Gz ҫjC<3W�rL6u%lى]~Vss2]+<�3p59Pe%f!qy%72`4WJ Fyhehޯ٭q�*Ydz#( wwB]ײ1kieLjq)+@ۻ[/*'VBOO[ DD1g q>1i @Z`�F#8`  YtBlH[= ˟-Gd!IN1 νJR@PpL錀#:,0L,�@hC( 4IH?+(6AP9#rM.9 YʆPNZ3x g\<Bh1̻AQV+PS/,@Y/nu.$ޓn L/jȅLi�x! tVB3f-;  \ 4NWl3|<%ag7$A'KqFL5�Y=0ϴ.p<΄U! ,-�A}$S� A(n$h TAu02tei+-qƀ! q2/*&04on#y,=]sƷIұ; �KAKhs֏ gC�S>Ϧ]t\bm< <AfѬs8*/^`_wԛy 0Vxs�<][O4)Hf`ZAgLG}㈀ugHGBx!%L$, }8@w?'g93.$�>s O.ݩC'w|KrD̶uD4SgdA~mO-G/ڵЭFN ߕ u5P $`]YkF�̍ļا''qa\54 7Q BT"G-3r?I揈>CGH>s5{W)�~R,B`ꑾV^āIEc/#}~z(Eq0cb*>_}&t5Pu4|8fe=g-V䂐E0U962m_?Ϛ^,=c5>BZ1-`I�q\nx+$Nso<;夣$gs :,) 9?@z�&ޙTB%`=셔,O<F\ G[`�Lm"YHGrmnƎE>l}"z( , c7y( %W 4?gV(N(Ch$ V@0 s4q0y7z%j,`RyyТ b):(D3Br˜clgI @/WɠI0nrg\5 c; |g+w 6A{|3g, R䲄6A;](μ3R ;-D?/ڟ033#8tҢO?:@H&$NH-l3H$|hJM3;X jQ̷V<9uLKCw'&�{HޗoCgBp΃4)5#oyqE.]Mv`(YI5Q5$ȶM�@8n{ZʶH8ꏶ|'Ůݕ :X CāИgі `�i8RM,< Дhiz0?CYo! "Y([֩6TYe$�—rYEcf{AD @P\ _nhm97N}U$�h]ndE|05* 4mY[hԾ`6= thhݮvd`ɰFF4 ߛuP~_r"҃(Dh`�C)!e  `4sRXdAE&�hQ$Z>%t|1g3_ϡt_Mn.?@P: PwLȬD@  5Ɇ^|}[0Xh4FJO0!]gO�3>1?� Bio@K-8&gqM1=Ab^`5 TҶg0V9<;ќaYEONg�3RgiG ]'gZa8#Y0S"@b\�d4ᘧS H0?BI� zf2Jtv(.rlMc,|7oF:FM'rC=g@hpmE tw |4Hp-u(ȓF.#F&CjmC(.Q ۂ Tc?w@gPV8g#bոV8?)FO67Y~K=`�WfLʂw%ĵ!ҙN@�L+-YGbcP�޷LmACC,~�l9K}�gz�I[; xE]/9:;{TAB0ңGExມ|rQ?&<p0z_`ح]m?]@8!p<Gվ nl` I-:A iЮn;"j!8T^߃%c`5R##03/߇=7S#Վ|J%#`%-79=Іݝ-) @9 6A@s6)67J( VB>c2=jtأGyg@X/K>oJf|Pr{籺|hWg| ķہɞ b٣eje͛׺[Zs,׽r_'$upy+ZQe/IxgYF6|$Ahܕţ͌׏/J-9/o>p:Xݝo9NO[[uDܯ=/Ev xΎX`AɦMW˹ߔr%-9e|G[4uzyֶ몂z<. 'l4.q6tD(^qAUS6@:(}߾vD8J;3]<S#{WFMv?H�QJ׬$� @[a.`_@e:z u˜#㳼l�&W8Yo6�Aݮ{ H}-d_H}/TW)`W?ذ Ynь~΁RvC߭P睳[chݯ{aKu.xk߄=^[4kw1nC`h=u/g{n?3>T(+6>D6Z9< ALqT_cӹ7p~6.oT z-dr.1߫Z=)9Zn.?Q(XW]~اn55fL9~fS y;S/V7VwOQ `pxJ& % -;Y<,�fe߈ 6~mkõ.":4>ج>t5 AwN�666WB|_y*KnmF.qrCbd{˿ꢿ‹uia}u �7AR=̽yLu_]l D *C `]N:|?M661E6Y :"y/ mݟFI< $m>^_w8mcI�fĥ­u %w[[@O^Jkz<�OoۯRnŵ4 hZx<aPգwªw"y3o>\߽XwC͍|z+ Bޝ@GSuܥa䭑y4kwkFw,:֟ |7ZN<nq~Pn`-*un'G-m<w+üЗFyi`/!+[q }H\oĠ]c=\'GI ǂu`ŭ dܦ?`=g>X{L{̟yu1ɿ>U  Yo|k pkeƽ;wigt|V>K *%Gtwl�++.&=l/24({ d!]c|s_d2_*+x{\эXZ|5z\ S؇ *cx7$L4Yy?9ϑs\t9<ܟ#P9�Fe0ÒoK~ Q\Y(jb�& Z|0t[k ؁ �&1YjBo<ڂ hlW @/W!�A&l<p/5h$ wݴ,Ȃ9Ƃ2bXwAr D.35<-9lrC~".hǖAYf+')/#wAyx F]Mvhj @@d�s6(Gh N-hI {pܑTYEg$2U~s< L`irC֬(My$}А/ 4. `Uf YW�p# 7�,�:y �Ă3L@8N(40 2q=t0[��sNd/؃;pweå#=O@ z?^X�߅j{k i1a6Og=,H��x؀ TvM)jJo |-P'v7gdYA5<}%ڱ0017_KW`-�pGv$D1a ? @Ν-S4{Vv0brI�ZZi=qZM0Fa48WOx]LJ�hw*cq''h'@ZqWHT^jz K$*KP/'Ɓ8 iWn Lēb`k8xBO�ۓ^JCv$$D )'L#{x( FB w6@]DZh˫YDOU $n>w{I$ A0㽬'-(:*4&aJWa|'� vE1PV;{Ej$rf7np5.R9UX'6S @ "+ߤkN*X-�lzHG9eڟyO?t-#̪M-T"�%g5yMfJEN|>#xt uPGB' <Ln< 3";$7RF!'7&c:\ &5IM $$Vc5^ #qB-9BH$͠l/DMCk�'H&Z/Rlsqͤ["q"'w4mm2ٗ]mxJWM( :f햀 "FkkJH]\׶{j99s534y^PA bk<0楔z"@>{<>ŷgiXba2FC965\7CU�cS -@D*yFJ: 6| h t�h0tA;�\}$2ux7"U(c,jਣGZc޷&c9sW�.`;Ջxc�]la`PD2\UufQjmCQw9@GhׄZ} ?\{c= @\�ĄQIh7vҴ x� �D]u RZ\\DL0HUZsbŹ fLhHMNwp~MGI;obF߲]85sv~c@QZJ\V: 襟zk%w8JzWMSV'oL/ )E�~RJ:ֱ�c`*V^w,Jx47VZoE:fY|o7",1-E'Ԏ1ZL.)gTKRLyIkOq_b:`j$nW );Ć6fPhO.oгK|vʶJDnέt,]w_ q"B7e^Q/_9)z}\w<%S% LH1r]$]J?~|͝+\OOox"|~IA&-8c|8oh׺t;3)O;?h'qevF,Y#qa^;<Qf.G'E 4ZOyQ>/ E}.hARx~^ s[$EV- bɋtϿ.$z1<&-Ѕ2f.c :AqqL#w|bB1gqd[لhDi,.\Li�2�=-bϘy^'Zkl^:Bc=&^� ! &;(NxޛZc[qP?拯En$w˜(/h-E?ts!9.ϊш^&dbD}a4}]*/ zbQ>2 hqIAu�w6 ]�dz9l-m d.I WA4SǼ F )y@(=c?MQ犪,ҊXѦ̔-R zNzZضHɄ_T)^S�b �YJL +tkI7ϣ +ԉS=}QD>ci%<Ut%+��%I9@'3�pU&7' c QP(Lӧ)6(ֽiqB!Ls]!*@bXaܒ2UD>ʎ f6Ք2+]�E:Q* #7�)oOR'(uJ rN(/:9IJ/FRV%<Za'G.Z׎>/Y)uyX4C@;u{}<Θ&&#W`3gqmғzCc.H>Ӑ5p1d )Uj< C FafP^Z adZUTA,3)ɠ+X|5N} .c& K C3 t{ } F״Jd`$�Ú63! ff$�jLn^R3.hfM ]LK)J[Ў =KPDžtxz6sRIqT@X34UJPwWƏ jV@HFOnhF3� Pjv#921S挝qy)ϸ3fAPI@fgH22b0̐t�N8p #$28۳hfe&HY&pQS_ USx'?wF� E&�AG۫4_#^%^ :T(vQd3fAWGϠ&HGxu;pZt{h@M�([ęU-1mCzG4H?aFXDftHsj~71cBFxꆞ MЍXDDnlvm,U @$Bta`m vA=aX=`h*<Oh m~D3ߩ,wnY3nd2b'rD5@hҌ #a�l1t=RߙKC#Pj&{n)wdL[`ĬU),Gxeet.K8Y>#U58C1ًn6A1Fo罈6 ѰeLPVh4��xy�#Λpv֨˵Dp$y,jC {4 VŝЈczഭ4u9}n˚VaQ5TwjQ<v^#nЩo&r{[DV5!,EcWEk1Y)6ehTP_h۴k<Lмkh�7il*)um�z NVxÆnNpy!vx'GsmUw0e�W<t|uP骯7F[yR#; I@w$m{?&-=-\4U<�Y7d<;#:J ;9! 4w_Ϳ0 V9 / ^Kk8j麎[c|)=WfX8oN;01TkdJ:{JGEg xY[G7g�qڙ>5fMQ 8[> ֍)5(vp+8fx2l_]\\s<�-P�h Y5ek:Z ˘ t 5Ƀ."x~rg k (E hڴ;QPx"2*Ek.ۍ)=8^kX0=P9!HA'g]@pfCzu ::Z= :Jp6c/x'?<t0yy氚T5湎!x2;O%t>8NUA&Ԡ}c=#X zerz@֧*@ C[n7|'#>�Y'`WxC;c(hcǪ S `�VT<=1UpvGg8&-Zk�-׆ O6#渞Gqi^RVB7]:#Eo!qq\P3⛛ogެdLݎ J  I1ە_c GEOVg [U[:"Ɋ pL_Vs<Vm l"yG71S5 (bk(N%E kA R S)r Y}} 6\A5�͕G7>(Uj-P;YyƜ[Έ g t%k^Mjތ7W衒pwbʀUq=m:-S˅6]G7]+{A-��&v. 58@k[݌- vˀSRQɪ-? A朂 C!+şp;/ ˻?t#,]?̹`f>kuAz2b oĿ RʂZ(??Qp!UhOP0#w,kͿKZ? _[4l6r<_?w@F"M, @k{2=طaƳN4s{~_!?GtŸ-`V SpK=}ģA *a8 wnaJ+"h`h.N+A0FӼʀFyjF1ȉwb1vX-#gF0އPu$@j6.A<[ 9JFDa jnw0O<ܯ)˃NH1(V'@:([O] ) v-Ax!OPu r/p FY" A=Aj v΀@ W䶀`Ղ 8( @ @22†(CM2iU YC`gl @`�]]O jKB9\�l"jT6ࡾ &`~(jy@B[Kx }} fjs\ΊPC| u7tb.5"YSQ~ AVBABG<VY5=l�SEMiH彬#8�}FP@bc|�|' P{ /ʡ|FH4X=]@]ݏ'7/ �q pգ.�UO2�F\ 8j< ]  O/C݂6w)}"+A`i;z',x(@YJ3.P 99�Ab�F"QCV9_%`!f:n[Wpͫ\􀓚os0sX :roi Ƹ *V4jUp!#WK4K�J-|F*d�GP"h{dGI4ԊAX_f=6 t\wR\ EoD`"E`@zP`I 2k0_uoB�XS$L;y+IG'T}z?hUu *'w$A^R "%5+$;`5@`#ɡ#bXs1i&^G^ݗʞyEIқXB ! #p¯$🡱ĬofzGVޝP%vyli5^MIt% �A_(+!;}r~=+pBIZO酮H⾧&iN|Ol-I>f+qlNlwiM��߉Ø4ѳޒ&½N׮-=4'$ `ibFYPJ}qhoKrҎ$#}I9.,`I:$;l%ۚDwuBHM;$yII"X#f@i(Fq7ФI&ɢ_r@xXozw{D} Kjk#{4Q[sP@fm祚&iEQ+K]Ns&S$r}Dm( %&MR(֞_NM,1^k<e3Љ7J0z$2Ea$QSvjncq'M:H/Ig"gugjm $<TMFiWe5 o ~Z� 8qěJu1�LNo.l:P(OQ"1 b^Pn&SΉiT+[vJjW7j�uEVPU <u|wa`a@Dxf!:FHY98#CPۘQwMH 9sm)<aDyG'YU3G-Tf AUM02%0 A $̫Iڅv/3w624jBT,e Ձe>+.O2;n:Yޚ耢caOV@ޢحT sblc.l%Aw%8;Q@ .[3mh![s9/0{dp pޙK;;hf\I `DB5<2 J$juszna@H_-$j~ugUp@nsgB��AI#%΂t4'3BBs6T40w @P"W/)2MIREˊNcR\n�ɔ1e.:X�qJZ?ehHXߘb8)Er](1B_ǼXa'zy Da1z^u>JYr,4_:0&uJYxa*b |+kdR+)tNvb9Z7%>F—Dh̕e>e2>VR&³ RHBtJZcnR$%] =cҘ ްƦo)ptȧ$ש+?eVz*|J|o_'7ңuoaۅ6{ d{\9/�/h1p\XEM^X1Bǐqrg#"_IG%'1xvwrhFWK/ؤɻpݩ,{i&3W۠ -=W&�coGy*šb(Xz}̜�+t{?=/-R$t\L^ԫ }ۮOF&.16a|"Nc҄:.iMg1zB&&aނ8]ӣ҄?_T%aLR"cP_~Hn-1h(} ژ 5l"ZЎFFƥEqtDۅ=cJ)C8*j3lZt?ya<=qs_׭ky+D~=Ey't֘�yͣ%^㔉Tlh1|([g0rHDtB"''8cn_LIs-;j&nhCMOO26 k?&jQ}~QA˶>3ߙRXPteHi?)< *|ONm�af<I)2+nJA\ $52%F~&JI)$OTD)tf~Ǧ y'Eݥ)qE%<yhy*R!)^S ꥮƒB*@^d)2#y*:?չHO6^bH/b8ERҍ]V'b4%(* (Oq)露S!OJOʜVffu"1>)oM|ɢXϥ{['ߐ6/xIWGENIJ=Z.^oo,DL_oqS;t{QO;eMY-Iqʂa&ԩ锯S)i& ˈ*qBRʅ}>eՒWu".)]͘S)CCVq[m{܆ x..Sw u1EjLVm @K'SyKj8ݚnW2V3q!eąAO%霡 Lxl�Ӈ3~JyOHD_ v)鱛*1�Xt!*$<(a&iJ�<j sxL-唗t*JF>jp<f t3i('#ewF<l%R#)f�xO7)trtJm% \v{Е2bo5CjP27$/.S[>#=gԡcTGx锢IK)3 qB›; HgP7UJ$�Arcyn)E EH#mf$Ari|Dldo n)p6i4lffYm\]p"3v7n2� DC~7"�DFlK|E0zfnh ֌#Z$qn]ш b6H aeOo};"qF �ݞk=<-FX3Rw!foDq͸`|!<#hH-.XF6IFл;k<A|L1 2/ipS@: ussDT-u\Nw+V fRp+/.<|zWa9@Bܕlyt{# o5b\8x~D֝++wM 令{m"TuMom\ m§0kjQ-q̉iCl*u+mwecSɲNctT;!J8NH'ށzgЮi黼Ӽ@K]Eo睈3JF$(6`1'Ӓ!r:yxZ^˹@S6 5F5 D5r͕kZ7~VwyZpJ#/Z[U:j+߮ fGiQ/N=dwﴒ9ARc+ ԧ$^4TN1(s9@3 Σ6[Ձs㚮; oKETw,p>0bdaAP9ȼ0,:BP#@L[)L']9j3K;2l@`wpq=Fk^=׆FV}Tx(<8<~g ="֬`N!\ϲ?Pu]?�P g' "@W;N6+sQ\=ptc8�ጦV#UpxZ�aP04MwWA01]+npV9521plx�i5 C=4)cʋ3>#;ȅ �gUO^J\<g]=ँ{jOO7DE( -<]8msWl p�.xh( N<*7-:U:}H �=7[ p�{]xyWaOUeo 1H wAV@�oLUAǂ2 WgɗÀN <K:'0g# @(PJkc7@�uی\ch+ksrь]1 CЉ:ǥϖuFKEE3�vݫ:vyY6yBx@ /-~圳w]lY/�:30VtwzvV7h~v: ~vK£;k;TrКןwE7I:oA 6i3rK|Wgzmz~ ZU�xǖ WE\F Hշ=[ D*"jztv =D:� T}J$h?NP<Aʰi'8$LGɨfuYgtmsk?,b9XjSm3k+Mpb?Qkul7]mb'}k=4MFV0VX<ahP(w]{Noug�=7s<fD+aƜsKG ̣ q|iΧ  |z$`nTǷFY.':Tӏr@}[@ﻱ_wޭޥ$5MڈۼAo;*dP䆍-aook|,NCju^f=X*os{_G?N|cweF HoΝˀ7}:fj;md J"UI <k'4B}ۂR'# w%�UF=.èw|#{�JQ|"5 d0-FoaLp9/c|A&-ܻ_64;0wWYҰ:?8src}b +`B{1j<os4ț6kͥ칠͜jzZFF(A.A!m,@Vƪ`1ۭF;r[|Wpa$+ w@P@y<a$TzX %bҧ@lU  6~ A�\u&NAP)ҵ`M* *!j.UTwҒDCP/K�`37±� *>MLIВ :%�A AP˒[]bՐtd? q/| p@Nb?|Ó _@9dIld^X HEI"_N`W"Z'q^;<zĥ> e!̜XN GB" D?&XhK`՝bs{,Z՚k@�g"E`*<,b:HMt12$_M+HcHH4Q^/aNU0VaULqf$L,���IDAT `wYFus{;.<{ ׬@K۪RX4\Wf8rIpr`\(CPJ 2fJ; ʯ.Xi40Uzc#hw%$ ]ɉ9:]|d9P&aY|U4RZVK]XwuǍg\}dYԀ5NmI `>]mC[^r#s,PnB`%�AC80P "AE#* dxtp(㭮eE:\^fه\iVt@ܑG$p!$kJIO򸟤pA`h\D\;r\�:X򛉦^I~׼s$1MğK�f"~ᨙYqv2j ѡҒ?@ɮt;$$J +Do1'<T&v]*'$'no5p{^z4{]O>?F^70ϠWpL<A8'| $` ~49]^ 'irjOf>3.mmйg[@=S0CRk\佦'�|I 5�k$<"$y,sMH <DGD %A ]Uˎo#o�wkK jՎf".j�y&qpEL|hrˀăM`$H1VF-R֚&y'y ( |sk+J$!3NMiM&K/6I[DhAf4IRmD5mo: *jbM"&tIZKMi7.nt.+U8i&%.y�@xЛK-!` /wǎN] @S|UZ6~Cŭ[D,y[-oHP};10K"pGZsWSRZ6q&Oj"#D *Jo;o=#"QK1 l挋b$h�$ݖPT0t馗$!q:\sY2p3#BIANĥ߽݂lI{!ϗo 99jA>SժeTw/8h)M m'wb2NXdrC8͎ɢq`5uu{ }0)`:LLM+J{i5pN gZ̀M±t~@kjp'"hdy>NL%\Ĝ(Awo8(>݆UhtQ'shPnI# EP{MRFyΧAfc. ~-<8NZq"He ~SͫJDU\&~PZH1\"c(ueH agڪ8Y2v?7t$Qͽ8L3(΃MJA(y|gQ*1yȧ1i*kGBXbL'ɔyK0LK(EuJM._%R>/0iNhSKKd>KS$EyEiLyҤrA2صI|l$NU7)oZ<\&g%m-CF͝+b%~54&]17{hhv"Z.]1iu1(y!YO|y^kʜNɛbǼ<M ,S&8 #.)h!%SŊd%)t9q,,>9%NMOUc^/J*1]ltQ$8QˣޥДty"T$c_AwdZ0Jɢl$8h8x=&^S$G=6Lb� =c_�bǽtE\{g>FV|_'c#Ů{OMw^K1sk3y_:/^gǜ_ãJIn,<@c\Q_TGǤOMp>uON/ �-.>YIǵqo{\&b<6a?Dbb|镉 \FE>qBs14Q:Kc(?.É"Ƥ|C>1V;F1mܴċˏ#߻|LDǥtldpaV̏6I&//o?1S qi\H_q ZՁG(8+R!<Q# {/Z ZǓc\׎^L^dȏ%a|tz\TȸUʗԱqBzfE")ij-UJ/~#OyJOuoݪ tx<V${J?l?eNRf*SCJb.JS֥G&c? (N9y䮌DE:%O䔟*y5vS]RʥO'-�'AqytF|q褘^L d\ q<2_dUD9J8] Եcš( 4* 9)S'w P:ҀUg_'wO?R!+nVHf"%T8R y A@Ʃ)�Z&<l"�/~b[9o<[J�t1`8e:'a5x%1O%'롓je<'\͔t*=Aҏ ~fI?uy%E'[M>iAK_{ivT>hڭԵA!=d$:8*1x&a/I鶔њ")e>^ɤ3ڝU:J,t<kJFNISɠҖ*=ތQ^VA1sJ5(3#_IpSOmUIܝ1QHAQM�%Vfz{3CHi><6ؓJIFuP� [ E*p=#̨r̠.ip 5@Lw`2n:mIxJߨԤS-k$mLOqxŸOg IfXV:=xJo72~^DA2bfAV+ ԵDFJ 2<:EPs$T]IgOU3#8(*:|A%$3-CH_XzV(5g$wHR7M鑗=ݤFҾQ DQ= ˴;#NWXd1ڭsi8vDS: Pz9X +˷_oR|*T=|[23i['1ŔKwX7Gj:-s[:toh*<+*'=mvUmlM��t᮰!q~CTcӢk9sR`v78V4Ǻ:)DӹcP`ELjíI||t=mu3  I#H<9AΧ P=%raԭb7%=-nO(zsnڡ?-f|#c51LXQ7A֮?J]�91k55D^5i+Z{%->f x;O_ppPN!TYȹsW~1YUa6Ym,Źwq.ЙvCxr0?r0#XN@>ZN84Xq-wmsםIE'AիvT\e hG fܐrQ]Un{liKew^фY>Jsu5*x 1N+rȜF{TvlsL゛/e9rě~~gYA�9KK8#�_z\sItm85'Ņ*]V @_W#:n1 /p6خu)HCK3T#`eM4@@4t:o�TԀ:M�Gn.G$*7NL]EKsor*Ѕ; tY˘,-˽IkUpdq8:(BPc݊ 96]8O^=@{!y'Z;tç0F[d)UfVqAVpt5,qK/k-.[=�4S:�` &vdpTp*g *R@c-%͙�ae i�Vr�\^'9pzga|DO;n^l͙�| o// sq଎v9l$;..Y"(lMU�iA7ZΉTe.:M@�� |>sݘ�Af˯:�:Q haA~( d[_q5%3z5v7@:7/S`~jի~jYhI_2N*(5@p*|{wYj s�HL� 6{(;Bu:lu-�fxҬ\Tgbnӻo_qlN<㩇nw h[߲3P c{m1N<m�w\ v= �6SD7#g�)"�{Jy;%W*s ?Bh^]p %J.<!{D.FwsWY M7fjR-ceI@UQg^Z7ޚp >*F }W.77[U?F�鼃W*n8 Q�vP{KZ>{ (W%Ac#;+桥%Cgf EQ7cdp*s6H&rs騪n2_1`> ْ+r4q\�TUb6s0Q\YU|Y;nnRh]teVlNTJAi\OvWiq{BfPRꤿB^TC@jOpwgjE`m?#Ÿ?Gyտ76|sW1܉|zJ8(F9w`,?xCIPp6_hOy�_aQǜ@lV x;d[F<0σ2,=@/nxr>S apÓL-ǨbNp%0|'s ^#w8ήw?ZP#./| uu/6{^.M"Y 1ŃOpW -Z6+Jfsׂl) I(62jug�w'@X4DH]1 O G,t-r'O᷂ieg!RaDwT ܵ:PA9A Ν0|N;N[8}4X:96##X.b||3aDH4W2 drq'; (47Xp~vX y'[Xs.9|MO"HAOw y}'̎k.؇aQB5r[kj* Q~Z;eI7@`zw mmK!}vB߁[/ۂ8އ#r'@L0L,�VP52׫Z1pZZi@`c8j:l AZ*jZUii0U} 8\yе~,0ʬL&\TCm! ^fvdU,i[OEft |mWPT$-q'$#K"r,=Pܩ]pEgzAK~ Mwdz,4]z [?Ő9sN|}sbU,P p6:%}iOk7pJ#l!.+X+VD 4:fOӵt?';ԥ/J{`Uy3�fb$D<Ն3Eew �(I200a>X `?z&~5XB˨!IS15Wq1XUpd+ȯPЂHHBۙ\~WH{PiVO�A5N[^xxg|ςoP؅ҽ$Jf3!Ί&JS2p.ǴC&sh*zO#( @JK_.ʗv, _Y:80ֹ^";6$0Q'=G6L?r'O%B7[> -vx$INI BcFپ*'dĘnMbC^PbNmT]{?D:vQ$0 &L�* tHi(.%dނ'c۲&e 3L+&;iEfw+UD4)I>@XM*iUt}yW\zՏąFe?VcI~É\^1gb\7X!f#nYAUSO/ˡ#{F\U#→ý 5ʴ}sIUf՝l$I \(!T?lM_]s&_Ƥq\ uԚ'&ղ#_㫡pdgl:b:xERv1ݔyLCͭ6h`b,,jʞ1a-} D JЏƚBhsW3&Έ[%)MfG{_]ݗ5|(v ʥ7Ili%mi*oىX2~)%Qɴ- hձE^v _DkxҜ-b'ޣ4yfܼ{o^da(hQxˠ3MΧ,(X*[Nݗ~cS='т->ټOB ZK`9Mͭ[&sCIC|~IiI%Y=Q㴉38c"eKڿOlڛN/( (8$K w3t ёl(WزULU{hNGSt:}Bѫ{L)=첓 = wt(˨܀5޸c:sNW˩KFC9TV+c )W0޴-᪍$gӭXj,`䣪1`H x "6%ܓbA0›NSug%]=J˟\x*SS2b2MoKoir�i#m#J <ngٿ0)ΩAknmN!{/?y=&4ݺ$8FIi,IRJ蜙(gqp7*kKa3�I`!�u')UBZv:|o}njF>Id!g*$NǴ4-ÝYv'teo̊6f9'><i]yo2=SlU*ħ8'/1kR] q49%ȸ?&]/ Vd{)4$VȜ}u^E.KyqVR۔4u}Aő ^܆5_&|_*cRLOted"wY ǍFtL<>%]K0%Rzʛ9 %:&u"[qi9vtJ)q;%ђDq2mb"";$/bb4)36+58WƕqqnuYJzA|oi%qJʎ*rK/Z<rIl.SҤ5ɯd}ج4Z#clⱢ>O}cNb65%ΥǤ5 =eZ]%y29Qѻk”:q`ο*ۥa@IL^3.}}NF )]KO:vMGҜ0+_|I:&߅`*Kcyh2~1>2.sv\ĵ8΋g΋?\^Ջȯcܘ8< B<9AFSw{Ru;Vlu0m-�@֘Iz^\l.hz4!Z]؝%xn\ LFQkG&ȹ߉cqqko[K|\}1q4}A�(;/ F1ms^Ҕt^</>}R\[ď%x{ .o;ΛE>vl47]'ǥYQm3M@0}|i]Mbro[y~u:/#? `-KQ=?ϼw"pmq;efqб~yſ }ȚQg|j픕xO^|U!/N:f:<TrqCdrܜ rp%/ SOi'?=.20&J/bܟ‹=St:TIQ)io3S9%DƟwL]ImMyʗN)Sʼx;?5YWC*VTN$LDO~}\1- ^I++Ft\:)v㒘 )r{qH!ODu(ʏ/T�K~)7lxR6>Rd{ Z K )#~~ďsh:=(K?yXQN(oBR?JK+S*uJ?Ne^?'*F.gBRB.IwASK]K| -gb(ީrzu+?^9ȩ¥yҹ,'Ǭ;)PGW;y+*I)!8f7Cq!}1VŎ|;1y3RJLU4(d8((--fҭ)op2#fx)I% jyPRe܉`FS1c ~/=qDW#%'3b̘iS`l3G|:b:>eoRJtn#YLTmJwkTxSC=mev=e>kP8EU֮oJfPL?}7ܙT�j:DV%ӞZ֞3R:] Igߒ;#zGNylPܙ3 \S2#ȇM·o*rړ!h: y ؛B:y^}>v}{PǡA1$A*9KkPĕ{?sn~'~3]ie0ƠNAk~?M_O `C_[x*Çz +PG{ 'n}枧 նC dg֌n$#f!vG2E%|7x qOg̴eW$#GH>h'a~?i%l9~x[ʘ ,3n:(êZElj.g$</(Ma}PfOߖ"mەljt_GWv\S", =<Χ}do?qxZz[2V^䱿w1t['JsŸIJzHi0aMcUE�aS;}z%=[ fѰm�r*`w{aŸ뾶{'xIx;a/C'V=^jGhfoI֮/}IcEI|/⤯(ꄭ\ QMjI6V͂]<C'ioi_3vWIOa:͎*g upAUg̱&ҊkUuN#8lIX s$<˓7Vdjz,x:T{Ūe~'6NAqF0]sNwE;L=?W&K֙VYtťDSڂsi욳4y7EԲ ݭqaZoݎJI)A6نj/_ Wh˝7O)UaN;a_x䃰;Y٫!zHbUiδ)v}G|Y&'cFr=/Vӎ,ۑ:vBy6�ͽUtrcsA`堳 ;Ne U}5ՙ SNco]ۖݽZi�6k4 f)Y#ǘ=u4(xDZ{fv PܭToA; Q<r�h! ~p%z2g } Q׷îaj2HLmi�,ә4 �HJeF P˹=5pV\sZ6V:J7ߴ^#Ŭ57Do`dW9Q{d^mJg C_5c` rw8V9ޜd )\<zN? \!SsDg7/9݋aĥMVƃ4o:*ȼV2TuOEä5x6q�׮VyPts::t겛bjV׆FQM+]?�8o1OQI';zK �Ծss.t`$Pf2u+U>]~�EFU$7JA�Ivלv�0 $A|4e$zwKo^){3mgxUq )�AP9d в.Mx@wb˹9/tͫ*wWj4HC^r>|Bg+/99}>l L/Q~5d0/Sc/@drkd�[ZuvΧa UC)+]uc˚ӍFno͆_n6)fl'H_�{uEMzLLc`9`i9|puw,N`^Aw,#Xinn. 777q]}@u.@՗tܘ*|wK7�u62W*>3W?k9igO26:\0[8em8i2&S_+s֭]pp9)mYx|̈́_חĆ$έ(@ߝ2jnJeouWP 4@"jW*ɛ?>)7:p.Œ07amQpUS- ȀLy<�Z Py5p{fgjϻJrܵ 0ZK, ZUQry{ՊHC9eȕHAijA9:llX{7|}Z󃈶y'~]ˀ;CN$?_-w#>`'1 fYt}KWDY#BJ6G`aw62#!ܑ8<BݝWneX1(HUc4>n8nnmj'o?o0l*l۰W+linlӄ>8$o\[tp@\ܹTX3 \P%̝w=svc`HWJYkV?V"xڷQ /CpYz2r Zt�Ϻ\{tl0A6`9/uƃ|q7/Ql(ںx:6R s;~qeY˹9+HSfQ |W@U I#ѱ#SGu^6φcdT<d& "wwH!XykVQF8k1�,2`;Iu`rpȈ'�V"'xQ,nBXD~@0p'D %BW,nõMnGWe4x’\k#}KHI y3S0W-؉eVD5e0u)qx ޅ�Zz!NȋЏC&RDDu_ʍfǁؐہ^B6 ,v;)b3AI]-`|BI`Eo~O瘓&HrGPA. @퀀FA0*d3$�e Gpj<R$M�0W 0|.PR:ABL(q�X99+BkKb|tAְ"5f#]ã tHj_!L#l`3l%(8 =kTmDQ1VG?Dl*|OXaEqE\+|E"8r12|WP; X/(4ZXjv g ׬GTk �u;kl,kkOUwj]7:�jU?4GJcS 5OURXTQ{Pc�2U�Z@m,u,3@`#Xn pY_1H 6|l(l! 1 Rs LVxD 0ˆqS xV6YJ�knKܖP|EJoj@̍K~Fe*M(ߋh=*_<<<G?~eEF{[8^^F Iú0&d!\WoSxL>ACi(1�H m9Ʈ1+1@ VaIcWI"WWQE7֖I|U-}б$ĝx'p=/|ⵕO`8?(_ 3w�hKh D2>P%PYlauGQ$9 "9!a1b#ͅOHjt|Ywr$X#iUc*p>A#S =ua|d^g?#T2@ ˉ~6 KW1� �ceaetߪ(<+~8*8 h`�i�$ҲG 닆�]AE"R}r|OŋjҖ= 䳋'V *b ~e�H*Ek߉6%C,,8_W  tq=�:w=H =GnOEx�t_l=Gާ\Tr1}tY?5שM wais(v̤I 㦙of)o9pݴ,Y4M+pfyY42aCngc t\0Y0?obD”̗ʟae8 [T\ Bk5n^ x%zݤqG]m_J*ۇA`@P �YrtH�g@n0 OɚZ9&jWa6hBi?xt,H�$@ ƧNx2><MhZl G&}u0?Ead) ''S+F_{G"H ?5҄h4p>@dUq%Yu.)qwthLJڄ6 r:io ?x:pzD[=7 m<re.t,{5o9'+BHOKDIdqrjߟZ-Ěbax|ڟa/^z`8&�A}PdoծOQ`;U߼~ s^$(H0 Wrޟ繒+ R?P?T<l^~%W-O@ Q╯\a( ~x߂rRL,p-l/>c_o933yg&cǧg 3_+:Ac8zt8V[X;1UXm<AZ^5땾^etlm $O 6_[PbWִTkWve+~M'|c#WW;REWa%u_|MY:%[]UWD/Z[|= H:8§y'5Ga Q�b _!,g՗wR'旧h t֟>Cms`e![5Tf.MeRM,(HbQn p^2؜bZ%VAgUWs4eJsd;Sg呗sj/+Ts|IΩԀgթ!dM#I"Or 4 F\p|[ap @vQjƭˁѶ*2-OƕBX/JLO/1ѱvx'x06.v}|$'c@%~+W2xUH~__/lZ8ѿٗJ{GK{/>K`:+�~(|lABb8u; 0>ϛi){hIȭ@h}*VXjP{V[Ѐā z)?@~*.L m XjW ،2ǍA*)pi۰rM#F4t1~;A`HTbe153GʓsRhf.>L˗9BG99dOPeF)G*d'SL@FEeQ5a8Hqd J i-N[ <S8R\C-߫cOtSDꟸ*/^5}R*J".,K!5~KƥR&ܝJvR x'2Z;2w0>5(~w+=ףW+kgCp�A|d/" A #s1 m-�Rh V6?w1M  ϏMRDQ{/jS U@` **cK &7S)הwSlB~CFgbO7S+7&ͯoo(_5)x777v7\UZ)-''^z}kBubfFtN}ZJcP n\E:>< L^}̉Qn9!u<&N._OʮRBWO1k#OyKR20JU3婧b߿#O|bpR釢>{SӓI^Po{fx?P/=m @OÓf `4߬ }@0W�bR8.yG̀i/@~éMq} hS( >8wq9\wan0g,`RSKdzBJ@uMd'//S1"Mep9`qHz9'OB:d1}Q9/.͉A=/f:h0dcNrɽo*7'^4S0 Ah X3\@�1bSt|bO. �E"L<3[ΡsO`k £!|#B֌Z+4> ->[}cWS׮%_|蕜yeʏC-೼>G}~S ʿ+d/0€uFщ $gp^ܶ,�߲|d1I۶ݲ>ש=n5;7E{/"e?>5yo WeP{<[a><8|l|p9Qpmg.-7At ^\xs*%AbJ[`-$6-X\0-r+ &Ęȷo}9H̦hR [XFk[1 *#H+- ڋ.; �^p;o :v|E Bk O#bG-X׵vתz.rn {'w*oO.SXc·'6S]wI|=Dk,)Kǀ76O1,<(A}5 ñe9Wx,tzϒ␺R=260lj-{j;0ǎ@@l§SqHl%9�[@P|�7|T=Z tN} Kp%7xH("B1+hzL3^Ԍ;7FH`�A ̉?`#`'CxzpWbWLspK*4'3A ґun@'" *VUW(]ssnkB[G �&QJO%?ߡJ|6E?mx%V(Bsk,%(<a~=ىwžosA<CT~v)|%`r{`I)c/>^C0L}T #!}IoQ s ֤ztbxQaLStߵO]<qtm>}*Geٱ>i{iE"g% G M,RZvWbmXo(�Ȫk 3ĺ Q4a=XP&"(&j1xWg⫭20@FQ$?.T/:>1/]kpj3~:nb[߂)NJwﻱ|5; 갹, ҡ'|Ymx lvof;NBV9N(H&wS5kJ.z<b~>A޿H= /CJ.y_1˷W>gQ|O-.eW8  #VfBm8dtkcƨFIcBM(?Iqc=gFG 5N�gIvzMyܧ>meij8@0-6X< 8\N/ 8w˲}Bd� ^L`ٲa]57d,^ y?368dxhq1LTv$ȿ6&~tҤ;euF/,9qRT~6- B*ԇ )zb;"_:"3 y8ʡa(;^gTvrcw˒))@OҏMmm3Z_r&QMoЀg}o<c?9vcNןXx^t;hv-p җ \ `qhvpicRac5~mHא9B]t:3k\xs3ǯ Ba<g?08g?.aeXz]^ }aFY1֤~GWYط/{!6%\`< /| ߎ}})1\Ry|3Q.kbJ+%og fbtbi o³O!0ùYṘ_Zb}gs2F_7Wƾ 8WMӘ?%�1 (n\[�fPn^K_\hr6Cw6u�p#uj; ^o(^CJpz: '=kET]�_HC-$/\<'yl'e36TJv8jf(ͭ'2qڡiJ!o_tOe3걆aF.*tl] d?}rg+f,l\2kEW,OX73C;eMцz eօy<3ީ=g+(pbg {UJ?:߬w:bo=2+ƾ<`< &#~)Xאb ]CZp3Exׯ6T6e1p}@_mMu.0z]3=Y :Zah,)n)K)iN:+J=9E,yk?MI=Nhuqt_( Sfgȭ~i1ۊbQ,JSvE,D\e9ePh1B1ҐACslf)*ؐvՄ6Ra$Ə4aWpmxc6~^WW*p? ꭗ_i3ٽ;XY&jR@(%/Yp/΀g# E_q*zV>C .h=B _U(H CJQ�n@ah AR0:8 ge ׉�F ZQeY8M # wJYAي :.>:^ *wVPC=[c&cW ^"Z'.hIFǧC]<5ZWm t}yc:s%`zN5cw|X=FzėV@W,CS'`-y+;(Yiy"Oh Y"vR1zH6zx"ۄ Xc; `-5C`RZ%_Ū |>e.ML3`,q!PǩԌa)mq<:d@`ق`} ͣ- u`Pw s:Vb( d( 𶄉@ &ٓM oălrM:!\TOphVemoŰ- 4uk1ɀWĆ`ψKO@3f3<HOD >OyO,508:FnCo-\>}ţ+s)O�yAdN["l^1`IHDU  Ɗ- c6b<έ*R/H�`{ )Cj1,mX [Dn|+!G<>�%�!mõX[4Z;|+ * v3*G&% ԤxBjCΊwc)UU:a(j{Pz8$նwπU~ӡz;6!j=!ؠW&W XCӼ6)/q|u+dFj^fHdve!zL1fZP:�{ˣt혥e ǀ l0Ӂ 6)vL HLXR Bhq+ P0~W x^+AdiLbR5iet*P?-%₝ JTOMR2ikxF Y &!m31k?hFu6ux#nCjAeh&2Fi#6 d62@1COrA�/bYF0 %jdK] P@҅xdO0kSkG0^TNH_*UhVSu>pW޷^VtsLfGҋL+@|5K O ;0Xn1bFq4JRg1½83"iLv>S(}<B %359iN0`4:RCfTJY|k�Y$lh~.iJVq1U#m MfaߌQ=a9z}ҶnbK ԋR-A ЀЃ\f1 ֋=YS'>JTECƐNiPZP* H'ˇ(4-uEqH ҶbB^_y"pf=lH,c}c}3J0/ʱKcO(<R񅮅'|Kr8^ٷ 'ڲV /ɔvDiQJmpSR'|�\4LݚUcjLe#@i6X`Nyղ�K�.9&:zikSbZNQnLm3ʛJ'*q ]JjOc)߿B?5 =qc.`/Sa\`u6RMYh=˳EjXViЭg0z匴z=xLMX^XsMOٗ֋d*E1a޴4ux) )\*)°~A]~ #1 K-<P"Üeb,Jxn[Z6)ܒ m!�9 <] u_3b&)SR@ yHl�FX߂T k+do��Ai54޻bVUX%krT-e{Ӄm#VzɼFW!/&ośT bp)"C2c?Nd,t{ !;m3˛}9Ԟ-ɚ&oh{C`xǀXזB lA;3[2Ў >ЈCM$x\&iB!۱pzCc}  ͋fځ+fjq2s'Cj˖l*Ro[x !\Fz#p juCs.usp{0,ǛM{Q 2VX0 Q=PjkRpa,=5m("oRdupOH)[,1#G�&0(� 8FJO apcmӗH �&e ϐV]Ŗ3薲yDO5iK-o)� GW-maX qFi؊NQR g&0ۺl(Km*p҈P֓UC)kfKG�( �JL0|2r>:"d0T ׯZ%9}}z;z@pgDJ~S!fWY4߇SF~o j/^~!5?7R.R8T8@ zVV%@ j(�Q@I]j'4A("DqM' pG�9F(P0vS2�$@U))̚ ��@A^�A (,'^#E]c>*@քzCo k{fKiRmfBa�0K5QҼ<^Y< fògmNiPЛ!Ԡ,֡&1XRl@[�A\l�~~!м<,>|ݩ:]c[EX山1WAV9nt@'- |K}"_HK') ޗ%,UӅsMZ0�@wyb !ZGre'�uX•GQL ,u A"C�vZx?m@.^tM>`(gSy& io3z}rX�yG46<؍D{YK bf}x!=F O& Ozxg"q"lv$= il} �Κ߂<-nz.VcL$V|a m7 zD^ֱ{EdKR+qq~8٘iKڢ@gI`&5&^OԨ]LVr~-ܻ\8 u)~!C*M\0j'mΙ#=X?8˙<5�," 0P&o 1@, @4.x0imQs= xqżQ+PRt\ @{ JAnAPn}3cAÝ\"OBenL!@[c8)@6e۳NSnfl' ќ(/ߢh=7 KU^nW<vn[SZrW4T4ȹ`?_ \wnn9lHb禦d|] ^Zy q 74 `�^WRGq~gȶ D" 遈H@4r8 TDs�&yuH(`wADNCm@J;l9 : Un>L:4�˜ �m&|Jp6 QN(QD:"�ŏN `z# fleQ;%AD(4{cF `/6^!@m! *wv7uDLgL&(!�/wp+m> ^?<6I#_o-Z Xu@94?b�KSS,nl fkzS|.jB>*#bt eºݙܗ.MA8HXop; /Etv!4u`~*l>)} o*@R: X 0ޢ> t(kplg٥pۘP?aTA; M;Oo�}Qn�+r~E(�8C �0e� x?JJKlt@`Ѷ,sףY)5Yw)[�PMRixOX‘lĎU llGvr;!1F ;rxc,},Y0\YxN;ߠ_vj;1{<;5;|,e}m}WZ1c^`weEa6E@$0mH討(v,܅a!6e-ȃgb4pzex&Fv f&A*f(6>|i eQKal9*r ZdZW5鋫ٙŌn̶ƳJ6S!!zX#ĭaG�4+W TRkm{^_ZDTc YL�RWgY±* @nX M6;ԙE裗*A}lgy%5TUv"{箍HW3M6f \geRFe!KKX?Fw9>ꅒEW"Ë["5\'/<<`q?p`wVb@(B/P`د[o[9lGӽ!~cQV"m*,0vg;sP uN%h DGCn9hρ㿨r_,"Ζ{f=yע'%KdgYJ-&:ypkh_.H ~9N3_k܉RD̤d0#밎}&ibTB "zR&�_~TCͲ`O|:q,'x n,uldGk#.e`X,jT߷<&`2a-qUǎ!!,YlÉt^+ H䢭Dg7|؟QkIzhpex<^R# 9e *j-�3fjCE5[7[xEჍ np<ӞeIhQL.QOŹ?GX\F7Jrx(*XU嫜B 53 &Jj5À[.eІ�u贓YG.$_e}VW*XZg}hQn9HqCw6ZVif lT:|VIT_WJt/bUNTTJL1FU0|ty䙢pmjҩI\R}<fv󳞵PY&̨dn2㈝,%Mݠ˶`+H-VPmf؈qDB=\Eϓ"#-;d FQ#z)b<рRl#E?U`*0Jf <&>R0tG+VWVVЈAŶT*eBP'C D]w Z"UT5[!ݖ=Y{@4}јC>ߊm�&\#KJ-@ KF ښެ59FنU XI:7& =ݏDF# k�*[m)o&k4 5A AQ,9TFL|GX^U֯;F% W‰S$ ё)@m+<y[lC` h@R 8\{J[E7`$` "϶I\>ܔyUw[Aj9ȓ{b t@("iS{A[Vv2JyT)ajbp 5pSjT %nǹñnkF;p5o6#Ȣ \%0ҹ=%|QU=ׁ89Ag{~ Ez?(S^TUڵ!'C�dm^d-+L u60_Uq-SBmA);"azwm/!_|"{LieSC8t!5FgPG t$T. q] ҁy`Ff 'D٬4rBs\Fh!^ jFV+XQP---ZsC\ xZ?\R)(Cz!||q ͂:df B1}!^2k{,&2 xR5,iZPZ3t`-݀l^9|<S%̼ !W+KLm=cm!}!1$ <<YF ^F{Hl֤.�8hy%"5kt+o<Zzgv+ ci`WYy U4 a zs&'xE#ISy0^}ЈpF2XvTbCtς@u1OsrrAU.;ˎ(bam ȗbhQseϜ`lYHEq r\nvر҃Vj^ͦt0yˢ` *GN7D)֓ʗ(5biKsaSuf7gԂ d+Q N2(ҋ&P�jpeVpV8 [yÀ2qRF@>7~+p2G9XEcБ8:=Pțl_>R�Cs*K1^H:S^j$z#fQ8LQ|E3&@)bXyZl!oO{3bnrJ/< ՔSY6bOLxc.+U5 3Q /C! O]|i*qXϛf xNM{tk2 K)ˉB ˊ},KL1%<=OrHTjҲG|oJkFf</4WSƴQ稧93` c "&%Dau< | S‚b,KzaA5=sOʐsGjESeS)x9ggw.ol8C9/4 tWcL e{ ̻AOV*u{ins5`8<i`:tAg>9恁kɭ o:mم߂$:%VX 8/rX�F+V �-9f\Dto/poQj'lNHtfmǤhvkrQElJ10}o{B-]A%,"Bb oj)׫ʞ +~֊0؃||MJqSw* !݊Ҿ�Ay^l='Po9}憻?*֪'kc φ6ZMJ:O`!Í+{τ0/A)iAnA % ȑ60ɝTDn9 o) ׀gk/w'px4d$,9V`=&LC <%{�G_y�z["UWE6V|<�[BxXA+W=zXf@�k\^mjFv j[*46zFTnl.0cS l^N*EK�[j E Ȅ[k`ƽ7PX#ok. vǶj\EZ HK]~(An)PW�A6m4Zx vvp= � d ;ޔ).ÉMޚxs-��V@V<Ll#{ ܂x^ h $l9D] Rh Aiq(B.v@(Ta1R JKlI?<&@|�H/hu﹒ IMh@ :QB&Wlq�A x[E`5[j3/@ma s( <w*k}[[{e0B?Nu/@05 5&MMcIg4Ѥ`-X9Hp@5+en�VV9]RYr%q�. +M^:Eum)@yz V7eOBM% ڑVl+ܨ k@8ei<Vҩ@I&+^@[/m&q4HCP_otxU+fGt'oϻ>t݃=}=ix]?,z7D"{@@ XўzwNèˇ.[ab@@s VAR� wB{/^\\º+c'ügG&X ڱ( -x<z]I,!y x <|;C͉=FwgT<T.@˺w"v'lJۍ-n~KFe u'҇w+ݹnPrwwWbaqsU=yM߯wZBAYBky@nDSoO{raF >\rw;/DM2g=h1z 1',>byŲYviЭCy@ n)v ΀waI{ 0^+C2s-=YP� `\q?pu �6yf[ 9pu8h q[:PH 7IV]d[G+q yzy4;~@2 #׹A6PI-{ B}>aTg. @SNo}RTg)w!ۡWȗ.A[]Jp)ڤi?H<u-+Ћg`z՘{�wFri!h-^<(4(pVߏѺaU9$\*NXs)h׀, IG*[��騄>1g~SF0(�@@AY? R} ձ.!j� } 3hzRB+KJchZԀ[�4q|H٦ `@pC* FJ]0v K}HO&4Bƽ!e°ph �Q,@`SPkVI Wm0. ahqA/̓v X=2Ԑ@^Z+ҬO>uYN9ġiӾY2ƅ\$0<JtaK"F pDI`t@#; xs37�dP :rPsX8 k.PYIJA@A|: sAdd`�L4(?\"6ꄱ^CئTp( bz<(دQ gy 5M}g8H1;0B/_Y Ee��*.Ɓj&0 ,+M\b!hjn!D1gignY-<mo <[gk� B; hB7XT>dژ,0G< fj/)%jabvIW6FQW^P?ps4@Ա+ *^ym坊b6 fZ_R1GTVyc;'ĥ05AaHZ f I}Cј)̕%և^xa�cH݂jWg6%0kFᒕ�&Ϟ1ژW0߰U[)>% ffuk&mc X[VI)<`bc~6fРߚWXB`%p9NUiK;V banb{ $06ìZN7B"ftz/l`&F.B?7w8mزg%%Ǭx fdONg9 ;@yІ}s9hwľ& h75OFZa& `G]:iA럺2D~�>77mPCL+!@kQv?S;e�l,:?Etd> o餝 IHc}Ae6tjn3}w\_ڿ̨^V4qw.쫒QWf<Fd-�꠯%kcP*<Id|ф-oP3~r\ aYC"m}pEy-�RuP׍H\rGrreIrD,c;P V�-C=*Av%w,Bm) y-(P; [HJbu�:!0~ۭ �DiA f`daOfX+B DgBДNtĿ_<z1cPH#]GdaB POKòx<!ׯcP'ԽOG5 Kj ey*RY.؊*p*:ZA1h2ɯګacJ0P|GFG^O'^mA&nVڍ@eleԣr� eoStt JRĐCbFZD7�ʪ.T^4d2.hm \GֻAP(wPnNgO U=Y/=S_(�Ͻ%G L#8 Fg"zR׭ȑT6JRg_>$QR+9,oD5ML3w@PU'Q S[ vm-rQU0ΚB0+]*TKS[܊mam כAD#9ѤU؈,SUʦ[J<nC4)Qۍ"-&('Ъmqۯ*55>>q O�E{,&xJZ3bިnAUŕImP^WqװQ?[悐,r|mĚqhp*<Poy[{V#VEzo=ޤM 5f[bao)!>+3|nBP\U[iZs3[? 2*#$܄'qZ0. �60ԼeZkX >l�kIV-ER=FX 8:̴C-SAmGS$4)oOF$gR0mj`bO@jamTH{0 iۏ P cx;0OTwFan[HT[y֪Gg]@  Ԫyzt?<<6 r|@C'>w=�mu6eZ^ HPC|2C5 yPX`Uf־Rl0se^v0"c)6ȀR#ϵp퀄$kۋu<?RCRʇzF TA  J>k _g@ Q}^QvzdWXְ*gEK~q}+㷴0M!&1Ο*,+*Z9  K 8nZ\R ~agNӅW3:暱xF+%gnl &.g\U1?se̽l!Wtzh {$5 VS <9�[v (X 26-xX A3#ɌH2mLiCb~ݛ9t Y2q@2>_kRzF"0R$* #f/5w/. !weŲ& LfuiRF{ӆ)@X0=H6V -k yXwQ٣J.kc'Ui $RAXQ : LݹB&`%t&g f^c73,i/+NPfyXYtԌQ>ܣQtեg4PZYnJ ?)V _fϫN`eM1GfG^~ؼRB\󤐷RF)րA|Ϡ_oBXY#JYZXEH2g)?Qrux6w$ $Kv0{Q'#8�Se.KжBٕ<Hlh e*Ƙџ3-W$M b#r3TM[/CFz3՘<]Qg9? ^jG={[zvУu4SM^0ҝU8Ƶ3GtvK0G灤y\bI?{Aΰ%4և/+&Q݁z`Ă|9>^Э2!/˪u56ZI̩S|:n�Ta 83eTHL]W>CSD?E-u9ScWf9+<599e[Yխ&fTȃBͣ)NQ^0K5:MB;2h  ]Ҏ)1R2ĸZ F+lX)=9n7)9^ }Ì5^8G&[s2n#DǠQ٭I]���IDATlm;X|e)9c z,aNXxe78 o+� j:W2gY=hh|IBZQǽfr\muxM@>،B&|mooһ ,Yd3*nOk7nx`|O3me; pd6úJ<vyX}=%�CvV�܅r+Ȫ hRB&⓰9kb>/ѠSq^="" 79Ck~ ]LpOVOA JJ}muS\m A9$|!껷a/>Ol z=h\5΁_i\MDzql?m۟WsC(ށGj_]=؊m~mb|X/U0 P(7snzknd)ws- ~,&ZA{OA@@Z17AaQ-tdyrUA*x0lW!oe3Vo@AdYtKtD󪺳IyxrOoIoPX j(Px` y⭮>q9 Q�VF~֍'X=zk?9:ٚiru/wUG=) snD=Z O m4RjrVU6G> v 0$lrqk]o 2Zƫh9] e!9ҁs`_n;# (6XJm|fݘ"r@e`ӉG2V@Vt_iY@A)5bњzK4홛:yy/mǚ̓0 > $D [EK-C&ěF0H_7FҚE{@Pj&7h4*`&|Gj*(y $Ɩ^R\ B'{�O}585W[=,0 -RE[QZ^4m*Z^'đEɚ�0$%/5'@%Nʊsž r7C N쭝`ƿŭٱb<DVgnS! f7[u<*-jerSesa8hI2{ O@9DśfSIשF[Z Y oںF S8 )_:>Oy\빣G?}Wc݆?ݣkw35 x]&Vn1af^ 8̽D+ww=F{DGׂۼ{nlw lMܥߩu':|mtͰw=g]szrcnn#v\Op -nMՓ=/>/av?MV5=Aa[f .{<�rXKԻ�݃M{]=Q޻UaWgοݩ\'kzw /j#N5AGWۉlBn?+ǭDw2anݟH{L] \�ʹ/Tf0`=?~f8O:|9(=%�%<Q}%H,\93iyrU@RjII^�FA8$1x tMc cTpF'c ,,O|>;} HkKzR:5�EUGrcH@9<-0@&?C,u|lۨ %$NIȷLWXCIWꣃ5^ A< 2pWzR ֒HO:~sΫeQ~pAtz2K:gK0'1jEQWj6#VvP`YN'A0D>mנ>*ɑ~'o%Ś*%u*s6zpo}j2uU/~g y6,BJ(Z:jʰD'%uсRc<MO?G6#�6IF'8(Q�x ^ :`,A7FxA@ߣ>ejwiJL#kϤt o<B`pTA萐2<%\`P~5�p^1X"R�7R;@)Ѝ,oX2E rsŠ+Ap٫&:YdTO [X3 Ȱ<,XR]a29c�$ W>x:52T9\&gq"�OPK0}\?9 ӱWfAMMO9�ʵe99 `D"Dsy2:Q&%О� =: U{{ٔd:Uc 2Ԕ bm�1" SBA:'qт@P:6, [G μ9 CP1KSKMR,@TKo2'@hHN#w EWg@&'g# ٬HC^Bش !SzF pB@{>JDn : 3D @&P�KR.8`u)ȳdZ<i qJX2Iɝs>3.woBCe%\<,ÄN�bL~ĴtšEh6f[Vĉ0R5{':Cow@0X*$ޜݳ~*̏TkLf/Llfv&flX".PQX֬řX1vJ٘>\R%>f-l5T�QmJ3柀TGG5a+̋U*1}nl%u^Y>MEIݠbIY(>SQ/ _XR{d(u+] 턵v9fnPZ@+SFq,./mCmb]=f1I+=*S֚ vV=}@Sef/m R6͙M:F�%Xݴ~&]K^6Xc+K 1gbcha^EG�`uyjIͼaEjZʍXIs>A\' X&3{F%'nlD$ޥ 3-z<iW;b_i#[ [Cnm~~ƻDZN9^VtV�Fxg/.6Jiq3lold }aǭφB$;ON4swX?HwBvjN{[ϬaX}>QbvĬ63e?@@Go`_GE>j볙NwN[{k6G-RxDv4>*^H(Fh E"XyG3nblX߉\e@kl=rȂu.ၴf_F1}/ُsNP UdRX?w�X.͢m1юΡ:APKc߀-c7hUD܃ Dcl/.]K m*PFQ]26Ta<#,h!zAn\0b !d�rr*{+E|euMvu]V [dՓQ2XB6.[]bN d@"..85sx# �񺷃tʣ%|nVa; %ޠ0J(2Aܲ8IzҁjB_ptzjf�# ٜ:n/ LX<gU OCNͷw=\3q3ۃġ8g/){�w9Š_*,J' _E: f?¬#Z?3ǁѫuєw_1&Il@Ote:,`K ֱ66?" 2 30 }zcZ͝TQϼ|CJ[ p1ke4B<U=9SYꍘ'XԖ"]\'Dz&mmTk$4 EV5ʼ̫<UWp)fl͊{͓psq޿9OJ*{~!6yATFnSUAum[j;FO nj<H$vOk^ `@Fl_h~q{31ʹdpj뭐Ox}[79q<TWInm*Sffx|g3Z?pTե[σ+Hq--S{KYIyF6AͯBc4xZ[?ݺW惵S!nǨdQۊ [~XOj !{a�A1!1>w=:Z:<[:K#@NUZwZB{TjU5|r/dEՎ|+/dU8kUM?B%tU GoNpٷnvvp㗃p ھ`)x:q,mP?;ሗxTj26}4Uɖy�jü|!c{G\n߳}O;pZnIfJ;KvsO -COW1nos}^>z`COdp5"os` H[@B Hh�}T֚J�@�xP:h^A�`j|{blێa{me',{I%'+F &ŤMn9SҧfF j$3e20 #k]dfpHp^Isd WIrek&;1e < nyʽuW[Թ)5t3Z^=Yi|^+7&ϫ湴fOp'W \PM;P;ka(oȡ<2IK]`sZ8/ ǜȌ>::sjL_8*mwY͜d:f>.I-M5ùe0JB~gT3f!vᓍ3hy=%$:htu`>5zz}P0 6]AtixPϲ1#oUmwo^z|_@=ENȣT2yS#Ɋr_M281_I=Vbaնs9GhX̜|<Wzp>3A*̩= ܙtO\~}zi6]i 3wR3G)Jӆa+QҠI&gN<RlF$gTKVNQ5iپ|} g_" +tq)V:`=q'H98BֶdwtABtO 0wΗ@'hI䏮ͼ9r^i%9KnbK͋ĘItG]i/Xg͹$?,xa CK?KL '߳|DG(R|et%dW*i'_UHqS#UrQGWR&b/y~V)ߨ+/I9wѺ& T5rG/+Ӟ LQWG%03nm `cNgYbUcUZ/s`k sOl~xZ{djM `5Vƌ6 ͯG}{^Ɣv"p XƔG=%o �iey{=3\~4QW̻m]pw; aFW:ekFǀ#K6NXCށu7jA}kO{K=X Q-LjD56}s գ32b %z5+^o5nΨѥH0sc{ݬP),K'|ry|ʆq# 6I඲L_ Ty[;B <4Byu?N0lm ǽqWP[0tv3]|-dnHNWwj=e>U,P�k~s .ٷJV] {k=]NzF &a=l8I aW4bliE yU6lU%BOF[U@.}ox{^,ȫA8؎m8Êk[ޓSMy¯q{\(1 7@`j/6eGg0A? Oaܾ7<֔:t@#!ݠ󥇥3@A<} ?SnihS{j{^UjjdO`M{ߨx ҷ!}7ψpsx[գ^?Tܼ<f$`=^LszKDMmV=o)pq;06o� ksx/\գ�+nx _FFΪ[z}0ı5ýCܥ-4n!x:Z'j]ݨ[A00 썸9scZ))o*FhwӍhmuosjR)6�Jw}ք:ByG^[g27Fja]m{QxIq{A\m7VqUJ\U/ dDh-:2M”O(F` TK#ɚ'%5)i^fOy&k|KY fF_mR-@l]XRn.YfQ_M Jh9-4. Ӯ? p_QN4iK(H˚Fϫ쁒 Sӿr%NKe}ET[1M [聓a>8 +cKGqcNm^{so|�Z+i=ޜغ_H|Rd薂aQb[)ܟRn>MmC_@+#�ȍ�VɍxxS+ L99T9H84D@Y #QYK(LO­ӫ uUXB6+qF#- ͠T3-L F ˣXI?A؎VGީgVkBX8|Ozcճs >&;D`o܇1zUu0[ۺZj"+w7on=;ՄuNiKXRwab(hw&DAJG}<v-�~{<@FٝC?8k֣*6j{oo;݃wCۼ tn`nӻ\qOީn~}o3S yWNh 1(yFwQ@jSKGՖw*ݦ7챚VoM]_ѡTO{"J;9z'޿<:_vOՃg&ė}mܿw�RMZc7'~ST .Cu5HapXz5VLq4J:Ѻc,)e'NVwb:tUy J gS3j<RαT])v/s:(?$:P*eOne2I$ XB[򘇎?E7Z<B 81㫕OG9Xsk<E<kc L!ԽaP=,P @qs<VK#T>_uziO jz OS?uTAY^#�Vߧ,=TJA�9O*qaaT2=IE鸣W{�Mt�}4^7o<E(zL}[C�AMRZ ɜߣ8e(4Oͳ6D =rna<yclC)_γbe!8TQT܅1:Z9 SNp7c,`嗨d<ɈC`9}\k@˧9,$ XLf{: NRA :&4NPΕQvˮl]I#ȡ<pzS6JJQ/,O ]R }St't#1JrT8:@o 2)ǭM8)"}TM]tL>oP$6T =_>|y.)(}gN=.[N:Q>tWYE8AJ B7+&+Y܆kg @7ߎ$2":g-sv17䝐]rŕ _0F]5@O|u1 ('JD36u D%]- W*�b\?KI pA6 o'@be(ƁA$2)=3YPVGGW#ԛhRCh)dp^ в2y/EeY [^�Vg +6+bIzdʄVK42zV=RWV2%p5b`0�h?$Kjp]6f#�AY8l}[2a')}x 6.V zsֺT(/LlIY5拊37e?gb�-){47*fb9ʵ;:C?U(q-󎮖ƈ|fwo\ -2P>=eX@ԭ,yt.Cr<W:ܢ)̢~ꟀEYQvZ2GԗF $5Ouؼ: ]6>!=6f?Exbl+v/$gkkb%XL?^t/CaTP@m?zs7 L &EK)7ˊ%Ȅ[6_(X;>w(YX[ l*Ld%yK ?4Wi#ϡM^ `1*7\k˱̵ckd^]6 M1ՙNm'͘Ŕ#-|A~-=iHEf{d 6<cI�9(^ol(-} n&6 i\tl 6;{? X)H'}Z?EyY?i�{a[ٷ~$2>3oȟYR`xR 6?rɱP+vfO5|+J;5Hn>bKϒ[vˋֻrjd* v"J�hCިiG) dmAm7k! .t0``Lkk�<md;۱8%#|TGN+E}CJyyO):}pTq,,Ԡ][6ĘW\wzmjBt4y0͊C|h nv yVtw*0z:ŀWh]sLubE;!0 q`Q:϶el4cE g A8ҏZsF,>ǵJ0Ә6Oͳm ^|kixDS͗~Cf߃-0G*esW܋#ӪIJɏ~qqxyi@ }BlN/AWfJJ,>]:QMG\tn]W-U99slLhN0O{ 1ۺ۽bϽ;(ɘ"2qú; v_UpA}E~;gqX(: #AgxW�w dpS~;1> �El! $��~ -1 Ay  _+_:tq⣷,cQWb;P FX# nѓ+}!ƫZ3c |Z_=¤lFʟ +VxB#8CEaaõe)VOU_mm( MnNKIϸKKTOR)-}dž\5駏.UurSG}5`˼Wwt 4;^PE'-/ @ @kɢ]a5(Aᘟ 3eI#(ӀO\dvW;QΚORzOD_&L^`q?Z(!Ɇ axG`!% hW'VS )߅ <I 'Fm+OX|IkFHxGGkvxN@w7 �qAIWcpk=%K<w[-C4ju(nn1ȇp_c0\\5lՂ#JZbdbg/,uۦvڷV~Ƕ7wmo%x$̷)gvW,*{=5Gc5⦫ WM-K" eb 5LeAS_�(0(@]Xt hܬ-0n&iֵ|eOU͘& BSupe@1(ҺZ5Y5X+Zope0Ӝ$jWf$:!'(cMqtEM4{]�OqhAF]) |)/UN] j3s[|xP�@27 n5~jމ!5:e#6& ʜ2}|yqrA}CXy=yi~iK.哨oԷլ՚2Eu/NgM̒y^jtCٔ1{P| XO=h<h$͉q]?͍OZ1Sxukx,j8'YA#XR߹|{96=/<VrlAYFRٜ5f[ \c8y +ixxNyN+9izȱVs[/,X9YJфظoVǞ ϒ72p%?>r<2NƵ�6/\v<p='srY5}6h"2ųzo2&{<Ib?\Mg\56W}Rp}u0nxbCɱgIN>=|O@%I y^6"7ICC9\eQQ v!^QxMFٓ@OϨgzœOf-.1`g4:_ȼZ瑃YK7o6r*?deT5b�%}9y96t˿u9^:R92W9uYο+~p{NZkc`Xj>gL4x(AqxZzzն'x $JP4&^Гϱ`R]6i<|ϒI`|kY"og<{={m<7N`:fEe56~h<Ո2N%?l> `EsϲsىPD}/j1im9sgI1kg]}. ߞ  M17Izo;g ,.O7Ϫ]}[L OjVc1hΜjlF)&y `⚩<cY^ѿzOɿ urt`xz\?7, Fu攩O/G&f\gNuhF-/skӋ׀JJѬuz6j־3jW[sIt='? <6P#odF@0%;S1Eot$N@7& yMƷ7&<ˏ|*룓*KlL@b/�7ʤ[:/xSt|8I' t>^\&#M>x^+79; OơB�'cRi]sx``B ')Cɉ|<z =v,^Pr2#4%ɫPR P^]b �֕0|kp;ʚs7Sq]gϫa^j4~ԜO~}#]ljO^akxzv^OĹ<ZUvo{h^.{蘉nm|&n/Y=pnԽlվl妚?Fqh|V'aG:[!24#iX# nF:Bo�>CRIy"I@7RUO= ߌHϨi?Jq@pe`"t.rTJ=唖b)kz3&�p9p R3vQROdx&"ʔj:ə0T?ХL@)yHȤ .r&8ChFJIkRgv T{ |K=-D/05<Rlov<-4WChԎf?Trwkq_ y`!4Ns9Ys?~皽 k{ۣ~/C7!5_l~motPUC'h~`7b[+|F]7(}Ǘ}5]SQ6~ga.ܾmdͶfD1A1L :@f'|ß !>v.m -?0_ߑ5ΫDd|.`>n|[H/~4REi^�VM<0b?%;'P)D|玜Q>M .G<U`1Q }j@ѿ¥H^LԚ@Xo{ͅ_"(ze\_}5xw 'ڲӽܤTo"徲ZWݕ{QL/&VXImW/ɦ<'X%Q<UVE }j>x>ݻt5zdJ| #v9X+R*{)[:>Ԓ{=Փ/6ﭾroeMV{zLO|C{>bPQRK j?C֢~/CVC�Ix �:_lo!v qmZcܐ_'5#�@BG\^? H \@)ޞVcQl|5Gw(- ___)�o^𴷗}|U$A߄+(Qq%ߞ_qӞblZ&|y:29j~rS;}a|z}t=Rx?~{:& t Y;~JJn0?wߥ~@=o~ -{vW'zF?zNLH7y+vUkgU-\wzº;Cs'Ou]DX_ӫ{.rk!n. >wێ 0�@vansAq,�4w!e%!g¿$*?sD`<�, aԮ|G=}TAW7ڲR#*]4Vq?x-f+9ArG,Q<;0uƝA#(ǟkNW=A5E^LPwz:YvV򱧏ֿk|߾ѻ4<&PbJ#n..s',TYb/bKzts{V2YWJQ E&,ֲtr/j>*7+hjt>%8Z=R@9GE՘3{s9gi lsqwMdUmn>]Wbmn'uSEio$LЌ^;A$CNSHXbSk7DeC`XXFZ(pp("(3*Mrp~9??c=bW!G+]"KsM׀JfDʎ[@fвIȅZFcТZv*bY خ&iO^ Uj`i.'`Ŋm %uY˭xb p%jŜ97 \qcKv[VCNIR}"K2P~V `'VR +ViurA@3\ jdDʏURNgCՆΩL hk7 ;l?(/-nj P\G*+wԘs;% 87� gP9u]U*j�ľWG㪭}:êN*;pә[oy/v|nHE[sXzڅN3Ui�;*wcٚMd RJqZepD1z9i;\YZzۦ#lZ6wիӬ 5VmU1p8 g@~ ;iVh-g qkWY͊[NzÜ'hõ,mG6ԱUru涂y:6\V ȩJm(#t93˙zĭ8 Eav'Z=7\VZ&Yp+2̗ݺ j d7*ɟ9ű=-龋q\D7.n;i~j7*�M{whz�-ܦ7ҶzY9?A{;g _[(zwab|41Vqm:]�(BP_/F"Yuj"$Mt,V/rN_r�aEHapoHMBbr}/qT(�P+θ?b'r1:gq6rܭ+ 8<we F 3O*jqSЀ SCɻPP o:P#(/$@!o,^W 3+gץS6d)R]k`hOF=yCu)W.Cʟ{]:vb^"Kx:9aNJcu2N0g|3zo/8GaNMԌsjԽh2:C^1~|NIԴƫW1tկfW/;ƋR!|d<S(Xfc:E9aɺ971afo+~ YŖI`|]g/nF i_dqT$f&1x)-oRa@r:zH_e3eu[s w`UN"ԲPO dx`=tN@HQ6g*( -sERq_W ~S^,Pe } NP.ж;@r{}VI8Z7Zv: ? 4ömv}R]0�.�|oFWs+{W|lYj$}~4 |&>ODsV]هwɾ-{%`e\+oK'+گ'�1<$7WI>0r�ŔG>Γ n97xǜɛ'xǺaNuKXKI?GhѓT'#HCO�*ul2Z}(aSҾiJZ8 =Gq4QǛvo&8B8g4xF�m=wiG= 7^dЪX> � X"U8 юe9&@}tp/@s+[Vtf ܓaMQF`2iOnT MĂ_lZ$0|7A<5) :u8GD{Xܔk_Ƞ}9.gwsC a_XA/x2n[O{CP:=’<5aϡ�"b&fr3gKēmt^Pl8&oM37?K ܍ ҼHwA?h4Di2m蛻"i^dZk{}qNW -]d"IS^�J4x N@$XBF<wڋ>qbC7$�J51ql%IhcAJ;_^h?�m~<k~l&]vn+U*CoApFRU kA9"5qWXx(>\N!܏!lng27uaf`DÈkĻǓ1CSO{p;}*ݛ Їe - �P61LЙL[d4ޔT*|Tޗf c\}d\J#y_ Ϯ aIIyɅnqb@?^X)lUZ08O�ҬBV=D& ˖tk{DePd;+Q<]Ko+CxA @Wqdƌh0y˃v7) @K0WinZ +7Xsw'7M2lQbÌ'lBS%ju:: df`ާ/Gqa7!^|ӘgݬYs_(q3o 0"Wq> ;:SgnoHѓ)caXYe)+R'=.ۀ3tKC)'`D#`oXo^$5A\2nP6y2@6]\_e=y1 \ׂh 5ʅg[aEyѯq .b\Xb_eː'"erv\CTa5&DPB9Z\ HCvyYZ  喍1h3(޲grW) EҰZ*kQYJhžRZ"/vr[,7g >Ģ|-SZ{RDLSC* W@Y1C#ט]/2RX,|lawbp(ۅxIΜ saE˴Ejn_ edi׈,H {(n'pFVa-I<l{BQ%G3_b/9R1wf( }W~Yy@0/RF" GݸgOݗ2Ҩ=~)vr4 $(?"w e_)1-/)KuR[PXnG u?qr-2ݲJ⩮ͼS3"/cGFcrg%?(uiw^/vA*^ydT~Ys9QRb1+KjA>UEN&$wo%#[ˉN_qxR]q*wM9^VFe5]Q#ҡB#rhεv#RB1pch=*?GqrKD]|Ź: Υ^=<9zV9T7mZ%f1YhG&_㨜q~I-0Q+)jg J nїv>[Y(wz@1#2F1rLr3Nΰ鏦5zlϥF" v/ĻI[UzL<+w %Q:#b)eh-?]A-`\]"Ǣ|dďMqdc=j˰,J|Z9PI~d:Y|qhRct"j1r,6rWbWF'!d4d 1/?ȟE^jO䬬v,6 !Y:z`1MOyWj䱏f0(+Wo9t>{T}?<v9}egL>}FC�?!EwklMQR'5of+��EfL& J嘤?V؊;R8ֻnnf&2L,OIQ,׻QY 2+ SD6rI2 Er <C_o:Y䄔VϘUށ2N2r =ٝ6W7{zT/݆&fȾ۞<ӟɊ1%e_Y5 @yWdq-,LG2\ʚZ""i cգubMP_ c,R4[4|16F-^�^ω.?g$LcSښxl>R+{3?{n׵зLaMJ$XQP%}||y'#g.1_]۹}ǠFг= #0'l,SE�zRRLؑGocNc$z$&b\ώ(=y${vXhf)f1 B'׿rQab"HcrƔ>;F>Уt:A}ގsK=٧v:A@gx@ i!a:j/EbfLyc]}"F#QAoﳳN_G -}..ve<JW: J4K#o}rF&[:ѯFƔoXM% r7t*EOPAS,GH'9ׁ<ȢR5+^ip+YuO1lxֆVܛ9uУ)WoɒH=S)UHV.u&<wc${[$,|1-2#I5O{>$z{f!o6mP8X`np=dw 7~N@N@cl mz`kQV}4~TUt60]uT\C .̍ s6.EIP+oa{MkoуvLv�J+;1:eq5[5ԆjrPijSý=tA0FZ+Q݈]2tGmnDݠbJn~ɻCՆq2,mY_2TkAc0ڌPV%U&lsYQИ V1{v7 [> P3%5n_Z$~qP>:X�4_PZy<oT`XhȷZDP/yR{ऑh?6vG~C7 nAW49hu yڥToU)wjnuOaq@IRaN|pEQh.;ejaMަ� ץ5}� ;q2h0b+WR �P,0{NVh54AJxaWL]vuǚ[ci4#wԽ�H�u\g5 4NWÕz=C:jެHozޫAEdT?e+Lkl[?\cS{Xеb~`O=>3/@&:--V``<oJ0pР-Δl�_p1CKKu!%bU9a HT+I M,J-\e^.ڸhhiZ6]gQZ4b^vIapABn@ `~6Ԋ#ZI#(YL6`ny°4A@mV8ҟ`LS^zk@ '�:[J,#\5hgni5)a^Hq15Tv/) 5$)%|W!fG`rKDOaE'[0=+x9f̯xꃞ_2s@=TYHFSwK/n9M;3 w7&݌EU*~*UHKӳX7yբnul JP-|KP;^ F^m. z('*r[ڹEs&+"_"NO9q\]�F9Q뗈^2[m "WjC@qW_B%R]8=QEWtuQ$q] e)CI] rEXE438C0SjrZm/OԴj%lrY"/o,T%hߺ&.N,~(Er"rTowq..Swh)2z@iT<%Z[yE Uee'c 5wbVszcwZk56Xn$[ }PJjc;Y) '_s$K>jN;�=hkǎn æB8=U8ϴ6wÜJ#C1t862;ygZV6!ӘFwQ'c מv>#䭸kۓ6k<Ͱ`Q[w v3vf;=S]ӽЎYfwL=V*PPl-3[<q 0- 6)j@GU;aә`O;pު:] O 3_By0\FUumUﱴbV?9]S"KȀ7j)eJ|`z{ۺYA.vwVe[ hnз̅, z|[">( gdtkvg6ϢǂHW)#C8ՌO[ )v=sA\wM+x>}P A!_v:_1(ڮǁ]y!cV`F6N0g0N ,Gk:E PZkUMkn$<Vh*ıv5>(EόלK45]q(5S|0 HsQsq#+(_wqYe VͅkF}!\}#a'�e"35iͭz{Mg1>9x:=n)k ʸCuYX6ܸubcɂ(3<B\/J!_HO@H+0>/>n@oN Of ʫ+0 yn PjW)2.O#W̼JBH}rn>R-[ 'LZ<cSŠѰS>pBHv]p 5chgLaQdX@}&🟒O'ah4)@C+xP4nKq`K&/(E,JzQ2J 6N~jX'h=yJ{ݪJ}8BN[ ~S7 @O^' S[ZB!@"GFICŜqɩzmВR>(\(ZC#~wƻ +foQ.Ir +Tϗf)A je#g )rr } 5- / ōc u045Rk�S}zz)ó#5CКN=J2:aП _ߴڝhNM[x"x2{ ~p-o|&ڮC<SڬmO? M~"<F OcsO)i%S�kE 5y=>ӼaOd>Az;Or(z� 'f9شoZ6h.?$7�4Z{k%(L8[$Ib$}x;VOOD6q'̝ިHo ['o a"?976GkӉ-';>h7J<Nȓ0rOL㽿xCJq/Zh>Ngdm/5]mZЇ4IDez = TlJQrؐ;,"bC\\|FpS_q_q/|lHѓsbÙe3ly7C@\ iYb\ c`9M@b, Fl|Srf7j'@_ !o} ӑMF/fMiƲu@3oж$|fF_0i7510X^Iaw1)'}SsteRR}aeAX+%=E @мCݎPSSp10])N#̔5P&=No2IJToԹ㙬kfK^%*%_3>y2s"|Q8 26:Փ)@qR%*-Uh `-�AS~ڂk@߰BX1rrb-a@HKT$+V"t˳ ÷P-4 F @+ P\ܭ|:(dDPZF>0H zaAIb=pLt_j$_'iH3ظ<SҰ!9jILߎ@6^ :@HZ 3h 9H Jn\AUNtEL5>Ef $Is75ũݞ Z(. @J Zs@zHAP3-[ @!:B4*3ְ'lQyC(#%`)“:@33 kX4oc3&3�F@ ▂1 4 h1 h| ݰc4L0F"Z3)XԘ% Eu �Kώ(?2F2ŲvwE4Zf =)[IpҊeX5#DBwr*.O`pQAѱȥ{PYϢM,b 9`·_ي=9 yؗJIL면e1KX~^d aT8"_s6>v9 {J㿺NEtصLP7,~ +Qv]\JԽעv*Kί1.˸#Ga0۞(w"yǍ:>*mUm:ͫy~A_�) fe] Y�@ � O%�mNtY |"Ri 2-%Zԅn`PSݩ&4-ӯpy(ETVRmdeKdД+8, <Gic$M2LoF!7N$-|MAk8@bCq}P)1LL)̙RG<YƇ1 Qtq:1Se0]cSf3zӔc.5`Op1u~LK>G'ƎQ>-ݝָdU?_~#'ȟG:2_wԞ>s}]/_/;_| CT=b9F-&{& j6&M�r{r7A0a& w䖯`Aa6$лNLttr"$?'!9t (K-c!{ 4xZ̤( |{?PdX}1} sQOyj7B )>)wSi ~3,ޗ*p&,ţK&,K %H@P\a,Zq+~F.|X=_ Ae3މQL'rW+,ߏ3h $:G<n),}'#ktT?dz?'w^QyYݣ,42?{SBS^|_c{L Ɵ|1LO_0S`RJYEa,mӁly_<ò#OEO8MYbL S?=]ZnH5 HQ`!9I<O=\^۳4˨:{Giq]4$_'ҘufyΏ9< >۝[)5dz;4qόj-aMd "#Lod?} ( x޷X9hHyfi#>tK:i</EN2ɎK$OFN5d?W"> Ar <Z);P{O({#QGM`Nv ;y+R&q YWV~YIv9_}f,9#/iʗ>q rOϗ/]]_}9J9 (ERR- 69>I?#LxDCX ɴ~F͠nqI&j\p[Jmm1�Aa-zw,K}m<?F{>Ze8@}s?Bm�ѬZL<FN/>9E~XH (W^Rcڋvc{hyAvVȣ2Ks_ Xu>+t `96 {Z?ө uМs1h䜁wsӹ� "V~;@SE � ^ЙlJOH7Iۋצ~Bno<u]j&A+J ] ǀ$%|w>gSV:=SHG1c~{>FjF;zD( ~do/M(?]U03V(w}x:sPep&|eHOނQ,=�Rv͝R[bdR@r2F$+G^ʛgqJF+jwXqcUzF`tX:C^|Z^垅�Mx2g�z^W^!-kmc-Sh�­U}kWŪGV٪ #idVyͻJTW+W NWb<ث>|L!7,_I(US 6UNyY 杕 y;U]jnU?eFӭ xۙGݎykd勧;m%3w>z\ @ ߐSJ_w�mKe�drG)2ܹJmDOi4ֆ{{A7 Kپ.9%nՙKůw]7˽pvžb]gWʀ_s:.uΉY ſ3'qoYW+v%]ܬ^Ojj{ Qj^U%=r{rݽ;Kyi1@xA7u3 >Ym]ާWymޞwZlުU置{yc8ocU{އmk=q.< O|>WOGfI1K<4#W;.Ñp7=I9]SvUvjU{Vb[rSTNWALj;xq:^#8Q͜ET :ŬT*tR-2υ2MZh.Q|8{TD8;ߞS"mPCKXqlm3 d[<2Qnc-$w)r&fmF]Yj_nsm_ aKHͺ6ybm6v?^ϓ}͞.%E~8wcfUۿ{_IįS=`<jbPe48\|Y|tۂԊJžVNx(WvXVA=c[[]EHu!(\_$R'\%oT=.[FF{% i} #}7kKt?n4QSO2F\ꖁW<WTChJƣnSZDKKmS`ପ)AJUKJWZ%I/f# hn) T]ގ T5y;չrN�b:Z\$0KIYYlMg֝y%1*ρx gBsd ߁&1zP#뺪hB]Yuzwo?0Oȟg|O2x.]zSlāH^D _#|ùYc>n[L (J$z|. [C]d\ sGt[׾L݈~FcZ߿@>}vAP ߨMҕeڅ"U:M*DO}܅l>voYJ "%(w�($Ҹ)*%8YaNkFJYT3ve'BJ.϶0 /G�'H5WzOP"[) 0q\湸;^$Ol2MO*|wہ͐. R,6ӳyz.Eu2H7e�P0ޱJ܁sĸ<8 Е~W XB�Al�`w OsA0t;q>pvpSYrSk63*Y ٳ&B]U|\alN=;:]qMi*l]m3{>Yy ]<aoHx=uZ˔HGa5hhlL6;|Z ؝Ucm4Bx[du@M]7)Afcԍv!d}h (@gٮ##%HB3w󌂶� xxpeԠWy|٘M&^XO5<|-޼tvb�0 .*pxjm]z0 PBQuN}s@Yi p}iÓqEs_qA0 e\qb*.[qz~\(P"&Ṥg*Yt'Uȁ qkyjv\]_-*yB<ןUf\.Wkwޓ'O`H$uϫz@yKzeX:5�1*N:PFܨ>MBqr(kݨAFp3ꟃ XDr5 0!%]_BJ (h�HW7,6V A`kaE&%"L!=-oq�P\ il\"#a^˅a[ X V�E=w70eq! jg{Qh|MڊR`*Y+e6NtNEMYEQc&Ƒ} d8I}3rW2\BwBƉV _?fd MgW{ {^_ĕN(t�%uxOf7ujͭd?O<|h-kҾ(Jw{aaQ}"Q H6 @ֻ :8`NO_BAɵD\[2du> ROf֪Ĭ#tsMzWo�R+ Ʊa PHe"~'llZ@)$9:+PI7RjȆط1"^;6rd@%+ЬK}຦nix md߲I#pNkiތ9|^#GIVz1m Y2'GdW6ؗ߭|dvk硤: \O7O2vLQϘh]M=(x =xR$A'I;s߄Oy\ =w}s�=?\qcݭs}E 0R#?g2\C{*AH cԒ 7S3:`*7܌ 2�(x0.`,c=]<_yݫeo?k#ƞF nn' yS:q ~- ͫo교:+\TNR)aN7֦?v ZɇJ,LvhʟψЊ iW "!XhZ 8iE~*W7+-uc.8kh]%ú`*FE0+gh80%-+.*@u_RqUoCS{*|t$0/Dsw`n(�$1,g-%7;L)nQ%=p o@?LuW`O6C/n^ֱY+fQ7y gˊiP@`LI`f\S@rAE;4=9׈Vl9Lj} \6=Gqvg9HZ_ߝOc~ʷC7 uɀ87^WK9b*hU(=>xAq%/Hyv!c-b羽OudഡZcQz^^G5`ΗgGoGnѝ'3a( hi?mVђ7يlD Qg2D+ A# k hɿψ )"pF4 +[`7[N+a>qZESVA h]Na%ܤe D wC*l!_KDh[fZʘe`Ҋ*6Z/xe2Y^.;_ _B\/J'SeV e ҁ}Q/ ܑU#cVX޵V.)8w"ջ -,zYtQrʪnOd|-Y[=^Kz>n))$(G v|nͼi5DV5;KH 8|+ @@1mlLCNM9)390+0ki!k66'Stmr4lBe1=?(ѧ"tXICn2mL#6 +mDV"~%(9.Y;� k]-#|9=P?6dGxo,ZÓiSfS ïARr&q)kAmuK0u04};JGϝ6A ǀnؠ%ؽFnD vTmb~Ej1v'S$pS>iOt@Ii2[d"7ұ]gArk$$5buFVKfx^vﴹIuI@ۤh%V97`ahZeV4D$0.i蚦y C_, t�eTodGjI1.¿7OaPK|eC ,]}0T-x gµKqUC҆L`h<p9П@Ueb�or�fYKl,blե@SrJ Pݤ]l@8&܍tJ莕Ԙ:Fƨ&]Mr@ )*g+f")A |'{͟żl)ei%2{8lCw{@m`1q#wD_uBYR)741OINH. reA!jaZޖ$n9W!X(a1hutυBCdNݚ; jD#x-k3!h0-AAmp 4".ly{9tc/HCY#щS1cSh˚+ lEhJfy9r d*Y򻜖ITו䘙>.J\6r˹~]);]L)n K>DE[m/A^Hg"1K>Jr>(I{ģL>ڛDWoG },o]yG(/I+rLTDC~`F+[H"e [z-gG{n/=-09�AAP8E&ܛ@ s׾ Ω688<|'iy MY( ]@9? TAap\&P@@B(l3 4gT5"%h⻆+aMJ�t͠ }@ߑ!E,�t:wzV|0Y/3W&qE32X�Du?e*Uf~|i Rqu{UE~Bz̉+r₀6 7ـ˹V^n9�@'1v|b(02A^4 4F-Vc= /Bž@N�9'v}9'N~}Ƞt[R\cG%sq/<@p8ھ)pIs@�|4~D<1D<L&%HjF50= t'7�X̥2t  �  !ySUt<MoɱI[ q6��#7!߱�\LtH,-`�2#5&F4'`1ê|7WW \*:F8bIbK* 3ߗ߇ wOVsQUW\NŨ*Yp.< /Vk<mՇA4W WV*0rJ[|F_.Y?UQ[ꪼ k*ҔYIa *3q貕yz߂>iVq] @w}sjT:vjzffȠڢC!;rp!1$A` 3lİbC�$,mYI;HAlUTp na!xLx`e-H{AwSa|$ZԎ;I@q/bG e?j৤H~(hA'C xfݘ'yڼ\̓-u^>LEMs=R@ݞgvH'WL]YZ\W]nmCqx q(|[JPW+9sy^=mcޟRYƼ.EeO~ۑ Bg{/4ɷny=r5s{}=2O+绮C:yr m{Wears}"?g@> 0:`$՛bam 0:` wKB�?trq 7 a' a>$6E&”\Ô`rR{ UI`, r0v"eQ X|x:Qo8)<b,P0&%6z-ڥZ<k@][vtn|Tܚ=ʝgB5froWP1@tQu^ĕD7.Izcgc`7#sKFO+hYK[3Hž8Ώy>?꬀jB=*pLd8nڣS᳜ϨrفsVQ|sҞ (}z4=$a]u!%2m@c@e ,@9!9 k)y 2"pP& Q&`[ 8N«;'FKy2HB!Pso  ���IDAT)cxfOI&�eOuNAXD銮o#sV>Sby/ z 9N3Oȹިқ@5h Ao򡔐5215he(�<P,eݟhǧ SQ.bh1kxTyGƞi$AHo㣍@Z~֩LlNޙ{HjOs졷GeG;ﮪy L":[Mî¢ 0B@CA h#q�>\@:AN(=er7Ag  BI5A`\ zg&��(*1B u<qb vءsV\xҹPJ^ѿMMpNT :P/pl{ɪx]qW㛄i w)BW}d =By@\\uخm^-jZ]ι=`oJZ8]ؓ@0d_.E}�dSW  mYwJ+(ҀZ<KDEÍ,fΒ⽋)[܅JI4! -q]_f;G/W9zHWDs}ΘsZ]痕z2`W6T s~ec<"tYsv)2g]Vx~%x͡]α+`^~+<%ɮ0lWr9y)v2й[ r�GF9{AOvgL̺߈] .Ws͉C+7@0s{ ɕ<7\}o]jpxѕ`N*�r8ldV5 G> j@n7 Wuq?'=vE(-kK�٪\EXYcv, !`9t\)WP#<^\ )ub#yVSvbZ"e< C$X w]N.mNvqFӣ93tDQH͜Ge 8] _-1㣫>\qG=<y}<?tW9:vʑ舾KG؈3iخ濋wW{.>`=rP?Bw;ݣĜ?2dg^)?|'vvehy;{MK6n ښb4jVh\vL̷w>n8wDŻ{pL9ys ܆k�q Jq~QoNf6v7s"Ϲ~{zcB+ydQ@SX TF#XlnP[|/9(uE tO]Ph\s3G@+E;˹wrſ %D$I'% 0Y7NפZQhc[i hER_h;�ek&(Dvz>1`x QJVQ&";@Z2բ[APM,.׋=Š: Ztrx{2i46Np{+"e + ~h==ѿX?f(<Yʝ]N6:d<@F̿iϊ祣s#NeɞFϯ=rWzN.Ƒ^x~"]RV4_x/X-pv9_$_1h4Hsh6F.Y7Y:y<3FFO?|~@Y/z׏ʇt;GG}ⅿȪ_zRŚ[;_%>ұ>hkJAk_ {R$=cNHDh ",@=B2-k66vυԅiRFp}C LGV W 2?hl2.ll [dsے߷_oqx#)IfZKZjɢ͵uA#po,ܚ\O)v,Ps"1z�ПWf WSB<f7r ѵh.1Oi.`iˡ;ޓnn2')/hz˛)<U�F`֍8kS\7&7 BA !N9[+.eͩo w :Է>L g ?w[6nǖ]&a9mC#/|q|cE.thYt~km%k7Oqju�}g{sYT[@?-3E[\跁U9-Z3e[1GqHF& awSJ$i7,I e^TC[χ"~t`a[E(z%3e)F|6ӱsq!Ӱ$Hd`.j;omUKT7:P'o†,>$X>o-s[_J8G/5|81N>/&1؛;%8GB,X japx3}*8tgH  HkE AV֝&%o B" A^l R s}MjoH-[2CDtroh_ 5M+B'(9b" q<;�ufs8dd%oh I&[,-{cM ,oEb�; GeCn r2`i=p!6vRbBD'>Y"k}zWFdm/}l㎔ A}wn<,5'Dsk!kFBomc&"k mwd 6)`)e1r$炤( #I¨ JeɖK!dmHZamS|dr6{;#?E>B4†7d9&k|<m"t'"y>Ed>$=%ú}<A&kzZܧS6,AY=!\pWN'[A) +Cp~`#SuvndLCw&cOI-O]BDft=G ?SwLm^(<2xAV""G̣"zDlA{X;`3w4j`B_ڻ=2o׶я>LDcގ}p|! ʝ]is;%rAl#߅/톧3 Ćy붕?sΤKw@0NC]oS& KZ&M6) &3f^,27;PT0'^ϦޠCX'|^;3dxǝ;q [k`XiN7s+`k-Ws,|vvfpӅp {&Ҩy݆[-wC<sLe ûczxG[;(nϢaRwr)h&2YSZIZVj,df_1ס^n}p@:QiktϨ^͐NC:8hN5w_ޫhiJ,ҔlIi8x["StFv{l%G( q 16Hv2odAx;e,0>)&i&K@ߵmZ0yٴ)Bglƹdr8 7? /G@0 MyxSPM:宏S@+Bk:SFBX/VaaH� a pY7%O^ ^"XxH!73MbmKo;CB\{34e̐Fu iqA;]]Q=PtMNPeABYcgU 8wYf10aAr h"9El7ej?tYg͓TX9@?9aew>"^q,OCa+n;ff{bx9^]zA0 ,s8M d4tA&JHLHaen?㋛``+@[xf&p܂Aa5@V<BenPC%�6H#|mb<6Zgiց9ɒS@f@y3txs$ZǩIc%\R0 t�j"33N5 (XI^hc6RV  @;qDžޚ|Qc(7Դif&i}͸0`nVj3nӴwKJy>3aG8ׄiEvOٝ3mSkˎ+jsw(] ˬ:$G;+hLX2;-F{ ١r' HX.4jO#2PHڮ0΅ہ[iSwb??gԙ܅pGG6<Na(f73N^;q7@JgK)Pՠ�,rG C>Ϋts=nf6HszHnt ُ<E<)-}pzQg Y�A�Tr2 u\ӄH`W Q1t[H EeJigA<C-&1` 6w/ "7owRnͰԞiӢƧ{[9n$ =Qp:ء4ԽI>̔;l:EpqAFj]WGnگ[d#G*�%; `5:UՇK҄  aLnaPgWmƢJ wHe4O7xD!p0%Nl !l_w2C0ݮ3ؐi5ڗ$2 e8>R#zyw?9Dg94 taX{Az�*۾rRd El`ӃAudf^O1<%vQO\r3yK2F[-O#S$oc08�J?qG`B܂Bflܢtv#NAo/?Ua  h> ;5@9-˟&di>g<9"L&R(x;y4 2U~D deW~#۝v/O[ȰRk;Hw <=iu "�c;X��cg@ BH@0!/a+5~ b QЁȤ؂|K&K\p AX^e{ 5xb$ѶMzqVBJl6y/tt1y*/6<ϿI-{nsUK[PB]u R GȎ+I`#Zs;nʎ&6<i;8ÀJL0 12|ѳ&/txE-O Ge=t 73 ΚD}/|@#>jfi`DXWBJ�tJdY �]e~)Wt_WȐN:h6W a*'<]憖 nAw[ @N0`|GM2ޝ) ]k( ؎ oi $\ ;e5`ss]Cg޻� w *ߎƋ@qxtkБ AqXJT\Ib GQ�u4hkz/y+y1iE2[tA{gm`\wxPPKp_M9QAK:@{j ܊?K <ݿ0r>!'�8:nT6#{%lU .%Aُ]cu DժXkmz͸\sƭqZa>9%o&pA*4!"7�Q  8 C5)S {vj%w!P\F'^,Ӡ-5ˍW %X`! B]bzh8VFhCwpS_^P �jY @c@{6Q-;?]WkX�1vzwzJ�_[tE� 2tC0\]_) 0`ybF y&�veG�2H>pKBD`,ug2o&)[5bUJRH 2]؁glA˩. Xks A9�A;\ 9Z/0zԞ?}%FP+2\WvΞogļ6"W`TSD>o"W箐:}[O\ծ<T8$~l79:|p%t6BWCW7:qϏY|&3`swWYgs꿿ֵ2:^ o|i{MYW.$q\"WYںyӘ"ghSMr5˵+r~~sޞO#NWvR13Mg̡Y9FizLku#5v]�;SW^)E=SuPoEo`m*oW>"_PE?$.�%�O77:<+͐y{K0nI?yU) *p{pe8q0VkK1B\G>9?\E:A\;3]o;{XNwIqvZbs]=?zgayi$>$FG\fvQ�G칮N{Mt}ww4@ɻNu.sen[622BF#GΓS9dٻЛ\Ď<p4$;vɐuF@ . ߩЖŎ#Q=H(I7oܙ{yS=K;r8u7mVG#a~cmV>jc9q[wv]]ꬼ?*RCޱ˿wEF:돟s7?):ع-17;;7:kZf9i]ӫu3.>pm|mz~5co51Zc wC[qAo�_/bDQvñvf&-_~0LbE^6~Bs�NG~i8f|Q 4ўv/\]i=^Ok$'K|b_,Dyx6zSJhUzom-'uetcP¹ܮ h)Rd_B~Ōψ: ʁRp5 2<,REL7̸r_ 87 "zD u}ܣ;V̧hQ.Ae?*̡.5Q? Jh:bq+BqYo|N="WGr<+Gjؗ7ZmnK- C9n{U_suy9E9X2eZY@;om? VCP͟0x 4. D!FZÚt}ICo- 94$o;E஌`E!=k8%𢿾jzJC a`o~A^hil8HJ[D"PKfŃ% ZZJOChj7_Op/m=!W.6|1<󁺾!@ ⷯQhOMk`%*HJjkdiPOB/Zac}훜2~OuB;6~Eo􁽱yfrN}!#KGVQ^^pTx?7`RS]П ?oevx)6Ϳhl}'M; __m?9%(`a4ػ</27Ѐw?\i !o%]aڪa:F~:7g`bY搖o])tUh-o|k?k2' d݇iƒ iBbڡqhm{Zquss~}kiz ЀV1 l}PMND|Qk>3u…,t\ jŧd>b 8<"?ɠp߀u9Nl[K] p)ySr+<=+GpتQ WA:-EngHm=s oR_7_b¯/7ղoۺ {mZҞӧ+)iPrTɃtJ|!4]JMS X�g%�OM'D2IM%曅&�f Y!RD�HiZ%qwyoIN)!² ts\?@_Vpӕp^վq3*G�{ Aّ~̏a|<Y)2MBD>$ݿͩp%/J?OoΒaB S~n򻝃ԓ4MYh(ӁP�daq\ɃTaPnYQd e rD �G% x4Tt,6ݕ(gCJcCmISIk)H/E04KA=VifuxJ`.1]taHJYMwj>{zP"ߐE �CڐZ?KoHѿ<W3-kOJ|d)<Y)~Wӂ٠Rabg0-5(A"P*`y2 �^Ɋ>!po/ M�{)R8 j<A50UU#$ )j89N)Whhj*mՄ{TGa'*Q*P|TeTn_LfeJ9RJUY; ~'*=0R\!C)XM'$+̛ΓnWpF~Bg/v##\Mnxo+?sWQ2õ0/&6S$ "˘yVMp}aia'#CE-=)%ѺeR8yj9ӵ%84C=H F` i ޛN#BY!+X9 s = JGx�((Fy4Θj 6I E،>\̣N ؎>EοU(`VT hͨr@cQ4�jQ!ÕffT~巖"Igv:F2ae)#a w'&1+M:13vGm>XLOI-6 g8/ yHgY8G#=(I} <Scgγ~LLL({T>kB3/8 <?/ɪvd⾳R;ٷ3nz̴S~N0::CsiN==zK )ԭ, )Ap=j+!Ǚ)\6,@xxkEJ*R6jrÌA| VAبZJz9gOćBJXT])a4ZA�JPL 1 j(m=?s]&Q3ˋ*X+jk;f%&G8+'Ři f:<Ҵe20G M?N<ڛ1ɛ&aHW d I 1af.H q9{6%a}�ubcfqpd]]=K!'vw2,v}˅v?5o<(WoFk4d�kXr;Z a]ԙM:t!  ҤNX x\&`s"3"7@H -2/E2aF`O+ihz:d𕏞 h.g\j 6$G.Y?6+]Ǘx 2@{sZq!`6B t}rTbє$'&f I+Zc0" Dr\eUx Y }n {0䪩g�<axW4 hP_̌߈a]Dgb@0 0&K#biSE{ŀpɆ(~<2,o4Ռ-<ೋ�(fu.ʍZ6 hRUôd?1.un)5+eZH   ;04i'Opbo�?8�!C� qDv0ȢFjtqIU m:)@C6*ޖT棺%#) *ؾu5S\$Lҽi3YDTS"km8. eJ$ QH' ځZ۾)Dm 0lYǨls<W`l="2v ޴`> 3!>|F\^7",fXr^,0' cq+'01; 3".D0zz3ryv!ѢLGN{ =I <rXiR.nFCZ~C]U0t`I狇87/\R9) @~_�%NNEaFn� J)( 46FM�ف/ewDV v)2ƼU/B~' @o�#�zlOlUG>@+/m59Rdk 0TɥlE,izlR\dۑstyv' s:䟾?3ϱ۝ gm;'7{[/?;r o>{v!rpN\8}V~?+3B{?Wul.ho>o ?gxۑ3;A)oygI$v@ގg1{Kl+\-soa&OP3 k14$#ۖM^zwTOSqK.z4M& S0'@0u*> nGæ`X"0xQ�KA;a W@ ,  8f羭ք)ChB*�HԢz++ /uA*jm`uʒb*1FǒL0f@$8ZEYHFrM$pr;ә�(YGLE2?z({<�ji�Å\G+i,umD3zk;K OT9._p1_$1 �hT=>T}[WoPC3^@Vjr\]%) SFU_"li//P(;� 28R+I|I 6eS|]DC�)ArEQ&˶j4~knAA&�/PYe @` O =W@\ A�Op5mt|JQ0"K[&< �@�,#Dp먈Pa&Hlz(1-fF)Q;\E`7omh^$/Y3Ll1y5`Rr7}]{y1Qhq-D{F2_jQ5kE={&f'Q&yYX赇=k|uDԩHc JL@Aw|M-/ו%CyXkk)%d }AHk{yA1(`SkR+ %@$ e�@ntƩ1.`6pڬFF)~9Q(xeNH"5Yl[:I ц @CƋ;ft?07DR#@u6頳Jc@cD+ F-p]W84(-ש1p-Ws;,�*sb3OLڭ ngɋ+]�``ؠN񚼸q?쑆RSO[ug" 73UlFj\gɢjGA0VL:Z~։2:Kڪj]m'/Ӡ^w;F_aԿK/z/ĕUz( ]TLzsvp j+5;pbd+�  P|` c> @�"&t _)�S.Z-AilDiP39&%!lMJH =t 4 }jO략!Yyh>lgZZd: L7Z~T8ŧI *]5t{2r1jVsۭn1lá2,9]Ngy\Àdj~MTQF֤oӱ0uPsJ 5V=PfmT �E.!EϴQq@pwVmN"pv A@a[va|g}v鶵F ]rw̳;ۼ.;ggoa]G`+[ x:3f#O^ D'. APE~6A @Ǩ7}8Ax 3pzih Hl5> �ēC>0, |epjSM;XAAAQmc ȇAyq_D֣7ڤ 0?\F�32 qr$00+0T挳qƎ|{4 ENo;f 5' |}p5aH-�iҴ\6t+46%??AU #Q @pc曇j6 T Ye�7Z5tڸ-W Gk5[os~óم\o-YfWYa,r&F,9Sڸ~T[cVb � |8#zęH,IM3=uD}*77feSZ0ӁȥĽoVnIZ9!oH6ZX/Ȼ]Xg֑2g#Y / " h9u祍 8,QIˆQX^d|a_kzg}>[$Nܚѩ FZF+bZחNKdI_웕Ly==4Ea\gdIWɬjh7֞l-.Dę׉ɗYh' .6%lxV2S}knb9u:�m#`-h(6LzdM:Ek,_ow=#M0tJB5r:ɭ'ٓ&>~R?'?ۆK7 J܈~! Y*Fc? 7?« CxI31J4>I9avI1xX'o*ķZÔP?$yC xq^I&~rI~�KӷL>Wh +> S:))`,MnvS-nh~x|7&ۛ7wRoF/1Bű+4ef8o8 7 m*4PY92,L?n3]G�}A8JiqVl|WDЙYjý-GrطHb&lƗa}.)_`Bgs/ZZϞ%44ߜ۬ߛҢ 7Rvdϟ7^.ykA+J+{*%CJ(+BL9=8," H6W'3$vwMl#GZ+;10u;@BH[ Hq?eFWm V7}>9rjCV&}B`\j=*om"u":>b�cAa$VAg -t5tt)<Jryei&J7Жϕn$kRQ.i5kSlFT`.: jji_a3( B+H~FKoZ&z4P�-&Yg,Ej(kKJAӡ8jLo|p I8Rی4ɔּ ]g i3:P/V`}e|+r/XH@IN9f A!3- (6|W"m+IN?YYF-1B*OO4itrHN'yb3ӛ pEk1oLL71ڡ + mZhlhpUB6k@ ,~P(JbLyg~f@֨g?htT$Ha t, L"Era(D-2,cLgK3CLҔ\ݺdq\;qP qw@|H5OKIi7 >E`x4奧gàA$w: *<4z@; bU pl⧸O>vDk_nAMHcPp6'PǐI�% ()ũ},ъl`�9w1!&N#e˳<sO,(>vNyTԝLۣB?I/Fg*{{?=+&{_/KLb.NGO"Q6Hl|YnVEqtr^$g'أF.ZgI?zoo&~aigzُn+ErqoOMf?}AoCoesz_^kM6m\[C^hx0nRd\䢆1@pGc9 )9[Km<eb%/ ?q )A' Pev!%iDD_?|] 5Pj\ y2X}}@X)RO8^C"{& L^3k/(0A)s5h!}ko� 'f{-qy mثskݼY ȋX ]Y_uٮ&΅(7[0zq~,a/Nީ/~s/|1꼷ӟ<Boٳtp-~fh=n{7X2.?aO,uFy}g!`ּx  |yy{ѿPWݯ5?=rw4|)rh r%dfq9g2!N˥ z~UL;,N j943/2Z(kj.\6^zԻQ@��K2|B]̛ hC_ՀaPtz`|)W_`m#A F1;]6i1 Pdx HӅHZ l{Bt3r/6lӞS^䏀(fY#Gz<mӌ6# vߕ.3d5?˞^ j JG&L]e|OvLwrGJ}+l#ij^wBZ_$nm eq~xyfpcۧ䆲 -vyeb~�0^;ೂv\cV/O 3N 0rt7)o�ft_'c�� y �(y4Sӟ]�J L#1+b"fM|&u@O�Pw ~3o-*C7.q)f:[=s-72n<8nP`ɩu7s �2͟l3h E%2RU&4=d)L zH dY(/Myi�=Srl6 ruȸ_Ů{B_Ipmyޓ]LX4QhۍyKHyfمޙŧWw,Uw"Uuf^5Uj2EgចY#x;|6'NyW}7A@pT!3/T >) A0, 8(.x0Ї  BϏ -;W9Z.u9*èƠCʃrsrZ&?iq扢],HƑ=YdrG&o޾sdf3(w3!$G#w@(6=b&Xl i@Ph6 2cC]Dj6}_={A_Uk.|n~Ssi*3AKY=8;x׸qXd](RuZ ̫d � @(!a׍ oF g e;ov&V|ל˯ٹBo:+J՜~mRh ˽UG??<:Cq~9)_{+4uKti[r0b<M5.%sͯdZt(zͯdg_|ЙQMz!4"5yts9W,*ț{̿>_^uҙ_Loޛ{T e0j!c5ʽ"U�]0#YP@Jy~]j2tt6Ab\ʀ7NpHE0N|bp=:"G8^z+zY{dv~3{%^)6G7L}uA}p'S\1窏;3؋+VB *=S/Rt vR<Ict&;p22v;iKXŻQ~>5E+v||/ҧ#?xCO>g'JeNy;(4ɀ^r} 1t_?^Yh׳gx2eZ[_9x.0=7h&L#+'/dg}OA;/W㙵>7Ap^ҋ{rf&幵˟Op/ @&(LH!e\L(,=3(3 N=εV_Lt J E8Ӓ8 &{E/ﵳjvr);_*cE*bttsō=DYULl/ژ=:&0wjh-Lr-�e0 XCA."6@+UzklԔC wlA6 �Ñrd#-*qzMFڨwp7GU?i@P#rZ2̾CG75W{*H{Ue #<ےL\ӘK5Zgw}R£t̀BW~xLDJpaֻ&LеA !FSei  i2 rޚ|QV[zD"=<R%==e=Ŭ̔&L-ŵFۿ� mpc dpHtn:;5z=mNj!#I"X ;t� +vAY|e,M>g˽~[:u w:]m{s=483F.ZEK*-.K-3Fs,n=`@AŵL)zZ/_2[J}EbݺpnZƵ}�*R#.1S] X bh4/D,22/.ʉKе@/`)0@`eB٤3 gqT#zLH�^%jfOxChx G~ݓgZ0=^^RnRzR > �t iB88L'[@�_}46d8 J: (Gq۷jx::kY v漅пaҔKFŪмW1-ЋȂb7`G*|A)VdKZ(/X�q! ʍ~i .0 3[jآdT͒ZU{?-j'K.|Y^$?-%-֭$� w~@il�r wʼnՔ7#%=hTzP@  M`^:&!P iDm{3|E^GBpD"E<ܳ_KLD ! a@؎]Z9G|X&X @TЅM1Cr?E@Y7Su#lE(( ^djyR3C&1Z~MfOӞ~l4U[RU/״9khV= ȫ45w1{5CT,8n5DyuC/[i,CZy+J֝' 5t*Txǫ"@WiMS5n˥BO 'H 6uoEU,G@ $HI{6:Re|OR�; :\<*�}ӑ4/AL!6=i/冝(/6Trqx%@Ц[6%H 1a=!a/IsE O�Fk ~Ѻ\d]o RGԌl ýj+ʊҪ]Nו: 0Ʉ#stܸ]{mr}/H2;F֚huwe4ک%wrW(Mt<}WxAdjj/9o ޸݄H;NueK xA7A^Fm̿ \9YV]G� ll*>nk5&5hi2R[dy̸omr!<^ݜT4ϝ.~Ef[X1Q6A) }3i~篧U Pt+! җ$uYD^뒭Z^~(n>ehw~omfہM^ L~x<v#PtN,Vy8V69<np}5ULFW8xO ![ jI{~B;}<fk"+ 'WvXk9r~͟a{`Svq7hM}k1;&$؎1C![wmyXlm�w6)Zu >�Dtuzp7p`ǽ&=oՎoͧت, eƷb^d[Jx{zk$n{<uVmh{mi~Yj`+`kZK6q+p JԠTD/J/ٺb�*6w9!}pCZW{zuF@bnq__}46wy.G4'@7*m2T<J∂¤U$N 2�+E�ȉXlRyJH2>B4 /P&~{HsHSGB(ļy# GNpP5(IƓ!8Ce)iva^3IHm#WZ!hӐS_걹kb6lta(%=r!dpO0 N6~fYGZEu4GAO!|*xv~ف f@Lwn}P:'dr][{Jpd>ґ#=i9b}љE4`3`\L3*^D*kuIHt& &CRQ6%I^ŀLÀ X2Tn 1FÄeD.[`ヲ)^7`q:^BU*IBNCNH"jZ{8 MHP(s!D2DhV3͆:+ia'#{!^H!#ZzpN:ik!xwfZ#$]'i''!<Bƕ '][;L;.�IGkt.o'ߕi5!r{MLiU3>V' [>s{i,{t:ƠV!1KWwGVmٙM]+"^ǯ) (NƖbeRVN=:hd"E mѹG&8b"i:IKWJH&s= i 7]+ q0Q/4</R7$([S~k3A5$W/oQ_�g4t> wY^xי ơ+٨C,Q]7 D${!]eY{_|" {Z [VHӡ 8 17)ȱ81O% șGƕ|0ײ713ߡk. >zFJvuvjYP5ʘLFw(ZT{=3̟{\ɽpfE;$V&Ai&4+*Td@7HWZ8 $؟y�abWB״ h䄅sbƒmՈ#5'@'8N 0u@`N =F5B]-]tWINl$nIvC!P@@I'p`arZ{Ń~@D?v$@ 8\Y|�@Gt)'?$Oܥy @PA< |Y8)3ͮuBz4"4 uoxbk!KB~< ɿC5#Zv\?8LyBy%s0y[I+ iQ^~M׀hOfhO"vczn`-xXX)ȱr\�eS'Bm6\,<k)<xZMє9h 7(b|8k8wF. .9B+#t�?O@L<S<~ xi An`Gznd1:0`geH؁?@(iV H� vAHAؙ!`:f^#yN(A`5pW&ȇ^NIwX2J`,ސzj�y{ rMQؠf Qir4 փn׆pW`~s ?�B^~ZCr?MпL�G痢m#%a.#l?bAHø .ؑ]?(H=Mk }ycq{U99ÿH #xl0L t|/u6axx( [!ثDrk0P6璯1-Pя{†}'6, ԥ7tkCRc,'ь{_踧lYnl8Z6;Pא8J{ Si? &>Ŧ=�Z O s݋Ѣz( @ "z r`.`pf.qEWF-)ZY$2G'`C} wM6 H>@Z;Nx<H{qo�$άK($8t21sukMץvVi1i i#VTa(2 A: :v Ёk �nkO(0)0STC� y;ό0gZy41KHu& 8$@@ <GgRjA;P)a೺ _8 ym� E6ice& u` %hht80O孃 2@n�<?@wW^d^��vk"`I~+7ӯ1qdYu'om,F`5 p /O�a:�otO4jޥXS ]P\e"R5|-~E,yDF& Er�;� ):on!؁U\d�8u {�4 Y`9v] Chu t: ʸ2�r2A:|fP2B:Š5׃yP/.Ǥyu`k{'AA`T&@KrK:7v>P.i R-ztH&YvJ2Dِ;9jP;8B:0^E-A!@㲵[Zrָ `P{s{p<#=)b)smw~|ט"*Aw<A"> a%bM'Hn. 9eA# ^c;G#|A=ɗAe3t*Ev^EqvP> K9O!=Fζ(GTAcȄ侜6'4 nv@Ah %#pߞȸ\Yt,tE |cze8Ca[F5 xV I ͹> UA.tO^:Zw׺`ȝA畏FDa8Ϟy_]AJ 녔AߡJfnVsHǴLlg#ALSZu<rREsװHкyvTȟ�whǙʇ\�;ZF#Yv9VZq pxws&<<M-~N2xEz,+Al##N(k Ӳ ԺP;� @`!@ GJ�ʝN)�d|(jُK7&tW) B(2>@�z?rx zOوjL TYmGCso<䀈k=yFv@A˳ j\ `4�Je8e]"%W8y %�83`3 Ntխ =H L u-Sk;Ȁ=ESB|믡Ԉ!g 1 Wb|8ezƽ/vfdr;NZ& U X7z+҈wF%)a,@`m�C� �uU2AQ04�2Ad;`ǀZ<@ @�B" [> 9T;Wϼ264Hy'y5#x,}o3 "zaz9 s%]%� gqH+="Q-ScCG%Q (?lS A^K!I=P偧aH=dBt8 ).CV+n(LBypu=(WT蝄~=b4</#: }sO=mP~cϴ|] Lrj"p9'U5^C=(�a˶�m xXtoPك@u S!~n:2AXڔ@Qy/k= 1ؠ 2A0K JzR 20*Ak*by7K| rAC<C ِ527 dſ@&Px!F>H4%r$<uDJЀx}뮄}*6!9՗DdF)Ɏ+ZSvrM;ɐu:JK`'Q&H X ]c3e"r#TOAyP(gCD% ._:᩹"`ٚVYX_,�[9[ٟ o =M IF4w4G'$>#OgZ e 'L� U} 8٪X?C?-OhρLk't}P"6T5Xkk .L <a j35X4cj 6‡w@ (zf(f܅!OR!M `X-?2Ad4jsțeС~�2֭>6hYNÃރ| X? V @JaGf=C"<EK%XCd%z= 闯 jrs4^2o{'Pc\֛Tv O{dLiӌg'nRDK̂S弱j=orce:}Ed_['1ZKQuI+xƆZW˓^r5ɼ ~ofBR9GcwpuEM'bo!ŚecD*6nx-$wֺYWZJ-j/9 q1L oGSCxxB76e)/N4nq4&+B=dasC|۳?(}߿, u~ayd_憿yycs3$w�_Q6MaCOg0k+ONh ?:>+ݛm]+ֿ7Krãi ӞKźrZ9XaCsXˮ@ˆw1Vήw*-O(b> 졏Zr3ț>-;g+4p@v2Au6U>Ua+G{qVA,Ub'�٨_І..Ňj[x (0kǹ~ wA �sc7!k7MƗ8M~G|pϖ8{x'MsÃ7篶?!ϊ=7-|íߋ}NnW�=,7aX|OmgN�|uM;E&$rkٲ_[y|ﲛtmz3'e/mo{FLPofH#+y{7cnhr7X Rno͐k[u}mtؚ ߍb` o!fW!Ta˿bi^+k}~0Q:-'G]^|dy+ vGg o6&хtb`3,*.Vu9H;7w �rʥ,%-�ڼqO ttPl †EGFMMI*0-,"I85eڵMvb|<!h6z"Rp&Ip`+ xvs~ CRʥu3$Ct~nց.%jKdwɜm`` C.[ķ׿u !$AcRiħa-[ vl\m ^xeҧF)K$C&h4GshpԁeԤ,hSd4;B׊"L$#pNoɸBiؙT:,*h.|h?Nb0it)aP }b2얯u[ ]G'b@I¸R$T鰒[iBVQ 4[hO㷐[ȭ3t2xBuHSM_ h4PnDrg!VR[[H򉎮ۼ[/ОӿV;[: 4itҵFA<ʚiOt-$ON;MAm% b찼F'`T_H:^ښSz2 /gpƅkqdR9TãY9WUsE 8 .sD)|g .R!r%eAzUDx/qOg&\umKޜ-xΪz @Betpʩ n(\]fpXE.;PVpp`2ڐV>ULJQƠz(9 Ή7l8 >v0dbÜGgm߭Prb+13hXǵ<iL-@U@,c\Y"zXc<tم XVOl#cL..ۃ`d<g9Owځfrky?b�zS|٪ zHø<b+�B2(s3Parn(� ou<93h|c:2e@g[}Q:n8c}mf[ Ng<W� UUlܦڌ 2e2vULYU,6kw Ht@y�fU<tǪ'I0 wϸft.(3 aVmT-䓕 {`?vuПy(eg\WWӆ6Ňl5�Tsy᫸4}š#m,K@.,?U@9Fu:$LW8!kz4]5aW,| ~SLcoYoղ;` ^*`j~S<s#8eV(V3 )6Q3#c6;]LfP#pOq~�0OAXل\YA0Y0NxUu4/I! -|I@S0T0'U�j^%ntO{o?NS Հ^;<&7sfc*1bvϤ[.S ڀQp_/xMB<} .)޿TBzA=u]F/NÛTOZB?9&+|tUxKm*Y "duښi>NtSIkҟ Liu)2Ŧ5iӧIs::ͧSJvO#"Vt&SP7e ty[Sl:2(#Ees) 9DqǕ)YZNyӽ黧2"@=blSקvaBwA, |/'9>:ELSGB=Cb&&: A۞G Oat&3E=&4dS2”?M >[9ԋAM)_}I!9)WTdCʃ m ^)hfZRH3(3ś|sisFh;C"?Mܙ9؝νaNSJQ)u>}?0Bjq�ʖ}ONAo:e)ZtlDG,tD*M߹;RRY1c=f{cIYQ+C9~Ljgp_a#|d= #ǼcT +o<fC6{aXrDV&FdK AJܧ ZLʄkkg|XfQE%=<DielY# [[Ċ^F[FT]&|*>ңy#V81ŵc^EےZV .52^LV L+|/<8FR$Ưܨhw;Ap=|,?g2zͫ{3^ݼc W u)-VIB{% 9 4Uh[|EgyQ՞ݼW{^<tcG6* ͮP ?j pȹ,w�PH�#zq� ]a0Np�Ac gɱԽltZ�Ja!to8GJs#r18fT/Ǵgx�["y!^lD<wGccP ;b$ � Mx$ %=ڭ{X阱[=z< ϒY"v-"=vt8v@Jy ı4̽#󏍀=¾@?e$<NwB!*_=V3qL8vGv1c,1nXY#_L=�+P.�*ӛH@ H[cq?_nq_˕{?w=ǺpZ29Es~ɿVso@yY q̆>a&J-7*{sI(He~$׫"r}ߗG^kZʽ}hI'O}F/ K(cyVg�A07sވzCwkDzOT(/GdGGXz1=eP,+UqT!H>m]޷/C=yk*JF{2X}ľWfQ=df;e*h{ %E{ VVx<8ԫk|Em0n_J ZUZ,ߘ}oySϙ[f% 3+@ᓽQ׺aY ]yc-}&PlΔd''p-NJX }rV V%W˷ 9_Z漕TKϗH[:ڥ,ޖw<H Vrr"Vp= 91H ~A6�^^T $xB(@Wc~U��A凑[9ъԓaȗ�y^)C k@"B?Ŭ8\PX^?gYv`OeyryY誔rAy5h9�? hYP >P(_l$ (k AVq+C?l޳b0Fƀ_ʀTj$+)k2^}âƞ'!7`!Q]LY BO N2�� J�F@-v_)X?�v 6U D- d $bb%ʁ.@{� @蕾Z(�j˝�fŭA`1'TK�P'Z F�AcD'+<tJ �]Uȵ@rAbT s-[Y,ܬT><~y(tQXX2 J`8# D @bSފV9nqP`RxݗЂyKCL J* ժx5?NAl+Uvn'SS  7ʳFf^ߥTKI# xIJi�jZqXP�I{9: u�Tv!^U2eH0ځ3-cSv3ޕTa@'Ͳ11Y<P;龩jY$?eO-Be8)u { d)\NSb f yƦ!9%AW9HcM)QXezZ>8M tBQ;` [u1h Aڛ y\*N1 :ӽԝ rПYGtn ړfSGؽL&9@=hz`ϐ7M@76@ 1ɐFvt)c�mOrOi rSYBɐ-Bm!kP-*Bt#?E2BA>LY胇΁6G`)' /Ga9"/x@"`[k|!Y`忄XJ$V er6v OL|$ܯvkM jnŁ̏i�@`%a -5Thůc\bhC\lh%n!+[nH-c*V|YZ8 V8if 5lOX_DVT[%Q.(_B>:46nR[Jc"«K-UVKR|vmdW5҈iq5  ܬh{,nZ_le6@UNIԚ\y,U74`_O{P"|ǞT`ЦG%~hū'G[gOE"_جj3dn}+bTZ +`s Nɦ⭬~͸L@>al�^[ -OV).ܾPKRU'>{5O@X^C*R~|Jd5(%j�PkΨ݇:TVn0N|w, UiWB@ WZol~N\hKR6cry+P5I*nlƠ>uǛF A5j)ߖ|k)xM2al-OMȭoVa/2Inh~$OVkɖ&ԔBDdMޢgψ˽PZmaMP/Z͈/(zjq !.ܔdB?A Oh{lvm3V Mm+߻.o{[7<\u-KηnG{`[_ R{dps!ߞV<־˱Em?y7ÊAY{ VMַMYoj[~ `0+VIX^s#Z \s58n'-z۵ѭ-߇92A^v^AĶ?AZGMHDe˵-lo#5h"8Hέk�f=ᡭޔ\`7A =bUp\{Oԙ8&BK@cdqehoǔfRX503nP N6, n# 2>/g I( r3MWic A`r| OveLV;*QnFdۥkʉiI`Vʭ`2%a�U&VW`WWX5\)f7*rUlmH(b۰Ṽ!&nʂ &6w-_(q;Fl!F6O? m?1#-"Uhk! =Ay߽=^"F@ i2l)e2$}h8O�\Щ.=f$3N'-K' C3T-eFIs@{&ޝAxJA˄e thQ i:M'!l,NJSh$,{.R$8Z>-},7iry+?mɕ8WL���IDATFkZ|%f}.MM4ŇK%9fK >şZoӷw0} Kl /܍?ŖH/r|@>mzZﺊfo[n Hf Gvrk#ޑ ֌k$3)`FIs'0Ȕj@JJ[H+G[-wA#-$Onم6[HH En?E C�8Bp~HwUfmNJ ܏ߦ1A' tד>Ƨ<<; W@fW8 Š=2Z$k-P2] k9*.õᢃ鬖iW-;vIMNvv lZ߂˜ab4SDœWns%v|ƽv"= tr߾gV³W]]9<]q%lW.3My)vvnu>Fxv̅}Yk;,i&C_w喖1LV _$cG> �A)C1@ w-+{T.;GҺJ<Dm Opa!f%m) YH P ˫_ޙRn�kuVқ,L+ MSx} M[=4nnB2ĀF~):@:á-d`z`RJo5$cI# IhZ$$oW elHz$!z4D[ےC%HnkZ[# H "8}@P<w @ -A�{,|Yṫ s1` #�@DS]kjv|W1E'{=]Ҝ9hE"q vi$Y<YPu׀ZU,j%U!Uvc8̲ O OTX_@w43y]8&9i I\g+*fR�T r&ײĔXM&P:obz<ZD rUk޿㽋ͣ%r0nX7</&dvMA^}h&m.!&t CAm@IjiN"ɚNP.~ߗdx�%:� p ؜%3� H0t= H((g))I<5˓l@&#\Qe0`@z@a9)q \[Z=j۝ecdRa*u.=,v0r2Ϫ]Ȃjw94- i<9`2 ]t;dvD! #>qd,ag^Kn $ﮗ2EO*K6/ jerK�HVPLMNAHr(yeks" ˸;㹁{6!U→$Z/` 2N2 $YBI;N A;):I*uNB] S"^wT;pz@Zݻ]1ͮA;h 3[”L0"KESC|Bkgnt,MfwZ/.)ޔ7O\cژ'}r7)YZUCSŎו!ԓbo®1#V<kO%HA*.0d}~^>ro*S[LG"%uӃF a\d5q{.Śߕj0{((ÁWpGѦRg[ BZZn(�Ͱ߱- /f}Ԃ48$ k*\֙[0a0ߥ.BcyxB+%l*NiM69bt3H !az&Ь�d~ȱt\&ud� z*�\]�Q 7' zr=&"p \XƗB*,ϵ+biGg#/P8�Z+UYM|\\yinVN$cY1+#d*^r24NK2G.ݫ.U"I=2~8Atlxe3tV, ^'gY*Y3k JD\AҴ9wxxd&5+gQе0oYyd=w ,mXg 5l|ƚɈ{f25e32}3 uTY98 mfՅ#y<X@87TޢNZ y[O v ZJȋ>>Y7[dF_ '(L,cuk>O>Lft97;㯓%WXsוmk[RztcsuYg͙EfY #F>t:"G#݌ [{{}حV7{~4UѧH^3/jX.~a׽H".X&3RdY/8%u)R*drxt %-3\/*%T~^ P=<fg9 3#!9F^'f eR(ƎXFf )ǎ>-t,4F2.ѧt뽫Hrg$(J<#1/ %2K=k}\%Icޘt$//zHI9'4gM\ZG߻^;~(LTg(YY{6~s3a9c힍@Hϯog3;\ggY1pBȝ79kugxg`!֞Qnϟ|k}t<YQ}Ti^{y:"RH?ߵ_GG6%l=}84rZnˏȳ؈P[돖x (82Txh?{/R@y,_c`3@ J j%aqFXQ9@X?RG@-%l%@aAWd:s,yDo<3a%żǒPr2+"|qK;]aK7oО+lKvBY X02A-5fxFMBK3#0E1>&2cz璒Y;Sd̓Lh<6F��L TReهǐRX2O+F%SdRV(w*:eŭT_$<A򞖽p.-bόe5WB|w+rOB/ݩ[HBߥ1+?8{xcw膪A- .8\|Z*p= F4_9rtq= mqPJawݲy'A&/pe-㞓-}d7 U-ţ8݌-r9@dˮ=d3íR+(RtSv8Yd_@d (gKQ[f~۫f,\$j(`ILaX/S}2529�;3>2zY?Ώ#1(Pyl83p2AJ.1s9�A,J3eP&odK役{r=9= \gwW>}Aɗ^ޝhd+l* ؄ojژVF0nu@)x3ʽ@KY=0ܓo,b(ȯE\{6jM!"Z  xT ":v(HW2%jڎt]P{ lQ%Hndl#݉m־Wܣ(Tb,+@aH8SzFؤjgX1%g aMk2YәP4Rm+ .lYFӔJc^''aT1@gB=*�GTVjs0|A/<@<\$BR?~u=8Qz:�<bՃV$|=v2!ܐ.dL)/ݳ$ܩ@/!\.g2ݫTHi19u2ͦd[A3:o7"+=Ct'@4A??H t^?@� z'ˮD:@繨yV}��ANWOCH月v԰N]pãg胧6 :9qE;uN/A ѿBRٸ!>Q+˥߬@ kUĝ^ă>0! bm Q 苠m�h*FՇqgmm멆>U_7yo7hs| (AR[<iT:Ѽ5"ZT"/@;^%3pV<.6X+-/A&0Zpi@ @<!L \k/~k @( P ύfQ>c‡sW@GO9tws۷-9!7/88 p njBj;P`Κk6TgCyw 95Dpf S|"J�/ú:d'Wm 2;>>IGQk6u%W߳mN)@*$`pzՀʦ0ޝ 9hmہWz7jfc'72ƪ[jz|O~[X':f6s2@o$foiiR{Y'-n<KԜ2efzlNQ֖녠qT$qQq|}eycq͸>a74kBM*ćQ:ח7ˋb|YK[`>rUs{qqvp}s,tR{bpb:ȺOxo:kN5l~ {ǃ y_FK֖߸D:i^glc`2>Zu6-$|}Zze2P_xnU֯\a`,㓃J]*mri }A0DĠop!>yb)> V @-GVoU^M(C`p묅 !e`�*zN<!zVkqM׼�7 xTJ|'nБm13)S_\qq!ޖ@CܦDa&̮҃\*F1:IvxO.x7(gN^ٹk5@cov5bVl.{ ZơݭR`RvO 6|Ӱe\ P(nq]Zz# lF*\FWk.fU~ aa#oD'临"*rmVshv7X jF \j,D]D z|.]䫬T77ԉՙZ9}ٶnK ~m mo_/|ڟs>W7hbBJaߎir6v-p+ v<Xc\̢ O'3�z.mKRdMo hN:fK01 wA!Ęu!m oO\R&?󩮥RnXr0KwN rMCl%>lξ O)}뻮E~5_'uu)'o4Cd)$t=59ަoD;SwCeSKWPޯv߾|ۯ_X ÊsM' `3 LV-(� t7Ἐ+(82 .# ]p*& sRN.^A^WzޕvK凖).ft7[.++@u쏑|`Ǡ9ӏ}vr};]<g;]v!zeE<qVq{rKNӷc۲ԝG,w s~N2:dLK܉˖.vU|znmT?<e]z˱߉ ~mHZnf !>\u[۟V$Aun;U}/Az KC j"r!qtHTDJ\bbNu<n(y dEԒJԒDupWTPhZum0,M$0 o O(? ebٔ8fDu F@I:C H؞f% og@EbvBڕrq@BdhCebgm�C'P~;pM?o  [O DNaBaբu3Ha9F*b}SElC60~IRMޜI5x"<ٓ$+X.8,yh`V'$v¡,E I:&Sv\O$jŚR#o K(6$\0A0�x҆O/ 3 +T4JMHvrPq_@{@*)CI7uDpJO4up+E.Hp%^H ȅH`Xm.xLR*�! d@Ol:I&3~Wh2 m> $/MD,N ~^e8P8x7n] ïbR}$J˞ m8 />xRcT7J$H(.4DMHՕ#"jG>.7xX,໠ޖa13ʬCzG|ʉnN[nNaߑ7pmZanֺ: zPJ:]#MR*B Ue!bɨ;<)6!S:'f3\-_ Dp˳Ҟ<P+)E{ޝ e:Zfe0<*`7_z#: bJ@WG׋ }X Ջmu b5h㵔Z ~ W/-W>+U&Z w Q~Wzw O&RMVKyrs$юGPDjNB0BM&l2Ofx!t6a1nz7|�6;)eZ&] +&BEa9MˊJIWI1Y֭ȄVMP�e4(S)Vx7 4@:5 ~Av@G:8g{ƀtV/n�ݤKje=D\nl|U<q(F!| Y=<2op=v !sQP[3l ^ B06I[GWpGUN5 Jć%$gxkUZWSFA\-VBPh (Vz%H#N#%|7Rm+i&=b\^ g`mU~Bm�@ ']w'+!+ jyԲhE)֞<YR_ b Q@yHy㼘GMfr3֍֜f[d01@wg{.['By>Ͱލo6<#yoNdb3urN33-r^;}ַoYs&<Yi?سs4f{sᙿ}=llx̲99<as֌ds3|rΕ" 1frzgYV:EޢC-(dt%4; -ʹ d*2ˇ�| ̂9'8MUHUt[d YNhK�L3ima֦A}fT6EWBNNVB JZ4@,6TlQi jg?'vr|ua�78 > B�e@M�)+UG!nq�=lb@Wȕ2o 10#ʙo7 92o g!1Q5s|:UG{V>M F =+:CgYu!cYo6FϘW3;{,Y3Yo37/6{F [g~,>Bΐו3tF=Cg~ uĺ=7㵼3<F,ticrԱ` F۔ے <-={5 IIQn:sǫ{KsQfFBħ^ xQ&jt~f�`(iK^�WAj+6; )Ťa[VW8DW{M^t@c@@НBYI5XVLɸR4jhNp*TZ@$Bd.G ̆G%% rl*82lc˔Xf̃Ռ̩X^ˤ~"7^̰2g2s Rwgh&>f]ķoKLr'AޟcggT4p1.ccR&0^&Y{1X/MuIy/iE\=Ngh{SY_̋$w<t#i'2 �AB9*D"#g Zq7BPfBqnkAm&դ.J9u@P SQ2�ŗ$2:?^%e</3E(`7ϸGRPQ1IH[-$Se hr uad*V4,Α4eV3�/;RUY޼?y)A mlfY]˄k0de~\DcvqY>W[ qd7d~,ݟ-eɟܝ+׺^&/ݙhِc=n<N3\ ŸŎP =~9Zއsn䬗QP$'_T&~gl˙#r;{hd#Ye==7d a%�1G2de?s,GydBmI7c+xF fw *̺ɐm8ԒZ"ԫ'BByZen :=_Ob[+"z-z;h^^k1Y0V� .�P\@}qBSiF# 2M�{N-Y ^d)(#%Py@ k<ܒ:"ArrA -5у.+e ]ͻ wGރ0Ѓ yiDD*1#9("ng]^#Yc ] s2cSNرfjtۏ\"_Ze9)pM)N2Xz,|Og")}�~ ]^ $PVi:*zgQ*J 5ڈNv'i*r:Y쐛Q�/|WGPfCmJ�2FX'D<VBH ~U? [ Y])Hy]\ TJ3q-JaPWBγ:2y;'&LU/mAW)Ag t{`6Vf5P|(݌h <&TP;ص.wZD{  >\Y-~/sm* ү;xMӮW͹ĞjI\)sģpQ7#MdПyjUt:a7S 99Gk{᫇?omg{yk �%.ÿIoe.ђx:Amr)ɮrEUK~r&+RUlĚ)/G4.\dxaڔ`>/Sa�0ba.ŻVnW \w}KJS.??ҷ*"yB46 4aqf pAԕ�M׋80 ,A_EQA8.�N^} @\쬆{3zdt.,K0#n8Np:rּӥN�{:-)b Ӊڟ^& WaxNr+mDUN\` 3@LEՇ^q"WRr+>�":ob_)$yam|Q.w\>t6PV+З&g)k 5v?)d3Mf� O,*z7.Qw>w[[y?Te./ ~�ؘvUE;>~6`3͇qMWJSY~%+AC<z}8ؽ@.+sw_~% XͨKfn?™vip;;OklTӼRUq!&u\U޿%ǗI97]mx @ 8e� ;w0M̭i)Erĺ96Wn�%*yV^hp7ˉy_H|B9ύA+ď>d-:/ I/N;u]?Es-5j q9?}EDʖAԭ߳OW۝."dG^2.B {1 X.ɕhtW6dRZĂp >\aMnjk}ȓ~9b6ooyOn`n\wm4Zն]_`E X{>m~۶uG7< kٯyxc&^pm)N`Qڹj|bNiڷ[BMs}| 0y};VK>HpˏmBf]E=ߎ==Z hWt{ςKW &?;[;C`w@tl{?S~:ܭ| B>̼" M nwKl3ͫەʹ45mサ羕vl;v-4Ud1V:jhnՒlV`%?VvJ~3rܾnޮv->no Rzn`[iz|?I|;V:m[#5kb 7@� 31k h׳-&Yn E4&;q'LĔvz'<?�Vd;.2aj} ]7k$i/J*޼[oGul/M/>킒VܾjzVY#E4R&*އ1nùc VM~PVQ ʇ2vfiɲ$NB-nw3}KS`0G0}n oF4hE[ymX_|ax_sE<!M]F;~4zЏ=lü1byv< %ws02UA|y�-7VɊǍ,u]^-?hj'#??ly޾rPak7~o@A6T(s+/ 1UK+G&s: Rv ~t+D߾La9ua5.-DJ[ AO|CX_|a0&8rXƷʐ[qF݅X?R ? rޮC"f  Wg~2j?}K CkPEn݁ bBV$Mh!'W+QN`1ބ/"0|i3ׂ)1CVwPBFaqQj>Ɔ(`qLuXP; T1NV_ Bхy&h :qyBeY#<W( DjdmQ-/ ?K^Ow? | sY (]t<|<kG 9uCMo=T+d1ծ*öpsXŅyݪ*em/(Rk-(dwk{ql.RɲZu('jF1Ԓt%aɖ"EW@ :ةҏ46ۿj]PHUsİ@*[ v=PHǍ Vv֠+e |@HezɄMUg䫬z{&P@ }r{&.e<JUjgtbͮ<V$.wa�[{JKzjX";e1<�/Lv %pۉYQ~[$ _GE si- uMPPymUE"'qt6Z#"4l˃^TGl%3WHFT>JWHBc"<>!Yy܊s rׇ9kD~zaC` Q]-Rhoá3;[ EtxU@1>RW۰.}4M}#^s�*sē�.nd7sTBU ιdpI1W# ([LɯɤY61Rbu}B NwIsg-䆰xJ<s b(AmZ U9C$sEb[,a $Џ&@\ š}+n�Pa Jo.u:DFUFD KG$ Bj!sUr핀t0 N{Seպ𼖼JFQ}7<n^ۃJgPG Y$abjQ8Ez;9cyҫ"0%㓂b>oY4&wsUHGSqؼ$AhU\ 7KID*U<ϯ/FS+Ԍ S2Qf] ]4irG!\I(9:]Sss&~{tڦg:,Y.@)SWȻ1x Cd]|rYpvQ0΅SW$^1 2$b!4l{�jj YP8FveR- G¨UR#0As3{9YS�dMr5zIZ߹aыMkA}5Io|}V1-IusY�NtH*S="b:`Y{p`\;u eQߤ'q( @p:�B.rÄ3�ӽu:Ο; htoj/ۏq<n��h#xK:֩F1g Bm8~ջ7e`~SxtoY4O0NI+MBhY8%vd ڝnɌ^낡2{KgZ{-3]nH dw-U&]J"xV(AJr.7 D4o/ (Z/R$cKNE={)DqV)P�Q"ҏ'՛9*;RSm&r/!M++Ա>jrh5z&hz۔=2E p&$y ńPqk7[MP^ٙPF7Y_Q"p (A1tY-`�Žh5 5icEFc@v@c K q_�YZ5ѿNH-q;ŐEJ eJ5{9@i \l)@ 0%�Q5h2@|Yvx)$]o1ڻ19i /O6Žf/xGv4 qyfm< u%`Y. cTؿEj}p\լ7iL: ܾI#%ʲEl @lv3od` mH#%8_;$Ñ<!%ѹnNˡt L_&zj]Mu9`�'/~i9`K2NoZ Ȫ B"/ #l8s"1" SZ0,e^�&E-~DxFt[=; E,a8߅HE`x-zT!3A J lަKJ':!ڔ-{R9_L�^& jLba]FP;i9ˡ3b , ek@&x癕J)ƥȲ @ek y}oՁ9+a0V:ʝ)/ 3/AJPrpB(0ƥ�<ZalvKhN0~#]EZSIhX /&-E{& r/{;,n�:9H"\K X.{\,ڢNb:9n@" C ExZ @Ї @ d疾; /q?~gOmeղYh:z+o‹&` >zv)�}<XHP^ÌHuj]q,Pa |pxQS/1 <~s+|%SfjtPnz tvTʵ. ԓ@P{X*_lSi0v_drkp/ Nin _m�KUrAu7 5)if �7elFΡ(9=AoCtٹ+A jg hoDsr/Z.³`-!v8tK^YD/OLWHw0eİcU(U*�DT;ow/n ;@)6g&MןÝ(sϫU˄pDDJ )򎴅|t4_7=.hLS�w\ߗy;;:d@4a@XDJB4-A7J̑ÈpH >x;UH ӎ |or9e]t%D4@W ;x;gѶ(A#zD:pi Ua@_q_ ʲv# ;eh%_"ZC14BƆdh9ld g @��<w5+țUmIOnD-׍as1X :: Dl'ګ4A;oq` 5G㯧@Du}UAVQb0 ޓu WCysvnHo'>AX}xa7MJ]4m'W<W6 z_}*P$@| "Ѽג�iW=0Eu ɨ4菫iO?u�l^+b,ʥ{(F]+�FK7͝,eA!ˡk;sje<^?;^EU> xڽxP2{ك(T�c>VdyCԭoȜڐ{X$YvetSs?F[q|zJ( Xg9E^Ǚ.g9{mRF@BfJd fDvPUlrm05\{uH,Em%;C@r+ ߳D+7@^:EPm54Jqcex~ɻ{\=^/.xM^jWtW̞n{C&sR$;hBKmt R�V,b@Zҵܷ$I1gbpye'(%'gwC\L宲ڬ~asͽ-}j^c5(<K ܣm X$ߨ!k՘Sl6HA{UYx&/y`7'hۧwn϶L|tZnȎv @+sb)|nu+ ۊqӂӷ`xR9րI\Em<V8[K~1!765Kq_٨h+7m=?h E0  OpA>"}nA|dl,aQ &+\w%7WzcVI?nݶʽmfގAmv;ʼnyǷJJFupݖ`wA: ` \Eh#;R=йR?B$3= a\P>8Sq=|h6ݺ2׃]OT eq=E4h4XMWQ_g V.e `].,|Mqg^Ao; hg.&?vbގmn[}msmq;yӮ72AxSy;Vx\gpe&Ц~+V]nZm? j3_ b�.^ @`!�D;NAKx�KJ�T5X(*sqӾL-+ <zg[ szܧAQN.U^a*XV wq]{qR7Lċ@9X}᫶~K1A(S>*$JÚxBE �:AA`hwhgEj[BͦhK{:Pۜ|nբX Z܆CĶMb'hALys]B  FF^X[CL}[}PmsoH~|k]<@gfk*v!K5o=LPij)A8"2?3Mk52oJMLy ;`QC^$hsp9q"_ c {5r'cX�) %aJU,g>F~u^;[HK+>۬!c%Q퍫zAMp`CG.ZѰ܋kwۜx?q}]L&c$Z1}!3 z˺U#rp�޶mBTe@/&b-X*oXv_#CzGmlX??;-ƠDjNf^3y)Rb;!2dD@0w LϋjV@PqkK/1R2J )r5ZXѻz[fL.cyc"Zq.3ѱVF 6 % ~c$XC _䛥Ha=3j3V6w=/q8rwr c^Z"~SdE.4狢9]sde:aXFpAY yQ>3GI`0ͼU*v-f`.ZYQ&SڞM Ť-0TY 5Z@ gmh܋|Qi̠ E&R-{RPTS @VtVxnąZ<_9 ~ D@}r..jl%Jb"{!T.BI[/EE9 /1h`]uQw"c/E<9"C XM`g=C`0'b{χ7h󴢿@^}A}A׬[g(R_`//ȓΰ|BB>?.?'/ Gџ!,_}/ s?(>={}s?Uڏ ch5 #0%jdN?W �d2 JHK(HZ%!ƆM v"Z�=('C\MaMrK(R9zO&U\ e5X1t^Ҳx'qX]�˕Im,B %r6g'SkE{cd*A,P>yd24l@&૫]d~f )I\Kx ֓V…=JnLՋ,<dn͸--=k.c 6x][&H`g=0w <Y9q2ah_eqCx wYQ.BHSa}xwܷˋc #dVB Gӆ9ImJ0ɣIO}) %YePc,JjԹjBAJHh^̗[&yT*T-ߎ¼oq+_W&qքQ"Eӊh-҅k:", |5mq+l;Y.Z 9NIXS Vړ?΢RN~2 @mF# &(K<GIeaLE$K%':$#TTJF*beI#;H:XJ@8ꇒ| َL*5u*ëhU7:㆞2`rTMQ*H*ӑ`N̄$ɓ2&g%)&:t>M(YTlv+ŒP 'J4?/es# /AkPN33Z ]>:g i\ % hΩD]5�0mN؁Y@<QI\֥B8TZdHRhŭ5pĕ;<U^? `T*>}$ZYv_lMZW8 }ȼm.4tX[H^W/~?*YBJ6[' MH}.aԅ[oa6ϳ|H�{b'<vѺ[yF;|4Mu57{>{8>keP:T'{xX4!{w*uؙj%Ȝ!)eѦǹ8ϩ^*R%-}~z-=< \/p9d0!APW~-^$I:+e8F> $ZZ y (H >2]+ɔMӣ ix4SNU2>-34bt ΖRyq]'] 2VFX #W+o~5[k kv]yUi.㽧5gjkݡƣޣOI�I'"7%y{ln,Q1cͲsK*nEf15gպB،Υ,K%u)Df%2c|fz&E �M >=s&;3tFy`iLx: eβه(jn&3%rF;~J.ԖA6 Y +92(7k'K3걿||oc I;IK6'uW6pslB'CW i;Wy\ꌏǫ@xl]%o#Ӆ gP=3A-B'=8<Qm(6흗xeg?Ϭ7hh曳$wUOF;À?!�f?&cˎd@Ev6Hd% Ei .*4Q[mPw;}!]]nUݾwVVN(SY45/{3lfeWvF2ɷۍY%4oh4(i#M'TRsa*#3埍,"ǗXƷZr[M?{|&-0MojhS+ <7=%-۰:"BguP'yނhw9aN99G%աssIDoo�ϫiqrҋUuӿ'IB^>EN�3褌p*zXUN1 1NNIC%'S,w_#<} |"8>ɪj`4Se$?$Nn˓Ih^Ehw"'GU [x3Uˉ 22A_̰ಀ )_>v&_@62C$By#H5q~�I@6ᒇ[{e}Υ6d$\Rw/@M Ԣ[rUc.(nљ2Fѩb'%yMWy:*4LZe7 y $Pr-m? Y̪<eYXD+D sS`g)Xu;-B1^7 `*TnZ0-S<V9#'WK <?+ y9; sلDԶ]U`B\G|=T?f^+S(Q.;aaP>%؛ *R>^!Z;"*塨>+=*/x$F20fgn̞+Yd]t$1xK}>/<~y#-vmmloH%A%rq%c?op^T=,FxVq932Y<'TX��T z4F@I/_4ln6g(SW[ǔCA߲@(>-S?֎;);`tSZ•<a7b)?5J*"^@<nŨWzqj1#n.F0+e%Ge޺^_ԭϨk_Y&8A-v<g]qO`D񎯓":Xqw'~#T*>:b)60t_'-%E^<}QU,>鳣D=1*TQRx CG%{ ii1nz#k{A"dˎYLMv% Ɲc֭U.eZƛE VW-ɘ{AUhsl%5D~E?%:%iqEw-e&bz[rEॽi &JLeOx|mίȔAgڟ!4O<_C`QƈSԆ_#XH#]SlXB() twm@%}:c5Z#*SQƢak`R[�ыEyuIƥqܓau/?B0sŭyGز·8ijmnMe@D[uw~[6@:SL2n Oi!WO6K}'^@E&`W{㶷\fo]кE$_4>g~odսMPǸmR7Ӷn%p}ncz`M8wIQMDkЖҺEG:7*K[$mT/P6.أtQ6>\ÐNݖ VpY 1.ny wL w|/xQ#ڱ[Wx*Z!6@I�#.9O$67�SC<M@_Ǹ !sr\k@-Ay}y>d$n(k02iu&0㤐 ^KB[_1 U 8cxd,j Ɛ }IDCz ܗt.>6>q]IޠS7Y@>{)-)fY\ŷ/߼zQʡoZ-է [m]j8ԨJ(D[ gϨ`8#쥺-x]ʆYvّw\<�~#29OG֕J+ǖtc-ߊ,/IsŽɛ/H*Xs _O]�L�&g/\g&Y(,W�oZ|sat0k5uNޕDwmp g/9*0݋GshxG0b&Ye`=8JIP3|5 d~]G\pBnAx/ {j.&ǽ fi7\f\g20a|X g[vkĝ~ktBA@TTҺ(z>9䆧;yſ,)LO)r{3oP8>zұ΄E*^ +Erۄ#՗<4&@F*q:~\I4@(@oW>@${+ЃWw\a r=pO@C{z{)t>EZǣw}!V *|`Er R^.P7[a+pAh?܁{B: {b<r#%lpË6RC?5|�5O1h: ut‚E p W={9{ [F.{ )EO*|<`6<07:\ >~r+y1{ X_. krk ‡_%JF_%o+.FY5ab:5�j&c/p}�\%A.a{n۷ )Le}Bۂd<䵡U|`!-PcY #.?ئ2n!ޢ̲ 1&e7I #qeҽ!^3@ xvLД7A6�Cpמ85B.oDNvLXHĥ\Y6T˄p|r߁%.s_jЍ@͇63rd}9Ƹ7�~aH%ޏy *j+{B0g!]P'2|et}<dy{-߄蝲kOxmQ+Y5. P+`5 h##X#h,Kn-u{Nw{8Fysxlώ,\]8`,]f ߴElylV93iv;ֱlFg2L[2Ub,>'6/+=�YUq)[bY`쁣-SڲvN 4p+%p?&ZجCҟ'>TMm|5_lmI 8ծdꍷ"-y2,gc#vi= ; .&$ہ|& cԎՍ[R 4R{ @߯ #hZiya&b-! Ȑg!: Q6$ԚǗnq@-ph h. =L ~lKX;GrymMv1Bi[mv� -R�%Mrhz60A$A;v^RR7eZ_Ԕm *Nl:@ oʳp2f[mUh-{^JH-;PoKX{C~5fv6+h畷Mn Š-48}*cn[:C Ϩ,|MvbgwQIi?/YHLh,x;Jo[T!WdBtޅkn[M|m|*MnhQf*@O1j)- ~*&@]g6[v{^avG'c0>fO4&PuAE0Ͳ5˦T_=p LZ1f*B WByRg&e-F;-Bo2S1s#b?"A "9I& 1kwPO2`$:Ȉj[c*Pt :)ɓ<(>"Fgqe ='#A:4D ҸFf ȸg(L]JG@oIzj5Y_:oJM(_(- kETy@;B';N3+ZAqçvɺ0;]LO<6IuRn20-Uc/kXdBܐ{REVPH1AQt4׶ IB:tQ ZA&lR5D8r<'w|p^E"C#l Wbu78s e00m�/|g23@|D }mBSvTgt6�9%@M8:>8:'$#,rQ~y&x�#c9],w|e䫈`?/EpLqs92㔮f@|c{@vD;6:Sd@r ȀZ r#Я�U85Qܨc5 R$r bδu8#[;n+N?$J0I~{aHӯ"WUh݉]5#@5>B˒s=Tr@_H�W>Y'6X<C~0s`-nC} N"2" : R�5bnC4x4h#rabpkri�Fވt fۍE>/`B־ %̆ڐ\ސ‡1qwr. jZkӄOFC ysP/@yρ\FJN\w>RuUȟuF>W.e מo4l#VXu(26 .D ڀ.t|6A#E+gp-h:S96\p4ݭohmMƩ�aj2C s�KGy *MƵs-[v|vkptU:"79ߕXn܁Ff96g6 \|(n9f\)93˵r"'Vs4{bd�4r�x_>svC%.j9֢k�Oܨ/.ϑpN͍�x+ӹps_o($;ĆrJ%Ut Z`4er3 zk%r�hKA`77V"@. r1J[\2WnH4TET!ޢ9KRo^I�֞2&JP@?ʙՠ%{\�@�|`휛3ws1Hj& 0{|eBi69lT.͊T/AU@c݃%-ڀ0/`2Xn?j@YVn D4azwFC;[wlu,(Q6D*ڠ1:ۘr3,_CiuyanM-J_=r jC3a0]Nթ@,nױ:f'ڐN;JD$:Zf;N|;zZt#F:um3` ;duZN3Dfv0":'@/b VG�غ=d@̈́h ?2"@c^dV0BF G},Z�.lw8:H]GoyH'ڋUoAd( #"!wuU:Y9#s5+] csX~2,b'އazL`"Fѷ:F8 bj٫eAg=ِ!w[|F,Re-hqYd?-}('[7,Ghi ɞ̬eJu6ԐFObԹ[IyZqaNhOTOCB/V\*:PYuҧYu9f:njՐN@R=B$gI,[R>tK "W->+-P0' p|׬yyȒ,J=" _<Y`ǙZټgZ c]$Zq9}̺Xs>l"EXQׯZtg: }Vs[sQ+6/N; J-2o h+ c6+x^ȀEu{+ܗ'=Vz.t]^~ozN/uzI]h8ZYWەoHk5`$M7Vr]Z+{Z+Mwտ_/=vݬ1̝Nc#uO'N= uiuk`:]:=?\PRVD.û=tnuz@)Hԓc^q}m3ޡO/)W NO'=�wm,[.aa6�׆%uķO OY™-v=7k'i 2+yr]8s:;[o zc7>umukX?q.Yt/O?^g|ֽzt(h݃2k5l];XWaD(LѻйRjqmNẩq( s |Q/5(~J+ R(+k"0p7(k��,iZ\tjM\jI"z Jp-.Rwn[]kik]0 P2SnAރPw\@W@TOU"A|h1hC%VQOQkˤ[7q<\jw]`p.S~'>@ZҤ$ O=g&hi1 ;]AB״e2!t:eݥ b~[jGT]gH=�31-O D<ꫠHd(] `wzq[|WSuU0Sjև2~m'UԘ?UF @w5E'jZݫVj\U*y*[1:=z̰ vq] LwZ&011 d_K;<L]y/zei&AJJ& |_ ]? 4 ]Iոj1-UꥡE:vP{]G?!WnZ!Oi#Y )p35ŵmERmh&!�zɻfEeÈ nh'#WḦi@Q_Kj%C/jBb0g5yYk䩦k?jXEyٸ.}yP}Jh]h'DeڞAyU ndbJU _Ç5'{w~P! DT�hMmax|^0ː Y[9so1%D"U@Ep< m.n<,E9CvE&z25y/zP02Ԑ;w@ս*>7|v lGbY{7 d&^RD鈦+y|݉*nT{OuawF;] 1A.(hS & ߙAx =Œ EK"df!/4םk @ʄ޹UCʀvې|4󞈊�&' #‹D)�C,±=G gyt_ϋXE w8̽_Lz)!xX|s);bA:S<Huѓ_g)^‘w~oO}t1idWd! Pk&3xs#o@VW@GڟwwxLN~ʄg':GR#" e_O&!rsw."@/&~'e )q\L|#y!u3Z!^ޥ$2&/@{:UL%2@9 ceBϊԞ"sp39νp% 竀/o]a ŗSBj?ds_?z߿�YRj]5#k? Ǖ;?Ý 1#;pt$ƄjgJ0gR>Yؿ[<a{k}J}>>cZߋq<xpw6V)�&HryB:F0H~�ӽ0*Kk%pKH6v葎! 2p� pŀ}ѳ]JN lk^0{WzW0k{M6T+GK#; 9wcd7z`JzЪKpz1-}k,>+px׆<u\K F~X:Y- W=t9O$ ĝF-$"P.B<n *Er ﹂T{Ź"0Zб9Z|1NfO~Y {9ƙv쎆~tͺi?/σGo}H)0o0]| :{gA j9<};�%] *={0뵠qA\FZY{+qU HƕP8COW.j׆&cힿo3@Y0B�c/| rc[/-+r5 mAkmn>nFgӵ/o ]Y6vr`wR[ W�em`(G:Mn݂1 =?J߀xW%Z7Γ]ץ N@ '+v88r5DŽޮ @gpe8`Y^q%d,=&Yu& .u#;`NA&>ģ-s_:d]=ǎT0Oi`'ieH˳a9F_ynfK,aOR3HyI]^kϱM-v}eC݌1&D 5h5UI}j[Z8n p-1 踞 1cmYhmé&n-`,Gl)6j>hG?fyѵwΛ`L@c:Of2Ҋ܋Vd3; E TcOK@saW֖0Jy9L-2\F߂k6U&rK30.2?!G XlePk9M8amqmo8_0R[nM&gM34ѼmbM6{w{k*Mi]iAw)Hۤ6o+8߭?mҔࣲdJTV`VX񧞴w)(Y8i[MQRxf+#ϝ!L;!8-~Gy 08+[KW ,@vv68NRe^69wn!+h1-t;Y&w>^9/=iٛ,9/ oJ;[gр&T?Th C&+Me P2bt5JIGMd2FYM%ZC9`S[3#c.(!3<<Оk!76M`ߪcA&k&ɚ9bz6iLLD&F ǩ#2ɚT|<)UE:I9cl'ՊſgrU<5&bkmc̕z+_6w%]8qA܂14A:U3;J[T9&vΎkMˤNtJwO rB軷dcJa0׾ŇN[#"svu`<z^ vuZN3 i*&wid؃HpKO&LF&C&(O:Luâ ~& ȗ$qsKEsf;3e< xZ<@2\<'ORǵ!ND!\a'dM$nZfA`0ԽҀ7s9khJ WpZv^0?չI *$rbRC*SSQ \ ȎNyj+=#m<P'kHzWVY7-UW8ūkpے߾:XpvBT;A(+^#WߋNѱӥy0Xyr7wWC>m9}I7k䕈ƼajNk,UےY^pk嚛ޖ>Lۿ{u4HI\@~/7!-v_ڎ/~v "fGC0Wm PxPҏ1з6tLm/rDa9D'G"o E`C0"v^[_ }ߎ\a(R EsH7&Aņyꪸ]}q|N:ܬSh$8�b�h4v7joaQߜSq 0C%7zϝ@?Dg;I *oiN9Xou{Ynpweh9ʃXsl>P Rƽupi6;zoTekzTз]ۜ[rx39jiXx=Oԣ ۯ]=mHPNNZfq T9ɋ7f|#%Bhq�3 Cr fP}t 9~Ô�;M#jnFhom.q3rdwopZ^{LM�b 5rDCo:n+oH 6MV]}% GxH>Tȱks�4r�x.s;sT&g5  y�܄<9AIz6p+_徖K&؅g9 ʊjX<X��-ط?拹CgZ<8}l={ryA -z-Sޮ` rׂܔYd'r93gv^i_du9퇜1RNd\&+~3OS=YABhy y\k%hMKiq1eiSڼُ��PxEUaȀ1ߘ!g� U/ȦCj!l@[n G 拲.۳}�@aV`L9~~[ սygYIS\eڲg@{ƭFD;D'bwGrHO=3T!q)n2X:ð%HmqM 7tqʂ3OsZ]W?:N^V%Z)<@=M.w~R/0 tQI]G nw?A{Z9te0 8O:*?ka՜;:\yh ŹC/,@?Ѣ|w<Q S4)c*( 3K/%T()>J[N))|QStJ_\*{eVS`�FHsh9xAؤD%HU1,U^")KJTTũR?@:6s(l*Rf$w,C}iR^C#<8#}>'5>ah0@dϯ{}?+ jrol~ÚMJ@vǯ">r JXX<P'Н ?d+EYΊԬnUQ#kF wfVpM o 4>ٝvM]\u7+ܝăxW7H}���IDAT*$H^аl%+ [[YB^wa6,ͺ@�ל ςFQ9 Í-70}A? >"U9_d?4P(<GNA "�A D(|<RēA@[7 "W0 _e%2W\DHJD6g&09@" R$-Or=v.]I`SיW^qw` ۋ|VZ'wN)MG=3i]:~Z:]%އ[ VvA7Xk.Nw:YhĩtTD޵)wɺ'N'隹V8;%;'!{)XzRr]}x7nZv΅Zgo';O5.I]!o4퓅72u_yF:; w3 N_oS7) .;FJ~t*$�)b$ؔpǗw4 aSH r|L J!MJ"-?Y2&Ŕuā87 %Aɞ MdMSLpyV{[i˂lW>,!VO]_;RN/[?Ҭܕ5i?}+w1v+HUr3EdpKIZhIՃ]5o7wz@ J&mt]E(3c…Vה`調�zݚ0N~ `W5rq4m \+Ooxvg()4ϡ]ݷI |{kAI 98�TG6x]+>W| eX�=aIwKZ] !̓/zs].Gn px,yl\@ݾэŀ\΋]4] YP? B& MϗF`]e XhtM C0i<2Q:! ;Z[nꪭҟX_U3GiQ&ZTGT\Ґ|Y ,\Ԑl? GKCdU]>Z8%;o]I s^4My9Hh;\+`ĆZ/h\CfߩE'9*3"Z2M/mYV _  yUen/"Xdo9}38-ΙK7 Kw·<[[Ҟ7=(GVxS s[M&]Tֹ7[/ >-Hos7 iP/s<r<ު3Klhi-ŗ俄s=jx>~E%ѶPZjE-GSjf֚y4 `P1}j*u[psȼ'O/u.e)U>c|]U#c]aTey51$LU;/{ϯ:G?n_W"wyт-7\Uc\WY%弼0x>Ŕ{ts^2^CO(<:; ThR.@A (QEMw)_{aޡQ1ޱ%ma[؍su`B!tclKyn0onl[Pn WRXm<ƚonp,ntLlOC@{EH+AeKs3L쁺pnUqhݿ�tRu(zI*f'3CtɻSIdR#8. WJѧlJID,3>~A';7L~o7OY)o!bԎdskRQ;S1nܻ,{9r[ᤗ|H~D!5h :~yaqM+Cyݛ )xr_#%wp' |yi~u^ǿ}]I}3CN|cp;+uEo^Ao+I{buMtLΧ)RN]Jڥ)H%~%/ME^$Yu䗏(~h)ًd Ty pf �@6.Ȕ2U c,0T\lmVn#(1Pp=_̓kBwG?Kp߯B(iO0\?h+>=<{mn\ [?}^*>An, <[2yɯCZ 'Ƽý{5x~=,GzzOAJ#A$l|&/zjKhq/xW/k)ުzaL|9@?8X/hv/&� ._�T81e$XW<(bTx;y0^ j _|X縛G(lshc,h^ ,ܘ¥6֡ost뽃'`rPx=BXu˜/-+>-7qoD_!Wa`l<@cn_+6kY,eĖC|5~p1%PX  xo~%E/KZ�gvwƗY{Wp3#z-E˥J+1i&L0 &p&Nܕw#ۆ-@;氷wlw{l>4M�[g;ʯd;LlڢiL@ \)d`Vڷ?ζu(m`-UY"{F*4Mbo"5w^!6 ib0Ӵ+9{i>y0^E&e|F4Wv>%YS`JSg!RqrZ$UX!zxeKԬyrLudYkk|&&*P+W3M^8įk6Ex2Y^Ӓ{mu]u?\puS?:ֺI.sz؇\'בz aUeM0ֆ2мl{-f<C/q"9-j+ ‡gmj/Dʪ-A>t վDhWc?Jۦ5l_~{nE&f//5L80Ch WU E_j+pEF/:m+%Vʳ6vb2K!;#YE\TdbE};nVmK@:TAp8smݵ5h֡Y*$l&N3~^@s׎Ζ_~DSfi٬YV֬b8Q8 4BTi/ZdMPaElYD˭="r)6C3Il ך5}:L"c)sEX 3"ӥbhaКUySR,'ۯKCISrT*& z zLzoQf㠌{v]x_xTBZ9HIq\,K}wZϘA&$`dݠNZ}S}^yn uY?ƃ Ϳ?o[M2_vjf:MCk13,)ptUTNj_NT[{S멹&a2MmaW[u$`'8*4Ì<[v.zDLʺl! Dw<B 91oe] fq=O@ YmS '[0(&aSmv>Q"grqZ[Kn۲=L;]Q2 Lt//8鸑.BύU(,vq&/`,&ܱAnp$}dL 4qe>]ρ[睫+yTYc EJ(0@< ~;~sODEc{B4e�ڙ JOz8w*?0+hE{(YѝvW5:\l4{@$~~"_I4G0f5&~H$5}0 $p?~ulr${)F yGu 2 G!&p\5l:` LP809̓6hJ֭r2jp S(@~̕T0U XZ @ ,l}'YíHN^>Q HA:=3�km52$#^ %D;c; 0p;) t GxT: %p=Pc֗Qڏz,E3ï>yk3w<歯=6×zc޹W'+'s> S3O{,Auy~bau1k6WR[O矪i~}̎V2O"x<2"VsFk&/R'7ϕq %sdYv#p U6P \pYnm\*ϩyd@sۚQI6ʘDm?Hx7IpH-;z=J[9G-f"�|;#+/ �eŝe3s!'n]-y~ ci%-jQe> Hmox,鋠@WJ5%-e =;u ʡ^VO9*gSDfp).@t@տ[diNYu~rۛt֬!Dvdv, +&fI-_l)k/͡YTUn^D>Ա7L4X @UFq58 ]@b�H@ny�--3`-Zuݞ=^!I 6 1vg%L�]YyTqT` HS܌NYؓ9T1\vș*XpLaӻqCYuA6�*ezNl5R5 K[-Ġ=2oHHm(r.ʕ*VsʹtY1='MH8$@L lcDeU^ [G��5hDڟD.Q�&C)Q{LT0\{h?gߙnAOs]b0WKwytEyFB5ȋåXR|*1iOME^K_S$-_V 0XNi ()!0RŭF 08t$y͎.DV"֜0`A0:~bp/pܐ7-m܋Y7Š<>� ʸ%/je! s]n+gwwv2LyOp_sTJD Ct._"8vJhLז +L$pY X{ -|R$W#V4(h"Ӿ/0]c8> qootR㫛'Fv!mm$`$m*#P~(`r@ƫofu4^y zyA:Y C7>G|>>/R?vy9h3쿷_g#~P\e!r}ğmUu^W<O:/D󵼜wC,}|p:�Cf˩ pbq} (>/kO* &[XTZ`%.]t؉[ w, V#鬓23ZW *Y _A+•>Y;< WDrDd<Ǡ׿y 2yG{SR0XDk�<B\Jx<%۬'Ȱ>G##]x"n[xD6Kxk;>)YNn}8Ad@#Jl�_mzy0!^p,3:6MZLEB@h*PLS\\�%Ay?)JSj8/SdǓ( p] -@ȥvI^uYb4SX˓]. _MC`fQ\qPs?Y "2CΫp$XT5ҹ변pkZEIw8ťҽƶWjuebU�HP#*f84o9`1cׇ/x}wW]0͙/c xuwU *畬0XǹZwn['V.y! vMBL}ә<ܺ2o; n]}J~oOKvғ{;R@Jnn|2?|YLt.Ȼ2<ǻϻY_A{Ou#p0tXW nHW|gu߅z]'`L@0}=&P#j1/Cռz( 6 Jy^܇�mLGI%0T.F7]E BcBY/T:e�<*`Y\1։>z4NƋ2VUJcU�%A,|n`,<2&LSQl`BsvCv9`mWf]'ܛ|!HdLA# 6Z(Hqnfά L``m٠L0"_~4ogն0x~|C?}םN@\* le~2f `&}n> mUٷ-Vj3[yndV${znMzn;ߢ7s7OSTxK%) ??)K}S] {^1,ޢoyoPSri++ϱ:p'cuGbvNK?~" x6']NWB7m1`^d>݀Vh%A˯D<ZtXE=|TdZHH N^2Aѽ`K^ H)-ߡ"A"X/+uKWb 2} k :--\tLDՖʖn1[Z'�;0tTl3;{xB Wj[;'lE�_M+� /<2 ^~(kց | 6`v[|hZ<%~#QpTA6[蟆 FkˑQ7{GlQn0n Ûlڍ-Gn;fn!lGLnBܪ9ǪP귫ìxv8I'l#zIW`2l�/LB r-3 o0jn0A vqAyFPl$A<eɣcDZng ZL?)yepL=siiEnzoLJl6@-;oQL9s#Sar0o_$فLpX"`w#`5xh֫fMa>ӲE|$ JsH}Զi[%n@倱Mi`!b=I8 x'H ^$%􌹻dfȳW7>(0d*$Jkl_S{Kvw-8nݡO< uuW2nnc]o;Z%־?)8X{5ԕʽ-/ ,s^(V".%Tf:pOv`Yq꙱OW$ZEpL 2a~Jo 奏oH6tfDйO"ZHʔU&SnsuߡʖfʜD_^$SThp|aJ}|* c(}v|0K'^X;;3\%3< :fY&qoGAFMB*jFȤZ'ՙ O,|.-.@HWVwG_Ip:}Ԭ|&HEG&7㮺_B˾苒^Kj4Sc]e._6|e?"`jW~V-_+K#<߼NdPD]&BRV$ )~()_�ޓߖA C=+�mW ߼[exaf="LM+%{{5g'pmJmdF/o*H/%Kap(mH& iN|_}ǁ0w(0õ�l*W3960(;TDʶ\pMs${Q-+/J\I~}܈O^H$aR<5ޒ?]",z�֋{>oi,vPƗ1j(W:\ |S΁1XN#z9(n / a5 1FJyRQpWJXk<e<G,ahf5?Bʁؠ ^Tx%CqHYDkaTXp*TG~ !;�0In<m|IôGz'0DB&pNt r/"*19$2JZ.`HȐ oG&` �)�Gj|H{ $h83rK L93PS9S9.z e&g}$3x`P6Xz0g:#%.;$#ZpLo[ Wkil"+ \@'Gos'0) xljPcձZ9 vD Uc@(p,.x-њ<eԊ*5SEf`kL45vԘRcJAȫɵ"\5H-BЊ m8:4ck\dj0Aخ2̃ikQ[,ȵ59. I.\| -x2&%c~ L@:LNR .1)><C bNćd!��bp[i]ʔӄi4₁()Pbi9 ƞl0Z4܅:s+F&cSbT-4[M~|LlP|gt] Jw<`}TMiLwISr`Pp>>I`__! 6AeOQpYāb,@=Ii�&cb)܅@[:J)>Nuw&X98'ߌ'd 4HɌp:!ǡ^ @Cֱ4+\ $]Z.Ӛ! yNzN0Mm` X6 @@oJZ`DOP.<! 5$'GHY$ҷ+k"+”DLf>#Ir\$;ݲ: $ w eO1luL)i 6AB&./;1!I&`XKF`fT+4:剻ڙi,}[%qh`sju5w9S((|;iiѩU%mI Rh. fء)L' < &0XIzS llčS6%S j:4 Ӗ@'T:j{N6-02J/B̓a k \uפ I$]Bڊz@٤0Et* c`l|( <n*wS~$`O7,mJPUF%7Hm e "&{8 q 0\RI+UvV,ؗf<yiR 'y`>^\uAm<@p7 90/26@oI$\5*‰D_>\vșӳ9^)iHEג <jFK͠5#)] d x7t~3$�m)XS!$6'+Dx&=>�DMd.^@&(5ɐ Jυ-r~m]`%[6b�(baI5-`xSi|}*k~#h` -0AW޺cyVȅ`υUlAw̅U\He^,**XMTHN= 3`0'P)&8=`D⠑S7$ R0)�wIZ%c = .m1"M B J [y0�v!=P0wj4Ti((1ַoZR %Aଳ $X:*Uyͮ5ca𳗠^XOՆ)5�`9X&hiu898}ڭʽUus_4 (Ko=ci�o =QC\ rmtFvM &9Vk 1wRH/1cOӱ#c@XZk_Sj贜5!Q bng@<xM<xab.!hH1 @I]d빲;%;9L\ xWr~ӕ7~華P.w0eզc"FIsX%ar/nKm~Kgh.õ^ {[ %Qzۦwœp/ͽ J4b{|-2 9K}DI@ +Py�H( Dx�K( >}$̀ե:(MUr5onFIvY:>) Cu,5M CJ)Jjp((YBL`$PPVSR$aMY65MShU#J#._ Vd L0d743L ב>$E 0*yr'g BI>iIO:?4^&f藶�A->lZԞɩc0A$]QJƂOvO{SifLZr,�u@t,'μDOV`B-́6<׫srTSL43sh}&�#@0LB!B&�L�H-"~2L0KcAi:e:d`{a 0 ަ B,V"@h#t�aSxXa-492'L�ڻot>ߠi,DT'Pr``ke.(]tk#"lEK6ث]\"M!iN&ҩ$O g8/k'b`30W<}E\, e5Vg,T`1S&wꀪgܦ�"  �'0^0mBo lqP`h'z=|ĵzF4kcDV0k*? LP1jB=ۓƆ$~h0i0i Q` 6#m6�¾=H /T {H) }msdZPdL /_mLǪI 62LzwS@'A(MP*QB$ʥ u 0v Z+qՁ䬢$Hdt"/ɟH?#ϼD\^"/%vvgW!&(�*U$Cl&�L�(!h� mJuq(KjAa]F PֺN<M}rڬɷKӘ7r0[KS9KV=L.>5 S5-j  EֱZfNNV-#5kz��+LE�` V?HEΡ\<֚�1 zio%3�{<y1pJmdZ.`ՈE̴5-  nZ<l̬YcF xlZS[=L"q9^d%r _P%|X=X1NN%RN'SI\tO)oy'S"?>%$ʿ`'mqvn2Je=z}f\gEjz[׋c8`WAj1וٱm( ^7[mʏx<FCK|e!$hp,K'@/ ^ִ_ [%;EK=u&}$-6ԁz P*a ?PAA$@SCI�] %A܈$Ԓ:$0�E *d*z)RzT( &E1T I l*: �֕'A0z.7n7^،F][1W9qֽYvK-5qn|~ȫuRGśQFh[ YU ۀ Z &%ևAl9L)~-bs 6clS1漱;ireX1w_0JMFm7otpi ~ohT� x1AN}`410K!*K4 H�ɐ A)AX, &a�p^a2-1[lm^@i�$A �@ &U&uf1u�LX( cLѼch }>LP)CzD<M|)Dσlly!0E^ UGy1Q_TFգxbT57g͟2i¾uY5=KF%«&7Y}ҬfS]<]nƷ?ijgD433)Sv}-)ەOyAj{n m$H8Lc;d%n~~ ~?Y0)Q]epQz|0qTvZ<tX5Dd:/U?3 R'dI2>=&`IbӇha�&DudEظd( a$PB|$�dA$PiAr72{`Rjn֠ЉL@ 7P] Ah&@"C#~ Ip9dGs xe<owxWl EU$cDFG=WQiq+ƉpEBḗxHdNz:B0:P3/.l/vؐx Huu8)mPQA W34s/lNzzOl_ QhB%/ީ `,4^3$mf:cS14%܇.IL`Ma' 0J?&x~>4J=IR1;I1 sx&0.n֚0-3akHaLL&wHy _q5aB'? -zV}{kОd`3Cᛡ$Mu<Q7{ŷq]�c1X iBW8U|qn]'DBl k�F>Z'c5@EwXuۮŕ:~?lg0Y2A=uɻGֻ֬S7{#c<⡇-);vpG:rZ<+X'ס6e}q}']xPN@n͋o_={-Z+bUy|1102b9xK,VXRI'Te8qL#TK9v߱Ttg*-c]_'my'"Θj.UFwX;b^'8QY^V*Ǯg>XKxZ]ӽZ)}jw{r>�`J_ıFb\>v9Pxn|eO~sZ(fj'y>0sG{aoɏ|`dC{*\ wSk~X}[E҅@Ik �t$A BzI]$kӿU9zSl{YW{~@R>=x~mׁ}U9rw^+1g_|b{{W 4sWX%LKޏ^ }H+[V*[ cT%{ĕRR齚~i,GBsj#R?^ [-u di"G@ԟ(S㷽/Oe{^ +{ K]yǕkҕ7rW6(|+o5�uCT/{q &]B Z)S]1rV΍MdV} 8.%`]WAnwn  [pͅ2A`횪 r- 6W\DvNc ,Onxkg.]D�W.RScڦ<V9`:p e3IF7}<MkZ1e =PXj3CkhMCʉP2-<99GX+Vv1Omk>;- rVMGVPZ;NZ�AxF@Q-݀{3 ;hOKBHNokD><GZ's¥686y =_q�;eOkŦ*b, R%cLW[E-`l9kr6-}ے !F2)ҹp5|[Ӝ !2}!Z蹒kn1ʗ=ݲ)Ehp|Ϟ$B#s؛Rz:A 7LğPħ{t];{;44474=3# EtO܅Nкm*RS&92>_.| t9t$ [34IB?kf; M/5e|^GHlJsOA ,PcP$v@jA,2vwchʡS~wt=C(#`)gnkU`&nП&yM G~@Yݤ4ZOMdžF{*B͌v̏_ʍb &u^,HNLl=COɏ 2Js_�{x&3YK+ĕV;!pl x ?oxE0U00`+s{h |m4A41;eutA�YL`&Aq*5L9`Del]=t_5?@>:BЎ Tmh΄LaB&pC&�C}F9UlrM54e"3F-B{Y*kyc؈Sb^ M§20H)x[ CpUݠ*qTKؚ MZ5Rc5Y{VQך9Ҕ8<VtN73F%7`$=\>yXJt0EfeASF myb|A(Lr@R�봡=8[0ܲI 4]VIv`1B}t bt! hn޷6L,}(=G �&t &˽E&y-%Z=ݔ]a�y21( үYV8:073L&M°'J5 e4HR`ZjFYm#g~n7'aTlR-~m(sd4jZHM%Q C~f ? 'vTXzdg�Z{B&-%$pg=[ʢl?% 2%lc>,zgjI_Lz:%_3rW/)9>V j,k6 d3ӏFrVNԜ@WZ|Z>u61 ס$b}9&)c]]=-Wп!*>.Сwf3K9fNӼfL_ P�(L3�GPEsZR+ԂZlLk?7Ms&VS Gr*`R `k;@P250M1\;rЬc<Gji,2W灚dD&�(Z!9Usj3rG5g|ZSg@3m&1[AjjܿQ c{gfK#ӿR%rs73oG+re>1QL}@, 76W°Z1�&bpBuo <]K}]D6Ztŀ03Lm$S 4W܉f�cФA �Ck�s I5 &�904a43#qJ&7ttv+J6x{h(W }:**A NՂfA(X u�`I~iVxO�VD*%iY=hyMufsz &ުN h~KP<O:IL@oeg6hث/$<AJ׾]<ebbk]qo-?>μiRi-V2? A&٤H>�l䥐 J>Q1kfh_ QHF0i7kJ6o詃ƫTL M(t䙋M (7;f r0MP@`"+0&.Bu�bz&DJF� hH_5xc]tZL0 ]A , ; *4Rf1AWցKhDs;AaʷAVqYدn=הO ?3ǠV6&wc7i7ZN {6>~TзY]U,# }Y/VkƂ#A$O,Byz?>^3|&SR[JYB~]I'lGqiqɼK.b 8 za!4,dR  Z>l+/aM@hi!M N�iH }mQ-ZNDQ ]-SyLPH-M 4;WL�foz�qvKsلZQ4fPw`OҼ)\C=q=Pp7.2X%ۜm3n}^cQ 7ez7 L!y=3> hO A2("V)!�F] 2Z,P$�*F@V0U*Nh_QR ,dj �>R^rpt]$O`adS6g5y;VAZ:&?ݨ=Zۅ~DA޴~0:{")\"lX2@rbh~jNTH0 =[` #�UM=媃k*Ҵ V<\lER!`tЇm~B Ek_H<73_#(hE:9^ Mz1Q?#,zл_bZT5_ZyC}i�fvOarׂW_sj- H9ml?;`[7 UJ=(&Y`3ЯMAKvDF G _usp%GIМmtDQ wf,`04gނ4Eoڐ2$o4y@u@ KM(w߇"{&=a@A $(:M{?0}[z p ikrG7J\\qDItiOSKk7ۀ>` E·iW"4 7cPl-/a/Dl@ RZ`ڠ(/ct;P\L=[L-o|ȣ1?0;* % j`DW2ֹ V&p F0� �`3߮ Ry@Vu|. eI+6ta\/r*Yz#!tgڐ0@fq @!�lTZzmhʘzU6kFQB9K< @U Z`0]U1n(\0[=B3BD/%&z8E S`)J-c:(+*XIdM&šCf2dZamz3(%TnSJssDV_t|Í�@j{E&`ATf[hF;( <o I&` `kJ\aP`D6Z K3fA$0q0o 17.+v7l[L2,Cq dP] |_JιL2lgK[S0fAIӬ!�1`9u4칿 L�6@0AktI|' #PA9F $с )70|C1>vELD} F!(0Պk&s~T( mOsCmHMh0�&Ja$8� Kd!\]д( j(%R%�9_jw/Jx( f`$>'W9J 3c%:ԉ X]I ԇ-tpqtQ';0¡$0u1&><2>syK<Y8xjwzLPu8yl 1  z S%EL`s0ܸw6vS7. 1w.2=D8n92A&0dL&@�lSA6c&zg�k;A7Jq&K&uy(vdORH̻-t³dz`ex?> %Oh;& h&ԖyM e3yfIZjҝTMМ@Mq-i1qdɯ.By\?td ;܉I`gh4ɟC})SJh%ݛ|�;''&t͌AtiuoSS]7Ro|UPd' �0}եYK"'VYE߉CL2Aswe 4^-O'8Ws=XʌL@CyEuϏ1I=I5ϨX,رT殪\ Γcݘ}ښo<w GFK\tދlRy9=ކ)4>Oht|8F^1X^mg,{1tL:3;&=k/נT'&>v|;/y'hrlq(N<'=wxF=92ȋ ?ohAge|P�.Q-K$8x}$?!hꚪsGd=F?ôgyO,x'-Եk◞>z%~zu쾼zl8 ]:'֡5?;_Qݮ%v[Zl:tqK%^=[!>;Z9~ 1WЁ$>e/3[+)lo-a>s+Ї[ynx{tu=wz=o39 |ePoVR)% {}}eRC}^| $>7<a{!_ O]p{XsbΔ\KAj, U_yyw]+O9W}B۰JH韉++ w+9kzgЪǾz%WZ*<k@�A TsztL`+Y0@/%kU\ _BmHqT}tԗ+E�<G�} %d\ "]ҽ\pKJ0> xDb kJ +p{,>.q10@J57p !=rӻq\2#!^){ŕfS߮西V~^MUѦx{z~r,,ւԉȅڅ_U2tSZ2J[/x"Mޔߔwc1Ee{eck02tEgL/k-4Wqy/ 0Vfp{M?5 1&nQ[e+�Ea ڒyT- RvVmb<g1BX;yqJ˕??u&h;`EefV. Y0HK3c Cy-�V…J*WIձrUDzU*Uy xbժ*TR:@5U'bVaE7 d5[cjQIրk]5Z6lʫcCP+pvJ'x/߿Hx$mr=/ `^<|+w@5B0,WRK\2sFMiz~RٕO^_o/{^΍_+2A %tXk[oGOե)W.e4m>MK!".Y*0>Nzțن ;%N: E۴]d^}Mh]; HC+iG`NzP$%vl Ďq, U1dmPlҔ6.ly3Tv7/�+`gIJǒO$A/$/ vڂ\$b˧k.DP|#G Vg00/ A5ARGB^1+TݬuV7weHUz^_V 䬓WU+Njːyب^wM(+C>|Ǎ �6H#~=VgzqRh;~Gօ~>[O`k &DVAw65@4̋wzkS1(މ(X=~9ƻAx%Úp}&\ rk!dz=~%^j%a0P#zx=�B+ u.q6ZBnx5Cd NoꚇR| _H_HfZ'EYF"lܵY 2ԍ<͓z &|>i49Pׁ !9:ϫ?`J*\2"uSM>myޫgb n j0gSD 3>VT'odO:<q^N\\_!>vn>X˕n/"Z6%<]ph _bp+;i-W zӲ*HD,W5_龷1=~:V]ZSa:|i߉7�"0"JK/$xqicۗ#+7SHE(  `5ࠟ@<1Rz !/.{A H'bFh TL0l 2"_v Ľik~șWy>fd'iKybֳ6#]{=1`_eP>HpأyTG`(y{Ԗ#(hQ;t&db+YA \t8 #T@amW# W,!F&HMlq31x/L ]p q>f}8f`28!̵cub _]e\ݠes2 ;;2hX*'>{:Z Q1po\z x*0}�O>_R0 T  3>6^[� B: �ɧ0d4r LpX ή7p!4O yʌ<*[i3}<=;ˑtgdִ -6 "5pwp' K}f_ }A}$LA:Cя7c9`_L>!L?L! %kG:w00>h,`8D�2Z80*;X OENM_hX��Ʊ$H@GVY ]0mDA b@60cc_a/@zه?x{F~e @xf!dr#`Z]Nh T~%A0W}QxBPL`z+O,TD6-UDžr 92A2Dk'd>n Q�L�1A P"cIw~!!@d*�|R �3�RpGa�wb^8e̱Ibʓd2�<߅k &)��Z%vˆ�0Z/Ѧ G{@zO\| k+LQ{1Sѹx'J"5a E!0M#yUj*LKi7G&[1`s?X"vyn Rۭ--nO*2vT +DAncHG=0E%jr ;P(6%A �aM@q]ghJ`yk՝ULxxfl1+ cͶ*ɭVYgdJLQX"4m (Fu (�D5ՅDHHwߺN쟳هFJr'8#ܱ˹@rgΩS](3|v_jf-<ߏt߷vZ6@SA0A0L@ JG@&xiFɏ#>S#oeP Gt}"2t+ @\㐯P:)ߠSod0 {Z+U۔ _M N?A@Uph T9M bO3F Hl-F@$͞+=GqRlHE1 k@>#qM� �=)T<_̟.u�#f [�>u[ ֊~ 4 d/�@j Cx &CV”G#H>4c,7@K \Ƴ8"'JY$~}VN%h)ZJRWU#M J9vz @`L�r==L>@ݐ(=ӝB TcbNW U0('A\4n/KߗR</me A0TF ejc +IzH 5�:&%cV@9pxޢ@6*�0*}1[O@}&P{vЌbQ�}<FZu�XC`kqA#ݢӟxGΎ26K~(HI IVmZ5̢Ïk\'@@F`yA<Z" MgM ]@J%T*@0`X\�-*B̅ QEI r IN<\)  I"õt.j\ij` 1iBy'j3 y&@;_`tHL (cL9 A�D?_'-N8m@zIQڠ@8bObT]%8S"y܏<& ޟ(�d S!n1#K0䃤ld֘�r77@R[�M `yτ ҨoiDV+I\!vF {0)H4%ABNQ͋Y] TCpaixtzND[6RQAV(p5Ym񴯡NqQ bzW >tҕQSӦGARPQ;c(H3<)F|[|I-FijӦ̌Z Bb(`h @@װy(y x]pÊCG2x@^a:_X~%`I  B"�54c'O@`y߰A mfrKG. }GA ;\bl^_X(Ӥij }f=Б5m-ؾ%r4N?b#EGme2UJPK30PBUJ!*֞  -ԕ!�n,.$ oQ=Q H5 WV94A��B{ z& = Iq~O&У6bg*ÅNԈTHBmvZ^CLJ#!( Vjx8Nm^� ]2A]Cƍ|uy|}om"j>lөUVB^c H$YA@~PVYK�~bui>`a xh- 9{;`C$�_\%@=X> jqQ�^+ lL �RޫK_/l�d~fbN 91UYÏO}'WNqn$2ST=U<%Ssds$<? ;&N>~꛹azRx/=&J 2q;g9�iRpK\-HS?)[GSτkO<6p3 _ԋz:ԧ 1I X_Xyc.dYh6$qA%i#i̱e>h$Y!BPo$7&VKYnʵ Vܐ&D-�jF8Ovu̍n,󇛎/J_K,GLtO~lL &_X* |\̒q6bQ&&=mz:5] o.FП` ݸjM kzk !~ZtZV*#d#Cx-t|u1%O|v-Z-k_XVK6n Η;7A0[钴]o7mMV{Aܻ>*bqi 8qb4Z7$߄ 9z8Ք{:iOZAo6q͘qmzбPqո2ݴvcǶ\nmo} ?{oC54]-sEz@ 6{q+U/~ ro}kVV@ IlȶVA^Ʀ)ZS< ز_V ax}jn/@w4*)N[%x_O~wn]m f-RŅ[e};F[W7Kn?/|Uku/vV-v{^ݯ[Wzjʭa7LZ- ^`9^ ̹A�t_I _(jx=jm_|G,P%XVbl^deU 4nR·j1A7+Z9oR)}fUӐ>3; 2q93X %R쏰N;[`C ja7·&vFSSEQ{*iA94O.xZG3X5A|B!$Zh?o5[ O Ġb1[@/!xN:qeOcH <V̷%#)IJxNj+nXBB>JGJBuT§å@뉁O7r @ëRoBrI6n<LI~Si ڋ'�(A.XӗJ𛢓V vP}Ks<tͫmybg8g4C3 Eh\(ʩxhJBH6QL"t9ǣ,dݼ&oD@OP%9%VŢT0#%.E <YMz29cCf`8 %s4s6 փg֍M)cuFS+ y:x28Hx�!J/BSlg t,J)i yXBQdҡ#B#%ģ GEM e/OhGk~#RP)UiMIx^Z:YP <ZU iM%%bM%blAAFUZ4Ijh'@04NljWOɞh2ZY^a]i[͔w$khJžz6! x\(AŠr$Tu.uhFd g,0QM =#bEOA[ XM($'gSAADD/9עb :6A#Փ>ot(!PRQ¨$><7%̜$a4yJ&Y5|\`Z[lEѣcEX�Ȣv�l Dq2TMaPʆ K[A0jP)mP'�z.(:xL6z8E~RI8LCש(@ޤu`N'] TK2лݷ2c<m0G0RJD+x5$[~}5ix 铌ًAT5( x=MV@ɵ fz4SP [ U5a6#j Cw�g5$kqr׈%:~O-(:9-%$Gמ==Qc23zsŪ4ηǨg iWBM06-ao3 i;E԰~tFŌϔ8 q(!S?CbԄxĮ)ā4ڎsyܻ^Ax6UFC`|LI&eZK'j~E]ވU0Q- L$v&|  [ÚIj{iirפUC@oִ©RċG }Av@ЊrDGLMo` AvӬUEw(_E;$];B#o]H&m g,]yMDfm9dY2};!T'M-<$][W7ӭk7/W-ۏ޾�^,ޏGANY-MZx�/Rx{&\"VZ}f݊.eS>,h0"^ѩ̳.Td툮 :+3{d,#N' R5 PF .~#-J`$ 5f<(JW(| >YPab$ 0$v c '8X%*~_4:A :!7[ R4Oj%J dG,7W^>VH]n-@ $F˧Y_mN`{K0 ~ίJRı}= x0R<WvD1�VesKef-C )h@ MA]?`8'zzAs^W5-Elӥ5C4A&%I{@]`} YPt 9&#.1~KTO|(]о)bbu1>Wc�/b5lWE ], :ImCJ@PeeM~0ϓl_q$$0@ *i>*ջQ˵tAkw\ d怤p-'?5EP;5kpQu>b}(OԴn,+ {}2o'hDW RЌ! F2:pkZʔ4>g{};Kc@� Xs=j 7_P温0xr'@=�ybcB~e -=#hiiϱcޏĦ |@@y S~3Un=  B;;ҢpO! w_ud(VH44yخX!`0aY.6:{e2sGv�BW^Ah� , 1<fh`.v&мOK P&w}Kkq1g 3�QjҞWk.5@֕(NStTaTO- K“R%=�ա;~g5.,XZHq?bLnBglV6\ݼ�7>mt8'AFi<3 J^*JT =~좨 (TUTPx?2S Hȯm-[{4B֞zϏZe@ {:A~մtgN8R椄4s h;&ASp d=ݿxdK}bVAc-� H 읹7R!ݶjC104ʲ� ŕ&-HFsǨLn Y.l W*~EwY�=]4Aܿ(B=9>.{c<98Y\5|P]["TxBdh)`(:Sj/u8}N'ߊߥbJ�Ҿ _muN 0J(ԸEBy kѢ Z1NR|]ԩV<Bþ"3.|o|=[-Иp5Ð?+H|t r%?[ 0%aP{.#QliTOc`MN6&ު <N)<9qLC'KЯTڟ\z P<V՚Ph�rf[,ؠM .o\@@6A-AJ*JNFc&bkUЊ+QZd,ЗOU솆{,x397jɷGNPF븪_H*��P%Lcow8�+Dž X +`n}O(x4Tk '64�GlTo9 4X(@sFRKԍ ?_LxfgV}h<YJP~ZO|Ҹ댆nW%?\6�-:UHN*6uᆈ _0 fʒ!:50Oo%\,Wxr�jLJxQ_;ѿē}'0 2Je783¡lu .mb}3EO(`aQ17 !n wx|ϨS#vh$2 WpǍBc &*_uP|ia#y&9l xQD7N)FjUX> -}c"AnJ<[%�sR3PMIlnmBKQ0G6gs5h>~I|Q^c设пV~zU77_@tQ RxR]54+ ύ˸jӆ  qӧ+<lҭT1a0=- u_  l/oدٮ og ؛N%ؖ~veZ}0s~Rܻ>�nR s֦6ӀF 0BCu?7�~(АR[psnE/٫KnY?p*@0(1VZ5nͥ$+%c.n?՞2g[}} f;y.EJ,<as# BJ}6nKcRCnmFel7\8>J|̵e7 3W}А:lm[frv5`c\mqjןn7wM괭=WkmmX鶶~Y6#&Z6斕yeVڿ[pkeMfw ׌[&ܫ跬a]h6Bik5ljˌ_(a[7)Z{׮l`zU㭶2/-,hAsi[aMl mft!Z7{jZ h Ζu}˒Z[^[[:e-o}nYƱb[On$R-GwflQZ6-|VdҸJ m#6>V+}W:\L4&V[5 ۪-~[% ><-(ҸNؖ5]MJPBQhr\ݜk;Q.cNw^КV7}�%F"<z_eX*inz~\io>y5Jjʖ߀Ӳ_mׇ@54]kXú@oؼ>!6̍(*t tE :Ap}J.A\hGznSBOgs,�WJ'$bJhghQۄY(&!xIڔux—5)%!!丌` !\uZ&꣕OZGr[#Ar4kQ5CF DdIA)t !g ѩV7PCII@T @Wg~*IFZ/U۷7@z 1h$V#撂F ?G،Q g"+CyxB doVhOʚR�mff>4b>0I8> &Gρdwo-ʞU_@C}P7R0Γ[9P<ZB1[%-�T(䨼&ge3a OEt4-d0pBKMMT<ˣ)Ih(sPC{n`U.<=biEyljx%RbQHC a~ >F(G{,#{&K'7tSVjc HC('1F+c0$ԣ,R7E| 6١!J}*V}T=UL[6*p0dے ]Цs2VD~ =@L;;*- !<}-r}DC[k@y[a8ᦤ_/iīڌƠwFxWэ4eIl_blQ<<͓S&FߍeNzL/>El 3t$ro#XE+ӷ!s[^ |_/wowAV*#hj @:\'R(%K i50;t Y俸Nar=1H59袝X8gw͒4. '4F@ QX0K'ۚ P5BJPVq*q���IDATs}XNJ?cPc<^3V.={ב lhk^ O{521el&JI aBF7uܮ* ot 8(=˂g w}iiz֮ψ3Rwк/e䍤 Z4ڷb$w[n0-%,Juw0=I 0\k=%̶|<n%^POɯ?3PQ+~td)|G!Zڈ[Y* <&@E`DE ).ZA2dKKwQ}c 0ˈgKE v"{sݕ�x) jtwMdzPZ(OYs;ohJ@E:m=S}!挿&n}.JzA׳B@``}30"Gh۷JP#`ZҋʭM^hFtBM~,>EU~촔ŃHEZJi|:2OHeXizU߈0d K7({0/*+*lO0tbKwƠz]E=(]PŰ4[;;6a@XtOZq\(viR- !_'g=JSe ?V" ,O4%(u;\)+C@kuzU\ŭoZ( zW�l! ?-<e.E2 wɌ�d2'@R)sZ>'4�396^eA!n+.k/e�J\ yP;VFi3`5⹓-D J@f)ٵ]fDVcqobI TgA)7FYE[}MJ?򳏨*5f{u2zC׀fy]Z*\j('"Lt31JOI܈=TltBEIlMTw91CWHw?#|gǻu32tYi0^!x{WpC;EjjR!%x`k7y-d#1y7ݻ>GvgEM5;s:!'m+�߷cy*ˈΎdyr4lfjXpREϱ&uB@y{Cʼ)_$$|KpӿX0{�C׋ <&L$SpVc@<kG6м{\{D3&U 29܇ؚ0,:$g cե48_9o"΢>JUa$@&y�/$gԋ#V'</uU&jwhJz{Iٵ1d.6Z&%ɮZ 9 mDN<{YN~šЊ+>}g+hq HWvO4i~|G0RI,!7V](])zml<2K7lⱋ<VBxY0V6\c?KI 0gʅP{%V$Ru-N|Wm%vNFq_Be }o_/$P$ϵ'~ rW5V~W9en b%=c�%�@016@27wg+KҴofCxy쿱sg^V#F o#}{Ы:zIST*aqQrn{{YqW!HKƠq+/{2aVw_lݳS' nO:ۻ(N VÑ[F9sw%ؔ9.)?@JI<0NVjoE?1\M�#YR:P~^nOF<9D)ُt6(hYiaEI.H X׍N S{:Ӷ*`!|o =hJ`ʝ{. KkYH\ n^N:`6{z]>MfiN)?aC5.<RwU;^2Q4X!ӑUPH1À6JY9u(W峏֪ЬI RGz?+y�@ŪdtFغ:[*Yz9ǔS[0I%HIof=f!”LϢd:BPi44}T~WFrd5>Pm w# @ v"acy;r襄Z@y<7ˊ}&1s\gQ )J@@$!%Xh0i4\�YH#~v qfV+V@`^՝.(y]Ϧ=v(oNTs !ƌY?xmb`j{{ F�Q ,jJ@& _u5?2b$]kIa}fFm6p$H�6= W@WWsUB/yBbqמհֿt/9(-]m\f1�0vZ0eZ?+l%{-Q,V(}h�~Q:s @bnԔ,K ,ذt'iF?B.c fĵCWS'<2e�N8^sTObd_!%}  u( `?ʁGjR̚?EI IY@Ҏeʍ< q\*) t=aūxx*+5kJٱԢPG{&:y 4j~8ڨM3j&R; c6Z,$ȉY :'F& d⾡l۵N[-wyvFAvySc9_B-%FFh2te$!'+c|h`Ȭ)*wL$'wq{0zϼ1@m)'v~B@'P>"k0ɹeIqI.(l$gqS߉7Ϝ$C8 z-0: JC6y=%VV̊C:N;kבCY7tc<*RrrC5f�M(g5`9, zZE;q\6W81k<UMP;?j~߭w&֛{yG_.rvtu_s �%8#0 +8[;ZEy8lDП�޼wJ)a`As'Ou}PK)]t_jƠ~as*s&N&r&%IsO '<9�Cbb<b,kk)aIڐ^66�ߧXVhDы_E>GHǛyIuQZt`$N NI~ƇHS*dd }anlbh(m߲< , 9�V4( :�e{Cih1BQ.BJf6\FlOwr6hy<ؾB(z5l �z^\h:j'>t$??il͔ -,YƓ 4'ɹVm`+i$i$1m2a(8HoFEteUj֓[`ϙ$�#y7B4X+ 6뿵 $=VtIH? v*O[ o޾[a[1[[*?`9}u77o/,͏ymc赭ۯmS[6e~W[~{Y1-국ƭk׌ʍ}=jj?Ble06zn-Sm@|e4鶌ƛ&ګ[@ijƖ6MðcexɵMڭ4O@i׶_ی}olY7MڴUkomJp\ت)n}}q-ݵ^3o)l? VXz3>Alѷ \ll ŶVv~A[7hl:[˹V*fVFJrJ:g=صح\Mh}ۭ-hƕ x}1+Φ;G #[+±L"RXSU;_iׯzl@vJt167Z5 z|5&On7A<+Z[55Wm<T3Aghom oeoП�Wڪk5AźB7!a^p4gUw\- ,n7wvJg2|6(^C?nT7Hv5i4bY)h}ߢKr)}a,x?r@D+cYZ6%*|{V=OvhEx6 u+RkZQ↣r 4ݐ*4<k(T-^c7 3 2OJBCzQ }P %?S{g,Rϣ*wueSHBB/(�k=Ex#ol h CءGr6nY)Ie:F°k[tHkx(AjjCdЙLO련<A3p[V]hE)%ڬL)xt}V断 , r7tNɍ7h1H* 3IY̴vY\C+/DBl"&O '?s欒�rUHl\/ 6zs2t ڰԇ\ge㔎�{('PnZ #j:OY*.c9РY79u7N&Glۧv6CϝR/h$|z%h1( `)MIkjjNt}L]ft(9KN[McV/3\6 LOE4f#(#eEq.f�h&Y'բ()A ؒ|bka,&5}XLa)*=g',/#%x~2-E%#v$#W|0UUYҕd >䲀OS&R^?#J|6K%4=x~胊iq3!XK3[*/�VT]j yl@$?^#!>'L1ْ\؞I *P D, ށL\ZV#U˜k)۵RB}gkkVTk̵H\ c]b~YЋЂIᨘ%2Mur!H=Ž5ϯ?2mO}HO=>]ťK\'mImiTTټֳ뇔ठ\KQׯ�$T`+K1kO֕IKYu^lVb|2$I`#3uǓ�,VL)9CFlת%GpiR�)J{ו}1 XgNԑf1ӬXE:#Ђs[ẺoȴkfO˯38ϑY $vJOga 3;JEg_]h+\pi Xa&+4nn3~p4&㶍*5L`*9@Ns?Geo01,:\4ZXҥ dN>I:ж1BFRYv.xZ %c� ﲢ%Tu #rް7a�%�h륗CFаd%H !Μ_p﬷؁π$| ‹ \eǮuْ RK2ݔ5)?I S.(';K#l褎8GF+foGj)*4Y{+KXSWtRFCY)%@�*02KH a?)Vi1[Q*(WDnLb<B責”F,JMj*ce37 2F=3es( 2Ԓ|m&rv֊9?ѻ,_�JO? u{,sF&Z 4:rդH \zWUf,P~IҋҤ/"0X€2-Ո-s@`ת~mR6;{K VuENfc !gKF) Ȼ;7-\5(S)SEXg'oy?~_-(di1_nDȱ5kʜ݃A4/dJ�s/YJIYfQ8oXm4 :Sُ# }x5&Py(A(w/cP BQJoKF%yq(o: $5I-PfX5wf^NsaX)SB.<;Ho[6CP�*oKUəS&XlW).( dUE5Ǔ ?F E E=EJ֧BJn76@~=)!c=fQO/pARD0^N'T;؉5p],ϩSYYţ[.mZWIkgOs1zF{_cBGcUXJc% �%HK\acLZӞggx9?fę1Պ3<>NM:6S9B7sxV5=3OL:,o, H(qS>"7 IL�$%w6(@IA rmQ&`IOMJP4 ]gw>6+Bd=Ѫ YZ1RG㊗=_MioXrG鏈:tx>e1R)<gx1.H@ h128K6n px+߾`$iUAvZүKw֤foZ ;g1Į˷�mȖ > A-J{3։Υlƃ4rQx"NYt6M50UiOF|eڒdS] tNI)a3G@9ga4}Q2Z_diiD񔄔�xZw\SN <[=oJ\V\0؆%\^v]MOwIY";Y\Neq>zdBJc@< 2Ҧ^ܝ΢R%z(W &֏n͘IB3ί3l1 5J4Vfe#ɞ0-�_):pܭ\X(\^ uAF^GnG_66^V^Jܶ_ aZ[_5rDg (kU&syR l? RڠW$:_V %7(ˎ)G^>NmAbtŀE&{AO0.Bv�ë[:UPE LuF4TkR..9Ū;'ڝw xtlJx2촣@49oנH @ LG YUD0b9} ("3H4N)Ym+Xc *^2:Ҙm$yrFyC 4eѵv{x8-'a ջN ULWc\](>)Cu@^|ECtJYZO ߐ/D}yNQ`u?NJ]vЭT`fwMvX)0ISoX;mJ0$>h2q\ ٱto|]ڲ jwhhkQ73ٯu&ӽA{vb+ֆb}W9:b-lÂhY41LnR$~O_Letl6y߀0J`'aDβ$jFѳptL xe(0x0 kR R 0[~b(39܈Ek(A7X2ī֌hCmmstxYw.X9hljqb<pQrA<T9%8'X5✯tp01^wmOK7VI<hlxL<G&| bF0&T$?[JM̓8{b kLjQ:,5 \$yO1v,eUMSדaސ}Zv5y,SR zUztXv@?y׉v:?aQޯ +m>i>[W<iqwxL;hu^pޙ=!?zެ<1�;-;Gn`�Sy= H&4ޛxYþrA  cI=FxvŶAUn wubrY;49s�@P{msf+B5bBf.)W OSSa+4gzl٤f}u9~G5l-}X(M <O xo}٤vKHVXGMZү?IK@F~PiV_ӑׁOc�7r+22*5ɇ A̩ 0ĮG#R<�Ey: 5-V1O[zWxRR27O�c/?Nl$ @v_/p =SG LsTYq-ȺXq2p7®v-Ɇc9O!%Si`?2R h9tҙ|ʕ ?d|y|MzŽ ` @efIsrzr)V6Y^J}B_+3mZJfSeУ^G/&N~| C1\T <~3,? LśJ3z.{xtM*xKOVp=v߱5 >/=a T Nl, %Kkk{#ʎYFV_EJpRBG{O kҹLKwP}qqDQKǤucԬ7*l'hČ <+Ib8xͫv"pڡp~<J9o;%~cJ'<*OsnZ<P2;#+H}(k� e�C]JHB̾jgɦ] {0Jϴkv=a֯V<fnυOշ<8[_h߇g:J_{R xv2<k݅@S6 |tLb*oݵ3]7@$Z}SlC�#LnA3jϝGwEҋahz@6EE {*4 }c`C!-سs�=�؍FmvVY@دo@y\ ݊{*M(ţ8 (p(``;0 עB!uu+a %P̋eFj¡ h`Imo0=|Jǝ4It :fRak h vx- k!  $ɰ[< u݊ۯ]߶CܻO_ )eM/ezhϳtK)rqZ"MD\S[?˚Rel;aTp@ApdYxtj# ,t= BHlC  m4gUe@jkC=Ko2 id P^8t"-ƲOu0�ÈJj-#ok-@bIn!l=aTȉB )i&¹kU_ }[Nڬ[x+@hM'-ρi}�% h=+ ,umс9_L(=ǡ;᭷Af  Ih@M�)P O .O2V׋𤇃°t=Lm|, a5Il#L?< )šGYPxFR{bOj/,g3Htf7*, CYhTP^ O`zC`(͇ XSRCoq76dA�3Gd|"pp<LULS0w(hWmLi1ZsIimxGQ dhfq#w ᩱ�2Q şlVU|ٴ¾r _h"ɴ�Ex%\tQ(»*t$",ugNA$egc%а=%Xh@U+ YYc-le XBViF( %1f/lf@-˂|6 OܔU2R0;gŪTrJFK(@:eÓl<#- ʄl!k5#%=5 R&_=U ެH鉬Yc$YhIQuxgO<KLdVHɄEcm YR�&=]LJ쑀;t\4}Kq1ĈȻb_v￉VWCӴ90hvCMfW?X71}GFB?Foh#uw,7f4'NK.Fme o³'n<_>Q lx͑%G+,:4hQ4>BFl<s.1p>2Ui֭r2TarP,<5 ^>X9Gtm*W*j2'Zʉ*Sy@H4es|,=9KUUv^Pޓ6œrbN{>2?^ad.OAܞ\^OC1QV˱N+']P&rC iu*[TҕrrnϘ5y>E5crW ~w |eI))qmP w�HvW=- jKR/nm3Eu)AE*FR=xK*f\@ 8UzH[hI}#ZU+�IIyU⍞|Qi$MkufO{F&F@p B ;�Z ͽ U: -Q�@9@`z@#6 �,mR�A4GnUXUIUre? pB$l;Yv(O ɱ*J8){UTn8O$�TDW<75 }YL.Բf7guY*9PF,Qx1ȌQ1mlu:tK.5gY!Ir�] ȑbS]Q *YLӯ{S])[u.>]Z`$ܝQ'];2s_ >98YEET5)TdP &}VWH\LӾ?�%q.Wo$5OzAn *�}e1Gq10�6�"mWAጔ|~~@srt]po4gV$}.׮>%�>B2} K2  jY@/P\@ Xo3[ PIRǟ^K9.󂧪]�x@T9R[?.~uud$,TX|Wj:"yR=$D@GW&}[r@J VA4e!-.t?Iф7.}ꖿx10Ù[^k |` C? 7B.Dk^pQ)ϊDHADvut,2o�%h�@ ǢIJ�/ *+ʪ6jTW!cb!&tq�8t`ؔȵA9RZ*28FG>ѵϫ9 S$�e;*qLɕ$JUR�\BJ ,A'U ZF]lrYA.�FUYI,�JO@Aƞ{*% �,'7!;APWwh\) {S"`OvNYq+#pq~*XzD5ՠw*5+MӓCή w=Og'1=^ID6#AbL >x~rGOC?}触дhsÆSVEA;HfAH zY=3J,Ь–^3biW.q&fJZbZYA-g4^K+uD ݌YBloD`ogAQ;3I CY":d�;NF͊(%C;}~J 2W KdDEuf!S( \I,EA0fih@(co7OKEeD|0yGo޻]LJEн/%fۿK˽ U@&N7*d_Nd[wVOI#}CS闾JqTm}ΦqS%^wč)#H.?op\!|2~(LM߹wZk_T]I#iVگ2/AQ1fk4[sF˱VyRay<|Pg8 e&{U|</fAE5\!) I:]ywp9p7?$PE\cOC\AQ%r;dl>NY!=|7!eeҘy24/+4BULݟ"3eh%T̗ʐҟ/jK}Y̳3,BLP< AwD/bHsߵijERE=W)Lۙ?>xЕ~i!}Ż2ѣ &wTj_EXcRJm1]ŠK[;yjM&勠 Ťͦ,;oseʚrSv<\Ov~ǟq$ɻ3{•t&j:Cu W&Fp-(սWuuN: 5kդU5yD]ݳ WǩUiul@^?\W(w#.cYZMx 4jq7$mOTJHI3Eѡj[jbVA(5$huU4~ x�ٝPK<kU\=蘫&|&{x«}L^ĤTt1;/2P.1>p"D1d[+iK]@3u39Fg1{G1E)EJ`dTlQ{z˒%+M3�D7]oYqZ.[3�iqX- A/1.,@K=< 'g6U;s�zs9$1pi<B@�;p�N8@PgK2w49CC P].�޵N %~ '̉jϛa.Aݬ:�! W6U낣hP#GnġjLA05n祺1] `7cfgXgn3n_[QwX|ioQJ3IQ˜J4 zV ^VTۦhFY@ ^dDMzKmTd)==CtWzQEƻ@ ΒuωC%2<BbV*B¦!W:np0 beybH ?"Lkݕ:K2a},s'2#gKM:p3|a>X.,(<`^z}j|\_Wy|ޝS.̱y6G2g/�;g K6 X%Bl0w~) Ə.K\<}[ d.$=ļI|r-KT|p/='O\O_J\2_^(@ seޟԩKjS^w_ jF9{>q%Yxd P;X9pH |;f w,A*&iS\9p酳ums;yRI'+Eev>/͘d8Zc&B@c'*nu%)PoهORR)Ap@J0+swveLt0zR~ pn|u;G͛hb{8(|c}b9LKj$wMydەwvIf'~wO|O?ۻynwr=t7Cvdoۣ@o;Ts~84Wna}O(7Yo2w{M (E_r�nz:Zh'գty7/gnp~`{a7;x:> 9sTa 5@˔Z=H>x4q~[4yM( '{G?kOڨP]^:z 9hP_\ڢp8:PgckiFǧ܅Q=9եMOT%F:ߛ8} _imYX{N*+™o t˽< e]恑O== 1FJᤤQP2D(K|?ƒ!:<>G+Qf3HsW r$ |4;ʚT}^,cM@]0䔅 XЍ)zsRS诎ן( g*YpKf _X`>֌f�RMhMp!w\`h6k6o6 uFb:eDzjXmyeO^ } FFr|LpI1UBd\Gfz18??17i7C_eqxlհsu_S?8e")(zaV2y$@|n~C[q6WxږZ3 |mNGckOːVLL:e+M g̥b$^#'ZnRI\rNN~˦N?xR̉5e1Lϡԋvt@L?m$} C% WpEt:[o6d�&*ZƻHfC0}I]HI @}Ҳ}'+heG?kݏTܓt$PNrnO! v$1*)59V>j?luUF-WCuVݚ QdG4<z!I4f +PQA h$I3j2$hF36 耞B~% 73)VkQ-A$�A(y":}uE*'8wŊt) IyFvR]OȅRPvrix=;6-=Kcy]\y׻{*7EP\;/oP ܅1܍}*J.v@�{`A@Y cobjt^mМdh & /vM^xT�^WT ܋J !(h#f!>\�Yqdjj�D~ }%)F^G%=%.Ff#l)4cЫ+b/ɠ C?Fht/e7 ;CzE|Q`tut=VI[€ Vy4 j@IԢg%ag ju}th{*TtH4�(5] `,~Bm�FAZxtQdx wԥ-v`*"$;mP*iHe� =f; r1O>>+*]} =z5=:vxl>JIQ6+UV% Ş* (~qV,4U!&#%nh y�`_ yDaT [Gfogtz'U/ K\z (jHB<h!UTg7I՟7-E+e6AƳݓrga2]z$;3l"KRw.<ճJ&?3T`#d Y-KDt%/d|f׋gwΒ,3*a^%e!ױOldŶ #e3OfPb:(%2鬘^̰JB)5FR{2RLz X<_+tW;K?*2IFYH@FL`mrmdhLFxJ-E%K2~vgfd6kɤȪi+֦Jj|c;Ԟ<am21+B/ijHvȩ`4oLAm3pCV YHsmTIGdtJl JvYЫr-Y9-m&XJ %9+0*Vʢca|e˪gJs:sPcY+X.I}(ANZfDUԟvQ54o-NRe'rRc]Tl)gC.*> SU1U{;x ׵/W_sֱ=j| ;rsFTṂȉ8UYN*,D m]~Jf <%pJz9<.9,SX=p5#4'_>{pyR'ٜͩtHl:}DUgc;YW~͉j>w;| f*vor;Ԍo*U!cYX cB.uHպHyL {Ms֕TN}D 1IUUއ~pB]֟\Q}+kMk8 mHտ-pr|Y)'x=Qڥ>Rտαm�'IzR*>itXVԯoWR8t�jg T%LQx2EurN^%]\qp½\mh) AJPCsY�P3]]HƏ8 ;�_:<v^\(,9*z{}~Wj_P@ޞ�N�@|'t'kI6 B4~^JnXv>{EbB9!BH F7_*YW>�Ns�D*Q0/.nD}wO.Gد];;N9;4 1G'S9áx.s=')JZ%=n)�,}Đ ih7 k0�>эGBJaƣQjo^� xZ%ޞTJ� ȩD̈́. H+�^gVrҽ2^QH!%0̻soِ?�9>4l!$'WIr(tB4RU#$@yHP.8ʝ]Lr\; W6>ޱ}<'rƛ/wQ-Y5ޱLtu e:|W#�§=f痀,#UW9}̣Iڹ_]P'B"|QtP'2~'hhX|+VqO}77+&ҏa+aX[/PoXC< HGF5R;rw8TT^,%w; s)Bv{0 p�ihCnJ02{TlE`a65E2I1Tnh R(A2GRHe;7l@)@f9hHjCN, ;�fʗa`0$e X @@_ 459jt@P!%`>Otm02fuq@tz9 AG$I6Am5kxTsMuWES~.�CFTؽj#f[gE a! ]_©5ctNO~) ڦv Yqt9ψ8O~<s]`yD:-ۖ2׋t$T F4HG6.#%4X2h2^-۞mk8 bi@ 33KӃh_ߙz@ ?=+CDK)ȨΌd34+'ľ^*p7ȓ^DlFJ R]B@$ARKOdL)CA+XRȪY:l v0{m@Xg .Ȥ{K;3<-f,qьئ\}&k׋;lQ ޙ=Fc뿒2AJhL3OPbV)s᏷S Lsƕ�" e,�Jٮ뿴C-̾=F6){UyhгsNy>*i|~6qx<? $U#ntHO// ;-Nc/yF!mwz•?<O&I+|CC~I 5}yCRš,KCoI VUV,߯$R#| ^Ո' ImOl4&Iu}쥽CҢS9}~1of,y^Cpwt<cL)X{aD4\{XEi\R)q 69}X4OcoHKCu~~C:)(e`j`?xyIt u(ǢG_W_dAZLCIy Ocz<u A`{n7R0O۫y,\#uǓV{9x]kta{�,#hǶ;:G'#ޠw;Fet:Ez#hQWGubQ@C+cuCBR$g=8Jv}'_mW z�7ŲIuORd) Fy9Aꩫ_@mG x$W;qСuм(؃3" K%Iv{�&ˤ N%U;b](vQ. vc5rQ,S-6P>T%{ v;Y'=8+po[mϟavezLKoV%A^umt=. 0>!|UBK39@ :8UGqڜX}|ha9VkϿA]-`V_uQ "x* [ (w{ˉj!e<tʽ!m".ܺ NT?[ϮWXz=JCJY?HR'x]+ifx+Pr mfWݮ0\=PWsnu uϋSYER˟-AOt%yG(BcCgze 7߆ZlshZC6ࠏ�P' bmJ‘o|3-9�/+E߅gM^/H!Dz]Ѻ.:& 0uK7}"8j#mE0!%p$0zu^C4ɼdڼ}i/w.$9\gBt~?xo!:W# |!WF.DBf~<}0<@p^#/<r))腃 j6ϑ\Tg. GɜPy?_ -t e¥ y>/V@C_8=??vA7Ug~hyΥly ?ڡihxQ % %v�دE:/ -=ۯ_k>ߝzT8@+JCP_i]/Յ:㉛nE~EɅڗ/D}\}`_ xF]ysqiiw~pJϿ =*l~swoqt4o9J;oҟaztvr{:;8<ţvw7:okvhnGo*7movuGi[C&l >}{k^m Qzfn³;n${GggvaG~k]iޤ.>Qـ?t(ɳo$h;tndy'v7Pǭ?q[ n<} 7 &``fЮб󛝻oVQd񣝫ߥ[ n};a�,~H(-~ñN�%Z},ձwڻnb8΍5ǂ>n=GNo0Q`^{!v?qɞunq G):?^^kWџc5=�nz󠴢9M;ͥ&g66ΈPz٬6SX >;RlhcN:#6ROB_3qT} Ќ< < O95(/^iJՔgC~T/5gy F!AZQr3#4~o.? Y~ S77+aHϐ[ =?21I`M XX6BiE;sKq^W+ :_ãQ=#b9p(9i_7Ղ mir1vz|BoD9m~sqg=j^)oΈ�0:\ C^3TFsMIwF%Q1GU4SokBf ʿ D14x?BEMK2c_3?ܿ}m[o7WV[ Xs̀Pߴf}5/h30BihlM[oC:- {[utk>mOl9.w>gA'>mR H ๹VEL/\Gk}V0P*F:wp+V`#xgUg3qncd 5;a[-X2pZߊ-ASjDX%Ѧ}J@[V{FumtzJzx-N8Zyxd4gdb(ؔk~%AЛ-p3{ L`<fΊV O_|<wՄ+�8K $p˒Xr ӡ4ZIXHɷ0 mx~r =B?V &<ч$l-a<z$W4,mZ5iaAkHO6!r ��+%UyR kh Ho:ց lV'PNB~# N''mlX =AЋA J?(EOCVR;=(` Rgo8$<*R15'FZ$Y(Th*gb(ɶhZg\c2{wKﴇq _x2h0x0 }` \>$ǜ\|`c<2]A+&�O6D<FB(ŭ؝kb–7`pX7K, lApEj `Z : s$,i)!L+ 3$a!//_ Ag/\0nJy4'HQh~D3rQ94O` <C:Y2BЂ;EqV+. EOI#CJ0XHavWSbp (@^9ƌ5{Kz<v^t"% 1BJP YۥJZtצ?i 35-k^IZ_ c7ltA�$`ZOtV 4&zJ=͈DJzѷf0*ZJI< 8`+$Gyk\WRBs$lq!6-Cǚ04L@+04.QUKx&KO�DYm6Guws[x'M{�K{i- W.1ڄ7�]3dUb0ؔxǛ-."]zC\/hJ!,/J;$J6Q3Nf0#e>GlIF6g;f3FnRz K 9ЙxG''vA~;�m“f޻+s of$\[+FS^kҋ݂h@oKdHF(F=d89mr=֏ dz+Q< EYNL'JR(^LvZLE1KN➽CQ dȦO1]/B!-Ju:q`;CJ2!]/J΁ѴІQYY3`Y+C4e;MIJrRw,6kO7xFw Z,$gI$zY6# V:z]kP^ IYW _{�a)=Oݞ |r~9rd>IE+4!socx9o5U)穱}_I>TKU(;%4e8wє Nz/]uspIҕ/SkQ^(^tܩX,61:7hM0tjG|#޳ jϣ{/ W Th h  Q4 �5h<X"k~J�(F He1J ~ <sY3^JCZV 6f X>3X'WB{A1_9Ʈ< cwX@x}݆O@YhȔ5dFV/-d}be1v皰 I5re(soP7<^ZM,Do<ǯHW]RHc 銈E3ӗ|OrǏKrW^}V6L Ðg zEjUN +zΚs=VF8?&{O){ڗ" 9jcǟ3VgTBܞ#{1g :eQxu{Dz1Y# TY1 2Ž[c A3 0q�\\+q !BxEڵVl,x>Y'ݓ�7 <(jxG"�ωo`Pg8Ao<iA^J&%\G O]<V<2/18䟢 > ) HQj'm�U.;�F0.!% 1j\JYeNj+x&@=d#1R?I@ siȵzY3'TwEyhW3ߙFröߤ ;' ԋ"Pf?SԽ>{o!z1z^ת?M�$Nr*,w6Q7WJ3%rL%<ۺvŝӷ}f/�;Jwį!,m <k~"YCvGP<՝r<,XWV-tbuz3)ox0?oOQ0tP0m}arv8 U;�"fC}^0@S}θI�� go3m =@W[V0 ovk̢5ȑ؇--~/�iQq *ԹER. )=bLh�x[@os}K>5N`˹ :iqܟ@ йCǾsd=]$_i;KNr⽱R=.J9|L,+=uyxNv)de!G ؁^3 6?~( ﺏ(C>MbDW,]~.\sҳD8|> VU:Gl "?3pdgI%gM~V�eVoMc l @pK8+!!3uAКq,yzrZ%B5Xt\4+Ym3ar7Tf6H=o'og{ސ"^;̔7oGfs&v!G6twpw80j:64ꟓ.Ly! we|vHFH]U2,:f.>2ĕ;ia XZ%x*:qp[ג%]s-*SSumYspC\}iwZ6L#Td; Qs^_a*w}Q<݋.;n]pL~y'/wƋ Vs4G_/a/A}4ً1%ˡ ?g֋*_`//. 9sIΉ+5/8<oS]*ќޜO{WH.//yݩ <}+.&yA ߍ,/ | h./P)}YۨyEOmSr!n.%z/r`$cTw 7`HJICm=dU!!+ӯiy+/zK'P oRdH|(֑잢\7}wJ۟?)R^JPzxIMl r/sQ?lYdqfشB4f/ZUn_lZ>c$Fr7KY}=^t͗J녿bRBA$ doi,IBzFfo QGv'}P{}o4Ko,G)losoo tV|>(Z~j1 oě^Ai^hYGjQg*M$a<jfg郬z0]>[v=<-|#ČER_h_7f`I_Wgź~Eٓi:OzӁv$ל36pRR,ҌUE8:UVWMԨV"U6,K+s.�+�;lFx4 -w_iP�.;Ӆ&##n#A}A_ 8DZN7wؐ #e;Zu{luשsuVQ^:c:u'n,Pb;Uow?+| >[Na0=8d0:">u>Rh'ɢ=0/I+4ۆgz>,d7 b]:mp{DVy=Cqeխ+�TojEqp_Ǎv9G3:tZ#uqqJhQ>6?STV-OMo?Wr9<(+M.25utfe=9zv b�lN?S6b5`plvOjէؾ )_!1�.ӳjG"-+Wtf(Z O?t* 0c4=Uq QX"nylSoh( 暾4<7kWn%O_|Fg&{.-*#T A.<eyUg5/ _Y<qݤ}QF<fA9fCjޠ=A=�\70oꞴ-x-v0Bע~+B]x*VB.|ݑ ]/Wk6jPҥ b/ DoQͩ __;T,..W^kSc{,F>vJu `w [1!!o83Qx-jK!ڬ7Uk36дxcƏ[ثKh~(JȍhmMƖ`$3M5Ҡ)hAwPvz=:Y=?0 my&M^pM] Y>la!D" 0 u7xBLBsKqvAOFm He3pg]hLm. gf.M}K> FE|9AG<!㚍�<q_ݎ p \*hsq1(AvA maXW F5&bG/5sr 7.{v"n|r5Hߑ_ƾsߑ3wxw>rґ>`_+V5Eߓ?B&?#}j�v`i;nS_-/-/kQ<4MG! }D)bi IDKw6 /޳EQ'�ItzZp h�&6Fk> X<3e0WɏOBIN=q'߭&L6w@0^u<WW.`;y>ߜ`]X|; €17@`B-qεoC=�PB p:p,o;hF_!xs.ΝeꈫH:\ r/r. *z{EVX}@sg܁fe.5}+7S^:zҖk&b77:sbIBۡf\0q=ߥKwXy Y|(4f]KA nc'j Rfײwl3KWY%~hW^bk p<m͛Vۦ8}E 85>詂XK+kgsk<]U6vc*6<Јiޟ`ġKikCSBYhs,?֮9ubǮ@Gsy+9̕/a=t.yիBdb[旬u/9󫜸6||\{69/,�.�1ަyOm~GukZ�/PA2xhX k;~ _t@%@lj=C4y $閶K%+ \7@ ;usop`+8OEm;APy0n=\@d8=ĵƅy׭!'󮣿%B/f7=o;KvRqGM$L/,uKq x}LQp~xn~aE\amme[8߭5\+k^dFj: 􁣧~g9&ߋ2[^awcr3&+^ 0zѡ$I~8dc 1تYEOa<t+ CiƓ` exMVu�[} y e-sLI"Ƨp"}K8g~fmiOmq4pp�<ppZ[aLK {ݘ -A} z/pHq5^ЉGk4@y\Rw躩CkcWD7exB6'-(S1=2F( 6 X7p;\!,#|/~�Z c\ ̋n$q-z=x1�$Qj#3%0�/X LV|�*K؂T[>N*4q!Ot"sޭǫ{J\*-\ iH+#=`Nte6ktJȠsRUV4kM2\TrV2"#f&5{Z:3k_zc`/jZ_j=eK|ܷIMhmm.jܿ ŋ+\^Kk \](gy-hfVBںaOo}c"H8cO'u;J^wu':AzR@A >$�_'$@_1w x䈔?WD H%pGXCUǟA>Ȼ@,uP@Gnt w]R /0l/zf盠}usb\( [W?cN7ՉoXWvD*$j4`~Ů`W SFb${|�XB ӆ-3;I0Cf.fQG`:9~d gt`3oJLK\n2RM63f4͈MR.z\ni)W'\XZZrR'c4rR"++X;Lmae~Q>la19L#!`\b৛[Yrz[bDWsUlnV4S34pMެ(jTDY6K8v04'oy [t)f~s!*SY;Ԉ]넉MJ41j5mV˒h78"#ܾͣ({QU:CoV6=DMWm #?+lRmLM~=<I)"Ii_Ak3bj`;uJʢL _j`f�z|&Q%l齮)H<AD<Z53NF�q]@&UfkF&o~tY6 8;"Yi3rï(ec:5h7Ey Z|[7%]*)/F%sj c&h_3^Wqئfh"GJ$VWe O 0;+{XN\2SN`>!qCkiGQ*mΚ}ض5XпNyy,r4]; 2;P;w;[@sgw],D?.K{׋ _P؊r=)/ï߽0g@� `V>l wlz"M`ok!h‚O!(&2QmHK>-ݲrFsT} 1yF4{ߨ%-!꼺i{tmJY=1idx10<BJaf1ic/f?jج}@4cƍ H 0p2x4*"@|*LVzI֢~SPVk$"/WO6 P'(̂s/^t&wݹ^Q4~vs3=NVoO?\ twgO1`-,p옉{]\O ZAqB.n5s7WZlK^yzIm zE["Ww8ٚg\u}tYlMWQA@&yږBlOAP$.%7-Cq`&i~]qH =q<1jJZfv e3M龚Qݗe> y|h � =+.h8Joބ60\,u4x#N0HޕYIrnNck�6iqz6ؕ Pe{|'� W|NRilE+3y.NES+Cm�F[u<k:?}k+ C8+/94dL[y}eJD[)3~w"5a8.xZ,̧ go3gOmV*e{Ż+w+dNpI`ౙWh3Nd4qg�t| 0zk'gEt/P etEE} >o5�I&bfQqΤMɘ�Aaн1S@{OoaߘtdW"Hģ=ٞٞ4 ֟�P�p�PV{ihv21(]lEQ98lH%0uֈA#P ]y+3[g*(y݁wtE&E,[TTVFVĄ|J?ǐB(TP>BQ^qL+7_hJʓCU_V^SW+dyoAXn,f ^%?|VoEY<?Q9sgī䩾Urg.g�a}3QVN>EćF?<w *bl+٧_5_9"#kr1* E; !lOATᅿՕWV{lV$Iy%TR-V-?RGE Xmz1,Sjǧ "�:�4%%}Q5,2A^ì Q ֐󱆺j VAFiRSLMUjdqO@#hDl~6??FtL~%ɳJ~|Vϳr2\e<U(ᛟyDO>,3=+uvL̹rbsW.+?;Etgշ~&u{>{v??Tw>}pû~h?/YqY^yϔҟ|_W?/ν|?fS?O˷|pgW>�!:Nsg_2�d +~1QO6āty S Xl3&t߹}Bg`S& 0렺#8(R-яsN+U`*oEjdlk*(5ZeS 5vDBgj 55EwF Rfk!}dF& W3.=0xP9˾99[yڕ38;{PX]9L=sFĜv>8IEd$ƥA'-S?5Μ2Kg/Ca?llYV{V9;p@ms`sgك_~9+xq?\Tك/ǢuY8+i ji3w@.Ydvo)生<mS9q&,IG?3#t@q  d3 @= /3 O( {|#3⠚lOuT 2X2c |=  U{=@{A}\GT�_֋EpnF��$F軭F3^q[\B�Am{0SݘEmɓm`|f^&/Kum#^:t<r>t$18pOIws;Ou #hIxP['_8!掼Jy%73gA:X/(WFhζt|Sr_v6w 4O$5���IDATTMHGfq|:p!cg>N?*Dt*4ltQ3|MGA& El748MB`<5(DU} , `sm6ڧGਸ਼oMZ]tvh+0|3fQ ͟8L5�A-h< �jT{@:&j|Tٸޯ7Z:.fV5)8xrs"!/�-wyI|#}}ϼ κu@IKՈ\n";7i`q:&YWrS{F }}>6s0O^@8X8@Y+g#XOzwPgNfq^/ eVl~D.1GfL6htR~yTc :< Ll^2�՞). lӏ׌84^`p1ڱ=a_[voT`jg/؟�0^զm?E&q8?hamW�_wFknlFg"Y16  &4VDBcUDw.h 5 a. Tg/]*x+;\gf'ϻ�O [Kh3?m3? g Sg5{|$fY汥F[ѵ\% :wksk8ǩJ܃tgjueƥh<L a1<:$>{Sp/X9U 0z{ B.}U 5R.53v ]lJ uYh|/`o@P*BК=)ٰ] Z�)v9|`NگϬ2f;h5ld?e)A R3ݶ�4�4 8F9֐s-0'>Z y `!�<G)]D |P/St>v>ķx>yg-~Z;3ov'Lh G$;�U'p)ͯ>0.n-ɏON٫l��gX}\2p`(d_sY,95o@M=AP%�iP-sC"3Sg>B_+3_F<` Km]Ȟ96 3sҟVe<cb[jX�VrތNQ>Lc<S,}{)ΖS\,lB9۳ {[|X?]|oRVt)4wf]?',;P,EErҥr<Y|_$зe�Ake<YJgl^)n!uO/FGY~tT/ZwBo_Mx텯c߿{@;|lcUO&�8xZ zkk{ {R3o._l/8vmY[㼝8]sj+Iw-<Z뫫{]r >nq^dp5O:儵czoQ} )ܖy [.Z Ο𑖘reViMUEAu=;xdd6pyR^<1GGfSŷW;E#fƌWjr̎ 22\__z8uhr/^~}hb~yd l6}dB\uOsb1Wdʉ/S?vj+ԣRP'^W_Sg/S|5rde]2/]0/o^N cNxO 6g 4\|/C;)مRA`E~ >o<Vtúk7\gdKہc}ؾ[,5\\Gʡ:^rѭL@>*eˡIPv7>D؞rcD†o~mҵpkjgZzAypkֺ ᷉Gp;~zC1;ZvOƿ5֎jڣ]!P!pO86R!5'6P!x_?bL8e CCA @XwCgn<0F1F#pɄKx8oN w8?~d`*~g1u_ùLp %l]kNS Yuq|A j]a oIpD@Â[4ubwuK#F�wen q0w )q*r* ﶛ+|뀋 xB ]cvz>`l{Uc#FkKvxG>p`Eɺ XҒ58+8ƽ+5E-+-bX~+V/_pU@S,VV4m\: gE0v-c]d=iz %:)2'w[QW A5`ExtV#p=ƅy5W,Vժ*81ZƁcYzd [_DcSVŻ Cp(IXFN #3zU*3kK:Ġ~]qZV jVϵppGҘPeYdzzdAūA>xFL=S ;O׏pʍWu&>wЋuS*PRZ߆ fZv_A)ܣ&VhURxoR<9&Ĭh&�T ]"KGƪ$d\JURiK@cť:@ȩ!8THt";s )@apztj8N>�׋K4bý@Ƥu(!r:tDB+[^G4%FF=eżCEgdRف%,%+,t>!*�d=AUco3$;}P~�#cD: uߑl3pr(ljp4"PwpSY d܅Nx"?_H Hgv:<љ 9u"p$<%*^ WhtNG8'ȌHS&`~o(iAve"E&q21)3<ɰ )@*%63BXl" qEMGN37L\ar&BG&||D61(G͐*%|f2M<Nw2&밉DLLzJFfZGӹ 5GMX<)( #a d@:BDˆGD'a+4I+<l"cdMbZQBa WbiOQiNh6@i<Ʉ!p?P36e" 7?g2ioT̔5#{ɹW`SD+H6BTFn꽹11ܹgSH"=ZO")A24#qtSi5M 91,ov2QL�=X`0` Sa *{[d PiB/ pʂuARšΔ~�` |z:2(Grnp�, b%cܑC^BlU:&ATx')\/yo0W3$=1Q 8ȗ;@QǫBO@_%p<R)0&i�Sm7 xd2֘OgS؞'c@9Nd,`ݞ}ѹKv!M[pЂ[:5(+NJ 0lk<G݆,q5iR3'As5[jjqX]ZkFŷ>VBcugx[5kE, !\S#>\JW95=Lke+Rbr%sաwXhlA9Pb< /eAPCV NXZ&| ew0&soXXP%}AS<9.j2rij6i:bGw>!-++R3rI&>dXdX[V?\/fÕ@{hZv3O¶u5Gr0e Sx*A'ᢕ:Z2s"\=fQϿA'hڰ25 <w7hIx"vwӿVRs$u퇉S*m0f4ĭ/#8 ]&@ d$"u @\0.&1ZO./.qE8~?d^C&z@ܾ.�F 0`uz {dPЁSTB�z_O@>s$0H^8~Y &z$=v\v݅ރle5PCXaa}a/5/-z?HہMh = mY%yǃ<.L.sWGB Jj;;_{42~p=EC:1*Zٙx +`#~^ϯ'L$<AgHl%r:tl0e V"Kj`��&He fd lMB_ Zm( ='1LgҚa@m H0r(L0 WαX:򄮱\AC렜.Z/[SGr 0y86VaRM;1X>`y l١ÄK(u}9EC眪RBO!a W*b:ѯu/ɰ.ŬT=R෨ibl<<[dD,'s!A&U,sȯ,Oj~KF3(nHwCٯ{Pj A]: _ ׯ䐑֧L՝'&?}(LWc E[FC &B&xHNP u]=l׋0VJcr(:$Л;2gCg cwd!Lq#24&0HP'Z3?�`4IuaOΝ gr@/ ,`N:AQvmtClf�JQ{S1Qk  �l? xհ x6h*<@M4>8+ZpwtYĠJgv&Cq:PQya퀋A{Nts(A_<)4hJlЃP1l `tij&t8N @:44�0 ʏAE&Ig(azG�tEhZ�s.d}5CL!Da7n#!bǃZNETRj/C�8#߃ C KcNPNt.0锴_-@)i gɧ&�9> q4:IM4d0�#8LJ,<'uNVӹWN6?C~hO.U ? �@h 7>"W_Ȱ߹SÖI6 9/!X8T (AߐӱA3t|8-S q`aSM5^4kdobʨUP/n Ӱf2 Z mN3nO,לbҴ-PKJY T qj>*m=o%Kp-Ps)I%ֽV+Y%{|lSuր ,_A~�!VXlEJ@Vf#f2x蟉 C=q_ NK/2+S _έ1bw[ -?7XϢ(dpgRˌzRv @�8/mύ<Խ F;Fɇ;^/q#o%\gTovbEDHGxZ 1�yPzIWg @H lR"NJ:<5NxmP E>GvÇ!, aJ*lM pij C)Z4F(5 ~) Gn_VMAr9fs :%KظOQpڳB"fpʉB$)D$ʝjjբNA@8ner{In*T (trI\hjq`'J('vB{`Q(e�6 }Tʜ $;"0;SIIAB|PTz>VF`,5� ` R^Ռ$MIR܄4n&5Jf0oڰHӂQ>^ĚX ԗhNxzqPPbd^l~eS X6>7Ce» H6Y%Ay<_G Ո1�A t7AO9.C{зͿ&?q4 Mȡ& Bh(\17C8m]E&�DO* 8`͹GcEIa< KԌAf_Ni`7Xl�4N>=TtIU8_ R.AS4Eֹsg?4qj6)4}T} `? � e`3?fc\͠5ib 0# 4UR_C< p/n%Mm& uA0\W&N2j~xX 9�A9  @cpfAHYha%9a:Mr ZA ,`Ȇ9d�uAA>;l AK4W,LÂ:" l?q  :xyrTͩJ5根a5ޜop?| !> �M@'hvr{2]Å}<�l\̈́'s, '*6ͦ0ew(p9J/:LӃ' ֡L h!)1<d^X#߄O9{G8 &j2LxZ}ݴk%s?Z0Vښ@ΜK~5Y2Ajj$JqbKFS]i"1Vy)k7`NE 8 ,5VZ*ϖMVfFzWAv%k 2Hws̯jԮ1aMZ﷖@:7 G9HKC֬f!֚@1k`bfJQtIEQ_5 ĺtF97s%mmWK,䱪~`N`jG#E 33n1__Z_{(f,;j1Y/RS[5x?zqHI[_LszrSm`O.0 +?{D2^'P 89Keb{QL2F5#dLywRX _u'XpnD_{w \ǔ=tt2࿰RVw0uXfw>X7j9f{ws* x2<5:_lϻu^ ڍPk n SW ݰp%n.Hֽ : >l\6Jw<F=u~aCƓ,B߽;X׋hnw;㠎|GB67êͅ p##Qybзκ/i!M*UñڒJ+ocl~y-\bBxJp}(>]|0alq7B<<##;m.F%䎬E3p;L =3;*kReH* :Ȏ8J,QQRv5H+> |f]§"w-ۖeґGߐb:0~ōBFR"<D41OS aD~+z[޴"}[P,`$9o.Z0�� YDbc*^#gX J8|RZT\aո:xZ[@ /XX<U:s1T]%a8ȃ:+W1j�Kmx,q:oZ6ȋiµ֮ u~⫟}_+.{קk=/n 2Vƹ_Z1\(dFgC bD!G"3Vd*r S!pv mcVӲ,[>`0rJTN*- `'{[҄s'HS1_sҽHX+{Bt"2'iuH�*2h>J:|G:�{N; ;"|O% % }~*�JGv(02AtD&Hލo CķduWg/cN\9\gC)neDڝ[;}!+wlYXU̸@ ͣҾUuH%0A?>H0`07^ `;ťk>}2މ#V#b:Fr HØCO.p Fq%=lxwy{eQc,fy\)<=72(ބs7`i%b5�8 ->lNOa)w V Atd$6P-EluL#F*ґ3$g OȬ;ĈID̀Tv;7&D67I>{3r{3^g#7~!噃 #eRHG~eoIm%u�6|D(BfwMJwAQMg]cJ 7=#e@ͺ".ݿi{Cu"${뿎* Mlԛ>_̮"ܖٛ}7\[)Ci+a `R."įWSis^ |�9\ da[ܑX=.f&/;GB5`K9 :%~qlNpn3'T~vD珠V�zAIs=|DNV|ӆ;Z5%Y�Na~21ݹ(IU;:V\ ؀~1~rTA@򎸮w"͎�Q\@nNA\yCYzmgxFUS|$& |wk12zw0od4{}DT3$1)y'*o+X7z{Cc~.e* ZvGaR E{@ :P , * zG;|U;Q~Pr4`z4Paw�GWeQW'FIz`<YV+:LDX::X5gY ׆9O&9}X}gXcV,b8wZc;`?'뛆[dy|vxX V, u%?LSújR-WCsќ=g".(OŒJq= Z4e >M9cj֭qz(Vn ?5TɑY?7wQ~_dɓ׬>ﱝw<v뭷m` WtD`♠�݇Nmh<ZX�Q�!`>�e8B$+*q։b_{`�� Tu)tbUU:.*i i:݅$ȯub4(NnNO8Ĥ|~% [Geo#n �}J9Zh8D*4<&pU[dƁ>y(P,5 dέA`;<Oncos5tUցpLƺwR qQqm럷fF5s6y0EoACU`30/^o/DzXOr nDaj߫l-lN-k[-czV--WoQnioe= ^({Vu{vCzLLlm7z[+=lq lo;m'=o7]&ЬEMXې ̺|ܰ )۟x+&hЃfe,L q [B5o{GK :ذqc<3ֲS<vAoP,GږL0hJꓖ; c3C~V_5�0aLu)'h>V[B&H�HO<'GȄegᏴ LGoC aJdCqa퇿z�5nȏ~cӫO a%o}^-޶,<3~Ћf2w Q/ : M_؆qAټe ݁q@u(-PA';&X0@|g&d)`kr(= |z iHIG"F'RU@>- .[ׁU씡E`wH8M?^|N>X]<JxW - J!Aj*0AVB=_)x]9Z``5ڱ;wuگ^&_8+> cG^yG4 ێ h,ŵݵ9: 졯\~`$0AuBֿN񃚇!.C{Pp,邀OK:4�JB`WUŐP-]AKq|.T{0m jswӻ�7sԅB+hN$/8<)C&eIXi |@<< m>P0A&'&Ӓ p4\saWAȰ �߀!C;|h8nOga#BNL~ô0r�A64(,2Ls`8@\y^P~yXl'|B a/OFYi6uA`Sa_&o :y`<~#6ً "7<1eIvϭV<A:(� ntWqc<#Dـ !I\ Y 2֋@Ei?&� p(&SC( .H`dG&%O2֝V`MbWb9(Z[{>01R%ɧU;AFΫۋ7'k0#e{x%K~,rGa/AuK}jԒcnqy%r(c  YR0Y/c% W5^$POYWEI+XSR咞oc4ҼRtV:NSZ|1hY8$maxm= }}?R{k~_T/Wo׊%8 ex@]_ ~Wnq`(R `aC  X؅�~ `:͏ @x H=.[_.loBL8dQxJ ApDƛ>-QJJ 31>C g0C)JM� :W<đ0RFMX3r8>NlB%4AßF%].=+e�vSPRbl'HqٙVl|UI10$%'M 5(>@M�P^؅o?7f;&SG} udW;&)ý%ZcY,MX}jF3'H~4Y"m}+m 64l)l`�F{O ll+m[u] on܅7A `̶yeAi0^Xo6z 3-͵:ϦdV)NZ 4dz32%@SfT5;AJ r!#S ј7/Fg ӀC&zBm>LP d<.'ih _]yNЄ/^Ts$5tdQ4:IxnL`j^(A3J!/0A5CM7>PۋC+%�K__)dQd?#f<�Rotԏ_sĖo=Pl64};u_qە9syz9+_s+.^oyrpY]\m1W"\O)d?#uG /?Ʈyw'y6Ѯ4 zog Pψ8[xd!}{*zyӴpoæG?>C}B,;ͦvnih°Si>&Mj Iz3tA;pYej.,]I MbPawR^>!@ǡ' 7aPēmjѓ `>6>nhyCO4ʥ<>пn67_<KRn?ۆfed[L'=|vYd!FH Լo`h7ذF2o6w L@GRhNAϥ\s s (..? +8ӚϙbszU.Kx?Cr9csl%5.C^S ׹^i&*gU 5)s69.o@סIuΚob < bG$nYNcZY Vtj녊6UM1ԢVh%Y֯qEJvq_}+?%,׭L3c{2`B Eٞ�7֟[G~VRņrkY*GIIF풱l<k{Zv5Sq/%, j#V?@a<ʊ)mqVq`_2kԿj}cz)査tOVi˾8S\U `ށ=R @xkv.@d]qpbm}/*5Wq s[.,\� /}g<erfa d)"#*(^e,K ʂaF@m^hTwclwKIT抌[@E8D/wݓzm ߓU{\Nzh5tQF_wp==\Op\ʆk+b 0v*2p>ߢ hЯ]h}R `cw58Cw8J^y +o<7ٔna_Z'{o!1ځKk 0|*7le;�Σ~:H ޖ@ijBHOpSp],L,8]8׃poe}c<ASy#]{·qP ػ:2LU gnx;_;(թaL@F+w yQaa(Z8!fiz#']8\aL9^AiY/^{}#}u-ɥÁ|�l^> A)c W30v_'9t(Τ X6F1 .N -Á:qvr+ `:2\�;$'% Yl ]Aemic Wq ю-n<!eaĉn|ӕӬR9TR譮T]i^OJr^Vi0E%VHeT}<@.?y/zOi~2zZ䕨/%�fp¦ mJpci>Td&vԉD6)0]%U(zEeJNVHCrVnRn"+lΟTILad$ds(+7@מ#sfoΜc3,(oDbOL x ˀVdmT55;X.4T05UV5]i\[鱘ƵT4fKXTSrz=iRsk=x-[a"T`tfl(m_Zɱ)8b+ 8 4XخVIc"!ʴV4."I5DѦIV3 ԜV,(-G[t_%x%fH$>a'Fy[b}' 6N}Ntts58Bd޾xu/2pV WQ F JVUAVBmYR 'ooo{=OН=O(6(|}7ɷco)mۑorvEߊ]9@ŝ7K45;BLN$M ޾,Fg{8s7~S`=`j5#&7+J &*LjS*`,stDp($Ȕ'tWOVYaftD1hfg&zb f#J4#qLbCPs85�よmi2Xŝ\eqipSc8fΩP@c^.ixgG[&LLrӴh΃yzp,=T`ՀjdV9b;2Vn[09v@h"M-ʕj-dlybT)BSyL3'<J0θ~<iyeC\o^iS% 7yN17Bry!A1(;4r޽m9/l4LV=N|\1|ES 0ADByDpqfs;^CCqbMjFl13Q* >DDK9 J1Oq&x*3{p8Ap�FȏRVJ%F=$Sfz@GANOlU @)�]pH%XEnpOt뻃 zXUP'gct*0Ǡ4q[;@|bԁZ8F2 } "A"QW辣Q *@PU D 2c9i}L8Fc!KJ~UG 5~O}O ځ*/1j^c &wj_)]gXbUn5_FHHUخ|unp8zdkr 2 nsK@$ò`[e^UPjTS ey,#]KSx(hMD�" ×Eט nRvT1D'pNNCM֣~ fLF}u> ;:m�|mSp {}-r�NG`cڴX%o ۻ|Wkƃ?lP}PiA)N\J){A!8gd8^%3ɹ6Hp&s7I ZB9{d.6wE `Nŀ}$Wer6_puFiSlJ$C`Z&�,۸xxl;cv TEFeK9ӸN|8f?^:lI)q@nǤaZ5Q%SFK[iVERC㤞;[�&(>2`;6r[-bg{vkwϝW{w[٭˷ɭdÿ_E{T߯_fwgoGZvk[n%wی^~rKsf4횩=5ŁS"���7f,&,'OGۯ@Rrx޿5y?܌'95ϑ9P0|䊜I 3ykʏ3]ή?3?T+QkLr4ĞI6v-yA4;뷕g&(Q`h=fIttQk:BٸfA%sd+U-P勄MAUKN '>Ϥ>f,L+@'h;̯" N7lHG%a2Jt么i"FV2VfHR3q,P#6r=ѮR [-:&(3љ(\6q\ȡ -SN93ya] UwlgqpG'Fi냏;PЫú'LGpoi? S{pLjYcQ;ʔ1ڮmߥYHՔBtlٱQ1{ߞ':0\?4Z[™oɶlyY\2'j("yE^Kg,jLkI)|k(g S \P[@2 Pe-kB�2Az861NAgϹhMG`",07xnhNS@-ibѴ22lO6 4oґ|2_`0iWšjB[4l`W&|DɩO�\h HPA\;/\sf�JpM�о׸8ۿ۝Nk Ag#46s1_z:T{/'Ɨ֞͗]&<ևmn^}KeL,< F5tRvYmNeT4#\ɔߺۍh;|lJYP8Nljdh !h�p 79đ� v/F5ِ *ttLM$Y39>lFp4~yU 4e3gߝC5^ON8?1PSLLܦR @<9n0kon @q@x0}W:&B.l]|V\? PX &`]2CQOPjFݒK6c'KJT vl4S 7ȗ"I3~&&gψ/E;g3Ɨs3˝ V/QbQ/~)v>Q&avD⇜ߥKwŏd~]H߇k|xH0{8~GoQQ3G"e(C L:K&w L0rI: L0ā3NpvTg{@AD%9PAl:()iȘi=F8rN'DyELʟmǯTtq4LPig<M 88`�}rнyc�G0uOSN?5x0l@p�|zW#jLʊ` d<iO !eUG;GۺNguC7Fec(o@WG'󱥩=SˣA=CƧΏ*c~fk6Q8lגkښq8h/߷Lss%>?zEYVw +(B&2Ϫj5dL�2$7 fj!dujx�jC&x։ 9m X -F´.ɒ p>l#dm</%2P%\30.7ǯd;5A0EvvUhvl(u1 )G LmQ㋠M Ny\w0Cݖyoܟ7eg\m j8>]@ww>DmLlt#F ڎٓ`7Hc�3TKGVRߌPk ogJ�Y?b5~$A�6&M|˗ӄ } nٔ(QĖ dZ\dej zzǾ5 ֹ�dGlPW*ѽ&,1Y kuqk_RddڛAJ{C :"=aY0/'dB*辇?\jhͯ v9_s2 " oan!lquh˻6()6?6_C2g[{+|s[Cۅh$A\}`  x Lp>k<yxE?8}^{YjBwZ{`š^^YUW\�TQo֯ߣ*qa/}&xw#<>N?N?*?9GGYqPA#Q=K}Cڏ*kkpc^_ώ!;Cc:ɩ.p`^ ܛ8={6 32;1)dے'fܳ $ L _]S*2cuO_.4:2ulSbR\ھ"^z>#Ao7(;j'+g}\ &=.7]APw|렕p\1ݙa�> EpRl=muw+)]2=\1 &{: xT|E_yAw1Ź<* 1}_>.闯՗ *I}?,cDaE_0WB9QqmMs4[}r�/k+}͹%q,bM$1O4%N1"K %u@!3Xt�d6 "#q#п^8]ePDZ&M~$3jlitZdLcw3ߩ F\%oQ<E)f;6+�?36H}y >f#r?zfhf{$sÁt՛rE/,FO+;k�vZ9Pk3 ґ`_Պ}#:#{RD -c@l;ytR=cbmrjNɣL|j /T{itM]Ͼ>0̔b9uLjeXZy=Ox\zA}FxHE #GFq>q|irrzڸ;qmb|onm#&&Xyȵq2gˤLdn+y4kK'ISԑr`&V˿ofHyReUU^Rĵq-a2+/5,.+eztTNiWI(/tRh8@P :6&BG }һ$+VK_we2t1&V1bT.|YFq#d" ᎾGNUQ@r*{ZKXϓ6kKRNp}3NbIW8^)o&CQ8;.0čt2)WܸW;%7G_Lh2wKZ7aHAk+_xLP/S>]ڜ?ڽbepT"eިÍ멐 ҹL8 Kb я]&9>FytK -ޑ~8#C*R~[ &,t˺)D|MX}T2Sb;.->p޽d#pP1FCsUODxGrv8�)q.a xSහ_xN,z9. ̋3aǠL( Oq\Ă<E,FG$8cc�ݕ80Oyc ݒ{0E|ðX c˧6BTt5A`eSs9**[l[wQZYS H4PTfTh Ѯ5KKi؈T3Qil' sNIG1TZјP@N~Zh4K:xvIV 0w*cx*KLZ!M)5CFm .f݅p%~q&4y[l zWrG ,;*?sUPDpQ;+`1'Vn] ս`0UJ5 U`߂j,klTsp|B[)ͨUpc|UpQLE FidƞV2sjLKIq-u4 ZtA3 ?{d5`Qb,1*|~7#(QNm{ώ+<Pլ �=~ern|2bBo'372L~'3gbr3aqV̂yfq GYj\1x 2')2i70`~pV-CCL׈gzdV3WHVT x=jAP3k A (s 1az'ke U$kV(]pUEb8a־ѫ{B3x>Ld;4Hq0{>z6n8&c`A;BS#L9-CjɓJ:3 3q1E LQ!%n;.8qOCB<*JD;[.#S0͈21Y((A �\uЂ^�AjRWtスLA&Cx5WBEJ-'ٸ F確ʘ:%P~7<>$~W~9C2F #Y32ATau 2^eL%3Qu)Lj` M,cfkjE&q?GՌ _cR>IjQ(>a!YVv6{C@dIC`*`& 5.@-ʼn8mGWH'ɸ@H N>1 H:6D/ $pmY3 �Ϩ2-ۿ˘Ca;+ܜڶ^}h*?L"ckEDs0GYM+ D?=5>WFB^9�VS7t~%N �Aϕ¨l:ӡQmbϦ1_ًwJgq @ *z ݤ$|A HAPm`- @Я}[ ? bOd(ʐG&(Ba)V| OY/ "BQ`.Uru\ ܄` p0}aN@Ƌd|*Ff!f7p\qh"ĠËqh~A` or^p|OܢQ6)d.>T>ӌP>b g!^]PZ,9 ^*'!|�i<*; ��tťb@pUA  ^zYGr90r(hu5Elhv=Fhm;Gh4VvAS;nM=&!O#�Q^1> _+J@@*vP8|'=!,oO U!C] c@>{Bb䶕Z[fY֐|FAˤj\t~V־) +U̺/ q VOC jI(&UKCGLڃ5њ1̐aZVKRպ3&3Q8AX1_hzTFiQnM1M- %N@FU>!kϫz j^?<o> ?Uw0M t @P-\R7#@{ĈUZB+΁ tPi<&h:1fzO$#e;#r~iz@, Ax:NhDI?@QxČ.8ɈIaӅM !#PIg"`(M QM$2m*6o!&|gsߦOɔǀWV\.}L/y£OGV uqL *3Vz6g6د,'=\}"I~6J= ^>."L¡p[|Ļ�IZX HL!s7?zJ,Fiń`lfHto�==$Q`i@uSz ?ѓz,6hDCN~ai~ώ +)_< E#3Juy9SS'm;l.gڱގ5rN)dLV&p?>CD?1m0`-HqĂpQLއ?2a�b~` =~CP DCS &Ҏu�lrjAAx>ןhy"<Tr+d$HcS!;$S�e�c% �ʠ!߾\Ty’8]$SXlt@&NuF[>ԉX  PP=f{= 6~unrʨ) z+x^AXjp3ɹȨG1=|*r:hJ]rG5)Kۼa.AS�]S�Ѧm);f/}n3@`N}{�h4 ;v![MvbJ_SGܾ{ZR;by?9hŖTu/Sqvqy8ce81<?"r~¾�)o<Λvi'3GMPS}B^x+1zj5Əo+f{2*-FK蟠cs&RRf9e&f@h XpcwAظ}?=^\7*@ ^P8@XQጾ?=@s?=B<JuTG@R=q*:<JdXeJ>߲ckNJc]pP mNO!$uԶ 1ĔP m6 lLLS`"~{JzleLR9'S%)y&c*/^P2 &TcJ($Ǐ<o kт_?`ƌJw qR至p�T`oE^ 1G1rW9Na'024LkZHn* ZL�V8? :AABĻP_AF:{4O @x�wj?CۣjF}Lg1)D訦ZqFyGhe4V-=c`Y9oR�y<y缁 888<>w~c6<E;g&8w||!%>[%~` Tf{  �& 1iS�A؜ٲ S�1� 84v`ۘ?U/FT,4m@ PL_0LԂv{\@&# ώ`.LQK Խ, j[~&�~{ <x[x<n:W G= � :HPi[l{8_pJy7smw=~2[)Kكt7:jm6=J˰8]Ob׾�t84bc_AKB d #SN 0A%fR d _&sX A@0`R p6Y)BKscBJp7T.\`5 jIr>"*|7y&Glmb1/Ȑї'rh(~f6ࠝGLX4.60U"V1ц3 "eۘ?).Z_a%j SqoڮN]tʺ@c)M58?m 2ԋMhrʟB#?;aW" P�qp4ή5h (aM];{Eډ'A{-@V 2>σ`vTxmX`1Np doMM{| @7Q@S�sˎK?]Rl\pCiS?!?uE/ cx:AGǿ끔g~Jct|5ch<5$,6=ʃQҁiѴqY~GA�Ѧ̑h^`&pj9.4*1!.\OC~UH3 7>1#"(-Dl^I=+__g>R-d,9zY)¿ LuF?O8Ot?2=+ r= < )~ OUG'M=RX{O&z^vg^|w;co|Ny~mw@t%'=.zY:Ay" !)H?|p'#t!ugScǷt89υ uC9?d~n>q~9s;?zO\;|#I̯<|I1&&ܸo޳4w/W)漵W&ǮPN_Xmsh,Uv2p$ )Zn'rg WRXBvon|i}^x/gJVIW/W"#/c7R_w "7/0T0G7HAaˋ1QI _r$S? ] ڽI\5!#yΝ'*^cߩd~M'## jG#r< >ګz'g^zN1)b8Wnٍml耖|0?*/F?R#A*{))9Mb%$nMbD< )SjR>@J(W #HbI< A*1"@غ)薐0?sS~aõy7 } ~_%w|܍߯/8=+oF#{OpEhq?';Cw/ࡻ޿1 ƜZڻ+IhpsvsqNfT8۴g x�<JwC,_XI=lUщލ-Lv/6ƭh"<~wY6~qdX/,!nݶ9^ s,<qdKXJ�<p*3n0:SpJ;KFX<#_\߁e]ᗯ&Aд",G,\ #uG(HakK|Uvv(pga_(Z`hlْYpJ2<wJa>?1BeAU0RR5^ur1xSSZ<SýΡGRkJ S?˩eq-yR?~)_299z$+ eq!Mj[k|H>U.xhF<%t+Q(r8g LkƇ\|ݨ +Ju2JmpӴT+0R*6sV 8jaY C}p$dž[{ȋ=~DHl ޜ%2G[ {QhAZ^ABK+3ی{zu"1>C @ ! E~ @+dDS ^5xaD2"27B$%fL)d&(?pqo6s{fƝ'^(t<VtRM HMƕqb{Ss3:Nb1DŽ3=wS [^̄p)Oqc8$iFNYf lD̿3PBgN$FK,s)FƿߌD)Rt^$FGfd.Iɍ~Sso\9Sr>'v  ub euԢ<AN ^4ԟ=X/q@ ƾlAqΑ]¨.r�'j\hC:]Yu #C.4o#1a9Iؤ\ l{8zy! L XAg{q8x=߀I{ ]H+\�AdE4.$1dγ3{е9Cc) j3@$@i6;�>.eܝy`8Vu8 S8s{#%q6␙蛬x`b_8Abqnoj)h 11^,bL:a-�iƚTw@?n ^<xP ~3ն  =tAs_>\ 'R$Es;1rnǗbk Ɗ< |o1oފ+ M8Ʌ} 9Ou fsʌ\iđ�6O(eF8C*0n"@L7U8VpVñ̅pڤ(RyS$ }bT Sy�׈<M-pghݹ`P]ϵ1nfi'�AlE*@S(1gX.0X Q'R"`(5lD~vn3� 0<R3lIJEw_ԠԁqIG53 ͙lFȉ`E?YI'v(04HҐ;<hWIwZF̽'}؉-wEͩX23!K㩿;X߉)`+XZ 2A\$ih>L�&3ٻ "0/zuMUZyE|BэkzRkR0Ac2$ģV |/jZjCBͮFxt1|T<Ob5tjQ{Mjk#da=HVKVf-ߺCo 8yso &2>jkĴp#k괳4gh Yt $svJA';\t˯Ȱ=dGjjC$f룠 C&k}_7j t�-tgR5gPFpn1}z1Dß] 9C]YR :^御Mב ) $NXB&PhE}56ݤx{]sK. 1pj[7@jqAv-&}YY Fd1 dϝjntdHVN5Hh5 ,Wh]ҳ#B_"Z;x\W+><=OQ;V"B3::zgkS<ΩgV~ _Cge*"CUGY#/IcٮsiGAs5]ShЇ41v.r!ᅕRQlߠ+2">_)S] ! ;AJʕ{aXMv ʨ ¯xy762xh7s„hn]j;)@c:΀;|;{Qj tcY OL@0iZبY%M; L@ 2|GΞھQp̩QE??X5!mZ-@AHz&8]+B߬ l?`wp[G-NqqE83Y#4R%_`׀qc `JY !C~T Gl0� @)Jp"  L4� j&W6/]M$�fŃf wӧ<et(Խxk+3w8(te#nO] N+[DJ%^~p%"LrvlHgҸcܺxldR[1'Q_HNMa:~lRu LSC}8' =c#7@R,dh;w8yP+1%kڽpWHMiĚ!`[E&l=ǘ}L9]qB_'O7Qmx|r^9^Xl|y|<X+x`#SoycmT1y =l1;v>•y6 E<S=ScWHG q~.F/E̟j?y7')-Ž1Ћ='9}\O>,NO&;ǔcOnx^FndrNɯxw/(/3yS#y6n*T [=_2}+Scb+L1 Sq\nV�[q*+E\Yk>6 8X*w7 k~ߐ]q0t$2Anps `<8thsz{z܆A&x�(!K j&@6$�L%!Ac/f{l8M9??iq%]lȎG9Ό"2켼|dOΜ&QG-<N֛.X0A&,K-qd[-Ţd,e:o5$[@Kl6ׂfwjA9ٟ]?nUݾu{E#}ZVP'Ej _1A*)T~xWbvsE-t&0a@UbXqBդB Z"0!%>>Wֿw:z{G X:`^/G8Wfr=. ; B+i#PR)D#6^Lx@(Vr~Wi[^OxuQ; \?HO!3]KQeU"uo3B�=5įD07"Ѥds@: țüf6C,L@Md"^XJ (2x, }?8T:Q$a$^Vg.ԁlHͦ!>p9` ɵ"i03M#oVF`Ce$5XOYQ|U,&|]2j_qf€ɅR@cJW!h[0] M2T>#RV-Z<N.SF~&ŨP%,@i A!^L^(G�:ԃVF HA*z@!N#^W3VhJP+mx:{U1*E PwU8A곯~HJ.+x5XzB+ҥWɖ~OIN)"W)%72,e rJƕ=go!B|(wE"V ?Ϧr!'zfV;P _,;Fq+w1@yRVU<q\=NJ``RmFX,|s0PHa ._] L AxHc#(["mZ*IXaE,0جX*H2\ FD� 1n$� SWX3E`W5 Ҡ| O/@<hPH8jVRi0%QDINW Z|/_ ce(:Wo!'?ٟW4Uw98n{20>mv]H/<2[Y;lf6Eb6=z%!B] 2RH%Mb [HOJsɚ[t>H.x,IuCK}RY%CbJDҀB/ )fN̓�N`AUFahFӸP(@ryYwāAv_^;`�h}:2zy0~ꅢUI<d0߫ {A&&99 "Њ/g<u�{p(2LπO}o{пՕ?SJW Ec0jP9A~N k@^+aNp_y1O}yb�2_!yx2 05nk'$&ހ cšxdtƎO6vJ|h̓ߐ] Fq^9ehQg `4>o CNPvp2p;WanNoyz@y;Od8Z9xPJVN]~Ҟ=m+GVZ+R[XVj=I(N`;8~mrG{� +n?`~9ͺA ¦c@ɭNL,t}np@|px?oj&}=y& ic+n`b?]^rLP:0Oي_ύ,Z9Fzr9%e/Yk`<iq-ee7׭}i+l46jwiFKZ^3v'@"2KDuи&R"PZ�"2P,@(N6x ZZ o1�WY2|m`1nn6<ӣ#d^v̗EoW份;9̆=?{h60n=:|ׂ?){7lީq Ņ z76Y^0u2s:LkJïŅn4EoM02"}v?h{]{}#ˋPz+I&o|:w 6Wz=Z@~1j{ׯ(  啯 z ӽ? }oVAW,}ׇ_=m5v<)k,ƌVt-ZBl83_oZog$ߎˁ3Ƿ |kyai7 )w}Et7ƃlP1xOcTw+"n̑m{;[-!d:ST[׽ZF>} =v:= ]{_#?@X_ģ֏Hi`}c,xZk?Vb>[^Y6v9%,ZXޒ/ַ?0]wC3y~y9\)޵`Ѻ/]vG6>Vjᶗ"ZZ 6A` k01r;`a=gI=w9m i611(=D{t:���IDAT@j*TB'x<`*&P,W*>}*,9+}֗Е0hޮ6j?`LA-'$u >lAyXq3i6qpTg: �T9� h0%>/]U ӯۂήD8AA 6bL0d\ҙ#ٍP]-3J(aF%φE,"?3kmx?Ŷ L%"Isx ^ lN`+8[~m铫m �OJ83p!,T| lt UDx<m թ1 2#4;\=6I94w"a{E{$:IԳ90UH ҈o!מj?:;y rbM w]U"%zG:TA'6oeD\@'_5nW顺Kd)œ=CuMZ"Lc^;\AK}- LzQzF$44sMi^EJT S\!Cʂ%&,3#2k<jUK|UduH�AҀ9-f],%jYI}H '$Ǚ%sdH—!aV@ w 8ߧ�%'P~ iuJN S˻8_dt'tP=N:fTa �{gpWn�YP ;l#w!iX$9VC-‡VM ,!I\x7jv )Od5w^i;K'C./XЂ@ .8R Ó-+ajuVDueGm ~k1&8+ԣ4s}- T, EҰxu3 &bW$\ }AH$0 vyQ2سH]Y#s/wb J $>dOE`$&;:|޹p5?;nE\ "u0WpZBg *"bo61H7= ɛn7ΟVI %O!v�P "h"Jާ$a]yR ib'N>h^n" 2u-mYK&gn(LU24~tv �x~.YY Lk XT޿ϻ!;npI'(E(<@Yˎ@da ͣ.X eP^Ҵ}}GQAOExq\gcqytC&\2tG59oCCxʦ g0v x$yVlȕ⁓q)g,a}e4"VxMWr)W%-onsp_,J^z2bX!f˸0=42;<څ<Ũ0r9܉&TOV@}AŀkO+b�"ĿcGfˊ0𲥵]:YDE"@EY9#WXD{r(jWeWq"*_`u,J^M(Վ>2"uKFoyԲ OTj:iu^ rГa+—EjYZ3bR͹a(d͜Q#5rk \!Z}Rr!S *&˛j gɳA"Yf ulKJ$gW/z, x^sJ@d͙Cbg4zdwӊ[ɛnANĭrB.{ӪV`J`ub)zQ-p#YxGQ<E"54EUoU A$y "QR⊮Hٵ T_%Z]1}ʁ?ڸ1ե'zLՌl~6ڙկ^hi2A6u'W ( ./zU \‡|)HUjd.FPq}_m u~ S�- :u1@Վ$뫯`-_}7ZNyjd+t. r<Oyu;mWH.#9/7 �r�_ɱ>NP=KqK y* zrN]Wr^N̙ddgY(;\DU ZpUO$TRd6[$mm^&ztUcT1S% %& xJ^J[HH_5 &&h\ 4*+3f�Hq]`d!2IbC&lOך F޾*,?֥aKgURdj.c]F?Y˻ ~*]H])'Ӟy/\LuO[`״g.}آ<)<=o$K^z#D嗙s~M&jϣWZ r9} Ȋ;jZϦkl*Wz45"ڶ|0$})˱ܐx9O$p΅,kC,E Z y9are }"g ҹRdr:)ܟײlȝC l^?sM+y2Pg9U@ńd*zWid�DN ~]); !IC@ :oo; mpwH8k rZjKAܠ s1p0pzl`q#^M7Th;2{ˆ=ntWZ ؇p਋+ -u5Aۇr^ss={/w c5S]&l;yzF0c5']˓c9a9�\ HʭΫ\-nk+4�!̭GIMy$D:LsjѼ4L7,$yxsՂϭ܉<2;NN|-šT '4N 3/^Ho I!VR5uht@hR]ոF3h>do) {�m]�:bBsotGCKaǵ]` 'G]r-&`$'0#ưֻ 7!/q1}±6K^6@x@Fdp4 9�vN[( >-uH -2criGq6?wc9".7T�OUc^VXH6:fw ̾4"ߒ-!� 5䄜�DCx�|?�n6pr@j[h#cN% jdrmbYqh8KYy}i Cل$޴bHZ3Hɇ&1J }չiе[]ܱjp >N࣠.4ʵ``-ĹƑP sWaSVY5< 0w8lnmHf23."@\M.ڻAs @ [N$f [~)\ N63ۉ3B"Y:ŜrbT7`h$'S]n}av n8,Q46'qb)aK0ȸ;X͓P'LZ qͭY߆\jP;|d<iuTwuwg#ahBkZDXx x`-q+ OV:ILb+w^9W#wΛ32C; ɘ'3əyq>97Λm \獙ykG.?w3:E3*_ +w$uMC3z6;wF@"`  "}L "Om2 Aep+8.o@] .șkE`ID@"@vcH$vpxH>DP $@z. 5$մBN@*dЧ%U&2#j:1◘tPvwtIy9uDJz% #+BGtDz4!\9*v"ُOu|W|G<𥘘BNಛMsЯ/RGXDh]ADrcyJt)]Kꋤ7aڕuHKY^[.nw ,\^XN7嫑rqY߲՟J^etF:S pU%`9N4C"SBh6 ǰ.]wuUBm"P@q 'w*&L*%QG)ev <oDĩP}d㊵xQ ]c6rEN"@78u�Lo]CK jsu ̔5p]?+hK�;+gYܺr ` N��8_lZ窍uwN�NxԼ u!7vsI9;@xU"\IUSbI[QS /E M_,H헡$o͂хϐ"+t,%V *_]M9 GIa Do@&hrd(G-HJ}vHMf3 9_㳅= �ӆj ȅ髆y<k]Spb$<�+-g}:T% ]$VuZ D }U.LZ($.0iaE HDX�ls-  e@osD `߆!<I %Lmw6{CRΆV p\sD4eI[v%i}x ec`h`'o&Q�O˞Ouqm+h_s=;aЏ0r. DZ$M5#I}DU#~ 3J?xׁ_ ';,-vgm,\-A u γ,;ۺm Bj;ljO.M�f8&_8�X:2fϹPv>|9X\2pq#+^BCttG{X g 瓰�+Xi qky-&{-(bA569k" rqg<, _!q`9`]^kl =TDr=o@Hy5hSu3WtD+t4R,s#7L1!] Ό$ӌ�L8/&1aN)Tg|i:15yO%Yv�|-׎&c ,%cFp k50brX0pTP,)%lx*t] sנW Cy\{s(s(܌5ohv OX4u?ߍwG? ЗE ]/'5X3k,2IڎPC3 MxuT 8aTNz~{Sv}/.yښ}ڸ~ԾB-:š .z}d|f%!I`QyO}4HҤi;:FqUz:}Lʂv^)H X…Iz1CXuB Ak0D.An-`m`~#lgڥ*bV6/$T=ZfTYѩ*pj^IEE�z_E݈W(l2PM4`G6ҔHLJ*u=ՏgJ*|Np#Gţ&#"ΉM�zq*7#ً. *~i2IJK;"\TO7ޣP,lg7v.(̭b,*c4zѵEvW\rV68V,l�_ogyzUR*\{9n` ߭*o,L cU!GqS@:>{܃tXyӈaqG҆xk\d՜6Tǫ�UPӮY`(N\0s,|nK~.$GSZ1&.s 4qY҂\ĤxQ(cYh%AK< 6'F #E<ʭq`žCE>$�I17 /fq[SfA[[Gk2rUpT`}&O,įL;ޤPp@2pt Z ȩĩS¤p% 0*4'A,>hN27\]˓~C2a^Xe'iU'9 kpkp _D_pqn .7}I٢(Ƃ7@nܲRlkek%i R`-WP=YZUHpv<(5,-cVTR7Z"itKY ˒\-7XRwE]IӶڛ7,ɪn!̬SrpQ3@{+Uxz\^1˵0pXf*Y:Hv Ԅ<a\܈&#tǺD]X&/eoa7|.rT@(.8Gũx7ΉxS�s<bkf)5kw9>A.L)Ruc 'N9 qm\F\„agm\(Yl❍*#꫋*/s@"ZTAuT53TejJ&j6*&WHm!-()Az60wpMa>ږ6h�>&We�n٧m;&�+*%SV`0?rOA׾E:9+ ?1)e߃5*轖R"<V=\'eWj#r]NՍTYT`Ws:lh] WEpxQ |͇ oѴ<3L@{`p&Ʉp]JήdE]*W-]?G�mg5x?ƲN9}:}~V8:GdꌧYDrW@S O*[ 4j|1ճ`1 )s 7qf9XϤ kRc} UIu~hZP7R)H}-UX^2~́XfdJ+h?ek}1j[pv奾Yk*-.s˜YV{#09FF�, Q#N[jt d,"ұG:ꬊ+"6Yku|+1%+_&2S%䢀,oAk'愋*^G:آ2kϑPbi& f>s=׮{=.\-$us"}xO_e>Ev8(̑z82,aଢ଼z]?WL n.�(J4$ɢ WB`Aa)5YꟃzR/1 Wrz7*Ɣ4έ硫e4 @0昱Z [3�2$5`a�"-/) VY)FˀViR1fNά3d%sj f/,~F{YD2t~Jl&a٢~6-tEsGҝf{d[6 bb+ew~+C_]x>{z~څ&=֢u?)Q[a8�*Q!A +ň?؅?T'ޏ/D>*te0}q%|u w{b7poSbpe-)gWW>5uu5Q؀#unzkիBU䪭VCN/5-b>4i^|H7ټkjs6U$jL)MoC "<>ɴm \u psH͉/8O9f{olYjiT2g·jTQǜ󫝼G(p { j/.CXVtcqz<F.k8S gD[+:$;% Su&-uU]&z{|r>5]pr7xs=MY ydh g%O{ ["{=h|j 7 ,= O2<;{{m Ҿ2w3dgD`^W|FT]x<Үg"{3?7&#Ӱ�l?p9'%`@XkTޏˁ 7IuI7'q<0d?,KS_4UZ$k&.&V\XMBi>e?Drߒ,rۇl_ZVGVj)_1~fL?yɼcgI}@Z&7`me8n]+us:\%(;9'Κmoypi<Vт9o"(suiĩ3+0m(':k0I_:\q ڰs<G Nc]0F㉼YKNrs% <[gk3[ _$NZ[\/N| *Q_O-ک}Ca�i31uROɳ`.jU2fᎀbd*kACat4 Ź`dMﶉ�v DD�IC[AԶ7▵`U�BvB?ހurm(#׃ Y  cWEɿ~Qa.څS a`M-A2`D/i)+A ~ُXu&kî`z8W\R2Դs'fz0.P, "'M!RK<܉ ukp72 %v 5t\Df.`66{\,?k�{6;,⹸C9&1NeH6M[D0n!5-lp(@cEnsXB4d 6lrl,k �\nQX=4`HN-[Bk1tiS2Lq8[5"ƅ~mն9NW"�SˍmHP#.fN:K\.vmdn5p -mFmDvȺyv!8| &qnLRw|5q_"-}NóY0*HE- G&ΊN^0\6>[X-g쨣Ҍ X|N�QJ[QOu.r(23lSyg|vlmD|Lcy D֛!P Po_HN9I- DX�6rKDWCeD`[M +D YY ~k KHHV Kp $ HYR s 8&wZ8Ciؿa:L XإI'o7`m�AMn:LZdHlnpC��9 Dž'9@9cN%*8>id yuc1 1϶Dx-sc665ˎz0 K̻}fik>~6U9}?Ҁ?k=xJ~u٩-a'g'ue@nÄkް\Y '&N=A xv_ :!tDpb|:�Wn0qbaN8'I{RG?\gK/h4''$,ҶO윘mϾ 2 wٟc'm﹧XueϣEμ=SSsA:a=}[ER_3K8" vP&Ё'K f@�Yu2]w$6bw9d+5\v/kslbqI8Y4~2+^:rr@S ;+lҬpGc �KKwNkךf]e &A&8TS)4x _[Ćb)9 %IeC)E"N{齍s2,D`{:@)?3c>n \pa~ׁ-d Dڅ^ǰy�fgwn8W59ާ `h~wBs?PAHK@=nS^ROK}Tc7mnWa%cP{m|5>Qr>Ngz;!BO&?Fׯ%OYcSb[ 'i9x,߳泌1bmucEsFPέ{66 zF?ŀzKuVtMt:�7^W}+tJa+* Us�. \ԇR xLD * Z:0;PcȧM밧K4e-@6rNwY;1NMXTaezD8*MVO[4GMv1XxT 9X9qGB 6E.cۺq̩yqW,]H~"ҌT 3@%(L@}ft}V�Dj"T3]G!C KUa@@^ojѿ.D;5A>rN]VR�D)ř4 ,t (Sˉ?O?7Knk?UG~_`}_1hk-`OBx'Uh' DPJoI}\"% #0B ă ,=rAT'ihc4s. ^#V;;"2\/g%Hnq,tmRhNА$XЮ 5,4@ҒN]n,ȌQtP fPmfPCB"Nx2Ksz-H8 ^{Xh;B[E~CeU8*M^[V�, ׃ ~=,{ < @x_ a;ÿkGu`nDx`PC akX7b4p�q a- SC6\son *8\WƱ 7ŊΙ2ɂE= |-|8c+`w =t:JCǤ&7nq᧳p6�[S꭫5S%AjC9U{ak<;M_uGSǧ4>Q?~C O-N}jqoCty%i|>W~9H$*ɒG(زKtL҈!ɐ*$H� ɔq]&A BDQ3�BCtɐ.MD (_6ɄTY)Y"8Yi' 4wfս@mC]hC'DѺZy.(g,FdY7@Swww)qnI*$#,n3 Vawú|4@6M8.-hym"P!7DǠf@n'U* maYmrU}l_tO:ϓw-fl?Ut-7ԇW,-&YRJڢˈ;Y)9kXNmc*B5\-p}AAyʈ-]7l6 F0 "33H}3`pq{J 1ElkaK Ǫ�'�p4|)ae>ٶ!z JF #[ǚ0@mbidKpg>dDi`Ja1olXYsrOi^F7<Vc>p>-n j$4SŨtNډ^c 䱰Sv5P=uz Y*VLq/B0jf`VMfj[*&f@=u'f:̩d&$sNQV+f֋cUS }Nˍt¶'̙r;-y]sۧ>W+6ݦX\55ҝo.͝HS]"$ nL R@0B"x]FӀv-Cv`!7J1� .54LuM @ ˽&΅u W7G()H,6#F lӆR#!AxxmI`ػ~s IV+|Dj[29LTd03Œ&:4I̤T5'7FDF4n H7Q5L( P.eU9YSz"u'3I,n{b͆*jSXj)xߩ/ [?5ȣR/Va*9Og8JY̜آY}U&7f֑nak9spjMZSTg BP%nYREa96#O4x)m{r MJ*r "\OZ%D'r0NJeXҒ-d% F V,(YXNe.3dAm\ABN.LYc$ �IjHhOc_"Ea;|`>&U k$.,kMStMKpVIǕ4%6ӼRʙ2/3 22|ZN,eUȾr*^d(MS\iY4*[Q,=>n ~Ԗ?o7_,?aT#f 4~fM`2ϩcJuM�1` 6D b^Zm— 1 j6>r>+7 f<ٛ3jۨZ|b7VKkj;ni9Jy,JxވrܑrAF%93r<Gy@sM~Fa_;'rPr,JA45MD+Dw̨+G9+T{Z8U x_beG35h?? Gsj_փk-dnr΍GI�W{Q5ݕF�x=E7^tQqi1+^x73FFܽ> EݘF�0<nqocfsgS_nLmNn&eskHҊvSߘYkVTgS>9 ՘'K %fp j�Ϙc5F̬ޢ坼 WhV/-Z-͗]V[3N@"A j,Ø 0 #Jq_rdfss<佒K4fW�RC"@r/Sa47!(%xGlXN-`̄�jeÓpX,w~nw/w^YS"ѵX;&~A@)i`ލ`"\iT2H@>!f%kDpp%B֊"[Gp\m"�8>ڏFIgWoi\-o�Ӆee2h?k & -+qOՁdS]M)A$Ӂzϙ_祕f᠉@\[Lǀ8v8-ԝ%"h(mC"swϙ0lf`Wv=7]xu"3(<4LH |VߣLa,F @-(N^G Q\�;b jJ l_3?>w;\ 0ͿANp!};/G՜䘽^.$&xl\K݁[<ij# $`Qsnƀ {IjHLÒw a,r&�)#,9G>$ b1bIkJ~nU)MN98KҪk{w#ТMX[4^]SYÒ� wNU]6aY9BulC39`߃AecscYyy>H1샱=Ǟ; Asփ}0ueWsAe9Au{!?pcE 7xNx.Sfq@9#(Y ̃i:)ƟςP'�\ h3ϕ ?9/J BfuIvhͱS #g*'8F" C0~GN@h*rd:L(a 'EJbRyn"6h,Y5~s <ZY@?oqNn[CZ6-4lLnlUieymԝݰLD[=؄[�N5,H�(*yVEx_jOWTrru=ze=]*+ VR[߷^UkS lZE8@]8@-*b_UP_*@-kO'P&Q_[O+jk׀' rъ>p_lE *BJ`�-<9U$ ʀ?0Ho<*OpRdM3]RK@%"`Rx-K+!cB=!KF<Hf=WeFM'Tm S$m!g8.eUҲw~xgu=Zx( ^s52O'j89wVEc_-o;u'r'nԡ۪w` ݛfiz7!UaLioD�JbXZ06.WxRVVie3t_:WrR!,#RetRI5N57p jlU` ʿ<`3�AHg�JE<ӓ]0߮<%jZm #s< bP9<ZJj,RDҵŚ_ct-[YƼ0̚uj a1_&PMVk ·y⟼lpt؉�}zyU 'drx6?8U#*'˞+Swzn¶[]'eOԿ2*@E`Qa3؏[ċ8l4؜i$&FD2lzQa>F2[H +Cn1\%^,GHC6LLI lo^&J6kP+Z1p#[lQ*ycS1`*Q _q4DŽ`�mf+•,IJo"3 [D�ޙvwFaHZ}L5^'Ghz{6 ըd&hƢ 3JG0Hj43͌Zp6�Q9b}'j+}׊ي(E#0{ kFΥwQ_m^;W6?<D{neaKF./~u~)}qfTc/JգUGK13v5V̻_|%NóI^ai2iR5�t9_6'Ts 9<i% 3jV|l$BNUt'<0]8/N\9Aq�56mVQӉJ$ǡL<9x[ (LvBCXx*_(Rҫ�$�Nglg)59s#T%aCjR|%晒+q//< -: UyO(ڼ\6w@NrQ+y$N6PAB:8$r"h@e6)wt>uU,:O+.-)g5VX*4\`e M8t1J\{Y C5ûXOAq]_"@zs"ny&i "X \Js d&i&ށ2ߪ`Ϯ $]cۙE"H`P@k̃{rkv.e+.r v=AH躗Si[ƟzʹhS~ol&Oi^]tf&LO McN货SHզ/|m<5JhT,te"iɪI JF~;J MդB}~Gm=3bԯQ2rESwyYr&L~sXyʁ KvGe#3wrЄ`FJ3D&;pcX(0`S[t .Đ^05 v ,C] ROJ`5iĉ"Ԅ�u wâ\82IOB H8{Hr'!A?!dQ)(D B�B $}>SҾ Ϗ;o,\-F2;Vķ@Kv].k`ϕ]g$a--.#'G}~.c#3]bK!]oH]d}r1-В`a%з@@)4~ ҡ^z=okCehUBg{_@+Mk5텺_5K exfj?>㿝Ýy>pO@QI5aݥ|8F&#̯ vt !h-1J ?@ҡv�R667փo h>�m!YQꆷms}&/ZOkٍvھGi~(ǖ >aQS=B-u;8F XsWo8ht^k7 s )T-t+WԗkrW^vwg:FdkRfF| } bÞ{@O% 5pSdM!/|aly#qi`xs9nUQfpMtE ]21z8J^b$_䋔. 2㞵cH�Fu5Bvxz0KD`Jt4PLl69_v8u.F$H={+0 OQ{̬`a*-{3 vn+6AԔcr)v&!~ W6M 6_f;aZK@M6NvΜ(S]10?ʰt!a K)[q?o9l)aGl,]֏Xb*bocâ|ʎAqb"8]fz!-tbWhKh5 ׿ %�o;[<uG;~<֨B9j?Qv<t;AoP::Ό#c8#Uql{T=i 7 (CSP>{u6]x<y$@6$8qCT5P/:a@w>8�Eq`q ,]@M�E1*bT7 �V]{hd.O<`RFƈC%`D@b(F1 x'~2rgUb�=uzC=�Ū22x&3FF3^1xS4Fo t< c!Wqȯ>C�Aā̒zs̈(�I=(¨!.̎R[a^'xfGਊYuSq`l3{s 5hi&'el49!.4F3fҤ4O� e'SOVL:k(<! L ?M^h 5TH-n&)BQύPCiiZQ%33t=*6ҕ:-OphI0Qk S&<HS̾ LM̄64 m 5u`9N CL712 0 -SL'؋k0qYc&h, XROǖGqۄ<s4�}f_ES4;O;&MĴhz£ %-3nt^7aQc'&b@? SE?1,%ڐ>6V OS<ֵbʴb2/tMfeB ̱ѓ: &dMQ8嗎2wr"VH9QNEY*'崑x;U9 5Ut>-9JJVt"q9^Be]3ҢLT�m29ַV(i~^N2(SKdP^r `)=a&uG�#Sr9-_`qZ~;,knorBD<y=M]! UtUOKΗ. ceo董iEw(Y.�Г̯v@eX*L`);0nəVRu9 yLl<i .SKD֥ņ-M%7< ̍Fqstf[M+x͉͔o#j3== xxϵM&=19&ӧSD̃ `وSh'6+vh7C^W/lV!- w>)\ۜiwˡFqFl!čM&㉍Lo>Qaj7ǹ;6E:)_0dkqsw�LlmJKhL˦rYLw; fFmԠe^ sW2llfsA= c!Cfes7ukukːO7y6IE7(B+=)n6S7<s7k}`<ZYs<܅"S!3Uj-!$ taD]=S`$ j`1~�rekVw(�}%Y]n"0H) y]sW\[<|kՂ Co%\lDp"ѷ2r`*˷}n} +ٳm"O<ORyckX 1?w%CaM",O˜?/Ox ˜el#^9n{3gq>P5<({ <EU�ؿ]oC^B0. hoWEIPyƢN0:M_|D"dl(A�"PB0Qb/ꡯ4Bwxs&h\A V3E'�"C@%3,pٖ,5G Uӊcv9KCg )$9yn㤡1KC'e24&8ӑL"J.Ic HӠt@O\�@1<,L[c� 㮐лGL5i3eUHHwy0979' s`\ Z +2+Swd*U�F.a)yd"z.\F9d@�F-P z^f\B(^N)/i-e{~5ׂ508 n^UK4ɂʻ h Rat -ZU!rKTJ8I; c�ux;4Ci⪘"F41A_0 )QbK*Qxyu9Q @<*sxG :.2�Àrt�%OgN wbHK1�|uph#xlr#!&;q4H p87:{^GL;g7DᙃyENq|mbF nz�uXXVDBP"eBcpepFBk7=�I\ +oi7Gqt#8GD  ^7ǁtu<N}m7nCgÃҽXW-ƃPXvFU< s`/+J~)jpw1<ߤ[xAD/_%})䭷*P5r+YR;nRbN X)je+) N2뎔H)[*!?N�9ꥲk0t&,R/"N`7$q9ǽ{,Pe,^2|{PgMIXop -BiVH0vwi q<,a(e4aQE^bnyr.ž-;J& :vM CL<? 2~(�brpaE)hWs QzF𧡕%BPKI P7:1#DԬSFb^3Z[k[ҘR#bfͯŶ1ZjZͪ1leP,31j+I5}SaJ[j�7kɺYct,լk *5>VhMٵrX#t|lcJMjZӵVSkIk0k` 6nob"j1#X �J)ԌX9XfԚ�Ķ:8;_^3c1R#޶5mP#YBK.`fKM>SQdmۣl`[KP(3[ok0`\7zzQ; lV,U 2[E(7KW4ukFrc1kR'kx zKѭ"߫!޵ޭVHւZ&}Oj̙Ԏ֑Z(*(M1J!kT1QЌBY3j2cqB!sԇڐ3M2OU#C&|ءg ϰA#]ጦ 6?dqH mXN`j Lc hQ>۵XY~ upFSCC+QP5;h0Q_z7CO@^Յ!ճP~10P~A3m�#=6i||]hd\ F{0 D9T3K?o�ňGtJ :)#f0FewF҇z\^ 0gt)>W:.Ʒp h6a($G{ZT_h/e% WRJj^S(XEKIλ}Ŝ.l^/łR(h ,ŇO ^t3Ų\ZX.EO=ߜweUќϳbr$.Eo~|Z)_0ͳfZ<QdJf|6>,91P +`p>1/3)拞@]TBE }MBB|L_w=s<Fjd~ aek-mOO<_"k%]OFn # P:7xj'E-X["ߏ7Q( ?:?Xơ]Q0|g)10oBwG@7`y *qO^ڝQ0<73iuOΓfzBuޚI6ݦ?c6yӚ6fh6feZ9IM?mN!etrzy̜/O'/y|i)i6tfb&_| MѬ4?2jkMm? Ptlj31(^)Pob:;d5l2{`fxޜ3d<lCGP3\1?ƶЎ3(\6ej񱚍L7RH =}{|ikF�Ux� 02&e6M>7IuR qvޛQL",8^@9㉹m0~s7+q*Q{+ PtiK\XqJvvOzb^F.tk#|BG/쿲jwry{~nFf0L]v[nvϯGM@Vw=񕅑%;F_"#�~Go߿qD{iyD+A\BH'erMF c�# -0(=323E>CrH{+K=#='2&{ۇ~#?WPVޝ/JE!zP~|:29}(,Chk}7yjO+/-3@N~QϹYA?K#+Gtz$tc# ۝vv;+v̋eV=Fc<21rn?ڢ7C,Y�e^X^@$ .W8V_A%U]X~kӨkSz 6�4 >z*f+'T_:_YҔWX%>Q-aCX,il( 1l[;+^ -. 0kh@GC]=u| #3hTx5)6N}S�o@Tk= .hc0 p^+_gV ˷Uɴq5gZUɯ ޣz_P7~C~T؊^w J£dנR,,iC}7@pf1<QP)jzsBaT TT^3 u-L{`U*Cm�0K(Fh}-Y0v�Åo69 Lђ{܈�~)ˣY80k撊R|Ёq @mo--ހF(ƕI J]\ qA+C^F k 'sqLã8K q+jl,j[Ϣ5z\64<Klӎ,g{^CmvfKWl)vY"366XvJ爰 [حlr=y]H:#l<a6:CTiDf*=V]6]a\ dlZQç�ws&|tJaOT$p `T =IvX^}drg >a$m>�Sm�HЄ?0,عä̚HB1 c(D�D)Nf4Ъ0+\zر&ng0kh�H &&iуOegN vbuJ6̐ n:b9 uuR(`uTdrIs-,g(sCmq|<S9+#g8' (~ ʴ^%Y 3rPp�-P2DH`,G 壢:g5&vHh@k0g/yG3RN?`UJ!F wB=ug!^׽:b`݆X@!N~RB܁3hy0 u{V@mRMSvثk4i]c^E4SS I#;B`& М}Gze- >p7'Ǣsc0u0 #n9R3=K)μB蠢HCXJ߈=_%J?fLJoHfr¤lҔ'%fP*@jLQJoJ$ͤ ְ" 7+*/Ij2PF �lԜ '4kYzMq@[Z'hڸ -Sh�|0Ld5󤙄92ՠLph]0aYS:oa?W0vYo;o846!Vu T&֜M >Z*L_1 pñ`_"ʍ '1QuRѱJƄp Y:fO0q*C' O1&FgYR0!zѻIı7<'s~IƧar4* TM24oUKMra2fN02jaZUR7Q^E(Gf4TxE,S=.eU^+4,HrG,dФE9+_/dSkY|:2zZreSW£eh2*+IV VHKY/ ۾Je2 *$] #ҭGQ/nn_rꉾFV5e ޠQ.W{KUW rFEԓz\tIˬWᩘNUĊ t^F5h%H%7*Y9-;2eB3vP,~G+`U # ʁ\~GQH�A*J=^vDH�6* CT1S$3_M˒jr fDYiQJɎ|<sR6RER7vbr0]Vh&i+n8Jv \gf܄A<k16'77'X9侠O7S(ͽ l&s'V5n41—&ڔ&5ËAKKOx۬\V7Yħ]}<,O� ` /o.�6/scg"su&sIMF%7:Qks=?D7Mbppo~w p&oĺMT»x~gyW6&$cCO''yٵY'VQrD`}:<ǹjtIqOORN0<X\IY/'^#"ط''V]Kxlzl~&S%kZM*4Tn0vߵ3wZx6IHI>.v ɵ=϶1XV7o\:eN]X[93B ;Ng#Y4WA+=)@FtX[.Xo5ں&bJod@ܰ:Y2tlE@bb "eL�#\vE.0 'hm< BV!OMF!2l\9K[i {֓n�=,3aEw(>n c#zz-FrC(f"mpGUh]4׍sǡQ`w 9w_IQ[YO]|O<[ L{awn &7|-'s%'Fq7ҤhO.Vli0\hZ$` TmO�?̮-s%kDqK/rl"[99e`$] Pb YW))609ד\)`.9,dzG&Br/l̴w{\2MN7Uw7RD.cpjeɝ\! CS L%փ2o?_^fYZVYwpZ�=$0=@*ǔ|&_x,4 זҒLЀ/cDzv@F/K!yld+)^h%~FPJ>`w<'+(7>nLb@Ю60Bh~5.2È[Y\x\exV^Fs9M0$i^9A= @]<u oD 08t:t T=(!䵻E-�#FxƲEϵU$R�HGK<4,lQub_D:{;7GQvw%c"8uR{ϥyCHA;0>pii BbC:}#W|uGs 8v<~)ꭗ v:<Q$Vk'ZLҡ}*A}57и EƧx>B;{ ߴk0"D: |'?UI'qP&o|NEܴX˜v7f¿ދP1tryV',AZ{T봠NM&k!r#aDFk9pSم1'R:p_fIxNZ{H_'vFsrs&uADzY|=xK>AU2~Ư+oD&;e%<.yrƾ�+Ҷåe%9_fL)>q(KKM|Kk>y0)4^v$6Os 5M !x¾�HkYjI`\+�9/-qh�[rey\ݟq11K\\ %9jB^Vp=\JԁpטRݟ[]>Ju,(4Jkw[4lhA;6@iD0Q7V%he V46H._|G 8w]z7k+~.^d9,YْXNZF7= �8@e B)6wԚNfJ߰_ZPDU 7O֎/8%z[Iմ_51eWbZFj䯉VKg ;;o&j3o1[[Eθ Y^nMz ƿgĨiͯknֿULv$bZsmg/GJcGź <󷒭g>d�{r~0AM}X>l-lMm-4Zcr_<F=:%5hr*ƅٚ5_'cAc5-_C b; `DkX clQk0|9ޥsԒ> 1ӌ^ë=A�3x=3]5 u\b#i[uļ8@{Ĉ֎j }3$wp(?kfF rMGC.PJ=UFr18Bh| mBf$x_|C< +/\G~uǷzR2u?e2g0yʎo%ãImˆˇZ[_r!kϺ@e7^;?к7%Is8T/ƣԟ<{(9ՇFr+Y ߲5CC%#}H}/7.zطI 3$ 5 0zو~x/O2BKw(M@?}= ) 0)o|Q%WgoZy2NN�1D ƆCF~[\e0=ea~ 2<{УPb0_htSzCt潢?~^6yJQgh$ ^vژk~ټRJ0k/pNjr1ϡF1}&@*T#UINJ߾ew_y*Žjd>YԊt2o*d>34ld_ J�PYVJ 1EQRS \.˵}bp_rQ,B?B;B/j՗m>~cC=FHW}>g~ü@?#|bϚ7ZWZT.`tbp- w싎<<F(ʾ.|9X X#těw�{%ծyve^x9{H1}l^VØ)qH?}#ʾea/bXeXQFzőީMu,;W#}7罙x.LwoWԦv"Lm~e3x >d3ɷ./l|4 5f?4_p xv{>?Ccǒ߲�RePMfL[ܷ[>� ns.Γyy2M6 W)? R^K4 o ~%/<{Z3Lɦ忘3}'mZk:H[[Qgxpkee]Лf5#6m:C9y˂]�.l>~4}0z ۿLrϟ'9=>(Af|pfߐ^ʅ'ϗg<#|+?Wf`&b_tm<6<FOUhߐפ3Jq~t'ou޿EGN dn'6�TXFn0,߾vh_!#|Ů]w78G~ғ6Vh Y0YY2r+=+hf/g B[Y^}F~}me|a_zȕ:"�z_ep,/tH_ؿ=6Gij#�p6º!;ojqW,{}zѮ݉WYWWfGRO yꉟ%+Yݿ}:rEaD~g ؒZ ;ݓ߾J)뻝֊]Uz{¾jPqa%o1V/l3_ WRbw_6 /puȆ_cϿnvGVZw Hw{-~9:G?{~TF܃˨UX[Ӎ/ϣJ/Y|Ds�2 Vu#2vMgck&nZV�nk4ܰZh{*O bqZ�=v A52jP]hWbƑkm^z|}ҷ^;rCs6|hoGK;Ĉ4n:o_- @waAx?ZMY7QU9eƢÈ |އX.zZ_._ژ{dctyDɸ@8MbS|_ ,lpو$d;xt{%8:f3dChɐe#4md8nmq)78S&#1b,TZ̶e9 h]shrw.ˆ a S:6h؎*жs `sC{=C>~0~!z*d~RYPKi Rhkj蒫%Pz@E 3!Tm4hv$�mL׭=̧ u+4r.ZIbgm6+aw=ZY@I;l+j$gUvlV[g|'xV+a@jrE1ٸ6 Lb2<Ol2aOo'={|fi7�p) D@ϊsd}P+i foJ6'�-&,|`wԴ9RԞcV gf*j+v�\'*Mԉ%VRg>RXάj(?I9\9 SAhcD]KRmo3AXK%CMX$4$9:&; OpxA]JcQM3" md)u#KD�!ĶpPQ6'Haщ\=g<МPJr9Ww4eǨ{x>03^>ݹ )޴�FnURHADsvhQs蝠?W7 v4X*\G "q.g7 ˠ�:5WW)aWgVp%ݗY! G{+b>W63&V^_htMqIi};FyӜfRocc/ӏ7ccX׏Qr,%2D4=8i)$X 녵fXK s~|7wKfczcڱxPxFw,6fM1vߎ`V7o@$qmV_?ëhVt<_߸c8Гx>_xq+Ԙǵ_h&P?I:h<LJVI1{B3diA`& o,S~^M-Vw|"qZ+WG#BY;竴"N1& 1UvS-N_.ަ]icT(ǎ~GW0Y,W `>.oE/ix BS4KE>0J Rւu@BZ&R�NZ7Ih!(+0nAа}QO W}GS ϲUk@ڳx7Rh�7C.X 5d iZI@=)j)wDv"Ǥ,e6R?UuI$aO;+b.:z8 tGt 1e"RQ䠢,AD#2ѕ ӟAK;~) O;HZ˖$NǶ`ZcP3>6׃]?!RCC{Y'/R#]ĪAYQ"ҪLo,d1پ'%a䮫f~lȅ]|D9$\JiŤQp4hVY]ӆ&X mztWzq q4+VB9�Q])tEW't#h{˷@Kbقoc ee:+c 7u~%rd.)"+�1KkgxwLMOOewf6='O&[On$o$nN>6'ZLXĪ{fcȓNesz[_ 8ٕo 7'7k^j}u)+vim3mlIJJJ<䪝MkO Z\^v%ZbK&7Oٛ';-qܗra0H )oKpΨ?' {A6fjH1ɍ{crcfc=GܩnǼǂom1ۘپ{FԥmN,ׄ۩BZrg[UBC6*#Fq'eB t'6;;$w6&; p'{�^w6'ԓ.ؙ@"(l*\2fy?s.q\ƿ  n'{Z?@lEŋ&:[̕\$Znku\sk*X8 Fvu6-B=+zO晥y _9>nLjŜɈts .`;E+jmk]z >jxixq7 &@~>2Vҩ:>f}egE D�Y &Lp7<G8.pwUrw5 X $.I>)^+ {]նCT0q]ӁsԽ_pmhCq.S (XGQZ=Y]/֏Vn$^=GjN8���IDATNjN)!ll( HH]tIL`@S0wnAd̔P]VHr69oש[w=7W8Hs |-tM <|095hD<'!ȇ V8�J@AաW[zf+.iCS+ iY1Ƕ] zSӚk}j&A3X ZorK<@M hu.mX jm% -Ak4zkM)SWP]nXT}Ys68eN �[7t ٿI]bE1a%RiUl4==׿c( Y ݾp&Ւ`3HF-ԙ5HhrN&0+ * ঘs MS4"3 b6�@TdjG@PvAvA bSfD䣴 -O]>B4R!]?KM/pCCPJN5WE|?265T&nLvϬ>2fOk@19 Ϲ+ĠP2,F-S=r"Zq_[3#K+VG=w_ =Q{ =bS p,@Js_F1VgE8bl}A_&|ْzߨG^1Σp\4$ssZ4(A/Z,/]C+<@PlEٖjvZӋzU@!r�ţb=ǒ՞ȦlJ7!=qr$9gds+Fg`k,=x%b<$%!Fz3+;z䘐s)$t"rć^dbI(q}Y•XsCέ@=JZB pW[] !>-6Š*J~>a.)&9^wlF=8E\vW+'&Գ5bJ׊0)^sh&-9~b˖btX^"EQe^CDq(Z.Q! %oҴ|8lsYbah&YVTLeZÙmO%|jMa FCWߞ=h.}'-Q[XjNZb Ncv f+ċXčRDLՠh#9&(A hiPkeC20@\Уb`P1LI*m%N PDJaAx fX8)!,>YUHƟ kkɳIGyTkx28<_H8;S#dP}GL*:j yK5g59%?੧~zdoE҅)>"S>/MُZ4;1 % zcZLQ zD4?|$4kO<Bˏ<ISI;<2:^Fo^{|Č~]]ݤCn hEK p?� M@wn fGZ a[.A r1[F@� 5~I@%ށ~)k>,@2ܢiK\��b+Z�ATXjd.Ak€z2*>}6K~}V>)}N۾U]k|wߞO|H[+ɿLNi_/K3}q}'}1EDbTChlo_X}Eu?Q ~ Tz_;oO|15iLK}Cd TN';/ ?NjEiOw;OKO_L~5Uh*atK h�f,&A�1 @ oZbF� A38x B& XbfOM=< s �=L3ܪ%d:ᙺ]$ j5@A:- p%7[6!K7Gݩ4Q5щ],.h4/͛{76烹\y͓Xh0>X|8Hr* ~(s;GwdRϧOFk<E9%IHGzǡ=v223|vԒw 4*?ѰE|f>gswN.$5m4n?C|z CW ^Nﭮ_nڈհn|gWI˯6v<j( RF#݁}5UW{FZ!TP(429WɓMHBy?�aP5syd# ƫUP9?Pkr255AjIg\mNF2|* P}ZEWϮZUNO�[خwfU鷶qp]WDj\M_\, LE7.+oo/oKhvXq\9n^V"+@5Y~r{i[rJ~˜&ސeO0s}.H_?|=qzK~~"RR凗S'׿4.gN@W~#Olǝ'PEU۪=hVΊY7 J{֚Ug+lB6\&!, lCf[<9OծAjr $kJ.{@:+F_̬gN7E OANS+<dT0 zdttºbvp:<)ekE\N~=SFmuG0rndb;mw$vo5. ˊywk.#;_.;̑4>v_8eOrGlu:gF/5 טMQPu&B>|uʯ[_k;w41s⿦.wGܵG@W){]+dC,Ň@sX9:tXy>p]Ĝ7@}[M)rPޮ݀{,BbbbVtjʅЗzsLIA:)r3tiCB"k6 !M2}$j"# 0,ѧdivG8b\ԍvl|tU 5@'ѝ+aJ�?E7v`9 %)p\8x uB j3H0x3# aFPofy@qw͡;QtrHs Q&K, `ax3d� o+LFnƖNf!n�vؽ4LN olFN vNna.Dy%B\ݰtz:N7x=)*bB;Qob�a""f՗'ڹۘchصBףz$;> œ]Lkyײ-@݅H⟧ex�1/Xu!ΨL #T~ȏct<z+fsFu1@<+q뤾zi݋x[y {s].t,uqI~oa~.\a9͇r姥|t5EL r>Y냗*y:qA!bR&V R7ؘY-M̨VA'c�&H|mcbu]XA zFA \[}q 5gPb[\5  d%nc}i4o698f71yuphX�I.J4S?g7d9FiN.bvspqow~_7F0?.|x.Y~&|;`l`l89 zjӺ1 XD >9.'腓 qx(ҍ!Duc9g! xpD׃N"S'Hi<z#SN4GWY {=5aP;g^G'^208??NNPސ rȥ:Y�= 4/ECr~gݳWn9?MSջw ׍->O@P6>i[|r6GgпBjúR ; W\2d ǂn'^b : EĦzb&}tv P gDmEw oaj|LlԷ4>5:% ztH-LJ f O*ӈh?p.ӟK%.5c eJ %ߢnvh݉qZ7_m/DfnJ"liKDD?(oȮWgX�|JB䒉w>hVdǬ+,lRPY_ ϵcXˮ yȎ[U'q%zp c kUL] *;Z븕S(#rIAx_5 Hk (�* )۔` `h?1%X(1Fu}Ϫks�qYG6 t۟c=y %O[ [{ۈ56A6=A~|N~=2ǷmdD8ms'ȶslQ(ED8zB~8=O8[OIcYM-DJI$m[! 2o+[ 颭/JRS$SNHP(vϟnh$*!+O >kiOB7jC ;?Olx}D-5_ lrdr6e:Syt5")3#]U@@1޳JKD\1.L0>&Aפɣ>=of("$񻯡!12| M`n[rdm"<^ ?B _]InMdh}%]dn !к7pC&W!em\w d(=Pߐ?fCC뿶j()%}Uy(z8>p_�/ptJ|}c}dxCTrॺڤB6` *R8T{Vi_hN(l k)J^ӃY75e|d[uۇ?El,rmnh2=u,Bڥeh-<C*ƶhvKD�pѢ,դEBZi@ yrPȸxm93�߯Ac0XxAثanX:7@Pnj#mAkE.UAp!!4(`<(>Pi/LO{'o˾:^Sb$߮֗BԬ˵~|@/1XHBatOrPEYxtAppްZ$Rbo}<x pZZ`飻 k١u{ O=`[-0HAϼeO/NSP O JPj\[tpkݳX5:GE<%KK  �� &O. x[E[-@(I+uH2ocDnEb%I.2#aٞW 9)q&Rrpl*+s92-=B^Bܫ W+!D�."!/@z+NBJHzVSfA/*++!u!PH: b 29ޛZ!D+}GP WYףeq= p=>-G@_U_h:jzqS�>ܻmh5gzmwd9�ƚ#kz){6%Yɯ 1%�(%(z0 /[}q l5{RWp-ƞU^GV Jਂ; я yi6J�(>Axɦ?M)10A%(HݨZ jʄ~2v1ÿVex6N訳)NAoQA'ZaSmZdZJy(P3� w)|xZMo lCHdh?=_̩f: |H%ӻ l;C JP ჸY9b}{djyЎ)pT| �BdWg?xJ%xaU!%)^kBw\kѬ}. i7dLBr{dm!e9k+MI%�s 4(4@ ZFMjwhH ,(nL˸ `,,@> H |=3HDK^ݢ@SSuu^TvַMS4`M*\ OM!hXE/ 6,0%fcJ*>*qET!*�H`k9)P>{)fJ=<; S�� @O��HH3;a@mOrd��}iD19|s@?Ue%J_Bo+l4>m 8PK18 ڦBłMk^{n)B㽼5ߏt>ÃkEυ2i Fͽ1~=hA%jE8o)eН%@](Aŀl/7>$fE|�fR4dlJM:)f[Zۙ5@&h4f+JA _7CC-\WOj�0:�z։/�Dݜ>yAL!�ݸ3kZ?;2"f.nZUAnlpz "'`P 0h6,QL.xY R NXuW��v^q=Z[ރk+Кs,ȹw��VPy$@5KMŻG!J#4i%ٻjOa/YdJ�y *b<j 1, {4F0RX=aEШ0^jذ듡-;|Z4] UgI|L_7*چk(v;mdޭ]5kF-[ȇ*UmëdqU>ck_SjϮf&!ϓo}$ԫFk2i?FAk7$?/vOA&ʹ5b#8/_'~vX9O'`"\xb8ي?_d���S��w@s `ѯѷǢլJA{A @o Nv6g4B3(4MvxϚ`;הo9zOٳK�EHOW R/HQm jT¿u`rR$>UGF>Alf>q}:tlϩ©6%<Hx2puB=& ަW Woca`m25>JxqtR=m^' 9M o֚eo'5;r0auBaʄ}LOO}:8mNdP 61r*!@SPiy"ctpNlK$ݪRѩ'=T%Q^uvv%; /:@+Xgz TD�XK.s8Xƣk +anS8 Md6P&H6=4@#!^fj?Ux%)㣻8hICo׀@ DP|c{a( ckt ~GVu H �^C:5f)zxVQo!B jcv gMLR<K{ #CṁX ;=d' bޝٴFPrZдUX987K HPPM:06AlGY"5Oh8eWmG[n7vMҮ-p]2Ooۯ{SG!+)p*x4J6:i=r[wGe W/޾:v^c}݃[cSqYGYw~#\"Ӈ^|ڃWF*GGSWvʍWϖȡ/r )+OE=tMin,͐؆&6</E;*àDj kt;^B;<s ( 7DF*V_p�{Y1|/-~a چ_4 emχaF#deonݸs !M(DܡNke-xFA`[nAy]?:xBݙ xgZ+|'A銏l YXCkaiu8A?\yY8q[A;*Gs瞏wGhc&~sOv]y0Ћ˱O`q4PyXZz!sq*5N .7>ϼ@ZK3q.C_jb\|GĿ:p<J?CJhGa� Cx{IMte !L2@V1"++V.wYD pu"Ṋ5#/6CΛnnBH|; !G}G w6i pW\lxÒ` > `E؟ h >6wOH2u''BF P2s6QNFCAQ^Naxa= :,?ycබ '#: Cӱk[01,QS+a)V{xu\�oÒ(_,BkOږqW2 +UYt;fVl^W'njxRIt <;aq+ 3dqF$8Q56\M3RUq³xO~iA leG~ksQZcnu80rtD)GeE9 JZeTi5VE lvYԪذR9_0E Q9:܄rDy#"bA院[S:)*Cyy]1.rXeDy#(VJ '*2-)S.r 2:ÿdE]XeFm.zPz#@3HΑ\bQCܡg0Uu_r/~$Em!4Ԩ\a|'rO䀲@qjHܣw0PA�Qle7%d]rB _m ԋc5EgU=CTld+`)ūp!-’\ⶊ%hVn:9_l^F6XI-`@2zY{?N"QKLelY y)%%XCzE׶JV chcelPV,e�Z)J9(?Z%^|\ۥ 2\F +OZ='4qS!)E W z'z{͠9m C<MqHMm;K:buɁ>}UFUO5I]3FH" 7%HkjTٓx�@и*")DÓTY2 ~P&Gt͎5nj*Z'ܣY#3g@ƽ)^ؤQH%`ehRT:g,a.$& Զ;MmTh!}Ki[_%ۂ_!`R,rcz.4ܿYtSl (8s��1<EG4m-vV K\/PRM~hr� LyZlg!wZO]2EFe{`4zChP]moF/ +�:1~ '%q8{{=xfz3S]iny;ȕcMmxJL}ޭ<ٵ쀷eWfZ[34wg~r+,[i[*?^i,ˊ{Ob?nCJΖCЯG*4U0A'E2 {مAlL SuŭL!=;F(j"Yt@2 рmK22ܒ bMb-G@H5q\pDm[mh625pR<J^Yo P@Ba4<ł(%P'.<7![r#�YhbɡPG͢d+e>.[XFSuy2F2(ЙW~QR_~ː,Y^^V۬5'ܹՍh E �0 ͰJr=S_}aUE|&kmî!`J~M>]6Pe&Ԍ̲a뫿G;m?; '?"[U GqSډqYU�-\<$l6B m׎@Үё OzOm۶^{L J21%{pN@yb=4*VHCuxvJ^xі >CP#KaI0ځ 8^% =�8x83P4f,>` EASS[ޭ`YDP*r0P(Q(A�:W\Q!G?aX@9ԺU?R=TjgݙXd{SfM>Qd"Hg&�mrM AH>ue`}Q (AȦ<W,Y=Ol`ߖN֎N$[;*m>@֎/ /׈vW,(UzhM2�< ]dmhr�Ai`vpxd- ^vҁ:@ 41u�hW0o=(`�Pԙҿ/Kyl!M0tł)sP*++XC(p�)$R4mnq^x43|RI- [tp rd*õ^@W_.umDßL6#GCe䳙 #euI( p#΂089 �( $FgmͮvvF.�*6>؎↿1!ju'l J6DM\VkƋ&Pɛ <.n ِY&% ^ [cA[ځk KiRv[>8,)&qe\/DGeڑr 1Jb4 eBH@<rdhO Jf\hKxmG$HBC(|'):w9arI*=PY)o e f9H_>"7P-Z!Js`B3R @=@UA0lO"�TD1\ͦ }4emnu@S"rݶsw.vm?N|hpm g YUMsr^"vUȁغ\jl' @ @N !n_^/w�@42XdцKD@a 1X9.@(B#ICӤE!tjg0~ ؂ ʅ'1;1TERfPHKl=S4>4 M@WJQ L r׃Q/◡ёq .SP�.*pD *䃊QAhX˗^1 c U?\OۂlpR3OEb]y.A2,ցn39�Ӛ2貰|V YC;E0 (\Uuդ&o՚0Yܯf3riQmX1OuMA#k܍ 8 bl�xb 8  D`# p�jh%()J*.Q-@= > ?#SB3( 03NBhi}| xwUܡ*pAZH3BC岝(4N&}Dz,Q&@�y5l=!4[.@8)�#ɏ�GMvΘ4Gw_~6BCUT`K2m>jD5P1y5}+9!(AOyBZeG{6R+hN^rQT"A|r5Zfna }'qTPQSP: ""FURn Gvp=CM3c;d3͝N ?W{τϼ?>C95Jvg 3d?Sx~F~g>?|FlGdگ?}hya_iߧgS~ 4g Ea\'?}h_c'۟ڟ)}tnxk?ܿgJZ.֎#/0(PwP N>#Cm9-]oxms L AP (v $V`g0f' @0pF4 DmTѝW켭m׻2{DfoO[3 F6w&su&.)Az ĽcxQi`9fo JSB1x|�A%Yj8r(A6BkRہ'^طXeq~͌,ōSPQ6@b*bv+nŽOGI::sǤQ:`0Xbm.T@Hg;]&>OG3TiZNZVQVӵ E1)䰉 XRݴk W=œwY!Y MA8+.JV+t3nb%&wud+_A+ 5AsH9?un~dbvpc"ʅe�J3 @ (kOm �Nұ`(yzK6!km'B&Dts F>HyQv6/K(R:.hLHh.;OP<ydx聝S#(WVFHXxh@: 4bD+ ,+m.dJQ@`x'Zg7bu;5q0^qZ. {u-4P�na\zJ%ٕ!uNeǮW6hK.@5(JUqIȋ<x}2f/|̱ Nʷ Ҭx>Ag6'? y_ [P ӊcnX+ BGd@QUw@\yVj_?-eX&srWf}7{۱<E�6mt"�6Y CXemk~ A qD1f Maގ]䢊 i;;*C.WXA $1 bϻUW<V^K;t #]1#7++ +JqLr Gn*Jr 溊^s W<5HXGs&<z3s"H!G=vc:A~Mc-WkuW+׎tG*[0Iq4<vXћxGM 8M\>pQ_=Č4 /Mxh!7B)\$kQ=iFvFGڈ4"s 4Or̭ё4ft5W4 m=qg@;p"qlBooÖ.ܺ\%ޏ�rN<`ɲе.p.sn0O{a?<9hl276&KρX,Vz_Vg:낎ץuw8�F.?7NxVX>sc݌'PV˒c*Hp=idU^5N@`lG#jXG$i;ae ?kDaL-Cpj br}euC.7;q.eDPȈ׵"OekGP*KveG! O胘r<a9vG&H,A �T#;3 Z< 5 y+jE&܇7QC,&5-~ "-ڵ%bU�FԸ ;X:jBfj)wJ#:Bΐ·!y,.@6FFZg}$bjW&j}RrP0oq&w]? HFk7{"~͡,"].A@(3p3/-v`>e957,*COUY5iѨ_]wZN7re銰[ZcK H 0�tA L&U$!f T�ՖG^5'לc$[Ix&7 &eh_֕e_sW-Dbd]9I 9hxT +KaCItAp~glRHCMu1Ue<ky M%sa_ntV�X  6gcj �J%ЛPwm۵u)Anܵ7hmI$IߍߵLwnS./[E\8cr#ib^ <~gC""}XjIZZ1 뒶Ia�/B>ry m$#ki4WCU)O }޳ٚqpB4C J 5.g: 馢2,!Y[/钬蒎l]- ښ0(!EOyORߚ[CV|B3*;ĪzH Pd xM�E*b#n{F^Z7Ѱi:PX]Qx�<(Ҥ*Ǵ6dC5 ~vr,ۚe9/ٞԯ!wѺKq4ԍ'ne;p8D5ef Ɣ/"{n 8&%SuVFeՊ%`,Zr3JZ*PL[ ˦}{-4>nH@ *@i\3NLNCՎ_)OKW;/7&(,T ^8PUIȷ|`5x7HB%wjRIEaDi4"5MO"J־Cfb>S&!de \StBh y-^`,neYٍܬf~Nɸ]l7V/[­6!rğ?ھsjCG_<N|FbtI;( ?1Ub10,B9=`6ۦISf^\0ﭞ gji]x|<3.Sd+ӗ9\S88/?qv^q  ~9o]oLB+=.[[R`u+Pޱy_~)z `㉷@= Ab[(+o_7 Fx"?]FHkJ%$H➤0;@&PB-NJ%K$`ż-`,fm&M . i&jVu.[XȞ5pdk7 [xYX.O/>#"4ΏLԉ.ke?R MD w PFx's"kFgO@\^|KHcjs^ũɗ1%F�LC9ЁAG]<Dw|!IE0 kJ`L->,o%7OXŜ896,n[C6|wdj\qv[;M@ 5ųAAytOVN*T[j[%8,kmݭ[ZrS {ιDTSr@i1@~/B/fDv?N12�s %y{W SKY#ҨB$U}67b{5JgIxkά<`04B\ďeB܇A`D \;ri2MFϿ"=4skL%HyiGQy_xf5}@ѤtAEy@kjh͞ _y#ك pAcEFa # 7 ӇeEHyੁK{i.<,{|۸ܹ<i8cXF4L<!ρ8jDkávq\/[6=|55O U<W&ea1V/+802|UzCPo!t~v7PL`)589L凋zH $\ XBIKcm$㟹`i n$Dgr0-l PD?/>4lnMKۘ#3 FvT m$ZK\6 zXEq5q3(ׇjxޔj2JB\Jh}bi <]o( 3gXa"Ɏ9X7tM_B@[I�AGX;lz- ^( Al*Q` ߩuJ̐Bk'r>4ZLO ,6ͭČfTBFLj13_6kf}\[9TM%oXi;I/AZL~d&;�l0D6w,}$s|d<˛2]׋1xGdx2:ɔ^k)rcNK8uӥ$|J'zZ"H{yțءLh{MK: ]]/lB ( EE&0k;CP0pkU4h:'7wmѵd[xy(ek&y|;4jʉfg) y%rEPgԁz.a  ƀׄ~m{7YD 3<N`NKx ?1�4Qe|)wy�sd> P 'j� (p-o{t&VsSo�h} �d>�1�d|ܨٗH$9⮗ bF$:&uD x]1d/cJh#TItz@:^dp#t:OpdT^x*fqV<]{FU \aqi[ i;aYTje+3rވ~w ,k ?߯:wWQM쟈In;@C@|R}1ttewnI�?|,fͨMaUA.3JZ iA ׼NF"f 5>㍃$e^報s^ Z:t=`#,fȈ@13AtU Yv7zxV!ݖaE0_Dqw%AN"AJ!͠08$rX4B%/{y*Dɛ-CA;FXSvu"q: O! �9?Ab=hfB5XԸ<~j.A\;xXE4-CVsNDDvH ?gHύ?\I޵(PCUO|s hP% �<Fk~͆WAZb�azЁ&C@Q.<lh:<j0|^huH,X 0`]d'A,xm͹f*0%MqQ%ZOQ+2Mb5 Lx(ToP f]ɐW)Ն@B�E6BIC&!N�~Nϐ)sSL{Kc1NS@ ]MAPE:>$(@&M.T.] ;m)IpYka8|+T SS]32W}2ǀ,ul;P?%{XJr=Pq.qL܈JSuQ묊j_hFtz ppBo9ʡڔbJ�P?(?m2ڽZGim-9E 'Bײz).3[ )y�Zd{Td (d-I9RhpjcZS)BFG+n>k_$SJgt9#[mS4,D=w SHf7%0;WAA�]dyQ&fH4DVҁ S>I�A"@i / h՟@YCBA �JWTP2& 5I,�Ы2y:!Hs~!סJw^�x}/6=J=yl_7\':|i 5f Kd)WWXJs6`-^ukn5Mޥdz#i2}[: kP'hCKD5xiă,(mJ->vsu^�ȶ%i菠>W4)xbJ &YG]h˙0xRHlI.(VY=T [5nzK %<H?�@�ٱۜYm)Y46O ڽHKچ5jXx $154 \)7i[P#8Kafx�A讵)`6:s,s}![7pMYgѦ莡B>�;2)PCj@?˄b�y:t:Ͳ%-p6y饹De7+=6x_H]$s&f�%0 .y_FYZY*@#/2_AP)J� p~ @�Mxض@(@|@|2o1@l@  jq`=Dvm@b{>-],$@MߍDP{]PH Aҹ.C5L 4U"~6iN x'}- xL`yJ<?ӋK0\ftV5v06M<5/k/{K`58w7#/<Lg?pGrصUT ]Za>!T;6 ^d<d)Cb;b{m?Q=Vդ'>,`Gv<R}(iF[{O/0N{-0aԪоűLp9rosZo$/5 %j5A$4xc=(8j$HZ �,44SI,p/4 0^@P%pEl&� YxCF߭"5wL*Zi2_^jVM1)6M1Ǡ+mޗD!oynwx0glW|tOGpﲧH+&+Ƕ"d,Qw}y8mCE_EQTݽ쐻Y7hYWG ӲL9nh~1A"tbof*˶pMldJ lCu,rp|G"1tAН%Vvj/LLR*A ksZLCf1<Kwd"%" m3ڷ$݈o5nz!{!W<�b7#Bq4i�Ҁe9r?xnwGJ((~ 8!n�~AMrhw x|.crNC7]OЍm|R]si}P* HQ5'z8ឌGA|ǻK,=/|֒,O/xRՂx$KkG[^t`鍋L:'Gݱ5Q44<<n/]$G vwQ Nj%Gr5 nJ: )<)BM-'jR5-ׁ-ѴBB:ХE]ĹnhtGsځ|/;(XH _@OjžJ%pFUmJ&'uhtD!�{B__w"[&wH> U^FP�BP'0w=C5<%]l$N&tM?+>${4hw^Ctu-կT4w Uc^Nz@\:~5X-QD DϭN ?10sxvt_;aV8֐X Xb`\Ď= HB"G@`[DU.osMl w59a5^U(Adk|WroH a/.#~oAP)b0V@qh`B9:' xh<ϫ4oD)A+()ӂ6mL'@M S< >ŻḠ $`%8qllfW`%N$bR|pf�i3b4,κvūKdSY|Iܘ ٿc!,|Na?w 뗰 =*4Fb@"70Wf`MhjxVR"kF Bp~c}n *D]6a&#UtYStoQ%VIsAKֱj3.e:קn:3cTAZ|/CX3,d#}z^Z´ +y-괯GyoF<ʷ<h�}I<O!azn6Hl]5Έ$pH>ՠّusGbAd J[24$ۏty[zxK_{ B|?ORfpO;]_T.f^3/F@((\rZ)b嵲F-f^":fdoBS_>M~Ds9{Sj7sNS'X8bWRkלZ)@ yз>5#Y[ٽr /5`hHĠ^=cr$:et,'e" Iˠ:u,Z\rla2<%ÑqdGc%I熃dǫj:`D #4iϔ50 4Swtb!{ ),A=yH)Pgb#cPYM  @FK[ h<QbCkƙB'W^4Ǖ׎gֶo~Q*q6O>_޸~6d~ Ҹ}'} 7ŏw)\`k!Q~{ӄ$z_Klvr#[˛ӶpLI о-ɴ|}2#(rCo JUxZuxjFUMzn[B_庯޿1{B] 1*QWҩ^¶ZM%1\qUC5| ֟a]%}TTW@ˀ U!@#(Ee==Zlb5HL p{}/O ^TUy+<LW|B jBC}4,bZT1ΩTtѰ+k%LNCfP|eԬQ?Mk۰=bz7;6̟OW<j5ơCdk)<;kfut=mJO2&kK q+ɶn ~@MzH�ŔL 0k<[P{66p֜\ Ae؃3J _ @uHA~<=UpKZkSyy_^ M5P�M{ u/%@ D j@ ,䵀 }y%.C= @)ܢmJ &[EyH*DOm!X"M4RAFpP!~QCJfdLdJ1̼\OOgn߃IO*f<sng޽^0r#ʼ*/UztW6W^ąOIUCݝjhEh0 of+4MiM6 S!yjbmXh0sQ (Q 9�v`d @ƻ X,vA�~ ?D#ggzY `Vsq?F$rZ~L:a F`@K^ yۑ#rcN_us@'WZt3H4ױA3FLA.0s'm.zb(tA` OC4s 4)2 FpOH`.AGi@ƐqӜ;kRko6 /-RMm5R&uL[fuao\F6zf$tͶ0yQ?`R~dK]J(�%C5ą�(A * zd^ <[ 8b-uS'@]pp�:vԯ c؁W( jS$GV‹^Vi@ &jIԦwK#5#=R uF[?-AAvqzo:UPĐ78!:0"E4թQFƍ) ]'t]~,0i^hmuվRz bL *�Oz@!fF�cH!6ά&WkJPmp}d~q؀dkü� Ld�HrU6dm f8u'�T6| yJ2DrO"%X)()DPph')B(+(,B5QdY ߊC |iĔAF(PqyX2u=,tߧ`H "c(h 3Ó=A=sٹOkT D#ڠ\<pÔi1;T cJPJ8@ Ư%S!(F jk3\LZ2^S%c@AP'F}:x o@TH‰͆3h!y@94{Qkit̻?�_^ea ފY5,k[#sO"Pcn@K Wb ̪0jĔ#clQFïĔ@gpkPv0<X&&c  Pv� =e cobîv@ ԧ4R-:1U)!VJ/Lg8H %W5%jA�;sP+`+N@[�mQA 4g7qrT0G"%`ܫL0?A`A 1LP&@ *@BR%- D.g4x5[� P@j~C܀ sNEl v@? f@b|E@ 6w~#2cl8+<\{%#ƕ(%6  Ak̟[B)[�1gacKs\ -yJ|\}A@K@: N|`h>1BPNA;(5c�FqV}[[9|zW �!|^ O}yԧ@ۯ]4y%j@}6rz&ԑ~F_\_lyZ?%ܩ̴io<^km0MSub,@08s %M@<sLbL67G P .LN;je؁wV4Q o 뵯Zl"h~U q#~?a@ [x7e��L&P(σ@#v :&>Y02faz uIOQ;p#\/0S~7*<`"/1Кy_{tf_ΰ_07Y|` ň|!lР2eAMy }# yde �_$ O2 K}Xn@j(}? L&SW 73b0fybԔjrYZgЄ9Ѱ bG'YO4'\'Dc¶T5 V=~3=5/ˋٖs{,{gǹ'榿tpnwsv ΜNwL: `!*:s>_|gZg@4EYGcGe܌#s(Z7j6GOփw, 6ka2WX =^~x+0{#bgn/)+I/wvD:vUnsumoGƘ>u.jXҺȟ]]䶡`]EvqKmlv}=(ӀжH؇@\C{}\׾U}$*bMҳ/Gryr壥<)<w tygoDiDJlLjH@5. @^O!Hካ mgoa͕G<1lj]ٺ(RtLG&y -AJD~#ޫ%~nߖݷuoˡMaI|~tmڷ| O<V}[zw8,pT~wߖ[Jb8"oᨸy߽f3ii;2�?~;Gʚ+e/)^-|�%575 gOSllxo捛govnrzv<c-Wܼy gJkK'q,#!߻v1ߤ@uUt�Q+5ԃ}y>\bE-[{fgAV{KA&8R9&u{k-cf}jˑw|F%<6J0ʖYRS/!uٹr{mPXXhM{gOAga9R[Hͩ֝ ø j?@ :b:> *4 H,(NlCBUs^w%8j .弜ZMo߷8[%}|ȽQA .VэùS*;ŧl0~SٱS >k竻)'(=�v?:K~b7Vwǀ:-�1rڋK*3p-?QaKϖ|VQv wbJh?sh bvCw0]qu v>}phgz\ nnVGpwwO[fg\dDfy6,<!r,5s-s:nt.ާu̵9_N8ޟ\>ƣ-]+cKX;\.bí��hͅ �šxO.> ulw9.V ,C{xG[v\V6c>�va 7V`/JW}.mwc`.6 2s(3^؇5`;Tu U4@^JG!-1vh`atý ` |̺}wA bifdǃQp1P@y< \ڛ/hwox8R,6dK(Z"|2GK=e`>րmP�ZUTE!tFbHbn??@pv'bk<j t�MAlbخ7 GXa\WZbA:n_Zv_J%4@w5vc \㻆gM~UZzY4b}5VO #. ;�Snp$^jMt؝Tn.ܷfoqml7gO8ٖЦN4M]ZU\ yWqIr8jOd;z;yRU=*UVt%T4]o.2]LAtKgnU5HQJ':e]BWeur]7&F6J7XAc:I_]?ofӬN7 <j>~gWm|9xW'YyjM6%H7ѵI|ɛiXZ4MԤKto~?a<;yML$W4eQiҮ�T+qupDuqAwzX"ŜTJ�eHL [[] 6ktZv[D9n Ժ/v]D0xqBhYN½A,RF!`&a?!!t86IdrrlIçO�q5ST!ĶDMpoċ@&PR62H>H6y5Q {\4Uhf;$@<rSBU-9Ǜ?ɮs9Υso~\6w q ;W" '\~N0@V5I y)˽~sq3M Mh1eKy+h?z_@Sȓ.Btыp7 }^|c#A@#{q ɘr<x18zXXjL!xFp=\k<�DzSN'2z8ӥ(,"G!Rz>ճN{d-|xHE&@d/D �J4Ocm'.3 @@(�5Oó @4}gX&&y=%HB 4"uJJ %u_WDH #2OPP`.ĮTX?`[\hI-0ee\>PYoY\}R]V&qA[v'/ʂ̮B`$X RfoMMWJ\_Knڮ\]>E�bAӺH,zȃ%qgIV>0kK{@el6Y1*%eוY1<JgR~Q a#=0+'pI>\’%D=2fv~ 8(~md6Y,C I[ �%0'jkbMĜ\D,Ml^oc^Z@ PZB_f8WlF*UZy{FIdjVv2<brS;cLVP]- )!PQ[jr=?"Q҃_nhR{Wt& !@=C,guECZC<<l :1eWzPKZ+<Ѓ)=s=O}G^ )ъ5N1XtT9qUPڽDUӞ$av` UmDRcXlCBC0*vtЌF-@D I+g3+zy}%}Y?Ae 2\W Ӷ8?)Ao; BI].3ҌفaR%/)Iy$9mx{MaBJ:BJ0 D1›cP�z >P[]a-A9<`64(` @?S۔ MݩB*4=-,( Q:؍pL(~i ˏ2vK!PF^<PnF8DT2M_ wF =m7 _3)ia =bb;?y_*-&Ax݄6cx ڛc[C9gWr`{K0b[!e ?wK} eۃ4r`I#[>9MbɇkL-fd&L|QL:�A-dPH =E;$t�r BHzrm]dCI~LٗhbIg@�<JЊb@  2x A8n-JȤ-x*9`8Ab\x\{87F*79BeX>@ pGb?<c0~ш6ox}lcb$R+c"xgn K?B;ީ~S p+v3i+Zl~\~9qu $s6Ճ tADŔXh߀ 'DAYQ !T+NfУ_4 ԣ,<JT$ܣaFM}+xa4+ptڼ v{v g�TهSv-fƪW�v8 v0ړu~A "v"ՓU TmTM& k=*AT6ToH'ŊXzcD%&N(\ JHh8CcUS;zDx2u))Wɟ)Fh?ըke)��NC(kRVlPT4cZaR|c�kpG_x>T]B@ }J JX6고 �TA#@BzBAF~ Қ v@#1` 0ޘ6lO)fD4,Z(AAFKHAMXKjO@c bSJ�b]ibMɔ@{@SE`5E/"= i`ܖ�P�aJO;BN;@xt G.x0׷l�O_6GCXM`3H W}N׼-яn(v-\/1|(,'vyJQOڦ #A gbJCKC*b/Ę$w)AUJ3 l&1j%@mMC_J /Q/Ј4-fVQ"TzpT]7@?-PM�AM-($ޑz> 9�l�Gh^: zYA2�ؤ3G )~G@�w�Ak-BZH,&bՐ/$wTi$"r~=D8 m,DJ{v2z\~ۂrZ�q١tl'LjCG}m*ok{ ϭcG.f Έi >-T w \-1Œ Cs*kInuW\j7U!~h}r3ʰm=k<K dt}GG ~X|�]!1ent̜I8,�'eVf/@A0!, "hz_ Q_ /b/MPR?Х1;XwPI.ResF"4'UkR2TLժ@ILW*JաUM_UZ `+d_UIT?T<TCbԄɪ:T=\$okEՁKF |ƫNu”L1C#?`{ K[7ۉ!ߣЇM+ 24-�}Geo<)w@b!=9J@W+eɾa'{{ƐeAOzr<8H6x㒘3z,{sw~nGQQ�j1˨5yInE7-FHݟ^3E%�) � <S'j,4 1RԴ`@H\3Ps !{.} p͝?E6ͨXg )H >²I?Xi&;;V2 t*3c E w-I%AFǴ,3r$@$MH QBKb¤yR}t ɇ#cX(%'hc'I^%$s7^XE[ |saiYު@ b*BM?w{ 4Δb[Ewm_=*v!iۃd�o}eXΊY9bLA&1CE[|#;y(Av�Ő%d6-n<,R% FMߩQo$o(~a$d2<d]bG|\ӷZ &I~>& �_b>ǃx`@mӞr/hT20,A ih>U]A';y)v@O5yOH??@2%+3(M*Ay%;)B\? 44fHVE� %K_χt~6o&3y%_ /ZTĂNb4t-BsM={/]A7S@~ڂ>}z[jؤ>&{éB[4YH^}bj-ʻTz{KK N1"ĢsY/;j {y<[PEb?[>S 3L\`?Ll>nOp"8<O \D4StAWv:w*uO/;iN(�~,@p/2�MZm:>=Y6E( )rۘ rsJ@}8is0eP6m6y@ͻ~@!m27d*$mfs9s::cTLeM'9M9eUgՄP2lm~)g<ɏfEs7)<:þ;ǰ<{*]C- oLajbgֿ&)cץc'&z^? dߠX4ؽ;Lk)wPZ9v)ӥ7_#Y!5@ib};3;tȪ2)gA&<xFߧN��F%r!džJ]iP ez ` dW=|ӞKR瞹0<|Iƍ!imiohT5`l{N2cGJ?Z756WƷUxrshcs*~߫aH*~>xΫWsW/Uf걨aTeu[���IDATwkz{oVT*}Ƕ, v#>iccEq&ޯ56{.Oݜm@LQw5{!SuulKw ҺqJTQ<YwbYN>LRh[Hw� KL";^V'*!wDim1!awר*¨tNpF \s1F½޸|]xt߻/#펔Xnw\g9`WP<tx8ƪatc9 o8pC/ vg۴tRk5]oG. v@@ Ũ_>M8,&TY4ػKi~,kb7![m/[XQ. N%R5DbbZ΃g-dP=}uV݅bc+<YbX@'Q &;r;ӦKmu¥r&J<>ÍҺ li�T2Z].!>Ksc΀*Hv,[:r.Q;JЁXzk݅آ,~aKZgε݆Ջ gTqpEK]_qBg^ ų H] Hr(t .FWJ@uYGj`nuG{u8Uu6|nb醗֙(rk:EGVիjbUUc^/TvV?Cݼ+nԃ{h j[] ܚ`[dml%IȐ2+^3h �D yG!H v 'V_)Oc+P@Ҿ'σ>cPkUހ0f0xo0o[wq`Un\F-f@Ff8rc Op<ms:Qz:!e3aA5d>3+\33A WČ{w6Tl$vH|;=ddx6M"}"8 ի[lX 14f#K!F$-{ؘ u 1jf)�3B%5@A !%WQKĵ4ԇClj2!Pّv?IZm%_L\S|}CpE--FX -@ !Hf,<pqbXGr`OТ =PQY;YD,a.O;]NV7) KVs(r+KP2-P SMA2dzC$(b?%tFY0fFfNYoDn)Wb#-HHDMOCUWY$B~ `Jk)Гmu"9$zDi=M 4%_#bO.BgHn(�%!4OՑ0"1)ARo$_S˷i"H K7zdJ.p?|ֹDĈJXX)$b{nS3(bba=,S~ }X7ܞ0dG3%6ƶ6ľ TlۤJX_ǥ;$A Q,}HGZ\ݞ~b;;L5JgvkmY>v Nó6>wF:&z [&/֘ Cy/n/d yY|YC83p`we<JOFնBbl ϯM#luXJX *@ -z]J(%?5_̊bJWUJ4|Atd^<\{ZӵvaV` dNzP V<BsmNx@ޭ^}!` ^R [N@"&o/�-mHuE;c3b]KC ҷmk%3t&jҗGEO6d0k(pV>u?jvMqPs2;˦]+tӭKEZ8gvkt-R%!ﭞY F㷽̜ff [;.>O3g*p~ANk;3 Lw!(=۫uuS,}jᲞߗ9q((]OF( �hA%71շAV`IL{G1%@I/8IˡӽA.=HvPVdMo�Ё{As�:Y !@p88b6+MʈwjW7xԡ!ضP �8݆Ta3vcЏ|ȋ}/ T@Lȷ Aaع}. 4Ei_E ZR(vhv M!)R(%dkV@۴D;"_lm:BCi{ej(QLluC;+\pGܿ'|ŕ.hpKx @0p t8y,<jM dS?ںv`cv dѵ"(kS+2I%H%'[,dFC#GaA (Adns Χ5GfJ]C=󩏑[!|mF B;4eg-20xN2/M_nV@Ĕ`�A)Z5GȾy}u4U*rۑ b]��ᣜ%n<^^Rvfd~2؍l |W ؕr6ul1+J!T Sف2H{ U3:wTyb<֥ی!/F^گKba{&q (AΆܜ45Q|C鼎.gsuLoukNFVZf['!609eZbS2(DͦLuCb7�mR$$b@Fg쮡G3D-4%۹\y?7ƏB[/Po}޷.>{vb©c\~\Ԃ�?'5z5a v@Dxjs@[`f)7go a�cbCEaOa[=D@D8"j,˶CwDB(Aa8ڞEmiiⶤ_윕&[k LՖf́:PA\۔͇6n.ߎ@}[5x['ͫlI z(xjkɧT*/Pwϫ[ԔjPKٴjXlrѼ#tU) $c{ ::R5OB.Hؓ䞆 k 86V*lthq]!YÅ,� <knA ḍ BjA>csh�g&>+,3.t 6YkmaH+Bbo"Z/#2U RЕ;@L8` 2u@d*aw %f?tJ%F_U|=۽{XhR/yޚW GS*= yWFӷ){+BuFR\`#q.#]/\t/zQ-,kG AC/\Z0܋Q5`We/r"ju"|{Q_<N�;BױA^]KZ-ŷ>>�dh-^mC:U~ZMz:0PJ a v^:^|6M)N%,V*X8M9kKpF%+<81l! ؐX8s 9HI|G/6cfƛ:XRhMdlno�|Z1r&pGzwSz߽)c;U{7Xm<.cuEBS�ݕZB: DJP/_t!G)(B�na#T h,/G>b{4E  ċBWphoEɋBD7o_X.N`�nj`Csꐚ.x W%ǀkNEb!VCl7X-0Ab8،@Yk.|d_0YC^^bzd.+yhb)GȂ8sl >pu'!"@B҄c%XC!k,"7t!�K6`jU֚5�1=7yly %u*l>+NB:ܹYY T#T;[y>E@X?/^] ^Aj)U:vOofKYqvtxzi~6&ϝf#bNYOSHxڝ=M~d@59N{li/0N MO1пX 8>p=|@* Bs/\/<߉H Fv:??{ ɕWo26prsWC~VJ`tb?ΧZ>|_˳Rs£מo 4҉tẗpcy(؎QranH.tU!+/ڍBCZU:9Nf /{Ѩ[�D7tnȞTTᮀ&;1]l_: 5XPq |<",z -8ev�gpkJ>ɭ.ίWH#huZGY}~=q(*~_8åBγ>r'?4<^:-|*? C =$h"PS#vx/+Ý�hs: ۯi_qGexBYHkI5b>Sz)ϐyt_^D| _FlFFkd~Ix Au߭)BF(B&-+jh#<>nvp naD BaA$:<g§6u0pթkAaAsiV BFcH@nNjî# HAt4ӃZ_a6ATej.*luy!-y588f_0w=>aF4hd.q\_X~/#8?xCv H`GV '} H�y@$Xs Ax_4y5ۡnmZ5'{9ϐCK^w!q{ٵtI7ϳ!I" Y,)#e訆Ӛ$ܴ$iŭ:ٖV2{?=X$@43)f$<q.$8Sۖ ,$R9YLP$ `qfJl\iկ�WYj SF$/;:dݟ/4 X\.),�a%6$׃>.hȍ+{A2Te?B>s�iȗCBbzVsKX%F[ AIw& l!D\0�E?z x1 %,`PF7 sa;h)�$DRdxoo~{Ṿ`W=1[ο%SVj|6^^ki%.4I$Gpa^{l6T5G{Ty:կ-m6 ;;ǚGXBP=QSbf�ݳn !ǚ|m[NGw,O y1]֞GJjл_9=&_9Jz(@S;w.-./|s|gh 5yW'T8M{-Q&mzM\슋N A-uis*:hSqӎ ;Tͽ+w:CnmY;-[ O=+֯փS=S9^.N=uS#E63XW-:h;'/T'`pC9ihW/p&^ QnN ;h6̉Ǟ\_u .Dxҟ.ZKѫQ KDѰ]C2 rgj4;|x3[M;!^C)|ey௼Zp;WKǓ!\ʼ "K&n_\&FŸ%ܹ[˄I(s5!n;j-)ZkwuN'f;'i؂Kێ(i~doX~ɐ[(--6LJ*AReej@ϝ$ D3U y`_\xnNlHzU|&ѧPJl;''ݕ!$̝]0;03s˜%Ǯ!%aQ&Z;c!tcKXѯߓ.ԝi$Ƈ)j"G1!fS5$M ^PJDd!mai5b=E%%#L:DrZGev#I3`.$}ҟ9Hz&3W;8I6Of@HjN8MBʹLAg3L҉̤{ Y N.h&KOI|"ybaž6i_�IHwFB쓧_N>rl $i&gRfu0z*_x^鮿9'sJ07d0?Bod?;ۿm_a_A1]eB:<jY52:[DJ(AձY)IZld^fjun Jm= l }]!\)] ((gHR<g,Av/h&u!3!B3lQ2<;4+&㑺t M6fYdhg ЃUI.KAQRR nβ|`̲!τ`֟-x�V ]&mpu1?Ӛ%,G4Y Y"= f7cΨ ,aO=,9=>Þ"7K੼�ͪ3<%Át;s{=6sO2o3ǎt͍W9 c=IG~,4=Y[{ZQjHIj(+^ٕKHnP%/SKj˒^M%K(Z*~XN fÀcG-X/+yalep߀X.o,1VJpkc,5n@'*BjūL5VвNJi]}2RXiWΆy;q*<~ʮ-pyczû@kw,sǵD/73&]UuyiBcAk+4pkBcxi"5[nk󸱨uD;<51c.xI'/c70?BWY$O![wX;٦~J *�WBT̊[i~Wl KϠuD.hY #MyPT{:fAg87ظ| upb02LtP{YlzUcAM Q5272&*4'MbP)A3\%7'?++yQln#~jiӐx ['y*a(߮xT:_0`g쭄U*e 6gW2AwY&ʻ,, -,n-˻ ZeU/˟wחY?Ƞzwov !B %B+)PϞ:^Q5^' `9@鈛uFS/9O!"bNl7 E[<gHN@A6R%$U1ʆ !1Ȋ8Z. -{FAH-JV̋lC[R2p[[m%C4 2O 7o{-)oCY8AQMuS2poEYQ!(!"*"a)%,ݭ\R xH 𬐭]UQ87gNa\#SF[B6V6nl/ [ċ疙jRvzHhcZ{\X0S1cSPnX#$X{<ϭOMTxq'EU]L $csL_p\hT-HOU0^PJˆ8*iQaE4EN8qou[Y>‹ SM%zU5#H- M8Y%wǹOA[]k#@H^}"%pv8-gb�'҉ 5)D&;  {"H >+Nt 8ǁkTSPp(ܜ*(Y5 99HrSVu8U|SN W;m9}/{Ր7 B;}drYMo/4zY桠4oA\/^|\#0NJ}gjy? dhsF"͎ؔYʣG}61ͰU)_8Y\ԁ+> iC$h %j+Pk!%/~10*F'w;X1]tpT\ArE!OtyMqE\|`hf1sG*fx9'SH!Z V5ї ( +>Y, G. 46[BOuԤEShôc-^cO9Ӆ"X"\3zʡxkm 42E&3Eʄ>ծ𻜼ֱUG=Ճ [<دD?wBDdmȈsQ-Q>etm\=Դ9`H2|F2/1jqz[Յᯯĵ $BFF  JɄ`'Sd ԁB0B-ɲ)==?L5zS]!lg I�!(ߞ a60! Zd|38Rm&Ug^Ql0!YțX-�O?5v֦Eê&#h-Z(Bw^ aM!bsk3EACItؙԍ"$dgQM'{+@E-[M[rEd?`_=W,T#vVeK;&=wpN(�ۗj7ELf^VIdHţb=AJO!)3Jz4Z~}r}/ @)P;@:p:Yu]Mu:ЖA`]Q\{b$sZaJZ) 9JI> 5!Pc95Hc@ bCJj+FLu2"Su jQSTլr-PP shf'(li*LePB�4OD!V   +G:u> Ppg > #x0* PTTkW!gcA? \j"xxbB|,W;axFLp$ иDY/cOri/s=H̨e\kՓ`G <Å}Qow"tha_-%F3&.6G#ȔCL܎ȧ`λHIicW $e�tFV�d$ڰϽ/Z<SKPQ*~Ӏ<T44FTv B&~V/vZVo1B9UȽ L3rx3]GXv BEPx:(PGmb JB�P'gAlg�<2{m9HA!vDXӀ~ǐ;!(<͒ޯ ԩmDJ|/9[C*8t2Eh1ë->dr9�w+ժѪ,UH8Tw9欳>S^&Ð 1cZ(."oog#qSqo'5RCS|DI;++I >/:CP%PDxCV_q&@{=WDr: �}h"LPi "_ un ߵm6hD#:[bJ #Q9:2u`LOi hi6{s)4> uxff&Hc۰ګ[uP PD{=xQuU $wNl6Ahm"Ź!A#ELBv!leexs�ah25!b po+Kؙ@ɷlfGyoHœq#^LY;'dr=þ|+l0B#QHSfH#PlTf_ͮkZtuU:�cց**Ղ)AZ +e֩DA @*Q f@ V la٢ ^aѫt*-Зh@GT~Tzէ nZŊN)GK Rs@æSE 4J xGK3DABgt3(c@ixz*t5!LGG'*BT,T4_Դ"`5x[=ߜ)�e8?sXZsiQv>1yIVMU$ě9vrg22( a{7 k'?3~RL7ɏ"'ag&5KS8pP}ppXZn0hd߈J 𢵊&8| amVVOV.΁PDÝ'ۤ+ix!U8)q: q6me:^ Pޡ=gb a@;ІWLΤ6Ūu~fp�–2Ze� ڿ껁 Ú瘣D,u7"TńZ C0Wյ"FÔ�GYʐڕP;aTTճ17 !\3 qM�%e̐{_XyȔ[:<5<WHA $#`˸영ԤuA mm1jqĈaAK ,Mu_`6DzU /D!sЇ(\WQh>A"$z Ts"@`P!.K-QE3,0[&Omiu Ҋ3ܫ:cIQ@z]"]Xҷ'h{349$ �YR/3a~ykU˼HwLw &֦aX }~z5-ӥ!lvǗ_G^Kc Ft<zH<:>79&dOy^]}~yC{h?{_W#Bo g2W^ 6}&ؾ:ʱb5| ~GF�z�{ssߜg,db{aXT #B<bϘ}vD&'q�ըIj9!%AA p`6o"[j\&j*f9u[N-fcM. l!sA 3k2!P>B& 6+ u}N7߄"W\Id)kXo]f=A<U{ 3 R_znhy{R7op% i>. %B>vcap ª0#Q~{w& ˔W%׾<Ky)q,~J^k v aX@>w y:{޻]5jΞR脗w<B'CsIxnJ͈N,U7�+  eRg{r\fw^_<E><A)9{o|Knǯ←nL;L@]L蔌$^t:f^k0 ixxJ9tEgj'^mϓ,󝓮/{R4`>$,&osI(2C$B;`\^4ESɲ[A\,'&{ngy?4%o&ve޻H凼5dn4mҝd rɓswd mfB NLl2@py6Xc [%&/Mv6A1/`&WHa\ %B0:k~b83fpc04 44 sY2YOh&cxbgٛġfVl8[fD/r3OϨ1Q70/&>΢`"X|`.̬7Lq^JŧOΠ:?w׌ /^[3% Ґknf3_W&f BPj}$)L$lBY:t bG/)2QT%u3! Hބ}gAҏ} @d &ө\ם�ުdJZ]KY"Tқl1.a MTq CNQSہ|*O$yw!5 F"adžZИqks.ڒ zXŵ2^غ}Lslk1oWR>e[^ƌiW=Lފ5%zw|Nj=髻P#ݵşfy'F v1cl-oo-m>7Ʒ'M'6noo־]_gֱ$龰2zZ#c!wϤ � # ̀|Ϙ* Y�ea NMB8q;Tـ1Ք`\@3΢;S?&`Tk5&!F.c\2<+_UyN3* }GׯQKj BS)ZIp/uTUZX50A$8|o> ^kNA?v,LTq!úGވ'yL_a >7UC0鼗p 핎H~F`OxMJrA*qAW(j<~rʨz9O ~McuEyˣ!Ms"oAmNs82=Ǖ5+]AFʓ2+UtO(b*?d_gǴR%|c8SoqZ cy;BG`wǣQgbTLYunSƋ(;8hǾ7ZğLf;csEů!_rum!ΏG 1z\T:qnm3شc[?=zů5kdG8H֣Tzt2HMEWDֱU}irE9D:TT\'JVO;9m:+9QUV !V,*SBv?:�.E͖l޳%e>E<ckȾeK[};PCY?em'm G~TOm!QK[,+dN鷷vmFY(xY!EU7,n+ ,U6 c ʦ6os3Ydo")S BkFo` ES n=s'ېx3{[~/-ѶgL 푖nz$Z#6}RD1;MVbi/yۢ6m6kmxxx1 lXIb_CJ拆Xj_Mۡnk[%~5IbV/Ċ* AH4 SEd$GsmJ!_H�xS :ܪ莫㵠8## v8hz.lzUg:C�=WH9ǝ� s#Nc.5zfs=X[}9*�da8;K3U8V�ss+s4M*L>=MgQ-wnsgu ]+/i9b Y)8F=[c[ 9%ȅc.C{+1Ӭbec{XoՔ]D 5U: A db5W .euҫ)HuCX92<QP =JJqzB %"=MSe,fn2\| NfHͰ�  @NpE9`Q?#N`V.hEQtʺkh;ᎬguG)H `vC C'68AQ҇sվ^&!vC;H@^ෞ\ᔵ}`"Yw N?vVis$M{栃Ad;wl=GN&9-{p}Q8ZkX!g &>nI9!o�p/Z$[gI_#g\\S˜ZgL%<\G)$†N {_m 6}B>Ttź>p5syU4-ZSXW�|.VT+k j .$_",$/hMYmHu޾X#lFa{؂%jHm1Dh?aI:O QqSk gm]+{V2<]QAxbD*twlnSUG7!fn[9 U; E_ؒN}=nKlQb[={vT@ETl u' &BiOdžJB@+yט<ŃNnY AE q3t<* τ�ֵAR&ā9+6~BUH9JF9ufA yoT!: B]sD%<gi HM) H@9 U4.}mzUh;O�@P֑AqVKA�u r85H� uBYS)y 0# kgR.4g�ic8T04B^�xg)tT5GiyV$wh#pOWAUA_Yr8�v\\U�,SCOp'f!m���454GRtP/-PȜ?ڠ lx�քT@yu[6e@ �:U&6+pUz9LMS ~WG�KGPV7!PAUDj51f*4l{@0 gT&zN(9+ Hir(Q)lsmp\Qt CSipƼ7j":1κN i=[י@6!Yg&#;� Pa*Q'W ؃dʥAO'oz!�&^P PxMGisjOk:8U54;ܤ E;c)[N rrgAΟqx`$[ %isz0@$ z^=5v0d]ACX1>H.c=C_ҁJg`N4x/)vXԁzn@@%H j D $@SP]6HP!^!^ 8q @/> k_]̀:@lY �vϖA9�aAV" b�136g4[so $s6:@uKTzu,@CAe؋aߎS�~6&޶>LMAVXّj$ÆqU6PMmU!ocضj#[oت{ $Bpa% sL4z5FzB�-BACutvdwC[D / CLXZPTtPHp1tP<wchң (!CNi*`n6 xu@ T "6<!b_BŎjЌ*!~D*Vr:yBNb*6pE3*x�P+':(W^}r]#W(D!t UBr^.Rx xp̯\SI}+oqʣt*"'[ <u@@?IV>)R:C gլ4zAЂ[`sBuHcV0P:x$%0XF줻S{=�4=#�96sQqP9sL iPsJRm6f U5O҈ w@ ʏ_y5k?5zJAڳ+tPG41OڡW43 h~{񾫽%X�0fw\؞g?F`kFLgNL'K3ZL3߮]H|B#ZMS5kePjHzC*v\MX &= '@4 t]G ƁbÌlhgH) $:}I i#iMߏià m Hkfir'M۴ (V/;Q2'%a$ /9Xs'#wNElchf)b'Y ,q lK.]!hdQurd>OC&6;UMfiBoe(٠>M#p" K|< (mn_ç|w [B]sX. #pJ|BKXü}+aYIjx 1mQh�O5(A(bYg^p=km(ftѫO^3Z^:sF�{5G@aN?&QW�֞@G<X+z@G4(!%aH<Wץ܊ p>P06qrsMMؤ@^:զytkoϝgw68l|nVbsMiN맣My3[:O[ŷY2g69ioRΊltt 42oD3_gKo{3-@8]N`\A T2\΢FF/pgso},?+Q[MB˂$BPKi-. }|yɅr"nCGX_{[5U7 TMd. \ڿbn5_+׸'̇� n.G`%^ ĽUBDxmi�}-B<.X9H&�wߖ˵!vPkmc%Xxv^jc,֞|+W_K8G7U]V=7Cȷ>`7mz-;)ZwEpw5>qw Z}5mՏkҵQ̵@5,kr-?oz5\HGaH'|Z/�΀NfZt~ǯ\˯ݫ oǛG;ݍ/q,|)ZnոJB\}Njۊ.b(.o˖~' :+%~yƿtMGnozgys  _uwC.!p Mn_Bz\DsuS)G�fI� 6%3r>EA`AaĎ5FS-T7Wãai̹k/{eC8Te?OZ\M!Ѽ&9lRֶ4YgCh74Kz82sG},z/2Z J\~_Uv\Bw=s36sY fľF$dL%:;a2j 툘$>5dм 1d7<@Yp.$h@7O¦H\ !0t|U. l,:KD24"lq%7ϤC�[8X6a_ gycBI`s&tk2 gKL@�hH&7ClGT4" �trXCL PX [!G.exF]gʺo0o'18“bdHbsM)B>dV%d凰5#@4l![!Е1}s6L�Nb (G'&)]قj׳1 �/^$RT\_,B$ QॅĜ1 vw 5{pg" tz@5I2# qwA>E%f4Rِ1 FH~ ^A7y9Kr`~OJy=!? 4&D\B~lb[+d g6]ՔQTxYFٓZ$sK`^ '|Y>�: Iv!Ã<DYryޔ?&El:kN1CȔee)Y3|.ȧ;4M_Cu " arŖ7&-oU@ ͹cJ_&B$O$ 9t v'n6 >OA8U ]t ѢbÛ)|_C�dC%VU}<[x5?T^|)3HA-EԨû|y?#mR~@Q ~ć#r+$mWob_@AlUr-2_ z&=uqnZMyOC<WԚRvb޷@\|y\d?הޜo͈,AJ]R\z<we ?YC* <>i*me!i"c,o҄WGLrMxNmu o6 AԎlWҹJ$W_f)jJ8sjQk՜"-qI۪U:U"R ck+KE9Q͙͡ ܅j͛UOU}^Z@YDQU=)2j+|HVdTIc<ž_ZjK %z8񔗋n.aOWakur8הLRnW1y4 %UaƓ\{9܉»UدjUjRn#ˀeSV}<k>�u WNF8w c8##ZkE"A5oqsef|: H.x_q4Q#x3!YYB*ܜS7g>r'>\/>fdUw^5uEd_ !E UfovXS<[5[PJZ)n$x\ėQW'{؄)F,!`|UKD (-Ÿ ,H(* UW|Q @4R,Qd ͰnHU!/|s99UZyMV ]~BVS.@{~J6Lm*o( 5y_<y!CRg.;j+ZU5TT*~U8AG-Z^ۦv 3[Icޙ" H:UycQ neHo` i.૚;+ ɪ\ǐ�1/bU@EosUi4~gwiĮz`@H[#B* .DPǣ� B0$<`H 1CfίFoXsJթNW$$ jbI<SYE9캹BD$8wlI%֦al`sZ/x\>g 3rfH3$P %-"Gb9P1WU@0oEP'¯FM܏"@ Љ!Sp< J9Ϲ+iJ3ŒD긯aWoPϏf>暗j[˭bU&j3<3h ZE98Rrg>r> 4~]3{VJ0I5.04?!~9漎 *IJǨ&0KEEy] ɬ_EI*צwbZGEБ6r6A5rڠƙN@p!̢h!6CLUa`FM0$M-r聝 jJex@]Rsڀ7 T jZ"z_Vhr0yj*Q PAa�#@zӖ |axښ"#ƹ6nR+3ؔG 6!ZDk/xnz:_q}1`:OrQx�yB_Fn=Gt1+١?q�m0#_6z@B_fM͑F; cmkRc2o4Rj"#? ^+c$`Fo1ƔG8f ya4Jn5d15%>俛2-8OIЈbfYM)y5Q+y 8VR)/lix7Q7 [xIh6ikydSJiZ{<h 9JeSx xL\PW-yDfHw?fvŇ;ŒA7MBt`rl C;H6 2 |nBy<R7y<xM+q'zQDTAM qB-5pJ )EN%d}-FpW %AihyrB*qBH@*B a;"B^̈́ w8_qtr'{r@fU`Tt@V9S* Qgsd6Ƚ&s�Zr)SFȒdS2\}{-֖*r]*v8iJ҄ce"yMȲ̸Ch 0HTm@VG E!B,�E=Y+9=هmqCہ+WweF <-<lW#8އeZm ͧNz2^bZA(<-ǔ @o t�6NsGW(�o,WJjpNq C7 e/ 02 i@ŇĐ:t .�=i!՟B|d_Bf-G b $.A10VBFh{cP`2$s$0$x2oma! @Ӂɇ<:M|d:y#<5\FH@NChj/4x} jC@�C< ^b@#[ئM7ϵg n /W <6ufW6@5k&+2L� &{4z w l@g.#oR6[p뛀7 qB�55� BM=$ː^Z+P-r&5yp"OaH@Z!Ð 5W\8ǀ:'˷*>}` A(Ci_G'R z H"<7AnSpo �6"Ov6.�| ܹ:dC$+X7~f9rV45 VUS*k#π Ae$2bJcVM(r#{8bHJ L-g,/#@ٓ׬ mE `�ɤ'@W,x!gs\Gb]| #Vt6g!wELQj$Bn؈OuH<5;a8#q-F|;x5N'<ٙt+$C{+!;jL!\$VX;,ǡv|ȧiuN1u&β8֙[z*Ět(:P#[K` g"gc,Eyt\e8LvHrzxw4xKO[/=i]4 x,hQbgcO@>>w8cu9)cpRrdžAUqvL|ɝcm\ta $Ĵ#\̄>aHcR m@5z)E1)J*< &T߂w�p57'h4-- eh FgZ/4a3;,v{Yx[N BDp<t s$~VX@,Le!JֺpZKB8nWku9@Yp> |9BÂq"qa9Œ_I4ZSXYw g<G<?FtaZs @|\0RҰ06pd@4gI+ gX<㔅3(|y *Xl^78!8;;ph�@b$3 Ӛ ae8[)ȹ_hBt '*( HpX8gWPwINs<iH� i4'I'4 ϖGDAZB׮a[x`kZ) :Q[~x:MxwனR`f,,}s0.z Ð#T|7x&P?$0$5ڡV<A1X:8, Pl{p?Hu' vjkSo`(@_BpdpFPhY8K eaA<j˃l� ePrp5 8m('!>[B|!8!<wW*)w4D&<AV` $x #⋇ x !T /w\Ԛ QP E`NRSuvXSU4y^|:gb4# rg}Lzximc `8.ǝy~rh /K;hoxy|YfY<yL!nxyD~'̅r<- 4b񸺼cK2˥% }{yg| !F,~񴸳~( r) m_,yYZ_h$q!.x1>+ŸvHnpZ,HRoP-FOI=q+6P<tr`՝T]$9.V%5J#*7Ox"Z\=}˨/>r|J:RKߌkq;~".?ҽqZw{"_ۋz4*-Tj|OlF^5PY$ ǶT Wx|xЙkR`f'9> ?=Uި'i8_�Ut9<SpAꦤY 9ǎ 7YȲץPy5.KB`aA'~p?F7qρ1\H+<Z7eJ:]I=Sss ]| -l)}r('qOOs gx2gAW@e!$ PmotX 1zKݽÎ$žp9W},' zTG) K|4SlѰG& "$Cd3e|$%l*V ɤa7q "CI'OϜl"_o7 # <M6kL8ɄzlI`}<hl޽_n]wg-(�g. ݳ铥8讨 xѤc%πI�#G$# B\"VT»iloyͰ\.i!HLQ ` @ O ԑE.X}SI- B\%bls1 Xk[& "\Ek^v f&LȳuL.kF3'x+T aKɬתy,h9PdB3:3c6&7a~){Bu\6 . ./4@L�Ӽ.g!Ѽ.,{B"_Bp sT!BKB KB$$2!&c!gE(Fm-Ѻ,܁bLXb-/ K#x7g ZEOs3nPeh"fPYP^OOۀŸL\G3ܭM_F_z4z򱽋yZCD3|oWUlXzo'Uwy*mQ wT\?_{lG DS1)!Q^�YwD}~oT–7̔p=qLŠ͂*\X,;P ^+z|:csq+H99Tv3Yf(]9ؑZelTFj ƐU<o$C` mMU*9O> 2ʽ2(X(gaa \~r]&NisFÓv;hJz8nW#/cla@,HmOCX&?noA9nC%s8ZxoN$/a}* H6aMClbR߇q&W|"7*` Q`e^׏4T!}*'@z k؄!^Džy<68k HP"P G 7|HX\R/ xA\4B滛8#P\#^A8�ـC~ۜ*t59;@wA;BС>Sz?R$p$@8{6ei/%k/m8lh%їͯ-_+[⡵.r/ 4Zg̜=4^暮z7z:O# yjE}SwͪddvU>ǐ|ǀ׷? |C{<Tك=d(3TPuZK v &? mr{Bk{<8iEp⿢рgs|u{+.8d {{Z{i{{C~ijMhHz=3ygO"R!4@[ ߻cD||}<^wfGsˡ~rzsSgljp@d 5`YZTO;uR_"ȟ+i-p`k&))xMMq}kүo2OD6WZfڄg>i_{pld:HF%�XXΰG?yrg~-ψ> (ZгǠ޶~<�DjzՊtۦsNrB-Trq~kqnNq{Gd=suGG*z3NAiUuYXzKIAѩF(S"j'rR 1-lhzQt_Wrv6Fsr?㵬D(;2ňPX1..#&_BGOjf%$-eY@@΄MM@~@s](􈣟xԱuJe[e,@>Y?:Dzd2L,PPAvl{<;"r/e(+gYwxdbYcJMe5246 ) _)mGF8T{ :E7bįT<xO�dFp#kMu/ua`iddX se_22e Fb߇.Ft||3k5Ј0e1\řVE̐ WyXre'[:@<v5V�Ld3n#ڮf%:9 ;edIF̉v6%(ܖ7Mn<;2xBrFa2yaXw ʢ%F! ޒ`~'Si5+S(F"P[-h|2ܒ{@:RUzOufn>3">4ږf3=!6\^i^+xK rDDWl,YUd?B&#Ẍ|(G"!0bZ\ЎSOA"s$GT;>"#YHOTNɧ#hG+#2#|I;/:56,B?JbÑ?0/G(cTDrGS7t3kQͩiF(Z5] pu&nݭU$ߨ;:ɾT'DFLM<z֨|CgJB*ResUб,?WTc̽S ν/i|dd$OSp4@͛'{_XmuDH:  j;i2Ltaib&(E?"kLIGVO7T JLWeW1Tb᧖(6"Qdŏ9w1} = v(o<;zyo=M2ռb|&#,YqQ/L;l6}x&4c[jĜt,W =oʦfVVS߲6`H5Q r^:kZEsT _UȣNMDLyI,VB4G Fhyuߟ4VI|7-kc5>] h0ꤱ1]_H�Me. UqJP0UAG:𾉴t̴gS޹y/-[S�ҤV�3)/e_yĜi+ 8Z&I[HO-CǑף(gyVAO A5�\)dhf>||4@6+n[u!l$Ȯ =y6�bl-VP�DBPS(TTDa 1%eoѧ)TJE ?t*=T-X񔇕*bS1{߲)>r#M:58e2؊X>> NYhW(S#kSkG6x=�w�TGad�)+:4&yf Jx{sdn�H`Q;gc$>R aD\RfGfd8SOg6 ?Gl 25Z$РB�uCc_ qAQ0Q!HP"[* @ӗ#>#o Ej U<1$WB#-J)Y1*%G$ EQ*� lB^C"?y|Fӱ:m=q3vb{Lĭ�Θ V ؏_Üt},$jR{:spߍxкb+IU  {ҊImSភ 1#B(.P}|#:%} }7>ާ. Ǎ<@rY>{bȥ?lpqp@VY sM&Df9kp><A pyTO9x^$`\ i)/^lᘽ0gf\RFj3.\{O/ <34 4�u,yیqA0<0m\?[C<M e$(pqw#q^} ^(OsҲ`};l vG!No <(ix\8{](2hq Y硈g!B@̼PxxhƏNBj(#]:&?hlA!}{9 <{oĞwsx#7h~c䑀1arԛf8PG>O=)/L& M7Mt`u6xǏuQ.|]ߪ XIS7V�N/#|Rߥ٭KƤ>6IioW58V['S}龑Ҽ]>w[1vpdQ @G$ Avv|-}#!`8 mV dJ W7�J}vB%EA,==4SY}gZOROoTHA\zLi;wg9=#=Na畝N3ک<ړک 䑞No3soORh oCZ˧(>:av֣ ɔj6ք\߷ EO]$0g+]əFJ'Fdʇ:w֗9qk~`^D4O�ZnЫޥe=^ CK (MgށMC Z1sѤ;.(@ՐSlbᮅ i-ZM&ş/F񰙇TlA4/{0סWJY|O; )8F|(NGh?= 0Oq?!<83\ 8"Ĺc.#¸(,FW{Pl'HPXhĽA5~ERZ�* "(cOCH(u� 0LaiD d,p~�~ÐEؓ | *RGLUǓ jɱ|0y0^>G^qaFBS8|vզ?ч.]Vߡl f3a1$(Kmszj0d=2CcDTv?�6g7 mqM)P <\ǩe�gN`+?I} <AnS|c5|6X-4$+E <KjR�ӜgWe˷|_`T}&mlpl6_Mw1$p-6z 1||rCh.#9? wmU/�gC_cQ1E B^Y/-VȷׯOw<v<zr@"rG�x5{6.qs6nmUzy#SvQ5~bnFL8J@OH|,hlic[\f&+QL>Yu[�SqQʠ;)/sUvy{%L6cԪst =jqMQk;_IeŰӸgLJ:2ub% ?~W.ܾ/M~~3E f<p~Փ\g|= kp; <d̰ w|h�sը9v58AC#\Bˌr`#g0s P @gZ_4|>~s#]|MFt߳~M^T7pY,D#H [Eн) ߻@6lIrYa I-̋W{syr{+3=<k-ϰ xG>Ow;yN~oՃdwsȀ.{/Rκ^]tWFV/x'ҰC_9$WbK4fk�s: a27^."PE )@Dn4PI?V]fˁKˆ,s*d׉t-BTuҍMp&D$xɆ3~7n \7)MY'Q 4MKz9v6,8:<eR@#nRSJS,m'EP0l9,y<i&u)Y<% # wQ|0vVEBK&=^',y d~63f=0dOl0d8, >"ͬRTNM3^ϙ̟))lk]orojDnnadž o"ٛTB7?A?1Y6Ր-wLꄊLl8b4AJ|t,$% Jfr3,iGDa.~awyJ$T7-Hg)%. B&B@6^UB2eUVgy[%{8vDGc!q=ԉ,+!P@ dF*' )' Ԯp&5h0Ŀ 2ͮxyx|<[A.ͱA? ^Aqk萾 )h-τB| `wHl(zC UX#8⫫(p AALr+$"yɖL$z(?5ڑdUTwS> }qG Qy21l-Txfˤ?<~=#Ng2g?3lm<r&<3TL5�MqO}T)4Y<sÙ۟By =9rz..JR)I24-K*eV;;8|7Ia3j~.s-y+. f�GjFSHYp,K-|p( hƛf^88B!/o*D|du"~mFth"}3I ܬP+x_\3L/fLp(d~;:]u2 Xѣ=J+7z-@0x\mfX)%**pUUhUʃ}uJ **_xۿD!MHpTx]/^w{Y!F3pRε4[.nm?f=-AK` @Rn5%ԡ.T6'Is/M\oNʁ p*DN7ѥC|k@OJ#W"ԅ(Ci$.'; #W@$5}V>T<z [U"8vIY3eʙi6eoʠ;z`K™nO8}8;{E+'�]NNͦc.Ae e'WYA_10- A<NI^ID *ܑJAR'H0H H`a, Klxq?te!rWBin%���IDAT4BCM a (T1TB ꦃ@D 0!CҦﲱ"H.%2PPQug_CUXZo}4|@=P>WI[C~XB7 `7s0&RnwK|%bXF?[Wj@ 5W sxZ-Uѣhzξ~c�FCh+ ]oM{aS46JahuN^&^D+Ō@{R8i*orː�}a@U>3+rL9Ec)@ؓrE he! )jyW$HLX 29fi;GsRRBaykfgE4\Auy ֑M^aErF>*كWCC ɟ7}QS”^qA<7B�!@DrOT`KjQr%X?N-%aKW/0(J2@YaћQL1}ooXV} Y7^3%u4k[G N muܺe֋3l@}x672WA@w>);_LQHnAP] I<Ȑ�8F מ]ki^͐`, 9zys1{ޜw#خ"KL8[(;)UIWTQ 6 [#H]Z)zZV?]M饃<؏h,-~At4OѲBZչJW_; y# li"q�)UAԊΝF7RB] Xۇs 0p1jnE`sqj|g^&�H [2 +u{u2v# h+噞?T3ՒQT=& ̇Jh٣yƷM}ofU~}w.Ewά=v\}R}?nMq(ZclZgMLn[+,dmqmΒj&7<.>nx"}$ RXFr,L( ܷ|` և}Xr+2Lr ML'Ϟlm^Biu^ du: mu>} =W$codWv >`{^݅U;Gf 4x[sY-֢֎<:66RQR楛_ʿ͟^^;Rz;/ $KGkõңtp>)V˯Yҵi\ |c|%MmXc4kP"q=~2ਖ,l(LMaI!-gBPm8r)xoA/=l�3787HԻSsIs6;MqCo6MgӾMߠ6 =_ܴv靴qDhku#7OСo^p76.W󭬥ԫl+Kg*kvƐ<)*APPl)jps( μg 8~+0mUؚ$wzIP%A[y|wo @!ikXӕD ~ݩ׮e l4 <iEHi) 䃍޶`K|0k8SFB5E` H!!IV@SV όTtf8C+kfW'Iۯկ_n_6 dtgL#Y-~PKE0$^*^3WPY7} ܔӬV&z#H+ O ^{έz^Vx/.l;k۞V'^hGjU:P ~"2p'Sv^1YnOmbl>RݻSdt"IM.+ӕ x}�ÝU(C'U~oR$8H i$ _w |[[`"bȄְ 66yfp}rbr ^eK>@3c#h5eVT!R&Azʞ N٧r\Ўv/[T 1oyXB*ɔb!hIv ؂/ At�l䷞麯#55;tx;&x+Ɋ;йTxD-B�f5zIuMOeցM }gf2"jO~9sX7dz4&nSnsvJݦM`>i&^{yC" ?vYU^M]Žԧ`¥pLū@0upw ~=~ǯׇφW B#/qcK #>ٝ� 8k�`OR> ^& `6>'avyۜ:is6<x88Z,W  A͂;'#а 9— C0L>!?w|aZ%_J"h/<ovd]ʠϟ=�xP;AqU,ClXa?t! snJ@h9T0!AeB^h姊kk:Z <uZ_Zה? BMӧ>Ԧ=[BN\ ԫxֽ82;֦!UШ~J1${_]=yMs$ Pq 3+:3FN@ P`OƽʜtSlRi#5VUR �%H Y #Q`5g/5x1amT@X@aMׁdLx|x,ޜ~zs͹'J7,C0M,A;�$ϟg .ܷ?ԁZ֎iB䙊ኄ@!*!ͿK _vPZOM?ϥ"ٌ-v̄KƚRm;Q[ \ 56as6mM\p ZMϣgv?͚);,*u0fQцolג]$د"yU<zAz7@ۡ;tݩ=A@�zrC4M~8�(0w+M<odFGuԡ?t<C|G4ӮgaH�l[+Q Y_+4K_{I|I򌵭[#`A0Gk xo_d~m\oY;C[k՚QЬԪ RV&/&~ ,ĐaYӖ8޻D Nu%HN{$n#HT2^uWy~zTi,>>&�f+dBЂw튛X po 6!0 e[^[]{{fxZ0w-}Z0V/rMR="󵟟_jS4w|LL{?k/E;թuj*ŝ A۪\lY<SP;_q} L$؛a7vdA^ ZH\{rwu;s߮W$j=exu0|nga; ave 9; 6;`ֺ3\Ik wwVt{gf>?_}x'=_o}C}t_֯KuM\Zk _/A=Nk;1( V7:G9ocBfظfש^ >GbX+$_̄ΑOnWBUiPρ%0 OGrI?//N| Yn˔\ 殮wHռ-^>?u~[㧍xfj6F;:q,[^%1~o~w h>h;tȽ^^t|cGza꽸y\)=?y/QVoQEš U3̞\A}�l[Z99F6Y\mjmP~+ֵ k/k5Ʊ| (BENz^SPj.{ $+]ʫW޲uS1Lw6)4\kBr;GAp]JLAZW�O,6sR_CEX:aπi](2 <6Tu0fWtͱ6 OVS/\t}6GO}-aʗ}qr)͟﭅&οM&ݾ[]n޻1>8u (FsВx=MҾʠtn<0Rnlew'!f /4*3sa5 }PylF {m+6GKo6u:ݘR7%ggeWLԥ73ZGS=9Ő;'wnbi%J<y;: y VJyP] x)R k+8pYRÆsCK#" aDs'Q}7/,'&q08z=!'sM|v9i1Sr\ħl~{}{&XVb08B)1G=u ^S^nyOkxo[[<?OWcu,b_92nJ_{0To[[<?ORs)=6#M~5κ6?c:4A 7F86&sỹ9\Sv}Z_/Mع2=8vJgl<z^y|!"GvTv$!K"zEI,P@B(Oབྷ/3l,M_Zi),N.NrHE\5Lc(ǗIS`# (HI@5jh!P RLX]K!!7T j \RP RH)L6*KX ̺uL`7bnĨ+ll!rڐrz@{G+ |? Ix!ؕ앬kݸ5rLǬP(Y=$)#) .9UCuQj?Ol  fUHKє36u%birPY*Tޗ("N(hwI)e` ]XG!B]9pnP0w6\j]].�Ay U<wcnL�ס̞=QYPƏ ;W}L*]*0d 5at8 u c,QE0BBH0U5NeSrX&0o+Ukv 1\ btג2F>,; +;tp9ŝc[8/UА0 wܵ97gU,Y6Rd ⸪ʶlS@QsHuFt{?c~hھھ cؖu* h4jJkw$ ArLDU(}t^ �R]6vsGUb>eO$J1J.nCmcXdE߾mU^ٱI/ѥhemA  )uy��`-Ө"XJR#_t̥Svʐ[ Ft;z ߉f,T+\q_Sx0@Z~\APwC[\Z[q[/|"dU-dm&A8tgI�#Z̋ecٰVl~)pM_@P�HmP{�(Jrʧ491+Tfa8r<Q$JI@@yn. Eٸruߺ X *9Sr@�o=M"P 3˦z|GH*y) �͠Cñ;(Ut"Jgkt7EB7@#%wxTqǺc!4\UWena쮲0o&Sw#U�$20gވވbhP7e↰r�<sxwX`NK#8/ϛ9v(j5;PrACQ5pc(˖@#b9UtOњY3Ư@<{'HhK 8@׀Wm!nl֭UvA؋$2[@ &=ulx"uwO!|0 ht",6��?1Z2*]}̲tBCȺ! QԲf cmkc8/fW0BG&:* 6Qkј 4KQ(1T ^5kM0? "b-XCJ,YSVZs#&X , tap,ܘN솺]ǡ ˡe�Kjal{{|4nqC?CvV@C�A�FvHtvY Qw4&2 A,ggC[[v+H 'b@xPB(tA�{†.Oq 5!Qq@c�N1|4~3n^xo>emhpȬ5{M,ӍBP`ɚǎ1G< rhi@�k$rFΰO&M C'A\TK5]QP:`�u[Q @MPcHDwIjZmm?<JA,;p=hM =h � V;x&M`a,)kʲ[-;K�M;)ؓ&*dA@;�m/�M5R"%A6k<bu6P 4DZ2 K&Z@PVJF,Wwu/c;e-:Y m*N*+  ܀P9j hD%QO2tY1 rbwBqo_@~ayrliM{ iðlꧥAmJDQfY`l eEqbixyx�1b4�4d*m,UڦohMVaeqEӣ`.,/ o"Isk� T�=7alf|j{TY2 �#hɼ* fi+/fȢU@6U-0@!rVQwqk@Y7O鲥d/@ z<$+2 =H5EuVCJ@!"FƳ V2 F F BC[xcƻ3`�KCD}AnQ0k~>@# mCD]iQR&C@\3=0(~yJpOppF9T9UFy6A5zyT"XH* 0Ib Cp[xCDm6#;ZNC[ʡiH*<ͮKOzRU'Z4}$ No`EZYn̐L;jMG. 4Yҕh)FNz5hByE4 !7=YDIez`!SY8YDI5 ].Vqz4>~Elo[ɢwfߙq&dލJ 5fSpԂZ 6pIàeww 8ऩ٪Z(Y5߻A-?ݦɸz&p+UʖxXM8c\ 5"}P"~aԥ&ޫ_~#~|lVnwNj'hWf?t7~vG>fwo;w==Xm~i^OٵvrZ;:^ȅxmPwKl?uWޢcz7/qmI~(۟mrZ=tOhVz uSjDuўS3hͩZ\MMQߡKrZK-VkRR'{xTkw-.Ra#uk6)W0a<AFEqXT6D!!M& wı2˨b+ 3gS�H�J,jpv5HvFqh%cf -骥J6Lѱph]ӹOhj-�,²j=`A]$<qD°v4 Ѯ*TWGùu(k5m:m@bi>؋u4` 8cuC8LUr0M%>yм^Vjߥ0QPwr9^AZ$$*4ȲVǃ/a;+@`BTX<{񎔑yk#Dƕ~:M(?>mc*ԇccp}roi,^Yt I0FĐ@0|%xz.=W9!| M}=iܓs}}�̠/ϫx9R(@Z6r{s{g7SJcj6uDn_n_6Jwb0L&ܜn7 p[nsbVYF1Twinu>iBM Qe7c#}ymU-{ )Zub箎9'U}FT7s(n N!Zy@XHC5#F,_uاJ'U0@+D"jk_{G3>G ϟK,ܠ'68~IHig <1vBLg^̼P~i j]6ni^ĹzVyn;QW,>�tBdƘA@AA-u;/:@�vFPR.uHx2OC:VFuTvV٢c^@VVgCUi]&`Z6a( jZ �ǣgxKuC<Y7pe4tYgvtP1/"@q@P̉'>V@j9845t2^G?͛I_"MPi+m]3TPϠ*~[7"Š@%cQ ϫkl%)4͡^QeܠA!]wu{ CLjlqGhaD!uYvdy?pA9쁀/kHhg4~+*+ϙ`TP{ Fv:J]\ BJ+KN5; NA;D$�\]~|n.}!'p-w#FljHDJPT3X 'Bz<|˺ŮJn'5 q;x;Fh: g_&$fׅm؋%#0 edڜ6t}�!N9?IN-ܕ3 n-ǣxb>*jRMjWNvuٸl\Ih0懚邒ʝNhq% r' x5n~*_~!_oxpod,%8QcwF lIOW* ȸ  (QqCw`ȵD;zhbuxF`e"jM Ѷ 000_C&z}g p*?yRU^#HCn |BG�Js1T !tRQ ƺ;@M@jJ;ny~@am,<k &(yqY> .rϖSd1` Dh{FP/k5O-ƿcPC\whDE}qN9GFȊFO%I�=q^CkXL̫.Kek~kakk1׸~eJ"a2`u3@w@uE:>^Q|&;, hAZ`ޠ}Pe2Ȩ`9BKAtLc#^Y]Y |楶 'tZ+U��24cw;3 .&+G'&@\QYu*[{@mG:ydm͹&@~f&Ǧz葽X2*H6\41/gA;|-5{.iJ zC #v$oSEIIaX4V!Χ`taf]2" ZU 'l`jaX4$¹X,:8g\X;5&0c! "֏{J@Enbo6 ьMH#�W }ԷA1tJ>L@j5 ArRWAA }"FggVw�Z OM "9+! ͚�Uʐt^\` eB(qQ@9d? Щ\rNy;b '\6@OQ<LSqCIra512�а# %M'*,`, ~`LzΡ1"Jp`y%-d �!+| A8Ң O7O@q�| =RKARprTx̄ɛzV: ݁kg Oi @{N+hj;$)Ic$t>N߱cYqp~L{qIJ@"M,< A\@ چ'Dc˴VՐP8Y$hhb7bbb Ng݈(ZKIDf oS`4Ѽ#8tRP+jHTCPFzXwwc;MuEL^r@A݄oRԷ*;Gwr:&`3^ #~]dB7uyg?he_?.a@^?o=5:]ݴ`fgHߡSdAzebKm*}әݳgVtF�UW@+wxZ^S>$ ]7[ V[ټJLeSU8Y]1zGVV:5'7\Ypt6 vUSR^ ?»f5WiRx'ga8X BN6xVKi~V8II3f߷cJFk>gkz0ܒOAQwXmY8KTUaC^FD4 WnYh68^$(*RqbH GHRh?}q8Й0XŝO(yB8Ҷ+J?čӇ�NYuoVR̡JUobij{KnVpPysYTnI+.jp0+*VD[Y7_gE+( ŵ1NjwvGBആx0ӖH'�1t G%05rX -s:~FCE!̫kZP(p*MKrZ22QVtMhÕ2;;Q D.P;H܍YYXz0`Cf0 QFwcÕzu mm]�~KRXQRt'#%ަ y64!:CAd0ʏGw@91|$t<Yj;vN>V<тw=.t<BfEuwDq^ J` op~Q">qdv,\lII ;7=W)yj&PM~8{|8- OZ[h" DhəY)ZN%C^t(Hg:eqqvAΡ]™; [qFA7� 3*p/8O/LG)Ŵӓ05F6Z30 [ⴹ4|55]!C2L jDT@ Ңf5B=3NJ޽9rPdAL` tݨHrBBSi4fb.9e4kkP3<ڝ,$hhWWPQ&obX0hEHr`y X |QE y<o/Syeo(ʸtAPAOd<Y3hI41lܠ .Q]* 35AE:B@zwK>Sp-ZoyW=PbBL#;g8,%hE( z?T@7i^($#~Zi @b0.ho M w cز>q, qir)І ctw*a@[,/;Q@AID (*H >B-nP *Ah*Dx AZޜO&J6] ܉܉(b:' C+;ːoq^a7/G/>O)c^ eYhRU2yo{.q8aF(-_ͅI *5^ bXy+4u 5�BܙP[Cњ@t@_m)\2s'к�=H- @M�Vi:h0YX UgZSuUQyx B{ҞTY40:0r&ltDuwzT4e^\AbQ, |W)$\, \$U�U? A�_XRAZЎj{ {ޅ�`!53h-s}BM`5Yf܅ܛ@U T-!e6kz.VN!4m( PLr6"VڙF� {u6%ω@*Т%jZ bn1z"O%Wv `EJGԏGqHX:tո2Bq3O�"" PD̛WNXFZ`xFQh@iax"2  R離"`< cL(u#T>;2&j]h4a9ȂJAQc&@73 rl�<qv2DYfQ&ϤQd 5�6 &^ N~,R1 M@&֭ lJD5tSAA@;-&$�qPB0̂Y jBD x1:@$#@T"8:fD <F4Q{P4pg㇨d#x .G@1Րj4DP= U>(Lj.’8D+Y7ֿ\N|APUelс l.�ryٰ ("C644i$eM ^̕g(mRtu *a VÐڔ43= 8:z1P8͚`T0v |?1 @&\/pPYhFɏ(O8K�1uXHR7[[),f*SQL%e}klϡ#. kAi<8ZB&41A[&]4ks pav І8!Nio iH?x5} C< àG]Wu耎#pdqW;@h!fTHs%h(ˍ @J zPL&�D" >0`&30&lƓJ �3j � ߆^Eucb RY<]Ϲ0'4�+ + ,otwAfdb-{ p  &q>KAс]S쓞, X h6SGG& !"iLxEd=;ПBޤR5k]$ꞕDLTxņM zCiW '  s~-[UALm :_pXsʾnޕr>N<z-}ZO_p4>ݝOY+Gޙ2ሢh# |ˆInˣ@ h]OCwV`N>IAQ||۝z;,EzS37zeׯG/\+j ucjJk-YO0m21d]EijWI; Q`<s0 ɐ2JҌ \."v7K 3mUcz@suK4/ihő5lPқUݍf1D\{J02@]åi_UK~x= hИ!J.B;9e~ gLLՃJڐ Bs!IzT[5Ī�|ΝiqΎ2^c4%JT Rw׃7i$hR / ObC1K#:x6ϼFkyzHى< Fw ZVX%Vǧj'd]hO}[S=P%^pA1rNN| ɥcK`\N|e\&u7j�+w<rOB[XNN;2G<^'J0{'?j)7jk}b9N# 39�nBl! V uy\EdISy#:NW(9= ]y.)SyNxyr)_1/h@ZwO7b1M 'XՓ8yCSeEkI M՞z>f)@̡21jȎU?!p@^-{DZ׳mJz46cܚ5q|6-7hs|G粿b |5(r@<>4ٸK^ Ѽе@@F>:1r=fo"s/νKXx 隹kk٥=)}=焑A�9  ЬgDqe=q'ZI^dӸUCup/xt|@e%KfTU' F�9͓X™jH~fғR8.%eY5@@M:±1v3N@?݁vRCOw gVmӡ/A/js9ei^`Z֞eӊYsţsYQ)ql <-\ZId�AA�{ )zCgnVA .Iպ ؉kҞ?^VI0nÄf$T9ZlnT3%,; Lph( ]˙p&[rktCdc'N^Pk|WʣɝriGeͬUnĀeхРMm@%XugUګwwy( % % ꃍD&D?yדA*4ABRYJ^^P?u#mdЫ<zw\ЫHk)hQ'yM+x&\0i:>QwԜW %1J5?2uwP:t�HaLL �[{u%UI=nq~T<YzR:K{fd1*<|#WeM#arqZ >-ӂӆ_eMmA *&ym駆Ee,@95iwZ$w'1Q�=2W@J@9XM 4Z9B`X?K@,rܩG-.1kp j] * +*2v�RW^TUūOc܎ߎ i+8Q<&6Z5AJ<_=n.*aVTB`^QS&85c@3dU�o LHUC(ޏ@\; &{s=if q!�̱1D +d4r-ܣD�9p=A1tTv8!nXdP!Z"XI&hM�G76v%ƶzP{#uw_vXM@k�3|G-+ &Ћm 0|,>`aq OA"w ԜM &PqV\֨QwP6<�:Moܻȡw@. j酧 |Ð@%l(Ȃa55, =:BX!K6{qx`֐a6AA-{uHf8:93GuC G7Z˦6V ,E9Drs%T  @qF"PSP9_�~ma%rD:o!p`E &h8:l^ ]IƲ CA1l #CtVYuOh#<ݦ Rvv^xi:o7kf+c`ӭ*|{2{UE,e 軑+N8:@=`>9 '׆+nӐ@݁O!ϲm`sp>oc{F GP+cO] kE 9*=:==.">�5jNAyooat� F Uhx=gGDbtf@(")pzt0 A݁^"bwp:a:+^zJsU!x-'E =YD/) 'bBztP=22_Zs] }J}B�®xЌأ:@`gWCY[@w z#8IRhe$=YH49M3@-$cjU BғE#!'(r"MB@RX0 F0D6MMG.(0X,&> CCХSM2L-b`YŀtY2bdɢ>t{AV2P^DJkj}{bxaԳ&Qal<N-yW{;[;i!v<\cipHg6CC;4%gluMT:S_k ˡB4?kqf뷝wtr,T}lαbeS'!l[D_^Xk�2 p:5g\47GǷ|@Ǖ̕71dpGWE _Vb,<e+DŽyFQQZ(4g^Ȓ eC8Gg%N`.E<g`X^U`'di([ӲT&ï0z>5ˆަjւgcj B~q%s!8CCRG}jm콢]~cڴ2a`<Z`B1`6E^s!~{ gF=.N&TU*R]?<l(фͨ)ΨAl§Wixo%xT8}&s"/vԎ{%zN)WPjh.\x;#,?}gߝ}8 T}Y"49RiJX[Z իxpj *|wlyŸ /q'`-Y5wv_95 _9}(Sv I(q&EД̫B X6X ASqβSCpF:wZ^et>�7H'd`!<:RYܷvw:fuTf,o@3 q8F`J "ɴi� AP9X F X\3gӶYAW /^D'L{}`\ Ыq%9Ki1`u8#t$A,E_*@5@${ _B0Boouw%"VV|3ZϠ&1W-Y<9LFC_Ąg^C@iS�*}A0 7 dT~@@0hץ64..$�@'叉%)n܍NթYC=\|g|M@zĸ>Kӊt1x3~3 >-0 s:q߂,&ОܱwOUs{Šv9 g23A3:@Z"HϮn*A3 7恺<Ao畅uwA;Wpnɨ{;Ч4ڭ4TqU<am x݃uA2E̗)<A ¥i)<VOA&ͩQ&`\A`Y}ؑUVZ)$! ą|V/EfɒdT;~ڄj˞~ه`t<R3wBW 38w .bC 4>"7p9tgzFSI  @i3h v aͅFC+DqUGI vCDm ub{ @3Ш߅?Q \j |uDK=��P3bhzT/g. Ȩ+d"PdSO\zr-5[r\@f*78=<iVMi濥I:|VQh�s>V5?#1Na@wٜ Wl#ʓ&p= DCwZ8dViz =. z+O~+_W|M OY[n@w ߼MiRx&(�T|MPVʹBR 6z; VN_ȡ&(MpXFﭚ`)bGM@ �Ky ''P& 7S. Gbx;4bݥ4:" A`xЌCWiAɼWP g|5h=rHטe !X =3zfMXax&Au&M 4cuŵ>2}~kEP DP5bApb&@h^(|׋Y. tB צ=\zs 4OL.E|)J0Y赉tGܧ!bZYGyt!ގi<0*|Uazsf>ZHhM`7l�;D 8C @05y=Iぜ 2oEs0:H~<u(HGo,z :TB6#H{.@sظALPLZ*n ^- M7\!d<2SHkk,JV`u0T5x@ pzF@CDOeP>qb3�նQ/CH} Jiqt Z < ہ@ e0� 5A$RvQT'șj(My@m"W�w'!ݚ@0"`whybPQ.Tc]њ@? RMqy%Zț,A*@jTSGсSX0<΃%TP'Eēdvd`w~N<JА!=YA5V7jԥ`cc�zhu^5bKfyh|lg63GԔdI}>8tLhIdE3d-`iElG&ۏ66GՁ4$R+E Sô@ɉg"Kں޲}es\\tN@/</.[$F2\Ez#UNZU1ȃ7:Hkx1GbZ C"PrEjd0(†L*LcXTuoso=90:IfpoyH}2{C;䚿sN-唘u쬎ƭa$Ya@RyV faI=Z<sXTǣqp$4KBfrr( hI^m Ȑ -T 2?Nob©f)kTb9ySg8wc|*<\%(94I[y[qo9Y².gmimA UGC s*L4I]4 ߋqh0EK# ># N�WT"J1 dE'5ZPF!B^`�c ĭh=H&IeRp_>UK(X˲ cǓQ;{¹0݂^97Wuu[@4 UjCjhIAPexZ ^(B [oc~ ǀ Ayn2y?+GqUcΑD k,.�mP3iA&Wp՟t`D`)7wej+zRANB7śPz?EAԲohrJǠAp3H RY &pLxяFn>}?-@`\IAwScw0<yS?\ȩij%74<|Pnme�SLT�/~i$M`81p%Բdش2PJ$P\f޼RsQtN*5~|ƦLkA#R!1=<\ϸ&/Bgvc%jbvQ-~4$/_SϫӶjht' \YI&wLG@)D&U:BC/h  htvJB< |a Q .#R6N˸cABD y.N&'N02X4:z{H/^AwqHjor ׿~yp" m[ ]7, GqtW2k ^d/WvJ騀mGils^� X4n$ ,C&jSLFq4;zI&nBѣ4 ϙu]]H&M@ @ΚdX;5~ (ވ4 wDȃ'&= ؛8@ɽ/P76A3cg5&bN'VJ`Bv2(A Ӊ;Oo.<dZsRyZU^ms4)I[� b)*nz H9x5DBΪhΞJ@1wŠOO 펭Rhc|84 kɝ j\j蛟y38!6Єp} mlzm=ԍH5~`b5#O5`|z^mI XNVGzvJ9\7ޙ Ƶn4Aud&M5il_܈jMpU&t #&#jb݄g,�G JDz{|N[p?f 5#D5A؍ƴ_ hu01'L ԃ i5>˶+Z70{ @aT#?[&H<M-%ϳ @пcB~[4kS5k-;v: IE G4 htM \m\$@Evx30eR,DT n_}5Δ5s1ثM@ pXp%8:@@6#!M̷ P�g" JN;>|;|nQٷ J@p@pWaA =@ixoh.ᜆ`{h�Fp,ǽlbr&M@O@FlͧSf У\G9(t4/ԑFhk7?R/z@F5 44'7 * Ft4Dto 4m'@>Uh>lOG�9ui4/Bd`9&^ *Hmt Mn70zpBS _8&ۡE�ǔeuMHReٲat@ ܹ< �;͵)"p)6ɵ6(*4?YY`c!irb!i^ pl�*@6!ps8j; :<& z.E2 4ӫA(w?O@^5 F=y_*3&@05EׅMsz@ "Ak=OAPUZMP>zh@ =V %~yxf <+ Oucvz�4` PPs?ʌp 0$!JE(1+u g CoRlUK&;\Ĺ@4!i) )5I ƚ]\yQ�け3TAn`2cm##iH: %+ -n ]BNތ!QY8[ ⌡:z(GEg;hI^+F u g"q|`x%AmHʌ!nQ75 Ypތ%Hxai^SqRuDn۞kV}Y9�9AJ _b_Tg7% uRTwpw�` OCR6W4 Es7ި\Y+CK`\O<}^\Y" �a\Ak7TWMuõp=ڏǽf_T߅k|n2ꐮA(lOjlMUW?|W;ZAո-fSUsr?U楌$cm&&QL1H뇺.Pj+*cfBR] +K(=RǿZn}l&/+I|gAyAɪJTx{Rqx=mpл $M`R HfKp\Ǣ8ҧDn@ ǑOgx֬Ɉ)3S%}VL7-Jju,$J$c܋)8_eb0Ganp%Py8*4ڠDõs8^sLy @05?,^@@lJmb K߁F3D6К`%婃HnD]9uRZdwiYV^$c| Q8mVBKK%-IFr%A8OS9֤;CHԂҬq:O|C`uS<AժU%z ǔqqszM&h$cx4k0 ALc ^I[gVi!ƍimBq]9 OsP9'?,�AuDK#T#x篤 iğ|ګV I p3B{^z88IdU bRpL.C F+  j dT+C q5AWs�T_la;8K q b +4pN^y*Yo`U뽒-m2 ko5kwlVj@n�AP$~AfsW͚4&%В* Y: '� /9泪b]@`Ӣ__RT5Q&3ħ9Gk�LZ @E 1(sꀊ M Cx%@c<G Aj$H#̩/z 8@ 8 G3! C61pE^O`<Q}f-Ǖ?7m} z=r}ޕ �KDǀ+ ({ t6!b  cTc[ M d0{_;47!3F AbЉc#s Nx!1$)A#)|Ҡ&#_ScTޣ(5O |NQ:Oα N wFdՉ 87I`P%94|V tIu8 ~ _A `-&pgr +N lRz` ^"_?~ѡ=#?_ԣ OF@f@U_ 7h"&*:{_E�5AfGE@ L@15�Ia Hhf >_;ͥY!\QPˁ}PaCrLK;JE@/qPȀz6)E>}Η%O4% ~{HY40< m㵏f9'@C�nnp/ : pIv6r@Kl¶ 7?OOWv shDx�tWAN.w@#(s`@0 x <?W&@ۦMډqGk6pev3n Im0A`Qq yMӜi;6{@`7H<Ϡ5qrȄMqPӀ :t#$+EG|XdW/ޣCgjh"MDm5fq(+o?u5ӭk\k2{%Үxן!+ϾWEdx)WLϮw D;¬S0&yV�ܪ<-o0]L4pLhbtHx 0!ߤ˵ I4h#S?A#djM`Aw z|G|`)n?yhP@ Q%hssIhmYx}Y^gɾD=:�Bta݁^}gr*Շ|`˺g&&y- A@i_ DCpVTMռ<A%^5AZ3la uf&֯>mkjO@3Ad>U ⌡Úp >yF#MPGg%نMJ Md=M M .2  - 5-`νZFC%usj|ị+ ffb@AGS`S3hM߼L2YoGAA/I>JH�Azcx3L: 'lI#9 ԙ {O uA0�֧gm35< G<W VNIS$=iN3=Aw">tRvgWh~ϏZz i) xyKHx |o趫eliS@Wm.{G~4Vr?_):aA JL8zͦWJ,W Qd~B^'-?<e[>.9r<?Dָ]kIfkwb6 8!~Hz4p8Rn6'ӛ >KꢁiacJ1x_^3tN x#jIu3 9 MѢoL}ašUvdJwgTsצ#R^8<0?ʍ?q E,Q8#3E P0ִtIGi_O&ZNp.v_r4#b);H#y:jxQ2l =/c{PU/=p&E01iWZ@3.O.l.w 8|ՁRy=YRΤ^Sroz=GSP/CӾ))EsQGhW?K> h;=z x.{sRG[@0KYw&E!s4y1 'ol~?As5"]05 ꎺŘgPD9n� {Bh.G u$O_O365 ]V3pSD+w9{xPWQ%#?`H|YjҗT}J ӏA03(_f2;XOHz?e}nTG.s%x DlN4^~w7]5ѡsM}r-scC\&g٤+ߎpsm<LI ./`.0DPu ][�^6CǼIcx)FT.jK*#ߒ&iQ,!QV,{C8/CMgM {$WdaQ44)LAExԛEBKn͠ALo!q+:i%Q&'OH;Uur3j@0E=z.ZI"f^]0i~"[(uSW9?(5p"Wѝf4x�䴂`rJIy@0E/,BW=6(@0Udn̐6xhI5-)uYFGF.I/ϻ/n}k�xny3]ny\ٷ=\FRS+<hϬd7;~~ҝ&qVӠ+b껤>Oj+ 49.F͚Iܵ@)ϓtѳ? Ôjx)00>Sxݷfd?'M଀@fs Y be\RC.ѕ5wVx>E<YTgDDDRhTH3SiNU4V@E 0I:Fo pXN{6A5 W_P_#c mtix]y]= cV|TƝ^}M,1 ;>EA8z~ J2_=: k*¤5=CSz.@iI^C X _1xRr8=/uNLYB%,?lB6kz YovI @k| ~;;##/`\?!vlmABR⫇ W[Z^/Vj EonfĽ{IicRgK_8% +#hUąq{S:,=7`F18r#-S P g)֦ f{ 8O;$y( >K ! N&8<@Fd&<p3I$<0&  @ $  κ=fMYрB슪d^~X I\&nKdx"p3`°Kt`�dCh>Gj\~,eG#F VvM XV- f^ƷTF;KI=e;N'c(@ _V6u-'oõqmdXSlks<_$Slg63j{ D YfB/N\+l86m4(sϴ R]yzjJyfErhaRyÀu'$0i~𯩡2ulywjt}}􃾻)ͦգEO@UVZ<> ]+/)LPJu5׬0gXA+״JV@I})SSgbM)̶ (Qul$\U[TW+%[f1!CBZ& U5UPt/x/�dSn{$TѴ8*?zy=)g{k>5Lyd[vw[MDr}  uETtM'XUuV8Ω5 w{LC+pOg*A6n\ۏ8^õg]g% Yƴ^7rC ;U~62k={o2c$b o :�[?3>2cMQon Ӵ=Ր] �XWrֲ۬© Ғ!Ǵ"tChר=R/hYy&aLd0,ǥv/fd4iE'}Ɉ,Fxh^cym4#T (3:m\8eU oN2V W ʩԴ13RWP'Jۆ_*jJSUû7iAơۏ@ :cQ rI>PcLk^˸ z3G0} g՟7Rn8#aRvEp %rOxǚ{3Хm\fաq-q-5XA)Eu :,HڴT`i1$åeBPuAjX?*y pbJDJ+ 6DU  HcjMP&Pi4#A1 Dq @JJg>D (�+ Ț*)PY\&c582A5:_ONgQaWMC?e9a$AgU.q3n i`#7ȴڋ-;;ͯU"?.!Euu] "5*#anX$FO@7W@Ub#ƽk[S*>=V[L<8CAi}c J`\ѳ)M 4 ( rZQ +r�2f"vEŤi:gM]Ssx?6"*n|čQIE8L��-uAU՘w vNA$ Zx8}Cx HXp P 8ZjTmO&pLMk+pX%3sQ2 `'+g܏8pD2.C7ڸB$chD;,\uCM!U[SM42C<2q{�~쨘 >}0W (`R)^yzbLwKԌݠ+*Bv@/+!Ώ�Ngql~㟫?P9#mFW1=ZGh cI�77+Z']5H܁n�ݯ7Ԛ@SNqsxD; :~Vs^W>dܵ7un/,']QeSy+kbJ[ ]Tq#ҖAuǖ� r@0 Xpvs|YM@ حD5Ǧ@W 4)p.=�3f 4#w7e\ay@ 5$i©ABg`ņ~:7?4�/܏ذQ4�c�b�y5WYZg@x e#ug?\о 3]xYqQj2nB�Be-BRb mi~3a � D� $MG_x Lk pŎkaHl �H h}L%L9 6�o 44T uΉ 3mnjEo6 ʎ60&1@pYQ@LQ$]9O�AhYod0GK{s-B.Wz0|X<k* jVC@`<ٿ;�uԱdL;,)+`d6^uAH2 hYllڬA0! C>p,6�� !Ӻ H �9oT\3 W#=Ai kSThpiN"o<C·qSD�o Z~dڪ{l&V  Zƅse0k֑Bj`Q3fhL/H!ZzV�A bY&݈m `&@mAO``ش4F ,�6`Ѵ9i5 ,|O7f)0Sзֳ~д&chl$:ek㈃pu~S|>MC#�JQ]&MQH+t~ C4zwXh/C7t GE$c8L 'U-A#\MfrU Tը)ˢ7\ާnj(FEvhP쭚`1"T-S=÷oo0twB'ѷx0q q:)t1O7c6\ ?gd6t]0& *e̠[۸ x=#K!%uSIu@�dWx Ix�~ @v8�"fS$k'S5ܐ+pN�i]�guGmvynhڟ!nWZo)g^^dYceMY lQ j7<&7�RlduJ1ہ~ԝf~nKloD-VX9֖]/_+J pҒ` Jh4 ܰNhxdNxU&ƃYO1r̩c 49iAB_R?4SSԥĥGG7/ץ䟝wqm&s4S3&Uv+uǽ=,,ar#ggadPKs6[ 0;)]AX]Jz +mSI(-6Z_i[$p$ h$)xtp"̈k-n{2s/ Y v|A)S3zhn Y{l ;Et70(u=cDhV =襬k9 G⨜I^2L^@. xg~ @xh4A)o_ NTTݤicQ��EٖoeυNSDAxIZH7](�fK_fy쉅X #"fq;30R,,KF{%Fd@,F"V{0���IDATHƥ$Rq [B*ܨi;87.]>n-:_l' M0g͙?ϟf;Kka{`;hD~.άK컲3 ݈]7jvbvʅ /wL &gc;OLv\ HN̼;k({Ҟ~ iawYK86M뻻"?ߜJ'(JT[AKZ xJl�(`>Q 3 ~}",\%'ޥ_UO7,G"w0f9^޿<<�-@XwN3spTR'/%IhI~9 SKhd' b 铧N>gMM ?g”8dB:ȨXr}D$aw_INΞJGOM$sHrPQv=RB_(#ax 1gSgO%"wq{EE Y5>Z2 XDLzG$ܯД#Xzeh֜; M,­=8wS6s SsDyD/ 7 <~3j?gR uaAGAd"�A@pT"qjo$1k):=k;^J>Xݮ [KcSK`enҙr:ו8;]vXV<>QYVce`a7ܑ -z4kRbV@S"MM^m!e\wXd{EɍN @ rт@uH#,Z,}3I;~*~*iЯY5F3J;}!x!H hxm"A Ph}j+aY循HZG QzC[}U  XU@?w/=@T}u͵Þq%M dJV=4m#\Ǟ'{8:F{!�u´!dV&@ WvVT"xzR/=@@aN"ou CGD}1*A(gV@pV-ͲgO^]Moh93M�='$+wj}}y>EX"M Ou,.�k5+�P_.j�(#{2:!,@j$ 9a])]*gnVN"n7 "ʾ`α Zx 5kOHO.adK =n>7ۈ'T -U0 Mp@F?:>�_|5ՃAv5{CZ8HtY=Mਫ ,/_AV腫- uO@ x@pܡKhzFlrIѬ h ="-��C) ܜ3'#4'f0#M� I Ȳ '5dF^�] z{JnF<t4}� ϮbS `ƞ<;8{?sQh|.<$/rN =|;rM�s\x|t~R9D-7DQ)(? `x^D7 x5 ܌];?Ş_%qt "jd59 vNVLBw�}TNhX 1˾'Sv4}~H2L6`^Tȧ?;C,e Sp"|4 0@zc琱ĸ54OɓWtD&||#>r& }! =Zn_0d\ (ua֞ pBQGI^<R�(ݯ}sHpt Et�g~2{WU*DfFfa/%Y8 AT,7A3*vqDdF;4�, 6A�ilm_Bi hP|D߰.EuAb'ތ)YO#j|""T胧;kD,x A @gl.hguB�5R'ѥe7Tokn*V&$g In]kϰOIFou{N-. GJI9۳q7',_9 _˖c_(+W$M�6WRݏ'hs5 $E)禴zfNh4Dj-*T%UV^/+Pa,'&nV鶺] Y*c[C8 RJG )0~=Y -?aY[4'A(2dm\\_'QM)%u='WW?@iThĪMZjf)4Ԭ a:zN< l\q̪k~wz%!qZQ6DUU𝺍n. 0HROk;*h飩Z#aJSA O)E@˦{ mKwpRCy13SL@#>:͌-Fs͵V A٢i3v-wN݅wli3V8Pk~GWOAS�xnએ:1f}E =`9|Avz#Tʈ4ʻJ =,�Lt]":'wJ(4I. ڈr/ |dQsIxɔYT%Jh+e(՗f5k݀a!T5zTFըlrrNrFvy_b^*42!&=-L kP(ZIxT~q$=<zad8Y\,T'R6~l*P,TYV]ָnH,EqΜ])N.NGCK{_)N*{ IF!OҌzmжhU6Ud&S{9<G~DAHh=8/d4a@Aq9!+�є#dR`XC?VAؖ#G�W'�<Y�UJu\ -nZZT4㻫!2aCdjo߳l Q|OL$q܅}s(2Zgh&"t!NY:N&R>N3ijĕ$e4>څh~?ڶH' њܹvIBW}Q\=Sg,Y[3nɖ٧g?᪡^q 2n +"Dz"YbmYLZDm"*M˰E"6F@PX&*V:ibIxO .:-�2|=G[] ~�@F!M1k6˶ 9'7"~I'{35J17~bfj5E/,T@@<WP�N^H[>O~sw~{ހN pfyu >K  Hx ysz]]GvcW$^O_ȋH)Ϸ/ #ra[ #'H)m=LV@EcJ$N\sC0 7hkaT -[˧AnL<l(ť6"9%g?\<Trr;(wGfEܝx9^(3W2.\"Hsi[s}kXBXN Й-/1KFCK1cg+$e\BAoxoh?߯ͻ`-ϻ?sV'Jڒe"2 6&nk p#v4 !*AvȍVbkWr5RX>ۏ�qD *R Rv1-3"sE}UP)e#(A" \s kc$ (me$F8IKk'Xq1> kK  0x/ՠ^@o xl5 xEd9@ |LٲI4r:~@s K>e ߔH<{@Gw -D&*\|)}5s]?<5lޅ= YR/8ƽF $Q�'4ƨ!m[U#_ϾJ/Z˅Ò#nI֢qzøtjJQ"#}́n�s95oA΋&hڽkHE.ع) Ș3F$9toAl3E'�FbLd&6Av�觵&|w?�;4׳Tw^][?{`! ]̿W,SM`6lհ m!&F2`BAVkМc5 6aB#(ybVGyUl8ox lZL � "/o�J4-lJUdlF!J4 xii8g{1~. 8^U7/NY?0U;!&eQ0:8sJz@sArֵ˙4r"|L�{A`�ekOߕŻIJd:xMpf&a"<á~o?Ea\zj9VD7UT^ Zܜ =֠^@`%A0']U6j%Ws uBpVc( 8?aYZ-ъPO9|pf~ioqwsQ{ӖVG6�W6Rp@$n4aSlgV�G u9TK?jEʽ[7JࣗiϺRƘ<\J +> iӦO>ZWU1X'12ԲV֚G*|=4zSӹ%A Në phOF"jWϋϗA[V"?+8&00l  @ j T&!JvDL\hkO@(d%V"K@‰WU ]q܆'.=,3X4pVdl$kVE y4sh1�rbO}M+鸥ZSs2 `ezsdo{t-}p1eBt&TZ3%VYdQPy3^~^Sev (M֍TJ_ FTp ^@&ys 2r jW7EU~ +dG><տ^Q'hsCAP.A#gܛA]3,|U;K Љ"{�;h<"{?}ڴ]4 x uu-H͐Zs8OS*g6їޒZ\A}ySȥCo ߘ+4mh=b%gfH1ܩ걵߹N-+rSNsQc<q1)Q#PMJ5.ꃍiSpPKRl?c4IMмJJ:4Jq;[tXs-nZB=m&cbT_6a oS)zK7L=%yStzAUhM . ת;? ]g\dCsY.{NǸ5 ˺&:TBj?#5 E sw|xp<h0n}[MOmWd0[#W(=�ߎj>�tq"bX2!|/!ʆJlXxR iZUW0hf7]ǛݮMl0^p7ڛEߜBk^E| !|g,4?/SZM`BCuzo~T53)dohZ 'Ǒj�쾸{ad:مHqr wi7[HbM�@p.]= ] -}&FY? A6RGZ5/R4ʕS>[&(N%BOP+Qmvc=z&0~WI(+Q[X�Wʛ0(x%F8VWҎXF {mT_(?-$}&�Г^K᫖BԆ&xffZ-c(g쫇jm*n�Ƴd1m3Wg?)~>t@AQiRS%kp9/eu_VM;]qg q[)2}6ќ˄cf?Twr#)Iwbw!%/*U gAwUf3KczT!@aD7qs["*DAPk^U,5t{>$z$TӒQ{sь!M @{gPjɎ\ao�/׎BW 0|FgӴQh<ϪӴc0_!Rû�'^ߞ[22͟Qq|ND'qKz'Ho8pmk4a6NBf[kMy;"gLQTMs3 u^{qCt7SBIC<"Oev5L @زAp5ǔ&\0<�C`A _"0E_Z`!uqr Ѝ !샠�_J/'ߘ9c;X`) *YlJ|*<>A`A%e` 4E'4U$ qpMfLr?Rwlu議tiỻY:. u1D9gm$oUނ{u?L0?HLTmV'0af�A`a7NV,ty"7v;ֈ0mk@ 6뮪xwCA)z*[w@)- ,_oKo~K?_?\ MBb1@a'F zVM 8E Ju$8k�)x =DqTc[M8f@ wCP< 9q@pTvgFx' 7M6ByW៥; 9I[] g }Tzk"eUD(;�4�@.@ꅈapA;F6.3lƎ/o>oV գ&j�PcP &S> Ddի|~G&Χ'뙿1 RٿTq;lp1o>THaKPͺ;A_&5^2UyA!nԌhwy=羗l4<4,6$>B')h$5O!M@N/w99FKqo9GG=Y jJsSg+X�?QPx*rl0('*ȓoPߞJ" P) 6l{?\rXEֿJeaRSNFuoT /o}z~o}wuzӥe'C،äL<B@=&ɸCп�  8 _ׇjea �ӴO5S&@7- @&[$pބw W 薞#uW@ �)u %W_M7` MAwYFlh~ۚ#ґJ;]&X,+N&�I |smN V3AVc@cT󲪈Z0> <೯>>R@M-{ |Sz@̷_/nzM}�ϧ�04 P~B xL/tFyu@!\  TӞax?�& "#O�)ǯz HRkLQ_@v~@$5{jS d|ST?3ǪkC|ɪ@ #P>E[,XQعh,Bh\V@{5h EU;Z SȻ}M~)pGT*[3=MP_{<^GRx<j3zxtW> @O?DV8<V | n, K[#?!OÓWʧPlg& CRg9Ѧxl7 YsL8D'!t/ߧ.I40,~%)hdfT<TtŔs š&ڤ �DoJ]Oց<sK=צlﻵ%R d(vr&qҬjJ)큍]nXIy0_oraޱJJ+OK:@2%͔a~7y]%SL淩].9NB kft$n%ΰk~\] R|4ΜeIÑM�A W:Eo⦝@~,qg4G @pĝ`U:gPD!WǠmًi%n"b/͐RmB=whN'@KnZd)=T08c8Ŕ3Jsc+7oY>n~K(wq! {#<k-=%۟q?Mدzoy/?j;4-F.\PBK(Kp#.T BQ!BrA_F[WAG>9?W\Z i.X^~K*r\T Q,+FOQ13ƃx:K4$kKV) "\ӝs ۿi)vmv\(?kM~^~'$oZ$h/B&ϸ/W 6(!wnA 6gp \eޚ%/zY^~)&'B7=7ǰ eXq!3R-曞`[$A0|Cu򜰑ԙBU6osk$ 5? 0?۵Eqٸm8]$J7/!m(J1^Msp+7=G7 I)1zQ/)mn~Y_t~}x!$23-]MejK4d7%\%3L|$%j [ʖP}-fY)?2 [o(%/:?>y;MJ:L&,c>p\%^mVyy>tO]z`^Mf8KpD|#γ1_@G\yz7�G6Lʷ<'7qӂ%nY3a8Lq˧V+hڸgp,D0rF8+{8|jhm{TByx8Tz2,<N"( f~ʣit'm4#: 坷1@|{]zv~m*ez{ z{^G'ɬv~._|jUނFg y;&祭ʧV />+{x"bʧV 3c}u9('3+ZU/4m<~vAI}Jfx[]O0~ve')b|&});W`@#~TEl+Sx>G4SU ӫ k+C67N0_cvL$]ÒN~vf 3Zً-2SE oRTP>m']&nw6TS~{6| [׬+w=zB1)9RI9RcVn|:\hmܨ6z$䓚�Vd1y1y^ tf33Lv~._]%</=kВN1Krc;|RC<z'%(<_M~Cx%?'u={�>o H~9JKw0/4‘# \ ul@n^4fr ;AG�j' mo8+Rؓacۂ#뙹 |z.Ǜ@ "c(wzZ"ü:i_APd"ɛ} -0y2&P<V[X^ߗapox'=y)n~ ou[^<^P{4x7[V?�;7aElK}`x[(&07A (v?) Ԯ] *v?) :g ('ٙ¢WEI3eӮO)�"[I3;Z[ N} �>k A vqAo?;>K÷\# .^wv.e.VcűymvaF@g1p\lɛP`$yd*fxІ5AquPx0y5No0 yL^v~]& pPxmf7`pceLބn ?3@1`pc;lu~4D?b>�<fVGEÿռ \~]q[`@y 1 (7?< An)c"QGS2%f~K`VC`l&eIÑ!V d4KgM0~#fza@ R*&ӡf2s|6;F!6oAo;Afz/gAM0 &3@zAVxwxͯ&Xz7]VÝbkk9?#ʛst[>_ow~Cބy z& ț'T!oBxt<F#g߶zlHUv w͸06x6<?~X?9 pO6LM͏[>~e-aH+%\w ^ >7lț@ ]\8=3A-ߎA݁l@1]ï$%q]&7_M@ oWp rʿAx^y`7AҠ obpy|Py? F@0<g.!qIM`WpSk`ys *7?=|Ax ;XOa~m禺82tT{^Kӻ_C3ؾ (X^('7 dvߦQ z6ě@d<|"x66Jߐ7a]yÛ�6w~a~m͛<jߴ wy >) a3x7a-WQoxhh <moEz~ś v 6& ~~z!.7gI)^Zڅ@0d&< =&Sp~o>dX&p;70tA&<<YA;T!oBx^>{CބMMX *'~? y7A!o&MT!oBxV@0�CބMɢA&7ț'T!oBx<~?x.@e )?Jb 1"NJ$n%=6ÒoS{TA3fYNnyw̓9n thueb5Yv'z2]!t}N3{Q!l5Xg͎1<r&oum'<8z_on`{W7c&QVqcc&w69? O{ӯ?̯`Ǹ1-?']Qyx~a~ &!;=?O0<j '&x~~z3TFxdRa-ߣR/檡aIR2%f~=*AQ) i&X/?6:MO{eL­g$6z6k^ߗd.L2r㖏_/UI&oB ta(wxK/qy?M/z6<.♼ L<* :`>2<Q^7~qQM zꋫ0)f~=* ڋ8<Cބ `Py M0<&x&7A (7? :`@y Mx8?AowP~g-?b wm˕4S[$v+iw%]硚`Mb[o<yN u|*7k#.;pC~]^  '>ޖڻm7__ܢE^!v)n!trr+;o@УAf&?3]I-SBpSGznkD70y]opc5?.?=+Ώɛm~̠o5o` Lv~]@0<[`pc5?ÿ<fà懆afPy˷t<yO0<Cބ>`˹ͯO@S弝/6a͏[^@of}¶ͅܣ5H eI|V\257?nzne7kGn�GqY䈛6g8vjᖯW'*刻` /pdfYm(*d -_ivb&d&L˛z޲y&ةrb2d'7?nzMhO3yt_/4ΜgNOq㖯WAכߐ7asx<L7asx<L7asx0ܩ!o&дNy67 v|ț) :O\Gs:_Sy<`sy3g_gP<Ys\vSp%͓UO,v0d?;0D&&Sp:X7.4gۭp&V\LX6׵x}+q{ggX.X7 uo:oMZG G `<><AM&0Ǟ'peyPy;Mw#8=B ة~AMWnjv}y yG1A #h~fPyw:o;{7D`0y }@[{Py wx~N1w~ܴMҞ`׏x~Qlt$^~ύ;?-82͕4S}k eI<Fa7KgM0^tz|#Ӎ-M4tM3x~~m^57=;6R>[=0#L97?_˛7aɛ0(7_?Ygާjk&GvoBH)/?0y~NMlvoZx0TNMhxwzNM vzM;mUwMߕ 6^̍"zu]rd;jLMo'nip)GTʽ.r]c&Az&G_K;79TWM` k+&]Ûgkm;X/țNbgu<`Py&A0<jț% +V@0<CބMX_AyÛ@ƃï }MxA&7acNx4U=la~<.M*WҐ7aSA#i aH|p&pOdyő '=JM }M \p6_ߞm*_6A ț6zQx<.7y̛@ T!oBxtdрo`Py7&__xx?` y7Av߉ T1WK['_8\ Bm4`;^Sc xqBϠ&p3vxg821v4,nwh&Ќ <ބ@]<Cބ& A%lițЩ|]Q&ƛ@ x &qPy =Y4<Cބ&i&7 țބ zMx~N"X w- Q`#C a`"v+^2Ky/D%/u4;|8D|Sc-'l3’/Fh#Swph|[<dAg~z_gVү3Az�&on_!6O *By޸Qˏ4wxy~^}uY>0Ln{!<�o @_P];?jy Lnk^;?j5&~=<ט6D!oBxq?MO~:`$$g<魨Mf 3?nқf@@pi#֗s̅ C G^8{82a^AJC5j~a9 Gƙ pɢ6W8]0awAہLc=\/-'AcV LބsLބ0O ol<v&p/ބe/ji?`s{ϼ 7A-0 _2v?&x ^90MhOk\~!o) 4m- yZsǶ_︅!oB}&ӱҫ_7xͩ۱k9,y Ԣ bc"Kiᅨ xmŞ5A7cEWy>w"K G ?R<1y xԻbF"2a,fL!Z[_-XDyqʍL65<=MHn8pW2`< �36 8WҠovؕbNOqrL_=7?n&p+2LL); (&p+22vGCAn|43if7?,TAMW&)mA&'ޡ=?V)qN@oNɏ.Ν^<̰dv@#ΜeIZራІ].]α_>"f ; @apDNr]6t"{t"әȞ+'72&23ˑʞ Kcr#9Qҿ}#!kg㿮鯿럷MMc9f7ͯilɥ o~ M0y2̠i띒M64>5G f f'xe&J'b`/}Rx0S&)}Rxp~wJ~ߋ8<۝'7A ( MК_9}NxMeX^i/ Kd,kN#2;8͏[lO/M}@%OF,xiRlgz2Lބ  �K 蕂X$P,w<qˇX$t ~4i1 ŵ <<F<oɼ<Mjk \5MMw7/ *v7_qryDu?<gtn|E4z ț5- P*7akΣiA&7 țK)z~>]93rguXi} ,^6dپwJdLji>N'J&}r#2_O23'&8Ñ|ҝMs$# 3 A#ؠO NdmqÌ@2eY9/'{|=J.>ms! P] OtJ:ɬFa7L } ݮqI8z_> @tf c&d&S#tf?g67K?_zlA~<j0ټ 4YԵ~~zl6Û@~~__x'跟߉pRL;-Jyz6I!bBKNa.־:q˷y8D̷2wa.֝ktCG2-<\zr wHf\+o I&ozF<\HrdYǠ{X)M2yzGC<h CބD9Bn~=5=:|ț^ %>CބNrT~!oBx0*?7? A&7&țO0`~v|țMx3Co;[v wMbp%͔a~$)"$n%=5Ò+!t3-r+i_7ۍ]G,7؂ j"5I'Ia Qf؍2=,<Df{A'A �N>x<37L۳Cy)3^Hg=YG+~dY>n~]\N G1y0�G1y1y^.y]{s&o;~Е\臖çyGa5@P)o6?w3)f0?tCsyg$<_OtC{`x5^A`0y9^ͯ=?MsNKTROB ,Rp!fagz,/㞷w1=ݓ6-oES=n~qpB`_ՒG=7?n2XӽwnKEI_f<eG g _Z x! x}#7M7 6?{ޒyn}fz',5SEfx S' o"7aGOIk\‘f7üOn~ :o`M<&?uaM03o|Λ@ ,f*?ƛ@_o6<j 6<Cބ&P<f7țm<<g&P<o›@w$Nx~K|o?;;)Lag;fpNLY$v+i[.VvS:}AHRd:7ȏ%r&@>gg/dR)s Yhb/͐2L+_n1|pm^#ooCW}"-;oJx]ZrE#ʑ܌q#9]PyA�\ ;?_w =+Ώɛ *f&p2q&o7?4 3<}r2`o6o`{3ޡa<AfPy;<_#<~Cx (`Py ɯ=?AC N &/Ce |r"Uڧx\j["m,KrG\6tv47?n|s|#P=\W ݻ]k\=Q"٦03gef#=8нKNv#o7?n)]ٳM6y}eK$7?ނyی$`˙놿OI 7!M+{P'u9W_A(owÿ:e&jdDo~ ߐ7 d>!oy|țp,zCބ&4|țPOgu&<7Ak^snv~Nx~K;~]fm޷~K;~`L%6g[3~ zLp <ѫz|yK <Y$v)əfɢ^\oWif ?!I-œW#w0 ߉@u_QVʤH= <G~_Ky.Vi0y'<Y4n<�W׆<<̛n<Iy@IMW䞷*.›hٝ ?<n|E z9@k;dg›r[@ƃ?Mo *7? :`PyiS (nl}"^J*y˽.7d\=qi7>{پwJdLjii3=\"Vrgag>s2o#P=Lln'LGY"8IGNp`׍R`C[mtFf9r{ri#'w>:;ˆ_6wcOolZz\˸ pIfV ^c_&A/qfiy+8]̑N</<&oI&o;q+;in'<'/7Av,0M t,0M17=oxhxPy7 WQo@x' ]<<<#7:q%3]N}N, <9_7 O2<9kw~~\%_k'! -=ôARɛe&p˗ny= źSxDu�Oqy Bt1yVTLܟ'P!oBx0T!oBxt<#CoM *7? :`@y M?MoBc͔K\I3e߆̧φN!x%d"|D] enCt `ʶRs~+,G =w1؂LQ&)$i9n5 9twF&dC-C@9bN{oۥw8Of9RٓJ3h~3ɯgʷ^r]^?W�qP1dM0͏J:iv<j 萸�\W7c&7@|\ sɛί0l>}.深<l.>:X~4Y|\~?Z~:`@yWˏ4jR';-^xs=D'-{oi]Ϫ I"{/|z9k~ծ<]Q^aw|z,uo03WBdqǯ^%ddQ~1fYIߎrD�Gq=/M1^N4cڿl<cZ9͏`6aJ}ft uYZ<dL{.'L.NǛ;x _C6ZL3if͏[G7-?AS{8{Ty?MOa8<Cބ U,T!oBxhxPy MxA&7A;?{eǸ_ ?oo^afNA_%J""[I3,a@gg87m�b.gge&W>V$v)n@~,qgKsN5.m�mًi%n"b/͐Rwr\ej[ ޼ # ;?\˥wz}qgRizeMG x�qd%N:Ē_ ?\~�{W7O0<`sc Lv~ylAoW~R;%?,T?IyLNc9L!oB+pL0<Cބ~i˹ͯw#vWdWz%J~.qms!(>[l,I{8/,t_A~lG -, ӕ"Gta#Kw&p+_.Y{lp.gɮt%Q5Acizٵg= <ӂ%RM p8"#q k/W2y\&oM�M`pD1;R P<NC g<snoi_ur)yy)n~_QA\[̸'#Û@N񗻂 )MM 9@0S0x›EN? |M;_>Mބ]jdSCބ-M"zO}eځ@г]gg[6+A0 ;)b4SQ$4'sh)꿻<M35j^|4Cۥ]31t8سw-ʐ~k]~2\Wwnk<ˌXyrL?;<m݁lt[;iì$\1].7_AGf68:(6՞O< 9퀸3?9O:?AoM�6v^q Co7MWq*2 }<7<lqPywoBy=:?,Tƛbo<f;ΏțПx'T!oBz')<Ώ^4? BCa=I3,Ώ )it#(p,KXM?L&0 `[ui05#kG ^w`0&,rs#5+-Mp=8Fznt(;wd2Ctuz)ǚL&oM0; ~/xB;μNitf_M8M wN.NOuȏ@~_Ǹv|&sxA׏Z~-�ρCL׏Z~l~�}J}v'Qo&^yx\S ;q2S^FZo~qubzɺ3 XYO_/<Ygҕ&:H;`}'`gh.XuP^&6L7dT֐[ 'g3L?8tY]@+z[ Xt*+cM/畏z6 \yy}=<=7Mjnz2窽? ?X/AR�Vyţʛ?&_ATX}*o3@q$9Vl_ y67a �(&l oz4m<<bțg8;Q<udDU,|^??Upy}e܄M44A Z"ȲH¶"" 2֠,KБ!l4hXILSS3= e9TUWԩ6n'Qv6nBm+Okj[WV۸tV6jdn{ղa}V7$b& 9ZAoZqə#5'JgM\c7$ggW3gtkD\ rsk:A~ne_̵JDy_?Ze'VԦ͚5Ο7HqDY_Z[ V?5kך5k?Z#Y]F5W݄ &\nj@PڬqY<sf`Vk7AwP_5@Uj%^CYo9j?tx!ܠv6nkƴwr܂OPN~& ˆkoUD�䚼jخZؙ/^ pJfM^gYӧfZ[m/z/j XjXfALmc?U o^=} 5*/#'h5Nտs5NaױVU'j2_pmU[ԅ7ni jjVvt%e\ &vVߪ 2`iH)lZQ`7a)n~&\ 2w�݄U̍j?1BE7n 5ߨv c7ܨv c7xRjZ٨8`5?7^'UJް~Y8Kؑ*T-uk֞kM]5KbJH-\"Fj+ZZY^}?{mȭgZX5gw\%5}-(Vmd4Yc$]#n x]ܪk֬(<6ט5JFЙ5~UH[~Mk,kGGSӋ#njn,Z߫Ѯ@h7a@oZ^kP}Ru_|Z߫_?Op<_'v6?Opk{o^VoL;݄ c nT;݄$F_O7~ZxNjVpFv=KlluLkRc/{͋T}Kmnod$h-\K^׌tk,jf8^G">*:76rk-֕r=1rkV]O�Ip3#c6 8{眍ckg_5j@`ZqG-<X݄&ԚntCm9k0M-fm6\cVje7hF;cvje7A`k~0`cWknb7ܨv M]}nµP@v6n;ƴMX{Wk7ANH]cKZϾ\.VGY5DqĆE\Tں7jP#ǔ,xU,�G! Ud?\޺$GuJír7о@1\4M3p[ל<kmZ߫Q:Ц\qgA0庀 0 o]s|"7Zkkwʼ #2xo]{>xٵڱR[:mm]5*x5ʼX P|[psdq '~ZXk l쵁7W< '[B4k2rlUںXknBm Z; Avb$nv<?$Jѣb� \ߠv=U:b%..BF`XZoVt o~Am?b41YZ4,H: Xɳ|DGT@(;oZ~prt+lG[ L`<.Oh=rM!3c;F;ohij 1>Mؓlb"qF0; 0La"HfY5v[q; 3 Q{嵎?nB+m? x%oW7/^\t'v{얡$tLJ7܎l9VԼha [{o9>nm�pxX5-�qS5Uh*Gf, MjlH˟iWV\? vpP Un9ζlh9ڒI̥SEfUV;Qk8x-l�A:6$|#[^6щ`lh*ھ3JYo?r.jg5*]]iJΡ]?w= xohw/FgkX] ͐?AX ]#YLjf#x"al&A~3iZq8O%Kki3HkZX \GWIQ_/ o=@xC[ak=m2<L;R5 <5tͤl? 8=sst8g\-�A~z4q�ܟxFh"皍6#Z[ %\?sƈfi9؊ if7Z-NtbPߐ:Jm//5> bRS:<z+ޓ`N>܃ņO wGG^<1O<r'O|=JH'%;G|Huʍj}g7*WWt:xj=A@k @P�$\v;]_,@MCށR�y|) (�A@""$ƢDl m׀nd $A@ @@( 4$$xw $WMM @ew Ew\@t})h6(OP xz"KXt%l6@`<A@ |) (r F�8  $A@"�A@"�A@"�A@BVp   @ t8 � HUĀDXxD z( 4$$N @P�D$*b@"h, H`<A@"��� 9<XNX,8� H H H HUĀDXxD ,'l, $ (X HD�D�DPE HE8 'H    TAcQ@"h6H H $H H HUĀl, @8 �A]0N7$HI&ށ Ё#;_}!“B\I+H{jLIYɒ%qM?Nl'Go h9^WpwK@pt< 8E^M6%R4(!@`E-Rx]Ah-;�ЍcG #є7%d JA(+_2C1t܁a7W퇷W*-t8Ep�ߔq7|]% 0cN &8&H:BdMl7.)tAJ=#sN~1M4w{mOg<kQzb Op!RequE]%A5$/J%pL%p7x8.Nұ [?DU&LJ&rM�pAr3E ; H1g_&>O|x H_4SIZi O=%bɆ'h/^v8uMHQX@>eTL¿[3< ~ZIWn1Xޯn!d}Q!b1U0mq#F]WBrHǗx\ggp*)QBhf/OARUA583K|e:yL| OM.i)'eqNϿ8фxC|=d._~~8CA^u:E? H:qxjk:I1PqH$S Bw_w ?{y:^l/9G`+'(,$C\ůOBR !~D~% ($n@°9&أ wmM9f)*RtυԫnaA#c""K6"cl"Ɓ5x7 Q0bm,`{:%F9^AB޷鮦c=Ł!Q(8PQR1:ûi@~QRy�"Nrh``sr?Cjb'D҅@ԪAO�v`' o~t.\/o�"O@)r-Z!--N$jZ$[ak={Ao8xJ<H#q'tf�A7z|WbHI%B1pr' a$@/&Ҏn\" VVw@$¾v:oB@(> rmK_/=`rDJ!<`߶Qx~Tۤ{P.3U'Ph*6ڶuaC@.G?[O׍# _LXLʅR]}P $:A NP\ @ g$v(֋ER8` O "Td\bq`ciMߦJ)+�R)6(99FVysS@ˁ!$.E(nK,ʟ-rbMu-[<`:X q4S9.+~;\8$QTd2**bEBQ|i]VR.G]�A!H v=Yu$V[6yW "_w5_L̩H6Axsb)2 `Bgvxw|> vp bs? \O=X�H`iŰz|¹�jR/lSH$UQGAK6tDa-ȫl{BIp+I�) 6öL'Fਛ^@dSRa?k3Dj�BVnH'(-píb;UDf#ݭȱBi[md-A[7XygXl-68Ʀ&#Q\k2~0z` $}+om $ \m+ۨjAi햻APށ\(sׁ�ߏbRIp܁H,J{-IVUw )W l ^\%F+{cz{m(4D2`aaqãM+dm�bxcjFx^X)ͻ xXt|ɵ ؿ9&'"_Vׂ" eׂr:zhȧZWU["_�«.A9W\H`Y�)_>'W+gN;Ibu+]G B&B<$B|E{B^77Nb ̤MG"RI@^Gi]CbRE&[<`bsJ2ˀ{% 0ʆ 0MURl`_Ӎfh(yҌ*&5fT VѧQ%!X9(nБ< + g=l,klY3o3un7o^"L醰9Pmjtv>|pA</^tA`` @0W.H^gI�a P!~>I}-XYE$OՔIKС]-yXFlhaMmĭU(p}XI|=FaƢ#PҲpiEȌ {W3Ƃ3*{EbD#V:u>t썽}1GaYV\ x"kQܲzbʆ OD5W @tA0X^vYXTy2s&~AE8ĖQjV6)mUM(R"G,SYHv)5@6g(dxV<Zh1>B _Mn8^@Ueˆ MaΈ~~1ĔŬф '14@2SA H&-fu[ 8ѭ^GY6bbinۆV99b.$BN8/^(Asѭxoʿ1Jv�@{ ܊QQ!La(|~I P&~$ 0+Ep]]VH A=遀 m \lF1uR$LSÄ )PSZPL! &Dӊp,ځ~ 6*8c!ظ ІTKr1IsޅDm b9n' #'HܲE%)$%A…Dv`S;C 0)؆ "�R^r2tfuh@L>&`Vh[/Nە\oډmek aۚU"g脋+S15v*DïO(-Fߋz-"ZZOX49+'T HX)x m7'A#́6+^QW*  &*V^WY u7;4Q)FYIR;iT֛T@8$/^"h0cc{~EE! 8'~3,.-"iC$Xe>8)>-\zX z3kwp^0g\tiYa1;ߍrI:ϡ8^2^ 9zo[Gؓ<>!9 n<%߹9AI) t\)0DR Vi-Ė$*'_puQPsA +A`@#rA ͦ ɏu0'\Ia* Pב삠kHs% q( zbO�HqFZ W-ay$H<G}~q\bұ.κP X JQBC?|?%u}5ܷzO1tBml@kdd޲m+~Q'<11NhJtp[^٫JUR@C".^ {tߦm;Poc|́x""z!i0,&44^JtY Ho@+zS#0^Da&C#Ntn3.6) \iB936 strlj^`qo? o qxrZl;@KAfV2] _I' ;$qUt%&${ -!"5A* Ő ?(�[ w)< %_qs #$(*? )v.a,�'0sz`1:밨ewŸ xY�I#V's$ 20ih2ob#{x h`z o̲AGX6%A{1N]dz%Iwf<$+/v:t _:͢$ 0m \qs@\[Rb6](uN` ?.qG B iOn^NDdrӂܰ8dP_#󍨴 ua1 ~J&�%  t}G|3= (ffqWt##kjAȚޗ .Vztl=rU`L!n6%b9Yb.|u!#T]$OD; n?I('.#3!K4'knh@Zói_ VoT x)fWw<j^XC(Who|j%ݭ]}kDI]1t}iAz1_P^\CX*Y~Ek9aYk!_73Mvh- EE7+__>_ھaAtV'+ +Q�Aj)CD}i"pG e{MWTK*M<ˑP,6^pߑl3pq(ʼ{=_rߋg^NC/}O6t XS$~B๮XEe~HuЍDhTLUZ"݆0+E:_3TɅVorryvR#*=?D/'/ظ)VT^7B%"2p}Q&Ѝ":/Ń.'g^SA5j&~mZpgZy $82- 1f1Mg\ƉƔ� ^fus _LD34a|Z%:[Ņ {lru'+dZsno7w=g>-SQcOyGzAa/>ܷWw7JVYSTl&?<0[`zbL7!Xc"Dֹp4e�l>a 2AviIҐ'KT.F+>QoշWP0nҝY ˈ,{B 3f[[L3iБ ]IpE朗M0 䱝DDW[ð>�Fya�]J 玐Mc"SۡZlfLml"A�&Mųk{+9gMPH–5%] [S4*SvjhrpG ?.{-Edf͸0�C-Lf[N|pP46tu o btM y|G 7.*P;!F+G w4:;*Jxl[ltݐ���IDAT->I}x:|SqA=`"މf439n㜧q|r)@h qw%~o3y@؂[+Ǩ>h{G4BO?Fq9SR_E0 ۨ;6$"> eTUQjPRVRO) u:_ m�k$VCf5!=I1}I$]K-&j?+mS8~X�-ȷ^+D $ܐ a|[@�Tq{O%p< VU|@ K]} 1�S*pN2@ADGZ�|I \CF|S4rl+)XIGZ xd? i�\&7W1?>W<N*Ke [VAksi O˸ Ы`%| 0EYPߺ+ AEJA[)m6pqסQnM\$iLN[@#!c >!{8(B!i{IuK%!(\HŰ&JK`S'6K2qh$Aph6Dmc `Lx+Y�b 4i9HQ�c- A"N\D C80V5s˱`V [&$�0SV, aw/WM qwb@C#οh*"s+�[=tT|Lxu=yrII@ ꒀT4xn);�/tM1#AB *"T;-k[CC±>�GQMIoe I߽I ~r4K�NPd{A?�m/)`>E0T$%SiX.9 }^lBYz kЋ$�"rqEEvBdf }ۏPEK*Tx x�K$AH'm N qtf@Y0lX5vA}'rM46Zlo,|qn+3i>iL::MB֫ 6Jhսd18^럆;kH[!^5I&;oc ?lA:gFT#KTG, :G !P#GZqK-r<E#xwJ:NP(}+@`I-2kTB6F ǍWxݺ|Y[^Pleefe:RjjDv 9B^r;Kz?UWѳ&](Z <HVb@ D6~{^B(N\͛mUݫD %aj\}gWeU({٣ݷ_ qP|(t#pVtc-Gͥ\Wp_TOQZ-ī$8]4T+|.^mVr%bTZ rnQ,÷A%L ,JRZ6 Wa+~z~TX8('Xx6M42"I39w>\ jy/8צ9qiqP!"FgI&nK5`5S\t܉UF-2(gQo(WV>W#YLk0G}O*.G]]6Mq)J4{L?6 #LÒ y$|%&;?:F,ZNK^YF;3Důl[Lk7ʝ[⺴ȋ�A`:!9QzL& �8}Sδuqʹۛ]]'7$ɶC<8ֻ63}WLVSf>a+_\<Iaqz2,sl$!^GbxM./wSo;9#lW(N3Ex:A^l[ltK$+$<hl% O`^?l7Bì9u"APv0HmaH0} 8Bͤ NgE댵dDžz,]Xl+TޱӤnQ] +;fq�U1f)j?(�[ i�k4]}pz͟R j<vHbKy6We4Y }B8g(fSg|ۄ8,%%sD/cRa+V D$Cx *�Q!P!ĽM( Q�d T]m>I}IS $;3ψˀ`�@`B͐g\`CiK @?8s$Mʘ\-8&[Ahi f9%9g wb J n&Dwl::pd2;Ty$hB&-(#m mZ¡>Fp~']�qdZNC]ЪuU8t@`@0B=Ul &,K4~7t $&@PO0iY/5R1vN@lI ϜAɟ&(JbS%[ixr@0\�9|ҡs,�1KM{)Z|Ɔ(-F'ihE$TCS�AO9&8Jvg%#` x@r}ɸ8?_~kLWMQrʢ AC23Q�Ai{3oN_'E9H>N(y*Nwzir@@6 p̭h&90@ڀg8t!5�<c*Q W14 u[oٿζߎ 511KCNѭQr!AvoA|l$p)0zxe+w<Eq= k$n�(oH\m:1N@P$0^b3?hX s쿞r*Q1qAE+ 6Q. &NFd p< A x'A /*4�IbMox3lx6@ݤQ6I4!AMMЕ~h @ '\"O�&$8/λ 8KE-#%A%kH 5 b@(95VU)Ҋ]`_cQa[0A/GQ:tWl:³dܭixMyE/En JԵDf o&gdcH#T9⪩#Zڪ,A[�[?VZI~PiS hƑ/E8j?I28Iߊ `'*; ]/R,c&J$u2hǩOa|JOsZOa"Hzbk"Z\kzt Ihir-_X|{ʶJh-7УEPyP wRE'h vZHNc?2ox#XJit%p.5-u5$Oz_⦶^XuT*ߨY jrGnUj] W_i_oT}l6>gWC{dT[uL4w>2GnO䮗A^Xi�GM'@P[uL4v GVG?Ҋ`} EU*XX[#n^/XL #wAy ILQ'X?IP?}?2Q϶ҙ;Vu o*$WJkvo%:-׵#E2i@&6Nվ*XX[HpZZJO  t QY-nw}or36 neerZܿo*,ojo{/uj.[ FZ_}4R=(pFyw+O^_;9:nKc5ҍ^%hWpPȽ#ޠޠ\9r2GhX4̋ѕGECqFd˱[ N>:(rW3Ud[ <3͒XIh2+K3mK0* A`}j VAܗZh2nmo{,� e嵃Gnh]Dk"M26m"aGǭ bOؿuנ88ms֫8h=^gb6HkHHe.v%AVPL8_f0@@]ֳţk^>B/^/NK xT"l ��$;}Ob<$h`.TP{dK�!^"c>[?c 57yhtjP+k 9o WC5Z1~& jRIr~I0#>%v _ F2IY1_}---ֺn hh`.xW'(y߯$V⊫HUhM` O` "&|Hx_Z8|yg<%6LWn~K O\W[q1 侸d gXlկQ#N^�U z7|2/p-4˖U#ڄﯯFz}F >*+'ʹc9VkZ� 0ߐmW.*1/k;s\vx %Eqb 5<\US?h5]߽ dw!qr]8*{< յ"91E.{)/l Q_{8EY;qE;_ -px8n\ t0HMyB;F]\?GsdgȈE�.<.]LlXdyE>]|A]k�A3YJ9QC4>ǜNT �� ϟ?;E5F=y 6/C&ɬ\%S{t^}.V:ZB3RX%/v2݂<7Ig\ەn.c;m(D4'}.~Eoj ]vpr&מRx@؋Ł'! (s$ AeZf%^${]Ĕ/W5` h$МvEYl̃,byg軏-"B.A_}>2 h2c#•yS&p3d4{( 7a{(>w}|$ #RA 臰_UҪA7Dda>q6:]"c콢C6p+' 8Hy^`ʵ[䃔{'\bt<#[Ȗׄ>HA�'{RI�xs%E�$HohƁZF|.'oٖwj(/ H-O�lͨn�/Ł R<  fIqn( GDD 7lAN':V;t<#IlE5푖?EI$G )WM#*~COk2FR]*ϫl}@]R8Ɓ�.t#< W(5\A0x (O�V@H<0Vrn%k+phyb5ѫ3~I89 +jS C$ 33vV^'􌘎r(ݎ J"c�'@`Cc`jAP24l1LqߡՋ F~NSW¢bUD\%]|` .}b1D 䛥9wTЁSt +L{'�  \Z8 ntM@zQzme}4 q6 V?G!XV s.(I7^'no˓ZJg]T=ZRrq&h%~V9/I95U>[yב&+|*U [%c1'b~lw+rXo}>GtsT XqWMO;0*uB0aqHF-Jߓo7VQ& d2ZIZ ۲Q>@ZY؋b܌XrM\;P}MvY/?Hiq@�A Ol ˻[|m\f||}k ϧCӡL %/6,6zIZڀ�[)&iE&8'L/Ak%{9qY;1)'NRmnrAh )AďWAb xct duyw \RBj!�`31?G5̻y7π8M;֫P<xia,Wr]ҊӲE?Nc2 N -Fru *vez @@G $/_FxZx[A^6DhPns"J�y?md\@ /c'OJlLW(b"A@%AJ&-%]$; GI zz7?UDO๢]\A�EIZH<Vʉ"{�K7AiFQҒ9/`Ձ8YIZ..bt1*5Y8 +@ T`"$+DU?ƃ' &EcIW q{HKt]<W�ui{.(8&S>$JA rb1ǧJox6\鹐vB{A!#b( a}pdq�`N9HRdf1$sI\e"Lov/^'{ Ap#2%:A+_e.KI6yD@ H+''& V@$X,7\�B 8UP A,_@` S'@(OLDxA+S/>@]r~-�@#0Q|w').[jNI|_}^ x9 F ]H*EIPKAC .$B,R2<Ű2J"*4O,?Qo<WE" qKj �&쨿Ǩ0zGvH\ꇅb;)E`Xף M(V4±MaF)GD:JT\`pl)>$p/UQrUx�fcA9  OX82Vvd_;A%0%*zz!w|MaެU p\>ƢjϯFtW{RE@2 g>/zidA[+U@ F77> v vfp3Ս~k ' ۫⚁` v￾6re+_KF JfR{xkj3WvgDATCqfkթ_вo.c^�q1(؆pLbbB\x5݋kP{ave2v&l;rU>aft}NL*EIQkowHPGshctrHGspqH΃ʐw{FIOC~T́92Jq/>v6=IXAV]ⸯ^|`Ӌo_zR{i܊ N׼k)L0H:v{"9&!ŧ_NGax_U]`2OY٘2轩dlR+q?99ʉ~AQLJ�$@EZ+I( [?(=^  K:u%oL�B2 ?1jiԋP{`P;SLWxw=<[Rs[fG1iLt!Ή `y?#G:L$`f z]�$ȇK NBu%?8DQtbAr\:]3�7>1ӕ-6<dnrTWᡕtP8%c:< G(Aii H3p.'`N� {< ^$9nQNV;<�.xMBG�}f_]\鞋}ڽ%p-s�w;]hF>?xYz�r˜e(�Dd)iٻ2@R,B>�wgD>FC;! 7�iA<$ hYv*d:@pA(T}L/L@`#3,�XAj _| 4M9�m㜻nMQ .I�Awwejdh@+ i�y_4#A4zaY,A cx- %[؏seBMrA=\VoL4^w1w>ѱ(^Ob$Eq-dn;AL+5vp Iٮr<ʂ@PPը݆MY @"OR'N$qQ" A0� "^qp901�:G`/E쭻ߝy\D^.dǖ]nWY[�Et)(ߙ}ZVvn|/ p${b.]�A0Dq"#b4W>D@0I )zZɭJ! "Sb@k%O1QQ^ǩ=)A%x�P$;RVJ'sL2 @|8^d"[d6Ex{޻ ۧ}4N8_=|&&KJH,{ww />(va:N{#�d7ɦnN.W(X՟}Z \R3l@�d2^BA! PiFŁcn?A}(Ie^T)m0SP% xAP/Ad t[X0'߾br1t/BЍҽa3 `L=|]ӝӝɟ}80ϒ}/})McZ xk; ,j/ޝS^O@޿5Ҟ}طb(3e X_!A1IE$ BH|@�9v+-@r|у-A\-Zԁ"\dW:��wY6"R'Ljc Hy|zk X)$ttMKw4z}QuJ$M% R<C_.'Hi<�u3iXEB*N@{$(|ӡI142߀!u"w%caUDC@J~$�yȽ^Pr( �S `Fn/+'E6484Ƀ &6bov$(534,sy4`DPPtnnL9FɲO_> nmLHx:x_!g3"-Ar!RCCPŤGL{ yHL:BN H *}9.vxH2 )ǎ h=@xWkف$o 'tQ{6OPn%kKUAït#PU:I*^QȖN~,!K㵓x= W՛T^&\'_r!CBUJ9UNAxM ~xD \HpҼt pF4RBMVe1=4J$,!b ~> .Q∅9qR|yslF%BdЯyTK@0@0;;M-Kg�U& o~WIpc&.ݯRMd.3fн!~K2?!ViM9)!za;A �ǀψ?g4pg ͊w)AÂ;oqrt'`זHT8#+�sE�m-G^V�2 d{Vf,j~G $沌~'4HI=4A"\`95-ALߡjFQ P'ie~jtܹKwDHK%(I4#%)WҤ,p+JA/$^Њ`k�N&k̸D!*~@!mZjA`@ HNw-E5 AMxR gˌKB"|x2/RY?#4?<pH/Ct!C &=?w$MM�=Lh4SOe=O$H'HSd%(W# #$IYR$걷$P tExo%B/|S.,4xP!8SMfijJ 8$~�xK3' <iw!@-0N sW&$ Apd?t/]+iᔴ8IT8Ad.Ը C2<*+<+_,_]]zғkcAR%NDO?P,\OOA!K%Rgŋ$vu`JI,ݛ A[)0Eo), K\שC/H@V*i<k Cuwk%x4PbEI }x2Ti$*6uiU@u)RSr;5H.6݈O@-'~D9N&A�w] ( x] {z NR%s2!)̤8>=@]p=�A8(H'XzoWw7�dz/'O"98ΑZ1j!óe &z b ȐNZ 5w⋄j \�~IRYIk>Kd/ո *(% 8A?@_,qrx %t(_//A8~L@)H*䫕WOҤĻT# 0L KR�ob"}.H9RT'@WX,x H\ Шln )ƨ8R$[=H'ɓIc>8Az>&[G4.u߆o s^s% @.Kk +XXXVRȅ<.or T:i0w~Gophpwփ/8DZB@r}T8חV6q6\U=*Sؒo/+7'u %wH>KK% (% ZH`:z65+Yeb�lwo/Tqr/u_]$<ë4']bKɩxYHJabΓ6uzv9+_oȐJugx.Amߐ ZšU<W`#ή%UʵpF|I- 8 �qv-K%\.APgגXnZéW8[HKGjV#+~/V;ru#Ϯ%t~vƊ4"Tt&ChH8ҔlO&I/l@V0,~l,j*$kcN-"4nTS2/< 0 ST`J`)nȳkIGs;\&!$(a< Ax'\ Mƥ$y֟|v;M`TA _qܠv6.J~LW�;{ l=$z2tU_SG mɆk+ @N 8A5HÑvA構 x@ {څ7APsA(@BLB'_t$2ف<PG;@_#A援xg[+mΎ*P?ZxpF+r<-GoYKlUqVZ)]/Oaʡa^.I`T4BJ& %ie]<ϧ| }X)<Z@ '(Cۗ=6l_!mpV$9v}[}g5~hrV?)8atA8Ȱ?1W/rs9:J@0V( tҐ'XBA\>Iв@KϮ%u+qg cNJU=@끭h-tr`i9"D @S7qD@(+t_q0@ H,QE``9߿y鵃T$׮%ɜo}xÛ;[�V}}a$4*N׊^HƁ b8@cE A0P�AA`SUZJ:/@pVlx<և[�r&*7{%x)V?LE#4#&.ҠXhm,gutA[ FZI * B X£xx 0l=I@beeK ^rfbi<nzU_&C`;+kA%אV?)OP- X8L–^?ɯ _Qh\) 9vm--˺UKks=z(5_Q*hNc*\M{7W`&)%_iz޿z?T̒fJαy 8~xGNFW%y_kCp8Ju,NpX4 ~W,p諴%u7Q-*ptƻQ.le1-_7.;cWW<ʒ52&wpP!RKˀq|A_OrO&LhK.!Ky-(ev+(R;qGsttǝ2+MiS#<$.-Pd$MQ G0oJU/&MHܹqi1}2a (Fg]v_\?/>9|碫m,|;yg{u@8E+ AIqTb+jḴ E f2!TCP� $p弖� Em~q׺_te>v4{N\}KA`[x�J[ل2tک}T/oq2S�AUKDz_gY+ نW _qrۮЪsQt[n+lR*WcVBЈ_'  2 Ipye%qZq\r⮇P[*(v TO[ak=/O?$~C Y˯j!~Mlwym@ ^6L0pʳhөW'n9J X + ^q#@gMd/X{dr|]T.Vd/c%GXZ!Nsp {ƅF\ 4 ]@ E̞?79ڗ\Y V|UIG t,xgd|IW'(A YT<@wP!۫d?KKF}}-C.#n{QaBQr3$&ض"W=g$D@ IUGٟnWҭ( `i V1Y`cvWl>x{̪z^$i_` @  9 Zmжeo 46 M+MRs+UKotm_W     d>TqI@, @ > |) (P AcQ@"h6H $Hlj r!\WozMZf\@% kk76mshF=mWyyWo|"r~\k`ڰ{;;\#j Nq6\ͯ8dSw;d~"/$> Yc47rWtZEK.E (JS!Di9+MI^�A�P|^du�v30h2 F(N~)xvW:]w͸zT S@~֮@O:K๻xxAC)4x>h.tйpݛ%c=>:~E) ^"ψŷ^q:hM  мh4 :N~]<cc8RFAhu<uCOO�rPN �1w|?AzhvdI' (/<'?)~$�ɤw).P'z� P�hn t}]A ln|AS@ %W i j^&C (ÅJp~Kj l:BC:BSTGhcF p�'[KA!:-#wPB|�:>A9upRK S |� PX8p W+xCطmbtv{BAF%<oK;�(&e9k-w@ʷOK$@]I tZb]W !N%^6 byp- y. [Aiі\Oa.7r?Uo]Ξ-K+TWK|AP&I[/`!al-ќX|}Q1E}V ɴ;Ͱmwp N$}pgI1Lbxb%:H9x (m,B]`v,HA)D(4A^9sCeU@o6Z)>`fض;xJbqߠL_q73LW(>p}{1@*s;Op 6$^')> CX&v{խ 3  @P�D�"|~`Z@ @p;ށR  @P�D�DXxD A1 4$$$@$$$$dcQ�8t $A@ @@K⽟M M;]_ VH @D@חp<D@חPM xz"KbPPE H h,SlP` @$$$$xz"KA;A@;]_B�>H  !ASlP0 @$$$$xH H '8u%/!ڮw (�A@x8  $A@"�A@"�A@"�A@"OxOD@חIP�0  !NAq@xI I˫�7(Ŕ"+#V<_ܠtt{֍ @pEZ7Vzd)M8ZvExD~x#T$qB ?Rpc% zrSn*!8]K#\wz?zGЖeߛ X&:S%k"t` tL^"Cw@4`}Z@@p sC8zVZ2N\Io`zh(M@@mm N 0!KһfJNHLAz`�t}K@ vx-+$ ir~$xQ@Z(A.l/�G$!MaR}W'Xfv J  $A@TEPbe@ @ ihp  �>A@"OxD >A`N2] H AR@"�A@"�A@"�A@"OxD }D0)  X4 H|)/ (�A@Aq@"O$A@b1�a1CdږY|4�ulM?z{\ 5·rRN,�B[D1,!:DpbEE<)܁lMI2G| ^39,E1-Ľ \̈ƉŽE'%.@B7,&N7 ]HCu<e8�A]|pUVJ|V[ Iވ �4.?Nipy::Hv$"7*F%.��s")Ί.o &-;�q@6�?`�\,q%`JKE^LDG� 記nbTLd;׽(D:):e`JF3�KɡƢ$x!�: @Za H`\HI+ВH@�HS+щ x%:0#Dc�E;T yt#}Acw I11D};ly]3�:`& `G�n&(|IH�<58G�;uKkӍC>7@u10 e :<5LGg(�@HP!mP20Hwx@'JZ\ᐁM\<)~�HCR"H|1 ?( ȣKACe.t9 E(Q,^f \h&K\'-K"]PA@AM$5m@@'< I0I H Ѕn] a!q`ˁZɭ lc= ɝG Ig A%AnA]b"45P֣-Zɭ 7^ y�`=A`@B[qRp@ 8"d;�{?GQ]fNݿjP#${squts(FQ8D[E_ @%Nɞ"I)L�P p&] vpփ--[b[-?OFcX#AC 9 EQ#T2[vx;[ ס,{ X~*GCbHJn2H~*"6 [t=n*IaF6`nCST>Wį *)%N!(b;AQt aI#erU& :6HgXp#jV7>PH_^ P}N;Ưb"J2f+p]l|CRd.Tg3x<%ݮ䨰�Au`!yT^ yeCUD^cilٶ2\D_Ӷ^ct$.Йzn3YGm_Dև;fEXضc*yްDh~He 8m2,SY̲pްǹ,OryT0p=Ԛo[i[:wuuu'xV؝9bf_Tۿ3:|bFNdg _\vsuVy8 yCD-,4ˁwBh)5Fapq>1TΘ+VTױ |3S HDTqhL=h }Plˋ阶qVE8cJ޶q59"ޗpl"ZL*4γ9<YgUr+r3 gǭ,<!vhtLe�tNV$G,hVhgLCi [D3,Ke(Yx:dE-"*տ !)LCcYmbas,-cJTOڼ "$9׭x"Bt&bWsgT`%<St-m "],<8Qf)Ds|�Aê֠3)<U122@ `ȵ>\VǙv^Y6=PT(λFf]VFQηeOqYSdj+rvd,KLDM0L hsA | hrc $55pgMUm=5mz%;S5fV?`nȼ1vŔ=<}Yɲ 9{j0ßV,l!MH5OA9BO 0ctXjY1%VL{NRS<c �;9 <g"zkóyѭ/!fxr@|Qy.+rWlٻ.rYYu%wn^JlrٴlY}汸Clө>oK`nMߑIS]ipʄ.AD/ _r.s2)13ʛ{>+Κ=T;2'md L-!Y^wW2|NR3B4+":1 χ.RZ8`"�F|sC(}G7&kHSo!exԁ$hW;GCnj lbt8J77͊VyzH&-e C"aR1{(t2S-{Ȳ!=y4 j a\I Za{ah'UF Y>>s ꔞYc6gu H ( iXO{SS;bѷɛQ <X;.B`PqW Ag Ǜ�e{JdnRSJڀF{ bjw.Df S\2Pe8Ԙnhv}jֳ|(7eerI@v9ip 8֞Dw@jHg}PMF<gԋґgh<GR֎1~Z&3 'kDLs6hxuJzMBD c2xV6n&x*lY7CKܜR~AF~ݴx'&MFŽ e2Wfr]YZHc=;3IvUE-<>Ȑ{/zQɠT'\w  1QM&ȌhޮiORWw^+|Yb)'̑TmuQT]oy4HkXszv<ųTGƒ /uiF2Wz-wNԯ7M⩎LTVzH� 񄰏ۣe oϔ2 qv9+gfg4l;ןNSl R1Oy�hm,bP ](t;e5a/>N^=( $V߱X|xry_=e$ }C×A1|p׎]C? C�̉Pou$h/!X*ta=o0D;r f՟Bg1bd>CӼ_y (^go7oCCC˪"5now,=:4c[UIr6h_VgשEXVO~fs4V${cxgLKw3$9[�5@5Իdj 7>e$  %J@[ʿS42RLFXTXTc|OFJ35MB�Da373�]uPDw1d|Ğ&G(njc25- uhNP@�%=N�6nBm�i{zTwoulړu{z^t:f"S=wcK$ !WwДXhJ|CV1Na5aFC_@N[cv֗,D}97BLhadq x"o5W= Zwo= 2v7An}sPP" = J3&i/)cYsVfCd|cMe~^S1SeΙzs8>gz.f&ߝ_͟ˤoT}湬jG"LK>Nq!=,D߽PdDND;p~rLd`]>nn}E�Q%b͋wAKcP0 0./+Ďݙ5CR͠d{Ǻw= wCcKyԮq3/ƙTʲvS{w^�$LԱV3=a%%4ZǢ2s+f+YytZ1g{lj�\PMRbͶ"Jh 9gC.(ȒLs,>5BnWv%p[@5ִ/U+=z{"y:dy{5>S|cgGm=O;zHTX;0M! iӡze l֐G@Xh#G>Tz8O)nN=аS^eQ'DJLB'V&P{~~@`Fl{^ g<A,Mt=oM|ٓ1#!�ArQ$Mjƾ:Cq m6t(ou/.dxcj#_Tq~4|8j3!ueXOSȌe < ihj~͛\~ l%9fdsDNy`vCDɾNn3lT蟘g=l.w g)i> *-h5};#1gH�8%u~ :3[cƮF?Ju(dSMc:dm;yx{lG@)f:td }nj;LVS ؗ7KO-"6o<K컏hY5oxO7Z»vޤζ֯~@kjױ=:3DP uZ@<odAav�$B5s _Szny�wuݻLnMd3) ~'4J6:|wH5{Jm>Ql(۔sڱ2;anQ wc'mGmܼ7B4jZHBI>4iwnrz*dC*JgorB1;j_$?Ka(! u;' A'W;|QC"ն[VFj9zd1ɑe HnT1j?t$d^ 4xd*G;zOmeމfe uמtx^ccPz,"aMUvC,zdF,Hz#VN-2�SMC'v@'P HL9ǬtʋXMR3f~lzvI}Z(t=$X&04<&x2ӑw9gٶestLP,φXsG͏>o/ sRyQSIk�]Χ;kb C-HGd$hj؉XX| j񚮿;ad3HȋEPÿ-4 |1vЇ'u ԾR> *X*z"/4S;Q` Xh>i+߿ H'ҁ꿥_~k-&^P]-@\1.[v\;0|TX"ꨌMql �wm%~׎(ӧ3}cP/M$x9n5nj"dNph۠Uj4IEk:LhvOY_ZNذ|2~i繝?;coCׁjao܈=?mW@4B5R'pD6D PrGyLdnw9sqk&BNc?}l�$TNeD7XYշL &b;S;<35+hɋSOh)}ϟbT>W 5g3?cSL:r^׍漰E$ۛCNco'˧xvgGDl.mW^2>ۛ]lAcLhNM9 x[i;yQ"}s$OڂnET;Acaw~8'9VAqIcA\D]W)Kݙs( 1�Ϙ/H"UƮle?c)OYǎwi/{7X1nl{E1"yX7z3G3Y?t{ϘCjlkQ`$Z=4α9?ܶךS[{%9v@|@#rn;MN ޽ f^lH@ 6/@ezx~;= ZcxsgvBd$DٕI02-D;=ǚ"<bJݬ;v@I<ǎGX3D埠jw[%ӊZyq4bimqn4SfQ>"vb8Y=9H|RO}=}na)�7hm?c}[Mx1оbE.tX\_SQu74-Ғ-_JH_2zytJ}8ϱs7}kwyȼ ϰ#wkwKc=)cQ(z*Y^ vfQw(o~"`q C7x϶o{XS8z33"'Λ8r \rݿ3bs% ;돚]⍙!] jnO?91Itw<W_?l=` :D0E^mIp4-Aeش#.N�nw {{Է'5msٖc.t}އ@1өZ]Q̋t:ފ`޼8<{Q)õ#|;N Nog-Iߑcoo[w5?ut*pF+Me%ϘvsLyLKd3E47eNiǟq8G8KBa83ճ8:s)l{.?pohwKtߥ^eP,t;Igα-{n(ky,7Җמ=9J7>Ŀ�N.>tnf5uj hh2%߱y X"s]gیh{|)bBX-BAD .|>gʢM%7G,^5㶮O:7}#xg{{)ȹ Q氀Oح 3- /GǎGtE(DxǸs yarх 8nmȂqqHH7F T}%ܦt;} gn+L1L/RM*Qˆ@=!v;N-Őq{'2 L e8Q�D7Th[(ȋPg (c֡_^m%R'4c>>GH_)SFٜOݑxζ;[fEʗp2P%xmam8$&X׻; 5$2=QڵkPd}PBAGX,PKB⺖ Ƕt;co5s|%! , yHp:wH%"+XgD.@݊ K1 gUae8ʁY�2.zD㺢G'_d/`γC s! ;/wGpEdiq =uV؂F_<s]Gނg!3E[@UWx]+f%[H [ϫ{ī C-OX`)K,G&Lк   _a~ta0_c g6k Z0N ]�SlZ#&_}oh4w:b=yun2,`8 ]'NX#l wau}F�;M 2hCN<>j.\y\ALC,@@Xeq޿':ś(A!&: 6 P1q&$@0@G(e T^+pA6[ϪŶ}a [{4[wtߨ] HCɳIflFLpjZЮ lS3 ZtudLa]FO%&hpdJ} Klg3TÔ3Ԥk2gcmMy32X^V.Eӡl{{*OBtg$a� 1!e3SiNC$h #qʤ/NC; [7@>NL<zHpafU!ӾܘqΪn&۸1β e~])ȚVNz·g>KwBL(CE-S YY~ACw)u C77/B.*y8Ϊ37闕}ʃbuG,>!3N˛OwKIt@.5jdsAW;ⱺ&w4HPD{VQ3S6{g #cn*�9cIęDZv@q!5BLR6r&cMqqk\X`ٌ :6 ħػg&@q8w,S"}�7_D]5%.|1� MyPfa[i-;裗wN]I ǭf$hF{[23X�3܊[V&]aC׬g6VX : PT5|3Wÿ畛a ] Ǿ2sá7첂 x^٫;VcOp@Q'><Q}Dѡ9zHA'`8@ $OBz,QV)qBʬԧP<yޭ&YeJ]cM5`ǭeB=G|cϘgo CL:[3G h.H^ ܙw3`BIySPtI`0F9χ~`79&CtYUk}=ԸEkntʵ@ݤ̇R//__nSg1u#_gA6YaC1W7Sjs ضМHA*W64ow*z?+*Xoo$ƺ+v6ǭm!"~z14xA~7ٶ$<*Z͠Z=+,gNc1K@SzIH>hemYMl "})khjPeB;S=O͚f\qlh)+ퟋX$k`[C̎&Jd=BwŔq>خ6ZPh(1p_(<UoHW{͋vޜK}W3;~A#H1ŭs 8Z|05u#/)%8FϮ]�apN*�+7XdYOB8jC~StZ7 kG{\[yeo`쳌`qOF`(Β@4Cq0Iic#oaV @;[)F#/<Oq6:zs!g3+_x-n~6d2o1 ֻChb hCV13;}ȅ utwVc |aOd\Au+esd3\j^1!2'�,,AN^8qϫ@h<Uզ/d G?kI D<}TKBY$^P"}t�H9 u:8uC*|ǜ*q!L~V�4EM,*wpt;w4eV*zfoZŬ{;ͦ+Rá˛n3vc1%@d7G۔}H~o5ĸIS#GwX#Ś/sf|bxpp8M;9? kǣ+˿2Xm߻{ 3~)omA/o'gbu!u\瑑HS'XpC0:^M~g?r`(dZ<ru5/k4 ͶOYn>5cwƌwձxݮNWjfloj 0/XCphx[5 1QϱŀXWB˲]& SzB_NWԇNH`CbA?Д }OEA5RF굝Bq� fX +=[;dք-K=SO) l߱7,Kj= 3vTAC}g{jb( 퓊 5C hycvfB-�HC7zy8,h^7]7NE~C?Ǵvc_kdyԟ?+!) ( @'xDCʙqO(!HC NGI~ǞWΫ} Y_TP|Q=eTO:�y~ Ĕ>rhB) {φtGЮu-dD(:1t])NO^ݱyeGMG呉ַُ NLS ͆v65xdo3jgQ5F6|PgO5;mO\wF}M55CݑU0>b;̙uR IGԝ�"Pm uC"/"gǧ?{Lc#FAb@)fnb<f0 7qCq $"H#Sq }(dh4,TAo~~15rJI_PAkL3~vP\$H({|xBN )SP 艧>~V PC}fc툋_ޣfOFxQB}1w;n_>o,4C-Go%{ۏy+'X>)̈́1UϤ c0&AN _i�g!~Y7(nFOrƲ>zӺRە~ue:jv[ύCx$h} NϫϚ ٘vApI?kSoٶ`t؏q(I�@ɛcuX(ʝ3zλC]I}%AL= =L�JV5{LL=wx qHf}:uGW࿦ 7_5_Q'8]?Qqꉧvʪ=d@y z[mODbgՎ&[Ee6P;mOv>uh;6p񖃛h&3|;7+yddbm{_�L2߲"&Qg5ޮbNE~6}~w)h}EthE0wzvfX(bu=jzln:lv4ۓgYsD&|Ǽ:?k$ic"[؞ء|[7MOB/~_>}@'V8{$t6ba}�XJ@RA1T9'zŞn)aćB(w$kN*z߯Gk۳WPO:@ { (j =q�_e̞X FYsP Po*|-p VO ׬H@pľҘ5Ynz=<)'HCV6ǿLZF_E'B[s;9"ZuY\Ma$MPFD/]Tbhuf^]>l<A?x"ſd�XmcZ mH8:5j)hboP'> cc;iň�n>tif.|YFL=> aOC3HB<$S�ʜ}t~%Sud< NYb5q7#l@MYϪ>S-l/RZ1yf`}m\/R}3l$ .uJL^JBqХ[v Xm4ƓDA=nf  op}~fR%G]<%l$^^|P=ӫ78||<?#PQsx�{,(]Ϙ}~4ƿ팙MXsYC.>4=qm)8iKS"�R" S8 c+iL# W8,⑺@7Gp__NdRf=xW)Yٮ�gA~xǍca3y?X N :ȃZ'b6v1Ghpx[QOM|瀋{xPnR'%V*7Qy|}( M @ud�V iiEґEsYdٖ:ml5 Uc &4pމ-֍/^kebOC_ {lͪ]z] y;V7ͼUC =I}tP=8=6o<N""*8G{ # /Ս$^<~* CLMu>�K-"g3;5y<U!53=} OSS ]O3Ϫg?59_IY 1rޞ#z2mn3t E|;kf8`:A:% ,%uGIe'ald@]fy{*~Цu@Z>AX%%,`Cדzv{cCPw[4HI#T lJnfgl[v*׷ %,e΂mEd!7hvo䎓xq8 'B j) J<ʤs 3�Ji۪izdP:Q/2^oB}˄BҁjFUGª}a. ))]O`ouMT�A5Q ikmT߿/Y(J0f_)y*()p=bClfJB{QPrU�(%_J"vB^L ȮBrTo\߳i7Bt5/Że]K}%BfhM+ ;bJպ*F^Ttɢs߿cDW2hr-{nQi XN /w>;|E n80&4Z`{sd~<UbhX5G ADDb$XoYt.ne-UknFe"JV(ٻ] J�Q5=F81E`G"EBx,t, Y4jKTCxx 0Cw\SP= l p=�4xp 8a8N+o} Qx O, r@}cBh6U~TS>s~$AFd {{Y_\p2]Y,AKeNy-{d@@vށ-@lS`K?B>@WO{7Z@w\?$U.YA7+Kj,ӷJ4%lT $`~{rݷīUog1@'2L"P N@S7� 0 6W}\";Dv{~!xHU\v>|J|`¶TٔWr8D'Ъ A  KHee H/#r;"Ļ20c6r5IvJB�s㮣>x]~<GZ [#uk-gWe~0]vnD>2� GţGxo6d]wd�a%F9?{`h^hd`Dn{e.**qHZl?J+l)]BUqGV|& ] 8z|TlPl:& N.R]1۷)A}žmd6C4Z-( p.& zD/(F*\"<H+ZjzLIa;-/C_MӶETTrh~ xbFKioF!祒 UJp/8t+x_NJ`+Im$s.A�UK 8pk�H1<ڊǽUMgE3/?' V"OrI'iS^& \ þ[ ~z j-Ewɿ2C*eFq[ M~I@ `$̢$쁀$ \ٷi)dxZ E3 A\A<Q5K)\/l3O V2մnœ*z,} ]��&IDATFxd3 :6(h}j? *HqASCp1p1Û vpqxۈZqe}`naK5I5 D.Z]`@=�s+;#C%!| @ZcljX[d6[N:rVEWVI`qʑ&U(3Zt|IGRv�.Gebq(C H fK]HA^{Z;$J4RykM&eK[Av|WtUz}1\ZXQB-Q,RkpR_}tJɾEs~J̩z[V 6Б|}0\^JK2[<& B}>U_LA/Pm+q`,HҗW~/mҦp/YGH kܯx!N*^G i%ArF!o0p_qEg%ިE^{(G2R oS ~yq*O4:]Ѫ KB-~EuIJ!nl0K~&6k`/g ۺ$[T@ *gWX?d|dB1gZ�sU(GSnٟ{˻+'B F I:>{!h zր*d($myEnn =rKrUrşI,ֹ˟&" gxyɯK&u>wXL_aHQUQwqHݲh9I i;ţ9=sOhr[9#\Gw#^\zS"ɜ�@`޹YEɼR݁p\ͺ+l{ªE3X$5L#h0}~ z}n(4S$–~qڽӋ?<p^< {/8(w(ƴ4}H{8U$۴xxMJ85I7Xo , yTE=MlǕn dT/P<x{=Ё8xHr8w7NWH*lJ^8w$(ҘXڊ c�A$ImV_QxLfRe@r((IX#x,\%|ިt�w&BaFTJ9WgN. Ł~׼V>-/S"uTxq= Mp`5WB&ݳ>HVz[..(#0e 345G&?yCn;s,+*HNŁ|ObI}.`:Ccf+*c)�+j~:h@PKmôwW!îR&H8^yf|HSy;(ٌ̹|\K^%e$3) d"`z \;)a{G>aw9o( v>:Bq=YIJ'9s\*?T8Р{"Kp6u{5oLU<cDzwa2$ Xڢ{f|_+e2 ^؞qc/ J 5#VJh qEEH ;ܫp-zg߻ Ac 8'_RK*.tߴog Cs%.mBP}Է!7X_]?ZM VٿggV;Y$ ~?y^^<nXʣYCth6=%\.x[[>@]9G]E&iŧhGee?|x~"|BsR+Er oWRZE&)1bn{$ *;/`qR�nfTqwR'kG f (/(Kjm4̛ 9N8(dc} )Qф-2j'ZSM_$NEwKTˊd{MO>YSt?OTmwsoy4UhYK}k?u+fcǐL7a${zhr|r7\/<Sx/by5Y/HRjW9~I땣\p:/\-{voci<kIQx,Noܼs\"ݔB,J3*]A2S<AnG}ȷV[yR%Zw%+b c{Bй~c$tyxc:ZŜq_ۓ"$vB[y5z|uA.SY ':[* 6v$7чoD/g cT?)>秖ǢrR _7Nzm ;wEoƼV9j%`Sgfff7ƾrb`9q溃:WWǘݩ"Y's6>ű^W Ew.G!g0 ű7KqѺd,}n�5owYy= :API1Җg@0L<D;Ul,<-<2RTqf(Q~1Pg w3ZB15KECbم=֢QG؎םi8ziy @b~DAKQw싒Y_ٝ-g޻mW- rN߂_&IA.z=3nqqF.#`e.]}lu?Y)!) -\4(!A+6,@�C5À\·- 0k:@kc@m"_R:+gr%4$v_{3_#Aawvggggw~{-o'|yԙ/ ?I՟T_Kk]׾tK cεY !Zj VvP銁--Bħb:3Ԙs)6_U7흨^RccK'^3z,7)Gk7@E*T\tmy+ܞA4 ax802Xş)gsoW6Ve),DL~N:sLQ湓 9<ל^r,!tNXG,k 9tNm$ρ8<9 =\`�Y_#W`..O`lӣ; gc_trgkJq}GQt9_pnͧ_i1}t--MHE\BOFX h $19Bny3W?_36㶿m[(ئծRyegH*g r<| |uf|3uX~:ϼywPjPG}:S˔Hӓ'݁2ŸA霛er7)frS4&rB6T>43Tt:WTS}f7 =LEA`Z Ǘ;KW0_LJRgo.VzfzfQM *Go"ǡd[Հ..)nKH8Qb?q;ך 'M``d ls\1*FG3vGu^sqA\ kTDM ȊY1 9%U6qwU^;VEvǜ15YMn{QIc{Y!|C Ɵj49K.Fdo߹C;߱s!l >i#:ۡV JY$M Ff.<qu_bA'=n҉eItL_H>{Ķ>9$!cڞ~ޒT1+5wi̮/f"1xv*qQ7iN&:b a{(qoϮ{鏿q ^VLksz;."%گߑ#vK|loD�O#ڔޔh߻MN!M(JS|J| c'w>hKߝtSqj3`?g Kmf<CPHo}isD,0KE.CG+Q!4HK F62%j$!/Ĥ2-Q‘RpSWl8g/N]htlOs:i&aVٌы1qϜ3hq9iJ q (gX/x;؉(S ǤvEw >?,KarEG.g_+`NMkTE�|O0Q޹жp;Gq�) a+rr`*Dž",orr s4 n"a@0ٌ,$S]C~5]_-~>1q]{_2\,zw9rE3f<;gL 0y~}R|NgjB.D`Ե9rJFSPdTc:<L4j3S)'ebZ IR75rzL.G@R3觜y̋iXfJ<)rH,gD.qv9 v2\`'nÜmԈ+d*CF;#O;Z9h>j4_U�Vh1n5vc%$gv&_zG/|_Aj�CJ6A&*) Z* ^*92xZ*g2d(B1_-2sD�C,D/<;I2#:F,3&cz>i Wm:Ncx_QӅI=nҮ hV>!LԢ_FSS34WhELȆq* D[Q 6{iHkN? V12Iį 8d\Cꞥ*(JחopuT(bCXƮ@0/ DtW&2Dҋ =EdWC]kVs-g+v5_TO¨1_*ruu[0ZvҤ/Oβ{{='voO/X'QGy,n=(+:A`īUўF9oD1% rr)е#!S(@ߝ߭jK_cDӟN@0@=NdjO7PfmdIn&N\O篪CQ\c I 4  \Y-Bq٫G=Z[u56Mܹ\xۀ,&1CR9:.}JT A~N<_j:֟Y�.l{APTw䊿5ܭS&5-}M>h#ef|u;:40_ 2|}I,X h9A4hEZ >):nF@WСmA<0jOp @_O9_Ric!S97 '� z0Oo B@J{=& E , F^Ǫ֦5n lA[qxͪ |:$ ijJAvz 0 FJn_`^g5k|Zi\]Qh!6liL΄*4sVĒs1uH.)@7%yaFM5" ^\5H_?f@g(&au @�IT�,pӴжYap5&v uq<f AEYW?~ت43zҠ|]bTDNDƶ6P phH:3*V%{ܽ9#{v;*rC�Y�H{f+lZUʀj}Zce w52+Mq]F%C. . tMm!FügRf`&lM!n5A@4jI1X|6߫ӗ|PX^xKhU'[glQ0 I#'O f{X%a39$MGʸNna E*/&]Ch_Ob<*kI%\1uݨkK�FªYOՄ+?WOqU|j%xϷ -L9F,/lQ]7]U>}A0 Ӆw-(`d7Dl@A�By$O{1.Ca:q-~Pg=:ۢnu-;pzplNH٘2GVn2/}EiaeҷJ>} 8GlN)'gH{t3dgQ"7�+܎mQUD8'xqVdGEk ·M2󬢣7M 5׫~ե-WH;; :qyѩwM=;ubn̤g_lp0 3V 3"6@0] y,T+Af| +Z%U~>毕vq Z_AzV)U Al48v5o"RB6HrYv͚ȵƣRT>ɚN/p{udYd>X#u `t bΕ1<n+%\Gs�z.7ZZ];a6:,Zҁ^ F?“#CSv䑵{*3E$!O活H #ɸ$I ;Ʌv|:cc\H.-Փ4Rzyy# کbRuAX_dMj"lhCj2G)1ύ:,xg| VVs&[) @k'9G<QBf ǪZ0Ҧk9{PC J"OBT5o*[pl7a=Q9VhC�sˣBl̳_@?tCL3γrq)*8%t&٬TsA02Y#i\['|X4H?JQiAprAm('lfa ,Dz)l*R2B@(XB>P.](8Tdo|RA0L-֨*iS3TX}W:Y67Z[9q[:8G4H?JSD *xw9|>†J6g _@^k1�jNI@ٜDN A� 8n�ppu>شa> 4Ͼ#(x{5^mW~1A ( DǜA`[S~YP*K` ^H  :96@`*jAJ ϹT q|,&{޹\Ap@@S%ۿCXER|9%/ ;Ϫ:8AZ ll47m"^kfμ@ 0PX77Q<"GK}`-q nhx@X(X.xIYNruqO/'}n'P%d1y\-�1<O5)g"u~Pp*:#k&>AAӡߑA ǥ2F HB `ќ6ʶAOg\&t >4O <({@� ybWH;c><|Dkvm1B֒ Bj9:8#\X0J i̾/"'٬|PҚ0AGws [U"Y}0 c筷ea):p2vìS`P[l::Gtܷ4]U 26m|`:v>hG Xl%TBNb-8 aEpǧu{x @8&VTIF@Py.PO`\SH Sϫ)35l+<4`r[U m $Hxm6wNn;{Ҝ@ 3qyPژ aC|8`8>.�3K`=�"DAPW XP[FH&B xI@Z/MES@x63  W?W@Eڣ6; }1vf Рt@L0GxvHkɷU(]op;N y R,0j"j9l/wˏ1npQq\/nݬ3k@L&f!>B@ ӗ7uQ P A @&P z1''!\c98Iy Z1,p]hr" ^M q3 !,[>$r{@:61öHfW[ "lin-MsiE4r ҏP +3<ۙ,KQ[@prK`U[Yd'�0'W&}Il"R`+p|�qpс=`�K`o7l-D@`ic\y5ly1.*DZ 46<"n!&k_@s9,.V  A,X?,v,~K`+rŃ,@P c1$gû(xQN$|#cϾ~ Hsc}tϨ~aA c2xB@ Qn`r.<I D" 9oV ȱ8Ac_Dʜ@M< @@kXЃ.kMJ:S*Hr1NEr(B`4!9}n@@X'wA�t0`ǎXeDeAӚA UQ,##^hVUOqdp(˱ԓVh#@ =B1  Ltv mHTr1G y% oJNP*9,; m: �{ 'OU.of!@B;o*e`n e'KOLet)<x<LM+m|ݹ:s]$\Ӕ  M!ZrNFM,+V>[$W8U3 2@CI`Q/l XjIvcɿ<iNrT[|U 며bciEZJJJ''d iLCљ" Gu-  ���%tEXtdate:create�2023-06-04T15:47:09+00:00;k���%tEXtdate:modify�2023-06-04T15:47:09+00:00JK���(tEXtdate:timestamp�2023-06-04T16:04:57+00:00~����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/urimethodmap����������������������������������������������������������������������0000664�0000000�0000000�00000001123�15202323131�0016341�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Default urimethodmap file for Chawan. http: cgi-bin:http https: cgi-bin:http finger: cgi-bin:finger gemini: cgi-bin:gemini file: cgi-bin:file ftp: cgi-bin:ftp sftp: cgi-bin:sftp gopher: cgi-bin:gopher spartan: cgi-bin:spartan man: cgi-bin:man man-k: cgi-bin:man man-l: cgi-bin:man img-codec+png: cgi-bin:stbi img-codec+jpeg: cgi-bin:stbi img-codec+gif: cgi-bin:stbi img-codec+bmp: cgi-bin:stbi img-codec+x-unknown: cgi-bin:stbi img-codec+webp: cgi-bin:jebp img-codec+x-sixel: cgi-bin:sixel img-codec+x-cha-canvas: cgi-bin:canvas img-codec+svg+xml: cgi-bin:nanosvg ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/res/widthconvmap.tab������������������������������������������������������������������0000664�0000000�0000000�00000002325�15202323131�0017120�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������! ! " " # # $ $ % % & & ' ' ( ( ) ) * * + + , , - - . . / / 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 : : ; ; < < = = > > ? ? ⦆ ⦆ 。 。 「 「 」 」 、 、 ・ ・ ¥ ¥ a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z A A B B C C D D E E F F G G H H I I J J K K L L M M N N O O P P Q Q R R S S T T U U V V W W X X Y Y Z Z ヲ ヲ を ァ ァ ぁ ィ ィ ぃ ゥ ゥ ぅ ェ ェ ぇ ォ ォ ぉ ャ ャ ゃ ュ ュ ゅ ョ ョ ょ ッ ッ っ ー ー ア ア あ イ イ い ウ ウ う エ エ え オ オ お カ カ か キ キ き ク ク く ケ ケ け コ コ こ サ サ さ シ シ し ス ス す セ セ せ ソ ソ そ タ タ た チ チ ち ツ ツ つ テ テ て ト ト と ナ ナ な ニ ニ に ヌ ヌ ぬ ネ ネ ね ノ ノ の ハ ハ は ヒ ヒ ひ フ フ ふ ヘ ヘ へ ホ ホ ほ マ マ ま ミ ミ み ム ム む メ メ め モ モ も ヤ ヤ や ユ ユ ゆ ヨ ヨ よ ラ ラ ら リ リ り ル ル る レ レ れ ロ ロ ろ ワ ワ わ ン ン ん ゙ ゛ ゚ ゜ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/����������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0013721�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/chac.nim��������������������������������������������������������������������������0000664�0000000�0000000�00000003550�15202323131�0015327�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/os import io/chafile import monoucha/jsutils import monoucha/quickjs import types/opt proc die(s: string) {.noreturn.} = discard cast[ChaFile](stderr).writeLine("chac: " & s) quit(1) proc usage() {.noreturn.} = die("usage: chac [-s] ifile ofile") proc bindMalloc(s: JSMallocStateP; size: csize_t): pointer {.cdecl.} = return alloc(size) proc bindFree(s: JSMallocStateP; p: pointer) {.cdecl.} = if p != nil: dealloc(p) proc bindRealloc(s: JSMallocStateP; p: pointer; size: csize_t): pointer {.cdecl.} = return realloc(p, size) proc main() = let params = commandLineParams() var strip = false var ifile = "" var ofile = "" for param in params: if param == "-s": strip = true elif ifile == "": ifile = param elif ofile == "": ofile = param else: usage() if ifile == "" or ofile == "": usage() var mf {.global.} = JSMallocFunctions( js_malloc: bindMalloc, js_free: bindFree, js_realloc: bindRealloc, js_malloc_usable_size: nil ) let rt = JS_NewRuntime2(addr mf, nil) if rt == nil: die("failed to allocate JS runtime") if strip: JS_SetStripInfo(rt, JS_STRIP_SOURCE or JS_STRIP_DEBUG) let ctx = JS_NewContext(rt) if ctx == nil: die("failed to allocate JS context") var src: string if chafile.readFile(ifile, src).isErr: die("failed to read " & ifile) let obj = ctx.eval(src, ifile, JS_EVAL_TYPE_MODULE or JS_EVAL_FLAG_COMPILE_ONLY) if JS_IsException(obj): die(ctx.getExceptionMsg()) var plen: csize_t let p = cast[ptr UncheckedArray[char]]( JS_WriteObject(ctx, addr plen, obj, JS_WRITE_OBJ_BYTECODE)) if chafile.writeFile(ofile, p.toOpenArray(0, int(plen) - 1), 0o600).isErr: die("failed to write " & ofile) js_free(ctx, p) JS_FreeValue(ctx, obj) JS_FreeContext(ctx) JS_FreeRuntime(rt) main() {.pop.} ��������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/config/���������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0015166�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/config/chapath.nim����������������������������������������������������������������0000664�0000000�0000000�00000015655�15202323131�0017317�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/os import monoucha/fromjs import monoucha/quickjs import monoucha/tojs import types/opt import utils/myposix import utils/twtstr type ChaPath* = distinct string proc `$`*(p: ChaPath): string = return string(p) type UnquoteContext = object state: UnquoteState s: string p: string i: int identStr: string subChar: char hasColon: bool UnquoteState = enum usNormal, usTilde, usDollar, usIdent, usBslash, usCurly, usCurlyHash, usCurlyColon, usCurlyExpand ChaPathError = string ChaPathResult[T] = Result[T, ChaPathError] proc unquote(p: string; starti: var int; terminal: char): ChaPathResult[string] proc stateCurlyStart(ctx: var UnquoteContext; c: char): ChaPathResult[void] proc stateNormal(ctx: var UnquoteContext; c: char) = case c of '$': ctx.state = usDollar of '\\': ctx.state = usBslash of '~': if ctx.i == 0: ctx.identStr = "~" ctx.state = usTilde else: ctx.s &= c else: ctx.s &= c proc stateTilde(ctx: var UnquoteContext; c: char) = if c != '/': ctx.identStr &= c else: ctx.s &= expandPath(ctx.identStr) & '/' ctx.state = usNormal # Kind of a hack. We special case `\$' (backslash-dollar) in TOML, so that # it produces itself in dquote strings. # Thus by applying stateBSlash we get '\$' -> "$", but also "\$" -> "$". proc stateBSlash(ctx: var UnquoteContext; c: char) = if c != '$': ctx.s &= '\\' ctx.s &= c ctx.state = usNormal proc stateDollar(ctx: var UnquoteContext; c: char): ChaPathResult[void] = # $ case c of '$': ctx.s &= $getCurrentProcessId() ctx.state = usNormal of '0': # Use getAppFilename so that any symbolic links are resolved. ctx.s &= myposix.getAppFilename() ctx.state = usNormal of AsciiAlpha: ctx.identStr = $c ctx.state = usIdent of '{': inc ctx.i if ctx.i >= ctx.p.len: return err("} expected") let c = ctx.p[ctx.i] return ctx.stateCurlyStart(c) else: return err("unrecognized dollar substitution $" & c) ok() proc flushIdent(ctx: var UnquoteContext) = ctx.s &= getEnv(ctx.identStr) ctx.identStr = "" const BareChars = AsciiAlphaNumeric + {'_'} proc stateIdent(ctx: var UnquoteContext; c: char) = # $ident if c in BareChars: ctx.identStr &= c else: ctx.flushIdent() dec ctx.i ctx.state = usNormal proc stateCurlyStart(ctx: var UnquoteContext; c: char): ChaPathResult[void] = # ${ case c of '#': ctx.state = usCurlyHash of '%': # backwards compat ctx.state = usCurly of BareChars - {'1'..'9'}: dec ctx.i ctx.state = usCurly else: return err("unexpected character in substitution: '" & c & "'") return ok() proc stateCurly(ctx: var UnquoteContext; c: char): ChaPathResult[void] = # ${ident case c of '}': if ctx.identStr == "0": ctx.s &= myposix.getAppFilename() else: ctx.s &= getEnv(ctx.identStr) ctx.identStr = "" ctx.state = usNormal return ok() of '$': # allow $ as first char only if ctx.identStr.len > 0: return err("unexpected dollar sign in substitution") ctx.identStr &= c return ok() of ':', '-', '?', '+': # note: we don't support `=' (assign) if ctx.identStr.len == 0: return err("substitution without parameter name") if c == ':': ctx.state = usCurlyColon else: ctx.subChar = c ctx.state = usCurlyExpand return ok() of '1'..'9': return err("parameter substitution is not supported") of BareChars - {'1'..'9'}: ctx.identStr &= c return ok() else: return err("unexpected character in substitution: '" & c & "'") proc stateCurlyHash(ctx: var UnquoteContext; c: char): ChaPathResult[void] = # ${#ident if c == '}': let s = getEnv(ctx.identStr) ctx.s &= $s.len ctx.identStr = "" ctx.state = usNormal return ok() if c == '$': # allow $ as first char only if ctx.identStr.len > 0: return err("unexpected dollar sign in substitution") # fall through elif c notin BareChars: return err("unexpected character in substitution: '" & c & "'") ctx.identStr &= c return ok() proc stateCurlyColon(ctx: var UnquoteContext; c: char): ChaPathResult[void] = # ${ident: if c notin {'-', '?', '+'}: # Note: we don't support `=' (assign) return err("unexpected character after colon: '" & c & "'") ctx.hasColon = true ctx.subChar = c ctx.state = usCurlyExpand return ok() proc flushCurlyExpand(ctx: var UnquoteContext; word: string): ChaPathResult[void] = case ctx.subChar of '-': if ctx.hasColon: ctx.s &= getEnvEmpty(ctx.identStr, word) else: ctx.s &= getEnv(ctx.identStr, word) of '?': if ctx.hasColon: let s = getEnv(ctx.identStr) if s.len == 0: return err(word) ctx.s &= s else: if not existsEnv(ctx.identStr): return err(word) ctx.s &= getEnv(ctx.identStr) of '+': if ctx.hasColon: if getEnv(ctx.identStr).len > 0: ctx.s &= word else: if existsEnv(ctx.identStr): ctx.s &= word else: assert false ctx.subChar = '\0' ctx.identStr = "" ctx.hasColon = false ctx.state = usNormal return ok() proc stateCurlyExpand(ctx: var UnquoteContext; c: char): ChaPathResult[void] = # ${ident:-[word], ${ident:=[word], ${ident:?[word], ${ident:+[word] # word must be unquoted too. let word = ?unquote(ctx.p, ctx.i, '}') return ctx.flushCurlyExpand(word) proc unquote(p: string; starti: var int; terminal: char): ChaPathResult[string] = var ctx = UnquoteContext(p: p, i: starti) while ctx.i < p.len: let c = p[ctx.i] if ctx.state in {usNormal, usTilde, usDollar, usIdent} and terminal != '\0' and terminal == c: break case ctx.state of usNormal: ctx.stateNormal(c) of usTilde: ctx.stateTilde(c) of usBslash: ctx.stateBSlash(c) of usDollar: ?ctx.stateDollar(c) of usIdent: ctx.stateIdent(c) of usCurly: ?ctx.stateCurly(c) of usCurlyHash: ?ctx.stateCurlyHash(c) of usCurlyColon: ?ctx.stateCurlyColon(c) of usCurlyExpand: ?ctx.stateCurlyExpand(c) inc ctx.i case ctx.state of usNormal: discard of usTilde: ctx.s &= expandPath(ctx.identStr) of usBslash: ctx.s &= '\\' of usDollar: ctx.s &= '$' of usIdent: ctx.flushIdent() of usCurly, usCurlyHash, usCurlyColon: return err("} expected") of usCurlyExpand: ?ctx.flushCurlyExpand("") starti = ctx.i return ok(ctx.s) proc unquote(p: string): ChaPathResult[string] = var dummy = 0 return unquote(p, dummy, '\0') proc toJS*(ctx: JSContext; p: ChaPath): JSValue = toJS(ctx, $p) proc fromJS*(ctx: JSContext; val: JSValueConst; res: var ChaPath): FromJSResult = ctx.fromJS(val, string(res)) proc unquote*(p: ChaPath; base: string): ChaPathResult[string] = var s = ?unquote(string(p)) if s.len <= 0: return ok(s) if base != "" and s[0] != '/': s.insert(base & '/', 0) return ok(normalizedPath(s)) proc unquoteGet*(p: ChaPath): string = return p.unquote("").get {.pop.} # raises: [] �����������������������������������������������������������������������������������chawan-v0.4.0/src/config/config.nim�����������������������������������������������������������������0000664�0000000�0000000�00000220023�15202323131�0017137�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/algorithm import std/macros import std/math import std/os import std/sets import std/tables import encoding/charset import config/chapath import config/conftypes import config/cookie import css/cssparser import css/cssvalues import html/script import io/chafile import io/dynstream import monoucha/dtoa import monoucha/fromjs import monoucha/jsbind import monoucha/jspropenumlist import monoucha/jsutils import monoucha/quickjs import monoucha/tojs import server/headers import types/cell import types/color import types/jscolor import types/jsopt import types/opt import types/url import utils/dtoawrap import utils/lrewrap import utils/myposix import utils/twtstr type RegexCase* = enum rcAuto = "auto" # smart case rcStrict = "" # case-sensitive rcIgnore = "ignore" # case-insensitive Action = object k: string n: uint32 val: JSValue ActionMap* = ref object defaultAction*: JSValue t*: seq[Action] keyIdx: int keyLast* {.jsget.}: int num: uint32 FormRequestType* = enum frtHttp = "http" frtFtp = "ftp" frtData = "data" frtMailto = "mailto" SiteconfMatch* = enum smUrl, smHost BoolAuto* = enum baAuto = "auto" baFalse = "false" baTrue = "true" # ColorMode or -1 for auto ColorModeAuto = distinct uint8 # ImageMode or -1 for auto ImageModeAuto = distinct uint8 # cast[int32] of FormatMode or -1 for auto FormatModeAuto = distinct uint32 ConfigOptionBit {.union.} = object u*: uint8 bool*: bool boolAuto*: BoolAuto # bool or "auto" charset*: Charset colorModeAuto*: ColorModeAuto cookieMode*: CookieMode formatMode: FormatMode headlessMode*: HeadlessMode imageModeAuto*: ImageModeAuto metaRefresh*: MetaRefresh regexCase: RegexCase scriptingMode*: ScriptingMode ConfigOptionHWord {.union.} = object int32: int32 formatModeAuto: FormatModeAuto # RGBColor or -1 for auto RGBColorAuto = distinct uint64 ConfigOptionWord {.union.} = object cssColor: CSSColor rgbColorAuto: RGBColorAuto ConfigOptionType = enum # bit (1 byte) cotBool = "bool" cotBoolAuto = "boolAuto" cotCharset = "charset" cotColorModeAuto = "colorModeAuto" cotCookieMode = "cookieMode" cotFormatMode = "formatMode" cotHeadlessMode = "headlessMode" cotImageModeAuto = "imageModeAuto" cotMetaRefresh = "metaRefresh" cotRegexCase = "regexCase" cotScriptingMode = "scriptingMode" # hword (4 bytes) cotInt32 = "int32" cotInt32Auto = "int32" # signed int32; parses "auto" as -1 cotFormatModeAuto = "formatModeAuto" # word (8 bytes) cotCSSColor = "cssColor" cotRGBColorAuto = "rgbColorAuto" # string cotString cotStylesheet cotPath cotCodepointSet # seq[Charset] cotCharsetSeq # seq[ChaPath] cotPathSeq # Headers cotHeaders # URL cotURL # regex cotRegex # JS function cotFunction ConfigSection* = enum csNone = "none" # starting section csBuffer = "buffer" csDisplay = "display" csEncoding = "encoding" csExternal = "external" csInput = "input" csNetwork = "network" csSearch = "search" csStart = "start" csStatus = "status" # command sections csCmd = "cmd" csPage = "page" csLine = "line" # array sections csSiteconf = "siteconf" csOmnirule = "omnirule" # Note: when adding a new option, the compiler will scream about a bunch # of places. Just fill the gaps until it's satisfied, then everything # should be OK. ConfigOption* = enum # 1 byte coAllowHttpFromFile = "allowHttpFromFile" coAltScreen = "altScreen" coAutofocus = "autofocus" coBracketedPaste = "bracketedPaste" coColorMode = "colorMode" coConsoleBuffer = "consoleBuffer" coCookie = "cookie" coDisplayCharset = "displayCharset" coDoubleWidthAmbiguous = "doubleWidthAmbiguous" coForceColumns = "forceColumns" coForceLines = "forceLines" coForcePixelsPerColumn = "forcePixelsPerColumn" coForcePixelsPerLine = "forcePixelsPerLine" coFormatModeStatus = "status.formatMode" coHeadless = "headless" coHighlightMarks = "highlightMarks" coHistory = "history" coIgnoreCase = "ignoreCase" coImageMode = "imageMode" coImages = "images" coMarkLinks = "markLinks" coMetaRefresh = "metaRefresh" coNoFormatMode = "noFormatMode" coOsc52Copy = "osc52Copy" coOsc52Primary = "osc52Primary" coRefererFrom = "refererFrom" coScripting = "scripting" coSetTitle = "setTitle" coShowCursorPosition = "showCursorPosition" coShowDownloadPanel = "showDownloadPanel" coShowHoverLink = "showHoverLink" coStyling = "styling" coUseMouse = "useMouse" coViNumericPrefix = "viNumericPrefix" coW3mCgiCompat = "w3mCgiCompat" coWrap = "wrap" # 4 bytes coColumns = "columns" coFormatModeDisplay = "display.formatMode" coHistorySize = "historySize" coLines = "lines" coMaxNetConnections = "maxNetConnections" coMaxRedirect = "maxRedirect" coMinimumContrast = "minimumContrast" coPixelsPerColumn = "pixelsPerColumn" coPixelsPerLine = "pixelsPerLine" coSideWheelScroll = "sideWheelScroll" coSixelColors = "sixelColors" coWheelScroll = "wheelScroll" # 8 bytes coDefaultBackgroundColor = "defaultBackgroundColor" coDefaultForegroundColor = "defaultForegroundColor" coHighlightColor = "highlightColor" # string coAutoMailcap = "autoMailcap" coBookmark = "bookmark" coCookieFile = "cookieFile" coCopyCmd = "copyCmd" coDownloadDir = "downloadDir" coEditor = "editor" coHistoryFile = "historyFile" coLinkHintChars = "linkHintChars" coPasteCmd = "pasteCmd" coPrependScheme = "prependScheme" coStartupScript = "startupScript" coTmpdir = "tmpdir" coUserStyle = "userStyle" coVisualHome = "visualHome" # seq[string] coCgiDir = "cgiDir" coInclude = "include" coMailcap = "mailcap" coMimeTypes = "mimeTypes" coUrimethodmap = "urimethodmap" # Note: if you add another of these, don't forget to add an # array in Config too # seq[Charset] coDocumentCharset = "documentCharset" # Headers coDefaultHeaders = "defaultHeaders" # URL coProxy = "proxy" # siteconf-only, not available in config coAddEntry = "-cha-addEntry" # pseudo-rule for new entries coFilterCmd = "filterCmd" coHost = "host" coInsecureSslNoVerify = "insecureSslNoVerify" coMatch = "match" coRewriteUrl = "rewriteUrl" coShareCookieJar = "shareCookieJar" coSubstituteUrl = "substituteUrl" coUrl = "url" ConfigOptionClass* = enum cocBit, cocHWord, cocWord, cocStr, cocStrSeq, cocCharsetSeq, cocHeaders, cocURL, cocRegex, cocFunction, cocCmdInit, cocClear ConfigHeadersInit* = ref object clear*: bool s*: seq[HTTPHeader] ConfigEntry* = object section*: ConfigSection opt*: ConfigOption case t*: ConfigOptionClass of cocBit: bit*: ConfigOptionBit of cocHWord: hword*: ConfigOptionHWord of cocWord: word*: ConfigOptionWord of cocStr: str*: string of cocStrSeq: strSeq*: seq[string] of cocCharsetSeq: charsetSeq*: seq[Charset] of cocHeaders: headers*: ConfigHeadersInit of cocURL: url*: URL of cocRegex: regex*: Regex of cocFunction: fun*: pointer # JSObject * of cocCmdInit: cmdInit*: seq[tuple[k: string; fun: pointer]] of cocClear: discard ConfigRule* = ref object name: string matchType*: SiteconfMatch # only used for siteconf regex*: Regex # url for siteconf, match for omnirule fun*: JSValue # substituteUrl for siteconf, rewriteUrl for omnirule entries*: seq[ConfigEntry] # only used for siteconf next: ConfigRule ConfigList = object head: ConfigRule tail: ConfigRule const OptionMap = [ coAllowHttpFromFile: (t: cotBool, section: csNetwork), coAltScreen: (cotBoolAuto, csDisplay), coAutofocus: (cotBool, csBuffer), coBracketedPaste: (cotBoolAuto, csInput), coColorMode: (cotColorModeAuto, csDisplay), coConsoleBuffer: (cotBool, csStart), coCookie: (cotCookieMode, csBuffer), coDisplayCharset: (cotCharset, csEncoding), coDoubleWidthAmbiguous: (cotBool, csDisplay), coForceColumns: (cotBool, csDisplay), coForceLines: (cotBool, csDisplay), coForcePixelsPerColumn: (cotBool, csDisplay), coForcePixelsPerLine: (cotBool, csDisplay), coFormatModeStatus: (cotFormatMode, csStatus), coHeadless: (cotHeadlessMode, csStart), coHighlightMarks: (cotBool, csDisplay), coHistory: (cotBool, csBuffer), coIgnoreCase: (cotRegexCase, csSearch), coImageMode: (cotImageModeAuto, csDisplay), coImages: (cotBool, csBuffer), coMarkLinks: (cotBool, csBuffer), coMetaRefresh: (cotMetaRefresh, csBuffer), coNoFormatMode: (cotFormatMode, csDisplay), coOsc52Copy: (cotBoolAuto, csInput), coOsc52Primary: (cotBoolAuto, csInput), coRefererFrom: (cotBool, csBuffer), coScripting: (cotScriptingMode, csBuffer), coSetTitle: (cotBoolAuto, csDisplay), coShowCursorPosition: (cotBool, csStatus), coShowDownloadPanel: (cotBool, csExternal), coShowHoverLink: (cotBool, csStatus), coStyling: (cotBool, csBuffer), coUseMouse: (cotBoolAuto, csInput), coViNumericPrefix: (cotBool, csInput), coW3mCgiCompat: (cotBool, csExternal), coWrap: (cotBool, csSearch), coColumns: (cotInt32, csDisplay), coFormatModeDisplay: (cotFormatModeAuto, csDisplay), coHistorySize: (cotInt32, csExternal), coLines: (cotInt32, csDisplay), coMaxNetConnections: (cotInt32, csNetwork), coMaxRedirect: (cotInt32, csNetwork), coMinimumContrast: (cotInt32, csDisplay), coPixelsPerColumn: (cotInt32, csDisplay), coPixelsPerLine: (cotInt32, csDisplay), coSideWheelScroll: (cotInt32, csInput), coSixelColors: (cotInt32Auto, csDisplay), coWheelScroll: (cotInt32, csInput), coDefaultBackgroundColor: (cotRGBColorAuto, csDisplay), coDefaultForegroundColor: (cotRGBColorAuto, csDisplay), coHighlightColor: (cotCSSColor, csDisplay), coAutoMailcap: (cotPath, csExternal), coBookmark: (cotPath, csExternal), coCookieFile: (cotPath, csExternal), coCopyCmd: (cotString, csExternal), coDownloadDir: (cotPath, csExternal), coEditor: (cotPath, csExternal), coHistoryFile: (cotPath, csExternal), coLinkHintChars: (cotCodepointSet, csInput), coPasteCmd: (cotString, csExternal), coPrependScheme: (cotString, csNetwork), coStartupScript: (cotString, csStart), coTmpdir: (cotPath, csExternal), coUserStyle: (cotStylesheet, csBuffer), coVisualHome: (cotString, csStart), coCgiDir: (cotPathSeq, csExternal), coInclude: (cotPathSeq, csNone), coMailcap: (cotPathSeq, csExternal), coMimeTypes: (cotPathSeq, csExternal), coUrimethodmap: (cotPathSeq, csExternal), coDocumentCharset: (cotCharsetSeq, csEncoding), coDefaultHeaders: (cotHeaders, csNetwork), coProxy: (cotURL, csNetwork), coAddEntry: (cotString, csSiteconf), coFilterCmd: (cotString, csSiteconf), coHost: (cotRegex, csSiteconf), coInsecureSslNoVerify: (cotBool, csSiteconf), coMatch: (cotRegex, csOmnirule), coRewriteUrl: (cotFunction, csSiteconf), coShareCookieJar: (cotString, csSiteconf), coSubstituteUrl: (cotFunction, csOmnirule), coUrl: (cotRegex, csSiteconf), ] const FirstBitOpt = ConfigOption.low const LastBitOpt = coWrap const FirstHWordOpt = LastBitOpt.succ const LastHWordOpt = coWheelScroll const FirstWordOpt = LastHWordOpt.succ const LastWordOpt = coHighlightColor const FirstStrOpt = LastWordOpt.succ const LastStrOpt = coVisualHome const FirstStrSeqOpt = LastStrOpt.succ const LastStrSeqOpt = coUrimethodmap const SiteconfOptions = { coCookie, coScripting, coRefererFrom, coImages, coStyling, coInsecureSslNoVerify, coAutofocus, coMetaRefresh, coHistory, coMarkLinks, coShareCookieJar, coUserStyle, coFilterCmd, coDocumentCharset, coProxy, coDefaultHeaders } type Config* = ref ConfigObj ConfigObj = object bits*: array[FirstBitOpt..LastBitOpt, ConfigOptionBit] hwords*: array[FirstHWordOpt..LastHWordOpt, ConfigOptionHWord] words*: array[FirstWordOpt..LastWordOpt, ConfigOptionWord] strs*: array[FirstStrOpt..LastStrOpt, string] strSeqs*: array[FirstStrSeqOpt..LastStrSeqOpt, seq[string]] # we only have one of these types, so no arrays documentCharset*: seq[Charset] defaultHeaders*: Headers proxy*: URL dir* {.jsget.}: string dataDir* {.jsget.}: string #TODO getset lists*: array[csSiteconf..csOmnirule, ConfigList] ruleSeen: HashSet[string] cmdInit: seq[tuple[k: string; fun: pointer]] # initial k/v map actionMap*: array[csPage..csLine, ActionMap] TomlState = enum tsTable tsArray tsMultiStringSimple tsMultiStringDouble TomlType = enum ttString = "string" ttMultiString = "multi-string" ttInteger = "integer" ttFloat = "float" ttBoolean = "boolean" ttTable = "table" ttArray = "array" BeforeKey = object keyLen: int section: ConfigSection opt: ConfigOption addEntrySeen: bool ConfigParser = object ctx: JSContext config: Config dir: string # CWD for -o, config.dir otherwise filename: string key: string # user-specified key buf: string # last consumed string warnings: seq[string] states: seq[TomlState] arr: seq[string] entries: seq[ConfigEntry] # these sections have user-defined keys, so we prevent dupes like this keysSeen: array[csCmd..csOmnirule, HashSet[string]] tableArrayCount: array[csSiteconf..csOmnirule, uint32] error: string line: int entryStart: int # line where siteconf started beforeKey: BeforeKey ival: int32 tt: TomlType bval: bool laxnames: bool commaSeen: bool section: ConfigSection opt: ConfigOption sectionsSeen: set[ConfigSection] optionsSeen: set[ConfigOption] # cleared on every new siteconf/omnirule ruleOptionsSeen: set[ConfigOption] jsDestructor(ActionMap) jsDestructor(Config) when defined(gcDestructors): proc `=destroy`*(a: var ConfigOptionBit) = discard proc `=destroy`*(a: var ConfigOptionHWord) = discard proc `=destroy`*(a: var ConfigOptionWord) = discard proc `=copy`*(a: var ConfigOptionBit; b: ConfigOptionBit) = copyMem(addr a, unsafeAddr b, sizeof(a)) proc `=copy`*(a: var ConfigOptionHWord; b: ConfigOptionHWord) = copyMem(addr a, unsafeAddr b, sizeof(a)) proc `=copy`*(a: var ConfigOptionWord; b: ConfigOptionWord) = copyMem(addr a, unsafeAddr b, sizeof(a)) # Forward declarations proc consumeValue(cp: var ConfigParser; line: string; n: var int): Opt[void] proc parseConfigValue(cp: var ConfigParser): Opt[void] proc parseKeyComb(key: openArray[char]; warnings: var seq[string]): string static: doAssert sizeof(ConfigOptionBit) == 1 doAssert sizeof(ConfigOptionHWord) == 4 doAssert sizeof(ConfigOptionWord) == 8 proc parseOption(s: openArray[char]): Opt[ConfigOption] = return strictParseEnum[ConfigOption](s) proc optionType(o: ConfigOption): ConfigOptionType = return OptionMap[o].t proc section(o: ConfigOption): ConfigSection = return OptionMap[o].section macro `{}`*(config: Config; s: static string): untyped = let t = parseOption(s).get let om = OptionMap[t] let ot = om.t if om.section == csSiteconf: error("value only available in siteconf") let vs = ident($ot) case ot of cotBool..cotScriptingMode: return quote do: `config`.bits[ConfigOption(`t`)].`vs` of cotInt32..cotFormatModeAuto: return quote do: `config`.hwords[ConfigOption(`t`)].`vs` of cotCSSColor..cotRGBColorAuto: return quote do: `config`.words[ConfigOption(`t`)].`vs` of cotString..cotCodepointSet: return quote do: `config`.strs[ConfigOption(`t`)] of cotCharsetSeq: return quote do: `config`.documentCharset of cotPathSeq: return quote do: `config`.strSeqs[ConfigOption(`t`)] of cotHeaders: return quote do: `config`.defaultHeaders of cotURL: return quote do: `config`.proxy of cotRegex, cotFunction: # only used in omnirule/siteconf error("no such config value") proc page*(config: Config): lent ActionMap {.jsfget.} = config.actionMap[csPage] proc line*(config: Config): lent ActionMap {.jsfget.} = config.actionMap[csLine] proc parseConfig*(config: Config; dir: string; buf: openArray[char]; warnings: var seq[string]; ctx: JSContext; name: string; laxnames = false): Err[string] proc finalize(rt: JSRuntime; map: ActionMap) {.jsfin.} = JS_FreeValueRT(rt, map.defaultAction) for it in map.t: JS_FreeValueRT(rt, it.val) proc mark(rt: JSRuntime; map: ActionMap; markFunc: JS_MarkFunc) {.jsmark.} = JS_MarkValue(rt, map.defaultAction, markFunc) for it in map.t: JS_MarkValue(rt, it.val, markFunc) template siteconf*(config: Config): ConfigList = config.lists[csSiteconf] template omnirule*(config: Config): ConfigList = config.lists[csOmnirule] proc get*(ba: BoolAuto; b: bool): bool = case ba of baAuto: return b of baTrue: return true of baFalse: return false template isSome*(ba: BoolAuto): bool = ba != baAuto template isNone*(ba: BoolAuto): bool = ba == baAuto template get*(ba: BoolAuto): bool = ba == baTrue template defineAuto(typ, other: untyped) = template isSome*(v: typ): bool = uint8(v) > 0 template isNone*(v: typ): bool = uint8(v) == 0 template get*(v: typ): other = other(uint8(v) - 1) proc toJS*(ctx: JSContext; v: typ): JSValue = if v.isSome: return ctx.toJS(v.get) return JS_NULL proc fromJS*(ctx: JSContext; val: JSValueConst; res: var typ): FromJSResult = if not JS_IsNull(val): res = typ(0) else: var res2: other ?ctx.fromJS(val, res2) res = typ(uint(res2) + 1) fjOk defineAuto(ColorModeAuto, ColorMode) defineAuto(ImageModeAuto, ImageMode) template isSome*(v: FormatModeAuto): bool = uint32(v) > 0 template get*(v: FormatModeAuto): FormatMode = cast[set[FormatFlag]](uint32(v) - 1) proc toJS*(ctx: JSContext; v: FormatModeAuto): JSValue = if v.isSome: return ctx.toJS(v.get) return JS_NULL proc fromJS*(ctx: JSContext; val: JSValueConst; res: var FormatModeAuto): FromJSResult = if JS_IsNull(val): res = FormatModeAuto(0) else: var res2: FormatMode ?ctx.fromJS(val, res2) res = FormatModeAuto(cast[uint32](res2) + 1) fjOk template isSome*(v: RGBColorAuto): bool = int64(v) > 0 template isNone*(v: RGBColorAuto): bool = int64(v) == 0 template get*(v: RGBColorAuto): RGBColor = cast[RGBColor](int64(v)) proc toJS*(ctx: JSContext; v: RGBColorAuto): JSValue = if v.isSome: return ctx.toJS(v.get) return JS_NULL proc fromJS*(ctx: JSContext; val: JSValueConst; res: var RGBColorAuto): FromJSResult = if JS_IsNull(val): res = RGBColorAuto(0) else: var res2: RGBColor ?ctx.fromJS(val, res2) res = RGBColorAuto(uint64(res2) + 1) fjOk proc evalCmdDecl(ctx: JSContext; s: string): JSValue = if s.len == 0: return JS_UNDEFINED if AllChars - AsciiAlphaNumeric - {'_', '$', '.'} notin s and not s.startsWith("cmd."): return ctx.compileScript("cmd." & s, "<command>") return ctx.compileScript(s, "<command>") proc newActionMap(ctx: JSContext; s, defaultAction: string): ActionMap = let map = ActionMap(defaultAction: JS_UNDEFINED) if defaultAction != "": map.defaultAction = ctx.evalCmdDecl(defaultAction) var dummy: seq[string] for it in s.split('\n'): var i = 0 while true: let j = it.find(' ', i) if j == -1: if i == 0: break var key = parseKeyComb(it.toOpenArray(0, i - 2), dummy) let val = ctx.evalCmdDecl(it.substr(i)) map.t.add(Action(k: move(key), val: val, n: map.num)) inc map.num break i = j + 1 map iterator items*(list: ConfigList): ConfigRule = var it = list.head while it != nil: yield it it = it.next proc add(list: var ConfigList; x: ConfigRule) = if list.tail == nil: list.head = x else: list.tail.next = x list.tail = x proc freeValues*(ctx: JSContext; list: ConfigList) = for it in list: JS_FreeValue(ctx, it.fun) proc clear(ctx: JSContext; list: var ConfigList) = ctx.freeValues(list) list.head = nil list.tail = nil proc remove(ctx: JSContext; list: var ConfigList; name: string) = var it = list.head var prev: ConfigRule = nil while it != nil: if it.name == name: let next = move(it.next) if prev == nil: list.head = next else: prev.next = next if next == nil: list.tail = nil it.next = nil JS_FreeValue(ctx, it.fun) break prev = it it = it.next proc addOmniRule(ctx: JSContext; config: Config; name: string; re, fun: JSValueConst): JSValue {.jsfunc.} = var len: cint let p = JS_GetRegExpBytecode(ctx, re, len) if p == nil: return JS_EXCEPTION if not JS_IsFunction(ctx, fun): return JS_ThrowTypeError(ctx, "function expected") if config.ruleSeen.containsOrIncl(name): # replace ctx.remove(config.omnirule, name) config.omnirule.add(ConfigRule( name: name, regex: bytecodeToRegex(cast[REBytecode](p), len), fun: JS_DupValue(ctx, fun) )) return JS_UNDEFINED proc toJS*(ctx: JSContext; b: BoolAuto): JSValue = case b of baAuto: return JS_NULL of baFalse: return JS_FALSE of baTrue: return JS_TRUE proc toJS*(ctx: JSContext; cookie: CookieMode): JSValue = case cookie of cmReadOnly: return JS_TRUE of cmNone: return JS_FALSE of cmSave: return JS_NewString(ctx, "save") proc toJS*(ctx: JSContext; headless: HeadlessMode): JSValue = case headless of hmTrue: return JS_TRUE of hmFalse: return JS_FALSE of hmDump: return JS_NewString(ctx, "dump") proc toJS*(ctx: JSContext; val: ScriptingMode): JSValue = case val of smTrue: return JS_TRUE of smFalse: return JS_FALSE of smApp: return JS_NewString(ctx, "app") proc sort(ctx: JSContext; map: ActionMap) = map.t.sort(proc(a, b: Action): int = cmp(a.k, b.k), SortOrder.Ascending) #TODO we could probably do this more efficiently for i in countdown(map.t.high - 1, 0): let j = i + 1 if map.t[j].k.startsWith(map.t[i].k): # always remove the older keybinding let k = if map.t[j].n < map.t[i].n: j else: i JS_FreeValue(ctx, map.t[k].val) map.t.delete(k) for i in countdown(map.t.high, 0): if JS_IsUndefined(map.t[i].val): map.t.delete(i) #TODO not sure what happens if this is called after feedNext, but probably # not what you'd expect map.keyIdx = 0 map.keyLast = 0 # Helper function for evalAction in case it wants to replace the value we # are reading. proc mgetValue*(map: ActionMap): var JSValue = return map.t[map.keyIdx].val proc advance*(map: ActionMap; k: string): JSValueConst = var i = map.keyIdx var j = map.keyLast if i == 0 and j == 0 and k.len > 0: # optimization: bisearch for the first char let c = k[0] i = map.t.binarySearch(c, proc(x: Action; c: char): int = cmp(x.k[0], c)) if i < 0: return JS_UNDEFINED # go back to first relevant key while i >= 0 and map.t[i].k[0] == c: dec i inc i while i < map.t.len: block current: let ik = map.t[i].k while j < ik.len: if j >= k.len: map.keyIdx = i map.keyLast = j return JS_UNDEFINED if k[j] != ik[j]: j = 0 break current inc j map.keyIdx = i map.keyLast = 0 return map.t[i].val inc i map.keyIdx = 0 map.keyLast = 0 return JS_UNDEFINED proc feedNext*(ctx: JSContext; map: ActionMap; b: bool; k: string) = if b: inc map.keyIdx discard map.advance(k) else: map.keyIdx = 0 type CustomKey = enum ckSpc = "Spc" ckTab = "Tab" ckEsc = "Esc" ckRet = "Ret" ckLf = "Lf" ckLeft = "Left" ckUp = "Up" ckDown = "Down" ckRight = "Right" ckPageUp = "Pageup" ckPageDown = "Pagedown" ckHome = "Home" ckEnd = "End" ckF1 = "F1" ckF2 = "F2" ckF3 = "F3" ckF4 = "F4" ckF5 = "F5" ckF6 = "F6" ckF7 = "F7" ckF8 = "F8" ckF9 = "F9" ckF10 = "F10" ckF11 = "F11" ckF12 = "F12" ckF13 = "F13" ckF14 = "F14" ckF15 = "F15" ckF16 = "F16" ckF17 = "F17" ckF18 = "F18" ckF19 = "F19" ckF20 = "F20" KeyModifier = enum kmShift, kmControl, kmMeta proc toXTermMod(mods: set[KeyModifier]): uint8 = return if mods == {kmShift}: 2 elif mods == {kmControl}: 5 elif mods == {kmShift, kmControl}: 6 elif mods == {kmMeta}: 9 elif mods == {kmMeta, kmShift}: 10 elif mods == {kmMeta, kmControl}: 13 elif mods == {kmMeta, kmControl, kmShift}: 14 else: 0 proc parseKeyComb(key: openArray[char]; warnings: var seq[string]): string = var realk = "" var i = 0 var mods: set[KeyModifier] = {} if i < key.len and key[i] == ' ': realk &= ' ' inc i var start = true while i < key.len: let c = key[i] if c == ' ': start = true inc i continue if i + 1 < key.len and key[i + 1] == '-': case c of 'C': mods.incl(kmControl) of 'M': mods.incl(kmMeta) of 'S': mods.incl(kmShift) else: warnings.add("invalid modifier " & c & '-') i += 2 continue if start and c in AsciiUpperAlpha and i + 1 < key.len and key[i + 1] != ' ': var j = i + 2 while j < key.len and key[j] != ' ': inc j if key := parseEnumNoCase[CustomKey](key.toOpenArray(i, j - 1)): case key of ckSpc: if kmMeta in mods: realk &= '\e' if kmControl in mods: realk &= '\0' else: realk &= ' ' of ckTab: if kmMeta in mods: realk &= '\e' if kmShift in mods: realk &= "\e[Z" else: realk &= '\t' of ckEsc: if kmMeta in mods: realk &= '\e' realk &= '\e' of ckRet: if kmMeta in mods: realk &= '\e' realk &= '\r' of ckLf: if kmMeta in mods: realk &= '\e' realk &= '\n' of ckF1, ckF2, ckF3, ckF4: let n = mods.toXTermMod() let c = char(uint8(key) - uint8(ckF1) + uint8('P')) if n == 0: realk &= "\eO" & c else: realk &= "\e[1;" & $n & c else: realk &= "\e[" # see ctlseqs(ms) (from XTerm) case key of ckPageDown: realk &= '6' of ckPageUp: realk &= '5' of ckF5: realk &= "15" of ckF6: realk &= "17" of ckF7: realk &= "18" of ckF8: realk &= "19" of ckF9: realk &= "20" of ckF10: realk &= "21" of ckF11: realk &= "23" of ckF12: realk &= "24" of ckF13: realk &= "25" of ckF14: realk &= "26" of ckF15: realk &= "28" of ckF16: realk &= "29" of ckF17: realk &= "31" of ckF18: realk &= "32" of ckF19: realk &= "33" of ckF20: realk &= "34" else: discard let n = mods.toXTermMod() if n > 0: realk &= "1;" & $n case key of ckLeft: realk &= 'D' of ckDown: realk &= 'B' of ckUp: realk &= 'A' of ckRight: realk &= 'C' of ckHome: realk &= 'H' of ckEnd: realk &= 'F' else: discard else: var buf = "unknown key " for i in i ..< j: let c = key[i] realk &= c buf &= c warnings.add(buf) start = true i = j + 1 mods = {} continue if kmMeta in mods: realk &= '\e' if kmControl in mods: realk &= (if c == '?': '\x7F' else: char(uint8(c) and 0x1F)) elif kmShift in mods: realk &= c.toUpperAscii() else: realk &= c mods = {} start = false inc i if key.len > 1 and key[^1] == ' ': realk &= ' ' move(realk) proc find(a: ActionMap; s: string): int = var dummy: seq[string] let rk = parseKeyComb(s, dummy) return a.t.binarySearch(rk, proc(x: Action; k: string): int = cmp(x.k, k)) proc getter(ctx: JSContext; a: ActionMap; s: string): JSValue {.jsgetownprop.} = let i = a.find(s) if i == -1: return JS_UNINITIALIZED return JS_DupValue(ctx, a.t[i].val) proc setter(ctx: JSContext; a: ActionMap; k: string; val: JSValueConst): Opt[void] {.jssetprop.} = var dummy: seq[string] let rk = parseKeyComb(k, dummy) if rk == "": return ok() let val2 = if JS_IsFunction(ctx, val): JS_DupValue(ctx, val) else: var s: string ?ctx.fromJS(val, s) ctx.evalCmdDecl(s) if JS_IsException(val2): return err() a.t.add(Action(k: rk, val: val2, n: a.num)) inc a.num ctx.sort(a) ok() proc delete(a: ActionMap; k: string): bool {.jsdelprop.} = let i = a.find(k) if i != -1: a.t.delete(i) return i != -1 proc names(ctx: JSContext; a: ActionMap): JSPropertyEnumList {.jspropnames.} = let L = uint32(a.t.len) var list = newJSPropertyEnumList(ctx, L) for it in a.t: list.add(it.k) return list proc isCompatibleIdent(s: string): bool = if s.len == 0 or s[0] notin AsciiAlpha + {'_', '$'}: return false for i in 1 ..< s.len: if s[i] notin AsciiAlphaNumeric + {'_', '$'}: return false return true const ValidBare = AsciiAlphaNumeric + {'-', '_'} proc setError(cp: var ConfigParser; msg: string) = #TODO add line etc later? cp.error = cp.filename & "(" & $cp.line & "): " & msg template err(cp: var ConfigParser; msg: string): untyped = cp.setError(msg) err() proc warn(cp: var ConfigParser; msg: string) = cp.warnings.add(cp.filename & "(" & $cp.line & "): " & msg) proc expect(cp: var ConfigParser; c: char; line: string; n: var int): Opt[void] = let m = n if m >= line.len: return cp.err("expected `" & c & "', got end of line") let nc = line[m] if nc != c: return cp.err("expected `" & c & "', got `" & nc & "'") inc n ok() proc expectEOL(cp: var ConfigParser; line: string; n: int): Opt[void] = if n < line.len and line[n] != '#': return cp.err("unexpected character `" & line[n] & '\'') ok() proc skipTomlBlanks(line: openArray[char]; n: int): int = var n = n while n < line.len: if line[n] notin {' ', '\t'}: break inc n n proc consumeEscape(cp: var ConfigParser; line: openArray[char]; c: char; res: var string; n: int): Opt[n] = var n = n case c of 'b': res &= '\b' of 't': res &= '\t' of 'n': res &= '\n' of 'f': res &= '\f' of 'r': res &= '\r' of '"': res &= '"' of '\\': res &= '\\' of 'u', 'U': var last = n + 4 if c == 'U': last = n + 8 let c = line[n] inc n var num = 0'u32 let val = hexValue(c) if val == -1: return cp.err("invalid escaped codepoint: " & $c) num = uint32(val) while n < last: let val = hexValue(line[n]) if val == -1: break num *= 0x10 num += uint32(val) inc n if n != last: return cp.err("invalid escaped length") if num > 0x10FFFF or num in 0xD800'u32..0xDFFF'u32: return cp.err("invalid escaped codepoint: " & $num) res.addUTF8(num) of '$': res &= "\\$" # special case for substitution in paths else: return cp.err("invalid escape sequence \\" & c) ok(n) # Consume a string and store it in cp.buf. # If `camel' is true, the buffer is converted to camel-case from # kebab-case. proc consumeKeyString(cp: var ConfigParser; camel: bool; line: string; first: char; n: int): Opt[int] = var n = n var escape = false var upper = false while n < line.len: var c = line[n] inc n if escape: n = ?cp.consumeEscape(line, c, cp.buf, n) escape = false elif c == first: break elif first == '"' and c == '\\': escape = true elif c == '-' and camel: upper = true else: if upper: c = c.toUpperAscii() upper = false cp.buf &= c if escape: return cp.err("invalid escape sequence \\ LF") ok(n) # Consume a bare token, and store it (optionally camel-cased) in cp.buf. proc consumeBare(cp: var ConfigParser; camel: bool; line: string; n: int): Opt[int] = var n = line.skipTomlBlanks(n) var upper = false while n < line.len: var c = line[n] if c == '-' and camel: upper = true elif c in ValidBare: if upper: c = c.toUpperAscii() upper = false cp.buf &= c else: break inc n ok(n) proc consumeKey(cp: var ConfigParser; camel: bool; line: string; n: int): Opt[int] = var n = line.skipTomlBlanks(n) if n >= line.len: return cp.err("key expected") cp.buf.setLen(0) let c = line[n] if c in {'"', '\''}: n = ?cp.consumeKeyString(camel, line, c, n + 1) else: n = ?cp.consumeBare(camel, line, n) ok(line.skipTomlBlanks(n)) proc consumeString(cp: var ConfigParser; line: string; first: char; n: int): Opt[int] = var n = n var escape = false var multiline = false var start = true if cp.states.len > 0 and cp.states[^1] in {tsMultiStringSimple, tsMultiStringDouble}: multiline = true start = false elif line.startsWith("\"\"", n): cp.states.add(tsMultiStringDouble) multiline = true n += 2 elif line.startsWith("''", n): cp.states.add(tsMultiStringSimple) multiline = true n += 2 if start: cp.buf.setLen(0) while n < line.len: var c = line[n] inc n if escape: n = ?cp.consumeEscape(line, c, cp.buf, n) escape = false elif c == first: if not multiline: return ok(n) if n + 1 < line.len and line[n] == first and line[n + 1] == first: n += 2 doAssert cp.states.pop() in {tsMultiStringSimple, tsMultiStringDouble} return ok(n) cp.buf &= c elif first == '"' and c == '\\': escape = true else: cp.buf &= c if escape: return cp.err("invalid escape sequence \\ LF") if not multiline: return cp.err("unexpected end of line") if not start: cp.buf &= '\n' ok(n) proc parseSection(cp: var ConfigParser; key: string): Opt[ConfigSection] = let section = strictParseEnum[ConfigSection](key).get(csNone) if section == csNone: return cp.err("unknown section " & key) ok(section) proc parseOption(cp: var ConfigParser; section: ConfigSection; key: string): Opt[ConfigOption] = var x = parseOption(key) if x.isErr: # retry ambiguous names let full = $section & '.' & key x = parseOption(full) if x.isErr: cp.warn("unknown option " & camelToKebabCase(full)) return ok(coAddEntry) # dummy value let opt = x.get if opt.section != section and not (section == csSiteconf and opt in SiteconfOptions): let kebab = camelToKebabCase(key) cp.warnings.add("unknown option " & $section & '.' & kebab & ", maybe try " & $opt.section & '.' & kebab & '?') return ok(coAddEntry) # dummy value if section in {csSiteconf, csOmnirule}: if opt in cp.ruleOptionsSeen: let kebab = camelToKebabCase(key) return cp.err("re-definition of option " & kebab) cp.ruleOptionsSeen.incl(opt) else: if opt in cp.optionsSeen: let kebab = camelToKebabCase(key) return cp.err("re-definition of option " & $section & '.' & kebab) cp.optionsSeen.incl(opt) x proc addRuleEntry(cp: var ConfigParser) = cp.entries.add(ConfigEntry( section: cp.section, opt: coAddEntry, t: cocStr, str: move(cp.buf) )) cp.entryStart = cp.line cp.ruleOptionsSeen.incl(coAddEntry) proc checkRuleRegex(cp: var ConfigParser): Opt[void] = if coAddEntry in cp.ruleOptionsSeen: let intersection = {coUrl, coHost, coMatch} * cp.ruleOptionsSeen if intersection == {}: cp.line = cp.entryStart return cp.err("missing match regex for " & $cp.section) if intersection notin [{coUrl}, {coHost}, {coMatch}]: cp.line = cp.entryStart return cp.err("too many match regexes for " & $cp.section) ok() proc parseKey(cp: var ConfigParser; single, tableArray: bool; line: string; n: int): Opt[int] = var n = n var section = cp.section if section == csNone: n = ?cp.consumeKey(camel = false, line, n) section = cp.parseSection(cp.buf).get(csNone) if section == csNone: if cp.buf != "include": return err() cp.opt = coInclude cp.section = section if single or n >= line.len or line[n] != '.': if section in cp.sectionsSeen: cp.warn("re-definition of section " & $section) return ok(n) if not tableArray and section notin {csSiteconf, csOmnirule}: # Duplicate sections are invalid TOML for siteconf/omnirule too, # but the old parser accepted them. cp.sectionsSeen.incl(section) inc n case section of csSiteconf, csOmnirule: if coAddEntry notin cp.ruleOptionsSeen: n = ?cp.consumeKey(camel = false, line, n) if cp.keysSeen[section].containsOrIncl(cp.buf): return cp.err("duplicate key " & $section & '.' & cp.buf) cp.addRuleEntry() if single or n >= line.len or line[n] != '.': return ok(n) inc n of csCmd: n = ?cp.consumeKey(camel = false, line, n) if not cp.buf.isCompatibleIdent(): return cp.err("invalid command name: " & cp.buf) if cp.key.len > 0: cp.key &= '.' cp.key &= cp.buf while n < line.len and line[n] == '.': inc n n = ?cp.consumeKey(camel = false, line, n) if not cp.buf.isCompatibleIdent(): return cp.err("invalid command name: " & cp.buf) cp.key &= '.' cp.key &= cp.buf if cp.keysSeen[section].containsOrIncl(cp.key): return cp.err("duplicate command") return ok(n) of csPage, csLine: if cp.key.len > 0: return cp.err("unexpected nested key for section " & $section) n = ?cp.consumeKey(camel = false, line, n) var warnings: seq[string] cp.key = parseKeyComb(cp.buf, warnings) for warning in warnings: cp.warn(warning) if cp.keysSeen[section].containsOrIncl(cp.key): return cp.err("duplicate keybinding") return ok(n) else: discard if cp.opt == coAddEntry: n = ?cp.consumeKey(camel = true, line, n) cp.opt = ?cp.parseOption(cp.section, cp.buf) if single or n >= line.len or line[n] != '.': return ok(n) inc n if cp.opt.optionType == cotHeaders: n = ?cp.consumeKey(camel = false, line, n) cp.key = move(cp.buf) ok(n) proc parseConfigSection(cp: var ConfigParser; line: string; n: int): Opt[void] = var n = n if n >= line.len: return cp.err("unexpected end of line") let c = line[n] let tableArray = c == '[' if tableArray: inc n ?cp.checkRuleRegex() cp.buf.setLen(0) cp.ruleOptionsSeen = {} cp.section = csNone cp.opt = coAddEntry n = ?cp.parseKey(single = false, tableArray, line, n) let section = cp.section if tableArray: if section notin {csSiteconf, csOmnirule}: return cp.err("unexpected table array " & $section & ", maybe try [" & $section & "]") if coAddEntry in cp.ruleOptionsSeen: return cp.err("unexpected name, maybe try [[" & $section & "]]") cp.buf = $cp.tableArrayCount[section] inc cp.tableArrayCount[section] cp.addRuleEntry() ?cp.expect(']', line, n) if tableArray: ?cp.expect(']', line, n) n = line.skipTomlBlanks(n) cp.expectEOL(line, n) proc typeCheck(cp: var ConfigParser; t: TomlType): Opt[void] = let vt = cp.tt if vt != t: return cp.err("invalid type (got " & $vt & ", expected " & $t & ")") ok() proc typeCheck(cp: var ConfigParser; t: set[TomlType]): Opt[void] = let vt = cp.tt if vt notin t: return cp.err("invalid type (got " & $vt & ", expected " & $t & ")") ok() proc parseBool(cp: var ConfigParser; x: var bool): Opt[void] = ?cp.typeCheck(ttBoolean) x = cp.bval ok() proc parseBoolAuto(cp: var ConfigParser; x: var BoolAuto): Opt[void] = if cp.tt == ttString and cp.buf == "auto": x = baAuto else: ?cp.typeCheck(ttBoolean) x = BoolAuto(uint8(cp.bval) + 1) ok() proc parseCharset(cp: var ConfigParser; x: var Charset): Opt[void] = ?cp.typeCheck(ttString) let charset = getCharset(cp.buf) if charset == csUnknown and cp.buf != "auto": # auto represented as unknown return cp.err("unknown charset '" & cp.buf & "'") x = charset ok() proc parseEnum[T: enum](cp: var ConfigParser; x: var T): Opt[void] = let e = if cp.tt == ttBoolean: strictParseEnum[T]($cp.bval) else: ?cp.typeCheck(ttString) strictParseEnum[T](cp.buf) if e.isErr: var buf = "invalid value '" & cp.buf & "', expected one of [" for e in T: buf &= '"' buf &= $e buf &= "\", " buf.setLen(buf.high) buf[^1] = ']' return cp.err(buf) x = e.get ok() proc parseColorModeAuto(cp: var ConfigParser; x: var ColorModeAuto): Opt[void] = if cp.tt == ttString and cp.buf == "auto": x = ColorModeAuto(0) else: var y: ColorMode ?cp.parseEnum(y) x = ColorModeAuto(uint8(y) + 1) ok() proc parseImageModeAuto(cp: var ConfigParser; x: var ImageModeAuto): Opt[void] = if cp.tt == ttString and cp.buf == "auto": x = ImageModeAuto(0) else: var y: ImageMode ?cp.parseEnum(y) x = ImageModeAuto(uint8(y) + 1) ok() proc parseRegexCase(cp: var ConfigParser; x: var RegexCase): Opt[void] = ?cp.typeCheck({ttString, ttBoolean}) if cp.tt == ttBoolean: x = if cp.bval: rcIgnore else: rcStrict else: # string if cp.buf != "auto": return cp.err("invalid value '" & cp.buf & "'") x = rcAuto ok() proc parseSet[T: enum](cp: var ConfigParser; x: var set[T]): Opt[void] = ?cp.typeCheck({ttString, ttArray}) if cp.tt == ttString: var e: T ?cp.parseEnum(e) x = {e} return ok() cp.tt = ttString var tmp: set[T] = {} for s in cp.arr.mitems: cp.buf = move(s) var e: T ?cp.parseEnum(e) tmp.incl(e) x = tmp ok() proc parseInt32(cp: var ConfigParser; x: var int32): Opt[void] = ?cp.typeCheck(ttInteger) x = cp.ival ok() proc parseInt32Auto(cp: var ConfigParser; x: var int32): Opt[void] = if cp.tt == ttString and cp.buf == "auto": x = 0'i32 else: ?cp.typeCheck(ttInteger) if cp.ival <= 0: return cp.err("positive value expected") x = cp.ival ok() proc parseFormatModeAuto(cp: var ConfigParser; x: var FormatModeAuto): Opt[void] = if cp.tt == ttString and cp.buf == "auto": x = FormatModeAuto(0'u32) else: var y: FormatMode ?cp.parseSet(y) x = FormatModeAuto(cast[uint32](y) + 1) ok() proc parseCSSColor(cp: var ConfigParser; x: var CSSColor): Opt[void] = ?cp.typeCheck(ttString) var ctx = initCSSParser(cp.buf) let c = ctx.parseColor() if c.isErr or ctx.has() or c.get.t == cctCurrent: return cp.err("invalid color '" & cp.buf & "'") x = c.get ok() proc parseRGBColorAuto(cp: var ConfigParser; x: var RGBColorAuto): Opt[void] = ?cp.typeCheck(ttString) if cp.buf == "auto": x = RGBColorAuto(0) else: let c = parseLegacyColor(cp.buf) if c.isErr: return cp.err("invalid color '" & cp.buf & "'") x = RGBColorAuto(uint64(c.get) + 1) ok() proc parseString(cp: var ConfigParser; x: var string): Opt[void] = ?cp.typeCheck(ttString) x = move(cp.buf) ok() proc parseStylesheet(cp: var ConfigParser; x: var string): Opt[void] = ?cp.typeCheck(ttString) var y = "" var parser = initCSSParser(cp.buf) var j = 0 for it in parser.consumeImports(): var parser2 = initCSSParserSink(it.prelude) if parser2.skipBlanksCheckHas().isErr: break let tok = parser2.consume() if parser2.skipBlanksCheckDone().isErr: break if tok.t != cttString: return cp.err("wrong CSS import (unexpected token)") let path = ChaPath(tok.s).unquote(cp.config.dir) if path.isErr: return cp.err("wrong CSS import (" & tok.s & " is not a valid path)") let ps = newPosixStream(path.get) if ps == nil: return cp.err("wrong CSS import (file " & tok.s & " not found)") y &= ps.readAll() j = parser.i y &= cp.buf.substr(j) x = move(y) ok() proc parsePath(cp: var ConfigParser; x: var string): Opt[void] = ?cp.typeCheck(ttString) var y = ChaPath(cp.buf).unquote(cp.config.dir) if y.isErr: return cp.err(y.error) x = move(y.get) ok() proc parseCodepointSet(cp: var ConfigParser; x: var string): Opt[void] = ?cp.typeCheck(ttString) var seen = initHashSet[uint32]() var nseen = 0 for u in cp.buf.points: if seen.containsOrIncl(u): return cp.err("duplicate codepoint '" & u.toUTF8() & "'") inc nseen if nseen > int(cint.high): return cp.err("too many values") x = move(cp.buf) ok() proc parseCharsetSeq(cp: var ConfigParser; x: var seq[Charset]): Opt[void] = ?cp.typeCheck({ttString, ttArray}) if cp.tt == ttString: var charset: Charset ?cp.parseEnum(charset) x = @[charset] else: x = @[] cp.tt = ttString for it in cp.arr.mitems: cp.buf = move(it) var charset: Charset ?cp.parseCharset(charset) x.add(charset) ok() proc parsePathSeq(cp: var ConfigParser; x: var seq[string]): Opt[void] = ?cp.typeCheck({ttString, ttArray}) if cp.tt == ttString: var s: string ?cp.parsePath(s) x = @[move(s)] else: x = @[] for it in cp.arr: var y = ChaPath(it).unquote(cp.config.dir) if y.isErr: return cp.err(y.error) x.add(move(y.get)) ok() proc parseHeaders(cp: var ConfigParser; x: var ConfigHeadersInit): Opt[void] = if x == nil: x = ConfigHeadersInit() if cp.tt == ttTable: x.clear = true else: ?cp.typeCheck(ttString) x.s.add((move(cp.key), move(cp.buf))) ok() proc parseURL(cp: var ConfigParser; x: var URL): Opt[void] = ?cp.typeCheck(ttString) if cp.buf == "": x = nil else: x = parseURL0(cp.buf) if x == nil: return cp.err("invalid URL " & cp.buf) ok() proc parseRegex(cp: var ConfigParser; x: var Regex): Opt[void] = ?cp.typeCheck(ttString) var y = compileMatchRegex(cp.buf) if y.isErr: return cp.err("invalid regex (" & y.error & ")") x = move(y.get) ok() proc parseFunction(cp: var ConfigParser; x: var pointer): Opt[void] = ?cp.typeCheck(ttString) let fun = cp.ctx.eval(cp.buf, "<config>", JS_EVAL_TYPE_GLOBAL) if JS_IsException(fun): return cp.err(cp.ctx.getExceptionMsg()) if not JS_IsFunction(cp.ctx, fun): return cp.err("not a function") x = JS_VALUE_GET_PTR(fun) ok() proc saveKeyState(cp: var ConfigParser) = # state to be restored after the current option is flushed cp.beforeKey = BeforeKey( keyLen: cp.key.len, section: cp.section, opt: cp.opt, addEntrySeen: coAddEntry in cp.ruleOptionsSeen ) proc parseKVPair(cp: var ConfigParser; single: bool; line: string; n: var int): Opt[void] = let nstates = cp.states.len cp.saveKeyState() n = ?cp.parseKey(single, tableArray = false, line, n) ?cp.expect('=', line, n) n = line.skipTomlBlanks(n) ?cp.consumeValue(line, n) n = line.skipTomlBlanks(n) # if nesting increased (e.g. array), we defer flushing the option until # the line that decreases it. if nstates != cp.states.len: return ok() cp.parseConfigValue() proc consumeArray(cp: var ConfigParser; line: string; n: var int): Opt[void] = let nstates = cp.states.len while true: n = line.skipTomlBlanks(n) if n >= line.len: break let c = line[n] if c == ']': inc n cp.states.setLen(cp.states.high) cp.tt = ttArray break if c == '#': break if not cp.commaSeen: ?cp.expect(',', line, n) n = line.skipTomlBlanks(n) cp.commaSeen = true if n >= line.len or line[n] == '#': break ?cp.consumeValue(line, n) cp.commaSeen = false if nstates != cp.states.len: return cp.err("unexpected nested array") ?cp.typeCheck(ttString) cp.arr.add(move(cp.buf)) ok() proc consumeTable(cp: var ConfigParser; line: string; n: var int): Opt[void] = while true: n = line.skipTomlBlanks(n) if n >= line.len: break let c = line[n] if c == '}': inc n cp.states.setLen(cp.states.high) cp.tt = ttTable if cp.key.len > 0: cp.key.setLen(max(cp.key.rfind('.'), 0)) elif cp.opt != coAddEntry: cp.opt = coAddEntry elif coAddEntry in cp.ruleOptionsSeen: ?cp.checkRuleRegex() cp.ruleOptionsSeen.excl(coAddEntry) else: cp.section = csNone cp.saveKeyState() break if c == '#': break if not cp.commaSeen: ?cp.expect(',', line, n) n = line.skipTomlBlanks(n) cp.commaSeen = true if n >= line.len or line[n] == '#': break ?cp.parseKVPair(single = true, line, n) cp.commaSeen = false ok() proc consumeValue(cp: var ConfigParser; line: string; n: var int): Opt[void] = if n >= line.len: return cp.err("value expected") let c = line[n] case c of '[': cp.commaSeen = true inc n cp.states.add(tsArray) cp.arr.setLen(0) return cp.consumeArray(line, n) of '{': cp.commaSeen = true inc n cp.states.add(tsTable) if cp.opt == coAddEntry and cp.section in {csSiteconf, csOmnirule}: # Note: the old parser could clear all objects, but this seems like # a fairly useless feature. cp.entries.add(ConfigEntry(section: cp.section, t: cocClear)) return cp.consumeTable(line, n) of '+', '-', AsciiDigit: cp.tt = ttInteger let val = atod(cstring(line), n, 0, JS_ATOD_INT_ONLY or JS_ATOD_ACCEPT_UNDERSCORES) if classify(val) in {fcInf, fcNegInf, fcNan}: return cp.err("invalid number") let ival = int64(val) if ival notin int64(int32.low)..int64(int32.high): return cp.err("number out of bounds") cp.ival = int32(ival) of AsciiAlpha: cp.buf.setLen(0) n = ?cp.consumeBare(camel = false, line, n) if cp.buf == "true": cp.tt = ttBoolean cp.bval = true elif cp.buf == "false": cp.tt = ttBoolean cp.bval = false elif cp.laxnames: cp.tt = ttString else: return cp.err("invalid token: " & cp.buf) of '"', '\'': cp.tt = ttString n = ?cp.consumeString(line, c, n + 1) else: return cp.err("unexpected character in value: `" & c & "'") ok() proc addBit(cp: var ConfigParser): var ConfigOptionBit = cp.entries.add(ConfigEntry(section: cp.section, opt: cp.opt, t: cocBit)) cp.entries[^1].bit proc addHWord(cp: var ConfigParser): var ConfigOptionHWord = cp.entries.add(ConfigEntry(section: cp.section, opt: cp.opt, t: cocHWord)) cp.entries[^1].hword proc addWord(cp: var ConfigParser): var ConfigOptionWord = cp.entries.add(ConfigEntry(section: cp.section, opt: cp.opt, t: cocWord)) cp.entries[^1].word proc addStr(cp: var ConfigParser): var string = cp.entries.add(ConfigEntry(section: cp.section, opt: cp.opt, t: cocStr)) cp.entries[^1].str proc addCharsetSeq(cp: var ConfigParser): var seq[Charset] = cp.entries.add(ConfigEntry( section: cp.section, opt: cp.opt, t: cocCharsetSeq )) cp.entries[^1].charsetSeq proc addStrSeq(cp: var ConfigParser): var seq[string] = cp.entries.add(ConfigEntry(section: cp.section, opt: cp.opt, t: cocStrSeq)) cp.entries[^1].strSeq proc addHeaders(cp: var ConfigParser): var ConfigHeadersInit = if cp.entries.len == 0 or cp.entries[^1].opt != cp.opt: cp.entries.add(ConfigEntry(section: cp.section, opt: cp.opt, t: cocHeaders)) cp.entries[^1].headers proc addURL(cp: var ConfigParser): var URL = cp.entries.add(ConfigEntry(section: cp.section, opt: cp.opt, t: cocURL)) cp.entries[^1].url proc addRegex(cp: var ConfigParser): var Regex = cp.entries.add(ConfigEntry(section: cp.section, opt: cp.opt, t: cocRegex)) cp.entries[^1].regex proc addFunction(cp: var ConfigParser): var pointer = cp.entries.add(ConfigEntry(section: cp.section, opt: cp.opt, t: cocFunction)) cp.entries[^1].fun proc addCmdInit(cp: var ConfigParser): var seq[tuple[k: string; fun: pointer]] = if cp.entries.len == 0 or cp.entries[^1].t != cocCmdInit: cp.entries.add(ConfigEntry( section: cp.section, opt: cp.opt, t: cocCmdInit )) cp.entries[^1].cmdInit proc parseConfigValue1(cp: var ConfigParser): Opt[void] = let ot = optionType(cp.opt) return case ot of cotBool: cp.parseBool(cp.addBit().bool) of cotBoolAuto: cp.parseBoolAuto(cp.addBit().boolAuto) of cotCharset: cp.parseCharset(cp.addBit().charset) of cotColorModeAuto: cp.parseColorModeAuto(cp.addBit().colorModeAuto) of cotCookieMode: cp.parseEnum(cp.addBit().cookieMode) of cotFormatMode: cp.parseSet(cp.addBit().formatMode) of cotHeadlessMode: cp.parseEnum(cp.addBit().headlessMode) of cotImageModeAuto: cp.parseImageModeAuto(cp.addBit().imageModeAuto) of cotMetaRefresh: cp.parseEnum(cp.addBit().metaRefresh) of cotRegexCase: cp.parseRegexCase(cp.addBit().regexCase) of cotScriptingMode: cp.parseEnum(cp.addBit().scriptingMode) of cotInt32: cp.parseInt32(cp.addHWord().int32) of cotInt32Auto: cp.parseInt32Auto(cp.addHWord().int32) of cotFormatModeAuto: cp.parseFormatModeAuto(cp.addHWord().formatModeAuto) of cotCSSColor: cp.parseCSSColor(cp.addWord().cssColor) of cotRGBColorAuto: cp.parseRGBColorAuto(cp.addWord().rgbColorAuto) of cotString: cp.parseString(cp.addStr()) of cotStylesheet: cp.parseStylesheet(cp.addStr()) of cotPath: cp.parsePath(cp.addStr()) of cotCodepointSet: cp.parseCodepointSet(cp.addStr()) of cotCharsetSeq: cp.parseCharsetSeq(cp.addCharsetSeq()) of cotPathSeq: cp.parsePathSeq(cp.addStrSeq()) of cotHeaders: cp.parseHeaders(cp.addHeaders()) of cotURL: cp.parseURL(cp.addURL()) of cotRegex: cp.parseRegex(cp.addRegex()) of cotFunction: cp.parseFunction(cp.addFunction()) proc parseConfigValue(cp: var ConfigParser): Opt[void] = let section = cp.section case section of csCmd: ?cp.typeCheck(ttString) let dotIdx = cp.key.find('.') if dotIdx == -1: cp.warn("please move cmd." & cp.key & " to your own namespace (e.g. [cmd.me]) to avoid name clashes") elif cp.key.startsWith("pager.") or cp.key.startsWith("buffer."): cp.warn("the namespace " & cp.key.until('.') & " is deprecated") elif AsciiUpperAlpha in cp.key.toOpenArray(0, dotIdx): cp.warn("the first component of namespaces must be lower-case") let ctx = cp.ctx let fun = if cp.buf.len > 0: let val = ctx.eval(cp.buf, "<" & cp.key & ">", JS_EVAL_TYPE_GLOBAL) if JS_IsException(val): return cp.err(ctx.getExceptionMsg()) if not JS_IsFunction(ctx, val): JS_FreeValue(ctx, val) return cp.err("not a function") JS_VALUE_GET_PTR(val) else: nil cp.addCmdInit().add((move(cp.key), fun)) of csPage, csLine: ?cp.typeCheck(ttString) let ctx = cp.ctx let val = ctx.evalCmdDecl(cp.buf) if JS_IsException(val): return cp.err(ctx.getExceptionMsg()) #TODO this won't fly for dynamic reloading let map = cp.config.actionMap[section] map.t.add(Action(k: move(cp.key), val: val, n: map.num)) inc map.num elif cp.opt != coAddEntry: # add entry here means "not found" ?cp.parseConfigValue1() # reset to state before this key cp.section = cp.beforeKey.section cp.opt = cp.beforeKey.opt if not cp.beforeKey.addEntrySeen: ?cp.checkRuleRegex() cp.ruleOptionsSeen.excl(coAddEntry) cp.key.setLen(cp.beforeKey.keyLen) ok() proc applyEntry(ctx: JSContext; config: Config; entry: var ConfigEntry) = let section = entry.section let opt = entry.opt if section in {csSiteconf, csOmnirule}: if entry.t == cocStr and opt == coAddEntry: let rule = ConfigRule(fun: JS_UNDEFINED, name: move(entry.str)) if config.ruleSeen.containsOrIncl(rule.name): # replace ctx.remove(config.lists[section], rule.name) config.lists[section].add(rule) else: let rule = config.lists[section].tail case entry.t of cocRegex: if opt == coHost: # smUrl is the default rule.matchType = smHost rule.regex.bytecode = move(entry.regex.bytecode) of cocFunction: rule.fun = JS_MKPTR(JS_TAG_OBJECT, entry.fun) of cocClear: ctx.clear(config.lists[section]) else: assert opt in SiteconfOptions rule.entries.add(entry) elif section == csCmd: assert entry.t == cocCmdInit if config.cmdInit.len == 0: config.cmdInit = move(entry.cmdInit) else: config.cmdInit.add(entry.cmdInit) else: case entry.t of cocBit: config.bits[opt] = entry.bit of cocHWord: config.hwords[opt] = entry.hword of cocWord: config.words[opt] = entry.word of cocStr: config.strs[opt] = move(entry.str) of cocStrSeq: config.strSeqs[opt] = move(entry.strSeq) of cocCharsetSeq: config.documentCharset = move(entry.charsetSeq) of cocHeaders: let init = entry.headers if init.clear: config.defaultHeaders = newHeaders(hgRequest, init.s) else: for it in init.s: config.defaultHeaders[it.name] = it.value of cocURL: config.proxy = move(entry.url) of cocClear, cocRegex, cocFunction, cocCmdInit: assert false proc applyEntries(ctx: JSContext; config: Config; entries: var seq[ConfigEntry]) = for entry in entries.mitems: ctx.applyEntry(config, entry) proc parseConfigRegular(cp: var ConfigParser; line: string): Opt[void] = var n = line.skipTomlBlanks(0) if n >= line.len: return ok() case (let c = line[n]; c) of '#': return ok() of '[': inc n return cp.parseConfigSection(line, n) of '"', '\'', ValidBare: ?cp.parseKVPair(single = false, line, n) return cp.expectEOL(line, n) else: return cp.err("unexpected character `" & c & "'") proc parseConfigLine(cp: var ConfigParser; line: string): Opt[void] = if cp.states.len == 0: return cp.parseConfigRegular(line) var n = 0 while cp.states.len > 0 and n < line.len and line[n] != '#': let nstates = cp.states.len case cp.states[^1] of tsTable: ?cp.consumeTable(line, n) of tsArray: ?cp.consumeArray(line, n) of tsMultiStringSimple: n = ?cp.consumeString(line, '\'', n) of tsMultiStringDouble: n = ?cp.consumeString(line, '"', n) if nstates > cp.states.len: ?cp.parseConfigValue() n = line.skipTomlBlanks(n) cp.expectEOL(line, n) proc initConfigParser(config: Config; dir: string; ctx: JSContext; name: string; laxnames: bool): ConfigParser = ConfigParser( config: config, dir: dir, ctx: ctx, filename: dir / name, line: 1, laxnames: laxnames, sectionsSeen: {}, opt: coAddEntry ) proc parseFile(cp: var ConfigParser; file: ChaFile): Opt[void] = var line: string while ?file.readLine(line): ?cp.parseConfigLine(line) inc cp.line ok() proc cleanup(cp: var ConfigParser) = for entry in cp.entries: case entry.t of cocFunction: if entry.fun != nil: JS_FreeValue(cp.ctx, JS_MKPTR(JS_TAG_OBJECT, entry.fun)) of cocCmdInit: for it in entry.cmdInit: if it.fun != nil: JS_FreeValue(cp.ctx, JS_MKPTR(JS_TAG_OBJECT, it.fun)) else: discard if cp.error == "": cp.error = "failed to read config" proc parseConfig*(config: Config; dir: string; file: ChaFile; warnings: var seq[string]; ctx: JSContext; name: string; laxnames = false): Err[string] = var cp = initConfigParser(config, dir, ctx, name, laxnames) if cp.parseFile(file).isErr: cp.cleanup() return err(move(cp.error)) ctx.applyEntries(config, cp.entries) #TODO warn about recursive includes # or just remove include var includes = move(config{"include"}) for s in includes: let x = chafile.fopen(s, "r") if x.isErr: return err("include file not found: " & s) let f = x.get ?config.parseConfig(dir, f, warnings, ctx, s.afterLast('/')) f.close() warnings.add(cp.warnings) ok() proc parseConfig*(config: Config; dir: string; buf: openArray[char]; warnings: var seq[string]; ctx: JSContext; name: string; laxnames = false): Err[string] = var cp = initConfigParser(config, dir, ctx, name, laxnames) for line in buf.split('\n'): if cp.parseConfigLine(line).isErr: for entry in cp.entries: if entry.t == cocFunction and entry.fun != nil: JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, entry.fun)) return err(move(cp.error)) inc cp.line ctx.applyEntries(config, cp.entries) warnings.add(cp.warnings) ok() proc openConfig*(dir, dataDir: var string; override: string; warnings: var seq[string]): Opt[ChaFile] = if override.len > 0: if override[0] == '/': dir = parentDir(override) dataDir = dir return chafile.fopen(override, "r") let path = myposix.getcwd() / override dir = parentDir(path) dataDir = dir return chafile.fopen(path, "r") dir = getEnvEmpty("CHA_DIR") if dir != "": # mainly just to behave sanely in nested invocations dataDir = getEnvEmpty("CHA_DATA_DIR", dir) return chafile.fopen(dir / "config.toml", "r") dir = getEnvEmpty("XDG_CONFIG_HOME") if dir != "": dir = dir / "chawan" else: dir = expandPath("~/.config/chawan") if (let fs = chafile.fopen(dir / "config.toml", "r"); fs.isOk): let s = getEnvEmpty("XDG_DATA_HOME") if s != "": dataDir = s / "chawan" else: dataDir = expandPath("~/.local/share/chawan") return fs dir = expandPath("~/.chawan") dataDir = dir return chafile.fopen(dir / "config.toml", "r") # called at pager init proc initCommands(ctx: JSContext; config: Config): Opt[void] {.jsfunc.} = let global = JS_GetGlobalObject(ctx) let obj = JS_GetPropertyStr(ctx, global, "cmd") JS_FreeValue(ctx, global) if JS_IsException(obj): JS_FreeValue(ctx, obj) return err() for (k, cmd) in config.cmdInit.mritems: var objIt = JS_DupValue(ctx, obj) let name = k.afterLast('.') if name.len < k.len: for ss in k.substr(0, k.high - name.len - 1).split('.'): var prop = JS_GetPropertyStr(ctx, objIt, cstring(ss)) if JS_IsUndefined(prop): prop = JS_NewObject(ctx) case ctx.definePropertyE(objIt, ss, JS_DupValue(ctx, prop)) of dprException: JS_FreeValue(ctx, obj) return err() else: discard if JS_IsException(prop): JS_FreeValue(ctx, obj) return err() JS_FreeValue(ctx, objIt) objIt = prop if cmd == nil: continue let dpr = ctx.definePropertyE(objIt, name, JS_MKPTR(JS_TAG_OBJECT, cmd)) JS_FreeValue(ctx, objIt) cmd = nil if dpr == dprException: JS_FreeValue(ctx, obj) return err() JS_FreeValue(ctx, obj) config.cmdInit = @[] ctx.sort(config.page) ctx.sort(config.line) ok() const PageCommands = """ y u copyCursorLink y I copyCursorImage h cursorLeft j cursorDown k cursorUp l cursorRight Left cursorLeft Down cursorDown Up cursorUp Right cursorRight C-n cursorDown C-p cursorUp 0 cursorLineBegin Home cursorLineBegin ^ cursorLineTextStart $ cursorLineEnd End cursorLineEnd b cursorViWordBegin e cursorViWordEnd w cursorNextViWord B cursorBigWordBegin E cursorBigWordEnd W cursorNextBigWord [ cursorPrevLink ] cursorNextLink { cursorPrevParagraph } cursorNextParagraph H cursorTop M cursorMiddle L cursorBottom g 0 cursorLeftEdge g c cursorMiddleColumn g $ cursorRightEdge C-d halfPageDown C-u halfPageUp C-f pageDown C-b pageUp PageDown pageDown PageUp pageUp z H pageLeft z L pageRight < pageLeft > pageRight C-e scrollDown C-y scrollUp J scrollDown K scrollUp s e editScreen s E editSource s RET saveLink s LF saveLink s s saveScreen s S saveSource m mark ` gotoMark ' gotoMarkY z h scrollLeft z l scrollRight - scrollLeft + scrollRight RET click LF click c rightClick C toggleMenu I viewImage s I saveImage M-i toggleImages M-j toggleScripting M-k toggleCookie : markURL r redraw R reshape C-c cancel g g gotoLineOrStart G gotoLineOrEnd | gotoColumnOrBegin z . centerLineBegin z RET raisePageBegin z LF raisePageBegin z - lowerPageBegin z z centerLine z t raisePage z b lowerPage z + nextPageBegin z ^ previousPageBegin y copySelection v cursorToggleSelection V cursorToggleSelectionLine C-v cursorToggleSelectionBlock q quit C-z suspend C-l load M-l loadCursor C-k webSearch M-a addBookmark M-b openBookmarks C-h openHistory M-u dupeBuffer U reloadBuffer C-g lineInfo \ toggleSource D discardBuffer d, discardBufferPrev d. discardBufferNext M-d discardTree , prevBuffer . nextBuffer M-c enterCommand / isearchForward ? isearchBackward n searchNext N searchPrev u peekCursor s u showFullAlert C-w toggleWrap M-y copyURL M-p gotoClipboardURL f toggleLinkHints C-a cursorSearchWordForward * cursorSearchWordForward # cursorSearchWordBackward """ const LineCommands = """ RET line.submit LF line.submit C-h line.backspace C-? line.backspace C-d line.delete C-c line.copyOrCancel C-g line.cancel M-b line.prevWord M-f line.nextWord C-b line.backward C-f line.forward C-u line.clear C-x C-? line.clear C-x C-e line.openEditor C-_ line.clear M-k line.clear C-k line.kill C-w line.clearWord M-C-h line.clearWord M-C-? line.clearWord M-d line.killWord C-a line.begin Home line.begin C-e line.end End line.end C-v line.escape C-p line.prevHist C-n line.nextHist M-c toggleCommandMode Down line.nextHist Up line.prevHist Right line.forward Left line.backward C-Left line.prevWord C-Right line.nextWord """ # boolean options that initialize to true const ConfigInitTrue = [ coConsoleBuffer, coWrap, coShowDownloadPanel, coViNumericPrefix, coHighlightMarks, coShowCursorPosition, coShowHoverLink, coStyling, coHistory ] const ConfigInitInt32 = { coHistorySize: 100'i32, coMaxRedirect: 10, coMaxNetConnections: 12, coWheelScroll: 5, coSideWheelScroll: 5, coMinimumContrast: 100, coColumns: 80, coLines: 24, coPixelsPerColumn: 9, coPixelsPerLine: 18 } const ConfigInitStr = { coVisualHome: "about:chawan", coEditor: "${VISUAL:-${EDITOR:-vi}}", coCopyCmd: "xsel -bi", coPasteCmd: "xsel -bo", coPrependScheme: "https://", coLinkHintChars: "abcdefghijklmnoprstuvxyz", } const ConfigInitPath = { coAutoMailcap: "mailcap", coBookmark: "$CHA_DATA_DIR/bookmark.md", coHistoryFile: "$CHA_DATA_DIR/history.uri", coTmpdir: "${TMPDIR:-/tmp}/cha-tmp-$LOGNAME", coCookieFile: "$CHA_DATA_DIR/cookies.txt", coDownloadDir: "${TMPDIR:-/tmp}/", } const ConfigInitPathSeq = { coMailcap: @[ "~/.mailcap", "/etc/mailcap", "/usr/etc/mailcap", "/usr/local/etc/mailcap" ], coMimeTypes: @[ "~/.mime.types", "/etc/mime.types", "/usr/etc/mime.types", "/usr/local/etc/mime.types" ], coUrimethodmap: @["urimethodmap", "~/.urimethodmap", "/etc/urimethodmap"], coCgiDir: @["cgi-bin", "$CHA_LIBEXEC_DIR/cgi-bin"], } proc getConfigOption(ctx: JSContext; this: JSValueConst; magic: cint): JSValue {.cdecl.} = let config = cast[ptr ConfigObj](JS_GetOpaque(this, JS_GetClassID(this))) let opt = cast[ConfigOption](magic) case opt.optionType of cotBool: return ctx.toJS(config.bits[opt].bool) of cotBoolAuto: return ctx.toJS(config.bits[opt].boolAuto) of cotCharset: return ctx.toJS(config.bits[opt].charset) of cotColorModeAuto: return ctx.toJS(config.bits[opt].colorModeAuto) of cotCookieMode: return ctx.toJS(config.bits[opt].cookieMode) of cotFormatMode: return ctx.toJS(config.bits[opt].formatMode) of cotHeadlessMode: return ctx.toJS(config.bits[opt].headlessMode) of cotImageModeAuto: return ctx.toJS(config.bits[opt].imageModeAuto) of cotMetaRefresh: return ctx.toJS(config.bits[opt].metaRefresh) of cotRegexCase: return ctx.toJS(config.bits[opt].regexCase) of cotScriptingMode: return ctx.toJS(config.bits[opt].scriptingMode) of cotInt32: return ctx.toJS(config.hwords[opt].int32) of cotInt32Auto: let i = config.hwords[opt].int32 if i < 0: return JS_NULL return ctx.toJS(i) of cotFormatModeAuto: return ctx.toJS(config.hwords[opt].formatModeAuto) of cotCSSColor: return ctx.toJS(config.words[opt].cssColor) of cotRGBColorAuto: return ctx.toJS(config.words[opt].rgbColorAuto) of cotString, cotStylesheet, cotPath, cotCodepointSet: return ctx.toJS(config.strs[opt]) of cotCharsetSeq: return ctx.toJS(config.documentCharset) of cotPathSeq: return ctx.toJS(config.strSeqs[opt]) of cotHeaders: return ctx.toJS(config.defaultHeaders) of cotURL: return ctx.toJS(config.proxy) of cotRegex, cotFunction: return JS_NULL proc setConfigOption(ctx: JSContext; this, val: JSValueConst; magic: cint): JSValue {.cdecl.} = let config = cast[ptr ConfigObj](JS_GetOpaque(this, JS_GetClassID(this))) let opt = cast[ConfigOption](magic) let res = case opt.optionType of cotBool: ctx.fromJS(val, config.bits[opt].bool) of cotBoolAuto: ctx.fromJS(val, config.bits[opt].boolAuto) of cotCharset: ctx.fromJS(val, config.bits[opt].charset) of cotColorModeAuto: ctx.fromJS(val, config.bits[opt].colorModeAuto) of cotCookieMode: ctx.fromJS(val, config.bits[opt].cookieMode) of cotFormatMode: ctx.fromJS(val, config.bits[opt].formatMode) of cotHeadlessMode: ctx.fromJS(val, config.bits[opt].headlessMode) of cotImageModeAuto: ctx.fromJS(val, config.bits[opt].imageModeAuto) of cotMetaRefresh: ctx.fromJS(val, config.bits[opt].metaRefresh) of cotRegexCase: ctx.fromJS(val, config.bits[opt].regexCase) of cotScriptingMode: ctx.fromJS(val, config.bits[opt].scriptingMode) of cotInt32: ctx.fromJS(val, config.hwords[opt].int32) of cotInt32Auto: if JS_IsNull(val): config.hwords[opt].int32 = -1 fjOk else: ctx.fromJS(val, config.hwords[opt].int32) of cotFormatModeAuto: ctx.fromJS(val, config.hwords[opt].formatModeAuto) of cotCSSColor: ctx.fromJS(val, config.words[opt].cssColor) of cotRGBColorAuto: ctx.fromJS(val, config.words[opt].rgbColorAuto) of cotString, cotStylesheet, cotPath, cotCodepointSet: ctx.fromJS(val, config.strs[opt]) of cotCharsetSeq: ctx.fromJS(val, config.documentCharset) of cotPathSeq: ctx.fromJS(val, config.strSeqs[opt]) of cotHeaders: ctx.fromJS(val, config.defaultHeaders) of cotURL: ctx.fromJS(val, config.proxy) of cotRegex, cotFunction: fjOk if res == fjErr: return JS_EXCEPTION return JS_DupValue(ctx, val) proc addConfigSections(ctx: JSContext; config: Config): Opt[void] = var objs {.noinit.}: array[csBuffer..csStatus, JSValue] for obj in objs.mitems: obj = JS_NewObject(ctx) if JS_IsException(obj): return err() JS_SetOpaque(obj, addr config[]) for opt in ConfigOption.low..coAddEntry.pred: let desc = OptionMap[opt] if desc.section == csNone: continue let obj = objs[desc.section] let s = $opt let start = s.find('.') + 1 let p = cast[cstring](unsafeAddr s[start]) let atom = JS_NewAtomLen(ctx, p, csize_t(s.len - start)) var f: JSCFunctionType f.getter_magic = getConfigOption let get = JS_NewCFunction2(ctx, f.generic, p, 0, JS_CFUNC_getter_magic, cint(opt)) if JS_IsException(get): return err() f.setter_magic = setConfigOption let set = JS_NewCFunction2(ctx, f.generic, p, 0, JS_CFUNC_setter_magic, cint(opt)) if JS_IsException(set): return err() if JS_DefineProperty(ctx, obj, atom, JS_UNDEFINED, get, set, JS_PROP_HAS_GET or JS_PROP_HAS_GET) < 0: return err() ctx.freeValues(get, set) JS_FreeAtom(ctx, atom) let configObj = ctx.toJS(config) for section in csBuffer..csStatus: let s = $section let obj = objs[section] if ctx.defineProperty(configObj, cstring(s), obj) == dprException: return err() JS_FreeValue(ctx, configObj) ok() proc newConfig*(ctx: JSContext; dir, dataDir: string): Config = let config = Config( dir: dir, dataDir: dataDir, actionMap: [ csPage: newActionMap(ctx, PageCommands, ""), csLine: newActionMap(ctx, LineCommands, "writeInputBuffer"), ], documentCharset: @[ csUtf8, csShiftJIS, csEucJP, csIso8859_2 ], defaultHeaders: newHeaders(hgRequest, { "User-Agent": "chawan", "Accept": "text/html, text/*;q=0.5, */*;q=0.4", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en;q=1.0", "Pragma": "no-cache", "Cache-Control": "no-cache" }), ) for it in ConfigInitTrue: config.bits[it].bool = true config.bits[coFormatModeStatus].formatMode = {ffReverse} config.bits[coNoFormatMode].formatMode = {ffOverline} config.words[coHighlightColor].cssColor = ANSIColor(6).cssColor() # cyan for it in ConfigInitInt32: config.hwords[it[0]].int32 = it[1] for it in ConfigInitStr: config.strs[it[0]] = it[1] for it in ConfigInitPath: config.strs[it[0]] = ChaPath(it[1]).unquote(dir).get for it in ConfigInitPathSeq: for path in it[1]: config.strSeqs[it[0]].add(ChaPath(path).unquote(dir).get) config.siteconf.add(ConfigRule( name: "downloads", regex: compileMatchRegex("about:downloads").get, fun: JS_UNDEFINED, entries: @[ConfigEntry( section: csSiteconf, opt: coMetaRefresh, t: cocBit, bit: ConfigOptionBit(metaRefresh: mrAlways) )] )) if ctx.addConfigSections(config).isErr: return nil config proc addConfigModule*(ctx: JSContext): Opt[void] = ?ctx.registerType(ActionMap) ?ctx.registerType(Config) ok() {.pop.} # raises: [] �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/config/conftypes.nim��������������������������������������������������������������0000664�0000000�0000000�00000001067�15202323131�0017711�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������type ColorMode* = enum cmMonochrome = "monochrome" cmANSI = "ansi" cmEightBit = "eight-bit" cmTrueColor = "true-color" HeadlessMode* = enum hmFalse = "false" hmTrue = "true" hmDump = "dump" ScriptingMode* = enum smFalse = "false" smTrue = "true" smApp = "app" CookieMode* = enum cmNone = "false" cmReadOnly = "true" cmSave = "save" MetaRefresh* = enum mrAsk = "ask" mrNever = "never" mrAlways = "always" ImageMode* = enum imNone = "none" imSixel = "sixel" imKitty = "kitty" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/config/cookie.nim�����������������������������������������������������������������0000664�0000000�0000000�00000032121�15202323131�0017143�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/algorithm import std/posix import std/tables import std/times import io/chafile import io/dynstream import io/packetreader import io/packetwriter import types/opt import types/url import utils/twtstr type Cookie* = ref object name: string value: string expires: int64 # unix time domain: string path: string persist: bool secure: bool httpOnly: bool hostOnly: bool isnew: bool skip: bool CookieJar* = ref object name*: string cookies: seq[Cookie] map: Table[string, Cookie] # {host}{path}\t{name} next: CookieJar CookieJarMap* = ref object mtime: int64 jars: Table[string, CookieJar] jarsHead: CookieJar jarsTail: CookieJar transient*: bool # set if there is a failure in parsing cookies # Forward declarations proc getMapKey(cookie: Cookie): string proc sread*(r: var PacketReader; cookieJar: var CookieJar) = var n: bool r.sread(n) if n: cookieJar = CookieJar() r.sread(cookieJar.name) r.sread(cookieJar.cookies) for cookie in cookieJar.cookies: if not cookie.skip: cookieJar.map[cookie.getMapKey()] = cookie else: cookieJar = nil proc swrite*(w: var PacketWriter; cookieJar: CookieJar) = w.swrite(cookieJar != nil) if cookieJar != nil: w.swrite(cookieJar.name) w.swrite(cookieJar.cookies) proc newCookieJarMap*(): CookieJarMap = return CookieJarMap() proc addNew*(map: CookieJarMap; name: sink string): CookieJar = let jar = CookieJar(name: name) map.jars[jar.name] = jar if map.jarsTail == nil: map.jarsHead = jar else: map.jarsTail.next = jar map.jarsTail = jar return jar proc getOrDefault*(map: CookieJarMap; name: string): CookieJar = return map.jars.getOrDefault(name) proc getMapKey(cookie: Cookie): string = return cookie.domain & cookie.path & '\t' & cookie.name proc parseCookieDate(val: string): Opt[int64] = # cookie-date const Delimiters = {'\t', ' '..'/', ';'..'@', '['..'`', '{'..'~'} var foundTime = false # date-token-list var time = array[3, int].default var dayOfMonth = 0 var month = 0 var year = -1 for dateToken in val.split(Delimiters): if dateToken == "": continue # *delimiter if not foundTime: # test for time let hmsTime = dateToken.until(NonDigit - {':'}) var i = 0 for timeField in hmsTime.split(':'): if i > 2: i = 0 break # too many time fields # 1*2DIGIT if timeField.len != 1 and timeField.len != 2: i = 0 break time[i] = parseInt32(timeField).get inc i if i == 3: foundTime = true continue if dayOfMonth == 0: # test for day-of-month let digits = dateToken.until(NonDigit) if digits.len in 1..2: dayOfMonth = parseInt32(digits).get continue if month == 0: # test for month if dateToken.len >= 3: case dateToken.toOpenArray(0, 2).toLowerAscii() of "jan": month = 1 of "feb": month = 2 of "mar": month = 3 of "apr": month = 4 of "may": month = 5 of "jun": month = 6 of "jul": month = 7 of "aug": month = 8 of "sep": month = 9 of "oct": month = 10 of "nov": month = 11 of "dec": month = 12 else: discard if month != 0: continue if year == -1: # test for year let digits = dateToken.until(NonDigit) if digits.len == 4: year = parseInt32(digits).get continue if month == 0 or dayOfMonth notin 1..getDaysInMonth(Month(month), year) or year < 1601 or not foundTime or time[0] > 23 or time[1] > 59 or time[2] > 59: return err() let dt = dateTime(year, Month(month), MonthdayRange(dayOfMonth), HourRange(time[0]), MinuteRange(time[1]), SecondRange(time[2]), zone = utc()) ok(dt.toTime().toUnix()) # For debugging proc `$`*(cookieJar: CookieJar): string = result = "" for cookie in cookieJar.cookies: result &= "Cookie " result &= $cookie[] result &= "\n" # https://www.rfc-editor.org/rfc/rfc6265#section-5.1.4 proc defaultCookiePath(url: URL): string = var path = url.pathname.untilLast('/') if path == "" or path[0] != '/': return "/" move(path) proc cookiePathMatches(cookiePath, requestPath: string): bool = if requestPath.startsWith(cookiePath): if requestPath.len == cookiePath.len: return true if cookiePath[^1] == '/': return true if requestPath.len > cookiePath.len and requestPath[cookiePath.len] == '/': return true return false proc cookieDomainMatches(cookieDomain: string; url: URL): bool = if cookieDomain.len == 0: return false if url.isIP(): return url.hostname == cookieDomain if url.hostname.endsWith(cookieDomain) and url.hostname.len >= cookieDomain.len: return url.hostname.len == cookieDomain.len or url.hostname[url.hostname.len - cookieDomain.len - 1] == '.' return false proc add(cookieJar: CookieJar; cookie: Cookie; parseMode = false, persist = true) = let s = cookie.getMapKey() let old = cookieJar.map.getOrDefault(s) if old != nil: if parseMode and old.isnew: return # do not override newly added cookies if persist or not old.persist: let i = cookieJar.cookies.find(old) cookieJar.cookies.delete(i) else: # we cannot save this cookie, but it must be kept for this session. old.skip = true cookieJar.map[s] = cookie cookieJar.cookies.add(cookie) # https://www.rfc-editor.org/rfc/rfc6265#section-5.4 # if http is true, httpOnly cookies are included too proc serialize*(cookieJar: CookieJar; url: URL; http: bool): string = var res = "" let t = getTime().toUnix() var expired: seq[int] = @[] for i, cookie in cookieJar.cookies.mypairs: let cookie = cookieJar.cookies[i] if cookie.skip: # "read-only" cookie continue if cookie.expires != -1 and cookie.expires <= t: expired.add(i) continue if not http and cookie.httpOnly: continue if cookie.secure and url.schemeType != stHttps and url.hostname != "localhost": continue if not cookiePathMatches(cookie.path, url.pathname): continue if cookie.hostOnly and cookie.domain != url.hostname: continue if not cookie.hostOnly and not cookieDomainMatches(cookie.domain, url): continue if res != "": res &= "; " res &= cookie.name res &= "=" res &= cookie.value for i in expired.ritems: cookieJar.map.del(cookieJar.cookies[i].getMapKey()) cookieJar.cookies.delete(i) move(res) proc parseSetCookie(str: string; t: int64; url: URL; persist, http: bool): Opt[Cookie] = let cookie = Cookie( expires: -1, hostOnly: true, persist: persist, isnew: true ) var first = true var hasPath = false for part in str.split(';'): if first: if '\t' in part: # Drop cookie if it has a tab. # Gecko seems to accept it, but Blink drops it too, # so this should be safe from a compat perspective. continue cookie.name = part.until('=') cookie.value = part.substr(cookie.name.len + 1) first = false continue let part = part.strip(leading = true, trailing = false) let key = part.untilLower('=') let val = part.substr(key.len + 1) case key of "expires": if cookie.expires == -1: if date := parseCookieDate(val): cookie.expires = date of "max-age": let x = parseInt32(val).get(-1) if x >= 0: cookie.expires = t + x of "secure": cookie.secure = true of "httponly": if not http: return err() cookie.httpOnly = true of "path": if val != "" and val[0] == '/' and '\t' notin val: hasPath = true cookie.path = val of "domain": var hostType = htNone var domain = parseHost(val, url.schemeType, hostType) if domain.len > 0 and domain[0] == '.': domain.delete(0..0) if hostType == htNone or not cookieDomainMatches(domain, url): return err() if hostType != htNone: cookie.domain = move(domain) cookie.hostOnly = false if cookie.hostOnly: cookie.domain = url.hostname if not hasPath: cookie.path = defaultCookiePath(url) if cookie.expires < 0: cookie.persist = false return ok(cookie) proc setCookie*(cookieJar: CookieJar; header: openArray[string]; url: URL; persist, http: bool) = let t = getTime().toUnix() var sorted = true for s in header: if cookie := parseSetCookie(s, t, url, persist, http): cookieJar.add(cookie, persist = persist) sorted = false if not sorted: cookieJar.cookies.sort(proc(a, b: Cookie): int = return cmp(a.path.len, b.path.len), order = Descending) type ParseState = object i: int error: bool proc nextField(state: var ParseState; iq: openArray[char]): string = if state.i >= iq.len: state.error = true return "" var field = iq.until('\t', state.i) state.i += field.len if state.i < iq.len and iq[state.i] == '\t': inc state.i move(field) proc nextBool(state: var ParseState; iq: openArray[char]): bool = let field = state.nextField(iq) if field == "TRUE": return true if field != "FALSE": state.error = true return false proc nextInt64(state: var ParseState; iq: openArray[char]): int64 = if x := parseInt64(state.nextField(iq)): return x state.error = true return 0 proc parse0(map: CookieJarMap; file: ChaFile; warnings: var seq[string]): Opt[void] = var line = "" var nline = 0 while ?file.readLine(line): if line.len != 0: var state = ParseState() var httpOnly = false if line[0] == '#': inc state.i let first = line.until('_', state.i) state.i += first.len if first != "HttpOnly": inc nline continue inc state.i httpOnly = true state.error = false let cookie = Cookie(httpOnly: httpOnly, persist: true) var domain = state.nextField(line) var cookieJar: CookieJar = nil if (let j = domain.find('@'); j != -1): cookie.domain = domain.substr(j + 1) if cookie.domain.startsWith("."): cookie.domain.delete(0..0) domain.setLen(j) else: if domain[0] == '.': domain.delete(0..0) cookie.domain = domain cookieJar = map.getOrDefault(domain) if cookieJar == nil: cookieJar = map.addNew(domain) cookie.hostOnly = not state.nextBool(line) cookie.path = state.nextField(line) cookie.secure = state.nextBool(line) cookie.expires = state.nextInt64(line) cookie.name = state.nextField(line) cookie.value = state.nextField(line) if not state.error: cookieJar.add(cookie, parseMode = true) else: warnings.add("skipped invalid cookie line " & $nline) inc nline ok() # Consumes `ps'. # If the cookie file's mtime is less than otime, it won't be parsed. # (This is used when writing the file, to merge in new data # from other instances written after we first parsed the file.) proc parse*(map: CookieJarMap; ps: PosixStream; warnings: var seq[string]; otime = int64.high): Opt[void] = var stats: Stat if fstat(ps.fd, stats) == -1: ps.sclose() return err() let mtime = int64(stats.st_mtime) if mtime < otime: let file = ?ps.fdopen("r") let res = map.parse0(file, warnings) ?file.close() ?res map.mtime = mtime ok() proc write0(map: CookieJarMap; file: ChaFile; ps: PosixStream; tmp, path: string): Opt[void] = ?file.write(""" # Netscape HTTP Cookie file # Autogenerated by Chawan. Manually added cookies are normally # preserved, but comments will be lost. """) var i = 0 let time = getTime().toUnix() var jar = map.jarsHead while jar != nil: for cookie in jar.cookies: if cookie.expires <= time or not cookie.persist: continue # session cookie var buf = "" if cookie.httpOnly: buf &= "#HttpOnly_" if cookie.domain != jar.name: buf &= jar.name & "@" if not cookie.hostOnly: buf &= '.' buf &= cookie.domain & '\t' const BoolMap = [false: "FALSE", true: "TRUE"] buf &= BoolMap[not cookie.hostOnly] & '\t' # flipped intentionally buf &= cookie.path & '\t' buf &= BoolMap[cookie.secure] & '\t' buf &= $cookie.expires & '\t' buf &= cookie.name & '\t' buf &= cookie.value & '\n' ?file.write(buf) inc i jar = jar.next if i == 0: discard unlink(cstring(tmp)) discard unlink(cstring(path)) return ok() if fsync(ps.fd) != 0: return err() return chafile.rename(tmp, path) proc write*(map: CookieJarMap; path: string): Opt[void] = let ps = newPosixStream(path) if ps != nil: var dummy: seq[string] = @[] ?map.parse(ps, dummy, map.mtime) elif map.jarsHead == nil: return ok() let tmp = path & '~' discard unlink(cstring(tmp)) let ps2 = newPosixStream(tmp, O_WRONLY or O_CREAT or O_EXCL, 0o600) if ps2 == nil: return err() let file = ?ps2.fdopen("w") let res = map.write0(file, ps2, tmp, path) ?file.close() res proc needsWrite*(map: CookieJarMap): bool = not map.transient and map.jarsHead != nil {.pop.} # raises: [] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/config/history.nim����������������������������������������������������������������0000664�0000000�0000000�00000006240�15202323131�0017376�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Generic object for line editing and browsing hist. {.push raises: [].} import std/posix import std/tables import io/chafile import io/dynstream import types/opt type History* = ref object first*: HistoryEntry last*: HistoryEntry mtime*: int64 map: Table[string, HistoryEntry] len: int maxLen: int transient*: bool # set if there is a failure in parsing history HistoryEntry* = ref object s*: string prev*: HistoryEntry next*: HistoryEntry proc add(hist: History; entry: sink HistoryEntry; merge = false) = let old = hist.map.getOrDefault(entry.s) if merge and old != nil: return if old != nil: if hist.first == old: hist.first = old.next if hist.last == old: hist.last = old.prev let prev = old.prev if prev != nil: prev.next = old.next if old.next != nil: old.next.prev = prev dec hist.len if hist.first == nil: hist.first = entry else: entry.prev = hist.last hist.last.next = entry hist.map[entry.s] = entry hist.last = entry inc hist.len if hist.len > hist.maxLen: if hist.first.next != nil: hist.first.next.prev = nil hist.first = hist.first.next if hist.first == nil: hist.last = nil dec hist.len proc newHistory*(maxLen: int; mtime = 0i64): History = return History(maxLen: maxLen, mtime: mtime) proc add*(hist: History; s: sink string) = hist.add(HistoryEntry(s: s), merge = false) proc parse0(hist: History; file: ChaFile; merge: bool): Opt[void] = var line = "" while ?file.readLine(line): hist.add(HistoryEntry(s: move(line)), merge) ok() # Consumes `ps'. # If the history file's mtime is less than otime, it won't be parsed. # (This is used when writing the file, to merge in new data from other # instances written after we first parsed the file.) proc parse*(hist: History; ps: PosixStream; otime = int64.low; merge = false): Opt[void] = var stats: Stat if fstat(ps.fd, stats) == -1: ps.sclose() return err() let mtime = int64(stats.st_mtime) if otime < mtime: let file = ?ps.fdopen("r") let res = hist.parse0(file, merge) ?file.close() ?res hist.mtime = mtime ok() proc write0(hist: History; file: ChaFile; reverse: bool): Opt[void] = if reverse: var entry = hist.last while entry != nil: ?file.writeLine(entry.s) entry = entry.prev else: var entry = hist.first while entry != nil: ?file.writeLine(entry.s) entry = entry.next ?file.flush() ok() # Consumes `ps'. proc write*(hist: History; ps: PosixStream; sync, reverse: bool): Opt[void] = let file = ?ps.fdopen("w") var res = hist.write0(file, reverse) if res.isOk and sync and fsync(ps.fd) != 0: res = err() ?file.close() res proc write*(hist: History; file: string): Opt[void] = let ps = newPosixStream(file) if ps != nil: ?hist.parse(ps, hist.mtime, merge = true) if hist.first == nil: return ok() let tmp = file & '~' discard unlink(cstring(tmp)) let ps2 = newPosixStream(tmp, O_WRONLY or O_CREAT or O_EXCL, 0o600) if ps2 == nil: return err() ?hist.write(ps2, sync = true, reverse = false) ?chafile.rename(tmp, file) ok() {.pop.} # raises: [] ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/config/mailcap.nim����������������������������������������������������������������0000664�0000000�0000000�00000034220�15202323131�0017302�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# See https://www.rfc-editor.org/rfc/rfc1524 {.push raises: [].} import std/os import std/posix import std/tables import io/chafile import io/dynstream import monoucha/libregexp import types/opt import types/url import utils/lrewrap import utils/myposix import utils/twtstr type MailcapParser* = object line: int error*: string MailcapFlag* = enum mfNeedsterminal = "needsterminal" mfCopiousoutput = "copiousoutput" mfHtmloutput = "x-htmloutput" # w3m extension mfAnsioutput = "x-ansioutput" # Chawan extension mfSaveoutput = "x-saveoutput" # Chawan extension mfNeedsstyle = "x-needsstyle" # Chawan extension mfNeedsimage = "x-needsimage" # Chawan extension mfType = "x-type" # w3mmee extension mfNetpath = "x-netpath" # w3mmee extension NamedFieldType* = enum nfTest = "test" nfNametemplate = "nametemplate" nfEdit = "edit" nfMatch = "x-match" # w3mmee extension nfNcMatch = "x-nc-match" # w3mmee extension NamedField = ref object t: NamedFieldType value*: string next: NamedField MailcapEntry* = ref object cmd*: string flags*: set[MailcapFlag] id*: uint32 # actual count in mailcap fieldsHead: NamedField MailcapList = ref object s*: seq[MailcapEntry] next: MailcapList # used for chaining lists with identical main types Mailcap* = object tab: Table[string, MailcapList] iterator fields(entry: MailcapEntry): NamedField = var field = entry.fieldsHead while field != nil: yield field field = field.next proc getList*(mailcap: Mailcap; t: string): MailcapList = let list = mailcap.tab.getOrDefault(t) if list != nil: return list #TODO it would be nice if this didn't allocate mailcap.tab.getOrDefault(t.until('/')) proc isHtmlOrText(s: string): bool = s == "text/html" or s == "text/plain" proc getListOrAdd(mailcap: var Mailcap; t: string): MailcapList = let list0 = mailcap.tab.getOrDefault(t) if list0 != nil: return list0 let list = MailcapList() let slash = t.find('/') if slash != -1: let main = t.substr(0, slash - 1) var mainList = mailcap.getList(main) if mainList == nil: # ensure a wildcard type exists for all subtypes. (if we were to add # main types after subtypes, then we'd have troubles linking them # together) mainList = MailcapList() mailcap.tab[main] = mainList else: # add existing wildcard entries if t.isHtmlOrText(): # these types only accept x-type for entry in mainList.s: if mfType in entry.flags: list.s.add(entry) else: list.s.add(mainList.s) # link together lists of the same main type so we can efficiently add # further wildcard entries list.next = mainList.next mainList.next = list mailcap.tab[t] = list list proc add(mailcap: var Mailcap; entry: MailcapEntry; t: string) = if t.isHtmlOrText() and mfType notin entry.flags: return var list = mailcap.getListOrAdd(t) let slash = t.find('/') if slash == -1: # wildcard; add to sub-entries too while list != nil: list.s.add(entry) list = list.next else: # add to this entry only list.s.add(entry) proc find*(entry: MailcapEntry; t: NamedFieldType): NamedField = for field in entry.fields: if field.t == t: return field nil proc toStr(entry: MailcapEntry; t: string): string = var s = t & ';' & entry.cmd for flag in MailcapFlag: if flag in entry.flags: s &= ';' & $flag for field in entry.fields: # if value is regex, then the source is until the first NUL s &= ';' & $field.t & '=' & $cstring(field.value) s &= '\n' move(s) template err(state: MailcapParser; msg: string): untyped = state.error = msg err() proc consumeTypeField(state: var MailcapParser; line: openArray[char]; outs: var string): Opt[int] = var slash = -1 var n = 0 while n < line.len: let c = line[n] if c in AsciiWhitespace + {';'}: break if c == '/': if slash >= 0: return state.err("too many slash characters") slash = outs.len elif c notin AsciiAlphaNumeric + {'-', '.', '*', '_', '+'}: return state.err("invalid character in type field: " & c) outs &= c.toLowerAscii() inc n if slash >= 0 and slash + 2 == outs.len and outs[slash + 1] == '*': # normalize type/* to type without a subtype (implicit-wild) outs.setLen(slash) n = line.skipBlanks(n) if n >= line.len or line[n] != ';': return state.err("semicolon not found") ok(n + 1) proc consumeCommand(state: var MailcapParser; line: string; outs: var string; n: int): Opt[int] = var n = line.skipBlanks(n) var quoted = false while n < line.len: let c = line[n] if not quoted: if c == '\r': continue if c == ';': return ok(n) if c == '\\': quoted = true # fall through; backslash will be parsed again in unquoteCommand elif c in Controls: return state.err("invalid character in command: " & c) else: quoted = false outs &= c inc n ok(n) proc addNamedField(entry: MailcapEntry; t: NamedFieldType; fieldsTail: var NamedField; cmd: var string) = var s = move(cmd) if t in {nfMatch, nfNcMatch}: let flags = if t == nfNcMatch: {LRE_FLAG_IGNORECASE} else: {} var re: Regex if not compileRegex(s, flags, re): return s &= '\0' & re.bytecode let field = entry.find(t) if field != nil: field.value = move(s) else: let field = NamedField(t: t, value: move(s)) if fieldsTail == nil: entry.fieldsHead = field else: fieldsTail.next = field fieldsTail = field proc consumeField(state: var MailcapParser; line: string; entry: MailcapEntry; n: int; fieldsTail: var NamedField): Opt[int] = var n = line.skipBlanks(n) var s = "" while n < line.len: let c = line[n] inc n case c of ';': break of '\r': continue of '=': var cmd = "" n = ?state.consumeCommand(line, cmd, n) while s.len > 0 and s[^1] in AsciiWhitespace: s.setLen(s.len - 1) if t := parseEnumNoCase[NamedFieldType](s): entry.addNamedField(t, fieldsTail, cmd) return ok(n) elif c in Controls: return state.err("invalid character in field: " & c) else: s &= c while s.len > 0 and s[^1] in AsciiWhitespace: s.setLen(s.len - 1) if x := parseEnumNoCase[MailcapFlag](s): entry.flags.incl(x) return ok(n) proc parseEntry*(state: var MailcapParser; line: string; entry: MailcapEntry; t: var string): Opt[void] = var n = ?state.consumeTypeField(line, t) n = ?state.consumeCommand(line, entry.cmd, n) var fieldsTail: NamedField while n < line.len: n = ?state.consumeField(line, entry, n, fieldsTail) ok() proc parseBuiltin*(mailcap: var Mailcap; buf: openArray[char]) = var state = MailcapParser(line: 1) var id = 0'u32 for line in buf.split('\n'): if line.len <= 0: continue let entry = MailcapEntry(id: id) inc id var t: string let res = state.parseEntry(line, entry, t) doAssert res.isOk, state.error mailcap.add(entry, t) proc parseMailcap(state: var MailcapParser; mailcap: var Mailcap; file: ChaFile): Opt[void] = var id = 0'u32 var line: string while file.readLine(line).get(false): if line.len <= 0 or line[0] == '#': continue while true: if line.len > 0 and line[^1] == '\r': line.setLen(line.high) if line.len == 0 or line[^1] != '\\': break line.setLen(line.high) # trim backslash if not ?file.readLineAppend(line): break var t: string let entry = MailcapEntry(id: id) inc id ?state.parseEntry(line, entry, t) mailcap.add(entry, t) inc state.line return ok() proc parseMailcap*(mailcap: var Mailcap; path: string): Err[string] = let file0 = chafile.fopen(path, "r") if file0.isErr: return ok() let file = file0.get var state = MailcapParser(line: 1) let res = state.parseMailcap(mailcap, file) file.close() if res.isErr: return err(path & '(' & $state.line & "): " & msg) ok() # Mostly based on w3m's mailcap quote/unquote type UnquoteState = enum usNormal, usQuoted, usPerc, usAttr, usAttrQuoted, usDollar type UnquoteResult* = object canpipe*: bool cmd*: string type QuoteState* = enum qsNormal, qsDoubleQuoted, qsSingleQuoted proc quoteFile*(file: string; qs: QuoteState): string = var s = "" for c in file: case c of '$', '`', '"', '\\': if qs != qsSingleQuoted: s &= '\\' of '\'': if qs == qsSingleQuoted: s &= "'\\'" # then re-open the quote by appending c elif qs == qsNormal: s &= '\\' # double-quoted: append normally of AsciiAlphaNumeric, '_', '.', ':', '/': discard # no need to quote elif qs == qsNormal: s &= '\\' s &= c move(s) proc unquoteCommand*(ecmd, contentType, outpath: string; url: URL; canpipe: var bool; line = -1): string = var cmd = "" var attrname = "" var state = usNormal var qs = qsNormal # current quote state var qss: seq[QuoteState] = @[] # quote state stack for c in ecmd: case state of usQuoted: cmd &= c state = usNormal of usAttrQuoted: attrname &= c.toLowerAscii() state = usAttr of usNormal, usDollar: let prevDollar = state == usDollar state = usNormal case c of '%': state = usPerc of '\\': state = usQuoted of '\'': if qs == qsSingleQuoted: qs = qsNormal else: qs = qsSingleQuoted cmd &= c of '"': if qs == qsDoubleQuoted: qs = qsNormal else: qs = qsDoubleQuoted cmd &= c of '$': if qs != qsSingleQuoted: state = usDollar cmd &= c of '(': if prevDollar: qss.add(qs) qs = qsNormal cmd &= c of ')': if qs != qsSingleQuoted: if qss.len > 1: qs = qss.pop() else: # mismatched parens; probably an invalid shell command... qs = qsNormal cmd &= c else: cmd &= c of usPerc: case c of '%': cmd &= c of 's': cmd &= quoteFile(outpath, qs) canpipe = false of 't': cmd &= quoteFile(contentType.untilLower(';'), qs) of 'u': # Netscape extension if url != nil: # nil in getEditorCommand cmd &= quoteFile($url, qs) of 'h': # w3mmee extension if url != nil: cmd &= quoteFile(url.hostname, qs) of 'H': # Chawan extension if url != nil: cmd &= quoteFile(url.host, qs) of 'p': # w3mmee extension if url != nil: cmd &= quoteFile(url.port, qs) of '?': # w3mmee(-ish) extension if url != nil: cmd &= quoteFile(url.search, qs) of 'd': # Chawan extension if line != -1: # -1 in mailcap cmd &= $line of '{': state = usAttr continue else: discard state = usNormal of usAttr: if c == '}': let s = contentType.getContentTypeAttr(attrname) cmd &= quoteFile(s, qs) attrname = "" state = usNormal elif c == '\\': state = usAttrQuoted else: attrname &= c move(cmd) proc unquoteCommand*(ecmd, contentType, outpath: string; url: URL): string = var canpipe: bool return unquoteCommand(ecmd, contentType, outpath, url, canpipe) proc checkEntry(entry: MailcapEntry; contentType: string; url: URL): bool = if mfNetpath in entry.flags and not url.isNetPath(): return false for field in entry.fields: case field.t of nfTest: var canpipe = true let cmd = unquoteCommand(field.value, contentType, "", url, canpipe) if not canpipe or myposix.system(cstring(cmd)) != 0: return false of nfMatch, nfNcMatch: let i = field.value.find('\0') + 1 let surl = $url let (si, ei) = cast[REBytecode](addr field.value[i]).matchFirst(surl) if si != 0 or ei != surl.len: return false else: discard true proc findPrevMailcapEntry*(mailcap: Mailcap; shortContentType, contentType: string; url: URL; last: int): int = let list = mailcap.getList(shortContentType) if list != nil: for i in countdown(last - 1, 0): if mfType in list.s[i].flags: continue # only supported in auto-mailcap if checkEntry(list.s[i], contentType, url): return i return -1 proc findMailcapEntry*(mailcap: Mailcap; shortContentType, contentType: string; url: URL; outIdx: var int): MailcapEntry = let list = mailcap.getList(shortContentType) if list != nil: let start = outIdx for i in start + 1 ..< list.s.len: let entry = list.s[i] if mfType in entry.flags: continue # only supported in auto-mailcap if checkEntry(entry, contentType, url): outIdx = i return entry outIdx = -1 nil # called for auto-mailcap only; allows modifying the type proc findMailcapEntryMut*(mailcap: Mailcap; shortContentType, contentType: var string; url: URL): MailcapEntry = var id = 0'u32 var done = false while not done: let list = mailcap.getList(shortContentType) if list == nil: break done = true for i in 0 ..< list.s.len: let entry = list.s[i] if entry.id < id: continue if not checkEntry(entry, contentType, url): continue if mfType in entry.flags: var canpipe: bool contentType = unquoteCommand(entry.cmd, contentType, "", url, canpipe) shortContentType = contentType.untilLower(';') id = entry.id done = false break return entry nil proc findMailcapEntry*(mailcap: Mailcap; shortContentType, contentType: string; url: URL): MailcapEntry = var start = -1 mailcap.findMailcapEntry(shortContentType, contentType, url, start) proc saveEntry*(mailcap: var Mailcap; path, t: string; entry: MailcapEntry): Opt[void] = let s = entry.toStr(t) let pdir = path.parentDir() discard mkdir(cstring(pdir), 0o700) let ps = newPosixStream(path, O_WRONLY or O_APPEND or O_CREAT, 0o644) if ps == nil: return err() let res = ps.writeLoop(s) if res.isOk: mailcap.add(entry, t) ps.sclose() res {.pop.} # raises: [] ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/config/mimetypes.nim��������������������������������������������������������������0000664�0000000�0000000�00000005071�15202323131�0017712�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/algorithm import std/tables import io/chafile import types/opt import utils/twtstr const DefaultGuess* = { "ans": "text/x-ansi", "asc": "text/x-ansi", "css": "text/css", "gmi": "text/gemini", "htm": "text/html", "html": "text/html", "md": "text/markdown", "txt": "text/plain", "uri": "text/uri-list", "xht": "application/xhtml+xml", "xhtm": "application/xhtml+xml", "xhtml": "application/xhtml+xml", "bmp": "image/bmp", "gif": "image/gif", "jfif": "image/jpeg", "jpe": "image/jpeg", "jpeg": "image/jpeg", "jpg": "image/jpeg", "png": "image/png", "svg": "image/svg+xml", "webp": "image/webp", }.toTable() # Part after image/, *not* the file extension. # (sorted by order of perceived frequency) const DefaultImages = [ "png", "jpeg", "webp", "svg+xml", "gif", "bmp" ] # extension -> type type MimeTypesTable* = Table[string, string] # ext -> type MimeTypes* = object t*: MimeTypesTable image*: Table[string, string] # ext -> image/(\w*) proc parseMimeTypes*(mimeTypes: var MimeTypes; file: ChaFile): Opt[void] = var line: string while ?file.readLine(line): if line.len == 0 or line[0] == '#': continue let t = line.untilLower(AsciiWhitespace) var i = t.len while i < line.len: i = line.skipBlanks(i) let ext = line.untilLower(AsciiWhitespace, i) i += ext.len if ext.len > 0 and not mimeTypes.t.hasKeyOrPut(ext, t) and t.startsWith("image/"): let t = t.substr("image/".len) # As a fingerprinting countermeasure: prevent additional # extensions for predefined inline image type detection. if t notin DefaultImages: mimeTypes.image[ext] = t ok() proc guessContentType*(mimeTypes: MimeTypesTable; path: string; fallback = "application/octet-stream"): string = let ext = path.getFileExt() if ext.len > 0: return mimeTypes.getOrDefault(ext, fallback) return fallback const JavaScriptTypes = [ "application/ecmascript", "application/javascript", "application/x-ecmascript", "application/x-javascript", "text/ecmascript", "text/javascript", "text/javascript1.0", "text/javascript1.1", "text/javascript1.2", "text/javascript1.3", "text/javascript1.4", "text/javascript1.5", "text/jscript", "text/livescript", "text/x-ecmascript", "text/x-javascript" ] proc isJavaScriptType*(s: string): bool = return JavaScriptTypes.binarySearch(s, cmpIgnoreCase) != -1 proc isTextType*(s: string): bool = return s.startsWithIgnoreCase("text/") or s.isJavaScriptType() {.pop.} # raises: [] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/config/urimethodmap.nim�����������������������������������������������������������0000664�0000000�0000000�00000003571�15202323131�0020377�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# w3m's URI method map format. import std/tables import types/opt import types/url import utils/twtstr type URIMethodMap* = object map*: Table[string, string] imageProtos*: seq[string] proc rewriteURL(pattern, surl: string): string = result = "" var wasPerc = false for c in pattern: if wasPerc: if c == '%': result &= '%' elif c == 's': result &= surl else: result &= '%' result &= c wasPerc = false elif c != '%': result &= c else: wasPerc = true if wasPerc: result &= '%' type URIMethodMapResult* = enum ummrNotFound, ummrSuccess, ummrWrongURL proc findAndRewrite*(this: URIMethodMap; url: var URL): URIMethodMapResult = let s = this.map.getOrDefault(url.scheme) if s != "": let surl = s.rewriteURL($url) if x := parseURL(surl): url = x return ummrSuccess return ummrWrongURL return ummrNotFound proc insert(this: var URIMethodMap; k, v: string) = if not this.map.hasKeyOrPut(k, v) and k.startsWith("img-codec+"): this.imageProtos.add(k.until(':')) const DefaultURIMethodMap* = staticRead"res/urimethodmap" proc parseURIMethodMap*(this: var URIMethodMap; s: string) = for line in s.split('\n'): if line.len == 0 or line[0] == '#': continue # comments var k = line.untilLower(AsciiWhitespace + {':'}) var i = k.len if i >= line.len or line[i] != ':': continue # invalid i = line.skipBlanks(i + 1) # skip colon var v = line.until(AsciiWhitespace, i) # Basic w3m compatibility. # If needed, w3m-cgi-compat covers more cases. if v.startsWith("file:/cgi-bin/"): v = "cgi-bin:" & v.substr("file:/cgi-bin/".len) elif v.startsWith("file:///cgi-bin/"): v = "cgi-bin:" & v.substr("file:///cgi-bin/".len) elif v.startsWith("/cgi-bin/"): v = "cgi-bin:" & v.substr("/cgi-bin/".len) this.insert(k, v) ���������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/css/������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0014511�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/css/box.nim�����������������������������������������������������������������������0000664�0000000�0000000�00000026367�15202323131�0016024�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import css/cssparser import css/cssvalues import css/lunit import html/dom import types/bitmap import types/refstring type DimensionType* = enum dtHorizontal, dtVertical Offset* = array[DimensionType, LUnit] Size* = array[DimensionType, LUnit] # Note: with some effort this could be turned into a non-ref object, # but that's slower (at least with refc). TextRun* = ref object offset*: Offset s*: string BorderStyleSpan* = object start*: CSSBorderStyle send*: CSSBorderStyle CSSBorder* = array[DimensionType, BorderStyleSpan] CSSBorderMerge* = array[DimensionType, bool] PendingFloat* = ref object offset*: Offset bfcOffset*: Offset space*: Space box*: BlockBox marginOffset*: Offset outerSize*: Size newLine*: bool # "should we put this on a new line?" next*: PendingFloat Exclusion* = ref object offset*: Offset size*: Size t*: CSSFloat id*: uint32 next*: Exclusion BoxLayoutState* = object # offset relative to parent offset*: Offset # padding size size*: Size # intrinsic minimum size (e.g. longest word) intr*: Size # Margin left to add to the next box. marginTodo*: Span # The first uncleared float. (clear: both flushes existing floats.) exclusionsHead*: Exclusion # Last float seen among descendants. exclusionsTail*: Exclusion # First float whose Y position is not resolved yet. pendingFloatsHead*: PendingFloat # Last float whose Y position is not resolved yet. pendingFloatsTail*: PendingFloat # baseline of the first line box of all descendants firstBaseline*: LUnit # baseline of the last line box of all descendants baseline*: LUnit # Top margin that was resolved in this box, but belongs to an ancestor. marginOutput*: LUnit # Additional y position to be added to our own offset (=flushed margin). yshift*: LUnit # Maximum float height relative to the BFC. maxFloatHeight*: LUnit # Clear offset relative to the BFC. clearOffset*: LUnit # Indicates which borders have been merged with an adjacent one. merge*: CSSBorderMerge # Whether or not a line box has set a baseline for us. baselineSet*: bool # Whether our margin has been flushed (either by this box or its # descendants.) marginResolved*: bool Area* = object offset*: Offset size*: Size InlineBoxState* = object startOffset*: Offset # offset of the first word, for position: absolute areas*: seq[Area] # background that should be painted by box Span* = object start*: LUnit send*: LUnit RelativeRect* = array[DimensionType, Span] StackItem* = ref object box*: CSSBox index*: int32 children*: seq[StackItem] ClipBox* = object start*: Offset send*: Offset BoxRenderState* = object # Whether the following two variables have been initialized. #TODO find a better name that doesn't conflict with box.positioned positioned*: bool offset*: Offset clipBox*: ClipBox # min-content: box width is longest word's width # max-content: box width is content width without wrapping # stretch: box width is n px wide # fit-content: also known as shrink-to-fit, box width is # min(max-content, stretch(availableWidth)) # in other words, as wide as needed, but wrap if wider than allowed # (note: I write width here, but it can apply for any constraint) SizeConstraintType* = enum scStretch, scFitContent, scMinContent, scMaxContent, scMeasure SizeConstraint* = object t*: SizeConstraintType u*: LUnit Space* = array[DimensionType, SizeConstraint] BoundsPart* = array[DimensionType, Span] Bounds* = object a*: BoundsPart # width clamp mi*: BoundsPart # intrinsic clamp LayoutInput* = object # BFC offset before flushing margins. # Also, `position: absolute' recycles bfcOffset for storing storing its # own position which is typically computed by other boxes in the tree. bfcOffset*: Offset margin*: RelativeRect padding*: RelativeRect space*: Space bounds*: Bounds marginTodo*: Span pendingFloatsHead*: PendingFloat pendingFloatsTail*: PendingFloat exclusionsHead*: Exclusion exclusionsTail*: Exclusion clearOffset*: LUnit border*: CSSBorder marginResolved*: bool CSSBoxType* = enum cbtElement, cbtAnonymous, cbtText CSSBox* = ref object of RootObj parent*: CSSBox firstChild*: CSSBox next*: CSSBox absolute*: CSSAbsolute pseudo*: PseudoElement t*: CSSBoxType keepLayout*: bool positioned*: bool # set if we participate in positioned layout render*: BoxRenderState # render output computed*: CSSValues element*: Element CSSAbsolute* {.acyclic.} = ref object box*: BlockBox next*: CSSAbsolute BlockBox* = ref object of CSSBox input*: LayoutInput # tree builder output -> layout input state*: BoxLayoutState # layout output -> render input InlineBox* = ref object of CSSBox state*: InlineBoxState InlineTextBox* = ref object of InlineBox runs*: seq[TextRun] # state text*: RefString len*: int # must invalidate if text.s.len != len InlineNewLineBox* = ref object of InlineBox proc offset*(x, y: LUnit): Offset = return [dtHorizontal: x, dtVertical: y] proc x*(offset: Offset): LUnit {.inline.} = return offset[dtHorizontal] proc x*(offset: var Offset): var LUnit {.inline.} = return offset[dtHorizontal] proc `x=`*(offset: var Offset; x: LUnit) {.inline.} = offset[dtHorizontal] = x proc y*(offset: Offset): LUnit {.inline.} = return offset[dtVertical] proc y*(offset: var Offset): var LUnit {.inline.} = return offset[dtVertical] proc `y=`*(offset: var Offset; y: LUnit) {.inline.} = offset[dtVertical] = y proc size*(w, h: LUnit): Size = return [dtHorizontal: w, dtVertical: h] proc w*(size: Size): LUnit {.inline.} = return size[dtHorizontal] proc w*(size: var Size): var LUnit {.inline.} = return size[dtHorizontal] proc `w=`*(size: var Size; w: LUnit) {.inline.} = size[dtHorizontal] = w proc h*(size: Size): LUnit {.inline.} = return size[dtVertical] proc h*(size: var Size): var LUnit {.inline.} = return size[dtVertical] proc `h=`*(size: var Size; h: LUnit) {.inline.} = size[dtVertical] = h proc `+`*(a, b: Offset): Offset = return offset(x = a.x + b.x, y = a.y + b.y) proc `-`*(a, b: Offset): Offset = return offset(x = a.x - b.x, y = a.y - b.y) proc `+=`*(a: var Offset; b: Offset) = a.x += b.x a.y += b.y proc `-=`*(a: var Offset; b: Offset) = a.x -= b.x a.y -= b.y proc left*(s: RelativeRect): LUnit = return s[dtHorizontal].start proc right*(s: RelativeRect): LUnit = return s[dtHorizontal].send proc top*(s: RelativeRect): LUnit = return s[dtVertical].start proc bottom*(s: RelativeRect): LUnit = return s[dtVertical].send proc left*(b: CSSBorder): CSSBorderStyle = return b[dtHorizontal].start proc right*(b: CSSBorder): CSSBorderStyle = return b[dtHorizontal].send proc top*(b: CSSBorder): CSSBorderStyle = return b[dtVertical].start proc bottom*(b: CSSBorder): CSSBorderStyle = return b[dtVertical].send proc topLeft*(s: RelativeRect): Offset = return offset(x = s.left, y = s.top) proc bottomRight*(s: RelativeRect): Offset = return offset(x = s.right, y = s.bottom) proc `+=`*(span: var Span; u: LUnit) = span.start += u span.send += u proc `<`*(a, b: Offset): bool = a.x < b.x and a.y < b.y proc `<=`*(a, b: Offset): bool = a.x <= b.x and a.y <= b.y proc sum*(span: Span): LUnit = return span.start + span.send proc sum*(rect: RelativeRect): Size = return [ dtHorizontal: rect[dtHorizontal].sum(), dtVertical: rect[dtVertical].sum() ] const Offset0* = offset(0'lu, 0'lu) proc borderTopLeft*(input: LayoutInput; cellSize: Size): Offset = var o = Offset0 if input.border.left notin BorderStyleNoneHidden: o.x += cellSize.w if input.border.top notin BorderStyleNoneHidden: o.y += cellSize.h o proc borderBottomRight*(input: LayoutInput; cellSize: Size): Offset = var o = Offset0 if input.border.right notin BorderStyleNoneHidden: o.x += cellSize.w if input.border.bottom notin BorderStyleNoneHidden: o.y += cellSize.h o iterator children*(box: CSSBox): CSSBox = var it = box.firstChild while it != nil: yield it it = it.next proc resetState(box: CSSBox) = box.render = BoxRenderState() proc resetState*(ibox: InlineBox) = CSSBox(ibox).resetState() ibox.state = InlineBoxState() proc resetState*(box: BlockBox) = CSSBox(box).resetState() box.state = BoxLayoutState() const DefaultClipBox* = ClipBox(send: offset(LUnit.high, LUnit.high)) proc newDOMRect(offset: Offset; size: Size): DOMRect = DOMRect( x: offset.x.toFloat64(), y: offset.y.toFloat64(), width: size.w.toFloat64(), height: size.h.toFloat64() ) proc getClientRects(res: var seq[DOMRect]; box: CSSBox; firstOnly, blockOnly: bool) = if box of BlockBox: let box = BlockBox(box) res.add(newDOMRect(box.render.offset, box.state.size)) elif not blockOnly: let ibox = InlineBox(box) for area in ibox.state.areas: let offset = ibox.render.offset - ibox.state.startOffset + area.offset res.add(newDOMRect(offset, area.size)) if firstOnly: break for it in ibox.children: if it.element == box.element and it of InlineBox: res.getClientRects(it, firstOnly, false) getClientRectsImpl = proc(element: Element; firstOnly, blockOnly: bool): seq[DOMRect] = result = @[] if element.box != nil: result.getClientRects(CSSBox(element.box), firstOnly, blockOnly) # Currently, getBitmap and getImageBitmap is effectively the same. # The separation exists so that in the future, getBitmap can be expanded # to return background-image too. proc getBitmap*(box: BlockBox): NetworkBitmap = box.element.getBitmap() proc getImageBitmap*(box: BlockBox): NetworkBitmap = if box.computed{"display"} in {DisplayImageInline, DisplayImageBlock}: return box.getBitmap() return nil when defined(debug): import chame/tags proc `$`*(box: CSSBox; pass2 = true): string = if box.positioned and not pass2: return "" result = "<" let name = if box.computed{"display"} != DisplayInline: if box.element.tagType in {TAG_HTML, TAG_BODY}: $box.element.tagType else: "div" elif box of InlineNewLineBox: "br" else: "span" result &= name let computed = box.computed.copyProperties() if computed{"display"} == DisplayBlock: computed{"display"} = DisplayInline var style = $computed.serializeEmpty() if style != "": if style[^1] == ';': style.setLen(style.high) result &= " style='" & style & "'" result &= ">" if box of InlineNewLineBox: return if box of BlockBox: result &= '\n' for it in box.children: result &= `$`(it, pass2 = false) if box of InlineTextBox: for run in InlineTextBox(box).runs: result &= run.s if box of BlockBox: result &= '\n' result &= "</" & name & ">" proc `$`*(stack: StackItem): string = result = "<STACK index=" & $stack.index & ">\n" result &= `$`(stack.box, pass2 = true) result &= "\n" for child in stack.children: result &= "<child>\n" result &= $child result &= "</child>\n" result &= "</STACK>\n" {.pop.} �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/css/cascade.nim�������������������������������������������������������������������0000664�0000000�0000000�00000041745�15202323131�0016614�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/algorithm import std/math import std/tables import chame/tags import config/conftypes import css/cssparser import css/cssvalues import css/match import css/sheet import html/catom import html/dom import html/script import types/color import types/jscolor import types/opt import utils/dtoawrap import utils/twtstr type RuleListEntry = object vals: array[CSSImportantFlag, seq[CSSComputedEntry]] vars: array[CSSImportantFlag, seq[CSSVariable]] LayeredRuleList = object unlayered: RuleListEntry layers: seq[RuleListEntry] RuleList = object a: array[CSSOrigin, LayeredRuleList] hasValues: bool RuleListMap = array[PseudoElement, RuleList] RulePair = tuple specificity: uint rule: CSSRuleDef ToSorts = array[PseudoElement, seq[RulePair]] RevertType = enum rtUnset, rtUser, rtUserAgent, rtSet RevertMap = array[CSSPropertyType, RevertType] ApplyValueContext = object vals: CSSValues parentComputed: CSSValues window: Window old: CSSValues revertMap: RevertMap varsSeen: array[20, CAtom] # Forward declarations proc ensureStyle*(element: Element) proc applyValues(ctx: var ApplyValueContext; entries: openArray[CSSComputedEntry]; revertType: RevertType) proc calcRules(tosorts: var ToSorts; element: Element; depends: var DependencyInfo; rules: openArray[CSSRuleDef]) = for rule in rules: var seen: set[PseudoElement] = {} for sel in rule.sels: if sel.pseudo in seen: continue if element.matches(sel, depends): tosorts[sel.pseudo].add((sel.specificity, rule)) seen.incl(sel.pseudo) proc add(entry: var RuleListEntry; rule: CSSRuleDef) = for f in CSSImportantFlag: # normal, important entry.vals[f].add(rule.vals[f]) entry.vars[f].add(rule.vars[f]) proc calcRules(map: var RuleListMap; element: Element; sheet: CSSRuleMap; depends: var DependencyInfo) = var tosorts = ToSorts.default sheet.tagTable.withValue(element.localName, v): tosorts.calcRules(element, depends, v[]) if element.id != CAtomNull: sheet.idTable.withValue(element.id.toLowerAscii(), v): tosorts.calcRules(element, depends, v[]) for class in element.classList: sheet.classTable.withValue(class.toLowerAscii(), v): tosorts.calcRules(element, depends, v[]) for attr in element.attrs: sheet.attrTable.withValue(attr.qualifiedName, v): tosorts.calcRules(element, depends, v[]) if element.parentElement == nil: tosorts.calcRules(element, depends, sheet.rootList) if element.hint: tosorts.calcRules(element, depends, sheet.hintList) tosorts.calcRules(element, depends, sheet.generalList) for pseudo, it in tosorts.mpairs: it.sort(proc(x, y: RulePair): int = let n = cmp(x.specificity, y.specificity) if n != 0: return n return cmp(x.rule.idx, y.rule.idx), order = Ascending) for item in it: let rule = item.rule let origin = rule.origin let layerId = rule.layerId if rule.vals[cifNormal].len > 0 or rule.vals[cifImportant].len > 0: map[pseudo].hasValues = true if layerId == 0: map[pseudo].a[origin].unlayered.add(rule) else: let n = int(layerId) if n > map[pseudo].a[origin].layers.len: map[pseudo].a[origin].layers.setLen(n) map[pseudo].a[origin].layers[n - 1].add(rule) proc addItems(ctx: var ApplyValueContext; toks: var seq[CSSToken]; vars: CSSVariableMap; items: openArray[CSSVarItem]): Opt[void] = for item in items: let varName = item.name if varName != CAtomNull: var success = false for it in ctx.varsSeen.mitems: if it == varName: break if it == CAtomNull: it = varName success = true break if not success: return err() var cv: CSSVariable = nil var vars = vars while vars != nil: cv = vars.table.getOrDefault(varName) if cv != nil: break vars = vars.parent if cv != nil: ?ctx.addItems(toks, vars, cv.items) continue if item.toks.len == 0: return err() toks.add(item.toks) ok() proc resolveVariable(ctx: var ApplyValueContext; p: CSSWidePropertyType; cvar: CSSVarEntry; revertType: RevertType): Opt[void] = let vars = ctx.vals.vars for it in cvar.resolved: if it.vars == vars: ctx.applyValues(it.entries, revertType) return ok() var toks: seq[CSSToken] = @[] let res = ctx.addItems(toks, vars, cvar.items) zeroMem(addr ctx.varsSeen, sizeof(ctx.varsSeen)) if res.isErr: return err() # fully resolved var entries: seq[CSSComputedEntry] = @[] let window = ctx.window var parser = initCSSParserSink(toks) ?parser.parseComputedValues0(p, window.settings.attrsp[], entries) ctx.applyValues(entries, revertType) cvar.resolved.add((vars, move(entries))) ok() # applyValues runs backwards on the available entries, so that an # important revert can skip non-important entries until the previous # layer is reached. # e.g. if user important sets revert on property t, then the revertMap # of t is set to rtUserAgent, and all entries that are not in the # user-agent origin are skipped. (Alternatively, if user-agent set an # important value on t, then revertMap already has t set to rtSet, and # the user important entry in question is skipped.) proc applyValue(ctx: var ApplyValueContext; entry: CSSComputedEntry; revertType: RevertType) = if entry.et == ceVar: discard ctx.resolveVariable(entry.p, entry.cvar, revertType) return let t = entry.p.p if ctx.revertMap[t] > revertType.pred: # either already set, or reverted to a subsequent value. return case entry.et of ceBit: ctx.vals.bits[t].dummy = entry.bit of ceHWord: ctx.vals.hwords[t] = entry.hword of ceWord: ctx.vals.words[t] = entry.word of ceObject: ctx.vals.objs[t] = entry.obj of ceGlobal: case entry.global of cgtInherit: ctx.vals.initialOrCopyFrom(ctx.parentComputed, t) of cgtInitial: ctx.vals.setInitial(t) of cgtUnset: ctx.vals.initialOrInheritFrom(ctx.parentComputed, t) of cgtRevert: if revertType == rtSet: # user agent ctx.vals.initialOrInheritFrom(ctx.parentComputed, t) else: ctx.revertMap[t] = revertType return of ceVar: discard ctx.revertMap[t] = rtSet proc applyValues(ctx: var ApplyValueContext; entries: openArray[CSSComputedEntry]; revertType: RevertType) = for entry in entries.ritems: ctx.applyValue(entry, revertType) proc applyNormalValues(ctx: var ApplyValueContext; list: LayeredRuleList; revertType: RevertType) = ctx.applyValues(list.unlayered.vals[cifNormal], revertType) for layer in list.layers.ritems: ctx.applyValues(layer.vals[cifNormal], revertType) proc applyImportantValues(ctx: var ApplyValueContext; list: LayeredRuleList; revertType: RevertType) = for layer in list.layers: ctx.applyValues(layer.vals[cifImportant], revertType) ctx.applyValues(list.unlayered.vals[cifImportant], revertType) proc applyPresHint(ctx: var ApplyValueContext; entry: CSSComputedEntry) = # This is a bit awkward: presentational hints are below author and # user style in the cascade, but reverting either just skips the # presentational hint. # I guess this means that even with an attr() implementation, it's # impossible to move presentational hints to pure CSS. Another # spectacular failure of the committee... ctx.applyValue(entry, rtUser) proc parseDimensionValues(s: string): Opt[CSSLength] = var i = s.skipBlanks(0) if i >= s.len or s[i] notin AsciiDigit: return err() let n = float32(atod(cstring(s), i)) if isNaN(n): return err() if i < s.len and s[i] == '%': return ok(cssLengthPerc(n)) ok(cssLength(n)) proc applyDimensionHint(ctx: var ApplyValueContext; p: CSSPropertyType; s: string) = if dim := parseDimensionValues(s): ctx.applyPresHint(makeEntry(p, dim)) proc applyDimensionHintGz(ctx: var ApplyValueContext; p: CSSPropertyType; s: string) = let s = parseDimensionValues(s).get(CSSLengthZero) if not s.isZero: ctx.applyPresHint(makeEntry(p, s)) proc applyColorHint(ctx: var ApplyValueContext; p: CSSPropertyType; s: string) = let c = parseLegacyColor(s) if c.isOk: ctx.applyPresHint(makeEntry(p, c.get.cssColor())) proc applyLengthHint(ctx: var ApplyValueContext; p: CSSPropertyType; unit: CSSUnit; u: uint32) = let length = resolveLength(unit, float32(u), ctx.window.settings.attrsp[]) ctx.applyPresHint(makeEntry(p, length)) const InputTypeWithSize* = { itColor, itDate, itDatetimeLocal, itEmail, itFile, itImage, itMonth, itNumber, itPassword, itRange, itSearch, itTel, itText, itTime, itURL, itWeek } proc applyPresHints(ctx: var ApplyValueContext; element: Element) = case element.tagType of TAG_TABLE: ctx.applyDimensionHintGz(cptWidth, element.attr(satWidth)) ctx.applyDimensionHintGz(cptHeight, element.attr(satHeight)) ctx.applyColorHint(cptBackgroundColor, element.attr(satBgcolor)) if s := element.attrul(satCellspacing): let n = cssLength(float32(s)) ctx.applyPresHint(makeEntry(cptBorderSpacingInline, n)) ctx.applyPresHint(makeEntry(cptBorderSpacingBlock, n)) of TAG_TD, TAG_TH: ctx.applyDimensionHintGz(cptWidth, element.attr(satWidth)) ctx.applyDimensionHintGz(cptHeight, element.attr(satHeight)) ctx.applyColorHint(cptBackgroundColor, element.attr(satBgcolor)) let colspan = element.attrulgz(satColspan).get(1001) if colspan < 1001: ctx.applyPresHint(makeEntry(cptChaColspan, int32(colspan))) let rowspan = element.attrul(satRowspan).get(65535) if rowspan < 65535: ctx.applyPresHint(makeEntry(cptChaRowspan, int32(rowspan))) of TAG_THEAD, TAG_TBODY, TAG_TFOOT, TAG_TR: ctx.applyDimensionHint(cptHeight, element.attr(satHeight)) ctx.applyColorHint(cptBackgroundColor, element.attr(satBgcolor)) of TAG_COL: ctx.applyDimensionHint(cptWidth, element.attr(satWidth)) of TAG_IMG, TAG_CANVAS, TAG_SVG: ctx.applyDimensionHint(cptWidth, element.attr(satWidth)) ctx.applyDimensionHint(cptHeight, element.attr(satHeight)) of TAG_HTML: ctx.applyPresHint(makeEntry(cptBgcolorIsCanvas, CSSValueBit(bgcolorIsCanvas: true))) of TAG_BODY: ctx.applyPresHint(makeEntry(cptBgcolorIsCanvas, CSSValueBit(bgcolorIsCanvas: true))) ctx.applyColorHint(cptBackgroundColor, element.attr(satBgcolor)) ctx.applyColorHint(cptColor, element.attr(satText)) of TAG_TEXTAREA: let textarea = HTMLTextAreaElement(element) let cols = textarea.attrul(satCols).get(20) let rows = textarea.attrul(satRows).get(1) ctx.applyLengthHint(cptWidth, cuCh, cols) ctx.applyLengthHint(cptHeight, cuEm, rows) of TAG_FONT: ctx.applyColorHint(cptColor, element.attr(satColor)) of TAG_INPUT: let input = HTMLInputElement(element) if input.inputType in InputTypeWithSize: let n = float32(element.attrulgz(satSize).get(20)) let length = resolveLength(cuCh, n, ctx.window.settings.attrsp[]) ctx.applyPresHint(makeEntry(cptInputIntrinsicSize, length.npx)) of TAG_PROGRESS: let position = element.getProgressPosition() if position > 0: ctx.applyPresHint(makeEntry(cptInputIntrinsicSize, float32(position))) of TAG_SELECT: if element.attrb(satMultiple): let size = element.attrulgz(satSize).get(4) ctx.applyLengthHint(cptHeight, cuEm, size) of TAG_OL: if n := element.attrl(satStart): if n > int32.low: let n = n - 1 let val = CSSValue( v: cvtCounterSet, counterSet: @[CSSCounterSet(name: satListItem.toAtom(), num: n)] ) ctx.applyPresHint(makeEntry(cptCounterReset, val)) of TAG_LI: if n := element.attrl(satValue): let val = CSSValue( v: cvtCounterSet, counterSet: @[CSSCounterSet(name: satListItem.toAtom(), num: n)] ) ctx.applyPresHint(makeEntry(cptCounterSet, val)) of TAG_HR: if dim := parseDimensionValues(element.attr(satWidth)): if dim.isPx: dim.npx = max(dim.npx, float32(ctx.window.settings.attrsp.ppc)) ctx.applyPresHint(makeEntry(cptWidth, dim)) ctx.applyColorHint(cptColor, element.attr(satColor)) else: discard proc applyVars(ctx: var ApplyValueContext; vars: seq[CSSVariable]; parentVars: CSSVariableMap) = if vars.len > 0: if ctx.vals.vars == nil: ctx.vals.vars = newCSSVariableMap(parentVars) for cvar in vars.ritems: ctx.vals.vars.putIfAbsent(cvar.name, cvar) proc applyDeclarations(rules: RuleList; parent, element: Element; window: Window; old: CSSValues): CSSValues = result = CSSValues() var parentVars: CSSVariableMap = nil var ctx = ApplyValueContext(window: window, vals: result, old: old) if parent != nil: parent.ensureStyle() ctx.parentComputed = parent.computed parentVars = ctx.parentComputed.vars for origin in CSSOrigin: for layer in rules.a[origin].layers: ctx.applyVars(layer.vars[cifImportant], parentVars) ctx.applyVars(rules.a[origin].unlayered.vars[cifImportant], parentVars) for origin in countdown(CSSOrigin.high, CSSOrigin.low): ctx.applyVars(rules.a[origin].unlayered.vars[cifNormal], parentVars) for layer in rules.a[origin].layers: ctx.applyVars(layer.vars[cifNormal], parentVars) if result.vars == nil: result.vars = parentVars # inherit parent ctx.applyImportantValues(rules.a[coUserAgent], rtSet) ctx.applyImportantValues(rules.a[coUser], rtUserAgent) ctx.applyImportantValues(rules.a[coAuthor], rtUser) ctx.applyNormalValues(rules.a[coAuthor], rtUser) ctx.applyNormalValues(rules.a[coUser], rtUserAgent) # Presentational hints override user agent style, but respect user/author # style. if element != nil: ctx.applyPresHints(element) ctx.applyNormalValues(rules.a[coUserAgent], rtSet) # fill in defaults if ctx.revertMap[cptColor] != rtSet or result{"color"}.t == cctCurrent: # do this first so currentcolor works result.initialOrInheritFrom(ctx.parentComputed, cptColor) var relayout = old != nil and old.relayout for t in CSSPropertyType: if ctx.revertMap[t] != rtSet: result.initialOrInheritFrom(ctx.parentComputed, t) if valueType(t) == cvtColor and result.words[t].color.t == cctCurrent: result.words[t].color = result{"color"} if old != nil and t in LayoutProperties: relayout = relayout or not result.equals(old, t) result.relayout = relayout # Quirk: it seems others aren't implementing what the spec says about # blockification. # Well, neither will I, because the spec breaks on actual websites. # Curse CSS. if result{"position"} in PositionAbsoluteFixed: if result{"display"} == DisplayInline: result{"display"} = DisplayInlineBlock elif result{"float"} != FloatNone or ctx.parentComputed != nil and ctx.parentComputed{"display"} in DisplayInnerFlex + DisplayInnerGrid: result{"display"} = result{"display"}.blockify() if (result{"overflow-x"} in {OverflowVisible, OverflowClip}) != (result{"overflow-y"} in {OverflowVisible, OverflowClip}): result{"overflow-x"} = result{"overflow-x"}.bfcify() result{"overflow-y"} = result{"overflow-y"}.bfcify() if element != nil and element.getBitmap() != nil: result{"display"} = result{"display"}.imgify() proc applyDeclarations(map: RuleListMap; pseudo: PseudoElement; parent, element: Element; window: Window; old: CSSValues): CSSValues = result = map[pseudo].applyDeclarations(parent, element, window, old) result.pseudo = pseudo proc applyStyle(element: Element) = let document = element.document let window = document.window var depends = DependencyInfo.default var map = RuleListMap.default map.calcRules(element, document.getRuleMap(), depends) let style = element.cachedStyle if window.settings.styling and style != nil: for decl in style.decls: let f = decl.f case decl.t of cdtVariable: map[peNone].a[coAuthor].unlayered.vars[f].add(CSSVariable( name: decl.v, items: parseDeclWithVar0(decl.value) )) of cdtNestedRule: discard of cdtProperty: if decl.hasVar: if entry := parseDeclWithVar(decl.p, decl.value): map[peNone].a[coAuthor].unlayered.vals[f].add(entry) else: map[peNone].a[coAuthor].unlayered.vals[f].parseComputedValues(decl.p, decl.value, window.settings.attrsp[]) element.applyStyleDependencies(depends) var computed = map.applyDeclarations(peNone, element.parentElement, element, window, element.computed) element.computed = computed for pseudo in peBefore .. PseudoElement.high: if map[pseudo].hasValues or window.settings.scripting == smApp: let next = computed.next let old = if next != nil and next.pseudo == pseudo: next else: nil let pcomputed = map.applyDeclarations(pseudo, element, nil, window, old) if pseudo == peMarker: pcomputed{"display"} = DisplayMarker computed.next = pcomputed computed = pcomputed proc ensureStyle*(element: Element) = if element.computed == nil or element.computed.invalid: element.applyStyle() # Forward declaration hack applyStyleImpl = applyStyle {.pop.} # raises: [] ���������������������������chawan-v0.4.0/src/css/cssparser.nim�����������������������������������������������������������������0000664�0000000�0000000�00000145774�15202323131�0017245�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/algorithm import html/catom import types/opt import utils/dtoawrap import utils/twtstr type CSSParser* = object toks*: seq[CSSToken] at: int # pointer into toks iqp: ptr UncheckedArray[char] # addr iq[0] iqlen: int # iq.len i*: int # pointer into iq # Tokens CSSTokenType* = enum cttIdent, cttFunction, cttAtKeyword, cttHash, cttString, cttBadString, cttUrl, cttBadUrl, cttDelim, cttNumber, cttPercentage, cttDimension, cttCdo = "<!--" cttCdc = "-->" cttWhitespace cttBang = "!" cttDollar = "$" cttAnd = "&" cttLparen = "(" cttRparen = ")" cttStar = "*" cttPlus = "+" cttComma = "," cttMinus = "-" cttDot = "." cttSlash = "/" cttColon = ":" cttSemicolon = ";" cttLt = "<" cttEquals = "=" cttGt = ">" cttRbracket = "[" cttLbracket = "]" cttCaret = "^" cttLbrace = "{" cttPipe = "|" cttRbrace = "}" cttTilde = "~" CSSTokenFlag = enum ctfId, ctfSign, ctfInteger CSSTokenUnion {.union.} = object i: int32 # cttNumber with ctfInteger f: float32 # cttNumber without ctfInteger u: uint32 # cttDelim (codepoint) ft: CSSFunctionType # cttFunction at: CSSAtRuleType # cttAtKeyword CSSDimensionType* = enum cdtUnknown = "" # AnB cdtN = "n" cdtNDash = "n-" # CSSUnit cuAuto = "" cuCap = "cap" cuCh = "ch" cuCm = "cm" cuDvb = "dvb" cuDvh = "dvh" cuDvi = "dvi" cuDvmax = "dvmax" cuDvmin = "dvmin" cuDvw = "dvw" cuEm = "em" cuEx = "ex" cuIc = "ic" cuIn = "in" cuLh = "lh" cuLvmax = "lvmax" cuLvmin = "lvmin" cuMm = "mm" cuPc = "pc" cuPt = "pt" cuPx = "px" cuRcap = "rcap" cuRch = "rch" cuRem = "rem" cuRex = "rex" cuRic = "ric" cuRlh = "rlh" cuSvmax = "svmax" cuSvmin = "svmin" cuVb = "vb" cuVh = "vh" cuVi = "vi" cuVmax = "vmax" cuVmin = "vmin" cuVw = "vw" # CSSAngle catDeg = "deg" catGrad = "grad" catRad = "rad" catTurn = "turn" CSSUnit* = range[cuAuto..cuVw] CSSAngleType* = range[catDeg..catTurn] CSSToken* = object t*: CSSTokenType flags*: set[CSSTokenFlag] dt*: CSSDimensionType tu: CSSTokenUnion s*: string # for ident/string-like, and unit of number tokens CSSRuleType* = enum crtAt, crtQualified CSSRule* = object case t*: CSSRuleType of crtAt: at*: CSSAtRule of crtQualified: qualified*: CSSQualifiedRule CSSAtRuleType* = enum cartUnknown = "-cha-unknown" cartImport = "import" cartMedia = "media" cartLayer = "layer" CSSAtRule* = ref object name*: CSSAtRuleType hasBlock*: bool prelude*: seq[CSSToken] oblock*: seq[CSSToken] CSSQualifiedRule* = ref object sels*: SelectorList decls*: seq[CSSDeclaration] CSSDeclarationType* = enum cdtProperty, cdtVariable, cdtNestedRule CSSImportantFlag* = enum cifNormal, cifImportant CSSWidePropertyType* = object sh*: CSSShorthandType # if sh is cstNone, then use p p*: CSSPropertyType CSSDeclaration* = object f*: CSSImportantFlag hasVar*: bool case t*: CSSDeclarationType of cdtProperty: p*: CSSWidePropertyType of cdtVariable: v*: CAtom of cdtNestedRule: r*: CSSQualifiedRule value*: seq[CSSToken] CSSFunctionType* = enum cftUnknown = "-cha-unknown" cftCalc = "calc" cftChaAnsi = "-cha-ansi" cftCounter = "counter" cftHost = "host" cftHsl = "hsl" cftHsla = "hsla" cftIs = "is" cftLang = "lang" cftNot = "not" cftNthChild = "nth-child" cftNthLastChild = "nth-last-child" cftRgb = "rgb" cftRgba = "rgba" cftSrc = "src" cftUrl = "url" cftVar = "var" cftWhere = "where" cftLayer = "layer" CSSSimpleBlock* = ref object value*: seq[CSSToken] CSSAnB* = tuple[A, B: int32] # Properties CSSShorthandType* = enum cstNone = "" cstAll = "all" cstMargin = "margin" cstPadding = "padding" cstBorderStyle = "border-style" cstBorderColor = "border-color" cstBorderWidth = "border-width" cstBackground = "background" cstListStyle = "list-style" cstFlex = "flex" cstFlexFlow = "flex-flow" cstOverflow = "overflow" cstVerticalAlign = "vertical-align" cstBorderSpacing = "border-spacing" cstBorderBottom = "border-bottom" cstBorderLeft = "border-left" cstBorderRight = "border-right" cstBorderTop = "border-top" cstBorder = "border" CSSPropertyType* = enum # primitive/enum properties: stored as byte # (when adding a new property, sort the individual lists, and update # LastBitPropType/LastWordPropType if needed.) cptBgcolorIsCanvas = "-cha-bgcolor-is-canvas" cptBorderBottomStyle = "border-bottom-style" cptBorderCollapse = "border-collapse" cptBorderLeftStyle = "border-left-style" cptBorderRightStyle = "border-right-style" cptBorderTopStyle = "border-top-style" cptBoxSizing = "box-sizing" cptCaptionSide = "caption-side" cptClear = "clear" cptDisplay = "display" cptFlexDirection = "flex-direction" cptFlexWrap = "flex-wrap" cptFloat = "float" cptFontStyle = "font-style" cptListStylePosition = "list-style-position" cptListStyleType = "list-style-type" cptOverflowX = "overflow-x" cptOverflowY = "overflow-y" cptPosition = "position" cptTextAlign = "text-align" cptTextDecoration = "text-decoration" cptTextTransform = "text-transform" cptVerticalAlign = "vertical-align" cptVisibility = "visibility" cptWhiteSpace = "white-space" cptWordBreak = "word-break" # half-word properties: stored as (32-bit) word cptBorderBottomWidth = "border-bottom-width" cptBorderLeftWidth = "border-left-width" cptBorderRightWidth = "border-right-width" cptBorderTopWidth = "border-top-width" cptChaColspan = "-cha-colspan" cptChaRowspan = "-cha-rowspan" cptFlexGrow = "flex-grow" cptFlexShrink = "flex-shrink" cptFontWeight = "font-weight" cptInputIntrinsicSize = "-cha-input-intrinsic-size" cptOpacity = "opacity" # word properties: stored as (64-bit) word cptBackgroundColor = "background-color" cptBorderBottomColor = "border-bottom-color" cptBorderLeftColor = "border-left-color" cptBorderRightColor = "border-right-color" cptBorderSpacingBlock = "-cha-border-spacing-block" cptBorderSpacingInline = "-cha-border-spacing-inline" cptBorderTopColor = "border-top-color" cptBottom = "bottom" cptColor = "color" cptFlexBasis = "flex-basis" cptFontSize = "font-size" cptHeight = "height" cptLeft = "left" cptMarginBottom = "margin-bottom" cptMarginLeft = "margin-left" cptMarginRight = "margin-right" cptMarginTop = "margin-top" cptMaxHeight = "max-height" cptMaxWidth = "max-width" cptMinHeight = "min-height" cptMinWidth = "min-width" cptPaddingBottom = "padding-bottom" cptPaddingLeft = "padding-left" cptPaddingRight = "padding-right" cptPaddingTop = "padding-top" cptRight = "right" cptTop = "top" cptVerticalAlignLength = "-cha-vertical-align-length" cptWidth = "width" cptZIndex = "z-index" # object properties: stored as a tagged ref object cptBackgroundImage = "background-image" cptContent = "content" cptCounterReset = "counter-reset" cptCounterIncrement = "counter-increment" cptCounterSet = "counter-set" cptQuotes = "quotes" # Selectors SelectorType* = enum stType, stId, stAttr, stClass, stUniversal, stPseudoClass, stIs = "is" stNot = "not" stWhere = "where" stLang = "lang" stNthChild = "nth-child" stNthLastChild = "nth-last-child" stHost = "host" SelectorTypeRecursive = range[stIs..stWhere] SelectorTypeNthChild = range[stNthChild..stNthLastChild] # Note: this must match the order csstree processes pseudo-elements. PseudoElement* = enum peNone = "-cha-none" peBefore = "before" peLinkHint = "-cha-link-hint" peLinkMarker = "-cha-link-marker" peMarker = "marker" peBackdrop = "backdrop" peAfter = "after" PseudoClass* = enum pcFirstChild = "first-child" pcLastChild = "last-child" pcOnlyChild = "only-child" pcHover = "hover" pcRoot = "root" pcChecked = "checked" pcFocus = "focus" pcLink = "link" pcVisited = "visited" pcTarget = "target" pcDisabled = "disabled" pcHost = "host" pcDefined = "defined" pcFirstNode = "-cha-first-node" pcLastNode = "-cha-last-node" pcBorderNonzero = "-cha-border-nonzero" CombinatorType* = enum ctNone, ctDescendant, ctChild, ctNextSibling, ctSubsequentSibling SelectorParser = object ctx: CSSParser failed: bool nested: bool RelationType* = enum rtExists, rtEquals, rtToken, rtBeginDash, rtStartsWith, rtEndsWith, rtContains RelationFlag* = enum rfNone, rfI, rfS SelectorRelation* = object t*: RelationType flag*: RelationFlag CSSNthChild* = object anb*: CSSAnB ofsels*: SelectorList HostSelector* = ref object specificity*: uint csel*: CompoundSelector Selector* = ref object # Simple selector case t*: SelectorType of stType: tag*: CAtom of stId: id*: CAtom of stClass: class*: CAtom of stAttr: attr*: CAtom rel*: SelectorRelation value*: string of stUniversal: #TODO namespaces? discard of stPseudoClass: pc*: PseudoClass of stIs, stWhere, stNot: fsels*: SelectorList of stHost: host*: HostSelector of stLang: lang*: string of stNthChild, stNthLastChild: nthChild*: CSSNthChild next: Selector CompoundSelector* = object ct*: CombinatorType # relation to the next entry in a ComplexSelector. head: Selector ComplexSelector* = object specificity*: uint pseudo*: PseudoElement csels: seq[CompoundSelector] SelectorList* = seq[ComplexSelector] when defined(gcDestructors): proc `=destroy`*(a: var CSSTokenUnion) = discard proc `=copy`*(a: var CSSTokenUnion; b: CSSTokenUnion) = copyMem(addr a, unsafeAddr b, sizeof(a)) # Forward declarations proc consumeDeclarations(ctx: var CSSParser; nested: bool; parentSels: openArray[CSSToken]): seq[CSSDeclaration] proc parseSelectorsConsume(toks: var seq[CSSToken]): SelectorList proc parseSelectorList(state: var SelectorParser; forgiving: bool): SelectorList proc parseComplexSelector(state: var SelectorParser): ComplexSelector proc parseCompoundSelector(state: var SelectorParser; pseudoElement: var PseudoElement; specificityOut: var uint): Selector proc addComponentValue(ctx: var CSSParser; toks: var seq[CSSToken]) proc seek*(ctx: var CSSParser) proc `$`*(tok: CSSToken): string proc `$`*(c: CSSRule): string proc `$`*(decl: CSSDeclaration): string proc `$`*(c: CSSSimpleBlock): string proc `$`*(slist: SelectorList): string proc `$`*(c: CSSQualifiedRule): string template fnum(tok: CSSToken): float32 = tok.tu.f template inum(tok: CSSToken): int32 = tok.tu.i template ft*(tok: CSSToken): CSSFunctionType = tok.tu.ft template at(tok: CSSToken): CSSAtRuleType = tok.tu.at template delim(tok: CSSToken): uint32 = tok.tu.u proc num*(tok: CSSToken): float32 {.inline.} = if ctfInteger in tok.flags: float32(tok.inum) else: tok.fnum proc toi*(tok: CSSToken): int32 {.inline.} = if ctfInteger in tok.flags: tok.inum else: int32(tok.fnum) proc `$`*(tok: CSSToken): string = return case tok.t: of cttAtKeyword: '@' & $tok.at of cttFunction: $tok.ft & '(' of cttUrl: "url(" & tok.s & ')' of cttHash: '#' & tok.s of cttIdent: tok.s of cttString: ("\"" & tok.s & "\"") of cttDelim: tok.delim.toUTF8() of cttNumber: if ctfInteger in tok.flags: $tok.inum else: dtoa(tok.fnum) of cttDimension: var s = if ctfInteger in tok.flags: $tok.inum else: dtoa(tok.fnum) if tok.dt == cdtUnknown: s &= tok.s else: s &= $tok.dt move(s) of cttPercentage: dtoa(tok.fnum) & '%' of cttWhitespace: " " of cttSemicolon: ";\n" of cttRbrace: "}\n" else: $tok.t proc `$`*(p: CSSWidePropertyType): string = if p.sh != cstNone: return $p.sh return $p.p proc name*(decl: CSSDeclaration): string = case decl.t of cdtProperty: return $decl.p of cdtVariable: return "--" & $decl.v of cdtNestedRule: assert false return "" proc `$`*(decl: CSSDeclaration): string = if decl.t == cdtNestedRule: return $decl.r result = decl.name & ": " for s in decl.value: result &= $s if decl.f == cifImportant: result &= " !important" result &= ";" proc `$`*(c: CSSSimpleBlock): string = result = "" for s in c.value: result &= $s proc `$`*(c: CSSAtRule): string = result = $c.name & ' ' for it in c.prelude: result &= $it result &= "{\n" for it in c.oblock: result &= $it result &= "}" proc `$`*(c: CSSQualifiedRule): string = result = $c.sels & " {\n" for decl in c.decls: result &= $decl & '\n' result &= "}\n" proc `$`*(c: CSSRule): string = case c.t of crtAt: return $c.at of crtQualified: return $c.qualified const LastBitPropType* = cptWordBreak const FirstHWordPropType* = LastBitPropType.succ const LastHWordPropType* = cptOpacity const FirstWordPropType* = LastHWordPropType.succ const LastWordPropType* = cptZIndex const FirstObjPropType* = LastWordPropType.succ proc shorthandType*(s: string): CSSShorthandType = return parseEnumNoCase[CSSShorthandType](s).get(cstNone) proc propertyType*(s: string): Opt[CSSPropertyType] = return parseEnumNoCase[CSSPropertyType](s) proc wide*(p: CSSPropertyType): CSSWidePropertyType = CSSWidePropertyType(sh: cstNone, p: p) proc anyPropertyType*(s: string): Opt[CSSWidePropertyType] = let sh = shorthandType(s) if sh == cstNone: let p = ?propertyType(s) return ok(CSSWidePropertyType(sh: sh, p: p)) return ok(CSSWidePropertyType(sh: sh)) proc cssNumberToken*(n: float32): CSSToken = let tu = CSSTokenUnion(f: n) return CSSToken(t: cttNumber, tu: tu) proc cssDimensionToken*(n: float32; dt: CSSDimensionType): CSSToken = let tu = CSSTokenUnion(f: n) CSSToken(t: cttDimension, tu: tu, dt: dt) proc cssPercentageToken*(n: float32; flags: set[CSSTokenFlag] = {}): CSSToken = let tu = CSSTokenUnion(f: n) return CSSToken(t: cttPercentage, tu: tu, flags: flags) proc cssDelimToken(c: char): CSSToken = let tu = CSSTokenUnion(u: uint32(c)) return CSSToken(t: cttDelim, tu: tu) proc cssFunctionToken(ft: CSSFunctionType): CSSToken = let tu = CSSTokenUnion(ft: ft) return CSSToken(t: cttFunction, tu: tu) proc cssAtKeywordToken(s: string): CSSToken = let at = parseEnumNoCase[CSSAtRuleType](s).get(cartUnknown) let tu = CSSTokenUnion(at: at) return CSSToken(t: cttAtKeyword, tu: tu) const IdentStart = AsciiAlpha + NonAscii + {'_'} const Ident = IdentStart + AsciiDigit + {'-'} proc consumeDelimToken(iq: openArray[char]; n: var int): CSSToken = let u = iq.nextUTF8(n) let tu = CSSTokenUnion(u: u) return CSSToken(t: cttDelim, tu: tu) # next, next(1) proc startsWithIdentSequenceDash(iq: openArray[char]; n: int): bool = return n < iq.len and iq[n] in IdentStart + {'-'} or n + 1 < iq.len and iq[n] == '\\' and iq[n + 1] != '\n' # next, next(1), next(2) proc startsWithIdentSequence(iq: openArray[char]; n: int): bool = if n >= iq.len: return false case iq[n] of '-': return n + 1 < iq.len and iq[n + 1] in IdentStart + {'-'} or n + 2 < iq.len and iq[n + 1] == '\\' and iq[n + 2] != '\n' of IdentStart: return true of '\\': return n + 1 < iq.len and iq[n + 1] != '\n' else: return false proc consumeEscape(iq: openArray[char]; n: var int): string = if n >= iq.len: return "\uFFFD" var m = n let c = iq[m] inc m let hex = hexValue(c) if hex != -1: var num = uint32(hex) var i = 0 while i <= 5 and m < iq.len: let val = hexValue(iq[m]) if val == -1: break num *= 0x10 num += uint32(val) inc m inc i if m < iq.len and iq[m] in AsciiWhitespace: inc m n = m if num == 0 or num > 0x10FFFF or num in 0xD800u32..0xDFFFu32: return "\uFFFD" return num.toUTF8() n = m return $c # assume the caller doesn't care about non-ascii proc consumeStringToken(iq: openArray[char]; ending: char; n: var int): CSSToken = var m = n var s = "" while m < iq.len: let c = iq[m] case c of '\n': n = m return CSSToken(t: cttBadString) of '\\': if m + 1 >= iq.len or iq[m + 1] == '\n': discard else: inc m s &= iq.consumeEscape(m) continue elif c == ending: inc m break else: s &= c inc m n = m return CSSToken(t: cttString, s: move(s)) proc consumeIdentSequence(iq: openArray[char]; n: var int): string = var s = "" var m = n while m < iq.len: let c = iq[m] if c == '\\' and m + 1 < iq.len and iq[m + 1] != '\n': inc m s &= iq.consumeEscape(m) continue elif c in Ident: s &= c else: break inc m n = m move(s) proc consumeNumericToken(iq: openArray[char]; n: var int): CSSToken = var flags: set[CSSTokenFlag] = {} var m = n var sign = 1i32 if m < iq.len: let c = iq[m] let s = if c == '+': 1i32 elif c == '-': -1i32 else: 0i32 if s != 0: flags.incl(ctfSign) sign = s inc m var integer = 0u32 while m < iq.len: let u = uint32(iq[m]) - uint32('0') if u > 9: break integer = max(integer * 10 + u, integer) inc m var tu = CSSTokenUnion() if m < iq.len and iq[m] == '%' or m + 1 < iq.len and iq[m] in {'.', 'e', 'E'} and iq[m + 1] in AsciiDigit or m + 2 < iq.len and iq[m] in {'e', 'E'} and iq[m + 1] in {'+', '-'} and iq[m + 2] in AsciiDigit: # this works because initCSSParser takes string only tu.f = float32(atod(cast[cstring](unsafeAddr iq[0]), n)) m = n if m < iq.len and iq[m] == '%': n = m + 1 return cssPercentageToken(tu.f, flags) else: flags.incl(ctfInteger) let ii = int64(integer) * sign tu.i = cast[int32](clamp(ii, int64(int32.low), int64(int32.high))) if iq.startsWithIdentSequence(m): var s = iq.consumeIdentSequence(m) n = m if dt := parseEnumNoCase[CSSDimensionType](s): return CSSToken(t: cttDimension, tu: tu, dt: dt, flags: flags) return CSSToken( t: cttDimension, tu: tu, dt: cdtUnknown, s: move(s), flags: flags ) n = m return CSSToken(t: cttNumber, tu: tu, flags: flags) proc consumeBadURL(iq: openArray[char]; n: int): int = var n = n while n < iq.len: let c = iq[n] inc n if c == ')': break if c == '\\' and n < iq.len and iq[n] != '\n': discard iq.consumeEscape(n) n const NonPrintable = {'\0'..'\8', '\v', '\x0E'..'\x1F', '\x7F'} proc consumeURL(iq: openArray[char]; n: var int): CSSToken = var res = CSSToken(t: cttUrl) var m = iq.skipBlanks(n) while m < iq.len: let c = iq[m] inc m case c of ')': break of '"', '\'', '(', NonPrintable: n = iq.consumeBadURL(m) return CSSToken(t: cttBadUrl) of AsciiWhitespace: m = iq.skipBlanks(m) if m >= iq.len: break if iq[m] == ')': inc m break n = iq.consumeBadURL(m) return CSSToken(t: cttBadUrl) of '\\': if m < iq.len and iq[m] != '\n': res.s &= iq.consumeEscape(m) else: n = iq.consumeBadURL(m) return CSSToken(t: cttBadUrl) else: res.s &= c n = m move(res) proc consumeIdentLikeToken(iq: openArray[char]; n: var int): CSSToken = var s = iq.consumeIdentSequence(n) var m = n if s.equalsIgnoreCase("url") and m < iq.len and iq[m] == '(': inc m while m + 1 < iq.len and iq[m] in AsciiWhitespace and iq[m + 1] in AsciiWhitespace: inc m n = m if m < iq.len and iq[m] in {'"', '\''} or m + 1 < iq.len and iq[m] in {'"', '\''} + AsciiWhitespace and iq[m + 1] in {'"', '\''}: return cssFunctionToken(cftUrl) return iq.consumeURL(n) if m < iq.len and iq[m] == '(': let ft = parseEnumNoCase[CSSFunctionType](s).get(cftUnknown) inc n return cssFunctionToken(ft) return CSSToken(t: cttIdent, s: move(s)) proc nextToken(iq: openArray[char]; n: var int): bool = var m = n while m + 1 < iq.len and iq[m] == '/' and iq[m + 1] == '*': m += 2 while m < iq.len and not (m + 1 < iq.len and iq[m] == '*' and iq[m + 1] == '/'): inc m if m + 1 < iq.len: inc m if m < iq.len: inc m n = m return m < iq.len proc consume(iq: openArray[char]; n: var int): CSSToken = let c = iq[n] inc n case c of AsciiWhitespace: n = iq.skipBlanks(n) return CSSToken(t: cttWhitespace) of '"', '\'': return iq.consumeStringToken(c, n) of '#': if n < iq.len and iq[n] in Ident or n + 1 < iq.len and iq[n] == '\\' and iq[n + 1] != '\n': var flags: set[CSSTokenFlag] = {} if iq.startsWithIdentSequence(n): flags.incl(ctfId) return CSSToken(t: cttHash, s: iq.consumeIdentSequence(n), flags: flags) return cssDelimToken('#') of '(': return CSSToken(t: cttLparen) of ')': return CSSToken(t: cttRparen) of '{': return CSSToken(t: cttLbrace) of '}': return CSSToken(t: cttRbrace) of '+': # starts with a number if n < iq.len and iq[n] in AsciiDigit or n + 1 < iq.len and iq[n] == '.' and iq[n + 1] in AsciiDigit: dec n return iq.consumeNumericToken(n) return CSSToken(t: cttPlus) of ',': return CSSToken(t: cttComma) of '-': # starts with a number if n < iq.len and iq[n] in AsciiDigit or n + 1 < iq.len and iq[n] == '.' and iq[n + 1] in AsciiDigit: dec n return iq.consumeNumericToken(n) elif n + 1 < iq.len and iq[n] == '-' and iq[n + 1] == '>': n += 2 return CSSToken(t: cttCdc) elif iq.startsWithIdentSequenceDash(n): dec n return iq.consumeIdentLikeToken(n) else: return CSSToken(t: cttMinus) of '.': # starts with a number if n < iq.len and iq[n] in AsciiDigit: dec n return iq.consumeNumericToken(n) return CSSToken(t: cttDot) of ':': return CSSToken(t: cttColon) of ';': return CSSToken(t: cttSemicolon) of '<': if n + 2 < iq.len and iq[n] == '!' and iq[n + 1] == '-' and iq[n + 2] == '-': n += 3 return CSSToken(t: cttCdo) return CSSToken(t: cttLt) of '@': if iq.startsWithIdentSequence(n): let s = iq.consumeIdentSequence(n) return cssAtKeywordToken(s) return cssDelimToken('@') of '[': return CSSToken(t: cttLbracket) of '\\': if n < iq.len and iq[n] != '\n': dec n return iq.consumeIdentLikeToken(n) return cssDelimToken('\\') of ']': return CSSToken(t: cttRbracket) of AsciiDigit: dec n return iq.consumeNumericToken(n) of IdentStart: dec n return iq.consumeIdentLikeToken(n) of '/': return CSSToken(t: cttSlash) of '>': return CSSToken(t: cttGt) of '*': return CSSToken(t: cttStar) of '~': return CSSToken(t: cttTilde) of '|': return CSSToken(t: cttPipe) of '^': return CSSToken(t: cttCaret) of '$': return CSSToken(t: cttDollar) of '=': return CSSToken(t: cttEquals) of '!': return CSSToken(t: cttBang) of '&': return CSSToken(t: cttAnd) else: dec n return iq.consumeDelimToken(n) proc tokenPair(t: CSSTokenType): CSSTokenType = case t of cttLparen, cttFunction: return cttRparen of cttLbracket: return cttRbracket of cttLbrace: return cttRbrace else: return t template iq(ctx: CSSParser): openArray[char] = ctx.iqp.toOpenArray(0, ctx.iqlen - 1) # iq *must* be a string, because parseFloat32 needs the NUL terminator. proc initCSSParser*(iq: string): CSSParser = if iq.len <= 0: return CSSParser() return CSSParser( iqp: cast[ptr UncheckedArray[char]](unsafeAddr iq[0]), iqlen: iq.len ) proc initCSSParser*(toks: openArray[CSSToken]): CSSParser = return CSSParser(toks: @toks) # Destroys `toks'. proc initCSSParserSink*(toks: var seq[CSSToken]): CSSParser = return CSSParser(toks: move(toks)) proc initCSSDeclaration*(name: string): Opt[CSSDeclaration] = if name.startsWith("--"): return ok(CSSDeclaration( t: cdtVariable, v: name.toOpenArray(2, name.high).toAtom() )) let p = ?anyPropertyType(name) ok(CSSDeclaration(t: cdtProperty, p: p)) proc peekToken*(ctx: var CSSParser): lent CSSToken = if ctx.at >= ctx.toks.len: var i = ctx.i doAssert ctx.iq.nextToken(i) ctx.toks.add(ctx.iq.consume(i)) ctx.i = i return ctx.toks[ctx.at] proc consume*(ctx: var CSSParser): lent CSSToken = let at = ctx.at if at >= ctx.toks.len: var i = ctx.i doAssert ctx.iq.nextToken(i) ctx.toks.add(ctx.iq.consume(i)) ctx.i = i inc ctx.at return ctx.toks[at] proc seekToken*(ctx: var CSSParser) = if ctx.at < ctx.toks.len: inc ctx.at else: discard ctx.consume() proc has*(ctx: var CSSParser): bool = return ctx.at < ctx.toks.len or ctx.iq.nextToken(ctx.i) proc peekTokenType*(ctx: var CSSParser): CSSTokenType = ctx.peekToken().t proc peekIdentNoCase*(ctx: var CSSParser; s: string): bool = ctx.peekTokenType() == cttIdent and ctx.peekToken().s.equalsIgnoreCase(s) proc peekFunction*(ctx: var CSSParser; ft: CSSFunctionType): bool = ctx.peekTokenType() == cttFunction and ctx.peekToken().ft == ft proc consumeInt*(ctx: var CSSParser): Opt[int32] = let tok = ctx.peekToken() if tok.t != cttNumber or ctfInteger notin tok.flags: return err() ok(ctx.consume().inum) proc skipBlanks*(ctx: var CSSParser) = while ctx.has() and ctx.peekTokenType() == cttWhitespace: ctx.seekToken() proc skipBlanksCheckHas*(ctx: var CSSParser): Opt[void] = ctx.skipBlanks() if not ctx.has(): return err() ok() proc skipBlanksCheckDone*(ctx: var CSSParser): Opt[void] = ctx.skipBlanks() if ctx.has(): return err() ok() proc checkFunctionEnd*(ctx: var CSSParser): Opt[void] = if ctx.skipBlanksCheckDone().isOk: return ok() if ctx.peekTokenType() != cttRparen: return err() ctx.seekToken() ok() proc addComponentValue(ctx: var CSSParser; toks: var seq[CSSToken]) = var tok = ctx.consume() let t = tok.t toks.add(move(tok)) if (let pair = t.tokenPair; pair != t): while ctx.has(): let t = ctx.peekTokenType() ctx.addComponentValue(toks) if t == pair: break proc addUntil*(ctx: var CSSParser; tt: CSSTokenType; toks: var seq[CSSToken]): Opt[CSSToken] = while ctx.has(): if ctx.peekTokenType() == tt: return ok(ctx.consume()) ctx.addComponentValue(toks) err() proc addUntil(ctx: var CSSParser; tt: set[CSSTokenType]; toks: var seq[CSSToken]): Opt[CSSToken] = while ctx.has(): if ctx.peekTokenType() in tt: return ok(ctx.consume()) ctx.addComponentValue(toks) err() proc skipUntil(ctx: var CSSParser; t: CSSTokenType) = while ctx.has(): let it = ctx.peekTokenType() ctx.seek() if it == t: break proc skipFunction*(ctx: var CSSParser) = ctx.skipUntil(cttRparen) proc seek*(ctx: var CSSParser) = let tok = ctx.consume() let pair = tok.t.tokenPair if pair != tok.t: ctx.skipUntil(pair) proc addPreludeComponentValue(ctx: var CSSParser; parentSels: openArray[CSSToken]; andSeen: var bool; toks: var seq[CSSToken]) = var tok = ctx.consume() let t = tok.t if parentSels.len > 0 and t == cttAnd: toks.add(CSSToken(t: cttColon)) toks.add(cssFunctionToken(cftIs)) toks.add(parentSels) toks.add(CSSToken(t: cttRparen)) andSeen = true else: toks.add(move(tok)) if (let pair = t.tokenPair; pair != t): while ctx.has(): let t = ctx.peekTokenType() ctx.addPreludeComponentValue(parentSels, andSeen, toks) if t == pair: break proc addPrelude(ctx: var CSSParser; parentSels: openArray[CSSToken]; nested, semi: bool; andSeen: var bool; toks: var seq[CSSToken]): Opt[void] = while ctx.has(): let tt = ctx.peekTokenType() if tt == cttLbrace or semi and tt == cttSemicolon: ctx.seekToken() return ok() if tt == cttRbrace and nested: return err() ctx.addPreludeComponentValue(parentSels, andSeen, toks) err() proc consumeQualifiedRule2(ctx: var CSSParser; prelude: var seq[CSSToken]; nested, semi: bool; parentSels: openArray[CSSToken]): Opt[CSSQualifiedRule] = var prelude = move(prelude) var andSeen: bool ?ctx.addPrelude(parentSels, nested, semi, andSeen, prelude) if not andSeen and parentSels.len > 0: var prelude2 = @parentSels if parentSels[^1].t != cttWhitespace: prelude2.add(CSSToken(t: cttWhitespace)) prelude2.add(prelude) prelude = move(prelude2) let r = CSSQualifiedRule() r.decls = ctx.consumeDeclarations(nested = true, prelude) r.sels = parseSelectorsConsume(prelude) ok(r) proc consumeQualifiedRule(ctx: var CSSParser; nested: bool; parentSels: openArray[CSSToken]): Opt[CSSQualifiedRule] = var prelude: seq[CSSToken] ctx.consumeQualifiedRule2(prelude, nested, semi = false, parentSels) proc skipDeclaration(ctx: var CSSParser) = while ctx.has(): let it = ctx.peekTokenType() if it == cttRbrace: break ctx.seek() if it == cttSemicolon: break proc consumeDeclaration2(ctx: var CSSParser; name: string): Opt[CSSDeclaration] = let x = initCSSDeclaration(name) if x.isErr: ctx.skipDeclaration() return err() var decl = x.get ctx.seekToken() ctx.skipBlanks() var lastTokIdx1 = -1 var lastTokIdx2 = -1 var hasVar = false while ctx.has(): case ctx.peekTokenType() of cttSemicolon: ctx.seekToken() break of cttWhitespace: discard of cttRbrace: break else: lastTokIdx1 = lastTokIdx2 lastTokIdx2 = decl.value.len let olen = decl.value.len ctx.addComponentValue(decl.value) for it in decl.value.toOpenArray(olen, decl.value.high): if it.t == cttFunction and it.ft == cftVar: hasVar = true break decl.hasVar = hasVar if lastTokIdx1 != -1 and lastTokIdx2 != -1: let lastTok1 = decl.value[lastTokIdx1] let lastTok2 = decl.value[lastTokIdx2] if lastTok1.t == cttBang and lastTok2.t == cttIdent and lastTok2.s.equalsIgnoreCase("important"): decl.value.setLen(lastTokIdx1) decl.f = cifImportant while decl.value.len > 0 and decl.value[^1].t == cttWhitespace: decl.value.setLen(decl.value.len - 1) ok(move(decl)) #TODO for supports proc consumeDeclaration(ctx: var CSSParser): Opt[CSSDeclaration] {.used.} = let tok = ctx.consume() ?ctx.skipBlanksCheckHas() if ctx.peekTokenType() != cttColon: ctx.skipDeclaration() return err() ctx.consumeDeclaration2(tok.s) proc consumeAtRule(ctx: var CSSParser): CSSAtRule = let name = ctx.consume().at result = CSSAtRule(name: name) if found := ctx.addUntil({cttSemicolon, cttLbrace}, result.prelude): if found.t == cttLbrace: result.hasBlock = true while ctx.has(): let t = ctx.peekTokenType() if t == cttRbrace: ctx.seek() break ctx.addComponentValue(result.oblock) proc consumeDeclarations(ctx: var CSSParser; nested: bool; parentSels: openArray[CSSToken]): seq[CSSDeclaration] = result = @[] var valid = not nested while ctx.has(): case ctx.peekTokenType() of cttWhitespace, cttSemicolon: ctx.seekToken() of cttAtKeyword: discard ctx.consumeAtRule() of cttRbrace: ctx.seekToken() if nested: valid = true break of cttIdent: var tok = ctx.consume() var blank = false if ctx.has() and ctx.peekTokenType() == cttWhitespace: blank = true ctx.seekToken() if ctx.has() and ctx.peekTokenType() == cttColon: if decl := ctx.consumeDeclaration2(tok.s): # looks ridiculous, but it's the only way to convince refc not # to copy the seq... TODO remove when moving to ARC var value = move(decl.value) result.add(move(decl)) result[^1].value = move(value) elif nested: var prelude: seq[CSSToken] = @[move(tok)] if blank: prelude.add(CSSToken(t: cttWhitespace)) if rule := ctx.consumeQualifiedRule2(prelude, nested = true, semi = true, parentSels): result.add(CSSDeclaration(t: cdtNestedRule, r: rule)) else: # Note: I don't think the branch on nested matches the spec, but # this is what others seem to implement. ctx.skipDeclaration() else: if rule := ctx.consumeQualifiedRule(nested = true, parentSels): result.add(CSSDeclaration(t: cdtNestedRule, r: rule)) if not valid: result.setLen(0) proc consumeRule(ctx: var CSSParser; topLevel: bool): Opt[CSSRule] = ?ctx.skipBlanksCheckHas() let t = ctx.peekTokenType() if t == cttAtKeyword: let at = ctx.consumeAtRule() if at != nil: return ok(CSSRule(t: crtAt, at: at)) elif topLevel and t in {cttCdo, cttCdc}: ctx.seekToken() return err() let qualified = ?ctx.consumeQualifiedRule(nested = false, []) ok(CSSRule(t: crtQualified, qualified: qualified)) iterator parseListOfRules*(ctx: var CSSParser; topLevel: bool): CSSRule {.inline.} = while ctx.has(): if rule := ctx.consumeRule(topLevel): yield rule proc parseDeclarations*(iq: string): seq[CSSDeclaration] = var ctx = initCSSParser(iq) return ctx.consumeDeclarations(nested = false, []) proc parseComponentValues*(iq: string): seq[CSSToken] = var ctx = initCSSParser(iq) result = @[] while ctx.has(): result.add(ctx.consume()) proc consumeImports*(ctx: var CSSParser): seq[CSSAtRule] = result = @[] while ctx.has(): case ctx.peekTokenType() of cttWhitespace: ctx.seekToken() of cttAtKeyword: let rule = ctx.consumeAtRule() if rule.name != cartImport or rule.oblock.len > 0: break result.add(rule) else: break type AnBIdent = enum abiOdd = "odd" abiEven = "even" abiN = "n" abiDashN = "-n" abiNDash = "n-" abiDashNDash = "-n-" proc isInteger(tok: CSSToken): bool = tok.t == cttNumber and ctfInteger in tok.flags proc isUnsignedInteger(tok: CSSToken): bool = tok.isInteger() and ctfSign notin tok.flags proc parseAnB(ctx: var CSSParser): Opt[CSSAnB] = ?ctx.skipBlanksCheckHas() var tok = ctx.peekToken() let isPlus = tok.t == cttPlus let noPlus = if not isPlus: Opt[void].ok() else: Opt[void].err() if isPlus: ctx.seekToken() tok = ctx.peekToken() case tok.t of cttIdent: ctx.seekToken() if x := parseEnumNoCase[AnBIdent](tok.s): case x of abiOdd: ?noPlus return ok((2i32, 1i32)) of abiEven: ?noPlus return ok((2i32, 0i32)) of abiN: if ctx.skipBlanksCheckDone().isOk: return ok((1i32, 0i32)) let tok2 = ctx.peekToken() if tok2.t in {cttPlus, cttMinus}: ctx.seekToken() let sign = if tok2.t == cttPlus: 1i32 else: -1i32 ?ctx.skipBlanksCheckHas() let tok3 = ctx.peekToken() if not tok3.isUnsignedInteger(): return ok((1i32, 0i32)) ctx.seekToken() return ok((1i32, sign * tok3.inum)) elif tok2.isInteger(): if ctfInteger notin tok2.flags: return ok((1i32, 0i32)) ctx.seekToken() return ok((1i32, tok2.inum)) else: return ok((1i32, 0i32)) of abiDashN: ?noPlus if ctx.skipBlanksCheckDone().isOk: return ok((-1i32, 0i32)) let tok2 = ctx.peekToken() if tok2.t in {cttPlus, cttMinus}: ctx.seekToken() let sign = if tok2.t == cttPlus: 1i32 else: -1i32 ?ctx.skipBlanksCheckHas() let tok3 = ctx.peekToken() if not tok3.isUnsignedInteger(): return ok((-1i32, 0i32)) ctx.seekToken() return ok((-1i32, sign * tok3.inum)) elif tok2.isInteger(): ctx.seekToken() return ok((-1i32, tok2.inum)) else: return ok((-1i32, 0i32)) of abiNDash: ?ctx.skipBlanksCheckHas() let tok2 = ctx.peekToken() if not tok2.isUnsignedInteger(): return err() ctx.seekToken() return ok((1i32, -tok2.inum)) of abiDashNDash: ?noPlus ?ctx.skipBlanksCheckHas() let tok2 = ctx.peekToken() if not tok2.isUnsignedInteger(): return err() ctx.seekToken() return ok((-1i32, -tok2.inum)) elif tok.s.startsWithIgnoreCase("n-"): let n = ?parseInt32(tok.s.toOpenArray(2, tok.s.high)) return ok((1i32, n)) elif tok.s.startsWithIgnoreCase("-n-"): ?noPlus let n = ?parseInt32(tok.s.toOpenArray(2, tok.s.high)) return ok((-1i32, -n)) else: return err() of cttNumber: if ctfInteger notin tok.flags: return err() ctx.seekToken() ?noPlus # <integer> return ok((0i32, tok.inum)) of cttDimension: if ctfInteger notin tok.flags: return err() ctx.seekToken() ?noPlus case tok.dt of cdtN: # <n-dimension> if ctx.skipBlanksCheckDone().isOk: return ok((tok.inum, 0i32)) let tok2 = ctx.peekToken() if tok2.t in {cttPlus, cttMinus}: ctx.seekToken() let sign = if tok2.t == cttPlus: 1i32 else: -1i32 ?ctx.skipBlanksCheckHas() let tok3 = ctx.peekToken() if not tok3.isUnsignedInteger(): return ok((tok.inum, 0i32)) ctx.seekToken() return ok((tok.inum, sign * tok3.inum)) elif tok2.isInteger(): ctx.seekToken() return ok((tok.inum, tok2.inum)) else: return ok((tok.inum, 0i32)) of cdtNDash: # <ndash-dimension> ?ctx.skipBlanksCheckHas() let tok2 = ctx.peekToken() if not tok2.isUnsignedInteger(): return err() ctx.seekToken() return ok((tok.inum, -tok2.inum)) of cdtUnknown: if tok.s.startsWithIgnoreCase("n-"): # <ndashdigit-dimension> let n = ?parseInt32(tok.s.toOpenArray(2, tok.s.high)) return ok((tok.inum, n)) return err() else: return err() else: return err() iterator items*(csel: CompoundSelector): Selector {.inline.} = var it = csel.head while it != nil: yield it it = it.next iterator ritems*(cxsel: ComplexSelector): lent CompoundSelector {.inline.} = for csel in cxsel.csels.ritems: yield csel proc `[]`*(cxsel: ComplexSelector; i: int): lent CompoundSelector {.inline.} = return cxsel.csels[i] proc `[]`*(cxsel: ComplexSelector; i: BackwardsIndex): lent CompoundSelector {.inline.} = return cxsel[cxsel.csels.len - int(i)] proc `[]`*(cxsel: var ComplexSelector; i: BackwardsIndex): var CompoundSelector {.inline.} = return cxsel.csels[i] proc len*(cxsel: ComplexSelector): int {.inline.} = return cxsel.csels.len iterator items*(cxsel: ComplexSelector): lent CompoundSelector {.inline.} = for it in cxsel.csels: yield it proc `$`*(nthChild: CSSNthChild): string = result = $nthChild.anb.A & 'n' & $nthChild.anb.B if nthChild.ofsels.len != 0: result &= " of " result &= $nthChild.ofsels proc `$`*(sel: Selector): string = case sel.t of stType: return $sel.tag of stId: return "#" & $sel.id of stAttr: let rel = case sel.rel.t of rtExists: "" of rtEquals: "=" of rtToken: "~=" of rtBeginDash: "|=" of rtStartsWith: "^=" of rtEndsWith: "$=" of rtContains: "*=" let flag = case sel.rel.flag of rfNone: "" of rfI: " i" of rfS: " s" return '[' & $sel.attr & rel & sel.value & flag & ']' of stClass: return "." & $sel.class of stUniversal: return "*" of stPseudoClass: return ':' & $sel.pc of stIs, stNot, stWhere, stHost: return ":" & $sel.t & '(' & $sel.fsels & ')' of stLang: return ":lang(" & sel.lang & ')' of stNthChild, stNthLastChild: return ':' & $sel.t & '(' & $sel.nthChild & ')' proc `$`*(sels: CompoundSelector): string = result = "" for sel in sels: result &= $sel proc `$`*(cxsel: ComplexSelector): string = result = "" for sels in cxsel: result &= $sels case sels.ct of ctDescendant: result &= ' ' of ctChild: result &= " > " of ctNextSibling: result &= " + " of ctSubsequentSibling: result &= " ~ " of ctNone: discard if cxsel.pseudo != peNone: result &= "::" & $cxsel.pseudo proc `$`*(slist: SelectorList): string = result = "" var s = false for cxsel in slist: if s: result &= ", " result &= $cxsel s = true proc getSpecificity(sel: Selector): uint = case sel.t of stId: return 1000000 of stClass, stAttr, stPseudoClass, stLang: return 1000 of stType: return 1 of stUniversal, stWhere: return 0 of stIs, stNot: var best = 0u for child in sel.fsels: let s = child.specificity if s > best: best = s return best of stHost: return sel.host.specificity of stNthChild, stNthLastChild: var best = 0u if sel.nthChild.ofsels.len != 0: for child in sel.nthChild.ofsels: let s = child.specificity if s > best: best = s return 1000 + best proc consume(state: var SelectorParser): CSSToken = state.ctx.consume() proc has(state: var SelectorParser): bool = return not state.failed and state.ctx.has() proc peekToken(state: var SelectorParser): lent CSSToken = return state.ctx.peekToken() proc peekTokenType(state: var SelectorParser): CSSTokenType = return state.ctx.peekTokenType() proc seekToken(state: var SelectorParser) = state.ctx.seekToken() template fail() = state.failed = true return proc skipUntil(state: var SelectorParser; t: CSSTokenType) = state.ctx.skipUntil(t) proc skipFunction(state: var SelectorParser) = state.ctx.skipFunction() proc skipBlanks(state: var SelectorParser) = state.ctx.skipBlanks() # Functions that may contain other selectors, functions, etc. proc parseRecursiveSelectorFunction(state: var SelectorParser; t: SelectorTypeRecursive; forgiving: bool): Selector = let onested = state.nested state.nested = true let fun = Selector( t: t, fsels: state.parseSelectorList(forgiving) ) state.skipFunction() state.nested = onested if fun.fsels.len == 0: fail return fun proc parseHost(state: var SelectorParser): Selector = let onested = state.nested state.nested = true var pseudo = peNone var specificity: uint let head = state.parseCompoundSelector(pseudo, specificity) state.skipFunction() state.nested = onested if head == nil or pseudo != peNone: fail let host = HostSelector( csel: CompoundSelector(head: head), specificity: specificity + 1000 ) Selector(t: stHost, host: host) proc parseNthChild(state: var SelectorParser; t: SelectorTypeNthChild): Selector = let x = state.ctx.parseAnB() if x.isErr: state.skipFunction() fail let anb = x.get state.skipBlanks() if not state.has() or state.peekTokenType() == cttRparen: state.skipFunction() return Selector(t: t, nthChild: CSSNthChild(anb: anb)) let lasttok = state.consume() if lasttok.t != cttIdent or not lasttok.s.equalsIgnoreCase("of"): state.skipFunction() fail state.skipBlanks() if not state.has() or state.peekTokenType() == cttRparen: state.skipFunction() fail let onested = state.nested state.nested = true let sel = Selector( t: t, nthChild: CSSNthChild( anb: anb, ofsels: state.parseSelectorList(forgiving = false) ) ) state.skipFunction() state.nested = onested if sel.nthChild.ofsels.len == 0: fail return sel proc parseLang(state: var SelectorParser): Selector = state.skipBlanks() if not state.has(): fail let tok = state.consume() let b = tok.t != cttIdent or not state.has() or state.peekTokenType() != cttRparen state.skipFunction() if b: fail return Selector(t: stLang, lang: tok.s) proc parseSelectorFunction(state: var SelectorParser; ft: CSSFunctionType): Selector = return case ft of cftNot: state.parseRecursiveSelectorFunction(stNot, forgiving = false) of cftIs: state.parseRecursiveSelectorFunction(stIs, forgiving = true) of cftWhere: state.parseRecursiveSelectorFunction(stWhere, forgiving = true) of cftHost: state.parseHost() of cftNthChild: state.parseNthChild(stNthChild) of cftNthLastChild: state.parseNthChild(stNthLastChild) of cftLang: state.parseLang() else: fail proc parsePseudoSelector(state: var SelectorParser; pseudoElement: var PseudoElement): Selector = result = nil if not state.has(): fail let tok = state.consume() pseudoElement = peNone case tok.t of cttIdent: if tok.s.equalsIgnoreCase("before"): pseudoElement = peBefore # fall through elif tok.s.equalsIgnoreCase("after"): pseudoElement = peAfter # fall through elif pc := parseEnumNoCase[PseudoClass](tok.s): return Selector(t: stPseudoClass, pc: pc) else: fail of cttColon: if not state.has(): fail let tok = state.consume() if tok.t != cttIdent: fail pseudoElement = parseEnumNoCase[PseudoElement](tok.s).get(peNone) if pseudoElement == peNone: fail # fall through of cttFunction: return state.parseSelectorFunction(tok.ft) else: fail state.skipBlanks() if state.nested or state.has() and state.peekTokenType() != cttComma: fail const CaseInsensitiveAttr = [ satAccept, satAcceptCharset, satAlign, satAlink, satAxis, satBgcolor, satCharset, satChecked, satClear, satCodetype, satColor, satCompact, satDeclare, satDefer, satDir, satDirection, satDisabled, satEnctype, satFace, satFrame, satHreflang, satHttpEquiv, satLang, satLanguage, satLink, satMedia, satMethod, satMultiple, satNohref, satNoresize, satNoshade, satNowrap, satReadonly, satRel, satRev, satRules, satScope, satScrolling, satSelected, satShape, satTarget, satText, satType, satValign, satValuetype, satVlink ] proc parseAttributeSelector(state: var SelectorParser): Selector = state.skipBlanks() if not state.has() or state.peekTokenType() == cttRbracket: state.skipUntil(cttRbracket) fail let attrToken = state.consume() if attrToken.t != cttIdent: state.skipUntil(cttRbracket) fail let attr = attrToken.s.toAtomLower() state.skipBlanks() if not state.has(): fail let delim = state.consume() if delim.t == cttRbracket: return Selector( t: stAttr, attr: attr, rel: SelectorRelation(t: rtExists) ) let rel = case delim.t of cttTilde: rtToken of cttPipe: rtBeginDash of cttCaret: rtStartsWith of cttDollar: rtEndsWith of cttStar: rtContains of cttEquals: rtEquals else: state.skipUntil(cttRbracket) fail if rel != rtEquals: if not state.has(): fail let delim = state.consume() if delim.t != cttEquals: if delim.t != cttRbracket: state.skipUntil(cttRbracket) fail state.skipBlanks() if not state.has(): fail let value = state.consume() if value.t notin {cttIdent, cttString}: if value.t != cttRbracket: state.skipUntil(cttRbracket) fail state.skipBlanks() var flag = if attr.toStaticAtom() in CaseInsensitiveAttr: rfNone else: rfS if state.has() and state.peekTokenType() != cttRbracket: let delim = state.consume() if delim.t != cttIdent: state.skipUntil(cttRbracket) fail if delim.s.equalsIgnoreCase("i"): flag = rfI elif delim.s.equalsIgnoreCase("s"): flag = rfS if not state.has() or state.consume().t != cttRbracket: state.skipUntil(cttRbracket) fail return Selector( t: stAttr, attr: attr, value: value.s, rel: SelectorRelation(t: rel, flag: flag) ) proc parseClassSelector(state: var SelectorParser): Selector = if not state.has(): fail let tok = state.consume() if tok.t != cttIdent: fail let class = tok.s.toAtomLower() Selector(t: stClass, class: class) # returns head proc parseCompoundSelector(state: var SelectorParser; pseudoElement: var PseudoElement; specificityOut: var uint): Selector = var head: Selector = nil var tail: Selector = nil var specificity = 0u while state.has(): let tok = state.peekToken() var sel: Selector case tok.t of cttIdent: state.seekToken() sel = Selector(t: stType, tag: tok.s.toAtomLower()) of cttColon: state.seekToken() sel = state.parsePseudoSelector(pseudoElement) of cttHash: state.seekToken() if ctfId notin tok.flags: fail sel = Selector(t: stId, id: tok.s.toAtomLower()) of cttDot: state.seekToken() sel = state.parseClassSelector() of cttStar: state.seekToken() sel = Selector(t: stUniversal) of cttLbracket: state.seekToken() sel = state.parseAttributeSelector() of cttRparen: if not state.nested: fail break of cttComma, cttPlus, cttGt, cttTilde, cttWhitespace: break else: fail if sel != nil: if head == nil: head = sel else: tail.next = sel tail = sel specificity += sel.getSpecificity() specificityOut = specificity head proc parseComplexSelector(state: var SelectorParser): ComplexSelector = var pseudo = peNone result = ComplexSelector() while true: state.skipBlanks() var specificity: uint let head = state.parseCompoundSelector(pseudo, specificity) if state.failed: break if head == nil and pseudo == peNone: fail result.specificity += specificity result.csels.add(CompoundSelector(head: head)) if not state.has() or state.nested and state.peekTokenType() == cttRparen: break # finish let tok = state.consume() case tok.t of cttGt: result[^1].ct = ctChild of cttPlus: result[^1].ct = ctNextSibling of cttTilde: result[^1].ct = ctSubsequentSibling of cttWhitespace: if not state.has() or state.peekTokenType() == cttComma or state.nested and state.peekTokenType() == cttRparen: break # skip trailing whitespace elif state.peekTokenType() in {cttGt, cttPlus, cttTilde}: case state.consume().t of cttGt: result[^1].ct = ctChild of cttPlus: result[^1].ct = ctNextSibling else: result[^1].ct = ctSubsequentSibling # cttTilde else: result[^1].ct = ctDescendant of cttComma: break # finish else: fail if result.len == 0 or result[^1].ct != ctNone: fail result.pseudo = pseudo if pseudo != peNone: # pseudo-elements have a specificity of 1 inc result.specificity proc parseSelectorList(state: var SelectorParser; forgiving: bool): SelectorList = var res: SelectorList = @[] while true: if not state.has() or state.nested and state.peekTokenType() == cttRparen: break let csel = state.parseComplexSelector() if state.failed: if not forgiving: return @[] # forgiving is always nested assert state.nested state.failed = false while state.has(): case state.peekTokenType() of cttComma: state.seekToken() break of cttRparen: break else: state.ctx.seek() else: res.add(csel) res.sort(proc(a, b: ComplexSelector): int = cmp(a.specificity, b.specificity), Descending) move(res) proc parseSelectorsConsume(toks: var seq[CSSToken]): SelectorList = var state = SelectorParser(ctx: initCSSParserSink(toks)) state.parseSelectorList(forgiving = false) proc parseSelectors*(ibuf: string): SelectorList = var state = SelectorParser(ctx: initCSSParser(ibuf)) state.parseSelectorList(forgiving = false) {.pop.} # raises: [] ����chawan-v0.4.0/src/css/csstree.nim�������������������������������������������������������������������0000664�0000000�0000000�00000066722�15202323131�0016703�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Tree building. # # This is currently a separate pass from layout, meaning at least two tree # traversals are required. (We should merge these at some point, but that # will require some refactoring in layout as well as in the invalidation # logic.) # # --- # # This wouldn't be nearly as complex as it is if not for CSS's asinine # anonymous table box generation rules. In particular: # * Runs of misparented boxes inside a table/table row/table row group # must be placed in appropriate anonymous wrappers. For example, if # we encounter two consecutive `display: block's inside a `display: # table-row', these must be wrapped around a single `display: # table-cell'. # * Runs of misparented table row/table row group/table cell boxes must # be wrapped in an anonymous table, or in some cases an anonymous # table row and *then* an anonymous table. e.g. a `display: # table-row', `display: table-cell', then a `display: table-row-group' # will all be wrapped in a single table. # * If this weren't enough, we also have to *split up* the entire table # into an inner and an outer table. The outer table wraps the inner # table and the caption. The inner table (of DisplayTableWrapper) # includes the rows/row groups. # Whatever your reason may be for looking at this: good luck. {.push raises: [].} import std/algorithm import chame/tags import css/box import css/cascade import css/cssparser import css/cssvalues import html/catom import html/dom import types/bitmap import types/color import types/refstring import utils/twtstr type StyledNodeType = enum stElement, stText, stBr, stCounter # Abstraction over the DOM to pretend that elements, text, replaced # and pseudo-elements are derived from the same type. StyledNode = object element: Element computed: CSSValues pseudo: PseudoElement skipChildren: bool case t: StyledNodeType of stText: text: RefString of stElement: anonChildren: seq[StyledNode] of stBr: # <br> element discard of stCounter: # counters counterName: CAtom counterStyle: CSSListStyleType counterSuffix: bool CSSCounter = object element: Element name: CAtom n: int32 TreeContext = ref object markLinks: bool quoteLevel: int linkHintChars: ref seq[uint32] counters: seq[CSSCounter] stackItem: StackItem absoluteHead: CSSAbsolute absoluteTail: CSSAbsolute fixedHead: CSSAbsolute fixedTail: CSSAbsolute TreeFrame = object parent: Element computed: CSSValues pseudoComputed: CSSValues children: seq[StyledNode] lastChildWasInline: bool captionSeen: bool anonComputed: CSSValues anonInlineComputed: CSSValues ctx: TreeContext # Forward declarations proc build(ctx: TreeContext; cached: CSSBox; styledNode: StyledNode; forceZ, root: bool): CSSBox when defined(debug): proc `$`*(node: StyledNode): string = case node.t of stText: return node.text.s of stElement: if node.pseudo != peNone: return $node.element.tagType & "::" & $node.pseudo return $node.element of stBr: return "#br" of stCounter: return "#counter" proc incCounter(ctx: TreeContext; name: CAtom; n: int32; element: Element) = var found = false for counter in ctx.counters.mritems: if counter.name == name: let n64 = clamp(int64(counter.n) + int64(n), int32.low, int32.high) counter.n = int32(n64) found = true break if not found: # instantiate a new counter ctx.counters.add(CSSCounter(name: name, n: n, element: element)) proc setCounter(ctx: TreeContext; name: CAtom; n: int32; element: Element) = var found = false for counter in ctx.counters.mritems: if counter.name == name: counter.n = n found = true break if not found: # instantiate a new counter ctx.counters.add(CSSCounter(name: name, n: n, element: element)) proc resetCounter(ctx: TreeContext; name: CAtom; n: int32; element: Element) = var found = false for counter in ctx.counters.mritems: if counter.name == name and counter.element.isPreviousSiblingOf(element): if name == satListItem: if counter.element != element: continue counter.element = element counter.n = n found = true break if not found: ctx.counters.add(CSSCounter(name: name, n: n, element: element)) proc counter(ctx: TreeContext; name: CAtom): int32 = for counter in ctx.counters.mritems: if counter.name == name: return counter.n return 0 proc inheritFor(frame: TreeFrame; display: CSSDisplay): CSSValues = result = frame.computed.inheritProperties() result{"display"} = display proc initTreeFrame(ctx: TreeContext; parent: Element; computed: CSSValues): TreeFrame = result = TreeFrame( parent: parent, computed: computed, pseudoComputed: computed.next, ctx: ctx ) proc getAnonInlineComputed(frame: var TreeFrame): CSSValues = if frame.anonInlineComputed == nil: if frame.computed{"display"} == DisplayInline: frame.anonInlineComputed = frame.computed else: frame.anonInlineComputed = frame.computed.inheritProperties() return frame.anonInlineComputed proc displayed(frame: TreeFrame; text: RefString): bool = if text.len == 0: return false return frame.computed{"display"} == DisplayInline or frame.lastChildWasInline or frame.computed{"white-space"} in WhiteSpacePreserve or not text.s.onlyWhitespace() #TODO implement table columns const DisplayNoneLike = { DisplayNone, DisplayTableColumn, DisplayTableColumnGroup } proc displayed(frame: TreeFrame; element: Element): bool = return element.computed{"display"} notin DisplayNoneLike proc initStyledAnon(element: Element; computed: CSSValues; children: sink seq[StyledNode] = @[]): StyledNode = result = StyledNode( t: stElement, element: element, anonChildren: children, computed: computed, skipChildren: true ) proc getInternalTableParent(frame: var TreeFrame; display: CSSDisplay): var seq[StyledNode] = if frame.anonComputed == nil: frame.anonComputed = frame.inheritFor(display) frame.children.add(initStyledAnon(frame.parent, frame.anonComputed)) return frame.children[^1].anonChildren # Add an anonymous table to children, and return based on display either # * row, row group: the table children # * cell: its last anonymous row (if there isn't one, create it) # * caption: its outer box proc addAnonTable(frame: var TreeFrame; parentDisplay, display: CSSDisplay): var seq[StyledNode] = if frame.anonComputed == nil or frame.anonComputed{"display"} notin DisplayInnerTable + {DisplayTableRow}: let anonDisplay = if parentDisplay == DisplayInline: DisplayInlineTable else: DisplayTable let (outer, inner) = frame.inheritFor(anonDisplay).splitTable() frame.anonComputed = outer frame.children.add(initStyledAnon(frame.parent, outer, @[initStyledAnon( frame.parent, inner )])) if display == DisplayTableCaption: frame.anonComputed = frame.children[^1].computed return frame.children[^1].anonChildren if display in RowGroupBox + {DisplayTableRow}: frame.anonComputed = frame.children[^1].computed return frame.children[^1].anonChildren[0].anonChildren assert display == DisplayTableCell if frame.anonComputed{"display"} == DisplayTableRow: return frame.children[^1].anonChildren[0].anonChildren[^1].anonChildren frame.anonComputed = frame.inheritFor(DisplayTableRow) frame.children[^1].anonChildren[0].anonChildren.add(initStyledAnon( frame.parent, frame.anonComputed )) return frame.children[^1].anonChildren[0].anonChildren[^1].anonChildren proc madd(s: var seq[StyledNode]; node: StyledNode): var StyledNode = s.add(node) s[^1] proc getParent(frame: var TreeFrame; display: CSSDisplay): var seq[StyledNode] = let parentDisplay = frame.computed{"display"} if display in DisplayInlineBlockLike and parentDisplay != DisplayInline: let computed = frame.getAnonInlineComputed() return frame.getParent(DisplayInline) .madd(initStyledAnon(frame.parent, computed)).anonChildren case parentDisplay of DisplayInnerFlex, DisplayInnerGrid: if display in DisplayOuterInline: if frame.anonComputed == nil: frame.anonComputed = frame.inheritFor(DisplayBlock) frame.children.add(initStyledAnon(frame.parent, frame.anonComputed)) return frame.children[^1].anonChildren of DisplayTableRow: if display != DisplayTableCell: return frame.getInternalTableParent(DisplayTableCell) frame.anonComputed = nil of RowGroupBox: if display != DisplayTableRow: return frame.getInternalTableParent(DisplayTableRow) frame.anonComputed = nil of DisplayTableWrapper: if display notin RowGroupBox + {DisplayTableRow}: return frame.getInternalTableParent(DisplayTableRow) frame.anonComputed = nil of DisplayInnerTable: if frame.children.len > 0 and display != DisplayTableCaption: return frame.children[0].anonChildren of DisplayTableCell: if frame.anonComputed == nil: frame.anonComputed = frame.inheritFor(DisplayFlowRoot) frame.children.add(initStyledAnon(frame.parent, frame.anonComputed)) return frame.children[^1].anonChildren elif display in DisplayInternalTable: return frame.addAnonTable(parentDisplay, display) else: frame.captionSeen = false frame.anonComputed = nil return frame.children proc addListItem(frame: var TreeFrame; node: sink StyledNode) = var node = node # Generate a marker box. var markerComputed = node.element.getComputedStyle(peMarker) if markerComputed == nil: markerComputed = node.computed.inheritProperties() markerComputed{"display"} = DisplayMarker let textComputed = markerComputed.inheritProperties() textComputed{"white-space"} = WhiteSpacePre textComputed{"content"} = markerComputed{"content"} let markerText = if markerComputed{"content"}.len == 0: StyledNode( t: stCounter, element: node.element, computed: textComputed, counterName: satListItem.toAtom(), counterStyle: node.computed{"list-style-type"}, counterSuffix: true ) else: StyledNode( t: stElement, pseudo: peMarker, element: node.element, computed: textComputed ) case node.computed{"list-style-position"} of ListStylePositionOutside: # Generate separate boxes for the content and marker. node.anonChildren.add(initStyledAnon(node.element, markerComputed, @[markerText])) of ListStylePositionInside: node.anonChildren.add(markerText) frame.getParent(node.computed{"display"}).add(node) proc addTable(frame: var TreeFrame; node: sink StyledNode) = var node = node let (outer, inner) = node.computed.splitTable() node.computed = outer node.anonChildren.add(initStyledAnon(node.element, inner)) frame.getParent(node.computed{"display"}).add(node) proc add(frame: var TreeFrame; node: sink StyledNode) = let display = node.computed{"display"} if frame.captionSeen and display == DisplayTableCaption: return if node.t == stElement and node.anonChildren.len == 0: case display of DisplayListItem: frame.addListItem(node) frame.lastChildWasInline = false return # already added of DisplayInnerTable: frame.addTable(node) frame.lastChildWasInline = false return # already added else: discard frame.getParent(display).add(node) frame.lastChildWasInline = display in DisplayOuterInline frame.captionSeen = frame.captionSeen or display == DisplayTableCaption proc addAnon(frame: var TreeFrame; computed: CSSValues; children: sink seq[StyledNode]) = frame.add(initStyledAnon(frame.parent, computed, children)) proc addElement(frame: var TreeFrame; element: Element) = element.ensureStyle() if frame.displayed(element): frame.add(StyledNode( t: stElement, element: element, computed: element.computed )) proc addPseudo(frame: var TreeFrame; pseudo: PseudoElement) = var computed = frame.pseudoComputed while computed != nil: if computed.pseudo == pseudo: frame.pseudoComputed = computed.next break computed = computed.next if computed != nil and computed{"display"} notin DisplayNoneLike and computed{"content"}.len > 0: frame.add(StyledNode( t: stElement, pseudo: pseudo, element: frame.parent, computed: computed )) proc addText(frame: var TreeFrame; text: RefString) = if frame.displayed(text): frame.add(StyledNode( t: stText, element: frame.parent, text: text, computed: frame.getAnonInlineComputed() )) proc addCounter(frame: var TreeFrame; name: CAtom; style: CSSListStyleType) = frame.add(StyledNode( t: stCounter, element: frame.parent, counterName: name, counterStyle: style, computed: frame.getAnonInlineComputed() )) proc addText(frame: var TreeFrame; s: sink string) = #TODO should probably cache these... frame.addText(newRefString(s)) proc addImage(frame: var TreeFrame; bmp: NetworkBitmap) = if bmp == nil or bmp.cacheId == -1: # Add a placeholder text if we have no bmp. # (If we have bmp, render will take care of it automatically.) frame.addText("[img]") proc addBr(frame: var TreeFrame) = frame.add(StyledNode( t: stBr, element: frame.parent, computed: frame.computed )) proc addElementChildren(frame: var TreeFrame) = for it in frame.parent.shadowChildList: if it of Element: let element = Element(it) frame.addElement(element) elif it of Text: #TODO collapse subsequent text nodes into one StyledNode # (it isn't possible in HTML, only with JS DOM manipulation) let text = Text(it) frame.addText(text.data) proc addInputChildren(frame: var TreeFrame; input: HTMLInputElement) = let cdata = input.inputString() if input.inputType in InputTypeWithSize: let computed = frame.computed.inheritProperties() let n = frame.computed{"-cha-input-intrinsic-size"} computed{"display"} = DisplayBlock computed{"width"} = cssLength(n) var aframe = frame.ctx.initTreeFrame(input, computed) if cdata != nil: aframe.addText(cdata) frame.addAnon(computed, move(aframe.children)) else: if cdata != nil: frame.addText(cdata) proc addOptionChildren(frame: var TreeFrame; option: HTMLOptionElement) = if option.select != nil and option.select.attrb(satMultiple): frame.addText("[") let cdata = newRefString(if option.selected: "*" else: " ") let computed = option.computed.inheritProperties() computed{"color"} = cssColor(ANSIColor(1)) # red computed{"white-space"} = WhiteSpacePre block anon: var aframe = frame.ctx.initTreeFrame(option, computed) aframe.addText(cdata) frame.addAnon(computed, move(aframe.children)) frame.addText("]") frame.addElementChildren() proc addAnchorChildren(frame: var TreeFrame; anchor: HTMLAnchorElement) = if frame.ctx.markLinks: frame.addPseudo(peLinkMarker) frame.addElementChildren() proc addProgress(frame: var TreeFrame; element: Element) = if element.attr(satValue) != "": let computed = frame.computed.inheritProperties() computed{"display"} = DisplayBlock let n = frame.computed{"-cha-input-intrinsic-size"} computed{"width"} = cssLengthFrac(clamp(n, 0, 1)) computed{"border-bottom-style"} = BorderStyleHash frame.addAnon(computed, @[]) else: frame.addElementChildren() proc addChildren(frame: var TreeFrame) = case frame.parent.tagType of TAG_INPUT: frame.addInputChildren(HTMLInputElement(frame.parent)) of TAG_TEXTAREA: #TODO cache (do the same as with input, and add borders in render) frame.addText(HTMLTextAreaElement(frame.parent).textAreaString()) of TAG_IMG: frame.addImage(HTMLImageElement(frame.parent).bitmap) of TAG_CANVAS: frame.addImage(HTMLCanvasElement(frame.parent).bitmap) of TAG_VIDEO: frame.addText("[video]") of TAG_AUDIO: frame.addText("[audio]") of TAG_BR: frame.addBr() of TAG_IFRAME: frame.addText("[iframe]") of TAG_FRAME: frame.addText("[frame]") of TAG_PROGRESS: frame.addProgress(frame.parent) of TAG_OPTION: let option = HTMLOptionElement(frame.parent) frame.addOptionChildren(option) of TAG_A: frame.addAnchorChildren(HTMLAnchorElement(frame.parent)) elif frame.parent.tagType(satNamespaceSVG) == TAG_SVG: frame.addImage(SVGSVGElement(frame.parent).bitmap) else: frame.addElementChildren() proc addContent(frame: var TreeFrame; content: CSSContent) = case content.t of ContentString: frame.addText(content.s) of ContentOpenQuote: let quotes = frame.computed{"quotes"} if quotes == nil: frame.addText(quoteStart(frame.ctx.quoteLevel)) elif quotes.qs.len > 0: frame.addText(quotes.qs[min(frame.ctx.quoteLevel, quotes.qs.high)].s) else: return inc frame.ctx.quoteLevel of ContentCloseQuote: if frame.ctx.quoteLevel > 0: dec frame.ctx.quoteLevel let quotes = frame.computed{"quotes"} if quotes == nil: frame.addText(quoteEnd(frame.ctx.quoteLevel)) elif quotes.qs.len > 0: frame.addText(quotes.qs[min(frame.ctx.quoteLevel, quotes.qs.high)].e) of ContentNoOpenQuote: inc frame.ctx.quoteLevel of ContentNoCloseQuote: if frame.ctx.quoteLevel > 0: dec frame.ctx.quoteLevel of ContentCounter: frame.addCounter(content.counter, content.counterStyle) proc buildChildren(frame: var TreeFrame; styledNode: StyledNode) = for child in styledNode.anonChildren: frame.add(child) if not styledNode.skipChildren: if styledNode.pseudo == peNone: frame.addPseudo(peBefore) if frame.parent.hint: frame.addPseudo(peLinkHint) frame.addChildren() frame.addPseudo(peAfter) else: for content in frame.computed{"content"}: frame.addContent(content) proc newBoxOrTakeCached(cached: CSSBox; display: CSSDisplay; node: StyledNode): CSSBox = let t = if node.skipChildren: cbtAnonymous else: cbtElement if cached != nil: cached.firstChild = nil return cached elif display == DisplayInline: return InlineBox( t: t, computed: node.computed, element: node.element, pseudo: node.pseudo ) else: return BlockBox( t: t, computed: node.computed, element: node.element, pseudo: node.pseudo ) proc matchCache(node: StyledNode; box: CSSBox): bool = if box == nil or box.element != node.element: return false case box.t of cbtAnonymous: if node.skipChildren and node.computed{"display"} == box.computed{"display"}: if node.computed.relayout: box.keepLayout = false box.computed = node.computed box.absolute = nil return true return false of cbtElement: # Do not reuse anon boxes as non-anon boxes, incorrect pseudo-elements, # or boxes of the wrong type for the display. (Could be more granular # but it probably doesn't matter.) if node.t == stElement and not node.skipChildren and node.pseudo == box.pseudo and node.computed{"display"} == box.computed{"display"}: if node.computed.relayout: box.keepLayout = false box.computed = node.computed box.absolute = nil return true return false of cbtText: case node.t of stText: if box of InlineTextBox: let box = InlineTextBox(box) # We don't have to check computed here; it's always derived from the # parent so it would be pointless. # (That does bring up the question why we have a computed field for # text boxes at at all. I really don't know...) box.keepLayout = box.len == node.text.len and (box.text == node.text or box.text.s == node.text.s) box.len = node.text.len box.computed = node.computed box.text = node.text return true return false of stBr: if box of InlineNewLineBox: # br only checks clear. (And white-space, which is a bug.) if box.computed{"clear"} != node.computed{"clear"} or box.computed{"white-space"} != node.computed{"white-space"}: box.keepLayout = false box.computed = node.computed return true return false of stCounter: if box of InlineTextBox: box.computed = node.computed return true return false of stElement: return false proc takeCache(node: StyledNode; box: CSSBox): CSSBox = if node.matchCache(box): box.parent = nil box.next = nil return box nil proc buildInnerBox(ctx: TreeContext; frame: TreeFrame; cached: CSSBox; node: StyledNode): CSSBox = let display = frame.computed{"display"} var cachedIt = if cached != nil: cached.firstChild else: nil let box = newBoxOrTakeCached(cached, display, node) box.computed.relayout = false # Grid and flex items always respect z-index. Other boxes only # respect it with position != static. let forceZ = display in DisplayInnerFlex + DisplayInnerGrid var last: CSSBox = nil var keepLayout = true for child in frame.children: let next = if cachedIt != nil: cachedIt.next else: nil let childBox = ctx.build(cachedIt, child, forceZ, root = false) childBox.parent = box if last != nil: last.next = childBox else: box.firstChild = childBox last = childBox keepLayout = keepLayout and childBox.keepLayout cachedIt = next box.keepLayout = box.keepLayout and keepLayout and cachedIt == nil box proc applyCounters(ctx: TreeContext; styledNode: StyledNode; firstSetCounterIdx: var int) = for counter in styledNode.computed{"counter-reset"}: ctx.resetCounter(counter.name, counter.num, styledNode.element) firstSetCounterIdx = ctx.counters.len var liSeen = false for counter in styledNode.computed{"counter-increment"}: liSeen = liSeen or counter.name == satListItem ctx.incCounter(counter.name, counter.num, styledNode.element) if not liSeen and styledNode.computed{"display"} == DisplayListItem: ctx.incCounter(satListItem.toAtom(), 1, styledNode.element) for counter in styledNode.computed{"counter-set"}: ctx.setCounter(counter.name, counter.num, styledNode.element) proc resetCounters(ctx: TreeContext; element: Element; countersLen, firstElementIdx, firstSetCounterIdx: int) = ctx.counters.setLen(countersLen) # Special case list-item, because the spec is broken. # In particular, we want list-item counters introduced by # counter-reset to be "narrow", i.e. delete them after the element # goes out of scope so that an OL nested in another OL does not shadow # the counter of the parent OL. # Note that this does not apply to list-items introduced by # counter-increment/counter-set, so we do not search those. for i in countdown(firstSetCounterIdx - 1, firstElementIdx): if ctx.counters[i].name == satListItem: ctx.counters.delete(i) break proc pushStackItem(ctx: TreeContext; styledNode: StyledNode): StackItem = ctx.absoluteHead = nil ctx.absoluteTail = nil let index = styledNode.computed{"z-index"} let stack = StackItem(index: index.num) ctx.stackItem.children.add(stack) return stack proc popStackItem(ctx: TreeContext; old: StackItem) = let stackItem = ctx.stackItem if stackItem != old: stackItem.children.sort(proc(x, y: StackItem): int = cmp(x.index, y.index)) ctx.stackItem = old proc addAbsolute(ctx: TreeContext; box: CSSBox) = let absolute = CSSAbsolute(box: BlockBox(box)) if ctx.absoluteHead == nil: ctx.absoluteHead = absolute else: ctx.absoluteTail.next = absolute ctx.absoluteTail = absolute proc addFixed(ctx: TreeContext; box: CSSBox) = let absolute = CSSAbsolute(box: BlockBox(box)) if ctx.fixedHead == nil: ctx.fixedHead = absolute else: ctx.fixedTail.next = absolute ctx.fixedTail = absolute proc buildOuterBox(ctx: TreeContext; cached: CSSBox; styledNode: StyledNode; forceZ, root: bool): CSSBox = let oldCountersLen = ctx.counters.len var firstSetCounterIdx: int ctx.applyCounters(styledNode, firstSetCounterIdx) let countersLen = ctx.counters.len var frame = ctx.initTreeFrame(styledNode.element, styledNode.computed) var stackItem: StackItem = nil let display = frame.computed{"display"} let position = frame.computed{"position"} let oldStackItem = ctx.stackItem let oldAbsoluteHead = ctx.absoluteHead let oldAbsoluteTail = ctx.absoluteTail if not root: let index = frame.computed{"z-index"} if position != PositionStatic and display notin DisplayNeverHasStack or forceZ and not index.auto: stackItem = ctx.pushStackItem(styledNode) if not index.auto: ctx.stackItem = stackItem elif frame.computed{"float"} != FloatNone: # floats don't really create a new stacking context, but you have to # treat them "as if" they did. (effectively it's the same as the # auto index case) stackItem = ctx.pushStackItem(styledNode) frame.buildChildren(styledNode) let box = ctx.buildInnerBox(frame, cached, styledNode) if styledNode.t == stElement: box.element.box = box ctx.resetCounters(styledNode.element, countersLen, oldCountersLen, firstSetCounterIdx) box.positioned = stackItem != nil and position != PositionStatic if stackItem != nil: stackItem.box = box box.absolute = ctx.absoluteHead ctx.absoluteHead = oldAbsoluteHead ctx.absoluteTail = oldAbsoluteTail ctx.popStackItem(oldStackItem) case position of PositionAbsolute: ctx.addAbsolute(box) of PositionFixed: ctx.addFixed(box) else: discard return box proc build(ctx: TreeContext; cached: CSSBox; styledNode: StyledNode; forceZ, root: bool): CSSBox = let cached = styledNode.takeCache(cached) case styledNode.t of stElement: return ctx.buildOuterBox(cached, styledNode, forceZ, root) of stText: if cached != nil: return cached return InlineTextBox( t: cbtText, computed: styledNode.computed, element: styledNode.element, text: styledNode.text, len: styledNode.text.len ) of stBr: if cached != nil: return cached return InlineNewLineBox( t: cbtText, computed: styledNode.computed, element: styledNode.element ) of stCounter: let counter = ctx.counter(styledNode.counterName) let addSuffix = styledNode.counterSuffix # only used for markers let text = styledNode.counterStyle.listMarker(counter, addSuffix, ctx.linkHintChars[]) if cached != nil: let cached = InlineTextBox(cached) cached.keepLayout = cached.text.s == text.s cached.text = text return cached return InlineTextBox( t: cbtText, computed: styledNode.computed, element: styledNode.element, text: styledNode.counterStyle.listMarker(counter, addSuffix, ctx.linkHintChars[]) ) # Root proc buildTree*(element: Element; cached: CSSBox; markLinks: bool; nhints: int; linkHintChars: ref seq[uint32]): tuple[stack: StackItem, fixedHead: CSSAbsolute] = element.ensureStyle() let styledNode = StyledNode( t: stElement, element: element, computed: element.computed ) let stack = StackItem() let ctx = TreeContext( markLinks: markLinks, stackItem: stack, linkHintChars: linkHintChars ) ctx.resetCounter(satDashChaLinkCounter.toAtom(), 0, element) let hintHigh = max(linkHintChars[].high, 0) let hintOffset = if hintHigh > 0: min(int(int32.high), ((nhints + hintHigh - 1) div hintHigh) - 1) else: hintHigh ctx.resetCounter(satDashChaHintCounter.toAtom(), int32(hintOffset), element) let root = BlockBox(ctx.build(cached, styledNode, forceZ = false, root = true)) stack.box = root root.absolute = ctx.absoluteHead ctx.popStackItem(nil) return (stack, ctx.fixedHead) {.pop.} # raises: [] ����������������������������������������������chawan-v0.4.0/src/css/cssvalues.nim�����������������������������������������������������������������0000664�0000000�0000000�00000215117�15202323131�0017235�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/algorithm import std/macros import std/math import std/tables import css/cssparser import css/lunit import html/catom import types/bitmap import types/color import types/opt import types/refstring import types/winattrs import utils/dtoawrap import utils/twtstr export CSSPropertyType type CSSValueType* = enum cvtBgcolorIsCanvas = "bgcolorIsCanvas" cvtBorderCollapse = "borderCollapse" cvtBorderStyle = "borderStyle" cvtBoxSizing = "boxSizing" cvtCaptionSide = "captionSide" cvtClear = "clear" cvtColor = "color" cvtContent = "content" cvtCounterSet = "counterSet" cvtDisplay = "display" cvtFlexDirection = "flexDirection" cvtFlexWrap = "flexWrap" cvtFloat = "float" cvtFontStyle = "fontStyle" cvtImage = "image" cvtInteger = "integer" cvtLength = "length" cvtLineWidth = "lineWidth" cvtListStylePosition = "listStylePosition" cvtListStyleType = "listStyleType" cvtNumber = "number" cvtOverflow = "overflow" cvtPosition = "position" cvtQuotes = "quotes" cvtTextAlign = "textAlign" cvtTextDecoration = "textDecoration" cvtTextTransform = "textTransform" cvtVerticalAlign = "verticalAlign" cvtVisibility = "visibility" cvtWhiteSpace = "whiteSpace" cvtWordBreak = "wordBreak" cvtZIndex = "zIndex" CSSGlobalType* = enum cgtInitial = "initial" cgtInherit = "inherit" cgtRevert = "revert" cgtUnset = "unset" CSSDisplay* = enum DisplayInline = "inline" DisplayNone = "none" DisplayBlock = "block" DisplayListItem = "list-item" DisplayInlineBlock = "inline-block" DisplayTable = "table" DisplayInlineTable = "inline-table" DisplayTableRowGroup = "table-row-group" DisplayTableHeaderGroup = "table-header-group" DisplayTableFooterGroup = "table-footer-group" DisplayTableColumnGroup = "table-column-group" DisplayTableRow = "table-row" DisplayTableColumn = "table-column" DisplayTableCell = "table-cell" DisplayTableCaption = "table-caption" DisplayFlowRoot = "flow-root" DisplayFlex = "flex" DisplayInlineFlex = "inline-flex" DisplayGrid = "grid" DisplayInlineGrid = "inline-grid" # internal, for layout DisplayTableWrapper = "" DisplayMarker = "" DisplayImageBlock = "" DisplayImageInline = "" CSSWhiteSpace* = enum WhiteSpaceNormal = "normal" WhiteSpaceNowrap = "nowrap" WhiteSpacePre = "pre" WhiteSpacePreLine = "pre-line" WhiteSpacePreWrap = "pre-wrap" CSSFontStyle* = enum FontStyleNormal = "normal" FontStyleItalic = "italic" FontStyleOblique = "oblique" CSSPosition* = enum PositionStatic = "static" PositionRelative = "relative" PositionAbsolute = "absolute" PositionFixed = "fixed" PositionSticky = "sticky" CSSTextDecoration* = enum TextDecorationNone = "none" TextDecorationUnderline = "underline" TextDecorationOverline = "overline" TextDecorationLineThrough = "line-through" TextDecorationBlink = "blink" TextDecorationReverse = "-cha-reverse" CSSWordBreak* = enum WordBreakNormal = "normal" WordBreakBreakAll = "break-all" WordBreakKeepAll = "keep-all" CSSListStyleType* = enum ListStyleTypeDisc = "disc" ListStyleTypeNone = "none" ListStyleTypeCircle = "circle" ListStyleTypeSquare = "square" ListStyleTypeDecimal = "decimal" ListStyleTypeDisclosureClosed = "disclosure-closed" ListStyleTypeDisclosureOpen = "disclosure-open" ListStyleTypeCjkEarthlyBranch = "cjk-earthly-branch" ListStyleTypeCjkHeavenlyStem = "cjk-heavenly-stem" ListStyleTypeLowerRoman = "lower-roman" ListStyleTypeUpperRoman = "upper-roman" ListStyleTypeLowerAlpha = "lower-alpha" ListStyleTypeUpperAlpha = "upper-alpha" ListStyleTypeLowerGreek = "lower-greek" ListStyleTypeHiragana = "hiragana" ListStyleTypeHiraganaIroha = "hiragana-iroha" ListStyleTypeKatakana = "katakana" ListStyleTypeKatakanaIroha = "katakana-iroha" ListStyleTypeJapaneseInformal = "japanese-informal" ListStyleTypeJapaneseFormal = "japanese-formal" ListStyleTypeHint = "-cha-hint" CSSVerticalAlign* = enum VerticalAlignBaseline = "baseline" VerticalAlignSub = "sub" VerticalAlignSuper = "super" VerticalAlignTextTop = "text-top" VerticalAlignTextBottom = "text-bottom" VerticalAlignMiddle = "middle" VerticalAlignTop = "top" VerticalAlignBottom = "bottom" VerticalAlignLength = "-cha-length" CSSTextAlign* = enum TextAlignStart = "start" TextAlignEnd = "end" TextAlignLeft = "left" TextAlignRight = "right" TextAlignCenter = "center" TextAlignJustify = "justify" TextAlignChaCenter = "-cha-center" TextAlignChaLeft = "-cha-left" TextAlignChaRight = "-cha-right" CSSListStylePosition* = enum ListStylePositionOutside = "outside" ListStylePositionInside = "inside" CSSCaptionSide* = enum CaptionSideTop = "top" CaptionSideBottom = "bottom" CaptionSideBlockStart = "block-start" CaptionSideBlockEnd = "block-end" CSSBorderCollapse* = enum BorderCollapseSeparate = "separate" BorderCollapseCollapse = "collapse" CSSContentType* = enum ContentString = "-cha-string" ContentCounter = "-cha-counter" ContentOpenQuote = "open-quote" ContentCloseQuote = "close-quote" ContentNoOpenQuote = "no-open-quote" ContentNoCloseQuote = "no-close-quote" CSSFloat* = enum FloatNone = "none" FloatLeft = "left" FloatRight = "right" CSSVisibility* = enum VisibilityVisible = "visible" VisibilityHidden = "hidden" VisibilityCollapse = "collapse" CSSBoxSizing* = enum BoxSizingContentBox = "content-box" BoxSizingBorderBox = "border-box" CSSClear* = enum ClearNone = "none" ClearLeft = "left" ClearRight = "right" ClearBoth = "both" ClearInlineStart = "inline-start" ClearInlineEnd = "inline-end" CSSTextTransform* = enum TextTransformNone = "none" TextTransformCapitalize = "capitalize" TextTransformUppercase = "uppercase" TextTransformLowercase = "lowercase" TextTransformFullWidth = "full-width" TextTransformFullSizeKana = "full-size-kana" TextTransformChaHalfWidth = "-cha-half-width" CSSFlexDirection* = enum FlexDirectionRow = "row" FlexDirectionRowReverse = "row-reverse" FlexDirectionColumn = "column" FlexDirectionColumnReverse = "column-reverse" CSSFlexWrap* = enum FlexWrapNowrap = "nowrap" FlexWrapWrap = "wrap" FlexWrapWrapReverse = "wrap-reverse" CSSOverflow* = enum OverflowVisible = "visible" OverflowHidden = "hidden" OverflowClip = "clip" OverflowScroll = "scroll" OverflowAuto = "auto" OverflowOverlay = "overlay" CSSBorderStyle* = enum BorderStyleNone = "none" BorderStyleHidden = "hidden" BorderStyleDotted = "dotted" BorderStyleDashed = "dashed" BorderStyleSolid = "solid" BorderStyleDouble = "double" BorderStyleGroove = "groove" BorderStyleRidge = "ridge" BorderStyleInset = "inset" BorderStyleOutset = "outset" BorderStyleBracket = "-cha-bracket" BorderStyleParen = "-cha-paren" BorderStyleHash = "-cha-hash" BorderStylePeriod = "-cha-period" type # CSSLength may represent: # * if isNaN(px) and isNaN(perc), the ident "auto" # * if px == 0, {npx} pixels # * if perc == 0, {perc} * the parent dimensions (*not* a percentage) # * otherwise, {npx} pixels + {perc}% CSSLength* = object npx*: float32 perc*: float32 CSSContent* = object case t*: CSSContentType of ContentString: s*: RefString of ContentCounter: counter*: CAtom counterStyle*: CSSListStyleType else: discard # nil -> auto CSSQuotes* = ref object qs*: seq[tuple[s, e: RefString]] CSSCounterSet* = object name*: CAtom num*: int32 CSSZIndex* = object `auto`*: bool num*: int32 CSSValueBit* {.union.} = object dummy*: uint8 bgcolorIsCanvas*: bool borderCollapse*: CSSBorderCollapse borderStyle*: CSSBorderStyle boxSizing*: CSSBoxSizing captionSide*: CSSCaptionSide clear*: CSSClear display*: CSSDisplay flexDirection*: CSSFlexDirection flexWrap*: CSSFlexWrap float*: CSSFloat fontStyle*: CSSFontStyle listStylePosition*: CSSListStylePosition listStyleType*: CSSListStyleType overflow*: CSSOverflow position*: CSSPosition textAlign*: CSSTextAlign textDecoration*: set[CSSTextDecoration] textTransform*: CSSTextTransform verticalAlign*: CSSVerticalAlign visibility*: CSSVisibility whiteSpace*: CSSWhiteSpace wordBreak*: CSSWordBreak CSSValueHWord* {.union.} = object dummy: uint32 integer*: int32 number*: float32 lineWidth*: float32 CSSValueWord* {.union.} = object dummy*: uint64 color*: CSSColor length*: CSSLength zIndex*: CSSZIndex CSSValue* = ref object case v*: CSSValueType of cvtContent: content*: seq[CSSContent] of cvtQuotes: quotes*: CSSQuotes of cvtCounterSet: counterSet*: seq[CSSCounterSet] of cvtImage: image*: NetworkBitmap else: discard # Linked list of variable maps, except empty maps are skipped. CSSVariableMap* = ref object parent*: CSSVariableMap table*: Table[CAtom, CSSVariable] CSSValues* = ref object pseudo*: PseudoElement invalid*: bool relayout*: bool bits*: array[CSSPropertyType.low..LastBitPropType, CSSValueBit] hwords*: array[FirstHWordPropType..LastHWordPropType, CSSValueHWord] words*: array[FirstWordPropType..LastWordPropType, CSSValueWord] objs*: array[FirstObjPropType..CSSPropertyType.high, CSSValue] vars*: CSSVariableMap next*: CSSValues CSSOrigin* = enum coUserAgent coUser coAuthor CSSEntryType* = enum ceBit, ceWord, ceHWord, ceObject, ceVar, ceGlobal CSSVarItem* = object name*: CAtom toks*: seq[CSSToken] CSSVarEntry* = ref object resolved*: seq[tuple[vars: CSSVariableMap; entries: seq[CSSComputedEntry]]] items*: seq[CSSVarItem] CSSComputedEntry* = object p*: CSSWidePropertyType case et*: CSSEntryType of ceBit: bit*: uint8 of ceHWord: hword*: CSSValueHWord of ceWord: word*: CSSValueWord of ceObject: obj*: CSSValue of ceVar: cvar*: CSSVarEntry of ceGlobal: global*: CSSGlobalType CSSVariable* = ref object name*: CAtom items*: seq[CSSVarItem] when defined(gcDestructors): proc `=destroy`*(a: var CSSValueBit) = discard proc `=destroy`*(a: var CSSValueHWord) = discard proc `=destroy`*(a: var CSSValueWord) = discard proc `=copy`*(a: var CSSValueBit; b: CSSValueBit) = copyMem(addr a, unsafeAddr b, sizeof(a)) proc `=copy`*(a: var CSSValueHWord; b: CSSValueHWord) = copyMem(addr a, unsafeAddr b, sizeof(a)) proc `=copy`*(a: var CSSValueWord; b: CSSValueWord) = copyMem(addr a, unsafeAddr b, sizeof(a)) static: doAssert sizeof(CSSValueBit) == 1 doAssert sizeof(CSSValueHWord) <= 4 doAssert sizeof(CSSValueWord) <= 8 doAssert sizeof(CSSComputedEntry()) <= 16 const ValueTypes = [ # bits cptBgcolorIsCanvas: cvtBgcolorIsCanvas, cptBorderBottomStyle: cvtBorderStyle, cptBorderCollapse: cvtBorderCollapse, cptBorderLeftStyle: cvtBorderStyle, cptBorderRightStyle: cvtBorderStyle, cptBorderTopStyle: cvtBorderStyle, cptBoxSizing: cvtBoxSizing, cptCaptionSide: cvtCaptionSide, cptClear: cvtClear, cptDisplay: cvtDisplay, cptFlexDirection: cvtFlexDirection, cptFlexWrap: cvtFlexWrap, cptFloat: cvtFloat, cptFontStyle: cvtFontStyle, cptListStylePosition: cvtListStylePosition, cptListStyleType: cvtListStyleType, cptOverflowX: cvtOverflow, cptOverflowY: cvtOverflow, cptPosition: cvtPosition, cptTextAlign: cvtTextAlign, cptTextDecoration: cvtTextDecoration, cptTextTransform: cvtTextTransform, cptVerticalAlign: cvtVerticalAlign, cptVisibility: cvtVisibility, cptWhiteSpace: cvtWhiteSpace, cptWordBreak: cvtWordBreak, # half-words cptBorderBottomWidth: cvtLineWidth, cptBorderLeftWidth: cvtLineWidth, cptBorderRightWidth: cvtLineWidth, cptBorderTopWidth: cvtLineWidth, cptChaColspan: cvtInteger, cptChaRowspan: cvtInteger, cptFlexGrow: cvtNumber, cptFlexShrink: cvtNumber, cptFontWeight: cvtInteger, cptInputIntrinsicSize: cvtNumber, cptOpacity: cvtNumber, # words cptBackgroundColor: cvtColor, cptBorderBottomColor: cvtColor, cptBorderLeftColor: cvtColor, cptBorderRightColor: cvtColor, cptBorderSpacingBlock: cvtLength, cptBorderSpacingInline: cvtLength, cptBorderTopColor: cvtColor, cptBottom: cvtLength, cptColor: cvtColor, cptFlexBasis: cvtLength, cptFontSize: cvtLength, cptHeight: cvtLength, cptLeft: cvtLength, cptMarginBottom: cvtLength, cptMarginLeft: cvtLength, cptMarginRight: cvtLength, cptMarginTop: cvtLength, cptMaxHeight: cvtLength, cptMaxWidth: cvtLength, cptMinHeight: cvtLength, cptMinWidth: cvtLength, cptPaddingBottom: cvtLength, cptPaddingLeft: cvtLength, cptPaddingRight: cvtLength, cptPaddingTop: cvtLength, cptRight: cvtLength, cptTop: cvtLength, cptVerticalAlignLength: cvtLength, cptWidth: cvtLength, cptZIndex: cvtZIndex, # pointers cptBackgroundImage: cvtImage, cptContent: cvtContent, cptCounterReset: cvtCounterSet, cptCounterIncrement: cvtCounterSet, cptCounterSet: cvtCounterSet, cptQuotes: cvtQuotes, ] const InheritedProperties = { cptColor, cptFontStyle, cptWhiteSpace, cptFontWeight, cptTextDecoration, cptWordBreak, cptListStyleType, cptTextAlign, cptListStylePosition, cptCaptionSide, cptBorderSpacingInline, cptBorderSpacingBlock, cptBorderCollapse, cptQuotes, cptVisibility, cptTextTransform } const OverflowScrollLike* = {OverflowScroll, OverflowAuto, OverflowOverlay} const OverflowHiddenLike* = {OverflowHidden, OverflowClip} const FlexReverse* = {FlexDirectionRowReverse, FlexDirectionColumnReverse} const DisplayInlineBlockLike* = { DisplayInlineTable, DisplayInlineBlock, DisplayInlineFlex, DisplayInlineGrid, DisplayMarker, DisplayImageInline } const DisplayOuterInline* = DisplayInlineBlockLike + {DisplayInline} const DisplayOuterBlock* = { DisplayFlex, DisplayGrid, DisplayBlock, DisplayImageBlock, DisplayTable, DisplayFlowRoot, DisplayTableWrapper, DisplayListItem } const DisplayInnerBlock* = { DisplayBlock, DisplayFlowRoot, DisplayTableCaption, DisplayTableCell, DisplayInlineBlock, DisplayListItem, DisplayMarker } const DisplayInnerFlex* = {DisplayFlex, DisplayInlineFlex} const DisplayInnerGrid* = {DisplayGrid, DisplayInlineGrid} const RowGroupBox* = { # Note: caption is not included here DisplayTableRowGroup, DisplayTableHeaderGroup, DisplayTableFooterGroup } const DisplayInnerTable* = {DisplayTable, DisplayInlineTable} const DisplayInternalTable* = { DisplayTableCell, DisplayTableRow, DisplayTableCaption, DisplayTableColumn, DisplayTableColumnGroup } + RowGroupBox const DisplayNeverHasStack* = DisplayInternalTable - {DisplayTableCell} const PositionAbsoluteFixed* = {PositionAbsolute, PositionFixed} const WhiteSpacePreserve* = { WhiteSpacePre, WhiteSpacePreLine, WhiteSpacePreWrap } const BorderStyleNoneHidden* = {BorderStyleNone, BorderStyleHidden} const BorderStyleInput* = { BorderStyleBracket, BorderStyleParen, BorderStyleHash } # Changing these properties triggers a relayout for the box. const LayoutProperties* = { cptMarginLeft, cptMarginRight, cptMarginTop, cptMarginBottom, cptPaddingLeft, cptPaddingRight, cptPaddingTop, cptPaddingBottom, cptBoxSizing, cptBorderLeftStyle, cptBorderRightStyle, cptBorderTopStyle, cptBorderBottomStyle, cptBorderLeftWidth, cptBorderRightWidth, cptBorderTopWidth, cptBorderBottomWidth, cptLeft, cptRight, cptTop, cptBottom, cptWidth, cptHeight, cptFlexShrink, cptFlexGrow, cptFlexBasis, cptOverflowX, cptOverflowY, cptWhiteSpace, cptVerticalAlign, cptTextAlign, cptVerticalAlignLength, cptWordBreak, cptTextTransform, cptFloat, cptClear, cptMinWidth, cptMinHeight, cptMaxWidth, cptMaxHeight, cptChaColspan, cptChaRowspan, cptVisibility, # collapse affects tables cptBorderCollapse, cptBorderSpacingInline, cptBorderSpacingBlock, cptCaptionSide, cptPosition } type CSSCalcSumType = enum ccstNumber, ccstLength, ccstDegree CSSCalcKeyword = enum ccskE = "e" ccskPi = "pi" ccskInfinity = "infinity" ccskMinusInfinity = "-infinity" ccskNaN = "NaN" CSSCalcSum = object case t: CSSCalcSumType of ccstNumber: n: float32 of ccstLength: l: CSSLength of ccstDegree: deg: float32 # Forward declarations proc parseValue(ctx: var CSSParser; t: CSSPropertyType; entry: var CSSComputedEntry; attrs: WindowAttributes): Opt[void] proc parseCalcSum(ctx: var CSSParser; attrs: ptr WindowAttributes): Opt[CSSCalcSum] proc newCSSVariableMap*(parent: CSSVariableMap): CSSVariableMap = return CSSVariableMap(parent: parent) proc putIfAbsent*(map: CSSVariableMap; name: CAtom; cvar: CSSVariable) = discard map.table.hasKeyOrPut(name, cvar) type CSSPropertyReprType* = enum cprtBit, cprtHWord, cprtWord, cprtObject proc reprType*(t: CSSPropertyType): CSSPropertyReprType = if t <= LastBitPropType: return cprtBit if t <= LastHWordPropType: return cprtHWord if t <= LastWordPropType: return cprtWord return cprtObject proc valueType*(prop: CSSPropertyType): CSSValueType = return ValueTypes[prop] proc isSupportedProperty*(s: string): bool = return propertyType(s).isOk template auto*(length: CSSLength): bool = isNaN(length.npx) template isPx*(length: CSSLength): bool = length.perc == 0 proc isPerc*(length: CSSLength): bool {.inline.} = not isNaN(length.perc) and length.perc != 0 proc isZero*(length: CSSLength): bool {.inline.} = length.npx == 0 and length.perc == 0 proc `$`*(length: CSSLength): string = if length.auto: return "auto" result = "" if length.perc != 0: result.addDouble(length.perc * 100) result &= '%' if length.npx != 0: let calc = result.len > 0 var npx = length.npx if calc: if length.npx > 0: result &= " + " else: npx = -npx result &= " - " result.addDouble(npx) result &= "px" if calc: result = "calc(" & result & ')' if result.len == 0: result &= '0' proc `$`*(bmp: NetworkBitmap): string = return "" #TODO proc `$`*(content: CSSContent): string = case content.t of ContentString: return $content.s of ContentCounter: return "counter(" & $content.counter & ", " & $content.counterStyle & ')' of ContentOpenQuote, ContentCloseQuote, ContentNoOpenQuote, ContentNoCloseQuote: return $content.t proc `$`(quotes: CSSQuotes): string = if quotes == nil: return "auto" result = "" for (s, e) in quotes.qs: result &= "'" & ($s).cssEscape() & "' '" & ($e).cssEscape() & "'" proc `$`(counterreset: seq[CSSCounterSet]): string = result = "" for it in counterreset: result &= $it.name result &= ' ' result &= $it.num proc `$`(zIndex: CSSZIndex): string = if zIndex.auto: return "auto" return $zIndex.num proc serialize(val: CSSValue): string = result = "" case val.v of cvtImage: return $val.image of cvtContent: result = "" for x in val.content: if result.len > 0: result &= ' ' result &= $x of cvtQuotes: return $val.quotes of cvtCounterSet: return $val.counterSet else: assert false proc serialize(val: CSSValueHWord; t: CSSValueType): string = case t of cvtInteger: return $val.integer of cvtNumber: return dtoa(val.number) of cvtLineWidth: return dtoa(val.lineWidth) & "px" else: assert false return "" proc serialize(val: CSSValueWord; t: CSSValueType): string = case t of cvtColor: return $val.color of cvtLength: return $val.length of cvtZIndex: return $val.zIndex else: assert false return "" proc serialize(val: CSSValueBit; t: CSSValueType): string = case t of cvtBgcolorIsCanvas: return $val.bgcolorIsCanvas of cvtBorderCollapse: return $val.borderCollapse of cvtBorderStyle: return $val.borderStyle of cvtBoxSizing: return $val.boxSizing of cvtCaptionSide: return $val.captionSide of cvtClear: return $val.clear of cvtDisplay: return $val.display of cvtFlexDirection: return $val.flexDirection of cvtFlexWrap: return $val.flexWrap of cvtFloat: return $val.float of cvtFontStyle: return $val.fontStyle of cvtListStylePosition: return $val.listStylePosition of cvtListStyleType: return $val.listStyleType of cvtOverflow: return $val.overflow of cvtPosition: return $val.position of cvtTextAlign: return $val.textAlign of cvtTextDecoration: return $val.textDecoration of cvtTextTransform: return $val.textTransform of cvtVerticalAlign: return $val.verticalAlign of cvtVisibility: return $val.visibility of cvtWhiteSpace: return $val.whiteSpace of cvtWordBreak: return $val.wordBreak else: assert false return "" proc serialize*(computed: CSSValues; p: CSSPropertyType): string = case p.reprType of cprtBit: return computed.bits[p].serialize(valueType(p)) of cprtHWord: return computed.hwords[p].serialize(valueType(p)) of cprtWord: return computed.words[p].serialize(valueType(p)) of cprtObject: return computed.objs[p].serialize() proc `$`*(computed: CSSValues): string = result = "" const skip = { cptVerticalAlignLength, cptBorderSpacingInline, cptBorderSpacingBlock } for p in CSSPropertyType: if p in skip: continue result &= $p & ':' if p == cptVerticalAlign: if computed.bits[p].verticalAlign == VerticalAlignLength: result &= computed.serialize(cptVerticalAlignLength) result &= ';' continue result &= computed.serialize(p) result &= ';' result &= "border-spacing: " & computed.serialize(cptBorderSpacingInline) & ' ' & computed.serialize(cptBorderSpacingBlock) & ';' when defined(debug): proc `$`*(val: CSSValue): string = return val.serialize() proc getLength*(vals: CSSValues; p: CSSPropertyType): CSSLength = return vals.words[p].length proc getLineWidth*(vals: CSSValues; p: CSSPropertyType): float32 = return vals.hwords[p].lineWidth proc getBorderStyle*(vals: CSSValues; p: CSSPropertyType): CSSBorderStyle = return vals.bits[p].borderStyle macro `{}`*(vals: CSSValues; s: static string): untyped = let t = propertyType(s).get let vs = ident($valueType(t)) case t.reprType of cprtBit: return quote do: `vals`.bits[CSSPropertyType(`t`)].`vs` of cprtHWord: return quote do: `vals`.hwords[CSSPropertyType(`t`)].`vs` of cprtWord: return quote do: `vals`.words[CSSPropertyType(`t`)].`vs` of cprtObject: return quote do: `vals`.objs[CSSPropertyType(`t`)].`vs` macro `{}=`*(vals: CSSValues; s: static string, val: typed) = let t = propertyType(s).get let v = valueType(t) let vs = ident($v) case t.reprType of cprtBit: return quote do: `vals`.bits[CSSPropertyType(`t`)] = CSSValueBit(`vs`: `val`) of cprtHWord: return quote do: `vals`.words[CSSPropertyType(`t`)] = CSSValueHWord(`vs`: `val`) of cprtWord: return quote do: `vals`.words[CSSPropertyType(`t`)] = CSSValueWord(`vs`: `val`) of cprtObject: return quote do: `vals`.objs[CSSPropertyType(`t`)] = CSSValue( v: CSSValueType(`v`), `vs`: `val` ) proc inherited*(t: CSSPropertyType): bool = return t in InheritedProperties proc blockify*(display: CSSDisplay): CSSDisplay = case display of DisplayBlock, DisplayTable, DisplayListItem, DisplayNone, DisplayFlowRoot, DisplayFlex, DisplayTableWrapper, DisplayGrid, DisplayMarker, DisplayImageBlock, DisplayImageInline: return display of DisplayInline, DisplayInlineBlock, DisplayTableRow, DisplayTableRowGroup, DisplayTableColumn, DisplayTableColumnGroup, DisplayTableCell, DisplayTableCaption, DisplayTableHeaderGroup, DisplayTableFooterGroup: return DisplayBlock of DisplayInlineTable: return DisplayTable of DisplayInlineFlex: return DisplayFlex of DisplayInlineGrid: return DisplayGrid proc bfcify*(overflow: CSSOverflow): CSSOverflow = if overflow == OverflowVisible: return OverflowAuto if overflow == OverflowClip: return OverflowHidden return overflow proc imgify*(display: CSSDisplay): CSSDisplay = case display of DisplayOuterInline: return DisplayImageInline of DisplayOuterBlock: return DisplayImageBlock of DisplayNone: return display of DisplayInternalTable: return DisplayImageBlock const UpperAlphaMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toPoints() const LowerGreekMap = "αβγδεζηθικλμνξοπρστυφχψω".toPoints() const HiraganaMap = ("あいうえおかきくけこさしすせそたちつてとなにぬねの" & "はひふへほまみむめもやゆよらりるれろわゐゑをん").toPoints() const HiraganaIrohaMap = ("いろはにほへとちりぬるをわかよたれそつねならむ" & "うゐのおくやまけふこえてあさきゆめみしゑひもせす").toPoints() const KatakanaMap = ("アイウエオカキクケコサシスセソタチツテトナニヌネノ" & "ハヒフヘホマミムメモヤユヨラリルレロワヰヱヲン").toPoints() const KatakanaIrohaMap = ("イロハニホヘトチリヌルヲワカヨタレソツネナラム" & "ウヰノオクヤマケフコエテアサキユメミシヱヒモセス").toPoints() const EarthlyBranchMap = "子丑寅卯辰巳午未申酉戌亥".toPoints() const HeavenlyStemMap = "甲乙丙丁戊己庚辛壬癸".toPoints() proc numToBase(n: int; map: openArray[uint32]): string = if n <= 0 or map.len == 0: return $n var tmp: seq[uint32] = @[] var n = n while n != 0: n -= 1 tmp &= map[n mod map.len] n = n div map.len var res = "" for u in tmp.ritems: res.addUTF8(u) move(res) proc numToFixed(n: int32; map: openArray[uint32]): string = if n in 1 .. map.len: return map[n - 1].toUTF8() return $n proc numberAdditive(i: int32; range: Slice[int32]; symbols: openArray[(int32, cstring)]): string = if i notin range: return $i var s = "" var n = i var at = 0 while n > 0: if n >= symbols[at][0]: n -= symbols[at][0] s &= $symbols[at][1] continue inc at move(s) type Z = cstring const romanNumbers = [ (1000i32, Z"M"), (900i32, Z"CM"), (500i32, Z"D"), (400i32, Z"CD"), (100i32, Z"C"), (90i32, Z"XC"), (50i32, Z"L"), (40i32, Z"XL"), (10i32, Z"X"), (9i32, Z"IX"), (5i32, Z"V"), (4i32, Z"IV"), (1i32, Z"I") ] proc romanNumber(i: int32): string = return numberAdditive(i, 1i32..3999i32, romanNumbers) proc japaneseNumber(i: int32; formal: bool): string = if i == 0: return if formal: "〇" else: "零" var n = i var s = "" if i < 0: s &= "マイナス" n *= -1 let o = n var ss: seq[cstring] = @[] var d = 0 while n > 0: let m = n mod 10 if m != 0: case d of 1: ss.add(if formal: cstring"拾" else: "十") if formal: ss.add("壱") of 2: ss.add("百") if formal: ss.add("壱") of 3: ss.add(if formal: cstring"阡" else: "千") if formal: ss.add("壱") of 4: ss.add("万") ss.add(if formal: cstring"壱" else: "一") of 5: ss.add("万") ss.add(if formal: cstring"拾" else: "十") of 6: ss.add("万") ss.add("百") of 7: ss.add("万") ss.add(if formal: cstring"阡" else: "千") ss.add(if formal: cstring"壱" else: "一") of 8: ss.add("億") ss.add(if formal: cstring"壱" else: "一") of 9: ss.add("億") ss.add(if formal: cstring"拾" else: "十") else: discard case m of 0: inc d n = n div 10 of 1: if o == n: ss.add(if formal: cstring"壱" else: "一") of 2: ss.add(if formal: cstring"弐" else: "二") of 3: ss.add(if formal: cstring"参" else: "三") of 4: ss.add("四") of 5: ss.add(if formal: cstring"伍" else: "五") of 6: ss.add("六") of 7: ss.add("七") of 8: ss.add("八") of 9: ss.add("九") else: discard n -= m for it in ss.ritems: s &= $it move(s) proc listMarker0(t: CSSListStyleType; i: int32; hintMap: openArray[uint32]): string = return case t of ListStyleTypeNone: "" of ListStyleTypeDisc: "•" # U+2022 of ListStyleTypeCircle: "○" # U+25CB of ListStyleTypeSquare: "□" # U+25A1 of ListStyleTypeDisclosureOpen: "▶" # U+25B6 of ListStyleTypeDisclosureClosed: "▼" # U+25BC of ListStyleTypeDecimal: $i of ListStyleTypeUpperRoman: romanNumber(i) of ListStyleTypeLowerRoman: romanNumber(i).toLowerAscii() of ListStyleTypeUpperAlpha: numToBase(i, UpperAlphaMap) of ListStyleTypeLowerAlpha: numToBase(i, UpperAlphaMap).toLowerAscii() of ListStyleTypeLowerGreek: numToBase(i, LowerGreekMap) of ListStyleTypeHiragana: numToBase(i, HiraganaMap) of ListStyleTypeHiraganaIroha: numToBase(i, HiraganaIrohaMap) of ListStyleTypeKatakana: numToBase(i, KatakanaMap) of ListStyleTypeKatakanaIroha: numToBase(i, KatakanaIrohaMap) of ListStyleTypeCjkEarthlyBranch: numToFixed(i, EarthlyBranchMap) of ListStyleTypeCjkHeavenlyStem: numToFixed(i, HeavenlyStemMap) of ListStyleTypeJapaneseInformal: japaneseNumber(i, formal = false) of ListStyleTypeJapaneseFormal: japaneseNumber(i, formal = true) of ListStyleTypeHint: numToBase(i, hintMap) proc listMarkerSuffix(t: CSSListStyleType): string = return case t of ListStyleTypeNone, ListStyleTypeHint: "" of ListStyleTypeDisc, ListStyleTypeCircle, ListStyleTypeSquare, ListStyleTypeDisclosureOpen, ListStyleTypeDisclosureClosed: " " of ListStyleTypeDecimal, ListStyleTypeUpperRoman, ListStyleTypeLowerRoman, ListStyleTypeUpperAlpha, ListStyleTypeLowerAlpha, ListStyleTypeLowerGreek: ". " of ListStyleTypeHiragana, ListStyleTypeHiraganaIroha, ListStyleTypeKatakana, ListStyleTypeKatakanaIroha, ListStyleTypeCjkEarthlyBranch, ListStyleTypeCjkHeavenlyStem, ListStyleTypeJapaneseInformal, ListStyleTypeJapaneseFormal: "、" proc listMarker*(t: CSSListStyleType; i: int32; suffix: bool; hintMap: openArray[uint32]): RefString = let res = newRefString(listMarker0(t, i, hintMap)) if suffix: res.s &= listMarkerSuffix(t) res proc quoteStart*(level: int): string = if level == 0: return "“" return "‘" proc quoteEnd*(level: int): string = if level == 0: return "“" return "‘" proc parseIdent(map: openArray[IdentMapItem]; tok: CSSToken): int = if tok.t == cttIdent: return map.parseEnumNoCase0(tok.s) return -1 proc parseIdent[T: enum](tok: CSSToken): Opt[T] = const IdentMap = getIdentMap(T) let i = IdentMap.parseIdent(tok) if i != -1: return ok(T(i)) return err() proc parseIdent[T: enum](ctx: var CSSParser): Opt[T] = return parseIdent[T](ctx.consume()) template cssLength*(n: float32): CSSLength = CSSLength(npx: n) template cssLengthFrac*(n: float32): CSSLength = CSSLength(perc: n) template cssLengthPerc*(n: float32): CSSLength = cssLengthFrac(n / 100) const CSSLengthAuto* = CSSLength(npx: NaN, perc: NaN) const CSSLengthZero* = CSSLength(npx: 0, perc: 0) proc resolveLength*(u: CSSUnit; val: float32; attrs: WindowAttributes): CSSLength = return case u of cuAuto: CSSLengthAuto of cuEm, cuRem, cuCap, cuRcap, cuLh, cuRlh: cssLength(val * float32(attrs.ppl)) of cuCh, cuRch: cssLength(val * float32(attrs.ppc)) of cuIc, cuRic: cssLength(val * float32(attrs.ppc) * 2) of cuEx, cuRex: cssLength(val * float32(attrs.ppc) / 2) of cuPx: cssLength(val) of cuCm: cssLength(val * 37.8) of cuMm: cssLength(val * 3.78) of cuIn: cssLength(val * 96) of cuPc: cssLength(val * 16) of cuPt: cssLength(val * 4 / 3) of cuDvw, cuVw, cuDvi, cuVi: cssLength(float32(attrs.widthPx) * val / 100) of cuDvh, cuVh, cuDvb, cuVb: cssLength(float32(attrs.heightPx) * val / 100) of cuVmin, cuSvmin, cuLvmin, cuDvmin: cssLength(min(attrs.widthPx, attrs.heightPx) / 100 * val) of cuVmax, cuSvmax, cuLvmax, cuDvmax: cssLength(max(attrs.widthPx, attrs.heightPx) / 100 * val) proc parseLength(tok: CSSToken; attrs: WindowAttributes): Opt[CSSLength] = if tok.dt in CSSDimensionType(CSSUnit.low)..CSSDimensionType(CSSUnit.high): return ok(resolveLength(CSSUnit(tok.dt), tok.num, attrs)) return err() # The return value is in degrees. proc parseAngle(tok: CSSToken): Opt[float32] = case tok.dt of catDeg: return ok(tok.num) of catGrad: return ok(tok.num * 0.9f32) of catRad: return ok(radToDeg(tok.num)) of catTurn: return ok(tok.num * 360f32) else: return err() template calcSumNumber(num: float32): CSSCalcSum = CSSCalcSum(t: ccstNumber, n: num) proc parseCalcValue(ctx: var CSSParser; attrs: ptr WindowAttributes): Opt[CSSCalcSum] = ?ctx.skipBlanksCheckHas() case (let t = ctx.peekTokenType(); t) of cttNumber: let tok = ctx.consume() return ok(calcSumNumber(tok.num)) of cttIdent: let tok = ctx.consume() let keyword = ?parseEnumNoCase[CSSCalcKeyword](tok.s) case keyword of ccskE: return ok(calcSumNumber(E)) of ccskPi: return ok(calcSumNumber(PI)) of ccskInfinity: return ok(calcSumNumber(Inf)) of ccskMinusInfinity: return ok(calcSumNumber(-Inf)) of ccskNaN: return err() #TODO it seems nobody implements this yet? of cttLparen, cttFunction: if t == cttFunction and ctx.peekToken().ft != cftCalc: return err() ctx.seekToken() var res = ctx.parseCalcSum(attrs) if ctx.has() and ctx.peekTokenType() != cttRparen: res = Opt[CSSCalcSum].err() ctx.skipFunction() return res of cttPercentage: let tok = ctx.consume() let length = cssLengthPerc(tok.num) return ok(CSSCalcSum(t: ccstLength, l: length)) of cttDimension: let tok = ctx.consume() if deg := parseAngle(tok): return ok(CSSCalcSum(t: ccstDegree, deg: deg)) if attrs == nil: return err() let length = ?parseLength(tok, attrs[]) return ok(CSSCalcSum(t: ccstLength, l: length)) else: return err() proc parseCalcProduct(ctx: var CSSParser; attrs: ptr WindowAttributes): Opt[CSSCalcSum] = var a = ?ctx.parseCalcValue(attrs) while ctx.skipBlanksCheckHas().isOk: let t = ctx.peekTokenType() if t notin {cttStar, cttSlash}: break let delim = ctx.consume().t var b = ?ctx.parseCalcProduct(attrs) var n = 0f32 if delim == cttSlash: # division: b must be a number if b.t != ccstNumber or b.n == 0: return err() n = 1 / b.n else: # multiplication: either can be length, but not both if b.t != ccstNumber: swap(a, b) if b.t != ccstNumber: return err() n = b.n case a.t of ccstLength: a.l.npx *= n a.l.perc *= n of ccstNumber: a.n *= n of ccstDegree: a.deg *= n ok(a) proc parseCalcSum(ctx: var CSSParser; attrs: ptr WindowAttributes): Opt[CSSCalcSum] = var a = ?ctx.parseCalcProduct(attrs) while ctx.skipBlanksCheckHas().isOk: let t = ctx.peekTokenType() if t notin {cttPlus, cttMinus}: break let mul = if ctx.consume().t == cttPlus: 1f32 else: -1f32 var b = ?ctx.parseCalcProduct(attrs) if a.t != b.t: # cannot add length to number return err() case b.t of ccstLength: a.l.npx += mul * b.l.npx a.l.perc += mul * b.l.perc of ccstDegree: a.deg += mul * b.deg of ccstNumber: a.n += mul * b.n ok(a) # Note: `attrs' may be nil, in that case only numbers are accepted. proc parseCalc(ctx: var CSSParser; attrs: ptr WindowAttributes): Opt[CSSCalcSum] = var res = ctx.parseCalcSum(attrs) if ctx.has() and ctx.peekTokenType() != cttRparen: res = Opt[CSSCalcSum].err() ctx.skipFunction() res proc parseColorComponent(ctx: var CSSParser): Opt[CSSToken] = ?ctx.skipBlanksCheckHas() case ctx.peekTokenType() of cttFunction: if ctx.peekToken().ft != cftCalc: ctx.seek() return err() ctx.seekToken() let res = ?ctx.parseCalc(nil) case res.t of ccstNumber: return ok(cssNumberToken(res.n)) of ccstDegree: return ok(cssDimensionToken(res.deg, catDeg)) of ccstLength: return ok(cssPercentageToken(res.l.perc * 100)) of cttNumber, cttPercentage, cttDimension: return ok(ctx.consume()) of cttIdent: if not ctx.peekIdentNoCase("none"): return err() return ok(ctx.consume()) else: return err() proc parseRGBComponent(tok: CSSToken): Opt[uint8] = case tok.t of cttDimension: return err() of cttIdent: # none return ok(0u8) else: var res = tok.num if tok.t == cttPercentage: res *= 2.55 res += 0.5 ok(uint8(clamp(res, 0, 255))) # number proc parseHue(tok: CSSToken): Opt[uint32] = var n = 0i32 case tok.t of cttNumber: n = tok.toi of cttIdent: discard # none -> 0 of cttDimension: n = int32(?parseAngle(tok)) else: return err() n = n mod 360 if n < 0: n = n + 360 return ok(uint32(n)) proc parseSatOrLight(tok: CSSToken): Opt[uint8] = if tok.t in {cttNumber, cttPercentage}: return ok(uint8(clamp(tok.toi, 0i32, 100i32))) return err() # For rgb(), rgba(), hsl(), hsla(). proc parseLegacyColorFun(ctx: var CSSParser; ft: CSSFunctionType): Opt[CSSColor] = let v1 = ?ctx.parseColorComponent() ?ctx.skipBlanksCheckHas() let legacy = ctx.peekTokenType() == cttComma if legacy: ctx.seekToken() let v2 = ?ctx.parseColorComponent() if legacy: ?ctx.skipBlanksCheckHas() if ctx.consume().t != cttComma: return err() let v3 = ?ctx.parseColorComponent() if legacy and (v1.t == cttIdent or v2.t == cttIdent or v3.t == cttIdent): return err() # legacy doesn't accept "none" var a = 255u8 if ctx.skipBlanksCheckHas().isOk and ctx.peekTokenType() != cttRparen: if ctx.peekTokenType() != (if legacy: cttComma else: cttSlash): return err() ctx.seekToken() let v4 = ?ctx.parseColorComponent() if v4.t in {cttIdent, cttDimension}: return err() a = uint8(clamp(v4.num, 0, 1) * 255) case ft of cftRgb, cftRgba: if legacy and (v1.t != v2.t or v2.t != v3.t): return err() let r = ?parseRGBComponent(v1) let g = ?parseRGBComponent(v2) let b = ?parseRGBComponent(v3) return ok(rgba(r, g, b, a).cssColor()) of cftHsl, cftHsla: if legacy and (v1.t == cttIdent or v2.t != cttPercentage or v3.t != cttPercentage): return err() let h = ?parseHue(v1) let s = ?parseSatOrLight(v2) let l = ?parseSatOrLight(v3) return ok(hsla(h, s, l, a).cssColor()) else: return err() proc ansiColorNumeric(n: int32): Opt[CSSColor] = if n < 0 or n > 255: return err() ok(ANSIColor(n).cssColor()) # syntax: -cha-ansi( number | ident ) # where number is an ANSI color (0..255) # and ident is in NameTable and may start with "bright-" proc parseANSI(ctx: var CSSParser): Opt[CSSColor] = ?ctx.skipBlanksCheckHas() let tok = ctx.consume() case tok.t of cttNumber: return ansiColorNumeric(tok.toi) of cttFunction: if tok.ft != cftCalc: ctx.skipFunction() return err() let res = ?ctx.parseCalc(nil) if res.t == ccstNumber: return ansiColorNumeric(int32(res.n)) of cttIdent: var name = tok.s if name.equalsIgnoreCase("default"): return ok(defaultColor.cssColor()) var bright = false if name.startsWithIgnoreCase("bright-"): bright = true name = name.substr("bright-".len) const NameTable = [ "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white" ] for i, it in NameTable.mypairs: if it.equalsIgnoreCase(name): var i = int(i) if bright: i += 8 return ok(ANSIColor(i).cssColor()) else: discard return err() proc parseColor*(ctx: var CSSParser): Opt[CSSColor] = ?ctx.skipBlanksCheckHas() let tok = ctx.consume() case tok.t of cttHash: let c = ?parseHexColor(tok.s) return ok(c.cssColor()) of cttIdent: if tok.s.equalsIgnoreCase("transparent"): return ok(rgba(0, 0, 0, 0).cssColor()) if tok.s.equalsIgnoreCase("currentcolor"): return ok(cssCurrentColor()) if x := namedRGBColor(tok.s): return ok(x.cssColor()) elif tok.s.equalsIgnoreCase("canvas") or tok.s.equalsIgnoreCase("canvastext"): # Not really compliant, but if you're setting text color to # canvas you're doing it wrong anyway. return ok(defaultColor.cssColor()) else: return err() of cttFunction: var res = case tok.ft of cftRgb, cftRgba, cftHsl, cftHsla: ctx.parseLegacyColorFun(tok.ft) of cftChaAnsi: ctx.parseANSI() else: Opt[CSSColor].err() if ctx.has() and ctx.peekTokenType() != cttRparen: res = Opt[CSSColor].err() ctx.skipFunction() return res else: return err() proc parseLength*(ctx: var CSSParser; attrs: WindowAttributes; hasAuto = true; allowNegative = true): Opt[CSSLength] = ?ctx.skipBlanksCheckHas() case (let tok = ctx.consume(); tok.t) of cttNumber: if tok.num == 0: return ok(CSSLengthZero) of cttPercentage: let n = tok.num if not allowNegative and n < 0: return err() return ok(cssLengthPerc(n)) of cttDimension: if not allowNegative and tok.num < 0: return err() return parseLength(tok, attrs) of cttIdent: if hasAuto and tok.s.equalsIgnoreCase("auto"): return ok(CSSLengthAuto) of cttFunction: if tok.ft != cftCalc: ctx.skipFunction() return err() let res = ?ctx.parseCalc(unsafeAddr attrs) if res.t == ccstLength: return ok(res.l) else: discard err() proc parseLength*(toks: openArray[CSSToken]; attrs: WindowAttributes; hasAuto = true; allowNegative = true): Opt[CSSLength] = var ctx = initCSSParser(toks) return ctx.parseLength(attrs, hasAuto, allowNegative) proc parseAbsoluteLength(tok: CSSToken; attrs: WindowAttributes): Opt[CSSLength] = case tok.t of cttNumber: if tok.num == 0: return ok(CSSLengthZero) of cttDimension: if tok.num >= 0: return parseLength(tok, attrs) else: discard err() proc parseQuotes(ctx: var CSSParser): Opt[CSSQuotes] = case ctx.peekTokenType() of cttIdent: let tok = ctx.consume() if tok.s.equalsIgnoreCase("auto"): return ok(nil) elif tok.s.equalsIgnoreCase("none"): return ok(CSSQuotes()) return err() of cttString: var res = CSSQuotes() while ctx.has(): ?ctx.skipBlanksCheckHas() if ctx.peekTokenType() != cttString: return err() let tok1 = ctx.consume() ?ctx.skipBlanksCheckHas() if ctx.peekTokenType() != cttString: return err() let tok2 = ctx.consume() res.qs.add((newRefString(tok1.s), newRefString(tok2.s))) return ok(move(res)) else: return err() proc parseContent(ctx: var CSSParser): Opt[seq[CSSContent]] = var res: seq[CSSContent] = @[] ctx.skipBlanks() while ctx.has(): case (let tok = ctx.consume(); tok.t) of cttIdent: if tok.s == "/": break elif tok.s.equalsIgnoreCase("open-quote"): res.add(CSSContent(t: ContentOpenQuote)) elif tok.s.equalsIgnoreCase("no-open-quote"): res.add(CSSContent(t: ContentNoOpenQuote)) elif tok.s.equalsIgnoreCase("close-quote"): res.add(CSSContent(t: ContentCloseQuote)) elif tok.s.equalsIgnoreCase("no-close-quote"): res.add(CSSContent(t: ContentNoCloseQuote)) of cttString: res.add(CSSContent(t: ContentString, s: newRefString(tok.s))) of cttWhitespace: discard of cttFunction: case tok.ft of cftCounter: ctx.skipBlanks() if ctx.peekTokenType() != cttIdent: ctx.skipFunction() return err() let name = ctx.consume().s.toAtom() var style = ListStyleTypeDecimal ctx.skipBlanks() if ctx.has() and (let tok = ctx.consume(); tok.t != cttRparen): if tok.t != cttComma: ctx.skipFunction() return err() ctx.skipBlanks() if ctx.has() and (let tok = ctx.consume(); tok.t != cttRparen): # stick with decimal if not found style = parseIdent[CSSListStyleType](tok).get(style) ctx.skipBlanks() if ctx.consume().t != cttRparen: ctx.skipFunction() return err() res.add(CSSContent( t: ContentCounter, counter: name, counterStyle: style )) else: ctx.skipFunction() return err() else: return err() ok(res) proc parseFontWeight(ctx: var CSSParser): Opt[int32] = let tok = ctx.consume() case tok.t of cttIdent: const FontWeightMap = { "bold": 700, "bolder": 700, "lighter": 400, "normal": 400 } let i = FontWeightMap.parseIdent(tok) if i != -1: return ok(int32(i)) elif tok.t == cttNumber: let i = tok.toi if i in 1i32..1000i32: return ok(i) return err() proc parseTextDecoration(ctx: var CSSParser): Opt[set[CSSTextDecoration]] = var s: set[CSSTextDecoration] = {} while ctx.has(): let tok = ctx.consume() if tok.t == cttIdent: let td = ?parseIdent[CSSTextDecoration](tok) if td == TextDecorationNone: if s != {}: return err() return ok(s) s.incl(td) return ok(s) proc parseCounterSet(ctx: var CSSParser; n: int32): Opt[seq[CSSCounterSet]] = var res: seq[CSSCounterSet] = @[] while ctx.has(): if ctx.peekTokenType() != cttIdent: return err() let name = ctx.consume().s.toAtom() var r = CSSCounterSet(name: name) ctx.skipBlanks() if ctx.has() and ctx.peekTokenType() == cttNumber: r.num = ctx.consume().toi res.add(r) else: r.num = n res.add(r) ctx.skipBlanks() return ok(move(res)) proc parseMaxSize(ctx: var CSSParser; attrs: WindowAttributes): Opt[CSSLength] = ?ctx.skipBlanksCheckHas() if ctx.peekTokenType() == cttIdent and ctx.consume().s.equalsIgnoreCase("none"): return ok(CSSLengthAuto) return ctx.parseLength(attrs, hasAuto = true, allowNegative = false) #TODO should be URL (parsed with baseurl of document...) proc parseURL*(ctx: var CSSParser; tok: CSSToken; src = false): Opt[string] = case tok.t of cttUrl: return ok(tok.s) of cttString: if src: return err() return ok(tok.s) of cttFunction: if tok.ft != cftUrl and (not src or tok.ft != cftSrc): return err() ?ctx.skipBlanksCheckHas() let tok = ctx.consume() if tok.t != cttString: return err() ctx.skipBlanks() if ctx.has() and ctx.consume().t != cttRparen: ctx.skipFunction() return err() return ok(tok.s) else: return err() #TODO this should be bg-image, add gradient, etc etc proc parseImage(ctx: var CSSParser): Opt[NetworkBitmap] = #TODO bg-image only ?ctx.skipBlanksCheckHas() let tok = ctx.consume() if tok.t == cttIdent and tok.s.equalsIgnoreCase("none"): return ok(nil) let url = ?ctx.parseURL(tok, src = true) #TODO do something with the URL discard url return ok(NetworkBitmap(cacheId: -1, imageId: -1)) proc parseInteger(ctx: var CSSParser; range: Slice[int32]): Opt[int32] = let i = ?ctx.consumeInt() if i in range: return ok(i) return err() proc parseZIndex(ctx: var CSSParser): Opt[CSSZIndex] = if ctx.peekIdentNoCase("auto"): ctx.seekToken() return ok(CSSZIndex(auto: true)) let n = ?ctx.parseInteger(-65534i32 .. 65534i32) return ok(CSSZIndex(num: n)) proc parseNumber(ctx: var CSSParser; range: Slice[float32]): Opt[float32] = let tok = ctx.peekToken() if tok.t == cttNumber: if (let n = tok.num; n in range): ctx.seekToken() return ok(n) return err() type LineWidthKeyword = enum lwkThin = (1, "thin") lwkMedium = (2, "medium") lwkThick = (3, "thick") proc parseLineWidth(ctx: var CSSParser; attrs: WindowAttributes): Opt[float32] = let tok = ctx.peekToken() if tok.t == cttIdent: ctx.seek() let s = ?parseEnumNoCase[LineWidthKeyword](tok.s) return ok(float32(s)) let l = ?ctx.parseLength(attrs, hasAuto = false, allowNegative = false) if l.isPerc: return err() ok(l.npx) proc makeEntry*(t: CSSPropertyType; obj: CSSValue): CSSComputedEntry = return CSSComputedEntry(et: ceObject, p: wide(t), obj: obj) proc makeEntry(t: CSSPropertyType; hword: CSSValueHWord): CSSComputedEntry = return CSSComputedEntry(et: ceHWord, p: wide(t), hword: hword) proc makeEntry(t: CSSPropertyType; word: CSSValueWord): CSSComputedEntry = return CSSComputedEntry(et: ceWord, p: wide(t), word: word) proc makeEntry*(t: CSSPropertyType; bit: CSSValueBit): CSSComputedEntry = return CSSComputedEntry(et: ceBit, p: wide(t), bit: bit.dummy) proc makeEntry(t: CSSPropertyType; global: CSSGlobalType): CSSComputedEntry = return CSSComputedEntry(et: ceGlobal, p: wide(t), global: global) proc makeEntry*(t: CSSPropertyType; length: CSSLength): CSSComputedEntry = makeEntry(t, CSSValueWord(length: length)) proc makeEntry*(t: CSSPropertyType; color: CSSColor): CSSComputedEntry = makeEntry(t, CSSValueWord(color: color)) proc makeEntry(t: CSSPropertyType; zIndex: CSSZIndex): CSSComputedEntry = makeEntry(t, CSSValueWord(zIndex: zIndex)) proc makeEntry*(t: CSSPropertyType; integer: int32): CSSComputedEntry = makeEntry(t, CSSValueHWord(integer: integer)) proc makeEntry*(t: CSSPropertyType; number: float32): CSSComputedEntry = makeEntry(t, CSSValueHWord(number: number)) proc makeEntry(t: CSSPropertyType; image: NetworkBitmap): CSSComputedEntry = makeEntry(t, CSSValue(v: cvtImage, image: image)) template makeEntry*[T: enum|set](t: CSSPropertyType; val: T): CSSComputedEntry = CSSComputedEntry(et: ceBit, p: wide(t), bit: cast[uint8](val)) proc parseDeclWithVar0*(toks: openArray[CSSToken]): seq[CSSVarItem] = var ctx = initCSSParser(toks) ctx.skipBlanks() var items: seq[CSSVarItem] = @[] while ctx.has(): let tok = ctx.consume() if tok.t == cttFunction and tok.ft == cftVar: if ctx.skipBlanksCheckHas().isErr: return @[] let tok = ctx.consume() if tok.t != cttIdent: return @[] let name = tok.s.substr(2).toAtom() items.add(CSSVarItem(name: name)) ctx.skipBlanks() var toks: seq[CSSToken] = @[] if ctx.has() and (let tok = ctx.consume(); tok.t != cttRparen): if tok.t != cttComma: return @[] ctx.skipBlanks() while ctx.has() and (let tok = ctx.consume(); tok.t != cttRparen): toks.add(tok) items[^1].toks = move(toks) else: if items.len == 0 or items[^1].name != CAtomNull: items.add(CSSVarItem(name: CAtomNull)) items[^1].toks.add(tok) move(items) proc parseDeclWithVar*(p: CSSWidePropertyType; value: openArray[CSSToken]): Opt[CSSComputedEntry] = var items = parseDeclWithVar0(value) if items.len == 0: return err() let cvar = CSSVarEntry(items: move(items)) return ok(CSSComputedEntry(et: ceVar, p: p, cvar: cvar)) proc parseValue(ctx: var CSSParser; t: CSSPropertyType; entry: var CSSComputedEntry; attrs: WindowAttributes): Opt[void] = ?ctx.skipBlanksCheckHas() let v = valueType(t) entry = case v of cvtDisplay: makeEntry(t, ?parseIdent[CSSDisplay](ctx)) of cvtWhiteSpace: makeEntry(t, ?parseIdent[CSSWhiteSpace](ctx)) of cvtWordBreak: makeEntry(t, ?parseIdent[CSSWordBreak](ctx)) of cvtListStyleType: makeEntry(t, ?parseIdent[CSSListStyleType](ctx)) of cvtFontStyle: makeEntry(t, ?parseIdent[CSSFontStyle](ctx)) of cvtColor: makeEntry(t, ?ctx.parseColor()) of cvtLength: case t of cptMinWidth, cptMinHeight: makeEntry(t, ?ctx.parseLength(attrs, hasAuto = true, allowNegative = false)) of cptMaxWidth, cptMaxHeight: makeEntry(t, ?ctx.parseMaxSize(attrs)) of cptPaddingLeft, cptPaddingRight, cptPaddingTop, cptPaddingBottom: makeEntry(t, ?ctx.parseLength(attrs, hasAuto = false, allowNegative = false)) #TODO content for flex-basis else: makeEntry(t, ?ctx.parseLength(attrs, hasAuto = true, allowNegative = true)) of cvtContent: makeEntry(t, CSSValue(v: v, content: ?ctx.parseContent())) of cvtInteger: case t of cptFontWeight: makeEntry(t, ?ctx.parseFontWeight()) of cptChaColspan: makeEntry(t, ?ctx.parseInteger(1i32 .. 1000i32)) of cptChaRowspan: makeEntry(t, ?ctx.parseInteger(0i32 .. 65534i32)) else: return err() of cvtZIndex: makeEntry(t, ?ctx.parseZIndex()) of cvtTextDecoration: makeEntry(t, ?ctx.parseTextDecoration()) of cvtVerticalAlign: makeEntry(t, ?parseIdent[CSSVerticalAlign](ctx)) of cvtTextAlign: makeEntry(t, ?parseIdent[CSSTextAlign](ctx)) of cvtListStylePosition: makeEntry(t, ?parseIdent[CSSListStylePosition](ctx)) of cvtPosition: makeEntry(t, ?parseIdent[CSSPosition](ctx)) of cvtCaptionSide: makeEntry(t, ?parseIdent[CSSCaptionSide](ctx)) of cvtBorderCollapse: makeEntry(t, ?parseIdent[CSSBorderCollapse](ctx)) of cvtBorderStyle: makeEntry(t, ?parseIdent[CSSBorderStyle](ctx)) of cvtQuotes: makeEntry(t, CSSValue(v: v, quotes: ?ctx.parseQuotes())) of cvtCounterSet: let n = if t == cptCounterIncrement: 1i32 else: 0i32 makeEntry(t, CSSValue(v: v, counterSet: ?ctx.parseCounterSet(n))) of cvtImage: makeEntry(t, CSSValue(v: v, image: ?ctx.parseImage())) of cvtFloat: makeEntry(t, ?parseIdent[CSSFloat](ctx)) of cvtVisibility: makeEntry(t, ?parseIdent[CSSVisibility](ctx)) of cvtBoxSizing: makeEntry(t, ?parseIdent[CSSBoxSizing](ctx)) of cvtClear: makeEntry(t, ?parseIdent[CSSClear](ctx)) of cvtTextTransform: makeEntry(t, ?parseIdent[CSSTextTransform](ctx)) of cvtBgcolorIsCanvas: return err() # internal value of cvtFlexDirection: makeEntry(t, ?parseIdent[CSSFlexDirection](ctx)) of cvtFlexWrap: makeEntry(t, ?parseIdent[CSSFlexWrap](ctx)) of cvtNumber: if t == cptOpacity: makeEntry(t, ?ctx.parseNumber(0f32..1f32)) else: # flex-grow, flex-shrink makeEntry(t, ?ctx.parseNumber(0f32..float32.high)) of cvtOverflow: makeEntry(t, ?parseIdent[CSSOverflow](ctx)) of cvtLineWidth: makeEntry(t, ?ctx.parseLineWidth(attrs)) ok() proc getInitialColor(t: CSSPropertyType): CSSColor = case t of cptBackgroundColor: return rgba(0, 0, 0, 0).cssColor() of cptBorderLeftColor, cptBorderRightColor, cptBorderTopColor, cptBorderBottomColor: return cssCurrentColor() else: return defaultColor.cssColor() proc getInitialLength(t: CSSPropertyType): CSSLength = case t of cptWidth, cptHeight, cptLeft, cptRight, cptTop, cptBottom, cptMaxWidth, cptMaxHeight, cptMinWidth, cptMinHeight, cptFlexBasis: return CSSLengthAuto of cptFontSize: return cssLength(16) else: return CSSLengthZero proc getInitialInteger(t: CSSPropertyType): int32 = case t of cptChaColspan, cptChaRowspan: return 1 of cptFontWeight: return 400 # normal else: return 0 proc getInitialNumber(t: CSSPropertyType): float32 = if t in {cptFlexShrink, cptOpacity}: return 1 return 0 proc getInitialTable(): array[CSSPropertyType, CSSValue] = result = array[CSSPropertyType, CSSValue].default for t in CSSPropertyType: result[t] = CSSValue(v: valueType(t)) let defaultTable = getInitialTable() template getDefault(t: CSSPropertyType): CSSValue = defaultTable[t] proc getDefaultHWord(t: CSSPropertyType): CSSValueHWord = case valueType(t) of cvtInteger: return CSSValueHWord(integer: getInitialInteger(t)) of cvtNumber: return CSSValueHWord(number: getInitialNumber(t)) of cvtLineWidth: return CSSValueHWord(lineWidth: 1) # medium else: return CSSValueHWord(dummy: 0) proc getDefaultWord(t: CSSPropertyType): CSSValueWord = case valueType(t) of cvtColor: return CSSValueWord(color: getInitialColor(t)) of cvtLength: return CSSValueWord(length: getInitialLength(t)) of cvtZIndex: return CSSValueWord(zIndex: CSSZIndex(auto: true)) else: return CSSValueWord(dummy: 0) proc makeDefaultEntry(t: CSSPropertyType): CSSComputedEntry = case t.reprType of cprtBit: return makeEntry(t, CSSValueBit(dummy: 0)) of cprtHWord: return makeEntry(t, getDefaultHWord(t)) of cprtWord: return makeEntry(t, getDefaultWord(t)) of cprtObject: return makeEntry(t, getDefault(t)) const ShorthandMap = [ cstNone: @[], cstAll: @[], cstMargin: @[cptMarginTop, cptMarginRight, cptMarginBottom, cptMarginLeft], cstPadding: @[cptPaddingTop, cptPaddingRight, cptPaddingBottom, cptPaddingLeft], cstBorderStyle: @[cptBorderTopStyle, cptBorderRightStyle, cptBorderBottomStyle, cptBorderLeftStyle], cstBorderColor: @[cptBorderTopColor, cptBorderRightColor, cptBorderBottomColor, cptBorderLeftColor], cstBorderWidth: @[cptBorderTopWidth, cptBorderRightWidth, cptBorderBottomWidth, cptBorderLeftWidth], cstBackground: @[cptBackgroundColor, cptBackgroundImage], cstListStyle: @[cptListStylePosition, cptListStyleType], cstFlex: @[cptFlexGrow, cptFlexShrink, cptFlexBasis], cstFlexFlow: @[cptFlexDirection, cptFlexWrap], cstOverflow: @[cptOverflowX, cptOverflowY], cstVerticalAlign: @[cptVerticalAlign, cptVerticalAlignLength], cstBorderSpacing: @[cptBorderSpacingInline, cptBorderSpacingBlock], cstBorderBottom: @[cptBorderBottomStyle, cptBorderBottomColor, cptBorderBottomWidth], cstBorderLeft: @[cptBorderLeftStyle, cptBorderLeftColor, cptBorderLeftWidth], cstBorderRight: @[cptBorderRightStyle, cptBorderRightColor, cptBorderRightWidth], cstBorderTop: @[cptBorderTopStyle, cptBorderTopColor, cptBorderTopWidth], cstBorder: @[cptBorderTopStyle, cptBorderRightStyle, cptBorderBottomStyle, cptBorderLeftStyle, cptBorderTopColor, cptBorderRightColor, cptBorderBottomColor, cptBorderLeftColor, cptBorderTopWidth, cptBorderRightWidth, cptBorderBottomWidth, cptBorderLeftWidth], ] proc parseBorder(ctx: var CSSParser; sh: CSSShorthandType; attrs: WindowAttributes; res: var seq[CSSComputedEntry]): Opt[void] = var style = makeDefaultEntry(cptBorderLeftStyle) var color = makeDefaultEntry(cptBorderLeftColor) var width = makeDefaultEntry(cptBorderLeftWidth) var nstyle = 0u var ncolor = 0u var nwidth = 0u while ctx.has(): case ctx.peekTokenType() of cttHash: color = makeEntry(cptBorderLeftColor, ?ctx.parseColor()) inc ncolor of cttIdent: let s = ctx.peekToken().s if x := parseEnumNoCase[CSSBorderStyle](s): ctx.seek() style = makeEntry(cptBorderLeftStyle, x) inc nstyle elif x := parseEnumNoCase[LineWidthKeyword](s): ctx.seek() width = makeEntry(cptBorderLeftWidth, float32(x)) inc nwidth else: color = makeEntry(cptBorderLeftColor, ?ctx.parseColor()) inc ncolor of cttFunction: if ctx.peekToken().ft == cftCalc: width = makeEntry(cptBorderLeftWidth, ?ctx.parseLineWidth(attrs)) inc nwidth else: color = makeEntry(cptBackgroundColor, ?ctx.parseColor()) inc ncolor of cttDimension, cttNumber: width = makeEntry(cptBorderLeftWidth, ?ctx.parseLineWidth(attrs)) inc nwidth else: return err() ctx.skipBlanks() if ncolor > 1 or nwidth > 1 or nstyle > 1: return err() for t in ShorthandMap[sh]: case valueType(t) of cvtBorderStyle: style.p = wide(t) res.add(style) of cvtColor: color.p = wide(t) res.add(color) of cvtLineWidth: width.p = wide(t) res.add(width) else: discard return ctx.skipBlanksCheckDone() proc parseBoxShorthand(ctx: var CSSParser; props: openArray[CSSPropertyType]; attrs: WindowAttributes; res: var seq[CSSComputedEntry]): Opt[void] = var entries: seq[CSSComputedEntry] = @[] for i, t in props: if ctx.skipBlanksCheckHas().isErr: break var entry: CSSComputedEntry ?ctx.parseValue(t, entry, attrs) entries.add(entry) case entries.len of 1: # top, bottom, left, right for t in props: entries[0].p = wide(t) res.add(entries[0]) of 2: # top, bottom | left, right for i, t in props.mypairs: entries[i mod 2].p = wide(t) res.add(entries[i mod 2]) of 3: # top | left, right | bottom for i, t in props.mypairs: let j = if i == 0: 0 # top elif i == 2: 2 # bottom else: 1 # left, right entries[j].p = wide(t) res.add(entries[j]) of 4: # top | right | bottom | left res.add(entries) else: discard return ctx.skipBlanksCheckDone() proc parseBackground(ctx: var CSSParser; attrs: WindowAttributes; res: var seq[CSSComputedEntry]): Opt[void] = var color = makeDefaultEntry(cptBackgroundColor) var image = makeDefaultEntry(cptBackgroundImage) while ctx.has(): case ctx.peekTokenType() of cttHash: color = makeEntry(cptBackgroundColor, ?ctx.parseColor()) of cttString: image = makeEntry(cptBackgroundImage, ?ctx.parseImage()) of cttIdent: if ctx.peekIdentNoCase("none"): image = makeEntry(cptBackgroundImage, ?ctx.parseImage()) elif x := ctx.parseColor(): color = makeEntry(cptBackgroundColor, x) of cttFunction: if ctx.peekToken().ft == cftUrl: image = makeEntry(cptBackgroundImage, ?ctx.parseImage()) elif x := ctx.parseColor(): color = makeEntry(cptBackgroundColor, x) else: #TODO when we implement the other shorthands too #return err() while ctx.has() and ctx.peekTokenType() != cttWhitespace: ctx.seek() ctx.skipBlanks() res.add(color) res.add(image) return ctx.skipBlanksCheckDone() proc parseListStyle(ctx: var CSSParser; attrs: WindowAttributes; res: var seq[CSSComputedEntry]): Opt[void] = var typeVal = CSSValueBit() var positionVal = CSSValueBit() while ctx.skipBlanksCheckHas().isOk: let tok = ctx.consume() if r := parseIdent[CSSListStylePosition](tok): positionVal.listStylePosition = r elif r := parseIdent[CSSListStyleType](tok): typeVal.listStyleType = r else: while ctx.has() and ctx.peekTokenType() != cttWhitespace: ctx.seek() #TODO list-style-image #return err() res.add(makeEntry(cptListStylePosition, positionVal)) res.add(makeEntry(cptListStyleType, typeVal)) return ctx.skipBlanksCheckDone() proc parseFlex(ctx: var CSSParser; attrs: WindowAttributes; res: var seq[CSSComputedEntry]): Opt[void] = if r := ctx.parseNumber(0f32..float32.high): # flex-grow res.add(makeEntry(cptFlexGrow, r)) if ctx.skipBlanksCheckHas().isOk: if r := ctx.parseNumber(0f32..float32.high): # flex-shrink res.add(makeEntry(cptFlexShrink, r)) ctx.skipBlanks() if res.len < 1: # flex-grow omitted, default to 1 res.add(makeEntry(cptFlexGrow, 1f32)) if res.len < 2: # flex-shrink omitted, default to 1 res.add(makeEntry(cptFlexShrink, 1f32)) if ctx.has(): # flex-basis res.add(makeEntry(cptFlexBasis, ?ctx.parseLength(attrs))) else: # omitted, default to 0px res.add(makeEntry(cptFlexBasis, CSSLengthZero)) return ctx.skipBlanksCheckDone() proc parseFlexFlow(ctx: var CSSParser; attrs: WindowAttributes; tok0: CSSToken; res: var seq[CSSComputedEntry]): Opt[void] = if dir := parseIdent[CSSFlexDirection](tok0): # flex-direction ctx.seekToken() var val = CSSValueBit(flexDirection: dir) res.add(makeEntry(cptFlexDirection, val)) ctx.skipBlanks() if ctx.has(): let tok = ctx.consume() let wrap = ?parseIdent[CSSFlexWrap](tok) var val = CSSValueBit(flexWrap: wrap) res.add(makeEntry(cptFlexWrap, val)) return ctx.skipBlanksCheckDone() proc parseOverflow(ctx: var CSSParser; attrs: WindowAttributes; tok0: CSSToken; res: var seq[CSSComputedEntry]): Opt[void] = let overflow = ?parseIdent[CSSOverflow](tok0) ctx.seekToken() let x = CSSValueBit(overflow: overflow) var y = x if ctx.skipBlanksCheckHas().isOk: let tok = ctx.consume() y.overflow = ?parseIdent[CSSOverflow](tok) res.add(makeEntry(cptOverflowX, x)) res.add(makeEntry(cptOverflowY, y)) return ctx.skipBlanksCheckDone() proc parseVerticalAlign(ctx: var CSSParser; attrs: WindowAttributes; res: var seq[CSSComputedEntry]): Opt[void] = if ctx.peekTokenType() == cttIdent: var entry = CSSComputedEntry() ?ctx.parseValue(cptVerticalAlign, entry, attrs) res.add(entry) else: let length = ?ctx.parseLength(attrs, hasAuto = false) let val = CSSValueBit(verticalAlign: VerticalAlignLength) res.add(makeEntry(cptVerticalAlign, val)) res.add(makeEntry(cptVerticalAlignLength, length)) return ctx.skipBlanksCheckDone() proc parseBorderSpacing(ctx: var CSSParser; attrs: WindowAttributes; tok0: CSSToken; res: var seq[CSSComputedEntry]): Opt[void] = let a = ?parseAbsoluteLength(tok0, attrs) ctx.seekToken() ctx.skipBlanks() let b = if ctx.has(): ?parseAbsoluteLength(ctx.consume(), attrs) else: a res.add(makeEntry(cptBorderSpacingInline, a)) res.add(makeEntry(cptBorderSpacingBlock, b)) return ctx.skipBlanksCheckDone() proc addGlobal(res: var seq[CSSComputedEntry]; p: CSSWidePropertyType; global: CSSGlobalType) = case p.sh of cstNone: res.add(makeEntry(p.p, global)) of cstAll: for t in CSSPropertyType: res.add(makeEntry(t, global)) else: for t in ShorthandMap[p.sh]: res.add(makeEntry(t, global)) proc parseComputedValues0*(ctx: var CSSParser; p: CSSWidePropertyType; attrs: WindowAttributes; res: var seq[CSSComputedEntry]): Opt[void] = ?ctx.skipBlanksCheckHas() let tok = ctx.peekToken() if global := parseIdent[CSSGlobalType](tok): ctx.seekToken() res.addGlobal(p, global) return ctx.skipBlanksCheckDone() case p.sh of cstNone: var entry = CSSComputedEntry() ?ctx.parseValue(p.p, entry, attrs) res.add(entry) return ctx.skipBlanksCheckDone() of cstAll: return err() of cstBorder, cstBorderBottom, cstBorderLeft, cstBorderRight, cstBorderTop: return ctx.parseBorder(p.sh, attrs, res) of cstMargin, cstPadding, cstBorderStyle, cstBorderColor, cstBorderWidth: return ctx.parseBoxShorthand(ShorthandMap[p.sh], attrs, res) of cstBackground: return ctx.parseBackground(attrs, res) of cstListStyle: return ctx.parseListStyle(attrs, res) of cstFlex: return ctx.parseFlex(attrs, res) of cstFlexFlow: return ctx.parseFlexFlow(attrs, tok, res) of cstOverflow: return ctx.parseOverflow(attrs, tok, res) of cstVerticalAlign: return ctx.parseVerticalAlign(attrs, res) of cstBorderSpacing: return ctx.parseBorderSpacing(attrs, tok, res) proc parseComputedValues*(res: var seq[CSSComputedEntry]; p: CSSWidePropertyType; toks: openArray[CSSToken]; attrs: WindowAttributes) = var ctx = initCSSParser(toks) let olen = res.len if ctx.parseComputedValues0(p, attrs, res).isErr: res.setLen(olen) proc copyFrom*(a, b: CSSValues; t: CSSPropertyType) = case t.reprType of cprtBit: a.bits[t] = b.bits[t] of cprtHWord: a.hwords[t] = b.hwords[t] of cprtWord: a.words[t] = b.words[t] of cprtObject: a.objs[t] = b.objs[t] proc setInitial*(a: CSSValues; t: CSSPropertyType) = case t.reprType of cprtBit: a.bits[t].dummy = 0 of cprtHWord: a.hwords[t] = getDefaultHWord(t) of cprtWord: a.words[t] = getDefaultWord(t) of cprtObject: a.objs[t] = getDefault(t) proc setAllInitial*(a: CSSValues) = for it in a.bits.mitems: it.dummy = 0 for t, it in a.hwords.mpairs: it = getDefaultHWord(t) for t, it in a.words.mpairs: it = getDefaultWord(t) for t, it in a.objs.mpairs: it = getDefault(t) # Note: this doesn't work with objects (it doesn't have to.) proc equals*(a, b: CSSValues; t: CSSPropertyType): bool = return case t.reprType of cprtBit: a.bits[t].dummy == b.bits[t].dummy of cprtHWord: a.hwords[t].dummy == b.hwords[t].dummy of cprtWord: a.words[t].dummy == b.words[t].dummy of cprtObject: false proc initialOrInheritFrom*(a, b: CSSValues; t: CSSPropertyType) = if t.inherited and b != nil: a.copyFrom(b, t) else: a.setInitial(t) proc initialOrCopyFrom*(a, b: CSSValues; t: CSSPropertyType) = if b != nil: a.copyFrom(b, t) else: a.setInitial(t) proc inheritProperties*(parent: CSSValues): CSSValues = result = CSSValues(relayout: parent.relayout) for t in CSSPropertyType: if t.inherited: result.copyFrom(parent, t) else: result.setInitial(t) proc copyProperties*(props: CSSValues): CSSValues = result = CSSValues() result[] = props[] proc rootProperties*(): CSSValues = result = CSSValues() result.setAllInitial() # Separate CSSValues of a table into those of the wrapper and the actual # table. proc splitTable*(computed: CSSValues): tuple[outer, innner: CSSValues] = var outer = CSSValues() var inner = CSSValues() const props = { cptPosition, cptFloat, cptMarginLeft, cptMarginRight, cptMarginTop, cptMarginBottom, cptTop, cptRight, cptBottom, cptLeft, # Note: the standard does not ask us to include padding or sizing, but the # wrapper & actual table layouts share the same sizing from the wrapper, # so we must add them here. cptPaddingLeft, cptPaddingRight, cptPaddingTop, cptPaddingBottom, cptWidth, cptHeight, cptBoxSizing, # no clue why this isn't included in the standard cptClear, cptZIndex } for t in CSSPropertyType: if t in props: outer.copyFrom(computed, t) inner.setInitial(t) else: inner.copyFrom(computed, t) outer.setInitial(t) outer{"display"} = computed{"display"} inner{"display"} = DisplayTableWrapper return (outer, inner) proc borderChar*(style: CSSBorderStyle; c: BoxDrawingChar): string = return case style of BorderStyleNone, BorderStyleHidden: "" of BorderStyleDotted: case c of HorizontalBar: "\u2508" of VerticalBar: "\u250A" else: $c # no dotted corners in Unicode of BorderStyleDashed: case c of HorizontalBar: "\u254C" of VerticalBar: "\u254E" else: $c # likewise of BorderStyleSolid: # the default $c of BorderStyleOutset, BorderStyleGroove: # like solid, but thicker case c of HorizontalBar: "\u2501" of VerticalBar: "\u2503" of bdcCornerTopLeft: "\u250F" of bdcCornerTopRight: "\u2513" of bdcCornerBottomLeft: "\u2517" of bdcCornerBottomRight: "\u251B" of bdcSideBarLeft: "\u2523" of bdcSideBarRight: "\u252B" of bdcSideBarTop: "\u2533" of bdcSideBarBottom: "\u253B" of bdcSideBarCross: "\u254B" of BorderStyleDouble, BorderStyleInset, BorderStyleRidge: # interpret inset/ridge as double case c of HorizontalBar: "\u2550" of VerticalBar: "\u2551" of bdcCornerTopLeft: "\u2554" of bdcCornerTopRight: "\u2557" of bdcCornerBottomLeft: "\u255A" of bdcCornerBottomRight: "\u255D" of bdcSideBarLeft: "\u2560" of bdcSideBarRight: "\u2563" of bdcSideBarTop: "\u2566" of bdcSideBarBottom: "\u2569" of bdcSideBarCross: "\u256C" of BorderStyleBracket: # proprietary extension case c of bdcVerticalBarLeft: "[" of bdcVerticalBarRight: "]" else: " " of BorderStyleParen: # likewise case c of bdcVerticalBarLeft: "(" of bdcVerticalBarRight: ")" else: " " of BorderStyleHash: # likewise case c of bdcHorizontalBarBottom: return "#" of bdcHorizontalBarTop: return "_" else: " " of BorderStylePeriod: # likewise case c of bdcHorizontalBarBottom: return "." else: " " when defined(debug): proc serializeEmpty*(computed: CSSValues): string = let default = rootProperties() result = "" for p in CSSPropertyType: let a = computed.serialize(p) let b = default.serialize(p) if a != b: result &= $p & ':' result &= a result &= ';' {.pop.} # raises: [] �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/css/layout.nim��������������������������������������������������������������������0000664�0000000�0000000�00000356206�15202323131�0016547�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} # Note: if you start (or stop) using a property in layout, don't forget to # modify LayoutProperties in cssvalues. import std/math import css/box import css/cssparser import css/cssvalues import css/lunit import types/bitmap import types/winattrs import utils/luwrap import utils/strwidth import utils/twtstr import utils/widthconv type LayoutContext = ref object cellSize: Size # size(w = attrs.ppc, h = attrs.ppl) luctx: LUContext const DefaultSpan = Span(start: 0'lu, send: LUnit.high) proc minWidth(bounds: BoundsPart): LUnit = return bounds[dtHorizontal].start proc maxWidth(bounds: BoundsPart): LUnit = return bounds[dtHorizontal].send proc minHeight(bounds: BoundsPart): LUnit = return bounds[dtVertical].start proc maxHeight(bounds: BoundsPart): LUnit = return bounds[dtVertical].send proc startOffset(rect: RelativeRect): Offset = return offset(x = rect[dtHorizontal].start, y = rect[dtVertical].start) proc opposite(dim: DimensionType): DimensionType = case dim of dtHorizontal: return dtVertical of dtVertical: return dtHorizontal proc initSpace(w, h: SizeConstraint): Space = return [dtHorizontal: w, dtVertical: h] proc w(space: Space): SizeConstraint {.inline.} = return space[dtHorizontal] proc w(space: var Space): var SizeConstraint {.inline.} = return space[dtHorizontal] proc `w=`(space: var Space; w: SizeConstraint) {.inline.} = space[dtHorizontal] = w proc h(space: var Space): var SizeConstraint {.inline.} = return space[dtVertical] proc h(space: Space): SizeConstraint {.inline.} = return space[dtVertical] proc `h=`(space: var Space; h: SizeConstraint) {.inline.} = space[dtVertical] = h proc measure(): SizeConstraint = return SizeConstraint(t: scMeasure) proc maxContent(): SizeConstraint = return SizeConstraint(t: scMaxContent) proc stretch(u: LUnit): SizeConstraint = return SizeConstraint(t: scStretch, u: u) proc stretch(s: Size): Space = return initSpace(w = stretch(s.w), h = stretch(s.h)) proc fitContent(u: LUnit): SizeConstraint = return SizeConstraint(t: scFitContent, u: u) proc fitContent(sc: SizeConstraint): SizeConstraint = case sc.t of scMinContent, scMaxContent, scMeasure: return sc of scStretch, scFitContent: return SizeConstraint(t: scFitContent, u: sc.u) proc isDefinite(sc: SizeConstraint): bool = return sc.t in {scStretch, scFitContent} proc canpx(l: CSSLength; sc: SizeConstraint): bool = return not l.auto and (l.perc == 0 or sc.t == scStretch) proc px(l: CSSLength; p: LUnit): LUnit {.inline.} = if l.auto: return 0'lu return (p.toFloat32() * l.perc + l.npx).toLUnit() proc px(l: CSSLength; p: SizeConstraint): LUnit {.inline.} = if l.perc == 0: return l.npx.toLUnit() if l.auto: return 0'lu if p.t == scStretch: return (p.u.toFloat32() * l.perc + l.npx).toLUnit() return 0'lu proc stretchOrMaxContent(l: CSSLength; sc: SizeConstraint): SizeConstraint = if l.canpx(sc): return stretch(l.px(sc)) return maxContent() proc applySizeConstraint(u: LUnit; availableSize: SizeConstraint): LUnit = case availableSize.t of scStretch: return availableSize.u of scMinContent, scMaxContent, scMeasure: # must be calculated elsewhere... return u of scFitContent: return min(u, availableSize.u) proc borderTopLeft(input: LayoutInput; lctx: LayoutContext): Offset = input.borderTopLeft(lctx.cellSize) proc borderSize(input: LayoutInput; dim: DimensionType; lctx: LayoutContext): Span = var span = Span() if input.border[dim].start notin BorderStyleNoneHidden: span.start = lctx.cellSize[dim] if input.border[dim].send notin BorderStyleNoneHidden and (dim == dtHorizontal or input.border[dim].send notin BorderStyleInput): span.send = lctx.cellSize[dim] return span proc borderSum(input: LayoutInput; dim: DimensionType; lctx: LayoutContext): LUnit = input.borderSize(dim, lctx).sum() proc borderTop(input: LayoutInput; lctx: LayoutContext): LUnit = if input.border[dtVertical].start notin BorderStyleNoneHidden: return lctx.cellSize[dtVertical] return 0'lu proc borderBottom(input: LayoutInput; lctx: LayoutContext): LUnit = if input.border[dtVertical].send notin BorderStyleNoneHidden: return lctx.cellSize[dtVertical] return 0'lu proc borderLeft(input: LayoutInput; lctx: LayoutContext): LUnit = if input.border[dtHorizontal].start notin BorderStyleNoneHidden: return lctx.cellSize[dtHorizontal] return 0'lu proc borderRight(input: LayoutInput; lctx: LayoutContext): LUnit = if input.border[dtHorizontal].send notin BorderStyleNoneHidden: return lctx.cellSize[dtHorizontal] return 0'lu proc outerSize(box: BlockBox; dim: DimensionType; input: LayoutInput; lctx: LayoutContext): LUnit = return input.margin[dim].sum() + box.state.size[dim] + input.borderSum(dim, lctx) proc outerSize(box: BlockBox; input: LayoutInput; lctx: LayoutContext): Size = return size( w = box.outerSize(dtHorizontal, input, lctx), h = box.outerSize(dtVertical, input, lctx) ) proc max(span: Span): LUnit = return max(span.start, span.send) # In CSS, "min" beats "max". proc minClamp(x: LUnit; span: Span): LUnit = return max(min(x, span.send), span.start) # Note: padding must still be applied after this. proc applySize(box: BlockBox; bounds: Bounds; maxChildSize: LUnit; space: Space; dim: DimensionType) = # Make the box as small/large as the content's width or specified width. box.state.size[dim] = maxChildSize.applySizeConstraint(space[dim]) # Then, clamp it to minWidth and maxWidth (if applicable). box.state.size[dim] = box.state.size[dim].minClamp(bounds.a[dim]) proc applySize(box: BlockBox; input: LayoutInput; maxChildSize: Size; space: Space) = for dim in DimensionType: box.applySize(input.bounds, maxChildSize[dim], space, dim) proc applyIntr(box: BlockBox; input: LayoutInput; intr: Size) = for dim in DimensionType: const pt = [dtHorizontal: cptOverflowX, dtVertical: cptOverflowY] if box.computed.bits[pt[dim]].overflow notin OverflowScrollLike: box.state.intr[dim] = intr[dim].minClamp(input.bounds.mi[dim]) else: # We do not have a scroll bar, so do the next best thing: expand the # box to the size its contents want. (Or the specified size, if # it's greater.) #TODO intrinsic minimum size isn't really guaranteed to equal the # desired scroll size. Also, it's possible that a parent box clamps # the height of this box; in that case, the parent box's # width/height should be clamped to the inner scroll width/height # instead. box.state.intr[dim] = max(intr[dim], input.bounds.mi[dim].start) box.state.size[dim] = max(box.state.size[dim], intr[dim]) # Size resolution for all layouts. const MarginStartMap = [ dtHorizontal: cptMarginLeft, dtVertical: cptMarginTop ] const MarginEndMap = [ dtHorizontal: cptMarginRight, dtVertical: cptMarginBottom ] proc spx(l: CSSLength; p: SizeConstraint; computed: CSSValues; padding: LUnit): LUnit = let u = l.px(p) if computed{"box-sizing"} == BoxSizingBorderBox: return max(u - padding, 0'lu) return max(u, 0'lu) proc resolveMargins(lctx: LayoutContext; availableWidth: SizeConstraint; computed: CSSValues): RelativeRect = # Note: we use availableWidth for percentage resolution intentionally. return [ dtHorizontal: Span( start: computed{"margin-left"}.px(availableWidth), send: computed{"margin-right"}.px(availableWidth), ), dtVertical: Span( start: computed{"margin-top"}.px(availableWidth), send: computed{"margin-bottom"}.px(availableWidth), ) ] proc resolvePadding(lctx: LayoutContext; availableWidth: SizeConstraint; computed: CSSValues): RelativeRect = # Note: we use availableWidth for percentage resolution intentionally. return [ dtHorizontal: Span( start: max(computed{"padding-left"}.px(availableWidth), 0'lu), send: max(computed{"padding-right"}.px(availableWidth), 0'lu) ), dtVertical: Span( start: max(computed{"padding-top"}.px(availableWidth), 0'lu), send: max(computed{"padding-bottom"}.px(availableWidth), 0'lu) ) ] proc roundSmallMarginsAndPadding(lctx: LayoutContext; input: var LayoutInput) = for i, it in input.padding.mpairs: let cs = lctx.cellSize[i] it.start = (it.start div cs).toInt.toLUnit * cs it.send = (it.send div cs).toInt.toLUnit * cs for i, it in input.margin.mpairs: let cs = lctx.cellSize[i] it.start = (it.start div cs).toInt.toLUnit * cs it.send = (it.send div cs).toInt.toLUnit * cs proc resolveBorder(lctx: LayoutContext; computed: CSSValues; margin: var RelativeRect): CSSBorder = const Map = [ dtHorizontal: { cptBorderLeftStyle: cptBorderLeftWidth, cptBorderRightStyle: cptBorderRightWidth }, dtVertical: { cptBorderTopStyle: cptBorderTopWidth, cptBorderBottomStyle: cptBorderBottomWidth } ] result = CSSBorder.default #TODO error correction should probably be done on padding first and margin # only as a last resort. (then maybe it becomes feasible to do box-sizing # right too somehow) for dim, it in Map: let cellSize = lctx.cellSize[dim] let styleStart = computed.getBorderStyle(it[0][0]) if styleStart != BorderStyleNone: let w = computed.getLineWidth(it[0][1]).toLUnit() if w != 0'lu: let e = w - cellSize if e < 0'lu and margin[dim].start >= -e or e > 0'lu: margin[dim].start += e # correct error result[dim].start = styleStart let styleEnd = computed.getBorderStyle(it[1][0]) if styleEnd != BorderStyleNone: let w = computed.getLineWidth(it[1][1]).toLUnit() if w != 0'lu: let e = w - cellSize if e < 0'lu and margin[dim].send >= -e or e > 0'lu: margin[dim].send += e # correct error result[dim].send = styleEnd proc resolvePositioned(lctx: LayoutContext; size: Size; computed: CSSValues): RelativeRect = # As per standard, vertical percentages refer to the *height*, not the width # (unlike with margin/padding) return [ dtHorizontal: Span( start: computed{"left"}.px(size.w), send: computed{"right"}.px(size.w) ), dtVertical: Span( start: computed{"top"}.px(size.h), send: computed{"bottom"}.px(size.h), ) ] const DefaultBounds = Bounds( a: [DefaultSpan, DefaultSpan], mi: [DefaultSpan, DefaultSpan] ) const SizeMap = [dtHorizontal: cptWidth, dtVertical: cptHeight] const MinSizeMap = [dtHorizontal: cptMinWidth, dtVertical: cptMinHeight] const MaxSizeMap = [dtHorizontal: cptMaxWidth, dtVertical: cptMaxHeight] proc resolveBounds(lctx: LayoutContext; space: Space; padding: Size; computed: CSSValues; replaced: bool; flexItem = false): Bounds = var res = DefaultBounds for dim in DimensionType: let sc = space[dim] let padding = padding[dim] let maxLength = computed.getLength(MaxSizeMap[dim]) if maxLength.canpx(sc): let px = maxLength.spx(sc, computed, padding) res.a[dim].send = px res.mi[dim].send = px elif replaced and maxLength.isPerc: # for replaced elements (img), cyclic percentage max size is resolved # against 0 when computing the intrinsic minimum size. res.mi[dim].send = maxLength.spx(stretch(0'lu), computed, padding) if computed.getLength(MinSizeMap[dim]).canpx(sc): let px = computed.getLength(MinSizeMap[dim]).spx(sc, computed, padding) res.a[dim].start = px if computed.getLength(MinSizeMap[dim]).isPx: res.mi[dim].start = px if flexItem: # for flex items, min-width overrides the intrinsic size. res.mi[dim].send = px return res proc resolveAbsoluteWidth(lctx: LayoutContext; size: Size; positioned: RelativeRect; computed: CSSValues; input: var LayoutInput) = let paddingSum = input.padding[dtHorizontal].sum() if computed{"width"}.auto: var u = max(size.w - positioned[dtHorizontal].sum() - paddingSum - input.margin[dtHorizontal].sum() - input.borderSum(dtHorizontal, lctx), 0'lu) u = minClamp(u, input.bounds.a[dtHorizontal]) if not computed{"left"}.auto and not computed{"right"}.auto: # Both left and right are known, so we can calculate the width. input.space.w = stretch(u) else: # Return shrink to fit and solve for left/right. input.space.w = fitContent(u) else: var u = computed{"width"}.spx(stretch(size.w), computed, paddingSum) u = minClamp(u, input.bounds.a[dtHorizontal]) input.space.w = stretch(u) proc resolveAbsoluteHeight(lctx: LayoutContext; size: Size; positioned: RelativeRect; computed: CSSValues; input: var LayoutInput) = let paddingSum = input.padding[dtVertical].sum() if computed{"height"}.auto: if not computed{"top"}.auto and not computed{"bottom"}.auto: # Both top and bottom are known, so we can calculate the height. # Well, but subtract padding and margin first. var u = max(size.h - positioned[dtVertical].sum() - paddingSum - input.margin[dtVertical].sum() - input.borderSum(dtVertical, lctx), 0'lu) u = minClamp(u, input.bounds.a[dtVertical]) input.space.h = stretch(u) else: # The height is based on the content. input.space.h = maxContent() else: var u = computed{"height"}.spx(stretch(size.h), computed, paddingSum) u = minClamp(u, input.bounds.a[dtVertical]) input.space.h = stretch(u) proc fillImageSize(bounds: BoundsPart; osize: Size): Size = if osize.w == 0'lu or osize.h == 0'lu: return osize let ww = osize.w.minClamp(bounds[dtHorizontal]) * osize.h let hh = osize.h.minClamp(bounds[dtVertical]) * osize.w let rat = if osize.w < bounds.minWidth: if osize.h < bounds.minHeight: max(ww, hh) else: ww elif osize.h < bounds.minHeight: hh elif osize.w > bounds.maxWidth: if osize.h > bounds.maxHeight: min(ww, hh) else: ww elif osize.h > bounds.maxHeight: hh else: osize.w * osize.h return size(w = rat div osize.h, h = rat div osize.w) proc resolveImageSizes(lctx: LayoutContext; input: LayoutInput; space: Space; paddingSum: Size; bmp: NetworkBitmap; computed: CSSValues; intrinsic = false): Size = let width = computed{"width"} let height = computed{"height"} let hasWidth = width.canpx(space.w) let hasHeight = height.canpx(space.h) let osize = size(w = bmp.width.toLUnit(), h = bmp.height.toLUnit()) var size = osize if hasWidth: size.w = width.spx(space.w, computed, paddingSum.w) elif intrinsic and width.isPerc: # For replaced elements, cyclic percentage intrinsic size is resolved # against 0. Note that this *does not* apply to the max-content size, # so we perform this calculation twice (see applyImageSizes). size.w = width.spx(stretch(0'lu), computed, paddingSum.w) if hasHeight: size.h = height.spx(space.h, computed, paddingSum.h) elif intrinsic and height.isPerc: # see above size.h = height.spx(stretch(0'lu), computed, paddingSum.h) if not hasWidth and hasHeight and osize.h > 0'lu: size.w = size.h * osize.w div osize.h elif hasWidth and not hasHeight and osize.w > 0'lu: size.h = size.w * osize.h div osize.w elif not hasWidth and not hasHeight and bmp.vector: # SVG has no intrinsic width. if space.w.isDefinite(): size.w = min(size.w, space.w.u) else: size.w = 0'lu # I guess? if osize.w > 0'lu: size.h = size.w * osize.h div osize.w if intrinsic: # intrinsic min size return input.bounds.mi.fillImageSize(size) return input.bounds.a.fillImageSize(size) proc applyImageSizes(lctx: LayoutContext; space: Space; paddingSum: Size; bmp: NetworkBitmap; computed: CSSValues; input: var LayoutInput) = let size = lctx.resolveImageSizes(input, space, paddingSum, bmp, computed) input.space = stretch(size) # Here we run into the problem that we are supposed to resolve intr in # layoutImage, but by that time we lose information of the parent size. # That is a problem because cyclic intrinsic minimum size (state.intr: # a percentage width with indefinite parent, e.g. in shrink-to-fit or # table cell measurement) is different from cyclic intrinsic preferred/ # maximum size (state.size). # # So our rather inelegant solution here is to resolve intr already, # and then just tuck it into input.bounds which layoutImage will clamp # the size to. I guess it would be cleaner if we had a different # LayoutInput variant for images (then we could just put intr right # there), but alas, we don't. let intr = lctx.resolveImageSizes(input, space, paddingSum, bmp, computed, intrinsic = true) + paddingSum for dim in DimensionType: let u = intr[dim] input.bounds.mi[dim] = Span(start: u, send: u) # Calculate and resolve available width & height for absolutely positioned # boxes. proc resolveAbsoluteSizes(lctx: LayoutContext; size: Size; positioned: RelativeRect; box: BlockBox): LayoutInput = let computed = box.computed let padding = lctx.resolvePadding(stretch(size.w), computed) let paddingSum = padding.sum() let space = stretch(size) let bmp = box.getImageBitmap() var input = LayoutInput( margin: lctx.resolveMargins(stretch(size.w), computed), padding: padding, bounds: lctx.resolveBounds(space, paddingSum, computed, bmp != nil) ) input.border = lctx.resolveBorder(computed, input.margin) if bmp != nil: lctx.applyImageSizes(space, paddingSum, bmp, computed, input) else: lctx.resolveAbsoluteWidth(size, positioned, computed, input) lctx.resolveAbsoluteHeight(size, positioned, computed, input) return input # Calculate and resolve available width & height for floating boxes. proc resolveFloatSizes(lctx: LayoutContext; space: Space; box: BlockBox): LayoutInput = let computed = box.computed var input = LayoutInput( margin: lctx.resolveMargins(space.w, computed), padding: lctx.resolvePadding(space.w, computed), space: space ) input.border = lctx.resolveBorder(computed, input.margin) if computed{"display"} in DisplayInlineBlockLike: lctx.roundSmallMarginsAndPadding(input) let paddingSum = input.padding.sum() let bmp = box.getImageBitmap() input.bounds = lctx.resolveBounds(space, paddingSum, computed, bmp != nil) input.space.h = maxContent() if bmp != nil: lctx.applyImageSizes(space, paddingSum, bmp, computed, input) else: for dim in DimensionType: let length = computed.getLength(SizeMap[dim]) if length.canpx(space[dim]): let u = length.spx(space[dim], computed, paddingSum[dim]) input.space[dim] = stretch(minClamp(u, input.bounds.a[dim])) elif input.space[dim].isDefinite(): let u = input.space[dim].u - input.margin[dim].sum() - paddingSum[dim] input.space[dim] = fitContent(minClamp(u, input.bounds.a[dim])) return input proc resolveFlexItemSizes(lctx: LayoutContext; space: Space; dim: DimensionType; box: BlockBox): LayoutInput = let computed = box.computed let padding = lctx.resolvePadding(space.w, computed) let paddingSum = padding.sum() var input = LayoutInput( margin: lctx.resolveMargins(space.w, computed), padding: padding, space: space, bounds: lctx.resolveBounds(space, paddingSum, computed, replaced = false, flexItem = true) ) input.border = lctx.resolveBorder(computed, input.margin) if dim != dtHorizontal: input.space.h = maxContent() let length = computed.getLength(SizeMap[dim]) if length.canpx(space[dim]): let u = length.spx(space[dim], computed, paddingSum[dim]) .minClamp(input.bounds.a[dim]) input.space[dim] = stretch(u) if computed{"flex-shrink"} == 0: input.bounds.mi[dim].start = max(u, input.bounds.mi[dim].start) if computed{"flex-grow"} == 0: input.bounds.mi[dim].send = min(u, input.bounds.mi[dim].send) elif space[dim].t == scStretch and input.bounds.a[dim].send < LUnit.high: input.space[dim] = stretch(input.bounds.a[dim].max()) else: # Ensure that space is indefinite in the first pass if no width has # been specified. input.space[dim] = maxContent() let odim = dim.opposite() let olength = computed.getLength(SizeMap[odim]) if olength.canpx(space[odim]): let u = olength.spx(space[odim], computed, paddingSum[odim]) .minClamp(input.bounds.a[odim]) input.space[odim] = stretch(u) if olength.isPx: input.bounds.mi[odim].start = max(u, input.bounds.mi[odim].start) input.bounds.mi[odim].send = min(u, input.bounds.mi[odim].send) elif input.space[odim].isDefinite(): let u = input.space[odim].u - input.margin[odim].sum() - paddingSum[odim] - input.borderSum(odim, lctx) input.space[odim] = SizeConstraint( t: input.space[odim].t, u: minClamp(u, input.bounds.a[odim]) ) if computed.getLength(MarginStartMap[odim]).auto or computed.getLength(MarginEndMap[odim]).auto: input.space[odim].t = scFitContent elif input.bounds.a[odim].send < LUnit.high: input.space[odim] = stretch(input.bounds.a[odim].max()) return input proc resolveBlockSpace(lctx: LayoutContext; input: var LayoutInput; dim: DimensionType; psc: SizeConstraint; paddingSum: LUnit; computed: CSSValues): SizeConstraint = var sc = case dim of dtHorizontal: psc of dtVertical: # height is max-content normally, but fit-content for clip. if computed{"overflow-y"} != OverflowClip: maxContent() else: fitContent(psc) let length = computed.getLength(SizeMap[dim]) if length.canpx(psc): #TODO parent height should be the nearest non-auto height in quirks mode # for percentage resolution. let px = length.spx(psc, computed, paddingSum) sc = stretch(px) if length.isPx: input.bounds.mi[dim].start = max(input.bounds.mi[dim].start, px) input.bounds.mi[dim].send = min(input.bounds.mi[dim].send, px) elif dim == dtHorizontal and psc.t == scStretch: let underflow = psc.u - input.margin[dim].sum() - paddingSum - input.borderSum(dim, lctx) sc = stretch(max(underflow, 0'lu)) let minu = input.bounds.a[dim].start let maxu = input.bounds.a[dim].send if sc.isDefinite() and maxu < sc.u or maxu < LUnit.high and sc.t in {scMaxContent, scMeasure}: if sc.t == scStretch: # available width would stretch over max-width sc = stretch(maxu) else: # scFitContent # available width could be higher than max-width (but not necessarily) sc = fitContent(maxu) input.bounds.mi[dim].send = sc.u if sc.isDefinite() and minu > sc.u or minu > 0'lu and sc.t == scMinContent: # two cases: # * available width is stretched under min-width, so stretch to # min-width instead. # * available width is fit under min-width, so stretch to min-width as # well (as we must satisfy min-width >= width). sc = stretch(minu) return sc proc resolveBlockSizes(lctx: LayoutContext; space: Space; box: BlockBox): LayoutInput = let computed = box.computed let padding = lctx.resolvePadding(space.w, computed) let paddingSum = padding.sum() let bmp = box.getImageBitmap() var input = LayoutInput( margin: lctx.resolveMargins(space.w, computed), padding: padding, space: space, bounds: lctx.resolveBounds(space, paddingSum, computed, bmp != nil), ) input.border = lctx.resolveBorder(computed, input.margin) if bmp != nil: lctx.applyImageSizes(space, paddingSum, bmp, computed, input) else: for dim in DimensionType: input.space[dim] = lctx.resolveBlockSpace(input, dim, space[dim], paddingSum[dim], computed) if computed{"display"} == DisplayListItem: # Eliminate distracting margins and padding here, because # resolveBlockWidth may change them beforehand. lctx.roundSmallMarginsAndPadding(input) if input.space.h.isDefinite() and input.space.h.u == 0'lu and paddingSum[dtVertical] == 0'lu and input.border.bottom notin BorderStyleInput: # prevent ugly <hr> when set using border (not just border-style-bottom) input.border[dtHorizontal] = BorderStyleSpan() if input.border[dtVertical].send notin BorderStyleNoneHidden: input.border[dtVertical].start = BorderStyleHidden return input # Flow layout. Probably the most complex part of CSS. # # One would be excused for thinking that flow can be subdivided into # "inline" and "block" layouts. This approach isn't exactly wrong - # indeed, it seems to be the most intuitive interpretation of CSS 2.1, # and is how I first did it - but mainstream browsers behave otherwise, # so it is more useful to recognize flow as a single layout type. # # Flow is rooted in any block box that establishes a Block Formatting # Context (BFC)[1]. State associated with these is passed over to (and read # from) children that do not establish a BFC. # Then, flow includes further child "boxes"[2] of the following types: # # * Inline. These may contain further inline boxes, text, images, # or block boxes (!). # * Block that does not establish a BFC. Contents of these flow around # floats in the same BFC, for example. # * Block that establishes a BFC. There are two kinds of these: # floats, which grow the exclusion zone, and flow roots (e.g. # overflow: hidden), which try to fit into the exclusion zone while # maintaining a rectangular shape. # * position: absolute. This does not really affect flow, but has some # bizarre rules regarding its positioning that makes it particularly # tricky to implement. # # [1]: For example, the root box, boxes with `overflow: hidden', floated # boxes or flex items all establish a new BFC. # # [2]: Thinking of these as "boxes" is somewhat misleading, since any # box that doesn't establish a new BFC may fragment (e.g. text with a # line break, or a block child.) # ## Anonymous block boxes # # Blocks nested in inlines are tricky. Consider this fragment: # <div id=a><span id=b>1<div id=c>2</div>3</span></div> # # One interpretation of this (this is how Chawan used to behave): # # * div#a # * anonymous block # * span#b (split) # * anonymous inline # * 1 # * div#c # * anonymous inline # * 2 # * anonymous block # * span#b (split) # * anonymous inline # * 3 # # This has several issues. For one, out-of-flow boxes (e.g. if div#c is # a float, or absolute) must still be placed inside the inline box. # Also, it isn't how mainstream browsers implement this[3], so you end # up chasing strange bugs that arise from this implementation detail # (go figure.) # # Therefore, Chawan now generates this tree: # # * div#a # * span#b # * anonymous inline # * 1 # * div#c # * anonymous inline # * 2 # * anonymous inline # * 3 # # and blocks that come after inlines simply flush the current line box. # # [3]: The spec itself does not even mention this case, but there is a # resolution that agrees with our new implementation: # https://github.com/w3c/csswg-drafts/issues/1477 # ## Floats # # Floats have three issues that make their implementation less than # straightforward: # # * They aren't constrained to their parent block, but their parent # BFC. So while they do not affect previously laid out blocks, they # do affect subsequent siblings of their parent/grandparent/etc. # (Solved by adding exclusions to a BFC, and offsetting blocks/inlines # by their relative position to the BFC when considering exclusions.) # # * They *do* affect previous inlines. e.g. this puts the float to # the left of "second": # <span>second<div style="float: left">first</div></span> # So floats must be processed before flushing a line box (solved using # pendingFloats in LineBoxState). # # * Consider this: # <div style="margin-top: 1em"> # <div style="float: left">float</div> # <div style="margin-top: 2em"></div> # </div> # The float moves to 2em from the top, not 1em! # This means that floats can only be positioned once their parent's margin # is known; until then, they live in the pendingFloats list. # ## Margin collapsing # # The algorithm looks something like: # * track BFC position for each (non-root) flow block # * look for the first child that resolves the margin (flushMargins) # * position floats in said child, pretending that the parent's y position # is already flushed # * once the child's layout is finished, move the ancestors' BFC position by # the margin the child has output (marginOutput) # * finally, as the first ancestor box is reached for which the margin is # unresolved but the margin of its parent isn't, move said ancestor by # marginOutput, and then set it to 0. # # It gets a bit messy when floats are involved: unpositioned floats on the # current line can just use the BFC position of the line's flow state, but # BFC-level unpositioned floats must be shifted inside flushMargins, making # sure that we don't leak state of an individual block box outside (i.e. # using the temporary yshift variable instead of updating bfcOffset itself.) type LineInitState = enum lisUninited, lisNoExclusions, lisExclusions LineBoxState = object atomsHead: InlineAtom atomsTail: InlineAtom nowrapHead: InlineAtom nowrapTail: InlineAtom charwidth: int paddingTodo: seq[tuple[box: InlineBox; i: int]] # absolutes that want to stick to the next atom pendingAbsolutes: seq[BlockBox] size: Size pendingFloatsHead: PendingFloat pendingFloatsTail: PendingFloat lastrw: int # last rune width of the previous word firstrw: int # first rune width of the current word prevrw: int # last processed rune's width whitespaceBox: InlineTextBox whitespaceNum: int # Set at the end of layoutText. It helps determine the beginning of the # next inline box. widthAfterWhitespace: LUnit availableWidth: LUnit # actual place available after float exclusions intrh: LUnit # intrinsic minimum height totalFloatWidth: LUnit baseline: LUnit nowrapWidth: LUnit # width of pending nowrap atoms # Line boxes start in an uninited state. When something is placed # on the line box, we call initLine to # * flush margins and position floats # * check the relevant exclusions and resize the line appropriately init: LineInitState # float values currently included in pendingFloats. floatsSeen: set[CSSFloat] whitespaceIsLF: bool WordState = object s: string ibox: InlineTextBox wrapPos: int # position of last wrapping opportunity, or -1 width: LUnit intrWidth: LUnit # intrinsic size of currently processed word segment hasSoftHyphen: bool InlineAtom = ref object ibox: InlineBox box: BlockBox run: TextRun offset: Offset size: Size absolutes: seq[BlockBox] iboxStack: seq[InlineBox] # track parent inlines to flush next: InlineAtom FlowState = object lctx: LayoutContext box: BlockBox bfcOffset: Offset offset: Offset maxChildWidth: LUnit totalFloatWidth: LUnit # used for re-layouts space: Space intr: Size marginResolved: bool textAlign: CSSTextAlign # text align of parent, for block-level alignment marginOutput: LUnit maxFloatHeight: LUnit clearOffset: LUnit marginTodo: Span pendingFloatsHead: PendingFloat pendingFloatsTail: PendingFloat exclusionsHead: Exclusion exclusionsTail: Exclusion # Inline context state: lbstate: LineBoxState iboxStack: seq[InlineBox] # Forward declarations proc layout(lctx: LayoutContext; box: BlockBox; offset: Offset; input: LayoutInput; forceRoot = false) iterator exclusions(fstate: FlowState): Exclusion {.inline.} = var ex = fstate.exclusionsHead while ex != nil: yield ex if ex == fstate.exclusionsTail: break ex = ex.next proc nowrap(computed: CSSValues): bool = computed{"white-space"} in {WhiteSpaceNowrap, WhiteSpacePre} template cellSize(fstate: FlowState): Size = fstate.lctx.cellSize template computed(fstate: FlowState): CSSValues = fstate.box.computed proc realAtomsTail(lbstate: LineBoxState): InlineAtom = if lbstate.nowrapTail != nil: return lbstate.nowrapTail return lbstate.atomsTail proc lastTextBox(fstate: FlowState): InlineBox = if fstate.lbstate.whitespaceBox != nil: return fstate.lbstate.whitespaceBox let tail = fstate.lbstate.realAtomsTail if tail != nil: return tail.ibox nil proc addMargin(a: var Span; b: LUnit) = if b < 0'lu: a.start = min(b, a.start) else: a.send = max(b, a.send) proc clearFloats(offsety: var LUnit; fstate: var FlowState; bfcOffsety: LUnit; clear: CSSClear; cleared: var bool) = let oy = bfcOffsety + offsety var y = oy let target = case clear of ClearLeft, ClearInlineStart: FloatLeft of ClearRight, ClearInlineEnd: FloatRight of ClearBoth, ClearNone: FloatNone var clearedTo = fstate.exclusionsHead for ex in fstate.exclusions: if ex.t == target or target == FloatNone: let iy = ex.offset.y + ex.size.h if iy > y: y = iy clearedTo = ex.next if clearedTo != fstate.exclusionsHead: cleared = y > max(fstate.clearOffset, oy) fstate.clearOffset = y if target == FloatNone: fstate.exclusionsHead = clearedTo offsety = y - bfcOffsety proc clearFloats(offsety: var LUnit; fstate: var FlowState; bfcOffsety: LUnit; clear: CSSClear) = var dummy: bool offsety.clearFloats(fstate, bfcOffsety, clear, dummy) proc findNextFloatOffset(fstate: FlowState; offset: Offset; size: Size; space: Space; float: CSSFloat; outw: var LUnit): Offset = # Algorithm originally from QEmacs. var y = offset.y let leftStart = offset.x let rightStart = offset.x + max(size.w, space.w.u) while true: var left = leftStart var right = rightStart var miny = high(LUnit) let cy2 = y + size.h for ex in fstate.exclusions: let ey2 = ex.offset.y + ex.size.h if cy2 >= ex.offset.y and y < ey2: let ex2 = ex.offset.x + ex.size.w if ex.t == FloatLeft and left < ex2: left = ex2 if ex.t == FloatRight and right > ex.offset.x: right = ex.offset.x miny = min(ey2, miny) let w = right - left if w >= size.w or miny == high(LUnit): # Enough space, or no other exclusions found at this y offset. outw = min(w, space.w.u) # do not overflow the container. if float == FloatLeft: return offset(x = left, y = y) else: # FloatRight return offset(x = right - size.w, y = y) # Move y to the bottom exclusion edge at the lowest y (where the exclusion # still intersects with the previous y). y = miny assert false Offset0 proc findNextFloatOffset(fstate: FlowState; offset: Offset; size: Size; space: Space; float: CSSFloat): Offset = var dummy: LUnit return fstate.findNextFloatOffset(offset, size, space, float, dummy) proc findNextBlockOffset(fstate: FlowState; offset: Offset; size: Size; outw: var LUnit): Offset = return fstate.findNextFloatOffset(offset, size, fstate.space, FloatLeft, outw) proc positionFloat(fstate: var FlowState; child: BlockBox; space: Space; outerSize: Size; marginOffset, bfcOffset, offset: Offset) = assert space.w.t != scFitContent var offset = offset offset.y += fstate.marginTodo.sum() let clear = child.computed{"clear"} if clear != ClearNone: offset.y.clearFloats(fstate, fstate.bfcOffset.y, clear) var childBfcOffset = bfcOffset + offset - marginOffset childBfcOffset.y = max(fstate.clearOffset, childBfcOffset.y) let ft = child.computed{"float"} assert ft != FloatNone offset = fstate.findNextFloatOffset(childBfcOffset, outerSize, space, ft) child.state.offset = offset - bfcOffset + marginOffset let ex = Exclusion(offset: offset, size: outerSize, t: ft) if fstate.exclusionsHead == nil: fstate.exclusionsHead = ex else: fstate.exclusionsTail.next = ex fstate.exclusionsTail = ex fstate.maxFloatHeight = max(fstate.maxFloatHeight, offset.y + outerSize.h) proc positionFloats(fstate: var FlowState; yshift = 0'lu) = var f = fstate.pendingFloatsHead while f != nil: var bfcOffset = f.bfcOffset bfcOffset.y += yshift fstate.positionFloat(f.box, f.space, f.outerSize, f.marginOffset, bfcOffset, f.offset) if f == fstate.pendingFloatsTail: break f = f.next fstate.pendingFloatsHead = nil fstate.pendingFloatsTail = nil proc flushMargins(fstate: var FlowState; offsety: var LUnit) = # Apply uncommitted margins. let margin = fstate.marginTodo.sum() var yshift = 0'lu if fstate.marginResolved: offsety += margin else: fstate.marginOutput = margin fstate.bfcOffset.y += margin yshift = margin fstate.marginResolved = true fstate.marginTodo = Span() fstate.positionFloats(yshift) # Prepare the next line's initial width and available width. # (If space on the left is excluded by floats, set the initial width to # the end of that space. If space on the right is excluded, set the # available width to that space.) type InitLineFlag = enum ilfRegular # set the line to inited, and flush floats. ilfFloat # set the line to inited, but do not flush floats. ilfAbsolute # set size, but allow further calls to override the state. proc initLine(fstate: var FlowState; flag = ilfRegular) = if flag == ilfRegular: let poffsety = fstate.offset.y fstate.flushMargins(fstate.offset.y) # Don't forget to add it to intrinsic height... fstate.intr.h += fstate.offset.y - poffsety if fstate.lbstate.init != lisUninited: return # we want to start from padding-left, but normally exclude padding # from space. so we must offset available width with padding-left too let paddingLeft = fstate.box.input.padding.left fstate.lbstate.availableWidth = fstate.space.w.u + paddingLeft fstate.lbstate.size.w = paddingLeft fstate.lbstate.init = lisNoExclusions #TODO what if maxContent/minContent? if fstate.exclusionsTail != nil: let bfcOffset = fstate.bfcOffset let y = fstate.offset.y + bfcOffset.y var left = bfcOffset.x + fstate.lbstate.size.w var right = bfcOffset.x + fstate.lbstate.availableWidth for ex in fstate.exclusions: if ex.offset.y <= y and y < ex.offset.y + ex.size.h: fstate.lbstate.init = lisExclusions if ex.t == FloatLeft: left = ex.offset.x + ex.size.w else: right = ex.offset.x fstate.lbstate.size.w = max(left - bfcOffset.x, fstate.lbstate.size.w) fstate.lbstate.availableWidth = min(right - bfcOffset.x, fstate.lbstate.availableWidth) if flag == ilfAbsolute: fstate.lbstate.init = lisUninited # Whitespace between words proc computeShift(lbstate: LineBoxState; ibox: InlineBox): int = if lbstate.whitespaceNum == 0: return 0 if lbstate.whitespaceIsLF and lbstate.lastrw == 2 and lbstate.firstrw == 2: # skip line feed between double-width characters return 0 if ibox.computed{"white-space"} notin WhiteSpacePreserve: let tail = lbstate.realAtomsTail if tail == nil: return 0 let ibox = tail.ibox if ibox of InlineTextBox: let ibox = InlineTextBox(ibox) if ibox.runs.len > 0 and ibox.runs[^1].s[^1] == ' ': return 0 return lbstate.whitespaceNum proc initWord(fstate: var FlowState; ibox: InlineTextBox): WordState = WordState(ibox: ibox, wrapPos: -1) #TODO start & justify would be nice to have const TextAlignNone = { TextAlignStart, TextAlignLeft, TextAlignChaLeft, TextAlignJustify } proc baseline(atom: InlineAtom; lctx: LayoutContext): LUnit = let box = atom.box if box != nil: let baseline = if box.state.baselineSet: box.state.baseline else: box.state.size.h return baseline + box.input.margin.top + box.input.borderTop(lctx) return atom.size.h proc vertalign(atom: InlineAtom): CSSVerticalAlign = if atom.box != nil: return atom.box.computed{"vertical-align"} atom.ibox.computed{"vertical-align"} proc positionAtom(lbstate: LineBoxState; atom: InlineAtom; lctx: LayoutContext) = case atom.vertalign of VerticalAlignBaseline: # Atom is placed at (line baseline) - (atom baseline) - len atom.offset.y = lbstate.baseline - atom.offset.y of VerticalAlignMiddle: # Atom is placed at (line baseline) - ((atom height) / 2) atom.offset.y = lbstate.baseline - atom.size.h div 2'lu of VerticalAlignTop: # Atom is placed at the top of the line. atom.offset.y = 0'lu of VerticalAlignBottom: # Atom is placed at the bottom of the line. atom.offset.y = lbstate.size.h - atom.size.h else: # See baseline (with len = 0). atom.offset.y = lbstate.baseline - atom.baseline(lctx) proc getLineWidth(fstate: FlowState): LUnit = return case fstate.space.w.t of scMinContent, scMaxContent, scMeasure: fstate.maxChildWidth of scFitContent: fstate.space.w.u of scStretch: max(fstate.maxChildWidth, fstate.space.w.u) proc getLineXShift(fstate: FlowState): LUnit = let width = fstate.getLineWidth() return case fstate.computed{"text-align"} of TextAlignNone: LUnit(0) of TextAlignEnd, TextAlignRight, TextAlignChaRight: let width = min(width, fstate.lbstate.availableWidth) max(width, fstate.lbstate.size.w) - fstate.lbstate.size.w of TextAlignCenter, TextAlignChaCenter: let w = min(width, fstate.lbstate.availableWidth) max(max(w, fstate.lbstate.size.w) div 2'lu - fstate.lbstate.size.w div 2'lu, 0'lu) # Calculate the position of atoms and background areas inside the # line. proc alignLine(fstate: var FlowState) = let xshift = fstate.getLineXShift() var totalWidth = 0'lu var currentAreaOffsetX = 0'lu var currentBox: InlineBox = nil let areaY = fstate.offset.y + fstate.lbstate.baseline - fstate.cellSize.h var minHeight = fstate.cellSize.h for (box, i) in fstate.lbstate.paddingTodo: box.state.areas[i].offset.x += xshift box.state.areas[i].offset.y = areaY var atom = fstate.lbstate.atomsHead # only align until the first atom affected by nowrap var lastAtom: InlineAtom = nil while atom != nil: fstate.lbstate.positionAtom(atom, fstate.lctx) atom.offset.y += fstate.offset.y minHeight = max(minHeight, atom.offset.y - fstate.offset.y + atom.size.h) # now position on the inline axis atom.offset.x += xshift # absolutes track the atom, except if they have a position themselves for absolute in atom.absolutes: if absolute.computed{"left"}.auto and absolute.computed{"right"}.auto: absolute.input.bfcOffset.x = atom.offset.x absolute.state.offset.x = atom.offset.x if absolute.computed{"top"}.auto and absolute.computed{"bottom"}.auto: absolute.input.bfcOffset.y = atom.offset.y absolute.state.offset.y = atom.offset.y totalWidth += atom.size.w let box = atom.ibox if currentBox != box: if currentBox != nil: # flush area let w = lastAtom.offset.x + lastAtom.size.w - currentAreaOffsetX if w != 0'lu: currentBox.state.areas.add(Area( offset: offset(x = currentAreaOffsetX, y = areaY), size: size(w = w, h = fstate.cellSize.h) )) # init new box currentBox = box currentAreaOffsetX = atom.offset.x for ibox in atom.iboxStack.ritems: ibox.state.startOffset = atom.offset if atom.ibox of InlineTextBox: atom.run.offset = atom.offset elif atom.box != nil: # Add the offset to avoid destroying margins (etc.) of the block. atom.box.state.offset += atom.offset else: assert false lastAtom = atom atom = atom.next if currentBox != nil: # flush area let atom = fstate.lbstate.atomsTail let w = atom.offset.x + atom.size.w - currentAreaOffsetX let offset = offset(x = currentAreaOffsetX, y = areaY) template lastArea: Area = currentBox.state.areas[^1] if currentBox.state.areas.len > 0 and lastArea.offset.x == offset.x and lastArea.size.w == w and lastArea.offset.y + lastArea.size.h == offset.y: # merge contiguous areas lastArea.size.h += fstate.cellSize.h else: currentBox.state.areas.add(Area( offset: offset, size: size(w = w, h = fstate.cellSize.h) )) if fstate.space.w.t == scFitContent: fstate.maxChildWidth = max(totalWidth, fstate.maxChildWidth) # Ensure that the line is exactly as high as its highest atom demands, # rounded up to the next line. fstate.lbstate.size.h = minHeight.ceilTo(fstate.cellSize.h.toInt()) proc getBaseline(atom: InlineAtom; lctx: LayoutContext): LUnit = return case atom.vertalign of VerticalAlignLength: let length = atom.ibox.computed{"-cha-vertical-align-length"} atom.baseline(lctx) + length.px(lctx.cellSize.h) of VerticalAlignTop: 0'lu of VerticalAlignMiddle: atom.size.h div 2'lu of VerticalAlignBottom: atom.size.h else: atom.baseline(lctx) proc putAtom2(fstate: var FlowState; atom: InlineAtom; takeAbsolutes: bool) = if takeAbsolutes: atom.absolutes = move(fstate.lbstate.pendingAbsolutes) atom.offset = offset( x = fstate.lbstate.size.w, y = atom.getBaseline(fstate.lctx) ) atom.iboxStack = move(fstate.iboxStack) fstate.lbstate.size.w += atom.size.w fstate.lbstate.baseline = max(fstate.lbstate.baseline, atom.offset.y) # In all cases, the line's height must at least equal the atom's height. fstate.lbstate.size.h = max(fstate.lbstate.size.h, atom.size.h) proc flushNowrap(fstate: var FlowState) = if fstate.lbstate.nowrapHead == nil: return if fstate.lbstate.atomsTail == nil: fstate.lbstate.atomsHead = fstate.lbstate.nowrapHead else: fstate.lbstate.atomsTail.next = fstate.lbstate.nowrapHead fstate.lbstate.atomsTail = fstate.lbstate.nowrapTail var atom = fstate.lbstate.nowrapHead while atom != nil: fstate.putAtom2(atom, takeAbsolutes = false) atom = atom.next fstate.lbstate.nowrapHead = nil fstate.lbstate.nowrapTail = nil fstate.intr.w = max(fstate.intr.w, fstate.lbstate.nowrapWidth) fstate.lbstate.nowrapWidth = 0'lu proc putAtom(fstate: var FlowState; atom: InlineAtom; takeAbsolutes = true) = if atom.ibox.computed.nowrap: fstate.lbstate.nowrapWidth += atom.size.w if fstate.lbstate.nowrapTail == nil: fstate.lbstate.nowrapHead = atom else: fstate.lbstate.nowrapTail.next = atom fstate.lbstate.nowrapTail = atom else: fstate.flushNowrap() fstate.putAtom2(atom, takeAbsolutes) if fstate.lbstate.atomsTail == nil: fstate.lbstate.atomsHead = atom else: fstate.lbstate.atomsTail.next = atom fstate.lbstate.atomsTail = atom proc mergeSpace(fstate: var FlowState; ibox: InlineTextBox): InlineAtom = if ibox.runs.len > 0: let tail = fstate.lbstate.realAtomsTail if tail != nil and tail.run == ibox.runs[^1]: return tail let cellHeight = fstate.cellSize.h let run = TextRun() ibox.runs.add(run) let atom = InlineAtom( ibox: ibox, size: size(w = 0'lu, h = cellHeight), run: run ) fstate.putAtom(atom, takeAbsolutes = false) return atom proc addSpacing(fstate: var FlowState; ibox: InlineTextBox; shift: int; hang = false) = let atom = fstate.mergeSpace(ibox) let run = atom.run for i in 0 ..< shift: run.s &= ' ' let w = shift.toLUnit() * fstate.cellSize.w if not hang: # In some cases, whitespace may "hang" at the end of the line. This means # it is written, but is not actually counted in the box's width. atom.size.w += w if atom == fstate.lbstate.atomsTail: fstate.lbstate.size.w += w else: fstate.lbstate.nowrapWidth += w proc flushWhitespace(fstate: var FlowState; ibox: InlineBox; hang = false) = let shift = fstate.lbstate.computeShift(ibox) fstate.lbstate.charwidth += fstate.lbstate.whitespaceNum fstate.lbstate.whitespaceNum = 0 let wbox = move(fstate.lbstate.whitespaceBox) if shift > 0: fstate.initLine() fstate.addSpacing(wbox, shift, hang) proc initLineBoxState(fstate: var FlowState): LineBoxState = let cellHeight = fstate.cellSize.h # move over pendingAbsolutes # (I guess this means it doesn't quite belong in lbstate, but FlowState is # also way too overloaded so it still seems preferable) var pendingAbsolutes = move(fstate.lbstate.pendingAbsolutes) result = LineBoxState( intrh: cellHeight, baseline: cellHeight, size: size(w = 0'lu, h = cellHeight), pendingAbsolutes: move(pendingAbsolutes) ) proc finishLine(fstate: var FlowState; ibox: InlineBox; wrap: bool; force = false; clear = ClearNone) = if fstate.lbstate.realAtomsTail != nil or force or fstate.lbstate.whitespaceNum != 0 and ibox != nil and ibox.computed{"white-space"} in {WhiteSpacePre, WhiteSpacePreWrap}: fstate.initLine() let whitespace = ibox.computed{"white-space"} case whitespace of WhiteSpacePre: fstate.flushWhitespace(ibox) of WhiteSpacePreWrap: fstate.flushWhitespace(ibox, hang = true) else: # Note: per standard, we really should always flush with hang except # on pre, but a) w3m doesn't, b) I find hang annoying, so we don't. # (I'm leaving the hang code in so it's easy to add if I ever change # my mind (or add a graphical mode.)) fstate.lbstate.whitespaceNum = 0 fstate.flushNowrap() fstate.iboxStack.setLen(0) # align atoms + calculate width for fit-content + place fstate.alignLine() var f = fstate.lbstate.pendingFloatsHead while f != nil: if whitespace != WhiteSpacePre and f.newLine: f.offset.y += fstate.lbstate.size.h fstate.positionFloat(f.box, f.space, f.outerSize, f.marginOffset, fstate.bfcOffset, f.offset) f = f.next # add line to fstate let y = fstate.offset.y if clear != ClearNone: fstate.lbstate.size.h.clearFloats(fstate, fstate.bfcOffset.y + y, clear) # * set first baseline if this is the first line box # * always set last baseline (so the baseline of the last line box remains) fstate.box.state.baseline = y + fstate.lbstate.baseline if not fstate.box.state.baselineSet: fstate.box.state.firstBaseline = y + fstate.lbstate.baseline fstate.box.state.baselineSet = true fstate.offset.y += fstate.lbstate.size.h fstate.intr.h += fstate.lbstate.intrh let lineWidth = if wrap: fstate.lbstate.availableWidth else: fstate.lbstate.size.w # padding-left is added to the line to aid float exclusion; undo # this here to prevent double-padding later fstate.maxChildWidth = max(fstate.maxChildWidth, lineWidth - fstate.box.input.padding.left) else: # Two cases exist: # a) The float cannot be positioned, because `fstate.box' has not # resolved its y offset yet. (e.g. if float comes before the # first child, we do not know yet if said child will move our y # offset with a margin-top value larger than ours.) # In this case we put it in pendingFloats, and defer positioning # until our y offset is resolved. # b) `box' has resolved its y offset, so the float can already be # positioned. if fstate.marginResolved: # y offset resolved var f = fstate.lbstate.pendingFloatsHead while f != nil: fstate.positionFloat(f.box, f.space, f.outerSize, f.marginOffset, fstate.bfcOffset, f.offset) f = f.next elif fstate.lbstate.pendingFloatsHead != nil: if fstate.pendingFloatsHead != nil: fstate.pendingFloatsTail.next = fstate.lbstate.pendingFloatsHead else: fstate.pendingFloatsHead = fstate.lbstate.pendingFloatsHead fstate.pendingFloatsTail = fstate.lbstate.pendingFloatsTail # Reinit in both cases. fstate.totalFloatWidth = max(fstate.totalFloatWidth, fstate.lbstate.totalFloatWidth) fstate.lbstate = fstate.initLineBoxState() proc shouldWrap0(lbstate: LineBoxState; w: LUnit): bool = return lbstate.size.w + lbstate.nowrapWidth + w > lbstate.availableWidth proc shouldWrap(fstate: FlowState; w: LUnit): bool = if fstate.space.w.t in {scMaxContent, scMeasure}: return false # no wrap with max-content if fstate.space.w.t == scMinContent: return true # always wrap with min-content return fstate.lbstate.shouldWrap0(w) proc shouldWrap2(fstate: FlowState; w: LUnit): bool = assert fstate.lbstate.init != lisUninited if fstate.lbstate.init == lisNoExclusions: return false return fstate.lbstate.shouldWrap0(w) # Wrap assuming the next atom is "width" wide and associated with "ibox". # Returns true if wrapped (i.e. on newline). proc prepareSpace(fstate: var FlowState; ibox: InlineBox; width: LUnit): bool = fstate.initLine() var wrapped = false var shift = fstate.lbstate.computeShift(ibox) fstate.lbstate.charwidth += fstate.lbstate.whitespaceNum fstate.lbstate.whitespaceNum = 0 let wbox = move(fstate.lbstate.whitespaceBox) let widthSum = width + shift.toLUnit() * fstate.cellSize.w let nowrapHead = fstate.lbstate.nowrapHead if ibox.computed.nowrap and fstate.lbstate.atomsHead != nil and fstate.shouldWrap(widthSum): # flush nowrap fstate.lbstate.nowrapHead = nil let nowrapTail = move(fstate.lbstate.nowrapTail) let nowrapWidth = fstate.lbstate.nowrapWidth fstate.finishLine(ibox, wrap = true) fstate.initLine() if nowrapTail == nil: # new line introduced by this atom; recompute the shift. shift = fstate.lbstate.computeShift(ibox) fstate.lbstate.nowrapHead = nowrapHead fstate.lbstate.nowrapTail = nowrapTail fstate.lbstate.nowrapWidth = nowrapWidth # Line wrapping if not ibox.computed.nowrap and fstate.shouldWrap(widthSum): fstate.finishLine(ibox, wrap = true) fstate.initLine() wrapped = true # Recompute on newline shift = fstate.lbstate.computeShift(ibox) # For floats: flush lines until we can place the atom. #TODO this is inefficient while fstate.shouldWrap2(width + shift.toLUnit() * fstate.cellSize.w): fstate.finishLine(ibox, wrap = false, force = true) fstate.initLine() # Recompute on newline shift = fstate.lbstate.computeShift(ibox) if shift > 0: fstate.addSpacing(wbox, shift) wrapped proc flushIntrSize(fstate: var FlowState; word: var WordState) = fstate.intr.w = max(fstate.intr.w, word.intrWidth) word.intrWidth = 0'lu # Returns true if wrapped. proc addWord(fstate: var FlowState; word: var WordState): bool = if word.s == "" or word.width == 0'lu: return false word.s.mnormalize() #TODO this may break on EOL. if word.s == "": return false fstate.flushIntrSize(word) let ibox = word.ibox let wrapped = fstate.prepareSpace(ibox, word.width) let tail = fstate.lbstate.realAtomsTail if tail != nil and ibox.runs.len > 0 and tail.run == ibox.runs[^1]: tail.run.s &= word.s tail.size.w += word.width if tail == fstate.lbstate.atomsTail: fstate.lbstate.size.w += word.width else: fstate.lbstate.nowrapWidth += word.width else: let size = size(w = word.width, h = fstate.cellSize.h) let run = TextRun(s: move(word.s)) ibox.runs.add(run) fstate.putAtom(InlineAtom(ibox: ibox, run: run, size: size)) word = fstate.initWord(ibox) return wrapped proc addWordEOL(fstate: var FlowState; word: var WordState): bool = if word.s == "": return false let wrapPos = word.wrapPos if wrapPos != -1: var leftstr = word.s.substr(wrapPos) word.s.setLen(wrapPos) if word.hasSoftHyphen: const shy = "\u00AD" # soft hyphen word.s &= shy word.hasSoftHyphen = false let wrapped = fstate.addWord(word) word.width = leftstr.width().toLUnit() * fstate.cellSize.w word.s = move(leftstr) return wrapped return fstate.addWord(word) proc checkWrap(fstate: var FlowState; word: var WordState; u: uint32; uw: int) = let ibox = word.ibox if ibox.computed.nowrap: return fstate.initLine() let shiftw = fstate.lbstate.computeShift(ibox).toLUnit() * fstate.cellSize.w fstate.lbstate.prevrw = uw if word.s.len == 0: fstate.lbstate.firstrw = uw let luw = uw.toLUnit() case ibox.computed{"word-break"} of WordBreakNormal: if uw == 2: # remove wrap opportunity, so we wrap properly on the last CJK char # (instead of any dash inside CJK sentences) word.wrapPos = -1 fstate.flushIntrSize(word) if uw == 2 or word.wrapPos != -1: # break on cjk and wrap opportunities let plusWidth = word.width + shiftw + luw * fstate.cellSize.w if fstate.shouldWrap(plusWidth): if not fstate.addWordEOL(word): # no line wrapping occurred in addWord fstate.finishLine(ibox, wrap = true) of WordBreakBreakAll: word.wrapPos = -1 fstate.flushIntrSize(word) let plusWidth = word.width + shiftw + luw * fstate.cellSize.w if fstate.shouldWrap(plusWidth): if not fstate.addWordEOL(word): # no line wrapping occurred in addWord fstate.finishLine(ibox, wrap = true) of WordBreakKeepAll: let plusWidth = word.width + shiftw + luw * fstate.cellSize.w if fstate.shouldWrap(plusWidth): fstate.finishLine(ibox, wrap = true) proc processWhitespace(fstate: var FlowState; word: var WordState; c: char) = let ibox = word.ibox discard fstate.addWord(word) case ibox.computed{"white-space"} of WhiteSpaceNormal, WhiteSpaceNowrap: if fstate.lbstate.whitespaceNum < 1 and fstate.lbstate.realAtomsTail != nil: fstate.lbstate.whitespaceNum = 1 fstate.lbstate.whitespaceBox = ibox fstate.lbstate.whitespaceIsLF = c == '\n' if c != '\n': fstate.lbstate.whitespaceIsLF = false of WhiteSpacePreLine: if c == '\n': fstate.finishLine(ibox, wrap = false, force = true) elif fstate.lbstate.whitespaceNum < 1 and fstate.lbstate.realAtomsTail != nil: fstate.lbstate.whitespaceIsLF = false fstate.lbstate.whitespaceNum = 1 fstate.lbstate.whitespaceBox = ibox of WhiteSpacePre, WhiteSpacePreWrap: fstate.lbstate.whitespaceIsLF = false if c == '\n': fstate.finishLine(ibox, wrap = false, force = true) elif c == '\t': let realWidth = fstate.lbstate.charwidth + fstate.lbstate.whitespaceNum # We must flush first, because addWord would otherwise try to wrap the # line. (I think.) fstate.flushWhitespace(ibox) let w = ((realWidth + 8) and not 7) - realWidth word.s.addUTF8(tabPUAPoint(w)) word.width += w.toLUnit() * fstate.cellSize.w fstate.lbstate.charwidth += w # Ditto here - we don't want the tab stop to get merged into the next # word. discard fstate.addWord(word) else: inc fstate.lbstate.whitespaceNum fstate.lbstate.whitespaceBox = ibox # set the "last word's last rune width" to the previous rune width fstate.lbstate.lastrw = fstate.lbstate.prevrw proc addWrapPos(fstate: var FlowState; word: var WordState) = # largest gap between wrapping opportunities is the intrinsic minimum # width fstate.flushIntrSize(word) word.wrapPos = word.s.len proc layoutTextLoop(fstate: var FlowState; ibox: InlineTextBox; s: string) = var word = fstate.initWord(ibox) let luctx = fstate.lctx.luctx var i = 0 while i < s.len: let pi = i var u = s.nextUTF8(i) if u < 0x80: let c = char(u) if c in AsciiWhitespace: fstate.processWhitespace(word, c) else: let w = u.width() fstate.checkWrap(word, u, w) word.s &= c let cw = w.toLUnit() * fstate.cellSize.w word.width += cw word.intrWidth += cw fstate.lbstate.charwidth += w if c == '-': # ascii dash fstate.addWrapPos(word) word.hasSoftHyphen = false # override soft hyphen elif luctx.isEnclosingMark(u) or luctx.isNonspacingMark(u) or luctx.isFormat(u): continue elif u == 0xAD: # soft hyphen fstate.addWrapPos(word) word.hasSoftHyphen = true continue else: if u in TabPUARange: # filter out chars placed in our PUA range u = 0xFFFD let w = u.width() fstate.checkWrap(word, u, w) for j in pi ..< i: word.s &= s[j] let cw = w.toLUnit() * fstate.cellSize.w word.width += cw word.intrWidth += cw fstate.lbstate.charwidth += w discard fstate.addWord(word) let shiftw = fstate.lbstate.computeShift(ibox).toLUnit() * fstate.cellSize.w #TODO not sure if this works with nowrap... fstate.lbstate.widthAfterWhitespace = fstate.lbstate.size.w + shiftw proc layoutText(fstate: var FlowState; ibox: InlineTextBox; s: string) = let transform = ibox.computed{"text-transform"} if transform == TextTransformNone: fstate.layoutTextLoop(ibox, s) else: let s = case transform of TextTransformCapitalize: s.capitalizeLU() of TextTransformUppercase: s.toUpperLU() of TextTransformLowercase: s.toLowerLU() of TextTransformFullWidth: s.fullwidth() of TextTransformFullSizeKana: s.fullsize() of TextTransformChaHalfWidth: s.halfwidth() else: "" fstate.layoutTextLoop(ibox, s) # size is the parent's size. proc popPositioned(lctx: LayoutContext; head: CSSAbsolute; size: Size) = var it = head while it != nil: let child = it.box var size = size #TODO this is very ugly. # I'm subtracting the X offset because it's normally equivalent to # the float-induced offset. But this isn't always true, e.g. it # definitely isn't in flex layout. var offset = child.input.bfcOffset size.w -= offset.x let positioned = lctx.resolvePositioned(size, child.computed) var input = lctx.resolveAbsoluteSizes(size, positioned, child) input.bfcOffset = offset offset.x += input.margin.left lctx.layout(child, offset, input) if not child.computed{"left"}.auto: child.state.offset.x = positioned.left + input.margin.left + input.borderLeft(lctx) elif not child.computed{"right"}.auto: child.state.offset.x = size.w - positioned.right - child.state.size.w - input.margin.right + input.borderRight(lctx) # margin.left is added in layout if not child.computed{"top"}.auto: child.state.offset.y = positioned.top + input.margin.top + input.borderTop(lctx) elif not child.computed{"bottom"}.auto: child.state.offset.y = size.h - positioned.bottom - child.state.size.h - input.margin.bottom + input.borderBottom(lctx) else: child.state.offset.y += input.margin.top it = it.next proc positionRelative(lctx: LayoutContext; space: Space; box: BlockBox) = # Interestingly, relative percentages don't actually work when the # parent's height is auto. if box.computed{"left"}.canpx(space.w): box.state.offset.x += box.computed{"left"}.px(space.w) elif box.computed{"right"}.canpx(space.w): box.state.offset.x -= box.computed{"right"}.px(space.w) if box.computed{"top"}.canpx(space.h): box.state.offset.y += box.computed{"top"}.px(space.h) elif box.computed{"bottom"}.canpx(space.h): box.state.offset.y -= box.computed{"bottom"}.px(space.h) proc clearedBy(floats: set[CSSFloat]; clear: CSSClear): bool = return case clear of ClearNone: false of ClearBoth: floats != {} of ClearInlineStart, ClearLeft: FloatLeft in floats of ClearInlineEnd, ClearRight: FloatRight in floats proc layoutFloat(fstate: var FlowState; child: BlockBox) = let lctx = fstate.lctx let input = lctx.resolveFloatSizes(fstate.space, child) lctx.layout(child, fstate.offset + input.margin.topLeft, input) let outerSize = child.outerSize(input, lctx) if fstate.space.w.t == scMeasure: # Float position depends on the available width, but in this case # the parent width is not known. Skip this box; we will position # it in the next pass. # # Since we emulate max-content here, the float will not contribute # to maxChildWidth in this iteration; instead, its outer width # will be summed up in totalFloatWidth and added to maxChildWidth # in initReLayout. fstate.lbstate.totalFloatWidth += outerSize.w else: assert fstate.space.w.t == scStretch fstate.maxChildWidth = max(fstate.maxChildWidth, outerSize.w) fstate.initLine(flag = ilfFloat) var newLine = true let float = child.computed{"float"} if not fstate.lbstate.floatsSeen.clearedBy(child.computed{"clear"}) and not fstate.lbstate.shouldWrap0(outerSize.w) and (fstate.lbstate.pendingFloatsTail == nil or not fstate.lbstate.pendingFloatsTail.newLine): # We can still cram floats into the line. if float == FloatLeft: fstate.lbstate.size.w += outerSize.w var atom = fstate.lbstate.atomsHead while atom != nil: atom.offset.x += outerSize.w atom = atom.next else: fstate.lbstate.availableWidth -= outerSize.w fstate.lbstate.floatsSeen.incl(float) newLine = false let f = PendingFloat( space: fstate.space, offset: child.state.offset, bfcOffset: fstate.bfcOffset, box: child, marginOffset: input.margin.startOffset() + input.borderTopLeft(lctx), outerSize: outerSize, newLine: newLine ) if fstate.lbstate.pendingFloatsHead != nil: fstate.lbstate.pendingFloatsTail.next = f else: fstate.lbstate.pendingFloatsHead = f fstate.lbstate.pendingFloatsTail = f fstate.intr.w = max(fstate.intr.w, child.state.intr.w) proc resolveAutoMarginStart(lctx: LayoutContext; input: LayoutInput; parentSpace: LUnit; child: BlockBox; dim: DimensionType): LUnit = let start = child.computed.getLength(MarginStartMap[dim]) # need to subtract margin end too to get the true outer size let underflow = parentSpace - child.state.size[dim] - input.margin[dim].send - input.borderSum(dim, lctx) - child.state.offset[dim] if underflow > 0'lu and start.auto: let send = child.computed.getLength(MarginEndMap[dim]) if not send.auto: return underflow else: return underflow div 2'lu return 0'lu # Outer layout for block-level children. proc layoutBlockChild(fstate: var FlowState; child: BlockBox) = fstate.finishLine(fstate.lastTextBox, wrap = false) let lctx = fstate.lctx var input = lctx.resolveBlockSizes(fstate.space, child) var space = fstate.space # may be modified if child is a BFC var offset = fstate.offset offset.x += input.margin.left let clear = child.computed{"clear"} var cleared = false if clear != ClearNone: let target = case clear of ClearLeft, ClearInlineStart: FloatLeft of ClearRight, ClearInlineEnd: FloatRight of ClearBoth, ClearNone: FloatNone var f = fstate.pendingFloatsHead while f != nil: if target == FloatNone or f.box.computed{"float"} == target: fstate.flushMargins(offset.y) break f = f.next offset.y.clearFloats(fstate, fstate.bfcOffset.y, clear, cleared) fstate.marginTodo.addMargin(input.margin.top) if cleared: # subtract the current state of our collapsed margin so that the top # edge of this box touches the bottom edge of the last cleared float # (margin must be collapsed with subsequent boxes as usual, so we # can't just skip addMargin) offset.y -= fstate.marginTodo.sum() const DisplayWithBFC = { DisplayFlowRoot, DisplayTable, DisplayFlex, DisplayGrid, DisplayImageBlock, DisplayImageInline } if child.computed{"display"} in DisplayWithBFC or child.computed{"overflow-x"} notin {OverflowVisible, OverflowClip}: # This box establishes a new BFC. input.marginResolved = fstate.marginResolved fstate.flushMargins(offset.y) lctx.layout(child, offset, input) if fstate.exclusionsTail != nil: # From the standard (abridged): # # > The border box of an element that establishes a new BFC must # > not overlap the margin box of any floats in the same BFC. If # > necessary, implementations should clear the said element, but # > may place it adjacent to such floats if there is sufficient # > space. CSS2 does not define when a UA may put said element # > next to the float. # # ...thanks for nothing. So here's what we do: # # * run a normal pass # * place the longest word (i.e. intr.w) somewhere # * run another pass with the placement we got # #TODO other browsers just try again until they find enough available # space; we should do that too once we have proper layout caching. # # Note that this does not apply to absolutely positioned elements, # as those ignore floats. let pbfcOffset = fstate.bfcOffset let bfcOffset = offset( x = pbfcOffset.x + child.state.offset.x, y = max(pbfcOffset.y + child.state.offset.y, fstate.clearOffset) ) let minSize = size(w = child.state.intr.w, h = lctx.cellSize.h) var outw: LUnit let offset = fstate.findNextBlockOffset(bfcOffset, minSize, outw) let roffset = offset - pbfcOffset # skip relayout if we can if outw != fstate.space.w.u or roffset != child.state.offset: space = initSpace(w = stretch(outw), h = fstate.space.h) input = lctx.resolveBlockSizes(space, child) lctx.layout(child, roffset, input) else: offset += input.borderTopLeft(lctx) input.bfcOffset = fstate.bfcOffset + offset input.marginResolved = fstate.marginResolved input.marginTodo = fstate.marginTodo input.pendingFloatsHead = fstate.pendingFloatsHead input.pendingFloatsTail = fstate.pendingFloatsTail input.exclusionsHead = fstate.exclusionsHead input.exclusionsTail = fstate.exclusionsTail input.clearOffset = fstate.clearOffset fstate.lctx.layout(child, offset, input) fstate.pendingFloatsHead = child.state.pendingFloatsHead fstate.pendingFloatsTail = child.state.pendingFloatsTail fstate.marginTodo = child.state.marginTodo fstate.maxFloatHeight = max(fstate.maxFloatHeight, child.state.maxFloatHeight) fstate.clearOffset = child.state.clearOffset fstate.exclusionsHead = child.state.exclusionsHead fstate.exclusionsTail = child.state.exclusionsTail if not fstate.marginResolved and child.state.marginResolved: # We are "inheriting" the margin flushed by a descendant, so we must # move our BFC offset by said margin (as flushMargins only did it for # the descendant.) let marginOutput = child.state.marginOutput fstate.marginOutput = marginOutput fstate.bfcOffset.y += marginOutput fstate.marginResolved = true fstate.marginTodo.addMargin(input.margin.bottom) let outerSize = size( w = child.outerSize(dtHorizontal, input, lctx), # delta y is difference between old and new offsets (margin-top), # plus height, plus border size. h = child.state.offset.y - fstate.offset.y + child.state.size.h + input.borderBottom(lctx) ) if child.state.baselineSet: if not fstate.box.state.baselineSet: fstate.box.state.firstBaseline = child.state.offset.y + child.state.firstBaseline fstate.box.state.baselineSet = true fstate.box.state.baseline = child.state.offset.y + child.state.baseline if fstate.space.w.t == scStretch: if child.computed{"margin-left"}.auto or child.computed{"margin-right"}.auto: # auto margin seems to have precedence over center let underflow = lctx.resolveAutoMarginStart(input, space.w.u, child, dtHorizontal) child.state.offset.x += underflow elif fstate.textAlign == TextAlignChaCenter: child.state.offset.x += max(space.w.u div 2'lu - outerSize.w div 2'lu, 0'lu) elif fstate.textAlign == TextAlignChaRight: child.state.offset.x += max(space.w.u - outerSize.w - input.margin.right, 0'lu) if child.computed{"position"} == PositionRelative: fstate.lctx.positionRelative(fstate.space, child) fstate.maxChildWidth = max(fstate.maxChildWidth, outerSize.w) fstate.offset.y += outerSize.h fstate.intr.h += outerSize.h - child.state.size.h + child.state.intr.h fstate.lbstate.whitespaceNum = 0 fstate.intr.w = max(fstate.intr.w, child.state.intr.w) proc layoutOuterBlock(fstate: var FlowState; child: BlockBox) = if child.computed{"position"} in PositionAbsoluteFixed: # Delay this block's layout until its parent's dimensions are # actually known. # We want to get the child to a Y position where it would have # been placed had it not been absolutely positioned. # # Like with floats, we must consider both the case where the # parent's position is resolved, and the case where it isn't. # Here our job is much easier in the unresolved case: subsequent # children's layout doesn't depend on our position; so we can just # defer margin resolution to the parent. if fstate.space.w.t == scMeasure: # Do not queue in the first pass. return var offset = fstate.offset fstate.initLine(flag = ilfAbsolute) if fstate.marginResolved: offset.y += fstate.marginTodo.sum() if child.computed{"display"} in DisplayOuterInline: # inline-block or similar. put it on the current line. # our position will stick to the next atom's end, which may be moved # at alignLine. fstate.lbstate.pendingAbsolutes.add(child) # ...however, that is not guaraneteed to happen before we are actually # positioned, so we also have to set a sensible offset here. offset.x = fstate.lbstate.size.w + fstate.getLineXShift() elif fstate.lbstate.realAtomsTail != nil: # flush if there is already something on the line *and* our outer # display is block. offset.y += fstate.cellSize.h # This really has nothing to do with bfcOffset, but I don't want to # waste more bytes in LayoutInput. child.input.bfcOffset = offset elif child.computed{"float"} != FloatNone: fstate.layoutFloat(child) else: fstate.layoutBlockChild(child) proc layoutInlineBlock(fstate: var FlowState; ibox: InlineBox; box: BlockBox) = let lctx = fstate.lctx if box.computed{"position"} in PositionAbsoluteFixed: # Absolute is a bit of a special case in inline: while the spec # *says* it should blockify, absolutely positioned inline-blocks are # placed in a different place than absolutely positioned blocks (and # websites depend on this). fstate.layoutOuterBlock(box) elif box.computed{"display"} == DisplayMarker: # Marker box. This is a mixture of absolute and inline-block # layout, where we don't care about the parent size but want to # place ourselves outside the left edge of our parent box. var input = lctx.resolveFloatSizes(fstate.space, box) fstate.initLine(flag = ilfAbsolute) lctx.layout(box, input.margin.topLeft, input) box.state.offset.x = fstate.lbstate.size.w - box.state.size.w else: # A real inline block. var input = lctx.resolveFloatSizes(fstate.space, box) lctx.layout(box, input.margin.topLeft, input) # Apply the block box's properties to the atom itself. let atom = InlineAtom( ibox: ibox, box: box, size: box.outerSize(input, lctx) ) discard fstate.prepareSpace(ibox, atom.size.w) fstate.putAtom(atom) fstate.intr.w = max(fstate.intr.w, box.state.intr.w) fstate.lbstate.intrh = max(fstate.lbstate.intrh, atom.size.h) fstate.lbstate.charwidth = 0 fstate.lbstate.whitespaceNum = 0 proc layoutInline(fstate: var FlowState; ibox: InlineBox) = let lctx = fstate.lctx ibox.keepLayout = true ibox.resetState() let padding = Span( start: ibox.computed{"padding-left"}.px(fstate.space.w), send: ibox.computed{"padding-right"}.px(fstate.space.w) ) let oldTextAlign = fstate.textAlign # -moz-center uses the inline parent too, which is nonsense if you # consider the CSS 2 anonymous box generation rules, but whatever. fstate.textAlign = ibox.computed{"text-align"} fstate.iboxStack.add(ibox) if ibox of InlineTextBox: let ibox = InlineTextBox(ibox) ibox.runs.setLen(0) fstate.layoutText(ibox, ibox.text.s) elif ibox of InlineNewLineBox: let ibox = InlineNewLineBox(ibox) fstate.finishLine(ibox, wrap = false, force = true, ibox.computed{"clear"}) else: ibox.state.startOffset = offset( x = fstate.lbstate.widthAfterWhitespace, y = fstate.offset.y ) let w = ibox.computed{"margin-left"}.px(fstate.space.w) if w != 0'lu: fstate.initLine() fstate.lbstate.size.w += w fstate.lbstate.widthAfterWhitespace += w ibox.state.startOffset.x += w if padding.start != 0'lu: ibox.state.areas.add(Area( offset: offset(x = fstate.lbstate.widthAfterWhitespace, y = 0'lu), size: size(w = padding.start, h = fstate.cellSize.h) )) fstate.lbstate.paddingTodo.add((ibox, 0)) fstate.initLine() fstate.lbstate.size.w += padding.start for child in ibox.children: if child of InlineBox: fstate.layoutInline(InlineBox(child)) else: assert child of BlockBox let child = BlockBox(child) if child.computed{"display"} in DisplayInlineBlockLike: fstate.layoutInlineBlock(ibox, child) else: fstate.layoutOuterBlock(child) if padding.send != 0'lu: ibox.state.areas.add(Area( offset: offset(x = fstate.lbstate.size.w, y = 0'lu), size: size(w = padding.send, h = fstate.cellSize.h) )) fstate.lbstate.paddingTodo.add((ibox, ibox.state.areas.high)) fstate.initLine() fstate.lbstate.size.w += padding.send let marginRight = ibox.computed{"margin-right"}.px(fstate.space.w) if marginRight != 0'lu: fstate.initLine() fstate.lbstate.size.w += marginRight if fstate.space.w.t != scMeasure: # This is UB in CSS 2.1, I can't find a newer spec about it, # and Gecko can't even layout it consistently (???) # # So I'm trying to follow Blink, though it's still not quite right, # since this uses cellHeight instead of the actual line height # for the last line. # Well, it seems good enough. lctx.popPositioned(ibox.absolute, size( w = fstate.maxChildWidth, h = fstate.offset.y + fstate.cellSize.h - ibox.state.startOffset.y )) fstate.textAlign = oldTextAlign proc layoutFlow0(fstate: var FlowState) = fstate.lbstate = fstate.initLineBoxState() let box = fstate.box for child in box.children: if child of InlineBox: fstate.layoutInline(InlineBox(child)) else: fstate.layoutOuterBlock(BlockBox(child)) fstate.finishLine(fstate.lastTextBox, wrap = false) fstate.totalFloatWidth = max(fstate.totalFloatWidth, fstate.lbstate.totalFloatWidth) proc initFlowState(lctx: LayoutContext; box: BlockBox; input: LayoutInput; root: bool): FlowState = result = FlowState( lctx: lctx, box: box, offset: input.padding.topLeft, bfcOffset: input.bfcOffset, space: input.space, exclusionsHead: input.exclusionsHead, exclusionsTail: input.exclusionsTail, textAlign: box.computed{"text-align"}, marginResolved: root, clearOffset: input.clearOffset, marginTodo: input.marginTodo, pendingFloatsHead: input.pendingFloatsHead, pendingFloatsTail: input.pendingFloatsTail ) if box.computed{"position"} in PositionAbsoluteFixed: # absolute abuses bfcOffset as its own offset, so unset it result.bfcOffset = Offset0 # Second layout. Reset the starting offset, and stretch the box to the # max child width. proc initReLayout(fstate: var FlowState; box: BlockBox; input: LayoutInput; root: bool) = if fstate.exclusionsTail != nil: fstate.exclusionsTail.next = nil var bounds = input.bounds bounds.a[dtHorizontal].start = max(bounds.a[dtHorizontal].start, fstate.intr.w) box.applySize(bounds, fstate.maxChildWidth + fstate.totalFloatWidth, input.space, dtHorizontal) let lctx = fstate.lctx fstate = lctx.initFlowState(box, input, root) fstate.space.w = stretch(box.state.size.w) proc layoutFlow(lctx: LayoutContext; box: BlockBox; input: LayoutInput; root: bool) = var fstate = lctx.initFlowState(box, input, root) if box.computed{"position"} notin PositionAbsoluteFixed and (input.padding.top != 0'lu or input.borderTop(lctx) != 0'lu or input.space.h.isDefinite() and input.space.h.u != 0'lu): fstate.flushMargins(box.state.yshift) let spacew = fstate.space.w let indefinite = spacew.t in {scFitContent, scMaxContent} if indefinite: fstate.space.w = measure() fstate.layoutFlow0() if indefinite: fstate.space.w = spacew # shrink-to-fit size; layout again. let oldIntr = fstate.intr fstate.initReLayout(box, input, root) fstate.layoutFlow0() # Restore old intrinsic input, as the new ones are a function of the # current input and therefore wrong. fstate.intr = oldIntr elif fstate.space.w.t == scMeasure: fstate.maxChildWidth += fstate.totalFloatWidth # Apply width, and height. For height, temporarily remove padding we have # applied before so that percentage resolution works correctly. var childSize = size( w = fstate.maxChildWidth, h = fstate.offset.y - input.padding.top ) if input.padding.bottom != 0'lu or input.borderBottom(lctx) != 0'lu: let oldHeight = childSize.h fstate.flushMargins(childSize.h) fstate.intr.h += childSize.h - oldHeight box.applySize(input, childSize, fstate.space) let paddingSum = input.padding.sum() # Intrinsic minimum size includes the sum of our padding. (However, # this padding must also be clamped to the same bounds.) box.applyIntr(input, fstate.intr + paddingSum) # Add padding after applying space, since space applies to the content # box. box.state.size += paddingSum if not root and fstate.marginResolved and box.input.marginResolved: box.state.yshift += fstate.marginOutput fstate.marginOutput = 0'lu if fstate.marginResolved or input.marginResolved: # Our offset has already been resolved, ergo any margins in # marginTodo will be passed onto the next box. fstate.positionFloats() fstate.marginResolved = true box.state.maxFloatHeight = fstate.maxFloatHeight box.state.marginOutput = fstate.marginOutput box.state.marginResolved = fstate.marginResolved box.state.clearOffset = fstate.clearOffset box.state.marginTodo = fstate.marginTodo box.state.pendingFloatsHead = fstate.pendingFloatsHead box.state.pendingFloatsTail = fstate.pendingFloatsTail box.state.exclusionsHead = fstate.exclusionsHead box.state.exclusionsTail = fstate.exclusionsTail box.state.offset.y += box.state.yshift proc layoutFlowDescendant(lctx: LayoutContext; box: BlockBox; offset: Offset; input: LayoutInput) = if box.keepLayout and box.input == input: box.state.offset = offset box.state.offset.y += box.state.yshift return box.input = input box.keepLayout = true box.resetState() box.state.offset = offset lctx.layoutFlow(box, input, root = false) proc layoutFlowRootPre(lctx: LayoutContext; box: BlockBox; offset: Offset; input: LayoutInput): bool = let offset = offset + input.borderTopLeft(lctx) if box.keepLayout and box.input == input: box.state.offset = offset return false box.input = input box.keepLayout = true box.resetState() box.state.offset = offset true proc layoutFlowRoot(lctx: LayoutContext; box: BlockBox; offset: Offset; input: LayoutInput) = if not lctx.layoutFlowRootPre(box, offset, input): return lctx.layoutFlow(box, input, root = true) assert box.state.pendingFloatsTail == nil let marginBottom = box.state.marginTodo.sum() # If the highest float edge is higher than the box itself, set that as # the box height. let maxFloatHeight = box.state.maxFloatHeight box.state.size.h = max(box.state.size.h + marginBottom, maxFloatHeight) box.state.intr.h = max(box.state.intr.h + marginBottom, maxFloatHeight) proc layoutImage(lctx: LayoutContext; box: BlockBox; offset: Offset; input: LayoutInput) = if not lctx.layoutFlowRootPre(box, offset, input): return let bmp = box.getImageBitmap() # applyDeclaration only sets this layout if getBitmap isn't nil. # If it is nil, something is wrong with layout invalidation. assert bmp != nil let osize = size( w = bmp.width.toLUnit(), h = bmp.height.toLUnit() ) var size = osize if input.space.w.t == scStretch: let w = input.space.w.u if input.space.h.t != scStretch and osize.w > 0'lu: size.h = w * osize.h div osize.w size.w = w if input.space.h.t == scStretch: let h = input.space.h.u if input.space.w.t != scStretch and osize.h > 0'lu: size.w = h * osize.w div osize.h size.h = h let paddingSum = input.padding.sum() box.state.size = size + paddingSum box.applyIntr(input, box.state.size) # Table layout. This imitates what mainstream browsers do: # 1. Calculate minimum, maximum and preferred width of each column. # 2. If column width is not auto, set width to max(min_width, specified). # 3. Calculate the maximum preferred row width. If this is # a) less than the specified table width, or # b) greater than the table's content width: # Distribute the table's content width among cells proportionally to # their specified width. If this would give any cell a width < # min_width, set that cell's width to min_width, then re-do the # distribution. # 4. Relayout cells whose width changed since step 1. # 5. Align cells based on their text-align. # # Rowspan/colspan handling: in general, overlapping rowspan & colspan is # left to be. However, if a column would *start* at a rowspan, then it is # moved to the right by one column. This means that a column only has one # multi-row cell at a given time. # # Percentage widths (width=n%): # 1. for each column, assign the largest percentage width among its cells # as its weight (divided as appropriate by colspan). at each step, keep # track of the remaining weight (1 - assigned), and clamp the column's # weight down if it exceeds this. # 2. count sum of min width of all columns with weight=0, this is "unassigned" # 3. if unassigned is 0, and the total assigned weight is < 1, then scale all # assigned weight such that the sum is 1 (i.e. divide each column's weight # by the total weight.) # 4. for each assigned column, compute the total width implied by its weight: # (min width) / weight, as well as (unassigned) / (1 - weight). # 5. set the table's max width to the largest value computed in the previous # step. # 6. in the second pass, first fix the width of columns with an author weight, # *then* columns with an author width. # #TODO: # * <col>, <colgroup> # * distribute table height too type CellWrapper = ref object box: BlockBox # may be nil coli: int colspan: int rowspan: int real: CellWrapper # for filler wrappers last: bool # is this the last filler? reflow: bool height: LUnit baseline: LUnit inlineBorder: Span next: CellWrapper RowContext = object cellHead: CellWrapper width: LUnit height: LUnit borderWidth: LUnit blockBorder: Span box: BlockBox ncols: int ColumnContext = object minwidth: LUnit width: LUnit widthSpecified: bool weight: float32 reflow: int # last row index that need not be reflowed grown: int # number of remaining rows growing: CellWrapper TableContext = object lctx: LayoutContext rows: seq[RowContext] cols: seq[ColumnContext] hasAuthorWeight: bool maxwidth: LUnit blockSpacing: LUnit inlineSpacing: LUnit borderWidth: LUnit space: Space # space we got from parent proc layoutTableCell(lctx: LayoutContext; box: BlockBox; space: Space; border: CSSBorder; merge: CSSBorderMerge) = box.input = LayoutInput( padding: lctx.resolvePadding(space.w, box.computed), space: initSpace(w = space.w, h = maxContent()), bounds: DefaultBounds, border: border ) box.keepLayout = true box.resetState() box.state.merge = merge if box.input.space.w.isDefinite(): box.input.space.w.u -= box.input.padding[dtHorizontal].sum() lctx.layout(box, Offset0, box.input) assert box.state.pendingFloatsTail == nil # If the highest float edge is higher than the box itself, set that as # the box height. box.state.size.h = max(box.state.size.h, box.state.maxFloatHeight) if space.h.t == scStretch: box.state.size.h = max(box.state.size.h, space.h.u - box.input.padding[dtVertical].sum()) # A table cell's minimum width overrides its width. box.state.size.w = max(box.state.size.w, box.state.intr.w) # Ensure the cell has at least *some* baseline. if not box.state.baselineSet: box.state.firstBaseline = box.state.size.h box.state.baseline = box.state.size.h box.state.baselineSet = true # Grow cells with a rowspan > 1 (to occupy their place in a new row). proc growRowspan(tctx: var TableContext; growi, n: var int; ntill, growlen: int; width: var LUnit; cellHead, cellTail: var CellWrapper) = while growi < growlen: let cellw = tctx.cols[growi].growing if cellw == nil: inc growi continue if growi > ntill: break dec tctx.cols[growi].grown let grown = tctx.cols[growi].grown if grown == 0: tctx.cols[growi].growing = nil let colspan = cellw.colspan - (n - cellw.coli) let rowspanFiller = CellWrapper( colspan: colspan, rowspan: cellw.rowspan, coli: n, real: cellw, last: grown == 0, inlineBorder: cellw.inlineBorder ) if cellTail != nil: cellTail.next = rowspanFiller else: cellHead = rowspanFiller cellTail = rowspanFiller for i in n ..< n + colspan: width += tctx.cols[i].width width += tctx.inlineSpacing * 2'lu n += colspan inc growi proc resolveBorder(tctx: var TableContext; computed: CSSValues; firstRow, lastCell, lastRow: bool; inlineBorder, blockBorder: var Span): CSSBorder = let lctx = tctx.lctx var dummyMargin = RelativeRect.default # table cells have no margin var border = lctx.resolveBorder(computed, dummyMargin) if border.left notin BorderStyleNoneHidden: inlineBorder.start = max(lctx.cellSize.w div 2'lu, inlineBorder.start) if border.right notin BorderStyleNoneHidden: inlineBorder.send = max(lctx.cellSize.w div 2'lu, inlineBorder.send) if border.top notin BorderStyleNoneHidden: let d = if firstRow: 1'lu else: 2'lu blockBorder.start = max(blockBorder.start, lctx.cellSize.h div d) if border.bottom notin BorderStyleNoneHidden: let d = if lastRow: 1'lu else: 2'lu blockBorder.send = max(blockBorder.send, lctx.cellSize.h div d) if not lastCell: border[dtHorizontal].send = BorderStyleNone if not lastRow: border[dtVertical].send = BorderStyleNone border proc preLayoutTableColspan(tctx: var TableContext; cellw: CellWrapper; space: Space; rowi, n, nextn: int; weight: float32): LUnit = var width = 0'lu let colspan = cellw.colspan let lcolspan = colspan.toLUnit() let minw = cellw.box.state.intr.w div lcolspan let weight = weight / float32(colspan) let w = cellw.box.state.size.w div lcolspan if tctx.cols.len < nextn: tctx.cols.setLen(nextn) for col in tctx.cols.toOpenArray(n, nextn - 1).mitems: if col.weight < weight: tctx.hasAuthorWeight = true col.weight = weight col.widthSpecified = false # Figure out this cell's effect on the column's width. # Four cases exist: # 1. colwidth already fixed, cell width is fixed: take maximum # 2. colwidth already fixed, cell width is auto: take colwidth # 3. colwidth is not fixed, cell width is fixed: take cell width # 4. neither of colwidth or cell width are fixed: take maximum if col.widthSpecified: if space.w.isDefinite() and col.weight == 0: # A specified column already exists; we take the larger width. if w > col.width: col.width = w col.reflow = rowi if col.width != w: cellw.reflow = true elif space.w.isDefinite() and col.weight == 0: # This is the first specified column. Replace colwidth with whatever # we have. col.reflow = rowi col.widthSpecified = true col.width = w elif w > col.width: col.width = w col.reflow = rowi else: cellw.reflow = true if col.minwidth < minw: col.minwidth = minw if col.width < minw: col.width = minw col.reflow = rowi width += col.width let grown = cellw.rowspan - 1 if grown > 0: tctx.cols[n].grown = grown tctx.cols[n].growing = cellw width proc cellWidthPx(l: CSSLength): SizeConstraint = if l.auto or l.perc != 0: return measure() return stretch(l.npx.toLUnit()) proc preLayoutTableRow(tctx: var TableContext; row, parent: BlockBox; numrows: int) = let lctx = tctx.lctx let rowi = tctx.rows.len var cellHead: CellWrapper = nil var cellTail: CellWrapper = nil var blockBorder = Span(start: tctx.blockSpacing, send: tctx.blockSpacing) var n = 0 var growi = 0 var width = 0'lu var borderWidth = 0'lu var firstCell = true # this increases in the loop, but we only want to check growing cells that # were added by previous rows. let growlen = tctx.cols.len for box in row.children: let box = BlockBox(box) assert box.computed{"display"} == DisplayTableCell let firstRow = rowi == 0 let colspan = box.computed{"-cha-colspan"} # grow until n, but not more tctx.growRowspan(growi, n, n, growlen, width, cellHead, cellTail) let rowspan = min(box.computed{"-cha-rowspan"}, numrows - rowi) let cw = box.computed{"width"} let ch = box.computed{"height"} let perc = if cw.auto: 0f32 else: cw.perc let space = initSpace( w = cw.cellWidthPx(), h = ch.stretchOrMaxContent(tctx.space.h) ) var inlineBorder = Span(start: tctx.inlineSpacing, send: tctx.inlineSpacing) var border = tctx.resolveBorder(box.computed, firstRow, box.next == nil, row.next == nil, inlineBorder, blockBorder) borderWidth += inlineBorder.sum() let merge = [dtHorizontal: not firstCell, dtVertical: not firstRow] lctx.layoutTableCell(box, space, border, merge) let cellw = CellWrapper( box: box, colspan: colspan, rowspan: rowspan, coli: n, inlineBorder: inlineBorder, reflow: space.w.t == scMeasure ) if cellTail != nil: cellTail.next = cellw else: cellHead = cellw cellTail = cellw let nextn = n + colspan width += tctx.preLayoutTableColspan(cellw, space, rowi, n, nextn, perc) # add spacing for border inside colspan let spacing = tctx.inlineSpacing * ((colspan - 1) * 2).toLUnit() width += spacing borderWidth += spacing n = nextn firstCell = false tctx.growRowspan(growi, n, tctx.cols.len, growlen, width, cellHead, cellTail) width += borderWidth tctx.maxwidth = max(width, tctx.maxwidth) tctx.borderWidth = max(borderWidth, tctx.borderWidth) tctx.rows.add(RowContext( box: row, cellHead: cellHead, width: width, borderWidth: borderWidth, blockBorder: blockBorder, ncols: n )) proc alignTableCell(cell: BlockBox; availableHeight, baseline: LUnit) = let firstChild = BlockBox(cell.firstChild) if firstChild != nil: firstChild.state.offset.y += (case cell.computed{"vertical-align"} of VerticalAlignTop: 0'lu of VerticalAlignMiddle: availableHeight div 2'lu - cell.state.size.h div 2'lu of VerticalAlignBottom: availableHeight - cell.state.size.h else: baseline - cell.state.firstBaseline) cell.state.size.h = availableHeight proc layoutTableRow(tctx: TableContext; ctx: RowContext; parent, row: BlockBox; rowi: int) = row.keepLayout = true row.resetState() var x = 0'lu var n = 0 var baseline = 0'lu var cellw = ctx.cellHead while cellw != nil: var w = 0'lu var reflow = cellw.reflow let colspan1 = cellw.colspan - 1 if n < tctx.cols.len: for col in tctx.cols.toOpenArray(n, n + colspan1): w += col.width reflow = reflow or rowi < col.reflow # Add inline spacing for merged columns. w += tctx.inlineSpacing * colspan1.toLUnit() * 2'lu if reflow and cellw.box != nil: let space = initSpace(w = stretch(w), h = maxContent()) let border = cellw.box.input.border let merge = cellw.box.state.merge tctx.lctx.layoutTableCell(cellw.box, space, border, merge) w = max(w, cellw.box.state.size.w) row.state.intr.w += cellw.box.state.intr.w let cell = cellw.box x += cellw.inlineBorder.start if cell != nil: cell.state.offset.x += x x += cellw.inlineBorder.send x += w row.state.intr.w += cellw.inlineBorder.sum() n += cellw.colspan const HasNoBaseline = { VerticalAlignTop, VerticalAlignMiddle, VerticalAlignBottom } if cell != nil: if cell.computed{"vertical-align"} notin HasNoBaseline: baseline = max(cell.state.firstBaseline, baseline) row.state.size.h = max(row.state.size.h, cell.state.size.h div cellw.rowspan.toLUnit()) else: row.state.size.h = max(row.state.size.h, cellw.real.box.state.size.h div cellw.rowspan.toLUnit()) cellw = cellw.next cellw = ctx.cellHead while cellw != nil: if cellw.box != nil: if cellw.rowspan > 1: cellw.height += row.state.size.h cellw.baseline = baseline else: alignTableCell(cellw.box, row.state.size.h, baseline) else: let real = cellw.real real.height += row.state.size.h if cellw.last: alignTableCell(real.box, real.height, real.baseline) cellw = cellw.next row.state.size.w = x proc preLayoutTableRows(tctx: var TableContext; table: BlockBox) = # Per CSS 2.1, the first thead and tfoot is always rendered as the first # and the last group, while subsequent thead/tfoot is treated as tbody. var thead: CSSBox = nil var tfoot: CSSBox = nil var nrows = 0 for child in table.children: let display = child.computed{"display"} case display of DisplayTableHeaderGroup: if thead == nil: thead = child of DisplayTableRowGroup: child.keepLayout = true of DisplayTableRow: inc nrows continue of DisplayTableFooterGroup: if tfoot == nil: tfoot = child else: assert false for it in child.children: assert it.computed{"display"} == DisplayTableRow inc nrows tctx.rows = newSeqOfCap[RowContext](nrows) if thead != nil: for child in thead.children: tctx.preLayoutTableRow(BlockBox(child), table, nrows) for child in table.children: if child == thead or child == tfoot: continue if child.computed{"display"} == DisplayTableRow: tctx.preLayoutTableRow(BlockBox(child), table, nrows) else: for it in child.children: tctx.preLayoutTableRow(BlockBox(it), table, nrows) if tfoot != nil: for child in tfoot.children: tctx.preLayoutTableRow(BlockBox(child), table, nrows) proc calcSpecifiedRatio(tctx: var TableContext; totalWidth, weightRatio: float32): float32 = var totalSpecified = 0'lu var hasUnspecified = false let hasWeightRatio = not almostEqual(weightRatio, 1) for col in tctx.cols.mitems: let minwidth = col.minwidth if col.weight > 0: let width = max((col.weight * totalWidth).toLUnit(), minwidth) totalSpecified += width col.width = width elif col.widthSpecified: if hasWeightRatio: let scaled = (col.width.toFloat32() * weightRatio).toLUnit() col.width = max(scaled, minwidth) col.reflow = tctx.rows.len totalSpecified += col.width else: hasUnspecified = true totalSpecified += minwidth # Only grow specified columns if no unspecified column exists to take the # rest of the space. if totalSpecified == 0'lu: return 1 let ftotalSpecified = totalSpecified.toFloat32() if hasUnspecified and totalWidth > ftotalSpecified: return 1 return totalWidth / ftotalSpecified proc calcUnspecifiedColIndices(tctx: var TableContext; W: var LUnit; weight: var float32; weightRatio: float32): seq[int] = let totalWidth = W.toFloat32() let rtotalWidth = 1 / W.toFloat32() let specifiedRatio = tctx.calcSpecifiedRatio(totalWidth, weightRatio) let hasSpecifiedRatio = not almostEqual(specifiedRatio, 1) # Spacing for each column: var avail = newSeqOfCap[int](tctx.cols.len) for i, col in tctx.cols.mpairs: if col.weight != 0: W -= col.width let w = (col.width.toFloat32() * specifiedRatio).toLUnit() col.width = max(w, col.minwidth) col.reflow = tctx.rows.len elif col.widthSpecified: if hasSpecifiedRatio: let w = (col.width.toFloat32() * specifiedRatio).toLUnit() col.width = max(w, col.minwidth) col.reflow = tctx.rows.len W -= col.width else: avail.add(i) let width = col.width.toFloat32() let w = if width < totalWidth: width else: totalWidth * (ln(width * rtotalWidth) + 1) let colWeight = w * specifiedRatio col.weight = colWeight weight += colWeight move(avail) proc needsRedistribution(tctx: TableContext; computed: CSSValues): bool = case tctx.space.w.t of scMinContent, scMaxContent, scMeasure: return false of scStretch: return tctx.hasAuthorWeight or tctx.space.w.u != tctx.maxwidth of scFitContent: return tctx.space.w.u > tctx.maxwidth and not computed{"width"}.auto or tctx.space.w.u < tctx.maxwidth proc expandToWeight(tctx: var TableContext): float32 = var maxwidth = tctx.maxwidth var avail = 1f32 var unassigned = 0'lu var specified = 0'lu var hasUnspecified = false for col in tctx.cols.mitems: let weight = min(col.weight, avail) if weight == 0: unassigned += col.width if col.widthSpecified: specified += col.width else: hasUnspecified = true continue let colTarget = (1 / weight).toLUnit() * col.minwidth maxwidth = max(maxwidth, colTarget) col.weight = weight avail -= weight let omaxwidth = maxwidth if avail > 0: let restTarget = (1 / avail).toLUnit() * unassigned maxwidth = max(maxwidth, restTarget) + tctx.borderWidth elif unassigned > 0'lu: maxwidth = tctx.space.w.u else: maxwidth += tctx.borderWidth if tctx.space.w.t == scFitContent: tctx.space.w = stretch(min(tctx.space.w.u, maxwidth)) if hasUnspecified and tctx.space.w.u > omaxwidth + unassigned: # the unspecified column will take the rest of the width return 1 let fspecified = unassigned.toFloat32() if fspecified == 0: return 1 # either the total column width too small, and there are no unspecified # columns to take the rest, or columns overflow the table and must be # rescaled. return (tctx.space.w.u.toFloat32() * avail) / fspecified proc redistributeWidth(tctx: var TableContext; weightRatio: float32) = # Remove inline spacing from distributable width. var W = max(tctx.space.w.u - tctx.borderWidth, 0'lu) var weight = 0f32 var avail = tctx.calcUnspecifiedColIndices(W, weight, weightRatio) var redo = true while redo and avail.len > 0 and weight != 0: if weight == 0: break # zero weight; nothing to distribute W = max(W, 0'lu) redo = false # divide delta width by sum of ln(width) for all elem in avail let unit = W.toFloat32() / weight weight = 0 for i in countdown(avail.high, 0): let j = avail[i] let x = (unit * tctx.cols[j].weight).toLUnit() let mw = tctx.cols[j].minwidth tctx.cols[j].width = x if mw > x: W -= mw tctx.cols[j].width = mw avail.del(i) redo = true else: weight += tctx.cols[j].weight tctx.cols[j].reflow = tctx.rows.len proc layoutTableRows(tctx: TableContext; table: BlockBox; input: LayoutInput) = var y = input.padding.top for i, roww in tctx.rows.mypairs: if roww.box.computed{"visibility"} == VisibilityCollapse: continue y += roww.blockBorder.start let row = roww.box tctx.layoutTableRow(roww, table, row, i) row.state.offset.y += y row.state.offset.x += input.padding.left row.state.size.w += input.padding[dtHorizontal].sum() y += roww.blockBorder.send y += row.state.size.h table.state.size.w = max(row.state.size.w, table.state.size.w) table.state.intr.w = max(row.state.intr.w, table.state.intr.w) y += input.padding.bottom # Note: we can't use applySizeConstraint here; in CSS, "height" on tables just # sets the minimum height. case tctx.space.h.t of scStretch: table.state.size.h = max(tctx.space.h.u, y) of scMinContent, scMaxContent, scMeasure, scFitContent: # I don't think these are ever used here; not that they make much sense for # min-height... table.state.size.h = y proc layoutCaption(lctx: LayoutContext; box: BlockBox; space: Space; input: var LayoutInput) = input = lctx.resolveBlockSizes(space, box) lctx.layout(box, input.margin.topLeft, input) proc layoutInnerTable(tctx: var TableContext; table, parent: BlockBox; input: LayoutInput) = # Switch the table's space to fit-content if its width is auto. if tctx.space.w.t == scStretch: let width = parent.computed{"width"} if width.isPx(): table.state.intr.w = tctx.space.w.u elif not width.canpx(tctx.space.w): tctx.space.w = fitContent(tctx.space.w.u) if table.computed{"border-collapse"} != BorderCollapseCollapse: tctx.inlineSpacing = table.computed{"-cha-border-spacing-inline"}.px(0'lu) tctx.blockSpacing = table.computed{"-cha-border-spacing-block"}.px(0'lu) tctx.preLayoutTableRows(table) # first pass let weightRatio = if tctx.hasAuthorWeight and tctx.space.w.isDefinite(): tctx.expandToWeight() else: 1f32 if tctx.needsRedistribution(table.computed): tctx.redistributeWidth(weightRatio) for col in tctx.cols: table.state.size.w += col.width tctx.layoutTableRows(table, input) # second pass # Table height is minimum by default, and non-negotiable when # specified, ergo it always equals the intrinisc minimum height. table.state.intr.h = table.state.size.h # As per standard, we must put the caption outside the actual table, # inside a block-level wrapper box. # # Note that computing the caption's width isn't as simple as it sounds. # First, the caption's intrinsic minimum size overrides the available # space (unlike what happens in flow, where available space wins). # Second, table and caption width has a cyclic dependency, in that the # larger of the two must be used for layouting both the cells and the # caption. # # So conceptually we first layout caption, relayout with its intrinsic # min size if needed, then layout table, then caption again if table's # width exceeds caption's width. (In practice, the second layout is # skipped if there will be a third one, so we never layout more than # twice.) proc layoutTable(lctx: LayoutContext; box: BlockBox; offset: Offset; input: LayoutInput) = if not lctx.layoutFlowRootPre(box, offset, input): return let table = BlockBox(box.firstChild) table.keepLayout = true table.resetState() var tctx = TableContext(lctx: lctx, space: input.space) let caption = BlockBox(table.next) var captionSpace = initSpace( w = fitContent(input.space.w), h = maxContent() ) var captionSizes: LayoutInput if caption != nil: lctx.layoutCaption(caption, captionSpace, captionSizes) if captionSpace.w.isDefinite(): if caption.state.intr.w != captionSpace.w.u: captionSpace.w.u = caption.state.intr.w if tctx.space.w.t == scStretch and tctx.space.w.u < captionSpace.w.u: tctx.space.w.u = captionSpace.w.u tctx.layoutInnerTable(table, box, input) box.state.size = table.state.size box.state.intr = table.state.intr var baseline = 0'lu if caption != nil: if captionSpace.w.isDefinite(): if table.state.size.w > captionSpace.w.u: captionSpace.w = stretch(table.state.size.w) if captionSpace.w.u != caption.state.size.w: # desired size changed; redo lctx.layoutCaption(caption, captionSpace, captionSizes) let outerSize = caption.outerSize(captionSizes, lctx) case caption.computed{"caption-side"} of CaptionSideTop, CaptionSideBlockStart: table.state.offset.y += outerSize.h of CaptionSideBottom, CaptionSideBlockEnd: caption.state.offset.y += table.state.size.h box.state.size.w = max(box.state.size.w, outerSize.w) box.state.intr.w = max(box.state.intr.w, caption.state.intr.w) box.state.size.h += outerSize.h box.state.intr.h += outerSize.h - caption.state.size.h + caption.state.intr.h if caption.state.baselineSet: baseline = max(baseline, caption.state.offset.y + caption.state.size.h) box.state.baseline = max(baseline, table.state.offset.y + table.state.size.h) box.state.firstBaseline = baseline box.state.baselineSet = true # Flex layout. type FlexWeightType = enum fwtGrow, fwtShrink FlexPendingItem = object child: BlockBox weights: array[FlexWeightType, float32] input: LayoutInput FlexContext = object offset: Offset lctx: LayoutContext totalMaxSize: Size intr: Size # intrinsic minimum size relativeChildren: seq[BlockBox] redistSpace: SizeConstraint firstBaseline: LUnit baseline: LUnit canWrap: bool reverse: bool dim: DimensionType # main dimension baselineSet: bool FlexMainContext = object totalSize: Size maxSize: Size shrinkSize: LUnit maxMargin: RelativeRect totalWeight: array[FlexWeightType, float32] pending: seq[FlexPendingItem] proc layoutFlexItem(lctx: LayoutContext; box: BlockBox; input: LayoutInput) = lctx.layout(box, Offset0, input, forceRoot = true) const FlexRow = {FlexDirectionRow, FlexDirectionRowReverse} proc updateMaxSizes(mctx: var FlexMainContext; child: BlockBox; input: LayoutInput; lctx: LayoutContext) = for dim in DimensionType: mctx.maxSize[dim] = max(mctx.maxSize[dim], child.state.size[dim] + input.borderSum(dim, lctx)) mctx.maxMargin[dim].start = max(mctx.maxMargin[dim].start, input.margin[dim].start) mctx.maxMargin[dim].send = max(mctx.maxMargin[dim].send, input.margin[dim].send) proc redistributeMainSize(mctx: var FlexMainContext; diff: LUnit; wt: FlexWeightType; dim: DimensionType; lctx: LayoutContext) = var diff = diff var totalWeight = mctx.totalWeight[wt] let odim = dim.opposite var relayout: seq[int] = @[] while (wt == fwtGrow and diff > 0'lu or wt == fwtShrink and diff < 0'lu) and totalWeight > 0: # redo maxSize calculation; we only need height here mctx.maxSize[odim] = 0'lu var udiv = totalWeight if wt == fwtShrink: udiv *= mctx.shrinkSize.toFloat32() / totalWeight let unit = if udiv != 0: diff.toFloat32() / udiv else: 0 # reset total weight & available diff for the next iteration (if there is # one) totalWeight = 0 diff = 0'lu relayout.setLen(0) for i, it in mctx.pending.mpairs: if it.weights[wt] == 0: mctx.updateMaxSizes(it.child, it.input, lctx) continue var uw = unit * it.weights[wt] if wt == fwtShrink: uw *= it.child.state.size[dim].toFloat32() var u = it.child.state.size[dim] + uw.toLUnit() # check for min/max violation let minu = max(it.child.state.intr[dim], it.input.bounds.a[dim].start) if minu > u: # min violation if wt == fwtShrink: # freeze diff += u - minu it.weights[wt] = 0 mctx.shrinkSize -= it.child.state.size[dim] u = minu it.input.bounds.mi[dim].start = u let maxu = max(minu, it.input.bounds.a[dim].send) if maxu < u: # max violation if wt == fwtGrow: # freeze diff += u - maxu it.weights[wt] = 0 u = maxu it.input.bounds.mi[dim].send = u u -= it.input.padding[dim].sum() it.input.space[dim] = stretch(u) # override minimum intrinsic size clamping too totalWeight += it.weights[wt] if it.weights[wt] == 0: # frozen, relayout immediately lctx.layoutFlexItem(it.child, it.input) mctx.updateMaxSizes(it.child, it.input, lctx) else: # delay relayout relayout.add(i) for i in relayout: let child = mctx.pending[i].child lctx.layoutFlexItem(child, mctx.pending[i].input) mctx.updateMaxSizes(child, mctx.pending[i].input, lctx) proc flushMain(fctx: var FlexContext; mctx: var FlexMainContext; input: LayoutInput) = let dim = fctx.dim let odim = dim.opposite let lctx = fctx.lctx if fctx.redistSpace.isDefinite: let diff = fctx.redistSpace.u - mctx.totalSize[dim] let wt = if diff > 0'lu: fwtGrow else: fwtShrink # Do not grow shrink-to-fit input. if wt == fwtShrink or fctx.redistSpace.t == scStretch: mctx.redistributeMainSize(diff, wt, dim, lctx) elif input.bounds.a[dim].start > 0'lu: # Override with min-width/min-height, but *only* if we are smaller # than the desired size. (Otherwise, we would incorrectly limit # max-content size when only a min-width is requested.) if input.bounds.a[dim].start > mctx.totalSize[dim]: let diff = input.bounds.a[dim].start - mctx.totalSize[dim] mctx.redistributeMainSize(diff, fwtGrow, dim, lctx) let maxMarginSum = mctx.maxMargin[odim].sum() let h = mctx.maxSize[odim] + maxMarginSum var intr = size(w = 0'lu, h = 0'lu) var offset = fctx.offset for it in mctx.pending.mitems: let oborder = it.child.input.borderSum(odim, lctx) if it.child.state.size[odim] + oborder < h and not it.input.space[odim].isDefinite: # if the max height is greater than our height, then take max height # instead. (if the box's available height is definite, then this will # change nothing, so we skip it as an optimization.) it.input.space[odim] = stretch(h - it.input.margin[odim].sum() - it.input.padding[odim].sum() - oborder) if odim == dtVertical: # Exclude the bottom margin; space only applies to the actual # height. it.input.space[odim].u -= it.child.state.marginTodo.sum() lctx.layoutFlexItem(it.child, it.input) offset[dim] += it.input.margin[dim].start it.child.state.offset[dim] += offset[dim] # resolve auto cross margins for shrink-to-fit items if input.space[odim].t == scStretch: it.input.margin[odim].start += lctx.resolveAutoMarginStart(it.input, input.space[odim].u, it.child, odim) # margins are added here, since they belong to the flex item. it.child.state.offset[odim] += offset[odim] + it.input.margin[odim].start offset[dim] += it.child.state.size[dim] offset[dim] += it.input.margin[dim].send offset[dim] += it.input.borderSum(dim, lctx) let intru = it.child.state.intr[dim] + it.input.margin[dim].sum() if fctx.canWrap: intr[dim] = max(intr[dim], intru) else: intr[dim] += intru intr[odim] = max(it.child.state.intr[odim], intr[odim]) if it.child.computed{"position"} == PositionRelative: fctx.relativeChildren.add(it.child) let baseline = it.child.state.offset.y + it.child.state.baseline if not fctx.baselineSet: fctx.baselineSet = true fctx.firstBaseline = baseline fctx.baseline = baseline if fctx.reverse: for it in mctx.pending: let child = it.child child.state.offset[dim] = offset[dim] - child.state.offset[dim] - child.state.size[dim] fctx.totalMaxSize[dim] = max(fctx.totalMaxSize[dim], offset[dim]) fctx.intr[dim] = max(fctx.intr[dim], intr[dim]) fctx.intr[odim] += intr[odim] + maxMarginSum mctx = FlexMainContext() fctx.offset[odim] += h proc layoutFlexIter(fctx: var FlexContext; mctx: var FlexMainContext; child: BlockBox; input: LayoutInput) = let lctx = fctx.lctx let dim = fctx.dim var childSizes = lctx.resolveFlexItemSizes(input.space, dim, child) let flexBasis = child.computed{"flex-basis"} let childMinBounds = childSizes.bounds.a[dim] let skipBounds = childSizes.space[dim].t == scMaxContent if skipBounds: childSizes.bounds.a[dim] = DefaultSpan lctx.layoutFlexItem(child, childSizes) if not flexBasis.auto and input.space[dim].isDefinite: # we can't skip this pass; it is needed to calculate the minimum # height. let minu = child.state.intr[dim] childSizes.space[dim] = stretch(flexBasis.spx(input.space[dim], child.computed, childSizes.padding[dim].sum())) if minu > childSizes.space[dim].u: # First pass gave us a box that is thinner than the minimum # acceptable width for whatever reason; this may have happened # because the initial flex basis was e.g. 0. Try to resize it to # something more usable. childSizes.space[dim] = stretch(minu) lctx.layoutFlexItem(child, childSizes) if skipBounds: childSizes.bounds.a[dim] = childMinBounds if child.computed{"position"} in PositionAbsoluteFixed: # Absolutely positioned flex children do not participate in flex layout. child.input.bfcOffset = Offset0 else: if fctx.canWrap and (input.space[dim].t == scMinContent or input.space[dim].isDefinite and mctx.totalSize[dim] + child.state.size[dim] > input.space[dim].u): fctx.flushMain(mctx, input) let outerSize = child.outerSize(dim, childSizes, lctx) mctx.updateMaxSizes(child, childSizes, lctx) let grow = child.computed{"flex-grow"} let shrink = child.computed{"flex-shrink"} mctx.totalWeight[fwtGrow] += grow mctx.totalWeight[fwtShrink] += shrink mctx.totalSize[dim] += outerSize if shrink != 0: mctx.shrinkSize += outerSize mctx.pending.add(FlexPendingItem( child: child, weights: [grow, shrink], input: childSizes )) proc layoutFlex(lctx: LayoutContext; box: BlockBox; offset: Offset; input: LayoutInput) = if not lctx.layoutFlowRootPre(box, offset, input): return let flexDir = box.computed{"flex-direction"} let dim = if flexDir in FlexRow: dtHorizontal else: dtVertical let odim = dim.opposite() var fctx = FlexContext( lctx: lctx, offset: input.padding.topLeft, redistSpace: input.space[dim], canWrap: box.computed{"flex-wrap"} != FlexWrapNowrap, reverse: box.computed{"flex-direction"} in FlexReverse, dim: dim ) if fctx.redistSpace.t == scFitContent and input.bounds.a[dim].start > 0'lu: fctx.redistSpace = stretch(input.bounds.a[dim].start) if fctx.redistSpace.isDefinite: fctx.redistSpace.u = fctx.redistSpace.u.minClamp(input.bounds.a[dim]) var mctx = FlexMainContext() for child in box.children: let child = BlockBox(child) fctx.layoutFlexIter(mctx, child, input) if mctx.pending.len > 0: fctx.flushMain(mctx, input) let paddingSum = input.padding.sum() var size = fctx.totalMaxSize size[odim] = fctx.offset[odim] size -= input.padding.topLeft box.applySize(input, size, input.space) box.state.size += paddingSum box.applyIntr(input, fctx.intr + paddingSum) box.state.baselineSet = fctx.baselineSet box.state.firstBaseline = fctx.firstBaseline box.state.baseline = fctx.baseline for child in fctx.relativeChildren: lctx.positionRelative(input.space, child) proc layout(lctx: LayoutContext; box: BlockBox; offset: Offset; input: LayoutInput; forceRoot = false) = case box.computed{"display"} of DisplayFlowRoot, DisplayTableCaption, DisplayInlineBlock, DisplayInnerGrid, DisplayMarker: lctx.layoutFlowRoot(box, offset, input) of DisplayBlock, DisplayListItem: if forceRoot or box.computed{"position"} in PositionAbsoluteFixed or box.computed{"float"} != FloatNone or box.computed{"overflow-x"} notin {OverflowVisible, OverflowClip}: lctx.layoutFlowRoot(box, offset, input) else: lctx.layoutFlowDescendant(box, offset, input) of DisplayTableCell: lctx.layoutFlow(box, input, root = true) of DisplayInnerTable: lctx.layoutTable(box, offset, input) of DisplayInnerFlex: lctx.layoutFlex(box, offset, input) of DisplayImageBlock, DisplayImageInline: lctx.layoutImage(box, offset, input) else: assert false if input.space.w.t != scMeasure: lctx.popPositioned(box.absolute, box.state.size) proc layout*(box: BlockBox; attrs: WindowAttributes; fixedHead: CSSAbsolute; luctx: LUContext) = var size = size(w = attrs.widthPx.toLUnit(), h = attrs.heightPx.toLUnit()) let space = initSpace(w = stretch(size.w), h = stretch(size.h)) let cellSize = size(w = attrs.ppc.toLUnit(), h = attrs.ppl.toLUnit()) let lctx = LayoutContext(cellSize: cellSize, luctx: luctx) let input = lctx.resolveBlockSizes(space, box) # the bottom margin is unused. lctx.layout(box, input.margin.topLeft, input, forceRoot = true) # Fixed containing block. # The idea is to move fixed boxes to the real edges of the page, # so that they do not overlap with other boxes *and* we don't have # to move them on scroll. It's still not compatible with what desktop # browsers do, but the alternative would completely break search (and # slow down the renderer to a crawl.) size.w = max(size.w, box.state.size.w) size.h = max(size.h, box.state.size.h) lctx.popPositioned(fixedHead, size) {.pop.} # raises: [] ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/css/lunit.nim���������������������������������������������������������������������0000664�0000000�0000000�00000004202�15202323131�0016347�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 32-bit fixed-point number, with 6 bits of precision. import std/math import types/opt import utils/dtoawrap import utils/twtstr type LUnit* = distinct int32 {.push overflowChecks: off, rangeChecks: off.} template satlu(a: int64): LUnit = if unlikely(a < int32.low): LUnit.low elif unlikely(a > int32.high): LUnit.high else: LUnit(a) proc `+`*(a, b: LUnit): LUnit {.inline.} = let ab = int64(a) + int64(b) return satlu(ab) proc `-`*(a, b: LUnit): LUnit {.inline.} = let ab = int64(a) - int64(b) return satlu(ab) proc `*`*(a, b: LUnit): LUnit {.inline.} = let ab = (int64(a) * int64(b)) shr 6 return satlu(ab) proc `div`*(a, b: LUnit): LUnit {.inline.} = let a = int64(uint64(a) shl 12) let b = int64(b) return LUnit((a div b) shr 6) proc toLUnit*(a: int32): LUnit = let b = int64(a) shl 6 satlu(b) proc toLUnit*(a: int): LUnit = let b = int64(a) shl 6 satlu(b) proc `-`*(a: LUnit): LUnit {.inline.} = let a = int32(a) if unlikely(a == int32.low): return LUnit.high return LUnit(-a) {.pop.} # overflowChecks, rangeChecks template `'lu`*(s: static string): LUnit = (static(parseInt32(s).get.toLUnit())) proc `==`*(a, b: LUnit): bool {.borrow.} proc `<`*(a, b: LUnit): bool {.borrow.} proc `<=`*(a, b: LUnit): bool {.borrow.} proc toInt*(a: LUnit): int = if a < 0'lu: return -(int32(-a) shr 6) return int32(a) shr 6 proc `+=`*(a: var LUnit; b: LUnit) {.inline.} = a = a + b proc `-=`*(a: var LUnit; b: LUnit) {.inline.} = a = a - b proc `*=`*(a: var LUnit; b: LUnit) {.inline.} = a = a * b proc toLUnit*(a: float32): LUnit = let a = round(a * 64) if unlikely(a == Inf): return LUnit(int32.high) elif unlikely(a == -Inf): return LUnit(int32.low) return LUnit(int32(a)) proc toFloat32*(a: LUnit): float32 = return float32(int32(a)) / 64 proc toFloat64*(a: LUnit): float64 = return float64(int32(a)) / 64 proc `$`*(a: LUnit): string = dtoa(a.toFloat32()) proc min*(a, b: LUnit): LUnit {.borrow.} proc max*(a, b: LUnit): LUnit {.borrow.} proc ceilTo*(a: LUnit; prec: int): LUnit = let prec = prec.toLUnit() return (1 + ((a - 1'lu) div prec).toInt).toLUnit() * prec ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/css/match.nim���������������������������������������������������������������������0000664�0000000�0000000�00000024035�15202323131�0016316�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import chame/tags import css/cssparser import html/catom import html/dom import types/opt import utils/twtstr # Matching is slightly complicated by dependency tracking. # In general, dependencies must be added for any element whose state # affects the selectors matched onto the element. However, consider the # following situation: # # * to match: x > y:hover # * on elements: <z><y>test</y></z> # # A naive algorithm would mark a dependency of y on itself, since it # y:hover depends on y's hover status. But upon closer inspection, we # can see that it is *not necessary*: y's parent is x, not z, so no # matter if y is hovered, matching it again would be pointless. # # Hence it is more efficient for us to *continue matching* upon seeing # y:hover, and discard the dependency once it is determined that the # parent doesn't match z. # # A similar situation arises for compound selectors as well, and even # selector lists (in case of pseudo-class functions). proc matches(element: Element; cxsel: ComplexSelector; depends: var DependencyInfo; ohasDeps: var bool): bool type CaseSensitivity = enum csI, csS proc attrCase(sel: Selector; element: Element): CaseSensitivity = case sel.rel.flag of rfNone: if element.namespaceURI == satNamespaceHTML: return csI return csS of rfS: return csS of rfI: return csI proc matchesAttr(element: Element; sel: Selector): bool = case sel.rel.t of rtExists: return element.attrb(sel.attr) of rtEquals: case sel.attrCase(element) of csI: return element.attr(sel.attr).equalsIgnoreCase(sel.value) of csS: return element.attr(sel.attr) == sel.value of rtToken: let val = element.attr(sel.attr) case sel.attrCase(element) of csI: return val.containsTokenIgnoreCase(sel.value) of csS: return val.containsToken(sel.value) of rtBeginDash: let val = element.attr(sel.attr) case sel.attrCase(element) of csI: return val.startsWithIgnoreCase(sel.value) and (val.len <= sel.value.len or val[sel.value.len] == '-') of csS: return val.startsWith(sel.value) and (val.len <= sel.value.len or val[sel.value.len] == '-') of rtStartsWith: let val = element.attr(sel.attr) case sel.attrCase(element) of csI: return val.startsWithIgnoreCase(sel.value) of csS: return val.startsWith(sel.value) of rtEndsWith: let val = element.attr(sel.attr) case sel.attrCase(element) of csI: return val.endsWithIgnoreCase(sel.value) of csS: return val.endsWith(sel.value) of rtContains: let val = element.attr(sel.attr) case sel.attrCase(element) of csI: return sel.value.toLowerAscii() in val.toLowerAscii() of csS: return sel.value in val proc matches(element: Element; slist: SelectorList; depends: var DependencyInfo; ohasDeps: var bool): bool = var pmatch = false var rhasDeps = false for cxsel in slist: var hasDeps = false let match = element.matches(cxsel, depends, hasDeps) if not hasDeps: if match: return true if pmatch: # already seen a matching selector; merge depends and return # false. break else: rhasDeps = true pmatch = match ohasDeps = rhasDeps return pmatch proc matches(element: Element; pc: PseudoClass; depends: var DependencyInfo; hasDeps: var bool): bool = case pc of pcFirstChild: let parentNode = element.parentNode return parentNode != nil and parentNode.firstElementChild == element of pcLastChild: let parentNode = element.parentNode return parentNode != nil and parentNode.lastElementChild == element of pcFirstNode: return element.isFirstVisualNode() of pcLastNode: return element.isLastVisualNode() of pcOnlyChild: let parentNode = element.parentNode return parentNode != nil and parentNode.firstElementChild == element and parentNode.lastElementChild == element of pcHover: hasDeps = true depends.add(element, dtHover) return element.hover of pcRoot: return element == element.document.documentElement of pcChecked: if element of HTMLInputElement: hasDeps = true depends.add(element, dtChecked) return HTMLInputElement(element).checked elif element of HTMLOptionElement: hasDeps = true depends.add(element, dtChecked) return HTMLOptionElement(element).selected return false of pcFocus: hasDeps = true depends.add(element, dtFocus) return element.document.focus == element of pcTarget: hasDeps = true depends.add(element, dtTarget) return element.document.target == element of pcLink: return element.tagType in {TAG_A, TAG_AREA} and element.attrb(satHref) of pcVisited: return false of pcDisabled: return element.isDisabled() of pcBorderNonzero: return element.attrb(satBorder) and element.attrul(satBorder).get(1) != 0 of pcHost: return false #TODO shadow DOM of pcDefined: return element.isDefined() proc matchesLang(element: Element; lang: string): bool = for element in element.branchElems: if element.attrb(satLang): return element.attr(satLang) == lang false proc matchesNthChild(element: Element; nthChild: CSSNthChild; depends: var DependencyInfo; ohasDeps: var bool): bool = let parentNode = element.parentNode if parentNode == nil: return false let A = nthChild.anb.A # step let B = nthChild.anb.B # start if nthChild.ofsels.len == 0: let i = element.elIndex + 1 if A == 0: return i == B let j = (i - B) if A < 0: return j <= 0 and j mod A == 0 return j >= 0 and j mod A == 0 if element.matches(nthChild.ofsels, depends, ohasDeps): var i = 1 for child in parentNode.elementList: if child == element: if A == 0: return i == B let j = (i - B) if A < 0: return j <= 0 and j mod A == 0 return j >= 0 and j mod A == 0 var hasDeps = false if child.matches(nthChild.ofsels, depends, hasDeps): inc i ohasDeps = ohasDeps or hasDeps false proc matchesNthLastChild(element: Element; nthChild: CSSNthChild; depends: var DependencyInfo; ohasDeps: var bool): bool = let parentNode = element.parentNode if parentNode == nil: return false let A = nthChild.anb.A # step let B = nthChild.anb.B # start if nthChild.ofsels.len == 0: let last = element.parentNode.lastElementChild let i = last.elIndex + 1 - element.elIndex if A == 0: return i == B let j = (i - B) if A < 0: return j <= 0 and j mod A == 0 return j >= 0 and j mod A == 0 if element.matches(nthChild.ofsels, depends, ohasDeps): var i = 1 for child in parentNode.relementList: if child == element: if A == 0: return i == B let j = (i - B) if A < 0: return j <= 0 and j mod A == 0 return j >= 0 and j mod A == 0 var hasDeps: bool if child.matches(nthChild.ofsels, depends, hasDeps): inc i ohasDeps = ohasDeps or hasDeps false proc matches(element: Element; sel: Selector; depends: var DependencyInfo; ohasDeps: var bool): bool = case sel.t of stType: return element.localName == sel.tag of stClass: for it in element.classList: if sel.class == it.toLowerAscii(): return true return false of stId: return sel.id == element.id.toLowerAscii() of stAttr: return element.matchesAttr(sel) of stPseudoClass: return element.matches(sel.pc, depends, ohasDeps) of stUniversal: return true of stNthChild: return element.matchesNthChild(sel.nthChild, depends, ohasDeps) of stNthLastChild: return element.matchesNthLastChild(sel.nthChild, depends, ohasDeps) of stNot: return not element.matches(sel.fsels, depends, ohasDeps) of stIs, stWhere: return element.matches(sel.fsels, depends, ohasDeps) of stLang: return element.matchesLang(sel.lang) of stHost: return false #TODO shadow DOM proc matches(element: Element; sels: CompoundSelector; depends: var DependencyInfo; ohasDeps: var bool): bool = var pmatch = true for sel in sels: var hasDeps = false let match = element.matches(sel, depends, hasDeps) if not hasDeps: if not match: return false if not pmatch: # already seen a matching selector; merge depends and return # false. break else: ohasDeps = true pmatch = match return pmatch proc matches(element: Element; cxsel: ComplexSelector; depends: var DependencyInfo; ohasDeps: var bool): bool = var e = element var pmatch = true var mdepends = DependencyInfo.default for csel in cxsel.ritems: var match = false var hasDeps = false case csel.ct of ctNone: match = e.matches(csel, mdepends, hasDeps) of ctDescendant: e = e.parentElement while e != nil: if e.matches(csel, mdepends, hasDeps): match = true break e = e.parentElement of ctChild: e = e.parentElement match = e != nil and e.matches(csel, mdepends, hasDeps) of ctNextSibling: e = e.previousElementSibling match = e != nil and e.matches(csel, mdepends, hasDeps) of ctSubsequentSibling: var it = e.previousElementSibling while it != nil: if it.matches(csel, mdepends, hasDeps): e = it match = true break it = it.previousElementSibling if not hasDeps: if not match: return false # we can discard depends. if not pmatch: # already seen a non-matching selector; merge depends and return # false. break else: ohasDeps = true pmatch = match if e == nil: break depends.merge(mdepends) return pmatch # Note: this modifies "depends". proc matches*(element: Element; cxsel: ComplexSelector; depends: var DependencyInfo): bool = var dummy: bool return element.matches(cxsel, depends, dummy) # Forward declaration hack matchesImpl = proc(element: Element; slist: SelectorList): bool {.nimcall.} = var dummy = DependencyInfo.default var dummy2: bool return element.matches(slist, dummy, dummy2) {.pop.} # raises: [] ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/css/mediaquery.nim����������������������������������������������������������������0000664�0000000�0000000�00000034463�15202323131�0017375�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import config/conftypes import css/cssparser import css/cssvalues import html/catom import html/script import types/opt import types/winattrs import utils/dtoawrap import utils/twtstr type MediaQueryParser = object ctx: CSSParser attrs: ptr WindowAttributes MediaType = enum mtAll = "all" mtPrint = "print" mtScreen = "screen" mtSpeech = "speech" mtTty = "tty" MediaConditionType = enum mctNot, mctAnd, mctOr, mctFeature, mctMedia MediaFeatureType = enum mftColor = "color" mftColorIndex = "color-index" mftMonochrome = "monochrome" mftGrid = "grid" mftHover = "hover" mftPrefersColorScheme = "prefers-color-scheme" mftWidth = "width" mftHeight = "height" mftScripting = "scripting" mftContentType = "-cha-content-type" LengthRange = object s: Slice[float32] aeq: bool beq: bool MediaScripting = enum msNone = "none" msInitialOnly = "initial-only" msEnabled = "enabled" MediaFeature = object case t: MediaFeatureType of mftColor, mftColorIndex, mftMonochrome: range: Slice[int32] of mftGrid, mftHover, mftPrefersColorScheme: b: bool of mftScripting: ms: MediaScripting of mftWidth, mftHeight: lengthrange: LengthRange of mftContentType: a: CAtom MediaQuery* = ref object case t: MediaConditionType of mctMedia: media: MediaType of mctFeature: feature: MediaFeature of mctNot: n: MediaQuery of mctOr, mctAnd: left: MediaQuery right: MediaQuery MediaQueryComparison = enum mqcEq, mqcGt, mqcLt, mqcGe, mqcLe # Forward declarations proc parseMediaCondition(parser: var MediaQueryParser; non = false; noor = false; nested = false): Opt[MediaQuery] # Serializer. # As usual, the spec is incomplete, so it's hard to say if it's # compliant. What can you do :/ proc `$`(mf: MediaFeature): string = case mf.t of mftColor, mftColorIndex, mftMonochrome: return $mf.range.a & " <= " & $mf.t & " <= " & $mf.range.b of mftGrid: return "grid: " & $int(mf.b) of mftHover: return "hover: " & [false: "none", true: "hover"][mf.b] of mftPrefersColorScheme: return "prefers-color-scheme: " & [false: "light", true: "dark"][mf.b] of mftWidth, mftHeight: result = dtoa(mf.lengthrange.s.a) & " <" if mf.lengthrange.aeq: result &= '=' result &= ' ' & $mf.t & " <" if mf.lengthrange.beq: result &= '=' result &= ' ' result.addDouble(mf.lengthrange.s.b) of mftScripting: return "scripting: " & $mf.ms of mftContentType: return $mf.t & ": \"" & ($mf.a).dqEscape() & '"' proc `$`(mq: MediaQuery): string = case mq.t of mctMedia: return $mq.media of mctFeature: return $mq.feature of mctNot: return "not (" & $mq.n & ")" of mctOr: return "(" & $mq.left & ") or (" & $mq.right & ")" of mctAnd: return "(" & $mq.left & ") or (" & $mq.right & ")" proc `$`*(mqlist: seq[MediaQuery]): string = result = "" for it in mqlist: if result.len > 0: result &= ", " result &= $it const RangeFeatures = { mftColor, mftColorIndex, mftMonochrome, mftWidth, mftHeight } proc has(parser: var MediaQueryParser): bool = return parser.ctx.has() proc consume(parser: var MediaQueryParser): CSSToken = return parser.ctx.consume() proc peekTokenType(parser: var MediaQueryParser): CSSTokenType = return parser.ctx.peekTokenType() proc seek(parser: var MediaQueryParser) = parser.ctx.seek() proc skipBlanks(parser: var MediaQueryParser) = parser.ctx.skipBlanks() proc getBoolFeature(feature: MediaFeatureType): Opt[MediaQuery] = case feature of mftGrid, mftHover, mftPrefersColorScheme: return ok(MediaQuery( t: mctFeature, feature: MediaFeature(t: feature, b: true) )) of mftColor, mftColorIndex, mftMonochrome: return ok(MediaQuery( t: mctFeature, feature: MediaFeature(t: feature, range: 1i32 .. int32.high) )) else: return err() proc skipBlanksCheckHas(parser: var MediaQueryParser): Opt[void] = parser.skipBlanks() if parser.has(): return ok() return err() proc consumeIdent(parser: var MediaQueryParser): Opt[CSSToken] = if parser.peekTokenType() != cttIdent: return err() return ok(parser.consume()) proc consumeString(parser: var MediaQueryParser): Opt[CSSToken] = if parser.peekTokenType() != cttString: return err() return ok(parser.consume()) proc consumeInt(parser: var MediaQueryParser): Opt[int32] = parser.ctx.consumeInt() proc parseMqInt(parser: var MediaQueryParser; ifalse, itrue: int32): Opt[bool] = let i = ?parser.consumeInt() if i == ifalse: return ok(false) elif i == itrue: return ok(true) return err() proc parseBool(parser: var MediaQueryParser; sfalse, strue: string): Opt[bool] = let tok = ?parser.consumeIdent() if tok.s.equalsIgnoreCase(strue): return ok(true) elif tok.s.equalsIgnoreCase(sfalse): return ok(false) else: return err() proc parseComparison(parser: var MediaQueryParser): Opt[MediaQueryComparison] = let tok = parser.consume() case tok.t of cttLt: if parser.skipBlanksCheckHas().isOk: if parser.peekTokenType() == cttEquals: discard parser.consume() return ok(mqcLe) return ok(mqcLt) of cttGt: if parser.skipBlanksCheckHas().isOk: if parser.peekTokenType() == cttEquals: discard parser.consume() return ok(mqcGe) return ok(mqcGt) of cttEquals: return ok(mqcEq) else: return err() proc parseIntRange(parser: var MediaQueryParser; ismin, ismax: bool): Opt[Slice[int32]] = if ismin: let a = ?parser.consumeInt() return ok(a .. int32.high) if ismax: let b = ?parser.consumeInt() return ok(0i32 .. b) let comparison = ?parser.parseComparison() ?parser.skipBlanksCheckHas() let n = ?parser.consumeInt() case comparison of mqcEq: #TODO should be >= 0 (for color at least) return ok(n .. n) of mqcGt, mqcGe: return ok(n .. int32.high) of mqcLt, mqcLe: return ok(0i32 .. n) proc parseLength(parser: var MediaQueryParser): Opt[float32] = let len = ?parser.ctx.parseLength(parser.attrs[], hasAuto = false, allowNegative = true) if len.auto or len.perc != 0: return err() return ok(len.npx) proc parseLengthRange(parser: var MediaQueryParser; ismin, ismax: bool): Opt[LengthRange] = if ismin: let a = ?parser.parseLength() return ok(LengthRange(s: a .. float32(Inf), aeq: true, beq: false)) if ismax: let b = ?parser.parseLength() return ok(LengthRange(s: 0f32 .. b, aeq: false, beq: true)) let comparison = ?parser.parseComparison() ?parser.skipBlanksCheckHas() let len = ?parser.parseLength() case comparison of mqcEq: return ok(LengthRange(s: len .. len, aeq: true, beq: true)) of mqcGt, mqcGe: let b = float32(Inf) return ok(LengthRange(s: len .. b, aeq: comparison == mqcGe, beq: false)) of mqcLt, mqcLe: return ok(LengthRange(s: 0f32 .. len, aeq: false, beq: comparison == mqcLe)) proc parseFeature0(parser: var MediaQueryParser; t: MediaFeatureType; ismin, ismax: bool): Opt[MediaFeature] = let feature = case t of mftGrid: let b = ?parser.parseMqInt(0, 1) MediaFeature(t: t, b: b) of mftHover: let b = ?parser.parseBool("none", "hover") MediaFeature(t: t, b: b) of mftPrefersColorScheme: let b = ?parser.parseBool("light", "dark") MediaFeature(t: t, b: b) of mftColor, mftColorIndex, mftMonochrome: let range = ?parser.parseIntRange(ismin, ismax) MediaFeature(t: t, range: range) of mftWidth, mftHeight: let range = ?parser.parseLengthRange(ismin, ismax) MediaFeature(t: t, lengthrange: range) of mftScripting: if ismin or ismax: return err() let tok = ?parser.consumeIdent() let ms = ?parseEnumNoCase[MediaScripting](tok.s) MediaFeature(t: t, ms: ms) of mftContentType: let tok = ?parser.consumeString() MediaFeature(t: t, a: tok.s.toAtom()) return ok(feature) proc parseFeature(parser: var MediaQueryParser; t: MediaFeatureType; ismin, ismax: bool): Opt[MediaQuery] = if not parser.has(): return err() let nt = parser.peekTokenType() if nt == cttRparen: let res = ?getBoolFeature(t) parser.seek() return ok(res) if t notin RangeFeatures and (nt != cttColon or ismin or ismax): return err() if nt == cttColon: # for range parsing; e.g. we might have gotten a delim or similar discard parser.consume() ?parser.skipBlanksCheckHas() let feature = ?parser.parseFeature0(t, ismin, ismax) ?parser.skipBlanksCheckHas() if parser.consume().t != cttRparen: # die if there's still something left to parse return err() return ok(MediaQuery(t: mctFeature, feature: feature)) proc parseMediaInParens(parser: var MediaQueryParser): Opt[MediaQuery] = if parser.consume().t != cttLparen: return err() ?parser.skipBlanksCheckHas() let tok = ?parser.consumeIdent() parser.skipBlanks() if tok.s.equalsIgnoreCase("not"): return parser.parseMediaCondition(non = true, nested = true) var tokval = tok.s let ismin = tokval.startsWithIgnoreCase("min-") let ismax = tokval.startsWithIgnoreCase("max-") if ismin or ismax: tokval = tokval.substr(4) let t = ?parseEnumNoCase[MediaFeatureType](tokval) parser.parseFeature(t, ismin, ismax) proc parseMediaOr(parser: var MediaQueryParser; left: MediaQuery): Opt[MediaQuery] = let right = ?parser.parseMediaCondition(nested = true) return ok(MediaQuery(t: mctOr, left: left, right: right)) proc parseMediaAnd(parser: var MediaQueryParser; left: MediaQuery; noor = false): Opt[MediaQuery] = let right = ?parser.parseMediaCondition(noor = noor, nested = true) return ok(MediaQuery(t: mctAnd, left: left, right: right)) proc negateIf(mq: MediaQuery; non: bool): MediaQuery = if non: return MediaQuery(t: mctNot, n: mq) return mq proc parseMediaCondition(parser: var MediaQueryParser; non = false; noor = false; nested = false): Opt[MediaQuery] = var non = non if not non: if parser.ctx.peekIdentNoCase("not"): discard parser.consume() non = true ?parser.skipBlanksCheckHas() let res = (?parser.parseMediaInParens()).negateIf(non) if parser.skipBlanksCheckHas().isErr: return ok(res) let tok = ?parser.consumeIdent() parser.skipBlanks() if tok.s.equalsIgnoreCase("and"): return parser.parseMediaAnd(res, noor) elif tok.s.equalsIgnoreCase("or"): if noor: return err() return parser.parseMediaOr(res) err() proc parseMediaQuery(parser: var MediaQueryParser): Opt[MediaQuery] = ?parser.skipBlanksCheckHas() let tokx = parser.consumeIdent() if tokx.isErr: return parser.parseMediaCondition() let tok = tokx.get if (let non = tok.s.equalsIgnoreCase("not"); non or tok.s.equalsIgnoreCase("only")): ?parser.skipBlanksCheckHas() if tok := parser.consumeIdent(): if media := parseEnumNoCase[MediaType](tok.s): let res = MediaQuery(t: mctMedia, media: media).negateIf(non) if parser.skipBlanksCheckHas().isErr: return ok(res) let tok = ?parser.consumeIdent() if tok.s.equalsIgnoreCase("and"): ?parser.skipBlanksCheckHas() return parser.parseMediaAnd(res) return err() return parser.parseMediaCondition(non) elif media := parseEnumNoCase[MediaType](tok.s): let res = MediaQuery(t: mctMedia, media: media) if parser.skipBlanksCheckHas().isErr: return ok(res) let tok = ?parser.consumeIdent() if tok.s.equalsIgnoreCase("and"): return parser.parseMediaAnd(res, noor = true) return err() proc parseMediaQueryList*(ctx: var CSSParser; attrs: ptr WindowAttributes): seq[MediaQuery] = result = @[] while ctx.has(): var s: seq[CSSToken] = @[] discard ctx.addUntil(cttComma, s) var parser = MediaQueryParser(ctx: initCSSParserSink(s), attrs: attrs) if query := parser.parseMediaQuery(): result.add(query) else: # sadly, the standard doesn't let us skip this :/ #TODO but it seems Blink does something else nevertheless o_0 let all = MediaQuery(t: mctMedia, media: mtAll) result.add(MediaQuery(t: mctNot, n: all)) type MediaApplyContext = object env: ptr EnvironmentSettings attrsp: ptr WindowAttributes proc appliesLR(feature: MediaFeature; n: float32): bool = let a = feature.lengthrange.s.a let b = feature.lengthrange.s.b return (feature.lengthrange.aeq and a == n or a < n) and (feature.lengthrange.beq and b == n or n < b) proc applies(ctx: MediaApplyContext; feature: MediaFeature): bool = case feature.t of mftColor: let bitDepth = if ctx.attrsp.colorMode != cmMonochrome: 8 else: 0 return bitDepth in feature.range of mftColorIndex: let mapSize = case ctx.attrsp.colorMode of cmANSI: 16 of cmEightBit: 256 of cmMonochrome, cmTrueColor: 0 return mapSize in feature.range of mftMonochrome: let bitDepth = if ctx.attrsp.colorMode == cmMonochrome: 1 else: 0 return bitDepth in feature.range of mftGrid: return feature.b of mftHover: return feature.b of mftPrefersColorScheme: return feature.b == ctx.attrsp.prefersDark of mftWidth: return feature.appliesLR(float32(ctx.attrsp.widthPx)) of mftHeight: return feature.appliesLR(float32(ctx.attrsp.heightPx)) of mftScripting: case feature.ms of msNone: return ctx.env.scripting == smFalse of msInitialOnly: return ctx.env.scripting != smFalse and ctx.env.headless == hmDump of msEnabled: return ctx.env.scripting != smFalse and ctx.env.headless != hmDump of mftContentType: return ctx.env.contentType.equalsIgnoreCase(feature.a) proc applies(ctx: MediaApplyContext; mq: MediaQuery): bool = case mq.t of mctMedia: return mq.media in {mtAll, mtScreen, mtTty} of mctNot: return not ctx.applies(mq.n) of mctAnd: return ctx.applies(mq.left) and ctx.applies(mq.right) of mctOr: return ctx.applies(mq.left) or ctx.applies(mq.right) of mctFeature: return ctx.applies(mq.feature) proc applies(ctx: MediaApplyContext; mqlist: seq[MediaQuery]): bool = for mq in mqlist: if ctx.applies(mq): return true return false proc applies*(mqlist: seq[MediaQuery]; env: ptr EnvironmentSettings): bool = let ctx = MediaApplyContext(env: env, attrsp: env.attrsp) return ctx.applies(mqlist) proc appliesScript*(mqlist: seq[MediaQuery]; env: ptr EnvironmentSettings): bool = let ctx = MediaApplyContext(env: env, attrsp: env.scriptAttrsp) return ctx.applies(mqlist) {.pop.} # raises: [] �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/css/render.nim��������������������������������������������������������������������0000664�0000000�0000000�00000064106�15202323131�0016504�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import css/box import css/cssvalues import css/lunit import html/dom import types/bitmap import types/cell import types/color import types/winattrs import utils/strwidth import utils/twtstr type # A FormatCell *starts* a new terminal formatting context. # If no FormatCell exists before a given cell, the default formatting is used. FormatCell* = object format*: Format pos*: int node*: Element # Following properties should hold for `formats': # * Position should be >= 0, <= str.width(). # * The position of every FormatCell should be greater than the position # of the previous FormatCell. FlexibleLine* = object str*: string formats*: seq[FormatCell] FlexibleGrid* = seq[FlexibleLine] PosBitmap* = ref object x*: int y*: int offx*: int offy*: int width*: int height*: int bmp*: NetworkBitmap RenderState = object bgcolor: CellColor images: seq[PosBitmap] spaces: string # buffer filled with spaces for padding cellSize: Size # size(w = attrs.ppc, h = attrs.ppl) # Forward declarations proc renderBlock(grid: var FlexibleGrid; state: var RenderState; box: BlockBox; offset: Offset; pass2 = false) proc findFormatN*(line: FlexibleLine; pos: int; start = 0): int = var i = start while i < line.formats.len: if line.formats[i].pos > pos: break inc i return i proc insertFormat(line: var FlexibleLine; i: int; cell: FormatCell) = line.formats.insert(cell, i) proc insertFormat(line: var FlexibleLine; pos, i: int; format: Format; node: Element) = line.insertFormat(i, FormatCell(format: format, node: node, pos: pos)) proc toFormat(computed: CSSValues): Format = if computed == nil: return Format() var flags: set[FormatFlag] = {} if computed{"font-style"} in {FontStyleItalic, FontStyleOblique}: flags.incl(ffItalic) if computed{"font-weight"} > 500: flags.incl(ffBold) if TextDecorationUnderline in computed{"text-decoration"}: flags.incl(ffUnderline) if TextDecorationOverline in computed{"text-decoration"}: flags.incl(ffOverline) if TextDecorationLineThrough in computed{"text-decoration"}: flags.incl(ffStrike) if TextDecorationBlink in computed{"text-decoration"}: flags.incl(ffBlink) if TextDecorationReverse in computed{"text-decoration"}: flags.incl(ffReverse) #TODO this ignores alpha; we should blend somewhere. return initFormat(defaultColor, computed{"color"}.cellColor(), flags) proc findFirstX(line: var FlexibleLine; x: int; outi: var int): int = var cx = 0 var i = 0 while cx < x and i < line.str.len: let pi = i let u = line.str.nextUTF8(i) let w = u.width() # we must ensure x is max(cx, x), otherwise our assumption of cx <= x # breaks down if cx + w > x: i = pi break cx += w outi = i return cx proc setTextStr(line: var FlexibleLine; s: openArray[char]; i, j, x, cx, nx, targetX: int) = var i = i let padlen = i + x - cx var widthError = max(nx - targetX, 0) let targeti = padlen + s.len let remainingLen = line.str.len - j let nj = targeti + widthError let nlen = nj + remainingLen if remainingLen > 0: # we are overprinting *some* text, but the rest remains and must be # moved to the right place. # if the new offset is smaller, this must happen before the resize so # the data isn't destroyed. otherwise it must happen afterwards so we # have enough space. if nj < j: moveMem(addr line.str[nj], unsafeAddr line.str[j], remainingLen) line.str.setLen(nlen) if nj > j: moveMem(addr line.str[nj], unsafeAddr line.str[j], remainingLen) else: line.str.setLen(nlen) while i < padlen: # place before new string line.str[i] = ' ' inc i copyMem(addr line.str[i], unsafeAddr s[0], s.len) i = targeti while widthError > 0: # we ate half of a double width char; pad it out with spaces. line.str[i] = ' ' dec widthError inc i proc setTextFormat(line: var FlexibleLine; x, cx, targetX, nx: int; hadStr: bool; format: Format; node: Element) = var fi = line.findFormatN(cx) - 1 # Skip unchanged formats before new string var lformat = initFormat() var lnode: Element = nil if fi != -1: # Start by saving the old formatting before padding for later use. # This is important because the following code will gladly overwrite # said formatting. lformat = line.formats[fi].format # save for later use lnode = line.formats[fi].node if x > cx: # Amend formatting for padding. # Since we only generate padding in place of non-existent text, it # should be enough to just append a single format cell to erase the # last one's effect. # (This means that if fi is -1, we have nothing to erase -> # nothing to do.) let pos = line.formats[fi].pos if pos == cx: # This branch is only taken if we are overwriting a double-width # char. Then it is possible to get a single blank cell of # padding affected by the old formatting. # In this case, we must copy the bgcolor as well; in the other # branch this isn't necessary because paintBackground adds # padding anyway. line.formats[fi] = FormatCell( format: initFormat(lformat.bgcolor, defaultColor, {}), pos: cx ) else: # First format < cx => split it up assert pos < cx inc fi # insert after first format line.insertFormat(cx, fi, initFormat(), nil) # Now for the text's formats: var format = format if fi == -1: # No formats => just insert a new format at 0 inc fi line.insertFormat(x, fi, format, node) else: # First format's pos may be == x here. if line.formats[fi].pos == x: # Replace. # We must check if the old string's last x position is greater than # the new string's first x position. If not, we cannot inherit # its bgcolor (which is supposed to end before the new string started.) if nx > x: format.bgcolor = lformat.bgcolor line.formats[fi] = FormatCell(format: format, node: node, pos: x) else: # First format's pos < x => split it up. assert line.formats[fi].pos < x if nx > x: # see above format.bgcolor = lformat.bgcolor inc fi # insert after first format line.insertFormat(x, fi, format, node) if nx > x and nx < targetX and fi == line.formats.high: # The old format's background is bleeding into ours. If this was # the last format, we must preserve it. inc fi format.bgcolor = defaultColor line.insertFormat(nx, fi, format, node) inc fi # skip last format while fi < line.formats.len and line.formats[fi].pos < targetX: # Other formats must be > x => replace them format.bgcolor = line.formats[fi].format.bgcolor let px = line.formats[fi].pos lformat = line.formats[fi].format # save for later use lnode = line.formats[fi].node line.formats[fi] = FormatCell(format: format, node: node, pos: px) inc fi if hadStr: # If nx > targetX, we are overwriting a double-width character; then # we want the next formatting to apply from the end of said character. let ostrx = max(nx, targetX) if fi >= line.formats.len or line.formats[fi].pos > ostrx: # targetX < ostr.width, but we have removed all formatting in the # range of our string, and no formatting comes directly after it. So # we insert the continuation of the last format we replaced after # our string. (Default format when we haven't replaced anything.) line.insertFormat(ostrx, fi, lformat, lnode) else: if fi == line.formats.len: # We have skipped all formats. There are two cases: # a) Our text overwrites the old text, but ends at the same x position # as the old text. Then, the last format's background is correct, # nothing to do. # b) The old text is shorter than ours. We must add a new format to # restore the background of the chunk that was not covered. if nx < targetX and format.bgcolor != defaultColor: format.bgcolor = defaultColor line.insertFormat(nx, fi, format, node) dec fi # go back to previous format, so that pos <= targetX assert line.formats[fi].pos <= targetX # That's it! proc setText0(line: var FlexibleLine; s: openArray[char]; x, targetX: int; ocx, onx: var int; hadStr: var bool) = var i = 0 let cx = line.findFirstX(x, i) # first x of new string (before padding) var j = i var nx = cx # last x of new string *before the end of the old string* # (nx starts from cx, not x; we are still advancing in the old string) while nx < targetX and j < line.str.len: nx += line.str.nextUTF8(j).width() ocx = cx onx = nx hadStr = j < line.str.len line.setTextStr(s, i, j, x, cx, nx, targetX) proc setText1(line: var FlexibleLine; s: openArray[char]; x, targetX: int; format: Format; node: Element) = assert x >= 0 and s.len != 0 var cx: int var nx: int var hadStr: bool line.setText0(s, x, targetX, cx, nx, hadStr) line.setTextFormat(x, cx, targetX, nx, hadStr, format, node) proc setText(grid: var FlexibleGrid; state: var RenderState; s: string; offset: Offset; format: Format; node: Element; clipBox: ClipBox) = if offset.y notin clipBox.start.y ..< clipBox.send.y: return if offset.x > clipBox.send.x: return let rx = offset.x div state.cellSize.w var x = rx.toInt # Give room for rounding errors. let sx = max((clipBox.start.x div state.cellSize.w).toInt, 0) var i = 0 while x < sx and i < s.len: x += s.nextUTF8(i).width() if x < sx: # highest x is outside the clipping box, no need to draw return let diff = rx - x.toLUnit() let ppc2 = state.cellSize.w div 2'lu let ex = ((clipBox.send.x + ppc2 - diff) div state.cellSize.w).toInt var j = i var targetX = x while targetX < ex and j < s.len: targetX += s.nextUTF8(j).width() if i < j: let y = (offset.y div state.cellSize.h).toInt # make sure we have line y if grid.len < y + 1: grid.setLen(y + 1) grid[y].setText1(s.toOpenArray(i, j - 1), x, targetX, format, node) proc clip(clipBox: ClipBox; state: RenderState; start, send: Offset): tuple[start, send: Offset] = var startx = start.x var starty = start.y var endx = send.x var endy = send.y if starty > endy: swap(starty, endy) if startx > endx: swap(startx, endx) return ( offset(x = max(startx, clipBox.start.x), y = max(starty, clipBox.start.y)), offset(x = min(endx, clipBox.send.x), y = min(endy, clipBox.send.y)) ) proc paintBackground(grid: var FlexibleGrid; state: var RenderState; color: CellColor; start, send: Offset; node: Element; alpha: uint8; clipBox: ClipBox) = let (start, send) = clipBox.clip(state, start, send) let startx = (start.x div state.cellSize.w).toInt() let starty = (start.y div state.cellSize.h).toInt() let endx = (send.x div state.cellSize.w).toInt() let endy = (send.y div state.cellSize.h).toInt() if starty >= endy or startx >= endx: return if grid.len < endy: # make sure we have line y - 1 grid.setLen(endy) var format = initFormat(color, defaultColor, {}) for line in grid.toOpenArray(starty, endy - 1).mitems: # Make sure line.width() >= endx var hadStr: bool var cx: int if alpha < 255: # If the background is not fully opaque, then text under it is # preserved. let w = line.str.width() for i in w ..< endx: line.str &= ' ' cx = min(w, startx) hadStr = w > endx else: # Otherwise, background overpaints old text. let w = endx - startx while state.spaces.len < w: state.spaces &= ' ' var nx: int line.setText0(state.spaces.toOpenArray(0, w - 1), startx, endx, cx, nx, hadStr) # Process formatting around startx var sfi = line.findFormatN(startx) - 1 if sfi == -1: # No format <= startx line.insertFormat(startx, 0, initFormat(), nil) inc sfi elif line.formats[sfi].pos == startx: # Last format equals startx => next comes after, nothing to be done discard else: # Last format lower than startx => separate format from startx if cx < startx and sfi == line.formats.high: inc sfi line.insertFormat(cx, sfi, initFormat(), nil) var copy = line.formats[sfi] inc sfi copy.pos = startx line.insertFormat(sfi, copy) # Paint format backgrounds between startx and endx var lformat = initFormat() var lnode: Element = nil var ifi = 0 for fi, it in line.formats.toOpenArray(sfi, line.formats.high).mpairs: if it.pos >= endx: break lformat = it.format lnode = it.node if alpha == 0: discard elif alpha == 255: it.format = format else: it.format.bgcolor = it.format.bgcolor.blend(state.bgcolor, color, alpha) it.node = node ifi = fi # Process formatting around endx let efi = line.findFormatN(endx, ifi) - 1 if efi != -1 and line.formats[efi].pos < endx and hadStr: assert line.formats[efi].pos < endx line.insertFormat(endx, efi + 1, lformat, lnode) proc paintInlineBox(grid: var FlexibleGrid; state: var RenderState; box: InlineBox; offset: Offset; bgcolor: CellColor; alpha: uint8) = for area in box.state.areas: let offset = offset + area.offset grid.paintBackground(state, bgcolor, offset, offset + area.size, box.element, alpha, box.render.clipBox) proc renderImage(grid: var FlexibleGrid; state: var RenderState; box: BlockBox; offset: Offset) = let bmp = box.getBitmap() if bmp == nil: return let clipBox = box.render.clipBox let padding = box.input.padding #TODO we have to add/subtract padding here, but it's very ugly... let offset = offset + padding.topLeft() let size = box.state.size - padding.sum() let p2 = offset + size #TODO implement proper image clipping if offset.x < clipBox.send.x and offset.y < clipBox.send.y and p2.x >= clipBox.start.x and p2.y >= clipBox.start.y: # add Element to background (but don't actually color it) grid.paintBackground(state, defaultColor, offset, p2, box.element, 0, box.render.clipBox) let x = (offset.x div state.cellSize.w).toInt let y = (offset.y div state.cellSize.h).toInt let offx = (offset.x - x.toLUnit * state.cellSize.w).toInt let offy = (offset.y - y.toLUnit * state.cellSize.h).toInt state.images.add(PosBitmap( x: x, y: y, offx: offx, offy: offy, width: size.w.toInt, height: size.h.toInt, bmp: bmp )) proc renderInline(grid: var FlexibleGrid; state: var RenderState; ibox: InlineBox; offset: Offset; bgcolor0 = rgba(0, 0, 0, 0); pass2 = false) = let clipBox = if ibox.parent != nil: ibox.parent.render.clipBox else: DefaultClipBox ibox.render = BoxRenderState( offset: offset + ibox.state.startOffset, clipBox: clipBox, positioned: true ) let bgcolor = ibox.computed{"background-color"} var bgcolor0 = bgcolor0 if bgcolor.t == cctCell: let bgcolor = bgcolor.cellColor() if bgcolor.t != ctNone: grid.paintInlineBox(state, ibox, offset, bgcolor, 255) else: bgcolor0 = bgcolor0.blend(bgcolor.argb) if bgcolor0.a > 0: grid.paintInlineBox(state, ibox, offset, bgcolor0.rgb.cellColor(), bgcolor0.a) if ibox of InlineTextBox: let ibox = InlineTextBox(ibox) if ibox.computed{"visibility"} != VisibilityVisible: return let format = ibox.computed.toFormat() for run in ibox.runs: let offset = offset + run.offset grid.setText(state, run.s, offset, format, ibox.element, clipBox) else: # InlineNewLineBox does not have children, so we handle it here # only check position here to avoid skipping leaves that use our # computed values if ibox.positioned and not pass2: return for child in ibox.children: if child of InlineBox: grid.renderInline(state, InlineBox(child), offset, bgcolor0) else: grid.renderBlock(state, BlockBox(child), offset) proc inheritClipBox(box: BlockBox; parent: CSSBox; state: RenderState) = if parent == nil: box.render.clipBox = DefaultClipBox return assert parent.render.positioned var clipBox = parent.render.clipBox let overflowX = box.computed{"overflow-x"} let overflowY = box.computed{"overflow-y"} if overflowX != OverflowVisible or overflowY != OverflowVisible: var offset = box.render.offset var size = box.state.size let topLeft = box.input.borderTopLeft(state.cellSize) offset -= topLeft size += topLeft size += box.input.borderBottomRight(state.cellSize) if overflowX in OverflowHiddenLike: clipBox.start.x = max(offset.x, clipBox.start.x) clipBox.send.x = min(offset.x + size.w, clipBox.send.x) else: # scroll like clipBox.start.x = max(min(offset.x, clipBox.start.x), 0'lu) clipBox.send.x = max(offset.x + size.w, clipBox.send.x) if overflowY in OverflowHiddenLike: clipBox.start.y = max(offset.y, clipBox.start.y) clipBox.send.y = min(offset.y + size.h, clipBox.send.y) box.render.clipBox = clipBox proc paintBorder(grid: var FlexibleGrid; state: var RenderState; start, send: Offset; box: BlockBox) = let start = start - state.cellSize let send = send + state.cellSize let startx = (start.x div state.cellSize.w).toInt() let starty = (start.y div state.cellSize.h).toInt() let endx = (send.x div state.cellSize.w).toInt() var endy = (send.y div state.cellSize.h).toInt() var buf = "" var top = box.input.border.top var bottom = box.input.border.bottom var left = box.input.border.left var right = box.input.border.right let colorTop = box.computed{"border-top-color"} let colorBottom = box.computed{"border-bottom-color"} let colorLeft = box.computed{"border-left-color"} let colorRight = box.computed{"border-right-color"} let hasLeft = left notin BorderStyleNoneHidden and not colorLeft.rgbTransparent let hasRight = right notin BorderStyleNoneHidden and not colorRight.rgbTransparent if top notin BorderStyleNoneHidden and not colorTop.rgbTransparent: var offset = start if hasLeft: if box.state.merge[dtHorizontal]: if box.state.merge[dtVertical]: buf &= top.borderChar(bdcSideBarCross) else: buf &= top.borderChar(bdcSideBarTop) else: if box.state.merge[dtVertical]: buf &= left.borderChar(bdcSideBarLeft) else: buf &= left.borderChar(bdcCornerTopLeft) else: offset.x += state.cellSize.w for i in startx + 1 ..< endx - 1: buf &= top.borderChar(bdcHorizontalBarTop) if hasRight: if box.state.merge[dtVertical]: buf &= right.borderChar(bdcSideBarRight) else: buf &= top.borderChar(bdcCornerTopRight) let format = initFormat(defaultColor, colorTop.cellColor(), {}) grid.setText(state, buf, offset, format, box.element, box.render.clipBox) buf.setLen(0) if hasLeft or hasRight: buf &= left.borderChar(bdcVerticalBarLeft) let rbuf = right.borderChar(bdcVerticalBarRight) var soff = start var eoff = send eoff.x -= state.cellSize.w let formatLeft = initFormat(defaultColor, colorLeft.cellColor(), {}) let formatRight = initFormat(defaultColor, colorRight.cellColor(), {}) for y in starty + 1 ..< endy - 1: let sy = y.toLUnit() * state.cellSize.h if hasLeft: soff.y = sy grid.setText(state, buf, soff, formatLeft, nil, box.render.clipBox) if hasRight: eoff.y = sy grid.setText(state, rbuf, eoff, formatRight, nil, box.render.clipBox) buf.setLen(0) if bottom notin BorderStyleNoneHidden and not colorBottom.rgbTransparent: let proprietary = bottom in BorderStyleInput var offset = offset(x = start.x, y = send.y - state.cellSize.h) if hasLeft and not proprietary: if box.state.merge[dtHorizontal]: buf &= bottom.borderChar(bdcSideBarBottom) else: buf &= bottom.borderChar(bdcCornerBottomLeft) else: offset.x += state.cellSize.w if bottom == BorderStylePeriod: # proprietary too var n = 0u for i in startx + 1 ..< endx - 1: if n mod 2 == 0: buf &= ' ' else: buf &= '.' inc n else: for i in startx + 1 ..< endx - 1: buf &= bottom.borderChar(bdcHorizontalBarBottom) if right notin BorderStyleNoneHidden and not proprietary: buf &= bottom.borderChar(bdcCornerBottomRight) var flags: set[FormatFlag] = {} if proprietary: offset.y -= state.cellSize.h if bottom != BorderStyleHash: flags.incl(ffUnderline) let format = initFormat(defaultColor, colorBottom.cellColor(), flags) grid.setText(state, buf, offset, format, box.element, box.render.clipBox) proc renderBlock(grid: var FlexibleGrid; state: var RenderState; box: BlockBox; offset: Offset; pass2 = false) = if box.positioned and not pass2: return let offset = offset + box.state.offset if not pass2: box.render.offset = offset box.render.positioned = true box.inheritClipBox(box.parent, state) let opacity = box.computed{"opacity"} if box.computed{"visibility"} == VisibilityVisible and opacity != 0: grid.renderImage(state, box, offset) #TODO maybe blend with the terminal background? let bgcolor0 = box.computed{"background-color"} let bgcolor = bgcolor0.cellColor() let endOffset = offset + box.state.size if bgcolor != defaultColor: if box.computed{"-cha-bgcolor-is-canvas"} and state.bgcolor == defaultColor: #TODO bgimage # note: this eats the alpha state.bgcolor = bgcolor else: grid.paintBackground(state, bgcolor, offset, endOffset, box.element, bgcolor0.a, box.render.clipBox) grid.paintBorder(state, offset, endOffset, box) if box.computed{"background-image"} != nil: # ugly hack for background-image display... TODO actually display images const s = "[img]" let w = s.len.toLUnit() * state.cellSize.w var offset = offset if box.state.size.w < w: # text is larger than image; center it to minimize error offset.x -= w div 2'lu offset.x += box.state.size.w div 2'lu grid.setText(state, s, offset, box.computed.toFormat(), box.element, box.render.clipBox) if opacity != 0: #TODO this isn't right... if box.render.clipBox.start < box.render.clipBox.send: for child in box.children: if child of InlineBox: grid.renderInline(state, InlineBox(child), offset) else: grid.renderBlock(state, BlockBox(child), offset) # This function exists to support another insane CSS construct: negative # z-index. # The issue here is that their position depends on their parent, but the # parent box is very often not positioned yet. So we brute-force our # way out of the problem by resolving the parent box's position here. # The algorithm itself is mildly confusing because we must skip # InlineBox offsets in the process - this means that there may be inline # boxes after this pass with an unresolved position which contain block # boxes with a resolved position. proc resolveBlockOffset(box: CSSBox; state: RenderState): Offset = var dims: set[DimensionType] = {} let absolute = box.positioned and box.computed{"position"} == PositionAbsolute let absoluteOrFixed = box.positioned and box.computed{"position"} in PositionAbsoluteFixed if absoluteOrFixed: if not box.computed{"left"}.auto or not box.computed{"right"}.auto: dims.incl(dtHorizontal) if not box.computed{"top"}.auto or not box.computed{"bottom"}.auto: dims.incl(dtVertical) var clipAncestor: BlockBox = nil var it = box.parent var absAncestor: CSSBox = nil var toPosition: seq[CSSBox] = @[] var parent: CSSBox = nil var offset = Offset0 while it != nil: if absolute and it.positioned and absAncestor == nil: absAncestor = it # record first absolute ancestor if it of BlockBox: let it = BlockBox(it) if clipAncestor == nil and (not absolute or it.positioned or it.parent == nil): clipAncestor = it if it.render.positioned and (not absolute or absAncestor != nil): offset = it.render.offset break toPosition.add(it) it = it.parent for it in toPosition.ritems: if it of InlineBox: let it = InlineBox(it) it.render = BoxRenderState( offset: offset + it.state.startOffset, clipBox: if parent != nil: parent.render.clipBox else: DefaultClipBox, positioned: true ) else: let it = BlockBox(it) offset += it.state.offset it.render = BoxRenderState( offset: offset, clipBox: DefaultClipBox, positioned: true ) it.inheritClipBox(parent, state) parent = it var absOffset = Offset0 if absAncestor != nil: absOffset = absAncestor.render.offset for dim in DimensionType: if dim in dims: offset[dim] = absOffset[dim] if box of BlockBox: let box = BlockBox(box) box.render = BoxRenderState( positioned: true, offset: offset + box.state.offset, clipBox: DefaultClipBox ) box.inheritClipBox(clipAncestor, state) return offset proc renderPositioned(grid: var FlexibleGrid; state: var RenderState; box: CSSBox) = let offset = box.resolveBlockOffset(state) if box of BlockBox: grid.renderBlock(state, BlockBox(box), offset, pass2 = true) else: grid.renderInline(state, InlineBox(box), offset, pass2 = true) proc renderStack(grid: var FlexibleGrid; state: var RenderState; stack: StackItem) = var i = 0 # negative z-index while i < stack.children.len: let it = stack.children[i] if it.index >= 0: break grid.renderStack(state, it) inc i grid.renderPositioned(state, stack.box) # z-index >= 0 for it in stack.children.toOpenArray(i, stack.children.high): grid.renderStack(state, it) proc render*(grid: var FlexibleGrid; bgcolor: var CellColor; stack: StackItem; attrs: WindowAttributes; images: var seq[PosBitmap]) = grid.setLen(0) var state = RenderState( bgcolor: defaultColor, cellSize: size(w = attrs.ppc.toLUnit(), h = attrs.ppl.toLUnit()), ) grid.renderStack(state, stack) bgcolor = state.bgcolor images = move(state.images) {.pop.} # raises: [] ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/css/sheet.nim���������������������������������������������������������������������0000664�0000000�0000000�00000026251�15202323131�0016334�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/tables import chame/tags import css/cssparser import css/cssvalues import css/mediaquery import html/catom import html/script import types/opt import types/url type CSSRuleDef* = ref object sels*: SelectorList vals*: array[CSSImportantFlag, seq[CSSComputedEntry]] vars*: array[CSSImportantFlag, seq[CSSVariable]] # Absolute position in the stylesheet; used for sorting rules after # retrieval from the cache. # Top 32 bits: sheet id; bottom 32 bits: rule id. idx*: uint64 origin*: CSSOrigin layerId*: uint16 layer*: CAtom next: CSSRuleDef CSSImport* = object url*: URL layer*: CAtom StyleState = object importList*: seq[CSSImport] layers: seq[CAtom] defsHead: CSSRuleDef defsTail: CSSRuleDef len: uint32 idx: uint32 anonLayerCount: uint16 CSSStylesheet* = ref object s*: StyleState settings: ptr EnvironmentSettings next*: CSSStylesheet media*: string # media attr toks: seq[CSSToken] baseLayer: CAtom origin: CSSOrigin disabled*: bool # whether or not we have disabled attr etc. applies*: bool # whether or not media attr/import applies CSSRuleMap* = ref object tagTable*: Table[CAtom, seq[CSSRuleDef]] idTable*: Table[CAtom, seq[CSSRuleDef]] classTable*: Table[CAtom, seq[CSSRuleDef]] attrTable*: Table[CAtom, seq[CSSRuleDef]] rootList*: seq[CSSRuleDef] generalList*: seq[CSSRuleDef] hintList*: seq[CSSRuleDef] sheetId: uint32 layers: seq[CAtom] anonLayers: uint16 SelectorHashType = enum shtGeneral, shtRoot, shtHint SelectorHashes = object tags: seq[CAtom] id: CAtom class: CAtom attr: CAtom t: SelectorHashType # Forward declarations proc getSelectorIds(hashes: var SelectorHashes; sel: Selector): bool proc addRule(sheet: CSSStylesheet; rule: CSSQualifiedRule; layer: CAtom) proc addAtRule(sheet: CSSStylesheet; atrule: CSSAtRule; base: URL; layer: CAtom): Opt[void] proc getSelectorIds(hashes: var SelectorHashes; sels: CompoundSelector) = for sel in sels: if hashes.getSelectorIds(sel): break proc getSelectorIds(hashes: var SelectorHashes; cxsel: ComplexSelector) = if cxsel.pseudo == peLinkHint: hashes.t = shtHint else: hashes.getSelectorIds(cxsel[^1]) proc getSelectorIds(hashes: var SelectorHashes; sel: Selector): bool = case sel.t of stType: hashes.tags.add(sel.tag) return true of stClass: hashes.class = sel.class return true of stId: hashes.id = sel.id return true of stAttr: hashes.attr = sel.attr return true of stIs, stWhere: # Hash whatever the selectors have in common: # 1. get the hashable values of selector 1 # 2. for each other selector x: # 3. get hashable values of selector x # 4. store hashable values of selector x that aren't stored yet # 5. for each hashable value of selector 1 that doesn't match selector x # 6. cancel hashable value var cancelId = false var cancelClass = false var cancelAttr = false var cancelT = false var i = 0 if i < sel.fsels.len: hashes.getSelectorIds(sel.fsels[i]) inc i while i < sel.fsels.len: var nhashes = SelectorHashes() nhashes.getSelectorIds(sel.fsels[i]) hashes.tags.add(nhashes.tags) if hashes.id == CAtomNull: hashes.id = nhashes.id elif nhashes.id != CAtomNull and nhashes.id != hashes.id: cancelId = true if hashes.class == CAtomNull: hashes.class = nhashes.class elif nhashes.class != CAtomNull and nhashes.class != hashes.class: cancelClass = true if hashes.attr == CAtomNull: hashes.attr = nhashes.attr elif nhashes.attr != CAtomNull and nhashes.attr != hashes.attr: cancelAttr = true if hashes.t != nhashes.t: cancelT = true inc i if cancelId: hashes.id = CAtomNull if cancelClass: hashes.class = CAtomNull if cancelAttr: hashes.attr = CAtomNull if cancelT: hashes.t = shtGeneral return hashes.tags.len > 0 or hashes.id != CAtomNull or hashes.class != CAtomNull or hashes.attr != CAtomNull or hashes.t != shtGeneral of stPseudoClass: case sel.pc of pcRoot: hashes.t = shtRoot return true of pcLink, pcVisited: hashes.tags.add(TAG_A.toAtom()) hashes.tags.add(TAG_AREA.toAtom()) hashes.attr = satHref.toAtom() return true else: return false of stUniversal, stNot, stLang, stNthChild, stNthLastChild, stHost: return false proc addIfNotLast(s: var seq[CSSRuleDef]; rule: CSSRuleDef) = if s.len == 0 or s[^1] != rule: s.add(rule) proc add(sheet: CSSRuleMap; rule: CSSRuleDef) = for cxsel in rule.sels: var hashes = SelectorHashes() hashes.getSelectorIds(cxsel) if hashes.id != CAtomNull: sheet.idTable.mgetOrPut(hashes.id, @[]).add(rule) elif hashes.tags.len > 0: for tag in hashes.tags: sheet.tagTable.mgetOrPut(tag, @[]).addIfNotLast(rule) elif hashes.class != CAtomNull: sheet.classTable.mgetOrPut(hashes.class, @[]).add(rule) elif hashes.attr != CAtomNull: sheet.attrTable.mgetOrPut(hashes.attr, @[]).add(rule) else: case hashes.t of shtRoot: sheet.rootList.add(rule) of shtHint: sheet.hintList.add(rule) of shtGeneral: sheet.generalList.add(rule) proc add*(map: CSSRuleMap; sheet: CSSStylesheet) = let sheetId = map.sheetId sheet.s.idx = sheetId inc map.sheetId # We don't have to dedupe, it won't make linear search much faster and # layer switches happen rarely enough anyway. map.layers.add(sheet.s.layers) var def = sheet.s.defsHead var prevLayer = CAtomNull var layerId = 0u16 let sheetIdShifted = (uint64(sheetId) shl 32) while def != nil: def.idx = sheetIdShifted or uint32(def.idx) let layer = def.layer if layer != CAtomNull: if layer != prevLayer: if ($layer)[0] == '!': layerId = 20000 + map.anonLayers # ought to be enough for everyone inc map.anonLayers else: layerId = uint16(map.layers.find(layer)) + 1 prevLayer = layer def.layerId = layerId map.add(def) def = def.next proc add(s: var StyleState; ruleDef: CSSRuleDef) = if s.defsTail == nil: s.defsHead = ruleDef else: s.defsTail.next = ruleDef s.defsTail = ruleDef inc s.len proc addRules(sheet: CSSStylesheet; ctx: var CSSParser; topLevel: bool; base: URL; layer: CAtom) = for rule in ctx.parseListOfRules(topLevel): case rule.t of crtAt: discard sheet.addAtRule(rule.at, base, layer) of crtQualified: sheet.addRule(rule.qualified, layer) proc addRule(sheet: CSSStylesheet; rule: CSSQualifiedRule; layer: CAtom) = if rule.sels.len > 0: var ruleDef = CSSRuleDef( sels: move(rule.sels), idx: sheet.s.len, origin: sheet.origin, layer: layer ) for decl in rule.decls: let f = decl.f case decl.t of cdtVariable: ruleDef.vars[f].add(CSSVariable( name: decl.v, items: parseDeclWithVar0(decl.value) )) of cdtNestedRule: sheet.s.add(ruleDef) ruleDef = CSSRuleDef( sels: ruleDef.sels, idx: sheet.s.len, origin: sheet.origin, layer: layer ) sheet.addRule(decl.r, layer) of cdtProperty: if decl.hasVar: if entry := parseDeclWithVar(decl.p, decl.value): ruleDef.vals[f].add(entry) else: ruleDef.vals[f].parseComputedValues(decl.p, decl.value, sheet.settings.attrsp[]) sheet.s.add(ruleDef) proc nextAnonLayer(sheet: CSSStylesheet): CAtom = let res = sheet.s.anonLayerCount inc sheet.s.anonLayerCount ('!' & $res).toAtom() proc consumeLayerName(ctx: var CSSParser; parent: CAtom; anon: var bool): Opt[CAtom] = var name = "" if parent != CAtomNull: name &= $parent & '.' while ctx.has(): case ctx.peekTokenType() of cttIdent: name &= ctx.consume().s of cttDot: if name.len <= 0 or name[^1] == '.': return err() name &= '.' ctx.seekToken() else: break if name.len <= 0 or name[^1] == '.': return err() anon = name[0] == '!' ok(name.toAtom()) proc parseImportLayer(ctx: var CSSParser; sheet: CSSStylesheet; oldLayer: CAtom): Opt[CAtom] = if ctx.skipBlanksCheckHas().isErr: return ok(oldLayer) if ctx.peekFunction(cftLayer): ctx.seekToken() if ctx.skipBlanksCheckDone().isOk: return ok(sheet.nextAnonLayer()) var anon: bool let layer = ?ctx.consumeLayerName(oldLayer, anon) ?ctx.checkFunctionEnd() return ok(layer) if ctx.peekIdentNoCase("layer"): ctx.seekToken() return ok(sheet.nextAnonLayer()) ok(oldLayer) proc addAtRule(sheet: CSSStylesheet; atrule: CSSAtRule; base: URL; layer: CAtom): Opt[void] = case atrule.name of cartUnknown: discard of cartImport: if sheet.s.len == 0 and base != nil: var ctx = initCSSParser(atrule.prelude) ?ctx.skipBlanksCheckHas() let tok = ctx.consume() let urls = ?ctx.parseURL(tok) let url = ?parseURL(urls, base) let layer = ?ctx.parseImportLayer(sheet, layer) #TODO media queries # Warning: this is a tracking vector minefield. If you implement # media query based imports, make sure to not filter here, but in # DOM after the sheet has been downloaded. (e.g. importList can # get a "media" field, etc.) ?ctx.skipBlanksCheckDone() sheet.s.importList.add(CSSImport(url: url, layer: layer)) of cartMedia: var ctx = initCSSParser(atrule.prelude) let query = ctx.parseMediaQueryList(sheet.settings.attrsp) if query.applies(sheet.settings): var ctx = initCSSParser(atrule.oblock) sheet.addRules(ctx, topLevel = false, base = nil, layer) of cartLayer: var ctx = initCSSParser(atrule.prelude) if atrule.hasBlock: let name = if ctx.skipBlanksCheckHas().isOk: var anon: bool let name = ?ctx.consumeLayerName(layer, anon) ?ctx.skipBlanksCheckDone() if anon: sheet.s.layers.add(name) # note: we intentionally don't dedupe name else: sheet.nextAnonLayer() var ctx = initCSSParser(atrule.oblock) sheet.addRules(ctx, topLevel = false, base = nil, name) else: var names: seq[CAtom] = @[] while ctx.skipBlanksCheckHas().isOk: var anon: bool let name = ?ctx.consumeLayerName(layer, anon) if ctx.skipBlanksCheckHas().isErr: break if ctx.consume().t != cttComma: return err() names.add(name) sheet.s.layers.add(names) ok() proc parseStylesheet*(iq: string; base: URL; settings: ptr EnvironmentSettings; origin: CSSOrigin; layer: CAtom): CSSStylesheet = var ctx = initCSSParser(iq) let sheet = CSSStylesheet( settings: settings, origin: origin, baseLayer: layer, applies: true ) sheet.addRules(ctx, topLevel = true, base, layer) sheet.toks = move(ctx.toks) return sheet proc windowChange*(sheet: CSSStylesheet; base: URL) = var ctx = initCSSParserSink(sheet.toks) sheet.s = StyleState() sheet.addRules(ctx, topLevel = true, base, sheet.baseLayer) sheet.toks = move(ctx.toks) {.pop.} # raises: [] �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/encoding/�������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0015507�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/encoding/charset.nim��������������������������������������������������������������0000664�0000000�0000000�00000033102�15202323131�0017644�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## This module contains the `Charset` enum used by [encoder](encoder.html) and ## [decoder](decoder.html). {.push raises: [].} import std/algorithm import utils/twtstr type Charset* = enum csUnknown csUtf8 = "utf-8" csIbm866 = "ibm866" csIso8859_2 = "iso-8859-2" csIso8859_3 = "iso-8859-3" csIso8859_4 = "iso-8859-4" csIso8859_5 = "iso-8859-5" csIso8859_6 = "iso-8859-6" csIso8859_7 = "iso-8859-7" csIso8859_8 = "iso-8859-8" csIso8859_8i = "iso-8859-8-i" csIso8859_10 = "iso-8859-10" csIso8859_13 = "iso-8859-13" csIso8859_14 = "iso-8859-14" csIso8859_15 = "iso-8859-15" csIso8859_16 = "iso-8859-16" csKoi8r = "koi8-r" csKoi8u = "koi8-u" csMacintosh = "macintosh" csWindows874 = "windows-874" csWindows1250 = "windows-1250" csWindows1251 = "windows-1251" csWindows1252 = "windows-1252" csWindows1253 = "windows-1253" csWindows1254 = "windows-1254" csWindows1255 = "windows-1255" csWindows1256 = "windows-1256" csWindows1257 = "windows-1257" csWindows1258 = "windows-1258" csXMacCyrillic = "x-mac-cyrillic" csGbk = "gbk" csGb18030 = "gb18030" csBig5 = "Big5" csEucJP = "euc-jp" csIso2022JP = "iso-2022-jp" csShiftJIS = "shift_jis" csEucKR = "euc-kr" csReplacement = "replacement" csUtf16be = "utf-16be" csUtf16le = "utf-16le" csXUserDefined = "x-user-defined" const CharsetMap = { "866": csIbm866, "ansi_x3.4-1968": csWindows1252, "arabic": csIso8859_6, "ascii": csWindows1252, # lol "asmo-708": csIso8859_6, "big5": csBig5, "big5-hkscs": csBig5, "chinese": csGbk, "cn-big5": csBig5, "cp1250": csWindows1250, "cp1251": csWindows1251, "cp1252": csWindows1252, "cp1253": csWindows1253, "cp1254": csWindows1254, "cp1255": csWindows1255, "cp1256": csWindows1256, "cp1257": csWindows1257, "cp1258": csWindows1258, "cp819": csWindows1252, "cp866": csIbm866, "csbig5": csBig5, "cseuckr": csEucKR, "cseucpkdfmtjapanese": csEucJP, "csgb2312": csGbk, "csibm866": csIbm866, "csiso2022jp": csIso2022JP, "csiso2022kr": csReplacement, "csiso58gb231280": csGbk, "csiso88596e": csIso8859_6, "csiso88596i": csIso8859_6, "csiso88598e": csIso8859_8, "csiso88598i": csIso8859_8i, "csisolatin1": csWindows1252, "csisolatin2": csIso8859_2, "csisolatin3": csIso8859_3, "csisolatin4": csIso8859_4, "csisolatin5": csWindows1254, "csisolatin6": csIso8859_10, "csisolatin9": csIso8859_15, "csisolatinarabic": csIso8859_6, "csisolatincyrillic": csIso8859_5, "csisolatingreek": csIso8859_7, "csisolatinhebrew": csIso8859_8, "cskoi8r": csKoi8r, "csksc56011987": csEucKR, "csmacintosh": csMacintosh, "csshiftjis": csShiftJIS, "csunicode": csUtf16le, "cyrillic": csIso8859_5, "dos-874": csWindows874, "ecma-114": csIso8859_6, "ecma-118": csIso8859_7, "elot_928": csIso8859_7, "euc-jp": csEucJP, "euc-kr": csEucKR, "gb18030": csGb18030, "gb2312": csGbk, "gb_2312": csGbk, "gb_2312-80": csGbk, "gbk": csGbk, "greek": csIso8859_7, "greek8": csIso8859_7, "hebrew": csIso8859_8, "hz-gb-2312": csReplacement, "ibm819": csWindows1252, "ibm866": csIbm866, "iso-10646-ucs-2": csUtf16le, "iso-2022-cn": csReplacement, "iso-2022-cn-ext": csReplacement, "iso-2022-jp": csIso2022JP, "iso-2022-kr": csReplacement, "iso-8859-1": csWindows1252, "iso-8859-10": csIso8859_10, "iso-8859-11": csWindows874, "iso-8859-13": csIso8859_13, "iso-8859-14": csIso8859_14, "iso-8859-15": csIso8859_15, "iso-8859-16": csIso8859_16, "iso-8859-2": csIso8859_2, "iso-8859-3": csIso8859_3, "iso-8859-4": csIso8859_4, "iso-8859-5": csIso8859_5, "iso-8859-6": csIso8859_6, "iso-8859-6-e": csIso8859_6, "iso-8859-6-i": csIso8859_6, "iso-8859-7": csIso8859_7, "iso-8859-8": csIso8859_8, "iso-8859-8-e": csIso8859_8, "iso-8859-8-i": csIso8859_8i, "iso-8859-9": csWindows1254, "iso-ir-101": csIso8859_2, "iso-ir-109": csIso8859_3, "iso-ir-110": csIso8859_4, "iso-ir-126": csIso8859_7, "iso-ir-127": csIso8859_6, "iso-ir-138": csIso8859_8, "iso-ir-144": csIso8859_5, "iso-ir-148": csWindows1254, "iso-ir-149": csEucKR, "iso-ir-157": csIso8859_10, "iso-ir-58": csGbk, "iso8859-10": csIso8859_10, "iso8859-11": csWindows874, "iso8859-13": csIso8859_13, "iso8859-14": csIso8859_14, "iso8859-15": csIso8859_15, "iso8859-2": csIso8859_2, "iso8859-3": csIso8859_3, "iso8859-4": csIso8859_4, "iso8859-5": csIso8859_5, "iso8859-6": csIso8859_6, "iso8859-7": csIso8859_7, "iso8859-8": csIso8859_8, "iso8859-9": csWindows1254, "iso88591": csWindows1252, "iso885910": csIso8859_10, "iso885911": csWindows874, "iso885913": csIso8859_13, "iso885914": csIso8859_14, "iso885915": csIso8859_15, "iso88592": csIso8859_2, "iso88593": csIso8859_3, "iso88594": csIso8859_4, "iso88595": csIso8859_5, "iso88596": csIso8859_6, "iso88597": csIso8859_7, "iso88598": csIso8859_8, "iso88599": csWindows1254, "iso_8859-15": csIso8859_15, "iso_8859-1:1987": csWindows1252, "iso_8859-2": csIso8859_2, "iso_8859-2:1987": csIso8859_2, "iso_8859-3": csIso8859_3, "iso_8859-3:1988": csIso8859_3, "iso_8859-4": csIso8859_4, "iso_8859-4:1988": csIso8859_4, "iso_8859-5": csIso8859_5, "iso_8859-5:1988": csIso8859_5, "iso_8859-6": csIso8859_6, "iso_8859-6:1987": csIso8859_6, "iso_8859-7": csIso8859_7, "iso_8859-7:1987": csIso8859_7, "iso_8859-8": csIso8859_8, "iso_8859-8:1988": csIso8859_8, "iso_8859-9": csWindows1254, "iso_8859-9:1989": csWindows1254, "koi": csKoi8r, "koi8": csKoi8r, "koi8-r": csKoi8r, "koi8-ru": csKoi8u, "koi8-u": csKoi8u, "koi8_r": csKoi8r, "korean": csEucKR, "ks_c_5601-1987": csEucKR, "ks_c_5601-1989": csEucKR, "ksc5601": csEucKR, "ksc_5601": csEucKR, "l1": csWindows1252, "l2": csIso8859_2, "l3": csIso8859_3, "l4": csIso8859_4, "l5": csWindows1254, "l6": csIso8859_10, "l9": csIso8859_15, "latin1": csWindows1252, "latin2": csIso8859_2, "latin3": csIso8859_3, "latin4": csIso8859_4, "latin5": csWindows1254, "latin6": csIso8859_10, "logical": csIso8859_8i, "mac": csMacintosh, "macintosh": csMacintosh, "ms932": csShiftJIS, "ms_kanji": csShiftJIS, "replacement": csReplacement, "shift-jis": csShiftJIS, "shift_jis": csShiftJIS, "sjis": csShiftJIS, "sun_eu_greek": csIso8859_7, "tis-620": csWindows874, "ucs-2": csUtf16le, "unicode": csUtf16le, "unicode-1-1-utf-8": csUtf8, "unicode11utf-8": csUtf8, "unicode20utf-8": csUtf8, "unicodefeff": csUtf16le, "unicodefffe": csUtf16be, "us-ascii": csWindows1252, "utf-16": csUtf16le, "utf-16be": csUtf16be, "utf-16le": csUtf16le, "utf-8": csUtf8, "utf8": csUtf8, "visual": csIso8859_8, "windows-1250": csWindows1250, "windows-1251": csWindows1251, "windows-1252": csWindows1252, "windows-1253": csWindows1253, "windows-1254": csWindows1254, "windows-1255": csWindows1255, "windows-1256": csWindows1256, "windows-1257": csWindows1257, "windows-1258": csWindows1258, "windows-31j": csShiftJIS, "windows-874": csWindows874, "windows-949": csEucKR, "x-cp1250" : csWindows1250, "x-cp1251": csWindows1251, "x-cp1252": csWindows1252, "x-cp1253": csWindows1253, "x-cp1254": csWindows1254, "x-cp1255": csWindows1255, "x-cp1256": csWindows1256, "x-cp1257": csWindows1257, "x-cp1258": csWindows1258, "x-euc-jp": csEucJP, "x-gbk": csGbk, "x-mac-cyrillic": csXMacCyrillic, "x-mac-roman": csMacintosh, "x-mac-ukrainian": csXMacCyrillic, "x-sjis": csShiftJIS, "x-unicode20utf8": csUtf8, "x-user-defined": csXUserDefined, "x-x-big5": csBig5, } const NormalizedCharsetMap = { "866": csIbm866, "arabic": csIso8859_6, "ascii": csWindows1252, # lol "asmo708": csIso8859_6, "big5": csBig5, "big5hkscs": csBig5, "chinese": csGbk, "cnbig5": csBig5, "cp1250": csWindows1250, "cp1251": csWindows1251, "cp1252": csWindows1252, "cp1253": csWindows1253, "cp1254": csWindows1254, "cp1255": csWindows1255, "cp1256": csWindows1256, "cp1257": csWindows1257, "cp1258": csWindows1258, "cp819": csWindows1252, "cp866": csIbm866, "csbig5": csBig5, "cseuckr": csEucKR, "cseucpkdfmtjapanese": csEucJP, "csgb2312": csGbk, "csibm866": csIbm866, "csiso2022jp": csIso2022JP, "csiso2022kr": csReplacement, "csiso58gb231280": csGbk, "csiso88596e": csIso8859_6, "csiso88596i": csIso8859_6, "csiso88598e": csIso8859_8, "csiso88598i": csIso8859_8i, "csisolatin1": csWindows1252, "csisolatin2": csIso8859_2, "csisolatin3": csIso8859_3, "csisolatin4": csIso8859_4, "csisolatin5": csWindows1254, "csisolatin6": csIso8859_10, "csisolatin9": csIso8859_15, "csisolatinarabic": csIso8859_6, "csisolatincyrillic": csIso8859_5, "csisolatingreek": csIso8859_7, "csisolatinhebrew": csIso8859_8, "cskoi8r": csKoi8r, "csksc56011987": csEucKR, "csmacintosh": csMacintosh, "csshiftjis": csShiftJIS, "csunicode": csUtf16le, "cyrillic": csIso8859_5, "dos874": csWindows874, "ecma114": csIso8859_6, "ecma118": csIso8859_7, "elot928": csIso8859_7, "eucjp": csEucJP, "euckr": csEucKR, "gb18030": csGb18030, "gb2312": csGbk, "gb231280": csGbk, "gbk": csGbk, "greek": csIso8859_7, "greek8": csIso8859_7, "hebrew": csIso8859_8, "hzgb2312": csReplacement, "ibm819": csWindows1252, "ibm866": csIbm866, "iso10646ucs2": csUtf16le, "iso2022cn": csReplacement, "iso2022cnext": csReplacement, "iso2022jp": csIso2022JP, "iso2022kr": csReplacement, "iso88591": csWindows1252, "iso885910": csIso8859_10, "iso885911": csWindows874, "iso885913": csIso8859_13, "iso885914": csIso8859_14, "iso885915": csIso8859_15, "iso885915": csIso8859_15, "iso885916": csIso8859_16, "iso88592": csIso8859_2, "iso88592": csIso8859_2, "iso88593": csIso8859_3, "iso88593": csIso8859_3, "iso88594": csIso8859_4, "iso88594": csIso8859_4, "iso88595": csIso8859_5, "iso88595": csIso8859_5, "iso88596": csIso8859_6, "iso88596": csIso8859_6, "iso88596e": csIso8859_6, "iso88596i": csIso8859_6, "iso88597": csIso8859_7, "iso88597": csIso8859_7, "iso88598": csIso8859_8, "iso88598": csIso8859_8, "iso88598e": csIso8859_8, "iso88598i": csIso8859_8i, "iso88599": csWindows1254, "iso88599": csWindows1254, "isoir101": csIso8859_2, "isoir109": csIso8859_3, "isoir110": csIso8859_4, "isoir126": csIso8859_7, "isoir127": csIso8859_6, "isoir138": csIso8859_8, "isoir144": csIso8859_5, "isoir148": csWindows1254, "isoir149": csEucKR, "isoir157": csIso8859_10, "isoir58": csGbk, "koi": csKoi8r, "koi8": csKoi8r, "koi8r": csKoi8r, "koi8ru": csKoi8u, "koi8u": csKoi8u, "korean": csEucKR, "ksc5601": csEucKR, "ksc56011987": csEucKR, "ksc56011989": csEucKR, "l1": csWindows1252, "l2": csIso8859_2, "l3": csIso8859_3, "l4": csIso8859_4, "l5": csWindows1254, "l6": csIso8859_10, "l9": csIso8859_15, "latin1": csWindows1252, "latin2": csIso8859_2, "latin3": csIso8859_3, "latin4": csIso8859_4, "latin5": csWindows1254, "latin6": csIso8859_10, "logical": csIso8859_8i, "mac": csMacintosh, "macintosh": csMacintosh, "ms932": csShiftJIS, "mskanji": csShiftJIS, "shiftjis": csShiftJIS, "sjis": csShiftJIS, "suneugreek": csIso8859_7, "tis620": csWindows874, "ucs2": csUtf16le, "unicode": csUtf16le, "unicode11utf8": csUtf8, "unicode20utf8": csUtf8, "unicodefeff": csUtf16le, "unicodefffe": csUtf16be, "usascii": csWindows1252, "utf16": csUtf16le, "utf16be": csUtf16be, "utf16le": csUtf16le, "utf8": csUtf8, "visual": csIso8859_8, "windows1250": csWindows1250, "windows1251": csWindows1251, "windows1252": csWindows1252, "windows1253": csWindows1253, "windows1254": csWindows1254, "windows1255": csWindows1255, "windows1256": csWindows1256, "windows1257": csWindows1257, "windows1258": csWindows1258, "windows31j": csShiftJIS, "windows874": csWindows874, "windows949": csEucKR, "xcp1250" : csWindows1250, "xcp1251": csWindows1251, "xcp1252": csWindows1252, "xcp1253": csWindows1253, "xcp1254": csWindows1254, "xcp1255": csWindows1255, "xcp1256": csWindows1256, "xcp1257": csWindows1257, "xcp1258": csWindows1258, "xeucjp": csEucJP, "xgbk": csGbk, "xmaccyrillic": csXMacCyrillic, "xmacroman": csMacintosh, "xmacukrainian": csXMacCyrillic, "xsjis": csShiftJIS, "xunicode20utf8": csUtf8, "xxbig5": csBig5, } proc normalizeLocale(s: openArray[char]): string = result = "" for c in s: if uint8(c) > 0x20 and c notin {'_', '-'}: result &= c.toLowerAscii() const DefaultCharset* = csUtf8 proc cmpCharsetPair(x: (string, Charset); k: string): int = cmpIgnoreCase(x[0], k) proc getCharset*(s: string): Charset = ## Return a Charset from the label `s`. This function is equivalent to the ## standard "get an encoding from a string label" algorithm: ## ## https://encoding.spec.whatwg.org/#concept-encoding-get ## ## On failure, csUnknown is returned. const AsciiWhitespace = {' ', '\n', '\r', '\t', '\f'} let s = s.strip(chars = AsciiWhitespace) let i = CharsetMap.binarySearch(s, cmpCharsetPair) if i < 0: return csUnknown return CharsetMap[i][1] proc getLocaleCharset*(s: string): Charset = ## Extract a charset from a locale. e.g. returns EUC_JP for the string ## LC_ALL=ja_JP.EUC_JP. let i = s.find('.') if i >= 0 and i < s.high: let ss = s.toOpenArray(i + 1, s.high).normalizeLocale() let i = NormalizedCharsetMap.binarySearch(ss, cmpCharsetPair) if i < 0: return csUnknown return NormalizedCharsetMap[i][1] # We could try to guess the charset based on the language here, like w3m # does. # However, these days it is more likely for any system to be using UTF-8 # than any other charset, irrespective of the language. So we just assume # UTF-8. return DefaultCharset {.pop.} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/encoding/charset_map.nim����������������������������������������������������������0000664�0000000�0000000�00004635476�15202323131�0020533�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������const Big5DecodeOffset* = 942 type UCS16x16* = tuple[ucs, p: uint16] const Ibm866Decode*: array[128, uint16] = [ uint16 1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053, 1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069, 1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085, 1086,1087,9617,9618,9619,9474,9508,9569,9570,9558,9557,9571,9553,9559,9565,9564, 9563,9488,9492,9524,9516,9500,9472,9532,9566,9567,9562,9556,9577,9574,9568,9552, 9580,9575,9576,9572,9573,9561,9560,9554,9555,9579,9578,9496,9484,9608,9604,9612, 9616,9600,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101, 1102,1103,1025,1105,1028,1108,1031,1111,1038,1118,176,8729,183,8730,8470,164, 9632,160, ] const Ibm866Encode* = (start: 0u8, len: 47u8, offset: 1040u16) const Iso8859_2Decode*: array[128, uint16] = [ uint16 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, 146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,260,728,321,164,317, 346,167,168,352,350,356,377,173,381,379,176,261,731,322,180,318,347,711,184,353, 351,357,378,733,382,380,340,193,194,258,196,313,262,199,268,201,280,203,282,205, 206,270,272,323,327,211,212,336,214,215,344,366,218,368,220,221,354,223,341,225, 226,259,228,314,263,231,269,233,281,235,283,237,238,271,273,324,328,243,244,337, 246,247,345,367,250,369,252,253,355,729, ] const Iso8859_2Encode* = (start: 0u8, len: 32u8, offset: 128u16) const Iso8859_3Decode*: array[128, uint16] = [ uint16 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, 146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,294,728,163,164,0, 292,167,168,304,350,286,308,173,0,379,176,295,178,179,180,181,293,183,184,305, 351,287,309,189,0,380,192,193,194,0,196,266,264,199,200,201,202,203,204,205,206, 207,0,209,210,211,212,288,214,215,284,217,218,219,220,364,348,223,224,225,226,0, 228,267,265,231,232,233,234,235,236,237,238,239,0,241,242,243,244,289,246,247, 285,249,250,251,252,365,349,729, ] const Iso8859_3Encode* = (start: 0u8, len: 32u8, offset: 128u16) const Iso8859_4Decode*: array[128, uint16] = [ uint16 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, 146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,260,312,342,164,296, 315,167,168,352,274,290,358,173,381,175,176,261,731,343,180,297,316,711,184,353, 275,291,359,330,382,331,256,193,194,195,196,197,198,302,268,201,280,203,278,205, 206,298,272,325,332,310,212,213,214,215,216,370,218,219,220,360,362,223,257,225, 226,227,228,229,230,303,269,233,281,235,279,237,238,299,273,326,333,311,244,245, 246,247,248,371,250,251,252,361,363,729, ] const Iso8859_4Encode* = (start: 0u8, len: 32u8, offset: 128u16) const Iso8859_5Decode*: array[128, uint16] = [ uint16 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, 146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,1025,1026,1027,1028, 1029,1030,1031,1032,1033,1034,1035,1036,173,1038,1039,1040,1041,1042,1043,1044, 1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060, 1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076, 1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092, 1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,8470,1105,1106,1107,1108, 1109,1110,1111,1112,1113,1114,1115,1116,167,1118,1119, ] const Iso8859_5Encode* = (start: 46u8, len: 65u8, offset: 1038u16) const Iso8859_6Decode*: array[115, uint16] = [ uint16 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, 146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,0,0,0,164,0,0,0,0,0, 0,0,1548,173,0,0,0,0,0,0,0,0,0,0,0,0,0,1563,0,0,0,1567,0,1569,1570,1571,1572, 1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588, 1589,1590,1591,1592,1593,1594,0,0,0,0,0,1600,1601,1602,1603,1604,1605,1606,1607, 1608,1609,1610,1611,1612,1613,1614,1615,1616,1617,1618, ] const Iso8859_6Encode* = (start: 0u8, len: 32u8, offset: 128u16) const Iso8859_7Decode*: array[127, uint16] = [ uint16 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, 146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,8216,8217,163,8364, 8367,166,167,168,169,890,171,172,173,0,8213,176,177,178,179,900,901,902,183,904, 905,906,187,908,189,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924, 925,926,927,928,929,0,931,932,933,934,935,936,937,938,939,940,941,942,943,944, 945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964, 965,966,967,968,969,970,971,972,973,974, ] const Iso8859_7Encode* = (start: 83u8, len: 43u8, offset: 931u16) const Iso8859_8Decode*: array[127, uint16] = [ uint16 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, 146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,0,162,163,164,165, 166,167,168,169,215,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185, 247,187,188,189,190,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,8215,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501, 1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,0,0,8206,8207, ] const Iso8859_8Encode* = (start: 0u8, len: 32u8, offset: 128u16) const Iso8859_10Decode*: array[128, uint16] = [ uint16 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, 146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,260,274,290,298,296, 310,167,315,272,352,358,381,173,362,330,176,261,275,291,299,297,311,183,316,273, 353,359,382,8213,363,331,256,193,194,195,196,197,198,302,268,201,280,203,278, 205,206,207,208,325,332,211,212,213,214,360,216,370,218,219,220,221,222,223,257, 225,226,227,228,229,230,303,269,233,281,235,279,237,238,239,240,326,333,243,244, 245,246,361,248,371,250,251,252,253,254,312, ] const Iso8859_10Encode* = (start: 0u8, len: 32u8, offset: 128u16) const Iso8859_13Decode*: array[128, uint16] = [ uint16 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, 146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,8221,162,163,164, 8222,166,167,216,169,342,171,172,173,174,198,176,177,178,179,8220,181,182,183, 248,185,343,187,188,189,190,230,260,302,256,262,196,197,280,274,268,201,377,278, 290,310,298,315,352,323,325,211,332,213,214,215,370,321,346,362,220,379,381,223, 261,303,257,263,228,229,281,275,269,233,378,279,291,311,299,316,353,324,326,243, 333,245,246,247,371,322,347,363,252,380,382,8217, ] const Iso8859_13Encode* = (start: 0u8, len: 32u8, offset: 128u16) const Iso8859_14Decode*: array[128, uint16] = [ uint16 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, 146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,7682,7683,163,266, 267,7690,167,7808,169,7810,7691,7922,173,174,376,7710,7711,288,289,7744,7745, 182,7766,7809,7767,7811,7776,7923,7812,7813,7777,192,193,194,195,196,197,198, 199,200,201,202,203,204,205,206,207,372,209,210,211,212,213,214,7786,216,217, 218,219,220,221,374,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237, 238,239,373,241,242,243,244,245,246,7787,248,249,250,251,252,253,375,255, ] const Iso8859_14Encode* = (start: 0u8, len: 32u8, offset: 128u16) const Iso8859_15Decode*: array[128, uint16] = [ uint16 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, 146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,8364, 165,352,167,353,169,170,171,172,173,174,175,176,177,178,179,381,181,182,183,382, 185,186,187,338,339,376,191,192,193,194,195,196,197,198,199,200,201,202,203,204, 205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224, 225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244, 245,246,247,248,249,250,251,252,253,254,255, ] const Iso8859_15Encode* = (start: 63u8, len: 64u8, offset: 191u16) const Iso8859_16Decode*: array[128, uint16] = [ uint16 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, 146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,260,261,321,8364, 8222,352,167,353,169,536,171,377,173,378,379,176,177,268,322,381,8221,182,183, 382,269,537,187,338,339,376,380,192,193,194,258,196,262,198,199,200,201,202,203, 204,205,206,207,272,323,210,211,212,336,214,346,368,217,218,219,220,280,538,223, 224,225,226,259,228,263,230,231,232,233,234,235,236,237,238,239,273,324,242,243, 244,337,246,347,369,249,250,251,252,281,539,255, ] const Iso8859_16Encode* = (start: 0u8, len: 32u8, offset: 128u16) const Koi8rDecode*: array[128, uint16] = [ uint16 9472,9474,9484,9488,9492,9496,9500,9508,9516,9524,9532,9600,9604,9608, 9612,9616,9617,9618,9619,8992,9632,8729,8730,8776,8804,8805,160,8993,176,178, 183,247,9552,9553,9554,1105,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564, 9565,9566,9567,9568,9569,1025,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579, 9580,169,1102,1072,1073,1094,1076,1077,1092,1075,1093,1080,1081,1082,1083,1084, 1085,1086,1087,1103,1088,1089,1090,1091,1078,1074,1100,1099,1079,1096,1101,1097, 1095,1098,1070,1040,1041,1062,1044,1045,1060,1043,1061,1048,1049,1050,1051,1052, 1053,1054,1055,1071,1056,1057,1058,1059,1046,1042,1068,1067,1047,1064,1069,1065, 1063,1066, ] const Koi8rEncode* = (start: 36u8, len: 14u8, offset: 9555u16) const Koi8uDecode*: array[128, uint16] = [ uint16 9472,9474,9484,9488,9492,9496,9500,9508,9516,9524,9532,9600,9604,9608, 9612,9616,9617,9618,9619,8992,9632,8729,8730,8776,8804,8805,160,8993,176,178, 183,247,9552,9553,9554,1105,1108,9556,1110,1111,9559,9560,9561,9562,9563,1169, 1118,9566,9567,9568,9569,1025,1028,9571,1030,1031,9574,9575,9576,9577,9578,1168, 1038,169,1102,1072,1073,1094,1076,1077,1092,1075,1093,1080,1081,1082,1083,1084, 1085,1086,1087,1103,1088,1089,1090,1091,1078,1074,1100,1099,1079,1096,1101,1097, 1095,1098,1070,1040,1041,1062,1044,1045,1060,1043,1061,1048,1049,1050,1051,1052, 1053,1054,1055,1071,1056,1057,1058,1059,1046,1042,1068,1067,1047,1064,1069,1065, 1063,1066, ] const Koi8uEncode* = (start: 73u8, len: 7u8, offset: 1080u16) const MacintoshDecode*: array[128, uint16] = [ uint16 196,197,199,201,209,214,220,225,224,226,228,227,229,231,233,232,234,235, 237,236,238,239,241,243,242,244,246,245,250,249,251,252,8224,176,162,163,167, 8226,182,223,174,169,8482,180,168,8800,198,216,8734,177,8804,8805,165,181,8706, 8721,8719,960,8747,170,186,937,230,248,191,161,172,8730,402,8776,8710,171,187, 8230,160,192,195,213,338,339,8211,8212,8220,8221,8216,8217,247,9674,255,376, 8260,8364,8249,8250,64257,64258,8225,183,8218,8222,8240,194,202,193,203,200,205, 206,207,204,211,212,63743,210,218,219,217,305,710,732,175,728,729,730,184,733, 731,711, ] const MacintoshEncode* = (start: 106u8, len: 2u8, offset: 205u16) const Windows874Decode*: array[124, uint16] = [ uint16 8364,129,130,131,132,8230,134,135,136,137,138,139,140,141,142,143,144, 8216,8217,8220,8221,8226,8211,8212,152,153,154,155,156,157,158,159,160,3585, 3586,3587,3588,3589,3590,3591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601, 3602,3603,3604,3605,3606,3607,3608,3609,3610,3611,3612,3613,3614,3615,3616,3617, 3618,3619,3620,3621,3622,3623,3624,3625,3626,3627,3628,3629,3630,3631,3632,3633, 3634,3635,3636,3637,3638,3639,3640,3641,3642,0,0,0,0,3647,3648,3649,3650,3651, 3652,3653,3654,3655,3656,3657,3658,3659,3660,3661,3662,3663,3664,3665,3666,3667, 3668,3669,3670,3671,3672,3673,3674,3675, ] const Windows874Encode* = (start: 33u8, len: 57u8, offset: 3585u16) const Windows1250Decode*: array[128, uint16] = [ uint16 8364,129,8218,131,8222,8230,8224,8225,136,8240,352,8249,346,356,381,377, 144,8216,8217,8220,8221,8226,8211,8212,152,8482,353,8250,347,357,382,378,160, 711,728,321,164,260,166,167,168,169,350,171,172,173,174,379,176,177,731,322,180, 181,182,183,184,261,351,187,317,733,318,380,340,193,194,258,196,313,262,199,268, 201,280,203,282,205,206,270,272,323,327,211,212,336,214,215,344,366,218,368,220, 221,354,223,341,225,226,259,228,314,263,231,269,233,281,235,283,237,238,271,273, 324,328,243,244,337,246,247,345,367,250,369,252,253,355,729, ] const Windows1250Encode* = (start: 52u8, len: 4u8, offset: 180u16) const Windows1251Decode*: array[128, uint16] = [ uint16 1026,1027,8218,1107,8222,8230,8224,8225,8364,8240,1033,8249,1034,1036, 1035,1039,1106,8216,8217,8220,8221,8226,8211,8212,152,8482,1113,8250,1114,1116, 1115,1119,160,1038,1118,1032,164,1168,166,167,1025,169,1028,171,172,173,174, 1031,176,177,1030,1110,1169,181,182,183,1105,8470,1108,187,1112,1029,1109,1111, 1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055, 1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071, 1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087, 1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103, ] const Windows1251Encode* = (start: 64u8, len: 63u8, offset: 1040u16) const Windows1252Decode*: array[128, uint16] = [ uint16 8364,129,8218,402,8222,8230,8224,8225,710,8240,352,8249,338,141,381,143, 144,8216,8217,8220,8221,8226,8211,8212,732,8482,353,8250,339,157,382,376,160, 161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180, 181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200, 201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, 221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240, 241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, ] const Windows1252Encode* = (start: 32u8, len: 95u8, offset: 160u16) const Windows1253Decode*: array[127, uint16] = [ uint16 8364,129,8218,402,8222,8230,8224,8225,136,8240,138,8249,140,141,142,143, 144,8216,8217,8220,8221,8226,8211,8212,152,8482,154,8250,156,157,158,159,160, 901,902,163,164,165,166,167,168,169,0,171,172,173,174,8213,176,177,178,179,900, 181,182,183,904,905,906,187,908,189,910,911,912,913,914,915,916,917,918,919,920, 921,922,923,924,925,926,927,928,929,0,931,932,933,934,935,936,937,938,939,940, 941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960, 961,962,963,964,965,966,967,968,969,970,971,972,973,974, ] const Windows1253Encode* = (start: 83u8, len: 43u8, offset: 931u16) const Windows1254Decode*: array[128, uint16] = [ uint16 8364,129,8218,402,8222,8230,8224,8225,710,8240,352,8249,338,141,142,143, 144,8216,8217,8220,8221,8226,8211,8212,732,8482,353,8250,339,157,158,376,160, 161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180, 181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200, 201,202,203,204,205,206,207,286,209,210,211,212,213,214,215,216,217,218,219,220, 304,350,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,287, 241,242,243,244,245,246,247,248,249,250,251,252,305,351,255, ] const Windows1254Encode* = (start: 32u8, len: 47u8, offset: 160u16) const Windows1255Decode*: array[127, uint16] = [ uint16 8364,129,8218,402,8222,8230,8224,8225,710,8240,138,8249,140,141,142,143, 144,8216,8217,8220,8221,8226,8211,8212,732,8482,154,8250,156,157,158,159,160, 161,162,163,8362,165,166,167,168,169,215,171,172,173,174,175,176,177,178,179, 180,181,182,183,184,185,247,187,188,189,190,191,1456,1457,1458,1459,1460,1461, 1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1520,1521, 1522,1523,1524,0,0,0,0,0,0,0,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497, 1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513, 1514,0,0,8206,8207, ] const Windows1255Encode* = (start: 96u8, len: 26u8, offset: 1488u16) const Windows1256Decode*: array[128, uint16] = [ uint16 8364,1662,8218,402,8222,8230,8224,8225,710,8240,1657,8249,338,1670,1688, 1672,1711,8216,8217,8220,8221,8226,8211,8212,1705,8482,1681,8250,339,8204,8205, 1722,160,1548,162,163,164,165,166,167,168,169,1726,171,172,173,174,175,176,177, 178,179,180,181,182,183,184,185,1563,187,188,189,190,1567,1729,1569,1570,1571, 1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587, 1588,1589,1590,215,1591,1592,1593,1594,1600,1601,1602,1603,224,1604,226,1605, 1606,1607,1608,231,232,233,234,235,1609,1610,238,239,1611,1612,1613,1614,244, 1615,1616,247,1617,249,1618,251,252,8206,8207,1746, ] const Windows1256Encode* = (start: 65u8, len: 21u8, offset: 1569u16) const Windows1257Decode*: array[128, uint16] = [ uint16 8364,129,8218,131,8222,8230,8224,8225,136,8240,138,8249,140,168,711,184, 144,8216,8217,8220,8221,8226,8211,8212,152,8482,154,8250,156,175,731,159,160,0, 162,163,164,0,166,167,216,169,342,171,172,173,174,198,176,177,178,179,180,181, 182,183,248,185,343,187,188,189,190,230,260,302,256,262,196,197,280,274,268,201, 377,278,290,310,298,315,352,323,325,211,332,213,214,215,370,321,346,362,220,379, 381,223,261,303,257,263,228,229,281,275,269,233,378,279,291,311,299,316,353,324, 326,243,333,245,246,247,371,322,347,363,252,380,382,729, ] const Windows1257Encode* = (start: 48u8, len: 7u8, offset: 176u16) const Windows1258Decode*: array[128, uint16] = [ uint16 8364,129,8218,402,8222,8230,8224,8225,710,8240,138,8249,338,141,142,143, 144,8216,8217,8220,8221,8226,8211,8212,732,8482,154,8250,339,157,158,376,160, 161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180, 181,182,183,184,185,186,187,188,189,190,191,192,193,194,258,196,197,198,199,200, 201,202,203,768,205,206,207,272,209,777,211,212,416,214,215,216,217,218,219,220, 431,771,223,224,225,226,259,228,229,230,231,232,233,234,235,769,237,238,239,273, 241,803,243,244,417,246,247,248,249,250,251,252,432,8363,255, ] const Windows1258Encode* = (start: 32u8, len: 34u8, offset: 160u16) const XMacCyrillicDecode*: array[128, uint16] = [ uint16 1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053, 1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069, 1070,1071,8224,176,1168,163,167,8226,182,1030,174,169,8482,1026,1106,8800,1027, 1107,8734,177,8804,8805,1110,181,1169,1032,1028,1108,1031,1111,1033,1113,1034, 1114,1112,1029,172,8730,402,8776,8710,171,187,8230,160,1035,1115,1036,1116,1109, 8211,8212,8220,8221,8216,8217,247,8222,1038,1118,1039,1119,8470,1025,1105,1103, 1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087, 1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,8364, ] const XMacCyrillicEncode* = (start: 0u8, len: 31u8, offset: 1040u16) const GB18030Runs*: array[1916, uint32] = [ 33554432u32,100671489u32,33628164u32,33644549u32,33677318u32,100843527u32, 33742858u32,33759243u32,33775628u32,67362829u32,33816591u32,33824784u32, 33832977u32,33841170u32,33873939u32,101007380u32,33906711u32,33914904u32, 33939481u32,33988634u32,34013211u32,34021404u32,67592221u32,134750239u32, 67649571u32,201875493u32,34119723u32,336117804u32,235462710u32,34144317u32, 34160702u32,34201663u32,67797056u32,34250818u32,101376067u32,34299974u32, 34349127u32,101490760u32,34398283u32,135069772u32,101531728u32,34496595u32, 34521172u32,68091989u32,34545751u32,101711960u32,34627675u32,34635868u32, 68214877u32,34668639u32,101802080u32,34701411u32,34717796u32,101851237u32, 34750568u32,34758761u32,34766954u32,236101739u32,68345970u32,169050228u32, 68427897u32,34898043u32,34906236u32,68493437u32,102064255u32,34971778u32, 34979971u32,34988164u32,34996357u32,35004550u32,35012743u32,169246856u32, 68591757u32,202817679u32,35086485u32,35094678u32,35102871u32,68739224u32, 35209370u32,35217563u32,68780188u32,68788382u32,68804768u32,35266722u32, 135938211u32,35291303u32,102416552u32,102432939u32,35340462u32,35348655u32, 35356848u32,35365041u32,68927666u32,68935860u32,102498486u32,35397817u32, 68960442u32,68968636u32,35422398u32,35471551u32,35479744u32,169713857u32, 303939782u32,102621391u32,136200402u32,102654166u32,169795801u32,35594462u32, 35602655u32,35635424u32,35643617u32,69206242u32,35660004u32,69239013u32, 35709159u32,35717352u32,136388841u32,35733741u32,102850798u32,438403313u32, 35766526u32,69329151u32,35782913u32,102899970u32,35815685u32,69378310u32, 35832072u32,102949129u32,35856652u32,35881229u32,371450126u32,35914009u32, 35922202u32,136593691u32,103047455u32,103063842u32,35963173u32,170197286u32, 136651051u32,35995951u32,270885168u32,203784504u32,304455998u32,103145799u32, 69599562u32,136733004u32,69632336u32,136749394u32,707182934u32,36102507u32, 36110700u32,69689709u32,170361199u32,237478260u32,640147835u32,203948430u32, 103293332u32,371736983u32,136872354u32,136896934u32,36241834u32,170467755u32, 338248112u32,103383482u32,204054973u32,472498627u32,975823313u32,36323822u32, 36356591u32,36372976u32,36381169u32,103498226u32,69951989u32,103530999u32, 36430330u32,170656251u32,70001152u32,70009346u32,70017540u32,36495878u32, 36512263u32,36569608u32,70148617u32,70173195u32,70181389u32,70197775u32, 137323025u32,70222357u32,36692503u32,36700696u32,103825945u32,36725276u32, 36733469u32,170967582u32,70320675u32,36807205u32,103940646u32,70410793u32, 103973419u32,36872750u32,36889135u32,36897328u32,70468145u32,36921907u32, 305365556u32,36938301u32,70500926u32,70517312u32,204743234u32,36979272u32, 36987465u32,70558282u32,37012044u32,37028429u32,37077582u32,70672975u32, 37143121u32,70705746u32,70722132u32,104292950u32,37233241u32,70795866u32, 104358492u32,104366687u32,37274210u32,37282403u32,37298788u32,70861413u32, 70869607u32,37364329u32,37372522u32,205185643u32,37421681u32,70992498u32, 71008884u32,37462646u32,171688567u32,37479036u32,71041661u32,104604287u32, 37503618u32,37511811u32,138191492u32,71090824u32,339534474u32,37552788u32, 37560981u32,171795094u32,238912155u32,71148194u32,238928548u32,37610155u32, 138330796u32,104825520u32,339731123u32,104866493u32,104874688u32,37774019u32, 37782212u32,138453701u32,37798601u32,104915658u32,37814989u32,205595342u32, 138494676u32,373383896u32,272728803u32,104973035u32,138552046u32,37905138u32, 138576627u32,37921527u32,138601208u32,37962492u32,71533309u32,71541503u32, 38003457u32,71566082u32,105128708u32,105136903u32,340026122u32,71615252u32, 38077206u32,38085399u32,38093592u32,38101785u32,105243418u32,38150941u32, 38175518u32,71754527u32,38208289u32,38216482u32,38273827u32,38290212u32, 38298405u32,71861030u32,38339368u32,38363945u32,38380330u32,139051819u32, 71951151u32,38404913u32,71983922u32,38437684u32,239788853u32,72024892u32, 38478654u32,72041279u32,38495041u32,72057666u32,38519620u32,38536005u32, 139215686u32,239887178u32,139232081u32,105685845u32,38585176u32,172819289u32, 105759582u32,72213345u32,38667107u32,38699876u32,105816933u32,72278888u32, 38757226u32,38855531u32,38896492u32,106029933u32,38929264u32,38945649u32, 38953842u32,38978419u32,39043956u32,106177397u32,39076728u32,39117689u32, 72680314u32,39158652u32,39199613u32,39215998u32,72786815u32,39248769u32, 39265154u32,39273347u32,72835972u32,72844166u32,39297928u32,39306121u32, 139985802u32,39330702u32,39396239u32,173630352u32,39420821u32,39429014u32, 39437207u32,274326424u32,39469984u32,73057185u32,73081763u32,39535525u32, 39543718u32,39551911u32,140223400u32,39576492u32,39601069u32,39609262u32, 73188271u32,39658417u32,173884338u32,39682999u32,39748536u32,39756729u32, 39764922u32,106890171u32,73343934u32,39797696u32,39805889u32,39838658u32, 39846851u32,73434052u32,39961542u32,39969735u32,39986120u32,174236617u32, 73622478u32,107193296u32,207872979u32,40109017u32,40125402u32,40133595u32, 140805084u32,40158176u32,174384097u32,73745382u32,207971304u32,140870638u32, 40215538u32,73794547u32,73802741u32,40256503u32,40264696u32,40297465u32, 107414522u32,140977149u32,40322049u32,40338434u32,40346627u32,40363012u32, 73925637u32,174605319u32,141059084u32,174629904u32,141083669u32,73983001u32, 74015771u32,40469533u32,208266270u32,74081316u32,40543270u32,40551463u32, 74146856u32,107742250u32,40641581u32,74204206u32,107766832u32,74228787u32, 40690741u32,242025526u32,309142589u32,40715334u32,40723527u32,40731720u32, 40739913u32,40748106u32,40756299u32,174990412u32,107897937u32,74351700u32, 107922518u32,40846425u32,175072346u32,40871007u32,40879200u32,40887393u32, 40920162u32,40928355u32,74507364u32,74515558u32,40977512u32,40985705u32, 175211626u32,41010287u32,208798832u32,74597494u32,41051256u32,275948665u32, 74630273u32,74638467u32,108209285u32,74671240u32,141788298u32,108250254u32, 41157777u32,41165970u32,74728595u32,41182357u32,108299414u32,410297497u32, 175441061u32,74785962u32,74810540u32,175482030u32,41272499u32,108389556u32, 141984951u32,141993147u32,142001343u32,276235459u32,242697419u32,108496082u32, 511157461u32,376947940u32,242738415u32,142083318u32,444081402u32,309871879u32, 74999056u32,75007250u32,41469204u32,41518357u32,209298710u32,41534748u32, 75097373u32,75113759u32,108684577u32,75146532u32,108725542u32,41633065u32, 41641258u32,578536747u32,75228476u32,108791102u32,142353729u32,41715013u32, 75310406u32,175981896u32,75343181u32,41796943u32,41805136u32,142476625u32, 75375957u32,41829719u32,176096600u32,75441501u32,75507039u32,41960801u32, 41968994u32,42001763u32,42009956u32,109127013u32,75580776u32,109151594u32, 176276845u32,142763378u32,176334198u32,243459451u32,142804354u32,42182022u32, 42198407u32,42206600u32,42214793u32,109340042u32,42239373u32,109356430u32, 310691217u32,243598746u32,75834785u32,75851171u32,42304933u32,75875750u32, 75900328u32,42354090u32,109479339u32,277259694u32,42386870u32,143058359u32, 109512123u32,75982270u32,75990464u32,42444226u32,109561283u32,109577670u32, 42477001u32,109594058u32,109602253u32,109610448u32,143173075u32,42517975u32, 76088792u32,176760282u32,176768479u32,143222244u32,478774760u32,243901942u32, 109700605u32,76154368u32,109716994u32,176834053u32,210396682u32,176850448u32, 579520021u32,42657318u32,42673703u32,42681896u32,109798953u32,277579308u32, 176932404u32,109839929u32,277628476u32,613189188u32,143435350u32,109889114u32, 378332765u32,109905512u32,479012459u32,210585209u32,42829439u32,42837632u32, 76400257u32,76408451u32,76416645u32,277751431u32,42878607u32,76441232u32, 177112722u32,42903191u32,143574680u32,76490396u32,42952350u32,76514975u32, 143632033u32,42985125u32,42993318u32,43017895u32,43042472u32,76605097u32, 76613291u32,43091629u32,143763118u32,43116210u32,76678835u32,43148981u32, 76711606u32,43173560u32,76736185u32,43222715u32,177448636u32,43239105u32, 76801730u32,445908676u32,43271889u32,43280082u32,110405331u32,110413526u32, 43337433u32,43362010u32,76924635u32,144041693u32,76949217u32,43411171u32, 144082660u32,144090856u32,77006572u32,77039342u32,77055728u32,211281650u32, 43517688u32,77080313u32,244860667u32,110651138u32,144221957u32,77154057u32, 43616011u32,43624204u32,177858317u32,43648786u32,77211411u32,110774037u32, 412772120u32,43681572u32,110798629u32,43697960u32,43706153u32,77317930u32, 144434988u32,43779888u32,144451377u32,110905141u32,77358904u32,77375290u32, 43829052u32,110946109u32,245172032u32,43861831u32,43870024u32,178095945u32, 110995278u32,178112337u32,77457238u32,345909080u32,144590690u32,245262182u32, 144607085u32,77506417u32,312395635u32,77547388u32,144664446u32,614434690u32, 245344148u32,480241563u32,245368745u32,44058544u32,77621169u32,178292659u32, 77637560u32,211871674u32,77662144u32,178333634u32,44124103u32,44132296u32, 44140489u32,111257546u32,111265741u32,44173264u32,77735889u32,77744083u32, 44197845u32,178423766u32,782411739u32,413321202u32,883099646u32,44247064u32, 77809689u32,279144475u32,514033699u32,44288050u32,44312627u32,44369972u32, 77932597u32,77973559u32,44435513u32,111552570u32,44460093u32,44468286u32, 145139775u32,78039107u32,78047301u32,44509255u32,44533832u32,44558409u32, 78129226u32,111691852u32,44591183u32,44599376u32,44664913u32,111831122u32, 145401941u32,78301273u32,44779611u32,111904860u32,78375007u32,44828769u32, 145524834u32,111978598u32,44877929u32,313329770u32,44918899u32,78481524u32, 78497910u32,179169400u32,44959869u32,246294654u32,78563461u32,45017223u32, 78579848u32,45033610u32,78596235u32,145721485u32,45066385u32,78629010u32, 45099156u32,45107349u32,45115542u32,145795223u32,45140123u32,45156508u32, 145827997u32,145836193u32,78735525u32,112298151u32,78833834u32,78842028u32, 78874798u32,112462000u32,112470195u32,146032822u32,45377722u32,45394107u32, 45402300u32,246745277u32,45435076u32,246769861u32,146122956u32,45467856u32, 179701969u32,112601302u32,79063257u32,79079643u32,45533405u32,179808478u32, 179824867u32,45615336u32,112748777u32,45648108u32,45656301u32,45664494u32, 146344175u32,45689075u32,45697268u32,79259893u32,213485815u32,213494013u32, 213502211u32,247064841u32,79300880u32,45771026u32,45779219u32,79341844u32, 79350038u32,347793688u32,213584162u32,79382824u32,213616938u32,180070704u32, 45861173u32,146532662u32,79431994u32,180103484u32,45893953u32,45910338u32, 113027395u32,180152646u32,280824139u32,280840531u32,79522139u32,381536605u32, 79554920u32,46008682u32,381561195u32,46025078u32,79595895u32,146712953u32, 448711037u32,750709130u32,113183136u32,851388835u32,448743868u32,247425481u32, 448760272u32,46115293u32,79686110u32,79702496u32,46189026u32,79751651u32, 46213605u32,79800806u32,180472296u32,79825389u32,46295535u32,46311920u32, 113428977u32,79882740u32,79907318u32,46377464u32,281307641u32,180660737u32, 80013830u32,180685320u32,80038413u32,147171855u32,46516755u32,214305300u32, 247867930u32,180775457u32,80120358u32,80128552u32,516352554u32,46615097u32, 46623290u32,46631483u32,46664252u32,113789501u32,46688832u32,80259649u32, 113830467u32,46746182u32,46787143u32,46803528u32,46811721u32,147499594u32, 181078606u32,181086803u32,46877272u32,147581529u32,348916317u32,214714983u32, 80521837u32,147638895u32,416082547u32,46991999u32,315435648u32,47008393u32, 80579210u32,114141836u32,114199183u32,47098514u32,114223763u32,47123094u32, 47131287u32,47139480u32,47147673u32,80718490u32,114281116u32,147851935u32, 47213219u32,80784036u32,47237798u32,47245991u32,248580776u32,47270575u32, 114387632u32,517049011u32,47295170u32,47311555u32,148007620u32,114461384u32, 47368907u32,47377100u32,80939725u32,47401679u32,80972496u32,47434450u32, 114551507u32,47450838u32,47459031u32,114584280u32,47499995u32,47516380u32, 114674397u32,47573728u32,81136353u32,47590115u32,81169124u32,148286182u32, 215403242u32,47639280u32,81201905u32,215436019u32,47672057u32,148343546u32, 181914366u32,81283843u32,81292037u32,47753991u32,114895624u32,114928395u32, 81382158u32,81398544u32,81406738u32,81414932u32,47876886u32,81447703u32, 115010329u32,81464092u32,81472286u32,47926048u32,115116833u32,81570596u32, 81595174u32,48048936u32,81627945u32,48081707u32,81660716u32,115231534u32, 115288881u32,182405940u32,182414137u32,81767230u32,48220992u32,249572161u32, 48253768u32,81816393u32,48270155u32,81832780u32,115395406u32,81857361u32, 148974419u32,81890135u32,48393049u32,81963866u32,81972060u32,48425822u32, 48474975u32,115592032u32,149162851u32,82062183u32,149187433u32,48532333u32, 48540526u32,115657583u32,48565106u32,48573299u32,82144116u32,82152310u32, 48606072u32,82168697u32,48638843u32,48647036u32,48663421u32,115780478u32, 82234241u32,283577219u32,115821451u32,182946702u32,115846035u32,82299798u32, 48753560u32,48761753u32,48778138u32,183012251u32,48827296u32,82430881u32, 48892835u32,82455460u32,183135142u32,149597099u32,48941999u32,116067248u32, 183200691u32,149654456u32,149662652u32,82570176u32,49032130u32,116157379u32, 653036486u32,283945945u32,49073121u32,49081314u32,49089507u32,82652132u32, 116214758u32,250440681u32,149785584u32,149793780u32,250473464u32,149818367u32, 49163267u32,653151236u32,82734103u32,183405593u32,284077086u32,317639718u32, 82783279u32,351226929u32,217017403u32,116362305u32,183479364u32,49269833u32, 183503946u32,49302607u32,586181712u32,485526625u32,317762671u32,217107576u32, 49343614u32,49351807u32,82979968u32,49458306u32,116583555u32,49482886u32, 49499271u32,150178952u32,49523852u32,49532045u32,150203534u32,83111058u32, 183782548u32,49605785u32,116722842u32,49638557u32,83225758u32,116812960u32, 83266723u32,251047077u32,83283116u32,49745070u32,83365039u32,83373233u32, 83381427u32,83389621u32,49843383u32,116976824u32,150539451u32,217664703u32, 49917125u32,49949894u32,117075143u32,49999050u32,83569867u32,83578061u32, 150703311u32,117157075u32,117165270u32,50064601u32,50089178u32,83651803u32, 50105565u32,50162910u32,50187487u32,50195680u32,50220257u32,83832034u32, 83840228u32,50302182u32,83897575u32,50375913u32,50384106u32,50400491u32, 151080172u32,50449648u32,151129329u32,151153909u32,84053241u32,151170299u32, 117624063u32,50531586u32,84159747u32,50613509u32,117738758u32,84192521u32, 218418443u32,84217105u32,151334163u32,50687255u32,84258072u32,50711834u32, 151424283u32,285650207u32,50785575u32,117919016u32,50818347u32,117935404u32, 84397359u32,151514417u32,84421941u32,151547191u32,50892091u32,151563580u32, 50933056u32,50941249u32,50965826u32,118082883u32,50982214u32,252316999u32, 50998606u32,51014991u32,51023184u32,51055953u32,51080530u32,84643155u32, 84659541u32,51121495u32,51129688u32,51137881u32,185363802u32,51154271u32, 84716896u32,118279522u32,51203429u32,118320486u32,252546409u32,51228016u32, 51244401u32,185470322u32,84823415u32,151940473u32,51285373u32,51293566u32, 51301759u32,151973248u32,51318148u32,84905349u32,185576839u32,84929932u32, 84946318u32,219180432u32,51424662u32,51432855u32,152112536u32,118566300u32, 51465631u32,219254176u32,185707942u32,85052843u32,51506605u32,51514798u32, 85077423u32,51563953u32,252898738u32,51580345u32,118697402u32,185814461u32, 286485954u32,51613130u32,118730187u32,353619406u32,252980696u32,51662303u32, 51678688u32,320122337u32,85257706u32,85274092u32,152391150u32,185953778u32, 152407543u32,85306875u32,51777021u32,152448510u32,51793410u32,51809795u32, 51817988u32,118935045u32,51834376u32,85397001u32,253177355u32,51867154u32, 51875347u32,152546836u32,186117656u32,119016989u32,51916320u32,51924513u32, 857239074u32,286821947u32,286830147u32,186175051u32,421064272u32,186191452u32, 85536353u32,152661603u32,52022887u32,52039272u32,85601897u32,186281579u32, 85626480u32,85642866u32,85651060u32,52104822u32,119221879u32,85683834u32, 52137596u32,52145789u32,119271038u32,85732993u32,152850051u32,119312007u32, 52211338u32,52219531u32,85782156u32,521997966u32,119352989u32,119369376u32, 52276899u32,119393956u32,52293287u32,52301480u32,85872297u32,52326059u32, 85888684u32,52350638u32,52358831u32,52367024u32,52375217u32,52383410u32, 287280819u32,85962427u32,119533245u32,52432576u32,153128641u32,52481733u32, 86052550u32,119615176u32,287403723u32,52530899u32,86093524u32,86134486u32, 153292504u32,86200028u32,186871518u32,52661987u32,86232804u32,119795430u32, 52694761u32,52702954u32,119828203u32,119852782u32,119860977u32,52760308u32, 153439989u32,52784889u32,153464570u32,52809470u32,52817663u32,86380288u32, 187068162u32,52858631u32,86421256u32,52875018u32,254209803u32,86454034u32, 86462228u32,86511382u32,153628440u32,52973340u32,86535965u32,52989727u32, 52997920u32,187223841u32,120139558u32,53038889u32,86609706u32,120172332u32, 120180527u32,53079858u32,86642483u32,153759541u32,153767737u32,153775933u32, 187346753u32,321572678u32,187371343u32,187379540u32,153833305u32,153841501u32, 892047201u32,53194619u32,288100220u32,86781828u32,221007750u32,53243788u32, 86822797u32,53276559u32,86839184u32,53292946u32,254644115u32,53350298u32, 86912923u32,120475549u32,53383072u32,120500129u32,53399460u32,53407653u32, 221188006u32,53424044u32,53432237u32,53465006u32,53473199u32,87035824u32, 154161074u32,87060406u32,87068600u32,53522362u32,87093179u32,53546941u32, 87117758u32,53571520u32,53604289u32,87166914u32,187838404u32,53628873u32, 120770506u32,87224269u32,87248847u32,53702609u32,53718994u32,53735379u32, 53743572u32,154415061u32,53759961u32,53776346u32,87338971u32,87347165u32, 53800927u32,53809120u32,154480609u32,154488805u32,53833705u32,53850090u32, 53858283u32,120991724u32,53899247u32,53907440u32,53923825u32,53940210u32, 53948403u32,87519220u32,53972982u32,288886775u32,54013951u32,356020224u32, 121188362u32,54104077u32,54128654u32,54136847u32,87699472u32,121262098u32, 87715861u32,87724055u32,54194201u32,289091610u32,54218786u32,154898467u32, 54243367u32,54292520u32,54308905u32,54317098u32,87879723u32,188559405u32, 121458738u32,255684661u32,255701052u32,121499715u32,87969862u32,54440008u32, 54497353u32,54521930u32,54530123u32,54538316u32,54554701u32,356569166u32, 54661208u32,289550425u32,54677601u32,323129442u32,54702187u32,54710380u32, 289607789u32,121843829u32,121852024u32,356741243u32,121868421u32,155447432u32, 54792332u32,88363149u32,54816911u32,356814992u32,54833306u32,222613659u32, 54849697u32,54857890u32,155529379u32,88428711u32,88436905u32,54890667u32, 189116588u32,88461489u32,356905139u32,54923453u32,122048702u32,122056897u32, 54964420u32,155635909u32,122089673u32,189206732u32,54997201u32,55013586u32, 55021779u32,424128724u32,122155232u32,289935587u32,88617195u32,122179821u32, 155742448u32,122196212u32,55095543u32,88658168u32,591982842u32,88674571u32, 88682765u32,88690959u32,55152913u32,88715538u32,88723732u32,155840790u32, 88740122u32,88748316u32,189419806u32,88781091u32,122343717u32,55243048u32, 55251241u32,55259434u32,122401067u32,223072558u32,88871220u32,88879414u32, 357331256u32,88912194u32,55365956u32,122483013u32,88936776u32,88944970u32, 122507596u32,189624655u32,290296148u32,55423324u32,55431517u32,55439710u32, 122556767u32,223228258u32,122573160u32,424579435u32,156152183u32,357486971u32, 55505285u32,357503366u32,424620432u32,223310236u32,55546274u32,223326627u32, 55562665u32,156234154u32,55579054u32,122696111u32,256922034u32,189829561u32, 89174462u32,290509248u32,256963016u32,55652815u32,189878736u32,122778069u32, 391221720u32,257012195u32,89248234u32,122810860u32,122819055u32,324153842u32, 55726587u32,189960700u32,290632193u32,290640393u32,55767569u32,3880989202u32, 89379461u32,357823111u32,156504721u32,55849621u32,122974870u32,156537497u32, 89436829u32,55898783u32,89461408u32,425013922u32,290804398u32,89526966u32, 492188344u32,55988934u32,156668615u32,56038091u32,56054476u32,56079053u32, 156750542u32,89658066u32,123220692u32,190345943u32,291017436u32,291025636u32, 56169196u32,257503981u32,56185588u32,89756405u32,190427895u32,56218364u32, 56226557u32,89789182u32,56283904u32,56292097u32,190518018u32,291189511u32, 123433743u32,123441938u32,56341269u32,123458326u32,123466521u32,257692444u32, 190608163u32,56398632u32,56423209u32,56455978u32,123597611u32,56496942u32, 56513327u32,56521520u32,123671345u32,56587060u32,56595253u32,90166070u32, 157283128u32,90182460u32,123761470u32,56668993u32,190903106u32,123802439u32, 56709962u32,123827019u32,90329934u32,123892560u32,191026003u32,56816472u32, 56824665u32,56832858u32,90395483u32,123958109u32,90420064u32,56890210u32, 56906595u32,90477412u32,90485606u32,90501992u32,157627242u32,56972142u32, 124089199u32,56988530u32,56996723u32,57037684u32,57062261u32,90633078u32, 157766520u32,57119612u32,157823869u32,124285825u32,57193348u32,124310405u32, 90764168u32,124359562u32,90813325u32,57267087u32,57299856u32,90862481u32, 57316243u32,90887060u32,57365398u32,57373591u32,57406360u32,91001753u32, 91009947u32,91018141u32,124580767u32,57488290u32,124605347u32,158167974u32, 57512874u32,91091883u32,225317805u32,57553843u32,91116468u32,91132854u32, 91141048u32,57611194u32,124728251u32,57627582u32,91214783u32,57668545u32, 57676738u32,57709507u32,57725892u32,57750469u32,158446534u32,57799626u32, 57807819u32,57816012u32,91378637u32,91386831u32,91395025u32,124965843u32, 158536662u32,91435994u32,125006812u32,192123871u32,91468772u32,91476966u32, 91493352u32,57947114u32,91509739u32,57963501u32,192205806u32,57996275u32, 58037236u32,58053621u32,91657206u32,91673592u32,91681786u32,91689980u32, 225915902u32,125268996u32,125301767u32,158872586u32,158880782u32,58225682u32, 125350931u32,58258454u32,91829271u32,58283033u32,158954522u32,58307614u32, 91870239u32,58324001u32,125441058u32,58340389u32,58348582u32,293245991u32, 159036463u32,58381363u32,58405940u32,91976757u32,58430519u32,92001336u32, 92009530u32,92017724u32,58479678u32,125613119u32,58512450u32,58520643u32, 58528836u32,92091461u32,58545223u32,125662280u32,58561611u32,293450828u32, 293467220u32,159265884u32,58618976u32,58627169u32,92189794u32,125752420u32, 394196071u32,92214386u32,528430196u32,125793411u32,58692742u32,92263559u32, 192935049u32,260060302u32,125850773u32,92304536u32,92312730u32,92320924u32, 58774686u32,92337311u32,159454369u32,58799269u32,58815654u32,58823847u32, 92394664u32,58856618u32,125973675u32,159544494u32,125998258u32,126006453u32, 58905784u32,58913977u32,58938554u32,92501179u32,126063805u32,58995904u32, 59020481u32,361026754u32,159708364u32,293934288u32,126170328u32,92624091u32, 193295581u32,126194914u32,361100517u32,126227695u32,159790322u32,59151606u32, 59159799u32,59167992u32,59176185u32,92738810u32,260519164u32,260527363u32, 126326026u32,59225357u32,361223438u32,126350616u32,59249947u32,126367004u32, 126375199u32,227046690u32,126399784u32,59299115u32,126416172u32,59315503u32, 59323696u32,260658481u32,126448952u32,92910907u32,462034237u32,160052554u32, 193615182u32,394949971u32,92968286u32,92976480u32,227202402u32,59438440u32, 227218793u32,260781423u32,395015542u32,59479425u32,428594562u32,1133254030u32, 294401455u32,260863415u32,596415934u32,126662095u32,629986770u32,93124068u32, 495785446u32,428684788u32,59610624u32,160290305u32,59643397u32,126760454u32, 59659785u32,160347658u32,126801422u32,126817809u32,126826004u32,59725335u32, 93304344u32,93312538u32,462427676u32,59815465u32,59823658u32,126940715u32, 59856430u32,93435439u32,160577073u32,59921973u32,462583350u32,59946563u32, 127063620u32,160626247u32,59971147u32,60003916u32,60028493u32,261363278u32, 60044885u32,127161942u32,395605593u32,194295396u32,93640297u32,60094059u32, 60110444u32,395679341u32,295024248u32,160831104u32,496383620u32,160847506u32, 60192406u32,60200599u32,462861976u32,60216997u32,194442918u32,60233387u32, 194475692u32,127375025u32,160945844u32,60290744u32,93853369u32,228079291u32, 194533057u32,160986822u32,160995018u32,127448782u32,194574033u32,261699286u32, 127489757u32,228161248u32,60397286u32,127514343u32,328849130u32,362411763u32, 194647805u32,362436354u32,161117964u32,60462864u32,228243217u32,362469143u32, 429586209u32,765138733u32,362493763u32,60512077u32,60520270u32,127637327u32, 127653714u32,60585813u32,60594006u32,60602199u32,261936984u32,127735647u32, 161306466u32,127760230u32,94213993u32,60667755u32,60675948u32,60684141u32, 60692334u32,127817583u32,60725106u32,161396595u32,94304119u32,94312313u32, 127874939u32,127891326u32,94369665u32,195041155u32,60839816u32,60848009u32, 94410634u32,429963148u32,429971352u32,60888996u32,128014245u32,60913576u32, 262272937u32,128087984u32,161650611u32,61003703u32,61011896u32,161683385u32, 61028285u32,94590910u32, ] const GB18030RunsOffset* = 19970u16 const GB18030Runs2*: array[1626, uint32] = [ 67108864u32,33562626u32,201351171u32,67149833u32,67223563u32,33685517u32, 134373390u32,33718290u32,201498643u32,100843545u32,134406172u32,33751072u32, 100884513u32,67362852u32,67379238u32,100941864u32,33865771u32,67428396u32, 67436590u32,67444784u32,134578226u32,436584502u32,67493955u32,33947717u32, 134619206u32,268845130u32,369516626u32,33988701u32,470204510u32,168222828u32, 67567729u32,34021491u32,34029684u32,67592309u32,67600503u32,134717561u32, 134725757u32,101179521u32,67633284u32,201859206u32,34095244u32,67657869u32, 34128015u32,101253264u32,67707027u32,134832277u32,34177177u32,168403098u32, 67764383u32,34218145u32,235569314u32,134914217u32,34259117u32,134930606u32, 34275506u32,34283699u32,101400756u32,134963383u32,537624763u32,34316491u32, 67887308u32,135012558u32,302801106u32,202154203u32,67944673u32,34406627u32, 34414820u32,34423013u32,34431206u32,34439399u32,68002024u32,168698090u32, 135151855u32,638476531u32,34504966u32,34513159u32,34545928u32,437215497u32, 68124950u32,168796440u32,202367261u32,34603299u32,34619684u32,101736741u32, 101744936u32,68198699u32,34652461u32,370204974u32,34668857u32,269558074u32, 538018114u32,772907346u32,303153513u32,34726258u32,34734451u32,34742644u32, 34767221u32,236102006u32,135455101u32,34800001u32,236142978u32,135487881u32, 269713805u32,34840981u32,34849174u32,34857367u32,135528856u32,34890140u32, 68452765u32,169124255u32,68469156u32,34931110u32,34955687u32,34996648u32, 35004841u32,35021226u32,68592043u32,35045805u32,135717294u32,68616626u32, 68624820u32,35086774u32,135766455u32,135774651u32,270025151u32,102269383u32, 236495306u32,35176913u32,102293970u32,169419221u32,102318554u32,68772317u32, 135889375u32,102343139u32,35242470u32,35258855u32,35267048u32,35283433u32, 68854250u32,35308012u32,35332589u32,169574894u32,35373555u32,68993524u32, 69009910u32,102588920u32,35512827u32,69100028u32,136217086u32,35561986u32, 35586563u32,69149188u32,69157382u32,102720008u32,35635723u32,35660300u32, 136339981u32,69247505u32,136364563u32,69263895u32,69272089u32,35742235u32, 35750428u32,136421917u32,35766817u32,102883874u32,136446501u32,35791401u32, 35815978u32,102933035u32,35840558u32,35848751u32,69427760u32,35897906u32, 69460531u32,69468725u32,69493303u32,103055929u32,35955260u32,69534269u32, 270869055u32,203776583u32,36012621u32,170238542u32,36029011u32,136700500u32, 237371992u32,103162463u32,270942818u32,69624426u32,36078188u32,103203437u32, 36102768u32,36110961u32,69689970u32,69698164u32,69706358u32,36160120u32, 69722745u32,69730939u32,338174589u32,304628359u32,69755536u32,36217490u32, 338215571u32,69788317u32,69796511u32,36258465u32,36266658u32,69829283u32, 36324005u32,36332198u32,69911207u32,103473833u32,170590892u32,271262385u32, 36397753u32,36414138u32,103531195u32,69993150u32,36446912u32,70009537u32, 70017731u32,70025925u32,36496071u32,36504264u32,372056777u32,137192148u32, 36545240u32,103662297u32,36561628u32,103686877u32,36586208u32,170812129u32, 36627174u32,36635367u32,103752424u32,36659947u32,103777004u32,271557359u32, 271573751u32,170926847u32,36733700u32,36750085u32,70312710u32,405873416u32, 103891732u32,103924503u32,204604186u32,70411040u32,405971746u32,36889390u32, 70452015u32,36905777u32,36913970u32,36930355u32,104047412u32,70501175u32, 36954937u32,171180858u32,36971327u32,36979520u32,439640897u32,305431374u32, 104112983u32,171238234u32,37036895u32,37045088u32,37053281u32,37061474u32, 137757539u32,70656871u32,37110633u32,137782122u32,204940142u32,70730612u32, 104301430u32,37208953u32,37217146u32,37241723u32,37249916u32,37266301u32, 104383358u32,37282689u32,37307266u32,70869891u32,70886277u32,104448903u32, 70902666u32,37397388u32,37405581u32,138077070u32,37421970u32,138093459u32, 37438359u32,37446552u32,37454745u32,71017370u32,171705244u32,406594465u32, 272417709u32,138208181u32,339542969u32,37561283u32,71123908u32,71148486u32, 37602248u32,104719305u32,37626828u32,71205837u32,37659599u32,37667792u32, 37675985u32,37684178u32,272573395u32,138396635u32,138404831u32,71304163u32, 104866789u32,104874984u32,138453995u32,104907759u32,104924146u32,474031093u32, 104940547u32,172057606u32,37848075u32,71410700u32,71418894u32,205644816u32, 104989718u32,440542233u32,339887142u32,172123184u32,507675701u32,172139588u32, 37946441u32,37954634u32,138634315u32,37979215u32,306431056u32,71558233u32, 71574619u32,38077533u32,71640158u32,38093920u32,138773601u32,38118501u32, 239453286u32,38143085u32,172369006u32,71722099u32,138847349u32,138855545u32, 340190333u32,407307399u32,373761171u32,172442782u32,38249635u32,38266020u32, 38282405u32,71845030u32,71853224u32,38306986u32,38315179u32,105432236u32, 71894191u32,71902385u32,206128307u32,105473209u32,38380732u32,38397117u32, 38405310u32,38413503u32,38421696u32,239764673u32,72000712u32,38454474u32, 72017099u32,38470861u32,72041678u32,139158736u32,38503636u32,172737749u32, 72082650u32,72090844u32,105653470u32,38552801u32,72115426u32,508331236u32, 105686259u32,38585590u32,38593783u32,38618360u32,206398713u32,340624639u32, 172860681u32,810403086u32,105768230u32,38667561u32,139371818u32,38733102u32, 38749487u32,38757680u32,139429169u32,105882933u32,72344888u32,105932090u32, 38839613u32,139519294u32,38872386u32,105989443u32,173114694u32,374449483u32, 374457686u32,340911457u32,72484203u32,139601261u32,72516977u32,38970739u32, 206759284u32,38995322u32,307438971u32,72574340u32,39028102u32,106145159u32, 39052682u32,39060875u32,39069068u32,106194317u32,39093648u32,72656273u32, 106227091u32,39126422u32,72689047u32,39142809u32,106259866u32,39175581u32, 39183774u32,39208351u32,72770976u32,39224738u32,139896227u32,39241127u32, 39249320u32,39257513u32,207037866u32,39273904u32,39282097u32,39290290u32, 72861107u32,39339445u32,39347638u32,39355831u32,39364024u32,39380409u32, 72943034u32,39396796u32,374949309u32,72967624u32,72984010u32,39437772u32, 39445965u32,39454158u32,73016783u32,39470545u32,140142034u32,240813526u32, 73049565u32,106612191u32,39519714u32,140191203u32,106653159u32,106669546u32, 106735085u32,73188848u32,106751474u32,274531829u32,140322301u32,140338689u32, 140346885u32,39691785u32,173917706u32,73270799u32,106833425u32,106841620u32, 106858007u32,106866202u32,73319965u32,173991455u32,140445220u32,39790120u32, 274679337u32,106915377u32,73377332u32,207603254u32,274720316u32,207619652u32, 73418314u32,442525260u32,207652441u32,375449183u32,1247872618u32,207701647u32, 375498389u32,241288864u32,73533095u32,39986857u32,107112106u32,73590445u32, 40044207u32,140723888u32,107177652u32,73631415u32,174319289u32,73664190u32, 73688768u32,107251394u32,40150725u32,40167110u32,40175303u32,241518280u32, 40216271u32,73778896u32,73787090u32,241575636u32,208029403u32,275146465u32, 73828073u32,476489451u32,711378681u32,40298254u32,140969743u32,107423507u32, 107431702u32,2087151385u32,275220311u32,1550296927u32,241682317u32, 4268222356u32,443017235u32,174589984u32,174598181u32,1952991274u32,812148836u32, 107513980u32,40527999u32,40568960u32,74172545u32,40822915u32,40929412u32, 40986757u32,41085062u32,41216135u32,41257096u32,41363593u32,41560202u32, 41568395u32,242903180u32,41584787u32,343591060u32,75171998u32,41633952u32, 41650337u32,142321826u32,41666726u32,175900839u32,108816556u32,75270319u32, 41732273u32,142403762u32,142411958u32,75311290u32,276646076u32,41773252u32, 41781445u32,176007366u32,176015563u32,75360464u32,41830610u32,75393235u32, 75401429u32,243181783u32,41871582u32,176097503u32,75450596u32,41912550u32, 41920743u32,109037800u32,142600427u32,41945327u32,41953520u32,176179441u32, 75532534u32,209758456u32,109119742u32,75581697u32,142698755u32,42043655u32, 42060040u32,243394825u32,109193488u32,42101011u32,142797076u32,75712792u32, 42166554u32,42174747u32,75778332u32,109340958u32,42240289u32,75802914u32, 210069796u32,42305834u32,42314027u32,75901228u32,42354990u32,42363183u32, 75925808u32,75942194u32,109504820u32,143092023u32,42436923u32,109553980u32, 42453311u32,478669120u32,210250062u32,445139284u32,76056929u32,42518883u32, 42535268u32,42543461u32,210332006u32,76122476u32,42576238u32,42584431u32, 42617200u32,42649969u32,109775218u32,42690933u32,42715510u32,42731895u32, 76294520u32,76302714u32,42756476u32,42830205u32,177056126u32,244189571u32, 42879370u32,76482955u32,76491149u32,42953103u32,43010448u32,43059601u32, 43067794u32,43075987u32,43084180u32,143763861u32,110217625u32,76671388u32, 76687774u32,43198880u32,43207073u32,43215266u32,110332323u32,445884838u32, 76794291u32,43248053u32,110373302u32,43272633u32,177498554u32,244615615u32, 43297222u32,43305415u32,110438856u32,43346379u32,110479820u32,177605071u32, 144058836u32,43403736u32,43411929u32,110528986u32,43436509u32,77007326u32, 144124384u32,43526628u32,177752549u32,43543018u32,144214507u32,43559407u32, 211339760u32,77130230u32,177818104u32,77163005u32,43616767u32,43624960u32, 278514177u32,211413513u32,144321039u32,77244947u32,110807573u32,43706904u32, 748358169u32,110832175u32,77285938u32,43739700u32,177973813u32,211544634u32, 43788864u32,43797057u32,43821634u32,178063939u32,77417032u32,43870794u32, 43878987u32,211659340u32,43903570u32,43919955u32,144607828u32,43952728u32, 43985497u32,44010074u32,44067419u32,77630044u32,178301534u32,77646435u32, 44100197u32,44108390u32,111225447u32,279005802u32,44132978u32,144804467u32, 279030391u32,178375295u32,44182148u32,144870021u32,77777545u32,77802123u32, 44255885u32,111372942u32,44272273u32,44288658u32,44313235u32,144992916u32, 77908632u32,44370586u32,44378779u32,77941404u32,44411550u32,44493471u32, 78064288u32,111643298u32,78105253u32,78113447u32,78121641u32,44583595u32, 44632748u32,44673709u32,78244526u32,44706480u32,44739249u32,145435314u32, 111889078u32,44788409u32,78351034u32,78359228u32,44812990u32,44821183u32, 179047104u32,78457541u32,44911303u32,44927688u32,78490313u32,44952267u32, 78514892u32,346974926u32,78555864u32,45026010u32,45034203u32,45042396u32, 45075165u32,45099742u32,112216799u32,78670562u32,78678756u32,45140710u32, 179366631u32,45181676u32,179407597u32,45214450u32,45247219u32,246680308u32, 78924539u32,246721277u32,78965508u32,146082566u32,112536330u32,146107149u32, 79006481u32,45468435u32,45476628u32,246811413u32,146180892u32,45558560u32, 45599521u32,79170338u32,112741156u32,45640487u32,79203112u32,45656874u32, 79219499u32,146336557u32,45681457u32,45689650u32,112806707u32,45714230u32, 112847671u32,112855866u32,179981117u32,180005698u32,112913223u32,112921418u32, 45820749u32,45837134u32,146508623u32,45886291u32,213666644u32,113011546u32, 213691229u32,280841059u32,213740395u32,113085297u32,280873844u32,347990908u32, 180226950u32,46017419u32,146713484u32,46058384u32,180284305u32,46074774u32, 113208215u32,46107546u32,46115739u32,46132124u32,46140317u32,247475102u32, 146820005u32,46181289u32,46197674u32,281086891u32,46214067u32,79776692u32, 146893750u32,448891834u32,79801287u32,46255049u32,113372106u32,79842253u32, 46296015u32,46304208u32,79866833u32,146983891u32,79891415u32,79899609u32, 46361563u32,79924188u32,214150110u32,46386148u32,79956965u32,46410727u32, 180644840u32,113544173u32,381987824u32,80006139u32,415558653u32,147131401u32, 46476301u32,113593358u32,80047121u32,147164179u32,46509079u32,314952728u32, 348523553u32,180808747u32,147262512u32,382168116u32,80186431u32,147303489u32, 180866117u32,113765450u32,315100237u32,46672982u32,147344471u32,80260187u32, 180931677u32,46730338u32,248065123u32,382291050u32,248089717u32,113880188u32, 46779519u32,113896576u32,214584451u32,46820489u32,248155274u32,248163473u32, 181062808u32,80415901u32,46869663u32,214650016u32,248212646u32,147557549u32, 583773361u32,114019522u32,181136581u32,382471370u32,147598549u32,550259929u32, 46951657u32,483167466u32,114076920u32,550292731u32,80571659u32,181243149u32, 114142482u32,114150677u32,281931032u32,47066400u32,80629025u32,248409379u32, 248491306u32,181415217u32,47205686u32,214986039u32,181447997u32,80801090u32, 47279428u32,80842053u32,80866631u32,114445641u32,181562700u32,114462033u32, 47361364u32,47377749u32,80956758u32,80989528u32,114552154u32,47459677u32, 81022302u32,148147552u32,148155748u32,114609512u32,47517035u32,114666860u32, 148237679u32,47582579u32,47590772u32,114716021u32,81194360u32,148311418u32, 47664510u32,47672703u32,47689088u32,47697281u32,47705474u32,81268099u32, 47738245u32,114855302u32,148417929u32,81317261u32,81325455u32,81333649u32, 114896275u32,81350038u32,249138584u32,81391007u32,47844769u32,148516258u32, 114970022u32,47869353u32,215649706u32,81440176u32,282791346u32,47918522u32, 115035579u32,47934910u32,148606399u32,115084739u32,47992262u32,81554887u32, 81563081u32,48016843u32,182242764u32,115142097u32,249368020u32,282930651u32, 81612259u32,48082405u32,115199462u32,48098793u32,148770282u32,81669614u32, 81677808u32,182349298u32,115248631u32,182373882u32,249507327u32,148852230u32, 148860426u32,148868622u32,115322386u32,350211605u32,148893215u32,148901411u32, 216018471u32,283135533u32,48262709u32,148942390u32,182505018u32,518065727u32, 216084046u32,81874516u32,115437142u32,115445337u32,216125020u32,216141410u32, 81931880u32,48385642u32,249720427u32,81989234u32,48451188u32,48467573u32, 48475766u32,48483959u32,149155448u32,182718076u32,48524929u32,48541314u32, 82112131u32,82120325u32,48574087u32,149245576u32,115699340u32,182816399u32, 182824596u32,48615065u32,216395418u32,48631456u32,115748513u32,182865572u32, 149319337u32,149327533u32,82235057u32,82251443u32,149368501u32,115822265u32, 48721596u32,82292413u32,182972095u32,82316996u32,82349766u32,250130120u32, 48819919u32,115945168u32,82407123u32,48860885u32,115977942u32,250203865u32, 183103200u32,48893669u32,183127782u32,183152363u32,116051696u32,149614323u32, 149630711u32,116084475u32,48983806u32,350981887u32,82554633u32,854314763u32, 216796964u32,686567210u32,116150078u32,49049409u32,49057602u32,82620227u32, 1961676613u32,49090431u32,49164160u32,116313985u32,116322180u32,49221511u32, 49229704u32,149901193u32,49246093u32,149925774u32,116379538u32,116387733u32, 418385816u32,217067428u32,1827688362u32,317747168u32,1626378217u32,519090201u32, 284225576u32,3874558000u32,1022439587u32,2129744065u32,183595264u32, 1727107333u32,49484088u32,49516857u32,49590586u32,49680699u32,49746236u32, 49951037u32,50196798u32,50360639u32,319000896u32,151236937u32,50590029u32, 84152654u32,285487440u32,151277912u32,218394972u32,251965794u32,251982185u32, 151327088u32,252014964u32,84251003u32,117813629u32,50721152u32,252055937u32, 117846408u32,4278604171u32,184963594u32,50770447u32,84718096u32,51196434u32, 51253779u32,51294740u32,118419989u32,51319320u32,84881945u32,84890139u32, 319812125u32,84939302u32,152064552u32,185635372u32,84980273u32,353423923u32, 118551101u32,454103616u32,51458637u32,85037646u32,51491408u32,51499601u32, 51507794u32,118633043u32,51540566u32,152212055u32,51565147u32,51581532u32, 152253021u32,85160545u32,51622499u32,118755940u32,118772327u32,51671658u32, 85250667u32,118813293u32,51712624u32,51720817u32,51761778u32,253096563u32, 118887034u32,51794557u32,85357182u32,152474240u32,286700164u32,85398156u32, 186077838u32,51876499u32,51884692u32,51901077u32,119018134u32,119026329u32, 85488284u32,85496478u32,51966624u32,85529249u32,186233507u32,219804328u32, 421139118u32,85603002u32,85611196u32,52073150u32,52089535u32,52097728u32, 52105921u32,186331842u32,85676743u32,52130505u32,119247562u32,52146893u32, 253481678u32,119280341u32,253506264u32,52187871u32,421294816u32,85766892u32, 85775086u32,253555440u32,656216823u32,4280103690u32,823997321u32,52278177u32, 52450210u32,52540323u32,52581284u32,52663205u32,119788454u32,153351081u32, 52704173u32,153375662u32,153392050u32,86291382u32,119854008u32,86315963u32, 52777917u32,52794302u32,187028415u32,52818884u32,52835269u32,86414278u32, 52876232u32,86471625u32,52925387u32,52949964u32,52982733u32,52999118u32, 86561743u32,120124369u32,120148948u32,86602711u32,86660057u32,53130203u32, 53138396u32,53171165u32,53179358u32,86750175u32,53212129u32,120370146u32, 221041637u32,187511787u32,53310448u32,86873073u32,53335027u32,86897652u32, 53359606u32,86922231u32,187593721u32,53384190u32,120534015u32,86995970u32, 221221892u32,53466122u32,87028747u32,154145805u32,187716625u32,254841878u32, 53523485u32,53539870u32,154219551u32,87118883u32,187790373u32,53580842u32, 53589035u32,53597228u32,53605421u32,53613614u32,53621807u32,120738864u32, 87209011u32,120771637u32,53670968u32,53679161u32,53711930u32,53744699u32, 87331900u32,87340094u32,87348288u32,53810242u32,87372867u32,120935493u32, 53859400u32,120976457u32,120984652u32,121009231u32,121025618u32,87495765u32, 53949527u32,53957720u32,154629209u32,121082973u32,154645600u32,121107556u32, 54006887u32,691549288u32,154686588u32,121140352u32,389592195u32,54056078u32, 255390863u32,322507926u32,87635103u32,87643297u32,54154403u32,154825892u32, 87725224u32,87733418u32,87749804u32,121345198u32,54252721u32,54260914u32, 54301875u32,121459892u32,188593335u32,54383804u32,54391997u32,54400190u32, 87979199u32,255775937u32,222237896u32,222254286u32,88044756u32,155178198u32, 155194586u32,423638238u32,54547690u32,54564075u32,54596844u32,356594925u32, 4282471671u32,826365302u32,859927950u32,1061262759u32,859944390u32, 3946960351u32,1463940692u32,1229067903u32,1967273635u32,390223581u32, 3477239528u32,1497536335u32,860010363u32,54802324u32,54835093u32,54843286u32, 55220119u32,55277464u32,88856473u32,55343003u32,55433116u32,55596957u32, 55859102u32,55883679u32,55932832u32,56022945u32,56096674u32,56137635u32, 56170404u32,56186789u32,56260518u32,56293287u32,56334248u32,56440745u32, 90036138u32,291370924u32,3512604596u32,56530972u32,56678429u32,56735774u32, 56825887u32,56858656u32,56875041u32,56891426u32,56899619u32,258242596u32, 124033067u32,90486830u32,157644848u32,57006132u32,57022517u32,57030710u32, 57079863u32,90658872u32,124221498u32,191346749u32,124246082u32,57145413u32, 57161798u32,90724423u32,57202761u32,191428682u32,57219151u32,459905104u32, 57268317u32,90830942u32,57284704u32,57292897u32,124418146u32,90871909u32, 90896487u32,359340137u32,292239475u32,90921083u32,90929277u32,90937471u32, 90945665u32,57415811u32,90986628u32,57464966u32,91027591u32,91060361u32, 91068555u32,359512205u32,258857111u32,158218398u32,124672162u32,91125925u32, 57587879u32,158259368u32,57604268u32,91175085u32,57628847u32,124770480u32, 124795059u32,91248822u32,191920312u32,57710781u32,393263294u32,91281609u32, 91289803u32,57743565u32,191969486u32,158431443u32,661756119u32,91347178u32, 91355372u32,57809134u32,91371759u32,57825521u32,91404530u32,124967156u32, 326301943u32,57882880u32,192108801u32,292780294u32,192125198u32,57915667u32, 125032724u32,57940247u32,125057304u32,259283227u32,91519266u32,259299620u32, 57981227u32,57989420u32,91552045u32,58005807u32,1668626736u32,58030433u32, 192289122u32,58079591u32,4252399976u32,58276326u32,58292711u32,58317288u32, 58333673u32,58358250u32,58431979u32,1299978732u32,92027410u32,58497556u32, 92060181u32,125639191u32,259873306u32,1232968225u32,92125765u32,998103623u32, 1266547300u32,461257353u32,58612374u32,58620567u32,58718872u32,92306073u32, 58759835u32,58776220u32,92355229u32,58841759u32,58858144u32,58866337u32, 394500770u32,92519085u32,4286831279u32,2307119918u32,59022194u32,59153267u32, 59194228u32,92773237u32,92814199u32,59284345u32,59382650u32,260725627u32, 160078722u32,59440006u32,59448199u32,126565256u32,93035403u32,193706893u32, 160168850u32,59513750u32,160185239u32,227302299u32,59538337u32,160209826u32, 160218022u32,59562922u32,59571115u32,328014764u32,59587509u32,260922294u32, 160267197u32,227384257u32,126729159u32,395172810u32,126745557u32,395189208u32, 93207523u32,294542309u32,160340973u32,59718641u32,126852082u32,59751413u32, 59759606u32,93322231u32,4287634425u32,4287634552u32,1401953527u32,93338912u32, 59792674u32,93363491u32,93396261u32,59850023u32,59866408u32,59890985u32, 160570666u32,59931950u32,60030255u32,60038448u32,60054833u32,60128562u32, 194379059u32,93756728u32,93814074u32,93871420u32,93904190u32,4288216384u32, 4288216511u32,2107178558u32,60399228u32,60415613u32,60464766u32,60472959u32, 60497536u32,94101121u32,60571267u32,60669572u32,60685957u32,127803014u32, 60702345u32,60718730u32,60743307u32,161414796u32,60767888u32,94387857u32, 60849811u32,362847892u32,94428830u32,161545888u32,94453412u32,228679334u32, 329359020u32,60931765u32,228712118u32,463601340u32,128065225u32,94518988u32, 60972750u32,195206863u32,161660628u32,128114392u32,61030107u32,94592732u32, 128155358u32,94609121u32,61079267u32,61095652u32,94658277u32,61112039u32, 61120232u32,161799913u32,329580269u32,61153014u32,61169399u32,430276344u32, 61185796u32,61202181u32,94764806u32,128327432u32,61226763u32,229007116u32, 61243154u32,329686803u32,94813980u32,94822174u32, ] const GB18030RunsOffset2* = 29404u16 const GB18030Decode*: array[9220, uint16] = [ uint16 12288,12289,12290,183,713,711,168,12291,12293,8212,65374,8214,8230,8216,8217, 8220,8221,12308,12309,12296,12297,12298,12299,12300,12301,12302,12303,12310, 12311,12304,12305,177,215,247,8758,8743,8744,8721,8719,8746,8745,8712,8759,8730, 8869,8741,8736,8978,8857,8747,8750,8801,8780,8776,8765,8733,8800,8814,8815,8804, 8805,8734,8757,8756,9794,9792,176,8242,8243,8451,65284,164,65504,65505,8240,167, 8470,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651,9650,8251,8594,8592,8593, 8595,12307,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,59238,59239,59240, 59241,59242,59243,9352,9353,9354,9355,9356,9357,9358,9359,9360,9361,9362,9363, 9364,9365,9366,9367,9368,9369,9370,9371,9332,9333,9334,9335,9336,9337,9338,9339, 9340,9341,9342,9343,9344,9345,9346,9347,9348,9349,9350,9351,9312,9313,9314,9315, 9316,9317,9318,9319,9320,9321,8364,59245,12832,12833,12834,12835,12836,12837, 12838,12839,12840,12841,59246,59247,8544,8545,8546,8547,8548,8549,8550,8551, 8552,8553,8554,8555,59248,59249,65281,65282,65283,65509,65285,65286,65287,65288, 65289,65290,65291,65292,65293,65294,65295,65296,65297,65298,65299,65300,65301, 65302,65303,65304,65305,65306,65307,65308,65309,65310,65311,65312,65313,65314, 65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,65327, 65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,65339,65340, 65341,65342,65343,65344,65345,65346,65347,65348,65349,65350,65351,65352,65353, 65354,65355,65356,65357,65358,65359,65360,65361,65362,65363,65364,65365,65366, 65367,65368,65369,65370,65371,65372,65373,65507,12353,12354,12355,12356,12357, 12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370, 12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383, 12384,12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396, 12397,12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,12408,12409, 12410,12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,12421,12422, 12423,12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,12434,12435, 59250,59251,59252,59253,59254,59255,59256,59257,59258,59259,59260,12449,12450, 12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462,12463, 12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,12476, 12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,12488,12489, 12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,12502, 12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,12513,12514,12515, 12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,12526,12527,12528, 12529,12530,12531,12532,12533,12534,59261,59262,59263,59264,59265,59266,59267, 59268,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931, 932,933,934,935,936,937,59269,59270,59271,59272,59273,59274,59275,59276,945,946, 947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,963,964,965,966,967, 968,969,65040,65042,65041,65043,65044,65045,65046,65077,65078,65081,65082,65087, 65088,65085,65086,65089,65090,65091,65092,65047,65048,65083,65084,65079,65080, 65073,65049,65075,65076,59287,59288,59289,59290,59291,59292,59293,59294,59295, 1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,1054, 1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070, 1071,59296,59297,59298,59299,59300,59301,59302,59303,59304,59305,59306,59307, 59308,59309,59310,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,1082, 1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098, 1099,1100,1101,1102,1103,59311,59312,59313,59314,59315,59316,59317,59318,59319, 59320,59321,59322,59323,714,715,729,8211,8213,8229,8245,8453,8457,8598,8599, 8600,8601,8725,8735,8739,8786,8806,8807,8895,9552,9553,9554,9555,9556,9557,9558, 9559,9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574, 9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9601,9602,9603, 9604,9605,9606,9607,9608,9609,9610,9611,9612,9613,9614,9615,9619,9620,9621,9660, 9661,9698,9699,9700,9701,9737,8853,12306,12317,12318,59324,59325,59326,59327, 59328,59329,59330,59331,59332,59333,59334,257,225,462,224,275,233,283,232,299, 237,464,236,333,243,466,242,363,250,468,249,470,472,474,476,252,234,593,7743, 324,328,505,609,59337,59338,59339,59340,12549,12550,12551,12552,12553,12554, 12555,12556,12557,12558,12559,12560,12561,12562,12563,12564,12565,12566,12567, 12568,12569,12570,12571,12572,12573,12574,12575,12576,12577,12578,12579,12580, 12581,12582,12583,12584,12585,59341,59342,59343,59344,59345,59346,59347,59348, 59349,59350,59351,59352,59353,59354,59355,59356,59357,59358,59359,59360,59361, 12321,12322,12323,12324,12325,12326,12327,12328,12329,12963,13198,13199,13212, 13213,13214,13217,13252,13262,13265,13266,13269,65072,65506,65508,59362,8481, 12849,59363,8208,59364,59365,59366,12540,12443,12444,12541,12542,12294,12445, 12446,65097,65098,65099,65100,65101,65102,65103,65104,65105,65106,65108,65109, 65110,65111,65113,65114,65115,65116,65117,65118,65119,65120,65121,65122,65123, 65124,65125,65126,65128,65129,65130,65131,12350,12272,12273,12274,12275,12276, 12277,12278,12279,12280,12281,12282,12283,12295,59380,59381,59382,59383,59384, 59385,59386,59387,59388,59389,59390,59391,59392,9472,9473,9474,9475,9476,9477, 9478,9479,9480,9481,9482,9483,9484,9485,9486,9487,9488,9489,9490,9491,9492,9493, 9494,9495,9496,9497,9498,9499,9500,9501,9502,9503,9504,9505,9506,9507,9508,9509, 9510,9511,9512,9513,9514,9515,9516,9517,9518,9519,9520,9521,9522,9523,9524,9525, 9526,9527,9528,9529,9530,9531,9532,9533,9534,9535,9536,9537,9538,9539,9540,9541, 9542,9543,9544,9545,9546,9547,59393,59394,59395,59396,59397,59398,59399,59400, 59401,59402,59403,59404,59405,59406,59407,57344,57345,57346,57347,57348,57349, 57350,57351,57352,57353,57354,57355,57356,57357,57358,57359,57360,57361,57362, 57363,57364,57365,57366,57367,57368,57369,57370,57371,57372,57373,57374,57375, 57376,57377,57378,57379,57380,57381,57382,57383,57384,57385,57386,57387,57388, 57389,57390,57391,57392,57393,57394,57395,57396,57397,57398,57399,57400,57401, 57402,57403,57404,57405,57406,57407,57408,57409,57410,57411,57412,57413,57414, 57415,57416,57417,57418,57419,57420,57421,57422,57423,57424,57425,57426,57427, 57428,57429,57430,57431,57432,57433,57434,57435,57436,57437,57438,57439,57440, 57441,57442,57443,57444,57445,57446,57447,57448,57449,57450,57451,57452,57453, 57454,57455,57456,57457,57458,57459,57460,57461,57462,57463,57464,57465,57466, 57467,57468,57469,57470,57471,57472,57473,57474,57475,57476,57477,57478,57479, 57480,57481,57482,57483,57484,57485,57486,57487,57488,57489,57490,57491,57492, 57493,57494,57495,57496,57497,57498,57499,57500,57501,57502,57503,57504,57505, 57506,57507,57508,57509,57510,57511,57512,57513,57514,57515,57516,57517,57518, 57519,57520,57521,57522,57523,57524,57525,57526,57527,57528,57529,57530,57531, 57532,57533,57534,57535,57536,57537,57538,57539,57540,57541,57542,57543,57544, 57545,57546,57547,57548,57549,57550,57551,57552,57553,57554,57555,57556,57557, 57558,57559,57560,57561,57562,57563,57564,57565,57566,57567,57568,57569,57570, 57571,57572,57573,57574,57575,57576,57577,57578,57579,57580,57581,57582,57583, 57584,57585,57586,57587,57588,57589,57590,57591,57592,57593,57594,57595,57596, 57597,57598,57599,57600,57601,57602,57603,57604,57605,57606,57607,57608,57609, 57610,57611,57612,57613,57614,57615,57616,57617,57618,57619,57620,57621,57622, 57623,57624,57625,57626,57627,57628,57629,57630,57631,57632,57633,57634,57635, 57636,57637,57638,57639,57640,57641,57642,57643,57644,57645,57646,57647,57648, 57649,57650,57651,57652,57653,57654,57655,57656,57657,57658,57659,57660,57661, 57662,57663,57664,57665,57666,57667,57668,57669,57670,57671,57672,57673,57674, 57675,57676,57677,57678,57679,57680,57681,57682,57683,57684,57685,57686,57687, 57688,57689,57690,57691,57692,57693,57694,57695,57696,57697,57698,57699,57700, 57701,57702,57703,57704,57705,57706,57707,57708,57709,57710,57711,57712,57713, 57714,57715,57716,57717,57718,57719,57720,57721,57722,57723,57724,57725,57726, 57727,57728,57729,57730,57731,57732,57733,57734,57735,57736,57737,57738,57739, 57740,57741,57742,57743,57744,57745,57746,57747,57748,57749,57750,57751,57752, 57753,57754,57755,57756,57757,57758,57759,57760,57761,57762,57763,57764,57765, 57766,57767,57768,57769,57770,57771,57772,57773,57774,57775,57776,57777,57778, 57779,57780,57781,57782,57783,57784,57785,57786,57787,57788,57789,57790,57791, 57792,57793,57794,57795,57796,57797,57798,57799,57800,57801,57802,57803,57804, 57805,57806,57807,57808,57809,57810,57811,57812,57813,57814,57815,57816,57817, 57818,57819,57820,57821,57822,57823,57824,57825,57826,57827,57828,57829,57830, 57831,57832,57833,57834,57835,57836,57837,57838,57839,57840,57841,57842,57843, 57844,57845,57846,57847,57848,57849,57850,57851,57852,57853,57854,57855,57856, 57857,57858,57859,57860,57861,57862,57863,57864,57865,57866,57867,57868,57869, 57870,57871,57872,57873,57874,57875,57876,57877,57878,57879,57880,57881,57882, 57883,57884,57885,57886,57887,57888,57889,57890,57891,57892,57893,57894,57895, 57896,57897,57898,57899,57900,57901,57902,57903,57904,57905,57906,57907,21834, 38463,22467,25384,21710,21769,21696,30353,30284,34108,30702,33406,30861,29233, 38552,38797,27688,23433,20474,25353,26263,23736,33018,26696,32942,26114,30414, 20985,25942,29100,32753,34948,20658,22885,25034,28595,33453,25420,25170,21485, 21543,31494,20843,30116,24052,25300,36299,38774,25226,32793,22365,38712,32610, 29240,30333,26575,30334,25670,20336,36133,25308,31255,26001,29677,25644,25203, 33324,39041,26495,29256,25198,25292,20276,29923,21322,21150,32458,37030,24110, 26758,27036,33152,32465,26834,30917,34444,38225,20621,35876,33502,32990,21253, 35090,21093,34180,38649,20445,22561,39281,23453,25265,25253,26292,35961,40077, 29190,26479,30865,24754,21329,21271,36744,32972,36125,38049,20493,29384,22791, 24811,28953,34987,22868,33519,26412,31528,23849,32503,29997,27893,36454,36856, 36924,40763,27604,37145,31508,24444,30887,34006,34109,27605,27609,27606,24065, 24199,30201,38381,25949,24330,24517,36767,22721,33218,36991,38491,38829,36793, 32534,36140,25153,20415,21464,21342,36776,36777,36779,36941,26631,24426,33176, 34920,40150,24971,21035,30250,24428,25996,28626,28392,23486,25672,20853,20912, 26564,19993,31177,39292,28851,30149,24182,29627,33760,25773,25320,38069,27874, 21338,21187,25615,38082,31636,20271,24091,33334,33046,33162,28196,27850,39539, 25429,21340,21754,34917,22496,19981,24067,27493,31807,37096,24598,25830,29468, 35009,26448,25165,36130,30572,36393,37319,24425,33756,34081,39184,21442,34453, 27531,24813,24808,28799,33485,33329,20179,27815,34255,25805,31961,27133,26361, 33609,21397,31574,20391,20876,27979,23618,36461,25554,21449,33580,33590,26597, 30900,25661,23519,23700,24046,35815,25286,26612,35962,25600,25530,34633,39307, 35863,32544,38130,20135,38416,39076,26124,29462,22330,23581,24120,38271,20607, 32928,21378,25950,30021,21809,20513,36229,25220,38046,26397,22066,28526,24034, 21557,28818,36710,25199,25764,25507,24443,28552,37108,33251,36784,23576,26216, 24561,27785,38472,36225,34924,25745,31216,22478,27225,25104,21576,20056,31243, 24809,28548,35802,25215,36894,39563,31204,21507,30196,25345,21273,27744,36831, 24347,39536,32827,40831,20360,23610,36196,32709,26021,28861,20805,20914,34411, 23815,23456,25277,37228,30068,36364,31264,24833,31609,20167,32504,30597,19985, 33261,21021,20986,27249,21416,36487,38148,38607,28353,38500,26970,30784,20648, 30679,25616,35302,22788,25571,24029,31359,26941,20256,33337,21912,20018,30126, 31383,24162,24202,38383,21019,21561,28810,25462,38180,22402,26149,26943,37255, 21767,28147,32431,34850,25139,32496,30133,33576,30913,38604,36766,24904,29943, 35789,27492,21050,36176,27425,32874,33905,22257,21254,20174,19995,20945,31895, 37259,31751,20419,36479,31713,31388,25703,23828,20652,33030,30209,31929,28140, 32736,26449,23384,23544,30923,25774,25619,25514,25387,38169,25645,36798,31572, 30249,25171,22823,21574,27513,20643,25140,24102,27526,20195,36151,34955,24453, 36910,24608,32829,25285,20025,21333,37112,25528,32966,26086,27694,20294,24814, 28129,35806,24377,34507,24403,25377,20826,33633,26723,20992,25443,36424,20498, 23707,31095,23548,21040,31291,24764,36947,30423,24503,24471,30340,36460,28783, 30331,31561,30634,20979,37011,22564,20302,28404,36842,25932,31515,29380,28068, 32735,23265,25269,24213,22320,33922,31532,24093,24351,36882,32532,39072,25474, 28359,30872,28857,20856,38747,22443,30005,20291,30008,24215,24806,22880,28096, 27583,30857,21500,38613,20939,20993,25481,21514,38035,35843,36300,29241,30879, 34678,36845,35853,21472,19969,30447,21486,38025,39030,40718,38189,23450,35746, 20002,19996,20908,33891,25026,21160,26635,20375,24683,20923,27934,20828,25238, 26007,38497,35910,36887,30168,37117,30563,27602,29322,29420,35835,22581,30585, 36172,26460,38208,32922,24230,28193,22930,31471,30701,38203,27573,26029,32526, 22534,20817,38431,23545,22697,21544,36466,25958,39039,22244,38045,30462,36929, 25479,21702,22810,22842,22427,36530,26421,36346,33333,21057,24816,22549,34558, 23784,40517,20420,39069,35769,23077,24694,21380,25212,36943,37122,39295,24681, 32780,20799,32819,23572,39285,27953,20108,36144,21457,32602,31567,20240,20047, 38400,27861,29648,34281,24070,30058,32763,27146,30718,38034,32321,20961,28902, 21453,36820,33539,36137,29359,39277,27867,22346,33459,26041,32938,25151,38450, 22952,20223,35775,32442,25918,33778,38750,21857,39134,32933,21290,35837,21536, 32954,24223,27832,36153,33452,37210,21545,27675,20998,32439,22367,28954,27774, 31881,22859,20221,24575,24868,31914,20016,23553,26539,34562,23792,38155,39118, 30127,28925,36898,20911,32541,35773,22857,20964,20315,21542,22827,25975,32932, 23413,25206,25282,36752,24133,27679,31526,20239,20440,26381,28014,28074,31119, 34993,24343,29995,25242,36741,20463,37340,26023,33071,33105,24220,33104,36212, 21103,35206,36171,22797,20613,20184,38428,29238,33145,36127,23500,35747,38468, 22919,32538,21648,22134,22030,35813,25913,27010,38041,30422,28297,24178,29976, 26438,26577,31487,32925,36214,24863,31174,25954,36195,20872,21018,38050,32568, 32923,32434,23703,28207,26464,31705,30347,39640,33167,32660,31957,25630,38224, 31295,21578,21733,27468,25601,25096,40509,33011,30105,21106,38761,33883,26684, 34532,38401,38548,38124,20010,21508,32473,26681,36319,32789,26356,24218,32697, 22466,32831,26775,24037,25915,21151,24685,40858,20379,36524,20844,23467,24339, 24041,27742,25329,36129,20849,38057,21246,27807,33503,29399,22434,26500,36141, 22815,36764,33735,21653,31629,20272,27837,23396,22993,40723,21476,34506,39592, 35895,32929,25925,39038,22266,38599,21038,29916,21072,23521,25346,35074,20054, 25296,24618,26874,20851,23448,20896,35266,31649,39302,32592,24815,28748,36143, 20809,24191,36891,29808,35268,22317,30789,24402,40863,38394,36712,39740,35809, 30328,26690,26588,36330,36149,21053,36746,28378,26829,38149,37101,22269,26524, 35065,36807,21704,39608,23401,28023,27686,20133,23475,39559,37219,25000,37039, 38889,21547,28085,23506,20989,21898,32597,32752,25788,25421,26097,25022,24717, 28938,27735,27721,22831,26477,33322,22741,22158,35946,27627,37085,22909,32791, 21495,28009,21621,21917,33655,33743,26680,31166,21644,20309,21512,30418,35977, 38402,27827,28088,36203,35088,40548,36154,22079,40657,30165,24456,29408,24680, 21756,20136,27178,34913,24658,36720,21700,28888,34425,40511,27946,23439,24344, 32418,21897,20399,29492,21564,21402,20505,21518,21628,20046,24573,29786,22774, 33899,32993,34676,29392,31946,28246,24359,34382,21804,25252,20114,27818,25143, 33457,21719,21326,29502,28369,30011,21010,21270,35805,27088,24458,24576,28142, 22351,27426,29615,26707,36824,32531,25442,24739,21796,30186,35938,28949,28067, 23462,24187,33618,24908,40644,30970,34647,31783,30343,20976,24822,29004,26179, 24140,24653,35854,28784,25381,36745,24509,24674,34516,22238,27585,24724,24935, 21321,24800,26214,36159,31229,20250,28905,27719,35763,35826,32472,33636,26127, 23130,39746,27985,28151,35905,27963,20249,28779,33719,25110,24785,38669,36135, 31096,20987,22334,22522,26426,30072,31293,31215,31637,32908,39269,36857,28608, 35749,40481,23020,32489,32521,21513,26497,26840,36753,31821,38598,21450,24613, 30142,27762,21363,23241,32423,25380,20960,33034,24049,34015,25216,20864,23395, 20238,31085,21058,24760,27982,23492,23490,35745,35760,26082,24524,38469,22931, 32487,32426,22025,26551,22841,20339,23478,21152,33626,39050,36158,30002,38078, 20551,31292,20215,26550,39550,23233,27516,30417,22362,23574,31546,38388,29006, 20860,32937,33392,22904,32516,33575,26816,26604,30897,30839,25315,25441,31616, 20461,21098,20943,33616,27099,37492,36341,36145,35265,38190,31661,20214,20581, 33328,21073,39279,28176,28293,28071,24314,20725,23004,23558,27974,27743,30086, 33931,26728,22870,35762,21280,37233,38477,34121,26898,30977,28966,33014,20132, 37066,27975,39556,23047,22204,25605,38128,30699,20389,33050,29409,35282,39290, 32564,32478,21119,25945,37237,36735,36739,21483,31382,25581,25509,30342,31224, 34903,38454,25130,21163,33410,26708,26480,25463,30571,31469,27905,32467,35299, 22992,25106,34249,33445,30028,20511,20171,30117,35819,23626,24062,31563,26020, 37329,20170,27941,35167,32039,38182,20165,35880,36827,38771,26187,31105,36817, 28908,28024,23613,21170,33606,20834,33550,30555,26230,40120,20140,24778,31934, 31923,32463,20117,35686,26223,39048,38745,22659,25964,38236,24452,30153,38742, 31455,31454,20928,28847,31384,25578,31350,32416,29590,38893,20037,28792,20061, 37202,21417,25937,26087,33276,33285,21646,23601,30106,38816,25304,29401,30141, 23621,39545,33738,23616,21632,30697,20030,27822,32858,25298,25454,24040,20855, 36317,36382,38191,20465,21477,24807,28844,21095,25424,40515,23071,20518,30519, 21367,32482,25733,25899,25225,25496,20500,29237,35273,20915,35776,32477,22343, 33740,38055,20891,21531,23803,20426,31459,27994,37089,39567,21888,21654,21345, 21679,24320,25577,26999,20975,24936,21002,22570,21208,22350,30733,30475,24247, 24951,31968,25179,25239,20130,28821,32771,25335,28900,38752,22391,33499,26607, 26869,30933,39063,31185,22771,21683,21487,28212,20811,21051,23458,35838,32943, 21827,22438,24691,22353,21549,31354,24656,23380,25511,25248,21475,25187,23495, 26543,21741,31391,33510,37239,24211,35044,22840,22446,25358,36328,33007,22359, 31607,20393,24555,23485,27454,21281,31568,29378,26694,30719,30518,26103,20917, 20111,30420,23743,31397,33909,22862,39745,20608,39304,24871,28291,22372,26118, 25414,22256,25324,25193,24275,38420,22403,25289,21895,34593,33098,36771,21862, 33713,26469,36182,34013,23146,26639,25318,31726,38417,20848,28572,35888,25597, 35272,25042,32518,28866,28389,29701,27028,29436,24266,37070,26391,28010,25438, 21171,29282,32769,20332,23013,37226,28889,28061,21202,20048,38647,38253,34174, 30922,32047,20769,22418,25794,32907,31867,27882,26865,26974,20919,21400,26792, 29313,40654,31729,29432,31163,28435,29702,26446,37324,40100,31036,33673,33620, 21519,26647,20029,21385,21169,30782,21382,21033,20616,20363,20432,30178,31435, 31890,27813,38582,21147,29827,21737,20457,32852,33714,36830,38256,24265,24604, 28063,24088,25947,33080,38142,24651,28860,32451,31918,20937,26753,31921,33391, 20004,36742,37327,26238,20142,35845,25769,32842,20698,30103,29134,23525,36797, 28518,20102,25730,38243,24278,26009,21015,35010,28872,21155,29454,29747,26519, 30967,38678,20020,37051,40158,28107,20955,36161,21533,25294,29618,33777,38646, 40836,38083,20278,32666,20940,28789,38517,23725,39046,21478,20196,28316,29705, 27060,30827,39311,30041,21016,30244,27969,26611,20845,40857,32843,21657,31548, 31423,38534,22404,25314,38471,27004,23044,25602,31699,28431,38475,33446,21346, 39045,24208,28809,25523,21348,34383,40065,40595,30860,38706,36335,36162,40575, 28510,31108,24405,38470,25134,39540,21525,38109,20387,26053,23653,23649,32533, 34385,27695,24459,29575,28388,32511,23782,25371,23402,28390,21365,20081,25504, 30053,25249,36718,20262,20177,27814,32438,35770,33821,34746,32599,36923,38179, 31657,39585,35064,33853,27931,39558,32476,22920,40635,29595,30721,34434,39532, 39554,22043,21527,22475,20080,40614,21334,36808,33033,30610,39314,34542,28385, 34067,26364,24930,28459,35881,33426,33579,30450,27667,24537,33725,29483,33541, 38170,27611,30683,38086,21359,33538,20882,24125,35980,36152,20040,29611,26522, 26757,37238,38665,29028,27809,30473,23186,38209,27599,32654,26151,23504,22969, 23194,38376,38391,20204,33804,33945,27308,30431,38192,29467,26790,23391,30511, 37274,38753,31964,36855,35868,24357,31859,31192,35269,27852,34588,23494,24130, 26825,30496,32501,20885,20813,21193,23081,32517,38754,33495,25551,30596,34256, 31186,28218,24217,22937,34065,28781,27665,25279,30399,25935,24751,38397,26126, 34719,40483,38125,21517,21629,35884,25720,25721,34321,27169,33180,30952,25705, 39764,25273,26411,33707,22696,40664,27819,28448,23518,38476,35851,29279,26576, 25287,29281,20137,22982,27597,22675,26286,24149,21215,24917,26408,30446,30566, 29287,31302,25343,21738,21584,38048,37027,23068,32435,27670,20035,22902,32784, 22856,21335,30007,38590,22218,25376,33041,24700,38393,28118,21602,39297,20869, 23273,33021,22958,38675,20522,27877,23612,25311,20320,21311,33147,36870,28346, 34091,25288,24180,30910,25781,25467,24565,23064,37247,40479,23615,25423,32834, 23421,21870,38218,38221,28037,24744,26592,29406,20957,23425,25319,27870,29275, 25197,38062,32445,33043,27987,20892,24324,22900,21162,24594,22899,26262,34384, 30111,25386,25062,31983,35834,21734,27431,40485,27572,34261,21589,20598,27812, 21866,36276,29228,24085,24597,29750,25293,25490,29260,24472,28227,27966,25856, 28504,30424,30928,30460,30036,21028,21467,20051,24222,26049,32810,32982,25243, 21638,21032,28846,34957,36305,27873,21624,32986,22521,35060,36180,38506,37197, 20329,27803,21943,30406,30768,25256,28921,28558,24429,34028,26842,30844,31735, 33192,26379,40527,25447,30896,22383,30738,38713,25209,25259,21128,29749,27607, 21860,33086,30130,30382,21305,30174,20731,23617,35692,31687,20559,29255,39575, 39128,28418,29922,31080,25735,30629,25340,39057,36139,21697,32856,20050,22378, 33529,33805,24179,20973,29942,35780,23631,22369,27900,39047,23110,30772,39748, 36843,31893,21078,25169,38138,20166,33670,33889,33769,33970,22484,26420,22275, 26222,28006,35889,26333,28689,26399,27450,26646,25114,22971,19971,20932,28422, 26578,27791,20854,26827,22855,27495,30054,23822,33040,40784,26071,31048,31041, 39569,36215,23682,20062,20225,21551,22865,30732,22120,27668,36804,24323,27773, 27875,35755,25488,24688,27965,29301,25190,38030,38085,21315,36801,31614,20191, 35878,20094,40660,38065,38067,21069,28508,36963,27973,35892,22545,23884,27424, 27465,26538,21595,33108,32652,22681,34103,24378,25250,27207,38201,25970,24708, 26725,30631,20052,20392,24039,38808,25772,32728,23789,20431,31373,20999,33540, 19988,24623,31363,38054,20405,20146,31206,29748,21220,33465,25810,31165,23517, 27777,38738,36731,27682,20542,21375,28165,25806,26228,27696,24773,39031,35831, 24198,29756,31351,31179,19992,37041,29699,27714,22234,37195,27845,36235,21306, 34502,26354,36527,23624,39537,28192,21462,23094,40843,36259,21435,22280,39079, 26435,37275,27849,20840,30154,25331,29356,21048,21149,32570,28820,30264,21364, 40522,27063,30830,38592,35033,32676,28982,29123,20873,26579,29924,22756,25880, 22199,35753,39286,25200,32469,24825,28909,22764,20161,20154,24525,38887,20219, 35748,20995,22922,32427,25172,20173,26085,25102,33592,33993,33635,34701,29076, 28342,23481,32466,20887,25545,26580,32905,33593,34837,20754,23418,22914,36785, 20083,27741,20837,35109,36719,38446,34122,29790,38160,38384,28070,33509,24369, 25746,27922,33832,33134,40131,22622,36187,19977,21441,20254,25955,26705,21971, 20007,25620,39578,25195,23234,29791,33394,28073,26862,20711,33678,30722,26432, 21049,27801,32433,20667,21861,29022,31579,26194,29642,33515,26441,23665,21024, 29053,34923,38378,38485,25797,36193,33203,21892,27733,25159,32558,22674,20260, 21830,36175,26188,19978,23578,35059,26786,25422,31245,28903,33421,21242,38902, 23569,21736,37045,32461,22882,36170,34503,33292,33293,36198,25668,23556,24913, 28041,31038,35774,30775,30003,21627,20280,36523,28145,23072,32453,31070,27784, 23457,23158,29978,32958,24910,28183,22768,29983,29989,29298,21319,32499,30465, 30427,21097,32988,22307,24072,22833,29422,26045,28287,35799,23608,34417,21313, 30707,25342,26102,20160,39135,34432,23454,35782,21490,30690,20351,23630,39542, 22987,24335,31034,22763,19990,26623,20107,25325,35475,36893,21183,26159,21980, 22124,36866,20181,20365,37322,39280,27663,24066,24643,23460,35270,35797,25910, 25163,39318,23432,23551,25480,21806,21463,30246,20861,34092,26530,26803,27530, 25234,36755,21460,33298,28113,30095,20070,36174,23408,29087,34223,26257,26329, 32626,34560,40653,40736,23646,26415,36848,26641,26463,25101,31446,22661,24246, 25968,28465,24661,21047,32781,25684,34928,29993,24069,26643,25332,38684,21452, 29245,35841,27700,30561,31246,21550,30636,39034,33308,35828,30805,26388,28865, 26031,25749,22070,24605,31169,21496,19997,27515,32902,23546,21987,22235,20282, 20284,39282,24051,26494,32824,24578,39042,36865,23435,35772,35829,25628,33368, 25822,22013,33487,37221,20439,32032,36895,31903,20723,22609,28335,23487,35785, 32899,37240,33948,31639,34429,38539,38543,32485,39635,30862,23681,31319,36930, 38567,31071,23385,25439,31499,34001,26797,21766,32553,29712,32034,38145,25152, 22604,20182,23427,22905,22612,29549,25374,36427,36367,32974,33492,25260,21488, 27888,37214,22826,24577,27760,22349,25674,36138,30251,28393,22363,27264,30192, 28525,35885,35848,22374,27631,34962,30899,25506,21497,28845,27748,22616,25642, 22530,26848,33179,21776,31958,20504,36538,28108,36255,28907,25487,28059,28372, 32486,33796,26691,36867,28120,38518,35752,22871,29305,34276,33150,30140,35466, 26799,21076,36386,38161,25552,39064,36420,21884,20307,26367,22159,24789,28053, 21059,23625,22825,28155,22635,30000,29980,24684,33300,33094,25361,26465,36834, 30522,36339,36148,38081,24086,21381,21548,28867,27712,24311,20572,20141,24237, 25402,33351,36890,26704,37230,30643,21516,38108,24420,31461,26742,25413,31570, 32479,30171,20599,25237,22836,36879,20984,31171,31361,22270,24466,36884,28034, 23648,22303,21520,20820,28237,22242,25512,39059,33151,34581,35114,36864,21534, 23663,33216,25302,25176,33073,40501,38464,39534,39548,26925,22949,25299,21822, 25366,21703,34521,27964,23043,29926,34972,27498,22806,35916,24367,28286,29609, 39037,20024,28919,23436,30871,25405,26202,30358,24779,23451,23113,19975,33109, 27754,29579,20129,26505,32593,24448,26106,26395,24536,22916,23041,24013,24494, 21361,38886,36829,26693,22260,21807,24799,20026,28493,32500,33479,33806,22996, 20255,20266,23614,32428,26410,34074,21619,30031,32963,21890,39759,20301,28205, 35859,23561,24944,21355,30239,28201,34442,25991,38395,32441,21563,31283,32010, 38382,21985,32705,29934,25373,34583,28065,31389,25105,26017,21351,25569,27779, 24043,21596,38056,20044,27745,35820,23627,26080,33436,26791,21566,21556,27595, 27494,20116,25410,21320,33310,20237,20398,22366,25098,38654,26212,29289,21247, 21153,24735,35823,26132,29081,26512,35199,30802,30717,26224,22075,21560,38177, 29306,31232,24687,24076,24713,33181,22805,24796,29060,28911,28330,27728,29312, 27268,34989,24109,20064,23219,21916,38115,27927,31995,38553,25103,32454,30606, 34430,21283,38686,36758,26247,23777,20384,29421,19979,21414,22799,21523,25472, 38184,20808,20185,40092,32420,21688,36132,34900,33335,38386,28046,24358,23244, 26174,38505,29616,29486,21439,33146,39301,32673,23466,38519,38480,32447,30456, 21410,38262,39321,31665,35140,28248,20065,32724,31077,35814,24819,21709,20139, 39033,24055,27233,20687,21521,35937,33831,30813,38660,21066,21742,22179,38144, 28040,23477,28102,26195,23567,23389,26657,32918,21880,31505,25928,26964,20123, 27463,34638,38795,21327,25375,25658,37034,26012,32961,35856,20889,26800,21368, 34809,25032,27844,27899,35874,23633,34218,33455,38156,27427,36763,26032,24571, 24515,20449,34885,26143,33125,29481,24826,20852,21009,22411,24418,37026,34892, 37266,24184,26447,24615,22995,20804,20982,33016,21256,27769,38596,29066,20241, 20462,32670,26429,21957,38152,31168,34966,32483,22687,25100,38656,34394,22040, 39035,24464,35768,33988,37207,21465,26093,24207,30044,24676,32110,23167,32490, 32493,36713,21927,23459,24748,26059,29572,36873,30307,30505,32474,38772,34203, 23398,31348,38634,34880,21195,29071,24490,26092,35810,23547,39535,24033,27529, 27739,35757,35759,36874,36805,21387,25276,40486,40493,21568,20011,33469,29273, 34460,23830,34905,28079,38597,21713,20122,35766,28937,21693,38409,28895,28153, 30416,20005,30740,34578,23721,24310,35328,39068,38414,28814,27839,22852,25513, 30524,34893,28436,33395,22576,29141,21388,30746,38593,21761,24422,28976,23476, 35866,39564,27523,22830,40495,31207,26472,25196,20335,30113,32650,27915,38451, 27687,20208,30162,20859,26679,28478,36992,33136,22934,29814,25671,23591,36965, 31377,35875,23002,21676,33280,33647,35201,32768,26928,22094,32822,29239,37326, 20918,20063,39029,25494,19994,21494,26355,33099,22812,28082,19968,22777,21307, 25558,38129,20381,20234,34915,39056,22839,36951,31227,20202,33008,30097,27778, 23452,23016,24413,26885,34433,20506,24050,20057,30691,20197,33402,25233,26131, 37009,23673,20159,24441,33222,36920,32900,30123,20134,35028,24847,27589,24518, 20041,30410,28322,35811,35758,35850,35793,24322,32764,32716,32462,33589,33643, 22240,27575,38899,38452,23035,21535,38134,28139,23493,39278,23609,24341,38544, 21360,33521,27185,23156,40560,24212,32552,33721,33828,33829,33639,34631,36814, 36194,30408,24433,39062,30828,26144,21727,25317,20323,33219,30152,24248,38605, 36362,34553,21647,27891,28044,27704,24703,21191,29992,24189,20248,24736,24551, 23588,30001,37038,38080,29369,27833,28216,37193,26377,21451,21491,20305,37321, 35825,21448,24188,36802,28132,20110,30402,27014,34398,24858,33286,20313,20446, 36926,40060,24841,28189,28180,38533,20104,23089,38632,19982,23679,31161,23431, 35821,32701,29577,22495,33419,37057,21505,36935,21947,23786,24481,24840,27442, 29425,32946,35465,28020,23507,35029,39044,35947,39533,40499,28170,20900,20803, 22435,34945,21407,25588,36757,22253,21592,22278,29503,28304,32536,36828,33489, 24895,24616,38498,26352,32422,36234,36291,38053,23731,31908,26376,24742,38405, 32792,20113,37095,21248,38504,20801,36816,34164,37213,26197,38901,23381,21277, 30776,26434,26685,21705,28798,23472,36733,20877,22312,21681,25874,26242,36190, 36163,33039,33900,36973,31967,20991,34299,26531,26089,28577,34468,36481,22122, 36896,30338,28790,29157,36131,25321,21017,27901,36156,24590,22686,24974,26366, 36192,25166,21939,28195,26413,36711,38113,38392,30504,26629,27048,21643,20045, 28856,35784,25688,25995,23429,31364,20538,23528,30651,27617,35449,31896,27838, 30415,26025,36759,23853,23637,34360,26632,21344,25112,31449,28251,32509,27167, 31456,24432,28467,24352,25484,28072,26454,19976,24080,36134,20183,32960,30260, 38556,25307,26157,25214,27836,36213,29031,32617,20806,32903,21484,36974,25240, 21746,34544,36761,32773,38167,34071,36825,27993,29645,26015,30495,29956,30759, 33275,36126,38024,20390,26517,30137,35786,38663,25391,38215,38453,33976,25379, 30529,24449,29424,20105,24596,25972,25327,27491,25919,24103,30151,37073,35777, 33437,26525,25903,21553,34584,30693,32930,33026,27713,20043,32455,32844,30452, 26893,27542,25191,20540,20356,22336,25351,27490,36286,21482,26088,32440,24535, 25370,25527,33267,33268,32622,24092,23769,21046,26234,31209,31258,36136,28825, 30164,28382,27835,31378,20013,30405,24544,38047,34935,32456,31181,32959,37325, 20210,20247,33311,21608,24030,27954,35788,31909,36724,32920,24090,21650,30385, 23449,26172,39588,29664,26666,34523,26417,29482,35832,35803,36880,31481,28891, 29038,25284,30633,22065,20027,33879,26609,21161,34496,36142,38136,31569,20303, 27880,31069,39547,25235,29226,25341,19987,30742,36716,25776,36186,31686,26729, 24196,35013,22918,25758,22766,29366,26894,38181,36861,36184,22368,32512,35846, 20934,25417,25305,21331,26700,29730,33537,37196,21828,30528,28796,27978,20857, 21672,36164,23039,28363,28100,23388,32043,20180,31869,28371,23376,33258,28173, 23383,39683,26837,36394,23447,32508,24635,32437,37049,36208,22863,25549,31199, 36275,21330,26063,31062,35781,38459,32452,38075,32386,22068,37257,26368,32618, 23562,36981,26152,24038,20304,26590,20570,20316,22352,24231,59408,59409,59410, 59411,59412,20109,19980,20800,19984,24319,21317,19989,20120,19998,39730,23404, 22121,20008,31162,20031,21269,20039,22829,29243,21358,27664,22239,32996,39319, 27603,30590,40727,20022,20127,40720,20060,20073,20115,33416,23387,21868,22031, 20164,21389,21405,21411,21413,21422,38757,36189,21274,21493,21286,21294,21310, 36188,21350,21347,20994,21000,21006,21037,21043,21055,21056,21068,21086,21089, 21084,33967,21117,21122,21121,21136,21139,20866,32596,20155,20163,20169,20162, 20200,20193,20203,20190,20251,20211,20258,20324,20213,20261,20263,20233,20267, 20318,20327,25912,20314,20317,20319,20311,20274,20285,20342,20340,20369,20361, 20355,20367,20350,20347,20394,20348,20396,20372,20454,20456,20458,20421,20442, 20451,20444,20433,20447,20472,20521,20556,20467,20524,20495,20526,20525,20478, 20508,20492,20517,20520,20606,20547,20565,20552,20558,20588,20603,20645,20647, 20649,20666,20694,20742,20717,20716,20710,20718,20743,20747,20189,27709,20312, 20325,20430,40864,27718,31860,20846,24061,40649,39320,20865,22804,21241,21261, 35335,21264,20971,22809,20821,20128,20822,20147,34926,34980,20149,33044,35026, 31104,23348,34819,32696,20907,20913,20925,20924,20935,20886,20898,20901,35744, 35750,35751,35754,35764,35765,35767,35778,35779,35787,35791,35790,35794,35795, 35796,35798,35800,35801,35804,35807,35808,35812,35816,35817,35822,35824,35827, 35830,35833,35836,35839,35840,35842,35844,35847,35852,35855,35857,35858,35860, 35861,35862,35865,35867,35864,35869,35871,35872,35873,35877,35879,35882,35883, 35886,35887,35890,35891,35893,35894,21353,21370,38429,38434,38433,38449,38442, 38461,38460,38466,38473,38484,38495,38503,38508,38514,38516,38536,38541,38551, 38576,37015,37019,37021,37017,37036,37025,37044,37043,37046,37050,37048,37040, 37071,37061,37054,37072,37060,37063,37075,37094,37090,37084,37079,37083,37099, 37103,37118,37124,37154,37150,37155,37169,37167,37177,37187,37190,21005,22850, 21154,21164,21165,21182,21759,21200,21206,21232,21471,29166,30669,24308,20981, 20988,39727,21430,24321,30042,24047,22348,22441,22433,22654,22716,22725,22737, 22313,22316,22314,22323,22329,22318,22319,22364,22331,22338,22377,22405,22379, 22406,22396,22395,22376,22381,22390,22387,22445,22436,22412,22450,22479,22439, 22452,22419,22432,22485,22488,22490,22489,22482,22456,22516,22511,22520,22500, 22493,22539,22541,22525,22509,22528,22558,22553,22596,22560,22629,22636,22657, 22665,22682,22656,39336,40729,25087,33401,33405,33407,33423,33418,33448,33412, 33422,33425,33431,33433,33451,33464,33470,33456,33480,33482,33507,33432,33463, 33454,33483,33484,33473,33449,33460,33441,33450,33439,33476,33486,33444,33505, 33545,33527,33508,33551,33543,33500,33524,33490,33496,33548,33531,33491,33553, 33562,33542,33556,33557,33504,33493,33564,33617,33627,33628,33544,33682,33596, 33588,33585,33691,33630,33583,33615,33607,33603,33631,33600,33559,33632,33581, 33594,33587,33638,33637,33640,33563,33641,33644,33642,33645,33646,33712,33656, 33715,33716,33696,33706,33683,33692,33669,33660,33718,33705,33661,33720,33659, 33688,33694,33704,33722,33724,33729,33793,33765,33752,22535,33816,33803,33757, 33789,33750,33820,33848,33809,33798,33748,33759,33807,33795,33784,33785,33770, 33733,33728,33830,33776,33761,33884,33873,33882,33881,33907,33927,33928,33914, 33929,33912,33852,33862,33897,33910,33932,33934,33841,33901,33985,33997,34000, 34022,33981,34003,33994,33983,33978,34016,33953,33977,33972,33943,34021,34019, 34060,29965,34104,34032,34105,34079,34106,34134,34107,34047,34044,34137,34120, 34152,34148,34142,34170,30626,34115,34162,34171,34212,34216,34183,34191,34169, 34222,34204,34181,34233,34231,34224,34259,34241,34268,34303,34343,34309,34345, 34326,34364,24318,24328,22844,22849,32823,22869,22874,22872,21263,23586,23589, 23596,23604,25164,25194,25247,25275,25290,25306,25303,25326,25378,25334,25401, 25419,25411,25517,25590,25457,25466,25486,25524,25453,25516,25482,25449,25518, 25532,25586,25592,25568,25599,25540,25566,25550,25682,25542,25534,25669,25665, 25611,25627,25632,25612,25638,25633,25694,25732,25709,25750,25722,25783,25784, 25753,25786,25792,25808,25815,25828,25826,25865,25893,25902,24331,24530,29977, 24337,21343,21489,21501,21481,21480,21499,21522,21526,21510,21579,21586,21587, 21588,21590,21571,21537,21591,21593,21539,21554,21634,21652,21623,21617,21604, 21658,21659,21636,21622,21606,21661,21712,21677,21698,21684,21714,21671,21670, 21715,21716,21618,21667,21717,21691,21695,21708,21721,21722,21724,21673,21674, 21668,21725,21711,21726,21787,21735,21792,21757,21780,21747,21794,21795,21775, 21777,21799,21802,21863,21903,21941,21833,21869,21825,21845,21823,21840,21820, 21815,21846,21877,21878,21879,21811,21808,21852,21899,21970,21891,21937,21945, 21896,21889,21919,21886,21974,21905,21883,21983,21949,21950,21908,21913,21994, 22007,21961,22047,21969,21995,21996,21972,21990,21981,21956,21999,21989,22002, 22003,21964,21965,21992,22005,21988,36756,22046,22024,22028,22017,22052,22051, 22014,22016,22055,22061,22104,22073,22103,22060,22093,22114,22105,22108,22092, 22100,22150,22116,22129,22123,22139,22140,22149,22163,22191,22228,22231,22237, 22241,22261,22251,22265,22271,22276,22282,22281,22300,24079,24089,24084,24081, 24113,24123,24124,24119,24132,24148,24155,24158,24161,23692,23674,23693,23696, 23702,23688,23704,23705,23697,23706,23708,23733,23714,23741,23724,23723,23729, 23715,23745,23735,23748,23762,23780,23755,23781,23810,23811,23847,23846,23854, 23844,23838,23814,23835,23896,23870,23860,23869,23916,23899,23919,23901,23915, 23883,23882,23913,23924,23938,23961,23965,35955,23991,24005,24435,24439,24450, 24455,24457,24460,24469,24473,24476,24488,24493,24501,24508,34914,24417,29357, 29360,29364,29367,29368,29379,29377,29390,29389,29394,29416,29423,29417,29426, 29428,29431,29441,29427,29443,29434,29435,29463,29459,29473,29450,29470,29469, 29461,29474,29497,29477,29484,29496,29489,29520,29517,29527,29536,29548,29551, 29566,33307,22821,39143,22820,22786,39267,39271,39272,39273,39274,39275,39276, 39284,39287,39293,39296,39300,39303,39306,39309,39312,39313,39315,39316,39317, 24192,24209,24203,24214,24229,24224,24249,24245,24254,24243,36179,24274,24273, 24283,24296,24298,33210,24516,24521,24534,24527,24579,24558,24580,24545,24548, 24574,24581,24582,24554,24557,24568,24601,24629,24614,24603,24591,24589,24617, 24619,24586,24639,24609,24696,24697,24699,24698,24642,24682,24701,24726,24730, 24749,24733,24707,24722,24716,24731,24812,24763,24753,24797,24792,24774,24794, 24756,24864,24870,24853,24867,24820,24832,24846,24875,24906,24949,25004,24980, 24999,25015,25044,25077,24541,38579,38377,38379,38385,38387,38389,38390,38396, 38398,38403,38404,38406,38408,38410,38411,38412,38413,38415,38418,38421,38422, 38423,38425,38426,20012,29247,25109,27701,27732,27740,27722,27811,27781,27792, 27796,27788,27752,27753,27764,27766,27782,27817,27856,27860,27821,27895,27896, 27889,27863,27826,27872,27862,27898,27883,27886,27825,27859,27887,27902,27961, 27943,27916,27971,27976,27911,27908,27929,27918,27947,27981,27950,27957,27930, 27983,27986,27988,27955,28049,28015,28062,28064,27998,28051,28052,27996,28000, 28028,28003,28186,28103,28101,28126,28174,28095,28128,28177,28134,28125,28121, 28182,28075,28172,28078,28203,28270,28238,28267,28338,28255,28294,28243,28244, 28210,28197,28228,28383,28337,28312,28384,28461,28386,28325,28327,28349,28347, 28343,28375,28340,28367,28303,28354,28319,28514,28486,28487,28452,28437,28409, 28463,28470,28491,28532,28458,28425,28457,28553,28557,28556,28536,28530,28540, 28538,28625,28617,28583,28601,28598,28610,28641,28654,28638,28640,28655,28698, 28707,28699,28729,28725,28751,28766,23424,23428,23445,23443,23461,23480,29999, 39582,25652,23524,23534,35120,23536,36423,35591,36790,36819,36821,36837,36846, 36836,36841,36838,36851,36840,36869,36868,36875,36902,36881,36877,36886,36897, 36917,36918,36909,36911,36932,36945,36946,36944,36968,36952,36962,36955,26297, 36980,36989,36994,37000,36995,37003,24400,24407,24406,24408,23611,21675,23632, 23641,23409,23651,23654,32700,24362,24361,24365,33396,24380,39739,23662,22913, 22915,22925,22953,22954,22947,22935,22986,22955,22942,22948,22994,22962,22959, 22999,22974,23045,23046,23005,23048,23011,23000,23033,23052,23049,23090,23092, 23057,23075,23059,23104,23143,23114,23125,23100,23138,23157,33004,23210,23195, 23159,23162,23230,23275,23218,23250,23252,23224,23264,23267,23281,23254,23270, 23256,23260,23305,23319,23318,23346,23351,23360,23573,23580,23386,23397,23411, 23377,23379,23394,39541,39543,39544,39546,39551,39549,39552,39553,39557,39560, 39562,39568,39570,39571,39574,39576,39579,39580,39581,39583,39584,39586,39587, 39589,39591,32415,32417,32419,32421,32424,32425,32429,32432,32446,32448,32449, 32450,32457,32459,32460,32464,32468,32471,32475,32480,32481,32488,32491,32494, 32495,32497,32498,32525,32502,32506,32507,32510,32513,32514,32515,32519,32520, 32523,32524,32527,32529,32530,32535,32537,32540,32539,32543,32545,32546,32547, 32548,32549,32550,32551,32554,32555,32556,32557,32559,32560,32561,32562,32563, 32565,24186,30079,24027,30014,37013,29582,29585,29614,29602,29599,29647,29634, 29649,29623,29619,29632,29641,29640,29669,29657,39036,29706,29673,29671,29662, 29626,29682,29711,29738,29787,29734,29733,29736,29744,29742,29740,29723,29722, 29761,29788,29783,29781,29785,29815,29805,29822,29852,29838,29824,29825,29831, 29835,29854,29864,29865,29840,29863,29906,29882,38890,38891,38892,26444,26451, 26462,26440,26473,26533,26503,26474,26483,26520,26535,26485,26536,26526,26541, 26507,26487,26492,26608,26633,26584,26634,26601,26544,26636,26585,26549,26586, 26547,26589,26624,26563,26552,26594,26638,26561,26621,26674,26675,26720,26721, 26702,26722,26692,26724,26755,26653,26709,26726,26689,26727,26688,26686,26698, 26697,26665,26805,26767,26740,26743,26771,26731,26818,26990,26876,26911,26912, 26873,26916,26864,26891,26881,26967,26851,26896,26993,26937,26976,26946,26973, 27012,26987,27008,27032,27000,26932,27084,27015,27016,27086,27017,26982,26979, 27001,27035,27047,27067,27051,27053,27092,27057,27073,27082,27103,27029,27104, 27021,27135,27183,27117,27159,27160,27237,27122,27204,27198,27296,27216,27227, 27189,27278,27257,27197,27176,27224,27260,27281,27280,27305,27287,27307,29495, 29522,27521,27522,27527,27524,27538,27539,27533,27546,27547,27553,27562,36715, 36717,36721,36722,36723,36725,36726,36728,36727,36729,36730,36732,36734,36737, 36738,36740,36743,36747,36749,36750,36751,36760,36762,36558,25099,25111,25115, 25119,25122,25121,25125,25124,25132,33255,29935,29940,29951,29967,29969,29971, 25908,26094,26095,26096,26122,26137,26482,26115,26133,26112,28805,26359,26141, 26164,26161,26166,26165,32774,26207,26196,26177,26191,26198,26209,26199,26231, 26244,26252,26279,26269,26302,26331,26332,26342,26345,36146,36147,36150,36155, 36157,36160,36165,36166,36168,36169,36167,36173,36181,36185,35271,35274,35275, 35276,35278,35279,35280,35281,29294,29343,29277,29286,29295,29310,29311,29316, 29323,29325,29327,29330,25352,25394,25520,25663,25816,32772,27626,27635,27645, 27637,27641,27653,27655,27654,27661,27669,27672,27673,27674,27681,27689,27684, 27690,27698,25909,25941,25963,29261,29266,29270,29232,34402,21014,32927,32924, 32915,32956,26378,32957,32945,32939,32941,32948,32951,32999,33000,33001,33002, 32987,32962,32964,32985,32973,32983,26384,32989,33003,33009,33012,33005,33037, 33038,33010,33020,26389,33042,35930,33078,33054,33068,33048,33074,33096,33100, 33107,33140,33113,33114,33137,33120,33129,33148,33149,33133,33127,22605,23221, 33160,33154,33169,28373,33187,33194,33228,26406,33226,33211,33217,33190,27428, 27447,27449,27459,27462,27481,39121,39122,39123,39125,39129,39130,27571,24384, 27586,35315,26000,40785,26003,26044,26054,26052,26051,26060,26062,26066,26070, 28800,28828,28822,28829,28859,28864,28855,28843,28849,28904,28874,28944,28947, 28950,28975,28977,29043,29020,29032,28997,29042,29002,29048,29050,29080,29107, 29109,29096,29088,29152,29140,29159,29177,29213,29224,28780,28952,29030,29113, 25150,25149,25155,25160,25161,31035,31040,31046,31049,31067,31068,31059,31066, 31074,31063,31072,31087,31079,31098,31109,31114,31130,31143,31155,24529,24528, 24636,24669,24666,24679,24641,24665,24675,24747,24838,24845,24925,25001,24989, 25035,25041,25094,32896,32895,27795,27894,28156,30710,30712,30720,30729,30743, 30744,30737,26027,30765,30748,30749,30777,30778,30779,30751,30780,30757,30764, 30755,30761,30798,30829,30806,30807,30758,30800,30791,30796,30826,30875,30867, 30874,30855,30876,30881,30883,30898,30905,30885,30932,30937,30921,30956,30962, 30981,30964,30995,31012,31006,31028,40859,40697,40699,40700,30449,30468,30477, 30457,30471,30472,30490,30498,30489,30509,30502,30517,30520,30544,30545,30535, 30531,30554,30568,30562,30565,30591,30605,30589,30592,30604,30609,30623,30624, 30640,30645,30653,30010,30016,30030,30027,30024,30043,30066,30073,30083,32600, 32609,32607,35400,32616,32628,32625,32633,32641,32638,30413,30437,34866,38021, 38022,38023,38027,38026,38028,38029,38031,38032,38036,38039,38037,38042,38043, 38044,38051,38052,38059,38058,38061,38060,38063,38064,38066,38068,38070,38071, 38072,38073,38074,38076,38077,38079,38084,38088,38089,38090,38091,38092,38093, 38094,38096,38097,38098,38101,38102,38103,38105,38104,38107,38110,38111,38112, 38114,38116,38117,38119,38120,38122,38121,38123,38126,38127,38131,38132,38133, 38135,38137,38140,38141,38143,38147,38146,38150,38151,38153,38154,38157,38158, 38159,38162,38163,38164,38165,38166,38168,38171,38173,38174,38175,38178,38186, 38187,38185,38188,38193,38194,38196,38198,38199,38200,38204,38206,38207,38210, 38197,38212,38213,38214,38217,38220,38222,38223,38226,38227,38228,38230,38231, 38232,38233,38235,38238,38239,38237,38241,38242,38244,38245,38246,38247,38248, 38249,38250,38251,38252,38255,38257,38258,38259,38202,30695,30700,38601,31189, 31213,31203,31211,31238,23879,31235,31234,31262,31252,31289,31287,31313,40655, 39333,31344,30344,30350,30355,30361,30372,29918,29920,29996,40480,40482,40488, 40489,40490,40491,40492,40498,40497,40502,40504,40503,40505,40506,40510,40513, 40514,40516,40518,40519,40520,40521,40523,40524,40526,40529,40533,40535,40538, 40539,40540,40542,40547,40550,40551,40552,40553,40554,40555,40556,40561,40557, 40563,30098,30100,30102,30112,30109,30124,30115,30131,30132,30136,30148,30129, 30128,30147,30146,30166,30157,30179,30184,30182,30180,30187,30183,30211,30193, 30204,30207,30224,30208,30213,30220,30231,30218,30245,30232,30229,30233,30235, 30268,30242,30240,30272,30253,30256,30271,30261,30275,30270,30259,30285,30302, 30292,30300,30294,30315,30319,32714,31462,31352,31353,31360,31366,31368,31381, 31398,31392,31404,31400,31405,31411,34916,34921,34930,34941,34943,34946,34978, 35014,34999,35004,35017,35042,35022,35043,35045,35057,35098,35068,35048,35070, 35056,35105,35097,35091,35099,35082,35124,35115,35126,35137,35174,35195,30091, 32997,30386,30388,30684,32786,32788,32790,32796,32800,32802,32805,32806,32807, 32809,32808,32817,32779,32821,32835,32838,32845,32850,32873,32881,35203,39032, 39040,39043,39049,39052,39053,39055,39060,39066,39067,39070,39071,39073,39074, 39077,39078,34381,34388,34412,34414,34431,34426,34428,34427,34472,34445,34443, 34476,34461,34471,34467,34474,34451,34473,34486,34500,34485,34510,34480,34490, 34481,34479,34505,34511,34484,34537,34545,34546,34541,34547,34512,34579,34526, 34548,34527,34520,34513,34563,34567,34552,34568,34570,34573,34569,34595,34619, 34590,34597,34606,34586,34622,34632,34612,34609,34601,34615,34623,34690,34594, 34685,34686,34683,34656,34672,34636,34670,34699,34643,34659,34684,34660,34649, 34661,34707,34735,34728,34770,34758,34696,34693,34733,34711,34691,34731,34789, 34732,34741,34739,34763,34771,34749,34769,34752,34762,34779,34794,34784,34798, 34838,34835,34814,34826,34843,34849,34873,34876,32566,32578,32580,32581,33296, 31482,31485,31496,31491,31492,31509,31498,31531,31503,31559,31544,31530,31513, 31534,31537,31520,31525,31524,31539,31550,31518,31576,31578,31557,31605,31564, 31581,31584,31598,31611,31586,31602,31601,31632,31654,31655,31672,31660,31645, 31656,31621,31658,31644,31650,31659,31668,31697,31681,31692,31709,31706,31717, 31718,31722,31756,31742,31740,31759,31766,31755,31775,31786,31782,31800,31809, 31808,33278,33281,33282,33284,33260,34884,33313,33314,33315,33325,33327,33320, 33323,33336,33339,33331,33332,33342,33348,33353,33355,33359,33370,33375,33384, 34942,34949,34952,35032,35039,35166,32669,32671,32679,32687,32688,32690,31868, 25929,31889,31901,31900,31902,31906,31922,31932,31933,31937,31943,31948,31949, 31944,31941,31959,31976,33390,26280,32703,32718,32725,32741,32737,32742,32745, 32750,32755,31992,32119,32166,32174,32327,32411,40632,40628,36211,36228,36244, 36241,36273,36199,36205,35911,35913,37194,37200,37198,37199,37220,37218,37217, 37232,37225,37231,37245,37246,37234,37236,37241,37260,37253,37264,37261,37265, 37282,37283,37290,37293,37294,37295,37301,37300,37306,35925,40574,36280,36331, 36357,36441,36457,36277,36287,36284,36282,36292,36310,36311,36314,36318,36302, 36303,36315,36294,36332,36343,36344,36323,36345,36347,36324,36361,36349,36372, 36381,36383,36396,36398,36387,36399,36410,36416,36409,36405,36413,36401,36425, 36417,36418,36433,36434,36426,36464,36470,36476,36463,36468,36485,36495,36500, 36496,36508,36510,35960,35970,35978,35973,35992,35988,26011,35286,35294,35290, 35292,35301,35307,35311,35390,35622,38739,38633,38643,38639,38662,38657,38664, 38671,38670,38698,38701,38704,38718,40832,40835,40837,40838,40839,40840,40841, 40842,40844,40702,40715,40717,38585,38588,38589,38606,38610,30655,38624,37518, 37550,37576,37694,37738,37834,37775,37950,37995,40063,40066,40069,40070,40071, 40072,31267,40075,40078,40080,40081,40082,40084,40085,40090,40091,40094,40095, 40096,40097,40098,40099,40101,40102,40103,40104,40105,40107,40109,40110,40112, 40113,40114,40115,40116,40117,40118,40119,40122,40123,40124,40125,40132,40133, 40134,40135,40138,40139,40140,40141,40142,40143,40144,40147,40148,40149,40151, 40152,40153,40156,40157,40159,40162,38780,38789,38801,38802,38804,38831,38827, 38819,38834,38836,39601,39600,39607,40536,39606,39610,39612,39617,39616,39621, 39618,39627,39628,39633,39749,39747,39751,39753,39752,39757,39761,39144,39181, 39214,39253,39252,39647,39649,39654,39663,39659,39675,39661,39673,39688,39695, 39699,39711,39715,40637,40638,32315,40578,40583,40584,40587,40594,37846,40605, 40607,40667,40668,40669,40672,40671,40674,40681,40679,40677,40682,40687,40738, 40748,40751,40761,40759,40765,40766,40772,57908,57909,57910,57911,57912,57913, 57914,57915,57916,57917,57918,57919,57920,57921,57922,57923,57924,57925,57926, 57927,57928,57929,57930,57931,57932,57933,57934,57935,57936,57937,57938,57939, 57940,57941,57942,57943,57944,57945,57946,57947,57948,57949,57950,57951,57952, 57953,57954,57955,57956,57957,57958,57959,57960,57961,57962,57963,57964,57965, 57966,57967,57968,57969,57970,57971,57972,57973,57974,57975,57976,57977,57978, 57979,57980,57981,57982,57983,57984,57985,57986,57987,57988,57989,57990,57991, 57992,57993,57994,57995,57996,57997,57998,57999,58000,58001,58002,58003,58004, 58005,58006,58007,58008,58009,58010,58011,58012,58013,58014,58015,58016,58017, 58018,58019,58020,58021,58022,58023,58024,58025,58026,58027,58028,58029,58030, 58031,58032,58033,58034,58035,58036,58037,58038,58039,58040,58041,58042,58043, 58044,58045,58046,58047,58048,58049,58050,58051,58052,58053,58054,58055,58056, 58057,58058,58059,58060,58061,58062,58063,58064,58065,58066,58067,58068,58069, 58070,58071,58072,58073,58074,58075,58076,58077,58078,58079,58080,58081,58082, 58083,58084,58085,58086,58087,58088,58089,58090,58091,58092,58093,58094,58095, 58096,58097,58098,58099,58100,58101,58102,58103,58104,58105,58106,58107,58108, 58109,58110,58111,58112,58113,58114,58115,58116,58117,58118,58119,58120,58121, 58122,58123,58124,58125,58126,58127,58128,58129,58130,58131,58132,58133,58134, 58135,58136,58137,58138,58139,58140,58141,58142,58143,58144,58145,58146,58147, 58148,58149,58150,58151,58152,58153,58154,58155,58156,58157,58158,58159,58160, 58161,58162,58163,58164,58165,58166,58167,58168,58169,58170,58171,58172,58173, 58174,58175,58176,58177,58178,58179,58180,58181,58182,58183,58184,58185,58186, 58187,58188,58189,58190,58191,58192,58193,58194,58195,58196,58197,58198,58199, 58200,58201,58202,58203,58204,58205,58206,58207,58208,58209,58210,58211,58212, 58213,58214,58215,58216,58217,58218,58219,58220,58221,58222,58223,58224,58225, 58226,58227,58228,58229,58230,58231,58232,58233,58234,58235,58236,58237,58238, 58239,58240,58241,58242,58243,58244,58245,58246,58247,58248,58249,58250,58251, 58252,58253,58254,58255,58256,58257,58258,58259,58260,58261,58262,58263,58264, 58265,58266,58267,58268,58269,58270,58271,58272,58273,58274,58275,58276,58277, 58278,58279,58280,58281,58282,58283,58284,58285,58286,58287,58288,58289,58290, 58291,58292,58293,58294,58295,58296,58297,58298,58299,58300,58301,58302,58303, 58304,58305,58306,58307,58308,58309,58310,58311,58312,58313,58314,58315,58316, 58317,58318,58319,58320,58321,58322,58323,58324,58325,58326,58327,58328,58329, 58330,58331,58332,58333,58334,58335,58336,58337,58338,58339,58340,58341,58342, 58343,58344,58345,58346,58347,58348,58349,58350,58351,58352,58353,58354,58355, 58356,58357,58358,58359,58360,58361,58362,58363,58364,58365,58366,58367,58368, 58369,58370,58371,58372,58373,58374,58375,58376,58377,40754,40755,40756,40757, 40758,40760,40762,40764,40767,40768,40769,40770,40771,40773,40774,40775,40776, 40777,40778,40779,40780,40781,40782,40783,40786,40787,40788,40789,40790,40791, 40792,40793,40794,40795,40796,40797,40798,40799,40800,40801,40802,40803,40804, 40805,40806,40807,40808,40809,40810,40811,40812,40813,40814,40815,40816,40817, 40818,40819,40820,40821,40822,40823,40824,40825,40826,40827,40828,40829,40830, 40833,40834,40845,40846,40847,40848,40849,40850,40851,40852,40853,40854,40855, 40856,40860,40861,40862,40865,40866,40867,40868,40869,63788,63865,63893,63975, 63985,58378,58379,58380,58381,58382,58383,58384,58385,58386,58387,58388,58389, 58390,58391,58392,58393,58394,58395,58396,58397,58398,58399,58400,58401,58402, 58403,58404,58405,58406,58407,58408,58409,58410,58411,58412,58413,58414,58415, 58416,58417,58418,58419,58420,58421,58422,58423,58424,58425,58426,58427,58428, 58429,58430,58431,58432,58433,58434,58435,58436,58437,58438,58439,58440,58441, 58442,58443,58444,58445,58446,58447,58448,58449,58450,58451,58452,58453,58454, 58455,58456,58457,58458,58459,58460,58461,58462,58463,58464,58465,58466,58467, 58468,58469,58470,58471,64012,64013,64014,64015,64017,64019,64020,64024,64031, 64032,64033,64035,64036,64039,64040,64041,11905,59414,59415,59416,11908,13427, 13383,11912,11915,40884,13726,13850,13838,11916,11927,14702,14616,40885,14799, 14815,14963,14800,40886,40887,15182,15470,15584,11943,59441,40888,11946,16470, 16735,11950,17207,11955,11958,11959,59451,17329,17324,11963,17373,17622,18017, 17996,40889,18211,18217,18300,18317,11978,18759,18810,18813,18818,18819,18821, 18822,18847,18843,18871,18870,40890,59477,19619,19615,19616,19617,19575,19618, 19731,19732,19733,19734,19735,19736,19737,19886,40891,58472,58473,58474,58475, 58476,58477,58478,58479,58480,58481,58482,58483,58484,58485,58486,58487,58488, 58489,58490,58491,58492,58493,58494,58495,58496,58497,58498,58499,58500,58501, 58502,58503,58504,58505,58506,58507,58508,58509,58510,58511,58512,58513,58514, 58515,58516,58517,58518,58519,58520,58521,58522,58523,58524,58525,58526,58527, 58528,58529,58530,58531,58532,58533,58534,58535,58536,58537,58538,58539,58540, 58541,58542,58543,58544,58545,58546,58547,58548,58549,58550,58551,58552,58553, 58554,58555,58556,58557,58558,58559,58560,58561,58562,58563,58564,58565, ] const GB18030Encode*: array[9891, UCS16x16] = [ (164u16,6247u16),(167u16,6251u16),(168u16,6182u16),(176u16,6242u16), (177u16,6207u16),(183u16,6179u16),(215u16,6208u16),(224u16,7509u16), (225u16,7507u16),(232u16,7513u16),(233u16,7511u16),(234u16,7531u16), (236u16,7517u16),(237u16,7515u16),(242u16,7521u16),(243u16,7519u16), (247u16,6209u16),(249u16,7525u16),(250u16,7523u16),(252u16,7530u16), (257u16,7506u16),(275u16,7510u16),(283u16,7512u16),(299u16,7514u16), (324u16,7534u16),(328u16,7535u16),(333u16,7518u16),(363u16,7522u16), (462u16,7508u16),(464u16,7516u16),(466u16,7520u16),(468u16,7524u16), (470u16,7526u16),(472u16,7527u16),(474u16,7528u16),(476u16,7529u16), (505u16,7536u16),(593u16,7532u16),(609u16,7537u16),(711u16,6181u16), (713u16,6180u16),(714u16,7410u16),(715u16,7411u16),(729u16,7412u16), (913u16,7126u16),(914u16,7127u16),(915u16,7128u16),(916u16,7129u16), (917u16,7130u16),(918u16,7131u16),(919u16,7132u16),(920u16,7133u16), (921u16,7134u16),(922u16,7135u16),(923u16,7136u16),(924u16,7137u16), (925u16,7138u16),(926u16,7139u16),(927u16,7140u16),(928u16,7141u16), (929u16,7142u16),(931u16,7143u16),(932u16,7144u16),(933u16,7145u16), (934u16,7146u16),(935u16,7147u16),(936u16,7148u16),(937u16,7149u16), (945u16,7158u16),(946u16,7159u16),(947u16,7160u16),(948u16,7161u16), (949u16,7162u16),(950u16,7163u16),(951u16,7164u16),(952u16,7165u16), (953u16,7166u16),(954u16,7167u16),(955u16,7168u16),(956u16,7169u16), (957u16,7170u16),(958u16,7171u16),(959u16,7172u16),(960u16,7173u16), (961u16,7174u16),(963u16,7175u16),(964u16,7176u16),(965u16,7177u16), (966u16,7178u16),(967u16,7179u16),(968u16,7180u16),(969u16,7181u16), (1025u16,7322u16),(1040u16,7316u16),(1041u16,7317u16),(1042u16,7318u16), (1043u16,7319u16),(1044u16,7320u16),(1045u16,7321u16),(1046u16,7323u16), (1047u16,7324u16),(1048u16,7325u16),(1049u16,7326u16),(1050u16,7327u16), (1051u16,7328u16),(1052u16,7329u16),(1053u16,7330u16),(1054u16,7331u16), (1055u16,7332u16),(1056u16,7333u16),(1057u16,7334u16),(1058u16,7335u16), (1059u16,7336u16),(1060u16,7337u16),(1061u16,7338u16),(1062u16,7339u16), (1063u16,7340u16),(1064u16,7341u16),(1065u16,7342u16),(1066u16,7343u16), (1067u16,7344u16),(1068u16,7345u16),(1069u16,7346u16),(1070u16,7347u16), (1071u16,7348u16),(1072u16,7364u16),(1073u16,7365u16),(1074u16,7366u16), (1075u16,7367u16),(1076u16,7368u16),(1077u16,7369u16),(1078u16,7371u16), (1079u16,7372u16),(1080u16,7373u16),(1081u16,7374u16),(1082u16,7375u16), (1083u16,7376u16),(1084u16,7377u16),(1085u16,7378u16),(1086u16,7379u16), (1087u16,7380u16),(1088u16,7381u16),(1089u16,7382u16),(1090u16,7383u16), (1091u16,7384u16),(1092u16,7385u16),(1093u16,7386u16),(1094u16,7387u16), (1095u16,7388u16),(1096u16,7389u16),(1097u16,7390u16),(1098u16,7391u16), (1099u16,7392u16),(1100u16,7393u16),(1101u16,7394u16),(1102u16,7395u16), (1103u16,7396u16),(1105u16,7370u16),(7743u16,7533u16),(8208u16,7628u16), (8211u16,7413u16),(8212u16,6185u16),(8213u16,7414u16),(8214u16,6187u16), (8216u16,6189u16),(8217u16,6190u16),(8220u16,6191u16),(8221u16,6192u16), (8229u16,7415u16),(8230u16,6188u16),(8240u16,6250u16),(8242u16,6243u16), (8243u16,6244u16),(8245u16,7416u16),(8251u16,6264u16),(8364u16,6432u16), (8451u16,6245u16),(8453u16,7417u16),(8457u16,7418u16),(8470u16,6252u16), (8481u16,7625u16),(8544u16,6446u16),(8545u16,6447u16),(8546u16,6448u16), (8547u16,6449u16),(8548u16,6450u16),(8549u16,6451u16),(8550u16,6452u16), (8551u16,6453u16),(8552u16,6454u16),(8553u16,6455u16),(8554u16,6456u16), (8555u16,6457u16),(8560u16,6366u16),(8561u16,6367u16),(8562u16,6368u16), (8563u16,6369u16),(8564u16,6370u16),(8565u16,6371u16),(8566u16,6372u16), (8567u16,6373u16),(8568u16,6374u16),(8569u16,6375u16),(8592u16,6266u16), (8593u16,6267u16),(8594u16,6265u16),(8595u16,6268u16),(8598u16,7419u16), (8599u16,7420u16),(8600u16,7421u16),(8601u16,7422u16),(8712u16,6217u16), (8719u16,6214u16),(8721u16,6213u16),(8725u16,7423u16),(8730u16,6219u16), (8733u16,6231u16),(8734u16,6237u16),(8735u16,7424u16),(8736u16,6222u16), (8739u16,7425u16),(8741u16,6221u16),(8743u16,6211u16),(8744u16,6212u16), (8745u16,6216u16),(8746u16,6215u16),(8747u16,6225u16),(8750u16,6226u16), (8756u16,6239u16),(8757u16,6238u16),(8758u16,6210u16),(8759u16,6218u16), (8765u16,6230u16),(8776u16,6229u16),(8780u16,6228u16),(8786u16,7426u16), (8800u16,6232u16),(8801u16,6227u16),(8804u16,6235u16),(8805u16,6236u16), (8806u16,7427u16),(8807u16,7428u16),(8814u16,6233u16),(8815u16,6234u16), (8853u16,7491u16),(8857u16,6224u16),(8869u16,6220u16),(8895u16,7429u16), (8978u16,6223u16),(9312u16,6422u16),(9313u16,6423u16),(9314u16,6424u16), (9315u16,6425u16),(9316u16,6426u16),(9317u16,6427u16),(9318u16,6428u16), (9319u16,6429u16),(9320u16,6430u16),(9321u16,6431u16),(9332u16,6402u16), (9333u16,6403u16),(9334u16,6404u16),(9335u16,6405u16),(9336u16,6406u16), (9337u16,6407u16),(9338u16,6408u16),(9339u16,6409u16),(9340u16,6410u16), (9341u16,6411u16),(9342u16,6412u16),(9343u16,6413u16),(9344u16,6414u16), (9345u16,6415u16),(9346u16,6416u16),(9347u16,6417u16),(9348u16,6418u16), (9349u16,6419u16),(9350u16,6420u16),(9351u16,6421u16),(9352u16,6382u16), (9353u16,6383u16),(9354u16,6384u16),(9355u16,6385u16),(9356u16,6386u16), (9357u16,6387u16),(9358u16,6388u16),(9359u16,6389u16),(9360u16,6390u16), (9361u16,6391u16),(9362u16,6392u16),(9363u16,6393u16),(9364u16,6394u16), (9365u16,6395u16),(9366u16,6396u16),(9367u16,6397u16),(9368u16,6398u16), (9369u16,6399u16),(9370u16,6400u16),(9371u16,6401u16),(9472u16,7699u16), (9473u16,7700u16),(9474u16,7701u16),(9475u16,7702u16),(9476u16,7703u16), (9477u16,7704u16),(9478u16,7705u16),(9479u16,7706u16),(9480u16,7707u16), (9481u16,7708u16),(9482u16,7709u16),(9483u16,7710u16),(9484u16,7711u16), (9485u16,7712u16),(9486u16,7713u16),(9487u16,7714u16),(9488u16,7715u16), (9489u16,7716u16),(9490u16,7717u16),(9491u16,7718u16),(9492u16,7719u16), (9493u16,7720u16),(9494u16,7721u16),(9495u16,7722u16),(9496u16,7723u16), (9497u16,7724u16),(9498u16,7725u16),(9499u16,7726u16),(9500u16,7727u16), (9501u16,7728u16),(9502u16,7729u16),(9503u16,7730u16),(9504u16,7731u16), (9505u16,7732u16),(9506u16,7733u16),(9507u16,7734u16),(9508u16,7735u16), (9509u16,7736u16),(9510u16,7737u16),(9511u16,7738u16),(9512u16,7739u16), (9513u16,7740u16),(9514u16,7741u16),(9515u16,7742u16),(9516u16,7743u16), (9517u16,7744u16),(9518u16,7745u16),(9519u16,7746u16),(9520u16,7747u16), (9521u16,7748u16),(9522u16,7749u16),(9523u16,7750u16),(9524u16,7751u16), (9525u16,7752u16),(9526u16,7753u16),(9527u16,7754u16),(9528u16,7755u16), (9529u16,7756u16),(9530u16,7757u16),(9531u16,7758u16),(9532u16,7759u16), (9533u16,7760u16),(9534u16,7761u16),(9535u16,7762u16),(9536u16,7763u16), (9537u16,7764u16),(9538u16,7765u16),(9539u16,7766u16),(9540u16,7767u16), (9541u16,7768u16),(9542u16,7769u16),(9543u16,7770u16),(9544u16,7771u16), (9545u16,7772u16),(9546u16,7773u16),(9547u16,7774u16),(9552u16,7430u16), (9553u16,7431u16),(9554u16,7432u16),(9555u16,7433u16),(9556u16,7434u16), (9557u16,7435u16),(9558u16,7436u16),(9559u16,7437u16),(9560u16,7438u16), (9561u16,7439u16),(9562u16,7440u16),(9563u16,7441u16),(9564u16,7442u16), (9565u16,7443u16),(9566u16,7444u16),(9567u16,7445u16),(9568u16,7446u16), (9569u16,7447u16),(9570u16,7448u16),(9571u16,7449u16),(9572u16,7450u16), (9573u16,7451u16),(9574u16,7452u16),(9575u16,7453u16),(9576u16,7454u16), (9577u16,7455u16),(9578u16,7456u16),(9579u16,7457u16),(9580u16,7458u16), (9581u16,7459u16),(9582u16,7460u16),(9583u16,7461u16),(9584u16,7462u16), (9585u16,7463u16),(9586u16,7464u16),(9587u16,7465u16),(9601u16,7466u16), (9602u16,7467u16),(9603u16,7468u16),(9604u16,7469u16),(9605u16,7470u16), (9606u16,7471u16),(9607u16,7472u16),(9608u16,7473u16),(9609u16,7474u16), (9610u16,7475u16),(9611u16,7476u16),(9612u16,7477u16),(9613u16,7478u16), (9614u16,7479u16),(9615u16,7480u16),(9619u16,7481u16),(9620u16,7482u16), (9621u16,7483u16),(9632u16,6261u16),(9633u16,6260u16),(9650u16,6263u16), (9651u16,6262u16),(9660u16,7484u16),(9661u16,7485u16),(9670u16,6259u16), (9671u16,6258u16),(9675u16,6255u16),(9678u16,6257u16),(9679u16,6256u16), (9698u16,7486u16),(9699u16,7487u16),(9700u16,7488u16),(9701u16,7489u16), (9733u16,6254u16),(9734u16,6253u16),(9737u16,7490u16),(9792u16,6241u16), (9794u16,6240u16),(11905u16,23766u16),(11908u16,23770u16),(11912u16,23773u16), (11915u16,23774u16),(11916u16,23779u16),(11927u16,23780u16),(11943u16,23793u16), (11946u16,23796u16),(11950u16,23799u16),(11955u16,23801u16),(11958u16,23802u16), (11959u16,23803u16),(11963u16,23807u16),(11978u16,23817u16),(12272u16,7673u16), (12273u16,7674u16),(12274u16,7675u16),(12275u16,7676u16),(12276u16,7677u16), (12277u16,7678u16),(12278u16,7679u16),(12279u16,7680u16),(12280u16,7681u16), (12281u16,7682u16),(12282u16,7683u16),(12283u16,7684u16),(12288u16,6176u16), (12289u16,6177u16),(12290u16,6178u16),(12291u16,6183u16),(12293u16,6184u16), (12294u16,7637u16),(12295u16,7685u16),(12296u16,6195u16),(12297u16,6196u16), (12298u16,6197u16),(12299u16,6198u16),(12300u16,6199u16),(12301u16,6200u16), (12302u16,6201u16),(12303u16,6202u16),(12304u16,6205u16),(12305u16,6206u16), (12306u16,7492u16),(12307u16,6269u16),(12308u16,6193u16),(12309u16,6194u16), (12310u16,6203u16),(12311u16,6204u16),(12317u16,7493u16),(12318u16,7494u16), (12321u16,7600u16),(12322u16,7601u16),(12323u16,7602u16),(12324u16,7603u16), (12325u16,7604u16),(12326u16,7605u16),(12327u16,7606u16),(12328u16,7607u16), (12329u16,7608u16),(12350u16,7672u16),(12353u16,6746u16),(12354u16,6747u16), (12355u16,6748u16),(12356u16,6749u16),(12357u16,6750u16),(12358u16,6751u16), (12359u16,6752u16),(12360u16,6753u16),(12361u16,6754u16),(12362u16,6755u16), (12363u16,6756u16),(12364u16,6757u16),(12365u16,6758u16),(12366u16,6759u16), (12367u16,6760u16),(12368u16,6761u16),(12369u16,6762u16),(12370u16,6763u16), (12371u16,6764u16),(12372u16,6765u16),(12373u16,6766u16),(12374u16,6767u16), (12375u16,6768u16),(12376u16,6769u16),(12377u16,6770u16),(12378u16,6771u16), (12379u16,6772u16),(12380u16,6773u16),(12381u16,6774u16),(12382u16,6775u16), (12383u16,6776u16),(12384u16,6777u16),(12385u16,6778u16),(12386u16,6779u16), (12387u16,6780u16),(12388u16,6781u16),(12389u16,6782u16),(12390u16,6783u16), (12391u16,6784u16),(12392u16,6785u16),(12393u16,6786u16),(12394u16,6787u16), (12395u16,6788u16),(12396u16,6789u16),(12397u16,6790u16),(12398u16,6791u16), (12399u16,6792u16),(12400u16,6793u16),(12401u16,6794u16),(12402u16,6795u16), (12403u16,6796u16),(12404u16,6797u16),(12405u16,6798u16),(12406u16,6799u16), (12407u16,6800u16),(12408u16,6801u16),(12409u16,6802u16),(12410u16,6803u16), (12411u16,6804u16),(12412u16,6805u16),(12413u16,6806u16),(12414u16,6807u16), (12415u16,6808u16),(12416u16,6809u16),(12417u16,6810u16),(12418u16,6811u16), (12419u16,6812u16),(12420u16,6813u16),(12421u16,6814u16),(12422u16,6815u16), (12423u16,6816u16),(12424u16,6817u16),(12425u16,6818u16),(12426u16,6819u16), (12427u16,6820u16),(12428u16,6821u16),(12429u16,6822u16),(12430u16,6823u16), (12431u16,6824u16),(12432u16,6825u16),(12433u16,6826u16),(12434u16,6827u16), (12435u16,6828u16),(12443u16,7633u16),(12444u16,7634u16),(12445u16,7638u16), (12446u16,7639u16),(12449u16,6936u16),(12450u16,6937u16),(12451u16,6938u16), (12452u16,6939u16),(12453u16,6940u16),(12454u16,6941u16),(12455u16,6942u16), (12456u16,6943u16),(12457u16,6944u16),(12458u16,6945u16),(12459u16,6946u16), (12460u16,6947u16),(12461u16,6948u16),(12462u16,6949u16),(12463u16,6950u16), (12464u16,6951u16),(12465u16,6952u16),(12466u16,6953u16),(12467u16,6954u16), (12468u16,6955u16),(12469u16,6956u16),(12470u16,6957u16),(12471u16,6958u16), (12472u16,6959u16),(12473u16,6960u16),(12474u16,6961u16),(12475u16,6962u16), (12476u16,6963u16),(12477u16,6964u16),(12478u16,6965u16),(12479u16,6966u16), (12480u16,6967u16),(12481u16,6968u16),(12482u16,6969u16),(12483u16,6970u16), (12484u16,6971u16),(12485u16,6972u16),(12486u16,6973u16),(12487u16,6974u16), (12488u16,6975u16),(12489u16,6976u16),(12490u16,6977u16),(12491u16,6978u16), (12492u16,6979u16),(12493u16,6980u16),(12494u16,6981u16),(12495u16,6982u16), (12496u16,6983u16),(12497u16,6984u16),(12498u16,6985u16),(12499u16,6986u16), (12500u16,6987u16),(12501u16,6988u16),(12502u16,6989u16),(12503u16,6990u16), (12504u16,6991u16),(12505u16,6992u16),(12506u16,6993u16),(12507u16,6994u16), (12508u16,6995u16),(12509u16,6996u16),(12510u16,6997u16),(12511u16,6998u16), (12512u16,6999u16),(12513u16,7000u16),(12514u16,7001u16),(12515u16,7002u16), (12516u16,7003u16),(12517u16,7004u16),(12518u16,7005u16),(12519u16,7006u16), (12520u16,7007u16),(12521u16,7008u16),(12522u16,7009u16),(12523u16,7010u16), (12524u16,7011u16),(12525u16,7012u16),(12526u16,7013u16),(12527u16,7014u16), (12528u16,7015u16),(12529u16,7016u16),(12530u16,7017u16),(12531u16,7018u16), (12532u16,7019u16),(12533u16,7020u16),(12534u16,7021u16),(12540u16,7632u16), (12541u16,7635u16),(12542u16,7636u16),(12549u16,7542u16),(12550u16,7543u16), (12551u16,7544u16),(12552u16,7545u16),(12553u16,7546u16),(12554u16,7547u16), (12555u16,7548u16),(12556u16,7549u16),(12557u16,7550u16),(12558u16,7551u16), (12559u16,7552u16),(12560u16,7553u16),(12561u16,7554u16),(12562u16,7555u16), (12563u16,7556u16),(12564u16,7557u16),(12565u16,7558u16),(12566u16,7559u16), (12567u16,7560u16),(12568u16,7561u16),(12569u16,7562u16),(12570u16,7563u16), (12571u16,7564u16),(12572u16,7565u16),(12573u16,7566u16),(12574u16,7567u16), (12575u16,7568u16),(12576u16,7569u16),(12577u16,7570u16),(12578u16,7571u16), (12579u16,7572u16),(12580u16,7573u16),(12581u16,7574u16),(12582u16,7575u16), (12583u16,7576u16),(12584u16,7577u16),(12585u16,7578u16),(12832u16,6434u16), (12833u16,6435u16),(12834u16,6436u16),(12835u16,6437u16),(12836u16,6438u16), (12837u16,6439u16),(12838u16,6440u16),(12839u16,6441u16),(12840u16,6442u16), (12841u16,6443u16),(12849u16,7626u16),(12963u16,7609u16),(13198u16,7610u16), (13199u16,7611u16),(13212u16,7612u16),(13213u16,7613u16),(13214u16,7614u16), (13217u16,7615u16),(13252u16,7616u16),(13262u16,7617u16),(13265u16,7618u16), (13266u16,7619u16),(13269u16,7620u16),(13383u16,23772u16),(13427u16,23771u16), (13726u16,23776u16),(13838u16,23778u16),(13850u16,23777u16),(14616u16,23782u16), (14702u16,23781u16),(14799u16,23784u16),(14800u16,23787u16),(14815u16,23785u16), (14963u16,23786u16),(15182u16,23790u16),(15470u16,23791u16),(15584u16,23792u16), (16470u16,23797u16),(16735u16,23798u16),(17207u16,23800u16),(17324u16,23806u16), (17329u16,23805u16),(17373u16,23808u16),(17622u16,23809u16),(17996u16,23811u16), (18017u16,23810u16),(18211u16,23813u16),(18217u16,23814u16),(18300u16,23815u16), (18317u16,23816u16),(18759u16,23818u16),(18810u16,23819u16),(18813u16,23820u16), (18818u16,23821u16),(18819u16,23822u16),(18821u16,23823u16),(18822u16,23824u16), (18843u16,23826u16),(18847u16,23825u16),(18870u16,23828u16),(18871u16,23827u16), (19575u16,23835u16),(19615u16,23832u16),(19616u16,23833u16),(19617u16,23834u16), (19618u16,23836u16),(19619u16,23831u16),(19731u16,23837u16),(19732u16,23838u16), (19733u16,23839u16),(19734u16,23840u16),(19735u16,23841u16),(19736u16,23842u16), (19737u16,23843u16),(19886u16,23844u16),(19968u16,15512u16),(19969u16,10166u16), (19971u16,13268u16),(19975u16,14617u16),(19976u16,16096u16),(19977u16,13678u16), (19978u16,13822u16),(19979u16,14949u16),(19980u16,16627u16),(19981u16,9432u16), (19982u16,15750u16),(19984u16,16629u16),(19985u16,9678u16),(19987u16,16443u16), (19988u16,13445u16),(19989u16,16632u16),(19990u16,13997u16),(19992u16,13475u16), (19993u16,9306u16),(19994u16,15506u16),(19995u16,9837u16),(19996u16,10176u16), (19997u16,14186u16),(19998u16,16634u16),(20002u16,10175u16),(20004u16,12284u16), (20005u16,15342u16),(20007u16,13780u16),(20008u16,16638u16),(20010u16,10631u16), (20011u16,15325u16),(20012u16,18775u16),(20013u16,16293u16),(20016u16,10420u16), (20018u16,9799u16),(20020u16,12312u16),(20022u16,16653u16),(20024u16,14607u16), (20025u16,9979u16),(20026u16,14735u16),(20027u16,16332u16),(20029u16,12151u16), (20030u16,11742u16),(20031u16,16640u16),(20035u16,12868u16),(20037u16,11720u16), (20039u16,16642u16),(20040u16,12655u16),(20041u16,15554u16),(20043u16,16259u16), (20044u16,14783u16),(20045u16,16062u16),(20046u16,11010u16),(20047u16,10361u16), (20048u16,12119u16),(20050u16,13230u16),(20051u16,13065u16),(20052u16,13434u16), (20054u16,10787u16),(20056u16,9638u16),(20057u16,15535u16),(20060u16,16656u16), (20061u16,11722u16),(20062u16,13287u16),(20063u16,15503u16),(20064u16,14931u16), (20065u16,14986u16),(20070u16,14038u16),(20073u16,16657u16),(20080u16,12527u16), (20081u16,12495u16),(20083u16,13658u16),(20094u16,13407u16),(20102u16,12298u16), (20104u16,15747u16),(20105u16,16144u16),(20107u16,13999u16),(20108u16,10259u16), (20109u16,16626u16),(20110u16,15733u16),(20111u16,11962u16),(20113u16,15903u16), (20114u16,11120u16),(20115u16,16658u16),(20116u16,14794u16),(20117u16,11699u16), (20120u16,16633u16),(20122u16,15334u16),(20123u16,15114u16),(20127u16,16654u16), (20128u16,16894u16),(20129u16,14621u16),(20130u16,11901u16),(20132u16,11522u16), (20133u16,10930u16),(20134u16,15549u16),(20135u16,9495u16),(20136u16,10989u16), (20137u16,12847u16),(20139u16,14992u16),(20140u16,11694u16),(20141u16,14539u16), (20142u16,12288u16),(20146u16,13450u16),(20147u16,16896u16),(20149u16,16899u16), (20154u16,13628u16),(20155u16,16698u16),(20159u16,15543u16),(20160u16,13983u16), (20161u16,13627u16),(20162u16,16701u16),(20163u16,16699u16),(20164u16,16663u16), (20165u16,11581u16),(20166u16,13250u16),(20167u16,9675u16),(20169u16,16700u16), (20170u16,11576u16),(20171u16,11568u16),(20173u16,13637u16),(20174u16,9836u16), (20177u16,12501u16),(20179u16,9459u16),(20180u16,16483u16),(20181u16,14008u16), (20182u16,14246u16),(20183u16,16099u16),(20184u16,10567u16),(20185u16,14956u16), (20189u16,16873u16),(20190u16,16705u16),(20191u16,13405u16),(20193u16,16703u16), (20195u16,9875u16),(20196u16,12333u16),(20197u16,15537u16),(20200u16,16702u16), (20202u16,15524u16),(20203u16,16704u16),(20204u16,12674u16),(20208u16,15381u16), (20210u16,16302u16),(20211u16,16707u16),(20213u16,16710u16),(20214u16,11399u16), (20215u16,11364u16),(20219u16,13631u16),(20221u16,10416u16),(20223u16,10389u16), (20225u16,13288u16),(20233u16,16713u16),(20234u16,15518u16),(20237u16,14798u16), (20238u16,11336u16),(20239u16,10447u16),(20240u16,10360u16),(20241u16,15166u16), (20247u16,16303u16),(20248u16,15712u16),(20249u16,11194u16),(20250u16,11180u16), (20251u16,16706u16),(20254u16,13776u16),(20255u16,14741u16),(20256u16,9796u16), (20258u16,16708u16),(20260u16,13818u16),(20261u16,16711u16),(20262u16,12500u16), (20263u16,16712u16),(20266u16,14742u16),(20267u16,16714u16),(20271u16,9419u16), (20272u16,10767u16),(20274u16,16818u16),(20276u16,9098u16),(20278u16,12325u16), (20280u16,13851u16),(20282u16,14192u16),(20284u16,14193u16),(20285u16,16819u16), (20291u16,10047u16),(20294u16,9986u16),(20301u16,14752u16),(20302u16,10020u16), (20303u16,16436u16),(20304u16,16519u16),(20305u16,15726u16),(20307u16,14414u16), (20309u16,10971u16),(20311u16,16817u16),(20312u16,16875u16),(20313u16,15739u16), (20314u16,16718u16),(20315u16,10435u16),(20316u16,16522u16),(20317u16,16719u16), (20318u16,16715u16),(20319u16,16816u16),(20320u16,12892u16),(20323u16,15697u16), (20324u16,16709u16),(20325u16,16876u16),(20327u16,16716u16),(20329u16,13084u16), (20332u16,12113u16),(20335u16,15375u16),(20336u16,9084u16),(20339u16,11354u16), (20340u16,16821u16),(20342u16,16820u16),(20347u16,16827u16),(20348u16,16829u16), (20350u16,16826u16),(20351u16,13990u16),(20355u16,16824u16),(20356u16,16267u16), (20360u16,9657u16),(20361u16,16823u16),(20363u16,12158u16),(20365u16,14009u16), (20367u16,16825u16),(20369u16,16822u16),(20372u16,16831u16),(20375u16,10182u16), (20379u16,10744u16),(20381u16,15517u16),(20384u16,14947u16),(20387u16,12479u16), (20389u16,11531u16),(20390u16,16131u16),(20391u16,9469u16),(20392u16,13435u16), (20393u16,11950u16),(20394u16,16828u16),(20396u16,16830u16),(20398u16,14799u16), (20399u16,11003u16),(20405u16,13449u16),(20415u16,9282u16),(20419u16,9842u16), (20420u16,10242u16),(20421u16,16835u16),(20426u16,11876u16),(20430u16,16877u16), (20431u16,13441u16),(20432u16,12159u16),(20433u16,16839u16),(20439u16,14210u16), (20440u16,10448u16),(20442u16,16836u16),(20444u16,16838u16),(20445u16,9218u16), (20446u16,15740u16),(20447u16,16840u16),(20449u16,15142u16),(20451u16,16837u16), (20454u16,16832u16),(20456u16,16833u16),(20457u16,12264u16),(20458u16,16834u16), (20461u16,11388u16),(20462u16,15167u16),(20463u16,10554u16),(20465u16,11752u16), (20467u16,16844u16),(20472u16,16841u16),(20474u16,9044u16),(20478u16,16849u16), (20492u16,16851u16),(20493u16,9237u16),(20495u16,16846u16),(20498u16,10000u16), (20500u16,11768u16),(20504u16,14385u16),(20505u16,11007u16),(20506u16,15533u16), (20508u16,16850u16),(20511u16,11567u16),(20513u16,9606u16),(20517u16,16852u16), (20518u16,11760u16),(20520u16,16853u16),(20521u16,16842u16),(20522u16,12888u16), (20524u16,16845u16),(20525u16,16848u16),(20526u16,16847u16),(20538u16,16069u16), (20540u16,16266u16),(20542u16,13462u16),(20547u16,16855u16),(20551u16,11362u16), (20552u16,16857u16),(20556u16,16843u16),(20558u16,16858u16),(20559u16,13216u16), (20565u16,16856u16),(20570u16,16521u16),(20572u16,14538u16),(20581u16,11496u16), (20588u16,16859u16),(20598u16,13043u16),(20599u16,14556u16),(20603u16,16860u16), (20606u16,16854u16),(20607u16,9600u16),(20608u16,11969u16),(20613u16,10566u16), (20616u16,12157u16),(20621u16,9113u16),(20643u16,9871u16),(20645u16,16861u16), (20647u16,16862u16),(20648u16,9787u16),(20649u16,16863u16),(20652u16,9848u16), (20658u16,9058u16),(20666u16,16864u16),(20667u16,13796u16),(20687u16,14996u16), (20694u16,16865u16),(20698u16,12292u16),(20710u16,16869u16),(20711u16,13789u16), (20716u16,16868u16),(20717u16,16867u16),(20718u16,16870u16),(20723u16,14214u16), (20725u16,11504u16),(20731u16,13212u16),(20742u16,16866u16),(20743u16,16871u16), (20747u16,16872u16),(20754u16,13654u16),(20769u16,12125u16),(20799u16,10254u16), (20800u16,16628u16),(20801u16,15907u16),(20803u16,15875u16),(20804u16,15159u16), (20805u16,9663u16),(20806u16,16110u16),(20808u16,14955u16),(20809u16,10801u16), (20811u16,11918u16),(20813u16,12701u16),(20817u16,10215u16),(20820u16,14570u16), (20821u16,16893u16),(20822u16,16895u16),(20826u16,9994u16),(20828u16,10186u16), (20834u16,11689u16),(20837u16,13660u16),(20840u16,13596u16),(20843u16,9068u16), (20844u16,10746u16),(20845u16,12344u16),(20846u16,16881u16),(20848u16,12093u16), (20849u16,10753u16),(20851u16,10791u16),(20852u16,15148u16),(20853u16,9303u16), (20854u16,13273u16),(20855u16,11748u16),(20856u16,10043u16),(20857u16,16475u16), (20859u16,15383u16),(20860u16,11375u16),(20861u16,14027u16),(20864u16,11334u16), (20865u16,16885u16),(20866u16,16696u16),(20869u16,12883u16),(20872u16,10597u16), (20873u16,13614u16),(20876u16,9470u16),(20877u16,15922u16),(20882u16,12651u16), (20885u16,12700u16),(20886u16,17007u16),(20887u16,13648u16),(20889u16,15125u16), (20891u16,11777u16),(20892u16,13024u16),(20896u16,10793u16),(20898u16,17008u16), (20900u16,15874u16),(20901u16,17009u16),(20907u16,16906u16),(20908u16,10177u16), (20911u16,10430u16),(20912u16,9304u16),(20913u16,16907u16),(20914u16,9664u16), (20915u16,11771u16),(20917u16,11961u16),(20918u16,15502u16),(20919u16,12133u16), (20923u16,10184u16),(20924u16,16909u16),(20925u16,16908u16),(20928u16,11712u16), (20932u16,13269u16),(20934u16,16463u16),(20935u16,17006u16),(20937u16,12280u16), (20939u16,10057u16),(20940u16,12327u16),(20943u16,11390u16),(20945u16,9838u16), (20955u16,12316u16),(20957u16,12918u16),(20960u16,11329u16),(20961u16,10373u16), (20964u16,10434u16),(20971u16,16891u16),(20973u16,13235u16),(20975u16,11888u16), (20976u16,11158u16),(20979u16,10017u16),(20981u16,17236u16),(20982u16,15160u16), (20984u16,14560u16),(20985u16,9053u16),(20986u16,9681u16),(20987u16,11202u16), (20988u16,17237u16),(20989u16,10940u16),(20991u16,15933u16),(20992u16,9997u16), (20993u16,10058u16),(20994u16,16679u16),(20995u16,13633u16),(20998u16,10409u16), (20999u16,13443u16),(21000u16,16680u16),(21002u16,11890u16),(21005u16,17222u16), (21006u16,16681u16),(21009u16,15149u16),(21010u16,11129u16),(21014u16,20265u16), (21015u16,12303u16),(21016u16,12340u16),(21017u16,15947u16),(21018u16,10598u16), (21019u16,9805u16),(21021u16,9680u16),(21024u16,13805u16),(21028u16,13063u16), (21032u16,13072u16),(21033u16,12156u16),(21035u16,9295u16),(21037u16,16682u16), (21038u16,10781u16),(21040u16,10004u16),(21043u16,16683u16),(21046u16,16283u16), (21047u16,14157u16),(21048u16,13600u16),(21049u16,13793u16),(21050u16,9829u16), (21051u16,11919u16),(21053u16,10819u16),(21055u16,16684u16),(21056u16,16685u16), (21057u16,10236u16),(21058u16,11338u16),(21059u16,14419u16),(21066u16,15002u16), (21068u16,16686u16),(21069u16,13411u16),(21072u16,10783u16),(21073u16,11498u16), (21076u16,14407u16),(21078u16,13247u16),(21084u16,16689u16),(21086u16,16687u16), (21089u16,16688u16),(21093u16,9119u16),(21095u16,11756u16),(21097u16,13968u16), (21098u16,11389u16),(21103u16,10562u16),(21106u16,10623u16),(21117u16,16691u16), (21119u16,11538u16),(21121u16,16693u16),(21122u16,16692u16),(21128u16,13107u16), (21136u16,16694u16),(21139u16,16695u16),(21147u16,12261u16),(21149u16,13601u16), (21150u16,9101u16),(21151u16,10741u16),(21152u16,11356u16),(21153u16,14806u16), (21154u16,17224u16),(21155u16,12306u16),(21160u16,10180u16),(21161u16,16335u16), (21162u16,13027u16),(21163u16,11552u16),(21164u16,17225u16),(21165u16,17226u16), (21169u16,12153u16),(21170u16,11687u16),(21171u16,12110u16),(21182u16,17227u16), (21183u16,14003u16),(21187u16,9415u16),(21191u16,15709u16),(21193u16,12702u16), (21195u16,15306u16),(21200u16,17229u16),(21202u16,12118u16),(21206u16,17230u16), (21208u16,11892u16),(21215u16,12853u16),(21220u16,13453u16),(21232u16,17231u16), (21241u16,16887u16),(21242u16,13830u16),(21246u16,10755u16),(21247u16,14805u16), (21248u16,15905u16),(21253u16,9117u16),(21254u16,9835u16),(21256u16,15162u16), (21261u16,16888u16),(21263u16,17808u16),(21264u16,16890u16),(21269u16,16641u16), (21270u16,11130u16),(21271u16,9232u16),(21273u16,9650u16),(21274u16,16671u16), (21277u16,15914u16),(21280u16,11514u16),(21281u16,11954u16),(21283u16,14942u16), (21286u16,16673u16),(21290u16,10398u16),(21294u16,16674u16),(21305u16,13210u16), (21306u16,13483u16),(21307u16,15514u16),(21310u16,16675u16),(21311u16,12893u16), (21313u16,13979u16),(21315u16,13402u16),(21317u16,16631u16),(21319u16,13868u16), (21320u16,14796u16),(21321u16,11175u16),(21322u16,9100u16),(21326u16,11125u16), (21327u16,15118u16),(21329u16,9231u16),(21330u16,16503u16),(21331u16,16466u16), (21333u16,9980u16),(21334u16,12529u16),(21335u16,12872u16),(21338u16,9414u16), (21340u16,9428u16),(21342u16,9284u16),(21343u16,17973u16),(21344u16,16083u16), (21345u16,11883u16),(21346u16,12457u16),(21347u16,16678u16),(21348u16,12462u16), (21350u16,16677u16),(21351u16,14777u16),(21353u16,17069u16),(21355u16,14757u16), (21358u16,16645u16),(21359u16,12649u16),(21360u16,15676u16),(21361u16,14728u16), (21363u16,11325u16),(21364u16,13605u16),(21365u16,12494u16),(21367u16,11762u16), (21368u16,15127u16),(21370u16,17070u16),(21375u16,13463u16),(21378u16,9602u16), (21380u16,10247u16),(21381u16,14437u16),(21382u16,12155u16),(21385u16,12152u16), (21387u16,15320u16),(21388u16,15360u16),(21389u16,16664u16),(21397u16,9467u16), (21400u16,12134u16),(21402u16,11006u16),(21405u16,16665u16),(21407u16,15878u16), (21410u16,14980u16),(21411u16,16666u16),(21413u16,16667u16),(21414u16,14950u16), (21416u16,9683u16),(21417u16,11724u16),(21422u16,16668u16),(21430u16,17239u16), (21435u16,13590u16),(21439u16,14971u16),(21441u16,13679u16),(21442u16,9451u16), (21448u16,15729u16),(21449u16,9475u16),(21450u16,11321u16),(21451u16,15724u16), (21452u16,14166u16),(21453u16,10375u16),(21457u16,10357u16),(21460u16,14034u16), (21462u16,13586u16),(21463u16,14025u16),(21464u16,9283u16),(21465u16,15185u16), (21467u16,13064u16),(21471u16,17232u16),(21472u16,10069u16),(21475u16,11933u16), (21476u16,10772u16),(21477u16,11753u16),(21478u16,12332u16),(21480u16,17977u16), (21481u16,17976u16),(21482u16,16272u16),(21483u16,11543u16),(21484u16,16112u16), (21485u16,9065u16),(21486u16,10168u16),(21487u16,11916u16),(21488u16,14353u16), (21489u16,17974u16),(21490u16,13988u16),(21491u16,15725u16),(21493u16,16672u16), (21494u16,15507u16),(21495u16,10962u16),(21496u16,14185u16),(21497u16,14375u16), (21499u16,17978u16),(21500u16,10055u16),(21501u16,17975u16),(21505u16,15760u16), (21507u16,9647u16),(21508u16,10632u16),(21510u16,17981u16),(21512u16,10972u16), (21513u16,11315u16),(21514u16,10060u16),(21516u16,14547u16),(21517u16,12726u16), (21518u16,11008u16),(21519u16,12149u16),(21520u16,14569u16),(21521u16,14997u16), (21522u16,17979u16),(21523u16,14952u16),(21525u16,12477u16),(21526u16,17980u16), (21527u16,12525u16),(21531u16,11778u16),(21533u16,12318u16),(21534u16,14579u16), (21535u16,15572u16),(21536u16,10400u16),(21537u16,17988u16),(21539u16,17991u16), (21542u16,10436u16),(21543u16,9066u16),(21544u16,10219u16),(21545u16,10407u16), (21547u16,10937u16),(21548u16,14438u16),(21549u16,11927u16),(21550u16,14172u16), (21551u16,13289u16),(21553u16,16253u16),(21554u16,17992u16),(21556u16,14791u16), (21557u16,9614u16),(21560u16,14817u16),(21561u16,9806u16),(21563u16,14764u16), (21564u16,11005u16),(21566u16,14790u16),(21568u16,15324u16),(21571u16,17987u16), (21574u16,9869u16),(21576u16,9637u16),(21578u16,10615u16),(21579u16,17982u16), (21584u16,12862u16),(21586u16,17983u16),(21587u16,17984u16),(21588u16,17985u16), (21589u16,13042u16),(21590u16,17986u16),(21591u16,17989u16),(21592u16,15882u16), (21593u16,17990u16),(21595u16,13421u16),(21596u16,14781u16),(21602u16,12881u16), (21604u16,17997u16),(21606u16,18002u16),(21608u16,16305u16),(21617u16,17996u16), (21618u16,18013u16),(21619u16,14747u16),(21621u16,10964u16),(21622u16,18001u16), (21623u16,17995u16),(21624u16,13077u16),(21627u16,13850u16),(21628u16,11009u16), (21629u16,12727u16),(21632u16,11740u16),(21634u16,17993u16),(21636u16,18000u16), (21638u16,13071u16),(21643u16,16061u16),(21644u16,10970u16),(21646u16,11729u16), (21647u16,15704u16),(21648u16,10577u16),(21650u16,16313u16),(21652u16,17994u16), (21653u16,10765u16),(21654u16,11882u16),(21657u16,12347u16),(21658u16,17998u16), (21659u16,17999u16),(21661u16,18003u16),(21667u16,18014u16),(21668u16,18024u16), (21670u16,18010u16),(21671u16,18009u16),(21672u16,16476u16),(21673u16,18022u16), (21674u16,18023u16),(21675u16,19170u16),(21676u16,15492u16),(21677u16,18005u16), (21679u16,11884u16),(21681u16,15924u16),(21683u16,11915u16),(21684u16,18007u16), (21688u16,14959u16),(21691u16,18016u16),(21693u16,15337u16),(21695u16,18017u16), (21696u16,9032u16),(21697u16,13228u16),(21698u16,18006u16),(21700u16,10994u16), (21702u16,10228u16),(21703u16,14594u16),(21704u16,10829u16),(21705u16,15918u16), (21708u16,18018u16),(21709u16,14991u16),(21710u16,9030u16),(21711u16,18026u16), (21712u16,18004u16),(21713u16,15333u16),(21714u16,18008u16),(21715u16,18011u16), (21716u16,18012u16),(21717u16,18015u16),(21719u16,11124u16),(21721u16,18019u16), (21722u16,18020u16),(21724u16,18021u16),(21725u16,18025u16),(21726u16,18027u16), (21727u16,15695u16),(21733u16,10616u16),(21734u16,13037u16),(21735u16,18029u16), (21736u16,13833u16),(21737u16,12263u16),(21738u16,12861u16),(21741u16,11937u16), (21742u16,15003u16),(21746u16,16115u16),(21747u16,18033u16),(21754u16,9429u16), (21756u16,10988u16),(21757u16,18031u16),(21759u16,17228u16),(21761u16,15363u16), (21766u16,14239u16),(21767u16,9814u16),(21769u16,9031u16),(21775u16,18036u16), (21776u16,14383u16),(21777u16,18037u16),(21780u16,18032u16),(21787u16,18028u16), (21792u16,18030u16),(21794u16,18034u16),(21795u16,18035u16),(21796u16,11144u16), (21799u16,18038u16),(21802u16,18039u16),(21804u16,11118u16),(21806u16,14024u16), (21807u16,14733u16),(21808u16,18152u16),(21809u16,9605u16),(21811u16,18151u16), (21815u16,18146u16),(21820u16,18049u16),(21822u16,14592u16),(21823u16,18047u16), (21825u16,18045u16),(21827u16,11923u16),(21828u16,16471u16),(21830u16,13819u16), (21833u16,18043u16),(21834u16,9026u16),(21840u16,18048u16),(21845u16,18046u16), (21846u16,18147u16),(21852u16,18153u16),(21857u16,10395u16),(21860u16,13206u16), (21861u16,13797u16),(21862u16,12083u16),(21863u16,18040u16),(21866u16,13045u16), (21868u16,16661u16),(21869u16,18044u16),(21870u16,12911u16),(21877u16,18148u16), (21878u16,18149u16),(21879u16,18150u16),(21880u16,15110u16),(21883u16,18165u16), (21884u16,14413u16),(21886u16,18162u16),(21888u16,11881u16),(21889u16,18160u16), (21890u16,14750u16),(21891u16,18156u16),(21892u16,13813u16),(21895u16,12079u16), (21896u16,18159u16),(21897u16,11002u16),(21898u16,10941u16),(21899u16,18154u16), (21903u16,18041u16),(21905u16,18164u16),(21908u16,18169u16),(21912u16,9798u16), (21913u16,18170u16),(21916u16,14933u16),(21917u16,10965u16),(21919u16,18161u16), (21927u16,15195u16),(21937u16,18157u16),(21939u16,15956u16),(21941u16,18042u16), (21943u16,13086u16),(21945u16,18158u16),(21947u16,15762u16),(21949u16,18167u16), (21950u16,18168u16),(21956u16,18181u16),(21957u16,15170u16),(21961u16,18173u16), (21964u16,18186u16),(21965u16,18187u16),(21969u16,18175u16),(21970u16,18155u16), (21971u16,13779u16),(21972u16,18178u16),(21974u16,18163u16),(21980u16,14005u16), (21981u16,18180u16),(21983u16,18166u16),(21985u16,14768u16),(21987u16,14190u16), (21988u16,18190u16),(21989u16,18183u16),(21990u16,18179u16),(21992u16,18188u16), (21994u16,18171u16),(21995u16,18176u16),(21996u16,18177u16),(21999u16,18182u16), (22002u16,18184u16),(22003u16,18185u16),(22005u16,18189u16),(22007u16,18172u16), (22013u16,14207u16),(22014u16,18198u16),(22016u16,18199u16),(22017u16,18195u16), (22024u16,18193u16),(22025u16,11351u16),(22028u16,18194u16),(22030u16,10579u16), (22031u16,16662u16),(22040u16,15179u16),(22043u16,12524u16),(22046u16,18192u16), (22047u16,18174u16),(22051u16,18197u16),(22052u16,18196u16),(22055u16,18200u16), (22060u16,18205u16),(22061u16,18201u16),(22065u16,16331u16),(22066u16,9611u16), (22068u16,16511u16),(22070u16,14182u16),(22073u16,18203u16),(22075u16,14816u16), (22079u16,10982u16),(22092u16,18210u16),(22093u16,18206u16),(22094u16,15498u16), (22100u16,18211u16),(22103u16,18204u16),(22104u16,18202u16),(22105u16,18208u16), (22108u16,18209u16),(22114u16,18207u16),(22116u16,18213u16),(22120u16,13292u16), (22121u16,16637u16),(22122u16,15940u16),(22123u16,18215u16),(22124u16,14006u16), (22129u16,18214u16),(22134u16,10578u16),(22139u16,18216u16),(22140u16,18217u16), (22149u16,18218u16),(22150u16,18212u16),(22158u16,10956u16),(22159u16,14416u16), (22163u16,18219u16),(22179u16,15004u16),(22191u16,18220u16),(22199u16,13619u16), (22204u16,11527u16),(22218u16,12875u16),(22228u16,18221u16),(22231u16,18222u16), (22234u16,13479u16),(22235u16,14191u16),(22237u16,18223u16),(22238u16,11171u16), (22239u16,16647u16),(22240u16,15567u16),(22241u16,18224u16),(22242u16,14572u16), (22244u16,10223u16),(22251u16,18226u16),(22253u16,15881u16),(22256u16,12072u16), (22257u16,9834u16),(22260u16,14732u16),(22261u16,18225u16),(22265u16,18227u16), (22266u16,10779u16),(22269u16,10825u16),(22270u16,14563u16),(22271u16,18228u16), (22275u16,13257u16),(22276u16,18229u16),(22278u16,15883u16),(22280u16,13591u16), (22281u16,18231u16),(22282u16,18230u16),(22300u16,18232u16),(22303u16,14568u16), (22307u16,13970u16),(22312u16,15923u16),(22313u16,17250u16),(22314u16,17252u16), (22316u16,17251u16),(22317u16,10806u16),(22318u16,17255u16),(22319u16,17256u16), (22320u16,10031u16),(22323u16,17253u16),(22329u16,17254u16),(22330u16,9596u16), (22331u16,17258u16),(22334u16,11203u16),(22336u16,16268u16),(22338u16,17259u16), (22343u16,11774u16),(22346u16,10382u16),(22348u16,17243u16),(22349u16,14359u16), (22350u16,11893u16),(22351u16,11136u16),(22352u16,16523u16),(22353u16,11926u16), (22359u16,11948u16),(22362u16,11370u16),(22363u16,14364u16),(22364u16,17257u16), (22365u16,9076u16),(22366u16,14800u16),(22367u16,10411u16),(22368u16,16460u16), (22369u16,13239u16),(22372u16,12069u16),(22374u16,14370u16),(22376u16,17266u16), (22377u16,17260u16),(22378u16,13231u16),(22379u16,17262u16),(22381u16,17267u16), (22383u16,13102u16),(22387u16,17269u16),(22390u16,17268u16),(22391u16,11907u16), (22395u16,17265u16),(22396u16,17264u16),(22402u16,9810u16),(22403u16,12077u16), (22404u16,12447u16),(22405u16,17261u16),(22406u16,17263u16),(22411u16,15150u16), (22412u16,17272u16),(22418u16,12126u16),(22419u16,17277u16),(22427u16,10231u16), (22432u16,17278u16),(22433u16,17245u16),(22434u16,10759u16),(22435u16,15876u16), (22436u16,17271u16),(22438u16,11924u16),(22439u16,17275u16),(22441u16,17244u16), (22443u16,10045u16),(22445u16,17270u16),(22446u16,11944u16),(22450u16,17273u16), (22452u16,17276u16),(22456u16,17284u16),(22466u16,10736u16),(22467u16,9028u16), (22475u16,12526u16),(22478u16,9634u16),(22479u16,17274u16),(22482u16,17283u16), (22484u16,13255u16),(22485u16,17279u16),(22488u16,17280u16),(22489u16,17282u16), (22490u16,17281u16),(22493u16,17289u16),(22495u16,15757u16),(22496u16,9431u16), (22500u16,17288u16),(22509u16,17389u16),(22511u16,17286u16),(22516u16,17285u16), (22520u16,17287u16),(22521u16,13079u16),(22522u16,11204u16),(22525u16,17388u16), (22528u16,17390u16),(22530u16,14380u16),(22534u16,10214u16),(22535u16,17607u16), (22539u16,17386u16),(22541u16,17387u16),(22545u16,13416u16),(22549u16,10238u16), (22553u16,17392u16),(22558u16,17391u16),(22560u16,17394u16),(22561u16,9219u16), (22564u16,10019u16),(22570u16,11891u16),(22576u16,15358u16),(22581u16,10199u16), (22596u16,17393u16),(22604u16,14245u16),(22605u16,20318u16),(22609u16,14215u16), (22612u16,14249u16),(22616u16,14378u16),(22622u16,13676u16),(22629u16,17395u16), (22635u16,14423u16),(22636u16,17396u16),(22654u16,17246u16),(22656u16,17400u16), (22657u16,17397u16),(22659u16,11704u16),(22661u16,14056u16),(22665u16,17398u16), (22674u16,13817u16),(22675u16,12850u16),(22681u16,13424u16),(22682u16,17399u16), (22686u16,15951u16),(22687u16,15175u16),(22696u16,12836u16),(22697u16,10218u16), (22716u16,17247u16),(22721u16,9273u16),(22725u16,17248u16),(22737u16,17249u16), (22741u16,10955u16),(22756u16,13617u16),(22763u16,13996u16),(22764u16,13626u16), (22766u16,16454u16),(22768u16,13864u16),(22771u16,11914u16),(22774u16,11013u16), (22777u16,15513u16),(22786u16,18551u16),(22788u16,9791u16),(22791u16,9239u16), (22797u16,10565u16),(22799u16,14951u16),(22804u16,16886u16),(22805u16,14921u16), (22806u16,14601u16),(22809u16,16892u16),(22810u16,10229u16),(22812u16,15510u16), (22815u16,10762u16),(22820u16,18550u16),(22821u16,18548u16),(22823u16,9868u16), (22825u16,14421u16),(22826u16,14356u16),(22827u16,10437u16),(22829u16,16643u16), (22830u16,15370u16),(22831u16,10952u16),(22833u16,13972u16),(22836u16,14558u16), (22839u16,15521u16),(22840u16,11943u16),(22841u16,11353u16),(22842u16,10230u16), (22844u16,17802u16),(22849u16,17803u16),(22850u16,17223u16),(22852u16,15352u16), (22855u16,13275u16),(22856u16,12871u16),(22857u16,10433u16),(22859u16,10415u16), (22862u16,11967u16),(22863u16,16499u16),(22865u16,13290u16),(22868u16,9243u16), (22869u16,17805u16),(22870u16,11512u16),(22871u16,14400u16),(22872u16,17807u16), (22874u16,17806u16),(22880u16,10051u16),(22882u16,13836u16),(22885u16,9059u16), (22899u16,13029u16),(22900u16,13026u16),(22902u16,12869u16),(22904u16,11378u16), (22905u16,14248u16),(22909u16,10960u16),(22913u16,19184u16),(22914u16,13656u16), (22915u16,19185u16),(22916u16,14628u16),(22918u16,16452u16),(22919u16,10575u16), (22920u16,12517u16),(22922u16,13634u16),(22925u16,19186u16),(22930u16,10207u16), (22931u16,11348u16),(22934u16,15388u16),(22935u16,19286u16),(22937u16,12713u16), (22942u16,19289u16),(22947u16,19189u16),(22948u16,19290u16),(22949u16,14590u16), (22952u16,10388u16),(22953u16,19187u16),(22954u16,19188u16),(22955u16,19288u16), (22958u16,12886u16),(22959u16,19293u16),(22962u16,19292u16),(22969u16,12670u16), (22971u16,13267u16),(22974u16,19295u16),(22982u16,12848u16),(22986u16,19287u16), (22987u16,13993u16),(22992u16,11562u16),(22993u16,10770u16),(22994u16,19291u16), (22995u16,15158u16),(22996u16,14740u16),(22999u16,19294u16),(23000u16,19301u16), (23002u16,15491u16),(23004u16,11505u16),(23005u16,19298u16),(23011u16,19300u16), (23013u16,12114u16),(23016u16,15529u16),(23020u16,11312u16),(23033u16,19302u16), (23035u16,15571u16),(23039u16,16478u16),(23041u16,14629u16),(23043u16,14597u16), (23044u16,12451u16),(23045u16,19296u16),(23046u16,19297u16),(23047u16,11526u16), (23048u16,19299u16),(23049u16,19304u16),(23052u16,19303u16),(23057u16,19307u16), (23059u16,19309u16),(23064u16,12904u16),(23068u16,12865u16),(23071u16,11759u16), (23072u16,13854u16),(23075u16,19308u16),(23077u16,10245u16),(23081u16,12703u16), (23089u16,15748u16),(23090u16,19305u16),(23092u16,19306u16),(23094u16,13587u16), (23100u16,19314u16),(23104u16,19310u16),(23110u16,13242u16),(23113u16,14616u16), (23114u16,19312u16),(23125u16,19313u16),(23130u16,11188u16),(23138u16,19315u16), (23143u16,19311u16),(23146u16,12088u16),(23156u16,15679u16),(23157u16,19316u16), (23158u16,13859u16),(23159u16,19320u16),(23162u16,19321u16),(23167u16,15191u16), (23186u16,12664u16),(23194u16,12671u16),(23195u16,19319u16),(23210u16,19318u16), (23218u16,19324u16),(23219u16,14932u16),(23221u16,20319u16),(23224u16,19327u16), (23230u16,19322u16),(23233u16,11367u16),(23234u16,13784u16),(23241u16,11326u16), (23244u16,14966u16),(23250u16,19325u16),(23252u16,19326u16),(23254u16,19331u16), (23256u16,19333u16),(23260u16,19334u16),(23264u16,19328u16),(23265u16,10028u16), (23267u16,19329u16),(23270u16,19332u16),(23273u16,12884u16),(23275u16,19323u16), (23281u16,19330u16),(23305u16,19335u16),(23318u16,19337u16),(23319u16,19336u16), (23346u16,19338u16),(23348u16,16903u16),(23351u16,19339u16),(23360u16,19340u16), (23376u16,16486u16),(23377u16,19346u16),(23379u16,19347u16),(23380u16,11930u16), (23381u16,15913u16),(23383u16,16489u16),(23384u16,9855u16),(23385u16,14234u16), (23386u16,19343u16),(23387u16,16660u16),(23388u16,16481u16),(23389u16,15107u16), (23391u16,12682u16),(23394u16,19348u16),(23395u16,11335u16),(23396u16,10769u16), (23397u16,19344u16),(23398u16,15302u16),(23401u16,10927u16),(23402u16,12492u16), (23404u16,16636u16),(23408u16,14040u16),(23409u16,19173u16),(23411u16,19345u16), (23413u16,10440u16),(23418u16,13655u16),(23421u16,12910u16),(23424u16,19113u16), (23425u16,12919u16),(23427u16,14247u16),(23428u16,19114u16),(23429u16,16067u16), (23431u16,15753u16),(23432u16,14021u16),(23433u16,9043u16),(23435u16,14201u16), (23436u16,14609u16),(23439u16,10999u16),(23443u16,19116u16),(23445u16,19115u16), (23447u16,16493u16),(23448u16,10792u16),(23449u16,16315u16),(23450u16,10173u16), (23451u16,14615u16),(23452u16,15528u16),(23453u16,9221u16),(23454u16,13986u16), (23456u16,9667u16),(23457u16,13858u16),(23458u16,11920u16),(23459u16,15196u16), (23460u16,14015u16),(23461u16,19117u16),(23462u16,11149u16),(23466u16,14975u16), (23467u16,10747u16),(23472u16,15920u16),(23475u16,10931u16),(23476u16,15366u16), (23477u16,15007u16),(23478u16,11355u16),(23480u16,19118u16),(23481u16,13646u16), (23485u16,11952u16),(23486u16,9301u16),(23487u16,14217u16),(23490u16,11342u16), (23492u16,11341u16),(23493u16,15575u16),(23494u16,12695u16),(23495u16,11935u16), (23500u16,10572u16),(23504u16,12669u16),(23506u16,10939u16),(23507u16,15867u16), (23517u16,13457u16),(23518u16,12840u16),(23519u16,9481u16),(23521u16,10784u16), (23524u16,19122u16),(23525u16,12295u16),(23528u16,16070u16),(23534u16,19123u16), (23536u16,19125u16),(23544u16,9856u16),(23545u16,10217u16),(23546u16,14189u16), (23547u16,15311u16),(23548u16,10003u16),(23551u16,14022u16),(23553u16,10421u16), (23556u16,13843u16),(23558u16,11506u16),(23561u16,14755u16),(23562u16,16515u16), (23567u16,15106u16),(23569u16,13832u16),(23572u16,10256u16),(23573u16,19341u16), (23574u16,11371u16),(23576u16,9625u16),(23578u16,13823u16),(23580u16,19342u16), (23581u16,9597u16),(23586u16,17809u16),(23588u16,15715u16),(23589u16,17810u16), (23591u16,15487u16),(23596u16,17811u16),(23601u16,11730u16),(23604u16,17812u16), (23608u16,13977u16),(23609u16,15577u16),(23610u16,9658u16),(23611u16,19169u16), (23612u16,12890u16),(23613u16,11686u16),(23614u16,14743u16),(23615u16,12907u16), (23616u16,11739u16),(23617u16,13213u16),(23618u16,9472u16),(23621u16,11736u16), (23624u16,13487u16),(23625u16,14420u16),(23626u16,11571u16),(23627u16,14786u16), (23630u16,13991u16),(23631u16,13238u16),(23632u16,19171u16),(23633u16,15133u16), (23637u16,16080u16),(23641u16,19172u16),(23646u16,14049u16),(23648u16,14567u16), (23649u16,12482u16),(23651u16,19174u16),(23653u16,12481u16),(23654u16,19175u16), (23662u16,19183u16),(23663u16,14580u16),(23665u16,13804u16),(23673u16,15542u16), (23674u16,18343u16),(23679u16,15751u16),(23681u16,14229u16),(23682u16,13286u16), (23688u16,18347u16),(23692u16,18342u16),(23693u16,18344u16),(23696u16,18345u16), (23697u16,18350u16),(23700u16,9482u16),(23702u16,18346u16),(23703u16,10603u16), (23704u16,18348u16),(23705u16,18349u16),(23706u16,18351u16),(23707u16,10001u16), (23708u16,18352u16),(23714u16,18354u16),(23715u16,18359u16),(23721u16,15345u16), (23723u16,18357u16),(23724u16,18356u16),(23725u16,12330u16),(23729u16,18358u16), (23731u16,15897u16),(23733u16,18353u16),(23735u16,18361u16),(23736u16,9047u16), (23741u16,18355u16),(23743u16,11964u16),(23745u16,18360u16),(23748u16,18362u16), (23755u16,18365u16),(23762u16,18363u16),(23769u16,16282u16),(23777u16,14946u16), (23780u16,18364u16),(23781u16,18366u16),(23782u16,12490u16),(23784u16,10240u16), (23786u16,15763u16),(23789u16,13440u16),(23792u16,10424u16),(23803u16,11779u16), (23810u16,18367u16),(23811u16,18368u16),(23814u16,18374u16),(23815u16,9666u16), (23822u16,13278u16),(23828u16,9847u16),(23830u16,15329u16),(23835u16,18375u16), (23838u16,18373u16),(23844u16,18372u16),(23846u16,18370u16),(23847u16,18369u16), (23849u16,9247u16),(23853u16,16079u16),(23854u16,18371u16),(23860u16,18378u16), (23869u16,18379u16),(23870u16,18377u16),(23879u16,21085u16),(23882u16,18386u16), (23883u16,18385u16),(23884u16,13417u16),(23896u16,18376u16),(23899u16,18381u16), (23901u16,18383u16),(23913u16,18387u16),(23915u16,18384u16),(23916u16,18380u16), (23919u16,18382u16),(23924u16,18388u16),(23938u16,18389u16),(23961u16,18390u16), (23965u16,18391u16),(23991u16,18393u16),(24005u16,18394u16),(24013u16,14726u16), (24027u16,19536u16),(24029u16,9793u16),(24030u16,16306u16),(24033u16,15313u16), (24034u16,9613u16),(24037u16,10739u16),(24038u16,16518u16),(24039u16,13436u16), (24040u16,11747u16),(24041u16,10749u16),(24043u16,14780u16),(24046u16,9483u16), (24047u16,17242u16),(24049u16,11331u16),(24050u16,15534u16),(24051u16,14195u16), (24052u16,9070u16),(24055u16,14994u16),(24061u16,16882u16),(24062u16,11572u16), (24065u16,9265u16),(24066u16,14013u16),(24067u16,9433u16),(24069u16,14162u16), (24070u16,10366u16),(24072u16,13971u16),(24076u16,14918u16),(24079u16,18233u16), (24080u16,16097u16),(24081u16,18236u16),(24084u16,18235u16),(24085u16,13048u16), (24086u16,14436u16),(24088u16,12272u16),(24089u16,18234u16),(24090u16,16312u16), (24091u16,9420u16),(24092u16,16281u16),(24093u16,10034u16),(24102u16,9873u16), (24103u16,16246u16),(24109u16,14930u16),(24110u16,9104u16),(24113u16,18237u16), (24119u16,18336u16),(24120u16,9598u16),(24123u16,18238u16),(24124u16,18239u16), (24125u16,12652u16),(24130u16,12696u16),(24132u16,18337u16),(24133u16,10444u16), (24140u16,11162u16),(24148u16,18338u16),(24149u16,12852u16),(24155u16,18339u16), (24158u16,18340u16),(24161u16,18341u16),(24162u16,9802u16),(24178u16,10586u16), (24179u16,13234u16),(24180u16,12899u16),(24182u16,9407u16),(24184u16,15155u16), (24186u16,19534u16),(24187u16,11150u16),(24188u16,15730u16),(24189u16,15711u16), (24191u16,10802u16),(24192u16,18572u16),(24196u16,16450u16),(24198u16,13471u16), (24199u16,9266u16),(24202u16,9803u16),(24203u16,18574u16),(24207u16,15187u16), (24208u16,12459u16),(24209u16,18573u16),(24211u16,11941u16),(24212u16,15681u16), (24213u16,10030u16),(24214u16,18575u16),(24215u16,10049u16),(24217u16,12712u16), (24218u16,10638u16),(24220u16,10559u16),(24222u16,13066u16),(24223u16,10402u16), (24224u16,18577u16),(24229u16,18576u16),(24230u16,10205u16),(24231u16,16524u16), (24237u16,14540u16),(24243u16,18581u16),(24245u16,18579u16),(24246u16,14057u16), (24247u16,11896u16),(24248u16,15700u16),(24249u16,18578u16),(24254u16,18580u16), (24265u16,12269u16),(24266u16,12105u16),(24273u16,18584u16),(24274u16,18583u16), (24275u16,12075u16),(24278u16,12301u16),(24283u16,18585u16),(24296u16,18586u16), (24298u16,18587u16),(24308u16,17235u16),(24310u16,15346u16),(24311u16,14537u16), (24314u16,11503u16),(24318u16,17800u16),(24319u16,16630u16),(24320u16,11885u16), (24321u16,17240u16),(24322u16,15561u16),(24323u16,13295u16),(24324u16,13025u16), (24328u16,17801u16),(24330u16,9270u16),(24331u16,17969u16),(24335u16,13994u16), (24337u16,17972u16),(24339u16,10748u16),(24341u16,15578u16),(24343u16,10550u16), (24344u16,11000u16),(24347u16,9653u16),(24351u16,10035u16),(24352u16,16092u16), (24357u16,12689u16),(24358u16,14965u16),(24359u16,11116u16),(24361u16,19178u16), (24362u16,19177u16),(24365u16,19179u16),(24367u16,14603u16),(24369u16,13670u16), (24377u16,9990u16),(24378u16,13426u16),(24380u16,19181u16),(24384u16,20441u16), (24400u16,19165u16),(24402u16,10808u16),(24403u16,9992u16),(24405u16,12473u16), (24406u16,19167u16),(24407u16,19166u16),(24408u16,19168u16),(24413u16,15530u16), (24417u16,18409u16),(24418u16,15151u16),(24420u16,14549u16),(24422u16,15364u16), (24425u16,9447u16),(24426u16,9290u16),(24428u16,9297u16),(24429u16,13092u16), (24432u16,16090u16),(24433u16,15691u16),(24435u16,18395u16),(24439u16,18396u16), (24441u16,15544u16),(24443u16,9620u16),(24444u16,9258u16),(24448u16,14624u16), (24449u16,16142u16),(24450u16,18397u16),(24452u16,11707u16),(24453u16,9878u16), (24455u16,18398u16),(24456u16,10985u16),(24457u16,18399u16),(24458u16,11133u16), (24459u16,12486u16),(24460u16,18400u16),(24464u16,15181u16),(24466u16,14564u16), (24469u16,18401u16),(24471u16,10010u16),(24472u16,13054u16),(24473u16,18402u16), (24476u16,18403u16),(24481u16,15764u16),(24488u16,18404u16),(24490u16,15308u16), (24493u16,18405u16),(24494u16,14727u16),(24501u16,18406u16),(24503u16,10009u16), (24508u16,18407u16),(24509u16,11168u16),(24515u16,15141u16),(24516u16,18589u16), (24517u16,9271u16),(24518u16,15553u16),(24521u16,18590u16),(24524u16,11346u16), (24525u16,13629u16),(24527u16,18592u16),(24528u16,20519u16),(24529u16,20518u16), (24530u16,17970u16),(24534u16,18591u16),(24535u16,16275u16),(24536u16,14627u16), (24537u16,12641u16),(24541u16,18750u16),(24544u16,16295u16),(24545u16,18596u16), (24548u16,18597u16),(24551u16,15714u16),(24554u16,18601u16),(24555u16,11951u16), (24557u16,18602u16),(24558u16,18594u16),(24561u16,9627u16),(24565u16,12903u16), (24568u16,18603u16),(24571u16,15140u16),(24573u16,11011u16),(24574u16,18598u16), (24575u16,10417u16),(24576u16,11134u16),(24577u16,14357u16),(24578u16,14198u16), (24579u16,18593u16),(24580u16,18595u16),(24581u16,18599u16),(24582u16,18600u16), (24586u16,18612u16),(24589u16,18609u16),(24590u16,15950u16),(24591u16,18608u16), (24594u16,13028u16),(24596u16,16145u16),(24597u16,13049u16),(24598u16,9437u16), (24601u16,18604u16),(24603u16,18607u16),(24604u16,12270u16),(24605u16,14183u16), (24608u16,9976u16),(24609u16,18614u16),(24613u16,11322u16),(24614u16,18606u16), (24615u16,15157u16),(24616u16,15890u16),(24617u16,18610u16),(24618u16,10789u16), (24619u16,18611u16),(24623u16,13446u16),(24629u16,18605u16),(24635u16,16495u16), (24636u16,20616u16),(24639u16,18613u16),(24641u16,20620u16),(24642u16,18619u16), (24643u16,14014u16),(24651u16,12276u16),(24653u16,11163u16),(24656u16,11929u16), (24658u16,10992u16),(24661u16,14156u16),(24665u16,20621u16),(24666u16,20618u16), (24669u16,20617u16),(24674u16,11169u16),(24675u16,20622u16),(24676u16,15189u16), (24679u16,20619u16),(24680u16,10987u16),(24681u16,10252u16),(24682u16,18716u16), (24683u16,10183u16),(24684u16,14426u16),(24685u16,10742u16),(24687u16,14917u16), (24688u16,13396u16),(24691u16,11925u16),(24694u16,10246u16),(24696u16,18615u16), (24697u16,18616u16),(24698u16,18618u16),(24699u16,18617u16),(24700u16,12878u16), (24701u16,18717u16),(24703u16,15708u16),(24707u16,18722u16),(24708u16,13431u16), (24713u16,14919u16),(24716u16,18724u16),(24717u16,10948u16),(24722u16,18723u16), (24724u16,11173u16),(24726u16,18718u16),(24730u16,18719u16),(24731u16,18725u16), (24733u16,18721u16),(24735u16,14807u16),(24736u16,15713u16),(24739u16,11143u16), (24742u16,15900u16),(24744u16,12915u16),(24747u16,20623u16),(24748u16,15197u16), (24749u16,18720u16),(24751u16,12720u16),(24753u16,18728u16),(24754u16,9230u16), (24756u16,18733u16),(24760u16,11339u16),(24763u16,18727u16),(24764u16,10006u16), (24773u16,13468u16),(24774u16,18731u16),(24778u16,11695u16),(24779u16,14614u16), (24785u16,11198u16),(24789u16,14417u16),(24792u16,18730u16),(24794u16,18732u16), (24796u16,14922u16),(24797u16,18729u16),(24799u16,14734u16),(24800u16,11176u16), (24806u16,10050u16),(24807u16,11754u16),(24808u16,9455u16),(24809u16,9640u16), (24811u16,9240u16),(24812u16,18726u16),(24813u16,9454u16),(24814u16,9987u16), (24815u16,10798u16),(24816u16,10237u16),(24819u16,14990u16),(24820u16,18738u16), (24822u16,11159u16),(24825u16,13624u16),(24826u16,15147u16),(24832u16,18739u16), (24833u16,9673u16),(24838u16,20624u16),(24840u16,15765u16),(24841u16,15743u16), (24845u16,20625u16),(24846u16,18740u16),(24847u16,15551u16),(24853u16,18736u16), (24858u16,15737u16),(24863u16,10593u16),(24864u16,18734u16),(24867u16,18737u16), (24868u16,10418u16),(24870u16,18735u16),(24871u16,12067u16),(24875u16,18741u16), (24895u16,15889u16),(24904u16,9825u16),(24906u16,18742u16),(24908u16,11152u16), (24910u16,13862u16),(24913u16,13844u16),(24917u16,12854u16),(24925u16,20626u16), (24930u16,12538u16),(24935u16,11174u16),(24936u16,11889u16),(24944u16,14756u16), (24949u16,18743u16),(24951u16,11897u16),(24971u16,9294u16),(24974u16,15952u16), (24980u16,18745u16),(24989u16,20628u16),(24999u16,18746u16),(25000u16,10934u16), (25001u16,20627u16),(25004u16,18744u16),(25015u16,18747u16),(25022u16,10947u16), (25026u16,10179u16),(25032u16,15129u16),(25034u16,9060u16),(25035u16,20629u16), (25041u16,20630u16),(25042u16,12098u16),(25044u16,18748u16),(25062u16,13034u16), (25077u16,18749u16),(25087u16,17403u16),(25094u16,20631u16),(25096u16,10619u16), (25098u16,14801u16),(25099u16,20052u16),(25100u16,15176u16),(25101u16,14054u16), (25102u16,13639u16),(25103u16,14938u16),(25104u16,9636u16),(25105u16,14775u16), (25106u16,11563u16),(25109u16,18777u16),(25110u16,11197u16),(25111u16,20053u16), (25112u16,16084u16),(25114u16,13266u16),(25115u16,20054u16),(25119u16,20055u16), (25121u16,20057u16),(25122u16,20056u16),(25124u16,20059u16),(25125u16,20058u16), (25130u16,11551u16),(25132u16,20060u16),(25134u16,12475u16),(25139u16,9818u16), (25140u16,9872u16),(25143u16,11122u16),(25149u16,20495u16),(25150u16,20494u16), (25151u16,10386u16),(25152u16,14244u16),(25153u16,9281u16),(25155u16,20496u16), (25159u16,13815u16),(25160u16,20497u16),(25161u16,20498u16),(25163u16,14019u16), (25164u16,17813u16),(25165u16,9442u16),(25166u16,15955u16),(25169u16,13248u16), (25170u16,9064u16),(25171u16,9867u16),(25172u16,13636u16),(25176u16,14583u16), (25179u16,11899u16),(25187u16,11934u16),(25190u16,13399u16),(25191u16,16265u16), (25193u16,12074u16),(25194u16,17814u16),(25195u16,13783u16),(25196u16,15374u16), (25197u16,13019u16),(25198u16,9096u16),(25199u16,9617u16),(25200u16,13622u16), (25203u16,9091u16),(25206u16,10441u16),(25209u16,13105u16),(25212u16,10248u16), (25214u16,16105u16),(25215u16,9643u16),(25216u16,11333u16),(25220u16,9608u16), (25225u16,11766u16),(25226u16,9074u16),(25233u16,15539u16),(25234u16,14032u16), (25235u16,16440u16),(25237u16,14557u16),(25238u16,10187u16),(25239u16,11900u16), (25240u16,16114u16),(25242u16,10552u16),(25243u16,13070u16),(25247u16,17815u16), (25248u16,11932u16),(25249u16,12498u16),(25250u16,13427u16),(25252u16,11119u16), (25253u16,9223u16),(25256u16,13089u16),(25259u16,13106u16),(25260u16,14352u16), (25265u16,9222u16),(25269u16,10029u16),(25273u16,12833u16),(25275u16,17816u16), (25276u16,15321u16),(25277u16,9668u16),(25279u16,12717u16),(25282u16,10442u16), (25284u16,16329u16),(25285u16,9978u16),(25286u16,9485u16),(25287u16,12845u16), (25288u16,12898u16),(25289u16,12078u16),(25290u16,17817u16),(25292u16,9097u16), (25293u16,13051u16),(25294u16,12319u16),(25296u16,10788u16),(25298u16,11745u16), (25299u16,14591u16),(25300u16,9071u16),(25302u16,14582u16),(25303u16,17819u16), (25304u16,11733u16),(25305u16,16465u16),(25306u16,17818u16),(25307u16,16103u16), (25308u16,9086u16),(25311u16,12891u16),(25314u16,12448u16),(25315u16,11385u16), (25317u16,15696u16),(25318u16,12090u16),(25319u16,13016u16),(25320u16,9411u16), (25321u16,15946u16),(25324u16,12073u16),(25325u16,14000u16),(25326u16,17820u16), (25327u16,16147u16),(25329u16,10751u16),(25331u16,13598u16),(25332u16,14164u16), (25334u16,17822u16),(25335u16,11904u16),(25340u16,13225u16),(25341u16,16442u16), (25342u16,13981u16),(25343u16,12860u16),(25345u16,9649u16),(25346u16,10785u16), (25351u16,16269u16),(25352u16,20137u16),(25353u16,9045u16),(25358u16,11945u16), (25361u16,14429u16),(25366u16,14593u16),(25370u16,16276u16),(25371u16,12491u16), (25373u16,14771u16),(25374u16,14347u16),(25375u16,15119u16),(25376u16,12876u16), (25377u16,9993u16),(25378u16,17821u16),(25379u16,16140u16),(25380u16,11328u16), (25381u16,11166u16),(25384u16,9029u16),(25386u16,13033u16),(25387u16,9861u16), (25391u16,16136u16),(25394u16,20138u16),(25401u16,17823u16),(25402u16,14541u16), (25405u16,14611u16),(25410u16,14795u16),(25411u16,17825u16),(25413u16,14552u16), (25414u16,12071u16),(25417u16,16464u16),(25419u16,17824u16),(25420u16,9063u16), (25421u16,10945u16),(25422u16,13826u16),(25423u16,12908u16),(25424u16,11757u16), (25429u16,9427u16),(25438u16,12109u16),(25439u16,14235u16),(25441u16,11386u16), (25442u16,11142u16),(25443u16,9998u16),(25447u16,13100u16),(25449u16,17835u16), (25453u16,17832u16),(25454u16,11746u16),(25457u16,17828u16),(25462u16,9808u16), (25463u16,11556u16),(25466u16,17829u16),(25467u16,12902u16),(25472u16,14953u16), (25474u16,10039u16),(25479u16,10227u16),(25480u16,14023u16),(25481u16,10059u16), (25482u16,17834u16),(25484u16,16093u16),(25486u16,17830u16),(25487u16,14390u16), (25488u16,13299u16),(25490u16,13052u16),(25494u16,15505u16),(25496u16,11767u16), (25504u16,12496u16),(25506u16,14374u16),(25507u16,9619u16),(25509u16,11546u16), (25511u16,11931u16),(25512u16,14573u16),(25513u16,15353u16),(25514u16,9860u16), (25516u16,17833u16),(25517u16,17826u16),(25518u16,17836u16),(25520u16,20139u16), (25523u16,12461u16),(25524u16,17831u16),(25527u16,16277u16),(25528u16,9982u16), (25530u16,9489u16),(25532u16,17837u16),(25534u16,17847u16),(25540u16,17842u16), (25542u16,17846u16),(25545u16,13649u16),(25549u16,16500u16),(25550u16,17844u16), (25551u16,12707u16),(25552u16,14410u16),(25554u16,9474u16),(25558u16,15515u16), (25566u16,17843u16),(25568u16,17840u16),(25569u16,14778u16),(25571u16,9792u16), (25577u16,11886u16),(25578u16,11715u16),(25581u16,11545u16),(25586u16,17838u16), (25588u16,15879u16),(25590u16,17827u16),(25592u16,17839u16),(25597u16,12096u16), (25599u16,17841u16),(25600u16,9488u16),(25601u16,10618u16),(25602u16,12452u16), (25605u16,11528u16),(25611u16,17850u16),(25612u16,17853u16),(25615u16,9416u16), (25616u16,9789u16),(25619u16,9859u16),(25620u16,13781u16),(25627u16,17851u16), (25628u16,14204u16),(25630u16,10612u16),(25632u16,17852u16),(25633u16,17855u16), (25638u16,17854u16),(25642u16,14379u16),(25644u16,9090u16),(25645u16,9863u16), (25652u16,19121u16),(25658u16,15120u16),(25661u16,9480u16),(25663u16,20236u16), (25665u16,17849u16),(25668u16,13842u16),(25669u16,17848u16),(25670u16,9083u16), (25671u16,15486u16),(25672u16,9302u16),(25674u16,14360u16),(25682u16,17845u16), (25684u16,14159u16),(25688u16,16065u16),(25694u16,17856u16),(25703u16,9846u16), (25705u16,12831u16),(25709u16,17858u16),(25720u16,12729u16),(25721u16,12826u16), (25722u16,17956u16),(25730u16,12299u16),(25732u16,17857u16),(25733u16,11764u16), (25735u16,13223u16),(25745u16,9632u16),(25746u16,13671u16),(25749u16,14181u16), (25750u16,17859u16),(25753u16,17959u16),(25758u16,16453u16),(25764u16,9618u16), (25769u16,12290u16),(25772u16,13438u16),(25773u16,9410u16),(25774u16,9858u16), (25776u16,16446u16),(25781u16,12901u16),(25783u16,17957u16),(25784u16,17958u16), (25786u16,17960u16),(25788u16,10944u16),(25792u16,17961u16),(25794u16,12127u16), (25797u16,13810u16),(25805u16,9462u16),(25806u16,13465u16),(25808u16,17962u16), (25810u16,13455u16),(25815u16,17963u16),(25816u16,20237u16),(25822u16,14206u16), (25826u16,17965u16),(25828u16,17964u16),(25830u16,9438u16),(25856u16,13057u16), (25865u16,17966u16),(25874u16,15925u16),(25880u16,13618u16),(25893u16,17967u16), (25899u16,11765u16),(25902u16,17968u16),(25903u16,16252u16),(25908u16,20068u16), (25909u16,20257u16),(25910u16,14018u16),(25912u16,16717u16),(25913u16,10581u16), (25915u16,10740u16),(25918u16,10392u16),(25919u16,16149u16),(25925u16,10777u16), (25928u16,15112u16),(25929u16,21990u16),(25932u16,10023u16),(25935u16,12719u16), (25937u16,11725u16),(25941u16,20258u16),(25942u16,9054u16),(25945u16,11539u16), (25947u16,12273u16),(25949u16,9269u16),(25950u16,9603u16),(25954u16,10595u16), (25955u16,13777u16),(25958u16,10221u16),(25963u16,20259u16),(25964u16,11705u16), (25968u16,14058u16),(25970u16,13430u16),(25972u16,16146u16),(25975u16,10438u16), (25991u16,14761u16),(25995u16,16066u16),(25996u16,9298u16),(26000u16,20444u16), (26001u16,9088u16),(26003u16,20446u16),(26007u16,10188u16),(26009u16,12302u16), (26011u16,22225u16),(26012u16,15122u16),(26015u16,16124u16),(26017u16,14776u16), (26020u16,11574u16),(26021u16,9661u16),(26023u16,10556u16),(26025u16,16077u16), (26027u16,20644u16),(26029u16,10212u16),(26031u16,14180u16),(26032u16,15139u16), (26041u16,10384u16),(26044u16,20447u16),(26045u16,13974u16),(26049u16,13067u16), (26051u16,20450u16),(26052u16,20449u16),(26053u16,12480u16),(26054u16,20448u16), (26059u16,15198u16),(26060u16,20451u16),(26062u16,20452u16),(26063u16,16504u16), (26066u16,20453u16),(26070u16,20454u16),(26071u16,13281u16),(26080u16,14787u16), (26082u16,11345u16),(26085u16,13638u16),(26086u16,9984u16),(26087u16,11726u16), (26088u16,16273u16),(26089u16,15936u16),(26092u16,15309u16),(26093u16,15186u16), (26094u16,20069u16),(26095u16,20070u16),(26096u16,20071u16),(26097u16,10946u16), (26102u16,13982u16),(26103u16,11960u16),(26106u16,14625u16),(26112u16,20077u16), (26114u16,9051u16),(26115u16,20075u16),(26118u16,12070u16),(26122u16,20072u16), (26124u16,9498u16),(26126u16,12722u16),(26127u16,11187u16),(26131u16,15540u16), (26132u16,14809u16),(26133u16,20076u16),(26137u16,20073u16),(26141u16,20080u16), (26143u16,15144u16),(26144u16,15694u16),(26149u16,9811u16),(26151u16,12668u16), (26152u16,16517u16),(26157u16,16104u16),(26159u16,14004u16),(26161u16,20082u16), (26164u16,20081u16),(26165u16,20084u16),(26166u16,20083u16),(26172u16,16316u16), (26174u16,14967u16),(26177u16,20088u16),(26179u16,11161u16),(26187u16,11585u16), (26188u16,13821u16),(26191u16,20089u16),(26194u16,13800u16),(26195u16,15009u16), (26196u16,20087u16),(26197u16,15911u16),(26198u16,20090u16),(26199u16,20092u16), (26202u16,14612u16),(26207u16,20086u16),(26209u16,20091u16),(26212u16,14803u16), (26214u16,11177u16),(26216u16,9626u16),(26222u16,13258u16),(26223u16,11701u16), (26224u16,14815u16),(26228u16,13466u16),(26230u16,11692u16),(26231u16,20093u16), (26234u16,16284u16),(26238u16,12287u16),(26242u16,15926u16),(26244u16,20094u16), (26247u16,14945u16),(26252u16,20095u16),(26257u16,14043u16),(26262u16,13030u16), (26263u16,9046u16),(26269u16,20097u16),(26279u16,20096u16),(26280u16,22008u16), (26286u16,12851u16),(26292u16,9224u16),(26297u16,19158u16),(26302u16,20098u16), (26329u16,14044u16),(26331u16,20099u16),(26332u16,20100u16),(26333u16,13261u16), (26342u16,20101u16),(26345u16,20102u16),(26352u16,15892u16),(26354u16,13485u16), (26355u16,15508u16),(26356u16,10637u16),(26359u16,20079u16),(26361u16,9465u16), (26364u16,12537u16),(26366u16,15953u16),(26367u16,14415u16),(26368u16,16513u16), (26376u16,15899u16),(26377u16,15723u16),(26378u16,20270u16),(26379u16,13098u16), (26381u16,10449u16),(26384u16,20287u16),(26388u16,14178u16),(26389u16,20297u16), (26391u16,12107u16),(26395u16,14626u16),(26397u16,9610u16),(26399u16,13263u16), (26406u16,20327u16),(26408u16,12855u16),(26410u16,14745u16),(26411u16,12834u16), (26412u16,9245u16),(26413u16,15958u16),(26415u16,14050u16),(26417u16,16321u16), (26420u16,13256u16),(26421u16,10233u16),(26426u16,11205u16),(26429u16,15169u16), (26432u16,13792u16),(26434u16,15916u16),(26435u16,13593u16),(26438u16,10588u16), (26440u16,19695u16),(26441u16,13803u16),(26444u16,19692u16),(26446u16,12143u16), (26447u16,15156u16),(26448u16,9441u16),(26449u16,9854u16),(26451u16,19693u16), (26454u16,16095u16),(26460u16,10202u16),(26462u16,19694u16),(26463u16,14053u16), (26464u16,10605u16),(26465u16,14430u16),(26469u16,12085u16),(26472u16,15373u16), (26473u16,19696u16),(26474u16,19699u16),(26477u16,10953u16),(26479u16,9228u16), (26480u16,11555u16),(26482u16,20074u16),(26483u16,19700u16),(26485u16,19703u16), (26487u16,19708u16),(26492u16,19709u16),(26494u16,14196u16),(26495u16,9094u16), (26497u16,11316u16),(26500u16,10760u16),(26503u16,19698u16),(26505u16,14622u16), (26507u16,19707u16),(26512u16,14811u16),(26517u16,16132u16),(26519u16,12309u16), (26520u16,19701u16),(26522u16,12657u16),(26524u16,10826u16),(26525u16,16251u16), (26526u16,19705u16),(26530u16,14029u16),(26531u16,15935u16),(26533u16,19697u16), (26535u16,19702u16),(26536u16,19704u16),(26538u16,13420u16),(26539u16,10422u16), (26541u16,19706u16),(26543u16,11936u16),(26544u16,19715u16),(26547u16,19720u16), (26549u16,19718u16),(26550u16,11365u16),(26551u16,11352u16),(26552u16,19724u16), (26561u16,19727u16),(26563u16,19723u16),(26564u16,9305u16),(26575u16,9081u16), (26576u16,12844u16),(26577u16,10589u16),(26578u16,13271u16),(26579u16,13615u16), (26580u16,13650u16),(26584u16,19712u16),(26585u16,19717u16),(26586u16,19719u16), (26588u16,10816u16),(26589u16,19721u16),(26590u16,16520u16),(26592u16,12916u16), (26594u16,19725u16),(26597u16,9478u16),(26601u16,19714u16),(26604u16,11382u16), (26607u16,11909u16),(26608u16,19710u16),(26609u16,16334u16),(26611u16,12343u16), (26612u16,9486u16),(26621u16,19728u16),(26623u16,13998u16),(26624u16,19722u16), (26629u16,16059u16),(26631u16,9289u16),(26632u16,16082u16),(26633u16,19711u16), (26634u16,19713u16),(26635u16,10181u16),(26636u16,19716u16),(26638u16,19726u16), (26639u16,12089u16),(26641u16,14052u16),(26643u16,14163u16),(26646u16,13265u16), (26647u16,12150u16),(26653u16,19738u16),(26657u16,15108u16),(26665u16,19747u16), (26666u16,16319u16),(26674u16,19729u16),(26675u16,19730u16),(26679u16,15384u16), (26680u16,10968u16),(26681u16,10634u16),(26684u16,10626u16),(26685u16,15917u16), (26686u16,19744u16),(26688u16,19743u16),(26689u16,19741u16),(26690u16,10815u16), (26691u16,14395u16),(26692u16,19735u16),(26693u16,14731u16),(26694u16,11957u16), (26696u16,9049u16),(26697u16,19746u16),(26698u16,19745u16),(26700u16,16467u16), (26702u16,19733u16),(26704u16,14544u16),(26705u16,13778u16),(26707u16,11139u16), (26708u16,11554u16),(26709u16,19739u16),(26720u16,19731u16),(26721u16,19732u16), (26722u16,19734u16),(26723u16,9996u16),(26724u16,19736u16),(26725u16,13432u16), (26726u16,19740u16),(26727u16,19742u16),(26728u16,11511u16),(26729u16,16449u16), (26731u16,19753u16),(26740u16,19750u16),(26742u16,14551u16),(26743u16,19751u16), (26753u16,12281u16),(26755u16,19737u16),(26757u16,12658u16),(26758u16,9105u16), (26767u16,19749u16),(26771u16,19752u16),(26775u16,10738u16),(26786u16,13825u16), (26790u16,12681u16),(26791u16,14789u16),(26792u16,12135u16),(26797u16,14238u16), (26799u16,14406u16),(26800u16,15126u16),(26803u16,14030u16),(26805u16,19748u16), (26816u16,11381u16),(26818u16,19754u16),(26825u16,12697u16),(26827u16,13274u16), (26829u16,10822u16),(26834u16,9109u16),(26837u16,16491u16),(26840u16,11317u16), (26842u16,13094u16),(26848u16,14381u16),(26851u16,19861u16),(26862u16,13788u16), (26864u16,19857u16),(26865u16,12131u16),(26869u16,11910u16),(26873u16,19759u16), (26874u16,10790u16),(26876u16,19756u16),(26881u16,19859u16),(26885u16,15531u16), (26891u16,19858u16),(26893u16,16263u16),(26894u16,16456u16),(26896u16,19862u16), (26898u16,11518u16),(26911u16,19757u16),(26912u16,19758u16),(26916u16,19856u16), (26925u16,14589u16),(26928u16,15497u16),(26932u16,19873u16),(26937u16,19864u16), (26941u16,9795u16),(26943u16,9812u16),(26946u16,19866u16),(26964u16,15113u16), (26967u16,19860u16),(26970u16,9689u16),(26973u16,19867u16),(26974u16,12132u16), (26976u16,19865u16),(26979u16,19880u16),(26982u16,19879u16),(26987u16,19869u16), (26990u16,19755u16),(26993u16,19863u16),(26999u16,11887u16),(27000u16,19872u16), (27001u16,19881u16),(27004u16,12450u16),(27008u16,19870u16),(27010u16,10582u16), (27012u16,19868u16),(27014u16,15735u16),(27015u16,19875u16),(27016u16,19876u16), (27017u16,19878u16),(27021u16,19894u16),(27028u16,12103u16),(27029u16,19892u16), (27032u16,19871u16),(27035u16,19882u16),(27036u16,9106u16),(27047u16,19883u16), (27048u16,16060u16),(27051u16,19885u16),(27053u16,19886u16),(27057u16,19888u16), (27060u16,12336u16),(27063u16,13607u16),(27067u16,19884u16),(27073u16,19889u16), (27082u16,19890u16),(27084u16,19874u16),(27086u16,19877u16),(27088u16,11132u16), (27092u16,19887u16),(27099u16,11392u16),(27103u16,19891u16),(27104u16,19893u16), (27117u16,19897u16),(27122u16,19901u16),(27133u16,9464u16),(27135u16,19895u16), (27146u16,10369u16),(27159u16,19898u16),(27160u16,19899u16),(27167u16,16088u16), (27169u16,12828u16),(27176u16,19911u16),(27178u16,10990u16),(27183u16,19896u16), (27185u16,15678u16),(27189u16,19907u16),(27197u16,19910u16),(27198u16,19903u16), (27204u16,19902u16),(27207u16,13428u16),(27216u16,19905u16),(27224u16,19912u16), (27225u16,9635u16),(27227u16,19906u16),(27233u16,14995u16),(27237u16,19900u16), (27249u16,9682u16),(27257u16,19909u16),(27260u16,19913u16),(27264u16,14365u16), (27268u16,14928u16),(27278u16,19908u16),(27280u16,19915u16),(27281u16,19914u16), (27287u16,19917u16),(27296u16,19904u16),(27305u16,19916u16),(27307u16,19918u16), (27308u16,12677u16),(27424u16,13418u16),(27425u16,9831u16),(27426u16,11137u16), (27427u16,15137u16),(27428u16,20428u16),(27431u16,13038u16),(27442u16,15766u16), (27447u16,20429u16),(27449u16,20430u16),(27450u16,13264u16),(27454u16,11953u16), (27459u16,20431u16),(27462u16,20432u16),(27463u16,15115u16),(27465u16,13419u16), (27468u16,10617u16),(27481u16,20433u16),(27490u16,16270u16),(27491u16,16148u16), (27492u16,9828u16),(27493u16,9434u16),(27494u16,14793u16),(27495u16,13276u16), (27498u16,14600u16),(27513u16,9870u16),(27515u16,14187u16),(27516u16,11368u16), (27521u16,19921u16),(27522u16,19922u16),(27523u16,15369u16),(27524u16,19924u16), (27526u16,9874u16),(27527u16,19923u16),(27529u16,15314u16),(27530u16,14031u16), (27531u16,9453u16),(27533u16,19927u16),(27538u16,19925u16),(27539u16,19926u16), (27542u16,16264u16),(27546u16,19928u16),(27547u16,19929u16),(27553u16,19930u16), (27562u16,19931u16),(27571u16,20440u16),(27572u16,13040u16),(27573u16,10211u16), (27575u16,15568u16),(27583u16,10053u16),(27585u16,11172u16),(27586u16,20442u16), (27589u16,15552u16),(27595u16,14792u16),(27597u16,12849u16),(27599u16,12666u16), (27602u16,10195u16),(27603u16,16650u16),(27604u16,9255u16),(27605u16,9262u16), (27606u16,9264u16),(27607u16,13109u16),(27609u16,9263u16),(27611u16,12646u16), (27617u16,16072u16),(27626u16,20239u16),(27627u16,10958u16),(27631u16,14371u16), (27635u16,20240u16),(27637u16,20242u16),(27641u16,20243u16),(27645u16,20241u16), (27653u16,20244u16),(27654u16,20246u16),(27655u16,20245u16),(27661u16,20247u16), (27663u16,14012u16),(27664u16,16646u16),(27665u16,12716u16),(27667u16,12640u16), (27668u16,13293u16),(27669u16,20248u16),(27670u16,12867u16),(27672u16,20249u16), (27673u16,20250u16),(27674u16,20251u16),(27675u16,10408u16),(27679u16,10445u16), (27681u16,20252u16),(27682u16,13461u16),(27684u16,20254u16),(27686u16,10929u16), (27687u16,15380u16),(27688u16,9042u16),(27689u16,20253u16),(27690u16,20255u16), (27694u16,9985u16),(27695u16,12485u16),(27696u16,13467u16),(27698u16,20256u16), (27700u16,14169u16),(27701u16,18778u16),(27704u16,15707u16),(27709u16,16874u16), (27712u16,14536u16),(27713u16,16258u16),(27714u16,13478u16),(27718u16,16879u16), (27719u16,11182u16),(27721u16,10951u16),(27722u16,18781u16),(27728u16,14926u16), (27732u16,18779u16),(27733u16,13814u16),(27735u16,10950u16),(27739u16,15315u16), (27740u16,18780u16),(27741u16,13659u16),(27742u16,10750u16),(27743u16,11508u16), (27744u16,9651u16),(27745u16,14784u16),(27748u16,14377u16),(27752u16,18787u16), (27753u16,18788u16),(27754u16,14619u16),(27760u16,14358u16),(27762u16,11324u16), (27764u16,18789u16),(27766u16,18790u16),(27769u16,15163u16),(27773u16,13296u16), (27774u16,10413u16),(27777u16,13458u16),(27778u16,15527u16),(27779u16,14779u16), (27781u16,18783u16),(27782u16,18791u16),(27784u16,13857u16),(27785u16,9628u16), (27788u16,18786u16),(27791u16,13272u16),(27792u16,18784u16),(27795u16,20634u16), (27796u16,18785u16),(27801u16,13794u16),(27803u16,13085u16),(27807u16,10756u16), (27809u16,12662u16),(27811u16,18782u16),(27812u16,13044u16),(27813u16,12259u16), (27814u16,12502u16),(27815u16,9460u16),(27817u16,18792u16),(27818u16,11121u16), (27819u16,12838u16),(27821u16,18795u16),(27822u16,11743u16),(27825u16,18806u16), (27826u16,18800u16),(27827u16,10976u16),(27832u16,10403u16),(27833u16,15720u16), (27835u16,16291u16),(27836u16,16106u16),(27837u16,10768u16),(27838u16,16075u16), (27839u16,15351u16),(27844u16,15130u16),(27845u16,13481u16),(27849u16,13595u16), (27850u16,9425u16),(27852u16,12693u16),(27856u16,18793u16),(27859u16,18807u16), (27860u16,18794u16),(27861u16,10363u16),(27862u16,18802u16),(27863u16,18799u16), (27867u16,10381u16),(27870u16,13017u16),(27872u16,18801u16),(27873u16,13076u16), (27874u16,9413u16),(27875u16,13297u16),(27877u16,12889u16),(27880u16,16437u16), (27882u16,12130u16),(27883u16,18804u16),(27886u16,18805u16),(27887u16,18808u16), (27888u16,14354u16),(27889u16,18798u16),(27891u16,15705u16),(27893u16,9250u16), (27894u16,20635u16),(27895u16,18796u16),(27896u16,18797u16),(27898u16,18803u16), (27899u16,15131u16),(27900u16,13240u16),(27901u16,15948u16),(27902u16,18809u16), (27905u16,11559u16),(27908u16,18912u16),(27911u16,18911u16),(27915u16,15378u16), (27916u16,18908u16),(27918u16,18914u16),(27922u16,13672u16),(27927u16,14935u16), (27929u16,18913u16),(27930u16,18919u16),(27931u16,12514u16),(27934u16,10185u16), (27941u16,11577u16),(27943u16,18907u16),(27946u16,10998u16),(27947u16,18915u16), (27950u16,18917u16),(27953u16,10258u16),(27954u16,16307u16),(27955u16,18923u16), (27957u16,18918u16),(27961u16,18906u16),(27963u16,11193u16),(27964u16,14596u16), (27965u16,13397u16),(27966u16,13056u16),(27969u16,12342u16),(27971u16,18909u16), (27973u16,13414u16),(27974u16,11507u16),(27975u16,11524u16),(27976u16,18910u16), (27978u16,16474u16),(27979u16,9471u16),(27981u16,18916u16),(27982u16,11340u16), (27983u16,18920u16),(27985u16,11190u16),(27986u16,18921u16),(27987u16,13023u16), (27988u16,18922u16),(27993u16,16122u16),(27994u16,11878u16),(27996u16,18931u16), (27998u16,18928u16),(28000u16,18932u16),(28003u16,18934u16),(28006u16,13259u16), (28009u16,10963u16),(28010u16,12108u16),(28014u16,10546u16),(28015u16,18925u16), (28020u16,15866u16),(28023u16,10928u16),(28024u16,11589u16),(28028u16,18933u16), (28034u16,14566u16),(28037u16,12914u16),(28040u16,15006u16),(28041u16,13845u16), (28044u16,15706u16),(28046u16,14964u16),(28049u16,18924u16),(28051u16,18929u16), (28052u16,18930u16),(28053u16,14418u16),(28059u16,14391u16),(28061u16,12117u16), (28062u16,18926u16),(28063u16,12271u16),(28064u16,18927u16),(28065u16,14773u16), (28067u16,11148u16),(28068u16,10026u16),(28070u16,13668u16),(28071u16,11502u16), (28072u16,16094u16),(28073u16,13787u16),(28074u16,10547u16),(28075u16,18947u16), (28078u16,18949u16),(28079u16,15331u16),(28082u16,15511u16),(28085u16,10938u16), (28088u16,10977u16),(28095u16,18940u16),(28096u16,10052u16),(28100u16,16480u16), (28101u16,18937u16),(28102u16,15008u16),(28103u16,18936u16),(28107u16,12315u16), (28108u16,14387u16),(28113u16,14036u16),(28118u16,12880u16),(28120u16,14397u16), (28121u16,18945u16),(28125u16,18944u16),(28126u16,18938u16),(28128u16,18941u16), (28129u16,9988u16),(28132u16,15732u16),(28134u16,18943u16),(28139u16,15574u16), (28140u16,9852u16),(28142u16,11135u16),(28145u16,13853u16),(28147u16,9815u16), (28151u16,11191u16),(28153u16,15340u16),(28155u16,14422u16),(28156u16,20636u16), (28165u16,13464u16),(28170u16,15873u16),(28172u16,18948u16),(28173u16,16488u16), (28174u16,18939u16),(28176u16,11500u16),(28177u16,18942u16),(28180u16,15745u16), (28182u16,18946u16),(28183u16,13863u16),(28186u16,18935u16),(28189u16,15744u16), (28192u16,13489u16),(28193u16,10206u16),(28195u16,15957u16),(28196u16,9424u16), (28197u16,18960u16),(28201u16,14759u16),(28203u16,18950u16),(28205u16,14753u16), (28207u16,10604u16),(28210u16,18959u16),(28212u16,11917u16),(28216u16,15721u16), (28218u16,12711u16),(28227u16,13055u16),(28228u16,18961u16),(28237u16,14571u16), (28238u16,18952u16),(28243u16,18957u16),(28244u16,18958u16),(28246u16,11019u16), (28248u16,14985u16),(28251u16,16086u16),(28255u16,18955u16),(28267u16,18953u16), (28270u16,18951u16),(28286u16,14604u16),(28287u16,13975u16),(28291u16,12068u16), (28293u16,11501u16),(28294u16,18956u16),(28297u16,10585u16),(28303u16,18976u16), (28304u16,15885u16),(28312u16,18964u16),(28316u16,12334u16),(28319u16,18978u16), (28322u16,15556u16),(28325u16,18968u16),(28327u16,18969u16),(28330u16,14925u16), (28335u16,14216u16),(28337u16,18963u16),(28338u16,18954u16),(28340u16,18974u16), (28342u16,13645u16),(28343u16,18972u16),(28346u16,12896u16),(28347u16,18971u16), (28349u16,18970u16),(28353u16,9687u16),(28354u16,18977u16),(28359u16,10040u16), (28363u16,16479u16),(28367u16,18975u16),(28369u16,11127u16),(28371u16,16485u16), (28372u16,14392u16),(28373u16,20323u16),(28375u16,18973u16),(28378u16,10821u16), (28382u16,16290u16),(28383u16,18962u16),(28384u16,18965u16),(28385u16,12535u16), (28386u16,18967u16),(28388u16,12488u16),(28389u16,12101u16),(28390u16,12493u16), (28392u16,9300u16),(28393u16,14363u16),(28404u16,10021u16),(28409u16,18984u16), (28418u16,13220u16),(28422u16,13270u16),(28425u16,18990u16),(28431u16,12454u16), (28435u16,12141u16),(28436u16,15356u16),(28437u16,18983u16),(28448u16,12839u16), (28452u16,18982u16),(28457u16,18991u16),(28458u16,18989u16),(28459u16,12539u16), (28461u16,18966u16),(28463u16,18985u16),(28465u16,14059u16),(28467u16,16091u16), (28470u16,18986u16),(28478u16,15385u16),(28486u16,18980u16),(28487u16,18981u16), (28491u16,18987u16),(28493u16,14736u16),(28504u16,13058u16),(28508u16,13412u16), (28510u16,12471u16),(28514u16,18979u16),(28518u16,12297u16),(28525u16,14367u16), (28526u16,9612u16),(28530u16,18996u16),(28532u16,18988u16),(28536u16,18995u16), (28538u16,18998u16),(28540u16,18997u16),(28548u16,9641u16),(28552u16,9621u16), (28553u16,18992u16),(28556u16,18994u16),(28557u16,18993u16),(28558u16,13091u16), (28572u16,12094u16),(28577u16,15937u16),(28583u16,19097u16),(28595u16,9061u16), (28598u16,19099u16),(28601u16,19098u16),(28608u16,11309u16),(28610u16,19100u16), (28617u16,19096u16),(28625u16,18999u16),(28626u16,9299u16),(28638u16,19103u16), (28640u16,19104u16),(28641u16,19101u16),(28654u16,19102u16),(28655u16,19105u16), (28689u16,13262u16),(28698u16,19106u16),(28699u16,19108u16),(28707u16,19107u16), (28725u16,19110u16),(28729u16,19109u16),(28748u16,10799u16),(28751u16,19111u16), (28766u16,19112u16),(28779u16,11195u16),(28780u16,20490u16),(28781u16,12715u16), (28783u16,10013u16),(28784u16,11165u16),(28789u16,12328u16),(28790u16,15943u16), (28792u16,11721u16),(28796u16,16473u16),(28798u16,15919u16),(28799u16,9456u16), (28800u16,20455u16),(28805u16,20078u16),(28809u16,12460u16),(28810u16,9807u16), (28814u16,15350u16),(28818u16,9615u16),(28820u16,13603u16),(28821u16,11902u16), (28822u16,20457u16),(28825u16,16288u16),(28828u16,20456u16),(28829u16,20458u16), (28843u16,20462u16),(28844u16,11755u16),(28845u16,14376u16),(28846u16,13073u16), (28847u16,11713u16),(28849u16,20463u16),(28851u16,9309u16),(28855u16,20461u16), (28856u16,16063u16),(28857u16,10042u16),(28859u16,20459u16),(28860u16,12277u16), (28861u16,9662u16),(28864u16,20460u16),(28865u16,14179u16),(28866u16,12100u16), (28867u16,14439u16),(28872u16,12305u16),(28874u16,20465u16),(28888u16,10995u16), (28889u16,12116u16),(28891u16,16327u16),(28895u16,15339u16),(28900u16,11905u16), (28902u16,10374u16),(28903u16,13828u16),(28904u16,20464u16),(28905u16,11181u16), (28907u16,14389u16),(28908u16,11588u16),(28909u16,13625u16),(28911u16,14924u16), (28919u16,14608u16),(28921u16,13090u16),(28925u16,10428u16),(28937u16,15336u16), (28938u16,10949u16),(28944u16,20466u16),(28947u16,20467u16),(28949u16,11147u16), (28950u16,20468u16),(28952u16,20491u16),(28953u16,9241u16),(28954u16,10412u16), (28966u16,11520u16),(28975u16,20469u16),(28976u16,15365u16),(28977u16,20470u16), (28982u16,13612u16),(28997u16,20474u16),(29002u16,20476u16),(29004u16,11160u16), (29006u16,11374u16),(29020u16,20472u16),(29022u16,13798u16),(29028u16,12661u16), (29030u16,20492u16),(29031u16,16108u16),(29032u16,20473u16),(29038u16,16328u16), (29042u16,20475u16),(29043u16,20471u16),(29048u16,20477u16),(29050u16,20478u16), (29053u16,13806u16),(29060u16,14923u16),(29066u16,15165u16),(29071u16,15307u16), (29076u16,13644u16),(29080u16,20479u16),(29081u16,14810u16),(29087u16,14041u16), (29088u16,20483u16),(29096u16,20482u16),(29100u16,9055u16),(29107u16,20480u16), (29109u16,20481u16),(29113u16,20493u16),(29123u16,13613u16),(29134u16,12294u16), (29140u16,20485u16),(29141u16,15359u16),(29152u16,20484u16),(29157u16,15944u16), (29159u16,20486u16),(29166u16,17233u16),(29177u16,20487u16),(29190u16,9227u16), (29213u16,20488u16),(29224u16,20489u16),(29226u16,16441u16),(29228u16,13047u16), (29232u16,20263u16),(29233u16,9039u16),(29237u16,11769u16),(29238u16,10569u16), (29239u16,15500u16),(29240u16,9079u16),(29241u16,10064u16),(29243u16,16644u16), (29245u16,14167u16),(29247u16,18776u16),(29255u16,13217u16),(29256u16,9095u16), (29260u16,13053u16),(29261u16,20260u16),(29266u16,20261u16),(29270u16,20262u16), (29273u16,15327u16),(29275u16,13018u16),(29277u16,20127u16),(29279u16,12843u16), (29281u16,12846u16),(29282u16,12111u16),(29286u16,20128u16),(29287u16,12858u16), (29289u16,14804u16),(29294u16,20125u16),(29295u16,20129u16),(29298u16,13867u16), (29301u16,13398u16),(29305u16,14401u16),(29306u16,14819u16),(29310u16,20130u16), (29311u16,20131u16),(29312u16,14927u16),(29313u16,12136u16),(29316u16,20132u16), (29322u16,10196u16),(29323u16,20133u16),(29325u16,20134u16),(29327u16,20135u16), (29330u16,20136u16),(29343u16,20126u16),(29356u16,13599u16),(29357u16,18410u16), (29359u16,10379u16),(29360u16,18411u16),(29364u16,18412u16),(29366u16,16455u16), (29367u16,18413u16),(29368u16,18414u16),(29369u16,15719u16),(29377u16,18416u16), (29378u16,11956u16),(29379u16,18415u16),(29380u16,10025u16),(29384u16,9238u16), (29389u16,18418u16),(29390u16,18417u16),(29392u16,11017u16),(29394u16,18419u16), (29399u16,10758u16),(29401u16,11734u16),(29406u16,12917u16),(29408u16,10986u16), (29409u16,11533u16),(29416u16,18420u16),(29417u16,18422u16),(29420u16,10197u16), (29421u16,14948u16),(29422u16,13973u16),(29423u16,18421u16),(29424u16,16143u16), (29425u16,15767u16),(29426u16,18423u16),(29427u16,18427u16),(29428u16,18424u16), (29431u16,18425u16),(29432u16,12139u16),(29434u16,18429u16),(29435u16,18526u16), (29436u16,12104u16),(29441u16,18426u16),(29443u16,18428u16),(29450u16,18530u16), (29454u16,12307u16),(29459u16,18528u16),(29461u16,18533u16),(29462u16,9499u16), (29463u16,18527u16),(29467u16,12680u16),(29468u16,9439u16),(29469u16,18532u16), (29470u16,18531u16),(29473u16,18529u16),(29474u16,18534u16),(29477u16,18536u16), (29481u16,15146u16),(29482u16,16322u16),(29483u16,12643u16),(29484u16,18537u16), (29486u16,14970u16),(29489u16,18539u16),(29492u16,11004u16),(29495u16,19919u16), (29496u16,18538u16),(29497u16,18535u16),(29502u16,11126u16),(29503u16,15884u16), (29517u16,18541u16),(29520u16,18540u16),(29522u16,19920u16),(29527u16,18542u16), (29536u16,18543u16),(29548u16,18544u16),(29549u16,14346u16),(29551u16,18545u16), (29566u16,18546u16),(29572u16,15199u16),(29575u16,12487u16),(29577u16,15756u16), (29579u16,14620u16),(29582u16,19539u16),(29585u16,19540u16),(29590u16,11718u16), (29595u16,12519u16),(29599u16,19543u16),(29602u16,19542u16),(29609u16,14605u16), (29611u16,12656u16),(29614u16,19541u16),(29615u16,11138u16),(29616u16,14969u16), (29618u16,12320u16),(29619u16,19548u16),(29623u16,19547u16),(29626u16,19559u16), (29627u16,9408u16),(29632u16,19549u16),(29634u16,19545u16),(29640u16,19551u16), (29641u16,19550u16),(29642u16,13801u16),(29645u16,16123u16),(29647u16,19544u16), (29648u16,10364u16),(29649u16,19546u16),(29657u16,19553u16),(29662u16,19558u16), (29664u16,16318u16),(29669u16,19552u16),(29671u16,19557u16),(29673u16,19556u16), (29677u16,9089u16),(29682u16,19560u16),(29699u16,13477u16),(29701u16,12102u16), (29702u16,12142u16),(29705u16,12335u16),(29706u16,19555u16),(29711u16,19561u16), (29712u16,14241u16),(29722u16,19667u16),(29723u16,19666u16),(29730u16,16468u16), (29733u16,19565u16),(29734u16,19564u16),(29736u16,19566u16),(29738u16,19562u16), (29740u16,19569u16),(29742u16,19568u16),(29744u16,19567u16),(29747u16,12308u16), (29748u16,13452u16),(29749u16,13108u16),(29750u16,13050u16),(29756u16,13472u16), (29761u16,19668u16),(29781u16,19671u16),(29783u16,19670u16),(29785u16,19672u16), (29786u16,11012u16),(29787u16,19563u16),(29788u16,19669u16),(29790u16,13665u16), (29791u16,13785u16),(29805u16,19674u16),(29808u16,10804u16),(29814u16,15389u16), (29815u16,19673u16),(29822u16,19675u16),(29824u16,19678u16),(29825u16,19679u16), (29827u16,12262u16),(29831u16,19680u16),(29835u16,19681u16),(29838u16,19677u16), (29840u16,19685u16),(29852u16,19676u16),(29854u16,19682u16),(29863u16,19686u16), (29864u16,19683u16),(29865u16,19684u16),(29882u16,19688u16),(29906u16,19687u16), (29916u16,10782u16),(29918u16,21197u16),(29920u16,21198u16),(29922u16,13221u16), (29923u16,9099u16),(29924u16,13616u16),(29926u16,14598u16),(29934u16,14770u16), (29935u16,20062u16),(29940u16,20063u16),(29942u16,13236u16),(29943u16,9826u16), (29951u16,20064u16),(29956u16,16126u16),(29965u16,17664u16),(29967u16,20065u16), (29969u16,20066u16),(29971u16,20067u16),(29976u16,10587u16),(29977u16,17971u16), (29978u16,13860u16),(29980u16,14425u16),(29983u16,13865u16),(29989u16,13866u16), (29992u16,15710u16),(29993u16,14161u16),(29995u16,10551u16),(29996u16,21199u16), (29997u16,9249u16),(29999u16,19119u16),(30000u16,14424u16),(30001u16,15716u16), (30002u16,11360u16),(30003u16,13849u16),(30005u16,10046u16),(30007u16,12873u16), (30008u16,10048u16),(30010u16,20819u16),(30011u16,11128u16),(30014u16,19537u16), (30016u16,20820u16),(30021u16,9604u16),(30024u16,20823u16),(30027u16,20822u16), (30028u16,11566u16),(30030u16,20821u16),(30031u16,14748u16),(30036u16,13062u16), (30041u16,12339u16),(30042u16,17241u16),(30043u16,20824u16),(30044u16,15188u16), (30053u16,12497u16),(30054u16,13277u16),(30058u16,10367u16),(30066u16,20825u16), (30068u16,9670u16),(30072u16,11206u16),(30073u16,20826u16),(30079u16,19535u16), (30083u16,20827u16),(30086u16,11509u16),(30091u16,21441u16),(30095u16,14037u16), (30097u16,15526u16),(30098u16,21243u16),(30100u16,21244u16),(30102u16,21245u16), (30103u16,12293u16),(30105u16,10622u16),(30106u16,11731u16),(30109u16,21247u16), (30111u16,13032u16),(30112u16,21246u16),(30113u16,15376u16),(30115u16,21249u16), (30116u16,9069u16),(30117u16,11569u16),(30123u16,15548u16),(30124u16,21248u16), (30126u16,9800u16),(30127u16,10427u16),(30128u16,21255u16),(30129u16,21254u16), (30130u16,13208u16),(30131u16,21250u16),(30132u16,21251u16),(30133u16,9820u16), (30136u16,21252u16),(30137u16,16133u16),(30140u16,14404u16),(30141u16,11735u16), (30142u16,11323u16),(30146u16,21257u16),(30147u16,21256u16),(30148u16,21253u16), (30149u16,9406u16),(30151u16,16247u16),(30152u16,15699u16),(30153u16,11708u16), (30154u16,13597u16),(30157u16,21259u16),(30162u16,15382u16),(30164u16,16289u16), (30165u16,10984u16),(30166u16,21258u16),(30168u16,10192u16),(30171u16,14555u16), (30174u16,13211u16),(30178u16,12256u16),(30179u16,21260u16),(30180u16,21263u16), (30182u16,21262u16),(30183u16,21265u16),(30184u16,21261u16),(30186u16,11145u16), (30187u16,21264u16),(30192u16,14366u16),(30193u16,21267u16),(30196u16,9648u16), (30201u16,9267u16),(30204u16,21268u16),(30207u16,21269u16),(30208u16,21271u16), (30209u16,9850u16),(30211u16,21266u16),(30213u16,21272u16),(30218u16,21275u16), (30220u16,21273u16),(30224u16,21270u16),(30229u16,21278u16),(30231u16,21274u16), (30232u16,21277u16),(30233u16,21279u16),(30235u16,21376u16),(30239u16,14758u16), (30240u16,21379u16),(30242u16,21378u16),(30244u16,12341u16),(30245u16,21276u16), (30246u16,14026u16),(30249u16,9866u16),(30250u16,9296u16),(30251u16,14362u16), (30253u16,21381u16),(30256u16,21382u16),(30259u16,21387u16),(30260u16,16101u16), (30261u16,21384u16),(30264u16,13604u16),(30268u16,21377u16),(30270u16,21386u16), (30271u16,21383u16),(30272u16,21380u16),(30275u16,21385u16),(30284u16,9034u16), (30285u16,21388u16),(30292u16,21390u16),(30294u16,21392u16),(30300u16,21391u16), (30302u16,21389u16),(30307u16,15297u16),(30315u16,21393u16),(30319u16,21394u16), (30328u16,10814u16),(30331u16,10014u16),(30333u16,9080u16),(30334u16,9082u16), (30338u16,15942u16),(30340u16,10011u16),(30342u16,11547u16),(30343u16,11157u16), (30344u16,21192u16),(30347u16,10607u16),(30350u16,21193u16),(30353u16,9033u16), (30355u16,21194u16),(30358u16,14613u16),(30361u16,21195u16),(30372u16,21196u16), (30382u16,13209u16),(30385u16,16314u16),(30386u16,21443u16),(30388u16,21444u16), (30399u16,12718u16),(30402u16,15734u16),(30405u16,16294u16),(30406u16,13087u16), (30408u16,15690u16),(30410u16,15555u16),(30413u16,20838u16),(30414u16,9052u16), (30415u16,16076u16),(30416u16,15341u16),(30417u16,11369u16),(30418u16,10973u16), (30420u16,11963u16),(30422u16,10584u16),(30423u16,10008u16),(30424u16,13059u16), (30427u16,13967u16),(30431u16,12678u16),(30437u16,20839u16),(30446u16,12856u16), (30447u16,10167u16),(30449u16,20691u16),(30450u16,12639u16),(30452u16,16262u16), (30456u16,14979u16),(30457u16,20694u16),(30460u16,13061u16),(30462u16,10225u16), (30465u16,13966u16),(30468u16,20692u16),(30471u16,20695u16),(30472u16,20696u16), (30473u16,12663u16),(30475u16,11895u16),(30477u16,20693u16),(30489u16,20699u16), (30490u16,20697u16),(30495u16,16125u16),(30496u16,12698u16),(30498u16,20698u16), (30502u16,20701u16),(30504u16,16058u16),(30505u16,15298u16),(30509u16,20700u16), (30511u16,12683u16),(30517u16,20702u16),(30518u16,11959u16),(30519u16,11761u16), (30520u16,20703u16),(30522u16,14432u16),(30524u16,15354u16),(30528u16,16472u16), (30529u16,16141u16),(30531u16,20707u16),(30535u16,20706u16),(30544u16,20704u16), (30545u16,20705u16),(30554u16,20708u16),(30555u16,11691u16),(30561u16,14170u16), (30562u16,20806u16),(30563u16,10194u16),(30565u16,20807u16),(30566u16,12857u16), (30568u16,20709u16),(30571u16,11557u16),(30572u16,9444u16),(30585u16,10200u16), (30589u16,20810u16),(30590u16,16651u16),(30591u16,20808u16),(30592u16,20811u16), (30596u16,12708u16),(30597u16,9677u16),(30604u16,20812u16),(30605u16,20809u16), (30606u16,14940u16),(30609u16,20813u16),(30610u16,12532u16),(30623u16,20814u16), (30624u16,20815u16),(30626u16,17776u16),(30629u16,13224u16),(30631u16,13433u16), (30633u16,16330u16),(30634u16,10016u16),(30636u16,14173u16),(30640u16,20816u16), (30643u16,14546u16),(30645u16,20817u16),(30651u16,16071u16),(30653u16,20818u16), (30655u16,22361u16),(30669u16,17234u16),(30679u16,9788u16),(30683u16,12647u16), (30684u16,21445u16),(30690u16,13989u16),(30691u16,15536u16),(30693u16,16255u16), (30695u16,21077u16),(30697u16,11741u16),(30699u16,11530u16),(30700u16,21078u16), (30701u16,10209u16),(30702u16,9036u16),(30707u16,13980u16),(30710u16,20637u16), (30712u16,20638u16),(30717u16,14814u16),(30718u16,10370u16),(30719u16,11958u16), (30720u16,20639u16),(30721u16,12520u16),(30722u16,13791u16),(30729u16,20640u16), (30732u16,13291u16),(30733u16,11894u16),(30737u16,20643u16),(30738u16,13103u16), (30740u16,15343u16),(30742u16,16444u16),(30743u16,20641u16),(30744u16,20642u16), (30746u16,15361u16),(30748u16,20646u16),(30749u16,20647u16),(30751u16,20651u16), (30755u16,20655u16),(30757u16,20653u16),(30758u16,20661u16),(30759u16,16127u16), (30761u16,20656u16),(30764u16,20654u16),(30765u16,20645u16),(30768u16,13088u16), (30772u16,13243u16),(30775u16,13848u16),(30776u16,15915u16),(30777u16,20648u16), (30778u16,20649u16),(30779u16,20650u16),(30780u16,20652u16),(30782u16,12154u16), (30784u16,9786u16),(30789u16,10807u16),(30791u16,20663u16),(30796u16,20664u16), (30798u16,20657u16),(30800u16,20662u16),(30802u16,14813u16),(30805u16,14177u16), (30806u16,20659u16),(30807u16,20660u16),(30813u16,15000u16),(30826u16,20665u16), (30827u16,12337u16),(30828u16,15693u16),(30829u16,20658u16),(30830u16,13608u16), (30839u16,11384u16),(30844u16,13095u16),(30855u16,20669u16),(30857u16,10054u16), (30860u16,12466u16),(30861u16,9038u16),(30862u16,14228u16),(30865u16,9229u16), (30867u16,20667u16),(30871u16,14610u16),(30872u16,10041u16),(30874u16,20668u16), (30875u16,20666u16),(30876u16,20670u16),(30879u16,10065u16),(30881u16,20671u16), (30883u16,20672u16),(30885u16,20675u16),(30887u16,9259u16),(30896u16,13101u16), (30897u16,11383u16),(30898u16,20673u16),(30899u16,14373u16),(30900u16,9479u16), (30905u16,20674u16),(30910u16,12900u16),(30913u16,9822u16),(30917u16,9110u16), (30921u16,20678u16),(30922u16,12123u16),(30923u16,9857u16),(30928u16,13060u16), (30932u16,20676u16),(30933u16,11911u16),(30937u16,20677u16),(30952u16,12830u16), (30956u16,20679u16),(30962u16,20680u16),(30964u16,20682u16),(30967u16,12310u16), (30970u16,11154u16),(30977u16,11519u16),(30981u16,20681u16),(30995u16,20683u16), (31006u16,20685u16),(31012u16,20684u16),(31028u16,20686u16),(31034u16,13995u16), (31035u16,20499u16),(31036u16,12146u16),(31038u16,13846u16),(31040u16,20500u16), (31041u16,13283u16),(31046u16,20501u16),(31048u16,13282u16),(31049u16,20502u16), (31059u16,20505u16),(31062u16,16505u16),(31063u16,20508u16),(31066u16,20506u16), (31067u16,20503u16),(31068u16,20504u16),(31069u16,16438u16),(31070u16,13856u16), (31071u16,14233u16),(31072u16,20509u16),(31074u16,20507u16),(31077u16,14988u16), (31079u16,20511u16),(31080u16,13222u16),(31085u16,11337u16),(31087u16,20510u16), (31095u16,10002u16),(31096u16,11201u16),(31098u16,20512u16),(31104u16,16902u16), (31105u16,11586u16),(31108u16,12472u16),(31109u16,20513u16),(31114u16,20514u16), (31119u16,10548u16),(31130u16,20515u16),(31143u16,20516u16),(31155u16,20517u16), (31161u16,15752u16),(31162u16,16639u16),(31163u16,12140u16),(31165u16,13456u16), (31166u16,10969u16),(31168u16,15172u16),(31169u16,14184u16),(31171u16,14561u16), (31174u16,10594u16),(31177u16,9307u16),(31179u16,13474u16),(31181u16,16299u16), (31185u16,11913u16),(31186u16,12710u16),(31189u16,21080u16),(31192u16,12691u16), (31199u16,16501u16),(31203u16,21082u16),(31204u16,9646u16),(31206u16,13451u16), (31207u16,15372u16),(31209u16,16285u16),(31211u16,21083u16),(31213u16,21081u16), (31215u16,11208u16),(31216u16,9633u16),(31224u16,11548u16),(31227u16,15523u16), (31229u16,11179u16),(31232u16,14916u16),(31234u16,21087u16),(31235u16,21086u16), (31238u16,21084u16),(31243u16,9639u16),(31245u16,13827u16),(31246u16,14171u16), (31252u16,21089u16),(31255u16,9087u16),(31258u16,16286u16),(31262u16,21088u16), (31264u16,9672u16),(31267u16,22378u16),(31283u16,14765u16),(31287u16,21187u16), (31289u16,21186u16),(31291u16,10005u16),(31292u16,11363u16),(31293u16,11207u16), (31295u16,10614u16),(31302u16,12859u16),(31313u16,21188u16),(31319u16,14230u16), (31344u16,21191u16),(31348u16,15303u16),(31350u16,11716u16),(31351u16,13473u16), (31352u16,21397u16),(31353u16,21398u16),(31354u16,11928u16),(31359u16,9794u16), (31360u16,21399u16),(31361u16,14562u16),(31363u16,13447u16),(31364u16,16068u16), (31366u16,21400u16),(31368u16,21401u16),(31373u16,13442u16),(31377u16,15489u16), (31378u16,16292u16),(31381u16,21402u16),(31382u16,11544u16),(31383u16,9801u16), (31384u16,11714u16),(31388u16,9845u16),(31389u16,14774u16),(31391u16,11938u16), (31392u16,21404u16),(31397u16,11965u16),(31398u16,21403u16),(31400u16,21406u16), (31404u16,21405u16),(31405u16,21407u16),(31411u16,21408u16),(31423u16,12349u16), (31435u16,12257u16),(31446u16,14055u16),(31449u16,16085u16),(31454u16,11711u16), (31455u16,11710u16),(31456u16,16089u16),(31459u16,11877u16),(31461u16,14550u16), (31462u16,21396u16),(31469u16,11558u16),(31471u16,10208u16),(31481u16,16326u16), (31482u16,21790u16),(31485u16,21791u16),(31487u16,10590u16),(31491u16,21793u16), (31492u16,21794u16),(31494u16,9067u16),(31496u16,21792u16),(31498u16,21796u16), (31499u16,14236u16),(31503u16,21798u16),(31505u16,15111u16),(31508u16,9257u16), (31509u16,21795u16),(31513u16,21802u16),(31515u16,10024u16),(31518u16,21810u16), (31520u16,21805u16),(31524u16,21807u16),(31525u16,21806u16),(31526u16,10446u16), (31528u16,9246u16),(31530u16,21801u16),(31531u16,21797u16),(31532u16,10033u16), (31534u16,21803u16),(31537u16,21804u16),(31539u16,21808u16),(31544u16,21800u16), (31546u16,11372u16),(31548u16,12348u16),(31550u16,21809u16),(31557u16,21813u16), (31559u16,21799u16),(31561u16,10015u16),(31563u16,11573u16),(31564u16,21815u16), (31567u16,10359u16),(31568u16,11955u16),(31569u16,16339u16),(31570u16,14553u16), (31572u16,9865u16),(31574u16,9468u16),(31576u16,21811u16),(31578u16,21812u16), (31579u16,13799u16),(31581u16,21816u16),(31584u16,21817u16),(31586u16,21820u16), (31598u16,21818u16),(31601u16,21822u16),(31602u16,21821u16),(31605u16,21814u16), (31607u16,11949u16),(31609u16,9674u16),(31611u16,21819u16),(31614u16,13404u16), (31616u16,11387u16),(31621u16,21830u16),(31629u16,10766u16),(31632u16,21823u16), (31636u16,9418u16),(31637u16,11209u16),(31639u16,14222u16),(31644u16,21832u16), (31645u16,21828u16),(31649u16,10795u16),(31650u16,21833u16),(31654u16,21824u16), (31655u16,21825u16),(31656u16,21829u16),(31657u16,12510u16),(31658u16,21831u16), (31659u16,21834u16),(31660u16,21827u16),(31661u16,11398u16),(31665u16,14983u16), (31668u16,21835u16),(31672u16,21826u16),(31681u16,21837u16),(31686u16,16448u16), (31687u16,13215u16),(31692u16,21838u16),(31697u16,21836u16),(31699u16,12453u16), (31705u16,10606u16),(31706u16,21840u16),(31709u16,21839u16),(31713u16,9844u16), (31717u16,21841u16),(31718u16,21842u16),(31722u16,21843u16),(31726u16,12091u16), (31729u16,12138u16),(31735u16,13096u16),(31740u16,21846u16),(31742u16,21845u16), (31751u16,9841u16),(31755u16,21849u16),(31756u16,21844u16),(31759u16,21847u16), (31766u16,21848u16),(31775u16,21946u16),(31782u16,21948u16),(31783u16,11156u16), (31786u16,21947u16),(31800u16,21949u16),(31807u16,9435u16),(31808u16,21951u16), (31809u16,21950u16),(31821u16,11319u16),(31859u16,12690u16),(31860u16,16880u16), (31867u16,12129u16),(31868u16,21989u16),(31869u16,16484u16),(31881u16,10414u16), (31889u16,21991u16),(31890u16,12258u16),(31893u16,13246u16),(31895u16,9839u16), (31896u16,16074u16),(31900u16,21993u16),(31901u16,21992u16),(31902u16,21994u16), (31903u16,14213u16),(31906u16,21995u16),(31908u16,15898u16),(31909u16,16309u16), (31914u16,10419u16),(31918u16,12279u16),(31921u16,12282u16),(31922u16,21996u16), (31923u16,11697u16),(31929u16,9851u16),(31932u16,21997u16),(31933u16,21998u16), (31934u16,11696u16),(31937u16,21999u16),(31941u16,22004u16),(31943u16,22000u16), (31944u16,22003u16),(31946u16,11018u16),(31948u16,22001u16),(31949u16,22002u16), (31957u16,10611u16),(31958u16,14384u16),(31959u16,22005u16),(31961u16,9463u16), (31964u16,12686u16),(31967u16,15932u16),(31968u16,11898u16),(31976u16,22006u16), (31983u16,13035u16),(31992u16,22018u16),(31995u16,14936u16),(32010u16,14766u16), (32032u16,14211u16),(32034u16,14242u16),(32039u16,11579u16),(32043u16,16482u16), (32047u16,12124u16),(32110u16,15190u16),(32119u16,22019u16),(32166u16,22020u16), (32174u16,22021u16),(32315u16,22582u16),(32321u16,10372u16),(32327u16,22022u16), (32386u16,16510u16),(32411u16,22023u16),(32415u16,19374u16),(32416u16,11717u16), (32417u16,19375u16),(32418u16,11001u16),(32419u16,19376u16),(32420u16,14958u16), (32421u16,19377u16),(32422u16,15893u16),(32423u16,11327u16),(32424u16,19378u16), (32425u16,19379u16),(32426u16,11350u16),(32427u16,13635u16),(32428u16,14744u16), (32429u16,19476u16),(32431u16,9816u16),(32432u16,19477u16),(32433u16,13795u16), (32434u16,10602u16),(32435u16,12866u16),(32437u16,16496u16),(32438u16,12503u16), (32439u16,10410u16),(32440u16,16274u16),(32441u16,14763u16),(32442u16,10391u16), (32445u16,13021u16),(32446u16,19478u16),(32447u16,14978u16),(32448u16,19479u16), (32449u16,19480u16),(32450u16,19481u16),(32451u16,12278u16),(32452u16,16508u16), (32453u16,13855u16),(32454u16,14939u16),(32455u16,16260u16),(32456u16,16298u16), (32457u16,19482u16),(32458u16,9102u16),(32459u16,19483u16),(32460u16,19484u16), (32461u16,13835u16),(32462u16,15564u16),(32463u16,11698u16),(32464u16,19485u16), (32465u16,9108u16),(32466u16,13647u16),(32467u16,11560u16),(32468u16,19486u16), (32469u16,13623u16),(32471u16,19487u16),(32472u16,11185u16),(32473u16,10633u16), (32474u16,15299u16),(32475u16,19488u16),(32476u16,12516u16),(32477u16,11773u16), (32478u16,11537u16),(32479u16,14554u16),(32480u16,19489u16),(32481u16,19490u16), (32482u16,11763u16),(32483u16,15174u16),(32485u16,14226u16),(32486u16,14393u16), (32487u16,11349u16),(32488u16,19491u16),(32489u16,11313u16),(32490u16,15192u16), (32491u16,19492u16),(32493u16,15193u16),(32494u16,19493u16),(32495u16,19494u16), (32496u16,9819u16),(32497u16,19495u16),(32498u16,19496u16),(32499u16,13869u16), (32500u16,14737u16),(32501u16,12699u16),(32502u16,19498u16),(32503u16,9248u16), (32504u16,9676u16),(32506u16,19499u16),(32507u16,19500u16),(32508u16,16494u16), (32509u16,16087u16),(32510u16,19501u16),(32511u16,12489u16),(32512u16,16461u16), (32513u16,19502u16),(32514u16,19503u16),(32515u16,19504u16),(32516u16,11379u16), (32517u16,12704u16),(32518u16,12099u16),(32519u16,19505u16),(32520u16,19506u16), (32521u16,11314u16),(32523u16,19507u16),(32524u16,19508u16),(32525u16,19497u16), (32526u16,10213u16),(32527u16,19509u16),(32529u16,19510u16),(32530u16,19511u16), (32531u16,11141u16),(32532u16,10037u16),(32533u16,12483u16),(32534u16,9279u16), (32535u16,19512u16),(32536u16,15886u16),(32537u16,19513u16),(32538u16,10576u16), (32539u16,19515u16),(32540u16,19514u16),(32541u16,10431u16),(32543u16,19516u16), (32544u16,9493u16),(32545u16,19517u16),(32546u16,19518u16),(32547u16,19519u16), (32548u16,19520u16),(32549u16,19521u16),(32550u16,19522u16),(32551u16,19523u16), (32552u16,15682u16),(32553u16,14240u16),(32554u16,19524u16),(32555u16,19525u16), (32556u16,19526u16),(32557u16,19527u16),(32558u16,13816u16),(32559u16,19528u16), (32560u16,19529u16),(32561u16,19530u16),(32562u16,19531u16),(32563u16,19532u16), (32564u16,11536u16),(32565u16,19533u16),(32566u16,21785u16),(32568u16,10600u16), (32570u16,13602u16),(32578u16,21786u16),(32580u16,21787u16),(32581u16,21788u16), (32592u16,10797u16),(32593u16,14623u16),(32596u16,16697u16),(32597u16,10942u16), (32599u16,12507u16),(32600u16,20828u16),(32602u16,10358u16),(32607u16,20830u16), (32609u16,20829u16),(32610u16,9078u16),(32616u16,20832u16),(32617u16,16109u16), (32618u16,16514u16),(32622u16,16280u16),(32625u16,20834u16),(32626u16,14045u16), (32628u16,20833u16),(32633u16,20835u16),(32638u16,20837u16),(32641u16,20836u16), (32650u16,15377u16),(32652u16,13423u16),(32654u16,12667u16),(32660u16,10610u16), (32666u16,12326u16),(32669u16,21983u16),(32670u16,15168u16),(32671u16,21984u16), (32673u16,14974u16),(32676u16,13611u16),(32679u16,21985u16),(32687u16,21986u16), (32688u16,21987u16),(32690u16,21988u16),(32696u16,16905u16),(32697u16,10639u16), (32700u16,19176u16),(32701u16,15755u16),(32703u16,22009u16),(32705u16,14769u16), (32709u16,9660u16),(32714u16,21395u16),(32716u16,15563u16),(32718u16,22010u16), (32724u16,14987u16),(32725u16,22011u16),(32728u16,13439u16),(32735u16,10027u16), (32736u16,9853u16),(32737u16,22013u16),(32741u16,22012u16),(32742u16,22014u16), (32745u16,22015u16),(32750u16,22016u16),(32752u16,10943u16),(32753u16,9056u16), (32755u16,22017u16),(32763u16,10368u16),(32764u16,15562u16),(32768u16,15496u16), (32769u16,12112u16),(32771u16,11903u16),(32772u16,20238u16),(32773u16,16118u16), (32774u16,20085u16),(32779u16,21458u16),(32780u16,10253u16),(32781u16,14158u16), (32784u16,12870u16),(32786u16,21446u16),(32788u16,21447u16),(32789u16,10636u16), (32790u16,21448u16),(32791u16,10961u16),(32792u16,15902u16),(32793u16,9075u16), (32796u16,21449u16),(32800u16,21450u16),(32802u16,21451u16),(32805u16,21452u16), (32806u16,21453u16),(32807u16,21454u16),(32808u16,21456u16),(32809u16,21455u16), (32810u16,13068u16),(32817u16,21457u16),(32819u16,10255u16),(32821u16,21459u16), (32822u16,15499u16),(32823u16,17804u16),(32824u16,14197u16),(32827u16,9655u16), (32829u16,9977u16),(32831u16,10737u16),(32834u16,12909u16),(32835u16,21460u16), (32838u16,21461u16),(32842u16,12291u16),(32843u16,12346u16),(32844u16,16261u16), (32845u16,21462u16),(32850u16,21463u16),(32852u16,12265u16),(32856u16,13229u16), (32858u16,11744u16),(32873u16,21464u16),(32874u16,9832u16),(32881u16,21465u16), (32895u16,20633u16),(32896u16,20632u16),(32899u16,14219u16),(32900u16,15547u16), (32902u16,14188u16),(32903u16,16111u16),(32905u16,13651u16),(32907u16,12128u16), (32908u16,11306u16),(32915u16,20268u16),(32918u16,15109u16),(32920u16,16311u16), (32922u16,10204u16),(32923u16,10601u16),(32924u16,20267u16),(32925u16,10591u16), (32927u16,20266u16),(32928u16,9601u16),(32929u16,10776u16),(32930u16,16256u16), (32932u16,10439u16),(32933u16,10397u16),(32937u16,11376u16),(32938u16,10385u16), (32939u16,20273u16),(32941u16,20274u16),(32942u16,9050u16),(32943u16,11922u16), (32945u16,20272u16),(32946u16,15768u16),(32948u16,20275u16),(32951u16,20276u16), (32954u16,10401u16),(32956u16,20269u16),(32957u16,20271u16),(32958u16,13861u16), (32959u16,16300u16),(32960u16,16100u16),(32961u16,15123u16),(32962u16,20282u16), (32963u16,14749u16),(32964u16,20283u16),(32966u16,9983u16),(32972u16,9234u16), (32973u16,20285u16),(32974u16,14350u16),(32982u16,13069u16),(32983u16,20286u16), (32985u16,20284u16),(32986u16,13078u16),(32987u16,20281u16),(32988u16,13969u16), (32989u16,20288u16),(32990u16,9116u16),(32993u16,11015u16),(32996u16,16648u16), (32997u16,21442u16),(32999u16,20277u16),(33000u16,20278u16),(33001u16,20279u16), (33002u16,20280u16),(33003u16,20289u16),(33004u16,19317u16),(33005u16,20292u16), (33007u16,11947u16),(33008u16,15525u16),(33009u16,20290u16),(33010u16,20295u16), (33011u16,10621u16),(33012u16,20291u16),(33014u16,11521u16),(33016u16,15161u16), (33018u16,9048u16),(33020u16,20296u16),(33021u16,12885u16),(33026u16,16257u16), (33030u16,9849u16),(33033u16,12531u16),(33034u16,11330u16),(33037u16,20293u16), (33038u16,20294u16),(33039u16,15929u16),(33040u16,13279u16),(33041u16,12877u16), (33042u16,20298u16),(33043u16,13022u16),(33044u16,16900u16),(33046u16,9422u16), (33048u16,20303u16),(33050u16,11532u16),(33054u16,20301u16),(33068u16,20302u16), (33071u16,10557u16),(33073u16,14584u16),(33074u16,20304u16),(33078u16,20300u16), (33080u16,12274u16),(33086u16,13207u16),(33094u16,14428u16),(33096u16,20305u16), (33098u16,12081u16),(33099u16,15509u16),(33100u16,20306u16),(33104u16,10560u16), (33105u16,10558u16),(33107u16,20307u16),(33108u16,13422u16),(33109u16,14618u16), (33113u16,20309u16),(33114u16,20310u16),(33120u16,20312u16),(33125u16,15145u16), (33127u16,20317u16),(33129u16,20313u16),(33133u16,20316u16),(33134u16,13674u16), (33136u16,15387u16),(33137u16,20311u16),(33140u16,20308u16),(33145u16,10570u16), (33146u16,14972u16),(33147u16,12894u16),(33148u16,20314u16),(33149u16,20315u16), (33150u16,14403u16),(33151u16,14575u16),(33152u16,9107u16),(33154u16,20321u16), (33160u16,20320u16),(33162u16,9423u16),(33167u16,10609u16),(33169u16,20322u16), (33176u16,9291u16),(33179u16,14382u16),(33180u16,12829u16),(33181u16,14920u16), (33187u16,20324u16),(33190u16,20427u16),(33192u16,13097u16),(33194u16,20325u16), (33203u16,13812u16),(33210u16,18588u16),(33211u16,20329u16),(33216u16,14581u16), (33217u16,20426u16),(33218u16,9274u16),(33219u16,15698u16),(33222u16,15545u16), (33226u16,20328u16),(33228u16,20326u16),(33251u16,9623u16),(33255u16,20061u16), (33258u16,16487u16),(33260u16,21956u16),(33261u16,9679u16),(33267u16,16278u16), (33268u16,16279u16),(33275u16,16128u16),(33276u16,11727u16),(33278u16,21952u16), (33280u16,15493u16),(33281u16,21953u16),(33282u16,21954u16),(33284u16,21955u16), (33285u16,11728u16),(33286u16,15738u16),(33292u16,13839u16),(33293u16,13840u16), (33296u16,21789u16),(33298u16,14035u16),(33300u16,14427u16),(33307u16,18547u16), (33308u16,14175u16),(33310u16,14797u16),(33311u16,16304u16),(33313u16,21958u16), (33314u16,21959u16),(33315u16,21960u16),(33320u16,21963u16),(33322u16,10954u16), (33323u16,21964u16),(33324u16,9092u16),(33325u16,21961u16),(33327u16,21962u16), (33328u16,11497u16),(33329u16,9458u16),(33331u16,21967u16),(33332u16,21968u16), (33333u16,10235u16),(33334u16,9421u16),(33335u16,14962u16),(33336u16,21965u16), (33337u16,9797u16),(33339u16,21966u16),(33342u16,21969u16),(33348u16,21970u16), (33351u16,14542u16),(33353u16,21971u16),(33355u16,21972u16),(33359u16,21973u16), (33368u16,14205u16),(33370u16,21974u16),(33375u16,21975u16),(33384u16,21976u16), (33390u16,22007u16),(33391u16,12283u16),(33392u16,11377u16),(33394u16,13786u16), (33395u16,15357u16),(33396u16,19180u16),(33401u16,17404u16),(33402u16,15538u16), (33405u16,17405u16),(33406u16,9037u16),(33407u16,17406u16),(33410u16,11553u16), (33412u16,17410u16),(33416u16,16659u16),(33418u16,17408u16),(33419u16,15758u16), (33421u16,13829u16),(33422u16,17411u16),(33423u16,17407u16),(33425u16,17412u16), (33426u16,12637u16),(33431u16,17413u16),(33432u16,17422u16),(33433u16,17414u16), (33436u16,14788u16),(33437u16,16250u16),(33439u16,17432u16),(33441u16,17430u16), (33444u16,17435u16),(33445u16,11565u16),(33446u16,12456u16),(33448u16,17409u16), (33449u16,17428u16),(33450u16,17431u16),(33451u16,17415u16),(33452u16,10405u16), (33453u16,9062u16),(33454u16,17424u16),(33455u16,15135u16),(33456u16,17418u16), (33457u16,11123u16),(33459u16,10383u16),(33460u16,17429u16),(33463u16,17423u16), (33464u16,17416u16),(33465u16,13454u16),(33469u16,15326u16),(33470u16,17417u16), (33473u16,17427u16),(33476u16,17433u16),(33479u16,14738u16),(33480u16,17419u16), (33482u16,17420u16),(33483u16,17425u16),(33484u16,17426u16),(33485u16,9457u16), (33486u16,17434u16),(33487u16,14208u16),(33489u16,15888u16),(33490u16,17444u16), (33491u16,17448u16),(33492u16,14351u16),(33493u16,17455u16),(33495u16,12706u16), (33496u16,17445u16),(33499u16,11908u16),(33500u16,17442u16),(33502u16,9115u16), (33503u16,10757u16),(33504u16,17454u16),(33505u16,17436u16),(33507u16,17421u16), (33508u16,17439u16),(33509u16,13669u16),(33510u16,11939u16),(33515u16,13802u16), (33519u16,9244u16),(33521u16,15677u16),(33524u16,17443u16),(33527u16,17438u16), (33529u16,13232u16),(33531u16,17447u16),(33537u16,16469u16),(33538u16,12650u16), (33539u16,10377u16),(33540u16,13444u16),(33541u16,12644u16),(33542u16,17451u16), (33543u16,17441u16),(33544u16,17460u16),(33545u16,17437u16),(33548u16,17446u16), (33550u16,11690u16),(33551u16,17440u16),(33553u16,17449u16),(33556u16,17452u16), (33557u16,17453u16),(33559u16,17473u16),(33562u16,17450u16),(33563u16,17577u16), (33564u16,17456u16),(33575u16,11380u16),(33576u16,9821u16),(33579u16,12638u16), (33580u16,9476u16),(33581u16,17475u16),(33583u16,17467u16),(33585u16,17464u16), (33587u16,17477u16),(33588u16,17463u16),(33589u16,15565u16),(33590u16,9477u16), (33592u16,13640u16),(33593u16,13652u16),(33594u16,17476u16),(33596u16,17462u16), (33600u16,17472u16),(33603u16,17470u16),(33606u16,11688u16),(33607u16,17469u16), (33609u16,9466u16),(33615u16,17468u16),(33616u16,11391u16),(33617u16,17457u16), (33618u16,11151u16),(33620u16,12148u16),(33626u16,11357u16),(33627u16,17458u16), (33628u16,17459u16),(33630u16,17466u16),(33631u16,17471u16),(33632u16,17474u16), (33633u16,9995u16),(33635u16,13642u16),(33636u16,11186u16),(33637u16,17479u16), (33638u16,17478u16),(33639u16,15686u16),(33640u16,17576u16),(33641u16,17578u16), (33642u16,17580u16),(33643u16,15566u16),(33644u16,17579u16),(33645u16,17581u16), (33646u16,17582u16),(33647u16,15494u16),(33655u16,10966u16),(33656u16,17584u16), (33659u16,17597u16),(33660u16,17592u16),(33661u16,17595u16),(33669u16,17591u16), (33670u16,13251u16),(33673u16,12147u16),(33678u16,13790u16),(33682u16,17461u16), (33683u16,17589u16),(33688u16,17598u16),(33691u16,17465u16),(33692u16,17590u16), (33694u16,17599u16),(33696u16,17587u16),(33704u16,17600u16),(33705u16,17594u16), (33706u16,17588u16),(33707u16,12835u16),(33712u16,17583u16),(33713u16,12084u16), (33714u16,12266u16),(33715u16,17585u16),(33716u16,17586u16),(33718u16,17593u16), (33719u16,11196u16),(33720u16,17596u16),(33721u16,15683u16),(33722u16,17601u16), (33724u16,17602u16),(33725u16,12642u16),(33728u16,17625u16),(33729u16,17603u16), (33733u16,17624u16),(33735u16,10764u16),(33738u16,11738u16),(33740u16,11775u16), (33743u16,10967u16),(33748u16,17617u16),(33750u16,17612u16),(33752u16,17606u16), (33756u16,9448u16),(33757u16,17610u16),(33759u16,17618u16),(33760u16,9409u16), (33761u16,17628u16),(33765u16,17605u16),(33769u16,13253u16),(33770u16,17623u16), (33776u16,17627u16),(33777u16,12321u16),(33778u16,10393u16),(33784u16,17621u16), (33785u16,17622u16),(33789u16,17611u16),(33793u16,17604u16),(33795u16,17620u16), (33796u16,14394u16),(33798u16,17616u16),(33803u16,17609u16),(33804u16,12675u16), (33805u16,13233u16),(33806u16,14739u16),(33807u16,17619u16),(33809u16,17615u16), (33816u16,17608u16),(33820u16,17613u16),(33821u16,12505u16),(33828u16,15684u16), (33829u16,15685u16),(33830u16,17626u16),(33831u16,14999u16),(33832u16,13673u16), (33841u16,17645u16),(33848u16,17614u16),(33852u16,17639u16),(33853u16,12513u16), (33862u16,17640u16),(33873u16,17630u16),(33879u16,16333u16),(33881u16,17632u16), (33882u16,17631u16),(33883u16,10625u16),(33884u16,17629u16),(33889u16,13252u16), (33891u16,10178u16),(33897u16,17641u16),(33899u16,11014u16),(33900u16,15930u16), (33901u16,17646u16),(33905u16,9833u16),(33907u16,17633u16),(33909u16,11966u16), (33910u16,17642u16),(33912u16,17638u16),(33914u16,17636u16),(33922u16,10032u16), (33927u16,17634u16),(33928u16,17635u16),(33929u16,17637u16),(33931u16,11510u16), (33932u16,17643u16),(33934u16,17644u16),(33943u16,17660u16),(33945u16,12676u16), (33948u16,14221u16),(33953u16,17657u16),(33967u16,16690u16),(33970u16,13254u16), (33972u16,17659u16),(33976u16,16139u16),(33977u16,17658u16),(33978u16,17655u16), (33981u16,17651u16),(33983u16,17654u16),(33985u16,17647u16),(33988u16,15183u16), (33993u16,13641u16),(33994u16,17653u16),(33997u16,17648u16),(34000u16,17649u16), (34001u16,14237u16),(34003u16,17652u16),(34006u16,9260u16),(34013u16,12087u16), (34015u16,11332u16),(34016u16,17656u16),(34019u16,17662u16),(34021u16,17661u16), (34022u16,17650u16),(34028u16,13093u16),(34032u16,17666u16),(34044u16,17769u16), (34047u16,17768u16),(34060u16,17663u16),(34065u16,12714u16),(34067u16,12536u16), (34071u16,16120u16),(34074u16,14746u16),(34079u16,17668u16),(34081u16,9449u16), (34091u16,12897u16),(34092u16,14028u16),(34103u16,13425u16),(34104u16,17665u16), (34105u16,17667u16),(34106u16,17669u16),(34107u16,17767u16),(34108u16,9035u16), (34109u16,9261u16),(34115u16,17777u16),(34120u16,17771u16),(34121u16,11517u16), (34122u16,13664u16),(34134u16,17766u16),(34137u16,17770u16),(34142u16,17774u16), (34148u16,17773u16),(34152u16,17772u16),(34162u16,17778u16),(34164u16,15909u16), (34169u16,17784u16),(34170u16,17775u16),(34171u16,17779u16),(34174u16,12122u16), (34180u16,9216u16),(34181u16,17787u16),(34183u16,17782u16),(34191u16,17783u16), (34203u16,15301u16),(34204u16,17786u16),(34212u16,17780u16),(34216u16,17781u16), (34218u16,15134u16),(34222u16,17785u16),(34223u16,14042u16),(34224u16,17790u16), (34231u16,17789u16),(34233u16,17788u16),(34241u16,17792u16),(34249u16,11564u16), (34255u16,9461u16),(34256u16,12709u16),(34259u16,17791u16),(34261u16,13041u16), (34268u16,17793u16),(34276u16,14402u16),(34281u16,10365u16),(34299u16,15934u16), (34303u16,17794u16),(34309u16,17796u16),(34321u16,12827u16),(34326u16,17798u16), (34343u16,17795u16),(34345u16,17797u16),(34360u16,16081u16),(34364u16,17799u16), (34381u16,21579u16),(34382u16,11117u16),(34383u16,12463u16),(34384u16,13031u16), (34385u16,12484u16),(34388u16,21580u16),(34394u16,15178u16),(34398u16,15736u16), (34402u16,20264u16),(34411u16,9665u16),(34412u16,21581u16),(34414u16,21582u16), (34417u16,13978u16),(34425u16,10996u16),(34426u16,21584u16),(34427u16,21586u16), (34428u16,21585u16),(34429u16,14223u16),(34430u16,14941u16),(34431u16,21583u16), (34432u16,13985u16),(34433u16,15532u16),(34434u16,12521u16),(34442u16,14760u16), (34443u16,21589u16),(34444u16,9111u16),(34445u16,21588u16),(34451u16,21595u16), (34453u16,9452u16),(34460u16,15328u16),(34461u16,21591u16),(34467u16,21593u16), (34468u16,15938u16),(34471u16,21592u16),(34472u16,21587u16),(34473u16,21596u16), (34474u16,21594u16),(34476u16,21590u16),(34479u16,21604u16),(34480u16,21601u16), (34481u16,21603u16),(34484u16,21607u16),(34485u16,21599u16),(34486u16,21597u16), (34490u16,21602u16),(34496u16,16336u16),(34500u16,21598u16),(34502u16,13484u16), (34503u16,13838u16),(34505u16,21605u16),(34506u16,10773u16),(34507u16,9991u16), (34510u16,21600u16),(34511u16,21606u16),(34512u16,21613u16),(34513u16,21619u16), (34516u16,11170u16),(34520u16,21618u16),(34521u16,14595u16),(34523u16,16320u16), (34526u16,21615u16),(34527u16,21617u16),(34532u16,10627u16),(34537u16,21608u16), (34541u16,21611u16),(34542u16,12534u16),(34544u16,16116u16),(34545u16,21609u16), (34546u16,21610u16),(34547u16,21612u16),(34548u16,21616u16),(34552u16,21622u16), (34553u16,15703u16),(34558u16,10239u16),(34560u16,14046u16),(34562u16,10423u16), (34563u16,21620u16),(34567u16,21621u16),(34568u16,21623u16),(34569u16,21626u16), (34570u16,21624u16),(34573u16,21625u16),(34578u16,15344u16),(34579u16,21614u16), (34581u16,14576u16),(34583u16,14772u16),(34584u16,16254u16),(34586u16,21632u16), (34588u16,12694u16),(34590u16,21629u16),(34593u16,12080u16),(34594u16,21641u16), (34595u16,21627u16),(34597u16,21630u16),(34601u16,21637u16),(34606u16,21631u16), (34609u16,21636u16),(34612u16,21635u16),(34615u16,21638u16),(34619u16,21628u16), (34622u16,21633u16),(34623u16,21639u16),(34631u16,15687u16),(34632u16,21634u16), (34633u16,9490u16),(34636u16,21647u16),(34638u16,15116u16),(34643u16,21650u16), (34647u16,11155u16),(34649u16,21654u16),(34656u16,21645u16),(34659u16,21651u16), (34660u16,21653u16),(34661u16,21655u16),(34670u16,21648u16),(34672u16,21646u16), (34676u16,11016u16),(34678u16,10066u16),(34683u16,21644u16),(34684u16,21652u16), (34685u16,21642u16),(34686u16,21643u16),(34690u16,21640u16),(34691u16,21761u16), (34693u16,21758u16),(34696u16,21757u16),(34699u16,21649u16),(34701u16,13643u16), (34707u16,21656u16),(34711u16,21760u16),(34719u16,12723u16),(34728u16,21658u16), (34731u16,21762u16),(34732u16,21764u16),(34733u16,21759u16),(34735u16,21657u16), (34739u16,21766u16),(34741u16,21765u16),(34746u16,12506u16),(34749u16,21769u16), (34752u16,21771u16),(34758u16,21756u16),(34762u16,21772u16),(34763u16,21767u16), (34769u16,21770u16),(34770u16,21659u16),(34771u16,21768u16),(34779u16,21773u16), (34784u16,21775u16),(34789u16,21763u16),(34794u16,21774u16),(34798u16,21776u16), (34809u16,15128u16),(34814u16,21779u16),(34819u16,16904u16),(34826u16,21780u16), (34835u16,21778u16),(34837u16,13653u16),(34838u16,21777u16),(34843u16,21781u16), (34849u16,21782u16),(34850u16,9817u16),(34866u16,20840u16),(34873u16,21783u16), (34876u16,21784u16),(34880u16,15305u16),(34884u16,21957u16),(34885u16,15143u16), (34892u16,15153u16),(34893u16,15355u16),(34900u16,14961u16),(34903u16,11549u16), (34905u16,15330u16),(34913u16,10991u16),(34914u16,18408u16),(34915u16,15519u16), (34916u16,21409u16),(34917u16,9430u16),(34920u16,9292u16),(34921u16,21410u16), (34923u16,13807u16),(34924u16,9631u16),(34926u16,16897u16),(34928u16,14160u16), (34930u16,21411u16),(34935u16,16297u16),(34941u16,21412u16),(34942u16,21977u16), (34943u16,21413u16),(34945u16,15877u16),(34946u16,21414u16),(34948u16,9057u16), (34949u16,21978u16),(34952u16,21979u16),(34955u16,9877u16),(34957u16,13074u16), (34962u16,14372u16),(34966u16,15173u16),(34972u16,14599u16),(34978u16,21415u16), (34980u16,16898u16),(34987u16,9242u16),(34989u16,14929u16),(34993u16,10549u16), (34999u16,21417u16),(35004u16,21418u16),(35009u16,9440u16),(35010u16,12304u16), (35013u16,16451u16),(35014u16,21416u16),(35017u16,21419u16),(35022u16,21421u16), (35026u16,16901u16),(35028u16,15550u16),(35029u16,15868u16),(35032u16,21980u16), (35033u16,13610u16),(35039u16,21981u16),(35042u16,21420u16),(35043u16,21422u16), (35044u16,11942u16),(35045u16,21423u16),(35048u16,21427u16),(35056u16,21429u16), (35057u16,21424u16),(35059u16,13824u16),(35060u16,13080u16),(35064u16,12512u16), (35065u16,10827u16),(35068u16,21426u16),(35070u16,21428u16),(35074u16,10786u16), (35082u16,21434u16),(35088u16,10979u16),(35090u16,9118u16),(35091u16,21432u16), (35097u16,21431u16),(35098u16,21425u16),(35099u16,21433u16),(35105u16,21430u16), (35109u16,13661u16),(35114u16,14577u16),(35115u16,21436u16),(35120u16,19124u16), (35124u16,21435u16),(35126u16,21437u16),(35137u16,21438u16),(35140u16,14984u16), (35166u16,21982u16),(35167u16,11578u16),(35174u16,21439u16),(35195u16,21440u16), (35199u16,14812u16),(35201u16,15495u16),(35203u16,21466u16),(35206u16,10563u16), (35265u16,11396u16),(35266u16,10794u16),(35268u16,10805u16),(35269u16,12692u16), (35270u16,14016u16),(35271u16,20117u16),(35272u16,12097u16),(35273u16,11770u16), (35274u16,20118u16),(35275u16,20119u16),(35276u16,20120u16),(35278u16,20121u16), (35279u16,20122u16),(35280u16,20123u16),(35281u16,20124u16),(35282u16,11534u16), (35286u16,22226u16),(35290u16,22228u16),(35292u16,22229u16),(35294u16,22227u16), (35299u16,11561u16),(35301u16,22326u16),(35302u16,9790u16),(35307u16,22327u16), (35311u16,22328u16),(35315u16,20443u16),(35328u16,15347u16),(35335u16,16889u16), (35390u16,22329u16),(35400u16,20831u16),(35449u16,16073u16),(35465u16,15769u16), (35466u16,14405u16),(35475u16,14001u16),(35591u16,19127u16),(35622u16,22330u16), (35686u16,11700u16),(35692u16,13214u16),(35744u16,17010u16),(35745u16,11343u16), (35746u16,10174u16),(35747u16,10573u16),(35748u16,13632u16),(35749u16,11310u16), (35750u16,17011u16),(35751u16,17012u16),(35752u16,14399u16),(35753u16,13620u16), (35754u16,17013u16),(35755u16,13298u16),(35757u16,15316u16),(35758u16,15558u16), (35759u16,15317u16),(35760u16,11344u16),(35762u16,11513u16),(35763u16,11183u16), (35764u16,17014u16),(35765u16,17015u16),(35766u16,15335u16),(35767u16,17016u16), (35768u16,15182u16),(35769u16,10244u16),(35770u16,12504u16),(35772u16,14202u16), (35773u16,10432u16),(35774u16,13847u16),(35775u16,10390u16),(35776u16,11772u16), (35777u16,16249u16),(35778u16,17017u16),(35779u16,17018u16),(35780u16,13237u16), (35781u16,16506u16),(35782u16,13987u16),(35784u16,16064u16),(35785u16,14218u16), (35786u16,16134u16),(35787u16,17019u16),(35788u16,16308u16),(35789u16,9827u16), (35790u16,17021u16),(35791u16,17020u16),(35793u16,15560u16),(35794u16,17022u16), (35795u16,17023u16),(35796u16,17024u16),(35797u16,14017u16),(35798u16,17025u16), (35799u16,13976u16),(35800u16,17026u16),(35801u16,17027u16),(35802u16,9642u16), (35803u16,16324u16),(35804u16,17028u16),(35805u16,11131u16),(35806u16,9989u16), (35807u16,17029u16),(35808u16,17030u16),(35809u16,10813u16),(35810u16,15310u16), (35811u16,15557u16),(35812u16,17031u16),(35813u16,10580u16),(35814u16,14989u16), (35815u16,9484u16),(35816u16,17032u16),(35817u16,17033u16),(35819u16,11570u16), (35820u16,14785u16),(35821u16,15754u16),(35822u16,17034u16),(35823u16,14808u16), (35824u16,17035u16),(35825u16,15728u16),(35826u16,11184u16),(35827u16,17036u16), (35828u16,14176u16),(35829u16,14203u16),(35830u16,17037u16),(35831u16,13470u16), (35832u16,16323u16),(35833u16,17038u16),(35834u16,13036u16),(35835u16,10198u16), (35836u16,17039u16),(35837u16,10399u16),(35838u16,11921u16),(35839u16,17040u16), (35840u16,17041u16),(35841u16,14168u16),(35842u16,17042u16),(35843u16,10062u16), (35844u16,17043u16),(35845u16,12289u16),(35846u16,16462u16),(35847u16,17044u16), (35848u16,14369u16),(35850u16,15559u16),(35851u16,12842u16),(35852u16,17045u16), (35853u16,10068u16),(35854u16,11164u16),(35855u16,17046u16),(35856u16,15124u16), (35857u16,17047u16),(35858u16,17048u16),(35859u16,14754u16),(35860u16,17049u16), (35861u16,17050u16),(35862u16,17051u16),(35863u16,9492u16),(35864u16,17054u16), (35865u16,17052u16),(35866u16,15367u16),(35867u16,17053u16),(35868u16,12688u16), (35869u16,17055u16),(35871u16,17056u16),(35872u16,17057u16),(35873u16,17058u16), (35874u16,15132u16),(35875u16,15490u16),(35876u16,9114u16),(35877u16,17059u16), (35878u16,13406u16),(35879u16,17060u16),(35880u16,11582u16),(35881u16,12636u16), (35882u16,17061u16),(35883u16,17062u16),(35884u16,12728u16),(35885u16,14368u16), (35886u16,17063u16),(35887u16,17064u16),(35888u16,12095u16),(35889u16,13260u16), (35890u16,17065u16),(35891u16,17066u16),(35892u16,13415u16),(35893u16,17067u16), (35894u16,17068u16),(35895u16,10775u16),(35905u16,11192u16),(35910u16,10190u16), (35911u16,22033u16),(35913u16,22034u16),(35916u16,14602u16),(35925u16,22160u16), (35930u16,20299u16),(35937u16,14998u16),(35938u16,11146u16),(35946u16,10957u16), (35947u16,15870u16),(35955u16,18392u16),(35960u16,22219u16),(35961u16,9225u16), (35962u16,9487u16),(35970u16,22220u16),(35973u16,22222u16),(35977u16,10974u16), (35978u16,22221u16),(35980u16,12653u16),(35988u16,22224u16),(35992u16,22223u16), (36125u16,9235u16),(36126u16,16129u16),(36127u16,10571u16),(36129u16,10752u16), (36130u16,9443u16),(36131u16,15945u16),(36132u16,14960u16),(36133u16,9085u16), (36134u16,16098u16),(36135u16,11200u16),(36136u16,16287u16),(36137u16,10378u16), (36138u16,14361u16),(36139u16,13227u16),(36140u16,9280u16),(36141u16,10761u16), (36142u16,16337u16),(36143u16,10800u16),(36144u16,10356u16),(36145u16,11395u16), (36146u16,20103u16),(36147u16,20104u16),(36148u16,14434u16),(36149u16,10818u16), (36150u16,20105u16),(36151u16,9876u16),(36152u16,12654u16),(36153u16,10404u16), (36154u16,10981u16),(36155u16,20106u16),(36156u16,15949u16),(36157u16,20107u16), (36158u16,11359u16),(36159u16,11178u16),(36160u16,20108u16),(36161u16,12317u16), (36162u16,12469u16),(36163u16,15928u16),(36164u16,16477u16),(36165u16,20109u16), (36166u16,20110u16),(36167u16,20113u16),(36168u16,20111u16),(36169u16,20112u16), (36170u16,13837u16),(36171u16,10564u16),(36172u16,10201u16),(36173u16,20114u16), (36174u16,14039u16),(36175u16,13820u16),(36176u16,9830u16),(36179u16,18582u16), (36180u16,13081u16),(36181u16,20115u16),(36182u16,12086u16),(36184u16,16459u16), (36185u16,20116u16),(36186u16,16447u16),(36187u16,13677u16),(36188u16,16676u16), (36189u16,16670u16),(36190u16,15927u16),(36192u16,15954u16),(36193u16,13811u16), (36194u16,15689u16),(36195u16,10596u16),(36196u16,9659u16),(36198u16,13841u16), (36199u16,22031u16),(36203u16,10978u16),(36205u16,22032u16),(36208u16,16498u16), (36211u16,22026u16),(36212u16,10561u16),(36213u16,16107u16),(36214u16,10592u16), (36215u16,13285u16),(36225u16,9630u16),(36228u16,22027u16),(36229u16,9607u16), (36234u16,15894u16),(36235u16,13482u16),(36241u16,22029u16),(36244u16,22028u16), (36255u16,14388u16),(36259u16,13589u16),(36273u16,22030u16),(36275u16,16502u16), (36276u16,13046u16),(36277u16,22167u16),(36280u16,22162u16),(36282u16,22170u16), (36284u16,22169u16),(36286u16,16271u16),(36287u16,22168u16),(36291u16,15895u16), (36292u16,22171u16),(36294u16,22179u16),(36299u16,9072u16),(36300u16,10063u16), (36302u16,22176u16),(36303u16,22177u16),(36305u16,13075u16),(36310u16,22172u16), (36311u16,22173u16),(36314u16,22174u16),(36315u16,22178u16),(36317u16,11749u16), (36318u16,22175u16),(36319u16,10635u16),(36323u16,22183u16),(36324u16,22186u16), (36328u16,11946u16),(36330u16,10817u16),(36331u16,22163u16),(36332u16,22180u16), (36335u16,12468u16),(36339u16,14433u16),(36341u16,11394u16),(36343u16,22181u16), (36344u16,22182u16),(36345u16,22184u16),(36346u16,10234u16),(36347u16,22185u16), (36349u16,22188u16),(36357u16,22164u16),(36361u16,22187u16),(36362u16,15702u16), (36364u16,9671u16),(36367u16,14349u16),(36372u16,22189u16),(36381u16,22190u16), (36382u16,11750u16),(36383u16,22191u16),(36386u16,14408u16),(36387u16,22194u16), (36393u16,9445u16),(36394u16,16492u16),(36396u16,22192u16),(36398u16,22193u16), (36399u16,22195u16),(36401u16,22201u16),(36405u16,22199u16),(36409u16,22198u16), (36410u16,22196u16),(36413u16,22200u16),(36416u16,22197u16),(36417u16,22203u16), (36418u16,22204u16),(36420u16,14412u16),(36423u16,19126u16),(36424u16,9999u16), (36425u16,22202u16),(36426u16,22207u16),(36427u16,14348u16),(36433u16,22205u16), (36434u16,22206u16),(36441u16,22165u16),(36454u16,9251u16),(36457u16,22166u16), (36460u16,10012u16),(36461u16,9473u16),(36463u16,22211u16),(36464u16,22208u16), (36466u16,10220u16),(36468u16,22212u16),(36470u16,22209u16),(36476u16,22210u16), (36479u16,9843u16),(36481u16,15939u16),(36485u16,22213u16),(36487u16,9684u16), (36495u16,22214u16),(36496u16,22216u16),(36500u16,22215u16),(36508u16,22217u16), (36510u16,22218u16),(36523u16,13852u16),(36524u16,10745u16),(36527u16,13486u16), (36530u16,10232u16),(36538u16,14386u16),(36558u16,20051u16),(36710u16,9616u16), (36711u16,15959u16),(36712u16,10811u16),(36713u16,15194u16),(36715u16,19932u16), (36716u16,16445u16),(36717u16,19933u16),(36718u16,12499u16),(36719u16,13662u16), (36720u16,10993u16),(36721u16,19934u16),(36722u16,19935u16),(36723u16,19936u16), (36724u16,16310u16),(36725u16,19937u16),(36726u16,19938u16),(36727u16,19940u16), (36728u16,19939u16),(36729u16,19941u16),(36730u16,19942u16),(36731u16,13460u16), (36732u16,19943u16),(36733u16,15921u16),(36734u16,19944u16),(36735u16,11541u16), (36737u16,19945u16),(36738u16,19946u16),(36739u16,11542u16),(36740u16,19947u16), (36741u16,10553u16),(36742u16,12285u16),(36743u16,19948u16),(36744u16,9233u16), (36745u16,11167u16),(36746u16,10820u16),(36747u16,19949u16),(36749u16,20046u16), (36750u16,20047u16),(36751u16,20048u16),(36752u16,10443u16),(36753u16,11318u16), (36755u16,14033u16),(36756u16,18191u16),(36757u16,15880u16),(36758u16,14944u16), (36759u16,16078u16),(36760u16,20049u16),(36761u16,16117u16),(36762u16,20050u16), (36763u16,15138u16),(36764u16,10763u16),(36766u16,9824u16),(36767u16,9272u16), (36771u16,12082u16),(36776u16,9285u16),(36777u16,9286u16),(36779u16,9287u16), (36784u16,9624u16),(36785u16,13657u16),(36790u16,19128u16),(36793u16,9278u16), (36797u16,12296u16),(36798u16,9864u16),(36801u16,13403u16),(36802u16,15731u16), (36804u16,13294u16),(36805u16,15319u16),(36807u16,10828u16),(36808u16,12530u16), (36814u16,15688u16),(36816u16,15908u16),(36817u16,11587u16),(36819u16,19129u16), (36820u16,10376u16),(36821u16,19130u16),(36824u16,11140u16),(36825u16,16121u16), (36827u16,11583u16),(36828u16,15887u16),(36829u16,14730u16),(36830u16,12267u16), (36831u16,9652u16),(36834u16,14431u16),(36836u16,19133u16),(36837u16,19131u16), (36838u16,19135u16),(36840u16,19137u16),(36841u16,19134u16),(36842u16,10022u16), (36843u16,13245u16),(36845u16,10067u16),(36846u16,19132u16),(36848u16,14051u16), (36851u16,19136u16),(36855u16,12687u16),(36856u16,9252u16),(36857u16,11308u16), (36861u16,16458u16),(36864u16,14578u16),(36865u16,14200u16),(36866u16,14007u16), (36867u16,14396u16),(36868u16,19139u16),(36869u16,19138u16),(36870u16,12895u16), (36873u16,15296u16),(36874u16,15318u16),(36875u16,19140u16),(36877u16,19143u16), (36879u16,14559u16),(36880u16,16325u16),(36881u16,19142u16),(36882u16,10036u16), (36884u16,14565u16),(36886u16,19144u16),(36887u16,10191u16),(36890u16,14543u16), (36891u16,10803u16),(36893u16,14002u16),(36894u16,9644u16),(36895u16,14212u16), (36896u16,15941u16),(36897u16,19145u16),(36898u16,10429u16),(36902u16,19141u16), (36909u16,19148u16),(36910u16,9879u16),(36911u16,19149u16),(36917u16,19146u16), (36918u16,19147u16),(36920u16,15546u16),(36923u16,12508u16),(36924u16,9253u16), (36926u16,15741u16),(36929u16,10226u16),(36930u16,14231u16),(36932u16,19150u16), (36935u16,15761u16),(36941u16,9288u16),(36943u16,10249u16),(36944u16,19153u16), (36945u16,19151u16),(36946u16,19152u16),(36947u16,10007u16),(36951u16,15522u16), (36952u16,19155u16),(36955u16,19157u16),(36962u16,19156u16),(36963u16,13413u16), (36965u16,15488u16),(36968u16,19154u16),(36973u16,15931u16),(36974u16,16113u16), (36980u16,19159u16),(36981u16,16516u16),(36989u16,19160u16),(36991u16,9275u16), (36992u16,15386u16),(36994u16,19161u16),(36995u16,19163u16),(37000u16,19162u16), (37003u16,19164u16),(37009u16,15541u16),(37011u16,10018u16),(37013u16,19538u16), (37015u16,17090u16),(37017u16,17093u16),(37019u16,17091u16),(37021u16,17092u16), (37025u16,17095u16),(37026u16,15152u16),(37027u16,12864u16),(37030u16,9103u16), (37034u16,15121u16),(37036u16,17094u16),(37038u16,15717u16),(37039u16,10935u16), (37040u16,17197u16),(37041u16,13476u16),(37043u16,17097u16),(37044u16,17096u16), (37045u16,13834u16),(37046u16,17098u16),(37048u16,17196u16),(37049u16,16497u16), (37050u16,17099u16),(37051u16,12313u16),(37054u16,17200u16),(37057u16,15759u16), (37060u16,17202u16),(37061u16,17199u16),(37063u16,17203u16),(37066u16,11523u16), (37070u16,12106u16),(37071u16,17198u16),(37072u16,17201u16),(37073u16,16248u16), (37075u16,17204u16),(37079u16,17208u16),(37083u16,17209u16),(37084u16,17207u16), (37085u16,10959u16),(37089u16,11879u16),(37090u16,17206u16),(37094u16,17205u16), (37095u16,15904u16),(37096u16,9436u16),(37099u16,17210u16),(37101u16,10824u16), (37103u16,17211u16),(37108u16,9622u16),(37112u16,9981u16),(37117u16,10193u16), (37118u16,17212u16),(37122u16,10250u16),(37124u16,17213u16),(37145u16,9256u16), (37150u16,17215u16),(37154u16,17214u16),(37155u16,17216u16),(37167u16,17218u16), (37169u16,17217u16),(37177u16,17219u16),(37187u16,17220u16),(37190u16,17221u16), (37193u16,15722u16),(37194u16,22035u16),(37195u16,13480u16),(37196u16,16470u16), (37197u16,13083u16),(37198u16,22037u16),(37199u16,22038u16),(37200u16,22036u16), (37202u16,11723u16),(37207u16,15184u16),(37210u16,10406u16),(37213u16,15910u16), (37214u16,14355u16),(37217u16,22137u16),(37218u16,22136u16),(37219u16,10933u16), (37220u16,22039u16),(37221u16,14209u16),(37225u16,22139u16),(37226u16,12115u16), (37228u16,9669u16),(37230u16,14545u16),(37231u16,22140u16),(37232u16,22138u16), (37233u16,11515u16),(37234u16,22143u16),(37236u16,22144u16),(37237u16,11540u16), (37238u16,12659u16),(37239u16,11940u16),(37240u16,14220u16),(37241u16,22145u16), (37245u16,22141u16),(37246u16,22142u16),(37247u16,12905u16),(37253u16,22147u16), (37255u16,9813u16),(37257u16,16512u16),(37259u16,9840u16),(37260u16,22146u16), (37261u16,22149u16),(37264u16,22148u16),(37265u16,22150u16),(37266u16,15154u16), (37274u16,12684u16),(37275u16,13594u16),(37282u16,22151u16),(37283u16,22152u16), (37290u16,22153u16),(37293u16,22154u16),(37294u16,22155u16),(37295u16,22156u16), (37300u16,22158u16),(37301u16,22157u16),(37306u16,22159u16),(37319u16,9446u16), (37321u16,15727u16),(37322u16,14010u16),(37324u16,12144u16),(37325u16,16301u16), (37326u16,15501u16),(37327u16,12286u16),(37329u16,11575u16),(37340u16,10555u16), (37492u16,11393u16),(37518u16,22363u16),(37550u16,22364u16),(37576u16,22365u16), (37694u16,22366u16),(37738u16,22367u16),(37775u16,22369u16),(37834u16,22368u16), (37846u16,22588u16),(37950u16,22370u16),(37995u16,22371u16),(38021u16,20841u16), (38022u16,20842u16),(38023u16,20843u16),(38024u16,16130u16),(38025u16,10169u16), (38026u16,20845u16),(38027u16,20844u16),(38028u16,20846u16),(38029u16,20847u16), (38030u16,13400u16),(38031u16,20848u16),(38032u16,20849u16),(38034u16,10371u16), (38035u16,10061u16),(38036u16,20850u16),(38037u16,20852u16),(38039u16,20851u16), (38041u16,10583u16),(38042u16,20853u16),(38043u16,20854u16),(38044u16,20855u16), (38045u16,10224u16),(38046u16,9609u16),(38047u16,16296u16),(38048u16,12863u16), (38049u16,9236u16),(38050u16,10599u16),(38051u16,20856u16),(38052u16,20857u16), (38053u16,15896u16),(38054u16,13448u16),(38055u16,11776u16),(38056u16,14782u16), (38057u16,10754u16),(38058u16,20859u16),(38059u16,20858u16),(38060u16,20861u16), (38061u16,20860u16),(38062u16,13020u16),(38063u16,20862u16),(38064u16,20863u16), (38065u16,13409u16),(38066u16,20864u16),(38067u16,13410u16),(38068u16,20865u16), (38069u16,9412u16),(38070u16,20866u16),(38071u16,20867u16),(38072u16,20868u16), (38073u16,20869u16),(38074u16,20870u16),(38075u16,16509u16),(38076u16,20871u16), (38077u16,20872u16),(38078u16,11361u16),(38079u16,20873u16),(38080u16,15718u16), (38081u16,14435u16),(38082u16,9417u16),(38083u16,12324u16),(38084u16,20874u16), (38085u16,13401u16),(38086u16,12648u16),(38088u16,20875u16),(38089u16,20876u16), (38090u16,20877u16),(38091u16,20878u16),(38092u16,20879u16),(38093u16,20880u16), (38094u16,20881u16),(38096u16,20882u16),(38097u16,20883u16),(38098u16,20884u16), (38101u16,20885u16),(38102u16,20886u16),(38103u16,20887u16),(38104u16,20889u16), (38105u16,20888u16),(38107u16,20890u16),(38108u16,14548u16),(38109u16,12478u16), (38110u16,20891u16),(38111u16,20892u16),(38112u16,20893u16),(38113u16,16056u16), (38114u16,20894u16),(38115u16,14934u16),(38116u16,20895u16),(38117u16,20896u16), (38119u16,20897u16),(38120u16,20898u16),(38121u16,20996u16),(38122u16,20899u16), (38123u16,20997u16),(38124u16,10630u16),(38125u16,12725u16),(38126u16,20998u16), (38127u16,20999u16),(38128u16,11529u16),(38129u16,15516u16),(38130u16,9494u16), (38131u16,21000u16),(38132u16,21001u16),(38133u16,21002u16),(38134u16,15573u16), (38135u16,21003u16),(38136u16,16338u16),(38137u16,21004u16),(38138u16,13249u16), (38140u16,21005u16),(38141u16,21006u16),(38142u16,12275u16),(38143u16,21007u16), (38144u16,15005u16),(38145u16,14243u16),(38146u16,21009u16),(38147u16,21008u16), (38148u16,9685u16),(38149u16,10823u16),(38150u16,21010u16),(38151u16,21011u16), (38152u16,15171u16),(38153u16,21012u16),(38154u16,21013u16),(38155u16,10425u16), (38156u16,15136u16),(38157u16,21014u16),(38158u16,21015u16),(38159u16,21016u16), (38160u16,13666u16),(38161u16,14409u16),(38162u16,21017u16),(38163u16,21018u16), (38164u16,21019u16),(38165u16,21020u16),(38166u16,21021u16),(38167u16,16119u16), (38168u16,21022u16),(38169u16,9862u16),(38170u16,12645u16),(38171u16,21023u16), (38173u16,21024u16),(38174u16,21025u16),(38175u16,21026u16),(38177u16,14818u16), (38178u16,21027u16),(38179u16,12509u16),(38180u16,9809u16),(38181u16,16457u16), (38182u16,11580u16),(38184u16,14954u16),(38185u16,21030u16),(38186u16,21028u16), (38187u16,21029u16),(38188u16,21031u16),(38189u16,10172u16),(38190u16,11397u16), (38191u16,11751u16),(38192u16,12679u16),(38193u16,21032u16),(38194u16,21033u16), (38196u16,21034u16),(38197u16,21042u16),(38198u16,21035u16),(38199u16,21036u16), (38200u16,21037u16),(38201u16,13429u16),(38202u16,21076u16),(38203u16,10210u16), (38204u16,21038u16),(38206u16,21039u16),(38207u16,21040u16),(38208u16,10203u16), (38209u16,12665u16),(38210u16,21041u16),(38212u16,21043u16),(38213u16,21044u16), (38214u16,21045u16),(38215u16,16137u16),(38217u16,21046u16),(38218u16,12912u16), (38220u16,21047u16),(38221u16,12913u16),(38222u16,21048u16),(38223u16,21049u16), (38224u16,10613u16),(38225u16,9112u16),(38226u16,21050u16),(38227u16,21051u16), (38228u16,21052u16),(38230u16,21053u16),(38231u16,21054u16),(38232u16,21055u16), (38233u16,21056u16),(38235u16,21057u16),(38236u16,11706u16),(38237u16,21060u16), (38238u16,21058u16),(38239u16,21059u16),(38241u16,21061u16),(38242u16,21062u16), (38243u16,12300u16),(38244u16,21063u16),(38245u16,21064u16),(38246u16,21065u16), (38247u16,21066u16),(38248u16,21067u16),(38249u16,21068u16),(38250u16,21069u16), (38251u16,21070u16),(38252u16,21071u16),(38253u16,12121u16),(38255u16,21072u16), (38256u16,12268u16),(38257u16,21073u16),(38258u16,21074u16),(38259u16,21075u16), (38262u16,14981u16),(38271u16,9599u16),(38376u16,12672u16),(38377u16,18752u16), (38378u16,13808u16),(38379u16,18753u16),(38381u16,9268u16),(38382u16,14767u16), (38383u16,9804u16),(38384u16,13667u16),(38385u16,18754u16),(38386u16,14963u16), (38387u16,18755u16),(38388u16,11373u16),(38389u16,18756u16),(38390u16,18757u16), (38391u16,12673u16),(38392u16,16057u16),(38393u16,12879u16),(38394u16,10810u16), (38395u16,14762u16),(38396u16,18758u16),(38397u16,12721u16),(38398u16,18759u16), (38400u16,10362u16),(38401u16,10628u16),(38402u16,10975u16),(38403u16,18760u16), (38404u16,18761u16),(38405u16,15901u16),(38406u16,18762u16),(38408u16,18763u16), (38409u16,15338u16),(38410u16,18764u16),(38411u16,18765u16),(38412u16,18766u16), (38413u16,18767u16),(38414u16,15349u16),(38415u16,18768u16),(38416u16,9496u16), (38417u16,12092u16),(38418u16,18769u16),(38420u16,12076u16),(38421u16,18770u16), (38422u16,18771u16),(38423u16,18772u16),(38425u16,18773u16),(38426u16,18774u16), (38428u16,10568u16),(38429u16,17071u16),(38431u16,10216u16),(38433u16,17073u16), (38434u16,17072u16),(38442u16,17075u16),(38446u16,13663u16),(38449u16,17074u16), (38450u16,10387u16),(38451u16,15379u16),(38452u16,15570u16),(38453u16,16138u16), (38454u16,11550u16),(38459u16,16507u16),(38460u16,17077u16),(38461u16,17076u16), (38463u16,9027u16),(38464u16,14586u16),(38466u16,17078u16),(38468u16,10574u16), (38469u16,11347u16),(38470u16,12474u16),(38471u16,12449u16),(38472u16,9629u16), (38473u16,17079u16),(38475u16,12455u16),(38476u16,12841u16),(38477u16,11516u16), (38480u16,14977u16),(38484u16,17080u16),(38485u16,13809u16),(38491u16,9276u16), (38495u16,17081u16),(38497u16,10189u16),(38498u16,15891u16),(38500u16,9688u16), (38503u16,17082u16),(38504u16,15906u16),(38505u16,14968u16),(38506u16,13082u16), (38508u16,17083u16),(38514u16,17084u16),(38516u16,17085u16),(38517u16,12329u16), (38518u16,14398u16),(38519u16,14976u16),(38533u16,15746u16),(38534u16,12446u16), (38536u16,17086u16),(38539u16,14224u16),(38541u16,17087u16),(38543u16,14225u16), (38544u16,15579u16),(38548u16,10629u16),(38551u16,17088u16),(38552u16,9040u16), (38553u16,14937u16),(38556u16,16102u16),(38567u16,14232u16),(38576u16,17089u16), (38579u16,18751u16),(38582u16,12260u16),(38585u16,22356u16),(38588u16,22357u16), (38589u16,22358u16),(38590u16,12874u16),(38592u16,13609u16),(38593u16,15362u16), (38596u16,15164u16),(38597u16,15332u16),(38598u16,11320u16),(38599u16,10780u16), (38601u16,21079u16),(38604u16,9823u16),(38605u16,15701u16),(38606u16,22359u16), (38607u16,9686u16),(38610u16,22360u16),(38613u16,10056u16),(38624u16,22362u16), (38632u16,15749u16),(38633u16,22332u16),(38634u16,15304u16),(38639u16,22334u16), (38643u16,22333u16),(38646u16,12322u16),(38647u16,12120u16),(38649u16,9217u16), (38654u16,14802u16),(38656u16,15177u16),(38657u16,22336u16),(38660u16,15001u16), (38662u16,22335u16),(38663u16,16135u16),(38664u16,22337u16),(38665u16,12660u16), (38669u16,11199u16),(38670u16,22339u16),(38671u16,22338u16),(38675u16,12887u16), (38678u16,12311u16),(38684u16,14165u16),(38686u16,14943u16),(38698u16,22340u16), (38701u16,22341u16),(38704u16,22342u16),(38706u16,12467u16),(38712u16,9077u16), (38713u16,13104u16),(38718u16,22343u16),(38738u16,13459u16),(38739u16,22331u16), (38742u16,11709u16),(38745u16,11703u16),(38747u16,10044u16),(38750u16,10394u16), (38752u16,11906u16),(38753u16,12685u16),(38754u16,12705u16),(38757u16,16669u16), (38761u16,10624u16),(38771u16,11584u16),(38772u16,15300u16),(38774u16,9073u16), (38780u16,22531u16),(38789u16,22532u16),(38795u16,15117u16),(38797u16,9041u16), (38801u16,22533u16),(38802u16,22534u16),(38804u16,22535u16),(38808u16,13437u16), (38816u16,11732u16),(38819u16,22538u16),(38827u16,22537u16),(38829u16,9277u16), (38831u16,22536u16),(38834u16,22539u16),(38836u16,22540u16),(38886u16,14729u16), (38887u16,13630u16),(38889u16,10936u16),(38890u16,19689u16),(38891u16,19690u16), (38892u16,19691u16),(38893u16,11719u16),(38899u16,15569u16),(38901u16,15912u16), (38902u16,13831u16),(39029u16,15504u16),(39030u16,10170u16),(39031u16,13469u16), (39032u16,21467u16),(39033u16,14993u16),(39034u16,14174u16),(39035u16,15180u16), (39036u16,19554u16),(39037u16,14606u16),(39038u16,10778u16),(39039u16,10222u16), (39040u16,21468u16),(39041u16,9093u16),(39042u16,14199u16),(39043u16,21469u16), (39044u16,15869u16),(39045u16,12458u16),(39046u16,12331u16),(39047u16,13241u16), (39048u16,11702u16),(39049u16,21566u16),(39050u16,11358u16),(39052u16,21567u16), (39053u16,21568u16),(39055u16,21569u16),(39056u16,15520u16),(39057u16,13226u16), (39059u16,14574u16),(39060u16,21570u16),(39062u16,15692u16),(39063u16,11912u16), (39064u16,14411u16),(39066u16,21571u16),(39067u16,21572u16),(39068u16,15348u16), (39069u16,10243u16),(39070u16,21573u16),(39071u16,21574u16),(39072u16,10038u16), (39073u16,21575u16),(39074u16,21576u16),(39076u16,9497u16),(39077u16,21577u16), (39078u16,21578u16),(39079u16,13592u16),(39118u16,10426u16),(39121u16,20434u16), (39122u16,20435u16),(39123u16,20436u16),(39125u16,20437u16),(39128u16,13219u16), (39129u16,20438u16),(39130u16,20439u16),(39134u16,10396u16),(39135u16,13984u16), (39143u16,18549u16),(39144u16,22562u16),(39181u16,22563u16),(39184u16,9450u16), (39214u16,22564u16),(39252u16,22566u16),(39253u16,22565u16),(39267u16,18552u16), (39269u16,11307u16),(39271u16,18553u16),(39272u16,18554u16),(39273u16,18555u16), (39274u16,18556u16),(39275u16,18557u16),(39276u16,18558u16),(39277u16,10380u16), (39278u16,15576u16),(39279u16,11499u16),(39280u16,14011u16),(39281u16,9220u16), (39282u16,14194u16),(39284u16,18559u16),(39285u16,10257u16),(39286u16,13621u16), (39287u16,18560u16),(39290u16,11535u16),(39292u16,9308u16),(39293u16,18561u16), (39295u16,10251u16),(39296u16,18562u16),(39297u16,12882u16),(39300u16,18563u16), (39301u16,14973u16),(39302u16,10796u16),(39303u16,18564u16),(39304u16,12066u16), (39306u16,18565u16),(39307u16,9491u16),(39309u16,18566u16),(39311u16,12338u16), (39312u16,18567u16),(39313u16,18568u16),(39314u16,12533u16),(39315u16,18569u16), (39316u16,18570u16),(39317u16,18571u16),(39318u16,14020u16),(39319u16,16649u16), (39320u16,16884u16),(39321u16,14982u16),(39333u16,21190u16),(39336u16,17401u16), (39532u16,12522u16),(39533u16,15871u16),(39534u16,14587u16),(39535u16,15312u16), (39536u16,9654u16),(39537u16,13488u16),(39539u16,9426u16),(39540u16,12476u16), (39541u16,19349u16),(39542u16,13992u16),(39543u16,19350u16),(39544u16,19351u16), (39545u16,11737u16),(39546u16,19352u16),(39547u16,16439u16),(39548u16,14588u16), (39549u16,19354u16),(39550u16,11366u16),(39551u16,19353u16),(39552u16,19355u16), (39553u16,19356u16),(39554u16,12523u16),(39556u16,11525u16),(39557u16,19357u16), (39558u16,12515u16),(39559u16,10932u16),(39560u16,19358u16),(39562u16,19359u16), (39563u16,9645u16),(39564u16,15368u16),(39567u16,11880u16),(39568u16,19360u16), (39569u16,13284u16),(39570u16,19361u16),(39571u16,19362u16),(39574u16,19363u16), (39575u16,13218u16),(39576u16,19364u16),(39578u16,13782u16),(39579u16,19365u16), (39580u16,19366u16),(39581u16,19367u16),(39582u16,19120u16),(39583u16,19368u16), (39584u16,19369u16),(39585u16,12511u16),(39586u16,19370u16),(39587u16,19371u16), (39588u16,16317u16),(39589u16,19372u16),(39591u16,19373u16),(39592u16,10774u16), (39600u16,22542u16),(39601u16,22541u16),(39606u16,22545u16),(39607u16,22543u16), (39608u16,10926u16),(39610u16,22546u16),(39612u16,22547u16),(39616u16,22549u16), (39617u16,22548u16),(39618u16,22551u16),(39621u16,22550u16),(39627u16,22552u16), (39628u16,22553u16),(39633u16,22554u16),(39635u16,14227u16),(39640u16,10608u16), (39647u16,22567u16),(39649u16,22568u16),(39654u16,22569u16),(39659u16,22571u16), (39661u16,22573u16),(39663u16,22570u16),(39673u16,22574u16),(39675u16,22572u16), (39683u16,16490u16),(39688u16,22575u16),(39695u16,22576u16),(39699u16,22577u16), (39711u16,22578u16),(39715u16,22579u16),(39727u16,17238u16),(39730u16,16635u16), (39739u16,19182u16),(39740u16,10812u16),(39745u16,11968u16),(39746u16,11189u16), (39747u16,22556u16),(39748u16,13244u16),(39749u16,22555u16),(39751u16,22557u16), (39752u16,22559u16),(39753u16,22558u16),(39757u16,22560u16),(39759u16,14751u16), (39761u16,22561u16),(39764u16,12832u16),(40060u16,15742u16),(40063u16,22372u16), (40065u16,12464u16),(40066u16,22373u16),(40069u16,22374u16),(40070u16,22375u16), (40071u16,22376u16),(40072u16,22377u16),(40075u16,22379u16),(40077u16,9226u16), (40078u16,22380u16),(40080u16,22381u16),(40081u16,22382u16),(40082u16,22383u16), (40084u16,22384u16),(40085u16,22385u16),(40090u16,22386u16),(40091u16,22387u16), (40092u16,14957u16),(40094u16,22388u16),(40095u16,22389u16),(40096u16,22390u16), (40097u16,22391u16),(40098u16,22392u16),(40099u16,22393u16),(40100u16,12145u16), (40101u16,22394u16),(40102u16,22395u16),(40103u16,22396u16),(40104u16,22397u16), (40105u16,22398u16),(40107u16,22399u16),(40109u16,22400u16),(40110u16,22401u16), (40112u16,22402u16),(40113u16,22403u16),(40114u16,22404u16),(40115u16,22405u16), (40116u16,22406u16),(40117u16,22407u16),(40118u16,22408u16),(40119u16,22409u16), (40120u16,11693u16),(40122u16,22410u16),(40123u16,22411u16),(40124u16,22412u16), (40125u16,22413u16),(40131u16,13675u16),(40132u16,22414u16),(40133u16,22415u16), (40134u16,22416u16),(40135u16,22417u16),(40138u16,22418u16),(40139u16,22419u16), (40140u16,22516u16),(40141u16,22517u16),(40142u16,22518u16),(40143u16,22519u16), (40144u16,22520u16),(40147u16,22521u16),(40148u16,22522u16),(40149u16,22523u16), (40150u16,9293u16),(40151u16,22524u16),(40152u16,22525u16),(40153u16,22526u16), (40156u16,22527u16),(40157u16,22528u16),(40158u16,12314u16),(40159u16,22529u16), (40162u16,22530u16),(40479u16,12906u16),(40480u16,21200u16),(40481u16,11311u16), (40482u16,21201u16),(40483u16,12724u16),(40485u16,13039u16),(40486u16,15322u16), (40488u16,21202u16),(40489u16,21203u16),(40490u16,21204u16),(40491u16,21205u16), (40492u16,21206u16),(40493u16,15323u16),(40495u16,15371u16),(40497u16,21208u16), (40498u16,21207u16),(40499u16,15872u16),(40501u16,14585u16),(40502u16,21209u16), (40503u16,21211u16),(40504u16,21210u16),(40505u16,21212u16),(40506u16,21213u16), (40509u16,10620u16),(40510u16,21214u16),(40511u16,10997u16),(40513u16,21215u16), (40514u16,21216u16),(40515u16,11758u16),(40516u16,21217u16),(40517u16,10241u16), (40518u16,21218u16),(40519u16,21219u16),(40520u16,21220u16),(40521u16,21221u16), (40522u16,13606u16),(40523u16,21222u16),(40524u16,21223u16),(40526u16,21224u16), (40527u16,13099u16),(40529u16,21225u16),(40533u16,21226u16),(40535u16,21227u16), (40536u16,22544u16),(40538u16,21228u16),(40539u16,21229u16),(40540u16,21230u16), (40542u16,21231u16),(40547u16,21232u16),(40548u16,10980u16),(40550u16,21233u16), (40551u16,21234u16),(40552u16,21235u16),(40553u16,21236u16),(40554u16,21237u16), (40555u16,21238u16),(40556u16,21239u16),(40557u16,21241u16),(40560u16,15680u16), (40561u16,21240u16),(40563u16,21242u16),(40574u16,22161u16),(40575u16,12470u16), (40578u16,22583u16),(40583u16,22584u16),(40584u16,22585u16),(40587u16,22586u16), (40594u16,22587u16),(40595u16,12465u16),(40605u16,22589u16),(40607u16,22590u16), (40614u16,12528u16),(40628u16,22025u16),(40632u16,22024u16),(40635u16,12518u16), (40637u16,22580u16),(40638u16,22581u16),(40644u16,11153u16),(40649u16,16883u16), (40653u16,14047u16),(40654u16,12137u16),(40655u16,21189u16),(40657u16,10983u16), (40660u16,13408u16),(40664u16,12837u16),(40667u16,22591u16),(40668u16,22592u16), (40669u16,22593u16),(40671u16,22595u16),(40672u16,22594u16),(40674u16,22596u16), (40677u16,22599u16),(40679u16,22598u16),(40681u16,22597u16),(40682u16,22600u16), (40687u16,22601u16),(40697u16,20688u16),(40699u16,20689u16),(40700u16,20690u16), (40702u16,22353u16),(40715u16,22354u16),(40717u16,22355u16),(40718u16,10171u16), (40720u16,16655u16),(40723u16,10771u16),(40727u16,16652u16),(40729u16,17402u16), (40736u16,14048u16),(40738u16,22602u16),(40748u16,22603u16),(40751u16,22604u16), (40754u16,23560u16),(40755u16,23561u16),(40756u16,23562u16),(40757u16,23563u16), (40758u16,23564u16),(40759u16,22606u16),(40760u16,23565u16),(40761u16,22605u16), (40762u16,23566u16),(40763u16,9254u16),(40764u16,23567u16),(40765u16,22607u16), (40766u16,22608u16),(40767u16,23568u16),(40768u16,23569u16),(40769u16,23570u16), (40770u16,23571u16),(40771u16,23572u16),(40772u16,22609u16),(40773u16,23573u16), (40774u16,23574u16),(40775u16,23575u16),(40776u16,23576u16),(40777u16,23577u16), (40778u16,23578u16),(40779u16,23579u16),(40780u16,23580u16),(40781u16,23581u16), (40782u16,23582u16),(40783u16,23583u16),(40784u16,13280u16),(40785u16,20445u16), (40786u16,23584u16),(40787u16,23585u16),(40788u16,23586u16),(40789u16,23587u16), (40790u16,23588u16),(40791u16,23589u16),(40792u16,23590u16),(40793u16,23591u16), (40794u16,23592u16),(40795u16,23593u16),(40796u16,23594u16),(40797u16,23595u16), (40798u16,23596u16),(40799u16,23597u16),(40800u16,23598u16),(40801u16,23599u16), (40802u16,23600u16),(40803u16,23601u16),(40804u16,23602u16),(40805u16,23603u16), (40806u16,23604u16),(40807u16,23605u16),(40808u16,23606u16),(40809u16,23607u16), (40810u16,23608u16),(40811u16,23609u16),(40812u16,23610u16),(40813u16,23611u16), (40814u16,23612u16),(40815u16,23613u16),(40816u16,23614u16),(40817u16,23615u16), (40818u16,23616u16),(40819u16,23617u16),(40820u16,23618u16),(40821u16,23619u16), (40822u16,23620u16),(40823u16,23621u16),(40824u16,23622u16),(40825u16,23623u16), (40826u16,23624u16),(40827u16,23625u16),(40828u16,23626u16),(40829u16,23627u16), (40830u16,23628u16),(40831u16,9656u16),(40832u16,22344u16),(40833u16,23629u16), (40834u16,23630u16),(40835u16,22345u16),(40836u16,12323u16),(40837u16,22346u16), (40838u16,22347u16),(40839u16,22348u16),(40840u16,22349u16),(40841u16,22350u16), (40842u16,22351u16),(40843u16,13588u16),(40844u16,22352u16),(40845u16,23631u16), (40846u16,23632u16),(40847u16,23633u16),(40848u16,23634u16),(40849u16,23635u16), (40850u16,23636u16),(40851u16,23637u16),(40852u16,23638u16),(40853u16,23639u16), (40854u16,23640u16),(40855u16,23641u16),(40856u16,23642u16),(40857u16,12345u16), (40858u16,10743u16),(40859u16,20687u16),(40860u16,23643u16),(40861u16,23644u16), (40862u16,23645u16),(40863u16,10809u16),(40864u16,16878u16),(40865u16,23646u16), (40866u16,23647u16),(40867u16,23648u16),(40868u16,23649u16),(40869u16,23650u16), (40884u16,23775u16),(40885u16,23783u16),(40886u16,23788u16),(40887u16,23789u16), (40888u16,23795u16),(40889u16,23812u16),(40890u16,23829u16),(40891u16,23845u16), (57344u16,7886u16),(57345u16,7887u16),(57346u16,7888u16),(57347u16,7889u16), (57348u16,7890u16),(57349u16,7891u16),(57350u16,7892u16),(57351u16,7893u16), (57352u16,7894u16),(57353u16,7895u16),(57354u16,7896u16),(57355u16,7897u16), (57356u16,7898u16),(57357u16,7899u16),(57358u16,7900u16),(57359u16,7901u16), (57360u16,7902u16),(57361u16,7903u16),(57362u16,7904u16),(57363u16,7905u16), (57364u16,7906u16),(57365u16,7907u16),(57366u16,7908u16),(57367u16,7909u16), (57368u16,7910u16),(57369u16,7911u16),(57370u16,7912u16),(57371u16,7913u16), (57372u16,7914u16),(57373u16,7915u16),(57374u16,7916u16),(57375u16,7917u16), (57376u16,7918u16),(57377u16,7919u16),(57378u16,7920u16),(57379u16,7921u16), (57380u16,7922u16),(57381u16,7923u16),(57382u16,7924u16),(57383u16,7925u16), (57384u16,7926u16),(57385u16,7927u16),(57386u16,7928u16),(57387u16,7929u16), (57388u16,7930u16),(57389u16,7931u16),(57390u16,7932u16),(57391u16,7933u16), (57392u16,7934u16),(57393u16,7935u16),(57394u16,7936u16),(57395u16,7937u16), (57396u16,7938u16),(57397u16,7939u16),(57398u16,7940u16),(57399u16,7941u16), (57400u16,7942u16),(57401u16,7943u16),(57402u16,7944u16),(57403u16,7945u16), (57404u16,7946u16),(57405u16,7947u16),(57406u16,7948u16),(57407u16,7949u16), (57408u16,7950u16),(57409u16,7951u16),(57410u16,7952u16),(57411u16,7953u16), (57412u16,7954u16),(57413u16,7955u16),(57414u16,7956u16),(57415u16,7957u16), (57416u16,7958u16),(57417u16,7959u16),(57418u16,7960u16),(57419u16,7961u16), (57420u16,7962u16),(57421u16,7963u16),(57422u16,7964u16),(57423u16,7965u16), (57424u16,7966u16),(57425u16,7967u16),(57426u16,7968u16),(57427u16,7969u16), (57428u16,7970u16),(57429u16,7971u16),(57430u16,7972u16),(57431u16,7973u16), (57432u16,7974u16),(57433u16,7975u16),(57434u16,7976u16),(57435u16,7977u16), (57436u16,7978u16),(57437u16,7979u16),(57438u16,8076u16),(57439u16,8077u16), (57440u16,8078u16),(57441u16,8079u16),(57442u16,8080u16),(57443u16,8081u16), (57444u16,8082u16),(57445u16,8083u16),(57446u16,8084u16),(57447u16,8085u16), (57448u16,8086u16),(57449u16,8087u16),(57450u16,8088u16),(57451u16,8089u16), (57452u16,8090u16),(57453u16,8091u16),(57454u16,8092u16),(57455u16,8093u16), (57456u16,8094u16),(57457u16,8095u16),(57458u16,8096u16),(57459u16,8097u16), (57460u16,8098u16),(57461u16,8099u16),(57462u16,8100u16),(57463u16,8101u16), (57464u16,8102u16),(57465u16,8103u16),(57466u16,8104u16),(57467u16,8105u16), (57468u16,8106u16),(57469u16,8107u16),(57470u16,8108u16),(57471u16,8109u16), (57472u16,8110u16),(57473u16,8111u16),(57474u16,8112u16),(57475u16,8113u16), (57476u16,8114u16),(57477u16,8115u16),(57478u16,8116u16),(57479u16,8117u16), (57480u16,8118u16),(57481u16,8119u16),(57482u16,8120u16),(57483u16,8121u16), (57484u16,8122u16),(57485u16,8123u16),(57486u16,8124u16),(57487u16,8125u16), (57488u16,8126u16),(57489u16,8127u16),(57490u16,8128u16),(57491u16,8129u16), (57492u16,8130u16),(57493u16,8131u16),(57494u16,8132u16),(57495u16,8133u16), (57496u16,8134u16),(57497u16,8135u16),(57498u16,8136u16),(57499u16,8137u16), (57500u16,8138u16),(57501u16,8139u16),(57502u16,8140u16),(57503u16,8141u16), (57504u16,8142u16),(57505u16,8143u16),(57506u16,8144u16),(57507u16,8145u16), (57508u16,8146u16),(57509u16,8147u16),(57510u16,8148u16),(57511u16,8149u16), (57512u16,8150u16),(57513u16,8151u16),(57514u16,8152u16),(57515u16,8153u16), (57516u16,8154u16),(57517u16,8155u16),(57518u16,8156u16),(57519u16,8157u16), (57520u16,8158u16),(57521u16,8159u16),(57522u16,8160u16),(57523u16,8161u16), (57524u16,8162u16),(57525u16,8163u16),(57526u16,8164u16),(57527u16,8165u16), (57528u16,8166u16),(57529u16,8167u16),(57530u16,8168u16),(57531u16,8169u16), (57532u16,8266u16),(57533u16,8267u16),(57534u16,8268u16),(57535u16,8269u16), (57536u16,8270u16),(57537u16,8271u16),(57538u16,8272u16),(57539u16,8273u16), (57540u16,8274u16),(57541u16,8275u16),(57542u16,8276u16),(57543u16,8277u16), (57544u16,8278u16),(57545u16,8279u16),(57546u16,8280u16),(57547u16,8281u16), (57548u16,8282u16),(57549u16,8283u16),(57550u16,8284u16),(57551u16,8285u16), (57552u16,8286u16),(57553u16,8287u16),(57554u16,8288u16),(57555u16,8289u16), (57556u16,8290u16),(57557u16,8291u16),(57558u16,8292u16),(57559u16,8293u16), (57560u16,8294u16),(57561u16,8295u16),(57562u16,8296u16),(57563u16,8297u16), (57564u16,8298u16),(57565u16,8299u16),(57566u16,8300u16),(57567u16,8301u16), (57568u16,8302u16),(57569u16,8303u16),(57570u16,8304u16),(57571u16,8305u16), (57572u16,8306u16),(57573u16,8307u16),(57574u16,8308u16),(57575u16,8309u16), (57576u16,8310u16),(57577u16,8311u16),(57578u16,8312u16),(57579u16,8313u16), (57580u16,8314u16),(57581u16,8315u16),(57582u16,8316u16),(57583u16,8317u16), (57584u16,8318u16),(57585u16,8319u16),(57586u16,8320u16),(57587u16,8321u16), (57588u16,8322u16),(57589u16,8323u16),(57590u16,8324u16),(57591u16,8325u16), (57592u16,8326u16),(57593u16,8327u16),(57594u16,8328u16),(57595u16,8329u16), (57596u16,8330u16),(57597u16,8331u16),(57598u16,8332u16),(57599u16,8333u16), (57600u16,8334u16),(57601u16,8335u16),(57602u16,8336u16),(57603u16,8337u16), (57604u16,8338u16),(57605u16,8339u16),(57606u16,8340u16),(57607u16,8341u16), (57608u16,8342u16),(57609u16,8343u16),(57610u16,8344u16),(57611u16,8345u16), (57612u16,8346u16),(57613u16,8347u16),(57614u16,8348u16),(57615u16,8349u16), (57616u16,8350u16),(57617u16,8351u16),(57618u16,8352u16),(57619u16,8353u16), (57620u16,8354u16),(57621u16,8355u16),(57622u16,8356u16),(57623u16,8357u16), (57624u16,8358u16),(57625u16,8359u16),(57626u16,8456u16),(57627u16,8457u16), (57628u16,8458u16),(57629u16,8459u16),(57630u16,8460u16),(57631u16,8461u16), (57632u16,8462u16),(57633u16,8463u16),(57634u16,8464u16),(57635u16,8465u16), (57636u16,8466u16),(57637u16,8467u16),(57638u16,8468u16),(57639u16,8469u16), (57640u16,8470u16),(57641u16,8471u16),(57642u16,8472u16),(57643u16,8473u16), (57644u16,8474u16),(57645u16,8475u16),(57646u16,8476u16),(57647u16,8477u16), (57648u16,8478u16),(57649u16,8479u16),(57650u16,8480u16),(57651u16,8481u16), (57652u16,8482u16),(57653u16,8483u16),(57654u16,8484u16),(57655u16,8485u16), (57656u16,8486u16),(57657u16,8487u16),(57658u16,8488u16),(57659u16,8489u16), (57660u16,8490u16),(57661u16,8491u16),(57662u16,8492u16),(57663u16,8493u16), (57664u16,8494u16),(57665u16,8495u16),(57666u16,8496u16),(57667u16,8497u16), (57668u16,8498u16),(57669u16,8499u16),(57670u16,8500u16),(57671u16,8501u16), (57672u16,8502u16),(57673u16,8503u16),(57674u16,8504u16),(57675u16,8505u16), (57676u16,8506u16),(57677u16,8507u16),(57678u16,8508u16),(57679u16,8509u16), (57680u16,8510u16),(57681u16,8511u16),(57682u16,8512u16),(57683u16,8513u16), (57684u16,8514u16),(57685u16,8515u16),(57686u16,8516u16),(57687u16,8517u16), (57688u16,8518u16),(57689u16,8519u16),(57690u16,8520u16),(57691u16,8521u16), (57692u16,8522u16),(57693u16,8523u16),(57694u16,8524u16),(57695u16,8525u16), (57696u16,8526u16),(57697u16,8527u16),(57698u16,8528u16),(57699u16,8529u16), (57700u16,8530u16),(57701u16,8531u16),(57702u16,8532u16),(57703u16,8533u16), (57704u16,8534u16),(57705u16,8535u16),(57706u16,8536u16),(57707u16,8537u16), (57708u16,8538u16),(57709u16,8539u16),(57710u16,8540u16),(57711u16,8541u16), (57712u16,8542u16),(57713u16,8543u16),(57714u16,8544u16),(57715u16,8545u16), (57716u16,8546u16),(57717u16,8547u16),(57718u16,8548u16),(57719u16,8549u16), (57720u16,8646u16),(57721u16,8647u16),(57722u16,8648u16),(57723u16,8649u16), (57724u16,8650u16),(57725u16,8651u16),(57726u16,8652u16),(57727u16,8653u16), (57728u16,8654u16),(57729u16,8655u16),(57730u16,8656u16),(57731u16,8657u16), (57732u16,8658u16),(57733u16,8659u16),(57734u16,8660u16),(57735u16,8661u16), (57736u16,8662u16),(57737u16,8663u16),(57738u16,8664u16),(57739u16,8665u16), (57740u16,8666u16),(57741u16,8667u16),(57742u16,8668u16),(57743u16,8669u16), (57744u16,8670u16),(57745u16,8671u16),(57746u16,8672u16),(57747u16,8673u16), (57748u16,8674u16),(57749u16,8675u16),(57750u16,8676u16),(57751u16,8677u16), (57752u16,8678u16),(57753u16,8679u16),(57754u16,8680u16),(57755u16,8681u16), (57756u16,8682u16),(57757u16,8683u16),(57758u16,8684u16),(57759u16,8685u16), (57760u16,8686u16),(57761u16,8687u16),(57762u16,8688u16),(57763u16,8689u16), (57764u16,8690u16),(57765u16,8691u16),(57766u16,8692u16),(57767u16,8693u16), (57768u16,8694u16),(57769u16,8695u16),(57770u16,8696u16),(57771u16,8697u16), (57772u16,8698u16),(57773u16,8699u16),(57774u16,8700u16),(57775u16,8701u16), (57776u16,8702u16),(57777u16,8703u16),(57778u16,8704u16),(57779u16,8705u16), (57780u16,8706u16),(57781u16,8707u16),(57782u16,8708u16),(57783u16,8709u16), (57784u16,8710u16),(57785u16,8711u16),(57786u16,8712u16),(57787u16,8713u16), (57788u16,8714u16),(57789u16,8715u16),(57790u16,8716u16),(57791u16,8717u16), (57792u16,8718u16),(57793u16,8719u16),(57794u16,8720u16),(57795u16,8721u16), (57796u16,8722u16),(57797u16,8723u16),(57798u16,8724u16),(57799u16,8725u16), (57800u16,8726u16),(57801u16,8727u16),(57802u16,8728u16),(57803u16,8729u16), (57804u16,8730u16),(57805u16,8731u16),(57806u16,8732u16),(57807u16,8733u16), (57808u16,8734u16),(57809u16,8735u16),(57810u16,8736u16),(57811u16,8737u16), (57812u16,8738u16),(57813u16,8739u16),(57814u16,8836u16),(57815u16,8837u16), (57816u16,8838u16),(57817u16,8839u16),(57818u16,8840u16),(57819u16,8841u16), (57820u16,8842u16),(57821u16,8843u16),(57822u16,8844u16),(57823u16,8845u16), (57824u16,8846u16),(57825u16,8847u16),(57826u16,8848u16),(57827u16,8849u16), (57828u16,8850u16),(57829u16,8851u16),(57830u16,8852u16),(57831u16,8853u16), (57832u16,8854u16),(57833u16,8855u16),(57834u16,8856u16),(57835u16,8857u16), (57836u16,8858u16),(57837u16,8859u16),(57838u16,8860u16),(57839u16,8861u16), (57840u16,8862u16),(57841u16,8863u16),(57842u16,8864u16),(57843u16,8865u16), (57844u16,8866u16),(57845u16,8867u16),(57846u16,8868u16),(57847u16,8869u16), (57848u16,8870u16),(57849u16,8871u16),(57850u16,8872u16),(57851u16,8873u16), (57852u16,8874u16),(57853u16,8875u16),(57854u16,8876u16),(57855u16,8877u16), (57856u16,8878u16),(57857u16,8879u16),(57858u16,8880u16),(57859u16,8881u16), (57860u16,8882u16),(57861u16,8883u16),(57862u16,8884u16),(57863u16,8885u16), (57864u16,8886u16),(57865u16,8887u16),(57866u16,8888u16),(57867u16,8889u16), (57868u16,8890u16),(57869u16,8891u16),(57870u16,8892u16),(57871u16,8893u16), (57872u16,8894u16),(57873u16,8895u16),(57874u16,8896u16),(57875u16,8897u16), (57876u16,8898u16),(57877u16,8899u16),(57878u16,8900u16),(57879u16,8901u16), (57880u16,8902u16),(57881u16,8903u16),(57882u16,8904u16),(57883u16,8905u16), (57884u16,8906u16),(57885u16,8907u16),(57886u16,8908u16),(57887u16,8909u16), (57888u16,8910u16),(57889u16,8911u16),(57890u16,8912u16),(57891u16,8913u16), (57892u16,8914u16),(57893u16,8915u16),(57894u16,8916u16),(57895u16,8917u16), (57896u16,8918u16),(57897u16,8919u16),(57898u16,8920u16),(57899u16,8921u16), (57900u16,8922u16),(57901u16,8923u16),(57902u16,8924u16),(57903u16,8925u16), (57904u16,8926u16),(57905u16,8927u16),(57906u16,8928u16),(57907u16,8929u16), (57908u16,22706u16),(57909u16,22707u16),(57910u16,22708u16),(57911u16,22709u16), (57912u16,22710u16),(57913u16,22711u16),(57914u16,22712u16),(57915u16,22713u16), (57916u16,22714u16),(57917u16,22715u16),(57918u16,22716u16),(57919u16,22717u16), (57920u16,22718u16),(57921u16,22719u16),(57922u16,22720u16),(57923u16,22721u16), (57924u16,22722u16),(57925u16,22723u16),(57926u16,22724u16),(57927u16,22725u16), (57928u16,22726u16),(57929u16,22727u16),(57930u16,22728u16),(57931u16,22729u16), (57932u16,22730u16),(57933u16,22731u16),(57934u16,22732u16),(57935u16,22733u16), (57936u16,22734u16),(57937u16,22735u16),(57938u16,22736u16),(57939u16,22737u16), (57940u16,22738u16),(57941u16,22739u16),(57942u16,22740u16),(57943u16,22741u16), (57944u16,22742u16),(57945u16,22743u16),(57946u16,22744u16),(57947u16,22745u16), (57948u16,22746u16),(57949u16,22747u16),(57950u16,22748u16),(57951u16,22749u16), (57952u16,22750u16),(57953u16,22751u16),(57954u16,22752u16),(57955u16,22753u16), (57956u16,22754u16),(57957u16,22755u16),(57958u16,22756u16),(57959u16,22757u16), (57960u16,22758u16),(57961u16,22759u16),(57962u16,22760u16),(57963u16,22761u16), (57964u16,22762u16),(57965u16,22763u16),(57966u16,22764u16),(57967u16,22765u16), (57968u16,22766u16),(57969u16,22767u16),(57970u16,22768u16),(57971u16,22769u16), (57972u16,22770u16),(57973u16,22771u16),(57974u16,22772u16),(57975u16,22773u16), (57976u16,22774u16),(57977u16,22775u16),(57978u16,22776u16),(57979u16,22777u16), (57980u16,22778u16),(57981u16,22779u16),(57982u16,22780u16),(57983u16,22781u16), (57984u16,22782u16),(57985u16,22783u16),(57986u16,22784u16),(57987u16,22785u16), (57988u16,22786u16),(57989u16,22787u16),(57990u16,22788u16),(57991u16,22789u16), (57992u16,22790u16),(57993u16,22791u16),(57994u16,22792u16),(57995u16,22793u16), (57996u16,22794u16),(57997u16,22795u16),(57998u16,22796u16),(57999u16,22797u16), (58000u16,22798u16),(58001u16,22799u16),(58002u16,22896u16),(58003u16,22897u16), (58004u16,22898u16),(58005u16,22899u16),(58006u16,22900u16),(58007u16,22901u16), (58008u16,22902u16),(58009u16,22903u16),(58010u16,22904u16),(58011u16,22905u16), (58012u16,22906u16),(58013u16,22907u16),(58014u16,22908u16),(58015u16,22909u16), (58016u16,22910u16),(58017u16,22911u16),(58018u16,22912u16),(58019u16,22913u16), (58020u16,22914u16),(58021u16,22915u16),(58022u16,22916u16),(58023u16,22917u16), (58024u16,22918u16),(58025u16,22919u16),(58026u16,22920u16),(58027u16,22921u16), (58028u16,22922u16),(58029u16,22923u16),(58030u16,22924u16),(58031u16,22925u16), (58032u16,22926u16),(58033u16,22927u16),(58034u16,22928u16),(58035u16,22929u16), (58036u16,22930u16),(58037u16,22931u16),(58038u16,22932u16),(58039u16,22933u16), (58040u16,22934u16),(58041u16,22935u16),(58042u16,22936u16),(58043u16,22937u16), (58044u16,22938u16),(58045u16,22939u16),(58046u16,22940u16),(58047u16,22941u16), (58048u16,22942u16),(58049u16,22943u16),(58050u16,22944u16),(58051u16,22945u16), (58052u16,22946u16),(58053u16,22947u16),(58054u16,22948u16),(58055u16,22949u16), (58056u16,22950u16),(58057u16,22951u16),(58058u16,22952u16),(58059u16,22953u16), (58060u16,22954u16),(58061u16,22955u16),(58062u16,22956u16),(58063u16,22957u16), (58064u16,22958u16),(58065u16,22959u16),(58066u16,22960u16),(58067u16,22961u16), (58068u16,22962u16),(58069u16,22963u16),(58070u16,22964u16),(58071u16,22965u16), (58072u16,22966u16),(58073u16,22967u16),(58074u16,22968u16),(58075u16,22969u16), (58076u16,22970u16),(58077u16,22971u16),(58078u16,22972u16),(58079u16,22973u16), (58080u16,22974u16),(58081u16,22975u16),(58082u16,22976u16),(58083u16,22977u16), (58084u16,22978u16),(58085u16,22979u16),(58086u16,22980u16),(58087u16,22981u16), (58088u16,22982u16),(58089u16,22983u16),(58090u16,22984u16),(58091u16,22985u16), (58092u16,22986u16),(58093u16,22987u16),(58094u16,22988u16),(58095u16,22989u16), (58096u16,23086u16),(58097u16,23087u16),(58098u16,23088u16),(58099u16,23089u16), (58100u16,23090u16),(58101u16,23091u16),(58102u16,23092u16),(58103u16,23093u16), (58104u16,23094u16),(58105u16,23095u16),(58106u16,23096u16),(58107u16,23097u16), (58108u16,23098u16),(58109u16,23099u16),(58110u16,23100u16),(58111u16,23101u16), (58112u16,23102u16),(58113u16,23103u16),(58114u16,23104u16),(58115u16,23105u16), (58116u16,23106u16),(58117u16,23107u16),(58118u16,23108u16),(58119u16,23109u16), (58120u16,23110u16),(58121u16,23111u16),(58122u16,23112u16),(58123u16,23113u16), (58124u16,23114u16),(58125u16,23115u16),(58126u16,23116u16),(58127u16,23117u16), (58128u16,23118u16),(58129u16,23119u16),(58130u16,23120u16),(58131u16,23121u16), (58132u16,23122u16),(58133u16,23123u16),(58134u16,23124u16),(58135u16,23125u16), (58136u16,23126u16),(58137u16,23127u16),(58138u16,23128u16),(58139u16,23129u16), (58140u16,23130u16),(58141u16,23131u16),(58142u16,23132u16),(58143u16,23133u16), (58144u16,23134u16),(58145u16,23135u16),(58146u16,23136u16),(58147u16,23137u16), (58148u16,23138u16),(58149u16,23139u16),(58150u16,23140u16),(58151u16,23141u16), (58152u16,23142u16),(58153u16,23143u16),(58154u16,23144u16),(58155u16,23145u16), (58156u16,23146u16),(58157u16,23147u16),(58158u16,23148u16),(58159u16,23149u16), (58160u16,23150u16),(58161u16,23151u16),(58162u16,23152u16),(58163u16,23153u16), (58164u16,23154u16),(58165u16,23155u16),(58166u16,23156u16),(58167u16,23157u16), (58168u16,23158u16),(58169u16,23159u16),(58170u16,23160u16),(58171u16,23161u16), (58172u16,23162u16),(58173u16,23163u16),(58174u16,23164u16),(58175u16,23165u16), (58176u16,23166u16),(58177u16,23167u16),(58178u16,23168u16),(58179u16,23169u16), (58180u16,23170u16),(58181u16,23171u16),(58182u16,23172u16),(58183u16,23173u16), (58184u16,23174u16),(58185u16,23175u16),(58186u16,23176u16),(58187u16,23177u16), (58188u16,23178u16),(58189u16,23179u16),(58190u16,23276u16),(58191u16,23277u16), (58192u16,23278u16),(58193u16,23279u16),(58194u16,23280u16),(58195u16,23281u16), (58196u16,23282u16),(58197u16,23283u16),(58198u16,23284u16),(58199u16,23285u16), (58200u16,23286u16),(58201u16,23287u16),(58202u16,23288u16),(58203u16,23289u16), (58204u16,23290u16),(58205u16,23291u16),(58206u16,23292u16),(58207u16,23293u16), (58208u16,23294u16),(58209u16,23295u16),(58210u16,23296u16),(58211u16,23297u16), (58212u16,23298u16),(58213u16,23299u16),(58214u16,23300u16),(58215u16,23301u16), (58216u16,23302u16),(58217u16,23303u16),(58218u16,23304u16),(58219u16,23305u16), (58220u16,23306u16),(58221u16,23307u16),(58222u16,23308u16),(58223u16,23309u16), (58224u16,23310u16),(58225u16,23311u16),(58226u16,23312u16),(58227u16,23313u16), (58228u16,23314u16),(58229u16,23315u16),(58230u16,23316u16),(58231u16,23317u16), (58232u16,23318u16),(58233u16,23319u16),(58234u16,23320u16),(58235u16,23321u16), (58236u16,23322u16),(58237u16,23323u16),(58238u16,23324u16),(58239u16,23325u16), (58240u16,23326u16),(58241u16,23327u16),(58242u16,23328u16),(58243u16,23329u16), (58244u16,23330u16),(58245u16,23331u16),(58246u16,23332u16),(58247u16,23333u16), (58248u16,23334u16),(58249u16,23335u16),(58250u16,23336u16),(58251u16,23337u16), (58252u16,23338u16),(58253u16,23339u16),(58254u16,23340u16),(58255u16,23341u16), (58256u16,23342u16),(58257u16,23343u16),(58258u16,23344u16),(58259u16,23345u16), (58260u16,23346u16),(58261u16,23347u16),(58262u16,23348u16),(58263u16,23349u16), (58264u16,23350u16),(58265u16,23351u16),(58266u16,23352u16),(58267u16,23353u16), (58268u16,23354u16),(58269u16,23355u16),(58270u16,23356u16),(58271u16,23357u16), (58272u16,23358u16),(58273u16,23359u16),(58274u16,23360u16),(58275u16,23361u16), (58276u16,23362u16),(58277u16,23363u16),(58278u16,23364u16),(58279u16,23365u16), (58280u16,23366u16),(58281u16,23367u16),(58282u16,23368u16),(58283u16,23369u16), (58284u16,23466u16),(58285u16,23467u16),(58286u16,23468u16),(58287u16,23469u16), (58288u16,23470u16),(58289u16,23471u16),(58290u16,23472u16),(58291u16,23473u16), (58292u16,23474u16),(58293u16,23475u16),(58294u16,23476u16),(58295u16,23477u16), (58296u16,23478u16),(58297u16,23479u16),(58298u16,23480u16),(58299u16,23481u16), (58300u16,23482u16),(58301u16,23483u16),(58302u16,23484u16),(58303u16,23485u16), (58304u16,23486u16),(58305u16,23487u16),(58306u16,23488u16),(58307u16,23489u16), (58308u16,23490u16),(58309u16,23491u16),(58310u16,23492u16),(58311u16,23493u16), (58312u16,23494u16),(58313u16,23495u16),(58314u16,23496u16),(58315u16,23497u16), (58316u16,23498u16),(58317u16,23499u16),(58318u16,23500u16),(58319u16,23501u16), (58320u16,23502u16),(58321u16,23503u16),(58322u16,23504u16),(58323u16,23505u16), (58324u16,23506u16),(58325u16,23507u16),(58326u16,23508u16),(58327u16,23509u16), (58328u16,23510u16),(58329u16,23511u16),(58330u16,23512u16),(58331u16,23513u16), (58332u16,23514u16),(58333u16,23515u16),(58334u16,23516u16),(58335u16,23517u16), (58336u16,23518u16),(58337u16,23519u16),(58338u16,23520u16),(58339u16,23521u16), (58340u16,23522u16),(58341u16,23523u16),(58342u16,23524u16),(58343u16,23525u16), (58344u16,23526u16),(58345u16,23527u16),(58346u16,23528u16),(58347u16,23529u16), (58348u16,23530u16),(58349u16,23531u16),(58350u16,23532u16),(58351u16,23533u16), (58352u16,23534u16),(58353u16,23535u16),(58354u16,23536u16),(58355u16,23537u16), (58356u16,23538u16),(58357u16,23539u16),(58358u16,23540u16),(58359u16,23541u16), (58360u16,23542u16),(58361u16,23543u16),(58362u16,23544u16),(58363u16,23545u16), (58364u16,23546u16),(58365u16,23547u16),(58366u16,23548u16),(58367u16,23549u16), (58368u16,23550u16),(58369u16,23551u16),(58370u16,23552u16),(58371u16,23553u16), (58372u16,23554u16),(58373u16,23555u16),(58374u16,23556u16),(58375u16,23557u16), (58376u16,23558u16),(58377u16,23559u16),(58378u16,23656u16),(58379u16,23657u16), (58380u16,23658u16),(58381u16,23659u16),(58382u16,23660u16),(58383u16,23661u16), (58384u16,23662u16),(58385u16,23663u16),(58386u16,23664u16),(58387u16,23665u16), (58388u16,23666u16),(58389u16,23667u16),(58390u16,23668u16),(58391u16,23669u16), (58392u16,23670u16),(58393u16,23671u16),(58394u16,23672u16),(58395u16,23673u16), (58396u16,23674u16),(58397u16,23675u16),(58398u16,23676u16),(58399u16,23677u16), (58400u16,23678u16),(58401u16,23679u16),(58402u16,23680u16),(58403u16,23681u16), (58404u16,23682u16),(58405u16,23683u16),(58406u16,23684u16),(58407u16,23685u16), (58408u16,23686u16),(58409u16,23687u16),(58410u16,23688u16),(58411u16,23689u16), (58412u16,23690u16),(58413u16,23691u16),(58414u16,23692u16),(58415u16,23693u16), (58416u16,23694u16),(58417u16,23695u16),(58418u16,23696u16),(58419u16,23697u16), (58420u16,23698u16),(58421u16,23699u16),(58422u16,23700u16),(58423u16,23701u16), (58424u16,23702u16),(58425u16,23703u16),(58426u16,23704u16),(58427u16,23705u16), (58428u16,23706u16),(58429u16,23707u16),(58430u16,23708u16),(58431u16,23709u16), (58432u16,23710u16),(58433u16,23711u16),(58434u16,23712u16),(58435u16,23713u16), (58436u16,23714u16),(58437u16,23715u16),(58438u16,23716u16),(58439u16,23717u16), (58440u16,23718u16),(58441u16,23719u16),(58442u16,23720u16),(58443u16,23721u16), (58444u16,23722u16),(58445u16,23723u16),(58446u16,23724u16),(58447u16,23725u16), (58448u16,23726u16),(58449u16,23727u16),(58450u16,23728u16),(58451u16,23729u16), (58452u16,23730u16),(58453u16,23731u16),(58454u16,23732u16),(58455u16,23733u16), (58456u16,23734u16),(58457u16,23735u16),(58458u16,23736u16),(58459u16,23737u16), (58460u16,23738u16),(58461u16,23739u16),(58462u16,23740u16),(58463u16,23741u16), (58464u16,23742u16),(58465u16,23743u16),(58466u16,23744u16),(58467u16,23745u16), (58468u16,23746u16),(58469u16,23747u16),(58470u16,23748u16),(58471u16,23749u16), (58472u16,23846u16),(58473u16,23847u16),(58474u16,23848u16),(58475u16,23849u16), (58476u16,23850u16),(58477u16,23851u16),(58478u16,23852u16),(58479u16,23853u16), (58480u16,23854u16),(58481u16,23855u16),(58482u16,23856u16),(58483u16,23857u16), (58484u16,23858u16),(58485u16,23859u16),(58486u16,23860u16),(58487u16,23861u16), (58488u16,23862u16),(58489u16,23863u16),(58490u16,23864u16),(58491u16,23865u16), (58492u16,23866u16),(58493u16,23867u16),(58494u16,23868u16),(58495u16,23869u16), (58496u16,23870u16),(58497u16,23871u16),(58498u16,23872u16),(58499u16,23873u16), (58500u16,23874u16),(58501u16,23875u16),(58502u16,23876u16),(58503u16,23877u16), (58504u16,23878u16),(58505u16,23879u16),(58506u16,23880u16),(58507u16,23881u16), (58508u16,23882u16),(58509u16,23883u16),(58510u16,23884u16),(58511u16,23885u16), (58512u16,23886u16),(58513u16,23887u16),(58514u16,23888u16),(58515u16,23889u16), (58516u16,23890u16),(58517u16,23891u16),(58518u16,23892u16),(58519u16,23893u16), (58520u16,23894u16),(58521u16,23895u16),(58522u16,23896u16),(58523u16,23897u16), (58524u16,23898u16),(58525u16,23899u16),(58526u16,23900u16),(58527u16,23901u16), (58528u16,23902u16),(58529u16,23903u16),(58530u16,23904u16),(58531u16,23905u16), (58532u16,23906u16),(58533u16,23907u16),(58534u16,23908u16),(58535u16,23909u16), (58536u16,23910u16),(58537u16,23911u16),(58538u16,23912u16),(58539u16,23913u16), (58540u16,23914u16),(58541u16,23915u16),(58542u16,23916u16),(58543u16,23917u16), (58544u16,23918u16),(58545u16,23919u16),(58546u16,23920u16),(58547u16,23921u16), (58548u16,23922u16),(58549u16,23923u16),(58550u16,23924u16),(58551u16,23925u16), (58552u16,23926u16),(58553u16,23927u16),(58554u16,23928u16),(58555u16,23929u16), (58556u16,23930u16),(58557u16,23931u16),(58558u16,23932u16),(58559u16,23933u16), (58560u16,23934u16),(58561u16,23935u16),(58562u16,23936u16),(58563u16,23937u16), (58564u16,23938u16),(58565u16,23939u16),(58566u16,6080u16),(58567u16,6081u16), (58568u16,6082u16),(58569u16,6083u16),(58570u16,6084u16),(58571u16,6085u16), (58572u16,6086u16),(58573u16,6087u16),(58574u16,6088u16),(58575u16,6089u16), (58576u16,6090u16),(58577u16,6091u16),(58578u16,6092u16),(58579u16,6093u16), (58580u16,6094u16),(58581u16,6095u16),(58582u16,6096u16),(58583u16,6097u16), (58584u16,6098u16),(58585u16,6099u16),(58586u16,6100u16),(58587u16,6101u16), (58588u16,6102u16),(58589u16,6103u16),(58590u16,6104u16),(58591u16,6105u16), (58592u16,6106u16),(58593u16,6107u16),(58594u16,6108u16),(58595u16,6109u16), (58596u16,6110u16),(58597u16,6111u16),(58598u16,6112u16),(58599u16,6113u16), (58600u16,6114u16),(58601u16,6115u16),(58602u16,6116u16),(58603u16,6117u16), (58604u16,6118u16),(58605u16,6119u16),(58606u16,6120u16),(58607u16,6121u16), (58608u16,6122u16),(58609u16,6123u16),(58610u16,6124u16),(58611u16,6125u16), (58612u16,6126u16),(58613u16,6127u16),(58614u16,6128u16),(58615u16,6129u16), (58616u16,6130u16),(58617u16,6131u16),(58618u16,6132u16),(58619u16,6133u16), (58620u16,6134u16),(58621u16,6135u16),(58622u16,6136u16),(58623u16,6137u16), (58624u16,6138u16),(58625u16,6139u16),(58626u16,6140u16),(58627u16,6141u16), (58628u16,6142u16),(58629u16,6143u16),(58630u16,6144u16),(58631u16,6145u16), (58632u16,6146u16),(58633u16,6147u16),(58634u16,6148u16),(58635u16,6149u16), (58636u16,6150u16),(58637u16,6151u16),(58638u16,6152u16),(58639u16,6153u16), (58640u16,6154u16),(58641u16,6155u16),(58642u16,6156u16),(58643u16,6157u16), (58644u16,6158u16),(58645u16,6159u16),(58646u16,6160u16),(58647u16,6161u16), (58648u16,6162u16),(58649u16,6163u16),(58650u16,6164u16),(58651u16,6165u16), (58652u16,6166u16),(58653u16,6167u16),(58654u16,6168u16),(58655u16,6169u16), (58656u16,6170u16),(58657u16,6171u16),(58658u16,6172u16),(58659u16,6173u16), (58660u16,6174u16),(58661u16,6175u16),(58662u16,6270u16),(58663u16,6271u16), (58664u16,6272u16),(58665u16,6273u16),(58666u16,6274u16),(58667u16,6275u16), (58668u16,6276u16),(58669u16,6277u16),(58670u16,6278u16),(58671u16,6279u16), (58672u16,6280u16),(58673u16,6281u16),(58674u16,6282u16),(58675u16,6283u16), (58676u16,6284u16),(58677u16,6285u16),(58678u16,6286u16),(58679u16,6287u16), (58680u16,6288u16),(58681u16,6289u16),(58682u16,6290u16),(58683u16,6291u16), (58684u16,6292u16),(58685u16,6293u16),(58686u16,6294u16),(58687u16,6295u16), (58688u16,6296u16),(58689u16,6297u16),(58690u16,6298u16),(58691u16,6299u16), (58692u16,6300u16),(58693u16,6301u16),(58694u16,6302u16),(58695u16,6303u16), (58696u16,6304u16),(58697u16,6305u16),(58698u16,6306u16),(58699u16,6307u16), (58700u16,6308u16),(58701u16,6309u16),(58702u16,6310u16),(58703u16,6311u16), (58704u16,6312u16),(58705u16,6313u16),(58706u16,6314u16),(58707u16,6315u16), (58708u16,6316u16),(58709u16,6317u16),(58710u16,6318u16),(58711u16,6319u16), (58712u16,6320u16),(58713u16,6321u16),(58714u16,6322u16),(58715u16,6323u16), (58716u16,6324u16),(58717u16,6325u16),(58718u16,6326u16),(58719u16,6327u16), (58720u16,6328u16),(58721u16,6329u16),(58722u16,6330u16),(58723u16,6331u16), (58724u16,6332u16),(58725u16,6333u16),(58726u16,6334u16),(58727u16,6335u16), (58728u16,6336u16),(58729u16,6337u16),(58730u16,6338u16),(58731u16,6339u16), (58732u16,6340u16),(58733u16,6341u16),(58734u16,6342u16),(58735u16,6343u16), (58736u16,6344u16),(58737u16,6345u16),(58738u16,6346u16),(58739u16,6347u16), (58740u16,6348u16),(58741u16,6349u16),(58742u16,6350u16),(58743u16,6351u16), (58744u16,6352u16),(58745u16,6353u16),(58746u16,6354u16),(58747u16,6355u16), (58748u16,6356u16),(58749u16,6357u16),(58750u16,6358u16),(58751u16,6359u16), (58752u16,6360u16),(58753u16,6361u16),(58754u16,6362u16),(58755u16,6363u16), (58756u16,6364u16),(58757u16,6365u16),(58758u16,6460u16),(58759u16,6461u16), (58760u16,6462u16),(58761u16,6463u16),(58762u16,6464u16),(58763u16,6465u16), (58764u16,6466u16),(58765u16,6467u16),(58766u16,6468u16),(58767u16,6469u16), (58768u16,6470u16),(58769u16,6471u16),(58770u16,6472u16),(58771u16,6473u16), (58772u16,6474u16),(58773u16,6475u16),(58774u16,6476u16),(58775u16,6477u16), (58776u16,6478u16),(58777u16,6479u16),(58778u16,6480u16),(58779u16,6481u16), (58780u16,6482u16),(58781u16,6483u16),(58782u16,6484u16),(58783u16,6485u16), (58784u16,6486u16),(58785u16,6487u16),(58786u16,6488u16),(58787u16,6489u16), (58788u16,6490u16),(58789u16,6491u16),(58790u16,6492u16),(58791u16,6493u16), (58792u16,6494u16),(58793u16,6495u16),(58794u16,6496u16),(58795u16,6497u16), (58796u16,6498u16),(58797u16,6499u16),(58798u16,6500u16),(58799u16,6501u16), (58800u16,6502u16),(58801u16,6503u16),(58802u16,6504u16),(58803u16,6505u16), (58804u16,6506u16),(58805u16,6507u16),(58806u16,6508u16),(58807u16,6509u16), (58808u16,6510u16),(58809u16,6511u16),(58810u16,6512u16),(58811u16,6513u16), (58812u16,6514u16),(58813u16,6515u16),(58814u16,6516u16),(58815u16,6517u16), (58816u16,6518u16),(58817u16,6519u16),(58818u16,6520u16),(58819u16,6521u16), (58820u16,6522u16),(58821u16,6523u16),(58822u16,6524u16),(58823u16,6525u16), (58824u16,6526u16),(58825u16,6527u16),(58826u16,6528u16),(58827u16,6529u16), (58828u16,6530u16),(58829u16,6531u16),(58830u16,6532u16),(58831u16,6533u16), (58832u16,6534u16),(58833u16,6535u16),(58834u16,6536u16),(58835u16,6537u16), (58836u16,6538u16),(58837u16,6539u16),(58838u16,6540u16),(58839u16,6541u16), (58840u16,6542u16),(58841u16,6543u16),(58842u16,6544u16),(58843u16,6545u16), (58844u16,6546u16),(58845u16,6547u16),(58846u16,6548u16),(58847u16,6549u16), (58848u16,6550u16),(58849u16,6551u16),(58850u16,6552u16),(58851u16,6553u16), (58852u16,6554u16),(58854u16,6650u16),(58855u16,6651u16),(58856u16,6652u16), (58857u16,6653u16),(58858u16,6654u16),(58859u16,6655u16),(58860u16,6656u16), (58861u16,6657u16),(58862u16,6658u16),(58863u16,6659u16),(58864u16,6660u16), (58865u16,6661u16),(58866u16,6662u16),(58867u16,6663u16),(58868u16,6664u16), (58869u16,6665u16),(58870u16,6666u16),(58871u16,6667u16),(58872u16,6668u16), (58873u16,6669u16),(58874u16,6670u16),(58875u16,6671u16),(58876u16,6672u16), (58877u16,6673u16),(58878u16,6674u16),(58879u16,6675u16),(58880u16,6676u16), (58881u16,6677u16),(58882u16,6678u16),(58883u16,6679u16),(58884u16,6680u16), (58885u16,6681u16),(58886u16,6682u16),(58887u16,6683u16),(58888u16,6684u16), (58889u16,6685u16),(58890u16,6686u16),(58891u16,6687u16),(58892u16,6688u16), (58893u16,6689u16),(58894u16,6690u16),(58895u16,6691u16),(58896u16,6692u16), (58897u16,6693u16),(58898u16,6694u16),(58899u16,6695u16),(58900u16,6696u16), (58901u16,6697u16),(58902u16,6698u16),(58903u16,6699u16),(58904u16,6700u16), (58905u16,6701u16),(58906u16,6702u16),(58907u16,6703u16),(58908u16,6704u16), (58909u16,6705u16),(58910u16,6706u16),(58911u16,6707u16),(58912u16,6708u16), (58913u16,6709u16),(58914u16,6710u16),(58915u16,6711u16),(58916u16,6712u16), (58917u16,6713u16),(58918u16,6714u16),(58919u16,6715u16),(58920u16,6716u16), (58921u16,6717u16),(58922u16,6718u16),(58923u16,6719u16),(58924u16,6720u16), (58925u16,6721u16),(58926u16,6722u16),(58927u16,6723u16),(58928u16,6724u16), (58929u16,6725u16),(58930u16,6726u16),(58931u16,6727u16),(58932u16,6728u16), (58933u16,6729u16),(58934u16,6730u16),(58935u16,6731u16),(58936u16,6732u16), (58937u16,6733u16),(58938u16,6734u16),(58939u16,6735u16),(58940u16,6736u16), (58941u16,6737u16),(58942u16,6738u16),(58943u16,6739u16),(58944u16,6740u16), (58945u16,6741u16),(58946u16,6742u16),(58947u16,6743u16),(58948u16,6744u16), (58949u16,6745u16),(58950u16,6840u16),(58951u16,6841u16),(58952u16,6842u16), (58953u16,6843u16),(58954u16,6844u16),(58955u16,6845u16),(58956u16,6846u16), (58957u16,6847u16),(58958u16,6848u16),(58959u16,6849u16),(58960u16,6850u16), (58961u16,6851u16),(58962u16,6852u16),(58963u16,6853u16),(58964u16,6854u16), (58965u16,6855u16),(58966u16,6856u16),(58967u16,6857u16),(58968u16,6858u16), (58969u16,6859u16),(58970u16,6860u16),(58971u16,6861u16),(58972u16,6862u16), (58973u16,6863u16),(58974u16,6864u16),(58975u16,6865u16),(58976u16,6866u16), (58977u16,6867u16),(58978u16,6868u16),(58979u16,6869u16),(58980u16,6870u16), (58981u16,6871u16),(58982u16,6872u16),(58983u16,6873u16),(58984u16,6874u16), (58985u16,6875u16),(58986u16,6876u16),(58987u16,6877u16),(58988u16,6878u16), (58989u16,6879u16),(58990u16,6880u16),(58991u16,6881u16),(58992u16,6882u16), (58993u16,6883u16),(58994u16,6884u16),(58995u16,6885u16),(58996u16,6886u16), (58997u16,6887u16),(58998u16,6888u16),(58999u16,6889u16),(59000u16,6890u16), (59001u16,6891u16),(59002u16,6892u16),(59003u16,6893u16),(59004u16,6894u16), (59005u16,6895u16),(59006u16,6896u16),(59007u16,6897u16),(59008u16,6898u16), (59009u16,6899u16),(59010u16,6900u16),(59011u16,6901u16),(59012u16,6902u16), (59013u16,6903u16),(59014u16,6904u16),(59015u16,6905u16),(59016u16,6906u16), (59017u16,6907u16),(59018u16,6908u16),(59019u16,6909u16),(59020u16,6910u16), (59021u16,6911u16),(59022u16,6912u16),(59023u16,6913u16),(59024u16,6914u16), (59025u16,6915u16),(59026u16,6916u16),(59027u16,6917u16),(59028u16,6918u16), (59029u16,6919u16),(59030u16,6920u16),(59031u16,6921u16),(59032u16,6922u16), (59033u16,6923u16),(59034u16,6924u16),(59035u16,6925u16),(59036u16,6926u16), (59037u16,6927u16),(59038u16,6928u16),(59039u16,6929u16),(59040u16,6930u16), (59041u16,6931u16),(59042u16,6932u16),(59043u16,6933u16),(59044u16,6934u16), (59045u16,6935u16),(59046u16,7030u16),(59047u16,7031u16),(59048u16,7032u16), (59049u16,7033u16),(59050u16,7034u16),(59051u16,7035u16),(59052u16,7036u16), (59053u16,7037u16),(59054u16,7038u16),(59055u16,7039u16),(59056u16,7040u16), (59057u16,7041u16),(59058u16,7042u16),(59059u16,7043u16),(59060u16,7044u16), (59061u16,7045u16),(59062u16,7046u16),(59063u16,7047u16),(59064u16,7048u16), (59065u16,7049u16),(59066u16,7050u16),(59067u16,7051u16),(59068u16,7052u16), (59069u16,7053u16),(59070u16,7054u16),(59071u16,7055u16),(59072u16,7056u16), (59073u16,7057u16),(59074u16,7058u16),(59075u16,7059u16),(59076u16,7060u16), (59077u16,7061u16),(59078u16,7062u16),(59079u16,7063u16),(59080u16,7064u16), (59081u16,7065u16),(59082u16,7066u16),(59083u16,7067u16),(59084u16,7068u16), (59085u16,7069u16),(59086u16,7070u16),(59087u16,7071u16),(59088u16,7072u16), (59089u16,7073u16),(59090u16,7074u16),(59091u16,7075u16),(59092u16,7076u16), (59093u16,7077u16),(59094u16,7078u16),(59095u16,7079u16),(59096u16,7080u16), (59097u16,7081u16),(59098u16,7082u16),(59099u16,7083u16),(59100u16,7084u16), (59101u16,7085u16),(59102u16,7086u16),(59103u16,7087u16),(59104u16,7088u16), (59105u16,7089u16),(59106u16,7090u16),(59107u16,7091u16),(59108u16,7092u16), (59109u16,7093u16),(59110u16,7094u16),(59111u16,7095u16),(59112u16,7096u16), (59113u16,7097u16),(59114u16,7098u16),(59115u16,7099u16),(59116u16,7100u16), (59117u16,7101u16),(59118u16,7102u16),(59119u16,7103u16),(59120u16,7104u16), (59121u16,7105u16),(59122u16,7106u16),(59123u16,7107u16),(59124u16,7108u16), (59125u16,7109u16),(59126u16,7110u16),(59127u16,7111u16),(59128u16,7112u16), (59129u16,7113u16),(59130u16,7114u16),(59131u16,7115u16),(59132u16,7116u16), (59133u16,7117u16),(59134u16,7118u16),(59135u16,7119u16),(59136u16,7120u16), (59137u16,7121u16),(59138u16,7122u16),(59139u16,7123u16),(59140u16,7124u16), (59141u16,7125u16),(59142u16,7220u16),(59143u16,7221u16),(59144u16,7222u16), (59145u16,7223u16),(59146u16,7224u16),(59147u16,7225u16),(59148u16,7226u16), (59149u16,7227u16),(59150u16,7228u16),(59151u16,7229u16),(59152u16,7230u16), (59153u16,7231u16),(59154u16,7232u16),(59155u16,7233u16),(59156u16,7234u16), (59157u16,7235u16),(59158u16,7236u16),(59159u16,7237u16),(59160u16,7238u16), (59161u16,7239u16),(59162u16,7240u16),(59163u16,7241u16),(59164u16,7242u16), (59165u16,7243u16),(59166u16,7244u16),(59167u16,7245u16),(59168u16,7246u16), (59169u16,7247u16),(59170u16,7248u16),(59171u16,7249u16),(59172u16,7250u16), (59173u16,7251u16),(59174u16,7252u16),(59175u16,7253u16),(59176u16,7254u16), (59177u16,7255u16),(59178u16,7256u16),(59179u16,7257u16),(59180u16,7258u16), (59181u16,7259u16),(59182u16,7260u16),(59183u16,7261u16),(59184u16,7262u16), (59185u16,7263u16),(59186u16,7264u16),(59187u16,7265u16),(59188u16,7266u16), (59189u16,7267u16),(59190u16,7268u16),(59191u16,7269u16),(59192u16,7270u16), (59193u16,7271u16),(59194u16,7272u16),(59195u16,7273u16),(59196u16,7274u16), (59197u16,7275u16),(59198u16,7276u16),(59199u16,7277u16),(59200u16,7278u16), (59201u16,7279u16),(59202u16,7280u16),(59203u16,7281u16),(59204u16,7282u16), (59205u16,7283u16),(59206u16,7284u16),(59207u16,7285u16),(59208u16,7286u16), (59209u16,7287u16),(59210u16,7288u16),(59211u16,7289u16),(59212u16,7290u16), (59213u16,7291u16),(59214u16,7292u16),(59215u16,7293u16),(59216u16,7294u16), (59217u16,7295u16),(59218u16,7296u16),(59219u16,7297u16),(59220u16,7298u16), (59221u16,7299u16),(59222u16,7300u16),(59223u16,7301u16),(59224u16,7302u16), (59225u16,7303u16),(59226u16,7304u16),(59227u16,7305u16),(59228u16,7306u16), (59229u16,7307u16),(59230u16,7308u16),(59231u16,7309u16),(59232u16,7310u16), (59233u16,7311u16),(59234u16,7312u16),(59235u16,7313u16),(59236u16,7314u16), (59237u16,7315u16),(59238u16,6376u16),(59239u16,6377u16),(59240u16,6378u16), (59241u16,6379u16),(59242u16,6380u16),(59243u16,6381u16),(59245u16,6433u16), (59246u16,6444u16),(59247u16,6445u16),(59248u16,6458u16),(59249u16,6459u16), (59250u16,6829u16),(59251u16,6830u16),(59252u16,6831u16),(59253u16,6832u16), (59254u16,6833u16),(59255u16,6834u16),(59256u16,6835u16),(59257u16,6836u16), (59258u16,6837u16),(59259u16,6838u16),(59260u16,6839u16),(59261u16,7022u16), (59262u16,7023u16),(59263u16,7024u16),(59264u16,7025u16),(59265u16,7026u16), (59266u16,7027u16),(59267u16,7028u16),(59268u16,7029u16),(59269u16,7150u16), (59270u16,7151u16),(59271u16,7152u16),(59272u16,7153u16),(59273u16,7154u16), (59274u16,7155u16),(59275u16,7156u16),(59276u16,7157u16),(59287u16,7211u16), (59288u16,7212u16),(59289u16,7213u16),(59290u16,7214u16),(59291u16,7215u16), (59292u16,7216u16),(59293u16,7217u16),(59294u16,7218u16),(59295u16,7219u16), (59296u16,7349u16),(59297u16,7350u16),(59298u16,7351u16),(59299u16,7352u16), (59300u16,7353u16),(59301u16,7354u16),(59302u16,7355u16),(59303u16,7356u16), (59304u16,7357u16),(59305u16,7358u16),(59306u16,7359u16),(59307u16,7360u16), (59308u16,7361u16),(59309u16,7362u16),(59310u16,7363u16),(59311u16,7397u16), (59312u16,7398u16),(59313u16,7399u16),(59314u16,7400u16),(59315u16,7401u16), (59316u16,7402u16),(59317u16,7403u16),(59318u16,7404u16),(59319u16,7405u16), (59320u16,7406u16),(59321u16,7407u16),(59322u16,7408u16),(59323u16,7409u16), (59324u16,7495u16),(59325u16,7496u16),(59326u16,7497u16),(59327u16,7498u16), (59328u16,7499u16),(59329u16,7500u16),(59330u16,7501u16),(59331u16,7502u16), (59332u16,7503u16),(59333u16,7504u16),(59334u16,7505u16),(59337u16,7538u16), (59338u16,7539u16),(59339u16,7540u16),(59340u16,7541u16),(59341u16,7579u16), (59342u16,7580u16),(59343u16,7581u16),(59344u16,7582u16),(59345u16,7583u16), (59346u16,7584u16),(59347u16,7585u16),(59348u16,7586u16),(59349u16,7587u16), (59350u16,7588u16),(59351u16,7589u16),(59352u16,7590u16),(59353u16,7591u16), (59354u16,7592u16),(59355u16,7593u16),(59356u16,7594u16),(59357u16,7595u16), (59358u16,7596u16),(59359u16,7597u16),(59360u16,7598u16),(59361u16,7599u16), (59362u16,7624u16),(59363u16,7627u16),(59364u16,7629u16),(59365u16,7630u16), (59366u16,7631u16),(59380u16,7686u16),(59381u16,7687u16),(59382u16,7688u16), (59383u16,7689u16),(59384u16,7690u16),(59385u16,7691u16),(59386u16,7692u16), (59387u16,7693u16),(59388u16,7694u16),(59389u16,7695u16),(59390u16,7696u16), (59391u16,7697u16),(59392u16,7698u16),(59393u16,7775u16),(59394u16,7776u16), (59395u16,7777u16),(59396u16,7778u16),(59397u16,7779u16),(59398u16,7780u16), (59399u16,7781u16),(59400u16,7782u16),(59401u16,7783u16),(59402u16,7784u16), (59403u16,7785u16),(59404u16,7786u16),(59405u16,7787u16),(59406u16,7788u16), (59407u16,7789u16),(59408u16,16525u16),(59409u16,16526u16),(59410u16,16527u16), (59411u16,16528u16),(59412u16,16529u16),(59414u16,23767u16),(59415u16,23768u16), (59416u16,23769u16),(59441u16,23794u16),(59451u16,23804u16),(59477u16,23830u16), (63788u16,23651u16),(63865u16,23652u16),(63893u16,23653u16),(63975u16,23654u16), (63985u16,23655u16),(64012u16,23750u16),(64013u16,23751u16),(64014u16,23752u16), (64015u16,23753u16),(64017u16,23754u16),(64019u16,23755u16),(64020u16,23756u16), (64024u16,23757u16),(64031u16,23758u16),(64032u16,23759u16),(64033u16,23760u16), (64035u16,23761u16),(64036u16,23762u16),(64039u16,23763u16),(64040u16,23764u16), (64041u16,23765u16),(65040u16,7182u16),(65041u16,7184u16),(65042u16,7183u16), (65043u16,7185u16),(65044u16,7186u16),(65045u16,7187u16),(65046u16,7188u16), (65047u16,7201u16),(65048u16,7202u16),(65049u16,7208u16),(65072u16,7621u16), (65073u16,7207u16),(65075u16,7209u16),(65076u16,7210u16),(65077u16,7189u16), (65078u16,7190u16),(65079u16,7205u16),(65080u16,7206u16),(65081u16,7191u16), (65082u16,7192u16),(65083u16,7203u16),(65084u16,7204u16),(65085u16,7195u16), (65086u16,7196u16),(65087u16,7193u16),(65088u16,7194u16),(65089u16,7197u16), (65090u16,7198u16),(65091u16,7199u16),(65092u16,7200u16),(65097u16,7640u16), (65098u16,7641u16),(65099u16,7642u16),(65100u16,7643u16),(65101u16,7644u16), (65102u16,7645u16),(65103u16,7646u16),(65104u16,7647u16),(65105u16,7648u16), (65106u16,7649u16),(65108u16,7650u16),(65109u16,7651u16),(65110u16,7652u16), (65111u16,7653u16),(65113u16,7654u16),(65114u16,7655u16),(65115u16,7656u16), (65116u16,7657u16),(65117u16,7658u16),(65118u16,7659u16),(65119u16,7660u16), (65120u16,7661u16),(65121u16,7662u16),(65122u16,7663u16),(65123u16,7664u16), (65124u16,7665u16),(65125u16,7666u16),(65126u16,7667u16),(65128u16,7668u16), (65129u16,7669u16),(65130u16,7670u16),(65131u16,7671u16),(65281u16,6556u16), (65282u16,6557u16),(65283u16,6558u16),(65284u16,6246u16),(65285u16,6560u16), (65286u16,6561u16),(65287u16,6562u16),(65288u16,6563u16),(65289u16,6564u16), (65290u16,6565u16),(65291u16,6566u16),(65292u16,6567u16),(65293u16,6568u16), (65294u16,6569u16),(65295u16,6570u16),(65296u16,6571u16),(65297u16,6572u16), (65298u16,6573u16),(65299u16,6574u16),(65300u16,6575u16),(65301u16,6576u16), (65302u16,6577u16),(65303u16,6578u16),(65304u16,6579u16),(65305u16,6580u16), (65306u16,6581u16),(65307u16,6582u16),(65308u16,6583u16),(65309u16,6584u16), (65310u16,6585u16),(65311u16,6586u16),(65312u16,6587u16),(65313u16,6588u16), (65314u16,6589u16),(65315u16,6590u16),(65316u16,6591u16),(65317u16,6592u16), (65318u16,6593u16),(65319u16,6594u16),(65320u16,6595u16),(65321u16,6596u16), (65322u16,6597u16),(65323u16,6598u16),(65324u16,6599u16),(65325u16,6600u16), (65326u16,6601u16),(65327u16,6602u16),(65328u16,6603u16),(65329u16,6604u16), (65330u16,6605u16),(65331u16,6606u16),(65332u16,6607u16),(65333u16,6608u16), (65334u16,6609u16),(65335u16,6610u16),(65336u16,6611u16),(65337u16,6612u16), (65338u16,6613u16),(65339u16,6614u16),(65340u16,6615u16),(65341u16,6616u16), (65342u16,6617u16),(65343u16,6618u16),(65344u16,6619u16),(65345u16,6620u16), (65346u16,6621u16),(65347u16,6622u16),(65348u16,6623u16),(65349u16,6624u16), (65350u16,6625u16),(65351u16,6626u16),(65352u16,6627u16),(65353u16,6628u16), (65354u16,6629u16),(65355u16,6630u16),(65356u16,6631u16),(65357u16,6632u16), (65358u16,6633u16),(65359u16,6634u16),(65360u16,6635u16),(65361u16,6636u16), (65362u16,6637u16),(65363u16,6638u16),(65364u16,6639u16),(65365u16,6640u16), (65366u16,6641u16),(65367u16,6642u16),(65368u16,6643u16),(65369u16,6644u16), (65370u16,6645u16),(65371u16,6646u16),(65372u16,6647u16),(65373u16,6648u16), (65374u16,6186u16),(65504u16,6248u16),(65505u16,6249u16),(65506u16,7622u16), (65507u16,6649u16),(65508u16,7623u16),(65509u16,6559u16), ] const Jis0208Decode*: array[8096, uint16] = [ uint16 12288,12289,12290,65292,65294,12539,65306,65307,65311,65281,12443,12444, 180,65344,168,65342,65507,65343,12541,12542,12445,12446,12291,20189,12293,12294, 12295,12540,8213,8208,65295,65340,65374,8741,65372,8230,8229,8216,8217,8220, 8221,65288,65289,12308,12309,65339,65341,65371,65373,12296,12297,12298,12299, 12300,12301,12302,12303,12304,12305,65291,65293,177,215,247,65309,8800,65308, 65310,8806,8807,8734,8756,9794,9792,176,8242,8243,8451,65509,65284,65504,65505, 65285,65283,65286,65290,65312,167,9734,9733,9675,9679,9678,9671,9670,9633,9632, 9651,9650,9661,9660,8251,12306,8594,8592,8593,8595,12307,0,0,0,0,0,0,0,0,0,0,0, 8712,8715,8838,8839,8834,8835,8746,8745,0,0,0,0,0,0,0,0,8743,8744,65506,8658, 8660,8704,8707,0,0,0,0,0,0,0,0,0,0,0,8736,8869,8978,8706,8711,8801,8786,8810, 8811,8730,8765,8733,8757,8747,8748,0,0,0,0,0,0,0,8491,8240,9839,9837,9834,8224, 8225,182,0,0,0,0,9711,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65296,65297,65298,65299, 65300,65301,65302,65303,65304,65305,0,0,0,0,0,0,0,65313,65314,65315,65316,65317, 65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,65328,65329,65330, 65331,65332,65333,65334,65335,65336,65337,65338,0,0,0,0,0,0,65345,65346,65347, 65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360, 65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,0,0,0,0,12353,12354, 12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367, 12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380, 12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,12393, 12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,12406, 12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,12419, 12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,12432, 12433,12434,12435,0,0,0,0,0,0,0,0,0,0,0,12449,12450,12451,12452,12453,12454, 12455,12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,12467, 12468,12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,12480, 12481,12482,12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,12493, 12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506, 12507,12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519, 12520,12521,12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,12532, 12533,12534,0,0,0,0,0,0,0,0,913,914,915,916,917,918,919,920,921,922,923,924,925, 926,927,928,929,931,932,933,934,935,936,937,0,0,0,0,0,0,0,0,945,946,947,948,949, 950,951,952,953,954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1040, 1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055, 1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080, 1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096, 1097,1098,1099,1100,1101,1102,1103,0,0,0,0,0,0,0,0,0,0,0,0,0,9472,9474,9484, 9488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487,9491,9499,9495,9507,9523, 9515,9531,9547,9504,9519,9512,9527,9535,9501,9520,9509,9528,9538,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321, 9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,8544,8545,8546,8547,8548,8549, 8550,8551,8552,8553,0,13129,13076,13090,13133,13080,13095,13059,13110,13137, 13143,13069,13094,13091,13099,13130,13115,13212,13213,13214,13198,13199,13252, 13217,0,0,0,0,0,0,0,0,13179,12317,12319,8470,13261,8481,12964,12965,12966,12967, 12968,12849,12850,12857,13182,13181,13180,8786,8801,8747,8750,8721,8730,8869, 8736,8735,8895,8757,8745,8746,0,0,20124,21782,23043,38463,21696,24859,25384, 23030,36898,33909,33564,31312,24746,25569,28197,26093,33894,33446,39925,26771, 22311,26017,25201,23451,22992,34427,39156,32098,32190,39822,25110,31903,34999, 23433,24245,25353,26263,26696,38343,38797,26447,20197,20234,20301,20381,20553, 22258,22839,22996,23041,23561,24799,24847,24944,26131,26885,28858,30031,30064, 31227,32173,32239,32963,33806,34915,35586,36949,36986,21307,20117,20133,22495, 32946,37057,30959,19968,22769,28322,36920,31282,33576,33419,39983,20801,21360, 21693,21729,22240,23035,24341,39154,28139,32996,34093,38498,38512,38560,38907, 21515,21491,23431,28879,32701,36802,38632,21359,40284,31418,19985,30867,33276, 28198,22040,21764,27421,34074,39995,23013,21417,28006,29916,38287,22082,20113, 36939,38642,33615,39180,21473,21942,23344,24433,26144,26355,26628,27704,27891, 27945,29787,30408,31310,38964,33521,34907,35424,37613,28082,30123,30410,39365, 24742,35585,36234,38322,27022,21421,20870,22290,22576,22852,23476,24310,24616, 25513,25588,27839,28436,28814,28948,29017,29141,29503,32257,33398,33489,34199, 36960,37467,40219,22633,26044,27738,29989,20985,22830,22885,24448,24540,25276, 26106,27178,27431,27572,29579,32705,35158,40236,40206,40644,23713,27798,33659, 20740,23627,25014,33222,26742,29281,20057,20474,21368,24681,28201,31311,38899, 19979,21270,20206,20309,20285,20385,20339,21152,21487,22025,22799,23233,23478, 23521,31185,26247,26524,26550,27468,27827,28779,29634,31117,31166,31292,31623, 33457,33499,33540,33655,33775,33747,34662,35506,22057,36008,36838,36942,38686, 34442,20420,23784,25105,29273,30011,33253,33469,34558,36032,38597,39187,39381, 20171,20250,35299,22238,22602,22730,24315,24555,24618,24724,24674,25040,25106, 25296,25913,39745,26214,26800,28023,28784,30028,30342,32117,33445,34809,38283, 38542,35997,20977,21182,22806,21683,23475,23830,24936,27010,28079,30861,33995, 34903,35442,37799,39608,28012,39336,34521,22435,26623,34510,37390,21123,22151, 21508,24275,25313,25785,26684,26680,27579,29554,30906,31339,35226,35282,36203, 36611,37101,38307,38548,38761,23398,23731,27005,38989,38990,25499,31520,27179, 27263,26806,39949,28511,21106,21917,24688,25324,27963,28167,28369,33883,35088, 36676,19988,39993,21494,26907,27194,38788,26666,20828,31427,33970,37340,37772, 22107,40232,26658,33541,33841,31909,21000,33477,29926,20094,20355,20896,23506, 21002,21208,21223,24059,21914,22570,23014,23436,23448,23515,24178,24185,24739, 24863,24931,25022,25563,25954,26577,26707,26874,27454,27475,27735,28450,28567, 28485,29872,29976,30435,30475,31487,31649,31777,32233,32566,32752,32925,33382, 33694,35251,35532,36011,36996,37969,38291,38289,38306,38501,38867,39208,33304, 20024,21547,23736,24012,29609,30284,30524,23721,32747,36107,38593,38929,38996, 39000,20225,20238,21361,21916,22120,22522,22855,23305,23492,23696,24076,24190, 24524,25582,26426,26071,26082,26399,26827,26820,27231,24112,27589,27671,27773, 30079,31048,23395,31232,32000,24509,35215,35352,36020,36215,36556,36637,39138, 39438,39740,20096,20605,20736,22931,23452,25135,25216,25836,27450,29344,30097, 31047,32681,34811,35516,35696,25516,33738,38816,21513,21507,21931,26708,27224, 35440,30759,26485,40653,21364,23458,33050,34384,36870,19992,20037,20167,20241, 21450,21560,23470,24339,24613,25937,26429,27714,27762,27875,28792,29699,31350, 31406,31496,32026,31998,32102,26087,29275,21435,23621,24040,25298,25312,25369, 28192,34394,35377,36317,37624,28417,31142,39770,20136,20139,20140,20379,20384, 20689,20807,31478,20849,20982,21332,21281,21375,21483,21932,22659,23777,24375, 24394,24623,24656,24685,25375,25945,27211,27841,29378,29421,30703,33016,33029, 33288,34126,37111,37857,38911,39255,39514,20208,20957,23597,26241,26989,23616, 26354,26997,29577,26704,31873,20677,21220,22343,24062,37670,26020,27427,27453, 29748,31105,31165,31563,32202,33465,33740,34943,35167,35641,36817,37329,21535, 37504,20061,20534,21477,21306,29399,29590,30697,33510,36527,39366,39368,39378, 20855,24858,34398,21936,31354,20598,23507,36935,38533,20018,27355,37351,23633, 23624,25496,31391,27795,38772,36705,31402,29066,38536,31874,26647,32368,26705, 37740,21234,21531,34219,35347,32676,36557,37089,21350,34952,31041,20418,20670, 21009,20804,21843,22317,29674,22411,22865,24418,24452,24693,24950,24935,25001, 25522,25658,25964,26223,26690,28179,30054,31293,31995,32076,32153,32331,32619, 33550,33610,34509,35336,35427,35686,36605,38938,40335,33464,36814,39912,21127, 25119,25731,28608,38553,26689,20625,27424,27770,28500,31348,32080,34880,35363, 26376,20214,20537,20518,20581,20860,21048,21091,21927,22287,22533,23244,24314, 25010,25080,25331,25458,26908,27177,29309,29356,29486,30740,30831,32121,30476, 32937,35211,35609,36066,36562,36963,37749,38522,38997,39443,40568,20803,21407, 21427,24187,24358,28187,28304,29572,29694,32067,33335,35328,35578,38480,20046, 20491,21476,21628,22266,22993,23396,24049,24235,24359,25144,25925,26543,28246, 29392,31946,34996,32929,32993,33776,34382,35463,36328,37431,38599,39015,40723, 20116,20114,20237,21320,21577,21566,23087,24460,24481,24735,26791,27278,29786, 30849,35486,35492,35703,37264,20062,39881,20132,20348,20399,20505,20502,20809, 20844,21151,21177,21246,21402,21475,21521,21518,21897,22353,22434,22909,23380, 23389,23439,24037,24039,24055,24184,24195,24218,24247,24344,24658,24908,25239, 25304,25511,25915,26114,26179,26356,26477,26657,26775,27083,27743,27946,28009, 28207,28317,30002,30343,30828,31295,31968,32005,32024,32094,32177,32789,32771, 32943,32945,33108,33167,33322,33618,34892,34913,35611,36002,36092,37066,37237, 37489,30783,37628,38308,38477,38917,39321,39640,40251,21083,21163,21495,21512, 22741,25335,28640,35946,36703,40633,20811,21051,21578,22269,31296,37239,40288, 40658,29508,28425,33136,29969,24573,24794,39592,29403,36796,27492,38915,20170, 22256,22372,22718,23130,24680,25031,26127,26118,26681,26801,28151,30165,32058, 33390,39746,20123,20304,21449,21766,23919,24038,24046,26619,27801,29811,30722, 35408,37782,35039,22352,24231,25387,20661,20652,20877,26368,21705,22622,22971, 23472,24425,25165,25505,26685,27507,28168,28797,37319,29312,30741,30758,31085, 25998,32048,33756,35009,36617,38555,21092,22312,26448,32618,36001,20916,22338, 38442,22586,27018,32948,21682,23822,22524,30869,40442,20316,21066,21643,25662, 26152,26388,26613,31364,31574,32034,37679,26716,39853,31545,21273,20874,21047, 23519,25334,25774,25830,26413,27578,34217,38609,30352,39894,25420,37638,39851, 30399,26194,19977,20632,21442,23665,24808,25746,25955,26719,29158,29642,29987, 31639,32386,34453,35715,36059,37240,39184,26028,26283,27531,20181,20180,20282, 20351,21050,21496,21490,21987,22235,22763,22987,22985,23039,23376,23629,24066, 24107,24535,24605,25351,25903,23388,26031,26045,26088,26525,27490,27515,27663, 29509,31049,31169,31992,32025,32043,32930,33026,33267,35222,35422,35433,35430, 35468,35566,36039,36060,38604,39164,27503,20107,20284,20365,20816,23383,23546, 24904,25345,26178,27425,28363,27835,29246,29885,30164,30913,31034,32780,32819, 33258,33940,36766,27728,40575,24335,35672,40235,31482,36600,23437,38635,19971, 21489,22519,22833,23241,23460,24713,28287,28422,30142,36074,23455,34048,31712, 20594,26612,33437,23649,34122,32286,33294,20889,23556,25448,36198,26012,29038, 31038,32023,32773,35613,36554,36974,34503,37034,20511,21242,23610,26451,28796, 29237,37196,37320,37675,33509,23490,24369,24825,20027,21462,23432,25163,26417, 27530,29417,29664,31278,33131,36259,37202,39318,20754,21463,21610,23551,25480, 27193,32172,38656,22234,21454,21608,23447,23601,24030,20462,24833,25342,27954, 31168,31179,32066,32333,32722,33261,33311,33936,34886,35186,35728,36468,36655, 36913,37195,37228,38598,37276,20160,20303,20805,21313,24467,25102,26580,27713, 28171,29539,32294,37325,37507,21460,22809,23487,28113,31069,32302,31899,22654, 29087,20986,34899,36848,20426,23803,26149,30636,31459,33308,39423,20934,24490, 26092,26991,27529,28147,28310,28516,30462,32020,24033,36981,37255,38918,20966, 21021,25152,26257,26329,28186,24246,32210,32626,26360,34223,34295,35576,21161, 21465,22899,24207,24464,24661,37604,38500,20663,20767,21213,21280,21319,21484, 21736,21830,21809,22039,22888,22974,23100,23477,23558,23567,23569,23578,24196, 24202,24288,24432,25215,25220,25307,25484,25463,26119,26124,26157,26230,26494, 26786,27167,27189,27836,28040,28169,28248,28988,28966,29031,30151,30465,30813, 30977,31077,31216,31456,31505,31911,32057,32918,33750,33931,34121,34909,35059, 35359,35388,35412,35443,35937,36062,37284,37478,37758,37912,38556,38808,19978, 19976,19998,20055,20887,21104,22478,22580,22732,23330,24120,24773,25854,26465, 26454,27972,29366,30067,31331,33976,35698,37304,37664,22065,22516,39166,25325, 26893,27542,29165,32340,32887,33394,35302,39135,34645,36785,23611,20280,20449, 20405,21767,23072,23517,23529,24515,24910,25391,26032,26187,26862,27035,28024, 28145,30003,30137,30495,31070,31206,32051,33251,33455,34218,35242,35386,36523, 36763,36914,37341,38663,20154,20161,20995,22645,22764,23563,29978,23613,33102, 35338,36805,38499,38765,31525,35535,38920,37218,22259,21416,36887,21561,22402, 24101,25512,27700,28810,30561,31883,32736,34928,36930,37204,37648,37656,38543, 29790,39620,23815,23913,25968,26530,36264,38619,25454,26441,26905,33733,38935, 38592,35070,28548,25722,23544,19990,28716,30045,26159,20932,21046,21218,22995, 24449,24615,25104,25919,25972,26143,26228,26866,26646,27491,28165,29298,29983, 30427,31934,32854,22768,35069,35199,35488,35475,35531,36893,37266,38738,38745, 25993,31246,33030,38587,24109,24796,25114,26021,26132,26512,30707,31309,31821, 32318,33034,36012,36196,36321,36447,30889,20999,25305,25509,25666,25240,35373, 31363,31680,35500,38634,32118,33292,34633,20185,20808,21315,21344,23459,23554, 23574,24029,25126,25159,25776,26643,26676,27849,27973,27927,26579,28508,29006, 29053,26059,31359,31661,32218,32330,32680,33146,33307,33337,34214,35438,36046, 36341,36984,36983,37549,37521,38275,39854,21069,21892,28472,28982,20840,31109, 32341,33203,31950,22092,22609,23720,25514,26366,26365,26970,29401,30095,30094, 30990,31062,31199,31895,32032,32068,34311,35380,38459,36961,40736,20711,21109, 21452,21474,20489,21930,22766,22863,29245,23435,23652,21277,24803,24819,25436, 25475,25407,25531,25805,26089,26361,24035,27085,27133,28437,29157,20105,30185, 30456,31379,31967,32207,32156,32865,33609,33624,33900,33980,34299,35013,36208, 36865,36973,37783,38684,39442,20687,22679,24974,33235,34101,36104,36896,20419, 20596,21063,21363,24687,25417,26463,28204,36275,36895,20439,23646,36042,26063, 32154,21330,34966,20854,25539,23384,23403,23562,25613,26449,36956,20182,22810, 22826,27760,35409,21822,22549,22949,24816,25171,26561,33333,26965,38464,39364, 39464,20307,22534,23550,32784,23729,24111,24453,24608,24907,25140,26367,27888, 28382,32974,33151,33492,34955,36024,36864,36910,38538,40667,39899,20195,21488, 22823,31532,37261,38988,40441,28381,28711,21331,21828,23429,25176,25246,25299, 27810,28655,29730,35351,37944,28609,35582,33592,20967,34552,21482,21481,20294, 36948,36784,22890,33073,24061,31466,36799,26842,35895,29432,40008,27197,35504, 20025,21336,22022,22374,25285,25506,26086,27470,28129,28251,28845,30701,31471, 31658,32187,32829,32966,34507,35477,37723,22243,22727,24382,26029,26262,27264, 27573,30007,35527,20516,30693,22320,24347,24677,26234,27744,30196,31258,32622, 33268,34584,36933,39347,31689,30044,31481,31569,33988,36880,31209,31378,33590, 23265,30528,20013,20210,23449,24544,25277,26172,26609,27880,34411,34935,35387, 37198,37619,39376,27159,28710,29482,33511,33879,36015,19969,20806,20939,21899, 23541,24086,24115,24193,24340,24373,24427,24500,25074,25361,26274,26397,28526, 29266,30010,30522,32884,33081,33144,34678,35519,35548,36229,36339,37530,38263, 38914,40165,21189,25431,30452,26389,27784,29645,36035,37806,38515,27941,22684, 26894,27084,36861,37786,30171,36890,22618,26626,25524,27131,20291,28460,26584, 36795,34086,32180,37716,26943,28528,22378,22775,23340,32044,29226,21514,37347, 40372,20141,20302,20572,20597,21059,35998,21576,22564,23450,24093,24213,24237, 24311,24351,24716,25269,25402,25552,26799,27712,30855,31118,31243,32224,33351, 35330,35558,36420,36883,37048,37165,37336,40718,27877,25688,25826,25973,28404, 30340,31515,36969,37841,28346,21746,24505,25764,36685,36845,37444,20856,22635, 22825,23637,24215,28155,32399,29980,36028,36578,39003,28857,20253,27583,28593, 30000,38651,20814,21520,22581,22615,22956,23648,24466,26007,26460,28193,30331, 33759,36077,36884,37117,37709,30757,30778,21162,24230,22303,22900,24594,20498, 20826,20908,20941,20992,21776,22612,22616,22871,23445,23798,23947,24764,25237, 25645,26481,26691,26812,26847,30423,28120,28271,28059,28783,29128,24403,30168, 31095,31561,31572,31570,31958,32113,21040,33891,34153,34276,35342,35588,35910, 36367,36867,36879,37913,38518,38957,39472,38360,20685,21205,21516,22530,23566, 24999,25758,27934,30643,31461,33012,33796,36947,37509,23776,40199,21311,24471, 24499,28060,29305,30563,31167,31716,27602,29420,35501,26627,27233,20984,31361, 26932,23626,40182,33515,23493,37193,28702,22136,23663,24775,25958,27788,35930, 36929,38931,21585,26311,37389,22856,37027,20869,20045,20970,34201,35598,28760, 25466,37707,26978,39348,32260,30071,21335,26976,36575,38627,27741,20108,23612, 24336,36841,21250,36049,32905,34425,24319,26085,20083,20837,22914,23615,38894, 20219,22922,24525,35469,28641,31152,31074,23527,33905,29483,29105,24180,24565, 25467,25754,29123,31896,20035,24316,20043,22492,22178,24745,28611,32013,33021, 33075,33215,36786,35223,34468,24052,25226,25773,35207,26487,27874,27966,29750, 30772,23110,32629,33453,39340,20467,24259,25309,25490,25943,26479,30403,29260, 32972,32954,36649,37197,20493,22521,23186,26757,26995,29028,29437,36023,22770, 36064,38506,36889,34687,31204,30695,33833,20271,21093,21338,25293,26575,27850, 30333,31636,31893,33334,34180,36843,26333,28448,29190,32283,33707,39361,40614, 20989,31665,30834,31672,32903,31560,27368,24161,32908,30033,30048,20843,37474, 28300,30330,37271,39658,20240,32624,25244,31567,38309,40169,22138,22617,34532, 38588,20276,21028,21322,21453,21467,24070,25644,26001,26495,27710,27726,29256, 29359,29677,30036,32321,33324,34281,36009,31684,37318,29033,38930,39151,25405, 26217,30058,30436,30928,34115,34542,21290,21329,21542,22915,24199,24444,24754, 25161,25209,25259,26000,27604,27852,30130,30382,30865,31192,32203,32631,32933, 34987,35513,36027,36991,38750,39131,27147,31800,20633,23614,24494,26503,27608, 29749,30473,32654,40763,26570,31255,21305,30091,39661,24422,33181,33777,32920, 24380,24517,30050,31558,36924,26727,23019,23195,32016,30334,35628,20469,24426, 27161,27703,28418,29922,31080,34920,35413,35961,24287,25551,30149,31186,33495, 37672,37618,33948,34541,39981,21697,24428,25996,27996,28693,36007,36051,38971, 25935,29942,19981,20184,22496,22827,23142,23500,20904,24067,24220,24598,25206, 25975,26023,26222,28014,29238,31526,33104,33178,33433,35676,36000,36070,36212, 38428,38468,20398,25771,27494,33310,33889,34154,37096,23553,26963,39080,33914, 34135,20239,21103,24489,24133,26381,31119,33145,35079,35206,28149,24343,25173, 27832,20175,29289,39826,20998,21563,22132,22707,24996,25198,28954,22894,31881, 31966,32027,38640,25991,32862,19993,20341,20853,22592,24163,24179,24330,26564, 20006,34109,38281,38491,31859,38913,20731,22721,30294,30887,21029,30629,34065, 31622,20559,22793,29255,31687,32232,36794,36820,36941,20415,21193,23081,24321, 38829,20445,33303,37610,22275,25429,27497,29995,35036,36628,31298,21215,22675, 24917,25098,26286,27597,31807,33769,20515,20472,21253,21574,22577,22857,23453, 23792,23791,23849,24214,25265,25447,25918,26041,26379,27861,27873,28921,30770, 32299,32990,33459,33804,34028,34562,35090,35370,35914,37030,37586,39165,40179, 40300,20047,20129,20621,21078,22346,22952,24125,24536,24537,25151,26292,26395, 26576,26834,20882,32033,32938,33192,35584,35980,36031,37502,38450,21536,38956, 21271,20693,21340,22696,25778,26420,29287,30566,31302,37350,21187,27809,27526, 22528,24140,22868,26412,32763,20961,30406,25705,30952,39764,40635,22475,22969, 26151,26522,27598,21737,27097,24149,33180,26517,39850,26622,40018,26717,20134, 20451,21448,25273,26411,27819,36804,20397,32365,40639,19975,24930,28288,28459, 34067,21619,26410,39749,24051,31637,23724,23494,34588,28234,34001,31252,33032, 22937,31885,27665,30496,21209,22818,28961,29279,30683,38695,40289,26891,23167, 23064,20901,21517,21629,26126,30431,36855,37528,40180,23018,29277,28357,20813, 26825,32191,32236,38754,40634,25720,27169,33538,22916,23391,27611,29467,30450, 32178,32791,33945,20786,26408,40665,30446,26466,21247,39173,23588,25147,31870, 36016,21839,24758,32011,38272,21249,20063,20918,22812,29242,32822,37326,24357, 30690,21380,24441,32004,34220,35379,36493,38742,26611,34222,37971,24841,24840, 27833,30290,35565,36664,21807,20305,20778,21191,21451,23461,24189,24736,24962, 25558,26377,26586,28263,28044,29494,29495,30001,31056,35029,35480,36938,37009, 37109,38596,34701,22805,20104,20313,19982,35465,36671,38928,20653,24188,22934, 23481,24248,25562,25594,25793,26332,26954,27096,27915,28342,29076,29992,31407, 32650,32768,33865,33993,35201,35617,36362,36965,38525,39178,24958,25233,27442, 27779,28020,32716,32764,28096,32645,34746,35064,26469,33713,38972,38647,27931, 32097,33853,37226,20081,21365,23888,27396,28651,34253,34349,35239,21033,21519, 23653,26446,26792,29702,29827,30178,35023,35041,37324,38626,38520,24459,29575, 31435,33870,25504,30053,21129,27969,28316,29705,30041,30827,31890,38534,31452, 40845,20406,24942,26053,34396,20102,20142,20698,20001,20940,23534,26009,26753, 28092,29471,30274,30637,31260,31975,33391,35538,36988,37327,38517,38936,21147, 32209,20523,21400,26519,28107,29136,29747,33256,36650,38563,40023,40607,29792, 22593,28057,32047,39006,20196,20278,20363,20919,21169,23994,24604,29618,31036, 33491,37428,38583,38646,38666,40599,40802,26278,27508,21015,21155,28872,35010, 24265,24651,24976,28451,29001,31806,32244,32879,34030,36899,37676,21570,39791, 27347,28809,36034,36335,38706,21172,23105,24266,24324,26391,27004,27028,28010, 28431,29282,29436,31725,32769,32894,34635,37070,20845,40595,31108,32907,37682, 35542,20525,21644,35441,27498,36036,33031,24785,26528,40434,20121,20120,39952, 35435,34241,34152,26880,28286,30871,33109,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24332,19984,19989,20010,20017, 20022,20028,20031,20034,20054,20056,20098,20101,35947,20106,33298,24333,20110, 20126,20127,20128,20130,20144,20147,20150,20174,20173,20164,20166,20162,20183, 20190,20205,20191,20215,20233,20314,20272,20315,20317,20311,20295,20342,20360, 20367,20376,20347,20329,20336,20369,20335,20358,20374,20760,20436,20447,20430, 20440,20443,20433,20442,20432,20452,20453,20506,20520,20500,20522,20517,20485, 20252,20470,20513,20521,20524,20478,20463,20497,20486,20547,20551,26371,20565, 20560,20552,20570,20566,20588,20600,20608,20634,20613,20660,20658,20681,20682, 20659,20674,20694,20702,20709,20717,20707,20718,20729,20725,20745,20737,20738, 20758,20757,20756,20762,20769,20794,20791,20796,20795,20799,20800,20818,20812, 20820,20834,31480,20841,20842,20846,20864,20866,22232,20876,20873,20879,20881, 20883,20885,20886,20900,20902,20898,20905,20906,20907,20915,20913,20914,20912, 20917,20925,20933,20937,20955,20960,34389,20969,20973,20976,20981,20990,20996, 21003,21012,21006,21031,21034,21038,21043,21049,21071,21060,21067,21068,21086, 21076,21098,21108,21097,21107,21119,21117,21133,21140,21138,21105,21128,21137, 36776,36775,21164,21165,21180,21173,21185,21197,21207,21214,21219,21222,39149, 21216,21235,21237,21240,21241,21254,21256,30008,21261,21264,21263,21269,21274, 21283,21295,21297,21299,21304,21312,21318,21317,19991,21321,21325,20950,21342, 21353,21358,22808,21371,21367,21378,21398,21408,21414,21413,21422,21424,21430, 21443,31762,38617,21471,26364,29166,21486,21480,21485,21498,21505,21565,21568, 21548,21549,21564,21550,21558,21545,21533,21582,21647,21621,21646,21599,21617, 21623,21616,21650,21627,21632,21622,21636,21648,21638,21703,21666,21688,21669, 21676,21700,21704,21672,21675,21698,21668,21694,21692,21720,21733,21734,21775, 21780,21757,21742,21741,21754,21730,21817,21824,21859,21836,21806,21852,21829, 21846,21847,21816,21811,21853,21913,21888,21679,21898,21919,21883,21886,21912, 21918,21934,21884,21891,21929,21895,21928,21978,21957,21983,21956,21980,21988, 21972,22036,22007,22038,22014,22013,22043,22009,22094,22096,29151,22068,22070, 22066,22072,22123,22116,22063,22124,22122,22150,22144,22154,22176,22164,22159, 22181,22190,22198,22196,22210,22204,22209,22211,22208,22216,22222,22225,22227, 22231,22254,22265,22272,22271,22276,22281,22280,22283,22285,22291,22296,22294, 21959,22300,22310,22327,22328,22350,22331,22336,22351,22377,22464,22408,22369, 22399,22409,22419,22432,22451,22436,22442,22448,22467,22470,22484,22482,22483, 22538,22486,22499,22539,22553,22557,22642,22561,22626,22603,22640,27584,22610, 22589,22649,22661,22713,22687,22699,22714,22750,22715,22712,22702,22725,22739, 22737,22743,22745,22744,22757,22748,22756,22751,22767,22778,22777,22779,22780, 22781,22786,22794,22800,22811,26790,22821,22828,22829,22834,22840,22846,31442, 22869,22864,22862,22874,22872,22882,22880,22887,22892,22889,22904,22913,22941, 20318,20395,22947,22962,22982,23016,23004,22925,23001,23002,23077,23071,23057, 23068,23049,23066,23104,23148,23113,23093,23094,23138,23146,23194,23228,23230, 23243,23234,23229,23267,23255,23270,23273,23254,23290,23291,23308,23307,23318, 23346,23248,23338,23350,23358,23363,23365,23360,23377,23381,23386,23387,23397, 23401,23408,23411,23413,23416,25992,23418,23424,23427,23462,23480,23491,23495, 23497,23508,23504,23524,23526,23522,23518,23525,23531,23536,23542,23539,23557, 23559,23560,23565,23571,23584,23586,23592,23608,23609,23617,23622,23630,23635, 23632,23631,23409,23660,23662,20066,23670,23673,23692,23697,23700,22939,23723, 23739,23734,23740,23735,23749,23742,23751,23769,23785,23805,23802,23789,23948, 23786,23819,23829,23831,23900,23839,23835,23825,23828,23842,23834,23833,23832, 23884,23890,23886,23883,23916,23923,23926,23943,23940,23938,23970,23965,23980, 23982,23997,23952,23991,23996,24009,24013,24019,24018,24022,24027,24043,24050, 24053,24075,24090,24089,24081,24091,24118,24119,24132,24131,24128,24142,24151, 24148,24159,24162,24164,24135,24181,24182,24186,40636,24191,24224,24257,24258, 24264,24272,24271,24278,24291,24285,24282,24283,24290,24289,24296,24297,24300, 24305,24307,24304,24308,24312,24318,24323,24329,24413,24412,24331,24337,24342, 24361,24365,24376,24385,24392,24396,24398,24367,24401,24406,24407,24409,24417, 24429,24435,24439,24451,24450,24447,24458,24456,24465,24455,24478,24473,24472, 24480,24488,24493,24508,24534,24571,24548,24568,24561,24541,24755,24575,24609, 24672,24601,24592,24617,24590,24625,24603,24597,24619,24614,24591,24634,24666, 24641,24682,24695,24671,24650,24646,24653,24675,24643,24676,24642,24684,24683, 24665,24705,24717,24807,24707,24730,24708,24731,24726,24727,24722,24743,24715, 24801,24760,24800,24787,24756,24560,24765,24774,24757,24792,24909,24853,24838, 24822,24823,24832,24820,24826,24835,24865,24827,24817,24845,24846,24903,24894, 24872,24871,24906,24895,24892,24876,24884,24893,24898,24900,24947,24951,24920, 24921,24922,24939,24948,24943,24933,24945,24927,24925,24915,24949,24985,24982, 24967,25004,24980,24986,24970,24977,25003,25006,25036,25034,25033,25079,25032, 25027,25030,25018,25035,32633,25037,25062,25059,25078,25082,25076,25087,25085, 25084,25086,25088,25096,25097,25101,25100,25108,25115,25118,25121,25130,25134, 25136,25138,25139,25153,25166,25182,25187,25179,25184,25192,25212,25218,25225, 25214,25234,25235,25238,25300,25219,25236,25303,25297,25275,25295,25343,25286, 25812,25288,25308,25292,25290,25282,25287,25243,25289,25356,25326,25329,25383, 25346,25352,25327,25333,25424,25406,25421,25628,25423,25494,25486,25472,25515, 25462,25507,25487,25481,25503,25525,25451,25449,25534,25577,25536,25542,25571, 25545,25554,25590,25540,25622,25652,25606,25619,25638,25654,25885,25623,25640, 25615,25703,25711,25718,25678,25898,25749,25747,25765,25769,25736,25788,25818, 25810,25797,25799,25787,25816,25794,25841,25831,33289,25824,25825,25260,25827, 25839,25900,25846,25844,25842,25850,25856,25853,25880,25884,25861,25892,25891, 25899,25908,25909,25911,25910,25912,30027,25928,25942,25941,25933,25944,25950, 25949,25970,25976,25986,25987,35722,26011,26015,26027,26039,26051,26054,26049, 26052,26060,26066,26075,26073,26080,26081,26097,26482,26122,26115,26107,26483, 26165,26166,26164,26140,26191,26180,26185,26177,26206,26205,26212,26215,26216, 26207,26210,26224,26243,26248,26254,26249,26244,26264,26269,26305,26297,26313, 26302,26300,26308,26296,26326,26330,26336,26175,26342,26345,26352,26357,26359, 26383,26390,26398,26406,26407,38712,26414,26431,26422,26433,26424,26423,26438, 26462,26464,26457,26467,26468,26505,26480,26537,26492,26474,26508,26507,26534, 26529,26501,26551,26607,26548,26604,26547,26601,26552,26596,26590,26589,26594, 26606,26553,26574,26566,26599,27292,26654,26694,26665,26688,26701,26674,26702, 26803,26667,26713,26723,26743,26751,26783,26767,26797,26772,26781,26779,26755, 27310,26809,26740,26805,26784,26810,26895,26765,26750,26881,26826,26888,26840, 26914,26918,26849,26892,26829,26836,26855,26837,26934,26898,26884,26839,26851, 26917,26873,26848,26863,26920,26922,26906,26915,26913,26822,27001,26999,26972, 27000,26987,26964,27006,26990,26937,26996,26941,26969,26928,26977,26974,26973, 27009,26986,27058,27054,27088,27071,27073,27091,27070,27086,23528,27082,27101, 27067,27075,27047,27182,27025,27040,27036,27029,27060,27102,27112,27138,27163, 27135,27402,27129,27122,27111,27141,27057,27166,27117,27156,27115,27146,27154, 27329,27171,27155,27204,27148,27250,27190,27256,27207,27234,27225,27238,27208, 27192,27170,27280,27277,27296,27268,27298,27299,27287,34327,27323,27331,27330, 27320,27315,27308,27358,27345,27359,27306,27354,27370,27387,27397,34326,27386, 27410,27414,39729,27423,27448,27447,30428,27449,39150,27463,27459,27465,27472, 27481,27476,27483,27487,27489,27512,27513,27519,27520,27524,27523,27533,27544, 27541,27550,27556,27562,27563,27567,27570,27569,27571,27575,27580,27590,27595, 27603,27615,27628,27627,27635,27631,40638,27656,27667,27668,27675,27684,27683, 27742,27733,27746,27754,27778,27789,27802,27777,27803,27774,27752,27763,27794, 27792,27844,27889,27859,27837,27863,27845,27869,27822,27825,27838,27834,27867, 27887,27865,27882,27935,34893,27958,27947,27965,27960,27929,27957,27955,27922, 27916,28003,28051,28004,27994,28025,27993,28046,28053,28644,28037,28153,28181, 28170,28085,28103,28134,28088,28102,28140,28126,28108,28136,28114,28101,28154, 28121,28132,28117,28138,28142,28205,28270,28206,28185,28274,28255,28222,28195, 28267,28203,28278,28237,28191,28227,28218,28238,28196,28415,28189,28216,28290, 28330,28312,28361,28343,28371,28349,28335,28356,28338,28372,28373,28303,28325, 28354,28319,28481,28433,28748,28396,28408,28414,28479,28402,28465,28399,28466, 28364,28478,28435,28407,28550,28538,28536,28545,28544,28527,28507,28659,28525, 28546,28540,28504,28558,28561,28610,28518,28595,28579,28577,28580,28601,28614, 28586,28639,28629,28652,28628,28632,28657,28654,28635,28681,28683,28666,28689, 28673,28687,28670,28699,28698,28532,28701,28696,28703,28720,28734,28722,28753, 28771,28825,28818,28847,28913,28844,28856,28851,28846,28895,28875,28893,28889, 28937,28925,28956,28953,29029,29013,29064,29030,29026,29004,29014,29036,29071, 29179,29060,29077,29096,29100,29143,29113,29118,29138,29129,29140,29134,29152, 29164,29159,29173,29180,29177,29183,29197,29200,29211,29224,29229,29228,29232, 29234,29243,29244,29247,29248,29254,29259,29272,29300,29310,29314,29313,29319, 29330,29334,29346,29351,29369,29362,29379,29382,29380,29390,29394,29410,29408, 29409,29433,29431,20495,29463,29450,29468,29462,29469,29492,29487,29481,29477, 29502,29518,29519,40664,29527,29546,29544,29552,29560,29557,29563,29562,29640, 29619,29646,29627,29632,29669,29678,29662,29858,29701,29807,29733,29688,29746, 29754,29781,29759,29791,29785,29761,29788,29801,29808,29795,29802,29814,29822, 29835,29854,29863,29898,29903,29908,29681,29920,29923,29927,29929,29934,29938, 29936,29937,29944,29943,29956,29955,29957,29964,29966,29965,29973,29971,29982, 29990,29996,30012,30020,30029,30026,30025,30043,30022,30042,30057,30052,30055, 30059,30061,30072,30070,30086,30087,30068,30090,30089,30082,30100,30106,30109, 30117,30115,30146,30131,30147,30133,30141,30136,30140,30129,30157,30154,30162, 30169,30179,30174,30206,30207,30204,30209,30192,30202,30194,30195,30219,30221, 30217,30239,30247,30240,30241,30242,30244,30260,30256,30267,30279,30280,30278, 30300,30296,30305,30306,30312,30313,30314,30311,30316,30320,30322,30326,30328, 30332,30336,30339,30344,30347,30350,30358,30355,30361,30362,30384,30388,30392, 30393,30394,30402,30413,30422,30418,30430,30433,30437,30439,30442,34351,30459, 30472,30471,30468,30505,30500,30494,30501,30502,30491,30519,30520,30535,30554, 30568,30571,30555,30565,30591,30590,30585,30606,30603,30609,30624,30622,30640, 30646,30649,30655,30652,30653,30651,30663,30669,30679,30682,30684,30691,30702, 30716,30732,30738,31014,30752,31018,30789,30862,30836,30854,30844,30874,30860, 30883,30901,30890,30895,30929,30918,30923,30932,30910,30908,30917,30922,30956, 30951,30938,30973,30964,30983,30994,30993,31001,31020,31019,31040,31072,31063, 31071,31066,31061,31059,31098,31103,31114,31133,31143,40779,31146,31150,31155, 31161,31162,31177,31189,31207,31212,31201,31203,31240,31245,31256,31257,31264, 31263,31104,31281,31291,31294,31287,31299,31319,31305,31329,31330,31337,40861, 31344,31353,31357,31368,31383,31381,31384,31382,31401,31432,31408,31414,31429, 31428,31423,36995,31431,31434,31437,31439,31445,31443,31449,31450,31453,31457, 31458,31462,31469,31472,31490,31503,31498,31494,31539,31512,31513,31518,31541, 31528,31542,31568,31610,31492,31565,31499,31564,31557,31605,31589,31604,31591, 31600,31601,31596,31598,31645,31640,31647,31629,31644,31642,31627,31634,31631, 31581,31641,31691,31681,31692,31695,31668,31686,31709,31721,31761,31764,31718, 31717,31840,31744,31751,31763,31731,31735,31767,31757,31734,31779,31783,31786, 31775,31799,31787,31805,31820,31811,31828,31823,31808,31824,31832,31839,31844, 31830,31845,31852,31861,31875,31888,31908,31917,31906,31915,31905,31912,31923, 31922,31921,31918,31929,31933,31936,31941,31938,31960,31954,31964,31970,39739, 31983,31986,31988,31990,31994,32006,32002,32028,32021,32010,32069,32075,32046, 32050,32063,32053,32070,32115,32086,32078,32114,32104,32110,32079,32099,32147, 32137,32091,32143,32125,32155,32186,32174,32163,32181,32199,32189,32171,32317, 32162,32175,32220,32184,32159,32176,32216,32221,32228,32222,32251,32242,32225, 32261,32266,32291,32289,32274,32305,32287,32265,32267,32290,32326,32358,32315, 32309,32313,32323,32311,32306,32314,32359,32349,32342,32350,32345,32346,32377, 32362,32361,32380,32379,32387,32213,32381,36782,32383,32392,32393,32396,32402, 32400,32403,32404,32406,32398,32411,32412,32568,32570,32581,32588,32589,32590, 32592,32593,32597,32596,32600,32607,32608,32616,32617,32615,32632,32642,32646, 32643,32648,32647,32652,32660,32670,32669,32666,32675,32687,32690,32697,32686, 32694,32696,35697,32709,32710,32714,32725,32724,32737,32742,32745,32755,32761, 39132,32774,32772,32779,32786,32792,32793,32796,32801,32808,32831,32827,32842, 32838,32850,32856,32858,32863,32866,32872,32883,32882,32880,32886,32889,32893, 32895,32900,32902,32901,32923,32915,32922,32941,20880,32940,32987,32997,32985, 32989,32964,32986,32982,33033,33007,33009,33051,33065,33059,33071,33099,38539, 33094,33086,33107,33105,33020,33137,33134,33125,33126,33140,33155,33160,33162, 33152,33154,33184,33173,33188,33187,33119,33171,33193,33200,33205,33214,33208, 33213,33216,33218,33210,33225,33229,33233,33241,33240,33224,33242,33247,33248, 33255,33274,33275,33278,33281,33282,33285,33287,33290,33293,33296,33302,33321, 33323,33336,33331,33344,33369,33368,33373,33370,33375,33380,33378,33384,33386, 33387,33326,33393,33399,33400,33406,33421,33426,33451,33439,33467,33452,33505, 33507,33503,33490,33524,33523,33530,33683,33539,33531,33529,33502,33542,33500, 33545,33497,33589,33588,33558,33586,33585,33600,33593,33616,33605,33583,33579, 33559,33560,33669,33690,33706,33695,33698,33686,33571,33678,33671,33674,33660, 33717,33651,33653,33696,33673,33704,33780,33811,33771,33742,33789,33795,33752, 33803,33729,33783,33799,33760,33778,33805,33826,33824,33725,33848,34054,33787, 33901,33834,33852,34138,33924,33911,33899,33965,33902,33922,33897,33862,33836, 33903,33913,33845,33994,33890,33977,33983,33951,34009,33997,33979,34010,34000, 33985,33990,34006,33953,34081,34047,34036,34071,34072,34092,34079,34069,34068, 34044,34112,34147,34136,34120,34113,34306,34123,34133,34176,34212,34184,34193, 34186,34216,34157,34196,34203,34282,34183,34204,34167,34174,34192,34249,34234, 34255,34233,34256,34261,34269,34277,34268,34297,34314,34323,34315,34302,34298, 34310,34338,34330,34352,34367,34381,20053,34388,34399,34407,34417,34451,34467, 34473,34474,34443,34444,34486,34479,34500,34502,34480,34505,34851,34475,34516, 34526,34537,34540,34527,34523,34543,34578,34566,34568,34560,34563,34555,34577, 34569,34573,34553,34570,34612,34623,34615,34619,34597,34601,34586,34656,34655, 34680,34636,34638,34676,34647,34664,34670,34649,34643,34659,34666,34821,34722, 34719,34690,34735,34763,34749,34752,34768,38614,34731,34756,34739,34759,34758, 34747,34799,34802,34784,34831,34829,34814,34806,34807,34830,34770,34833,34838, 34837,34850,34849,34865,34870,34873,34855,34875,34884,34882,34898,34905,34910, 34914,34923,34945,34942,34974,34933,34941,34997,34930,34946,34967,34962,34990, 34969,34978,34957,34980,34992,35007,34993,35011,35012,35028,35032,35033,35037, 35065,35074,35068,35060,35048,35058,35076,35084,35082,35091,35139,35102,35109, 35114,35115,35137,35140,35131,35126,35128,35148,35101,35168,35166,35174,35172, 35181,35178,35183,35188,35191,35198,35203,35208,35210,35219,35224,35233,35241, 35238,35244,35247,35250,35258,35261,35263,35264,35290,35292,35293,35303,35316, 35320,35331,35350,35344,35340,35355,35357,35365,35382,35393,35419,35410,35398, 35400,35452,35437,35436,35426,35461,35458,35460,35496,35489,35473,35493,35494, 35482,35491,35524,35533,35522,35546,35563,35571,35559,35556,35569,35604,35552, 35554,35575,35550,35547,35596,35591,35610,35553,35606,35600,35607,35616,35635, 38827,35622,35627,35646,35624,35649,35660,35663,35662,35657,35670,35675,35674, 35691,35679,35692,35695,35700,35709,35712,35724,35726,35730,35731,35734,35737, 35738,35898,35905,35903,35912,35916,35918,35920,35925,35938,35948,35960,35962, 35970,35977,35973,35978,35981,35982,35988,35964,35992,25117,36013,36010,36029, 36018,36019,36014,36022,36040,36033,36068,36067,36058,36093,36090,36091,36100, 36101,36106,36103,36111,36109,36112,40782,36115,36045,36116,36118,36199,36205, 36209,36211,36225,36249,36290,36286,36282,36303,36314,36310,36300,36315,36299, 36330,36331,36319,36323,36348,36360,36361,36351,36381,36382,36368,36383,36418, 36405,36400,36404,36426,36423,36425,36428,36432,36424,36441,36452,36448,36394, 36451,36437,36470,36466,36476,36481,36487,36485,36484,36491,36490,36499,36497, 36500,36505,36522,36513,36524,36528,36550,36529,36542,36549,36552,36555,36571, 36579,36604,36603,36587,36606,36618,36613,36629,36626,36633,36627,36636,36639, 36635,36620,36646,36659,36667,36665,36677,36674,36670,36684,36681,36678,36686, 36695,36700,36706,36707,36708,36764,36767,36771,36781,36783,36791,36826,36837, 36834,36842,36847,36999,36852,36869,36857,36858,36881,36885,36897,36877,36894, 36886,36875,36903,36918,36917,36921,36856,36943,36944,36945,36946,36878,36937, 36926,36950,36952,36958,36968,36975,36982,38568,36978,36994,36989,36993,36992, 37002,37001,37007,37032,37039,37041,37045,37090,37092,25160,37083,37122,37138, 37145,37170,37168,37194,37206,37208,37219,37221,37225,37235,37234,37259,37257, 37250,37282,37291,37295,37290,37301,37300,37306,37312,37313,37321,37323,37328, 37334,37343,37345,37339,37372,37365,37366,37406,37375,37396,37420,37397,37393, 37470,37463,37445,37449,37476,37448,37525,37439,37451,37456,37532,37526,37523, 37531,37466,37583,37561,37559,37609,37647,37626,37700,37678,37657,37666,37658, 37667,37690,37685,37691,37724,37728,37756,37742,37718,37808,37804,37805,37780, 37817,37846,37847,37864,37861,37848,37827,37853,37840,37832,37860,37914,37908, 37907,37891,37895,37904,37942,37931,37941,37921,37946,37953,37970,37956,37979, 37984,37986,37982,37994,37417,38000,38005,38007,38013,37978,38012,38014,38017, 38015,38274,38279,38282,38292,38294,38296,38297,38304,38312,38311,38317,38332, 38331,38329,38334,38346,28662,38339,38349,38348,38357,38356,38358,38364,38369, 38373,38370,38433,38440,38446,38447,38466,38476,38479,38475,38519,38492,38494, 38493,38495,38502,38514,38508,38541,38552,38549,38551,38570,38567,38577,38578, 38576,38580,38582,38584,38585,38606,38603,38601,38605,35149,38620,38669,38613, 38649,38660,38662,38664,38675,38670,38673,38671,38678,38681,38692,38698,38704, 38713,38717,38718,38724,38726,38728,38722,38729,38748,38752,38756,38758,38760, 21202,38763,38769,38777,38789,38780,38785,38778,38790,38795,38799,38800,38812, 38824,38822,38819,38835,38836,38851,38854,38856,38859,38876,38893,40783,38898, 31455,38902,38901,38927,38924,38968,38948,38945,38967,38973,38982,38991,38987, 39019,39023,39024,39025,39028,39027,39082,39087,39089,39094,39108,39107,39110, 39145,39147,39171,39177,39186,39188,39192,39201,39197,39198,39204,39200,39212, 39214,39229,39230,39234,39241,39237,39248,39243,39249,39250,39244,39253,39319, 39320,39333,39341,39342,39356,39391,39387,39389,39384,39377,39405,39406,39409, 39410,39419,39416,39425,39439,39429,39394,39449,39467,39479,39493,39490,39488, 39491,39486,39509,39501,39515,39511,39519,39522,39525,39524,39529,39531,39530, 39597,39600,39612,39616,39631,39633,39635,39636,39646,39647,39650,39651,39654, 39663,39659,39662,39668,39665,39671,39675,39686,39704,39706,39711,39714,39715, 39717,39719,39720,39721,39722,39726,39727,39730,39748,39747,39759,39757,39758, 39761,39768,39796,39827,39811,39825,39830,39831,39839,39840,39848,39860,39872, 39882,39865,39878,39887,39889,39890,39907,39906,39908,39892,39905,39994,39922, 39921,39920,39957,39956,39945,39955,39948,39942,39944,39954,39946,39940,39982, 39963,39973,39972,39969,39984,40007,39986,40006,39998,40026,40032,40039,40054, 40056,40167,40172,40176,40201,40200,40171,40195,40198,40234,40230,40367,40227, 40223,40260,40213,40210,40257,40255,40254,40262,40264,40285,40286,40292,40273, 40272,40281,40306,40329,40327,40363,40303,40314,40346,40356,40361,40370,40388, 40385,40379,40376,40378,40390,40399,40386,40409,40403,40440,40422,40429,40431, 40445,40474,40475,40478,40565,40569,40573,40577,40584,40587,40588,40594,40597, 40593,40605,40613,40617,40632,40618,40621,38753,40652,40654,40655,40656,40660, 40668,40670,40669,40672,40677,40680,40687,40692,40694,40695,40697,40699,40700, 40701,40711,40712,30391,40725,40737,40748,40766,40778,40786,40788,40803,40799, 40800,40801,40806,40807,40812,40810,40823,40818,40822,40853,40860,40864,22575, 27079,36953,29796,20956,29081,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32394,35100,37704,37512,34012, 20425,28859,26161,26824,37625,26363,24389,20008,20193,20220,20224,20227,20281, 20310,20370,20362,20378,20372,20429,20544,20514,20479,20510,20550,20592,20546, 20628,20724,20696,20810,20836,20893,20926,20972,21013,21148,21158,21184,21211, 21248,21255,21284,21362,21395,21426,21469,64014,21660,21642,21673,21759,21894, 22361,22373,22444,22472,22471,64015,64016,22686,22706,22795,22867,22875,22877, 22883,22948,22970,23382,23488,29999,23512,23532,23582,23718,23738,23797,23847, 23891,64017,23874,23917,23992,23993,24016,24353,24372,24423,24503,24542,24669, 24709,24714,24798,24789,24864,24818,24849,24887,24880,24984,25107,25254,25589, 25696,25757,25806,25934,26112,26133,26171,26121,26158,26142,26148,26213,26199, 26201,64018,26227,26265,26272,26290,26303,26362,26382,63785,26470,26555,26706, 26560,26625,26692,26831,64019,26984,64020,27032,27106,27184,27243,27206,27251, 27262,27362,27364,27606,27711,27740,27782,27759,27866,27908,28039,28015,28054, 28076,28111,28152,28146,28156,28217,28252,28199,28220,28351,28552,28597,28661, 28677,28679,28712,28805,28843,28943,28932,29020,28998,28999,64021,29121,29182, 29361,29374,29476,64022,29559,29629,29641,29654,29667,29650,29703,29685,29734, 29738,29737,29742,29794,29833,29855,29953,30063,30338,30364,30366,30363,30374, 64023,30534,21167,30753,30798,30820,30842,31024,64024,64025,64026,31124,64027, 31131,31441,31463,64028,31467,31646,64029,32072,32092,32183,32160,32214,32338, 32583,32673,64030,33537,33634,33663,33735,33782,33864,33972,34131,34137,34155, 64031,34224,64032,64033,34823,35061,35346,35383,35449,35495,35518,35551,64034, 35574,35667,35711,36080,36084,36114,36214,64035,36559,64036,64037,36967,37086, 64038,37141,37159,37338,37335,37342,37357,37358,37348,37349,37382,37392,37386, 37434,37440,37436,37454,37465,37457,37433,37479,37543,37495,37496,37607,37591, 37593,37584,64039,37589,37600,37587,37669,37665,37627,64040,37662,37631,37661, 37634,37744,37719,37796,37830,37854,37880,37937,37957,37960,38290,63964,64041, 38557,38575,38707,38715,38723,38733,38735,38737,38741,38999,39013,64042,64043, 39207,64044,39326,39502,39641,39644,39797,39794,39823,39857,39867,39936,40304, 40299,64045,40473,40657,0,0,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569, 65506,65508,65287,65282,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,8544, 8545,8546,8547,8548,8549,8550,8551,8552,8553,65506,65508,65287,65282,12849,8470, 8481,8757,32394,35100,37704,37512,34012,20425,28859,26161,26824,37625,26363, 24389,20008,20193,20220,20224,20227,20281,20310,20370,20362,20378,20372,20429, 20544,20514,20479,20510,20550,20592,20546,20628,20724,20696,20810,20836,20893, 20926,20972,21013,21148,21158,21184,21211,21248,21255,21284,21362,21395,21426, 21469,64014,21660,21642,21673,21759,21894,22361,22373,22444,22472,22471,64015, 64016,22686,22706,22795,22867,22875,22877,22883,22948,22970,23382,23488,29999, 23512,23532,23582,23718,23738,23797,23847,23891,64017,23874,23917,23992,23993, 24016,24353,24372,24423,24503,24542,24669,24709,24714,24798,24789,24864,24818, 24849,24887,24880,24984,25107,25254,25589,25696,25757,25806,25934,26112,26133, 26171,26121,26158,26142,26148,26213,26199,26201,64018,26227,26265,26272,26290, 26303,26362,26382,63785,26470,26555,26706,26560,26625,26692,26831,64019,26984, 64020,27032,27106,27184,27243,27206,27251,27262,27362,27364,27606,27711,27740, 27782,27759,27866,27908,28039,28015,28054,28076,28111,28152,28146,28156,28217, 28252,28199,28220,28351,28552,28597,28661,28677,28679,28712,28805,28843,28943, 28932,29020,28998,28999,64021,29121,29182,29361,29374,29476,64022,29559,29629, 29641,29654,29667,29650,29703,29685,29734,29738,29737,29742,29794,29833,29855, 29953,30063,30338,30364,30366,30363,30374,64023,30534,21167,30753,30798,30820, 30842,31024,64024,64025,64026,31124,64027,31131,31441,31463,64028,31467,31646, 64029,32072,32092,32183,32160,32214,32338,32583,32673,64030,33537,33634,33663, 33735,33782,33864,33972,34131,34137,34155,64031,34224,64032,64033,34823,35061, 35346,35383,35449,35495,35518,35551,64034,35574,35667,35711,36080,36084,36114, 36214,64035,36559,64036,64037,36967,37086,64038,37141,37159,37338,37335,37342, 37357,37358,37348,37349,37382,37392,37386,37434,37440,37436,37454,37465,37457, 37433,37479,37543,37495,37496,37607,37591,37593,37584,64039,37589,37600,37587, 37669,37665,37627,64040,37662,37631,37661,37634,37744,37719,37796,37830,37854, 37880,37937,37957,37960,38290,63964,64041,38557,38575,38707,38715,38723,38733, 38735,38737,38741,38999,39013,64042,64043,39207,64044,39326,39502,39641,39644, 39797,39794,39823,39857,39867,39936,40304,40299,64045,40473,40657, ] const Jis0208Encode*: array[7327, UCS16x16] = [ (167u16,87u16),(168u16,14u16),(176u16,74u16),(177u16,61u16),(180u16,12u16), (182u16,182u16),(215u16,62u16),(247u16,63u16),(913u16,470u16),(914u16,471u16), (915u16,472u16),(916u16,473u16),(917u16,474u16),(918u16,475u16),(919u16,476u16), (920u16,477u16),(921u16,478u16),(922u16,479u16),(923u16,480u16),(924u16,481u16), (925u16,482u16),(926u16,483u16),(927u16,484u16),(928u16,485u16),(929u16,486u16), (931u16,487u16),(932u16,488u16),(933u16,489u16),(934u16,490u16),(935u16,491u16), (936u16,492u16),(937u16,493u16),(945u16,502u16),(946u16,503u16),(947u16,504u16), (948u16,505u16),(949u16,506u16),(950u16,507u16),(951u16,508u16),(952u16,509u16), (953u16,510u16),(954u16,511u16),(955u16,512u16),(956u16,513u16),(957u16,514u16), (958u16,515u16),(959u16,516u16),(960u16,517u16),(961u16,518u16),(963u16,519u16), (964u16,520u16),(965u16,521u16),(966u16,522u16),(967u16,523u16),(968u16,524u16), (969u16,525u16),(1025u16,570u16),(1040u16,564u16),(1041u16,565u16), (1042u16,566u16),(1043u16,567u16),(1044u16,568u16),(1045u16,569u16), (1046u16,571u16),(1047u16,572u16),(1048u16,573u16),(1049u16,574u16), (1050u16,575u16),(1051u16,576u16),(1052u16,577u16),(1053u16,578u16), (1054u16,579u16),(1055u16,580u16),(1056u16,581u16),(1057u16,582u16), (1058u16,583u16),(1059u16,584u16),(1060u16,585u16),(1061u16,586u16), (1062u16,587u16),(1063u16,588u16),(1064u16,589u16),(1065u16,590u16), (1066u16,591u16),(1067u16,592u16),(1068u16,593u16),(1069u16,594u16), (1070u16,595u16),(1071u16,596u16),(1072u16,612u16),(1073u16,613u16), (1074u16,614u16),(1075u16,615u16),(1076u16,616u16),(1077u16,617u16), (1078u16,619u16),(1079u16,620u16),(1080u16,621u16),(1081u16,622u16), (1082u16,623u16),(1083u16,624u16),(1084u16,625u16),(1085u16,626u16), (1086u16,627u16),(1087u16,628u16),(1088u16,629u16),(1089u16,630u16), (1090u16,631u16),(1091u16,632u16),(1092u16,633u16),(1093u16,634u16), (1094u16,635u16),(1095u16,636u16),(1096u16,637u16),(1097u16,638u16), (1098u16,639u16),(1099u16,640u16),(1100u16,641u16),(1101u16,642u16), (1102u16,643u16),(1103u16,644u16),(1105u16,618u16),(8208u16,29u16), (8213u16,28u16),(8216u16,37u16),(8217u16,38u16),(8220u16,39u16),(8221u16,40u16), (8224u16,180u16),(8225u16,181u16),(8229u16,36u16),(8230u16,35u16), (8240u16,176u16),(8242u16,75u16),(8243u16,76u16),(8251u16,101u16), (8451u16,77u16),(8470u16,1193u16),(8481u16,1195u16),(8491u16,175u16), (8544u16,1148u16),(8545u16,1149u16),(8546u16,1150u16),(8547u16,1151u16), (8548u16,1152u16),(8549u16,1153u16),(8550u16,1154u16),(8551u16,1155u16), (8552u16,1156u16),(8553u16,1157u16),(8560u16,8634u16),(8561u16,8635u16), (8562u16,8636u16),(8563u16,8637u16),(8564u16,8638u16),(8565u16,8639u16), (8566u16,8640u16),(8567u16,8641u16),(8568u16,8642u16),(8569u16,8643u16), (8592u16,104u16),(8593u16,105u16),(8594u16,103u16),(8595u16,106u16), (8658u16,138u16),(8660u16,139u16),(8704u16,140u16),(8706u16,156u16), (8707u16,141u16),(8711u16,157u16),(8712u16,119u16),(8715u16,120u16), (8721u16,1211u16),(8722u16,60u16),(8730u16,162u16),(8733u16,164u16), (8734u16,70u16),(8735u16,1215u16),(8736u16,153u16),(8741u16,33u16), (8743u16,135u16),(8744u16,136u16),(8745u16,126u16),(8746u16,125u16), (8747u16,166u16),(8748u16,167u16),(8750u16,1210u16),(8756u16,71u16), (8757u16,165u16),(8765u16,163u16),(8786u16,159u16),(8800u16,65u16), (8801u16,158u16),(8806u16,68u16),(8807u16,69u16),(8810u16,160u16), (8811u16,161u16),(8834u16,123u16),(8835u16,124u16),(8838u16,121u16), (8839u16,122u16),(8869u16,154u16),(8895u16,1216u16),(8978u16,155u16), (9312u16,1128u16),(9313u16,1129u16),(9314u16,1130u16),(9315u16,1131u16), (9316u16,1132u16),(9317u16,1133u16),(9318u16,1134u16),(9319u16,1135u16), (9320u16,1136u16),(9321u16,1137u16),(9322u16,1138u16),(9323u16,1139u16), (9324u16,1140u16),(9325u16,1141u16),(9326u16,1142u16),(9327u16,1143u16), (9328u16,1144u16),(9329u16,1145u16),(9330u16,1146u16),(9331u16,1147u16), (9472u16,658u16),(9473u16,669u16),(9474u16,659u16),(9475u16,670u16), (9484u16,660u16),(9487u16,671u16),(9488u16,661u16),(9491u16,672u16), (9492u16,663u16),(9495u16,674u16),(9496u16,662u16),(9499u16,673u16), (9500u16,664u16),(9501u16,685u16),(9504u16,680u16),(9507u16,675u16), (9508u16,666u16),(9509u16,687u16),(9512u16,682u16),(9515u16,677u16), (9516u16,665u16),(9519u16,681u16),(9520u16,686u16),(9523u16,676u16), (9524u16,667u16),(9527u16,683u16),(9528u16,688u16),(9531u16,678u16), (9532u16,668u16),(9535u16,684u16),(9538u16,689u16),(9547u16,679u16), (9632u16,96u16),(9633u16,95u16),(9650u16,98u16),(9651u16,97u16), (9660u16,100u16),(9661u16,99u16),(9670u16,94u16),(9671u16,93u16), (9675u16,90u16),(9678u16,92u16),(9679u16,91u16),(9711u16,187u16), (9733u16,89u16),(9734u16,88u16),(9792u16,73u16),(9794u16,72u16), (9834u16,179u16),(9837u16,178u16),(9839u16,177u16),(12288u16,0u16), (12289u16,1u16),(12290u16,2u16),(12291u16,22u16),(12293u16,24u16), (12294u16,25u16),(12295u16,26u16),(12296u16,49u16),(12297u16,50u16), (12298u16,51u16),(12299u16,52u16),(12300u16,53u16),(12301u16,54u16), (12302u16,55u16),(12303u16,56u16),(12304u16,57u16),(12305u16,58u16), (12306u16,102u16),(12307u16,107u16),(12308u16,43u16),(12309u16,44u16), (12317u16,1191u16),(12319u16,1192u16),(12353u16,282u16),(12354u16,283u16), (12355u16,284u16),(12356u16,285u16),(12357u16,286u16),(12358u16,287u16), (12359u16,288u16),(12360u16,289u16),(12361u16,290u16),(12362u16,291u16), (12363u16,292u16),(12364u16,293u16),(12365u16,294u16),(12366u16,295u16), (12367u16,296u16),(12368u16,297u16),(12369u16,298u16),(12370u16,299u16), (12371u16,300u16),(12372u16,301u16),(12373u16,302u16),(12374u16,303u16), (12375u16,304u16),(12376u16,305u16),(12377u16,306u16),(12378u16,307u16), (12379u16,308u16),(12380u16,309u16),(12381u16,310u16),(12382u16,311u16), (12383u16,312u16),(12384u16,313u16),(12385u16,314u16),(12386u16,315u16), (12387u16,316u16),(12388u16,317u16),(12389u16,318u16),(12390u16,319u16), (12391u16,320u16),(12392u16,321u16),(12393u16,322u16),(12394u16,323u16), (12395u16,324u16),(12396u16,325u16),(12397u16,326u16),(12398u16,327u16), (12399u16,328u16),(12400u16,329u16),(12401u16,330u16),(12402u16,331u16), (12403u16,332u16),(12404u16,333u16),(12405u16,334u16),(12406u16,335u16), (12407u16,336u16),(12408u16,337u16),(12409u16,338u16),(12410u16,339u16), (12411u16,340u16),(12412u16,341u16),(12413u16,342u16),(12414u16,343u16), (12415u16,344u16),(12416u16,345u16),(12417u16,346u16),(12418u16,347u16), (12419u16,348u16),(12420u16,349u16),(12421u16,350u16),(12422u16,351u16), (12423u16,352u16),(12424u16,353u16),(12425u16,354u16),(12426u16,355u16), (12427u16,356u16),(12428u16,357u16),(12429u16,358u16),(12430u16,359u16), (12431u16,360u16),(12432u16,361u16),(12433u16,362u16),(12434u16,363u16), (12435u16,364u16),(12443u16,10u16),(12444u16,11u16),(12445u16,20u16), (12446u16,21u16),(12449u16,376u16),(12450u16,377u16),(12451u16,378u16), (12452u16,379u16),(12453u16,380u16),(12454u16,381u16),(12455u16,382u16), (12456u16,383u16),(12457u16,384u16),(12458u16,385u16),(12459u16,386u16), (12460u16,387u16),(12461u16,388u16),(12462u16,389u16),(12463u16,390u16), (12464u16,391u16),(12465u16,392u16),(12466u16,393u16),(12467u16,394u16), (12468u16,395u16),(12469u16,396u16),(12470u16,397u16),(12471u16,398u16), (12472u16,399u16),(12473u16,400u16),(12474u16,401u16),(12475u16,402u16), (12476u16,403u16),(12477u16,404u16),(12478u16,405u16),(12479u16,406u16), (12480u16,407u16),(12481u16,408u16),(12482u16,409u16),(12483u16,410u16), (12484u16,411u16),(12485u16,412u16),(12486u16,413u16),(12487u16,414u16), (12488u16,415u16),(12489u16,416u16),(12490u16,417u16),(12491u16,418u16), (12492u16,419u16),(12493u16,420u16),(12494u16,421u16),(12495u16,422u16), (12496u16,423u16),(12497u16,424u16),(12498u16,425u16),(12499u16,426u16), (12500u16,427u16),(12501u16,428u16),(12502u16,429u16),(12503u16,430u16), (12504u16,431u16),(12505u16,432u16),(12506u16,433u16),(12507u16,434u16), (12508u16,435u16),(12509u16,436u16),(12510u16,437u16),(12511u16,438u16), (12512u16,439u16),(12513u16,440u16),(12514u16,441u16),(12515u16,442u16), (12516u16,443u16),(12517u16,444u16),(12518u16,445u16),(12519u16,446u16), (12520u16,447u16),(12521u16,448u16),(12522u16,449u16),(12523u16,450u16), (12524u16,451u16),(12525u16,452u16),(12526u16,453u16),(12527u16,454u16), (12528u16,455u16),(12529u16,456u16),(12530u16,457u16),(12531u16,458u16), (12532u16,459u16),(12533u16,460u16),(12534u16,461u16),(12539u16,5u16), (12540u16,27u16),(12541u16,18u16),(12542u16,19u16),(12849u16,1201u16), (12850u16,1202u16),(12857u16,1203u16),(12964u16,1196u16),(12965u16,1197u16), (12966u16,1198u16),(12967u16,1199u16),(12968u16,1200u16),(13059u16,1165u16), (13069u16,1169u16),(13076u16,1160u16),(13080u16,1163u16),(13090u16,1161u16), (13091u16,1171u16),(13094u16,1170u16),(13095u16,1164u16),(13099u16,1172u16), (13110u16,1166u16),(13115u16,1174u16),(13129u16,1159u16),(13130u16,1173u16), (13133u16,1162u16),(13137u16,1167u16),(13143u16,1168u16),(13179u16,1190u16), (13180u16,1206u16),(13181u16,1205u16),(13182u16,1204u16),(13198u16,1178u16), (13199u16,1179u16),(13212u16,1175u16),(13213u16,1176u16),(13214u16,1177u16), (13217u16,1181u16),(13252u16,1180u16),(13261u16,1194u16),(19968u16,1485u16), (19969u16,3285u16),(19971u16,2560u16),(19975u16,4039u16),(19976u16,2795u16), (19977u16,2459u16),(19978u16,2794u16),(19979u16,1625u16),(19981u16,3811u16), (19982u16,4166u16),(19984u16,4419u16),(19985u16,1518u16),(19988u16,1769u16), (19989u16,4420u16),(19990u16,2917u16),(19991u16,4639u16),(19992u16,1933u16), (19993u16,3879u16),(19998u16,2796u16),(20001u16,4259u16),(20006u16,3887u16), (20008u16,8284u16),(20010u16,4421u16),(20013u16,3265u16),(20017u16,4422u16), (20018u16,2063u16),(20022u16,4423u16),(20024u16,1846u16),(20025u16,3211u16), (20027u16,2608u16),(20028u16,4424u16),(20031u16,4425u16),(20034u16,4426u16), (20035u16,3592u16),(20037u16,1934u16),(20043u16,3594u16),(20045u16,3544u16), (20046u16,2196u16),(20047u16,3966u16),(20053u16,6808u16),(20054u16,4427u16), (20055u16,2797u16),(20056u16,4428u16),(20057u16,1618u16),(20061u16,2042u16), (20062u16,2241u16),(20063u16,4114u16),(20066u16,4987u16),(20081u16,4215u16), (20083u16,3570u16),(20094u16,1790u16),(20096u16,1900u16),(20098u16,4429u16), (20101u16,4430u16),(20102u16,4256u16),(20104u16,4164u16),(20105u16,3079u16), (20106u16,4432u16),(20107u16,2529u16),(20108u16,3560u16),(20110u16,4435u16), (20113u16,1533u16),(20114u16,2224u16),(20116u16,2223u16),(20117u16,1479u16), (20120u16,4366u16),(20121u16,4365u16),(20123u16,2368u16),(20124u16,1410u16), (20126u16,4436u16),(20127u16,4437u16),(20128u16,4438u16),(20129u16,3967u16), (20130u16,4439u16),(20132u16,2243u16),(20133u16,1480u16),(20134u16,4029u16), (20136u16,1971u16),(20139u16,1972u16),(20140u16,1973u16),(20141u16,3355u16), (20142u16,4257u16),(20144u16,4440u16),(20147u16,4441u16),(20150u16,4442u16), (20154u16,2864u16),(20160u16,2657u16),(20161u16,2865u16),(20162u16,4447u16), (20164u16,4445u16),(20166u16,4446u16),(20167u16,1935u16),(20170u16,2352u16), (20171u16,1677u16),(20173u16,4444u16),(20174u16,4443u16),(20175u16,3862u16), (20180u16,2481u16),(20181u16,2480u16),(20182u16,3131u16),(20183u16,4448u16), (20184u16,3812u16),(20185u16,2984u16),(20189u16,23u16),(20190u16,4449u16), (20191u16,4451u16),(20193u16,8285u16),(20195u16,3170u16),(20196u16,4294u16), (20197u16,1451u16),(20205u16,4450u16),(20206u16,1627u16),(20208u16,2009u16), (20210u16,3266u16),(20214u16,2146u16),(20215u16,4452u16),(20219u16,3575u16), (20220u16,8286u16),(20224u16,8287u16),(20225u16,1860u16),(20227u16,8288u16), (20233u16,4453u16),(20234u16,1452u16),(20237u16,2225u16),(20238u16,1861u16), (20239u16,3849u16),(20240u16,3683u16),(20241u16,1936u16),(20250u16,1678u16), (20252u16,4488u16),(20253u16,3416u16),(20271u16,3647u16),(20272u16,4455u16), (20276u16,3693u16),(20278u16,4295u16),(20280u16,2832u16),(20281u16,8289u16), (20282u16,2482u16),(20284u16,2530u16),(20285u16,1629u16),(20291u16,3338u16), (20294u16,3197u16),(20295u16,4459u16),(20301u16,1453u16),(20302u16,3356u16), (20303u16,2658u16),(20304u16,2369u16),(20305u16,4139u16),(20307u16,3147u16), (20309u16,1628u16),(20310u16,8290u16),(20311u16,4458u16),(20313u16,4165u16), (20314u16,4454u16),(20315u16,4456u16),(20316u16,2427u16),(20317u16,4457u16), (20318u16,4891u16),(20329u16,4465u16),(20335u16,4468u16),(20336u16,4466u16), (20339u16,1631u16),(20341u16,3880u16),(20342u16,4460u16),(20347u16,4464u16), (20348u16,2244u16),(20351u16,2483u16),(20355u16,1791u16),(20358u16,4469u16), (20360u16,4461u16),(20362u16,8292u16),(20363u16,4296u16),(20365u16,2531u16), (20367u16,4462u16),(20369u16,4467u16),(20370u16,8291u16),(20372u16,8294u16), (20374u16,4470u16),(20376u16,4463u16),(20378u16,8293u16),(20379u16,1974u16), (20381u16,1454u16),(20384u16,1975u16),(20385u16,1630u16),(20395u16,4892u16), (20397u16,4036u16),(20398u16,3837u16),(20399u16,2245u16),(20405u16,2834u16), (20406u16,4252u16),(20415u16,3909u16),(20418u16,2091u16),(20419u16,3106u16), (20420u16,1665u16),(20425u16,8277u16),(20426u16,2682u16),(20429u16,8295u16), (20430u16,4474u16),(20432u16,4479u16),(20433u16,4477u16),(20436u16,4472u16), (20439u16,3116u16),(20440u16,4475u16),(20442u16,4478u16),(20443u16,4476u16), (20445u16,3914u16),(20447u16,4473u16),(20449u16,2833u16),(20451u16,4030u16), (20452u16,4480u16),(20453u16,4481u16),(20462u16,2635u16),(20463u16,4494u16), (20467u16,3619u16),(20469u16,3781u16),(20470u16,4489u16),(20472u16,3933u16), (20474u16,1619u16),(20478u16,4493u16),(20479u16,8298u16),(20485u16,4487u16), (20486u16,4496u16),(20489u16,3057u16),(20491u16,2197u16),(20493u16,3631u16), (20495u16,5960u16),(20497u16,4495u16),(20498u16,3444u16),(20500u16,4484u16), (20502u16,2247u16),(20505u16,2246u16),(20506u16,4482u16),(20510u16,8299u16), (20511u16,2595u16),(20513u16,4490u16),(20514u16,8297u16),(20515u16,3932u16), (20516u16,3240u16),(20517u16,4486u16),(20518u16,2148u16),(20520u16,4483u16), (20521u16,4491u16),(20522u16,4485u16),(20523u16,4278u16),(20524u16,4492u16), (20525u16,4356u16),(20534u16,2043u16),(20537u16,2147u16),(20544u16,8296u16), (20546u16,8302u16),(20547u16,4497u16),(20550u16,8300u16),(20551u16,4498u16), (20552u16,4502u16),(20553u16,1455u16),(20559u16,3901u16),(20560u16,4501u16), (20565u16,4500u16),(20566u16,4504u16),(20570u16,4503u16),(20572u16,3357u16), (20581u16,2149u16),(20588u16,4505u16),(20592u16,8301u16),(20594u16,2574u16), (20596u16,3107u16),(20597u16,3358u16),(20598u16,2059u16),(20600u16,4506u16), (20605u16,1901u16),(20608u16,4507u16),(20613u16,4509u16),(20621u16,3968u16), (20625u16,2137u16),(20628u16,8303u16),(20632u16,2460u16),(20633u16,3752u16), (20634u16,4508u16),(20652u16,2386u16),(20653u16,4170u16),(20658u16,4511u16), (20659u16,4514u16),(20660u16,4510u16),(20661u16,2385u16),(20663u16,2724u16), (20670u16,2092u16),(20674u16,4515u16),(20677u16,2020u16),(20681u16,4512u16), (20682u16,4513u16),(20685u16,3492u16),(20687u16,3099u16),(20689u16,1976u16), (20693u16,3992u16),(20694u16,4516u16),(20696u16,8305u16),(20698u16,4258u16), (20702u16,4517u16),(20707u16,4520u16),(20709u16,4518u16),(20711u16,3053u16), (20717u16,4519u16),(20718u16,4521u16),(20724u16,8304u16),(20725u16,4523u16), (20729u16,4522u16),(20731u16,3893u16),(20736u16,1902u16),(20737u16,4525u16), (20738u16,4526u16),(20740u16,1612u16),(20745u16,4524u16),(20754u16,2621u16), (20756u16,4529u16),(20757u16,4528u16),(20758u16,4527u16),(20760u16,4471u16), (20762u16,4530u16),(20767u16,2725u16),(20769u16,4531u16),(20778u16,4140u16), (20786u16,4098u16),(20791u16,4533u16),(20794u16,4532u16),(20795u16,4535u16), (20796u16,4534u16),(20799u16,4536u16),(20800u16,4537u16),(20801u16,1493u16), (20803u16,2182u16),(20804u16,2094u16),(20805u16,2659u16),(20806u16,3286u16), (20807u16,1977u16),(20808u16,2985u16),(20809u16,2248u16),(20810u16,8306u16), (20811u16,2333u16),(20812u16,4539u16),(20813u16,4081u16),(20814u16,3421u16), (20816u16,2532u16),(20818u16,4538u16),(20820u16,4540u16),(20826u16,3445u16), (20828u16,1776u16),(20834u16,4541u16),(20836u16,8307u16),(20837u16,3571u16), (20840u16,3027u16),(20841u16,4543u16),(20842u16,4544u16),(20843u16,3677u16), (20844u16,2249u16),(20845u16,4350u16),(20846u16,4545u16),(20849u16,1979u16), (20853u16,3881u16),(20854u16,3123u16),(20855u16,2054u16),(20856u16,3404u16), (20860u16,2150u16),(20864u16,4546u16),(20866u16,4547u16),(20869u16,3543u16), (20870u16,1566u16),(20873u16,4550u16),(20874u16,2442u16),(20876u16,4549u16), (20877u16,2387u16),(20879u16,4551u16),(20880u16,6563u16),(20881u16,4552u16), (20882u16,3980u16),(20883u16,4553u16),(20885u16,4554u16),(20886u16,4555u16), (20887u16,2798u16),(20889u16,2581u16),(20893u16,8308u16),(20896u16,1792u16), (20898u16,4558u16),(20900u16,4556u16),(20901u16,4070u16),(20902u16,4557u16), (20904u16,3817u16),(20905u16,4559u16),(20906u16,4560u16),(20907u16,4561u16), (20908u16,3446u16),(20912u16,4565u16),(20913u16,4563u16),(20914u16,4564u16), (20915u16,4562u16),(20916u16,2416u16),(20917u16,4566u16),(20918u16,4115u16), (20919u16,4297u16),(20925u16,4567u16),(20926u16,8309u16),(20932u16,2921u16), (20933u16,4568u16),(20934u16,2689u16),(20937u16,4569u16),(20939u16,3287u16), (20940u16,4260u16),(20941u16,3447u16),(20950u16,4642u16),(20955u16,4570u16), (20956u16,7806u16),(20957u16,2010u16),(20960u16,4571u16),(20961u16,4009u16), (20966u16,2703u16),(20967u16,3193u16),(20969u16,4573u16),(20970u16,3545u16), (20972u16,8310u16),(20973u16,4574u16),(20976u16,4575u16),(20977u16,1705u16), (20981u16,4576u16),(20982u16,1980u16),(20984u16,3521u16),(20985u16,1593u16), (20986u16,2679u16),(20989u16,3666u16),(20990u16,4577u16),(20992u16,3448u16), (20995u16,2866u16),(20996u16,4578u16),(20998u16,3865u16),(20999u16,2971u16), (21000u16,1787u16),(21002u16,1794u16),(21003u16,4579u16),(21006u16,4581u16), (21009u16,2093u16),(21012u16,4580u16),(21013u16,8311u16),(21015u16,4312u16), (21021u16,2704u16),(21028u16,3694u16),(21029u16,3897u16),(21031u16,4582u16), (21033u16,4223u16),(21034u16,4583u16),(21038u16,4584u16),(21040u16,3477u16), (21043u16,4585u16),(21046u16,2922u16),(21047u16,2443u16),(21048u16,2151u16), (21049u16,4586u16),(21050u16,2484u16),(21051u16,2334u16),(21059u16,3359u16), (21060u16,4588u16),(21063u16,3108u16),(21066u16,2428u16),(21067u16,4589u16), (21068u16,4590u16),(21069u16,3023u16),(21071u16,4587u16),(21076u16,4592u16), (21078u16,3969u16),(21083u16,2323u16),(21086u16,4591u16),(21091u16,2152u16), (21092u16,2411u16),(21093u16,3648u16),(21097u16,4595u16),(21098u16,4593u16), (21103u16,3850u16),(21104u16,2799u16),(21105u16,4602u16),(21106u16,1759u16), (21107u16,4596u16),(21108u16,4594u16),(21109u16,3054u16),(21117u16,4598u16), (21119u16,4597u16),(21123u16,1727u16),(21127u16,2131u16),(21128u16,4603u16), (21129u16,4242u16),(21133u16,4599u16),(21137u16,4604u16),(21138u16,4601u16), (21140u16,4600u16),(21147u16,4276u16),(21148u16,8312u16),(21151u16,2250u16), (21152u16,1632u16),(21155u16,4313u16),(21158u16,8313u16),(21161u16,2716u16), (21162u16,3439u16),(21163u16,2324u16),(21164u16,4607u16),(21165u16,4608u16), (21167u16,8487u16),(21169u16,4298u16),(21172u16,4334u16),(21173u16,4610u16), (21177u16,2251u16),(21180u16,4609u16),(21182u16,1706u16),(21184u16,8314u16), (21185u16,4611u16),(21187u16,4001u16),(21189u16,3317u16),(21191u16,4141u16), (21193u16,3910u16),(21197u16,4612u16),(21202u16,7478u16),(21205u16,3493u16), (21207u16,4613u16),(21208u16,1795u16),(21209u16,4060u16),(21211u16,8315u16), (21213u16,2726u16),(21214u16,4614u16),(21215u16,3924u16),(21216u16,4618u16), (21218u16,2923u16),(21219u16,4615u16),(21220u16,2021u16),(21222u16,4616u16), (21223u16,1796u16),(21234u16,2081u16),(21235u16,4619u16),(21237u16,4620u16), (21240u16,4621u16),(21241u16,4622u16),(21242u16,2596u16),(21246u16,2252u16), (21247u16,4103u16),(21248u16,8316u16),(21249u16,4113u16),(21250u16,3564u16), (21253u16,3934u16),(21254u16,4623u16),(21255u16,8317u16),(21256u16,4624u16), (21261u16,4626u16),(21263u16,4628u16),(21264u16,4627u16),(21269u16,4629u16), (21270u16,1626u16),(21271u16,3991u16),(21273u16,2441u16),(21274u16,4630u16), (21277u16,3064u16),(21280u16,2727u16),(21281u16,1982u16),(21283u16,4631u16), (21284u16,8318u16),(21290u16,3724u16),(21295u16,4632u16),(21297u16,4633u16), (21299u16,4634u16),(21304u16,4635u16),(21305u16,3763u16),(21306u16,2045u16), (21307u16,1478u16),(21311u16,3508u16),(21312u16,4636u16),(21313u16,2660u16), (21315u16,2986u16),(21317u16,4638u16),(21318u16,4637u16),(21319u16,2728u16), (21320u16,2226u16),(21321u16,4640u16),(21322u16,3695u16),(21325u16,4641u16), (21329u16,3725u16),(21330u16,3121u16),(21331u16,3179u16),(21332u16,1981u16), (21335u16,3555u16),(21336u16,3212u16),(21338u16,3649u16),(21340u16,3993u16), (21342u16,4643u16),(21344u16,2987u16),(21350u16,2088u16),(21353u16,4644u16), (21358u16,4645u16),(21359u16,1515u16),(21360u16,1494u16),(21361u16,1862u16), (21362u16,8319u16),(21363u16,3109u16),(21364u16,1928u16),(21365u16,4216u16), (21367u16,4648u16),(21368u16,1620u16),(21371u16,4647u16),(21375u16,1983u16), (21378u16,4649u16),(21380u16,4122u16),(21395u16,8320u16),(21398u16,4650u16), (21400u16,4279u16),(21402u16,2253u16),(21407u16,2183u16),(21408u16,4651u16), (21413u16,4653u16),(21414u16,4652u16),(21416u16,2882u16),(21417u16,1528u16), (21421u16,1565u16),(21422u16,4654u16),(21424u16,4655u16),(21426u16,8321u16), (21427u16,2184u16),(21430u16,4656u16),(21435u16,1957u16),(21442u16,2461u16), (21443u16,4657u16),(21448u16,4031u16),(21449u16,2370u16),(21450u16,1937u16), (21451u16,4142u16),(21452u16,3055u16),(21453u16,3696u16),(21454u16,2630u16), (21460u16,2670u16),(21462u16,2609u16),(21463u16,2622u16),(21465u16,2717u16), (21467u16,3697u16),(21469u16,8322u16),(21471u16,4660u16),(21473u16,1538u16), (21474u16,3056u16),(21475u16,2254u16),(21476u16,2198u16),(21477u16,2044u16), (21480u16,4664u16),(21481u16,3196u16),(21482u16,3195u16),(21483u16,1984u16), (21484u16,2729u16),(21485u16,4665u16),(21486u16,4663u16),(21487u16,1633u16), (21488u16,3171u16),(21489u16,2561u16),(21490u16,2486u16),(21491u16,1509u16), (21494u16,1771u16),(21495u16,2325u16),(21496u16,2485u16),(21498u16,4666u16), (21505u16,4667u16),(21507u16,1920u16),(21508u16,1729u16),(21512u16,2326u16), (21513u16,1919u16),(21514u16,3352u16),(21515u16,1508u16),(21516u16,3494u16), (21517u16,4071u16),(21518u16,2256u16),(21519u16,4224u16),(21520u16,3422u16), (21521u16,2255u16),(21531u16,2082u16),(21533u16,4676u16),(21535u16,2040u16), (21536u16,3989u16),(21542u16,3726u16),(21545u16,4675u16),(21547u16,1847u16), (21548u16,4670u16),(21549u16,4671u16),(21550u16,4673u16),(21558u16,4674u16), (21560u16,1938u16),(21561u16,2884u16),(21563u16,3866u16),(21564u16,4672u16), (21565u16,4668u16),(21566u16,2228u16),(21568u16,4669u16),(21570u16,4327u16), (21574u16,3935u16),(21576u16,3361u16),(21577u16,2227u16),(21578u16,2335u16), (21582u16,4677u16),(21585u16,3538u16),(21599u16,4681u16),(21608u16,2631u16), (21610u16,2623u16),(21616u16,4684u16),(21617u16,4682u16),(21619u16,4044u16), (21621u16,4679u16),(21622u16,4688u16),(21623u16,4683u16),(21627u16,4686u16), (21628u16,2199u16),(21629u16,4072u16),(21632u16,4687u16),(21636u16,4689u16), (21638u16,4691u16),(21642u16,8325u16),(21643u16,2429u16),(21644u16,4357u16), (21646u16,4680u16),(21647u16,4678u16),(21648u16,4690u16),(21650u16,4685u16), (21660u16,8324u16),(21666u16,4693u16),(21668u16,4702u16),(21669u16,4695u16), (21672u16,4699u16),(21673u16,8326u16),(21675u16,4700u16),(21676u16,4696u16), (21679u16,4729u16),(21682u16,2422u16),(21683u16,1708u16),(21688u16,4694u16), (21692u16,4704u16),(21693u16,1495u16),(21694u16,4703u16),(21696u16,1414u16), (21697u16,3801u16),(21698u16,4701u16),(21700u16,4697u16),(21703u16,4692u16), (21704u16,4698u16),(21705u16,2389u16),(21720u16,4705u16),(21729u16,1496u16), (21730u16,4714u16),(21733u16,4706u16),(21734u16,4707u16),(21736u16,2730u16), (21737u16,4020u16),(21741u16,4712u16),(21742u16,4711u16),(21746u16,3398u16), (21754u16,4713u16),(21757u16,4710u16),(21759u16,8327u16),(21764u16,1523u16), (21766u16,2371u16),(21767u16,2835u16),(21775u16,4708u16),(21776u16,3449u16), (21780u16,4709u16),(21782u16,1411u16),(21806u16,4719u16),(21807u16,4138u16), (21809u16,2732u16),(21811u16,4725u16),(21816u16,4724u16),(21817u16,4715u16), (21822u16,3136u16),(21824u16,4716u16),(21828u16,3180u16),(21829u16,4721u16), (21830u16,2731u16),(21836u16,4718u16),(21839u16,4109u16),(21843u16,2095u16), (21846u16,4722u16),(21847u16,4723u16),(21852u16,4720u16),(21853u16,4726u16), (21859u16,4717u16),(21883u16,4732u16),(21884u16,4737u16),(21886u16,4733u16), (21888u16,4728u16),(21891u16,4738u16),(21892u16,3024u16),(21894u16,8328u16), (21895u16,4740u16),(21897u16,2257u16),(21898u16,4730u16),(21899u16,3288u16), (21912u16,4734u16),(21913u16,4727u16),(21914u16,1798u16),(21916u16,1863u16), (21917u16,1760u16),(21918u16,4735u16),(21919u16,4731u16),(21927u16,2153u16), (21928u16,4741u16),(21929u16,4739u16),(21930u16,3058u16),(21931u16,1921u16), (21932u16,1985u16),(21934u16,4736u16),(21936u16,2057u16),(21942u16,1539u16), (21956u16,4745u16),(21957u16,4743u16),(21959u16,4800u16),(21972u16,4748u16), (21978u16,4742u16),(21980u16,4746u16),(21983u16,4744u16),(21987u16,2487u16), (21988u16,4747u16),(22007u16,4750u16),(22009u16,4755u16),(22013u16,4753u16), (22014u16,4752u16),(22022u16,3213u16),(22025u16,1634u16),(22036u16,4749u16), (22038u16,4751u16),(22039u16,2733u16),(22040u16,1522u16),(22043u16,4754u16), (22057u16,1659u16),(22063u16,4765u16),(22065u16,2817u16),(22066u16,4761u16), (22068u16,4759u16),(22070u16,4760u16),(22072u16,4762u16),(22082u16,1532u16), (22092u16,3032u16),(22094u16,4756u16),(22096u16,4757u16),(22107u16,1781u16), (22116u16,4764u16),(22120u16,1864u16),(22122u16,4767u16),(22123u16,4763u16), (22124u16,4766u16),(22132u16,3867u16),(22136u16,3530u16),(22138u16,3689u16), (22144u16,4769u16),(22150u16,4768u16),(22151u16,1728u16),(22154u16,4770u16), (22159u16,4773u16),(22164u16,4772u16),(22176u16,4771u16),(22178u16,3596u16), (22181u16,4774u16),(22190u16,4775u16),(22196u16,4777u16),(22198u16,4776u16), (22204u16,4779u16),(22208u16,4782u16),(22209u16,4780u16),(22210u16,4778u16), (22211u16,4781u16),(22216u16,4783u16),(22222u16,4784u16),(22225u16,4785u16), (22227u16,4786u16),(22231u16,4787u16),(22232u16,4548u16),(22234u16,2629u16), (22235u16,2488u16),(22238u16,1680u16),(22240u16,1497u16),(22243u16,3231u16), (22254u16,4788u16),(22256u16,2353u16),(22258u16,1456u16),(22259u16,2881u16), (22265u16,4789u16),(22266u16,2200u16),(22269u16,2336u16),(22271u16,4791u16), (22272u16,4790u16),(22275u16,3917u16),(22276u16,4792u16),(22280u16,4794u16), (22281u16,4793u16),(22283u16,4795u16),(22285u16,4796u16),(22287u16,2154u16), (22290u16,1567u16),(22291u16,4797u16),(22294u16,4799u16),(22296u16,4798u16), (22300u16,4801u16),(22303u16,3441u16),(22310u16,4802u16),(22311u16,1430u16), (22312u16,2412u16),(22317u16,2096u16),(22320u16,3242u16),(22327u16,4803u16), (22328u16,4804u16),(22331u16,4806u16),(22336u16,4807u16),(22338u16,2417u16), (22343u16,2022u16),(22346u16,3970u16),(22350u16,4805u16),(22351u16,4808u16), (22352u16,2382u16),(22353u16,2258u16),(22361u16,8329u16),(22369u16,4812u16), (22372u16,2354u16),(22373u16,8330u16),(22374u16,3214u16),(22377u16,4809u16), (22378u16,3347u16),(22399u16,4813u16),(22402u16,2885u16),(22408u16,4811u16), (22409u16,4814u16),(22411u16,2098u16),(22419u16,4815u16),(22432u16,4816u16), (22434u16,2259u16),(22435u16,1723u16),(22436u16,4818u16),(22442u16,4819u16), (22444u16,8331u16),(22448u16,4820u16),(22451u16,4817u16),(22464u16,4810u16), (22467u16,4821u16),(22470u16,4822u16),(22471u16,8333u16),(22472u16,8332u16), (22475u16,4015u16),(22478u16,2800u16),(22482u16,4824u16),(22483u16,4825u16), (22484u16,4823u16),(22486u16,4827u16),(22492u16,3595u16),(22495u16,1481u16), (22496u16,3813u16),(22499u16,4828u16),(22516u16,2818u16),(22519u16,2562u16), (22521u16,3632u16),(22522u16,1865u16),(22524u16,2424u16),(22528u16,4004u16), (22530u16,3495u16),(22533u16,2155u16),(22534u16,3148u16),(22538u16,4826u16), (22539u16,4829u16),(22549u16,3137u16),(22553u16,4830u16),(22557u16,4831u16), (22561u16,4833u16),(22564u16,3362u16),(22570u16,1799u16),(22575u16,7802u16), (22576u16,1568u16),(22577u16,3936u16),(22580u16,2801u16),(22581u16,3423u16), (22586u16,2419u16),(22589u16,4839u16),(22592u16,3882u16),(22593u16,4290u16), (22602u16,1681u16),(22603u16,4835u16),(22609u16,3033u16),(22610u16,4838u16), (22612u16,3450u16),(22615u16,3424u16),(22616u16,3451u16),(22617u16,3690u16), (22618u16,3334u16),(22622u16,2390u16),(22626u16,4834u16),(22633u16,1589u16), (22635u16,3405u16),(22640u16,4836u16),(22642u16,4832u16),(22645u16,2867u16), (22649u16,4840u16),(22654u16,2677u16),(22659u16,1986u16),(22661u16,4841u16), (22675u16,3925u16),(22679u16,3100u16),(22684u16,3327u16),(22686u16,8336u16), (22687u16,4843u16),(22696u16,3994u16),(22699u16,4844u16),(22702u16,4849u16), (22706u16,8337u16),(22707u16,3868u16),(22712u16,4848u16),(22713u16,4842u16), (22714u16,4845u16),(22715u16,4847u16),(22718u16,2355u16),(22721u16,3894u16), (22725u16,4850u16),(22727u16,3232u16),(22730u16,1682u16),(22732u16,2802u16), (22737u16,4852u16),(22739u16,4851u16),(22741u16,2327u16),(22743u16,4853u16), (22744u16,4855u16),(22745u16,4854u16),(22748u16,4857u16),(22750u16,4846u16), (22751u16,4859u16),(22756u16,4858u16),(22757u16,4856u16),(22763u16,2489u16), (22764u16,2868u16),(22766u16,3059u16),(22767u16,4860u16),(22768u16,2941u16), (22769u16,1486u16),(22770u16,3639u16),(22775u16,3348u16),(22777u16,4862u16), (22778u16,4861u16),(22779u16,4863u16),(22780u16,4864u16),(22781u16,4865u16), (22786u16,4866u16),(22793u16,3902u16),(22794u16,4867u16),(22795u16,8338u16), (22799u16,1635u16),(22800u16,4868u16),(22805u16,4163u16),(22806u16,1707u16), (22808u16,4646u16),(22809u16,2671u16),(22810u16,3132u16),(22811u16,4869u16), (22812u16,4116u16),(22818u16,4061u16),(22821u16,4871u16),(22823u16,3172u16), (22825u16,3406u16),(22826u16,3133u16),(22827u16,3814u16),(22828u16,4872u16), (22829u16,4873u16),(22830u16,1594u16),(22833u16,2563u16),(22834u16,4874u16), (22839u16,1457u16),(22840u16,4875u16),(22846u16,4876u16),(22852u16,1569u16), (22855u16,1866u16),(22856u16,3541u16),(22857u16,3937u16),(22862u16,4880u16), (22863u16,3060u16),(22864u16,4879u16),(22865u16,2099u16),(22867u16,8339u16), (22868u16,4006u16),(22869u16,4878u16),(22871u16,3452u16),(22872u16,4882u16), (22874u16,4881u16),(22875u16,8340u16),(22877u16,8341u16),(22880u16,4884u16), (22882u16,4883u16),(22883u16,8342u16),(22885u16,1595u16),(22887u16,4885u16), (22888u16,2734u16),(22889u16,4887u16),(22890u16,3200u16),(22892u16,4886u16), (22894u16,3872u16),(22899u16,2718u16),(22900u16,3442u16),(22904u16,4888u16), (22909u16,2260u16),(22913u16,4889u16),(22914u16,3572u16),(22915u16,3727u16), (22916u16,4090u16),(22922u16,3576u16),(22925u16,4898u16),(22931u16,1903u16), (22934u16,4172u16),(22937u16,4056u16),(22939u16,4993u16),(22941u16,4890u16), (22947u16,4893u16),(22948u16,8343u16),(22949u16,3138u16),(22952u16,3971u16), (22956u16,3425u16),(22962u16,4894u16),(22969u16,4016u16),(22970u16,8344u16), (22971u16,2391u16),(22974u16,2735u16),(22982u16,4895u16),(22985u16,2491u16), (22987u16,2490u16),(22992u16,1434u16),(22993u16,2201u16),(22995u16,2924u16), (22996u16,1458u16),(23001u16,4899u16),(23002u16,4900u16),(23004u16,4897u16), (23013u16,1527u16),(23014u16,1800u16),(23016u16,4896u16),(23018u16,4078u16), (23019u16,3776u16),(23030u16,1417u16),(23035u16,1498u16),(23039u16,2492u16), (23041u16,1459u16),(23043u16,1412u16),(23049u16,4905u16),(23057u16,4903u16), (23064u16,4069u16),(23066u16,4906u16),(23068u16,4904u16),(23071u16,4902u16), (23072u16,2836u16),(23077u16,4901u16),(23081u16,3911u16),(23087u16,2229u16), (23093u16,4910u16),(23094u16,4911u16),(23100u16,2736u16),(23104u16,4907u16), (23105u16,4335u16),(23110u16,3615u16),(23113u16,4909u16),(23130u16,2356u16), (23138u16,4912u16),(23142u16,3815u16),(23146u16,4913u16),(23148u16,4908u16), (23167u16,4068u16),(23186u16,3633u16),(23194u16,4914u16),(23195u16,3777u16), (23228u16,4915u16),(23229u16,4919u16),(23230u16,4916u16),(23233u16,1636u16), (23234u16,4918u16),(23241u16,2564u16),(23243u16,4917u16),(23244u16,2156u16), (23248u16,4931u16),(23254u16,4924u16),(23255u16,4921u16),(23265u16,3263u16), (23267u16,4920u16),(23270u16,4922u16),(23273u16,4923u16),(23290u16,4925u16), (23291u16,4926u16),(23305u16,1867u16),(23307u16,4928u16),(23308u16,4927u16), (23318u16,4929u16),(23330u16,2803u16),(23338u16,4932u16),(23340u16,3349u16), (23344u16,1540u16),(23346u16,4930u16),(23350u16,4933u16),(23358u16,4934u16), (23360u16,4937u16),(23363u16,4935u16),(23365u16,4936u16),(23376u16,2493u16), (23377u16,4938u16),(23380u16,2261u16),(23381u16,4939u16),(23382u16,8345u16), (23383u16,2533u16),(23384u16,3125u16),(23386u16,4940u16),(23387u16,4941u16), (23388u16,2501u16),(23389u16,2262u16),(23391u16,4091u16),(23395u16,1887u16), (23396u16,2202u16),(23397u16,4942u16),(23398u16,1747u16),(23401u16,4943u16), (23403u16,3126u16),(23408u16,4944u16),(23409u16,4984u16),(23411u16,4945u16), (23413u16,4946u16),(23416u16,4947u16),(23418u16,4949u16),(23424u16,4950u16), (23427u16,4951u16),(23429u16,3181u16),(23431u16,1510u16),(23432u16,2610u16), (23433u16,1443u16),(23435u16,3062u16),(23436u16,1801u16),(23437u16,2558u16), (23439u16,2263u16),(23445u16,3453u16),(23447u16,2632u16),(23448u16,1802u16), (23449u16,3267u16),(23450u16,3363u16),(23451u16,1433u16),(23452u16,1904u16), (23453u16,3938u16),(23455u16,2571u16),(23458u16,1929u16),(23459u16,2988u16), (23460u16,2565u16),(23461u16,4143u16),(23462u16,4952u16),(23470u16,1939u16), (23472u16,2392u16),(23475u16,1709u16),(23476u16,1570u16),(23477u16,2737u16), (23478u16,1637u16),(23480u16,4953u16),(23481u16,4173u16),(23487u16,2672u16), (23488u16,8346u16),(23490u16,2605u16),(23491u16,4954u16),(23492u16,1868u16), (23493u16,3527u16),(23494u16,4050u16),(23495u16,4955u16),(23497u16,4956u16), (23500u16,3816u16),(23504u16,4958u16),(23506u16,1793u16),(23507u16,2060u16), (23508u16,4957u16),(23512u16,8348u16),(23515u16,1803u16),(23517u16,2837u16), (23518u16,4962u16),(23519u16,2444u16),(23521u16,1638u16),(23522u16,4961u16), (23524u16,4959u16),(23525u16,4963u16),(23526u16,4960u16),(23527u16,3582u16), (23528u16,5590u16),(23529u16,2838u16),(23531u16,4964u16),(23532u16,8349u16), (23534u16,4261u16),(23536u16,4965u16),(23539u16,4967u16),(23541u16,3289u16), (23542u16,4966u16),(23544u16,2916u16),(23546u16,2534u16),(23550u16,3149u16), (23551u16,2624u16),(23553u16,3844u16),(23554u16,2989u16),(23556u16,2582u16), (23557u16,4968u16),(23558u16,2738u16),(23559u16,4969u16),(23560u16,4970u16), (23561u16,1460u16),(23562u16,3127u16),(23563u16,2869u16),(23565u16,4971u16), (23566u16,3496u16),(23567u16,2739u16),(23569u16,2740u16),(23571u16,4972u16), (23574u16,2990u16),(23578u16,2741u16),(23582u16,8350u16),(23584u16,4973u16), (23586u16,4974u16),(23588u16,4105u16),(23592u16,4975u16),(23597u16,2011u16), (23601u16,2633u16),(23608u16,4976u16),(23609u16,4977u16),(23610u16,2597u16), (23611u16,2831u16),(23612u16,3561u16),(23613u16,2871u16),(23614u16,3753u16), (23615u16,3573u16),(23616u16,2014u16),(23617u16,4978u16),(23621u16,1958u16), (23622u16,4979u16),(23624u16,2067u16),(23626u16,3524u16),(23627u16,1613u16), (23629u16,2494u16),(23630u16,4980u16),(23631u16,4983u16),(23632u16,4982u16), (23633u16,2066u16),(23635u16,4981u16),(23637u16,3407u16),(23646u16,3117u16), (23648u16,3426u16),(23649u16,2577u16),(23652u16,3063u16),(23653u16,4225u16), (23660u16,4985u16),(23662u16,4986u16),(23663u16,3531u16),(23665u16,2462u16), (23670u16,4988u16),(23673u16,4989u16),(23692u16,4990u16),(23696u16,1869u16), (23697u16,4991u16),(23700u16,4992u16),(23713u16,1609u16),(23718u16,8351u16), (23720u16,3034u16),(23721u16,1853u16),(23723u16,4994u16),(23724u16,4049u16), (23729u16,3151u16),(23731u16,1748u16),(23734u16,4996u16),(23735u16,4998u16), (23736u16,1848u16),(23738u16,8352u16),(23739u16,4995u16),(23740u16,4997u16), (23742u16,5000u16),(23749u16,4999u16),(23751u16,5001u16),(23769u16,5002u16), (23776u16,3506u16),(23777u16,1987u16),(23784u16,1666u16),(23785u16,5003u16), (23786u16,5008u16),(23789u16,5006u16),(23791u16,3940u16),(23792u16,3939u16), (23797u16,8353u16),(23798u16,3454u16),(23802u16,5005u16),(23803u16,2683u16), (23805u16,5004u16),(23815u16,2901u16),(23819u16,5009u16),(23822u16,2423u16), (23825u16,5015u16),(23828u16,5016u16),(23829u16,5010u16),(23830u16,1710u16), (23831u16,5011u16),(23832u16,5020u16),(23833u16,5019u16),(23834u16,5018u16), (23835u16,5014u16),(23839u16,5013u16),(23842u16,5017u16),(23847u16,8354u16), (23849u16,3941u16),(23874u16,8357u16),(23883u16,5024u16),(23884u16,5021u16), (23886u16,5023u16),(23888u16,4217u16),(23890u16,5022u16),(23891u16,8355u16), (23900u16,5012u16),(23913u16,2902u16),(23916u16,5025u16),(23917u16,8358u16), (23919u16,2372u16),(23923u16,5026u16),(23926u16,5027u16),(23938u16,5030u16), (23940u16,5029u16),(23943u16,5028u16),(23947u16,3455u16),(23948u16,5007u16), (23952u16,5036u16),(23965u16,5032u16),(23970u16,5031u16),(23980u16,5033u16), (23982u16,5034u16),(23991u16,5037u16),(23992u16,8359u16),(23993u16,8360u16), (23994u16,4299u16),(23996u16,5038u16),(23997u16,5035u16),(24009u16,5039u16), (24012u16,1849u16),(24013u16,5040u16),(24016u16,8361u16),(24018u16,5042u16), (24019u16,5041u16),(24022u16,5043u16),(24027u16,5044u16),(24029u16,2991u16), (24030u16,2634u16),(24033u16,2699u16),(24035u16,3074u16),(24037u16,2264u16), (24038u16,2373u16),(24039u16,2265u16),(24040u16,1959u16),(24043u16,5045u16), (24046u16,2374u16),(24049u16,2203u16),(24050u16,5046u16),(24051u16,4047u16), (24052u16,3606u16),(24053u16,5047u16),(24055u16,2266u16),(24059u16,1797u16), (24061u16,3202u16),(24062u16,2023u16),(24066u16,2495u16),(24067u16,3818u16), (24070u16,3698u16),(24075u16,5048u16),(24076u16,1870u16),(24081u16,5051u16), (24086u16,3290u16),(24089u16,5050u16),(24090u16,5049u16),(24091u16,5052u16), (24093u16,3364u16),(24101u16,2886u16),(24107u16,2496u16),(24109u16,2955u16), (24111u16,3152u16),(24112u16,1881u16),(24115u16,3291u16),(24118u16,5053u16), (24119u16,5054u16),(24120u16,2804u16),(24125u16,3972u16),(24128u16,5057u16), (24131u16,5056u16),(24132u16,5055u16),(24133u16,3852u16),(24135u16,5064u16), (24140u16,4005u16),(24142u16,5058u16),(24148u16,5060u16),(24149u16,4022u16), (24151u16,5059u16),(24159u16,5061u16),(24161u16,3673u16),(24162u16,5062u16), (24163u16,3883u16),(24164u16,5063u16),(24178u16,1804u16),(24179u16,3884u16), (24180u16,3586u16),(24181u16,5065u16),(24182u16,5066u16),(24184u16,2267u16), (24185u16,1805u16),(24186u16,5067u16),(24187u16,2185u16),(24188u16,4171u16), (24189u16,4144u16),(24190u16,1871u16),(24191u16,5069u16),(24193u16,3292u16), (24195u16,2268u16),(24196u16,2742u16),(24199u16,3728u16),(24202u16,2743u16), (24207u16,2719u16),(24213u16,3365u16),(24214u16,3942u16),(24215u16,3408u16), (24218u16,2269u16),(24220u16,3819u16),(24224u16,5070u16),(24230u16,3440u16), (24231u16,2383u16),(24235u16,2204u16),(24237u16,3366u16),(24245u16,1444u16), (24246u16,2709u16),(24247u16,2270u16),(24248u16,4174u16),(24257u16,5071u16), (24258u16,5072u16),(24259u16,3620u16),(24264u16,5073u16),(24265u16,4316u16), (24266u16,4336u16),(24271u16,5075u16),(24272u16,5074u16),(24275u16,1730u16), (24278u16,5076u16),(24282u16,5079u16),(24283u16,5080u16),(24285u16,5078u16), (24287u16,3791u16),(24288u16,2744u16),(24289u16,5082u16),(24290u16,5081u16), (24291u16,5077u16),(24296u16,5083u16),(24297u16,5084u16),(24300u16,5085u16), (24304u16,5088u16),(24305u16,5086u16),(24307u16,5087u16),(24308u16,5089u16), (24310u16,1571u16),(24311u16,3367u16),(24312u16,5090u16),(24314u16,2157u16), (24315u16,1683u16),(24316u16,3593u16),(24318u16,5091u16),(24319u16,3568u16), (24321u16,3912u16),(24323u16,5092u16),(24324u16,4337u16),(24329u16,5093u16), (24330u16,3885u16),(24331u16,5096u16),(24332u16,4418u16),(24333u16,4434u16), (24335u16,2553u16),(24336u16,3562u16),(24337u16,5097u16),(24339u16,1940u16), (24340u16,3293u16),(24341u16,1499u16),(24342u16,5098u16),(24343u16,3859u16), (24344u16,2271u16),(24347u16,3243u16),(24351u16,3368u16),(24353u16,8362u16), (24357u16,4120u16),(24358u16,2186u16),(24359u16,2205u16),(24361u16,5099u16), (24365u16,5100u16),(24367u16,5106u16),(24369u16,2606u16),(24372u16,8363u16), (24373u16,3294u16),(24375u16,1988u16),(24376u16,5101u16),(24380u16,3770u16), (24382u16,3233u16),(24385u16,5102u16),(24389u16,8283u16),(24392u16,5103u16), (24394u16,1989u16),(24396u16,5104u16),(24398u16,5105u16),(24401u16,5107u16), (24403u16,3469u16),(24406u16,5108u16),(24407u16,5109u16),(24409u16,5110u16), (24412u16,5095u16),(24413u16,5094u16),(24417u16,5111u16),(24418u16,2100u16), (24422u16,3766u16),(24423u16,8364u16),(24425u16,2393u16),(24426u16,3782u16), (24427u16,3295u16),(24428u16,3802u16),(24429u16,5112u16),(24432u16,2745u16), (24433u16,1541u16),(24435u16,5113u16),(24439u16,5114u16),(24441u16,4123u16), (24444u16,3729u16),(24447u16,5117u16),(24448u16,1596u16),(24449u16,2925u16), (24450u16,5116u16),(24451u16,5115u16),(24452u16,2101u16),(24453u16,3153u16), (24455u16,5121u16),(24456u16,5119u16),(24458u16,5118u16),(24459u16,4236u16), (24460u16,2230u16),(24464u16,2720u16),(24465u16,5120u16),(24466u16,3427u16), (24467u16,2661u16),(24471u16,3509u16),(24472u16,5124u16),(24473u16,5123u16), (24478u16,5122u16),(24480u16,5125u16),(24481u16,2231u16),(24488u16,5126u16), (24489u16,3851u16),(24490u16,2690u16),(24493u16,5127u16),(24494u16,3754u16), (24499u16,3510u16),(24500u16,3296u16),(24503u16,8365u16),(24505u16,3399u16), (24508u16,5128u16),(24509u16,1890u16),(24515u16,2839u16),(24517u16,3771u16), (24524u16,1872u16),(24525u16,3577u16),(24534u16,5129u16),(24535u16,2497u16), (24536u16,3973u16),(24537u16,3974u16),(24540u16,1597u16),(24541u16,5134u16), (24542u16,8366u16),(24544u16,3268u16),(24548u16,5131u16),(24555u16,1684u16), (24560u16,5182u16),(24561u16,5133u16),(24565u16,3587u16),(24568u16,5132u16), (24571u16,5130u16),(24573u16,2345u16),(24575u16,5136u16),(24590u16,5142u16), (24591u16,5148u16),(24592u16,5140u16),(24594u16,3443u16),(24597u16,5145u16), (24598u16,3820u16),(24601u16,5139u16),(24603u16,5144u16),(24604u16,4300u16), (24605u16,2498u16),(24608u16,3154u16),(24609u16,5137u16),(24613u16,1941u16), (24614u16,5147u16),(24615u16,2926u16),(24616u16,1572u16),(24617u16,5141u16), (24618u16,1685u16),(24619u16,5146u16),(24623u16,1990u16),(24625u16,5143u16), (24634u16,5149u16),(24641u16,5151u16),(24642u16,5161u16),(24643u16,5159u16), (24646u16,5156u16),(24650u16,5155u16),(24651u16,4317u16),(24653u16,5157u16), (24656u16,1991u16),(24658u16,2272u16),(24661u16,2721u16),(24665u16,5164u16), (24666u16,5150u16),(24669u16,8367u16),(24671u16,5154u16),(24672u16,5138u16), (24674u16,1687u16),(24675u16,5158u16),(24676u16,5160u16),(24677u16,3244u16), (24680u16,2357u16),(24681u16,1621u16),(24682u16,5152u16),(24683u16,5163u16), (24684u16,5162u16),(24685u16,1992u16),(24687u16,3110u16),(24688u16,1761u16), (24693u16,2102u16),(24695u16,5153u16),(24705u16,5165u16),(24707u16,5168u16), (24708u16,5170u16),(24709u16,8368u16),(24713u16,2566u16),(24714u16,8369u16), (24715u16,5176u16),(24716u16,3369u16),(24717u16,5166u16),(24722u16,5174u16), (24724u16,1686u16),(24726u16,5172u16),(24727u16,5173u16),(24730u16,5169u16), (24731u16,5171u16),(24735u16,2232u16),(24736u16,4145u16),(24739u16,1806u16), (24742u16,1560u16),(24743u16,5175u16),(24745u16,3597u16),(24746u16,1422u16), (24754u16,3730u16),(24755u16,5135u16),(24756u16,5181u16),(24757u16,5185u16), (24758u16,4110u16),(24760u16,5178u16),(24764u16,3456u16),(24765u16,5183u16), (24773u16,2805u16),(24774u16,5184u16),(24775u16,3532u16),(24785u16,4362u16), (24787u16,5180u16),(24789u16,8371u16),(24792u16,5186u16),(24794u16,2346u16), (24796u16,2956u16),(24798u16,8370u16),(24799u16,1461u16),(24800u16,5179u16), (24801u16,5177u16),(24803u16,3065u16),(24807u16,5167u16),(24808u16,2463u16), (24816u16,3139u16),(24817u16,5198u16),(24818u16,8373u16),(24819u16,3066u16), (24820u16,5193u16),(24822u16,5190u16),(24823u16,5191u16),(24825u16,2607u16), (24826u16,5194u16),(24827u16,5197u16),(24832u16,5192u16),(24833u16,2636u16), (24835u16,5195u16),(24838u16,5189u16),(24840u16,4133u16),(24841u16,4132u16), (24845u16,5199u16),(24846u16,5200u16),(24847u16,1462u16),(24849u16,8374u16), (24853u16,5188u16),(24858u16,2055u16),(24859u16,1415u16),(24863u16,1807u16), (24864u16,8372u16),(24865u16,5196u16),(24871u16,5204u16),(24872u16,5203u16), (24876u16,5208u16),(24880u16,8376u16),(24884u16,5209u16),(24887u16,8375u16), (24892u16,5207u16),(24893u16,5210u16),(24894u16,5202u16),(24895u16,5206u16), (24898u16,5211u16),(24900u16,5212u16),(24903u16,5201u16),(24904u16,2535u16), (24906u16,5205u16),(24907u16,3155u16),(24908u16,2273u16),(24909u16,5187u16), (24910u16,2840u16),(24915u16,5225u16),(24917u16,3926u16),(24920u16,5215u16), (24921u16,5216u16),(24922u16,5217u16),(24925u16,5224u16),(24927u16,5223u16), (24930u16,4040u16),(24931u16,1808u16),(24933u16,5221u16),(24935u16,2104u16), (24936u16,1711u16),(24939u16,5218u16),(24942u16,4253u16),(24943u16,5220u16), (24944u16,1463u16),(24945u16,5222u16),(24947u16,5213u16),(24948u16,5219u16), (24949u16,5226u16),(24950u16,2103u16),(24951u16,5214u16),(24958u16,4196u16), (24962u16,4146u16),(24967u16,5229u16),(24970u16,5233u16),(24974u16,3101u16), (24976u16,4318u16),(24977u16,5234u16),(24980u16,5231u16),(24982u16,5228u16), (24984u16,8377u16),(24985u16,5227u16),(24986u16,5232u16),(24996u16,3869u16), (24999u16,3497u16),(25001u16,2105u16),(25003u16,5235u16),(25004u16,5230u16), (25006u16,5236u16),(25010u16,2158u16),(25014u16,1614u16),(25018u16,5244u16), (25022u16,1809u16),(25027u16,5242u16),(25030u16,5243u16),(25031u16,2358u16), (25032u16,5241u16),(25033u16,5239u16),(25034u16,5238u16),(25035u16,5245u16), (25036u16,5237u16),(25037u16,5247u16),(25040u16,1688u16),(25059u16,5249u16), (25062u16,5248u16),(25074u16,3297u16),(25076u16,5252u16),(25078u16,5250u16), (25079u16,5240u16),(25080u16,2159u16),(25082u16,5251u16),(25084u16,5255u16), (25085u16,5254u16),(25086u16,5256u16),(25087u16,5253u16),(25088u16,5257u16), (25096u16,5258u16),(25097u16,5259u16),(25098u16,3927u16),(25100u16,5261u16), (25101u16,5260u16),(25102u16,2662u16),(25104u16,2927u16),(25105u16,1667u16), (25106u16,1689u16),(25107u16,8378u16),(25108u16,5262u16),(25110u16,1440u16), (25114u16,2957u16),(25115u16,5263u16),(25117u16,7084u16),(25118u16,5264u16), (25119u16,2132u16),(25121u16,5265u16),(25126u16,2992u16),(25130u16,5266u16), (25134u16,5267u16),(25135u16,1905u16),(25136u16,5268u16),(25138u16,5269u16), (25139u16,5270u16),(25140u16,3156u16),(25144u16,2206u16),(25147u16,4106u16), (25151u16,3975u16),(25152u16,2705u16),(25153u16,5271u16),(25159u16,2993u16), (25160u16,7266u16),(25161u16,3731u16),(25163u16,2611u16),(25165u16,2394u16), (25166u16,5272u16),(25171u16,3140u16),(25173u16,3860u16),(25176u16,3182u16), (25179u16,5275u16),(25182u16,5273u16),(25184u16,5276u16),(25187u16,5274u16), (25192u16,5277u16),(25198u16,3870u16),(25201u16,1432u16),(25206u16,3821u16), (25209u16,3732u16),(25212u16,5278u16),(25214u16,5281u16),(25215u16,2746u16), (25216u16,1906u16),(25218u16,5279u16),(25219u16,5286u16),(25220u16,2747u16), (25225u16,5280u16),(25226u16,3607u16),(25233u16,4197u16),(25234u16,5282u16), (25235u16,5283u16),(25236u16,5287u16),(25237u16,3457u16),(25238u16,5284u16), (25239u16,2274u16),(25240u16,2975u16),(25243u16,5301u16),(25244u16,3685u16), (25246u16,3183u16),(25254u16,8379u16),(25259u16,3733u16),(25260u16,5370u16), (25265u16,3943u16),(25269u16,3370u16),(25273u16,4032u16),(25275u16,5290u16), (25276u16,1598u16),(25277u16,3269u16),(25282u16,5299u16),(25285u16,3215u16), (25286u16,5293u16),(25287u16,5300u16),(25288u16,5295u16),(25289u16,5302u16), (25290u16,5298u16),(25292u16,5297u16),(25293u16,3650u16),(25295u16,5291u16), (25296u16,1690u16),(25297u16,5289u16),(25298u16,1960u16),(25299u16,3184u16), (25300u16,5285u16),(25303u16,5288u16),(25304u16,2275u16),(25305u16,2972u16), (25307u16,2748u16),(25308u16,5296u16),(25309u16,3621u16),(25312u16,1961u16), (25313u16,1731u16),(25324u16,1762u16),(25325u16,2820u16),(25326u16,5304u16), (25327u16,5309u16),(25329u16,5305u16),(25331u16,2160u16),(25333u16,5310u16), (25334u16,2445u16),(25335u16,2328u16),(25342u16,2637u16),(25343u16,5292u16), (25345u16,2536u16),(25346u16,5307u16),(25351u16,2499u16),(25352u16,5308u16), (25353u16,1445u16),(25356u16,5303u16),(25361u16,3298u16),(25369u16,1962u16), (25375u16,1993u16),(25383u16,5306u16),(25384u16,1416u16),(25387u16,2384u16), (25391u16,2841u16),(25402u16,3371u16),(25405u16,3717u16),(25406u16,5312u16), (25407u16,3069u16),(25417u16,3111u16),(25420u16,2454u16),(25421u16,5313u16), (25423u16,5315u16),(25424u16,5311u16),(25429u16,3918u16),(25431u16,3318u16), (25436u16,3067u16),(25447u16,3944u16),(25448u16,2583u16),(25449u16,5327u16), (25451u16,5326u16),(25454u16,2907u16),(25458u16,2161u16),(25462u16,5320u16), (25463u16,2750u16),(25466u16,3549u16),(25467u16,3588u16),(25472u16,5318u16), (25475u16,3068u16),(25480u16,2625u16),(25481u16,5323u16),(25484u16,2749u16), (25486u16,5317u16),(25487u16,5322u16),(25490u16,3622u16),(25494u16,5316u16), (25496u16,2068u16),(25499u16,1752u16),(25503u16,5324u16),(25504u16,4240u16), (25505u16,2395u16),(25506u16,3216u16),(25507u16,5321u16),(25509u16,2973u16), (25511u16,2276u16),(25512u16,2887u16),(25513u16,1573u16),(25514u16,3035u16), (25515u16,5319u16),(25516u16,1916u16),(25522u16,2106u16),(25524u16,3336u16), (25525u16,5325u16),(25531u16,3070u16),(25534u16,5328u16),(25536u16,5330u16), (25539u16,3124u16),(25540u16,5336u16),(25542u16,5331u16),(25545u16,5333u16), (25551u16,3792u16),(25552u16,3372u16),(25554u16,5334u16),(25558u16,4147u16), (25562u16,4175u16),(25563u16,1810u16),(25569u16,1423u16),(25571u16,5332u16), (25577u16,5329u16),(25582u16,1873u16),(25588u16,1574u16),(25589u16,8380u16), (25590u16,5335u16),(25594u16,4176u16),(25606u16,5339u16),(25613u16,3128u16), (25615u16,5346u16),(25619u16,5340u16),(25622u16,5337u16),(25623u16,5344u16), (25628u16,5314u16),(25638u16,5341u16),(25640u16,5345u16),(25644u16,3699u16), (25645u16,3458u16),(25652u16,5338u16),(25654u16,5342u16),(25658u16,2107u16), (25662u16,2430u16),(25666u16,2974u16),(25678u16,5350u16),(25688u16,3389u16), (25696u16,8381u16),(25703u16,5347u16),(25705u16,4011u16),(25711u16,5348u16), (25718u16,5349u16),(25720u16,4087u16),(25722u16,2915u16),(25731u16,2133u16), (25736u16,5356u16),(25746u16,2464u16),(25747u16,5353u16),(25749u16,5352u16), (25754u16,3589u16),(25757u16,8382u16),(25758u16,3498u16),(25764u16,3400u16), (25765u16,5354u16),(25769u16,5355u16),(25771u16,3838u16),(25773u16,3608u16), (25774u16,2446u16),(25776u16,2994u16),(25778u16,3995u16),(25785u16,1732u16), (25787u16,5362u16),(25788u16,5357u16),(25793u16,4177u16),(25794u16,5364u16), (25797u16,5360u16),(25799u16,5361u16),(25805u16,3071u16),(25806u16,8383u16), (25810u16,5359u16),(25812u16,5294u16),(25816u16,5363u16),(25818u16,5358u16), (25824u16,5368u16),(25825u16,5369u16),(25826u16,3390u16),(25827u16,5371u16), (25830u16,2447u16),(25831u16,5366u16),(25836u16,1907u16),(25839u16,5372u16), (25841u16,5365u16),(25842u16,5376u16),(25844u16,5375u16),(25846u16,5374u16), (25850u16,5377u16),(25853u16,5379u16),(25854u16,2806u16),(25856u16,5378u16), (25861u16,5382u16),(25880u16,5380u16),(25884u16,5381u16),(25885u16,5343u16), (25891u16,5384u16),(25892u16,5383u16),(25898u16,5351u16),(25899u16,5385u16), (25900u16,5373u16),(25903u16,2500u16),(25908u16,5386u16),(25909u16,5387u16), (25910u16,5389u16),(25911u16,5388u16),(25912u16,5390u16),(25913u16,1691u16), (25915u16,2277u16),(25918u16,3945u16),(25919u16,2928u16),(25925u16,2207u16), (25928u16,5392u16),(25933u16,5395u16),(25934u16,8384u16),(25935u16,3809u16), (25937u16,1942u16),(25941u16,5394u16),(25942u16,5393u16),(25943u16,3623u16), (25944u16,5396u16),(25945u16,1994u16),(25949u16,5398u16),(25950u16,5397u16), (25954u16,1811u16),(25955u16,2465u16),(25958u16,3533u16),(25964u16,2108u16), (25968u16,2903u16),(25970u16,5399u16),(25972u16,2929u16),(25973u16,3391u16), (25975u16,3822u16),(25976u16,5400u16),(25986u16,5401u16),(25987u16,5402u16), (25991u16,3877u16),(25992u16,4948u16),(25993u16,2951u16),(25996u16,3803u16), (25998u16,2405u16),(26000u16,3734u16),(26001u16,3700u16),(26007u16,3428u16), (26009u16,4262u16),(26011u16,5404u16),(26012u16,2585u16),(26015u16,5405u16), (26017u16,1431u16),(26020u16,2025u16),(26021u16,2958u16),(26023u16,3823u16), (26027u16,5406u16),(26028u16,2477u16),(26029u16,3234u16),(26031u16,2502u16), (26032u16,2842u16),(26039u16,5407u16),(26041u16,3946u16),(26044u16,1590u16), (26045u16,2503u16),(26049u16,5410u16),(26051u16,5408u16),(26052u16,5411u16), (26053u16,4254u16),(26054u16,5409u16),(26059u16,3004u16),(26060u16,5412u16), (26063u16,3119u16),(26066u16,5413u16),(26071u16,1875u16),(26073u16,5415u16), (26075u16,5414u16),(26080u16,5416u16),(26081u16,5417u16),(26082u16,1876u16), (26085u16,3569u16),(26086u16,3217u16),(26087u16,1955u16),(26088u16,2504u16), (26089u16,3072u16),(26092u16,2691u16),(26093u16,1425u16),(26097u16,5418u16), (26106u16,1599u16),(26107u16,5422u16),(26112u16,8385u16),(26114u16,2278u16), (26115u16,5421u16),(26118u16,2360u16),(26119u16,2751u16),(26121u16,8388u16), (26122u16,5420u16),(26124u16,2752u16),(26126u16,4073u16),(26127u16,2359u16), (26131u16,1464u16),(26132u16,2959u16),(26133u16,8386u16),(26140u16,5427u16), (26142u16,8390u16),(26143u16,2930u16),(26144u16,1542u16),(26148u16,8391u16), (26149u16,2684u16),(26151u16,4017u16),(26152u16,2431u16),(26157u16,2753u16), (26158u16,8389u16),(26159u16,2920u16),(26161u16,8279u16),(26164u16,5426u16), (26165u16,5424u16),(26166u16,5425u16),(26171u16,8387u16),(26172u16,3270u16), (26175u16,5457u16),(26177u16,5431u16),(26178u16,2537u16),(26179u16,2279u16), (26180u16,5429u16),(26185u16,5430u16),(26187u16,2843u16),(26191u16,5428u16), (26194u16,2458u16),(26199u16,8393u16),(26201u16,8394u16),(26205u16,5433u16), (26206u16,5432u16),(26207u16,5437u16),(26210u16,5438u16),(26212u16,5434u16), (26213u16,8392u16),(26214u16,1693u16),(26215u16,5435u16),(26216u16,5436u16), (26217u16,3718u16),(26222u16,3824u16),(26223u16,2109u16),(26224u16,5439u16), (26227u16,8396u16),(26228u16,2931u16),(26230u16,2754u16),(26234u16,3245u16), (26241u16,2012u16),(26243u16,5440u16),(26244u16,5444u16),(26247u16,1640u16), (26248u16,5441u16),(26249u16,5443u16),(26254u16,5442u16),(26257u16,2706u16), (26262u16,3235u16),(26263u16,1446u16),(26264u16,5445u16),(26265u16,8397u16), (26269u16,5446u16),(26272u16,8398u16),(26274u16,3299u16),(26278u16,4310u16), (26283u16,2478u16),(26286u16,3928u16),(26290u16,8399u16),(26292u16,3976u16), (26296u16,5453u16),(26297u16,5448u16),(26300u16,5451u16),(26302u16,5450u16), (26303u16,8400u16),(26305u16,5447u16),(26308u16,5452u16),(26311u16,3539u16), (26313u16,5449u16),(26326u16,5454u16),(26329u16,2707u16),(26330u16,5455u16), (26332u16,4178u16),(26333u16,3659u16),(26336u16,5456u16),(26342u16,5458u16), (26345u16,5459u16),(26352u16,5460u16),(26354u16,2015u16),(26355u16,1543u16), (26356u16,2280u16),(26357u16,5461u16),(26359u16,5462u16),(26360u16,2712u16), (26361u16,3073u16),(26362u16,8401u16),(26363u16,8282u16),(26364u16,4661u16), (26365u16,3037u16),(26366u16,3036u16),(26367u16,3157u16),(26368u16,2388u16), (26371u16,4499u16),(26376u16,2145u16),(26377u16,4148u16),(26379u16,3947u16), (26381u16,3853u16),(26382u16,8402u16),(26383u16,5463u16),(26388u16,2432u16), (26389u16,3320u16),(26390u16,5464u16),(26391u16,4338u16),(26395u16,3977u16), (26397u16,3300u16),(26398u16,5465u16),(26399u16,1877u16),(26406u16,5466u16), (26407u16,5467u16),(26408u16,4099u16),(26410u16,4045u16),(26411u16,4033u16), (26412u16,4007u16),(26413u16,2448u16),(26414u16,5469u16),(26417u16,2612u16), (26420u16,3996u16),(26422u16,5471u16),(26423u16,5474u16),(26424u16,5473u16), (26426u16,1874u16),(26429u16,1943u16),(26431u16,5470u16),(26433u16,5472u16), (26438u16,5475u16),(26441u16,2908u16),(26446u16,4226u16),(26447u16,1450u16), (26448u16,2413u16),(26449u16,3129u16),(26451u16,2598u16),(26454u16,2808u16), (26457u16,5478u16),(26460u16,3429u16),(26462u16,5476u16),(26463u16,3112u16), (26464u16,5477u16),(26465u16,2807u16),(26466u16,4102u16),(26467u16,5479u16), (26468u16,5480u16),(26469u16,4207u16),(26470u16,8404u16),(26474u16,5485u16), (26477u16,2281u16),(26479u16,3624u16),(26480u16,5482u16),(26481u16,3459u16), (26482u16,5419u16),(26483u16,5423u16),(26485u16,1926u16),(26487u16,3610u16), (26492u16,5484u16),(26494u16,2755u16),(26495u16,3701u16),(26501u16,5490u16), (26503u16,3755u16),(26505u16,5481u16),(26507u16,5487u16),(26508u16,5486u16), (26512u16,2960u16),(26517u16,4024u16),(26519u16,4280u16),(26522u16,4018u16), (26524u16,1641u16),(26525u16,2505u16),(26528u16,4363u16),(26529u16,5489u16), (26530u16,2904u16),(26534u16,5488u16),(26537u16,5483u16),(26543u16,2208u16), (26547u16,5495u16),(26548u16,5493u16),(26550u16,1642u16),(26551u16,5491u16), (26552u16,5497u16),(26553u16,5503u16),(26555u16,8405u16),(26560u16,8407u16), (26561u16,3141u16),(26564u16,3886u16),(26566u16,5505u16),(26570u16,3761u16), (26574u16,5504u16),(26575u16,3651u16),(26576u16,3978u16),(26577u16,1812u16), (26579u16,3000u16),(26580u16,2663u16),(26584u16,3340u16),(26586u16,4149u16), (26589u16,5500u16),(26590u16,5499u16),(26594u16,5501u16),(26596u16,5498u16), (26599u16,5506u16),(26601u16,5496u16),(26604u16,5494u16),(26606u16,5502u16), (26607u16,5492u16),(26609u16,3271u16),(26611u16,4129u16),(26612u16,2575u16), (26613u16,2433u16),(26619u16,2375u16),(26622u16,4026u16),(26623u16,1724u16), (26625u16,8408u16),(26626u16,3335u16),(26627u16,3519u16),(26628u16,1544u16), (26643u16,2995u16),(26646u16,2933u16),(26647u16,2077u16),(26654u16,5508u16), (26657u16,2282u16),(26658u16,1783u16),(26665u16,5510u16),(26666u16,1775u16), (26667u16,5516u16),(26674u16,5513u16),(26676u16,2996u16),(26680u16,1734u16), (26681u16,2361u16),(26684u16,1733u16),(26685u16,2396u16),(26688u16,5511u16), (26689u16,2136u16),(26690u16,2110u16),(26691u16,3460u16),(26692u16,8409u16), (26694u16,5509u16),(26696u16,1447u16),(26701u16,5512u16),(26702u16,5514u16), (26704u16,2018u16),(26705u16,2079u16),(26706u16,8406u16),(26707u16,1813u16), (26708u16,1922u16),(26713u16,5517u16),(26716u16,2438u16),(26717u16,4028u16), (26719u16,2466u16),(26723u16,5518u16),(26727u16,3775u16),(26740u16,5530u16), (26742u16,1616u16),(26743u16,5519u16),(26750u16,5536u16),(26751u16,5520u16), (26753u16,4263u16),(26755u16,5527u16),(26757u16,3634u16),(26765u16,5535u16), (26767u16,5522u16),(26771u16,1429u16),(26772u16,5524u16),(26775u16,2283u16), (26779u16,5526u16),(26781u16,5525u16),(26783u16,5521u16),(26784u16,5532u16), (26786u16,2756u16),(26790u16,4870u16),(26791u16,2233u16),(26792u16,4227u16), (26797u16,5523u16),(26799u16,3373u16),(26800u16,1694u16),(26801u16,2362u16), (26803u16,5515u16),(26805u16,5531u16),(26806u16,1756u16),(26809u16,5529u16), (26810u16,5533u16),(26812u16,3461u16),(26820u16,1879u16),(26822u16,5563u16), (26824u16,8280u16),(26825u16,4082u16),(26826u16,5538u16),(26827u16,1878u16), (26829u16,5545u16),(26831u16,8410u16),(26834u16,3979u16),(26836u16,5546u16), (26837u16,5548u16),(26839u16,5552u16),(26840u16,5540u16),(26842u16,3205u16), (26847u16,3462u16),(26848u16,5556u16),(26849u16,5543u16),(26851u16,5553u16), (26855u16,5547u16),(26862u16,2844u16),(26863u16,5557u16),(26866u16,2932u16), (26873u16,5555u16),(26874u16,1814u16),(26880u16,4371u16),(26881u16,5537u16), (26884u16,5551u16),(26885u16,1465u16),(26888u16,5539u16),(26891u16,4067u16), (26892u16,5544u16),(26893u16,2821u16),(26894u16,3328u16),(26895u16,5534u16), (26898u16,5550u16),(26905u16,2909u16),(26906u16,5560u16),(26907u16,1772u16), (26908u16,2162u16),(26913u16,5562u16),(26914u16,5541u16),(26915u16,5561u16), (26917u16,5554u16),(26918u16,5542u16),(26920u16,5558u16),(26922u16,5559u16), (26928u16,5576u16),(26932u16,3523u16),(26934u16,5549u16),(26937u16,5572u16), (26941u16,5574u16),(26943u16,3345u16),(26954u16,4179u16),(26963u16,3845u16), (26964u16,5569u16),(26965u16,3143u16),(26969u16,5575u16),(26970u16,3038u16), (26972u16,5566u16),(26973u16,5579u16),(26974u16,5578u16),(26976u16,3556u16), (26977u16,5577u16),(26978u16,3551u16),(26984u16,8412u16),(26986u16,5581u16), (26987u16,5568u16),(26989u16,2013u16),(26990u16,5571u16),(26991u16,2692u16), (26995u16,3635u16),(26996u16,5573u16),(26997u16,2016u16),(26999u16,5565u16), (27000u16,5567u16),(27001u16,5564u16),(27004u16,4339u16),(27005u16,1749u16), (27006u16,5570u16),(27009u16,5580u16),(27010u16,1712u16),(27018u16,2420u16), (27022u16,1564u16),(27025u16,5597u16),(27028u16,4340u16),(27029u16,5600u16), (27032u16,8414u16),(27035u16,2845u16),(27036u16,5599u16),(27040u16,5598u16), (27047u16,5595u16),(27054u16,5583u16),(27057u16,5612u16),(27058u16,5582u16), (27060u16,5601u16),(27067u16,5593u16),(27070u16,5588u16),(27071u16,5585u16), (27073u16,5586u16),(27075u16,5594u16),(27079u16,7803u16),(27082u16,5591u16), (27083u16,2284u16),(27084u16,3329u16),(27085u16,3075u16),(27086u16,5589u16), (27088u16,5584u16),(27091u16,5587u16),(27096u16,4180u16),(27097u16,4021u16), (27101u16,5592u16),(27102u16,5602u16),(27106u16,8415u16),(27111u16,5610u16), (27112u16,5603u16),(27115u16,5616u16),(27117u16,5614u16),(27122u16,5609u16), (27129u16,5608u16),(27131u16,3337u16),(27133u16,3076u16),(27135u16,5606u16), (27138u16,5604u16),(27141u16,5611u16),(27146u16,5617u16),(27147u16,3750u16), (27148u16,5623u16),(27154u16,5618u16),(27155u16,5621u16),(27156u16,5615u16), (27159u16,3279u16),(27161u16,3783u16),(27163u16,5605u16),(27166u16,5613u16), (27167u16,2757u16),(27169u16,4088u16),(27170u16,5633u16),(27171u16,5620u16), (27177u16,2163u16),(27178u16,1600u16),(27179u16,1754u16),(27182u16,5596u16), (27184u16,8416u16),(27189u16,2758u16),(27190u16,5625u16),(27192u16,5632u16), (27193u16,2626u16),(27194u16,1773u16),(27197u16,3209u16),(27204u16,5622u16), (27206u16,8418u16),(27207u16,5627u16),(27208u16,5631u16),(27211u16,1995u16), (27224u16,1923u16),(27225u16,5629u16),(27231u16,1880u16),(27233u16,3520u16), (27234u16,5628u16),(27238u16,5630u16),(27243u16,8417u16),(27250u16,5624u16), (27251u16,8419u16),(27256u16,5626u16),(27262u16,8420u16),(27263u16,1755u16), (27264u16,3236u16),(27268u16,5637u16),(27277u16,5635u16),(27278u16,2234u16), (27280u16,5634u16),(27287u16,5640u16),(27292u16,5507u16),(27296u16,5636u16), (27298u16,5638u16),(27299u16,5639u16),(27306u16,5651u16),(27308u16,5647u16), (27310u16,5528u16),(27315u16,5646u16),(27320u16,5645u16),(27323u16,5642u16), (27329u16,5619u16),(27330u16,5644u16),(27331u16,5643u16),(27345u16,5649u16), (27347u16,4329u16),(27354u16,5652u16),(27355u16,2064u16),(27358u16,5648u16), (27359u16,5650u16),(27362u16,8421u16),(27364u16,8422u16),(27368u16,3672u16), (27370u16,5653u16),(27386u16,5657u16),(27387u16,5654u16),(27396u16,4218u16), (27397u16,5655u16),(27402u16,5607u16),(27410u16,5658u16),(27414u16,5659u16), (27421u16,1524u16),(27423u16,5661u16),(27424u16,2138u16),(27425u16,2538u16), (27427u16,2026u16),(27431u16,1601u16),(27442u16,4198u16),(27447u16,5663u16), (27448u16,5662u16),(27449u16,5665u16),(27450u16,1908u16),(27453u16,2027u16), (27454u16,1815u16),(27459u16,5668u16),(27463u16,5667u16),(27465u16,5669u16), (27468u16,1643u16),(27470u16,3218u16),(27472u16,5670u16),(27475u16,1816u16), (27476u16,5672u16),(27481u16,5671u16),(27483u16,5673u16),(27487u16,5674u16), (27489u16,5675u16),(27490u16,2506u16),(27491u16,2934u16),(27492u16,2350u16), (27494u16,3839u16),(27497u16,3919u16),(27498u16,4359u16),(27503u16,2528u16), (27507u16,2397u16),(27508u16,4311u16),(27512u16,5676u16),(27513u16,5677u16), (27515u16,2507u16),(27519u16,5678u16),(27520u16,5679u16),(27523u16,5681u16), (27524u16,5680u16),(27526u16,4003u16),(27529u16,2693u16),(27530u16,2613u16), (27531u16,2479u16),(27533u16,5682u16),(27541u16,5684u16),(27542u16,2822u16), (27544u16,5683u16),(27550u16,5685u16),(27556u16,5686u16),(27562u16,5687u16), (27563u16,5688u16),(27567u16,5689u16),(27569u16,5691u16),(27570u16,5690u16), (27571u16,5692u16),(27572u16,1602u16),(27573u16,3237u16),(27575u16,5693u16), (27578u16,2449u16),(27579u16,1735u16),(27580u16,5694u16),(27583u16,3417u16), (27584u16,4837u16),(27589u16,1882u16),(27590u16,5695u16),(27595u16,5696u16), (27597u16,3929u16),(27598u16,4019u16),(27602u16,3516u16),(27603u16,5697u16), (27604u16,3735u16),(27606u16,8423u16),(27608u16,3756u16),(27611u16,4092u16), (27615u16,5698u16),(27627u16,5700u16),(27628u16,5699u16),(27631u16,5702u16), (27635u16,5701u16),(27656u16,5704u16),(27663u16,2508u16),(27665u16,4058u16), (27667u16,5705u16),(27668u16,5706u16),(27671u16,1883u16),(27675u16,5707u16), (27683u16,5709u16),(27684u16,5708u16),(27700u16,2888u16),(27703u16,3784u16), (27704u16,1545u16),(27710u16,3702u16),(27711u16,8424u16),(27712u16,3374u16), (27713u16,2664u16),(27714u16,1944u16),(27726u16,3703u16),(27728u16,2551u16), (27733u16,5711u16),(27735u16,1817u16),(27738u16,1591u16),(27740u16,8425u16), (27741u16,3559u16),(27742u16,5710u16),(27743u16,2285u16),(27744u16,3246u16), (27746u16,5712u16),(27752u16,5720u16),(27754u16,5713u16),(27759u16,8427u16), (27760u16,3134u16),(27762u16,1945u16),(27763u16,5721u16),(27770u16,2139u16), (27773u16,1884u16),(27774u16,5719u16),(27777u16,5717u16),(27778u16,5714u16), (27779u16,4199u16),(27782u16,8426u16),(27784u16,3321u16),(27788u16,3534u16), (27789u16,5715u16),(27792u16,5723u16),(27794u16,5722u16),(27795u16,2070u16), (27798u16,1610u16),(27801u16,2376u16),(27802u16,5716u16),(27803u16,5718u16), (27809u16,4002u16),(27810u16,3185u16),(27819u16,4034u16),(27822u16,5731u16), (27825u16,5732u16),(27827u16,1644u16),(27832u16,3861u16),(27833u16,4134u16), (27834u16,5734u16),(27835u16,2540u16),(27836u16,2759u16),(27837u16,5727u16), (27838u16,5733u16),(27839u16,1575u16),(27841u16,1996u16),(27844u16,5724u16), (27845u16,5729u16),(27849u16,2997u16),(27850u16,3652u16),(27852u16,3736u16), (27859u16,5726u16),(27861u16,3948u16),(27863u16,5728u16),(27865u16,5737u16), (27866u16,8428u16),(27867u16,5735u16),(27869u16,5730u16),(27873u16,3949u16), (27874u16,3611u16),(27875u16,1946u16),(27877u16,3388u16),(27880u16,3272u16), (27882u16,5738u16),(27887u16,5736u16),(27888u16,3158u16),(27889u16,5725u16), (27891u16,1546u16),(27908u16,8429u16),(27915u16,4181u16),(27916u16,5749u16), (27922u16,5748u16),(27927u16,2999u16),(27929u16,5745u16),(27931u16,4211u16), (27934u16,3499u16),(27935u16,5739u16),(27941u16,3326u16),(27945u16,1547u16), (27946u16,2286u16),(27947u16,5742u16),(27954u16,2638u16),(27955u16,5747u16), (27957u16,5746u16),(27958u16,5741u16),(27960u16,5744u16),(27963u16,1763u16), (27965u16,5743u16),(27966u16,3612u16),(27969u16,4243u16),(27972u16,2809u16), (27973u16,2998u16),(27993u16,5755u16),(27994u16,5753u16),(27996u16,3804u16), (28003u16,5750u16),(28004u16,5752u16),(28006u16,1529u16),(28009u16,2287u16), (28010u16,4341u16),(28012u16,1720u16),(28014u16,3825u16),(28015u16,8431u16), (28020u16,4200u16),(28023u16,1695u16),(28024u16,2846u16),(28025u16,5754u16), (28037u16,5759u16),(28039u16,8430u16),(28040u16,2760u16),(28044u16,4151u16), (28046u16,5756u16),(28051u16,5751u16),(28053u16,5757u16),(28054u16,8432u16), (28057u16,4291u16),(28059u16,3466u16),(28060u16,3511u16),(28076u16,8433u16), (28079u16,1713u16),(28082u16,1556u16),(28085u16,5763u16),(28088u16,5766u16), (28092u16,4264u16),(28096u16,4203u16),(28101u16,5773u16),(28102u16,5767u16), (28103u16,5764u16),(28107u16,4281u16),(28108u16,5770u16),(28111u16,8434u16), (28113u16,2673u16),(28114u16,5772u16),(28117u16,5777u16),(28120u16,3464u16), (28121u16,5775u16),(28126u16,5769u16),(28129u16,3219u16),(28132u16,5776u16), (28134u16,5765u16),(28136u16,5771u16),(28138u16,5778u16),(28139u16,1501u16), (28140u16,5768u16),(28142u16,5779u16),(28145u16,2847u16),(28146u16,8436u16), (28147u16,2694u16),(28149u16,3858u16),(28151u16,2363u16),(28152u16,8435u16), (28153u16,5760u16),(28154u16,5774u16),(28155u16,3409u16),(28156u16,8437u16), (28165u16,2935u16),(28167u16,1764u16),(28168u16,2398u16),(28169u16,2761u16), (28170u16,5762u16),(28171u16,2665u16),(28179u16,2111u16),(28181u16,5761u16), (28185u16,5783u16),(28186u16,2708u16),(28187u16,2187u16),(28189u16,5798u16), (28191u16,5792u16),(28192u16,1963u16),(28193u16,3430u16),(28195u16,5787u16), (28196u16,5796u16),(28197u16,1424u16),(28198u16,1521u16),(28199u16,8440u16), (28201u16,1622u16),(28203u16,5789u16),(28204u16,3113u16),(28205u16,5780u16), (28206u16,5782u16),(28207u16,2288u16),(28216u16,5799u16),(28217u16,8438u16), (28218u16,5794u16),(28220u16,8441u16),(28222u16,5786u16),(28227u16,5793u16), (28234u16,4052u16),(28237u16,5791u16),(28238u16,5795u16),(28246u16,2209u16), (28248u16,2762u16),(28251u16,3220u16),(28252u16,8439u16),(28255u16,5785u16), (28263u16,4150u16),(28267u16,5788u16),(28270u16,5781u16),(28271u16,3465u16), (28274u16,5784u16),(28278u16,5790u16),(28286u16,4372u16),(28287u16,2567u16), (28288u16,4041u16),(28290u16,5800u16),(28300u16,3679u16),(28303u16,5812u16), (28304u16,2188u16),(28310u16,2695u16),(28312u16,5802u16),(28316u16,4244u16), (28317u16,2289u16),(28319u16,5815u16),(28322u16,1487u16),(28325u16,5813u16), (28330u16,5801u16),(28335u16,5807u16),(28338u16,5809u16),(28342u16,4182u16), (28343u16,5804u16),(28346u16,3397u16),(28349u16,5806u16),(28351u16,8442u16), (28354u16,5814u16),(28356u16,5808u16),(28357u16,4080u16),(28361u16,5803u16), (28363u16,2539u16),(28364u16,5827u16),(28369u16,1765u16),(28371u16,5805u16), (28372u16,5810u16),(28373u16,5811u16),(28381u16,3177u16),(28382u16,3159u16), (28396u16,5819u16),(28399u16,5825u16),(28402u16,5823u16),(28404u16,3392u16), (28407u16,5830u16),(28408u16,5820u16),(28414u16,5821u16),(28415u16,5797u16), (28417u16,1968u16),(28418u16,3785u16),(28422u16,2568u16),(28425u16,2342u16), (28431u16,4342u16),(28433u16,5817u16),(28435u16,5829u16),(28436u16,1576u16), (28437u16,3077u16),(28448u16,3660u16),(28450u16,1818u16),(28451u16,4319u16), (28459u16,4042u16),(28460u16,3339u16),(28465u16,5824u16),(28466u16,5826u16), (28472u16,3025u16),(28478u16,5828u16),(28479u16,5822u16),(28481u16,5816u16), (28485u16,1820u16),(28500u16,2140u16),(28504u16,5842u16),(28507u16,5837u16), (28508u16,3001u16),(28511u16,1758u16),(28516u16,2696u16),(28518u16,5846u16), (28525u16,5839u16),(28526u16,3301u16),(28527u16,5836u16),(28528u16,3346u16), (28532u16,5871u16),(28536u16,5833u16),(28538u16,5832u16),(28540u16,5841u16), (28544u16,5835u16),(28545u16,5834u16),(28546u16,5840u16),(28548u16,2914u16), (28550u16,5831u16),(28552u16,8443u16),(28558u16,5843u16),(28561u16,5844u16), (28567u16,1819u16),(28577u16,5849u16),(28579u16,5848u16),(28580u16,5850u16), (28586u16,5853u16),(28593u16,3418u16),(28595u16,5847u16),(28597u16,8444u16), (28601u16,5851u16),(28608u16,2134u16),(28609u16,3190u16),(28610u16,5845u16), (28611u16,3598u16),(28614u16,5852u16),(28628u16,5857u16),(28629u16,5855u16), (28632u16,5858u16),(28635u16,5861u16),(28639u16,5854u16),(28640u16,2329u16), (28641u16,3579u16),(28644u16,5758u16),(28651u16,4219u16),(28652u16,5856u16), (28654u16,5860u16),(28655u16,3186u16),(28657u16,5859u16),(28659u16,5838u16), (28661u16,8445u16),(28662u16,7404u16),(28666u16,5864u16),(28670u16,5868u16), (28673u16,5866u16),(28677u16,8446u16),(28679u16,8447u16),(28681u16,5862u16), (28683u16,5863u16),(28687u16,5867u16),(28689u16,5865u16),(28693u16,3805u16), (28696u16,5873u16),(28698u16,5870u16),(28699u16,5869u16),(28701u16,5872u16), (28702u16,3529u16),(28703u16,5874u16),(28710u16,3280u16),(28711u16,3178u16), (28712u16,8448u16),(28716u16,2918u16),(28720u16,5875u16),(28722u16,5877u16), (28734u16,5876u16),(28748u16,5818u16),(28753u16,5878u16),(28760u16,3548u16), (28771u16,5879u16),(28779u16,1645u16),(28783u16,3467u16),(28784u16,1696u16), (28792u16,1947u16),(28796u16,2599u16),(28797u16,2399u16),(28805u16,8449u16), (28809u16,4330u16),(28810u16,2889u16),(28814u16,1577u16),(28818u16,5881u16), (28825u16,5880u16),(28843u16,8450u16),(28844u16,5884u16),(28845u16,3221u16), (28846u16,5887u16),(28847u16,5882u16),(28851u16,5886u16),(28856u16,5885u16), (28857u16,3415u16),(28858u16,1466u16),(28859u16,8278u16),(28872u16,4314u16), (28875u16,5889u16),(28879u16,1511u16),(28889u16,5891u16),(28893u16,5890u16), (28895u16,5888u16),(28913u16,5883u16),(28921u16,3950u16),(28925u16,5893u16), (28932u16,8452u16),(28937u16,5892u16),(28943u16,8451u16),(28948u16,1578u16), (28953u16,5895u16),(28954u16,3871u16),(28956u16,5894u16),(28961u16,4062u16), (28966u16,2764u16),(28982u16,3026u16),(28988u16,2763u16),(28998u16,8454u16), (28999u16,8455u16),(29001u16,4320u16),(29004u16,5901u16),(29006u16,3002u16), (29013u16,5897u16),(29014u16,5902u16),(29017u16,1579u16),(29020u16,8453u16), (29026u16,5900u16),(29028u16,3636u16),(29029u16,5896u16),(29030u16,5899u16), (29031u16,2765u16),(29033u16,3714u16),(29036u16,5903u16),(29038u16,2586u16), (29053u16,3003u16),(29060u16,5906u16),(29064u16,5898u16),(29066u16,2074u16), (29071u16,5904u16),(29076u16,4183u16),(29077u16,5907u16),(29081u16,7807u16), (29087u16,2678u16),(29096u16,5908u16),(29100u16,5909u16),(29105u16,3585u16), (29113u16,5911u16),(29118u16,5912u16),(29121u16,8457u16),(29123u16,3590u16), (29128u16,3468u16),(29129u16,5914u16),(29134u16,5916u16),(29136u16,4282u16), (29138u16,5913u16),(29140u16,5915u16),(29141u16,1580u16),(29143u16,5910u16), (29151u16,4758u16),(29152u16,5917u16),(29157u16,3078u16),(29158u16,2467u16), (29159u16,5919u16),(29164u16,5918u16),(29165u16,2823u16),(29166u16,4662u16), (29173u16,5920u16),(29177u16,5922u16),(29179u16,5905u16),(29180u16,5921u16), (29182u16,8458u16),(29183u16,5923u16),(29190u16,3661u16),(29197u16,5924u16), (29200u16,5925u16),(29211u16,5926u16),(29224u16,5927u16),(29226u16,3351u16), (29228u16,5929u16),(29229u16,5928u16),(29232u16,5930u16),(29234u16,5931u16), (29237u16,2600u16),(29238u16,3826u16),(29242u16,4117u16),(29243u16,5932u16), (29244u16,5933u16),(29245u16,3061u16),(29246u16,2541u16),(29247u16,5934u16), (29248u16,5935u16),(29254u16,5936u16),(29255u16,3903u16),(29256u16,3704u16), (29259u16,5937u16),(29260u16,3626u16),(29266u16,3302u16),(29272u16,5938u16), (29273u16,1668u16),(29275u16,1956u16),(29277u16,4079u16),(29279u16,4063u16), (29281u16,1617u16),(29282u16,4343u16),(29287u16,3997u16),(29289u16,3863u16), (29298u16,2936u16),(29300u16,5939u16),(29305u16,3512u16),(29309u16,2164u16), (29310u16,5940u16),(29312u16,2401u16),(29313u16,5942u16),(29314u16,5941u16), (29319u16,5943u16),(29330u16,5944u16),(29334u16,5945u16),(29344u16,1909u16), (29346u16,5946u16),(29351u16,5947u16),(29356u16,2165u16),(29359u16,3705u16), (29361u16,8459u16),(29362u16,5949u16),(29366u16,2810u16),(29369u16,5948u16), (29374u16,8460u16),(29378u16,1997u16),(29379u16,5950u16),(29380u16,5952u16), (29382u16,5951u16),(29390u16,5953u16),(29392u16,2210u16),(29394u16,5954u16), (29399u16,2046u16),(29401u16,3039u16),(29403u16,2348u16),(29408u16,5956u16), (29409u16,5957u16),(29410u16,5955u16),(29417u16,2614u16),(29420u16,3517u16), (29421u16,1998u16),(29431u16,5959u16),(29432u16,3207u16),(29433u16,5958u16), (29436u16,4344u16),(29437u16,3637u16),(29450u16,5962u16),(29462u16,5964u16), (29463u16,5961u16),(29467u16,4093u16),(29468u16,5963u16),(29469u16,5965u16), (29471u16,4265u16),(29476u16,8461u16),(29477u16,5969u16),(29481u16,5968u16), (29482u16,3281u16),(29483u16,3584u16),(29486u16,2166u16),(29487u16,5967u16), (29492u16,5966u16),(29494u16,4152u16),(29495u16,4153u16),(29502u16,5970u16), (29503u16,1581u16),(29508u16,2341u16),(29509u16,2509u16),(29518u16,5971u16), (29519u16,5972u16),(29527u16,5974u16),(29539u16,2666u16),(29544u16,5976u16), (29546u16,5975u16),(29552u16,5977u16),(29554u16,1736u16),(29557u16,5979u16), (29559u16,8463u16),(29560u16,5978u16),(29562u16,5981u16),(29563u16,5980u16), (29572u16,2189u16),(29575u16,4237u16),(29577u16,2017u16),(29579u16,1603u16), (29590u16,2047u16),(29609u16,1850u16),(29618u16,4301u16),(29619u16,5983u16), (29627u16,5985u16),(29629u16,8464u16),(29632u16,5986u16),(29634u16,1646u16), (29640u16,5982u16),(29641u16,8465u16),(29642u16,2468u16),(29645u16,3322u16), (29646u16,5984u16),(29650u16,8468u16),(29654u16,8466u16),(29662u16,5989u16), (29664u16,2615u16),(29667u16,8467u16),(29669u16,5987u16),(29674u16,2097u16), (29677u16,3706u16),(29678u16,5988u16),(29681u16,6015u16),(29685u16,8470u16), (29688u16,5994u16),(29694u16,2190u16),(29699u16,1948u16),(29701u16,5991u16), (29702u16,4228u16),(29703u16,8469u16),(29705u16,4245u16),(29730u16,3187u16), (29733u16,5993u16),(29734u16,8471u16),(29737u16,8473u16),(29738u16,8472u16), (29742u16,8474u16),(29746u16,5995u16),(29747u16,4283u16),(29748u16,2028u16), (29749u16,3757u16),(29750u16,3613u16),(29754u16,5996u16),(29759u16,5998u16), (29761u16,6001u16),(29781u16,5997u16),(29785u16,6000u16),(29786u16,2235u16), (29787u16,1548u16),(29788u16,6002u16),(29790u16,2899u16),(29791u16,5999u16), (29792u16,4289u16),(29794u16,8475u16),(29795u16,6005u16),(29796u16,7805u16), (29801u16,6003u16),(29802u16,6006u16),(29807u16,5992u16),(29808u16,6004u16), (29811u16,2377u16),(29814u16,6007u16),(29822u16,6008u16),(29827u16,4229u16), (29833u16,8476u16),(29835u16,6009u16),(29854u16,6010u16),(29855u16,8477u16), (29858u16,5990u16),(29863u16,6011u16),(29872u16,1821u16),(29885u16,2542u16), (29898u16,6012u16),(29903u16,6013u16),(29908u16,6014u16),(29916u16,1530u16), (29920u16,6016u16),(29922u16,3786u16),(29923u16,6017u16),(29926u16,1789u16), (29927u16,6018u16),(29929u16,6019u16),(29934u16,6020u16),(29936u16,6022u16), (29937u16,6023u16),(29938u16,6021u16),(29942u16,3810u16),(29943u16,6025u16), (29944u16,6024u16),(29953u16,8478u16),(29955u16,6027u16),(29956u16,6026u16), (29957u16,6028u16),(29964u16,6029u16),(29965u16,6031u16),(29966u16,6030u16), (29969u16,2344u16),(29971u16,6033u16),(29973u16,6032u16),(29976u16,1822u16), (29978u16,2870u16),(29980u16,3411u16),(29982u16,6034u16),(29983u16,2937u16), (29987u16,2469u16),(29989u16,1592u16),(29990u16,6035u16),(29992u16,4184u16), (29995u16,3920u16),(29996u16,6036u16),(29999u16,8347u16),(30000u16,3419u16), (30001u16,4154u16),(30002u16,2290u16),(30003u16,2848u16),(30007u16,3238u16), (30008u16,4625u16),(30010u16,3303u16),(30011u16,1669u16),(30012u16,6037u16), (30020u16,6038u16),(30022u16,6043u16),(30025u16,6041u16),(30026u16,6040u16), (30027u16,5391u16),(30028u16,1697u16),(30029u16,6039u16),(30031u16,1467u16), (30033u16,3675u16),(30036u16,3707u16),(30041u16,4246u16),(30042u16,6044u16), (30043u16,6042u16),(30044u16,3255u16),(30045u16,2919u16),(30048u16,3676u16), (30050u16,3772u16),(30052u16,6046u16),(30053u16,4241u16),(30054u16,2112u16), (30055u16,6047u16),(30057u16,6045u16),(30058u16,3719u16),(30059u16,6048u16), (30061u16,6049u16),(30063u16,8479u16),(30064u16,1468u16),(30067u16,2811u16), (30068u16,6054u16),(30070u16,6051u16),(30071u16,3554u16),(30072u16,6050u16), (30079u16,1885u16),(30082u16,6057u16),(30086u16,6052u16),(30087u16,6053u16), (30089u16,6056u16),(30090u16,6055u16),(30091u16,3764u16),(30094u16,3041u16), (30095u16,3040u16),(30097u16,1910u16),(30100u16,6058u16),(30106u16,6059u16), (30109u16,6060u16),(30115u16,6062u16),(30117u16,6061u16),(30123u16,1557u16), (30129u16,6070u16),(30130u16,3737u16),(30131u16,6064u16),(30133u16,6066u16), (30136u16,6068u16),(30137u16,2849u16),(30140u16,6069u16),(30141u16,6067u16), (30142u16,2569u16),(30146u16,6063u16),(30147u16,6065u16),(30149u16,3793u16), (30151u16,2766u16),(30154u16,6072u16),(30157u16,6071u16),(30162u16,6073u16), (30164u16,2543u16),(30165u16,2364u16),(30168u16,3470u16),(30169u16,6074u16), (30171u16,3332u16),(30174u16,6076u16),(30178u16,4230u16),(30179u16,6075u16), (30185u16,3080u16),(30192u16,6081u16),(30194u16,6083u16),(30195u16,6084u16), (30196u16,3247u16),(30202u16,6082u16),(30204u16,6079u16),(30206u16,6077u16), (30207u16,6078u16),(30209u16,6080u16),(30217u16,6087u16),(30219u16,6085u16), (30221u16,6086u16),(30239u16,6088u16),(30240u16,6090u16),(30241u16,6091u16), (30242u16,6092u16),(30244u16,6093u16),(30247u16,6089u16),(30256u16,6095u16), (30260u16,6094u16),(30267u16,6096u16),(30274u16,4266u16),(30278u16,6099u16), (30279u16,6097u16),(30280u16,6098u16),(30284u16,1851u16),(30290u16,4135u16), (30294u16,3895u16),(30296u16,6101u16),(30300u16,6100u16),(30305u16,6102u16), (30306u16,6103u16),(30311u16,6107u16),(30312u16,6104u16),(30313u16,6105u16), (30314u16,6106u16),(30316u16,6108u16),(30320u16,6109u16),(30322u16,6110u16), (30326u16,6111u16),(30328u16,6112u16),(30330u16,3680u16),(30331u16,3431u16), (30332u16,6113u16),(30333u16,3653u16),(30334u16,3779u16),(30336u16,6114u16), (30338u16,8480u16),(30339u16,6115u16),(30340u16,3393u16),(30342u16,1698u16), (30343u16,2291u16),(30344u16,6116u16),(30347u16,6117u16),(30350u16,6118u16), (30352u16,2452u16),(30355u16,6120u16),(30358u16,6119u16),(30361u16,6121u16), (30362u16,6122u16),(30363u16,8483u16),(30364u16,8481u16),(30366u16,8482u16), (30374u16,8484u16),(30382u16,3738u16),(30384u16,6123u16),(30388u16,6124u16), (30391u16,7780u16),(30392u16,6125u16),(30393u16,6126u16),(30394u16,6127u16), (30399u16,2457u16),(30402u16,6128u16),(30403u16,3625u16),(30406u16,4010u16), (30408u16,1549u16),(30410u16,1558u16),(30413u16,6129u16),(30418u16,6131u16), (30422u16,6130u16),(30423u16,3463u16),(30427u16,2938u16),(30428u16,5664u16), (30430u16,6132u16),(30431u16,4074u16),(30433u16,6133u16),(30435u16,1823u16), (30436u16,3720u16),(30437u16,6134u16),(30439u16,6135u16),(30442u16,6136u16), (30446u16,4101u16),(30450u16,4094u16),(30452u16,3319u16),(30456u16,3081u16), (30459u16,6138u16),(30462u16,2697u16),(30465u16,2767u16),(30468u16,6141u16), (30471u16,6140u16),(30472u16,6139u16),(30473u16,3758u16),(30475u16,1824u16), (30476u16,2170u16),(30491u16,6147u16),(30494u16,6144u16),(30495u16,2850u16), (30496u16,4059u16),(30500u16,6143u16),(30501u16,6145u16),(30502u16,6146u16), (30505u16,6142u16),(30519u16,6148u16),(30520u16,6149u16),(30522u16,3304u16), (30524u16,1852u16),(30528u16,3264u16),(30534u16,8486u16),(30535u16,6150u16), (30554u16,6151u16),(30555u16,6154u16),(30561u16,2890u16),(30563u16,3513u16), (30565u16,6155u16),(30566u16,3998u16),(30568u16,6152u16),(30571u16,6153u16), (30585u16,6158u16),(30590u16,6157u16),(30591u16,6156u16),(30603u16,6160u16), (30606u16,6159u16),(30609u16,6161u16),(30622u16,6163u16),(30624u16,6162u16), (30629u16,3898u16),(30636u16,2685u16),(30637u16,4267u16),(30640u16,6164u16), (30643u16,3500u16),(30646u16,6165u16),(30649u16,6166u16),(30651u16,6170u16), (30652u16,6168u16),(30653u16,6169u16),(30655u16,6167u16),(30663u16,6171u16), (30669u16,6172u16),(30679u16,6173u16),(30682u16,6174u16),(30683u16,4064u16), (30684u16,6175u16),(30690u16,4121u16),(30691u16,6176u16),(30693u16,3241u16), (30695u16,3645u16),(30697u16,2048u16),(30701u16,3222u16),(30702u16,6177u16), (30703u16,1999u16),(30707u16,2961u16),(30716u16,6178u16),(30722u16,2378u16), (30732u16,6179u16),(30738u16,6180u16),(30740u16,2167u16),(30741u16,2402u16), (30752u16,6182u16),(30753u16,8488u16),(30757u16,3437u16),(30758u16,2403u16), (30759u16,1925u16),(30770u16,3951u16),(30772u16,3614u16),(30778u16,3438u16), (30783u16,2315u16),(30789u16,6184u16),(30798u16,8489u16),(30813u16,2768u16), (30820u16,8490u16),(30827u16,4247u16),(30828u16,2292u16),(30831u16,2168u16), (30834u16,3668u16),(30836u16,6186u16),(30842u16,8491u16),(30844u16,6188u16), (30849u16,2236u16),(30854u16,6187u16),(30855u16,3375u16),(30860u16,6190u16), (30861u16,1714u16),(30862u16,6185u16),(30865u16,3739u16),(30867u16,1519u16), (30869u16,2425u16),(30871u16,4373u16),(30874u16,6189u16),(30883u16,6191u16), (30887u16,3896u16),(30889u16,2970u16),(30890u16,6193u16),(30895u16,6194u16), (30901u16,6192u16),(30906u16,1737u16),(30908u16,6200u16),(30910u16,6199u16), (30913u16,2544u16),(30917u16,6201u16),(30918u16,6196u16),(30922u16,6202u16), (30923u16,6197u16),(30928u16,3721u16),(30929u16,6195u16),(30932u16,6198u16), (30938u16,6205u16),(30951u16,6204u16),(30952u16,4012u16),(30956u16,6203u16), (30959u16,1484u16),(30964u16,6207u16),(30973u16,6206u16),(30977u16,2769u16), (30983u16,6208u16),(30990u16,3042u16),(30993u16,6210u16),(30994u16,6209u16), (31001u16,6211u16),(31014u16,6181u16),(31018u16,6183u16),(31019u16,6213u16), (31020u16,6212u16),(31024u16,8492u16),(31034u16,2545u16),(31036u16,4302u16), (31038u16,2587u16),(31040u16,6214u16),(31041u16,2090u16),(31047u16,1911u16), (31048u16,1886u16),(31049u16,2510u16),(31056u16,4155u16),(31059u16,6220u16), (31061u16,6219u16),(31062u16,3043u16),(31063u16,6216u16),(31066u16,6218u16), (31069u16,2674u16),(31070u16,2851u16),(31071u16,6217u16),(31072u16,6215u16), (31074u16,3581u16),(31077u16,2770u16),(31080u16,3787u16),(31085u16,2404u16), (31095u16,3471u16),(31098u16,6221u16),(31103u16,6222u16),(31104u16,6244u16), (31105u16,2029u16),(31108u16,4352u16),(31109u16,3028u16),(31114u16,6223u16), (31117u16,1647u16),(31118u16,3376u16),(31119u16,3854u16),(31124u16,8496u16), (31131u16,8498u16),(31133u16,6224u16),(31142u16,1969u16),(31143u16,6225u16), (31146u16,6227u16),(31150u16,6228u16),(31152u16,3580u16),(31155u16,6229u16), (31161u16,6230u16),(31162u16,6231u16),(31165u16,2030u16),(31166u16,1648u16), (31167u16,3514u16),(31168u16,2639u16),(31169u16,2511u16),(31177u16,6232u16), (31179u16,2640u16),(31185u16,1639u16),(31186u16,3794u16),(31189u16,6233u16), (31192u16,3740u16),(31199u16,3044u16),(31201u16,6236u16),(31203u16,6237u16), (31204u16,3644u16),(31206u16,2852u16),(31207u16,6234u16),(31209u16,3260u16), (31212u16,6235u16),(31216u16,2771u16),(31227u16,1469u16),(31232u16,1888u16), (31240u16,6238u16),(31243u16,3377u16),(31245u16,6239u16),(31246u16,2952u16), (31252u16,4054u16),(31255u16,3762u16),(31256u16,6240u16),(31257u16,6241u16), (31258u16,3248u16),(31260u16,4268u16),(31263u16,6243u16),(31264u16,6242u16), (31278u16,2616u16),(31281u16,6245u16),(31282u16,1489u16),(31287u16,6248u16), (31291u16,6246u16),(31292u16,1649u16),(31293u16,2113u16),(31294u16,6247u16), (31295u16,2293u16),(31296u16,2337u16),(31298u16,3923u16),(31299u16,6249u16), (31302u16,3999u16),(31305u16,6251u16),(31309u16,2962u16),(31310u16,1550u16), (31311u16,1623u16),(31312u16,1421u16),(31319u16,6250u16),(31329u16,6252u16), (31330u16,6253u16),(31331u16,2812u16),(31337u16,6254u16),(31339u16,1738u16), (31344u16,6256u16),(31348u16,2141u16),(31350u16,1949u16),(31353u16,6257u16), (31354u16,2058u16),(31357u16,6258u16),(31359u16,3005u16),(31361u16,3522u16), (31363u16,2977u16),(31364u16,2434u16),(31368u16,6259u16),(31378u16,3261u16), (31379u16,3082u16),(31381u16,6261u16),(31382u16,6263u16),(31383u16,6260u16), (31384u16,6262u16),(31391u16,2069u16),(31401u16,6264u16),(31402u16,2073u16), (31406u16,1950u16),(31407u16,4185u16),(31408u16,6266u16),(31414u16,6267u16), (31418u16,1517u16),(31423u16,6270u16),(31427u16,1777u16),(31428u16,6269u16), (31429u16,6268u16),(31431u16,6272u16),(31432u16,6265u16),(31434u16,6273u16), (31435u16,4238u16),(31437u16,6274u16),(31439u16,6275u16),(31441u16,8499u16), (31442u16,4877u16),(31443u16,6277u16),(31445u16,6276u16),(31449u16,6278u16), (31450u16,6279u16),(31452u16,4250u16),(31453u16,6280u16),(31455u16,7504u16), (31456u16,2772u16),(31457u16,6281u16),(31458u16,6282u16),(31459u16,2686u16), (31461u16,3501u16),(31462u16,6283u16),(31463u16,8500u16),(31466u16,3203u16), (31467u16,8502u16),(31469u16,6284u16),(31471u16,3223u16),(31472u16,6285u16), (31478u16,1978u16),(31480u16,4542u16),(31481u16,3256u16),(31482u16,2556u16), (31487u16,1825u16),(31490u16,6286u16),(31492u16,6299u16),(31494u16,6289u16), (31496u16,1951u16),(31498u16,6288u16),(31499u16,6301u16),(31503u16,6287u16), (31505u16,2773u16),(31512u16,6291u16),(31513u16,6292u16),(31515u16,3394u16), (31518u16,6293u16),(31520u16,1753u16),(31525u16,2877u16),(31526u16,3827u16), (31528u16,6295u16),(31532u16,3173u16),(31539u16,6290u16),(31541u16,6294u16), (31542u16,6296u16),(31545u16,2440u16),(31557u16,6303u16),(31558u16,3773u16), (31560u16,3671u16),(31561u16,3472u16),(31563u16,2031u16),(31564u16,6302u16), (31565u16,6300u16),(31567u16,3686u16),(31568u16,6297u16),(31569u16,3257u16), (31570u16,3474u16),(31572u16,3473u16),(31574u16,2435u16),(31581u16,6321u16), (31589u16,6305u16),(31591u16,6307u16),(31596u16,6310u16),(31598u16,6311u16), (31600u16,6308u16),(31601u16,6309u16),(31604u16,6306u16),(31605u16,6304u16), (31610u16,6298u16),(31622u16,3900u16),(31623u16,1650u16),(31627u16,6318u16), (31629u16,6315u16),(31631u16,6320u16),(31634u16,6319u16),(31636u16,3654u16), (31637u16,4048u16),(31639u16,2470u16),(31640u16,6313u16),(31641u16,6322u16), (31642u16,6317u16),(31644u16,6316u16),(31645u16,6312u16),(31646u16,8503u16), (31647u16,6314u16),(31649u16,1826u16),(31658u16,3224u16),(31661u16,3006u16), (31665u16,3667u16),(31668u16,6327u16),(31672u16,3669u16),(31680u16,2978u16), (31681u16,6324u16),(31684u16,3712u16),(31686u16,6328u16),(31687u16,3904u16), (31689u16,3254u16),(31691u16,6323u16),(31692u16,6325u16),(31695u16,6326u16), (31709u16,6329u16),(31712u16,2573u16),(31716u16,3515u16),(31717u16,6334u16), (31718u16,6333u16),(31721u16,6330u16),(31725u16,4345u16),(31731u16,6339u16), (31734u16,6343u16),(31735u16,6340u16),(31744u16,6336u16),(31751u16,6337u16), (31757u16,6342u16),(31761u16,6331u16),(31762u16,4658u16),(31763u16,6338u16), (31764u16,6332u16),(31767u16,6341u16),(31775u16,6347u16),(31777u16,1827u16), (31779u16,6344u16),(31783u16,6345u16),(31786u16,6346u16),(31787u16,6349u16), (31799u16,6348u16),(31800u16,3751u16),(31805u16,6350u16),(31806u16,4321u16), (31807u16,3930u16),(31808u16,6355u16),(31811u16,6352u16),(31820u16,6351u16), (31821u16,2963u16),(31823u16,6354u16),(31824u16,6356u16),(31828u16,6353u16), (31830u16,6360u16),(31832u16,6357u16),(31839u16,6358u16),(31840u16,6335u16), (31844u16,6359u16),(31845u16,6361u16),(31852u16,6362u16),(31859u16,3891u16), (31861u16,6363u16),(31870u16,4107u16),(31873u16,2019u16),(31874u16,2076u16), (31875u16,6364u16),(31881u16,3873u16),(31883u16,2891u16),(31885u16,4057u16), (31888u16,6365u16),(31890u16,4248u16),(31893u16,3655u16),(31895u16,3045u16), (31896u16,3591u16),(31899u16,2676u16),(31903u16,1441u16),(31905u16,6370u16), (31906u16,6368u16),(31908u16,6366u16),(31909u16,1786u16),(31911u16,2774u16), (31912u16,6371u16),(31915u16,6369u16),(31917u16,6367u16),(31918u16,6375u16), (31921u16,6374u16),(31922u16,6373u16),(31923u16,6372u16),(31929u16,6376u16), (31933u16,6377u16),(31934u16,2939u16),(31936u16,6378u16),(31938u16,6380u16), (31941u16,6379u16),(31946u16,2211u16),(31950u16,3031u16),(31954u16,6382u16), (31958u16,3475u16),(31960u16,6381u16),(31964u16,6383u16),(31966u16,3874u16), (31967u16,3083u16),(31968u16,2294u16),(31970u16,6384u16),(31975u16,4269u16), (31983u16,6386u16),(31986u16,6387u16),(31988u16,6388u16),(31990u16,6389u16), (31992u16,2512u16),(31994u16,6390u16),(31995u16,2114u16),(31998u16,1953u16), (32000u16,1889u16),(32002u16,6392u16),(32004u16,4124u16),(32005u16,2295u16), (32006u16,6391u16),(32010u16,6395u16),(32011u16,4111u16),(32013u16,3599u16), (32016u16,3778u16),(32020u16,2698u16),(32021u16,6394u16),(32023u16,2588u16), (32024u16,2296u16),(32025u16,2513u16),(32026u16,1952u16),(32027u16,3875u16), (32028u16,6393u16),(32032u16,3046u16),(32033u16,3981u16),(32034u16,2436u16), (32043u16,2514u16),(32044u16,3350u16),(32046u16,6398u16),(32047u16,4292u16), (32048u16,2406u16),(32050u16,6399u16),(32051u16,2853u16),(32053u16,6401u16), (32057u16,2775u16),(32058u16,2365u16),(32063u16,6400u16),(32066u16,2641u16), (32067u16,2191u16),(32068u16,3047u16),(32069u16,6396u16),(32070u16,6402u16), (32072u16,8505u16),(32075u16,6397u16),(32076u16,2115u16),(32078u16,6405u16), (32079u16,6409u16),(32080u16,2142u16),(32086u16,6404u16),(32091u16,6413u16), (32092u16,8506u16),(32094u16,2297u16),(32097u16,4212u16),(32098u16,1437u16), (32099u16,6410u16),(32102u16,1954u16),(32104u16,6407u16),(32110u16,6408u16), (32113u16,3476u16),(32114u16,6406u16),(32115u16,6403u16),(32117u16,1699u16), (32118u16,2981u16),(32121u16,2169u16),(32125u16,6415u16),(32137u16,6412u16), (32143u16,6414u16),(32147u16,6411u16),(32153u16,2116u16),(32154u16,3120u16), (32155u16,6416u16),(32156u16,3085u16),(32159u16,6429u16),(32160u16,8508u16), (32162u16,6425u16),(32163u16,6419u16),(32171u16,6423u16),(32172u16,2627u16), (32173u16,1470u16),(32174u16,6418u16),(32175u16,6426u16),(32176u16,6430u16), (32177u16,2298u16),(32178u16,4095u16),(32180u16,3343u16),(32181u16,6420u16), (32183u16,8507u16),(32184u16,6428u16),(32186u16,6417u16),(32187u16,3225u16), (32189u16,6422u16),(32190u16,1438u16),(32191u16,4083u16),(32199u16,6421u16), (32202u16,2032u16),(32203u16,3741u16),(32207u16,3084u16),(32209u16,4277u16), (32210u16,2710u16),(32213u16,6469u16),(32214u16,8509u16),(32216u16,6431u16), (32218u16,3007u16),(32220u16,6427u16),(32221u16,6432u16),(32222u16,6434u16), (32224u16,3378u16),(32225u16,6437u16),(32228u16,6433u16),(32232u16,3905u16), (32233u16,1828u16),(32236u16,4084u16),(32239u16,1471u16),(32242u16,6436u16), (32244u16,4322u16),(32251u16,6435u16),(32257u16,1582u16),(32260u16,3553u16), (32261u16,6438u16),(32265u16,6445u16),(32266u16,6439u16),(32267u16,6446u16), (32274u16,6442u16),(32283u16,3662u16),(32286u16,2579u16),(32287u16,6444u16), (32289u16,6441u16),(32290u16,6447u16),(32291u16,6440u16),(32294u16,2667u16), (32299u16,3952u16),(32302u16,2675u16),(32305u16,6443u16),(32306u16,6455u16), (32309u16,6451u16),(32311u16,6454u16),(32313u16,6452u16),(32314u16,6456u16), (32315u16,6450u16),(32317u16,6424u16),(32318u16,2964u16),(32321u16,3708u16), (32323u16,6453u16),(32326u16,6448u16),(32330u16,3008u16),(32331u16,2117u16), (32333u16,2642u16),(32338u16,8510u16),(32340u16,2824u16),(32341u16,3029u16), (32342u16,6459u16),(32345u16,6461u16),(32346u16,6462u16),(32349u16,6458u16), (32350u16,6460u16),(32358u16,6449u16),(32359u16,6457u16),(32361u16,6465u16), (32362u16,6464u16),(32365u16,4037u16),(32368u16,2078u16),(32377u16,6463u16), (32379u16,6467u16),(32380u16,6466u16),(32381u16,6470u16),(32383u16,6472u16), (32386u16,2471u16),(32387u16,6468u16),(32392u16,6473u16),(32393u16,6474u16), (32394u16,8272u16),(32396u16,6475u16),(32398u16,6481u16),(32399u16,3410u16), (32400u16,6477u16),(32402u16,6476u16),(32403u16,6478u16),(32404u16,6479u16), (32406u16,6480u16),(32411u16,6482u16),(32412u16,6483u16),(32566u16,1829u16), (32568u16,6484u16),(32570u16,6485u16),(32581u16,6486u16),(32583u16,8511u16), (32588u16,6487u16),(32589u16,6488u16),(32590u16,6489u16),(32592u16,6490u16), (32593u16,6491u16),(32596u16,6493u16),(32597u16,6492u16),(32600u16,6494u16), (32607u16,6495u16),(32608u16,6496u16),(32615u16,6499u16),(32616u16,6497u16), (32617u16,6498u16),(32618u16,2414u16),(32619u16,2118u16),(32622u16,3249u16), (32624u16,3684u16),(32626u16,2711u16),(32629u16,3616u16),(32631u16,3742u16), (32632u16,6500u16),(32633u16,5246u16),(32642u16,6501u16),(32643u16,6503u16), (32645u16,4204u16),(32646u16,6502u16),(32647u16,6505u16),(32648u16,6504u16), (32650u16,4186u16),(32652u16,6506u16),(32654u16,3759u16),(32660u16,6507u16), (32666u16,6510u16),(32669u16,6509u16),(32670u16,6508u16),(32673u16,8512u16), (32675u16,6511u16),(32676u16,2085u16),(32680u16,3009u16),(32681u16,1912u16), (32686u16,6515u16),(32687u16,6512u16),(32690u16,6513u16),(32694u16,6516u16), (32696u16,6517u16),(32697u16,6514u16),(32701u16,1512u16),(32705u16,1604u16), (32709u16,6519u16),(32710u16,6520u16),(32714u16,6521u16),(32716u16,4201u16), (32722u16,2643u16),(32724u16,6523u16),(32725u16,6522u16),(32736u16,2892u16), (32737u16,6524u16),(32742u16,6525u16),(32745u16,6526u16),(32747u16,1854u16), (32752u16,1830u16),(32755u16,6527u16),(32761u16,6528u16),(32763u16,4008u16), (32764u16,4202u16),(32768u16,4187u16),(32769u16,4346u16),(32771u16,2300u16), (32772u16,6531u16),(32773u16,2589u16),(32774u16,6530u16),(32779u16,6532u16), (32780u16,2546u16),(32784u16,3150u16),(32786u16,6533u16),(32789u16,2299u16), (32791u16,4096u16),(32792u16,6534u16),(32793u16,6535u16),(32796u16,6536u16), (32801u16,6537u16),(32808u16,6538u16),(32819u16,2547u16),(32822u16,4118u16), (32827u16,6540u16),(32829u16,3226u16),(32831u16,6539u16),(32838u16,6542u16), (32842u16,6541u16),(32850u16,6543u16),(32854u16,2940u16),(32856u16,6544u16), (32858u16,6545u16),(32862u16,3878u16),(32863u16,6546u16),(32865u16,3086u16), (32866u16,6547u16),(32872u16,6548u16),(32879u16,4323u16),(32880u16,6551u16), (32882u16,6550u16),(32883u16,6549u16),(32884u16,3305u16),(32886u16,6552u16), (32887u16,2825u16),(32889u16,6553u16),(32893u16,6554u16),(32894u16,4347u16), (32895u16,6555u16),(32900u16,6556u16),(32901u16,6558u16),(32902u16,6557u16), (32903u16,3670u16),(32905u16,3566u16),(32907u16,4353u16),(32908u16,3674u16), (32915u16,6560u16),(32918u16,2776u16),(32920u16,3769u16),(32922u16,6561u16), (32923u16,6559u16),(32925u16,1831u16),(32929u16,2213u16),(32930u16,2515u16), (32933u16,3743u16),(32937u16,2171u16),(32938u16,3982u16),(32940u16,6564u16), (32941u16,6562u16),(32943u16,2301u16),(32945u16,2302u16),(32946u16,1482u16), (32948u16,2421u16),(32954u16,3628u16),(32963u16,1472u16),(32964u16,6569u16), (32966u16,3227u16),(32972u16,3627u16),(32974u16,3160u16),(32982u16,6571u16), (32985u16,6567u16),(32986u16,6570u16),(32987u16,6565u16),(32989u16,6568u16), (32990u16,3953u16),(32993u16,2214u16),(32996u16,1502u16),(32997u16,6566u16), (33007u16,6573u16),(33009u16,6574u16),(33012u16,3502u16),(33016u16,2000u16), (33020u16,6585u16),(33021u16,3600u16),(33026u16,2516u16),(33029u16,2001u16), (33030u16,2953u16),(33031u16,4361u16),(33032u16,4055u16),(33033u16,6572u16), (33034u16,2965u16),(33050u16,1930u16),(33051u16,6575u16),(33059u16,6577u16), (33065u16,6576u16),(33071u16,6578u16),(33073u16,3201u16),(33075u16,3601u16), (33081u16,3306u16),(33086u16,6582u16),(33094u16,6581u16),(33099u16,6579u16), (33102u16,2872u16),(33104u16,3828u16),(33105u16,6584u16),(33107u16,6583u16), (33108u16,2303u16),(33109u16,4374u16),(33119u16,6600u16),(33125u16,6588u16), (33126u16,6589u16),(33131u16,2617u16),(33134u16,6587u16),(33136u16,2343u16), (33137u16,6586u16),(33140u16,6590u16),(33144u16,3307u16),(33145u16,3855u16), (33146u16,3010u16),(33151u16,3161u16),(33152u16,6594u16),(33154u16,6595u16), (33155u16,6591u16),(33160u16,6592u16),(33162u16,6593u16),(33167u16,2304u16), (33171u16,6601u16),(33173u16,6597u16),(33178u16,3829u16),(33180u16,4023u16), (33181u16,3767u16),(33184u16,6596u16),(33187u16,6599u16),(33188u16,6598u16), (33192u16,3983u16),(33193u16,6602u16),(33200u16,6603u16),(33203u16,3030u16), (33205u16,6604u16),(33208u16,6606u16),(33210u16,6610u16),(33213u16,6607u16), (33214u16,6605u16),(33215u16,3602u16),(33216u16,6608u16),(33218u16,6609u16), (33222u16,1615u16),(33224u16,6616u16),(33225u16,6611u16),(33229u16,6612u16), (33233u16,6613u16),(33235u16,3102u16),(33240u16,6615u16),(33241u16,6614u16), (33242u16,6617u16),(33247u16,6618u16),(33248u16,6619u16),(33251u16,2854u16), (33253u16,1670u16),(33255u16,6620u16),(33256u16,4284u16),(33258u16,2548u16), (33261u16,2644u16),(33267u16,2517u16),(33268u16,3250u16),(33274u16,6621u16), (33275u16,6622u16),(33276u16,1520u16),(33278u16,6623u16),(33281u16,6624u16), (33282u16,6625u16),(33285u16,6626u16),(33287u16,6627u16),(33288u16,2002u16), (33289u16,5367u16),(33290u16,6628u16),(33292u16,2982u16),(33293u16,6629u16), (33294u16,2580u16),(33296u16,6630u16),(33298u16,4433u16),(33302u16,6631u16), (33303u16,3915u16),(33304u16,1845u16),(33307u16,3011u16),(33308u16,2687u16), (33310u16,3840u16),(33311u16,2645u16),(33321u16,6632u16),(33322u16,2305u16), (33323u16,6633u16),(33324u16,3709u16),(33326u16,6647u16),(33331u16,6635u16), (33333u16,3142u16),(33334u16,3656u16),(33335u16,2192u16),(33336u16,6634u16), (33337u16,3012u16),(33344u16,6636u16),(33351u16,3379u16),(33368u16,6638u16), (33369u16,6637u16),(33370u16,6640u16),(33373u16,6639u16),(33375u16,6641u16), (33378u16,6643u16),(33380u16,6642u16),(33382u16,1832u16),(33384u16,6644u16), (33386u16,6645u16),(33387u16,6646u16),(33390u16,2366u16),(33391u16,4270u16), (33393u16,6648u16),(33394u16,2826u16),(33398u16,1583u16),(33399u16,6649u16), (33400u16,6650u16),(33406u16,6651u16),(33419u16,1491u16),(33421u16,6652u16), (33426u16,6653u16),(33433u16,3830u16),(33437u16,2576u16),(33439u16,6655u16), (33445u16,1700u16),(33446u16,1427u16),(33451u16,6654u16),(33452u16,6657u16), (33453u16,3617u16),(33455u16,2855u16),(33457u16,1651u16),(33459u16,3954u16), (33464u16,2128u16),(33465u16,2033u16),(33467u16,6656u16),(33469u16,1671u16), (33477u16,1788u16),(33489u16,1584u16),(33490u16,6661u16),(33491u16,4303u16), (33492u16,3162u16),(33495u16,3795u16),(33497u16,6673u16),(33499u16,1652u16), (33500u16,6671u16),(33502u16,6669u16),(33503u16,6660u16),(33505u16,6658u16), (33507u16,6659u16),(33509u16,2604u16),(33510u16,2049u16),(33511u16,3282u16), (33515u16,3526u16),(33521u16,1552u16),(33523u16,6663u16),(33524u16,6662u16), (33529u16,6668u16),(33530u16,6664u16),(33531u16,6667u16),(33537u16,8514u16), (33538u16,4089u16),(33539u16,6666u16),(33540u16,1653u16),(33541u16,1784u16), (33542u16,6670u16),(33545u16,6672u16),(33550u16,2119u16),(33558u16,6676u16), (33559u16,6685u16),(33560u16,6686u16),(33564u16,1420u16),(33571u16,6693u16), (33576u16,1490u16),(33579u16,6684u16),(33583u16,6683u16),(33585u16,6678u16), (33586u16,6677u16),(33588u16,6675u16),(33589u16,6674u16),(33590u16,3262u16), (33592u16,3192u16),(33593u16,6680u16),(33600u16,6679u16),(33605u16,6682u16), (33609u16,3087u16),(33610u16,2120u16),(33615u16,1536u16),(33616u16,6681u16), (33618u16,2306u16),(33624u16,3088u16),(33634u16,8515u16),(33651u16,6699u16), (33653u16,6700u16),(33655u16,1654u16),(33659u16,1611u16),(33660u16,6697u16), (33663u16,8516u16),(33669u16,6687u16),(33671u16,6695u16),(33673u16,6702u16), (33674u16,6696u16),(33678u16,6694u16),(33683u16,6665u16),(33686u16,6692u16), (33690u16,6688u16),(33694u16,1833u16),(33695u16,6690u16),(33696u16,6701u16), (33698u16,6691u16),(33704u16,6703u16),(33706u16,6689u16),(33707u16,3663u16), (33713u16,4208u16),(33717u16,6698u16),(33725u16,6720u16),(33729u16,6712u16), (33733u16,2910u16),(33735u16,8517u16),(33738u16,1917u16),(33740u16,2034u16), (33742u16,6707u16),(33747u16,1656u16),(33750u16,2777u16),(33752u16,6710u16), (33756u16,2407u16),(33759u16,3432u16),(33760u16,6715u16),(33769u16,3931u16), (33771u16,6706u16),(33775u16,1655u16),(33776u16,2215u16),(33777u16,3768u16), (33778u16,6716u16),(33780u16,6704u16),(33782u16,8518u16),(33783u16,6713u16), (33787u16,6723u16),(33789u16,6708u16),(33795u16,6709u16),(33796u16,3503u16), (33799u16,6714u16),(33803u16,6711u16),(33804u16,3955u16),(33805u16,6717u16), (33806u16,1473u16),(33811u16,6705u16),(33824u16,6719u16),(33826u16,6718u16), (33833u16,3646u16),(33834u16,6725u16),(33836u16,6736u16),(33841u16,1785u16), (33845u16,6739u16),(33848u16,6721u16),(33852u16,6726u16),(33853u16,4213u16), (33862u16,6735u16),(33864u16,8519u16),(33865u16,4188u16),(33870u16,4239u16), (33879u16,3283u16),(33883u16,1766u16),(33889u16,3841u16),(33890u16,6741u16), (33891u16,3478u16),(33894u16,1426u16),(33897u16,6734u16),(33899u16,6730u16), (33900u16,3089u16),(33901u16,6724u16),(33902u16,6732u16),(33903u16,6737u16), (33905u16,3583u16),(33909u16,1419u16),(33911u16,6729u16),(33913u16,6738u16), (33914u16,3847u16),(33922u16,6733u16),(33924u16,6728u16),(33931u16,2778u16), (33936u16,2646u16),(33940u16,2549u16),(33945u16,4097u16),(33948u16,3798u16), (33951u16,6744u16),(33953u16,6753u16),(33965u16,6731u16),(33970u16,1778u16), (33972u16,8520u16),(33976u16,2813u16),(33977u16,6742u16),(33979u16,6747u16), (33980u16,3090u16),(33983u16,6743u16),(33985u16,6750u16),(33988u16,3258u16), (33990u16,6751u16),(33993u16,4189u16),(33994u16,6740u16),(33995u16,1715u16), (33997u16,6746u16),(34000u16,6749u16),(34001u16,4053u16),(34006u16,6752u16), (34009u16,6745u16),(34010u16,6748u16),(34012u16,8276u16),(34028u16,3956u16), (34030u16,4324u16),(34036u16,6756u16),(34044u16,6763u16),(34047u16,6755u16), (34048u16,2572u16),(34054u16,6722u16),(34065u16,3899u16),(34067u16,4043u16), (34068u16,6762u16),(34069u16,6761u16),(34071u16,6757u16),(34072u16,6758u16), (34074u16,1525u16),(34079u16,6760u16),(34081u16,6754u16),(34086u16,3342u16), (34092u16,6759u16),(34093u16,1503u16),(34101u16,3103u16),(34109u16,3888u16), (34112u16,6764u16),(34113u16,6768u16),(34115u16,3722u16),(34120u16,6767u16), (34121u16,2779u16),(34122u16,2578u16),(34123u16,6770u16),(34126u16,2003u16), (34131u16,8521u16),(34133u16,6771u16),(34135u16,3848u16),(34136u16,6766u16), (34137u16,8522u16),(34138u16,6727u16),(34147u16,6765u16),(34152u16,4370u16), (34153u16,3479u16),(34154u16,3842u16),(34155u16,8523u16),(34157u16,6778u16), (34167u16,6784u16),(34174u16,6785u16),(34176u16,6772u16),(34180u16,3657u16), (34183u16,6782u16),(34184u16,6774u16),(34186u16,6776u16),(34192u16,6786u16), (34193u16,6775u16),(34196u16,6779u16),(34199u16,1585u16),(34201u16,3546u16), (34203u16,6780u16),(34204u16,6783u16),(34212u16,6773u16),(34214u16,3013u16), (34216u16,6777u16),(34217u16,2450u16),(34218u16,2856u16),(34219u16,2083u16), (34220u16,4125u16),(34222u16,4130u16),(34223u16,2713u16),(34224u16,8525u16), (34233u16,6790u16),(34234u16,6788u16),(34241u16,4369u16),(34249u16,6787u16), (34253u16,4220u16),(34255u16,6789u16),(34256u16,6791u16),(34261u16,6792u16), (34268u16,6795u16),(34269u16,6793u16),(34276u16,3480u16),(34277u16,6794u16), (34281u16,3710u16),(34282u16,6781u16),(34295u16,2714u16),(34297u16,6796u16), (34298u16,6801u16),(34299u16,3091u16),(34302u16,6800u16),(34306u16,6769u16), (34310u16,6802u16),(34311u16,3048u16),(34314u16,6797u16),(34315u16,6799u16), (34323u16,6798u16),(34326u16,5656u16),(34327u16,5641u16),(34330u16,6804u16), (34338u16,6803u16),(34349u16,4221u16),(34351u16,6137u16),(34352u16,6805u16), (34367u16,6806u16),(34381u16,6807u16),(34382u16,2216u16),(34384u16,1931u16), (34388u16,6809u16),(34389u16,4572u16),(34394u16,1964u16),(34396u16,4255u16), (34398u16,2056u16),(34399u16,6810u16),(34407u16,6811u16),(34411u16,3273u16), (34417u16,6812u16),(34425u16,3567u16),(34427u16,1435u16),(34442u16,1664u16), (34443u16,6817u16),(34444u16,6818u16),(34451u16,6813u16),(34453u16,2472u16), (34467u16,6814u16),(34468u16,3605u16),(34473u16,6815u16),(34474u16,6816u16), (34475u16,6826u16),(34479u16,6820u16),(34480u16,6823u16),(34486u16,6819u16), (34500u16,6821u16),(34502u16,6822u16),(34503u16,2593u16),(34505u16,6824u16), (34507u16,3228u16),(34509u16,2121u16),(34510u16,1725u16),(34516u16,6827u16), (34521u16,1722u16),(34523u16,6832u16),(34526u16,6828u16),(34527u16,6831u16), (34532u16,3691u16),(34537u16,6829u16),(34540u16,6830u16),(34541u16,3799u16), (34542u16,3723u16),(34543u16,6833u16),(34552u16,3194u16),(34553u16,6843u16), (34555u16,6839u16),(34558u16,1672u16),(34560u16,6837u16),(34562u16,3957u16), (34563u16,6838u16),(34566u16,6835u16),(34568u16,6836u16),(34569u16,6841u16), (34570u16,6844u16),(34573u16,6842u16),(34577u16,6840u16),(34578u16,6834u16), (34584u16,3251u16),(34586u16,6851u16),(34588u16,4051u16),(34597u16,6849u16), (34601u16,6850u16),(34612u16,6845u16),(34615u16,6847u16),(34619u16,6848u16), (34623u16,6846u16),(34633u16,2983u16),(34635u16,4348u16),(34636u16,6855u16), (34638u16,6856u16),(34643u16,6862u16),(34645u16,2829u16),(34647u16,6858u16), (34649u16,6861u16),(34655u16,6853u16),(34656u16,6852u16),(34659u16,6863u16), (34662u16,1657u16),(34664u16,6859u16),(34666u16,6864u16),(34670u16,6860u16), (34676u16,6857u16),(34678u16,3308u16),(34680u16,6854u16),(34687u16,3643u16), (34690u16,6868u16),(34701u16,4162u16),(34719u16,6867u16),(34722u16,6866u16), (34731u16,6875u16),(34735u16,6869u16),(34739u16,6877u16),(34746u16,4205u16), (34747u16,6880u16),(34749u16,6871u16),(34752u16,6872u16),(34756u16,6876u16), (34758u16,6879u16),(34759u16,6878u16),(34763u16,6870u16),(34768u16,6873u16), (34770u16,6890u16),(34784u16,6883u16),(34799u16,6881u16),(34802u16,6882u16), (34806u16,6887u16),(34807u16,6888u16),(34809u16,1701u16),(34811u16,1913u16), (34814u16,6886u16),(34821u16,6865u16),(34823u16,8528u16),(34829u16,6885u16), (34830u16,6889u16),(34831u16,6884u16),(34833u16,6891u16),(34837u16,6893u16), (34838u16,6892u16),(34849u16,6895u16),(34850u16,6894u16),(34851u16,6825u16), (34855u16,6899u16),(34865u16,6896u16),(34870u16,6897u16),(34873u16,6898u16), (34875u16,6900u16),(34880u16,2143u16),(34882u16,6902u16),(34884u16,6901u16), (34886u16,2647u16),(34892u16,2307u16),(34893u16,5740u16),(34898u16,6903u16), (34899u16,2680u16),(34903u16,1716u16),(34905u16,6904u16),(34907u16,1553u16), (34909u16,2780u16),(34910u16,6905u16),(34913u16,2308u16),(34914u16,6906u16), (34915u16,1474u16),(34920u16,3788u16),(34923u16,6907u16),(34928u16,2893u16), (34930u16,6914u16),(34933u16,6911u16),(34935u16,3274u16),(34941u16,6912u16), (34942u16,6909u16),(34943u16,2035u16),(34945u16,6908u16),(34946u16,6915u16), (34952u16,2089u16),(34955u16,3163u16),(34957u16,6921u16),(34962u16,6917u16), (34966u16,3122u16),(34967u16,6916u16),(34969u16,6919u16),(34974u16,6910u16), (34978u16,6920u16),(34980u16,6922u16),(34987u16,3744u16),(34990u16,6918u16), (34992u16,6923u16),(34993u16,6925u16),(34996u16,2212u16),(34997u16,6913u16), (34999u16,1442u16),(35007u16,6924u16),(35009u16,2408u16),(35010u16,4315u16), (35011u16,6926u16),(35012u16,6927u16),(35013u16,3092u16),(35023u16,4231u16), (35028u16,6928u16),(35029u16,4156u16),(35032u16,6929u16),(35033u16,6930u16), (35036u16,3921u16),(35037u16,6931u16),(35039u16,2381u16),(35041u16,4232u16), (35048u16,6936u16),(35058u16,6937u16),(35059u16,2781u16),(35060u16,6935u16), (35061u16,8529u16),(35064u16,4206u16),(35065u16,6932u16),(35068u16,6934u16), (35069u16,2942u16),(35070u16,2913u16),(35074u16,6933u16),(35076u16,6938u16), (35079u16,3856u16),(35082u16,6940u16),(35084u16,6939u16),(35088u16,1767u16), (35090u16,3958u16),(35091u16,6941u16),(35100u16,8273u16),(35101u16,6953u16), (35102u16,6943u16),(35109u16,6944u16),(35114u16,6945u16),(35115u16,6946u16), (35126u16,6950u16),(35128u16,6951u16),(35131u16,6949u16),(35137u16,6947u16), (35139u16,6942u16),(35140u16,6948u16),(35148u16,6952u16),(35149u16,7448u16), (35158u16,1605u16),(35166u16,6955u16),(35167u16,2036u16),(35168u16,6954u16), (35172u16,6957u16),(35174u16,6956u16),(35178u16,6959u16),(35181u16,6958u16), (35183u16,6960u16),(35186u16,2648u16),(35188u16,6961u16),(35191u16,6962u16), (35198u16,6963u16),(35199u16,2943u16),(35201u16,4190u16),(35203u16,6964u16), (35206u16,3857u16),(35207u16,3609u16),(35208u16,6965u16),(35210u16,6966u16), (35211u16,2172u16),(35215u16,1891u16),(35219u16,6967u16),(35222u16,2518u16), (35223u16,3604u16),(35224u16,6968u16),(35226u16,1739u16),(35233u16,6969u16), (35238u16,6971u16),(35239u16,4222u16),(35241u16,6970u16),(35242u16,2857u16), (35244u16,6972u16),(35247u16,6973u16),(35250u16,6974u16),(35251u16,1834u16), (35258u16,6975u16),(35261u16,6976u16),(35263u16,6977u16),(35264u16,6978u16), (35282u16,1740u16),(35290u16,6979u16),(35292u16,6980u16),(35293u16,6981u16), (35299u16,1679u16),(35302u16,2827u16),(35303u16,6982u16),(35316u16,6983u16), (35320u16,6984u16),(35328u16,2193u16),(35330u16,3380u16),(35331u16,6985u16), (35336u16,2122u16),(35338u16,2873u16),(35340u16,6988u16),(35342u16,3481u16), (35344u16,6987u16),(35346u16,8530u16),(35347u16,2084u16),(35350u16,6986u16), (35351u16,3188u16),(35352u16,1892u16),(35355u16,6989u16),(35357u16,6990u16), (35359u16,2782u16),(35363u16,2144u16),(35365u16,6991u16),(35370u16,3959u16), (35373u16,2976u16),(35377u16,1965u16),(35379u16,4126u16),(35380u16,3049u16), (35382u16,6992u16),(35383u16,8531u16),(35386u16,2858u16),(35387u16,3275u16), (35388u16,2783u16),(35393u16,6993u16),(35398u16,6996u16),(35400u16,6997u16), (35408u16,2379u16),(35409u16,3135u16),(35410u16,6995u16),(35412u16,2784u16), (35413u16,3789u16),(35419u16,6994u16),(35422u16,2519u16),(35424u16,1554u16), (35426u16,7001u16),(35427u16,2123u16),(35430u16,2521u16),(35433u16,2520u16), (35435u16,4368u16),(35436u16,7000u16),(35437u16,6999u16),(35438u16,3014u16), (35440u16,1924u16),(35441u16,4358u16),(35442u16,1717u16),(35443u16,2785u16), (35449u16,8532u16),(35452u16,6998u16),(35458u16,7003u16),(35460u16,7004u16), (35461u16,7002u16),(35463u16,2217u16),(35465u16,4167u16),(35468u16,2522u16), (35469u16,3578u16),(35473u16,7007u16),(35475u16,2945u16),(35477u16,3229u16), (35480u16,4157u16),(35482u16,7010u16),(35486u16,2237u16),(35488u16,2944u16), (35489u16,7006u16),(35491u16,7011u16),(35492u16,2238u16),(35493u16,7008u16), (35494u16,7009u16),(35495u16,8533u16),(35496u16,7005u16),(35500u16,2979u16), (35501u16,3518u16),(35504u16,3210u16),(35506u16,1658u16),(35513u16,3745u16), (35516u16,1914u16),(35518u16,8534u16),(35519u16,3309u16),(35522u16,7014u16), (35524u16,7012u16),(35527u16,3239u16),(35531u16,2946u16),(35532u16,1835u16), (35533u16,7013u16),(35535u16,2878u16),(35538u16,4271u16),(35542u16,4355u16), (35546u16,7015u16),(35547u16,7026u16),(35548u16,3310u16),(35550u16,7025u16), (35551u16,8535u16),(35552u16,7022u16),(35553u16,7030u16),(35554u16,7023u16), (35556u16,7019u16),(35558u16,3381u16),(35559u16,7018u16),(35563u16,7016u16), (35565u16,4136u16),(35566u16,2523u16),(35569u16,7020u16),(35571u16,7017u16), (35574u16,8537u16),(35575u16,7024u16),(35576u16,2715u16),(35578u16,2194u16), (35582u16,3191u16),(35584u16,3984u16),(35585u16,1561u16),(35586u16,1475u16), (35588u16,3482u16),(35591u16,7028u16),(35596u16,7027u16),(35598u16,3547u16), (35600u16,7032u16),(35604u16,7021u16),(35606u16,7031u16),(35607u16,7033u16), (35609u16,2173u16),(35610u16,7029u16),(35611u16,2309u16),(35613u16,2590u16), (35616u16,7034u16),(35617u16,4191u16),(35622u16,7037u16),(35624u16,7040u16), (35627u16,7038u16),(35628u16,3780u16),(35635u16,7035u16),(35641u16,2037u16), (35646u16,7039u16),(35649u16,7041u16),(35657u16,7045u16),(35660u16,7042u16), (35662u16,7044u16),(35663u16,7043u16),(35667u16,8538u16),(35670u16,7046u16), (35672u16,2554u16),(35674u16,7048u16),(35675u16,7047u16),(35676u16,3831u16), (35679u16,7050u16),(35686u16,2124u16),(35691u16,7049u16),(35692u16,7051u16), (35695u16,7052u16),(35696u16,1915u16),(35697u16,6518u16),(35698u16,2814u16), (35700u16,7053u16),(35703u16,2239u16),(35709u16,7054u16),(35711u16,8539u16), (35712u16,7055u16),(35715u16,2473u16),(35722u16,5403u16),(35724u16,7056u16), (35726u16,7057u16),(35728u16,2649u16),(35730u16,7058u16),(35731u16,7059u16), (35734u16,7060u16),(35737u16,7061u16),(35738u16,7062u16),(35895u16,3206u16), (35898u16,7063u16),(35903u16,7065u16),(35905u16,7064u16),(35910u16,3483u16), (35912u16,7066u16),(35914u16,3960u16),(35916u16,7067u16),(35918u16,7068u16), (35920u16,7069u16),(35925u16,7070u16),(35930u16,3535u16),(35937u16,2786u16), (35938u16,7071u16),(35946u16,2330u16),(35947u16,4431u16),(35948u16,7072u16), (35960u16,7073u16),(35961u16,3790u16),(35962u16,7074u16),(35964u16,7082u16), (35970u16,7075u16),(35973u16,7077u16),(35977u16,7076u16),(35978u16,7078u16), (35980u16,3985u16),(35981u16,7079u16),(35982u16,7080u16),(35988u16,7081u16), (35992u16,7083u16),(35997u16,1704u16),(35998u16,3360u16),(36000u16,3832u16), (36001u16,2415u16),(36002u16,2310u16),(36007u16,3806u16),(36008u16,1660u16), (36009u16,3711u16),(36010u16,7086u16),(36011u16,1836u16),(36012u16,2966u16), (36013u16,7085u16),(36014u16,7090u16),(36015u16,3284u16),(36016u16,4108u16), (36018u16,7088u16),(36019u16,7089u16),(36020u16,1893u16),(36022u16,7091u16), (36023u16,3638u16),(36024u16,3164u16),(36027u16,3746u16),(36028u16,3412u16), (36029u16,7087u16),(36031u16,3986u16),(36032u16,1673u16),(36033u16,7093u16), (36034u16,4331u16),(36035u16,3323u16),(36036u16,4360u16),(36039u16,2524u16), (36040u16,7092u16),(36042u16,3118u16),(36045u16,7109u16),(36046u16,3015u16), (36049u16,3565u16),(36051u16,3807u16),(36058u16,7096u16),(36059u16,2474u16), (36060u16,2525u16),(36062u16,2787u16),(36064u16,3640u16),(36066u16,2174u16), (36067u16,7095u16),(36068u16,7094u16),(36070u16,3833u16),(36074u16,2570u16), (36077u16,3433u16),(36080u16,8540u16),(36084u16,8541u16),(36090u16,7098u16), (36091u16,7099u16),(36092u16,2311u16),(36093u16,7097u16),(36100u16,7100u16), (36101u16,7101u16),(36103u16,7103u16),(36104u16,3104u16),(36106u16,7102u16), (36107u16,1855u16),(36109u16,7105u16),(36111u16,7104u16),(36112u16,7106u16), (36114u16,8542u16),(36115u16,7108u16),(36116u16,7110u16),(36118u16,7111u16), (36196u16,2967u16),(36198u16,2584u16),(36199u16,7112u16),(36203u16,1741u16), (36205u16,7113u16),(36208u16,3093u16),(36209u16,7114u16),(36211u16,7115u16), (36212u16,3834u16),(36214u16,8543u16),(36215u16,1894u16),(36225u16,7116u16), (36229u16,3311u16),(36234u16,1562u16),(36249u16,7117u16),(36259u16,2618u16), (36264u16,2905u16),(36275u16,3114u16),(36282u16,7120u16),(36286u16,7119u16), (36290u16,7118u16),(36299u16,7126u16),(36300u16,7124u16),(36303u16,7121u16), (36310u16,7123u16),(36314u16,7122u16),(36315u16,7125u16),(36317u16,1966u16), (36319u16,7129u16),(36321u16,2968u16),(36323u16,7130u16),(36328u16,2218u16), (36330u16,7127u16),(36331u16,7128u16),(36335u16,4332u16),(36339u16,3312u16), (36341u16,3016u16),(36348u16,7131u16),(36351u16,7134u16),(36360u16,7132u16), (36361u16,7133u16),(36362u16,4192u16),(36367u16,3484u16),(36368u16,7137u16), (36381u16,7135u16),(36382u16,7136u16),(36383u16,7138u16),(36394u16,7152u16), (36400u16,7141u16),(36404u16,7142u16),(36405u16,7140u16),(36418u16,7139u16), (36420u16,3382u16),(36423u16,7144u16),(36424u16,7148u16),(36425u16,7145u16), (36426u16,7143u16),(36428u16,7146u16),(36432u16,7147u16),(36437u16,7154u16), (36441u16,7149u16),(36447u16,2969u16),(36448u16,7151u16),(36451u16,7153u16), (36452u16,7150u16),(36466u16,7156u16),(36468u16,2650u16),(36470u16,7155u16), (36476u16,7157u16),(36481u16,7158u16),(36484u16,7161u16),(36485u16,7160u16), (36487u16,7159u16),(36490u16,7163u16),(36491u16,7162u16),(36493u16,4127u16), (36497u16,7165u16),(36499u16,7164u16),(36500u16,7166u16),(36505u16,7167u16), (36513u16,7169u16),(36522u16,7168u16),(36523u16,2859u16),(36524u16,7170u16), (36527u16,2050u16),(36528u16,7171u16),(36529u16,7173u16),(36542u16,7174u16), (36549u16,7175u16),(36550u16,7172u16),(36552u16,7176u16),(36554u16,2591u16), (36555u16,7177u16),(36556u16,1895u16),(36557u16,2086u16),(36559u16,8545u16), (36562u16,2175u16),(36571u16,7178u16),(36575u16,3557u16),(36578u16,3413u16), (36579u16,7179u16),(36587u16,7182u16),(36600u16,2557u16),(36603u16,7181u16), (36604u16,7180u16),(36605u16,2125u16),(36606u16,7183u16),(36611u16,1742u16), (36613u16,7185u16),(36617u16,2409u16),(36618u16,7184u16),(36620u16,7193u16), (36626u16,7187u16),(36627u16,7189u16),(36628u16,3922u16),(36629u16,7186u16), (36633u16,7188u16),(36635u16,7192u16),(36636u16,7190u16),(36637u16,1896u16), (36639u16,7191u16),(36646u16,7194u16),(36649u16,3629u16),(36650u16,4285u16), (36655u16,2651u16),(36659u16,7195u16),(36664u16,4137u16),(36665u16,7197u16), (36667u16,7196u16),(36670u16,7200u16),(36671u16,4168u16),(36674u16,7199u16), (36676u16,1768u16),(36677u16,7198u16),(36678u16,7203u16),(36681u16,7202u16), (36684u16,7201u16),(36685u16,3401u16),(36686u16,7204u16),(36695u16,7205u16), (36700u16,7206u16),(36703u16,2331u16),(36705u16,2072u16),(36706u16,7207u16), (36707u16,7208u16),(36708u16,7209u16),(36763u16,2860u16),(36764u16,7210u16), (36766u16,2550u16),(36767u16,7211u16),(36771u16,7212u16),(36775u16,4606u16), (36776u16,4605u16),(36781u16,7213u16),(36782u16,6471u16),(36783u16,7214u16), (36784u16,3199u16),(36785u16,2830u16),(36786u16,3603u16),(36791u16,7215u16), (36794u16,3906u16),(36795u16,3341u16),(36796u16,2349u16),(36799u16,3204u16), (36802u16,1513u16),(36804u16,4035u16),(36805u16,2874u16),(36814u16,2129u16), (36817u16,2038u16),(36820u16,3907u16),(36826u16,7216u16),(36834u16,7218u16), (36837u16,7217u16),(36838u16,1661u16),(36841u16,3563u16),(36842u16,7219u16), (36843u16,3658u16),(36845u16,3402u16),(36847u16,7220u16),(36848u16,2681u16), (36852u16,7222u16),(36855u16,4075u16),(36856u16,7237u16),(36857u16,7224u16), (36858u16,7225u16),(36861u16,3330u16),(36864u16,3165u16),(36865u16,3094u16), (36867u16,3485u16),(36869u16,7223u16),(36870u16,1932u16),(36875u16,7232u16), (36877u16,7229u16),(36878u16,7242u16),(36879u16,3486u16),(36880u16,3259u16), (36881u16,7226u16),(36883u16,3383u16),(36884u16,3434u16),(36885u16,7227u16), (36886u16,7231u16),(36887u16,2883u16),(36889u16,3642u16),(36890u16,3333u16), (36893u16,2947u16),(36894u16,7230u16),(36895u16,3115u16),(36896u16,3105u16), (36897u16,7228u16),(36898u16,1418u16),(36899u16,4325u16),(36903u16,7233u16), (36910u16,3166u16),(36913u16,2652u16),(36914u16,2861u16),(36917u16,7235u16), (36918u16,7234u16),(36920u16,1488u16),(36921u16,7236u16),(36924u16,3774u16), (36926u16,7244u16),(36929u16,3536u16),(36930u16,2894u16),(36933u16,3252u16), (36935u16,2061u16),(36937u16,7243u16),(36938u16,4158u16),(36939u16,1534u16), (36941u16,3908u16),(36942u16,1662u16),(36943u16,7238u16),(36944u16,7239u16), (36945u16,7240u16),(36946u16,7241u16),(36947u16,3504u16),(36948u16,3198u16), (36949u16,1476u16),(36950u16,7245u16),(36952u16,7246u16),(36953u16,7804u16), (36956u16,3130u16),(36958u16,7247u16),(36960u16,1586u16),(36961u16,3051u16), (36963u16,2176u16),(36965u16,4193u16),(36967u16,8548u16),(36968u16,7248u16), (36969u16,3395u16),(36973u16,3095u16),(36974u16,2592u16),(36975u16,7249u16), (36978u16,7252u16),(36981u16,2700u16),(36982u16,7250u16),(36983u16,3018u16), (36984u16,3017u16),(36986u16,1477u16),(36988u16,4272u16),(36989u16,7254u16), (36991u16,3747u16),(36992u16,7256u16),(36993u16,7255u16),(36994u16,7253u16), (36995u16,6271u16),(36996u16,1837u16),(36999u16,7221u16),(37001u16,7258u16), (37002u16,7257u16),(37007u16,7259u16),(37009u16,4159u16),(37027u16,3542u16), (37030u16,3961u16),(37032u16,7260u16),(37034u16,2594u16),(37039u16,7261u16), (37041u16,7262u16),(37045u16,7263u16),(37048u16,3384u16),(37057u16,1483u16), (37066u16,2312u16),(37070u16,4349u16),(37083u16,7267u16),(37086u16,8549u16), (37089u16,2087u16),(37090u16,7264u16),(37092u16,7265u16),(37096u16,3843u16), (37101u16,1743u16),(37109u16,4160u16),(37111u16,2004u16),(37117u16,3435u16), (37122u16,7268u16),(37138u16,7269u16),(37141u16,8551u16),(37145u16,7270u16), (37159u16,8552u16),(37165u16,3385u16),(37168u16,7272u16),(37170u16,7271u16), (37193u16,3528u16),(37194u16,7273u16),(37195u16,2653u16),(37196u16,2601u16), (37197u16,3630u16),(37198u16,3276u16),(37202u16,2619u16),(37204u16,2895u16), (37206u16,7274u16),(37208u16,7275u16),(37218u16,2880u16),(37219u16,7276u16), (37221u16,7277u16),(37225u16,7278u16),(37226u16,4214u16),(37228u16,2654u16), (37234u16,7280u16),(37235u16,7279u16),(37237u16,2313u16),(37239u16,2338u16), (37240u16,2475u16),(37250u16,7283u16),(37255u16,2701u16),(37257u16,7282u16), (37259u16,7281u16),(37261u16,3174u16),(37264u16,2240u16),(37266u16,2948u16), (37271u16,3681u16),(37276u16,2656u16),(37282u16,7284u16),(37284u16,2788u16), (37290u16,7287u16),(37291u16,7285u16),(37295u16,7286u16),(37300u16,7289u16), (37301u16,7288u16),(37304u16,2815u16),(37306u16,7290u16),(37312u16,7291u16), (37313u16,7292u16),(37318u16,3713u16),(37319u16,2400u16),(37320u16,2602u16), (37321u16,7293u16),(37323u16,7294u16),(37324u16,4233u16),(37325u16,2668u16), (37326u16,4119u16),(37327u16,4273u16),(37328u16,7295u16),(37329u16,2039u16), (37334u16,7296u16),(37335u16,8554u16),(37336u16,3386u16),(37338u16,8553u16), (37339u16,7299u16),(37340u16,1779u16),(37341u16,2862u16),(37342u16,8555u16), (37343u16,7297u16),(37345u16,7298u16),(37347u16,3353u16),(37348u16,8558u16), (37349u16,8559u16),(37350u16,4000u16),(37351u16,2065u16),(37357u16,8556u16), (37358u16,8557u16),(37365u16,7301u16),(37366u16,7302u16),(37372u16,7300u16), (37375u16,7304u16),(37382u16,8560u16),(37386u16,8562u16),(37389u16,3540u16), (37390u16,1726u16),(37392u16,8561u16),(37393u16,7308u16),(37396u16,7305u16), (37397u16,7307u16),(37406u16,7303u16),(37417u16,7378u16),(37420u16,7306u16), (37428u16,4304u16),(37431u16,2219u16),(37433u16,8569u16),(37434u16,8563u16), (37436u16,8565u16),(37439u16,7316u16),(37440u16,8564u16),(37444u16,3403u16), (37445u16,7311u16),(37448u16,7314u16),(37449u16,7312u16),(37451u16,7317u16), (37454u16,8566u16),(37456u16,7318u16),(37457u16,8568u16),(37463u16,7310u16), (37465u16,8567u16),(37466u16,7323u16),(37467u16,1587u16),(37470u16,7309u16), (37474u16,3678u16),(37476u16,7313u16),(37478u16,2789u16),(37479u16,8570u16), (37489u16,2314u16),(37495u16,8572u16),(37496u16,8573u16),(37502u16,3987u16), (37504u16,2041u16),(37507u16,2669u16),(37509u16,3505u16),(37512u16,8275u16), (37521u16,3020u16),(37523u16,7321u16),(37525u16,7315u16),(37526u16,7320u16), (37528u16,4076u16),(37530u16,3313u16),(37531u16,7322u16),(37532u16,7319u16), (37543u16,8571u16),(37549u16,3019u16),(37559u16,7326u16),(37561u16,7325u16), (37583u16,7324u16),(37584u16,8577u16),(37586u16,3962u16),(37587u16,8581u16), (37589u16,8579u16),(37591u16,8575u16),(37593u16,8576u16),(37600u16,8580u16), (37604u16,2722u16),(37607u16,8574u16),(37609u16,7327u16),(37610u16,3916u16), (37613u16,1555u16),(37618u16,3797u16),(37619u16,3277u16),(37624u16,1967u16), (37625u16,8281u16),(37626u16,7329u16),(37627u16,8584u16),(37628u16,2316u16), (37631u16,8587u16),(37634u16,8589u16),(37638u16,2455u16),(37647u16,7328u16), (37648u16,2896u16),(37656u16,2897u16),(37657u16,7332u16),(37658u16,7334u16), (37661u16,8588u16),(37662u16,8586u16),(37664u16,2816u16),(37665u16,8583u16), (37666u16,7333u16),(37667u16,7335u16),(37669u16,8582u16),(37670u16,2024u16), (37672u16,3796u16),(37675u16,2603u16),(37676u16,4326u16),(37678u16,7331u16), (37679u16,2437u16),(37682u16,4354u16),(37685u16,7337u16),(37690u16,7336u16), (37691u16,7338u16),(37700u16,7330u16),(37704u16,8274u16),(37707u16,3550u16), (37709u16,3436u16),(37716u16,3344u16),(37718u16,7343u16),(37719u16,8591u16), (37723u16,3230u16),(37724u16,7339u16),(37728u16,7340u16),(37740u16,2080u16), (37742u16,7342u16),(37744u16,8590u16),(37749u16,2177u16),(37756u16,7341u16), (37758u16,2790u16),(37772u16,1780u16),(37780u16,7347u16),(37782u16,2380u16), (37783u16,3096u16),(37786u16,3331u16),(37796u16,8592u16),(37799u16,1718u16), (37804u16,7345u16),(37805u16,7346u16),(37806u16,3324u16),(37808u16,7344u16), (37817u16,7348u16),(37827u16,7354u16),(37830u16,8593u16),(37832u16,7357u16), (37840u16,7356u16),(37841u16,3396u16),(37846u16,7349u16),(37847u16,7350u16), (37848u16,7353u16),(37853u16,7355u16),(37854u16,8594u16),(37857u16,2005u16), (37860u16,7358u16),(37861u16,7352u16),(37864u16,7351u16),(37880u16,8595u16), (37891u16,7362u16),(37895u16,7363u16),(37904u16,7364u16),(37907u16,7361u16), (37908u16,7360u16),(37912u16,2791u16),(37913u16,3487u16),(37914u16,7359u16), (37921u16,7368u16),(37931u16,7366u16),(37937u16,8596u16),(37941u16,7367u16), (37942u16,7365u16),(37944u16,3189u16),(37946u16,7369u16),(37953u16,7370u16), (37956u16,7372u16),(37957u16,8597u16),(37960u16,8598u16),(37969u16,1838u16), (37970u16,7371u16),(37971u16,4131u16),(37978u16,7383u16),(37979u16,7373u16), (37982u16,7376u16),(37984u16,7374u16),(37986u16,7375u16),(37994u16,7377u16), (38000u16,7379u16),(38005u16,7380u16),(38007u16,7381u16),(38012u16,7384u16), (38013u16,7382u16),(38014u16,7385u16),(38015u16,7387u16),(38017u16,7386u16), (38263u16,3314u16),(38272u16,4112u16),(38274u16,7388u16),(38275u16,3021u16), (38279u16,7389u16),(38281u16,3889u16),(38282u16,7390u16),(38283u16,1702u16), (38287u16,1531u16),(38289u16,1840u16),(38290u16,8599u16),(38291u16,1839u16), (38292u16,7391u16),(38294u16,7392u16),(38296u16,7393u16),(38297u16,7394u16), (38304u16,7395u16),(38306u16,1841u16),(38307u16,1744u16),(38308u16,2317u16), (38309u16,3687u16),(38311u16,7397u16),(38312u16,7396u16),(38317u16,7398u16), (38322u16,1563u16),(38329u16,7401u16),(38331u16,7400u16),(38332u16,7399u16), (38334u16,7402u16),(38339u16,7405u16),(38343u16,1448u16),(38346u16,7403u16), (38348u16,7407u16),(38349u16,7406u16),(38356u16,7409u16),(38357u16,7408u16), (38358u16,7410u16),(38360u16,3491u16),(38364u16,7411u16),(38369u16,7412u16), (38370u16,7414u16),(38373u16,7413u16),(38428u16,3835u16),(38433u16,7415u16), (38440u16,7416u16),(38442u16,2418u16),(38446u16,7417u16),(38447u16,7418u16), (38450u16,3988u16),(38459u16,3050u16),(38463u16,1413u16),(38464u16,3144u16), (38466u16,7419u16),(38468u16,3836u16),(38475u16,7422u16),(38476u16,7420u16), (38477u16,2318u16),(38479u16,7421u16),(38480u16,2195u16),(38491u16,3890u16), (38492u16,7424u16),(38493u16,7426u16),(38494u16,7425u16),(38495u16,7427u16), (38498u16,1504u16),(38499u16,2875u16),(38500u16,2723u16),(38501u16,1842u16), (38502u16,7428u16),(38506u16,3641u16),(38508u16,7430u16),(38512u16,1505u16), (38514u16,7429u16),(38515u16,3325u16),(38517u16,4274u16),(38518u16,3488u16), (38519u16,7423u16),(38520u16,4235u16),(38522u16,2178u16),(38525u16,4194u16), (38533u16,2062u16),(38534u16,4249u16),(38536u16,2075u16),(38538u16,3167u16), (38539u16,6580u16),(38541u16,7431u16),(38542u16,1703u16),(38543u16,2898u16), (38548u16,1745u16),(38549u16,7433u16),(38551u16,7434u16),(38552u16,7432u16), (38553u16,2135u16),(38555u16,2410u16),(38556u16,2792u16),(38557u16,8602u16), (38560u16,1506u16),(38563u16,4286u16),(38567u16,7436u16),(38568u16,7251u16), (38570u16,7435u16),(38575u16,8603u16),(38576u16,7439u16),(38577u16,7437u16), (38578u16,7438u16),(38580u16,7440u16),(38582u16,7441u16),(38583u16,4305u16), (38584u16,7442u16),(38585u16,7443u16),(38587u16,2954u16),(38588u16,3692u16), (38592u16,2912u16),(38593u16,1856u16),(38596u16,4161u16),(38597u16,1674u16), (38598u16,2655u16),(38599u16,2220u16),(38601u16,7446u16),(38603u16,7445u16), (38604u16,2526u16),(38605u16,7447u16),(38606u16,7444u16),(38609u16,2451u16), (38613u16,7451u16),(38614u16,6874u16),(38617u16,4659u16),(38619u16,2906u16), (38620u16,7449u16),(38626u16,4234u16),(38627u16,3558u16),(38632u16,1514u16), (38634u16,2980u16),(38635u16,2559u16),(38640u16,3876u16),(38642u16,1535u16), (38646u16,4306u16),(38647u16,4210u16),(38649u16,7452u16),(38651u16,3420u16), (38656u16,2628u16),(38660u16,7453u16),(38662u16,7454u16),(38663u16,2863u16), (38664u16,7455u16),(38666u16,4307u16),(38669u16,7450u16),(38670u16,7457u16), (38671u16,7459u16),(38673u16,7458u16),(38675u16,7456u16),(38678u16,7460u16), (38681u16,7461u16),(38684u16,3097u16),(38686u16,1663u16),(38692u16,7462u16), (38695u16,4065u16),(38698u16,7463u16),(38704u16,7464u16),(38706u16,4333u16), (38707u16,8604u16),(38712u16,5468u16),(38713u16,7465u16),(38715u16,8605u16), (38717u16,7466u16),(38718u16,7467u16),(38722u16,7471u16),(38723u16,8606u16), (38724u16,7468u16),(38726u16,7469u16),(38728u16,7470u16),(38729u16,7472u16), (38733u16,8607u16),(38735u16,8608u16),(38737u16,8609u16),(38738u16,2949u16), (38741u16,8610u16),(38742u16,4128u16),(38745u16,2950u16),(38748u16,7473u16), (38750u16,3748u16),(38752u16,7474u16),(38753u16,7758u16),(38754u16,4085u16), (38756u16,7475u16),(38758u16,7476u16),(38760u16,7477u16),(38761u16,1746u16), (38763u16,7479u16),(38765u16,2876u16),(38769u16,7480u16),(38772u16,2071u16), (38777u16,7481u16),(38778u16,7485u16),(38780u16,7483u16),(38785u16,7484u16), (38788u16,1774u16),(38789u16,7482u16),(38790u16,7486u16),(38795u16,7487u16), (38797u16,1449u16),(38799u16,7488u16),(38800u16,7489u16),(38808u16,2793u16), (38812u16,7490u16),(38816u16,1918u16),(38819u16,7493u16),(38822u16,7492u16), (38824u16,7491u16),(38827u16,7036u16),(38829u16,3913u16),(38835u16,7494u16), (38836u16,7495u16),(38851u16,7496u16),(38854u16,7497u16),(38856u16,7498u16), (38859u16,7499u16),(38867u16,1843u16),(38876u16,7500u16),(38893u16,7501u16), (38894u16,3574u16),(38898u16,7503u16),(38899u16,1624u16),(38901u16,7506u16), (38902u16,7505u16),(38907u16,1507u16),(38911u16,2006u16),(38913u16,3892u16), (38914u16,3315u16),(38915u16,2351u16),(38917u16,2319u16),(38918u16,2702u16), (38920u16,2879u16),(38924u16,7508u16),(38927u16,7507u16),(38928u16,4169u16), (38929u16,1857u16),(38930u16,3715u16),(38931u16,3537u16),(38935u16,2911u16), (38936u16,4275u16),(38938u16,2126u16),(38945u16,7511u16),(38948u16,7510u16), (38956u16,3990u16),(38957u16,3489u16),(38964u16,1551u16),(38967u16,7512u16), (38968u16,7509u16),(38971u16,3808u16),(38972u16,4209u16),(38973u16,7513u16), (38982u16,7514u16),(38987u16,7516u16),(38988u16,3175u16),(38989u16,1750u16), (38990u16,1751u16),(38991u16,7515u16),(38996u16,1858u16),(38997u16,2179u16), (38999u16,8611u16),(39000u16,1859u16),(39003u16,3414u16),(39006u16,4293u16), (39013u16,8612u16),(39015u16,2221u16),(39019u16,7517u16),(39023u16,7518u16), (39024u16,7519u16),(39025u16,7520u16),(39027u16,7522u16),(39028u16,7521u16), (39080u16,3846u16),(39082u16,7523u16),(39087u16,7524u16),(39089u16,7525u16), (39094u16,7526u16),(39107u16,7528u16),(39108u16,7527u16),(39110u16,7529u16), (39131u16,3749u16),(39132u16,6529u16),(39135u16,2828u16),(39138u16,1897u16), (39145u16,7530u16),(39147u16,7531u16),(39149u16,4617u16),(39150u16,5666u16), (39151u16,3716u16),(39154u16,1500u16),(39156u16,1436u16),(39164u16,2527u16), (39165u16,3963u16),(39166u16,2819u16),(39171u16,7532u16),(39173u16,4104u16), (39177u16,7533u16),(39178u16,4195u16),(39180u16,1537u16),(39184u16,2476u16), (39186u16,7534u16),(39187u16,1675u16),(39188u16,7535u16),(39192u16,7536u16), (39197u16,7538u16),(39198u16,7539u16),(39200u16,7541u16),(39201u16,7537u16), (39204u16,7540u16),(39207u16,8615u16),(39208u16,1844u16),(39212u16,7542u16), (39214u16,7543u16),(39229u16,7544u16),(39230u16,7545u16),(39234u16,7546u16), (39237u16,7548u16),(39241u16,7547u16),(39243u16,7550u16),(39244u16,7553u16), (39248u16,7549u16),(39249u16,7551u16),(39250u16,7552u16),(39253u16,7554u16), (39255u16,2007u16),(39318u16,2620u16),(39319u16,7555u16),(39320u16,7556u16), (39321u16,2320u16),(39326u16,8617u16),(39333u16,7557u16),(39336u16,1721u16), (39340u16,3618u16),(39341u16,7558u16),(39342u16,7559u16),(39347u16,3253u16), (39348u16,3552u16),(39356u16,7560u16),(39361u16,3664u16),(39364u16,3145u16), (39365u16,1559u16),(39366u16,2051u16),(39368u16,2052u16),(39376u16,3278u16), (39377u16,7565u16),(39378u16,2053u16),(39381u16,1676u16),(39384u16,7564u16), (39387u16,7562u16),(39389u16,7563u16),(39391u16,7561u16),(39394u16,7575u16), (39405u16,7566u16),(39406u16,7567u16),(39409u16,7568u16),(39410u16,7569u16), (39416u16,7571u16),(39419u16,7570u16),(39423u16,2688u16),(39425u16,7572u16), (39429u16,7574u16),(39438u16,1898u16),(39439u16,7573u16),(39442u16,3098u16), (39443u16,2180u16),(39449u16,7576u16),(39464u16,3146u16),(39467u16,7577u16), (39472u16,3490u16),(39479u16,7578u16),(39486u16,7583u16),(39488u16,7581u16), (39490u16,7580u16),(39491u16,7582u16),(39493u16,7579u16),(39501u16,7585u16), (39502u16,8618u16),(39509u16,7584u16),(39511u16,7587u16),(39514u16,2008u16), (39515u16,7586u16),(39519u16,7588u16),(39522u16,7589u16),(39524u16,7591u16), (39525u16,7590u16),(39529u16,7592u16),(39530u16,7594u16),(39531u16,7593u16), (39592u16,2347u16),(39597u16,7595u16),(39600u16,7596u16),(39608u16,1719u16), (39612u16,7597u16),(39616u16,7598u16),(39620u16,2900u16),(39631u16,7599u16), (39633u16,7600u16),(39635u16,7601u16),(39636u16,7602u16),(39640u16,2321u16), (39641u16,8619u16),(39644u16,8620u16),(39646u16,7603u16),(39647u16,7604u16), (39650u16,7605u16),(39651u16,7606u16),(39654u16,7607u16),(39658u16,3682u16), (39659u16,7609u16),(39661u16,3765u16),(39662u16,7610u16),(39663u16,7608u16), (39665u16,7612u16),(39668u16,7611u16),(39671u16,7613u16),(39675u16,7614u16), (39686u16,7615u16),(39704u16,7616u16),(39706u16,7617u16),(39711u16,7618u16), (39714u16,7619u16),(39715u16,7620u16),(39717u16,7621u16),(39719u16,7622u16), (39720u16,7623u16),(39721u16,7624u16),(39722u16,7625u16),(39726u16,7626u16), (39727u16,7627u16),(39729u16,5660u16),(39730u16,7628u16),(39739u16,6385u16), (39740u16,1899u16),(39745u16,1692u16),(39746u16,2367u16),(39747u16,7630u16), (39748u16,7629u16),(39749u16,4046u16),(39757u16,7632u16),(39758u16,7633u16), (39759u16,7631u16),(39761u16,7634u16),(39764u16,4013u16),(39768u16,7635u16), (39770u16,1970u16),(39791u16,4328u16),(39794u16,8622u16),(39796u16,7636u16), (39797u16,8621u16),(39811u16,7638u16),(39822u16,1439u16),(39823u16,8623u16), (39825u16,7639u16),(39826u16,3864u16),(39827u16,7637u16),(39830u16,7640u16), (39831u16,7641u16),(39839u16,7642u16),(39840u16,7643u16),(39848u16,7644u16), (39850u16,4025u16),(39851u16,2456u16),(39853u16,2439u16),(39854u16,3022u16), (39857u16,8624u16),(39860u16,7645u16),(39865u16,7648u16),(39867u16,8625u16), (39872u16,7646u16),(39878u16,7649u16),(39881u16,2242u16),(39882u16,7647u16), (39887u16,7650u16),(39889u16,7651u16),(39890u16,7652u16),(39892u16,7656u16), (39894u16,2453u16),(39899u16,3169u16),(39905u16,7657u16),(39906u16,7654u16), (39907u16,7653u16),(39908u16,7655u16),(39912u16,2130u16),(39920u16,7661u16), (39921u16,7660u16),(39922u16,7659u16),(39925u16,1428u16),(39936u16,8626u16), (39940u16,7671u16),(39942u16,7667u16),(39944u16,7668u16),(39945u16,7664u16), (39946u16,7670u16),(39948u16,7666u16),(39949u16,1757u16),(39952u16,4367u16), (39954u16,7669u16),(39955u16,7665u16),(39956u16,7663u16),(39957u16,7662u16), (39963u16,7673u16),(39969u16,7676u16),(39972u16,7675u16),(39973u16,7674u16), (39981u16,3800u16),(39982u16,7672u16),(39983u16,1492u16),(39984u16,7677u16), (39986u16,7679u16),(39993u16,1770u16),(39994u16,7658u16),(39995u16,1526u16), (39998u16,7681u16),(40006u16,7680u16),(40007u16,7678u16),(40008u16,3208u16), (40018u16,4027u16),(40023u16,4287u16),(40026u16,7682u16),(40032u16,7683u16), (40039u16,7684u16),(40054u16,7685u16),(40056u16,7686u16),(40165u16,3316u16), (40167u16,7687u16),(40169u16,3688u16),(40171u16,7692u16),(40172u16,7688u16), (40176u16,7689u16),(40179u16,3964u16),(40180u16,4077u16),(40182u16,3525u16), (40195u16,7693u16),(40198u16,7694u16),(40199u16,3507u16),(40200u16,7691u16), (40201u16,7690u16),(40206u16,1607u16),(40210u16,7702u16),(40213u16,7701u16), (40219u16,1588u16),(40223u16,7699u16),(40227u16,7698u16),(40230u16,7696u16), (40232u16,1782u16),(40234u16,7695u16),(40235u16,2555u16),(40236u16,1606u16), (40251u16,2322u16),(40254u16,7705u16),(40255u16,7704u16),(40257u16,7703u16), (40260u16,7700u16),(40262u16,7706u16),(40264u16,7707u16),(40272u16,7712u16), (40273u16,7711u16),(40281u16,7713u16),(40284u16,1516u16),(40285u16,7708u16), (40286u16,7709u16),(40288u16,2339u16),(40289u16,4066u16),(40292u16,7710u16), (40299u16,8628u16),(40300u16,3965u16),(40303u16,7718u16),(40304u16,8627u16), (40306u16,7714u16),(40314u16,7719u16),(40327u16,7716u16),(40329u16,7715u16), (40335u16,2127u16),(40346u16,7720u16),(40356u16,7721u16),(40361u16,7722u16), (40363u16,7717u16),(40367u16,7697u16),(40370u16,7723u16),(40372u16,3354u16), (40376u16,7727u16),(40378u16,7728u16),(40379u16,7726u16),(40385u16,7725u16), (40386u16,7731u16),(40388u16,7724u16),(40390u16,7729u16),(40399u16,7730u16), (40403u16,7733u16),(40409u16,7732u16),(40422u16,7735u16),(40429u16,7736u16), (40431u16,7737u16),(40434u16,4364u16),(40440u16,7734u16),(40441u16,3176u16), (40442u16,2426u16),(40445u16,7738u16),(40473u16,8630u16),(40474u16,7739u16), (40475u16,7740u16),(40478u16,7741u16),(40565u16,7742u16),(40568u16,2181u16), (40569u16,7743u16),(40573u16,7744u16),(40575u16,2552u16),(40577u16,7745u16), (40584u16,7746u16),(40587u16,7747u16),(40588u16,7748u16),(40593u16,7751u16), (40594u16,7749u16),(40595u16,4351u16),(40597u16,7750u16),(40599u16,4308u16), (40605u16,7752u16),(40607u16,4288u16),(40613u16,7753u16),(40614u16,3665u16), (40617u16,7754u16),(40618u16,7756u16),(40621u16,7757u16),(40632u16,7755u16), (40633u16,2332u16),(40634u16,4086u16),(40635u16,4014u16),(40636u16,5068u16), (40638u16,5703u16),(40639u16,4038u16),(40644u16,1608u16),(40652u16,7759u16), (40653u16,1927u16),(40654u16,7760u16),(40655u16,7761u16),(40656u16,7762u16), (40657u16,8631u16),(40658u16,2340u16),(40660u16,7763u16),(40664u16,5973u16), (40665u16,4100u16),(40667u16,3168u16),(40668u16,7764u16),(40669u16,7766u16), (40670u16,7765u16),(40672u16,7767u16),(40677u16,7768u16),(40680u16,7769u16), (40687u16,7770u16),(40692u16,7771u16),(40694u16,7772u16),(40695u16,7773u16), (40697u16,7774u16),(40699u16,7775u16),(40700u16,7776u16),(40701u16,7777u16), (40711u16,7778u16),(40712u16,7779u16),(40718u16,3387u16),(40723u16,2222u16), (40725u16,7781u16),(40736u16,3052u16),(40737u16,7782u16),(40748u16,7783u16), (40763u16,3760u16),(40766u16,7784u16),(40778u16,7785u16),(40779u16,6226u16), (40782u16,7107u16),(40783u16,7502u16),(40786u16,7786u16),(40788u16,7787u16), (40799u16,7789u16),(40800u16,7790u16),(40801u16,7791u16),(40802u16,4309u16), (40803u16,7788u16),(40806u16,7792u16),(40807u16,7793u16),(40810u16,7795u16), (40812u16,7794u16),(40818u16,7797u16),(40822u16,7798u16),(40823u16,7796u16), (40845u16,4251u16),(40853u16,7799u16),(40860u16,7800u16),(40861u16,6255u16), (40864u16,7801u16),(63785u16,8403u16),(63964u16,8600u16),(64014u16,8323u16), (64015u16,8334u16),(64016u16,8335u16),(64017u16,8356u16),(64018u16,8395u16), (64019u16,8411u16),(64020u16,8413u16),(64021u16,8456u16),(64022u16,8462u16), (64023u16,8485u16),(64024u16,8493u16),(64025u16,8494u16),(64026u16,8495u16), (64027u16,8497u16),(64028u16,8501u16),(64029u16,8504u16),(64030u16,8513u16), (64031u16,8524u16),(64032u16,8526u16),(64033u16,8527u16),(64034u16,8536u16), (64035u16,8544u16),(64036u16,8546u16),(64037u16,8547u16),(64038u16,8550u16), (64039u16,8578u16),(64040u16,8585u16),(64041u16,8601u16),(64042u16,8613u16), (64043u16,8614u16),(64044u16,8616u16),(64045u16,8629u16),(65281u16,9u16), (65282u16,8647u16),(65283u16,83u16),(65284u16,79u16),(65285u16,82u16), (65286u16,84u16),(65287u16,8646u16),(65288u16,41u16),(65289u16,42u16), (65290u16,85u16),(65291u16,59u16),(65292u16,3u16),(65293u16,60u16), (65294u16,4u16),(65295u16,30u16),(65296u16,203u16),(65297u16,204u16), (65298u16,205u16),(65299u16,206u16),(65300u16,207u16),(65301u16,208u16), (65302u16,209u16),(65303u16,210u16),(65304u16,211u16),(65305u16,212u16), (65306u16,6u16),(65307u16,7u16),(65308u16,66u16),(65309u16,64u16), (65310u16,67u16),(65311u16,8u16),(65312u16,86u16),(65313u16,220u16), (65314u16,221u16),(65315u16,222u16),(65316u16,223u16),(65317u16,224u16), (65318u16,225u16),(65319u16,226u16),(65320u16,227u16),(65321u16,228u16), (65322u16,229u16),(65323u16,230u16),(65324u16,231u16),(65325u16,232u16), (65326u16,233u16),(65327u16,234u16),(65328u16,235u16),(65329u16,236u16), (65330u16,237u16),(65331u16,238u16),(65332u16,239u16),(65333u16,240u16), (65334u16,241u16),(65335u16,242u16),(65336u16,243u16),(65337u16,244u16), (65338u16,245u16),(65339u16,45u16),(65340u16,31u16),(65341u16,46u16), (65342u16,15u16),(65343u16,17u16),(65344u16,13u16),(65345u16,252u16), (65346u16,253u16),(65347u16,254u16),(65348u16,255u16),(65349u16,256u16), (65350u16,257u16),(65351u16,258u16),(65352u16,259u16),(65353u16,260u16), (65354u16,261u16),(65355u16,262u16),(65356u16,263u16),(65357u16,264u16), (65358u16,265u16),(65359u16,266u16),(65360u16,267u16),(65361u16,268u16), (65362u16,269u16),(65363u16,270u16),(65364u16,271u16),(65365u16,272u16), (65366u16,273u16),(65367u16,274u16),(65368u16,275u16),(65369u16,276u16), (65370u16,277u16),(65371u16,47u16),(65372u16,34u16),(65373u16,48u16), (65374u16,32u16),(65504u16,80u16),(65505u16,81u16),(65506u16,137u16), (65507u16,16u16),(65508u16,8645u16),(65509u16,78u16), ] const Jis0212Decode*: array[7211, uint16] = [ uint16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,728,711,184,729,733,175, 731,730,65374,900,901,0,0,0,0,0,0,0,0,161,166,191,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,186,170,169,174,8482,164,8470,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,902, 904,905,906,938,0,908,0,910,939,0,911,0,0,0,0,940,941,942,943,970,912,972,962, 973,971,944,974,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1038,1039,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1106,1107,1108, 1109,1110,1111,1112,1113,1114,1115,1116,1118,1119,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 198,272,0,294,0,306,0,321,319,0,330,216,338,0,358,222,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,230,273,240,295,305,307,312,322,320,329,331,248,339,223,359,254,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,193,192,196,194,258,461,256,260,197,195,262,264,268,199,266,270,201,200,203, 202,282,278,274,280,0,284,286,290,288,292,205,204,207,206,463,304,298,302,296, 308,310,313,317,315,323,327,325,209,211,210,214,212,465,336,332,213,340,344,342, 346,348,352,350,356,354,218,217,220,219,364,467,368,362,370,366,360,471,475,473, 469,372,221,376,374,377,381,379,0,0,0,0,0,0,0,225,224,228,226,259,462,257,261, 229,227,263,265,269,231,267,271,233,232,235,234,283,279,275,281,501,285,287,0, 289,293,237,236,239,238,464,0,299,303,297,309,311,314,318,316,324,328,326,241, 243,242,246,244,466,337,333,245,341,345,343,347,349,353,351,357,355,250,249,252, 251,365,468,369,363,371,367,361,472,476,474,470,373,253,255,375,378,382,380,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19970,19972,19973,19980,19986,19999, 20003,20004,20008,20011,20014,20015,20016,20021,20032,20033,20036,20039,20049, 20058,20060,20067,20072,20073,20084,20085,20089,20095,20109,20118,20119,20125, 20143,20153,20163,20176,20186,20187,20192,20193,20194,20200,20207,20209,20211, 20213,20221,20222,20223,20224,20226,20227,20232,20235,20236,20242,20245,20246, 20247,20249,20270,20273,20320,20275,20277,20279,20281,20283,20286,20288,20290, 20296,20297,20299,20300,20306,20308,20310,20312,20319,20323,20330,20332,20334, 20337,20343,20344,20345,20346,20349,20350,20353,20354,20356,20357,20361,20362, 20364,20366,20368,20370,20371,20372,20375,20377,20378,20382,20383,20402,20407, 20409,20411,20412,20413,20414,20416,20417,20421,20422,20424,20425,20427,20428, 20429,20431,20434,20444,20448,20450,20464,20466,20476,20477,20479,20480,20481, 20484,20487,20490,20492,20494,20496,20499,20503,20504,20507,20508,20509,20510, 20514,20519,20526,20528,20530,20531,20533,20544,20545,20546,20549,20550,20554, 20556,20558,20561,20562,20563,20567,20569,20575,20576,20578,20579,20582,20583, 20586,20589,20592,20593,20539,20609,20611,20612,20614,20618,20622,20623,20624, 20626,20627,20628,20630,20635,20636,20638,20639,20640,20641,20642,20650,20655, 20656,20665,20666,20669,20672,20675,20676,20679,20684,20686,20688,20691,20692, 20696,20700,20701,20703,20706,20708,20710,20712,20713,20719,20721,20726,20730, 20734,20739,20742,20743,20744,20747,20748,20749,20750,20722,20752,20759,20761, 20763,20764,20765,20766,20771,20775,20776,20780,20781,20783,20785,20787,20788, 20789,20792,20793,20802,20810,20815,20819,20821,20823,20824,20831,20836,20838, 20862,20867,20868,20875,20878,20888,20893,20897,20899,20909,20920,20922,20924, 20926,20927,20930,20936,20943,20945,20946,20947,20949,20952,20958,20962,20965, 20974,20978,20979,20980,20983,20993,20994,20997,21010,21011,21013,21014,21016, 21026,21032,21041,21042,21045,21052,21061,21065,21077,21079,21080,21082,21084, 21087,21088,21089,21094,21102,21111,21112,21113,21120,21122,21125,21130,21132, 21139,21141,21142,21143,21144,21146,21148,21156,21157,21158,21159,21167,21168, 21174,21175,21176,21178,21179,21181,21184,21188,21190,21192,21196,21199,21201, 21204,21206,21211,21212,21217,21221,21224,21225,21226,21228,21232,21233,21236, 21238,21239,21248,21251,21258,21259,21260,21265,21267,21272,21275,21276,21278, 21279,21285,21287,21288,21289,21291,21292,21293,21296,21298,21301,21308,21309, 21310,21314,21324,21323,21337,21339,21345,21347,21349,21356,21357,21362,21369, 21374,21379,21383,21384,21390,21395,21396,21401,21405,21409,21412,21418,21419, 21423,21426,21428,21429,21431,21432,21434,21437,21440,21445,21455,21458,21459, 21461,21466,21469,21470,21472,21478,21479,21493,21506,21523,21530,21537,21543, 21544,21546,21551,21553,21556,21557,21571,21572,21575,21581,21583,21598,21602, 21604,21606,21607,21609,21611,21613,21614,21620,21631,21633,21635,21637,21640, 21641,21645,21649,21653,21654,21660,21663,21665,21670,21671,21673,21674,21677, 21678,21681,21687,21689,21690,21691,21695,21702,21706,21709,21710,21728,21738, 21740,21743,21750,21756,21758,21759,21760,21761,21765,21768,21769,21772,21773, 21774,21781,21802,21803,21810,21813,21814,21819,21820,21821,21825,21831,21833, 21834,21837,21840,21841,21848,21850,21851,21854,21856,21857,21860,21862,21887, 21889,21890,21894,21896,21902,21903,21905,21906,21907,21908,21911,21923,21924, 21933,21938,21951,21953,21955,21958,21961,21963,21964,21966,21969,21970,21971, 21975,21976,21979,21982,21986,21993,22006,22015,22021,22024,22026,22029,22030, 22031,22032,22033,22034,22041,22060,22064,22067,22069,22071,22073,22075,22076, 22077,22079,22080,22081,22083,22084,22086,22089,22091,22093,22095,22100,22110, 22112,22113,22114,22115,22118,22121,22125,22127,22129,22130,22133,22148,22149, 22152,22155,22156,22165,22169,22170,22173,22174,22175,22182,22183,22184,22185, 22187,22188,22189,22193,22195,22199,22206,22213,22217,22218,22219,22223,22224, 22220,22221,22233,22236,22237,22239,22241,22244,22245,22246,22247,22248,22257, 22251,22253,22262,22263,22273,22274,22279,22282,22284,22289,22293,22298,22299, 22301,22304,22306,22307,22308,22309,22313,22314,22316,22318,22319,22323,22324, 22333,22334,22335,22341,22342,22348,22349,22354,22370,22373,22375,22376,22379, 22381,22382,22383,22384,22385,22387,22388,22389,22391,22393,22394,22395,22396, 22398,22401,22403,22412,22420,22423,22425,22426,22428,22429,22430,22431,22433, 22421,22439,22440,22441,22444,22456,22461,22471,22472,22476,22479,22485,22493, 22494,22500,22502,22503,22505,22509,22512,22517,22518,22520,22525,22526,22527, 22531,22532,22536,22537,22497,22540,22541,22555,22558,22559,22560,22566,22567, 22573,22578,22585,22591,22601,22604,22605,22607,22608,22613,22623,22625,22628, 22631,22632,22648,22652,22655,22656,22657,22663,22664,22665,22666,22668,22669, 22671,22672,22676,22678,22685,22688,22689,22690,22694,22697,22705,22706,22724, 22716,22722,22728,22733,22734,22736,22738,22740,22742,22746,22749,22753,22754, 22761,22771,22789,22790,22795,22796,22802,22803,22804,34369,22813,22817,22819, 22820,22824,22831,22832,22835,22837,22838,22847,22851,22854,22866,22867,22873, 22875,22877,22878,22879,22881,22883,22891,22893,22895,22898,22901,22902,22905, 22907,22908,22923,22924,22926,22930,22933,22935,22943,22948,22951,22957,22958, 22959,22960,22963,22967,22970,22972,22977,22979,22980,22984,22986,22989,22994, 23005,23006,23007,23011,23012,23015,23022,23023,23025,23026,23028,23031,23040, 23044,23052,23053,23054,23058,23059,23070,23075,23076,23079,23080,23082,23085, 23088,23108,23109,23111,23112,23116,23120,23125,23134,23139,23141,23143,23149, 23159,23162,23163,23166,23179,23184,23187,23190,23193,23196,23198,23199,23200, 23202,23207,23212,23217,23218,23219,23221,23224,23226,23227,23231,23236,23238, 23240,23247,23258,23260,23264,23269,23274,23278,23285,23286,23293,23296,23297, 23304,23319,23348,23321,23323,23325,23329,23333,23341,23352,23361,23371,23372, 23378,23382,23390,23400,23406,23407,23420,23421,23422,23423,23425,23428,23430, 23434,23438,23440,23441,23443,23444,23446,23464,23465,23468,23469,23471,23473, 23474,23479,23482,23484,23488,23489,23501,23503,23510,23511,23512,23513,23514, 23520,23535,23537,23540,23549,23564,23575,23582,23583,23587,23590,23593,23595, 23596,23598,23600,23602,23605,23606,23641,23642,23644,23650,23651,23655,23656, 23657,23661,23664,23668,23669,23674,23675,23676,23677,23687,23688,23690,23695, 23698,23709,23711,23712,23714,23715,23718,23722,23730,23732,23733,23738,23753, 23755,23762,23773,23767,23790,23793,23794,23796,23809,23814,23821,23826,23851, 23843,23844,23846,23847,23857,23860,23865,23869,23871,23874,23875,23878,23880, 23893,23889,23897,23882,23903,23904,23905,23906,23908,23914,23917,23920,23929, 23930,23934,23935,23937,23939,23944,23946,23954,23955,23956,23957,23961,23963, 23967,23968,23975,23979,23984,23988,23992,23993,24003,24007,24011,24016,24014, 24024,24025,24032,24036,24041,24056,24057,24064,24071,24077,24082,24084,24085, 24088,24095,24096,24110,24104,24114,24117,24126,24139,24144,24137,24145,24150, 24152,24155,24156,24158,24168,24170,24171,24172,24173,24174,24176,24192,24203, 24206,24226,24228,24229,24232,24234,24236,24241,24243,24253,24254,24255,24262, 24268,24267,24270,24273,24274,24276,24277,24284,24286,24293,24299,24322,24326, 24327,24328,24334,24345,24348,24349,24353,24354,24355,24356,24360,24363,24364, 24366,24368,24372,24374,24379,24381,24383,24384,24388,24389,24391,24397,24400, 24404,24408,24411,24416,24419,24420,24423,24431,24434,24436,24437,24440,24442, 24445,24446,24457,24461,24463,24470,24476,24477,24482,24487,24491,24484,24492, 24495,24496,24497,24504,24516,24519,24520,24521,24523,24528,24529,24530,24531, 24532,24542,24545,24546,24552,24553,24554,24556,24557,24558,24559,24562,24563, 24566,24570,24572,24583,24586,24589,24595,24596,24599,24600,24602,24607,24612, 24621,24627,24629,24640,24647,24648,24649,24652,24657,24660,24662,24663,24669, 24673,24679,24689,24702,24703,24706,24710,24712,24714,24718,24721,24723,24725, 24728,24733,24734,24738,24740,24741,24744,24752,24753,24759,24763,24766,24770, 24772,24776,24777,24778,24779,24782,24783,24788,24789,24793,24795,24797,24798, 24802,24805,24818,24821,24824,24828,24829,24834,24839,24842,24844,24848,24849, 24850,24851,24852,24854,24855,24857,24860,24862,24866,24874,24875,24880,24881, 24885,24886,24887,24889,24897,24901,24902,24905,24926,24928,24940,24946,24952, 24955,24956,24959,24960,24961,24963,24964,24971,24973,24978,24979,24983,24984, 24988,24989,24991,24992,24997,25000,25002,25005,25016,25017,25020,25024,25025, 25026,25038,25039,25045,25052,25053,25054,25055,25057,25058,25063,25065,25061, 25068,25069,25071,25089,25091,25092,25095,25107,25109,25116,25120,25122,25123, 25127,25129,25131,25145,25149,25154,25155,25156,25158,25164,25168,25169,25170, 25172,25174,25178,25180,25188,25197,25199,25203,25210,25213,25229,25230,25231, 25232,25254,25256,25267,25270,25271,25274,25278,25279,25284,25294,25301,25302, 25306,25322,25330,25332,25340,25341,25347,25348,25354,25355,25357,25360,25363, 25366,25368,25385,25386,25389,25397,25398,25401,25404,25409,25410,25411,25412, 25414,25418,25419,25422,25426,25427,25428,25432,25435,25445,25446,25452,25453, 25457,25460,25461,25464,25468,25469,25471,25474,25476,25479,25482,25488,25492, 25493,25497,25498,25502,25508,25510,25517,25518,25519,25533,25537,25541,25544, 25550,25553,25555,25556,25557,25564,25568,25573,25578,25580,25586,25587,25589, 25592,25593,25609,25610,25616,25618,25620,25624,25630,25632,25634,25636,25637, 25641,25642,25647,25648,25653,25661,25663,25675,25679,25681,25682,25683,25684, 25690,25691,25692,25693,25695,25696,25697,25699,25709,25715,25716,25723,25725, 25733,25735,25743,25744,25745,25752,25753,25755,25757,25759,25761,25763,25766, 25768,25772,25779,25789,25790,25791,25796,25801,25802,25803,25804,25806,25808, 25809,25813,25815,25828,25829,25833,25834,25837,25840,25845,25847,25851,25855, 25857,25860,25864,25865,25866,25871,25875,25876,25878,25881,25883,25886,25887, 25890,25894,25897,25902,25905,25914,25916,25917,25923,25927,25929,25936,25938, 25940,25951,25952,25959,25963,25978,25981,25985,25989,25994,26002,26005,26008, 26013,26016,26019,26022,26030,26034,26035,26036,26047,26050,26056,26057,26062, 26064,26068,26070,26072,26079,26096,26098,26100,26101,26105,26110,26111,26112, 26116,26120,26121,26125,26129,26130,26133,26134,26141,26142,26145,26146,26147, 26148,26150,26153,26154,26155,26156,26158,26160,26161,26163,26169,26167,26176, 26181,26182,26186,26188,26193,26190,26199,26200,26201,26203,26204,26208,26209, 26363,26218,26219,26220,26238,26227,26229,26239,26231,26232,26233,26235,26240, 26236,26251,26252,26253,26256,26258,26265,26266,26267,26268,26271,26272,26276, 26285,26289,26290,26293,26299,26303,26304,26306,26307,26312,26316,26318,26319, 26324,26331,26335,26344,26347,26348,26350,26362,26373,26375,26382,26387,26393, 26396,26400,26402,26419,26430,26437,26439,26440,26444,26452,26453,26461,26470, 26476,26478,26484,26486,26491,26497,26500,26510,26511,26513,26515,26518,26520, 26521,26523,26544,26545,26546,26549,26555,26556,26557,26617,26560,26562,26563, 26565,26568,26569,26578,26583,26585,26588,26593,26598,26608,26610,26614,26615, 26706,26644,26649,26653,26655,26664,26663,26668,26669,26671,26672,26673,26675, 26683,26687,26692,26693,26698,26700,26709,26711,26712,26715,26731,26734,26735, 26736,26737,26738,26741,26745,26746,26747,26748,26754,26756,26758,26760,26774, 26776,26778,26780,26785,26787,26789,26793,26794,26798,26802,26811,26821,26824, 26828,26831,26832,26833,26835,26838,26841,26844,26845,26853,26856,26858,26859, 26860,26861,26864,26865,26869,26870,26875,26876,26877,26886,26889,26890,26896, 26897,26899,26902,26903,26929,26931,26933,26936,26939,26946,26949,26953,26958, 26967,26971,26979,26980,26981,26982,26984,26985,26988,26992,26993,26994,27002, 27003,27007,27008,27021,27026,27030,27032,27041,27045,27046,27048,27051,27053, 27055,27063,27064,27066,27068,27077,27080,27089,27094,27095,27106,27109,27118, 27119,27121,27123,27125,27134,27136,27137,27139,27151,27153,27157,27162,27165, 27168,27172,27176,27184,27186,27188,27191,27195,27198,27199,27205,27206,27209, 27210,27214,27216,27217,27218,27221,27222,27227,27236,27239,27242,27249,27251, 27262,27265,27267,27270,27271,27273,27275,27281,27291,27293,27294,27295,27301, 27307,27311,27312,27313,27316,27325,27326,27327,27334,27337,27336,27340,27344, 27348,27349,27350,27356,27357,27364,27367,27372,27376,27377,27378,27388,27389, 27394,27395,27398,27399,27401,27407,27408,27409,27415,27419,27422,27428,27432, 27435,27436,27439,27445,27446,27451,27455,27462,27466,27469,27474,27478,27480, 27485,27488,27495,27499,27502,27504,27509,27517,27518,27522,27525,27543,27547, 27551,27552,27554,27555,27560,27561,27564,27565,27566,27568,27576,27577,27581, 27582,27587,27588,27593,27596,27606,27610,27617,27619,27622,27623,27630,27633, 27639,27641,27647,27650,27652,27653,27657,27661,27662,27664,27666,27673,27679, 27686,27687,27688,27692,27694,27699,27701,27702,27706,27707,27711,27722,27723, 27725,27727,27730,27732,27737,27739,27740,27755,27757,27759,27764,27766,27768, 27769,27771,27781,27782,27783,27785,27796,27797,27799,27800,27804,27807,27824, 27826,27828,27842,27846,27853,27855,27856,27857,27858,27860,27862,27866,27868, 27872,27879,27881,27883,27884,27886,27890,27892,27908,27911,27914,27918,27919, 27921,27923,27930,27942,27943,27944,27751,27950,27951,27953,27961,27964,27967, 27991,27998,27999,28001,28005,28007,28015,28016,28028,28034,28039,28049,28050, 28052,28054,28055,28056,28074,28076,28084,28087,28089,28093,28095,28100,28104, 28106,28110,28111,28118,28123,28125,28127,28128,28130,28133,28137,28143,28144, 28148,28150,28156,28160,28164,28190,28194,28199,28210,28214,28217,28219,28220, 28228,28229,28232,28233,28235,28239,28241,28242,28243,28244,28247,28252,28253, 28254,28258,28259,28264,28275,28283,28285,28301,28307,28313,28320,28327,28333, 28334,28337,28339,28347,28351,28352,28353,28355,28359,28360,28362,28365,28366, 28367,28395,28397,28398,28409,28411,28413,28420,28424,28426,28428,28429,28438, 28440,28442,28443,28454,28457,28458,28463,28464,28467,28470,28475,28476,28461, 28495,28497,28498,28499,28503,28505,28506,28509,28510,28513,28514,28520,28524, 28541,28542,28547,28551,28552,28555,28556,28557,28560,28562,28563,28564,28566, 28570,28575,28576,28581,28582,28583,28584,28590,28591,28592,28597,28598,28604, 28613,28615,28616,28618,28634,28638,28648,28649,28656,28661,28665,28668,28669, 28672,28677,28678,28679,28685,28695,28704,28707,28719,28724,28727,28729,28732, 28739,28740,28744,28745,28746,28747,28756,28757,28765,28766,28750,28772,28773, 28780,28782,28789,28790,28798,28801,28805,28806,28820,28821,28822,28823,28824, 28827,28836,28843,28848,28849,28852,28855,28874,28881,28883,28884,28885,28886, 28888,28892,28900,28922,28931,28932,28933,28934,28935,28939,28940,28943,28958, 28960,28971,28973,28975,28976,28977,28984,28993,28997,28998,28999,29002,29003, 29008,29010,29015,29018,29020,29022,29024,29032,29049,29056,29061,29063,29068, 29074,29082,29083,29088,29090,29103,29104,29106,29107,29114,29119,29120,29121, 29124,29131,29132,29139,29142,29145,29146,29148,29176,29182,29184,29191,29192, 29193,29203,29207,29210,29213,29215,29220,29227,29231,29236,29240,29241,29249, 29250,29251,29253,29262,29263,29264,29267,29269,29270,29274,29276,29278,29280, 29283,29288,29291,29294,29295,29297,29303,29304,29307,29308,29311,29316,29321, 29325,29326,29331,29339,29352,29357,29358,29361,29364,29374,29377,29383,29385, 29388,29397,29398,29400,29407,29413,29427,29428,29434,29435,29438,29442,29444, 29445,29447,29451,29453,29458,29459,29464,29465,29470,29474,29476,29479,29480, 29484,29489,29490,29493,29498,29499,29501,29507,29517,29520,29522,29526,29528, 29533,29534,29535,29536,29542,29543,29545,29547,29548,29550,29551,29553,29559, 29561,29564,29568,29569,29571,29573,29574,29582,29584,29587,29589,29591,29592, 29596,29598,29599,29600,29602,29605,29606,29610,29611,29613,29621,29623,29625, 29628,29629,29631,29637,29638,29641,29643,29644,29647,29650,29651,29654,29657, 29661,29665,29667,29670,29671,29673,29684,29685,29687,29689,29690,29691,29693, 29695,29696,29697,29700,29703,29706,29713,29722,29723,29732,29734,29736,29737, 29738,29739,29740,29741,29742,29743,29744,29745,29753,29760,29763,29764,29766, 29767,29771,29773,29777,29778,29783,29789,29794,29798,29799,29800,29803,29805, 29806,29809,29810,29824,29825,29829,29830,29831,29833,29839,29840,29841,29842, 29848,29849,29850,29852,29855,29856,29857,29859,29862,29864,29865,29866,29867, 29870,29871,29873,29874,29877,29881,29883,29887,29896,29897,29900,29904,29907, 29912,29914,29915,29918,29919,29924,29928,29930,29931,29935,29940,29946,29947, 29948,29951,29958,29970,29974,29975,29984,29985,29988,29991,29993,29994,29999, 30006,30009,30013,30014,30015,30016,30019,30023,30024,30030,30032,30034,30039, 30046,30047,30049,30063,30065,30073,30074,30075,30076,30077,30078,30081,30085, 30096,30098,30099,30101,30105,30108,30114,30116,30132,30138,30143,30144,30145, 30148,30150,30156,30158,30159,30167,30172,30175,30176,30177,30180,30183,30188, 30190,30191,30193,30201,30208,30210,30211,30212,30215,30216,30218,30220,30223, 30226,30227,30229,30230,30233,30235,30236,30237,30238,30243,30245,30246,30249, 30253,30258,30259,30261,30264,30265,30266,30268,30282,30272,30273,30275,30276, 30277,30281,30283,30293,30297,30303,30308,30309,30317,30318,30319,30321,30324, 30337,30341,30348,30349,30357,30363,30364,30365,30367,30368,30370,30371,30372, 30373,30374,30375,30376,30378,30381,30397,30401,30405,30409,30411,30412,30414, 30420,30425,30432,30438,30440,30444,30448,30449,30454,30457,30460,30464,30470, 30474,30478,30482,30484,30485,30487,30489,30490,30492,30498,30504,30509,30510, 30511,30516,30517,30518,30521,30525,30526,30530,30533,30534,30538,30541,30542, 30543,30546,30550,30551,30556,30558,30559,30560,30562,30564,30567,30570,30572, 30576,30578,30579,30580,30586,30589,30592,30596,30604,30605,30612,30613,30614, 30618,30623,30626,30631,30634,30638,30639,30641,30645,30654,30659,30665,30673, 30674,30677,30681,30686,30687,30688,30692,30694,30698,30700,30704,30705,30708, 30712,30715,30725,30726,30729,30733,30734,30737,30749,30753,30754,30755,30765, 30766,30768,30773,30775,30787,30788,30791,30792,30796,30798,30802,30812,30814, 30816,30817,30819,30820,30824,30826,30830,30842,30846,30858,30863,30868,30872, 30881,30877,30878,30879,30884,30888,30892,30893,30896,30897,30898,30899,30907, 30909,30911,30919,30920,30921,30924,30926,30930,30931,30933,30934,30948,30939, 30943,30944,30945,30950,30954,30962,30963,30976,30966,30967,30970,30971,30975, 30982,30988,30992,31002,31004,31006,31007,31008,31013,31015,31017,31021,31025, 31028,31029,31035,31037,31039,31044,31045,31046,31050,31051,31055,31057,31060, 31064,31067,31068,31079,31081,31083,31090,31097,31099,31100,31102,31115,31116, 31121,31123,31124,31125,31126,31128,31131,31132,31137,31144,31145,31147,31151, 31153,31156,31160,31163,31170,31172,31175,31176,31178,31183,31188,31190,31194, 31197,31198,31200,31202,31205,31210,31211,31213,31217,31224,31228,31234,31235, 31239,31241,31242,31244,31249,31253,31259,31262,31265,31271,31275,31277,31279, 31280,31284,31285,31288,31289,31290,31300,31301,31303,31304,31308,31317,31318, 31321,31324,31325,31327,31328,31333,31335,31338,31341,31349,31352,31358,31360, 31362,31365,31366,31370,31371,31376,31377,31380,31390,31392,31395,31404,31411, 31413,31417,31419,31420,31430,31433,31436,31438,31441,31451,31464,31465,31467, 31468,31473,31476,31483,31485,31486,31495,31508,31519,31523,31527,31529,31530, 31531,31533,31534,31535,31536,31537,31540,31549,31551,31552,31553,31559,31566, 31573,31584,31588,31590,31593,31594,31597,31599,31602,31603,31607,31620,31625, 31630,31632,31633,31638,31643,31646,31648,31653,31660,31663,31664,31666,31669, 31670,31674,31675,31676,31677,31682,31685,31688,31690,31700,31702,31703,31705, 31706,31707,31720,31722,31730,31732,31733,31736,31737,31738,31740,31742,31745, 31746,31747,31748,31750,31753,31755,31756,31758,31759,31769,31771,31776,31781, 31782,31784,31788,31793,31795,31796,31798,31801,31802,31814,31818,31829,31825, 31826,31827,31833,31834,31835,31836,31837,31838,31841,31843,31847,31849,31853, 31854,31856,31858,31865,31868,31869,31878,31879,31887,31892,31902,31904,31910, 31920,31926,31927,31930,31931,31932,31935,31940,31943,31944,31945,31949,31951, 31955,31956,31957,31959,31961,31962,31965,31974,31977,31979,31989,32003,32007, 32008,32009,32015,32017,32018,32019,32022,32029,32030,32035,32038,32042,32045, 32049,32060,32061,32062,32064,32065,32071,32072,32077,32081,32083,32087,32089, 32090,32092,32093,32101,32103,32106,32112,32120,32122,32123,32127,32129,32130, 32131,32133,32134,32136,32139,32140,32141,32145,32150,32151,32157,32158,32166, 32167,32170,32179,32182,32183,32185,32194,32195,32196,32197,32198,32204,32205, 32206,32215,32217,32256,32226,32229,32230,32234,32235,32237,32241,32245,32246, 32249,32250,32264,32272,32273,32277,32279,32284,32285,32288,32295,32296,32300, 32301,32303,32307,32310,32319,32324,32325,32327,32334,32336,32338,32344,32351, 32353,32354,32357,32363,32366,32367,32371,32376,32382,32385,32390,32391,32394, 32397,32401,32405,32408,32410,32413,32414,32572,32571,32573,32574,32575,32579, 32580,32583,32591,32594,32595,32603,32604,32605,32609,32611,32612,32613,32614, 32621,32625,32637,32638,32639,32640,32651,32653,32655,32656,32657,32662,32663, 32668,32673,32674,32678,32682,32685,32692,32700,32703,32704,32707,32712,32718, 32719,32731,32735,32739,32741,32744,32748,32750,32751,32754,32762,32765,32766, 32767,32775,32776,32778,32781,32782,32783,32785,32787,32788,32790,32797,32798, 32799,32800,32804,32806,32812,32814,32816,32820,32821,32823,32825,32826,32828, 32830,32832,32836,32864,32868,32870,32877,32881,32885,32897,32904,32910,32924, 32926,32934,32935,32939,32952,32953,32968,32973,32975,32978,32980,32981,32983, 32984,32992,33005,33006,33008,33010,33011,33014,33017,33018,33022,33027,33035, 33046,33047,33048,33052,33054,33056,33060,33063,33068,33072,33077,33082,33084, 33093,33095,33098,33100,33106,33111,33120,33121,33127,33128,33129,33133,33135, 33143,33153,33168,33156,33157,33158,33163,33166,33174,33176,33179,33182,33186, 33198,33202,33204,33211,33227,33219,33221,33226,33230,33231,33237,33239,33243, 33245,33246,33249,33252,33259,33260,33264,33265,33266,33269,33270,33272,33273, 33277,33279,33280,33283,33295,33299,33300,33305,33306,33309,33313,33314,33320, 33330,33332,33338,33347,33348,33349,33350,33355,33358,33359,33361,33366,33372, 33376,33379,33383,33389,33396,33403,33405,33407,33408,33409,33411,33412,33415, 33417,33418,33422,33425,33428,33430,33432,33434,33435,33440,33441,33443,33444, 33447,33448,33449,33450,33454,33456,33458,33460,33463,33466,33468,33470,33471, 33478,33488,33493,33498,33504,33506,33508,33512,33514,33517,33519,33526,33527, 33533,33534,33536,33537,33543,33544,33546,33547,33620,33563,33565,33566,33567, 33569,33570,33580,33581,33582,33584,33587,33591,33594,33596,33597,33602,33603, 33604,33607,33613,33614,33617,33621,33622,33623,33648,33656,33661,33663,33664, 33666,33668,33670,33677,33682,33684,33685,33688,33689,33691,33692,33693,33702, 33703,33705,33708,33726,33727,33728,33735,33737,33743,33744,33745,33748,33757, 33619,33768,33770,33782,33784,33785,33788,33793,33798,33802,33807,33809,33813, 33817,33709,33839,33849,33861,33863,33864,33866,33869,33871,33873,33874,33878, 33880,33881,33882,33884,33888,33892,33893,33895,33898,33904,33907,33908,33910, 33912,33916,33917,33921,33925,33938,33939,33941,33950,33958,33960,33961,33962, 33967,33969,33972,33978,33981,33982,33984,33986,33991,33992,33996,33999,34003, 34012,34023,34026,34031,34032,34033,34034,34039,34098,34042,34043,34045,34050, 34051,34055,34060,34062,34064,34076,34078,34082,34083,34084,34085,34087,34090, 34091,34095,34099,34100,34102,34111,34118,34127,34128,34129,34130,34131,34134, 34137,34140,34141,34142,34143,34144,34145,34146,34148,34155,34159,34169,34170, 34171,34173,34175,34177,34181,34182,34185,34187,34188,34191,34195,34200,34205, 34207,34208,34210,34213,34215,34228,34230,34231,34232,34236,34237,34238,34239, 34242,34247,34250,34251,34254,34221,34264,34266,34271,34272,34278,34280,34285, 34291,34294,34300,34303,34304,34308,34309,34317,34318,34320,34321,34322,34328, 34329,34331,34334,34337,34343,34345,34358,34360,34362,34364,34365,34368,34370, 34374,34386,34387,34390,34391,34392,34393,34397,34400,34401,34402,34403,34404, 34409,34412,34415,34421,34422,34423,34426,34445,34449,34454,34456,34458,34460, 34465,34470,34471,34472,34477,34481,34483,34484,34485,34487,34488,34489,34495, 34496,34497,34499,34501,34513,34514,34517,34519,34522,34524,34528,34531,34533, 34535,34440,34554,34556,34557,34564,34565,34567,34571,34574,34575,34576,34579, 34580,34585,34590,34591,34593,34595,34600,34606,34607,34609,34610,34617,34618, 34620,34621,34622,34624,34627,34629,34637,34648,34653,34657,34660,34661,34671, 34673,34674,34683,34691,34692,34693,34694,34695,34696,34697,34699,34700,34704, 34707,34709,34711,34712,34713,34718,34720,34723,34727,34732,34733,34734,34737, 34741,34750,34751,34753,34760,34761,34762,34766,34773,34774,34777,34778,34780, 34783,34786,34787,34788,34794,34795,34797,34801,34803,34808,34810,34815,34817, 34819,34822,34825,34826,34827,34832,34841,34834,34835,34836,34840,34842,34843, 34844,34846,34847,34856,34861,34862,34864,34866,34869,34874,34876,34881,34883, 34885,34888,34889,34890,34891,34894,34897,34901,34902,34904,34906,34908,34911, 34912,34916,34921,34929,34937,34939,34944,34968,34970,34971,34972,34975,34976, 34984,34986,35002,35005,35006,35008,35018,35019,35020,35021,35022,35025,35026, 35027,35035,35038,35047,35055,35056,35057,35061,35063,35073,35078,35085,35086, 35087,35093,35094,35096,35097,35098,35100,35104,35110,35111,35112,35120,35121, 35122,35125,35129,35130,35134,35136,35138,35141,35142,35145,35151,35154,35159, 35162,35163,35164,35169,35170,35171,35179,35182,35184,35187,35189,35194,35195, 35196,35197,35209,35213,35216,35220,35221,35227,35228,35231,35232,35237,35248, 35252,35253,35254,35255,35260,35284,35285,35286,35287,35288,35301,35305,35307, 35309,35313,35315,35318,35321,35325,35327,35332,35333,35335,35343,35345,35346, 35348,35349,35358,35360,35362,35364,35366,35371,35372,35375,35381,35383,35389, 35390,35392,35395,35397,35399,35401,35405,35406,35411,35414,35415,35416,35420, 35421,35425,35429,35431,35445,35446,35447,35449,35450,35451,35454,35455,35456, 35459,35462,35467,35471,35472,35474,35478,35479,35481,35487,35495,35497,35502, 35503,35507,35510,35511,35515,35518,35523,35526,35528,35529,35530,35537,35539, 35540,35541,35543,35549,35551,35564,35568,35572,35573,35574,35580,35583,35589, 35590,35595,35601,35612,35614,35615,35594,35629,35632,35639,35644,35650,35651, 35652,35653,35654,35656,35666,35667,35668,35673,35661,35678,35683,35693,35702, 35704,35705,35708,35710,35713,35716,35717,35723,35725,35727,35732,35733,35740, 35742,35743,35896,35897,35901,35902,35909,35911,35913,35915,35919,35921,35923, 35924,35927,35928,35931,35933,35929,35939,35940,35942,35944,35945,35949,35955, 35957,35958,35963,35966,35974,35975,35979,35984,35986,35987,35993,35995,35996, 36004,36025,36026,36037,36038,36041,36043,36047,36054,36053,36057,36061,36065, 36072,36076,36079,36080,36082,36085,36087,36088,36094,36095,36097,36099,36105, 36114,36119,36123,36197,36201,36204,36206,36223,36226,36228,36232,36237,36240, 36241,36245,36254,36255,36256,36262,36267,36268,36271,36274,36277,36279,36281, 36283,36288,36293,36294,36295,36296,36298,36302,36305,36308,36309,36311,36313, 36324,36325,36327,36332,36336,36284,36337,36338,36340,36349,36353,36356,36357, 36358,36363,36369,36372,36374,36384,36385,36386,36387,36390,36391,36401,36403, 36406,36407,36408,36409,36413,36416,36417,36427,36429,36430,36431,36436,36443, 36444,36445,36446,36449,36450,36457,36460,36461,36463,36464,36465,36473,36474, 36475,36482,36483,36489,36496,36498,36501,36506,36507,36509,36510,36514,36519, 36521,36525,36526,36531,36533,36538,36539,36544,36545,36547,36548,36551,36559, 36561,36564,36572,36584,36590,36592,36593,36599,36601,36602,36589,36608,36610, 36615,36616,36623,36624,36630,36631,36632,36638,36640,36641,36643,36645,36647, 36648,36652,36653,36654,36660,36661,36662,36663,36666,36672,36673,36675,36679, 36687,36689,36690,36691,36692,36693,36696,36701,36702,36709,36765,36768,36769, 36772,36773,36774,36789,36790,36792,36798,36800,36801,36806,36810,36811,36813, 36816,36818,36819,36821,36832,36835,36836,36840,36846,36849,36853,36854,36859, 36862,36866,36868,36872,36876,36888,36891,36904,36905,36911,36906,36908,36909, 36915,36916,36919,36927,36931,36932,36940,36955,36957,36962,36966,36967,36972, 36976,36980,36985,36997,37000,37003,37004,37006,37008,37013,37015,37016,37017, 37019,37024,37025,37026,37029,37040,37042,37043,37044,37046,37053,37068,37054, 37059,37060,37061,37063,37064,37077,37079,37080,37081,37084,37085,37087,37093, 37074,37110,37099,37103,37104,37108,37118,37119,37120,37124,37125,37126,37128, 37133,37136,37140,37142,37143,37144,37146,37148,37150,37152,37157,37154,37155, 37159,37161,37166,37167,37169,37172,37174,37175,37177,37178,37180,37181,37187, 37191,37192,37199,37203,37207,37209,37210,37211,37217,37220,37223,37229,37236, 37241,37242,37243,37249,37251,37253,37254,37258,37262,37265,37267,37268,37269, 37272,37278,37281,37286,37288,37292,37293,37294,37296,37297,37298,37299,37302, 37307,37308,37309,37311,37314,37315,37317,37331,37332,37335,37337,37338,37342, 37348,37349,37353,37354,37356,37357,37358,37359,37360,37361,37367,37369,37371, 37373,37376,37377,37380,37381,37382,37383,37385,37386,37388,37392,37394,37395, 37398,37400,37404,37405,37411,37412,37413,37414,37416,37422,37423,37424,37427, 37429,37430,37432,37433,37434,37436,37438,37440,37442,37443,37446,37447,37450, 37453,37454,37455,37457,37464,37465,37468,37469,37472,37473,37477,37479,37480, 37481,37486,37487,37488,37493,37494,37495,37496,37497,37499,37500,37501,37503, 37512,37513,37514,37517,37518,37522,37527,37529,37535,37536,37540,37541,37543, 37544,37547,37551,37554,37558,37560,37562,37563,37564,37565,37567,37568,37569, 37570,37571,37573,37574,37575,37576,37579,37580,37581,37582,37584,37587,37589, 37591,37592,37593,37596,37597,37599,37600,37601,37603,37605,37607,37608,37612, 37614,37616,37625,37627,37631,37632,37634,37640,37645,37649,37652,37653,37660, 37661,37662,37663,37665,37668,37669,37671,37673,37674,37683,37684,37686,37687, 37703,37704,37705,37712,37713,37714,37717,37719,37720,37722,37726,37732,37733, 37735,37737,37738,37741,37743,37744,37745,37747,37748,37750,37754,37757,37759, 37760,37761,37762,37768,37770,37771,37773,37775,37778,37781,37784,37787,37790, 37793,37795,37796,37798,37800,37803,37812,37813,37814,37818,37801,37825,37828, 37829,37830,37831,37833,37834,37835,37836,37837,37843,37849,37852,37854,37855, 37858,37862,37863,37881,37879,37880,37882,37883,37885,37889,37890,37892,37896, 37897,37901,37902,37903,37909,37910,37911,37919,37934,37935,37937,37938,37939, 37940,37947,37951,37949,37955,37957,37960,37962,37964,37973,37977,37980,37983, 37985,37987,37992,37995,37997,37998,37999,38001,38002,38020,38019,38264,38265, 38270,38276,38280,38284,38285,38286,38301,38302,38303,38305,38310,38313,38315, 38316,38324,38326,38330,38333,38335,38342,38344,38345,38347,38352,38353,38354, 38355,38361,38362,38365,38366,38367,38368,38372,38374,38429,38430,38434,38436, 38437,38438,38444,38449,38451,38455,38456,38457,38458,38460,38461,38465,38482, 38484,38486,38487,38488,38497,38510,38516,38523,38524,38526,38527,38529,38530, 38531,38532,38537,38545,38550,38554,38557,38559,38564,38565,38566,38569,38574, 38575,38579,38586,38602,38610,23986,38616,38618,38621,38622,38623,38633,38639, 38641,38650,38658,38659,38661,38665,38682,38683,38685,38689,38690,38691,38696, 38705,38707,38721,38723,38730,38734,38735,38741,38743,38744,38746,38747,38755, 38759,38762,38766,38771,38774,38775,38776,38779,38781,38783,38784,38793,38805, 38806,38807,38809,38810,38814,38815,38818,38828,38830,38833,38834,38837,38838, 38840,38841,38842,38844,38846,38847,38849,38852,38853,38855,38857,38858,38860, 38861,38862,38864,38865,38868,38871,38872,38873,38877,38878,38880,38875,38881, 38884,38895,38897,38900,38903,38904,38906,38919,38922,38937,38925,38926,38932, 38934,38940,38942,38944,38947,38950,38955,38958,38959,38960,38962,38963,38965, 38949,38974,38980,38983,38986,38993,38994,38995,38998,38999,39001,39002,39010, 39011,39013,39014,39018,39020,39083,39085,39086,39088,39092,39095,39096,39098, 39099,39103,39106,39109,39112,39116,39137,39139,39141,39142,39143,39146,39155, 39158,39170,39175,39176,39185,39189,39190,39191,39194,39195,39196,39199,39202, 39206,39207,39211,39217,39218,39219,39220,39221,39225,39226,39227,39228,39232, 39233,39238,39239,39240,39245,39246,39252,39256,39257,39259,39260,39262,39263, 39264,39323,39325,39327,39334,39344,39345,39346,39349,39353,39354,39357,39359, 39363,39369,39379,39380,39385,39386,39388,39390,39399,39402,39403,39404,39408, 39412,39413,39417,39421,39422,39426,39427,39428,39435,39436,39440,39441,39446, 39454,39456,39458,39459,39460,39463,39469,39470,39475,39477,39478,39480,39495, 39489,39492,39498,39499,39500,39502,39505,39508,39510,39517,39594,39596,39598, 39599,39602,39604,39605,39606,39609,39611,39614,39615,39617,39619,39622,39624, 39630,39632,39634,39637,39638,39639,39643,39644,39648,39652,39653,39655,39657, 39660,39666,39667,39669,39673,39674,39677,39679,39680,39681,39682,39683,39684, 39685,39688,39689,39691,39692,39693,39694,39696,39698,39702,39705,39707,39708, 39712,39718,39723,39725,39731,39732,39733,39735,39737,39738,39741,39752,39755, 39756,39765,39766,39767,39771,39774,39777,39779,39781,39782,39784,39786,39787, 39788,39789,39790,39795,39797,39799,39800,39801,39807,39808,39812,39813,39814, 39815,39817,39818,39819,39821,39823,39824,39828,39834,39837,39838,39846,39847, 39849,39852,39856,39857,39858,39863,39864,39867,39868,39870,39871,39873,39879, 39880,39886,39888,39895,39896,39901,39903,39909,39911,39914,39915,39919,39923, 39927,39928,39929,39930,39933,39935,39936,39938,39947,39951,39953,39958,39960, 39961,39962,39964,39966,39970,39971,39974,39975,39976,39977,39978,39985,39989, 39990,39991,39997,40001,40003,40004,40005,40009,40010,40014,40015,40016,40019, 40020,40022,40024,40027,40029,40030,40031,40035,40041,40042,40028,40043,40040, 40046,40048,40050,40053,40055,40059,40166,40178,40183,40185,40203,40194,40209, 40215,40216,40220,40221,40222,40239,40240,40242,40243,40244,40250,40252,40261, 40253,40258,40259,40263,40266,40275,40276,40287,40291,40290,40293,40297,40298, 40299,40304,40310,40311,40315,40316,40318,40323,40324,40326,40330,40333,40334, 40338,40339,40341,40342,40343,40344,40353,40362,40364,40366,40369,40373,40377, 40380,40383,40387,40391,40393,40394,40404,40405,40406,40407,40410,40414,40415, 40416,40421,40423,40425,40427,40430,40432,40435,40436,40446,40458,40450,40455, 40462,40464,40465,40466,40469,40470,40473,40476,40477,40570,40571,40572,40576, 40578,40579,40580,40581,40583,40590,40591,40598,40600,40603,40606,40612,40616, 40620,40622,40623,40624,40627,40628,40629,40646,40648,40651,40661,40671,40676, 40679,40684,40685,40686,40688,40689,40690,40693,40696,40703,40706,40707,40713, 40719,40720,40721,40722,40724,40726,40727,40729,40730,40731,40735,40738,40742, 40746,40747,40751,40753,40754,40756,40759,40761,40762,40764,40765,40767,40769, 40771,40772,40773,40774,40775,40787,40789,40790,40791,40792,40794,40797,40798, 40808,40809,40813,40814,40815,40816,40817,40819,40821,40826,40829,40847,40848, 40849,40850,40852,40854,40855,40862,40865,40866,40867,40869, ] const EucKRRuns*: array[1079, uint32] = [ 67108864u32,67117058u32,167813124u32,33660937u32,67256330u32,100818956u32, 235044879u32,33734678u32,201531415u32,67330077u32,100892703u32,335781922u32, 33800236u32,201580589u32,100925491u32,100933686u32,637812793u32,67403852u32, 67412046u32,33874000u32,168099921u32,33898582u32,67485783u32,101072985u32, 101081180u32,235307103u32,33996902u32,201793639u32,34046061u32,67608686u32, 235397232u32,34087031u32,101220472u32,67674235u32,101236861u32,101245056u32, 269025411u32,34152587u32,269041804u32,67731604u32,67739798u32,34201752u32, 34209945u32,67772570u32,34242716u32,34250909u32,168485022u32,67838115u32, 101400741u32,34300072u32,168525993u32,34324654u32,34332847u32,202113200u32, 101458102u32,101466297u32,269246652u32,67928260u32,202162374u32,67961036u32, 101523662u32,235749585u32,34439384u32,34447577u32,202227930u32,101572832u32, 101581027u32,269361382u32,34488558u32,269377775u32,68067575u32,68075769u32, 135217403u32,34578687u32,34586880u32,168820993u32,68174086u32,101736712u32, 370180363u32,202424598u32,605085980u32,269549870u32,68239670u32,101802296u32, 236028219u32,34718018u32,269607235u32,101843275u32,101851470u32,638730577u32, 68321636u32,68329830u32,202572136u32,34816366u32,34824559u32,202604912u32, 907256182u32,68411793u32,68419987u32,34881941u32,169107862u32,34906523u32, 34914716u32,102039965u32,34939296u32,34963873u32,102080930u32,34980261u32, 169206182u32,35004843u32,102138284u32,68592047u32,68608433u32,102171059u32, 236396982u32,35086781u32,202883518u32,202899908u32,1578639818u32,35160569u32, 102277626u32,236503549u32,35193348u32,202990085u32,68788747u32,370786829u32, 68805144u32,35258906u32,203039259u32,102384161u32,102392356u32,337281575u32, 135971377u32,68870709u32,907739703u32,68895314u32,35349076u32,35357269u32, 236692054u32,35381853u32,35390046u32,136077919u32,203203171u32,370983529u32, 203227764u32,639451770u32,203252365u32,102597267u32,102605462u32,236831385u32, 102630048u32,203301539u32,907952809u32,69108420u32,102671046u32,203342537u32, 35594959u32,35603152u32,169837265u32,236954326u32,371180253u32,203424488u32, 69223150u32,102785776u32,237011699u32,69255930u32,237036284u32,102826755u32, 102834950u32,237060873u32,337740560u32,908174106u32,69329717u32,35783479u32, 35791672u32,35799865u32,136471354u32,35832638u32,35840831u32,102957888u32, 1008935747u32,69428065u32,102990691u32,237216614u32,35906413u32,35914606u32, 203694959u32,35947381u32,69510006u32,170206072u32,36004733u32,36045694u32, 36053887u32,69632896u32,103195522u32,237421445u32,36111244u32,203907981u32, 69706643u32,103269269u32,237495192u32,136840095u32,1143481251u32,36201413u32, 103326662u32,36225993u32,136905674u32,36258766u32,170501071u32,69862356u32, 103424982u32,237650905u32,36340704u32,204137441u32,69936103u32,103498729u32, 237724652u32,69968883u32,69985269u32,103547895u32,103556090u32,774652925u32, 70026260u32,103588886u32,36488217u32,170714138u32,36512799u32,36520992u32, 137192481u32,103662629u32,103670824u32,372114475u32,1177429046u32,103695449u32, 103703644u32,237929567u32,36619366u32,271508583u32,70198383u32,103761009u32, 271541364u32,36668540u32,36676733u32,204457086u32,70255748u32,70263942u32, 238052488u32,36742287u32,36750480u32,204530833u32,640746647u32,238101674u32, 909198513u32,103900364u32,103908559u32,238134482u32,338814169u32,204612835u32, 238175465u32,103974128u32,204645619u32,70444281u32,104006907u32,171140350u32, 36939011u32,36947204u32,104072453u32,36971784u32,104088841u32,104097036u32, 640976143u32,70567202u32,104129828u32,37029159u32,171255080u32,37053741u32, 37061934u32,137733423u32,37078323u32,37102900u32,70665525u32,104260919u32, 37176634u32,104326459u32,70796606u32,104359232u32,238585155u32,37274954u32, 205071691u32,1849247057u32,37332360u32,70894985u32,37356939u32,138036620u32, 37389712u32,37397905u32,37406098u32,70968723u32,37422485u32,70993302u32, 104555928u32,238781851u32,37471650u32,205268387u32,104613289u32,104621484u32, 373065135u32,205309370u32,104654272u32,775751107u32,71124442u32,71132636u32, 37594590u32,37602783u32,104719840u32,37627363u32,37635556u32,37643749u32, 37651942u32,71214567u32,104777193u32,104785388u32,641664495u32,641672706u32, 239027733u32,104818204u32,104826399u32,239052322u32,37742121u32,272631338u32, 910173746u32,71329357u32,104891983u32,239117906u32,37807705u32,37815898u32, 205596251u32,641812065u32,239167092u32,675382907u32,205629071u32,104973973u32, 104982168u32,272762523u32,37889699u32,37897892u32,205678245u32,105023147u32, 105031342u32,239257265u32,138602168u32,205719228u32,71517890u32,71526084u32, 37988038u32,172213959u32,38012620u32,38020813u32,205801166u32,910452436u32, 71608047u32,71616241u32,239404787u32,38094586u32,172345083u32,71698176u32, 105260802u32,239486725u32,38176524u32,172418829u32,71780114u32,105342740u32, 239568663u32,38258462u32,2085103391u32,71853917u32,105416543u32,38315874u32, 138995555u32,38348647u32,172590952u32,71952237u32,105514863u32,239740786u32, 38430585u32,206227322u32,642443136u32,1179322259u32,72042422u32,105605048u32, 407603131u32,206284743u32,239847373u32,642508756u32,910952423u32,105654274u32, 1716275205u32,72124472u32,105687098u32,206358589u32,139266115u32,1145907271u32, 911034473u32,105736324u32,105744519u32,239970442u32,105769105u32,1145964692u32, 72239286u32,72247480u32,240036026u32,38725825u32,273615042u32,105851082u32, 105859277u32,240085200u32,340764887u32,105892065u32,105900260u32,240126183u32, 38815982u32,38824175u32,206604528u32,72403190u32,105965816u32,240191739u32, 38881538u32,106023171u32,72501510u32,106064136u32,240290059u32,38979858u32, 206776595u32,72575257u32,475236635u32,39037225u32,1146341674u32,72616268u32, 106178894u32,240404817u32,39094616u32,173336921u32,72698206u32,106260832u32, 240486755u32,39176554u32,39184747u32,206965100u32,72763762u32,106326388u32, 240552311u32,39242110u32,207038847u32,106383749u32,408381832u32,39291284u32, 274180501u32,72870301u32,106432927u32,240658850u32,39348649u32,39356842u32, 207137195u32,106482097u32,542697908u32,878250436u32,240724446u32,106514917u32, 106523112u32,240749035u32,39438834u32,39447027u32,207227380u32,106572282u32, 106580477u32,274360832u32,39488008u32,39496201u32,207276554u32,73075216u32, 106637842u32,240863765u32,39553564u32,39561757u32,207342110u32,643557924u32, 240912951u32,912009790u32,73165401u32,106728027u32,240953950u32,73189989u32, 39643751u32,207424104u32,73222766u32,106785392u32,241011315u32,39701114u32, 39709307u32,207489660u32,73288322u32,106850948u32,241076871u32,39766670u32, 39774863u32,73345680u32,979331730u32,73378479u32,106941105u32,241167028u32, 39856827u32,39865020u32,207645373u32,73444035u32,39897797u32,174156486u32, 39955147u32,39963340u32,73534157u32,39987919u32,73566928u32,107129554u32, 241355477u32,40045276u32,174295773u32,207866594u32,409201384u32,1147407092u32, 73681686u32,107244312u32,40143643u32,174369564u32,40168225u32,40176418u32, 140856099u32,73771815u32,107334441u32,241560364u32,40250163u32,208046900u32, 73845562u32,107408188u32,342297407u32,40332105u32,141003594u32,912763726u32, 40364905u32,107490154u32,40389485u32,174615406u32,40414067u32,40422260u32, 208202613u32,107547515u32,510208894u32,1147759501u32,107580335u32,107588530u32, 275368885u32,40496061u32,40504254u32,208284607u32,107629509u32,107637704u32, 275418059u32,40545235u32,275434452u32,40578012u32,74140637u32,174836703u32, 40635364u32,40643557u32,107760614u32,40659945u32,107785194u32,107793389u32, 275573744u32,40700920u32,275590137u32,913132545u32,107834396u32,107842591u32, 644721698u32,107858997u32,107867192u32,242093115u32,74329154u32,275663940u32, 107899980u32,107908175u32,242134098u32,74370137u32,1215229019u32,74394751u32, 74402945u32,40864899u32,175090820u32,40889481u32,40914058u32,40922251u32, 74484876u32,74525838u32,141675664u32,41028756u32,41036949u32,108154006u32, 74607769u32,74624155u32,108186781u32,242412704u32,41102503u32,108235944u32, 74689707u32,74706093u32,410258607u32,1282682043u32,74738913u32,74747107u32, 41209061u32,175434982u32,41233643u32,41241836u32,175475949u32,74829042u32, 74837236u32,242625782u32,41315581u32,209112318u32,74910980u32,108473606u32, 276253961u32,41381137u32,108514578u32,74968341u32,108530967u32,779627802u32, 41454897u32,108571954u32,242797877u32,41487676u32,41495869u32,209276222u32, 108621124u32,511282503u32,242855254u32,645516637u32,242871664u32,75115895u32, 108678521u32,242904444u32,343584131u32,108711309u32,779808144u32,75181479u32, 75189673u32,175885739u32,41684400u32,41692593u32,108809650u32,41717173u32, 243051958u32,377277885u32,243068360u32,914165199u32,75320810u32,108883436u32, 410881519u32,209563131u32,108908033u32,108916228u32,243142151u32,75378190u32, 41831952u32,209612305u32,75410967u32,108973593u32,243199516u32,41889315u32, 1216302628u32,75468360u32,109030986u32,41930317u32,176156238u32,41954899u32, 41963092u32,142650965u32,75558489u32,109121115u32,42020446u32,176246367u32, 42045028u32,176287333u32,75648618u32,109211244u32,243437167u32,42126966u32, 209923703u32,478375549u32,1317244555u32,75746994u32,75755188u32,243543734u32, 75779773u32,210022079u32,679792325u32,210038489u32,478490335u32,42299117u32, 1149619950u32,75894544u32,109457170u32,243683093u32,109481756u32,2089201439u32, 914804573u32,679931768u32,210177932u32,75976594u32,109539220u32,243765143u32, 76001182u32,42454944u32,3028807585u32,680005627u32,210251791u32,109596693u32, 109604888u32,243830811u32,1284034594u32,76091464u32,109654090u32,243880013u32, 42569812u32,42578005u32,210358358u32,42602588u32,76173405u32,176869471u32, 42668132u32,109801573u32,76255336u32,76271722u32,109834348u32,244060271u32, 42750070u32,210546807u32,76345469u32,109908095u32,244134018u32,42823817u32, 42832010u32,210612363u32,109957265u32,109965460u32,244191383u32,143536286u32, 210653346u32,76476584u32,42938538u32,143618219u32,42971311u32,143659184u32, 43004084u32,76574901u32,110137527u32,244363450u32,43053249u32,210849986u32, 76648648u32,110211274u32,244437197u32,43126996u32,210923733u32,110268635u32, 110276830u32,412274913u32,210956525u32,43208947u32,110326004u32,43225335u32, 177451256u32,43249917u32,43258110u32,110375167u32,76828930u32,76845316u32, 110407942u32,412406025u32,211087637u32,110432539u32,110440734u32,244666657u32, 76902696u32,244691242u32,110481713u32,110489908u32,244715831u32,43405630u32, 278294847u32,76984647u32,110547273u32,244773196u32,43462995u32,43471188u32, 211251541u32,77050203u32,77058397u32,244846943u32,43536742u32,43544935u32, 43553128u32,43561321u32,43577706u32,647565675u32,244920702u32,77164933u32, 110727559u32,244953482u32,144298385u32,211415445u32,77214107u32,110776733u32, 245002656u32,43692455u32,43700648u32,211481001u32,211497391u32,245060021u32, 77296060u32,43749822u32,211530175u32,77328837u32,110891463u32,211571146u32, 43815376u32,43823569u32,1151128018u32,77402612u32,77410806u32,211644920u32, 43897342u32,43905535u32,144577024u32,43921924u32,43938309u32,111063558u32, 245289481u32,77533712u32,178213394u32,77574679u32,111137305u32,245363228u32, 77607459u32,916484645u32,1151373888u32,77648482u32,111211108u32,44110439u32, 178336360u32,77689453u32,211923567u32,111268469u32,111276664u32,1721897595u32, 782381742u32,77755077u32,77763271u32,44225225u32,178451146u32,111358671u32, 212030162u32,77828824u32,514044634u32,245617385u32,648278768u32,245633795u32, 111424266u32,111432461u32,245658384u32,346338071u32,916771617u32,77927228u32, 111489854u32,245715777u32,111514440u32,212185931u32,648401745u32,245756772u32, 916853611u32,111555462u32,1487295369u32,212235189u32,78033851u32,111596477u32, 44495808u32,145167297u32,346518469u32,111645647u32,111653842u32,245879765u32, 380105692u32,78132199u32,111694825u32,245920748u32,44610547u32,44618740u32, 212399093u32,78197755u32,44667901u32,145355774u32,44717058u32,111850499u32, 44758022u32,78328839u32,111891465u32,246117388u32,44807187u32,212603924u32, 78402586u32,111965212u32,78418975u32,145536033u32,44889125u32,44897318u32, 112014375u32,44913706u32,112038955u32,112047150u32,279827505u32,346944569u32, 78525507u32,44987461u32,179237958u32,45077579u32,45085772u32,45093965u32, 78664782u32,112227408u32,246453331u32,45143130u32,45151323u32,212931676u32, 45184098u32,112301155u32,45200486u32,145880167u32,112374891u32,112407662u32, 112415857u32,246641780u32,45331579u32,246674556u32,78918787u32,112481413u32, 45397128u32,78959753u32,45429899u32,45438092u32,45446285u32,146117774u32, 79025298u32,112587924u32,246813847u32,45503646u32,213300383u32,79099045u32, 381097127u32,79115442u32,45569204u32,213349557u32,79148219u32,112710845u32, 246936768u32,45626567u32,45634760u32,213415113u32,79213775u32,112776401u32, 247002324u32,45692123u32,45700316u32,213480669u32,79279331u32,112841957u32, 179975400u32,45774061u32,45782254u32,213562607u32,79361269u32,112923895u32, 247149818u32,79394049u32,213628163u32,79426825u32,112989451u32,247215374u32, 113014037u32,213685528u32,79484190u32,113046816u32,247272739u32,45962538u32, 45970731u32,213751084u32,79549746u32,113112372u32,247338295u32,46028094u32, 46036287u32,46044480u32,146715969u32,79623493u32,113186119u32,180303178u32, 46093647u32,46110032u32,46118225u32,113292626u32,113300821u32,247526744u32, 79762783u32,281097569u32,79787369u32,113349995u32,146929006u32,46290290u32, 113431923u32,46331254u32,79902071u32,46355833u32,46380410u32,180606331u32, 46404992u32,180655489u32,80008582u32,113571208u32,247797131u32,46486930u32, 214283667u32,80082329u32,46536091u32,46544284u32,247879069u32,147223972u32, 214341032u32,113685934u32,113694129u32,650573236u32,80164295u32,113726921u32, 46626252u32,180852173u32,46650834u32,46659027u32,180893140u32,80246233u32, 113808859u32,248034782u32,46724581u32,46732774u32,214513127u32,113858029u32, 113866224u32,248092147u32,80336378u32,214570492u32,919221762u32,80377373u32, 113939999u32,46839330u32,181065251u32,46863912u32,46872105u32,114005546u32, 214693421u32,281810483u32,46937659u32,46945852u32,114062909u32, ] const EucKRRunsOffset* = 44034u16 const EucKRRuns2*: array[535, uint32] = [ 100663296u32,637542403u32,201351190u32,100696092u32,100704287u32,234930210u32, 33620009u32,33628202u32,201408555u32,67207217u32,536977459u32,201441347u32, 67240009u32,100802635u32,167936078u32,33734739u32,33742932u32,201523285u32, 637739099u32,235094126u32,906190965u32,67346576u32,100909202u32,235135125u32, 33824924u32,268714141u32,100950181u32,100958376u32,235184299u32,369410226u32, 67436733u32,100999359u32,235225282u32,33915081u32,33923274u32,1141227723u32, 67502317u32,67510511u32,33972465u32,168198386u32,33997047u32,34005240u32, 67576057u32,34038011u32,67608828u32,34062590u32,34070783u32,67633408u32, 134750466u32,34103558u32,201900295u32,67698957u32,101261583u32,235487506u32, 34177305u32,201974042u32,101318944u32,537534755u32,1141522739u32,67797333u32, 101359959u32,235585882u32,34275681u32,202072418u32,671842664u32,202088828u32, 638304642u32,1175183765u32,67903928u32,101466554u32,235692477u32,34382276u32, 34390469u32,34398662u32,135070151u32,202195403u32,369975761u32,235766236u32, 638427619u32,235782646u32,101573117u32,101581312u32,235807235u32,1041129994u32, 202277417u32,68076079u32,101638705u32,235864628u32,101663291u32,202334782u32, 638550596u32,1141883479u32,907010681u32,907018900u32,504373935u32,68174526u32, 34628288u32,1141932737u32,68207331u32,101769957u32,235995880u32,101794543u32, 135365362u32,68281078u32,34734840u32,34743033u32,236077818u32,34767617u32, 169018114u32,68371207u32,101933833u32,236159756u32,34849555u32,202646292u32, 101991194u32,34890525u32,34898718u32,236233503u32,135578406u32,1142219562u32, 68494156u32,102056782u32,236282705u32,34972504u32,202769241u32,68567903u32, 102130529u32,236356452u32,35046251u32,35054444u32,202834797u32,102179699u32, 504841078u32,236413829u32,102204300u32,538420111u32,202883999u32,68682661u32, 102245287u32,236471210u32,35161009u32,35169202u32,202949555u32,102294457u32, 102302652u32,404300735u32,1142506443u32,102327277u32,102335472u32,236561395u32, 35251194u32,35259387u32,203039740u32,505037826u32,370828305u32,68854812u32, 102417438u32,236643361u32,35333160u32,35341353u32,203121706u32,639337520u32, 236692547u32,102483018u32,773579853u32,102499428u32,102507623u32,236733546u32, 35423345u32,35431538u32,203211891u32,102556793u32,102564988u32,236790911u32, 136135814u32,203252874u32,69051536u32,102614162u32,236840085u32,35529884u32, 35538077u32,1142842526u32,69117120u32,69125314u32,203367620u32,35611850u32, 35620043u32,203400396u32,69199058u32,102761684u32,236987607u32,35677406u32, 35685599u32,203465952u32,69264614u32,102827240u32,237053163u32,35742962u32, 203539699u32,639763705u32,1143088396u32,69362990u32,69371184u32,237159730u32, 35849529u32,203646266u32,69444928u32,103007554u32,237233477u32,35923276u32, 35931469u32,203711822u32,103056724u32,103064919u32,237290842u32,35980641u32, 203777378u32,908428648u32,69584259u32,103146885u32,237372808u32,36062607u32, 36070800u32,203851153u32,69649815u32,103212441u32,237438364u32,136783267u32, 203900327u32,673670573u32,203916737u32,237479367u32,640140750u32,908584417u32, 69740028u32,103302654u32,237528577u32,36218376u32,36226569u32,204006922u32, 103351824u32,103360019u32,405358102u32,204039714u32,673809960u32,204056124u32, 69854786u32,103417412u32,237643335u32,36333134u32,36341327u32,204121680u32, 103466582u32,103474777u32,237700700u32,371926627u32,69953134u32,103515760u32, 237741683u32,103540346u32,1143735933u32,70010527u32,103573153u32,237799076u32, 36488875u32,36497068u32,204277421u32,70076083u32,103638709u32,204318392u32, 36562622u32,204359359u32,70158021u32,103720647u32,237946570u32,36636369u32, 204433106u32,674203352u32,1143973612u32,70248206u32,103810832u32,36710163u32, 170936084u32,36734745u32,204531482u32,70330144u32,103892770u32,238118693u32, 36808492u32,36816685u32,204597038u32,103941940u32,506603319u32,238176070u32, 103966541u32,775063376u32,70436711u32,103999337u32,238225260u32,36915059u32, 36923252u32,137594741u32,36939641u32,104056698u32,775153533u32,909379476u32, 104081327u32,473188274u32,36988864u32,204769217u32,909420487u32,70576098u32, 104138724u32,238364647u32,37054446u32,37062639u32,204842992u32,641058806u32, 238413833u32,909510672u32,70666283u32,104228909u32,238454832u32,104253495u32, 204924986u32,104269888u32,104278083u32,238504006u32,137848909u32,204965969u32, 70764631u32,70772825u32,37234779u32,171460700u32,37259361u32,272148578u32, 104384618u32,104392813u32,238618736u32,339298423u32,70879361u32,104441987u32, 238667910u32,37357709u32,37365902u32,205146255u32,37398677u32,104515734u32, 37415065u32,171640986u32,37439647u32,104573088u32,71026851u32,71043237u32, 104605863u32,238831786u32,37521585u32,205318322u32,1815947448u32,71133422u32, 104696048u32,238921971u32,37611770u32,205408507u32,71207169u32,104769795u32, 238995718u32,37685517u32,37693710u32,205474063u32,104818965u32,104827160u32, 239053083u32,71297314u32,205531428u32,239094058u32,272656689u32,37783865u32, 272673082u32,71362882u32,104925508u32,239151431u32,37841230u32,37849423u32, 205629776u32,675400022u32,1145170282u32,104991116u32,776087951u32,105007526u32, 105015721u32,272796076u32,37923252u32,272812469u32,71502269u32,71510463u32, 37972417u32,172198338u32,37996999u32,38005192u32,205785545u32,675555791u32, 1145326051u32,105146885u32,105155080u32,239381003u32,71617042u32,272951828u32, 105187868u32,105196063u32,239421986u32,71658025u32,38111787u32,205892140u32, 105237042u32,105245237u32,239471160u32,38160959u32,1212574272u32,71740004u32, 105302630u32,239528553u32,38218352u32,38226545u32,206006898u32,71805560u32, 105368186u32,138930813u32,71830145u32,38292099u32,38300292u32,206080645u32, 71879307u32,105441933u32,239667856u32,38357655u32,206154392u32,675924638u32, 1145694898u32,71969492u32,105532118u32,38431449u32,172657370u32,38456031u32, 38464224u32,206244577u32,72043239u32,105605865u32,239831788u32,38521587u32, 38529780u32,206310133u32,72108795u32,105671421u32,239897344u32,38587143u32, 206383880u32,105728782u32,105736977u32,273517332u32,340634396u32,72215334u32, 105777960u32,139340587u32,72239919u32,38701873u32,38710066u32,105827123u32, 72280886u32,72297272u32,105859898u32,340749117u32,38767431u32,206547784u32, 72346446u32,475007824u32,38808414u32,206588767u32,72387429u32,105950055u32, 273730410u32,38857586u32,38865779u32,206646132u32,105991034u32,105999229u32, 273779584u32,38906760u32,273795977u32,72485777u32,106048403u32,139611030u32, 72510362u32,72518556u32,38972318u32,206752671u32,106097573u32,106105768u32, 240331691u32,139676594u32,206793654u32,72592316u32,106154942u32,408153025u32, 206834637u32,72633299u32,106195925u32,240421848u32,39111647u32,39119840u32, 206900193u32,72698855u32,106261481u32,240487404u32,72723443u32,39177205u32, 206957558u32,72756220u32,39209982u32,207014911u32,39259141u32,39267334u32, 106384391u32,72838154u32,106400780u32,106408975u32,240634898u32,106433561u32, 207105052u32,72903714u32,106466340u32,240692263u32,39382062u32,39390255u32, 207170608u32, ] const EucKRRunsOffset2* = 51365u16 const EucKRDecode*: array[8742, uint16] = [ uint16 12288,12289,12290,183,8229,8230,168,12291,173,8213,8741,65340,8764,8216,8217, 8220,8221,12308,12309,12296,12297,12298,12299,12300,12301,12302,12303,12304, 12305,177,215,247,8800,8804,8805,8734,8756,176,8242,8243,8451,8491,65504,65505, 65509,9794,9792,8736,8869,8978,8706,8711,8801,8786,167,8251,9734,9733,9675,9679, 9678,9671,9670,9633,9632,9651,9650,9661,9660,8594,8592,8593,8595,8596,12307, 8810,8811,8730,8765,8733,8757,8747,8748,8712,8715,8838,8839,8834,8835,8746,8745, 8743,8744,65506,8658,8660,8704,8707,180,65374,711,728,733,730,729,184,731,161, 191,720,8750,8721,8719,164,8457,8240,9665,9664,9655,9654,9828,9824,9825,9829, 9831,9827,8857,9672,9635,9680,9681,9618,9636,9637,9640,9639,9638,9641,9832,9743, 9742,9756,9758,182,8224,8225,8597,8599,8601,8598,8600,9837,9833,9834,9836,12927, 12828,8470,13255,8482,13250,13272,8481,8364,174,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,65281,65282,65283,65284,65285,65286,65287,65288,65289,65290,65291, 65292,65293,65294,65295,65296,65297,65298,65299,65300,65301,65302,65303,65304, 65305,65306,65307,65308,65309,65310,65311,65312,65313,65314,65315,65316,65317, 65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,65328,65329,65330, 65331,65332,65333,65334,65335,65336,65337,65338,65339,65510,65341,65342,65343, 65344,65345,65346,65347,65348,65349,65350,65351,65352,65353,65354,65355,65356, 65357,65358,65359,65360,65361,65362,65363,65364,65365,65366,65367,65368,65369, 65370,65371,65372,65373,65507,12593,12594,12595,12596,12597,12598,12599,12600, 12601,12602,12603,12604,12605,12606,12607,12608,12609,12610,12611,12612,12613, 12614,12615,12616,12617,12618,12619,12620,12621,12622,12623,12624,12625,12626, 12627,12628,12629,12630,12631,12632,12633,12634,12635,12636,12637,12638,12639, 12640,12641,12642,12643,12644,12645,12646,12647,12648,12649,12650,12651,12652, 12653,12654,12655,12656,12657,12658,12659,12660,12661,12662,12663,12664,12665, 12666,12667,12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678, 12679,12680,12681,12682,12683,12684,12685,12686,8560,8561,8562,8563,8564,8565, 8566,8567,8568,8569,0,0,0,0,0,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553, 0,0,0,0,0,0,0,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928, 929,931,932,933,934,935,936,937,0,0,0,0,0,0,0,0,945,946,947,948,949,950,951,952, 953,954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,0,0,0,0,0,0, 9472,9474,9484,9488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487,9491,9499, 9495,9507,9523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520,9509,9528,9538, 9490,9489,9498,9497,9494,9493,9486,9485,9502,9503,9505,9506,9510,9511,9513,9514, 9517,9518,9521,9522,9525,9526,9529,9530,9533,9534,9536,9537,9539,9540,9541,9542, 9543,9544,9545,9546,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13205, 13206,13207,8467,13208,13252,13219,13220,13221,13222,13209,13210,13211,13212, 13213,13214,13215,13216,13217,13218,13258,13197,13198,13199,13263,13192,13193, 13256,13223,13224,13232,13233,13234,13235,13236,13237,13238,13239,13240,13241, 13184,13185,13186,13187,13188,13242,13243,13244,13245,13246,13247,13200,13201, 13202,13203,13204,8486,13248,13249,13194,13195,13196,13270,13253,13229,13230, 13231,13275,13225,13226,13227,13228,13277,13264,13267,13251,13257,13276,13254,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,198,208,170,294,0,306,0,319,321,216,338,186,222,358, 330,0,12896,12897,12898,12899,12900,12901,12902,12903,12904,12905,12906,12907, 12908,12909,12910,12911,12912,12913,12914,12915,12916,12917,12918,12919,12920, 12921,12922,12923,9424,9425,9426,9427,9428,9429,9430,9431,9432,9433,9434,9435, 9436,9437,9438,9439,9440,9441,9442,9443,9444,9445,9446,9447,9448,9449,9312,9313, 9314,9315,9316,9317,9318,9319,9320,9321,9322,9323,9324,9325,9326,189,8531,8532, 188,190,8539,8540,8541,8542,230,273,240,295,305,307,312,320,322,248,339,223,254, 359,331,329,12800,12801,12802,12803,12804,12805,12806,12807,12808,12809,12810, 12811,12812,12813,12814,12815,12816,12817,12818,12819,12820,12821,12822,12823, 12824,12825,12826,12827,9372,9373,9374,9375,9376,9377,9378,9379,9380,9381,9382, 9383,9384,9385,9386,9387,9388,9389,9390,9391,9392,9393,9394,9395,9396,9397,9332, 9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345,9346,185,178, 179,8308,8319,8321,8322,8323,8324,12353,12354,12355,12356,12357,12358,12359, 12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,12371,12372, 12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384,12385, 12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,12398, 12399,12400,12401,12402,12403,12404,12405,12406,12407,12408,12409,12410,12411, 12412,12413,12414,12415,12416,12417,12418,12419,12420,12421,12422,12423,12424, 12425,12426,12427,12428,12429,12430,12431,12432,12433,12434,12435,0,0,0,0,0,0,0, 0,0,0,0,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460, 12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473, 12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486, 12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499, 12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512, 12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525, 12526,12527,12528,12529,12530,12531,12532,12533,12534,0,0,0,0,0,0,0,0,1040,1041, 1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056, 1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080, 1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096, 1097,1098,1099,1100,1101,1102,1103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,44032,44033, 44036,44039,44040,44041,44042,44048,44049,44050,44051,44052,44053,44054,44055, 44057,44058,44059,44060,44061,44064,44068,44076,44077,44079,44080,44081,44088, 44089,44092,44096,44107,44109,44116,44120,44124,44144,44145,44148,44151,44152, 44154,44160,44161,44163,44164,44165,44166,44169,44170,44171,44172,44176,44180, 44188,44189,44191,44192,44193,44200,44201,44202,44204,44207,44208,44216,44217, 44219,44220,44221,44225,44228,44232,44236,44245,44247,44256,44257,44260,44263, 44264,44266,44268,44271,44272,44273,44275,44277,44278,44284,44285,44288,44292, 44294,44300,44301,44303,44305,44312,44316,44320,44329,44332,44333,44340,44341, 44344,44348,44356,44357,44359,44361,44368,44372,44376,44385,44387,44396,44397, 44400,44403,44404,44405,44406,44411,44412,44413,44415,44417,44418,44424,44425, 44428,44432,44444,44445,44452,44471,44480,44481,44484,44488,44496,44497,44499, 44508,44512,44516,44536,44537,44540,44543,44544,44545,44552,44553,44555,44557, 44564,44592,44593,44596,44599,44600,44602,44608,44609,44611,44613,44614,44618, 44620,44621,44622,44624,44628,44630,44636,44637,44639,44640,44641,44645,44648, 44649,44652,44656,44664,44665,44667,44668,44669,44676,44677,44684,44732,44733, 44734,44736,44740,44748,44749,44751,44752,44753,44760,44761,44764,44776,44779, 44781,44788,44792,44796,44807,44808,44813,44816,44844,44845,44848,44850,44852, 44860,44861,44863,44865,44866,44867,44872,44873,44880,44892,44893,44900,44901, 44921,44928,44932,44936,44944,44945,44949,44956,44984,44985,44988,44992,44999, 45000,45001,45003,45005,45006,45012,45020,45032,45033,45040,45041,45044,45048, 45056,45057,45060,45068,45072,45076,45084,45085,45096,45124,45125,45128,45130, 45132,45134,45139,45140,45141,45143,45145,45149,45180,45181,45184,45188,45196, 45197,45199,45201,45208,45209,45210,45212,45215,45216,45217,45218,45224,45225, 45227,45228,45229,45230,45231,45233,45235,45236,45237,45240,45244,45252,45253, 45255,45256,45257,45264,45265,45268,45272,45280,45285,45320,45321,45323,45324, 45328,45330,45331,45336,45337,45339,45340,45341,45347,45348,45349,45352,45356, 45364,45365,45367,45368,45369,45376,45377,45380,45384,45392,45393,45396,45397, 45400,45404,45408,45432,45433,45436,45440,45442,45448,45449,45451,45453,45458, 45459,45460,45464,45468,45480,45516,45520,45524,45532,45533,45535,45544,45545, 45548,45552,45561,45563,45565,45572,45573,45576,45579,45580,45588,45589,45591, 45593,45600,45620,45628,45656,45660,45664,45672,45673,45684,45685,45692,45700, 45701,45705,45712,45713,45716,45720,45721,45722,45728,45729,45731,45733,45734, 45738,45740,45744,45748,45768,45769,45772,45776,45778,45784,45785,45787,45789, 45794,45796,45797,45798,45800,45803,45804,45805,45806,45807,45811,45812,45813, 45815,45816,45817,45818,45819,45823,45824,45825,45828,45832,45840,45841,45843, 45844,45845,45852,45908,45909,45910,45912,45915,45916,45918,45919,45924,45925, 45927,45929,45931,45934,45936,45937,45940,45944,45952,45953,45955,45956,45957, 45964,45968,45972,45984,45985,45992,45996,46020,46021,46024,46027,46028,46030, 46032,46036,46037,46039,46041,46043,46045,46048,46052,46056,46076,46096,46104, 46108,46112,46120,46121,46123,46132,46160,46161,46164,46168,46176,46177,46179, 46181,46188,46208,46216,46237,46244,46248,46252,46261,46263,46265,46272,46276, 46280,46288,46293,46300,46301,46304,46307,46308,46310,46316,46317,46319,46321, 46328,46356,46357,46360,46363,46364,46372,46373,46375,46376,46377,46378,46384, 46385,46388,46392,46400,46401,46403,46404,46405,46411,46412,46413,46416,46420, 46428,46429,46431,46432,46433,46496,46497,46500,46504,46506,46507,46512,46513, 46515,46516,46517,46523,46524,46525,46528,46532,46540,46541,46543,46544,46545, 46552,46572,46608,46609,46612,46616,46629,46636,46644,46664,46692,46696,46748, 46749,46752,46756,46763,46764,46769,46804,46832,46836,46840,46848,46849,46853, 46888,46889,46892,46895,46896,46904,46905,46907,46916,46920,46924,46932,46933, 46944,46948,46952,46960,46961,46963,46965,46972,46973,46976,46980,46988,46989, 46991,46992,46993,46994,46998,46999,47000,47001,47004,47008,47016,47017,47019, 47020,47021,47028,47029,47032,47047,47049,47084,47085,47088,47092,47100,47101, 47103,47104,47105,47111,47112,47113,47116,47120,47128,47129,47131,47133,47140, 47141,47144,47148,47156,47157,47159,47160,47161,47168,47172,47185,47187,47196, 47197,47200,47204,47212,47213,47215,47217,47224,47228,47245,47272,47280,47284, 47288,47296,47297,47299,47301,47308,47312,47316,47325,47327,47329,47336,47337, 47340,47344,47352,47353,47355,47357,47364,47384,47392,47420,47421,47424,47428, 47436,47439,47441,47448,47449,47452,47456,47464,47465,47467,47469,47476,47477, 47480,47484,47492,47493,47495,47497,47498,47501,47502,47532,47533,47536,47540, 47548,47549,47551,47553,47560,47561,47564,47566,47567,47568,47569,47570,47576, 47577,47579,47581,47582,47585,47587,47588,47589,47592,47596,47604,47605,47607, 47608,47609,47610,47616,47617,47624,47637,47672,47673,47676,47680,47682,47688, 47689,47691,47693,47694,47699,47700,47701,47704,47708,47716,47717,47719,47720, 47721,47728,47729,47732,47736,47747,47748,47749,47751,47756,47784,47785,47787, 47788,47792,47794,47800,47801,47803,47805,47812,47816,47832,47833,47868,47872, 47876,47885,47887,47889,47896,47900,47904,47913,47915,47924,47925,47926,47928, 47931,47932,47933,47934,47940,47941,47943,47945,47949,47951,47952,47956,47960, 47969,47971,47980,48008,48012,48016,48036,48040,48044,48052,48055,48064,48068, 48072,48080,48083,48120,48121,48124,48127,48128,48130,48136,48137,48139,48140, 48141,48143,48145,48148,48149,48150,48151,48152,48155,48156,48157,48158,48159, 48164,48165,48167,48169,48173,48176,48177,48180,48184,48192,48193,48195,48196, 48197,48201,48204,48205,48208,48221,48260,48261,48264,48267,48268,48270,48276, 48277,48279,48281,48282,48288,48289,48292,48295,48296,48304,48305,48307,48308, 48309,48316,48317,48320,48324,48333,48335,48336,48337,48341,48344,48348,48372, 48373,48374,48376,48380,48388,48389,48391,48393,48400,48404,48420,48428,48448, 48456,48457,48460,48464,48472,48473,48484,48488,48512,48513,48516,48519,48520, 48521,48522,48528,48529,48531,48533,48537,48538,48540,48548,48560,48568,48596, 48597,48600,48604,48617,48624,48628,48632,48640,48643,48645,48652,48653,48656, 48660,48668,48669,48671,48708,48709,48712,48716,48718,48724,48725,48727,48729, 48730,48731,48736,48737,48740,48744,48746,48752,48753,48755,48756,48757,48763, 48764,48765,48768,48772,48780,48781,48783,48784,48785,48792,48793,48808,48848, 48849,48852,48855,48856,48864,48867,48868,48869,48876,48897,48904,48905,48920, 48921,48923,48924,48925,48960,48961,48964,48968,48976,48977,48981,49044,49072, 49093,49100,49101,49104,49108,49116,49119,49121,49212,49233,49240,49244,49248, 49256,49257,49296,49297,49300,49304,49312,49313,49315,49317,49324,49325,49327, 49328,49331,49332,49333,49334,49340,49341,49343,49344,49345,49349,49352,49353, 49356,49360,49368,49369,49371,49372,49373,49380,49381,49384,49388,49396,49397, 49399,49401,49408,49412,49416,49424,49429,49436,49437,49438,49439,49440,49443, 49444,49446,49447,49452,49453,49455,49456,49457,49462,49464,49465,49468,49472, 49480,49481,49483,49484,49485,49492,49493,49496,49500,49508,49509,49511,49512, 49513,49520,49524,49528,49541,49548,49549,49550,49552,49556,49558,49564,49565, 49567,49569,49573,49576,49577,49580,49584,49597,49604,49608,49612,49620,49623, 49624,49632,49636,49640,49648,49649,49651,49660,49661,49664,49668,49676,49677, 49679,49681,49688,49689,49692,49695,49696,49704,49705,49707,49709,49711,49713, 49714,49716,49736,49744,49745,49748,49752,49760,49765,49772,49773,49776,49780, 49788,49789,49791,49793,49800,49801,49808,49816,49819,49821,49828,49829,49832, 49836,49837,49844,49845,49847,49849,49884,49885,49888,49891,49892,49899,49900, 49901,49903,49905,49910,49912,49913,49915,49916,49920,49928,49929,49932,49933, 49939,49940,49941,49944,49948,49956,49957,49960,49961,49989,50024,50025,50028, 50032,50034,50040,50041,50044,50045,50052,50056,50060,50112,50136,50137,50140, 50143,50144,50146,50152,50153,50157,50164,50165,50168,50184,50192,50212,50220, 50224,50228,50236,50237,50248,50276,50277,50280,50284,50292,50293,50297,50304, 50324,50332,50360,50364,50409,50416,50417,50420,50424,50426,50431,50432,50433, 50444,50448,50452,50460,50472,50473,50476,50480,50488,50489,50491,50493,50500, 50501,50504,50505,50506,50508,50509,50510,50515,50516,50517,50519,50520,50521, 50525,50526,50528,50529,50532,50536,50544,50545,50547,50548,50549,50556,50557, 50560,50564,50567,50572,50573,50575,50577,50581,50583,50584,50588,50592,50601, 50612,50613,50616,50617,50619,50620,50621,50622,50628,50629,50630,50631,50632, 50633,50634,50636,50638,50640,50641,50644,50648,50656,50657,50659,50661,50668, 50669,50670,50672,50676,50678,50679,50684,50685,50686,50687,50688,50689,50693, 50694,50695,50696,50700,50704,50712,50713,50715,50716,50724,50725,50728,50732, 50733,50734,50736,50739,50740,50741,50743,50745,50747,50752,50753,50756,50760, 50768,50769,50771,50772,50773,50780,50781,50784,50796,50799,50801,50808,50809, 50812,50816,50824,50825,50827,50829,50836,50837,50840,50844,50852,50853,50855, 50857,50864,50865,50868,50872,50873,50874,50880,50881,50883,50885,50892,50893, 50896,50900,50908,50909,50912,50913,50920,50921,50924,50928,50936,50937,50941, 50948,50949,50952,50956,50964,50965,50967,50969,50976,50977,50980,50984,50992, 50993,50995,50997,50999,51004,51005,51008,51012,51018,51020,51021,51023,51025, 51026,51027,51028,51029,51030,51031,51032,51036,51040,51048,51051,51060,51061, 51064,51068,51069,51070,51075,51076,51077,51079,51080,51081,51082,51086,51088, 51089,51092,51094,51095,51096,51098,51104,51105,51107,51108,51109,51110,51116, 51117,51120,51124,51132,51133,51135,51136,51137,51144,51145,51148,51150,51152, 51160,51165,51172,51176,51180,51200,51201,51204,51208,51210,51216,51217,51219, 51221,51222,51228,51229,51232,51236,51244,51245,51247,51249,51256,51260,51264, 51272,51273,51276,51277,51284,51312,51313,51316,51320,51322,51328,51329,51331, 51333,51334,51335,51339,51340,51341,51348,51357,51359,51361,51368,51388,51389, 51396,51400,51404,51412,51413,51415,51417,51424,51425,51428,51445,51452,51453, 51456,51460,51461,51462,51468,51469,51471,51473,51480,51500,51508,51536,51537, 51540,51544,51552,51553,51555,51564,51568,51572,51580,51592,51593,51596,51600, 51608,51609,51611,51613,51648,51649,51652,51655,51656,51658,51664,51665,51667, 51669,51670,51673,51674,51676,51677,51680,51682,51684,51687,51692,51693,51695, 51696,51697,51704,51705,51708,51712,51720,51721,51723,51724,51725,51732,51736, 51753,51788,51789,51792,51796,51804,51805,51807,51808,51809,51816,51837,51844, 51864,51900,51901,51904,51908,51916,51917,51919,51921,51923,51928,51929,51936, 51948,51956,51976,51984,51988,51992,52000,52001,52033,52040,52041,52044,52048, 52056,52057,52061,52068,52088,52089,52124,52152,52180,52196,52199,52201,52236, 52237,52240,52244,52252,52253,52257,52258,52263,52264,52265,52268,52270,52272, 52280,52281,52283,52284,52285,52286,52292,52293,52296,52300,52308,52309,52311, 52312,52313,52320,52324,52326,52328,52336,52341,52376,52377,52380,52384,52392, 52393,52395,52396,52397,52404,52405,52408,52412,52420,52421,52423,52425,52432, 52436,52452,52460,52464,52481,52488,52489,52492,52496,52504,52505,52507,52509, 52516,52520,52524,52537,52572,52576,52580,52588,52589,52591,52593,52600,52616, 52628,52629,52632,52636,52644,52645,52647,52649,52656,52676,52684,52688,52712, 52716,52720,52728,52729,52731,52733,52740,52744,52748,52756,52761,52768,52769, 52772,52776,52784,52785,52787,52789,52824,52825,52828,52831,52832,52833,52840, 52841,52843,52845,52852,52853,52856,52860,52868,52869,52871,52873,52880,52881, 52884,52888,52896,52897,52899,52900,52901,52908,52909,52929,52964,52965,52968, 52971,52972,52980,52981,52983,52984,52985,52992,52993,52996,53000,53008,53009, 53011,53013,53020,53024,53028,53036,53037,53039,53040,53041,53048,53076,53077, 53080,53084,53092,53093,53095,53097,53104,53105,53108,53112,53120,53125,53132, 53153,53160,53168,53188,53216,53217,53220,53224,53232,53233,53235,53237,53244, 53248,53252,53265,53272,53293,53300,53301,53304,53308,53316,53317,53319,53321, 53328,53332,53336,53344,53356,53357,53360,53364,53372,53373,53377,53412,53413, 53416,53420,53428,53429,53431,53433,53440,53441,53444,53448,53449,53456,53457, 53459,53460,53461,53468,53469,53472,53476,53484,53485,53487,53488,53489,53496, 53517,53552,53553,53556,53560,53562,53568,53569,53571,53572,53573,53580,53581, 53584,53588,53596,53597,53599,53601,53608,53612,53628,53636,53640,53664,53665, 53668,53672,53680,53681,53683,53685,53690,53692,53696,53720,53748,53752,53767, 53769,53776,53804,53805,53808,53812,53820,53821,53823,53825,53832,53852,53860, 53888,53889,53892,53896,53904,53905,53909,53916,53920,53924,53932,53937,53944, 53945,53948,53951,53952,53954,53960,53961,53963,53972,53976,53980,53988,53989, 54000,54001,54004,54008,54016,54017,54019,54021,54028,54029,54030,54032,54036, 54038,54044,54045,54047,54048,54049,54053,54056,54057,54060,54064,54072,54073, 54075,54076,54077,54084,54085,54140,54141,54144,54148,54156,54157,54159,54160, 54161,54168,54169,54172,54176,54184,54185,54187,54189,54196,54200,54204,54212, 54213,54216,54217,54224,54232,54241,54243,54252,54253,54256,54260,54268,54269, 54271,54273,54280,54301,54336,54340,54364,54368,54372,54381,54383,54392,54393, 54396,54399,54400,54402,54408,54409,54411,54413,54420,54441,54476,54480,54484, 54492,54495,54504,54508,54512,54520,54523,54525,54532,54536,54540,54548,54549, 54551,54588,54589,54592,54596,54604,54605,54607,54609,54616,54617,54620,54624, 54629,54632,54633,54635,54637,54644,54645,54648,54652,54660,54661,54663,54664, 54665,54672,54693,54728,54729,54732,54736,54738,54744,54745,54747,54749,54756, 54757,54760,54764,54772,54773,54775,54777,54784,54785,54788,54792,54800,54801, 54803,54804,54805,54812,54816,54820,54829,54840,54841,54844,54848,54853,54856, 54857,54859,54861,54865,54868,54869,54872,54876,54887,54889,54896,54897,54900, 54915,54917,54924,54925,54928,54932,54941,54943,54945,54952,54956,54960,54969, 54971,54980,54981,54984,54988,54993,54996,54999,55001,55008,55012,55016,55024, 55029,55036,55037,55040,55044,55057,55064,55065,55068,55072,55080,55081,55083, 55085,55092,55093,55096,55100,55108,55111,55113,55120,55121,55124,55126,55127, 55128,55129,55136,55137,55139,55141,55145,55148,55152,55156,55164,55165,55169, 55176,55177,55180,55184,55192,55193,55195,55197,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 20285,20339,20551,20729,21152,21487,21621,21733,22025,23233,23478,26247,26550, 26551,26607,27468,29634,30146,31292,33499,33540,34903,34952,35382,36040,36303, 36603,36838,39381,21051,21364,21508,24682,24932,27580,29647,33050,35258,35282, 38307,20355,21002,22718,22904,23014,24178,24185,25031,25536,26438,26604,26751, 28567,30286,30475,30965,31240,31487,31777,32925,33390,33393,35563,38291,20075, 21917,26359,28212,30883,31469,33883,35088,34638,38824,21208,22350,22570,23884, 24863,25022,25121,25954,26577,27204,28187,29976,30131,30435,30640,32058,37039, 37969,37970,40853,21283,23724,30002,32987,37440,38296,21083,22536,23004,23713, 23831,24247,24378,24394,24951,27743,30074,30086,31968,32115,32177,32652,33108, 33313,34193,35137,35611,37628,38477,40007,20171,20215,20491,20977,22607,24887, 24894,24936,25913,27114,28433,30117,30342,30422,31623,33445,33995,63744,37799, 38283,21888,23458,22353,63745,31923,32697,37301,20520,21435,23621,24040,25298, 25454,25818,25831,28192,28844,31067,36317,36382,63746,36989,37445,37624,20094, 20214,20581,24062,24314,24838,26967,33137,34388,36423,37749,39467,20062,20625, 26480,26688,20745,21133,21138,27298,30652,37392,40660,21163,24623,36850,20552, 25001,25581,25802,26684,27268,28608,33160,35233,38548,22533,29309,29356,29956, 32121,32365,32937,35211,35700,36963,40273,25225,27770,28500,32080,32570,35363, 20860,24906,31645,35609,37463,37772,20140,20435,20510,20670,20742,21185,21197, 21375,22384,22659,24218,24465,24950,25004,25806,25964,26223,26299,26356,26775, 28039,28805,28913,29855,29861,29898,30169,30828,30956,31455,31478,32069,32147, 32789,32831,33051,33686,35686,36629,36885,37857,38915,38968,39514,39912,20418, 21843,22586,22865,23395,23622,24760,25106,26690,26800,26856,28330,30028,30328, 30926,31293,31995,32363,32380,35336,35489,35903,38542,40388,21476,21481,21578, 21617,22266,22993,23396,23611,24235,25335,25911,25925,25970,26272,26543,27073, 27837,30204,30352,30590,31295,32660,32771,32929,33167,33510,33533,33776,34241, 34865,34996,35493,63747,36764,37678,38599,39015,39640,40723,21741,26011,26354, 26767,31296,35895,40288,22256,22372,23825,26118,26801,26829,28414,29736,34974, 39908,27752,63748,39592,20379,20844,20849,21151,23380,24037,24656,24685,25329, 25511,25915,29657,31354,34467,36002,38799,20018,23521,25096,26524,29916,31185, 33747,35463,35506,36328,36942,37707,38982,24275,27112,34303,37101,63749,20896, 23448,23532,24931,26874,27454,28748,29743,29912,31649,32592,33733,35264,36011, 38364,39208,21038,24669,25324,36866,20362,20809,21281,22745,24291,26336,27960, 28826,29378,29654,31568,33009,37979,21350,25499,32619,20054,20608,22602,22750, 24618,24871,25296,27088,39745,23439,32024,32945,36703,20132,20689,21676,21932, 23308,23968,24039,25898,25934,26657,27211,29409,30350,30703,32094,32761,33184, 34126,34527,36611,36686,37066,39171,39509,39851,19992,20037,20061,20167,20465, 20855,21246,21312,21475,21477,21646,22036,22389,22434,23495,23943,24272,25084, 25304,25937,26552,26601,27083,27472,27590,27628,27714,28317,28792,29399,29590, 29699,30655,30697,31350,32127,32777,33276,33285,33290,33503,34914,35635,36092, 36544,36881,37041,37476,37558,39378,39493,40169,40407,40860,22283,23616,33738, 38816,38827,40628,21531,31384,32676,35033,36557,37089,22528,23624,25496,31391, 23470,24339,31353,31406,33422,36524,20518,21048,21240,21367,22280,25331,25458, 27402,28099,30519,21413,29527,34152,36470,38357,26426,27331,28528,35437,36556, 39243,63750,26231,27512,36020,39740,63751,21483,22317,22862,25542,27131,29674, 30789,31418,31429,31998,33909,35215,36211,36917,38312,21243,22343,30023,31584, 33740,37406,63752,27224,20811,21067,21127,25119,26840,26997,38553,20677,21156, 21220,25027,26020,26681,27135,29822,31563,33465,33771,35250,35641,36817,39241, 63753,20170,22935,25810,26129,27278,29748,31105,31165,33449,34942,34943,35167, 63754,37670,20235,21450,24613,25201,27762,32026,32102,20120,20834,30684,32943, 20225,20238,20854,20864,21980,22120,22331,22522,22524,22804,22855,22931,23492, 23696,23822,24049,24190,24524,25216,26071,26083,26398,26399,26462,26827,26820, 27231,27450,27683,27773,27778,28103,29592,29734,29738,29826,29859,30072,30079, 30849,30959,31041,31047,31048,31098,31637,32000,32186,32648,32774,32813,32908, 35352,35663,35912,36215,37665,37668,39138,39249,39438,39439,39525,40594,32202, 20342,21513,25326,26708,37329,21931,20794,63755,63756,23068,25062,63757,25295, 25343,63758,63759,63760,63761,63762,63763,37027,63764,63765,63766,63767,63768, 35582,63769,63770,63771,63772,26262,63773,29014,63774,63775,38627,63776,25423, 25466,21335,63777,26511,26976,28275,63778,30007,63779,63780,63781,32013,63782, 63783,34930,22218,23064,63784,63785,63786,63787,63788,20035,63789,20839,22856, 26608,32784,63790,22899,24180,25754,31178,24565,24684,25288,25467,23527,23511, 21162,63791,22900,24361,24594,63792,63793,63794,29785,63795,63796,63797,63798, 63799,63800,39377,63801,63802,63803,63804,63805,63806,63807,63808,63809,63810, 63811,28611,63812,63813,33215,36786,24817,63814,63815,33126,63816,63817,23615, 63818,63819,63820,63821,63822,63823,63824,63825,23273,35365,26491,32016,63826, 63827,63828,63829,63830,63831,33021,63832,63833,23612,27877,21311,28346,22810, 33590,20025,20150,20294,21934,22296,22727,24406,26039,26086,27264,27573,28237, 30701,31471,31774,32222,34507,34962,37170,37723,25787,28606,29562,30136,36948, 21846,22349,25018,25812,26311,28129,28251,28525,28601,30192,32835,33213,34113, 35203,35527,35674,37663,27795,30035,31572,36367,36957,21776,22530,22616,24162, 25095,25758,26848,30070,31958,34739,40680,20195,22408,22382,22823,23565,23729, 24118,24453,25140,25825,29619,33274,34955,36024,38538,40667,23429,24503,24755, 20498,20992,21040,22294,22581,22615,23566,23648,23798,23947,24230,24466,24764, 25361,25481,25623,26691,26873,27330,28120,28193,28372,28644,29182,30428,30585, 31153,31291,33796,35241,36077,36339,36424,36867,36884,36947,37117,37709,38518, 38876,27602,28678,29272,29346,29544,30563,31167,31716,32411,35712,22697,24775, 25958,26109,26302,27788,28958,29129,35930,38931,20077,31361,20189,20908,20941, 21205,21516,24999,26481,26704,26847,27934,28540,30140,30643,31461,33012,33891, 37509,20828,26007,26460,26515,30168,31431,33651,63834,35910,36887,38957,23663, 33216,33434,36929,36975,37389,24471,23965,27225,29128,30331,31561,34276,35588, 37159,39472,21895,25078,63835,30313,32645,34367,34746,35064,37007,63836,27931, 28889,29662,32097,33853,63837,37226,39409,63838,20098,21365,27396,27410,28734, 29211,34349,40478,21068,36771,23888,25829,25900,27414,28651,31811,32412,34253, 35172,35261,25289,33240,34847,24266,26391,28010,29436,29701,29807,34690,37086, 20358,23821,24480,33802,20919,25504,30053,20142,20486,20841,20937,26753,27153, 31918,31921,31975,33391,35538,36635,37327,20406,20791,21237,21570,24300,24942, 25150,26053,27354,28670,31018,34268,34851,38317,39522,39530,40599,40654,21147, 26310,27511,28701,31019,36706,38722,24976,25088,25891,28451,29001,29833,32244, 32879,34030,36646,36899,37706,20925,21015,21155,27916,28872,35010,24265,25986, 27566,28610,31806,29557,20196,20278,22265,63839,23738,23994,24604,29618,31533, 32666,32718,32838,36894,37428,38646,38728,38936,40801,20363,28583,31150,37300, 38583,21214,63840,25736,25796,27347,28510,28696,29200,30439,32769,34310,34396, 36335,36613,38706,39791,40442,40565,30860,31103,32160,33737,37636,40575,40595, 35542,22751,24324,26407,28711,29903,31840,32894,20769,28712,29282,30922,36034, 36058,36084,38647,20102,20698,23534,24278,26009,29134,30274,30637,32842,34044, 36988,39719,40845,22744,23105,23650,27155,28122,28431,30267,32047,32311,34078, 35128,37860,38475,21129,26066,26611,27060,27969,28316,28687,29705,29792,30041, 30244,30827,35628,39006,20845,25134,38520,20374,20523,23833,28138,32184,36650, 24459,24900,26647,63841,38534,21202,32907,20956,20940,26974,31260,32190,33777, 38517,20442,21033,21400,21519,21774,23653,24743,26446,26792,28012,29313,29432, 29702,29827,63842,30178,31852,32633,32696,33673,35023,35041,37324,37328,38626, 39881,21533,28542,29136,29848,34298,36522,38563,40023,40607,26519,28107,29747, 33256,38678,30764,31435,31520,31890,25705,29802,30194,30908,30952,39340,39764, 40635,23518,24149,28448,33180,33707,37000,19975,21325,23081,24018,24398,24930, 25405,26217,26364,28415,28459,28771,30622,33836,34067,34875,36627,39237,39995, 21788,25273,26411,27819,33545,35178,38778,20129,22916,24536,24537,26395,32178, 32596,33426,33579,33725,36638,37017,22475,22969,23186,23504,26151,26522,26757, 27599,29028,32629,36023,36067,36993,39749,33032,35978,38476,39488,40613,23391, 27667,29467,30450,30431,33804,20906,35219,20813,20885,21193,26825,27796,30468, 30496,32191,32236,38754,40629,28357,34065,20901,21517,21629,26126,26269,26919, 28319,30399,30609,33559,33986,34719,37225,37528,40180,34946,20398,20882,21215, 22982,24125,24917,25720,25721,26286,26576,27169,27597,27611,29279,29281,29761, 30520,30683,32791,33468,33541,35584,35624,35980,26408,27792,29287,30446,30566, 31302,40361,27519,27794,22818,26406,33945,21359,22675,22937,24287,25551,26164, 26483,28218,29483,31447,33495,37672,21209,24043,25006,25035,25098,25287,25771, 26080,26969,27494,27595,28961,29687,30045,32326,33310,33538,34154,35491,36031, 38695,40289,22696,40664,20497,21006,21563,21839,25991,27766,32010,32011,32862, 34442,38272,38639,21247,27797,29289,21619,23194,23614,23883,24396,24494,26410, 26806,26979,28220,28228,30473,31859,32654,34183,35598,36855,38753,40692,23735, 24758,24845,25003,25935,26107,26108,27665,27887,29599,29641,32225,38292,23494, 34588,35600,21085,21338,25293,25615,25778,26420,27192,27850,29632,29854,31636, 31893,32283,33162,33334,34180,36843,38649,39361,20276,21322,21453,21467,25292, 25644,25856,26001,27075,27886,28504,29677,30036,30242,30436,30460,30928,30971, 31020,32070,33324,34784,36820,38930,39151,21187,25300,25765,28196,28497,30332, 36299,37297,37474,39662,39747,20515,20621,22346,22952,23592,24135,24439,25151, 25918,26041,26049,26121,26507,27036,28354,30917,32033,32938,33152,33323,33459, 33953,34444,35370,35607,37030,38450,40848,20493,20467,63843,22521,24472,25308, 25490,26479,28227,28953,30403,32972,32986,35060,35061,35097,36064,36649,37197, 38506,20271,20336,24091,26575,26658,30333,30334,39748,24161,27146,29033,29140, 30058,63844,32321,34115,34281,39132,20240,31567,32624,38309,20961,24070,26805, 27710,27726,27867,29359,31684,33539,27861,29754,20731,21128,22721,25816,27287, 29863,30294,30887,34327,38370,38713,63845,21342,24321,35722,36776,36783,37002, 21029,30629,40009,40712,19993,20482,20853,23643,24183,26142,26170,26564,26821, 28851,29953,30149,31177,31453,36647,39200,39432,20445,22561,22577,23542,26222, 27493,27921,28282,28541,29668,29995,33769,35036,35091,35676,36628,20239,20693, 21264,21340,23443,24489,26381,31119,33145,33583,34068,35079,35206,36665,36667, 39333,39954,26412,20086,20472,22857,23553,23791,23792,25447,26834,28925,29090, 29739,32299,34028,34562,36898,37586,40179,19981,20184,20463,20613,21078,21103, 21542,21648,22496,22827,23142,23386,23413,23500,24220,63846,25206,25975,26023, 28014,28325,29238,31526,31807,32566,33104,33105,33178,33344,33433,33705,35331, 36000,36070,36091,36212,36282,37096,37340,38428,38468,39385,40167,21271,20998, 21545,22132,22707,22868,22894,24575,24996,25198,26128,27774,28954,30406,31881, 31966,32027,33452,36033,38640,63847,20315,24343,24447,25282,23849,26379,26842, 30844,32323,40300,19989,20633,21269,21290,21329,22915,23138,24199,24754,24970, 25161,25209,26000,26503,27047,27604,27606,27607,27608,27832,63848,29749,30202, 30738,30865,31189,31192,31875,32203,32737,32933,33086,33218,33778,34586,35048, 35513,35692,36027,37145,38750,39131,40763,22188,23338,24428,25996,27315,27567, 27996,28657,28693,29277,29613,36007,36051,38971,24977,27703,32856,39425,20045, 20107,20123,20181,20282,20284,20351,20447,20735,21490,21496,21766,21987,22235, 22763,22882,23057,23531,23546,23556,24051,24107,24473,24605,25448,26012,26031, 26614,26619,26797,27515,27801,27863,28195,28681,29509,30722,31038,31040,31072, 31169,31721,32023,32114,32902,33293,33678,34001,34503,35039,35408,35422,35613, 36060,36198,36781,37034,39164,39391,40605,21066,63849,26388,63850,20632,21034, 23665,25955,27733,29642,29987,30109,31639,33948,37240,38704,20087,25746,27578, 29022,34217,19977,63851,26441,26862,28183,33439,34072,34923,25591,28545,37394, 39087,19978,20663,20687,20767,21830,21930,22039,23360,23577,23776,24120,24202, 24224,24258,24819,26705,27233,28248,29245,29248,29376,30456,31077,31665,32724, 35059,35316,35443,35937,36062,38684,22622,29885,36093,21959,63852,31329,32034, 33394,29298,29983,29989,63853,31513,22661,22779,23996,24207,24246,24464,24661, 25234,25471,25933,26257,26329,26360,26646,26866,29312,29790,31598,32110,32214, 32626,32997,33298,34223,35199,35475,36893,37604,40653,40736,22805,22893,24109, 24796,26132,26227,26512,27728,28101,28511,30707,30889,33990,37323,37675,20185, 20682,20808,21892,23307,23459,25159,25982,26059,28210,29053,29697,29764,29831, 29887,30316,31146,32218,32341,32680,33146,33203,33337,34330,34796,35445,36323, 36984,37521,37925,39245,39854,21352,23633,26964,27844,27945,28203,33292,34203, 35131,35373,35498,38634,40807,21089,26297,27570,32406,34814,36109,38275,38493, 25885,28041,29166,63854,22478,22995,23468,24615,24826,25104,26143,26207,29481, 29689,30427,30465,31596,32854,32882,33125,35488,37266,19990,21218,27506,27927, 31237,31545,32048,63855,36016,21484,22063,22609,23477,23567,23569,24034,25152, 25475,25620,26157,26803,27836,28040,28335,28703,28836,29138,29990,30095,30094, 30233,31505,31712,31787,32032,32057,34092,34157,34311,35380,36877,36961,37045, 37559,38902,39479,20439,23660,26463,28049,31903,32396,35606,36118,36895,23403, 24061,25613,33984,36956,39137,29575,23435,24730,26494,28126,35359,35494,36865, 38924,21047,63856,28753,30862,37782,34928,37335,20462,21463,22013,22234,22402, 22781,23234,23432,23723,23744,24101,24833,25101,25163,25480,25628,25910,25976, 27193,27530,27700,27929,28465,29159,29417,29560,29703,29874,30246,30561,31168, 31319,31466,31929,32143,32172,32353,32670,33065,33585,33936,34010,34282,34966, 35504,35728,36664,36930,36995,37228,37526,37561,38539,38567,38568,38614,38656, 38920,39318,39635,39706,21460,22654,22809,23408,23487,28113,28506,29087,29729, 29881,32901,33789,24033,24455,24490,24642,26092,26642,26991,27219,27529,27957, 28147,29667,30462,30636,31565,32020,33059,33308,33600,34036,34147,35426,35524, 37255,37662,38918,39348,25100,34899,36848,37477,23815,23847,23913,29791,33181, 34664,28629,25342,32722,35126,35186,19998,20056,20711,21213,21319,25215,26119, 32361,34821,38494,20365,21273,22070,22987,23204,23608,23630,23629,24066,24337, 24643,26045,26159,26178,26558,26612,29468,30690,31034,32709,33940,33997,35222, 35430,35433,35553,35925,35962,22516,23508,24335,24687,25325,26893,27542,28252, 29060,31698,34645,35672,36606,39135,39166,20280,20353,20449,21627,23072,23480, 24892,26032,26216,29180,30003,31070,32051,33102,33251,33688,34218,34254,34563, 35338,36523,36763,63857,36805,22833,23460,23526,24713,23529,23563,24515,27777, 63858,28145,28683,29978,33455,35574,20160,21313,63859,38617,27663,20126,20420, 20818,21854,23077,23784,25105,29273,33469,33706,34558,34905,35357,38463,38597, 39187,40201,40285,22538,23731,23997,24132,24801,24853,25569,27138,28197,37122, 37716,38990,39952,40823,23433,23736,25353,26191,26696,30524,38593,38797,38996, 39839,26017,35585,36555,38332,21813,23721,24022,24245,26263,30284,33780,38343, 22739,25276,29390,40232,20208,22830,24591,26171,27523,31207,40230,21395,21696, 22467,23830,24859,26326,28079,30861,33406,38552,38724,21380,25212,25494,28082, 32266,33099,38989,27387,32588,40367,40474,20063,20539,20918,22812,24825,25590, 26928,29242,32822,63860,37326,24369,63861,63862,32004,33509,33903,33979,34277, 36493,63863,20335,63864,63865,22756,23363,24665,25562,25880,25965,26264,63866, 26954,27171,27915,28673,29036,30162,30221,31155,31344,63867,32650,63868,35140, 63869,35731,37312,38525,63870,39178,22276,24481,26044,28417,30208,31142,35486, 39341,39770,40812,20740,25014,25233,27277,33222,20547,22576,24422,28937,35328, 35578,23420,34326,20474,20796,22196,22852,25513,28153,23978,26989,20870,20104, 20313,63871,63872,63873,22914,63874,63875,27487,27741,63876,29877,30998,63877, 33287,33349,33593,36671,36701,63878,39192,63879,63880,63881,20134,63882,22495, 24441,26131,63883,63884,30123,32377,35695,63885,36870,39515,22181,22567,23032, 23071,23476,63886,24310,63887,63888,25424,25403,63889,26941,27783,27839,28046, 28051,28149,28436,63890,28895,28982,29017,63891,29123,29141,63892,30799,30831, 63893,31605,32227,63894,32303,63895,34893,36575,63896,63897,63898,37467,63899, 40182,63900,63901,63902,24709,28037,63903,29105,63904,63905,38321,21421,63906, 63907,63908,26579,63909,28814,28976,29744,33398,33490,63910,38331,39653,40573, 26308,63911,29121,33865,63912,63913,22603,63914,63915,23992,24433,63916,26144, 26254,27001,27054,27704,27891,28214,28481,28634,28699,28719,29008,29151,29552, 63917,29787,63918,29908,30408,31310,32403,63919,63920,33521,35424,36814,63921, 37704,63922,38681,63923,63924,20034,20522,63925,21000,21473,26355,27757,28618, 29450,30591,31330,33454,34269,34306,63926,35028,35427,35709,35947,63927,37555, 63928,38675,38928,20116,20237,20425,20658,21320,21566,21555,21978,22626,22714, 22887,23067,23524,24735,63929,25034,25942,26111,26212,26791,27738,28595,28879, 29100,29522,31613,34568,35492,39986,40711,23627,27779,29508,29577,37434,28331, 29797,30239,31337,32277,34314,20800,22725,25793,29934,29973,30320,32705,37013, 38605,39252,28198,29926,31401,31402,33253,34521,34680,35355,23113,23436,23451, 26785,26880,28003,29609,29715,29740,30871,32233,32747,33048,33109,33694,35916, 38446,38929,26352,24448,26106,26505,27754,29579,20525,23043,27498,30702,22806, 23916,24013,29477,30031,63930,63931,20709,20985,22575,22829,22934,23002,23525, 63932,63933,23970,25303,25622,25747,25854,63934,26332,63935,27208,63936,29183, 29796,63937,31368,31407,32327,32350,32768,33136,63938,34799,35201,35616,36953, 63939,36992,39250,24958,27442,28020,32287,35109,36785,20433,20653,20887,21191, 22471,22665,23481,24248,24898,27029,28044,28263,28342,29076,29794,29992,29996, 32883,33592,33993,36362,37780,37854,63940,20110,20305,20598,20778,21448,21451, 21491,23431,23507,23588,24858,24962,26100,29275,29591,29760,30402,31056,31121, 31161,32006,32701,33419,34261,34398,36802,36935,37109,37354,38533,38632,38633, 21206,24423,26093,26161,26671,29020,31286,37057,38922,20113,63941,27218,27550, 28560,29065,32792,33464,34131,36939,38549,38642,38907,34074,39729,20112,29066, 38596,20803,21407,21729,22291,22290,22435,23195,23236,23491,24616,24895,25588, 27781,27961,28274,28304,29232,29503,29783,33489,34945,36677,36960,63942,38498, 39000,40219,26376,36234,37470,20301,20553,20702,21361,22285,22996,23041,23561, 24944,26256,28205,29234,29771,32239,32963,33806,33894,34111,34655,34907,35096, 35586,36949,38859,39759,20083,20369,20754,20842,63943,21807,21929,23418,23461, 24188,24189,24254,24736,24799,24840,24841,25540,25912,26377,63944,26580,26586, 63945,26977,26978,27833,27943,63946,28216,63947,28641,29494,29495,63948,29788, 30001,63949,30290,63950,63951,32173,33278,33848,35029,35480,35547,35565,36400, 36418,36938,36926,36986,37193,37321,37742,63952,63953,22537,63954,27603,32905, 32946,63955,63956,20801,22891,23609,63957,63958,28516,29607,32996,36103,63959, 37399,38287,63960,63961,63962,63963,32895,25102,28700,32104,34701,63964,22432, 24681,24903,27575,35518,37504,38577,20057,21535,28139,34093,38512,38899,39150, 25558,27875,37009,20957,25033,33210,40441,20381,20506,20736,23452,24847,25087, 25836,26885,27589,30097,30691,32681,33380,34191,34811,34915,35516,35696,37291, 20108,20197,20234,63965,63966,22839,23016,63967,24050,24347,24411,24609,63968, 63969,63970,63971,29246,29669,63972,30064,30157,63973,31227,63974,32780,32819, 32900,33505,33617,63975,63976,36029,36019,36999,63977,63978,39156,39180,63979, 63980,28727,30410,32714,32716,32764,35610,20154,20161,20995,21360,63981,21693, 22240,23035,23493,24341,24525,28270,63982,63983,32106,33589,63984,34451,35469, 63985,38765,38775,63986,63987,19968,20314,20350,22777,26085,28322,36920,37808, 39353,20219,22764,22922,23001,24641,63988,63989,31252,63990,33615,36035,20837, 21316,63991,63992,63993,20173,21097,23381,33471,20180,21050,21672,22985,23039, 23376,23383,23388,24675,24904,28363,28825,29038,29574,29943,30133,30913,32043, 32773,33258,33576,34071,34249,35566,36039,38604,20316,21242,22204,26027,26152, 28796,28856,29237,32189,33421,37196,38592,40306,23409,26855,27544,28538,30430, 23697,26283,28507,31668,31786,34870,38620,19976,20183,21280,22580,22715,22767, 22892,23559,24115,24196,24373,25484,26290,26454,27167,27299,27404,28479,29254, 63994,29520,29835,31456,31911,33144,33247,33255,33674,33900,34083,34196,34255, 35037,36115,37292,38263,38556,20877,21705,22312,23472,25165,26448,26685,26771, 28221,28371,28797,32289,35009,36001,36617,40779,40782,29229,31631,35533,37658, 20295,20302,20786,21632,22992,24213,25269,26485,26990,27159,27822,28186,29401, 29482,30141,31672,32053,33511,33785,33879,34295,35419,36015,36487,36889,37048, 38606,40799,21219,21514,23265,23490,25688,25973,28404,29380,63995,30340,31309, 31515,31821,32318,32735,33659,35627,36042,36196,36321,36447,36842,36857,36969, 37841,20291,20346,20659,20840,20856,21069,21098,22625,22652,22880,23560,23637, 24283,24731,25136,26643,27583,27656,28593,29006,29728,30000,30008,30033,30322, 31564,31627,31661,31686,32399,35438,36670,36681,37439,37523,37666,37931,38651, 39002,39019,39198,20999,25130,25240,27993,30308,31434,31680,32118,21344,23742, 24215,28472,28857,31896,38673,39822,40670,25509,25722,34678,19969,20117,20141, 20572,20597,21576,22979,23450,24128,24237,24311,24449,24773,25402,25919,25972, 26060,26230,26232,26622,26984,27273,27491,27712,28096,28136,28191,28254,28702, 28833,29582,29693,30010,30555,30855,31118,31243,31357,31934,32142,33351,35330, 35562,35998,37165,37194,37336,37478,37580,37664,38662,38742,38748,38914,40718, 21046,21137,21884,22564,24093,24351,24716,25552,26799,28639,31085,31532,33229, 34234,35069,35576,36420,37261,38500,38555,38717,38988,40778,20430,20806,20939, 21161,22066,24340,24427,25514,25805,26089,26177,26362,26361,26397,26781,26839, 27133,28437,28526,29031,29157,29226,29866,30522,31062,31066,31199,31264,31381, 31895,31967,32068,32368,32903,34299,34468,35412,35519,36249,36481,36896,36973, 37347,38459,38613,40165,26063,31751,36275,37827,23384,23562,21330,25305,29469, 20519,23447,24478,24752,24939,26837,28121,29742,31278,32066,32156,32305,33131, 36394,36405,37758,37912,20304,22352,24038,24231,25387,32618,20027,20303,20367, 20570,23005,32964,21610,21608,22014,22863,23449,24030,24282,26205,26417,26609, 26666,27880,27954,28234,28557,28855,29664,30087,31820,32002,32044,32162,33311, 34523,35387,35461,36208,36490,36659,36913,37198,37202,37956,39376,31481,31909, 20426,20737,20934,22472,23535,23803,26201,27197,27994,28310,28652,28940,30063, 31459,34850,36897,36981,38603,39423,33537,20013,20210,34886,37325,21373,27355, 26987,27713,33914,22686,24974,26366,25327,28893,29969,30151,32338,33976,35657, 36104,20043,21482,21675,22320,22336,24535,25345,25351,25711,25903,26088,26234, 26525,26547,27490,27744,27802,28460,30693,30757,31049,31063,32025,32930,33026, 33267,33437,33463,34584,35468,63996,36100,36286,36978,30452,31257,31287,32340, 32887,21767,21972,22645,25391,25634,26185,26187,26733,27035,27524,27941,28337, 29645,29800,29857,30043,30137,30433,30494,30603,31206,32265,32285,33275,34095, 34967,35386,36049,36587,36784,36914,37805,38499,38515,38663,20356,21489,23018, 23241,24089,26702,29894,30142,31209,31378,33187,34541,36074,36300,36845,26015, 26389,63997,22519,28503,32221,36655,37878,38598,24501,25074,28548,19988,20376, 20511,21449,21983,23919,24046,27425,27492,30923,31642,63998,36425,36554,36974, 25417,25662,30528,31364,37679,38015,40810,25776,28591,29158,29864,29914,31428, 31762,32386,31922,32408,35738,36106,38013,39184,39244,21049,23519,25830,26413, 32046,20717,21443,22649,24920,24921,25082,26028,31449,35730,35734,20489,20513, 21109,21809,23100,24288,24432,24884,25950,26124,26166,26274,27085,28356,28466, 29462,30241,31379,33081,33369,33750,33980,20661,22512,23488,23528,24425,25505, 30758,32181,33756,34081,37319,37365,20874,26613,31574,36012,20932,22971,24765, 34389,20508,63999,21076,23610,24957,25114,25299,25842,26021,28364,30240,33034, 36448,38495,38587,20191,21315,21912,22825,24029,25797,27849,28154,29588,31359, 33307,34214,36068,36368,36983,37351,38369,38433,38854,20984,21746,21894,24505, 25764,28552,32180,36639,36685,37941,20681,23574,27838,28155,29979,30651,31805, 31844,35449,35522,22558,22974,24086,25463,29266,30090,30571,35548,36028,36626, 24307,26228,28152,32893,33729,35531,38737,39894,64000,21059,26367,28053,28399, 32224,35558,36910,36958,39636,21021,21119,21736,24980,25220,25307,26786,26898, 26970,27189,28818,28966,30813,30977,30990,31186,31245,32918,33400,33493,33609, 34121,35970,36229,37218,37259,37294,20419,22225,29165,30679,34560,35320,23544, 24534,26449,37032,21474,22618,23541,24740,24961,25696,32317,32880,34085,37507, 25774,20652,23828,26368,22684,25277,25512,26894,27000,27166,28267,30394,31179, 33467,33833,35535,36264,36861,37138,37195,37276,37648,37656,37786,38619,39478, 39949,19985,30044,31069,31482,31569,31689,32302,33988,36441,36468,36600,36880, 26149,26943,29763,20986,26414,40668,20805,24544,27798,34802,34909,34935,24756, 33205,33795,36101,21462,21561,22068,23094,23601,28810,32736,32858,33030,33261, 36259,37257,39519,40434,20596,20164,21408,24827,28204,23652,20360,20516,21988, 23769,24159,24677,26772,27835,28100,29118,30164,30196,30305,31258,31305,32199, 32251,32622,33268,34473,36636,38601,39347,40786,21063,21189,39149,35242,19971, 26578,28422,20405,23522,26517,27784,28024,29723,30759,37341,37756,34756,31204, 31281,24555,20182,21668,21822,22702,22949,24816,25171,25302,26422,26965,33333, 38464,39345,39389,20524,21331,21828,22396,64001,25176,64002,25826,26219,26589, 28609,28655,29730,29752,35351,37944,21585,22022,22374,24392,24986,27470,28760, 28845,32187,35477,22890,33067,25506,30472,32829,36010,22612,25645,27067,23445, 24081,28271,64003,34153,20812,21488,22826,24608,24907,27526,27760,27888,31518, 32974,33492,36294,37040,39089,64004,25799,28580,25745,25860,20814,21520,22303, 35342,24927,26742,64005,30171,31570,32113,36890,22534,27084,33151,35114,36864, 38969,20600,22871,22956,25237,36879,39722,24925,29305,38358,22369,23110,24052, 25226,25773,25850,26487,27874,27966,29228,29750,30772,32631,33453,36315,38935, 21028,22338,26495,29256,29923,36009,36774,37393,38442,20843,21485,25420,20329, 21764,24726,25943,27803,28031,29260,29437,31255,35207,35997,24429,28558,28921, 33192,24846,20415,20559,25153,29255,31687,32232,32745,36941,38829,39449,36022, 22378,24179,26544,33805,35413,21536,23318,24163,24290,24330,25987,32954,34109, 38281,38491,20296,21253,21261,21263,21638,21754,22275,24067,24598,25243,25265, 25429,64006,27873,28006,30129,30770,32990,33071,33502,33889,33970,34957,35090, 36875,37610,39165,39825,24133,26292,26333,28689,29190,64007,20469,21117,24426, 24915,26451,27161,28418,29922,31080,34920,35961,39111,39108,39491,21697,31263, 26963,35575,35914,39080,39342,24444,25259,30130,30382,34987,36991,38466,21305, 24380,24517,27852,29644,30050,30091,31558,33534,39325,20047,36924,19979,20309, 21414,22799,24264,26160,27827,29781,33655,34662,36032,36944,38686,39957,22737, 23416,34384,35604,40372,23506,24680,24717,26097,27735,28450,28579,28698,32597, 32752,38289,38290,38480,38867,21106,36676,20989,21547,21688,21859,21898,27323, 28085,32216,33382,37532,38519,40569,21512,21704,30418,34532,38308,38356,38492, 20130,20233,23022,23270,24055,24658,25239,26477,26689,27782,28207,32568,32923, 33322,64008,64009,38917,20133,20565,21683,22419,22874,23401,23475,25032,26999, 28023,28707,34809,35299,35442,35559,36994,39405,39608,21182,26680,20502,24184, 26447,33607,34892,20139,21521,22190,29670,37141,38911,39177,39255,39321,22099, 22687,34395,35377,25010,27382,29563,36562,27463,38570,39511,22869,29184,36203, 38761,20436,23796,24358,25080,26203,27883,28843,29572,29625,29694,30505,30541, 32067,32098,32291,33335,34898,64010,36066,37449,39023,23377,31348,34880,38913, 23244,20448,21332,22846,23805,25406,28025,29433,33029,33031,33698,37583,38960, 20136,20804,21009,22411,24418,27842,28366,28677,28752,28847,29074,29673,29801, 33610,34722,34913,36872,37026,37795,39336,20846,24407,24800,24935,26291,34137, 36426,37295,38795,20046,20114,21628,22741,22778,22909,23733,24359,25142,25160, 26122,26215,27627,28009,28111,28246,28408,28564,28640,28649,28765,29392,29733, 29786,29920,30355,31068,31946,32286,32993,33446,33899,33983,34382,34399,34676, 35703,35946,37804,38912,39013,24785,25110,37239,23130,26127,28151,28222,29759, 39746,24573,24794,31503,21700,24344,27742,27859,27946,28888,32005,34425,35340, 40251,21270,21644,23301,27194,28779,30069,31117,31166,33457,33775,35441,35649, 36008,38772,64011,25844,25899,30906,30907,31339,20024,21914,22864,23462,24187, 24739,25563,27489,26213,26707,28185,29029,29872,32008,36996,39529,39973,27963, 28369,29502,35905,38346,20976,24140,24488,24653,24822,24880,24908,26179,26180, 27045,27841,28255,28361,28514,29004,29852,30343,31681,31783,33618,34647,36945, 38541,40643,21295,22238,24315,24458,24674,24724,25079,26214,26371,27292,28142, 28590,28784,29546,32362,33214,33588,34516,35496,36036,21123,29554,23446,27243, 37892,21742,22150,23389,25928,25989,26313,26783,28045,28102,29243,32948,37237, 39501,20399,20505,21402,21518,21564,21897,21957,24127,24460,26429,29030,29661, 36869,21211,21235,22628,22734,28932,29071,29179,34224,35347,26248,34216,21927, 26244,29002,33841,21321,21913,27585,24409,24509,25582,26249,28999,35569,36637, 40638,20241,25658,28875,30054,34407,24676,35662,40440,20807,20982,21256,27958, 33016,40657,26133,27427,28824,30165,21507,23673,32007,35350,27424,27453,27462, 21560,24688,27965,32725,33288,20694,20958,21916,22123,22221,23020,23305,24076, 24985,24984,25137,26206,26342,29081,29113,29114,29351,31143,31232,32690,35440, ] const EucKREncode*: array[8226, UCS16x16] = [ (161u16,6379u16),(164u16,6385u16),(167u16,6230u16),(168u16,6182u16), (170u16,7508u16),(173u16,6184u16),(174u16,6436u16),(176u16,6213u16), (177u16,6205u16),(178u16,7782u16),(179u16,7783u16),(180u16,6370u16), (182u16,6415u16),(183u16,6179u16),(184u16,6377u16),(185u16,7781u16), (186u16,7517u16),(188u16,7594u16),(189u16,7591u16),(190u16,7595u16), (191u16,6380u16),(198u16,7506u16),(208u16,7507u16),(215u16,6206u16), (216u16,7515u16),(222u16,7518u16),(223u16,7707u16),(230u16,7696u16), (240u16,7698u16),(247u16,6207u16),(248u16,7705u16),(254u16,7708u16), (273u16,7697u16),(294u16,7509u16),(295u16,7699u16),(305u16,7700u16), (306u16,7511u16),(307u16,7701u16),(312u16,7702u16),(319u16,7513u16), (320u16,7703u16),(321u16,7514u16),(322u16,7704u16),(329u16,7711u16), (330u16,7520u16),(331u16,7710u16),(338u16,7516u16),(339u16,7706u16), (358u16,7519u16),(359u16,7709u16),(711u16,6372u16),(720u16,6381u16), (728u16,6373u16),(729u16,6376u16),(730u16,6375u16),(731u16,6378u16), (733u16,6374u16),(913u16,6968u16),(914u16,6969u16),(915u16,6970u16), (916u16,6971u16),(917u16,6972u16),(918u16,6973u16),(919u16,6974u16), (920u16,6975u16),(921u16,6976u16),(922u16,6977u16),(923u16,6978u16), (924u16,6979u16),(925u16,6980u16),(926u16,6981u16),(927u16,6982u16), (928u16,6983u16),(929u16,6984u16),(931u16,6985u16),(932u16,6986u16), (933u16,6987u16),(934u16,6988u16),(935u16,6989u16),(936u16,6990u16), (937u16,6991u16),(945u16,7000u16),(946u16,7001u16),(947u16,7002u16), (948u16,7003u16),(949u16,7004u16),(950u16,7005u16),(951u16,7006u16), (952u16,7007u16),(953u16,7008u16),(954u16,7009u16),(955u16,7010u16), (956u16,7011u16),(957u16,7012u16),(958u16,7013u16),(959u16,7014u16), (960u16,7015u16),(961u16,7016u16),(963u16,7017u16),(964u16,7018u16), (965u16,7019u16),(966u16,7020u16),(967u16,7021u16),(968u16,7022u16), (969u16,7023u16),(1025u16,8272u16),(1040u16,8266u16),(1041u16,8267u16), (1042u16,8268u16),(1043u16,8269u16),(1044u16,8270u16),(1045u16,8271u16), (1046u16,8273u16),(1047u16,8274u16),(1048u16,8275u16),(1049u16,8276u16), (1050u16,8277u16),(1051u16,8278u16),(1052u16,8279u16),(1053u16,8280u16), (1054u16,8281u16),(1055u16,8282u16),(1056u16,8283u16),(1057u16,8284u16), (1058u16,8285u16),(1059u16,8286u16),(1060u16,8287u16),(1061u16,8288u16), (1062u16,8289u16),(1063u16,8290u16),(1064u16,8291u16),(1065u16,8292u16), (1066u16,8293u16),(1067u16,8294u16),(1068u16,8295u16),(1069u16,8296u16), (1070u16,8297u16),(1071u16,8298u16),(1072u16,8314u16),(1073u16,8315u16), (1074u16,8316u16),(1075u16,8317u16),(1076u16,8318u16),(1077u16,8319u16), (1078u16,8321u16),(1079u16,8322u16),(1080u16,8323u16),(1081u16,8324u16), (1082u16,8325u16),(1083u16,8326u16),(1084u16,8327u16),(1085u16,8328u16), (1086u16,8329u16),(1087u16,8330u16),(1088u16,8331u16),(1089u16,8332u16), (1090u16,8333u16),(1091u16,8334u16),(1092u16,8335u16),(1093u16,8336u16), (1094u16,8337u16),(1095u16,8338u16),(1096u16,8339u16),(1097u16,8340u16), (1098u16,8341u16),(1099u16,8342u16),(1100u16,8343u16),(1101u16,8344u16), (1102u16,8345u16),(1103u16,8346u16),(1105u16,8320u16),(8213u16,6185u16), (8216u16,6189u16),(8217u16,6190u16),(8220u16,6191u16),(8221u16,6192u16), (8224u16,6416u16),(8225u16,6417u16),(8229u16,6180u16),(8230u16,6181u16), (8240u16,6387u16),(8242u16,6214u16),(8243u16,6215u16),(8251u16,6231u16), (8308u16,7784u16),(8319u16,7785u16),(8321u16,7786u16),(8322u16,7787u16), (8323u16,7788u16),(8324u16,7789u16),(8364u16,6435u16),(8451u16,6216u16), (8457u16,6386u16),(8467u16,7319u16),(8470u16,6429u16),(8481u16,6434u16), (8482u16,6431u16),(8486u16,7372u16),(8491u16,6217u16),(8531u16,7592u16), (8532u16,7593u16),(8539u16,7596u16),(8540u16,7597u16),(8541u16,7598u16), (8542u16,7599u16),(8544u16,6951u16),(8545u16,6952u16),(8546u16,6953u16), (8547u16,6954u16),(8548u16,6955u16),(8549u16,6956u16),(8550u16,6957u16), (8551u16,6958u16),(8552u16,6959u16),(8553u16,6960u16),(8560u16,6936u16), (8561u16,6937u16),(8562u16,6938u16),(8563u16,6939u16),(8564u16,6940u16), (8565u16,6941u16),(8566u16,6942u16),(8567u16,6943u16),(8568u16,6944u16), (8569u16,6945u16),(8592u16,6246u16),(8593u16,6247u16),(8594u16,6245u16), (8595u16,6248u16),(8596u16,6249u16),(8597u16,6418u16),(8598u16,6421u16), (8599u16,6419u16),(8600u16,6422u16),(8601u16,6420u16),(8658u16,6366u16), (8660u16,6367u16),(8704u16,6368u16),(8706u16,6226u16),(8707u16,6369u16), (8711u16,6227u16),(8712u16,6259u16),(8715u16,6260u16),(8719u16,6384u16), (8721u16,6383u16),(8730u16,6253u16),(8733u16,6255u16),(8734u16,6211u16), (8736u16,6223u16),(8741u16,6186u16),(8743u16,6267u16),(8744u16,6268u16), (8745u16,6266u16),(8746u16,6265u16),(8747u16,6257u16),(8748u16,6258u16), (8750u16,6382u16),(8756u16,6212u16),(8757u16,6256u16),(8764u16,6188u16), (8765u16,6254u16),(8786u16,6229u16),(8800u16,6208u16),(8801u16,6228u16), (8804u16,6209u16),(8805u16,6210u16),(8810u16,6251u16),(8811u16,6252u16), (8834u16,6263u16),(8835u16,6264u16),(8838u16,6261u16),(8839u16,6262u16), (8857u16,6398u16),(8869u16,6224u16),(8978u16,6225u16),(9312u16,7576u16), (9313u16,7577u16),(9314u16,7578u16),(9315u16,7579u16),(9316u16,7580u16), (9317u16,7581u16),(9318u16,7582u16),(9319u16,7583u16),(9320u16,7584u16), (9321u16,7585u16),(9322u16,7586u16),(9323u16,7587u16),(9324u16,7588u16), (9325u16,7589u16),(9326u16,7590u16),(9332u16,7766u16),(9333u16,7767u16), (9334u16,7768u16),(9335u16,7769u16),(9336u16,7770u16),(9337u16,7771u16), (9338u16,7772u16),(9339u16,7773u16),(9340u16,7774u16),(9341u16,7775u16), (9342u16,7776u16),(9343u16,7777u16),(9344u16,7778u16),(9345u16,7779u16), (9346u16,7780u16),(9372u16,7740u16),(9373u16,7741u16),(9374u16,7742u16), (9375u16,7743u16),(9376u16,7744u16),(9377u16,7745u16),(9378u16,7746u16), (9379u16,7747u16),(9380u16,7748u16),(9381u16,7749u16),(9382u16,7750u16), (9383u16,7751u16),(9384u16,7752u16),(9385u16,7753u16),(9386u16,7754u16), (9387u16,7755u16),(9388u16,7756u16),(9389u16,7757u16),(9390u16,7758u16), (9391u16,7759u16),(9392u16,7760u16),(9393u16,7761u16),(9394u16,7762u16), (9395u16,7763u16),(9396u16,7764u16),(9397u16,7765u16),(9424u16,7550u16), (9425u16,7551u16),(9426u16,7552u16),(9427u16,7553u16),(9428u16,7554u16), (9429u16,7555u16),(9430u16,7556u16),(9431u16,7557u16),(9432u16,7558u16), (9433u16,7559u16),(9434u16,7560u16),(9435u16,7561u16),(9436u16,7562u16), (9437u16,7563u16),(9438u16,7564u16),(9439u16,7565u16),(9440u16,7566u16), (9441u16,7567u16),(9442u16,7568u16),(9443u16,7569u16),(9444u16,7570u16), (9445u16,7571u16),(9446u16,7572u16),(9447u16,7573u16),(9448u16,7574u16), (9449u16,7575u16),(9472u16,7126u16),(9473u16,7137u16),(9474u16,7127u16), (9475u16,7138u16),(9484u16,7128u16),(9485u16,7165u16),(9486u16,7164u16), (9487u16,7139u16),(9488u16,7129u16),(9489u16,7159u16),(9490u16,7158u16), (9491u16,7140u16),(9492u16,7131u16),(9493u16,7163u16),(9494u16,7162u16), (9495u16,7142u16),(9496u16,7130u16),(9497u16,7161u16),(9498u16,7160u16), (9499u16,7141u16),(9500u16,7132u16),(9501u16,7153u16),(9502u16,7166u16), (9503u16,7167u16),(9504u16,7148u16),(9505u16,7168u16),(9506u16,7169u16), (9507u16,7143u16),(9508u16,7134u16),(9509u16,7155u16),(9510u16,7170u16), (9511u16,7171u16),(9512u16,7150u16),(9513u16,7172u16),(9514u16,7173u16), (9515u16,7145u16),(9516u16,7133u16),(9517u16,7174u16),(9518u16,7175u16), (9519u16,7149u16),(9520u16,7154u16),(9521u16,7176u16),(9522u16,7177u16), (9523u16,7144u16),(9524u16,7135u16),(9525u16,7178u16),(9526u16,7179u16), (9527u16,7151u16),(9528u16,7156u16),(9529u16,7180u16),(9530u16,7181u16), (9531u16,7146u16),(9532u16,7136u16),(9533u16,7182u16),(9534u16,7183u16), (9535u16,7152u16),(9536u16,7184u16),(9537u16,7185u16),(9538u16,7157u16), (9539u16,7186u16),(9540u16,7187u16),(9541u16,7188u16),(9542u16,7189u16), (9543u16,7190u16),(9544u16,7191u16),(9545u16,7192u16),(9546u16,7193u16), (9547u16,7147u16),(9618u16,6403u16),(9632u16,6240u16),(9633u16,6239u16), (9635u16,6400u16),(9636u16,6404u16),(9637u16,6405u16),(9638u16,6408u16), (9639u16,6407u16),(9640u16,6406u16),(9641u16,6409u16),(9650u16,6242u16), (9651u16,6241u16),(9654u16,6391u16),(9655u16,6390u16),(9660u16,6244u16), (9661u16,6243u16),(9664u16,6389u16),(9665u16,6388u16),(9670u16,6238u16), (9671u16,6237u16),(9672u16,6399u16),(9675u16,6234u16),(9678u16,6236u16), (9679u16,6235u16),(9680u16,6401u16),(9681u16,6402u16),(9733u16,6233u16), (9734u16,6232u16),(9742u16,6412u16),(9743u16,6411u16),(9756u16,6413u16), (9758u16,6414u16),(9792u16,6222u16),(9794u16,6221u16),(9824u16,6393u16), (9825u16,6394u16),(9827u16,6397u16),(9828u16,6392u16),(9829u16,6395u16), (9831u16,6396u16),(9832u16,6410u16),(9833u16,6424u16),(9834u16,6425u16), (9836u16,6426u16),(9837u16,6423u16),(12288u16,6176u16),(12289u16,6177u16), (12290u16,6178u16),(12291u16,6183u16),(12296u16,6195u16),(12297u16,6196u16), (12298u16,6197u16),(12299u16,6198u16),(12300u16,6199u16),(12301u16,6200u16), (12302u16,6201u16),(12303u16,6202u16),(12304u16,6203u16),(12305u16,6204u16), (12307u16,6250u16),(12308u16,6193u16),(12309u16,6194u16),(12353u16,7886u16), (12354u16,7887u16),(12355u16,7888u16),(12356u16,7889u16),(12357u16,7890u16), (12358u16,7891u16),(12359u16,7892u16),(12360u16,7893u16),(12361u16,7894u16), (12362u16,7895u16),(12363u16,7896u16),(12364u16,7897u16),(12365u16,7898u16), (12366u16,7899u16),(12367u16,7900u16),(12368u16,7901u16),(12369u16,7902u16), (12370u16,7903u16),(12371u16,7904u16),(12372u16,7905u16),(12373u16,7906u16), (12374u16,7907u16),(12375u16,7908u16),(12376u16,7909u16),(12377u16,7910u16), (12378u16,7911u16),(12379u16,7912u16),(12380u16,7913u16),(12381u16,7914u16), (12382u16,7915u16),(12383u16,7916u16),(12384u16,7917u16),(12385u16,7918u16), (12386u16,7919u16),(12387u16,7920u16),(12388u16,7921u16),(12389u16,7922u16), (12390u16,7923u16),(12391u16,7924u16),(12392u16,7925u16),(12393u16,7926u16), (12394u16,7927u16),(12395u16,7928u16),(12396u16,7929u16),(12397u16,7930u16), (12398u16,7931u16),(12399u16,7932u16),(12400u16,7933u16),(12401u16,7934u16), (12402u16,7935u16),(12403u16,7936u16),(12404u16,7937u16),(12405u16,7938u16), (12406u16,7939u16),(12407u16,7940u16),(12408u16,7941u16),(12409u16,7942u16), (12410u16,7943u16),(12411u16,7944u16),(12412u16,7945u16),(12413u16,7946u16), (12414u16,7947u16),(12415u16,7948u16),(12416u16,7949u16),(12417u16,7950u16), (12418u16,7951u16),(12419u16,7952u16),(12420u16,7953u16),(12421u16,7954u16), (12422u16,7955u16),(12423u16,7956u16),(12424u16,7957u16),(12425u16,7958u16), (12426u16,7959u16),(12427u16,7960u16),(12428u16,7961u16),(12429u16,7962u16), (12430u16,7963u16),(12431u16,7964u16),(12432u16,7965u16),(12433u16,7966u16), (12434u16,7967u16),(12435u16,7968u16),(12449u16,8076u16),(12450u16,8077u16), (12451u16,8078u16),(12452u16,8079u16),(12453u16,8080u16),(12454u16,8081u16), (12455u16,8082u16),(12456u16,8083u16),(12457u16,8084u16),(12458u16,8085u16), (12459u16,8086u16),(12460u16,8087u16),(12461u16,8088u16),(12462u16,8089u16), (12463u16,8090u16),(12464u16,8091u16),(12465u16,8092u16),(12466u16,8093u16), (12467u16,8094u16),(12468u16,8095u16),(12469u16,8096u16),(12470u16,8097u16), (12471u16,8098u16),(12472u16,8099u16),(12473u16,8100u16),(12474u16,8101u16), (12475u16,8102u16),(12476u16,8103u16),(12477u16,8104u16),(12478u16,8105u16), (12479u16,8106u16),(12480u16,8107u16),(12481u16,8108u16),(12482u16,8109u16), (12483u16,8110u16),(12484u16,8111u16),(12485u16,8112u16),(12486u16,8113u16), (12487u16,8114u16),(12488u16,8115u16),(12489u16,8116u16),(12490u16,8117u16), (12491u16,8118u16),(12492u16,8119u16),(12493u16,8120u16),(12494u16,8121u16), (12495u16,8122u16),(12496u16,8123u16),(12497u16,8124u16),(12498u16,8125u16), (12499u16,8126u16),(12500u16,8127u16),(12501u16,8128u16),(12502u16,8129u16), (12503u16,8130u16),(12504u16,8131u16),(12505u16,8132u16),(12506u16,8133u16), (12507u16,8134u16),(12508u16,8135u16),(12509u16,8136u16),(12510u16,8137u16), (12511u16,8138u16),(12512u16,8139u16),(12513u16,8140u16),(12514u16,8141u16), (12515u16,8142u16),(12516u16,8143u16),(12517u16,8144u16),(12518u16,8145u16), (12519u16,8146u16),(12520u16,8147u16),(12521u16,8148u16),(12522u16,8149u16), (12523u16,8150u16),(12524u16,8151u16),(12525u16,8152u16),(12526u16,8153u16), (12527u16,8154u16),(12528u16,8155u16),(12529u16,8156u16),(12530u16,8157u16), (12531u16,8158u16),(12532u16,8159u16),(12533u16,8160u16),(12534u16,8161u16), (12593u16,6746u16),(12594u16,6747u16),(12595u16,6748u16),(12596u16,6749u16), (12597u16,6750u16),(12598u16,6751u16),(12599u16,6752u16),(12600u16,6753u16), (12601u16,6754u16),(12602u16,6755u16),(12603u16,6756u16),(12604u16,6757u16), (12605u16,6758u16),(12606u16,6759u16),(12607u16,6760u16),(12608u16,6761u16), (12609u16,6762u16),(12610u16,6763u16),(12611u16,6764u16),(12612u16,6765u16), (12613u16,6766u16),(12614u16,6767u16),(12615u16,6768u16),(12616u16,6769u16), (12617u16,6770u16),(12618u16,6771u16),(12619u16,6772u16),(12620u16,6773u16), (12621u16,6774u16),(12622u16,6775u16),(12623u16,6776u16),(12624u16,6777u16), (12625u16,6778u16),(12626u16,6779u16),(12627u16,6780u16),(12628u16,6781u16), (12629u16,6782u16),(12630u16,6783u16),(12631u16,6784u16),(12632u16,6785u16), (12633u16,6786u16),(12634u16,6787u16),(12635u16,6788u16),(12636u16,6789u16), (12637u16,6790u16),(12638u16,6791u16),(12639u16,6792u16),(12640u16,6793u16), (12641u16,6794u16),(12642u16,6795u16),(12643u16,6796u16),(12644u16,6797u16), (12645u16,6798u16),(12646u16,6799u16),(12647u16,6800u16),(12648u16,6801u16), (12649u16,6802u16),(12650u16,6803u16),(12651u16,6804u16),(12652u16,6805u16), (12653u16,6806u16),(12654u16,6807u16),(12655u16,6808u16),(12656u16,6809u16), (12657u16,6810u16),(12658u16,6811u16),(12659u16,6812u16),(12660u16,6813u16), (12661u16,6814u16),(12662u16,6815u16),(12663u16,6816u16),(12664u16,6817u16), (12665u16,6818u16),(12666u16,6819u16),(12667u16,6820u16),(12668u16,6821u16), (12669u16,6822u16),(12670u16,6823u16),(12671u16,6824u16),(12672u16,6825u16), (12673u16,6826u16),(12674u16,6827u16),(12675u16,6828u16),(12676u16,6829u16), (12677u16,6830u16),(12678u16,6831u16),(12679u16,6832u16),(12680u16,6833u16), (12681u16,6834u16),(12682u16,6835u16),(12683u16,6836u16),(12684u16,6837u16), (12685u16,6838u16),(12686u16,6839u16),(12800u16,7712u16),(12801u16,7713u16), (12802u16,7714u16),(12803u16,7715u16),(12804u16,7716u16),(12805u16,7717u16), (12806u16,7718u16),(12807u16,7719u16),(12808u16,7720u16),(12809u16,7721u16), (12810u16,7722u16),(12811u16,7723u16),(12812u16,7724u16),(12813u16,7725u16), (12814u16,7726u16),(12815u16,7727u16),(12816u16,7728u16),(12817u16,7729u16), (12818u16,7730u16),(12819u16,7731u16),(12820u16,7732u16),(12821u16,7733u16), (12822u16,7734u16),(12823u16,7735u16),(12824u16,7736u16),(12825u16,7737u16), (12826u16,7738u16),(12827u16,7739u16),(12828u16,6428u16),(12896u16,7522u16), (12897u16,7523u16),(12898u16,7524u16),(12899u16,7525u16),(12900u16,7526u16), (12901u16,7527u16),(12902u16,7528u16),(12903u16,7529u16),(12904u16,7530u16), (12905u16,7531u16),(12906u16,7532u16),(12907u16,7533u16),(12908u16,7534u16), (12909u16,7535u16),(12910u16,7536u16),(12911u16,7537u16),(12912u16,7538u16), (12913u16,7539u16),(12914u16,7540u16),(12915u16,7541u16),(12916u16,7542u16), (12917u16,7543u16),(12918u16,7544u16),(12919u16,7545u16),(12920u16,7546u16), (12921u16,7547u16),(12922u16,7548u16),(12923u16,7549u16),(12927u16,6427u16), (13184u16,7356u16),(13185u16,7357u16),(13186u16,7358u16),(13187u16,7359u16), (13188u16,7360u16),(13192u16,7341u16),(13193u16,7342u16),(13194u16,7375u16), (13195u16,7376u16),(13196u16,7377u16),(13197u16,7337u16),(13198u16,7338u16), (13199u16,7339u16),(13200u16,7367u16),(13201u16,7368u16),(13202u16,7369u16), (13203u16,7370u16),(13204u16,7371u16),(13205u16,7316u16),(13206u16,7317u16), (13207u16,7318u16),(13208u16,7320u16),(13209u16,7326u16),(13210u16,7327u16), (13211u16,7328u16),(13212u16,7329u16),(13213u16,7330u16),(13214u16,7331u16), (13215u16,7332u16),(13216u16,7333u16),(13217u16,7334u16),(13218u16,7335u16), (13219u16,7322u16),(13220u16,7323u16),(13221u16,7324u16),(13222u16,7325u16), (13223u16,7344u16),(13224u16,7345u16),(13225u16,7384u16),(13226u16,7385u16), (13227u16,7386u16),(13228u16,7387u16),(13229u16,7380u16),(13230u16,7381u16), (13231u16,7382u16),(13232u16,7346u16),(13233u16,7347u16),(13234u16,7348u16), (13235u16,7349u16),(13236u16,7350u16),(13237u16,7351u16),(13238u16,7352u16), (13239u16,7353u16),(13240u16,7354u16),(13241u16,7355u16),(13242u16,7361u16), (13243u16,7362u16),(13244u16,7363u16),(13245u16,7364u16),(13246u16,7365u16), (13247u16,7366u16),(13248u16,7373u16),(13249u16,7374u16),(13250u16,6432u16), (13251u16,7391u16),(13252u16,7321u16),(13253u16,7379u16),(13254u16,7394u16), (13255u16,6430u16),(13256u16,7343u16),(13257u16,7392u16),(13258u16,7336u16), (13263u16,7340u16),(13264u16,7389u16),(13267u16,7390u16),(13270u16,7378u16), (13272u16,6433u16),(13275u16,7383u16),(13276u16,7393u16),(13277u16,7388u16), (19968u16,20498u16),(19969u16,21038u16),(19971u16,22375u16),(19975u16,16643u16), (19976u16,20674u16),(19977u16,17973u16),(19978u16,17985u16),(19979u16,22922u16), (19981u16,17469u16),(19985u16,22203u16),(19988u16,21761u16),(19989u16,17639u16), (19990u16,18341u16),(19992u16,14813u16),(19993u16,17401u16),(19998u16,18725u16), (20013u16,21448u16),(20018u16,14625u16),(20024u16,23480u16),(20025u16,15676u16), (20027u16,21386u16),(20034u16,19524u16),(20035u16,15497u16),(20037u16,14814u16), (20043u16,21468u16),(20045u16,17796u16),(20046u16,23301u16),(20047u16,22920u16), (20054u16,14775u16),(20056u16,18726u16),(20057u16,20299u16),(20061u16,14815u16), (20062u16,14242u16),(20063u16,19100u16),(20075u16,14030u16),(20077u16,15909u16), (20083u16,20110u16),(20086u16,17452u16),(20087u16,17968u16),(20094u16,14230u16), (20098u16,16070u16),(20102u16,16330u16),(20104u16,19183u16),(20107u16,17797u16), (20108u16,20428u16),(20110u16,19900u16),(20112u16,20052u16),(20113u16,19941u16), (20114u16,23302u16),(20116u16,19548u16),(20117u16,21039u16),(20120u16,15175u16), (20123u16,17798u16),(20126u16,18917u16),(20129u16,16669u16),(20130u16,22976u16), (20132u16,14788u16),(20133u16,23089u16),(20134u16,19303u16),(20136u16,23176u16), (20139u16,23114u16),(20140u16,14385u16),(20141u16,21040u16),(20142u16,16108u16), (20150u16,15677u16),(20154u16,20474u16),(20160u16,18912u16),(20161u16,20475u16), (20164u16,22342u16),(20167u16,14816u16),(20170u16,15154u16),(20171u16,14186u16), (20173u16,20619u16),(20180u16,20623u16),(20181u16,17799u16),(20182u16,22391u16), (20183u16,20675u16),(20184u16,17470u16),(20185u16,18170u16),(20189u16,15911u16), (20191u16,21966u16),(20195u16,15734u16),(20196u16,16266u16),(20197u16,20429u16), (20208u16,18975u16),(20210u16,21449u16),(20214u16,14231u16),(20215u16,14187u16), (20219u16,20507u16),(20225u16,15179u16),(20233u16,22977u16),(20234u16,20430u16), (20235u16,15168u16),(20237u16,19549u16),(20238u16,15180u16),(20239u16,17434u16), (20240u16,17268u16),(20241u16,23699u16),(20271u16,17250u16),(20276u16,17070u16), (20278u16,16267u16),(20280u16,18778u16),(20282u16,17800u16),(20284u16,17801u16), (20285u16,13966u16),(20291u16,20881u16),(20294u16,15678u16),(20295u16,20828u16), (20296u16,22752u16),(20301u16,20085u16),(20302u16,20829u16),(20303u16,21387u16), (20304u16,21380u16),(20305u16,19901u16),(20309u16,22923u16),(20313u16,19184u16), (20314u16,20499u16),(20315u16,17629u16),(20316u16,20649u16),(20329u16,22710u16), (20335u16,19121u16),(20336u16,17251u16),(20339u16,13967u16),(20342u16,15340u16), (20346u16,20882u16),(20350u16,20500u16),(20351u16,17802u16),(20353u16,18779u16), (20355u16,14006u16),(20356u16,21638u16),(20358u16,16101u16),(20360u16,22347u16), (20362u16,14759u16),(20363u16,16284u16),(20365u16,18735u16),(20367u16,21388u16), (20369u16,20111u16),(20374u16,16469u16),(20376u16,21762u16),(20379u16,14609u16), (20381u16,20313u16),(20398u16,16833u16),(20399u16,23660u16),(20405u16,22378u16), (20406u16,16121u16),(20415u16,22726u16),(20418u16,14430u16),(20419u16,22156u16), (20420u16,18918u16),(20425u16,19550u16),(20426u16,21428u16),(20430u16,21212u16), (20433u16,19876u16),(20435u16,14386u16),(20436u16,23138u16),(20439u16,18387u16), (20442u16,16489u16),(20445u16,17418u16),(20447u16,17803u16),(20448u16,23164u16), (20449u16,18780u16),(20462u16,18418u16),(20463u16,17471u16),(20465u16,14817u16), (20467u16,17231u16),(20469u16,22786u16),(20472u16,17453u16),(20474u16,19174u16), (20482u16,17402u16),(20486u16,16109u16),(20489u16,21813u16),(20491u16,14188u16), (20493u16,17230u16),(20497u16,16905u16),(20498u16,15753u16),(20502u16,23109u16), (20505u16,23661u16),(20506u16,20314u16),(20508u16,21951u16),(20510u16,14387u16), (20511u16,21763u16),(20513u16,21814u16),(20515u16,17202u16),(20516u16,22348u16), (20518u16,14985u16),(20519u16,21267u16),(20520u16,14213u16),(20522u16,19525u16), (20523u16,16470u16),(20524u16,22405u16),(20525u16,19727u16),(20539u16,19101u16), (20547u16,19166u16),(20551u16,13968u16),(20552u16,14352u16),(20553u16,20086u16), (20559u16,22727u16),(20565u16,23090u16),(20570u16,21389u16),(20572u16,21041u16), (20581u16,14232u16),(20596u16,22341u16),(20597u16,21042u16),(20598u16,19902u16), (20600u16,22577u16),(20608u16,14776u16),(20613u16,17472u16),(20621u16,17203u16), (20625u16,14243u16),(20632u16,17956u16),(20633u16,17640u16),(20652u16,22177u16), (20653u16,19877u16),(20658u16,19551u16),(20659u16,20883u16),(20661u16,21835u16), (20663u16,17986u16),(20670u16,14388u16),(20677u16,15138u16),(20681u16,21995u16), (20682u16,18171u16),(20687u16,17987u16),(20689u16,14789u16),(20693u16,17435u16), (20694u16,23729u16),(20698u16,16331u16),(20702u16,20087u16),(20709u16,19738u16), (20711u16,18727u16),(20717u16,21803u16),(20729u16,13969u16),(20731u16,17283u16), (20735u16,17804u16),(20736u16,20315u16),(20737u16,21429u16),(20740u16,19161u16), (20742u16,14389u16),(20745u16,14246u16),(20754u16,20112u16),(20767u16,17988u16), (20769u16,16322u16),(20778u16,19903u16),(20786u16,20830u16),(20791u16,16122u16), (20794u16,15346u16),(20796u16,19175u16),(20800u16,19685u16),(20801u16,20270u16), (20803u16,20055u16),(20804u16,23177u16),(20805u16,22221u16),(20806u16,21213u16), (20807u16,23707u16),(20808u16,18172u16),(20809u16,14760u16),(20811u16,15131u16), (20812u16,22541u16),(20813u16,16708u16),(20814u16,22560u16),(20818u16,18919u16), (20828u16,15928u16),(20834u16,15176u16),(20837u16,20518u16),(20839u16,15499u16), (20840u16,20884u16),(20841u16,16110u16),(20842u16,20113u16),(20843u16,22707u16), (20844u16,14610u16),(20845u16,16466u16),(20846u16,23292u16),(20849u16,14611u16), (20853u16,17403u16),(20854u16,15181u16),(20855u16,14818u16),(20856u16,20885u16), (20860u16,14379u16),(20864u16,15182u16),(20870u16,19182u16),(20874u16,21847u16), (20877u16,20807u16),(20882u16,16834u16),(20885u16,16709u16),(20887u16,19878u16), (20896u16,14739u16),(20901u16,16817u16),(20906u16,16706u16),(20908u16,15912u16), (20918u16,19102u16),(20919u16,16105u16),(20925u16,16254u16),(20932u16,21947u16), (20934u16,21430u16),(20937u16,16111u16),(20939u16,21214u16),(20940u16,16483u16), (20941u16,15913u16),(20956u16,16482u16),(20957u16,20309u16),(20958u16,23730u16), (20961u16,17272u16),(20976u16,23502u16),(20977u16,14189u16),(20982u16,23708u16), (20984u16,21985u16),(20985u16,19739u16),(20986u16,22218u16),(20989u16,22957u16), (20992u16,15754u16),(20995u16,20476u16),(20998u16,17609u16),(20999u16,21018u16), (21000u16,19527u16),(21002u16,14007u16),(21006u16,16906u16),(21009u16,23178u16), (21015u16,16255u16),(21021u16,22033u16),(21028u16,22602u16),(21029u16,17397u16), (21033u16,16490u16),(21034u16,17957u16),(21038u16,14755u16),(21040u16,15755u16), (21046u16,21189u16),(21047u16,18411u16),(21048u16,14986u16),(21049u16,21798u16), (21050u16,20624u16),(21051u16,13995u16),(21059u16,22024u16),(21063u16,22371u16), (21066u16,17856u16),(21067u16,15132u16),(21068u16,16078u16),(21069u16,20886u16), (21076u16,21953u16),(21078u16,17473u16),(21083u16,14162u16),(21085u16,17051u16), (21089u16,18215u16),(21097u16,20620u16),(21098u16,20887u16),(21103u16,17474u16), (21106u16,22955u16),(21109u16,21815u16),(21117u16,22787u16),(21119u16,22034u16), (21123u16,23546u16),(21127u16,15133u16),(21128u16,17284u16),(21129u16,16452u16), (21133u16,14247u16),(21137u16,21190u16),(21138u16,14248u16),(21147u16,16139u16), (21151u16,14612u16),(21152u16,13970u16),(21155u16,16256u16),(21156u16,15139u16), (21161u16,21215u16),(21162u16,15514u16),(21163u16,14349u16),(21182u16,23107u16), (21185u16,14390u16),(21187u16,17095u16),(21189u16,22372u16),(21191u16,19879u16), (21193u16,16710u16),(21197u16,14391u16),(21202u16,16480u16),(21205u16,15914u16), (21206u16,19932u16),(21208u16,14040u16),(21209u16,16881u16),(21211u16,23673u16), (21213u16,18728u16),(21214u16,16289u16),(21215u16,16835u16),(21218u16,18342u16), (21219u16,20856u16),(21220u16,15140u16),(21235u16,23674u16),(21237u16,16123u16), (21240u16,14987u16),(21242u16,20650u16),(21243u16,15123u16),(21246u16,14819u16), (21247u16,17013u16),(21253u16,22753u16),(21256u16,23709u16),(21261u16,22754u16), (21263u16,22755u16),(21264u16,17436u16),(21269u16,17641u16),(21270u16,23364u16), (21271u16,17608u16),(21273u16,18736u16),(21280u16,20676u16),(21281u16,14761u16), (21283u16,14156u16),(21290u16,17642u16),(21295u16,23526u16),(21305u16,22910u16), (21311u16,15576u16),(21312u16,14916u16),(21313u16,18913u16),(21315u16,21967u16), (21316u16,20519u16),(21319u16,18729u16),(21320u16,19552u16),(21321u16,23688u16), (21322u16,17071u16),(21325u16,16644u16),(21329u16,17643u16),(21330u16,21264u16), (21331u16,22406u16),(21332u16,23165u16),(21335u16,15380u16),(21338u16,17052u16), (21340u16,17437u16),(21342u16,17391u16),(21344u16,21026u16),(21350u16,14772u16), (21352u16,18202u16),(21359u16,16869u16),(21360u16,20477u16),(21361u16,20088u16), (21364u16,13996u16),(21365u16,16071u16),(21367u16,14988u16),(21373u16,21452u16), (21375u16,14392u16),(21380u16,18993u16),(21395u16,18982u16),(21400u16,16491u16), (21402u16,23662u16),(21407u16,20056u16),(21408u16,22343u16),(21413u16,14995u16), (21414u16,22924u16),(21421u16,19369u16),(21435u16,14214u16),(21443u16,21804u16), (21448u16,19904u16),(21449u16,21764u16),(21450u16,15169u16),(21451u16,19905u16), (21453u16,17072u16),(21460u16,18575u16),(21462u16,22327u16),(21463u16,18419u16), (21467u16,17073u16),(21473u16,19528u16),(21474u16,22166u16),(21475u16,14917u16), (21476u16,14550u16),(21477u16,14918u16),(21481u16,14551u16),(21482u16,21469u16), (21483u16,15108u16),(21484u16,18350u16),(21485u16,22708u16),(21487u16,13971u16), (21488u16,22542u16),(21489u16,21639u16),(21490u16,17805u16),(21491u16,19906u16), (21496u16,17806u16),(21507u16,23717u16),(21508u16,13997u16),(21512u16,22969u16), (21513u16,15341u16),(21514u16,20857u16),(21516u16,15915u16),(21517u16,16818u16), (21518u16,23663u16),(21519u16,16492u16),(21520u16,22561u16),(21521u16,23115u16), (21531u16,14969u16),(21533u16,16515u16),(21535u16,20300u16),(21536u16,22742u16), (21542u16,17475u16),(21545u16,17610u16),(21547u16,22958u16),(21555u16,19554u16), (21560u16,23724u16),(21561u16,22328u16),(21563u16,16907u16),(21564u16,23664u16), (21566u16,19553u16),(21570u16,16124u16),(21576u16,21043u16),(21578u16,14552u16), (21585u16,22517u16),(21608u16,21393u16),(21610u16,21392u16),(21617u16,14553u16), (21619u16,17016u16),(21621u16,13972u16),(21627u16,18781u16),(21628u16,23303u16), (21629u16,16819u16),(21632u16,20831u16),(21638u16,22756u16),(21644u16,23365u16), (21646u16,14919u16),(21648u16,17476u16),(21668u16,22392u16),(21672u16,20625u16), (21675u16,21566u16),(21676u16,14790u16),(21683u16,23091u16),(21688u16,22959u16), (21693u16,20479u16),(21696u16,18983u16),(21697u16,22896u16),(21700u16,23354u16), (21704u16,22970u16),(21705u16,20808u16),(21729u16,20057u16),(21733u16,13973u16), (21736u16,22035u16),(21741u16,14589u16),(21742u16,23551u16),(21746u16,21986u16), (21754u16,22757u16),(21764u16,22711u16),(21766u16,17807u16),(21767u16,21603u16), (21774u16,16493u16),(21776u16,15723u16),(21788u16,16662u16),(21807u16,20115u16), (21809u16,21816u16),(21813u16,18963u16),(21822u16,22393u16),(21828u16,22407u16), (21830u16,17989u16),(21839u16,16908u16),(21843u16,14431u16),(21846u16,15701u16), (21854u16,18920u16),(21859u16,22960u16),(21884u16,21191u16),(21888u16,14206u16), (21892u16,18173u16),(21894u16,21987u16),(21895u16,15955u16),(21897u16,23665u16), (21898u16,22961u16),(21912u16,21968u16),(21913u16,23689u16),(21914u16,23481u16), (21916u16,23731u16),(21917u16,14031u16),(21927u16,23684u16),(21929u16,20116u16), (21930u16,17990u16),(21931u16,15345u16),(21932u16,14791u16),(21934u16,15679u16), (21957u16,23666u16),(21959u16,18019u16),(21972u16,21604u16),(21978u16,19555u16), (21980u16,15183u16),(21983u16,21765u16),(21987u16,17808u16),(21988u16,22349u16), (22013u16,18420u16),(22014u16,21394u16),(22022u16,22518u16),(22025u16,13974u16), (22036u16,14920u16),(22039u16,17991u16),(22063u16,18351u16),(22066u16,21216u16), (22068u16,22329u16),(22070u16,18737u16),(22099u16,23123u16),(22120u16,15184u16), (22123u16,23732u16),(22132u16,17611u16),(22150u16,23552u16),(22181u16,19316u16), (22188u16,17778u16),(22190u16,23116u16),(22196u16,19176u16),(22204u16,20651u16), (22218u16,15490u16),(22221u16,23733u16),(22225u16,22157u16),(22234u16,18421u16), (22235u16,17809u16),(22238u16,23527u16),(22240u16,20480u16),(22256u16,14596u16), (22265u16,16268u16),(22266u16,14554u16),(22275u16,22758u16),(22276u16,19151u16), (22280u16,14989u16),(22283u16,14963u16),(22285u16,20089u16),(22290u16,20059u16), (22291u16,20058u16),(22294u16,15756u16),(22296u16,15680u16),(22303u16,22562u16), (22312u16,20809u16),(22317u16,15109u16),(22320u16,21567u16),(22331u16,15185u16), (22336u16,21568u16),(22338u16,22603u16),(22343u16,15124u16),(22346u16,17204u16), (22349u16,15702u16),(22350u16,14041u16),(22352u16,21381u16),(22353u16,14208u16), (22369u16,22586u16),(22372u16,14597u16),(22374u16,22519u16),(22378u16,22737u16), (22382u16,15736u16),(22384u16,14393u16),(22389u16,14921u16),(22396u16,22408u16), (22402u16,18422u16),(22408u16,15735u16),(22411u16,23179u16),(22419u16,23092u16), (22432u16,20292u16),(22434u16,14922u16),(22435u16,20060u16),(22467u16,18984u16), (22471u16,19880u16),(22472u16,21431u16),(22475u16,16681u16),(22478u16,18227u16), (22495u16,19305u16),(22496u16,17477u16),(22512u16,21836u16),(22516u16,18763u16), (22519u16,21656u16),(22521u16,17233u16),(22522u16,15186u16),(22524u16,15187u16), (22528u16,14975u16),(22530u16,15724u16),(22533u16,14362u16),(22534u16,22571u16), (22536u16,14163u16),(22537u16,20263u16),(22538u16,18935u16),(22558u16,22005u16), (22561u16,17419u16),(22564u16,21192u16),(22567u16,19317u16),(22570u16,14042u16), (22575u16,19740u16),(22576u16,19167u16),(22577u16,17420u16),(22580u16,20677u16), (22581u16,15757u16),(22586u16,14432u16),(22602u16,14777u16),(22603u16,19486u16), (22607u16,14190u16),(22609u16,18352u16),(22612u16,22533u16),(22615u16,15758u16), (22616u16,15725u16),(22618u16,22167u16),(22622u16,18016u16),(22625u16,20888u16), (22626u16,19556u16),(22628u16,23675u16),(22645u16,21605u16),(22649u16,21805u16), (22652u16,20889u16),(22654u16,18576u16),(22659u16,14394u16),(22661u16,18029u16), (22665u16,19881u16),(22675u16,16870u16),(22684u16,22180u16),(22686u16,21457u16), (22687u16,23124u16),(22696u16,16903u16),(22697u16,15899u16),(22702u16,22394u16), (22707u16,17612u16),(22714u16,19557u16),(22715u16,20678u16),(22718u16,14008u16), (22721u16,17285u16),(22725u16,19686u16),(22727u16,15681u16),(22734u16,23676u16), (22737u16,22936u16),(22739u16,18971u16),(22741u16,23304u16),(22744u16,16439u16), (22745u16,14762u16),(22750u16,14778u16),(22751u16,16315u16),(22756u16,19124u16), (22763u16,17810u16),(22764u16,20508u16),(22767u16,20679u16),(22777u16,20501u16), (22778u16,23305u16),(22779u16,18030u16),(22781u16,18423u16),(22799u16,22925u16), (22804u16,15188u16),(22805u16,18155u16),(22806u16,19731u16),(22809u16,18577u16), (22810u16,15578u16),(22812u16,19103u16),(22818u16,16866u16),(22823u16,15737u16), (22825u16,21969u16),(22826u16,22543u16),(22827u16,17478u16),(22829u16,19741u16), (22830u16,18976u16),(22833u16,18802u16),(22839u16,20433u16),(22846u16,23166u16), (22852u16,19177u16),(22855u16,15189u16),(22856u16,15500u16),(22857u16,17454u16), (22862u16,15110u16),(22863u16,21395u16),(22864u16,23482u16),(22865u16,14433u16), (22868u16,17613u16),(22869u16,23134u16),(22871u16,22578u16),(22874u16,23093u16), (22880u16,20890u16),(22882u16,17811u16),(22887u16,19558u16),(22890u16,22527u16), (22891u16,20271u16),(22892u16,20680u16),(22893u16,18156u16),(22894u16,17614u16), (22899u16,15504u16),(22900u16,15516u16),(22904u16,14009u16),(22909u16,23306u16), (22914u16,19188u16),(22915u16,17644u16),(22916u16,16670u16),(22922u16,20509u16), (22931u16,15190u16),(22934u16,19742u16),(22935u16,15155u16),(22937u16,16871u16), (22949u16,22395u16),(22952u16,17205u16),(22956u16,22579u16),(22969u16,16682u16), (22971u16,21948u16),(22974u16,22006u16),(22979u16,21044u16),(22982u16,16836u16), (22985u16,20626u16),(22987u16,18738u16),(22992u16,20832u16),(22993u16,14555u16), (22995u16,18228u16),(22996u16,20090u16),(23001u16,20510u16),(23002u16,19743u16), (23004u16,14164u16),(23005u16,21390u16),(23014u16,14010u16),(23016u16,20434u16), (23018u16,21640u16),(23020u16,23734u16),(23022u16,22978u16),(23032u16,19318u16), (23035u16,20481u16),(23039u16,20627u16),(23041u16,20091u16),(23043u16,19728u16), (23057u16,17812u16),(23064u16,15491u16),(23067u16,19559u16),(23068u16,15349u16), (23071u16,19319u16),(23072u16,18782u16),(23077u16,18921u16),(23081u16,16645u16), (23094u16,22330u16),(23100u16,21817u16),(23105u16,16440u16),(23110u16,22587u16), (23113u16,19703u16),(23130u16,23345u16),(23138u16,17645u16),(23142u16,17479u16), (23186u16,16683u16),(23194u16,17017u16),(23195u16,20061u16),(23204u16,18739u16), (23233u16,13975u16),(23234u16,18424u16),(23236u16,20062u16),(23241u16,21641u16), (23244u16,23163u16),(23265u16,20858u16),(23270u16,22979u16),(23273u16,15561u16), (23301u16,23366u16),(23305u16,23735u16),(23307u16,18174u16),(23308u16,14792u16), (23318u16,22743u16),(23338u16,17779u16),(23360u16,17992u16),(23363u16,19125u16), (23376u16,20628u16),(23377u16,23159u16),(23380u16,14613u16),(23381u16,20621u16), (23383u16,20629u16),(23384u16,21262u16),(23386u16,17576u16),(23388u16,20630u16), (23389u16,23553u16),(23391u16,16700u16),(23395u16,14434u16),(23396u16,14556u16), (23401u16,23094u16),(23403u16,18396u16),(23408u16,18578u16),(23409u16,20662u16), (23413u16,17577u16),(23416u16,22937u16),(23418u16,20117u16),(23420u16,19172u16), (23429u16,15750u16),(23431u16,19907u16),(23432u16,18425u16),(23433u16,18949u16), (23435u16,18403u16),(23436u16,19704u16),(23439u16,14784u16),(23443u16,17438u16), (23445u16,22536u16),(23446u16,23548u16),(23447u16,21268u16),(23448u16,14740u16), (23449u16,21396u16),(23450u16,21045u16),(23451u16,19705u16),(23452u16,20316u16), (23458u16,14207u16),(23459u16,18175u16),(23460u16,18803u16),(23461u16,20118u16), (23462u16,23483u16),(23468u16,18229u16),(23470u16,14979u16),(23472u16,20810u16), (23475u16,23095u16),(23476u16,19320u16),(23477u16,18353u16),(23478u16,13976u16), (23480u16,18783u16),(23481u16,19882u16),(23487u16,18579u16),(23488u16,21837u16), (23490u16,20859u16),(23491u16,20063u16),(23492u16,15191u16),(23493u16,20482u16), (23494u16,17048u16),(23495u16,14923u16),(23500u16,17578u16),(23504u16,16684u16), (23506u16,22941u16),(23507u16,19908u16),(23508u16,18764u16),(23511u16,15513u16), (23518u16,16637u16),(23519u16,21799u16),(23521u16,14626u16),(23522u16,22379u16), (23524u16,19560u16),(23525u16,19744u16),(23526u16,18804u16),(23527u16,15512u16), (23528u16,21838u16),(23529u16,18806u16),(23531u16,17813u16),(23532u16,14741u16), (23534u16,16332u16),(23535u16,21432u16),(23541u16,22168u16),(23542u16,17421u16), (23544u16,22162u16),(23546u16,17814u16),(23553u16,17455u16),(23556u16,17815u16), (23559u16,20681u16),(23560u16,20891u16),(23561u16,20092u16),(23562u16,21263u16), (23563u16,18807u16),(23565u16,15738u16),(23566u16,15759u16),(23567u16,18354u16), (23569u16,18355u16),(23574u16,21996u16),(23577u16,17993u16),(23588u16,19909u16), (23592u16,17206u16),(23601u16,22331u16),(23608u16,18740u16),(23609u16,20272u16), (23610u16,21954u16),(23611u16,14557u16),(23612u16,15574u16),(23614u16,17018u16), (23615u16,15552u16),(23616u16,14964u16),(23621u16,14215u16),(23622u16,14435u16), (23624u16,14976u16),(23627u16,19674u16),(23629u16,18742u16),(23630u16,18741u16), (23633u16,18203u16),(23637u16,20892u16),(23643u16,17404u16),(23648u16,15760u16), (23650u16,16441u16),(23652u16,22346u16),(23653u16,16494u16),(23660u16,18388u16), (23663u16,15939u16),(23665u16,17958u16),(23673u16,23718u16),(23696u16,15192u16), (23697u16,20667u16),(23713u16,14165u16),(23721u16,18964u16),(23723u16,18426u16), (23724u16,14157u16),(23729u16,15739u16),(23731u16,18936u16),(23733u16,23307u16), (23735u16,17035u16),(23736u16,18950u16),(23738u16,16270u16),(23742u16,21027u16), (23744u16,18427u16),(23769u16,22350u16),(23776u16,17994u16),(23784u16,18922u16), (23791u16,17456u16),(23792u16,17457u16),(23796u16,23139u16),(23798u16,15761u16), (23803u16,21433u16),(23805u16,23167u16),(23815u16,18618u16),(23821u16,16102u16), (23822u16,15193u16),(23825u16,14598u16),(23828u16,22178u16),(23830u16,18985u16), (23831u16,14166u16),(23833u16,16471u16),(23847u16,18619u16),(23849u16,17633u16), (23883u16,17019u16),(23884u16,14043u16),(23888u16,16080u16),(23913u16,18716u16), (23916u16,19732u16),(23919u16,21766u16),(23943u16,14924u16),(23947u16,15762u16), (23965u16,15946u16),(23968u16,14793u16),(23970u16,19747u16),(23978u16,19180u16), (23992u16,19489u16),(23994u16,16271u16),(23996u16,18031u16),(23997u16,18937u16), (24013u16,19733u16),(24018u16,16646u16),(24022u16,18965u16),(24029u16,21970u16), (24030u16,21397u16),(24033u16,18587u16),(24034u16,18356u16),(24037u16,14614u16), (24038u16,21382u16),(24039u16,14794u16),(24040u16,14216u16),(24043u16,16882u16), (24046u16,21767u16),(24049u16,15194u16),(24050u16,20436u16),(24051u16,17816u16), (24052u16,22588u16),(24055u16,22980u16),(24061u16,18397u16),(24062u16,14233u16), (24066u16,18743u16),(24067u16,22759u16),(24070u16,17273u16),(24076u16,23736u16), (24081u16,22537u16),(24086u16,22007u16),(24089u16,21642u16),(24091u16,17252u16), (24093u16,21193u16),(24101u16,18428u16),(24107u16,17817u16),(24109u16,18157u16), (24115u16,20682u16),(24118u16,15740u16),(24120u16,17995u16),(24125u16,16837u16), (24127u16,23667u16),(24128u16,21046u16),(24132u16,18938u16),(24133u16,22780u16), (24135u16,17207u16),(24140u16,23503u16),(24149u16,16638u16),(24159u16,22351u16), (24161u16,17258u16),(24162u16,15726u16),(24163u16,22744u16),(24178u16,14011u16), (24179u16,22738u16),(24180u16,15505u16),(24183u16,17405u16),(24184u16,23110u16), (24185u16,14012u16),(24187u16,23484u16),(24188u16,20119u16),(24189u16,20120u16), (24190u16,15195u16),(24196u16,20683u16),(24199u16,17646u16),(24202u16,17996u16), (24207u16,18032u16),(24213u16,20833u16),(24215u16,21028u16),(24218u16,14395u16), (24220u16,17579u16),(24224u16,17997u16),(24230u16,15763u16),(24231u16,21383u16), (24235u16,14558u16),(24237u16,21047u16),(24245u16,18966u16),(24246u16,18033u16), (24247u16,14167u16),(24248u16,19883u16),(24254u16,20121u16),(24258u16,17998u16), (24264u16,22926u16),(24265u16,16260u16),(24266u16,16093u16),(24272u16,14925u16), (24275u16,14734u16),(24278u16,16333u16),(24282u16,21398u16),(24283u16,20893u16), (24287u16,16872u16),(24288u16,21818u16),(24290u16,22745u16),(24291u16,14763u16), (24300u16,16125u16),(24307u16,22015u16),(24310u16,19322u16),(24311u16,21048u16), (24314u16,14234u16),(24315u16,23528u16),(24321u16,17392u16),(24324u16,16316u16), (24330u16,22746u16),(24335u16,18765u16),(24337u16,18744u16),(24339u16,14980u16), (24340u16,21217u16),(24341u16,20483u16),(24343u16,17630u16),(24344u16,23355u16), (24347u16,20437u16),(24351u16,21194u16),(24358u16,23140u16),(24359u16,23308u16), (24361u16,15517u16),(24369u16,19111u16),(24373u16,20684u16),(24378u16,14168u16), (24380u16,22911u16),(24392u16,22520u16),(24394u16,14169u16),(24396u16,17020u16), (24398u16,16647u16),(24406u16,15682u16),(24407u16,23293u16),(24409u16,23691u16), (24411u16,20438u16),(24418u16,23276u16),(24422u16,19168u16),(24423u16,19933u16), (24425u16,21839u16),(24426u16,22788u16),(24427u16,21218u16),(24428u16,17780u16), (24429u16,22721u16),(24432u16,21819u16),(24433u16,19490u16),(24439u16,17208u16), (24441u16,19306u16),(24444u16,22903u16),(24447u16,17631u16),(24448u16,19722u16), (24449u16,21049u16),(24453u16,15741u16),(24455u16,18588u16),(24458u16,23529u16), (24459u16,16475u16),(24460u16,23668u16),(24464u16,18034u16),(24465u16,14396u16), (24466u16,15764u16),(24471u16,15945u16),(24472u16,17234u16),(24473u16,17818u16), (24478u16,21269u16),(24480u16,16103u16),(24481u16,19152u16),(24488u16,23504u16), (24489u16,17439u16),(24490u16,18589u16),(24494u16,17021u16),(24501u16,21758u16), (24503u16,15751u16),(24505u16,21988u16),(24509u16,23692u16),(24515u16,18808u16), (24517u16,22912u16),(24524u16,15196u16),(24525u16,20484u16),(24534u16,22163u16), (24535u16,21569u16),(24536u16,16671u16),(24537u16,16672u16),(24544u16,22222u16), (24555u16,22390u16),(24565u16,15508u16),(24573u16,23351u16),(24575u16,17615u16), (24591u16,18977u16),(24594u16,15518u16),(24598u16,22760u16),(24604u16,16272u16), (24605u16,17819u16),(24608u16,22544u16),(24609u16,20439u16),(24613u16,15170u16), (24615u16,18230u16),(24616u16,20064u16),(24618u16,14779u16),(24623u16,14350u16), (24641u16,20511u16),(24642u16,18590u16),(24643u16,18745u16),(24653u16,23505u16), (24656u16,14615u16),(24658u16,22981u16),(24661u16,18035u16),(24665u16,19126u16), (24669u16,14756u16),(24674u16,23530u16),(24675u16,20631u16),(24676u16,23704u16), (24677u16,22352u16),(24680u16,22942u16),(24681u16,20293u16),(24682u16,13998u16), (24684u16,15509u16),(24685u16,14616u16),(24687u16,18766u16),(24688u16,23725u16), (24709u16,19362u16),(24713u16,18805u16),(24716u16,21195u16),(24717u16,22943u16), (24724u16,23531u16),(24726u16,22712u16),(24730u16,18404u16),(24731u16,20894u16), (24735u16,19561u16),(24736u16,20122u16),(24739u16,23485u16),(24740u16,22169u16), (24743u16,16495u16),(24752u16,21270u16),(24754u16,17647u16),(24755u16,15752u16), (24756u16,22227u16),(24758u16,17036u16),(24760u16,14436u16),(24764u16,15765u16), (24765u16,21949u16),(24773u16,21050u16),(24775u16,15900u16),(24785u16,23342u16), (24794u16,23352u16),(24796u16,18158u16),(24799u16,20123u16),(24800u16,23294u16), (24801u16,18939u16),(24816u16,22396u16),(24817u16,15546u16),(24819u16,17999u16), (24822u16,23506u16),(24825u16,19104u16),(24826u16,18231u16),(24827u16,22344u16), (24833u16,18429u16),(24838u16,14235u16),(24840u16,20124u16),(24841u16,20125u16), (24845u16,17037u16),(24846u16,22725u16),(24847u16,20317u16),(24853u16,18940u16), (24858u16,19910u16),(24859u16,18986u16),(24863u16,14044u16),(24871u16,14780u16), (24880u16,23507u16),(24884u16,21820u16),(24887u16,14191u16),(24892u16,18784u16), (24894u16,14192u16),(24895u16,20065u16),(24898u16,19884u16),(24900u16,16476u16), (24903u16,20294u16),(24904u16,20632u16),(24906u16,14380u16),(24907u16,22545u16), (24908u16,23508u16),(24915u16,22789u16),(24917u16,16838u16),(24920u16,21806u16), (24921u16,21807u16),(24925u16,22583u16),(24927u16,22564u16),(24930u16,16648u16), (24931u16,14742u16),(24932u16,13999u16),(24935u16,23295u16),(24936u16,14193u16), (24939u16,21271u16),(24942u16,16126u16),(24944u16,20093u16),(24950u16,14397u16), (24951u16,14170u16),(24957u16,21955u16),(24958u16,19870u16),(24961u16,22170u16), (24962u16,19911u16),(24970u16,17648u16),(24974u16,21458u16),(24976u16,16146u16), (24977u16,17792u16),(24980u16,22036u16),(24984u16,23738u16),(24985u16,23737u16), (24986u16,22521u16),(24996u16,17616u16),(24999u16,15916u16),(25001u16,14353u16), (25003u16,17038u16),(25004u16,14398u16),(25006u16,16883u16),(25010u16,23127u16), (25014u16,19162u16),(25018u16,15703u16),(25022u16,14045u16),(25027u16,15141u16), (25031u16,14013u16),(25032u16,23096u16),(25033u16,20310u16),(25034u16,19563u16), (25035u16,16884u16),(25062u16,15350u16),(25074u16,21759u16),(25078u16,15956u16), (25079u16,23532u16),(25080u16,23141u16),(25082u16,21808u16),(25084u16,14926u16), (25087u16,20318u16),(25088u16,16147u16),(25095u16,15727u16),(25096u16,14627u16), (25098u16,16885u16),(25100u16,18614u16),(25101u16,18526u16),(25102u16,20287u16), (25104u16,18232u16),(25105u16,18923u16),(25106u16,14437u16),(25110u16,23343u16), (25114u16,21956u16),(25119u16,15134u16),(25121u16,14046u16),(25130u16,21019u16), (25134u16,16467u16),(25136u16,20895u16),(25137u16,23739u16),(25140u16,15742u16), (25142u16,23309u16),(25150u16,16127u16),(25151u16,17209u16),(25152u16,18357u16), (25153u16,22728u16),(25159u16,18176u16),(25160u16,23310u16),(25161u16,17649u16), (25163u16,18527u16),(25165u16,20811u16),(25171u16,22397u16),(25176u16,22410u16), (25198u16,17617u16),(25201u16,15171u16),(25206u16,17581u16),(25209u16,17650u16), (25212u16,18994u16),(25215u16,18730u16),(25216u16,15197u16),(25220u16,22037u16), (25225u16,14373u16),(25226u16,22589u16),(25233u16,19163u16),(25234u16,18036u16), (25237u16,22580u16),(25239u16,22982u16),(25240u16,21020u16),(25243u16,22761u16), (25259u16,22904u16),(25265u16,22762u16),(25269u16,20834u16),(25273u16,16663u16), (25276u16,18972u16),(25277u16,22181u16),(25282u16,17632u16),(25287u16,16886u16), (25288u16,15510u16),(25289u16,16090u16),(25292u16,17074u16),(25293u16,17053u16), (25295u16,15352u16),(25296u16,14781u16),(25298u16,14217u16),(25299u16,21957u16), (25300u16,17096u16),(25302u16,22398u16),(25303u16,19748u16),(25304u16,14927u16), (25305u16,21265u16),(25307u16,22038u16),(25308u16,17235u16),(25324u16,14757u16), (25325u16,18767u16),(25326u16,15342u16),(25327u16,21460u16),(25329u16,14617u16), (25331u16,14990u16),(25335u16,14559u16),(25342u16,18721u16),(25343u16,15353u16), (25345u16,21570u16),(25351u16,21571u16),(25353u16,18951u16),(25361u16,15766u16), (25387u16,21384u16),(25391u16,21606u16),(25402u16,21051u16),(25403u16,19326u16), (25405u16,16649u16),(25406u16,23168u16),(25417u16,21776u16),(25420u16,22709u16), (25423u16,15378u16),(25424u16,19325u16),(25429u16,22763u16),(25447u16,17458u16), (25448u16,17820u16),(25454u16,14218u16),(25458u16,14991u16),(25463u16,22008u16), (25466u16,15379u16),(25467u16,15511u16),(25471u16,18037u16),(25475u16,18358u16), (25480u16,18528u16),(25481u16,15767u16),(25484u16,20685u16),(25490u16,17236u16), (25494u16,18995u16),(25496u16,14977u16),(25499u16,14773u16),(25504u16,16106u16), (25505u16,21840u16),(25506u16,22529u16),(25509u16,21035u16),(25511u16,14618u16), (25512u16,22182u16),(25513u16,19178u16),(25514u16,21219u16),(25536u16,14014u16), (25540u16,20126u16),(25542u16,15111u16),(25551u16,16873u16),(25552u16,21196u16), (25558u16,20306u16),(25562u16,19127u16),(25563u16,23486u16),(25569u16,18941u16), (25581u16,14354u16),(25582u16,23693u16),(25588u16,20066u16),(25590u16,19105u16), (25591u16,17981u16),(25613u16,18398u16),(25615u16,17054u16),(25620u16,18359u16), (25622u16,19749u16),(25623u16,15768u16),(25628u16,18529u16),(25634u16,21607u16), (25644u16,17075u16),(25645u16,22534u16),(25658u16,23700u16),(25662u16,21777u16), (25688u16,20860u16),(25696u16,22171u16),(25705u16,16629u16),(25711u16,21572u16), (25720u16,16839u16),(25721u16,16840u16),(25722u16,21036u16),(25736u16,16291u16), (25745u16,22558u16),(25746u16,17969u16),(25747u16,19750u16),(25754u16,15506u16), (25758u16,15728u16),(25764u16,21989u16),(25765u16,17097u16),(25771u16,16887u16), (25773u16,22590u16),(25774u16,22176u16),(25776u16,21783u16),(25778u16,17055u16), (25787u16,15696u16),(25793u16,19687u16),(25796u16,16292u16),(25797u16,21971u16), (25799u16,22556u16),(25802u16,14355u16),(25805u16,21220u16),(25806u16,14399u16), (25810u16,15156u16),(25812u16,15704u16),(25816u16,17286u16),(25818u16,14219u16), (25825u16,15743u16),(25826u16,22412u16),(25829u16,16081u16),(25830u16,21800u16), (25831u16,14220u16),(25836u16,20319u16),(25842u16,21958u16),(25844u16,23475u16), (25850u16,22591u16),(25854u16,19751u16),(25856u16,17076u16),(25860u16,22559u16), (25880u16,19128u16),(25885u16,18223u16),(25891u16,16148u16),(25898u16,14795u16), (25899u16,23476u16),(25900u16,16082u16),(25903u16,21573u16),(25910u16,18530u16), (25911u16,14560u16),(25912u16,20127u16),(25913u16,14194u16),(25915u16,14619u16), (25918u16,17210u16),(25919u16,21052u16),(25925u16,14561u16),(25928u16,23554u16), (25933u16,18038u16),(25934u16,14796u16),(25935u16,17039u16),(25937u16,14928u16), (25942u16,19564u16),(25943u16,22713u16),(25950u16,21821u16),(25954u16,14047u16), (25955u16,17959u16),(25958u16,15901u16),(25964u16,14400u16),(25965u16,19129u16), (25970u16,14562u16),(25972u16,21053u16),(25973u16,20861u16),(25975u16,17582u16), (25976u16,18531u16),(25982u16,18177u16),(25986u16,16261u16),(25987u16,22747u16), (25989u16,23555u16),(25991u16,16909u16),(25996u16,17781u16),(26000u16,17651u16), (26001u16,17077u16),(26007u16,15929u16),(26009u16,16334u16),(26011u16,14590u16), (26012u16,17821u16),(26015u16,21653u16),(26017u16,18959u16),(26020u16,15142u16), (26021u16,21959u16),(26023u16,17583u16),(26027u16,20652u16),(26028u16,21809u16), (26031u16,17822u16),(26032u16,18785u16),(26039u16,15683u16),(26041u16,17211u16), (26044u16,19153u16),(26045u16,18746u16),(26049u16,17212u16),(26053u16,16128u16), (26059u16,18178u16),(26060u16,21054u16),(26063u16,21258u16),(26066u16,16453u16), (26071u16,15198u16),(26080u16,16888u16),(26083u16,15199u16),(26085u16,20502u16), (26086u16,15684u16),(26088u16,21574u16),(26089u16,21221u16),(26092u16,18591u16), (26093u16,19934u16),(26097u16,22944u16),(26100u16,19912u16),(26106u16,19723u16), (26107u16,17040u16),(26108u16,17041u16),(26109u16,15902u16),(26111u16,19565u16), (26118u16,14599u16),(26119u16,18731u16),(26121u16,17213u16),(26122u16,23311u16), (26124u16,21822u16),(26126u16,16820u16),(26127u16,23346u16),(26128u16,17618u16), (26129u16,15157u16),(26131u16,19307u16),(26132u16,18159u16),(26133u16,23713u16), (26142u16,17406u16),(26143u16,18233u16),(26144u16,19492u16),(26149u16,22215u16), (26151u16,16685u16),(26152u16,20653u16),(26157u16,18360u16),(26159u16,18747u16), (26160u16,22927u16),(26161u16,19935u16),(26164u16,16874u16),(26166u16,21823u16), (26170u16,17407u16),(26171u16,18978u16),(26177u16,21222u16),(26178u16,18748u16), (26179u16,23509u16),(26180u16,23510u16),(26185u16,21608u16),(26187u16,21609u16), (26191u16,18952u16),(26201u16,21434u16),(26203u16,23142u16),(26205u16,21399u16), (26206u16,23740u16),(26207u16,18234u16),(26212u16,19566u16),(26213u16,23488u16), (26214u16,23533u16),(26215u16,23312u16),(26216u16,18786u16),(26217u16,16650u16), (26219u16,22413u16),(26222u16,17422u16),(26223u16,14401u16),(26227u16,18160u16), (26228u16,22016u16),(26230u16,21055u16),(26231u16,15007u16),(26232u16,21056u16), (26234u16,21575u16),(26244u16,23685u16),(26247u16,13977u16),(26248u16,23682u16), (26249u16,23694u16),(26254u16,19493u16),(26256u16,20094u16),(26257u16,18039u16), (26262u16,15371u16),(26263u16,18967u16),(26264u16,19130u16),(26269u16,16821u16), (26272u16,14563u16),(26274u16,21824u16),(26283u16,20668u16),(26286u16,16841u16), (26290u16,20686u16),(26291u16,23296u16),(26292u16,22781u16),(26297u16,18216u16), (26299u16,14402u16),(26302u16,15903u16),(26308u16,19480u16),(26310u16,16140u16), (26311u16,15705u16),(26313u16,23556u16),(26326u16,18987u16),(26329u16,18040u16), (26332u16,19753u16),(26333u16,22782u16),(26336u16,14764u16),(26342u16,23741u16), (26352u16,19721u16),(26354u16,14591u16),(26355u16,19529u16),(26356u16,14403u16), (26359u16,14032u16),(26360u16,18041u16),(26361u16,21224u16),(26362u16,21223u16), (26364u16,16651u16),(26366u16,21459u16),(26367u16,22025u16),(26368u16,22179u16), (26371u16,23534u16),(26376u16,20082u16),(26377u16,20128u16),(26379u16,17634u16), (26381u16,17440u16),(26388u16,17858u16),(26389u16,21654u16),(26391u16,16094u16), (26395u16,16673u16),(26397u16,21225u16),(26398u16,15296u16),(26399u16,15297u16), (26406u16,16867u16),(26407u16,16317u16),(26408u16,16857u16),(26410u16,17022u16), (26411u16,16664u16),(26412u16,17451u16),(26413u16,21801u16),(26414u16,22219u16), (26417u16,21400u16),(26420u16,17056u16),(26422u16,22399u16),(26426u16,15000u16), (26429u16,23669u16),(26438u16,14015u16),(26441u16,17975u16),(26446u16,16496u16), (26447u16,23111u16),(26448u16,20812u16),(26449u16,22164u16),(26451u16,22790u16), (26454u16,20687u16),(26460u16,15930u16),(26462u16,15298u16),(26463u16,18389u16), (26477u16,22983u16),(26479u16,17237u16),(26480u16,14244u16),(26481u16,15917u16), (26483u16,16875u16),(26485u16,20835u16),(26487u16,22592u16),(26491u16,15563u16), (26494u16,18405u16),(26495u16,22604u16),(26503u16,17652u16),(26505u16,19724u16), (26507u16,17214u16),(26511u16,15382u16),(26512u16,18161u16),(26515u16,15931u16), (26517u16,22380u16),(26519u16,16524u16),(26522u16,16686u16),(26524u16,14628u16), (26525u16,21576u16),(26543u16,14564u16),(26544u16,22739u16),(26547u16,21577u16), (26550u16,13978u16),(26551u16,13979u16),(26552u16,14929u16),(26558u16,18749u16), (26564u16,17408u16),(26575u16,17253u16),(26576u16,16842u16),(26577u16,14048u16), (26578u16,22376u16),(26579u16,19373u16),(26580u16,20130u16),(26586u16,20131u16), (26589u16,22414u16),(26601u16,14930u16),(26604u16,14016u16),(26607u16,13980u16), (26608u16,15501u16),(26609u16,21401u16),(26611u16,16454u16),(26612u16,18750u16), (26613u16,21848u16),(26614u16,17823u16),(26619u16,17824u16),(26622u16,21057u16), (26642u16,18592u16),(26643u16,20896u16),(26646u16,18042u16),(26647u16,16477u16), (26657u16,14797u16),(26658u16,17254u16),(26666u16,21402u16),(26671u16,19936u16), (26680u16,23108u16),(26681u16,15143u16),(26684u16,14356u16),(26685u16,20813u16), (26688u16,14245u16),(26689u16,22984u16),(26690u16,14438u16),(26691u16,15769u16), (26696u16,18953u16),(26702u16,21643u16),(26704u16,15918u16),(26705u16,18000u16), (26707u16,23489u16),(26708u16,15343u16),(26733u16,21610u16),(26742u16,22565u16), (26751u16,14017u16),(26753u16,16112u16),(26757u16,16687u16),(26767u16,14592u16), (26771u16,20814u16),(26772u16,22353u16),(26775u16,14404u16),(26781u16,21226u16), (26783u16,23557u16),(26785u16,19706u16),(26786u16,22039u16),(26791u16,19567u16), (26792u16,16497u16),(26797u16,17825u16),(26799u16,21197u16),(26800u16,14439u16), (26801u16,14600u16),(26803u16,18361u16),(26805u16,17274u16),(26806u16,17023u16), (26820u16,15300u16),(26821u16,17409u16),(26825u16,16711u16),(26827u16,15299u16), (26829u16,14601u16),(26834u16,17459u16),(26837u16,21272u16),(26839u16,21227u16), (26840u16,15135u16),(26842u16,17635u16),(26847u16,15919u16),(26848u16,15729u16), (26855u16,20663u16),(26856u16,14536u16),(26862u16,17976u16),(26866u16,18043u16), (26873u16,15866u16),(26874u16,14743u16),(26880u16,19707u16),(26885u16,20320u16), (26893u16,18768u16),(26894u16,22183u16),(26898u16,22136u16),(26919u16,16822u16), (26928u16,19106u16),(26941u16,19328u16),(26943u16,22216u16),(26954u16,19132u16), (26963u16,22898u16),(26964u16,18204u16),(26965u16,22400u16),(26967u16,14236u16), (26969u16,16889u16),(26970u16,22137u16),(26974u16,16484u16),(26976u16,15383u16), (26977u16,20133u16),(26978u16,20134u16),(26979u16,17024u16),(26984u16,21058u16), (26987u16,21454u16),(26989u16,19181u16),(26990u16,20836u16),(26991u16,18593u16), (26997u16,15136u16),(26999u16,23097u16),(27000u16,22184u16),(27001u16,19494u16), (27029u16,19885u16),(27035u16,21611u16),(27036u16,17215u16),(27045u16,23511u16), (27047u16,17653u16),(27054u16,19495u16),(27060u16,16455u16),(27067u16,22535u16), (27073u16,14565u16),(27075u16,17078u16),(27083u16,14931u16),(27084u16,22572u16), (27085u16,21825u16),(27088u16,14782u16),(27112u16,14735u16),(27114u16,14195u16), (27131u16,15112u16),(27133u16,21228u16),(27135u16,15144u16),(27138u16,18942u16), (27146u16,17259u16),(27153u16,16113u16),(27155u16,16442u16),(27159u16,20837u16), (27161u16,22791u16),(27166u16,22185u16),(27167u16,20688u16),(27169u16,16843u16), (27171u16,19133u16),(27189u16,22138u16),(27192u16,17057u16),(27193u16,18532u16), (27194u16,23367u16),(27197u16,21435u16),(27204u16,14049u16),(27208u16,19755u16), (27211u16,14798u16),(27218u16,19943u16),(27219u16,18594u16),(27224u16,15130u16), (27225u16,15947u16),(27231u16,15301u16),(27233u16,18001u16),(27243u16,23549u16), (27264u16,15685u16),(27268u16,14357u16),(27273u16,21059u16),(27277u16,19164u16), (27278u16,15158u16),(27287u16,17287u16),(27292u16,23535u16),(27298u16,14249u16), (27299u16,20689u16),(27315u16,17782u16),(27323u16,22962u16),(27330u16,15867u16), (27331u16,15001u16),(27347u16,16293u16),(27354u16,16129u16),(27355u16,21453u16), (27382u16,23128u16),(27387u16,19096u16),(27396u16,16072u16),(27402u16,14992u16), (27404u16,20690u16),(27410u16,16073u16),(27414u16,16083u16),(27424u16,23721u16), (27425u16,21768u16),(27427u16,23714u16),(27442u16,19871u16),(27450u16,15302u16), (27453u16,23722u16),(27454u16,14744u16),(27462u16,23723u16),(27463u16,23131u16), (27468u16,13981u16),(27470u16,22522u16),(27472u16,14932u16),(27487u16,19287u16), (27489u16,23487u16),(27490u16,21578u16),(27491u16,21060u16),(27492u16,21769u16), (27493u16,17423u16),(27494u16,16890u16),(27498u16,19729u16),(27506u16,18343u16), (27511u16,16141u16),(27512u16,15008u16),(27515u16,17826u16),(27519u16,16864u16), (27523u16,18979u16),(27524u16,21612u16),(27526u16,22546u16),(27529u16,18595u16), (27530u16,18533u16),(27542u16,18769u16),(27544u16,20664u16),(27550u16,19944u16), (27566u16,16262u16),(27567u16,17783u16),(27570u16,18217u16),(27573u16,15686u16), (27575u16,20295u16),(27578u16,17970u16),(27580u16,14000u16),(27583u16,20897u16), (27585u16,23690u16),(27589u16,20321u16),(27590u16,14933u16),(27595u16,16891u16), (27597u16,16844u16),(27599u16,16688u16),(27602u16,15889u16),(27603u16,20265u16), (27604u16,17654u16),(27606u16,17655u16),(27607u16,17656u16),(27608u16,17657u16), (27611u16,16845u16),(27627u16,23313u16),(27628u16,14934u16),(27656u16,20898u16), (27663u16,18916u16),(27665u16,17042u16),(27667u16,16701u16),(27683u16,15303u16), (27700u16,18534u16),(27703u16,17793u16),(27704u16,19496u16),(27710u16,17275u16), (27712u16,21061u16),(27713u16,21455u16),(27714u16,14935u16),(27726u16,17276u16), (27728u16,18162u16),(27733u16,17960u16),(27735u16,22945u16),(27738u16,19568u16), (27741u16,19288u16),(27742u16,23356u16),(27743u16,14171u16),(27744u16,21579u16), (27752u16,14606u16),(27754u16,19725u16),(27757u16,19530u16),(27760u16,22547u16), (27762u16,15172u16),(27766u16,17006u16),(27770u16,14374u16),(27773u16,15304u16), (27774u16,17619u16),(27777u16,18809u16),(27778u16,15305u16),(27779u16,19675u16), (27781u16,20067u16),(27782u16,22985u16),(27783u16,19329u16),(27784u16,22381u16), (27788u16,15904u16),(27792u16,16858u16),(27794u16,16865u16),(27795u16,15718u16), (27796u16,16712u16),(27797u16,17014u16),(27798u16,22223u16),(27801u16,17827u16), (27802u16,21580u16),(27803u16,22714u16),(27819u16,16665u16),(27822u16,20838u16), (27827u16,22928u16),(27832u16,17658u16),(27833u16,20135u16),(27835u16,22354u16), (27836u16,18362u16),(27837u16,14566u16),(27838u16,21997u16),(27839u16,19330u16), (27841u16,23512u16),(27842u16,23277u16),(27844u16,18205u16),(27849u16,21972u16), (27850u16,17058u16),(27852u16,22913u16),(27859u16,23357u16),(27861u16,17281u16), (27863u16,17828u16),(27867u16,17277u16),(27873u16,22765u16),(27874u16,22593u16), (27875u16,20307u16),(27877u16,15575u16),(27880u16,21403u16),(27883u16,23143u16), (27886u16,17079u16),(27887u16,17043u16),(27888u16,22548u16),(27891u16,19497u16), (27915u16,19134u16),(27916u16,16257u16),(27921u16,17424u16),(27927u16,18344u16), (27929u16,18535u16),(27931u16,16061u16),(27934u16,15920u16),(27941u16,21613u16), (27943u16,20136u16),(27945u16,18206u16),(27946u16,23358u16),(27954u16,21404u16), (27957u16,18596u16),(27958u16,23710u16),(27960u16,14765u16),(27961u16,20068u16), (27963u16,23497u16),(27965u16,23726u16),(27966u16,22594u16),(27969u16,16456u16), (27993u16,21021u16),(27994u16,21436u16),(27996u16,17784u16),(28003u16,19708u16), (28006u16,22766u16),(28009u16,23314u16),(28010u16,16095u16),(28012u16,16498u16), (28014u16,17584u16),(28020u16,19872u16),(28023u16,23098u16),(28024u16,22382u16), (28025u16,23169u16),(28031u16,22715u16),(28037u16,19363u16),(28039u16,14405u16), (28040u16,18363u16),(28041u16,18224u16),(28044u16,19886u16),(28045u16,23558u16), (28046u16,19331u16),(28049u16,18390u16),(28051u16,19332u16),(28053u16,22026u16), (28079u16,18988u16),(28082u16,18996u16),(28085u16,22963u16),(28096u16,21062u16), (28099u16,14993u16),(28100u16,22355u16),(28101u16,18163u16),(28102u16,23559u16), (28103u16,15306u16),(28107u16,16525u16),(28111u16,23315u16),(28113u16,18580u16), (28120u16,15868u16),(28121u16,21273u16),(28122u16,16443u16),(28126u16,18406u16), (28129u16,15706u16),(28136u16,21063u16),(28138u16,16472u16),(28139u16,20301u16), (28142u16,23536u16),(28145u16,18907u16),(28147u16,18597u16),(28149u16,19333u16), (28151u16,23347u16),(28152u16,22017u16),(28153u16,19179u16),(28154u16,21973u16), (28155u16,21998u16),(28183u16,17977u16),(28185u16,23490u16),(28186u16,20839u16), (28187u16,14050u16),(28191u16,21064u16),(28192u16,14221u16),(28193u16,15869u16), (28195u16,17829u16),(28196u16,17098u16),(28197u16,18943u16),(28198u16,19695u16), (28203u16,18207u16),(28204u16,22345u16),(28205u16,20095u16),(28207u16,22986u16), (28210u16,18179u16),(28212u16,14033u16),(28214u16,19498u16),(28216u16,20138u16), (28218u16,16876u16),(28220u16,17025u16),(28221u16,20815u16),(28222u16,23348u16), (28227u16,17238u16),(28228u16,17026u16),(28234u16,21405u16),(28237u16,15687u16), (28246u16,23316u16),(28248u16,18002u16),(28251u16,15707u16),(28252u16,18770u16), (28254u16,21065u16),(28255u16,23513u16),(28263u16,19887u16),(28267u16,22186u16), (28270u16,20485u16),(28271u16,22538u16),(28274u16,20069u16),(28275u16,15384u16), (28282u16,17425u16),(28304u16,20070u16),(28310u16,21437u16),(28316u16,16457u16), (28317u16,14936u16),(28319u16,16823u16),(28322u16,20503u16),(28325u16,17585u16), (28330u16,14537u16),(28331u16,19679u16),(28335u16,18364u16),(28337u16,21614u16), (28342u16,19888u16),(28346u16,15577u16),(28354u16,17216u16),(28356u16,21826u16), (28357u16,16719u16),(28361u16,23514u16),(28363u16,20633u16),(28364u16,21960u16), (28366u16,23278u16),(28369u16,23498u16),(28371u16,20816u16),(28372u16,15870u16), (28399u16,22027u16),(28404u16,20862u16),(28408u16,23317u16),(28414u16,14602u16), (28415u16,16652u16),(28417u16,19154u16),(28418u16,22792u16),(28422u16,22377u16), (28431u16,16444u16),(28433u16,14196u16),(28436u16,19334u16),(28437u16,21229u16), (28448u16,16639u16),(28450u16,22946u16),(28451u16,16149u16),(28459u16,16653u16), (28460u16,21581u16),(28465u16,18536u16),(28466u16,21827u16),(28472u16,21029u16), (28479u16,20691u16),(28481u16,19499u16),(28497u16,17099u16),(28500u16,14375u16), (28503u16,21657u16),(28504u16,17080u16),(28506u16,18581u16),(28507u16,20669u16), (28510u16,16294u16),(28511u16,18164u16),(28514u16,23515u16),(28516u16,20275u16), (28525u16,15708u16),(28526u16,21230u16),(28528u16,15002u16),(28538u16,20665u16), (28540u16,15921u16),(28541u16,17426u16),(28542u16,16516u16),(28545u16,17982u16), (28548u16,21760u16),(28552u16,21990u16),(28557u16,21406u16),(28558u16,22722u16), (28560u16,19945u16),(28564u16,23318u16),(28567u16,14018u16),(28579u16,22947u16), (28580u16,22557u16),(28583u16,16285u16),(28590u16,23537u16),(28591u16,21784u16), (28593u16,20899u16),(28595u16,19569u16),(28601u16,15709u16),(28606u16,15697u16), (28608u16,14358u16),(28609u16,22415u16),(28610u16,16263u16),(28611u16,15541u16), (28618u16,19531u16),(28629u16,18720u16),(28634u16,19500u16),(28639u16,21198u16), (28640u16,23319u16),(28641u16,20236u16),(28644u16,15871u16),(28649u16,23320u16), (28651u16,16084u16),(28652u16,21438u16),(28655u16,22416u16),(28657u16,17785u16), (28670u16,16130u16),(28673u16,19135u16),(28677u16,23279u16),(28678u16,15890u16), (28681u16,17830u16),(28683u16,18908u16),(28687u16,16458u16),(28689u16,22783u16), (28693u16,17786u16),(28696u16,16295u16),(28698u16,22948u16),(28699u16,19501u16), (28700u16,20288u16),(28701u16,16142u16),(28702u16,21066u16),(28703u16,18365u16), (28707u16,23099u16),(28711u16,16318u16),(28712u16,16323u16),(28719u16,19502u16), (28727u16,20468u16),(28734u16,16074u16),(28748u16,14745u16),(28752u16,23280u16), (28753u16,18413u16),(28760u16,22523u16),(28765u16,23321u16),(28771u16,16654u16), (28779u16,23368u16),(28784u16,23538u16),(28792u16,14937u16),(28796u16,20654u16), (28797u16,20817u16),(28805u16,14406u16),(28810u16,22332u16),(28814u16,19375u16), (28818u16,22139u16),(28824u16,23715u16),(28825u16,20634u16),(28826u16,14766u16), (28833u16,21067u16),(28836u16,18366u16),(28843u16,23144u16),(28844u16,14222u16), (28845u16,22524u16),(28847u16,23281u16),(28851u16,17410u16),(28855u16,21407u16), (28856u16,20655u16),(28857u16,21030u16),(28872u16,16258u16),(28875u16,23701u16), (28879u16,19666u16),(28888u16,23359u16),(28889u16,16062u16),(28893u16,21461u16), (28895u16,19336u16),(28913u16,14407u16),(28921u16,22723u16),(28925u16,17460u16), (28932u16,23677u16),(28937u16,19169u16),(28940u16,21439u16),(28953u16,17239u16), (28954u16,17620u16),(28958u16,15905u16),(28961u16,16892u16),(28966u16,22140u16), (28976u16,19376u16),(28982u16,19337u16),(28999u16,23695u16),(29001u16,16246u16), (29002u16,23686u16),(29004u16,23516u16),(29006u16,20996u16),(29008u16,19503u16), (29014u16,15373u16),(29017u16,19338u16),(29020u16,19937u16),(29022u16,17971u16), (29028u16,16689u16),(29029u16,23491u16),(29030u16,23670u16),(29031u16,21231u16), (29033u16,17260u16),(29036u16,19136u16),(29038u16,20635u16),(29053u16,18180u16), (29060u16,18771u16),(29065u16,19946u16),(29066u16,20053u16),(29071u16,23678u16), (29074u16,23282u16),(29076u16,19889u16),(29081u16,23742u16),(29087u16,18582u16), (29090u16,17461u16),(29100u16,19667u16),(29105u16,19365u16),(29113u16,23743u16), (29114u16,23744u16),(29118u16,22356u16),(29121u16,19482u16),(29123u16,19340u16), (29128u16,15948u16),(29129u16,15906u16),(29134u16,16335u16),(29136u16,16517u16), (29138u16,18367u16),(29140u16,17261u16),(29141u16,19341u16),(29151u16,19504u16), (29157u16,21232u16),(29158u16,21785u16),(29159u16,18537u16),(29165u16,22158u16), (29166u16,18225u16),(29179u16,23679u16),(29180u16,18787u16),(29182u16,15872u16), (29183u16,19757u16),(29184u16,23135u16),(29190u16,22784u16),(29200u16,16296u16), (29211u16,16075u16),(29226u16,21233u16),(29228u16,22595u16),(29229u16,20824u16), (29232u16,20071u16),(29234u16,20096u16),(29237u16,20656u16),(29238u16,17586u16), (29242u16,19107u16),(29243u16,23656u16),(29245u16,18003u16),(29246u16,20444u16), (29248u16,18004u16),(29254u16,20692u16),(29255u16,22729u16),(29256u16,22605u16), (29260u16,22716u16),(29266u16,22009u16),(29272u16,15891u16),(29273u16,18924u16), (29275u16,19913u16),(29277u16,17787u16),(29279u16,16846u16),(29281u16,16847u16), (29282u16,16324u16),(29287u16,16859u16),(29289u16,17015u16),(29298u16,18024u16), (29305u16,22584u16),(29309u16,14363u16),(29312u16,18044u16),(29313u16,16499u16), (29346u16,15892u16),(29351u16,23745u16),(29356u16,14364u16),(29359u16,17278u16), (29376u16,18005u16),(29378u16,14767u16),(29380u16,20863u16),(29390u16,18973u16), (29392u16,23322u16),(29399u16,14938u16),(29401u16,20840u16),(29409u16,14799u16), (29417u16,18538u16),(29432u16,16500u16),(29433u16,23170u16),(29436u16,16096u16), (29437u16,22717u16),(29450u16,19532u16),(29462u16,21828u16),(29467u16,16702u16), (29468u16,18751u16),(29469u16,21266u16),(29477u16,19734u16),(29481u16,18235u16), (29482u16,20841u16),(29483u16,16877u16),(29494u16,20237u16),(29495u16,20238u16), (29502u16,23499u16),(29503u16,20072u16),(29508u16,19676u16),(29509u16,17831u16), (29520u16,20694u16),(29522u16,19668u16),(29527u16,14996u16),(29544u16,15893u16), (29546u16,23539u16),(29552u16,19505u16),(29554u16,23547u16),(29557u16,16265u16), (29560u16,18539u16),(29562u16,15698u16),(29563u16,23129u16),(29572u16,23145u16), (29574u16,20636u16),(29575u16,18402u16),(29577u16,19677u16),(29579u16,19726u16), (29582u16,21068u16),(29588u16,21974u16),(29590u16,14939u16),(29591u16,19914u16), (29592u16,15307u16),(29599u16,17044u16),(29607u16,20276u16),(29609u16,19709u16), (29613u16,17788u16),(29618u16,16273u16),(29619u16,15744u16),(29625u16,23146u16), (29632u16,17059u16),(29634u16,13982u16),(29641u16,17045u16),(29642u16,17961u16), (29644u16,22914u16),(29645u16,21615u16),(29647u16,14001u16),(29654u16,14768u16), (29657u16,14620u16),(29661u16,23671u16),(29662u16,16063u16),(29664u16,21408u16), (29667u16,18598u16),(29668u16,17427u16),(29669u16,20445u16),(29670u16,23117u16), (29673u16,23283u16),(29674u16,15113u16),(29677u16,17081u16),(29687u16,16893u16), (29689u16,18236u16),(29693u16,21069u16),(29694u16,23147u16),(29697u16,18181u16), (29699u16,14940u16),(29701u16,16097u16),(29702u16,16501u16),(29703u16,18540u16), (29705u16,16459u16),(29715u16,19710u16),(29723u16,22383u16),(29728u16,20997u16), (29729u16,18583u16),(29730u16,22417u16),(29733u16,23323u16),(29734u16,15308u16), (29736u16,14603u16),(29738u16,15309u16),(29739u16,17462u16),(29740u16,19711u16), (29742u16,21274u16),(29743u16,14746u16),(29744u16,19377u16),(29747u16,16526u16), (29748u16,15159u16),(29749u16,17660u16),(29750u16,22596u16),(29752u16,22418u16), (29754u16,17282u16),(29759u16,23349u16),(29760u16,19915u16),(29761u16,16848u16), (29763u16,22217u16),(29764u16,18182u16),(29771u16,20097u16),(29781u16,22929u16), (29783u16,20073u16),(29785u16,15522u16),(29786u16,23324u16),(29787u16,19507u16), (29788u16,20240u16),(29790u16,18045u16),(29791u16,18717u16),(29792u16,16460u16), (29794u16,19890u16),(29796u16,19758u16),(29797u16,19680u16),(29800u16,21616u16), (29801u16,23284u16),(29802u16,16630u16),(29807u16,16098u16),(29822u16,15145u16), (29826u16,15310u16),(29827u16,16502u16),(29831u16,18183u16),(29833u16,16247u16), (29835u16,20695u16),(29848u16,16518u16),(29852u16,23517u16),(29854u16,17060u16), (29855u16,14408u16),(29857u16,21617u16),(29859u16,15311u16),(29861u16,14409u16), (29863u16,17288u16),(29864u16,21786u16),(29866u16,21234u16),(29872u16,23492u16), (29874u16,18541u16),(29877u16,19290u16),(29881u16,18584u16),(29885u16,18017u16), (29887u16,18184u16),(29894u16,21644u16),(29898u16,14410u16),(29903u16,16319u16), (29908u16,19509u16),(29912u16,14747u16),(29914u16,21787u16),(29916u16,14629u16), (29920u16,23325u16),(29922u16,22793u16),(29923u16,22606u16),(29926u16,19696u16), (29934u16,19688u16),(29943u16,20637u16),(29953u16,17411u16),(29956u16,14365u16), (29969u16,21462u16),(29973u16,19689u16),(29976u16,14051u16),(29978u16,18909u16), (29979u16,21999u16),(29983u16,18025u16),(29987u16,17962u16),(29989u16,18026u16), (29990u16,18368u16),(29992u16,19891u16),(29995u16,17428u16),(29996u16,19892u16), (30000u16,20998u16),(30001u16,20241u16),(30002u16,14158u16),(30003u16,18788u16), (30007u16,15386u16),(30008u16,20999u16),(30010u16,21070u16),(30023u16,15125u16), (30028u16,14538u16),(30031u16,19735u16),(30033u16,21000u16),(30035u16,15719u16), (30036u16,17082u16),(30041u16,16461u16),(30043u16,21618u16),(30044u16,22204u16), (30045u16,16894u16),(30050u16,22915u16),(30053u16,16107u16),(30054u16,23702u16), (30058u16,17262u16),(30063u16,21440u16),(30064u16,20447u16),(30069u16,23369u16), (30070u16,15730u16),(30072u16,15312u16),(30074u16,14172u16),(30079u16,15313u16), (30086u16,14173u16),(30087u16,21409u16),(30090u16,22010u16),(30091u16,22916u16), (30094u16,18370u16),(30095u16,18369u16),(30097u16,20322u16),(30109u16,17963u16), (30117u16,14197u16),(30123u16,19310u16),(30129u16,22767u16),(30130u16,22905u16), (30131u16,14052u16),(30133u16,20638u16),(30136u16,15699u16),(30137u16,21619u16), (30140u16,15922u16),(30141u16,20842u16),(30142u16,21645u16),(30146u16,13983u16), (30149u16,17412u16),(30151u16,21463u16),(30157u16,20448u16),(30162u16,19137u16), (30164u16,22357u16),(30165u16,23716u16),(30168u16,15932u16),(30169u16,14411u16), (30171u16,22567u16),(30178u16,16504u16),(30192u16,15710u16),(30194u16,16631u16), (30196u16,22358u16),(30202u16,17661u16),(30204u16,14567u16),(30208u16,19155u16), (30221u16,19138u16),(30233u16,18371u16),(30239u16,19681u16),(30240u16,21961u16), (30241u16,21829u16),(30242u16,17083u16),(30244u16,16462u16),(30246u16,18542u16), (30267u16,16445u16),(30274u16,16336u16),(30284u16,18968u16),(30286u16,14019u16), (30290u16,20243u16),(30294u16,17289u16),(30305u16,22359u16),(30308u16,21022u16), (30313u16,15958u16),(30316u16,18185u16),(30320u16,19690u16),(30322u16,21001u16), (30328u16,14539u16),(30331u16,15949u16),(30332u16,17196u16),(30333u16,17255u16), (30334u16,17256u16),(30340u16,20865u16),(30342u16,14198u16),(30343u16,23518u16), (30350u16,14800u16),(30352u16,14568u16),(30355u16,23326u16),(30382u16,22906u16), (30394u16,22187u16),(30399u16,16824u16),(30402u16,19916u16),(30403u16,17240u16), (30406u16,17621u16),(30408u16,19510u16),(30410u16,20469u16),(30418u16,22971u16), (30422u16,14199u16),(30427u16,18237u16),(30428u16,15873u16),(30430u16,20666u16), (30431u16,16704u16),(30433u16,21620u16),(30435u16,14053u16),(30436u16,17084u16), (30439u16,16297u16),(30446u16,16860u16),(30450u16,16703u16),(30452u16,21598u16), (30456u16,18006u16),(30460u16,17085u16),(30462u16,18599u16),(30465u16,18238u16), (30468u16,16713u16),(30472u16,22530u16),(30473u16,17027u16),(30475u16,14020u16), (30494u16,21621u16),(30496u16,16714u16),(30505u16,23148u16),(30519u16,14994u16), (30520u16,16849u16),(30522u16,21235u16),(30524u16,18954u16),(30528u16,21778u16), (30541u16,23149u16),(30555u16,21071u16),(30561u16,18543u16),(30563u16,15894u16), (30566u16,16861u16),(30571u16,22011u16),(30585u16,15874u16),(30590u16,14569u16), (30591u16,19533u16),(30603u16,21622u16),(30609u16,16825u16),(30622u16,16655u16), (30629u16,17398u16),(30636u16,18600u16),(30637u16,16337u16),(30640u16,14054u16), (30643u16,15923u16),(30651u16,22000u16),(30652u16,14346u16),(30655u16,14941u16), (30679u16,22159u16),(30683u16,16850u16),(30684u16,15177u16),(30690u16,18752u16), (30691u16,20323u16),(30693u16,21582u16),(30697u16,14942u16),(30701u16,15688u16), (30702u16,19730u16),(30703u16,14801u16),(30707u16,18165u16),(30722u16,17832u16), (30738u16,17662u16),(30757u16,21583u16),(30758u16,21841u16),(30759u16,22384u16), (30764u16,16529u16),(30770u16,22768u16),(30772u16,22597u16),(30789u16,15114u16), (30799u16,19343u16),(30813u16,22141u16),(30827u16,16463u16),(30828u16,14412u16), (30831u16,19344u16),(30844u16,17636u16),(30849u16,15314u16),(30855u16,21072u16), (30860u16,16307u16),(30861u16,18989u16),(30862u16,18414u16),(30865u16,17663u16), (30871u16,19712u16),(30883u16,14034u16),(30887u16,17386u16),(30889u16,18166u16), (30906u16,23477u16),(30907u16,23478u16),(30908u16,16632u16),(30913u16,20639u16), (30917u16,17217u16),(30922u16,16325u16),(30923u16,21770u16),(30926u16,14540u16), (30928u16,17086u16),(30952u16,16633u16),(30956u16,14413u16),(30959u16,15315u16), (30965u16,14021u16),(30971u16,17087u16),(30977u16,22142u16),(30990u16,22143u16), (30998u16,19291u16),(31018u16,16131u16),(31019u16,16143u16),(31020u16,17088u16), (31034u16,18753u16),(31038u16,17833u16),(31040u16,17834u16),(31041u16,15316u16), (31047u16,15317u16),(31048u16,15318u16),(31049u16,21584u16),(31056u16,19917u16), (31062u16,21236u16),(31063u16,21585u16),(31066u16,21237u16),(31067u16,14223u16), (31068u16,23327u16),(31069u16,22205u16),(31070u16,18789u16),(31072u16,17835u16), (31077u16,18007u16),(31080u16,22794u16),(31085u16,21199u16),(31098u16,15319u16), (31103u16,16308u16),(31105u16,15160u16),(31117u16,23466u16),(31118u16,21073u16), (31119u16,17441u16),(31121u16,19918u16),(31142u16,19156u16),(31143u16,23746u16), (31146u16,18186u16),(31150u16,16286u16),(31153u16,15875u16),(31155u16,19139u16), (31161u16,19919u16),(31165u16,15161u16),(31166u16,23467u16),(31167u16,15895u16), (31168u16,18544u16),(31169u16,17836u16),(31177u16,17413u16),(31178u16,15507u16), (31179u16,22188u16),(31185u16,14726u16),(31186u16,22144u16),(31189u16,17664u16), (31192u16,17665u16),(31199u16,21238u16),(31204u16,22388u16),(31206u16,21623u16), (31207u16,18980u16),(31209u16,21646u16),(31227u16,20450u16),(31232u16,23747u16), (31237u16,18345u16),(31240u16,14022u16),(31243u16,21074u16),(31245u16,22145u16), (31252u16,20514u16),(31255u16,22718u16),(31257u16,21599u16),(31258u16,22360u16), (31260u16,16485u16),(31263u16,22897u16),(31264u16,21239u16),(31278u16,21275u16), (31281u16,22389u16),(31286u16,19938u16),(31287u16,21600u16),(31291u16,15876u16), (31292u16,13984u16),(31293u16,14541u16),(31295u16,14570u16),(31296u16,14593u16), (31302u16,16862u16),(31305u16,22361u16),(31309u16,20866u16),(31310u16,19511u16), (31319u16,18545u16),(31329u16,18021u16),(31330u16,19534u16),(31337u16,19682u16), (31339u16,23479u16),(31344u16,19140u16),(31348u16,23160u16),(31350u16,14943u16), (31353u16,14981u16),(31354u16,14621u16),(31357u16,21075u16),(31359u16,21975u16), (31361u16,15910u16),(31364u16,21779u16),(31368u16,19856u16),(31378u16,21647u16), (31379u16,21830u16),(31381u16,21240u16),(31384u16,14970u16),(31391u16,14978u16), (31401u16,19697u16),(31402u16,19698u16),(31406u16,14982u16),(31407u16,19857u16), (31418u16,15115u16),(31428u16,21788u16),(31429u16,15116u16),(31431u16,15933u16), (31434u16,21023u16),(31435u16,16626u16),(31447u16,16878u16),(31449u16,21810u16), (31453u16,17414u16),(31455u16,14414u16),(31456u16,20696u16),(31459u16,21441u16), (31461u16,15924u16),(31466u16,18546u16),(31469u16,14035u16),(31471u16,15689u16), (31478u16,14415u16),(31481u16,21426u16),(31482u16,22206u16),(31487u16,14023u16), (31503u16,23353u16),(31505u16,18372u16),(31513u16,18028u16),(31515u16,20867u16), (31518u16,22549u16),(31520u16,16627u16),(31526u16,17587u16),(31532u16,21200u16), (31533u16,16274u16),(31545u16,18346u16),(31558u16,22917u16),(31561u16,15950u16), (31563u16,15146u16),(31564u16,21002u16),(31565u16,18601u16),(31567u16,17269u16), (31568u16,14769u16),(31569u16,22207u16),(31570u16,22568u16),(31572u16,15720u16), (31574u16,21849u16),(31584u16,15126u16),(31596u16,18239u16),(31598u16,18046u16), (31605u16,19346u16),(31613u16,19669u16),(31623u16,14200u16),(31627u16,21003u16), (31631u16,20825u16),(31636u16,17061u16),(31637u16,15320u16),(31639u16,17964u16), (31642u16,21771u16),(31645u16,14381u16),(31649u16,14748u16),(31661u16,21004u16), (31665u16,18008u16),(31668u16,20670u16),(31672u16,20843u16),(31680u16,21024u16), (31681u16,23519u16),(31684u16,17279u16),(31686u16,21005u16),(31687u16,22730u16), (31689u16,22208u16),(31698u16,18772u16),(31712u16,18373u16),(31716u16,15896u16), (31721u16,17837u16),(31751u16,21259u16),(31762u16,21789u16),(31774u16,15690u16), (31777u16,14024u16),(31783u16,23520u16),(31786u16,20671u16),(31787u16,18374u16), (31805u16,22001u16),(31806u16,16264u16),(31807u16,17588u16),(31811u16,16085u16), (31820u16,21410u16),(31821u16,20868u16),(31840u16,16320u16),(31844u16,22002u16), (31852u16,16505u16),(31859u16,17028u16),(31875u16,17666u16),(31881u16,17622u16), (31890u16,16628u16),(31893u16,17062u16),(31895u16,21241u16),(31896u16,21031u16), (31903u16,18391u16),(31909u16,21427u16),(31911u16,20697u16),(31918u16,16114u16), (31921u16,16115u16),(31922u16,21791u16),(31923u16,14210u16),(31929u16,18547u16), (31934u16,21076u16),(31946u16,23328u16),(31958u16,15731u16),(31966u16,17623u16), (31967u16,21242u16),(31968u16,14174u16),(31975u16,16116u16),(31995u16,14542u16), (31998u16,15117u16),(32000u16,15321u16),(32002u16,21411u16),(32004u16,19114u16), (32005u16,23360u16),(32006u16,19920u16),(32007u16,23719u16),(32008u16,23493u16), (32010u16,17007u16),(32011u16,17008u16),(32013u16,15486u16),(32016u16,15564u16), (32020u16,18602u16),(32023u16,17838u16),(32024u16,14785u16),(32025u16,21586u16), (32026u16,15173u16),(32027u16,17624u16),(32032u16,18375u16),(32033u16,17218u16), (32034u16,18022u16),(32043u16,20640u16),(32044u16,21412u16),(32046u16,21802u16), (32047u16,16446u16),(32048u16,18347u16),(32051u16,18790u16),(32053u16,20844u16), (32057u16,18376u16),(32058u16,14055u16),(32066u16,21276u16),(32067u16,23150u16), (32068u16,21243u16),(32069u16,14416u16),(32070u16,17089u16),(32080u16,14376u16), (32094u16,14802u16),(32097u16,16064u16),(32098u16,23151u16),(32102u16,15174u16), (32104u16,20289u16),(32106u16,20488u16),(32110u16,18047u16),(32113u16,22569u16), (32114u16,17839u16),(32115u16,14175u16),(32118u16,21025u16),(32121u16,14366u16), (32127u16,14944u16),(32142u16,21077u16),(32143u16,18548u16),(32147u16,14417u16), (32156u16,21277u16),(32160u16,16309u16),(32162u16,21413u16),(32172u16,18549u16), (32173u16,20246u16),(32177u16,14176u16),(32178u16,16674u16),(32180u16,21991u16), (32181u16,21842u16),(32184u16,16473u16),(32186u16,15322u16),(32187u16,22525u16), (32189u16,20657u16),(32190u16,16486u16),(32191u16,16715u16),(32199u16,22362u16), (32202u16,15339u16),(32203u16,17667u16),(32214u16,18048u16),(32216u16,22964u16), (32218u16,18187u16),(32221u16,21658u16),(32222u16,15691u16),(32224u16,22028u16), (32225u16,17046u16),(32227u16,19347u16),(32232u16,22731u16),(32233u16,19713u16), (32236u16,16716u16),(32239u16,20098u16),(32244u16,16248u16),(32251u16,22363u16), (32265u16,21624u16),(32266u16,18997u16),(32277u16,19683u16),(32283u16,17063u16), (32285u16,21625u16),(32286u16,23329u16),(32287u16,19873u16),(32289u16,20818u16), (32291u16,23152u16),(32299u16,17463u16),(32302u16,22209u16),(32303u16,19349u16), (32305u16,21278u16),(32311u16,16447u16),(32317u16,22172u16),(32318u16,20869u16), (32321u16,17264u16),(32323u16,17637u16),(32326u16,16895u16),(32327u16,19858u16), (32338u16,21464u16),(32340u16,21601u16),(32341u16,18188u16),(32350u16,19859u16), (32353u16,18550u16),(32361u16,18732u16),(32362u16,23540u16),(32363u16,14543u16), (32365u16,14367u16),(32368u16,21244u16),(32377u16,19311u16),(32380u16,14544u16), (32386u16,21790u16),(32396u16,18392u16),(32399u16,21006u16),(32403u16,19512u16), (32406u16,18218u16),(32408u16,21792u16),(32411u16,15897u16),(32412u16,16086u16), (32566u16,17589u16),(32568u16,22987u16),(32570u16,14377u16),(32588u16,19097u16), (32592u16,14749u16),(32596u16,16675u16),(32597u16,22949u16),(32618u16,21385u16), (32619u16,14774u16),(32622u16,22364u16),(32624u16,17270u16),(32626u16,18049u16), (32629u16,16690u16),(32631u16,22598u16),(32633u16,16506u16),(32645u16,15959u16), (32648u16,15323u16),(32650u16,19142u16),(32652u16,14177u16),(32654u16,17029u16), (32660u16,14571u16),(32666u16,16275u16),(32670u16,18551u16),(32676u16,14971u16), (32680u16,18189u16),(32681u16,20324u16),(32690u16,23748u16),(32696u16,16507u16), (32697u16,14211u16),(32701u16,19921u16),(32705u16,19691u16),(32709u16,18754u16), (32714u16,20470u16),(32716u16,20471u16),(32718u16,16276u16),(32722u16,18722u16), (32724u16,18009u16),(32725u16,23727u16),(32735u16,20870u16),(32736u16,22333u16), (32737u16,17668u16),(32745u16,22732u16),(32747u16,19714u16),(32752u16,22950u16), (32761u16,14803u16),(32764u16,20472u16),(32768u16,19860u16),(32769u16,16298u16), (32771u16,14572u16),(32773u16,20641u16),(32774u16,15324u16),(32777u16,14945u16), (32780u16,20452u16),(32784u16,15502u16),(32789u16,14418u16),(32791u16,16851u16), (32792u16,19947u16),(32813u16,15325u16),(32819u16,20453u16),(32822u16,19108u16), (32829u16,22531u16),(32831u16,14419u16),(32835u16,15711u16),(32838u16,16277u16), (32842u16,16338u16),(32854u16,18336u16),(32856u16,17794u16),(32858u16,22334u16), (32862u16,17009u16),(32879u16,16249u16),(32880u16,22173u16),(32882u16,18337u16), (32883u16,19893u16),(32887u16,21602u16),(32893u16,22018u16),(32894u16,16321u16), (32895u16,20286u16),(32900u16,20454u16),(32901u16,18585u16),(32902u16,17840u16), (32903u16,21245u16),(32905u16,20266u16),(32907u16,16481u16),(32908u16,15326u16), (32918u16,22146u16),(32923u16,22988u16),(32925u16,14025u16),(32929u16,14573u16), (32930u16,21587u16),(32933u16,17669u16),(32937u16,14368u16),(32938u16,17219u16), (32943u16,15178u16),(32945u16,14786u16),(32946u16,20267u16),(32948u16,23657u16), (32954u16,22748u16),(32963u16,20099u16),(32964u16,21391u16),(32972u16,17241u16), (32974u16,22550u16),(32986u16,17242u16),(32987u16,14159u16),(32990u16,22769u16), (32993u16,23330u16),(32996u16,20277u16),(32997u16,18146u16),(33009u16,14770u16), (33012u16,15925u16),(33016u16,23711u16),(33021u16,15571u16),(33026u16,21588u16), (33029u16,23171u16),(33030u16,22335u16),(33031u16,23172u16),(33032u16,16695u16), (33034u16,21962u16),(33048u16,19715u16),(33050u16,14002u16),(33051u16,14420u16), (33059u16,18603u16),(33065u16,18552u16),(33067u16,22528u16),(33071u16,22770u16), (33081u16,21831u16),(33086u16,17766u16),(33099u16,18998u16),(33102u16,18791u16), (33104u16,17590u16),(33105u16,17591u16),(33108u16,14178u16),(33109u16,19716u16), (33125u16,18338u16),(33126u16,15549u16),(33131u16,21279u16),(33136u16,19861u16), (33137u16,14237u16),(33144u16,20698u16),(33145u16,17442u16),(33146u16,18190u16), (33151u16,22573u16),(33152u16,17220u16),(33160u16,14359u16),(33162u16,17064u16), (33167u16,14574u16),(33178u16,17592u16),(33180u16,16640u16),(33181u16,18718u16), (33184u16,14804u16),(33187u16,21648u16),(33192u16,22724u16),(33203u16,18191u16), (33205u16,22228u16),(33210u16,20311u16),(33213u16,15712u16),(33214u16,23541u16), (33215u16,15544u16),(33216u16,15940u16),(33218u16,17767u16),(33222u16,19165u16), (33229u16,21201u16),(33240u16,16091u16),(33247u16,20699u16),(33251u16,18792u16), (33253u16,19699u16),(33255u16,20700u16),(33256u16,16527u16),(33258u16,20642u16), (33261u16,22336u16),(33267u16,21589u16),(33268u16,22365u16),(33274u16,15745u16), (33275u16,21626u16),(33276u16,14946u16),(33278u16,20247u16),(33285u16,14947u16), (33287u16,19293u16),(33288u16,23728u16),(33290u16,14948u16),(33292u16,18208u16), (33293u16,17841u16),(33298u16,18147u16),(33307u16,21976u16),(33308u16,18604u16), (33310u16,16896u16),(33311u16,21414u16),(33313u16,14179u16),(33322u16,22989u16), (33323u16,17221u16),(33324u16,17090u16),(33333u16,22401u16),(33334u16,17065u16), (33335u16,23153u16),(33337u16,18192u16),(33344u16,17593u16),(33349u16,19294u16), (33351u16,21078u16),(33369u16,21832u16),(33380u16,20325u16),(33382u16,22965u16), (33390u16,14026u16),(33391u16,16117u16),(33393u16,14027u16),(33394u16,18023u16), (33398u16,19378u16),(33400u16,22147u16),(33406u16,18990u16),(33419u16,19922u16), (33421u16,20658u16),(33422u16,14983u16),(33426u16,16676u16),(33433u16,17594u16), (33434u16,15941u16),(33437u16,21590u16),(33439u16,17978u16),(33445u16,14201u16), (33446u16,23331u16),(33449u16,15162u16),(33452u16,17625u16),(33453u16,22599u16), (33454u16,19535u16),(33455u16,18910u16),(33457u16,23468u16),(33459u16,17222u16), (33463u16,21591u16),(33464u16,19948u16),(33465u16,15147u16),(33467u16,22189u16), (33468u16,16852u16),(33469u16,18925u16),(33471u16,20622u16),(33489u16,20074u16), (33490u16,19379u16),(33492u16,22551u16),(33493u16,22148u16),(33495u16,16879u16), (33499u16,13985u16),(33502u16,22771u16),(33503u16,14949u16),(33505u16,20455u16), (33509u16,19115u16),(33510u16,14575u16),(33511u16,20845u16),(33521u16,19515u16), (33533u16,14576u16),(33534u16,22918u16),(33537u16,21447u16),(33538u16,16897u16), (33539u16,17280u16),(33540u16,13986u16),(33541u16,16853u16),(33545u16,16666u16), (33559u16,16826u16),(33576u16,20643u16),(33579u16,16677u16),(33583u16,17443u16), (33585u16,18553u16),(33588u16,23542u16),(33589u16,20489u16),(33590u16,15579u16), (33592u16,19894u16),(33593u16,19295u16),(33600u16,18605u16),(33607u16,23112u16), (33609u16,22149u16),(33610u16,23285u16),(33615u16,20516u16),(33617u16,20456u16), (33618u16,23521u16),(33651u16,15934u16),(33655u16,22930u16),(33659u16,20871u16), (33673u16,16508u16),(33674u16,20701u16),(33678u16,17842u16),(33686u16,14421u16), (33688u16,18793u16),(33694u16,19717u16),(33698u16,23173u16),(33705u16,17595u16), (33706u16,18926u16),(33707u16,16641u16),(33725u16,16678u16),(33729u16,22019u16), (33733u16,14750u16),(33737u16,16310u16),(33738u16,14965u16),(33740u16,15127u16), (33747u16,14727u16),(33750u16,21833u16),(33756u16,21843u16),(33769u16,17429u16), (33771u16,15148u16),(33775u16,23469u16),(33776u16,14577u16),(33777u16,16487u16), (33778u16,17768u16),(33780u16,18969u16),(33785u16,20846u16),(33789u16,18586u16), (33795u16,22229u16),(33796u16,15877u16),(33802u16,16104u16),(33804u16,16705u16), (33805u16,22740u16),(33806u16,20100u16),(33833u16,22190u16),(33836u16,16656u16), (33841u16,23687u16),(33848u16,20248u16),(33853u16,16065u16),(33865u16,19483u16), (33879u16,20847u16),(33883u16,14036u16),(33889u16,22772u16),(33891u16,15926u16), (33894u16,20101u16),(33899u16,23332u16),(33900u16,20702u16),(33903u16,19116u16), (33909u16,15118u16),(33914u16,21456u16),(33936u16,18554u16),(33940u16,18755u16), (33945u16,16868u16),(33948u16,17965u16),(33953u16,17223u16),(33970u16,22773u16), (33976u16,21465u16),(33979u16,19117u16),(33980u16,21834u16),(33983u16,23333u16), (33984u16,18399u16),(33986u16,16827u16),(33988u16,22210u16),(33990u16,18167u16), (33993u16,19895u16),(33995u16,14202u16),(33997u16,18756u16),(34001u16,17843u16), (34010u16,18555u16),(34028u16,17464u16),(34030u16,16250u16),(34036u16,18606u16), (34044u16,16339u16),(34065u16,16816u16),(34067u16,16657u16),(34068u16,17444u16), (34071u16,20644u16),(34072u16,17979u16),(34074u16,20050u16),(34078u16,16448u16), (34081u16,21844u16),(34083u16,20703u16),(34085u16,22174u16),(34092u16,18377u16), (34093u16,20302u16),(34095u16,21627u16),(34109u16,22749u16),(34111u16,20102u16), (34113u16,15713u16),(34115u16,17265u16),(34121u16,22150u16),(34126u16,14805u16), (34131u16,19949u16),(34137u16,23297u16),(34147u16,18607u16),(34152u16,14997u16), (34153u16,22540u16),(34154u16,16898u16),(34157u16,18378u16),(34180u16,17066u16), (34183u16,17030u16),(34191u16,20326u16),(34193u16,14180u16),(34196u16,20704u16), (34203u16,18209u16),(34214u16,21977u16),(34216u16,23683u16),(34217u16,17972u16), (34218u16,18794u16),(34223u16,18148u16),(34224u16,23680u16),(34234u16,21202u16), (34241u16,14578u16),(34249u16,20645u16),(34253u16,16087u16),(34254u16,18795u16), (34255u16,20705u16),(34261u16,19923u16),(34268u16,16132u16),(34269u16,19536u16), (34276u16,15951u16),(34277u16,19118u16),(34281u16,17266u16),(34282u16,18556u16), (34295u16,20848u16),(34298u16,16519u16),(34299u16,21246u16),(34303u16,14736u16), (34306u16,19537u16),(34310u16,16299u16),(34311u16,18379u16),(34314u16,19684u16), (34326u16,19173u16),(34327u16,17387u16),(34330u16,18193u16),(34349u16,16076u16), (34367u16,16056u16),(34382u16,23334u16),(34384u16,22938u16),(34388u16,14238u16), (34389u16,21950u16),(34395u16,23125u16),(34396u16,16300u16),(34398u16,19924u16), (34399u16,23335u16),(34407u16,23703u16),(34425u16,23361u16),(34442u16,17010u16), (34444u16,17224u16),(34451u16,20491u16),(34467u16,14622u16),(34468u16,21247u16), (34473u16,22366u16),(34503u16,17844u16),(34507u16,15692u16),(34516u16,23543u16), (34521u16,19700u16),(34523u16,21415u16),(34527u16,14806u16),(34532u16,22972u16), (34541u16,21649u16),(34558u16,18927u16),(34560u16,22160u16),(34562u16,17465u16), (34563u16,18796u16),(34568u16,19670u16),(34584u16,21592u16),(34586u16,17769u16), (34588u16,17049u16),(34638u16,14038u16),(34645u16,18773u16),(34647u16,23522u16), (34655u16,20103u16),(34662u16,22931u16),(34664u16,18719u16),(34676u16,23336u16), (34678u16,21037u16),(34680u16,19701u16),(34690u16,16099u16),(34701u16,20290u16), (34719u16,16828u16),(34722u16,23286u16),(34739u16,15732u16),(34746u16,16057u16), (34756u16,22387u16),(34784u16,17091u16),(34796u16,18194u16),(34799u16,19863u16), (34802u16,22224u16),(34809u16,23100u16),(34811u16,20327u16),(34814u16,18219u16), (34821u16,18733u16),(34847u16,16092u16),(34850u16,21442u16),(34851u16,16133u16), (34865u16,14579u16),(34870u16,20672u16),(34875u16,16658u16),(34880u16,23161u16), (34886u16,21450u16),(34892u16,23113u16),(34893u16,19351u16),(34898u16,23154u16), (34899u16,18615u16),(34903u16,13987u16),(34905u16,18928u16),(34907u16,20104u16), (34909u16,22225u16),(34913u16,23287u16),(34914u16,14950u16),(34915u16,20328u16), (34920u16,22795u16),(34923u16,17980u16),(34928u16,18416u16),(34930u16,15489u16), (34935u16,22226u16),(34942u16,15163u16),(34943u16,15164u16),(34945u16,20075u16), (34946u16,16832u16),(34952u16,13988u16),(34955u16,15746u16),(34957u16,22774u16), (34962u16,15693u16),(34966u16,18557u16),(34967u16,21628u16),(34974u16,14604u16), (34987u16,22907u16),(34996u16,14580u16),(35009u16,20819u16),(35010u16,16259u16), (35023u16,16509u16),(35028u16,19539u16),(35029u16,20249u16),(35033u16,14972u16), (35036u16,17430u16),(35037u16,20706u16),(35039u16,17845u16),(35041u16,16510u16), (35048u16,17770u16),(35059u16,18010u16),(35060u16,17243u16),(35061u16,17244u16), (35064u16,16058u16),(35069u16,21203u16),(35079u16,17445u16),(35088u16,14037u16), (35090u16,22775u16),(35091u16,17431u16),(35096u16,20105u16),(35097u16,17245u16), (35109u16,19874u16),(35114u16,22574u16),(35126u16,18723u16),(35128u16,16449u16), (35131u16,18210u16),(35137u16,14181u16),(35140u16,19144u16),(35167u16,15165u16), (35172u16,16088u16),(35178u16,16667u16),(35186u16,18724u16),(35199u16,18149u16), (35201u16,19864u16),(35203u16,15714u16),(35206u16,17446u16),(35207u16,22719u16), (35211u16,14369u16),(35215u16,15119u16),(35219u16,16707u16),(35222u16,18757u16), (35233u16,14360u16),(35241u16,15878u16),(35242u16,22374u16),(35250u16,15149u16), (35258u16,14003u16),(35261u16,16089u16),(35264u16,14751u16),(35282u16,14004u16), (35299u16,23101u16),(35316u16,18011u16),(35320u16,22161u16),(35328u16,19170u16), (35330u16,21079u16),(35331u16,17596u16),(35336u16,14545u16),(35338u16,18797u16), (35340u16,23362u16),(35342u16,22563u16),(35347u16,23681u16),(35350u16,23720u16), (35351u16,22419u16),(35352u16,15327u16),(35355u16,19702u16),(35357u16,18929u16), (35359u16,18407u16),(35363u16,14378u16),(35365u16,15562u16),(35370u16,17225u16), (35373u16,18211u16),(35377u16,23126u16),(35380u16,18380u16),(35382u16,13989u16), (35386u16,21629u16),(35387u16,21416u16),(35408u16,17846u16),(35412u16,21248u16), (35413u16,22741u16),(35419u16,20849u16),(35422u16,17847u16),(35424u16,19516u16), (35426u16,18608u16),(35427u16,19540u16),(35430u16,18758u16),(35433u16,18759u16), (35437u16,15003u16),(35438u16,21007u16),(35440u16,23749u16),(35441u16,23470u16), (35442u16,23102u16),(35443u16,18012u16),(35445u16,18195u16),(35449u16,22003u16), (35461u16,21417u16),(35463u16,14728u16),(35468u16,21593u16),(35469u16,20492u16), (35475u16,18150u16),(35477u16,22526u16),(35480u16,20250u16),(35486u16,19157u16), (35488u16,18339u16),(35489u16,14546u16),(35491u16,16899u16),(35492u16,19671u16), (35493u16,14581u16),(35494u16,18408u16),(35496u16,23544u16),(35498u16,18212u16), (35504u16,18558u16),(35506u16,14729u16),(35513u16,17771u16),(35516u16,20329u16), (35518u16,20296u16),(35519u16,21249u16),(35522u16,22004u16),(35524u16,18609u16), (35527u16,15715u16),(35531u16,22020u16),(35533u16,20826u16),(35535u16,22191u16), (35538u16,16118u16),(35542u16,16314u16),(35547u16,20251u16),(35548u16,22012u16), (35553u16,18760u16),(35558u16,22029u16),(35559u16,23103u16),(35562u16,21080u16), (35563u16,14028u16),(35565u16,20252u16),(35566u16,20646u16),(35569u16,23696u16), (35574u16,18911u16),(35575u16,22899u16),(35576u16,21204u16),(35578u16,19171u16), (35582u16,15366u16),(35584u16,16854u16),(35585u16,18960u16),(35586u16,20106u16), (35588u16,15952u16),(35598u16,17031u16),(35600u16,17050u16),(35604u16,22939u16), (35606u16,18393u16),(35607u16,17226u16),(35609u16,14382u16),(35610u16,20473u16), (35611u16,14182u16),(35613u16,17848u16),(35616u16,19865u16),(35624u16,16855u16), (35627u16,20872u16),(35628u16,16464u16),(35635u16,14951u16),(35641u16,15150u16), (35649u16,23471u16),(35657u16,21466u16),(35662u16,23705u16),(35663u16,15328u16), (35672u16,18774u16),(35674u16,15716u16),(35676u16,17432u16),(35686u16,14422u16), (35692u16,17772u16),(35695u16,19312u16),(35696u16,20426u16),(35700u16,14370u16), (35703u16,23337u16),(35709u16,19541u16),(35712u16,15898u16),(35722u16,17393u16), (35728u16,18559u16),(35730u16,21811u16),(35731u16,19146u16),(35734u16,21812u16), (35738u16,21793u16),(35895u16,14594u16),(35903u16,14547u16),(35905u16,23500u16), (35910u16,15936u16),(35912u16,15329u16),(35914u16,22900u16),(35916u16,19718u16), (35925u16,18761u16),(35930u16,15907u16),(35937u16,18013u16),(35946u16,23338u16), (35947u16,19542u16),(35961u16,22796u16),(35962u16,18762u16),(35970u16,22151u16), (35978u16,16696u16),(35980u16,16856u16),(35997u16,22720u16),(35998u16,21081u16), (36000u16,17597u16),(36001u16,20820u16),(36002u16,14623u16),(36007u16,17789u16), (36008u16,23472u16),(36009u16,22607u16),(36010u16,22532u16),(36011u16,14752u16), (36012u16,21946u16),(36015u16,20850u16),(36016u16,18349u16),(36019u16,20460u16), (36020u16,15009u16),(36022u16,22736u16),(36023u16,16691u16),(36024u16,15747u16), (36027u16,17773u16),(36028u16,22013u16),(36029u16,20459u16),(36031u16,16900u16), (36032u16,22932u16),(36033u16,17626u16),(36034u16,16326u16),(36035u16,20517u16), (36036u16,23545u16),(36039u16,20647u16),(36040u16,13990u16),(36042u16,20873u16), (36049u16,21630u16),(36051u16,17790u16),(36058u16,16327u16),(36060u16,17849u16), (36062u16,18014u16),(36064u16,17246u16),(36066u16,23156u16),(36067u16,16692u16), (36068u16,21978u16),(36070u16,17598u16),(36074u16,21650u16),(36077u16,15879u16), (36084u16,16328u16),(36091u16,17599u16),(36092u16,14952u16),(36093u16,18018u16), (36100u16,21595u16),(36101u16,22326u16),(36103u16,20278u16),(36104u16,21467u16), (36106u16,21794u16),(36109u16,18220u16),(36115u16,20707u16),(36118u16,18394u16), (36196u16,20874u16),(36198u16,17850u16),(36203u16,23136u16),(36208u16,21418u16), (36211u16,15120u16),(36212u16,17600u16),(36215u16,15330u16),(36229u16,22152u16), (36234u16,20083u16),(36249u16,21250u16),(36259u16,22337u16),(36264u16,22192u16), (36275u16,21260u16),(36282u16,17601u16),(36286u16,21596u16),(36294u16,22552u16), (36299u16,17197u16),(36300u16,21651u16),(36303u16,13991u16),(36315u16,22600u16), (36317u16,14224u16),(36321u16,20875u16),(36323u16,18196u16),(36328u16,14730u16), (36335u16,16301u16),(36339u16,15880u16),(36362u16,19896u16),(36367u16,15721u16), (36368u16,21979u16),(36382u16,14225u16),(36394u16,21376u16),(36400u16,20253u16), (36405u16,21377u16),(36418u16,20254u16),(36420u16,21205u16),(36423u16,14239u16), (36424u16,15881u16),(36425u16,21773u16),(36426u16,23298u16),(36441u16,22211u16), (36447u16,20876u16),(36448u16,21963u16),(36468u16,22212u16),(36470u16,14998u16), (36481u16,21251u16),(36487u16,20851u16),(36490u16,21419u16),(36493u16,19119u16), (36522u16,16520u16),(36523u16,18798u16),(36524u16,14984u16),(36544u16,14953u16), (36554u16,21774u16),(36555u16,18961u16),(36556u16,15004u16),(36557u16,14973u16), (36562u16,23130u16),(36575u16,19352u16),(36587u16,21631u16),(36600u16,22213u16), (36603u16,13992u16),(36606u16,18775u16),(36611u16,14807u16),(36613u16,16302u16), (36617u16,20821u16),(36626u16,22014u16),(36627u16,16659u16),(36628u16,17433u16), (36629u16,14423u16),(36635u16,16119u16),(36636u16,22367u16),(36637u16,23697u16), (36638u16,16679u16),(36639u16,21992u16),(36646u16,16251u16),(36647u16,17415u16), (36649u16,17247u16),(36650u16,16474u16),(36655u16,21659u16),(36659u16,21420u16), (36664u16,18560u16),(36665u16,17447u16),(36667u16,17448u16),(36670u16,21008u16), (36671u16,19296u16),(36676u16,22956u16),(36677u16,20076u16),(36681u16,21009u16), (36685u16,21993u16),(36686u16,14808u16),(36701u16,19297u16),(36703u16,14787u16), (36706u16,16144u16),(36763u16,18799u16),(36764u16,14583u16),(36771u16,16079u16), (36774u16,22608u16),(36776u16,17394u16),(36781u16,17851u16),(36783u16,17395u16), (36784u16,21632u16),(36785u16,19875u16),(36786u16,15545u16),(36802u16,19925u16), (36805u16,18801u16),(36814u16,19517u16),(36817u16,15151u16),(36820u16,17092u16), (36838u16,13993u16),(36842u16,20877u16),(36843u16,17067u16),(36845u16,21652u16), (36848u16,18616u16),(36850u16,14351u16),(36855u16,17032u16),(36857u16,20878u16), (36861u16,22193u16),(36864u16,22575u16),(36865u16,18409u16),(36866u16,14758u16), (36867u16,15882u16),(36869u16,23672u16),(36870u16,19314u16),(36872u16,23288u16), (36875u16,22776u16),(36877u16,18381u16),(36879u16,22581u16),(36880u16,22214u16), (36881u16,14954u16),(36884u16,15883u16),(36885u16,14424u16),(36887u16,15937u16), (36889u16,20852u16),(36890u16,22570u16),(36893u16,18151u16),(36894u16,16278u16), (36895u16,18395u16),(36896u16,21252u16),(36897u16,21443u16),(36898u16,17466u16), (36899u16,16252u16),(36910u16,22030u16),(36913u16,21421u16),(36914u16,21633u16), (36917u16,15121u16),(36920u16,20504u16),(36924u16,22921u16),(36926u16,20256u16), (36929u16,15942u16),(36930u16,18561u16),(36935u16,19926u16),(36938u16,20255u16), (36939u16,20046u16),(36941u16,22733u16),(36942u16,14731u16),(36944u16,22933u16), (36945u16,23523u16),(36947u16,15884u16),(36948u16,15700u16),(36949u16,20107u16), (36953u16,19866u16),(36956u16,18400u16),(36957u16,15722u16),(36958u16,22031u16), (36960u16,20077u16),(36961u16,18382u16),(36963u16,14371u16),(36969u16,20879u16), (36973u16,21253u16),(36974u16,21775u16),(36975u16,15943u16),(36978u16,21597u16), (36981u16,21444u16),(36983u16,21980u16),(36984u16,18197u16),(36986u16,20257u16), (36988u16,16436u16),(36989u16,14227u16),(36991u16,22908u16),(36992u16,19868u16), (36993u16,16693u16),(36994u16,23104u16),(36995u16,18562u16),(36996u16,23494u16), (36999u16,20461u16),(37000u16,16642u16),(37002u16,17396u16),(37007u16,16059u16), (37009u16,20308u16),(37013u16,19692u16),(37017u16,16680u16),(37026u16,23289u16), (37027u16,15360u16),(37030u16,17227u16),(37032u16,22165u16),(37034u16,17852u16), (37039u16,14056u16),(37040u16,22553u16),(37041u16,14955u16),(37045u16,18383u16), (37048u16,20853u16),(37057u16,19939u16),(37066u16,14809u16),(37086u16,16100u16), (37089u16,14974u16),(37096u16,17602u16),(37101u16,14737u16),(37109u16,19927u16), (37117u16,15885u16),(37122u16,18944u16),(37138u16,22194u16),(37141u16,23118u16), (37145u16,17774u16),(37159u16,15953u16),(37165u16,21082u16),(37170u16,15694u16), (37193u16,20258u16),(37194u16,21083u16),(37195u16,22195u16),(37196u16,20659u16), (37197u16,17248u16),(37198u16,21422u16),(37202u16,21423u16),(37218u16,22153u16), (37225u16,16829u16),(37226u16,16067u16),(37228u16,18563u16),(37237u16,23658u16), (37239u16,23344u16),(37240u16,17966u16),(37255u16,18610u16),(37257u16,22338u16), (37259u16,22154u16),(37261u16,21206u16),(37266u16,18340u16),(37276u16,22196u16), (37291u16,20427u16),(37292u16,20708u16),(37294u16,22155u16),(37295u16,23299u16), (37297u16,17198u16),(37300u16,16287u16),(37301u16,14212u16),(37312u16,19147u16), (37319u16,21845u16),(37321u16,20259u16),(37323u16,18168u16),(37324u16,16511u16), (37325u16,21451u16),(37326u16,19110u16),(37327u16,16120u16),(37328u16,16512u16), (37329u16,15344u16),(37335u16,18417u16),(37336u16,21084u16),(37340u16,17603u16), (37341u16,22385u16),(37347u16,21254u16),(37351u16,21981u16),(37354u16,19928u16), (37365u16,21846u16),(37389u16,15944u16),(37392u16,14347u16),(37393u16,22609u16), (37394u16,17983u16),(37399u16,20280u16),(37406u16,15128u16),(37428u16,16279u16), (37434u16,19678u16),(37439u16,21010u16),(37440u16,14160u16),(37445u16,14228u16), (37449u16,23157u16),(37463u16,14383u16),(37467u16,19356u16),(37470u16,20084u16), (37474u16,17199u16),(37476u16,14956u16),(37477u16,18617u16),(37478u16,21085u16), (37504u16,20297u16),(37507u16,22175u16),(37509u16,15927u16),(37521u16,18198u16), (37523u16,21011u16),(37526u16,18564u16),(37528u16,16830u16),(37532u16,22966u16), (37555u16,19544u16),(37558u16,14957u16),(37559u16,18384u16),(37561u16,18565u16), (37580u16,21086u16),(37583u16,23174u16),(37586u16,17467u16),(37604u16,18152u16), (37610u16,22777u16),(37624u16,14229u16),(37628u16,14183u16),(37636u16,16311u16), (37648u16,22197u16),(37656u16,22198u16),(37658u16,20827u16),(37662u16,18611u16), (37663u16,15717u16),(37664u16,21087u16),(37665u16,15331u16),(37666u16,21012u16), (37668u16,15332u16),(37670u16,15167u16),(37672u16,16880u16),(37675u16,18169u16), (37678u16,14584u16),(37679u16,21780u16),(37704u16,19519u16),(37706u16,16253u16), (37707u16,14732u16),(37709u16,15886u16),(37716u16,18945u16),(37723u16,15695u16), (37742u16,20260u16),(37749u16,14240u16),(37756u16,22386u16),(37758u16,21378u16), (37772u16,14384u16),(37780u16,19897u16),(37782u16,18415u16),(37786u16,22199u16), (37795u16,23290u16),(37799u16,14204u16),(37804u16,23339u16),(37805u16,21634u16), (37808u16,20505u16),(37827u16,21261u16),(37841u16,20880u16),(37854u16,19898u16), (37857u16,14425u16),(37860u16,16450u16),(37878u16,21756u16),(37892u16,23550u16), (37912u16,21379u16),(37925u16,18199u16),(37931u16,21013u16),(37941u16,21994u16), (37944u16,22516u16),(37956u16,21424u16),(37969u16,14057u16),(37970u16,14058u16), (37979u16,14771u16),(38013u16,21795u16),(38015u16,21781u16),(38263u16,20709u16), (38272u16,17011u16),(38275u16,18221u16),(38281u16,22750u16),(38283u16,14205u16), (38287u16,20281u16),(38289u16,22951u16),(38290u16,22952u16),(38291u16,14029u16), (38292u16,17047u16),(38296u16,14161u16),(38307u16,14005u16),(38308u16,22973u16), (38309u16,17271u16),(38312u16,15122u16),(38317u16,16134u16),(38321u16,19368u16), (38331u16,19477u16),(38332u16,18962u16),(38343u16,18970u16),(38346u16,23501u16), (38356u16,22974u16),(38357u16,14999u16),(38358u16,22585u16),(38364u16,14753u16), (38369u16,21982u16),(38370u16,17388u16),(38428u16,17604u16),(38433u16,21983u16), (38442u16,22706u16),(38446u16,19719u16),(38450u16,17228u16),(38459u16,21255u16), (38463u16,18930u16),(38464u16,22402u16),(38466u16,22909u16),(38468u16,17605u16), (38475u16,16451u16),(38476u16,16697u16),(38477u16,14184u16),(38480u16,22953u16), (38491u16,22751u16),(38492u16,22975u16),(38493u16,18222u16),(38494u16,18734u16), (38495u16,21964u16),(38498u16,20079u16),(38499u16,21635u16),(38500u16,21207u16), (38506u16,17249u16),(38512u16,20303u16),(38515u16,21636u16),(38517u16,16488u16), (38518u16,15887u16),(38519u16,22967u16),(38520u16,16468u16),(38525u16,19148u16), (38533u16,19929u16),(38534u16,16479u16),(38538u16,15748u16),(38539u16,18566u16), (38541u16,23524u16),(38542u16,14548u16),(38548u16,14361u16),(38549u16,20047u16), (38552u16,18991u16),(38553u16,15137u16),(38555u16,21208u16),(38556u16,20806u16), (38563u16,16521u16),(38567u16,18567u16),(38568u16,18568u16),(38570u16,23132u16), (38577u16,20298u16),(38583u16,16288u16),(38587u16,21965u16),(38592u16,20660u16), (38593u16,18955u16),(38596u16,20054u16),(38597u16,18931u16),(38598u16,21757u16), (38599u16,14585u16),(38601u16,22368u16),(38603u16,21445u16),(38604u16,20648u16), (38605u16,19693u16),(38606u16,20854u16),(38613u16,21256u16),(38614u16,18569u16), (38617u16,18915u16),(38619u16,22200u16),(38620u16,20673u16),(38626u16,16513u16), (38627u16,15376u16),(38632u16,19930u16),(38633u16,19931u16),(38634u16,18213u16), (38639u16,17012u16),(38640u16,17627u16),(38642u16,20048u16),(38646u16,16280u16), (38647u16,16329u16),(38649u16,17068u16),(38651u16,21014u16),(38656u16,18570u16), (38662u16,21088u16),(38663u16,21637u16),(38673u16,21032u16),(38675u16,19546u16), (38678u16,16528u16),(38681u16,19521u16),(38684u16,18015u16),(38686u16,22934u16), (38695u16,16901u16),(38704u16,17967u16),(38706u16,16303u16),(38713u16,17389u16), (38717u16,21209u16),(38722u16,16145u16),(38724u16,18992u16),(38728u16,16281u16), (38737u16,22021u16),(38742u16,21089u16),(38748u16,21186u16),(38750u16,17775u16), (38753u16,17033u16),(38754u16,16717u16),(38761u16,23137u16),(38765u16,20494u16), (38772u16,23473u16),(38775u16,20495u16),(38778u16,16668u16),(38795u16,23300u16), (38797u16,18956u16),(38799u16,14624u16),(38816u16,14966u16),(38824u16,14039u16), (38827u16,14967u16),(38829u16,22734u16),(38854u16,21984u16),(38859u16,20108u16), (38867u16,22954u16),(38876u16,15888u16),(38899u16,20304u16),(38902u16,18385u16), (38907u16,20049u16),(38911u16,23119u16),(38912u16,23340u16),(38913u16,23162u16), (38914u16,21187u16),(38915u16,14426u16),(38917u16,23088u16),(38918u16,18612u16), (38920u16,18571u16),(38922u16,19940u16),(38924u16,18410u16),(38928u16,19547u16), (38929u16,19720u16),(38930u16,17093u16),(38931u16,15908u16),(38935u16,22601u16), (38936u16,16282u16),(38957u16,15938u16),(38960u16,23175u16),(38968u16,14427u16), (38969u16,22576u16),(38971u16,17791u16),(38982u16,14733u16),(38988u16,21210u16), (38989u16,18999u16),(38990u16,18946u16),(38996u16,18957u16),(39000u16,20080u16), (39002u16,21015u16),(39006u16,16465u16),(39013u16,23341u16),(39015u16,14586u16), (39019u16,21016u16),(39023u16,23158u16),(39080u16,22901u16),(39087u16,17984u16), (39089u16,22554u16),(39108u16,22798u16),(39111u16,22797u16),(39131u16,17776u16), (39132u16,17267u16),(39135u16,18776u16),(39137u16,18401u16),(39138u16,15333u16), (39149u16,22373u16),(39150u16,20305u16),(39151u16,17094u16),(39156u16,20464u16), (39164u16,17853u16),(39165u16,22778u16),(39166u16,18777u16),(39171u16,14810u16), (39177u16,23120u16),(39178u16,19150u16),(39180u16,20465u16),(39184u16,21796u16), (39187u16,18932u16),(39192u16,19299u16),(39198u16,21017u16),(39200u16,17416u16), (39208u16,14754u16),(39237u16,16660u16),(39241u16,15152u16),(39243u16,15005u16), (39244u16,21797u16),(39245u16,18200u16),(39249u16,15334u16),(39250u16,19869u16), (39252u16,19694u16),(39255u16,23121u16),(39318u16,18572u16),(39321u16,23122u16), (39325u16,22919u16),(39333u16,17449u16),(39336u16,23291u16),(39340u16,16634u16), (39341u16,19158u16),(39342u16,22902u16),(39345u16,22403u16),(39347u16,22369u16), (39348u16,18613u16),(39353u16,20506u16),(39361u16,17069u16),(39376u16,21425u16), (39377u16,15529u16),(39378u16,14958u16),(39381u16,13994u16),(39385u16,17606u16), (39389u16,22404u16),(39391u16,17854u16),(39405u16,23105u16),(39409u16,16068u16), (39423u16,21446u16),(39425u16,17795u16),(39432u16,17417u16),(39438u16,15335u16), (39439u16,15336u16),(39449u16,22735u16),(39467u16,14241u16),(39472u16,15954u16), (39478u16,22201u16),(39479u16,18386u16),(39488u16,16698u16),(39491u16,22799u16), (39493u16,14959u16),(39501u16,23659u16),(39509u16,14811u16),(39511u16,23133u16), (39514u16,14428u16),(39515u16,19315u16),(39519u16,22339u16),(39522u16,16135u16), (39525u16,15337u16),(39529u16,23495u16),(39530u16,16136u16),(39592u16,14608u16), (39608u16,23106u16),(39635u16,18573u16),(39636u16,22032u16),(39640u16,14587u16), (39653u16,19478u16),(39662u16,17200u16),(39706u16,18574u16),(39719u16,16437u16), (39722u16,22582u16),(39729u16,20051u16),(39740u16,15106u16),(39745u16,14783u16), (39746u16,23350u16),(39747u16,17201u16),(39748u16,17257u16),(39749u16,16694u16), (39759u16,20109u16),(39764u16,16635u16),(39770u16,19159u16),(39791u16,16304u16), (39822u16,21033u16),(39825u16,22779u16),(39839u16,18958u16),(39851u16,14812u16), (39854u16,18201u16),(39881u16,16514u16),(39894u16,22022u16),(39908u16,14605u16), (39912u16,14429u16),(39949u16,22202u16),(39952u16,18947u16),(39954u16,17450u16), (39957u16,22935u16),(39973u16,23496u16),(39986u16,19672u16),(39995u16,16661u16), (40007u16,14185u16),(40009u16,17399u16),(40023u16,16522u16),(40165u16,21257u16), (40167u16,17607u16),(40169u16,14960u16),(40179u16,17468u16),(40180u16,16831u16), (40182u16,19358u16),(40201u16,18933u16),(40219u16,20081u16),(40230u16,18981u16), (40232u16,18974u16),(40251u16,23363u16),(40273u16,14372u16),(40285u16,18934u16), (40288u16,14595u16),(40289u16,16902u16),(40300u16,17638u16),(40306u16,20661u16), (40361u16,16863u16),(40367u16,19098u16),(40372u16,22940u16),(40388u16,14549u16), (40407u16,14961u16),(40434u16,22340u16),(40440u16,23706u16),(40441u16,20312u16), (40442u16,16305u16),(40474u16,19099u16),(40478u16,16077u16),(40565u16,16306u16), (40569u16,22968u16),(40573u16,19479u16),(40575u16,16312u16),(40594u16,15338u16), (40595u16,16313u16),(40599u16,16137u16),(40605u16,17855u16),(40607u16,16523u16), (40613u16,16699u16),(40628u16,14968u16),(40629u16,16718u16),(40635u16,16636u16), (40638u16,23698u16),(40643u16,23525u16),(40653u16,18153u16),(40654u16,16138u16), (40657u16,23712u16),(40660u16,14348u16),(40664u16,16904u16),(40667u16,15749u16), (40668u16,22220u16),(40670u16,21034u16),(40680u16,15733u16),(40692u16,17034u16), (40711u16,19673u16),(40712u16,17400u16),(40718u16,21188u16),(40723u16,14588u16), (40736u16,18154u16),(40763u16,17777u16),(40778u16,21211u16),(40779u16,20822u16), (40782u16,20823u16),(40786u16,22370u16),(40799u16,20855u16),(40801u16,16283u16), (40807u16,18214u16),(40810u16,21782u16),(40812u16,19160u16),(40823u16,18948u16), (40845u16,16438u16),(40848u16,17229u16),(40853u16,14059u16),(40860u16,14962u16), (44032u16,9026u16),(44033u16,9027u16),(44036u16,9028u16),(44039u16,9029u16), (44040u16,9030u16),(44041u16,9031u16),(44042u16,9032u16),(44048u16,9033u16), (44049u16,9034u16),(44050u16,9035u16),(44051u16,9036u16),(44052u16,9037u16), (44053u16,9038u16),(44054u16,9039u16),(44055u16,9040u16),(44057u16,9041u16), (44058u16,9042u16),(44059u16,9043u16),(44060u16,9044u16),(44061u16,9045u16), (44064u16,9046u16),(44068u16,9047u16),(44076u16,9048u16),(44077u16,9049u16), (44079u16,9050u16),(44080u16,9051u16),(44081u16,9052u16),(44088u16,9053u16), (44089u16,9054u16),(44092u16,9055u16),(44096u16,9056u16),(44107u16,9057u16), (44109u16,9058u16),(44116u16,9059u16),(44120u16,9060u16),(44124u16,9061u16), (44144u16,9062u16),(44145u16,9063u16),(44148u16,9064u16),(44151u16,9065u16), (44152u16,9066u16),(44154u16,9067u16),(44160u16,9068u16),(44161u16,9069u16), (44163u16,9070u16),(44164u16,9071u16),(44165u16,9072u16),(44166u16,9073u16), (44169u16,9074u16),(44170u16,9075u16),(44171u16,9076u16),(44172u16,9077u16), (44176u16,9078u16),(44180u16,9079u16),(44188u16,9080u16),(44189u16,9081u16), (44191u16,9082u16),(44192u16,9083u16),(44193u16,9084u16),(44200u16,9085u16), (44201u16,9086u16),(44202u16,9087u16),(44204u16,9088u16),(44207u16,9089u16), (44208u16,9090u16),(44216u16,9091u16),(44217u16,9092u16),(44219u16,9093u16), (44220u16,9094u16),(44221u16,9095u16),(44225u16,9096u16),(44228u16,9097u16), (44232u16,9098u16),(44236u16,9099u16),(44245u16,9100u16),(44247u16,9101u16), (44256u16,9102u16),(44257u16,9103u16),(44260u16,9104u16),(44263u16,9105u16), (44264u16,9106u16),(44266u16,9107u16),(44268u16,9108u16),(44271u16,9109u16), (44272u16,9110u16),(44273u16,9111u16),(44275u16,9112u16),(44277u16,9113u16), (44278u16,9114u16),(44284u16,9115u16),(44285u16,9116u16),(44288u16,9117u16), (44292u16,9118u16),(44294u16,9119u16),(44300u16,9216u16),(44301u16,9217u16), (44303u16,9218u16),(44305u16,9219u16),(44312u16,9220u16),(44316u16,9221u16), (44320u16,9222u16),(44329u16,9223u16),(44332u16,9224u16),(44333u16,9225u16), (44340u16,9226u16),(44341u16,9227u16),(44344u16,9228u16),(44348u16,9229u16), (44356u16,9230u16),(44357u16,9231u16),(44359u16,9232u16),(44361u16,9233u16), (44368u16,9234u16),(44372u16,9235u16),(44376u16,9236u16),(44385u16,9237u16), (44387u16,9238u16),(44396u16,9239u16),(44397u16,9240u16),(44400u16,9241u16), (44403u16,9242u16),(44404u16,9243u16),(44405u16,9244u16),(44406u16,9245u16), (44411u16,9246u16),(44412u16,9247u16),(44413u16,9248u16),(44415u16,9249u16), (44417u16,9250u16),(44418u16,9251u16),(44424u16,9252u16),(44425u16,9253u16), (44428u16,9254u16),(44432u16,9255u16),(44444u16,9256u16),(44445u16,9257u16), (44452u16,9258u16),(44471u16,9259u16),(44480u16,9260u16),(44481u16,9261u16), (44484u16,9262u16),(44488u16,9263u16),(44496u16,9264u16),(44497u16,9265u16), (44499u16,9266u16),(44508u16,9267u16),(44512u16,9268u16),(44516u16,9269u16), (44536u16,9270u16),(44537u16,9271u16),(44540u16,9272u16),(44543u16,9273u16), (44544u16,9274u16),(44545u16,9275u16),(44552u16,9276u16),(44553u16,9277u16), (44555u16,9278u16),(44557u16,9279u16),(44564u16,9280u16),(44592u16,9281u16), (44593u16,9282u16),(44596u16,9283u16),(44599u16,9284u16),(44600u16,9285u16), (44602u16,9286u16),(44608u16,9287u16),(44609u16,9288u16),(44611u16,9289u16), (44613u16,9290u16),(44614u16,9291u16),(44618u16,9292u16),(44620u16,9293u16), (44621u16,9294u16),(44622u16,9295u16),(44624u16,9296u16),(44628u16,9297u16), (44630u16,9298u16),(44636u16,9299u16),(44637u16,9300u16),(44639u16,9301u16), (44640u16,9302u16),(44641u16,9303u16),(44645u16,9304u16),(44648u16,9305u16), (44649u16,9306u16),(44652u16,9307u16),(44656u16,9308u16),(44664u16,9309u16), (44665u16,9406u16),(44667u16,9407u16),(44668u16,9408u16),(44669u16,9409u16), (44676u16,9410u16),(44677u16,9411u16),(44684u16,9412u16),(44732u16,9413u16), (44733u16,9414u16),(44734u16,9415u16),(44736u16,9416u16),(44740u16,9417u16), (44748u16,9418u16),(44749u16,9419u16),(44751u16,9420u16),(44752u16,9421u16), (44753u16,9422u16),(44760u16,9423u16),(44761u16,9424u16),(44764u16,9425u16), (44776u16,9426u16),(44779u16,9427u16),(44781u16,9428u16),(44788u16,9429u16), (44792u16,9430u16),(44796u16,9431u16),(44807u16,9432u16),(44808u16,9433u16), (44813u16,9434u16),(44816u16,9435u16),(44844u16,9436u16),(44845u16,9437u16), (44848u16,9438u16),(44850u16,9439u16),(44852u16,9440u16),(44860u16,9441u16), (44861u16,9442u16),(44863u16,9443u16),(44865u16,9444u16),(44866u16,9445u16), (44867u16,9446u16),(44872u16,9447u16),(44873u16,9448u16),(44880u16,9449u16), (44892u16,9450u16),(44893u16,9451u16),(44900u16,9452u16),(44901u16,9453u16), (44921u16,9454u16),(44928u16,9455u16),(44932u16,9456u16),(44936u16,9457u16), (44944u16,9458u16),(44945u16,9459u16),(44949u16,9460u16),(44956u16,9461u16), (44984u16,9462u16),(44985u16,9463u16),(44988u16,9464u16),(44992u16,9465u16), (44999u16,9466u16),(45000u16,9467u16),(45001u16,9468u16),(45003u16,9469u16), (45005u16,9470u16),(45006u16,9471u16),(45012u16,9472u16),(45020u16,9473u16), (45032u16,9474u16),(45033u16,9475u16),(45040u16,9476u16),(45041u16,9477u16), (45044u16,9478u16),(45048u16,9479u16),(45056u16,9480u16),(45057u16,9481u16), (45060u16,9482u16),(45068u16,9483u16),(45072u16,9484u16),(45076u16,9485u16), (45084u16,9486u16),(45085u16,9487u16),(45096u16,9488u16),(45124u16,9489u16), (45125u16,9490u16),(45128u16,9491u16),(45130u16,9492u16),(45132u16,9493u16), (45134u16,9494u16),(45139u16,9495u16),(45140u16,9496u16),(45141u16,9497u16), (45143u16,9498u16),(45145u16,9499u16),(45149u16,9596u16),(45180u16,9597u16), (45181u16,9598u16),(45184u16,9599u16),(45188u16,9600u16),(45196u16,9601u16), (45197u16,9602u16),(45199u16,9603u16),(45201u16,9604u16),(45208u16,9605u16), (45209u16,9606u16),(45210u16,9607u16),(45212u16,9608u16),(45215u16,9609u16), (45216u16,9610u16),(45217u16,9611u16),(45218u16,9612u16),(45224u16,9613u16), (45225u16,9614u16),(45227u16,9615u16),(45228u16,9616u16),(45229u16,9617u16), (45230u16,9618u16),(45231u16,9619u16),(45233u16,9620u16),(45235u16,9621u16), (45236u16,9622u16),(45237u16,9623u16),(45240u16,9624u16),(45244u16,9625u16), (45252u16,9626u16),(45253u16,9627u16),(45255u16,9628u16),(45256u16,9629u16), (45257u16,9630u16),(45264u16,9631u16),(45265u16,9632u16),(45268u16,9633u16), (45272u16,9634u16),(45280u16,9635u16),(45285u16,9636u16),(45320u16,9637u16), (45321u16,9638u16),(45323u16,9639u16),(45324u16,9640u16),(45328u16,9641u16), (45330u16,9642u16),(45331u16,9643u16),(45336u16,9644u16),(45337u16,9645u16), (45339u16,9646u16),(45340u16,9647u16),(45341u16,9648u16),(45347u16,9649u16), (45348u16,9650u16),(45349u16,9651u16),(45352u16,9652u16),(45356u16,9653u16), (45364u16,9654u16),(45365u16,9655u16),(45367u16,9656u16),(45368u16,9657u16), (45369u16,9658u16),(45376u16,9659u16),(45377u16,9660u16),(45380u16,9661u16), (45384u16,9662u16),(45392u16,9663u16),(45393u16,9664u16),(45396u16,9665u16), (45397u16,9666u16),(45400u16,9667u16),(45404u16,9668u16),(45408u16,9669u16), (45432u16,9670u16),(45433u16,9671u16),(45436u16,9672u16),(45440u16,9673u16), (45442u16,9674u16),(45448u16,9675u16),(45449u16,9676u16),(45451u16,9677u16), (45453u16,9678u16),(45458u16,9679u16),(45459u16,9680u16),(45460u16,9681u16), (45464u16,9682u16),(45468u16,9683u16),(45480u16,9684u16),(45516u16,9685u16), (45520u16,9686u16),(45524u16,9687u16),(45532u16,9688u16),(45533u16,9689u16), (45535u16,9786u16),(45544u16,9787u16),(45545u16,9788u16),(45548u16,9789u16), (45552u16,9790u16),(45561u16,9791u16),(45563u16,9792u16),(45565u16,9793u16), (45572u16,9794u16),(45573u16,9795u16),(45576u16,9796u16),(45579u16,9797u16), (45580u16,9798u16),(45588u16,9799u16),(45589u16,9800u16),(45591u16,9801u16), (45593u16,9802u16),(45600u16,9803u16),(45620u16,9804u16),(45628u16,9805u16), (45656u16,9806u16),(45660u16,9807u16),(45664u16,9808u16),(45672u16,9809u16), (45673u16,9810u16),(45684u16,9811u16),(45685u16,9812u16),(45692u16,9813u16), (45700u16,9814u16),(45701u16,9815u16),(45705u16,9816u16),(45712u16,9817u16), (45713u16,9818u16),(45716u16,9819u16),(45720u16,9820u16),(45721u16,9821u16), (45722u16,9822u16),(45728u16,9823u16),(45729u16,9824u16),(45731u16,9825u16), (45733u16,9826u16),(45734u16,9827u16),(45738u16,9828u16),(45740u16,9829u16), (45744u16,9830u16),(45748u16,9831u16),(45768u16,9832u16),(45769u16,9833u16), (45772u16,9834u16),(45776u16,9835u16),(45778u16,9836u16),(45784u16,9837u16), (45785u16,9838u16),(45787u16,9839u16),(45789u16,9840u16),(45794u16,9841u16), (45796u16,9842u16),(45797u16,9843u16),(45798u16,9844u16),(45800u16,9845u16), (45803u16,9846u16),(45804u16,9847u16),(45805u16,9848u16),(45806u16,9849u16), (45807u16,9850u16),(45811u16,9851u16),(45812u16,9852u16),(45813u16,9853u16), (45815u16,9854u16),(45816u16,9855u16),(45817u16,9856u16),(45818u16,9857u16), (45819u16,9858u16),(45823u16,9859u16),(45824u16,9860u16),(45825u16,9861u16), (45828u16,9862u16),(45832u16,9863u16),(45840u16,9864u16),(45841u16,9865u16), (45843u16,9866u16),(45844u16,9867u16),(45845u16,9868u16),(45852u16,9869u16), (45908u16,9870u16),(45909u16,9871u16),(45910u16,9872u16),(45912u16,9873u16), (45915u16,9874u16),(45916u16,9875u16),(45918u16,9876u16),(45919u16,9877u16), (45924u16,9878u16),(45925u16,9879u16),(45927u16,9976u16),(45929u16,9977u16), (45931u16,9978u16),(45934u16,9979u16),(45936u16,9980u16),(45937u16,9981u16), (45940u16,9982u16),(45944u16,9983u16),(45952u16,9984u16),(45953u16,9985u16), (45955u16,9986u16),(45956u16,9987u16),(45957u16,9988u16),(45964u16,9989u16), (45968u16,9990u16),(45972u16,9991u16),(45984u16,9992u16),(45985u16,9993u16), (45992u16,9994u16),(45996u16,9995u16),(46020u16,9996u16),(46021u16,9997u16), (46024u16,9998u16),(46027u16,9999u16),(46028u16,10000u16),(46030u16,10001u16), (46032u16,10002u16),(46036u16,10003u16),(46037u16,10004u16),(46039u16,10005u16), (46041u16,10006u16),(46043u16,10007u16),(46045u16,10008u16),(46048u16,10009u16), (46052u16,10010u16),(46056u16,10011u16),(46076u16,10012u16),(46096u16,10013u16), (46104u16,10014u16),(46108u16,10015u16),(46112u16,10016u16),(46120u16,10017u16), (46121u16,10018u16),(46123u16,10019u16),(46132u16,10020u16),(46160u16,10021u16), (46161u16,10022u16),(46164u16,10023u16),(46168u16,10024u16),(46176u16,10025u16), (46177u16,10026u16),(46179u16,10027u16),(46181u16,10028u16),(46188u16,10029u16), (46208u16,10030u16),(46216u16,10031u16),(46237u16,10032u16),(46244u16,10033u16), (46248u16,10034u16),(46252u16,10035u16),(46261u16,10036u16),(46263u16,10037u16), (46265u16,10038u16),(46272u16,10039u16),(46276u16,10040u16),(46280u16,10041u16), (46288u16,10042u16),(46293u16,10043u16),(46300u16,10044u16),(46301u16,10045u16), (46304u16,10046u16),(46307u16,10047u16),(46308u16,10048u16),(46310u16,10049u16), (46316u16,10050u16),(46317u16,10051u16),(46319u16,10052u16),(46321u16,10053u16), (46328u16,10054u16),(46356u16,10055u16),(46357u16,10056u16),(46360u16,10057u16), (46363u16,10058u16),(46364u16,10059u16),(46372u16,10060u16),(46373u16,10061u16), (46375u16,10062u16),(46376u16,10063u16),(46377u16,10064u16),(46378u16,10065u16), (46384u16,10066u16),(46385u16,10067u16),(46388u16,10068u16),(46392u16,10069u16), (46400u16,10166u16),(46401u16,10167u16),(46403u16,10168u16),(46404u16,10169u16), (46405u16,10170u16),(46411u16,10171u16),(46412u16,10172u16),(46413u16,10173u16), (46416u16,10174u16),(46420u16,10175u16),(46428u16,10176u16),(46429u16,10177u16), (46431u16,10178u16),(46432u16,10179u16),(46433u16,10180u16),(46496u16,10181u16), (46497u16,10182u16),(46500u16,10183u16),(46504u16,10184u16),(46506u16,10185u16), (46507u16,10186u16),(46512u16,10187u16),(46513u16,10188u16),(46515u16,10189u16), (46516u16,10190u16),(46517u16,10191u16),(46523u16,10192u16),(46524u16,10193u16), (46525u16,10194u16),(46528u16,10195u16),(46532u16,10196u16),(46540u16,10197u16), (46541u16,10198u16),(46543u16,10199u16),(46544u16,10200u16),(46545u16,10201u16), (46552u16,10202u16),(46572u16,10203u16),(46608u16,10204u16),(46609u16,10205u16), (46612u16,10206u16),(46616u16,10207u16),(46629u16,10208u16),(46636u16,10209u16), (46644u16,10210u16),(46664u16,10211u16),(46692u16,10212u16),(46696u16,10213u16), (46748u16,10214u16),(46749u16,10215u16),(46752u16,10216u16),(46756u16,10217u16), (46763u16,10218u16),(46764u16,10219u16),(46769u16,10220u16),(46804u16,10221u16), (46832u16,10222u16),(46836u16,10223u16),(46840u16,10224u16),(46848u16,10225u16), (46849u16,10226u16),(46853u16,10227u16),(46888u16,10228u16),(46889u16,10229u16), (46892u16,10230u16),(46895u16,10231u16),(46896u16,10232u16),(46904u16,10233u16), (46905u16,10234u16),(46907u16,10235u16),(46916u16,10236u16),(46920u16,10237u16), (46924u16,10238u16),(46932u16,10239u16),(46933u16,10240u16),(46944u16,10241u16), (46948u16,10242u16),(46952u16,10243u16),(46960u16,10244u16),(46961u16,10245u16), (46963u16,10246u16),(46965u16,10247u16),(46972u16,10248u16),(46973u16,10249u16), (46976u16,10250u16),(46980u16,10251u16),(46988u16,10252u16),(46989u16,10253u16), (46991u16,10254u16),(46992u16,10255u16),(46993u16,10256u16),(46994u16,10257u16), (46998u16,10258u16),(46999u16,10259u16),(47000u16,10356u16),(47001u16,10357u16), (47004u16,10358u16),(47008u16,10359u16),(47016u16,10360u16),(47017u16,10361u16), (47019u16,10362u16),(47020u16,10363u16),(47021u16,10364u16),(47028u16,10365u16), (47029u16,10366u16),(47032u16,10367u16),(47047u16,10368u16),(47049u16,10369u16), (47084u16,10370u16),(47085u16,10371u16),(47088u16,10372u16),(47092u16,10373u16), (47100u16,10374u16),(47101u16,10375u16),(47103u16,10376u16),(47104u16,10377u16), (47105u16,10378u16),(47111u16,10379u16),(47112u16,10380u16),(47113u16,10381u16), (47116u16,10382u16),(47120u16,10383u16),(47128u16,10384u16),(47129u16,10385u16), (47131u16,10386u16),(47133u16,10387u16),(47140u16,10388u16),(47141u16,10389u16), (47144u16,10390u16),(47148u16,10391u16),(47156u16,10392u16),(47157u16,10393u16), (47159u16,10394u16),(47160u16,10395u16),(47161u16,10396u16),(47168u16,10397u16), (47172u16,10398u16),(47185u16,10399u16),(47187u16,10400u16),(47196u16,10401u16), (47197u16,10402u16),(47200u16,10403u16),(47204u16,10404u16),(47212u16,10405u16), (47213u16,10406u16),(47215u16,10407u16),(47217u16,10408u16),(47224u16,10409u16), (47228u16,10410u16),(47245u16,10411u16),(47272u16,10412u16),(47280u16,10413u16), (47284u16,10414u16),(47288u16,10415u16),(47296u16,10416u16),(47297u16,10417u16), (47299u16,10418u16),(47301u16,10419u16),(47308u16,10420u16),(47312u16,10421u16), (47316u16,10422u16),(47325u16,10423u16),(47327u16,10424u16),(47329u16,10425u16), (47336u16,10426u16),(47337u16,10427u16),(47340u16,10428u16),(47344u16,10429u16), (47352u16,10430u16),(47353u16,10431u16),(47355u16,10432u16),(47357u16,10433u16), (47364u16,10434u16),(47384u16,10435u16),(47392u16,10436u16),(47420u16,10437u16), (47421u16,10438u16),(47424u16,10439u16),(47428u16,10440u16),(47436u16,10441u16), (47439u16,10442u16),(47441u16,10443u16),(47448u16,10444u16),(47449u16,10445u16), (47452u16,10446u16),(47456u16,10447u16),(47464u16,10448u16),(47465u16,10449u16), (47467u16,10546u16),(47469u16,10547u16),(47476u16,10548u16),(47477u16,10549u16), (47480u16,10550u16),(47484u16,10551u16),(47492u16,10552u16),(47493u16,10553u16), (47495u16,10554u16),(47497u16,10555u16),(47498u16,10556u16),(47501u16,10557u16), (47502u16,10558u16),(47532u16,10559u16),(47533u16,10560u16),(47536u16,10561u16), (47540u16,10562u16),(47548u16,10563u16),(47549u16,10564u16),(47551u16,10565u16), (47553u16,10566u16),(47560u16,10567u16),(47561u16,10568u16),(47564u16,10569u16), (47566u16,10570u16),(47567u16,10571u16),(47568u16,10572u16),(47569u16,10573u16), (47570u16,10574u16),(47576u16,10575u16),(47577u16,10576u16),(47579u16,10577u16), (47581u16,10578u16),(47582u16,10579u16),(47585u16,10580u16),(47587u16,10581u16), (47588u16,10582u16),(47589u16,10583u16),(47592u16,10584u16),(47596u16,10585u16), (47604u16,10586u16),(47605u16,10587u16),(47607u16,10588u16),(47608u16,10589u16), (47609u16,10590u16),(47610u16,10591u16),(47616u16,10592u16),(47617u16,10593u16), (47624u16,10594u16),(47637u16,10595u16),(47672u16,10596u16),(47673u16,10597u16), (47676u16,10598u16),(47680u16,10599u16),(47682u16,10600u16),(47688u16,10601u16), (47689u16,10602u16),(47691u16,10603u16),(47693u16,10604u16),(47694u16,10605u16), (47699u16,10606u16),(47700u16,10607u16),(47701u16,10608u16),(47704u16,10609u16), (47708u16,10610u16),(47716u16,10611u16),(47717u16,10612u16),(47719u16,10613u16), (47720u16,10614u16),(47721u16,10615u16),(47728u16,10616u16),(47729u16,10617u16), (47732u16,10618u16),(47736u16,10619u16),(47747u16,10620u16),(47748u16,10621u16), (47749u16,10622u16),(47751u16,10623u16),(47756u16,10624u16),(47784u16,10625u16), (47785u16,10626u16),(47787u16,10627u16),(47788u16,10628u16),(47792u16,10629u16), (47794u16,10630u16),(47800u16,10631u16),(47801u16,10632u16),(47803u16,10633u16), (47805u16,10634u16),(47812u16,10635u16),(47816u16,10636u16),(47832u16,10637u16), (47833u16,10638u16),(47868u16,10639u16),(47872u16,10736u16),(47876u16,10737u16), (47885u16,10738u16),(47887u16,10739u16),(47889u16,10740u16),(47896u16,10741u16), (47900u16,10742u16),(47904u16,10743u16),(47913u16,10744u16),(47915u16,10745u16), (47924u16,10746u16),(47925u16,10747u16),(47926u16,10748u16),(47928u16,10749u16), (47931u16,10750u16),(47932u16,10751u16),(47933u16,10752u16),(47934u16,10753u16), (47940u16,10754u16),(47941u16,10755u16),(47943u16,10756u16),(47945u16,10757u16), (47949u16,10758u16),(47951u16,10759u16),(47952u16,10760u16),(47956u16,10761u16), (47960u16,10762u16),(47969u16,10763u16),(47971u16,10764u16),(47980u16,10765u16), (48008u16,10766u16),(48012u16,10767u16),(48016u16,10768u16),(48036u16,10769u16), (48040u16,10770u16),(48044u16,10771u16),(48052u16,10772u16),(48055u16,10773u16), (48064u16,10774u16),(48068u16,10775u16),(48072u16,10776u16),(48080u16,10777u16), (48083u16,10778u16),(48120u16,10779u16),(48121u16,10780u16),(48124u16,10781u16), (48127u16,10782u16),(48128u16,10783u16),(48130u16,10784u16),(48136u16,10785u16), (48137u16,10786u16),(48139u16,10787u16),(48140u16,10788u16),(48141u16,10789u16), (48143u16,10790u16),(48145u16,10791u16),(48148u16,10792u16),(48149u16,10793u16), (48150u16,10794u16),(48151u16,10795u16),(48152u16,10796u16),(48155u16,10797u16), (48156u16,10798u16),(48157u16,10799u16),(48158u16,10800u16),(48159u16,10801u16), (48164u16,10802u16),(48165u16,10803u16),(48167u16,10804u16),(48169u16,10805u16), (48173u16,10806u16),(48176u16,10807u16),(48177u16,10808u16),(48180u16,10809u16), (48184u16,10810u16),(48192u16,10811u16),(48193u16,10812u16),(48195u16,10813u16), (48196u16,10814u16),(48197u16,10815u16),(48201u16,10816u16),(48204u16,10817u16), (48205u16,10818u16),(48208u16,10819u16),(48221u16,10820u16),(48260u16,10821u16), (48261u16,10822u16),(48264u16,10823u16),(48267u16,10824u16),(48268u16,10825u16), (48270u16,10826u16),(48276u16,10827u16),(48277u16,10828u16),(48279u16,10829u16), (48281u16,10926u16),(48282u16,10927u16),(48288u16,10928u16),(48289u16,10929u16), (48292u16,10930u16),(48295u16,10931u16),(48296u16,10932u16),(48304u16,10933u16), (48305u16,10934u16),(48307u16,10935u16),(48308u16,10936u16),(48309u16,10937u16), (48316u16,10938u16),(48317u16,10939u16),(48320u16,10940u16),(48324u16,10941u16), (48333u16,10942u16),(48335u16,10943u16),(48336u16,10944u16),(48337u16,10945u16), (48341u16,10946u16),(48344u16,10947u16),(48348u16,10948u16),(48372u16,10949u16), (48373u16,10950u16),(48374u16,10951u16),(48376u16,10952u16),(48380u16,10953u16), (48388u16,10954u16),(48389u16,10955u16),(48391u16,10956u16),(48393u16,10957u16), (48400u16,10958u16),(48404u16,10959u16),(48420u16,10960u16),(48428u16,10961u16), (48448u16,10962u16),(48456u16,10963u16),(48457u16,10964u16),(48460u16,10965u16), (48464u16,10966u16),(48472u16,10967u16),(48473u16,10968u16),(48484u16,10969u16), (48488u16,10970u16),(48512u16,10971u16),(48513u16,10972u16),(48516u16,10973u16), (48519u16,10974u16),(48520u16,10975u16),(48521u16,10976u16),(48522u16,10977u16), (48528u16,10978u16),(48529u16,10979u16),(48531u16,10980u16),(48533u16,10981u16), (48537u16,10982u16),(48538u16,10983u16),(48540u16,10984u16),(48548u16,10985u16), (48560u16,10986u16),(48568u16,10987u16),(48596u16,10988u16),(48597u16,10989u16), (48600u16,10990u16),(48604u16,10991u16),(48617u16,10992u16),(48624u16,10993u16), (48628u16,10994u16),(48632u16,10995u16),(48640u16,10996u16),(48643u16,10997u16), (48645u16,10998u16),(48652u16,10999u16),(48653u16,11000u16),(48656u16,11001u16), (48660u16,11002u16),(48668u16,11003u16),(48669u16,11004u16),(48671u16,11005u16), (48708u16,11006u16),(48709u16,11007u16),(48712u16,11008u16),(48716u16,11009u16), (48718u16,11010u16),(48724u16,11011u16),(48725u16,11012u16),(48727u16,11013u16), (48729u16,11014u16),(48730u16,11015u16),(48731u16,11016u16),(48736u16,11017u16), (48737u16,11018u16),(48740u16,11019u16),(48744u16,11116u16),(48746u16,11117u16), (48752u16,11118u16),(48753u16,11119u16),(48755u16,11120u16),(48756u16,11121u16), (48757u16,11122u16),(48763u16,11123u16),(48764u16,11124u16),(48765u16,11125u16), (48768u16,11126u16),(48772u16,11127u16),(48780u16,11128u16),(48781u16,11129u16), (48783u16,11130u16),(48784u16,11131u16),(48785u16,11132u16),(48792u16,11133u16), (48793u16,11134u16),(48808u16,11135u16),(48848u16,11136u16),(48849u16,11137u16), (48852u16,11138u16),(48855u16,11139u16),(48856u16,11140u16),(48864u16,11141u16), (48867u16,11142u16),(48868u16,11143u16),(48869u16,11144u16),(48876u16,11145u16), (48897u16,11146u16),(48904u16,11147u16),(48905u16,11148u16),(48920u16,11149u16), (48921u16,11150u16),(48923u16,11151u16),(48924u16,11152u16),(48925u16,11153u16), (48960u16,11154u16),(48961u16,11155u16),(48964u16,11156u16),(48968u16,11157u16), (48976u16,11158u16),(48977u16,11159u16),(48981u16,11160u16),(49044u16,11161u16), (49072u16,11162u16),(49093u16,11163u16),(49100u16,11164u16),(49101u16,11165u16), (49104u16,11166u16),(49108u16,11167u16),(49116u16,11168u16),(49119u16,11169u16), (49121u16,11170u16),(49212u16,11171u16),(49233u16,11172u16),(49240u16,11173u16), (49244u16,11174u16),(49248u16,11175u16),(49256u16,11176u16),(49257u16,11177u16), (49296u16,11178u16),(49297u16,11179u16),(49300u16,11180u16),(49304u16,11181u16), (49312u16,11182u16),(49313u16,11183u16),(49315u16,11184u16),(49317u16,11185u16), (49324u16,11186u16),(49325u16,11187u16),(49327u16,11188u16),(49328u16,11189u16), (49331u16,11190u16),(49332u16,11191u16),(49333u16,11192u16),(49334u16,11193u16), (49340u16,11194u16),(49341u16,11195u16),(49343u16,11196u16),(49344u16,11197u16), (49345u16,11198u16),(49349u16,11199u16),(49352u16,11200u16),(49353u16,11201u16), (49356u16,11202u16),(49360u16,11203u16),(49368u16,11204u16),(49369u16,11205u16), (49371u16,11206u16),(49372u16,11207u16),(49373u16,11208u16),(49380u16,11209u16), (49381u16,11306u16),(49384u16,11307u16),(49388u16,11308u16),(49396u16,11309u16), (49397u16,11310u16),(49399u16,11311u16),(49401u16,11312u16),(49408u16,11313u16), (49412u16,11314u16),(49416u16,11315u16),(49424u16,11316u16),(49429u16,11317u16), (49436u16,11318u16),(49437u16,11319u16),(49438u16,11320u16),(49439u16,11321u16), (49440u16,11322u16),(49443u16,11323u16),(49444u16,11324u16),(49446u16,11325u16), (49447u16,11326u16),(49452u16,11327u16),(49453u16,11328u16),(49455u16,11329u16), (49456u16,11330u16),(49457u16,11331u16),(49462u16,11332u16),(49464u16,11333u16), (49465u16,11334u16),(49468u16,11335u16),(49472u16,11336u16),(49480u16,11337u16), (49481u16,11338u16),(49483u16,11339u16),(49484u16,11340u16),(49485u16,11341u16), (49492u16,11342u16),(49493u16,11343u16),(49496u16,11344u16),(49500u16,11345u16), (49508u16,11346u16),(49509u16,11347u16),(49511u16,11348u16),(49512u16,11349u16), (49513u16,11350u16),(49520u16,11351u16),(49524u16,11352u16),(49528u16,11353u16), (49541u16,11354u16),(49548u16,11355u16),(49549u16,11356u16),(49550u16,11357u16), (49552u16,11358u16),(49556u16,11359u16),(49558u16,11360u16),(49564u16,11361u16), (49565u16,11362u16),(49567u16,11363u16),(49569u16,11364u16),(49573u16,11365u16), (49576u16,11366u16),(49577u16,11367u16),(49580u16,11368u16),(49584u16,11369u16), (49597u16,11370u16),(49604u16,11371u16),(49608u16,11372u16),(49612u16,11373u16), (49620u16,11374u16),(49623u16,11375u16),(49624u16,11376u16),(49632u16,11377u16), (49636u16,11378u16),(49640u16,11379u16),(49648u16,11380u16),(49649u16,11381u16), (49651u16,11382u16),(49660u16,11383u16),(49661u16,11384u16),(49664u16,11385u16), (49668u16,11386u16),(49676u16,11387u16),(49677u16,11388u16),(49679u16,11389u16), (49681u16,11390u16),(49688u16,11391u16),(49689u16,11392u16),(49692u16,11393u16), (49695u16,11394u16),(49696u16,11395u16),(49704u16,11396u16),(49705u16,11397u16), (49707u16,11398u16),(49709u16,11399u16),(49711u16,11496u16),(49713u16,11497u16), (49714u16,11498u16),(49716u16,11499u16),(49736u16,11500u16),(49744u16,11501u16), (49745u16,11502u16),(49748u16,11503u16),(49752u16,11504u16),(49760u16,11505u16), (49765u16,11506u16),(49772u16,11507u16),(49773u16,11508u16),(49776u16,11509u16), (49780u16,11510u16),(49788u16,11511u16),(49789u16,11512u16),(49791u16,11513u16), (49793u16,11514u16),(49800u16,11515u16),(49801u16,11516u16),(49808u16,11517u16), (49816u16,11518u16),(49819u16,11519u16),(49821u16,11520u16),(49828u16,11521u16), (49829u16,11522u16),(49832u16,11523u16),(49836u16,11524u16),(49837u16,11525u16), (49844u16,11526u16),(49845u16,11527u16),(49847u16,11528u16),(49849u16,11529u16), (49884u16,11530u16),(49885u16,11531u16),(49888u16,11532u16),(49891u16,11533u16), (49892u16,11534u16),(49899u16,11535u16),(49900u16,11536u16),(49901u16,11537u16), (49903u16,11538u16),(49905u16,11539u16),(49910u16,11540u16),(49912u16,11541u16), (49913u16,11542u16),(49915u16,11543u16),(49916u16,11544u16),(49920u16,11545u16), (49928u16,11546u16),(49929u16,11547u16),(49932u16,11548u16),(49933u16,11549u16), (49939u16,11550u16),(49940u16,11551u16),(49941u16,11552u16),(49944u16,11553u16), (49948u16,11554u16),(49956u16,11555u16),(49957u16,11556u16),(49960u16,11557u16), (49961u16,11558u16),(49989u16,11559u16),(50024u16,11560u16),(50025u16,11561u16), (50028u16,11562u16),(50032u16,11563u16),(50034u16,11564u16),(50040u16,11565u16), (50041u16,11566u16),(50044u16,11567u16),(50045u16,11568u16),(50052u16,11569u16), (50056u16,11570u16),(50060u16,11571u16),(50112u16,11572u16),(50136u16,11573u16), (50137u16,11574u16),(50140u16,11575u16),(50143u16,11576u16),(50144u16,11577u16), (50146u16,11578u16),(50152u16,11579u16),(50153u16,11580u16),(50157u16,11581u16), (50164u16,11582u16),(50165u16,11583u16),(50168u16,11584u16),(50184u16,11585u16), (50192u16,11586u16),(50212u16,11587u16),(50220u16,11588u16),(50224u16,11589u16), (50228u16,11686u16),(50236u16,11687u16),(50237u16,11688u16),(50248u16,11689u16), (50276u16,11690u16),(50277u16,11691u16),(50280u16,11692u16),(50284u16,11693u16), (50292u16,11694u16),(50293u16,11695u16),(50297u16,11696u16),(50304u16,11697u16), (50324u16,11698u16),(50332u16,11699u16),(50360u16,11700u16),(50364u16,11701u16), (50409u16,11702u16),(50416u16,11703u16),(50417u16,11704u16),(50420u16,11705u16), (50424u16,11706u16),(50426u16,11707u16),(50431u16,11708u16),(50432u16,11709u16), (50433u16,11710u16),(50444u16,11711u16),(50448u16,11712u16),(50452u16,11713u16), (50460u16,11714u16),(50472u16,11715u16),(50473u16,11716u16),(50476u16,11717u16), (50480u16,11718u16),(50488u16,11719u16),(50489u16,11720u16),(50491u16,11721u16), (50493u16,11722u16),(50500u16,11723u16),(50501u16,11724u16),(50504u16,11725u16), (50505u16,11726u16),(50506u16,11727u16),(50508u16,11728u16),(50509u16,11729u16), (50510u16,11730u16),(50515u16,11731u16),(50516u16,11732u16),(50517u16,11733u16), (50519u16,11734u16),(50520u16,11735u16),(50521u16,11736u16),(50525u16,11737u16), (50526u16,11738u16),(50528u16,11739u16),(50529u16,11740u16),(50532u16,11741u16), (50536u16,11742u16),(50544u16,11743u16),(50545u16,11744u16),(50547u16,11745u16), (50548u16,11746u16),(50549u16,11747u16),(50556u16,11748u16),(50557u16,11749u16), (50560u16,11750u16),(50564u16,11751u16),(50567u16,11752u16),(50572u16,11753u16), (50573u16,11754u16),(50575u16,11755u16),(50577u16,11756u16),(50581u16,11757u16), (50583u16,11758u16),(50584u16,11759u16),(50588u16,11760u16),(50592u16,11761u16), (50601u16,11762u16),(50612u16,11763u16),(50613u16,11764u16),(50616u16,11765u16), (50617u16,11766u16),(50619u16,11767u16),(50620u16,11768u16),(50621u16,11769u16), (50622u16,11770u16),(50628u16,11771u16),(50629u16,11772u16),(50630u16,11773u16), (50631u16,11774u16),(50632u16,11775u16),(50633u16,11776u16),(50634u16,11777u16), (50636u16,11778u16),(50638u16,11779u16),(50640u16,11876u16),(50641u16,11877u16), (50644u16,11878u16),(50648u16,11879u16),(50656u16,11880u16),(50657u16,11881u16), (50659u16,11882u16),(50661u16,11883u16),(50668u16,11884u16),(50669u16,11885u16), (50670u16,11886u16),(50672u16,11887u16),(50676u16,11888u16),(50678u16,11889u16), (50679u16,11890u16),(50684u16,11891u16),(50685u16,11892u16),(50686u16,11893u16), (50687u16,11894u16),(50688u16,11895u16),(50689u16,11896u16),(50693u16,11897u16), (50694u16,11898u16),(50695u16,11899u16),(50696u16,11900u16),(50700u16,11901u16), (50704u16,11902u16),(50712u16,11903u16),(50713u16,11904u16),(50715u16,11905u16), (50716u16,11906u16),(50724u16,11907u16),(50725u16,11908u16),(50728u16,11909u16), (50732u16,11910u16),(50733u16,11911u16),(50734u16,11912u16),(50736u16,11913u16), (50739u16,11914u16),(50740u16,11915u16),(50741u16,11916u16),(50743u16,11917u16), (50745u16,11918u16),(50747u16,11919u16),(50752u16,11920u16),(50753u16,11921u16), (50756u16,11922u16),(50760u16,11923u16),(50768u16,11924u16),(50769u16,11925u16), (50771u16,11926u16),(50772u16,11927u16),(50773u16,11928u16),(50780u16,11929u16), (50781u16,11930u16),(50784u16,11931u16),(50796u16,11932u16),(50799u16,11933u16), (50801u16,11934u16),(50808u16,11935u16),(50809u16,11936u16),(50812u16,11937u16), (50816u16,11938u16),(50824u16,11939u16),(50825u16,11940u16),(50827u16,11941u16), (50829u16,11942u16),(50836u16,11943u16),(50837u16,11944u16),(50840u16,11945u16), (50844u16,11946u16),(50852u16,11947u16),(50853u16,11948u16),(50855u16,11949u16), (50857u16,11950u16),(50864u16,11951u16),(50865u16,11952u16),(50868u16,11953u16), (50872u16,11954u16),(50873u16,11955u16),(50874u16,11956u16),(50880u16,11957u16), (50881u16,11958u16),(50883u16,11959u16),(50885u16,11960u16),(50892u16,11961u16), (50893u16,11962u16),(50896u16,11963u16),(50900u16,11964u16),(50908u16,11965u16), (50909u16,11966u16),(50912u16,11967u16),(50913u16,11968u16),(50920u16,11969u16), (50921u16,12066u16),(50924u16,12067u16),(50928u16,12068u16),(50936u16,12069u16), (50937u16,12070u16),(50941u16,12071u16),(50948u16,12072u16),(50949u16,12073u16), (50952u16,12074u16),(50956u16,12075u16),(50964u16,12076u16),(50965u16,12077u16), (50967u16,12078u16),(50969u16,12079u16),(50976u16,12080u16),(50977u16,12081u16), (50980u16,12082u16),(50984u16,12083u16),(50992u16,12084u16),(50993u16,12085u16), (50995u16,12086u16),(50997u16,12087u16),(50999u16,12088u16),(51004u16,12089u16), (51005u16,12090u16),(51008u16,12091u16),(51012u16,12092u16),(51018u16,12093u16), (51020u16,12094u16),(51021u16,12095u16),(51023u16,12096u16),(51025u16,12097u16), (51026u16,12098u16),(51027u16,12099u16),(51028u16,12100u16),(51029u16,12101u16), (51030u16,12102u16),(51031u16,12103u16),(51032u16,12104u16),(51036u16,12105u16), (51040u16,12106u16),(51048u16,12107u16),(51051u16,12108u16),(51060u16,12109u16), (51061u16,12110u16),(51064u16,12111u16),(51068u16,12112u16),(51069u16,12113u16), (51070u16,12114u16),(51075u16,12115u16),(51076u16,12116u16),(51077u16,12117u16), (51079u16,12118u16),(51080u16,12119u16),(51081u16,12120u16),(51082u16,12121u16), (51086u16,12122u16),(51088u16,12123u16),(51089u16,12124u16),(51092u16,12125u16), (51094u16,12126u16),(51095u16,12127u16),(51096u16,12128u16),(51098u16,12129u16), (51104u16,12130u16),(51105u16,12131u16),(51107u16,12132u16),(51108u16,12133u16), (51109u16,12134u16),(51110u16,12135u16),(51116u16,12136u16),(51117u16,12137u16), (51120u16,12138u16),(51124u16,12139u16),(51132u16,12140u16),(51133u16,12141u16), (51135u16,12142u16),(51136u16,12143u16),(51137u16,12144u16),(51144u16,12145u16), (51145u16,12146u16),(51148u16,12147u16),(51150u16,12148u16),(51152u16,12149u16), (51160u16,12150u16),(51165u16,12151u16),(51172u16,12152u16),(51176u16,12153u16), (51180u16,12154u16),(51200u16,12155u16),(51201u16,12156u16),(51204u16,12157u16), (51208u16,12158u16),(51210u16,12159u16),(51216u16,12256u16),(51217u16,12257u16), (51219u16,12258u16),(51221u16,12259u16),(51222u16,12260u16),(51228u16,12261u16), (51229u16,12262u16),(51232u16,12263u16),(51236u16,12264u16),(51244u16,12265u16), (51245u16,12266u16),(51247u16,12267u16),(51249u16,12268u16),(51256u16,12269u16), (51260u16,12270u16),(51264u16,12271u16),(51272u16,12272u16),(51273u16,12273u16), (51276u16,12274u16),(51277u16,12275u16),(51284u16,12276u16),(51312u16,12277u16), (51313u16,12278u16),(51316u16,12279u16),(51320u16,12280u16),(51322u16,12281u16), (51328u16,12282u16),(51329u16,12283u16),(51331u16,12284u16),(51333u16,12285u16), (51334u16,12286u16),(51335u16,12287u16),(51339u16,12288u16),(51340u16,12289u16), (51341u16,12290u16),(51348u16,12291u16),(51357u16,12292u16),(51359u16,12293u16), (51361u16,12294u16),(51368u16,12295u16),(51388u16,12296u16),(51389u16,12297u16), (51396u16,12298u16),(51400u16,12299u16),(51404u16,12300u16),(51412u16,12301u16), (51413u16,12302u16),(51415u16,12303u16),(51417u16,12304u16),(51424u16,12305u16), (51425u16,12306u16),(51428u16,12307u16),(51445u16,12308u16),(51452u16,12309u16), (51453u16,12310u16),(51456u16,12311u16),(51460u16,12312u16),(51461u16,12313u16), (51462u16,12314u16),(51468u16,12315u16),(51469u16,12316u16),(51471u16,12317u16), (51473u16,12318u16),(51480u16,12319u16),(51500u16,12320u16),(51508u16,12321u16), (51536u16,12322u16),(51537u16,12323u16),(51540u16,12324u16),(51544u16,12325u16), (51552u16,12326u16),(51553u16,12327u16),(51555u16,12328u16),(51564u16,12329u16), (51568u16,12330u16),(51572u16,12331u16),(51580u16,12332u16),(51592u16,12333u16), (51593u16,12334u16),(51596u16,12335u16),(51600u16,12336u16),(51608u16,12337u16), (51609u16,12338u16),(51611u16,12339u16),(51613u16,12340u16),(51648u16,12341u16), (51649u16,12342u16),(51652u16,12343u16),(51655u16,12344u16),(51656u16,12345u16), (51658u16,12346u16),(51664u16,12347u16),(51665u16,12348u16),(51667u16,12349u16), (51669u16,12446u16),(51670u16,12447u16),(51673u16,12448u16),(51674u16,12449u16), (51676u16,12450u16),(51677u16,12451u16),(51680u16,12452u16),(51682u16,12453u16), (51684u16,12454u16),(51687u16,12455u16),(51692u16,12456u16),(51693u16,12457u16), (51695u16,12458u16),(51696u16,12459u16),(51697u16,12460u16),(51704u16,12461u16), (51705u16,12462u16),(51708u16,12463u16),(51712u16,12464u16),(51720u16,12465u16), (51721u16,12466u16),(51723u16,12467u16),(51724u16,12468u16),(51725u16,12469u16), (51732u16,12470u16),(51736u16,12471u16),(51753u16,12472u16),(51788u16,12473u16), (51789u16,12474u16),(51792u16,12475u16),(51796u16,12476u16),(51804u16,12477u16), (51805u16,12478u16),(51807u16,12479u16),(51808u16,12480u16),(51809u16,12481u16), (51816u16,12482u16),(51837u16,12483u16),(51844u16,12484u16),(51864u16,12485u16), (51900u16,12486u16),(51901u16,12487u16),(51904u16,12488u16),(51908u16,12489u16), (51916u16,12490u16),(51917u16,12491u16),(51919u16,12492u16),(51921u16,12493u16), (51923u16,12494u16),(51928u16,12495u16),(51929u16,12496u16),(51936u16,12497u16), (51948u16,12498u16),(51956u16,12499u16),(51976u16,12500u16),(51984u16,12501u16), (51988u16,12502u16),(51992u16,12503u16),(52000u16,12504u16),(52001u16,12505u16), (52033u16,12506u16),(52040u16,12507u16),(52041u16,12508u16),(52044u16,12509u16), (52048u16,12510u16),(52056u16,12511u16),(52057u16,12512u16),(52061u16,12513u16), (52068u16,12514u16),(52088u16,12515u16),(52089u16,12516u16),(52124u16,12517u16), (52152u16,12518u16),(52180u16,12519u16),(52196u16,12520u16),(52199u16,12521u16), (52201u16,12522u16),(52236u16,12523u16),(52237u16,12524u16),(52240u16,12525u16), (52244u16,12526u16),(52252u16,12527u16),(52253u16,12528u16),(52257u16,12529u16), (52258u16,12530u16),(52263u16,12531u16),(52264u16,12532u16),(52265u16,12533u16), (52268u16,12534u16),(52270u16,12535u16),(52272u16,12536u16),(52280u16,12537u16), (52281u16,12538u16),(52283u16,12539u16),(52284u16,12636u16),(52285u16,12637u16), (52286u16,12638u16),(52292u16,12639u16),(52293u16,12640u16),(52296u16,12641u16), (52300u16,12642u16),(52308u16,12643u16),(52309u16,12644u16),(52311u16,12645u16), (52312u16,12646u16),(52313u16,12647u16),(52320u16,12648u16),(52324u16,12649u16), (52326u16,12650u16),(52328u16,12651u16),(52336u16,12652u16),(52341u16,12653u16), (52376u16,12654u16),(52377u16,12655u16),(52380u16,12656u16),(52384u16,12657u16), (52392u16,12658u16),(52393u16,12659u16),(52395u16,12660u16),(52396u16,12661u16), (52397u16,12662u16),(52404u16,12663u16),(52405u16,12664u16),(52408u16,12665u16), (52412u16,12666u16),(52420u16,12667u16),(52421u16,12668u16),(52423u16,12669u16), (52425u16,12670u16),(52432u16,12671u16),(52436u16,12672u16),(52452u16,12673u16), (52460u16,12674u16),(52464u16,12675u16),(52481u16,12676u16),(52488u16,12677u16), (52489u16,12678u16),(52492u16,12679u16),(52496u16,12680u16),(52504u16,12681u16), (52505u16,12682u16),(52507u16,12683u16),(52509u16,12684u16),(52516u16,12685u16), (52520u16,12686u16),(52524u16,12687u16),(52537u16,12688u16),(52572u16,12689u16), (52576u16,12690u16),(52580u16,12691u16),(52588u16,12692u16),(52589u16,12693u16), (52591u16,12694u16),(52593u16,12695u16),(52600u16,12696u16),(52616u16,12697u16), (52628u16,12698u16),(52629u16,12699u16),(52632u16,12700u16),(52636u16,12701u16), (52644u16,12702u16),(52645u16,12703u16),(52647u16,12704u16),(52649u16,12705u16), (52656u16,12706u16),(52676u16,12707u16),(52684u16,12708u16),(52688u16,12709u16), (52712u16,12710u16),(52716u16,12711u16),(52720u16,12712u16),(52728u16,12713u16), (52729u16,12714u16),(52731u16,12715u16),(52733u16,12716u16),(52740u16,12717u16), (52744u16,12718u16),(52748u16,12719u16),(52756u16,12720u16),(52761u16,12721u16), (52768u16,12722u16),(52769u16,12723u16),(52772u16,12724u16),(52776u16,12725u16), (52784u16,12726u16),(52785u16,12727u16),(52787u16,12728u16),(52789u16,12729u16), (52824u16,12826u16),(52825u16,12827u16),(52828u16,12828u16),(52831u16,12829u16), (52832u16,12830u16),(52833u16,12831u16),(52840u16,12832u16),(52841u16,12833u16), (52843u16,12834u16),(52845u16,12835u16),(52852u16,12836u16),(52853u16,12837u16), (52856u16,12838u16),(52860u16,12839u16),(52868u16,12840u16),(52869u16,12841u16), (52871u16,12842u16),(52873u16,12843u16),(52880u16,12844u16),(52881u16,12845u16), (52884u16,12846u16),(52888u16,12847u16),(52896u16,12848u16),(52897u16,12849u16), (52899u16,12850u16),(52900u16,12851u16),(52901u16,12852u16),(52908u16,12853u16), (52909u16,12854u16),(52929u16,12855u16),(52964u16,12856u16),(52965u16,12857u16), (52968u16,12858u16),(52971u16,12859u16),(52972u16,12860u16),(52980u16,12861u16), (52981u16,12862u16),(52983u16,12863u16),(52984u16,12864u16),(52985u16,12865u16), (52992u16,12866u16),(52993u16,12867u16),(52996u16,12868u16),(53000u16,12869u16), (53008u16,12870u16),(53009u16,12871u16),(53011u16,12872u16),(53013u16,12873u16), (53020u16,12874u16),(53024u16,12875u16),(53028u16,12876u16),(53036u16,12877u16), (53037u16,12878u16),(53039u16,12879u16),(53040u16,12880u16),(53041u16,12881u16), (53048u16,12882u16),(53076u16,12883u16),(53077u16,12884u16),(53080u16,12885u16), (53084u16,12886u16),(53092u16,12887u16),(53093u16,12888u16),(53095u16,12889u16), (53097u16,12890u16),(53104u16,12891u16),(53105u16,12892u16),(53108u16,12893u16), (53112u16,12894u16),(53120u16,12895u16),(53125u16,12896u16),(53132u16,12897u16), (53153u16,12898u16),(53160u16,12899u16),(53168u16,12900u16),(53188u16,12901u16), (53216u16,12902u16),(53217u16,12903u16),(53220u16,12904u16),(53224u16,12905u16), (53232u16,12906u16),(53233u16,12907u16),(53235u16,12908u16),(53237u16,12909u16), (53244u16,12910u16),(53248u16,12911u16),(53252u16,12912u16),(53265u16,12913u16), (53272u16,12914u16),(53293u16,12915u16),(53300u16,12916u16),(53301u16,12917u16), (53304u16,12918u16),(53308u16,12919u16),(53316u16,13016u16),(53317u16,13017u16), (53319u16,13018u16),(53321u16,13019u16),(53328u16,13020u16),(53332u16,13021u16), (53336u16,13022u16),(53344u16,13023u16),(53356u16,13024u16),(53357u16,13025u16), (53360u16,13026u16),(53364u16,13027u16),(53372u16,13028u16),(53373u16,13029u16), (53377u16,13030u16),(53412u16,13031u16),(53413u16,13032u16),(53416u16,13033u16), (53420u16,13034u16),(53428u16,13035u16),(53429u16,13036u16),(53431u16,13037u16), (53433u16,13038u16),(53440u16,13039u16),(53441u16,13040u16),(53444u16,13041u16), (53448u16,13042u16),(53449u16,13043u16),(53456u16,13044u16),(53457u16,13045u16), (53459u16,13046u16),(53460u16,13047u16),(53461u16,13048u16),(53468u16,13049u16), (53469u16,13050u16),(53472u16,13051u16),(53476u16,13052u16),(53484u16,13053u16), (53485u16,13054u16),(53487u16,13055u16),(53488u16,13056u16),(53489u16,13057u16), (53496u16,13058u16),(53517u16,13059u16),(53552u16,13060u16),(53553u16,13061u16), (53556u16,13062u16),(53560u16,13063u16),(53562u16,13064u16),(53568u16,13065u16), (53569u16,13066u16),(53571u16,13067u16),(53572u16,13068u16),(53573u16,13069u16), (53580u16,13070u16),(53581u16,13071u16),(53584u16,13072u16),(53588u16,13073u16), (53596u16,13074u16),(53597u16,13075u16),(53599u16,13076u16),(53601u16,13077u16), (53608u16,13078u16),(53612u16,13079u16),(53628u16,13080u16),(53636u16,13081u16), (53640u16,13082u16),(53664u16,13083u16),(53665u16,13084u16),(53668u16,13085u16), (53672u16,13086u16),(53680u16,13087u16),(53681u16,13088u16),(53683u16,13089u16), (53685u16,13090u16),(53690u16,13091u16),(53692u16,13092u16),(53696u16,13093u16), (53720u16,13094u16),(53748u16,13095u16),(53752u16,13096u16),(53767u16,13097u16), (53769u16,13098u16),(53776u16,13099u16),(53804u16,13100u16),(53805u16,13101u16), (53808u16,13102u16),(53812u16,13103u16),(53820u16,13104u16),(53821u16,13105u16), (53823u16,13106u16),(53825u16,13107u16),(53832u16,13108u16),(53852u16,13109u16), (53860u16,13206u16),(53888u16,13207u16),(53889u16,13208u16),(53892u16,13209u16), (53896u16,13210u16),(53904u16,13211u16),(53905u16,13212u16),(53909u16,13213u16), (53916u16,13214u16),(53920u16,13215u16),(53924u16,13216u16),(53932u16,13217u16), (53937u16,13218u16),(53944u16,13219u16),(53945u16,13220u16),(53948u16,13221u16), (53951u16,13222u16),(53952u16,13223u16),(53954u16,13224u16),(53960u16,13225u16), (53961u16,13226u16),(53963u16,13227u16),(53972u16,13228u16),(53976u16,13229u16), (53980u16,13230u16),(53988u16,13231u16),(53989u16,13232u16),(54000u16,13233u16), (54001u16,13234u16),(54004u16,13235u16),(54008u16,13236u16),(54016u16,13237u16), (54017u16,13238u16),(54019u16,13239u16),(54021u16,13240u16),(54028u16,13241u16), (54029u16,13242u16),(54030u16,13243u16),(54032u16,13244u16),(54036u16,13245u16), (54038u16,13246u16),(54044u16,13247u16),(54045u16,13248u16),(54047u16,13249u16), (54048u16,13250u16),(54049u16,13251u16),(54053u16,13252u16),(54056u16,13253u16), (54057u16,13254u16),(54060u16,13255u16),(54064u16,13256u16),(54072u16,13257u16), (54073u16,13258u16),(54075u16,13259u16),(54076u16,13260u16),(54077u16,13261u16), (54084u16,13262u16),(54085u16,13263u16),(54140u16,13264u16),(54141u16,13265u16), (54144u16,13266u16),(54148u16,13267u16),(54156u16,13268u16),(54157u16,13269u16), (54159u16,13270u16),(54160u16,13271u16),(54161u16,13272u16),(54168u16,13273u16), (54169u16,13274u16),(54172u16,13275u16),(54176u16,13276u16),(54184u16,13277u16), (54185u16,13278u16),(54187u16,13279u16),(54189u16,13280u16),(54196u16,13281u16), (54200u16,13282u16),(54204u16,13283u16),(54212u16,13284u16),(54213u16,13285u16), (54216u16,13286u16),(54217u16,13287u16),(54224u16,13288u16),(54232u16,13289u16), (54241u16,13290u16),(54243u16,13291u16),(54252u16,13292u16),(54253u16,13293u16), (54256u16,13294u16),(54260u16,13295u16),(54268u16,13296u16),(54269u16,13297u16), (54271u16,13298u16),(54273u16,13299u16),(54280u16,13396u16),(54301u16,13397u16), (54336u16,13398u16),(54340u16,13399u16),(54364u16,13400u16),(54368u16,13401u16), (54372u16,13402u16),(54381u16,13403u16),(54383u16,13404u16),(54392u16,13405u16), (54393u16,13406u16),(54396u16,13407u16),(54399u16,13408u16),(54400u16,13409u16), (54402u16,13410u16),(54408u16,13411u16),(54409u16,13412u16),(54411u16,13413u16), (54413u16,13414u16),(54420u16,13415u16),(54441u16,13416u16),(54476u16,13417u16), (54480u16,13418u16),(54484u16,13419u16),(54492u16,13420u16),(54495u16,13421u16), (54504u16,13422u16),(54508u16,13423u16),(54512u16,13424u16),(54520u16,13425u16), (54523u16,13426u16),(54525u16,13427u16),(54532u16,13428u16),(54536u16,13429u16), (54540u16,13430u16),(54548u16,13431u16),(54549u16,13432u16),(54551u16,13433u16), (54588u16,13434u16),(54589u16,13435u16),(54592u16,13436u16),(54596u16,13437u16), (54604u16,13438u16),(54605u16,13439u16),(54607u16,13440u16),(54609u16,13441u16), (54616u16,13442u16),(54617u16,13443u16),(54620u16,13444u16),(54624u16,13445u16), (54629u16,13446u16),(54632u16,13447u16),(54633u16,13448u16),(54635u16,13449u16), (54637u16,13450u16),(54644u16,13451u16),(54645u16,13452u16),(54648u16,13453u16), (54652u16,13454u16),(54660u16,13455u16),(54661u16,13456u16),(54663u16,13457u16), (54664u16,13458u16),(54665u16,13459u16),(54672u16,13460u16),(54693u16,13461u16), (54728u16,13462u16),(54729u16,13463u16),(54732u16,13464u16),(54736u16,13465u16), (54738u16,13466u16),(54744u16,13467u16),(54745u16,13468u16),(54747u16,13469u16), (54749u16,13470u16),(54756u16,13471u16),(54757u16,13472u16),(54760u16,13473u16), (54764u16,13474u16),(54772u16,13475u16),(54773u16,13476u16),(54775u16,13477u16), (54777u16,13478u16),(54784u16,13479u16),(54785u16,13480u16),(54788u16,13481u16), (54792u16,13482u16),(54800u16,13483u16),(54801u16,13484u16),(54803u16,13485u16), (54804u16,13486u16),(54805u16,13487u16),(54812u16,13488u16),(54816u16,13489u16), (54820u16,13586u16),(54829u16,13587u16),(54840u16,13588u16),(54841u16,13589u16), (54844u16,13590u16),(54848u16,13591u16),(54853u16,13592u16),(54856u16,13593u16), (54857u16,13594u16),(54859u16,13595u16),(54861u16,13596u16),(54865u16,13597u16), (54868u16,13598u16),(54869u16,13599u16),(54872u16,13600u16),(54876u16,13601u16), (54887u16,13602u16),(54889u16,13603u16),(54896u16,13604u16),(54897u16,13605u16), (54900u16,13606u16),(54915u16,13607u16),(54917u16,13608u16),(54924u16,13609u16), (54925u16,13610u16),(54928u16,13611u16),(54932u16,13612u16),(54941u16,13613u16), (54943u16,13614u16),(54945u16,13615u16),(54952u16,13616u16),(54956u16,13617u16), (54960u16,13618u16),(54969u16,13619u16),(54971u16,13620u16),(54980u16,13621u16), (54981u16,13622u16),(54984u16,13623u16),(54988u16,13624u16),(54993u16,13625u16), (54996u16,13626u16),(54999u16,13627u16),(55001u16,13628u16),(55008u16,13629u16), (55012u16,13630u16),(55016u16,13631u16),(55024u16,13632u16),(55029u16,13633u16), (55036u16,13634u16),(55037u16,13635u16),(55040u16,13636u16),(55044u16,13637u16), (55057u16,13638u16),(55064u16,13639u16),(55065u16,13640u16),(55068u16,13641u16), (55072u16,13642u16),(55080u16,13643u16),(55081u16,13644u16),(55083u16,13645u16), (55085u16,13646u16),(55092u16,13647u16),(55093u16,13648u16),(55096u16,13649u16), (55100u16,13650u16),(55108u16,13651u16),(55111u16,13652u16),(55113u16,13653u16), (55120u16,13654u16),(55121u16,13655u16),(55124u16,13656u16),(55126u16,13657u16), (55127u16,13658u16),(55128u16,13659u16),(55129u16,13660u16),(55136u16,13661u16), (55137u16,13662u16),(55139u16,13663u16),(55141u16,13664u16),(55145u16,13665u16), (55148u16,13666u16),(55152u16,13667u16),(55156u16,13668u16),(55164u16,13669u16), (55165u16,13670u16),(55169u16,13671u16),(55176u16,13672u16),(55177u16,13673u16), (55180u16,13674u16),(55184u16,13675u16),(55192u16,13676u16),(55193u16,13677u16), (55195u16,13678u16),(55197u16,13679u16),(63744u16,14203u16),(63745u16,14209u16), (63746u16,14226u16),(63747u16,14582u16),(63748u16,14607u16),(63749u16,14738u16), (63750u16,15006u16),(63751u16,15107u16),(63752u16,15129u16),(63753u16,15153u16), (63754u16,15166u16),(63755u16,15347u16),(63756u16,15348u16),(63757u16,15351u16), (63758u16,15354u16),(63759u16,15355u16),(63760u16,15356u16),(63761u16,15357u16), (63762u16,15358u16),(63763u16,15359u16),(63764u16,15361u16),(63765u16,15362u16), (63766u16,15363u16),(63767u16,15364u16),(63768u16,15365u16),(63769u16,15367u16), (63770u16,15368u16),(63771u16,15369u16),(63772u16,15370u16),(63773u16,15372u16), (63774u16,15374u16),(63775u16,15375u16),(63776u16,15377u16),(63777u16,15381u16), (63778u16,15385u16),(63779u16,15387u16),(63780u16,15388u16),(63781u16,15389u16), (63782u16,15487u16),(63783u16,15488u16),(63784u16,15492u16),(63785u16,15493u16), (63786u16,15494u16),(63787u16,15495u16),(63788u16,15496u16),(63789u16,15498u16), (63790u16,15503u16),(63791u16,15515u16),(63792u16,15519u16),(63793u16,15520u16), (63794u16,15521u16),(63795u16,15523u16),(63796u16,15524u16),(63797u16,15525u16), (63798u16,15526u16),(63799u16,15527u16),(63800u16,15528u16),(63801u16,15530u16), (63802u16,15531u16),(63803u16,15532u16),(63804u16,15533u16),(63805u16,15534u16), (63806u16,15535u16),(63807u16,15536u16),(63808u16,15537u16),(63809u16,15538u16), (63810u16,15539u16),(63811u16,15540u16),(63812u16,15542u16),(63813u16,15543u16), (63814u16,15547u16),(63815u16,15548u16),(63816u16,15550u16),(63817u16,15551u16), (63818u16,15553u16),(63819u16,15554u16),(63820u16,15555u16),(63821u16,15556u16), (63822u16,15557u16),(63823u16,15558u16),(63824u16,15559u16),(63825u16,15560u16), (63826u16,15565u16),(63827u16,15566u16),(63828u16,15567u16),(63829u16,15568u16), (63830u16,15569u16),(63831u16,15570u16),(63832u16,15572u16),(63833u16,15573u16), (63834u16,15935u16),(63835u16,15957u16),(63836u16,16060u16),(63837u16,16066u16), (63838u16,16069u16),(63839u16,16269u16),(63840u16,16290u16),(63841u16,16478u16), (63842u16,16503u16),(63843u16,17232u16),(63844u16,17263u16),(63845u16,17390u16), (63846u16,17580u16),(63847u16,17628u16),(63848u16,17659u16),(63849u16,17857u16), (63850u16,17859u16),(63851u16,17974u16),(63852u16,18020u16),(63853u16,18027u16), (63854u16,18226u16),(63855u16,18348u16),(63856u16,18412u16),(63857u16,18800u16), (63858u16,18906u16),(63859u16,18914u16),(63860u16,19109u16),(63861u16,19112u16), (63862u16,19113u16),(63863u16,19120u16),(63864u16,19122u16),(63865u16,19123u16), (63866u16,19131u16),(63867u16,19141u16),(63868u16,19143u16),(63869u16,19145u16), (63870u16,19149u16),(63871u16,19185u16),(63872u16,19186u16),(63873u16,19187u16), (63874u16,19189u16),(63875u16,19286u16),(63876u16,19289u16),(63877u16,19292u16), (63878u16,19298u16),(63879u16,19300u16),(63880u16,19301u16),(63881u16,19302u16), (63882u16,19304u16),(63883u16,19308u16),(63884u16,19309u16),(63885u16,19313u16), (63886u16,19321u16),(63887u16,19323u16),(63888u16,19324u16),(63889u16,19327u16), (63890u16,19335u16),(63891u16,19339u16),(63892u16,19342u16),(63893u16,19345u16), (63894u16,19348u16),(63895u16,19350u16),(63896u16,19353u16),(63897u16,19354u16), (63898u16,19355u16),(63899u16,19357u16),(63900u16,19359u16),(63901u16,19360u16), (63902u16,19361u16),(63903u16,19364u16),(63904u16,19366u16),(63905u16,19367u16), (63906u16,19370u16),(63907u16,19371u16),(63908u16,19372u16),(63909u16,19374u16), (63910u16,19476u16),(63911u16,19481u16),(63912u16,19484u16),(63913u16,19485u16), (63914u16,19487u16),(63915u16,19488u16),(63916u16,19491u16),(63917u16,19506u16), (63918u16,19508u16),(63919u16,19513u16),(63920u16,19514u16),(63921u16,19518u16), (63922u16,19520u16),(63923u16,19522u16),(63924u16,19523u16),(63925u16,19526u16), (63926u16,19538u16),(63927u16,19543u16),(63928u16,19545u16),(63929u16,19562u16), (63930u16,19736u16),(63931u16,19737u16),(63932u16,19745u16),(63933u16,19746u16), (63934u16,19752u16),(63935u16,19754u16),(63936u16,19756u16),(63937u16,19759u16), (63938u16,19862u16),(63939u16,19867u16),(63940u16,19899u16),(63941u16,19942u16), (63942u16,20078u16),(63943u16,20114u16),(63944u16,20129u16),(63945u16,20132u16), (63946u16,20137u16),(63947u16,20139u16),(63948u16,20239u16),(63949u16,20242u16), (63950u16,20244u16),(63951u16,20245u16),(63952u16,20261u16),(63953u16,20262u16), (63954u16,20264u16),(63955u16,20268u16),(63956u16,20269u16),(63957u16,20273u16), (63958u16,20274u16),(63959u16,20279u16),(63960u16,20282u16),(63961u16,20283u16), (63962u16,20284u16),(63963u16,20285u16),(63964u16,20291u16),(63965u16,20431u16), (63966u16,20432u16),(63967u16,20435u16),(63968u16,20440u16),(63969u16,20441u16), (63970u16,20442u16),(63971u16,20443u16),(63972u16,20446u16),(63973u16,20449u16), (63974u16,20451u16),(63975u16,20457u16),(63976u16,20458u16),(63977u16,20462u16), (63978u16,20463u16),(63979u16,20466u16),(63980u16,20467u16),(63981u16,20478u16), (63982u16,20486u16),(63983u16,20487u16),(63984u16,20490u16),(63985u16,20493u16), (63986u16,20496u16),(63987u16,20497u16),(63988u16,20512u16),(63989u16,20513u16), (63990u16,20515u16),(63991u16,20616u16),(63992u16,20617u16),(63993u16,20618u16), (63994u16,20693u16),(63995u16,20864u16),(63996u16,21594u16),(63997u16,21655u16), (63998u16,21772u16),(63999u16,21952u16),(64000u16,22023u16),(64001u16,22409u16), (64002u16,22411u16),(64003u16,22539u16),(64004u16,22555u16),(64005u16,22566u16), (64006u16,22764u16),(64007u16,22785u16),(64008u16,23086u16),(64009u16,23087u16), (64010u16,23155u16),(64011u16,23474u16),(65281u16,6556u16),(65282u16,6557u16), (65283u16,6558u16),(65284u16,6559u16),(65285u16,6560u16),(65286u16,6561u16), (65287u16,6562u16),(65288u16,6563u16),(65289u16,6564u16),(65290u16,6565u16), (65291u16,6566u16),(65292u16,6567u16),(65293u16,6568u16),(65294u16,6569u16), (65295u16,6570u16),(65296u16,6571u16),(65297u16,6572u16),(65298u16,6573u16), (65299u16,6574u16),(65300u16,6575u16),(65301u16,6576u16),(65302u16,6577u16), (65303u16,6578u16),(65304u16,6579u16),(65305u16,6580u16),(65306u16,6581u16), (65307u16,6582u16),(65308u16,6583u16),(65309u16,6584u16),(65310u16,6585u16), (65311u16,6586u16),(65312u16,6587u16),(65313u16,6588u16),(65314u16,6589u16), (65315u16,6590u16),(65316u16,6591u16),(65317u16,6592u16),(65318u16,6593u16), (65319u16,6594u16),(65320u16,6595u16),(65321u16,6596u16),(65322u16,6597u16), (65323u16,6598u16),(65324u16,6599u16),(65325u16,6600u16),(65326u16,6601u16), (65327u16,6602u16),(65328u16,6603u16),(65329u16,6604u16),(65330u16,6605u16), (65331u16,6606u16),(65332u16,6607u16),(65333u16,6608u16),(65334u16,6609u16), (65335u16,6610u16),(65336u16,6611u16),(65337u16,6612u16),(65338u16,6613u16), (65339u16,6614u16),(65340u16,6187u16),(65341u16,6616u16),(65342u16,6617u16), (65343u16,6618u16),(65344u16,6619u16),(65345u16,6620u16),(65346u16,6621u16), (65347u16,6622u16),(65348u16,6623u16),(65349u16,6624u16),(65350u16,6625u16), (65351u16,6626u16),(65352u16,6627u16),(65353u16,6628u16),(65354u16,6629u16), (65355u16,6630u16),(65356u16,6631u16),(65357u16,6632u16),(65358u16,6633u16), (65359u16,6634u16),(65360u16,6635u16),(65361u16,6636u16),(65362u16,6637u16), (65363u16,6638u16),(65364u16,6639u16),(65365u16,6640u16),(65366u16,6641u16), (65367u16,6642u16),(65368u16,6643u16),(65369u16,6644u16),(65370u16,6645u16), (65371u16,6646u16),(65372u16,6647u16),(65373u16,6648u16),(65374u16,6371u16), (65504u16,6218u16),(65505u16,6219u16),(65506u16,6269u16),(65507u16,6649u16), (65509u16,6220u16),(65510u16,6615u16), ] const GB18030Ranges*: array[206, UCS16x16] = [ (128u16,0u16),(165u16,36u16),(169u16,38u16),(178u16,45u16),(184u16,50u16), (216u16,81u16),(226u16,89u16),(235u16,95u16),(238u16,96u16),(244u16,100u16), (248u16,103u16),(251u16,104u16),(253u16,105u16),(258u16,109u16),(276u16,126u16), (284u16,133u16),(300u16,148u16),(325u16,172u16),(329u16,175u16),(334u16,179u16), (364u16,208u16),(463u16,306u16),(465u16,307u16),(467u16,308u16),(469u16,309u16), (471u16,310u16),(473u16,311u16),(475u16,312u16),(477u16,313u16),(506u16,341u16), (594u16,428u16),(610u16,443u16),(712u16,544u16),(716u16,545u16),(730u16,558u16), (930u16,741u16),(938u16,742u16),(962u16,749u16),(970u16,750u16), (1026u16,805u16),(1104u16,819u16),(1106u16,820u16),(8209u16,7922u16), (8215u16,7924u16),(8218u16,7925u16),(8222u16,7927u16),(8231u16,7934u16), (8241u16,7943u16),(8244u16,7944u16),(8246u16,7945u16),(8252u16,7950u16), (8365u16,8062u16),(8452u16,8148u16),(8454u16,8149u16),(8458u16,8152u16), (8471u16,8164u16),(8482u16,8174u16),(8556u16,8236u16),(8570u16,8240u16), (8596u16,8262u16),(8602u16,8264u16),(8713u16,8374u16),(8720u16,8380u16), (8722u16,8381u16),(8726u16,8384u16),(8731u16,8388u16),(8737u16,8390u16), (8740u16,8392u16),(8742u16,8393u16),(8748u16,8394u16),(8751u16,8396u16), (8760u16,8401u16),(8766u16,8406u16),(8777u16,8416u16),(8781u16,8419u16), (8787u16,8424u16),(8802u16,8437u16),(8808u16,8439u16),(8816u16,8445u16), (8854u16,8482u16),(8858u16,8485u16),(8870u16,8496u16),(8896u16,8521u16), (8979u16,8603u16),(9322u16,8936u16),(9372u16,8946u16),(9548u16,9046u16), (9588u16,9050u16),(9616u16,9063u16),(9622u16,9066u16),(9634u16,9076u16), (9652u16,9092u16),(9662u16,9100u16),(9672u16,9108u16),(9676u16,9111u16), (9680u16,9113u16),(9702u16,9131u16),(9735u16,9162u16),(9738u16,9164u16), (9793u16,9218u16),(9795u16,9219u16),(11906u16,11329u16),(11909u16,11331u16), (11913u16,11334u16),(11917u16,11336u16),(11928u16,11346u16),(11944u16,11361u16), (11947u16,11363u16),(11951u16,11366u16),(11956u16,11370u16),(11960u16,11372u16), (11964u16,11375u16),(11979u16,11389u16),(12284u16,11682u16),(12292u16,11686u16), (12312u16,11687u16),(12319u16,11692u16),(12330u16,11694u16),(12351u16,11714u16), (12436u16,11716u16),(12447u16,11723u16),(12535u16,11725u16),(12543u16,11730u16), (12586u16,11736u16),(12842u16,11982u16),(12850u16,11989u16),(12964u16,12102u16), (13200u16,12336u16),(13215u16,12348u16),(13218u16,12350u16),(13253u16,12384u16), (13263u16,12393u16),(13267u16,12395u16),(13270u16,12397u16),(13384u16,12510u16), (13428u16,12553u16),(13727u16,12851u16),(13839u16,12962u16),(13851u16,12973u16), (14617u16,13738u16),(14703u16,13823u16),(14801u16,13919u16),(14816u16,13933u16), (14964u16,14080u16),(15183u16,14298u16),(15471u16,14585u16),(15585u16,14698u16), (16471u16,15583u16),(16736u16,15847u16),(17208u16,16318u16),(17325u16,16434u16), (17330u16,16438u16),(17374u16,16481u16),(17623u16,16729u16),(17997u16,17102u16), (18018u16,17122u16),(18212u16,17315u16),(18218u16,17320u16),(18301u16,17402u16), (18318u16,17418u16),(18760u16,17859u16),(18811u16,17909u16),(18814u16,17911u16), (18820u16,17915u16),(18823u16,17916u16),(18844u16,17936u16),(18848u16,17939u16), (18872u16,17961u16),(19576u16,18664u16),(19620u16,18703u16),(19738u16,18814u16), (19887u16,18962u16),(40870u16,19043u16),(59244u16,33469u16),(59336u16,33470u16), (59367u16,33471u16),(59413u16,33484u16),(59417u16,33485u16),(59423u16,33490u16), (59431u16,33497u16),(59437u16,33501u16),(59443u16,33505u16),(59452u16,33513u16), (59460u16,33520u16),(59478u16,33536u16),(59493u16,33550u16),(63789u16,37845u16), (63866u16,37921u16),(63894u16,37948u16),(63976u16,38029u16),(63986u16,38038u16), (64016u16,38064u16),(64018u16,38065u16),(64021u16,38066u16),(64025u16,38069u16), (64034u16,38075u16),(64037u16,38076u16),(64042u16,38078u16),(65074u16,39108u16), (65093u16,39109u16),(65107u16,39113u16),(65112u16,39114u16),(65127u16,39115u16), (65132u16,39116u16),(65375u16,39265u16),(65510u16,39394u16), ] const Big5Decode*: array[18840, uint16] = [ uint16 17392,19506,17923,17830,17784,1,19831,17843,1,19682,1,15253,18230,18244, 19527,19520,1,1,1,1,1,19543,1,18255,17882,19589,1,19719,19108,18081,1,29221,1,1, 1,1,26189,22267,0,32149,22813,1,15860,38708,1,23515,1,23204,13861,1,23249,23479, 23804,26478,34195,1,29793,29853,14453,1,1,1,16108,1,15093,31484,40855,1,1,1,1,1, 17162,33924,40854,37935,18736,34323,22678,38730,37400,31184,31282,26208,27177, 34973,29772,31685,26498,31276,21071,36934,13542,29636,1,29894,40903,22451,18735, 21580,16689,1,22552,31346,1,35727,18094,1,16769,1,31662,1,40904,1,1,1,40905, 34052,1,16564,40906,17633,1,25281,28782,40907,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,12736,12737,12738,12739,12740,1,12741,1,1,12742, 12743,1,1,12744,1,12745,12746,12747,12748,1,12749,12750,256,193,461,192,274,201, 282,200,332,211,465,210,0,7870,0,7872,202,257,225,462,224,593,275,233,283,232, 299,237,464,236,333,243,466,242,363,250,468,249,470,472,474,476,252,0,7871,0, 7873,234,609,9178,9179,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,25866,0,0,20029,28381,40270,37343,0,0,1, 25745,20250,20264,20392,20822,20852,20892,20964,21153,21160,21307,21326,21457, 21464,22242,22768,22788,22791,22834,22836,23398,23454,23455,23706,24198,24635, 25993,26622,26628,26725,27982,28860,30005,32420,32428,32442,32455,32463,32479, 32518,32567,33402,33487,33647,35270,35774,35810,36710,36711,36718,29713,31996, 32205,26950,31433,21031,0,0,0,0,37260,30904,37214,32956,0,36107,33014,1,0,0, 32927,40647,19661,40393,40460,19518,1,1,40458,1,13761,0,28314,33342,29977,0, 18705,39532,39567,40857,31111,1,1,1,1,20004,20097,20096,20103,20159,20203,20279, 13388,20413,15944,20483,20616,13437,13459,13477,20870,22789,20955,20988,20997, 20105,21113,21136,21287,13767,21417,13649,21424,13651,21442,21539,13677,13682, 13953,21651,21667,21684,21689,21712,21743,21784,21795,21800,13720,21823,13733, 13759,21975,13765,1,21797,0,1,1,1,21904,1,14828,1,36422,1,1,16467,1,30586,1, 14900,18389,1,1,1,25821,1,1,1,1,25741,36478,1,1,1,1,1,1,0,1,1,1,18420,1,1,39602, 14951,1,16365,13574,1,1,1,1,40302,38933,0,17369,1,25780,21731,1,1,1,14843,1,1,1, 1,25834,1,1,36456,1,1,1,0,18443,1,16378,22643,1,0,1,1,1,1,1,21881,16571,17338,0, 19124,1,1,33194,39157,1,25465,14846,1,36288,22177,25724,15939,0,1,1,1,1,0,1,1, 14738,14854,1,13688,1,1,22098,1,1,1,13500,27709,1,0,0,1,1,1,1,1,1,1,1,32659,1,1, 1,13819,1,1,1,1,16275,1,1,1,1,0,1,1,1,1,1,16377,1,25650,1,1,1,1,1,1,1,1,14872,1, 1,1,1,1,1,1,1,38314,21708,33476,21945,0,1,39974,39606,1,1,28992,33133,33004, 23580,1,33076,14231,21343,1,37302,1,1,1,1,13789,1,13833,1,22191,1,1,1,1,1,1,1,1, 1,1,1,23124,1,1,1,1,22428,1,1,1,1,1,1,14083,1,1,1,1,1,1,1,1,22681,21096,13850,1, 31666,23400,18432,19244,40743,18919,39967,39821,1,1,22011,13810,22153,20008, 22786,1,1,38737,1,20059,20155,13630,23587,24401,24516,14586,25164,25909,27514, 27701,27706,28780,29227,20012,29357,1,32594,31035,31993,32595,1,13505,0,1,32770, 32896,1,1,21341,34916,35265,1,35744,36125,38021,38264,38271,38376,1,38886,39029, 39118,39134,39267,1,40060,40479,40644,27503,63751,20023,1,38429,25143,38050,0, 20539,28158,1,40870,15817,34959,1,28791,23797,19232,1,13657,1,24866,1,36775, 37366,29073,26393,29626,1,1,15499,1,19216,30948,29698,20910,1,16393,27235,1, 16931,34319,1,31274,1,1,38741,28749,21284,1,37876,30425,1,40871,30685,20131, 20464,20668,20015,20247,40872,21556,32139,22674,22736,1,24210,24217,24514,1, 25995,1,26905,27203,1,27903,0,29184,1,29580,16091,1,23317,29881,35715,1,1,31379, 31724,31939,32364,33528,34199,40873,34960,40874,36537,40875,36815,34143,39392, 37409,40876,1,1,16497,17058,23066,0,0,0,39016,26475,17014,22333,0,34262,1,33471, 1,19585,1,23931,1,1,40877,40878,23446,40879,26343,32347,28247,31178,15752,17603, 1,1,17306,17718,0,23765,1,35577,23672,15634,1,23928,40882,29015,17752,1,1,19575, 14712,13386,1,1,35532,20404,1,22975,33132,38998,1,24379,1,0,1,1,16642,18107,1, 16135,40883,1,16632,14294,18167,1,16764,1,1,17773,14548,1,17761,17691,19849, 19579,19830,17898,16328,1,13921,17630,17597,16877,23870,23880,23894,15868,14351, 23972,23993,14368,14392,24130,24253,24357,24451,14600,14612,14655,14669,24791, 24893,23781,14729,25015,25017,25039,14776,25132,25232,25317,25368,14840,22193, 14851,25570,25595,25607,25690,14923,25792,23829,22049,40863,14999,25990,15037, 26111,26195,15090,26258,15138,26390,15170,26532,26624,15192,26698,26756,15218, 15217,15227,26889,26947,29276,26980,27039,27013,15292,27094,15325,27237,27252, 27249,27266,15340,27289,15346,27307,27317,27348,27382,27521,27585,27626,27765, 27818,15563,27906,27910,27942,28033,15599,28068,28081,28181,28184,28201,28294,1, 28347,28386,28378,40831,28392,28393,28452,28468,15686,1,28545,28606,15722,15733, 29111,23705,15754,28716,15761,28752,28756,28783,28799,28809,1,17345,13809,1,1, 22462,1,28990,1,13902,27042,1,23412,31305,1,1,31333,31357,1,31419,31408,31426, 31427,29137,1,16842,31450,31453,31466,16879,21682,1,31499,31573,31529,1,1,31650, 31599,33692,1,1,31696,33825,31634,31672,1,15789,1,33938,31738,31750,31797,1, 31812,31875,1,31910,26237,1,31945,31943,31974,31860,31987,31989,31950,32359, 17693,1,32093,1,29837,32137,32171,28981,32179,32210,1,1,32228,15635,32245,1, 32229,1,32285,1,1,32366,32402,17195,37996,32295,32576,32577,32583,31030,1,39393, 32663,1,32675,1,1,17756,1,17667,1,32762,1,32773,32776,32797,32808,32815,1,1, 32827,32828,32865,1,18825,1,1,1,26405,32935,1,33031,33050,22704,1,27775,1,1, 25831,1,33304,1,27219,1,1,17530,33321,1,1,1,20473,1,34018,33634,1,1,1,1,1,33450, 26907,1,16859,34123,33488,33562,1,1,14017,1,1,33403,33506,33560,1,1,1,1,1,15807, 33565,21996,33669,17675,1,33708,33729,33747,13438,1,27223,34138,13462,1,1,33880, 1,33905,15827,17636,27303,33866,1,31064,33960,1,1,1,34014,33807,33681,17568, 33939,34020,1,16960,1,17731,34100,23282,1,17703,34163,17686,26559,34326,1,1, 34241,1,34306,1,1,1,17770,34344,13896,1,21495,1,34430,34673,1,34798,1,34737, 34778,34831,22113,34412,26710,17935,34885,34886,1,1,1,34910,34972,18011,34996, 34997,25537,35013,30583,1,35207,35210,35238,35241,35239,35260,1,35303,1,1,35484, 30611,37374,35472,1,31465,1,1,18195,1,29052,35596,35615,1,1,35647,35660,35661, 35497,1,35728,35739,35503,1,17941,34895,35995,1,1,1,14117,1,36054,1,1,36114, 36099,1,36059,28764,36113,1,16080,36215,36265,1,1,1,15228,1,1,31463,36525,36534, 36547,37588,36633,36653,1,1,36773,37635,1,1,36787,18730,1,1,1,24312,1,36857,1,1, 1,1,14720,1,36919,1,1,36961,1,1,37032,1,37060,1,37038,37117,37223,15088,37289, 37316,31916,1,1,37390,27807,37441,37474,1,37561,1,1,1,1,1,37676,37739,1,1,28815, 23235,1,1,18789,37444,1,1,1,37747,37979,36540,38277,38310,37926,38304,28662, 17081,1,1,1,1,18911,27676,38523,38550,16748,38563,1,25050,38582,30965,1,38589, 21452,18849,1,1,1,1,1,1,1,1,38705,34370,38710,18959,17725,17797,1,28789,23361, 38683,38748,1,38743,23370,1,38751,37925,20688,1,1,38793,38815,38833,38846,38848, 38866,38880,1,38894,29724,1,38911,38901,1,1,19153,38964,38963,38987,39014,15118, 1,15697,1,1,1,39114,39095,39112,39111,19199,1,1,21936,39137,39142,39148,37752, 39225,1,19314,1,1,39413,39436,39483,39440,39512,1,14020,1,1,39648,39650,1,39668, 19470,39700,39725,1,20532,39732,1,14531,1,39760,39744,1,23109,1,39822,1,39938, 39935,39948,1,40404,1,1,1,1,1,1,40318,40323,1,40462,26760,40388,1,1,1,1,1,40249, 1,1,40592,40597,40606,40610,19764,40618,40623,1,40641,15200,14821,15645,20274, 14270,1,40706,40712,19350,37924,1,40727,40726,40761,22175,22154,40773,39352,1, 38898,33919,40802,40809,31452,40846,29206,19390,1,1,29047,1,1,1,29598,1,1,31135, 1,1,37737,37875,1,37612,37761,37835,1,1,29207,16107,30578,31299,28880,1,1,29054, 1,28835,1,1,16071,1,1,1,14114,1,1,14049,1,1,1,14115,1,22363,1,1,1,1,1,34051,1, 34051,33877,1,1,1,1,1,1,17652,1,1,1,26617,14131,15381,15847,22636,1,26640,16471, 1,1,1,1,1,21707,22174,1,22162,1,1,1,37830,1,37788,20216,20779,14361,1,20156,1,1, 20299,20362,1,23144,1,1,14745,1,1,13365,20265,1,1,1,35546,1,20120,20685,20749, 20386,20227,1,1,20290,20526,20588,20609,20428,20453,20568,20732,20825,20827, 20829,20830,28278,1,1,1,28018,1,1,20904,20931,1,17629,1,1,1,36218,1,1,21081, 21156,1,21217,37742,18042,29068,1,1,1,1,27089,1,29817,16094,29849,29716,29782, 29592,19342,1,1,21456,13700,29199,1,21940,1,21709,1,22301,37469,38644,37734, 22493,22413,22399,13886,22731,23193,1,1,1,1,23084,22968,37519,23166,23247,23058, 1,1,1,1,14069,27909,29763,23073,1,23169,1,1,37856,29836,1,28933,18802,37896,1, 37821,14240,23582,23710,24158,24136,1,1,1,24269,23375,1,1,14081,1,14045,1,14035, 33066,1,1,1,1,24332,24334,1,1,23147,1,23364,34324,1,34912,24702,1,1,24539,16056, 1,1,1,1,25024,1,1,1,24985,24984,24693,1,1,1,1,25713,1,1,14889,1,1,1,1,25399,1, 25782,25393,25553,1,1,25252,1,25659,25963,26994,15348,1,1,1,1,21773,1,1,1,26318, 1,1,15072,16784,1,1,1,1,1,1,30958,1,1,1,13412,1,1,1,26254,1,26219,19347,26160,1, 1,26211,1,1,26142,1,14545,1,1,15257,1,1,29904,15254,26511,1,26806,26654,15300, 27326,14435,1,1,27187,27218,27337,27397,1,25873,26776,27212,15319,27258,27479,1, 1,37792,37618,1,1,37513,1,1,37991,28069,28427,1,28007,1,15759,28164,1,23101, 28170,22599,27940,30786,28987,1,1,28913,29264,29319,29332,1,1,20857,1,1,29818,1, 1,1,1,1,16134,16049,1,1,1,24743,16115,29900,29756,37767,29751,17567,1,17745, 30083,16227,1,1,16216,30037,30323,1,15129,29800,1,1,1,15099,15821,1,16127,1,1, 37370,22322,37698,1,1,20703,1,1,30584,1,30478,30479,30587,1,1,14942,1,29752, 29851,16063,1,1,16584,1,1,37639,1,30750,30861,30856,30930,29648,31065,1,1,16654, 31131,33942,31141,27181,1,31290,31220,16750,1,16690,37429,31217,1,1,1,1,1,13719, 21867,13680,13994,1,1,31458,23129,1,1,1,23053,1,30960,23082,1,31486,16889,31837, 31853,16913,1,1,1,31949,1,1,31886,31868,31918,27314,32220,32263,32211,32590,1,1, 1,32151,1,17002,1,1,26582,1,1,22468,1,1,1,32733,31527,1,1,1,31500,1,39398,34373, 39523,27164,1,14818,1,1,39455,1,33920,1,1,17642,33079,17410,32966,33033,33090,1, 39107,1,33378,33381,1,33875,1,34320,1,23174,16767,1,23339,1,23268,1,34464,1,1, 34861,1,23042,34926,20293,34951,35007,35046,35173,35149,1,35156,1,1,1,1,1,1, 16045,33955,18165,18127,14322,35389,35356,1,24397,37419,1,26068,28969,28868,1, 40301,35999,36073,1,22938,30659,23024,17262,14036,36394,36519,1,36656,36682, 17140,27736,28603,1,18587,28537,28299,1,39913,14005,1,37051,37015,21873,18694, 37307,37892,1,16482,1,37927,1,1,34021,35371,38297,38311,38295,38294,1,29765, 16066,1,1,1,16103,1,38543,1,1,1,16076,1,1,1,29714,29803,16124,38721,1,26695, 18973,1,1,38749,37736,1,1,1,1,37562,23313,35689,18748,29689,1,38811,38769,39224, 1,24001,1,1,38943,1,37622,1,37349,17600,1,1,1,39132,1,16128,37418,18725,33812, 39227,39245,1,15869,39323,19311,39338,39516,1,1,27279,39457,23294,39471,1,19344, 1,39356,19389,19351,37757,22642,1,22562,1,1,30788,1,1,26821,15741,37976,14631, 24912,1,1,24839,40015,40019,40059,39989,39952,39807,39887,1,39839,1,1,40225, 19630,1,40472,19632,40204,1,1,1,1,40357,33981,1,1,1,34300,17715,1,1,1,33824, 34286,1,1,1,31202,1,1,18733,1,15714,37851,37566,37704,1,30905,37495,37965,20452, 13376,36964,1,30781,30804,30902,30795,1,1,1,13978,20338,28634,28633,28702,28702, 21524,1,22459,22771,22410,40214,22487,28980,13487,1,29163,1,1,23336,1,1,24844, 23246,23051,17084,1,14124,19323,1,37819,37816,1,1,33906,1,1,1,1,1,22932,1,1, 32168,1,1,1,1,1,37605,29666,16105,29876,1,1,16097,1,27352,29683,29691,16086,1,1, 1,1,1,1,1,29768,1,28837,1,37508,29670,37727,1,37681,1,1,37766,1,1,18741,1,29035, 1,1,22180,1,1,1,21762,31172,1,32254,1,1,1,17710,37889,14090,1,1,22960,1,1,1, 23201,14050,1,14000,37471,23161,1,1,37748,15565,1,19094,14730,20724,15721,15692, 1,29045,17147,1,28175,1,17643,27991,1,28775,27823,15574,1,1,28162,28428,15727,1, 30033,14012,13512,18048,16090,18545,22980,37486,18750,36673,1,1,22546,22472, 14038,1,28926,1,1,1,1,1,26809,26983,1,1,1,1,1,1,1,1,27162,1,1,33854,17631,17614, 1,1,1,1,28439,1,33597,1,33773,1,1,1,22921,23170,1,23137,23153,1,1,14125,23023,1, 14023,29070,37776,26266,1,23150,23083,1,27179,1,1,1,1,28957,1,1,20400,1,23746,1, 1,1,27148,1,1,28838,28979,1,15781,27871,1,1,32357,23019,23855,15859,24412,1,1, 32164,33830,21637,1,1,1,22398,1,1,16357,1,1,28675,1,23920,29583,31955,1,1,20424, 32743,29389,29456,1,29496,29497,1,29505,29512,16041,1,36972,29173,1,29665,33270, 16074,30476,16081,27810,22269,29721,29726,29727,16098,16112,16116,16122,29907, 16142,16211,30018,30061,30066,30093,16252,30152,30172,16320,30285,16343,30324, 16348,30330,1,29064,22051,35200,22633,16413,30531,16441,26465,16453,13787,30616, 16490,16495,23646,30654,30667,22770,30744,28857,30748,16552,30777,30791,30801, 30822,33864,1,31027,26627,31026,16643,16649,31121,31129,36795,31238,36796,16743, 31377,16818,31420,33401,16836,31439,31451,16847,20001,31586,31596,31611,31762, 31771,16992,17018,31867,31900,17036,31928,17044,31981,36755,28864,1,32207,32212, 32208,32253,32686,32692,29343,17303,32800,32805,31545,32814,32817,32852,15820, 22452,28832,32951,33001,17389,33036,29482,33038,33042,30048,33044,17409,15161, 33110,33113,33114,17427,22586,33148,33156,17445,33171,17453,33189,22511,33217, 33252,33364,17551,33446,33398,33482,33496,33535,17584,33623,38505,27018,33797, 28917,33892,24803,33928,17668,33982,34017,34040,34064,34104,34130,17723,34159, 34160,34272,17783,34418,34450,34482,34543,38469,34699,17926,17943,34990,35071, 35108,35143,35217,1,35369,35384,35476,35508,35921,36052,36082,36124,18328,22623, 36291,18413,20206,36410,21976,22356,36465,22005,36528,18487,36558,36578,36580, 36589,36594,36791,36801,36810,36812,36915,39364,18605,39136,37395,18718,37416, 37464,37483,37553,37550,37567,37603,37611,37619,37620,37629,37699,37764,37805, 18757,18769,40639,37911,21249,37917,37933,37950,18794,37972,38009,38189,38306, 18855,38388,38451,18917,26528,18980,38720,18997,38834,38850,22100,19172,24808, 39097,19225,39153,22596,39182,39193,20916,39196,39223,39234,39261,39266,19312, 39365,19357,39484,39695,31363,39785,39809,39901,39921,39924,19565,39968,14191,1, 40265,39994,40702,22096,40339,40381,40384,40444,38134,36790,40571,40620,40625, 40637,40646,38108,40674,40689,40696,31432,40772,1,1,1,26906,38083,22956,1,22592, 38081,14265,1,1,1,1,22359,29043,1,1,1,21610,1,1,21662,1,1,1,1,1,24807,1,22138,1, 1,1,1,1,1,26965,39983,34725,1,1,1,1,1,1,23584,1,24075,1,1,1,26398,1,1,1,13895,1, 1,1,1,21348,33965,1,1,1,35713,1,1,1,1,20088,28859,1,1,1,1,1,1,1,1,25283,1,1, 29080,26709,1,27113,14024,1,1,1,1,1,1,33533,1,1,1,35237,1,36768,1,38840,1,38983, 39613,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,24497,26184,26303,1,1,1,29185,1,30679,1,1, 32391,1,22709,26382,26904,1,1,1,1,1,1,1,18640,19128,1,1,1,1,1,1,1,1,1,20946,1, 22943,1,15294,1,1,1,22408,1,14747,1,1,1,14178,1,35678,1,39382,1,1,1,29193,1,1, 22885,1,1,1,36570,1,21135,22335,29041,1,1,1,1,21948,1,1,1,37332,13427,1,1,1, 18200,1,1,1,1,1,20582,13563,1,24798,1,18300,1,1,1,1,1,22433,29009,28598,1,1, 36950,1,1,35682,1,1,23899,1,36662,1,1,35562,1,1,1,1,19392,1,1,1,37989,1,24981, 23079,1,20411,22201,1,1,20074,1,38486,28047,1,13848,35191,1,1,1,1,29151,1,31554, 1,1,1,37124,1,31301,40432,1,39462,1,13919,1,1,31107,1,1,23852,1,33743,1,18128,1, 30011,34917,1,22710,14108,1,1,1,15444,1,1,37505,1,1,37680,1,1,27705,38047,1,1, 34855,35061,1,1,1,28344,1,1,14756,14009,23568,31203,17727,26294,1,1,35139,1,1, 22230,16607,1,14753,1,1,1,29101,33638,1,1,23143,19639,1,1,1,1,1,1,1,31555,31102, 1,28597,1,27139,1,21410,1,37823,26678,38749,1,1,1,1,1,1,23941,1,1,22293,38947,1, 23979,1,26046,27093,21458,1,1,15377,26422,1,1,1,1,1,1,1,1,1,1,1,13770,1,1,18682, 25574,1,30728,37461,1,17394,1,17375,1,1,1,23032,1,36619,1,1,31569,1,1,15863,1,1, 36816,29327,22155,1,1,1,1,1,1,1,1,1,1,1,1,1,32415,1,1,19620,38215,1,29090,1, 19857,36882,1,19868,1,36798,21953,36794,1,36793,1,17673,32383,28502,27313,20202, 13540,1,1,14138,36480,1,1,1,1,1,1,15851,1,1,1,1,20122,1,1,22207,1,36366,23405,1, 1,25566,25296,1,1,25904,22061,1,21530,1,15814,1,19581,22050,22046,32585,1,22901, 1,34672,19996,1,1,1,33047,40286,36120,30267,40005,30286,30649,37701,21554,33096, 33527,22053,33074,33816,32957,21994,31074,22083,21526,1,13774,22021,22001,26353, 1,13869,30004,22000,21946,21655,21874,1,1,24272,1,1,1,1,40619,32090,21982,1, 25245,38765,21652,36045,29174,37238,25596,25529,25598,21865,1,40050,1,20890, 13535,1,20903,21581,21790,21779,30310,36397,1,30129,32950,34820,34694,35015, 33206,33820,1,17644,29444,1,23440,33547,1,22139,1,1,1,1,1,1,37232,1,37384,1,1,1, 1,29286,1,18254,1,1,1,16634,40029,25887,1,18675,1,1,1,1,24674,1,1,0,1,1,29091, 32398,40272,19994,19972,13687,23309,27826,21351,13996,14812,21373,13989,1,22682, 1,33325,21579,22442,1,1,0,14930,1,29556,1,19721,39917,1,1,19547,1,1,1,33884,1,1, 1,1,25390,32037,1,1,14890,36872,21196,15988,13946,17897,1,30272,23280,1,30842,1, 22695,16575,22140,39819,23924,30292,1,40581,19681,30201,14331,24857,1,1,0,22109, 1,22439,1,1,21044,1,13741,27722,40316,31830,39737,22494,1,23635,25811,1,1,1, 34477,1,1,1,1,0,20990,1,23950,38659,1,40577,36940,31519,39682,23761,31651,25192, 25397,39679,31695,39722,31870,39726,31810,31878,39957,31740,39689,40727,39963,1, 40794,21875,23491,20477,40600,20466,21088,15878,21201,22375,20566,22967,24082, 38856,40363,36700,21609,38836,39232,38842,21292,24880,26924,21466,39946,40194, 19515,38465,27008,20646,30022,1,39386,21107,0,37209,38529,37212,0,37201,1,25471, 1,27338,22033,37262,30074,25221,1,29519,31856,1,1,0,1,30422,39837,20010,1,33726, 34882,0,23626,27072,20717,22394,21023,24053,20174,27697,1,20281,21660,21722, 21146,36226,13822,24332,13811,0,27474,37244,40869,39831,38958,39092,39610,40616, 40580,29050,31508,0,27642,34840,32632,0,22048,1,36471,40787,0,36308,36431,40476, 36353,25218,1,36392,36469,31443,1,31294,30936,27882,35431,30215,1,40742,27854, 34774,30147,1,30803,1,36108,29410,29553,35629,29442,29937,36075,1,34351,24506, 34976,17591,0,1,1,0,35454,1,0,24829,30311,39639,40260,37742,39823,34805,0,34831, 36087,29484,38689,39856,13782,29362,19463,31825,39242,1,24921,19460,40598,24957, 0,22367,24943,25254,25145,25294,14940,25058,21418,1,25444,26626,13778,23895,1, 36826,1,0,20697,1,30982,21298,38456,1,16485,0,30718,0,31938,1,31962,31277,32870, 32867,32077,29957,29938,35220,33306,26380,32866,1,32859,29936,33027,30500,35209, 1,30035,1,34729,34766,33224,34700,35401,36013,35651,30507,29944,34010,13877, 27058,36262,0,35241,29800,28089,34753,1,29927,15835,29046,24740,24988,15569, 29026,24695,0,32625,1,29264,24809,19326,21024,15384,1,1,1,1,1,1,1,1,1,23745,1,1, 1,1,1,1,17762,23327,1,40784,40614,1,12288,65292,12289,12290,65294,8231,65307, 65306,65311,65281,65072,8230,8229,65104,65105,65106,183,65108,65109,65110,65111, 65372,8211,65073,8212,65075,9588,65076,65103,65288,65289,65077,65078,65371, 65373,65079,65080,12308,12309,65081,65082,12304,12305,65083,65084,12298,12299, 65085,65086,12296,12297,65087,65088,12300,12301,65089,65090,12302,12303,65091, 65092,65113,65114,65115,65116,65117,65118,8216,8217,8220,8221,12317,12318,8245, 8242,65283,65286,65290,8251,167,12291,9675,9679,9651,9650,9678,9734,9733,9671, 9670,9633,9632,9661,9660,12963,8453,175,65507,65343,717,65097,65098,65101,65102, 65099,65100,65119,65120,65121,65291,65293,215,247,177,8730,65308,65310,65309, 8806,8807,8800,8734,8786,8801,65122,65123,65124,65125,65126,65374,8745,8746, 8869,8736,8735,8895,13266,13265,8747,8750,8757,8756,9792,9794,8853,8857,8593, 8595,8592,8594,8598,8599,8601,8600,8741,8739,65295,65340,8725,65128,65284,65509, 12306,65504,65505,65285,65312,8451,8457,65129,65130,65131,13269,13212,13213, 13214,13262,13217,13198,13199,13252,176,20825,20827,20830,20829,20833,20835, 21991,29929,31950,9601,9602,9603,9604,9605,9606,9607,9608,9615,9614,9613,9612, 9611,9610,9609,9532,9524,9516,9508,9500,9620,9472,9474,9621,9484,9488,9492,9496, 9581,9582,9584,9583,9552,9566,9578,9569,9698,9699,9701,9700,9585,9586,9587, 65296,65297,65298,65299,65300,65301,65302,65303,65304,65305,8544,8545,8546,8547, 8548,8549,8550,8551,8552,8553,12321,12322,12323,12324,12325,12326,12327,12328, 12329,21313,21316,21317,65313,65314,65315,65316,65317,65318,65319,65320,65321, 65322,65323,65324,65325,65326,65327,65328,65329,65330,65331,65332,65333,65334, 65335,65336,65337,65338,65345,65346,65347,65348,65349,65350,65351,65352,65353, 65354,65355,65356,65357,65358,65359,65360,65361,65362,65363,65364,65365,65366, 65367,65368,65369,65370,913,914,915,916,917,918,919,920,921,922,923,924,925,926, 927,928,929,931,932,933,934,935,936,937,945,946,947,948,949,950,951,952,953,954, 955,956,957,958,959,960,961,963,964,965,966,967,968,969,12549,12550,12551,12552, 12553,12554,12555,12556,12557,12558,12559,12560,12561,12562,12563,12564,12565, 12566,12567,12568,12569,12570,12571,12572,12573,12574,12575,12576,12577,12578, 12579,12580,12581,12582,12583,12584,12585,729,713,714,711,715,9216,9217,9218, 9219,9220,9221,9222,9223,9224,9225,9226,9227,9228,9229,9230,9231,9232,9233,9234, 9235,9236,9237,9238,9239,9240,9241,9242,9243,9244,9245,9246,9247,9249,8364,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19968,20057,19969,19971, 20035,20061,20102,20108,20154,20799,20837,20843,20960,20992,20993,21147,21269, 21313,21340,21448,19977,19979,19976,19978,20011,20024,20961,20037,20040,20063, 20062,20110,20129,20800,20995,21242,21315,21449,21475,22303,22763,22805,22823, 22899,23376,23377,23379,23544,23567,23586,23608,23665,24029,24037,24049,24050, 24051,24062,24178,24318,24331,24339,25165,19985,19984,19981,20013,20016,20025, 20043,23609,20104,20113,20117,20114,20116,20130,20161,20160,20163,20166,20167, 20173,20170,20171,20164,20803,20801,20839,20845,20846,20844,20887,20982,20998, 20999,21000,21243,21246,21247,21270,21305,21320,21319,21317,21342,21380,21451, 21450,21453,22764,22825,22827,22826,22829,23380,23569,23588,23610,23663,24052, 24187,24319,24340,24341,24515,25096,25142,25163,25166,25903,25991,26007,26020, 26041,26085,26352,26376,26408,27424,27490,27513,27595,27604,27611,27663,27700, 28779,29226,29238,29243,29255,29273,29275,29356,29579,19993,19990,19989,19988, 19992,20027,20045,20047,20046,20197,20184,20180,20181,20182,20183,20195,20196, 20185,20190,20805,20804,20873,20874,20908,20985,20986,20984,21002,21152,21151, 21253,21254,21271,21277,20191,21322,21321,21345,21344,21359,21358,21435,21487, 21476,21491,21484,21486,21481,21480,21500,21496,21493,21483,21478,21482,21490, 21489,21488,21477,21485,21499,22235,22234,22806,22830,22833,22900,22902,23381, 23427,23612,24040,24039,24038,24066,24067,24179,24188,24321,24344,24343,24517, 25098,25171,25172,25170,25169,26021,26086,26414,26412,26410,26411,26413,27491, 27597,27665,27664,27704,27713,27712,27710,29359,29572,29577,29916,29926,29976, 29983,29992,29993,30000,30001,30002,30003,30091,30333,30382,30399,30446,30683, 30690,30707,31034,31166,31348,31435,19998,19999,20050,20051,20073,20121,20132, 20134,20133,20223,20233,20249,20234,20245,20237,20240,20241,20239,20210,20214, 20219,20208,20211,20221,20225,20235,20809,20807,20806,20808,20840,20849,20877, 20912,21015,21009,21010,21006,21014,21155,21256,21281,21280,21360,21361,21513, 21519,21516,21514,21520,21505,21515,21508,21521,21517,21512,21507,21518,21510, 21522,22240,22238,22237,22323,22320,22312,22317,22316,22319,22313,22809,22810, 22839,22840,22916,22904,22915,22909,22905,22914,22913,23383,23384,23431,23432, 23429,23433,23546,23574,23673,24030,24070,24182,24180,24335,24347,24537,24534, 25102,25100,25101,25104,25187,25179,25176,25910,26089,26088,26092,26093,26354, 26355,26377,26429,26420,26417,26421,27425,27492,27515,27670,27741,27735,27737, 27743,27744,27728,27733,27745,27739,27725,27726,28784,29279,29277,30334,31481, 31859,31992,32566,32650,32701,32769,32771,32780,32786,32819,32895,32905,32907, 32908,33251,33258,33267,33276,33292,33307,33311,33390,33394,33406,34411,34880, 34892,34915,35199,38433,20018,20136,20301,20303,20295,20311,20318,20276,20315, 20309,20272,20304,20305,20285,20282,20280,20291,20308,20284,20294,20323,20316, 20320,20271,20302,20278,20313,20317,20296,20314,20812,20811,20813,20853,20918, 20919,21029,21028,21033,21034,21032,21163,21161,21162,21164,21283,21363,21365, 21533,21549,21534,21566,21542,21582,21543,21574,21571,21555,21576,21570,21531, 21545,21578,21561,21563,21560,21550,21557,21558,21536,21564,21568,21553,21547, 21535,21548,22250,22256,22244,22251,22346,22353,22336,22349,22343,22350,22334, 22352,22351,22331,22767,22846,22941,22930,22952,22942,22947,22937,22934,22925, 22948,22931,22922,22949,23389,23388,23386,23387,23436,23435,23439,23596,23616, 23617,23615,23614,23696,23697,23700,23692,24043,24076,24207,24199,24202,24311, 24324,24351,24420,24418,24439,24441,24536,24524,24535,24525,24561,24555,24568, 24554,25106,25105,25220,25239,25238,25216,25206,25225,25197,25226,25212,25214, 25209,25203,25234,25199,25240,25198,25237,25235,25233,25222,25913,25915,25912, 26097,26356,26463,26446,26447,26448,26449,26460,26454,26462,26441,26438,26464, 26451,26455,27493,27599,27714,27742,27801,27777,27784,27785,27781,27803,27754, 27770,27792,27760,27788,27752,27798,27794,27773,27779,27762,27774,27764,27782, 27766,27789,27796,27800,27778,28790,28796,28797,28792,29282,29281,29280,29380, 29378,29590,29996,29995,30007,30008,30338,30447,30691,31169,31168,31167,31350, 31995,32597,32918,32915,32925,32920,32923,32922,32946,33391,33426,33419,33421, 35211,35282,35328,35895,35910,35925,35997,36196,36208,36275,36523,36554,36763, 36784,36802,36806,36805,36804,24033,37009,37026,37034,37030,37027,37193,37318, 37324,38450,38446,38449,38442,38444,20006,20054,20083,20107,20123,20126,20139, 20140,20335,20381,20365,20339,20351,20332,20379,20363,20358,20355,20336,20341, 20360,20329,20347,20374,20350,20367,20369,20346,20820,20818,20821,20841,20855, 20854,20856,20925,20989,21051,21048,21047,21050,21040,21038,21046,21057,21182, 21179,21330,21332,21331,21329,21350,21367,21368,21369,21462,21460,21463,21619, 21621,21654,21624,21653,21632,21627,21623,21636,21650,21638,21628,21648,21617, 21622,21644,21658,21602,21608,21643,21629,21646,22266,22403,22391,22378,22377, 22369,22374,22372,22396,22812,22857,22855,22856,22852,22868,22974,22971,22996, 22969,22958,22993,22982,22992,22989,22987,22995,22986,22959,22963,22994,22981, 23391,23396,23395,23447,23450,23448,23452,23449,23451,23578,23624,23621,23622, 23735,23713,23736,23721,23723,23729,23731,24088,24090,24086,24085,24091,24081, 24184,24218,24215,24220,24213,24214,24310,24358,24359,24361,24448,24449,24447, 24444,24541,24544,24573,24565,24575,24591,24596,24623,24629,24598,24618,24597, 24609,24615,24617,24619,24603,25110,25109,25151,25150,25152,25215,25289,25292, 25284,25279,25282,25273,25298,25307,25259,25299,25300,25291,25288,25256,25277, 25276,25296,25305,25287,25293,25269,25306,25265,25304,25302,25303,25286,25260, 25294,25918,26023,26044,26106,26132,26131,26124,26118,26114,26126,26112,26127, 26133,26122,26119,26381,26379,26477,26507,26517,26481,26524,26483,26487,26503, 26525,26519,26479,26480,26495,26505,26494,26512,26485,26522,26515,26492,26474, 26482,27427,27494,27495,27519,27667,27675,27875,27880,27891,27825,27852,27877, 27827,27837,27838,27836,27874,27819,27861,27859,27832,27844,27833,27841,27822, 27863,27845,27889,27839,27835,27873,27867,27850,27820,27887,27868,27862,27872, 28821,28814,28818,28810,28825,29228,29229,29240,29256,29287,29289,29376,29390, 29401,29399,29392,29609,29608,29599,29611,29605,30013,30109,30105,30106,30340, 30402,30450,30452,30693,30717,31038,31040,31041,31177,31176,31354,31353,31482, 31998,32596,32652,32651,32773,32954,32933,32930,32945,32929,32939,32937,32948, 32938,32943,33253,33278,33293,33459,33437,33433,33453,33469,33439,33465,33457, 33452,33445,33455,33464,33443,33456,33470,33463,34382,34417,21021,34920,36555, 36814,36820,36817,37045,37048,37041,37046,37319,37329,38263,38272,38428,38464, 38463,38459,38468,38466,38585,38632,38738,38750,20127,20141,20142,20449,20405, 20399,20415,20448,20433,20431,20445,20419,20406,20440,20447,20426,20439,20398, 20432,20420,20418,20442,20430,20446,20407,20823,20882,20881,20896,21070,21059, 21066,21069,21068,21067,21063,21191,21193,21187,21185,21261,21335,21371,21402, 21467,21676,21696,21672,21710,21705,21688,21670,21683,21703,21698,21693,21674, 21697,21700,21704,21679,21675,21681,21691,21673,21671,21695,22271,22402,22411, 22432,22435,22434,22478,22446,22419,22869,22865,22863,22862,22864,23004,23000, 23039,23011,23016,23043,23013,23018,23002,23014,23041,23035,23401,23459,23462, 23460,23458,23461,23553,23630,23631,23629,23627,23769,23762,24055,24093,24101, 24095,24189,24224,24230,24314,24328,24365,24421,24456,24453,24458,24459,24455, 24460,24457,24594,24605,24608,24613,24590,24616,24653,24688,24680,24674,24646, 24643,24684,24683,24682,24676,25153,25308,25366,25353,25340,25325,25345,25326, 25341,25351,25329,25335,25327,25324,25342,25332,25361,25346,25919,25925,26027, 26045,26082,26149,26157,26144,26151,26159,26143,26152,26161,26148,26359,26623, 26579,26609,26580,26576,26604,26550,26543,26613,26601,26607,26564,26577,26548, 26586,26597,26552,26575,26590,26611,26544,26585,26594,26589,26578,27498,27523, 27526,27573,27602,27607,27679,27849,27915,27954,27946,27969,27941,27916,27953, 27934,27927,27963,27965,27966,27958,27931,27893,27961,27943,27960,27945,27950, 27957,27918,27947,28843,28858,28851,28844,28847,28845,28856,28846,28836,29232, 29298,29295,29300,29417,29408,29409,29623,29642,29627,29618,29645,29632,29619, 29978,29997,30031,30028,30030,30027,30123,30116,30117,30114,30115,30328,30342, 30343,30344,30408,30406,30403,30405,30465,30457,30456,30473,30475,30462,30460, 30471,30684,30722,30740,30732,30733,31046,31049,31048,31047,31161,31162,31185, 31186,31179,31359,31361,31487,31485,31869,32002,32005,32000,32009,32007,32004, 32006,32568,32654,32703,32772,32784,32781,32785,32822,32982,32997,32986,32963, 32964,32972,32993,32987,32974,32990,32996,32989,33268,33314,33511,33539,33541, 33507,33499,33510,33540,33509,33538,33545,33490,33495,33521,33537,33500,33492, 33489,33502,33491,33503,33519,33542,34384,34425,34427,34426,34893,34923,35201, 35284,35336,35330,35331,35998,36000,36212,36211,36276,36557,36556,36848,36838, 36834,36842,36837,36845,36843,36836,36840,37066,37070,37057,37059,37195,37194, 37325,38274,38480,38475,38476,38477,38754,38761,38859,38893,38899,38913,39080, 39131,39135,39318,39321,20056,20147,20492,20493,20515,20463,20518,20517,20472, 20521,20502,20486,20540,20511,20506,20498,20497,20474,20480,20500,20520,20465, 20513,20491,20505,20504,20467,20462,20525,20522,20478,20523,20489,20860,20900, 20901,20898,20941,20940,20934,20939,21078,21084,21076,21083,21085,21290,21375, 21407,21405,21471,21736,21776,21761,21815,21756,21733,21746,21766,21754,21780, 21737,21741,21729,21769,21742,21738,21734,21799,21767,21757,21775,22275,22276, 22466,22484,22475,22467,22537,22799,22871,22872,22874,23057,23064,23068,23071, 23067,23059,23020,23072,23075,23081,23077,23052,23049,23403,23640,23472,23475, 23478,23476,23470,23477,23481,23480,23556,23633,23637,23632,23789,23805,23803, 23786,23784,23792,23798,23809,23796,24046,24109,24107,24235,24237,24231,24369, 24466,24465,24464,24665,24675,24677,24656,24661,24685,24681,24687,24708,24735, 24730,24717,24724,24716,24709,24726,25159,25331,25352,25343,25422,25406,25391, 25429,25410,25414,25423,25417,25402,25424,25405,25386,25387,25384,25421,25420, 25928,25929,26009,26049,26053,26178,26185,26191,26179,26194,26188,26181,26177, 26360,26388,26389,26391,26657,26680,26696,26694,26707,26681,26690,26708,26665, 26803,26647,26700,26705,26685,26612,26704,26688,26684,26691,26666,26693,26643, 26648,26689,27530,27529,27575,27683,27687,27688,27686,27684,27888,28010,28053, 28040,28039,28006,28024,28023,27993,28051,28012,28041,28014,27994,28020,28009, 28044,28042,28025,28037,28005,28052,28874,28888,28900,28889,28872,28879,29241, 29305,29436,29433,29437,29432,29431,29574,29677,29705,29678,29664,29674,29662, 30036,30045,30044,30042,30041,30142,30149,30151,30130,30131,30141,30140,30137, 30146,30136,30347,30384,30410,30413,30414,30505,30495,30496,30504,30697,30768, 30759,30776,30749,30772,30775,30757,30765,30752,30751,30770,31061,31056,31072, 31071,31062,31070,31069,31063,31066,31204,31203,31207,31199,31206,31209,31192, 31364,31368,31449,31494,31505,31881,32033,32023,32011,32010,32032,32034,32020, 32016,32021,32026,32028,32013,32025,32027,32570,32607,32660,32709,32705,32774, 32792,32789,32793,32791,32829,32831,33009,33026,33008,33029,33005,33012,33030, 33016,33011,33032,33021,33034,33020,33007,33261,33260,33280,33296,33322,33323, 33320,33324,33467,33579,33618,33620,33610,33592,33616,33609,33589,33588,33615, 33586,33593,33590,33559,33600,33585,33576,33603,34388,34442,34474,34451,34468, 34473,34444,34467,34460,34928,34935,34945,34946,34941,34937,35352,35344,35342, 35340,35349,35338,35351,35347,35350,35343,35345,35912,35962,35961,36001,36002, 36215,36524,36562,36564,36559,36785,36865,36870,36855,36864,36858,36852,36867, 36861,36869,36856,37013,37089,37085,37090,37202,37197,37196,37336,37341,37335, 37340,37337,38275,38498,38499,38497,38491,38493,38500,38488,38494,38587,39138, 39340,39592,39640,39717,39730,39740,20094,20602,20605,20572,20551,20547,20556, 20570,20553,20581,20598,20558,20565,20597,20596,20599,20559,20495,20591,20589, 20828,20885,20976,21098,21103,21202,21209,21208,21205,21264,21263,21273,21311, 21312,21310,21443,26364,21830,21866,21862,21828,21854,21857,21827,21834,21809, 21846,21839,21845,21807,21860,21816,21806,21852,21804,21859,21811,21825,21847, 22280,22283,22281,22495,22533,22538,22534,22496,22500,22522,22530,22581,22519, 22521,22816,22882,23094,23105,23113,23142,23146,23104,23100,23138,23130,23110, 23114,23408,23495,23493,23492,23490,23487,23494,23561,23560,23559,23648,23644, 23645,23815,23814,23822,23835,23830,23842,23825,23849,23828,23833,23844,23847, 23831,24034,24120,24118,24115,24119,24247,24248,24246,24245,24254,24373,24375, 24407,24428,24425,24427,24471,24473,24478,24472,24481,24480,24476,24703,24739, 24713,24736,24744,24779,24756,24806,24765,24773,24763,24757,24796,24764,24792, 24789,24774,24799,24760,24794,24775,25114,25115,25160,25504,25511,25458,25494, 25506,25509,25463,25447,25496,25514,25457,25513,25481,25475,25499,25451,25512, 25476,25480,25497,25505,25516,25490,25487,25472,25467,25449,25448,25466,25949, 25942,25937,25945,25943,21855,25935,25944,25941,25940,26012,26011,26028,26063, 26059,26060,26062,26205,26202,26212,26216,26214,26206,26361,21207,26395,26753, 26799,26786,26771,26805,26751,26742,26801,26791,26775,26800,26755,26820,26797, 26758,26757,26772,26781,26792,26783,26785,26754,27442,27578,27627,27628,27691, 28046,28092,28147,28121,28082,28129,28108,28132,28155,28154,28165,28103,28107, 28079,28113,28078,28126,28153,28088,28151,28149,28101,28114,28186,28085,28122, 28139,28120,28138,28145,28142,28136,28102,28100,28074,28140,28095,28134,28921, 28937,28938,28925,28911,29245,29309,29313,29468,29467,29462,29459,29465,29575, 29701,29706,29699,29702,29694,29709,29920,29942,29943,29980,29986,30053,30054, 30050,30064,30095,30164,30165,30133,30154,30157,30350,30420,30418,30427,30519, 30526,30524,30518,30520,30522,30827,30787,30798,31077,31080,31085,31227,31378, 31381,31520,31528,31515,31532,31526,31513,31518,31534,31890,31895,31893,32070, 32067,32113,32046,32057,32060,32064,32048,32051,32068,32047,32066,32050,32049, 32573,32670,32666,32716,32718,32722,32796,32842,32838,33071,33046,33059,33067, 33065,33072,33060,33282,33333,33335,33334,33337,33678,33694,33688,33656,33698, 33686,33725,33707,33682,33674,33683,33673,33696,33655,33659,33660,33670,33703, 34389,24426,34503,34496,34486,34500,34485,34502,34507,34481,34479,34505,34899, 34974,34952,34987,34962,34966,34957,34955,35219,35215,35370,35357,35363,35365, 35377,35373,35359,35355,35362,35913,35930,36009,36012,36011,36008,36010,36007, 36199,36198,36286,36282,36571,36575,36889,36877,36890,36887,36899,36895,36893, 36880,36885,36894,36896,36879,36898,36886,36891,36884,37096,37101,37117,37207, 37326,37365,37350,37347,37351,37357,37353,38281,38506,38517,38515,38520,38512, 38516,38518,38519,38508,38592,38634,38633,31456,31455,38914,38915,39770,40165, 40565,40575,40613,40635,20642,20621,20613,20633,20625,20608,20630,20632,20634, 26368,20977,21106,21108,21109,21097,21214,21213,21211,21338,21413,21883,21888, 21927,21884,21898,21917,21912,21890,21916,21930,21908,21895,21899,21891,21939, 21934,21919,21822,21938,21914,21947,21932,21937,21886,21897,21931,21913,22285, 22575,22570,22580,22564,22576,22577,22561,22557,22560,22777,22778,22880,23159, 23194,23167,23186,23195,23207,23411,23409,23506,23500,23507,23504,23562,23563, 23601,23884,23888,23860,23879,24061,24133,24125,24128,24131,24190,24266,24257, 24258,24260,24380,24429,24489,24490,24488,24785,24801,24754,24758,24800,24860, 24867,24826,24853,24816,24827,24820,24936,24817,24846,24822,24841,24832,24850, 25119,25161,25507,25484,25551,25536,25577,25545,25542,25549,25554,25571,25552, 25569,25558,25581,25582,25462,25588,25578,25563,25682,25562,25593,25950,25958, 25954,25955,26001,26000,26031,26222,26224,26228,26230,26223,26257,26234,26238, 26231,26366,26367,26399,26397,26874,26837,26848,26840,26839,26885,26847,26869, 26862,26855,26873,26834,26866,26851,26827,26829,26893,26898,26894,26825,26842, 26990,26875,27454,27450,27453,27544,27542,27580,27631,27694,27695,27692,28207, 28216,28244,28193,28210,28263,28234,28192,28197,28195,28187,28251,28248,28196, 28246,28270,28205,28198,28271,28212,28237,28218,28204,28227,28189,28222,28363, 28297,28185,28238,28259,28228,28274,28265,28255,28953,28954,28966,28976,28961, 28982,29038,28956,29260,29316,29312,29494,29477,29492,29481,29754,29738,29747, 29730,29733,29749,29750,29748,29743,29723,29734,29736,29989,29990,30059,30058, 30178,30171,30179,30169,30168,30174,30176,30331,30332,30358,30355,30388,30428, 30543,30701,30813,30828,30831,31245,31240,31243,31237,31232,31384,31383,31382, 31461,31459,31561,31574,31558,31568,31570,31572,31565,31563,31567,31569,31903, 31909,32094,32080,32104,32085,32043,32110,32114,32097,32102,32098,32112,32115, 21892,32724,32725,32779,32850,32901,33109,33108,33099,33105,33102,33081,33094, 33086,33100,33107,33140,33298,33308,33769,33795,33784,33805,33760,33733,33803, 33729,33775,33777,33780,33879,33802,33776,33804,33740,33789,33778,33738,33848, 33806,33796,33756,33799,33748,33759,34395,34527,34521,34541,34516,34523,34532, 34512,34526,34903,35009,35010,34993,35203,35222,35387,35424,35413,35422,35388, 35393,35412,35419,35408,35398,35380,35386,35382,35414,35937,35970,36015,36028, 36019,36029,36033,36027,36032,36020,36023,36022,36031,36024,36234,36229,36225, 36302,36317,36299,36314,36305,36300,36315,36294,36603,36600,36604,36764,36910, 36917,36913,36920,36914,36918,37122,37109,37129,37118,37219,37221,37327,37396, 37397,37411,37385,37406,37389,37392,37383,37393,38292,38287,38283,38289,38291, 38290,38286,38538,38542,38539,38525,38533,38534,38541,38514,38532,38593,38597, 38596,38598,38599,38639,38642,38860,38917,38918,38920,39143,39146,39151,39145, 39154,39149,39342,39341,40643,40653,40657,20098,20653,20661,20658,20659,20677, 20670,20652,20663,20667,20655,20679,21119,21111,21117,21215,21222,21220,21218, 21219,21295,21983,21992,21971,21990,21966,21980,21959,21969,21987,21988,21999, 21978,21985,21957,21958,21989,21961,22290,22291,22622,22609,22616,22615,22618, 22612,22635,22604,22637,22602,22626,22610,22603,22887,23233,23241,23244,23230, 23229,23228,23219,23234,23218,23913,23919,24140,24185,24265,24264,24338,24409, 24492,24494,24858,24847,24904,24863,24819,24859,24825,24833,24840,24910,24908, 24900,24909,24894,24884,24871,24845,24838,24887,25121,25122,25619,25662,25630, 25642,25645,25661,25644,25615,25628,25620,25613,25654,25622,25623,25606,25964, 26015,26032,26263,26249,26247,26248,26262,26244,26264,26253,26371,27028,26989, 26970,26999,26976,26964,26997,26928,27010,26954,26984,26987,26974,26963,27001, 27014,26973,26979,26971,27463,27506,27584,27583,27603,27645,28322,28335,28371, 28342,28354,28304,28317,28359,28357,28325,28312,28348,28346,28331,28369,28310, 28316,28356,28372,28330,28327,28340,29006,29017,29033,29028,29001,29031,29020, 29036,29030,29004,29029,29022,28998,29032,29014,29242,29266,29495,29509,29503, 29502,29807,29786,29781,29791,29790,29761,29759,29785,29787,29788,30070,30072, 30208,30192,30209,30194,30193,30202,30207,30196,30195,30430,30431,30555,30571, 30566,30558,30563,30585,30570,30572,30556,30565,30568,30562,30702,30862,30896, 30871,30872,30860,30857,30844,30865,30867,30847,31098,31103,31105,33836,31165, 31260,31258,31264,31252,31263,31262,31391,31392,31607,31680,31584,31598,31591, 31921,31923,31925,32147,32121,32145,32129,32143,32091,32622,32617,32618,32626, 32681,32680,32676,32854,32856,32902,32900,33137,33136,33144,33125,33134,33139, 33131,33145,33146,33126,33285,33351,33922,33911,33853,33841,33909,33894,33899, 33865,33900,33883,33852,33845,33889,33891,33897,33901,33862,34398,34396,34399, 34553,34579,34568,34567,34560,34558,34555,34562,34563,34566,34570,34905,35039, 35028,35033,35036,35032,35037,35041,35018,35029,35026,35228,35299,35435,35442, 35443,35430,35433,35440,35463,35452,35427,35488,35441,35461,35437,35426,35438, 35436,35449,35451,35390,35432,35938,35978,35977,36042,36039,36040,36036,36018, 36035,36034,36037,36321,36319,36328,36335,36339,36346,36330,36324,36326,36530, 36611,36617,36606,36618,36767,36786,36939,36938,36947,36930,36948,36924,36949, 36944,36935,36943,36942,36941,36945,36926,36929,37138,37143,37228,37226,37225, 37321,37431,37463,37432,37437,37440,37438,37467,37451,37476,37457,37428,37449, 37453,37445,37433,37439,37466,38296,38552,38548,38549,38605,38603,38601,38602, 38647,38651,38649,38646,38742,38772,38774,38928,38929,38931,38922,38930,38924, 39164,39156,39165,39166,39347,39345,39348,39649,40169,40578,40718,40723,40736, 20711,20718,20709,20694,20717,20698,20693,20687,20689,20721,20686,20713,20834, 20979,21123,21122,21297,21421,22014,22016,22043,22039,22013,22036,22022,22025, 22029,22030,22007,22038,22047,22024,22032,22006,22296,22294,22645,22654,22659, 22675,22666,22649,22661,22653,22781,22821,22818,22820,22890,22889,23265,23270, 23273,23255,23254,23256,23267,23413,23518,23527,23521,23525,23526,23528,23522, 23524,23519,23565,23650,23940,23943,24155,24163,24149,24151,24148,24275,24278, 24330,24390,24432,24505,24903,24895,24907,24951,24930,24931,24927,24922,24920, 24949,25130,25735,25688,25684,25764,25720,25695,25722,25681,25703,25652,25709, 25723,25970,26017,26071,26070,26274,26280,26269,27036,27048,27029,27073,27054, 27091,27083,27035,27063,27067,27051,27060,27088,27085,27053,27084,27046,27075, 27043,27465,27468,27699,28467,28436,28414,28435,28404,28457,28478,28448,28460, 28431,28418,28450,28415,28399,28422,28465,28472,28466,28451,28437,28459,28463, 28552,28458,28396,28417,28402,28364,28407,29076,29081,29053,29066,29060,29074, 29246,29330,29334,29508,29520,29796,29795,29802,29808,29805,29956,30097,30247, 30221,30219,30217,30227,30433,30435,30596,30589,30591,30561,30913,30879,30887, 30899,30889,30883,31118,31119,31117,31278,31281,31402,31401,31469,31471,31649, 31637,31627,31605,31639,31645,31636,31631,31672,31623,31620,31929,31933,31934, 32187,32176,32156,32189,32190,32160,32202,32180,32178,32177,32186,32162,32191, 32181,32184,32173,32210,32199,32172,32624,32736,32737,32735,32862,32858,32903, 33104,33152,33167,33160,33162,33151,33154,33255,33274,33287,33300,33310,33355, 33993,33983,33990,33988,33945,33950,33970,33948,33995,33976,33984,34003,33936, 33980,34001,33994,34623,34588,34619,34594,34597,34612,34584,34645,34615,34601, 35059,35074,35060,35065,35064,35069,35048,35098,35055,35494,35468,35486,35491, 35469,35489,35475,35492,35498,35493,35496,35480,35473,35482,35495,35946,35981, 35980,36051,36049,36050,36203,36249,36245,36348,36628,36626,36629,36627,36771, 36960,36952,36956,36963,36953,36958,36962,36957,36955,37145,37144,37150,37237, 37240,37239,37236,37496,37504,37509,37528,37526,37499,37523,37532,37544,37500, 37521,38305,38312,38313,38307,38309,38308,38553,38556,38555,38604,38610,38656, 38780,38789,38902,38935,38936,39087,39089,39171,39173,39180,39177,39361,39599, 39600,39654,39745,39746,40180,40182,40179,40636,40763,40778,20740,20736,20731, 20725,20729,20738,20744,20745,20741,20956,21127,21128,21129,21133,21130,21232, 21426,22062,22075,22073,22066,22079,22068,22057,22099,22094,22103,22132,22070, 22063,22064,22656,22687,22686,22707,22684,22702,22697,22694,22893,23305,23291, 23307,23285,23308,23304,23534,23532,23529,23531,23652,23653,23965,23956,24162, 24159,24161,24290,24282,24287,24285,24291,24288,24392,24433,24503,24501,24950, 24935,24942,24925,24917,24962,24956,24944,24939,24958,24999,24976,25003,24974, 25004,24986,24996,24980,25006,25134,25705,25711,25721,25758,25778,25736,25744, 25776,25765,25747,25749,25769,25746,25774,25773,25771,25754,25772,25753,25762, 25779,25973,25975,25976,26286,26283,26292,26289,27171,27167,27112,27137,27166, 27161,27133,27169,27155,27146,27123,27138,27141,27117,27153,27472,27470,27556, 27589,27590,28479,28540,28548,28497,28518,28500,28550,28525,28507,28536,28526, 28558,28538,28528,28516,28567,28504,28373,28527,28512,28511,29087,29100,29105, 29096,29270,29339,29518,29527,29801,29835,29827,29822,29824,30079,30240,30249, 30239,30244,30246,30241,30242,30362,30394,30436,30606,30599,30604,30609,30603, 30923,30917,30906,30922,30910,30933,30908,30928,31295,31292,31296,31293,31287, 31291,31407,31406,31661,31665,31684,31668,31686,31687,31681,31648,31692,31946, 32224,32244,32239,32251,32216,32236,32221,32232,32227,32218,32222,32233,32158, 32217,32242,32249,32629,32631,32687,32745,32806,33179,33180,33181,33184,33178, 33176,34071,34109,34074,34030,34092,34093,34067,34065,34083,34081,34068,34028, 34085,34047,34054,34690,34676,34678,34656,34662,34680,34664,34649,34647,34636, 34643,34907,34909,35088,35079,35090,35091,35093,35082,35516,35538,35527,35524, 35477,35531,35576,35506,35529,35522,35519,35504,35542,35533,35510,35513,35547, 35916,35918,35948,36064,36062,36070,36068,36076,36077,36066,36067,36060,36074, 36065,36205,36255,36259,36395,36368,36381,36386,36367,36393,36383,36385,36382, 36538,36637,36635,36639,36649,36646,36650,36636,36638,36645,36969,36974,36968, 36973,36983,37168,37165,37159,37169,37255,37257,37259,37251,37573,37563,37559, 37610,37548,37604,37569,37555,37564,37586,37575,37616,37554,38317,38321,38660, 38662,38663,38665,38752,38797,38795,38799,38945,38955,38940,39091,39178,39187, 39186,39192,39389,39376,39391,39387,39377,39381,39378,39385,39607,39662,39663, 39719,39749,39748,39799,39791,40198,40201,40195,40617,40638,40654,22696,40786, 20754,20760,20756,20752,20757,20864,20906,20957,21137,21139,21235,22105,22123, 22137,22121,22116,22136,22122,22120,22117,22129,22127,22124,22114,22134,22721, 22718,22727,22725,22894,23325,23348,23416,23536,23566,24394,25010,24977,25001, 24970,25037,25014,25022,25034,25032,25136,25797,25793,25803,25787,25788,25818, 25796,25799,25794,25805,25791,25810,25812,25790,25972,26310,26313,26297,26308, 26311,26296,27197,27192,27194,27225,27243,27224,27193,27204,27234,27233,27211, 27207,27189,27231,27208,27481,27511,27653,28610,28593,28577,28611,28580,28609, 28583,28595,28608,28601,28598,28582,28576,28596,29118,29129,29136,29138,29128, 29141,29113,29134,29145,29148,29123,29124,29544,29852,29859,29848,29855,29854, 29922,29964,29965,30260,30264,30266,30439,30437,30624,30622,30623,30629,30952, 30938,30956,30951,31142,31309,31310,31302,31308,31307,31418,31705,31761,31689, 31716,31707,31713,31721,31718,31957,31958,32266,32273,32264,32283,32291,32286, 32285,32265,32272,32633,32690,32752,32753,32750,32808,33203,33193,33192,33275, 33288,33368,33369,34122,34137,34120,34152,34153,34115,34121,34157,34154,34142, 34691,34719,34718,34722,34701,34913,35114,35122,35109,35115,35105,35242,35238, 35558,35578,35563,35569,35584,35548,35559,35566,35582,35585,35586,35575,35565, 35571,35574,35580,35947,35949,35987,36084,36420,36401,36404,36418,36409,36405, 36667,36655,36664,36659,36776,36774,36981,36980,36984,36978,36988,36986,37172, 37266,37664,37686,37624,37683,37679,37666,37628,37675,37636,37658,37648,37670, 37665,37653,37678,37657,38331,38567,38568,38570,38613,38670,38673,38678,38669, 38675,38671,38747,38748,38758,38808,38960,38968,38971,38967,38957,38969,38948, 39184,39208,39198,39195,39201,39194,39405,39394,39409,39608,39612,39675,39661, 39720,39825,40213,40227,40230,40232,40210,40219,40664,40660,40845,40860,20778, 20767,20769,20786,21237,22158,22144,22160,22149,22151,22159,22741,22739,22737, 22734,23344,23338,23332,23418,23607,23656,23996,23994,23997,23992,24171,24396, 24509,25033,25026,25031,25062,25035,25138,25140,25806,25802,25816,25824,25840, 25830,25836,25841,25826,25837,25986,25987,26329,26326,27264,27284,27268,27298, 27292,27355,27299,27262,27287,27280,27296,27484,27566,27610,27656,28632,28657, 28639,28640,28635,28644,28651,28655,28544,28652,28641,28649,28629,28654,28656, 29159,29151,29166,29158,29157,29165,29164,29172,29152,29237,29254,29552,29554, 29865,29872,29862,29864,30278,30274,30284,30442,30643,30634,30640,30636,30631, 30637,30703,30967,30970,30964,30959,30977,31143,31146,31319,31423,31751,31757, 31742,31735,31756,31712,31968,31964,31966,31970,31967,31961,31965,32302,32318, 32326,32311,32306,32323,32299,32317,32305,32325,32321,32308,32313,32328,32309, 32319,32303,32580,32755,32764,32881,32882,32880,32879,32883,33222,33219,33210, 33218,33216,33215,33213,33225,33214,33256,33289,33393,34218,34180,34174,34204, 34193,34196,34223,34203,34183,34216,34186,34407,34752,34769,34739,34770,34758, 34731,34747,34746,34760,34763,35131,35126,35140,35128,35133,35244,35598,35607, 35609,35611,35594,35616,35613,35588,35600,35905,35903,35955,36090,36093,36092, 36088,36091,36264,36425,36427,36424,36426,36676,36670,36674,36677,36671,36991, 36989,36996,36993,36994,36992,37177,37283,37278,37276,37709,37762,37672,37749, 37706,37733,37707,37656,37758,37740,37723,37744,37722,37716,38346,38347,38348, 38344,38342,38577,38584,38614,38684,38686,38816,38867,38982,39094,39221,39425, 39423,39854,39851,39850,39853,40251,40255,40587,40655,40670,40668,40669,40667, 40766,40779,21474,22165,22190,22745,22744,23352,24413,25059,25139,25844,25842, 25854,25862,25850,25851,25847,26039,26332,26406,27315,27308,27331,27323,27320, 27330,27310,27311,27487,27512,27567,28681,28683,28670,28678,28666,28689,28687, 29179,29180,29182,29176,29559,29557,29863,29887,29973,30294,30296,30290,30653, 30655,30651,30652,30990,31150,31329,31330,31328,31428,31429,31787,31783,31786, 31774,31779,31777,31975,32340,32341,32350,32346,32353,32338,32345,32584,32761, 32763,32887,32886,33229,33231,33290,34255,34217,34253,34256,34249,34224,34234, 34233,34214,34799,34796,34802,34784,35206,35250,35316,35624,35641,35628,35627, 35920,36101,36441,36451,36454,36452,36447,36437,36544,36681,36685,36999,36995, 37000,37291,37292,37328,37780,37770,37782,37794,37811,37806,37804,37808,37784, 37786,37783,38356,38358,38352,38357,38626,38620,38617,38619,38622,38692,38819, 38822,38829,38905,38989,38991,38988,38990,38995,39098,39230,39231,39229,39214, 39333,39438,39617,39683,39686,39759,39758,39757,39882,39881,39933,39880,39872, 40273,40285,40288,40672,40725,40748,20787,22181,22750,22751,22754,23541,40848, 24300,25074,25079,25078,25077,25856,25871,26336,26333,27365,27357,27354,27347, 28699,28703,28712,28698,28701,28693,28696,29190,29197,29272,29346,29560,29562, 29885,29898,29923,30087,30086,30303,30305,30663,31001,31153,31339,31337,31806, 31807,31800,31805,31799,31808,32363,32365,32377,32361,32362,32645,32371,32694, 32697,32696,33240,34281,34269,34282,34261,34276,34277,34295,34811,34821,34829, 34809,34814,35168,35167,35158,35166,35649,35676,35672,35657,35674,35662,35663, 35654,35673,36104,36106,36476,36466,36487,36470,36460,36474,36468,36692,36686, 36781,37002,37003,37297,37294,37857,37841,37855,37827,37832,37852,37853,37846, 37858,37837,37848,37860,37847,37864,38364,38580,38627,38698,38695,38753,38876, 38907,39006,39000,39003,39100,39237,39241,39446,39449,39693,39912,39911,39894, 39899,40329,40289,40306,40298,40300,40594,40599,40595,40628,21240,22184,22199, 22198,22196,22204,22756,23360,23363,23421,23542,24009,25080,25082,25880,25876, 25881,26342,26407,27372,28734,28720,28722,29200,29563,29903,30306,30309,31014, 31018,31020,31019,31431,31478,31820,31811,31821,31983,31984,36782,32381,32380, 32386,32588,32768,33242,33382,34299,34297,34321,34298,34310,34315,34311,34314, 34836,34837,35172,35258,35320,35696,35692,35686,35695,35679,35691,36111,36109, 36489,36481,36485,36482,37300,37323,37912,37891,37885,38369,38704,39108,39250, 39249,39336,39467,39472,39479,39477,39955,39949,40569,40629,40680,40751,40799, 40803,40801,20791,20792,22209,22208,22210,22804,23660,24013,25084,25086,25885, 25884,26005,26345,27387,27396,27386,27570,28748,29211,29351,29910,29908,30313, 30675,31824,32399,32396,32700,34327,34349,34330,34851,34850,34849,34847,35178, 35180,35261,35700,35703,35709,36115,36490,36493,36491,36703,36783,37306,37934, 37939,37941,37946,37944,37938,37931,38370,38712,38713,38706,38911,39015,39013, 39255,39493,39491,39488,39486,39631,39764,39761,39981,39973,40367,40372,40386, 40376,40605,40687,40729,40796,40806,40807,20796,20795,22216,22218,22217,23423, 24020,24018,24398,25087,25892,27402,27489,28753,28760,29568,29924,30090,30318, 30316,31155,31840,31839,32894,32893,33247,35186,35183,35324,35712,36118,36119, 36497,36499,36705,37192,37956,37969,37970,38717,38718,38851,38849,39019,39253, 39509,39501,39634,39706,40009,39985,39998,39995,40403,40407,40756,40812,40810, 40852,22220,24022,25088,25891,25899,25898,26348,27408,29914,31434,31844,31843, 31845,32403,32406,32404,33250,34360,34367,34865,35722,37008,37007,37987,37984, 37988,38760,39023,39260,39514,39515,39511,39635,39636,39633,40020,40023,40022, 40421,40607,40692,22225,22761,25900,28766,30321,30322,30679,32592,32648,34870, 34873,34914,35731,35730,35734,33399,36123,37312,37994,38722,38728,38724,38854, 39024,39519,39714,39768,40031,40441,40442,40572,40573,40711,40823,40818,24307, 27414,28771,31852,31854,34875,35264,36513,37313,38002,38000,39025,39262,39638, 39715,40652,28772,30682,35738,38007,38857,39522,39525,32412,35740,36522,37317, 38013,38014,38012,40055,40056,40695,35924,38015,40474,29224,39530,39729,40475, 40478,31858,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321,9332,9333,9334, 9335,9336,9337,9338,9339,9340,9341,8560,8561,8562,8563,8564,8565,8566,8567,8568, 8569,20022,20031,20101,20128,20866,20886,20907,21241,21304,21353,21430,22794, 23424,24027,12083,24191,24308,24400,24417,25908,26080,30098,30326,36789,38582, 168,710,12541,12542,12445,12446,12291,20189,12293,12294,12295,12540,65339,65341, 10045,12353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364, 12365,12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377, 12378,12379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390, 12391,12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403, 12404,12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416, 12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429, 12430,12431,12432,12433,12434,12435,12449,12450,12451,12452,12453,12454,12455, 12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468, 12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481, 12482,12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494, 12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507, 12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520, 12521,12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533, 12534,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052, 1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068, 1069,1070,1071,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083, 1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099, 1100,1101,1102,1103,8679,8632,8633,12751,1,20058,1,20994,17553,40880,20872, 40881,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,65506,65508,65287,65282,12849,8470,8481,12443,12444,11904,11908,11910, 11911,11912,11914,11916,11917,11925,11932,11933,11941,11943,11946,11948,11950, 11958,11964,11966,11974,11978,11980,11981,11983,11990,11991,11998,12003,0,0,0, 643,592,603,596,629,339,248,331,650,618,20034,20060,20981,21274,21378,19975, 19980,20039,20109,22231,64012,23662,24435,19983,20871,19982,20014,20115,20162, 20169,20168,20888,21244,21356,21433,22304,22787,22828,23568,24063,26081,27571, 27596,27668,29247,20017,20028,20200,20188,20201,20193,20189,20186,21004,21276, 21324,22306,22307,22807,22831,23425,23428,23570,23611,23668,23667,24068,24192, 24194,24521,25097,25168,27669,27702,27715,27711,27707,29358,29360,29578,31160, 32906,38430,20238,20248,20268,20213,20244,20209,20224,20215,20232,20253,20226, 20229,20258,20243,20228,20212,20242,20913,21011,21001,21008,21158,21282,21279, 21325,21386,21511,22241,22239,22318,22314,22324,22844,22912,22908,22917,22907, 22910,22903,22911,23382,23573,23589,23676,23674,23675,23678,24031,24181,24196, 24322,24346,24436,24533,24532,24527,25180,25182,25188,25185,25190,25186,25177, 25184,25178,25189,26095,26094,26430,26425,26424,26427,26426,26431,26428,26419, 27672,27718,27730,27740,27727,27722,27732,27723,27724,28785,29278,29364,29365, 29582,29994,30335,31349,32593,33400,33404,33408,33405,33407,34381,35198,37017, 37015,37016,37019,37012,38434,38436,38432,38435,20310,20283,20322,20297,20307, 20324,20286,20327,20306,20319,20289,20312,20269,20275,20287,20321,20879,20921, 21020,21022,21025,21165,21166,21257,21347,21362,21390,21391,21552,21559,21546, 21588,21573,21529,21532,21541,21528,21565,21583,21569,21544,21540,21575,22254, 22247,22245,22337,22341,22348,22345,22347,22354,22790,22848,22950,22936,22944, 22935,22926,22946,22928,22927,22951,22945,23438,23442,23592,23594,23693,23695, 23688,23691,23689,23698,23690,23686,23699,23701,24032,24074,24078,24203,24201, 24204,24200,24205,24325,24349,24440,24438,24530,24529,24528,24557,24552,24558, 24563,24545,24548,24547,24570,24559,24567,24571,24576,24564,25146,25219,25228, 25230,25231,25236,25223,25201,25211,25210,25200,25217,25224,25207,25213,25202, 25204,25911,26096,26100,26099,26098,26101,26437,26439,26457,26453,26444,26440, 26461,26445,26458,26443,27600,27673,27674,27768,27751,27755,27780,27787,27791, 27761,27759,27753,27802,27757,27783,27797,27804,27750,27763,27749,27771,27790, 28788,28794,29283,29375,29373,29379,29382,29377,29370,29381,29589,29591,29587, 29588,29586,30010,30009,30100,30101,30337,31037,32820,32917,32921,32912,32914, 32924,33424,33423,33413,33422,33425,33427,33418,33411,33412,35960,36809,36799, 37023,37025,37029,37022,37031,37024,38448,38440,38447,38445,20019,20376,20348, 20357,20349,20352,20359,20342,20340,20361,20356,20343,20300,20375,20330,20378, 20345,20353,20344,20368,20380,20372,20382,20370,20354,20373,20331,20334,20894, 20924,20926,21045,21042,21043,21062,21041,21180,21258,21259,21308,21394,21396, 21639,21631,21633,21649,21634,21640,21611,21626,21630,21605,21612,21620,21606, 21645,21615,21601,21600,21656,21603,21607,21604,22263,22265,22383,22386,22381, 22379,22385,22384,22390,22400,22389,22395,22387,22388,22370,22376,22397,22796, 22853,22965,22970,22991,22990,22962,22988,22977,22966,22972,22979,22998,22961, 22973,22976,22984,22964,22983,23394,23397,23443,23445,23620,23623,23726,23716, 23712,23733,23727,23720,23724,23711,23715,23725,23714,23722,23719,23709,23717, 23734,23728,23718,24087,24084,24089,24360,24354,24355,24356,24404,24450,24446, 24445,24542,24549,24621,24614,24601,24626,24587,24628,24586,24599,24627,24602, 24606,24620,24610,24589,24592,24622,24595,24593,24588,24585,24604,25108,25149, 25261,25268,25297,25278,25258,25270,25290,25262,25267,25263,25275,25257,25264, 25272,25917,26024,26043,26121,26108,26116,26130,26120,26107,26115,26123,26125, 26117,26109,26129,26128,26358,26378,26501,26476,26510,26514,26486,26491,26520, 26502,26500,26484,26509,26508,26490,26527,26513,26521,26499,26493,26497,26488, 26489,26516,27429,27520,27518,27614,27677,27795,27884,27883,27886,27865,27830, 27860,27821,27879,27831,27856,27842,27834,27843,27846,27885,27890,27858,27869, 27828,27786,27805,27776,27870,27840,27952,27853,27847,27824,27897,27855,27881, 27857,28820,28824,28805,28819,28806,28804,28817,28822,28802,28826,28803,29290, 29398,29387,29400,29385,29404,29394,29396,29402,29388,29393,29604,29601,29613, 29606,29602,29600,29612,29597,29917,29928,30015,30016,30014,30092,30104,30383, 30451,30449,30448,30453,30712,30716,30713,30715,30714,30711,31042,31039,31173, 31352,31355,31483,31861,31997,32821,32911,32942,32931,32952,32949,32941,33312, 33440,33472,33451,33434,33432,33435,33461,33447,33454,33468,33438,33466,33460, 33448,33441,33449,33474,33444,33475,33462,33442,34416,34415,34413,34414,35926, 36818,36811,36819,36813,36822,36821,36823,37042,37044,37039,37043,37040,38457, 38461,38460,38458,38467,20429,20421,20435,20402,20425,20427,20417,20436,20444, 20441,20411,20403,20443,20423,20438,20410,20416,20409,20460,21060,21065,21184, 21186,21309,21372,21399,21398,21401,21400,21690,21665,21677,21669,21711,21699, 33549,21687,21678,21718,21686,21701,21702,21664,21616,21692,21666,21694,21618, 21726,21680,22453,22430,22431,22436,22412,22423,22429,22427,22420,22424,22415, 22425,22437,22426,22421,22772,22797,22867,23009,23006,23022,23040,23025,23005, 23034,23037,23036,23030,23012,23026,23031,23003,23017,23027,23029,23008,23038, 23028,23021,23464,23628,23760,23768,23756,23767,23755,23771,23774,23770,23753, 23751,23754,23766,23763,23764,23759,23752,23750,23758,23775,23800,24057,24097, 24098,24099,24096,24100,24240,24228,24226,24219,24227,24229,24327,24366,24406, 24454,24631,24633,24660,24690,24670,24645,24659,24647,24649,24667,24652,24640, 24642,24671,24612,24644,24664,24678,24686,25154,25155,25295,25357,25355,25333, 25358,25347,25323,25337,25359,25356,25336,25334,25344,25363,25364,25338,25365, 25339,25328,25921,25923,26026,26047,26166,26145,26162,26165,26140,26150,26146, 26163,26155,26170,26141,26164,26169,26158,26383,26384,26561,26610,26568,26554, 26588,26555,26616,26584,26560,26551,26565,26603,26596,26591,26549,26573,26547, 26615,26614,26606,26595,26562,26553,26574,26599,26608,26546,26620,26566,26605, 26572,26542,26598,26587,26618,26569,26570,26563,26602,26571,27432,27522,27524, 27574,27606,27608,27616,27680,27681,27944,27956,27949,27935,27964,27967,27922, 27914,27866,27955,27908,27929,27962,27930,27921,27904,27933,27970,27905,27928, 27959,27907,27919,27968,27911,27936,27948,27912,27938,27913,27920,28855,28831, 28862,28849,28848,28833,28852,28853,28841,29249,29257,29258,29292,29296,29299, 29294,29386,29412,29416,29419,29407,29418,29414,29411,29573,29644,29634,29640, 29637,29625,29622,29621,29620,29675,29631,29639,29630,29635,29638,29624,29643, 29932,29934,29998,30023,30024,30119,30122,30329,30404,30472,30467,30468,30469, 30474,30455,30459,30458,30695,30696,30726,30737,30738,30725,30736,30735,30734, 30729,30723,30739,31050,31052,31051,31045,31044,31189,31181,31183,31190,31182, 31360,31358,31441,31488,31489,31866,31864,31865,31871,31872,31873,32003,32008, 32001,32600,32657,32653,32702,32775,32782,32783,32788,32823,32984,32967,32992, 32977,32968,32962,32976,32965,32995,32985,32988,32970,32981,32969,32975,32983, 32998,32973,33279,33313,33428,33497,33534,33529,33543,33512,33536,33493,33594, 33515,33494,33524,33516,33505,33522,33525,33548,33531,33526,33520,33514,33508, 33504,33530,33523,33517,34423,34420,34428,34419,34881,34894,34919,34922,34921, 35283,35332,35335,36210,36835,36833,36846,36832,37105,37053,37055,37077,37061, 37054,37063,37067,37064,37332,37331,38484,38479,38481,38483,38474,38478,20510, 20485,20487,20499,20514,20528,20507,20469,20468,20531,20535,20524,20470,20471, 20503,20508,20512,20519,20533,20527,20529,20494,20826,20884,20883,20938,20932, 20933,20936,20942,21089,21082,21074,21086,21087,21077,21090,21197,21262,21406, 21798,21730,21783,21778,21735,21747,21732,21786,21759,21764,21768,21739,21777, 21765,21745,21770,21755,21751,21752,21728,21774,21763,21771,22273,22274,22476, 22578,22485,22482,22458,22470,22461,22460,22456,22454,22463,22471,22480,22457, 22465,22798,22858,23065,23062,23085,23086,23061,23055,23063,23050,23070,23091, 23404,23463,23469,23468,23555,23638,23636,23788,23807,23790,23793,23799,23808, 23801,24105,24104,24232,24238,24234,24236,24371,24368,24423,24669,24666,24679, 24641,24738,24712,24704,24722,24705,24733,24707,24725,24731,24727,24711,24732, 24718,25113,25158,25330,25360,25430,25388,25412,25413,25398,25411,25572,25401, 25419,25418,25404,25385,25409,25396,25432,25428,25433,25389,25415,25395,25434, 25425,25400,25431,25408,25416,25930,25926,26054,26051,26052,26050,26186,26207, 26183,26193,26386,26387,26655,26650,26697,26674,26675,26683,26699,26703,26646, 26673,26652,26677,26667,26669,26671,26702,26692,26676,26653,26642,26644,26662, 26664,26670,26701,26682,26661,26656,27436,27439,27437,27441,27444,27501,32898, 27528,27622,27620,27624,27619,27618,27623,27685,28026,28003,28004,28022,27917, 28001,28050,27992,28002,28013,28015,28049,28045,28143,28031,28038,27998,28007, 28000,28055,28016,28028,27999,28034,28056,27951,28008,28043,28030,28032,28036, 27926,28035,28027,28029,28021,28048,28892,28883,28881,28893,28875,32569,28898, 28887,28882,28894,28896,28884,28877,28869,28870,28871,28890,28878,28897,29250, 29304,29303,29302,29440,29434,29428,29438,29430,29427,29435,29441,29651,29657, 29669,29654,29628,29671,29667,29673,29660,29650,29659,29652,29661,29658,29655, 29656,29672,29918,29919,29940,29941,29985,30043,30047,30128,30145,30139,30148, 30144,30143,30134,30138,30346,30409,30493,30491,30480,30483,30482,30499,30481, 30485,30489,30490,30498,30503,30755,30764,30754,30773,30767,30760,30766,30763, 30753,30761,30771,30762,30769,31060,31067,31055,31068,31059,31058,31057,31211, 31212,31200,31214,31213,31210,31196,31198,31197,31366,31369,31365,31371,31372, 31370,31367,31448,31504,31492,31507,31493,31503,31496,31498,31502,31497,31506, 31876,31889,31882,31884,31880,31885,31877,32030,32029,32017,32014,32024,32022, 32019,32031,32018,32015,32012,32604,32609,32606,32608,32605,32603,32662,32658, 32707,32706,32704,32790,32830,32825,33018,33010,33017,33013,33025,33019,33024, 33281,33327,33317,33587,33581,33604,33561,33617,33573,33622,33599,33601,33574, 33564,33570,33602,33614,33563,33578,33544,33596,33613,33558,33572,33568,33591, 33583,33577,33607,33605,33612,33619,33566,33580,33611,33575,33608,34387,34386, 34466,34472,34454,34445,34449,34462,34439,34455,34438,34443,34458,34437,34469, 34457,34465,34471,34453,34456,34446,34461,34448,34452,34883,34884,34925,34933, 34934,34930,34944,34929,34943,34927,34947,34942,34932,34940,35346,35911,35927, 35963,36004,36003,36214,36216,36277,36279,36278,36561,36563,36862,36853,36866, 36863,36859,36868,36860,36854,37078,37088,37081,37082,37091,37087,37093,37080, 37083,37079,37084,37092,37200,37198,37199,37333,37346,37338,38492,38495,38588, 39139,39647,39727,20095,20592,20586,20577,20574,20576,20563,20555,20573,20594, 20552,20557,20545,20571,20554,20578,20501,20549,20575,20585,20587,20579,20580, 20550,20544,20590,20595,20567,20561,20944,21099,21101,21100,21102,21206,21203, 21293,21404,21877,21878,21820,21837,21840,21812,21802,21841,21858,21814,21813, 21808,21842,21829,21772,21810,21861,21838,21817,21832,21805,21819,21824,21835, 22282,22279,22523,22548,22498,22518,22492,22516,22528,22509,22525,22536,22520, 22539,22515,22479,22535,22510,22499,22514,22501,22508,22497,22542,22524,22544, 22503,22529,22540,22513,22505,22512,22541,22532,22876,23136,23128,23125,23143, 23134,23096,23093,23149,23120,23135,23141,23148,23123,23140,23127,23107,23133, 23122,23108,23131,23112,23182,23102,23117,23097,23116,23152,23145,23111,23121, 23126,23106,23132,23410,23406,23489,23488,23641,23838,23819,23837,23834,23840, 23820,23848,23821,23846,23845,23823,23856,23826,23843,23839,23854,24126,24116, 24241,24244,24249,24242,24243,24374,24376,24475,24470,24479,24714,24720,24710, 24766,24752,24762,24787,24788,24783,24804,24793,24797,24776,24753,24795,24759, 24778,24767,24771,24781,24768,25394,25445,25482,25474,25469,25533,25502,25517, 25501,25495,25515,25486,25455,25479,25488,25454,25519,25461,25500,25453,25518, 25468,25508,25403,25503,25464,25477,25473,25489,25485,25456,25939,26061,26213, 26209,26203,26201,26204,26210,26392,26745,26759,26768,26780,26733,26734,26798, 26795,26966,26735,26787,26796,26793,26741,26740,26802,26767,26743,26770,26748, 26731,26738,26794,26752,26737,26750,26779,26774,26763,26784,26761,26788,26744, 26747,26769,26764,26762,26749,27446,27443,27447,27448,27537,27535,27533,27534, 27532,27690,28096,28075,28084,28083,28276,28076,28137,28130,28087,28150,28116, 28160,28104,28128,28127,28118,28094,28133,28124,28125,28123,28148,28106,28093, 28141,28144,28090,28117,28098,28111,28105,28112,28146,28115,28157,28119,28109, 28131,28091,28922,28941,28919,28951,28916,28940,28912,28932,28915,28944,28924, 28927,28934,28947,28928,28920,28918,28939,28930,28942,29310,29307,29308,29311, 29469,29463,29447,29457,29464,29450,29448,29439,29455,29470,29576,29686,29688, 29685,29700,29697,29693,29703,29696,29690,29692,29695,29708,29707,29684,29704, 30052,30051,30158,30162,30159,30155,30156,30161,30160,30351,30345,30419,30521, 30511,30509,30513,30514,30516,30515,30525,30501,30523,30517,30792,30802,30793, 30797,30794,30796,30758,30789,30800,31076,31079,31081,31082,31075,31083,31073, 31163,31226,31224,31222,31223,31375,31380,31376,31541,31559,31540,31525,31536, 31522,31524,31539,31512,31530,31517,31537,31531,31533,31535,31538,31544,31514, 31523,31892,31896,31894,31907,32053,32061,32056,32054,32058,32069,32044,32041, 32065,32071,32062,32063,32074,32059,32040,32611,32661,32668,32669,32667,32714, 32715,32717,32720,32721,32711,32719,32713,32799,32798,32795,32839,32835,32840, 33048,33061,33049,33051,33069,33055,33068,33054,33057,33045,33063,33053,33058, 33297,33336,33331,33338,33332,33330,33396,33680,33699,33704,33677,33658,33651, 33700,33652,33679,33665,33685,33689,33653,33684,33705,33661,33667,33676,33693, 33691,33706,33675,33662,33701,33711,33672,33687,33712,33663,33702,33671,33710, 33654,33690,34393,34390,34495,34487,34498,34497,34501,34490,34480,34504,34489, 34483,34488,34508,34484,34491,34492,34499,34493,34494,34898,34953,34965,34984, 34978,34986,34970,34961,34977,34975,34968,34983,34969,34971,34967,34980,34988, 34956,34963,34958,35202,35286,35289,35285,35376,35367,35372,35358,35897,35899, 35932,35933,35965,36005,36221,36219,36217,36284,36290,36281,36287,36289,36568, 36574,36573,36572,36567,36576,36577,36900,36875,36881,36892,36876,36897,37103, 37098,37104,37108,37106,37107,37076,37099,37100,37097,37206,37208,37210,37203, 37205,37356,37364,37361,37363,37368,37348,37369,37354,37355,37367,37352,37358, 38266,38278,38280,38524,38509,38507,38513,38511,38591,38762,38916,39141,39319, 20635,20629,20628,20638,20619,20643,20611,20620,20622,20637,20584,20636,20626, 20610,20615,20831,20948,21266,21265,21412,21415,21905,21928,21925,21933,21879, 22085,21922,21907,21896,21903,21941,21889,21923,21906,21924,21885,21900,21926, 21887,21909,21921,21902,22284,22569,22583,22553,22558,22567,22563,22568,22517, 22600,22565,22556,22555,22579,22591,22582,22574,22585,22584,22573,22572,22587, 22881,23215,23188,23199,23162,23202,23198,23160,23206,23164,23205,23212,23189, 23214,23095,23172,23178,23191,23171,23179,23209,23163,23165,23180,23196,23183, 23187,23197,23530,23501,23499,23508,23505,23498,23502,23564,23600,23863,23875, 23915,23873,23883,23871,23861,23889,23886,23893,23859,23866,23890,23869,23857, 23897,23874,23865,23881,23864,23868,23858,23862,23872,23877,24132,24129,24408, 24486,24485,24491,24777,24761,24780,24802,24782,24772,24852,24818,24842,24854, 24837,24821,24851,24824,24828,24830,24769,24835,24856,24861,24848,24831,24836, 24843,25162,25492,25521,25520,25550,25573,25576,25583,25539,25757,25587,25546, 25568,25590,25557,25586,25589,25697,25567,25534,25565,25564,25540,25560,25555, 25538,25543,25548,25547,25544,25584,25559,25561,25906,25959,25962,25956,25948, 25960,25957,25996,26013,26014,26030,26064,26066,26236,26220,26235,26240,26225, 26233,26218,26226,26369,26892,26835,26884,26844,26922,26860,26858,26865,26895, 26838,26871,26859,26852,26870,26899,26896,26867,26849,26887,26828,26888,26992, 26804,26897,26863,26822,26900,26872,26832,26877,26876,26856,26891,26890,26903, 26830,26824,26845,26846,26854,26868,26833,26886,26836,26857,26901,26917,26823, 27449,27451,27455,27452,27540,27543,27545,27541,27581,27632,27634,27635,27696, 28156,28230,28231,28191,28233,28296,28220,28221,28229,28258,28203,28223,28225, 28253,28275,28188,28211,28235,28224,28241,28219,28163,28206,28254,28264,28252, 28257,28209,28200,28256,28273,28267,28217,28194,28208,28243,28261,28199,28280, 28260,28279,28245,28281,28242,28262,28213,28214,28250,28960,28958,28975,28923, 28974,28977,28963,28965,28962,28978,28959,28968,28986,28955,29259,29274,29320, 29321,29318,29317,29323,29458,29451,29488,29474,29489,29491,29479,29490,29485, 29478,29475,29493,29452,29742,29740,29744,29739,29718,29722,29729,29741,29745, 29732,29731,29725,29737,29728,29746,29947,29999,30063,30060,30183,30170,30177, 30182,30173,30175,30180,30167,30357,30354,30426,30534,30535,30532,30541,30533, 30538,30542,30539,30540,30686,30700,30816,30820,30821,30812,30829,30833,30826, 30830,30832,30825,30824,30814,30818,31092,31091,31090,31088,31234,31242,31235, 31244,31236,31385,31462,31460,31562,31547,31556,31560,31564,31566,31552,31576, 31557,31906,31902,31912,31905,32088,32111,32099,32083,32086,32103,32106,32079, 32109,32092,32107,32082,32084,32105,32081,32095,32078,32574,32575,32613,32614, 32674,32672,32673,32727,32849,32847,32848,33022,32980,33091,33098,33106,33103, 33095,33085,33101,33082,33254,33262,33271,33272,33273,33284,33340,33341,33343, 33397,33595,33743,33785,33827,33728,33768,33810,33767,33764,33788,33782,33808, 33734,33736,33771,33763,33727,33793,33757,33765,33752,33791,33761,33739,33742, 33750,33781,33737,33801,33807,33758,33809,33798,33730,33779,33749,33786,33735, 33745,33770,33811,33731,33772,33774,33732,33787,33751,33762,33819,33755,33790, 34520,34530,34534,34515,34531,34522,34538,34525,34539,34524,34540,34537,34519, 34536,34513,34888,34902,34901,35002,35031,35001,35000,35008,35006,34998,35004, 34999,35005,34994,35073,35017,35221,35224,35223,35293,35290,35291,35406,35405, 35385,35417,35392,35415,35416,35396,35397,35410,35400,35409,35402,35404,35407, 35935,35969,35968,36026,36030,36016,36025,36021,36228,36224,36233,36312,36307, 36301,36295,36310,36316,36303,36309,36313,36296,36311,36293,36591,36599,36602, 36601,36582,36590,36581,36597,36583,36584,36598,36587,36593,36588,36596,36585, 36909,36916,36911,37126,37164,37124,37119,37116,37128,37113,37115,37121,37120, 37127,37125,37123,37217,37220,37215,37218,37216,37377,37386,37413,37379,37402, 37414,37391,37388,37376,37394,37375,37373,37382,37380,37415,37378,37404,37412, 37401,37399,37381,37398,38267,38285,38284,38288,38535,38526,38536,38537,38531, 38528,38594,38600,38595,38641,38640,38764,38768,38766,38919,39081,39147,40166, 40697,20099,20100,20150,20669,20671,20678,20654,20676,20682,20660,20680,20674, 20656,20673,20666,20657,20683,20681,20662,20664,20951,21114,21112,21115,21116, 21955,21979,21964,21968,21963,21962,21981,21952,21972,21956,21993,21951,21970, 21901,21967,21973,21986,21974,21960,22002,21965,21977,21954,22292,22611,22632, 22628,22607,22605,22601,22639,22613,22606,22621,22617,22629,22619,22589,22627, 22641,22780,23239,23236,23243,23226,23224,23217,23221,23216,23231,23240,23227, 23238,23223,23232,23242,23220,23222,23245,23225,23184,23510,23512,23513,23583, 23603,23921,23907,23882,23909,23922,23916,23902,23912,23911,23906,24048,24143, 24142,24138,24141,24139,24261,24268,24262,24267,24263,24384,24495,24493,24823, 24905,24906,24875,24901,24886,24882,24878,24902,24879,24911,24873,24896,25120, 37224,25123,25125,25124,25541,25585,25579,25616,25618,25609,25632,25636,25651, 25667,25631,25621,25624,25657,25655,25634,25635,25612,25638,25648,25640,25665, 25653,25647,25610,25626,25664,25637,25639,25611,25575,25627,25646,25633,25614, 25967,26002,26067,26246,26252,26261,26256,26251,26250,26265,26260,26232,26400, 26982,26975,26936,26958,26978,26993,26943,26949,26986,26937,26946,26967,26969, 27002,26952,26953,26933,26988,26931,26941,26981,26864,27000,26932,26985,26944, 26991,26948,26998,26968,26945,26996,26956,26939,26955,26935,26972,26959,26961, 26930,26962,26927,27003,26940,27462,27461,27459,27458,27464,27457,27547,64013, 27643,27644,27641,27639,27640,28315,28374,28360,28303,28352,28319,28307,28308, 28320,28337,28345,28358,28370,28349,28353,28318,28361,28343,28336,28365,28326, 28367,28338,28350,28355,28380,28376,28313,28306,28302,28301,28324,28321,28351, 28339,28368,28362,28311,28334,28323,28999,29012,29010,29027,29024,28993,29021, 29026,29042,29048,29034,29025,28994,29016,28995,29003,29040,29023,29008,29011, 28996,29005,29018,29263,29325,29324,29329,29328,29326,29500,29506,29499,29498, 29504,29514,29513,29764,29770,29771,29778,29777,29783,29760,29775,29776,29774, 29762,29766,29773,29780,29921,29951,29950,29949,29981,30073,30071,27011,30191, 30223,30211,30199,30206,30204,30201,30200,30224,30203,30198,30189,30197,30205, 30361,30389,30429,30549,30559,30560,30546,30550,30554,30569,30567,30548,30553, 30573,30688,30855,30874,30868,30863,30852,30869,30853,30854,30881,30851,30841, 30873,30848,30870,30843,31100,31106,31101,31097,31249,31256,31257,31250,31255, 31253,31266,31251,31259,31248,31395,31394,31390,31467,31590,31588,31597,31604, 31593,31602,31589,31603,31601,31600,31585,31608,31606,31587,31922,31924,31919, 32136,32134,32128,32141,32127,32133,32122,32142,32123,32131,32124,32140,32148, 32132,32125,32146,32621,32619,32615,32616,32620,32678,32677,32679,32731,32732, 32801,33124,33120,33143,33116,33129,33115,33122,33138,26401,33118,33142,33127, 33135,33092,33121,33309,33353,33348,33344,33346,33349,34033,33855,33878,33910, 33913,33935,33933,33893,33873,33856,33926,33895,33840,33869,33917,33882,33881, 33908,33907,33885,34055,33886,33847,33850,33844,33914,33859,33912,33842,33861, 33833,33753,33867,33839,33858,33837,33887,33904,33849,33870,33868,33874,33903, 33989,33934,33851,33863,33846,33843,33896,33918,33860,33835,33888,33876,33902, 33872,34571,34564,34551,34572,34554,34518,34549,34637,34552,34574,34569,34561, 34550,34573,34565,35030,35019,35021,35022,35038,35035,35034,35020,35024,35205, 35227,35295,35301,35300,35297,35296,35298,35292,35302,35446,35462,35455,35425, 35391,35447,35458,35460,35445,35459,35457,35444,35450,35900,35915,35914,35941, 35940,35942,35974,35972,35973,36044,36200,36201,36241,36236,36238,36239,36237, 36243,36244,36240,36242,36336,36320,36332,36337,36334,36304,36329,36323,36322, 36327,36338,36331,36340,36614,36607,36609,36608,36613,36615,36616,36610,36619, 36946,36927,36932,36937,36925,37136,37133,37135,37137,37142,37140,37131,37134, 37230,37231,37448,37458,37424,37434,37478,37427,37477,37470,37507,37422,37450, 37446,37485,37484,37455,37472,37479,37487,37430,37473,37488,37425,37460,37475, 37456,37490,37454,37459,37452,37462,37426,38303,38300,38302,38299,38546,38547, 38545,38551,38606,38650,38653,38648,38645,38771,38775,38776,38770,38927,38925, 38926,39084,39158,39161,39343,39346,39344,39349,39597,39595,39771,40170,40173, 40167,40576,40701,20710,20692,20695,20712,20723,20699,20714,20701,20708,20691, 20716,20720,20719,20707,20704,20952,21120,21121,21225,21227,21296,21420,22055, 22037,22028,22034,22012,22031,22044,22017,22035,22018,22010,22045,22020,22015, 22009,22665,22652,22672,22680,22662,22657,22655,22644,22667,22650,22663,22673, 22670,22646,22658,22664,22651,22676,22671,22782,22891,23260,23278,23269,23253, 23274,23258,23277,23275,23283,23266,23264,23259,23276,23262,23261,23257,23272, 23263,23415,23520,23523,23651,23938,23936,23933,23942,23930,23937,23927,23946, 23945,23944,23934,23932,23949,23929,23935,24152,24153,24147,24280,24273,24279, 24270,24284,24277,24281,24274,24276,24388,24387,24431,24502,24876,24872,24897, 24926,24945,24947,24914,24915,24946,24940,24960,24948,24916,24954,24923,24933, 24891,24938,24929,24918,25129,25127,25131,25643,25677,25691,25693,25716,25718, 25714,25715,25725,25717,25702,25766,25678,25730,25694,25692,25675,25683,25696, 25680,25727,25663,25708,25707,25689,25701,25719,25971,26016,26273,26272,26271, 26373,26372,26402,27057,27062,27081,27040,27086,27030,27056,27052,27068,27025, 27033,27022,27047,27021,27049,27070,27055,27071,27076,27069,27044,27092,27065, 27082,27034,27087,27059,27027,27050,27041,27038,27097,27031,27024,27074,27061, 27045,27078,27466,27469,27467,27550,27551,27552,27587,27588,27646,28366,28405, 28401,28419,28453,28408,28471,28411,28462,28425,28494,28441,28442,28455,28440, 28475,28434,28397,28426,28470,28531,28409,28398,28461,28480,28464,28476,28469, 28395,28423,28430,28483,28421,28413,28406,28473,28444,28412,28474,28447,28429, 28446,28424,28449,29063,29072,29065,29056,29061,29058,29071,29051,29062,29057, 29079,29252,29267,29335,29333,29331,29507,29517,29521,29516,29794,29811,29809, 29813,29810,29799,29806,29952,29954,29955,30077,30096,30230,30216,30220,30229, 30225,30218,30228,30392,30593,30588,30597,30594,30574,30592,30575,30590,30595, 30898,30890,30900,30893,30888,30846,30891,30878,30885,30880,30892,30882,30884, 31128,31114,31115,31126,31125,31124,31123,31127,31112,31122,31120,31275,31306, 31280,31279,31272,31270,31400,31403,31404,31470,31624,31644,31626,31633,31632, 31638,31629,31628,31643,31630,31621,31640,21124,31641,31652,31618,31931,31935, 31932,31930,32167,32183,32194,32163,32170,32193,32192,32197,32157,32206,32196, 32198,32203,32204,32175,32185,32150,32188,32159,32166,32174,32169,32161,32201, 32627,32738,32739,32741,32734,32804,32861,32860,33161,33158,33155,33159,33165, 33164,33163,33301,33943,33956,33953,33951,33978,33998,33986,33964,33966,33963, 33977,33972,33985,33997,33962,33946,33969,34000,33949,33959,33979,33954,33940, 33991,33996,33947,33961,33967,33960,34006,33944,33974,33999,33952,34007,34004, 34002,34011,33968,33937,34401,34611,34595,34600,34667,34624,34606,34590,34593, 34585,34587,34627,34604,34625,34622,34630,34592,34610,34602,34605,34620,34578, 34618,34609,34613,34626,34598,34599,34616,34596,34586,34608,34577,35063,35047, 35057,35058,35066,35070,35054,35068,35062,35067,35056,35052,35051,35229,35233, 35231,35230,35305,35307,35304,35499,35481,35467,35474,35471,35478,35901,35944, 35945,36053,36047,36055,36246,36361,36354,36351,36365,36349,36362,36355,36359, 36358,36357,36350,36352,36356,36624,36625,36622,36621,37155,37148,37152,37154, 37151,37149,37146,37156,37153,37147,37242,37234,37241,37235,37541,37540,37494, 37531,37498,37536,37524,37546,37517,37542,37530,37547,37497,37527,37503,37539, 37614,37518,37506,37525,37538,37501,37512,37537,37514,37510,37516,37529,37543, 37502,37511,37545,37533,37515,37421,38558,38561,38655,38744,38781,38778,38782, 38787,38784,38786,38779,38788,38785,38783,38862,38861,38934,39085,39086,39170, 39168,39175,39325,39324,39363,39353,39355,39354,39362,39357,39367,39601,39651, 39655,39742,39743,39776,39777,39775,40177,40178,40181,40615,20735,20739,20784, 20728,20742,20743,20726,20734,20747,20748,20733,20746,21131,21132,21233,21231, 22088,22082,22092,22069,22081,22090,22089,22086,22104,22106,22080,22067,22077, 22060,22078,22072,22058,22074,22298,22699,22685,22705,22688,22691,22703,22700, 22693,22689,22783,23295,23284,23293,23287,23286,23299,23288,23298,23289,23297, 23303,23301,23311,23655,23961,23959,23967,23954,23970,23955,23957,23968,23964, 23969,23962,23966,24169,24157,24160,24156,32243,24283,24286,24289,24393,24498, 24971,24963,24953,25009,25008,24994,24969,24987,24979,25007,25005,24991,24978, 25002,24993,24973,24934,25011,25133,25710,25712,25750,25760,25733,25751,25756, 25743,25739,25738,25740,25763,25759,25704,25777,25752,25974,25978,25977,25979, 26034,26035,26293,26288,26281,26290,26295,26282,26287,27136,27142,27159,27109, 27128,27157,27121,27108,27168,27135,27116,27106,27163,27165,27134,27175,27122, 27118,27156,27127,27111,27200,27144,27110,27131,27149,27132,27115,27145,27140, 27160,27173,27151,27126,27174,27143,27124,27158,27473,27557,27555,27554,27558, 27649,27648,27647,27650,28481,28454,28542,28551,28614,28562,28557,28553,28556, 28514,28495,28549,28506,28566,28534,28524,28546,28501,28530,28498,28496,28503, 28564,28563,28509,28416,28513,28523,28541,28519,28560,28499,28555,28521,28543, 28565,28515,28535,28522,28539,29106,29103,29083,29104,29088,29082,29097,29109, 29085,29093,29086,29092,29089,29098,29084,29095,29107,29336,29338,29528,29522, 29534,29535,29536,29533,29531,29537,29530,29529,29538,29831,29833,29834,29830, 29825,29821,29829,29832,29820,29817,29960,29959,30078,30245,30238,30233,30237, 30236,30243,30234,30248,30235,30364,30365,30366,30363,30605,30607,30601,30600, 30925,30907,30927,30924,30929,30926,30932,30920,30915,30916,30921,31130,31137, 31136,31132,31138,31131,27510,31289,31410,31412,31411,31671,31691,31678,31660, 31694,31663,31673,31690,31669,31941,31944,31948,31947,32247,32219,32234,32231, 32215,32225,32259,32250,32230,32246,32241,32240,32238,32223,32630,32684,32688, 32685,32749,32747,32746,32748,32742,32744,32868,32871,33187,33183,33182,33173, 33186,33177,33175,33302,33359,33363,33362,33360,33358,33361,34084,34107,34063, 34048,34089,34062,34057,34061,34079,34058,34087,34076,34043,34091,34042,34056, 34060,34036,34090,34034,34069,34039,34027,34035,34044,34066,34026,34025,34070, 34046,34088,34077,34094,34050,34045,34078,34038,34097,34086,34023,34024,34032, 34031,34041,34072,34080,34096,34059,34073,34095,34402,34646,34659,34660,34679, 34785,34675,34648,34644,34651,34642,34657,34650,34641,34654,34669,34666,34640, 34638,34655,34653,34671,34668,34682,34670,34652,34661,34639,34683,34677,34658, 34663,34665,34906,35077,35084,35092,35083,35095,35096,35097,35078,35094,35089, 35086,35081,35234,35236,35235,35309,35312,35308,35535,35526,35512,35539,35537, 35540,35541,35515,35543,35518,35520,35525,35544,35523,35514,35517,35545,35902, 35917,35983,36069,36063,36057,36072,36058,36061,36071,36256,36252,36257,36251, 36384,36387,36389,36388,36398,36373,36379,36374,36369,36377,36390,36391,36372, 36370,36376,36371,36380,36375,36378,36652,36644,36632,36634,36640,36643,36630, 36631,36979,36976,36975,36967,36971,37167,37163,37161,37162,37170,37158,37166, 37253,37254,37258,37249,37250,37252,37248,37584,37571,37572,37568,37593,37558, 37583,37617,37599,37592,37609,37591,37597,37580,37615,37570,37608,37578,37576, 37582,37606,37581,37589,37577,37600,37598,37607,37585,37587,37557,37601,37574, 37556,38268,38316,38315,38318,38320,38564,38562,38611,38661,38664,38658,38746, 38794,38798,38792,38864,38863,38942,38941,38950,38953,38952,38944,38939,38951, 39090,39176,39162,39185,39188,39190,39191,39189,39388,39373,39375,39379,39380, 39374,39369,39382,39384,39371,39383,39372,39603,39660,39659,39667,39666,39665, 39750,39747,39783,39796,39793,39782,39798,39797,39792,39784,39780,39788,40188, 40186,40189,40191,40183,40199,40192,40185,40187,40200,40197,40196,40579,40659, 40719,40720,20764,20755,20759,20762,20753,20958,21300,21473,22128,22112,22126, 22131,22118,22115,22125,22130,22110,22135,22300,22299,22728,22717,22729,22719, 22714,22722,22716,22726,23319,23321,23323,23329,23316,23315,23312,23318,23336, 23322,23328,23326,23535,23980,23985,23977,23975,23989,23984,23982,23978,23976, 23986,23981,23983,23988,24167,24168,24166,24175,24297,24295,24294,24296,24293, 24395,24508,24989,25000,24982,25029,25012,25030,25025,25036,25018,25023,25016, 24972,25815,25814,25808,25807,25801,25789,25737,25795,25819,25843,25817,25907, 25983,25980,26018,26312,26302,26304,26314,26315,26319,26301,26299,26298,26316, 26403,27188,27238,27209,27239,27186,27240,27198,27229,27245,27254,27227,27217, 27176,27226,27195,27199,27201,27242,27236,27216,27215,27220,27247,27241,27232, 27196,27230,27222,27221,27213,27214,27206,27477,27476,27478,27559,27562,27563, 27592,27591,27652,27651,27654,28589,28619,28579,28615,28604,28622,28616,28510, 28612,28605,28574,28618,28584,28676,28581,28590,28602,28588,28586,28623,28607, 28600,28578,28617,28587,28621,28591,28594,28592,29125,29122,29119,29112,29142, 29120,29121,29131,29140,29130,29127,29135,29117,29144,29116,29126,29146,29147, 29341,29342,29545,29542,29543,29548,29541,29547,29546,29823,29850,29856,29844, 29842,29845,29857,29963,30080,30255,30253,30257,30269,30259,30268,30261,30258, 30256,30395,30438,30618,30621,30625,30620,30619,30626,30627,30613,30617,30615, 30941,30953,30949,30954,30942,30947,30939,30945,30946,30957,30943,30944,31140, 31300,31304,31303,31414,31416,31413,31409,31415,31710,31715,31719,31709,31701, 31717,31706,31720,31737,31700,31722,31714,31708,31723,31704,31711,31954,31956, 31959,31952,31953,32274,32289,32279,32268,32287,32288,32275,32270,32284,32277, 32282,32290,32267,32271,32278,32269,32276,32293,32292,32579,32635,32636,32634, 32689,32751,32810,32809,32876,33201,33190,33198,33209,33205,33195,33200,33196, 33204,33202,33207,33191,33266,33365,33366,33367,34134,34117,34155,34125,34131, 34145,34136,34112,34118,34148,34113,34146,34116,34129,34119,34147,34110,34139, 34161,34126,34158,34165,34133,34151,34144,34188,34150,34141,34132,34149,34156, 34403,34405,34404,34715,34703,34711,34707,34706,34696,34689,34710,34712,34681, 34695,34723,34693,34704,34705,34717,34692,34708,34716,34714,34697,35102,35110, 35120,35117,35118,35111,35121,35106,35113,35107,35119,35116,35103,35313,35552, 35554,35570,35572,35573,35549,35604,35556,35551,35568,35528,35550,35553,35560, 35583,35567,35579,35985,35986,35984,36085,36078,36081,36080,36083,36204,36206, 36261,36263,36403,36414,36408,36416,36421,36406,36412,36413,36417,36400,36415, 36541,36662,36654,36661,36658,36665,36663,36660,36982,36985,36987,36998,37114, 37171,37173,37174,37267,37264,37265,37261,37263,37671,37662,37640,37663,37638, 37647,37754,37688,37692,37659,37667,37650,37633,37702,37677,37646,37645,37579, 37661,37626,37669,37651,37625,37623,37684,37634,37668,37631,37673,37689,37685, 37674,37652,37644,37643,37630,37641,37632,37627,37654,38332,38349,38334,38329, 38330,38326,38335,38325,38333,38569,38612,38667,38674,38672,38809,38807,38804, 38896,38904,38965,38959,38962,39204,39199,39207,39209,39326,39406,39404,39397, 39396,39408,39395,39402,39401,39399,39609,39615,39604,39611,39670,39674,39673, 39671,39731,39808,39813,39815,39804,39806,39803,39810,39827,39826,39824,39802, 39829,39805,39816,40229,40215,40224,40222,40212,40233,40221,40216,40226,40208, 40217,40223,40584,40582,40583,40622,40621,40661,40662,40698,40722,40765,20774, 20773,20770,20772,20768,20777,21236,22163,22156,22157,22150,22148,22147,22142, 22146,22143,22145,22742,22740,22735,22738,23341,23333,23346,23331,23340,23335, 23334,23343,23342,23419,23537,23538,23991,24172,24170,24510,24507,25027,25013, 25020,25063,25056,25061,25060,25064,25054,25839,25833,25827,25835,25828,25832, 25985,25984,26038,26074,26322,27277,27286,27265,27301,27273,27295,27291,27297, 27294,27271,27283,27278,27285,27267,27304,27300,27281,27263,27302,27290,27269, 27276,27282,27483,27565,27657,28620,28585,28660,28628,28643,28636,28653,28647, 28646,28638,28658,28637,28642,28648,29153,29169,29160,29170,29156,29168,29154, 29555,29550,29551,29847,29874,29867,29840,29866,29869,29873,29861,29871,29968, 29969,29970,29967,30084,30275,30280,30281,30279,30372,30441,30645,30635,30642, 30647,30646,30644,30641,30632,30704,30963,30973,30978,30971,30972,30962,30981, 30969,30974,30980,31147,31144,31324,31323,31318,31320,31316,31322,31422,31424, 31425,31749,31759,31730,31744,31743,31739,31758,31732,31755,31731,31746,31753, 31747,31745,31736,31741,31750,31728,31729,31760,31754,31976,32301,32316,32322, 32307,38984,32312,32298,32329,32320,32327,32297,32332,32304,32315,32310,32324, 32314,32581,32639,32638,32637,32756,32754,32812,33211,33220,33228,33226,33221, 33223,33212,33257,33371,33370,33372,34179,34176,34191,34215,34197,34208,34187, 34211,34171,34212,34202,34206,34167,34172,34185,34209,34170,34168,34135,34190, 34198,34182,34189,34201,34205,34177,34210,34178,34184,34181,34169,34166,34200, 34192,34207,34408,34750,34730,34733,34757,34736,34732,34745,34741,34748,34734, 34761,34755,34754,34764,34743,34735,34756,34762,34740,34742,34751,34744,34749, 34782,34738,35125,35123,35132,35134,35137,35154,35127,35138,35245,35247,35246, 35314,35315,35614,35608,35606,35601,35589,35595,35618,35599,35602,35605,35591, 35597,35592,35590,35612,35603,35610,35919,35952,35954,35953,35951,35989,35988, 36089,36207,36430,36429,36435,36432,36428,36423,36675,36672,36997,36990,37176, 37274,37282,37275,37273,37279,37281,37277,37280,37793,37763,37807,37732,37718, 37703,37756,37720,37724,37750,37705,37712,37713,37728,37741,37775,37708,37738, 37753,37719,37717,37714,37711,37745,37751,37755,37729,37726,37731,37735,37760, 37710,37721,38343,38336,38345,38339,38341,38327,38574,38576,38572,38688,38687, 38680,38685,38681,38810,38817,38812,38814,38813,38869,38868,38897,38977,38980, 38986,38985,38981,38979,39205,39211,39212,39210,39219,39218,39215,39213,39217, 39216,39320,39331,39329,39426,39418,39412,39415,39417,39416,39414,39419,39421, 39422,39420,39427,39614,39678,39677,39681,39676,39752,39834,39848,39838,39835, 39846,39841,39845,39844,39814,39842,39840,39855,40243,40257,40295,40246,40238, 40239,40241,40248,40240,40261,40258,40259,40254,40247,40256,40253,32757,40237, 40586,40585,40589,40624,40648,40666,40699,40703,40740,40739,40738,40788,40864, 20785,20781,20782,22168,22172,22167,22170,22173,22169,22896,23356,23657,23658, 24000,24173,24174,25048,25055,25069,25070,25073,25066,25072,25067,25046,25065, 25855,25860,25853,25848,25857,25859,25852,26004,26075,26330,26331,26328,27333, 27321,27325,27361,27334,27322,27318,27319,27335,27316,27309,27486,27593,27659, 28679,28684,28685,28673,28677,28692,28686,28671,28672,28667,28710,28668,28663, 28682,29185,29183,29177,29187,29181,29558,29880,29888,29877,29889,29886,29878, 29883,29890,29972,29971,30300,30308,30297,30288,30291,30295,30298,30374,30397, 30444,30658,30650,30975,30988,30995,30996,30985,30992,30994,30993,31149,31148, 31327,31772,31785,31769,31776,31775,31789,31773,31782,31784,31778,31781,31792, 32348,32336,32342,32355,32344,32354,32351,32337,32352,32343,32339,32693,32691, 32759,32760,32885,33233,33234,33232,33375,33374,34228,34246,34240,34243,34242, 34227,34229,34237,34247,34244,34239,34251,34254,34248,34245,34225,34230,34258, 34340,34232,34231,34238,34409,34791,34790,34786,34779,34795,34794,34789,34783, 34803,34788,34772,34780,34771,34797,34776,34787,34724,34775,34777,34817,34804, 34792,34781,35155,35147,35151,35148,35142,35152,35153,35145,35626,35623,35619, 35635,35632,35637,35655,35631,35644,35646,35633,35621,35639,35622,35638,35630, 35620,35643,35645,35642,35906,35957,35993,35992,35991,36094,36100,36098,36096, 36444,36450,36448,36439,36438,36446,36453,36455,36443,36442,36449,36445,36457, 36436,36678,36679,36680,36683,37160,37178,37179,37182,37288,37285,37287,37295, 37290,37813,37772,37778,37815,37787,37789,37769,37799,37774,37802,37790,37798, 37781,37768,37785,37791,37773,37809,37777,37810,37796,37800,37812,37795,37797, 38354,38355,38353,38579,38615,38618,24002,38623,38616,38621,38691,38690,38693, 38828,38830,38824,38827,38820,38826,38818,38821,38871,38873,38870,38872,38906, 38992,38993,38994,39096,39233,39228,39226,39439,39435,39433,39437,39428,39441, 39434,39429,39431,39430,39616,39644,39688,39684,39685,39721,39733,39754,39756, 39755,39879,39878,39875,39871,39873,39861,39864,39891,39862,39876,39865,39869, 40284,40275,40271,40266,40283,40267,40281,40278,40268,40279,40274,40276,40287, 40280,40282,40590,40588,40671,40705,40704,40726,40741,40747,40746,40745,40744, 40780,40789,20788,20789,21142,21239,21428,22187,22189,22182,22183,22186,22188, 22746,22749,22747,22802,23357,23358,23359,24003,24176,24511,25083,25863,25872, 25869,25865,25868,25870,25988,26078,26077,26334,27367,27360,27340,27345,27353, 27339,27359,27356,27344,27371,27343,27341,27358,27488,27568,27660,28697,28711, 28704,28694,28715,28705,28706,28707,28713,28695,28708,28700,28714,29196,29194, 29191,29186,29189,29349,29350,29348,29347,29345,29899,29893,29879,29891,29974, 30304,30665,30666,30660,30705,31005,31003,31009,31004,30999,31006,31152,31335, 31336,31795,31804,31801,31788,31803,31980,31978,32374,32373,32376,32368,32375, 32367,32378,32370,32372,32360,32587,32586,32643,32646,32695,32765,32766,32888, 33239,33237,33380,33377,33379,34283,34289,34285,34265,34273,34280,34266,34263, 34284,34290,34296,34264,34271,34275,34268,34257,34288,34278,34287,34270,34274, 34816,34810,34819,34806,34807,34825,34828,34827,34822,34812,34824,34815,34826, 34818,35170,35162,35163,35159,35169,35164,35160,35165,35161,35208,35255,35254, 35318,35664,35656,35658,35648,35667,35670,35668,35659,35669,35665,35650,35666, 35671,35907,35959,35958,35994,36102,36103,36105,36268,36266,36269,36267,36461, 36472,36467,36458,36463,36475,36546,36690,36689,36687,36688,36691,36788,37184, 37183,37296,37293,37854,37831,37839,37826,37850,37840,37881,37868,37836,37849, 37801,37862,37834,37844,37870,37859,37845,37828,37838,37824,37842,37863,38269, 38362,38363,38625,38697,38699,38700,38696,38694,38835,38839,38838,38877,38878, 38879,39004,39001,39005,38999,39103,39101,39099,39102,39240,39239,39235,39334, 39335,39450,39445,39461,39453,39460,39451,39458,39456,39463,39459,39454,39452, 39444,39618,39691,39690,39694,39692,39735,39914,39915,39904,39902,39908,39910, 39906,39920,39892,39895,39916,39900,39897,39909,39893,39905,39898,40311,40321, 40330,40324,40328,40305,40320,40312,40326,40331,40332,40317,40299,40308,40309, 40304,40297,40325,40307,40315,40322,40303,40313,40319,40327,40296,40596,40593, 40640,40700,40749,40768,40769,40781,40790,40791,40792,21303,22194,22197,22195, 22755,23365,24006,24007,24302,24303,24512,24513,25081,25879,25878,25877,25875, 26079,26344,26339,26340,27379,27376,27370,27368,27385,27377,27374,27375,28732, 28725,28719,28727,28724,28721,28738,28728,28735,28730,28729,28736,28731,28723, 28737,29203,29204,29352,29565,29564,29882,30379,30378,30398,30445,30668,30670, 30671,30669,30706,31013,31011,31015,31016,31012,31017,31154,31342,31340,31341, 31479,31817,31816,31818,31815,31813,31982,32379,32382,32385,32384,32698,32767, 32889,33243,33241,33291,33384,33385,34338,34303,34305,34302,34331,34304,34294, 34308,34313,34309,34316,34301,34841,34832,34833,34839,34835,34838,35171,35174, 35257,35319,35680,35690,35677,35688,35683,35685,35687,35693,36270,36486,36488, 36484,36697,36694,36695,36693,36696,36698,37005,37187,37185,37303,37301,37298, 37299,37899,37907,37883,37920,37903,37908,37886,37909,37904,37928,37913,37901, 37877,37888,37879,37895,37902,37910,37906,37882,37897,37880,37898,37887,37884, 37900,37878,37905,37894,38366,38368,38367,38702,38703,38841,38843,38909,38910, 39008,39010,39011,39007,39105,39106,39248,39246,39257,39244,39243,39251,39474, 39476,39473,39468,39466,39478,39465,39470,39480,39469,39623,39626,39622,39696, 39698,39697,39947,39944,39927,39941,39954,39928,40000,39943,39950,39942,39959, 39956,39945,40351,40345,40356,40349,40338,40344,40336,40347,40352,40340,40348, 40362,40343,40353,40346,40354,40360,40350,40355,40383,40361,40342,40358,40359, 40601,40603,40602,40677,40676,40679,40678,40752,40750,40795,40800,40798,40797, 40793,40849,20794,20793,21144,21143,22211,22205,22206,23368,23367,24011,24015, 24305,25085,25883,27394,27388,27395,27384,27392,28739,28740,28746,28744,28745, 28741,28742,29213,29210,29209,29566,29975,30314,30672,31021,31025,31023,31828, 31827,31986,32394,32391,32392,32395,32390,32397,32589,32699,32816,33245,34328, 34346,34342,34335,34339,34332,34329,34343,34350,34337,34336,34345,34334,34341, 34857,34845,34843,34848,34852,34844,34859,34890,35181,35177,35182,35179,35322, 35705,35704,35653,35706,35707,36112,36116,36271,36494,36492,36702,36699,36701, 37190,37188,37189,37305,37951,37947,37942,37929,37949,37948,37936,37945,37930, 37943,37932,37952,37937,38373,38372,38371,38709,38714,38847,38881,39012,39113, 39110,39104,39256,39254,39481,39485,39494,39492,39490,39489,39482,39487,39629, 39701,39703,39704,39702,39738,39762,39979,39965,39964,39980,39971,39976,39977, 39972,39969,40375,40374,40380,40385,40391,40394,40399,40382,40389,40387,40379, 40373,40398,40377,40378,40364,40392,40369,40365,40396,40371,40397,40370,40570, 40604,40683,40686,40685,40731,40728,40730,40753,40782,40805,40804,40850,20153, 22214,22213,22219,22897,23371,23372,24021,24017,24306,25889,25888,25894,25890, 27403,27400,27401,27661,28757,28758,28759,28754,29214,29215,29353,29567,29912, 29909,29913,29911,30317,30381,31029,31156,31344,31345,31831,31836,31833,31835, 31834,31988,31985,32401,32591,32647,33246,33387,34356,34357,34355,34348,34354, 34358,34860,34856,34854,34858,34853,35185,35263,35262,35323,35710,35716,35714, 35718,35717,35711,36117,36501,36500,36506,36498,36496,36502,36503,36704,36706, 37191,37964,37968,37962,37963,37967,37959,37957,37960,37961,37958,38719,38883, 39018,39017,39115,39252,39259,39502,39507,39508,39500,39503,39496,39498,39497, 39506,39504,39632,39705,39723,39739,39766,39765,40006,40008,39999,40004,39993, 39987,40001,39996,39991,39988,39986,39997,39990,40411,40402,40414,40410,40395, 40400,40412,40401,40415,40425,40409,40408,40406,40437,40405,40413,40630,40688, 40757,40755,40754,40770,40811,40853,40866,20797,21145,22760,22759,22898,23373, 24024,34863,24399,25089,25091,25092,25897,25893,26006,26347,27409,27410,27407, 27594,28763,28762,29218,29570,29569,29571,30320,30676,31847,31846,32405,33388, 34362,34368,34361,34364,34353,34363,34366,34864,34866,34862,34867,35190,35188, 35187,35326,35724,35726,35723,35720,35909,36121,36504,36708,36707,37308,37986, 37973,37981,37975,37982,38852,38853,38912,39510,39513,39710,39711,39712,40018, 40024,40016,40010,40013,40011,40021,40025,40012,40014,40443,40439,40431,40419, 40427,40440,40420,40438,40417,40430,40422,40434,40432,40418,40428,40436,40435, 40424,40429,40642,40656,40690,40691,40710,40732,40760,40759,40758,40771,40783, 40817,40816,40814,40815,22227,22221,23374,23661,25901,26349,26350,27411,28767, 28769,28765,28768,29219,29915,29925,30677,31032,31159,31158,31850,32407,32649, 33389,34371,34872,34871,34869,34891,35732,35733,36510,36511,36512,36509,37310, 37309,37314,37995,37992,37993,38629,38726,38723,38727,38855,38885,39518,39637, 39769,40035,40039,40038,40034,40030,40032,40450,40446,40455,40451,40454,40453, 40448,40449,40457,40447,40445,40452,40608,40734,40774,40820,40821,40822,22228, 25902,26040,27416,27417,27415,27418,28770,29222,29354,30680,30681,31033,31849, 31851,31990,32410,32408,32411,32409,33248,33249,34374,34375,34376,35193,35194, 35196,35195,35327,35736,35737,36517,36516,36515,37998,37997,37999,38001,38003, 38729,39026,39263,40040,40046,40045,40459,40461,40464,40463,40466,40465,40609, 40693,40713,40775,40824,40827,40826,40825,22302,28774,31855,34876,36274,36518, 37315,38004,38008,38006,38005,39520,40052,40051,40049,40053,40468,40467,40694, 40714,40868,28776,28773,31991,34410,34878,34877,34879,35742,35996,36521,36553, 38731,39027,39028,39116,39265,39339,39524,39526,39527,39716,40469,40471,40776, 25095,27422,29223,34380,36520,38018,38016,38017,39529,39528,39726,40473,29225, 34379,35743,38019,40057,40631,30325,39531,40058,40477,28777,28778,40612,40830, 40777,40856,30849,37561,35023,22715,24658,31911,23290,9556,9574,9559,9568,9580, 9571,9562,9577,9565,9554,9572,9557,9566,9578,9569,9560,9575,9563,9555,9573,9558, 9567,9579,9570,9561,9576,9564,9553,9552,9581,9582,9584,9583,65517,1,37595,1,1, 34124,17077,29679,20917,13897,1,1,37700,1,33518,1,30780,26436,25311,1,1,1,1,1, 20395,1,20488,1,1,1,1,1,20521,1,24484,1,1,28379,1,20605,20737,13434,20750,39020, 14147,33814,1,1,20832,1,20842,1,1,1,1,1,1,1,23426,34685,1,1,20914,20920,40244, 20937,20943,20945,15580,20947,1,20915,20962,21314,20973,33741,26942,1,24443, 21003,21030,21052,21173,21079,21140,21177,21189,31765,34114,21216,34317,1,21253, 1,21833,28377,1,1,1,21299,21316,1,27851,1,26651,29653,24650,16042,14540,1,29149, 17570,21357,21364,1,21374,21375,1,1,30694,21395,1,21408,21419,21422,29607,1, 16217,29596,21441,21445,27721,20041,22526,21465,15019,1,21472,1,1,21494,1,21523, 28793,21803,26199,27995,21613,1,1,21853,21647,21668,18342,1,1,15796,1,1,1,21831, 19693,21551,29719,21894,21929,22021,1,1,17746,1,26291,1,22071,26317,1,26276, 26285,22093,22095,30961,22257,38791,21502,22272,22255,22253,1,13859,1,22342,1, 27758,28811,22338,14001,1,22502,1,22531,1,1,22566,1,22620,22698,13665,22752, 22748,1,22779,23551,22339,1,1,37843,13729,22815,26790,14019,28249,1,23076,21843, 1,34053,22985,1,1,1,1,23001,1,1,1,28017,1,1,23033,1,23211,23139,14054,1,23159, 14088,23190,29797,23251,1,1,15749,1,14130,1,24195,21200,23414,25992,23420,1, 16388,18525,1,23509,24928,1,1,1,23539,23453,19728,23557,1,23571,29646,23572,1,1, 23625,18653,23685,23785,23791,23947,1,1,23824,23832,23878,1,23738,24023,33532, 14381,1,1,1,33415,14390,15298,24110,27274,24181,24186,1,1,21414,20151,24272, 21416,1,24073,24308,1,24313,24315,14496,24316,26686,37915,24333,1,1,15070,18606, 1,24378,1,1,24408,1,24419,38845,1,24434,37696,1,24487,23990,15711,1,1,1,1,37334, 1,1,24625,26245,1,14691,15815,13881,22416,1,31089,15936,24734,24740,24755,1,1,1, 29860,20705,23200,24932,33828,24898,1,1,24961,20980,1,24967,23466,1,1,25043,1,1, 25040,14642,1,1,24611,24924,25886,25483,1,25285,1,25301,1,25452,1,14871,25656, 25592,1,1,25744,28554,1,38932,1,1,25825,25829,38011,14950,25658,14935,25933, 28438,1,1,25989,25965,25951,1,26037,1,19255,26065,16600,1,26080,26083,24543,1, 26136,1,1,26180,1,1,26187,1,26215,1,26227,26228,1,1,1,1,1,30661,1,39332,26370,1, 1,15147,27130,1,26462,26471,26466,1,1,26583,17641,26658,28240,37436,26625,1,1, 26717,1,27105,27147,1,26995,26819,1,26881,26880,15666,14849,1,15232,26540,26977, 1,17148,26934,27032,15265,1,33635,20624,27129,1,1,27205,1,27293,15347,26545, 27336,1,15373,27421,1,24798,27445,27508,1,28341,1,1,1,14144,21537,1,27617,1, 27612,27703,1,1,1,27738,33318,27769,1,17605,1,1,1,1,1,14053,15595,1,39811,1,1, 32655,26679,1,1,1,28054,27996,28284,28420,1,1,1,34099,1,20935,27804,28189,33838, 1,28207,1,29779,1,31180,28239,23185,1,28664,14093,28573,1,28410,1,1,17749,37872, 28484,28508,15694,28532,1,15675,28575,1,28627,1,1,1,1,1,1,20959,1,1,1,1,28747, 28798,28839,28801,28876,28885,28886,28895,16644,15848,29108,29078,1,28971,28997, 23176,29002,29038,23708,1,29007,37730,1,28972,1,1,1,29114,1,28861,29198,37954, 29205,22801,37955,29220,37697,1,29230,29248,1,26813,29269,29271,15957,1,26637, 28477,29314,29482,29483,1,1,18669,1,29480,29486,29647,29610,1,1,29641,29769,1,1, 1,26147,14021,1,1,1,29687,29717,26883,1,29753,1,16087,29788,1,29792,1,29767, 29668,29814,33721,29804,14128,29812,37873,27180,29826,18771,1,1,1,1,23366,1,1, 29896,1,29966,29929,29982,1,1,23511,1,37765,30029,30026,30055,30062,1,16132,1, 30094,29789,30110,30132,30210,30252,30289,30287,30319,30326,1,30352,33263,14328, 1,1,30369,30373,30391,30412,1,33890,1,1,1,30494,30502,30528,25775,1,30552,1, 30639,1,1,1,30708,30729,1,1,26826,30895,30919,30931,38565,31022,1,30935,31028, 30897,1,36792,34948,1,1,1,31110,35072,26882,31104,1,31133,1,31036,31145,28202,1, 16040,31174,1,31188, ] const Big5EncodeLow*: array[16777, UCS16x16] = [ (167u16,5103u16),(168u16,10951u16),(175u16,5120u16),(176u16,5205u16), (177u16,5137u16),(183u16,5040u16),(192u16,1124u16),(193u16,1122u16), (200u16,1128u16),(201u16,1126u16),(202u16,1137u16),(210u16,1132u16), (211u16,1130u16),(215u16,5135u16),(224u16,1141u16),(225u16,1139u16), (232u16,1146u16),(233u16,1144u16),(234u16,1168u16),(236u16,1150u16), (237u16,1148u16),(242u16,1154u16),(243u16,1152u16),(247u16,5136u16), (248u16,11300u16),(249u16,1158u16),(250u16,1156u16),(252u16,1163u16), (256u16,1121u16),(257u16,1138u16),(274u16,1125u16),(275u16,1143u16), (282u16,1127u16),(283u16,1145u16),(299u16,1147u16),(331u16,11301u16), (332u16,1129u16),(333u16,1151u16),(339u16,11299u16),(363u16,1155u16), (461u16,1123u16),(462u16,1140u16),(464u16,1149u16),(465u16,1131u16), (466u16,1153u16),(468u16,1157u16),(470u16,1159u16),(472u16,1160u16), (474u16,1161u16),(476u16,1162u16),(592u16,11295u16),(593u16,1142u16), (596u16,11297u16),(603u16,11296u16),(609u16,1169u16),(618u16,11303u16), (629u16,11298u16),(643u16,11294u16),(650u16,11302u16),(710u16,10952u16), (711u16,5430u16),(713u16,5428u16),(714u16,5429u16),(715u16,5431u16), (717u16,5123u16),(729u16,5427u16),(913u16,5342u16),(914u16,5343u16), (915u16,5344u16),(916u16,5345u16),(917u16,5346u16),(918u16,5347u16), (919u16,5348u16),(920u16,5349u16),(921u16,5350u16),(922u16,5351u16), (923u16,5352u16),(924u16,5353u16),(925u16,5354u16),(926u16,5355u16), (927u16,5356u16),(928u16,5357u16),(929u16,5358u16),(931u16,5359u16), (932u16,5360u16),(933u16,5361u16),(934u16,5362u16),(935u16,5363u16), (936u16,5364u16),(937u16,5365u16),(945u16,5366u16),(946u16,5367u16), (947u16,5368u16),(948u16,5369u16),(949u16,5370u16),(950u16,5371u16), (951u16,5372u16),(952u16,5373u16),(953u16,5374u16),(954u16,5375u16), (955u16,5376u16),(956u16,5377u16),(957u16,5378u16),(958u16,5379u16), (959u16,5380u16),(960u16,5381u16),(961u16,5382u16),(963u16,5383u16), (964u16,5384u16),(965u16,5385u16),(966u16,5386u16),(967u16,5387u16), (968u16,5388u16),(969u16,5389u16),(1025u16,11141u16),(1040u16,11135u16), (1041u16,11136u16),(1042u16,11137u16),(1043u16,11138u16),(1044u16,11139u16), (1045u16,11140u16),(1046u16,11142u16),(1047u16,11143u16),(1048u16,11144u16), (1049u16,11145u16),(1050u16,11146u16),(1051u16,11147u16),(1052u16,11148u16), (1053u16,11149u16),(1054u16,11150u16),(1055u16,11151u16),(1056u16,11152u16), (1057u16,11153u16),(1058u16,11154u16),(1059u16,11155u16),(1060u16,11156u16), (1061u16,11157u16),(1062u16,11158u16),(1063u16,11159u16),(1064u16,11160u16), (1065u16,11161u16),(1066u16,11162u16),(1067u16,11163u16),(1068u16,11164u16), (1069u16,11165u16),(1070u16,11166u16),(1071u16,11167u16),(1072u16,11168u16), (1073u16,11169u16),(1074u16,11170u16),(1075u16,11171u16),(1076u16,11172u16), (1077u16,11173u16),(1078u16,11175u16),(1079u16,11176u16),(1080u16,11177u16), (1081u16,11178u16),(1082u16,11179u16),(1083u16,11180u16),(1084u16,11181u16), (1085u16,11182u16),(1086u16,11183u16),(1087u16,11184u16),(1088u16,11185u16), (1089u16,11186u16),(1090u16,11187u16),(1091u16,11188u16),(1092u16,11189u16), (1093u16,11190u16),(1094u16,11191u16),(1095u16,11192u16),(1096u16,11193u16), (1097u16,11194u16),(1098u16,11195u16),(1099u16,11196u16),(1100u16,11197u16), (1101u16,11198u16),(1102u16,11199u16),(1103u16,11200u16),(1105u16,11174u16), (7870u16,1134u16),(7871u16,1165u16),(7872u16,1136u16),(7873u16,1167u16), (8211u16,5046u16),(8212u16,5048u16),(8216u16,5091u16),(8217u16,5092u16), (8220u16,5093u16),(8221u16,5094u16),(8229u16,5036u16),(8230u16,5035u16), (8231u16,5029u16),(8242u16,5098u16),(8245u16,5097u16),(8251u16,5102u16), (8364u16,5465u16),(8451u16,5191u16),(8453u16,5119u16),(8457u16,5192u16), (8470u16,11259u16),(8481u16,11260u16),(8544u16,5268u16),(8545u16,5269u16), (8546u16,5270u16),(8547u16,5271u16),(8548u16,5272u16),(8549u16,5273u16), (8550u16,5274u16),(8551u16,5275u16),(8552u16,5276u16),(8553u16,5277u16), (8560u16,10916u16),(8561u16,10917u16),(8562u16,10918u16),(8563u16,10919u16), (8564u16,10920u16),(8565u16,10921u16),(8566u16,10922u16),(8567u16,10923u16), (8568u16,10924u16),(8569u16,10925u16),(8592u16,5172u16),(8593u16,5170u16), (8594u16,5173u16),(8595u16,5171u16),(8598u16,5174u16),(8599u16,5175u16), (8600u16,5177u16),(8601u16,5176u16),(8632u16,11202u16),(8633u16,11203u16), (8679u16,11201u16),(8725u16,5182u16),(8730u16,5138u16),(8734u16,5145u16), (8735u16,5158u16),(8736u16,5157u16),(8739u16,5179u16),(8741u16,5178u16), (8745u16,5154u16),(8746u16,5155u16),(8747u16,5162u16),(8750u16,5163u16), (8756u16,5165u16),(8757u16,5164u16),(8786u16,5146u16),(8800u16,5144u16), (8801u16,5147u16),(8806u16,5142u16),(8807u16,5143u16),(8853u16,5168u16), (8857u16,5169u16),(8869u16,5156u16),(8895u16,5159u16),(9178u16,1170u16), (9179u16,1171u16),(9216u16,5432u16),(9217u16,5433u16),(9218u16,5434u16), (9219u16,5435u16),(9220u16,5436u16),(9221u16,5437u16),(9222u16,5438u16), (9223u16,5439u16),(9224u16,5440u16),(9225u16,5441u16),(9226u16,5442u16), (9227u16,5443u16),(9228u16,5444u16),(9229u16,5445u16),(9230u16,5446u16), (9231u16,5447u16),(9232u16,5448u16),(9233u16,5449u16),(9234u16,5450u16), (9235u16,5451u16),(9236u16,5452u16),(9237u16,5453u16),(9238u16,5454u16), (9239u16,5455u16),(9240u16,5456u16),(9241u16,5457u16),(9242u16,5458u16), (9243u16,5459u16),(9244u16,5460u16),(9245u16,5461u16),(9246u16,5462u16), (9247u16,5463u16),(9249u16,5464u16),(9312u16,10896u16),(9313u16,10897u16), (9314u16,10898u16),(9315u16,10899u16),(9316u16,10900u16),(9317u16,10901u16), (9318u16,10902u16),(9319u16,10903u16),(9320u16,10904u16),(9321u16,10905u16), (9332u16,10906u16),(9333u16,10907u16),(9334u16,10908u16),(9335u16,10909u16), (9336u16,10910u16),(9337u16,10911u16),(9338u16,10912u16),(9339u16,10913u16), (9340u16,10914u16),(9341u16,10915u16),(9472u16,5236u16),(9474u16,5237u16), (9484u16,5239u16),(9488u16,5240u16),(9492u16,5241u16),(9496u16,5242u16), (9500u16,5234u16),(9508u16,5233u16),(9516u16,5232u16),(9524u16,5231u16), (9532u16,5230u16),(9552u16,18991u16),(9553u16,18990u16),(9554u16,18972u16), (9555u16,18981u16),(9556u16,18963u16),(9557u16,18974u16),(9558u16,18983u16), (9559u16,18965u16),(9560u16,18978u16),(9561u16,18987u16),(9562u16,18969u16), (9563u16,18980u16),(9564u16,18989u16),(9565u16,18971u16),(9566u16,18975u16), (9567u16,18984u16),(9568u16,18966u16),(9569u16,18977u16),(9570u16,18986u16), (9571u16,18968u16),(9572u16,18973u16),(9573u16,18982u16),(9574u16,18964u16), (9575u16,18979u16),(9576u16,18988u16),(9577u16,18970u16),(9578u16,18976u16), (9579u16,18985u16),(9580u16,18967u16),(9581u16,5243u16),(9582u16,5244u16), (9583u16,5246u16),(9584u16,5245u16),(9585u16,5255u16),(9586u16,5256u16), (9587u16,5257u16),(9588u16,5050u16),(9601u16,5215u16),(9602u16,5216u16), (9603u16,5217u16),(9604u16,5218u16),(9605u16,5219u16),(9606u16,5220u16), (9607u16,5221u16),(9608u16,5222u16),(9609u16,5229u16),(9610u16,5228u16), (9611u16,5227u16),(9612u16,5226u16),(9613u16,5225u16),(9614u16,5224u16), (9615u16,5223u16),(9620u16,5235u16),(9621u16,5238u16),(9632u16,5115u16), (9633u16,5114u16),(9650u16,5108u16),(9651u16,5107u16),(9660u16,5117u16), (9661u16,5116u16),(9670u16,5113u16),(9671u16,5112u16),(9675u16,5105u16), (9678u16,5109u16),(9679u16,5106u16),(9698u16,5251u16),(9699u16,5252u16), (9700u16,5254u16),(9701u16,5253u16),(9733u16,5111u16),(9734u16,5110u16), (9792u16,5166u16),(9794u16,5167u16),(10045u16,10965u16),(11904u16,11263u16), (11908u16,11264u16),(11910u16,11265u16),(11911u16,11266u16),(11912u16,11267u16), (11914u16,11268u16),(11916u16,11269u16),(11917u16,11270u16),(11925u16,11271u16), (11932u16,11272u16),(11933u16,11273u16),(11941u16,11274u16),(11943u16,11275u16), (11946u16,11276u16),(11948u16,11277u16),(11950u16,11278u16),(11958u16,11279u16), (11964u16,11280u16),(11966u16,11281u16),(11974u16,11282u16),(11978u16,11283u16), (11980u16,11284u16),(11981u16,11285u16),(11983u16,11286u16),(11990u16,11287u16), (11991u16,11288u16),(11998u16,11289u16),(12003u16,11290u16),(12083u16,10940u16), (12288u16,5024u16),(12289u16,5026u16),(12290u16,5027u16),(12291u16,5104u16), (12293u16,10959u16),(12294u16,10960u16),(12295u16,10961u16),(12296u16,5073u16), (12297u16,5074u16),(12298u16,5069u16),(12299u16,5070u16),(12300u16,5077u16), (12301u16,5078u16),(12302u16,5081u16),(12303u16,5082u16),(12304u16,5065u16), (12305u16,5066u16),(12306u16,5186u16),(12308u16,5061u16),(12309u16,5062u16), (12317u16,5095u16),(12318u16,5096u16),(12321u16,5278u16),(12322u16,5279u16), (12323u16,5280u16),(12324u16,5281u16),(12325u16,5282u16),(12326u16,5283u16), (12327u16,5284u16),(12328u16,5285u16),(12329u16,5286u16),(12353u16,10966u16), (12354u16,10967u16),(12355u16,10968u16),(12356u16,10969u16),(12357u16,10970u16), (12358u16,10971u16),(12359u16,10972u16),(12360u16,10973u16),(12361u16,10974u16), (12362u16,10975u16),(12363u16,10976u16),(12364u16,10977u16),(12365u16,10978u16), (12366u16,10979u16),(12367u16,10980u16),(12368u16,10981u16),(12369u16,10982u16), (12370u16,10983u16),(12371u16,10984u16),(12372u16,10985u16),(12373u16,10986u16), (12374u16,10987u16),(12375u16,10988u16),(12376u16,10989u16),(12377u16,10990u16), (12378u16,10991u16),(12379u16,10992u16),(12380u16,10993u16),(12381u16,10994u16), (12382u16,10995u16),(12383u16,10996u16),(12384u16,10997u16),(12385u16,10998u16), (12386u16,10999u16),(12387u16,11000u16),(12388u16,11001u16),(12389u16,11002u16), (12390u16,11003u16),(12391u16,11004u16),(12392u16,11005u16),(12393u16,11006u16), (12394u16,11007u16),(12395u16,11008u16),(12396u16,11009u16),(12397u16,11010u16), (12398u16,11011u16),(12399u16,11012u16),(12400u16,11013u16),(12401u16,11014u16), (12402u16,11015u16),(12403u16,11016u16),(12404u16,11017u16),(12405u16,11018u16), (12406u16,11019u16),(12407u16,11020u16),(12408u16,11021u16),(12409u16,11022u16), (12410u16,11023u16),(12411u16,11024u16),(12412u16,11025u16),(12413u16,11026u16), (12414u16,11027u16),(12415u16,11028u16),(12416u16,11029u16),(12417u16,11030u16), (12418u16,11031u16),(12419u16,11032u16),(12420u16,11033u16),(12421u16,11034u16), (12422u16,11035u16),(12423u16,11036u16),(12424u16,11037u16),(12425u16,11038u16), (12426u16,11039u16),(12427u16,11040u16),(12428u16,11041u16),(12429u16,11042u16), (12430u16,11043u16),(12431u16,11044u16),(12432u16,11045u16),(12433u16,11046u16), (12434u16,11047u16),(12435u16,11048u16),(12443u16,11261u16),(12444u16,11262u16), (12445u16,10955u16),(12446u16,10956u16),(12449u16,11049u16),(12450u16,11050u16), (12451u16,11051u16),(12452u16,11052u16),(12453u16,11053u16),(12454u16,11054u16), (12455u16,11055u16),(12456u16,11056u16),(12457u16,11057u16),(12458u16,11058u16), (12459u16,11059u16),(12460u16,11060u16),(12461u16,11061u16),(12462u16,11062u16), (12463u16,11063u16),(12464u16,11064u16),(12465u16,11065u16),(12466u16,11066u16), (12467u16,11067u16),(12468u16,11068u16),(12469u16,11069u16),(12470u16,11070u16), (12471u16,11071u16),(12472u16,11072u16),(12473u16,11073u16),(12474u16,11074u16), (12475u16,11075u16),(12476u16,11076u16),(12477u16,11077u16),(12478u16,11078u16), (12479u16,11079u16),(12480u16,11080u16),(12481u16,11081u16),(12482u16,11082u16), (12483u16,11083u16),(12484u16,11084u16),(12485u16,11085u16),(12486u16,11086u16), (12487u16,11087u16),(12488u16,11088u16),(12489u16,11089u16),(12490u16,11090u16), (12491u16,11091u16),(12492u16,11092u16),(12493u16,11093u16),(12494u16,11094u16), (12495u16,11095u16),(12496u16,11096u16),(12497u16,11097u16),(12498u16,11098u16), (12499u16,11099u16),(12500u16,11100u16),(12501u16,11101u16),(12502u16,11102u16), (12503u16,11103u16),(12504u16,11104u16),(12505u16,11105u16),(12506u16,11106u16), (12507u16,11107u16),(12508u16,11108u16),(12509u16,11109u16),(12510u16,11110u16), (12511u16,11111u16),(12512u16,11112u16),(12513u16,11113u16),(12514u16,11114u16), (12515u16,11115u16),(12516u16,11116u16),(12517u16,11117u16),(12518u16,11118u16), (12519u16,11119u16),(12520u16,11120u16),(12521u16,11121u16),(12522u16,11122u16), (12523u16,11123u16),(12524u16,11124u16),(12525u16,11125u16),(12526u16,11126u16), (12527u16,11127u16),(12528u16,11128u16),(12529u16,11129u16),(12530u16,11130u16), (12531u16,11131u16),(12532u16,11132u16),(12533u16,11133u16),(12534u16,11134u16), (12540u16,10962u16),(12541u16,10953u16),(12542u16,10954u16),(12549u16,5390u16), (12550u16,5391u16),(12551u16,5392u16),(12552u16,5393u16),(12553u16,5394u16), (12554u16,5395u16),(12555u16,5396u16),(12556u16,5397u16),(12557u16,5398u16), (12558u16,5399u16),(12559u16,5400u16),(12560u16,5401u16),(12561u16,5402u16), (12562u16,5403u16),(12563u16,5404u16),(12564u16,5405u16),(12565u16,5406u16), (12566u16,5407u16),(12567u16,5408u16),(12568u16,5409u16),(12569u16,5410u16), (12570u16,5411u16),(12571u16,5412u16),(12572u16,5413u16),(12573u16,5414u16), (12574u16,5415u16),(12575u16,5416u16),(12576u16,5417u16),(12577u16,5418u16), (12578u16,5419u16),(12579u16,5420u16),(12580u16,5421u16),(12581u16,5422u16), (12582u16,5423u16),(12583u16,5424u16),(12584u16,5425u16),(12585u16,5426u16), (12736u16,1099u16),(12737u16,1100u16),(12738u16,1101u16),(12739u16,1102u16), (12740u16,1103u16),(12741u16,1105u16),(12742u16,1108u16),(12743u16,1109u16), (12744u16,1112u16),(12745u16,1114u16),(12746u16,1115u16),(12747u16,1116u16), (12748u16,1117u16),(12749u16,1119u16),(12750u16,1120u16),(12751u16,11204u16), (12849u16,11258u16),(12963u16,5118u16),(13198u16,5202u16),(13199u16,5203u16), (13212u16,5197u16),(13213u16,5198u16),(13214u16,5199u16),(13217u16,5201u16), (13252u16,5204u16),(13262u16,5200u16),(13265u16,5161u16),(13266u16,5160u16), (13269u16,5196u16),(13365u16,2724u16),(13376u16,3422u16),(13386u16,1873u16), (13388u16,1371u16),(13412u16,2933u16),(13427u16,4207u16),(13434u16,19037u16), (13437u16,1376u16),(13438u16,2223u16),(13459u16,1377u16),(13462u16,2227u16), (13477u16,1378u16),(13487u16,3446u16),(13500u16,1533u16),(13505u16,1692u16), (13512u16,3575u16),(13535u16,4572u16),(13540u16,4468u16),(13542u16,1034u16), (13563u16,4218u16),(13574u16,1459u16),(13630u16,1672u16),(13649u16,1390u16), (13651u16,1392u16),(13657u16,1738u16),(13665u16,19202u16),(13677u16,1395u16), (13680u16,3106u16),(13682u16,1396u16),(13687u16,4635u16),(13688u16,1526u16), (13700u16,2790u16),(13719u16,3104u16),(13720u16,1407u16),(13729u16,19212u16), (13733u16,1409u16),(13741u16,4707u16),(13759u16,1410u16),(13761u16,1349u16), (13765u16,1412u16),(13767u16,1388u16),(13770u16,4402u16),(13774u16,4536u16), (13778u16,4929u16),(13782u16,4907u16),(13787u16,3746u16),(13789u16,1610u16), (13809u16,2039u16),(13810u16,1662u16),(13811u16,4829u16),(13819u16,1550u16), (13822u16,4827u16),(13833u16,1612u16),(13848u16,4267u16),(13850u16,1649u16), (13859u16,19184u16),(13861u16,990u16),(13869u16,4541u16),(13877u16,4977u16), (13881u16,19349u16),(13886u16,2804u16),(13895u16,4063u16),(13896u16,2271u16), (13897u16,19005u16),(13902u16,2046u16),(13919u16,4286u16),(13921u16,1912u16), (13946u16,4677u16),(13953u16,1397u16),(13978u16,3432u16),(13989u16,4642u16), (13994u16,3107u16),(13996u16,4639u16),(14000u16,3542u16),(14001u16,19191u16), (14005u16,3256u16),(14009u16,4328u16),(14012u16,3574u16),(14017u16,2203u16), (14019u16,19215u16),(14020u16,2536u16),(14021u16,19661u16),(14023u16,3633u16), (14024u16,4095u16),(14035u16,2853u16),(14036u16,3241u16),(14038u16,3587u16), (14045u16,2851u16),(14049u16,2659u16),(14050u16,3540u16),(14053u16,19532u16), (14054u16,19238u16),(14069u16,2821u16),(14081u16,2849u16),(14083u16,1638u16), (14088u16,19241u16),(14090u16,3532u16),(14093u16,19566u16),(14108u16,4302u16), (14114u16,2656u16),(14115u16,2663u16),(14117u16,2341u16),(14124u16,3459u16), (14125u16,3630u16),(14128u16,19681u16),(14130u16,19249u16),(14131u16,2686u16), (14138u16,4471u16),(14144u16,19512u16),(14147u16,19040u16),(14178u16,4178u16), (14191u16,3984u16),(14231u16,1602u16),(14240u16,2837u16),(14265u16,4016u16), (14270u16,2597u16),(14294u16,1895u16),(14322u16,3222u16),(14328u16,19724u16), (14331u16,4695u16),(14351u16,1920u16),(14361u16,2710u16),(14368u16,1923u16), (14381u16,19290u16),(14390u16,19295u16),(14392u16,1924u16),(14435u16,2963u16), (14453u16,1000u16),(14496u16,19313u16),(14531u16,2550u16),(14540u16,19104u16), (14545u16,2949u16),(14548u16,1902u16),(14586u16,1676u16),(14600u16,1929u16), (14612u16,1930u16),(14631u16,3367u16),(14642u16,19379u16),(14655u16,1931u16), (14669u16,1932u16),(14691u16,19347u16),(14712u16,1872u16),(14720u16,2387u16), (14729u16,1936u16),(14730u16,3551u16),(14738u16,1523u16),(14745u16,2721u16), (14747u16,4174u16),(14753u16,4341u16),(14756u16,4327u16),(14776u16,1940u16), (14812u16,4640u16),(14818u16,3166u16),(14821u16,2594u16),(14828u16,1421u16), (14840u16,1945u16),(14843u16,1474u16),(14846u16,1509u16),(14849u16,19478u16), (14851u16,1947u16),(14854u16,1524u16),(14871u16,19393u16),(14872u16,1577u16), (14889u16,2892u16),(14890u16,4673u16),(14900u16,1430u16),(14923u16,1952u16), (14930u16,4652u16),(14935u16,19409u16),(14940u16,4923u16),(14942u16,3066u16), (14950u16,19407u16),(14951u16,1456u16),(14999u16,1957u16),(15019u16,19131u16), (15037u16,1959u16),(15070u16,19320u16),(15072u16,2921u16),(15088u16,2402u16), (15090u16,1962u16),(15093u16,1006u16),(15099u16,3045u16),(15118u16,2507u16), (15129u16,3040u16),(15138u16,1964u16),(15147u16,19451u16),(15161u16,3827u16), (15170u16,1966u16),(15192u16,1969u16),(15200u16,2593u16),(15217u16,1973u16), (15218u16,1972u16),(15227u16,1974u16),(15228u16,2359u16),(15232u16,19480u16), (15253u16,953u16),(15254u16,2956u16),(15257u16,2952u16),(15265u16,19487u16), (15292u16,1981u16),(15294u16,4168u16),(15298u16,19296u16),(15300u16,2961u16), (15319u16,2974u16),(15325u16,1983u16),(15340u16,1988u16),(15346u16,1990u16), (15347u16,19497u16),(15348u16,2909u16),(15373u16,19501u16),(15377u16,4389u16), (15381u16,2687u16),(15384u16,5001u16),(15444u16,4306u16),(15499u16,1749u16), (15563u16,2000u16),(15565u16,3548u16),(15569u16,4991u16),(15574u16,3566u16), (15580u16,19064u16),(15595u16,19533u16),(15599u16,2005u16),(15634u16,1863u16), (15635u16,2118u16),(15645u16,2595u16),(15666u16,19477u16),(15675u16,19579u16), (15686u16,2021u16),(15692u16,3554u16),(15694u16,19576u16),(15697u16,2509u16), (15711u16,19336u16),(15714u16,3413u16),(15721u16,3553u16),(15722u16,2025u16), (15727u16,3571u16),(15733u16,2026u16),(15741u16,3365u16),(15749u16,19247u16), (15752u16,1852u16),(15754u16,2029u16),(15759u16,2992u16),(15761u16,2031u16), (15781u16,3661u16),(15789u16,2084u16),(15796u16,19152u16),(15807u16,2214u16), (15814u16,4502u16),(15815u16,19348u16),(15817u16,1731u16),(15820u16,3814u16), (15821u16,3046u16),(15827u16,2233u16),(15835u16,4987u16),(15847u16,2688u16), (15848u16,19603u16),(15851u16,4479u16),(15859u16,3668u16),(15860u16,984u16), (15863u16,4425u16),(15868u16,1919u16),(15869u16,3338u16),(15878u16,4758u16), (15936u16,19353u16),(15939u16,1514u16),(15944u16,1373u16),(15957u16,19638u16), (15988u16,4676u16),(16040u16,19778u16),(16041u16,3701u16),(16042u16,19103u16), (16045u16,3218u16),(16049u16,3019u16),(16056u16,2873u16),(16063u16,3070u16), (16066u16,3278u16),(16071u16,2652u16),(16074u16,3708u16),(16076u16,3288u16), (16080u16,2353u16),(16081u16,3710u16),(16086u16,3492u16),(16087u16,19671u16), (16090u16,3577u16),(16091u16,1799u16),(16094u16,2781u16),(16097u16,3487u16), (16098u16,3716u16),(16103u16,3282u16),(16105u16,3483u16),(16107u16,2641u16), (16108u16,1004u16),(16112u16,3717u16),(16115u16,3024u16),(16116u16,3718u16), (16122u16,3719u16),(16124u16,3294u16),(16127u16,3048u16),(16128u16,3331u16), (16132u16,19709u16),(16134u16,3018u16),(16135u16,1891u16),(16142u16,3721u16), (16211u16,3722u16),(16216u16,3036u16),(16217u16,19123u16),(16227u16,3033u16), (16252u16,3727u16),(16275u16,1555u16),(16320u16,3730u16),(16328u16,1910u16), (16343u16,3732u16),(16348u16,3734u16),(16357u16,3681u16),(16365u16,1458u16), (16377u16,1566u16),(16378u16,1489u16),(16388u16,19257u16),(16393u16,1756u16), (16413u16,3741u16),(16441u16,3743u16),(16453u16,3745u16),(16467u16,1426u16), (16471u16,2692u16),(16482u16,3265u16),(16485u16,4941u16),(16490u16,3748u16), (16495u16,3749u16),(16497u16,1824u16),(16552u16,3757u16),(16564u16,1061u16), (16571u16,1499u16),(16575u16,4686u16),(16584u16,3073u16),(16600u16,19422u16), (16607u16,4339u16),(16632u16,1894u16),(16634u16,4615u16),(16642u16,1888u16), (16643u16,3767u16),(16644u16,19602u16),(16649u16,3768u16),(16654u16,3086u16), (16689u16,1042u16),(16690u16,3096u16),(16743u16,3774u16),(16748u16,2449u16), (16750u16,3094u16),(16764u16,1898u16),(16767u16,3191u16),(16769u16,1050u16), (16784u16,2922u16),(16818u16,3776u16),(16836u16,3779u16),(16842u16,2062u16), (16847u16,3782u16),(16859u16,2197u16),(16877u16,1915u16),(16879u16,2066u16), (16889u16,3121u16),(16913u16,3124u16),(16931u16,1759u16),(16960u16,2250u16), (16992u16,3789u16),(17002u16,3144u16),(17014u16,1832u16),(17018u16,3790u16), (17036u16,3793u16),(17044u16,3795u16),(17058u16,1825u16),(17077u16,19002u16), (17081u16,2440u16),(17084u16,3457u16),(17140u16,3247u16),(17147u16,3557u16), (17148u16,19484u16),(17162u16,1014u16),(17195u16,2128u16),(17262u16,3240u16), (17303u16,3807u16),(17306u16,1856u16),(17338u16,1500u16),(17345u16,2038u16), (17369u16,1467u16),(17375u16,4413u16),(17389u16,3819u16),(17392u16,942u16), (17394u16,4411u16),(17409u16,3826u16),(17410u16,3176u16),(17427u16,3831u16), (17445u16,3835u16),(17453u16,3837u16),(17530u16,2180u16),(17551u16,3843u16), (17553u16,11209u16),(17567u16,3029u16),(17568u16,2246u16),(17570u16,19107u16), (17584u16,3849u16),(17591u16,4886u16),(17597u16,1914u16),(17600u16,3325u16), (17603u16,1853u16),(17605u16,19526u16),(17614u16,3610u16),(17629u16,2760u16), (17630u16,1913u16),(17631u16,3609u16),(17633u16,1063u16),(17636u16,2234u16), (17641u16,19460u16),(17642u16,3174u16),(17643u16,3561u16),(17644u16,4589u16), (17652u16,2681u16),(17667u16,2144u16),(17668u16,3858u16),(17673u16,4463u16), (17675u16,2218u16),(17686u16,2258u16),(17691u16,1905u16),(17693u16,2105u16), (17703u16,2256u16),(17710u16,3530u16),(17715u16,3399u16),(17718u16,1857u16), (17723u16,3865u16),(17725u16,2471u16),(17727u16,4331u16),(17731u16,2252u16), (17745u16,3031u16),(17746u16,19165u16),(17749u16,19572u16),(17752u16,1868u16), (17756u16,2142u16),(17761u16,1904u16),(17762u16,5018u16),(17770u16,2269u16), (17773u16,1901u16),(17783u16,3869u16),(17784u16,946u16),(17797u16,2472u16), (17830u16,945u16),(17843u16,949u16),(17882u16,966u16),(17897u16,4678u16), (17898u16,1909u16),(17923u16,944u16),(17926u16,3876u16),(17935u16,2286u16), (17941u16,2335u16),(17943u16,3877u16),(18011u16,2294u16),(18042u16,2772u16), (18048u16,3576u16),(18081u16,971u16),(18094u16,1048u16),(18107u16,1889u16), (18127u16,3221u16),(18128u16,4296u16),(18165u16,3220u16),(18167u16,1896u16), (18195u16,2319u16),(18200u16,4211u16),(18230u16,954u16),(18244u16,955u16), (18254u16,4611u16),(18255u16,965u16),(18300u16,4222u16),(18328u16,3892u16), (18342u16,19149u16),(18389u16,1431u16),(18413u16,3895u16),(18420u16,1452u16), (18432u16,1653u16),(18443u16,1487u16),(18487u16,3903u16),(18525u16,19258u16), (18545u16,3578u16),(18587u16,3251u16),(18605u16,3915u16),(18606u16,19321u16), (18640u16,4153u16),(18653u16,19276u16),(18669u16,19647u16),(18675u16,4619u16), (18682u16,4405u16),(18694u16,3261u16),(18705u16,1355u16),(18718u16,3918u16), (18725u16,3333u16),(18730u16,2376u16),(18733u16,3411u16),(18735u16,1040u16), (18736u16,1018u16),(18741u16,3514u16),(18748u16,3310u16),(18750u16,3581u16), (18757u16,3933u16),(18769u16,3934u16),(18771u16,19686u16),(18789u16,2427u16), (18794u16,3941u16),(18802u16,2833u16),(18825u16,2159u16),(18849u16,2458u16), (18855u16,3946u16),(18911u16,2445u16),(18917u16,3949u16),(18919u16,1656u16), (18959u16,2470u16),(18973u16,3298u16),(18980u16,3951u16),(18997u16,3953u16), (19094u16,3550u16),(19108u16,970u16),(19124u16,1502u16),(19128u16,4154u16), (19153u16,2502u16),(19172u16,3957u16),(19199u16,2517u16),(19216u16,1751u16), (19225u16,3960u16),(19232u16,1736u16),(19244u16,1654u16),(19255u16,19420u16), (19311u16,3340u16),(19312u16,3971u16),(19314u16,2527u16),(19323u16,3460u16), (19326u16,4999u16),(19342u16,2786u16),(19344u16,3350u16),(19347u16,2940u16), (19350u16,2601u16),(19351u16,3354u16),(19357u16,3973u16),(19389u16,3353u16), (19390u16,2619u16),(19392u16,4249u16),(19460u16,4914u16),(19463u16,4909u16), (19470u16,2543u16),(19506u16,943u16),(19515u16,4777u16),(19518u16,1344u16), (19520u16,957u16),(19527u16,956u16),(19543u16,963u16),(19547u16,4660u16), (19565u16,3982u16),(19575u16,1871u16),(19579u16,1907u16),(19581u16,4504u16), (19585u16,1839u16),(19589u16,967u16),(19620u16,4447u16),(19630u16,3384u16), (19632u16,3387u16),(19639u16,4350u16),(19661u16,1341u16),(19681u16,4693u16), (19682u16,951u16),(19693u16,19157u16),(19719u16,969u16),(19721u16,4656u16), (19728u16,19267u16),(19764u16,2588u16),(19830u16,1908u16),(19831u16,948u16), (19849u16,1906u16),(19857u16,4452u16),(19868u16,4455u16),(19968u16,5495u16), (19969u16,5497u16),(19971u16,5498u16),(19972u16,4634u16),(19975u16,11309u16), (19976u16,5517u16),(19977u16,5515u16),(19978u16,5518u16),(19979u16,5516u16), (19980u16,11310u16),(19981u16,5560u16),(19982u16,11319u16),(19983u16,11317u16), (19984u16,5559u16),(19985u16,5558u16),(19988u16,5654u16),(19989u16,5653u16), (19990u16,5652u16),(19992u16,5655u16),(19993u16,5651u16),(19994u16,4633u16), (19996u16,4512u16),(19998u16,5778u16),(19999u16,5779u16),(20001u16,3783u16), (20004u16,1364u16),(20006u16,6220u16),(20008u16,1664u16),(20010u16,4808u16), (20011u16,5519u16),(20012u16,1684u16),(20013u16,5561u16),(20014u16,11320u16), (20015u16,1777u16),(20016u16,5562u16),(20017u16,11339u16),(20018u16,5945u16), (20019u16,11697u16),(20022u16,10926u16),(20023u16,1721u16),(20024u16,5520u16), (20025u16,5563u16),(20027u16,5656u16),(20028u16,11340u16),(20029u16,1262u16), (20031u16,10927u16),(20034u16,11304u16),(20035u16,5499u16),(20037u16,5522u16), (20039u16,11311u16),(20040u16,5523u16),(20041u16,19128u16),(20043u16,5564u16), (20045u16,5657u16),(20046u16,5659u16),(20047u16,5658u16),(20050u16,5780u16), (20051u16,5781u16),(20054u16,6221u16),(20056u16,6998u16),(20057u16,5496u16), (20058u16,11206u16),(20059u16,1670u16),(20060u16,11305u16),(20061u16,5500u16), (20062u16,5525u16),(20063u16,5524u16),(20073u16,5782u16),(20074u16,4262u16), (20083u16,6222u16),(20088u16,4078u16),(20094u16,7455u16),(20095u16,13042u16), (20096u16,1366u16),(20097u16,1365u16),(20098u16,8418u16),(20099u16,14366u16), (20100u16,14367u16),(20101u16,10928u16),(20102u16,5501u16),(20103u16,1367u16), (20104u16,5566u16),(20105u16,1384u16),(20107u16,6223u16),(20108u16,5502u16), (20109u16,11312u16),(20110u16,5526u16),(20113u16,5567u16),(20114u16,5569u16), (20115u16,11321u16),(20116u16,5570u16),(20117u16,5568u16),(20120u16,2731u16), (20121u16,5783u16),(20122u16,4484u16),(20123u16,6224u16),(20126u16,6225u16), (20127u16,6599u16),(20128u16,10929u16),(20129u16,5527u16),(20130u16,5571u16), (20131u16,1774u16),(20132u16,5784u16),(20133u16,5786u16),(20134u16,5785u16), (20136u16,5946u16),(20139u16,6226u16),(20140u16,6227u16),(20141u16,6600u16), (20142u16,6601u16),(20147u16,6999u16),(20150u16,14368u16),(20151u16,19304u16), (20153u16,18485u16),(20154u16,5503u16),(20155u16,1671u16),(20156u16,2712u16), (20159u16,1368u16),(20160u16,5573u16),(20161u16,5572u16),(20162u16,11322u16), (20163u16,5574u16),(20164u16,5580u16),(20166u16,5575u16),(20167u16,5576u16), (20168u16,11324u16),(20169u16,11323u16),(20170u16,5578u16),(20171u16,5579u16), (20173u16,5577u16),(20174u16,4819u16),(20180u16,5662u16),(20181u16,5663u16), (20182u16,5664u16),(20183u16,5665u16),(20184u16,5661u16),(20185u16,5668u16), (20186u16,11346u16),(20188u16,11342u16),(20189u16,10958u16),(20190u16,5669u16), (20191u16,5685u16),(20193u16,11344u16),(20195u16,5666u16),(20196u16,5667u16), (20197u16,5660u16),(20200u16,11341u16),(20201u16,11343u16),(20202u16,4467u16), (20203u16,1369u16),(20206u16,3896u16),(20208u16,5799u16),(20209u16,11382u16), (20210u16,5796u16),(20211u16,5800u16),(20212u16,11392u16),(20213u16,11380u16), (20214u16,5797u16),(20215u16,11384u16),(20216u16,2708u16),(20219u16,5798u16), (20221u16,5801u16),(20223u16,5787u16),(20224u16,11383u16),(20225u16,5802u16), (20226u16,11387u16),(20227u16,2735u16),(20228u16,11391u16),(20229u16,11388u16), (20232u16,11385u16),(20233u16,5788u16),(20234u16,5790u16),(20235u16,5803u16), (20237u16,5792u16),(20238u16,11377u16),(20239u16,5795u16),(20240u16,5793u16), (20241u16,5794u16),(20242u16,11393u16),(20243u16,11390u16),(20244u16,11381u16), (20245u16,5791u16),(20247u16,1778u16),(20248u16,11378u16),(20249u16,5789u16), (20250u16,1270u16),(20253u16,11386u16),(20258u16,11389u16),(20264u16,1271u16), (20265u16,2725u16),(20268u16,11379u16),(20269u16,11499u16),(20271u16,5968u16), (20272u16,5955u16),(20274u16,2596u16),(20275u16,11500u16),(20276u16,5952u16), (20278u16,5970u16),(20279u16,1370u16),(20280u16,5960u16),(20281u16,4822u16), (20282u16,5959u16),(20283u16,11488u16),(20284u16,5963u16),(20285u16,5958u16), (20286u16,11493u16),(20287u16,11501u16),(20289u16,11497u16),(20290u16,2738u16), (20291u16,5961u16),(20293u16,3204u16),(20294u16,5964u16),(20295u16,5949u16), (20296u16,5973u16),(20297u16,11490u16),(20299u16,2715u16),(20300u16,11709u16), (20301u16,5947u16),(20302u16,5969u16),(20303u16,5948u16),(20304u16,5956u16), (20305u16,5957u16),(20306u16,11495u16),(20307u16,11491u16),(20308u16,5962u16), (20309u16,5954u16),(20310u16,11487u16),(20311u16,5950u16),(20312u16,11498u16), (20313u16,5971u16),(20314u16,5974u16),(20315u16,5953u16),(20316u16,5966u16), (20317u16,5972u16),(20318u16,5951u16),(20319u16,11496u16),(20320u16,5967u16), (20321u16,11502u16),(20322u16,11489u16),(20323u16,5965u16),(20324u16,11492u16), (20327u16,11494u16),(20329u16,6241u16),(20330u16,11711u16),(20331u16,11723u16), (20332u16,6233u16),(20334u16,11724u16),(20335u16,6228u16),(20336u16,6238u16), (20338u16,3433u16),(20339u16,6231u16),(20340u16,11705u16),(20341u16,6239u16), (20342u16,11704u16),(20343u16,11708u16),(20344u16,11715u16),(20345u16,11713u16), (20346u16,6247u16),(20347u16,6242u16),(20348u16,11699u16),(20349u16,11701u16), (20350u16,6244u16),(20351u16,6232u16),(20352u16,11702u16),(20353u16,11714u16), (20354u16,11721u16),(20355u16,6237u16),(20356u16,11707u16),(20357u16,11700u16), (20358u16,6236u16),(20359u16,11703u16),(20360u16,6240u16),(20361u16,11706u16), (20362u16,2716u16),(20363u16,6235u16),(20365u16,6230u16),(20367u16,6245u16), (20368u16,11716u16),(20369u16,6246u16),(20370u16,11720u16),(20372u16,11718u16), (20373u16,11722u16),(20374u16,6243u16),(20375u16,11710u16),(20376u16,11698u16), (20378u16,11712u16),(20379u16,6234u16),(20380u16,11717u16),(20381u16,6229u16), (20382u16,11719u16),(20386u16,2734u16),(20392u16,1272u16),(20395u16,19020u16), (20398u16,6616u16),(20399u16,6604u16),(20400u16,3649u16),(20402u16,12058u16), (20403u16,12066u16),(20404u16,1877u16),(20405u16,6603u16),(20406u16,6611u16), (20407u16,6623u16),(20409u16,12072u16),(20410u16,12070u16),(20411u16,4258u16), (20413u16,1372u16),(20415u16,6605u16),(20416u16,12071u16),(20417u16,12061u16), (20418u16,6619u16),(20419u16,6610u16),(20420u16,6618u16),(20421u16,12056u16), (20423u16,12068u16),(20424u16,3691u16),(20425u16,12059u16),(20426u16,6614u16), (20427u16,12060u16),(20428u16,2742u16),(20429u16,12055u16),(20430u16,6621u16), (20431u16,6608u16),(20432u16,6617u16),(20433u16,6607u16),(20435u16,12057u16), (20436u16,12062u16),(20438u16,12069u16),(20439u16,6615u16),(20440u16,6612u16), (20441u16,12064u16),(20442u16,6620u16),(20443u16,12067u16),(20444u16,12063u16), (20445u16,6609u16),(20446u16,6622u16),(20447u16,6613u16),(20448u16,6606u16), (20449u16,6602u16),(20452u16,3421u16),(20453u16,2743u16),(20460u16,12073u16), (20462u16,7025u16),(20463u16,7003u16),(20464u16,1775u16),(20465u16,7019u16), (20466u16,4756u16),(20467u16,7024u16),(20468u16,12513u16),(20469u16,12512u16), (20470u16,12517u16),(20471u16,12518u16),(20472u16,7006u16),(20473u16,2185u16), (20474u16,7015u16),(20477u16,4754u16),(20478u16,7028u16),(20480u16,7016u16), (20483u16,1374u16),(20485u16,12506u16),(20486u16,7009u16),(20487u16,12507u16), (20488u16,19022u16),(20489u16,7030u16),(20491u16,7021u16),(20492u16,7000u16), (20493u16,7001u16),(20494u16,12526u16),(20495u16,7472u16),(20497u16,7014u16), (20498u16,7013u16),(20499u16,12508u16),(20500u16,7017u16),(20501u16,13058u16), (20502u16,7008u16),(20503u16,12519u16),(20504u16,7023u16),(20505u16,7022u16), (20506u16,7012u16),(20507u16,12511u16),(20508u16,12520u16),(20510u16,12505u16), (20511u16,7011u16),(20512u16,12521u16),(20513u16,7020u16),(20514u16,12509u16), (20515u16,7002u16),(20517u16,7005u16),(20518u16,7004u16),(20519u16,12522u16), (20520u16,7018u16),(20521u16,7007u16),(20522u16,7027u16),(20523u16,7029u16), (20524u16,12516u16),(20525u16,7026u16),(20526u16,2739u16),(20527u16,12524u16), (20528u16,12510u16),(20529u16,12525u16),(20531u16,12514u16),(20532u16,2547u16), (20533u16,12523u16),(20535u16,12515u16),(20539u16,1727u16),(20540u16,7010u16), (20544u16,13066u16),(20545u16,13054u16),(20547u16,7460u16),(20549u16,13059u16), (20550u16,13065u16),(20551u16,7459u16),(20552u16,13052u16),(20553u16,7463u16), (20554u16,13056u16),(20555u16,13049u16),(20556u16,7461u16),(20557u16,13053u16), (20558u16,7466u16),(20559u16,7471u16),(20561u16,13070u16),(20563u16,13048u16), (20565u16,7467u16),(20566u16,4761u16),(20567u16,13069u16),(20568u16,2744u16), (20570u16,7462u16),(20571u16,13055u16),(20572u16,7458u16),(20573u16,13050u16), (20574u16,13046u16),(20575u16,13060u16),(20576u16,13047u16),(20577u16,13045u16), (20578u16,13057u16),(20579u16,13063u16),(20580u16,13064u16),(20581u16,7464u16), (20582u16,4217u16),(20584u16,13686u16),(20585u16,13061u16),(20586u16,13044u16), (20587u16,13062u16),(20588u16,2740u16),(20589u16,7474u16),(20590u16,13067u16), (20591u16,7473u16),(20592u16,13043u16),(20594u16,13051u16),(20595u16,13068u16), (20596u16,7469u16),(20597u16,7468u16),(20598u16,7465u16),(20599u16,7470u16), (20602u16,7456u16),(20605u16,7457u16),(20608u16,7952u16),(20609u16,2741u16), (20610u16,13689u16),(20611u16,13682u16),(20613u16,7949u16),(20615u16,13690u16), (20616u16,1375u16),(20619u16,13680u16),(20620u16,13683u16),(20621u16,7948u16), (20622u16,13684u16),(20624u16,19490u16),(20625u16,7951u16),(20626u16,13688u16), (20628u16,13678u16),(20629u16,13677u16),(20630u16,7953u16),(20632u16,7954u16), (20633u16,7950u16),(20634u16,7955u16),(20635u16,13676u16),(20636u16,13687u16), (20637u16,13685u16),(20638u16,13679u16),(20642u16,7947u16),(20643u16,13681u16), (20646u16,4780u16),(20652u16,8425u16),(20653u16,8419u16),(20654u16,14372u16), (20655u16,8428u16),(20656u16,14378u16),(20657u16,14381u16),(20658u16,8421u16), (20659u16,8422u16),(20660u16,14375u16),(20661u16,8420u16),(20662u16,14384u16), (20663u16,8426u16),(20664u16,14385u16),(20666u16,14380u16),(20667u16,8427u16), (20668u16,1776u16),(20669u16,14369u16),(20670u16,8424u16),(20671u16,14370u16), (20673u16,14379u16),(20674u16,14377u16),(20676u16,14373u16),(20677u16,8423u16), (20678u16,14371u16),(20679u16,8429u16),(20680u16,14376u16),(20681u16,14383u16), (20682u16,14374u16),(20683u16,14382u16),(20685u16,2732u16),(20686u16,8876u16), (20687u16,8873u16),(20688u16,2484u16),(20689u16,8874u16),(20691u16,15066u16), (20692u16,15058u16),(20693u16,8872u16),(20694u16,8869u16),(20695u16,15059u16), (20697u16,4935u16),(20698u16,8871u16),(20699u16,15062u16),(20701u16,15064u16), (20703u16,3056u16),(20704u16,15071u16),(20705u16,19361u16),(20707u16,15070u16), (20708u16,15065u16),(20709u16,8868u16),(20710u16,15057u16),(20711u16,8866u16), (20712u16,15060u16),(20713u16,8877u16),(20714u16,15063u16),(20716u16,15067u16), (20717u16,4815u16),(20718u16,8867u16),(20719u16,15069u16),(20720u16,15068u16), (20721u16,8875u16),(20723u16,15061u16),(20724u16,3552u16),(20725u16,9256u16), (20726u16,15681u16),(20728u16,15678u16),(20729u16,9257u16),(20731u16,9255u16), (20732u16,2745u16),(20733u16,15685u16),(20734u16,15682u16),(20735u16,15675u16), (20736u16,9254u16),(20737u16,19036u16),(20738u16,9258u16),(20739u16,15676u16), (20740u16,9253u16),(20741u16,9261u16),(20742u16,15679u16),(20743u16,15680u16), (20744u16,9259u16),(20745u16,9260u16),(20746u16,15686u16),(20747u16,15683u16), (20748u16,15684u16),(20749u16,2733u16),(20750u16,19038u16),(20752u16,9649u16), (20753u16,16321u16),(20754u16,9646u16),(20755u16,16318u16),(20756u16,9648u16), (20757u16,9650u16),(20759u16,16319u16),(20760u16,9647u16),(20762u16,16320u16), (20764u16,16317u16),(20767u16,9945u16),(20768u16,16890u16),(20769u16,9946u16), (20770u16,16888u16),(20772u16,16889u16),(20773u16,16887u16),(20774u16,16886u16), (20777u16,16891u16),(20778u16,9944u16),(20779u16,2709u16),(20781u16,17356u16), (20782u16,17357u16),(20784u16,15677u16),(20785u16,17355u16),(20786u16,9947u16), (20787u16,10393u16),(20788u16,17721u16),(20789u16,17722u16),(20791u16,10636u16), (20792u16,10637u16),(20793u16,18307u16),(20794u16,18306u16),(20795u16,10720u16), (20796u16,10719u16),(20797u16,18636u16),(20799u16,5504u16),(20800u16,5528u16), (20801u16,5582u16),(20803u16,5581u16),(20804u16,5671u16),(20805u16,5670u16), (20806u16,5806u16),(20807u16,5805u16),(20808u16,5807u16),(20809u16,5804u16), (20811u16,5976u16),(20812u16,5975u16),(20813u16,5977u16),(20818u16,6249u16), (20820u16,6248u16),(20821u16,6250u16),(20822u16,1273u16),(20823u16,6624u16), (20825u16,2746u16),(20826u16,12527u16),(20827u16,2747u16),(20828u16,7475u16), (20829u16,2748u16),(20830u16,2749u16),(20831u16,13691u16),(20832u16,19044u16), (20833u16,5210u16),(20834u16,8878u16),(20835u16,5211u16),(20837u16,5505u16), (20839u16,5583u16),(20840u16,5808u16),(20841u16,6251u16),(20842u16,19046u16), (20843u16,5506u16),(20844u16,5586u16),(20845u16,5584u16),(20846u16,5585u16), (20849u16,5809u16),(20852u16,1274u16),(20853u16,5978u16),(20854u16,6253u16), (20855u16,6252u16),(20856u16,6254u16),(20857u16,3009u16),(20860u16,7031u16), (20864u16,9651u16),(20866u16,10930u16),(20870u16,1379u16),(20871u16,11318u16), (20872u16,11211u16),(20873u16,5672u16),(20874u16,5673u16),(20877u16,5810u16), (20879u16,11503u16),(20881u16,6626u16),(20882u16,6625u16),(20883u16,12529u16), (20884u16,12528u16),(20885u16,7476u16),(20886u16,10931u16),(20887u16,5587u16), (20888u16,11325u16),(20890u16,4571u16),(20892u16,1275u16),(20894u16,11725u16), (20896u16,6627u16),(20898u16,7034u16),(20900u16,7032u16),(20901u16,7033u16), (20903u16,4574u16),(20904u16,2757u16),(20906u16,9652u16),(20907u16,10932u16), (20908u16,5674u16),(20910u16,1754u16),(20912u16,5811u16),(20913u16,11394u16), (20914u16,19058u16),(20915u16,19067u16),(20916u16,3965u16),(20917u16,19004u16), (20918u16,5979u16),(20919u16,5980u16),(20920u16,19059u16),(20921u16,11504u16), (20924u16,11726u16),(20925u16,6255u16),(20926u16,11727u16),(20931u16,2758u16), (20932u16,12531u16),(20933u16,12532u16),(20934u16,7037u16),(20935u16,19552u16), (20936u16,12533u16),(20937u16,19061u16),(20938u16,12530u16),(20939u16,7038u16), (20940u16,7036u16),(20941u16,7035u16),(20942u16,12534u16),(20943u16,19062u16), (20944u16,13071u16),(20945u16,19063u16),(20946u16,4164u16),(20947u16,19065u16), (20948u16,13692u16),(20951u16,14386u16),(20952u16,15072u16),(20955u16,1381u16), (20956u16,9262u16),(20957u16,9653u16),(20958u16,16322u16),(20959u16,19589u16), (20960u16,5507u16),(20961u16,5521u16),(20962u16,19068u16),(20964u16,1276u16), (20973u16,19070u16),(20976u16,7477u16),(20977u16,7957u16),(20979u16,8879u16), (20980u16,19369u16),(20981u16,11306u16),(20982u16,5588u16),(20984u16,5677u16), (20985u16,5675u16),(20986u16,5676u16),(20988u16,1382u16),(20989u16,6256u16), (20990u16,4725u16),(20992u16,5508u16),(20993u16,5509u16),(20994u16,11208u16), (20995u16,5529u16),(20997u16,1383u16),(20998u16,5589u16),(20999u16,5590u16), (21000u16,5591u16),(21001u16,11396u16),(21002u16,5678u16),(21003u16,19075u16), (21004u16,11347u16),(21006u16,5815u16),(21008u16,11397u16),(21009u16,5813u16), (21010u16,5814u16),(21011u16,11395u16),(21014u16,5816u16),(21015u16,5812u16), (21020u16,11505u16),(21021u16,6575u16),(21022u16,11506u16),(21023u16,4817u16), (21024u16,5000u16),(21025u16,11507u16),(21028u16,5982u16),(21029u16,5981u16), (21030u16,19076u16),(21031u16,1324u16),(21032u16,5985u16),(21033u16,5983u16), (21034u16,5984u16),(21038u16,6262u16),(21040u16,6261u16),(21041u16,11732u16), (21042u16,11729u16),(21043u16,11730u16),(21044u16,4705u16),(21045u16,11728u16), (21046u16,6263u16),(21047u16,6259u16),(21048u16,6258u16),(21050u16,6260u16), (21051u16,6257u16),(21052u16,19077u16),(21057u16,6264u16),(21059u16,6629u16), (21060u16,12074u16),(21062u16,11731u16),(21063u16,6634u16),(21065u16,12075u16), (21066u16,6630u16),(21067u16,6633u16),(21068u16,6632u16),(21069u16,6631u16), (21070u16,6628u16),(21071u16,1032u16),(21074u16,12537u16),(21076u16,7041u16), (21077u16,12540u16),(21078u16,7039u16),(21079u16,19079u16),(21081u16,2767u16), (21082u16,12536u16),(21083u16,7042u16),(21084u16,7040u16),(21085u16,7043u16), (21086u16,12538u16),(21087u16,12539u16),(21088u16,4757u16),(21089u16,12535u16), (21090u16,12541u16),(21096u16,1648u16),(21097u16,7961u16),(21098u16,7478u16), (21099u16,13072u16),(21100u16,13074u16),(21101u16,13073u16),(21102u16,13075u16), (21103u16,7479u16),(21106u16,7958u16),(21107u16,4784u16),(21108u16,7959u16), (21109u16,7960u16),(21111u16,8431u16),(21112u16,14388u16),(21113u16,1385u16), (21114u16,14387u16),(21115u16,14389u16),(21116u16,14390u16),(21117u16,8432u16), (21119u16,8430u16),(21120u16,15073u16),(21121u16,15074u16),(21122u16,8881u16), (21123u16,8880u16),(21124u16,15412u16),(21127u16,9263u16),(21128u16,9264u16), (21129u16,9265u16),(21130u16,9267u16),(21131u16,15687u16),(21132u16,15688u16), (21133u16,9266u16),(21135u16,4195u16),(21136u16,1386u16),(21137u16,9654u16), (21139u16,9655u16),(21140u16,19080u16),(21142u16,17723u16),(21143u16,18309u16), (21144u16,18308u16),(21145u16,18637u16),(21146u16,4825u16),(21147u16,5510u16), (21151u16,5680u16),(21152u16,5679u16),(21153u16,1277u16),(21155u16,5817u16), (21156u16,2768u16),(21158u16,11398u16),(21160u16,1278u16),(21161u16,5987u16), (21162u16,5988u16),(21163u16,5986u16),(21164u16,5989u16),(21165u16,11508u16), (21166u16,11509u16),(21173u16,19078u16),(21177u16,19081u16),(21179u16,6266u16), (21180u16,11733u16),(21182u16,6265u16),(21184u16,12076u16),(21185u16,6638u16), (21186u16,12077u16),(21187u16,6637u16),(21189u16,19082u16),(21191u16,6635u16), (21193u16,6636u16),(21196u16,4675u16),(21197u16,12542u16),(21200u16,19252u16), (21201u16,4759u16),(21202u16,7480u16),(21203u16,13077u16),(21205u16,7483u16), (21206u16,13076u16),(21207u16,7667u16),(21208u16,7482u16),(21209u16,7481u16), (21211u16,7964u16),(21213u16,7963u16),(21214u16,7962u16),(21215u16,8433u16), (21216u16,19085u16),(21217u16,2770u16),(21218u16,8436u16),(21219u16,8437u16), (21220u16,8435u16),(21222u16,8434u16),(21225u16,15075u16),(21227u16,15076u16), (21231u16,15690u16),(21232u16,9268u16),(21233u16,15689u16),(21235u16,9656u16), (21236u16,16892u16),(21237u16,9948u16),(21239u16,17724u16),(21240u16,10540u16), (21241u16,10933u16),(21242u16,5530u16),(21243u16,5592u16),(21244u16,11326u16), (21246u16,5593u16),(21247u16,5594u16),(21249u16,3937u16),(21253u16,5681u16), (21254u16,5682u16),(21256u16,5818u16),(21257u16,11510u16),(21258u16,11734u16), (21259u16,11735u16),(21261u16,6639u16),(21262u16,12543u16),(21263u16,7485u16), (21264u16,7484u16),(21265u16,13694u16),(21266u16,13693u16),(21269u16,5511u16), (21270u16,5595u16),(21271u16,5683u16),(21273u16,7486u16),(21274u16,11307u16), (21276u16,11348u16),(21277u16,5684u16),(21279u16,11400u16),(21280u16,5820u16), (21281u16,5819u16),(21282u16,11399u16),(21283u16,5990u16),(21284u16,1767u16), (21287u16,1387u16),(21290u16,7044u16),(21292u16,4771u16),(21293u16,13078u16), (21295u16,8438u16),(21296u16,15077u16),(21297u16,8882u16),(21298u16,4938u16), (21299u16,19095u16),(21300u16,16323u16),(21303u16,18053u16),(21304u16,10934u16), (21305u16,5596u16),(21307u16,1279u16),(21308u16,11736u16),(21309u16,12078u16), (21310u16,7489u16),(21311u16,7487u16),(21312u16,7488u16),(21313u16,5512u16), (21314u16,19069u16),(21315u16,5531u16),(21316u16,5288u16),(21317u16,5599u16), (21319u16,5598u16),(21320u16,5597u16),(21321u16,5687u16),(21322u16,5686u16), (21324u16,11349u16),(21325u16,11401u16),(21326u16,1280u16),(21329u16,6270u16), (21330u16,6267u16),(21331u16,6269u16),(21332u16,6268u16),(21335u16,6640u16), (21338u16,7965u16),(21340u16,5513u16),(21341u16,1699u16),(21342u16,5600u16), (21343u16,1603u16),(21344u16,5689u16),(21345u16,5688u16),(21347u16,11511u16), (21348u16,4068u16),(21350u16,6271u16),(21351u16,4638u16),(21353u16,10935u16), (21356u16,11327u16),(21357u16,19108u16),(21358u16,5691u16),(21359u16,5690u16), (21360u16,5821u16),(21361u16,5822u16),(21362u16,11512u16),(21363u16,5991u16), (21364u16,19109u16),(21365u16,5992u16),(21367u16,6272u16),(21368u16,6273u16), (21369u16,6274u16),(21371u16,6641u16),(21372u16,12079u16),(21373u16,4641u16), (21374u16,19111u16),(21375u16,7045u16),(21378u16,11308u16),(21380u16,5601u16), (21386u16,11402u16),(21390u16,11513u16),(21391u16,11514u16),(21394u16,11737u16), (21395u16,19116u16),(21396u16,11738u16),(21398u16,12081u16),(21399u16,12080u16), (21400u16,12083u16),(21401u16,12082u16),(21402u16,6642u16),(21404u16,13079u16), (21405u16,7047u16),(21406u16,12544u16),(21407u16,7046u16),(21408u16,19118u16), (21410u16,4365u16),(21412u16,13695u16),(21413u16,7966u16),(21414u16,19303u16), (21415u16,13696u16),(21416u16,19306u16),(21417u16,1389u16),(21418u16,4925u16), (21419u16,19119u16),(21420u16,15078u16),(21421u16,8883u16),(21422u16,19120u16), (21424u16,1391u16),(21426u16,9269u16),(21428u16,17725u16),(21430u16,10936u16), (21433u16,11328u16),(21435u16,5692u16),(21441u16,19125u16),(21442u16,1393u16), (21443u16,7490u16),(21445u16,19126u16),(21448u16,5514u16),(21449u16,5532u16), (21450u16,5603u16),(21451u16,5602u16),(21452u16,2457u16),(21453u16,5604u16), (21456u16,2789u16),(21457u16,1281u16),(21458u16,4386u16),(21460u16,6276u16), (21462u16,6275u16),(21463u16,6277u16),(21464u16,1282u16),(21465u16,19130u16), (21466u16,4774u16),(21467u16,6643u16),(21471u16,7048u16),(21472u16,19133u16), (21473u16,16324u16),(21474u16,10220u16),(21475u16,5533u16),(21476u16,5694u16), (21477u16,5709u16),(21478u16,5704u16),(21480u16,5699u16),(21481u16,5698u16), (21482u16,5705u16),(21483u16,5703u16),(21484u16,5696u16),(21485u16,5710u16), (21486u16,5697u16),(21487u16,5693u16),(21488u16,5708u16),(21489u16,5707u16), (21490u16,5706u16),(21491u16,5695u16),(21493u16,5702u16),(21494u16,19136u16), (21495u16,2273u16),(21496u16,5701u16),(21499u16,5711u16),(21500u16,5700u16), (21502u16,19179u16),(21505u16,5828u16),(21507u16,5834u16),(21508u16,5830u16), (21510u16,5836u16),(21511u16,11403u16),(21512u16,5833u16),(21513u16,5823u16), (21514u16,5826u16),(21515u16,5829u16),(21516u16,5825u16),(21517u16,5832u16), (21518u16,5835u16),(21519u16,5824u16),(21520u16,5827u16),(21521u16,5831u16), (21522u16,5837u16),(21523u16,19138u16),(21524u16,3438u16),(21526u16,4534u16), (21528u16,11523u16),(21529u16,11520u16),(21530u16,4500u16),(21531u16,6005u16), (21532u16,11521u16),(21533u16,5993u16),(21534u16,5995u16),(21535u16,6019u16), (21536u16,6014u16),(21537u16,19513u16),(21539u16,1394u16),(21540u16,11528u16), (21541u16,11522u16),(21542u16,5997u16),(21543u16,5999u16),(21544u16,11527u16), (21545u16,6006u16),(21546u16,11517u16),(21547u16,6018u16),(21548u16,6020u16), (21549u16,5994u16),(21550u16,6011u16),(21551u16,19158u16),(21552u16,11515u16), (21553u16,6017u16),(21554u16,4524u16),(21555u16,6002u16),(21556u16,1780u16), (21557u16,6012u16),(21558u16,6013u16),(21559u16,11516u16),(21560u16,6010u16), (21561u16,6008u16),(21563u16,6009u16),(21564u16,6015u16),(21565u16,11524u16), (21566u16,5996u16),(21568u16,6016u16),(21569u16,11526u16),(21570u16,6004u16), (21571u16,6001u16),(21573u16,11519u16),(21574u16,6000u16),(21575u16,11529u16), (21576u16,6003u16),(21578u16,6007u16),(21579u16,4647u16),(21580u16,1041u16), (21581u16,4575u16),(21582u16,5998u16),(21583u16,11525u16),(21588u16,11518u16), (21600u16,11755u16),(21601u16,11754u16),(21602u16,6295u16),(21603u16,11757u16), (21604u16,11759u16),(21605u16,11748u16),(21606u16,11751u16),(21607u16,11758u16), (21608u16,6296u16),(21609u16,4767u16),(21610u16,4026u16),(21611u16,11745u16), (21612u16,11749u16),(21613u16,19143u16),(21615u16,11753u16),(21616u16,12098u16), (21617u16,6291u16),(21618u16,12102u16),(21619u16,6278u16),(21620u16,11750u16), (21621u16,6279u16),(21622u16,6292u16),(21623u16,6285u16),(21624u16,6281u16), (21626u16,11746u16),(21627u16,6284u16),(21628u16,6289u16),(21629u16,6298u16), (21630u16,11747u16),(21631u16,11740u16),(21632u16,6283u16),(21633u16,11741u16), (21634u16,11743u16),(21636u16,6286u16),(21637u16,3674u16),(21638u16,6288u16), (21639u16,11739u16),(21640u16,11744u16),(21643u16,6297u16),(21644u16,6293u16), (21645u16,11752u16),(21646u16,6299u16),(21647u16,19147u16),(21648u16,6290u16), (21649u16,11742u16),(21650u16,6287u16),(21651u16,1398u16),(21652u16,4560u16), (21653u16,6282u16),(21654u16,6280u16),(21655u16,4545u16),(21656u16,11756u16), (21658u16,6294u16),(21660u16,4823u16),(21662u16,4029u16),(21664u16,12097u16), (21665u16,12085u16),(21666u16,12100u16),(21667u16,1399u16),(21668u16,19148u16), (21669u16,12087u16),(21670u16,6650u16),(21671u16,6664u16),(21672u16,6646u16), (21673u16,6663u16),(21674u16,6655u16),(21675u16,6660u16),(21676u16,6644u16), (21677u16,12086u16),(21678u16,12092u16),(21679u16,6659u16),(21680u16,12104u16), (21681u16,6661u16),(21682u16,2067u16),(21683u16,6651u16),(21684u16,1400u16), (21686u16,12094u16),(21687u16,12091u16),(21688u16,6649u16),(21689u16,1401u16), (21690u16,12084u16),(21691u16,6662u16),(21692u16,12099u16),(21693u16,6654u16), (21694u16,12101u16),(21695u16,6665u16),(21696u16,6645u16),(21697u16,6656u16), (21698u16,6653u16),(21699u16,12089u16),(21700u16,6657u16),(21701u16,12095u16), (21702u16,12096u16),(21703u16,6652u16),(21704u16,6658u16),(21705u16,6648u16), (21707u16,2698u16),(21708u16,1587u16),(21709u16,2795u16),(21710u16,6647u16), (21711u16,12088u16),(21712u16,1402u16),(21718u16,12093u16),(21722u16,4824u16), (21726u16,12103u16),(21728u16,12564u16),(21729u16,7061u16),(21730u16,12546u16), (21731u16,1470u16),(21732u16,12551u16),(21733u16,7054u16),(21734u16,7065u16), (21735u16,12549u16),(21736u16,7049u16),(21737u16,7059u16),(21738u16,7064u16), (21739u16,12556u16),(21741u16,7060u16),(21742u16,7063u16),(21743u16,1403u16), (21745u16,12559u16),(21746u16,7055u16),(21747u16,12550u16),(21751u16,12562u16), (21752u16,12563u16),(21754u16,7057u16),(21755u16,12561u16),(21756u16,7053u16), (21757u16,7068u16),(21759u16,12553u16),(21761u16,7051u16),(21762u16,3523u16), (21763u16,12566u16),(21764u16,12554u16),(21765u16,12558u16),(21766u16,7056u16), (21767u16,7067u16),(21768u16,12555u16),(21769u16,7062u16),(21770u16,12560u16), (21771u16,12567u16),(21772u16,13094u16),(21773u16,2914u16),(21774u16,12565u16), (21775u16,7069u16),(21776u16,7050u16),(21777u16,12557u16),(21778u16,12548u16), (21779u16,4577u16),(21780u16,7058u16),(21783u16,12547u16),(21784u16,1404u16), (21786u16,12552u16),(21790u16,4576u16),(21795u16,1405u16),(21797u16,1414u16), (21798u16,12545u16),(21799u16,7066u16),(21800u16,1406u16),(21802u16,13086u16), (21803u16,19140u16),(21804u16,7509u16),(21805u16,13100u16),(21806u16,7507u16), (21807u16,7504u16),(21808u16,13091u16),(21809u16,7500u16),(21810u16,13095u16), (21811u16,7511u16),(21812u16,13085u16),(21813u16,13090u16),(21814u16,13089u16), (21815u16,7052u16),(21816u16,7506u16),(21817u16,13098u16),(21819u16,13101u16), (21820u16,13082u16),(21822u16,7984u16),(21823u16,1408u16),(21824u16,13102u16), (21825u16,7512u16),(21827u16,7498u16),(21828u16,7495u16),(21829u16,13093u16), (21830u16,7492u16),(21831u16,19156u16),(21832u16,13099u16),(21833u16,19090u16), (21834u16,7499u16),(21835u16,13103u16),(21837u16,13083u16),(21838u16,13097u16), (21839u16,7502u16),(21840u16,13084u16),(21841u16,13087u16),(21842u16,13092u16), (21843u16,19219u16),(21845u16,7503u16),(21846u16,7501u16),(21847u16,7513u16), (21852u16,7508u16),(21853u16,19146u16),(21854u16,7496u16),(21855u16,7648u16), (21857u16,7497u16),(21858u16,13088u16),(21859u16,7510u16),(21860u16,7505u16), (21861u16,13096u16),(21862u16,7494u16),(21865u16,4567u16),(21866u16,7493u16), (21867u16,3105u16),(21873u16,3260u16),(21874u16,4546u16),(21875u16,4752u16), (21877u16,13080u16),(21878u16,13081u16),(21879u16,13701u16),(21881u16,1498u16), (21883u16,7967u16),(21884u16,7970u16),(21885u16,13712u16),(21886u16,7990u16), (21887u16,13715u16),(21888u16,7968u16),(21889u16,13708u16),(21890u16,7974u16), (21891u16,7980u16),(21892u16,8255u16),(21894u16,19160u16),(21895u16,7978u16), (21896u16,13705u16),(21897u16,7991u16),(21898u16,7971u16),(21899u16,7979u16), (21900u16,13713u16),(21901u16,14404u16),(21902u16,13718u16),(21903u16,13706u16), (21904u16,1419u16),(21905u16,13697u16),(21906u16,13710u16),(21907u16,13704u16), (21908u16,7977u16),(21909u16,13716u16),(21912u16,7973u16),(21913u16,7993u16), (21914u16,7986u16),(21916u16,7975u16),(21917u16,7972u16),(21919u16,7983u16), (21921u16,13717u16),(21922u16,13703u16),(21923u16,13709u16),(21924u16,13711u16), (21925u16,13699u16),(21926u16,13714u16),(21927u16,7969u16),(21928u16,13698u16), (21929u16,19161u16),(21930u16,7976u16),(21931u16,7992u16),(21932u16,7988u16), (21933u16,13700u16),(21934u16,7982u16),(21936u16,2520u16),(21937u16,7989u16), (21938u16,7985u16),(21939u16,7981u16),(21940u16,2793u16),(21941u16,13707u16), (21945u16,1589u16),(21946u16,4544u16),(21947u16,7987u16),(21948u16,4202u16), (21951u16,14402u16),(21952u16,14398u16),(21953u16,4458u16),(21954u16,14413u16), (21955u16,14391u16),(21956u16,14400u16),(21957u16,8452u16),(21958u16,8453u16), (21959u16,8445u16),(21960u16,14409u16),(21961u16,8455u16),(21962u16,14396u16), (21963u16,14395u16),(21964u16,14393u16),(21965u16,14411u16),(21966u16,8443u16), (21967u16,14405u16),(21968u16,14394u16),(21969u16,8446u16),(21970u16,14403u16), (21971u16,8441u16),(21972u16,14399u16),(21973u16,14406u16),(21974u16,14408u16), (21975u16,1411u16),(21976u16,3898u16),(21977u16,14412u16),(21978u16,8450u16), (21979u16,14392u16),(21980u16,8444u16),(21981u16,14397u16),(21982u16,4556u16), (21983u16,8439u16),(21985u16,8451u16),(21986u16,14407u16),(21987u16,8447u16), (21988u16,8448u16),(21989u16,8454u16),(21990u16,8442u16),(21991u16,5212u16), (21992u16,8440u16),(21993u16,14401u16),(21994u16,4531u16),(21996u16,2216u16), (21999u16,8449u16),(22000u16,4543u16),(22001u16,4538u16),(22002u16,14410u16), (22005u16,3901u16),(22006u16,8899u16),(22007u16,8894u16),(22009u16,15093u16), (22010u16,15089u16),(22011u16,1661u16),(22012u16,15083u16),(22013u16,8888u16), (22014u16,8884u16),(22015u16,15092u16),(22016u16,8885u16),(22017u16,15086u16), (22018u16,15088u16),(22020u16,15091u16),(22021u16,4537u16),(22022u16,8890u16), (22024u16,8897u16),(22025u16,8891u16),(22028u16,15081u16),(22029u16,8892u16), (22030u16,8893u16),(22031u16,15084u16),(22032u16,8898u16),(22033u16,4795u16), (22034u16,15082u16),(22035u16,15087u16),(22036u16,8889u16),(22037u16,15080u16), (22038u16,8895u16),(22039u16,8887u16),(22043u16,8886u16),(22044u16,15085u16), (22045u16,15090u16),(22046u16,4506u16),(22047u16,8896u16),(22048u16,4847u16), (22049u16,1955u16),(22050u16,4505u16),(22051u16,3738u16),(22053u16,4527u16), (22055u16,15079u16),(22057u16,9276u16),(22058u16,15707u16),(22060u16,15704u16), (22061u16,4498u16),(22062u16,9270u16),(22063u16,9282u16),(22064u16,9283u16), (22066u16,9273u16),(22067u16,15702u16),(22068u16,9275u16),(22069u16,15694u16), (22070u16,9281u16),(22071u16,19169u16),(22072u16,15706u16),(22073u16,9272u16), (22074u16,15708u16),(22075u16,9271u16),(22077u16,15703u16),(22078u16,15705u16), (22079u16,9274u16),(22080u16,15701u16),(22081u16,15695u16),(22082u16,15692u16), (22083u16,4533u16),(22085u16,13702u16),(22086u16,15698u16),(22088u16,15691u16), (22089u16,15697u16),(22090u16,15696u16),(22092u16,15693u16),(22093u16,19174u16), (22094u16,9278u16),(22095u16,19175u16),(22096u16,3989u16),(22098u16,1529u16), (22099u16,9277u16),(22100u16,3956u16),(22103u16,9279u16),(22104u16,15699u16), (22105u16,9657u16),(22106u16,15700u16),(22109u16,4700u16),(22110u16,16333u16), (22112u16,16326u16),(22113u16,2283u16),(22114u16,9669u16),(22115u16,16330u16), (22116u16,9661u16),(22117u16,9665u16),(22118u16,16329u16),(22120u16,9664u16), (22121u16,9660u16),(22122u16,9663u16),(22123u16,9658u16),(22124u16,9668u16), (22125u16,16331u16),(22126u16,16327u16),(22127u16,9667u16),(22128u16,16325u16), (22129u16,9666u16),(22130u16,16332u16),(22131u16,16328u16),(22132u16,9280u16), (22134u16,9670u16),(22135u16,16334u16),(22136u16,9662u16),(22137u16,9659u16), (22138u16,4037u16),(22139u16,4595u16),(22140u16,4687u16),(22142u16,16899u16), (22143u16,16901u16),(22144u16,9950u16),(22145u16,16902u16),(22146u16,16900u16), (22147u16,16898u16),(22148u16,16897u16),(22149u16,9952u16),(22150u16,16896u16), (22151u16,9953u16),(22153u16,1663u16),(22154u16,2608u16),(22155u16,4430u16), (22156u16,16894u16),(22157u16,16895u16),(22158u16,9949u16),(22159u16,9954u16), (22160u16,9951u16),(22162u16,2701u16),(22163u16,16893u16),(22165u16,10221u16), (22167u16,17360u16),(22168u16,17358u16),(22169u16,17363u16),(22170u16,17361u16), (22172u16,17359u16),(22173u16,17362u16),(22174u16,2699u16),(22175u16,2607u16), (22177u16,1512u16),(22180u16,3519u16),(22181u16,10394u16),(22182u16,17728u16), (22183u16,17729u16),(22184u16,10541u16),(22186u16,17730u16),(22187u16,17726u16), (22188u16,17731u16),(22189u16,17727u16),(22190u16,10222u16),(22191u16,1614u16), (22193u16,1946u16),(22194u16,18054u16),(22195u16,18056u16),(22196u16,10544u16), (22197u16,18055u16),(22198u16,10543u16),(22199u16,10542u16),(22201u16,4259u16), (22204u16,10545u16),(22205u16,18311u16),(22206u16,18312u16),(22207u16,4487u16), (22208u16,10639u16),(22209u16,10638u16),(22210u16,10640u16),(22211u16,18310u16), (22213u16,18487u16),(22214u16,18486u16),(22216u16,10721u16),(22217u16,10723u16), (22218u16,10722u16),(22219u16,18488u16),(22220u16,10778u16),(22221u16,18751u16), (22225u16,10819u16),(22227u16,18750u16),(22228u16,18823u16),(22230u16,4338u16), (22231u16,11313u16),(22234u16,5713u16),(22235u16,5712u16),(22237u16,5840u16), (22238u16,5839u16),(22239u16,11405u16),(22240u16,5838u16),(22241u16,11404u16), (22242u16,1283u16),(22244u16,6023u16),(22245u16,11532u16),(22247u16,11531u16), (22250u16,6021u16),(22251u16,6024u16),(22253u16,19182u16),(22254u16,11530u16), (22255u16,19181u16),(22256u16,6022u16),(22257u16,19177u16),(22263u16,11760u16), (22265u16,11761u16),(22266u16,6300u16),(22267u16,979u16),(22269u16,3712u16), (22271u16,6666u16),(22272u16,19180u16),(22273u16,12568u16),(22274u16,12569u16), (22275u16,7070u16),(22276u16,7071u16),(22279u16,13105u16),(22280u16,7514u16), (22281u16,7516u16),(22282u16,13104u16),(22283u16,7515u16),(22284u16,13719u16), (22285u16,7994u16),(22290u16,8456u16),(22291u16,8457u16),(22292u16,14414u16), (22293u16,4379u16),(22294u16,8901u16),(22296u16,8900u16),(22298u16,15709u16), (22299u16,16336u16),(22300u16,16335u16),(22301u16,2797u16),(22302u16,18883u16), (22303u16,5534u16),(22304u16,11329u16),(22306u16,11350u16),(22307u16,11351u16), (22312u16,5843u16),(22313u16,5847u16),(22314u16,11407u16),(22316u16,5845u16), (22317u16,5844u16),(22318u16,11406u16),(22319u16,5846u16),(22320u16,5842u16), (22322u16,3052u16),(22323u16,5841u16),(22324u16,11408u16),(22331u16,6034u16), (22333u16,1833u16),(22334u16,6031u16),(22335u16,4196u16),(22336u16,6027u16), (22337u16,11533u16),(22338u16,19190u16),(22339u16,19208u16),(22341u16,11534u16), (22342u16,19186u16),(22343u16,6029u16),(22345u16,11536u16),(22346u16,6025u16), (22347u16,11537u16),(22348u16,11535u16),(22349u16,6028u16),(22350u16,6030u16), (22351u16,6033u16),(22352u16,6032u16),(22353u16,6026u16),(22354u16,11538u16), (22356u16,3899u16),(22359u16,4021u16),(22363u16,2665u16),(22367u16,4918u16), (22369u16,6305u16),(22370u16,11774u16),(22372u16,6307u16),(22374u16,6306u16), (22375u16,4760u16),(22376u16,11775u16),(22377u16,6304u16),(22378u16,6303u16), (22379u16,11765u16),(22381u16,11764u16),(22383u16,11762u16),(22384u16,11767u16), (22385u16,11766u16),(22386u16,11763u16),(22387u16,11772u16),(22388u16,11773u16), (22389u16,11770u16),(22390u16,11768u16),(22391u16,6302u16),(22394u16,4816u16), (22395u16,11771u16),(22396u16,6308u16),(22397u16,11776u16),(22398u16,3678u16), (22399u16,2803u16),(22400u16,11769u16),(22402u16,6667u16),(22403u16,6301u16), (22408u16,4172u16),(22410u16,3442u16),(22411u16,6668u16),(22412u16,12109u16), (22413u16,2802u16),(22415u16,12115u16),(22416u16,19350u16),(22419u16,6674u16), (22420u16,12113u16),(22421u16,12119u16),(22423u16,12110u16),(22424u16,12114u16), (22425u16,12116u16),(22426u16,12118u16),(22427u16,12112u16),(22428u16,1631u16), (22429u16,12111u16),(22430u16,12106u16),(22431u16,12107u16),(22432u16,6669u16), (22433u16,4228u16),(22434u16,6671u16),(22435u16,6670u16),(22436u16,12108u16), (22437u16,12117u16),(22439u16,4702u16),(22442u16,4648u16),(22446u16,6673u16), (22451u16,1039u16),(22452u16,3815u16),(22453u16,12105u16),(22454u16,12579u16), (22456u16,12578u16),(22457u16,12583u16),(22458u16,12574u16),(22459u16,3440u16), (22460u16,12577u16),(22461u16,12576u16),(22462u16,2042u16),(22463u16,12580u16), (22465u16,12584u16),(22466u16,7072u16),(22467u16,7075u16),(22468u16,3150u16), (22470u16,12575u16),(22471u16,12581u16),(22472u16,3586u16),(22475u16,7074u16), (22476u16,12570u16),(22478u16,6672u16),(22479u16,13119u16),(22480u16,12582u16), (22482u16,12573u16),(22484u16,7073u16),(22485u16,12572u16),(22487u16,3444u16), (22492u16,13110u16),(22493u16,2801u16),(22494u16,4712u16),(22495u16,7517u16), (22496u16,7521u16),(22497u16,13126u16),(22498u16,13108u16),(22499u16,13122u16), (22500u16,7522u16),(22501u16,13124u16),(22502u16,19193u16),(22503u16,13130u16), (22505u16,13134u16),(22508u16,13125u16),(22509u16,13113u16),(22510u16,13121u16), (22511u16,3839u16),(22512u16,13135u16),(22513u16,13133u16),(22514u16,13123u16), (22515u16,13118u16),(22516u16,13111u16),(22517u16,13727u16),(22518u16,13109u16), (22519u16,7526u16),(22520u16,13116u16),(22521u16,7527u16),(22522u16,7523u16), (22523u16,13106u16),(22524u16,13128u16),(22525u16,13114u16),(22526u16,19129u16), (22528u16,13112u16),(22529u16,13131u16),(22530u16,7524u16),(22531u16,19195u16), (22532u16,13137u16),(22533u16,7518u16),(22534u16,7520u16),(22535u16,13120u16), (22536u16,13115u16),(22537u16,7076u16),(22538u16,7519u16),(22539u16,13117u16), (22540u16,13132u16),(22541u16,13136u16),(22542u16,13127u16),(22544u16,13129u16), (22546u16,3585u16),(22548u16,13107u16),(22552u16,1044u16),(22553u16,13722u16), (22555u16,13731u16),(22556u16,13730u16),(22557u16,8002u16),(22558u16,13723u16), (22560u16,8003u16),(22561u16,8001u16),(22562u16,3358u16),(22563u16,13725u16), (22564u16,7998u16),(22565u16,13729u16),(22566u16,19198u16),(22567u16,13724u16), (22568u16,13726u16),(22569u16,13720u16),(22570u16,7996u16),(22572u16,13739u16), (22573u16,13738u16),(22574u16,13735u16),(22575u16,7995u16),(22576u16,7999u16), (22577u16,8000u16),(22578u16,12571u16),(22579u16,13732u16),(22580u16,7997u16), (22581u16,7525u16),(22582u16,13734u16),(22583u16,13721u16),(22584u16,13737u16), (22585u16,13736u16),(22586u16,3832u16),(22587u16,13740u16),(22589u16,14428u16), (22591u16,13733u16),(22592u16,4014u16),(22596u16,3962u16),(22599u16,2997u16), (22600u16,13728u16),(22601u16,14420u16),(22602u16,8467u16),(22603u16,8470u16), (22604u16,8465u16),(22605u16,14419u16),(22606u16,14423u16),(22607u16,14418u16), (22609u16,8459u16),(22610u16,8469u16),(22611u16,14415u16),(22612u16,8463u16), (22613u16,14422u16),(22615u16,8461u16),(22616u16,8460u16),(22617u16,14425u16), (22618u16,8462u16),(22619u16,14427u16),(22620u16,19200u16),(22621u16,14424u16), (22622u16,8458u16),(22623u16,3893u16),(22626u16,8468u16),(22627u16,14429u16), (22628u16,14417u16),(22629u16,14426u16),(22632u16,14416u16),(22633u16,3740u16), (22635u16,8464u16),(22636u16,2689u16),(22637u16,8466u16),(22639u16,14421u16), (22641u16,14430u16),(22642u16,3356u16),(22643u16,1490u16),(22644u16,15101u16), (22645u16,8902u16),(22646u16,15107u16),(22649u16,8907u16),(22650u16,15103u16), (22651u16,15110u16),(22652u16,15095u16),(22653u16,8909u16),(22654u16,8903u16), (22655u16,15100u16),(22656u16,9284u16),(22657u16,15099u16),(22658u16,15108u16), (22659u16,8904u16),(22661u16,8908u16),(22662u16,15098u16),(22663u16,15104u16), (22664u16,15109u16),(22665u16,15094u16),(22666u16,8906u16),(22667u16,15102u16), (22670u16,15106u16),(22671u16,15112u16),(22672u16,15096u16),(22673u16,15105u16), (22674u16,1782u16),(22675u16,8905u16),(22676u16,15111u16),(22678u16,1020u16), (22680u16,15097u16),(22681u16,1647u16),(22682u16,4644u16),(22684u16,9288u16), (22685u16,15711u16),(22686u16,9286u16),(22687u16,9285u16),(22688u16,15713u16), (22689u16,15718u16),(22691u16,15714u16),(22693u16,15717u16),(22694u16,9291u16), (22695u16,4685u16),(22696u16,9644u16),(22697u16,9290u16),(22698u16,19201u16), (22699u16,15710u16),(22700u16,15716u16),(22702u16,9289u16),(22703u16,15715u16), (22704u16,2168u16),(22705u16,15712u16),(22707u16,9287u16),(22709u16,4143u16), (22710u16,4301u16),(22714u16,16341u16),(22715u16,18959u16),(22716u16,16343u16), (22717u16,16338u16),(22718u16,9672u16),(22719u16,16340u16),(22721u16,9671u16), (22722u16,16342u16),(22725u16,9674u16),(22726u16,16344u16),(22727u16,9673u16), (22728u16,16337u16),(22729u16,16339u16),(22731u16,2805u16),(22734u16,9958u16), (22735u16,16905u16),(22736u16,1783u16),(22737u16,9957u16),(22738u16,16906u16), (22739u16,9956u16),(22740u16,16904u16),(22741u16,9955u16),(22742u16,16903u16), (22744u16,10224u16),(22745u16,10223u16),(22746u16,17732u16),(22747u16,17734u16), (22748u16,19204u16),(22749u16,17733u16),(22750u16,10395u16),(22751u16,10396u16), (22752u16,19203u16),(22754u16,10397u16),(22755u16,18057u16),(22756u16,10546u16), (22759u16,18639u16),(22760u16,18638u16),(22761u16,10820u16),(22763u16,5535u16), (22764u16,5605u16),(22767u16,6035u16),(22768u16,1284u16),(22770u16,3753u16), (22771u16,3441u16),(22772u16,12120u16),(22777u16,8004u16),(22778u16,8005u16), (22779u16,19206u16),(22780u16,14431u16),(22781u16,8910u16),(22782u16,15113u16), (22783u16,15719u16),(22786u16,1665u16),(22787u16,11330u16),(22788u16,1285u16), (22789u16,1380u16),(22790u16,11539u16),(22791u16,1286u16),(22794u16,10937u16), (22796u16,11777u16),(22797u16,12121u16),(22798u16,12585u16),(22799u16,7077u16), (22801u16,19627u16),(22802u16,17735u16),(22804u16,10641u16),(22805u16,5536u16), (22806u16,5714u16),(22807u16,11352u16),(22809u16,5848u16),(22810u16,5849u16), (22812u16,6309u16),(22813u16,982u16),(22815u16,19213u16),(22816u16,7528u16), (22818u16,8912u16),(22820u16,8913u16),(22821u16,8911u16),(22823u16,5537u16), (22825u16,5606u16),(22826u16,5608u16),(22827u16,5607u16),(22828u16,11331u16), (22829u16,5609u16),(22830u16,5715u16),(22831u16,11353u16),(22833u16,5716u16), (22834u16,1287u16),(22836u16,1288u16),(22839u16,5850u16),(22840u16,5851u16), (22844u16,11409u16),(22846u16,6036u16),(22848u16,11540u16),(22852u16,6313u16), (22853u16,11778u16),(22855u16,6311u16),(22856u16,6312u16),(22857u16,6310u16), (22858u16,12586u16),(22862u16,6678u16),(22863u16,6677u16),(22864u16,6679u16), (22865u16,6676u16),(22867u16,12122u16),(22868u16,6314u16),(22869u16,6675u16), (22871u16,7078u16),(22872u16,7079u16),(22874u16,7080u16),(22876u16,13138u16), (22880u16,8006u16),(22881u16,13741u16),(22882u16,7529u16),(22885u16,4189u16), (22887u16,8471u16),(22889u16,8915u16),(22890u16,8914u16),(22891u16,15114u16), (22893u16,9292u16),(22894u16,9675u16),(22896u16,17364u16),(22897u16,18489u16), (22898u16,18640u16),(22899u16,5538u16),(22900u16,5717u16),(22901u16,4509u16), (22902u16,5718u16),(22903u16,11415u16),(22904u16,5853u16),(22905u16,5856u16), (22907u16,11413u16),(22908u16,11411u16),(22909u16,5855u16),(22910u16,11414u16), (22911u16,11416u16),(22912u16,11410u16),(22913u16,5858u16),(22914u16,5857u16), (22915u16,5854u16),(22916u16,5852u16),(22917u16,11412u16),(22921u16,3623u16), (22922u16,6047u16),(22925u16,6044u16),(22926u16,11545u16),(22927u16,11548u16), (22928u16,11547u16),(22930u16,6038u16),(22931u16,6046u16),(22932u16,3472u16), (22934u16,6043u16),(22935u16,11544u16),(22936u16,11542u16),(22937u16,6042u16), (22938u16,3237u16),(22941u16,6037u16),(22942u16,6040u16),(22943u16,4166u16), (22944u16,11543u16),(22945u16,11550u16),(22946u16,11546u16),(22947u16,6041u16), (22948u16,6045u16),(22949u16,6048u16),(22950u16,11541u16),(22951u16,11549u16), (22952u16,6039u16),(22956u16,4012u16),(22958u16,6319u16),(22959u16,6327u16), (22960u16,3535u16),(22961u16,11790u16),(22962u16,11783u16),(22963u16,6328u16), (22964u16,11794u16),(22965u16,11779u16),(22966u16,11786u16),(22967u16,4762u16), (22968u16,2812u16),(22969u16,6318u16),(22970u16,11780u16),(22971u16,6316u16), (22972u16,11787u16),(22973u16,11791u16),(22974u16,6315u16),(22975u16,1879u16), (22976u16,11792u16),(22977u16,11785u16),(22979u16,11788u16),(22980u16,3579u16), (22981u16,6330u16),(22982u16,6321u16),(22983u16,11795u16),(22984u16,11793u16), (22985u16,19222u16),(22986u16,6326u16),(22987u16,6324u16),(22988u16,11784u16), (22989u16,6323u16),(22990u16,11782u16),(22991u16,11781u16),(22992u16,6322u16), (22993u16,6320u16),(22994u16,6329u16),(22995u16,6325u16),(22996u16,6317u16), (22998u16,11789u16),(23000u16,6681u16),(23001u16,19227u16),(23002u16,6688u16), (23003u16,12136u16),(23004u16,6680u16),(23005u16,12128u16),(23006u16,12124u16), (23008u16,12140u16),(23009u16,12123u16),(23011u16,6683u16),(23012u16,12133u16), (23013u16,6686u16),(23014u16,6689u16),(23016u16,6684u16),(23017u16,12137u16), (23018u16,6687u16),(23019u16,3666u16),(23020u16,7087u16),(23021u16,12143u16), (23022u16,12125u16),(23023u16,3631u16),(23024u16,3239u16),(23025u16,12127u16), (23026u16,12134u16),(23027u16,12138u16),(23028u16,12142u16),(23029u16,12139u16), (23030u16,12132u16),(23031u16,12135u16),(23032u16,4417u16),(23033u16,19234u16), (23034u16,12129u16),(23035u16,6691u16),(23036u16,12131u16),(23037u16,12130u16), (23038u16,12141u16),(23039u16,6682u16),(23040u16,12126u16),(23041u16,6690u16), (23042u16,3202u16),(23043u16,6685u16),(23049u16,7093u16),(23050u16,12594u16), (23051u16,3456u16),(23052u16,7092u16),(23053u16,3115u16),(23055u16,12592u16), (23057u16,7081u16),(23058u16,2816u16),(23059u16,7086u16),(23061u16,12591u16), (23062u16,12588u16),(23063u16,12593u16),(23064u16,7082u16),(23065u16,12587u16), (23066u16,1826u16),(23067u16,7085u16),(23068u16,7083u16),(23070u16,12595u16), (23071u16,7084u16),(23072u16,7088u16),(23073u16,2824u16),(23075u16,7089u16), (23076u16,19218u16),(23077u16,7091u16),(23079u16,4256u16),(23081u16,7090u16), (23082u16,3118u16),(23083u16,3639u16),(23084u16,2811u16),(23085u16,12589u16), (23086u16,12590u16),(23091u16,12596u16),(23093u16,13145u16),(23094u16,7530u16), (23095u16,13755u16),(23096u16,13144u16),(23097u16,13163u16),(23100u16,7536u16), (23101u16,2995u16),(23102u16,13161u16),(23104u16,7535u16),(23105u16,7531u16), (23106u16,13170u16),(23107u16,13154u16),(23108u16,13157u16),(23109u16,2555u16), (23110u16,7539u16),(23111u16,13167u16),(23112u16,13159u16),(23113u16,7532u16), (23114u16,7540u16),(23116u16,13164u16),(23117u16,13162u16),(23120u16,13147u16), (23121u16,13168u16),(23122u16,13156u16),(23123u16,13151u16),(23124u16,1626u16), (23125u16,13141u16),(23126u16,13169u16),(23127u16,13153u16),(23128u16,13140u16), (23129u16,3111u16),(23130u16,7538u16),(23131u16,13158u16),(23132u16,13171u16), (23133u16,13155u16),(23134u16,13143u16),(23135u16,13148u16),(23136u16,13139u16), (23137u16,3626u16),(23138u16,7537u16),(23139u16,19237u16),(23140u16,13152u16), (23141u16,13149u16),(23142u16,7533u16),(23143u16,4349u16),(23144u16,2718u16), (23145u16,13166u16),(23146u16,7534u16),(23147u16,2863u16),(23148u16,13150u16), (23149u16,13146u16),(23150u16,3638u16),(23152u16,13165u16),(23153u16,3627u16), (23159u16,8007u16),(23160u16,13748u16),(23161u16,3544u16),(23162u16,13745u16), (23163u16,13762u16),(23164u16,13750u16),(23165u16,13763u16),(23166u16,2814u16), (23167u16,8009u16),(23169u16,2826u16),(23170u16,3624u16),(23171u16,13759u16), (23172u16,13756u16),(23174u16,3190u16),(23176u16,19609u16),(23178u16,13757u16), (23179u16,13760u16),(23180u16,13764u16),(23182u16,13160u16),(23183u16,13766u16), (23184u16,14451u16),(23185u16,19563u16),(23186u16,8010u16),(23187u16,13767u16), (23188u16,13743u16),(23189u16,13753u16),(23190u16,19242u16),(23191u16,13758u16), (23193u16,2806u16),(23194u16,8008u16),(23195u16,8011u16),(23196u16,13765u16), (23197u16,13768u16),(23198u16,13747u16),(23199u16,13744u16),(23200u16,19362u16), (23201u16,3539u16),(23202u16,13746u16),(23204u16,989u16),(23205u16,13751u16), (23206u16,13749u16),(23207u16,8012u16),(23209u16,13761u16),(23211u16,19236u16), (23212u16,13752u16),(23214u16,13754u16),(23215u16,13742u16),(23216u16,14439u16), (23217u16,14437u16),(23218u16,8480u16),(23219u16,8478u16),(23220u16,14447u16), (23221u16,14438u16),(23222u16,14448u16),(23223u16,14444u16),(23224u16,14436u16), (23225u16,14450u16),(23226u16,14435u16),(23227u16,14442u16),(23228u16,8477u16), (23229u16,8476u16),(23230u16,8475u16),(23231u16,14440u16),(23232u16,14445u16), (23233u16,8472u16),(23234u16,8479u16),(23235u16,2424u16),(23236u16,14433u16), (23238u16,14443u16),(23239u16,14432u16),(23240u16,14441u16),(23241u16,8473u16), (23242u16,14446u16),(23243u16,14434u16),(23244u16,8474u16),(23245u16,14449u16), (23246u16,3455u16),(23247u16,2815u16),(23249u16,992u16),(23251u16,19244u16), (23253u16,15118u16),(23254u16,8920u16),(23255u16,8919u16),(23256u16,8921u16), (23257u16,15130u16),(23258u16,15120u16),(23259u16,15126u16),(23260u16,15115u16), (23261u16,15129u16),(23262u16,15128u16),(23263u16,15132u16),(23264u16,15125u16), (23265u16,8916u16),(23266u16,15124u16),(23267u16,8922u16),(23268u16,3195u16), (23269u16,15117u16),(23270u16,8917u16),(23272u16,15131u16),(23273u16,8918u16), (23274u16,15119u16),(23275u16,15122u16),(23276u16,15127u16),(23277u16,15121u16), (23278u16,15116u16),(23280u16,4681u16),(23282u16,2254u16),(23283u16,15123u16), (23284u16,15721u16),(23285u16,9296u16),(23286u16,15724u16),(23287u16,15723u16), (23288u16,15726u16),(23289u16,15728u16),(23290u16,18962u16),(23291u16,9294u16), (23293u16,15722u16),(23294u16,3347u16),(23295u16,15720u16),(23297u16,15729u16), (23298u16,15727u16),(23299u16,15725u16),(23301u16,15731u16),(23303u16,15730u16), (23304u16,9298u16),(23305u16,9293u16),(23307u16,9295u16),(23308u16,9297u16), (23309u16,4636u16),(23311u16,15732u16),(23312u16,16351u16),(23313u16,3308u16), (23315u16,16350u16),(23316u16,16349u16),(23317u16,1801u16),(23318u16,16352u16), (23319u16,16345u16),(23321u16,16346u16),(23322u16,16354u16),(23323u16,16347u16), (23325u16,9676u16),(23326u16,16356u16),(23327u16,5019u16),(23328u16,16355u16), (23329u16,16348u16),(23331u16,16910u16),(23332u16,9961u16),(23333u16,16908u16), (23334u16,16913u16),(23335u16,16912u16),(23336u16,3451u16),(23338u16,9960u16), (23339u16,3193u16),(23340u16,16911u16),(23341u16,16907u16),(23342u16,16915u16), (23343u16,16914u16),(23344u16,9959u16),(23346u16,16909u16),(23348u16,9677u16), (23352u16,10225u16),(23356u16,17365u16),(23357u16,17736u16),(23358u16,17737u16), (23359u16,17738u16),(23360u16,10547u16),(23361u16,2475u16),(23363u16,10548u16), (23364u16,2865u16),(23365u16,18058u16),(23366u16,19691u16),(23367u16,18314u16), (23368u16,18313u16),(23370u16,2480u16),(23371u16,18490u16),(23372u16,18491u16), (23373u16,18641u16),(23374u16,18752u16),(23375u16,2846u16),(23376u16,5539u16), (23377u16,5540u16),(23379u16,5541u16),(23380u16,5610u16),(23381u16,5719u16), (23382u16,11417u16),(23383u16,5859u16),(23384u16,5860u16),(23386u16,6051u16), (23387u16,6052u16),(23388u16,6050u16),(23389u16,6049u16),(23391u16,6331u16), (23394u16,11796u16),(23395u16,6333u16),(23396u16,6332u16),(23397u16,11797u16), (23398u16,1289u16),(23400u16,1652u16),(23401u16,6692u16),(23403u16,7094u16), (23404u16,12597u16),(23405u16,4490u16),(23406u16,13173u16),(23408u16,7541u16), (23409u16,8014u16),(23410u16,13172u16),(23411u16,8013u16),(23412u16,2049u16), (23413u16,8923u16),(23414u16,19253u16),(23415u16,15133u16),(23416u16,9678u16), (23418u16,9962u16),(23419u16,16916u16),(23420u16,19255u16),(23421u16,10549u16), (23423u16,10724u16),(23424u16,10938u16),(23425u16,11354u16),(23426u16,19054u16), (23427u16,5720u16),(23428u16,11355u16),(23429u16,5863u16),(23431u16,5861u16), (23432u16,5862u16),(23433u16,5864u16),(23435u16,6054u16),(23436u16,6053u16), (23438u16,11551u16),(23439u16,6055u16),(23440u16,4592u16),(23442u16,11552u16), (23443u16,11798u16),(23445u16,11799u16),(23446u16,1846u16),(23447u16,6334u16), (23448u16,6336u16),(23449u16,6338u16),(23450u16,6335u16),(23451u16,6339u16), (23452u16,6337u16),(23453u16,19266u16),(23454u16,1290u16),(23455u16,1291u16), (23458u16,6696u16),(23459u16,6693u16),(23460u16,6695u16),(23461u16,6697u16), (23462u16,6694u16),(23463u16,12598u16),(23464u16,12144u16),(23466u16,19372u16), (23468u16,12600u16),(23469u16,12599u16),(23470u16,7100u16),(23472u16,7096u16), (23475u16,7097u16),(23476u16,7099u16),(23477u16,7101u16),(23478u16,7098u16), (23479u16,993u16),(23480u16,7103u16),(23481u16,7102u16),(23487u16,7546u16), (23488u16,13175u16),(23489u16,13174u16),(23490u16,7545u16),(23491u16,4753u16), (23492u16,7544u16),(23493u16,7543u16),(23494u16,7547u16),(23495u16,7542u16), (23498u16,13774u16),(23499u16,13771u16),(23500u16,8016u16),(23501u16,13770u16), (23502u16,13775u16),(23504u16,8018u16),(23505u16,13773u16),(23506u16,8015u16), (23507u16,8017u16),(23508u16,13772u16),(23509u16,19260u16),(23510u16,14452u16), (23511u16,19701u16),(23512u16,14453u16),(23513u16,14454u16),(23515u16,987u16), (23518u16,8924u16),(23519u16,8932u16),(23520u16,15134u16),(23521u16,8926u16), (23522u16,8930u16),(23523u16,15135u16),(23524u16,8931u16),(23525u16,8927u16), (23526u16,8928u16),(23527u16,8925u16),(23528u16,8929u16),(23529u16,9301u16), (23530u16,13769u16),(23531u16,9302u16),(23532u16,9300u16),(23534u16,9299u16), (23535u16,16357u16),(23536u16,9679u16),(23537u16,16917u16),(23538u16,16918u16), (23539u16,19265u16),(23541u16,10398u16),(23542u16,10550u16),(23544u16,5542u16), (23546u16,5865u16),(23551u16,19207u16),(23553u16,6698u16),(23555u16,12601u16), (23556u16,7104u16),(23557u16,19268u16),(23559u16,7550u16),(23560u16,7549u16), (23561u16,7548u16),(23562u16,8019u16),(23563u16,8020u16),(23564u16,13776u16), (23565u16,8933u16),(23566u16,9680u16),(23567u16,5543u16),(23568u16,4329u16), (23569u16,5611u16),(23570u16,11356u16),(23571u16,19270u16),(23572u16,19272u16), (23573u16,11418u16),(23574u16,5866u16),(23578u16,6340u16),(23580u16,1599u16), (23582u16,2838u16),(23583u16,14455u16),(23584u16,4053u16),(23586u16,5544u16), (23587u16,1673u16),(23588u16,5612u16),(23589u16,11419u16),(23592u16,11553u16), (23594u16,11554u16),(23596u16,6056u16),(23600u16,13777u16),(23601u16,8021u16), (23603u16,14456u16),(23607u16,9963u16),(23608u16,5545u16),(23609u16,5565u16), (23610u16,5613u16),(23611u16,11357u16),(23612u16,5721u16),(23614u16,6060u16), (23615u16,6059u16),(23616u16,6057u16),(23617u16,6058u16),(23620u16,11800u16), (23621u16,6342u16),(23622u16,6343u16),(23623u16,11801u16),(23624u16,6341u16), (23625u16,19275u16),(23626u16,4813u16),(23627u16,6702u16),(23628u16,12145u16), (23629u16,6701u16),(23630u16,6699u16),(23631u16,6700u16),(23632u16,7107u16), (23633u16,7105u16),(23635u16,4714u16),(23636u16,12603u16),(23637u16,7106u16), (23638u16,12602u16),(23640u16,7095u16),(23641u16,13176u16),(23644u16,7552u16), (23645u16,7553u16),(23646u16,3750u16),(23648u16,7551u16),(23650u16,8934u16), (23651u16,15136u16),(23652u16,9303u16),(23653u16,9304u16),(23655u16,15733u16), (23656u16,9964u16),(23657u16,17366u16),(23658u16,17367u16),(23660u16,10642u16), (23661u16,18753u16),(23662u16,11315u16),(23663u16,5614u16),(23665u16,5546u16), (23667u16,11359u16),(23668u16,11358u16),(23672u16,1862u16),(23673u16,5867u16), (23674u16,11421u16),(23675u16,11422u16),(23676u16,11420u16),(23678u16,11423u16), (23685u16,19277u16),(23686u16,11562u16),(23688u16,11557u16),(23689u16,11559u16), (23690u16,11561u16),(23691u16,11558u16),(23692u16,6064u16),(23693u16,11555u16), (23695u16,11556u16),(23696u16,6061u16),(23697u16,6062u16),(23698u16,11560u16), (23699u16,11563u16),(23700u16,6063u16),(23701u16,11564u16),(23705u16,2028u16), (23706u16,1292u16),(23708u16,19612u16),(23709u16,11815u16),(23710u16,2839u16), (23711u16,11809u16),(23712u16,11804u16),(23713u16,6345u16),(23714u16,11812u16), (23715u16,11810u16),(23716u16,11803u16),(23717u16,11816u16),(23718u16,11819u16), (23719u16,11814u16),(23720u16,11807u16),(23721u16,6347u16),(23722u16,11813u16), (23723u16,6348u16),(23724u16,11808u16),(23725u16,11811u16),(23726u16,11802u16), (23727u16,11806u16),(23728u16,11818u16),(23729u16,6349u16),(23731u16,6350u16), (23733u16,11805u16),(23734u16,11817u16),(23735u16,6344u16),(23736u16,6346u16), (23738u16,19287u16),(23745u16,5011u16),(23746u16,3651u16),(23750u16,12162u16), (23751u16,12155u16),(23752u16,12161u16),(23753u16,12154u16),(23754u16,12156u16), (23755u16,12150u16),(23756u16,12148u16),(23758u16,12163u16),(23759u16,12160u16), (23760u16,12146u16),(23761u16,4734u16),(23762u16,6704u16),(23763u16,12158u16), (23764u16,12159u16),(23765u16,1859u16),(23766u16,12157u16),(23767u16,12149u16), (23768u16,12147u16),(23769u16,6703u16),(23770u16,12153u16),(23771u16,12151u16), (23774u16,12152u16),(23775u16,12164u16),(23781u16,1935u16),(23784u16,7112u16), (23785u16,19278u16),(23786u16,7111u16),(23788u16,12604u16),(23789u16,7108u16), (23790u16,12606u16),(23791u16,19279u16),(23792u16,7113u16),(23793u16,12607u16), (23796u16,7116u16),(23797u16,1735u16),(23798u16,7114u16),(23799u16,12608u16), (23800u16,12165u16),(23801u16,12610u16),(23803u16,7110u16),(23804u16,994u16), (23805u16,7109u16),(23807u16,12605u16),(23808u16,12609u16),(23809u16,7115u16), (23814u16,7555u16),(23815u16,7554u16),(23819u16,13178u16),(23820u16,13182u16), (23821u16,13184u16),(23822u16,7556u16),(23823u16,13187u16),(23824u16,19283u16), (23825u16,7560u16),(23826u16,13189u16),(23828u16,7562u16),(23829u16,1954u16), (23830u16,7558u16),(23831u16,7566u16),(23832u16,19284u16),(23833u16,7563u16), (23834u16,13180u16),(23835u16,7557u16),(23837u16,13179u16),(23838u16,13177u16), (23839u16,13191u16),(23840u16,13181u16),(23842u16,7559u16),(23843u16,13190u16), (23844u16,7564u16),(23845u16,13186u16),(23846u16,13185u16),(23847u16,7565u16), (23848u16,13183u16),(23849u16,7561u16),(23852u16,4292u16),(23854u16,13192u16), (23855u16,3667u16),(23856u16,13188u16),(23857u16,13792u16),(23858u16,13799u16), (23859u16,13788u16),(23860u16,8024u16),(23861u16,13784u16),(23862u16,13800u16), (23863u16,13778u16),(23864u16,13797u16),(23865u16,13795u16),(23866u16,13789u16), (23868u16,13798u16),(23869u16,13791u16),(23870u16,1916u16),(23871u16,13783u16), (23872u16,13801u16),(23873u16,13781u16),(23874u16,13794u16),(23875u16,13779u16), (23877u16,13802u16),(23878u16,19285u16),(23879u16,8025u16),(23880u16,1917u16), (23881u16,13796u16),(23882u16,14459u16),(23883u16,13782u16),(23884u16,8022u16), (23886u16,13786u16),(23888u16,8023u16),(23889u16,13785u16),(23890u16,13790u16), (23893u16,13787u16),(23894u16,1918u16),(23895u16,4930u16),(23897u16,13793u16), (23899u16,4239u16),(23902u16,14463u16),(23906u16,14466u16),(23907u16,14458u16), (23909u16,14460u16),(23911u16,14465u16),(23912u16,14464u16),(23913u16,8481u16), (23915u16,13780u16),(23916u16,14462u16),(23919u16,8482u16),(23920u16,3686u16), (23921u16,14457u16),(23922u16,14461u16),(23924u16,4689u16),(23927u16,15143u16), (23928u16,1865u16),(23929u16,15150u16),(23930u16,15141u16),(23931u16,1841u16), (23932u16,15148u16),(23933u16,15139u16),(23934u16,15147u16),(23935u16,15151u16), (23936u16,15138u16),(23937u16,15142u16),(23938u16,15137u16),(23940u16,8935u16), (23941u16,4376u16),(23942u16,15140u16),(23943u16,8936u16),(23944u16,15146u16), (23945u16,15145u16),(23946u16,15144u16),(23947u16,19280u16),(23949u16,15149u16), (23950u16,4727u16),(23954u16,15737u16),(23955u16,15739u16),(23956u16,9306u16), (23957u16,15740u16),(23959u16,15735u16),(23961u16,15734u16),(23962u16,15744u16), (23964u16,15742u16),(23965u16,9305u16),(23966u16,15745u16),(23967u16,15736u16), (23968u16,15741u16),(23969u16,15743u16),(23970u16,15738u16),(23972u16,1921u16), (23975u16,16361u16),(23976u16,16366u16),(23977u16,16360u16),(23978u16,16365u16), (23979u16,4382u16),(23980u16,16358u16),(23981u16,16368u16),(23982u16,16364u16), (23983u16,16369u16),(23984u16,16363u16),(23985u16,16359u16),(23986u16,16367u16), (23988u16,16370u16),(23989u16,16362u16),(23990u16,19335u16),(23991u16,16919u16), (23992u16,9968u16),(23993u16,1922u16),(23994u16,9966u16),(23996u16,9965u16), (23997u16,9967u16),(24000u16,17368u16),(24001u16,3317u16),(24002u16,17634u16), (24003u16,17739u16),(24006u16,18059u16),(24007u16,18060u16),(24009u16,10551u16), (24011u16,18315u16),(24013u16,10643u16),(24015u16,18316u16),(24017u16,18493u16), (24018u16,10726u16),(24020u16,10725u16),(24021u16,18492u16),(24022u16,10779u16), (24023u16,19288u16),(24024u16,18642u16),(24027u16,10939u16),(24029u16,5547u16), (24030u16,5868u16),(24031u16,11424u16),(24032u16,11565u16),(24033u16,6206u16), (24034u16,7567u16),(24037u16,5548u16),(24038u16,5724u16),(24039u16,5723u16), (24040u16,5722u16),(24043u16,6065u16),(24046u16,7117u16),(24048u16,14467u16), (24049u16,5549u16),(24050u16,5550u16),(24051u16,5551u16),(24052u16,5615u16), (24053u16,4818u16),(24055u16,6705u16),(24057u16,12166u16),(24061u16,8026u16), (24062u16,5552u16),(24063u16,11333u16),(24066u16,5725u16),(24067u16,5726u16), (24068u16,11360u16),(24070u16,5869u16),(24073u16,19308u16),(24074u16,11566u16), (24075u16,4055u16),(24076u16,6066u16),(24078u16,11567u16),(24081u16,6356u16), (24082u16,4763u16),(24084u16,11821u16),(24085u16,6354u16),(24086u16,6353u16), (24087u16,11820u16),(24088u16,6351u16),(24089u16,11822u16),(24090u16,6352u16), (24091u16,6355u16),(24093u16,6706u16),(24095u16,6708u16),(24096u16,12170u16), (24097u16,12167u16),(24098u16,12168u16),(24099u16,12169u16),(24100u16,12171u16), (24101u16,6707u16),(24104u16,12612u16),(24105u16,12611u16),(24107u16,7119u16), (24109u16,7118u16),(24110u16,19297u16),(24115u16,7570u16),(24116u16,13194u16), (24118u16,7569u16),(24119u16,7571u16),(24120u16,7568u16),(24125u16,8028u16), (24126u16,13193u16),(24128u16,8029u16),(24129u16,13804u16),(24130u16,1925u16), (24131u16,8030u16),(24132u16,13803u16),(24133u16,8027u16),(24136u16,2841u16), (24138u16,14470u16),(24139u16,14472u16),(24140u16,8483u16),(24141u16,14471u16), (24142u16,14469u16),(24143u16,14468u16),(24147u16,15154u16),(24148u16,8941u16), (24149u16,8939u16),(24151u16,8940u16),(24152u16,15152u16),(24153u16,15153u16), (24155u16,8937u16),(24156u16,15749u16),(24157u16,15747u16),(24158u16,2840u16), (24159u16,9308u16),(24160u16,15748u16),(24161u16,9309u16),(24162u16,9307u16), (24163u16,8938u16),(24166u16,16373u16),(24167u16,16371u16),(24168u16,16372u16), (24169u16,15746u16),(24170u16,16921u16),(24171u16,9969u16),(24172u16,16920u16), (24173u16,17369u16),(24174u16,17370u16),(24175u16,16374u16),(24176u16,17740u16), (24178u16,5553u16),(24179u16,5727u16),(24180u16,5871u16),(24181u16,11425u16), (24182u16,5870u16),(24184u16,6357u16),(24185u16,8484u16),(24186u16,19300u16), (24187u16,5616u16),(24188u16,5728u16),(24189u16,6709u16),(24190u16,8031u16), (24191u16,10941u16),(24192u16,11361u16),(24194u16,11362u16),(24195u16,19251u16), (24196u16,11426u16),(24198u16,1293u16),(24199u16,6068u16),(24200u16,11571u16), (24201u16,11569u16),(24202u16,6069u16),(24203u16,11568u16),(24204u16,11570u16), (24205u16,11572u16),(24207u16,6067u16),(24210u16,1785u16),(24213u16,6361u16), (24214u16,6362u16),(24215u16,6359u16),(24217u16,1786u16),(24218u16,6358u16), (24219u16,12175u16),(24220u16,6360u16),(24224u16,6710u16),(24226u16,12174u16), (24227u16,12176u16),(24228u16,12173u16),(24229u16,12177u16),(24230u16,6711u16), (24231u16,7122u16),(24232u16,12613u16),(24234u16,12615u16),(24235u16,7120u16), (24236u16,12616u16),(24237u16,7121u16),(24238u16,12614u16),(24240u16,12172u16), (24241u16,13195u16),(24242u16,13198u16),(24243u16,13199u16),(24244u16,13196u16), (24245u16,7575u16),(24246u16,7574u16),(24247u16,7572u16),(24248u16,7573u16), (24249u16,13197u16),(24253u16,1926u16),(24254u16,7576u16),(24257u16,8033u16), (24258u16,8034u16),(24260u16,8035u16),(24261u16,14473u16),(24262u16,14475u16), (24263u16,14477u16),(24264u16,8486u16),(24265u16,8485u16),(24266u16,8032u16), (24267u16,14476u16),(24268u16,14474u16),(24269u16,2845u16),(24270u16,15158u16), (24272u16,4549u16),(24273u16,15156u16),(24274u16,15162u16),(24275u16,8942u16), (24276u16,15163u16),(24277u16,15160u16),(24278u16,8943u16),(24279u16,15157u16), (24280u16,15155u16),(24281u16,15161u16),(24282u16,9311u16),(24283u16,15751u16), (24284u16,15159u16),(24285u16,9313u16),(24286u16,15752u16),(24287u16,9312u16), (24288u16,9315u16),(24289u16,15753u16),(24290u16,9310u16),(24291u16,9314u16), (24293u16,16379u16),(24294u16,16377u16),(24295u16,16376u16),(24296u16,16378u16), (24297u16,16375u16),(24300u16,10400u16),(24302u16,18061u16),(24303u16,18062u16), (24305u16,18317u16),(24306u16,18494u16),(24307u16,10854u16),(24308u16,10942u16), (24310u16,6363u16),(24311u16,6070u16),(24312u16,2380u16),(24313u16,19311u16), (24314u16,6712u16),(24315u16,19312u16),(24316u16,19314u16),(24318u16,5554u16), (24319u16,5617u16),(24321u16,5729u16),(24322u16,11427u16),(24324u16,6071u16), (24325u16,11573u16),(24327u16,12178u16),(24328u16,6713u16),(24330u16,8944u16), (24331u16,5555u16),(24332u16,2859u16),(24333u16,19317u16),(24334u16,2860u16), (24335u16,5872u16),(24338u16,8487u16),(24339u16,5556u16),(24340u16,5618u16), (24341u16,5619u16),(24343u16,5731u16),(24344u16,5730u16),(24346u16,11428u16), (24347u16,5873u16),(24349u16,11574u16),(24351u16,6072u16),(24354u16,11824u16), (24355u16,11825u16),(24356u16,11826u16),(24357u16,1927u16),(24358u16,6364u16), (24359u16,6365u16),(24360u16,11823u16),(24361u16,6366u16),(24365u16,6714u16), (24366u16,12179u16),(24368u16,12618u16),(24369u16,7123u16),(24371u16,12617u16), (24373u16,7577u16),(24374u16,13200u16),(24375u16,7578u16),(24376u16,13201u16), (24378u16,19323u16),(24379u16,1883u16),(24380u16,8036u16),(24384u16,14478u16), (24387u16,15165u16),(24388u16,15164u16),(24390u16,8945u16),(24392u16,9316u16), (24393u16,15754u16),(24394u16,9681u16),(24395u16,16380u16),(24396u16,9970u16), (24397u16,3226u16),(24398u16,10727u16),(24399u16,18644u16),(24400u16,10943u16), (24401u16,1674u16),(24404u16,11827u16),(24406u16,12180u16),(24407u16,7579u16), (24408u16,13805u16),(24409u16,8488u16),(24412u16,3669u16),(24413u16,10226u16), (24417u16,10944u16),(24418u16,6074u16),(24419u16,19328u16),(24420u16,6073u16), (24421u16,6715u16),(24423u16,12619u16),(24425u16,7581u16),(24426u16,7853u16), (24427u16,7582u16),(24428u16,7580u16),(24429u16,8037u16),(24431u16,15166u16), (24432u16,8946u16),(24433u16,9317u16),(24434u16,19331u16),(24435u16,11316u16), (24436u16,11429u16),(24438u16,11576u16),(24439u16,6075u16),(24440u16,11575u16), (24441u16,6076u16),(24443u16,19074u16),(24444u16,6370u16),(24445u16,11830u16), (24446u16,11829u16),(24447u16,6369u16),(24448u16,6367u16),(24449u16,6368u16), (24450u16,11828u16),(24451u16,1928u16),(24453u16,6717u16),(24454u16,12181u16), (24455u16,6720u16),(24456u16,6716u16),(24457u16,6722u16),(24458u16,6718u16), (24459u16,6719u16),(24460u16,6721u16),(24464u16,7126u16),(24465u16,7125u16), (24466u16,7124u16),(24470u16,13203u16),(24471u16,7583u16),(24472u16,7586u16), (24473u16,7584u16),(24475u16,13202u16),(24476u16,7589u16),(24478u16,7585u16), (24479u16,13204u16),(24480u16,7588u16),(24481u16,7587u16),(24484u16,19030u16), (24485u16,13807u16),(24486u16,13806u16),(24487u16,19334u16),(24488u16,8040u16), (24489u16,8038u16),(24490u16,8039u16),(24491u16,13808u16),(24492u16,8489u16), (24493u16,14480u16),(24494u16,8490u16),(24495u16,14479u16),(24497u16,4130u16), (24498u16,15755u16),(24501u16,9319u16),(24502u16,15167u16),(24503u16,9318u16), (24505u16,8947u16),(24506u16,4884u16),(24507u16,16923u16),(24508u16,16381u16), (24509u16,9971u16),(24510u16,16922u16),(24511u16,17741u16),(24512u16,18063u16), (24513u16,18064u16),(24514u16,1787u16),(24515u16,5620u16),(24516u16,1675u16), (24517u16,5732u16),(24521u16,11363u16),(24524u16,6078u16),(24525u16,6080u16), (24527u16,11432u16),(24528u16,11579u16),(24529u16,11578u16),(24530u16,11577u16), (24532u16,11431u16),(24533u16,11430u16),(24534u16,5875u16),(24535u16,6079u16), (24536u16,6077u16),(24537u16,5874u16),(24539u16,2872u16),(24541u16,6371u16), (24542u16,11831u16),(24543u16,19426u16),(24544u16,6372u16),(24545u16,11584u16), (24547u16,11586u16),(24548u16,11585u16),(24549u16,11832u16),(24552u16,11581u16), (24554u16,6084u16),(24555u16,6082u16),(24557u16,11580u16),(24558u16,11582u16), (24559u16,11588u16),(24561u16,6081u16),(24563u16,11583u16),(24564u16,11592u16), (24565u16,6374u16),(24567u16,11589u16),(24568u16,6083u16),(24570u16,11587u16), (24571u16,11590u16),(24573u16,6373u16),(24575u16,6375u16),(24576u16,11591u16), (24585u16,11852u16),(24586u16,11839u16),(24587u16,11837u16),(24588u16,11851u16), (24589u16,11846u16),(24590u16,6727u16),(24591u16,6376u16),(24592u16,11847u16), (24593u16,11850u16),(24594u16,6723u16),(24595u16,11849u16),(24596u16,6377u16), (24597u16,6382u16),(24598u16,6380u16),(24599u16,11840u16),(24601u16,11835u16), (24602u16,11842u16),(24603u16,6387u16),(24604u16,11853u16),(24605u16,6724u16), (24606u16,11843u16),(24608u16,6725u16),(24609u16,6383u16),(24610u16,11845u16), (24611u16,19382u16),(24612u16,12196u16),(24613u16,6726u16),(24614u16,11834u16), (24615u16,6384u16),(24616u16,6728u16),(24617u16,6385u16),(24618u16,6381u16), (24619u16,6386u16),(24620u16,11844u16),(24621u16,11833u16),(24622u16,11848u16), (24623u16,6378u16),(24625u16,19344u16),(24626u16,11836u16),(24627u16,11841u16), (24628u16,11838u16),(24629u16,6379u16),(24631u16,12182u16),(24633u16,12183u16), (24635u16,1294u16),(24640u16,12193u16),(24641u16,12623u16),(24642u16,12194u16), (24643u16,6734u16),(24644u16,12197u16),(24645u16,12187u16),(24646u16,6733u16), (24647u16,12189u16),(24649u16,12190u16),(24650u16,19102u16),(24652u16,12192u16), (24653u16,6729u16),(24656u16,7130u16),(24658u16,18960u16),(24659u16,12188u16), (24660u16,12184u16),(24661u16,7131u16),(24664u16,12198u16),(24665u16,7127u16), (24666u16,12621u16),(24667u16,12191u16),(24669u16,12620u16),(24670u16,12186u16), (24671u16,12195u16),(24674u16,4624u16),(24675u16,7128u16),(24676u16,6738u16), (24677u16,7129u16),(24678u16,12199u16),(24679u16,12622u16),(24680u16,6731u16), (24681u16,7133u16),(24682u16,6737u16),(24683u16,6736u16),(24684u16,6735u16), (24685u16,7132u16),(24686u16,12200u16),(24687u16,7134u16),(24688u16,6730u16), (24690u16,12185u16),(24693u16,2884u16),(24695u16,4993u16),(24702u16,2869u16), (24703u16,7590u16),(24704u16,12626u16),(24705u16,12628u16),(24707u16,12630u16), (24708u16,7135u16),(24709u16,7141u16),(24710u16,13207u16),(24711u16,12634u16), (24712u16,12625u16),(24713u16,7592u16),(24714u16,13205u16),(24716u16,7140u16), (24717u16,7138u16),(24718u16,12636u16),(24720u16,13206u16),(24722u16,12627u16), (24724u16,7139u16),(24725u16,12631u16),(24726u16,7142u16),(24727u16,12633u16), (24730u16,7137u16),(24731u16,12632u16),(24732u16,12635u16),(24733u16,12629u16), (24734u16,19354u16),(24735u16,7136u16),(24736u16,7593u16),(24738u16,12624u16), (24739u16,7591u16),(24740u16,4989u16),(24743u16,3023u16),(24744u16,7594u16), (24752u16,13209u16),(24753u16,13218u16),(24754u16,8043u16),(24755u16,19356u16), (24756u16,7596u16),(24757u16,7601u16),(24758u16,8044u16),(24759u16,13220u16), (24760u16,7608u16),(24761u16,13810u16),(24762u16,13210u16),(24763u16,7600u16), (24764u16,7603u16),(24765u16,7598u16),(24766u16,13208u16),(24767u16,13222u16), (24768u16,13225u16),(24769u16,13825u16),(24771u16,13223u16),(24772u16,13814u16), (24773u16,7599u16),(24774u16,7606u16),(24775u16,7610u16),(24776u16,13217u16), (24777u16,13809u16),(24778u16,13221u16),(24779u16,7595u16),(24780u16,13811u16), (24781u16,13224u16),(24782u16,13813u16),(24783u16,13213u16),(24785u16,8041u16), (24787u16,13211u16),(24788u16,13212u16),(24789u16,7605u16),(24791u16,1933u16), (24792u16,7604u16),(24793u16,13215u16),(24794u16,7609u16),(24795u16,13219u16), (24796u16,7602u16),(24797u16,13216u16),(24798u16,4220u16),(24799u16,7607u16), (24800u16,8045u16),(24801u16,8042u16),(24802u16,13812u16),(24803u16,3856u16), (24804u16,13214u16),(24806u16,7597u16),(24807u16,4035u16),(24808u16,3958u16), (24809u16,4998u16),(24816u16,8050u16),(24817u16,8054u16),(24818u16,13816u16), (24819u16,8495u16),(24820u16,8052u16),(24821u16,13820u16),(24822u16,8056u16), (24823u16,14481u16),(24824u16,13822u16),(24825u16,8497u16),(24826u16,8048u16), (24827u16,8051u16),(24828u16,13823u16),(24829u16,4894u16),(24830u16,13824u16), (24831u16,13830u16),(24832u16,8058u16),(24833u16,8498u16),(24835u16,13826u16), (24836u16,13831u16),(24837u16,13819u16),(24838u16,8508u16),(24839u16,3371u16), (24840u16,8499u16),(24841u16,8057u16),(24842u16,13817u16),(24843u16,13832u16), (24844u16,3454u16),(24845u16,8507u16),(24846u16,8055u16),(24847u16,8492u16), (24848u16,13829u16),(24850u16,8059u16),(24851u16,13821u16),(24852u16,13815u16), (24853u16,8049u16),(24854u16,13818u16),(24856u16,13827u16),(24857u16,4696u16), (24858u16,8491u16),(24859u16,8496u16),(24860u16,8046u16),(24861u16,13828u16), (24863u16,8494u16),(24866u16,1740u16),(24867u16,8047u16),(24871u16,8506u16), (24872u16,15169u16),(24873u16,14492u16),(24875u16,14484u16),(24876u16,15168u16), (24878u16,14488u16),(24879u16,14490u16),(24880u16,4772u16),(24882u16,14487u16), (24884u16,8505u16),(24886u16,14486u16),(24887u16,8509u16),(24891u16,15184u16), (24893u16,1934u16),(24894u16,8504u16),(24895u16,8949u16),(24896u16,14493u16), (24897u16,15170u16),(24898u16,19365u16),(24900u16,8502u16),(24901u16,14485u16), (24902u16,14489u16),(24903u16,8948u16),(24904u16,8493u16),(24905u16,14482u16), (24906u16,14483u16),(24907u16,8950u16),(24908u16,8501u16),(24909u16,8503u16), (24910u16,8500u16),(24911u16,14491u16),(24912u16,3368u16),(24914u16,15174u16), (24915u16,15175u16),(24916u16,15180u16),(24917u16,9324u16),(24918u16,15187u16), (24920u16,8956u16),(24921u16,4913u16),(24922u16,8955u16),(24923u16,15182u16), (24924u16,19383u16),(24925u16,9323u16),(24926u16,15171u16),(24927u16,8954u16), (24928u16,19261u16),(24929u16,15186u16),(24930u16,8952u16),(24931u16,8953u16), (24932u16,19363u16),(24933u16,15183u16),(24934u16,15772u16),(24935u16,9321u16), (24936u16,8053u16),(24938u16,15185u16),(24939u16,9328u16),(24940u16,15177u16), (24942u16,9322u16),(24943u16,4919u16),(24944u16,9327u16),(24945u16,15172u16), (24946u16,15176u16),(24947u16,15173u16),(24948u16,15179u16),(24949u16,8957u16), (24950u16,9320u16),(24951u16,8951u16),(24953u16,15758u16),(24954u16,15181u16), (24956u16,9326u16),(24957u16,4916u16),(24958u16,9329u16),(24960u16,15178u16), (24961u16,19368u16),(24962u16,9325u16),(24963u16,15757u16),(24967u16,19371u16), (24969u16,15762u16),(24970u16,9685u16),(24971u16,15756u16),(24972u16,16393u16), (24973u16,15771u16),(24974u16,9333u16),(24976u16,9331u16),(24977u16,9683u16), (24978u16,15768u16),(24979u16,15764u16),(24980u16,9337u16),(24981u16,4255u16), (24982u16,16384u16),(24984u16,2883u16),(24985u16,2882u16),(24986u16,9335u16), (24987u16,15763u16),(24988u16,4990u16),(24989u16,16382u16),(24991u16,15767u16), (24993u16,15770u16),(24994u16,15761u16),(24996u16,9336u16),(24999u16,9330u16), (25000u16,16383u16),(25001u16,9684u16),(25002u16,15769u16),(25003u16,9332u16), (25004u16,9334u16),(25005u16,15766u16),(25006u16,9338u16),(25007u16,15765u16), (25008u16,15760u16),(25009u16,15759u16),(25010u16,9682u16),(25011u16,15773u16), (25012u16,16386u16),(25013u16,16925u16),(25014u16,9687u16),(25015u16,1937u16), (25016u16,16392u16),(25017u16,1938u16),(25018u16,16390u16),(25020u16,16926u16), (25022u16,9688u16),(25023u16,16391u16),(25024u16,2878u16),(25025u16,16388u16), (25026u16,9973u16),(25027u16,16924u16),(25029u16,16385u16),(25030u16,16387u16), (25031u16,9974u16),(25032u16,9690u16),(25033u16,9972u16),(25034u16,9689u16), (25035u16,9976u16),(25036u16,16389u16),(25037u16,9686u16),(25039u16,1939u16), (25040u16,19378u16),(25043u16,19375u16),(25046u16,17379u16),(25048u16,17371u16), (25050u16,2452u16),(25054u16,16932u16),(25055u16,17372u16),(25056u16,16928u16), (25058u16,4924u16),(25059u16,10227u16),(25060u16,16930u16),(25061u16,16929u16), (25062u16,9975u16),(25063u16,16927u16),(25064u16,16931u16),(25065u16,17380u16), (25066u16,17376u16),(25067u16,17378u16),(25069u16,17373u16),(25070u16,17374u16), (25072u16,17377u16),(25073u16,17375u16),(25074u16,10401u16),(25077u16,10404u16), (25078u16,10403u16),(25079u16,10402u16),(25080u16,10552u16),(25081u16,18065u16), (25082u16,10553u16),(25083u16,17742u16),(25084u16,10644u16),(25085u16,18318u16), (25086u16,10645u16),(25087u16,10728u16),(25088u16,10780u16),(25089u16,18645u16), (25091u16,18646u16),(25092u16,18647u16),(25095u16,18928u16),(25096u16,5621u16), (25097u16,11364u16),(25098u16,5733u16),(25100u16,5877u16),(25101u16,5878u16), (25102u16,5876u16),(25104u16,5879u16),(25105u16,6086u16),(25106u16,6085u16), (25108u16,11854u16),(25109u16,6389u16),(25110u16,6388u16),(25113u16,12637u16), (25114u16,7611u16),(25115u16,7612u16),(25119u16,8060u16),(25120u16,14494u16), (25121u16,8510u16),(25122u16,8511u16),(25123u16,14496u16),(25124u16,14498u16), (25125u16,14497u16),(25127u16,15189u16),(25129u16,15188u16),(25130u16,8958u16), (25131u16,15190u16),(25132u16,1941u16),(25133u16,15774u16),(25134u16,9339u16), (25136u16,9691u16),(25138u16,9977u16),(25139u16,10228u16),(25140u16,9978u16), (25142u16,5622u16),(25143u16,1724u16),(25145u16,4921u16),(25146u16,11593u16), (25149u16,11855u16),(25150u16,6391u16),(25151u16,6390u16),(25152u16,6392u16), (25153u16,6739u16),(25154u16,12201u16),(25155u16,12202u16),(25158u16,12638u16), (25159u16,7143u16),(25160u16,7613u16),(25161u16,8061u16),(25162u16,13833u16), (25163u16,5623u16),(25164u16,1677u16),(25165u16,5557u16),(25166u16,5624u16), (25168u16,11365u16),(25169u16,5737u16),(25170u16,5736u16),(25171u16,5734u16), (25172u16,5735u16),(25176u16,5882u16),(25177u16,11439u16),(25178u16,11441u16), (25179u16,5881u16),(25180u16,11433u16),(25182u16,11434u16),(25184u16,11440u16), (25185u16,11436u16),(25186u16,11438u16),(25187u16,5880u16),(25188u16,11435u16), (25189u16,11442u16),(25190u16,11437u16),(25192u16,4736u16),(25197u16,6093u16), (25198u16,6102u16),(25199u16,6100u16),(25200u16,11603u16),(25201u16,11600u16), (25202u16,11608u16),(25203u16,6098u16),(25204u16,11609u16),(25206u16,6091u16), (25207u16,11606u16),(25209u16,6097u16),(25210u16,11602u16),(25211u16,11601u16), (25212u16,6095u16),(25213u16,11607u16),(25214u16,6096u16),(25215u16,6393u16), (25216u16,6090u16),(25217u16,11604u16),(25218u16,4856u16),(25219u16,11594u16), (25220u16,6087u16),(25221u16,4798u16),(25222u16,6106u16),(25223u16,11599u16), (25224u16,11605u16),(25225u16,6092u16),(25226u16,6094u16),(25228u16,11595u16), (25230u16,11596u16),(25231u16,11597u16),(25232u16,1942u16),(25233u16,6105u16), (25234u16,6099u16),(25235u16,6104u16),(25236u16,11598u16),(25237u16,6103u16), (25238u16,6089u16),(25239u16,6088u16),(25240u16,6101u16),(25245u16,4558u16), (25252u16,2904u16),(25254u16,4920u16),(25256u16,6407u16),(25257u16,11867u16), (25258u16,11860u16),(25259u16,6402u16),(25260u16,6421u16),(25261u16,11856u16), (25262u16,11863u16),(25263u16,11865u16),(25264u16,11868u16),(25265u16,6416u16), (25267u16,11864u16),(25268u16,11857u16),(25269u16,6414u16),(25270u16,11861u16), (25272u16,11869u16),(25273u16,6399u16),(25275u16,11866u16),(25276u16,6409u16), (25277u16,6408u16),(25278u16,11859u16),(25279u16,6397u16),(25281u16,1065u16), (25282u16,6398u16),(25283u16,4088u16),(25284u16,6396u16),(25285u16,19387u16), (25286u16,6420u16),(25287u16,6412u16),(25288u16,6406u16),(25289u16,6394u16), (25290u16,11862u16),(25291u16,6405u16),(25292u16,6395u16),(25293u16,6413u16), (25294u16,4922u16),(25295u16,12203u16),(25296u16,4494u16),(25297u16,11858u16), (25298u16,6400u16),(25299u16,6403u16),(25300u16,6404u16),(25301u16,19389u16), (25302u16,6418u16),(25303u16,6419u16),(25304u16,6417u16),(25305u16,6411u16), (25306u16,6415u16),(25307u16,6401u16),(25308u16,6740u16),(25311u16,19014u16), (25317u16,1943u16),(25323u16,12209u16),(25324u16,6752u16),(25325u16,6744u16), (25326u16,6746u16),(25327u16,6751u16),(25328u16,12221u16),(25329u16,6749u16), (25330u16,12639u16),(25331u16,7144u16),(25332u16,6754u16),(25333u16,12206u16), (25334u16,12214u16),(25335u16,6750u16),(25336u16,12213u16),(25337u16,12210u16), (25338u16,12218u16),(25339u16,12220u16),(25340u16,6743u16),(25341u16,6747u16), (25342u16,6753u16),(25343u16,7146u16),(25344u16,12215u16),(25345u16,6745u16), (25346u16,6756u16),(25347u16,12208u16),(25351u16,6748u16),(25352u16,7145u16), (25353u16,6742u16),(25355u16,12205u16),(25356u16,12212u16),(25357u16,12204u16), (25358u16,12207u16),(25359u16,12211u16),(25360u16,12640u16),(25361u16,6755u16), (25363u16,12216u16),(25364u16,12217u16),(25365u16,12219u16),(25366u16,6741u16), (25368u16,1944u16),(25384u16,7160u16),(25385u16,12652u16),(25386u16,7158u16), (25387u16,7159u16),(25388u16,12642u16),(25389u16,12658u16),(25390u16,4669u16), (25391u16,7149u16),(25393u16,2900u16),(25394u16,13226u16),(25395u16,12660u16), (25396u16,12654u16),(25397u16,4737u16),(25398u16,12645u16),(25399u16,2897u16), (25400u16,12663u16),(25401u16,12648u16),(25402u16,7155u16),(25403u16,13249u16), (25404u16,12651u16),(25405u16,7157u16),(25406u16,7148u16),(25408u16,12665u16), (25409u16,12653u16),(25410u16,7151u16),(25411u16,12646u16),(25412u16,12643u16), (25413u16,12644u16),(25414u16,7152u16),(25415u16,12659u16),(25416u16,12666u16), (25417u16,7154u16),(25418u16,12650u16),(25419u16,12649u16),(25420u16,7162u16), (25421u16,7161u16),(25422u16,7147u16),(25423u16,7153u16),(25424u16,7156u16), (25425u16,12662u16),(25428u16,12656u16),(25429u16,7150u16),(25430u16,12641u16), (25431u16,12664u16),(25432u16,12655u16),(25433u16,12657u16),(25434u16,12661u16), (25444u16,4927u16),(25445u16,13227u16),(25447u16,7621u16),(25448u16,7641u16), (25449u16,7640u16),(25451u16,7629u16),(25452u16,19391u16),(25453u16,13245u16), (25454u16,13241u16),(25455u16,13238u16),(25456u16,13256u16),(25457u16,7624u16), (25458u16,7616u16),(25461u16,13243u16),(25462u16,8077u16),(25463u16,7620u16), (25464u16,13251u16),(25465u16,1508u16),(25466u16,7642u16),(25467u16,7639u16), (25468u16,13247u16),(25469u16,13230u16),(25471u16,4792u16),(25472u16,7638u16), (25473u16,13253u16),(25474u16,13229u16),(25475u16,7627u16),(25476u16,7631u16), (25477u16,13252u16),(25479u16,13239u16),(25480u16,7632u16),(25481u16,7626u16), (25482u16,13228u16),(25483u16,19385u16),(25484u16,8063u16),(25485u16,13255u16), (25486u16,13237u16),(25487u16,7637u16),(25488u16,13240u16),(25489u16,13254u16), (25490u16,7636u16),(25492u16,13834u16),(25494u16,7617u16),(25495u16,13235u16), (25496u16,7622u16),(25497u16,7633u16),(25499u16,7628u16),(25500u16,13244u16), (25501u16,13234u16),(25502u16,13232u16),(25503u16,13250u16),(25504u16,7614u16), (25505u16,7634u16),(25506u16,7618u16),(25507u16,8062u16),(25508u16,13248u16), (25509u16,7619u16),(25511u16,7615u16),(25512u16,7630u16),(25513u16,7625u16), (25514u16,7623u16),(25515u16,13236u16),(25516u16,7635u16),(25517u16,13233u16), (25518u16,13246u16),(25519u16,13242u16),(25520u16,13836u16),(25521u16,13835u16), (25529u16,4565u16),(25533u16,13231u16),(25534u16,13852u16),(25536u16,8065u16), (25537u16,2297u16),(25538u16,13858u16),(25539u16,13841u16),(25540u16,13855u16), (25541u16,14499u16),(25542u16,8068u16),(25543u16,13859u16),(25544u16,13862u16), (25545u16,8067u16),(25546u16,13844u16),(25547u16,13861u16),(25548u16,13860u16), (25549u16,8069u16),(25550u16,13837u16),(25551u16,8064u16),(25552u16,8072u16), (25553u16,2901u16),(25554u16,8070u16),(25555u16,13857u16),(25557u16,13847u16), (25558u16,8074u16),(25559u16,13864u16),(25560u16,13856u16),(25561u16,13865u16), (25562u16,8082u16),(25563u16,8080u16),(25564u16,13854u16),(25565u16,13853u16), (25566u16,4493u16),(25567u16,13851u16),(25568u16,13845u16),(25569u16,8073u16), (25570u16,1948u16),(25571u16,8071u16),(25572u16,12647u16),(25573u16,13838u16), (25574u16,4406u16),(25575u16,14529u16),(25576u16,13839u16),(25577u16,8066u16), (25578u16,8079u16),(25579u16,14501u16),(25581u16,8075u16),(25582u16,8076u16), (25583u16,13840u16),(25584u16,13863u16),(25585u16,14500u16),(25586u16,13848u16), (25587u16,13843u16),(25588u16,8078u16),(25589u16,13849u16),(25590u16,13846u16), (25592u16,19395u16),(25593u16,8083u16),(25595u16,1949u16),(25596u16,4564u16), (25598u16,4566u16),(25606u16,8526u16),(25607u16,1950u16),(25609u16,14504u16), (25610u16,14523u16),(25611u16,14528u16),(25612u16,14516u16),(25613u16,8522u16), (25614u16,14533u16),(25615u16,8519u16),(25616u16,14502u16),(25618u16,14503u16), (25619u16,8512u16),(25620u16,8521u16),(25621u16,14510u16),(25622u16,8524u16), (25623u16,8525u16),(25624u16,14511u16),(25626u16,14524u16),(25627u16,14530u16), (25628u16,8520u16),(25630u16,8514u16),(25631u16,14509u16),(25632u16,14505u16), (25633u16,14532u16),(25634u16,14514u16),(25635u16,14515u16),(25636u16,14506u16), (25637u16,14526u16),(25638u16,14517u16),(25639u16,14527u16),(25640u16,14519u16), (25642u16,8515u16),(25643u16,15191u16),(25644u16,8518u16),(25645u16,8516u16), (25646u16,14531u16),(25647u16,14522u16),(25648u16,14518u16),(25650u16,1568u16), (25651u16,14507u16),(25652u16,8968u16),(25653u16,14521u16),(25654u16,8523u16), (25655u16,14513u16),(25656u16,19394u16),(25657u16,14512u16),(25658u16,19408u16), (25659u16,2906u16),(25661u16,8517u16),(25662u16,8513u16),(25663u16,15212u16), (25664u16,14525u16),(25665u16,14520u16),(25667u16,14508u16),(25675u16,15207u16), (25677u16,15192u16),(25678u16,15203u16),(25680u16,15210u16),(25681u16,8966u16), (25682u16,8081u16),(25683u16,15208u16),(25684u16,8961u16),(25688u16,8960u16), (25689u16,15215u16),(25690u16,1951u16),(25691u16,15193u16),(25692u16,15206u16), (25693u16,15194u16),(25694u16,15205u16),(25695u16,8964u16),(25696u16,15209u16), (25697u16,13850u16),(25701u16,15216u16),(25702u16,15201u16),(25703u16,8967u16), (25704u16,15788u16),(25705u16,9340u16),(25707u16,15214u16),(25708u16,15213u16), (25709u16,8969u16),(25710u16,15775u16),(25711u16,9341u16),(25712u16,15776u16), (25713u16,2889u16),(25714u16,15197u16),(25715u16,15198u16),(25716u16,15195u16), (25717u16,15200u16),(25718u16,15196u16),(25719u16,15217u16),(25720u16,8963u16), (25721u16,9342u16),(25722u16,8965u16),(25723u16,8970u16),(25724u16,1513u16), (25725u16,15199u16),(25727u16,15211u16),(25730u16,15204u16),(25733u16,15779u16), (25735u16,8959u16),(25736u16,9345u16),(25737u16,16400u16),(25738u16,15784u16), (25739u16,15783u16),(25740u16,15785u16),(25741u16,1440u16),(25743u16,15782u16), (25744u16,9346u16),(25745u16,1269u16),(25746u16,9352u16),(25747u16,9349u16), (25749u16,9350u16),(25750u16,15777u16),(25751u16,15780u16),(25752u16,15790u16), (25753u16,9358u16),(25754u16,9356u16),(25756u16,15781u16),(25757u16,13842u16), (25758u16,9343u16),(25759u16,15787u16),(25760u16,15778u16),(25762u16,9359u16), (25763u16,15786u16),(25764u16,8962u16),(25765u16,9348u16),(25766u16,15202u16), (25769u16,9351u16),(25771u16,9355u16),(25772u16,9357u16),(25773u16,9354u16), (25774u16,9353u16),(25775u16,19739u16),(25776u16,9347u16),(25777u16,15789u16), (25778u16,9344u16),(25779u16,9360u16),(25780u16,1469u16),(25782u16,2899u16), (25787u16,9695u16),(25788u16,9696u16),(25789u16,16399u16),(25790u16,9705u16), (25791u16,9702u16),(25792u16,1953u16),(25793u16,9693u16),(25794u16,9700u16), (25795u16,16401u16),(25796u16,9698u16),(25797u16,9692u16),(25799u16,9699u16), (25801u16,16398u16),(25802u16,9980u16),(25803u16,9694u16),(25805u16,9701u16), (25806u16,9979u16),(25807u16,16397u16),(25808u16,16396u16),(25810u16,9703u16), (25811u16,4715u16),(25812u16,9704u16),(25814u16,16395u16),(25815u16,16394u16), (25816u16,9981u16),(25817u16,16404u16),(25818u16,9697u16),(25819u16,16402u16), (25821u16,1435u16),(25824u16,9982u16),(25825u16,19404u16),(25826u16,9987u16), (25827u16,16935u16),(25828u16,16937u16),(25829u16,19405u16),(25830u16,9984u16), (25831u16,2173u16),(25832u16,16938u16),(25833u16,16934u16),(25834u16,1479u16), (25835u16,16936u16),(25836u16,9985u16),(25837u16,9988u16),(25839u16,16933u16), (25840u16,9983u16),(25841u16,9986u16),(25842u16,10230u16),(25843u16,16403u16), (25844u16,10229u16),(25847u16,10235u16),(25848u16,17384u16),(25850u16,10233u16), (25851u16,10234u16),(25852u16,17387u16),(25853u16,17383u16),(25854u16,10231u16), (25855u16,17381u16),(25856u16,10405u16),(25857u16,17385u16),(25859u16,17386u16), (25860u16,17382u16),(25862u16,10232u16),(25863u16,17743u16),(25865u16,17746u16), (25866u16,1259u16),(25868u16,17747u16),(25869u16,17745u16),(25870u16,17748u16), (25871u16,10406u16),(25872u16,17744u16),(25873u16,2971u16),(25875u16,18069u16), (25876u16,10555u16),(25877u16,18068u16),(25878u16,18067u16),(25879u16,18066u16), (25880u16,10554u16),(25881u16,10556u16),(25883u16,18319u16),(25884u16,10647u16), (25885u16,10646u16),(25886u16,19384u16),(25887u16,4617u16),(25888u16,18496u16), (25889u16,18495u16),(25890u16,18498u16),(25891u16,10781u16),(25892u16,10729u16), (25893u16,18649u16),(25894u16,18497u16),(25897u16,18648u16),(25898u16,10783u16), (25899u16,10782u16),(25900u16,10821u16),(25901u16,18754u16),(25902u16,18824u16), (25903u16,5625u16),(25904u16,4497u16),(25906u16,13866u16),(25907u16,16405u16), (25908u16,10945u16),(25909u16,1678u16),(25910u16,5883u16),(25911u16,11610u16), (25912u16,6109u16),(25913u16,6107u16),(25915u16,6108u16),(25917u16,11870u16), (25918u16,6423u16),(25919u16,6757u16),(25921u16,12222u16),(25923u16,12223u16), (25925u16,6758u16),(25926u16,12668u16),(25928u16,7163u16),(25929u16,7164u16), (25930u16,12667u16),(25933u16,19410u16),(25935u16,7649u16),(25937u16,7645u16), (25939u16,13257u16),(25940u16,7652u16),(25941u16,7651u16),(25942u16,7644u16), (25943u16,7647u16),(25944u16,7650u16),(25945u16,7646u16),(25948u16,13870u16), (25949u16,7643u16),(25950u16,8084u16),(25951u16,19416u16),(25954u16,8086u16), (25955u16,8087u16),(25956u16,13869u16),(25957u16,13872u16),(25958u16,8085u16), (25959u16,13867u16),(25960u16,13871u16),(25962u16,13868u16),(25963u16,2907u16), (25964u16,8527u16),(25965u16,19415u16),(25967u16,14534u16),(25970u16,8971u16), (25971u16,15218u16),(25972u16,9706u16),(25973u16,9361u16),(25974u16,15791u16), (25975u16,9362u16),(25976u16,9363u16),(25977u16,15793u16),(25978u16,15792u16), (25979u16,15794u16),(25980u16,16407u16),(25983u16,16406u16),(25984u16,16940u16), (25985u16,16939u16),(25986u16,9989u16),(25987u16,9990u16),(25988u16,17749u16), (25989u16,19414u16),(25990u16,1958u16),(25991u16,5626u16),(25992u16,19254u16), (25993u16,1295u16),(25995u16,1789u16),(25996u16,13873u16),(26000u16,8089u16), (26001u16,8088u16),(26002u16,14535u16),(26004u16,17388u16),(26005u16,10648u16), (26006u16,18650u16),(26007u16,5627u16),(26009u16,7165u16),(26011u16,7654u16), (26012u16,7653u16),(26013u16,13874u16),(26014u16,13875u16),(26015u16,8528u16), (26016u16,15219u16),(26017u16,8972u16),(26018u16,16408u16),(26020u16,5628u16), (26021u16,5738u16),(26023u16,6424u16),(26024u16,11871u16),(26026u16,12224u16), (26027u16,6759u16),(26028u16,7655u16),(26030u16,13876u16),(26031u16,8090u16), (26032u16,8529u16),(26034u16,15795u16),(26035u16,15796u16),(26037u16,19418u16), (26038u16,16941u16),(26039u16,10236u16),(26040u16,18825u16),(26041u16,5629u16), (26043u16,11872u16),(26044u16,6425u16),(26045u16,6760u16),(26046u16,4384u16), (26047u16,12225u16),(26049u16,7166u16),(26050u16,12672u16),(26051u16,12670u16), (26052u16,12671u16),(26053u16,7167u16),(26054u16,12669u16),(26059u16,7657u16), (26060u16,7658u16),(26061u16,13258u16),(26062u16,7659u16),(26063u16,7656u16), (26064u16,13877u16),(26065u16,19421u16),(26066u16,13878u16),(26067u16,14536u16), (26068u16,3229u16),(26070u16,8974u16),(26071u16,8973u16),(26074u16,16942u16), (26075u16,17389u16),(26077u16,17751u16),(26078u16,17750u16),(26079u16,18070u16), (26080u16,10946u16),(26081u16,11334u16),(26082u16,6761u16),(26083u16,19425u16), (26085u16,5630u16),(26086u16,5739u16),(26088u16,5885u16),(26089u16,5884u16), (26092u16,5886u16),(26093u16,5887u16),(26094u16,11444u16),(26095u16,11443u16), (26096u16,11611u16),(26097u16,6110u16),(26098u16,11614u16),(26099u16,11613u16), (26100u16,11612u16),(26101u16,11615u16),(26106u16,6426u16),(26107u16,11878u16), (26108u16,11874u16),(26109u16,11883u16),(26111u16,1960u16),(26112u16,6433u16), (26114u16,6431u16),(26115u16,11879u16),(26116u16,11875u16),(26117u16,11882u16), (26118u16,6430u16),(26119u16,6437u16),(26120u16,11877u16),(26121u16,11873u16), (26122u16,6436u16),(26123u16,11880u16),(26124u16,6429u16),(26125u16,11881u16), (26126u16,6432u16),(26127u16,6434u16),(26128u16,11885u16),(26129u16,11884u16), (26130u16,11876u16),(26131u16,6428u16),(26132u16,6427u16),(26133u16,6435u16), (26136u16,19428u16),(26140u16,12230u16),(26141u16,12236u16),(26142u16,2947u16), (26143u16,6767u16),(26144u16,6764u16),(26145u16,12227u16),(26146u16,12232u16), (26147u16,19660u16),(26148u16,6770u16),(26149u16,6762u16),(26150u16,12231u16), (26151u16,6765u16),(26152u16,6768u16),(26155u16,12234u16),(26157u16,6763u16), (26158u16,12239u16),(26159u16,6766u16),(26160u16,2941u16),(26161u16,6769u16), (26162u16,12228u16),(26163u16,12233u16),(26164u16,12237u16),(26165u16,12229u16), (26166u16,12226u16),(26169u16,12238u16),(26170u16,12235u16),(26177u16,7175u16), (26178u16,7168u16),(26179u16,7171u16),(26180u16,19431u16),(26181u16,7174u16), (26183u16,12675u16),(26184u16,4131u16),(26185u16,7169u16),(26186u16,12673u16), (26187u16,19434u16),(26188u16,7173u16),(26189u16,978u16),(26191u16,7170u16), (26193u16,12676u16),(26194u16,7172u16),(26195u16,1961u16),(26199u16,19141u16), (26201u16,13262u16),(26202u16,7661u16),(26203u16,13261u16),(26204u16,13263u16), (26205u16,7660u16),(26206u16,7665u16),(26207u16,12674u16),(26208u16,1025u16), (26209u16,13260u16),(26210u16,13264u16),(26211u16,2944u16),(26212u16,7662u16), (26213u16,13259u16),(26214u16,7664u16),(26215u16,19436u16),(26216u16,7663u16), (26218u16,13885u16),(26219u16,2939u16),(26220u16,13880u16),(26222u16,8091u16), (26223u16,8095u16),(26224u16,8092u16),(26225u16,13883u16),(26226u16,13886u16), (26227u16,19438u16),(26228u16,8093u16),(26230u16,8094u16),(26231u16,8099u16), (26232u16,14545u16),(26233u16,13884u16),(26234u16,8097u16),(26235u16,13881u16), (26236u16,13879u16),(26237u16,2095u16),(26238u16,8098u16),(26240u16,13882u16), (26244u16,8535u16),(26245u16,19345u16),(26246u16,14537u16),(26247u16,8532u16), (26248u16,8533u16),(26249u16,8531u16),(26250u16,14542u16),(26251u16,14541u16), (26252u16,14538u16),(26253u16,8537u16),(26254u16,2937u16),(26256u16,14540u16), (26257u16,8096u16),(26258u16,1963u16),(26260u16,14544u16),(26261u16,14539u16), (26262u16,8534u16),(26263u16,8530u16),(26264u16,8536u16),(26265u16,14543u16), (26266u16,3636u16),(26269u16,8977u16),(26271u16,15222u16),(26272u16,15221u16), (26273u16,15220u16),(26274u16,8975u16),(26276u16,19172u16),(26280u16,8976u16), (26281u16,15799u16),(26282u16,15802u16),(26283u16,9365u16),(26285u16,19173u16), (26286u16,9364u16),(26287u16,15803u16),(26288u16,15798u16),(26289u16,9367u16), (26290u16,15800u16),(26291u16,19167u16),(26292u16,9366u16),(26293u16,15797u16), (26294u16,4332u16),(26295u16,15801u16),(26296u16,9712u16),(26297u16,9709u16), (26298u16,16417u16),(26299u16,16416u16),(26301u16,16415u16),(26302u16,16410u16), (26303u16,4132u16),(26304u16,16411u16),(26308u16,9710u16),(26310u16,9707u16), (26311u16,9711u16),(26312u16,16409u16),(26313u16,9708u16),(26314u16,16412u16), (26315u16,16413u16),(26316u16,16418u16),(26317u16,19170u16),(26318u16,2918u16), (26319u16,16414u16),(26322u16,16943u16),(26326u16,9992u16),(26328u16,17392u16), (26329u16,9991u16),(26330u16,17390u16),(26331u16,17391u16),(26332u16,10237u16), (26333u16,10408u16),(26334u16,17752u16),(26336u16,10407u16),(26339u16,18072u16), (26340u16,18073u16),(26342u16,10557u16),(26343u16,1848u16),(26344u16,18071u16), (26345u16,10649u16),(26347u16,18651u16),(26348u16,10784u16),(26349u16,18755u16), (26350u16,18756u16),(26352u16,5631u16),(26353u16,4539u16),(26354u16,5888u16), (26355u16,5889u16),(26356u16,6111u16),(26358u16,11886u16),(26359u16,6771u16), (26360u16,7176u16),(26361u16,7666u16),(26364u16,7491u16),(26366u16,8100u16), (26367u16,8101u16),(26368u16,7956u16),(26369u16,13887u16),(26370u16,19448u16), (26371u16,8538u16),(26372u16,15224u16),(26373u16,15223u16),(26376u16,5632u16), (26377u16,5890u16),(26378u16,11887u16),(26379u16,6439u16),(26380u16,4956u16), (26381u16,6438u16),(26382u16,4144u16),(26383u16,12240u16),(26384u16,12241u16), (26386u16,12677u16),(26387u16,12678u16),(26388u16,7177u16),(26389u16,7178u16), (26390u16,1965u16),(26391u16,7179u16),(26392u16,13265u16),(26393u16,1745u16), (26395u16,7668u16),(26397u16,8103u16),(26398u16,4059u16),(26399u16,8102u16), (26400u16,14546u16),(26401u16,14816u16),(26402u16,15225u16),(26403u16,16419u16), (26405u16,2163u16),(26406u16,10238u16),(26407u16,10558u16),(26408u16,5633u16), (26410u16,5742u16),(26411u16,5743u16),(26412u16,5741u16),(26413u16,5744u16), (26414u16,5740u16),(26417u16,5893u16),(26419u16,11452u16),(26420u16,5892u16), (26421u16,5894u16),(26422u16,4390u16),(26424u16,11447u16),(26425u16,11446u16), (26426u16,11449u16),(26427u16,11448u16),(26428u16,11451u16),(26429u16,5891u16), (26430u16,11445u16),(26431u16,11450u16),(26436u16,19013u16),(26437u16,11616u16), (26438u16,6121u16),(26439u16,11617u16),(26440u16,11621u16),(26441u16,6120u16), (26443u16,11625u16),(26444u16,11620u16),(26445u16,11623u16),(26446u16,6113u16), (26447u16,6114u16),(26448u16,6115u16),(26449u16,6116u16),(26451u16,6123u16), (26453u16,11619u16),(26454u16,6118u16),(26455u16,6124u16),(26457u16,11618u16), (26458u16,11624u16),(26460u16,6117u16),(26461u16,11622u16),(26462u16,6119u16), (26463u16,6112u16),(26464u16,6122u16),(26465u16,3744u16),(26466u16,19456u16), (26471u16,19455u16),(26474u16,6460u16),(26475u16,1831u16),(26476u16,11889u16), (26477u16,6440u16),(26478u16,995u16),(26479u16,6450u16),(26480u16,6451u16), (26481u16,6443u16),(26482u16,6461u16),(26483u16,6445u16),(26484u16,11897u16), (26485u16,6456u16),(26486u16,11892u16),(26487u16,6446u16),(26488u16,11907u16), (26489u16,11908u16),(26490u16,11900u16),(26491u16,11893u16),(26492u16,6459u16), (26493u16,11905u16),(26494u16,6454u16),(26495u16,6452u16),(26497u16,11906u16), (26498u16,1030u16),(26499u16,11904u16),(26500u16,11896u16),(26501u16,11888u16), (26502u16,11895u16),(26503u16,6447u16),(26505u16,6453u16),(26507u16,6441u16), (26508u16,11899u16),(26509u16,11898u16),(26510u16,11890u16),(26511u16,2957u16), (26512u16,6455u16),(26513u16,11902u16),(26514u16,11891u16),(26515u16,6458u16), (26516u16,11909u16),(26517u16,6442u16),(26519u16,6449u16),(26520u16,11894u16), (26521u16,11903u16),(26522u16,6457u16),(26524u16,6444u16),(26525u16,6448u16), (26527u16,11901u16),(26528u16,3950u16),(26532u16,1967u16),(26540u16,19481u16), (26542u16,12273u16),(26543u16,6779u16),(26544u16,6792u16),(26545u16,19498u16), (26546u16,12268u16),(26547u16,12258u16),(26548u16,6785u16),(26549u16,12256u16), (26550u16,6778u16),(26551u16,12251u16),(26552u16,6788u16),(26553u16,12264u16), (26554u16,12245u16),(26555u16,12247u16),(26559u16,2259u16),(26560u16,12250u16), (26561u16,12242u16),(26562u16,12263u16),(26563u16,12279u16),(26564u16,6783u16), (26565u16,12252u16),(26566u16,12270u16),(26568u16,12244u16),(26569u16,12277u16), (26570u16,12278u16),(26571u16,12281u16),(26572u16,12272u16),(26573u16,12257u16), (26574u16,12265u16),(26575u16,6789u16),(26576u16,6776u16),(26577u16,6784u16), (26578u16,6796u16),(26579u16,6773u16),(26580u16,6775u16),(26582u16,3147u16), (26583u16,19459u16),(26584u16,12249u16),(26585u16,6793u16),(26586u16,6786u16), (26587u16,12275u16),(26588u16,12246u16),(26589u16,6795u16),(26590u16,6790u16), (26591u16,12255u16),(26594u16,6794u16),(26595u16,12262u16),(26596u16,12254u16), (26597u16,6787u16),(26598u16,12274u16),(26599u16,12266u16),(26601u16,6781u16), (26602u16,12280u16),(26603u16,12253u16),(26604u16,6777u16),(26605u16,12271u16), (26606u16,12261u16),(26607u16,6782u16),(26608u16,12267u16),(26609u16,6774u16), (26610u16,12243u16),(26611u16,6791u16),(26612u16,7194u16),(26613u16,6780u16), (26614u16,12260u16),(26615u16,12259u16),(26616u16,12248u16),(26617u16,2685u16), (26618u16,12276u16),(26620u16,12269u16),(26622u16,1296u16),(26623u16,6772u16), (26624u16,1968u16),(26625u16,19464u16),(26626u16,4928u16),(26627u16,3765u16), (26628u16,1297u16),(26637u16,19640u16),(26640u16,2691u16),(26642u16,12698u16), (26643u16,7201u16),(26644u16,12699u16),(26646u16,12687u16),(26647u16,7190u16), (26648u16,7202u16),(26650u16,12680u16),(26651u16,19100u16),(26652u16,12689u16), (26653u16,12697u16),(26654u16,2960u16),(26655u16,12679u16),(26656u16,12706u16), (26657u16,7180u16),(26658u16,19461u16),(26661u16,12705u16),(26662u16,12700u16), (26664u16,12701u16),(26665u16,7188u16),(26666u16,7199u16),(26667u16,12691u16), (26669u16,12692u16),(26670u16,12702u16),(26671u16,12693u16),(26673u16,12688u16), (26674u16,12682u16),(26675u16,12683u16),(26676u16,12696u16),(26677u16,12690u16), (26678u16,4368u16),(26679u16,19539u16),(26680u16,7181u16),(26681u16,7185u16), (26682u16,12704u16),(26683u16,12684u16),(26684u16,7197u16),(26685u16,7193u16), (26686u16,19315u16),(26688u16,7196u16),(26689u16,7203u16),(26690u16,7186u16), (26691u16,7198u16),(26692u16,12695u16),(26693u16,7200u16),(26694u16,7183u16), (26695u16,3297u16),(26696u16,7182u16),(26697u16,12681u16),(26698u16,1970u16), (26699u16,12685u16),(26700u16,7191u16),(26701u16,12703u16),(26702u16,12694u16), (26703u16,12686u16),(26704u16,7195u16),(26705u16,7192u16),(26707u16,7184u16), (26708u16,7187u16),(26709u16,4092u16),(26710u16,2285u16),(26717u16,19467u16), (26725u16,1298u16),(26731u16,13286u16),(26733u16,13270u16),(26734u16,13271u16), (26735u16,13275u16),(26737u16,13290u16),(26738u16,13287u16),(26740u16,13280u16), (26741u16,13279u16),(26742u16,7675u16),(26743u16,13283u16),(26744u16,13298u16), (26745u16,13266u16),(26747u16,13299u16),(26748u16,13285u16),(26749u16,13303u16), (26750u16,13291u16),(26751u16,7674u16),(26752u16,13289u16),(26753u16,7669u16), (26754u16,7690u16),(26755u16,7680u16),(26756u16,1971u16),(26757u16,7684u16), (26758u16,7683u16),(26759u16,13267u16),(26760u16,2574u16),(26761u16,13296u16), (26762u16,13302u16),(26763u16,13294u16),(26764u16,13301u16),(26767u16,13282u16), (26768u16,13268u16),(26769u16,13300u16),(26770u16,13284u16),(26771u16,7672u16), (26772u16,7685u16),(26774u16,13293u16),(26775u16,7678u16),(26776u16,2972u16), (26779u16,13292u16),(26780u16,13269u16),(26781u16,7686u16),(26783u16,7688u16), (26784u16,13295u16),(26785u16,7689u16),(26786u16,7671u16),(26787u16,13276u16), (26788u16,13297u16),(26790u16,19214u16),(26791u16,7677u16),(26792u16,7687u16), (26793u16,13278u16),(26794u16,13288u16),(26795u16,13273u16),(26796u16,13277u16), (26797u16,7682u16),(26798u16,13272u16),(26799u16,7670u16),(26800u16,7679u16), (26801u16,7676u16),(26802u16,13281u16),(26803u16,7189u16),(26804u16,13910u16), (26805u16,7673u16),(26806u16,2959u16),(26809u16,3595u16),(26813u16,19635u16), (26819u16,19473u16),(26820u16,7681u16),(26821u16,3364u16),(26822u16,13913u16), (26823u16,13935u16),(26824u16,13924u16),(26825u16,8123u16),(26826u16,19751u16), (26827u16,8118u16),(26828u16,13907u16),(26829u16,8119u16),(26830u16,13923u16), (26832u16,13916u16),(26833u16,13929u16),(26834u16,8115u16),(26835u16,13889u16), (26836u16,13931u16),(26837u16,8105u16),(26838u16,13897u16),(26839u16,8108u16), (26840u16,8107u16),(26842u16,8124u16),(26844u16,13891u16),(26845u16,13925u16), (26846u16,13926u16),(26847u16,8110u16),(26848u16,8106u16),(26849u16,13905u16), (26851u16,8117u16),(26852u16,13900u16),(26854u16,13927u16),(26855u16,8113u16), (26856u16,13919u16),(26857u16,13932u16),(26858u16,13894u16),(26859u16,13899u16), (26860u16,13893u16),(26862u16,8112u16),(26863u16,13912u16),(26864u16,14568u16), (26865u16,13895u16),(26866u16,8116u16),(26867u16,13904u16),(26868u16,13928u16), (26869u16,8111u16),(26870u16,13901u16),(26871u16,13898u16),(26872u16,13915u16), (26873u16,8114u16),(26874u16,8104u16),(26875u16,8126u16),(26876u16,13918u16), (26877u16,13917u16),(26880u16,19476u16),(26881u16,19475u16),(26882u16,19769u16), (26883u16,19667u16),(26884u16,13890u16),(26885u16,8109u16),(26886u16,13930u16), (26887u16,13906u16),(26888u16,13908u16),(26889u16,1975u16),(26890u16,13921u16), (26891u16,13920u16),(26892u16,13888u16),(26893u16,8120u16),(26894u16,8122u16), (26895u16,13896u16),(26896u16,13903u16),(26897u16,13911u16),(26898u16,8121u16), (26899u16,13902u16),(26900u16,13914u16),(26901u16,13933u16),(26903u16,13922u16), (26904u16,4145u16),(26905u16,1791u16),(26906u16,4010u16),(26907u16,2195u16), (26917u16,13934u16),(26922u16,13892u16),(26924u16,4773u16),(26927u16,14588u16), (26928u16,8546u16),(26930u16,14586u16),(26931u16,14565u16),(26932u16,14570u16), (26933u16,14563u16),(26934u16,19485u16),(26935u16,14582u16),(26936u16,14549u16), (26937u16,14556u16),(26939u16,14580u16),(26940u16,14590u16),(26941u16,14566u16), (26942u16,19072u16),(26943u16,14553u16),(26944u16,14572u16),(26945u16,14577u16), (26946u16,14557u16),(26947u16,1976u16),(26948u16,14574u16),(26949u16,14554u16), (26950u16,1322u16),(26952u16,14561u16),(26953u16,14562u16),(26954u16,8548u16), (26955u16,14581u16),(26956u16,14579u16),(26958u16,14550u16),(26959u16,14584u16), (26961u16,14585u16),(26962u16,14587u16),(26963u16,8552u16),(26964u16,8544u16), (26965u16,4044u16),(26966u16,13274u16),(26967u16,14558u16),(26968u16,14576u16), (26969u16,14559u16),(26970u16,8541u16),(26971u16,8557u16),(26972u16,14583u16), (26973u16,8555u16),(26974u16,8551u16),(26975u16,14548u16),(26976u16,8543u16), (26977u16,19482u16),(26978u16,14551u16),(26979u16,8556u16),(26980u16,1978u16), (26981u16,14567u16),(26982u16,14547u16),(26983u16,3596u16),(26984u16,8549u16), (26985u16,14571u16),(26986u16,14555u16),(26987u16,8550u16),(26988u16,14564u16), (26989u16,8540u16),(26990u16,8125u16),(26991u16,14573u16),(26992u16,13909u16), (26993u16,14552u16),(26994u16,2908u16),(26995u16,19472u16),(26996u16,14578u16), (26997u16,8545u16),(26998u16,14575u16),(26999u16,8542u16),(27000u16,14569u16), (27001u16,8553u16),(27002u16,14560u16),(27003u16,14589u16),(27008u16,4779u16), (27010u16,8547u16),(27011u16,14701u16),(27013u16,1980u16),(27014u16,8554u16), (27018u16,3852u16),(27021u16,15239u16),(27022u16,15237u16),(27024u16,15259u16), (27025u16,15235u16),(27027u16,15253u16),(27028u16,8539u16),(27029u16,8980u16), (27030u16,15231u16),(27031u16,15258u16),(27032u16,19486u16),(27033u16,15236u16), (27034u16,15250u16),(27035u16,8985u16),(27036u16,8978u16),(27038u16,15256u16), (27039u16,1979u16),(27040u16,15229u16),(27041u16,15255u16),(27042u16,2047u16), (27043u16,8996u16),(27044u16,15246u16),(27045u16,15262u16),(27046u16,8994u16), (27047u16,15238u16),(27048u16,8979u16),(27049u16,15240u16),(27050u16,15254u16), (27051u16,8988u16),(27052u16,15233u16),(27053u16,8992u16),(27054u16,8982u16), (27055u16,15242u16),(27056u16,15232u16),(27057u16,15226u16),(27058u16,4978u16), (27059u16,15252u16),(27060u16,8989u16),(27061u16,15261u16),(27062u16,15227u16), (27063u16,8986u16),(27065u16,15248u16),(27067u16,8987u16),(27068u16,15234u16), (27069u16,15245u16),(27070u16,15241u16),(27071u16,15243u16),(27072u16,4814u16), (27073u16,8981u16),(27074u16,15260u16),(27075u16,8995u16),(27076u16,15244u16), (27078u16,15263u16),(27081u16,15228u16),(27082u16,15249u16),(27083u16,8984u16), (27084u16,8993u16),(27085u16,8991u16),(27086u16,15230u16),(27087u16,15251u16), (27088u16,8990u16),(27089u16,2778u16),(27091u16,8983u16),(27092u16,15247u16), (27093u16,4385u16),(27094u16,1982u16),(27097u16,15257u16),(27105u16,19469u16), (27106u16,15815u16),(27108u16,15811u16),(27109u16,15807u16),(27110u16,15827u16), (27111u16,15824u16),(27112u16,9370u16),(27113u16,4094u16),(27115u16,15831u16), (27116u16,15814u16),(27117u16,9381u16),(27118u16,15821u16),(27121u16,15810u16), (27122u16,15820u16),(27123u16,9378u16),(27124u16,15840u16),(27126u16,15837u16), (27127u16,15823u16),(27128u16,15808u16),(27129u16,19491u16),(27130u16,19452u16), (27131u16,15828u16),(27132u16,15830u16),(27133u16,9374u16),(27134u16,15818u16), (27135u16,15813u16),(27136u16,15804u16),(27137u16,9371u16),(27138u16,9379u16), (27139u16,4363u16),(27140u16,15833u16),(27141u16,9380u16),(27142u16,15805u16), (27143u16,15839u16),(27144u16,15826u16),(27145u16,15832u16),(27146u16,9377u16), (27147u16,19470u16),(27148u16,3655u16),(27149u16,15829u16),(27151u16,15836u16), (27153u16,9382u16),(27155u16,9376u16),(27156u16,15822u16),(27157u16,15809u16), (27158u16,15841u16),(27159u16,15806u16),(27160u16,15834u16),(27161u16,9373u16), (27162u16,3605u16),(27163u16,15816u16),(27164u16,3164u16),(27165u16,15817u16), (27166u16,9372u16),(27167u16,9369u16),(27168u16,15812u16),(27169u16,9375u16), (27171u16,9368u16),(27173u16,15835u16),(27174u16,15838u16),(27175u16,15819u16), (27176u16,16432u16),(27177u16,1026u16),(27179u16,3641u16),(27180u16,19684u16), (27181u16,3090u16),(27186u16,16424u16),(27187u16,2966u16),(27188u16,16420u16), (27189u16,9725u16),(27192u16,9714u16),(27193u16,9719u16),(27194u16,9715u16), (27195u16,16434u16),(27196u16,16445u16),(27197u16,9713u16),(27198u16,16426u16), (27199u16,16435u16),(27200u16,15825u16),(27201u16,16436u16),(27203u16,1792u16), (27204u16,9720u16),(27205u16,19494u16),(27206u16,16451u16),(27207u16,9724u16), (27208u16,9727u16),(27209u16,16422u16),(27211u16,9723u16),(27212u16,2973u16), (27213u16,16449u16),(27214u16,16450u16),(27215u16,16440u16),(27216u16,16439u16), (27217u16,16431u16),(27218u16,2967u16),(27219u16,2177u16),(27220u16,16441u16), (27221u16,16448u16),(27222u16,16447u16),(27223u16,2225u16),(27224u16,9718u16), (27225u16,9716u16),(27226u16,16433u16),(27227u16,16430u16),(27229u16,16427u16), (27230u16,16446u16),(27231u16,9726u16),(27232u16,16444u16),(27233u16,9722u16), (27234u16,9721u16),(27235u16,1757u16),(27236u16,16438u16),(27237u16,1984u16), (27238u16,16421u16),(27239u16,16423u16),(27240u16,16425u16),(27241u16,16443u16), (27242u16,16437u16),(27243u16,9717u16),(27245u16,16428u16),(27247u16,16442u16), (27249u16,1986u16),(27252u16,1985u16),(27254u16,16429u16),(27258u16,2975u16), (27262u16,10000u16),(27263u16,16961u16),(27264u16,9993u16),(27265u16,16946u16), (27266u16,1987u16),(27267u16,16957u16),(27268u16,9995u16),(27269u16,16964u16), (27271u16,16953u16),(27273u16,16948u16),(27274u16,19298u16),(27276u16,16965u16), (27277u16,16944u16),(27278u16,16955u16),(27279u16,3345u16),(27280u16,10002u16), (27281u16,16960u16),(27282u16,16966u16),(27283u16,16954u16),(27284u16,9994u16), (27285u16,16956u16),(27286u16,16945u16),(27287u16,10001u16),(27289u16,1989u16), (27290u16,16963u16),(27291u16,16950u16),(27292u16,9997u16),(27293u16,19496u16), (27294u16,16952u16),(27295u16,16949u16),(27296u16,10003u16),(27297u16,16951u16), (27298u16,9996u16),(27299u16,9999u16),(27300u16,16959u16),(27301u16,16947u16), (27302u16,16962u16),(27303u16,2235u16),(27304u16,16958u16),(27307u16,1991u16), (27308u16,10240u16),(27309u16,17403u16),(27310u16,10245u16),(27311u16,10246u16), (27313u16,4466u16),(27314u16,3134u16),(27315u16,10239u16),(27316u16,17402u16), (27317u16,1992u16),(27318u16,17399u16),(27319u16,17400u16),(27320u16,10243u16), (27321u16,17394u16),(27322u16,17398u16),(27323u16,10242u16),(27325u16,17395u16), (27326u16,2962u16),(27330u16,10244u16),(27331u16,10241u16),(27333u16,17393u16), (27334u16,17397u16),(27335u16,17401u16),(27336u16,19499u16),(27337u16,2968u16), (27338u16,4794u16),(27339u16,17758u16),(27340u16,17755u16),(27341u16,17764u16), (27343u16,17763u16),(27344u16,17761u16),(27345u16,17756u16),(27347u16,10412u16), (27348u16,1993u16),(27352u16,3489u16),(27353u16,17757u16),(27354u16,10411u16), (27355u16,9998u16),(27356u16,17760u16),(27357u16,10410u16),(27358u16,17765u16), (27359u16,17759u16),(27360u16,17754u16),(27361u16,17396u16),(27365u16,10409u16), (27367u16,17753u16),(27368u16,18077u16),(27370u16,18076u16),(27371u16,17762u16), (27372u16,10559u16),(27374u16,18080u16),(27375u16,18081u16),(27376u16,18075u16), (27377u16,18079u16),(27379u16,18074u16),(27382u16,1994u16),(27384u16,18323u16), (27385u16,18078u16),(27386u16,10652u16),(27387u16,10650u16),(27388u16,18321u16), (27392u16,18324u16),(27394u16,18320u16),(27395u16,18322u16),(27396u16,10651u16), (27397u16,2969u16),(27400u16,18500u16),(27401u16,18501u16),(27402u16,10730u16), (27403u16,18499u16),(27407u16,18654u16),(27408u16,10785u16),(27409u16,18652u16), (27410u16,18653u16),(27411u16,18757u16),(27414u16,10855u16),(27415u16,18828u16), (27416u16,18826u16),(27417u16,18827u16),(27418u16,18829u16),(27421u16,19502u16), (27422u16,18929u16),(27424u16,5634u16),(27425u16,5895u16),(27427u16,6462u16), (27429u16,11910u16),(27432u16,12282u16),(27436u16,12707u16),(27437u16,12709u16), (27439u16,12708u16),(27441u16,12710u16),(27442u16,7691u16),(27443u16,13305u16), (27444u16,12711u16),(27445u16,19505u16),(27446u16,13304u16),(27447u16,13306u16), (27448u16,13307u16),(27449u16,13936u16),(27450u16,8128u16),(27451u16,13937u16), (27452u16,13939u16),(27453u16,8129u16),(27454u16,8127u16),(27455u16,13938u16), (27457u16,14596u16),(27458u16,14594u16),(27459u16,14593u16),(27461u16,14592u16), (27462u16,14591u16),(27463u16,8558u16),(27464u16,14595u16),(27465u16,8997u16), (27466u16,15264u16),(27467u16,15266u16),(27468u16,8998u16),(27469u16,15265u16), (27470u16,9384u16),(27472u16,9383u16),(27473u16,15842u16),(27474u16,4831u16), (27476u16,16453u16),(27477u16,16452u16),(27478u16,16454u16),(27479u16,2976u16), (27481u16,9728u16),(27483u16,16967u16),(27484u16,10004u16),(27486u16,17404u16), (27487u16,10247u16),(27488u16,17766u16),(27489u16,10731u16),(27490u16,5635u16), (27491u16,5745u16),(27492u16,5896u16),(27493u16,6125u16),(27494u16,6463u16), (27495u16,6464u16),(27498u16,6797u16),(27501u16,12712u16),(27503u16,1719u16), (27506u16,8559u16),(27508u16,19506u16),(27510u16,15968u16),(27511u16,9729u16), (27512u16,10248u16),(27513u16,5636u16),(27514u16,1679u16),(27515u16,5897u16), (27518u16,11912u16),(27519u16,6465u16),(27520u16,11911u16),(27521u16,1995u16), (27522u16,12283u16),(27523u16,6798u16),(27524u16,12284u16),(27526u16,6799u16), (27528u16,12714u16),(27529u16,7205u16),(27530u16,7204u16),(27532u16,13312u16), (27533u16,13310u16),(27534u16,13311u16),(27535u16,13309u16),(27537u16,13308u16), (27540u16,13940u16),(27541u16,13943u16),(27542u16,8131u16),(27543u16,13941u16), (27544u16,8130u16),(27545u16,13942u16),(27547u16,14597u16),(27550u16,15267u16), (27551u16,15268u16),(27552u16,15269u16),(27554u16,15845u16),(27555u16,15844u16), (27556u16,9385u16),(27557u16,15843u16),(27558u16,15846u16),(27559u16,16455u16), (27562u16,16456u16),(27563u16,16457u16),(27565u16,16968u16),(27566u16,10005u16), (27567u16,10249u16),(27568u16,17767u16),(27570u16,10653u16),(27571u16,11335u16), (27573u16,6800u16),(27574u16,12285u16),(27575u16,7206u16),(27578u16,7692u16), (27580u16,8132u16),(27581u16,13944u16),(27583u16,8561u16),(27584u16,8560u16), (27585u16,1996u16),(27587u16,15270u16),(27588u16,15271u16),(27589u16,9386u16), (27590u16,9387u16),(27591u16,16459u16),(27592u16,16458u16),(27593u16,17405u16), (27594u16,18655u16),(27595u16,5637u16),(27596u16,11336u16),(27597u16,5746u16), (27599u16,6126u16),(27600u16,11626u16),(27602u16,6801u16),(27603u16,8562u16), (27604u16,5638u16),(27606u16,12286u16),(27607u16,6802u16),(27608u16,12287u16), (27610u16,10006u16),(27611u16,5639u16),(27612u16,19517u16),(27614u16,11913u16), (27616u16,12288u16),(27617u16,19515u16),(27618u16,12719u16),(27619u16,12718u16), (27620u16,12716u16),(27622u16,12715u16),(27623u16,12720u16),(27624u16,12717u16), (27626u16,1997u16),(27627u16,7693u16),(27628u16,7694u16),(27631u16,8133u16), (27632u16,13945u16),(27634u16,13946u16),(27635u16,13947u16),(27639u16,14602u16), (27640u16,14603u16),(27641u16,14601u16),(27642u16,4843u16),(27643u16,14599u16), (27644u16,14600u16),(27645u16,8563u16),(27646u16,15272u16),(27647u16,15849u16), (27648u16,15848u16),(27649u16,15847u16),(27650u16,15850u16),(27651u16,16461u16), (27652u16,16460u16),(27653u16,9730u16),(27654u16,16462u16),(27656u16,10007u16), (27657u16,16969u16),(27659u16,17406u16),(27660u16,17768u16),(27661u16,18502u16), (27663u16,5640u16),(27664u16,5748u16),(27665u16,5747u16),(27667u16,6466u16), (27668u16,11337u16),(27669u16,11366u16),(27670u16,5898u16),(27672u16,11453u16), (27673u16,11627u16),(27674u16,11628u16),(27675u16,6467u16),(27676u16,2446u16), (27677u16,11914u16),(27679u16,6803u16),(27680u16,12289u16),(27681u16,12290u16), (27683u16,7207u16),(27684u16,7211u16),(27685u16,12721u16),(27686u16,7210u16), (27687u16,7208u16),(27688u16,7209u16),(27690u16,13313u16),(27691u16,7695u16), (27692u16,8136u16),(27694u16,8134u16),(27695u16,8135u16),(27696u16,13948u16), (27697u16,4820u16),(27699u16,8999u16),(27700u16,5641u16),(27701u16,1680u16), (27702u16,11367u16),(27703u16,19518u16),(27704u16,5749u16),(27705u16,4315u16), (27706u16,1681u16),(27707u16,11370u16),(27709u16,1534u16),(27710u16,5752u16), (27711u16,11369u16),(27712u16,5751u16),(27713u16,5750u16),(27714u16,6127u16), (27715u16,11368u16),(27718u16,11454u16),(27721u16,19127u16),(27722u16,4708u16), (27723u16,11460u16),(27724u16,11461u16),(27725u16,5908u16),(27726u16,5909u16), (27727u16,11457u16),(27728u16,5904u16),(27730u16,11455u16),(27732u16,11459u16), (27733u16,5905u16),(27735u16,5900u16),(27736u16,3248u16),(27737u16,5901u16), (27738u16,19522u16),(27739u16,5907u16),(27740u16,11456u16),(27741u16,5899u16), (27742u16,6128u16),(27743u16,5902u16),(27744u16,5903u16),(27745u16,5906u16), (27749u16,11645u16),(27750u16,11643u16),(27751u16,11630u16),(27752u16,6140u16), (27753u16,11637u16),(27754u16,6135u16),(27755u16,11631u16),(27757u16,11639u16), (27758u16,19188u16),(27759u16,11636u16),(27760u16,6138u16),(27761u16,11635u16), (27762u16,6145u16),(27763u16,11644u16),(27764u16,6147u16),(27765u16,1998u16), (27766u16,6149u16),(27768u16,11629u16),(27769u16,19524u16),(27770u16,6136u16), (27771u16,11646u16),(27773u16,6143u16),(27774u16,6146u16),(27775u16,2170u16), (27776u16,11937u16),(27777u16,6130u16),(27778u16,6153u16),(27779u16,6144u16), (27780u16,11632u16),(27781u16,6133u16),(27782u16,6148u16),(27783u16,11640u16), (27784u16,6131u16),(27785u16,6132u16),(27786u16,11935u16),(27787u16,11633u16), (27788u16,6139u16),(27789u16,6150u16),(27790u16,11647u16),(27791u16,11634u16), (27792u16,6137u16),(27794u16,6142u16),(27795u16,11915u16),(27796u16,6151u16), (27797u16,11641u16),(27798u16,6141u16),(27800u16,6152u16),(27801u16,6129u16), (27802u16,11638u16),(27803u16,6134u16),(27804u16,11642u16),(27805u16,11936u16), (27807u16,2409u16),(27810u16,3711u16),(27818u16,1999u16),(27819u16,6479u16), (27820u16,6495u16),(27821u16,11922u16),(27822u16,6486u16),(27823u16,3565u16), (27824u16,11943u16),(27825u16,6471u16),(27826u16,4637u16),(27827u16,6474u16), (27828u16,11934u16),(27830u16,11920u16),(27831u16,11924u16),(27832u16,6482u16), (27833u16,6484u16),(27834u16,11927u16),(27835u16,6491u16),(27836u16,6477u16), (27837u16,6475u16),(27838u16,6476u16),(27839u16,6490u16),(27840u16,11939u16), (27841u16,6485u16),(27842u16,11926u16),(27843u16,11928u16),(27844u16,6483u16), (27845u16,6488u16),(27846u16,11929u16),(27847u16,11942u16),(27849u16,6804u16), (27850u16,6494u16),(27851u16,19098u16),(27852u16,6472u16),(27853u16,11941u16), (27854u16,4869u16),(27855u16,11945u16),(27856u16,11925u16),(27857u16,11947u16), (27858u16,11932u16),(27859u16,6481u16),(27860u16,11921u16),(27861u16,6480u16), (27862u16,6498u16),(27863u16,6487u16),(27865u16,11919u16),(27866u16,12299u16), (27867u16,6493u16),(27868u16,6497u16),(27869u16,11933u16),(27870u16,11938u16), (27871u16,3662u16),(27872u16,6499u16),(27873u16,6492u16),(27874u16,6478u16), (27875u16,6468u16),(27877u16,6473u16),(27879u16,11923u16),(27880u16,6469u16), (27881u16,11946u16),(27882u16,4864u16),(27883u16,11917u16),(27884u16,11916u16), (27885u16,11930u16),(27886u16,11918u16),(27887u16,6496u16),(27888u16,7212u16), (27889u16,6489u16),(27890u16,11931u16),(27891u16,6470u16),(27893u16,6819u16), (27897u16,11944u16),(27903u16,1794u16),(27904u16,12306u16),(27905u16,12309u16), (27906u16,2001u16),(27907u16,12312u16),(27908u16,12301u16),(27909u16,2822u16), (27910u16,2002u16),(27911u16,12315u16),(27912u16,12318u16),(27913u16,12320u16), (27914u16,12298u16),(27915u16,6805u16),(27916u16,6810u16),(27917u16,12726u16), (27918u16,6826u16),(27919u16,12313u16),(27920u16,12321u16),(27921u16,12305u16), (27922u16,12297u16),(27926u16,12753u16),(27927u16,6813u16),(27928u16,12310u16), (27929u16,12302u16),(27930u16,12304u16),(27931u16,6818u16),(27933u16,12307u16), (27934u16,6812u16),(27935u16,12294u16),(27936u16,12316u16),(27938u16,12319u16), (27940u16,2998u16),(27941u16,6809u16),(27942u16,2003u16),(27943u16,6821u16), (27944u16,12291u16),(27945u16,6823u16),(27946u16,6807u16),(27947u16,6827u16), (27948u16,12317u16),(27949u16,12293u16),(27950u16,6824u16),(27951u16,12747u16), (27952u16,11940u16),(27953u16,6811u16),(27954u16,6806u16),(27955u16,12300u16), (27956u16,12292u16),(27957u16,6825u16),(27958u16,6817u16),(27959u16,12311u16), (27960u16,6822u16),(27961u16,6820u16),(27962u16,12303u16),(27963u16,6814u16), (27964u16,12295u16),(27965u16,6815u16),(27966u16,6816u16),(27967u16,12296u16), (27968u16,12314u16),(27969u16,6808u16),(27970u16,12308u16),(27982u16,1299u16), (27991u16,3562u16),(27992u16,12729u16),(27993u16,7220u16),(27994u16,7225u16), (27995u16,19142u16),(27996u16,19544u16),(27998u16,12738u16),(27999u16,12744u16), (28000u16,12740u16),(28001u16,12727u16),(28002u16,12730u16),(28003u16,12723u16), (28004u16,12724u16),(28005u16,7232u16),(28006u16,7217u16),(28007u16,2990u16), (28008u16,12748u16),(28009u16,7227u16),(28010u16,7213u16),(28012u16,7222u16), (28013u16,12731u16),(28014u16,7224u16),(28015u16,12732u16),(28016u16,12742u16), (28017u16,19231u16),(28018u16,2754u16),(28020u16,7226u16),(28021u16,12757u16), (28022u16,12725u16),(28023u16,7219u16),(28024u16,7218u16),(28025u16,7230u16), (28026u16,12722u16),(28027u16,12755u16),(28028u16,12743u16),(28029u16,12756u16), (28030u16,12750u16),(28031u16,12736u16),(28032u16,12751u16),(28033u16,2004u16), (28034u16,12745u16),(28035u16,12754u16),(28036u16,12752u16),(28037u16,7231u16), (28038u16,12737u16),(28039u16,7216u16),(28040u16,7215u16),(28041u16,7223u16), (28042u16,7229u16),(28043u16,12749u16),(28044u16,7228u16),(28045u16,12734u16), (28046u16,7696u16),(28047u16,4265u16),(28048u16,12758u16),(28049u16,12733u16), (28050u16,12728u16),(28051u16,7221u16),(28052u16,7233u16),(28053u16,7214u16), (28054u16,19543u16),(28055u16,12741u16),(28056u16,12746u16),(28068u16,2006u16), (28069u16,2987u16),(28074u16,7730u16),(28075u16,13315u16),(28076u16,13319u16), (28078u16,7711u16),(28079u16,7709u16),(28081u16,2007u16),(28082u16,7700u16), (28083u16,13317u16),(28084u16,13316u16),(28085u16,7720u16),(28087u16,13322u16), (28088u16,7714u16),(28089u16,4983u16),(28090u16,13340u16),(28091u16,13352u16), (28092u16,7697u16),(28093u16,13337u16),(28094u16,13330u16),(28095u16,7732u16), (28096u16,13314u16),(28098u16,13342u16),(28100u16,7729u16),(28101u16,7717u16), (28102u16,7728u16),(28103u16,7707u16),(28104u16,13326u16),(28105u16,13344u16), (28106u16,13336u16),(28107u16,7708u16),(28108u16,7702u16),(28109u16,13350u16), (28111u16,13343u16),(28112u16,13345u16),(28113u16,7710u16),(28114u16,7718u16), (28115u16,13347u16),(28116u16,13324u16),(28117u16,13341u16),(28118u16,13329u16), (28119u16,13349u16),(28120u16,7723u16),(28121u16,7699u16),(28122u16,7721u16), (28123u16,13334u16),(28124u16,13332u16),(28125u16,13333u16),(28126u16,7712u16), (28127u16,13328u16),(28128u16,13327u16),(28129u16,7701u16),(28130u16,13321u16), (28131u16,13351u16),(28132u16,7703u16),(28133u16,13331u16),(28134u16,7733u16), (28136u16,7727u16),(28137u16,13320u16),(28138u16,7724u16),(28139u16,7722u16), (28140u16,7731u16),(28141u16,13338u16),(28142u16,7726u16),(28143u16,12735u16), (28144u16,13339u16),(28145u16,7725u16),(28146u16,13346u16),(28147u16,7698u16), (28148u16,13335u16),(28149u16,7716u16),(28150u16,13323u16),(28151u16,7715u16), (28153u16,7713u16),(28154u16,7705u16),(28155u16,7704u16),(28156u16,13949u16), (28157u16,13348u16),(28158u16,1728u16),(28160u16,13325u16),(28162u16,3569u16), (28163u16,13970u16),(28164u16,2993u16),(28165u16,7706u16),(28170u16,2996u16), (28175u16,3559u16),(28181u16,2008u16),(28184u16,2009u16),(28185u16,8165u16), (28186u16,7719u16),(28187u16,8147u16),(28188u16,13964u16),(28189u16,8161u16), (28191u16,13952u16),(28192u16,8144u16),(28193u16,8140u16),(28194u16,13982u16), (28195u16,8146u16),(28196u16,8150u16),(28197u16,8145u16),(28198u16,8154u16), (28199u16,13986u16),(28200u16,13977u16),(28201u16,2010u16),(28202u16,19776u16), (28203u16,13959u16),(28204u16,8159u16),(28205u16,8153u16),(28206u16,13971u16), (28207u16,8137u16),(28208u16,13983u16),(28209u16,13976u16),(28210u16,8141u16), (28211u16,13965u16),(28212u16,8156u16),(28213u16,13994u16),(28214u16,13995u16), (28216u16,8138u16),(28217u16,13981u16),(28218u16,8158u16),(28219u16,13969u16), (28220u16,13955u16),(28221u16,13956u16),(28222u16,8162u16),(28223u16,13960u16), (28224u16,13967u16),(28225u16,13961u16),(28227u16,8160u16),(28228u16,8168u16), (28229u16,13957u16),(28230u16,13950u16),(28231u16,13951u16),(28233u16,13953u16), (28234u16,8143u16),(28235u16,13966u16),(28237u16,8157u16),(28238u16,8166u16), (28239u16,19562u16),(28240u16,19462u16),(28241u16,13968u16),(28242u16,13992u16), (28243u16,13984u16),(28244u16,8139u16),(28245u16,13990u16),(28246u16,8151u16), (28247u16,1850u16),(28248u16,8149u16),(28249u16,19216u16),(28250u16,13996u16), (28251u16,8148u16),(28252u16,13974u16),(28253u16,13962u16),(28254u16,13972u16), (28255u16,8171u16),(28256u16,13978u16),(28257u16,13975u16),(28258u16,13958u16), (28259u16,8167u16),(28260u16,13988u16),(28261u16,13985u16),(28262u16,13993u16), (28263u16,8142u16),(28264u16,13973u16),(28265u16,8170u16),(28267u16,13980u16), (28270u16,8152u16),(28271u16,8155u16),(28273u16,13979u16),(28274u16,8169u16), (28275u16,13963u16),(28276u16,13318u16),(28278u16,2750u16),(28279u16,13989u16), (28280u16,13987u16),(28281u16,13991u16),(28284u16,19545u16),(28294u16,2011u16), (28296u16,13954u16),(28297u16,8164u16),(28299u16,3253u16),(28301u16,14634u16), (28302u16,14633u16),(28303u16,14607u16),(28304u16,8569u16),(28306u16,14632u16), (28307u16,14610u16),(28308u16,14611u16),(28310u16,8579u16),(28311u16,14641u16), (28312u16,8574u16),(28313u16,14631u16),(28314u16,1351u16),(28315u16,14604u16), (28316u16,8580u16),(28317u16,8570u16),(28318u16,14619u16),(28319u16,14609u16), (28320u16,14612u16),(28321u16,14636u16),(28322u16,8564u16),(28323u16,14643u16), (28324u16,14635u16),(28325u16,8573u16),(28326u16,14624u16),(28327u16,8584u16), (28330u16,8583u16),(28331u16,8577u16),(28334u16,14642u16),(28335u16,8565u16), (28336u16,14622u16),(28337u16,14613u16),(28338u16,14626u16),(28339u16,14638u16), (28340u16,8585u16),(28341u16,19508u16),(28342u16,8567u16),(28343u16,14621u16), (28344u16,4324u16),(28345u16,14614u16),(28346u16,8576u16),(28347u16,2013u16), (28348u16,8575u16),(28349u16,14617u16),(28350u16,14627u16),(28351u16,14637u16), (28352u16,14608u16),(28353u16,14618u16),(28354u16,8568u16),(28355u16,14628u16), (28356u16,8581u16),(28357u16,8572u16),(28358u16,14615u16),(28359u16,8571u16), (28360u16,14606u16),(28361u16,14620u16),(28362u16,14640u16),(28363u16,8163u16), (28364u16,9027u16),(28365u16,14623u16),(28366u16,15273u16),(28367u16,14625u16), (28368u16,14639u16),(28369u16,8578u16),(28370u16,14616u16),(28371u16,8566u16), (28372u16,8582u16),(28373u16,9405u16),(28374u16,14605u16),(28376u16,14630u16), (28377u16,19091u16),(28378u16,2015u16),(28379u16,19033u16),(28380u16,14629u16), (28381u16,1263u16),(28386u16,2014u16),(28392u16,2017u16),(28393u16,2018u16), (28395u16,15301u16),(28396u16,9024u16),(28397u16,15290u16),(28398u16,15295u16), (28399u16,9013u16),(28401u16,15275u16),(28402u16,9026u16),(28404u16,9004u16), (28405u16,15274u16),(28406u16,15307u16),(28407u16,9028u16),(28408u16,15278u16), (28409u16,15294u16),(28410u16,19569u16),(28411u16,15280u16),(28412u16,15310u16), (28413u16,15306u16),(28414u16,9002u16),(28415u16,9012u16),(28416u16,15876u16), (28417u16,9025u16),(28418u16,9010u16),(28419u16,15276u16),(28420u16,19546u16), (28421u16,15305u16),(28422u16,9014u16),(28423u16,15302u16),(28424u16,15315u16), (28425u16,15282u16),(28426u16,15291u16),(28427u16,2988u16),(28428u16,3570u16), (28429u16,15313u16),(28430u16,15303u16),(28431u16,9009u16),(28434u16,15289u16), (28435u16,9003u16),(28436u16,9001u16),(28437u16,9019u16),(28438u16,19411u16), (28439u16,3615u16),(28440u16,15287u16),(28441u16,15284u16),(28442u16,15285u16), (28444u16,15309u16),(28446u16,15314u16),(28447u16,15312u16),(28448u16,9007u16), (28449u16,15316u16),(28450u16,9011u16),(28451u16,9018u16),(28452u16,2019u16), (28453u16,15277u16),(28454u16,15852u16),(28455u16,15286u16),(28457u16,9005u16), (28458u16,9023u16),(28459u16,9020u16),(28460u16,9008u16),(28461u16,15296u16), (28462u16,15281u16),(28463u16,9021u16),(28464u16,15298u16),(28465u16,9015u16), (28466u16,9017u16),(28467u16,9000u16),(28468u16,2020u16),(28469u16,15300u16), (28470u16,15292u16),(28471u16,15279u16),(28472u16,9016u16),(28473u16,15308u16), (28474u16,15311u16),(28475u16,15288u16),(28476u16,15299u16),(28477u16,19641u16), (28478u16,9006u16),(28479u16,9388u16),(28480u16,15297u16),(28481u16,15851u16), (28483u16,15304u16),(28484u16,19574u16),(28494u16,15283u16),(28495u16,15861u16), (28496u16,15871u16),(28497u16,9391u16),(28498u16,15870u16),(28499u16,15882u16), (28500u16,9393u16),(28501u16,15868u16),(28502u16,4465u16),(28503u16,15872u16), (28504u16,9404u16),(28506u16,15863u16),(28507u16,9396u16),(28508u16,19575u16), (28509u16,15875u16),(28510u16,16470u16),(28511u16,9408u16),(28512u16,9407u16), (28513u16,15877u16),(28514u16,15860u16),(28515u16,15887u16),(28516u16,9402u16), (28518u16,9392u16),(28519u16,15880u16),(28521u16,15884u16),(28522u16,15889u16), (28523u16,15878u16),(28524u16,15866u16),(28525u16,9395u16),(28526u16,9398u16), (28527u16,9406u16),(28528u16,9401u16),(28530u16,15869u16),(28531u16,15293u16), (28532u16,19577u16),(28534u16,15865u16),(28535u16,15888u16),(28536u16,9397u16), (28537u16,3252u16),(28538u16,9400u16),(28539u16,15890u16),(28540u16,9389u16), (28541u16,15879u16),(28542u16,15853u16),(28543u16,15885u16),(28544u16,10016u16), (28545u16,2023u16),(28546u16,15867u16),(28548u16,9390u16),(28549u16,15862u16), (28550u16,9394u16),(28551u16,15854u16),(28552u16,9022u16),(28553u16,15858u16), (28554u16,19399u16),(28555u16,15883u16),(28556u16,15859u16),(28557u16,15857u16), (28558u16,9399u16),(28560u16,15881u16),(28562u16,15856u16),(28563u16,15874u16), (28564u16,15873u16),(28565u16,15886u16),(28566u16,15864u16),(28567u16,9403u16), (28573u16,19567u16),(28574u16,16473u16),(28575u16,19580u16),(28576u16,9743u16), (28577u16,9733u16),(28578u16,16485u16),(28579u16,16465u16),(28580u16,9735u16), (28581u16,16477u16),(28582u16,9742u16),(28583u16,9737u16),(28584u16,16475u16), (28585u16,16971u16),(28586u16,16481u16),(28587u16,16487u16),(28588u16,16480u16), (28589u16,16463u16),(28590u16,16478u16),(28591u16,16489u16),(28592u16,16491u16), (28593u16,9732u16),(28594u16,16490u16),(28595u16,9738u16),(28596u16,9744u16), (28597u16,4361u16),(28598u16,4230u16),(28600u16,16484u16),(28601u16,9740u16), (28602u16,16479u16),(28603u16,3249u16),(28604u16,16467u16),(28605u16,16472u16), (28606u16,2024u16),(28607u16,16483u16),(28608u16,9739u16),(28609u16,9736u16), (28610u16,9731u16),(28611u16,9734u16),(28612u16,16471u16),(28614u16,15855u16), (28615u16,16466u16),(28616u16,16469u16),(28617u16,16486u16),(28618u16,16474u16), (28619u16,16464u16),(28620u16,16970u16),(28621u16,16488u16),(28622u16,16468u16), (28623u16,16482u16),(28627u16,19582u16),(28628u16,16973u16),(28629u16,10020u16), (28632u16,10008u16),(28633u16,3435u16),(28634u16,3434u16),(28635u16,10012u16), (28636u16,16975u16),(28637u16,16981u16),(28638u16,16979u16),(28639u16,10010u16), (28640u16,10011u16),(28641u16,10018u16),(28642u16,16982u16),(28643u16,16974u16), (28644u16,10013u16),(28646u16,16978u16),(28647u16,16977u16),(28648u16,16983u16), (28649u16,10019u16),(28651u16,10014u16),(28652u16,10017u16),(28653u16,16976u16), (28654u16,10021u16),(28655u16,10015u16),(28656u16,10022u16),(28657u16,10009u16), (28658u16,16980u16),(28660u16,16972u16),(28662u16,2439u16),(28663u16,17419u16), (28664u16,19565u16),(28666u16,10254u16),(28667u16,17416u16),(28668u16,17418u16), (28670u16,10252u16),(28671u16,17414u16),(28672u16,17415u16),(28673u16,17410u16), (28675u16,3684u16),(28676u16,16476u16),(28677u16,17411u16),(28678u16,10253u16), (28679u16,17407u16),(28681u16,10250u16),(28682u16,17420u16),(28683u16,10251u16), (28684u16,17408u16),(28685u16,17409u16),(28686u16,17413u16),(28687u16,10256u16), (28689u16,10255u16),(28692u16,17412u16),(28693u16,10418u16),(28694u16,17772u16), (28695u16,17778u16),(28696u16,10419u16),(28697u16,17769u16),(28698u16,10416u16), (28699u16,10413u16),(28700u16,17780u16),(28701u16,10417u16),(28702u16,3436u16), (28703u16,10414u16),(28704u16,17771u16),(28705u16,17774u16),(28706u16,17775u16), (28707u16,17776u16),(28708u16,17779u16),(28710u16,17417u16),(28711u16,17770u16), (28712u16,10415u16),(28713u16,17777u16),(28714u16,17781u16),(28715u16,17773u16), (28716u16,2030u16),(28719u16,18084u16),(28720u16,10561u16),(28721u16,18087u16), (28722u16,10562u16),(28723u16,18095u16),(28724u16,18086u16),(28725u16,18083u16), (28727u16,18085u16),(28728u16,18089u16),(28729u16,18092u16),(28730u16,18091u16), (28731u16,18094u16),(28732u16,18082u16),(28734u16,10560u16),(28735u16,18090u16), (28736u16,18093u16),(28737u16,18096u16),(28738u16,18088u16),(28739u16,18325u16), (28740u16,18326u16),(28741u16,18330u16),(28742u16,18331u16),(28744u16,18328u16), (28745u16,18329u16),(28746u16,18327u16),(28747u16,19594u16),(28748u16,10654u16), (28749u16,1766u16),(28752u16,2032u16),(28753u16,10732u16),(28754u16,18506u16), (28756u16,2033u16),(28757u16,18503u16),(28758u16,18504u16),(28759u16,18505u16), (28760u16,10733u16),(28762u16,18657u16),(28763u16,18656u16),(28764u16,2350u16), (28765u16,18760u16),(28766u16,10822u16),(28767u16,18758u16),(28768u16,18761u16), (28769u16,18759u16),(28770u16,18830u16),(28771u16,10856u16),(28772u16,10870u16), (28773u16,18905u16),(28774u16,18884u16),(28775u16,3564u16),(28776u16,18904u16), (28777u16,18950u16),(28778u16,18951u16),(28779u16,5642u16),(28780u16,1682u16), (28782u16,1066u16),(28783u16,2034u16),(28784u16,5910u16),(28785u16,11462u16), (28788u16,11648u16),(28789u16,2474u16),(28790u16,6154u16),(28791u16,1734u16), (28792u16,6157u16),(28793u16,19139u16),(28794u16,11649u16),(28796u16,6155u16), (28797u16,6156u16),(28798u16,19595u16),(28799u16,2035u16),(28801u16,19597u16), (28802u16,11956u16),(28803u16,11958u16),(28804u16,11953u16),(28805u16,11950u16), (28806u16,11952u16),(28809u16,2036u16),(28810u16,6503u16),(28811u16,19189u16), (28814u16,6501u16),(28815u16,2423u16),(28817u16,11954u16),(28818u16,6502u16), (28819u16,11951u16),(28820u16,11948u16),(28821u16,6500u16),(28822u16,11955u16), (28824u16,11949u16),(28825u16,6504u16),(28826u16,11957u16),(28831u16,12323u16), (28832u16,3816u16),(28833u16,12327u16),(28835u16,2649u16),(28836u16,6836u16), (28837u16,3502u16),(28838u16,3658u16),(28839u16,19596u16),(28841u16,12330u16), (28843u16,6828u16),(28844u16,6831u16),(28845u16,6833u16),(28846u16,6835u16), (28847u16,6832u16),(28848u16,12326u16),(28849u16,12325u16),(28851u16,6830u16), (28852u16,12328u16),(28853u16,12329u16),(28855u16,12322u16),(28856u16,6834u16), (28857u16,3755u16),(28858u16,6829u16),(28859u16,4079u16),(28860u16,1300u16), (28861u16,19623u16),(28862u16,12324u16),(28864u16,3798u16),(28868u16,3231u16), (28869u16,12772u16),(28870u16,12773u16),(28871u16,12774u16),(28872u16,7238u16), (28874u16,7234u16),(28875u16,12763u16),(28876u16,19598u16),(28877u16,12771u16), (28878u16,12776u16),(28879u16,7239u16),(28880u16,2644u16),(28881u16,12761u16), (28882u16,12767u16),(28883u16,12760u16),(28884u16,12770u16),(28885u16,19599u16), (28886u16,19600u16),(28887u16,12766u16),(28888u16,7235u16),(28889u16,7237u16), (28890u16,12775u16),(28892u16,12759u16),(28893u16,12762u16),(28894u16,12768u16), (28895u16,19601u16),(28896u16,12769u16),(28897u16,12777u16),(28898u16,12765u16), (28900u16,7236u16),(28911u16,7738u16),(28912u16,13359u16),(28913u16,3003u16), (28915u16,13361u16),(28916u16,13357u16),(28917u16,3854u16),(28918u16,13369u16), (28919u16,13355u16),(28920u16,13368u16),(28921u16,7734u16),(28922u16,13353u16), (28923u16,14000u16),(28924u16,13363u16),(28925u16,7737u16),(28926u16,3589u16), (28927u16,13364u16),(28928u16,13367u16),(28930u16,13371u16),(28932u16,13360u16), (28933u16,2832u16),(28934u16,13365u16),(28937u16,7735u16),(28938u16,7736u16), (28939u16,13370u16),(28940u16,13358u16),(28941u16,13354u16),(28942u16,13372u16), (28944u16,13362u16),(28947u16,13366u16),(28951u16,13356u16),(28953u16,8172u16), (28954u16,8173u16),(28955u16,14010u16),(28956u16,8179u16),(28957u16,3646u16), (28958u16,13998u16),(28959u16,14007u16),(28960u16,13997u16),(28961u16,8176u16), (28962u16,14005u16),(28963u16,14003u16),(28965u16,14004u16),(28966u16,8174u16), (28968u16,14008u16),(28969u16,3230u16),(28971u16,19607u16),(28972u16,19617u16), (28974u16,14001u16),(28975u16,13999u16),(28976u16,8175u16),(28977u16,14002u16), (28978u16,14006u16),(28979u16,3659u16),(28980u16,3445u16),(28981u16,2112u16), (28982u16,8177u16),(28986u16,14009u16),(28987u16,3000u16),(28990u16,2044u16), (28992u16,1596u16),(28993u16,14649u16),(28994u16,14656u16),(28995u16,14658u16), (28996u16,14664u16),(28997u16,19608u16),(28998u16,8598u16),(28999u16,14644u16), (29001u16,8590u16),(29002u16,19610u16),(29003u16,14659u16),(29004u16,8595u16), (29005u16,14665u16),(29006u16,8586u16),(29007u16,19614u16),(29008u16,14662u16), (29009u16,4229u16),(29010u16,14646u16),(29011u16,14663u16),(29012u16,14645u16), (29014u16,8600u16),(29015u16,1867u16),(29016u16,14657u16),(29017u16,8587u16), (29018u16,14666u16),(29020u16,8592u16),(29021u16,14650u16),(29022u16,8597u16), (29023u16,14661u16),(29024u16,14648u16),(29025u16,14655u16),(29026u16,4992u16), (29027u16,14647u16),(29028u16,8589u16),(29029u16,8596u16),(29030u16,8594u16), (29031u16,8591u16),(29032u16,8599u16),(29033u16,8588u16),(29034u16,14654u16), (29035u16,3516u16),(29036u16,8593u16),(29038u16,8178u16),(29040u16,14660u16), (29041u16,4197u16),(29042u16,14652u16),(29043u16,4022u16),(29045u16,3556u16), (29046u16,4988u16),(29047u16,2622u16),(29048u16,14653u16),(29050u16,4840u16), (29051u16,15324u16),(29052u16,2321u16),(29053u16,9031u16),(29054u16,2647u16), (29056u16,15320u16),(29057u16,15326u16),(29058u16,15322u16),(29060u16,9033u16), (29061u16,15321u16),(29062u16,15325u16),(29063u16,15317u16),(29064u16,3737u16), (29065u16,15319u16),(29066u16,9032u16),(29068u16,2773u16),(29070u16,3634u16), (29071u16,15323u16),(29072u16,15318u16),(29073u16,1744u16),(29074u16,9034u16), (29076u16,9029u16),(29078u16,19605u16),(29079u16,15327u16),(29080u16,4091u16), (29081u16,9030u16),(29082u16,15896u16),(29083u16,15893u16),(29084u16,15905u16), (29085u16,15899u16),(29086u16,15901u16),(29087u16,9409u16),(29088u16,15895u16), (29089u16,15903u16),(29090u16,4450u16),(29091u16,4630u16),(29092u16,15902u16), (29093u16,15900u16),(29095u16,15906u16),(29096u16,9412u16),(29097u16,15897u16), (29098u16,15904u16),(29100u16,9410u16),(29101u16,4345u16),(29103u16,15892u16), (29104u16,15894u16),(29105u16,9411u16),(29106u16,15891u16),(29107u16,15907u16), (29108u16,19604u16),(29109u16,15898u16),(29111u16,2027u16),(29112u16,16495u16), (29113u16,9751u16),(29114u16,19621u16),(29116u16,16506u16),(29117u16,16504u16), (29118u16,9745u16),(29119u16,16494u16),(29120u16,16497u16),(29121u16,16498u16), (29122u16,16493u16),(29123u16,9755u16),(29124u16,9756u16),(29125u16,16492u16), (29126u16,16507u16),(29127u16,16502u16),(29128u16,9749u16),(29129u16,9746u16), (29130u16,16501u16),(29131u16,16499u16),(29134u16,9752u16),(29135u16,16503u16), (29136u16,9747u16),(29137u16,2060u16),(29138u16,9748u16),(29140u16,16500u16), (29141u16,9750u16),(29142u16,16496u16),(29144u16,16505u16),(29145u16,9753u16), (29146u16,16508u16),(29147u16,16509u16),(29148u16,9754u16),(29149u16,19106u16), (29151u16,4273u16),(29152u16,10031u16),(29153u16,16984u16),(29154u16,16990u16), (29156u16,16988u16),(29157u16,10027u16),(29158u16,10026u16),(29159u16,10023u16), (29160u16,16986u16),(29163u16,3448u16),(29164u16,10029u16),(29165u16,10028u16), (29166u16,10025u16),(29168u16,16989u16),(29169u16,16985u16),(29170u16,16987u16), (29172u16,10030u16),(29173u16,3704u16),(29174u16,4562u16),(29176u16,10260u16), (29177u16,17423u16),(29179u16,10257u16),(29180u16,10258u16),(29181u16,17425u16), (29182u16,10259u16),(29183u16,17422u16),(29184u16,1796u16),(29185u16,4136u16), (29186u16,17785u16),(29187u16,17424u16),(29189u16,17786u16),(29190u16,10420u16), (29191u16,17784u16),(29193u16,4186u16),(29194u16,17783u16),(29196u16,17782u16), (29197u16,10421u16),(29198u16,19624u16),(29199u16,2791u16),(29200u16,10563u16), (29203u16,18097u16),(29204u16,18098u16),(29205u16,19626u16),(29206u16,2618u16), (29207u16,2640u16),(29209u16,18334u16),(29210u16,18333u16),(29211u16,10655u16), (29213u16,18332u16),(29214u16,18507u16),(29215u16,18508u16),(29218u16,18658u16), (29219u16,18762u16),(29220u16,19629u16),(29221u16,973u16),(29222u16,18831u16), (29223u16,18930u16),(29224u16,10890u16),(29225u16,18940u16),(29226u16,5643u16), (29227u16,1683u16),(29228u16,6505u16),(29229u16,6506u16),(29230u16,19632u16), (29232u16,6837u16),(29237u16,10032u16),(29238u16,5644u16),(29240u16,6507u16), (29241u16,7240u16),(29242u16,8601u16),(29243u16,5645u16),(29245u16,7739u16), (29246u16,9035u16),(29247u16,11338u16),(29248u16,19633u16),(29249u16,12331u16), (29250u16,12778u16),(29252u16,15328u16),(29254u16,10033u16),(29255u16,5646u16), (29256u16,6508u16),(29257u16,12332u16),(29258u16,12333u16),(29259u16,14011u16), (29260u16,8180u16),(29263u16,14667u16),(29264u16,3004u16),(29266u16,8602u16), (29267u16,15329u16),(29269u16,19636u16),(29270u16,9413u16),(29271u16,19637u16), (29272u16,10422u16),(29273u16,5647u16),(29274u16,14012u16),(29275u16,5648u16), (29276u16,1977u16),(29277u16,5912u16),(29278u16,11463u16),(29279u16,5911u16), (29280u16,6160u16),(29281u16,6159u16),(29282u16,6158u16),(29283u16,11650u16), (29286u16,4609u16),(29287u16,6509u16),(29289u16,6510u16),(29290u16,11959u16), (29292u16,12334u16),(29294u16,12337u16),(29295u16,6839u16),(29296u16,12335u16), (29298u16,6838u16),(29299u16,12336u16),(29300u16,6840u16),(29302u16,12781u16), (29303u16,12780u16),(29304u16,12779u16),(29305u16,7241u16),(29307u16,13374u16), (29308u16,13375u16),(29309u16,7740u16),(29310u16,13373u16),(29311u16,13376u16), (29312u16,8182u16),(29313u16,7741u16),(29314u16,19642u16),(29316u16,8181u16), (29317u16,14016u16),(29318u16,14015u16),(29319u16,3005u16),(29320u16,14013u16), (29321u16,14014u16),(29323u16,14017u16),(29324u16,14669u16),(29325u16,14668u16), (29326u16,14672u16),(29327u16,4429u16),(29328u16,14671u16),(29329u16,14670u16), (29330u16,9036u16),(29331u16,15332u16),(29332u16,3006u16),(29333u16,15331u16), (29334u16,9037u16),(29335u16,15330u16),(29336u16,15908u16),(29338u16,15909u16), (29339u16,9414u16),(29341u16,16510u16),(29342u16,16511u16),(29343u16,3806u16), (29345u16,17791u16),(29346u16,10423u16),(29347u16,17790u16),(29348u16,17789u16), (29349u16,17787u16),(29350u16,17788u16),(29351u16,10656u16),(29352u16,18099u16), (29353u16,18509u16),(29354u16,18832u16),(29356u16,5649u16),(29357u16,1685u16), (29358u16,11371u16),(29359u16,5753u16),(29360u16,11372u16),(29362u16,4908u16), (29364u16,11464u16),(29365u16,11465u16),(29370u16,11656u16),(29373u16,11652u16), (29375u16,11651u16),(29376u16,6511u16),(29377u16,11655u16),(29378u16,6162u16), (29379u16,11653u16),(29380u16,6161u16),(29381u16,11657u16),(29382u16,11654u16), (29385u16,11963u16),(29386u16,12338u16),(29387u16,11961u16),(29388u16,11968u16), (29389u16,3693u16),(29390u16,6512u16),(29392u16,6515u16),(29393u16,11969u16), (29394u16,11965u16),(29396u16,11966u16),(29398u16,11960u16),(29399u16,6514u16), (29400u16,11962u16),(29401u16,6513u16),(29402u16,11967u16),(29404u16,11964u16), (29407u16,12342u16),(29408u16,6842u16),(29409u16,6843u16),(29410u16,4876u16), (29411u16,12345u16),(29412u16,12339u16),(29414u16,12344u16),(29416u16,12340u16), (29417u16,6841u16),(29418u16,12343u16),(29419u16,12341u16),(29427u16,12787u16), (29428u16,12784u16),(29430u16,12786u16),(29431u16,7246u16),(29432u16,7245u16), (29433u16,7243u16),(29434u16,12783u16),(29435u16,12788u16),(29436u16,7242u16), (29437u16,7244u16),(29438u16,12785u16),(29439u16,13384u16),(29440u16,12782u16), (29441u16,12789u16),(29442u16,4879u16),(29444u16,4590u16),(29447u16,13379u16), (29448u16,13383u16),(29450u16,13382u16),(29451u16,14019u16),(29452u16,14030u16), (29455u16,13385u16),(29456u16,3694u16),(29457u16,13380u16),(29458u16,14018u16), (29459u16,7745u16),(29462u16,7744u16),(29463u16,13378u16),(29464u16,13381u16), (29465u16,7746u16),(29467u16,7743u16),(29468u16,7742u16),(29469u16,13377u16), (29470u16,13386u16),(29474u16,14021u16),(29475u16,14028u16),(29477u16,8184u16), (29478u16,14027u16),(29479u16,14024u16),(29480u16,19649u16),(29481u16,8186u16), (29482u16,3821u16),(29483u16,19644u16),(29484u16,4904u16),(29485u16,14026u16), (29486u16,19650u16),(29488u16,14020u16),(29489u16,14022u16),(29490u16,14025u16), (29491u16,14023u16),(29492u16,8185u16),(29493u16,14029u16),(29494u16,8183u16), (29495u16,8603u16),(29496u16,3696u16),(29497u16,3697u16),(29498u16,14676u16), (29499u16,14675u16),(29500u16,14673u16),(29502u16,8606u16),(29503u16,8605u16), (29504u16,14677u16),(29505u16,3699u16),(29506u16,14674u16),(29507u16,15333u16), (29508u16,9038u16),(29509u16,8604u16),(29512u16,3700u16),(29513u16,14679u16), (29514u16,14678u16),(29516u16,15336u16),(29517u16,15334u16),(29518u16,9415u16), (29519u16,4800u16),(29520u16,9039u16),(29521u16,15335u16),(29522u16,15911u16), (29527u16,9416u16),(29528u16,15910u16),(29529u16,15919u16),(29530u16,15918u16), (29531u16,15916u16),(29533u16,15915u16),(29534u16,15912u16),(29535u16,15913u16), (29536u16,15914u16),(29537u16,15917u16),(29538u16,15920u16),(29541u16,16516u16), (29542u16,16513u16),(29543u16,16514u16),(29544u16,9757u16),(29545u16,16512u16), (29546u16,16518u16),(29547u16,16517u16),(29548u16,16515u16),(29550u16,16992u16), (29551u16,16993u16),(29552u16,10034u16),(29553u16,4877u16),(29554u16,10035u16), (29555u16,16991u16),(29556u16,4654u16),(29557u16,10262u16),(29558u16,17426u16), (29559u16,10261u16),(29560u16,10424u16),(29562u16,10425u16),(29563u16,10564u16), (29564u16,18101u16),(29565u16,18100u16),(29566u16,18335u16),(29567u16,18510u16), (29568u16,10734u16),(29569u16,18660u16),(29570u16,18659u16),(29571u16,18661u16), (29572u16,5754u16),(29573u16,12346u16),(29574u16,7247u16),(29575u16,7747u16), (29576u16,13387u16),(29577u16,5755u16),(29578u16,11373u16),(29579u16,5650u16), (29580u16,1798u16),(29582u16,11466u16),(29583u16,3687u16),(29586u16,11662u16), (29587u16,11660u16),(29588u16,11661u16),(29589u16,11658u16),(29590u16,6163u16), (29591u16,11659u16),(29592u16,2785u16),(29596u16,19124u16),(29597u16,11977u16), (29598u16,2626u16),(29599u16,6518u16),(29600u16,11975u16),(29601u16,11971u16), (29602u16,11974u16),(29604u16,11970u16),(29605u16,6520u16),(29606u16,11973u16), (29607u16,19121u16),(29608u16,6517u16),(29609u16,6516u16),(29610u16,19652u16), (29611u16,6519u16),(29612u16,11976u16),(29613u16,11972u16),(29618u16,6847u16), (29619u16,6850u16),(29620u16,12354u16),(29621u16,12353u16),(29622u16,12352u16), (29623u16,6844u16),(29624u16,12361u16),(29625u16,12351u16),(29626u16,1746u16), (29627u16,6846u16),(29628u16,12794u16),(29630u16,12358u16),(29631u16,12356u16), (29632u16,6849u16),(29634u16,12348u16),(29635u16,12359u16),(29636u16,1035u16), (29637u16,12350u16),(29638u16,12360u16),(29639u16,12357u16),(29640u16,12349u16), (29641u16,19655u16),(29642u16,6845u16),(29643u16,12362u16),(29644u16,12347u16), (29645u16,6848u16),(29646u16,19271u16),(29647u16,19651u16),(29648u16,3082u16), (29650u16,12799u16),(29651u16,12790u16),(29652u16,12801u16),(29653u16,19101u16), (29654u16,12793u16),(29655u16,12804u16),(29656u16,12805u16),(29657u16,12791u16), (29658u16,12803u16),(29659u16,12800u16),(29660u16,12798u16),(29661u16,12802u16), (29662u16,7253u16),(29664u16,7251u16),(29665u16,3706u16),(29666u16,3482u16), (29667u16,12796u16),(29668u16,19677u16),(29669u16,12792u16),(29670u16,3505u16), (29671u16,12795u16),(29672u16,12806u16),(29673u16,12797u16),(29674u16,7252u16), (29675u16,12355u16),(29677u16,7248u16),(29678u16,7250u16),(29679u16,19003u16), (29683u16,3490u16),(29684u16,13401u16),(29685u16,13390u16),(29686u16,13388u16), (29687u16,19665u16),(29688u16,13389u16),(29689u16,3311u16),(29690u16,13396u16), (29691u16,3491u16),(29692u16,13397u16),(29693u16,13393u16),(29694u16,7752u16), (29695u16,13398u16),(29696u16,13395u16),(29697u16,13392u16),(29698u16,1753u16), (29699u16,7750u16),(29700u16,13391u16),(29701u16,7748u16),(29702u16,7751u16), (29703u16,13394u16),(29704u16,13402u16),(29705u16,7249u16),(29706u16,7749u16), (29707u16,13400u16),(29708u16,13399u16),(29709u16,7753u16),(29713u16,1319u16), (29714u16,3292u16),(29716u16,2783u16),(29717u16,19666u16),(29718u16,14035u16), (29719u16,19159u16),(29721u16,3713u16),(29722u16,14036u16),(29723u16,8196u16), (29724u16,2496u16),(29725u16,14042u16),(29726u16,3714u16),(29727u16,3715u16), (29728u16,14044u16),(29729u16,14037u16),(29730u16,8190u16),(29731u16,14041u16), (29732u16,14040u16),(29733u16,8191u16),(29734u16,8197u16),(29736u16,8198u16), (29737u16,14043u16),(29738u16,8188u16),(29739u16,14034u16),(29740u16,14032u16), (29741u16,14038u16),(29742u16,14031u16),(29743u16,8195u16),(29744u16,14033u16), (29745u16,14039u16),(29746u16,14045u16),(29747u16,8189u16),(29748u16,8194u16), (29749u16,8192u16),(29750u16,8193u16),(29751u16,3028u16),(29752u16,3068u16), (29753u16,19669u16),(29754u16,8187u16),(29756u16,3026u16),(29759u16,8613u16), (29760u16,14686u16),(29761u16,8612u16),(29762u16,14690u16),(29763u16,2823u16), (29764u16,14680u16),(29765u16,3277u16),(29766u16,14691u16),(29767u16,19676u16), (29768u16,3500u16),(29769u16,19656u16),(29770u16,14681u16),(29771u16,14682u16), (29772u16,1028u16),(29773u16,14692u16),(29774u16,14689u16),(29775u16,14687u16), (29776u16,14688u16),(29777u16,14684u16),(29778u16,14683u16),(29779u16,19559u16), (29780u16,14693u16),(29781u16,8609u16),(29782u16,2784u16),(29783u16,14685u16), (29785u16,8614u16),(29786u16,8608u16),(29787u16,8615u16),(29788u16,8616u16), (29789u16,19712u16),(29790u16,8611u16),(29791u16,8610u16),(29792u16,19674u16), (29793u16,998u16),(29794u16,15337u16),(29795u16,9041u16),(29796u16,9040u16), (29797u16,19243u16),(29799u16,15342u16),(29800u16,3041u16),(29801u16,9417u16), (29802u16,9042u16),(29803u16,3293u16),(29804u16,19680u16),(29805u16,9044u16), (29806u16,15343u16),(29807u16,8607u16),(29808u16,9043u16),(29809u16,15339u16), (29810u16,15341u16),(29811u16,15338u16),(29812u16,19682u16),(29813u16,15340u16), (29814u16,19678u16),(29817u16,2780u16),(29818u16,3012u16),(29820u16,15929u16), (29821u16,15926u16),(29822u16,9420u16),(29823u16,16519u16),(29824u16,9421u16), (29825u16,15925u16),(29826u16,19685u16),(29827u16,9419u16),(29829u16,15927u16), (29830u16,15924u16),(29831u16,15921u16),(29832u16,15928u16),(29833u16,15922u16), (29834u16,15923u16),(29835u16,9418u16),(29836u16,2830u16),(29837u16,2109u16), (29840u16,16997u16),(29842u16,16523u16),(29844u16,16522u16),(29845u16,16524u16), (29847u16,16994u16),(29848u16,9760u16),(29849u16,2782u16),(29850u16,16520u16), (29851u16,3069u16),(29852u16,9758u16),(29853u16,999u16),(29854u16,9762u16), (29855u16,9761u16),(29856u16,16521u16),(29857u16,16525u16),(29859u16,9759u16), (29860u16,19360u16),(29861u16,17001u16),(29862u16,10038u16),(29863u16,10263u16), (29864u16,10039u16),(29865u16,10036u16),(29866u16,16998u16),(29867u16,16996u16), (29869u16,16999u16),(29871u16,17002u16),(29872u16,10037u16),(29873u16,17000u16), (29874u16,16995u16),(29876u16,3484u16),(29877u16,17429u16),(29878u16,17432u16), (29879u16,17794u16),(29880u16,17427u16),(29881u16,1802u16),(29882u16,18102u16), (29883u16,17433u16),(29885u16,10426u16),(29886u16,17431u16),(29887u16,10264u16), (29888u16,17428u16),(29889u16,17430u16),(29890u16,17434u16),(29891u16,17795u16), (29893u16,17793u16),(29894u16,1037u16),(29896u16,19694u16),(29898u16,10427u16), (29899u16,17792u16),(29900u16,3025u16),(29903u16,10565u16),(29904u16,2955u16), (29907u16,3720u16),(29908u16,10658u16),(29909u16,18512u16),(29910u16,10657u16), (29911u16,18514u16),(29912u16,18511u16),(29913u16,18513u16),(29914u16,10786u16), (29915u16,18763u16),(29916u16,5756u16),(29917u16,11978u16),(29918u16,12807u16), (29919u16,12808u16),(29920u16,7754u16),(29921u16,14694u16),(29922u16,9763u16), (29923u16,10428u16),(29924u16,10735u16),(29925u16,18764u16),(29926u16,5757u16), (29927u16,4986u16),(29928u16,11979u16),(29929u16,5213u16),(29932u16,12363u16), (29934u16,12364u16),(29936u16,4960u16),(29937u16,4880u16),(29938u16,4953u16), (29940u16,12809u16),(29941u16,12810u16),(29942u16,7755u16),(29943u16,7756u16), (29944u16,4975u16),(29947u16,14046u16),(29949u16,14697u16),(29950u16,14696u16), (29951u16,14695u16),(29952u16,15344u16),(29954u16,15345u16),(29955u16,15346u16), (29956u16,9045u16),(29957u16,4952u16),(29959u16,15932u16),(29960u16,15931u16), (29963u16,16526u16),(29964u16,9764u16),(29965u16,9765u16),(29966u16,19696u16), (29967u16,17006u16),(29968u16,17003u16),(29969u16,17004u16),(29970u16,17005u16), (29971u16,17436u16),(29972u16,17435u16),(29973u16,10265u16),(29974u16,17796u16), (29975u16,18336u16),(29976u16,5758u16),(29977u16,1353u16),(29978u16,6851u16), (29980u16,7757u16),(29981u16,14698u16),(29982u16,19698u16),(29983u16,5759u16), (29985u16,12811u16),(29986u16,7758u16),(29989u16,8199u16),(29990u16,8200u16), (29992u16,5760u16),(29993u16,5761u16),(29994u16,11467u16),(29995u16,6165u16), (29996u16,6164u16),(29997u16,6852u16),(29998u16,12365u16),(29999u16,14047u16), (30000u16,5762u16),(30001u16,5763u16),(30002u16,5764u16),(30003u16,5765u16), (30004u16,4542u16),(30005u16,1301u16),(30007u16,6166u16),(30008u16,6167u16), (30009u16,11664u16),(30010u16,11663u16),(30011u16,4298u16),(30013u16,6521u16), (30014u16,11982u16),(30015u16,11980u16),(30016u16,11981u16),(30018u16,3723u16), (30022u16,4781u16),(30023u16,12366u16),(30024u16,12367u16),(30026u16,19705u16), (30027u16,6856u16),(30028u16,6854u16),(30029u16,19704u16),(30030u16,6855u16), (30031u16,6853u16),(30033u16,3573u16),(30035u16,4965u16),(30036u16,7254u16), (30037u16,3037u16),(30041u16,7258u16),(30042u16,7257u16),(30043u16,12812u16), (30044u16,7256u16),(30045u16,7255u16),(30047u16,12813u16),(30048u16,3824u16), (30050u16,7761u16),(30051u16,13404u16),(30052u16,13403u16),(30053u16,7759u16), (30054u16,7760u16),(30055u16,19706u16),(30058u16,8202u16),(30059u16,8201u16), (30060u16,14049u16),(30061u16,3724u16),(30062u16,19707u16),(30063u16,14048u16), (30064u16,7762u16),(30066u16,3725u16),(30070u16,8617u16),(30071u16,14700u16), (30072u16,8618u16),(30073u16,14699u16),(30074u16,4797u16),(30077u16,15347u16), (30078u16,15933u16),(30079u16,9422u16),(30080u16,16527u16),(30083u16,3032u16), (30084u16,17007u16),(30086u16,10430u16),(30087u16,10429u16),(30090u16,10736u16), (30091u16,5766u16),(30092u16,11983u16),(30093u16,3726u16),(30094u16,19711u16), (30095u16,7763u16),(30096u16,15348u16),(30097u16,9046u16),(30098u16,10947u16), (30100u16,11665u16),(30101u16,11666u16),(30104u16,11984u16),(30105u16,6523u16), (30106u16,6524u16),(30109u16,6522u16),(30110u16,19713u16),(30114u16,6860u16), (30115u16,6861u16),(30116u16,6858u16),(30117u16,6859u16),(30119u16,12368u16), (30122u16,12369u16),(30123u16,6857u16),(30128u16,12814u16),(30129u16,4581u16), (30130u16,7262u16),(30131u16,7263u16),(30132u16,19714u16),(30133u16,7766u16), (30134u16,12820u16),(30136u16,7268u16),(30137u16,7266u16),(30138u16,12821u16), (30139u16,12816u16),(30140u16,7265u16),(30141u16,7264u16),(30142u16,7259u16), (30143u16,12819u16),(30144u16,12818u16),(30145u16,12815u16),(30146u16,7267u16), (30147u16,4871u16),(30148u16,12817u16),(30149u16,7260u16),(30151u16,7261u16), (30152u16,3728u16),(30154u16,7767u16),(30155u16,13408u16),(30156u16,13409u16), (30157u16,7768u16),(30158u16,13405u16),(30159u16,13407u16),(30160u16,13411u16), (30161u16,13410u16),(30162u16,13406u16),(30164u16,7764u16),(30165u16,7765u16), (30167u16,14057u16),(30168u16,8207u16),(30169u16,8206u16),(30170u16,14051u16), (30171u16,8204u16),(30172u16,3729u16),(30173u16,14054u16),(30174u16,8208u16), (30175u16,14055u16),(30176u16,8209u16),(30177u16,14052u16),(30178u16,8203u16), (30179u16,8205u16),(30180u16,14056u16),(30182u16,14053u16),(30183u16,14050u16), (30189u16,14713u16),(30191u16,14702u16),(30192u16,8620u16),(30193u16,8623u16), (30194u16,8622u16),(30195u16,8627u16),(30196u16,8626u16),(30197u16,14714u16), (30198u16,14712u16),(30199u16,14705u16),(30200u16,14709u16),(30201u16,4694u16), (30202u16,8624u16),(30203u16,14711u16),(30204u16,14707u16),(30205u16,14715u16), (30206u16,14706u16),(30207u16,8625u16),(30208u16,8619u16),(30209u16,8621u16), (30210u16,19715u16),(30211u16,14704u16),(30215u16,4866u16),(30216u16,15350u16), (30217u16,9050u16),(30218u16,15354u16),(30219u16,9049u16),(30220u16,15351u16), (30221u16,9048u16),(30223u16,14703u16),(30224u16,14710u16),(30225u16,15353u16), (30227u16,9051u16),(30228u16,15355u16),(30229u16,15352u16),(30230u16,15349u16), (30233u16,15936u16),(30234u16,15940u16),(30235u16,15942u16),(30236u16,15938u16), (30237u16,15937u16),(30238u16,15935u16),(30239u16,9425u16),(30240u16,9423u16), (30241u16,9428u16),(30242u16,9429u16),(30243u16,15939u16),(30244u16,9426u16), (30245u16,15934u16),(30246u16,9427u16),(30247u16,9047u16),(30248u16,15941u16), (30249u16,9424u16),(30252u16,19716u16),(30253u16,16529u16),(30255u16,16528u16), (30256u16,16536u16),(30257u16,16530u16),(30258u16,16535u16),(30259u16,16532u16), (30260u16,9766u16),(30261u16,16534u16),(30264u16,9767u16),(30266u16,9768u16), (30267u16,4519u16),(30268u16,16533u16),(30269u16,16531u16),(30272u16,4680u16), (30274u16,10041u16),(30275u16,17008u16),(30278u16,10040u16),(30279u16,17011u16), (30280u16,17009u16),(30281u16,17010u16),(30284u16,10042u16),(30285u16,3731u16), (30286u16,4521u16),(30287u16,19718u16),(30288u16,17440u16),(30289u16,19717u16), (30290u16,10268u16),(30291u16,17441u16),(30292u16,4690u16),(30294u16,10266u16), (30295u16,17442u16),(30296u16,10267u16),(30297u16,17439u16),(30298u16,17443u16), (30300u16,17437u16),(30303u16,10431u16),(30304u16,17797u16),(30305u16,10432u16), (30306u16,10566u16),(30308u16,17438u16),(30309u16,10567u16),(30310u16,4578u16), (30311u16,4895u16),(30313u16,10659u16),(30314u16,18337u16),(30316u16,10738u16), (30317u16,18515u16),(30318u16,10737u16),(30319u16,19719u16),(30320u16,18662u16), (30321u16,10823u16),(30322u16,10824u16),(30323u16,3038u16),(30324u16,3733u16), (30325u16,18946u16),(30326u16,10948u16),(30328u16,6862u16),(30329u16,12370u16), (30330u16,3735u16),(30331u16,8210u16),(30332u16,8211u16),(30333u16,5767u16), (30334u16,5913u16),(30335u16,11468u16),(30337u16,11667u16),(30338u16,6168u16), (30340u16,6525u16),(30342u16,6863u16),(30343u16,6864u16),(30344u16,6865u16), (30345u16,13413u16),(30346u16,12822u16),(30347u16,7269u16),(30350u16,7769u16), (30351u16,13412u16),(30352u16,19722u16),(30354u16,14059u16),(30355u16,8213u16), (30357u16,14058u16),(30358u16,8212u16),(30361u16,14716u16),(30362u16,9430u16), (30363u16,15946u16),(30364u16,15943u16),(30365u16,15944u16),(30366u16,15945u16), (30369u16,19727u16),(30372u16,17012u16),(30373u16,19728u16),(30374u16,17444u16), (30378u16,18104u16),(30379u16,18103u16),(30381u16,18516u16),(30382u16,5768u16), (30383u16,11985u16),(30384u16,7270u16),(30388u16,8214u16),(30389u16,14717u16), (30391u16,19729u16),(30392u16,15356u16),(30394u16,9431u16),(30395u16,16537u16), (30397u16,17445u16),(30398u16,18105u16),(30399u16,5769u16),(30402u16,6526u16), (30403u16,6868u16),(30404u16,12371u16),(30405u16,6869u16),(30406u16,6867u16), (30408u16,6866u16),(30409u16,12823u16),(30410u16,7271u16),(30412u16,19730u16), (30413u16,7272u16),(30414u16,7273u16),(30418u16,7771u16),(30419u16,13414u16), (30420u16,7770u16),(30422u16,4806u16),(30425u16,1770u16),(30426u16,14060u16), (30427u16,7772u16),(30428u16,8215u16),(30429u16,14718u16),(30430u16,8628u16), (30431u16,8629u16),(30433u16,9052u16),(30435u16,9053u16),(30436u16,9432u16), (30437u16,9770u16),(30438u16,16538u16),(30439u16,9769u16),(30441u16,17013u16), (30442u16,10043u16),(30444u16,17446u16),(30445u16,18106u16),(30446u16,5770u16), (30447u16,6169u16),(30448u16,11988u16),(30449u16,11987u16),(30450u16,6527u16), (30451u16,11986u16),(30452u16,6528u16),(30453u16,11989u16),(30455u16,12377u16), (30456u16,6872u16),(30457u16,6871u16),(30458u16,12379u16),(30459u16,12378u16), (30460u16,6876u16),(30462u16,6875u16),(30465u16,6870u16),(30467u16,12373u16), (30468u16,12374u16),(30469u16,12375u16),(30471u16,6877u16),(30472u16,12372u16), (30473u16,6873u16),(30474u16,12376u16),(30475u16,6874u16),(30476u16,3709u16), (30478u16,3061u16),(30479u16,3062u16),(30480u16,12826u16),(30481u16,12830u16), (30482u16,12828u16),(30483u16,12827u16),(30485u16,12831u16),(30489u16,12832u16), (30490u16,12833u16),(30491u16,12825u16),(30493u16,12824u16),(30494u16,19736u16), (30495u16,7275u16),(30496u16,7276u16),(30498u16,12834u16),(30499u16,12829u16), (30500u16,4962u16),(30501u16,13423u16),(30502u16,19737u16),(30503u16,12835u16), (30504u16,7277u16),(30505u16,7274u16),(30507u16,4974u16),(30509u16,13417u16), (30511u16,13416u16),(30513u16,13418u16),(30514u16,13419u16),(30515u16,13421u16), (30516u16,13420u16),(30517u16,13425u16),(30518u16,7776u16),(30519u16,7773u16), (30520u16,7777u16),(30521u16,13415u16),(30522u16,7778u16),(30523u16,13424u16), (30524u16,7775u16),(30525u16,13422u16),(30526u16,7774u16),(30528u16,19738u16), (30531u16,3742u16),(30532u16,14063u16),(30533u16,14065u16),(30534u16,14061u16), (30535u16,14062u16),(30538u16,14066u16),(30539u16,14068u16),(30540u16,14069u16), (30541u16,14064u16),(30542u16,14067u16),(30543u16,8216u16),(30546u16,14722u16), (30548u16,14727u16),(30549u16,14719u16),(30550u16,14723u16),(30552u16,19741u16), (30553u16,14728u16),(30554u16,14724u16),(30555u16,8630u16),(30556u16,8638u16), (30558u16,8633u16),(30559u16,14720u16),(30560u16,14721u16),(30561u16,9057u16), (30562u16,8641u16),(30563u16,8634u16),(30565u16,8639u16),(30566u16,8632u16), (30567u16,14726u16),(30568u16,8640u16),(30569u16,14725u16),(30570u16,8636u16), (30571u16,8631u16),(30572u16,8637u16),(30573u16,14729u16),(30574u16,15361u16), (30575u16,15363u16),(30578u16,2642u16),(30583u16,2299u16),(30584u16,3059u16), (30585u16,8635u16),(30586u16,1428u16),(30587u16,3063u16),(30588u16,15358u16), (30589u16,9055u16),(30590u16,15364u16),(30591u16,9056u16),(30592u16,15362u16), (30593u16,15357u16),(30594u16,15360u16),(30595u16,15365u16),(30596u16,9054u16), (30597u16,15359u16),(30599u16,9434u16),(30600u16,15950u16),(30601u16,15949u16), (30603u16,9437u16),(30604u16,9435u16),(30605u16,15947u16),(30606u16,9433u16), (30607u16,15948u16),(30609u16,9436u16),(30611u16,2312u16),(30613u16,16546u16), (30615u16,16548u16),(30616u16,3747u16),(30617u16,16547u16),(30618u16,16539u16), (30619u16,16543u16),(30620u16,16542u16),(30621u16,16540u16),(30622u16,9772u16), (30623u16,9773u16),(30624u16,9771u16),(30625u16,16541u16),(30626u16,16544u16), (30627u16,16545u16),(30629u16,9774u16),(30631u16,10048u16),(30632u16,17021u16), (30634u16,10045u16),(30635u16,17015u16),(30636u16,10047u16),(30637u16,10049u16), (30639u16,19743u16),(30640u16,10046u16),(30641u16,17020u16),(30642u16,17016u16), (30643u16,10044u16),(30644u16,17019u16),(30645u16,17014u16),(30646u16,17018u16), (30647u16,17017u16),(30649u16,4522u16),(30650u16,17448u16),(30651u16,10271u16), (30652u16,10272u16),(30653u16,10269u16),(30654u16,3751u16),(30655u16,10270u16), (30658u16,17447u16),(30659u16,3238u16),(30660u16,17800u16),(30661u16,19445u16), (30663u16,10433u16),(30665u16,17798u16),(30666u16,17799u16),(30667u16,3752u16), (30668u16,18107u16),(30669u16,18110u16),(30670u16,18108u16),(30671u16,18109u16), (30672u16,18338u16),(30675u16,10660u16),(30676u16,18663u16),(30677u16,18765u16), (30679u16,4138u16),(30680u16,18833u16),(30681u16,18834u16),(30682u16,10871u16), (30683u16,5771u16),(30684u16,6878u16),(30685u16,1773u16),(30686u16,14070u16), (30688u16,14730u16),(30690u16,5772u16),(30691u16,6170u16),(30693u16,6529u16), (30694u16,19115u16),(30695u16,12380u16),(30696u16,12381u16),(30697u16,7278u16), (30700u16,14071u16),(30701u16,8217u16),(30702u16,8642u16),(30703u16,10050u16), (30704u16,17022u16),(30705u16,17801u16),(30706u16,18111u16),(30707u16,5773u16), (30708u16,19747u16),(30711u16,11995u16),(30712u16,11990u16),(30713u16,11992u16), (30714u16,11994u16),(30715u16,11993u16),(30716u16,11991u16),(30717u16,6530u16), (30718u16,4943u16),(30722u16,6879u16),(30723u16,12390u16),(30725u16,12385u16), (30726u16,12382u16),(30728u16,4408u16),(30729u16,12389u16),(30732u16,6881u16), (30733u16,6882u16),(30734u16,12388u16),(30735u16,12387u16),(30736u16,12386u16), (30737u16,12383u16),(30738u16,12384u16),(30739u16,12391u16),(30740u16,6880u16), (30744u16,3754u16),(30748u16,3756u16),(30749u16,7282u16),(30750u16,3078u16), (30751u16,7288u16),(30752u16,7287u16),(30753u16,12844u16),(30754u16,12838u16), (30755u16,12836u16),(30757u16,7285u16),(30758u16,13432u16),(30759u16,7280u16), (30760u16,12841u16),(30761u16,12845u16),(30762u16,12847u16),(30763u16,12843u16), (30764u16,12837u16),(30765u16,7286u16),(30766u16,12842u16),(30767u16,12840u16), (30768u16,7279u16),(30769u16,12848u16),(30770u16,7289u16),(30771u16,12846u16), (30772u16,7283u16),(30773u16,12839u16),(30775u16,7284u16),(30776u16,7281u16), (30777u16,3758u16),(30780u16,19012u16),(30781u16,3425u16),(30786u16,2999u16), (30787u16,7780u16),(30788u16,3361u16),(30789u16,13433u16),(30791u16,3759u16), (30792u16,13426u16),(30793u16,13428u16),(30794u16,13430u16),(30795u16,3428u16), (30796u16,13431u16),(30797u16,13429u16),(30798u16,7781u16),(30800u16,13434u16), (30801u16,3760u16),(30802u16,13427u16),(30803u16,4873u16),(30804u16,3426u16), (30812u16,14075u16),(30813u16,8218u16),(30814u16,14083u16),(30816u16,14072u16), (30818u16,14084u16),(30820u16,14073u16),(30821u16,14074u16),(30822u16,3761u16), (30824u16,14082u16),(30825u16,14081u16),(30826u16,14078u16),(30827u16,7779u16), (30828u16,8219u16),(30829u16,14076u16),(30830u16,14079u16),(30831u16,8220u16), (30832u16,14080u16),(30833u16,14077u16),(30841u16,14741u16),(30842u16,4683u16), (30843u16,14745u16),(30844u16,8649u16),(30846u16,15371u16),(30847u16,8652u16), (30848u16,14743u16),(30849u16,18956u16),(30851u16,14740u16),(30852u16,14735u16), (30853u16,14737u16),(30854u16,14738u16),(30855u16,14731u16),(30856u16,3080u16), (30857u16,8648u16),(30860u16,8647u16),(30861u16,3079u16),(30862u16,8643u16), (30863u16,14734u16),(30865u16,8650u16),(30867u16,8651u16),(30868u16,14733u16), (30869u16,14736u16),(30870u16,14744u16),(30871u16,8645u16),(30872u16,8646u16), (30873u16,14742u16),(30874u16,14732u16),(30878u16,15373u16),(30879u16,9059u16), (30880u16,15375u16),(30881u16,14739u16),(30882u16,15377u16),(30883u16,9063u16), (30884u16,15378u16),(30885u16,15374u16),(30887u16,9060u16),(30888u16,15370u16), (30889u16,9062u16),(30890u16,15367u16),(30891u16,15372u16),(30892u16,15376u16), (30893u16,15369u16),(30895u16,19752u16),(30896u16,8644u16),(30897u16,19760u16), (30898u16,15366u16),(30899u16,9061u16),(30900u16,15368u16),(30902u16,3427u16), (30904u16,1330u16),(30905u16,3418u16),(30906u16,9440u16),(30907u16,15952u16), (30908u16,9444u16),(30910u16,9442u16),(30913u16,9058u16),(30915u16,15959u16), (30916u16,15960u16),(30917u16,9439u16),(30919u16,19753u16),(30920u16,15958u16), (30921u16,15961u16),(30922u16,9441u16),(30923u16,9438u16),(30924u16,15954u16), (30925u16,15951u16),(30926u16,15956u16),(30927u16,15953u16),(30928u16,9445u16), (30929u16,15955u16),(30930u16,3081u16),(30931u16,19754u16),(30932u16,15957u16), (30933u16,9443u16),(30935u16,19758u16),(30936u16,4863u16),(30938u16,9776u16), (30939u16,16555u16),(30941u16,16549u16),(30942u16,16553u16),(30943u16,16559u16), (30944u16,16560u16),(30945u16,16556u16),(30946u16,16557u16),(30947u16,16554u16), (30948u16,1752u16),(30949u16,16551u16),(30951u16,9778u16),(30952u16,9775u16), (30953u16,16550u16),(30954u16,16552u16),(30956u16,9777u16),(30957u16,16558u16), (30958u16,2929u16),(30959u16,10054u16),(30960u16,3117u16),(30961u16,19176u16), (30962u16,17028u16),(30963u16,17023u16),(30964u16,10053u16),(30965u16,2454u16), (30967u16,10051u16),(30969u16,17030u16),(30970u16,10052u16),(30971u16,17026u16), (30972u16,17027u16),(30973u16,17024u16),(30974u16,17031u16),(30975u16,17449u16), (30977u16,10055u16),(30978u16,17025u16),(30980u16,17032u16),(30981u16,17029u16), (30982u16,4937u16),(30985u16,17453u16),(30988u16,17450u16),(30990u16,10273u16), (30992u16,17454u16),(30993u16,17456u16),(30994u16,17455u16),(30995u16,17451u16), (30996u16,17452u16),(30999u16,17806u16),(31001u16,10434u16),(31003u16,17803u16), (31004u16,17805u16),(31005u16,17802u16),(31006u16,17807u16),(31009u16,17804u16), (31011u16,18113u16),(31012u16,18116u16),(31013u16,18112u16),(31014u16,10568u16), (31015u16,18114u16),(31016u16,18115u16),(31017u16,18117u16),(31018u16,10569u16), (31019u16,10571u16),(31020u16,10570u16),(31021u16,18339u16),(31022u16,19756u16), (31023u16,18341u16),(31025u16,18340u16),(31026u16,3766u16),(31027u16,3764u16), (31028u16,19759u16),(31029u16,18517u16),(31030u16,2134u16),(31032u16,18766u16), (31033u16,18835u16),(31034u16,5774u16),(31035u16,1688u16),(31036u16,19774u16), (31037u16,11668u16),(31038u16,6531u16),(31039u16,11997u16),(31040u16,6532u16), (31041u16,6533u16),(31042u16,11996u16),(31044u16,12396u16),(31045u16,12395u16), (31046u16,6883u16),(31047u16,6886u16),(31048u16,6885u16),(31049u16,6884u16), (31050u16,12392u16),(31051u16,12394u16),(31052u16,12393u16),(31055u16,12851u16), (31056u16,7291u16),(31057u16,12855u16),(31058u16,12854u16),(31059u16,12853u16), (31060u16,12849u16),(31061u16,7290u16),(31062u16,7294u16),(31063u16,7297u16), (31064u16,2238u16),(31065u16,3083u16),(31066u16,7298u16),(31067u16,12850u16), (31068u16,12852u16),(31069u16,7296u16),(31070u16,7295u16),(31071u16,7293u16), (31072u16,7292u16),(31073u16,13441u16),(31074u16,4532u16),(31075u16,13439u16), (31076u16,13435u16),(31077u16,7782u16),(31079u16,13436u16),(31080u16,7783u16), (31081u16,13437u16),(31082u16,13438u16),(31083u16,13440u16),(31085u16,7784u16), (31088u16,14088u16),(31089u16,19352u16),(31090u16,14087u16),(31091u16,14086u16), (31092u16,14085u16),(31097u16,14749u16),(31098u16,8653u16),(31100u16,14746u16), (31101u16,14748u16),(31102u16,4359u16),(31103u16,8654u16),(31104u16,19770u16), (31105u16,8655u16),(31106u16,14747u16),(31107u16,4289u16),(31110u16,19767u16), (31111u16,1359u16),(31112u16,15387u16),(31114u16,15380u16),(31115u16,15381u16), (31117u16,9066u16),(31118u16,9064u16),(31119u16,9065u16),(31120u16,15389u16), (31121u16,3769u16),(31122u16,15388u16),(31123u16,15385u16),(31124u16,15384u16), (31125u16,15383u16),(31126u16,15382u16),(31127u16,15386u16),(31128u16,15379u16), (31129u16,3770u16),(31130u16,15962u16),(31131u16,3087u16),(31132u16,15965u16), (31133u16,19772u16),(31135u16,2629u16),(31136u16,15964u16),(31137u16,15963u16), (31138u16,15966u16),(31140u16,16561u16),(31141u16,3089u16),(31142u16,9779u16), (31143u16,10056u16),(31144u16,17034u16),(31145u16,19775u16),(31146u16,10057u16), (31147u16,17033u16),(31148u16,17458u16),(31149u16,17457u16),(31150u16,10274u16), (31152u16,17808u16),(31153u16,10435u16),(31154u16,18118u16),(31155u16,10739u16), (31156u16,18518u16),(31158u16,18768u16),(31159u16,18767u16),(31160u16,11374u16), (31161u16,6887u16),(31162u16,6888u16),(31163u16,13442u16),(31165u16,8657u16), (31166u16,5775u16),(31167u16,6173u16),(31168u16,6172u16),(31169u16,6171u16), (31172u16,3524u16),(31173u16,11998u16),(31174u16,19779u16),(31176u16,6535u16), (31177u16,6534u16),(31178u16,1851u16),(31179u16,6891u16),(31180u16,19561u16), (31181u16,12398u16),(31182u16,12401u16),(31183u16,12399u16),(31184u16,1023u16), (31185u16,6889u16),(31186u16,6890u16),(31188u16,19781u16),(31189u16,12397u16), (31190u16,12400u16),(31192u16,7305u16),(31196u16,12862u16),(31197u16,12864u16), (31198u16,12863u16),(31199u16,7302u16),(31200u16,12858u16),(31202u16,3408u16), (31203u16,4330u16),(31204u16,7299u16),(31206u16,7303u16),(31207u16,7301u16), (31209u16,7304u16),(31210u16,12861u16),(31211u16,12856u16),(31212u16,12857u16), (31213u16,12860u16),(31214u16,12859u16),(31217u16,3098u16),(31220u16,3093u16), (31222u16,13445u16),(31223u16,13446u16),(31224u16,13444u16),(31226u16,13443u16), (31227u16,7785u16),(31232u16,8225u16),(31234u16,14089u16),(31235u16,14091u16), (31236u16,14093u16),(31237u16,8224u16),(31238u16,3772u16),(31240u16,8222u16), (31242u16,14090u16),(31243u16,8223u16),(31244u16,14092u16),(31245u16,8221u16), (31248u16,14759u16),(31249u16,14750u16),(31250u16,14753u16),(31251u16,14757u16), (31252u16,8661u16),(31253u16,14755u16),(31255u16,14754u16),(31256u16,14751u16), (31257u16,14752u16),(31258u16,8659u16),(31259u16,14758u16),(31260u16,8658u16), (31262u16,8663u16),(31263u16,8662u16),(31264u16,8660u16),(31266u16,14756u16), (31270u16,15395u16),(31272u16,15394u16),(31274u16,1762u16),(31275u16,15390u16), (31276u16,1031u16),(31277u16,4948u16),(31278u16,9067u16),(31279u16,15393u16), (31280u16,15392u16),(31281u16,9068u16),(31282u16,1024u16),(31287u16,9450u16), (31289u16,15969u16),(31290u16,3092u16),(31291u16,9451u16),(31292u16,9447u16), (31293u16,9449u16),(31294u16,4862u16),(31295u16,9446u16),(31296u16,9448u16), (31299u16,2643u16),(31300u16,16562u16),(31301u16,4281u16),(31302u16,9782u16), (31303u16,16564u16),(31304u16,16563u16),(31305u16,2050u16),(31306u16,15391u16), (31307u16,9784u16),(31308u16,9783u16),(31309u16,9780u16),(31310u16,9781u16), (31316u16,17039u16),(31318u16,17037u16),(31319u16,10058u16),(31320u16,17038u16), (31322u16,17040u16),(31323u16,17036u16),(31324u16,17035u16),(31327u16,17459u16), (31328u16,10277u16),(31329u16,10275u16),(31330u16,10276u16),(31333u16,2053u16), (31335u16,17809u16),(31336u16,17810u16),(31337u16,10437u16),(31339u16,10436u16), (31340u16,18120u16),(31341u16,18121u16),(31342u16,18119u16),(31344u16,18519u16), (31345u16,18520u16),(31346u16,1045u16),(31348u16,5776u16),(31349u16,11469u16), (31350u16,6174u16),(31352u16,11999u16),(31353u16,6537u16),(31354u16,6536u16), (31355u16,12000u16),(31357u16,2054u16),(31358u16,12403u16),(31359u16,6892u16), (31360u16,12402u16),(31361u16,6893u16),(31363u16,3976u16),(31364u16,7306u16), (31365u16,12867u16),(31366u16,12865u16),(31367u16,12871u16),(31368u16,7307u16), (31369u16,12866u16),(31370u16,12870u16),(31371u16,12868u16),(31372u16,12869u16), (31375u16,13447u16),(31376u16,13449u16),(31377u16,3775u16),(31378u16,7786u16), (31379u16,1806u16),(31380u16,13448u16),(31381u16,7787u16),(31382u16,8228u16), (31383u16,8227u16),(31384u16,8226u16),(31385u16,14094u16),(31390u16,14762u16), (31391u16,8664u16),(31392u16,8665u16),(31394u16,14761u16),(31395u16,14760u16), (31400u16,15396u16),(31401u16,9070u16),(31402u16,9069u16),(31403u16,15397u16), (31404u16,15398u16),(31406u16,9453u16),(31407u16,9452u16),(31408u16,2057u16), (31409u16,16568u16),(31410u16,15970u16),(31411u16,15972u16),(31412u16,15971u16), (31413u16,16567u16),(31414u16,16565u16),(31415u16,16569u16),(31416u16,16566u16), (31418u16,9785u16),(31419u16,2056u16),(31420u16,3777u16),(31422u16,17041u16), (31423u16,10059u16),(31424u16,17042u16),(31425u16,17043u16),(31426u16,2058u16), (31427u16,2059u16),(31428u16,10278u16),(31429u16,10279u16),(31431u16,10572u16), (31432u16,4005u16),(31433u16,1323u16),(31434u16,10787u16),(31435u16,5777u16), (31439u16,3780u16),(31441u16,12404u16),(31443u16,4860u16),(31448u16,12872u16), (31449u16,7308u16),(31450u16,2063u16),(31451u16,3781u16),(31452u16,2616u16), (31453u16,2064u16),(31455u16,7938u16),(31456u16,7937u16),(31458u16,3110u16), (31459u16,8230u16),(31460u16,14096u16),(31461u16,8229u16),(31462u16,14095u16), (31463u16,2362u16),(31465u16,2316u16),(31466u16,2065u16),(31467u16,14763u16), (31469u16,9071u16),(31470u16,15399u16),(31471u16,9072u16),(31478u16,10573u16), (31479u16,18122u16),(31481u16,5914u16),(31482u16,6538u16),(31483u16,12001u16), (31484u16,1007u16),(31485u16,6895u16),(31486u16,3120u16),(31487u16,6894u16), (31488u16,12405u16),(31489u16,12406u16),(31492u16,12874u16),(31493u16,12876u16), (31494u16,7309u16),(31496u16,12878u16),(31497u16,12881u16),(31498u16,12879u16), (31499u16,2069u16),(31500u16,3159u16),(31502u16,12880u16),(31503u16,12877u16), (31504u16,12873u16),(31505u16,7310u16),(31506u16,12882u16),(31507u16,12875u16), (31508u16,4841u16),(31512u16,13458u16),(31513u16,7793u16),(31514u16,13467u16), (31515u16,7790u16),(31517u16,13460u16),(31518u16,7794u16),(31519u16,4732u16), (31520u16,7788u16),(31522u16,13455u16),(31523u16,13468u16),(31524u16,13456u16), (31525u16,13453u16),(31526u16,7792u16),(31527u16,3155u16),(31528u16,7789u16), (31529u16,2071u16),(31530u16,13459u16),(31531u16,13462u16),(31532u16,7791u16), (31533u16,13463u16),(31534u16,7795u16),(31535u16,13464u16),(31536u16,13454u16), (31537u16,13461u16),(31538u16,13465u16),(31539u16,13457u16),(31540u16,13452u16), (31541u16,13450u16),(31544u16,13466u16),(31545u16,3810u16),(31547u16,14098u16), (31552u16,14103u16),(31554u16,4275u16),(31555u16,4358u16),(31556u16,14099u16), (31557u16,14105u16),(31558u16,8233u16),(31559u16,13451u16),(31560u16,14100u16), (31561u16,8231u16),(31562u16,14097u16),(31563u16,8238u16),(31564u16,14101u16), (31565u16,8237u16),(31566u16,14102u16),(31567u16,8239u16),(31568u16,8234u16), (31569u16,4422u16),(31570u16,8235u16),(31572u16,8236u16),(31573u16,2070u16), (31574u16,8232u16),(31576u16,14104u16),(31584u16,8668u16),(31585u16,14774u16), (31586u16,3784u16),(31587u16,14777u16),(31588u16,14765u16),(31589u16,14770u16), (31590u16,14764u16),(31591u16,8670u16),(31593u16,14768u16),(31596u16,3785u16), (31597u16,14766u16),(31598u16,8669u16),(31599u16,2075u16),(31600u16,14773u16), (31601u16,14772u16),(31602u16,14769u16),(31603u16,14771u16),(31604u16,14767u16), (31605u16,9076u16),(31606u16,14776u16),(31607u16,8666u16),(31608u16,14775u16), (31611u16,3786u16),(31618u16,15415u16),(31620u16,9083u16),(31621u16,15410u16), (31623u16,9082u16),(31624u16,15400u16),(31626u16,15402u16),(31627u16,9075u16), (31628u16,15407u16),(31629u16,15406u16),(31630u16,15409u16),(31631u16,9080u16), (31632u16,15404u16),(31633u16,15403u16),(31634u16,2081u16),(31636u16,9079u16), (31637u16,9074u16),(31638u16,15405u16),(31639u16,9077u16),(31640u16,15411u16), (31641u16,15413u16),(31643u16,15408u16),(31644u16,15401u16),(31645u16,9078u16), (31648u16,9461u16),(31649u16,9073u16),(31650u16,2074u16),(31651u16,4735u16), (31652u16,15414u16),(31660u16,15976u16),(31661u16,9454u16),(31662u16,1052u16), (31663u16,15978u16),(31665u16,9455u16),(31666u16,1651u16),(31668u16,9457u16), (31669u16,15981u16),(31671u16,15973u16),(31672u16,2082u16),(31673u16,15979u16), (31678u16,15975u16),(31680u16,8667u16),(31681u16,9460u16),(31684u16,9456u16), (31685u16,1029u16),(31686u16,9458u16),(31687u16,9459u16),(31689u16,9788u16), (31690u16,15980u16),(31691u16,15974u16),(31692u16,9462u16),(31694u16,15977u16), (31695u16,4739u16),(31696u16,2079u16),(31700u16,16579u16),(31701u16,16574u16), (31704u16,16584u16),(31705u16,9786u16),(31706u16,16576u16),(31707u16,9790u16), (31708u16,16582u16),(31709u16,16573u16),(31710u16,16570u16),(31711u16,16585u16), (31712u16,10065u16),(31713u16,9791u16),(31714u16,16581u16),(31715u16,16571u16), (31716u16,9789u16),(31717u16,16575u16),(31718u16,9793u16),(31719u16,16572u16), (31720u16,16577u16),(31721u16,9792u16),(31722u16,16580u16),(31723u16,16583u16), (31724u16,1807u16),(31728u16,17061u16),(31729u16,17062u16),(31730u16,17046u16), (31731u16,17053u16),(31732u16,17051u16),(31735u16,10063u16),(31736u16,17058u16), (31737u16,16578u16),(31738u16,2087u16),(31739u16,17049u16),(31740u16,4746u16), (31741u16,17059u16),(31742u16,10062u16),(31743u16,17048u16),(31744u16,17047u16), (31745u16,17057u16),(31746u16,17054u16),(31747u16,17056u16),(31749u16,17044u16), (31750u16,2088u16),(31751u16,10060u16),(31753u16,17055u16),(31754u16,17064u16), (31755u16,17052u16),(31756u16,10064u16),(31757u16,10061u16),(31758u16,17050u16), (31759u16,17045u16),(31760u16,17063u16),(31761u16,9787u16),(31762u16,3787u16), (31765u16,19083u16),(31769u16,17462u16),(31771u16,3788u16),(31772u16,17460u16), (31773u16,17466u16),(31774u16,10283u16),(31775u16,17464u16),(31776u16,17463u16), (31777u16,10285u16),(31778u16,17469u16),(31779u16,10284u16),(31781u16,17470u16), (31782u16,17467u16),(31783u16,10281u16),(31784u16,17468u16),(31785u16,17461u16), (31786u16,10282u16),(31787u16,10280u16),(31788u16,17814u16),(31789u16,17465u16), (31792u16,17471u16),(31795u16,17811u16),(31797u16,2089u16),(31799u16,10442u16), (31800u16,10440u16),(31801u16,17813u16),(31803u16,17815u16),(31804u16,17812u16), (31805u16,10441u16),(31806u16,10438u16),(31807u16,10439u16),(31808u16,10443u16), (31810u16,4743u16),(31811u16,10575u16),(31812u16,2091u16),(31813u16,18127u16), (31815u16,18126u16),(31816u16,18124u16),(31817u16,18123u16),(31818u16,18125u16), (31820u16,10574u16),(31821u16,10576u16),(31824u16,10661u16),(31825u16,4910u16), (31827u16,18343u16),(31828u16,18342u16),(31830u16,4710u16),(31831u16,18521u16), (31833u16,18523u16),(31834u16,18525u16),(31835u16,18524u16),(31836u16,18522u16), (31837u16,3122u16),(31839u16,10741u16),(31840u16,10740u16),(31843u16,10789u16), (31844u16,10788u16),(31845u16,10790u16),(31846u16,18665u16),(31847u16,18664u16), (31849u16,18836u16),(31850u16,18769u16),(31851u16,18837u16),(31852u16,10857u16), (31853u16,3123u16),(31854u16,10858u16),(31855u16,18885u16),(31856u16,4801u16), (31858u16,10895u16),(31859u16,5915u16),(31860u16,2100u16),(31861u16,12002u16), (31864u16,12408u16),(31865u16,12409u16),(31866u16,12407u16),(31867u16,3791u16), (31868u16,3132u16),(31869u16,6896u16),(31870u16,4741u16),(31871u16,12410u16), (31872u16,12411u16),(31873u16,12412u16),(31875u16,2092u16),(31876u16,12883u16), (31877u16,12889u16),(31878u16,4744u16),(31880u16,12887u16),(31881u16,7311u16), (31882u16,12885u16),(31884u16,12886u16),(31885u16,12888u16),(31886u16,3131u16), (31889u16,12884u16),(31890u16,7796u16),(31892u16,13469u16),(31893u16,7798u16), (31894u16,13471u16),(31895u16,7797u16),(31896u16,13470u16),(31900u16,3792u16), (31902u16,14107u16),(31903u16,8241u16),(31905u16,14109u16),(31906u16,14106u16), (31907u16,13472u16),(31909u16,8242u16),(31910u16,2094u16),(31911u16,18961u16), (31912u16,14108u16),(31916u16,2405u16),(31918u16,3133u16),(31919u16,14780u16), (31921u16,8671u16),(31922u16,14778u16),(31923u16,8672u16),(31924u16,14779u16), (31925u16,8673u16),(31928u16,3794u16),(31929u16,9084u16),(31930u16,15419u16), (31931u16,15416u16),(31932u16,15418u16),(31933u16,9085u16),(31934u16,9086u16), (31935u16,15417u16),(31938u16,4945u16),(31939u16,1808u16),(31941u16,15982u16), (31943u16,2098u16),(31944u16,15983u16),(31945u16,2097u16),(31946u16,9463u16), (31947u16,15985u16),(31948u16,15984u16),(31949u16,3128u16),(31950u16,2103u16), (31952u16,16589u16),(31953u16,16590u16),(31954u16,16586u16),(31955u16,3688u16), (31956u16,16587u16),(31957u16,9794u16),(31958u16,9795u16),(31959u16,16588u16), (31961u16,10071u16),(31962u16,4947u16),(31964u16,10067u16),(31965u16,10072u16), (31966u16,10068u16),(31967u16,10070u16),(31968u16,10066u16),(31970u16,10069u16), (31974u16,2099u16),(31975u16,10286u16),(31976u16,17065u16),(31978u16,17817u16), (31980u16,17816u16),(31981u16,3796u16),(31982u16,18128u16),(31983u16,10577u16), (31984u16,10578u16),(31985u16,18527u16),(31986u16,18344u16),(31987u16,2101u16), (31988u16,18526u16),(31989u16,2102u16),(31990u16,18838u16),(31991u16,18906u16), (31992u16,5916u16),(31993u16,1689u16),(31995u16,6175u16),(31996u16,1320u16), (31997u16,12003u16),(31998u16,6539u16),(32000u16,6899u16),(32001u16,12415u16), (32002u16,6897u16),(32003u16,12413u16),(32004u16,6902u16),(32005u16,6898u16), (32006u16,6903u16),(32007u16,6901u16),(32008u16,12414u16),(32009u16,6900u16), (32010u16,7315u16),(32011u16,7314u16),(32012u16,12900u16),(32013u16,7323u16), (32014u16,12893u16),(32015u16,12899u16),(32016u16,7319u16),(32017u16,12892u16), (32018u16,12898u16),(32019u16,12896u16),(32020u16,7318u16),(32021u16,7320u16), (32022u16,12895u16),(32023u16,7313u16),(32024u16,12894u16),(32025u16,7324u16), (32026u16,7321u16),(32027u16,7325u16),(32028u16,7322u16),(32029u16,12891u16), (32030u16,12890u16),(32031u16,12897u16),(32032u16,7316u16),(32033u16,7312u16), (32034u16,7317u16),(32037u16,4670u16),(32040u16,13487u16),(32041u16,13480u16), (32043u16,8247u16),(32044u16,13479u16),(32046u16,7802u16),(32047u16,7809u16), (32048u16,7806u16),(32049u16,7812u16),(32050u16,7811u16),(32051u16,7807u16), (32053u16,13473u16),(32054u16,13476u16),(32056u16,13475u16),(32057u16,7803u16), (32058u16,13477u16),(32059u16,13486u16),(32060u16,7804u16),(32061u16,13474u16), (32062u16,13483u16),(32063u16,13484u16),(32064u16,7805u16),(32065u16,13481u16), (32066u16,7810u16),(32067u16,7800u16),(32068u16,7808u16),(32069u16,13478u16), (32070u16,7799u16),(32071u16,13482u16),(32074u16,13485u16),(32077u16,4951u16), (32078u16,14126u16),(32079u16,14117u16),(32080u16,8244u16),(32081u16,14124u16), (32082u16,14121u16),(32083u16,14113u16),(32084u16,14122u16),(32085u16,8246u16), (32086u16,14114u16),(32088u16,14110u16),(32090u16,4555u16),(32091u16,8679u16), (32092u16,14119u16),(32093u16,2107u16),(32094u16,8243u16),(32095u16,14125u16), (32097u16,8250u16),(32098u16,8252u16),(32099u16,14112u16),(32102u16,8251u16), (32103u16,14115u16),(32104u16,8245u16),(32105u16,14123u16),(32106u16,14116u16), (32107u16,14120u16),(32109u16,14118u16),(32110u16,8248u16),(32111u16,14111u16), (32112u16,8253u16),(32113u16,7801u16),(32114u16,8249u16),(32115u16,8254u16), (32121u16,8675u16),(32122u16,14787u16),(32123u16,14789u16),(32124u16,14791u16), (32125u16,14795u16),(32127u16,14785u16),(32128u16,14783u16),(32129u16,8677u16), (32131u16,14790u16),(32132u16,14794u16),(32133u16,14786u16),(32134u16,14782u16), (32136u16,14781u16),(32137u16,2110u16),(32139u16,1781u16),(32140u16,14792u16), (32141u16,14784u16),(32142u16,14788u16),(32143u16,8678u16),(32145u16,8676u16), (32146u16,14796u16),(32147u16,8674u16),(32148u16,14793u16),(32149u16,981u16), (32150u16,15436u16),(32151u16,3142u16),(32156u16,9089u16),(32157u16,15428u16), (32158u16,9476u16),(32159u16,15438u16),(32160u16,9092u16),(32161u16,15442u16), (32162u16,9098u16),(32163u16,15423u16),(32164u16,3672u16),(32166u16,15439u16), (32167u16,15420u16),(32168u16,3475u16),(32169u16,15441u16),(32170u16,15424u16), (32171u16,2111u16),(32172u16,9105u16),(32173u16,9102u16),(32174u16,15440u16), (32175u16,15434u16),(32176u16,9088u16),(32177u16,9096u16),(32178u16,9095u16), (32179u16,2113u16),(32180u16,9094u16),(32181u16,9100u16),(32183u16,15421u16), (32184u16,9101u16),(32185u16,15435u16),(32186u16,9097u16),(32187u16,9087u16), (32188u16,15437u16),(32189u16,9090u16),(32190u16,9091u16),(32191u16,9099u16), (32192u16,15426u16),(32193u16,15425u16),(32194u16,15422u16),(32196u16,15430u16), (32197u16,15427u16),(32198u16,15431u16),(32199u16,9104u16),(32201u16,15443u16), (32202u16,9093u16),(32203u16,15432u16),(32204u16,15433u16),(32205u16,1321u16), (32206u16,15429u16),(32207u16,3800u16),(32208u16,3802u16),(32210u16,2114u16), (32211u16,3137u16),(32212u16,3801u16),(32215u16,15990u16),(32216u16,9468u16), (32217u16,9477u16),(32218u16,9473u16),(32219u16,15987u16),(32220u16,3135u16), (32221u16,9470u16),(32222u16,9474u16),(32223u16,15999u16),(32224u16,9464u16), (32225u16,15991u16),(32227u16,9472u16),(32228u16,2117u16),(32229u16,2121u16), (32230u16,15994u16),(32231u16,15989u16),(32232u16,9471u16),(32233u16,9475u16), (32234u16,15988u16),(32236u16,9469u16),(32238u16,15998u16),(32239u16,9466u16), (32240u16,15997u16),(32241u16,15996u16),(32242u16,9478u16),(32243u16,15750u16), (32244u16,9465u16),(32245u16,2119u16),(32246u16,15995u16),(32247u16,15986u16), (32249u16,9479u16),(32250u16,15993u16),(32251u16,9467u16),(32253u16,3803u16), (32254u16,3526u16),(32259u16,15992u16),(32263u16,3136u16),(32264u16,9798u16), (32265u16,9803u16),(32266u16,9796u16),(32267u16,16603u16),(32268u16,16594u16), (32269u16,16606u16),(32270u16,16598u16),(32271u16,16604u16),(32272u16,9804u16), (32273u16,9797u16),(32274u16,16591u16),(32275u16,16597u16),(32276u16,16607u16), (32277u16,16600u16),(32278u16,16605u16),(32279u16,16593u16),(32282u16,16601u16), (32283u16,9799u16),(32284u16,16599u16),(32285u16,2123u16),(32286u16,9801u16), (32287u16,16595u16),(32288u16,16596u16),(32289u16,16592u16),(32290u16,16602u16), (32291u16,9800u16),(32292u16,16609u16),(32293u16,16608u16),(32295u16,2130u16), (32297u16,17076u16),(32298u16,17072u16),(32299u16,10079u16),(32301u16,17066u16), (32302u16,10073u16),(32303u16,10089u16),(32304u16,17078u16),(32305u16,10081u16), (32306u16,10077u16),(32307u16,17069u16),(32308u16,10084u16),(32309u16,10087u16), (32310u16,17080u16),(32311u16,10076u16),(32312u16,17071u16),(32313u16,10085u16), (32314u16,17082u16),(32315u16,17079u16),(32316u16,17067u16),(32317u16,10080u16), (32318u16,10074u16),(32319u16,10088u16),(32320u16,17074u16),(32321u16,10083u16), (32322u16,17068u16),(32323u16,10078u16),(32324u16,17081u16),(32325u16,10082u16), (32326u16,10075u16),(32327u16,17075u16),(32328u16,10086u16),(32329u16,17073u16), (32332u16,17077u16),(32336u16,17473u16),(32337u16,17479u16),(32338u16,10292u16), (32339u16,17482u16),(32340u16,10287u16),(32341u16,10288u16),(32342u16,17474u16), (32343u16,17481u16),(32344u16,17476u16),(32345u16,10293u16),(32346u16,10290u16), (32347u16,1849u16),(32348u16,17472u16),(32350u16,10289u16),(32351u16,17478u16), (32352u16,17480u16),(32353u16,10291u16),(32354u16,17477u16),(32355u16,17475u16), (32357u16,3665u16),(32359u16,2104u16),(32360u16,17827u16),(32361u16,10447u16), (32362u16,10448u16),(32363u16,10444u16),(32364u16,1809u16),(32365u16,10445u16), (32366u16,2126u16),(32367u16,17823u16),(32368u16,17821u16),(32370u16,17825u16), (32371u16,10450u16),(32372u16,17826u16),(32373u16,17819u16),(32374u16,17818u16), (32375u16,17822u16),(32376u16,17820u16),(32377u16,10446u16),(32378u16,17824u16), (32379u16,18129u16),(32380u16,10581u16),(32381u16,10580u16),(32382u16,18130u16), (32383u16,4464u16),(32384u16,18132u16),(32385u16,18131u16),(32386u16,10582u16), (32390u16,18349u16),(32391u16,4141u16),(32392u16,18347u16),(32394u16,18345u16), (32395u16,18348u16),(32396u16,10663u16),(32397u16,18350u16),(32398u16,4631u16), (32399u16,10662u16),(32401u16,18528u16),(32402u16,2127u16),(32403u16,10791u16), (32404u16,10793u16),(32405u16,18666u16),(32406u16,10792u16),(32407u16,18770u16), (32408u16,18840u16),(32409u16,18842u16),(32410u16,18839u16),(32411u16,18841u16), (32412u16,10877u16),(32415u16,4444u16),(32420u16,1302u16),(32428u16,1303u16), (32442u16,1304u16),(32455u16,1305u16),(32463u16,1306u16),(32479u16,1307u16), (32518u16,1308u16),(32566u16,5917u16),(32567u16,1309u16),(32568u16,6904u16), (32569u16,12764u16),(32570u16,7326u16),(32573u16,7813u16),(32574u16,14127u16), (32575u16,14128u16),(32576u16,2131u16),(32577u16,2132u16),(32579u16,16610u16), (32580u16,10090u16),(32581u16,17083u16),(32583u16,2133u16),(32584u16,10294u16), (32585u16,4507u16),(32586u16,17829u16),(32587u16,17828u16),(32588u16,10583u16), (32589u16,18351u16),(32590u16,3138u16),(32591u16,18529u16),(32592u16,10826u16), (32593u16,11470u16),(32594u16,1687u16),(32595u16,1690u16),(32596u16,6540u16), (32597u16,6176u16),(32600u16,12416u16),(32603u16,12906u16),(32604u16,12901u16), (32605u16,12905u16),(32606u16,12903u16),(32607u16,7327u16),(32608u16,12904u16), (32609u16,12902u16),(32611u16,13488u16),(32613u16,14129u16),(32614u16,14130u16), (32615u16,14799u16),(32616u16,14800u16),(32617u16,8681u16),(32618u16,8682u16), (32619u16,14798u16),(32620u16,14801u16),(32621u16,14797u16),(32622u16,8680u16), (32624u16,9106u16),(32625u16,4995u16),(32626u16,8683u16),(32627u16,15444u16), (32629u16,9480u16),(32630u16,16000u16),(32631u16,9481u16),(32632u16,4845u16), (32633u16,9805u16),(32634u16,16613u16),(32635u16,16611u16),(32636u16,16612u16), (32637u16,17086u16),(32638u16,17085u16),(32639u16,17084u16),(32643u16,17830u16), (32645u16,10449u16),(32646u16,17831u16),(32647u16,18530u16),(32648u16,10827u16), (32649u16,18771u16),(32650u16,5918u16),(32651u16,6542u16),(32652u16,6541u16), (32653u16,12418u16),(32654u16,6905u16),(32655u16,19538u16),(32657u16,12417u16), (32658u16,12908u16),(32659u16,1546u16),(32660u16,7328u16),(32661u16,13489u16), (32662u16,12907u16),(32663u16,2137u16),(32666u16,7815u16),(32667u16,13492u16), (32668u16,13490u16),(32669u16,13491u16),(32670u16,7814u16),(32672u16,14132u16), (32673u16,14133u16),(32674u16,14131u16),(32675u16,2139u16),(32676u16,8686u16), (32677u16,14803u16),(32678u16,14802u16),(32679u16,14804u16),(32680u16,8685u16), (32681u16,8684u16),(32684u16,16001u16),(32685u16,16003u16),(32686u16,3804u16), (32687u16,9482u16),(32688u16,16002u16),(32689u16,16614u16),(32690u16,9806u16), (32691u16,17484u16),(32692u16,3805u16),(32693u16,17483u16),(32694u16,10451u16), (32695u16,17832u16),(32696u16,10453u16),(32697u16,10452u16),(32698u16,18133u16), (32699u16,18352u16),(32700u16,10664u16),(32701u16,5919u16),(32702u16,12419u16), (32703u16,6906u16),(32704u16,12911u16),(32705u16,7330u16),(32706u16,12910u16), (32707u16,12909u16),(32709u16,7329u16),(32711u16,13498u16),(32713u16,13500u16), (32714u16,13493u16),(32715u16,13494u16),(32716u16,7816u16),(32717u16,13495u16), (32718u16,7817u16),(32719u16,13499u16),(32720u16,13496u16),(32721u16,13497u16), (32722u16,7818u16),(32724u16,8256u16),(32725u16,8257u16),(32727u16,14134u16), (32731u16,14805u16),(32732u16,14806u16),(32733u16,3154u16),(32734u16,15448u16), (32735u16,9109u16),(32736u16,9107u16),(32737u16,9108u16),(32738u16,15445u16), (32739u16,15446u16),(32741u16,15447u16),(32742u16,16008u16),(32743u16,3692u16), (32744u16,16009u16),(32745u16,9483u16),(32746u16,16006u16),(32747u16,16005u16), (32748u16,16007u16),(32749u16,16004u16),(32750u16,9809u16),(32751u16,16615u16), (32752u16,9807u16),(32753u16,9808u16),(32754u16,17088u16),(32755u16,10091u16), (32756u16,17087u16),(32757u16,17340u16),(32759u16,17485u16),(32760u16,17486u16), (32761u16,10295u16),(32762u16,2146u16),(32763u16,10296u16),(32764u16,10092u16), (32765u16,17833u16),(32766u16,17834u16),(32767u16,18134u16),(32768u16,10584u16), (32769u16,5920u16),(32770u16,1695u16),(32771u16,5921u16),(32772u16,6907u16), (32773u16,2148u16),(32774u16,7331u16),(32775u16,12420u16),(32776u16,2149u16), (32779u16,8258u16),(32780u16,5922u16),(32781u16,6909u16),(32782u16,12421u16), (32783u16,12422u16),(32784u16,6908u16),(32785u16,6910u16),(32786u16,5923u16), (32788u16,12423u16),(32789u16,7333u16),(32790u16,12912u16),(32791u16,7335u16), (32792u16,7332u16),(32793u16,7334u16),(32795u16,13503u16),(32796u16,7819u16), (32797u16,2150u16),(32798u16,13502u16),(32799u16,13501u16),(32800u16,3808u16), (32801u16,14807u16),(32804u16,15449u16),(32805u16,3809u16),(32806u16,9484u16), (32808u16,2151u16),(32809u16,16617u16),(32810u16,16616u16),(32812u16,17089u16), (32814u16,3811u16),(32815u16,2152u16),(32816u16,18353u16),(32817u16,3812u16), (32819u16,5924u16),(32820u16,11669u16),(32821u16,12004u16),(32822u16,6911u16), (32823u16,12424u16),(32825u16,12914u16),(32827u16,2155u16),(32828u16,2156u16), (32829u16,7336u16),(32830u16,12913u16),(32831u16,7337u16),(32835u16,13505u16), (32838u16,7821u16),(32839u16,13504u16),(32840u16,13506u16),(32842u16,7820u16), (32847u16,14136u16),(32848u16,14137u16),(32849u16,14135u16),(32850u16,8259u16), (32852u16,3813u16),(32854u16,8687u16),(32856u16,8688u16),(32858u16,9111u16), (32859u16,4959u16),(32860u16,15451u16),(32861u16,15450u16),(32862u16,9110u16), (32865u16,2157u16),(32866u16,4957u16),(32867u16,4950u16),(32868u16,16010u16), (32870u16,4949u16),(32871u16,16011u16),(32876u16,16618u16),(32879u16,10096u16), (32880u16,10095u16),(32881u16,10093u16),(32882u16,10094u16),(32883u16,10097u16), (32885u16,17487u16),(32886u16,10298u16),(32887u16,10297u16),(32888u16,17835u16), (32889u16,18135u16),(32893u16,10743u16),(32894u16,10742u16),(32895u16,5925u16), (32896u16,1696u16),(32898u16,12713u16),(32900u16,8690u16),(32901u16,8260u16), (32902u16,8689u16),(32903u16,9112u16),(32905u16,5926u16),(32906u16,11375u16), (32907u16,5927u16),(32908u16,5928u16),(32911u16,12005u16),(32912u16,11672u16), (32914u16,11673u16),(32915u16,6178u16),(32917u16,11670u16),(32918u16,6177u16), (32920u16,6180u16),(32921u16,11671u16),(32922u16,6182u16),(32923u16,6181u16), (32924u16,11674u16),(32925u16,6179u16),(32927u16,1339u16),(32929u16,6548u16), (32930u16,6546u16),(32931u16,12007u16),(32933u16,6545u16),(32935u16,2164u16), (32937u16,6550u16),(32938u16,6552u16),(32939u16,6549u16),(32941u16,12010u16), (32942u16,12006u16),(32943u16,6553u16),(32945u16,6547u16),(32946u16,6183u16), (32948u16,6551u16),(32949u16,12009u16),(32950u16,4582u16),(32951u16,3817u16), (32952u16,12008u16),(32954u16,6544u16),(32956u16,1332u16),(32957u16,4530u16), (32962u16,12430u16),(32963u16,6915u16),(32964u16,6916u16),(32965u16,12432u16), (32966u16,3177u16),(32967u16,12426u16),(32968u16,12429u16),(32969u16,12438u16), (32970u16,12436u16),(32972u16,6917u16),(32973u16,12442u16),(32974u16,6920u16), (32975u16,12439u16),(32976u16,12431u16),(32977u16,12428u16),(32980u16,14139u16), (32981u16,12437u16),(32982u16,6912u16),(32983u16,12440u16),(32984u16,12425u16), (32985u16,12434u16),(32986u16,6914u16),(32987u16,6919u16),(32988u16,12435u16), (32989u16,6923u16),(32990u16,6921u16),(32992u16,12427u16),(32993u16,6918u16), (32995u16,12433u16),(32996u16,6922u16),(32997u16,6913u16),(32998u16,12441u16), (33001u16,3818u16),(33004u16,1598u16),(33005u16,7342u16),(33007u16,7351u16), (33008u16,7340u16),(33009u16,7338u16),(33010u16,12916u16),(33011u16,7346u16), (33012u16,7343u16),(33013u16,12918u16),(33014u16,1335u16),(33016u16,7345u16), (33017u16,12917u16),(33018u16,12915u16),(33019u16,12920u16),(33020u16,7350u16), (33021u16,7348u16),(33022u16,14138u16),(33024u16,12921u16),(33025u16,12919u16), (33026u16,7339u16),(33027u16,4961u16),(33029u16,7341u16),(33030u16,7344u16), (33031u16,2166u16),(33032u16,7347u16),(33033u16,3178u16),(33034u16,7349u16), (33036u16,3820u16),(33038u16,3822u16),(33042u16,3823u16),(33044u16,3825u16), (33045u16,13516u16),(33046u16,7823u16),(33047u16,4516u16),(33048u16,13507u16), (33049u16,13509u16),(33050u16,2167u16),(33051u16,13510u16),(33053u16,13518u16), (33054u16,13514u16),(33055u16,13512u16),(33057u16,13515u16),(33058u16,13519u16), (33059u16,7824u16),(33060u16,7828u16),(33061u16,13508u16),(33063u16,13517u16), (33065u16,7826u16),(33066u16,2854u16),(33067u16,7825u16),(33068u16,13513u16), (33069u16,13511u16),(33071u16,7822u16),(33072u16,7827u16),(33074u16,4528u16), (33076u16,1601u16),(33079u16,3175u16),(33081u16,8266u16),(33082u16,14147u16), (33085u16,14145u16),(33086u16,8268u16),(33090u16,3179u16),(33091u16,14140u16), (33092u16,14821u16),(33094u16,8267u16),(33095u16,14144u16),(33096u16,4525u16), (33098u16,14141u16),(33099u16,8263u16),(33100u16,8269u16),(33101u16,14146u16), (33102u16,8265u16),(33103u16,14143u16),(33104u16,9113u16),(33105u16,8264u16), (33106u16,14142u16),(33107u16,8270u16),(33108u16,8262u16),(33109u16,8261u16), (33110u16,3828u16),(33113u16,3829u16),(33114u16,3830u16),(33115u16,14813u16), (33116u16,14811u16),(33118u16,14817u16),(33120u16,14809u16),(33121u16,14822u16), (33122u16,14814u16),(33124u16,14808u16),(33125u16,8694u16),(33126u16,8700u16), (33127u16,14819u16),(33129u16,14812u16),(33131u16,8697u16),(33132u16,1880u16), (33133u16,1597u16),(33134u16,8695u16),(33135u16,14820u16),(33136u16,8692u16), (33137u16,8691u16),(33138u16,14815u16),(33139u16,8696u16),(33140u16,8271u16), (33142u16,14818u16),(33143u16,14810u16),(33144u16,8693u16),(33145u16,8698u16), (33146u16,8699u16),(33148u16,3833u16),(33151u16,9118u16),(33152u16,9114u16), (33154u16,9119u16),(33155u16,15454u16),(33156u16,3834u16),(33158u16,15453u16), (33159u16,15455u16),(33160u16,9116u16),(33161u16,15452u16),(33162u16,9117u16), (33163u16,15458u16),(33164u16,15457u16),(33165u16,15456u16),(33167u16,9115u16), (33171u16,3836u16),(33173u16,16015u16),(33175u16,16018u16),(33176u16,9490u16), (33177u16,16017u16),(33178u16,9489u16),(33179u16,9485u16),(33180u16,9486u16), (33181u16,9487u16),(33182u16,16014u16),(33183u16,16013u16),(33184u16,9488u16), (33186u16,16016u16),(33187u16,16012u16),(33189u16,3838u16),(33190u16,16620u16), (33191u16,16630u16),(33192u16,9813u16),(33193u16,9812u16),(33194u16,1505u16), (33195u16,16624u16),(33196u16,16626u16),(33198u16,16621u16),(33200u16,16625u16), (33201u16,16619u16),(33202u16,16628u16),(33203u16,9811u16),(33204u16,16627u16), (33205u16,16623u16),(33206u16,4586u16),(33207u16,16629u16),(33209u16,16622u16), (33210u16,10100u16),(33211u16,17090u16),(33212u16,17096u16),(33213u16,10104u16), (33214u16,10106u16),(33215u16,10103u16),(33216u16,10102u16),(33217u16,3840u16), (33218u16,10101u16),(33219u16,10099u16),(33220u16,17091u16),(33221u16,17094u16), (33222u16,10098u16),(33223u16,17095u16),(33224u16,4969u16),(33225u16,10105u16), (33226u16,17093u16),(33228u16,17092u16),(33229u16,10299u16),(33231u16,10300u16), (33232u16,17490u16),(33233u16,17488u16),(33234u16,17489u16),(33237u16,17837u16), (33239u16,17836u16),(33240u16,10454u16),(33241u16,18137u16),(33242u16,10585u16), (33243u16,18136u16),(33245u16,18354u16),(33246u16,18531u16),(33247u16,10744u16), (33248u16,18843u16),(33249u16,18844u16),(33250u16,10794u16),(33251u16,5929u16), (33252u16,3841u16),(33253u16,6554u16),(33254u16,14148u16),(33255u16,9120u16), (33256u16,10107u16),(33257u16,17097u16),(33258u16,5930u16),(33260u16,7353u16), (33261u16,7352u16),(33262u16,14149u16),(33263u16,19723u16),(33266u16,16631u16), (33267u16,5931u16),(33268u16,6924u16),(33270u16,3707u16),(33271u16,14150u16), (33272u16,14151u16),(33273u16,14152u16),(33274u16,9121u16),(33275u16,9814u16), (33276u16,5932u16),(33278u16,6555u16),(33279u16,12443u16),(33280u16,7354u16), (33281u16,12922u16),(33282u16,7829u16),(33284u16,14153u16),(33285u16,8701u16), (33287u16,9122u16),(33288u16,9815u16),(33289u16,10108u16),(33290u16,10301u16), (33291u16,18138u16),(33292u16,5933u16),(33293u16,6556u16),(33296u16,7355u16), (33297u16,13520u16),(33298u16,8272u16),(33300u16,9123u16),(33301u16,15459u16), (33302u16,16019u16),(33304u16,2175u16),(33306u16,4955u16),(33307u16,5934u16), (33308u16,8273u16),(33309u16,14823u16),(33310u16,9124u16),(33311u16,5935u16), (33312u16,12011u16),(33313u16,12444u16),(33314u16,6925u16),(33317u16,12924u16), (33318u16,19523u16),(33320u16,7358u16),(33321u16,2181u16),(33322u16,7356u16), (33323u16,7357u16),(33324u16,7359u16),(33325u16,4646u16),(33327u16,12923u16), (33330u16,13525u16),(33331u16,13522u16),(33332u16,13524u16),(33333u16,7830u16), (33334u16,7832u16),(33335u16,7831u16),(33336u16,13521u16),(33337u16,7833u16), (33338u16,13523u16),(33340u16,14154u16),(33341u16,14155u16),(33342u16,1352u16), (33343u16,14156u16),(33344u16,14826u16),(33346u16,14827u16),(33348u16,14825u16), (33349u16,14828u16),(33351u16,8702u16),(33353u16,14824u16),(33355u16,9125u16), (33358u16,16024u16),(33359u16,16020u16),(33360u16,16023u16),(33361u16,16025u16), (33362u16,16022u16),(33363u16,16021u16),(33364u16,3842u16),(33365u16,16632u16), (33366u16,16633u16),(33367u16,16634u16),(33368u16,9816u16),(33369u16,9817u16), (33370u16,17099u16),(33371u16,17098u16),(33372u16,17100u16),(33374u16,17492u16), (33375u16,17491u16),(33377u16,17839u16),(33378u16,3183u16),(33379u16,17840u16), (33380u16,17838u16),(33381u16,3184u16),(33382u16,10586u16),(33384u16,18139u16), (33385u16,18140u16),(33387u16,18532u16),(33388u16,18667u16),(33389u16,18772u16), (33390u16,5936u16),(33391u16,6184u16),(33393u16,10109u16),(33394u16,5937u16), (33396u16,13526u16),(33397u16,14157u16),(33398u16,3845u16),(33399u16,10834u16), (33400u16,11471u16),(33401u16,3778u16),(33402u16,1310u16),(33403u16,2206u16), (33404u16,11472u16),(33405u16,11474u16),(33406u16,5938u16),(33407u16,11475u16), (33408u16,11473u16),(33411u16,11682u16),(33412u16,11683u16),(33413u16,11677u16), (33415u16,19294u16),(33418u16,11681u16),(33419u16,6186u16),(33421u16,6187u16), (33422u16,11678u16),(33423u16,11676u16),(33424u16,11675u16),(33425u16,11679u16), (33426u16,6185u16),(33427u16,11680u16),(33428u16,12445u16),(33432u16,12016u16), (33433u16,6559u16),(33434u16,12015u16),(33435u16,12017u16),(33437u16,6558u16), (33438u16,12022u16),(33439u16,6562u16),(33440u16,12012u16),(33441u16,12026u16), (33442u16,12032u16),(33443u16,6569u16),(33444u16,12029u16),(33445u16,6566u16), (33446u16,3844u16),(33447u16,12019u16),(33448u16,12025u16),(33449u16,12027u16), (33450u16,2194u16),(33451u16,12014u16),(33452u16,6565u16),(33453u16,6560u16), (33454u16,12020u16),(33455u16,6567u16),(33456u16,6570u16),(33457u16,6564u16), (33459u16,6557u16),(33460u16,12024u16),(33461u16,12018u16),(33462u16,12031u16), (33463u16,6572u16),(33464u16,6568u16),(33465u16,6563u16),(33466u16,12023u16), (33467u16,7360u16),(33468u16,12021u16),(33469u16,6561u16),(33470u16,6571u16), (33471u16,1837u16),(33472u16,12013u16),(33474u16,12028u16),(33475u16,12030u16), (33476u16,1588u16),(33482u16,3846u16),(33487u16,1311u16),(33488u16,2199u16), (33489u16,6942u16),(33490u16,6936u16),(33491u16,6944u16),(33492u16,6941u16), (33493u16,12452u16),(33494u16,12455u16),(33495u16,6937u16),(33496u16,3847u16), (33497u16,12446u16),(33499u16,6930u16),(33500u16,6940u16),(33502u16,6943u16), (33503u16,6945u16),(33504u16,12467u16),(33505u16,12458u16),(33506u16,2207u16), (33507u16,6929u16),(33508u16,12466u16),(33509u16,6933u16),(33510u16,6931u16), (33511u16,6926u16),(33512u16,12450u16),(33514u16,12465u16),(33515u16,12454u16), (33516u16,12457u16),(33517u16,12470u16),(33518u16,19010u16),(33519u16,6946u16), (33520u16,12464u16),(33521u16,6938u16),(33522u16,12459u16),(33523u16,12469u16), (33524u16,12456u16),(33525u16,12460u16),(33526u16,12463u16),(33527u16,4526u16), (33528u16,1810u16),(33529u16,12448u16),(33530u16,12468u16),(33531u16,12462u16), (33532u16,19289u16),(33533u16,4102u16),(33534u16,12447u16),(33535u16,3848u16), (33536u16,12451u16),(33537u16,6939u16),(33538u16,6934u16),(33539u16,6927u16), (33540u16,6932u16),(33541u16,6928u16),(33542u16,6947u16),(33543u16,12449u16), (33544u16,12941u16),(33545u16,6935u16),(33547u16,4593u16),(33548u16,12461u16), (33549u16,12090u16),(33558u16,12944u16),(33559u16,7374u16),(33560u16,2208u16), (33561u16,12928u16),(33562u16,2200u16),(33563u16,12939u16),(33564u16,12935u16), (33565u16,2215u16),(33566u16,12954u16),(33568u16,12946u16),(33570u16,12936u16), (33572u16,12945u16),(33573u16,12930u16),(33574u16,12934u16),(33575u16,12957u16), (33576u16,7377u16),(33577u16,12949u16),(33578u16,12940u16),(33579u16,7361u16), (33580u16,12955u16),(33581u16,12926u16),(33583u16,12948u16),(33585u16,7376u16), (33586u16,7371u16),(33587u16,12925u16),(33588u16,7369u16),(33589u16,7368u16), (33590u16,7373u16),(33591u16,12947u16),(33592u16,7365u16),(33593u16,7372u16), (33594u16,12453u16),(33595u16,14158u16),(33596u16,12942u16),(33597u16,3617u16), (33599u16,12932u16),(33600u16,7375u16),(33601u16,12933u16),(33602u16,12937u16), (33603u16,7378u16),(33604u16,12927u16),(33605u16,12951u16),(33607u16,12950u16), (33608u16,12958u16),(33609u16,7367u16),(33610u16,7364u16),(33611u16,12956u16), (33612u16,12952u16),(33613u16,12943u16),(33614u16,12938u16),(33615u16,7370u16), (33616u16,7366u16),(33617u16,12929u16),(33618u16,7362u16),(33619u16,12953u16), (33620u16,7363u16),(33622u16,12931u16),(33623u16,3850u16),(33634u16,2188u16), (33635u16,19489u16),(33638u16,4346u16),(33647u16,1312u16),(33651u16,13532u16), (33652u16,13534u16),(33653u16,13539u16),(33654u16,13559u16),(33655u16,7847u16), (33656u16,7837u16),(33658u16,13531u16),(33659u16,7848u16),(33660u16,7849u16), (33661u16,13542u16),(33662u16,13549u16),(33663u16,13555u16),(33665u16,13536u16), (33667u16,13543u16),(33669u16,2217u16),(33670u16,7850u16),(33671u16,13557u16), (33672u16,13552u16),(33673u16,7845u16),(33674u16,7843u16),(33675u16,13548u16), (33676u16,13544u16),(33677u16,13530u16),(33678u16,7834u16),(33679u16,13535u16), (33680u16,13527u16),(33681u16,2245u16),(33682u16,7842u16),(33683u16,7844u16), (33684u16,13540u16),(33685u16,13537u16),(33686u16,7839u16),(33687u16,13553u16), (33688u16,7836u16),(33689u16,13538u16),(33690u16,13560u16),(33691u16,13546u16), (33692u16,2076u16),(33693u16,13545u16),(33694u16,7835u16),(33696u16,7846u16), (33698u16,7838u16),(33699u16,13528u16),(33700u16,13533u16),(33701u16,13550u16), (33702u16,13556u16),(33703u16,7851u16),(33704u16,13529u16),(33705u16,13541u16), (33706u16,13547u16),(33707u16,7841u16),(33708u16,2220u16),(33710u16,13558u16), (33711u16,13551u16),(33712u16,13554u16),(33721u16,19679u16),(33725u16,7840u16), (33726u16,4810u16),(33727u16,14174u16),(33728u16,14162u16),(33729u16,2221u16), (33730u16,14191u16),(33731u16,14199u16),(33732u16,14202u16),(33733u16,8279u16), (33734u16,14170u16),(33735u16,14195u16),(33736u16,14171u16),(33737u16,14185u16), (33738u16,8292u16),(33739u16,14181u16),(33740u16,8289u16),(33741u16,19071u16), (33742u16,14182u16),(33743u16,4294u16),(33745u16,14196u16),(33747u16,2222u16), (33748u16,8298u16),(33749u16,14193u16),(33750u16,14183u16),(33751u16,14204u16), (33752u16,14178u16),(33753u16,14860u16),(33755u16,14207u16),(33756u16,8296u16), (33757u16,14176u16),(33758u16,14188u16),(33759u16,8299u16),(33760u16,8278u16), (33761u16,14180u16),(33762u16,14205u16),(33763u16,14173u16),(33764u16,14166u16), (33765u16,14177u16),(33767u16,14165u16),(33768u16,14163u16),(33769u16,8274u16), (33770u16,14197u16),(33771u16,14172u16),(33772u16,14200u16),(33773u16,3619u16), (33774u16,14201u16),(33775u16,8282u16),(33776u16,8287u16),(33777u16,8283u16), (33778u16,8291u16),(33779u16,14192u16),(33780u16,8284u16),(33781u16,14184u16), (33782u16,14168u16),(33784u16,8276u16),(33785u16,14160u16),(33786u16,14194u16), (33787u16,14203u16),(33788u16,14167u16),(33789u16,8290u16),(33790u16,14208u16), (33791u16,14179u16),(33793u16,14175u16),(33795u16,8275u16),(33796u16,8295u16), (33797u16,3853u16),(33798u16,14190u16),(33799u16,8297u16),(33801u16,14186u16), (33802u16,8286u16),(33803u16,8280u16),(33804u16,8288u16),(33805u16,8277u16), (33806u16,8294u16),(33807u16,2244u16),(33808u16,14169u16),(33809u16,14189u16), (33810u16,14164u16),(33811u16,14198u16),(33812u16,3334u16),(33814u16,19041u16), (33816u16,4529u16),(33819u16,14206u16),(33820u16,4587u16),(33824u16,3403u16), (33825u16,2080u16),(33827u16,14161u16),(33828u16,19364u16),(33830u16,3673u16), (33833u16,14859u16),(33835u16,14881u16),(33836u16,8656u16),(33837u16,14864u16), (33838u16,19555u16),(33839u16,14862u16),(33840u16,14841u16),(33841u16,8706u16), (33842u16,14857u16),(33843u16,14877u16),(33844u16,14853u16),(33845u16,8714u16), (33846u16,14876u16),(33847u16,14851u16),(33848u16,8293u16),(33849u16,14867u16), (33850u16,14852u16),(33851u16,14874u16),(33852u16,8713u16),(33853u16,8705u16), (33854u16,3608u16),(33855u16,14830u16),(33856u16,14838u16),(33858u16,14863u16), (33859u16,14855u16),(33860u16,14880u16),(33861u16,14858u16),(33862u16,8719u16), (33863u16,14875u16),(33864u16,3762u16),(33865u16,8710u16),(33866u16,2236u16), (33867u16,14861u16),(33868u16,14869u16),(33869u16,14842u16),(33870u16,14868u16), (33872u16,14885u16),(33873u16,14837u16),(33874u16,14870u16),(33875u16,3186u16), (33876u16,14883u16),(33877u16,2674u16),(33878u16,14831u16),(33879u16,8285u16), (33880u16,2230u16),(33881u16,14845u16),(33882u16,14844u16),(33883u16,8712u16), (33884u16,4664u16),(33885u16,14848u16),(33886u16,14850u16),(33887u16,14865u16), (33888u16,14882u16),(33889u16,8715u16),(33890u16,19732u16),(33891u16,8716u16), (33892u16,3855u16),(33893u16,14836u16),(33894u16,8708u16),(33895u16,14840u16), (33896u16,14878u16),(33897u16,8717u16),(33899u16,8709u16),(33900u16,8711u16), (33901u16,8718u16),(33902u16,14884u16),(33903u16,14871u16),(33904u16,14866u16), (33905u16,2232u16),(33906u16,3466u16),(33907u16,14847u16),(33908u16,14846u16), (33909u16,8707u16),(33910u16,14832u16),(33911u16,8704u16),(33912u16,14856u16), (33913u16,14833u16),(33914u16,14854u16),(33917u16,14843u16),(33918u16,14879u16), (33919u16,2613u16),(33920u16,3171u16),(33922u16,8703u16),(33924u16,1015u16), (33926u16,14839u16),(33928u16,3857u16),(33933u16,14835u16),(33934u16,14873u16), (33935u16,14834u16),(33936u16,9138u16),(33937u16,15499u16),(33938u16,2086u16), (33939u16,2247u16),(33940u16,15482u16),(33942u16,3088u16),(33943u16,15460u16), (33944u16,15490u16),(33945u16,9130u16),(33946u16,15475u16),(33947u16,15485u16), (33948u16,9133u16),(33949u16,15478u16),(33950u16,9131u16),(33951u16,15463u16), (33952u16,15493u16),(33953u16,15462u16),(33954u16,15481u16),(33955u16,3219u16), (33956u16,15461u16),(33959u16,15479u16),(33960u16,2239u16),(33961u16,15486u16), (33962u16,15474u16),(33963u16,15469u16),(33964u16,15467u16),(33965u16,4069u16), (33966u16,15468u16),(33967u16,15487u16),(33968u16,15498u16),(33969u16,15476u16), (33970u16,9132u16),(33972u16,15471u16),(33974u16,15491u16),(33976u16,9135u16), (33977u16,15470u16),(33978u16,15464u16),(33979u16,15480u16),(33980u16,9139u16), (33981u16,3394u16),(33982u16,3859u16),(33983u16,9127u16),(33984u16,9136u16), (33985u16,15472u16),(33986u16,15466u16),(33988u16,9129u16),(33989u16,14872u16), (33990u16,9128u16),(33991u16,15483u16),(33993u16,9126u16),(33994u16,9141u16), (33995u16,9134u16),(33996u16,15484u16),(33997u16,15473u16),(33998u16,15465u16), (33999u16,15492u16),(34000u16,15477u16),(34001u16,9140u16),(34002u16,15496u16), (34003u16,9137u16),(34004u16,15495u16),(34006u16,15489u16),(34007u16,15494u16), (34010u16,4976u16),(34011u16,15497u16),(34014u16,2243u16),(34017u16,3860u16), (34018u16,2187u16),(34020u16,2248u16),(34021u16,3270u16),(34023u16,16065u16), (34024u16,16066u16),(34025u16,16053u16),(34026u16,16052u16),(34027u16,16048u16), (34028u16,9502u16),(34030u16,9494u16),(34031u16,16068u16),(34032u16,16067u16), (34033u16,14829u16),(34034u16,16045u16),(34035u16,16049u16),(34036u16,16043u16), (34038u16,16062u16),(34039u16,16047u16),(34040u16,3861u16),(34041u16,16069u16), (34042u16,16040u16),(34043u16,16038u16),(34044u16,16050u16),(34045u16,16060u16), (34046u16,16055u16),(34047u16,9504u16),(34048u16,16029u16),(34050u16,16059u16), (34051u16,2671u16),(34052u16,1059u16),(34053u16,19221u16),(34054u16,9505u16), (34055u16,14849u16),(34056u16,16041u16),(34057u16,16032u16),(34058u16,16035u16), (34059u16,16073u16),(34060u16,16042u16),(34061u16,16033u16),(34062u16,16031u16), (34063u16,16028u16),(34064u16,3862u16),(34065u16,9498u16),(34066u16,16051u16), (34067u16,9497u16),(34068u16,9501u16),(34069u16,16046u16),(34070u16,16054u16), (34071u16,9491u16),(34072u16,16070u16),(34073u16,16074u16),(34074u16,9493u16), (34076u16,16037u16),(34077u16,16057u16),(34078u16,16061u16),(34079u16,16034u16), (34080u16,16071u16),(34081u16,9500u16),(34083u16,9499u16),(34084u16,16026u16), (34085u16,9503u16),(34086u16,16064u16),(34087u16,16036u16),(34088u16,16056u16), (34089u16,16030u16),(34090u16,16044u16),(34091u16,16039u16),(34092u16,9495u16), (34093u16,9496u16),(34094u16,16058u16),(34095u16,16075u16),(34096u16,16072u16), (34097u16,16063u16),(34099u16,19550u16),(34100u16,2253u16),(34104u16,3863u16), (34107u16,16027u16),(34109u16,9492u16),(34110u16,16651u16),(34112u16,16642u16), (34113u16,16645u16),(34114u16,19084u16),(34115u16,9823u16),(34116u16,16647u16), (34117u16,16636u16),(34118u16,16643u16),(34119u16,16649u16),(34120u16,9820u16), (34121u16,9824u16),(34122u16,9818u16),(34123u16,2198u16),(34124u16,19001u16), (34125u16,16638u16),(34126u16,16654u16),(34129u16,16648u16),(34130u16,3864u16), (34131u16,16639u16),(34132u16,16663u16),(34133u16,16657u16),(34134u16,16635u16), (34135u16,17119u16),(34136u16,16641u16),(34137u16,9819u16),(34138u16,2226u16), (34139u16,16652u16),(34141u16,16662u16),(34142u16,9827u16),(34143u16,1818u16), (34144u16,16659u16),(34145u16,16640u16),(34146u16,16646u16),(34147u16,16650u16), (34148u16,16644u16),(34149u16,16664u16),(34150u16,16661u16),(34151u16,16658u16), (34152u16,9821u16),(34153u16,9822u16),(34154u16,9826u16),(34155u16,16637u16), (34156u16,16665u16),(34157u16,9825u16),(34158u16,16655u16),(34159u16,3866u16), (34160u16,3867u16),(34161u16,16653u16),(34163u16,2257u16),(34165u16,16656u16), (34166u16,17132u16),(34167u16,17113u16),(34168u16,17118u16),(34169u16,17131u16), (34170u16,17117u16),(34171u16,17109u16),(34172u16,17114u16),(34174u16,10112u16), (34176u16,17102u16),(34177u16,17126u16),(34178u16,17128u16),(34179u16,17101u16), (34180u16,10111u16),(34181u16,17130u16),(34182u16,17122u16),(34183u16,10118u16), (34184u16,17129u16),(34185u16,17115u16),(34186u16,10120u16),(34187u16,17107u16), (34188u16,16660u16),(34189u16,17123u16),(34190u16,17120u16),(34191u16,17103u16), (34192u16,17134u16),(34193u16,10114u16),(34195u16,996u16),(34196u16,10115u16), (34197u16,17105u16),(34198u16,17121u16),(34199u16,1811u16),(34200u16,17133u16), (34201u16,17124u16),(34202u16,17111u16),(34203u16,10117u16),(34204u16,10113u16), (34205u16,17125u16),(34206u16,17112u16),(34207u16,17135u16),(34208u16,17106u16), (34209u16,17116u16),(34210u16,17127u16),(34211u16,17108u16),(34212u16,17110u16), (34214u16,10310u16),(34215u16,17104u16),(34216u16,10119u16),(34217u16,10303u16), (34218u16,10110u16),(34223u16,10116u16),(34224u16,10307u16),(34225u16,17508u16), (34227u16,17498u16),(34228u16,17493u16),(34229u16,17499u16),(34230u16,17509u16), (34231u16,17513u16),(34232u16,17512u16),(34233u16,10309u16),(34234u16,10308u16), (34237u16,17500u16),(34238u16,17514u16),(34239u16,17503u16),(34240u16,17495u16), (34241u16,2263u16),(34242u16,17497u16),(34243u16,17496u16),(34244u16,17502u16), (34245u16,17507u16),(34246u16,17494u16),(34247u16,17501u16),(34248u16,17506u16), (34249u16,10306u16),(34251u16,17504u16),(34253u16,10304u16),(34254u16,17505u16), (34255u16,10302u16),(34256u16,10305u16),(34257u16,17856u16),(34258u16,17510u16), (34261u16,10458u16),(34262u16,1835u16),(34263u16,17848u16),(34264u16,17852u16), (34265u16,17844u16),(34266u16,17847u16),(34268u16,17855u16),(34269u16,10456u16), (34270u16,17860u16),(34271u16,17853u16),(34272u16,3868u16),(34273u16,17845u16), (34274u16,17861u16),(34275u16,17854u16),(34276u16,10459u16),(34277u16,10460u16), (34278u16,17858u16),(34280u16,17846u16),(34281u16,10455u16),(34282u16,10457u16), (34283u16,17841u16),(34284u16,17849u16),(34285u16,17843u16),(34286u16,3404u16), (34287u16,17859u16),(34288u16,17857u16),(34289u16,17842u16),(34290u16,17850u16), (34294u16,18147u16),(34295u16,10461u16),(34296u16,17851u16),(34297u16,10588u16), (34298u16,10590u16),(34299u16,10587u16),(34300u16,3398u16),(34301u16,18152u16), (34302u16,18144u16),(34303u16,18142u16),(34304u16,18146u16),(34305u16,18143u16), (34306u16,2265u16),(34308u16,18148u16),(34309u16,18150u16),(34310u16,10591u16), (34311u16,10593u16),(34313u16,18149u16),(34314u16,10594u16),(34315u16,10592u16), (34316u16,18151u16),(34317u16,19086u16),(34319u16,1760u16),(34320u16,3188u16), (34321u16,10589u16),(34323u16,1019u16),(34324u16,2866u16),(34326u16,2260u16), (34327u16,10665u16),(34328u16,18355u16),(34329u16,18361u16),(34330u16,10667u16), (34331u16,18145u16),(34332u16,18360u16),(34334u16,18367u16),(34335u16,18358u16), (34336u16,18365u16),(34337u16,18364u16),(34338u16,18141u16),(34339u16,18359u16), (34340u16,17511u16),(34341u16,18368u16),(34342u16,18357u16),(34343u16,18362u16), (34344u16,2270u16),(34345u16,18366u16),(34346u16,18356u16),(34348u16,18536u16), (34349u16,10666u16),(34350u16,18363u16),(34351u16,4883u16),(34353u16,18672u16), (34354u16,18537u16),(34355u16,18535u16),(34356u16,18533u16),(34357u16,18534u16), (34358u16,18538u16),(34360u16,10795u16),(34361u16,18670u16),(34362u16,18668u16), (34363u16,18673u16),(34364u16,18671u16),(34366u16,18674u16),(34367u16,10796u16), (34368u16,18669u16),(34370u16,2468u16),(34371u16,18773u16),(34373u16,3162u16), (34374u16,18845u16),(34375u16,18846u16),(34376u16,18847u16),(34379u16,18941u16), (34380u16,18931u16),(34381u16,11476u16),(34382u16,6573u16),(34384u16,6948u16), (34386u16,12960u16),(34387u16,12959u16),(34388u16,7379u16),(34389u16,7852u16), (34390u16,13562u16),(34393u16,13561u16),(34395u16,8300u16),(34396u16,8721u16), (34398u16,8720u16),(34399u16,8722u16),(34401u16,15500u16),(34402u16,16076u16), (34403u16,16666u16),(34404u16,16668u16),(34405u16,16667u16),(34407u16,10121u16), (34408u16,17136u16),(34409u16,17515u16),(34410u16,18907u16),(34411u16,5939u16), (34412u16,2284u16),(34413u16,12035u16),(34414u16,12036u16),(34415u16,12034u16), (34416u16,12033u16),(34417u16,6574u16),(34418u16,3870u16),(34419u16,12474u16), (34420u16,12472u16),(34423u16,12471u16),(34425u16,6949u16),(34426u16,6951u16), (34427u16,6950u16),(34428u16,12473u16),(34430u16,2275u16),(34437u16,12972u16), (34438u16,12969u16),(34439u16,12967u16),(34442u16,7380u16),(34443u16,12970u16), (34444u16,7385u16),(34445u16,12964u16),(34446u16,12979u16),(34448u16,12981u16), (34449u16,12965u16),(34450u16,3871u16),(34451u16,7382u16),(34452u16,12982u16), (34453u16,12977u16),(34454u16,12963u16),(34455u16,12968u16),(34456u16,12978u16), (34457u16,12974u16),(34458u16,12971u16),(34460u16,7387u16),(34461u16,12980u16), (34462u16,12966u16),(34464u16,3197u16),(34465u16,12975u16),(34466u16,12961u16), (34467u16,7386u16),(34468u16,7383u16),(34469u16,12973u16),(34471u16,12976u16), (34472u16,12962u16),(34473u16,7384u16),(34474u16,7381u16),(34477u16,4719u16), (34479u16,7862u16),(34480u16,13569u16),(34481u16,7861u16),(34482u16,3872u16), (34483u16,13572u16),(34484u16,13575u16),(34485u16,7858u16),(34486u16,7856u16), (34487u16,13564u16),(34488u16,13573u16),(34489u16,13571u16),(34490u16,13568u16), (34491u16,13576u16),(34492u16,13577u16),(34493u16,13579u16),(34494u16,13580u16), (34495u16,13563u16),(34496u16,7855u16),(34497u16,13566u16),(34498u16,13565u16), (34499u16,13578u16),(34500u16,7857u16),(34501u16,13567u16),(34502u16,7859u16), (34503u16,7854u16),(34504u16,13570u16),(34505u16,7863u16),(34507u16,7860u16), (34508u16,13574u16),(34512u16,8307u16),(34513u16,14223u16),(34515u16,14212u16), (34516u16,8304u16),(34518u16,14891u16),(34519u16,14221u16),(34520u16,14209u16), (34521u16,8302u16),(34522u16,14214u16),(34523u16,8305u16),(34524u16,14218u16), (34525u16,14216u16),(34526u16,8308u16),(34527u16,8301u16),(34530u16,14210u16), (34531u16,14213u16),(34532u16,8306u16),(34534u16,14211u16),(34536u16,14222u16), (34537u16,14220u16),(34538u16,14215u16),(34539u16,14217u16),(34540u16,14219u16), (34541u16,8303u16),(34543u16,3873u16),(34549u16,14892u16),(34550u16,14898u16), (34551u16,14888u16),(34552u16,14894u16),(34553u16,8723u16),(34554u16,14890u16), (34555u16,8729u16),(34558u16,8728u16),(34560u16,8727u16),(34561u16,14897u16), (34562u16,8730u16),(34563u16,8731u16),(34564u16,14887u16),(34565u16,14900u16), (34566u16,8732u16),(34567u16,8726u16),(34568u16,8725u16),(34569u16,14896u16), (34570u16,8733u16),(34571u16,14886u16),(34572u16,14889u16),(34573u16,14899u16), (34574u16,14895u16),(34577u16,15532u16),(34578u16,15521u16),(34579u16,8724u16), (34584u16,9148u16),(34585u16,15509u16),(34586u16,15530u16),(34587u16,15510u16), (34588u16,9143u16),(34590u16,15507u16),(34592u16,15516u16),(34593u16,15508u16), (34594u16,9145u16),(34595u16,15502u16),(34596u16,15529u16),(34597u16,9146u16), (34598u16,15526u16),(34599u16,15527u16),(34600u16,15503u16),(34601u16,9151u16), (34602u16,15518u16),(34604u16,15512u16),(34605u16,15519u16),(34606u16,15506u16), (34608u16,15531u16),(34609u16,15523u16),(34610u16,15517u16),(34611u16,15501u16), (34612u16,9147u16),(34613u16,15524u16),(34615u16,9150u16),(34616u16,15528u16), (34618u16,15522u16),(34619u16,9144u16),(34620u16,15520u16),(34622u16,15514u16), (34623u16,9142u16),(34624u16,15505u16),(34625u16,15513u16),(34626u16,15525u16), (34627u16,15511u16),(34630u16,15515u16),(34636u16,9515u16),(34637u16,14893u16), (34638u16,16094u16),(34639u16,16103u16),(34640u16,16093u16),(34641u16,16089u16), (34642u16,16086u16),(34643u16,9516u16),(34644u16,16084u16),(34645u16,9149u16), (34646u16,16077u16),(34647u16,9514u16),(34648u16,16083u16),(34649u16,9513u16), (34650u16,16088u16),(34651u16,16085u16),(34652u16,16101u16),(34653u16,16096u16), (34654u16,16090u16),(34655u16,16095u16),(34656u16,9509u16),(34657u16,16087u16), (34658u16,16106u16),(34659u16,16078u16),(34660u16,16079u16),(34661u16,16102u16), (34662u16,9510u16),(34663u16,16107u16),(34664u16,9512u16),(34665u16,16108u16), (34666u16,16092u16),(34667u16,15504u16),(34668u16,16098u16),(34669u16,16091u16), (34670u16,16100u16),(34671u16,16097u16),(34672u16,4511u16),(34673u16,2276u16), (34675u16,16082u16),(34676u16,9507u16),(34677u16,16105u16),(34678u16,9508u16), (34679u16,16080u16),(34680u16,9511u16),(34681u16,16678u16),(34682u16,16099u16), (34683u16,16104u16),(34685u16,19055u16),(34689u16,16675u16),(34690u16,9506u16), (34691u16,9828u16),(34692u16,16685u16),(34693u16,16681u16),(34694u16,4584u16), (34695u16,16679u16),(34696u16,16674u16),(34697u16,16689u16),(34699u16,3875u16), (34700u16,4970u16),(34701u16,9832u16),(34703u16,16670u16),(34704u16,16682u16), (34705u16,16683u16),(34706u16,16673u16),(34707u16,16672u16),(34708u16,16686u16), (34710u16,16676u16),(34711u16,16671u16),(34712u16,16677u16),(34714u16,16688u16), (34715u16,16669u16),(34716u16,16687u16),(34717u16,16684u16),(34718u16,9830u16), (34719u16,9829u16),(34722u16,9831u16),(34723u16,16680u16),(34724u16,17532u16), (34725u16,4046u16),(34729u16,4967u16),(34730u16,17138u16),(34731u16,10127u16), (34732u16,17142u16),(34733u16,17139u16),(34734u16,17146u16),(34735u16,17152u16), (34736u16,17141u16),(34737u16,2280u16),(34738u16,17161u16),(34739u16,10124u16), (34740u16,17155u16),(34741u16,17144u16),(34742u16,17156u16),(34743u16,17151u16), (34744u16,17158u16),(34745u16,17143u16),(34746u16,10129u16),(34747u16,10128u16), (34748u16,17145u16),(34749u16,17159u16),(34750u16,17137u16),(34751u16,17157u16), (34752u16,10122u16),(34753u16,4984u16),(34754u16,17149u16),(34755u16,17148u16), (34756u16,17153u16),(34757u16,17140u16),(34758u16,10126u16),(34760u16,10130u16), (34761u16,17147u16),(34762u16,17154u16),(34763u16,10131u16),(34764u16,17150u16), (34766u16,4968u16),(34769u16,10123u16),(34770u16,10125u16),(34771u16,17528u16), (34772u16,17526u16),(34774u16,4870u16),(34775u16,17533u16),(34776u16,17530u16), (34777u16,17534u16),(34778u16,2281u16),(34779u16,17519u16),(34780u16,17527u16), (34781u16,17538u16),(34782u16,17160u16),(34783u16,17523u16),(34784u16,10314u16), (34785u16,16081u16),(34786u16,17518u16),(34787u16,17531u16),(34788u16,17525u16), (34789u16,17522u16),(34790u16,17517u16),(34791u16,17516u16),(34792u16,17537u16), (34794u16,17521u16),(34795u16,17520u16),(34796u16,10312u16),(34797u16,17529u16), (34798u16,2278u16),(34799u16,10311u16),(34802u16,10313u16),(34803u16,17524u16), (34804u16,17536u16),(34805u16,4900u16),(34806u16,17865u16),(34807u16,17866u16), (34809u16,10465u16),(34810u16,17863u16),(34811u16,10462u16),(34812u16,17871u16), (34814u16,10466u16),(34815u16,17873u16),(34816u16,17862u16),(34817u16,17535u16), (34818u16,17875u16),(34819u16,17864u16),(34820u16,4583u16),(34821u16,10463u16), (34822u16,17870u16),(34824u16,17872u16),(34825u16,17867u16),(34826u16,17874u16), (34827u16,17869u16),(34828u16,17868u16),(34829u16,10464u16),(34831u16,2282u16), (34832u16,18154u16),(34833u16,18155u16),(34835u16,18157u16),(34836u16,10595u16), (34837u16,10596u16),(34838u16,18158u16),(34839u16,18156u16),(34840u16,4844u16), (34841u16,18153u16),(34843u16,18371u16),(34844u16,18374u16),(34845u16,18370u16), (34847u16,10671u16),(34848u16,18372u16),(34849u16,10670u16),(34850u16,10669u16), (34851u16,10668u16),(34852u16,18373u16),(34853u16,18543u16),(34854u16,18541u16), (34855u16,4319u16),(34856u16,18540u16),(34857u16,18369u16),(34858u16,18542u16), (34859u16,18375u16),(34860u16,18539u16),(34861u16,3200u16),(34862u16,18677u16), (34863u16,18643u16),(34864u16,18675u16),(34865u16,10797u16),(34866u16,18676u16), (34867u16,18678u16),(34869u16,18776u16),(34870u16,10828u16),(34871u16,18775u16), (34872u16,18774u16),(34873u16,10829u16),(34875u16,10859u16),(34876u16,18886u16), (34877u16,18909u16),(34878u16,18908u16),(34879u16,18910u16),(34880u16,5940u16), (34881u16,12475u16),(34882u16,4811u16),(34883u16,12983u16),(34884u16,12984u16), (34885u16,2287u16),(34886u16,2288u16),(34888u16,14224u16),(34890u16,18376u16), (34891u16,18777u16),(34892u16,5941u16),(34893u16,6952u16),(34894u16,12476u16), (34895u16,2336u16),(34898u16,13581u16),(34899u16,7864u16),(34901u16,14226u16), (34902u16,14225u16),(34903u16,8309u16),(34905u16,8734u16),(34906u16,16109u16), (34907u16,9517u16),(34909u16,9518u16),(34910u16,2292u16),(34912u16,2868u16), (34913u16,9833u16),(34914u16,10830u16),(34915u16,5942u16),(34916u16,1700u16), (34917u16,4299u16),(34919u16,12477u16),(34920u16,6576u16),(34921u16,12479u16), (34922u16,12478u16),(34923u16,6953u16),(34925u16,12985u16),(34926u16,3203u16), (34927u16,12992u16),(34928u16,7388u16),(34929u16,12990u16),(34930u16,12988u16), (34932u16,12995u16),(34933u16,12986u16),(34934u16,12987u16),(34935u16,7389u16), (34937u16,7393u16),(34940u16,12996u16),(34941u16,7392u16),(34942u16,12994u16), (34943u16,12991u16),(34944u16,12989u16),(34945u16,7390u16),(34946u16,7391u16), (34947u16,12993u16),(34948u16,19763u16),(34951u16,3205u16),(34952u16,7866u16), (34953u16,13582u16),(34955u16,7871u16),(34956u16,13598u16),(34957u16,7870u16), (34958u16,13600u16),(34959u16,1732u16),(34960u16,1813u16),(34961u16,13588u16), (34962u16,7868u16),(34963u16,13599u16),(34965u16,13583u16),(34966u16,7869u16), (34967u16,13595u16),(34968u16,13591u16),(34969u16,13593u16),(34970u16,13587u16), (34971u16,13594u16),(34972u16,2293u16),(34973u16,1027u16),(34974u16,7865u16), (34975u16,13590u16),(34976u16,4885u16),(34977u16,13589u16),(34978u16,13585u16), (34980u16,13596u16),(34983u16,13592u16),(34984u16,13584u16),(34986u16,13586u16), (34987u16,7867u16),(34988u16,13597u16),(34990u16,3878u16),(34993u16,8312u16), (34994u16,14237u16),(34996u16,2295u16),(34997u16,2296u16),(34998u16,14233u16), (34999u16,14235u16),(35000u16,14230u16),(35001u16,14229u16),(35002u16,14227u16), (35004u16,14234u16),(35005u16,14236u16),(35006u16,14232u16),(35007u16,3206u16), (35008u16,14231u16),(35009u16,8310u16),(35010u16,8311u16),(35013u16,2298u16), (35015u16,4585u16),(35017u16,14239u16),(35018u16,8742u16),(35019u16,14902u16), (35020u16,14908u16),(35021u16,14903u16),(35022u16,14904u16),(35023u16,18958u16), (35024u16,14909u16),(35026u16,8744u16),(35028u16,8736u16),(35029u16,8743u16), (35030u16,14901u16),(35031u16,14228u16),(35032u16,8739u16),(35033u16,8737u16), (35034u16,14907u16),(35035u16,14906u16),(35036u16,8738u16),(35037u16,8740u16), (35038u16,14905u16),(35039u16,8735u16),(35041u16,8741u16),(35046u16,3207u16), (35047u16,15534u16),(35048u16,9158u16),(35051u16,15545u16),(35052u16,15544u16), (35054u16,15539u16),(35055u16,9160u16),(35056u16,15543u16),(35057u16,15535u16), (35058u16,15536u16),(35059u16,9152u16),(35060u16,9154u16),(35061u16,4320u16), (35062u16,15541u16),(35063u16,15533u16),(35064u16,9156u16),(35065u16,9155u16), (35066u16,15537u16),(35067u16,15542u16),(35068u16,15540u16),(35069u16,9157u16), (35070u16,15538u16),(35071u16,3879u16),(35072u16,19768u16),(35073u16,14238u16), (35074u16,9153u16),(35077u16,16110u16),(35078u16,16117u16),(35079u16,9520u16), (35081u16,16121u16),(35082u16,9524u16),(35083u16,16113u16),(35084u16,16111u16), (35086u16,16120u16),(35088u16,9519u16),(35089u16,16119u16),(35090u16,9521u16), (35091u16,9522u16),(35092u16,16112u16),(35093u16,9523u16),(35094u16,16118u16), (35095u16,16114u16),(35096u16,16115u16),(35097u16,16116u16),(35098u16,9159u16), (35102u16,16690u16),(35103u16,16702u16),(35105u16,9838u16),(35106u16,16697u16), (35107u16,16699u16),(35108u16,3880u16),(35109u16,9836u16),(35110u16,16691u16), (35111u16,16695u16),(35113u16,16698u16),(35114u16,9834u16),(35115u16,9837u16), (35116u16,16701u16),(35117u16,16693u16),(35118u16,16694u16),(35119u16,16700u16), (35120u16,16692u16),(35121u16,16696u16),(35122u16,9835u16),(35123u16,17163u16), (35125u16,17162u16),(35126u16,10133u16),(35127u16,17168u16),(35128u16,10135u16), (35131u16,10132u16),(35132u16,17164u16),(35133u16,10136u16),(35134u16,17165u16), (35137u16,17166u16),(35138u16,17169u16),(35139u16,4335u16),(35140u16,10134u16), (35142u16,17543u16),(35143u16,3881u16),(35145u16,17546u16),(35147u16,17540u16), (35148u16,17542u16),(35149u16,3209u16),(35151u16,17541u16),(35152u16,17544u16), (35153u16,17545u16),(35154u16,17167u16),(35155u16,17539u16),(35156u16,3211u16), (35158u16,10469u16),(35159u16,17879u16),(35160u16,17882u16),(35161u16,17884u16), (35162u16,17877u16),(35163u16,17878u16),(35164u16,17881u16),(35165u16,17883u16), (35166u16,10470u16),(35167u16,10468u16),(35168u16,10467u16),(35169u16,17880u16), (35170u16,17876u16),(35171u16,18159u16),(35172u16,10597u16),(35173u16,3208u16), (35174u16,18160u16),(35177u16,18378u16),(35178u16,10672u16),(35179u16,18380u16), (35180u16,10673u16),(35181u16,18377u16),(35182u16,18379u16),(35183u16,10746u16), (35185u16,18544u16),(35186u16,10745u16),(35187u16,18681u16),(35188u16,18680u16), (35190u16,18679u16),(35191u16,4268u16),(35193u16,18848u16),(35194u16,18849u16), (35195u16,18851u16),(35196u16,18850u16),(35198u16,11477u16),(35199u16,5943u16), (35200u16,3739u16),(35201u16,6954u16),(35202u16,13601u16),(35203u16,8313u16), (35205u16,14910u16),(35206u16,10315u16),(35207u16,2301u16),(35208u16,17885u16), (35209u16,4963u16),(35210u16,2302u16),(35211u16,6188u16),(35215u16,7873u16), (35217u16,3882u16),(35219u16,7872u16),(35220u16,4954u16),(35221u16,14240u16), (35222u16,8314u16),(35223u16,14242u16),(35224u16,14241u16),(35227u16,14911u16), (35228u16,8745u16),(35229u16,15546u16),(35230u16,15549u16),(35231u16,15548u16), (35233u16,15547u16),(35234u16,16122u16),(35235u16,16124u16),(35236u16,16123u16), (35237u16,4106u16),(35238u16,2303u16),(35239u16,2305u16),(35241u16,2304u16), (35242u16,9839u16),(35244u16,10137u16),(35245u16,17170u16),(35246u16,17172u16), (35247u16,17171u16),(35250u16,10316u16),(35254u16,17887u16),(35255u16,17886u16), (35257u16,18161u16),(35258u16,10598u16),(35260u16,2306u16),(35261u16,10674u16), (35262u16,18546u16),(35263u16,18545u16),(35264u16,10860u16),(35265u16,1701u16), (35270u16,1313u16),(35282u16,6189u16),(35283u16,12480u16),(35284u16,6955u16), (35285u16,13604u16),(35286u16,13602u16),(35289u16,13603u16),(35290u16,14244u16), (35291u16,14245u16),(35292u16,14918u16),(35293u16,14243u16),(35295u16,14912u16), (35296u16,14916u16),(35297u16,14915u16),(35298u16,14917u16),(35299u16,8746u16), (35300u16,14914u16),(35301u16,14913u16),(35302u16,14919u16),(35303u16,2308u16), (35304u16,15552u16),(35305u16,15550u16),(35307u16,15551u16),(35308u16,16127u16), (35309u16,16125u16),(35312u16,16126u16),(35313u16,16703u16),(35314u16,17173u16), (35315u16,17174u16),(35316u16,10317u16),(35318u16,17888u16),(35319u16,18162u16), (35320u16,10599u16),(35322u16,18381u16),(35323u16,18547u16),(35324u16,10747u16), (35326u16,18682u16),(35327u16,18852u16),(35328u16,6190u16),(35330u16,6957u16), (35331u16,6958u16),(35332u16,12481u16),(35335u16,12482u16),(35336u16,6956u16), (35338u16,7399u16),(35340u16,7397u16),(35342u16,7396u16),(35343u16,7403u16), (35344u16,7395u16),(35345u16,7404u16),(35346u16,12997u16),(35347u16,7401u16), (35349u16,7398u16),(35350u16,7402u16),(35351u16,7400u16),(35352u16,7394u16), (35355u16,7881u16),(35356u16,3224u16),(35357u16,7875u16),(35358u16,13608u16), (35359u16,7880u16),(35362u16,7882u16),(35363u16,7876u16),(35365u16,7877u16), (35367u16,13606u16),(35369u16,3884u16),(35370u16,7874u16),(35371u16,3271u16), (35372u16,13607u16),(35373u16,7879u16),(35376u16,13605u16),(35377u16,7878u16), (35380u16,8325u16),(35382u16,8327u16),(35384u16,3885u16),(35385u16,14248u16), (35386u16,8326u16),(35387u16,8315u16),(35388u16,8319u16),(35389u16,3223u16), (35390u16,8765u16),(35391u16,14924u16),(35392u16,14250u16),(35393u16,8320u16), (35396u16,14253u16),(35397u16,14254u16),(35398u16,8324u16),(35400u16,14256u16), (35401u16,4971u16),(35402u16,14258u16),(35404u16,14259u16),(35405u16,14247u16), (35406u16,14246u16),(35407u16,14260u16),(35408u16,8323u16),(35409u16,14257u16), (35410u16,14255u16),(35412u16,8321u16),(35413u16,8317u16),(35414u16,8328u16), (35415u16,14251u16),(35416u16,14252u16),(35417u16,14249u16),(35419u16,8322u16), (35422u16,8318u16),(35424u16,8316u16),(35425u16,14923u16),(35426u16,8760u16), (35427u16,8755u16),(35430u16,8750u16),(35431u16,4865u16),(35432u16,8766u16), (35433u16,8751u16),(35435u16,8747u16),(35436u16,8762u16),(35437u16,8759u16), (35438u16,8761u16),(35440u16,8752u16),(35441u16,8757u16),(35442u16,8748u16), (35443u16,8749u16),(35444u16,14931u16),(35445u16,14928u16),(35446u16,14920u16), (35447u16,14925u16),(35449u16,8763u16),(35450u16,14932u16),(35451u16,8764u16), (35452u16,8754u16),(35454u16,4891u16),(35455u16,14922u16),(35457u16,14930u16), (35458u16,14926u16),(35459u16,14929u16),(35460u16,14927u16),(35461u16,8758u16), (35462u16,14921u16),(35463u16,8753u16),(35467u16,15555u16),(35468u16,9162u16), (35469u16,9165u16),(35471u16,15557u16),(35472u16,2314u16),(35473u16,9173u16), (35474u16,15556u16),(35475u16,9167u16),(35476u16,3886u16),(35477u16,9529u16), (35478u16,15558u16),(35480u16,9172u16),(35481u16,15554u16),(35482u16,9174u16), (35484u16,2311u16),(35486u16,9163u16),(35488u16,8756u16),(35489u16,9166u16), (35491u16,9164u16),(35492u16,9168u16),(35493u16,9170u16),(35494u16,9161u16), (35495u16,9175u16),(35496u16,9171u16),(35497u16,2329u16),(35498u16,9169u16), (35499u16,15553u16),(35503u16,2333u16),(35504u16,9536u16),(35506u16,9532u16), (35508u16,3887u16),(35510u16,9539u16),(35512u16,16130u16),(35513u16,9540u16), (35514u16,16142u16),(35515u16,16135u16),(35516u16,9525u16),(35517u16,16143u16), (35518u16,16137u16),(35519u16,9535u16),(35520u16,16138u16),(35522u16,9534u16), (35523u16,16141u16),(35524u16,9528u16),(35525u16,16139u16),(35526u16,16129u16), (35527u16,9527u16),(35528u16,16714u16),(35529u16,9533u16),(35531u16,9530u16), (35532u16,1876u16),(35533u16,9538u16),(35535u16,16128u16),(35537u16,16132u16), (35538u16,9526u16),(35539u16,16131u16),(35540u16,16133u16),(35541u16,16134u16), (35542u16,9537u16),(35543u16,16136u16),(35544u16,16140u16),(35545u16,16144u16), (35546u16,2729u16),(35547u16,9541u16),(35548u16,9846u16),(35549u16,16709u16), (35550u16,16715u16),(35551u16,16712u16),(35552u16,16704u16),(35553u16,16716u16), (35554u16,16705u16),(35556u16,16711u16),(35558u16,9841u16),(35559u16,9847u16), (35560u16,16717u16),(35562u16,4244u16),(35563u16,9843u16),(35565u16,9853u16), (35566u16,9848u16),(35567u16,16719u16),(35568u16,16713u16),(35569u16,9844u16), (35570u16,16706u16),(35571u16,9854u16),(35572u16,16707u16),(35573u16,16708u16), (35574u16,9855u16),(35575u16,9852u16),(35576u16,9531u16),(35577u16,1861u16), (35578u16,9842u16),(35579u16,16720u16),(35580u16,9856u16),(35582u16,9849u16), (35583u16,16718u16),(35584u16,9845u16),(35585u16,9850u16),(35586u16,9851u16), (35588u16,10145u16),(35589u16,17179u16),(35590u16,17188u16),(35591u16,17185u16), (35592u16,17187u16),(35594u16,10142u16),(35595u16,17180u16),(35596u16,2322u16), (35597u16,17186u16),(35598u16,10138u16),(35599u16,17182u16),(35600u16,10146u16), (35601u16,17178u16),(35602u16,17183u16),(35603u16,17190u16),(35604u16,16710u16), (35605u16,17184u16),(35606u16,17177u16),(35607u16,10139u16),(35608u16,17176u16), (35609u16,10140u16),(35610u16,17191u16),(35611u16,10141u16),(35612u16,17189u16), (35613u16,10144u16),(35614u16,17175u16),(35615u16,2323u16),(35616u16,10143u16), (35618u16,17181u16),(35619u16,17549u16),(35620u16,17563u16),(35621u16,17558u16), (35622u16,17560u16),(35623u16,17548u16),(35624u16,10318u16),(35626u16,17547u16), (35627u16,10321u16),(35628u16,10320u16),(35629u16,4878u16),(35630u16,17562u16), (35631u16,17554u16),(35632u16,17551u16),(35633u16,17557u16),(35635u16,17550u16), (35637u16,17552u16),(35638u16,17561u16),(35639u16,17559u16),(35641u16,10319u16), (35642u16,17566u16),(35643u16,17564u16),(35644u16,17555u16),(35645u16,17565u16), (35646u16,17556u16),(35647u16,2326u16),(35648u16,17892u16),(35649u16,10471u16), (35650u16,17899u16),(35651u16,4973u16),(35653u16,18384u16),(35654u16,10478u16), (35655u16,17553u16),(35656u16,17890u16),(35657u16,10474u16),(35658u16,17891u16), (35659u16,17896u16),(35660u16,2327u16),(35661u16,2328u16),(35662u16,10476u16), (35663u16,10477u16),(35664u16,17889u16),(35665u16,17898u16),(35666u16,17900u16), (35667u16,17893u16),(35668u16,17895u16),(35669u16,17897u16),(35670u16,17894u16), (35671u16,17901u16),(35672u16,10473u16),(35673u16,10479u16),(35674u16,10475u16), (35676u16,10472u16),(35677u16,18165u16),(35678u16,4180u16),(35679u16,10604u16), (35680u16,18163u16),(35682u16,4236u16),(35683u16,18167u16),(35685u16,18168u16), (35686u16,10602u16),(35687u16,18169u16),(35688u16,18166u16),(35689u16,3309u16), (35690u16,18164u16),(35691u16,10605u16),(35692u16,10601u16),(35693u16,18170u16), (35695u16,10603u16),(35696u16,10600u16),(35700u16,10675u16),(35703u16,10676u16), (35704u16,18383u16),(35705u16,18382u16),(35706u16,18385u16),(35707u16,18386u16), (35709u16,10677u16),(35710u16,18548u16),(35711u16,18553u16),(35712u16,10748u16), (35713u16,4073u16),(35714u16,18550u16),(35715u16,1803u16),(35716u16,18549u16), (35717u16,18552u16),(35718u16,18551u16),(35720u16,18686u16),(35722u16,10798u16), (35723u16,18685u16),(35724u16,18683u16),(35726u16,18684u16),(35727u16,1047u16), (35728u16,2331u16),(35730u16,10832u16),(35731u16,10831u16),(35732u16,18778u16), (35733u16,18779u16),(35734u16,10833u16),(35736u16,18853u16),(35737u16,18854u16), (35738u16,10872u16),(35739u16,2332u16),(35740u16,10878u16),(35742u16,18911u16), (35743u16,18942u16),(35744u16,1703u16),(35774u16,1314u16),(35810u16,1315u16), (35895u16,6191u16),(35897u16,13609u16),(35899u16,13610u16),(35900u16,14933u16), (35901u16,15559u16),(35902u16,16145u16),(35903u16,10148u16),(35905u16,10147u16), (35906u16,17567u16),(35907u16,17902u16),(35909u16,18687u16),(35910u16,6192u16), (35911u16,12998u16),(35912u16,7405u16),(35913u16,7883u16),(35914u16,14935u16), (35915u16,14934u16),(35916u16,9542u16),(35917u16,16146u16),(35918u16,9543u16), (35919u16,17192u16),(35920u16,10322u16),(35921u16,3888u16),(35924u16,10887u16), (35925u16,6193u16),(35926u16,12037u16),(35927u16,12999u16),(35930u16,7884u16), (35932u16,13611u16),(35933u16,13612u16),(35935u16,14261u16),(35937u16,8329u16), (35938u16,8767u16),(35940u16,14937u16),(35941u16,14936u16),(35942u16,14938u16), (35944u16,15560u16),(35945u16,15561u16),(35946u16,9176u16),(35947u16,9857u16), (35948u16,9544u16),(35949u16,9858u16),(35951u16,17196u16),(35952u16,17193u16), (35953u16,17195u16),(35954u16,17194u16),(35955u16,10149u16),(35957u16,17568u16), (35958u16,17904u16),(35959u16,17903u16),(35960u16,11684u16),(35961u16,7407u16), (35962u16,7406u16),(35963u16,13000u16),(35965u16,13613u16),(35968u16,14263u16), (35969u16,14262u16),(35970u16,8330u16),(35972u16,14940u16),(35973u16,14941u16), (35974u16,14939u16),(35977u16,8769u16),(35978u16,8768u16),(35980u16,9178u16), (35981u16,9177u16),(35983u16,16147u16),(35984u16,16723u16),(35985u16,16721u16), (35986u16,16722u16),(35987u16,9859u16),(35988u16,17198u16),(35989u16,17197u16), (35991u16,17571u16),(35992u16,17570u16),(35993u16,17569u16),(35994u16,17905u16), (35995u16,2337u16),(35996u16,18912u16),(35997u16,6194u16),(35998u16,6959u16), (35999u16,3234u16),(36000u16,6960u16),(36001u16,7408u16),(36002u16,7409u16), (36003u16,13002u16),(36004u16,13001u16),(36005u16,13614u16),(36007u16,7890u16), (36008u16,7888u16),(36009u16,7885u16),(36010u16,7889u16),(36011u16,7887u16), (36012u16,7886u16),(36013u16,4972u16),(36015u16,8331u16),(36016u16,14266u16), (36018u16,8774u16),(36019u16,8333u16),(36020u16,8338u16),(36021u16,14268u16), (36022u16,8340u16),(36023u16,8339u16),(36024u16,8342u16),(36025u16,14267u16), (36026u16,14264u16),(36027u16,8336u16),(36028u16,8332u16),(36029u16,8334u16), (36030u16,14265u16),(36031u16,8341u16),(36032u16,8337u16),(36033u16,8335u16), (36034u16,8776u16),(36035u16,8775u16),(36036u16,8773u16),(36037u16,8777u16), (36039u16,8771u16),(36040u16,8772u16),(36042u16,8770u16),(36044u16,14942u16), (36045u16,4561u16),(36047u16,15563u16),(36049u16,9180u16),(36050u16,9181u16), (36051u16,9179u16),(36052u16,3889u16),(36053u16,15562u16),(36054u16,2343u16), (36055u16,15564u16),(36057u16,16150u16),(36058u16,16152u16),(36059u16,2349u16), (36060u16,9553u16),(36061u16,16153u16),(36062u16,9546u16),(36063u16,16149u16), (36064u16,9545u16),(36065u16,9555u16),(36066u16,9551u16),(36067u16,9552u16), (36068u16,9548u16),(36069u16,16148u16),(36070u16,9547u16),(36071u16,16154u16), (36072u16,16151u16),(36073u16,3235u16),(36074u16,9554u16),(36075u16,4881u16), (36076u16,9549u16),(36077u16,9550u16),(36078u16,16725u16),(36080u16,16727u16), (36081u16,16726u16),(36082u16,3890u16),(36083u16,16728u16),(36084u16,9860u16), (36085u16,16724u16),(36087u16,4903u16),(36088u16,10153u16),(36089u16,17199u16), (36090u16,10150u16),(36091u16,10154u16),(36092u16,10152u16),(36093u16,10151u16), (36094u16,17572u16),(36096u16,17575u16),(36098u16,17574u16),(36099u16,2347u16), (36100u16,17573u16),(36101u16,10323u16),(36102u16,17906u16),(36103u16,17907u16), (36104u16,10480u16),(36105u16,17908u16),(36106u16,10481u16),(36107u16,1334u16), (36108u16,4875u16),(36109u16,10607u16),(36111u16,10606u16),(36112u16,18387u16), (36113u16,2351u16),(36114u16,2346u16),(36115u16,10678u16),(36116u16,18388u16), (36117u16,18554u16),(36118u16,10749u16),(36119u16,10750u16),(36120u16,4518u16), (36121u16,18688u16),(36123u16,10835u16),(36124u16,3891u16),(36125u16,1704u16), (36196u16,6195u16),(36198u16,7892u16),(36199u16,7891u16),(36200u16,14943u16), (36201u16,14944u16),(36203u16,9182u16),(36204u16,16729u16),(36205u16,9556u16), (36206u16,16730u16),(36207u16,17200u16),(36208u16,6196u16),(36210u16,12483u16), (36211u16,6962u16),(36212u16,6961u16),(36214u16,13003u16),(36215u16,2354u16), (36216u16,13004u16),(36217u16,13617u16),(36218u16,2764u16),(36219u16,13616u16), (36221u16,13615u16),(36224u16,14270u16),(36225u16,8345u16),(36226u16,4826u16), (36228u16,14269u16),(36229u16,8344u16),(36233u16,14271u16),(36234u16,8343u16), (36236u16,14946u16),(36237u16,14949u16),(36238u16,14947u16),(36239u16,14948u16), (36240u16,14952u16),(36241u16,14945u16),(36242u16,14953u16),(36243u16,14950u16), (36244u16,14951u16),(36245u16,9184u16),(36246u16,15565u16),(36249u16,9183u16), (36251u16,16158u16),(36252u16,16156u16),(36255u16,9557u16),(36256u16,16155u16), (36257u16,16157u16),(36259u16,9558u16),(36261u16,16731u16),(36262u16,4979u16), (36263u16,16732u16),(36264u16,10155u16),(36265u16,2355u16),(36266u16,17910u16), (36267u16,17912u16),(36268u16,17909u16),(36269u16,17911u16),(36270u16,18171u16), (36271u16,18389u16),(36274u16,18887u16),(36275u16,6197u16),(36276u16,6963u16), (36277u16,13005u16),(36278u16,13007u16),(36279u16,13006u16),(36281u16,13620u16), (36282u16,7894u16),(36284u16,13618u16),(36286u16,7893u16),(36287u16,13621u16), (36288u16,1511u16),(36289u16,13622u16),(36290u16,13619u16),(36291u16,3894u16), (36293u16,14283u16),(36294u16,8353u16),(36295u16,14275u16),(36296u16,14281u16), (36299u16,8348u16),(36300u16,8351u16),(36301u16,14274u16),(36302u16,8346u16), (36303u16,14278u16),(36304u16,14959u16),(36305u16,8350u16),(36307u16,14273u16), (36308u16,4852u16),(36309u16,14279u16),(36310u16,14276u16),(36311u16,14282u16), (36312u16,14272u16),(36313u16,14280u16),(36314u16,8349u16),(36315u16,8352u16), (36316u16,14277u16),(36317u16,8347u16),(36319u16,8779u16),(36320u16,14955u16), (36321u16,8778u16),(36322u16,14962u16),(36323u16,14961u16),(36324u16,8785u16), (36326u16,8786u16),(36327u16,14963u16),(36328u16,8780u16),(36329u16,14960u16), (36330u16,8784u16),(36331u16,14965u16),(36332u16,14956u16),(36334u16,14958u16), (36335u16,8781u16),(36336u16,14954u16),(36337u16,14957u16),(36338u16,14964u16), (36339u16,8782u16),(36340u16,14966u16),(36346u16,8783u16),(36348u16,9185u16), (36349u16,15570u16),(36350u16,15576u16),(36351u16,15568u16),(36352u16,15577u16), (36353u16,4855u16),(36354u16,15567u16),(36355u16,15572u16),(36356u16,15578u16), (36357u16,15575u16),(36358u16,15574u16),(36359u16,15573u16),(36361u16,15566u16), (36362u16,15571u16),(36365u16,15569u16),(36366u16,4489u16),(36367u16,9563u16), (36368u16,9560u16),(36369u16,16167u16),(36370u16,16172u16),(36371u16,16174u16), (36372u16,16171u16),(36373u16,16164u16),(36374u16,16166u16),(36375u16,16176u16), (36376u16,16173u16),(36377u16,16168u16),(36378u16,16177u16),(36379u16,16165u16), (36380u16,16175u16),(36381u16,9561u16),(36382u16,9567u16),(36383u16,9565u16), (36384u16,16159u16),(36385u16,9566u16),(36386u16,9562u16),(36387u16,16160u16), (36388u16,16162u16),(36389u16,16161u16),(36390u16,16169u16),(36391u16,16170u16), (36392u16,4858u16),(36393u16,9564u16),(36394u16,3242u16),(36395u16,9559u16), (36397u16,4579u16),(36398u16,16163u16),(36400u16,16742u16),(36401u16,9862u16), (36403u16,16733u16),(36404u16,9863u16),(36405u16,9866u16),(36406u16,16738u16), (36408u16,16735u16),(36409u16,9865u16),(36410u16,3897u16),(36412u16,16739u16), (36413u16,16740u16),(36414u16,16734u16),(36415u16,16743u16),(36416u16,16736u16), (36417u16,16741u16),(36418u16,9864u16),(36420u16,9861u16),(36421u16,16737u16), (36422u16,1423u16),(36423u16,17206u16),(36424u16,10158u16),(36425u16,10156u16), (36426u16,10159u16),(36427u16,10157u16),(36428u16,17205u16),(36429u16,17202u16), (36430u16,17201u16),(36431u16,4853u16),(36432u16,17204u16),(36435u16,17203u16), (36436u16,17589u16),(36437u16,10329u16),(36438u16,17580u16),(36439u16,17579u16), (36441u16,10324u16),(36442u16,17585u16),(36443u16,17584u16),(36444u16,17576u16), (36445u16,17587u16),(36446u16,17581u16),(36447u16,10328u16),(36448u16,17578u16), (36449u16,17586u16),(36450u16,17577u16),(36451u16,10325u16),(36452u16,10327u16), (36453u16,17582u16),(36454u16,10326u16),(36455u16,17583u16),(36456u16,1482u16), (36457u16,17588u16),(36458u16,17916u16),(36460u16,10486u16),(36461u16,17913u16), (36463u16,17917u16),(36465u16,3900u16),(36466u16,10483u16),(36467u16,17915u16), (36468u16,10488u16),(36469u16,4859u16),(36470u16,10485u16),(36471u16,4849u16), (36472u16,17914u16),(36474u16,10487u16),(36475u16,17918u16),(36476u16,10482u16), (36478u16,1441u16),(36480u16,4472u16),(36481u16,10609u16),(36482u16,10611u16), (36484u16,18174u16),(36485u16,10610u16),(36486u16,18172u16),(36487u16,10484u16), (36488u16,18173u16),(36489u16,10608u16),(36490u16,10679u16),(36491u16,10681u16), (36492u16,18391u16),(36493u16,10680u16),(36494u16,18390u16),(36496u16,18559u16), (36497u16,10751u16),(36498u16,18558u16),(36499u16,10752u16),(36500u16,18556u16), (36501u16,18555u16),(36502u16,18560u16),(36503u16,18561u16),(36504u16,18689u16), (36506u16,18557u16),(36509u16,18783u16),(36510u16,18780u16),(36511u16,18781u16), (36512u16,18782u16),(36513u16,10861u16),(36515u16,18857u16),(36516u16,18856u16), (36517u16,18855u16),(36518u16,18888u16),(36519u16,3243u16),(36520u16,18932u16), (36521u16,18913u16),(36522u16,10879u16),(36523u16,6198u16),(36524u16,7411u16), (36525u16,2363u16),(36528u16,3902u16),(36530u16,8787u16),(36534u16,2364u16), (36537u16,1815u16),(36538u16,9568u16),(36540u16,2434u16),(36541u16,16744u16), (36544u16,10330u16),(36546u16,17919u16),(36547u16,2365u16),(36553u16,18914u16), (36554u16,6199u16),(36555u16,6577u16),(36556u16,6965u16),(36557u16,6964u16), (36558u16,3904u16),(36559u16,7414u16),(36561u16,13008u16),(36562u16,7412u16), (36563u16,13009u16),(36564u16,7413u16),(36567u16,13627u16),(36568u16,13623u16), (36570u16,4193u16),(36571u16,7895u16),(36572u16,13626u16),(36573u16,13625u16), (36574u16,13624u16),(36575u16,7896u16),(36576u16,13628u16),(36577u16,13629u16), (36578u16,3905u16),(36580u16,3906u16),(36581u16,14290u16),(36582u16,14288u16), (36583u16,14292u16),(36584u16,14293u16),(36585u16,14299u16),(36587u16,14295u16), (36588u16,14297u16),(36589u16,3907u16),(36590u16,14289u16),(36591u16,14284u16), (36593u16,14296u16),(36594u16,3908u16),(36596u16,14298u16),(36597u16,14291u16), (36598u16,14294u16),(36599u16,14285u16),(36600u16,8355u16),(36601u16,14287u16), (36602u16,14286u16),(36603u16,8354u16),(36604u16,8356u16),(36606u16,8790u16), (36607u16,14968u16),(36608u16,14970u16),(36609u16,14969u16),(36610u16,14974u16), (36611u16,8788u16),(36613u16,14971u16),(36614u16,14967u16),(36615u16,14972u16), (36616u16,14973u16),(36617u16,8789u16),(36618u16,8791u16),(36619u16,4419u16), (36621u16,15582u16),(36622u16,15581u16),(36624u16,15579u16),(36625u16,15580u16), (36626u16,9187u16),(36627u16,9189u16),(36628u16,9186u16),(36629u16,9188u16), (36630u16,16184u16),(36631u16,16185u16),(36632u16,16180u16),(36633u16,2367u16), (36634u16,16181u16),(36635u16,9570u16),(36636u16,9575u16),(36637u16,9569u16), (36638u16,9576u16),(36639u16,9571u16),(36640u16,16182u16),(36643u16,16183u16), (36644u16,16179u16),(36645u16,9577u16),(36646u16,9573u16),(36649u16,9572u16), (36650u16,9574u16),(36652u16,16178u16),(36653u16,2368u16),(36654u16,16746u16), (36655u16,9868u16),(36656u16,3245u16),(36658u16,16748u16),(36659u16,9870u16), (36660u16,16751u16),(36661u16,16747u16),(36662u16,4241u16),(36663u16,16750u16), (36664u16,9869u16),(36665u16,16749u16),(36667u16,9867u16),(36670u16,10161u16), (36671u16,10164u16),(36672u16,17208u16),(36673u16,3582u16),(36674u16,10162u16), (36675u16,17207u16),(36676u16,10160u16),(36677u16,10163u16),(36678u16,17590u16), (36679u16,17591u16),(36680u16,17592u16),(36681u16,10331u16),(36682u16,3246u16), (36683u16,17593u16),(36685u16,10332u16),(36686u16,10490u16),(36687u16,17922u16), (36688u16,17923u16),(36689u16,17921u16),(36690u16,17920u16),(36691u16,17924u16), (36692u16,10489u16),(36693u16,18178u16),(36694u16,18176u16),(36695u16,18177u16), (36696u16,18179u16),(36697u16,18175u16),(36698u16,18180u16),(36699u16,18393u16), (36700u16,4766u16),(36701u16,18394u16),(36702u16,18392u16),(36703u16,10682u16), (36704u16,18562u16),(36705u16,10753u16),(36706u16,18563u16),(36707u16,18691u16), (36708u16,18690u16),(36710u16,1316u16),(36711u16,1317u16),(36718u16,1318u16), (36755u16,3797u16),(36763u16,6200u16),(36764u16,8357u16),(36767u16,8792u16), (36768u16,4108u16),(36771u16,9190u16),(36773u16,2371u16),(36774u16,9872u16), (36775u16,1742u16),(36776u16,9871u16),(36781u16,10491u16),(36782u16,10579u16), (36783u16,10683u16),(36784u16,6201u16),(36785u16,7415u16),(36786u16,8793u16), (36787u16,2375u16),(36788u16,17925u16),(36789u16,10949u16),(36790u16,3995u16), (36791u16,3909u16),(36792u16,19762u16),(36793u16,4461u16),(36794u16,4459u16), (36795u16,3771u16),(36796u16,3773u16),(36798u16,4457u16),(36799u16,11686u16), (36801u16,3910u16),(36802u16,6202u16),(36804u16,6205u16),(36805u16,6204u16), (36806u16,6203u16),(36809u16,11685u16),(36810u16,3911u16),(36811u16,12039u16), (36812u16,3912u16),(36813u16,12041u16),(36814u16,6578u16),(36815u16,1817u16), (36816u16,4428u16),(36817u16,6580u16),(36818u16,12038u16),(36819u16,12040u16), (36820u16,6579u16),(36821u16,12043u16),(36822u16,12042u16),(36823u16,12044u16), (36826u16,4932u16),(36832u16,12487u16),(36833u16,12485u16),(36834u16,6968u16), (36835u16,12484u16),(36836u16,6973u16),(36837u16,6970u16),(36838u16,6967u16), (36840u16,6974u16),(36842u16,6969u16),(36843u16,6972u16),(36845u16,6971u16), (36846u16,12486u16),(36848u16,6966u16),(36852u16,7421u16),(36853u16,13011u16), (36854u16,13017u16),(36855u16,7418u16),(36856u16,7425u16),(36857u16,2382u16), (36858u16,7420u16),(36859u16,13014u16),(36860u16,13016u16),(36861u16,7423u16), (36862u16,13010u16),(36863u16,13013u16),(36864u16,7419u16),(36865u16,7416u16), (36866u16,13012u16),(36867u16,7422u16),(36868u16,13015u16),(36869u16,7424u16), (36870u16,7417u16),(36872u16,4674u16),(36875u16,13631u16),(36876u16,13634u16), (36877u16,7898u16),(36879u16,7908u16),(36880u16,7904u16),(36881u16,13632u16), (36882u16,4453u16),(36884u16,7912u16),(36885u16,7905u16),(36886u16,7910u16), (36887u16,7900u16),(36889u16,7897u16),(36890u16,7899u16),(36891u16,7911u16), (36892u16,13633u16),(36893u16,7903u16),(36894u16,7906u16),(36895u16,7902u16), (36896u16,7907u16),(36897u16,13635u16),(36898u16,7909u16),(36899u16,7901u16), (36900u16,13630u16),(36909u16,14300u16),(36910u16,8358u16),(36911u16,14302u16), (36913u16,8360u16),(36914u16,8362u16),(36915u16,3913u16),(36916u16,14301u16), (36917u16,8359u16),(36918u16,8363u16),(36919u16,2389u16),(36920u16,8361u16), (36924u16,8799u16),(36925u16,14980u16),(36926u16,8807u16),(36927u16,14977u16), (36929u16,8808u16),(36930u16,8797u16),(36932u16,14978u16),(36934u16,1033u16), (36935u16,8802u16),(36937u16,14979u16),(36938u16,8795u16),(36939u16,8794u16), (36940u16,4731u16),(36941u16,8805u16),(36942u16,8804u16),(36943u16,8803u16), (36944u16,8801u16),(36945u16,8806u16),(36946u16,14976u16),(36947u16,8796u16), (36948u16,8798u16),(36949u16,8800u16),(36950u16,4233u16),(36952u16,9192u16), (36953u16,9195u16),(36955u16,9199u16),(36956u16,9193u16),(36957u16,9198u16), (36958u16,9196u16),(36960u16,9191u16),(36961u16,2392u16),(36962u16,9197u16), (36963u16,9194u16),(36964u16,3423u16),(36967u16,16189u16),(36968u16,9580u16), (36969u16,9578u16),(36971u16,16190u16),(36972u16,3703u16),(36973u16,9581u16), (36974u16,9579u16),(36975u16,16188u16),(36976u16,16187u16),(36978u16,9876u16), (36979u16,16186u16),(36980u16,9874u16),(36981u16,9873u16),(36982u16,16752u16), (36983u16,9582u16),(36984u16,9875u16),(36985u16,16753u16),(36986u16,9878u16), (36987u16,16754u16),(36988u16,9877u16),(36989u16,10166u16),(36990u16,17210u16), (36991u16,10165u16),(36992u16,10170u16),(36993u16,10168u16),(36994u16,10169u16), (36995u16,10334u16),(36996u16,10167u16),(36997u16,17209u16),(36998u16,16755u16), (36999u16,10333u16),(37000u16,10335u16),(37002u16,10492u16),(37003u16,10493u16), (37005u16,18181u16),(37007u16,10800u16),(37008u16,10799u16),(37009u16,6207u16), (37012u16,11482u16),(37013u16,7426u16),(37015u16,3259u16),(37016u16,11480u16), (37017u16,11478u16),(37019u16,11481u16),(37022u16,11690u16),(37023u16,11687u16), (37024u16,11692u16),(37025u16,11688u16),(37026u16,6208u16),(37027u16,6211u16), (37029u16,11689u16),(37030u16,6210u16),(37031u16,11691u16),(37032u16,2395u16), (37034u16,6209u16),(37038u16,2399u16),(37039u16,12047u16),(37040u16,12049u16), (37041u16,6583u16),(37042u16,12045u16),(37043u16,12048u16),(37044u16,12046u16), (37045u16,6581u16),(37046u16,6584u16),(37048u16,6582u16),(37051u16,3258u16), (37053u16,12489u16),(37054u16,12493u16),(37055u16,12490u16),(37057u16,6977u16), (37059u16,6978u16),(37060u16,2397u16),(37061u16,12492u16),(37063u16,12494u16), (37064u16,12496u16),(37066u16,6975u16),(37067u16,12495u16),(37070u16,6976u16), (37076u16,13642u16),(37077u16,12491u16),(37078u16,13018u16),(37079u16,13027u16), (37080u16,13025u16),(37081u16,13020u16),(37082u16,13021u16),(37083u16,13026u16), (37084u16,13028u16),(37085u16,7428u16),(37087u16,13023u16),(37088u16,13019u16), (37089u16,7427u16),(37090u16,7429u16),(37091u16,13022u16),(37092u16,13029u16), (37093u16,13024u16),(37096u16,7913u16),(37097u16,13645u16),(37098u16,13637u16), (37099u16,13643u16),(37100u16,13644u16),(37101u16,7914u16),(37103u16,13636u16), (37104u16,13638u16),(37105u16,12488u16),(37106u16,13640u16),(37107u16,13641u16), (37108u16,13639u16),(37109u16,8365u16),(37113u16,14309u16),(37114u16,16756u16), (37115u16,14310u16),(37116u16,14307u16),(37117u16,2400u16),(37118u16,8367u16), (37119u16,14306u16),(37120u16,14312u16),(37121u16,14311u16),(37122u16,8364u16), (37123u16,14315u16),(37124u16,4279u16),(37125u16,14314u16),(37126u16,14303u16), (37127u16,14313u16),(37128u16,14308u16),(37129u16,8366u16),(37131u16,14987u16), (37133u16,14982u16),(37134u16,14988u16),(37135u16,14983u16),(37136u16,14981u16), (37137u16,14984u16),(37138u16,8809u16),(37140u16,14986u16),(37142u16,14985u16), (37143u16,8810u16),(37144u16,9201u16),(37145u16,9200u16),(37146u16,15589u16), (37147u16,15592u16),(37148u16,15584u16),(37149u16,15588u16),(37150u16,9202u16), (37151u16,15587u16),(37152u16,15585u16),(37153u16,15591u16),(37154u16,15586u16), (37155u16,15583u16),(37156u16,15590u16),(37158u16,16196u16),(37159u16,9585u16), (37160u16,17594u16),(37161u16,16193u16),(37162u16,16194u16),(37163u16,16192u16), (37164u16,14304u16),(37165u16,9584u16),(37166u16,16197u16),(37167u16,16191u16), (37168u16,9583u16),(37169u16,9586u16),(37170u16,16195u16),(37171u16,16757u16), (37172u16,9879u16),(37173u16,16758u16),(37174u16,16759u16),(37176u16,17211u16), (37177u16,10171u16),(37178u16,17595u16),(37179u16,17596u16),(37182u16,17597u16), (37183u16,17927u16),(37184u16,17926u16),(37185u16,18183u16),(37187u16,18182u16), (37188u16,18396u16),(37189u16,18397u16),(37190u16,18395u16),(37191u16,18564u16), (37192u16,10754u16),(37193u16,6212u16),(37194u16,6980u16),(37195u16,6979u16), (37196u16,7432u16),(37197u16,7431u16),(37198u16,13031u16),(37199u16,13032u16), (37200u16,13030u16),(37201u16,4790u16),(37202u16,7430u16),(37203u16,13649u16), (37205u16,13650u16),(37206u16,13646u16),(37207u16,7916u16),(37208u16,13647u16), (37209u16,4786u16),(37210u16,13648u16),(37212u16,4788u16),(37214u16,1331u16), (37215u16,14318u16),(37216u16,14320u16),(37217u16,14316u16),(37218u16,14319u16), (37219u16,8368u16),(37220u16,14317u16),(37221u16,8369u16),(37223u16,2401u16), (37224u16,14495u16),(37225u16,8813u16),(37226u16,8812u16),(37228u16,8811u16), (37230u16,14989u16),(37231u16,14990u16),(37232u16,4602u16),(37234u16,15594u16), (37235u16,15596u16),(37236u16,9206u16),(37237u16,9203u16),(37238u16,4563u16), (37239u16,9205u16),(37240u16,9204u16),(37241u16,15595u16),(37242u16,15593u16), (37244u16,4832u16),(37248u16,16204u16),(37249u16,16201u16),(37250u16,16202u16), (37251u16,9590u16),(37252u16,16203u16),(37253u16,16198u16),(37254u16,16199u16), (37255u16,9587u16),(37257u16,9588u16),(37258u16,16200u16),(37259u16,9589u16), (37260u16,1329u16),(37261u16,16763u16),(37262u16,4796u16),(37263u16,16764u16), (37264u16,16761u16),(37265u16,16762u16),(37266u16,9880u16),(37267u16,16760u16), (37273u16,17215u16),(37274u16,17212u16),(37275u16,17214u16),(37276u16,10174u16), (37277u16,17218u16),(37278u16,10173u16),(37279u16,17216u16),(37280u16,17219u16), (37281u16,17217u16),(37282u16,17213u16),(37283u16,10172u16),(37285u16,17599u16), (37287u16,17600u16),(37288u16,17598u16),(37289u16,2403u16),(37290u16,17602u16), (37291u16,10336u16),(37292u16,10337u16),(37293u16,17929u16),(37294u16,10495u16), (37295u16,17601u16),(37296u16,17928u16),(37297u16,10494u16),(37298u16,18186u16), (37299u16,18187u16),(37300u16,10612u16),(37301u16,18185u16),(37302u16,1605u16), (37303u16,18184u16),(37305u16,18398u16),(37306u16,10684u16),(37307u16,3262u16), (37308u16,18692u16),(37309u16,18785u16),(37310u16,18784u16),(37312u16,10836u16), (37313u16,10862u16),(37314u16,18786u16),(37315u16,18889u16),(37316u16,2404u16), (37317u16,10880u16),(37318u16,6213u16),(37319u16,6585u16),(37321u16,8814u16), (37323u16,10613u16),(37324u16,6214u16),(37325u16,6981u16),(37326u16,7917u16), (37327u16,8370u16),(37328u16,10338u16),(37329u16,6586u16),(37331u16,12498u16), (37332u16,4206u16),(37333u16,13033u16),(37334u16,19341u16),(37335u16,7435u16), (37336u16,7433u16),(37337u16,7437u16),(37338u16,13035u16),(37340u16,7436u16), (37341u16,7434u16),(37343u16,1265u16),(37346u16,13034u16),(37347u16,7920u16), (37348u16,13656u16),(37349u16,3324u16),(37350u16,7919u16),(37351u16,7921u16), (37352u16,13661u16),(37353u16,7923u16),(37354u16,13658u16),(37355u16,13659u16), (37356u16,13651u16),(37357u16,7922u16),(37358u16,13662u16),(37361u16,13653u16), (37363u16,13654u16),(37364u16,13652u16),(37365u16,7918u16),(37366u16,1743u16), (37367u16,13660u16),(37368u16,13655u16),(37369u16,13657u16),(37370u16,3051u16), (37373u16,14332u16),(37374u16,2313u16),(37375u16,14331u16),(37376u16,14329u16), (37377u16,14321u16),(37378u16,14336u16),(37379u16,14324u16),(37380u16,14334u16), (37381u16,14341u16),(37382u16,14333u16),(37383u16,8378u16),(37384u16,4604u16), (37385u16,8374u16),(37386u16,14322u16),(37388u16,14328u16),(37389u16,8376u16), (37390u16,2408u16),(37391u16,14327u16),(37392u16,8377u16),(37393u16,8379u16), (37394u16,14330u16),(37395u16,3917u16),(37396u16,8371u16),(37397u16,8372u16), (37398u16,14342u16),(37399u16,14340u16),(37400u16,1022u16),(37401u16,14339u16), (37402u16,14325u16),(37404u16,14337u16),(37406u16,8375u16),(37409u16,1820u16), (37411u16,8373u16),(37412u16,14338u16),(37413u16,14323u16),(37414u16,14326u16), (37415u16,14335u16),(37416u16,3919u16),(37418u16,3332u16),(37419u16,3227u16), (37421u16,15631u16),(37422u16,15000u16),(37424u16,14993u16),(37425u16,15012u16), (37426u16,15021u16),(37427u16,14996u16),(37428u16,8825u16),(37429u16,3097u16), (37430u16,15009u16),(37431u16,8815u16),(37432u16,8817u16),(37433u16,8829u16), (37434u16,14994u16),(37436u16,19463u16),(37437u16,8818u16),(37438u16,8820u16), (37439u16,8830u16),(37440u16,8819u16),(37441u16,2410u16),(37444u16,2428u16), (37445u16,8828u16),(37446u16,15002u16),(37448u16,14991u16),(37449u16,8826u16), (37450u16,15001u16),(37451u16,8822u16),(37452u16,15019u16),(37453u16,8827u16), (37454u16,15017u16),(37455u16,15005u16),(37456u16,15015u16),(37457u16,8824u16), (37458u16,14992u16),(37459u16,15018u16),(37460u16,15013u16),(37461u16,4409u16), (37462u16,15020u16),(37463u16,8816u16),(37464u16,3920u16),(37466u16,8831u16), (37467u16,8821u16),(37469u16,2798u16),(37470u16,14998u16),(37471u16,3543u16), (37472u16,15006u16),(37473u16,15010u16),(37474u16,2411u16),(37475u16,15014u16), (37476u16,8823u16),(37477u16,14997u16),(37478u16,14995u16),(37479u16,15007u16), (37483u16,3921u16),(37484u16,15004u16),(37485u16,15003u16),(37486u16,3580u16), (37487u16,15008u16),(37488u16,15011u16),(37490u16,15016u16),(37494u16,15599u16), (37495u16,3419u16),(37496u16,9207u16),(37497u16,15609u16),(37498u16,15601u16), (37499u16,9212u16),(37500u16,9216u16),(37501u16,15618u16),(37502u16,15626u16), (37503u16,15611u16),(37504u16,9208u16),(37505u16,4309u16),(37506u16,15615u16), (37507u16,14999u16),(37508u16,3504u16),(37509u16,9209u16),(37510u16,15622u16), (37511u16,15627u16),(37512u16,15619u16),(37513u16,2983u16),(37514u16,15621u16), (37515u16,15630u16),(37516u16,15623u16),(37517u16,15605u16),(37518u16,15614u16), (37519u16,2813u16),(37521u16,9217u16),(37523u16,9213u16),(37524u16,15603u16), (37525u16,15616u16),(37526u16,9211u16),(37527u16,15610u16),(37528u16,9210u16), (37529u16,15624u16),(37530u16,15607u16),(37531u16,15600u16),(37532u16,9214u16), (37533u16,15629u16),(37536u16,15602u16),(37537u16,15620u16),(37538u16,15617u16), (37539u16,15612u16),(37540u16,15598u16),(37541u16,15597u16),(37542u16,15606u16), (37543u16,15625u16),(37544u16,9215u16),(37545u16,15628u16),(37546u16,15604u16), (37547u16,15608u16),(37548u16,9595u16),(37550u16,3923u16),(37553u16,3922u16), (37554u16,9603u16),(37555u16,9598u16),(37556u16,16237u16),(37557u16,16234u16), (37558u16,16210u16),(37559u16,9593u16),(37561u16,2413u16),(37562u16,3307u16), (37563u16,9592u16),(37564u16,9599u16),(37566u16,3415u16),(37567u16,3924u16), (37568u16,16208u16),(37569u16,9597u16),(37570u16,16220u16),(37571u16,16206u16), (37572u16,16207u16),(37573u16,9591u16),(37574u16,16236u16),(37575u16,9601u16), (37576u16,16223u16),(37577u16,16228u16),(37578u16,16222u16),(37579u16,16782u16), (37580u16,16218u16),(37581u16,16226u16),(37582u16,16224u16),(37583u16,16211u16), (37584u16,16205u16),(37585u16,16232u16),(37586u16,9600u16),(37587u16,16233u16), (37588u16,2366u16),(37589u16,16227u16),(37591u16,16216u16),(37592u16,16214u16), (37593u16,16209u16),(37595u16,18998u16),(37597u16,16217u16),(37598u16,16230u16), (37599u16,16213u16),(37600u16,16229u16),(37601u16,16235u16),(37603u16,3925u16), (37604u16,9596u16),(37605u16,3481u16),(37606u16,16225u16),(37607u16,16231u16), (37608u16,16221u16),(37609u16,16215u16),(37610u16,9594u16),(37611u16,3926u16), (37612u16,2635u16),(37614u16,15613u16),(37615u16,16219u16),(37616u16,9602u16), (37617u16,16212u16),(37618u16,2980u16),(37619u16,3927u16),(37620u16,3928u16), (37622u16,3322u16),(37623u16,16788u16),(37624u16,9883u16),(37625u16,16787u16), (37626u16,16784u16),(37627u16,16803u16),(37628u16,9887u16),(37629u16,3929u16), (37630u16,16800u16),(37631u16,16792u16),(37632u16,16802u16),(37633u16,16777u16), (37634u16,16790u16),(37635u16,2372u16),(37636u16,9889u16),(37638u16,16769u16), (37639u16,3076u16),(37640u16,16767u16),(37641u16,16801u16),(37643u16,16799u16), (37644u16,16798u16),(37645u16,16781u16),(37646u16,16780u16),(37647u16,16770u16), (37648u16,9891u16),(37650u16,16776u16),(37651u16,16786u16),(37652u16,16797u16), (37653u16,9894u16),(37654u16,16804u16),(37656u16,10182u16),(37657u16,9896u16), (37658u16,9890u16),(37659u16,16774u16),(37661u16,16783u16),(37662u16,16766u16), (37663u16,16768u16),(37664u16,9881u16),(37665u16,9893u16),(37666u16,9886u16), (37667u16,16775u16),(37668u16,16791u16),(37669u16,16785u16),(37670u16,9892u16), (37671u16,16765u16),(37672u16,10177u16),(37673u16,16793u16),(37674u16,16796u16), (37675u16,9888u16),(37676u16,2419u16),(37677u16,16779u16),(37678u16,9895u16), (37679u16,9885u16),(37680u16,4312u16),(37681u16,3508u16),(37683u16,9884u16), (37684u16,16789u16),(37685u16,16795u16),(37686u16,9882u16),(37688u16,16772u16), (37689u16,16794u16),(37692u16,16773u16),(37696u16,19332u16),(37697u16,19630u16), (37698u16,3053u16),(37699u16,3930u16),(37700u16,19008u16),(37701u16,4523u16), (37702u16,16778u16),(37703u16,17225u16),(37704u16,3416u16),(37705u16,17230u16), (37706u16,10179u16),(37707u16,10181u16),(37708u16,17236u16),(37709u16,10175u16), (37710u16,17251u16),(37711u16,17242u16),(37712u16,17231u16),(37713u16,17232u16), (37714u16,17241u16),(37716u16,10188u16),(37717u16,17240u16),(37718u16,17224u16), (37719u16,17239u16),(37720u16,17227u16),(37721u16,17252u16),(37722u16,10187u16), (37723u16,10185u16),(37724u16,17228u16),(37726u16,17247u16),(37727u16,3506u16), (37728u16,17233u16),(37729u16,17246u16),(37730u16,19615u16),(37731u16,17248u16), (37732u16,17223u16),(37733u16,10180u16),(37734u16,2800u16),(37735u16,17249u16), (37736u16,3302u16),(37737u16,2632u16),(37738u16,17237u16),(37739u16,2420u16), (37740u16,10184u16),(37741u16,17234u16),(37742u16,2771u16),(37744u16,10186u16), (37745u16,17243u16),(37747u16,2432u16),(37748u16,3547u16),(37749u16,10178u16), (37750u16,17229u16),(37751u16,17244u16),(37752u16,2524u16),(37753u16,17238u16), (37754u16,16771u16),(37755u16,17245u16),(37756u16,17226u16),(37757u16,3355u16), (37758u16,10183u16),(37760u16,17250u16),(37761u16,2636u16),(37762u16,10176u16), (37763u16,17221u16),(37764u16,3931u16),(37765u16,19703u16),(37766u16,3511u16), (37767u16,3027u16),(37768u16,17616u16),(37769u16,17609u16),(37770u16,10340u16), (37772u16,17604u16),(37773u16,17619u16),(37774u16,17611u16),(37775u16,17235u16), (37776u16,3635u16),(37777u16,17621u16),(37778u16,17605u16),(37780u16,10339u16), (37781u16,17615u16),(37782u16,10341u16),(37783u16,10349u16),(37784u16,10347u16), (37785u16,17617u16),(37786u16,10348u16),(37787u16,17607u16),(37788u16,2707u16), (37789u16,17608u16),(37790u16,17613u16),(37791u16,17618u16),(37792u16,2979u16), (37793u16,17220u16),(37794u16,10342u16),(37795u16,17626u16),(37796u16,17623u16), (37797u16,17627u16),(37798u16,17614u16),(37799u16,17610u16),(37800u16,17624u16), (37801u16,17940u16),(37802u16,17612u16),(37804u16,10345u16),(37805u16,3932u16), (37806u16,10344u16),(37807u16,17222u16),(37808u16,10346u16),(37809u16,17620u16), (37810u16,17622u16),(37811u16,10343u16),(37812u16,17625u16),(37813u16,17603u16), (37815u16,17606u16),(37816u16,3463u16),(37819u16,3462u16),(37821u16,2836u16), (37823u16,4367u16),(37824u16,17949u16),(37826u16,17933u16),(37827u16,10499u16), (37828u16,17947u16),(37830u16,2705u16),(37831u16,17931u16),(37832u16,10500u16), (37834u16,17942u16),(37835u16,2637u16),(37836u16,17938u16),(37837u16,10505u16), (37838u16,17948u16),(37839u16,17932u16),(37840u16,17935u16),(37841u16,10497u16), (37842u16,17950u16),(37843u16,19211u16),(37844u16,17943u16),(37845u16,17946u16), (37846u16,10503u16),(37847u16,10508u16),(37848u16,10506u16),(37849u16,17939u16), (37850u16,17934u16),(37851u16,3414u16),(37852u16,10501u16),(37853u16,10502u16), (37854u16,17930u16),(37855u16,10498u16),(37856u16,2829u16),(37857u16,10496u16), (37858u16,10504u16),(37859u16,17945u16),(37860u16,10507u16),(37862u16,17941u16), (37863u16,17951u16),(37864u16,10509u16),(37868u16,17937u16),(37870u16,17944u16), (37872u16,19573u16),(37873u16,19683u16),(37875u16,2633u16),(37876u16,1769u16), (37877u16,18200u16),(37878u16,18214u16),(37879u16,18202u16),(37880u16,18209u16), (37881u16,17936u16),(37882u16,18207u16),(37883u16,18190u16),(37884u16,18212u16), (37885u16,10616u16),(37886u16,18194u16),(37887u16,18211u16),(37888u16,18201u16), (37889u16,3531u16),(37891u16,10615u16),(37892u16,3263u16),(37894u16,18216u16), (37895u16,18203u16),(37896u16,2834u16),(37897u16,18208u16),(37898u16,18210u16), (37899u16,18188u16),(37900u16,18213u16),(37901u16,18199u16),(37902u16,18204u16), (37903u16,18192u16),(37904u16,18196u16),(37905u16,18215u16),(37906u16,18206u16), (37907u16,18189u16),(37908u16,18193u16),(37909u16,18195u16),(37910u16,18205u16), (37911u16,3936u16),(37912u16,10614u16),(37913u16,18198u16),(37915u16,19316u16), (37917u16,3938u16),(37920u16,18191u16),(37924u16,2602u16),(37925u16,2483u16), (37926u16,2437u16),(37927u16,3267u16),(37928u16,18197u16),(37929u16,18402u16), (37930u16,18407u16),(37931u16,10691u16),(37932u16,18409u16),(37933u16,3939u16), (37934u16,10685u16),(37935u16,1017u16),(37936u16,18405u16),(37937u16,18411u16), (37938u16,10690u16),(37939u16,10686u16),(37941u16,10687u16),(37942u16,18401u16), (37943u16,18408u16),(37944u16,10689u16),(37945u16,18406u16),(37946u16,10688u16), (37947u16,18400u16),(37948u16,18404u16),(37949u16,18403u16),(37950u16,3940u16), (37951u16,18399u16),(37952u16,18410u16),(37954u16,19625u16),(37955u16,19628u16), (37956u16,10755u16),(37957u16,18571u16),(37958u16,18574u16),(37959u16,18570u16), (37960u16,18572u16),(37961u16,18573u16),(37962u16,18567u16),(37963u16,18568u16), (37964u16,18565u16),(37965u16,3420u16),(37967u16,18569u16),(37968u16,18566u16), (37969u16,10756u16),(37970u16,10757u16),(37972u16,3942u16),(37973u16,18694u16), (37975u16,18696u16),(37976u16,3366u16),(37979u16,2433u16),(37981u16,18695u16), (37982u16,18697u16),(37984u16,10802u16),(37986u16,18693u16),(37987u16,10801u16), (37988u16,10803u16),(37989u16,4253u16),(37991u16,2986u16),(37992u16,18788u16), (37993u16,18789u16),(37994u16,10837u16),(37995u16,18787u16),(37996u16,2129u16), (37997u16,18859u16),(37998u16,18858u16),(37999u16,18860u16),(38000u16,10864u16), (38001u16,18861u16),(38002u16,10863u16),(38003u16,18862u16),(38004u16,18890u16), (38005u16,18893u16),(38006u16,18892u16),(38007u16,10873u16),(38008u16,18891u16), (38009u16,3943u16),(38011u16,19406u16),(38012u16,10883u16),(38013u16,10881u16), (38014u16,10882u16),(38015u16,10888u16),(38016u16,18934u16),(38017u16,18935u16), (38018u16,18933u16),(38019u16,18943u16),(38021u16,1705u16),(38047u16,4316u16), (38050u16,1725u16),(38081u16,4015u16),(38083u16,4011u16),(38108u16,4001u16), (38134u16,3994u16),(38189u16,3944u16),(38215u16,4448u16),(38263u16,6587u16), (38264u16,1706u16),(38266u16,13663u16),(38267u16,14343u16),(38268u16,16238u16), (38269u16,17952u16),(38271u16,1707u16),(38272u16,6588u16),(38274u16,6982u16), (38275u16,7438u16),(38277u16,2435u16),(38278u16,13664u16),(38280u16,13665u16), (38281u16,7924u16),(38283u16,8382u16),(38284u16,14345u16),(38285u16,14344u16), (38286u16,8386u16),(38287u16,8381u16),(38288u16,14346u16),(38289u16,8383u16), (38290u16,8385u16),(38291u16,8384u16),(38292u16,8380u16),(38294u16,3275u16), (38295u16,3274u16),(38296u16,8832u16),(38297u16,3272u16),(38299u16,15025u16), (38300u16,15023u16),(38302u16,15024u16),(38303u16,15022u16),(38304u16,2438u16), (38305u16,9218u16),(38306u16,3945u16),(38307u16,9221u16),(38308u16,9223u16), (38309u16,9222u16),(38310u16,2436u16),(38311u16,3273u16),(38312u16,9219u16), (38313u16,9220u16),(38314u16,1586u16),(38315u16,16240u16),(38316u16,16239u16), (38317u16,9604u16),(38318u16,16241u16),(38320u16,16242u16),(38321u16,9605u16), (38325u16,16812u16),(38326u16,16810u16),(38327u16,17258u16),(38329u16,16808u16), (38330u16,16809u16),(38331u16,9897u16),(38332u16,16805u16),(38333u16,16813u16), (38334u16,16807u16),(38335u16,16811u16),(38336u16,17254u16),(38339u16,17256u16), (38341u16,17257u16),(38342u16,10193u16),(38343u16,17253u16),(38344u16,10192u16), (38345u16,17255u16),(38346u16,10189u16),(38347u16,10190u16),(38348u16,10191u16), (38349u16,16806u16),(38352u16,10352u16),(38353u16,17630u16),(38354u16,17628u16), (38355u16,17629u16),(38356u16,10350u16),(38357u16,10353u16),(38358u16,10351u16), (38362u16,17953u16),(38363u16,17954u16),(38364u16,10510u16),(38366u16,18217u16), (38367u16,18219u16),(38368u16,18218u16),(38369u16,10617u16),(38370u16,10692u16), (38371u16,18414u16),(38372u16,18413u16),(38373u16,18412u16),(38376u16,1708u16), (38388u16,3947u16),(38428u16,6589u16),(38429u16,1723u16),(38430u16,11376u16), (38432u16,11485u16),(38433u16,5944u16),(38434u16,11483u16),(38435u16,11486u16), (38436u16,11484u16),(38440u16,11694u16),(38442u16,6218u16),(38444u16,6219u16), (38445u16,11696u16),(38446u16,6216u16),(38447u16,11695u16),(38448u16,11693u16), (38449u16,6217u16),(38450u16,6215u16),(38451u16,3948u16),(38456u16,4939u16), (38457u16,12050u16),(38458u16,12053u16),(38459u16,6592u16),(38460u16,12052u16), (38461u16,12051u16),(38463u16,6591u16),(38464u16,6590u16),(38465u16,4778u16), (38466u16,6594u16),(38467u16,12054u16),(38468u16,6593u16),(38469u16,3874u16), (38474u16,12503u16),(38475u16,6984u16),(38476u16,6985u16),(38477u16,6986u16), (38478u16,12504u16),(38479u16,12500u16),(38480u16,6983u16),(38481u16,12501u16), (38483u16,12502u16),(38484u16,12499u16),(38486u16,4264u16),(38488u16,7445u16), (38491u16,7442u16),(38492u16,13036u16),(38493u16,7443u16),(38494u16,7446u16), (38495u16,13037u16),(38497u16,7441u16),(38498u16,7439u16),(38499u16,7440u16), (38500u16,7444u16),(38505u16,3851u16),(38506u16,7925u16),(38507u16,13668u16), (38508u16,7933u16),(38509u16,13667u16),(38511u16,13670u16),(38512u16,7929u16), (38513u16,13669u16),(38514u16,8394u16),(38515u16,7927u16),(38516u16,7930u16), (38517u16,7926u16),(38518u16,7931u16),(38519u16,7932u16),(38520u16,7928u16), (38523u16,2447u16),(38524u16,13666u16),(38525u16,8390u16),(38526u16,14348u16), (38528u16,14352u16),(38529u16,4787u16),(38531u16,14351u16),(38532u16,8395u16), (38533u16,8391u16),(38534u16,8392u16),(38535u16,14347u16),(38536u16,14349u16), (38537u16,14350u16),(38538u16,8387u16),(38539u16,8389u16),(38541u16,8393u16), (38542u16,8388u16),(38543u16,3284u16),(38545u16,15028u16),(38546u16,15026u16), (38547u16,15027u16),(38548u16,8834u16),(38549u16,8835u16),(38550u16,2448u16), (38551u16,15029u16),(38552u16,8833u16),(38553u16,9224u16),(38555u16,9226u16), (38556u16,9225u16),(38558u16,15632u16),(38561u16,15633u16),(38562u16,16244u16), (38563u16,2450u16),(38564u16,16243u16),(38565u16,19755u16),(38567u16,9898u16), (38568u16,9899u16),(38569u16,16814u16),(38570u16,9900u16),(38572u16,17261u16), (38574u16,17259u16),(38576u16,17260u16),(38577u16,10194u16),(38579u16,17631u16), (38580u16,10511u16),(38582u16,2453u16),(38584u16,10195u16),(38585u16,6595u16), (38587u16,7447u16),(38588u16,13038u16),(38589u16,2456u16),(38591u16,13671u16), (38592u16,7934u16),(38593u16,8396u16),(38594u16,14353u16),(38595u16,14355u16), (38596u16,8398u16),(38597u16,8397u16),(38598u16,8399u16),(38599u16,8400u16), (38600u16,14354u16),(38601u16,8838u16),(38602u16,8839u16),(38603u16,8837u16), (38604u16,9227u16),(38605u16,8836u16),(38606u16,15030u16),(38610u16,9228u16), (38611u16,16245u16),(38612u16,16815u16),(38613u16,9901u16),(38614u16,10196u16), (38615u16,17632u16),(38616u16,17636u16),(38617u16,10356u16),(38618u16,17633u16), (38619u16,10357u16),(38620u16,10355u16),(38621u16,17637u16),(38622u16,10358u16), (38623u16,17635u16),(38625u16,17955u16),(38626u16,10354u16),(38627u16,10512u16), (38629u16,18790u16),(38632u16,6596u16),(38633u16,7936u16),(38634u16,7935u16), (38639u16,8401u16),(38640u16,14357u16),(38641u16,14356u16),(38642u16,8402u16), (38644u16,2799u16),(38645u16,15034u16),(38646u16,8843u16),(38647u16,8840u16), (38648u16,15033u16),(38649u16,8842u16),(38650u16,15031u16),(38651u16,8841u16), (38653u16,15032u16),(38655u16,15634u16),(38656u16,9229u16),(38658u16,16248u16), (38659u16,4728u16),(38660u16,9606u16),(38661u16,16246u16),(38662u16,9607u16), (38663u16,9608u16),(38664u16,16247u16),(38665u16,9609u16),(38667u16,16816u16), (38669u16,9905u16),(38670u16,9902u16),(38671u16,9907u16),(38672u16,16818u16), (38673u16,9903u16),(38674u16,16817u16),(38675u16,9906u16),(38678u16,9904u16), (38680u16,17264u16),(38681u16,17266u16),(38683u16,2476u16),(38684u16,10197u16), (38685u16,17265u16),(38686u16,10198u16),(38687u16,17263u16),(38688u16,17262u16), (38689u16,4905u16),(38690u16,17639u16),(38691u16,17638u16),(38692u16,10359u16), (38693u16,17640u16),(38694u16,17960u16),(38695u16,10514u16),(38696u16,17959u16), (38697u16,17956u16),(38698u16,10513u16),(38699u16,17957u16),(38700u16,17958u16), (38702u16,18220u16),(38703u16,18221u16),(38704u16,10618u16),(38705u16,2467u16), (38706u16,10695u16),(38708u16,985u16),(38709u16,18415u16),(38710u16,2469u16), (38712u16,10693u16),(38713u16,10694u16),(38714u16,18416u16),(38717u16,10758u16), (38718u16,10759u16),(38719u16,18575u16),(38720u16,3952u16),(38721u16,3295u16), (38722u16,10838u16),(38723u16,18792u16),(38724u16,10840u16),(38726u16,18791u16), (38727u16,18793u16),(38728u16,10839u16),(38729u16,18863u16),(38730u16,1021u16), (38731u16,18915u16),(38737u16,1668u16),(38738u16,6597u16),(38741u16,1765u16), (38742u16,8844u16),(38743u16,2479u16),(38744u16,15635u16),(38746u16,16249u16), (38747u16,9908u16),(38748u16,2477u16),(38749u16,3301u16),(38750u16,6598u16), (38751u16,2482u16),(38752u16,9610u16),(38753u16,10515u16),(38754u16,6987u16), (38758u16,9910u16),(38760u16,10804u16),(38761u16,6988u16),(38762u16,13672u16), (38764u16,14358u16),(38765u16,4559u16),(38766u16,14360u16),(38768u16,14359u16), (38769u16,3314u16),(38770u16,15038u16),(38771u16,15035u16),(38772u16,8845u16), (38774u16,8846u16),(38775u16,15036u16),(38776u16,15037u16),(38778u16,15637u16), (38779u16,15642u16),(38780u16,9230u16),(38781u16,15636u16),(38782u16,15638u16), (38783u16,15645u16),(38784u16,15640u16),(38785u16,15644u16),(38786u16,15641u16), (38787u16,15639u16),(38788u16,15643u16),(38789u16,9231u16),(38791u16,19178u16), (38792u16,16252u16),(38793u16,2487u16),(38794u16,16250u16),(38795u16,9612u16), (38797u16,9611u16),(38798u16,16251u16),(38799u16,9613u16),(38804u16,16821u16), (38807u16,16820u16),(38808u16,9911u16),(38809u16,16819u16),(38810u16,17267u16), (38811u16,3313u16),(38812u16,17269u16),(38813u16,17271u16),(38814u16,17270u16), (38815u16,2488u16),(38816u16,10199u16),(38817u16,17268u16),(38818u16,17647u16), (38819u16,10360u16),(38820u16,17645u16),(38821u16,17648u16),(38822u16,10361u16), (38824u16,17643u16),(38826u16,17646u16),(38827u16,17644u16),(38828u16,17641u16), (38829u16,10362u16),(38830u16,17642u16),(38833u16,2489u16),(38834u16,3954u16), (38835u16,17961u16),(38836u16,4768u16),(38838u16,17963u16),(38839u16,17962u16), (38840u16,4110u16),(38841u16,18222u16),(38842u16,4770u16),(38843u16,18223u16), (38845u16,19329u16),(38846u16,2490u16),(38847u16,18417u16),(38848u16,2491u16), (38849u16,10761u16),(38850u16,3955u16),(38851u16,10760u16),(38852u16,18698u16), (38853u16,18699u16),(38854u16,10841u16),(38855u16,18794u16),(38856u16,4764u16), (38857u16,10874u16),(38859u16,6989u16),(38860u16,8403u16),(38861u16,15647u16), (38862u16,15646u16),(38863u16,16254u16),(38864u16,16253u16),(38866u16,2492u16), (38867u16,10200u16),(38868u16,17273u16),(38869u16,17272u16),(38870u16,17651u16), (38871u16,17649u16),(38872u16,17652u16),(38873u16,17650u16),(38876u16,10516u16), (38877u16,17964u16),(38878u16,17965u16),(38879u16,17966u16),(38880u16,2493u16), (38881u16,18418u16),(38883u16,18576u16),(38885u16,18795u16),(38886u16,1710u16), (38893u16,6990u16),(38894u16,2495u16),(38896u16,16822u16),(38897u16,17274u16), (38898u16,2612u16),(38899u16,6991u16),(38901u16,2499u16),(38902u16,9232u16), (38904u16,16823u16),(38905u16,10363u16),(38906u16,17653u16),(38907u16,10517u16), (38909u16,18224u16),(38910u16,18225u16),(38911u16,2498u16),(38912u16,18700u16), (38913u16,6992u16),(38914u16,7939u16),(38915u16,7940u16),(38916u16,13673u16), (38917u16,8404u16),(38918u16,8405u16),(38919u16,14361u16),(38920u16,8406u16), (38922u16,8850u16),(38924u16,8852u16),(38925u16,15040u16),(38926u16,15041u16), (38927u16,15039u16),(38928u16,8847u16),(38929u16,8848u16),(38930u16,8851u16), (38931u16,8849u16),(38932u16,19401u16),(38933u16,1465u16),(38934u16,15648u16), (38935u16,9233u16),(38936u16,9234u16),(38939u16,16261u16),(38940u16,9616u16), (38941u16,16256u16),(38942u16,16255u16),(38943u16,3320u16),(38944u16,16260u16), (38945u16,9614u16),(38947u16,4380u16),(38948u16,9918u16),(38950u16,16257u16), (38951u16,16262u16),(38952u16,16259u16),(38953u16,16258u16),(38955u16,9615u16), (38957u16,9916u16),(38958u16,4835u16),(38959u16,16825u16),(38960u16,9912u16), (38962u16,16826u16),(38963u16,2504u16),(38964u16,2503u16),(38965u16,16824u16), (38967u16,9915u16),(38968u16,9913u16),(38969u16,9917u16),(38971u16,9914u16), (38977u16,17275u16),(38979u16,17280u16),(38980u16,17276u16),(38981u16,17279u16), (38982u16,10201u16),(38983u16,4112u16),(38984u16,17070u16),(38985u16,17278u16), (38986u16,17277u16),(38987u16,2505u16),(38988u16,10366u16),(38989u16,10364u16), (38990u16,10367u16),(38991u16,10365u16),(38992u16,17654u16),(38993u16,17655u16), (38994u16,17656u16),(38995u16,10368u16),(38998u16,1881u16),(38999u16,17970u16), (39000u16,10519u16),(39001u16,17968u16),(39003u16,10520u16),(39004u16,17967u16), (39005u16,17969u16),(39006u16,10518u16),(39007u16,18229u16),(39008u16,18226u16), (39010u16,18227u16),(39011u16,18228u16),(39012u16,18419u16),(39013u16,10698u16), (39014u16,2506u16),(39015u16,10697u16),(39016u16,1830u16),(39017u16,18578u16), (39018u16,18577u16),(39019u16,10762u16),(39020u16,19039u16),(39023u16,10805u16), (39024u16,10842u16),(39025u16,10865u16),(39026u16,18864u16),(39027u16,18916u16), (39028u16,18917u16),(39029u16,1711u16),(39080u16,6993u16),(39081u16,14362u16), (39084u16,15042u16),(39085u16,15649u16),(39086u16,15650u16),(39087u16,9235u16), (39089u16,9236u16),(39090u16,16263u16),(39091u16,9617u16),(39092u16,4836u16), (39094u16,10202u16),(39095u16,2514u16),(39096u16,17657u16),(39097u16,3959u16), (39098u16,10369u16),(39099u16,17973u16),(39100u16,10521u16),(39101u16,17972u16), (39102u16,17974u16),(39103u16,17971u16),(39104u16,18422u16),(39105u16,18230u16), (39106u16,18231u16),(39107u16,3181u16),(39108u16,10619u16),(39110u16,18421u16), (39111u16,2516u16),(39112u16,2515u16),(39113u16,18420u16),(39114u16,2513u16), (39115u16,18579u16),(39116u16,18918u16),(39118u16,1712u16),(39131u16,6994u16), (39132u16,3329u16),(39134u16,1713u16),(39135u16,6995u16),(39136u16,3916u16), (39137u16,2521u16),(39138u16,7448u16),(39139u16,13039u16),(39141u16,13674u16), (39142u16,2522u16),(39143u16,8407u16),(39145u16,8410u16),(39146u16,8408u16), (39147u16,14363u16),(39148u16,2523u16),(39149u16,8412u16),(39151u16,8409u16), (39153u16,3961u16),(39154u16,8411u16),(39156u16,8854u16),(39157u16,1506u16), (39158u16,15043u16),(39161u16,15044u16),(39162u16,16265u16),(39164u16,8853u16), (39165u16,8855u16),(39166u16,8856u16),(39168u16,15652u16),(39170u16,15651u16), (39171u16,9237u16),(39173u16,9238u16),(39175u16,15653u16),(39176u16,16264u16), (39177u16,9240u16),(39178u16,9618u16),(39180u16,9239u16),(39182u16,3963u16), (39184u16,9919u16),(39185u16,16266u16),(39186u16,9620u16),(39187u16,9619u16), (39188u16,16267u16),(39189u16,16270u16),(39190u16,16268u16),(39191u16,16269u16), (39192u16,9621u16),(39193u16,3964u16),(39194u16,9924u16),(39195u16,9922u16), (39196u16,3966u16),(39198u16,9921u16),(39199u16,16828u16),(39201u16,9923u16), (39204u16,16827u16),(39205u16,17281u16),(39207u16,16829u16),(39208u16,9920u16), (39209u16,16830u16),(39210u16,17284u16),(39211u16,17282u16),(39212u16,17283u16), (39213u16,17288u16),(39214u16,10373u16),(39215u16,17287u16),(39216u16,17290u16), (39217u16,17289u16),(39218u16,17286u16),(39219u16,17285u16),(39221u16,10203u16), (39223u16,3967u16),(39224u16,3315u16),(39225u16,2525u16),(39226u16,17660u16), (39227u16,3335u16),(39228u16,17659u16),(39229u16,10372u16),(39230u16,10370u16), (39231u16,10371u16),(39232u16,4769u16),(39233u16,17658u16),(39234u16,3968u16), (39235u16,17977u16),(39237u16,10522u16),(39239u16,17976u16),(39240u16,17975u16), (39241u16,10523u16),(39242u16,4911u16),(39243u16,18236u16),(39244u16,18235u16), (39245u16,3336u16),(39246u16,18233u16),(39248u16,18232u16),(39249u16,10621u16), (39250u16,10620u16),(39251u16,18237u16),(39252u16,18580u16),(39253u16,10763u16), (39254u16,18424u16),(39255u16,10699u16),(39256u16,18423u16),(39257u16,18234u16), (39259u16,18581u16),(39260u16,10806u16),(39261u16,3969u16),(39262u16,10866u16), (39263u16,18865u16),(39265u16,18919u16),(39266u16,3970u16),(39267u16,1714u16), (39318u16,6996u16),(39319u16,13675u16),(39320u16,17291u16),(39321u16,6997u16), (39323u16,3339u16),(39324u16,15655u16),(39325u16,15654u16),(39326u16,16831u16), (39329u16,17293u16),(39331u16,17292u16),(39332u16,19447u16),(39333u16,10374u16), (39334u16,17978u16),(39335u16,17979u16),(39336u16,10622u16),(39338u16,3341u16), (39339u16,18920u16),(39340u16,7449u16),(39341u16,8414u16),(39342u16,8413u16), (39343u16,15045u16),(39344u16,15047u16),(39345u16,8858u16),(39346u16,15046u16), (39347u16,8857u16),(39348u16,8859u16),(39349u16,15048u16),(39352u16,2610u16), (39353u16,15657u16),(39354u16,15659u16),(39355u16,15658u16),(39356u16,3352u16), (39357u16,15661u16),(39361u16,9241u16),(39362u16,15660u16),(39363u16,15656u16), (39364u16,3914u16),(39365u16,3972u16),(39367u16,15662u16),(39369u16,16277u16), (39371u16,16280u16),(39372u16,16282u16),(39373u16,16272u16),(39374u16,16276u16), (39375u16,16273u16),(39376u16,9623u16),(39377u16,9626u16),(39378u16,9628u16), (39379u16,16274u16),(39380u16,16275u16),(39381u16,9627u16),(39382u16,4182u16), (39383u16,16281u16),(39384u16,16279u16),(39385u16,9629u16),(39386u16,4783u16), (39387u16,9625u16),(39388u16,16271u16),(39389u16,9622u16),(39391u16,9624u16), (39392u16,1819u16),(39393u16,2136u16),(39394u16,9926u16),(39395u16,16837u16), (39396u16,16835u16),(39397u16,16834u16),(39398u16,3161u16),(39399u16,16840u16), (39401u16,16839u16),(39402u16,16838u16),(39404u16,16833u16),(39405u16,9925u16), (39406u16,16832u16),(39408u16,16836u16),(39409u16,9927u16),(39412u16,17296u16), (39413u16,2530u16),(39414u16,17300u16),(39415u16,17297u16),(39416u16,17299u16), (39417u16,17298u16),(39418u16,17295u16),(39419u16,17301u16),(39420u16,17304u16), (39421u16,17302u16),(39422u16,17303u16),(39423u16,10205u16),(39425u16,10204u16), (39426u16,17294u16),(39427u16,17305u16),(39428u16,17665u16),(39429u16,17668u16), (39430u16,17670u16),(39431u16,17669u16),(39433u16,17663u16),(39434u16,17667u16), (39435u16,17662u16),(39436u16,2531u16),(39437u16,17664u16),(39438u16,10375u16), (39439u16,17661u16),(39440u16,2533u16),(39441u16,17666u16),(39444u16,17992u16), (39445u16,17981u16),(39446u16,10524u16),(39449u16,10525u16),(39450u16,17980u16), (39451u16,17985u16),(39452u16,17991u16),(39453u16,17983u16),(39454u16,17990u16), (39455u16,3169u16),(39456u16,17987u16),(39457u16,3346u16),(39458u16,17986u16), (39459u16,17989u16),(39460u16,17984u16),(39461u16,17982u16),(39462u16,4284u16), (39463u16,17988u16),(39465u16,18244u16),(39466u16,18242u16),(39467u16,10623u16), (39468u16,18241u16),(39469u16,18247u16),(39470u16,18245u16),(39471u16,3348u16), (39472u16,10624u16),(39473u16,18240u16),(39474u16,18238u16),(39476u16,18239u16), (39477u16,10626u16),(39478u16,18243u16),(39479u16,10625u16),(39480u16,18246u16), (39481u16,18425u16),(39482u16,18431u16),(39483u16,2532u16),(39484u16,3974u16), (39485u16,18426u16),(39486u16,10703u16),(39487u16,18432u16),(39488u16,10702u16), (39489u16,18430u16),(39490u16,18429u16),(39491u16,10701u16),(39492u16,18428u16), (39493u16,10700u16),(39494u16,18427u16),(39496u16,18587u16),(39497u16,18589u16), (39498u16,18588u16),(39500u16,18585u16),(39501u16,10765u16),(39502u16,18582u16), (39503u16,18586u16),(39504u16,18591u16),(39506u16,18590u16),(39507u16,18583u16), (39508u16,18584u16),(39509u16,10764u16),(39510u16,18701u16),(39511u16,10809u16), (39512u16,2534u16),(39513u16,18702u16),(39514u16,10807u16),(39515u16,10808u16), (39516u16,3342u16),(39518u16,18796u16),(39519u16,10843u16),(39520u16,18894u16), (39522u16,10875u16),(39523u16,3163u16),(39524u16,18921u16),(39525u16,10876u16), (39526u16,18922u16),(39527u16,18923u16),(39528u16,18937u16),(39529u16,18936u16), (39530u16,10891u16),(39531u16,18947u16),(39532u16,1356u16),(39567u16,1357u16), (39592u16,7450u16),(39595u16,15050u16),(39597u16,15049u16),(39599u16,9242u16), (39600u16,9243u16),(39601u16,15663u16),(39602u16,1455u16),(39603u16,16283u16), (39604u16,16843u16),(39606u16,1593u16),(39607u16,9630u16),(39608u16,9928u16), (39609u16,16841u16),(39610u16,4837u16),(39611u16,16844u16),(39612u16,9929u16), (39613u16,4113u16),(39614u16,17306u16),(39615u16,16842u16),(39616u16,17671u16), (39617u16,10376u16),(39618u16,17993u16),(39622u16,18250u16),(39623u16,18248u16), (39626u16,18249u16),(39629u16,18433u16),(39631u16,10704u16),(39632u16,18592u16), (39633u16,10812u16),(39634u16,10766u16),(39635u16,10810u16),(39636u16,10811u16), (39637u16,18797u16),(39638u16,10867u16),(39639u16,4896u16),(39640u16,7451u16), (39644u16,17672u16),(39647u16,13040u16),(39648u16,2539u16),(39649u16,8860u16), (39650u16,2540u16),(39651u16,15664u16),(39654u16,9244u16),(39655u16,15665u16), (39659u16,16285u16),(39660u16,16284u16),(39661u16,9931u16),(39662u16,9631u16), (39663u16,9632u16),(39665u16,16288u16),(39666u16,16287u16),(39667u16,16286u16), (39668u16,2542u16),(39670u16,16845u16),(39671u16,16848u16),(39673u16,16847u16), (39674u16,16846u16),(39675u16,9930u16),(39676u16,17310u16),(39677u16,17308u16), (39678u16,17307u16),(39679u16,4738u16),(39681u16,17309u16),(39682u16,4733u16), (39683u16,10377u16),(39684u16,17674u16),(39685u16,17675u16),(39686u16,10378u16), (39688u16,17673u16),(39689u16,4747u16),(39690u16,17995u16),(39691u16,17994u16), (39692u16,17997u16),(39693u16,10526u16),(39694u16,17996u16),(39695u16,3975u16), (39696u16,18251u16),(39697u16,18253u16),(39698u16,18252u16),(39700u16,2544u16), (39701u16,18434u16),(39702u16,18437u16),(39703u16,18435u16),(39704u16,18436u16), (39705u16,18593u16),(39706u16,10767u16),(39710u16,18703u16),(39711u16,18704u16), (39712u16,18705u16),(39714u16,10844u16),(39715u16,10868u16),(39716u16,18924u16), (39717u16,7452u16),(39719u16,9633u16),(39720u16,9932u16),(39721u16,17676u16), (39722u16,4740u16),(39723u16,18594u16),(39725u16,2545u16),(39726u16,4742u16), (39727u16,13041u16),(39729u16,10892u16),(39730u16,7453u16),(39731u16,16849u16), (39732u16,2548u16),(39733u16,17677u16),(39735u16,17998u16),(39737u16,4711u16), (39738u16,18438u16),(39739u16,18595u16),(39740u16,7454u16),(39742u16,15666u16), (39743u16,15667u16),(39744u16,2553u16),(39745u16,9245u16),(39746u16,9246u16), (39747u16,16290u16),(39748u16,9635u16),(39749u16,9634u16),(39750u16,16289u16), (39752u16,17311u16),(39754u16,17678u16),(39755u16,17680u16),(39756u16,17679u16), (39757u16,10381u16),(39758u16,10380u16),(39759u16,10379u16),(39760u16,2552u16), (39761u16,10706u16),(39762u16,18439u16),(39764u16,10705u16),(39765u16,18597u16), (39766u16,18596u16),(39768u16,10845u16),(39769u16,18798u16),(39770u16,7941u16), (39771u16,15051u16),(39775u16,15670u16),(39776u16,15668u16),(39777u16,15669u16), (39780u16,16299u16),(39782u16,16294u16),(39783u16,16291u16),(39784u16,16298u16), (39785u16,3977u16),(39788u16,16300u16),(39791u16,9637u16),(39792u16,16297u16), (39793u16,16293u16),(39796u16,16292u16),(39797u16,16296u16),(39798u16,16295u16), (39799u16,9636u16),(39802u16,16860u16),(39803u16,16855u16),(39804u16,16853u16), (39805u16,16862u16),(39806u16,16854u16),(39807u16,3377u16),(39808u16,16850u16), (39809u16,3978u16),(39810u16,16856u16),(39811u16,19535u16),(39813u16,16851u16), (39814u16,17320u16),(39815u16,16852u16),(39816u16,16863u16),(39819u16,4688u16), (39821u16,1658u16),(39822u16,2557u16),(39823u16,4899u16),(39824u16,16859u16), (39825u16,9933u16),(39826u16,16858u16),(39827u16,16857u16),(39829u16,16861u16), (39831u16,4834u16),(39834u16,17312u16),(39835u16,17315u16),(39837u16,4807u16), (39838u16,17314u16),(39839u16,3380u16),(39840u16,17322u16),(39841u16,17317u16), (39842u16,17321u16),(39844u16,17319u16),(39845u16,17318u16),(39846u16,17316u16), (39848u16,17313u16),(39850u16,10208u16),(39851u16,10207u16),(39853u16,10209u16), (39854u16,10206u16),(39855u16,17323u16),(39856u16,4906u16),(39861u16,17686u16), (39862u16,17689u16),(39864u16,17687u16),(39865u16,17691u16),(39869u16,17692u16), (39871u16,17684u16),(39872u16,10386u16),(39873u16,17685u16),(39875u16,17683u16), (39876u16,17690u16),(39878u16,17682u16),(39879u16,17681u16),(39880u16,10385u16), (39881u16,10383u16),(39882u16,10382u16),(39887u16,3378u16),(39891u16,17688u16), (39892u16,18007u16),(39893u16,18013u16),(39894u16,10529u16),(39895u16,18008u16), (39897u16,18011u16),(39898u16,18015u16),(39899u16,10530u16),(39900u16,18010u16), (39901u16,3979u16),(39902u16,18002u16),(39904u16,18001u16),(39905u16,18014u16), (39906u16,18005u16),(39908u16,18003u16),(39909u16,18012u16),(39910u16,18004u16), (39911u16,10528u16),(39912u16,10527u16),(39913u16,3255u16),(39914u16,17999u16), (39915u16,18000u16),(39916u16,18009u16),(39917u16,4657u16),(39920u16,18006u16), (39921u16,3980u16),(39924u16,3981u16),(39927u16,18256u16),(39928u16,18259u16), (39933u16,10384u16),(39935u16,2560u16),(39938u16,2559u16),(39941u16,18257u16), (39942u16,18263u16),(39943u16,18261u16),(39944u16,18255u16),(39945u16,18266u16), (39946u16,4775u16),(39947u16,18254u16),(39948u16,2561u16),(39949u16,10628u16), (39950u16,18262u16),(39952u16,3376u16),(39954u16,18258u16),(39955u16,10627u16), (39956u16,18265u16),(39957u16,4745u16),(39959u16,18264u16),(39963u16,4749u16), (39964u16,18442u16),(39965u16,18441u16),(39967u16,1657u16),(39968u16,3983u16), (39969u16,18448u16),(39971u16,18444u16),(39972u16,18447u16),(39973u16,10708u16), (39974u16,1592u16),(39976u16,18445u16),(39977u16,18446u16),(39979u16,18440u16), (39980u16,18443u16),(39981u16,10707u16),(39983u16,4045u16),(39985u16,10769u16), (39986u16,18608u16),(39987u16,18603u16),(39988u16,18607u16),(39989u16,3375u16), (39990u16,18610u16),(39991u16,18606u16),(39993u16,18602u16),(39994u16,3987u16), (39995u16,10771u16),(39996u16,18605u16),(39997u16,18609u16),(39998u16,10770u16), (39999u16,18600u16),(40000u16,18260u16),(40001u16,18604u16),(40004u16,18601u16), (40005u16,4520u16),(40006u16,18598u16),(40008u16,18599u16),(40009u16,10768u16), (40010u16,18709u16),(40011u16,18711u16),(40012u16,18714u16),(40013u16,18710u16), (40014u16,18715u16),(40015u16,3372u16),(40016u16,18708u16),(40018u16,18706u16), (40019u16,3373u16),(40020u16,10813u16),(40021u16,18712u16),(40022u16,10815u16), (40023u16,10814u16),(40024u16,18707u16),(40025u16,18713u16),(40029u16,4616u16), (40030u16,18803u16),(40031u16,10846u16),(40032u16,18804u16),(40034u16,18802u16), (40035u16,18799u16),(40038u16,18801u16),(40039u16,18800u16),(40040u16,18866u16), (40045u16,18868u16),(40046u16,18867u16),(40049u16,18897u16),(40050u16,4569u16), (40051u16,18896u16),(40052u16,18895u16),(40053u16,18898u16),(40055u16,10884u16), (40056u16,10885u16),(40057u16,18944u16),(40058u16,18948u16),(40059u16,3374u16), (40060u16,1716u16),(40165u16,7942u16),(40166u16,14364u16),(40167u16,15054u16), (40169u16,8861u16),(40170u16,15052u16),(40173u16,15053u16),(40177u16,15671u16), (40178u16,15672u16),(40179u16,9249u16),(40180u16,9247u16),(40181u16,15673u16), (40182u16,9248u16),(40183u16,16305u16),(40185u16,16308u16),(40186u16,16302u16), (40187u16,16309u16),(40188u16,16301u16),(40189u16,16303u16),(40191u16,16304u16), (40192u16,16307u16),(40194u16,4776u16),(40195u16,9640u16),(40196u16,16312u16), (40197u16,16311u16),(40198u16,9638u16),(40199u16,16306u16),(40200u16,16310u16), (40201u16,9639u16),(40204u16,3388u16),(40208u16,16873u16),(40210u16,9938u16), (40212u16,16868u16),(40213u16,9934u16),(40214u16,3443u16),(40215u16,16865u16), (40216u16,16871u16),(40217u16,16874u16),(40219u16,9939u16),(40221u16,16870u16), (40222u16,16867u16),(40223u16,16875u16),(40224u16,16866u16),(40225u16,3383u16), (40226u16,16872u16),(40227u16,9935u16),(40229u16,16864u16),(40230u16,9936u16), (40232u16,9937u16),(40233u16,16869u16),(40237u16,17341u16),(40238u16,17328u16), (40239u16,17329u16),(40240u16,17332u16),(40241u16,17330u16),(40243u16,17324u16), (40244u16,19060u16),(40246u16,17327u16),(40247u16,17337u16),(40248u16,17331u16), (40249u16,2581u16),(40251u16,10210u16),(40253u16,17339u16),(40254u16,17336u16), (40255u16,10211u16),(40256u16,17338u16),(40257u16,17325u16),(40258u16,17334u16), (40259u16,17335u16),(40260u16,4897u16),(40261u16,17333u16),(40265u16,3986u16), (40266u16,17696u16),(40267u16,17698u16),(40268u16,17701u16),(40270u16,1264u16), (40271u16,17695u16),(40272u16,4632u16),(40273u16,10387u16),(40274u16,17703u16), (40275u16,17694u16),(40276u16,17704u16),(40278u16,17700u16),(40279u16,17702u16), (40280u16,17706u16),(40281u16,17699u16),(40282u16,17707u16),(40283u16,17697u16), (40284u16,17693u16),(40285u16,10388u16),(40286u16,4517u16),(40287u16,17705u16), (40288u16,10389u16),(40289u16,10532u16),(40295u16,17326u16),(40296u16,18041u16), (40297u16,18032u16),(40298u16,10534u16),(40299u16,18028u16),(40300u16,10535u16), (40301u16,3233u16),(40302u16,1464u16),(40303u16,18037u16),(40304u16,18031u16), (40305u16,18021u16),(40306u16,10533u16),(40307u16,18034u16),(40308u16,18029u16), (40309u16,18030u16),(40311u16,18016u16),(40312u16,18023u16),(40313u16,18038u16), (40315u16,18035u16),(40316u16,4709u16),(40317u16,18027u16),(40318u16,2570u16), (40319u16,18039u16),(40320u16,18022u16),(40321u16,18017u16),(40322u16,18036u16), (40323u16,2571u16),(40324u16,18019u16),(40325u16,18033u16),(40326u16,18024u16), (40327u16,18040u16),(40328u16,18020u16),(40329u16,10531u16),(40330u16,18018u16), (40331u16,18025u16),(40332u16,18026u16),(40336u16,18273u16),(40338u16,18271u16), (40339u16,3990u16),(40340u16,18276u16),(40342u16,18288u16),(40343u16,18279u16), (40344u16,18272u16),(40345u16,18268u16),(40346u16,18281u16),(40347u16,18274u16), (40348u16,18277u16),(40349u16,18270u16),(40350u16,18284u16),(40351u16,18267u16), (40352u16,18275u16),(40353u16,18280u16),(40354u16,18282u16),(40355u16,18285u16), (40356u16,18269u16),(40357u16,3393u16),(40358u16,18289u16),(40359u16,18290u16), (40360u16,18283u16),(40361u16,18287u16),(40362u16,18278u16),(40363u16,4765u16), (40364u16,18464u16),(40365u16,18467u16),(40367u16,10709u16),(40369u16,18466u16), (40370u16,18471u16),(40371u16,18469u16),(40372u16,10710u16),(40373u16,18460u16), (40374u16,18450u16),(40375u16,18449u16),(40376u16,10712u16),(40377u16,18462u16), (40378u16,18463u16),(40379u16,18459u16),(40380u16,18451u16),(40381u16,3991u16), (40382u16,18456u16),(40383u16,18286u16),(40384u16,3992u16),(40385u16,18452u16), (40386u16,10711u16),(40387u16,18458u16),(40388u16,2575u16),(40389u16,18457u16), (40391u16,18453u16),(40392u16,18465u16),(40393u16,1342u16),(40394u16,18454u16), (40395u16,18615u16),(40396u16,18468u16),(40397u16,18470u16),(40398u16,18461u16), (40399u16,18455u16),(40400u16,18616u16),(40401u16,18618u16),(40402u16,18612u16), (40403u16,10772u16),(40404u16,2563u16),(40405u16,18625u16),(40406u16,18623u16), (40407u16,10773u16),(40408u16,18622u16),(40409u16,18621u16),(40410u16,18614u16), (40411u16,18611u16),(40412u16,18617u16),(40413u16,18626u16),(40414u16,18613u16), (40415u16,18619u16),(40417u16,18724u16),(40418u16,18729u16),(40419u16,18719u16), (40420u16,18722u16),(40421u16,10816u16),(40422u16,18726u16),(40424u16,18733u16), (40425u16,18620u16),(40427u16,18720u16),(40428u16,18730u16),(40429u16,18734u16), (40430u16,18725u16),(40431u16,18718u16),(40432u16,4282u16),(40434u16,18727u16), (40435u16,18732u16),(40436u16,18731u16),(40437u16,18624u16),(40438u16,18723u16), (40439u16,18717u16),(40440u16,18721u16),(40441u16,10847u16),(40442u16,10848u16), (40443u16,18716u16),(40444u16,3993u16),(40445u16,18815u16),(40446u16,18806u16), (40447u16,18814u16),(40448u16,18811u16),(40449u16,18812u16),(40450u16,18805u16), (40451u16,18808u16),(40452u16,18816u16),(40453u16,18810u16),(40454u16,18809u16), (40455u16,18807u16),(40457u16,18813u16),(40458u16,1347u16),(40459u16,18869u16), (40460u16,1343u16),(40461u16,18870u16),(40462u16,2573u16),(40463u16,18872u16), (40464u16,18871u16),(40465u16,18874u16),(40466u16,18873u16),(40467u16,18900u16), (40468u16,18899u16),(40469u16,18925u16),(40471u16,18926u16),(40472u16,3386u16), (40473u16,18939u16),(40474u16,10889u16),(40475u16,10893u16),(40476u16,4854u16), (40477u16,18949u16),(40478u16,10894u16),(40479u16,1717u16),(40565u16,7943u16), (40569u16,10629u16),(40570u16,18472u16),(40571u16,3996u16),(40572u16,10849u16), (40573u16,10850u16),(40575u16,7944u16),(40576u16,15055u16),(40577u16,4730u16), (40578u16,8862u16),(40579u16,16313u16),(40580u16,4839u16),(40581u16,4692u16), (40582u16,16877u16),(40583u16,16878u16),(40584u16,16876u16),(40585u16,17343u16), (40586u16,17342u16),(40587u16,10212u16),(40588u16,17709u16),(40589u16,17344u16), (40590u16,17708u16),(40592u16,2584u16),(40593u16,18043u16),(40594u16,10536u16), (40595u16,10538u16),(40596u16,18042u16),(40597u16,2585u16),(40598u16,4915u16), (40599u16,10537u16),(40600u16,4755u16),(40601u16,18291u16),(40602u16,18293u16), (40603u16,18292u16),(40604u16,18473u16),(40605u16,10713u16),(40606u16,2586u16), (40607u16,10817u16),(40608u16,18817u16),(40609u16,18875u16),(40610u16,2587u16), (40612u16,18952u16),(40613u16,7945u16),(40614u16,5022u16),(40615u16,15674u16), (40616u16,4838u16),(40617u16,9641u16),(40618u16,2589u16),(40619u16,4554u16), (40620u16,3997u16),(40621u16,16880u16),(40622u16,16879u16),(40623u16,2590u16), (40624u16,17345u16),(40625u16,3998u16),(40628u16,10539u16),(40629u16,10630u16), (40630u16,18627u16),(40631u16,18945u16),(40635u16,7946u16),(40636u16,9250u16), (40637u16,3999u16),(40638u16,9642u16),(40639u16,3935u16),(40640u16,18044u16), (40641u16,2592u16),(40642u16,18735u16),(40643u16,8415u16),(40644u16,1718u16), (40646u16,4000u16),(40647u16,1340u16),(40648u16,17346u16),(40652u16,10869u16), (40653u16,8416u16),(40654u16,9643u16),(40655u16,10213u16),(40656u16,18736u16), (40657u16,8417u16),(40659u16,16314u16),(40660u16,9941u16),(40661u16,16881u16), (40662u16,16882u16),(40664u16,9940u16),(40666u16,17347u16),(40667u16,10217u16), (40668u16,10215u16),(40669u16,10216u16),(40670u16,10214u16),(40671u16,17710u16), (40672u16,10390u16),(40674u16,4002u16),(40676u16,18295u16),(40677u16,18294u16), (40678u16,18297u16),(40679u16,18296u16),(40680u16,10631u16),(40683u16,18474u16), (40685u16,18476u16),(40686u16,18475u16),(40687u16,10714u16),(40688u16,18628u16), (40689u16,4003u16),(40690u16,18737u16),(40691u16,18738u16),(40692u16,10818u16), (40693u16,18876u16),(40694u16,18901u16),(40695u16,10886u16),(40696u16,4004u16), (40697u16,14365u16),(40698u16,16883u16),(40699u16,17348u16),(40700u16,18045u16), (40701u16,15056u16),(40702u16,3988u16),(40703u16,17349u16),(40704u16,17712u16), (40705u16,17711u16),(40706u16,2599u16),(40710u16,18739u16),(40711u16,10851u16), (40712u16,2600u16),(40713u16,18877u16),(40714u16,18902u16),(40718u16,8863u16), (40719u16,16315u16),(40720u16,16316u16),(40722u16,16884u16),(40723u16,8864u16), (40725u16,10391u16),(40726u16,2605u16),(40727u16,2604u16),(40728u16,18478u16), (40729u16,10715u16),(40730u16,18479u16),(40731u16,18477u16),(40732u16,18740u16), (40734u16,18818u16),(40736u16,8865u16),(40738u16,17352u16),(40739u16,17351u16), (40740u16,17350u16),(40741u16,17714u16),(40742u16,4868u16),(40743u16,1655u16), (40744u16,17718u16),(40745u16,17717u16),(40746u16,17716u16),(40747u16,17715u16), (40748u16,10392u16),(40749u16,18046u16),(40750u16,18299u16),(40751u16,10632u16), (40752u16,18298u16),(40753u16,18480u16),(40754u16,18631u16),(40755u16,18630u16), (40756u16,10774u16),(40757u16,18629u16),(40758u16,18743u16),(40759u16,18742u16), (40760u16,18741u16),(40761u16,2606u16),(40763u16,9251u16),(40765u16,16885u16), (40766u16,10218u16),(40768u16,18047u16),(40769u16,18048u16),(40770u16,18632u16), (40771u16,18744u16),(40772u16,4006u16),(40773u16,2609u16),(40774u16,18819u16), (40775u16,18878u16),(40776u16,18927u16),(40777u16,18954u16),(40778u16,9252u16), (40779u16,10219u16),(40780u16,17719u16),(40781u16,18049u16),(40782u16,18481u16), (40783u16,18745u16),(40784u16,5021u16),(40786u16,9645u16),(40787u16,4850u16), (40788u16,17353u16),(40789u16,17720u16),(40790u16,18050u16),(40791u16,18051u16), (40792u16,18052u16),(40793u16,18304u16),(40794u16,4751u16),(40795u16,18300u16), (40796u16,10716u16),(40797u16,18303u16),(40798u16,18302u16),(40799u16,10633u16), (40800u16,18301u16),(40801u16,10635u16),(40802u16,2614u16),(40803u16,10634u16), (40804u16,18483u16),(40805u16,18482u16),(40806u16,10717u16),(40807u16,10718u16), (40809u16,2615u16),(40810u16,10776u16),(40811u16,18633u16),(40812u16,10775u16), (40814u16,18748u16),(40815u16,18749u16),(40816u16,18747u16),(40817u16,18746u16), (40818u16,10853u16),(40820u16,18820u16),(40821u16,18821u16),(40822u16,18822u16), (40823u16,10852u16),(40824u16,18879u16),(40825u16,18882u16),(40826u16,18881u16), (40827u16,18880u16),(40830u16,18953u16),(40831u16,2016u16),(40845u16,9942u16), (40846u16,2617u16),(40848u16,10399u16),(40849u16,18305u16),(40850u16,18484u16), (40852u16,10777u16),(40853u16,18634u16),(40854u16,1016u16),(40855u16,1008u16), (40856u16,18955u16),(40857u16,1358u16),(40860u16,9943u16),(40863u16,1956u16), (40864u16,17354u16),(40866u16,18635u16),(40868u16,18903u16),(40869u16,4833u16), (40870u16,1730u16),(40871u16,1772u16),(40872u16,1779u16),(40873u16,1812u16), (40874u16,1814u16),(40875u16,1816u16),(40876u16,1821u16),(40877u16,1844u16), (40878u16,1845u16),(40879u16,1847u16),(40880u16,11210u16),(40881u16,11212u16), (40882u16,1866u16),(40883u16,1892u16),(40903u16,1038u16),(40904u16,1054u16), (40905u16,1058u16),(40906u16,1062u16),(40907u16,1067u16),(63751u16,1720u16), (64012u16,11314u16),(64013u16,14598u16),(65072u16,5034u16),(65073u16,5047u16), (65075u16,5049u16),(65076u16,5051u16),(65077u16,5055u16),(65078u16,5056u16), (65079u16,5059u16),(65080u16,5060u16),(65081u16,5063u16),(65082u16,5064u16), (65083u16,5067u16),(65084u16,5068u16),(65085u16,5071u16),(65086u16,5072u16), (65087u16,5075u16),(65088u16,5076u16),(65089u16,5079u16),(65090u16,5080u16), (65091u16,5083u16),(65092u16,5084u16),(65097u16,5124u16),(65098u16,5125u16), (65099u16,5128u16),(65100u16,5129u16),(65101u16,5126u16),(65102u16,5127u16), (65103u16,5052u16),(65104u16,5037u16),(65105u16,5038u16),(65106u16,5039u16), (65108u16,5041u16),(65109u16,5042u16),(65110u16,5043u16),(65111u16,5044u16), (65113u16,5085u16),(65114u16,5086u16),(65115u16,5087u16),(65116u16,5088u16), (65117u16,5089u16),(65118u16,5090u16),(65119u16,5130u16),(65120u16,5131u16), (65121u16,5132u16),(65122u16,5148u16),(65123u16,5149u16),(65124u16,5150u16), (65125u16,5151u16),(65126u16,5152u16),(65128u16,5183u16),(65129u16,5193u16), (65130u16,5194u16),(65131u16,5195u16),(65281u16,5033u16),(65282u16,11257u16), (65283u16,5099u16),(65284u16,5184u16),(65285u16,5189u16),(65286u16,5100u16), (65287u16,11256u16),(65288u16,5053u16),(65289u16,5054u16),(65290u16,5101u16), (65291u16,5133u16),(65292u16,5025u16),(65293u16,5134u16),(65294u16,5028u16), (65295u16,5180u16),(65296u16,5258u16),(65297u16,5259u16),(65298u16,5260u16), (65299u16,5261u16),(65300u16,5262u16),(65301u16,5263u16),(65302u16,5264u16), (65303u16,5265u16),(65304u16,5266u16),(65305u16,5267u16),(65306u16,5031u16), (65307u16,5030u16),(65308u16,5139u16),(65309u16,5141u16),(65310u16,5140u16), (65311u16,5032u16),(65312u16,5190u16),(65313u16,5290u16),(65314u16,5291u16), (65315u16,5292u16),(65316u16,5293u16),(65317u16,5294u16),(65318u16,5295u16), (65319u16,5296u16),(65320u16,5297u16),(65321u16,5298u16),(65322u16,5299u16), (65323u16,5300u16),(65324u16,5301u16),(65325u16,5302u16),(65326u16,5303u16), (65327u16,5304u16),(65328u16,5305u16),(65329u16,5306u16),(65330u16,5307u16), (65331u16,5308u16),(65332u16,5309u16),(65333u16,5310u16),(65334u16,5311u16), (65335u16,5312u16),(65336u16,5313u16),(65337u16,5314u16),(65338u16,5315u16), (65339u16,10963u16),(65340u16,5181u16),(65341u16,10964u16),(65343u16,5122u16), (65345u16,5316u16),(65346u16,5317u16),(65347u16,5318u16),(65348u16,5319u16), (65349u16,5320u16),(65350u16,5321u16),(65351u16,5322u16),(65352u16,5323u16), (65353u16,5324u16),(65354u16,5325u16),(65355u16,5326u16),(65356u16,5327u16), (65357u16,5328u16),(65358u16,5329u16),(65359u16,5330u16),(65360u16,5331u16), (65361u16,5332u16),(65362u16,5333u16),(65363u16,5334u16),(65364u16,5335u16), (65365u16,5336u16),(65366u16,5337u16),(65367u16,5338u16),(65368u16,5339u16), (65369u16,5340u16),(65370u16,5341u16),(65371u16,5057u16),(65372u16,5045u16), (65373u16,5058u16),(65374u16,5153u16),(65504u16,5187u16),(65505u16,5188u16), (65506u16,11254u16),(65507u16,5121u16),(65508u16,11255u16),(65509u16,5185u16), (65517u16,18996u16), ] const Big5EncodeHigh*: array[1713, UCS16x16] = [ (33u16,4288u16),(62u16,2879u16),(70u16,2880u16),(78u16,3148u16), (104u16,2141u16),(134u16,1669u16),(135u16,1722u16),(138u16,11207u16), (148u16,4007u16),(202u16,1113u16),(203u16,1110u16),(204u16,11205u16), (205u16,1107u16),(209u16,1106u16),(238u16,5015u16),(268u16,1104u16), (270u16,1118u16),(280u16,19386u16),(420u16,1874u16),(425u16,1488u16), (427u16,2719u16),(449u16,19318u16),(468u16,3108u16),(498u16,4821u16), (516u16,19259u16),(524u16,2730u16),(532u16,3677u16),(569u16,1878u16), (603u16,3116u16),(628u16,2460u16),(629u16,2728u16),(665u16,3101u16), (670u16,19342u16),(672u16,19017u16),(695u16,4008u16),(703u16,3417u16), (704u16,2726u16),(741u16,19049u16),(778u16,2722u16),(805u16,2037u16), (833u16,1422u16),(837u16,2794u16),(838u16,4142u16),(839u16,19032u16), (894u16,19029u16),(895u16,2714u16),(896u16,19031u16),(928u16,4009u16), (935u16,3497u16),(949u16,19510u16),(969u16,19488u16),(971u16,2720u16), (1013u16,3572u16),(1020u16,4799u16),(1043u16,2828u16),(1044u16,2723u16), (1055u16,19034u16),(1125u16,2713u16),(1159u16,19043u16),(1166u16,4679u16), (1169u16,2763u16),(1170u16,2762u16),(1187u16,2761u16),(1239u16,4013u16), (1276u16,1494u16),(1278u16,3507u16),(1351u16,18997u16),(1422u16,19051u16), (1445u16,19264u16),(1459u16,19056u16),(1475u16,19670u16),(1482u16,4163u16), (1488u16,1362u16),(1493u16,4017u16),(1503u16,18999u16),(1504u16,2759u16), (1515u16,3011u16),(1553u16,4165u16),(1557u16,4018u16),(1561u16,3680u16), (1562u16,3520u16),(1584u16,2510u16),(1622u16,19370u16),(1654u16,4019u16), (1806u16,2766u16),(1841u16,1485u16),(1913u16,4192u16),(2092u16,3156u16), (2163u16,2769u16),(2261u16,3679u16),(2326u16,3146u16),(2339u16,19503u16), (2388u16,19093u16),(2425u16,4650u16),(2535u16,1336u16),(2577u16,4277u16), (2640u16,2374u16),(2671u16,1761u16),(2698u16,1012u16),(2740u16,3549u16), (2754u16,4023u16),(2765u16,4024u16),(2829u16,2182u16),(2959u16,19132u16), (2975u16,1884u16),(2984u16,2703u16),(2985u16,1562u16),(3007u16,4025u16), (3014u16,2796u16),(3019u16,4028u16),(3042u16,19097u16),(3051u16,3521u16), (3067u16,4030u16),(3071u16,19047u16),(3083u16,1443u16),(3085u16,3109u16), (3104u16,2775u16),(3124u16,1544u16),(3130u16,19653u16),(3131u16,4031u16), (3137u16,4547u16),(3138u16,1416u16),(3139u16,1481u16),(3155u16,4032u16), (3173u16,4033u16),(3191u16,19137u16),(3192u16,4188u16),(3196u16,4034u16), (3213u16,4036u16),(3222u16,4548u16),(3228u16,4456u16),(3253u16,4038u16), (3256u16,3522u16),(3279u16,3799u16),(3283u16,19302u16),(3284u16,4809u16), (3285u16,1438u16),(3286u16,1613u16),(3293u16,4039u16),(3309u16,4040u16), (3327u16,3518u16),(3349u16,1417u16),(3368u16,4720u16),(3377u16,2418u16), (3378u16,19534u16),(3398u16,1449u16),(3399u16,1557u16),(3400u16,1563u16), (3401u16,4514u16),(3404u16,3099u16),(3405u16,19153u16),(3406u16,19223u16), (3439u16,4041u16),(3441u16,4723u16),(3444u16,19145u16),(3452u16,1436u16), (3454u16,1573u16),(3455u16,1574u16),(3478u16,1497u16),(3484u16,1507u16), (3495u16,4573u16),(3506u16,4042u16),(3528u16,4043u16),(3588u16,4047u16), (3593u16,1517u16),(3594u16,4623u16),(3597u16,2704u16),(3598u16,4048u16), (3599u16,1607u16),(3600u16,1617u16),(3601u16,1632u16),(3606u16,2201u16), (3613u16,2779u16),(3660u16,1559u16),(3693u16,4488u16),(3699u16,4052u16), (3701u16,19435u16),(3702u16,4551u16),(3703u16,1608u16),(3704u16,1618u16), (3705u16,1623u16),(3706u16,1543u16),(3707u16,1636u16),(3724u16,1552u16), (3734u16,1442u16),(3736u16,1578u16),(3741u16,4535u16),(3746u16,4553u16), (3754u16,1554u16),(3755u16,1561u16),(3756u16,4607u16),(3766u16,4682u16), (3799u16,4049u16),(3800u16,2040u16),(3805u16,19151u16),(3832u16,4318u16), (3833u16,4608u16),(3834u16,1606u16),(3835u16,1609u16),(3869u16,3465u16), (3878u16,3316u16),(3885u16,4051u16),(3886u16,1580u16),(3888u16,1556u16), (3889u16,1530u16),(3899u16,4940u16),(3916u16,1496u16),(3940u16,1444u16), (3981u16,1553u16),(3984u16,4050u16),(4013u16,1569u16),(4020u16,1437u16), (4021u16,1635u16),(4022u16,1639u16),(4028u16,4054u16),(4063u16,2702u16), (4074u16,4513u16),(4075u16,4614u16),(4076u16,4622u16),(4077u16,4626u16), (4116u16,2357u16),(4125u16,1627u16),(4126u16,1628u16),(4175u16,4057u16), (4188u16,4056u16),(4207u16,1475u16),(4213u16,4557u16),(4214u16,4058u16), (4215u16,1473u16),(4216u16,1619u16),(4219u16,4060u16),(4232u16,4061u16), (4246u16,4062u16),(4253u16,1504u16),(4276u16,19168u16),(4287u16,4064u16), (4288u16,1564u16),(4289u16,4588u16),(4295u16,1579u16),(4296u16,1521u16), (4297u16,1616u16),(4303u16,1547u16),(4307u16,4065u16),(4324u16,2777u16), (4340u16,1439u16),(4341u16,1629u16),(4342u16,1630u16),(4399u16,4066u16), (4411u16,4067u16),(4413u16,1565u16),(4421u16,1257u16),(4424u16,1620u16), (4431u16,1558u16),(4480u16,1640u16),(4487u16,4629u16),(4569u16,4603u16), (4668u16,19205u16),(4687u16,19185u16),(4732u16,2443u16),(4776u16,2668u16), (4777u16,4701u16),(4784u16,3593u16),(4835u16,4070u16),(4862u16,5007u16), (4866u16,3357u16),(4867u16,2831u16),(4868u16,3657u16),(4869u16,19019u16), (4918u16,4072u16),(4922u16,19322u16),(4981u16,4071u16),(4982u16,19749u16), (5006u16,19396u16),(5016u16,3597u16),(5020u16,3555u16),(5061u16,4344u16), (5062u16,2669u16),(5101u16,4373u16),(5118u16,2667u16),(5139u16,3468u16), (5142u16,19194u16),(5156u16,3498u16),(5183u16,1823u16),(5202u16,3588u16), (5204u16,19196u16),(5205u16,1622u16),(5258u16,2174u16),(5271u16,19570u16), (5302u16,2670u16),(5352u16,3360u16),(5373u16,2186u16),(5495u16,4074u16), (5506u16,2266u16),(5526u16,19113u16),(5642u16,4340u16),(5651u16,19114u16), (5657u16,4075u16),(5694u16,19217u16),(5729u16,2140u16),(5778u16,19220u16), (5816u16,19250u16),(5818u16,4020u16),(5824u16,2664u16),(5825u16,19746u16), (5826u16,3527u16),(5843u16,2519u16),(5845u16,19233u16),(5855u16,2334u16), (5862u16,3095u16),(5863u16,19658u16),(5864u16,19105u16),(5882u16,2808u16), (5883u16,2657u16),(5884u16,2926u16),(5886u16,2852u16),(5901u16,19150u16), (5904u16,2810u16),(5926u16,19099u16),(5946u16,3618u16),(5947u16,2864u16), (5948u16,3632u16),(5975u16,3429u16),(5996u16,4713u16),(5997u16,4782u16), (5998u16,3103u16),(5999u16,2809u16),(6000u16,19388u16),(6001u16,19307u16), (6003u16,2192u16),(6004u16,2660u16),(6059u16,2862u16),(6064u16,3130u16), (6065u16,4323u16),(6066u16,19229u16),(6067u16,3625u16),(6068u16,2202u16), (6069u16,3452u16),(6083u16,4076u16),(6087u16,4077u16),(6105u16,3495u16), (6106u16,3254u16),(6107u16,3622u16),(6108u16,19226u16),(6111u16,3671u16), (6127u16,2648u16),(6133u16,4473u16),(6134u16,4495u16),(6136u16,2655u16), (6137u16,2120u16),(6138u16,3525u16),(6139u16,19228u16),(6140u16,19397u16), (6176u16,4326u16),(6184u16,19232u16),(6185u16,19423u16),(6186u16,2931u16), (6189u16,4080u16),(6201u16,2658u16),(6202u16,1644u16),(6203u16,4888u16), (6208u16,3192u16),(6213u16,3232u16),(6226u16,3529u16),(6238u16,2176u16), (6241u16,2819u16),(6242u16,3546u16),(6243u16,2556u16),(6244u16,3055u16), (6263u16,19346u16),(6267u16,4496u16),(6275u16,3537u16),(6276u16,2755u16), (6277u16,2653u16),(6302u16,19693u16),(6303u16,3486u16),(6304u16,2850u16), (6305u16,3194u16),(6306u16,2272u16),(6334u16,2650u16),(6335u16,3536u16), (6353u16,2661u16),(6358u16,3464u16),(6359u16,19163u16),(6360u16,3196u16), (6361u16,2916u16),(6394u16,2628u16),(6403u16,2847u16),(6404u16,2848u16), (6405u16,3628u16),(6416u16,2348u16),(6417u16,19248u16),(6418u16,2970u16), (6421u16,2465u16),(6428u16,4243u16),(6434u16,2690u16),(6439u16,2861u16), (6459u16,2579u16),(6468u16,5006u16),(6488u16,19511u16),(6506u16,4081u16), (6524u16,2843u16),(6528u16,1750u16),(6531u16,19053u16),(6536u16,19695u16), (6550u16,2842u16),(6619u16,19009u16),(6643u16,2818u16),(6701u16,4082u16), (6708u16,19262u16),(6725u16,4083u16),(6731u16,19700u16),(6755u16,975u16), (6980u16,19269u16),(7105u16,1666u16),(7106u16,3985u16),(7210u16,4084u16), (7280u16,4085u16),(7330u16,4610u16),(7333u16,19273u16),(7340u16,4086u16), (7494u16,4936u16),(7507u16,1001u16),(7518u16,988u16),(7568u16,4227u16), (7606u16,1784u16),(7610u16,2856u16),(7626u16,1361u16),(7633u16,4729u16), (7659u16,2943u16),(7673u16,19281u16),(7708u16,19735u16),(7715u16,1870u16), (7735u16,19282u16),(7741u16,19440u16),(7817u16,2407u16),(7844u16,19286u16), (7848u16,4167u16),(7880u16,4087u16),(7893u16,4089u16),(7951u16,4726u16), (7957u16,4090u16),(8042u16,19338u16),(8094u16,3682u16),(8097u16,4394u16), (8168u16,1111u16),(8261u16,4093u16),(8265u16,19292u16),(8318u16,1768u16), (8346u16,4152u16),(8391u16,1528u16),(8444u16,19048u16),(8490u16,19493u16), (8539u16,2576u16),(8563u16,19293u16),(8570u16,4310u16),(8609u16,1483u16), (8641u16,1886u16),(8643u16,4179u16),(8712u16,1540u16),(8828u16,4096u16), (8993u16,3250u16),(8997u16,2386u16),(9149u16,3594u16),(9168u16,19325u16), (9175u16,4097u16),(9210u16,4098u16),(9317u16,4653u16),(9329u16,19327u16), (9355u16,19519u16),(9361u16,19537u16),(9392u16,4460u16),(9404u16,1053u16), (9409u16,1055u16),(9417u16,1056u16),(9420u16,1057u16),(9453u16,19021u16), (9491u16,19027u16),(9499u16,4892u16),(9520u16,19050u16),(9556u16,19246u16), (9613u16,4303u16),(9647u16,2874u16),(9662u16,2875u16),(9755u16,2881u16), (9756u16,19766u16),(9771u16,2871u16),(9832u16,19340u16),(9850u16,2441u16), (9878u16,1567u16),(9880u16,19155u16),(9972u16,4596u16),(9973u16,3112u16), (9974u16,2169u16),(10002u16,1788u16),(10004u16,2158u16),(10011u16,4252u16), (10015u16,3362u16),(10026u16,4099u16),(10101u16,1510u16),(10113u16,3369u16), (10134u16,1855u16),(10164u16,19351u16),(10165u16,1615u16),(10189u16,19507u16), (10243u16,1548u16),(10335u16,19374u16),(10336u16,2870u16),(10353u16,4100u16), (10413u16,19673u16),(10433u16,19381u16),(10487u16,19446u16),(10534u16,4321u16), (10553u16,1549u16),(10575u16,4101u16),(10599u16,4103u16),(10603u16,3370u16), (10624u16,19380u16),(10643u16,4104u16),(10854u16,1503u16),(10959u16,1518u16), (10965u16,4105u16),(10982u16,1363u16),(10984u16,4107u16),(11022u16,4109u16), (11042u16,2893u16),(11071u16,4111u16),(11075u16,4568u16),(11114u16,2891u16), (11210u16,1472u16),(11214u16,1572u16),(11302u16,3470u16),(11303u16,2279u16), (11320u16,1429u16),(11340u16,4114u16),(11345u16,1575u16),(11349u16,1576u16), (11362u16,4552u16),(11400u16,4116u16),(11419u16,2885u16),(11425u16,2905u16), (11433u16,1445u16),(11442u16,1531u16),(11447u16,4117u16),(11458u16,1454u16), (11462u16,1420u16),(11465u16,1519u16),(11527u16,2886u16),(11528u16,4119u16), (11538u16,4120u16),(11588u16,1463u16),(11596u16,1471u16),(11623u16,2903u16), (11661u16,1491u16),(11669u16,4122u16),(11680u16,4618u16),(11683u16,19135u16), (11684u16,1625u16),(11703u16,4121u16),(11758u16,1595u16),(11789u16,19390u16), (11830u16,19400u16),(11842u16,4123u16),(11896u16,2896u16),(11915u16,1539u16), (11955u16,4570u16),(12015u16,2229u16),(12148u16,4124u16),(12236u16,4125u16), (12259u16,3592u16),(12339u16,4126u16),(12356u16,19639u16),(12363u16,19564u16), (12390u16,4127u16),(12413u16,2551u16),(12414u16,19417u16),(12430u16,2910u16), (12471u16,2485u16),(12476u16,2486u16),(12506u16,4697u16),(12547u16,2930u16), (12605u16,1660u16),(12669u16,2204u16),(12674u16,2935u16),(12708u16,19432u16), (12709u16,19433u16),(12723u16,2920u16),(12744u16,19443u16),(12745u16,3430u16), (12778u16,1011u16),(12791u16,19429u16),(12792u16,19430u16),(12793u16,19536u16), (12815u16,2934u16),(12837u16,3283u16),(12847u16,4374u16),(12849u16,19441u16), (12850u16,3060u16),(12851u16,19052u16),(12852u16,2932u16),(12886u16,1854u16), (12894u16,1013u16),(12898u16,2381u16),(12929u16,1747u16),(12937u16,2919u16), (12938u16,19171u16),(12971u16,2913u16),(12972u16,19742u16),(12973u16,2911u16), (13010u16,2945u16),(13024u16,2915u16),(13025u16,2946u16),(13056u16,3676u16), (13066u16,2466u16),(13087u16,4128u16),(13236u16,19045u16),(13260u16,4219u16), (13278u16,4129u16),(13286u16,19465u16),(13300u16,1570u16),(13301u16,4926u16), (13305u16,1790u16),(13306u16,3603u16),(13310u16,2954u16),(13312u16,19427u16), (13375u16,3165u16),(13392u16,2894u16),(13423u16,19468u16),(13426u16,2857u16), (13541u16,3598u16),(13593u16,4293u16),(13616u16,2191u16),(13649u16,1864u16), (13658u16,2205u16),(13671u16,4134u16),(13717u16,2751u16),(13721u16,2651u16), (13724u16,3409u16),(13755u16,1060u16),(13773u16,19474u16),(13774u16,2213u16), (13775u16,3149u16),(13811u16,4135u16),(13824u16,19025u16),(13847u16,959u16), (13850u16,4139u16),(13884u16,19479u16),(13888u16,3410u16),(13913u16,19492u16), (13919u16,3014u16),(13943u16,5014u16),(13966u16,1043u16),(13982u16,1002u16), (13990u16,2672u16),(13997u16,3606u16),(14010u16,4515u16),(14047u16,3600u16), (14062u16,2682u16),(14083u16,19495u16),(14102u16,4140u16),(14112u16,4668u16), (14125u16,19073u16),(14127u16,4342u16),(14143u16,2693u16),(14182u16,2143u16), (14209u16,3065u16),(14242u16,2953u16),(14268u16,2951u16),(14274u16,19453u16), (14293u16,2964u16),(14294u16,3602u16),(14295u16,3406u16),(14394u16,2950u16), (14786u16,1522u16),(15015u16,4146u16),(15067u16,19509u16),(15086u16,2844u16), (15098u16,3675u16),(15130u16,1860u16),(15194u16,19514u16),(15459u16,1793u16), (15513u16,19057u16),(15514u16,2978u16),(15515u16,2415u16),(15541u16,2237u16), (15543u16,4481u16),(15559u16,5002u16),(15560u16,19011u16),(15561u16,19531u16), (15612u16,4605u16),(15613u16,4803u16),(15614u16,4658u16),(15615u16,4169u16), (15680u16,4510u16),(15707u16,3541u16),(15742u16,2184u16),(15759u16,3199u16), (15798u16,4665u16),(15799u16,3473u16),(15800u16,3363u16),(15801u16,2290u16), (15802u16,3102u16),(15803u16,2379u16),(15804u16,19525u16),(15805u16,19527u16), (15843u16,2161u16),(15864u16,2193u16),(15878u16,976u16),(15889u16,4149u16), (15916u16,4672u16),(15917u16,3568u16),(15918u16,2444u16),(15919u16,19558u16), (15920u16,19568u16),(15921u16,2677u16),(15929u16,2752u16),(16008u16,4491u16), (16009u16,2756u16),(16010u16,2737u16),(16011u16,2209u16),(16057u16,4150u16), (16063u16,2753u16),(16087u16,2041u16),(16119u16,4671u16),(16120u16,3013u16), (16121u16,3642u16),(16122u16,3091u16),(16123u16,2679u16),(16124u16,19516u16), (16181u16,3022u16),(16193u16,2022u16),(16202u16,4200u16),(16225u16,977u16), (16255u16,2991u16),(16256u16,19092u16),(16257u16,4388u16),(16258u16,19560u16), (16271u16,2318u16),(16308u16,19587u16),(16311u16,19373u16),(16320u16,2977u16), (16325u16,19000u16),(16363u16,19134u16),(16364u16,19094u16),(16365u16,3567u16), (16366u16,3291u16),(16367u16,4247u16),(16368u16,19586u16),(16401u16,4985u16), (16441u16,19585u16),(16442u16,19164u16),(16443u16,4159u16),(16444u16,2994u16), (16445u16,19571u16),(16471u16,2115u16),(16517u16,19548u16),(16523u16,2695u16), (16524u16,19402u16),(16525u16,2788u16),(16529u16,19583u16),(16585u16,2792u16), (16609u16,2694u16),(16620u16,1869u16),(16644u16,3385u16),(16655u16,2696u16), (16665u16,4155u16),(16703u16,19588u16),(16704u16,19592u16),(16708u16,19581u16), (16718u16,1733u16),(16725u16,19584u16),(16726u16,19590u16),(16727u16,19591u16), (16732u16,2511u16),(16735u16,19688u16),(16737u16,1009u16),(16759u16,1645u16), (16762u16,4357u16),(16803u16,4598u16),(16804u16,19528u16),(16805u16,19187u16), (16812u16,3447u16),(16821u16,3439u16),(16845u16,19457u16),(16866u16,19657u16), (16892u16,3629u16),(16923u16,3312u16),(16971u16,2558u16),(16982u16,3656u16), (16985u16,3647u16),(17014u16,3002u16),(17015u16,19606u16),(17016u16,19210u16), (17028u16,3228u16),(17043u16,3640u16),(17045u16,2820u16),(17061u16,3637u16), (17087u16,958u16),(17089u16,19616u16),(17097u16,2936u16),(17098u16,3645u16), (17134u16,4157u16),(17146u16,3469u16),(17165u16,4158u16),(17178u16,3001u16), (17204u16,4160u16),(17224u16,2624u16),(17250u16,3590u16),(17251u16,19197u16), (17252u16,2591u16),(17253u16,19613u16),(17292u16,2774u16),(17302u16,4161u16), (17308u16,19449u16),(17341u16,3654u16),(17345u16,3471u16),(17385u16,3660u16), (17386u16,3281u16),(17394u16,4698u16),(17400u16,2646u16),(17412u16,4170u16), (17461u16,19166u16),(17462u16,2711u16),(17498u16,19618u16),(17499u16,3644u16), (17523u16,2645u16),(17543u16,2965u16),(17544u16,3458u16),(17593u16,2639u16), (17596u16,19301u16),(17614u16,3652u16),(17619u16,1447u16),(17622u16,4171u16), (17669u16,1797u16),(17697u16,4260u16),(17784u16,2096u16),(17864u16,1493u16), (17944u16,4643u16),(17962u16,2958u16),(18021u16,2890u16),(18036u16,4173u16), (18071u16,3064u16),(18132u16,2887u16),(18182u16,4591u16),(18213u16,3008u16), (18223u16,4175u16),(18319u16,3007u16),(18400u16,4620u16),(18450u16,4183u16), (18467u16,19645u16),(18562u16,2093u16),(18665u16,1686u16),(18672u16,3067u16), (18673u16,19520u16),(18674u16,3705u16),(18675u16,3050u16),(18683u16,4184u16), (18687u16,3279u16),(18688u16,19530u16),(18689u16,19291u16),(18700u16,19529u16), (18710u16,3501u16),(18711u16,3016u16),(18713u16,4805u16),(18735u16,3257u16), (18739u16,19015u16),(18740u16,4263u16),(18750u16,4750u16),(18751u16,4215u16), (18752u16,19419u16),(18753u16,3431u16),(18754u16,19006u16),(18755u16,3517u16), (18786u16,3153u16),(18787u16,4703u16),(18804u16,19634u16),(18805u16,2620u16), (18806u16,3503u16),(18811u16,1836u16),(18815u16,19547u16),(18818u16,19357u16), (18824u16,4383u16),(18825u16,2912u16),(18826u16,2358u16),(18827u16,3479u16), (18828u16,3100u16),(18829u16,19663u16),(18830u16,3044u16),(18831u16,19358u16), (18836u16,2675u16),(18852u16,19042u16),(18855u16,2190u16),(18857u16,19239u16), (18859u16,3043u16),(18860u16,2776u16),(18861u16,3534u16),(18871u16,19662u16), (18872u16,3359u16),(18873u16,3478u16),(18874u16,4137u16),(18875u16,2621u16), (18885u16,3049u16),(18896u16,4314u16),(18906u16,1643u16),(18910u16,3412u16), (18911u16,19392u16),(18915u16,2902u16),(18917u16,3499u16),(18924u16,2989u16), (18925u16,3289u16),(18934u16,4245u16),(18935u16,3167u16),(18936u16,2623u16), (18937u16,3129u16),(18939u16,19664u16),(18958u16,2736u16),(18962u16,19750u16), (18963u16,1800u16),(18965u16,4185u16),(18977u16,19450u16),(18978u16,19620u16), (18979u16,19413u16),(18980u16,19659u16),(18981u16,2666u16),(18982u16,19668u16), (18983u16,19619u16),(18984u16,19412u16),(18985u16,2526u16),(18986u16,4325u16), (19006u16,3493u16),(19010u16,3280u16),(19013u16,4162u16),(19018u16,3015u16), (19022u16,3047u16),(19023u16,3664u16),(19024u16,3528u16),(19025u16,2625u16), (19037u16,3670u16),(19045u16,2178u16),(19046u16,3496u16),(19047u16,3327u16), (19057u16,3591u16),(19063u16,4861u16),(19064u16,3290u16),(19065u16,19689u16), (19066u16,2330u16),(19084u16,19687u16),(19091u16,4462u16),(19092u16,3494u16), (19093u16,2179u16),(19094u16,3074u16),(19108u16,3010u16),(19109u16,4387u16), (19110u16,19066u16),(19111u16,4201u16),(19121u16,19026u16),(19122u16,3319u16), (19123u16,3488u16),(19130u16,3071u16),(19131u16,4882u16),(19132u16,2787u16), (19136u16,4187u16),(19143u16,3072u16),(19146u16,4427u16),(19153u16,2464u16), (19167u16,3020u16),(19170u16,4722u16),(19177u16,2473u16),(19215u16,1911u16), (19310u16,4645u16),(19445u16,19199u16),(19465u16,3244u16),(19614u16,4492u16), (19615u16,3604u16),(19657u16,2352u16),(19673u16,3034u16),(19718u16,3035u16), (19731u16,19710u16),(19896u16,1424u16),(19946u16,1434u16),(19947u16,1611u16), (20027u16,1535u16),(20048u16,1624u16),(20133u16,4190u16),(20135u16,1453u16), (20238u16,5017u16),(20316u16,3736u16),(20354u16,19708u16),(20358u16,4191u16), (20375u16,3450u16),(20378u16,4235u16),(20393u16,4661u16),(20408u16,2172u16), (20418u16,4612u16),(20524u16,4194u16),(20562u16,1480u16),(20637u16,19733u16), (20779u16,1418u16),(20808u16,4550u16),(20861u16,19734u16),(20862u16,1637u16), (20941u16,1737u16),(20963u16,1551u16),(20966u16,19437u16),(20967u16,3058u16), (21024u16,19740u16),(21025u16,3057u16),(21072u16,19337u16),(21145u16,4198u16), (21191u16,1460u16),(21208u16,1641u16),(21262u16,2072u16),(21265u16,4501u16), (21267u16,19444u16),(21529u16,4199u16),(21541u16,2928u16),(21551u16,2654u16), (21552u16,2324u16),(21574u16,4203u16),(21612u16,2494u16),(21614u16,4204u16), (21658u16,1903u16),(21809u16,5005u16),(21813u16,3763u16),(21823u16,4208u16), (21851u16,2927u16),(21852u16,2678u16),(21853u16,3424u16),(21854u16,4210u16), (21858u16,4212u16),(21861u16,2325u16),(21862u16,4213u16),(21889u16,3077u16), (21892u16,2923u16),(21903u16,2925u16),(21945u16,2412u16),(21973u16,3513u16), (21979u16,2417u16),(21984u16,19757u16),(22021u16,19631u16),(22069u16,4482u16), (22097u16,2717u16),(22147u16,3210u16),(22165u16,1805u16),(22243u16,3085u16), (22262u16,3698u16),(22278u16,2512u16),(22301u16,19403u16),(22309u16,2535u16), (22333u16,1650u16),(22386u16,19122u16),(22471u16,4214u16),(22495u16,3300u16), (22496u16,2045u16),(22497u16,4254u16),(22615u16,19771u16),(22621u16,4216u16), (22642u16,2948u16),(22728u16,3344u16),(22750u16,1005u16),(22753u16,2051u16), (22787u16,4221u16),(22854u16,2817u16),(22870u16,4483u16),(22956u16,2055u16), (22988u16,19263u16),(23124u16,974u16),(23189u16,4649u16),(23196u16,3114u16), (23214u16,4224u16),(23215u16,3113u16),(23273u16,3157u16),(23412u16,1659u16), (23433u16,4225u16),(23475u16,3125u16),(23476u16,2077u16),(23494u16,3119u16), (23524u16,2231u16),(23528u16,4118u16),(23553u16,2068u16),(23558u16,4226u16), (23585u16,4802u16),(23626u16,4499u16),(23653u16,2085u16),(23697u16,2249u16), (23716u16,1804u16),(23744u16,2251u16),(23745u16,2090u16),(23806u16,2073u16), (23840u16,2083u16),(23856u16,1739u16),(23875u16,3158u16),(23961u16,1051u16), (23993u16,1036u16),(24078u16,3160u16),(24137u16,1527u16),(24193u16,4485u16), (24194u16,3143u16),(24195u16,2825u16),(24230u16,3127u16),(24252u16,3126u16), (24279u16,5003u16),(24280u16,4508u16),(24346u16,4946u16),(24395u16,2662u16), (24545u16,3017u16),(24546u16,4148u16),(24609u16,1003u16),(24617u16,2116u16), (24648u16,4628u16),(24676u16,3407u16),(24707u16,19765u16),(24727u16,1495u16), (24740u16,3477u16),(24741u16,1468u16),(24834u16,4231u16),(24865u16,2124u16), (24921u16,4912u16),(24922u16,2125u16),(24923u16,3476u16),(24924u16,3140u16), (25005u16,5012u16),(25006u16,3075u16),(25010u16,4234u16),(25053u16,19593u16), (25176u16,4486u16),(25185u16,3139u16),(25194u16,1691u16),(25195u16,5023u16), (25296u16,2135u16),(25397u16,4717u16),(25419u16,1694u16),(25420u16,5020u16), (25425u16,2138u16),(25534u16,3306u16),(25589u16,19721u16),(25592u16,3152u16), (25602u16,4237u16),(25616u16,2461u16),(25617u16,4271u16),(25618u16,3151u16), (25674u16,4238u16),(25705u16,4287u16),(25732u16,4242u16),(25736u16,4246u16), (25737u16,2147u16),(25741u16,2061u16),(25752u16,2171u16),(25874u16,4248u16), (25970u16,1600u16),(26016u16,3170u16),(26029u16,3168u16),(26047u16,4250u16), (26130u16,1697u16),(26150u16,2160u16),(26287u16,4478u16),(26289u16,2700u16), (26293u16,4251u16),(26330u16,1476u16),(26344u16,2162u16),(26364u16,4261u16), (26390u16,1477u16),(26433u16,3474u16),(26521u16,4269u16),(26547u16,4667u16), (26548u16,3180u16),(26572u16,4964u16),(26652u16,1545u16),(26694u16,5016u16), (26718u16,4272u16),(26734u16,4270u16),(26760u16,19324u16),(26762u16,4580u16), (26771u16,4594u16),(26823u16,4274u16),(26894u16,19726u16),(26897u16,19725u16), (26918u16,4278u16),(26937u16,4280u16),(26961u16,1698u16),(27048u16,2549u16), (27061u16,4372u16),(27122u16,1433u16),(27130u16,4283u16),(27181u16,4285u16), (27182u16,19654u16),(27188u16,4290u16),(27202u16,3182u16),(27217u16,3185u16), (27218u16,2183u16),(27397u16,2211u16),(27402u16,2189u16),(27411u16,19087u16), (27413u16,1842u16),(27427u16,972u16),(27432u16,19274u16),(27472u16,1582u16), (27473u16,19521u16),(27474u16,4205u16),(27475u16,19144u16),(27483u16,4291u16), (27509u16,3145u16),(27522u16,3397u16),(27542u16,2240u16),(27543u16,2212u16), (27549u16,4295u16),(27571u16,19018u16),(27584u16,3584u16),(27639u16,4240u16), (27681u16,2697u16),(27712u16,3449u16),(27713u16,1875u16),(27718u16,1897u16), (27774u16,19192u16),(27775u16,2078u16),(27776u16,3620u16),(27777u16,19224u16), (27778u16,3613u16),(27812u16,4297u16),(27831u16,3607u16),(27832u16,2459u16), (27837u16,4266u16),(27840u16,3467u16),(27843u16,2154u16),(27857u16,3173u16), (27938u16,4721u16),(27939u16,4793u16),(27940u16,2938u16),(27941u16,19540u16), (27942u16,3611u16),(27943u16,2518u16),(27944u16,3650u16),(27945u16,19023u16), (27946u16,19225u16),(27985u16,3612u16),(28020u16,1840u16),(28064u16,19466u16), (28065u16,19541u16),(28066u16,2603u16),(28067u16,2210u16),(28068u16,3400u16), (28069u16,2219u16),(28070u16,19230u16),(28071u16,3187u16),(28078u16,4300u16), (28124u16,5009u16),(28138u16,3030u16),(28139u16,19542u16),(28144u16,3402u16), (28160u16,3405u16),(28165u16,4889u16),(28167u16,4366u16),(28178u16,3395u16), (28226u16,2228u16),(28227u16,2242u16),(28228u16,2106u16),(28229u16,19235u16), (28270u16,19330u16),(28274u16,19549u16),(28279u16,2241u16),(28292u16,3401u16), (28296u16,1049u16),(28299u16,961u16),(28313u16,2255u16),(28368u16,4600u16), (28369u16,4966u16),(28370u16,19367u16),(28371u16,2043u16),(28372u16,2224u16), (28373u16,2451u16),(28374u16,2108u16),(28375u16,2388u16),(28454u16,2684u16), (28531u16,2877u16),(28532u16,19551u16),(28575u16,19731u16),(28577u16,19245u16), (28606u16,1843u16),(28638u16,3614u16),(28639u16,3396u16),(28686u16,1346u16), (28747u16,4304u16),(28754u16,2680u16),(28755u16,3621u16),(28808u16,2264u16), (28845u16,5010u16),(28846u16,4706u16),(28847u16,4351u16),(28877u16,2267u16), (28882u16,962u16),(28920u16,19339u16),(28937u16,3616u16),(28940u16,2361u16), (28941u16,1838u16),(28966u16,19777u16),(28967u16,3172u16),(29028u16,4718u16), (29029u16,2676u16),(29045u16,2508u16),(29133u16,4305u16),(29211u16,3189u16), (29287u16,947u16),(29312u16,4307u16),(29317u16,4308u16),(29323u16,4311u16), (29362u16,4666u16),(29366u16,4601u16),(29414u16,4313u16),(29522u16,960u16), (29594u16,2274u16),(29695u16,1900u16),(29730u16,3201u16),(29776u16,4317u16), (29828u16,3538u16),(29830u16,4958u16),(30068u16,1538u16),(30115u16,4625u16), (30176u16,2289u16),(30180u16,2291u16),(30205u16,2867u16),(30206u16,4151u16), (30215u16,11213u16),(30220u16,19761u16),(30258u16,4209u16),(30265u16,1571u16), (30293u16,4480u16),(30294u16,5004u16),(30295u16,4147u16),(30356u16,1633u16), (30479u16,2300u16),(30517u16,1268u16),(30518u16,3643u16),(30529u16,3084u16), (30558u16,1594u16),(30596u16,3213u16),(30597u16,3212u16),(30668u16,4336u16), (30808u16,4337u16),(30832u16,2942u16),(30877u16,4470u16),(30898u16,1702u16), (30920u16,1462u16),(31012u16,2309u16),(31079u16,3883u16),(31098u16,2501u16), (31136u16,1478u16),(31197u16,4347u16),(31229u16,4353u16),(31242u16,4354u16), (31246u16,19256u16),(31294u16,4477u16),(31315u16,19359u16),(31321u16,2315u16), (31353u16,4133u16),(31364u16,19024u16),(31421u16,2310u16),(31422u16,2391u16), (31476u16,3695u16),(31494u16,3337u16),(31499u16,4355u16),(31512u16,3702u16), (31544u16,2320u16),(31545u16,19773u16),(31546u16,2317u16),(31560u16,3141u16), (31589u16,1046u16),(31727u16,986u16),(31732u16,3599u16),(31762u16,4232u16), (31852u16,968u16),(31921u16,950u16),(31941u16,952u16),(32047u16,4597u16), (32083u16,2342u16),(32084u16,2338u16),(32102u16,4356u16),(32115u16,4599u16), (32132u16,1413u16),(32143u16,2339u16),(32152u16,2344u16),(32189u16,2345u16), (32220u16,3236u16),(32333u16,3653u16),(32335u16,3563u16),(32558u16,4684u16), (32761u16,4613u16),(32770u16,2356u16),(32777u16,4360u16),(32798u16,2984u16), (32803u16,4371u16),(32804u16,4474u16),(32840u16,4375u16),(32899u16,4378u16), (32912u16,4391u16),(32957u16,1604u16),(32958u16,1427u16),(33000u16,4343u16), (33001u16,1451u16),(33012u16,4392u16),(33070u16,4393u16),(33103u16,4395u16), (33117u16,1432u16),(33135u16,4370u16),(33161u16,4396u16),(33199u16,4397u16), (33212u16,2360u16),(33287u16,1621u16),(33304u16,3558u16),(33306u16,4398u16), (33366u16,1446u16),(33404u16,1646u16),(33435u16,1525u16),(33485u16,1634u16), (33506u16,4540u16),(33542u16,4399u16),(33560u16,4364u16),(33583u16,4400u16), (33594u16,2145u16),(33637u16,2369u16),(33645u16,2122u16),(33661u16,4857u16), (33674u16,4401u16),(33810u16,2370u16),(33896u16,4403u16),(33900u16,1360u16), (33907u16,4322u16),(33922u16,19310u16),(34049u16,2385u16),(34108u16,2390u16), (34109u16,2378u16),(34156u16,2393u16),(34280u16,4176u16),(34292u16,19442u16), (34304u16,2546u16),(34315u16,2394u16),(34341u16,2261u16),(34363u16,2262u16), (34474u16,4404u16),(34475u16,19110u16),(34482u16,1899u16),(34492u16,2384u16), (34520u16,2442u16),(34534u16,2398u16),(34575u16,1755u16),(34579u16,2396u16), (34820u16,19648u16),(34859u16,19646u16),(35085u16,1010u16),(35123u16,2406u16), (35144u16,4223u16),(35145u16,4381u16),(35158u16,4407u16),(35172u16,19744u16), (35176u16,19745u16),(35180u16,2638u16),(35181u16,1887u16),(35198u16,2630u16), (35209u16,3303u16),(35240u16,2858u16),(35242u16,19016u16),(35243u16,4352u16), (35256u16,4410u16),(35260u16,19154u16),(35264u16,2012u16),(35292u16,2985u16), (35294u16,2377u16),(35297u16,3648u16),(35299u16,1771u16),(35300u16,19007u16), (35303u16,4412u16),(35304u16,4414u16),(35321u16,3217u16),(35322u16,3480u16), (35323u16,2835u16),(35324u16,3461u16),(35343u16,5013u16),(35350u16,3510u16), (35365u16,2307u16),(35369u16,19343u16),(35378u16,1741u16),(35382u16,19333u16), (35396u16,2634u16),(35397u16,3330u16),(35398u16,2807u16),(35399u16,2855u16), (35400u16,2165u16),(35401u16,3453u16),(35402u16,19483u16),(35403u16,3264u16), (35417u16,3689u16),(35418u16,4867u16),(35457u16,3545u16),(35458u16,3515u16), (35459u16,3601u16),(35482u16,4156u16),(35483u16,19117u16),(35484u16,2765u16), (35520u16,3533u16),(35526u16,2414u16),(35531u16,2982u16),(35532u16,3042u16), (35534u16,3509u16),(35550u16,19089u16),(35551u16,19471u16),(35552u16,2455u16), (35553u16,2421u16),(35554u16,2425u16),(35555u16,3054u16),(35557u16,2426u16), (35562u16,1764u16),(35580u16,3266u16),(35596u16,2416u16),(35603u16,2706u16), (35617u16,19556u16),(35618u16,2924u16),(35627u16,19764u16),(35628u16,4469u16), (35629u16,4996u16),(35631u16,3305u16),(35654u16,4415u16),(35660u16,1484u16), (35662u16,4181u16),(35664u16,3326u16),(35683u16,3485u16),(35684u16,3328u16), (35685u16,3343u16),(35686u16,19183u16),(35692u16,4475u16),(35727u16,19690u16), (35737u16,4476u16),(35740u16,3216u16),(35741u16,19376u16),(35769u16,983u16), (35778u16,4931u16),(35781u16,3318u16),(35796u16,4416u16),(35799u16,2827u16), (35801u16,3215u16),(35802u16,2627u16),(35815u16,3512u16),(35816u16,19622u16), (35817u16,2048u16),(35818u16,2981u16),(35819u16,2422u16),(35820u16,2429u16), (35829u16,3214u16),(35839u16,2431u16),(35843u16,19692u16),(35849u16,4418u16), (35868u16,3583u16),(35869u16,3268u16),(35875u16,3021u16),(35878u16,3304u16), (35883u16,2598u16),(35888u16,4377u16),(35897u16,2430u16),(35899u16,3269u16), (36042u16,1585u16),(36045u16,1542u16),(36050u16,1583u16),(36148u16,3276u16), (36249u16,1584u16),(36281u16,1822u16),(36367u16,1709u16),(36406u16,2631u16), (36409u16,4933u16),(36453u16,3287u16),(36454u16,3286u16),(36503u16,4791u16), (36524u16,19702u16),(36530u16,19675u16),(36531u16,2727u16),(36569u16,19699u16), (36583u16,3285u16),(36805u16,4420u16),(36985u16,1890u16),(37000u16,2876u16), (37003u16,2611u16),(37011u16,3299u16),(37039u16,2462u16),(37040u16,3296u16), (37041u16,2537u16),(37056u16,4276u16),(37092u16,3560u16),(37093u16,2463u16), (37100u16,4421u16),(37101u16,19458u16),(37133u16,19780u16),(37136u16,4423u16), (37180u16,4424u16),(37197u16,2888u16),(37211u16,3685u16),(37214u16,4426u16), (37232u16,19578u16),(37276u16,19500u16),(37288u16,4348u16),(37333u16,2478u16), (37355u16,2481u16),(37917u16,2500u16),(37920u16,3690u16),(37939u16,2497u16), (37951u16,2917u16),(37960u16,3225u16),(38096u16,4716u16),(38105u16,2052u16), (38106u16,3321u16),(38117u16,1425u16),(38119u16,4431u16),(38302u16,4662u16), (38320u16,4433u16),(38328u16,4434u16),(38359u16,3323u16),(38377u16,4432u16), (38388u16,1457u16),(38688u16,1532u16),(38706u16,4435u16),(38868u16,1461u16), (38928u16,1715u16),(38999u16,2528u16),(39076u16,4334u16),(39121u16,4436u16), (39146u16,2895u16),(39153u16,3349u16),(39162u16,1882u16),(39171u16,5008u16), (39173u16,2529u16),(39215u16,3392u16),(39237u16,997u16),(39239u16,1763u16), (39240u16,3351u16),(39241u16,4437u16),(39261u16,19377u16),(39274u16,4438u16), (39325u16,2683u16),(39363u16,4439u16),(39369u16,4177u16),(39464u16,4440u16), (39501u16,1450u16),(39685u16,2541u16),(39694u16,4441u16),(39893u16,2538u16), (40051u16,1729u16),(40109u16,4333u16),(40254u16,2554u16),(40282u16,4442u16), (40316u16,4621u16),(40344u16,4503u16),(40347u16,4443u16),(40438u16,1345u16), (40454u16,4704u16),(40493u16,3379u16),(40552u16,2562u16),(40620u16,4655u16), (40624u16,991u16),(40643u16,1591u16),(40696u16,4445u16),(40739u16,4446u16), (40752u16,4659u16),(40887u16,2564u16),(40926u16,4663u16),(40980u16,2383u16), (41095u16,2153u16),(41145u16,2582u16),(41185u16,2567u16),(41197u16,3390u16), (41203u16,3391u16),(41208u16,2277u16),(41214u16,3382u16),(41223u16,1748u16), (41251u16,2568u16),(41267u16,1348u16),(41268u16,2572u16),(41296u16,19209u16), (41362u16,2565u16),(41363u16,2577u16),(41387u16,2566u16),(41396u16,3389u16), (41397u16,1893u16),(41439u16,2569u16),(41461u16,3381u16),(41504u16,2578u16), (41523u16,2580u16),(41619u16,4449u16),(41631u16,2373u16),(41650u16,4872u16), (41652u16,2583u16),(41654u16,3683u16),(41658u16,1758u16),(41661u16,1642u16), (41695u16,4362u16),(41727u16,4451u16),(41809u16,964u16),(41897u16,1256u16), (42036u16,4691u16),(42075u16,2898u16),(42438u16,3039u16),(42443u16,4454u16), (42497u16,1516u16),(42546u16,1581u16),(42570u16,4848u16),(42587u16,1541u16), (42665u16,4606u16),(44543u16,1064u16),(63525u16,3663u16),(63547u16,4027u16), (63552u16,4874u16),(63608u16,1667u16),(63636u16,19319u16),(63654u16,19366u16), (63693u16,4257u16),(63892u16,2196u16),(63922u16,2268u16),(63932u16,3198u16), (63956u16,2340u16), ] const ShiftJISEncode*: array[374, UCS16x16] = [ (8560u16,10716u16),(8561u16,10717u16),(8562u16,10718u16),(8563u16,10719u16), (8564u16,10720u16),(8565u16,10721u16),(8566u16,10722u16),(8567u16,10723u16), (8568u16,10724u16),(8569u16,10725u16),(8722u16,60u16),(20008u16,10756u16), (20193u16,10757u16),(20220u16,10758u16),(20224u16,10759u16),(20227u16,10760u16), (20281u16,10761u16),(20310u16,10762u16),(20362u16,10764u16),(20370u16,10763u16), (20372u16,10766u16),(20378u16,10765u16),(20425u16,10749u16),(20429u16,10767u16), (20479u16,10770u16),(20510u16,10771u16),(20514u16,10769u16),(20544u16,10768u16), (20546u16,10774u16),(20550u16,10772u16),(20592u16,10773u16),(20628u16,10775u16), (20696u16,10777u16),(20724u16,10776u16),(20810u16,10778u16),(20836u16,10779u16), (20893u16,10780u16),(20926u16,10781u16),(20972u16,10782u16),(21013u16,10783u16), (21148u16,10784u16),(21158u16,10785u16),(21167u16,10959u16),(21184u16,10786u16), (21211u16,10787u16),(21248u16,10788u16),(21255u16,10789u16),(21284u16,10790u16), (21362u16,10791u16),(21395u16,10792u16),(21426u16,10793u16),(21469u16,10794u16), (21642u16,10797u16),(21660u16,10796u16),(21673u16,10798u16),(21759u16,10799u16), (21894u16,10800u16),(22361u16,10801u16),(22373u16,10802u16),(22444u16,10803u16), (22471u16,10805u16),(22472u16,10804u16),(22686u16,10808u16),(22706u16,10809u16), (22795u16,10810u16),(22867u16,10811u16),(22875u16,10812u16),(22877u16,10813u16), (22883u16,10814u16),(22948u16,10815u16),(22970u16,10816u16),(23382u16,10817u16), (23488u16,10818u16),(23512u16,10820u16),(23532u16,10821u16),(23582u16,10822u16), (23718u16,10823u16),(23738u16,10824u16),(23797u16,10825u16),(23847u16,10826u16), (23874u16,10829u16),(23891u16,10827u16),(23917u16,10830u16),(23992u16,10831u16), (23993u16,10832u16),(24016u16,10833u16),(24353u16,10834u16),(24372u16,10835u16), (24389u16,10755u16),(24423u16,10836u16),(24503u16,10837u16),(24542u16,10838u16), (24669u16,10839u16),(24709u16,10840u16),(24714u16,10841u16),(24789u16,10843u16), (24798u16,10842u16),(24818u16,10845u16),(24849u16,10846u16),(24864u16,10844u16), (24880u16,10848u16),(24887u16,10847u16),(24984u16,10849u16),(25107u16,10850u16), (25254u16,10851u16),(25589u16,10852u16),(25696u16,10853u16),(25757u16,10854u16), (25806u16,10855u16),(25934u16,10856u16),(26112u16,10857u16),(26121u16,10860u16), (26133u16,10858u16),(26142u16,10862u16),(26148u16,10863u16),(26158u16,10861u16), (26161u16,10751u16),(26171u16,10859u16),(26199u16,10865u16),(26201u16,10866u16), (26213u16,10864u16),(26227u16,10868u16),(26265u16,10869u16),(26272u16,10870u16), (26290u16,10871u16),(26303u16,10872u16),(26362u16,10873u16),(26363u16,10754u16), (26382u16,10874u16),(26470u16,10876u16),(26555u16,10877u16),(26560u16,10879u16), (26625u16,10880u16),(26692u16,10881u16),(26706u16,10878u16),(26824u16,10752u16), (26831u16,10882u16),(26984u16,10884u16),(27032u16,10886u16),(27106u16,10887u16), (27184u16,10888u16),(27206u16,10890u16),(27243u16,10889u16),(27251u16,10891u16), (27262u16,10892u16),(27362u16,10893u16),(27364u16,10894u16),(27606u16,10895u16), (27711u16,10896u16),(27740u16,10897u16),(27759u16,10899u16),(27782u16,10898u16), (27866u16,10900u16),(27908u16,10901u16),(28015u16,10903u16),(28039u16,10902u16), (28054u16,10904u16),(28076u16,10905u16),(28111u16,10906u16),(28146u16,10908u16), (28152u16,10907u16),(28156u16,10909u16),(28199u16,10912u16),(28217u16,10910u16), (28220u16,10913u16),(28252u16,10911u16),(28351u16,10914u16),(28552u16,10915u16), (28597u16,10916u16),(28661u16,10917u16),(28677u16,10918u16),(28679u16,10919u16), (28712u16,10920u16),(28805u16,10921u16),(28843u16,10922u16),(28859u16,10750u16), (28932u16,10924u16),(28943u16,10923u16),(28998u16,10926u16),(28999u16,10927u16), (29020u16,10925u16),(29121u16,10929u16),(29182u16,10930u16),(29361u16,10931u16), (29374u16,10932u16),(29476u16,10933u16),(29559u16,10935u16),(29629u16,10936u16), (29641u16,10937u16),(29650u16,10940u16),(29654u16,10938u16),(29667u16,10939u16), (29685u16,10942u16),(29703u16,10941u16),(29734u16,10943u16),(29737u16,10945u16), (29738u16,10944u16),(29742u16,10946u16),(29794u16,10947u16),(29833u16,10948u16), (29855u16,10949u16),(29953u16,10950u16),(29999u16,10819u16),(30063u16,10951u16), (30338u16,10952u16),(30363u16,10955u16),(30364u16,10953u16),(30366u16,10954u16), (30374u16,10956u16),(30534u16,10958u16),(30753u16,10960u16),(30798u16,10961u16), (30820u16,10962u16),(30842u16,10963u16),(31024u16,10964u16),(31124u16,10968u16), (31131u16,10970u16),(31441u16,10971u16),(31463u16,10972u16),(31467u16,10974u16), (31646u16,10975u16),(32072u16,10977u16),(32092u16,10978u16),(32160u16,10980u16), (32183u16,10979u16),(32214u16,10981u16),(32338u16,10982u16),(32394u16,10744u16), (32583u16,10983u16),(32673u16,10984u16),(33537u16,10986u16),(33634u16,10987u16), (33663u16,10988u16),(33735u16,10989u16),(33782u16,10990u16),(33864u16,10991u16), (33972u16,10992u16),(34012u16,10748u16),(34131u16,10993u16),(34137u16,10994u16), (34155u16,10995u16),(34224u16,10997u16),(34823u16,11000u16),(35061u16,11001u16), (35100u16,10745u16),(35346u16,11002u16),(35383u16,11003u16),(35449u16,11004u16), (35495u16,11005u16),(35518u16,11006u16),(35551u16,11007u16),(35574u16,11009u16), (35667u16,11010u16),(35711u16,11011u16),(36080u16,11012u16),(36084u16,11013u16), (36114u16,11014u16),(36214u16,11015u16),(36559u16,11017u16),(36967u16,11020u16), (37086u16,11021u16),(37141u16,11023u16),(37159u16,11024u16),(37335u16,11026u16), (37338u16,11025u16),(37342u16,11027u16),(37348u16,11030u16),(37349u16,11031u16), (37357u16,11028u16),(37358u16,11029u16),(37382u16,11032u16),(37386u16,11034u16), (37392u16,11033u16),(37433u16,11041u16),(37434u16,11035u16),(37436u16,11037u16), (37440u16,11036u16),(37454u16,11038u16),(37457u16,11040u16),(37465u16,11039u16), (37479u16,11042u16),(37495u16,11044u16),(37496u16,11045u16),(37512u16,10747u16), (37543u16,11043u16),(37584u16,11049u16),(37587u16,11053u16),(37589u16,11051u16), (37591u16,11047u16),(37593u16,11048u16),(37600u16,11052u16),(37607u16,11046u16), (37625u16,10753u16),(37627u16,11056u16),(37631u16,11059u16),(37634u16,11061u16), (37661u16,11060u16),(37662u16,11058u16),(37665u16,11055u16),(37669u16,11054u16), (37704u16,10746u16),(37719u16,11063u16),(37744u16,11062u16),(37796u16,11064u16), (37830u16,11065u16),(37854u16,11066u16),(37880u16,11067u16),(37937u16,11068u16), (37957u16,11069u16),(37960u16,11070u16),(38290u16,11071u16),(38557u16,11074u16), (38575u16,11075u16),(38707u16,11076u16),(38715u16,11077u16),(38723u16,11078u16), (38733u16,11079u16),(38735u16,11080u16),(38737u16,11081u16),(38741u16,11082u16), (38999u16,11083u16),(39013u16,11084u16),(39207u16,11087u16),(39326u16,11089u16), (39502u16,11090u16),(39641u16,11091u16),(39644u16,11092u16),(39794u16,11094u16), (39797u16,11093u16),(39823u16,11095u16),(39857u16,11096u16),(39867u16,11097u16), (39936u16,11098u16),(40299u16,11100u16),(40304u16,11099u16),(40473u16,11102u16), (40657u16,11103u16),(63785u16,10875u16),(63964u16,11072u16),(64014u16,10795u16), (64015u16,10806u16),(64016u16,10807u16),(64017u16,10828u16),(64018u16,10867u16), (64019u16,10883u16),(64020u16,10885u16),(64021u16,10928u16),(64022u16,10934u16), (64023u16,10957u16),(64024u16,10965u16),(64025u16,10966u16),(64026u16,10967u16), (64027u16,10969u16),(64028u16,10973u16),(64029u16,10976u16),(64030u16,10985u16), (64031u16,10996u16),(64032u16,10998u16),(64033u16,10999u16),(64034u16,11008u16), (64035u16,11016u16),(64036u16,11018u16),(64037u16,11019u16),(64038u16,11022u16), (64039u16,11050u16),(64040u16,11057u16),(64041u16,11073u16),(64042u16,11085u16), (64043u16,11086u16),(64044u16,11088u16),(64045u16,11101u16),(65282u16,10739u16), (65287u16,10738u16),(65508u16,10737u16), ] const Iso2022JPKatakanaMap*: array[63, uint8] = [ uint8 2,12,13,1,251,242,161,163,165,167,169,227,229,231,195,252,162,164,166,168, 170,171,173,175,177,179,181,183,185,187,189,191,193,196,198,200,202,203,204,205, 206,207,210,213,216,219,222,223,224,225,226,228,230,232,233,234,235,236,237,239, 243,155,156, ] ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/encoding/decoder.nim��������������������������������������������������������������0000664�0000000�0000000�00000013504�15202323131�0017624�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import charset import decodercore type DecoderErrorMode* = enum demFatal, demReplacement proc initTextDecoder*(charset: Charset): TextDecoder = ## Create a new TextDecoder instance from the charset. ## `charset` may be any value except csUnknown. assert charset != csUnknown TextDecoder(charset: charset) type UnsafeSlice* = object p*: ptr UncheckedArray[char] len*: int proc `$`*(sl: UnsafeSlice): string = if sl.p == nil: return "" var s = newString(sl.len) copyMem(addr s[0], addr sl.p[0], sl.len) return s proc toUnsafeSlice(s: openArray[uint8]): UnsafeSlice = if s.len == 0: return UnsafeSlice(p: nil, len: 0) return UnsafeSlice( p: cast[ptr UncheckedArray[char]](unsafeAddr s[0]), len: s.len ) proc toUnsafeSlice(s: openArray[char]): UnsafeSlice = return s.toOpenArrayByte(0, s.high).toUnsafeSlice() proc toUnsafeSlice(s: string): UnsafeSlice = return s.toOpenArray(0, s.high).toUnsafeSlice() type TextDecoderContext* = object td*: TextDecoder n*: int oq*: seq[uint8] failed*: bool errorMode*: DecoderErrorMode proc initTextDecoderContext*(charset: Charset; errorMode = demReplacement; bufLen = 4096): TextDecoderContext = ## Initialize a new text decoder context. ## ## `charset` is the charset to decode the buffer with. ## ## `errorMode` affects how errors are handled. With `demReplacement`, ## a U+FFFD replacement character is output when an error is encountered. ## With `demFatal`, decoding is aborted and the `failed` member of the ## `TextDecoderContext` is set to `true`. ## ## `bufLen` is the size of the internal buffer in bytes. return TextDecoderContext( td: initTextDecoder(charset), oq: newSeq[uint8](bufLen), errorMode: errorMode ) # returns whether this is the last iteration proc decodeIter(ctx: var TextDecoderContext; iq: openArray[uint8]; slices: var array[2, UnsafeSlice]; finish: bool): bool = result = false case ctx.td.decode(iq, ctx.oq, ctx.n, finish) of tdrDone: slices[0] = ctx.oq.toOpenArray(0, ctx.n - 1).toUnsafeSlice() result = true of tdrReadInput: if ctx.n > 0: slices[0] = ctx.oq.toOpenArray(0, ctx.n - 1).toUnsafeSlice() slices[1] = iq.toOpenArray(ctx.td.pi, ctx.td.ri - 1).toUnsafeSlice() of tdrReqOutput: slices[0] = ctx.oq.toOpenArray(0, ctx.n - 1).toUnsafeSlice() of tdrError: slices[0] = ctx.oq.toOpenArray(0, ctx.n - 1).toUnsafeSlice() case ctx.errorMode of demReplacement: slices[1] = "\uFFFD".toUnsafeSlice() of demFatal: ctx.failed = true result = true ctx.n = 0 iterator decode*(ctx: var TextDecoderContext; iq: openArray[uint8]; finish: bool): UnsafeSlice = ## Decodes the bytes provided in `iq` (input queue). ## ## Streaming consumers should set `finish` to true when decoding the last ## chunk. (If you don't know which chunk will be the last, just pass ## an empty chunk after the stream is broken.) ## ## Returns an `UnsafeSlice` object, which can be further processed as an ## openArray or a string. WARNING: this is simply a pointer into the ## input data and/or the output buffer. Never use an `UnsafeSlice` ## object after the iteration you received it in. var done = false while not done: var slices: array[2, UnsafeSlice] done = ctx.decodeIter(iq, slices, finish) for slice in slices: if slice.p != nil: yield slice proc `&=`*(s: var string; sl: UnsafeSlice) = ## Append the slice `sl` to `s` without unnecessary copying. ## ## Note that setLen is called on the string, which may zero out the ## target space before the copy. if sl.p != nil: let L = s.len s.setLen(s.len + sl.len) copyMem(addr s[L], sl.p, sl.len) proc high*(sl: UnsafeSlice): int = return sl.len - 1 template toOpenArray*(sl: UnsafeSlice; lo, hi: int): openArray[char] = sl.p.toOpenArray(lo, hi) template toOpenArray*(sl: UnsafeSlice): openArray[char] = sl.toOpenArray(0, sl.high) template toOpenArrayByte*(sl: UnsafeSlice; lo, hi: int): openArray[uint8] = sl.p.toOpenArrayByte(lo, hi) template toOpenArrayByte*(sl: UnsafeSlice): openArray[uint8] = sl.toOpenArrayByte(0, sl.high) proc decodeAll*(iq: openArray[uint8]; charset: Charset; success: var bool): string = ## Decode `iq` using `charset`, with `iq` representing a complete ## contiguous input queue. When a decoding error occurs, `success` is ## set to `false` and an empty string is returned; otherwise, it is set ## to `true` and the decoder's full output is returned. result = newStringOfCap(iq.len) var ctx = initTextDecoderContext(charset, errorMode = demFatal) for s in ctx.decode(iq, finish = true): result &= s success = not ctx.failed proc decodeAll*(iq: openArray[char]; charset: Charset; success: var bool): string = return iq.toOpenArrayByte(0, iq.high).decodeAll(charset, success) proc decodeAll*(iq: openArray[uint8]; charset: Charset): string = ## Use `td` to decode `iq`, representing a complete contiguous input ## queue. Decoding errors are represented by U+FFFD replacement ## characters in the output. result = newStringOfCap(iq.len) var ctx = initTextDecoderContext(charset) for s in ctx.decode(iq, finish = true): result &= s proc decodeAll*(iq: openArray[char]; charset: Charset): string = ## See above. return iq.toOpenArrayByte(0, iq.high).decodeAll(charset) proc toValidUTF8*(iq: openArray[char]): string = ## Validate the UTF-8 string `iq`, replacing invalid characters with ## U+FFFD replacement characters. return iq.decodeAll(csUtf8) proc validateUTF8Surr*(s: openArray[char]): int = ## Analogous to std/unicode's validateUtf8, but also reports surrogates. var ctx = initTextDecoderContext(csUtf8, errorMode = demFatal) for chunk in ctx.decode(s.toOpenArrayByte(0, s.high), finish = true): discard if ctx.failed: return ctx.td.ri return -1 {.pop.} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/encoding/decodercore.nim����������������������������������������������������������0000664�0000000�0000000�00000072605�15202323131�0020504�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## `TextDecoder` decodes non-UTF-8 byte sequences to valid UTF-8, in ## accordance with WHATWG's [encoding standard](https://encoding.spec.whatwg.org/). ## ## This is a low-level interface; you may also be interested in ## [decoder](decoder.html), which provides equally efficient high-level ## wrapper procedures. ## ## The implementation consists of a single procedure: `decode`, which ## dispatches on the charset field to pick the desired decoder. To decode ## an input stream, call `decode` on any number of chunks with `finish = ## false`, then with `finish = true` on the last chunk. (If you don't know ## which is the last chunk, just use an empty chunk at the end.) ## ## Each decode call may return a tdrDone, tdrReqOutput, or tdrError result. ## It takes input from `iq` (input queue), and places it in `oq` (output ## queue). The parameter `n` is always set to the last byte *written* to ## in the output queue. ## ## `tdrReqOutput` signals that the output queue was too small to fit output ## of the decoder. The consumer should provide more space, e.g. by ## copying contents of the output queue elsewhere and resetting `n`, or by ## growing the output queue in size. ## ## At this point, the internal variable `i` points to the last input byte ## consumed; bytes before that may be safely discarded, provided you adjust ## `i` accordingly (subtracting the removed input bytes). ## ## `tdrReadInput` instructs the consumer to read the input queue between the ## bytes `pi..<ri` (exclusive) as decoded output. WARNING: this does not ## mean that `oq` is left unmodified. ## ## In particular, in the UTF-8 decoder, if the previous `iq` ended with a ## split up UTF-8 character, then the next pass fills `oq` with its remains ## before it would return `tdrReadInput`. Make sure to process `oq` to `n` ## before you process `iq`. ## ## `tdrError` is returned for *all* decoding errors encountered. ## For compliance with the encoding standard, callers must either abort ## decoding the input stream (error mode "fatal"), or manually append a ## `U+FFFD` replacement character (error mode "replacement"). ## ## Note that even if `finish` is true, decoding of the chunk is *not ## complete* after receiving `tdrError` if you're using error mode ## "replacement". ## ## `tdrDone` is returned once decoding of `iq` has finished. If `finish` ## was set to true, it can be assumed that decoding is complete; otherwise, ## you should call `decode` again on the next buffer. (`i` is reset to 0 ## automatically, so there's no need to do anything before the next call.) ## ## Using TextDecoder objects after setting `finish = true` is valid, but ## not well tested, so it is recommended that you reset your decoder after ## the last chunk. {.push raises: [].} import std/algorithm import std/bitops import charset import charset_map type TextDecoderResult* = enum tdrDone, tdrReadInput, tdrReqOutput, tdrError TextDecoderFinishResult* = enum tdfrDone, tdfrError TextDecoder* = object i*: int ri*: int #TODO could be removed with some effort pi*: int charset*: Charset # note: in UTF-8, `lead' is repurposed as `needed' lead: uint8 # Big5, Shift_JIS, EUC-KR, EUC-JP, ISO-2022-JP, UTF-16 bounds: uint8 # UTF-8 flag: TextDecoderResult # UTF-8 # UTF-8: buffer storing at most 3 bytes on chunk boundaries # UTF-16: surrogate at lower 2 bytes, then a flag for whether we've # already read a lead byte # replacement: bool for whether we've already returned error # EUC-JP: bool for whether the next character uses the JIS X 0212 table # GB18030: four bytes: a buffer to emit after error, then three bytes # for a pointer into the table # ISO-2022-JP: lowest byte is a char buffer (or 0), second byte is # output flag, third byte is state, fourth byte is output # state buf: uint32 # All decoders must take care of two things: # * Put all state changes *before* returning with tdrError - for obvious # reasons :) You can't change anything after returning from the proc. # * Put all state changes *after* `try_put_*' templates. This is important # because the templates might return early requesting more place for the # output; instead of using an internal buffer, in this case we simply # repeat the computation on the previous state in the next call (after # receiving more place.) template try_put_utf8(oq: var openArray[uint8]; c: uint32; n: var int) = if c < 0x80: if n >= oq.len: return tdrReqOutput oq[n] = uint8(c) inc n elif c < 0x800: if n + 1 >= oq.len: return tdrReqOutput oq[n] = uint8(c shr 6 or 0xC0) inc n oq[n] = uint8(c and 0x3F or 0x80) inc n elif c < 0x10000: if n + 2 >= oq.len: return tdrReqOutput oq[n] = uint8(c shr 12 or 0xE0) inc n oq[n] = uint8(c shr 6 and 0x3F or 0x80) inc n oq[n] = uint8(c and 0x3F or 0x80) inc n else: assert c <= 0x10FFFF if n + 3 >= oq.len: return tdrReqOutput oq[n] = uint8(c shr 18 or 0xF0) inc n oq[n] = uint8(c shr 12 and 0x3F or 0x80) inc n oq[n] = uint8(c shr 6 and 0x3F or 0x80) inc n oq[n] = uint8(c and 0x3F or 0x80) inc n template try_put_byte(oq: var openArray[uint8]; b: uint8; n: var int) = if n >= oq.len: return tdrReqOutput oq[n] = b inc n template try_put_str(oq: var openArray[uint8]; s: static string; n: var int) = if n + s.len > oq.len: return tdrReqOutput for c in s: oq[n] = uint8(c) inc n proc gb18030RangesCodepoint(p: uint32): uint32 = if p > 39419 and p < 189000 or p > 1237575: return high(uint32) # null if p == 7457: return 0xE7C7 # Let offset be the last pointer in index gb18030 ranges that is less than or # equal to pointer and code point offset its corresponding code point. var offset: uint32 var c: uint32 if p >= 189000: # omitted from the map for storage efficiency offset = 189000 c = 0x10000 elif p >= 39394: # Needed because upperBound returns the first element greater than pointer # OR last on failure, so we can't just subtract one if p is e.g. 39400. offset = 39394 c = 0xFFE6 else: # Find the first range that is greater than p, or last if no such element # is found. # We want the last that is <=, so decrease index by one. let i = GB18030Ranges.upperBound(p, proc(a: UCS16x16; b: uint32): int = cmp(uint32(a.p), b) ) let elem = GB18030Ranges[i - 1] offset = elem.p c = elem.ucs c + p - offset # UTF-8 table: # 00..7F: ASCII # 80..BF: continuation byte # C0..C1: bad, consume 1 # C2..DF: good, consume 1 # E0 : good, consume 2 with first >= A0 # E1..EC: good, consume 2 # ED : good, consume 2 with first < A0 # EE..EF: good, consume 2 # F0 : good, consume 3 with first >= 90 # F1..F3: good, consume 3 # F4 : good, consume 3 with first < 90 # F5..FF: bad, consume 1 const u8tConsume1 = 1'u8 shl 0 # consume1 + consume2 = needed u8tConsume2 = 1'u8 shl 1 u8tCont = 1'u8 shl 2 u8tBounds0 = 1'u8 shl 3 u8tBounds1 = 1'u8 shl 4 u8tBounds2 = 1'u8 shl 5 u8tBadLead = 1'u8 shl 7 u8tConsume3 = u8tConsume1 or u8tConsume2 u8tLt90 = u8tBounds0 # c < 90 u8tGe90 = u8tBounds1 # c >= 90 u8tGeA0 = u8tBounds2 # c >= A0 u8tLtA0 = u8tBounds0 or u8tBounds1 # c < A0 # unused = u8tBounds0 or u8tBounds2 u8tBoundsMask = u8tBounds0 or u8tBounds1 or u8tBounds2 or u8tBadLead const Utf8Table = block: var res: array[uint8, uint8] for u in uint8.low..uint8.high: case u of 0x00'u8 .. 0x7F'u8: res[u] = 0 # ASCII of 0x80'u8 .. 0xBF'u8: res[u] = u8tCont or u8tConsume1 if u < 0x90: res[u] = res[u] or u8tLt90 else: res[u] = res[u] or u8tGe90 if u < 0xA0: res[u] = res[u] or u8tLtA0 else: res[u] = res[u] or u8tGeA0 of 0xC0'u8 .. 0xC1'u8: res[u] = u8tConsume1 or u8tBadLead of 0xC2'u8 .. 0xDF'u8: res[u] = u8tConsume1 of 0xE0'u8: res[u] = u8tConsume2 or u8tGeA0 of 0xE1'u8 .. 0xEC'u8: res[u] = u8tConsume2 of 0xED'u8: res[u] = u8tConsume2 or u8tLtA0 of 0xEE'u8 .. 0xEF'u8: res[u] = u8tConsume2 of 0xF0'u8: res[u] = u8tConsume3 or u8tGe90 of 0xF1'u8 .. 0xF3: res[u] = u8tConsume3 of 0xF4'u8: res[u] = u8tConsume3 or u8tLt90 of 0xF5'u8 .. 0xFF: res[u] = u8tConsume1 or u8tBadLead res proc decodeUtf8(td: var TextDecoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int; finish: bool): TextDecoderResult = var bounds = td.bounds var flag = td.flag var i = td.i var ri = td.ri # we use the lead field to store the number of needed bytes var needed = td.lead var obuf = td.buf var buf = obuf let pi = i if flag == tdrDone: while i < iq.len: let b = iq[i] let ni = i + 1 if needed == 0: if b <= 0x7F: ri = ni else: let t = Utf8Table[b] needed = t and 3 bounds = (t and u8tBoundsMask) or ((t and u8tCont) shl 5) or u8tCont buf = b else: let t = Utf8Table[b] if (t and bounds) != bounds: needed = 0 buf = 0 # prepend, no consume flag = tdrError break dec needed if needed == 0: buf = 0 ri = ni else: buf = (buf shl 8) or b bounds = u8tCont i = ni if (bounds and u8tBadLead) != 0 and needed == 1: # if streaming, we can't defer error reporting to the next iteration # (as this would be observable) needed = 0 buf = 0 flag = tdrError if obuf != 0 and pi == 0 and ri != 0: let L = (uint8(fastLog2(obuf)) + 7) shr 3 let n2 = n + int(L) if n2 > oq.len: return tdrReqOutput for i in countdown(int(L - 1), 0): oq[n + i] = uint8(obuf and 0xFF) obuf = obuf shr 8 n = n2 td.ri = ri td.i = i td.lead = needed td.bounds = bounds td.buf = buf if pi < ri: td.pi = pi td.flag = flag return tdrReadInput td.flag = tdrDone case flag of tdrError: td.pi = pi of tdrDone: td.ri = 0 if finish: td.buf = 0 td.bounds = 0 if needed != 0: td.lead = 0 return tdrError td.i = 0 else: discard # unreachable flag proc findInRuns(runs: openArray[uint32]; offset, p: uint16): uint16 = let i = runs.upperBound(p, proc(x: uint32; y: uint16): int = let x = x and 0x1FFF # mask off first 13 bits; this is the pointer return cmp(x, y) ) let u = runs[i - 1] var op = uint16(u and 0x1FFF) let len = u shr 25 if p < op + len: let diff = uint16((u shr 13) and 0xFFF) # UCS - pointer - offset return offset + p + diff return 0 proc gb18030ToU16(row, col: uint16): uint16 = if row <= 0x1F: let p = row * 190 + col return GB18030Runs.findInRuns(GB18030RunsOffset, p) if row <= 0x26: if col <= 0x5F: # PUA section if row == 0x22 and col == 0x5F: # 6555 ideographic space return 0x3000 return 0xE4C6 + (row - 0x20) * 96 + col let p = (row - 0x20) * 190 + col - (row - 0x1F) * 96 return GB18030Decode[p] if row <= 0x28: let p = (row - 0x20) * 190 + col - 7 * 96 return GB18030Decode[p] if row <= 0x7B: if col <= 0x5F: let p = (row - 0x29) * 0x60 + col return GB18030Runs2.findInRuns(GB18030RunsOffset2, p) let p = (row - 0x20) * 190 + col - 7 * 96 - (row - 0x28) * 96 return GB18030Decode[p] let p = (row - 0x20) * 190 + col - 7 * 96 - 83 * 96 if p < GB18030Decode.len: return GB18030Decode[p] return 0 proc decodeGb18030(td: var TextDecoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int; finish: bool): TextDecoderResult = if (td.buf and 0xFF) != 0: # buffer: to output after error oq.try_put_byte uint8(td.buf and 0xFF), n td.buf = td.buf and not 0xFF'u32 while (let i = td.i; i < iq.len): let b = iq[i] let s = td.buf let first = (s shr 8) and 0xFF let second = (s shr 16) and 0xFF let third = (s shr 24) and 0xFF if b < 0x80 and s == 0: # first, second, third are all 0 (ASCII) oq.try_put_byte b, n elif third != 0: if b notin 0x30u8 .. 0x39u8: # set buf to second, first to third, second and third to 0 td.buf = s shr 16 # prepend (no inc i) return tdrError let p = ((uint32(first) - 0x81) * 10 * 126 * 10) + ((uint32(second) - 0x30) * (10 * 126)) + ((uint32(third) - 0x81) * 10) + uint32(b) - 0x30 let c = gb18030RangesCodepoint(p) if c == high(uint32): # null td.buf = 0 inc td.i return tdrError else: oq.try_put_utf8 c, n td.buf = 0 elif second != 0: if b in 0x81u8 .. 0xFEu8: td.buf = s or (uint32(b) shl 24) # set third to b else: td.buf = second # set buf to second, first/second/third to 0 return tdrError elif first != 0: if b in 0x30u8 .. 0x39u8: td.buf = s or (uint32(b) shl 16) # set second to b else: if b in {0x40u8..0x7Eu8, 0x80..0xFE}: let offset = if b < 0x7F: 0x40u16 else: 0x41u16 let row = (uint16(first) - 0x81) let col = (uint16(b) - offset) if (let c = gb18030ToU16(row, col); c != 0): oq.try_put_utf8 c, n td.buf = 0 # set first to 0 inc td.i continue if b < 0x80: # prepend if ASCII td.buf = b else: td.buf = 0 inc td.i return tdrError elif b == 0x80: oq.try_put_str "\u20AC", n elif b in 0x81u8 .. 0xFEu8: td.buf = uint32(b) shl 8 # set first to b else: inc td.i return tdrError inc td.i if finish and td.buf != 0: td.buf = 0 return tdrError td.i = 0 tdrDone proc decodeBig5(td: var TextDecoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int; finish: bool): TextDecoderResult = while (let i = td.i; i < iq.len): let b = iq[i] if b < 0x80 and td.lead == 0: oq.try_put_byte b, n inc td.i continue if td.lead != 0: let offset = if b < 0x7F: 0x40u16 else: 0x62u16 if b in {0x40u8..0x7Eu8, 0xA1u8..0xFEu8}: let p = (uint16(td.lead) - 0x81) * 157 + (uint16(b) - offset) block no_continue: case p of 1133: oq.try_put_str "\u00CA\u0304", n of 1135: oq.try_put_str "\u00CA\u030C", n of 1164: oq.try_put_str "\u00EA\u0304", n of 1166: oq.try_put_str "\u00EA\u030C", n else: break no_continue td.lead = 0 inc td.i continue if p >= Big5DecodeOffset and p < Big5Decode.len + Big5DecodeOffset: var c = uint32(Big5Decode[p - Big5DecodeOffset]) if c == 1: # must linear search as it's sorted by ucs #TODO this should be done the other way around for (ucs, itp) in Big5EncodeHigh: if p == itp: c = uint32(ucs) + 0x20000 break if c != 0: oq.try_put_utf8 c, n td.lead = 0 inc td.i continue td.lead = 0 if b >= 0x80: # prepend if ASCII (only inc if 8th bit of b is set) inc td.i return tdrError elif b in 0x81u8 .. 0xFEu8: td.lead = b else: inc td.i return tdrError inc td.i if finish and td.lead != 0: td.lead = 0 return tdrError td.i = 0 tdrDone proc jis0212ToU16(row, col: uint16): uint16 = let p = row * 94 + col if p < Jis0212Decode.len: return Jis0212Decode[p] return 0 proc jis0208ToU16(row, col: uint16): uint16 = var row = row if row >= 0x5C: if row <= 0x71: return 0 row -= 32 elif row >= 0x54: if row <= 0x57: return 0 row -= 10 elif row >= 0xD: if row <= 0xE: return 0 row -= 6 elif row >= 0x8: if row <= 0xB: return 0 row -= 4 let p = row * 94 + col if p < Jis0208Decode.len: return Jis0208Decode[p] return 0 proc decodeEucJP(td: var TextDecoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int; finish: bool): TextDecoderResult = while (let i = td.i; i < iq.len): let b = iq[i] let lead = td.lead if b < 0x80 and lead == 0: oq.try_put_byte b, n inc td.i continue if lead == 0x8E and b in 0xA1u8 .. 0xDFu8: oq.try_put_utf8 b, n td.lead = 0 elif lead == 0x8F and b in 0xA1u8 .. 0xFEu8: td.buf = 1 td.lead = b elif lead != 0: if lead in 0xA1u8 .. 0xFEu8 and b in 0xA1u8 .. 0xFEu8: let row = (uint16(lead) - 0xA1) let col = uint16(b) - 0xA1 let c = if td.buf != 0: jis0212ToU16(row, col) else: jis0208ToU16(row, col) if c != 0: oq.try_put_utf8 c, n td.buf = 0 td.lead = 0 inc td.i continue td.buf = 0 td.lead = 0 inc td.i return tdrError elif b in {0x8Eu8, 0x8Fu8, 0xA1u8 .. 0xFEu8}: td.lead = b else: inc td.i return tdrError inc td.i if finish and td.lead != 0: td.lead = 0 return tdrError td.i = 0 tdrDone proc packState(buf: uint8; output: bool; state, outputState: uint8): uint32 = buf or (uint32(output) shl 8) or (uint32(state) shl 16) or (uint32(outputState) shl 24) const i2jsAscii = 0'u8 i2jsRoman = 1'u8 i2jsKatakana = 2'u8 i2jsLeadByte = 3'u8 i2jsTrailByte = 4'u8 i2jsEscapeStart = 5'u8 i2jsEscape = 6'u8 i2jsNull = 7'u8 proc decodeIso2022JP(td: var TextDecoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int; finish: bool): TextDecoderResult = let s = td.buf var buf = uint8(s and 0xFF) var output = ((s shr 8) and 0xFF) != 0 var state = uint8((s shr 16) and 0xFF) var outputState = uint8((s shr 24) and 0xFF) #TODO checking buf in every iteration is not really needed, only in the # first one. (it's only set before returning error) while (let i = td.i; buf != 0 or i < iq.len): template consume = if buf != 0: buf = 0 else: inc td.i let b = if buf != 0: buf else: iq[i] td.buf = packState(buf, output, state, outputState) case state of i2jsAscii: case b of 0x1B: state = i2jsEscapeStart of {0x00u8..0x7Fu8} - {0x0Eu8, 0x0Fu8, 0x1Bu8}: oq.try_put_byte b, n output = false else: output = false consume td.buf = packState(buf, output, state, outputState) return tdrError of i2jsRoman: case b of 0x1B: state = i2jsEscapeStart of 0x5C: oq.try_put_str "\u00A5", n # yen output = false of 0x7E: oq.try_put_str "\u203E", n # overline output = false of {0x00u8..0x7Fu8} - {0x0Eu8, 0x0Fu8, 0x1Bu8, 0x5Cu8, 0x7Eu8}: oq.try_put_byte b, n output = false else: output = false consume td.buf = packState(buf, output, state, outputState) return tdrError of i2jsKatakana: case b of 0x1B: state = i2jsEscapeStart of 0x21u8..0x5Fu8: oq.try_put_utf8 0xFF61u16 - 0x21 + uint16(b), n output = false else: output = false consume td.buf = packState(buf, output, state, outputState) return tdrError of i2jsLeadByte: case b of 0x1B: state = i2jsEscapeStart of 0x21u8..0x7Eu8: output = false td.lead = b state = i2jsTrailByte else: output = false consume td.buf = packState(buf, output, state, outputState) return tdrError of i2jsTrailByte: case b of 0x1B: state = i2jsEscapeStart consume td.buf = packState(buf, output, state, outputState) return tdrError of 0x21u8..0x7Eu8: let row = (uint16(td.lead) - 0x21) let col = uint16(b) - 0x21 if (let c = jis0208ToU16(row, col); c != 0): oq.try_put_utf8 c, n state = i2jsLeadByte else: state = i2jsLeadByte consume td.buf = packState(buf, output, state, outputState) return tdrError else: state = i2jsLeadByte consume td.buf = packState(buf, output, state, outputState) return tdrError of i2jsEscapeStart: if b == 0x24 or b == 0x28: td.lead = b state = i2jsEscape else: output = false state = outputState td.buf = packState(buf, output, state, outputState) # prepend (no inc i) return tdrError else: # i2jsEscape let l = td.lead td.lead = 0 # this is ok; we don't put anything in this state. let s = if l == 0x28: case b of 0x42: i2jsAscii of 0x4A: i2jsRoman of 0x49: i2jsKatakana else: i2jsNull elif b in {0x40u8, 0x42u8}: i2jsLeadByte else: i2jsNull if s != i2jsNull: state = s outputState = s consume if output: td.buf = packState(buf, output, state, outputState) return tdrError output = true continue td.buf = packState(l, false, outputState, outputState) # prepend (no inc i) return tdrError consume if finish: let l = td.lead td.lead = 0 td.buf = 0 case state of i2jsTrailByte, i2jsEscapeStart: return tdrError of i2jsEscape: # restore lead to the input queue td.buf = packState(l, false, outputState, outputState) return tdrError else: discard else: td.buf = packState(buf, output, state, outputState) td.i = 0 tdrDone proc decodeShiftJIS(td: var TextDecoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int; finish: bool): TextDecoderResult = while (let i = td.i; i < iq.len): let b = iq[i] let lead = td.lead if b < 0x80 and lead == 0: # ASCII oq.try_put_byte b, n inc td.i continue if lead != 0: let offset = if b < 0x7Fu8: 0x40u16 else: 0x41u16 let leadoffset = if lead < 0xA0: 0x81u16 else: 0xC1u16 if b in 0x40u8..0x7Eu8 or b in 0x80u8..0xFCu8: var row = (uint16(lead) - leadoffset) * 2 var col = uint16(b) - offset if col >= 94: col -= 94 inc row if 0x5E <= row and row < 0x72: oq.try_put_utf8 0xE000 - 8836 + row * 94 + col, n td.lead = 0 inc td.i continue elif (let c = jis0208ToU16(row, col); c != 0): oq.try_put_utf8 c, n td.lead = 0 else: td.lead = 0 if b >= 0x80: # prepend if ASCII (only inc if 8th bit of b is set) inc td.i return tdrError else: td.lead = 0 if b >= 0x80: # prepend if ASCII (only inc if 8th bit of b is set) inc td.i return tdrError elif b == 0x80: # not ASCII, but treat it the same oq.try_put_str "\u80", n elif b in 0xA1u8..0xDFu8: oq.try_put_utf8 0xFF61u16 - 0xA1 + uint16(b), n elif b in {0x81..0x9F} + {0xE0..0xFC}: td.lead = b else: inc td.i return tdrError inc td.i if finish and td.lead != 0: td.lead = 0 return tdrError td.i = 0 tdrDone proc eucKRToU16(row, col: uint16): uint16 = var col = col var row = row if row <= 0x1F: # runs 1 # Skip empty columns 0x1A..0x1F and 0x3A..0x3F if col >= 0x3A: if col <= 0x3F: return 0 col -= 12 elif col >= 0x1A: if col <= 0x1F: return 0 col -= 6 let p = row * 178 + col return EucKRRuns.findInRuns(EucKRRunsOffset, p) row -= 0x20 if col < 0x60: # runs 2 # Skip empty columns 0x1A..0x1F and 0x3A..0x3F if col >= 0x3A: if col <= 0x3F: return 0 col -= 12 elif col >= 0x1A: if col <= 0x1F: return 0 col -= 6 let p = row * 0x54 + col return EucKRRuns2.findInRuns(EucKRRunsOffset2, p) # bottom right quadrant col -= 0x60 let p = row * 94 + col if p < EucKRDecode.len: return EucKRDecode[p] return 0 proc decodeEucKR(td: var TextDecoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int; finish: bool): TextDecoderResult = while (let i = td.i; i < iq.len): let b = iq[i] let lead = td.lead if lead == 0 and b < 0x80: oq.try_put_utf8 b, n inc td.i continue if lead != 0: if b in 0x41u8..0xFEu8: let col = (uint16(b) - 0x41) let row = (uint16(lead) - 0x81) if (let c = eucKRToU16(row, col); c != 0): oq.try_put_utf8 c, n inc td.i td.lead = 0 continue td.lead = 0 if b >= 0x80: # prepend on ASCII inc td.i return tdrError elif b in {0x81u8..0xFEu8}: td.lead = b inc td.i else: inc td.i return tdrError if finish and td.lead != 0: td.lead = 0 return tdrError td.i = 0 tdrDone proc decodeUtf16(td: var TextDecoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int; be, finish: bool): TextDecoderResult = let shiftLead = uint16(be) * 8 let shiftTrail = uint16(not be) * 8 while (let i = td.i; i < iq.len): let s = td.buf if ((s shr 16) and 0xFF) == 0: # no lead yet; read it td.buf = s or 0x10000 td.lead = iq[i] inc td.i continue let lead = td.lead let cu = (uint16(lead) shl shiftLead) + uint16(iq[i]) shl shiftTrail if s != 0x10000: # has surrogate if unlikely(cu notin 0xDC00u16 .. 0xDFFFu16): td.buf = 0x10000 return tdrError let surr = uint32(s and 0xFFFF) let c = 0x10000 + ((surr - 0xD800) shl 10) + (uint32(cu) - 0xDC00) oq.try_put_utf8 c, n td.buf = 0 # clear lead, surrogate inc td.i continue if cu in 0xD800u16 .. 0xDBFFu16: td.buf = uint32(cu) # clear lead, set cu as surrogate inc td.i continue if unlikely(cu in 0xDC00u16 .. 0xDFFFu16): inc td.i td.buf = 0 # clear lead, no surrogate return tdrError oq.try_put_utf8 uint32(cu), n td.buf = 0 # clear lead, no surrogate inc td.i if finish: td.lead = 0 if td.buf != 0: td.buf = 0 return tdrError td.i = 0 tdrDone proc decodeXUserDefined(td: var TextDecoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int): TextDecoderResult = while (let i = td.i; i < iq.len): let b = iq[i] if b < 0x80: oq.try_put_byte b, n else: oq.try_put_utf8 0xF780 + uint32(b) - 0x80, n inc td.i td.i = 0 tdrDone proc decodeSingleByte(td: var TextDecoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int; map: openArray[uint16]): TextDecoderResult = while (let i = td.i; i < iq.len): let b = iq[i] if b < 0x80: oq.try_put_byte b, n elif int(b) - 0x80 < map.len: let p = map[int(b) - 0x80] if p == 0: inc td.i return tdrError oq.try_put_utf8 uint32(p), n else: inc td.i return tdrError inc td.i td.i = 0 tdrDone proc decodeReplacement(td: var TextDecoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int): TextDecoderResult = if td.buf == 0: td.buf = 1 return tdrError tdrDone proc decode*(td: var TextDecoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int; finish = false): TextDecoderResult = case td.charset #TODO maybe reuse unknown as BOM sniff? of csUnknown: tdrError of csUtf8: td.decodeUtf8(iq, oq, n, finish) of csGbk, csGb18030: td.decodeGb18030(iq, oq, n, finish) of csBig5: td.decodeBig5(iq, oq, n, finish) of csEucJP: td.decodeEucJP(iq, oq, n, finish) of csIso2022JP: td.decodeIso2022JP(iq, oq, n, finish) of csShiftJIS: td.decodeShiftJIS(iq, oq, n, finish) of csEucKR: td.decodeEucKR(iq, oq, n, finish) of csUtf16be: td.decodeUtf16(iq, oq, n, be = true, finish) of csUtf16le: td.decodeUtf16(iq, oq, n, be = false, finish) of csXUserDefined: td.decodeXUserDefined(iq, oq, n) of csReplacement: td.decodeReplacement(iq, oq, n) of csIbm866: td.decodeSingleByte(iq, oq, n, Ibm866Decode) of csIso8859_2: td.decodeSingleByte(iq, oq, n, Iso8859_2Decode) of csIso8859_3: td.decodeSingleByte(iq, oq, n, Iso8859_3Decode) of csIso8859_4: td.decodeSingleByte(iq, oq, n, Iso8859_4Decode) of csIso8859_5: td.decodeSingleByte(iq, oq, n, Iso8859_5Decode) of csIso8859_6: td.decodeSingleByte(iq, oq, n, Iso8859_6Decode) of csIso8859_7: td.decodeSingleByte(iq, oq, n, Iso8859_7Decode) of csIso8859_8, csIso8859_8i: td.decodeSingleByte(iq, oq, n, Iso8859_8Decode) of csIso8859_10: td.decodeSingleByte(iq, oq, n, Iso8859_10Decode) of csIso8859_13: td.decodeSingleByte(iq, oq, n, Iso8859_13Decode) of csIso8859_14: td.decodeSingleByte(iq, oq, n, Iso8859_14Decode) of csIso8859_15: td.decodeSingleByte(iq, oq, n, Iso8859_15Decode) of csIso8859_16: td.decodeSingleByte(iq, oq, n, Iso8859_16Decode) of csKoi8r: td.decodeSingleByte(iq, oq, n, Koi8rDecode) of csKoi8u: td.decodeSingleByte(iq, oq, n, Koi8uDecode) of csMacintosh: td.decodeSingleByte(iq, oq, n, MacintoshDecode) of csWindows874: td.decodeSingleByte(iq, oq, n, Windows874Decode) of csWindows1250: td.decodeSingleByte(iq, oq, n, Windows1250Decode) of csWindows1251: td.decodeSingleByte(iq, oq, n, Windows1251Decode) of csWindows1252: td.decodeSingleByte(iq, oq, n, Windows1252Decode) of csWindows1253: td.decodeSingleByte(iq, oq, n, Windows1253Decode) of csWindows1254: td.decodeSingleByte(iq, oq, n, Windows1254Decode) of csWindows1255: td.decodeSingleByte(iq, oq, n, Windows1255Decode) of csWindows1256: td.decodeSingleByte(iq, oq, n, Windows1256Decode) of csWindows1257: td.decodeSingleByte(iq, oq, n, Windows1257Decode) of csWindows1258: td.decodeSingleByte(iq, oq, n, Windows1258Decode) of csXMacCyrillic: td.decodeSingleByte(iq, oq, n, XMacCyrillicDecode) {.pop.} ���������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/encoding/encoder.nim��������������������������������������������������������������0000664�0000000�0000000�00000003421�15202323131�0017633�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import charset import encodercore type EncoderErrorMode* = enum eemFatal, eemHtml proc initTextEncoder*(charset: Charset): TextEncoder = ## Create a new TextEncoder instance from the charset. ## Note: UTF-8 and UTF-16 encoders are not supported. ## (For UTF-8, use a TextDecoder instead.) assert charset notin {csUtf8, csUtf16be, csUtf16le, csReplacement, csUnknown} TextEncoder(charset: charset) proc encodeAll*(iq: openArray[uint8]; charset: Charset; success: var bool): string = result = newString(iq.len) var te = initTextEncoder(charset) var n = 0 while true: case te.encode(iq, result.toOpenArrayByte(0, result.high), n, finish = true) of terDone: result.setLen(n) break of terReqOutput: result.setLen(result.len * 2) of terError: success = false return "" success = true proc encodeAll*(iq: openArray[char]; charset: Charset; success: var bool): string = success = false return iq.toOpenArrayByte(0, iq.high).encodeAll(charset, success) proc encodeAll*(iq: openArray[uint8]; charset: Charset): string = result = newString(iq.len) var te = initTextEncoder(charset) var n = 0 while true: case te.encode(iq, result.toOpenArrayByte(0, result.high), n, finish = true) of terDone: result.setLen(n) break of terReqOutput: result.setLen(result.len * 2) of terError: result.setLen(n) result &= "&#" if te.c == 0: result &= '0' else: while te.c > 0: result &= char(uint8('0') + uint8(te.c mod 10)) te.c = te.c div 10 result &= ';' n = result.len proc encodeAll*(iq: openArray[char]; charset: Charset): string = return iq.toOpenArrayByte(0, iq.high).encodeAll(charset) {.pop.} �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/encoding/encodercore.nim����������������������������������������������������������0000664�0000000�0000000�00000044206�15202323131�0020512�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������## TextEncoder encodes valid UTF-8 (or WTF-8) byte sequences to non-UTF-8 ## encodings, in accordance with the WHATWG ## [encoding standard](https://encoding.spec.whatwg.org/). ## ## This is a low-level interface; you may also be interested in ## [encoder](encoder.html), which provides useful wrapper procedures. ## ## To encode a stream, sequentially call `encode` on any number of chunks ## with `finish = false`, then with `finish = true` on the last chunk. ## If you don't know which chunk is the last, use an empty chunk. ## ## (`finish` only has a significance for the ISO-2022-JP encoder, which ## is specified to emit a sequence at the end of the queue to reset the ## decoder state to ASCII.) ## ## The input stream **must** be valid UTF-8, with the exception that ## (invalid) surrogate codepoints are automagically replaced with ## replacement characters. So if std/unicode's `validateUtf8` returns -1 ## on a buffer, it is safe to feed it to `TextEncoder`. ## ## `encode` expects an input queue `iq`, an output queue `oq`, and an index ## in the output queue `n`. Output is placed in the output queue starting ## from `n`. `encode` may either return `terDone`, `terReqOutput`, or ## `terError`. ## ## `terDone` means the entire input buffer has been successfully encoded; ## the output can be found in `oq`, and the number of bytes output is ## stored in `n`. ## ## `terReqOutput` is a request for more output space to decode the current ## buffer. Users may handle this by processing the contents of `oq` until ## `n`, resetting `n` to 0, then calling `encode` on the same input queue ## `iq` again. ## ## `terError` represents an error with a specific code point, as specified ## by the standard. Per spec, implementations should handle this either ## by immediately aborting the encoding process (error mode "fatal"), or ## outputting a decimal representation of the code point stored in the ## `TextEncoder` object's `c` member as an HTML reference (error mode ## "html"). For an example, see [encoder](encoder.html)'s source code. {.push raises: [].} import std/algorithm import charset import charset_map type TextEncoderResult* = enum terDone, terReqOutput, terError Iso2022JPState* = enum i2jsAscii, i2jsRoman, i2jsJis0208 TextEncoder* = object i*: int c*: uint32 charset*: Charset state*: Iso2022JPState proc gb18030RangesPointer(c: uint32): uint32 = if c == 0xE7C7: return 7457 # Let offset be the last pointer in index gb18030 ranges that is less than or # equal to pointer and code point offset its corresponding code point. var offset: uint32 var p: uint32 if c >= 0x10000: # omitted from the map for storage efficiency offset = 0x10000 p = 189000 elif c >= 0xFFE6: # Needed because upperBound returns the first element greater than pointer # OR last on failure, so we can't just remove one if p is e.g. 39400. offset = 0xFFE6 p = 39394 else: # Find the first range that is greater than p, or last if no such element # is found. # We want the last that is <=, so decrease index by one. let i = GB18030Ranges.upperBound(c, proc(a: UCS16x16; b: uint32): int = cmp(uint32(a.ucs), b) ) let elem = GB18030Ranges[i - 1] offset = elem.ucs p = elem.p return p + c - offset proc findPair(map: openArray[UCS16x16]; u: uint16): int = return map.binarySearch(u, proc(x: UCS16x16; y: uint16): int = cmp(x[0], y)) proc findPair16(map: openArray[UCS16x16]; u: uint32): int = if u > uint16.high: return -1 let u = uint16(u) return map.binarySearch(u, proc(x: UCS16x16; y: uint16): int = cmp(x[0], y)) proc findRun(runs: openArray[uint32]; offset, ic: uint16): uint16 = let i = runs.upperBound(ic, proc(x: uint32; y: uint16): int = let op = x and 0x1FFF # this is the pointer let diff = (x shr 13) and 0xFFF # difference between op and the point let ucs = offset + op + diff # UCS return cmp(ucs, y) ) let x = runs[i - 1] let op = x and 0x1FFF # this is the pointer let diff = (x shr 13) and 0xFFF # difference between op and the point let ucs = offset + op + diff # UCS let len = x shr 25 if ucs <= ic and ic < ucs + len: return uint16(ic - offset - diff + 1) return 0 template try_put_byte(oq: var openArray[uint8]; b: uint8; n: var int) = if n >= oq.len: return terReqOutput oq[n] = b inc n template try_put_bytes(oq: var openArray[uint8]; bs: openArray[uint8]; n: var int) = if n + bs.len > oq.len: return terReqOutput for i in 0 ..< bs.len: oq[n] = bs[i] inc n # returns the consumed character's length in bytes template try_get_utf8(te: TextEncoder; iq: openArray[uint8]; b: uint8): int = if b shr 5 == 0x6: if te.i + 1 >= iq.len: return terReqOutput te.c = (uint32(b and 0x1F) shl 6) or (iq[te.i + 1] and 0x3F) 2 elif b shr 4 == 0xE: if te.i + 2 >= iq.len: return terReqOutput let c = (uint32(b and 0xF) shl 12) or (uint32(iq[te.i + 1] and 0x3F) shl 6) or (iq[te.i + 2] and 0x3F) if likely((c shr 11) != 0x1B): # valid (probably) te.c = c 3 else: # surrogate te.c = 0xFFFD 1 elif b shr 3 == 0x1E: if te.i + 3 >= iq.len: return terReqOutput te.c = (uint32(b and 0x7) shl 18) or (uint32(iq[te.i + 1] and 0x3F) shl 12) or (uint32(iq[te.i + 2] and 0x3F) shl 6) or (iq[te.i + 3] and 0x3F) 4 else: te.c = 0xFFFD # invalid 1 proc encodeGb18030(te: var TextEncoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int; isGBK: bool): TextEncoderResult = while te.i < iq.len: let b = iq[te.i] if b < 0x80: oq.try_put_byte b, n inc te.i continue let cl = te.try_get_utf8(iq, b) let c = te.c const NewTable2024Part2 = [ 0xE81Eu16, 0xE826, 0xE82B, 0xE82C, 0xE832, 0xE843, 0xE854, 0xE864 ] if isGBK and c == 0x20AC: oq.try_put_byte 0x80, n te.i += cl continue if c >= 0x4E02 and c <= 0x72DB and (let p0 = GB18030Runs.findRun(GB18030RunsOffset, uint16(c)); p0 != 0): let p = p0 - 1 let lead = p div 190 + 0x81 let trail = p mod 190 let offset = if trail < 0x3F: 0x40u8 else: 0x41u8 oq.try_put_bytes [uint8(lead), uint8(trail) + offset], n elif c >= 0x72DC and c <= 0x9F31 and (let p0 = GB18030Runs2.findRun(GB18030RunsOffset2, uint16(c)); p0 != 0): let p = p0 - 1 let lead = p div 96 + 0xAA let trail = p mod 96 let offset = if trail < 0x3F: 0x40u8 else: 0x41u8 oq.try_put_bytes [uint8(lead), uint8(trail) + offset], n elif c >= 0xE78D and c <= 0xE796: # new table of 2024 part 1 var b = c - 0xE78D + 0xD9 if b > 0xDF: b += 12 if b == 0xEE: b = 0xF3 oq.try_put_bytes [0xA6u8, uint8(b)], n elif c <= 0xE864 and uint16(c) in NewTable2024Part2: var b = c - 0xE81E + 0x59 if b > 0x7E: inc b oq.try_put_bytes [0xFEu8, uint8(b)], n elif (let i = GB18030Encode.findPair16(c); i != -1): let p = GB18030Encode[i].p let lead = p div 190 + 0x81 let trail = p mod 190 let offset = if trail < 0x3F: 0x40u8 else: 0x41u8 oq.try_put_bytes [uint8(lead), uint8(trail) + offset], n elif isGBK: te.i += cl return terError else: var p = gb18030RangesPointer(c) let b1 = p div (10 * 126 * 10) p = p mod (10 * 126 * 10) let b2 = p div (10 * 126) p = p mod (10 * 126) let b3 = p div 10 let b4 = p mod 10 let b1b = uint8(b1 + 0x81) let b2b = uint8(b2 + 0x30) let b3b = uint8(b3 + 0x81) let b4b = uint8(b4 + 0x30) oq.try_put_bytes [b1b, b2b, b3b, b4b], n te.i += cl te.i = 0 terDone proc encodeBig5(te: var TextEncoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int): TextEncoderResult = while te.i < iq.len: let b = iq[te.i] if b < 0x80: oq.try_put_byte b, n inc te.i continue let cl = te.try_get_utf8(iq, b) let c = te.c let p = if c <= uint16.high: let i = Big5EncodeLow.findPair(uint16(c)) if i == -1: te.i += cl return terError Big5EncodeLow[i].p else: let i = Big5EncodeHigh.findPair(uint16(c - 0x20000)) if i == -1: te.i += cl return terError Big5EncodeHigh[i].p let lead = p div 157 + 0x81 let trail = p mod 157 let offset = if trail < 0x3F: 0x40u8 else: 0x62u8 oq.try_put_bytes [uint8(lead), uint8(trail) + offset], n te.i += cl te.i = 0 terDone proc ucsToJis0208(c: uint16): uint16 = if (let i = Jis0208Encode.findPair16(c); i != -1): return Jis0208Encode[i].p + 1 return 0 proc encodeEucJP(te: var TextEncoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int): TextEncoderResult = while te.i < iq.len: let b = iq[te.i] if b < 0x80: oq.try_put_byte b, n inc te.i continue let cl = te.try_get_utf8(iq, b) var c = te.c if c == 0xA5: oq.try_put_byte 0x5C, n elif c == 0x203E: oq.try_put_byte 0x7E, n elif c in 0xFF61u32..0xFF9Fu32: oq.try_put_bytes [0x8Eu8, uint8(c - 0xFF61 + 0xA1)], n elif c < uint16.high and (let p0 = ucsToJis0208(uint16(c)); p0 != 0): let p = p0 - 1 let lead = p div 94 + 0xA1 let trail = p mod 94 + 0xA1 oq.try_put_bytes [uint8(lead), uint8(trail)], n else: te.i += cl return terError te.i += cl te.i = 0 terDone proc ucsToIso2022JP(c: uint16): uint16 = var c = c if c in 0xFF61'u32..0xFF9F'u32: c = uint16(Iso2022JPKatakanaMap[c - 0xFF61]) + 0x3000 return ucsToJis0208(c) proc encodeIso2022JP(te: var TextEncoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int; finish: bool): TextEncoderResult = while te.i < iq.len: let b = iq[te.i] if b < 0x80: # ASCII if te.state in {i2jsAscii, i2jsRoman} and b in {0x0Eu8, 0x0Fu8, 0x1Bu8}: te.c = 0xFFFD # note: this returns replacement intentionally inc te.i return terError if te.state == i2jsRoman and b notin {0x5Cu8, 0x7Eu8}: oq.try_put_byte b, n inc te.i continue if te.state == i2jsAscii: oq.try_put_byte b, n inc te.i continue oq.try_put_bytes [0x1Bu8, 0x28u8, 0x42u8], n te.state = i2jsAscii # prepend (no inc i) continue let cl = te.try_get_utf8(iq, b) let c = te.c if te.state == i2jsRoman and c == 0xA5: oq.try_put_byte 0x5C, n elif te.state == i2jsRoman and c == 0x203E: oq.try_put_byte 0x7E, n elif te.state != i2jsRoman and (c == 0xA5 or c == 0x203E): oq.try_put_bytes [0x1B'u8, 0x28'u8, 0x4A'u8], n te.state = i2jsRoman # prepend (no inc i) continue elif c < uint16.high and (let p0 = ucsToIso2022JP(uint16(c)); p0 != 0): let p = p0 - 1 if te.state != i2jsJis0208: oq.try_put_bytes [0x1B'u8, 0x24'u8, 0x42'u8], n te.state = i2jsJis0208 # prepend (no inc i) continue let lead = p div 94 + 0x21 let trail = p mod 94 + 0x21 oq.try_put_bytes [uint8(lead), uint8(trail)], n else: # pointer is null if te.state == i2jsJis0208: oq.try_put_bytes [0x1B'u8, 0x28'u8, 0x42'u8], n te.state = i2jsAscii # prepend (no inc i) continue te.i += cl return terError te.i += cl if finish and te.state != i2jsAscii: # reset state at end of queue oq.try_put_bytes [0x1B'u8, 0x28'u8, 0x42'u8], n te.state = i2jsAscii te.i = 0 terDone proc ucsToSJIS(c: uint16): uint16 = if (let i = ShiftJISEncode.findPair16(c); i != -1): return ShiftJISEncode[i].p + 1 return ucsToJis0208(c) proc encodeShiftJIS(te: var TextEncoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int): TextEncoderResult = while te.i < iq.len: let b = iq[te.i] if b < 0x80: oq.try_put_byte b, n inc te.i continue let cl = te.try_get_utf8(iq, b) let c = te.c if c == 0xA5: oq.try_put_byte 0x5C, n elif c == 0x203E: oq.try_put_byte 0x7E, n elif c in 0xFF61u32..0xFF9Fu32: oq.try_put_byte uint8(c - 0xFF61 + 0xA1), n elif c < uint16.high and (let p0 = ucsToSJIS(uint16(c)); p0 != 0): let p = p0 - 1 let lead = uint8(p div 188) let lead_offset = if lead < 0x1F: 0x81u8 else: 0xC1u8 let trail = uint8(p mod 188) let offset = if trail < 0x3F: 0x40u8 else: 0x41u8 oq.try_put_bytes [lead + lead_offset, trail + offset], n else: te.i += cl return terError te.i += cl te.i = 0 terDone proc encodeEucKR(te: var TextEncoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int): TextEncoderResult = while te.i < iq.len: let b = iq[te.i] if b < 0x80: oq.try_put_byte b, n inc te.i continue let cl = te.try_get_utf8(iq, b) let c = te.c if c >= 0xAC02 and c <= 0xC8A4 and (let p0 = EucKRRuns.findRun(EucKRRunsOffset, uint16(c)); p0 != 0): let p = p0 - 1 let row = p div 178 var col = p mod 178 if col >= 0x34: col += 12 elif col >= 0x1A: col += 6 let lead = row + 0x81 let trail = col + 0x41 oq.try_put_bytes [uint8(lead), uint8(trail)], n elif c >= 0xC8A5 and c <= 0xD7A3 and (let p0 = EucKRRuns2.findRun(EucKRRunsOffset2, uint16(c)); p0 != 0): let p = p0 - 1 let row = p div 84 + 32 var col = p mod 84 if col >= 0x34: col += 12 elif col >= 0x1A: col += 6 let lead = row + 0x81 let trail = col + 0x41 oq.try_put_bytes [uint8(lead), uint8(trail)], n elif (let i = EucKREncode.findPair16(c); i != -1): let p = EucKREncode[i].p let lead = p div 190 + 0x81 let trail = p mod 190 + 0x41 oq.try_put_bytes [uint8(lead), uint8(trail)], n else: te.i += cl return terError te.i += cl te.i = 0 terDone proc encodeXUserDefined(te: var TextEncoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int): TextEncoderResult = while te.i < iq.len: let b = iq[te.i] if b < 0x80: oq.try_put_byte b, n inc te.i continue let cl = te.try_get_utf8(iq, b) let c = te.c if c in 0xF780u32..0xF7FFu32: oq.try_put_byte uint8(c - 0xF780 + 0x80), n te.i += cl continue te.i += cl return terError te.i = 0 terDone proc encodeSingleByte(te: var TextEncoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int; decode: openArray[uint16]; encode: tuple[start, len: uint8; offset: uint16]): TextEncoderResult = while te.i < iq.len: let b = iq[te.i] if b < 0x80: oq.try_put_byte b, n inc te.i continue let cl = te.try_get_utf8(iq, b) if te.c > uint32(uint16.high): te.i += cl return terError let c = uint16(te.c) let runc = c - encode.offset var found = 0'u8 if runc < uint16(encode.len): found = 128 + encode.start + uint8(runc) else: block search: for u in 0'u8 ..< encode.start: if decode[u] == c: found = 128 + u break search for u in int(encode.start + encode.len) .. decode.high: if decode[u] == c: found = 128 + uint8(u) break search te.i += cl return terError oq.try_put_byte found, n te.i += cl te.i = 0 terDone proc encode*(te: var TextEncoder; iq: openArray[uint8]; oq: var openArray[uint8]; n: var int; finish = false): TextEncoderResult = case te.charset of csUnknown, csUtf8, csUtf16le, csUtf16be, csReplacement: terError of csGbk: te.encodeGb18030(iq, oq, n, isGBK = true) of csGb18030: te.encodeGb18030(iq, oq, n, isGBK = false) of csBig5: te.encodeBig5(iq, oq, n) of csEucJP: te.encodeEucJP(iq, oq, n) of csIso2022JP: te.encodeIso2022JP(iq, oq, n, finish) of csShiftJIS: te.encodeShiftJIS(iq, oq, n) of csEucKR: te.encodeEucKR(iq, oq, n) of csXUserDefined: te.encodeXUserDefined(iq, oq, n) of csIbm866: te.encodeSingleByte(iq, oq, n, Ibm866Decode, Ibm866Encode) of csIso8859_2: te.encodeSingleByte(iq, oq, n, Iso8859_2Decode, Iso8859_2Encode) of csIso8859_3: te.encodeSingleByte(iq, oq, n, Iso8859_3Decode, Iso8859_3Encode) of csIso8859_4: te.encodeSingleByte(iq, oq, n, Iso8859_4Decode, Iso8859_4Encode) of csIso8859_5: te.encodeSingleByte(iq, oq, n, Iso8859_5Decode, Iso8859_5Encode) of csIso8859_6: te.encodeSingleByte(iq, oq, n, Iso8859_6Decode, Iso8859_6Encode) of csIso8859_7: te.encodeSingleByte(iq, oq, n, Iso8859_7Decode, Iso8859_7Encode) of csIso8859_8, csIso8859_8i: te.encodeSingleByte(iq, oq, n, Iso8859_8Decode, Iso8859_8Encode) of csIso8859_10: te.encodeSingleByte(iq, oq, n, Iso8859_10Decode, Iso8859_10Encode) of csIso8859_13: te.encodeSingleByte(iq, oq, n, Iso8859_13Decode, Iso8859_13Encode) of csIso8859_14: te.encodeSingleByte(iq, oq, n, Iso8859_14Decode, Iso8859_14Encode) of csIso8859_15: te.encodeSingleByte(iq, oq, n, Iso8859_15Decode, Iso8859_15Encode) of csIso8859_16: te.encodeSingleByte(iq, oq, n, Iso8859_16Decode, Iso8859_16Encode) of csKoi8r: te.encodeSingleByte(iq, oq, n, Koi8rDecode, Koi8rEncode) of csKoi8u: te.encodeSingleByte(iq, oq, n, Koi8uDecode, Koi8uEncode) of csMacintosh: te.encodeSingleByte(iq, oq, n, MacintoshDecode, MacintoshEncode) of csWindows874: te.encodeSingleByte(iq, oq, n, Windows874Decode, Windows874Encode) of csWindows1250: te.encodeSingleByte(iq, oq, n, Windows1250Decode, Windows1250Encode) of csWindows1251: te.encodeSingleByte(iq, oq, n, Windows1251Decode, Windows1251Encode) of csWindows1252: te.encodeSingleByte(iq, oq, n, Windows1252Decode, Windows1252Encode) of csWindows1253: te.encodeSingleByte(iq, oq, n, Windows1253Decode, Windows1253Encode) of csWindows1254: te.encodeSingleByte(iq, oq, n, Windows1254Decode, Windows1254Encode) of csWindows1255: te.encodeSingleByte(iq, oq, n, Windows1255Decode, Windows1255Encode) of csWindows1256: te.encodeSingleByte(iq, oq, n, Windows1256Decode, Windows1256Encode) of csWindows1257: te.encodeSingleByte(iq, oq, n, Windows1257Decode, Windows1257Encode) of csWindows1258: te.encodeSingleByte(iq, oq, n, Windows1258Decode, Windows1258Encode) of csXMacCyrillic: te.encodeSingleByte(iq, oq, n, XMacCyrillicDecode, XMacCyrillicEncode) {.pop.} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/html/�����������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0014665�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/html/catom.nim��������������������������������������������������������������������0000664�0000000�0000000�00000031506�15202323131�0016502�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# String interning. # Currently, interned strings do not have a reference count, so it is # best to use them cautiously (as they technically leak memory). # This could be changed if we switched to ORC, but ORC is still utterly # broken in the latest version. What can you do... # (If this turns out to be an issue in practice, we can always turn # atoms into ref objects; that would work with refc, but it would also # add a lot of overhead.) import std/hashes import std/macros import std/sets import chame/tags import monoucha/fromjs import monoucha/quickjs import monoucha/tojs import types/jsopt import utils/twtstr # create a static enum compatible with chame/tags macro makeStaticAtom = # declare inside the macro to avoid confusion with StaticAtom0 type StaticAtom0 = enum satAbort = "abort" satAccept = "accept" satAcceptCharset = "accept-charset" satAction = "action" satAlign = "align" satAlink = "alink" satAlt = "alt" satAlternate = "alternate" satAnonymous = "anonymous" satApplicationXml = "application/xml" satApplicationXmlHtml = "application/xml+html" satAsync = "async" satAutofocus = "autofocus" satAxis = "axis" satBgcolor = "bgcolor" satBlocking = "blocking" satBlur = "blur" satBorder = "border" satCellspacing = "cellspacing" satChange = "change" satCharset = "charset" satChecked = "checked" satClass = "class" satClassName = "className" satClear = "clear" satClick = "click" satCodetype = "codetype" satColor = "color" satColorDashProfile = "color-profile" satCols = "cols" satColspan = "colspan" satCompact = "compact" satContent = "content" satContextmenu = "contextmenu" satCrossorigin = "crossorigin" satCustomevent = "customevent" satDOMContentLoaded = "DOMContentLoaded" satDashChaHintCounter = "-cha-hint-counter" satDashChaLinkCounter = "-cha-link-counter" satDatetime = "datetime" satDblclick = "dblclick" satDeclare = "declare" satDefaultSelected = "defaultSelected" satDefer = "defer" satDirection = "direction" satDirname = "dirname" satDisabled = "disabled" satEnctype = "enctype" satError = "error" satEvent = "event" satEvents = "events" satFocus = "focus" satFontDashFace = "font-face" satFontDashFaceDashFormat = "font-face-format" satFontDashFaceDashName = "font-face-name" satFontDashFaceDashSrc = "font-face-src" satFontDashFaceDashUri = "font-face-uri" satFor = "for" satForm = "form" satFormaction = "formaction" satFormenctype = "formenctype" satFormmethod = "formmethod" satHCrossOrigin = "crossOrigin" satHDateTime = "dateTime" satHFormMethod = "formMethod" satHHttpEquiv = "httpEquiv" satHIsMap = "isMap" satHNoValidate = "noValidate" satHReferrerPolicy = "referrerPolicy" satHUseMap = "useMap" satHash = "hash" satHeight = "height" satHost = "host" satHostname = "hostname" satHref = "href" satHreflang = "hreflang" satHtmlFor = "htmlFor" satHtmlevents = "htmlevents" satId = "id" satImageSvgXml = "image/svg+xml" satIntegrity = "integrity" satIsmap = "ismap" satLang = "lang" satLanguage = "language" satListItem = "list-item" satLoad = "load" satLoadend = "loadend" satLoadstart = "loadstart" satMax = "max" satMedia = "media" satMessage = "message" satMethod = "method" satMin = "min" satMissingDashGlyph = "missing-glyph" satMouseevent = "mouseevent" satMouseevents = "mouseevents" satMousewheel = "mousewheel" satMultiple = "multiple" satName = "name" satNamespaceHTML = "http://www.w3.org/1999/xhtml", satNamespaceMathML = "http://www.w3.org/1998/Math/MathML", satNamespaceSVG = "http://www.w3.org/2000/svg", satNamespaceXLink = "http://www.w3.org/1999/xlink", satNamespaceXML = "http://www.w3.org/XML/1998/namespace", satNamespaceXMLNS = "http://www.w3.org/2000/xmlns/", satNohref = "nohref" satNomodule = "nomodule" satNoresize = "noresize" satNoshade = "noshade" satNovalidate = "novalidate" satNowrap = "nowrap" satOnblur = "onblur" satOnchange = "onchange" satOnclick = "onclick" satOncontextmenu = "oncontextmenu" satOndblclick = "ondblclick" satOnerror = "onerror" satOnfocus = "onfocus" satOninput = "oninput" satOnload = "onload" satOnsubmit = "onsubmit" satOpen = "open" satOrigin = "origin" satPassword = "password" satPathname = "pathname" satPort = "port" satProgress = "progress" satProtocol = "protocol" satReadonly = "readonly" satReadystatechange = "readystatechange" satReferrerpolicy = "referrerpolicy" satRel = "rel" satRequired = "required" satRev = "rev" satRows = "rows" satRowspan = "rowspan" satRules = "rules" satScope = "scope" satScrolling = "scrolling" satSearch = "search" satSelected = "selected" satShape = "shape" satSize = "size" satSizes = "sizes" satSlot = "slot" satSrc = "src" satSrcset = "srcset" satStart = "start" satStyle = "style" satStylesheet = "stylesheet" satSubmit = "submit" satSvgevents = "svgevents" satTarget = "target" satText = "text" satTextHtml = "text/html" satTimeout = "timeout" satTitle = "title" satToString = "toString" satTouchmove = "touchmove" satTouchstart = "touchstart" satType = "type" satUempty = "" satUievent = "uievent" satUievents = "uievents" satUsemap = "usemap" satUsername = "username" satValign = "valign" satValue = "value" satValuetype = "valuetype" satVlink = "vlink" satWheel = "wheel" satWidth = "width" satXlink = "xlink" satXml = "xml" satXmlns = "xmlns" let decl = quote do: type StaticAtom* {.inject.} = enum satUnknown = "" let decl0 = decl[0][2] var seen = HashSet[string].default for t in TagType: if t == TAG_UNKNOWN: continue let tn = $t let name = "sat" & tn[0].toUpperAscii() & tn.substr(1).kebabToCamelCase() seen.incl(tn) decl0.add(newNimNode(nnkEnumFieldDef).add(ident(name), newStrLitNode(tn))) for i, f in StaticAtom0.getType(): if i == 0: continue let tn = $StaticAtom0(i - 1) if tn in seen: continue decl0.add(newNimNode(nnkEnumFieldDef).add(ident(f.strVal), newStrLitNode(tn))) decl makeStaticAtom const CAtomFactoryStrMapLength = 2048 # must be a power of 2 static: doAssert (CAtomFactoryStrMapLength and (CAtomFactoryStrMapLength - 1)) == 0 type CAtom* = distinct uint32 CAtomFactoryObj = object strMap: array[CAtomFactoryStrMapLength, seq[CAtom]] atomMap: seq[string] lowerMap: seq[CAtom] CAtomFactory = ptr CAtomFactoryObj # This maps to JS null. const CAtomNull* = CAtom(0) # Mandatory Atom functions proc `==`*(a, b: CAtom): bool {.borrow.} proc hash*(atom: CAtom): Hash {.borrow.} proc toAtom(factory: var CAtomFactoryObj; s: openArray[char]; addLower = true): CAtom = let h = s.hash() let i = h and (factory.strMap.len - 1) for atom in factory.strMap[i]: if factory.atomMap[int(atom)] == s: # Found return atom # Not found let atom = CAtom(factory.atomMap.len) var ss = newString(s.len) if s.len > 0: copyMem(addr ss[0], unsafeAddr s[0], s.len) var lower = "" if addLower and AsciiUpperAlpha in ss: lower = ss.toLowerAscii() factory.atomMap.add(move(ss)) if addLower: if lower == "": factory.lowerMap.add(atom) else: factory.lowerMap.add(factory.toAtom(lower)) factory.strMap[i].add(atom) return atom var factory {.global.}: CAtomFactoryObj template getFactory(): CAtomFactory = addr factory proc initCAtomFactory*() = # Null atom factory.atomMap.add("") factory.lowerMap.add(CAtom(0)) # StaticAtom includes TagType too. for sa in StaticAtom(1) .. StaticAtom.high: discard factory.toAtom($sa, addLower = false) for sa in StaticAtom(1) .. StaticAtom.high: let atom = factory.toAtom(($sa).toLowerAscii(), addLower = false) factory.lowerMap.add(atom) # fill slots of newly added lower mappings while factory.lowerMap.len < factory.atomMap.len: factory.lowerMap.add(CAtom(factory.lowerMap.len)) proc toLowerAscii*(a: CAtom): CAtom = return getFactory().lowerMap[int32(a)] proc equalsIgnoreCase*(a, b: CAtom): bool = return getFactory().lowerMap[int32(a)] == getFactory().lowerMap[int32(b)] proc containsIgnoreCase*(aa: openArray[CAtom]; a: CAtom): bool = let a = a.toLowerAscii() for it in aa: if a == it.toLowerAscii(): return true return false proc toAtom*(s: openArray[char]): CAtom = return getFactory()[].toAtom(s) proc toAtom*(tagType: TagType): CAtom = assert tagType != TAG_UNKNOWN return CAtom(tagType) proc toAtom*(attrType: StaticAtom): CAtom = assert attrType != satUnknown return CAtom(attrType) proc toAtomLower*(s: openArray[char]): CAtom = return getFactory().lowerMap[int32(s.toAtom())] proc containsIgnoreCase*(aa: openArray[CAtom]; a: StaticAtom): bool = return aa.containsIgnoreCase(a.toAtom()) proc `$`*(atom: CAtom): lent string = return getFactory().atomMap[int(atom)] proc toTagType*(atom: CAtom): TagType = let i = int(atom) if i <= int(TagType.high): return TagType(i) return TAG_UNKNOWN proc toStaticAtom*(atom: CAtom): StaticAtom = let i = int(atom) if i <= int(StaticAtom.high): return StaticAtom(i) return satUnknown proc toStaticAtom*(s: string): StaticAtom = let factory = getFactory() let h = s.hash() let i = h and (factory.strMap.len - 1) for atom in factory.strMap[i]: if factory.atomMap[int(atom)] == s: # Found return atom.toStaticAtom() satUnknown proc toNamespace*(atom: CAtom): Namespace = case atom.toStaticAtom() of satUempty: return NO_NAMESPACE of satNamespaceHTML: return Namespace.HTML of satNamespaceMathML: return Namespace.MATHML of satNamespaceSVG: return Namespace.SVG of satNamespaceXLink: return Namespace.XLINK of satNamespaceXML: return Namespace.XML of satNamespaceXMLNS: return Namespace.XMLNS else: return NAMESPACE_UNKNOWN proc toAtom*(namespace: Namespace): CAtom = return (case namespace of NO_NAMESPACE: satUempty of Namespace.HTML: satNamespaceHTML of Namespace.MATHML: satNamespaceMathML of Namespace.SVG: satNamespaceSVG of Namespace.XLINK: satNamespaceXLink of Namespace.XML: satNamespaceXML of Namespace.XMLNS: satNamespaceXMLNS of NAMESPACE_UNKNOWN: satUempty).toAtom() proc toAtom*(prefix: NamespacePrefix): CAtom = return (case prefix of NO_PREFIX: satUempty of PREFIX_XLINK: satXlink of PREFIX_XML: satXml of PREFIX_XMLNS: satXmlns of PREFIX_UNKNOWN: satUempty).toAtom() proc `==`*(a: CAtom; b: StaticAtom): bool = a.toStaticAtom() == b proc `==`*(a: StaticAtom; b: CAtom): bool = a == b.toStaticAtom() proc contains*(a: openArray[CAtom]; b: StaticAtom): bool = b.toAtom() in a proc contains*(a: openArray[StaticAtom]; b: CAtom): bool = b.toStaticAtom() in a proc fromJS*(ctx: JSContext; val: JSValueConst; res: var CAtom): FromJSResult = if JS_IsNull(val): res = CAtomNull else: var len: csize_t let cs = JS_ToCStringLen(ctx, len, val) if cs == nil: return fjErr if len > csize_t(int.high): JS_FreeCString(ctx, cs) JS_ThrowRangeError(ctx, "string length out of bounds") return fjErr {.push overflowChecks: off.} let H = cast[int](len) - 1 {.pop.} res = cs.toOpenArray(0, H).toAtom() JS_FreeCString(ctx, cs) fjOk proc fromJS*(ctx: JSContext; val: JSAtom; res: var CAtom): FromJSResult = if val == JS_ATOM_NULL: res = CAtomNull else: var s: string ?ctx.fromJS(val, s) res = s.toAtom() fjOk proc fromJS*(ctx: JSContext; val: JSAtom; res: var StaticAtom): FromJSResult = var ca: CAtom ?ctx.fromJS(val, ca) res = ca.toStaticAtom() fjOk type FromIdxResult* = enum fiIdx, fiStr, fiErr proc fromIdx*[T: string|CAtom](ctx: JSContext; atom: JSAtom; idx: var uint32; s: var T): FromIdxResult = let val = JS_AtomIsNumericIndex1(ctx, atom) if JS_IsException(val): return fiErr var i: int64 if not JS_IsUndefined(val) and ctx.fromJSFree(val, i).isOk and i in 0..int64(uint32.high - 1): idx = uint32(i) return fiIdx elif ctx.fromJS(atom, s).isOk: return fiStr fiErr proc fromIdx*(ctx: JSContext; atom: JSAtom; idx: var uint32): FromIdxResult = var dummy: string ctx.fromIdx(atom, idx, dummy) proc toJS*(ctx: JSContext; atom: CAtom): JSValue = if atom == CAtomNull: return JS_NULL return ctx.toJS($atom) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/html/chadombuilder.nim������������������������������������������������������������0000664�0000000�0000000�00000032515�15202323131�0020202�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/options import std/tables import chame/htmlparser import chame/tags import config/conftypes import encoding/charset import html/catom import html/dom import monoucha/fromjs import monoucha/jsbind import monoucha/quickjs import monoucha/tojs import types/refstring import types/url # DOMBuilder implementation for Chawan. type CharsetConfidence* = enum ccTentative, ccCertain, ccIrrelevant type HTML5ParserWrapper* = ref object of RootObj parser: HTML5Parser[ParentNode, CAtom] builder*: ChaDOMBuilder opts: HTML5ParserOpts[ParentNode, CAtom] stoppedFromScript: bool ChaDOMBuilder = ref object of DOMBuilder[ParentNode, CAtom] charset*: Charset confidence*: CharsetConfidence document*: Document poppedScript: HTMLScriptElement DOMBuilderImpl = ChaDOMBuilder HandleImpl = ParentNode AtomImpl = CAtom include chame/htmlparseriface type DOMParser = ref object # JS interface jsDestructor(DOMParser) proc setActiveParser(document: Document; wrapper: HTML5ParserWrapper) = document.parser = wrapper proc getDocumentImpl(builder: ChaDOMBuilder): ParentNode = return builder.document proc atomToTagTypeImpl(builder: ChaDOMBuilder; atom: CAtom): TagType = return atom.toTagType() proc tagTypeToAtomImpl(builder: ChaDOMBuilder; tagType: TagType): CAtom = return tagType.toAtom() proc strToAtomImpl(builder: ChaDOMBuilder; s: string): CAtom = return s.toAtom() proc finish(builder: ChaDOMBuilder) = while builder.document.scriptsToExecOnLoad != nil: #TODO spin event loop let script = builder.document.scriptsToExecOnLoad script.execute() let next = script.next builder.document.scriptsToExecOnLoad = next if next == nil: builder.document.scriptsToExecOnLoadTail = nil #TODO events proc restart*(wrapper: HTML5ParserWrapper; charset: Charset) = let builder = wrapper.builder let oldDocument = builder.document let document = newDocument(oldDocument.url) document.charset = charset document.setActiveParser(wrapper) document.contentType = satTextHtml let window = oldDocument.window if window != nil: document.window = window window.document = document builder.document = document builder.charset = charset wrapper.parser = initHTML5Parser(builder, wrapper.opts) proc setQuirksModeImpl(builder: ChaDOMBuilder; quirksMode: QuirksMode) = builder.document.mode = quirksMode if quirksMode == QUIRKS: builder.document.applyQuirksSheet() proc setEncodingImpl(builder: ChaDOMBuilder; encoding: string): SetEncodingResult = if builder.confidence != ccTentative: return SET_ENCODING_CONTINUE if builder.charset in {csUtf16le, csUtf16be}: builder.confidence = ccCertain return SET_ENCODING_CONTINUE let charset = getCharset(encoding) if charset == csUnknown: return SET_ENCODING_CONTINUE builder.confidence = ccCertain if charset == builder.charset: return SET_ENCODING_CONTINUE builder.charset = if charset == csXUserDefined: csWindows1252 else: charset return SET_ENCODING_STOP proc getTemplateContentImpl(builder: ChaDOMBuilder; handle: ParentNode): ParentNode = return HTMLTemplateElement(handle).content proc getParentNodeImpl(builder: ChaDOMBuilder; handle: ParentNode): Option[ParentNode] = return option(handle.parentNode) proc getLocalNameImpl(builder: ChaDOMBuilder; handle: ParentNode): CAtom = return Element(handle).localName proc getNamespaceImpl(builder: ChaDOMBuilder; handle: ParentNode): Namespace = return Element(handle).namespaceURI.toNamespace() proc createHTMLElementImpl(builder: ChaDOMBuilder): ParentNode = return builder.document.newHTMLElement(TAG_HTML) const ResettableElements = { TAG_INPUT, TAG_OUTPUT, TAG_SELECT, TAG_TEXTAREA } proc createElementForTokenImpl(builder: ChaDOMBuilder; localName: CAtom; namespace: Namespace; intendedParent: ParentNode; htmlAttrs: Table[CAtom, string]; xmlAttrs: seq[ParsedAttr[CAtom]]): ParentNode = let document = builder.document let element = document.newElement(localName, namespace) for k, v in htmlAttrs: element.attr(k, v) for attr in xmlAttrs: element.attrns(attr.name, attr.prefix, attr.namespace, attr.value) if element.tagType in ResettableElements: element.resetElement() if element of HTMLScriptElement: let script = HTMLScriptElement(element) script.parserDocument = document script.forceAsync = false # Note: per standard, we could set already started to true here when we # are parsing from document.write, but that sounds like a horrible idea. return element proc insertCommentImpl(builder: ChaDOMBuilder; parent: ParentNode; text: string; before: Option[ParentNode]) = let comment = builder.document.createComment(text) parent.insert(comment, before.get(nil)) proc appendDocumentTypeImpl(builder: ChaDOMBuilder; name, publicId, systemId: string) = let doctype = builder.document.newDocumentType(name, publicId, systemId) builder.document.insert(doctype, nil) proc insertBeforeImpl(builder: ChaDOMBuilder; parent, child: ParentNode; before: Option[ParentNode]) = parent.insert(child, before.get(nil)) proc insertTextImpl(builder: ChaDOMBuilder; parent: ParentNode; text: string; before: Option[ParentNode]) = let before = before.get(nil) let prevSibling = if before != nil: before.previousSibling else: parent.lastChild if prevSibling != nil and prevSibling of Text: Text(prevSibling).data &= text if parent of Element: Element(parent).invalidate() else: let text = builder.document.newText(text) parent.insert(text, before) proc removeImpl(builder: ChaDOMBuilder; child: ParentNode) = if child.parentNode != nil: child.remove(suppressObservers = true) proc moveChildrenImpl(builder: ChaDOMBuilder; fromNode, toNode: ParentNode) = let toMove = fromNode.getChildList() for node in toMove: node.remove(suppressObservers = true) for child in toMove: toNode.insert(child, nil) proc addAttrsIfMissingImpl(builder: ChaDOMBuilder; handle: ParentNode; attrs: Table[CAtom, string]) = let element = Element(handle) for k, v in attrs: if not element.attrb(k): element.attr(k, v) proc setScriptAlreadyStartedImpl(builder: ChaDOMBuilder; script: ParentNode) = HTMLScriptElement(script).alreadyStarted = true proc associateWithFormImpl(builder: ChaDOMBuilder; element, form, intendedParent: ParentNode) = if form.inSameTree(intendedParent): #TODO remove following test eventually if element of FormAssociatedElement: let element = FormAssociatedElement(element) element.setForm(HTMLFormElement(form)) element.parserInserted = true proc elementPoppedImpl(builder: ChaDOMBuilder; element: ParentNode) = let element = Element(element) let document = builder.document if element of HTMLTextAreaElement: element.resetElement() elif element of HTMLScriptElement: if document.scriptingEnabled: assert builder.poppedScript == nil inc document.throwOnDynamicMarkupInsertion #TODO I think this has to be moved for custom elements document.window.performMicrotaskCheckpoint() dec document.throwOnDynamicMarkupInsertion builder.poppedScript = HTMLScriptElement(element) elif element of SVGSVGElement: let window = document.window if window != nil: let svg = SVGSVGElement(element) window.loadSVG(svg) elif element of HTMLStyleElement: HTMLStyleElement(element).updateSheet() proc newChaDOMBuilder(url: URL; window: Window; confidence: CharsetConfidence; charset = DefaultCharset): ChaDOMBuilder = let document = newDocument(url) document.charset = charset document.contentType = satTextHtml if window != nil: document.window = window window.document = document return ChaDOMBuilder( document: document, confidence: confidence, charset: charset ) # https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments proc parseHTMLFragment*(element: Element; s: string): seq[Node] = let url = parseURL0("about:blank") let builder = newChaDOMBuilder(url, nil, ccIrrelevant) let document = builder.document document.mode = element.document.mode let state = case element.tagType of TAG_TITLE, TAG_TEXTAREA: RCDATA of TAG_STYLE, TAG_XMP, TAG_IFRAME, TAG_NOEMBED, TAG_NOFRAMES: RAWTEXT of TAG_SCRIPT: SCRIPT_DATA of TAG_NOSCRIPT: if element.document != nil and element.document.scriptingEnabled: RAWTEXT else: DATA of TAG_PLAINTEXT: PLAINTEXT else: DATA let root = document.newHTMLElement(TAG_HTML) document.insert(root, nil) let opts = HTML5ParserOpts[ParentNode, CAtom]( isIframeSrcdoc: false, #TODO? scripting: false, ctx: some((ParentNode(element), element.localName)), initialTokenizerState: state, openElementsInit: @[(ParentNode(root), root.localName)], pushInTemplate: element.tagType == TAG_TEMPLATE ) var parser = initHTML5Parser(builder, opts) let res = parser.parseChunk(s.toOpenArray(0, s.high)) # scripting is false and confidence is certain -> this must be continue assert res == PRES_CONTINUE parser.finish() builder.finish() return root.getChildList() proc newHTML5ParserWrapper*(window: Window; url: URL; confidence: CharsetConfidence; charset: Charset): HTML5ParserWrapper = let opts = HTML5ParserOpts[ParentNode, CAtom]( scripting: window.settings.scripting != smFalse ) let builder = newChaDOMBuilder(url, window, confidence, charset) let wrapper = HTML5ParserWrapper( builder: builder, opts: opts, parser: initHTML5Parser(builder, opts) ) builder.document.setActiveParser(wrapper) return wrapper template toOpenArray(writeBuffer: DocumentWriteBuffer): openArray[char] = writeBuffer.data.toOpenArray(writeBuffer.i, writeBuffer.data.high) proc addWriteBuffer(document: Document) = let buffer = DocumentWriteBuffer(prev: document.writeBuffersTop) document.writeBuffersTop = buffer proc parseBuffer*(wrapper: HTML5ParserWrapper; buffer: openArray[char]): ParseResult = let builder = wrapper.builder let document = builder.document var res = wrapper.parser.parseChunk(buffer) # set insertion point for when it's needed var ip = wrapper.parser.getInsertionPoint() while res == PRES_SCRIPT: let script = builder.poppedScript builder.poppedScript = nil document.addWriteBuffer() script.prepare() while document.parserBlockingScript != nil: let script = document.parserBlockingScript document.parserBlockingScript = nil #TODO style sheet script.execute() assert document.parserBlockingScript != script if wrapper.stoppedFromScript: # document.write inserted a meta charset tag break assert document.writeBuffersTop.toOpenArray().len == 0 document.writeBuffersTop = document.writeBuffersTop.prev assert document.writeBuffersTop == nil if ip == buffer.len: # script was at the end of the buffer; nothing to parse break # parse rest of input buffer res = wrapper.parser.parseChunk(buffer.toOpenArray(ip, buffer.high)) ip += wrapper.parser.getInsertionPoint() # move insertion point return res # Called from dom whenever document.write is executed. # We consume everything pushed into the top buffer. proc parseDocumentWriteChunk(wrapper: RootRef) = let wrapper = HTML5ParserWrapper(wrapper) let builder = wrapper.builder let document = builder.document let buffer = document.writeBuffersTop var res = wrapper.parser.parseChunk(buffer.toOpenArray()) if res == PRES_SCRIPT: document.addWriteBuffer() while true: buffer.i += wrapper.parser.getInsertionPoint() let script = builder.poppedScript builder.poppedScript = nil script.prepare() while document.parserBlockingScript != nil: let script = document.parserBlockingScript document.parserBlockingScript = nil #TODO style sheet script.execute() assert document.parserBlockingScript != script res = wrapper.parser.parseChunk(buffer.toOpenArray()) if res != PRES_SCRIPT: break assert document.writeBuffersTop.i == document.writeBuffersTop.data.len document.writeBuffersTop = document.writeBuffersTop.prev assert builder.poppedScript == nil buffer.i = buffer.data.len if res == PRES_STOP: wrapper.stoppedFromScript = true proc finish*(wrapper: HTML5ParserWrapper) = wrapper.parser.finish() wrapper.builder.finish() proc newDOMParser*(): DOMParser {.jsctor.} = return DOMParser() proc parseFromString*(ctx: JSContext; parser: DOMParser; str, t: string): JSValue {.jsfunc.} = case t of "text/html": let window = ctx.getWindow() let url = if window.document != nil: window.document.url else: parseURL0("about:blank") let builder = newChaDOMBuilder(url, nil, ccIrrelevant) var parser = initHTML5Parser(builder, HTML5ParserOpts[ParentNode, CAtom]()) let res = parser.parseChunk(str) assert res == PRES_CONTINUE parser.finish() builder.finish() return ctx.toJS(builder.document) of "text/xml", "application/xml", "application/xhtml+xml", "image/svg+xml": return JS_ThrowInternalError(ctx, "XML parsing is not supported yet") else: return JS_ThrowTypeError(ctx, "invalid mime type") # Forward declaration hack parseHTMLFragmentImpl = parseHTMLFragment parseDocumentWriteChunkImpl = parseDocumentWriteChunk proc addHTMLModule*(ctx: JSContext): JSClassID = return ctx.registerType(DOMParser) {.pop.} # raises: [] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/html/dom.nim����������������������������������������������������������������������0000664�0000000�0000000�00000754434�15202323131�0016172�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/algorithm import std/hashes import std/math import std/options import std/posix import std/sets import std/setutils import std/tables import std/times import chame/tags import config/conftypes import config/mimetypes import css/cssparser import css/cssvalues import css/mediaquery import css/sheet import encoding/charset import encoding/decoder import html/catom import html/domcanvas import html/domexception import html/event import html/performance import html/script import io/console import io/dynstream import io/timeout import monoucha/fromjs import monoucha/jsbind import monoucha/jsnull import monoucha/jsopaque import monoucha/jspropenumlist import monoucha/jstypes import monoucha/jsutils import monoucha/quickjs import monoucha/tojs import server/headers import server/loaderiface import server/request import types/bitmap import types/blob import types/color import types/jsopt import types/opt import types/path import types/referrer import types/refstring import types/url import types/winattrs import utils/dtoawrap import utils/strwidth import utils/twtstr type FormMethod* = enum fmGet = "get" fmPost = "post" fmDialog = "dialog" FormEncodingType* = enum fetUrlencoded = "application/x-www-form-urlencoded", fetMultipart = "multipart/form-data", fetTextPlain = "text/plain" DocumentReadyState* = enum rsLoading = "loading" rsInteractive = "interactive" rsComplete = "complete" type InputType* = enum itText = "text" itButton = "button" itCheckbox = "checkbox" itColor = "color" itDate = "date" itDatetimeLocal = "datetime-local" itEmail = "email" itFile = "file" itHidden = "hidden" itImage = "image" itMonth = "month" itNumber = "number" itPassword = "password" itRadio = "radio" itRange = "range" itReset = "reset" itSearch = "search" itSubmit = "submit" itTel = "tel" itTime = "time" itURL = "url" itWeek = "week" ButtonType* = enum btSubmit = "submit" btReset = "reset" btButton = "button" NodeType = enum ntElement = (1u16, "ELEMENT_NODE") ntAttribute = (2u16, "ATTRIBUTE_NODE") ntText = (3u16, "TEXT_NODE") ntCdataSection = (4u16, "CDATA_SECTION_NODE") ntEntityReference = (5u16, "ENTITY_REFERENCE_NODE") ntEntity = (6u16, "ENTITY_NODE") ntProcessingInstruction = (7u16, "PROCESSING_INSTRUCTION_NODE") ntComment = (8u16, "COMMENT_NODE") ntDocument = (9u16, "DOCUMENT_NODE") ntDocumentType = (10u16, "DOCUMENT_TYPE_NODE") ntDocumentFragment = (11u16, "DOCUMENT_FRAGMENT_NODE") ntNotation = (12u16, "NOTATION_NODE") type DependencyType* = enum dtHover, dtChecked, dtFocus, dtTarget DependencyMap = object dependsOn: Table[Element, seq[Element]] dependedBy: Table[Element, seq[Element]] DependencyInfo* = array[DependencyType, seq[Element]] LoadSheetResult = object head: CSSStylesheet tail: CSSStylesheet Location = ref object window: Window CachedURLImage = ref object of RootObj window: Window expiry: int64 loading: bool shared: seq[HTMLImageElement] bmp: NetworkBitmap cacheId: int t: string WindowWeakMap* = enum wwmChildren, wwmChildNodes, wwmSelectedOptions, wwmTBodies, wwmCells, wwmDataset, wwmAttributes Window* = ref object of EventTarget bc*: RootRef # backref to BufferContext console*: Console navigator* {.jsget.}: Navigator screen* {.jsget.}: Screen history* {.jsget.}: History localStorage* {.jsget.}: Storage sessionStorage* {.jsget.}: Storage crypto* {.jsget.}: Crypto event*: Event settings*: EnvironmentSettings loader*: FileLoader location* {.jsget.}: Location jsctx*: JSContext document* {.jsufget.}: Document timeouts*: TimeoutState importMapsAllowed*: bool inMicrotaskCheckpoint: bool dangerAlwaysSameOrigin*: bool # for client, insecure if Window sets true remoteSheetNum*: uint32 loadedSheetNum*: uint32 remoteImageNum*: uint32 loadedImageNum*: uint32 imageURLCache: Table[string, CachedURLImage] svgCache*: Table[string, SVGSVGElement] # ID of the next image imageId: int # list of streams that must be closed for canvas rendering on load pendingCanvasCtls*: seq[CanvasRenderingContext2D] imageTypes*: Table[string, string] userAgent*: string referrer* {.jsget.}: string performance* {.jsget.}: Performance weakMap*: array[WindowWeakMap, JSValue] customElements* {.jsget.}: CustomElementRegistry # Navigator stuff # (most of these are just shims; really there should be a framework for # this so we generate less code) Navigator* = ref object plugins* {.jsget.}: PluginArray mimeTypes* {.jsget.}: MimeTypeArray permissions* {.jsget.}: Permissions PluginArray* = ref object MimeTypeArray* = ref object Screen* = ref object History* = ref object Storage* = ref object map*: seq[tuple[key, value: string]] Crypto* = ref object urandom*: PosixStream Notification* = ref object Permissions* = ref object CECallbackType = enum cctConnected = "connectedCallback" cctDisconnected = "disconnectedCallback" cctAdopted = "adoptedCallback" cctConnectedMove = "connectedMoveCallback" cctAttributeChanged = "attributeChangedCallback" # note: if you add more, update define0 too cctFormAssociated = "formAssociatedCallback" cctFormReset = "formResetCallback" cctFormDisabled = "formDisabledCallback" cctFormStateRestore = "formStateRestoreCallback" CECallbackMap = array[CECallbackType, JSValue] CustomElementFlag = enum cefFormAssociated, cefInternals, cefShadow CustomElementDef = ref object name: CAtom localName: CAtom ctor: JSValue observedAttrs: seq[string] #TODO CAtom? callbacks: CECallbackMap flags: set[CustomElementFlag] next: CustomElementDef CustomElementRegistry* = ref object rt*: JSRuntime defsHead: CustomElementDef defsTail: CustomElementDef inDefine: bool scoped: bool scopedDocuments: seq[Document] NamedNodeMap = ref object element: Element attrlist: seq[Attr] NodeFilterType = enum nftAccept = (1, "FILTER_ACCEPT") nftReject = (2, "FILTER_REJECT") nftSkip = (3, "FILTER_SKIP") NodeFilterNode = enum SHOW_ELEMENT = 0 SHOW_ATTRIBUTE = 1 SHOW_TEXT = 2 SHOW_CDATA_SECTION = 3 SHOW_ENTITY_REFERENCE = 4 SHOW_ENTITY = 5 SHOW_PROCESSING_INSTRUCTION = 6 SHOW_COMMENT = 7 SHOW_DOCUMENT = 8 SHOW_DOCUMENT_TYPE = 9 SHOW_DOCUMENT_FRAGMENT = 10 SHOW_NOTATION = 11 CollectionMatchFun = proc(ctx: JSContext; this: Collection; node: Node): Opt[bool] {.nimcall, raises: [].} LoadSheetEnv = ref object of BlobOpaque window: Window this: SheetElement url: URL finish: LoadSheetFinish charset: Charset layer: CAtom i: int parseEnv: ParseSheetEnv ParseSheetEnv = ref object sheet: CSSStylesheet sheets: seq[LoadSheetResult] loaded: int finish: LoadSheetFinish parent: ParseSheetEnv i: int LoadSheetFinish = proc(window: Window; this: SheetElement; res: LoadSheetResult; env: ParseSheetEnv; i: int) {. nimcall, raises: [].} CollectionObj = object of RootObj childonly: bool invalid: bool inclusive: bool root: Node match: CollectionMatchFun snapshot: seq[Node] atoms: seq[CAtom] # if not nil, this is a live collection. (uses a ptr instead of a ref # because ORC likes to set refs to nil before the destructor is called) document: ptr DocumentObj Collection = ref CollectionObj NodeIterator = ref object of Collection filter: JSValue whatToShow: uint32 u: uint32 NodeList = ref object of Collection HTMLCollection = ref object of Collection HTMLFormControlsCollection = ref object of HTMLCollection form: HTMLFormElement HTMLOptionsCollection = ref object of HTMLCollection RadioNodeList = ref object of NodeList parent: HTMLFormControlsCollection HTMLAllCollection = ref object of Collection DOMTokenList = ref object toks: seq[CAtom] element: Element localName: CAtom DOMStringMap = ref object target: HTMLElement # Nodes are organized as doubly linked lists, which normally have # two unused pointers (prev of head, next of tail). We exploit this # property to elide two other pointers as follows: # * The tail of the child linked list is stored as the prev pointer of # the first child. # * The owner document is stored as the next pointer of the last # child. (However, a Document has no owner document, so its # internalNext is always nil.) # Additionally, we separate out the firstChild property into a subtype # (ParentNode) so that it doesn't take up space in e.g. Text nodes. Node* = ref object of EventTarget parentNode*: ParentNode internalNext: Node # either nextSibling or ownerDocument internalPrev: Node # either previousSibling or parentNode.lastChild ParentNode* = ref object of Node internalFirst: Node # either firstChild or shadow root Attr = ref object of Node dataIdx: int ownerElement: Element prefix {.jsget.}: CAtom localName {.jsget.}: CAtom DOMImplementation = ref object document: Document DOMRect* = ref object x* {.jsgetset.}: float64 y* {.jsgetset.}: float64 width* {.jsgetset.}: float64 height* {.jsgetset.}: float64 DOMRectList = ref object list: seq[DOMRect] DocumentWriteBuffer* = ref object data*: string i*: int prev*: DocumentWriteBuffer Document* = ref DocumentObj DocumentObj = object of ParentNode activeParserWasAborted: bool invalid*: bool # whether the document must be rendered again charset*: Charset mode*: QuirksMode readyState* {.jsget.}: DocumentReadyState contentType* {.jsget.}: StaticAtom window* {.jsget: "defaultView".}: Window url*: URL # not nil currentScript {.jsget.}: HTMLScriptElement implementation {.jsget.}: DOMImplementation origin: Origin # document.write ignoreDestructiveWrites: int throwOnDynamicMarkupInsertion*: int writeBuffersTop*: DocumentWriteBuffer styleDependencies: array[DependencyType, DependencyMap] scriptsToExecSoon: HTMLScriptElement scriptsToExecInOrder: HTMLScriptElement scriptsToExecInOrderTail: HTMLScriptElement scriptsToExecOnLoad*: HTMLScriptElement scriptsToExecOnLoadTail*: HTMLScriptElement parserBlockingScript*: HTMLScriptElement internalFocus: Element internalTarget: Element renderBlockingElements: seq[Element] uaSheetsHead: CSSStylesheet userSheet: CSSStylesheet authorSheetsHead: CSSStylesheet sheetTitle: string ruleMap: CSSRuleMap cachedForms: HTMLCollection cachedLinks: HTMLCollection cachedImages: HTMLCollection parser*: RootRef liveCollections: seq[ptr CollectionObj] cachedAll: HTMLAllCollection customElements: CustomElementRegistry #TODO ? XMLDocument = ref object of Document CharacterData* = ref object of Node # Note: layout assumes this is only modified directly by appending text. data* {.jsgetset.}: RefString Text* = ref object of CharacterData Comment* = ref object of CharacterData CDATASection = ref object of CharacterData ProcessingInstruction = ref object of CharacterData target {.jsget.}: string DocumentFragment* = ref object of ParentNode host*: Element ShadowRootInit = object of JSDict mode: ShadowRootMode delegatesFocus {.jsdefault.}: bool slotAssignment {.jsdefault.}: SlotAssignmentMode clonable {.jsdefault.}: bool serializable {.jsdefault.}: bool customElementRegistry {.jsdefault.}: CustomElementRegistry ShadowRootMode = enum srmOpen = "open", srmClosed = "closed" SlotAssignmentMode = enum samNamed = "named", samManual = "manual" ShadowRoot = ref object of DocumentFragment mode {.jsget.}: ShadowRootMode delegatesFocus {.jsget.}: bool slotAssignment {.jsget.}: SlotAssignmentMode clonable {.jsget.}: bool serializable {.jsget.}: bool declarative: bool unsetCustomElements: bool customElements: CustomElementRegistry #TODO onslotchange DocumentType* = ref object of Node name* {.jsget.}: string publicId* {.jsget.}: string systemId* {.jsget.}: string AttrData* = object qualifiedName*: CAtom namespace*: CAtom value*: string CustomElementState = enum cesUndefined = "undefined" cesFailed = "failed" cesUncustomized = "uncustomized" cesPrecustomized = "precustomized" cesCustom = "custom" ElementFlag = enum efHint, efHover, efShadowRoot Element* = ref object of ParentNode namespaceURI* {.jsget.}: CAtom # 4 prefix {.jsget.}: CAtom # 8 childElIndicesInvalid: bool # 9 flags: set[ElementFlag] # 10 selfDepends: set[DependencyType] # 11 custom: CustomElementState # 12 localName* {.jsget.}: CAtom # 16 id* {.jsget.}: CAtom # 20 name: CAtom # 24 internalElIndex: int # 32 classList* {.jsget.}: DOMTokenList # 40 attrs*: seq[AttrData] # 48, sorted by int(qualifiedName) cachedStyle*: CSSStyleDeclaration # 56 computed*: CSSValues # 64 box*: RootRef # 72, CSSBox AttrDummyElement = ref object of Element CSSStyleDeclaration* = ref object computed: bool readonly: bool decls*: seq[CSSDeclaration] element: Element HTMLElement* = ref object of Element SVGElement = ref object of Element SVGSVGElement* = ref object of SVGElement bitmap*: NetworkBitmap shared: seq[SVGSVGElement] # elements that serialize to the same string fetchStarted: bool FormAssociatedElement* = ref object of HTMLElement form*: HTMLFormElement parserInserted*: bool HTMLInputElement* = ref object of FormAssociatedElement inputType* {.jsget: "type".}: InputType internalValue: RefString internalChecked {.jsget: "checked".}: bool files* {.jsget.}: seq[WebFile] xcoord*: int ycoord*: int HTMLAnchorElement* = ref object of HTMLElement relList {.jsget.}: DOMTokenList HTMLSelectElement* = ref object of FormAssociatedElement userValidity: bool cachedOptions: HTMLOptionsCollection HTMLSpanElement = ref object of HTMLElement HTMLOptGroupElement = ref object of HTMLElement HTMLOptionElement* = ref object of HTMLElement selected* {.jsget.}: bool dirty: bool HTMLHeadingElement = ref object of HTMLElement HTMLBRElement = ref object of HTMLElement HTMLMenuElement = ref object of HTMLElement HTMLUListElement = ref object of HTMLElement HTMLOListElement = ref object of HTMLElement HTMLLIElement* = ref object of HTMLElement SheetElement = ref object of HTMLElement sheetHead: CSSStylesheet sheetTail: CSSStylesheet HTMLStyleElement* = ref object of SheetElement HTMLLinkElement* = ref object of SheetElement relList {.jsget.}: DOMTokenList fetchStarted: bool enabled: Option[bool] HTMLFormElement* = ref object of HTMLElement constructingEntryList*: bool firing*: bool controls*: seq[FormAssociatedElement] cachedElements: HTMLFormControlsCollection relList {.jsget.}: DOMTokenList HTMLTemplateElement* = ref object of HTMLElement content* {.jsget.}: DocumentFragment HTMLScriptElement* = ref object of HTMLElement parserDocument*: Document preparationTimeDocument*: Document forceAsync*: bool external*: bool readyForParserExec*: bool alreadyStarted*: bool delayingTheLoadEvent: bool ctype: ScriptType internalNonce: string scriptResult*: ScriptResult onReady: (proc(element: HTMLScriptElement) {.nimcall, raises: [].}) next*: HTMLScriptElement # scriptsToExecSoon/InOrder/OnLoad OnCompleteProc = proc(element: HTMLScriptElement; res: ScriptResult) HTMLBaseElement = ref object of HTMLElement HTMLAreaElement = ref object of HTMLElement relList {.jsget.}: DOMTokenList HTMLButtonElement* = ref object of FormAssociatedElement ctype* {.jsget: "type".}: ButtonType HTMLTextAreaElement* = ref object of FormAssociatedElement dirty: bool internalValue: string HTMLLabelElement* = ref object of HTMLElement HTMLCanvasElement* = ref object of HTMLElement ctx2d*: CanvasRenderingContext2D bitmap*: NetworkBitmap HTMLImageElement* = ref object of HTMLElement bitmap*: NetworkBitmap fetchStarted: bool HTMLVideoElement* = ref object of HTMLElement HTMLAudioElement* = ref object of HTMLElement HTMLIFrameElement = ref object of HTMLElement HTMLTableElement = ref object of HTMLElement cachedRows: HTMLCollection HTMLTableCaptionElement = ref object of HTMLElement HTMLTableSectionElement = ref object of HTMLElement cachedRows: HTMLCollection HTMLTableRowElement = ref object of HTMLElement HTMLMetaElement = ref object of HTMLElement HTMLDetailsElement = ref object of HTMLElement HTMLFrameElement = ref object of HTMLElement HTMLTimeElement = ref object of HTMLElement HTMLQuoteElement = ref object of HTMLElement HTMLDataElement = ref object of HTMLElement HTMLHeadElement = ref object of HTMLElement HTMLTitleElement = ref object of HTMLElement HTMLObjectElement = ref object of HTMLElement HTMLSourceElement = ref object of HTMLElement HTMLModElement = ref object of HTMLElement HTMLProgressElement = ref object of HTMLElement HTMLSlotElement = ref object of HTMLElement HTMLUnknownElement = ref object of HTMLElement jsDestructor(Navigator) jsDestructor(PluginArray) jsDestructor(MimeTypeArray) jsDestructor(Screen) jsDestructor(History) jsDestructor(Storage) jsDestructor(Crypto) jsDestructor(Notification) jsDestructor(Permissions) jsDestructor(Element) jsDestructor(HTMLElement) jsDestructor(HTMLInputElement) jsDestructor(HTMLAnchorElement) jsDestructor(HTMLSelectElement) jsDestructor(HTMLSpanElement) jsDestructor(HTMLOptGroupElement) jsDestructor(HTMLOptionElement) jsDestructor(HTMLHeadingElement) jsDestructor(HTMLBRElement) jsDestructor(HTMLMenuElement) jsDestructor(HTMLUListElement) jsDestructor(HTMLOListElement) jsDestructor(HTMLLIElement) jsDestructor(HTMLStyleElement) jsDestructor(HTMLLinkElement) jsDestructor(HTMLFormElement) jsDestructor(HTMLTemplateElement) jsDestructor(HTMLUnknownElement) jsDestructor(HTMLScriptElement) jsDestructor(HTMLBaseElement) jsDestructor(HTMLAreaElement) jsDestructor(HTMLButtonElement) jsDestructor(HTMLTextAreaElement) jsDestructor(HTMLLabelElement) jsDestructor(HTMLCanvasElement) jsDestructor(HTMLImageElement) jsDestructor(HTMLVideoElement) jsDestructor(HTMLAudioElement) jsDestructor(HTMLIFrameElement) jsDestructor(HTMLTableElement) jsDestructor(HTMLTableCaptionElement) jsDestructor(HTMLTableRowElement) jsDestructor(HTMLTableSectionElement) jsDestructor(HTMLMetaElement) jsDestructor(HTMLDetailsElement) jsDestructor(HTMLFrameElement) jsDestructor(HTMLTimeElement) jsDestructor(HTMLQuoteElement) jsDestructor(HTMLDataElement) jsDestructor(HTMLHeadElement) jsDestructor(HTMLTitleElement) jsDestructor(HTMLObjectElement) jsDestructor(HTMLSourceElement) jsDestructor(HTMLModElement) jsDestructor(HTMLProgressElement) jsDestructor(HTMLSlotElement) jsDestructor(SVGElement) jsDestructor(SVGSVGElement) jsDestructor(Node) jsDestructor(NodeList) jsDestructor(HTMLCollection) jsDestructor(HTMLFormControlsCollection) jsDestructor(RadioNodeList) jsDestructor(HTMLAllCollection) jsDestructor(HTMLOptionsCollection) jsDestructor(NodeIterator) jsDestructor(Location) jsDestructor(Document) jsDestructor(XMLDocument) jsDestructor(DOMImplementation) jsDestructor(DOMTokenList) jsDestructor(DOMStringMap) jsDestructor(Comment) jsDestructor(CDATASection) jsDestructor(DocumentFragment) jsDestructor(ProcessingInstruction) jsDestructor(CharacterData) jsDestructor(Text) jsDestructor(DocumentType) jsDestructor(Attr) jsDestructor(NamedNodeMap) jsDestructor(CSSStyleDeclaration) jsDestructor(DOMRect) jsDestructor(DOMRectList) jsDestructor(CustomElementRegistry) jsDestructor(ShadowRoot) # Forward declarations proc loadSheet(window: Window; this: SheetElement; url: URL; charset: Charset; layer: CAtom; finish: LoadSheetFinish; i: int; parseEnv: ParseSheetEnv) proc newCDATASection(document: Document; data: string): CDATASection proc newComment(document: Document; data: sink string): Comment proc newText*(document: Document; data: sink string): Text proc newText(ctx: JSContext; data: sink string = ""): Text proc newDocument*(url: URL): Document proc newDocumentType*(document: Document; name, publicId, systemId: sink string): DocumentType proc newDocumentFragment(document: Document): DocumentFragment proc newProcessingInstruction(document: Document; target: string; data: sink string): ProcessingInstruction proc newElement*(document: Document; localName: CAtom; namespace = Namespace.HTML; prefix = NO_PREFIX): Element proc newElement*(document: Document; localName, namespaceURI, prefix: CAtom): Element proc newHTMLElement*(document: Document; tagType: TagType): HTMLElement proc newHTMLCollection(ctx: JSContext; root: Node; match: CollectionMatchFun; islive, childonly: bool): Opt[HTMLCollection] proc newEmptyNodeList(): NodeList proc newNodeList(ctx: JSContext; root: Node; match: CollectionMatchFun; islive, childonly: bool): Opt[NodeList] proc newDOMTokenList(element: Element; name: StaticAtom): DOMTokenList proc newCSSStyleDeclaration(element: Element; value: string; computed = false; readonly = false): CSSStyleDeclaration proc adopt(document: Document; node: Node) proc applyStyleDependencies*(element: Element; depends: DependencyInfo) proc baseURL*(document: Document): URL proc documentElement*(document: Document): Element proc invalidateCollections(document: Document) proc isConnected(node: Node): bool proc lastChild*(node: Node): Node proc parseURL0*(document: Document; s: string): URL proc parseURL*(document: Document; s: string): Opt[URL] proc reflectEvent(document: Document; target: EventTarget; name, ctype: StaticAtom; value: string; target2 = none(EventTarget)) proc document*(node: Node): Document proc nextDescendant(node, start: Node): Node proc nextDescendantShadow(node, start: Node): Node proc parentNodeShadow(node: Node): Node proc parentNodeHost(node: Node): Node proc parentElement*(node: Node): Element proc serializeFragment(res: var string; node: Node; writeShadow: bool) proc serializeFragmentInner(res: var string; child: Node; parentType: TagType; writeShadow: bool) proc countChildren(node: ParentNode; nodeType: type): int proc hasChild(node: ParentNode; nodeType: type): bool proc hasChildExcept(node: ParentNode; nodeType: type; ex: Node): bool proc insert*(parent: ParentNode; node, before: Node; suppressObservers = false) proc replaceAll(parent: ParentNode; node: Node) proc replaceAll(parent: ParentNode; s: sink string) proc firstChild(parent: ParentNode): Node proc firstChildShadow(parent: ParentNode): Node proc setFirstChild(node: ParentNode; child: Node) proc containsIgnoreCase(tokenList: DOMTokenList; a: StaticAtom): bool proc newAttr(element: Element; dataIdx: int): Attr proc data(attr: Attr): lent AttrData proc setValue(attr: Attr; s: string) proc attachShadow(ctx: JSContext; this: Element; init: ShadowRootInit): Opt[ShadowRoot] proc attr*(element: Element; name: CAtom; value: sink string) proc attr*(element: Element; name: StaticAtom; value: sink string) proc attr*(element: Element; s: StaticAtom): lent string proc attrb*(element: Element; at: StaticAtom): bool proc attrb*(element: Element; s: CAtom): bool proc attrd(element: Element; name: StaticAtom; value: float64) proc attrd*(element: Element; s: StaticAtom): Opt[float64] proc attrdgz*(element: Element; s: StaticAtom): Opt[float64] proc attrl(element: Element; name: StaticAtom; value: int32) proc attrl*(element: Element; s: StaticAtom): Opt[int32] proc attrul(element: Element; name: StaticAtom; value: uint32) proc attrul*(element: Element; s: StaticAtom): Opt[uint32] proc attrulgz(element: Element; name: StaticAtom; value: uint32) proc attrulgz*(element: Element; s: StaticAtom): Opt[uint32] proc delAttr(ctx: JSContext; element: Element; i: int) proc elIndex*(this: Element): int proc elementInsertionSteps(element: Element): bool proc ensureStyle(element: Element) proc findAttr(element: Element; qualifiedName: CAtom): int proc findAttrNS(element: Element; namespace, localName: CAtom): int proc getCharset(element: Element): Charset proc getComputedStyle*(element: Element; pseudo: PseudoElement): CSSValues proc invalidate*(element: Element) proc invalidate*(element: Element; dep: DependencyType) proc nextDisplayedElement(element: Element): Element proc outerHTML(element: Element): string proc postConnectionSteps(element: Element) proc previousElementSibling*(element: Element): Element proc scriptingEnabled(element: Element): bool proc shadowRoot(this: Element): ShadowRoot proc tagName(element: Element): string proc tagType*(element: Element; namespace = satNamespaceHTML): TagType proc globalCustomElements(this: ShadowRoot): CustomElementRegistry proc crossOrigin(element: HTMLElement): CORSAttribute proc referrerPolicy(element: HTMLElement): Opt[ReferrerPolicy] proc resetFormOwner(element: FormAssociatedElement) proc insertSheet(this: SheetElement) proc removeSheet(this: SheetElement) proc updateSheet(this: SheetElement; head, tail: CSSStylesheet) proc toBlob(ctx: JSContext; this: HTMLCanvasElement; callback: JSValueConst; contentType = "image/png"; quality = none(float64)) proc getImageRect(this: HTMLImageElement): tuple[w, h: float64] proc checked*(input: HTMLInputElement): bool {.inline.} proc setChecked*(input: HTMLInputElement; b: bool) proc value*(this: HTMLInputElement): lent string proc setValue*(this: HTMLInputElement; value: sink string) proc isDisabled(link: HTMLLinkElement): bool proc value*(option: HTMLOptionElement): string proc setSelectedness(select: HTMLSelectElement) proc updateSheet*(this: HTMLStyleElement) proc execute*(element: HTMLScriptElement) proc prepare*(element: HTMLScriptElement) proc fetchDescendantsAndLink(element: HTMLScriptElement; script: Script; destination: RequestDestination; onComplete: OnCompleteProc) proc fetchSingleModule(element: HTMLScriptElement; url: URL; destination: RequestDestination; options: ScriptOptions; referrer: URL; isTopLevel: bool; onComplete: OnCompleteProc) # Forward declaration hacks # set in css/match var matchesImpl*: proc(element: Element; cxsels: SelectorList): bool {.nimcall, raises: [].} # set in html/chadombuilder var parseHTMLFragmentImpl*: proc(element: Element; s: string): seq[Node] {.nimcall, raises: [].} var parseDocumentWriteChunkImpl*: proc(wrapper: RootRef) {.nimcall, raises: [].} var applyStyleImpl*: proc(element: Element) {.nimcall, raises: [].} var getClientRectsImpl*: proc(element: Element; firstOnly, blockOnly: bool): seq[DOMRect] {.nimcall, raises: [].} # set in server/buffer var sheetLoadedImpl*: proc(bc: RootRef) {.nimcall, raises: [].} var imageLoadedImpl*: proc(bc: RootRef) {.nimcall, raises: [].} var navigateImpl*: proc(bc: RootRef; url: URL) {.nimcall, raises: [].} var ensureLayoutImpl*: proc(bc: RootRef; element: Element) {. nimcall, raises: [].} var clickImpl*: proc(bc: RootRef; element: HTMLElement) {.nimcall, raises: [].} # Reflected attributes. type ReflectType = enum rtStr, rtUrl, rtBool, rtLong, rtUlongGz, rtUlong, rtDoubleGz, rtFunction, rtReferrerPolicy, rtCrossOrigin, rtMethod ReflectEntry = object attrname: StaticAtom funcname: StaticAtom t: ReflectType u: uint32 # 32 bits of opaque associated data (mostly default values) ReflectEntryTag = object tags: seq[TagType] e: ReflectEntry proc makes(attrname, funcname: StaticAtom; ts: varargs[TagType]): ReflectEntryTag = ReflectEntryTag( tags: @ts, e: ReflectEntry( attrname: attrname, funcname: funcname, t: rtStr, ) ) proc makes(name: StaticAtom; ts: varargs[TagType]): ReflectEntryTag = makes(name, name, ts) proc makeurl(name: StaticAtom; ts: varargs[TagType]): ReflectEntryTag = ReflectEntryTag( tags: @ts, e: ReflectEntry( attrname: name, funcname: name, t: rtUrl, ) ) proc makeb(attrname, funcname: StaticAtom; ts: varargs[TagType]): ReflectEntryTag = ReflectEntryTag( tags: @ts, e: ReflectEntry( attrname: attrname, funcname: funcname, t: rtBool, ) ) proc makeb(name: StaticAtom; ts: varargs[TagType]): ReflectEntryTag = makeb(name, name, ts) proc makel(name: StaticAtom; ts: varargs[TagType]; default = 0u32): ReflectEntryTag = ReflectEntryTag( tags: @ts, e: ReflectEntry( attrname: name, funcname: name, t: rtLong, u: default ) ) proc makeul(name: StaticAtom; ts: varargs[TagType]; default = 0u32): ReflectEntryTag = ReflectEntryTag( tags: @ts, e: ReflectEntry( attrname: name, funcname: name, t: rtUlong, u: default ) ) proc makeulgz(name: StaticAtom; ts: varargs[TagType]; default = 0u32): ReflectEntryTag = ReflectEntryTag( tags: @ts, e: ReflectEntry( attrname: name, funcname: name, t: rtUlongGz, u: default ) ) proc makef(name, ctype: StaticAtom): ReflectEntryTag = ReflectEntryTag( tags: @[], e: ReflectEntry( attrname: name, funcname: name, t: rtFunction, u: uint32(ctype) ) ) proc makerp(attrName, funcName: StaticAtom; ts: varargs[TagType]): ReflectEntryTag = ReflectEntryTag( tags: @ts, e: ReflectEntry( attrname: attrName, funcname: funcName, t: rtReferrerPolicy, ) ) proc makeco(attrName, funcName: StaticAtom; ts: varargs[TagType]): ReflectEntryTag = ReflectEntryTag( tags: @ts, e: ReflectEntry( attrname: attrName, funcname: funcName, t: rtCrossOrigin, ) ) proc makem(attrname, funcname: StaticAtom; ts: varargs[TagType]): ReflectEntryTag = ReflectEntryTag( tags: @ts, e: ReflectEntry( attrname: attrname, funcname: funcname, t: rtMethod ) ) proc makedgz(name: StaticAtom; t: TagType; u: uint32): ReflectEntryTag = ReflectEntryTag( tags: @[t], e: ReflectEntry( attrname: name, funcname: name, t: rtDoubleGz, u: u, ) ) proc makem(name: StaticAtom; ts: varargs[TagType]): ReflectEntryTag = makem(name, name, ts) # Note: this table only works for tag types with a registered interface. const ReflectMap0 = [ # non-global attributes makes(satTarget, TAG_A, TAG_AREA, TAG_LABEL, TAG_LINK), makes(satHref, TAG_LINK), makes(satValue, TAG_BUTTON, TAG_DATA), makel(satValue, TAG_LI), makeb(satRequired, TAG_INPUT, TAG_SELECT, TAG_TEXTAREA), makes(satName, TAG_A, TAG_INPUT, TAG_SELECT, TAG_TEXTAREA, TAG_META, TAG_IFRAME, TAG_FRAME, TAG_IMG, TAG_OBJECT, TAG_PARAM, TAG_OBJECT, TAG_MAP, TAG_FORM, TAG_OUTPUT, TAG_FIELDSET, TAG_DETAILS, TAG_SLOT), makes(satOpen, TAG_DETAILS), makeb(satNovalidate, satHNoValidate, TAG_FORM), makeb(satSelected, satDefaultSelected, TAG_OPTION), makes(satRel, TAG_A, TAG_LINK, TAG_LABEL), makes(satFor, satHtmlFor, TAG_LABEL), makes(satHttpEquiv, satHHttpEquiv, TAG_META), makes(satContent, TAG_META), makes(satMedia, TAG_META, TAG_SOURCE), makes(satDatetime, satHDateTime, TAG_TIME, TAG_INS, TAG_DEL), makes(satType, TAG_SOURCE, TAG_A, TAG_OL, TAG_LINK, TAG_SCRIPT, TAG_OBJECT), makeul(satCols, TAG_TEXTAREA, 20u32), makeul(satRows, TAG_TEXTAREA, 1u32), makeulgz(satSize, TAG_SELECT, 0u32), makeulgz(satSize, TAG_INPUT, 20u32), makeul(satWidth, TAG_CANVAS, TAG_SOURCE, 300u32), makeul(satHeight, TAG_CANVAS, TAG_SOURCE, 150u32), makes(satAlt, TAG_IMG), makes(satSrcset, TAG_IMG, TAG_SOURCE), makes(satSizes, TAG_IMG, TAG_SOURCE), makeco(satCrossorigin, satHCrossOrigin, TAG_IMG, TAG_SCRIPT), makerp(satReferrerpolicy, satHReferrerPolicy, TAG_IMG, TAG_SCRIPT), makem(satMethod, TAG_FORM), makem(satFormmethod, satHFormMethod, TAG_INPUT, TAG_BUTTON), makes(satUsemap, satHUseMap, TAG_IMG), makeb(satIsmap, satHIsMap, TAG_IMG), makeb(satDisabled, TAG_LINK, TAG_OPTION, TAG_SELECT, TAG_OPTGROUP), makeurl(satSrc, TAG_IMG, TAG_SCRIPT, TAG_IFRAME, TAG_FRAME, TAG_INPUT, TAG_SOURCE), makeurl(satCite, TAG_BLOCKQUOTE, TAG_Q, TAG_INS, TAG_DEL), makeurl(satHref, TAG_LINK), makeurl(satData, TAG_OBJECT), makedgz(satValue, TAG_PROGRESS, 0), makedgz(satMax, TAG_PROGRESS, 1), # super-global attributes makes(satClass, satClassName), makef(satOnclick, satClick), makef(satOninput, satInput), makef(satOnchange, satChange), makef(satOnload, satLoad), makef(satOnerror, satError), makef(satOnblur, satBlur), makef(satOnfocus, satFocus), makef(satOnsubmit, satSubmit), makef(satOncontextmenu, satContextmenu), makef(satOndblclick, satDblclick), makes(satSlot), makes(satTitle), makes(satLang), ] static: # In the reflection magic we allocate 9 bits to attribute names and 7 bits # to class names. doAssert ReflectMap0.len < 512 const LabelableElements = { # input only if type not hidden TAG_BUTTON, TAG_INPUT, TAG_METER, TAG_OUTPUT, TAG_PROGRESS, TAG_SELECT, TAG_TEXTAREA } const VoidElements = { TAG_AREA, TAG_BASE, TAG_BR, TAG_COL, TAG_EMBED, TAG_HR, TAG_IMG, TAG_INPUT, TAG_LINK, TAG_META, TAG_SOURCE, TAG_TRACK, TAG_WBR } # Iterators iterator childList*(node: ParentNode): Node {.inline.} = var it = node.firstChild if it != nil: while true: yield it it = it.internalNext if it.internalNext == nil: break # it is ownerDocument iterator safeChildList*(node: ParentNode): Node {.inline.} = var it = node.firstChild if it != nil: while true: let next = it.internalNext yield it it = next if it.internalNext == nil: break # it is ownerDocument # either the shadow root, or our child list iterator shadowChildList*(node: ParentNode): Node {.inline.} = var it = node.firstChildShadow if it != nil: if it.parentNode != node: # shadow root it = ParentNode(it).firstChildShadow while true: yield it it = it.internalNext if it.internalNext == nil: break # it is ownerDocument iterator rchildList*(node: ParentNode): Node {.inline.} = let first = node.firstChild if first != nil: var it = first.internalPrev while true: yield it if it == first: break it = it.internalPrev iterator precedingSiblings*(node: Node): Node {.inline.} = let parent = node.parentNode if parent != nil: let first = parent.firstChild if node != first: var it = node.internalPrev while true: yield it if it == first: break it = it.internalPrev iterator subsequentSiblings*(node: Node): Node {.inline.} = var it = node.internalNext if it != nil: while it.internalNext != nil: yield it it = it.internalNext iterator elementList*(node: ParentNode): Element {.inline.} = for child in node.childList: if child of Element: yield Element(child) iterator relementList*(node: ParentNode): Element {.inline.} = for child in node.rchildList: if child of Element: yield Element(child) iterator ancestors*(node: Node): Element {.inline.} = var element = node.parentElement while element != nil: yield element element = element.parentElement # inclusive ancestors iterator branch*(node: Node): Node {.inline.} = var node = node while node != nil: yield node node = node.parentNode iterator branchHost(node: Node): Node {.inline.} = var node = node.parentNodeHost while node != nil: yield node node = node.parentNodeHost iterator branchElems*(node: Node): Element {.inline.} = for node in node.branch: if node of Element: yield Element(node) iterator descendants*(node: ParentNode): Node {.inline.} = var it = node.firstChild while it != nil: yield it it = it.nextDescendant(node) iterator descendantsIncl(node: Node): Node {.inline.} = var it = node while it != nil: yield it it = it.nextDescendant(node) iterator descendantsShadowIncl(node: Node): Node {.inline.} = var it = node while it != nil: yield it it = it.nextDescendantShadow(node) iterator elementDescendants*(node: ParentNode): Element {.inline.} = for child in node.descendants: if child of Element: yield Element(child) iterator elementDescendantsIncl(node: Node): Element {.inline.} = for child in node.descendantsIncl: if child of Element: yield Element(child) iterator elementDescendants*(node: ParentNode; tag: TagType): Element {.inline.} = for desc in node.elementDescendants: if desc.tagType == tag: yield desc iterator elementDescendants*(node: ParentNode; tag: set[TagType]): Element {.inline.} = for desc in node.elementDescendants: if desc.tagType in tag: yield desc iterator displayedElements*(window: Window): Element {.inline.} = var element = window.document.documentElement while element != nil: yield element element = element.nextDisplayedElement iterator inputs(form: HTMLFormElement): HTMLInputElement {.inline.} = for control in form.controls: if control of HTMLInputElement: yield HTMLInputElement(control) iterator radiogroup*(input: HTMLInputElement): HTMLInputElement {.inline.} = let name = input.name if name != CAtomNull and name != satUempty.toAtom(): if input.form != nil: for input in input.form.inputs: if input.name == name and input.inputType == itRadio: yield input else: for input in input.document.elementDescendants(TAG_INPUT): let input = HTMLInputElement(input) if input.form == nil and input.name == name and input.inputType == itRadio: yield input iterator textNodes*(node: ParentNode): Text {.inline.} = for node in node.childList: if node of Text: yield Text(node) iterator options*(select: HTMLSelectElement): HTMLOptionElement {.inline.} = for child in select.elementList: if child of HTMLOptionElement: yield HTMLOptionElement(child) elif child of HTMLOptGroupElement: for opt in child.elementList: if opt of HTMLOptionElement: yield HTMLOptionElement(opt) iterator sheets(this: SheetElement): CSSStylesheet {.inline.} = var sheet = this.sheetHead let tail = this.sheetTail while sheet != nil: yield sheet if sheet == tail: break sheet = sheet.next # Window/Global # For now, these are the same; on an API level however, getGlobal is # guaranteed to be non-null, while getWindow may return null in the # future. (This is in preparation for Worker support.) proc getGlobal*(ctx: JSContext): Window = let global = JS_GetGlobalObject(ctx) var window: Window doAssert ctx.fromJSFree(global, window).isOk return window proc getWindow*(ctx: JSContext): Window = let global = JS_GetGlobalObject(ctx) var window: Window doAssert ctx.fromJSFree(global, window).isOk return window proc setWeak(ctx: JSContext; wwm: WindowWeakMap; key, val: JSValue): Opt[void] = let global = ctx.getGlobal() let res = ctx.invokeSink(global.weakMap[wwm], ctx.getOpaque().strRefs[jstSet], key, val) if JS_IsException(res): return err() JS_FreeValue(ctx, res) ok() proc getWeak(ctx: JSContext; wwm: WindowWeakMap; key: JSValueConst): JSValue = let global = ctx.getGlobal() return ctx.invoke(global.weakMap[wwm], ctx.getOpaque().strRefs[jstGet], key) proc isCell(ctx: JSContext; this: Collection; node: Node): Opt[bool] = ok(node of Element and Element(node).tagType in {TAG_TD, TAG_TH}) proc isTBody(ctx: JSContext; this: Collection; node: Node): Opt[bool] = ok(node of Element and Element(node).tagType == TAG_TBODY) proc isRow(ctx: JSContext; this: Collection; node: Node): Opt[bool] = ok(node of Element and Element(node).tagType == TAG_TR) proc isOptionOf(node, select: Node): bool = if node of HTMLOptionElement: let parent = node.parentNode return Node(parent) == select or parent of HTMLOptGroupElement and Node(parent.parentNode) == select return false proc isElement(ctx: JSContext; this: Collection; node: Node): Opt[bool] = ok(node of Element) proc isForm(ctx: JSContext; this: Collection; node: Node): Opt[bool] = ok(node of HTMLFormElement) proc isLink(ctx: JSContext; this: Collection; node: Node): Opt[bool] = if not (node of Element): return ok(false) let element = Element(node) ok(element.tagType in {TAG_A, TAG_AREA} and element.attrb(satHref)) proc isImage(ctx: JSContext; this: Collection; node: Node): Opt[bool] = if not (node of Element): return ok(false) let element = Element(node) ok(element.tagType == TAG_IMG) proc logException(window: Window; url: URL) = #TODO excludepassword seems pointless? window.console.error("Exception in document", url.serialize(excludepassword = true), window.jsctx.getExceptionMsg()) proc newWeakCollection(ctx: JSContext; this: Node; wwm: WindowWeakMap): JSValue = case wwm of wwmChildren: return ctx.toJS(ctx.newHTMLCollection( this, match = isElement, islive = true, childonly = true )) of wwmChildNodes: return ctx.toJS(ctx.newNodeList( this, match = nil, islive = true, childonly = true )) of wwmSelectedOptions: let this = HTMLSelectElement(this) return ctx.toJS(ctx.newHTMLCollection( this, match = proc(ctx: JSContext; this: Collection; node: Node): Opt[bool] = ok(node.isOptionOf(this.root) and HTMLOptionElement(node).selected), islive = true, childonly = false )) of wwmTBodies: return ctx.toJS(ctx.newHTMLCollection( this, match = isTBody, islive = true, childonly = true )) of wwmCells: return ctx.toJS(ctx.newHTMLCollection( this, match = isCell, islive = true, childonly = true )) of wwmDataset: return ctx.toJS(DOMStringMap(target: HTMLElement(this))) of wwmAttributes: let element = Element(this) let map = NamedNodeMap(element: element) for i, attr in element.attrs.mypairs: map.attrlist.add(element.newAttr(i)) return ctx.toJS(map) proc getWeakCollection(ctx: JSContext; this: Node; wwm: WindowWeakMap): JSValue = let jsThis = ctx.toJS(this) if JS_IsException(jsThis): return JS_EXCEPTION let res = ctx.getWeak(wwm, jsThis) if JS_IsUndefined(res): let collection = ctx.newWeakCollection(this, wwm) if JS_IsException(collection): JS_FreeValue(ctx, jsThis) return JS_EXCEPTION if ctx.setWeak(wwm, jsThis, JS_DupValue(ctx, collection)).isErr: return JS_EXCEPTION return collection JS_FreeValue(ctx, jsThis) return res proc isSameOrigin*(window: Window; origin: Origin): bool = if window.dangerAlwaysSameOrigin: # for client return true return window.settings.origin.isSameOrigin(origin) proc fetch*(window: Window; input: Request; finish: FetchFinish; opaque: RootRef) = #TODO cors requests? if input.url.schemeType != stData and not window.isSameOrigin(input.url.origin): return window.loader.fetch(input, finish, opaque) proc corsFetch(window: Window; input: Request; finish: FetchFinish; opaque: RootRef) = if not window.settings.images and input.url.scheme.startsWith("img-codec+"): finish(opaque, nil) return window.loader.fetch(input, finish, opaque) proc sheetLoaded(window: Window) = inc window.loadedSheetNum if window.bc != nil: sheetLoadedImpl(window.bc) proc imageLoaded(window: Window) = inc window.loadedImageNum if window.bc != nil: imageLoadedImpl(window.bc) proc importSheetFinish(window: Window; this: SheetElement; res: LoadSheetResult; env: ParseSheetEnv; i: int) = env.sheets[i] = res inc env.loaded if env.loaded == env.sheets.len: var head: CSSStylesheet = env.sheet var tail: CSSStylesheet = env.sheet for res in env.sheets: if res.head != nil: #TODO check import media query here if tail == nil: head = res.head else: tail.next = res.head tail = res.tail env.finish(window, this, LoadSheetResult(head: head, tail: tail), env.parent, env.i) window.sheetLoaded() proc parseStylesheet(window: Window; this: SheetElement; s: string; baseURL: URL; charset: Charset; layer: CAtom; finish: LoadSheetFinish; parseEnv: ParseSheetEnv; i: int) = let sheet = s.parseStylesheet(baseURL, addr window.settings, coAuthor, layer) if sheet.s.importList.len == 0: let res = LoadSheetResult(head: sheet, tail: sheet) finish(window, this, res, parseEnv, i) else: var env = ParseSheetEnv( sheet: sheet, sheets: newSeq[LoadSheetResult](sheet.s.importList.len), finish: finish, parent: parseEnv, i: i ) for i, it in sheet.s.importList.mypairs: let url = it.url let layer = it.layer inc window.remoteSheetNum window.loadSheet(this, url, charset, layer, importSheetFinish, i, env) proc cssDecode(iq: openArray[char]; fallback: Charset): string = var charset = fallback var offset = 0 const charsetRule = "@charset \"" if iq.startsWith("\xFE\xFF"): charset = csUtf16be offset = 2 elif iq.startsWith("\xFF\xFE"): charset = csUtf16le offset = 2 elif iq.startsWith("\xEF\xBB\xBF"): charset = csUtf8 offset = 3 elif iq.startsWith(charsetRule): let s = iq.toOpenArray(charsetRule.len, min(1024, iq.high)).until('"') let n = charsetRule.len + s.len if n >= 0 and n + 1 < iq.len and iq[n] == '"' and iq[n + 1] == ';': charset = getCharset(s) if charset in {csUtf16le, csUtf16be}: charset = csUtf8 iq.toOpenArray(offset, iq.high).decodeAll(charset) proc onFinishCSSText(response: Response; success: bool) = let blob = response.onFinishBlob(success) let env = LoadSheetEnv(response.opaque) let window = env.window let this = env.this let finish = env.finish if blob != nil: let charset = env.charset let s = blob.toOpenArray().cssDecode(charset) window.parseStylesheet(this, s, env.url, charset, env.layer, finish, env.parseEnv, env.i) else: finish(window, this, LoadSheetResult(), env.parseEnv, env.i) proc loadSheet0(opaque: RootRef; response: Response) = let env = LoadSheetEnv(opaque) let window = env.window if response != nil: if response.getContentType().equalsIgnoreCase("text/css"): response.onFinish = onFinishCSSText window.loader.blob(response, env) return window.loader.close(response) env.finish(window, env.this, LoadSheetResult(), env.parseEnv, env.i) proc loadSheet(window: Window; this: SheetElement; url: URL; charset: Charset; layer: CAtom; finish: LoadSheetFinish; i: int; parseEnv: ParseSheetEnv) = let env = LoadSheetEnv( window: window, this: this, url: url, charset: charset, layer: layer, parseEnv: parseEnv, i: i, finish: finish ) window.corsFetch(newRequest(url), loadSheet0, env) proc loadSheet(window: Window; this: SheetElement; url: URL; finish: LoadSheetFinish) = let charset = this.getCharset() window.loadSheet(this, url, charset, CAtomNull, finish, 0, nil) proc loadLinkFinish(window: Window; this: SheetElement; res: LoadSheetResult; env: ParseSheetEnv; i: int) = let link = HTMLLinkElement(this) let media = link.attr(satMedia) var applies = true if media != "": var ctx = initCSSParser(media) let media = ctx.parseMediaQueryList(window.settings.attrsp) applies = media.applies(addr window.settings) # Note: we intentionally load all sheets first and *then* check # whether media applies, to prevent media query based tracking. #TODO should we really keep the current sheet if the result is nil? if res.head != nil: link.updateSheet(res.head, res.tail) let disabled = link.isDisabled() for sheet in link.sheets: sheet.disabled = disabled sheet.applies = applies sheet.media = media window.sheetLoaded() proc loadLink(window: Window; link: HTMLLinkElement) = if not window.settings.styling or not link.relList.containsIgnoreCase(satStylesheet) or link.fetchStarted or link.isDisabled(): return link.fetchStarted = true let href = link.attr(satHref) if href == "": return if url := parseURL(href, window.document.url): inc window.remoteSheetNum window.loadSheet(link, url, loadLinkFinish) proc getImageId(window: Window): int = result = window.imageId inc window.imageId proc fireEvent*(window: Window; event: Event; target: EventTarget) = discard window.jsctx.dispatch(target, event) proc fireEvent*(window: Window; name: StaticAtom; target: EventTarget; bubbles, cancelable, trusted: bool) = let event = newEvent(name.toAtom(), target, bubbles, cancelable) event.isTrusted = trusted window.fireEvent(event, target) proc loadImageFinish(opaque: RootRef; response: Response) = let cachedURL = CachedURLImage(opaque) let window = cachedURL.window if response == nil: window.imageLoaded() return # close immediately; all data we're interested in is in the headers. window.loader.close(response) let headers = response.headers let dims = headers.getFirst("Cha-Image-Dimensions") let width = parseIntP(dims.until('x')).get(-1) let height = parseIntP(dims.after('x')).get(-1) if width < 0 or height < 0: window.console.error("wrong Cha-Image-Dimensions in", $response.url) window.imageLoaded() return let bmp = NetworkBitmap( width: width, height: height, cacheId: cachedURL.cacheId, imageId: window.getImageId(), contentType: "image/" & cachedURL.t, vector: cachedURL.t == "image/svg+xml" ) cachedURL.bmp = bmp for share in cachedURL.shared: share.bitmap = bmp share.invalidate() #TODO fire error on error if window.settings.scripting != smFalse: window.fireEvent(satLoad, share, bubbles = false, cancelable = false, trusted = true) window.imageLoaded() proc loadImage0(opaque: RootRef; response: Response) = let cachedURL = CachedURLImage(opaque) let window = cachedURL.window if response == nil: window.imageLoaded() return let contentType = response.getContentType("image/x-unknown") if not contentType.startsWith("image/"): window.imageLoaded() return var t = contentType.after('/') if t == "x-unknown": let ext = response.url.pathname.getFileExt() # Note: imageTypes is taken from mime.types. # To avoid fingerprinting, we # a) always download the entire image (through addCacheFile) - # this prevents the server from knowing what content type # is supported # b) prevent mime.types extensions for images defined by # ourselves # In fact, a) would by itself be enough, but I'm not sure if # it's the best way, so I added b) as a fallback measure. t = window.imageTypes.getOrDefault(ext, "x-unknown") cachedURL.cacheId = window.loader.addCacheFile(response.outputId) let url = parseURL0("img-codec+" & t & ":decode") if url == nil: window.imageLoaded() return let request = newRequest( url, httpMethod = hmPost, headers = newHeaders(hgRequest, {"Cha-Image-Info-Only": "1"}), body = RequestBody(t: rbtOutput, outputId: response.outputId), ) cachedURL.t = t window.corsFetch(request, loadImageFinish, opaque) window.loader.close(response) var expiry = -1i64 for s in response.headers.getAllCommaSplit("Cache-Control"): if s.startsWithIgnoreCase("max-age="): let i = s.skipBlanks("max-age=".len) let s = s.until(NonDigit, i) if pi := parseInt64(s): expiry = getTime().toUnix() + pi break cachedURL.loading = false cachedURL.expiry = expiry proc loadImageFromCache(window: Window; image: HTMLImageElement; surl: string): bool = let cachedURL = window.imageURLCache.getOrDefault(surl) if cachedURL == nil: return false if cachedURL.expiry > getTime().toUnix(): image.bitmap = cachedURL.bmp return true if cachedURL.loading: cachedURL.shared.add(image) return true false proc loadImage*(window: Window; image: HTMLImageElement) = if not window.settings.images: if image.bitmap != nil: image.invalidate() image.bitmap = nil image.fetchStarted = false return if image.fetchStarted: return image.fetchStarted = true let src = image.attr(satSrc) if src == "": return let url0 = parseURL(src, window.document.url) if url0.isErr: return let url = url0.get if window.document.url.schemeType == stHttps and url.schemeType == stHttp: # mixed content :/ #TODO maybe do this in loader? url.setProtocol("https") let surl = $url if window.loadImageFromCache(image, surl): return let cachedURL = CachedURLImage( cacheId: -1, window: window, expiry: -1, loading: true, shared: @[image] ) window.imageURLCache[surl] = cachedURL let headers = newHeaders(hgRequest, {"Accept": "*/*"}) inc window.remoteImageNum window.corsFetch(newRequest(url, headers = headers), loadImage0, cachedURL) type LoadSVGEnv = ref object of RootObj window: Window svg: SVGSVGElement cacheId: int imageId: int proc loadSVGFinish(opaque: RootRef; response: Response) = let env = LoadSVGEnv(opaque) let window = env.window let svg = env.svg if response == nil: # no SVG module; give up window.imageLoaded() return let loader = window.loader # close immediately; all data we're interested in is in the headers. loader.close(response) let dims = response.headers.getFirst("Cha-Image-Dimensions") let width = parseIntP(dims.until('x')).get(-1) let height = parseIntP(dims.after('x')).get(-1) if width < 0 or height < 0: window.console.error("wrong Cha-Image-Dimensions in", $response.url) window.imageLoaded() return svg.bitmap = NetworkBitmap( width: width, height: height, cacheId: env.cacheId, imageId: env.imageId, contentType: "image/svg+xml", vector: true ) for share in svg.shared: share.bitmap = svg.bitmap share.invalidate() svg.invalidate() window.imageLoaded() proc loadSVG*(window: Window; svg: SVGSVGElement) = if not window.settings.images: if svg.bitmap != nil: svg.invalidate() svg.bitmap = nil svg.fetchStarted = false return if svg.fetchStarted: return svg.fetchStarted = true let s = svg.outerHTML if s.len <= 4096: # try to dedupe if the SVG is small enough. window.svgCache.withValue(s, elp): svg.bitmap = elp.bitmap if svg.bitmap != nil: # already decoded svg.invalidate() else: # tell me when you're done elp.shared.add(svg) return window.svgCache[s] = svg let imageId = window.getImageId() let loader = window.loader let (ps, svgres) = loader.doPipeRequest("svg-" & $imageId) if ps == nil: return let cacheId = loader.addCacheFile(svgres.outputId) let res = ps.writeLoop(s) ps.sclose() if res.isErr: return let request = newRequest( "img-codec+svg+xml:decode", httpMethod = hmPost, headers = newHeaders(hgRequest, {"Cha-Image-Info-Only": "1"}), body = RequestBody(t: rbtOutput, outputId: svgres.outputId) ) let env = LoadSVGEnv( window: window, svg: svg, cacheId: cacheId, imageId: imageId ) inc window.remoteImageNum loader.fetch(request, loadSVGFinish, env) loader.close(svgres) proc navigate*(window: Window; url: URL) = if window.bc != nil: navigateImpl(window.bc, url) proc ensureLayout(window: Window; element: Element) = if window.bc != nil: ensureLayoutImpl(window.bc, element) proc click(window: Window; element: HTMLElement) = if window.bc != nil: clickImpl(window.bc, element) proc runJSJobs*(window: Window) = let rt = JS_GetRuntime(window.jsctx) while true: let ctx = rt.runJSJobs() if ctx == nil: break window.console.writeException(ctx) proc performMicrotaskCheckpoint*(window: Window) = if window.inMicrotaskCheckpoint: return window.inMicrotaskCheckpoint = true window.runJSJobs() window.inMicrotaskCheckpoint = false proc windowChange*(window: Window) = let document = window.document document.ruleMap = nil if document.documentElement != nil: document.documentElement.invalidate() let baseURL = document.baseURL var sheet = document.uaSheetsHead while sheet != nil: sheet.windowChange(baseURL) sheet = sheet.next if document.userSheet != nil: document.userSheet.windowChange(baseURL) sheet = document.authorSheetsHead while sheet != nil: sheet.windowChange(baseURL) if sheet.media != "": var ctx = initCSSParser(sheet.media) let media = ctx.parseMediaQueryList(window.settings.attrsp) sheet.applies = media.applies(addr window.settings) sheet = sheet.next proc getComputedStyle0*(ctx: JSContext; window: Window; element: Element; pseudoElt: JSValueConst): Opt[CSSStyleDeclaration] = if not element.isConnected(): return ok(newCSSStyleDeclaration(nil, "")) var pseudo = peNone if not JS_IsUndefined(pseudoElt): # This isn't what the spec says, but it seems to be what others do. # Note: in Gecko this is case-sensitive, in Blink it isn't. CSS itself # is case-insensitive so I assume it's a Gecko bug. var s: string ?ctx.fromJS(pseudoElt, s) let i = if s.startsWith("::"): 2 elif s.startsWith(":"): 1 else: 0 if i != 0: # if no : at the beginning, ignore pseudoElt pseudo = parseEnumNoCase[PseudoElement](s.substr(i)).get(peNone) if pseudo == peNone or pseudo notin {peBefore, peAfter} and i == 1: return ok(newCSSStyleDeclaration(nil, "")) if window.settings.scripting == smApp: element.ensureStyle() return ok(newCSSStyleDeclaration(element, $element.getComputedStyle(pseudo), computed = true, readonly = true)) # In lite mode, we just parse the "style" attribute and hope for # the best. ok(newCSSStyleDeclaration(element, element.attr(satStyle), computed = true, readonly = true)) proc addCustomElementRegistry*(window: Window; rt: JSRuntime) = window.customElements = CustomElementRegistry(rt: rt) # CustomElementRegistry iterator defs(this: CustomElementRegistry): CustomElementDef = var def = this.defsHead while def != nil: yield def def = def.next proc newCustomElementRegistry(ctx: JSContext): CustomElementRegistry {.jsctor.} = return CustomElementRegistry(rt: JS_GetRuntime(ctx), scoped: true) proc mark(rt: JSRuntime; this: CustomElementRegistry; markFunc: JS_MarkFunc) {.jsmark.} = for def in this.defs: JS_MarkValue(rt, def.ctor, markFunc) for val in def.callbacks: JS_MarkValue(rt, val, markFunc) proc finalize(this: CustomElementRegistry) {.jsfin.} = let rt = this.rt for def in this.defs: JS_FreeValueRT(rt, def.ctor) rt.freeValues(def.callbacks) type CustomElementDefinitionOptions = object of JSDict extends {.jsdefault.}: Option[string] proc find(this: CustomElementRegistry; name: CAtom): CustomElementDef = for it in this.defs: if it.name == name: return it return nil proc find(this: CustomElementRegistry; ctx: JSContext; ctor: JSValueConst): CustomElementDef = for it in this.defs: if ctx.strictEquals(it.ctor, ctor): return it return nil proc tryGetStrSeq(ctx: JSContext; ctor: JSValueConst; name: cstring; res: var seq[string]): Opt[void] = let val = JS_GetPropertyStr(ctx, ctor, name) if JS_IsException(val): return err() if not JS_IsUndefined(val): ?ctx.fromJSFree(val, res) ok() proc tryGetCallback(ctx: JSContext; proto: JSValueConst; t: CECallbackType; callbacks: var CECallbackMap): Opt[void] = let val = JS_GetPropertyStr(ctx, proto, cstring($t)) if JS_IsException(val): return err() if not JS_IsUndefined(val): callbacks[t] = val # val is freed by caller if not JS_IsFunction(ctx, val): JS_ThrowTypeError(ctx, "lifecycle callback is not a function") return err() ok() proc define0(ctx: JSContext; this: CustomElementRegistry; name: CAtom; ctor, proto: JSValueConst; def: CustomElementDef): Opt[void] = if not JS_IsObject(proto): JS_ThrowTypeError(ctx, "prototype is not an object") return err() for t in cctConnected..cctAttributeChanged: ?ctx.tryGetCallback(proto, t, def.callbacks) if not JS_IsNull(def.callbacks[cctAttributeChanged]): ?ctx.tryGetStrSeq(ctor, "observedAttributes", def.observedAttrs) var disabled: seq[string] ?ctx.tryGetStrSeq(ctor, "disabledFeatures", disabled) if "internals" in disabled: def.flags.excl(cefInternals) if "shadow" in disabled: def.flags.excl(cefShadow) var formAssociated: bool discard ?ctx.fromJSGetProp(ctor, "formAssociated", formAssociated) if formAssociated: def.flags.incl(cefFormAssociated) for t in cctFormAssociated..cctFormStateRestore: ?ctx.tryGetCallback(proto, t, def.callbacks) ok() proc newCustomElementDef(name, localName: CAtom): CustomElementDef = let def = CustomElementDef( name: name, localName: localName, flags: {cefInternals, cefShadow} ) for it in def.callbacks.mitems: it = JS_NULL return def proc define(ctx: JSContext; this: CustomElementRegistry; name: CAtom; ctor: JSValueConst; options = CustomElementDefinitionOptions()): JSValue {.jsfunc.} = if not JS_IsConstructor(ctx, ctor): return JS_ThrowTypeError(ctx, "constructor expected") if this.find(name) != nil or this.find(ctx, ctor) != nil: return JS_ThrowDOMException(ctx, "NotSupportedError", "a custom element with this name/constructor is already defined") if options.extends.isSome: #TODO extends return JS_ThrowDOMException(ctx, "NotSupportedError", "extends not supported yet") if this.inDefine: return JS_ThrowDOMException(ctx, "NotSupportedError", "recursive custom element definition is not allowed") this.inDefine = true let proto = JS_GetPropertyStr(ctx, ctor, "prototype") if JS_IsException(proto): this.inDefine = false return JS_EXCEPTION let def = newCustomElementDef(name, name) #TODO extends/localName let res = ctx.define0(this, name, ctor, proto, def) JS_FreeValue(ctx, proto) this.inDefine = false if res.isErr: ctx.freeValues(def.callbacks) return JS_EXCEPTION def.ctor = JS_DupValue(ctx, ctor) if this.defsTail == nil: this.defsHead = def else: this.defsTail.next = def this.defsTail = def #TODO is scoped #TODO upgrade #TODO when-defined return JS_UNDEFINED proc get(ctx: JSContext; this: CustomElementRegistry; name: CAtom): JSValue {.jsfunc.} = let def = this.find(name) if def != nil: return JS_DupValue(ctx, def.ctor) return JS_UNDEFINED proc getName(ctx: JSContext; this: CustomElementRegistry; ctor: JSValueConst): CAtom {.jsfunc.} = let def = this.find(ctx, ctor) if def != nil: return def.name return CAtomNull #TODO whenDefined, initialize proc addScopedDocument(this: CustomElementRegistry; document: Document) = if document notin this.scopedDocuments: this.scopedDocuments.add(document) # Node when defined(debug): proc `$`*(node: Node): string = if node == nil: return "null" result = "" result.serializeFragmentInner(node, TAG_UNKNOWN, writeShadow = true) proc baseURI(node: Node): string {.jsfget.} = return $node.document.baseURL proc document*(node: Node): Document = let next = node.internalNext if next == nil: return Document(node) if next.internalNext == nil: return Document(next) return Document(next.parentNode.firstChild.internalPrev.internalNext) proc parentNodeShadow(node: Node): Node = let parent = node.parentNode if parent == nil and node of ShadowRoot: return ShadowRoot(node).host return parent proc parentNodeHost(node: Node): Node = let parent = node.parentNode if parent == nil and node of DocumentFragment: return DocumentFragment(node).host return parent proc parentElement*(node: Node): Element {.jsfget.} = let p = node.parentNode if p != nil and p of Element: return Element(p) return nil proc nextSiblingShadow(node: Node): Node = if node.internalNext == nil or node.internalNext.internalNext == nil: # if next is nil, then node is a Document. # if next.next is nil, then next is ownerDocument. return nil return node.internalNext proc nextSibling*(node: Node): Node {.jsfget.} = if node.parentNode == nil: # if parent is nil, then may be a shadow root return nil return node.nextSiblingShadow proc previousSibling*(node: Node): Node {.jsfget.} = if node.parentNode == nil or node == node.parentNode.firstChild: return nil return node.internalPrev # Return the next descendant if it isn't `start', and nil otherwise. # Note: `start' must be either an ancestor of `node', `node` itself, or nil. proc nextDescendant(node, start: Node): Node = if node of ParentNode: # parent let node = cast[ParentNode](node) if node.firstChild != nil: return node.firstChild # climb up until we find a non-last leaf (this might be node itself) var node = node while node != start: let next = node.nextSibling if next != nil: return next node = node.parentNode # done return nil proc nextDescendantShadow(node, start: Node): Node = if node of ParentNode: # parent let node = cast[ParentNode](node) if node.firstChildShadow != nil: return node.firstChildShadow # climb up until we find a non-last leaf (this might be node itself) var node = node while node != start: let next = node.nextSiblingShadow if next != nil: return next node = node.parentNodeShadow # done return nil proc previousDescendant(node: Node): Node = let prev = node.previousSibling if prev == nil: return node.parentNode var node = prev while node of ParentNode: let pnode = cast[ParentNode](node) if pnode.firstChild == nil: break node = pnode.lastChild return node proc ownerDocument(node: Node): Document {.jsfget.} = if node of Document: return nil return node.document proc jsNodeType0(node: Node): NodeType = if node of CharacterData: if node of Text: return ntText elif node of Comment: return ntComment elif node of CDATASection: return ntCdataSection else: # ProcessingInstruction return ntProcessingInstruction elif node of Element: return ntElement elif node of Document: return ntDocument elif node of DocumentType: return ntDocumentType elif node of Attr: return ntAttribute else: # DocumentFragment return ntDocumentFragment proc nodeType(node: Node): uint16 {.jsfget.} = return uint16(node.jsNodeType0) proc nodeName(node: Node): string {.jsfget.} = if node of Element: return Element(node).tagName if node of Attr: return $Attr(node).data.qualifiedName if node of DocumentType: return DocumentType(node).name if node of CDATASection: return "#cdata-section" if node of Comment: return "#comment" if node of Document: return "#document" if node of DocumentFragment: return "#document-fragment" if node of ProcessingInstruction: return ProcessingInstruction(node).target assert node of Text return "#text" proc isValidChild(node: Node): bool = return node of DocumentFragment or node of DocumentType or node of Element or node of CharacterData proc checkParentValidity(parent: Node): Result[ParentNode, cstring] = if parent of ParentNode: return ok(cast[ParentNode](parent)) return err("parent must be a document, a document fragment, or an element") proc rootNode(node: Node): Node = var node = node while node.parentNode != nil: node = node.parentNode return node proc rootNodeShadow(node: Node): Node = var node = node while (let parent = node.parentNodeShadow; parent != nil): node = parent node proc isInclusiveAncestorHost(a, b: Node): bool = for it in b.branchHost: if it == a: return true return false proc hasNextSibling(node: Node; nodeType: type): bool = var node = node.nextSibling while node != nil: if node of nodeType: return true node = node.nextSibling return false proc hasPreviousSibling(node: Node; nodeType: type): bool = var node = node.previousSibling while node != nil: if node of nodeType: return true node = node.previousSibling return false proc nodeValue(ctx: JSContext; node: Node): JSValue {.jsfget.} = if node of CharacterData: return ctx.toJS(CharacterData(node).data) elif node of Attr: return ctx.toJS(Attr(node).data.value) return JS_NULL proc textContent*(node: Node): string = result = "" if node of CharacterData: result = CharacterData(node).data.s elif node of ParentNode: let node = ParentNode(node) for child in node.childList: if not (child of Comment): result &= child.textContent proc textContent(ctx: JSContext; node: Node): JSValue {.jsfget.} = if node of Document or node of DocumentType: return JS_NULL return ctx.toJS(node.textContent) proc isConnected(node: Node): bool {.jsfget.} = return node.rootNodeShadow of Document proc inSameTree*(a, b: Node): bool = a.rootNode == b.rootNode # a == b or a in b's ancestors proc contains(a, b: Node): bool {.jsfunc.} = if b != nil: for node in b.branch: if node == a: return true return false proc jsParentNode(node: Node): Node {.jsfget: "parentNode".} = return node.parentNode proc firstChild(node: Node): Node {.jsfget.} = if node of ParentNode: return cast[ParentNode](node).firstChild nil proc lastChild*(node: Node): Node {.jsfget.} = let first = node.firstChild if first != nil: return first.internalPrev nil proc hasChildNodes(node: Node): bool {.jsfunc.} = return node.firstChild != nil # WARNING the ordering of the arguments in the standard is whack so this # doesn't match that proc preInsertionValidity(parent, node, before: Node): Result[ParentNode, cstring] = let parent = ?parent.checkParentValidity() if node.isInclusiveAncestorHost(parent): return err("parent must be an ancestor") if before != nil and before.parentNode != parent: return err(nil) if not node.isValidChild(): return err("node is not a valid child") if node of Text and parent of Document: return err("cannot insert text into document") if node of DocumentType and not (parent of Document): return err("document type can only be inserted into document") if parent of Document: if node of DocumentFragment: let node = DocumentFragment(node) let elems = node.countChildren(Element) if elems > 1 or node.hasChild(Text): return err("document fragment has invalid children") elif elems == 1 and (parent.hasChild(Element) or before != nil and (before of DocumentType or before.hasNextSibling(DocumentType))): return err("document fragment has invalid children") elif node of Element: if parent.hasChild(Element): return err("document already has an element child") elif before != nil and (before of DocumentType or before.hasNextSibling(DocumentType)): return err("cannot insert element before document type") elif node of DocumentType: if parent.hasChild(DocumentType) or before != nil and before.hasPreviousSibling(Element) or before == nil and parent.hasChild(Element): return err("cannot insert document type before an element node") else: discard ok(parent) # Pass an index to avoid searching for the node in parent's child list. proc remove*(node: Node; suppressObservers: bool) = let parent = node.parentNode let document = node.document # document is only nil for Document nodes, but those cannot call # remove(). assert parent != nil and document != nil #TODO live ranges #TODO NodeIterator let element = if node of Element: Element(node) else: nil let parentElement = node.parentElement if parentElement != nil: parentElement.invalidate() let prev = node.internalPrev let next = node.internalNext if next != nil and next.internalNext != nil: next.internalPrev = prev else: parent.firstChild.internalPrev = prev if parent.firstChild == node: if next != nil and next.internalNext != nil: parent.setFirstChild(next) else: parent.setFirstChild(nil) else: prev.internalNext = next node.internalPrev = nil node.internalNext = document node.parentNode = nil document.invalidateCollections() var hasSlot = false if element != nil: if parentElement == nil: element.invalidate() element.box = nil if element.internalElIndex == 0 and parentElement != nil: parentElement.childElIndicesInvalid = true element.internalElIndex = -1 if element of SheetElement: SheetElement(element).removeSheet() for desc in element.elementDescendantsIncl: desc.applyStyleDependencies(DependencyInfo.default) hasSlot = desc.tagType == TAG_SLOT #TODO assigned let root = parent.rootNode if root of ShadowRoot: let shadow = ShadowRoot(root) discard shadow #TODO signal slot change if parent is slot without assigned nodes if hasSlot: #TODO assign slottables for tree with root #TODO assign slottables for tree with node discard #TODO removing steps let parentConnected = root.isConnected #TODO if node is custom and connected, disconnectedcallback for desc in element.descendantsShadowIncl: #TODO removing steps if desc of Element: let element = Element(desc) if element.custom == cesCustom and parentConnected: discard #TODO call disconnectedCallback #TODO registered observers if not suppressObservers: discard #TODO queue tree mutation record #TODO children changed steps proc remove*(node: Node) = if node.parentNode != nil: node.remove(suppressObservers = false) # e may be nil proc insertThrow(ctx: JSContext; e: cstring): JSValue = if e == nil: return JS_ThrowDOMException(ctx, "NotFoundError", "reference node is not a child of parent") return JS_ThrowDOMException(ctx, "HierarchyRequestError", e) proc removeChild(ctx: JSContext; parent, node: Node): JSValue {.jsfunc.} = if Node(node.parentNode) != parent: return ctx.insertThrow(nil) node.remove() return ctx.toJS(node) # before may be nil proc insertBefore(parent, node, before: Node): Err[cstring] = let parent = ?parent.preInsertionValidity(node, before) let referenceChild = if before == node: node.nextSibling else: before parent.insert(node, referenceChild) ok() proc insertBefore(ctx: JSContext; parent, node: Node; before: Option[Node]): JSValue {.jsfunc.} = let res = parent.insertBefore(node, before.get(nil)) if res.isErr: return ctx.insertThrow(res.error) return ctx.toJS(node) proc insertBeforeUndefined(ctx: JSContext; parent, node: Node; before: Option[Node]): JSValue = let res = parent.insertBefore(node, before.get(nil)) if res.isErr: return ctx.insertThrow(res.error) return JS_UNDEFINED proc appendChild(ctx: JSContext; parent, node: Node): JSValue {.jsfunc.} = return ctx.insertBefore(parent, node, none(Node)) #TODO this looks wrong. either pre-insert and throw or just insert... proc append(parent, node: Node) = discard parent.insertBefore(node, nil) # WARNING the ordering of the arguments in the standard is whack so this # doesn't match that # Note: the standard returns child if not err. We don't, it's just a # pointless copy. proc replace*(parent, child, node: Node): Err[cstring] = let parent = ?parent.checkParentValidity() if node.isInclusiveAncestorHost(parent): return err("parent must be an ancestor") if child.parentNode != parent: return err(nil) if not node.isValidChild(): return err("node is not a valid child") if node of Text and parent of Document or node of DocumentType and not (parent of Document): return err("replacement cannot be placed in parent") let childNextSibling = child.nextSibling let childPreviousSibling = child.previousSibling if parent of Document: if node of DocumentFragment: let node = DocumentFragment(node) let elems = node.countChildren(Element) if elems > 1 or node.hasChild(Text): return err("document fragment has invalid children") elif elems == 1 and (parent.hasChildExcept(Element, child) or childNextSibling != nil and childNextSibling of DocumentType): return err("document fragment has invalid children") elif node of Element: if parent.hasChildExcept(Element, child): return err("document already has an element child") elif childNextSibling != nil and childNextSibling of DocumentType: return err("cannot insert element before document type") elif node of DocumentType: if parent.hasChildExcept(DocumentType, child) or childPreviousSibling != nil and childPreviousSibling of DocumentType: return err("cannot insert document type before an element node") let referenceChild = if childNextSibling == node: node.nextSibling else: childNextSibling #NOTE the standard says "if parent is not null", but the adoption step # that made it necessary has been removed. child.remove(suppressObservers = true) parent.insert(node, referenceChild, suppressObservers = true) #TODO tree mutation record ok() proc replaceChild(ctx: JSContext; parent, node, child: Node): JSValue {.jsfunc.} = let res = parent.replace(child, node) if res.isErr: return ctx.insertThrow(res.error) return ctx.toJS(child) proc replaceChildUndefined(ctx: JSContext; parent, node, child: Node): JSValue = let res = parent.replace(child, node) if res.isErr: return ctx.insertThrow(res.error) return JS_UNDEFINED proc clone(node: Node; document = none(Document); deep = false): Node = let document = document.get(node.document) let copy = if node of Element: #TODO is value let element = Element(node) let x = document.newElement(element.localName, element.namespaceURI, element.prefix) x.id = element.id x.name = element.name x.classList = x.newDOMTokenList(satClass) x.attrs = element.attrs #TODO namespaced attrs? # Cloning steps if x of HTMLScriptElement: let x = HTMLScriptElement(x) let element = HTMLScriptElement(element) x.alreadyStarted = element.alreadyStarted elif x of HTMLInputElement: let x = HTMLInputElement(x) let element = HTMLInputElement(element) x.inputType = element.inputType x.setValue(element.value) #TODO dirty value flag x.setChecked(element.checked) #TODO dirty checkedness flag Node(x) elif node of Attr: let attr = Attr(node) let data = attr.data let dummy = AttrDummyElement( internalNext: attr.ownerElement.document, internalElIndex: -1, attrs: @[data] ) Node(dummy.newAttr(0)) elif node of Text: let text = Text(node) let x = document.newText(text.data.s) Node(x) elif node of CDATASection: let x = document.newCDATASection("") #TODO is this really correct?? # really, I don't know. only relevant with xhtml anyway... Node(x) elif node of Comment: let comment = Comment(node) let x = document.newComment(comment.data.s) Node(x) elif node of ProcessingInstruction: let procinst = ProcessingInstruction(node) let x = document.newProcessingInstruction(procinst.target, procinst.data.s) Node(x) elif node of Document: let document = Document(node) let x = newDocument(document.url) x.charset = document.charset x.contentType = document.contentType x.origin = document.origin x.mode = document.mode Node(x) elif node of DocumentType: let doctype = DocumentType(node) let x = document.newDocumentType(doctype.name, doctype.publicId, doctype.systemId) Node(x) elif node of DocumentFragment: let x = document.newDocumentFragment() Node(x) else: assert false Node(nil) if deep and node of ParentNode: let node = ParentNode(node) for child in node.childList: copy.append(child.clone(deep = true)) return copy proc cloneNode(ctx: JSContext; node: Node; deep = false): JSValue {.jsfunc.} = if node of ShadowRoot: return JS_ThrowDOMException(ctx, "NotSupportedError", "cannot clone shadow roots") let copy = node.clone(deep = deep) if node of Element: let element = Element(node) let shadow = element.shadowRoot if shadow != nil: let customElements = shadow.globalCustomElements let x = ctx.attachShadow(Element(copy), ShadowRootInit( mode: shadow.mode, serializable: shadow.serializable, delegatesFocus: shadow.delegatesFocus, slotAssignment: shadow.slotAssignment, customElementRegistry: customElements )) if x.isErr: return JS_EXCEPTION let copyShadow = x.get copyShadow.declarative = shadow.declarative copyShadow.unsetCustomElements = shadow.unsetCustomElements for child in shadow.childList: copyShadow.append(child.clone(deep = deep)) return ctx.toJS(copy) proc isSameNode(node, other: Node): bool {.jsfunc.} = return node == other proc previousElementSiblingImpl(this: Node): Element = for it in this.precedingSiblings: if it of Element: return Element(it) nil proc nextElementSiblingImpl(this: Node): Element = for it in this.subsequentSiblings: if it of Element: return Element(it) nil proc childNodes(ctx: JSContext; node: Node): JSValue {.jsfget.} = return ctx.getWeakCollection(node, wwmChildNodes) proc isEqualNode(node, other: Node): bool {.jsfunc.} = if node of DocumentType: if not (other of DocumentType): return false let node = DocumentType(node) let other = DocumentType(other) if node.name != other.name or node.publicId != other.publicId or node.systemId != other.systemId: return false elif node of ParentNode: let node = ParentNode(node) if node of Element: let node = Element(node) if not (other of ParentNode): return false let other = Element(other) if node.namespaceURI != other.namespaceURI or node.prefix != other.prefix or node.localName != other.localName or node.attrs.len != other.attrs.len: return false for i, attr in node.attrs.mypairs: if attr != other.attrs[i]: return false var it = other.firstChild for child in node.childList: if it == nil or not child.isEqualNode(it): return false it = it.nextSibling elif node of Attr: if not (other of Attr): return false if Attr(node).data != Attr(other).data: return false elif node of ProcessingInstruction: if not (other of ProcessingInstruction): return false let node = ProcessingInstruction(node) let other = ProcessingInstruction(other) if node.target != other.target or node.data != other.data: return false elif node of CharacterData: if node of Text and not (other of Text) or node of Comment and not (other of Comment): return false return CharacterData(node).data == CharacterData(other).data true proc serializeFragmentInner(res: var string; child: Node; parentType: TagType; writeShadow: bool) = if child of Element: let element = Element(child) let tags = $element.localName res &= '<' #TODO qualified name if not HTML, SVG or MathML res &= tags #TODO custom elements for attr in element.attrs: res &= ' ' & $attr.qualifiedName & "=\"" & attr.value.htmlEscape(mode = emAttribute) & "\"" res &= '>' res.serializeFragment(element, writeShadow) res &= "</" & tags & '>' elif child of Text: let text = Text(child) const LiteralTags = { TAG_STYLE, TAG_SCRIPT, TAG_XMP, TAG_IFRAME, TAG_NOEMBED, TAG_NOFRAMES, TAG_PLAINTEXT, TAG_NOSCRIPT } if parentType in LiteralTags: res &= text.data.s else: res &= text.data.s.htmlEscape(mode = emText) elif child of Comment: res &= "<!--" & Comment(child).data.s & "-->" elif child of ProcessingInstruction: let inst = ProcessingInstruction(child) res &= "<?" & inst.target & " " & inst.data.s & '>' elif child of DocumentType: res &= "<!DOCTYPE " & DocumentType(child).name & '>' proc serializeFragment(res: var string; node: Node; writeShadow: bool) = var node = node var parentType = TAG_UNKNOWN if node of Element: let element = Element(node) const Extra = {TAG_BASEFONT, TAG_BGSOUND, TAG_FRAME, TAG_KEYGEN, TAG_PARAM} if element.tagType in VoidElements + Extra: return if element of HTMLTemplateElement: node = HTMLTemplateElement(element).content else: parentType = element.tagType if parentType == TAG_NOSCRIPT and not element.scriptingEnabled: # Pretend parentType is not noscript, so we do not append literally # in serializeFragmentInner. parentType = TAG_UNKNOWN let shadow = element.shadowRoot if shadow != nil and writeShadow and shadow.serializable: res &= "<template shadowrootmode=\"" & $shadow.mode & '"' if shadow.delegatesFocus: res &= " shadowrootdelegatesfocus=\"\"" if shadow.serializable: res &= " shadowrootserializable=\"\"" if shadow.clonable: res &= " shadowrootclonable=\"\"" let docCustomElements = node.document.customElements let shadowCustomElements = shadow.customElements if docCustomElements != nil and not docCustomElements.scoped or shadowCustomElements != nil and not shadowCustomElements.scoped: res &= " shadowrootcustomelementregistry=\"\"" res &= '>' res.serializeFragment(shadow, writeShadow) res &= "</template>" if node of ParentNode: let node = ParentNode(node) for child in node.childList: res.serializeFragmentInner(child, parentType, writeShadow) proc serializeFragment*(node: Node; writeShadow: bool): string = result = "" result.serializeFragment(node, writeShadow) proc findAncestor*(node: Node; tagType: TagType): Element = for element in node.ancestors: if element.tagType == tagType: return element return nil proc setNodeValue(ctx: JSContext; node: Node; data: JSValueConst): Opt[void] {.jsfset: "nodeValue".} = if node of CharacterData: var res = "" if not JS_IsNull(data): ?ctx.fromJS(data, res) CharacterData(node).data = newRefString(move(res)) elif node of Attr: var res = "" if not JS_IsNull(data): ?ctx.fromJS(data, res) Attr(node).setValue(move(res)) return ok() proc setTextContent(ctx: JSContext; node: Node; data: JSValueConst): Opt[void] {.jsfset: "textContent".} = if node of Element or node of DocumentFragment: let node = ParentNode(node) if JS_IsNull(data): node.replaceAll(nil) else: var res: string ?ctx.fromJS(data, res) node.replaceAll(move(res)) return ok() return ctx.setNodeValue(node, data) proc toNode(ctx: JSContext; nodes: openArray[JSValueConst]; document: Document): Opt[Node] = var node: Node = nil var fragment = false for it in nodes: var node0: Node if ctx.fromJS(it, node0).isErr: var s: string ?ctx.fromJS(it, s) node0 = ctx.newText(s) if node == nil: node = node0 else: if not fragment: let fragment = document.newDocumentFragment() fragment.append(node) node = fragment node.append(node0) if node == nil: node = document.newDocumentFragment() ok(node) proc prependImpl(ctx: JSContext; parent: Node; nodes: openArray[JSValueConst]): JSValue = let node = ctx.toNode(nodes, parent.document) if node.isErr: return JS_EXCEPTION return ctx.insertBeforeUndefined(parent, node.get, option(parent.firstChild)) proc appendImpl(ctx: JSContext; parent: Node; nodes: openArray[JSValueConst]): JSValue = let node = ctx.toNode(nodes, parent.document) if node.isErr: return JS_EXCEPTION return ctx.insertBeforeUndefined(parent, node.get, none(Node)) proc replaceChildrenImpl(ctx: JSContext; parent: Node; nodes: openArray[JSValueConst]): JSValue = let node0 = ctx.toNode(nodes, parent.document) if node0.isErr: return JS_EXCEPTION let node = node0.get let x = parent.preInsertionValidity(node, nil) if x.isErr: return ctx.insertThrow(x.error) let parent = x.get parent.replaceAll(node) return JS_UNDEFINED proc assignSlot(node: Node) = discard # ParentNode proc firstChild(parent: ParentNode): Node = let child = parent.internalFirst if child != nil and child.parentNode != parent: when defined(debug): assert child of ShadowRoot return child.internalNext return child proc firstChildShadow(parent: ParentNode): Node = return parent.internalFirst proc setFirstChild(node: ParentNode; child: Node) = let first = node.internalFirst if first != nil and first.parentNode != node: # shadow root first.internalNext = child else: node.internalFirst = child proc firstElementChild*(node: ParentNode): Element = for child in node.elementList: return child return nil proc lastElementChild*(node: ParentNode): Element = for child in node.relementList: return child return nil proc findFirstChildOf(node: ParentNode; tagType: TagType): Element = for element in node.elementList: if element.tagType == tagType: return element return nil proc findLastChildOf(node: ParentNode; tagType: TagType): Element = for element in node.relementList: if element.tagType == tagType: return element return nil proc findFirstChildNotOf(node: ParentNode; tagType: set[TagType]): Element = for element in node.elementList: if element.tagType notin tagType: return element return nil proc getChildList*(node: ParentNode): seq[Node] = result = @[] for child in node.childList: result.add(child) proc replaceAll(parent: ParentNode; node: Node) = let removedNodes = parent.getChildList() for child in removedNodes: child.remove(true) if node != nil: if node of DocumentFragment: let nodes = DocumentFragment(node).getChildList() for it in nodes: parent.insert(it, nil, suppressObservers = true) else: parent.insert(node, nil, suppressObservers = true) #TODO tree mutation record proc replaceAll(parent: ParentNode; s: sink string) = let node = if s != "": parent.document.newText(s) else: nil parent.replaceAll(node) proc childrenImpl(ctx: JSContext; node: ParentNode): JSValue = return ctx.getWeakCollection(node, wwmChildren) proc childElementCountImpl(node: ParentNode): int = let last = node.lastElementChild if last == nil: return 0 return last.elIndex + 1 proc countChildren(node: ParentNode; nodeType: type): int = result = 0 for child in node.childList: if child of nodeType: inc result proc hasChild(node: ParentNode; nodeType: type): bool = for child in node.childList: if child of nodeType: return true return false proc hasChildExcept(node: ParentNode; nodeType: type; ex: Node): bool = for child in node.childList: if child == ex: continue if child of nodeType: return true return false proc childTextContent*(node: ParentNode): string = result = "" for child in node.childList: if child of Text: result &= Text(child).data.s proc getElementsByTagNameImpl(ctx: JSContext; root: ParentNode; tagName: string): Opt[HTMLCollection] = if tagName == "*": return ctx.newHTMLCollection(root, isElement, islive = true, childonly = false) let localName = tagName.toAtom() let localNameLower = localName.toLowerAscii() let this = ?ctx.newHTMLCollection( root, proc(ctx: JSContext; this: Collection; node: Node): Opt[bool] = if node of Element: let element = Element(node) if element.namespaceURI == satNamespaceHTML: return ok(element.localName == this.atoms[1]) return ok(element.localName == this.atoms[0]) return ok(false), islive = true, childonly = false ) this.atoms = @[localName, localNameLower] ok(this) proc getElementsByClassNameImpl(ctx: JSContext; node: ParentNode; classNames: string): Opt[HTMLCollection] = let this = ?ctx.newHTMLCollection( node, proc(ctx: JSContext; this: Collection; node: Node): Opt[bool] = if not (node of Element): return ok(false) let element = Element(node) if element.document.mode == QUIRKS: for class in this.atoms: if not element.classList.toks.containsIgnoreCase(class): return ok(false) else: for class in this.atoms: if class notin element.classList.toks: return ok(false) ok(true), islive = true, childonly = false ) for class in classNames.split(AsciiWhitespace): this.atoms.add(class.toAtom()) ok(this) proc insert0(parent: ParentNode; node, before: Node; postConnectionNodes: var seq[Element]) = let parentDocument = parent.document parentDocument.adopt(node) let element = if node of Element: Element(node) else: nil let first = parent.firstChild if before == nil: if first != nil: let last = first.internalPrev last.internalNext = node node.internalPrev = last first.internalPrev = node else: parent.setFirstChild(node) node.internalPrev = node else: node.internalNext = before let prev = before.internalPrev node.internalPrev = prev if prev.nextSibling != nil: prev.internalNext = node before.internalPrev = node if before == first: parent.setFirstChild(node) node.parentNode = parent let parentElement = node.parentElement if element != nil: if element.nextSibling != nil and parentElement != nil: parentElement.childElIndicesInvalid = true elif (let prev = element.previousElementSibling; prev != nil): element.internalElIndex = prev.internalElIndex + 1 else: element.internalElIndex = 0 parentDocument.invalidateCollections() if parentElement != nil: let shadow = parentElement.shadowRoot if shadow != nil and shadow.slotAssignment == samNamed and (element != nil or node of Text): node.assignSlot() let root = parent.rootNode if parentElement.tagType == TAG_SLOT and root of ShadowRoot: discard #TODO signal a slot change #TODO assign slottables for a tree with root for desc in node.descendantsShadowIncl: if desc of Element: let el = Element(desc) if el.elementInsertionSteps(): postConnectionNodes.add(el) if el.custom == cesCustom: #TODO append parentDocument to element custom registry discard #TODO call connectedCallback (custom elements) else: discard #TODO try to upgrade (custom elements) elif desc of ShadowRoot: let shadow = ShadowRoot(desc) let customElements = shadow.customElements if customElements != nil and customElements.scoped: customElements.addScopedDocument(parentDocument) # WARNING ditto proc insert*(parent: ParentNode; node, before: Node; suppressObservers = false) = let nodes = if node of DocumentFragment: DocumentFragment(node).getChildList() else: @[node] let count = nodes.len if count == 0: return if node of DocumentFragment: for child in nodes: child.remove(true) #TODO tree mutation record if before != nil: #TODO live ranges discard if parent of Element: Element(parent).invalidate() var postConnectionNodes: seq[Element] = @[] for node in nodes: parent.insert0(node, before, postConnectionNodes) #TODO children changed steps for parent if not suppressObservers: discard #TODO queue tree mutation record for el in postConnectionNodes: el.postConnectionSteps() proc querySelectorImpl(ctx: JSContext; node: ParentNode; q: string): JSValue = let selectors = parseSelectors(q) if selectors.len == 0: return JS_ThrowDOMException(ctx, "SyntaxError", "invalid selector: %s", cstring(q)) for element in node.elementDescendants: if element.matchesImpl(selectors): return ctx.toJS(element) return JS_NULL proc querySelectorAllImpl(ctx: JSContext; node: ParentNode; q: string): JSValue = let selectors = parseSelectors(q) if selectors.len == 0: return JS_ThrowDOMException(ctx, "SyntaxError", "invalid selector: %s", cstring(q)) let this = newEmptyNodeList() for element in node.elementDescendants: if element.matchesImpl(selectors): this.snapshot.add(element) return ctx.toJS(this) # Collection proc populateCollection(ctx: JSContext; this: Collection): Opt[void] = if this.inclusive: if this.match == nil or ?this.match(ctx, this, this.root): this.snapshot.add(this.root) if this.root of ParentNode: let root = ParentNode(this.root) if this.childonly: for child in root.childList: if this.match == nil or ?this.match(ctx, this, child): this.snapshot.add(child) else: for desc in root.descendants: if this.match == nil or ?this.match(ctx, this, desc): this.snapshot.add(desc) ok() proc refreshCollection(ctx: JSContext; this: Collection): Opt[void] = if this.invalid: assert this.document != nil this.snapshot.setLen(0) ?ctx.populateCollection(this) this.invalid = false ok() proc finalize0(collection: Collection) = if collection.document != nil: let document = collection.document let i = document.liveCollections.find(cast[ptr CollectionObj](collection)) assert i != -1 document.liveCollections.del(i) proc finalize(collection: HTMLCollection) {.jsfin.} = collection.finalize0() proc finalize(collection: NodeList) {.jsfin.} = collection.finalize0() proc finalize(rt: JSRuntime; collection: NodeIterator) {.jsfin.} = collection.finalize0() JS_FreeValueRT(rt, collection.filter) proc mark(rt: JSRuntime; this: NodeIterator; markFun: JS_MarkFunc) {.jsmark.} = JS_MarkValue(rt, this.filter, markFun) proc finalize(collection: HTMLAllCollection) {.jsfin.} = collection.finalize0() proc finalize(document: Document) {.jsfin.} = for it in document.liveCollections: cast[Collection](it).document = nil proc getLength(ctx: JSContext; this: Collection): Opt[uint32] = ?ctx.refreshCollection(this) if uint64(this.snapshot.len) > uint64(uint32.high): JS_ThrowInternalError(ctx, "collection too large") ok(uint32(this.snapshot.len)) proc findNode(ctx: JSContext; this: Collection; node: Node): Opt[int] = ?ctx.refreshCollection(this) ok(this.snapshot.find(node)) proc newCollection[T: Collection](ctx: JSContext; root: Node; match: CollectionMatchFun; islive, childonly: bool; inclusive = false): Opt[T] = let document = root.document let this = T( childonly: childonly, inclusive: inclusive, match: match, root: root, document: if islive: cast[ptr DocumentObj](document) else: nil ) if islive: document.liveCollections.add(cast[ptr CollectionObj](this)) this.invalid = true else: ?ctx.populateCollection(this) ok(this) proc newEmptyNodeList(): NodeList = return NodeList( childonly: false, inclusive: false, match: nil, document: nil ) proc newHTMLCollection(ctx: JSContext; root: Node; match: CollectionMatchFun; islive, childonly: bool): Opt[HTMLCollection] = newCollection[HTMLCollection](ctx, root, match, islive, childonly) proc newNodeList(ctx: JSContext; root: Node; match: CollectionMatchFun; islive, childonly: bool): Opt[NodeList] = newCollection[NodeList](ctx, root, match, islive, childonly) # Text proc newText*(document: Document; data: sink string): Text = return Text(internalNext: document, data: newRefString(data)) proc newText(ctx: JSContext; data: sink string = ""): Text {.jsctor.} = let window = ctx.getGlobal() return window.document.newText(data) # CDATASection proc newCDATASection(document: Document; data: string): CDATASection = return CDATASection(internalNext: document, data: newRefString(data)) # ProcessingInstruction proc newProcessingInstruction(document: Document; target: string; data: sink string): ProcessingInstruction = return ProcessingInstruction( internalNext: document, target: target, data: newRefString(data) ) # Comment proc newComment(document: Document; data: sink string): Comment = return Comment( internalNext: document, data: newRefString(data) ) proc newComment(ctx: JSContext; data: sink string = ""): Comment {.jsctor.} = let window = ctx.getGlobal() return window.document.newComment(data) # DocumentFragment proc getDocument(ctx: JSContext): Document = return ctx.getWindow().document proc newDocumentFragment(document: Document): DocumentFragment = return DocumentFragment(internalNext: document) proc newDocumentFragment(ctx: JSContext): DocumentFragment {.jsctor.} = let window = ctx.getGlobal() return window.document.newDocumentFragment() proc firstElementChild(this: DocumentFragment): Element {.jsfget.} = return ParentNode(this).firstElementChild proc lastElementChild(this: DocumentFragment): Element {.jsfget.} = return ParentNode(this).lastElementChild proc childElementCount(this: DocumentFragment): int {.jsfget.} = return this.childElementCountImpl proc querySelector(ctx: JSContext; this: DocumentFragment; q: string): JSValue {.jsfunc.} = return ctx.querySelectorImpl(this, q) proc querySelectorAll(ctx: JSContext; this: DocumentFragment; q: string): JSValue {.jsfunc.} = return ctx.querySelectorAllImpl(this, q) proc prepend(ctx: JSContext; this: DocumentFragment; nodes: varargs[JSValueConst]): JSValue {.jsfunc.} = return ctx.prependImpl(this, nodes) proc append(ctx: JSContext; this: DocumentFragment; nodes: varargs[JSValueConst]): JSValue {.jsfunc.} = return ctx.appendImpl(this, nodes) proc replaceChildren(ctx: JSContext; this: DocumentFragment; nodes: varargs[JSValueConst]): JSValue {.jsfunc.} = return ctx.replaceChildrenImpl(this, nodes) proc children(ctx: JSContext; parentNode: DocumentFragment): JSValue {.jsfget.} = return childrenImpl(ctx, parentNode) # Document proc newXMLDocument(): XMLDocument = let document = XMLDocument( url: parseURL0("about:blank"), contentType: satApplicationXml ) document.implementation = DOMImplementation(document: document) return document proc newDocument*(url: URL): Document = let document = Document( url: url, contentType: satApplicationXml, origin: url.origin ) document.implementation = DOMImplementation(document: document) return document proc newDocument(ctx: JSContext): Document {.jsctor.} = let global = ctx.getGlobal() let document = Document( url: parseURL0("about:blank"), contentType: satApplicationXml, origin: global.document.origin ) document.implementation = DOMImplementation(document: document) return document proc newDocumentType*(document: Document; name, publicId, systemId: sink string): DocumentType = return DocumentType( internalNext: document, name: name, publicId: publicId, systemId: systemId ) proc firstElementChild(this: Document): Element {.jsfget.} = return ParentNode(this).firstElementChild proc lastElementChild(this: Document): Element {.jsfget.} = return ParentNode(this).lastElementChild proc isxml(document: Document): bool = return document.contentType != satTextHtml proc adopt(document: Document; node: Node) = let oldDocument = node.document if node.parentNode != nil: remove(node) if oldDocument != document: #TODO shadow root node.internalNext = document if node of ParentNode: let node = ParentNode(node) for desc in node.descendants: if desc.nextSibling == nil: desc.internalNext = document for i in countdown(oldDocument.liveCollections.high, 0): let collection = oldDocument.liveCollections[i] if collection.document == cast[ptr DocumentObj](document): collection.document = cast[ptr DocumentObj](document) document.liveCollections.add(collection) oldDocument.liveCollections.del(i) #TODO custom elements #..adopting steps proc compatMode(document: Document): string {.jsfget.} = if document.mode == QUIRKS: return "BackCompat" return "CSS1Compat" proc forms(ctx: JSContext; document: Document): Opt[HTMLCollection] {.jsfget.} = if document.cachedForms == nil: document.cachedForms = ?ctx.newHTMLCollection( document, match = isForm, islive = true, childonly = false ) ok(document.cachedForms) proc links(ctx: JSContext; document: Document): Opt[HTMLCollection] {.jsfget.} = if document.cachedLinks == nil: document.cachedLinks = ?ctx.newHTMLCollection( document, match = isLink, islive = true, childonly = false ) ok(document.cachedLinks) proc images(ctx: JSContext; document: Document): Opt[HTMLCollection] {. jsfget.} = if document.cachedImages == nil: document.cachedImages = ?ctx.newHTMLCollection( document, match = isImage, islive = true, childonly = false ) ok(document.cachedImages) proc getURL(ctx: JSContext; document: Document): JSValue {.jsfget: "URL".} = return ctx.toJS($document.url) proc getCookieWindow(ctx: JSContext; document: Document): Opt[Window] = let window = document.window if window == nil or document.url.schemeType notin {stHttp, stHttps}: return ok(nil) if document.origin.t == otOpaque: JS_ThrowDOMException(ctx, "SecurityError", "sandboxed iframe cannot access cookies") return err() ok(window) proc cookie(ctx: JSContext; document: Document): JSValue {.jsfget.} = let window0 = ctx.getCookieWindow(document) if window0.isErr: return JS_EXCEPTION let window = window0.get if window == nil: return ctx.toJS("") let response = window.loader.doRequest(newRequest("x-cha-cookie:get-all")) if response.stream == nil: return JS_ThrowInternalError(ctx, "internal error in cookie getter") window.loader.resume(response) let cookie = response.stream.readAll() return ctx.toJS(cookie) proc setCookie(ctx: JSContext; document: Document; cookie: string): Opt[void] {.jsfset: "cookie".} = let window = ?ctx.getCookieWindow(document) if window == nil: return ok() let headers = newHeaders(hgRequest, {"Set-Cookie": cookie}) let req = newRequest("x-cha-cookie:set", hmPost, headers, credentials = cmOmit) let response = window.loader.doRequest(req) window.loader.close(response) ok() proc focus*(document: Document): Element {.jsfget: "activeElement".} = return document.internalFocus proc setFocus*(document: Document; element: Element) = if document.focus != nil: document.focus.invalidate(dtFocus) document.internalFocus = element if element != nil: element.invalidate(dtFocus) proc findAutoFocus*(document: Document): Element = for child in document.elementDescendants: if child.attrb(satAutofocus): return child return nil proc target*(document: Document): Element = return document.internalTarget proc setTarget*(document: Document; element: Element) = if document.target != nil: document.target.invalidate(dtTarget) document.internalTarget = element if element != nil: element.invalidate(dtTarget) proc queryCommandSupported(document: Document): bool {.jsfunc.} = return false proc createCDATASection(ctx: JSContext; document: Document; data: string): JSValue {.jsfunc.} = if not document.isxml: return JS_ThrowDOMException(ctx, "NotSupportedError", "CDATA sections are not supported in HTML") if "]]>" in data: return JS_ThrowDOMException(ctx, "InvalidCharacterError", "CDATA sections may not contain the string ]]>") return ctx.toJS(newCDATASection(document, data)) proc createComment*(document: Document; data: string): Comment {.jsfunc.} = return newComment(document, data) proc createProcessingInstruction(ctx: JSContext; document: Document; target, data: string): JSValue {.jsfunc.} = if not target.matchNameProduction() or "?>" in data: return JS_ThrowDOMException(ctx, "InvalidCharacterError", "invalid data for processing instruction") return ctx.toJS(newProcessingInstruction(document, target, data)) proc createEvent(ctx: JSContext; document: Document; atom: CAtom): JSValue {.jsfunc.} = case atom.toLowerAscii().toStaticAtom() of satCustomevent: return ctx.toJS(ctx.newCustomEvent(satUempty.toAtom())) of satEvent, satEvents, satHtmlevents, satSvgevents: return ctx.toJS(newEvent(satUempty.toAtom(), nil, bubbles = false, cancelable = false)) of satUievent, satUievents: return ctx.toJS(newUIEvent(satUempty.toAtom())) of satMouseevent, satMouseevents: return ctx.toJS(newMouseEvent(satUempty.toAtom())) else: return JS_ThrowDOMException(ctx, "NotSupportedError", "event not supported") proc location(document: Document): Location {.jsfget.} = if document.window == nil: return nil return document.window.location proc setLocation*(ctx: JSContext; document: Document; s: string): JSValue {.jsfset: "location".} = if document.location == nil: return JS_ThrowTypeError(ctx, "document.location is not an object") let url = document.parseURL0(s) if url == nil: return JS_ThrowDOMException(ctx, "Invalid URL", "SyntaxError") document.window.navigate(url) return JS_UNDEFINED proc scriptingEnabled*(document: Document): bool = if document.window == nil: return false return document.window.settings.scripting != smFalse proc findFirst*(document: Document; tagType: TagType): HTMLElement = for element in document.elementDescendants(tagType): return HTMLElement(element) nil proc head*(document: Document): HTMLElement {.jsfget.} = return document.findFirst(TAG_HEAD) proc body*(document: Document): HTMLElement {.jsfget.} = return document.findFirst(TAG_BODY) proc getElementById*(document: Document; id: string): Element {.jsfunc.} = if id.len == 0: return nil let id = id.toAtom() for child in document.elementDescendants: if child.id == id: return child return nil proc getElementsByName(ctx: JSContext; document: Document; name: CAtom): Opt[NodeList] {.jsfunc.} = if name == satUempty.toAtom(): return ok(newEmptyNodeList()) let this = ?ctx.newNodeList( document, proc(ctx: JSContext; this: Collection; node: Node): Opt[bool] = ok(node of Element and Element(node).name == this.atoms[0]), islive = true, childonly = false ) this.atoms = @[name] ok(this) proc getElementsByTagName(ctx: JSContext; document: Document; tagName: string): Opt[HTMLCollection] {.jsfunc.} = return ctx.getElementsByTagNameImpl(document, tagName) proc getElementsByClassName(ctx: JSContext; document: Document; classNames: string): Opt[HTMLCollection] {.jsfunc.} = return ctx.getElementsByClassNameImpl(document, classNames) proc children(ctx: JSContext; parentNode: Document): JSValue {.jsfget.} = return childrenImpl(ctx, parentNode) proc querySelector(ctx: JSContext; this: Document; q: string): JSValue {.jsfunc.} = return ctx.querySelectorImpl(this, q) proc querySelectorAll(ctx: JSContext; this: Document; q: string): JSValue {.jsfunc.} = return ctx.querySelectorAllImpl(this, q) proc validateName(ctx: JSContext; name: string): Opt[void] = if not name.matchNameProduction(): JS_ThrowDOMException(ctx, "InvalidCharacterError", "invalid character in name") return err() ok() proc validateQName(ctx: JSContext; qname: string): Opt[void] = if not qname.matchQNameProduction(): JS_ThrowDOMException(ctx, "InvalidCharacterError", "invalid character in qualified name") return err() ok() proc baseURL*(document: Document): URL = #TODO frozen base url... var href = "" for base in document.elementDescendants(TAG_BASE): if base.attrb(satHref): href = base.attr(satHref) if href == "": return document.url let url = parseURL0(href, document.url) if url == nil: return document.url return url proc parseURL0*(document: Document; s: string): URL = #TODO encodings return parseURL0(s, document.baseURL) proc parseURL*(document: Document; s: string): Opt[URL] = #TODO encodings let url = document.parseURL0(s) if url == nil: return err() ok(url) proc title*(document: Document): string {.jsfget.} = if (let title = document.findFirst(TAG_TITLE); title != nil): return title.childTextContent.stripAndCollapse() return "" proc `title=`(document: Document; s: sink string) {.jsfset: "title".} = var title = document.findFirst(TAG_TITLE) if title == nil: let head = document.head if head == nil: return title = document.newHTMLElement(TAG_TITLE) head.append(title) title.replaceAll(s) proc invalidateCollections(document: Document) = for collection in document.liveCollections: collection.invalid = true proc isValidCustomElementName(atom: CAtom): bool = const Disallowed = [ satAnnotationXml, satColorDashProfile, satFontDashFace, satFontDashFaceDashSrc, satFontDashFaceDashUri, satFontDashFaceDashFormat, satFontDashFaceDashName, satMissingDashGlyph ] if atom.toStaticAtom() in Disallowed: return false let s = $atom if s.len <= 0 or s[0] notin AsciiLowerAlpha: return false var dash = false for c in s: if c in AsciiUpperAlpha: return false dash = dash or c == '-' dash #TODO options/custom elements proc createElement(ctx: JSContext; document: Document; localName: string): Opt[Element] {.jsfunc.} = ?ctx.validateName(localName) let localName = if not document.isxml: localName.toAtomLower() else: localName.toAtom() let namespace = if not document.isxml: #TODO or content type is application/xhtml+xml Namespace.HTML else: NO_NAMESPACE let element = document.newElement(localName, namespace) ok(element) proc validateAndExtract(ctx: JSContext; document: Document; qname: string; namespace, prefixOut, localNameOut: var CAtom): Opt[void] = ?ctx.validateQName(qname) if namespace == satUempty.toAtom(): namespace = CAtomNull var prefix = "" var localName = qname.until(':') if localName.len < qname.len: prefix = move(localName) localName = qname.substr(prefix.len + 1) if namespace == CAtomNull and prefix != "": JS_ThrowDOMException(ctx, "NamespaceError", "got namespace prefix, but no namespace") return err() let sns = namespace.toStaticAtom() if prefix == "xml" and sns != satNamespaceXML: JS_ThrowDOMException(ctx, "NamespaceError", "expected XML namespace") return err() if (qname == "xmlns" or prefix == "xmlns") != (sns == satNamespaceXMLNS): JS_ThrowDOMException(ctx, "NamespaceError", "expected XMLNS namespace") return err() prefixOut = if prefix == "": CAtomNull else: prefix.toAtom() localNameOut = localName.toAtom() ok() proc createElementNS(ctx: JSContext; document: Document; namespace: CAtom; qname: string): Opt[Element] {.jsfunc.} = var namespace = namespace var prefix, localName: CAtom ?ctx.validateAndExtract(document, qname, namespace, prefix, localName) #TODO custom elements (is) return ok(document.newElement(localName, namespace, prefix)) proc createDocumentFragment(document: Document): DocumentFragment {.jsfunc.} = return newDocumentFragment(document) proc createDocumentType(ctx: JSContext; implementation: DOMImplementation; qualifiedName, publicId, systemId: string): Opt[DocumentType] {.jsfunc.} = ?ctx.validateQName(qualifiedName) let document = implementation.document ok(document.newDocumentType(qualifiedName, publicId, systemId)) proc createDocument(ctx: JSContext; implementation: DOMImplementation; namespace: CAtom; qname0: JSValueConst = JS_NULL; doctype = none(DocumentType)): Opt[XMLDocument] {.jsfunc.} = let document = newXMLDocument() var qname = "" if not JS_IsNull(qname0): ?ctx.fromJS(qname0, qname) let element = if qname != "": ?ctx.createElementNS(document, namespace, qname) else: nil if doctype.isSome: document.append(doctype.get) if element != nil: document.append(element) document.origin = implementation.document.origin case namespace.toStaticAtom() of satNamespaceHTML: document.contentType = satApplicationXmlHtml of satNamespaceSVG: document.contentType = satImageSvgXml else: discard return ok(document) proc createHTMLDocument(ctx: JSContext; implementation: DOMImplementation; title: JSValueConst = JS_UNDEFINED): Opt[Document] {.jsfunc.} = let doc = newDocument(ctx) doc.contentType = satTextHtml doc.append(doc.newDocumentType("html", "", "")) let html = doc.newHTMLElement(TAG_HTML) doc.append(html) let head = doc.newHTMLElement(TAG_HEAD) html.append(head) if not JS_IsUndefined(title): var s: string ?ctx.fromJS(title, s) let titleElement = doc.newHTMLElement(TAG_TITLE) titleElement.append(doc.newText(s)) head.append(titleElement) html.append(doc.newHTMLElement(TAG_BODY)) doc.origin = implementation.document.origin ok(doc) proc hasFeature(implementation: DOMImplementation): bool {.jsfunc.} = return true proc createTextNode(document: Document; data: sink string): Text {.jsfunc.} = return newText(document, data) proc prepend(ctx: JSContext; this: Document; nodes: varargs[JSValueConst]): JSValue {.jsfunc.} = return ctx.prependImpl(this, nodes) proc append(ctx: JSContext; this: Document; nodes: varargs[JSValueConst]): JSValue {.jsfunc.} = return ctx.appendImpl(this, nodes) proc replaceChildren(ctx: JSContext; this: Document; nodes: varargs[JSValueConst]): JSValue {.jsfunc.} = return ctx.replaceChildrenImpl(this, nodes) const (ReflectMap, TagReflectMap, ReflectAllStartIndex) = (proc(): ( seq[ReflectEntry], array[TagType, seq[int16]], int16) = var i: int16 = 0 while i < ReflectMap0.len: let x = ReflectMap0[i] result[0].add(x.e) if x.tags.len == 0: break for tag in x.tags: result[1][tag].add(i) inc i result[2] = i while i < ReflectMap0.len: let x = ReflectMap0[i] assert x.tags.len == 0 result[0].add(x.e) inc i )() proc parseFormMethod(s: string): FormMethod = return parseEnumNoCase[FormMethod](s).get(fmGet) proc getReflectElement(ctx: JSContext; this: JSValueConst; magic: cint): HTMLElement = let rtOpaque = JS_GetRuntime(ctx).getOpaque() let magic = uint16(magic) let myClass = JS_GetClassID(this) let parent = rtOpaque.classes[myClass].parent let class = JSClassID(magic shr 9) + parent if class != parent and class != myClass: JS_ThrowTypeError(ctx, "invalid tag type") return nil var element: HTMLElement if ctx.fromJS(this, element).isErr: return nil return element proc jsReflectGet(ctx: JSContext; this: JSValueConst; magic: cint): JSValue {.cdecl.} = let entry = ReflectMap[uint16(magic) and 0x1FF] let element = ctx.getReflectElement(this, magic) if element == nil: return JS_EXCEPTION case entry.t of rtStr: return ctx.toJS(element.attr(entry.attrname)) of rtUrl: let s = element.attr(entry.attrname) if url := element.document.parseURL(s): return ctx.toJS($url) return ctx.toJS(s) of rtReferrerPolicy: if s := element.referrerPolicy: return ctx.toJS($s) return ctx.toJS("") of rtCrossOrigin: case (let co = element.crossOrigin; co) of caNoCors: return JS_NULL else: return ctx.toJS($co) of rtMethod: let s = element.attr(entry.attrname) if entry.attrname == satFormmethod and s == "": return ctx.toJS("") return ctx.toJS($parseFormMethod(s)) of rtBool: return ctx.toJS(element.attrb(entry.attrname)) of rtLong: let i = cast[int32](entry.u) return ctx.toJS(element.attrl(entry.attrname).get(i)) of rtUlong: return ctx.toJS(element.attrul(entry.attrname).get(entry.u)) of rtUlongGz: return ctx.toJS(element.attrulgz(entry.attrname).get(entry.u)) of rtDoubleGz: # we do not have fractional default values, so we actually store them # as uint32 and convert here. let f = float32(entry.u) return ctx.toJS(element.attrdgz(entry.attrname).get(f)) of rtFunction: return JS_NULL proc jsReflectSet(ctx: JSContext; this, val: JSValueConst; magic: cint): JSValue {.cdecl.} = let entry = ReflectMap[uint16(magic) and 0x1FF] let element = ctx.getReflectElement(this, magic) if element == nil: return JS_EXCEPTION case entry.t of rtStr, rtUrl, rtReferrerPolicy, rtMethod: var x: string ?ctx.fromJS(val, x) element.attr(entry.attrname, x) of rtCrossOrigin: if JS_IsNull(val): let i = element.findAttr(entry.attrname.toAtom()) if i != -1: ctx.delAttr(element, i) else: var x: string ?ctx.fromJS(val, x) element.attr(entry.attrname, x) of rtBool: var x: bool ?ctx.fromJS(val, x) if x: element.attr(entry.attrname, "") else: let i = element.findAttr(entry.attrname.toAtom()) if i != -1: ctx.delAttr(element, i) of rtLong: var x: int32 ?ctx.fromJS(val, x) element.attrl(entry.attrname, x) of rtUlong: var x: uint32 ?ctx.fromJS(val, x) element.attrul(entry.attrname, x) of rtUlongGz: var x: uint32 ?ctx.fromJS(val, x) element.attrulgz(entry.attrname, x) of rtDoubleGz: var x: float64 ?ctx.fromJS(val, x) if classify(x) in {fcInf, fcNegInf, fcNan}: return JS_ThrowTypeError(ctx, "double expected") element.attrd(entry.attrname, x) of rtFunction: let ctype = cast[StaticAtom](entry.u) return ctx.eventReflectSet0(element, val, magic, jsReflectSet, ctype) return JS_DupValue(ctx, val) proc findMagic(ctype: StaticAtom): cint = for i in ReflectAllStartIndex ..< int16(ReflectMap.len): if ReflectMap[i].t == rtFunction and ReflectMap[i].u == uint32(ctype): return cint(i) -1 proc reflectEvent(document: Document; target: EventTarget; name, ctype: StaticAtom; value: string; target2 = none(EventTarget)) = let ctx = document.window.jsctx let fun = ctx.newFunction(["event"], value) assert ctx != nil if JS_IsException(fun): document.window.logException(document.baseURL) else: let magic = findMagic(ctype) assert magic != -1 let res = ctx.eventReflectSet0(target, fun, magic, jsReflectSet, ctype, target2) if JS_IsException(res): document.window.logException(document.baseURL) JS_FreeValue(ctx, res) JS_FreeValue(ctx, fun) proc applyUASheet*(document: Document) = const ua = staticRead"res/ua.css" let sheet = parseStylesheet(ua, nil, addr document.window.settings, coUserAgent, CAtomNull) document.uaSheetsHead = sheet if document.documentElement != nil: document.documentElement.invalidate() proc applyQuirksSheet*(document: Document) = if document.window == nil: return const quirks = staticRead"res/quirk.css" let sheet = parseStylesheet(quirks, nil, addr document.window.settings, coUserAgent, CAtomNull) document.uaSheetsHead.next = sheet if document.documentElement != nil: document.documentElement.invalidate() proc applyUserSheet*(document: Document; user: string) = document.userSheet = parseStylesheet(user, nil, addr document.window.settings, coUser, CAtomNull) if document.documentElement != nil: document.documentElement.invalidate() proc getRuleMap*(document: Document): CSSRuleMap = if document.ruleMap == nil: let map = CSSRuleMap() var sheet = document.uaSheetsHead while sheet != nil: map.add(sheet) sheet = sheet.next map.add(document.userSheet) sheet = document.authorSheetsHead while sheet != nil: if not sheet.disabled and sheet.applies: map.add(sheet) sheet = sheet.next document.ruleMap = map return document.ruleMap proc findAnchor*(document: Document; id: string): Element = if id.len == 0: return nil let id = id.toAtom() for child in document.elementDescendants: if child.id == id: return child if child of HTMLAnchorElement and child.name == id: return child return nil proc findMetaRefresh*(document: Document): Element = for child in document.elementDescendants(TAG_META): if child.attr(satHttpEquiv).equalsIgnoreCase("refresh"): return child return nil # https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#document-write-steps proc write(ctx: JSContext; document: Document; args: varargs[JSValueConst]): JSValue {.jsfunc.} = var text = "" for arg in args: var s: string if ctx.fromJS(arg, s).isErr: return JS_EXCEPTION text &= s if document.isxml: return JS_ThrowDOMException(ctx, "InvalidStateError", "document.write not supported in XML documents") if document.throwOnDynamicMarkupInsertion > 0: return JS_ThrowDOMException(ctx, "InvalidStateError", "throw-on-dynamic-markup-insertion counter > 0") if document.activeParserWasAborted: return JS_UNDEFINED assert document.parser != nil #TODO if insertion point is undefined... (open document) let buffer = document.writeBuffersTop if buffer == nil: return JS_UNDEFINED #TODO (probably covered by open above) buffer.data &= text if document.parserBlockingScript == nil: parseDocumentWriteChunkImpl(document.parser) return JS_UNDEFINED proc childElementCount(this: Document): int {.jsfget.} = return this.childElementCountImpl proc documentElement*(document: Document): Element {.jsfget.} = return document.firstElementChild() proc names(ctx: JSContext; document: Document): JSPropertyEnumList {.jspropnames.} = var list = newJSPropertyEnumList(ctx, 0) #TODO I'm not quite sure why location isn't added, so I'll add it # manually for now. list.add("location") #TODO exposed embed, exposed object for child in document.elementDescendants({TAG_FORM, TAG_IFRAME, TAG_IMG}): if child.name != CAtomNull and child.name != satUempty.toAtom(): if child.tagType == TAG_IMG and child.id != CAtomNull and child.id != satUempty.toAtom(): list.add($child.id) list.add($child.name) return list proc getter(ctx: JSContext; document: Document; s: string): JSValue {.jsgetownprop.} = if s.len != 0: let id = s.toAtom() #TODO exposed embed, exposed object for child in document.elementDescendants({TAG_FORM, TAG_IFRAME, TAG_IMG}): if child.tagType == TAG_IMG and child.id == id and child.name != CAtomNull and child.name != satUempty.toAtom(): return ctx.toJS(child) if child.name == id: return ctx.toJS(child) return JS_UNINITIALIZED # DocumentType proc remove(this: DocumentType) {.jsfunc.} = Node(this).remove() proc nodeIteratorMatch(ctx: JSContext; this: Collection; node: Node): Opt[bool] = let this = NodeIterator(this) let n = 1u32 shl (uint32(node.nodeType) - 1) if (this.whatToShow and n) == 0: return ok(false) if JS_IsNull(this.filter): return ok(true) let filter = this.filter let node = ctx.toJS(node) if JS_IsException(node): return err() let val = if JS_IsFunction(ctx, filter): ctx.callSink(filter, JS_UNDEFINED, node) else: let atom = JS_NewAtom(ctx, cstringConst"acceptNode") let val = ctx.invokeSink(filter, atom, node) JS_FreeAtom(ctx, atom) val if JS_IsException(val): return err() var res: uint32 ?ctx.fromJSFree(val, res) ok(res == uint32(nftAccept)) # NodeIterator proc createNodeIterator(ctx: JSContext; document: Document; root: Node; whatToShow = 0xFFFFFFFFu32; filter: JSValueConst = JS_NULL): Opt[NodeIterator] {.jsfunc.} = let this = ?newCollection[NodeIterator]( ctx, root, match = nodeIteratorMatch, islive = true, childonly = false, inclusive = true ) this.whatToShow = whatToShow this.filter = JS_DupValue(ctx, filter) ok(this) proc referenceNode(ctx: JSContext; this: NodeIterator): Opt[Node] {.jsfget.} = let len = ?ctx.getLength(this) if this.u < uint32(len): return ok(this.snapshot[this.u]) ok(nil) proc nextNode(ctx: JSContext; this: NodeIterator): Opt[Node] {.jsfunc.} = let res = ?ctx.referenceNode(this) if res != nil: inc this.u ok(res) proc previousNode(ctx: JSContext; this: NodeIterator): Opt[Node] {.jsfunc.} = ?ctx.populateCollection(this) if this.u > 0: dec this.u return ok(this.snapshot[this.u]) ok(nil) proc detach(this: NodeIterator) {.jsfunc.} = discard # DOMTokenList proc newDOMTokenList(element: Element; name: StaticAtom): DOMTokenList = return DOMTokenList(element: element, localName: name.toAtom()) iterator items*(tokenList: DOMTokenList): CAtom {.inline.} = for tok in tokenList.toks: yield tok proc length(tokenList: DOMTokenList): int {.jsfget.} = return tokenList.toks.len proc item(ctx: JSContext; tokenList: DOMTokenList; u: uint32): JSValue {.jsfunc.} = if int64(u) < int64(int.high): let i = int(u) if i < tokenList.toks.len: return ctx.toJS(tokenList.toks[i]) return JS_NULL proc contains(tokenList: DOMTokenList; a: CAtom): bool = return a in tokenList.toks proc containsIgnoreCase(tokenList: DOMTokenList; a: StaticAtom): bool = return tokenList.toks.containsIgnoreCase(a) proc jsContains(tokenList: DOMTokenList; s: string): bool {.jsfunc: "contains".} = return s.toAtom() in tokenList.toks proc `$`(tokenList: DOMTokenList): string {.jsfunc: "toString".} = var s = "" for i, tok in tokenList.toks: if i != 0: s &= ' ' s &= $tok move(s) proc update(tokenList: DOMTokenList) = if not tokenList.element.attrb(tokenList.localName) and tokenList.toks.len == 0: return tokenList.element.attr(tokenList.localName, $tokenList) proc validateDOMToken(ctx: JSContext; tok: JSValueConst): Opt[CAtom] = var res: string ?ctx.fromJS(tok, res) if res == "": JS_ThrowDOMException(ctx, "SyntaxError", "got an empty string") return err() if AsciiWhitespace in res: JS_ThrowDOMException(ctx, "InvalidCharacterError", "got a string containing whitespace") return err() ok(res.toAtom()) proc add(ctx: JSContext; tokenList: DOMTokenList; tokens: varargs[JSValueConst]): Opt[void] {.jsfunc.} = var toks = newSeqOfCap[CAtom](tokens.len) for tok in tokens: toks.add(?ctx.validateDOMToken(tok)) tokenList.toks.add(toks) tokenList.update() ok() proc remove(ctx: JSContext; tokenList: DOMTokenList; tokens: varargs[JSValueConst]): Opt[void] {.jsfunc.} = var toks = newSeqOfCap[CAtom](tokens.len) for tok in tokens: toks.add(?ctx.validateDOMToken(tok)) for tok in toks: let i = tokenList.toks.find(tok) if i != -1: tokenList.toks.delete(i) tokenList.update() ok() proc toggle(ctx: JSContext; tokenList: DOMTokenList; token: JSValueConst; force = none(bool)): Opt[bool] {.jsfunc.} = let token = ?ctx.validateDOMToken(token) let i = tokenList.toks.find(token) if i != -1: if not force.get(false): tokenList.toks.delete(i) tokenList.update() return ok(false) return ok(true) if force.get(true): tokenList.toks.add(token) tokenList.update() return ok(true) ok(false) proc replace(ctx: JSContext; tokenList: DOMTokenList; token, newToken: JSValueConst): Opt[bool] {.jsfunc.} = let token = ?ctx.validateDOMToken(token) let newToken = ?ctx.validateDOMToken(newToken) let i = tokenList.toks.find(token) if i == -1: return ok(false) tokenList.toks[i] = newToken tokenList.update() return ok(true) const SupportedTokensMap = { satRel: @[ "alternate", "dns-prefetch", "icon", "manifest", "modulepreload", "next", "pingback", "preconnect", "prefetch", "preload", "search", "stylesheet" ] } proc supports(ctx: JSContext; tokenList: DOMTokenList; token: string): JSValue {.jsfunc.} = let localName = tokenList.localName.toStaticAtom() for it in SupportedTokensMap: if it[0] == localName: let lowercase = token.toLowerAscii() if lowercase in it[1]: return JS_TRUE return JS_FALSE return JS_ThrowTypeError(ctx, "No supported tokens defined for attribute") proc value(tokenList: DOMTokenList): string {.jsfget.} = return $tokenList proc getter(ctx: JSContext; this: DOMTokenList; atom: JSAtom): JSValue {.jsgetownprop.} = var u: uint32 return case ctx.fromIdx(atom, u) of fiIdx: ctx.item(this, u).uninitIfNull() of fiStr: JS_UNINITIALIZED of fiErr: JS_EXCEPTION proc reflectTokens(this: DOMTokenList; value: string) = this.toks.setLen(0) for x in value.split(AsciiWhitespace): if x != "": let a = x.toAtom() if a notin this: this.toks.add(a) # DOMStringMap proc delete(ctx: JSContext; map: DOMStringMap; name: string): bool {.jsfunc.} = let name = ("data-" & name.camelToKebabCase()).toAtom() let i = map.target.findAttr(name) if i != -1: ctx.delAttr(map.target, i) return i != -1 proc getter(ctx: JSContext; map: DOMStringMap; name: string): JSValue {.jsgetownprop.} = let name = ("data-" & name.camelToKebabCase()).toAtom() let i = map.target.findAttr(name) if i != -1: return ctx.toJS(map.target.attrs[i].value) return JS_UNINITIALIZED proc setter(ctx: JSContext; map: DOMStringMap; name, value: string): Opt[void] {.jssetprop.} = var washy = false for c in name: if not washy or c notin AsciiLowerAlpha: washy = c == '-' continue JS_ThrowDOMException(ctx, "InvalidCharacterError", "lower case after hyphen is not allowed in dataset") return err() let name = "data-" & name.camelToKebabCase() ?ctx.validateName(name) let aname = name.toAtom() map.target.attr(aname, value) ok() proc names(ctx: JSContext; map: DOMStringMap): JSPropertyEnumList {.jspropnames.} = var list = newJSPropertyEnumList(ctx, uint32(map.target.attrs.len)) for attr in map.target.attrs: let k = $attr.qualifiedName if k.startsWith("data-") and AsciiUpperAlpha notin k: list.add(k["data-".len .. ^1].kebabToCamelCase()) return list proc dataset(ctx: JSContext; element: HTMLElement): JSValue {.jsfget.} = return ctx.getWeakCollection(element, wwmDataset) # NodeList proc length(ctx: JSContext; this: NodeList): Opt[uint32] {.jsfget.} = return ctx.getLength(this) proc item(ctx: JSContext; this: NodeList; u: uint32): Opt[Node] {.jsfunc.} = if u < ?ctx.getLength(this): return ok(this.snapshot[u]) ok(nil) proc getter(ctx: JSContext; this: NodeList; atom: JSAtom): JSValue {.jsgetownprop.} = var u: uint32 var s: string return case ctx.fromIdx(atom, u, s) of fiIdx: ctx.toJS(ctx.item(this, u)).uninitIfNull() of fiStr: JS_UNINITIALIZED of fiErr: JS_EXCEPTION proc names(ctx: JSContext; this: NodeList): JSPropertyEnumList {.jspropnames.} = #TODO handle exception let L = ctx.getLength(this).get(0) var list = newJSPropertyEnumList(ctx, L) for u in 0 ..< L: list.add(u) return list # HTMLCollection proc length(ctx: JSContext; this: HTMLCollection): Opt[uint32] {.jsfget.} = return ctx.getLength(this) proc item(ctx: JSContext; this: HTMLCollection; u: uint32): Opt[Element] {.jsfunc.} = if u < ?ctx.getLength(this): return ok(Element(this.snapshot[int(u)])) ok(nil) proc namedItem(ctx: JSContext; this: HTMLCollection; atom: CAtom): Opt[Element] {.jsfunc.} = ?ctx.refreshCollection(this) for it in this.snapshot: let it = Element(it) if it.id == atom or it.namespaceURI == satNamespaceHTML and it.name == atom: return ok(it) ok(nil) proc getter(ctx: JSContext; this: HTMLCollection; atom: JSAtom): JSValue {.jsgetownprop.} = var u: uint32 var s: CAtom return case ctx.fromIdx(atom, u, s) of fiIdx: ctx.toJS(ctx.item(this, u)).uninitIfNull() of fiStr: ctx.toJS(ctx.namedItem(this, s)).uninitIfNull() of fiErr: JS_EXCEPTION proc names(ctx: JSContext; this: HTMLCollection): JSPropertyEnumList {.jspropnames.} = #TODO handle exception let L = ctx.getLength(this).get(0) var list = newJSPropertyEnumList(ctx, L) var ids = initOrderedSet[CAtom]() for u in 0 ..< L: list.add(u) let element = ctx.item(this, u).get(nil) if element == nil: continue if element.id != CAtomNull and element.id != satUempty.toAtom(): ids.incl(element.id) if element.namespaceURI == satNamespaceHTML: ids.incl(element.name) for id in ids: list.add($id) return list # HTMLFormControlsCollection proc namedItem(ctx: JSContext; this: HTMLFormControlsCollection; name: CAtom): JSValue {.jsfunc.} = let nodes0 = newCollection[RadioNodeList]( ctx, this.root, proc(ctx: JSContext; this: Collection; node: Node): Opt[bool] = let this = RadioNodeList(this) if not ?this.parent.match(ctx, this.parent, node): return ok(false) let element = Element(node) let name = this.atoms[0] ok(element.id == name or element.namespaceURI == satNamespaceHTML and element.name == name), islive = true, childonly = false ) if nodes0.isErr: return JS_EXCEPTION let nodes = nodes0.get nodes.parent = this nodes.atoms = @[name] let len0 = ctx.getLength(nodes) if len0.isErr: return JS_EXCEPTION let len = len0.get if len == 0: return JS_NULL if len == 1: return ctx.toJS(nodes.snapshot[0]) return ctx.toJS(nodes) proc names(ctx: JSContext; this: HTMLFormControlsCollection): JSPropertyEnumList {.jspropnames.} = return ctx.names(HTMLCollection(this)) proc getter(ctx: JSContext; this: HTMLFormControlsCollection; atom: JSAtom): JSValue {.jsgetownprop.} = var u: uint32 var s: CAtom return case ctx.fromIdx(atom, u, s) of fiIdx: ctx.toJS(ctx.item(this, u)).uninitIfNull() of fiStr: ctx.namedItem(this, s).uninitIfNull() of fiErr: JS_EXCEPTION # HTMLAllCollection proc length(ctx: JSContext; this: HTMLAllCollection): Opt[uint32] {.jsfget.} = return ctx.getLength(this) proc item(ctx: JSContext; this: HTMLAllCollection; u: uint32): Opt[Element] {. jsfunc.} = if u < ?ctx.getLength(this): return ok(Element(this.snapshot[u])) ok(nil) proc getter(ctx: JSContext; this: HTMLAllCollection; atom: JSAtom): JSValue {.jsgetownprop.} = var u: uint32 return case ctx.fromIdx(atom, u) of fiIdx: ctx.toJS(ctx.item(this, u)).uninitIfNull() of fiStr: JS_UNINITIALIZED of fiErr: JS_EXCEPTION proc names(ctx: JSContext; this: HTMLAllCollection): JSPropertyEnumList {.jspropnames.} = #TODO handle exception let L = ctx.getLength(this).get(0) var list = newJSPropertyEnumList(ctx, L) for u in 0 ..< L: list.add(u) return list proc all(ctx: JSContext; document: Document): JSValue {.jsfget.} = if document.cachedAll == nil: let res = newCollection[HTMLAllCollection]( ctx, root = document, match = isElement, islive = true, childonly = false ) if res.isErr: return JS_EXCEPTION document.cachedAll = res.get let val = ctx.toJS(document.cachedAll) JS_SetIsHTMLDDA(ctx, val) return val return ctx.toJS(document.cachedAll) # Location proc newLocation*(window: Window): Location = let location = Location(window: window) let ctx = window.jsctx if ctx != nil: let val = ctx.toJS(location) let valueOf0 = ctx.getOpaque().valRefs[jsvObjectPrototypeValueOf] let valueOf = JS_DupValue(ctx, valueOf0) doAssert ctx.defineProperty(val, "valueOf", valueOf) != dprException doAssert ctx.defineProperty(val, "toPrimitive", JS_UNDEFINED) != dprException #TODO [[DefaultProperties]] JS_FreeValue(ctx, val) return location proc document(location: Location): Document = return location.window.document proc url(location: Location): URL = let document = location.document if document != nil: return document.url return parseURL0("about:blank") # Note: we do not implement security checks (as documents are in separate # windows anyway). proc `$`(location: Location): string {.jsuffunc: "toString".} = return location.url.serialize() proc href(location: Location): string {.jsuffget.} = return $location proc setHref(ctx: JSContext; location: Location; s: string): JSValue {. jsfset: "href", jsuffunc: "assign", jsuffunc: "replace".} = if location.document == nil: return JS_UNDEFINED return ctx.setLocation(location.document, s) proc reload(location: Location) {.jsuffunc.} = if location.document == nil: return location.document.window.navigate(location.url) proc origin*(location: Location): string {.jsuffget.} = return location.url.jsOrigin proc protocol(ctx: JSContext; location: Location): JSValue {.jsuffget.} = return ctx.protocol(location.url) proc setProtocol(ctx: JSContext; location: Location; s: string): JSValue {.jsfset: "protocol".} = let document = location.document if document == nil: return JS_UNDEFINED let copyURL = newURL(location.url) copyURL.setProtocol(s) if copyURL.schemeType notin {stHttp, stHttps}: return JS_ThrowDOMException(ctx, "SyntaxError", "invalid URL") document.window.navigate(copyURL) return JS_UNDEFINED proc host(location: Location): string {.jsuffget.} = return location.url.host proc setHost(location: Location; s: string) {.jsfset: "host".} = let document = location.document if document == nil: return let copyURL = newURL(location.url) copyURL.setHost(s) document.window.navigate(copyURL) proc hostname(location: Location): string {.jsuffget.} = return location.url.hostname proc setHostname(location: Location; s: string) {.jsfset: "hostname".} = let document = location.document if document == nil: return let copyURL = newURL(location.url) copyURL.setHostname(s) document.window.navigate(copyURL) proc port(location: Location): string {.jsuffget.} = return location.url.port proc setPort(location: Location; s: string) {.jsfset: "port".} = let document = location.document if document == nil: return let copyURL = newURL(location.url) copyURL.setPort(s) document.window.navigate(copyURL) proc pathname(location: Location): string {.jsuffget.} = return location.url.pathname proc setPathname(location: Location; s: string) {.jsfset: "pathname".} = let document = location.document if document == nil: return let copyURL = newURL(location.url) copyURL.setPathname(s) document.window.navigate(copyURL) proc search(location: Location): string {.jsuffget.} = return location.url.search proc setSearch(location: Location; s: string) {.jsfset: "search".} = let document = location.document if document == nil: return let copyURL = newURL(location.url) copyURL.setSearch(s) document.window.navigate(copyURL) proc hash(location: Location): string {.jsuffget.} = return location.url.hash proc setHash(location: Location; s: string) {.jsfset: "hash".} = let document = location.document if document == nil: return let copyURL = newURL(location.url) copyURL.setHash(s) document.window.navigate(copyURL) # Attr proc newAttr(element: Element; dataIdx: int): Attr = let attr = Attr( internalNext: element.document, dataIdx: dataIdx, ownerElement: element, ) let namespace = attr.data.namespace let qualifiedName = attr.data.qualifiedName if namespace == CAtomNull: # no namespace -> qualifiedName == localName attr.prefix = CAtomNull attr.localName = qualifiedName else: # namespace -> qualifiedName == prefix & ':' & localName let prefixs = ($qualifiedName).until(':') let prefixLen = prefixs.len attr.prefix = prefixs.toAtom() attr.localName = ($qualifiedName).substr(prefixLen + 1).toAtom() return attr proc jsOwnerElement(attr: Attr): Element {.jsfget: "ownerElement".} = if attr.ownerElement of AttrDummyElement: return nil return attr.ownerElement proc ownerDocument(attr: Attr): Document {.jsfget.} = return attr.ownerElement.ownerDocument proc data(attr: Attr): lent AttrData = return attr.ownerElement.attrs[attr.dataIdx] proc namespaceURI(attr: Attr): CAtom {.jsfget.} = return attr.data.namespace proc value(attr: Attr): string {.jsfget.} = return attr.data.value proc name(attr: Attr): CAtom {.jsfget.} = return attr.data.qualifiedName proc setValue(attr: Attr; s: string) {.jsfset: "value".} = attr.ownerElement.attr(attr.data.qualifiedName, s) # NamedNodeMap proc findAttr(map: NamedNodeMap; dataIdx: int): int = for i, attr in map.attrlist.mypairs: if attr.dataIdx == dataIdx: return i return -1 proc getAttr(map: NamedNodeMap; dataIdx: int): Attr = let i = map.findAttr(dataIdx) if i != -1: return map.attrlist[i] let attr = map.element.newAttr(dataIdx) map.attrlist.add(attr) return attr proc getNamedItem(map: NamedNodeMap; qualifiedName: CAtom): Attr {.jsfunc.} = let i = map.element.findAttr(qualifiedName) if i != -1: return map.getAttr(i) return nil proc getNamedItemNS(map: NamedNodeMap; namespace, localName: CAtom): Attr {.jsfunc.} = let i = map.element.findAttrNS(namespace, localName) if i != -1: return map.getAttr(i) return nil proc length(map: NamedNodeMap): uint32 {.jsfget.} = return uint32(map.element.attrs.len) proc item(map: NamedNodeMap; i: uint32): Attr {.jsfunc.} = if int(i) < map.element.attrs.len: return map.getAttr(int(i)) return nil proc getter(ctx: JSContext; this: NamedNodeMap; atom: JSAtom): JSValue {.jsgetownprop.} = var u: uint32 var s: CAtom return case ctx.fromIdx(atom, u, s) of fiIdx: ctx.toJS(this.item(u)).uninitIfNull() of fiStr: ctx.toJS(this.getNamedItem(s)).uninitIfNull() of fiErr: JS_EXCEPTION proc names(ctx: JSContext; map: NamedNodeMap): JSPropertyEnumList {.jspropnames.} = let len = if map.element.namespaceURI == satNamespaceHTML: uint32(map.attrlist.len + map.element.attrs.len) else: uint32(map.attrlist.len) var list = newJSPropertyEnumList(ctx, len) for u in 0 ..< len: list.add(u) let element = map.element for attr in element.attrs: let name = attr.qualifiedName if element.namespaceURI == satNamespaceHTML and name.toLowerAscii() != name: continue list.add($name) return list # CharacterData proc length(this: CharacterData): int {.jsfget.} = return ($this.data).utf16Len proc previousElementSibling(this: CharacterData): Element {.jsfget.} = return this.previousElementSiblingImpl proc nextElementSibling(this: CharacterData): Element {.jsfget.} = return this.nextElementSiblingImpl proc remove(this: CharacterData) {.jsfunc.} = Node(this).remove() # Element proc hash(element: Element): Hash = return hash(cast[pointer](element)) proc firstElementChild(this: Element): Element {.jsfget.} = return ParentNode(this).firstElementChild proc lastElementChild(this: Element): Element {.jsfget.} = return ParentNode(this).lastElementChild proc childElementCount(this: Element): int {.jsfget.} = return this.childElementCountImpl proc isFirstVisualNode*(element: Element): bool = if element.elIndex == 0: let parent = element.parentNode for child in parent.childList: if child == element: return true if child of Text and not Text(child).data.s.onlyWhitespace(): break return false proc isLastVisualNode*(element: Element): bool = let parent = element.parentNode for child in parent.rchildList: if child == element: return true if child of Element: break if child of Text and not Text(child).data.s.onlyWhitespace(): break return false proc innerHTML(element: Element): string {.jsfget.} = #TODO xml return element.serializeFragment(writeShadow = true) proc outerHTML(element: Element): string {.jsfget.} = #TODO xml result = "" result.serializeFragmentInner(element, TAG_UNKNOWN, writeShadow = true) proc tagTypeNoNS(element: Element): TagType = return element.localName.toTagType() proc tagType*(element: Element; namespace = satNamespaceHTML): TagType = if element.namespaceURI != namespace: return TAG_UNKNOWN return element.tagTypeNoNS proc tagName(element: Element): string {.jsfget.} = result = $element.prefix if result.len > 0: result &= ':' result &= $element.localName if element.namespaceURI == satNamespaceHTML: result = result.toUpperAscii() proc normalizeAttrQName(element: Element; qualifiedName: CAtom): CAtom = if element.namespaceURI == satNamespaceHTML and not element.document.isxml: return qualifiedName.toLowerAscii() return qualifiedName proc cmpAttrName(a: AttrData; b: CAtom): int = return cmp(uint32(a.qualifiedName), uint32(b)) proc findAttr(element: Element; qualifiedName: CAtom): int = let qualifiedName = element.normalizeAttrQName(qualifiedName) let n = element.attrs.lowerBound(qualifiedName, cmpAttrName) if n < element.attrs.len and element.attrs[n].qualifiedName == qualifiedName: return n return -1 proc matchesLocalName(qualifiedName, localName: CAtom): bool = let i = ($qualifiedName).find(':') + 1 if i == 0: return qualifiedName == localName return ($qualifiedName).toOpenArray(i, ($qualifiedName).high) == $localName proc findAttrNS(element: Element; namespace, localName: CAtom): int = if namespace == CAtomNull: for i, attr in element.attrs.mypairs: if attr.namespace == CAtomNull and attr.qualifiedName == localName: return i return -1 # Potentially slow path, since we don't store namespace prefixes separately. # Still preferable to wasting memory for XML brain damage. for i, attr in element.attrs.mypairs: if attr.namespace == namespace and attr.qualifiedName.matchesLocalName(localName): return i return -1 proc hasAttributes(element: Element): bool {.jsfunc.} = return element.attrs.len > 0 proc attributes(ctx: JSContext; element: Element): JSValue {.jsfget.} = return ctx.getWeakCollection(element, wwmAttributes) proc cachedAttributes(ctx: JSContext; element: Element): NamedNodeMap = let this = ctx.toJS(element) if JS_IsException(this): return nil let res = ctx.getWeak(wwmAttributes, this) JS_FreeValue(ctx, this) var map: NamedNodeMap if ctx.fromJSFree(res, map).isErr: return nil return map proc hasAttribute(element: Element; qualifiedName: CAtom): bool {.jsfunc.} = return element.findAttr(qualifiedName) != -1 proc hasAttributeNS(element: Element; namespace, localName: CAtom): bool {.jsfunc.} = return element.findAttrNS(namespace, localName) != -1 proc getAttributeNames(ctx: JSContext; element: Element): JSValue {.jsfunc.} = var s = newSeqOfCap[JSValue](element.attrs.len) for it in element.attrs: s.add(ctx.toJS(it.qualifiedName)) return ctx.newArrayFrom(s) proc getAttribute(ctx: JSContext; element: Element; qualifiedName: CAtom): JSValue {.jsfunc.} = let i = element.findAttr(qualifiedName) if i != -1: return ctx.toJS(element.attrs[i].value) return JS_NULL proc getAttributeNS(ctx: JSContext; element: Element; namespace, localName: CAtom): JSValue {.jsfunc.} = let i = element.findAttrNS(namespace, localName) if i != -1: return ctx.toJS(element.attrs[i].value) return JS_NULL proc attr*(element: Element; s: CAtom): lent string = let i = element.findAttr(s) if i != -1: return element.attrs[i].value # the compiler cries if I return string literals :/ let emptyStr {.global.} = "" return emptyStr proc attr*(element: Element; s: StaticAtom): lent string = return element.attr(s.toAtom()) proc attrl*(element: Element; s: StaticAtom): Opt[int32] = return parseInt32(element.attr(s)) proc attrulgz*(element: Element; s: StaticAtom): Opt[uint32] = let x = parseUInt32(element.attr(s), allowSign = true).get(0) if x > 0: return ok(x) err() proc attrul*(element: Element; s: StaticAtom): Opt[uint32] = return parseUInt32(element.attr(s), allowSign = true) proc attrd*(element: Element; s: StaticAtom): Opt[float64] = let d = parseFloat64(element.attr(s)) if isNaN(d): return err() ok(d) proc attrdgz*(element: Element; s: StaticAtom): Opt[float64] = let d = element.attrd(s).get(0) if d <= 0: return err() ok(d) proc attrb*(element: Element; s: CAtom): bool = return element.findAttr(s) != -1 proc attrb*(element: Element; at: StaticAtom): bool = return element.attrb(at.toAtom()) proc getElementsByTagName(ctx: JSContext; element: Element; tagName: string): Opt[HTMLCollection] {.jsfunc.} = return ctx.getElementsByTagNameImpl(element, tagName) proc getElementsByClassName(ctx: JSContext; element: Element; classNames: string): Opt[HTMLCollection] {.jsfunc.} = return ctx.getElementsByClassNameImpl(element, classNames) proc children(ctx: JSContext; parentNode: Element): JSValue {.jsfget.} = return childrenImpl(ctx, parentNode) proc previousElementSibling*(element: Element): Element {.jsfget.} = return element.previousElementSiblingImpl proc nextElementSibling*(element: Element): Element {.jsfget.} = return element.nextElementSiblingImpl proc remove(element: Element) {.jsfunc.} = Node(element).remove() proc isDisplayed(element: Element): bool = element.ensureStyle() return element.computed{"display"} != DisplayNone proc nextDisplayedElement(element: Element): Element = for child in element.elementList: if child.isDisplayed(): return child # climb up until we find a non-last leaf (this might be node itself) var element = element while true: var next = element.nextElementSibling while next != nil: if next.isDisplayed(): return next next = next.nextElementSibling element = element.parentElement if element == nil: break # done return nil proc scriptingEnabled(element: Element): bool = return element.document.scriptingEnabled proc isSubmitButton*(element: Element): bool = if element of HTMLButtonElement: return element.attr(satType).equalsIgnoreCase("submit") elif element of HTMLInputElement: let element = HTMLInputElement(element) return element.inputType in {itSubmit, itImage} return false proc isButton*(element: Element): bool = if element of HTMLButtonElement: return true if element of HTMLInputElement: let element = HTMLInputElement(element) return element.inputType in {itSubmit, itButton, itReset, itImage} return false proc action*(element: Element): string = if element.isSubmitButton(): if element.attrb(satFormaction): return element.attr(satFormaction) if element of FormAssociatedElement: let element = FormAssociatedElement(element) if element.form != nil: if element.form.attrb(satAction): return element.form.attr(satAction) if element of HTMLFormElement: return element.attr(satAction) return "" proc enctype*(element: Element): FormEncodingType = if element of HTMLFormElement: # Note: see below, this is not in the standard. if element.attrb(satEnctype): let s = element.attr(satEnctype) return parseEnumNoCase[FormEncodingType](s).get(fetUrlencoded) if element.isSubmitButton(): if element.attrb(satFormenctype): let s = element.attr(satFormenctype) return parseEnumNoCase[FormEncodingType](s).get(fetUrlencoded) if element of FormAssociatedElement: let element = FormAssociatedElement(element) if (let form = element.form; form != nil): if form.attrb(satEnctype): let s = form.attr(satEnctype) return parseEnumNoCase[FormEncodingType](s).get(fetUrlencoded) return fetUrlencoded proc getFormMethod*(element: Element): FormMethod = if element.tagType == TAG_FORM: # The standard says nothing about this, but this code path is reached # on implicit form submission and other browsers seem to agree on this # behavior. return parseFormMethod(element.attr(satMethod)) if element.isSubmitButton(): if element.attrb(satFormmethod): return parseFormMethod(element.attr(satFormmethod)) if element of FormAssociatedElement: let element = FormAssociatedElement(element) if element.form != nil: if element.form.attrb(satMethod): return parseFormMethod(element.form.attr(satMethod)) return fmGet proc scrollTo(element: Element) {.jsfunc.} = discard #TODO maybe in app mode? proc scrollIntoView(element: Element) {.jsfunc.} = discard #TODO ditto proc fragmentParsingAlgorithm*(element: Element; s: string): DocumentFragment = #TODO xml let newChildren = parseHTMLFragmentImpl(element, s) let fragment = element.document.newDocumentFragment() for child in newChildren: fragment.append(child) return fragment proc innerHTML(element: Element; s: string) {.jsfset.} = #TODO shadow root let fragment = fragmentParsingAlgorithm(element, s) let ctx = if element of HTMLTemplateElement: HTMLTemplateElement(element).content else: element ctx.replaceAll(fragment) proc outerHTML(ctx: JSContext; element: Element; s: string): JSValue {.jsfset.} = let parent0 = element.parentNode if parent0 == nil: return JS_UNDEFINED if parent0 of Document: return JS_ThrowDOMException(ctx, "NoModificationAllowedError", "outerHTML is disallowed for document elements") let parent: Element = if parent0 of DocumentFragment: element.document.newHTMLElement(TAG_BODY) else: # neither a document, nor a document fragment => parent must be an # element node Element(parent0) let fragment = fragmentParsingAlgorithm(parent, s) return ctx.replaceChildUndefined(parent, element, fragment) type InsertAdjacentPosition = enum iapBeforeBegin = "beforebegin" iapAfterEnd = "afterend" iapAfterBegin = "afterbegin" iapBeforeEnd = "beforeend" proc insertAdjacentHTML(ctx: JSContext; this: Element; position, text: string): JSValue {.jsfunc.} = let pos0 = parseEnumNoCase[InsertAdjacentPosition](position) if pos0.isErr: return JS_ThrowDOMException(ctx, "SyntaxError", "invalid position") let position = pos0.get var nodeCtx = this if position in {iapBeforeBegin, iapAfterEnd}: if this.parentNode of Document or this.parentNode == nil: return JS_ThrowDOMException(ctx, "NoModificationAllowedError", "parent is not a valid element") nodeCtx = this.parentElement if nodeCtx == nil or not this.document.isxml and nodeCtx.tagType == TAG_HTML: nodeCtx = this.document.newHTMLElement(TAG_BODY) let fragment = nodeCtx.fragmentParsingAlgorithm(text) case position of iapBeforeBegin: this.parentNode.insert(fragment, this) of iapAfterBegin: this.insert(fragment, this.firstChild) of iapBeforeEnd: this.append(fragment) of iapAfterEnd: this.parentNode.insert(fragment, this.nextSibling) return JS_UNDEFINED proc insertAdjacent(ctx: JSContext; this: Node; position: string; node: Node): JSValue = let pos0 = parseEnumNoCase[InsertAdjacentPosition](position) if pos0.isErr: return JS_ThrowDOMException(ctx, "SyntaxError", "invalid position") let position = pos0.get return case position of iapBeforeBegin: if this.parentNode == nil: JS_NULL else: ctx.insertBefore(this.parentNode, node, option(this)) of iapAfterBegin: ctx.insertBefore(this, node, option(this.firstChild)) of iapBeforeEnd: ctx.insertBefore(this, node, none(Node)) of iapAfterEnd: ctx.insertBefore(this.parentNode, node, option(this.nextSibling)) proc insertAdjacentElement(ctx: JSContext; this: Element; position: string; element: Element): JSValue {.jsfunc.} = ctx.insertAdjacent(this, position, element) proc insertAdjacentText(ctx: JSContext; this: Element; position, s: string): JSValue {.jsfunc.} = ctx.toUndefined(ctx.insertAdjacent(this, position, this.document.newText(s))) proc hover*(element: Element): bool = return efHover in element.flags proc setHover*(element: Element; hover: bool) = if element.hover != hover: element.flags.toggle({efHover}) element.invalidate(dtHover) proc parseColor(element: Element; s: string): Opt[ARGBColor] = var ctx = initCSSParser(s) if color := ctx.parseColor(): case color.t of cctARGB: return ok(color.argb) of cctCurrent: let window = element.document.window if window != nil and window.settings.scripting == smApp and element.isConnected(): element.ensureStyle() if element.computed{"color"}.t == cctARGB: return ok(element.computed{"color"}.argb) return ok(rgba(0, 0, 0, 255)) of cctCell: discard return err() proc getBoundingClientRect(element: Element): DOMRect {.jsfunc.} = let window = element.document.window if window == nil: return DOMRect() if window.settings.scripting == smApp: window.ensureLayout(element) let objs = getClientRectsImpl(element, firstOnly = true, blockOnly = false) if objs.len > 0: return objs[0] return DOMRect() var width = float64(dummyAttrs.ppc) var height = float64(dummyAttrs.ppl) if element of HTMLImageElement: (width, height) = HTMLImageElement(element).getImageRect() return DOMRect(width: width, height: height) proc getClientRects(element: Element): DOMRectList {.jsfunc.} = let res = DOMRectList() let window = element.document.window if window != nil: if window.settings.scripting == smApp: window.ensureLayout(element) res.list = getClientRectsImpl(element, firstOnly = false, blockOnly = false) else: res.list.add(element.getBoundingClientRect()) res proc getBlockRect(element: Element): DOMRect = let window = element.document.window if window != nil: if window.settings.scripting != smApp: return element.getBoundingClientRect() window.ensureLayout(element) let res = element.getClientRectsImpl(firstOnly = true, blockOnly = true) if res.len > 0: return res[0] return DOMRect() proc clientWidth(element: Element): int32 {.jsfget.} = let rect = element.getBlockRect() if rect != nil and rect.width <= float64(int32.high): return int32(rect.width) 0 proc clientHeight(element: Element): int32 {.jsfget.} = let rect = element.getBlockRect() if rect != nil and rect.height <= float64(int32.high): return int32(rect.height) 0 const WindowEvents* = [satError, satLoad, satFocus, satBlur] proc reflectScriptAttr(element: Element; name: StaticAtom; value: string): bool = let document = element.document const ScriptEventMap = { satOnclick: satClick, satOninput: satInput, satOnchange: satChange, satOnload: satLoad, satOnerror: satError, satOnblur: satBlur, satOnfocus: satFocus, satOnsubmit: satSubmit, satOncontextmenu: satContextmenu, satOndblclick: satDblclick, } for (n, t) in ScriptEventMap: if n == name: var target = EventTarget(element) var target2 = none(EventTarget) if element.tagType == TAG_BODY and t in WindowEvents: target = document.window target2 = option(EventTarget(element)) document.reflectEvent(target, n, t, value, target2) return true false proc reflectLocalAttr(element: Element; name: StaticAtom; has: bool; value: string) = case element.tagType of TAG_INPUT: let input = HTMLInputElement(element) case name of satValue: input.setValue(value) of satChecked: input.setChecked(has) of satType: input.inputType = parseEnumNoCase[InputType](value).get(itText) else: discard of TAG_OPTION: let option = HTMLOptionElement(element) if name == satSelected: option.selected = has of TAG_BUTTON: let button = HTMLButtonElement(element) if name == satType: button.ctype = parseEnumNoCase[ButtonType](value).get(btSubmit) of TAG_LINK: let link = HTMLLinkElement(element) if name == satRel: link.relList.reflectTokens(value) # do not return let document = link.document let connected = link.isConnected() if name == satDisabled: let wasDisabled = link.isDisabled() link.enabled = some(not has) let disabled = link.isDisabled() if wasDisabled != disabled: for sheet in link.sheets: sheet.disabled = disabled if connected: document.ruleMap = nil let html = document.documentElement if html != nil: html.invalidate() if connected and name in {satHref, satRel, satDisabled}: link.fetchStarted = false let window = document.window if window != nil: window.loadLink(link) of TAG_A: let anchor = HTMLAnchorElement(element) if name == satRel: anchor.relList.reflectTokens(value) of TAG_AREA: let area = HTMLAreaElement(element) if name == satRel: area.relList.reflectTokens(value) of TAG_CANVAS: if element.scriptingEnabled and name in {satWidth, satHeight}: let w = element.attrul(satWidth).get(300) let h = element.attrul(satHeight).get(150) if w <= uint64(int.high) and h <= uint64(int.high): let w = int(w) let h = int(h) let canvas = HTMLCanvasElement(element) if canvas.bitmap == nil or canvas.bitmap.width != w or canvas.bitmap.height != h: let window = element.document.window if canvas.ctx2d != nil and canvas.ctx2d.ps != nil: let i = window.pendingCanvasCtls.find(canvas.ctx2d) window.pendingCanvasCtls.del(i) canvas.ctx2d.ps.sclose() canvas.ctx2d = nil canvas.bitmap = NetworkBitmap( contentType: "image/x-cha-canvas", imageId: window.getImageId(), cacheId: -1, width: w, height: h ) of TAG_IMG: let image = HTMLImageElement(element) # https://html.spec.whatwg.org/multipage/images.html#relevant-mutations if name == satSrc: image.fetchStarted = false let window = image.document.window if window != nil: window.loadImage(image) else: discard # Called whenever an attribute changes on the element. # If `has' is false, then value is "". Otherwise, value is the new # attribute value. proc reflectAttr(element: Element; name: CAtom; has: bool; value: string) = let name = name.toStaticAtom() case name of satId: if has: element.id = value.toAtom() else: element.id = CAtomNull of satName: if has: element.name = value.toAtom() else: element.name = CAtomNull of satClass: element.classList.reflectTokens(value) #TODO internalNonce of satStyle: if has: element.cachedStyle = newCSSStyleDeclaration(element, value) else: element.cachedStyle = nil of satUnknown: discard # early return elif element.scriptingEnabled and element.reflectScriptAttr(name, value): discard else: element.reflectLocalAttr(name, has, value) proc reflectAttrDel(element: Element; name: CAtom) = element.reflectAttr(name, false, "") proc reflectAttr(element: Element; name: CAtom; value: string) = element.reflectAttr(name, true, value) proc elIndex*(this: Element): int = if this.parentNode == nil: return -1 let parent = this.parentElement if parent == nil: return 0 # <html> if parent.childElIndicesInvalid: var n = 0 for element in parent.elementList: element.internalElIndex = n inc n parent.childElIndicesInvalid = false return this.internalElIndex proc isPreviousSiblingOf*(this, other: Element): bool = return this.parentNode == other.parentNode and this.elIndex <= other.elIndex proc querySelector(ctx: JSContext; this: Element; q: string): JSValue {.jsfunc.} = return ctx.querySelectorImpl(this, q) proc querySelectorAll(ctx: JSContext; this: Element; q: string): JSValue {.jsfunc.} = return ctx.querySelectorAllImpl(this, q) proc isDisabled*(this: Element): bool = case this.tagType of TAG_BUTTON, TAG_INPUT, TAG_SELECT, TAG_TEXTAREA, TAG_FIELDSET: if this.attrb(satDisabled): return true var lastLegend: Element = nil for it in this.ancestors: case it.tagType of TAG_LEGEND: lastLegend = it of TAG_FIELDSET: if it.attrb(satDisabled): return it.firstChild != lastLegend else: discard return false of TAG_OPTGROUP: return this.attrb(satDisabled) of TAG_OPTION: let parent = this.parentElement return parent.tagType == TAG_OPTGROUP and parent.attrb(satDisabled) or this.attrb(satDisabled) else: #TODO form-associated custom element return false #TODO custom elements proc newElement*(document: Document; localName, namespaceURI, prefix: CAtom): Element = let tagType = localName.toTagType() let sns = namespaceURI.toStaticAtom() let element: Element = case tagType of TAG_INPUT: HTMLInputElement() of TAG_A: let anchor = HTMLAnchorElement(internalNext: document) anchor.relList = anchor.newDOMTokenList(satRel) anchor of TAG_SELECT: HTMLSelectElement() of TAG_OPTGROUP: HTMLOptGroupElement() of TAG_OPTION: HTMLOptionElement() of TAG_H1, TAG_H2, TAG_H3, TAG_H4, TAG_H5, TAG_H6: HTMLHeadingElement() of TAG_BR: HTMLBRElement() of TAG_SPAN: HTMLSpanElement() of TAG_OL: HTMLOListElement() of TAG_UL: HTMLUListElement() of TAG_MENU: HTMLMenuElement() of TAG_LI: HTMLLIElement() of TAG_STYLE: HTMLStyleElement() of TAG_LINK: let link = HTMLLinkElement(internalNext: document) link.relList = link.newDOMTokenList(satRel) link of TAG_FORM: let form = HTMLFormElement(internalNext: document) form.relList = form.newDOMTokenList(satRel) form of TAG_TEMPLATE: let templ = HTMLTemplateElement(content: newDocumentFragment(document)) templ.content.host = templ templ of TAG_UNKNOWN: HTMLUnknownElement() of TAG_SCRIPT: HTMLScriptElement(forceAsync: true) of TAG_BASE: HTMLBaseElement() of TAG_BUTTON: HTMLButtonElement() of TAG_TEXTAREA: HTMLTextAreaElement() of TAG_LABEL: HTMLLabelElement() of TAG_CANVAS: let imageId = if document.window != nil: -1 else: document.window.getImageId() let bitmap = if document.scriptingEnabled: NetworkBitmap( contentType: "image/x-cha-canvas", imageId: imageId, cacheId: -1, width: 300, height: 150 ) else: nil HTMLCanvasElement(bitmap: bitmap) of TAG_IMG: HTMLImageElement() of TAG_VIDEO: HTMLVideoElement() of TAG_AUDIO: HTMLAudioElement() of TAG_AREA: let area = HTMLAreaElement(internalNext: document) area.relList = area.newDOMTokenList(satRel) area of TAG_TABLE: HTMLTableElement() of TAG_CAPTION: HTMLTableCaptionElement() of TAG_TR: HTMLTableRowElement() of TAG_TBODY, TAG_THEAD, TAG_TFOOT: HTMLTableSectionElement() of TAG_META: HTMLMetaElement() of TAG_IFRAME: HTMLIFrameElement() of TAG_DETAILS: HTMLDetailsElement() of TAG_FRAME: HTMLFrameElement() of TAG_Q, TAG_BLOCKQUOTE: HTMLQuoteElement() of TAG_DATA: HTMLDataElement() of TAG_HEAD: HTMLHeadElement() of TAG_TITLE: HTMLTitleElement() of TAG_OBJECT: HTMLObjectElement() of TAG_SOURCE: HTMLSourceElement() of TAG_INS, TAG_DEL: HTMLModElement() of TAG_PROGRESS: HTMLProgressElement() elif sns == satNamespaceSVG: if tagType == TAG_SVG: SVGSVGElement() else: SVGElement() else: HTMLElement() element.localName = localName element.namespaceURI = namespaceURI element.prefix = prefix element.internalNext = document element.classList = element.newDOMTokenList(satClass) element.internalElIndex = -1 element.custom = if localName.isValidCustomElementName(): cesUndefined else: cesUncustomized element proc newElement*(document: Document; localName: CAtom; namespace = Namespace.HTML; prefix = NO_PREFIX): Element = return document.newElement(localName, namespace.toAtom(), prefix.toAtom()) proc renderBlocking(element: Element): bool = if element.attr(satBlocking).containsToken("render"): return true if element of HTMLScriptElement: let element = HTMLScriptElement(element) if element.ctype == stClassic and element.parserDocument != nil and not element.attrb(satAsync) and not element.attrb(satDefer): return true return false proc blockRendering(element: Element) = let document = element.document if document.contentType == satTextHtml and document.body == nil: element.document.renderBlockingElements.add(element) proc invalidate*(element: Element) = let valid = element.computed != nil and not element.computed.invalid if element.computed != nil: element.computed.invalid = true element.document.invalid = true if valid: for it in element.elementList: it.invalidate() proc ensureStyle(element: Element) = if element.computed == nil or element.computed.invalid: element.applyStyleImpl() proc resetElement*(element: Element) = case element.tagType of TAG_INPUT: let input = HTMLInputElement(element) case input.inputType of itCheckbox, itRadio: input.setChecked(input.attrb(satChecked)) of itFile: input.files.setLen(0) else: input.setValue(input.attr(satValue)) input.invalidate() of TAG_SELECT: let select = HTMLSelectElement(element) select.userValidity = false for option in select.options: if option.attrb(satSelected): option.selected = true else: option.selected = false option.dirty = false option.invalidate(dtChecked) select.setSelectedness() of TAG_TEXTAREA: let textarea = HTMLTextAreaElement(element) textarea.dirty = false textarea.invalidate() else: discard # Returns true if has post-connection steps. proc elementInsertionSteps(element: Element): bool = case element.tagType of TAG_OPTION: if element.parentElement != nil: let parent = element.parentElement var select: HTMLSelectElement if parent of HTMLSelectElement: select = HTMLSelectElement(parent) elif parent.tagType == TAG_OPTGROUP and parent.parentElement != nil and parent.parentElement of HTMLSelectElement: select = HTMLSelectElement(parent.parentElement) if select != nil: select.setSelectedness() of TAG_LINK: let link = HTMLLinkElement(element) let document = link.document if link.isConnected() and document.sheetTitle == "" and link.enabled.get(true) and not link.relList.containsIgnoreCase(satAlternate): document.sheetTitle = link.attr(satTitle) let window = document.window if window != nil: window.loadLink(link) of TAG_IMG: let window = element.document.window if window != nil: let image = HTMLImageElement(element) window.loadImage(image) of TAG_STYLE: let style = HTMLStyleElement(element) if style.isConnected(): let document = style.document if document.sheetTitle == "": document.sheetTitle = style.attr(satTitle) style.updateSheet() of TAG_SCRIPT: return true elif element of FormAssociatedElement: let element = FormAssociatedElement(element) if element.parserInserted: return element.resetFormOwner() false proc postConnectionSteps(element: Element) = let script = HTMLScriptElement(element) if script.isConnected and script.parserDocument == nil: script.prepare() proc prepend(ctx: JSContext; this: Element; nodes: varargs[JSValueConst]): JSValue {.jsfunc.} = return ctx.prependImpl(this, nodes) proc append(ctx: JSContext; this: Element; nodes: varargs[JSValueConst]): JSValue {.jsfunc.} = return ctx.appendImpl(this, nodes) proc replaceChildren(ctx: JSContext; this: Element; nodes: varargs[JSValueConst]): JSValue {.jsfunc.} = return ctx.replaceChildrenImpl(this, nodes) proc delAttr(ctx: JSContext; element: Element; i: int) = let name = element.attrs[i].qualifiedName let map = ctx.cachedAttributes(element) if map != nil: # delete from attrlist + adjust indices invalidated var j = -1 for k, attr in map.attrlist.mypairs: if attr.dataIdx == i: j = k elif attr.dataIdx > i: dec attr.dataIdx if j != -1: let attr = map.attrlist[j] let data = attr.data attr.ownerElement = AttrDummyElement( internalNext: attr.ownerElement.document, internalElIndex: -1, attrs: @[data] ) attr.dataIdx = 0 map.attrlist.del(j) # ordering does not matter element.attrs.delete(i) # ordering matters element.reflectAttrDel(name) element.document.invalidateCollections() element.invalidate() # Returns the attr index if found, or the negation - 1 of an upper bound # (where a new attr with the passed name may be inserted). proc findAttrOrNext(element: Element; qualName: CAtom): int = for i, data in element.attrs.mypairs: if data.qualifiedName == qualName: return i if int(data.qualifiedName) > int(qualName): return -(i + 1) return -(element.attrs.len + 1) proc attr*(element: Element; name: CAtom; value: sink string) = var i = element.findAttrOrNext(name) if i >= 0: element.attrs[i].value = value else: i = -(i + 1) element.attrs.insert(AttrData( namespace: CAtomNull, qualifiedName: name, value: value ), i) element.reflectAttr(name, element.attrs[i].value) element.document.invalidateCollections() element.invalidate() proc attr*(element: Element; name: StaticAtom; value: sink string) = element.attr(name.toAtom(), value) proc attrns0(element: Element; namespace, localName, qualifiedName: CAtom; value: sink string) = var i = element.findAttrNS(namespace, localName) if i != -1: element.attrs[i].value = value else: i = element.attrs.upperBound(qualifiedName, cmpAttrName) element.attrs.insert(AttrData( namespace: namespace, qualifiedName: qualifiedName, value: value ), i) element.reflectAttr(qualifiedName, element.attrs[i].value) element.document.invalidateCollections() element.invalidate() proc attrns*(element: Element; localName: CAtom; prefix: NamespacePrefix; namespace: Namespace; value: sink string) = if prefix == NO_PREFIX and namespace == NO_NAMESPACE: element.attr(localName, value) return let namespace = namespace.toAtom() let qualifiedName = if prefix != NO_PREFIX: ($prefix & ':' & $localName).toAtom() else: localName element.attrns0(namespace, localName, qualifiedName, value) proc attrl(element: Element; name: StaticAtom; value: int32) = element.attr(name, $value) proc attrul(element: Element; name: StaticAtom; value: uint32) = element.attr(name, $value) proc attrulgz(element: Element; name: StaticAtom; value: uint32) = if value > 0: element.attrul(name, value) proc attrd(element: Element; name: StaticAtom; value: float64) = element.attr(name, dtoa(value)) proc setAttribute(ctx: JSContext; element: Element; qualifiedName: string; value: sink string): Opt[void] {.jsfunc.} = ?ctx.validateName(qualifiedName) let qualifiedName = if element.namespaceURI == satNamespaceHTML and not element.document.isxml: qualifiedName.toAtomLower() else: qualifiedName.toAtom() element.attr(qualifiedName, value) ok() proc setAttributeNS(ctx: JSContext; element: Element; namespace: CAtom; qualifiedName: string; value: sink string): Opt[void] {.jsfunc.} = ?ctx.validateQName(qualifiedName) let j = qualifiedName.find(':') let sprefix = if j != -1: qualifiedName.substr(0, j - 1) else: "" let qualifiedName = qualifiedName.toAtom() let prefix = sprefix.toAtom() let localName = if j == -1: qualifiedName else: ($qualifiedName).substr(j + 1).toAtom() if prefix != satUempty and namespace == satUempty or prefix == satXml and namespace != satNamespaceXML or satXmlns in [prefix, qualifiedName] and namespace != satNamespaceXMLNS or satXmlns notin [prefix, qualifiedName] and namespace == satNamespaceXMLNS: JS_ThrowDOMException(ctx, "NamespaceError", "unexpected namespace") return err() element.attrns0(namespace, localName, qualifiedName, value) ok() proc removeAttribute(ctx: JSContext; element: Element; qualifiedName: CAtom) {.jsfunc.} = let i = element.findAttr(qualifiedName) if i != -1: ctx.delAttr(element, i) proc removeAttributeNS(ctx: JSContext; element: Element; namespace, localName: CAtom) {.jsfunc.} = let i = element.findAttrNS(namespace, localName) if i != -1: ctx.delAttr(element, i) proc toggleAttribute(ctx: JSContext; element: Element; qualifiedName: string; force = none(bool)): Opt[bool] {.jsfunc.} = ?ctx.validateName(qualifiedName) let qualifiedName = element.normalizeAttrQName(qualifiedName.toAtom()) if not element.attrb(qualifiedName): if force.get(true): element.attr(qualifiedName, "") return ok(true) return ok(false) if not force.get(false): let i = element.findAttr(qualifiedName) if i != -1: ctx.delAttr(element, i) return ok(false) return ok(true) proc setId(element: Element; id: string) {.jsfset: "id".} = element.attr(satId, id) proc focus(ctx: JSContext; element: Element) {.jsfunc.} = let window = ctx.getWindow() if window != nil and window.settings.autofocus: element.document.setFocus(element) proc blur(ctx: JSContext; element: Element) {.jsfunc.} = let window = ctx.getWindow() if window != nil and window.settings.autofocus: if element.document.focus == element: element.document.setFocus(nil) proc hint*(element: Element): bool = efHint in element.flags proc setHint*(element: Element; hint: bool) = if element.hint != hint: element.flags.toggle({efHint}) element.invalidate() proc getCharset(element: Element): Charset = let charset = getCharset(element.attr(satCharset)) if charset != csUnknown: return charset return element.document.charset proc isDefined*(element: Element): bool = element.custom in {cesUncustomized, cesCustom} proc getProgressPosition*(element: Element): float64 = if not element.attrb(satValue): return -1 let value = element.attrdgz(satValue).get(0) let max = element.attrdgz(satMax).get(1) return min(value, max) / max proc getBitmap*(element: Element): NetworkBitmap = case element.tagType of TAG_IMG: return HTMLImageElement(element).bitmap of TAG_CANVAS: return HTMLCanvasElement(element).bitmap elif element.tagType(satNamespaceSVG) == TAG_SVG: return SVGSVGElement(element).bitmap else: return nil proc shadowRoot(this: Element): ShadowRoot {.jsfget.} = let first = this.internalFirst # note: you could optimize this by just checking if first.parentNode != this, # but it seems very risky so I won't if first of ShadowRoot: return cast[ShadowRoot](first) return nil proc setShadowRoot(this: Element; shadow: ShadowRoot) = if this.internalFirst != nil: shadow.internalNext = move(this.internalFirst) this.internalFirst = shadow proc attachShadow(ctx: JSContext; this: Element; init: ShadowRootInit): Opt[ShadowRoot] {.jsfunc.} = let document = this.document let customElements = if init.customElementRegistry != nil: init.customElementRegistry else: document.customElements if customElements != nil and not customElements.scoped and customElements != document.customElements: JS_ThrowDOMException(ctx, "NotSupportedError", "custom element registry is not scoped") return err() if this.namespaceURI != satNamespaceHTML: JS_ThrowDOMException(ctx, "NotSupportedError", "only HTML elements can have shadow trees") return err() const AllowedTags = { TAG_ARTICLE, TAG_ASIDE, TAG_BLOCKQUOTE, TAG_BODY, TAG_DIV, TAG_FOOTER, TAG_H1, TAG_H2, TAG_H3, TAG_H4, TAG_H5, TAG_H6, TAG_HEADER, TAG_MAIN, TAG_NAV, TAG_P, TAG_SECTION, TAG_SPAN } let validCustom = this.localName.isValidCustomElementName() if not validCustom and this.tagType notin AllowedTags: JS_ThrowDOMException(ctx, "NotSupportedError", "invalid tag name") return err() if validCustom: #TODO or is value is non-null #TODO check for disable shadow discard let old = this.shadowRoot if old != nil: if not old.declarative or old.mode != init.mode: JS_ThrowDOMException(ctx, "NotSupportedError", "cannot replace old shadow root") return err() let removedNodes = old.getChildList() for child in removedNodes: child.remove() old.declarative = false return ok(old) let shadow = ShadowRoot( internalNext: document, host: this, mode: init.mode, delegatesFocus: init.delegatesFocus, #TODO available to internals slotAssignment: init.slotAssignment, clonable: init.clonable, serializable: init.serializable, customElements: customElements ) this.setShadowRoot(shadow) ok(shadow) # ShadowRoot proc host(this: ShadowRoot): Element {.jsfget.} = DocumentFragment(this).host proc globalCustomElements(this: ShadowRoot): CustomElementRegistry = if not this.customElements.scoped: return this.customElements let document = this.document if not document.customElements.scoped: return document.customElements return nil # DOMRect proc left(rect: DOMRect): float64 {.jsfget.} = return min(rect.x, rect.x + rect.width) proc right(rect: DOMRect): float64 {.jsfget.} = return max(rect.x, rect.x + rect.width) proc top(rect: DOMRect): float64 {.jsfget.} = return min(rect.y, rect.y + rect.height) proc bottom(rect: DOMRect): float64 {.jsfget.} = return max(rect.y, rect.y + rect.height) # DOMRectList proc length(this: DOMRectList): int {.jsfget.} = this.list.len proc getter(ctx: JSContext; this: DOMRectList; atom: JSAtom): JSValue {.jsgetownprop.} = var u: uint32 return case ctx.fromIdx(atom, u) of fiIdx: if int64(u) < int64(this.list.len): ctx.toJS(this.list[int(u)]).uninitIfNull() else: JS_UNINITIALIZED of fiStr: JS_UNINITIALIZED of fiErr: JS_EXCEPTION # CSSStyleDeclaration # # To avoid having to invalidate the entire tree on pseudo-class changes, # each element holds a list of elements their CSS values depend on. # (This list may include the element itself.) In addition, elements # store each value valid for dependency d. These are then used for # checking the validity of StyledNodes. # # In other words - say we have to apply the author stylesheets of the # following document: # # <style> # div:hover { color: red; } # :not(input:checked) + p { display: none; } # </style> # <div>This div turns red on hover.</div> # <input type=checkbox> # <p>This paragraph is only shown when the checkbox above is checked. # # That produces the following dependency graph (simplified): # div -> div (hover) # p -> input (checked) # # Then, to check if a node has been invalidated, we just iterate over # all recorded dependencies of each StyledNode, and check if their # registered value of the pseudo-class still matches that of its # associated element. # # So in our example, for div we check if div's :hover pseudo-class has # changed, for p we check whether input's :checked pseudo-class has # changed. proc invalidate*(element: Element; dep: DependencyType) = if dep in element.selfDepends: element.invalidate() element.document.styleDependencies[dep].dependedBy.withValue(element, p): for it in p[]: it.invalidate() proc findAndDelete(map: var seq[Element]; element: Element) = map.del(map.find(element)) proc applyStyleDependencies*(element: Element; depends: DependencyInfo) = let document = element.document element.selfDepends = {} for t, map in document.styleDependencies.mpairs: map.dependsOn.withValue(element, p): for it in p[]: map.dependedBy.mgetOrPut(it, @[]).findAndDelete(element) map.dependsOn.del(element) for el in depends[t]: if el == element: element.selfDepends.incl(t) continue map.dependedBy.mgetOrPut(el, @[]).add(element) map.dependsOn.mgetOrPut(element, @[]).add(el) proc add*(depends: var DependencyInfo; element: Element; t: DependencyType) = depends[t].add(element) proc merge*(a: var DependencyInfo; b: DependencyInfo) = for t, it in b: for x in it: if x notin a[t]: a[t].add(x) proc newCSSStyleDeclaration(element: Element; value: string; computed = false; readonly = false): CSSStyleDeclaration = # Note: element may be nil return CSSStyleDeclaration( decls: value.parseDeclarations(), element: element, computed: computed, readonly: readonly ) proc cssText(this: CSSStyleDeclaration): string {.jsfget.} = if this.computed: return "" result = "" for it in this.decls: if result.len > 0: result &= ' ' result &= $it proc length(this: CSSStyleDeclaration): uint32 = return uint32(this.decls.len) proc item(ctx: JSContext; this: CSSStyleDeclaration; u: uint32): JSValue {.jsfunc.} = if u < this.length: return ctx.toJS(this.decls[int(u)].name) return ctx.toJS("") proc find(this: CSSStyleDeclaration; s: string): int = if s.startsWith("--"): let v = s.toOpenArray(2, s.high).toAtom() for i, decl in this.decls.mypairs: if decl.t == cdtVariable and decl.v == v: return i return -1 if p := anyPropertyType(s): for i, decl in this.decls.mypairs: if decl.t == cdtProperty and decl.p == p: return i return -1 proc getPropertyValue(this: CSSStyleDeclaration; s: string): string {.jsfunc.} = if (let i = this.find(s); i != -1): var s = "" for it in this.decls[i].value: s &= $it return move(s) return "" proc getter(ctx: JSContext; this: CSSStyleDeclaration; atom: JSAtom): JSValue {.jsgetownprop.} = var u: uint32 var s: string case ctx.fromIdx(atom, u, s) of fiIdx: if u < this.length: return ctx.toJS(this.decls[int(u)].name) return JS_UNINITIALIZED of fiStr: if s == "cssFloat": s = "float" if s.isSupportedProperty(): return ctx.toJS(this.getPropertyValue(s)) s = camelToKebabCase(s) if s.isSupportedProperty(): return ctx.toJS(this.getPropertyValue(s)) return JS_UNINITIALIZED of fiErr: return JS_EXCEPTION # Consumes toks. proc setValue(this: CSSStyleDeclaration; i: int; toks: var seq[CSSToken]): Opt[void] = if i notin 0 .. this.decls.high: return err() # dummyAttrs can be safely used because the result is discarded. case this.decls[i].t of cdtProperty: var ctx = initCSSParser(toks) var dummy: seq[CSSComputedEntry] = @[] ?ctx.parseComputedValues0(this.decls[i].p, dummyAttrs, dummy) of cdtNestedRule: return err() of cdtVariable: if parseDeclWithVar0(toks).len == 0: return err() this.decls[i].value = move(toks) return ok() proc removeProperty(ctx: JSContext; this: CSSStyleDeclaration; name: string): JSValue {.jsfunc.} = if this.readonly: return JS_ThrowDOMException(ctx, "NoModificationAllowedError", "cannot modify read-only declaration") let name = name.toLowerAscii() let value = this.getPropertyValue(name) #TODO shorthand let i = this.find(name) if i != -1: this.decls.delete(i) return ctx.toJS(value) proc checkReadOnly(ctx: JSContext; this: CSSStyleDeclaration): Opt[void] = if this.readonly: JS_ThrowDOMException(ctx, "NoModificationAllowedError", "cannot modify read-only declaration") return err() ok() proc setProperty(ctx: JSContext; this: CSSStyleDeclaration; name, value: string): JSValue {.jsfunc.} = if ctx.checkReadOnly(this).isErr: return JS_EXCEPTION let name = name.toLowerAscii() if not name.isSupportedProperty(): return JS_UNDEFINED if value == "": return ctx.removeProperty(this, name) var toks = parseComponentValues(value) if (let i = this.find(name); i != -1): if this.setValue(i, toks).isErr: # this does not throw. return JS_UNDEFINED else: let x = initCSSDeclaration(name) if x.isErr: return JS_UNDEFINED # ignore var decl = x.get case decl.t of cdtProperty: var ctx = initCSSParser(toks) var dummy = newSeq[CSSComputedEntry]() if ctx.parseComputedValues0(decl.p, dummyAttrs, dummy).isErr: return JS_UNDEFINED of cdtNestedRule: return JS_UNDEFINED of cdtVariable: if parseDeclWithVar0(toks).len == 0: return JS_UNDEFINED decl.value = move(toks) this.decls.add(move(decl)) this.element.attr(satStyle, this.cssText) return JS_UNDEFINED proc setter(ctx: JSContext; this: CSSStyleDeclaration; atom: JSAtom; value: string): JSValue {.jssetprop.} = if ctx.checkReadOnly(this).isErr: return JS_EXCEPTION var u: uint32 var name: string case ctx.fromIdx(atom, u, name) of fiIdx: var toks = parseComponentValues(value) if this.setValue(int(u), toks).isErr: this.element.attr(satStyle, this.cssText) return JS_UNDEFINED of fiStr: if name == "cssFloat": name = "float" name = camelToKebabCase(name) return ctx.setProperty(this, name, value) of fiErr: return JS_EXCEPTION proc style(element: Element): CSSStyleDeclaration {.jsfget.} = if element.cachedStyle == nil: element.cachedStyle = newCSSStyleDeclaration(element, "") return element.cachedStyle proc getComputedStyle*(element: Element; pseudo: PseudoElement): CSSValues = var computed = element.computed while computed != nil: if computed.pseudo == pseudo: return computed computed = computed.next nil # HTMLElement proc newHTMLElement*(document: Document; tagType: TagType): HTMLElement = let localName = tagType.toAtom() return HTMLElement(document.newElement(localName, Namespace.HTML, NO_PREFIX)) proc crossOrigin(element: HTMLElement): CORSAttribute = if not element.attrb(satCrossorigin): return caNoCors let s = element.attr(satCrossorigin) if s.equalsIgnoreCase("use-credentials"): return caUseCredentials caAnonymous proc referrerPolicy(element: HTMLElement): Opt[ReferrerPolicy] = parseEnumNoCase[ReferrerPolicy](element.attr(satReferrerpolicy)) # HTMLHyperlinkElementUtils (for <a> and <area>) proc reinitURL*(element: Element): Opt[URL] = if element.attrb(satHref): let url = element.document.parseURL(element.attr(satHref)) if url.isOk and url.get.schemeType != stBlob: return url return err() proc hyperlinkGet(ctx: JSContext; this: JSValueConst; magic: cint): JSValue {.cdecl.} = var element: Element ?ctx.fromJS(this, element) let sa = StaticAtom(magic) if url := element.reinitURL(): let href = ctx.toJS(url) if JS_IsException(href): return JS_EXCEPTION let res = JS_GetPropertyStr(ctx, href, cstring($sa)) JS_FreeValue(ctx, href) return res if sa == satProtocol: return ctx.toJS(":") return ctx.toJS("") proc hyperlinkSet(ctx: JSContext; this, val: JSValueConst; magic: cint): JSValue {.cdecl.} = var element: Element ?ctx.fromJS(this, element) let sa = StaticAtom(magic) if sa == satHref: var s: string if ctx.fromJS(val, s).isOk: element.attr(satHref, s) return JS_DupValue(ctx, val) return JS_EXCEPTION if url := element.reinitURL(): let href = ctx.toJS(url) let res = JS_SetPropertyStr(ctx, href, cstring($sa), JS_DupValue(ctx, val)) if res < 0: return JS_EXCEPTION var outs: string if ctx.fromJSFree(href, outs).isOk: element.attr(satHref, outs) return JS_DupValue(ctx, val) proc hyperlinkGetProp(ctx: JSContext; element: HTMLElement; a: JSAtom; desc: ptr JSPropertyDescriptor): JSValue = var s: string if ctx.fromJS(a, s).isOk: let sa = s.toStaticAtom() if sa in {satHref, satOrigin, satProtocol, satUsername, satPassword, satHost, satHostname, satPort, satPathname, satSearch, satHash}: if desc != nil: let u1 = JSCFunctionType(getter_magic: hyperlinkGet) let u2 = JSCFunctionType(setter_magic: hyperlinkSet) desc.getter = JS_NewCFunction2(ctx, u1.generic, cstring(s), 0, JS_CFUNC_getter_magic, cint(sa)) desc.setter = JS_NewCFunction2(ctx, u2.generic, cstring(s), 0, JS_CFUNC_setter_magic, cint(sa)) desc.value = JS_UNDEFINED desc.flags = JS_PROP_GETSET return JS_TRUE # dummy value return JS_UNINITIALIZED proc click(ctx: JSContext; element: HTMLElement) {.jsfunc.} = let event = newEvent(satClick.toAtom(), element, bubbles = true, cancelable = true) let canceled = ctx.dispatch(element, event) if not canceled: let window = ctx.getWindow() if window != nil: window.click(element) # <a> proc getter(ctx: JSContext; this: HTMLAnchorElement; a: JSAtom; desc: ptr JSPropertyDescriptor): JSValue {.jsgetownprop.} = return ctx.hyperlinkGetProp(this, a, desc) proc toString(anchor: HTMLAnchorElement): string {.jsfunc.} = if href := anchor.reinitURL(): return $href return "" proc setRelList(anchor: HTMLAnchorElement; s: string) {.jsfset: "relList".} = anchor.attr(satRel, s) # <area> proc getter(ctx: JSContext; this: HTMLAreaElement; a: JSAtom; desc: ptr JSPropertyDescriptor): JSValue {.jsgetownprop.} = return ctx.hyperlinkGetProp(this, a, desc) proc toString(area: HTMLAreaElement): string {.jsfunc.} = if href := area.reinitURL(): return $href return "" proc setRelList(area: HTMLAreaElement; s: string) {.jsfset: "relList".} = area.attr(satRel, s) # <base> proc href(base: HTMLBaseElement): string {.jsfget.} = #TODO with fallback base url if url := parseURL(base.attr(satHref)): return $url return "" # <button> proc jsForm(this: HTMLButtonElement): HTMLFormElement {.jsfget: "form".} = return this.form proc setType(this: HTMLButtonElement; s: string) {.jsfset: "type".} = this.attr(satType, s) # <canvas> proc getContext*(jctx: JSContext; this: HTMLCanvasElement; contextId: string; options: JSValueConst = JS_UNDEFINED): CanvasRenderingContext2D {.jsfunc.} = if contextId == "2d": if this.ctx2d == nil: let window = jctx.getWindow() let loader = window.loader let ctx2d = create2DContext(loader, this, this.bitmap, options) if ctx2d == nil: return nil this.ctx2d = ctx2d window.pendingCanvasCtls.add(ctx2d) return this.ctx2d return nil type ToBlobEnv = ref object of BlobOpaque ctx: JSContext callback: JSValue isPNG: bool this: HTMLCanvasElement url: URL proc onFinishToBlob(response: Response; success: bool) = let env = ToBlobEnv(response.opaque) let ctx = env.ctx let callback = env.callback let this = env.this let blob = response.onFinishBlob(success) if blob == nil: JS_FreeValue(ctx, callback) JS_FreeContext(ctx) return let jsBlob = ctx.toJS(blob) if JS_IsException(jsBlob): JS_FreeValue(ctx, callback) JS_FreeContext(ctx) return let window = this.document.window let res = ctx.callSinkFree(callback, JS_UNDEFINED, jsBlob) if JS_IsException(res): window.console.error("Exception in canvas toBlob:", ctx.getExceptionMsg()) else: JS_FreeValue(ctx, res) JS_FreeContext(ctx) proc toBlob1(opaque: RootRef; response: Response) = let env = ToBlobEnv(opaque) let ctx = env.ctx let callback = env.callback let this = env.this if response == nil: if not env.isPNG: # redo as PNG. # Note: this sounds dumb, and is dumb, but also standard mandated so # whatever. ctx.toBlob(this, callback, "image/png") # PNG doesn't understand quality else: # the png encoder doesn't work... let window = this.document.window window.console.error("missing/broken PNG encoder") JS_FreeValue(ctx, callback) JS_FreeContext(ctx) else: response.onFinish = onFinishToBlob let window = env.ctx.getGlobal() window.loader.blob(response, env) proc toBlob0(opaque: RootRef; response: Response) = let env = ToBlobEnv(opaque) let ctx = env.ctx if response == nil: JS_FreeValue(ctx, env.callback) JS_FreeContext(ctx) return let this = env.this let headers = newHeaders(hgRequest, { "Cha-Image-Dimensions": $this.bitmap.width & 'x' & $this.bitmap.height }) let request = newRequest( env.url, httpMethod = hmPost, headers = headers, body = RequestBody(t: rbtOutput, outputId: response.outputId) ) let window = this.document.window window.corsFetch(request, toBlob1, env) window.loader.close(response) # Note: the standard says quality should be converted in a strange way for # backwards compat, but I don't care. proc toBlob(ctx: JSContext; this: HTMLCanvasElement; callback: JSValueConst; contentType = "image/png"; quality = none(float64)) {.jsfunc.} = let contentType = contentType.toLowerAscii() if not contentType.startsWith("image/") or this.bitmap.cacheId == 0: return let url = parseURL0("img-codec+" & contentType.after('/') & ":encode") if url == nil: return let headers = newHeaders(hgRequest, { "Cha-Image-Dimensions": $this.bitmap.width & 'x' & $this.bitmap.height }) if (var quality = quality.get(-1); 0 <= quality and quality <= 1): quality *= 99 quality += 1 headers.add("Cha-Image-Quality", dtoa(quality)) # callback will go out of scope when we return, so capture a new reference. let callback = JS_DupValue(ctx, callback) let request = newRequest( "img-codec+x-cha-canvas:decode", httpMethod = hmPost, body = RequestBody(t: rbtCache, cacheId: this.bitmap.cacheId) ) let env = ToBlobEnv( ctx: JS_DupContext(ctx), callback: JS_DupValue(ctx, callback), isPNG: contentType == "image/png", this: this, url: url ) let window = this.document.window window.corsFetch(request, toBlob0, env) # <form> proc canSubmitImplicitly*(form: HTMLFormElement): bool = const BlocksImplicitSubmission = { itText, itSearch, itURL, itTel, itEmail, itPassword, itDate, itMonth, itWeek, itTime, itDatetimeLocal, itNumber } var found = false for control in form.controls: if control of HTMLInputElement: let input = HTMLInputElement(control) if input.inputType in BlocksImplicitSubmission: if found: return false found = true elif control.isSubmitButton(): return false return true proc setRelList(form: HTMLFormElement; s: string) {.jsfset: "relList".} = form.attr(satRel, s) proc elements(ctx: JSContext; form: HTMLFormElement): Opt[HTMLFormControlsCollection] {.jsfget.} = if form.cachedElements == nil: form.cachedElements = ?newCollection[HTMLFormControlsCollection]( ctx, root = form.rootNode, match = proc(ctx: JSContext; this: Collection; node: Node): Opt[bool] = if node of FormAssociatedElement: let element = FormAssociatedElement(node) if element.tagType in ListedElements: let this = HTMLFormControlsCollection(this) return ok(element.form == this.form) return ok(false), islive = true, childonly = false ) form.cachedElements.form = form ok(form.cachedElements) proc getter(ctx: JSContext; this: HTMLFormElement; atom: JSAtom): JSValue {.jsgetownprop.} = let elements0 = ctx.elements(this) if elements0.isErr: return JS_EXCEPTION return ctx.getter(elements0.get, atom) proc length(ctx: JSContext; this: HTMLFormElement): Opt[uint32] {.jsfget.} = let elements0 = ctx.elements(this) if elements0.isErr: return err() return ctx.getLength(elements0.get) proc reset*(form: HTMLFormElement) = for control in form.controls: control.resetElement() control.invalidate() # FormAssociatedElement proc setForm*(element: FormAssociatedElement; form: HTMLFormElement) = element.form = form form.controls.add(element) form.document.invalidateCollections() proc resetFormOwner(element: FormAssociatedElement) = element.parserInserted = false if element.form != nil: if element.tagType notin ListedElements: return let lastForm = element.findAncestor(TAG_FORM) if not element.attrb(satForm) and lastForm == element.form: return element.form = nil if element.tagType in ListedElements and element.isConnected: let form = element.document.getElementById(element.attr(satForm)) if form of HTMLFormElement: element.setForm(HTMLFormElement(form)) if element.form == nil: for ancestor in element.ancestors: if ancestor of HTMLFormElement: element.setForm(HTMLFormElement(ancestor)) # <img> proc newImage(ctx: JSContext; _: JSValueConst; argc: cint; argv: JSValueConstArray): JSValue {.cdecl.} = let document = ctx.getDocument() let this = document.newHTMLElement(TAG_IMG) if not JS_IsUndefined(argv[0]): var x: uint32 ?ctx.fromJS(argv[0], x) this.attrul(satWidth, x) if not JS_IsUndefined(argv[1]): var x: uint32 ?ctx.fromJS(argv[1], x) this.attrul(satHeight, x) ctx.toJS(this) proc getImageRect(this: HTMLImageElement): tuple[w, h: float64] = let window = this.document.window if window != nil and window.settings.scripting == smApp: window.ensureLayout(this) let objs = getClientRectsImpl(this, firstOnly = true, blockOnly = false) if objs.len > 0: return (objs[0].width, objs[0].height) let bitmap = this.bitmap if bitmap == nil: return (0, 0) let width = float64(this.attrul(satWidth).get(uint32(bitmap.width))) let height = float64(this.attrul(satHeight).get(uint32(bitmap.height))) return (width, height) proc width(this: HTMLImageElement): uint32 {.jsfget.} = return uint32(this.getImageRect().w) proc setWidth(this: HTMLImageElement; u: uint32) {.jsfset: "width".} = this.attrul(satWidth, u) proc height(this: HTMLImageElement): uint32 {.jsfget.} = return uint32(this.getImageRect().h) proc setHeight(this: HTMLImageElement; u: uint32) {.jsfset: "height".} = this.attrul(satHeight, u) # <input> proc jsForm(this: HTMLInputElement): HTMLFormElement {.jsfget: "form".} = return this.form proc value*(this: HTMLInputElement): lent string {.jsfget.} = if this.internalValue == nil: this.internalValue = newRefString("") return this.internalValue.s proc setValue*(this: HTMLInputElement; value: sink string) {.jsfset: "value".} = this.internalValue = newRefString(value) this.invalidate() proc setType(this: HTMLInputElement; s: string) {.jsfset: "type".} = this.attr(satType, s) proc checked*(input: HTMLInputElement): bool {.inline.} = return input.internalChecked proc setChecked*(input: HTMLInputElement; b: bool) {.jsfset: "checked".} = # Note: input elements are implemented as a replaced text, so we must # fully invalidate them on checked change. if input.inputType == itRadio: for radio in input.radiogroup: radio.invalidate(dtChecked) radio.invalidate() radio.internalChecked = false input.invalidate(dtChecked) input.invalidate() input.internalChecked = b proc inputString*(input: HTMLInputElement): RefString = case input.inputType of itCheckbox, itRadio: if input.checked: return newRefString("*") return newRefString(" ") of itPassword: return newRefString('*'.repeat(input.value.pointLen)) of itReset: if input.attrb(satValue): return input.internalValue return newRefString("RESET") of itSubmit, itButton: if input.attrb(satValue): return input.internalValue return newRefString("SUBMIT") of itFile: #TODO multiple files? let s = if input.files.len > 0: input.files[0].name else: "" return newRefString(s) else: return input.internalValue proc select(ctx: JSContext; input: HTMLInputElement) {.jsfunc.} = ctx.focus(input) # <label> proc control*(label: HTMLLabelElement): FormAssociatedElement {.jsfget.} = let f = label.attr(satFor) if f != "": let elem = label.document.getElementById(f) #TODO the supported check shouldn't be needed, just labelable if elem of FormAssociatedElement and elem.tagType in LabelableElements: return FormAssociatedElement(elem) return nil for elem in label.elementDescendants(LabelableElements): if elem of FormAssociatedElement: #TODO remove this return FormAssociatedElement(elem) return nil return nil proc form(label: HTMLLabelElement): HTMLFormElement {.jsfget.} = let control = label.control if control != nil: return control.form return nil # SheetElement proc findPrevSheet(this: SheetElement): CSSStylesheet = var node = this.previousDescendant() while node != nil: if node of SheetElement: let element = SheetElement(node) if element.sheetTail != nil: return element.sheetTail node = node.previousDescendant() nil proc findNextSheet(this: SheetElement): CSSStylesheet = var node = Node(this).nextDescendant(nil) while node != nil: if node of SheetElement: let element = SheetElement(node) if element.sheetHead != nil: return element.sheetHead node = node.nextDescendant(nil) nil proc isDisabled(this: SheetElement): bool = this of HTMLLinkElement and HTMLLinkElement(this).isDisabled() proc insertSheet(this: SheetElement) = if this.sheetHead != nil: let document = this.document let prev = this.findPrevSheet() let next = this.findNextSheet() if prev != nil: prev.next = this.sheetHead else: document.authorSheetsHead = this.sheetHead this.sheetTail.next = next if document.ruleMap != nil and not this.isDisabled(): if next == nil: for sheet in this.sheets: document.ruleMap.add(sheet) else: document.ruleMap = nil let html = document.documentElement if html != nil: html.invalidate() proc removeSheet(this: SheetElement) = if this.sheetHead != nil: let document = this.document let next = this.sheetTail.next let prev = this.findPrevSheet() if prev == nil: document.authorSheetsHead = next else: prev.next = next if not this.isDisabled(): document.ruleMap = nil this.sheetTail.next = nil let html = document.documentElement if html != nil: html.invalidate() proc updateSheet(this: SheetElement; head, tail: CSSStylesheet) = this.removeSheet() this.sheetHead = head this.sheetTail = tail if this.isConnected(): this.insertSheet() # <link> proc isDisabled(link: HTMLLinkElement): bool = let title = link.attr(satTitle) if title == "": return link.relList.containsIgnoreCase(satAlternate) or not link.enabled.get(true) if link.enabled.isSome: return not link.enabled.get return link.document.sheetTitle != title proc setRelList(link: HTMLLinkElement; s: string) {.jsfset: "relList".} = link.attr(satRel, s) # <option> proc newOption(ctx: JSContext; _: JSValueConst; argc: cint; argv: JSValueConstArray): JSValue {.cdecl.} = let document = ctx.getDocument() let this = HTMLOptionElement(document.newHTMLElement(TAG_OPTION)) if not JS_IsUndefined(argv[0]): var text: string ?ctx.fromJS(argv[0], text) if text != "": this.insert(document.newText(text), nil) if not JS_IsUndefined(argv[1]): var value: string ?ctx.fromJS(argv[1], value) this.attr(satValue, value) var defaultSelected: bool ?ctx.fromJS(argv[2], defaultSelected) if defaultSelected: this.attr(satSelected, "") ?ctx.fromJS(argv[3], this.selected) ctx.toJS(this) proc text(option: HTMLOptionElement): string {.jsfget.} = var s = "" for child in option.descendants: let parent = child.parentElement if child of Text and (parent.tagTypeNoNS != TAG_SCRIPT or parent.namespaceURI notin [satNamespaceHTML, satNamespaceSVG]): s &= Text(child).data.s return s.stripAndCollapse() proc value*(option: HTMLOptionElement): string {.jsfget.} = if option.attrb(satValue): return option.attr(satValue) return option.text proc setValue(option: HTMLOptionElement; s: string) {.jsfset: "value".} = option.attr(satValue, s) proc select*(option: HTMLOptionElement): HTMLSelectElement = for anc in option.ancestors: if anc of HTMLSelectElement: return HTMLSelectElement(anc) return nil proc setSelected*(option: HTMLOptionElement; selected: bool) {.jsfset: "selected".} = option.invalidate(dtChecked) option.selected = selected let select = option.select if select != nil and not select.attrb(satMultiple): var firstOption: HTMLOptionElement = nil var prevSelected: HTMLOptionElement = nil for option in select.options: if firstOption == nil: firstOption = option if option.selected: if prevSelected != nil: prevSelected.selected = false prevSelected.invalidate(dtChecked) prevSelected = option if select.attrul(satSize).get(1) == 1 and prevSelected == nil and firstOption != nil: firstOption.selected = true firstOption.invalidate(dtChecked) # <progress> proc position(this: HTMLProgressElement): float64 {.jsfget.} = return this.getProgressPosition() # <select> proc displaySize(select: HTMLSelectElement): uint32 = return select.attrul(satSize).get(1) proc setSelectedness(select: HTMLSelectElement) = var firstOption: HTMLOptionElement = nil var prevSelected: HTMLOptionElement = nil if not select.attrb(satMultiple): let displaySize = select.displaySize for option in select.options: if firstOption == nil: firstOption = option if option.selected: if prevSelected != nil: prevSelected.selected = false prevSelected.invalidate(dtChecked) prevSelected = option if select.displaySize == 1 and prevSelected == nil and firstOption != nil: firstOption.selected = true proc jsForm(this: HTMLSelectElement): HTMLFormElement {.jsfget: "form".} = return this.form proc jsType(this: HTMLSelectElement): string {.jsfget: "type".} = if this.attrb(satMultiple): return "select-multiple" return "select-one" proc names(ctx: JSContext; this: HTMLOptionsCollection): JSPropertyEnumList {.jspropnames.} = return ctx.names(HTMLCollection(this)) proc getter(ctx: JSContext; this: HTMLOptionsCollection; atom: JSAtom): JSValue {.jsgetownprop.} = return ctx.getter(HTMLCollection(this), atom) proc add(ctx: JSContext; this: HTMLOptionsCollection; element: Element; before: JSValueConst = JS_NULL): JSValue {.jsfunc.} = if not (element of HTMLOptionElement or element of HTMLOptGroupElement): return JS_ThrowTypeError(ctx, "Expected option or optgroup element") var beforeEl: HTMLElement = nil var beforeIdx = -1 if not JS_IsNull(before) and ctx.fromJS(before, beforeEl).isErr and ctx.fromJS(before, beforeIdx).isErr: return JS_EXCEPTION for it in this.root.ancestors: if element == it: return ctx.insertThrow("can't add ancestor of select") if beforeEl != nil and this.root notin beforeEl: return ctx.insertThrow(nil) if element != beforeEl: if beforeEl == nil: let it = ctx.item(this, uint32(beforeIdx)) if it.isErr: return JS_EXCEPTION if it.get of HTMLElement: beforeEl = HTMLElement(it.get) let parent = if beforeEl != nil: beforeEl.parentNode else: this.root return ctx.insertBeforeUndefined(parent, element, option(Node(beforeEl))) return JS_UNDEFINED proc remove(ctx: JSContext; this: HTMLOptionsCollection; i: int32): Opt[void] {. jsfunc.} = let element = ?ctx.item(this, uint32(i)) if element != nil: element.remove() ok() proc length(ctx: JSContext; this: HTMLOptionsCollection): Opt[uint32] {. jsfget.} = return ctx.getLength(this) proc setLength(ctx: JSContext; this: HTMLOptionsCollection; n: uint32): Opt[void] {.jsfset: "length".} = let len = ?ctx.getLength(this) if n > len: if n <= 100_000: # LOL let parent = this.root let document = parent.document for i in 0 ..< n - len: parent.append(document.newHTMLElement(TAG_OPTION)) else: for i in 0 ..< len - n: let it = ?ctx.item(this, uint32(i)) it.remove() ok() proc options(ctx: JSContext; this: HTMLSelectElement): Opt[HTMLOptionsCollection] {.jsfget.} = if this.cachedOptions == nil: this.cachedOptions = ?newCollection[HTMLOptionsCollection]( ctx, root = this, match = proc(ctx: JSContext; this: Collection; node: Node): Opt[bool] = ok(node.isOptionOf(this.root)), islive = true, childonly = false ) ok(this.cachedOptions) proc setter(ctx: JSContext; this: HTMLOptionsCollection; atom: JSAtom; value: Option[HTMLOptionElement]): JSValue {.jssetprop.} = var u: uint32 case ctx.fromIdx(atom, u) of fiIdx: discard of fiStr: return JS_UNINITIALIZED of fiErr: return JS_EXCEPTION let element0 = ctx.item(this, u) if element0.isErr: return JS_EXCEPTION let element = element0.get if value.isNone: if element != nil: element.remove() return JS_UNDEFINED let value = value.get let parent = this.root if element != nil: return ctx.replaceChild(parent, element, value) let len0 = ctx.getLength(this) if len0.isErr: return JS_EXCEPTION let document = parent.document for i in len0.get ..< u: let res = parent.insertBefore(document.newHTMLElement(TAG_OPTION), nil) if res.isErr: return ctx.insertThrow(res.error) return ctx.insertBeforeUndefined(parent, value, none(Node)) proc length(ctx: JSContext; this: HTMLSelectElement): Opt[uint32] {.jsfget.} = let options = ?ctx.options(this) ctx.getLength(options) proc setLength(ctx: JSContext; this: HTMLSelectElement; n: uint32): Opt[void] {. jsfset: "length".} = let options = ?ctx.options(this) ctx.setLength(options, n) proc getter(ctx: JSContext; this: HTMLSelectElement; u: JSAtom): JSValue {.jsgetownprop.} = let options = ctx.options(this) if options.isErr: return JS_EXCEPTION return ctx.getter(options.get, u) proc item(ctx: JSContext; this: HTMLSelectElement; u: uint32): Opt[Element] {.jsfunc.} = let options = ?ctx.options(this) ctx.item(options, u) proc namedItem(ctx: JSContext; this: HTMLSelectElement; atom: CAtom): Opt[Element] {.jsfunc.} = let options = ?ctx.options(this) ctx.namedItem(options, atom) proc selectedOptions(ctx: JSContext; this: HTMLSelectElement): JSValue {.jsfget.} = return ctx.getWeakCollection(this, wwmSelectedOptions) proc selectedIndex*(this: HTMLSelectElement): int {.jsfget.} = var i = 0 for it in this.options: if it.selected: return i inc i return -1 proc selectedIndex(this: HTMLOptionsCollection): int {.jsfget.} = return HTMLSelectElement(this.root).selectedIndex proc setSelectedIndex*(this: HTMLSelectElement; n: int) {.jsfset: "selectedIndex".} = var i = 0 for it in this.options: if i == n: it.selected = true it.dirty = true else: it.selected = false it.invalidate(dtChecked) inc i this.document.invalidateCollections() proc value(this: HTMLSelectElement): string {.jsfget.} = for it in this.options: if it.selected: return it.value return "" proc setValue(this: HTMLSelectElement; value: string) {.jsfset: "value".} = var found = false for it in this.options: if not found and it.value == value: found = true it.selected = true it.dirty = true else: it.selected = false it.invalidate(dtChecked) this.document.invalidateCollections() proc showPicker(ctx: JSContext; this: HTMLSelectElement): JSValue {.jsfunc.} = # Per spec, we should do something if it's being rendered and on # transient user activation. # If this is ever implemented, then the "is rendered" check must # be app mode only. return JS_ThrowDOMException(ctx, "NotAllowedError", "not allowed") proc add(ctx: JSContext; this: HTMLSelectElement; element: Element; before: JSValueConst = JS_NULL): JSValue {.jsfunc.} = let options = ctx.options(this) if options.isErr: return JS_EXCEPTION return ctx.add(options.get, element, before) proc remove(ctx: JSContext; this: HTMLSelectElement; idx: varargs[JSValueConst]): Opt[void] {.jsfunc.} = if idx.len > 0: var i: int32 ?ctx.fromJS(idx[0], i) let options = ?ctx.options(this) ?ctx.remove(options, i) else: this.remove() ok() # <style> proc updateSheetFinish(window: Window; this: SheetElement; res: LoadSheetResult; env: ParseSheetEnv; i: int) = this.updateSheet(res.head, res.tail) if this.isConnected(): let title = this.attr(satTitle) let document = this.document for sheet in this.sheets: sheet.disabled = title != "" and title != document.sheetTitle proc updateSheet*(this: HTMLStyleElement) = let document = this.document let window = document.window if window != nil: window.parseStylesheet(this, this.textContent, document.baseURL, DefaultCharset, CAtomNull, updateSheetFinish, nil, 0) # <script> proc finalize(element: HTMLScriptElement) {.jsfin.} = if element.scriptResult != nil and element.scriptResult.t == srtScript: let script = element.scriptResult.script if script.rt != nil and not JS_IsUninitialized(script.record): script.free() proc mark(rt: JSRuntime; element: HTMLScriptElement; markFunc: JS_MarkFunc) {.jsmark.} = if element.scriptResult != nil and element.scriptResult.t == srtScript: let script = element.scriptResult.script if script.rt != nil and not JS_IsUninitialized(script.record): JS_MarkValue(rt, script.record, markFunc) proc markAsReady(element: HTMLScriptElement; res: ScriptResult) = element.scriptResult = res if element.onReady != nil: element.onReady(element) element.onReady = nil element.delayingTheLoadEvent = false proc scriptOnReadyRunInParser(element: HTMLScriptElement) = element.readyForParserExec = true proc scriptOnReadyNoParser(element: HTMLScriptElement) = let prepdoc = element.preparationTimeDocument if prepdoc.scriptsToExecInOrder == element: while prepdoc.scriptsToExecInOrder != nil: let script = prepdoc.scriptsToExecInOrder if script.scriptResult == nil: break script.execute() let next = prepdoc.scriptsToExecInOrder.next prepdoc.scriptsToExecInOrder = next if next == nil: prepdoc.scriptsToExecInOrderTail = nil proc scriptOnReadyAsync(element: HTMLScriptElement) = let prepdoc = element.preparationTimeDocument element.execute() var it = prepdoc.scriptsToExecSoon if it == element: prepdoc.scriptsToExecSoon = element.next else: while it != nil: if it.next == element: it.next = element.next break it = it.next proc fetchClassicScript(element: HTMLScriptElement; url: URL; cors: CORSAttribute; onComplete: OnCompleteProc): Response = if not element.scriptingEnabled: element.markAsReady(ScriptResult(t: srtNull)) return nil let window = element.document.window let request = createPotentialCORSRequest(url, rdScript, cors) request.client = window.settings return window.loader.doRequest(request) #TODO settings object proc fetchExternalModuleGraph(element: HTMLScriptElement; url: URL; options: ScriptOptions; onComplete: OnCompleteProc) = let window = element.document.window if not element.scriptingEnabled: element.onComplete(ScriptResult(t: srtNull)) return window.importMapsAllowed = false element.fetchSingleModule( url, rdScript, options, parseURL0("about:client"), isTopLevel = true, onComplete = proc(element: HTMLScriptElement; res: ScriptResult) = if res.t == srtNull: element.onComplete(res) else: element.fetchDescendantsAndLink(res.script, rdScript, onComplete) ) proc fetchInlineModuleGraph(element: HTMLScriptElement; sourceText: string; url: URL; options: ScriptOptions; onComplete: OnCompleteProc) = let window = element.document.window let ctx = window.jsctx let res = ctx.newJSModuleScript(sourceText, url, options) if JS_IsException(res.script.record): window.logException(res.script.baseURL) element.onComplete(ScriptResult(t: srtNull)) else: element.fetchDescendantsAndLink(res.script, rdScript, onComplete) proc fetchDescendantsAndLink(element: HTMLScriptElement; script: Script; destination: RequestDestination; onComplete: OnCompleteProc) = let window = element.document.window let ctx = window.jsctx let record = script.record if JS_ResolveModule(ctx, record) < 0: window.logException(script.baseURL) script.free() return ctx.setImportMeta(record, true) script.record = JS_UNINITIALIZED script.rt = nil let res = JS_EvalFunction(ctx, record) # consumes record if JS_IsException(res): window.logException(script.baseURL) JS_FreeValue(ctx, res) type FetchModuleEnv = ref object of BlobOpaque window: Window element: HTMLScriptElement settings: EnvironmentSettings url: URL moduleType: ModuleType referrerPolicy: Opt[ReferrerPolicy] onComplete: OnCompleteProc options: ScriptOptions proc onFinishFetchModule(response: Response; success: bool) = let env = FetchModuleEnv(response.opaque) let url = env.url let window = env.window let settings = env.settings let element = env.element let moduleType = env.moduleType let onComplete = env.onComplete let contentType = env.contentType let ctx = window.jsctx let blob = response.onFinishBlob(success) if blob == nil: let res = ScriptResult(t: srtNull) settings.moduleMap.put(url, moduleType, res) element.onComplete(res) return if contentType.isJavaScriptType(): let source = blob.toOpenArray().toValidUTF8() let res = ctx.newJSModuleScript(source, url, env.options) #TODO can't we just return null from newJSModuleScript? if JS_IsException(res.script.record): window.logException(res.script.baseURL) element.onComplete(ScriptResult(t: srtNull)) else: if env.referrerPolicy.isOk: res.script.options.referrerPolicy = env.referrerPolicy # set & onComplete both take ownership settings.moduleMap.put(url, moduleType, res.clone()) element.onComplete(res) else: #TODO non-JS modules discard proc fetchSingleModuleResponse(opaque: RootRef; response: Response) = let env = FetchModuleEnv(opaque) let settings = env.settings let url = env.url let moduleType = env.moduleType let element = env.element let onComplete = env.onComplete let window = env.window if response == nil: let res = ScriptResult(t: srtNull) settings.moduleMap.put(url, moduleType, res) element.onComplete(res) return env.referrerPolicy = response.getReferrerPolicy() response.onFinish = onFinishFetchModule window.loader.blob(response, env) #TODO settings object proc fetchSingleModule(element: HTMLScriptElement; url: URL; destination: RequestDestination; options: ScriptOptions; referrer: URL; isTopLevel: bool; onComplete: OnCompleteProc) = let moduleType = mtJavascript #TODO moduleRequest let window = element.document.window let settings = window.settings let res = settings.moduleMap.get(url, moduleType) if res != nil: if res.t == srtFetching: #TODO await value assert false element.onComplete(res) return let destination = moduleType.moduleTypeToRequestDest(destination) let mode = if destination in {rdWorker, rdSharedworker, rdServiceworker}: rmSameOrigin else: rmCors #TODO client #TODO initiator type let request = newRequest( url, referrer = referrer, destination = destination, mode = mode ) #TODO set up module script request #TODO performFetch let opaque = FetchModuleEnv( window: window, element: element, url: url, settings: settings, moduleType: moduleType, onComplete: onComplete, options: options, ) window.fetch(request, fetchSingleModuleResponse, opaque) proc execute*(element: HTMLScriptElement) = let document = element.document let window = document.window if document != element.preparationTimeDocument or window == nil: return let i = document.renderBlockingElements.find(element) if i != -1: document.renderBlockingElements.delete(i) #TODO this should work eventually (when module & importmap are implemented) #assert element.scriptResult != nil if element.scriptResult == nil: return if element.scriptResult.t == srtNull: window.fireEvent(satError, element, bubbles = false, cancelable = false, trusted = true) return let needsInc = element.external or element.ctype == stModule if needsInc: inc document.ignoreDestructiveWrites case element.ctype of stClassic: let oldCurrentScript = document.currentScript document.currentScript = if not (element.rootNode of ShadowRoot): element else: nil if window.jsctx != nil: let script = element.scriptResult.script let ctx = window.jsctx if JS_IsException(script.record): window.logException(script.baseURL) else: let record = script.record script.record = JS_UNINITIALIZED script.rt = nil let ret = JS_EvalFunction(ctx, record) # consumes record if JS_IsException(ret): window.logException(script.baseURL) JS_FreeValue(ctx, ret) document.currentScript = oldCurrentScript else: discard #TODO if needsInc: dec document.ignoreDestructiveWrites if element.external: window.fireEvent(satLoad, element, bubbles = false, cancelable = false, trusted = true) # https://html.spec.whatwg.org/multipage/scripting.html#prepare-the-script-element proc prepare*(element: HTMLScriptElement) = if element.alreadyStarted: return let parserDocument = element.parserDocument element.parserDocument = nil if parserDocument != nil and not element.attrb(satAsync): element.forceAsync = true let window = element.document.window let sourceText = element.childTextContent if not element.attrb(satSrc) and sourceText == "" or not element.isConnected or window == nil: return let t = element.attr(satType) let typeString = if t != "": t.strip(chars = AsciiWhitespace) elif (let l = element.attr(satLanguage); l != ""): "text/" & l else: "text/javascript" if typeString.isJavaScriptType(): element.ctype = stClassic elif typeString.equalsIgnoreCase("module"): element.ctype = stModule elif typeString.equalsIgnoreCase("importmap"): element.ctype = stImportMap else: return if parserDocument != nil: element.parserDocument = parserDocument element.forceAsync = false element.alreadyStarted = true element.preparationTimeDocument = element.document if parserDocument != nil and parserDocument != element.document or not element.scriptingEnabled or element.attrb(satNomodule) and element.ctype == stClassic: return #TODO content security policy if element.ctype == stClassic and element.attrb(satEvent) and element.attrb(satFor): let f = element.attr(satFor).strip(chars = AsciiWhitespace) let event = element.attr(satEvent).strip(chars = AsciiWhitespace) if not f.equalsIgnoreCase("window") or not event.equalsIgnoreCase("onload") and not event.equalsIgnoreCase("onload()"): return let encoding = element.getCharset() let classicCORS = element.crossOrigin let parserMetadata = if element.parserDocument != nil: pmParserInserted else: pmNotParserInserted var options = ScriptOptions( nonce: element.internalNonce, integrity: element.attr(satIntegrity), parserMetadata: parserMetadata, referrerPolicy: element.referrerPolicy ) #TODO settings object var response: Response = nil if element.attrb(satSrc): let src = element.attr(satSrc) let url = element.document.parseURL0(src) element.external = src != "" and element.ctype != stImportMap if element.ctype == stImportMap or url == nil: window.fireEvent(satError, element, bubbles = false, cancelable = false, trusted = true) return if element.renderBlocking: element.blockRendering() element.delayingTheLoadEvent = true if element in element.document.renderBlockingElements: options.renderBlocking = true if element.ctype == stClassic: response = element.fetchClassicScript(url, classicCORS, markAsReady) else: # stModule element.fetchExternalModuleGraph(url, options, markAsReady) else: let baseURL = element.document.baseURL case element.ctype of stClassic: let ctx = element.document.window.jsctx let script = ctx.newClassicScript(sourceText, baseURL, options) element.markAsReady(script) of stModule: element.delayingTheLoadEvent = true if element.renderBlocking: element.blockRendering() options.renderBlocking = true element.fetchInlineModuleGraph(sourceText, baseURL, options, markAsReady) of stImportMap: #TODO element.markAsReady(ScriptResult(t: srtNull)) if element.ctype == stClassic and element.attrb(satSrc) or element.ctype == stModule: let prepdoc = element.preparationTimeDocument if element.attrb(satAsync) or element.forceAsync: element.next = prepdoc.scriptsToExecSoon prepdoc.scriptsToExecSoon = element element.onReady = scriptOnReadyAsync elif element.parserDocument == nil: let tail = prepdoc.scriptsToExecInOrderTail if tail != nil: tail.next = element else: prepdoc.scriptsToExecInOrder = element prepdoc.scriptsToExecInOrderTail = element element.onReady = scriptOnReadyNoParser elif element.ctype == stModule or element.attrb(satDefer): let tail = element.parserDocument.scriptsToExecOnLoadTail if tail != nil: tail.next = element else: element.parserDocument.scriptsToExecOnLoad = element element.parserDocument.scriptsToExecOnLoadTail = element element.onReady = scriptOnReadyRunInParser else: element.parserDocument.parserBlockingScript = element element.blockRendering() element.onReady = scriptOnReadyRunInParser if response != nil: if response.stream == nil: element.markAsReady(ScriptResult(t: srtNull)) else: window.loader.resume(response) let source = response.stream.readAll().decodeAll(encoding) response.stream.sclose() let script = window.jsctx.newClassicScript(source, response.url, options, false) element.markAsReady(script) else: #TODO if stClassic, parserDocument != nil, parserDocument has a style sheet # that is blocking scripts, either the parser is an XML parser or a HTML # parser with a script level <= 1 element.execute() # <table> proc caption(this: HTMLTableElement): Element {.jsfget.} = return this.findFirstChildOf(TAG_CAPTION) proc setCaption(ctx: JSContext; this: HTMLTableElement; caption: HTMLTableCaptionElement): JSValue {.jsfset: "caption".} = let old = this.caption if old != nil: old.remove() return ctx.insertBeforeUndefined(this, caption, option(this.firstChild)) proc tHead(this: HTMLTableElement): Element {.jsfget.} = return this.findFirstChildOf(TAG_THEAD) proc tFoot(this: HTMLTableElement): Element {.jsfget.} = return this.findFirstChildOf(TAG_TFOOT) proc setTSectImpl(ctx: JSContext; this: HTMLTableElement; sect: HTMLTableSectionElement; tagType: TagType): JSValue = if sect != nil and sect.tagType != tagType: return ctx.insertThrow("wrong element type") let old = this.findFirstChildOf(tagType) if old != nil: old.remove() return ctx.insertBeforeUndefined(this, sect, option(this.firstChild)) proc setTHead(ctx: JSContext; this: HTMLTableElement; tHead: HTMLTableSectionElement): JSValue {.jsfset: "tHead".} = return ctx.setTSectImpl(this, tHead, TAG_THEAD) proc setTFoot(ctx: JSContext; this: HTMLTableElement; tFoot: HTMLTableSectionElement): JSValue {.jsfset: "tFoot".} = return ctx.setTSectImpl(this, tFoot, TAG_TFOOT) proc tBodies(ctx: JSContext; this: HTMLTableElement): JSValue {.jsfget.} = return ctx.getWeakCollection(this, wwmTBodies) proc rows(ctx: JSContext; this: HTMLTableElement): Opt[HTMLCollection] {.jsfget.} = if this.cachedRows == nil: this.cachedRows = ?newHTMLCollection( ctx, this, match = proc(ctx: JSContext; this: Collection; node: Node): Opt[bool] = if Node(node.parentNode) == this.root or Node(node.parentNode.parentNode) == this.root: return ctx.isRow(this, node) ok(false), islive = true, childonly = false ) ok(this.cachedRows) proc create(this: HTMLTableElement; tagType: TagType; before: Node): Element = var element = this.findFirstChildOf(tagType) if element == nil: element = this.document.newHTMLElement(tagType) this.insert(element, before) return element proc delete(this: HTMLTableElement; tagType: TagType) = let element = this.findFirstChildOf(tagType) if element != nil: element.remove() proc createCaption(this: HTMLTableElement): Element {.jsfunc.} = return this.create(TAG_CAPTION, this.firstChild) proc createTHead(this: HTMLTableElement): Element {.jsfunc.} = let before = this.findFirstChildNotOf({TAG_CAPTION, TAG_COLGROUP}) return this.create(TAG_THEAD, before) proc createTBody(this: HTMLTableElement): Element {.jsfunc.} = let before = this.findLastChildOf(TAG_TBODY) return this.create(TAG_TBODY, before) proc createTFoot(this: HTMLTableElement): Element {.jsfunc.} = return this.create(TAG_TFOOT, nil) proc deleteCaption(this: HTMLTableElement) {.jsfunc.} = this.delete(TAG_CAPTION) proc deleteTHead(this: HTMLTableElement) {.jsfunc.} = this.delete(TAG_THEAD) proc deleteTFoot(this: HTMLTableElement) {.jsfunc.} = this.delete(TAG_TFOOT) proc insertRow(ctx: JSContext; this: HTMLTableElement; index: int32 = -1): Opt[HTMLElement] {.jsfunc.} = let rows = ?ctx.rows(this) let nrows = ?ctx.getLength(rows) if index < -1 or index > int64(nrows): JS_ThrowDOMException(ctx, "IndexSizeError", "index out of bounds") return err() let tr = this.document.newHTMLElement(TAG_TR) if nrows == 0: this.createTBody().append(tr) elif index == -1 or uint32(index) == nrows: let it = ?ctx.item(rows, nrows - 1) it.parentNode.append(tr) else: let it = ?ctx.item(rows, uint32(index)) it.parentNode.insert(tr, it) ok(tr) proc deleteRow(ctx: JSContext; rows: HTMLCollection; index: int32): Opt[void] = let nrows = ?ctx.getLength(rows) if index < -1 or index >= int64(nrows): JS_ThrowDOMException(ctx, "IndexSizeError", "index out of bounds") return err() if index == -1: let it = ?ctx.item(rows, uint32(nrows - 1)) it.remove() elif nrows > 0: let it = ?ctx.item(rows, uint32(index)) it.remove() ok() proc deleteRow(ctx: JSContext; this: HTMLTableElement; index: int32 = -1): Opt[void] {.jsfunc.} = let rows = ?ctx.rows(this) return ctx.deleteRow(rows, index) # <tbody> proc rows(ctx: JSContext; this: HTMLTableSectionElement): Opt[HTMLCollection] {.jsfget.} = if this.cachedRows == nil: this.cachedRows = ?newHTMLCollection( ctx, this, match = isRow, islive = true, childonly = true ) ok(this.cachedRows) proc insertRow(ctx: JSContext; this: HTMLTableSectionElement; index: int32 = -1): Opt[HTMLElement] {.jsfunc.} = let rows = ?ctx.rows(this) let nrows = ?ctx.getLength(rows) if index < -1 or index > int64(nrows): JS_ThrowDOMException(ctx, "index out of bounds", "IndexSizeError") return err() let tr = this.document.newHTMLElement(TAG_TR) if index == -1 or index == int64(nrows): this.append(tr) else: let it = ?ctx.item(rows, uint32(index)) this.insert(tr, it) ok(tr) proc deleteRow(ctx: JSContext; this: HTMLTableSectionElement; index: int32 = -1): Opt[void] {.jsfunc.} = let rows = ?ctx.rows(this) return ctx.deleteRow(rows, index) # <tr> proc cells(ctx: JSContext; this: HTMLTableRowElement): JSValue {.jsfget.} = return ctx.getWeakCollection(this, wwmCells) proc rowIndex(ctx: JSContext; this: HTMLTableRowElement): Opt[int] {.jsfget.} = let table = HTMLTableElement(this.findAncestor(TAG_TABLE)) if table == nil: return ok(-1) let rows = ?ctx.rows(table) ctx.findNode(rows, this) proc sectionRowIndex(ctx: JSContext; this: HTMLTableRowElement): Opt[int] {. jsfget.} = let parent = this.parentElement if parent of HTMLTableElement: return ctx.rowIndex(this) if parent of HTMLTableSectionElement: let parent = HTMLTableSectionElement(parent) let rows = ?ctx.rows(parent) return ctx.findNode(rows, this) return ok(-1) # <textarea> proc jsForm(this: HTMLTextAreaElement): HTMLFormElement {.jsfget: "form".} = return this.form proc value*(textarea: HTMLTextAreaElement): string {.jsfget.} = if textarea.dirty: return textarea.internalValue return textarea.childTextContent proc `value=`*(textarea: HTMLTextAreaElement; s: sink string) {.jsfset: "value".} = textarea.dirty = true textarea.internalValue = s proc textAreaString*(textarea: HTMLTextAreaElement): string = result = "" let rows = int64(textarea.attrul(satRows).get(1)) let cols = textarea.attrul(satCols).get(20) var i = 0'i64 for line in textarea.value.split('\n'): if i >= rows: break if cols > 2 and cols <= uint64(int.high): result &= '[' & line.padToWidth(cols - 2) & "]\n" else: result &= "[]\n" inc i while i < rows: if cols > 2 and cols <= uint64(int.high): result &= '[' & ' '.repeat(int(cols - 2)) & "]\n" else: result &= "[]\n" inc i proc defaultValue(textarea: HTMLTextAreaElement): string {.jsfget.} = return textarea.textContent proc `defaultValue=`(textarea: HTMLTextAreaElement; s: sink string) {.jsfset: "defaultValue".} = textarea.replaceAll(s) # <title> proc text(this: HTMLTitleElement): string {.jsfget.} = return this.textContent proc `text=`(this: HTMLTitleElement; s: sink string) {.jsfset: "text".} = this.replaceAll(s) # <video> proc getSrc*(this: HTMLElement): tuple[src, contentType: string] = let src = this.attr(satSrc) if src != "": return (src, "") for el in this.elementDescendants(TAG_SOURCE): let src = el.attr(satSrc) if src != "": return (src, el.attr(satType)) return ("", "") proc addElementReflection(ctx: JSContext; class: JSClassID): Opt[void] = let proto = JS_GetClassProto(ctx, class) for i in ReflectAllStartIndex ..< int16(ReflectMap.len): let name = $ReflectMap[i].funcname if ctx.addReflectFunction(proto, name, jsReflectGet, jsReflectSet, cint(i)).isErr: JS_FreeValue(ctx, proto) return err() JS_FreeValue(ctx, proto) ok() proc addAttributeReflection(ctx: JSContext; class: JSClassID; attrs: openArray[int16]; base: JSClassID): Opt[void] = let proto = JS_GetClassProto(ctx, class) let diff = (uint16(class) - uint16(base)) shl 9 for i in attrs: if ctx.addReflectFunction(proto, $ReflectMap[i].funcname, jsReflectGet, jsReflectSet, cint(diff or uint16(i))).isErr: JS_FreeValue(ctx, proto) return err() JS_FreeValue(ctx, proto) ok() proc registerElements(ctx: JSContext; nodeCID: JSClassID): Opt[void] = let elementCID = ctx.registerType(Element, parent = nodeCID) if elementCID == 0: return err() let htmlElementCID = ctx.registerType(HTMLElement, parent = elementCID) if htmlElementCID == 0: return err() ?ctx.addElementReflection(htmlElementCID) template register(t: typed; tags: openArray[TagType]) = let class = ctx.registerType(t, parent = htmlElementCID) if class == 0: return err() const attrs = TagReflectMap[tags[0]] when attrs.len > 0: ?ctx.addAttributeReflection(class, attrs, htmlElementCID) template register(t: typed; tag: TagType) = register(t, [tag]) register(HTMLInputElement, TAG_INPUT) register(HTMLAnchorElement, TAG_A) register(HTMLSelectElement, TAG_SELECT) register(HTMLSpanElement, TAG_SPAN) register(HTMLOptGroupElement, TAG_OPTGROUP) register(HTMLOptionElement, TAG_OPTION) register(HTMLHeadingElement, [TAG_H1, TAG_H2, TAG_H3, TAG_H4, TAG_H5, TAG_H6]) register(HTMLBRElement, TAG_BR) register(HTMLMenuElement, TAG_MENU) register(HTMLUListElement, TAG_UL) register(HTMLOListElement, TAG_OL) register(HTMLLIElement, TAG_LI) register(HTMLStyleElement, TAG_STYLE) register(HTMLLinkElement, TAG_LINK) register(HTMLFormElement, TAG_FORM) register(HTMLTemplateElement, TAG_TEMPLATE) register(HTMLUnknownElement, TAG_UNKNOWN) register(HTMLScriptElement, TAG_SCRIPT) register(HTMLBaseElement, TAG_BASE) register(HTMLAreaElement, TAG_AREA) register(HTMLButtonElement, TAG_BUTTON) register(HTMLTextAreaElement, TAG_TEXTAREA) register(HTMLLabelElement, TAG_LABEL) register(HTMLCanvasElement, TAG_CANVAS) register(HTMLImageElement, TAG_IMG) register(HTMLVideoElement, TAG_VIDEO) register(HTMLAudioElement, TAG_AUDIO) register(HTMLIFrameElement, TAG_IFRAME) register(HTMLTableElement, TAG_TABLE) register(HTMLTableCaptionElement, TAG_CAPTION) register(HTMLTableRowElement, TAG_TR) register(HTMLTableSectionElement, [TAG_TBODY, TAG_THEAD, TAG_TFOOT]) register(HTMLMetaElement, TAG_META) register(HTMLDetailsElement, TAG_DETAILS) register(HTMLFrameElement, TAG_FRAME) register(HTMLTimeElement, TAG_TIME) register(HTMLQuoteElement, [TAG_BLOCKQUOTE, TAG_Q]) register(HTMLDataElement, TAG_DATA) register(HTMLHeadElement, TAG_HEAD) register(HTMLTitleElement, TAG_TITLE) register(HTMLObjectElement, TAG_OBJECT) register(HTMLSourceElement, TAG_SOURCE) register(HTMLModElement, [TAG_INS, TAG_DEL]) register(HTMLProgressElement, TAG_PROGRESS) register(HTMLSlotElement, TAG_SLOT) # 45/127 (warning: the 128th interface doesn't fit in the top 7 bits of # the getter/setter magic) let svgElementCID = ctx.registerType(SVGElement, parent = elementCID) if svgElementCID == 0: return err() ?ctx.registerType(SVGSVGElement, parent = svgElementCID) ok() proc addDOMModule*(ctx: JSContext; eventTargetCID: JSClassID): Opt[void] = let nodeCID = ctx.registerType(Node, parent = eventTargetCID) if nodeCID == 0: return err() if ctx.defineConsts(nodeCID, NodeType) == dprException: return err() let nodeListCID = ctx.registerType(NodeList, iterable = jitValue) if nodeListCID == 0: return err() let htmlCollectionCID = ctx.registerType(HTMLCollection, iterable = jitPair) if htmlCollectionCID == 0: return err() ?ctx.registerType(HTMLAllCollection) ?ctx.registerType(HTMLFormControlsCollection, parent = htmlCollectionCID) ?ctx.registerType(HTMLOptionsCollection, parent = htmlCollectionCID) ?ctx.registerType(RadioNodeList, parent = nodeListCID) ?ctx.registerType(NodeIterator) ?ctx.registerType(Location) let documentCID = ctx.registerType(Document, parent = nodeCID) if documentCID == 0: return err() ?ctx.registerType(XMLDocument, parent = documentCID) ?ctx.registerType(DOMImplementation) ?ctx.registerType(DOMTokenList, iterable = jitValue) ?ctx.registerType(DOMStringMap) let characterDataCID = ctx.registerType(CharacterData, parent = nodeCID) if characterDataCID == 0: return err() ?ctx.registerType(Comment, parent = characterDataCID) ?ctx.registerType(CDATASection, parent = characterDataCID) let documentFragmentCID = ctx.registerType(DocumentFragment, parent = nodeCID) if documentFragmentCID == 0: return err() ?ctx.registerType(ProcessingInstruction, parent = characterDataCID) ?ctx.registerType(Text, parent = characterDataCID) ?ctx.registerType(DocumentType, parent = nodeCID) ?ctx.registerType(Attr, parent = nodeCID) ?ctx.registerType(NamedNodeMap) ?ctx.registerType(CSSStyleDeclaration) ?ctx.registerType(DOMRect) ?ctx.registerType(DOMRectList) ?ctx.registerType(CustomElementRegistry) ?ctx.registerType(ShadowRoot, parent = documentFragmentCID) ?ctx.registerElements(nodeCID) let global = JS_GetGlobalObject(ctx) let imageFun = JS_NewCFunction(ctx, newImage, "Image", 2) if JS_IsException(imageFun): return err() if ctx.definePropertyCW(global, "Image", imageFun) == dprException: return err() discard JS_SetConstructorBit(ctx, imageFun, true) let optionFun = JS_NewCFunction(ctx, newOption, "Option", 4) if JS_IsException(optionFun): return err() discard JS_SetConstructorBit(ctx, optionFun, true) if ctx.definePropertyCW(global, "Option", optionFun) == dprException: return err() let document = JS_GetPropertyStr(ctx, global, "Document") if ctx.definePropertyCW(global, "HTMLDocument", document) == dprException: return err() let nodeFilter = JS_NewObject(ctx) if JS_IsException(nodeFilter): return err() for e in NodeFilterNode: let n = ctx.toJS(1u32 shl uint32(e)) if ctx.definePropertyE(nodeFilter, $e, n) == dprException: return err() case ctx.definePropertyE(nodeFilter, "SHOW_ALL", ctx.toJS(0xFFFFFFFFu32)) of dprException: return err() else: discard if ctx.definePropertyCW(global, "NodeFilter", nodeFilter) == dprException: return err() JS_FreeValue(ctx, global) ok() # Forward declaration hack isDefaultPassiveImpl = proc(target: EventTarget): bool = if not (target of Node): return false let node = Node(target) return target of Window or EventTarget(node.document) == target or EventTarget(node.document.documentElement) == target or EventTarget(node.document.body) == target getParentImpl = proc(ctx: JSContext; eventTarget: EventTarget; isLoad: bool): EventTarget = if eventTarget of Node: if eventTarget of Document: if isLoad: return nil # if no browsing context, then window will be nil anyway return Document(eventTarget).window if eventTarget of ShadowRoot: let shadow = ShadowRoot(eventTarget) #TODO composed return shadow.host return Node(eventTarget).parentNode return nil errorImpl = proc(ctx: JSContext; ss: varargs[string]) = ctx.getGlobal().console.error(ss) getAPIBaseURLImpl = proc(ctx: JSContext): URL = let window = ctx.getWindow() if window == nil or window.document == nil: return nil return window.document.baseURL isWindowImpl = proc(target: EventTarget): bool = return target of Window isHTMLElementImpl = proc(target: EventTarget): bool = return target of HTMLElement parseColorImpl = proc(target: EventTarget; s: string): Opt[ARGBColor] = return Element(target).parseColor(s) setEventImpl = proc(ctx: JSContext; event: Event): Event = let window = ctx.getWindow() if window != nil: let res = window.event window.event = event return res nil {.pop.} # raises: [] ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/html/domcanvas.nim����������������������������������������������������������������0000664�0000000�0000000�00000031537�15202323131�0017356�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/math import html/domexception import html/event import io/dynstream import io/packetwriter import monoucha/fromjs import monoucha/jsbind import monoucha/quickjs import monoucha/tojs import server/headers import server/loaderiface import server/request import types/bitmap import types/canvastypes import types/color import types/jsopt import types/opt import types/path import utils/strwidth import utils/twtstr type DrawingState = ref object # CanvasTransform transformMatrix: Matrix # CanvasFillStrokeStyles fillStyle: ARGBColor strokeStyle: ARGBColor # CanvasPathDrawingStyles lineWidth: float64 # CanvasTextDrawingStyles textAlign: CanvasTextAlign # CanvasPath path: Path next: DrawingState TextMetrics = ref object # x-direction width {.jsget.}: float64 actualBoundingBoxLeft {.jsget.}: float64 actualBoundingBoxRight {.jsget.}: float64 # y-direction fontBoundingBoxAscent {.jsget.}: float64 fontBoundingBoxDescent {.jsget.}: float64 actualBoundingBoxAscent {.jsget.}: float64 actualBoundingBoxDescent {.jsget.}: float64 emHeightAscent {.jsget.}: float64 emHeightDescent {.jsget.}: float64 hangingBaseline {.jsget.}: float64 alphabeticBaseline {.jsget.}: float64 ideographicBaseline {.jsget.}: float64 CanvasRenderingContext2D* = ref object canvas {.jsget.}: EventTarget bitmap: NetworkBitmap state: DrawingState ps*: PosixStream jsDestructor(CanvasRenderingContext2D) jsDestructor(TextMetrics) # Forward declaration hack var parseColorImpl*: proc(target: EventTarget; s: string): Opt[ARGBColor] {.nimcall, raises: [].} proc parseColor(target: EventTarget; s: string): Opt[ARGBColor] = return target.parseColorImpl(s) proc resetTransform(state: var DrawingState) = state.transformMatrix = newIdentityMatrix(3) proc reset*(state: var DrawingState) = state.resetTransform() state.fillStyle = rgba(0, 0, 0, 255) state.strokeStyle = rgba(0, 0, 0, 255) state.path = newPath() proc create2DContext*(loader: FileLoader; target: EventTarget; bitmap: NetworkBitmap; options: JSValueConst = JS_UNDEFINED): CanvasRenderingContext2D = let imageId = bitmap.imageId let (ps, ctlres) = loader.doPipeRequest("canvas-ctl-" & $imageId) if ps == nil: return nil let cacheId = loader.addCacheFile(ctlres.outputId) bitmap.cacheId = cacheId let request = newRequest( "img-codec+x-cha-canvas:decode", httpMethod = hmPost, headers = newHeaders(hgRequest, {"Cha-Image-Info-Only": "1"}), body = RequestBody(t: rbtOutput, outputId: ctlres.outputId) ) let response = loader.doRequest(request) loader.close(ctlres) if response.stream == nil: # no canvas module; give up ps.sclose() return nil loader.close(response) ps.withPacketWriterFire w: w.swrite(pcSetDimensions) w.swrite(bitmap.width) w.swrite(bitmap.height) let ctx2d = CanvasRenderingContext2D( bitmap: bitmap, canvas: target, ps: ps, state: DrawingState() ) ctx2d.state.reset() return ctx2d proc fillRect(ctx: CanvasRenderingContext2D; x1, y1, x2, y2: int; color: ARGBColor) = if ctx.ps != nil: ctx.ps.withPacketWriterFire w: w.swrite(pcFillRect) w.swrite(x1) w.swrite(y1) w.swrite(x2) w.swrite(y2) w.swrite(color) proc strokeRect(ctx: CanvasRenderingContext2D; x1, y1, x2, y2: int; color: ARGBColor) = if ctx.ps != nil: ctx.ps.withPacketWriterFire w: w.swrite(pcStrokeRect) w.swrite(x1) w.swrite(y1) w.swrite(x2) w.swrite(y2) w.swrite(color) proc fillPath(ctx: CanvasRenderingContext2D; path: Path; color: ARGBColor; fillRule: CanvasFillRule) = if ctx.ps != nil: let lines = path.getLineSegments() ctx.ps.withPacketWriterFire w: w.swrite(pcFillPath) w.swrite(lines) w.swrite(color) w.swrite(fillRule) proc strokePath(ctx: CanvasRenderingContext2D; path: Path; color: ARGBColor) = if ctx.ps != nil: let lines = path.getLines() ctx.ps.withPacketWriterFire w: w.swrite(pcStrokePath) w.swrite(lines) w.swrite(color) proc fillText(ctx: CanvasRenderingContext2D; text: string; x, y: float64; color: ARGBColor; align: CanvasTextAlign) = if ctx.ps != nil: ctx.ps.withPacketWriterFire w: w.swrite(pcFillText) w.swrite(text) w.swrite(x) w.swrite(y) w.swrite(color) w.swrite(align) proc strokeText(ctx: CanvasRenderingContext2D; text: string; x, y: float64; color: ARGBColor; align: CanvasTextAlign) = if ctx.ps != nil: ctx.ps.withPacketWriterFire w: w.swrite(pcStrokeText) w.swrite(text) w.swrite(x) w.swrite(y) w.swrite(color) w.swrite(align) proc clearRect(ctx: CanvasRenderingContext2D; x1, y1, x2, y2: int) = ctx.fillRect(0, 0, ctx.bitmap.width, ctx.bitmap.height, rgba(0, 0, 0, 0)) proc clear(ctx: CanvasRenderingContext2D) = ctx.clearRect(0, 0, ctx.bitmap.width, ctx.bitmap.height) proc save(ctx: CanvasRenderingContext2D) {.jsfunc.} = let state = DrawingState() state[] = ctx.state[] state.next = ctx.state ctx.state = state proc restore(ctx: CanvasRenderingContext2D) {.jsfunc.} = if ctx.state.next != nil: ctx.state = ctx.state.next proc reset(ctx: CanvasRenderingContext2D) {.jsfunc.} = ctx.clear() ctx.state.next = nil ctx.state.reset() #TODO scale proc rotate(ctx: CanvasRenderingContext2D; angle: float64) {.jsfunc.} = if classify(angle) in {fcInf, fcNegInf, fcNan}: return ctx.state.transformMatrix *= newMatrix( me = @[ cos(angle), -sin(angle), 0, sin(angle), cos(angle), 0, 0, 0, 1 ], w = 3, h = 3 ) proc translate(ctx: CanvasRenderingContext2D; x, y: float64) {.jsfunc.} = for v in [x, y]: if classify(v) in {fcInf, fcNegInf, fcNan}: return ctx.state.transformMatrix *= newMatrix( me = @[ 1f64, 0, x, 0, 1, y, 0, 0, 1 ], w = 3, h = 3 ) proc transform(ctx: CanvasRenderingContext2D; a, b, c, d, e, f: float64) {.jsfunc.} = for v in [a, b, c, d, e, f]: if classify(v) in {fcInf, fcNegInf, fcNan}: return ctx.state.transformMatrix *= newMatrix( me = @[ a, c, e, b, d, f, 0, 0, 1 ], w = 3, h = 3 ) #TODO getTransform, setTransform with DOMMatrix (i.e. we're missing DOMMatrix) proc setTransform(ctx: CanvasRenderingContext2D; a, b, c, d, e, f: float64) {.jsfunc.} = for v in [a, b, c, d, e, f]: if classify(v) in {fcInf, fcNegInf, fcNan}: return ctx.state.resetTransform() ctx.transform(a, b, c, d, e, f) proc resetTransform(ctx: CanvasRenderingContext2D) {.jsfunc.} = ctx.state.resetTransform() proc transform(ctx: CanvasRenderingContext2D; v: Vector2D): Vector2D = let mul = ctx.state.transformMatrix * newMatrix(@[v.x, v.y, 1], 1, 3) return Vector2D(x: mul.me[0], y: mul.me[1]) proc fillStyle(ctx: CanvasRenderingContext2D): string {.jsfget.} = return ctx.state.fillStyle.serialize() proc fillStyle(ctx: CanvasRenderingContext2D; s: string) {.jsfset.} = #TODO gradient, pattern if color := ctx.canvas.parseColor(s): ctx.state.fillStyle = color proc strokeStyle(ctx: CanvasRenderingContext2D): string {.jsfget.} = return ctx.state.strokeStyle.serialize() proc strokeStyle(ctx: CanvasRenderingContext2D; s: string) {.jsfset.} = #TODO gradient, pattern if color := ctx.canvas.parseColor(s): ctx.state.strokeStyle = color proc clearRect(ctx: CanvasRenderingContext2D; x, y, w, h: float64) {.jsfunc.} = for v in [x, y, w, h]: if classify(v) in {fcInf, fcNegInf, fcNan}: return #TODO clipping regions (right now we just clip to default) let bw = float64(ctx.bitmap.width) let bh = float64(ctx.bitmap.height) let x1 = int(min(max(x, 0), bw)) let y1 = int(min(max(y, 0), bh)) let x2 = int(min(max(x + w, 0), bw)) let y2 = int(min(max(y + h, 0), bh)) ctx.clearRect(x1, y1, x2, y2) proc fillRect(ctx: CanvasRenderingContext2D; x, y, w, h: float64) {.jsfunc.} = for v in [x, y, w, h]: if classify(v) in {fcInf, fcNegInf, fcNan}: return #TODO do we have to clip here? if w == 0 or h == 0: return let bw = float64(ctx.bitmap.width) let bh = float64(ctx.bitmap.height) let x1 = int(min(max(x, 0), bw)) let y1 = int(min(max(y, 0), bh)) let x2 = int(min(max(x + w, 0), bw)) let y2 = int(min(max(y + h, 0), bh)) ctx.fillRect(x1, y1, x2, y2, ctx.state.fillStyle) proc strokeRect(ctx: CanvasRenderingContext2D; x, y, w, h: float64) {.jsfunc.} = for v in [x, y, w, h]: if classify(v) in {fcInf, fcNegInf, fcNan}: return #TODO do we have to clip here? if w == 0 or h == 0: return let bw = float64(ctx.bitmap.width) let bh = float64(ctx.bitmap.height) let x1 = int(min(max(x, 0), bw)) let y1 = int(min(max(y, 0), bh)) let x2 = int(min(max(x + w, 0), bw)) let y2 = int(min(max(y + h, 0), bh)) ctx.strokeRect(x1, y1, x2, y2, ctx.state.strokeStyle) proc beginPath(ctx: CanvasRenderingContext2D) {.jsfunc.} = ctx.state.path.beginPath() proc fill(ctx: CanvasRenderingContext2D; fillRule = cfrNonZero) {.jsfunc.} = #TODO path ctx.state.path.tempClosePath() ctx.fillPath(ctx.state.path, ctx.state.fillStyle, fillRule) ctx.state.path.tempOpenPath() proc stroke(ctx: CanvasRenderingContext2D) {.jsfunc.} = #TODO path ctx.strokePath(ctx.state.path, ctx.state.strokeStyle) proc clip(ctx: CanvasRenderingContext2D; fillRule = cfrNonZero) {.jsfunc.} = #TODO path discard #TODO implement #TODO maxwidth proc fillText(ctx: CanvasRenderingContext2D; text: string; x, y: float64) {.jsfunc.} = for v in [x, y]: if classify(v) in {fcInf, fcNegInf, fcNan}: return let vec = ctx.transform(Vector2D(x: x, y: y)) ctx.fillText(text, vec.x, vec.y, ctx.state.fillStyle, ctx.state.textAlign) #TODO maxwidth proc strokeText(ctx: CanvasRenderingContext2D; text: string; x, y: float64) {.jsfunc.} = for v in [x, y]: if classify(v) in {fcInf, fcNegInf, fcNan}: return let vec = ctx.transform(Vector2D(x: x, y: y)) ctx.strokeText(text, vec.x, vec.y, ctx.state.strokeStyle, ctx.state.textAlign) proc measureText(ctx: CanvasRenderingContext2D; text: string): TextMetrics {.jsfunc.} = let tw = text.width() return TextMetrics( width: 8 * float64(tw), actualBoundingBoxLeft: 0, actualBoundingBoxRight: 8 * float64(tw), #TODO and the rest... ) proc lineWidth(ctx: CanvasRenderingContext2D): float64 {.jsfget.} = return ctx.state.lineWidth proc lineWidth(ctx: CanvasRenderingContext2D; f: float64) {.jsfset.} = if classify(f) in {fcZero, fcNegZero, fcInf, fcNegInf, fcNan}: return ctx.state.lineWidth = f proc setLineDash(ctx: CanvasRenderingContext2D; segments: seq[float64]) {.jsfunc.} = discard #TODO implement proc getLineDash(ctx: CanvasRenderingContext2D): seq[float64] {.jsfunc.} = discard #TODO implement newSeq[float64]() proc textAlign(ctx: CanvasRenderingContext2D): string {.jsfget.} = return $ctx.state.textAlign proc textAlign(ctx: CanvasRenderingContext2D; s: string) {.jsfset.} = if x := parseEnumNoCase[CanvasTextAlign](s): ctx.state.textAlign = x proc closePath(ctx: CanvasRenderingContext2D) {.jsfunc.} = ctx.state.path.closePath() proc moveTo(ctx: CanvasRenderingContext2D; x, y: float64) {.jsfunc.} = ctx.state.path.moveTo(x, y) proc lineTo(ctx: CanvasRenderingContext2D; x, y: float64) {.jsfunc.} = ctx.state.path.lineTo(x, y) proc quadraticCurveTo(ctx: CanvasRenderingContext2D; cpx, cpy, x, y: float64) {.jsfunc.} = ctx.state.path.quadraticCurveTo(cpx, cpy, x, y) proc radiusThrow(ctx: JSContext): JSValue = return JS_ThrowDOMException(ctx, "IndexSizeError", "expected positive radius, but got negative") proc arcTo(jsctx: JSContext; ctx: CanvasRenderingContext2D; x1, y1, x2, y2, radius: float64): JSValue {.jsfunc.} = if radius < 0: return jsctx.radiusThrow() ctx.state.path.arcTo(x1, y1, x2, y2, radius) return JS_UNDEFINED proc arc(jsctx: JSContext; ctx: CanvasRenderingContext2D; x, y, radius, startAngle, endAngle: float64; counterclockwise = false): JSValue {.jsfunc.} = if radius < 0: return jsctx.radiusThrow() ctx.state.path.arc(x, y, radius, startAngle, endAngle, counterclockwise) return JS_UNDEFINED proc ellipse(jsctx: JSContext; ctx: CanvasRenderingContext2D; x, y, radiusX, radiusY, rotation, startAngle, endAngle: float64; counterclockwise = false): JSValue {.jsfunc.} = if radiusX < 0 or radiusY < 0: return jsctx.radiusThrow() ctx.state.path.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterclockwise) return JS_UNDEFINED proc rect(ctx: CanvasRenderingContext2D; x, y, w, h: float64) {.jsfunc.} = ctx.state.path.rect(x, y, w, h) proc roundRect(ctx: CanvasRenderingContext2D; x, y, w, h, radii: float64) {.jsfunc.} = ctx.state.path.roundRect(x, y, w, h, radii) proc addCanvasModule*(ctx: JSContext): Opt[void] = ?ctx.registerType(CanvasRenderingContext2D) ?ctx.registerType(TextMetrics) ok() {.pop.} # raises: [] �����������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/html/domexception.c���������������������������������������������������������������0000664�0000000�0000000�00000017665�15202323131�0017546�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include <stdarg.h> #include <stdio.h> #include "qjs/quickjs.h" #define COUNTOF(x) (sizeof(x) / sizeof(*(x))) typedef struct JSDOMExceptionData { JSValue name; JSValue message; int code; } JSDOMExceptionData; typedef struct JSDOMExceptionNameDef { const char * const name; const char * const code_name; } JSDOMExceptionNameDef; static const JSDOMExceptionNameDef js_dom_exception_names_table[] = { { "IndexSizeError", "INDEX_SIZE_ERR" }, { NULL, "DOMSTRING_SIZE_ERR" }, { "HierarchyRequestError", "HIERARCHY_REQUEST_ERR" }, { "WrongDocumentError", "WRONG_DOCUMENT_ERR" }, { "InvalidCharacterError", "INVALID_CHARACTER_ERR" }, { NULL, "NO_DATA_ALLOWED_ERR" }, { "NoModificationAllowedError", "NO_MODIFICATION_ALLOWED_ERR" }, { "NotFoundError", "NOT_FOUND_ERR" }, { "NotSupportedError", "NOT_SUPPORTED_ERR" }, { "InUseAttributeError", "INUSE_ATTRIBUTE_ERR" }, { "InvalidStateError", "INVALID_STATE_ERR" }, { "SyntaxError", "SYNTAX_ERR" }, { "InvalidModificationError", "INVALID_MODIFICATION_ERR" }, { "NamespaceError", "NAMESPACE_ERR" }, { "InvalidAccessError", "INVALID_ACCESS_ERR" }, { NULL, "VALIDATION_ERR" }, { "TypeMismatchError", "TYPE_MISMATCH_ERR" }, { "SecurityError", "SECURITY_ERR" }, { "NetworkError", "NETWORK_ERR" }, { "AbortError", "ABORT_ERR" }, { "URLMismatchError", "URL_MISMATCH_ERR" }, { "QuotaExceededError", "QUOTA_EXCEEDED_ERR" }, { "TimeoutError", "TIMEOUT_ERR" }, { "InvalidNodeTypeError", "INVALID_NODE_TYPE_ERR" }, { "DataCloneError", "DATA_CLONE_ERR" } }; static JSClassID js_class_dom_exception = 0; static void js_domexception_finalizer(JSRuntime *rt, JSValue val) { JSDOMExceptionData *s = JS_GetOpaque(val, js_class_dom_exception); if (s) { JS_FreeValueRT(rt, s->name); JS_FreeValueRT(rt, s->message); js_free_rt(rt, s); } } static void js_domexception_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSDOMExceptionData *s = JS_GetOpaque(val, js_class_dom_exception); if (s) { JS_MarkValue(rt, s->name, mark_func); JS_MarkValue(rt, s->message, mark_func); } } static JSValue js_domexception_constructor0(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv, int skip_first_level) { JSDOMExceptionData *s; JSValue obj, message, name; obj = JS_NewObjectFromCtor(ctx, new_target, js_class_dom_exception); if (JS_IsException(obj)) return JS_EXCEPTION; if (!JS_IsUndefined(argv[0])) message = JS_ToString(ctx, argv[0]); else message = JS_NewString(ctx, ""); if (JS_IsException(message)) goto fail1; if (!JS_IsUndefined(argv[1])) name = JS_ToString(ctx, argv[1]); else name = JS_NewString(ctx, "Error"); if (JS_IsException(name)) goto fail2; s = js_malloc(ctx, sizeof(*s)); if (!s) goto fail3; s->name = name; s->message = message; s->code = -1; JS_SetOpaque(obj, s); JS_BuildBacktrace(ctx, obj, skip_first_level); return obj; fail3: JS_FreeValue(ctx, name); fail2: JS_FreeValue(ctx, message); fail1: JS_FreeValue(ctx, obj); return JS_EXCEPTION; } static JSValue js_domexception_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) { return js_domexception_constructor0(ctx, new_target, argc, argv, 1); } static JSValue js_domexception_get_name(JSContext *ctx, JSValueConst this_val) { JSDOMExceptionData *s; JSValue *valp; s = JS_GetOpaque2(ctx, this_val, js_class_dom_exception); if (!s) return JS_EXCEPTION; return JS_DupValue(ctx, s->name); } static JSValue js_domexception_get_message(JSContext *ctx, JSValueConst this_val) { JSDOMExceptionData *s; s = JS_GetOpaque2(ctx, this_val, js_class_dom_exception); if (!s) return JS_EXCEPTION; return JS_DupValue(ctx, s->message); } static JSValue js_domexception_get_code(JSContext *ctx, JSValueConst this_val) { JSDOMExceptionData *s; const char *name, *it; int i; size_t len; s = JS_GetOpaque2(ctx, this_val, js_class_dom_exception); if (!s) return JS_EXCEPTION; if (s->code == -1) { name = JS_ToCStringLen(ctx, &len, s->name); if (!name) return JS_EXCEPTION; for (i = 0; i < COUNTOF(js_dom_exception_names_table); i++) { it = js_dom_exception_names_table[i].name; if (it && !strcmp(it, name) && len == strlen(it)) { s->code = i; break; } } s->code++; JS_FreeCString(ctx, name); } return JS_NewInt32(ctx, s->code); } static const JSCFunctionListEntry js_domexception_proto_funcs[] = { JS_CGETSET_DEF("name", js_domexception_get_name, NULL ), JS_CGETSET_DEF("message", js_domexception_get_message, NULL ), JS_CGETSET_DEF("code", js_domexception_get_code, NULL ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "DOMException", JS_PROP_CONFIGURABLE ), }; static const JSClassDef js_domexception_class_def = { "DOMException", js_domexception_finalizer, js_domexception_mark, NULL, NULL, NULL /* can_destroy */ }; JSValue JS_ThrowDOMException(JSContext *ctx, const char *name, const char *fmt, ...) { JSValue obj, js_name, js_message; JSValueConst argv[2]; va_list ap; char buf[256]; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); js_name = JS_NewString(ctx, name); if (JS_IsException(js_name)) return JS_EXCEPTION; js_message = JS_NewString(ctx, buf); if (JS_IsException(js_message)) { JS_FreeValue(ctx, js_name); return JS_EXCEPTION; } argv[0] = js_message; argv[1] = js_name; obj = js_domexception_constructor0(ctx, JS_UNDEFINED, 2, argv, 0); JS_FreeValue(ctx, js_message); JS_FreeValue(ctx, js_name); if (JS_IsException(obj)) return JS_EXCEPTION; return JS_Throw(ctx, obj); } int JS_AddIntrinsicDOMException(JSContext *ctx) { JSRuntime *rt = JS_GetRuntime(ctx); int i, res; JSAtom name; JSValue ctor, proto, global_obj; JS_NewClassID(&js_class_dom_exception); if (JS_NewClass(rt, js_class_dom_exception, &js_domexception_class_def) < 0) return -1; proto = JS_NewError(ctx); if (JS_IsException(proto)) return -1; if (JS_SetPropertyFunctionList(ctx, proto, js_domexception_proto_funcs, COUNTOF(js_domexception_proto_funcs)) < 0) goto fail1; ctor = JS_NewCFunction2(ctx, js_domexception_constructor, "DOMException", 2, JS_CFUNC_constructor, 0); if (JS_IsException(ctor)) goto fail1; if (JS_SetConstructor(ctx, ctor, proto) < 0) goto fail2; for (i = 0; i < COUNTOF(js_dom_exception_names_table); i++) { name = JS_NewAtom(ctx, js_dom_exception_names_table[i].code_name); if (name == JS_ATOM_NULL) goto fail2; if ((JS_DefinePropertyValue(ctx, proto, name, JS_NewInt32(ctx, i + 1), JS_PROP_ENUMERABLE) < 0) || (JS_DefinePropertyValue(ctx, ctor, name, JS_NewInt32(ctx, i + 1), JS_PROP_ENUMERABLE) < 0)) { JS_FreeAtom(ctx, name); goto fail2; } JS_FreeAtom(ctx, name); } global_obj = JS_GetGlobalObject(ctx); res = JS_DefinePropertyValueStr(ctx, global_obj, "DOMException", ctor, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); JS_FreeValue(ctx, global_obj); if (res < 0) goto fail1; JS_SetClassProto(ctx, js_class_dom_exception, proto); return 0; fail2: JS_FreeValue(ctx, ctor); fail1: JS_FreeValue(ctx, proto); return -1; } ���������������������������������������������������������������������������chawan-v0.4.0/src/html/domexception.nim�������������������������������������������������������������0000664�0000000�0000000�00000000573�15202323131�0020075�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import monoucha/quickjs import types/opt {.compile("domexception.c", "").} proc JS_AddIntrinsicDOMException*(ctx: JSContext): cint {.importc.} proc JS_ThrowDOMException*(ctx: JSContext; name, fmt: cstring): JSValue {. importc, varargs, discardable.} proc addDOMExceptionModule*(ctx: JSContext): Opt[void] = if JS_AddIntrinsicDOMException(ctx) < 0: return err() ok() �������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/html/env.nim����������������������������������������������������������������������0000664�0000000�0000000�00000051371�15202323131�0016171�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/tables import config/conftypes import css/cssparser import css/mediaquery import html/catom import html/chadombuilder import html/dom import html/domcanvas import html/domexception import html/event import html/formdata import html/jsencoding import html/jsintl import html/performance import html/script import html/xmlhttprequest import io/chafile import io/console import io/dynstream import io/timeout import monoucha/fromjs import monoucha/jsbind import monoucha/jspropenumlist import monoucha/jstypes import monoucha/jsutils import monoucha/quickjs import monoucha/tojs import server/headers import server/loaderiface import server/request import types/blob import types/jsopt import types/opt import types/url import types/winattrs import utils/twtstr type JSFetchOpaque = ref object of RootObj ctx: JSContext resolve: JSValue reject: JSValue # Forward declarations proc setLocation(ctx: JSContext; window: Window; s: string): JSValue # NavigatorID proc appCodeName(navigator: Navigator): string {.jsfget.} = "Mozilla" proc appName(navigator: Navigator): string {.jsfget.} = "Netscape" proc appVersion(navigator: Navigator): string {.jsfget.} = "5.0 (Windows)" proc platform(navigator: Navigator): string {.jsfget.} = "Win32" proc product(navigator: Navigator): string {.jsfget.} = "Gecko" proc productSub(navigator: Navigator): string {.jsfget.} = "20100101" proc userAgent(ctx: JSContext; navigator: Navigator): string {.jsfget.} = return ctx.getWindow().userAgent proc vendor(navigator: Navigator): string {.jsfget.} = "" proc vendorSub(navigator: Navigator): string {.jsfget.} = "" proc taintEnabled(navigator: Navigator): bool {.jsfunc.} = false proc oscpu(navigator: Navigator): string {.jsfget.} = "Windows NT 10.0" # NavigatorLanguage proc language(navigator: Navigator): string {.jsfget.} = "en-US" proc languages(navigator: Navigator): seq[string] {.jsfget.} = @["en-US"] #TODO frozen array? # NavigatorOnline proc onLine(navigator: Navigator): bool {.jsfget.} = true # at the very least, the terminal is on-line :) #TODO NavigatorContentUtils # NavigatorCookies # "this website needs cookies to be enabled to function correctly" # It's probably better to lie here. proc cookieEnabled(navigator: Navigator): bool {.jsfget.} = true # NavigatorPlugins proc pdfViewerEnabled(navigator: Navigator): bool {.jsfget.} = false proc javaEnabled(navigator: Navigator): bool {.jsfunc.} = false proc namedItem(pluginArray: PluginArray): string {.jsfunc.} = "" proc namedItem(mimeTypeArray: MimeTypeArray): string {.jsfunc.} = "" proc item(pluginArray: PluginArray): JSValue {.jsfunc.} = JS_NULL proc length(pluginArray: PluginArray): uint32 {.jsfget.} = 0 proc item(mimeTypeArray: MimeTypeArray): JSValue {.jsfunc.} = JS_NULL proc length(mimeTypeArray: MimeTypeArray): uint32 {.jsfget.} = 0 proc getter(pluginArray: PluginArray; atom: JSAtom): JSValue {.jsgetownprop.} = return JS_UNINITIALIZED proc getter(mimeTypeArray: MimeTypeArray; atom: JSAtom): JSValue {.jsgetownprop.} = return JS_UNINITIALIZED # Notification # The existence of this feature in mainstream browsers is an insult to all # users' intelligence. Nevertheless, we have to shim the API because some # geniuses use it for "browser verification." proc newNotification(): Notification {.jsctor.} = Notification() # Permissions # See above. proc query(ctx: JSContext; this: Permissions; desc: JSValueConst): JSValue {.jsfunc.} = let name = JS_GetPropertyStr(ctx, desc, "name") if JS_IsException(name): return name JS_FreeValue(ctx, name) var funs {.noinit.}: array[2, JSValue] let res = ctx.newPromiseCapability(funs) if JS_IsException(res): return res JS_FreeValue(ctx, funs[0]) # reject immediately JS_ThrowTypeError(ctx, "permissions are not supported") let code = ctx.enqueueRejection(funs[1]) if code < 0: JS_FreeValue(ctx, res) return JS_EXCEPTION return res # Screen # These are fingerprinting vectors; only app mode gets the real values. proc availWidth(ctx: JSContext; screen: Screen): int {.jsfget.} = let window = ctx.getWindow() return window.settings.scriptAttrsp.widthPx proc availHeight(ctx: JSContext; screen: Screen): int {.jsfget.} = let window = ctx.getWindow() return window.settings.scriptAttrsp.heightPx proc width(ctx: JSContext; screen: Screen): int {.jsfget.} = return ctx.availWidth(screen) proc height(ctx: JSContext; screen: Screen): int {.jsfget.} = return ctx.availHeight(screen) proc colorDepth(ctx: JSContext; screen: Screen): int32 {.jsfget.} = let window = ctx.getWindow() case window.settings.scriptAttrsp.colorMode of cmMonochrome: return 1 of cmANSI: return 4 of cmEightBit: return 8 of cmTrueColor: return 24 proc pixelDepth(ctx: JSContext; screen: Screen): int32 {.jsfget.} = ctx.colorDepth(screen) # History proc length(history: History): uint32 {.jsfget.} = 1 proc state(history: History): JSValue {.jsfget.} = JS_NULL proc go(history: History) {.jsfunc.} = discard proc back(history: History) {.jsfunc.} = discard proc forward(history: History) {.jsfunc.} = discard proc pushState(ctx: JSContext; history: History; data, unused: JSValueConst; s: string): JSValue {.jsfunc.} = let window = ctx.getWindow() if window != nil: return ctx.setLocation(window, s) return JS_UNDEFINED proc replaceState(ctx: JSContext; history: History; data, unused: JSValueConst; s: string): JSValue {.jsfunc.} = let window = ctx.getWindow() if window != nil: return ctx.setLocation(window, s) return JS_UNDEFINED # Storage proc find(this: Storage; key: string): int = for i in 0 ..< this.map.len: if this.map[i].key == key: return i return -1 proc length(this: Storage): uint32 {.jsfget.} = return uint32(this.map.len) proc key(ctx: JSContext; this: Storage; u: uint32): JSValue {.jsfunc.} = if u < uint32(this.map.len): return ctx.toJS(this.map[int(u)].key) return JS_NULL proc getItem(ctx: JSContext; this: Storage; s: string): JSValue {.jsfunc.} = let i = this.find(s) if i != -1: return ctx.toJS(this.map[i].value) return JS_NULL proc setItem(ctx: JSContext; this: Storage; key, value: string): JSValue {.jsfunc.} = let i = this.find(key) if i != -1: this.map[i].value = value else: if this.map.len >= 64: return JS_ThrowDOMException(ctx, "QuotaExceededError", "quota exceeded") this.map.add((key, value)) return JS_UNDEFINED proc removeItem(this: Storage; key: string) {.jsfunc.} = let i = this.find(key) if i != -1: this.map.del(i) proc names(ctx: JSContext; this: Storage): JSPropertyEnumList {.jspropnames.} = var list = newJSPropertyEnumList(ctx, uint32(this.map.len)) for it in this.map: list.add(it.key) return list proc getter(ctx: JSContext; this: Storage; s: string): JSValue {.jsgetownprop.} = return ctx.toJS(ctx.getItem(this, s)).uninitIfNull() proc setter(ctx: JSContext; this: Storage; k, v: string): JSValue {.jssetprop.} = return ctx.setItem(this, k, v) proc delete(this: Storage; k: string): bool {.jsdelprop.} = this.removeItem(k) return true # Crypto proc getRandomValues(ctx: JSContext; crypto: Crypto; array: JSValueConst): JSValue {.jsfunc.} = var view: JSArrayBufferView if ctx.fromJS(array, view).isErr: return JS_EXCEPTION if view.t == JS_TYPED_ARRAY_UINT8C or view.t > JS_TYPED_ARRAY_BIG_UINT64: return JS_ThrowDOMException(ctx, "TypeMismatchError", "Wrong typed array type") if view.abuf.len > 65536: return JS_ThrowDOMException(ctx, "QuotaExceededError", "Too large array") doAssert crypto.urandom.readLoop(view.toOpenArray()).isOk return JS_DupValue(ctx, array) proc addNavigatorModule*(ctx: JSContext): Opt[void] = ?ctx.registerType(Navigator) ?ctx.registerType(PluginArray) ?ctx.registerType(MimeTypeArray) ?ctx.registerType(Screen) ?ctx.registerType(History) ?ctx.registerType(Storage) ?ctx.registerType(Crypto) ?ctx.registerType(Notification) ?ctx.registerType(Permissions) ok() # Window proc finalize(rt: JSRuntime; window: Window) {.jsfin.} = window.timeouts.clearAll() rt.freeValues(window.weakMap) window.settings.moduleMap.clear(rt) for data in window.loader.data: if data of ConnectData: let data = ConnectData(data) if data.opaque of JSFetchOpaque: let opaque = JSFetchOpaque(data.opaque) JS_FreeValueRT(rt, opaque.resolve) JS_FreeValueRT(rt, opaque.reject) JS_FreeContext(opaque.ctx) opaque.resolve = JS_UNDEFINED opaque.reject = JS_UNDEFINED opaque.ctx = nil proc mark(rt: JSRuntime; window: Window; markFunc: JS_MarkFunc) {.jsmark.} = for it in window.weakMap: JS_MarkValue(rt, it, markFunc) proc throwNetworkError(ctx: JSContext): JSValue = return JS_ThrowTypeError(ctx, "NetworkError when attempting to fetch resource") proc jsFinish(opaque: RootRef; response: Response) = let opaque = JSFetchOpaque(opaque) let ctx = opaque.ctx let resolve = opaque.resolve let reject = opaque.reject opaque.resolve = JS_UNDEFINED opaque.reject = JS_UNDEFINED opaque.ctx = nil if response != nil: let val = ctx.toJS(response) if not JS_IsException(val): let res = ctx.callSink(resolve, JS_UNDEFINED, val) JS_FreeValue(ctx, res) JS_FreeValue(ctx, reject) else: discard ctx.throwNetworkError() discard ctx.enqueueRejection(reject) JS_FreeValue(ctx, resolve) JS_FreeContext(ctx) proc fetch(ctx: JSContext; window: Window; input: JSValueConst; init: JSValueConst = JS_UNDEFINED): JSValue {.jsfunc.} = let input0 = newRequest(ctx, input, init) if input0.isErr: return JS_EXCEPTION let input = input0.get var funs {.noinit.}: array[2, JSValue] let res = ctx.newPromiseCapability(funs) if JS_IsException(res): return res if input.url.schemeType != stData and not window.isSameOrigin(input.url.origin): JS_FreeValue(ctx, funs[0]) # reject immediately discard ctx.throwNetworkError() let code = ctx.enqueueRejection(funs[1]) if code < 0: JS_FreeValue(ctx, res) return JS_EXCEPTION else: let opaque = JSFetchOpaque( ctx: JS_DupContext(ctx), resolve: funs[0], reject: funs[1] ) window.loader.fetch(input, jsFinish, opaque) return res proc scrollTo(window: Window) {.jsfunc.} = discard #TODO maybe in app mode? proc setTimeout(window: Window; handler: JSValueConst; timeout = 0i32; args: varargs[JSValueConst]): int32 {.jsfunc.} = return window.timeouts.setTimeout(ttTimeout, handler, timeout, args) proc setInterval(window: Window; handler: JSValueConst; interval = 0i32; args: varargs[JSValueConst]): int32 {.jsfunc.} = return window.timeouts.setTimeout(ttInterval, handler, interval, args) proc clearTimeout(window: Window; id: int32) {.jsfunc.} = window.timeouts.clearTimeout(id) proc clearInterval(window: Window; id: int32) {.jsfunc.} = window.clearTimeout(id) proc screenX(window: Window): int {.jsrfget.} = 0 proc screenY(window: Window): int {.jsrfget.} = 0 proc screenLeft(window: Window): int {.jsrfget.} = 0 proc screenTop(window: Window): int {.jsrfget.} = 0 proc outerWidth(ctx: JSContext; window: Window): int {.jsrfget.} = return ctx.availWidth(window.screen) proc outerHeight(ctx: JSContext; window: Window): int {.jsrfget.} = return ctx.availHeight(window.screen) proc innerWidth(ctx: JSContext; window: Window): int {.jsrfget.} = return ctx.availWidth(window.screen) proc innerHeight(ctx: JSContext; window: Window): int {.jsrfget.} = return ctx.availHeight(window.screen) proc devicePixelRatio(window: Window): float64 {.jsrfget.} = 1 proc setLocation(ctx: JSContext; window: Window; s: string): JSValue {.jsfset: "location".} = if window.document == nil: return JS_ThrowTypeError(ctx, "document is null") return ctx.setLocation(window.document, s) proc getWindow(window: Window): Window {.jsuffget: "window", jsrfget: "frames", jsrfget: "self".} = return window proc getTop(window: Window): Window {.jsuffget: "top".} = return window #TODO frames? proc getParent(window: Window): Window {.jsrfget: "parent".} = return window #TODO frames? proc origin(window: Window): string {.jsrfget.} = return window.location.origin # See twtstr for the actual implementations. proc atob(ctx: JSContext; window: Window; data: string): JSValue {.jsfunc.} = var s: string if (let r = s.atob(data); r.isErr): return JS_ThrowDOMException(ctx, "InvalidCharacterError", r.error) return ctx.toJS(NarrowString(s)) proc btoa(ctx: JSContext; window: Window; data: JSValueConst): JSValue {.jsfunc.} = let data = JS_ToString(ctx, data) if JS_IsException(data): return JS_EXCEPTION let len = JS_GetStringLength(data) if len == 0: JS_FreeValue(ctx, data) return ctx.toJS("") let buf = JS_GetNarrowStringBuffer(data) if buf == nil: JS_FreeValue(ctx, data) return JS_ThrowDOMException(ctx, "InvalidCharacterError", "invalid character in string") let res = btoa(buf.toOpenArray(0, int(len) - 1)) JS_FreeValue(ctx, data) return ctx.toJS(res) proc alert(window: Window; s: string) {.jsfunc.} = window.console.error(s) proc getEvent(ctx: JSContext; window: Window): JSValue {.jsrfget: "event".} = if window.event == nil: return JS_UNDEFINED return ctx.toJS(window.event) proc animationFrameHandler(ctx: JSContext; this: JSValueConst; argc: cint; argv: JSValueConstArray): JSValue {.cdecl.} = let arg0 = ctx.toJS(getUnixMillis()) return ctx.callSink(argv[0], this, arg0) proc requestAnimationFrame(ctx: JSContext; window: Window; callback: JSValueConst): JSValue {.jsfunc.} = if not JS_IsFunction(ctx, callback): return JS_ThrowTypeError(ctx, "callback is not a function") let handler = JS_NewCFunction(ctx, animationFrameHandler, "animation frame handler", 1) if JS_IsException(handler): return JS_EXCEPTION let res = ctx.toJS(window.setTimeout(handler, 0, callback)) JS_FreeValue(ctx, handler) res proc getComputedStyle(ctx: JSContext; window: Window; element: Element; pseudoElt: JSValueConst = JS_UNDEFINED): Opt[CSSStyleDeclaration] {.jsfunc.} = return ctx.getComputedStyle0(window, element, pseudoElt) type MediaQueryList = ref object of EventTarget media {.jsget.}: string matches {.jsget.}: bool #TODO onchange jsDestructor(MediaQueryList) proc matchMedia(window: Window; s: string): MediaQueryList {.jsfunc.} = var ctx = initCSSParser(s) let mqlist = ctx.parseMediaQueryList(window.settings.scriptAttrsp) return MediaQueryList( matches: mqlist.appliesScript(addr window.settings), media: $mqlist ) proc postMessage(ctx: JSContext; window: Window; value: JSValueConst): Opt[void] {.jsfunc.} = #TODO structuredClone... let value = JS_JSONStringify(ctx, value, JS_UNDEFINED, JS_UNDEFINED) var s: string ?ctx.fromJSFree(value, s) let data = JS_ParseJSON(ctx, cstring(s), csize_t(s.len), cstring"<postMessage>") let event = ctx.newMessageEvent(satMessage.toAtom(), MessageEventInit(data: data)) JS_FreeValue(ctx, data) window.fireEvent(event, window) ok() proc microtaskJob(ctx: JSContext; argc: cint; argv: JSValueConstArray): JSValue {.cdecl.} = let global = JS_GetGlobalObject(ctx) let res = ctx.call(argv[0], global) JS_FreeValue(ctx, global) res proc queueMicrotask(ctx: JSContext; window: Window; fun: JSValueConst): JSValue {.jsfunc.} = if not JS_IsFunction(ctx, fun): return JS_ThrowTypeError(ctx, "not a function") if ctx.enqueueJob(microtaskJob, fun) < 0: return JS_EXCEPTION return JS_UNDEFINED proc normalizeModuleName*(ctx: JSContext; baseName, name: cstringConst; opaque: pointer): cstring {.cdecl.} = let sname = $name let url = parseURL0(sname) if url != nil: return js_strdup(ctx, cstring(name)) if name[0] == '.' and name[1] == '.' and name[2] == '/' or name[0] == '.' and name[1] == '/' or name[0] == '/': let url = parseURL0(sname, parseURL0($baseName)) if url != nil: let surl = $url return js_strdup(ctx, cstring(surl)) JS_ThrowTypeError(ctx, "relative module names must start with ./, ../ or /") return nil proc loadJSModule(ctx: JSContext; moduleName: cstringConst; opaque: pointer): JSModuleDef {.cdecl.} = let window = ctx.getWindow() let name = $moduleName let url = parseURL0(name) if url == nil or not window.isSameOrigin(url.origin): JS_ThrowTypeError(ctx, "invalid URL: %s", moduleName) return nil let request = newRequest(url) let response = window.loader.doRequest(request) if response.stream == nil: JS_ThrowTypeError(ctx, "Failed to load module %s", moduleName) return nil window.loader.resume(response) let source = response.stream.readAll() window.loader.close(response) return ctx.finishLoadModule(source, name) proc rejectionHandler(ctx: JSContext; promise, reason: JSValueConst; isHandled: JS_BOOL; opaque: pointer) {.cdecl.} = if not isHandled: let window = ctx.getGlobal() var s: string if fromJS(ctx, reason, s).isOk: s &= '\n' var ss: string if ctx.fromJSGetProp(reason, "stack", ss).isOk: s &= ss if window.document != nil: window.console.error("Unhandled promise in document", $window.document.url, s) else: window.console.error("(Unhandled promise)", s) window.console.flush() proc addCommonModules*(ctx: JSContext; window: Window): Opt[void] = ctx.setGlobal(window) let (eventCID, eventTargetCID) = ?ctx.addEventModule() let windowCID = ctx.registerType(Window, parent = eventTargetCID, asglobal = true) if windowCID == 0: return err() let global = JS_GetGlobalObject(ctx) ?ctx.addEventGetSet(global, WindowEvents) JS_FreeValue(ctx, global) ?ctx.registerType(MediaQueryList, parent = eventTargetCID) JS_SetHostPromiseRejectionTracker(JS_GetRuntime(ctx), rejectionHandler, nil) ?ctx.addConsoleModule() ?ctx.addNavigatorModule() ?ctx.addDOMExceptionModule() ?ctx.addDOMModule(eventTargetCID) ?ctx.addCanvasModule() ?ctx.addURLModule() ?ctx.addHTMLModule() ?ctx.addIntlModule() ?ctx.addBlobModule() ?ctx.addFormDataModule() ?ctx.addXMLHttpRequestModule(eventCID, eventTargetCID) ?ctx.addHeadersModule() ?ctx.addRequestModule() ?ctx.addResponseModule() ?ctx.addEncodingModule() ctx.addPerformanceModule(eventTargetCID) proc evalJSFree(opaque: RootRef; src, file: string) = let window = Window(opaque) let ret = window.jsctx.eval(src, file, JS_EVAL_TYPE_GLOBAL) if JS_IsException(ret): window.console.log("Exception in document", $window.document.url, window.jsctx.getExceptionMsg()) else: JS_FreeValue(window.jsctx, ret) proc getConsole(ctx: JSContext): Console = ctx.getGlobal().console proc getLoader(ctx: JSContext): FileLoader = ctx.getGlobal().loader proc addScripting*(window: Window; ctx: JSContext): Opt[void] = let rt = JS_GetRuntime(ctx) window.jsctx = ctx window.importMapsAllowed = true window.timeouts = newTimeoutState(ctx, evalJSFree, window) window.addCustomElementRegistry(rt) let jsWindow = JS_GetGlobalObject(ctx) let weakMap = JS_GetPropertyStr(ctx, jsWindow, "WeakMap") for it in window.weakMap.mitems: it = JS_CallConstructor(ctx, weakMap, 0, nil) if JS_IsException(it): return err() JS_FreeValue(ctx, weakMap) JS_FreeValue(ctx, jsWindow) JS_SetModuleLoaderFunc(rt, normalizeModuleName, loadJSModule, nil) window.performance = newPerformance(window.settings.scripting) if window.settings.scripting == smApp: window.settings.scriptAttrsp = window.settings.attrsp else: window.settings.scriptAttrsp = unsafeAddr dummyAttrs ctx.addCommonModules(window) proc newWindow*(scripting: ScriptingMode; images, styling, autofocus: bool; headless: HeadlessMode; attrsp: ptr WindowAttributes; loader: FileLoader; url: URL; urandom: PosixStream; imageTypes: Table[string, string]; userAgent, referrer, contentType: string): Window = let window = Window( console: newConsole(cast[ChaFile](stderr)), navigator: Navigator( plugins: PluginArray(), mimeTypes: MimeTypeArray(), permissions: Permissions() ), loader: loader, settings: EnvironmentSettings( attrsp: attrsp, styling: styling, scripting: scripting, origin: url.origin, images: images, autofocus: autofocus, headless: headless, contentType: contentType.toAtom() ), crypto: Crypto(urandom: urandom), imageTypes: imageTypes, userAgent: userAgent, referrer: referrer, screen: Screen(), history: History(), localStorage: Storage(), sessionStorage: Storage(), ) window.location = window.newLocation() for it in window.weakMap.mitems: it = JS_UNDEFINED if scripting != smFalse: let rt = newGlobalJSRuntime() let ctx = rt.newJSContext() if window.addScripting(ctx).isErr: window.console.error("failed to initialize JS") window.console.writeException(ctx) quit(1) return window # Forward declaration hack getConsoleImpl = getConsole getLoaderImpl = getLoader {.pop.} # raises: [] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/html/event.nim��������������������������������������������������������������������0000664�0000000�0000000�00000063361�15202323131�0016524�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/options import html/catom import html/domexception import html/script import io/timeout import monoucha/fromjs import monoucha/jsbind import monoucha/jsnull import monoucha/jstypes import monoucha/jsutils import monoucha/quickjs import monoucha/tojs import types/jsopt import types/opt import utils/twtstr type EventPhase = enum NONE = 0u16 CAPTURING_PHASE = 1u16 AT_TARGET = 2u16 BUBBLING_PHASE = 3u16 EventFlag* = enum efStopPropagation efStopImmediatePropagation efCanceled efInPassiveListener efComposed efInitialized efDispatch Event* = ref object of RootObj ctype* {.jsget: "type".}: CAtom target* {.jsget.}: EventTarget currentTarget* {.jsget.}: EventTarget eventPhase {.jsget.}: uint16 bubbles {.jsget.}: bool cancelable {.jsget.}: bool flags*: set[EventFlag] isTrusted* {.jsufget.}: bool timeStamp {.jsget.}: float64 CustomEvent* = ref object of Event detail {.jsget.}: JSValue MessageEvent* = ref object of Event data {.jsget.}: JSValue origin {.jsget.}: string SubmitEvent* = ref object of Event submitter {.jsget.}: EventTarget UIEvent* = ref object of Event detail {.jsget.}: int32 view {.jsget.}: EventTarget MouseEvent* = ref object of UIEvent screenX {.jsget.}: int32 screenY {.jsget.}: int32 clientX {.jsget, jsget: "x".}: int32 clientY {.jsget, jsget: "y".}: int32 button {.jsget.}: int16 buttons {.jsget.}: uint16 ctrlKey {.jsget.}: bool shiftKey {.jsget.}: bool altKey {.jsget.}: bool metaKey {.jsget.}: bool relatedTarget {.jsget.}: EventTarget #TODO and the others InputEvent* = ref object of UIEvent data {.jsget.}: Option[string] isComposing {.jsget.}: bool inputType {.jsget.}: string EventTarget* = ref object of RootObj eventListener: EventListener EventListener {.acyclic.} = ref object # if callback is undefined, the listener has been removed callback: JSValue ctype: CAtom capture: bool once: bool internal: bool passive: bool next: EventListener signal: AbortSignal AbortSignal = ref object of EventTarget reason {.jsget.}: JSValue aborted {.jsget.}: bool abortSteps: seq[JSValue] #TODO source/dependent signals AbortController = ref object signal {.jsget.}: AbortSignal jsDestructor(Event) jsDestructor(CustomEvent) jsDestructor(MessageEvent) jsDestructor(SubmitEvent) jsDestructor(UIEvent) jsDestructor(MouseEvent) jsDestructor(InputEvent) jsDestructor(EventTarget) jsDestructor(AbortSignal) jsDestructor(AbortController) # Forward declaration hack var isDefaultPassiveImpl*: proc(target: EventTarget): bool {.nimcall, raises: [].} var getParentImpl*: proc(ctx: JSContext; target: EventTarget; isLoad: bool): EventTarget {.nimcall, raises: [].} var isWindowImpl*: proc(target: EventTarget): bool {.nimcall, raises: [].} var isHTMLElementImpl*: proc(target: EventTarget): bool {.nimcall, raises: [].} var setEventImpl*: proc(ctx: JSContext; event: Event): Event {. nimcall, raises: [].} # Forward declarations proc removeEventListener(ctx: JSContext; eventTarget: EventTarget; ctype: CAtom; callback: JSValueConst; options: JSValueConst = JS_UNDEFINED): Opt[void] iterator eventListeners(this: EventTarget): EventListener = var it = this.eventListener while it != nil: yield it it = it.next proc finalize(rt: JSRuntime; target: EventTarget) {.jsfin.} = # Can't take rt as param here, because elements may be unbound in JS. for el in target.eventListeners: JS_FreeValueRT(rt, el.callback) proc mark(rt: JSRuntime; target: EventTarget; markFunc: JS_MarkFunc) {.jsmark.} = for el in target.eventListeners: JS_MarkValue(rt, el.callback, markFunc) type EventInit* = object of JSDict bubbles* {.jsdefault.}: bool cancelable* {.jsdefault.}: bool composed* {.jsdefault.}: bool CustomEventInit = object of EventInit detail {.jsdefault: JS_NULL.}: JSValueConst MessageEventInit* = object of EventInit data* {.jsdefault: JS_NULL.}: JSValueConst origin {.jsdefault.}: string lastEventId {.jsdefault.}: string # Event proc innerEventCreationSteps*(event: Event; eventInitDict: EventInit) = event.flags = {efInitialized} #TODO this should measure time starting from when the script was started. event.timeStamp = float64(getUnixMillis()) event.bubbles = eventInitDict.bubbles event.cancelable = eventInitDict.cancelable if eventInitDict.composed: event.flags.incl(efComposed) #TODO eventInitDict type proc newEvent(ctx: JSContext; ctype: CAtom; eventInitDict = EventInit()): Event {.jsctor.} = let event = Event(ctype: ctype) event.innerEventCreationSteps(eventInitDict) return event proc newEvent*(ctype: CAtom; target: EventTarget; bubbles, cancelable: bool): Event = return Event( ctype: ctype, target: target, currentTarget: target, bubbles: bubbles, cancelable: cancelable ) proc initialize(this: Event; ctype: CAtom; bubbles, cancelable: bool) = this.flags.incl(efInitialized) this.isTrusted = false this.target = nil this.ctype = ctype this.bubbles = bubbles this.cancelable = cancelable proc initEvent(this: Event; ctype: CAtom; bubbles, cancelable: bool) {.jsfunc.} = if efDispatch notin this.flags: this.initialize(ctype, bubbles, cancelable) proc srcElement(this: Event): EventTarget {.jsfget.} = return this.target #TODO shadow DOM etc. proc composedPath(this: Event): seq[EventTarget] {.jsfunc.} = if this.currentTarget == nil: return newSeq[EventTarget]() return @[this.currentTarget] proc stopPropagation(this: Event) {.jsfunc.} = this.flags.incl(efStopPropagation) proc cancelBubble(this: Event): bool {.jsfget.} = return efStopPropagation in this.flags proc `cancelBubble=`(this: Event; cancel: bool) {.jsfset: "cancelBubble".} = if cancel: this.stopPropagation() proc stopImmediatePropagation(this: Event) {.jsfunc.} = this.flags.incl({efStopPropagation, efStopImmediatePropagation}) proc preventDefault(this: Event) {.jsfunc.} = if this.cancelable and efInPassiveListener notin this.flags: this.flags.incl(efCanceled) proc returnValue(this: Event): bool {.jsfget.} = return efCanceled notin this.flags proc `returnValue=`(this: Event; value: bool) {.jsfset: "returnValue".} = if not value: this.preventDefault() proc defaultPrevented(this: Event): bool {.jsfget.} = return efCanceled in this.flags proc composed(this: Event): bool {.jsfget.} = return efComposed in this.flags # CustomEvent proc newCustomEvent*(ctx: JSContext; ctype: CAtom; eventInitDict = CustomEventInit(detail: JS_NULL)): CustomEvent {.jsctor.} = let event = CustomEvent( ctype: ctype, detail: JS_DupValue(ctx, eventInitDict.detail) ) event.innerEventCreationSteps(EventInit(eventInitDict)) return event proc finalize(rt: JSRuntime; this: CustomEvent) {.jsfin.} = JS_FreeValueRT(rt, this.detail) proc mark(rt: JSRuntime; this: CustomEvent; markFun: JS_MarkFunc) {.jsmark.} = JS_MarkValue(rt, this.detail, markFun) proc initCustomEvent(ctx: JSContext; this: CustomEvent; ctype: CAtom; bubbles, cancelable: bool; detail: JSValueConst) {.jsfunc.} = if efDispatch notin this.flags: if efInitialized notin this.flags: JS_FreeValue(ctx, this.detail) this.detail = JS_DupValue(ctx, detail) this.initialize(ctype, bubbles, cancelable) # MessageEvent proc newMessageEvent*(ctx: JSContext; ctype: CAtom; eventInit = MessageEventInit(data: JS_NULL)): MessageEvent = let event = MessageEvent( ctype: ctype, data: JS_DupValue(ctx, eventInit.data), origin: eventInit.origin ) event.innerEventCreationSteps(EventInit(eventInit)) return event proc finalize(rt: JSRuntime; this: MessageEvent) {.jsfin.} = JS_FreeValueRT(rt, this.data) proc mark(rt: JSRuntime; this: MessageEvent; markFun: JS_MarkFunc) {.jsmark.} = JS_MarkValue(rt, this.data, markFun) # SubmitEvent type EventTargetHTMLElement* = distinct EventTarget proc fromJS(ctx: JSContext; val: JSValueConst; res: var EventTargetHTMLElement): FromJSResult = var res0: EventTarget ?ctx.fromJS(val, res0) if not res0.isHTMLElementImpl(): JS_ThrowTypeError(ctx, "HTMLElement expected") return fjErr res = EventTargetHTMLElement(res0) fjOk type SubmitEventInit* = object of EventInit submitter* {.jsdefault.}: EventTargetHTMLElement proc newSubmitEvent*(ctype: CAtom; eventInit = SubmitEventInit()): SubmitEvent {.jsctor.} = let event = SubmitEvent( ctype: ctype, submitter: EventTarget(eventInit.submitter) ) event.innerEventCreationSteps(EventInit(eventInit)) return event # UIEvent type EventTargetWindow* = distinct EventTarget proc fromJS(ctx: JSContext; val: JSValueConst; res: var EventTargetWindow): FromJSResult = var res0: EventTarget ?ctx.fromJS(val, res0) if not res0.isWindowImpl(): JS_ThrowTypeError(ctx, "Window expected") return fjErr res = EventTargetWindow(res0) fjOk type UIEventInit = object of EventInit view* {.jsdefault.}: EventTargetWindow detail* {.jsdefault.}: int32 proc newUIEvent*(ctype: CAtom; eventInit = UIEventInit()): UIEvent {.jsctor.} = let event = UIEvent( ctype: ctype, view: EventTarget(eventInit.view), detail: eventInit.detail ) event.innerEventCreationSteps(EventInit(eventInit)) return event proc initUIEvent(this: UIEvent; ctype: CAtom; bubbles = false; cancelable = false; view = none(EventTarget); detail = 0i32) {.jsfunc.} = this.ctype = ctype this.bubbles = bubbles this.cancelable = cancelable this.view = view.get(nil) this.detail = detail type EventModifierInit = object of UIEventInit ctrlKey {.jsdefault.}: bool shiftKey {.jsdefault.}: bool altKey {.jsdefault.}: bool metaKey {.jsdefault.}: bool #TODO and the others... # MouseEvent type MouseEventInit* = object of EventModifierInit screenX* {.jsdefault.}: int32 screenY* {.jsdefault.}: int32 clientX* {.jsdefault.}: int32 clientY* {.jsdefault.}: int32 button* {.jsdefault.}: int16 buttons* {.jsdefault.}: uint16 relatedTarget {.jsdefault.}: Option[EventTarget] proc newMouseEvent*(ctype: CAtom; eventInit = MouseEventInit()): MouseEvent {.jsctor.} = let event = MouseEvent( ctype: ctype, view: EventTarget(eventInit.view), screenX: eventInit.screenX, screenY: eventInit.screenY, clientX: eventInit.clientX, clientY: eventInit.clientY, ctrlKey: eventInit.ctrlKey, shiftKey: eventInit.shiftKey, altKey: eventInit.altKey, metaKey: eventInit.metaKey, button: cast[int16](eventInit.button), buttons: uint16(eventInit.buttons), relatedTarget: eventInit.relatedTarget.get(nil) ) event.innerEventCreationSteps(EventInit(eventInit)) return event # InputEvent type InputEventInit* = object of UIEventInit data* {.jsdefault.}: Option[string] isComposing* {.jsdefault.}: bool inputType* {.jsdefault.}: string proc newInputEvent*(ctype: CAtom; eventInit = InputEventInit()): InputEvent = let event = InputEvent( ctype: ctype, view: EventTarget(eventInit.view), data: eventInit.data, isComposing: eventInit.isComposing, inputType: eventInit.inputType, detail: eventInit.detail ) event.innerEventCreationSteps(EventInit(eventInit)) return event # EventTarget proc newEventTarget(): EventTarget {.jsctor.} = return EventTarget() proc defaultPassiveValue(ctype: CAtom; eventTarget: EventTarget): bool = const check = [satTouchstart, satTouchmove, satWheel, satMousewheel] return ctype.toStaticAtom() in check and eventTarget.isDefaultPassiveImpl() proc findEventListener(ctx: JSContext; eventTarget: EventTarget; ctype: CAtom; callback: JSValueConst; capture: bool): EventListener = for it in eventTarget.eventListeners: if not it.internal and it.ctype == ctype and ctx.strictEquals(it.callback, callback) and it.capture == capture: return it nil proc hasEventListener*(eventTarget: EventTarget; ctype: CAtom): bool = for it in eventTarget.eventListeners: if it.ctype == ctype: return true false # EventListener proc invoke(ctx: JSContext; listener: EventListener; event: Event): JSValue = if JS_IsNull(listener.callback): return JS_UNDEFINED let jsTarget = ctx.toJS(event.currentTarget) if JS_IsException(jsTarget): return JS_EXCEPTION let jsEvent = ctx.toJS(event) if JS_IsException(jsEvent): JS_FreeValue(ctx, jsTarget) return JS_EXCEPTION var ret = JS_UNINITIALIZED if JS_IsFunction(ctx, listener.callback): # Apparently it's a bad idea to call a function that can then delete # the reference it was called from (hence the dup). let callback = JS_DupValue(ctx, listener.callback) ret = ctx.callFree(callback, jsTarget, jsEvent) else: assert JS_IsObject(listener.callback) ret = JS_GetPropertyStr(ctx, listener.callback, "handleEvent") if not JS_IsException(ret): ret = ctx.callFree(ret, jsTarget, jsEvent) JS_FreeValue(ctx, jsTarget) JS_FreeValue(ctx, jsEvent) return ret proc removeEventListenerData(ctx: JSContext; _: JSValueConst; argc: cint; argv: JSValueConstArray; margic: cint; funcData: JSValueConstArray): JSValue {.cdecl.} = var this: EventTarget ?ctx.fromJS(funcData[0], this) var ctype: CAtom ?ctx.fromJS(funcData[1], ctype) if ctx.removeEventListener(this, ctype, funcData[2], funcData[3]).isErr: return JS_EXCEPTION return JS_UNDEFINED # shared proc addEventListener(ctx: JSContext; target: EventTarget; ctype: CAtom; capture, once, internal: bool; passive: Option[bool]; callback: JSValueConst; signal: AbortSignal): Opt[void] = if signal != nil and signal.aborted or JS_IsUndefined(callback): return ok() let passive = passive.get(defaultPassiveValue(ctype, target)) if ctx.findEventListener(target, ctype, callback, capture) == nil: # dedup let listener = EventListener( ctype: ctype, capture: capture, once: once, internal: internal, passive: passive, callback: JS_DupValue(ctx, callback), next: target.eventListener, signal: signal ) target.eventListener = listener if signal != nil: let jsTarget = ctx.toJS(target) if JS_IsException(jsTarget): return err() let jsType = ctx.toJS(ctype) if JS_IsException(jsType): JS_FreeValue(ctx, jsTarget) return err() let jsCapture = ctx.toJS(capture) let data = [jsTarget, jsType, JS_DupValue(ctx, callback), jsCapture] let fun = JS_NewCFunctionData(ctx, removeEventListenerData, 0, 0, 4, data.toJSValueArray()) ctx.freeValues(data) if JS_IsException(fun): return err() signal.abortSteps.add(fun) ok() proc flatten(ctx: JSContext; options: JSValueConst): Opt[bool] = var res = false if JS_IsBool(options): ?ctx.fromJS(options, res) elif JS_IsObject(options): discard ?ctx.fromJSGetProp(options, "capture", res) ok(res) type FlattenMoreResult = object capture: bool once: bool passive: Option[bool] signal: AbortSignal proc flattenMore(ctx: JSContext; options: JSValueConst; res: var FlattenMoreResult): Opt[void] = let capture = ?ctx.flatten(options) var once = false var passive = none(bool) var signal: AbortSignal = nil if JS_IsObject(options): discard ?ctx.fromJSGetProp(options, "once", once) var res: bool if ?ctx.fromJSGetProp(options, "passive", res): passive = some(res) discard ?ctx.fromJSGetProp(options, "signal", signal) res = FlattenMoreResult( capture: capture, once: once, passive: passive, signal: signal ) ok() proc removeInternalEventListener(ctx: JSContext; eventTarget: EventTarget; ctype: StaticAtom) = var prev: EventListener = nil for it in eventTarget.eventListeners: if it.ctype == ctype and it.internal: let callback = it.callback it.callback = JS_UNDEFINED JS_FreeValue(ctx, callback) if prev == nil: eventTarget.eventListener = it.next else: prev.next = it.next break prev = it proc addInternalEventListener(ctx: JSContext; eventTarget: EventTarget; ctype: StaticAtom; callback: JSValueConst): Opt[void] = ctx.removeInternalEventListener(eventTarget, ctype) ctx.addEventListener(eventTarget, ctype.toAtom(), capture = false, once = false, internal = true, passive = none(bool), callback, signal = nil) # Event reflection const EventReflectMap = [ cint(0): satLoadstart, satProgress, satAbort, satError, satLoad, satTimeout, satLoadend, satReadystatechange, satFocus, satBlur ] proc eventReflectGet*(ctx: JSContext; this: JSValueConst; magic: cint): JSValue {.cdecl.} = return JS_NULL proc eventReflectSet0*(ctx: JSContext; target: EventTarget; val: JSValueConst; magic: cint; fun2: JSSetterMagicFunction; atom: StaticAtom; target2 = none(EventTarget)): JSValue = if JS_IsFunction(ctx, val) or JS_IsNull(val): let jsTarget = ctx.toJS(target) if JS_IsException(jsTarget): return JS_EXCEPTION let jsTarget2 = ctx.toJS(target2) if JS_IsException(jsTarget2): JS_FreeValue(ctx, jsTarget) return JS_EXCEPTION let name = "on" & $atom let getter = ctx.identityFunction(val) if JS_IsException(getter): ctx.freeValues(jsTarget, jsTarget2) return JS_EXCEPTION let f = JSCFunctionType(setter_magic: fun2) let setter = JS_NewCFunction2(ctx, f.generic, cstring(name), 1, JS_CFUNC_setter_magic, magic) if JS_IsException(getter): ctx.freeValues(jsTarget, jsTarget2, getter) return JS_EXCEPTION let ja = JS_NewAtom(ctx, cstring(name)) if ja == JS_ATOM_NULL: ctx.freeValues(jsTarget, jsTarget2, getter, setter) return JS_EXCEPTION var ret = JS_DefineProperty(ctx, jsTarget, ja, JS_UNDEFINED, getter, setter, JS_PROP_HAS_GET or JS_PROP_HAS_SET or JS_PROP_HAS_CONFIGURABLE or JS_PROP_CONFIGURABLE) if ret != -1 and target2.isSome: # target2 is set to document.body in case of properties like # onload, which set functions both on document.body and window, # but only set an event listener on window. ret = JS_DefineProperty(ctx, jsTarget2, ja, JS_UNDEFINED, getter, setter, JS_PROP_HAS_GET or JS_PROP_HAS_SET or JS_PROP_HAS_CONFIGURABLE or JS_PROP_CONFIGURABLE) JS_FreeAtom(ctx, ja) ctx.freeValues(getter, setter, jsTarget, jsTarget2) if ret == -1: return JS_EXCEPTION if JS_IsNull(val): ctx.removeInternalEventListener(target, atom) elif ctx.addInternalEventListener(target, atom, val).isErr: return JS_EXCEPTION return JS_DupValue(ctx, val) proc eventReflectSet*(ctx: JSContext; this, val: JSValueConst; magic: cint): JSValue {.cdecl.} = var target: EventTarget ?ctx.fromJS(this, target) return ctx.eventReflectSet0(target, val, magic, eventReflectSet, EventReflectMap[magic]) proc addEventListener(ctx: JSContext; eventTarget: EventTarget; ctype: CAtom; callback: JSValueConst; options: JSValueConst = JS_UNDEFINED): Opt[void] {.jsfunc.} = if not JS_IsObject(callback) and not JS_IsNull(callback): JS_ThrowTypeError(ctx, "callback is not an object") return err() var res: FlattenMoreResult ?ctx.flattenMore(options, res) ctx.addEventListener(eventTarget, ctype, res.capture, res.once, internal = false, res.passive, callback, res.signal) proc removeEventListener(ctx: JSContext; eventTarget: EventTarget; ctype: CAtom; callback: JSValueConst; options: JSValueConst = JS_UNDEFINED): Opt[void] {.jsfunc.} = let capture = ?ctx.flatten(options) var prev: EventListener = nil for it in eventTarget.eventListeners: if not it.internal and it.ctype == ctype and ctx.strictEquals(it.callback, callback) and it.capture == capture: let callback = it.callback it.callback = JS_UNDEFINED JS_FreeValue(ctx, callback) if prev == nil: eventTarget.eventListener = it.next else: prev.next = it.next break prev = it ok() type DispatchItem = object target: EventTarget els: seq[EventListener] DispatchContext = object event: Event ctx: JSContext stop: bool canceled: bool capture: seq[DispatchItem] bubble: seq[DispatchItem] proc collectItems(dctx: var DispatchContext; target: EventTarget) = let ctype = dctx.event.ctype let bubbles = dctx.event.bubbles let isLoad = dctx.event.ctype == satLoad.toAtom() var it = target while it != nil: var capture: seq[EventListener] = @[] var bubble: seq[EventListener] = @[] for el in it.eventListeners: if el.ctype == ctype: if el.capture: capture.add(el) elif bubbles or it == target: bubble.add(el) if capture.len > 0: dctx.capture.add(DispatchItem(target: it, els: move(capture))) if bubble.len > 0: dctx.bubble.add(DispatchItem(target: it, els: move(bubble))) it = dctx.ctx.getParentImpl(it, isLoad) proc dispatchEvent0(dctx: var DispatchContext; item: DispatchItem) = let ctx = dctx.ctx let event = dctx.event event.currentTarget = item.target for el in item.els.ritems: if JS_IsUndefined(el.callback): continue # removed, presumably by a previous handler if el.passive: event.flags.incl(efInPassiveListener) let e = ctx.invoke(el, event) if JS_IsException(e): ctx.logException() JS_FreeValue(ctx, e) if el.passive: event.flags.excl(efInPassiveListener) if efCanceled in event.flags: dctx.canceled = true if {efStopPropagation, efStopImmediatePropagation} * event.flags != {}: dctx.stop = true if efStopImmediatePropagation in event.flags: break proc dispatch*(ctx: JSContext; target: EventTarget; event: Event; targetOverride = false): bool = let prev = ctx.setEventImpl(event) var dctx = DispatchContext(ctx: ctx, event: event) event.flags.incl(efDispatch) if not targetOverride: event.target = target dctx.collectItems(target) event.eventPhase = 1 for item in dctx.capture.ritems: if dctx.stop: break if item.target == target: event.eventPhase = 2 dctx.dispatchEvent0(item) event.eventPhase = 2 for item in dctx.bubble: if dctx.stop: break if item.target != target: event.eventPhase = 3 dctx.dispatchEvent0(item) event.eventPhase = 0 event.flags.excl(efDispatch) discard ctx.setEventImpl(prev) return dctx.canceled proc dispatchEvent(ctx: JSContext; this: EventTarget; event: Event): JSValue {.jsfunc.} = if efDispatch in event.flags: return JS_ThrowDOMException(ctx, "InvalidStateError", "event's dispatch flag is already set") if efInitialized notin event.flags: return JS_ThrowDOMException(ctx, "InvalidStateError", "event is not initialized") event.isTrusted = false if ctx.dispatch(this, event): return JS_FALSE return JS_TRUE # AbortSignal proc finalize(rt: JSRuntime; this: AbortSignal) {.jsfin.} = JS_FreeValueRT(rt, this.reason) rt.freeValues(this.abortSteps) proc mark(rt: JSRuntime; this: AbortSignal; markFun: JS_MarkFunc) {.jsmark.} = JS_MarkValue(rt, this.reason, markFun) for it in this.abortSteps: JS_MarkValue(rt, it, markFun) proc toSignalReason(ctx: JSContext; reason: JSValueConst): JSValue = if not JS_IsUndefined(reason): return JS_DupValue(ctx, reason) JS_ThrowDOMException(ctx, "AbortError", "aborted (core not dumped)") return JS_GetException(ctx) proc abortSignalAbort(ctx: JSContext; reason: JSValueConst = JS_UNDEFINED): AbortSignal {.jsstfunc: "AbortSignal#abort".} = AbortSignal(reason: ctx.toSignalReason(reason)) proc throwIfAborted(ctx: JSContext; signal: AbortSignal): JSValue {.jsfunc.} = if signal.aborted: return JS_Throw(ctx, JS_DupValue(ctx, signal.reason)) return JS_UNDEFINED #TODO _any # AbortController proc newAbortController(ctx: JSContext): AbortController {.jsctor.} = let signal = AbortSignal(reason: JS_UNDEFINED) AbortController(signal: signal) proc abort(ctx: JSContext; this: AbortController; reason: JSValueConst): JSValue {.jsfunc.} = let signal = this.signal if not signal.aborted: signal.reason = ctx.toSignalReason(reason) #TODO dependent signals for step in signal.abortSteps: let res = ctx.call(step, JS_UNDEFINED) if JS_IsException(res): return res JS_FreeValue(ctx, res) let event = newEvent(satAbort.toAtom(), signal, bubbles = false, cancelable = false) event.isTrusted = true discard ctx.dispatch(signal, event) return JS_UNDEFINED # atoms must be sorted in the order of EventReflectMap proc addEventGetSet*(ctx: JSContext; obj: JSValueConst; atoms: openArray[StaticAtom]): Opt[void] = var i = cint(0) for atom in atoms: while EventReflectMap[i] != atom: inc i let name = "on" & $atom ?ctx.addReflectFunction(obj, name, eventReflectGet, eventReflectSet, i) ok() proc addEventGetSet*(ctx: JSContext; classid: JSClassID; atoms: openArray[StaticAtom]): Opt[void] = let proto = JS_GetClassProto(ctx, classid) let res = ctx.addEventGetSet(proto, atoms) JS_FreeValue(ctx, proto) res proc addEventModule*(ctx: JSContext): Opt[tuple[eventCID, eventTargetCID: JSClassID]] = let eventCID = ctx.registerType(Event) if eventCID == 0: return err() ?ctx.registerType(CustomEvent, parent = eventCID) ?ctx.registerType(MessageEvent, parent = eventCID) ?ctx.registerType(SubmitEvent, parent = eventCID) let uiEventCID = ctx.registerType(UIEvent, parent = eventCID) if uiEventCID == 0: return err() ?ctx.registerType(MouseEvent, parent = uiEventCID) ?ctx.registerType(InputEvent, parent = uiEventCID) if ctx.defineConsts(eventCID, EventPhase) == dprException: return err() let eventTargetCID = ctx.registerType(EventTarget) if eventTargetCID == 0: return err() let abortSignalCID = ctx.registerType(AbortSignal, parent = eventTargetCID) if abortSignalCID == 0: return err() ?ctx.addEventGetSet(abortSignalCID, [satAbort]) ?ctx.registerType(AbortController) ok((eventCID, eventTargetCID)) {.pop.} # raises: [] �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/html/formdata.nim�����������������������������������������������������������������0000664�0000000�0000000�00000014327�15202323131�0017176�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import chame/tags import html/catom import html/dom import html/domexception import io/dynstream import monoucha/fromjs import monoucha/jsbind import monoucha/quickjs import monoucha/tojs import types/blob import types/formdata import types/jsopt import types/opt import utils/twtstr proc constructEntryList*(form: HTMLFormElement; submitter: Element = nil; encoding = "UTF-8"): seq[FormDataEntry] proc generateBoundary(urandom: PosixStream): string = var s {.noinit.}: array[33, uint8] if urandom.readLoop(s).isErr: return "" # 33 * 4 / 3 = 44 + prefix string is 22 bytes = 66 bytes return "----WebKitFormBoundary" & btoa(s) proc newFormData0*(urandom: PosixStream): FormData = var boundary = urandom.generateBoundary() if boundary.len == 0: return nil return FormData(boundary: move(boundary)) proc newFormData(ctx: JSContext; argv: varargs[JSValueConst]): Opt[FormData] {.jsctor.} = let urandom = ctx.getGlobal().crypto.urandom let this = newFormData0(urandom) if this != nil and argv.len > 0: var form: HTMLFormElement var submitter: HTMLElement = nil ?ctx.fromJS(argv[0], form) if argv.len > 1: ?ctx.fromJS(argv[1], submitter) if not submitter.isSubmitButton(): JS_ThrowDOMException(ctx, "InvalidStateError", "submitter must be a submit button") return err() if FormAssociatedElement(submitter).form != form: JS_ThrowDOMException(ctx, "InvalidStateError", "submitter's form owner is not form") return err() if not form.constructingEntryList: this.entries = constructEntryList(form, submitter) ok(this) proc append*(ctx: JSContext; this: FormData; name: string; val: JSValueConst; rest: varargs[JSValueConst]): Opt[void] {.jsfunc.} = var blob: Blob if ctx.fromJS(val, blob).isOk: var filename = "blob" if rest.len > 0: ?ctx.fromJS(rest[0], filename) elif blob of WebFile: filename = WebFile(blob).name this.entries.add(FormDataEntry( name: name, isstr: false, value: blob, filename: filename )) ok() elif rest.len > 0: err() else: var s: string ?ctx.fromJS(val, s) this.entries.add(FormDataEntry(name: name, isstr: true, svalue: s)) ok() proc delete(this: FormData; name: string) {.jsfunc.} = for i in countdown(this.entries.high, 0): if this.entries[i].name == name: this.entries.delete(i) proc get(ctx: JSContext; this: FormData; name: string): JSValue {.jsfunc.} = for entry in this.entries: if entry.name == name: if entry.isstr: return ctx.toJS(entry.svalue) else: return ctx.toJS(entry.value) return JS_NULL proc getAll(ctx: JSContext; this: FormData; name: string): seq[JSValue] {.jsfunc.} = result = newSeq[JSValue]() for entry in this.entries: if entry.name == name: if entry.isstr: result.add(ctx.toJS(entry.svalue)) else: result.add(ctx.toJS(entry.value)) proc add(list: var seq[FormDataEntry], entry: tuple[name, value: string]) = list.add(FormDataEntry( name: entry.name, isstr: true, svalue: entry.value )) proc toNameValuePairs*(list: seq[FormDataEntry]): seq[tuple[name, value: string]] = result = @[] for entry in list: if entry.isstr: result.add((entry.name, entry.svalue)) else: result.add((entry.name, entry.name)) const AutoDirInput = { itHidden, itText, itSearch, itTel, itURL, itEmail, itPassword, itSubmit, itReset, itButton } # https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#constructing-the-form-data-set # Warning: we skip the first "constructing entry list" check; the caller must # do it. proc constructEntryList*(form: HTMLFormElement; submitter: Element = nil; encoding = "UTF-8"): seq[FormDataEntry] = assert not form.constructingEntryList form.constructingEntryList = true var entrylist: seq[FormDataEntry] = @[] for field in form.controls: if field.findAncestor(TAG_DATALIST) != nil or field.attrb(satDisabled) or field.isButton() and Element(field) != submitter: continue if field of HTMLInputElement: let field = HTMLInputElement(field) if field.inputType in {itCheckbox, itRadio} and not field.checked: continue if field.inputType == itImage: var name = field.attr(satName) if name != "": name &= '.' entrylist.add((name & 'x', $field.xcoord)) entrylist.add((name & 'y', $field.ycoord)) continue #TODO custom elements let name = field.attr(satName) if name == "": continue if field of HTMLSelectElement: let field = HTMLSelectElement(field) for option in field.options: if option.selected and not option.isDisabled: entrylist.add((name, option.value)) elif field of HTMLInputElement: let field = HTMLInputElement(field) case field.inputType of itCheckbox, itRadio: let v = field.attr(satValue) let value = if v != "": v else: "on" entrylist.add((name, value)) of itFile: for file in field.files: entrylist.add(FormDataEntry( name: name, filename: file.name, isstr: false, value: file )) of itHidden: if name.equalsIgnoreCase("_charset_"): entrylist.add((name, encoding)) else: entrylist.add((name, field.value)) else: entrylist.add((name, field.value)) elif field of HTMLButtonElement: entrylist.add((name, HTMLButtonElement(field).attr(satValue))) elif field of HTMLTextAreaElement: entrylist.add((name, HTMLTextAreaElement(field).value)) else: assert false, "Tag type " & $field.tagType & " not accounted for in constructEntryList" if field of HTMLTextAreaElement or field of HTMLInputElement and HTMLInputElement(field).inputType in AutoDirInput: let dirname = field.attr(satDirname) if dirname != "": let dir = "ltr" #TODO bidi entrylist.add((dirname, dir)) form.constructingEntryList = false move(entrylist) proc addFormDataModule*(ctx: JSContext): Opt[void] = ?ctx.registerType(FormData) ok() {.pop.} # raises: [] ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/html/jsencoding.nim���������������������������������������������������������������0000664�0000000�0000000�00000006030�15202323131�0017514�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import encoding/charset import encoding/decoder import monoucha/fromjs import monoucha/jsbind import monoucha/jstypes import monoucha/quickjs import monoucha/tojs import types/jsopt import types/opt type JSTextEncoder = ref object JSTextDecoder = ref object encoding {.jsget.}: Charset ignoreBOM {.jsget.}: bool errorMode: DecoderErrorMode stream: bool bomSeen: bool tdctx: TextDecoderContext jsDestructor(JSTextDecoder) jsDestructor(JSTextEncoder) type TextDecoderOptions = object of JSDict fatal {.jsdefault.}: bool ignoreBOM {.jsdefault.}: bool proc newJSTextDecoder(ctx: JSContext; label = "utf-8"; options = TextDecoderOptions()): Opt[JSTextDecoder] {.jsctor.} = let encoding = getCharset(label) if encoding in {csUnknown, csReplacement}: JS_ThrowRangeError(ctx, "invalid encoding label") return err() let errorMode = if options.fatal: demFatal else: demReplacement return ok(JSTextDecoder( ignoreBOM: options.ignoreBOM, errorMode: errorMode, tdctx: initTextDecoderContext(encoding, errorMode), encoding: encoding )) proc fatal(this: JSTextDecoder): bool {.jsfget.} = return this.errorMode == demFatal type TextDecodeOptions = object of JSDict stream {.jsdefault.}: bool #TODO AllowSharedBufferSource proc decode(ctx: JSContext; this: JSTextDecoder; jsInput: JSValueConst = JS_UNDEFINED; options = TextDecodeOptions()): JSValue {.jsfunc.} = var input: JSArrayBufferView if not JS_IsUndefined(jsInput): ?ctx.fromJS(jsInput, input) if not this.stream: this.tdctx = initTextDecoderContext(this.encoding, this.errorMode) this.bomSeen = false this.stream = options.stream var oq = "" let stream = this.stream if not JS_IsUndefined(jsInput): for chunk in this.tdctx.decode(input.toOpenArray(), not stream): oq &= chunk else: for chunk in this.tdctx.decode([], not stream): oq &= chunk if this.tdctx.failed: this.tdctx.failed = false return JS_ThrowTypeError(ctx, "failed to decode string") return JS_NewStringLen(ctx, cstring(oq), csize_t(oq.len)) proc newTextEncoder(): JSTextEncoder {.jsctor.} = return JSTextEncoder() proc encoding(this: JSTextEncoder): string {.jsfget.} = return "utf-8" proc deallocWrap(rt: JSRuntime; opaque, p: pointer) {.cdecl.} = if p != nil: dealloc(p) proc encode(this: JSTextEncoder; input = ""): JSArrayBufferView {.jsfunc.} = # we have to validate input first :/ #TODO it is possible to do less copies here... let input = input.toValidUTF8() let p = if input.len > 0: let buf = cast[ptr UncheckedArray[uint8]](alloc(input.len)) copyMem(buf, unsafeAddr input[0], input.len) buf else: nil JSArrayBufferView( t: JS_TYPED_ARRAY_UINT8, abuf: JSArrayBuffer(p: p, len: csize_t(input.len), dealloc: deallocWrap), offset: 0, len: input.len ) #TODO encodeInto proc addEncodingModule*(ctx: JSContext): Opt[void] = ?ctx.registerType(JSTextDecoder, name = "TextDecoder") ?ctx.registerType(JSTextEncoder, name = "TextEncoder") ok() {.pop.} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/html/jsintl.nim�������������������������������������������������������������������0000664�0000000�0000000�00000015711�15202323131�0016702�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import monoucha/fromjs import monoucha/jsbind import monoucha/jstypes import monoucha/jsutils import monoucha/quickjs import monoucha/tojs import types/jsopt import types/opt import utils/twtstr type NumberStyle = enum nsDecimal = "decimal" nsPercent = "percent" nsCurrency = "currency" nsUnit = "unit" NumberUnitPart = enum nupAcre = "acre" nupBit = "bit" nupByte = "byte" nupCelsius = "celsius" nupCentimeter = "centimeter" nupDay = "day" nupDegree = "degree" nupFahrenheit = "fahrenheit" nupFluidOunce = "fluid-ounce" nupFoot = "foot" nupGallon = "gallon" nupGigabit = "gigabit" nupGigabyte = "gigabyte" nupGram = "gram" nupHectare = "hectare" nupHour = "hour" nupInch = "inch" nupKilobit = "kilobit" nupKilobyte = "kilobyte" nupKilogram = "kilogram" nupKilometer = "kilometer" nupLiter = "liter" nupMegabit = "megabit" nupMegabyte = "megabyte" nupMeter = "meter" nupMicrosecond = "microsecond" nupMile = "mile" nupMileScandinavian = "mile-scandinavian" nupMilliliter = "milliliter" nupMillimeter = "millimeter" nupMillisecond = "millisecond" nupMinute = "minute" nupMonth = "month" nupNanosecond = "nanosecond" nupOunce = "ounce" nupPercent = "percent" nupPetabyte = "petabyte" nupPound = "pound" nupSecond = "second" nupStone = "stone" nupTerabit = "terabit" nupTerabyte = "terabyte" nupWeek = "week" nupYard = "yard" nupYear = "year" NumberUnit = object part1: NumberUnitPart part2: Opt[NumberUnitPart] NumberFormat = ref object maximumFractionDigits: int32 style: NumberStyle unit: NumberUnit PluralRules = ref object PRResolvedOptions = object of JSDict locale: string DateTimeFormat = ref object RelativeTimeFormat = ref object jsDestructor(NumberFormat) jsDestructor(DateTimeFormat) jsDestructor(PluralRules) jsDestructor(RelativeTimeFormat) # NumberFormat proc fromJS(ctx: JSContext; val: JSValueConst; unit: var NumberUnit): FromJSResult = var s: string ?ctx.fromJS(val, s) let i = s.find("-per-") if i != -1: let part1 = strictParseEnum[NumberUnitPart](s.substr(0, i - 1)) let part2 = strictParseEnum[NumberUnitPart](s.substr(i + "-per-".len)) if part1.isErr or part2.isErr: JS_ThrowRangeError(ctx, "wrong unit %s", cstring(s)) return fjErr unit = NumberUnit(part1: part1.get, part2: part2) else: let part1 = parseEnumNoCase[NumberUnitPart](s) if part1.isErr: JS_ThrowRangeError(ctx, "wrong unit %s", cstring(s)) return fjErr unit = NumberUnit(part1: part1.get) fjOk proc newNumberFormat(ctx: JSContext; name = "en-US"; options: JSValueConst = JS_UNDEFINED): Opt[NumberFormat] {.jsfctor.} = let nf = NumberFormat() if JS_IsObject(options): discard ?ctx.fromJSGetProp(options, "maximumFractionDigits", nf.maximumFractionDigits) if nf.maximumFractionDigits notin 0..100: let s = $nf.maximumFractionDigits JS_ThrowRangeError(ctx, "invalid digits value: %s", cstring(s)) return err() discard ?ctx.fromJSGetProp(options, "style", nf.style) if not ?ctx.fromJSGetProp(options, "unit", nf.unit) and nf.style == nsUnit: JS_ThrowTypeError(ctx, "undefined unit in NumberFormat() with unit style") return err() ok(nf) const UnitTable = [ nupAcre: cstring"ac", nupBit: nil, nupByte: nil, nupCelsius: cstring"°C", nupCentimeter: cstring"cm", nupDay: nil, nupDegree: cstring"deg", nupFahrenheit: cstring"°F", nupFluidOunce: cstring"fl oz", nupFoot: cstring"ft", nupGallon: cstring"gal", nupGigabit: cstring"Gb", nupGigabyte: cstring"GB", nupGram: cstring"g", nupHectare: cstring"ha", nupHour: cstring"hr", nupInch: cstring"in", nupKilobit: cstring"kb", nupKilobyte: cstring"kB", nupKilogram: cstring"kg", nupKilometer: cstring"km", nupLiter: cstring"L", nupMegabit: cstring"Mb", nupMegabyte: cstring"MB", nupMeter: cstring"m", nupMicrosecond: cstring"μs", nupMile: cstring"mi", nupMileScandinavian: cstring"smi", nupMilliliter: cstring"mL", nupMillimeter: cstring"mm", nupMillisecond: cstring"ms", nupMinute: cstring"min", nupMonth: cstring"mth", nupNanosecond: cstring"ns", nupOunce: cstring"oz", nupPercent: cstring"%", nupPetabyte: cstring"PB", nupPound: cstring"lb", nupSecond: cstring"sec", nupStone: cstring"st", nupTerabit: cstring"Tb", nupTerabyte: cstring"TB", nupWeek: cstring"wk", nupYard: cstring"yd", nupYear: cstring"yr" ] proc stringify(part: NumberUnitPart; s: string; part2 = false): string = let s = UnitTable[part] if s == nil: result = $part else: result = $s if part in {nupDay, nupMonth, nupWeek, nupYear} and s != "1": result &= 's' # plural if part2 and part in {nupSecond, nupDay, nupMonth, nupYear}: result.setLen(1) proc stringifyUnit(unit: NumberUnit; s: string): string = result = "" if unit.part1 notin {nupCelsius, nupFahrenheit, nupPercent}: result &= ' ' result &= unit.part1.stringify(s) if unit.part1 != nupPercent and unit.part2.isOk: result &= '/' result &= unit.part2.get.stringify(s, part2 = true) proc format(nf: NumberFormat; s: string): string {.jsfunc.} = result = "" var i = 0 var L = s.rfind('.') if L == -1: L = s.len if L mod 3 != 0: while i < L mod 3: result &= s[i] inc i if i < L: result &= ',' let j = i while i < L: if j != i and i mod 3 == j: result &= ',' result &= s[i] inc i if i + 1 < s.len and s[i] == '.' and (s[i + 1] != '0' or s.len != i + 2): if nf.maximumFractionDigits > 0: result &= '.' inc i var k = 0 while i < s.len and k < nf.maximumFractionDigits: result &= s[i] inc k inc i case nf.style of nsDecimal: discard of nsUnit: result &= nf.unit.stringifyUnit(s) of nsPercent: result &= '%' of nsCurrency: discard #TODO? # DateTimeFormat proc newDateTimeFormat(): Opt[DateTimeFormat] {.jsfctor.} = return ok(DateTimeFormat()) # PluralRules proc newPluralRules(): PluralRules {.jsctor.} = return PluralRules() proc resolvedOptions(this: PluralRules): PRResolvedOptions {.jsfunc.} = return PRResolvedOptions(locale: "en-US") proc select(this: PluralRules; num: float64): string {.jsfunc.} = if num == 1: return "one" return "many" # RelativeTimeFormat proc newRelativeTimeFormat(): RelativeTimeFormat {.jsctor.} = return RelativeTimeFormat() proc addIntlModule*(ctx: JSContext): Opt[void] = let global = JS_GetGlobalObject(ctx) let intl = JS_NewObject(ctx) if JS_IsException(intl): return err() ?ctx.registerType(NumberFormat, namespace = intl) ?ctx.registerType(DateTimeFormat, namespace = intl) ?ctx.registerType(PluralRules, namespace = intl) ?ctx.registerType(RelativeTimeFormat, namespace = intl) case ctx.defineProperty(global, "Intl", intl) of dprException: return err() else: discard JS_FreeValue(ctx, global) ok() {.pop.} �������������������������������������������������������chawan-v0.4.0/src/html/performance.nim��������������������������������������������������������������0000664�0000000�0000000�00000005673�15202323131�0017706�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import std/math import std/times import config/conftypes import html/event import io/timeout import monoucha/fromjs import monoucha/jsbind import monoucha/quickjs import monoucha/tojs import types/jsopt import types/opt type Performance* = ref object of EventTarget timeOrigin {.jsget.}: float64 scripting: ScriptingMode id: uint64 PerformanceEntry = ref object of RootObj id {.jsget.}: uint64 name {.jsget.}: string startTime {.jsget.}: float64 duration {.jsget.}: float64 navigationId {.jsget.}: uint64 PerformanceMark = ref object of PerformanceEntry detail {.jsget.}: JSValue jsDestructor(Performance) jsDestructor(PerformanceEntry) jsDestructor(PerformanceMark) proc finalize(rt: JSRuntime; this: PerformanceMark) {.jsfin.} = JS_FreeValueRT(rt, this.detail) proc mark(rt: JSRuntime; this: PerformanceMark; markFun: JS_MarkFunc) {.jsmark.} = JS_MarkValue(rt, this.detail, markFun) proc getTime(scripting: ScriptingMode): float64 = let t = getTime() if scripting == smApp: return float64(t.toUnix() * 1000) + floor(t.nanosecond / 100_000) / 10 return float64(getUnixMillis()) proc newPerformance*(scripting: ScriptingMode): Performance = return Performance(timeOrigin: getTime(scripting), scripting: scripting) proc now(performance: Performance): float64 {.jsfunc.} = return getTime(performance.scripting) - performance.timeOrigin proc getEntries(ctx: JSContext; performance: Performance): JSValue {.jsfunc.} = return JS_NewArray(ctx) proc getEntriesByType(ctx: JSContext; performance: Performance; t: string): JSValue {.jsfunc.} = return JS_NewArray(ctx) proc getEntriesByName(ctx: JSContext; performance: Performance; name: string; t: JSValueConst = JS_UNDEFINED): JSValue {.jsfunc.} = return JS_NewArray(ctx) proc getEntryId(this: Performance): uint64 = result = this.id inc this.id # PerformanceEntry proc entryType(this: PerformanceEntry): string {.jsfget.} = if this of PerformanceMark: return "mark" return "" # PerformanceMark #TODO constructor proc mark(ctx: JSContext; this: Performance; name: string; init: JSValueConst = JS_UNDEFINED): Opt[PerformanceMark] {.jsfunc.} = var startTime: float64 if ?ctx.fromJSGetProp(init, "startTime", startTime): if startTime < 0: JS_ThrowTypeError(ctx, "startTime must not be negative") return err() else: startTime = this.now() var detail: JSValue if not ?ctx.fromJSGetProp(init, "detail", detail): detail = JS_NULL #TODO serialize/deserialize detail let mark = PerformanceMark( id: this.getEntryId(), name: name, startTime: startTime, detail: detail ) ok(mark) proc addPerformanceModule*(ctx: JSContext; eventTargetCID: JSClassID): Opt[void] = ?ctx.registerType(Performance, parent = eventTargetCID) let performanceEntryCID = ctx.registerType(PerformanceEntry) if performanceEntryCID == 0: return err() ?ctx.registerType(PerformanceMark, performanceEntryCID) ok() ���������������������������������������������������������������������chawan-v0.4.0/src/html/script.nim�������������������������������������������������������������������0000664�0000000�0000000�00000015664�15202323131�0016712�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import config/conftypes import html/catom import monoucha/jsutils import monoucha/quickjs import types/opt import types/referrer import types/url import types/winattrs import utils/twtstr type ParserMetadata* = enum pmParserInserted, pmNotParserInserted ScriptType* = enum stClassic, stModule, stImportMap ScriptResultType* = enum srtNull, srtScript, srtImportMapParse, srtFetching RequestDestination* = enum rdNone = "" rdAudio = "audio" rdAudioworklet = "audioworklet" rdDocument = "document" rdEmbed = "embed" rdFont = "font" rdFrame = "frame" rdIframe = "iframe" rdImage = "image" rdJson = "json" rdManifest = "manifest" rdObject = "object" rdPaintworklet = "paintworklet" rdReport = "report" rdScript = "script" rdServiceworker = "serviceworker" rdSharedworker = "sharedworker" rdStyle = "style" rdTrack = "track" rdWorker = "worker" rdXslt = "xslt" CredentialsMode* = enum cmSameOrigin = "same-origin" cmOmit = "omit" cmInclude = "include" type EnvironmentSettings* = ref object attrsp*: ptr WindowAttributes # In app mode, attrsp == scriptAttrsp. # In lite mode, scriptAttrsp == addr dummyAttrs. scriptAttrsp*: ptr WindowAttributes moduleMap*: ModuleMap origin*: Origin scripting*: ScriptingMode headless*: HeadlessMode images*: bool styling*: bool autofocus*: bool contentType*: CAtom Script* = ref object #TODO setings baseURL*: URL options*: ScriptOptions mutedErrors*: bool #TODO parse error/error to rethrow rt*: JSRuntime record*: JSValue ScriptOptions* = object nonce*: string integrity*: string parserMetadata*: ParserMetadata credentialsMode*: CredentialsMode referrerPolicy*: Opt[ReferrerPolicy] renderBlocking*: bool ScriptResult* = ref object case t*: ScriptResultType of srtNull, srtFetching: discard of srtScript: script*: Script of srtImportMapParse: discard #TODO ModuleType* = enum mtJavascript = "javascript" mtJson = "json" mtCss = "css" ModuleMapEntry = object key: tuple[url: string; moduleType: ModuleType] value*: ScriptResult ModuleMap* = seq[ModuleMapEntry] # Forward declaration hack # set in html/dom var errorImpl*: proc(ctx: JSContext; ss: varargs[string]) {. nimcall, raises: [].} var getEnvSettingsImpl*: proc(ctx: JSContext): EnvironmentSettings {. nimcall, raises: [].} proc free*(script: Script) = let record = script.record let rt = script.rt assert rt != nil script.record = JS_UNINITIALIZED script.rt = nil JS_FreeValueRT(rt, record) proc clear*(moduleMap: var ModuleMap; rt: JSRuntime) = for it in moduleMap.mitems: if it.value.t == srtScript: it.value.script.free() moduleMap.setLen(0) proc find(moduleMap: ModuleMap; url: URL; moduleType: ModuleType): int = let surl = $url for i, entry in moduleMap.mypairs: if entry.key.moduleType == moduleType and entry.key.url == surl: return i return -1 proc clone(script: Script): Script = return Script( baseURL: script.baseURL, options: script.options, mutedErrors: script.mutedErrors, #TODO parse error/error to rethrow rt: script.rt, record: JS_DupValueRT(script.rt, script.record) ) proc clone*(value: ScriptResult): ScriptResult = case value.t of srtScript: return ScriptResult(t: srtScript, script: value.script.clone()) of srtNull, srtFetching: return value of srtImportMapParse: return ScriptResult(t: srtImportMapParse) proc get*(moduleMap: ModuleMap; url: URL; moduleType: ModuleType): ScriptResult = let i = moduleMap.find(url, moduleType) if i == -1: return nil return moduleMap[i].value.clone() proc put*(moduleMap: var ModuleMap; url: URL; moduleType: ModuleType; value: ScriptResult) = let i = moduleMap.find(url, moduleType) if i != -1: let ovalue = moduleMap[i].value if ovalue.t == srtScript: ovalue.script.free() moduleMap[i].value = value else: moduleMap.add(ModuleMapEntry(key: ($url, moduleType), value: value)) proc moduleTypeToRequestDest*(moduleType: ModuleType; default: RequestDestination): RequestDestination = if moduleType == mtJson: return rdJson if moduleType == mtCss: return rdStyle return default proc newClassicScript*(ctx: JSContext; source: string; baseURL: URL; options: ScriptOptions; mutedErrors = false): ScriptResult = let record = ctx.compileScript(source, $baseURL) return ScriptResult( t: srtScript, script: Script( rt: JS_GetRuntime(ctx), record: record, baseURL: baseURL, options: options, mutedErrors: mutedErrors ) ) proc newJSModuleScript*(ctx: JSContext; source: string; baseURL: URL; options: ScriptOptions): ScriptResult = let record = ctx.compileModule(source, $baseURL) return ScriptResult( t: srtScript, script: Script( rt: JS_GetRuntime(ctx), record: record, baseURL: baseURL, options: options ) ) proc setImportMeta*(ctx: JSContext; funcVal: JSValue; isMain: bool) = let m = cast[JSModuleDef](JS_VALUE_GET_PTR(funcVal)) let moduleNameAtom = JS_GetModuleName(ctx, m) let metaObj = JS_GetImportMeta(ctx, m) doAssert ctx.definePropertyCWE(metaObj, "url", JS_AtomToValue(ctx, moduleNameAtom)) == dprSuccess doAssert ctx.definePropertyCWE(metaObj, "main", JS_FALSE) == dprSuccess JS_FreeValue(ctx, metaObj) JS_FreeAtom(ctx, moduleNameAtom) proc finishLoadModule*(ctx: JSContext; source, name: string): JSModuleDef = let funcVal = compileModule(ctx, source, name) if JS_IsException(funcVal): return nil ctx.setImportMeta(funcVal, false) # "the module is already referenced, so we must free it" # idk how this works, so for now let's just do what qjs does result = cast[JSModuleDef](JS_VALUE_GET_PTR(funcVal)) JS_FreeValue(ctx, funcVal) proc logException*(ctx: JSContext) = ctx.errorImpl(ctx.getExceptionMsg()) proc uninitIfNull*(val: JSValue): JSValue = if JS_IsNull(val): return JS_UNINITIALIZED return val proc getEnvSettings*(ctx: JSContext): EnvironmentSettings = return ctx.getEnvSettingsImpl() proc addReflectFunction*(ctx: JSContext; proto: JSValueConst; name: string; get: JSGetterMagicFunction; set: JSSetterMagicFunction; i: cint): Opt[void] = var f: JSCFunctionType f.getter_magic = get let getter = JS_NewCFunction2(ctx, f.generic, cstring(name), 0, JS_CFUNC_getter_magic, i) f.setter_magic = set let setter = JS_NewCFunction2(ctx, f.generic, cstring(name), 1, JS_CFUNC_setter_magic, i) let atom = JS_NewAtom(ctx, cstring(name)) if JS_IsException(getter) or JS_IsException(setter) or atom == JS_ATOM_NULL: JS_FreeValue(ctx, setter) JS_FreeAtom(ctx, atom) return err() if JS_DefinePropertyGetSet(ctx, proto, atom, getter, setter, JS_PROP_ENUMERABLE or JS_PROP_CONFIGURABLE) < 0: return err() JS_FreeAtom(ctx, atom) ok() {.pop.} # raises: [] ����������������������������������������������������������������������������chawan-v0.4.0/src/html/xmlhttprequest.nim�����������������������������������������������������������0000664�0000000�0000000�00000043007�15202323131�0020507�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/algorithm import encoding/charset import encoding/decoder import html/catom import html/chadombuilder import html/dom import html/domexception import html/event import html/script import io/dynstream import monoucha/fromjs import monoucha/jsbind import monoucha/jstypes import monoucha/jsutils import monoucha/quickjs import monoucha/tojs import server/headers import server/loaderiface import server/request import types/blob import types/jsopt import types/opt import types/url import utils/twtstr type XMLHttpRequestResponseType = enum xhrtUnknown = "" xhrtArraybuffer = "arraybuffer" xhrtBlob = "blob" xhrtDocument = "document" xhrtJSON = "json" xhrtText = "text" XMLHttpRequestState = enum xhrsUnsent = (0u16, "UNSENT") xhrsOpened = (1u16, "OPENED") xhrsHeadersReceived = (2u16, "HEADERS_RECEIVED") xhrsLoading = (3u16, "LOADING") xhrsDone = (4u16, "DONE") XMLHttpRequestFlag = enum xhrfSend, xhrfUploadListener, xhrfSync, xhrfUploadComplete, xhrfTimedOut XMLHttpRequestEventTarget = ref object of EventTarget XMLHttpRequestUpload = ref object of XMLHttpRequestEventTarget XMLHttpRequest = ref object of XMLHttpRequestEventTarget readyState: XMLHttpRequestState upload {.jsget.}: XMLHttpRequestUpload flags: set[XMLHttpRequestFlag] requestMethod: HttpMethod responseType {.jsget.}: XMLHttpRequestResponseType withCredentials {.jsget.}: bool timeout {.jsget.}: uint32 requestURL: URL headers: Headers response: Response responseObject: JSValue received: string contentTypeOverride: string ProgressEvent = ref object of Event lengthComputable {.jsget.}: bool loaded {.jsget.}: int64 #TODO should be uint64 total {.jsget.}: int64 #TODO ditto ProgressEventInit = object of EventInit lengthComputable: bool loaded: int64 total: int64 jsDestructor(XMLHttpRequestEventTarget) jsDestructor(XMLHttpRequestUpload) jsDestructor(XMLHttpRequest) jsDestructor(ProgressEvent) proc newXMLHttpRequest(ctx: JSContext): XMLHttpRequest {.jsctor.} = let upload = XMLHttpRequestUpload() return XMLHttpRequest( upload: upload, headers: newHeaders(hgRequest), responseObject: JS_UNDEFINED, response: makeNetworkError() ) proc finalize(rt: JSRuntime; this: XMLHttpRequest) {.jsfin.} = JS_FreeValueRT(rt, this.responseObject) proc mark(rt: JSRuntime; this: XMLHttpRequest; markFun: JS_MarkFunc) {.jsmark.} = JS_MarkValue(rt, this.responseObject, markFun) proc newProgressEvent(ctype: CAtom; init = ProgressEventInit()): ProgressEvent {.jsctor.} = let event = ProgressEvent( ctype: ctype, lengthComputable: init.lengthComputable, loaded: init.loaded, total: init.total ) Event(event).innerEventCreationSteps(EventInit(init)) return event proc readyState(this: XMLHttpRequest): uint16 {.jsfget.} = return uint16(this.readyState) proc parseMethod(ctx: JSContext; s: string): Opt[HttpMethod] = let m = ?parseEnumNoCase[HttpMethod](s) if m in {hmGet, hmDelete, hmHead, hmOptions, hmPatch, hmPost, hmPut}: return ok(m) if m in {hmConnect, hmTrace, hmTrack}: JS_ThrowDOMException(ctx, "SecurityError", "forbidden method") else: JS_ThrowDOMException(ctx, "SyntaxError", "invalid method") err() proc fireReadyStateChangeEvent(window: Window; target: EventTarget) = window.fireEvent(satReadystatechange, target, bubbles = false, cancelable = false, trusted = true) proc open(ctx: JSContext; this: XMLHttpRequest; httpMethod, url: string; misc: varargs[JSValueConst]): Opt[void] {.jsfunc.} = let httpMethod = ?ctx.parseMethod(httpMethod) let global = ctx.getGlobal() let parsedURL = parseURL0(url, global.document.baseURL) if parsedURL == nil: JS_ThrowDOMException(ctx, "SyntaxError", "invalid URL") return err() var async = true if misc.len > 0: # standard weirdness ?ctx.fromJS(misc[0], async) if misc.len > 1 and not JS_IsNull(misc[1]) and not JS_IsUndefined(misc[1]): var username: string ?ctx.fromJS(misc[1], username) parsedURL.setUsername(username) if misc.len > 2 and not JS_IsNull(misc[2]) and not JS_IsUndefined(misc[2]): var password: string ?ctx.fromJS(misc[2], password) parsedURL.setPassword(password) if not async and ctx.getWindow() != nil and (this.timeout != 0 or this.responseType != xhrtUnknown): JS_ThrowDOMException(ctx, "InvalidAccessError", "today's horoscope: don't go outside") return err() #TODO terminate fetch controller this.flags.excl(xhrfSend) this.flags.excl(xhrfUploadListener) if async: this.flags.excl(xhrfSync) else: this.flags.incl(xhrfSync) this.requestMethod = httpMethod this.headers = newHeaders(hgRequest) this.response = makeNetworkError() this.received = "" this.requestURL = parsedURL #TODO response object, received bytes if this.readyState != xhrsOpened: this.readyState = xhrsOpened global.fireReadyStateChangeEvent(this) ok() proc checkOpened(ctx: JSContext; this: XMLHttpRequest): Opt[void] = if this.readyState != xhrsOpened: JS_ThrowDOMException(ctx, "InvalidStateError", "ready state was expected to be `opened'") return err() ok() proc checkSendFlag(ctx: JSContext; this: XMLHttpRequest): Opt[void] = if xhrfSend in this.flags: JS_ThrowDOMException(ctx, "InvalidStateError", "`send' flag is set") return err() ok() proc setRequestHeader(ctx: JSContext; this: XMLHttpRequest; name, value: string): Opt[void] {.jsfunc.} = ?ctx.checkOpened(this) ?ctx.checkSendFlag(this) if not name.isValidHeaderName() or not value.isValidHeaderValue(): JS_ThrowDOMException(ctx, "SyntaxError", "invalid header name or value") return err() if isForbiddenRequestHeader(name, value): return ok() this.headers[name] = value ok() proc setWithCredentials(ctx: JSContext; this: XMLHttpRequest; withCredentials: bool): Opt[void] {.jsfset: "withCredentials".} = if this.readyState notin {xhrsUnsent, xhrsOpened}: JS_ThrowDOMException(ctx, "InvalidStateError", "ready state was expected to be `unsent' or `opened'") return err() ?ctx.checkSendFlag(this) this.withCredentials = withCredentials ok() proc setTimeout(ctx: JSContext; this: XMLHttpRequest; value: uint32): JSValue {.jsfset: "timeout".} = if ctx.getWindow() != nil and xhrfSync in this.flags: return JS_ThrowDOMException(ctx, "InvalidAccessError", "timeout may not be set on synchronous XHR") this.timeout = value return JS_UNDEFINED proc fireProgressEvent(window: Window; target: EventTarget; name: StaticAtom; loaded, length: int64) = let event = newProgressEvent(name.toAtom(), ProgressEventInit( loaded: loaded, total: length, lengthComputable: length != 0 )) event.isTrusted = true window.fireEvent(event, target) proc errorSteps(window: Window; this: XMLHttpRequest; name: StaticAtom) = this.readyState = xhrsDone this.response = makeNetworkError() this.flags.excl(xhrfSend) if xhrfSync notin this.flags: window.fireReadyStateChangeEvent(this) if xhrfUploadComplete notin this.flags: this.flags.incl(xhrfUploadComplete) if xhrfUploadListener in this.flags: window.fireProgressEvent(this.upload, name, 0, 0) window.fireProgressEvent(this.upload, satLoadend, 0, 0) window.fireProgressEvent(this, name, 0, 0) window.fireProgressEvent(this, satLoadend, 0, 0) proc handleErrors(window: Window; this: XMLHttpRequest; ctx: JSContext): Opt[void] = if xhrfSend notin this.flags: return ok() if xhrfTimedOut in this.flags: window.errorSteps(this, satTimeout) if ctx != nil: JS_ThrowDOMException(ctx, "TimeoutError", "XHR timed out") return err() elif rfAborted in this.response.flags: window.errorSteps(this, satAbort) if ctx != nil: JS_ThrowDOMException(ctx, "AbortError", "XHR aborted") return err() elif this.response.responseType == rtError: window.errorSteps(this, satError) if ctx != nil: JS_ThrowDOMException(ctx, "NetworkError", "network error in XHR") return err() ok() type XHROpaque = ref object of RootObj this: XMLHttpRequest window: Window len: int64 #TODO should be uint64 proc onReadXHR(response: Response) = const BufferSize = 4096 let opaque = XHROpaque(response.opaque) let this = opaque.this let window = opaque.window while true: let olen = this.received.len this.received.setLen(olen + BufferSize) let n = response.stream.read(addr this.received[olen], BufferSize) if n <= 0: this.received.setLen(olen) break this.received.setLen(olen + n) if this.readyState == xhrsHeadersReceived: this.readyState = xhrsLoading window.fireReadyStateChangeEvent(this) window.fireProgressEvent(this, satProgress, int64(this.received.len), opaque.len) proc onFinishXHR(response: Response; success: bool) = let opaque = XHROpaque(response.opaque) let this = opaque.this let window = opaque.window if success: discard window.handleErrors(this, nil) if response.responseType != rtError: let recvLen = int64(this.received.len) window.fireProgressEvent(this, satProgress, recvLen, opaque.len) this.readyState = xhrsDone this.flags.excl(xhrfSend) window.fireReadyStateChangeEvent(this) window.fireProgressEvent(this, satLoad, recvLen, opaque.len) window.fireProgressEvent(this, satLoadend, recvLen, opaque.len) else: this.response = makeNetworkError() discard window.handleErrors(this, nil) proc sendAsync(opaque: RootRef; response: Response) = let env = XHROpaque(opaque) let this = env.this let window = env.window if response == nil: this.response = makeNetworkError() discard window.handleErrors(this, nil) return this.response = response this.readyState = xhrsHeadersReceived window.fireReadyStateChangeEvent(this) if this.readyState != xhrsHeadersReceived: return env.len = max(response.getContentLength(), 0) response.opaque = env response.onRead = onReadXHR response.onFinish = onFinishXHR window.loader.resume(response) #TODO timeout proc send(ctx: JSContext; this: XMLHttpRequest; body: JSValueConst = JS_NULL): Opt[void] {.jsfunc.} = ?ctx.checkOpened(this) ?ctx.checkSendFlag(this) var body = body if this.requestMethod in {hmGet, hmHead}: body = JS_NULL let credentials = if this.withCredentials: cmInclude else: cmSameOrigin #TODO unsafe request flag, client, initiator type let urlCredentials = this.requestURL.includesCredentials() let request = newRequest(this.requestURL, this.requestMethod, this.headers, credentials = credentials, urlCredentials = urlCredentials, mode = rmCors) if not JS_IsNull(body): var document: Document = nil let contentType = if ctx.fromJS(body, document).isOk: request.body = RequestBody( t: rbtString, s: document.serializeFragment(writeShadow = false) .toValidUTF8() # replace surrogates ) "text/html;charset=UTF-8" else: #TODO XML var init: BodyInit ?ctx.fromJS(body, init) init.safeExtract(request.body) if not request.headers.addIfNotFoundCheck("Content-Type", contentType): # author already set a content type if request.body.t == rbtString or document != nil: request.headers["Content-Type"].setContentTypeAttr("charset", "UTF-8") if JS_IsNull(body): this.flags.incl(xhrfUploadComplete) else: this.flags.excl(xhrfUploadComplete) this.flags.excl(xhrfTimedOut) this.flags.incl(xhrfSend) let window = ctx.getWindow() if xhrfSync notin this.flags: # async window.fireProgressEvent(this, satLoadstart, 0, 0) let opaque = XHROpaque(this: this, window: window) window.fetch(request, sendAsync, opaque) else: # sync #TODO cors requests? if window.settings.origin.isSameOrigin(request.url.origin): let response = window.loader.doRequest(request) if response.stream != nil: #TODO timeout window.loader.resume(response) this.response = response this.received = response.stream.readAll() window.loader.close(response) #TODO report timing let len = max(response.getContentLength(), 0) response.opaque = XHROpaque(this: this, window: window, len: len) response.onFinishXHR(true) return ok() let res = window.handleErrors(this, ctx) this.response = makeNetworkError() ?res ok() #TODO abort proc responseURL(this: XMLHttpRequest): string {.jsfget.} = return this.response.surl proc status(this: XMLHttpRequest): uint16 {.jsfget.} = return this.response.status proc statusText(this: XMLHttpRequest): string {.jsfget.} = return "" proc getResponseHeader(ctx: JSContext; this: XMLHttpRequest; name: string): JSValue {.jsfunc.} = let res = ctx.get(this.response.headers, name) if JS_IsException(res): return JS_NULL return res proc getAllResponseHeaders(this: XMLHttpRequest): string {.jsfunc.} = var list = newSeq[string]() for k, v in this.response.headers: list.add(k & ": " & v) list.sort(proc(a, b: string): int {.nimcall.} = # ew, but if the spec says so... let L = min(a.len, b.len) for i in 0 ..< L: let ac = a[i].toUpperAscii() let bc = b[i].toUpperAscii() if ac == ':' or bc == ':': break if uint8(ac) < uint8(bc): return -1 if uint8(ac) > uint8(bc): return 1 if a.len < b.len: return -1 if a.len > b.len: return 1 0 ) result = "" for it in list: result &= it.toLowerAscii() & "\r\n" proc getCharset(this: XMLHttpRequest): Charset = let override = this.contentTypeOverride.toLowerAscii() let cs = override.getContentTypeAttr("charset").getCharset() if cs != csUnknown: return cs return this.response.getCharset(csUtf8) proc responseText(ctx: JSContext; this: XMLHttpRequest): JSValue {.jsfget.} = if this.responseType notin {xhrtUnknown, xhrtText}: return JS_ThrowDOMException(ctx, "InvalidStateError", "Response type was expected to be '' or 'text'") if this.readyState notin {xhrsLoading, xhrsDone}: return ctx.toJS("") let charset = this.getCharset() #TODO XML encoding stuff? return ctx.toJS(this.received.decodeAll(charset)) proc overrideMimeType(ctx: JSContext; this: XMLHttpRequest; s: string): JSValue {.jsfunc.} = if this.readyState in {xhrsLoading, xhrsDone}: return JS_ThrowDOMException(ctx, "InvalidStateError", "readyState must not be loading or done") #TODO parse this.contentTypeOverride = s return JS_UNDEFINED proc setResponseType(ctx: JSContext; this: XMLHttpRequest; value: XMLHttpRequestResponseType): JSValue {.jsfset: "responseType".} = let window = ctx.getWindow() if window == nil and value == xhrtDocument: return JS_UNDEFINED if this.readyState in {xhrsLoading, xhrsDone}: return JS_ThrowDOMException(ctx, "InvalidStateError", "readyState must not be loading or done") if window != nil and xhrfSync in this.flags: return JS_ThrowDOMException(ctx, "InvalidAccessError", "responseType may not be set on synchronous XHR") this.responseType = value return JS_UNDEFINED proc getContentType(this: XMLHttpRequest): string = if this.contentTypeOverride != "": return this.contentTypeOverride return this.response.getContentType() proc ptrify(s: var string): tuple[opaque: pointer; p: ptr UncheckedArray[uint8]] = if s.len == 0: return (nil, nil) var sr = new(string) sr[] = move(s) GC_ref(sr) return (cast[pointer](sr), cast[ptr UncheckedArray[uint8]](addr sr[0])) proc deallocPtrified(p: pointer) = if p != nil: let sr = cast[ref string](p) GC_unref(sr) proc abufFree(rt: JSRuntime; opaque, p: pointer) {.cdecl.} = deallocPtrified(opaque) proc blobFree(opaque, p: pointer) {.nimcall.} = deallocPtrified(opaque) proc response(ctx: JSContext; this: XMLHttpRequest): JSValue {.jsfget.} = if this.responseType in {xhrtText, xhrtUnknown}: return ctx.responseText(this) if this.readyState != xhrsDone: return JS_NULL if JS_IsUndefined(this.responseObject): case this.responseType of xhrtArraybuffer: let len = csize_t(this.received.len) let (opaque, p) = this.received.ptrify() this.responseObject = JS_NewArrayBuffer(ctx, p, len, abufFree, opaque, false) of xhrtBlob: let len = this.received.len let (opaque, p) = this.received.ptrify() let blob = newBlob(p, len, this.getContentType(), blobFree, opaque) this.responseObject = ctx.toJS(blob) of xhrtDocument: #TODO this is certainly not compliant let res = ctx.parseFromString(newDOMParser(), this.received, "text/html") this.responseObject = ctx.toJS(res) of xhrtJSON: this.responseObject = JS_ParseJSON(ctx, cstring(this.received), csize_t(this.received.len), cstring"<input>") else: discard if JS_IsException(this.responseObject): this.responseObject = JS_UNDEFINED return JS_DupValue(ctx, this.responseObject) proc addXMLHttpRequestModule*(ctx: JSContext; eventCID, eventTargetCID: JSClassID): Opt[void] = let xhretCID = ctx.registerType(XMLHttpRequestEventTarget, eventTargetCID) if xhretCID == 0: return err() ?ctx.addEventGetSet(xhretCID, [satLoadstart, satProgress, satAbort, satError, satLoad, satTimeout, satLoadend]) ?ctx.registerType(XMLHttpRequestUpload, xhretCID) ?ctx.registerType(ProgressEvent, eventCID) let xhrCID = ctx.registerType(XMLHttpRequest, xhretCID) if xhrCID == 0: return err() ?ctx.addEventGetSet(xhrCID, [satReadystatechange]) case ctx.defineConsts(xhrCID, XMLHttpRequestState) of dprException: return err() else: discard ok() {.pop.} # raises: [] �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/init.js���������������������������������������������������������������������������0000664�0000000�0000000�00000302107�15202323131�0015225�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Script executed at startup. * * Note: since much of the public API is now implemented in JS, we mark * documented functions as "public" and undocumented functions as * "private". This has nothing to do with the language-level visibility of * functions (but obviously #private can be assumed to be undocumented too.) */ globalThis.cmd = { copyURL: () => { if (pager.clipboardWrite(pager.url)) pager.alert("Copied URL to clipboard."); else pager.alert("Error; please install xsel or adjust external.copy-cmd"); }, copyCursorLink: () => { const link = pager.hoverLink; if (!link) pager.alert("Please move the cursor above a link and try again."); else if (pager.clipboardWrite(link)) pager.alert("Copied URL to clipboard."); else pager.alert("Error; please install xsel or adjust external.copy-cmd"); }, copyCursorImage: () => { const link = pager.buffer.hoverImage; if (!link) pager.alert("Please move the cursor above an image and try again."); else if (pager.clipboardWrite(link)) pager.alert("Copied URL to clipboard."); else pager.alert("Error; please install xsel or adjust external.copy-cmd"); }, gotoClipboardURL: () => { const s = pager.externCapture(config.external.pasteCmd); if (s === null) pager.alert("Error; please install xsel or adjust external.paste-cmd"); else pager.loadSubmit(s); }, toggleWrap: () => { config.search.wrap = !config.search.wrap; pager.alert("Wrap search " + (config.search.wrap ? "on" : "off")); }, loadEmpty: () => pager.load(""), webSearch: () => pager.load("br:"), addBookmark: () => { const url = encodeURIComponent(pager.url); const title = encodeURIComponent(pager.title); pager.gotoURL(`cgi-bin:chabookmark?url=${url}&title=${title}`); }, openBookmarks: () => { pager.gotoURL(`cgi-bin:chabookmark?action=view`, {history: false}); }, openHistory: () => { pager.gotoURL(pager.getHistoryURL(), { contentType: 'text/uri-list;title="History Page"', history: false, charset: "utf-8" }); }, reloadBuffer: () => pager.reload(), discardBufferPrev: () => pager.discardBuffer(pager.buffer, "prev"), discardBufferNext: () => pager.discardBuffer(pager.buffer, "next"), enterCommand: () => pager.command(), toggleCommandMode: () => { if ((pager.commandMode = pager.pinned.console != pager.buffer)) { if (!line) pager.command(); console.show(); } else console.hide(); }, toggleLinkHintsAutoClick: async () => { const res = await pager.toggleLinkHints(); if (res) pager.click(); }, rightClick: async () => { if (!pager.menu && pager.buffer != null) { const canceled = await pager.buffer.contextMenu(); if (!canceled) return pager.openMenu() } else pager.closeMenu() }, toggleMenu: () => pager.menu ? pager.closeMenu() : pager.openMenu(), viewImage: (_, save) => { let contentType = null; let url = null; if (pager.buffer.hoverCachedImage) { [url, contentType] = pager.buffer.hoverCachedImage.split(' '); url = 'file:' + pager.getCacheFile(url, pager.buffer.process); } else if (pager.buffer.hoverImage) url = new Request(pager.buffer.hoverImage, {headers: {Accept: "*/*"}}); if (url) pager.gotoURL(url, {contentType: contentType, save: save}); }, toggleScripting: () => { const buffer = pager.buffer; const buffer2 = pager.gotoURL(buffer.url, { contentType: buffer.init.contentType, history: buffer.init.history, replace: buffer, scripting: !buffer.init.scripting, cookie: buffer.init.cookie }); if (buffer2) buffer2.init.copyCursorPos(buffer.iface ?? buffer.init) }, toggleCookie: () => { const buffer = pager.buffer; const buffer2 = pager.gotoURL(buffer.url, { contentType: buffer.init.contentType, history: buffer.init.history, replace: buffer, scripting: buffer.init.scripting, cookie: !buffer.init.cookie }); if (buffer2) buffer2.init.copyCursorPos(buffer.iface ?? buffer.init) }, /* vi G */ gotoLineOrEnd: n => pager.gotoLine(n ?? pager.buffer.numLines), /* vim gg */ gotoLineOrStart: n => pager.gotoLine(n ?? 1), /* vi | */ gotoColumnOrBegin: n => pager.buffer.setCursorXCenter((n ?? 1) - 1), gotoColumnOrEnd: n => n ? pager.buffer.setCursorXCenter(n - 1) : pager.buffer.cursorLineEnd(), selectOrCopy: n => { if (pager.currentSelection) cmd.buffer.copySelection(); else pager.buffer.cursorToggleSelection(n) }, cursorToggleSelectionLine: n => pager.buffer.cursorToggleSelection(n, {selectionType: "line"}), cursorToggleSelectionBlock: n => pager.buffer.cursorToggleSelection(n, {selectionType: "block"}), saveImage: () => cmd.buffer.viewImage(1, true), mark: async () => { const c = await pager.askChar('m'); if (c.charCodeAt() != 3) /* ctrl-c */ pager.setMark(c); }, gotoMark: async () => { const c = await pager.askChar('`'); if (c.charCodeAt() != 3) /* C-c */ pager.gotoMark(c); }, gotoMarkY: async () => { const c = await pager.askChar('`'); if (c.charCodeAt() != 3) /* C-c */ pager.gotoMarkY(c); }, copySelection: async () => { if (!pager.currentSelection) { feedNext(); return; } const text = await pager.buffer.getSelectionText(); const s = text.length != 1 ? "s" : ""; if (pager.clipboardWrite(text)) pager.alert(`Copied ${text.length} character${s}.`); else pager.alert("Error; please install xsel or adjust external.copy-cmd"); pager.cursorToggleSelection(); }, cursorSearchWordForward: async n => { const word = await pager.getCurrentWord(); pager.regex = new RegExp('\\b' + RegExp.escape(word) + '\\b', "g"); return pager.searchNext(n); }, cursorSearchWordBackward: async n => { const word = await pager.getCurrentWord(); pager.regex = new RegExp('\\b' + RegExp.escape(word) + '\\b', "g"); return pager.searchPrev(n); }, line: { openEditor: () => { const res = pager.openEditor(line.text); if (res != null) { line.end(); line.clear(); line.write(res); } }, copySelection: () => { const text = line.selectedText; if (pager.clipboardWrite(text)) line.clearSelection(); }, copyOrCancel: () => { if (line.hasSelection()) cmd.line.copySelection(); else return line.cancel(); } } } /* public */ globalThis.quit = function() { pager.quit(); } /* public */ globalThis.suspend = function() { pager.suspend(); } /* private */ globalThis.feedNext = function() { pager.feedNext = true; } /* private */ globalThis.__defineGetter__("line", function() { return pager.lineEdit; }); /* buffer, precnum */ for (const it of ["cursorLeft", "cursorDown", "cursorUp", "cursorRight", "cursorNextWord", "cursorNextViWord", "cursorNextBigWord", "cursorWordBegin", "cursorViWordBegin", "cursorBigWordBegin", "cursorWordEnd", "cursorViWordEnd", "cursorBigWordEnd", "cursorPrevLink", "cursorNextLink", "cursorPrevParagraph", "cursorNextParagraph", "cursorTop", "cursorBottom", "halfPageDown", "halfPageUp", "halfPageLeft", "halfPageRight", "pageDown", "pageUp", "pageLeft", "pageRight", "scrollDown", "scrollUp", "scrollLeft", "scrollRight", "click", "searchPrev", "searchNext", "centerLineBegin", "raisePageBegin", "lowerPageBegin", "nextPageBegin", "previousPageBegin", "centerLine", "raisePage", "lowerPage", "cursorToggleSelection", "cursorNthLink", "cursorRevNthLink"]) { cmd[it] = n => pager[it](n); } /* pager, no precnum */ for (const it of ["redraw", "cancel", "toggleSource", "nextBuffer", "prevBuffer", "lineInfo", "discardBuffer", "discardBufferTree", "searchForward", "searchBackward", "isearchForward", "isearchBackward", "discardTree", "dupeBuffer", "load", "loadCursor", "saveLink", "toggleImages", "writeInputBuffer", "showFullAlert", "toggleLinkHints", "peek", "peekCursor", "quit", "suspend"]) { cmd[it] = () => pager[it](); } /* buffer, no precnum */ for (const it of ["cursorLineBegin", "cursorLineTextStart", "cursorLineEnd", "cursorMiddleColumn", "cursorLeftEdge", "cursorRightEdge", "cursorMiddle"]) { cmd[it] = () => pager[it](); } /* buffer, unshared with select * (really select should have adifferent keymap) */ for (const it of ["markURL", "reshape", "editScreen", "editSource", "saveLink", "saveScreen", "saveSource", "toggleImages"]) { cmd[it] = () => pager.buffer[it](); } /* line */ for (const it of ["submit", "backspace", "delete", "cancel", "prevWord", "nextWord", "backward", "forward", "clear", "kill", "clearWord", "killWord", "begin", "end", "escape", "prevHist", "nextHist"]) { cmd.line[it] = () => pager.lineEdit[it](); } /* backwards compat: cmd.pager and cmd.buffer used to be separate */ cmd.pager = cmd.buffer = cmd; /* * Util */ Util.clamp = function(n, lo, hi) { return Math.min(Math.max(n, lo), hi); } /* * Used as a substitute for int.high. * TODO: might want to use Number.MAX_SAFE_INTEGER, but I'm not sure if * fromJS for int saturates. (If it doesn't, just change everything to * int64.) */ Util.MAX_INT32 = 0xFFFFFFFF; Util.HttpLike = ["http:", "https:"]; /* * Pager */ class Mouse { pressed = {}; /* button -> position */ released = {}; /* button -> position */ click = {}; /* button -> count - 1 */ blockTillRelease = false; moveType = "none"; /* none, drag, select */ static SHIFT = 1; static CTRL = 2; static META = 4; } /* private */ function addDefaultOmniRule(name, match, url) { const fun = x => url + encodeURIComponent(x.substring(x.indexOf(':') + 1)); config.addOmniRule(name, match, fun); } /* private */ Pager.prototype.init = function(pages, contentType, charset, history, pipe) { globalThis.pager = this; try { config.initCommands(); } catch (e) { pager.alert(e + '\n' + e.stack); quit(1); } this.pinned = { downloads: null, console: null, prev: null, }; this.navDirection = "prev"; /* "prev", "next", "any" */ this.mouse = new Mouse(); this.tab = this.tabHead = new Tab(); this.commandMode = false; this.refreshAllowed = new Set(); addDefaultOmniRule("ddg", /^ddg:/, "https://lite.duckduckgo.com/lite/?kp=-1&kd=-1&q="); addDefaultOmniRule("br", /^br:/, "https://search.brave.com/search?q="); addDefaultOmniRule("wk", /^wk:/, "https://en.wikipedia.org/wiki/Special:Search?search="); addDefaultOmniRule("wd", /^wd:/, "https://en.wiktionary.org/w/index.php?title=Special:Search&search="); addDefaultOmniRule("mo", /^mo:/, "https://mojeek.com/search?q="); this.runStartupScript(); if (pipe) { this.loadSubmit("stream:-", { contentType: contentType || "text/x-ansi" }); } const init = {contentType, charset, history}; for (const page of pages) this.loadSubmit(page, init); this.showAlerts(); if (!config.start.headless) this.inputLoop(); else { this.headlessLoop(); let tab = this.tabHead; loop: while (tab != null) { let buffer = tab.head; while (buffer != null) { if (!this.drawBuffer(buffer.iface)) { console.error("Error in buffer", buffer.url); this.handleStderr(); /* dump errors */ break loop; } buffer = buffer.next } tab = tab.next; } } } /* public */ console.hide = function() { const pager = globalThis.pager; if (pager.consoleCacheId != -1 && pager.buffer == pager.pinned.console) pager.setBuffer(pager.pinned.prev); } /* public */ console.show = () => pager.showConsole(); const ConsoleTitle = "Browser Console"; /* public */ console.clear = function() { const pager = pager; if (pager.consoleCacheId == -1) return; if (!pager.addConsole()) return; if (pager.pinned.console != null) { const request = new Request("cache:" + pager.consoleCacheId); const buffer = pager.gotoURL(request, { title: ConsoleTitle, history: false, replace: pager.pinned.console }); if (buffer != null) { pager.pinned.console = buffer; pager.addTab(buffer); } } } /* private */ Pager.prototype.showConsole = function() { const cacheId = this.consoleCacheId; if (cacheId == -1) return; const current = this.buffer; if (this.pinned.console == null) { const request = new Request("cache:" + cacheId); const buffer = this.gotoURL(request, { title: ConsoleTitle, history: false, suppressAdd: true }); if (buffer == null) return; this.pinned.console = buffer; this.addTab(buffer); this.consoleInit = buffer.init; } if (current != this.pinned.console) { this.pinned.prev = current; this.setBuffer(this.pinned.console); } } /* private */ Pager.prototype.setBuffer = function(buffer) { if (this.buffer?.iface != null) this.clearCachedImages(this.buffer.iface); if (buffer != null) { if (buffer.tab != this.tab) this.tab = buffer.tab; this.tab.current = buffer; this.bufferInit = buffer.init; this.copyLoadInfo(buffer.init); /* if iface is null, it will be set once the buffer is loaded */ if (buffer.iface != null) { this.setVisibleBuffer(buffer); } } else { this.tab.current = null; this.bufferInit = null; } } /* private */ Pager.prototype.setVisibleBuffer = function(buffer) { this.updateTitle(buffer.init); this.bufferIface = buffer.iface; this.menu = buffer.select; buffer.iface.queueDraw(); } /* * Emulate vim's \c/\C: override defaultFlags if one is found, then remove * it from str. * Also, replace \< and \> with \b as (a bit sloppy) vi emulation. */ /* private */ Pager.prototype.compileSearchRegex = function(s) { const ignoreCaseOpt = config.search.ignoreCase; let ignoreCase = ignoreCaseOpt == "ignore"; let s2 = ""; let hasUpper = false; let hasC = false; let quot = false; for (const c of s) { hasUpper = hasUpper || c != c.toLowerCase(); if (quot) { quot = false; if (c == 'c') ignoreCase = hasC = true; else if (c == 'C') { ignoreCase = false; hasC = true; } else if (c == '<' || c == '>') { s2 += '\\b'; } else s2 += '\\' + c; } else if (c == '\\') { quot = true; } else s2 += c; } if (quot) s2 += '\\'; if (!hasC && !hasUpper && ignoreCaseOpt == "auto") ignoreCase = true; return new RegExp(s2, ignoreCase ? "gui" : "gu"); } /* private */ Pager.prototype.setLineEdit = async function(mode, prompt, obj) { if (this.lineEdit != null) await this.lineEdit.cancel(); const res = await this.setLineEdit0(mode, prompt, obj); this.unsetLineEdit(); this.queueStatusUpdate(); return res; } /* public */ Pager.prototype.searchNext = async function(n = 1) { const regex = this.regex; if (regex) { let reverse = this.reverseSearch; if (n < 0) { n = -n; reverse = !reverse; } const fun = reverse ? "cursorPrevMatch" : "cursorNextMatch"; const wrap = config.search.wrap; /* TODO probably we should add a separate keymap for menu/select */ if (this.menu) return this.menu[fun](this.regex, wrap, true, n); const buffer = this.buffer; buffer.markPos0(); await buffer[fun](regex, wrap, true, n); buffer.markPos(); } else this.alert("No previous regular expression"); } /* public */ Pager.prototype.searchPrev = function(n = 1) { return this.searchNext(-n); } /* public */ Pager.prototype.searchForward = async function(reverse = false) { const text = await this.setLineEdit("search", reverse ? "?" : "/"); if (text == null) return; if (text != "") { try { this.regex = this.compileSearchRegex(text); } catch (e) { this.alert("Invalid regex: " + e.message); } } this.reverseSearch = reverse; this.searchNext(); } /* public */ Pager.prototype.searchBackward = function() { return this.searchForward(true); } /* public */ Pager.prototype.isearchForward = async function(reverse = false) { const buffer = this.buffer; if (this.menu || buffer?.select) { /* isearch doesn't work in menus. */ this.searchForward(reverse) } else if (buffer != null) { const cx = buffer.cursorx; const cy = buffer.cursory; const fx = buffer.fromx; const fy = buffer.fromy; buffer.markPos0() const text = await this.setLineEdit("search", reverse ? "?" : "/", { update: async () => { const iter = this.isearchIter = (this.isearchIter ?? 0) + 1; const text = line.text; if (text != "") { try { this.iregex = this.compileSearchRegex(text); } catch (e) { this.iregex = e.message; } this.regex = null; } const re = this.iregex; if (re instanceof RegExp) { buffer.highlight = true; /* TODO private variable */ let wrap = config.search.wrap; const iface = buffer.iface; if (iface != null) { const fun = reverse ? "findPrevMatch" : "findNextMatch"; const [x, y, w] = await iface[fun](re, cx, cy, wrap, 1); if (this.isearchIter === iter) buffer.onMatch(x, y, w, false); } } } }); if (text == null) { /* canceled */ delete this.isearchIter; this.iregex = null; this.setFromXY(fx, fy); this.setCursorXY(cx, cy); } else { delete this.isearchIter; if (text == "" && !this.regex) { this.setFromXY(fx, fy); this.setCursorXY(cx, cy); } else { if (text != "") { if (typeof this.iregex === "string") this.alert("Invalid regex: " + this.iregex); else this.regex = this.iregex; } else this.searchNext() this.reverseSearch = reverse; buffer.markPos() await buffer.iface.sendCursorPosition() } } const iface = buffer.iface; if (iface != null) iface.clearSearchHighlights() } } /* public */ Pager.prototype.isearchBackward = function() { return this.isearchForward(true); } /* Reuse the line editor as an alert message viewer. */ /* public */ Pager.prototype.showFullAlert = function() { const str = this.lastAlert; if (str != "") this.setLineEdit("alert", "", {current: str}); } /* private */ Pager.prototype.setTab = function(buffer, tab) { const removed = buffer.setTab(tab); if (removed != null) { if (removed.next != null) removed.next.prev = removed.prev; if (removed.prev != null) removed.prev.next = removed.next; if (this.tabHead == removed) this.tabHead = removed.next; removed.prev = removed.next = null; /* tab cannot be null */ if (this.tabHead == null) this.tab = this.tabHead = new Tab() } } /* private */ Pager.prototype.addBuffer = function(buffer) { this.navDirection = "next"; this.setTab(buffer, this.tab); this.setBuffer(buffer); } /* public */ Pager.prototype.addTab = function(buffer = "about:blank") { if (!(buffer instanceof Buffer)) { let url = buffer instanceof URL ? buffer : new URL(buffer); buffer = this.gotoURL(url, {history: false}); if (buffer == null) throw new TypeError("failed to go to " + url) } let tab = new Tab(); const oldTab = this.tab; if (oldTab.next != null) oldTab.next.prev = tab; /* add to link first, or setTab dies */ tab.prev = oldTab; tab.next = oldTab.next; if (tab.next != null) tab.next.prev = tab; oldTab.next = tab; pager.setTab(buffer, tab); this.setBuffer(buffer); } /* public */ Pager.prototype.prevTab = function() { if (this.tab.prev != null) { this.tab = this.tab.prev; this.setBuffer(this.buffer); } else pager.alert("No previous tab"); } /* public */ Pager.prototype.nextTab = function() { if (this.tab.next != null) { this.tab = this.tab.next; this.setBuffer(this.buffer); } else pager.alert("No next tab"); } /* public */ Pager.prototype.discardTab = function() { const tab = this.tab; const prevTab = tab.prev; const nextTab = tab.next; if (prevTab != null || nextTab != null) { let buffer = tab.head; while (buffer != null) { const next = buffer.next; this.deleteBuffer(buffer); buffer = next; } if (prevTab != null) { if (nextTab != null) nextTab.prev = prevTab; this.tab = prevTab; } else { nextTab.prev = prevTab; if (tab == this.tabHead) this.tabHead = nextTab; this.tab = nextTab; } this.setBuffer(this.buffer); } else this.alert("This is the last tab") } /* public */ Pager.prototype.gotoURL = function(request, obj) { const init = this.gotoURLImpl(request, obj); if (init == null) return null; const buffer = new Buffer(init, this.tab); buffer.retry = obj?.retry; const old = obj?.replace; if (old != null) { this.replaceWith(old, buffer); let replace = old; if (old.replace != null) { /* handle replacement chains by dropping everything in the * middle */ replace = old.replace; this.deleteBuffer(old); } buffer.replace = replace; replace.replaceRef = buffer; } else if (!obj?.suppressAdd) this.addBuffer(buffer); return buffer; } /* * Check if the user is trying to go to an anchor of the current buffer. * If yes, the caller need not call gotoURL. */ /* private */ Pager.prototype.gotoURLHash = function(request, current) { let url; if (request instanceof URL) url = request; else { if (request.method != "GET") return false; url = new URL(request.url); } if (current?.iface == null || url.hash == "") return false; /* check if only hash changed */ const anchor = url.hash.substring(1); url.hash = current.url.hash; if (current.url + "" != url + "") return false; url.hash = anchor; current.iface.gotoAnchor(anchor, false, false).then(([x, y, click]) => { if (y >= 0) { const nc = this.dupeBuffer2(current, url); nc.setCursorXYCenter(x, y); } else this.alert("Anchor #" + anchor + " not found"); }); return true; } /* * When the user has passed a partial URL as an argument, they might've meant * either: * - file://$PWD/<file> * - https://<url> * So we attempt to load both, and see what works. */ /* public */ Pager.prototype.loadSubmit = function(url, init) { let url0; try { url0 = this.omniRewrite(url); } catch (e) { this.alert(`Exception in omni-rule: ${e} ${e.stack}`); return; } const first = URL.parse(url0); if (first != null) { if (!this.gotoURLHash(first, this.buffer)) this.gotoURL(first, init); return; } const urls = Util.expandPath(url0); if (urls.length == 0) return; let retry = null; const prependScheme = config.network.prependScheme; if (prependScheme != "" && urls[0] != '/') retry = URL.parse(prependScheme + urls); const local = Util.encodeURIPath(urls); const cdir = "file:" + Util.encodeURIPath(Util.getcwd()) + "/"; let url1 = URL.parse(local, cdir); if (url1 == null) { url1 = retry; retry = null; } if (url1 != null) this.gotoURL(url1, {...init, retry: retry}); else this.alert("Invalid URL " + urls); } /* Open a URL prompt. */ /* public */ Pager.prototype.load = async function(url = null) { if (url == null) { if (!this.buffer) return; url = this.buffer.url; } const res = await this.setLineEdit("location", "URL: ", {current: url}); if (res) this.loadSubmit(res); } /* public */ Pager.prototype.loadCursor = function() { return this.load(this.buffer.hoverLink || this.buffer.hoverImage); } /* Reload the page in a new buffer, then kill the previous buffer. */ /* public */ Pager.prototype.reload = function() { const old = this.buffer; if (!old) return; const buffer = this.gotoURL(old.url, { contentType: old.init.contentType, replace: old, history: old.init.history, charset: old.init.charsetOverride }) buffer.init.copyCursorPos(old.iface ?? old.init); } /* public */ Pager.prototype.externFilterSource = function(cmd, buffer = this.buffer, contentType = null) { contentType ??= buffer.init.contentType || "text/plain"; const init = this.initBufferFrom(buffer.init, contentType, cmd); if (init != null) { const buffer = new Buffer(init, this.tab); this.addBuffer(buffer); } } /* public */ Pager.prototype.toggleSource = function() { const buffer = this.buffer; if (buffer == null) return; if (buffer.sourcePair != null) this.setBuffer(buffer.sourcePair); else { const ishtml = buffer.init.ishtml; /* TODO I wish I could set the contentType to whatever I wanted, * not just HTML */ const contentType = ishtml ? "text/plain" : "text/html"; const init = pager.initBufferFrom(buffer.init, contentType, ""); if (init != null) { const buffer2 = new Buffer(init, this.tab); buffer2.sourcePair = buffer; buffer.sourcePair = buffer2; this.addBuffer(buffer2); } } } /* public */ Pager.prototype.discardTree = function(buffer = this.buffer) { while (buffer != null) { const next = buffer.next; this.discardBuffer(buffer); buffer = next; } } /* public */ Pager.prototype.dupeBuffer = function() { this.dupeBuffer2(this.buffer, this.buffer.url) } /* private */ Pager.prototype.dupeBuffer2 = function(buffer, url) { const init2 = new BufferInit(url, buffer.init); const iface = this.clone(buffer.iface, init2, url); if (iface == null) { this.alert("Failed to duplicate buffer."); return; } const buffer2 = new Buffer(init2, this.tab, iface); buffer2.currentSelection = buffer.currentSelection; this.addBuffer(buffer2); return buffer2; } /* public */ Pager.prototype.traverse = function(dir) { this.navDirection = dir; const buffer = this.buffer; if (buffer == null) return false; const next = buffer.find(dir); if (next == null) return false; this.setBuffer(next); return true; } /* public */ Pager.prototype.prevBuffer = function() { return this.traverse("prev"); } /* public */ Pager.prototype.nextBuffer = function() { return this.traverse("next"); } /* public */ Pager.prototype.command = async function() { const text = await this.setLineEdit("command", "COMMAND: "); if (text != null) { try { console.log(this.evalCommand(text)); } catch (e) { console.log(e + '\n' + e.stack.trimEnd()); } if (this.commandMode) return this.command(); } else this.commandMode = false; } /* public */ Pager.prototype.gotoLine = async function(n) { const buffer = this.buffer; const target = this.menu ?? buffer?.select ?? buffer; if (!target) return; if (n === undefined) { const text = await this.setLineEdit("gotoLine", "Goto line: "); if (text != null) return this.gotoLine(text); } if (typeof n === "number") n--; /* gotoLine is 1-indexed */ else { n = n + ""; if (n.length == 0) return; if (n[0] == '^') n = 0; else if (n[0] == '$') n = Util.MAX_INT32; else n = parseInt(n) - 1; if (isNaN(n)) { this.alert("invalid line number"); return; } } if (target == buffer) buffer.markPos0(); target.setCursorY(n); if (target == buffer) buffer.markPos(); } /* public */ Pager.prototype.peek = function() { const buffer = this.buffer; if (buffer != null) this.alert(buffer.url); } /* public */ Pager.prototype.ask = async function(prompt) { const s = await this.askChar(this.fitAskPrompt(prompt)); switch (s) { case "y": return true; case "n": return false; default: return this.ask(prompt); } } /* private */ Pager.prototype.toggleLinkHints = async function() { const buffer = this.buffer; buffer.markPos0(); const urls = await this.showLinkHints(); if (urls.length == 0) { this.alert("No links on page"); return false; } const chars = config.input.linkHintChars; function hint(n) { let tmp = []; for (n--; n >= 0; n = Math.floor(n / chars.length) - 1) tmp.push(chars[n % chars.length]); return tmp.reverse().join(""); } const map = {}; let offset = Math.floor((urls.length + chars.length - 2) / (chars.length - 1)); for (let i = 0, j = offset; i < urls.length; i++, j++) { let h = hint(j); let it = map; for (let k = 0, L = h.length - 1; k < L; k++) it = it[h[k]] ??= {}; urls[i].leaf = true; it[h.at(-1)] = urls[i]; } let s = ""; let it = map; let alert = true; while (it && !it.leaf) { const c = await this.askChar(s); if (c == '\b' || c == '\x7f') { if (s.length == 0) { alert = false; break; } s = s.substring(0, s.length - 1); it = map; for (const c2 of s) it = it[c2]; } else if (c == '\x03') { alert = false; break; } else { it = it[c]; s += c; } } buffer.hideLinkHints(); if (it?.leaf) { this.setCursorXY(it.x, it.y); buffer.markPos(); return true; } else if (alert) this.alert("No such hint"); return false; } /* private */ Pager.prototype.lineInfo = function() { const buffer = this.buffer; const iface = buffer?.iface; if (iface == null) return; const x0 = buffer.cursorx; const y0 = buffer.cursory; const x = x0 + 1; const y = y0 + 1; const numLines = buffer.numLines; const perc = numLines == 0 ? 100 : Math.floor(100 * y / numLines); const w = iface.currentLineWidth(); const b = iface.cursorBytes(y0, x0); this.alert(`line ${y}/${numLines} (${perc}%) col ${x}/${w} (byte ${b})`); } const MenuMap = [ ["Select text (v)", cmd.selectOrCopy], ["Previous buffer (,)", cmd.prevBuffer], ["Next buffer (.)", cmd.nextBuffer], ["Discard buffer (D)", cmd.discardBuffer], null, ["Copy page URL (M-y)", cmd.copyURL], ["Copy link (yu)", cmd.copyCursorLink], ["View image (I)", cmd.viewImage], ["Copy image link (yI)", cmd.copyCursorImage], ["Reload (U)", cmd.reloadBuffer], null, ["Save link (sC-m)", cmd.saveLink], ["View source (\\)", cmd.toggleSource], ["Edit source (sE)", cmd.sourceEdit], ["Save source (sS)", cmd.saveSource], null, ["Linkify URLs (:)", cmd.markURL], ["Toggle images (M-i)", cmd.toggleImages], ["Toggle JS & reload (M-j)", cmd.toggleScripting], ["Toggle cookie & reload (M-k)", cmd.toggleCookie], null, ["Bookmark page (M-a)", cmd.addBookmark], ["Open bookmarks (M-b)", cmd.openBookmarks], ["Open history (C-h)", cmd.openHistory], ]; /* public */ Pager.prototype.openMenu = async function(x = null, y = null) { const buffer = this.buffer; x = Math.max(x ?? buffer?.acursorx, 0); y = Math.max(y ?? buffer?.acursory, 0); const options = MenuMap.map(x => x ? x[0] : null); if (buffer?.currentSelection != null) options[0] = "Copy selection (y)" const selected = await new Promise(resolve => { this.menu = new Select(options, -1, x, y, this.bufWidth, this.bufHeight, resolve); }); this.menu = null; if (selected != -1) MenuMap[selected][1](); if (buffer?.iface != null) buffer.iface.queueDraw(); } /* public */ Pager.prototype.closeMenu = function() { const menu = this.menu; if (menu != null) { this.menu = null; return menu.cancel(); } } /* public */ Pager.prototype.openEditor = function(input) { let tmpf = this.getTempFile(); Util.mkdir(config.external.tmpdir, 0o700); input += '\n'; try { writeFile(tmpf, input, 0o600); } catch (e) { this.alert("failed to write temporary file"); return null; } const cmd = this.getEditorCommand(tmpf); if (cmd == "") { this.alert("invalid external.editor command"); return null; } this.extern(cmd); let res = readFile(tmpf, input); Util.unlink(tmpf); if (res != null && res.at(-1) == '\n') res = res.substring(0, res.length - 1); return res; } /* public */ Pager.oppositeDir = function(dir) { switch (dir) { case "prev": return "next"; case "next": return "prev"; case "any": return "any"; default: throw new TypeError("direction expected"); } }; /* public */ Pager.prototype.__defineGetter__("buffer", function() { return this.tab.current; }); /* public */ Pager.prototype.__defineGetter__("revDirection", function() { return Pager.oppositeDir(this.navDirection); }); /* public */ Pager.prototype.__defineGetter__("cacheFile", function() { const buffer = this.buffer; if (buffer == null) return ""; return this.getCacheFile(buffer.cacheId); }); /* public */ Pager.prototype.discardBuffer = function(buffer = this.buffer, dir = null) { if (dir != null) this.navDirection = Pager.oppositeDir(dir); dir = this.revDirection; const setTarget = buffer.find(dir); if (buffer == null || setTarget == null) this.alert(dir == "next" ? "No next buffer" : "No previous buffer"); else this.deleteBuffer(buffer, setTarget); } /* private */ Pager.prototype.promptPaste = async function(input) { this.startMousePaste(); const text = await this.askChar("Waiting for paste (C-c to cancel)"); this.stopMousePaste(); if (!this.paste && text == '\x03') return null; return text; } /* private */ Pager.prototype.handleMouseInput = async function(input) { const mouse = this.mouse; if (mouse.blockTillRelease) { if (input.t != "release") return; mouse.blockTillRelease = false; } const button = input.button; let [pressedX, pressedY] = mouse.pressed[button] ?? [-1, -1]; let click = mouse.click[button] ?? 0; const edit = this.lineEdit; let buffer = this.buffer; const select = this.menu ?? buffer?.select; if (edit != null) { if (button == "left") { switch (input.t) { case "release": { if (mouse.moveType == "select") { if (this.osc52Primary && !edit.hide) this.clipboardWrite(edit.selectedText, false); } else if (pressedX == input.x && pressedY == input.y) { if (input.y < this.bufHeight - 4) { if (buffer != null) buffer.setAbsoluteCursorXY(input.x, input.y); await edit.cancel(); } else { if (click == 0) { edit.clearSelection(); edit.setAbsoluteCursorX(input.x); } else if (click < 3) { edit.startSelection(click == 1 ? "word" : "line"); if (this.osc52Primary && !edit.hide) this.clipboardWrite(edit.selectedText, false); } else if (click == 3) { edit.clearSelection(); edit.setAbsoluteCursorX(input.x); } else mouse.click[button] = 0; } } else if (pressedX != -1 && pressedY != -1) { const dcol = input.x - pressedX; const drow = input.y - pressedY; if (dcol > 0) buffer.shiftScreenLeft(dcol); else buffer.shiftScreenRight(-dcol); if (drow > 0) buffer.shiftScreenUp(drow); else buffer.shiftScreenDown(-drow); } break; } case "move": if (click >= 1) { switch (mouse.moveType) { case "none": /* drag if mouse moved vertically, select otherwise */ if (pressedY == input.y) { mouse.moveType = "select"; if (!edit.hasSelection()) edit.startSelection("char"); edit.setAbsoluteCursorX(input.x); } else mouse.moveType = "drag"; break; case "select": edit.setAbsoluteCursorX(input.x); break; } } break; } } else if (button == "right") { if (input.t == "release") await edit.cancel(); } else if (buffer != null && input.t == "press") { switch (button) { case "middle": const text = await this.promptPaste(); if (text != null) edit.write(text); break; case "thumbInner": edit.prevHist(); break; case "thumbTip": edit.nextHist(); break; case "wheelUp": buffer.shiftScreenUp(config.input.wheelScroll); break; case "wheelDown": buffer.shiftScreenDown(config.input.wheelScroll); break; case "wheelLeft": buffer.shiftScreenLeft(config.input.sideWheelScroll); break; case "wheelRight": buffer.shiftScreenRight(config.input.sideWheelScroll); break; } } } else if (select != null) { /* one off because of border */ const y = select.fromy + input.y - select.y - 1; let inside = select.y + 1 <= input.y && input.y < select.y + select.height - 1 && select.x + 1 <= input.x && input.x < select.x + select.width - 1; let outside = select.y > input.y || input.y >= select.y + select.height && select.x > input.x || input.x >= select.x + select.width; if (button == "right") { if (!inside) select.unselect(); else if (input.x != pressedX || input.y != pressedY) { /* * Prevent immediate movement/submission in case the menu * appeared under the cursor. */ select.setCursorY(y); } if (input.t == "press") { /* * Do not include borders, so that a double right click * closes the menu again. */ if (!inside) { mouse.blockTillRelease = true; select.cursorLeft(); } } else if (input.t == "release") { if (inside && (input.x != pressedX || input.y != pressedY)) select.click(); else if (outside) select.cursorLeft(); } } else if (button == "left") { if (input.t == "press") { if (outside) { /* clicked outside the select */ mouse.blockTillRelease = true; select.cursorLeft(); } } else if (input.t == "release") { if (input.x == pressedX && input.y == pressedY && inside) { /* clicked inside the select */ select.setCursorY(y); select.click(); } } } else if (input.t == "press") { switch (button) { case "wheelUp": this.scrollUp(config.input.wheelScroll); break; case "wheelDown": this.scrollDown(config.input.wheelScroll); break; case "wheelLeft": this.scrollLeft(config.input.sideWheelScroll); break; case "wheelRight": this.scrollRight(config.input.sideWheelScroll); break; } } } else if (buffer != null) { if (button == "left") { switch (input.t) { case "move": if (click < 1) break; switch (mouse.moveType) { case "none": if (pressedY == input.y) { mouse.moveType = "select"; if (!buffer.currentSelection?.mouse) await buffer.startSelection("normal", true); buffer.setAbsoluteCursorXY(input.x, input.y); } else mouse.moveType = "drag"; break; case "select": buffer.setAbsoluteCursorXY(input.x, input.y); break; } break; case "release": if (buffer.currentSelection?.mouse) { if (this.osc52Primary) { const text = await buffer.getSelectionText(); this.clipboardWrite(text, false); } } else if (pressedX == input.x && pressedY == input.y && input.y < buffer.height) { const px = buffer.cursorx; const py = buffer.cursory; buffer.setAbsoluteCursorXY(input.x, input.y); if (px == buffer.cursorx && py == buffer.cursory) buffer.click(click); } break; case "press": if (buffer.currentSelection?.mouse) buffer.clearSelection(); break; } } else if (button == "middle") { if (input.t == "release" && input.x == pressedX && input.y == pressedY && input.y < buffer.height) { this.discardBuffer(buffer); } } else if (input.t == "press") { switch (button) { case "right": if (input.y < buffer.height) { let canceled = false; if (buffer.currentSelection == null && !(input.mods & Mouse.META)) { buffer.setAbsoluteCursorXY(input.x, input.y); canceled = await buffer.contextMenu(); } if (!canceled) { this.openMenu(input.x, input.y); this.menu.unselect(); } } break; case "thumbInner": this.prevBuffer(); break; case "thumbTip": this.nextBuffer(); case "wheelUp": this.scrollUp(config.input.wheelScroll); break; case "wheelDown": this.scrollDown(config.input.wheelScroll); break; case "wheelLeft": this.scrollLeft(config.input.sideWheelScroll); break; case "wheelRight": this.scrollRight(config.input.sideWheelScroll); break; } } } if (!mouse.blockTillRelease) { if (input.t == "release") { switch (button) { case "left": const moveType = mouse.moveType; mouse.moveType = "none"; if (moveType == "select" || edit != null) { /* do nothing */ } else if (input.y == this.bufHeight && pressedX == input.x && pressedY == input.y && edit == null) { this.load(); /* reset click count */ mouse.pressed[button] = [-1, -1]; pressedX = pressedY = -1; } else if (input.y >= this.bufHeight - 1 && pressedY == input.y) { const dcol = input.x - pressedX; if (edit == null) { if (dcol <= -2) this.nextBuffer(); else if (dcol >= 2) this.prevBuffer(); } } else if (pressedX != -1 && pressedY != -1) { const dcol = input.x - pressedX; const drow = input.y - pressedY; if (dcol > 0) this.scrollLeft(dcol); else this.scrollRight(-dcol); if (drow > 0) this.scrollUp(drow); else this.scrollDown(-drow); } break; case "right": if (pressedX == input.x && pressedY == this.bufHeight && edit == null) { this.loadCursor(); } break; case "middle": if (pressedX == input.x && pressedY == this.bufHeight && edit == null) { this.load(""); } break; } if (pressedX != input.x || pressedY != input.y) mouse.click[button] = 0; mouse.released[button] = mouse.pressed[button]; mouse.pressed[button] = [-1, -1]; } else if (input.t == "press") { mouse.pressed[button] = [input.x, input.y]; const [releasedX, releasedY] = mouse.released[button] ?? [-1, -1]; if (input.x == releasedX && input.y == releasedY) mouse.click[button] = click + 1; else mouse.click[button] = 0; } } this.queueStatusUpdate(); } /* private */ Pager.prototype.handleInput = async function(t, mouseInput) { const line = globalThis.line; let paste = false; switch (t) { case "paste": paste = true; case "keyEnd": if (this.fulfillAsk(paste)) { this.queueStatusUpdate(); } else if (line != null) { if (paste || line.escNext) { line.escNext = false; this.writeInputBuffer(); } else { const map = config.line; return this.evalInputAction(map, 0); } } else if (paste) { const p = this.setLineEdit("location", "URL: "); this.writeInputBuffer(); const res = await p; if (res) this.loadSubmit(res); } else if (this.updateNumericPrefix()) { this.queueStatusUpdate(); } else { const map = config.page; const p = this.evalInputAction(map, this.arg0); /* * We must queue the status update before the await in order to * avoid the following situation: * 1. action calls alert() * 2. action awaits something * 3. action finishes * 4. now we return after the await, but the status update has * already been shown in another event cycle, so the alert * disappears. * (Probably there is a better design for all this.) */ this.queueStatusUpdate(); if (map.keyLast == 0) { this.precnum = 0; await p; } } break; case "mouse": return this.handleMouseInput(mouseInput); case "windowChange": let tab = this.tabHead; const width = this.bufWidth; const height = this.bufHeight; while (tab != null) { let buffer = tab.head; while (buffer != null) { buffer.init.width = width; buffer.init.height = height; const iface = buffer.iface; if (iface != null) { (function(buffer) { iface.windowChange(buffer.cursorx, buffer.cursory) .then(pos => buffer.setCursorXYCenter(...pos)); })(buffer); } const select = buffer.select; if (select != null) select.windowChange(width, height); buffer = buffer.next; } tab = tab.next; } break; } } /* private */ Pager.prototype.replaceWith = function(old, replacement) { if (replacement.prev != null) replacement.prev.next = replacement.next; if (replacement.next != null) replacement.next.prev = replacement.prev; if (old.tab.head == old) old.tab.head = replacement; replacement.prev = old.prev; replacement.next = old.next; replacement.tab = old.tab; old.prev = old.next = old.tab = null; if (replacement.prev != null) replacement.prev.next = replacement if (replacement.next != null) replacement.next.prev = replacement for (const name in this.pinned) { if (this.pinned[name] == old) this.pinned[name] = replacement; } if (this.buffer == old) this.setBuffer(replacement); } /* private */ Pager.prototype.deleteBuffer = function(buffer, setTarget = null) { const iface = buffer.iface; if (iface != null && iface.loadState == "loading") iface.cancel(); if (buffer.sourcePair != null) buffer.sourcePair = buffer.sourcePair.sourcePair = null; if (buffer.replaceRef != null) buffer.replaceRef = buffer.replaceRef.replace = null; if (buffer.replace != null) buffer.replace = buffer.replace.replaceRef = null; const wasCurrent = this.buffer == buffer; this.setTab(buffer, null); for (const name in this.pinned) { if (this.pinned[name] == buffer) this.pinned[name] = null; } if (wasCurrent) { if (iface != null) this.clearCachedImages(iface); this.setBuffer(setTarget); } if (iface != null) this.unregisterBufferIface(iface); else this.unregisterBufferInit(buffer.init); } /* private */ class Tab { head = null; /* Buffer */ current = null; /* Buffer */ prev = null; /* Tab */ next = null; /* Tab */ } /* * RegExp literals are pre-compiled. * We skip compiling vi words for now because bytecode with Unicode gets * obscenely large. */ const ReWordStart = /(?<!\w)\w/gu; /* kana, han, hangul, other alpha & non-alpha (symbol) */ const ReViWordStart = new RegExp( String.raw`((?<!\p{sc=Hira})\p{sc=Hira})|((?<!\p{sc=Kana})\p{sc=Kana})|((?<!\p{sc=Han})\p{sc=Han})|((?<!\p{sc=Hang})\p{sc=Hang})|((?<!\w)\w)|((?<![^\p{L}\p{Z}\p{N}])[^\p{L}\p{Z}\p{N}])`, "gu" ); const ReBigWordStart = /(?<!\S)\S/gu; const ReWordEnd = /\w(?!\w)/gu; /* kana, han, hangul, other alpha & non-alpha (symbol) */ const ReViWordEnd = new RegExp( String.raw`(\p{sc=Hira}(?!\p{sc=Hira}))|(\p{sc=Kana}(?!\p{sc=Kana}))|(\p{sc=Han}(?!\p{sc=Han}))|(\p{sc=Hang}(?!\p{sc=Hang}))|(\w(?!\w))|([^\p{L}\p{Z}\p{N}](?![^\p{L}\p{Z}\p{N}]))`, "gu" ); const ReBigWordEnd = /\S(?!\S)/gu; const ReTextStart = /\S/gu; /* public */ class Buffer { /* public Highlight */ currentSelection = null; /* public Select */ select = null; /* public Buffer */ prev = null; /* public Buffer */ next = null; /* private Buffer */ sourcePair = null; /* private Buffer */ replace = null; /* private Buffer */ replaceRef = null; /* private URL */ retry = null; /* private BufferInterface */ iface = null; /* private BufferInit */ init; /* private Tab */ tab; /* private */ constructor(init, tab, iface = null) { if (!(init instanceof BufferInit) || !(tab instanceof Tab)) throw new TypeError("invalid arguments"); this.init = init; this.tab = tab; if (iface != null) this.#connected("connected", iface); else init.connected = this.#connected.bind(this); } /* private */ get acursorx() { return this.iface?.acursorx ?? 0; } /* private */ get acursory() { return this.iface?.acursory ?? 0; } /* private */ async #connected(res, arg0) { const pager = globalThis.pager; switch (res) { case "connected": { this.iface = arg0; return this.#startLoad(); } case "redirect": { const request = arg0; const redirectDepth = this.init.redirectDepth; if (redirectDepth < config.network.maxRedirect) { const url = new URL(request.url); const requestProto = url.protocol; const bufferProto = this.url.protocol; if (bufferProto != requestProto && bufferProto != "cgi-bin:") { if (requestProto == "cgi-bin:") { pager.alert("Blocked redirection attempt to " + url); return; } if (!(Util.HttpLike.includes(bufferProto) && Util.HttpLike.includes(requestProto))) { const x = await pager.ask("Warning: switch protocols? " + url); if (!x) return; } } pager.numload--; const save = this.init.save; if (save || !pager.gotoURLHash(request, this)) { const nc = pager.gotoURL(request, { history: this.init.history, save: save, redirectDepth: redirectDepth + 1, referrer: this.init }); if (nc != null) { const replace = this.#popReplace(); pager.replaceWith(this, nc); if (replace != null) { nc.replace = replace; replace.replaceRef = nc; } nc.setLoadInfo("Redirecting to " + url); } } } else { pager.alert("Error: maximum redirection depth reached") pager.deleteBuffer(this, buffer.find("any")) } break; } case "unauthorized": { const url = new URL(this.url) const username = await pager.setLineEdit("username", "Username: ", { current: url.username }); if (username == null) { pager.discardBuffer(this); return; } const password = await pager.setLineEdit("password", "Password: ", { hide: true }); if (password != null) { url.username = username; url.password = password; const buffer2 = pager.gotoURL(url, {referrer: this.init}); pager.replaceWith(this, buffer2); } else pager.discardBuffer(this); break; } case "fail": { if (this.replace != null) /* deleteBuffer unsets replace etc. */ pager.replaceWith(this, this.replace); pager.deleteBuffer(this, this.find("any")); const retry = this.retry; if (retry != null) { pager.gotoURL(retry, { contentType: this.init.contentType, history: this.init.history }); } else { /* * Add to the history anyway, so that the user can edit the URL. */ if (this.init.history) pager.addHist("location", this.init.url); /* * Try to fit a meaningful part of the URL and the error * message too. * URLs can't include double-width chars, so we can just use * string length for those. (However, error messages can.) */ let msg = "Can't load " + this.init.url; const ew = Util.width(arg0); const width = pager.statusWidth; if (msg.length + ew > width) { msg = msg.substring(0, Math.max(width - ew, width / 3) + 1); if (msg.length > 0) msg += '$'; } pager.alert(`${msg} (${arg0})`); } break; } case "cancel": { pager.deleteBuffer(this, this.find("any")); pager.queueStatusUpdate(); break; } case "save": { let buf = config.external.downloadDir; if (buf.at(-1) != '/') buf += '/'; let path = this.init.url.pathname; if (path.at(-1) == '/') buf += "index.html"; else buf += decodeURI(path.substring(path.lastIndexOf('/') + 1)); pager.deleteBuffer(this, this.find("any")); pager.queueStatusUpdate(); for (;;) { const text = await pager.setLineEdit("download", "(Download)Save file to: ", { current: buf, hide: false }); if (text == null) return this.init.closeMailcap(); path = Util.unquote(text, Util.getcwd()); if (path != null) { if (Util.isFile(path)) { const x = await pager.ask(`Override file ${path}?`); if (!x) continue; } if (pager.saveTo(this.init, path)) break; } const x = await pager.ask(`Cannot save to ${path}. Retry?`); if (!x) return this.init.closeMailcap(); continue; } if (config.external.showDownloadPanel) { const old = pager.pinned.downloads; const downloads = pager.gotoURL("about:downloads", { history: false, replace: old }); if (downloads != null && old != null) pager.setBuffer(downloads); pager.pinned.downloads = downloads; } else pager.alert("Saving file to " + path); break; } case "mailcap": { const init = this.init; /* we must reset connectedPtr for connected2 */ init.connected = this.#connected.bind(this); let i = arg0; let sx = 0; loop: for (;;) { const [prev, next] = pager.findMailcapPrevNext(init, i); const s = await pager.askMailcap(init, i, sx, prev, next); let mailcapFlag; switch (s) { case '\x03': case 'q': pager.alert("Canceled"); init.closeMailcap(); break loop; case 'e': /* TODO no idea how to implement save :/ * probably it should run use a custom reader that runs * through auto-mailcap clearing any other entry. * but maybe it's better to add a full blown editor * like w3m has at that point... */ const text = await pager.setLineEdit("mailcap", "Mailcap: ", { current: init.shortContentType + ';' }); if (text == null) break; try { pager.applyMailcap(init, text); } catch (e) { break; } break loop; case 's': case 'S': init.save = true; if (s == 'S') pager.addMailcapEntry(init, "exec cat", "x-saveoutput"); break loop; case 't': case 'T': if (s == 'T') pager.addMailcapEntry(init, "exec cat", "copiousoutput"); break loop; case 'r': case 'R': if (i < 0) break; if (s == 'R') pager.saveMailcapEntry(init, i); pager.applyMailcap(init, i); break loop; /* navigation */ case 'p': case 'k': if (prev != -1) i = prev; break; case 'n': case 'j': if (next != -1) i = next; break; case 'h': sx = Math.max(sx - 1, 0); break; case 'l': sx = Math.max(sx + 1, 0); break; case '^': case '\x01': sx = 0; break; case '$': case '\x05': sx = Number.MAX_SAFE_INTEGER; break; } } return pager.connected2(init); }} } #setVisible() { if (this.iface.loadState == "loaded" && this.iface.gotLines) { const visible = pager.bufferInit == this.init; if (visible && pager.bufferIface != this.iface) pager.setVisibleBuffer(this); if (this.init.loadInfo != "") { this.setLoadInfo(""); if (visible && pager.alertState == "loadInfo") { pager.alertState = "normal"; pager.queueStatusUpdate(); } } } } async #startLoad() { let repaintLoopPromise, titlePromise; if (!this.init.headless) { repaintLoopPromise = (async () => { for (;;) { /* If we get lines before the buffer loads, show them. * However, loadinfo must remain visible until the * buffer actually loads. */ if (this.numLines > 0 && pager.bufferInit == this.init && pager.bufferIface != this.iface) pager.setVisibleBuffer(this); this.#setVisible(); await this.iface.onReshape(); await this.iface.requestLines(true); } })(); } titlePromise = this.iface.getTitle().then(title => { if (title != "") { this.init.title = title; if (pager.buffer == this) { if (this.iface != null && this.iface.loadState != "loading") pager.queueStatusUpdate(); pager.updateTitle(this.init); } } }); loop: while (this.iface.loadState != "canceled") { const [n, len, bs] = await this.iface.load(); switch (bs) { case "loadingPage": this.setLoadInfo(`${Util.convertSize(n)} loaded`); break; case "loadingStyle": this.setLoadInfo(`${n}/${len} stylesheets loaded`); break; case "loadingImages": this.setLoadInfo(`${n}/${len} images loaded`); break; default: /* loaded */ if (!this.iface.gotLines) await this.iface.requestLines(); break loop; } } this.iface.loadState = "loaded"; this.#setVisible(); const replace = this.#popReplace(); if (replace != null) pager.deleteBuffer(replace, this); pager.numload--; if (!this.init.hasStart) { if (!this.init.headless) this.iface.sendCursorPosition(); const anchor = this.url.hash.substring(1); const autofocus = this.init.autofocus; if (anchor != "" || autofocus) { const [x, y, click] = await this.iface.gotoAnchor(anchor, autofocus, true); if (y >= 0) { this.setCursorXYCenter(x, y); const ReadLine = ["read-text", "read-password", "read-file"]; if (click != null && ReadLine.includes(click.t)) await this.#onclick(click); } } } const metaRefresh = this.init.metaRefresh; if (metaRefresh != "never") { let [n, url] = await this.iface.checkRefresh(); url ??= this.url; /* null => reload (if n >= 0) */ if (n >= 0 && metaRefresh != "always") { const surl = url + ""; const refreshAllowed = pager.refreshAllowed; if (!refreshAllowed.has(surl)) { const ok = await pager.ask(`Redirect to ${surl} (in ${n}ms?)`); if (ok) refreshAllowed.add(surl); else n = -1; } } if (n >= 0) { setTimeout(() => { if (this.iface != null) { pager.gotoURL(url, { replace: this, history: this.init.history }).init.copyCursorPos(this.iface ?? this.init); } }, n); } } await titlePromise; await repaintLoopPromise; } #popReplace() { const replace = this.replace; if (replace != null) replace.replaceRef = this.replace = null; return replace; } #append(other) { if (other.prev != null) other.prev.next = other.next; if (other.next != null) other.next.prev = other.prev; other.next = this.next; if (this.next != null) this.next.prev = other; other.prev = this; this.next = other; } #remove() { if (this.prev != null) this.prev.next = this.next; if (this.next != null) this.next.prev = this.prev; if (this.tab.current == this) this.tab.current = this.prev ?? this.next; if (this.tab.head == this) this.tab.head = this.next; this.tab = this.next = this.prev = null; } async #onclick(res, save = false) { if (res == null) return; const iface = this.iface; switch (res.t) { case "open": { const request = res.open; const contentType = res.contentType; const url = new URL(request.url); const bufferProtocol = this.url.protocol; const urlProtocol = url.protocol; const sameProtocol = bufferProtocol == urlProtocol; if (request.method != "GET" && !sameProtocol && !(Util.HttpLike.includes(bufferProtocol) && Util.HttpLike.includes(urlProtocol))) { pager.alert("Blocked cross-protocol POST: " + url); return; } /* TODO this is horrible UX, async actions shouldn't block input */ const hover = URL.parse(this.hoverLink); let open = false; if (pager.buffer != this || !save && (hover == null || !Util.isSameAuthOrigin(hover, url))) { const x = await pager.ask("Open pop-up? " + url); open = x && (!save || !pager.gotoURLHash(request, this)); } else open = save || !pager.gotoURLHash(request, this); if (open) { pager.gotoURL(request, { contentType, save, referrer: this.init }); } break; } case "select": { const selected = await new Promise(resolve => { const selected = res.selected; this.select = new Select(res.options, selected, Math.max(this.acursorx - 1, 0), Math.max(this.acursory - 1 - selected, 0), this.width, this.height, resolve); pager.menu = this.select; }); if (pager.menu == this.select) pager.menu = null; this.select = null; iface.queueDraw(); const res2 = await iface.select(selected); return this.#onclick(res2); } case "read-password": case "read-text": { const text = await pager.setLineEdit("buffer", res.prompt, { current: res.value, hide: res.t == "read-password" }); if (text == null) return iface.readCanceled(); const res2 = await iface.readSuccess(text, -1); if (res2 != null) return this.#onclick(res2); break; } case "read-area": { const text = await pager.openEditor(res.value); if (text == null) return iface.readCanceled(); return iface.readSuccess(text, -1); } case "read-file": { const text = await pager.setLineEdit("download", "(Upload)Filename: "); if (text == null) return iface.readCanceled(); const path = Util.unquote(text, Util.getcwd()); if (path == null) { pager.alert("Invalid path: " + path); return iface.readCanceled(); } const fd = Util.openFile(path); if (fd < 0) { pager.alert("File not found"); return iface.readCanceled(); } if (!Util.isFile(fd)) { Util.closeFile(fd); pager.alert("Not a file: " + path); return iface.readCanceled(); } const name = path.substring(path.lastIndexOf('/') + 1); const res2 = await iface.readSuccess(name, fd); if (res2 != null) return this.#onclick(res2); }} } /* private */ setTab(tab) { const oldTab = this.tab; if (oldTab != null) this.#remove(); this.tab = tab; if (tab != null) { if (tab.current == null) tab.current = tab.head = this; else tab.current.#append(this); } if (oldTab != null && oldTab.current == null) return oldTab; return null; } /* private */ markPos0() { if (this.iface != null) this.iface.markPos0(); } /* private */ markPos() { if (this.iface != null) this.iface.markPos(); } /* private */ onMatch(x, y, w, refresh) { const iface = this.iface; if (y >= 0) { this.setCursorXYCenter(x, y, refresh); if (this.highlight) { iface.clearSearchHighlights(); iface.addSearchHighlight(x, y, x + w - 1, y); this.highlight = false; } } else if (this.highlight) { iface.clearSearchHighlights(); this.highlight = false; } } /* private */ async cursorNextMatch(re, wrap, refresh, n) { if (this.select) return this.select.cursorNextMatch(re, wrap, n); const iface = this.iface; const cx = this.cursorx; const cy = this.cursory; if (iface == null) return; const [x, y, w] = await iface.findNextMatch(re, cx, cy, wrap, n); this.onMatch(x, y, w, refresh); } /* private */ async cursorPrevMatch(re, wrap, refresh, n) { if (this.select) return this.select.cursorPrevMatch(re, wrap, n); const iface = this.iface; const cx = this.cursorx; const cy = this.cursory; if (iface == null) return; const [x, y, w] = await iface.findPrevMatch(re, cx, cy, wrap, n); this.onMatch(x, y, w, refresh); } /* private */ async #cursorPrevWordImpl(re, n = 1) { const cx = this.cursorx; const cy = this.cursory; const [x, y, w] = await this.findPrevMatch(re, cx, cy, false, n); if (y >= 0) this.setCursorXY(x + w - 1, y); else this.cursorLineBegin(); } /* private */ async #cursorNextWordImpl(re, n = 1) { const cx = this.cursorx; const cy = this.cursory; const [x, y, w] = await this.findNextMatch(re, cx, cy, false, n); if (y >= 0 && x >= 0) this.setCursorXY(x + w - 1, y); else this.cursorLineEnd(); } /* public */ findPrevMatch(regex, x, y, wrap = false, n = 1) { return this.iface.findPrevMatch(regex, x, y, wrap, n); } /* public */ findNextMatch(regex, x, y, wrap = false, n = 1) { return this.iface.findNextMatch(regex, x, y, wrap, n); } /* private */ startSelection(t, mouse, x1 = undefined) { const iface = this.iface; if (iface == null) return; x1 ??= iface.cursorFirstX; const selection = iface.startSelection(t, mouse, x1, this.cursory, this.cursorx, this.cursory) this.currentSelection = selection; return selection; } /* private */ clearSelection() { const iface = this.iface; if (iface == null) return; iface.removeHighlight(this.currentSelection); this.currentSelection = null; } /* private */ cancel() { const iface = this.iface; if (iface != null && iface.loadState != "loading") return; this.loadState = "canceled"; this.setLoadInfo(""); if (iface != null) iface.cancel(); else { pager.numload--; pager.deleteBuffer(this, this.find("any")); } pager.alert("Canceled loading") } /* private */ setLoadInfo(msg) { this.init.loadInfo = msg; pager.copyLoadInfo(this.init); } /* private */ async submitForm() { const iface = this.iface; if (iface == null) return; const res = await iface.submitForm(this.cursorx, this.cursory); return this.#onclick(res); } /* public */ get numLines() { return this.iface?.numLines ?? 0; } /* public */ get url() { return this.init.url; } /* public */ get cacheId() { return this.init.cacheId; } /* public */ get width() { return this.init.width; } /* public */ get height() { return this.init.height; } /* public */ get title() { return this.init.title; } /* public */ get process() { return this.iface?.process ?? -1; } /* public */ get cursorx() { return this.iface?.cursorx ?? 0; } /* public */ get cursory() { return this.iface?.cursory ?? 0; } /* public */ get fromx() { return this.iface?.fromx ?? 0; } /* public */ get fromy() { return this.iface?.fromy ?? 0; } /* public */ get hoverLink() { return this.iface?.hoverLink ?? ""; } /* public */ get hoverTitle() { return this.iface?.hoverTitle ?? ""; } /* public */ get hoverImage() { return this.iface?.hoverImage ?? ""; } /* private */ get hoverCachedImage() { return this.iface?.hoverCachedImage ?? ""; } /* public */ find(dir) { switch (dir) { case "prev": return this.prev; case "next": return this.next; case "any": return this.prev ?? this.next; default: throw new TypeError("unexpected direction"); } } /* public */ setCursorX(x, refresh = true, save = true) { if (this.iface != null) { this.iface.setCursorX(x, refresh, save); if (this.currentSelection != null) { x = this.iface.cursorx; if (x != this.currentSelection.x2) { this.currentSelection.x2 = x; this.iface.queueDraw(); } } } } /* public */ setCursorY(y, refresh = true) { if (this.iface != null) { const oy = this.iface.cursory; this.iface.setCursorY(y, refresh); if (oy != y) { pager.queueStatusUpdate(); if (this.currentSelection != null && y != this.currentSelection.y2) { this.currentSelection.y2 = y this.iface.queueDraw(); } } } } /* public */ setFromX(x, refresh = true) { if (this.iface != null) this.iface.setFromX(x, refresh); } /* public */ setFromY(y) { if (this.iface != null) this.iface.setFromY(y); } /* public */ cursorDown(n = 1) { this.setCursorY(this.cursory + n); } /* public */ cursorUp(n = 1) { this.setCursorY(this.cursory - n); } /* public */ cursorLeft(n = 1) { this.setCursorX((this.iface?.cursorFirstX ?? 0) - n); } /* public */ cursorRight(n = 1) { this.setCursorX((this.iface?.cursorLastX ?? 0) + n); } /* private */ shiftScreenDown(n = 1) { const H = this.numLines; const y = Math.min(this.fromy + this.height + n, H) - this.height; if (y > this.fromy) { this.setFromY(y); return true; } return false; } /* private */ shiftScreenUp(n = 1) { const y = Math.max(this.fromy - n, 0); if (y < this.fromy) { this.setFromY(y); return true; } return false; } /* private */ shiftScreenRight(n = 1) { const iface = this.iface; if (iface == null) return; const msw = iface.maxScreenWidth(); const x = Math.min(this.fromx + this.width + n, msw) - this.width; if (x > this.fromx) this.setFromX(x, false); } /* private */ shiftScreenLeft(n = 1) { const x = Math.max(this.fromx - n, 0); if (x < this.fromx) this.setFromX(x, false); } /* public */ scrollDown(n = 1) { if (this.shiftScreenDown(n)) { const dy = this.fromy - this.cursory; if (dy > 0) this.cursorDown(dy); } else this.cursorDown(n); } /* public */ scrollUp(n = 1) { if (this.shiftScreenUp(n)) { const dy = this.cursory - this.fromy - this.height + 1; if (dy > 0) this.cursorUp(dy); } else this.cursorUp(n); } /* public */ scrollRight(n = 1) { const iface = this.iface; if (iface == null) return; const msw = iface.maxScreenWidth(); const x = Math.min(this.fromx + this.width + n, msw) - this.width; if (x > this.fromx) this.setFromX(x); } /* public */ scrollLeft(n = 1) { const x = Math.max(this.fromx - n, 0); if (x < this.fromx) this.setFromX(x); } /* public */ pageDown(n = 1) { const iface = this.iface; if (iface == null) return; const delta = this.height * n; this.setFromY(this.fromy + delta); this.setCursorY(this.cursory + delta); } /* public */ pageUp(n = 1) { this.pageDown(-n); } /* public */ pageLeft(n = 1) { this.setFromX(this.fromx - this.width * n); } /* public */ pageRight(n = 1) { this.setFromX(this.fromx + this.width * n); } /* I am not cloning the vi behavior of e.g. 2^D setting paging size because * it is counter-intuitive and annoying. */ /* public */ halfPageDown(n = 1) { const iface = this.iface; if (iface == null) return; const delta = (this.height + 1) / 2 * n; this.setFromY(this.fromy + delta); this.setCursorY(this.cursory + delta); } /* public */ halfPageUp(n = 1) { this.halfPageDown(-n); } /* public */ halfPageLeft(n = 1) { this.setFromX(this.fromx - (this.width + 1) / 2 * n); } /* public */ halfPageRight(n = 1) { this.setFromX(this.fromx + (this.width + 1) / 2 * n); } /* public */ cursorTop(n = 1) { this.markPos0(); this.setCursorY(this.fromy + Util.clamp(n - 1, 0, this.height - 1)); this.markPos(); } /* public */ cursorMiddle() { this.markPos0(); this.setCursorY(this.fromy + (this.height - 2) / 2); this.markPos(); } /* public */ cursorBottom(n = 1) { this.markPos0(); this.setCursorY(this.fromy + this.height - Util.clamp(n, 0, this.height)); this.markPos(); } /* public */ cursorLeftEdge() { this.setCursorX(this.fromx); } /* public */ cursorMiddleColumn() { this.setCursorX(this.fromx + (this.width - 2) / 2); } /* public */ cursorRightEdge() { this.setCursorX(this.fromx + this.width - 1); } /* public */ setMark(id, x = this.cursorx, y = this.cursory) { if (this.iface == null) return false; return this.iface.setMark(id, x, y); } /* public */ clearMark(id) { if (this.iface == null) return false; return this.iface.clearMark(id); } /* public */ getMarkPos(id) { if (this.iface == null) return null; return this.iface.getMarkPos(id); } /* public */ findNextMark(id, x = this.cursorx, y = this.cursory) { if (this.iface == null) return false; return this.iface.findNextMark(id, x, y); } /* public */ findPrevMark(id, x = this.cursorx, y = this.cursory) { if (this.iface == null) return false; return this.iface.findPrevMark(id, x, y); } /* public */ cursorPrevWord(n) { return this.#cursorPrevWordImpl(ReWordEnd, n); } /* public */ cursorPrevViWord(n) { return this.#cursorPrevWordImpl(ReViWordEnd, n); } /* public */ cursorPrevBigWord(n) { return this.#cursorPrevWordImpl(ReBigWordEnd, n); } /* public */ cursorNextWord(n) { return this.#cursorNextWordImpl(ReWordStart, n); } /* public */ cursorNextViWord(n) { return this.#cursorNextWordImpl(ReViWordStart, n); } /* public */ cursorNextBigWord(n) { return this.#cursorNextWordImpl(ReBigWordStart, n); } /* public */ cursorWordBegin(n) { return this.#cursorPrevWordImpl(ReWordStart, n); } /* public */ cursorViWordBegin(n) { return this.#cursorPrevWordImpl(ReViWordStart, n); } /* public */ cursorBigWordBegin(n) { return this.#cursorPrevWordImpl(ReBigWordStart, n); } /* public */ cursorWordEnd(n) { return this.#cursorNextWordImpl(ReWordEnd, n); } /* public */ cursorViWordEnd(n) { return this.#cursorNextWordImpl(ReViWordEnd, n); } /* public */ cursorBigWordEnd(n) { return this.#cursorNextWordImpl(ReBigWordEnd, n); } /* public */ async getCurrentWord(x = this.cursorx, y = this.cursory) { const iface = this.iface if (iface == null) return; let p1 = iface.findPrevMatch(ReViWordStart, x + 1, y, false, 1); let p2 = iface.findNextMatch(ReViWordEnd, x - 1, y, false, 1); let [x1, y1, w1] = await p1; let [x2, y2, w2] = await p2; if (y1 < y) x1 = 0; if (y2 > y) x2 = 0; return iface.getSelectionText(x1, y, x2, y, "normal"); } /* zb */ /* public */ lowerPage(n) { if (n) this.setCursorY(n - 1); this.setFromY(this.cursory - this.height + 1); } /* z- */ /* public */ lowerPageBegin(n) { this.lowerPage(n); this.cursorLineTextStart() } /* zz */ /* public */ centerLine(n = 0) { if (n != 0) this.setCursorY(n - 1); this.setFromY(this.cursory - this.height / 2); } /* public */ centerColumn() { this.setFromX(this.cursorx - this.width / 2); } /* public */ setFromXY(x, y) { this.setFromY(y); this.setFromX(x); } /* public */ setCursorXY(x, y, refresh = true) { this.setCursorY(y, refresh); this.setCursorX(x, refresh); } /* public */ setCursorXYCenter(x, y, refresh = true) { const fy = this.fromy; const fx = this.fromx; this.setCursorXY(x, y, refresh); if (fy != this.fromy) this.centerLine(); if (fx != this.fromx) this.centerColumn(); } /* z. */ /* public */ centerLineBegin(n) { this.centerLine(n); this.cursorLineTextStart(); } /* zt */ /* public */ raisePage(n) { if (n) this.setCursorY(n - 1); this.setFromY(this.cursory); } /* z^M */ /* public */ raisePageBegin(n) { this.raisePage(n); this.cursorLineTextStart(); } /* z+ */ /* public */ nextPageBegin(n) { this.setCursorY(n ? n - 1 : this.fromy + this.height); this.cursorLineTextStart(); this.raisePage(); } /* z^ */ /* public */ previousPageBegin(n) { this.setCursorY(n ? n - this.height : this.fromy - 1); /* +-1 cancels out */ this.cursorLineTextStart(); this.lowerPage(); } /* public */ cursorToggleSelection(n = 1, opts = {}) { if (this.currentSelection) { this.clearSelection(); return null; } const cx = this.iface?.cursorFirstX ?? 0; this.cursorRight(n - 1); return this.startSelection(opts.selectionType ?? "normal", false, cx); } /* public */ cursorLineBegin() { this.setCursorX(-1); } /* public */ cursorLineEnd() { this.setCursorX(Util.MAX_INT32); } /* public */ cursorLineTextStart() { const iface = this.iface; if (iface == null) return; const [s, e] = iface.matchFirst(/\S/, this.cursory); if (s >= 0) { const x = iface.currentLineWidth(0, s); this.setCursorX(x > 0 ? x : x - 1); } else this.cursorLineEnd(); } /* public */ async cursorNextParagraph(n = 1) { const iface = this.iface; if (iface == null) return; this.markPos0(); const y = await iface.findNextParagraph(this.cursory, n); this.setCursorY(y) this.markPos(); } /* public */ async cursorPrevParagraph(n = 1) { return this.cursorNextParagraph(-n); } /* public */ async cursorNextLink(n = 1) { const iface = this.iface; if (iface == null) return; this.markPos0(); const [x, y] = await iface.findNextLink(this.cursorx, this.cursory, n); if (y >= 0) { this.setCursorXY(x, y); this.markPos(); } } /* public */ async cursorPrevLink(n = 1) { const iface = this.iface; if (iface == null) return; this.markPos0(); const [x, y] = await iface.findPrevLink(this.cursorx, this.cursory, n); if (y >= 0) { this.setCursorXY(x, y); this.markPos(); } } /* public */ async cursorNthLink(n = 1) { const iface = this.iface; if (iface == null) return; const pos = await iface.findNextLink(0, 0, n); if (y >= 0) this.setCursorXYCenter(...pos); } /* public */ async cursorRevNthLink(n = 1) { const iface = this.iface; if (iface == null) return; const pos = await iface.findRevNthLink(n); if (y >= 0) this.setCursorXYCenter(...pos); } /* public */ async cursorLinkNavDown(n = 1) { const iface = this.iface; if (iface == null) return; this.markPos0(); const [x, y] = await iface.findNextLink(this.cursorx, this.cursory, n); if (y < 0) { if (this.numLines <= this.height) { const [x2, y2] = await iface.findNextLink(-1, 0, 1); this.setCursorXYCenter(x2, y2); } else this.pageDown(); this.markPos(); } else if (y < this.fromy + this.height) { this.setCursorXYCenter(x, y); this.markPos(); } else { this.pageDown(); if (y < this.fromy + this.height) { this.setCursorXYCenter(x, y); this.markPos() } } } /* public */ async cursorLinkNavUp(n = 1) { const iface = this.iface; if (iface == null) return; const [x, y] = await iface.findPrevLink(this.cursorx, this.cursory, n); if (y < 0) { const numLines = this.numLines; if (numLines <= this.height) { const [x2, y2] = await iface.findPrevLink(Util.MAX_INT32, numLines - 1, 1); this.setCursorXYCenter(x2, y2); } else this.pageUp(); this.markPos(); } else if (y >= this.fromy) { this.setCursorXYCenter(x, y); this.markPos(); } else { this.pageUp(); if (y >= this.fromy) { this.setCursorXYCenter(x, y); this.markPos(); } } } /* public */ cursorFirstLine() { this.markPos0(); this.setCursorY(0); this.markPos(); } /* public */ cursorLastLine() { this.markPos0(); this.setCursorY(this.numLines - 1); this.markPos(); } /* public */ gotoMark(id) { const pos = this.getMarkPos(id); if (pos == null) return false; this.markPos0(); this.setCursorXYCenter(...pos); this.markPos(); return true; } /* public */ gotoMarkY(id) { const pos = this.getMarkPos(id); if (pos == null) return false; this.markPos0(); this.setCursorXYCenter(0, pos[1]); this.markPos(); return true; } /* public */ setCursorYCenter(y) { const fy = this.fromy; this.setCursorY(y); if (fy != this.fromy) this.centerLine(); } /* public */ setCursorXCenter(x) { const fx = this.fromx; this.setCursorX(x); if (fx != this.fromx) this.centerColumn(); } /* public */ setAbsoluteCursorXY(x, y) { this.setCursorXY(this.fromx + x, this.fromy + y); } /* public */ async markURL() { const iface = this.iface; if (iface == null) return; await iface.markURL(); return iface.sendCursorPosition(); } /* public */ reshape() { const iface = this.iface; if (iface == null) return; if (pager.bufferInit == this.init) pager.setVisibleBuffer(this); return iface.forceReshape(); } /* public */ editSource() { const url = pager.url; const path = url.protocol == "file:" ? decodeURIComponent(url.pathname) : pager.cacheFile; pager.extern(pager.getEditorCommand(path)); } /* public */ saveSource() { pager.gotoURL("cache:" + this.cacheId, {save: true, url: this.url}); } /* public */ async toggleImages() { const iface = this.iface; if (iface == null) return; this.init.images = await iface.toggleImages(); } /* public */ async click(n = 1) { const iface = this.iface; if (iface == null) return; const res = await iface.click(this.cursorx, this.cursory, n); return this.#onclick(res); } /* public */ async saveLink() { const iface = this.iface; if (iface == null) return; const res = await iface.click(this.cursorx, this.cursory, 1); return this.#onclick(res, true); } /* public */ showLinkHints = async function() { const iface = this.iface; if (iface == null) return []; const sx = this.fromx; const sy = this.fromy; const ex = sx + this.width; const ey = sy + this.height; return iface.showHints(sx, sy, ex, ey); } /* private */ hideLinkHints() { const iface = this.iface; if (iface == null) return; return iface.hideHints(); } /* private */ contextMenu() { const iface = this.iface; if (iface == null) return; return iface.contextMenu(this.cursorx, this.cursory); } /* public */ getSelectionText(sel = this.currentSelection) { const iface = this.iface; if (iface == null || sel == null) return ""; return iface.getSelectionText(sel.startx, sel.starty, sel.endx, sel.endy, sel.selectionType) } /* public */ async saveScreen() { let path = await pager.setLineEdit("download", "Save buffer to: "); if (path == null) return; path = Util.unquote(path, Util.getcwd()); const iface = this.iface; if (iface == null) { pager.alert("page is not loaded yet"); return; } const text = await iface.getSelectionText(0, 0, 0, this.numLines, "line"); try { writeFile(path, text); } catch (e) { pager.alert(e); } } /* public */ async editScreen() { const iface = this.iface; if (iface == null) { pager.alert("page is not loaded yet"); return; } const text = await iface.getSelectionText(0, 0, 0, this.numLines, "line"); try { const tmp = pager.getTempFile(); writeFile(tmp, text); const cmd = pager.getEditorCommand(tmp); if (cmd == "") throw new TypeError("invalid external.editor command"); pager.extern(cmd); } catch (e) { pager.alert(e); } } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/io/�������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0014330�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/io/chafile.nim��������������������������������������������������������������������0000664�0000000�0000000�00000013327�15202323131�0016436�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# syncio, but without the exceptions. {.push raises: [].} import std/posix import io/dynstream import types/opt import utils/twtstr type CFile {.importc: "FILE", header: "<stdio.h>", incompleteStruct.} = object ChaFile* = ptr CFile let EOF {.importc, header: "<stdio.h>".}: cint let SEEK_SET {.importc, header: "<stdio.h>".}: cint {.push importc, header: "<stdio.h>".} proc fopen(pathname, mode: cstring): ChaFile proc fdopen(fd: cint; mode: cstring): ChaFile proc fflush(f: ChaFile): cint proc fclose(f: ChaFile): cint proc rename(oldname, newname: cstring): cint proc fwrite(p: pointer; size, nmemb: csize_t; f: ChaFile): csize_t proc fread(p: pointer; size, nmemb: csize_t; f: ChaFile): csize_t proc fputc(c: cint; file: ChaFile): cint proc fputs(s: cstring; file: ChaFile): cint proc fgetc(file: ChaFile): cint proc fgets(s: cstring; n: cint; file: ChaFile): cstring proc ferror(file: ChaFile): cint proc popen*(cmd, t: cstring): ChaFile proc pclose*(file: ChaFile): cint proc fseek(file: ChaFile; offset: clong; whence: cint): cint {.pop.} # importc, header: "<stdio.h>" proc rename*(oldname, newname: string): Opt[void] = if rename(cstring(oldname), cstring(newname)) != 0: return err() ok() proc fopen*(name: string; mode: cstring): Opt[ChaFile] = let file = fopen(cstring(name), mode) if file == nil: return err() ok(file) proc fdopen*(ps: PosixStream; mode: cstring): Opt[ChaFile] = let file = fdopen(ps.fd, mode) if file == nil: ps.sclose() return err() ok(file) # Some Nim versions can't deal with overloading cstring and openArray[char], # better use a different name. proc writecstr*(file: ChaFile; s: cstring): Opt[void] = if fputs(s, file) == EOF: return err() ok() proc write*(file: ChaFile; s: openArray[uint8]): Opt[void] = if s.len > 0: if fwrite(unsafeAddr s[0], 1, csize_t(s.len), file) != csize_t(s.len): return err() ok() proc write*(file: ChaFile; s: openArray[char]): Opt[void] = if s.len > 0: if fwrite(unsafeAddr s[0], 1, csize_t(s.len), file) != csize_t(s.len): return err() ok() proc read*(file: ChaFile; s: var openArray[uint8]): int = if s.len > 0: return cast[int](fread(addr s[0], 1, csize_t(s.len), file)) return 0 proc read*(file: ChaFile; s: var openArray[char]): int = if s.len > 0: return cast[int](fread(addr s[0], 1, csize_t(s.len), file)) return 0 proc write*(file: ChaFile; c: char): Opt[void] = if fputc(cint(c), file) != cint(c): return err() ok() proc writeLine*(file: ChaFile): Opt[void] = file.write('\n') proc writeLine*(file: ChaFile; s: openArray[char]): Opt[void] = ?file.write(s) file.writeLine() proc writeCRLine*(file: ChaFile; s: openArray[char]): Opt[void] = ?file.write(s) ?file.write('\r') file.writeLine() proc readLineAppend*(file: ChaFile; s: var string): Opt[bool] = while (let c = file.fgetc(); c != EOF): let cc = cast[char](c) if cc == '\n': return ok(true) s &= cc if ferror(file) != 0: return err() ok(false) proc readLine*(file: ChaFile; s: var string): Opt[bool] = var i = 0 var bufLen = cint(80) s.setLen(int(bufLen)) zeroMem(addr s[0], 80) while true: if fgets(cast[cstring](addr s[i]), bufLen - cast[cint](i), file) == nil: break i = s.find('\n', i) if i >= 0: s.setLen(i) return ok(true) i = int(bufLen - 1) bufLen += 128 s.setLen(int(bufLen)) if i > 0: # got EOF before EOL? s.setLen(i) return ok(true) s = "" if ferror(file) != 0: return err() return ok(false) proc readAll*(file: ChaFile; s: var string): Opt[void] = s = newString(4096) var n = 0 while true: let avail = s.len - n let m = file.read(s.toOpenArray(n, s.len - 1)) n += m if n == s.len: s.setLen(s.len + 4096) if m < avail: break s.setLen(n) if ferror(file) != 0: return err() ok() proc flush*(file: ChaFile): Opt[void] = if fflush(file) != 0: return err() ok() proc close*(file: ChaFile): Opt[void] {.discardable.} = if fclose(file) != 0: return err() ok() proc readFile*(path: string; s: var string): Opt[void] = let file = ?fopen(path, "r") let res = file.readAll(s) ?file.close() res proc writeFile*(path: string; content: openArray[char]; mode: cint): Opt[void] = discard unlink(cstring(path)) let ps = newPosixStream(path, O_CREAT or O_WRONLY or O_EXCL, mode) if ps == nil: return err() let file = ?ps.fdopen("w") let res = file.write(content) ?file.close() res proc seek*(file: ChaFile; offset: clong): Opt[void] = if fseek(file, offset, SEEK_SET) != 0: return err() ok() when defined(gcDestructors): type AChaFile* = object p: ChaFile proc `=destroy`(f: var AChaFile) = if f.p != nil: discard f.p.fclose() proc `=wasMoved`(f: var AChaFile) = f.p = nil proc `=copy`(a: var AChaFile; b: AChaFile) {.error.} = discard proc afopen*(name: string; mode: cstring): Opt[AChaFile] = let p = ?fopen(name, mode) ok(AChaFile(p: p)) proc afdopen*(ps: PosixStream; mode: cstring): Opt[AChaFile] = let p = ?ps.fdopen(mode) ok(AChaFile(p: p)) proc read*(file: AChaFile; s: var openArray[uint8]): int = file.p.read(s) proc read*(file: AChaFile; s: var openArray[char]): int = file.p.read(s) proc readLine*(file: AChaFile; s: var string): Opt[bool] = file.p.readLine(s) proc write*(file: AChaFile; s: openArray[char]): Opt[void] = file.p.write(s) proc writeLine*(file: AChaFile; s: openArray[char]): Opt[void] = file.p.writeLine(s) proc writeCRLine*(file: AChaFile; s: openArray[char]): Opt[void] = file.p.writeCRLine(s) proc flush*(file: AChaFile): Opt[void] = file.p.flush() proc seek*(file: AChaFile; offset: clong): Opt[void] = file.p.seek(offset) {.pop.} # raises: [] ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/io/console.nim��������������������������������������������������������������������0000664�0000000�0000000�00000005171�15202323131�0016503�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import io/chafile import monoucha/fromjs import monoucha/jsopaque import monoucha/jsutils import monoucha/quickjs import types/jsopt import types/opt import utils/twtstr type Console* = ref object err: ChaFile # Forward declarations proc flush*(console: Console) # Forward declaration hacks # set in html/env var getConsoleImpl*: proc(ctx: JSContext): Console {.nimcall, raises: [].} proc newConsole*(err: ChaFile): Console = return Console(err: err) proc setStream*(console: Console; file: ChaFile; close: bool) = if console.err != nil and close: discard console.err.close() console.err = file proc write*(console: Console; s: openArray[char]) = discard console.err.write(s) proc write*(console: Console; c: char) = console.write([c]) proc log*(console: Console; ss: varargs[string]) = var buf = "" for i, s in ss.mypairs: buf &= s if i != ss.high: buf &= ' ' buf &= '\n' console.write(buf) proc error*(console: Console; ss: varargs[string]) = console.log(ss) proc jsConsoleLog(ctx: JSContext; this: JSValueConst; argc: cint; argv: JSValueConstArray): JSValue {.cdecl.} = let console = ctx.getConsoleImpl() var buf = "" let H = argc - 1 for i, val in argv.toOpenArray(0, H): var res: string ?ctx.fromJS(val, res) buf &= res if i != H: buf &= ' ' buf &= '\n' console.write(buf) console.flush() return JS_UNDEFINED proc jsConsoleClear(ctx: JSContext; this: JSValueConst; argc: cint; argv: JSValueConstArray): JSValue {.cdecl.} = return JS_UNDEFINED let jsConsoleFuncs {.global.} = [ JS_CFUNC_DEF("log", 0, jsConsoleLog), # For now, these are the same as log(). JS_CFUNC_DEF("debug", 0, jsConsoleLog), JS_CFUNC_DEF("error", 0, jsConsoleLog), JS_CFUNC_DEF("info", 0, jsConsoleLog), JS_CFUNC_DEF("warn", 0, jsConsoleLog), JS_CFUNC_DEF("clear", 0, jsConsoleClear), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "console", JS_PROP_CONFIGURABLE), ] proc addConsoleModule*(ctx: JSContext): Opt[void] = # console doesn't really look like other WebIDL interfaces; it's just an # object with a couple functions assigned. let console = JS_NewObject(ctx) if JS_IsException(console): return err() if not ctx.setPropertyFunctionList(console, jsConsoleFuncs): JS_FreeValue(ctx, console) return err() case ctx.definePropertyCW(ctx.getOpaque().global, "console", console) of dprException: return err() else: return ok() proc flush*(console: Console) = discard console.err.flush() proc writeException*(console: Console; ctx: JSContext) = console.write(ctx.getExceptionMsg()) console.flush() {.pop.} # raises: [] �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/io/dynstream.nim������������������������������������������������������������������0000664�0000000�0000000�00000024237�15202323131�0017053�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/posix import types/opt type PosixStream* = ref object fd*: cint blocking*: bool isend*: bool closed: bool # Like read(3), this may return a result that is lower than `len`, and that # does not mean the stream is finished. # isend is set when the end of the stream is reached. If the user is # trying to read after isend is set, we assert. proc read*(s: PosixStream; buffer: pointer; len: int): int = let n = read(s.fd, buffer, len) if n == 0: assert not s.isend s.isend = true return n # See above, but with write(2) proc write*(s: PosixStream; buffer: pointer; len: int): int = return write(s.fd, buffer, len) proc sclose*(s: PosixStream) = assert not s.closed discard close(s.fd) s.closed = true proc read*(s: PosixStream; buffer: var openArray[uint8]): int {.inline.} = return s.read(addr buffer[0], buffer.len) proc read*(s: PosixStream; buffer: var openArray[char]): int {.inline.} = return s.read(addr buffer[0], buffer.len) proc write*(s: PosixStream; buffer: openArray[char]): int {.inline.} = return s.write(unsafeAddr buffer[0], buffer.len) proc write*(s: PosixStream; buffer: openArray[uint8]): int {.inline.} = return s.write(unsafeAddr buffer[0], buffer.len) proc readLoop*(s: PosixStream; buffer: pointer; len: int): Opt[void] = var n = 0 while n < len: let m = s.read(addr cast[ptr UncheckedArray[uint8]](buffer)[n], len - n) if m <= 0: return err() n += m ok() proc readLoop*(s: PosixStream; buffer: var openArray[uint8]): Opt[void] = if buffer.len == 0: return ok() return s.readLoop(addr buffer[0], buffer.len) proc readLoop*(s: PosixStream; buffer: var openArray[char]): Opt[void] = if buffer.len == 0: return ok() return s.readLoop(addr buffer[0], buffer.len) proc writeLoop*(s: PosixStream; buffer: pointer; len: int): Opt[void] = var n = 0 while n < len: let p = addr cast[ptr UncheckedArray[uint8]](buffer)[n] let m = s.write(p, len - n) if m <= 0: return err() n += m ok() proc writeLoop*(s: PosixStream; buffer: openArray[uint8]): Opt[void] = if buffer.len > 0: return s.writeLoop(unsafeAddr buffer[0], buffer.len) ok() proc writeLoop*(s: PosixStream; buffer: openArray[char]): Opt[void] = if buffer.len > 0: return s.writeLoop(unsafeAddr buffer[0], buffer.len) ok() proc readAll*(s: PosixStream; buffer: var string): bool = assert s.blocking buffer = newString(4096) var idx = 0 while true: let n = s.read(addr buffer[idx], buffer.len - idx) if n == 0: break if n < 0: return false idx += n if idx == buffer.len: buffer.setLen(buffer.len + 4096) buffer.setLen(idx) true proc readAll*(s: PosixStream): string = discard s.readAll(result) proc setBlocking*(s: PosixStream; blocking: bool) = s.blocking = blocking let ofl = fcntl(s.fd, F_GETFL, 0) if blocking: discard fcntl(s.fd, F_SETFL, ofl and not O_NONBLOCK) else: discard fcntl(s.fd, F_SETFL, ofl or O_NONBLOCK) proc seek*(s: PosixStream; off: int64): int64 = return int64(lseek(s.fd, Off(off), SEEK_SET)) proc closeHandle(fd, flags: cint) = discard close(fd) let devnull = open("/dev/null", flags) if devnull == -1: quit(1) if devnull != fd: discard dup2(devnull, fd) discard close(devnull) proc closeStdin*() = closeHandle(0, O_RDONLY) proc closeStdout*() = closeHandle(1, O_WRONLY) proc closeStderr*() = closeHandle(2, O_WRONLY) # dup2 the stream to fd, close the old fd and set fd as the new fd # of ps. # If ps already points to fd, then do nothing. proc moveFd*(ps: PosixStream; fd: cint) = if ps.fd == fd: discard else: discard dup2(ps.fd, fd) discard close(ps.fd) ps.fd = fd proc isatty*(ps: PosixStream): bool = return ps.fd.isatty() == 1 proc newPosixStream*(fd: cint): PosixStream = return PosixStream(fd: fd, blocking: true) proc newPosixStream*(fd: SocketHandle): PosixStream = return newPosixStream(cint(fd)) proc newPosixStream*(path: string; flags = cint(O_RDONLY); mode = cint(0)): PosixStream = if path == "": return nil let fd = open(cstring(path), flags, mode) if fd == -1: return nil return newPosixStream(fd) type MaybeMappedMemory* = ptr MaybeMappedMemoryObj MaybeMappedMemoryType = enum mmmtMmap, mmmtAlloc, mmmtString MaybeMappedMemoryObj = object t: MaybeMappedMemoryType p0: pointer p0len: int p*: ptr UncheckedArray[uint8] len*: int proc mmap(ps: PosixStream; stats: Stat; ilen: int): MaybeMappedMemory = let srcOff = lseek(ps.fd, 0, SEEK_CUR) # skip headers doAssert srcOff >= 0 let p0len = int(stats.st_size) let len = int(stats.st_size - srcOff) if ilen != -1: doAssert ilen == len if len == 0: let res = create(MaybeMappedMemoryObj) res[] = MaybeMappedMemoryObj(t: mmmtMmap, p0: nil, p0len: 0, p: nil, len: 0) return res let p0 = mmap(nil, p0len, PROT_READ, MAP_PRIVATE, ps.fd, 0) if p0 == MAP_FAILED: return nil let p1 = addr cast[ptr UncheckedArray[uint8]](p0)[srcOff] let res = create(MaybeMappedMemoryObj) res[] = MaybeMappedMemoryObj( t: mmmtMmap, p0: p0, p0len: p0len, p: cast[ptr UncheckedArray[uint8]](p1), len: len ) return res # Try to mmap the stream, and return nil on failure. proc mmap*(ps: PosixStream): MaybeMappedMemory = var stats: Stat if fstat(ps.fd, stats) != -1: return ps.mmap(stats, -1) return nil # Read data of size "len", or mmap it if the stream is a file. # This may return nil. proc readLoopOrMmap*(ps: PosixStream; ilen: int): MaybeMappedMemory = var stats: Stat if fstat(ps.fd, stats) != -1 and S_ISREG(stats.st_mode): return ps.mmap(stats, ilen) let res = create(MaybeMappedMemoryObj) let p = cast[ptr UncheckedArray[uint8]](alloc(ilen)) if ps.readLoop(p, ilen).isErr: return nil res[] = MaybeMappedMemoryObj( t: mmmtAlloc, p0: p, p0len: ilen, p: p, len: ilen ) return res # Try to mmap the file, and fall back to readAll if it fails. # This never returns nil. proc readAllOrMmap*(ps: PosixStream): MaybeMappedMemory = var stats: Stat if fstat(ps.fd, stats) != -1 and S_ISREG(stats.st_mode): let res = ps.mmap(stats, -1) if res != nil: return res let res = create(MaybeMappedMemoryObj) let s = new(string) s[] = ps.readAll() GC_ref(s) let p = if s[].len > 0: cast[ptr UncheckedArray[uint8]](addr s[][0]) else: nil res[] = MaybeMappedMemoryObj( t: mmmtString, p0: cast[pointer](s), p0len: s[].len, p: p, len: s[].len ) return res proc maybeMmapForSend*(ps: PosixStream; len: int): MaybeMappedMemory = var stats: Stat if fstat(0, stats) != -1 and S_ISREG(stats.st_mode): if ps.seek(len - 1) < 0: return nil if ps.writeLoop([char(0)]).isErr: return nil let p0 = mmap(nil, len, PROT_WRITE, MAP_SHARED, ps.fd, 0) if p0 == MAP_FAILED: return nil let res = create(MaybeMappedMemoryObj) res[] = MaybeMappedMemoryObj( t: mmmtMmap, p0: p0, p0len: len, p: cast[ptr UncheckedArray[uint8]](p0), len: len ) return res let p = cast[ptr UncheckedArray[uint8]](alloc(len)) let res = create(MaybeMappedMemoryObj) res[] = MaybeMappedMemoryObj( t: mmmtAlloc, p0: p, p0len: len, p: p, len: len ) return res template toOpenArray*(mem: MaybeMappedMemory): openArray[char] = cast[ptr UncheckedArray[char]](mem.p).toOpenArray(0, mem.len - 1) proc writeLoop*(ps: PosixStream; mem: MaybeMappedMemory): Opt[void] = # only send if not mmapped; otherwise everything is already where it should be if mem.t != mmmtMmap: return ps.writeLoop(mem.toOpenArray()) ok() template dealloc*(mem: MaybeMappedMemory) {.error: "use deallocMem".} = discard proc deallocMem*(mem: MaybeMappedMemory) = case mem.t of mmmtMmap: if mem.p0len != 0: discard munmap(mem.p0, mem.p0len) of mmmtString: GC_unref(cast[ref string](mem.p0)) of mmmtAlloc: dealloc(mem.p0) dealloc(pointer(mem)) proc setCloseOnExec*(ps: PosixStream) = let ofd = fcntl(ps.fd, F_GETFD) discard fcntl(ps.fd, ofd or F_SETFD, FD_CLOEXEC) proc sendMsg*(s: PosixStream; buffer: openArray[uint8]; fds: openArray[cint]): int = assert buffer.len > 0 var iov = IOVec(iov_base: unsafeAddr buffer[0], iov_len: csize_t(buffer.len)) let fdSize = sizeof(cint) * fds.len let controlLen = cast[int](CMSG_SPACE(csize_t(fdSize))) var cmsgBuf = newSeq[uint8](controlLen) var hdr = Tmsghdr( msg_iov: addr iov, msg_iovlen: 1, msg_control: if cmsgBuf.len > 0: addr cmsgBuf[0] else: nil, msg_controllen: SockLen(controlLen) ) let cmsg = CMSG_FIRSTHDR(addr hdr) cmsg.cmsg_len = SockLen(CMSG_LEN(csize_t(fdSize))) cmsg.cmsg_level = SOL_SOCKET cmsg.cmsg_type = SCM_RIGHTS if fds.len > 0: copyMem(CMSG_DATA(cmsg), unsafeAddr fds[0], fdSize) return sendmsg(SocketHandle(s.fd), addr hdr, 0) proc recvMsg*(s: PosixStream; buffer: var openArray[uint8]; fdbuf: var openArray[cint]; numFds: var int): int = assert buffer.len > 0 var iov = IOVec(iov_base: addr buffer[0], iov_len: csize_t(buffer.len)) let fdbufSize = sizeof(cint) * fdbuf.len let controlLen = cast[int](CMSG_SPACE(csize_t(fdbufSize))) var cmsgBuf = newSeqUninit[uint8](controlLen) var hdr = Tmsghdr( msg_iov: addr iov, msg_iovlen: 1, msg_control: if cmsgBuf.len > 0: addr cmsgBuf[0] else: nil, msg_controllen: SockLen(controlLen) ) let n = recvmsg(SocketHandle(s.fd), addr hdr, 0) if n <= 0: return n numFds = 0 var cmsg = CMSG_FIRSTHDR(addr hdr) while cmsg != nil: let data = CMSG_DATA(cmsg) let size = int(cmsg.cmsg_len) - (cast[int](data) - cast[int](cmsg)) if cmsg.cmsg_level == SOL_SOCKET and cmsg.cmsg_type == SCM_RIGHTS and size mod sizeof(cint) == 0: let n = size div sizeof(cint) var m = min(fdbuf.len, numFds + n) - numFds copyMem(addr fdbuf[numFds], data, m * sizeof(cint)) numFds += m while m < n: var fd {.noinit.}: cint copyMem(addr fd, addr cast[ptr UncheckedArray[cint]](data)[m], sizeof(fd)) discard close(fd) else: #TODO we could just return -2 here, but I'm not sure if it can # ever happen assert false cmsg = CMSG_NXTHDR(addr hdr, cmsg) return n {.pop.} # raises: [] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/io/packetreader.nim���������������������������������������������������������������0000664�0000000�0000000�00000013230�15202323131�0017466�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/posix import std/tables import io/dynstream import types/color import types/opt type PacketReader* = object buffer: seq[uint8] bufIdx: int fds: seq[cint] PartialPacketReader* = object idx: int numFds: int lens: array[2 * sizeof(int), uint8] r*: PacketReader proc sread*(r: var PacketReader; n: var SomeNumber) proc sread*[T](r: var PacketReader; s: var set[T]) proc sread*[T: enum](r: var PacketReader; x: var T) proc sread*(r: var PacketReader; s: var string) proc sread*(r: var PacketReader; b: var bool) proc sread*(r: var PacketReader; tup: var tuple) proc sread*[I, T](r: var PacketReader; a: var array[I, T]) proc sread*[T](r: var PacketReader; s: var seq[T]) proc sread*[U, V](r: var PacketReader; t: var Table[U, V]) proc sread*(r: var PacketReader; obj: var object) proc sread*(r: var PacketReader; obj: var ref object) proc sread*(r: var PacketReader; c: var ARGBColor) proc sread*(r: var PacketReader; c: var CellColor) proc initReader*(stream: PosixStream; r: var PacketReader; len, nfds: int): bool = assert len != 0 or nfds != 0 r = PacketReader( buffer: newSeqUninit[uint8](len), fds: newSeqUninit[cint](nfds), bufIdx: 0 ) if stream.readLoop(r.buffer).isErr: return false if nfds > 0: # packetwriter added ancillary data. #TODO just use recvmsg for both? var dummy {.noinit.}: array[1, uint8] var numFds = 0 let n = stream.recvMsg(dummy, r.fds, numFds) if n < dummy.len: return false if numFds < nfds: for i in 0 ..< numFds: discard close(r.fds[i]) return false true proc initPacketReader*(stream: PosixStream; r: var PacketReader): bool = var len {.noinit.}: array[2, int] if stream.readLoop(addr len[0], sizeof(len)).isErr: return false return stream.initReader(r, len[0], len[1]) type PartialReaderCode* = enum prcEOF, prcDone, prcBuffer proc initPartialReader*(stream: PosixStream; pr: var PartialPacketReader): PartialReaderCode = if pr.r.bufIdx == pr.r.buffer.len and pr.r.fds.len == 0: # reset pr.idx = 0 pr.numFds = 0 if pr.idx < pr.lens.len: let n = stream.read(addr pr.lens[pr.idx], pr.lens.len - pr.idx) if n < 0: let e = errno if e == EAGAIN or e == EWOULDBLOCK or e == EINTR: return prcBuffer return prcEOF pr.idx += n if pr.idx < pr.lens.len: return prcBuffer var lens {.noinit.}: array[2, int] copyMem(addr lens[0], addr pr.lens[0], sizeof(lens)) pr.r = PacketReader( buffer: newSeqUninit[uint8](lens[0]), fds: newSeqUninit[cint](lens[1]) ) let dataIdx = pr.idx - pr.lens.len if dataIdx < pr.r.buffer.len: let n = stream.read(pr.r.buffer.toOpenArray(dataIdx, pr.r.buffer.high)) if n < 0: let e = errno if e == EAGAIN or e == EWOULDBLOCK or e == EINTR: return prcBuffer return prcEOF pr.idx += n if pr.idx - pr.lens.len < pr.r.buffer.len: return prcBuffer if pr.numFds < pr.r.fds.len: var dummy {.noinit.}: array[1, uint8] var numFds = 0 let n = stream.recvMsg(dummy, pr.r.fds.toOpenArray(pr.numFds, pr.r.fds.high), numFds) if n < 0: let e = errno if e == EAGAIN or e == EWOULDBLOCK or e == EINTR: return prcBuffer if n <= 0: return prcEOF pr.numFds += numFds if pr.numFds < pr.r.fds.len: return prcBuffer return prcDone proc assertEmpty(r: var PacketReader) = assert r.bufIdx == r.buffer.len and r.fds.len == 0 template withPacketReader*(stream: PosixStream; r, body, fallback: untyped) = block: var r: PacketReader if stream.initPacketReader(r): body r.assertEmpty() else: fallback template withPacketReaderFire*(stream: PosixStream; r, body: untyped) = stream.withPacketReader r: body do: discard proc readData*(r: var PacketReader; buffer: pointer; len: int) = assert r.bufIdx + len <= r.buffer.len copyMem(buffer, addr r.buffer[r.bufIdx], len) r.bufIdx += len proc recvFd*(r: var PacketReader): cint = return r.fds.pop() proc closeFds*(r: var PacketReader) = for fd in r.fds: discard close(fd) proc sread*(r: var PacketReader; n: var SomeNumber) = n = 0 r.readData(addr n, sizeof(n)) proc sread*[T: enum](r: var PacketReader; x: var T) = var i {.noinit.}: int r.sread(i) x = cast[T](i) proc sread*[T](r: var PacketReader; s: var set[T]) = r.readData(addr s, sizeof(s)) proc sread*(r: var PacketReader; s: var string) = var len {.noinit.}: int r.sread(len) s = newString(len) if len > 0: r.readData(addr s[0], len) proc sread*(r: var PacketReader; b: var bool) = var n: uint8 r.sread(n) if n == 1u8: b = true else: assert n == 0u8 b = false proc sread*(r: var PacketReader; tup: var tuple) = for f in tup.fields: r.sread(f) proc sread*[I; T](r: var PacketReader; a: var array[I, T]) = for x in a.mitems: r.sread(x) proc sread*[T](r: var PacketReader; s: var seq[T]) = var len {.noinit.}: int r.sread(len) s = newSeq[T](len) for x in s.mitems: r.sread(x) proc sread*[U; V](r: var PacketReader; t: var Table[U, V]) = var len {.noinit.}: int r.sread(len) t = initTable[U, V](len) for i in 0..<len: var k: U r.sread(k) var v: V r.sread(v) t[k] = v proc sread*(r: var PacketReader; obj: var object) = obj = default(typeof(obj)) for f in obj.fields: r.sread(f) proc sread*(r: var PacketReader; obj: var ref object) = var n: bool r.sread(n) if n: obj = new(typeof(obj)) r.sread(obj[]) else: obj = nil proc sread*(r: var PacketReader; c: var ARGBColor) = r.sread(uint32(c)) proc sread*(r: var PacketReader; c: var CellColor) = r.sread(uint32(c)) {.pop.} # raises: [] ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/io/packetwriter.nim���������������������������������������������������������������0000664�0000000�0000000�00000013021�15202323131�0017536�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Write data to streams in packets. # Each packet is prefixed with two pointer-sized integers; # the first one indicates the buffer's length, while the second one the # length of its ancillary data (i.e. the number of file descriptors # passed). {.push raises: [].} import std/algorithm import std/posix import std/tables import io/dynstream import types/color import types/opt type PacketWriter* = object buffer*: seq[uint8] bufLen*: int # file descriptors to send in the packet fds: seq[cint] type BufferPacketFun* = proc(opaque: RootRef; stream: PosixStream) {.nimcall, raises: [].} PacketBuffer* = object ws: seq[PacketWriter] wi: int # index into ws proc swrite*(w: var PacketWriter; n: SomeNumber) proc swrite*[T](w: var PacketWriter; s: set[T]) proc swrite*[T: enum](w: var PacketWriter; x: T) proc swrite*(w: var PacketWriter; s: string) proc swrite*(w: var PacketWriter; b: bool) proc swrite*(w: var PacketWriter; tup: tuple) proc swrite*[I, T](w: var PacketWriter; a: array[I, T]) proc swrite*[T](w: var PacketWriter; s: openArray[T]) proc swrite*[U, V](w: var PacketWriter; t: Table[U, V]) proc swrite*(w: var PacketWriter; obj: object) proc swrite*(w: var PacketWriter; obj: ref object) proc swrite*(w: var PacketWriter; c: ARGBColor) proc swrite*(w: var PacketWriter; c: CellColor) # consumes `fd' proc sendFd*(w: var PacketWriter; fd: cint) = w.fds.add(fd) const InitLen = sizeof(int) * 2 const SizeInit = max(64, InitLen) proc initPacketWriter*(): PacketWriter = return PacketWriter( buffer: newSeqUninit[uint8](SizeInit), bufLen: InitLen ) proc initPacketBuffer*(): PacketBuffer = PacketBuffer() proc writeSize*(w: var PacketWriter) = # subtract the length field's size let len = [w.bufLen - InitLen, w.fds.len] copyMem(addr w.buffer[0], unsafeAddr len[0], sizeof(len)) proc closeFds(w: var PacketWriter) = for fd in w.fds: discard close(fd) w.fds.setLen(0) # Returns false on EOF, true if we flushed successfully. proc flush*(w: var PacketWriter; stream: PosixStream): bool = w.writeSize() if stream.writeLoop(w.buffer.toOpenArray(0, w.bufLen - 1)).isErr: w.closeFds() return false if w.fds.len > 0: w.fds.reverse() let n = stream.sendMsg([0u8], w.fds) if n < 1: return false w.closeFds() w.bufLen = 0 true type FlushResult* = enum frEOF, frBuffer, frDone proc flush2(w: var PacketWriter; stream: PosixStream): FlushResult = let bufLen = w.bufLen let n = stream.write(w.buffer.toOpenArray(0, bufLen - 1)) if n < 0: let e = errno if e == EAGAIN or e == EWOULDBLOCK or e == EINTR: return frBuffer w.bufLen = 0 w.closeFds() return frEOF elif n < w.bufLen: let left = bufLen - n moveMem(addr w.buffer[0], addr w.buffer[n], left) w.bufLen = left return frBuffer w.bufLen = 0 w.buffer = @[] if w.fds.len > 0: w.fds.reverse() let n = stream.sendMsg([0u8], w.fds) assert n != 0 if n < 0: let e = errno if e == EAGAIN or e == EWOULDBLOCK or e == EINTR: w.fds.reverse() # will be reversed on next flush return frBuffer w.closeFds() return frEOF w.closeFds() frDone proc flush*(b: var PacketBuffer; stream: PosixStream): FlushResult = while b.wi < b.ws.len: let r = b.ws[b.wi].flush2(stream) if r != frDone: return r inc b.wi b.wi = 0 b.ws.setLen(0) frDone proc flush*(b: var PacketBuffer; w: var PacketWriter; stream: PosixStream): FlushResult = w.writeSize() b.ws.add(move(w)) b.flush(stream) template withPacketWriter*(stream: PosixStream; w, body, fallback: untyped) = var w = initPacketWriter() body if not w.flush(stream): fallback template withPacketWriterFire*(stream: PosixStream; w, body: untyped) = var w = initPacketWriter() body discard w.flush(stream) template withPacketWriter*(b: var PacketBuffer; stream: PosixStream; w, body, fallback: untyped) = var w = initPacketWriter() body if not b.flush(w): fallback proc writeData*(w: var PacketWriter; buffer: pointer; len: int) = let targetLen = w.bufLen + len let missing = targetLen - w.buffer.len if missing > 0: let target = max(w.buffer.len + missing, w.buffer.len * 2) w.buffer.setLen(target) copyMem(addr w.buffer[w.bufLen], buffer, len) w.bufLen = targetLen proc swrite*(w: var PacketWriter; n: SomeNumber) = w.writeData(unsafeAddr n, sizeof(n)) proc swrite*[T: enum](w: var PacketWriter; x: T) = static: doAssert sizeof(int) >= sizeof(T) w.swrite(int(x)) proc swrite*[T](w: var PacketWriter; s: set[T]) = w.writeData(unsafeAddr s, sizeof(s)) proc swrite*(w: var PacketWriter; s: string) = w.swrite(s.len) if s.len > 0: w.writeData(unsafeAddr s[0], s.len) proc swrite*(w: var PacketWriter; b: bool) = if b: w.swrite(1u8) else: w.swrite(0u8) proc swrite*(w: var PacketWriter; tup: tuple) = for f in tup.fields: w.swrite(f) proc swrite*[I, T](w: var PacketWriter; a: array[I, T]) = for x in a: w.swrite(x) proc swrite*[T](w: var PacketWriter; s: openArray[T]) = w.swrite(s.len) for x in s: w.swrite(x) proc swrite*[U, V](w: var PacketWriter; t: Table[U, V]) = w.swrite(t.len) for k, v in t: w.swrite(k) w.swrite(v) proc swrite*(w: var PacketWriter; obj: object) = for f in obj.fields: w.swrite(f) proc swrite*(w: var PacketWriter; obj: ref object) = w.swrite(obj != nil) if obj != nil: w.swrite(obj[]) proc swrite*(w: var PacketWriter; c: ARGBColor) = w.swrite(uint32(c)) proc swrite*(w: var PacketWriter; c: CellColor) = w.swrite(uint32(c)) {.pop.} # raises: [] ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/io/poll.nim�����������������������������������������������������������������������0000664�0000000�0000000�00000000472�15202323131�0016006�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������type PollType* = enum ptPoll = (1, "poll"), ptSelect = (2, "select") const forcePollMode {.intdefine.} = 0 const PollMode* = when forcePollMode != 0: PollType(forcePollMode) elif defined(macosx): ptSelect else: ptPoll when PollMode == ptSelect: include io/poll_select else: include io/poll_standard ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/io/poll_select.nim����������������������������������������������������������������0000664�0000000�0000000�00000006752�15202323131�0017354�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# macOS has no functional poll (it chokes on /dev/tty), so we instead # emulate it with select. {.passc: "-D_DARWIN_UNLIMITED_SELECT".} import std/posix type PollData* = object currentFd: cint nfds: cint fds: seq[cshort] readPool: seq[uint8] writePool: seq[uint8] errorPool: seq[uint8] template read(ctx: PollData): ptr TFdSet = cast[ptr TFdSet](unsafeAddr ctx.readPool[0]) template write(ctx: PollData): ptr TFdSet = cast[ptr TFdSet](unsafeAddr ctx.writePool[0]) template error(ctx: PollData): ptr TFdSet = cast[ptr TFdSet](unsafeAddr ctx.errorPool[0]) proc setFd(ctx: PollData; fd: cint) = let events = ctx.fds[int(fd)] if (events and POLLIN) != 0: FD_SET(fd, ctx.read[]) else: FD_CLR(fd, ctx.read[]) if (events and POLLOUT) != 0: FD_SET(fd, ctx.write[]) else: FD_CLR(fd, ctx.write[]) if (events and POLLERR) != 0: FD_SET(fd, ctx.error[]) else: FD_CLR(fd, ctx.error[]) iterator events*(ctx: var PollData): tuple[fd: cint; revents: cshort] = # Note that unlike in standard poll, ctx.nfds may change during the # iteration, and this is not a bug. In this case we just set up the # event post-addition. ctx.currentFd = 0 while ctx.currentFd < ctx.nfds: let fd = ctx.currentFd var revents = cshort(0) if FD_ISSET(fd, ctx.read[]) != 0: revents = revents or POLLIN if FD_ISSET(fd, ctx.write[]) != 0: revents = revents or POLLOUT if FD_ISSET(fd, ctx.error[]) != 0: revents = revents or POLLERR if revents != 0: yield (fd, revents) ctx.setFd(fd) inc ctx.currentFd proc register*(ctx: var PollData; fd: cint; events: cshort) = if fd >= ctx.nfds: let onfds = ctx.nfds ctx.nfds = fd + 1 if ctx.currentFd == onfds: # not in events iterator ctx.currentFd = ctx.nfds let infds = int(ctx.nfds) if infds > ctx.fds.len: if ctx.fds.len == 0: ctx.fds.setLen(64) else: ctx.fds.setLen(max(ctx.fds.len * 2, ((infds + 7) div 8) * 8)) assert ctx.fds.len mod 8 == 0 let sz = ctx.fds.len div 8 ctx.readPool.setLen(sz) ctx.writePool.setLen(sz) ctx.errorPool.setLen(sz) ctx.fds[int(fd)] = events or POLLERR # currentFd is always the next fd to be set. # if it points to us or a previous fd, then we must not set the event, # or else we'll get bogus events if fd < ctx.currentFd: ctx.setFd(fd) proc register*(ctx: var PollData; fd: int; events: cshort) = ctx.register(cint(fd), events) proc unregister*(ctx: var PollData; fd: int) = ctx.fds[fd] = cshort(0) # Mimic behavior of poll_standard: if unregister is called on an event # that has not been read yet, destroy said event. ctx.setFd(cint(fd)) proc clear*(ctx: var PollData) = # Do *not* set nfds to 0, because this is called from inside the # `events' iterator. for fd, it in ctx.fds.mpairs: it = 0 ctx.setFd(cint(fd)) proc trim(ctx: var PollData) = var i = ctx.nfds - 1 while i >= 0: if ctx.fds[int(i)] != 0: break dec i ctx.nfds = i + 1 proc poll*(ctx: var PollData; timeout: cint) = ctx.trim() var tv = Timeval( tv_sec: Time(max(timeout div 1000, 0)), tv_usec: Suseconds(max((timeout mod 1000) * 1000, 0)) ) let ptv = if timeout != -1: addr tv else: nil if ctx.nfds == 0: discard select(ctx.nfds, nil, nil, nil, ptv) else: let res = select(ctx.nfds, ctx.read, ctx.write, ctx.error, ptv) if res < 0: # error for fd in cint(0) ..< ctx.nfds: FD_CLR(fd, ctx.read[]) FD_CLR(fd, ctx.write[]) FD_CLR(fd, ctx.error[]) ����������������������chawan-v0.4.0/src/io/poll_standard.nim��������������������������������������������������������������0000664�0000000�0000000�00000004337�15202323131�0017672�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# poll wrapper for sane systems. # std only merged working bindings recently, so for now we have to bind # it on our own. from std/posix import TPollfd, POLLNVAL # NB: nfds_t on SVR4 was unsigned long, but BSDs use unsigned int. # Linux and Haiku emulate the former, BSDs inherit the latter. # ...except bionic copy-pasted from BSD headers, so it uses the latter # too. # Since there are less SVR4 imitators than BSD descendants, I'll use # the latter as the fallback. when defined(linux) and not defined(android) or defined(haiku): type nfds_t {.importc, header: "<poll.h>".} = culong else: type nfds_t {.importc, header: "<poll.h>".} = cuint const sizeofNfdsT = sizeof(nfds_t) {.emit: """ NIM_STATIC_ASSERT(`sizeofNfdsT` == sizeof(nfds_t), "nfds_t size mismatch; please report at https://todo.sr.ht/~bptato/chawan"); """.} proc poll(fds: ptr TPollfd; nfds: nfds_t; timeout: cint): cint {.cdecl, importc, header: "<poll.h>".} type PollData* = object fds: seq[TPollfd] iterator events*(ctx: var PollData): tuple[fd: cint; revents: cshort] = let L = ctx.fds.len for i in 0 ..< L: let event = ctx.fds[i] if event.fd == -1 or ctx.fds[i].revents == 0: continue assert (event.revents and POLLNVAL) == 0 yield (event.fd, event.revents) proc register*(ctx: var PollData; fd: int; events: cshort) = if fd >= ctx.fds.len: let olen = ctx.fds.len ctx.fds.setLen(fd + 1) for i in olen ..< fd: ctx.fds[i].fd = -1 ctx.fds[fd].fd = cint(fd) ctx.fds[fd].events = events proc register*(ctx: var PollData; fd: cint; events: cshort) = ctx.register(int(fd), events) proc unregister*(ctx: var PollData; fd: int) = ctx.fds[fd].fd = -1 proc trim(ctx: var PollData) = var i = ctx.fds.high while i >= 0: if ctx.fds[i].fd != -1: break dec i ctx.fds.setLen(i + 1) proc clear*(ctx: var PollData) = # Do *not* set fds' len to 0, because this is called from inside the # `events' iterator. for it in ctx.fds.mitems: it.fd = -1 it.revents = 0 proc poll*(ctx: var PollData; timeout: cint) = ctx.trim() let fds = if ctx.fds.len > 0: addr ctx.fds[0] else: nil let res = poll(fds, nfds_t(ctx.fds.len), timeout) if res < 0: # error for event in ctx.fds.mitems: event.revents = 0 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/io/timeout.nim��������������������������������������������������������������������0000664�0000000�0000000�00000007341�15202323131�0016530�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/algorithm import std/times import io/console import monoucha/fromjs import monoucha/jsutils import monoucha/quickjs type TimeoutType* = enum ttTimeout = "setTimeout handler" ttInterval = "setInterval handler" TimeoutEntry = ref object t: TimeoutType id: int32 val: JSValue args: seq[JSValue] expires: int64 timeout: int32 dead: bool EvalJSFree* = proc(opaque: RootRef; src, file: string) {.nimcall, raises: [].} TimeoutState* = ref object timeoutid: int32 sorted: bool timeouts: seq[TimeoutEntry] jsctx: JSContext jsrt: JSRuntime evalJSFree: EvalJSFree opaque: RootRef proc newTimeoutState*(jsctx: JSContext; evalJSFree: EvalJSFree; opaque: RootRef): TimeoutState = return TimeoutState( jsrt: JS_GetRuntime(jsctx), jsctx: jsctx, evalJSFree: evalJSFree, opaque: opaque, sorted: true ) proc empty*(state: TimeoutState): bool = return state.timeouts.len == 0 proc clearTimeout0(state: var TimeoutState; i: int) = let entry = state.timeouts[i] let rt = state.jsrt JS_FreeValueRT(rt, entry.val) rt.freeValues(entry.args) state.timeouts.del(i) if state.timeouts.len != i: # only set if we del'd in the middle state.sorted = false proc clearTimeout*(state: var TimeoutState; id: int32) = for entry in state.timeouts: if entry.id == id: entry.dead = true break proc getUnixMillis*(): int64 = let now = getTime() return now.toUnix() * 1000 + now.nanosecond div 1_000_000 proc setTimeout*(state: var TimeoutState; t: TimeoutType; handler: JSValueConst; timeout: int32; args: openArray[JSValueConst]): int32 = let id = state.timeoutid inc state.timeoutid let entry = TimeoutEntry( t: t, id: id, val: JS_DupValueRT(state.jsrt, handler), expires: getUnixMillis() + int64(timeout), timeout: timeout ) for arg in args: entry.args.add(JS_DupValueRT(state.jsrt, arg)) state.timeouts.add(entry) state.sorted = false return id proc runEntry(state: var TimeoutState; entry: TimeoutEntry; console: Console) = if JS_IsFunction(state.jsctx, entry.val): let ret = JS_Call(state.jsctx, entry.val, JS_UNDEFINED, cint(entry.args.len), entry.args.toJSValueArray()) if JS_IsException(ret): console.writeException(state.jsctx) JS_FreeValueRT(state.jsrt, ret) else: var s: string if state.jsctx.fromJS(entry.val, s).isOk: state.evalJSFree(state.opaque, s, $entry.t) # for poll proc sortAndGetTimeout*(state: var TimeoutState): cint = if state.timeouts.len == 0: return -1 if not state.sorted: state.timeouts.sort(proc(a, b: TimeoutEntry): int = cmp(a.expires, b.expires), order = Descending) state.sorted = true let now = getUnixMillis() return cint(max(state.timeouts[^1].expires - now, -1)) proc run*(state: var TimeoutState; console: Console): bool = let now = getUnixMillis() var found = false var H = state.timeouts.high for i in countdown(H, 0): if state.timeouts[i].expires > now: break let entry = state.timeouts[i] if entry.dead: continue state.runEntry(entry, console) found = true case entry.t of ttTimeout: entry.dead = true of ttInterval: entry.expires = now + entry.timeout state.sorted = false # we can't just delete timeouts in the above loop, because the JS # timeout handler may clear them in an arbitrary order H = state.timeouts.high for i in countdown(H, 0): if state.timeouts[i].dead: state.clearTimeout0(i) return found proc clearAll*(state: var TimeoutState) = let rt = state.jsrt for entry in state.timeouts: JS_FreeValueRT(rt, entry.val) rt.freeValues(entry.args) state.timeouts.setLen(0) {.pop.} # raises: [] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/local/����������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0015013�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/local/clientutil.nim��������������������������������������������������������������0000664�0000000�0000000�00000005131�15202323131�0017674�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/os import std/posix import config/chapath import io/dynstream import monoucha/fromjs import monoucha/jsbind import monoucha/jsutils import monoucha/quickjs import monoucha/tojs import types/blob import types/jsopt import types/opt import types/url import utils/myposix import utils/strwidth import utils/twtstr type Util = ref object jsDestructor(Util) proc getcwd(): string {.jsstfunc: "Util".} = return myposix.getcwd() proc unquote(ctx: JSContext; s: string; base = ""): JSValue {. jsstfunc: "Util".} = let res = ChaPath(s).unquote(base) if res.isOk: return ctx.toJS(res.get) return JS_ThrowTypeError(ctx, "%s", cstring(res.error)) proc openFile(path: string): cint {.jsstfunc: "Util".} = let ps = newPosixStream(path, O_RDONLY, 0) if ps == nil: return -1 return ps.fd proc isFile(ctx: JSContext; val: JSValueConst): Opt[bool] {.jsstfunc: "Util".} = if JS_IsNumber(val): var fd: cint ?ctx.fromJS(val, fd) var stats: Stat return ok(fstat(fd, stats) == 0 and not S_ISDIR(stats.st_mode)) var path: string ?ctx.fromJS(val, path) return ok(fileExists(path)) proc closeFile(fd: cint) {.jsstfunc: "Util".} = discard close(fd) proc nimGCStats(): string {.jsstfunc: "Util".} = return GC_getStatistics() proc jsGCStats(ctx: JSContext): string {.jsstfunc: "Util".} = let rt = JS_GetRuntime(ctx) return rt.getMemoryUsage() proc nimCollect() {.jsstfunc: "Util".} = try: GC_fullCollect() except Exception: discard proc jsCollect(ctx: JSContext) {.jsstfunc: "Util".} = let rt = JS_GetRuntime(ctx) JS_RunGC(rt) proc sleep(millis: int) {.jsstfunc: "Util".} = os.sleep(millis) proc isSameAuthOrigin(a, b: URL): bool {.jsstfunc: "Util".} = return a.authOrigin.isSameOrigin(b.authOrigin); proc encodeURIPath(s: string): string {.jsstfunc: "Util".} = return percentEncode(s, LocalPathPercentEncodeSet) proc expandPath(s: string): string {.jsstfunc: "Util".} = return twtstr.expandPath(s) proc mkdir(s: string; mode: cint): cint {.jsstfunc: "Util".} = return posix.mkdir(cstring(s), Mode(mode)) proc unlink(s: string) {.jsstfunc: "Util".} = discard posix.unlink(cstring(s)) proc readBlob(path: string): WebFile {.jsstfunc: "Util".} = let ps = newPosixStream(path, O_RDONLY, 0) if ps == nil: return nil let name = path.afterLast('/') return newWebFile(name, ps.fd) proc convertSize(n: float64): string {.jsstfunc: "Util".} = twtstr.convertSize(uint64(n)) proc width(s: string): int {.jsstfunc: "Util".} = strwidth.width(s) proc addUtilModule*(ctx: JSContext): JSClassID = return ctx.registerType(Util) {.pop.} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/local/lineedit.nim����������������������������������������������������������������0000664�0000000�0000000�00000031505�15202323131�0017321�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import types/color import config/history import monoucha/fromjs import monoucha/jsbind import monoucha/jsutils import monoucha/quickjs import monoucha/tojs import types/cell import types/winattrs import utils/luwrap import utils/strwidth import utils/twtstr type LineSelectType = enum lstChar = "char" lstWord = "word" lstLine = "line" LineEdit* = ref object text {.jsget.}: string # public prompt: string promptw: int cursorx: int # 0 ..< text.width cursori: int # 0 ..< text.len shiftx: int # 0 ..< text.width shifti: int # 0 ..< text.len padding: int # 0 or 1 maxwidth: int selecti: int # start of selection hist: History currHist: HistoryEntry histtmp: string luctx: LUContext selectType: LineSelectType redraw*: bool skipLast: bool escNext {.jsgetset.}: bool # private hide {.jsget.}: bool # private update: JSValue resolve: JSValue jsDestructor(LineEdit) proc finalize(rt: JSRuntime; this: LineEdit) {.jsfin.} = JS_FreeValueRT(rt, this.update) JS_FreeValueRT(rt, this.resolve) proc mark(rt: JSRuntime; this: LineEdit; markFun: JS_MarkFunc) {.jsmark.} = JS_MarkValue(rt, this.update, markFun) JS_MarkValue(rt, this.resolve, markFun) proc isDigitAscii(u: uint32): bool = return u < 128 and char(u) in AsciiDigit proc breaksWord(ctx: LUContext; u: uint32): bool = return not u.isDigitAscii() and u.width() != 0 and not ctx.isAlpha(u) proc width(edit: LineEdit; u: uint32): int = if edit.hide: return 1 return u.width() proc width(edit: LineEdit; s: string): int = var n = 0 for u in s.points: n += edit.width(u) n # Note: capped at edit.maxwidth. proc getDisplayWidth(edit: LineEdit): int = var dispw = 0 var i = edit.shifti while i < edit.text.len and dispw < edit.maxwidth: let u = edit.text.nextUTF8(i) dispw += edit.width(u) return dispw proc shiftView(edit: LineEdit) = # Shift view so it contains the cursor. if edit.cursorx < edit.shiftx: edit.shiftx = edit.cursorx edit.shifti = edit.cursori # Shift view so it is completely filled. if edit.shiftx > 0: let dispw = edit.getDisplayWidth() if dispw < edit.maxwidth: let targetx = edit.shiftx - edit.maxwidth + dispw if targetx <= 0: edit.shiftx = 0 edit.shifti = 0 else: while edit.shiftx > targetx: let u = edit.text.prevUTF8(edit.shifti) edit.shiftx -= edit.width(u) edit.padding = 0 # Shift view so it contains the cursor. (act 2) if edit.shiftx < edit.cursorx - edit.maxwidth: while edit.shiftx < edit.cursorx - edit.maxwidth and edit.shifti < edit.text.len: let u = edit.text.nextUTF8(edit.shifti) edit.shiftx += edit.width(u) if edit.shiftx > edit.cursorx - edit.maxwidth: # skipped over a cell because of a double-width char edit.padding = 1 proc selectStart(edit: LineEdit): int = if edit.selecti == -1: return -1 case edit.selectType of lstChar: return min(edit.selecti, edit.cursori) of lstWord: var i = min(edit.selecti, edit.cursori) if i < edit.text.len: # if we are on a word-breaking char, we stop immediately let pi = i let u = edit.text.nextUTF8(i) if edit.luctx.breaksWord(u): return pi i = pi while i > 0: let pi = i let u = edit.text.prevUTF8(i) if edit.luctx.breaksWord(u): return pi return i of lstLine: return 0 proc selectEnd(edit: LineEdit): int = if edit.selecti == -1: return -1 case edit.selectType of lstChar: var i = max(edit.selecti, edit.cursori) if i < edit.text.len: discard edit.text.nextUTF8(i) return i of lstWord: var i = max(edit.selecti, edit.cursori) if i < edit.text.len: # ensure the selection is at least one char wide let u = edit.text.nextUTF8(i) if edit.luctx.breaksWord(u): return i while i < edit.text.len: let pi = i let u = edit.text.nextUTF8(i) if edit.luctx.breaksWord(u): return pi return i of lstLine: return edit.text.len proc generateOutput*(edit: LineEdit; hlcolor: CellColor): FixedGrid = edit.shiftView() # Make the output grid +1 cell wide, so it covers the whole input area. result = newFixedGrid(edit.promptw + edit.maxwidth + 1, 1) var x = 0 for u in edit.prompt.points: result[x].str.addUTF8(u) x += u.width() if x >= result.width: break for i in 0 ..< edit.padding: if x < result.width: result[x].str = " " inc x var i = edit.shifti let selectStart = edit.selectStart let selectEnd = edit.selectEnd var format = Format() while i < edit.text.len: if selectStart != -1: if i in selectStart ..< selectEnd: format.bgcolor = hlcolor else: format.bgcolor = defaultColor let pi = i let u = edit.text.nextUTF8(i) let w = edit.width(u) if x + w > result.width: break if not edit.hide: if u.isControlChar(): result[x].str = u.controlToVisual() else: for j in pi ..< i: result[x].str &= edit.text[j] else: result[x].str &= '*' result[x].format = format x += w proc getCursorX*(edit: LineEdit): int {.jsfunc.} = return edit.promptw + edit.cursorx + edit.padding - edit.shiftx # private proc hasSelection(edit: LineEdit): bool {.jsfunc.} = return edit.selecti >= 0 # private proc clearSelection(edit: LineEdit) {.jsfunc.} = if edit.selecti != -1: edit.selecti = -1 edit.redraw = true # private proc startSelection(edit: LineEdit; t: LineSelectType) {.jsfunc.} = edit.selecti = edit.cursori edit.selectType = t edit.redraw = true # private proc selectedText(edit: LineEdit): string {.jsfget.} = if edit.selecti < 0: return "" return edit.text.substr(edit.selectStart, edit.selectEnd - 1) proc update(ctx: JSContext; edit: LineEdit): JSValue = if JS_IsUndefined(edit.update): return JS_UNDEFINED return ctx.call(edit.update, JS_UNDEFINED) proc resolve(ctx: JSContext; edit: LineEdit; val: JSValue): JSValue = if not JS_IsFunction(ctx, edit.resolve): JS_FreeValue(ctx, val) return JS_ThrowTypeError(ctx, "nothing to resolve") let resolve = edit.resolve edit.resolve = JS_UNDEFINED return ctx.callSinkFree(resolve, JS_UNDEFINED, val) proc cancel(ctx: JSContext; edit: LineEdit): JSValue {.jsfunc.} = return ctx.resolve(edit, JS_NULL) proc submit(ctx: JSContext; edit: LineEdit): JSValue {.jsfunc.} = let text = ctx.toJS(edit.text) if edit.hist.mtime == 0 and edit.text.len > 0: edit.hist.add(edit.text) if JS_IsException(text): return text return ctx.resolve(edit, text) proc deleteTextTo(edit: LineEdit; ei: int) = edit.text.delete(edit.cursori ..< ei) if edit.cursori < edit.selecti: edit.selecti -= ei - edit.cursori if edit.selecti <= edit.cursori: edit.clearSelection() edit.redraw = true proc backspace(ctx: JSContext; edit: LineEdit): JSValue {.jsfunc.} = if edit.cursori > 0: let pi = edit.cursori let u = edit.text.prevUTF8(edit.cursori) edit.cursorx -= edit.width(u) edit.deleteTextTo(pi) return ctx.update(edit) return JS_UNDEFINED proc write*(ctx: JSContext; edit: LineEdit; s: string): JSValue {.jsfunc.} = edit.escNext = false if s.len > 0: edit.text.insert(s, edit.cursori) edit.cursori += s.len edit.cursorx += edit.width(s) if edit.selecti >= edit.cursori: edit.selecti += s.len edit.redraw = true return ctx.update(edit) return JS_UNDEFINED proc delete(ctx: JSContext; edit: LineEdit): JSValue {.jsfunc.} = if edit.cursori < edit.text.len: let len = edit.text.pointLenAt(edit.cursori) edit.deleteTextTo(edit.cursori + len) return ctx.update(edit) return JS_UNDEFINED proc escape(edit: LineEdit) {.jsfunc.} = edit.escNext = true proc clear(ctx: JSContext; edit: LineEdit): JSValue {.jsfunc.} = let pi = edit.cursori if pi > 0: edit.cursori = 0 edit.cursorx = 0 edit.deleteTextTo(pi) return ctx.update(edit) return JS_UNDEFINED proc kill(ctx: JSContext; edit: LineEdit): JSValue {.jsfunc.} = if edit.cursori < edit.text.len: edit.text.setLen(edit.cursori) edit.redraw = true edit.selecti = min(edit.selecti, edit.cursori) if edit.selecti == edit.cursori: edit.clearSelection() return ctx.update(edit) return JS_UNDEFINED proc backward(edit: LineEdit) {.jsfunc.} = if edit.cursori > 0: let u = edit.text.prevUTF8(edit.cursori) edit.cursorx -= edit.width(u) if edit.cursorx < edit.shiftx or edit.selecti != -1: edit.redraw = true proc forward(edit: LineEdit) {.jsfunc.} = if edit.cursori < edit.text.len: let u = edit.text.nextUTF8(edit.cursori) edit.cursorx += edit.width(u) if edit.cursorx >= edit.shiftx + edit.maxwidth or edit.selecti != -1: edit.redraw = true # private proc setAbsoluteCursorX(edit: LineEdit; x: int) {.jsfunc.} = let x = max(x - edit.shiftx - edit.promptw, 0) while edit.cursorx < x: let x = edit.cursorx edit.forward() if edit.cursorx == x: break while edit.cursorx > x: let x = edit.cursorx edit.backward() if edit.cursorx == x: break proc prevWord(edit: LineEdit) {.jsfunc.} = if edit.cursori == 0: return let pi = edit.cursori let u = edit.text.prevUTF8(edit.cursori) if edit.luctx.breaksWord(u): edit.cursorx -= edit.width(u) else: edit.cursori = pi while edit.cursori > 0: let pi = edit.cursori let u = edit.text.prevUTF8(edit.cursori) if edit.luctx.breaksWord(u): edit.cursori = pi break edit.cursorx -= edit.width(u) if edit.cursorx < edit.shiftx: edit.redraw = true proc nextWord(edit: LineEdit) {.jsfunc.} = while edit.cursori < edit.text.len: let u = edit.text.nextUTF8(edit.cursori) edit.cursorx += edit.width(u) if edit.luctx.breaksWord(u): if edit.cursorx >= edit.shiftx + edit.maxwidth: edit.redraw = true break proc clearWord(ctx: JSContext; edit: LineEdit): JSValue {.jsfunc.} = let pi = edit.cursori edit.prevWord() if edit.cursori != pi: edit.deleteTextTo(pi) return ctx.update(edit) return JS_UNDEFINED proc killWord(ctx: JSContext; edit: LineEdit): JSValue {.jsfunc.} = if edit.cursori >= edit.text.len: return JS_UNDEFINED var i = edit.cursori var u = edit.text.nextUTF8(i) if not edit.luctx.breaksWord(u): while i < edit.text.len: let pi = i let u = edit.text.nextUTF8(i) if edit.luctx.breaksWord(u): i = pi break edit.deleteTextTo(i) return ctx.update(edit) proc begin(edit: LineEdit) {.jsfunc.} = edit.cursori = 0 edit.cursorx = 0 if edit.shiftx > 0 or edit.selecti != -1: edit.redraw = true proc `end`(edit: LineEdit) {.jsfunc.} = if edit.cursori < edit.text.len: edit.cursori = edit.text.len edit.cursorx = edit.width(edit.text) if edit.cursorx >= edit.shiftx + edit.maxwidth or edit.selecti != -1: edit.redraw = true proc prevHist(ctx: JSContext; edit: LineEdit): JSValue {.jsfunc.} = if edit.currHist == nil: var last = edit.hist.last if last != nil and edit.skipLast: last = last.prev if last != nil and edit.text.len > 0: edit.histtmp = edit.text edit.currHist = last elif edit.currHist.prev != nil: edit.currHist = edit.currHist.prev if edit.currHist != nil: edit.text = edit.currHist.s edit.clearSelection() # The begin call is needed so the cursor doesn't get lost outside # the string. edit.begin() edit.end() edit.redraw = true return ctx.update(edit) return JS_UNDEFINED proc nextHist(ctx: JSContext; edit: LineEdit): JSValue {.jsfunc.} = if edit.currHist != nil: edit.currHist = edit.currHist.next if edit.currHist != nil: edit.text = edit.currHist.s if edit.currHist == edit.hist.last and edit.skipLast: edit.currHist = nil else: edit.text = move(edit.histtmp) edit.clearSelection() edit.begin() edit.end() edit.redraw = true return ctx.update(edit) return JS_UNDEFINED proc windowChange*(edit: LineEdit; attrs: WindowAttributes) = edit.maxwidth = attrs.width - edit.promptw - 1 edit.redraw = true proc readLine*(prompt, current: string; termwidth: int; hide: bool; hist: History; luctx: LUContext; update, resolve: JSValue): LineEdit = let promptw = prompt.width() let edit = LineEdit( prompt: prompt, promptw: promptw, text: current, hide: hide, redraw: true, cursori: current.len, # - 1, so that the cursor always has place maxwidth: termwidth - promptw - 1, selecti: -1, hist: hist, currHist: nil, luctx: luctx, # Skip the last history entry if it's identical to the input. skipLast: hist.last != nil and hist.last.s == current, update: update, resolve: resolve ) edit.cursorx = edit.width(current) return edit proc addLineEditModule*(ctx: JSContext): JSClassID = return ctx.registerType(LineEdit) {.pop.} # raises: [] �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/local/pager.nim�������������������������������������������������������������������0000664�0000000�0000000�00000265342�15202323131�0016632�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/options import std/os import std/posix import std/tables import std/times import encoding/charset import encoding/decoder import config/chapath import config/config import config/conftypes import config/cookie import config/history import config/mailcap import config/mimetypes import css/render import html/script import io/chafile import io/console import io/dynstream import io/packetreader import io/packetwriter import io/poll import io/timeout import local/lineedit import local/select import local/term import monoucha/fromjs import monoucha/jsbind import monoucha/jsnull import monoucha/jstypes import monoucha/jsutils import monoucha/libregexp import monoucha/quickjs import monoucha/tojs import server/bufferiface import server/connectionerror import server/forkserver import server/headers import server/loaderiface import server/request import types/bitmap import types/blob import types/cell import types/color import types/jsopt import types/opt import types/url import types/winattrs import utils/lrewrap import utils/luwrap import utils/myposix import utils/strwidth import utils/twtstr type LineMode* = enum lmScript = "script" lmLocation = "location" lmUsername = "username" lmPassword = "password" lmCommand = "command" lmBuffer = "buffer" lmSearch = "search" lmGotoLine = "gotoLine" lmDownload = "download" lmAlert = "alert" lmMailcap = "mailcap" PagerAlertState = enum pasNormal = "normal" pasAlertOn = "alertOn" pasLoadInfo = "loadInfo" SurfaceType = enum stDisplay, stStatus Surface = object redraw: bool grid: FixedGrid UpdateStatusState = enum ussNone, ussUpdate, ussSkip JSMap = object # workaround for the annoying warnings (too lazy to fix them) pager: JSValue handleInput: JSValue showConsole: JSValue askPromise: JSValue # function to resolve on ask finish Pager* = ref object of RootObj mailcapLoaded: bool hasload: bool # has a page been successfully loaded since startup? dumpConsoleFile: bool feedNext {.jsgetset.}: bool paste {.jsget.}: bool # set in fulfillAsk mousePaste: bool updateStatus: UpdateStatusState alertState {.jsgetset.}: PagerAlertState # private # current number prefix (when vi-numeric-prefix is true) precnum {.jsgetset.}: int32 # private arg0 {.jsget.}: int32 # private bufferAtom: JSAtom consoleCacheId {.jsget.}: int # private consoleFile: string alerts: seq[string] askCursor: int askPrompt: string config: Config console: Console cookieJars: CookieJarMap surfaces: array[SurfaceType, Surface] consoleInit {.jsgetset.}: BufferInit exitCode: int forkserver: ForkServer inputBuffer: string # currently uninterpreted characters jsctx: JSContext lastAlert {.jsget.}: string # last alert seen by the user lineHist: array[LineMode, History] lineEdit* {.jsget.}: LineEdit # private loader: FileLoader loaderPid {.jsget.}: int luctx: LUContext menu {.jsget.}: Select numload {.jsgetset.}: int # number of pages currently being loaded term*: Terminal timeouts*: TimeoutState tmpfSeq: uint attrs: WindowAttributes pidMap: Table[int, string] # pid -> command jsmap: JSMap autoMailcap: Mailcap mailcap: Mailcap mimeTypes: MimeTypes bufferInit {.jsget.}: BufferInit # visible BufferInit (may != iface.init) bufferIface {.jsget.}: BufferInterface # visible BufferInterface jsDestructor(Pager) # Forward declarations proc addConsole2(pager: Pager; interactive: bool) proc alert(pager: Pager; msg: string) proc redraw(pager: Pager) proc windowChange(pager: Pager): Opt[void] # private proc bufWidth(pager: Pager): int {.jsfget.} = return pager.attrs.width # private proc bufHeight(pager: Pager): int {.jsfget.} = return pager.attrs.height - 1 proc surfaceSize(pager: Pager; t: SurfaceType): tuple[w, h: int] = case t of stDisplay: return (pager.bufWidth, pager.bufHeight) of stStatus: return (pager.attrs.width, 1) proc clear(pager: Pager; t: SurfaceType) = let (w, h) = pager.surfaceSize(t) pager.surfaces[t] = Surface( grid: newFixedGrid(w, h), redraw: true ) template status(pager: Pager): Surface = pager.surfaces[stStatus] template display(pager: Pager): Surface = pager.surfaces[stDisplay] # private proc statusWidth(pager: Pager): int {.jsfget.} = return pager.status.grid.width # private proc updateTitle(pager: Pager; init: BufferInit) {.jsfunc.} = pager.term.queueTitle(init.title) # private proc clearCachedImages(pager: Pager; iface: BufferInterface) {.jsfunc.} = if pager.term.imageMode != imNone: iface.clearCachedImages(pager.loader) # private proc setBufferInit(ctx: JSContext; pager: Pager; init: Option[BufferInit]) {.jsfset: "bufferInit".} = pager.bufferInit = init.get(nil) # private proc setBufferIface(ctx: JSContext; pager: Pager; iface: BufferInterface) {. jsfset: "bufferIface".} = pager.bufferIface = iface proc getHist(pager: Pager; mode: LineMode): History = if pager.lineHist[mode] == nil: pager.lineHist[mode] = newHistory(100) return pager.lineHist[mode] # private proc setLineEdit0(ctx: JSContext; pager: Pager; mode: LineMode; prompt: string; obj: JSValueConst = JS_UNDEFINED): JSValue {.jsfunc.} = var current = "" var hide = false var update = JS_UNDEFINED if not JS_IsUndefined(obj): if ctx.fromJSGetProp(obj, "current", current).isErr: return JS_EXCEPTION if ctx.fromJSGetProp(obj, "hide", hide).isErr: return JS_EXCEPTION update = JS_GetPropertyStr(ctx, obj, "update") if JS_IsException(update): return JS_EXCEPTION var funs {.noinit.}: array[2, JSValue] let res = ctx.newPromiseCapability(funs) if JS_IsException(res): JS_FreeValue(ctx, update) return JS_EXCEPTION JS_FreeValue(ctx, funs[1]) let hist = pager.getHist(mode) pager.lineEdit = readLine(prompt, current, pager.attrs.width, hide, hist, pager.luctx, update, funs[0]) return res # private proc unsetLineEdit(pager: Pager) {.jsfunc.} = pager.lineEdit = nil proc loadJSModule(ctx: JSContext; moduleName: cstringConst; opaque: pointer): JSModuleDef {.cdecl.} = let moduleName = $moduleName let x = if moduleName.startsWith("/") or moduleName.startsWith("./") or moduleName.startsWith("../"): parseURL0(moduleName, parseURL0("file://" & myposix.getcwd() & "/")) else: parseURL0(moduleName) if x == nil or x.schemeType != stFile: JS_ThrowTypeError(ctx, "invalid URL: %s", cstring(moduleName)) return nil var source: string if chafile.readFile(x.pathname, source).isOk: return ctx.finishLoadModule(source, moduleName) JS_ThrowTypeError(ctx, "failed to read file %s", cstring(moduleName)) return nil proc interruptHandler(rt: JSRuntime; opaque: pointer): cint {.cdecl.} = result = cint(term.sigintCaught) term.sigintCaught = false proc evalJSFree(opaque: RootRef; src, filename: string) = let pager = Pager(opaque) let ctx = pager.jsctx let headless = pager.config{"headless"} != hmFalse if not headless: pager.term.catchSigint() let ret = ctx.eval(src, filename, JS_EVAL_TYPE_GLOBAL) if not headless: pager.term.respectSigint() if JS_IsException(ret): pager.console.writeException(ctx) JS_FreeValue(ctx, ret) type CookieStreamOpaque = ref object of RootObj pager: Pager buffer: string proc onReadCookieStream(response: Response) = const BufferSize = 4096 let opaque = CookieStreamOpaque(response.opaque) let pager = opaque.pager while true: let olen = opaque.buffer.len opaque.buffer.setLen(olen + BufferSize) let n = response.stream.read(addr opaque.buffer[olen], BufferSize) if n <= 0: opaque.buffer.setLen(olen) break opaque.buffer.setLen(olen + n) var lastlf = opaque.buffer.rfind('\n') var i = 0 # Syntax: {jarId} RS {url} RS {persist?} RS {header} [ CR {header} ... ] LF # Persist is ASCII digit 0 if persist, 1 if not. const RS = '\x1E' # ASCII record separator while i < lastlf: let jarId = opaque.buffer.until(RS, i) i += jarId.len + 1 let urls = opaque.buffer.until(RS, i) i += urls.len + 1 let persists = opaque.buffer.until(RS, i) i += persists.len + 1 var headers: seq[string] = @[] while i - 1 < opaque.buffer.len and opaque.buffer[i - 1] != '\n': let header = opaque.buffer.until({'\n', '\r'}, i) headers.add(header) i += header.len + 1 let cookieJar = pager.cookieJars.getOrDefault(jarId) let url = parseURL0(urls) let persist = persists != "0" if cookieJar == nil or url == nil or persist and persists != "1": pager.alert("Error: received wrong set-cookie notification") continue cookieJar.setCookie(headers, url, persist, http = true) if i > 0: opaque.buffer.delete(0 ..< i) proc onFinishCookieStream(response: Response; success: bool) = let pager = CookieStreamOpaque(response.opaque).pager pager.alert("Error: cookie stream broken") proc initCookieStream(opaque: RootRef; response: Response) = let pager = Pager(opaque) if response == nil: pager.alert("failed to open cookie stream") return # ugly hack, so that the cookie stream does not keep headless # instances running dec pager.loader.mapFds response.opaque = CookieStreamOpaque(pager: pager) response.onRead = onReadCookieStream response.onFinish = onFinishCookieStream pager.loader.resume(response) proc normalizeModuleName(ctx: JSContext; baseName, name: cstringConst; opaque: pointer): cstring {.cdecl.} = return js_strdup(ctx, name) proc loadMailcap(pager: Pager; mailcap: var Mailcap; path: string) = let res = mailcap.parseMailcap(path) if res.isErr: pager.alert(res.error) # executed after prompting user const DefaultMailcap = """ image/png; exec "$CHA_LIBEXEC_DIR"/img2html '%t' '%u'; x-htmloutput; x-needsimage image/jpeg; exec "$CHA_LIBEXEC_DIR"/img2html '%t' '%u'; x-htmloutput; x-needsimage image/bmp; exec "$CHA_LIBEXEC_DIR"/img2html '%t' '%u'; x-htmloutput; x-needsimage image/gif; exec "$CHA_LIBEXEC_DIR"/img2html '%t' '%u'; x-htmloutput; x-needsimage image/webp; exec "$CHA_LIBEXEC_DIR"/img2html '%t' '%u'; x-htmloutput; x-needsimage image/svg+xml; exec "$CHA_LIBEXEC_DIR"/img2html '%t' '%u'; x-htmloutput; x-needsimage """ # executed automatically const DefaultAutoMailcap = """ text/gopher; exec "$CHA_LIBEXEC_DIR"/gopher2html -u '%u'; x-htmloutput text/gemini; exec "$CHA_LIBEXEC_DIR"/gmi2html; x-htmloutput text/markdown; exec "$CHA_LIBEXEC_DIR"/md2html; x-htmloutput text/x-ansi; exec "$CHA_LIBEXEC_DIR"/ansi2html -st '%{title}'; x-htmloutput; x-needsstyle text/x-dirlist; exec "$CHA_LIBEXEC_DIR"/dirlist2html -t '%{title}'; x-htmloutput text/uri-list; exec "$CHA_LIBEXEC_DIR"/uri2html '%{title}'; x-htmloutput application/xhtml+xml; exec cat; x-htmloutput """ proc loadAutoMailcap(pager: Pager) = # Backwards-compatibility: the default path used to be auto.mailcap, so # it is possible that # a) there is no ~/.config/mailcap, but there is ~/.config/auto.mailcap # b) there *is* a ~/.config/mailcap, but it is already assigned as the # non-auto mailcap # Here we make sure that both cases work as before. let config = pager.config if config{"autoMailcap"} == config.dir / "mailcap": if config{"autoMailcap"} in config{"mailcap"}: # case b pager.config.strs[coAutoMailcap] = config.dir / "auto.mailcap" elif not fileExists(config{"autoMailcap"}): var autoMailcapPath = config.dir / "auto.mailcap" if fileExists(autoMailcapPath): # case a pager.config.strs[coAutoMailcap] = move(autoMailcapPath) pager.loadMailcap(pager.autoMailcap, config{"autoMailcap"}) pager.autoMailcap.parseBuiltin(DefaultAutoMailcap) proc newPager*(config: Config; forkserver: ForkServer; ctx: JSContext; alerts: seq[string]; loader: FileLoader; loaderPid: int; console: Console): Pager = let pager = Pager( config: config, forkserver: forkserver, term: newTerminal(newPosixStream(STDOUT_FILENO), config, loader), alerts: alerts, jsctx: ctx, luctx: LUContext(), exitCode: -1, loader: loader, loaderPid: loaderPid, cookieJars: newCookieJarMap(), consoleCacheId: -1, console: console, bufferAtom: JS_NewAtom(ctx, cstring"buffer") ) pager.timeouts = newTimeoutState(pager.jsctx, evalJSFree, pager) pager.jsmap = JSMap( pager: ctx.toJS(pager), handleInput: ctx.eval("Pager.prototype.handleInput", "<init>", JS_EVAL_TYPE_GLOBAL), showConsole: ctx.eval("Pager.prototype.showConsole", "<init>", JS_EVAL_TYPE_GLOBAL), askPromise: JS_UNDEFINED ) for field in pager.jsmap.fields: doAssert not JS_IsException(field) let rt = JS_GetRuntime(ctx) JS_SetModuleLoaderFunc(rt, normalizeModuleName, loadJSModule, nil) JS_SetInterruptHandler(rt, interruptHandler, nil) let request = newRequest("about:cookie-stream") pager.loader.fetch(request, initCookieStream, pager) block history: let hist = newHistory(pager.config{"historySize"}, getTime().toUnix()) let ps = newPosixStream(pager.config{"historyFile"}) if ps != nil: if hist.parse(ps).isErr: hist.transient = true pager.alert("failed to read history") pager.lineHist[lmLocation] = hist block cookie: let ps = newPosixStream(pager.config{"cookieFile"}) if ps != nil: if pager.cookieJars.parse(ps, pager.alerts).isErr: pager.cookieJars.transient = true pager.alert("failed to read cookies") pager.loadAutoMailcap() for p in config{"mimeTypes"}: if f := chafile.fopen($p, "r"): let res = pager.mimeTypes.parseMimeTypes(f) f.close() if res.isErr: pager.alert("error reading file " & $p) return pager proc makeDataDir(pager: Pager) = # Try to ensure that we have a data directory. if mkdir(cstring(pager.config.dataDir), 0o700) < 0 and errno == ENOENT: # try creating parent dirs var s = pager.config.dataDir var i = 1 while (i = s.find('/', i); i > 0): s[i] = '\0' if mkdir(cstring(s), 0o755) < 0 and errno != EEXIST: return # something went very wrong; bail s[i] = '/' inc i # maybe it works now? discard mkdir(cstring(pager.config.dataDir), 0o700) proc cleanup(pager: Pager) = discard pager.term.quit() # maybe stdout is closed, but we don't mind here let hist = pager.lineHist[lmLocation] var needDataDir = true if not hist.transient: let hasConfigDir = dirExists(pager.config.dir) if hasConfigDir: needDataDir = false pager.makeDataDir() if hist.write(pager.config{"historyFile"}).isErr: if hasConfigDir: # History is enabled by default, so do not print the error # message if no config dir exists. pager.alert("failed to save history") if pager.cookieJars.needsWrite(): if needDataDir: pager.makeDataDir() if pager.cookieJars.write(pager.config{"cookieFile"}).isErr: pager.alert("failed to save cookies") for msg in pager.alerts: discard cast[ChaFile](stderr).write("cha: " & msg & '\n') let ctx = pager.jsctx # Decrement refcount of action maps. This is needed so that refc # actually cleans them up. # (For some reason, doing the same with config doesn't work.) for it in pager.config.actionMap.mitems: it = nil ctx.freeValues(pager.config.omnirule) ctx.freeValues(pager.config.siteconf) JS_FreeAtom(ctx, pager.bufferAtom) for val in pager.jsmap.fields: JS_FreeValue(ctx, val) pager.timeouts.clearAll() if pager.console != nil and pager.dumpConsoleFile: if file := chafile.fopen(pager.consoleFile, "r+"): let stderr = cast[ChaFile](stderr) var buffer {.noinit.}: array[1024, uint8] while (let n = file.read(buffer); n != 0): if stderr.write(buffer.toOpenArray(0, n - 1)).isErr: break proc runJSJobs(pager: Pager): Opt[void] = let rt = JS_GetRuntime(pager.jsctx) while true: let ctx = rt.runJSJobs() if ctx == nil: break pager.console.writeException(ctx) if pager.exitCode != -1: return err() ok() proc evalAction(pager: Pager; val: JSValue; arg0: int32; oval: var JSValue): JSValue = let ctx = pager.jsctx var val = val if not JS_IsFunction(ctx, val): # yes, this looks weird, but it's correct val = ctx.evalFunction(val) if JS_IsFunction(ctx, val): # optimization: skip this eval on the next call. JS_FreeValue(ctx, oval) oval = JS_DupValue(ctx, val) # If an action evaluates to a function that function is evaluated too. if JS_IsFunction(ctx, val): if arg0 != 0: let arg0 = ctx.toJS(arg0) if JS_IsException(arg0): JS_FreeValue(ctx, val) return arg0 val = ctx.callSinkFree(val, JS_UNDEFINED, arg0) else: # no precnum val = ctx.callFree(val, JS_UNDEFINED) return val # private proc writeInputBuffer(ctx: JSContext; pager: Pager): JSValue {.jsfunc.} = if pager.lineEdit != nil: let res = ctx.write(pager.lineEdit, pager.inputBuffer) pager.inputBuffer.setLen(0) return res return JS_UNDEFINED # private proc evalInputAction(ctx: JSContext; pager: Pager; map: ActionMap; arg0: int32): JSValue {.jsfunc.} = let val = map.advance(pager.inputBuffer) if JS_IsUndefined(val): if map.keyLast != 0: return JS_UNDEFINED if JS_IsUndefined(map.defaultAction): pager.inputBuffer.setLen(0) return JS_UNDEFINED let res = pager.evalAction(JS_DupValue(ctx, map.defaultAction), arg0, map.defaultAction) pager.inputBuffer.setLen(0) return res # note: this may replace val inside the ActionMap let res = pager.evalAction(JS_DupValue(ctx, val), arg0, map.mgetValue()) ctx.feedNext(map, pager.feedNext, pager.inputBuffer) pager.feedNext = false if map.keyLast == 0: pager.inputBuffer.setLen(0) return res # private proc queueStatusUpdate(pager: Pager) {.jsfunc.} = if pager.updateStatus == ussNone: pager.updateStatus = ussUpdate # private # called from JS command() proc evalCommand(ctx: JSContext; pager: Pager; src: string): JSValue {.jsfunc.} = if pager.consoleInit != nil: pager.consoleInit.flags.incl(bifTailOnLoad) return ctx.eval(src, "<command>", JS_EVAL_TYPE_GLOBAL or JS_EVAL_FLAG_BACKTRACE_BARRIER) proc toJS(ctx: JSContext; input: MouseInput): JSValue = #TODO might want to make this an opaque type let obj = JS_NewObject(ctx) let t = input.t let button = input.button let mods = cast[int32](input.mods) let (x, y) = input.pos if ctx.definePropertyConvert(obj, "t", t) == dprException or ctx.definePropertyConvert(obj, "button", button) == dprException or ctx.definePropertyConvert(obj, "mods", mods) == dprException or ctx.definePropertyConvert(obj, "x", x) == dprException or ctx.definePropertyConvert(obj, "y", y) == dprException: JS_FreeValue(ctx, obj) return JS_EXCEPTION return obj # private proc jsQuit(ctx: JSContext; pager: Pager; code = 0): JSValue {. jsfunc: "quit".} = pager.exitCode = int(code) JS_ThrowInternalError(ctx, "interrupted") JS_SetUncatchableException(ctx, true) return JS_EXCEPTION proc jsQuit(pager: Pager; code: int): JSValue = return pager.jsctx.jsQuit(pager, code) # private proc osc52Primary(pager: Pager): bool {.jsfget.} = pager.term.osc52Primary # The maximum number we are willing to accept. # This should be fine for 32-bit signed ints (which precnum currently is). const MaxPrecNum = 100000000 # private proc updateNumericPrefix(pager: Pager): bool {.jsfunc.} = if pager.config{"viNumericPrefix"} and pager.precnum >= 0: let c = pager.inputBuffer[0] if pager.precnum != 0 and c == '0' or c in '1'..'9': if pager.precnum < MaxPrecNum: # better ignore than eval... pager.precnum *= 10 pager.precnum += int32(decValue(c)) pager.inputBuffer.setLen(0) return true pager.arg0 = max(pager.precnum, 0) pager.precnum = -1 false proc handleKeyEnd(pager: Pager; e: InputEvent): int = let ctx = pager.jsctx let arg0 = ctx.toJS(e.t) if JS_IsException(arg0): pager.console.writeException(ctx) return 0 let arg1 = if e.t == ietMouse: ctx.toJS(e.m) else: JS_UNDEFINED pager.term.catchSigint() let res = ctx.callSink(pager.jsmap.handleInput, pager.jsmap.pager, arg0, arg1) pager.term.respectSigint() if JS_IsException(res): if pager.exitCode != -1: # quit() called return -1 # user code, so catch & log exceptions here pager.console.writeException(ctx) JS_FreeValue(ctx, res) 1 proc handleUserInput(pager: Pager): JSValue = let res = pager.term.ahandleRead() if res.isErr: return pager.jsQuit(1) if not res.get: return JS_UNDEFINED let pasteHack = pager.mousePaste and not pager.term.hasBracketedPaste() while e := pager.term.areadEvent(): case e.t of ietKey: pager.inputBuffer &= e.c of ietWindowChange: if pager.windowChange().isErr: return JS_EXCEPTION of ietRedraw: pager.redraw() of ietKeyEnd, ietPaste, ietMouse: if e.t == ietKeyEnd and pasteHack: continue case pager.handleKeyEnd(e) of -1: return JS_EXCEPTION of 0: break else: discard if pasteHack: # hack: when we have no bracketed paste, we pretend that all keys sent # together on middle click are a single event. if pager.handleKeyEnd(InputEvent(t: ietPaste)) < 0: return JS_EXCEPTION return JS_UNDEFINED # private proc runStartupScript(ctx: JSContext; pager: Pager): JSValue {.jsfunc.} = if pager.config{"startupScript"} == "": return JS_UNDEFINED let ps = newPosixStream(pager.config{"startupScript"}) let s = if ps != nil: var x = ps.readAll() ps.sclose() move(x) else: pager.config{"startupScript"} let flag = if pager.config{"startupScript"}.endsWith(".mjs"): JS_EVAL_TYPE_MODULE else: JS_EVAL_TYPE_GLOBAL return ctx.eval(s, pager.config{"startupScript"}, flag) proc run*(pager: Pager; pages: openArray[JSValue]; contentType: string; charset: Charset; history: bool): int = var istream: PosixStream = nil let ps = newPosixStream(STDIN_FILENO) if pager.config{"headless"} == hmFalse: let os = newPosixStream(STDOUT_FILENO) if ps.isatty(): istream = ps if os.isatty(): if istream == nil: istream = newPosixStream("/dev/tty", O_RDONLY, 0) else: istream = nil if istream == nil: pager.config.bits[coHeadless].headlessMode = hmDump pager.loader.pollData.register(pager.forkserver.estream.fd, POLLIN) let sr = pager.term.start(istream) if sr.isErr: return pager.attrs = pager.term.attrs for st in SurfaceType: pager.clear(st) pager.addConsole2(istream != nil) let pipe = not ps.isatty() if pipe: pager.loader.passFd("-", ps.fd) # we don't want history for dump/headless mode let history = pager.config{"headless"} == hmFalse and history let ctx = pager.jsctx let pages = ctx.newArrayFrom(pages) let jsInit = ctx.eval("Pager.prototype.init", "<init>", JS_EVAL_TYPE_GLOBAL) doAssert not JS_IsException(jsInit) let res = ctx.callSinkFree(jsInit, pager.jsmap.pager, pages, ctx.toJS(contentType), ctx.toJS(charset), ctx.toJS(history), ctx.toJS(pipe)) if JS_IsException(res) and pager.exitCode == -1: pager.console.writeException(ctx) JS_FreeValue(ctx, res) pager.cleanup() return max(pager.exitCode, 0) # Note: this function does not work correctly if start < x of last written char proc writeStatusMessage(status: var Surface; str: string; format = Format(); start = 0; maxwidth = -1): int = var maxwidth = maxwidth if maxwidth == -1: maxwidth = status.grid.len var x = start let e = min(start + maxwidth, status.grid.width) if x >= e: return x status.redraw = true for u in str.points: var u = u var w = u.width() if u == uint32('\t'): w = ((x + 8) and not 7) - x if x + w > e: # clip if we overflow (but not on exact fit) break if u.isControlChar(): if u == uint32('\t'): while w > 0: status.grid[x].str = " " status.grid[x].format = format inc x dec w continue status.grid[x].str = u.controlToVisual() else: status.grid[x].str = u.toUTF8() status.grid[x].format = format let nx = x + w inc x while x < nx: # clear unset cells status.grid[x].str = "" status.grid[x].format = Format() inc x result = x while x < e: status.grid[x] = FixedCell() inc x # Note: should only be called directly after user interaction. proc refreshStatusMsg(pager: Pager) = let init = pager.bufferInit if init == nil or not JS_IsUndefined(pager.jsmap.askPromise) or pager.lineEdit != nil: return if pager.precnum > 0: discard pager.status.writeStatusMessage($pager.precnum & pager.inputBuffer) elif pager.inputBuffer != "": discard pager.status.writeStatusMessage(pager.inputBuffer) elif pager.alerts.len > 0: pager.alertState = pasAlertOn discard pager.status.writeStatusMessage(pager.alerts[0]) # save to alert history if pager.lastAlert != "": let hist = pager.getHist(lmAlert) hist.add(move(pager.lastAlert)) pager.lastAlert = move(pager.alerts[0]) pager.alerts.delete(0) else: let fgcolor = if bifCrashed in init.flags: ANSIColor(1).cellColor() else: defaultColor let config = pager.config var format = initFormat(defaultColor, fgcolor, config{"status.formatMode"}) pager.alertState = pasNormal var msg = "" let iface = pager.bufferIface if config{"showCursorPosition"} and iface != nil and iface.numLines > 0: msg &= $(iface.cursory + 1) & "/" & $iface.numLines & " (" & $iface.atPercentOf() & "%)" else: msg &= "Viewing" if bifCrashed in init.flags: msg &= " CRASHED!" msg &= " <" & init.title let hover = if config{"showHoverLink"} and iface != nil: iface.getHoverText() else: "" let sl = hover.width() var l = 0 var i = 0 var maxw = pager.status.grid.width - 1 if sl > 0: maxw -= 2 # -2 for '>' and one blank while i < msg.len: let pi = i let u = msg.nextUTF8(i) l += u.width() if l + sl > maxw: i = pi break msg.setLen(i) if i > 0 and l < maxw: msg &= '>' if sl > 0 and l < maxw: msg &= ' ' msg &= hover if iface == nil or iface.numLines == 0: msg &= "\tNo Line" discard pager.status.writeStatusMessage(msg, format) # Call refreshStatusMsg if no alert is being displayed on the screen. # Alerts take precedence over load info, but load info is preserved when no # pending alerts exist. # private proc showAlerts(pager: Pager) {.jsfunc.} = if (pager.alertState == pasNormal or pager.alertState == pasLoadInfo and pager.alerts.len > 0) and pager.inputBuffer == "" and pager.precnum <= 0: pager.queueStatusUpdate() proc drawBufferAdvance(s: openArray[char]; bgcolor: CellColor; oi, ox: var int; ex: int): string = var ls = newStringOfCap(s.len) var i = oi var x = ox while x < ex and i < s.len: let pi = i let u = s.nextUTF8(i) let uw = u.width() x += uw if u in TabPUARange: # PUA tabs can be expanded to hard tabs if # * they are correctly aligned # * they don't have a bgcolor (terminals will fail to output bgcolor with # tabs) if bgcolor == defaultColor and (x and 7) == 0: ls &= '\t' else: for i in 0 ..< uw: ls &= ' ' else: for i in pi ..< i: ls &= s[i] oi = i ox = x move(ls) # private proc drawBuffer(pager: Pager; iface: BufferInterface): Opt[bool] {.jsfunc.} = let ctx = pager.jsctx let res = ctx.requestLinesSync(iface, proc(line: SimpleFlexibleLine): Opt[void] = let term = pager.term var x = 0 var i = 0 let bgcolor = iface.bgcolor let bgformat = term.reduceFormat(initFormat(bgcolor, defaultColor, {})) if bgcolor != defaultColor and (line.formats.len == 0 or line.formats[0].pos > 0): ?term.processFormat(bgformat) for f in line.formats: var ff = f.format if ff.bgcolor == defaultColor: ff.bgcolor = iface.bgcolor let termBgcolor = term.getCurrentBgcolor() let ls = line.str.drawBufferAdvance(termBgcolor, i, x, f.pos) ?term.processOutputString(ls, trackCursor = false) if i < line.str.len: ?term.processFormat(term.reduceFormat(ff)) if i < line.str.len: let termBgcolor = term.getCurrentBgcolor() let ls = line.str.drawBufferAdvance(termBgcolor, i, x, int.high) ?term.processOutputString(ls, trackCursor = false) if bgcolor != defaultColor and x < iface.init.width: ?term.processFormat(bgformat) let spaces = ' '.repeat(iface.init.width - x) ?term.processOutputString(spaces, trackCursor = false) ?term.processFormat(Format()) term.cursorNextLine() ) if pager.term.flush().isErr: return ok(false) case res of irEOF: return ok(false) of irOk: return ok(true) of irException: return err() # public proc redraw(pager: Pager) {.jsfunc.} = pager.term.clearCanvas() for surface in pager.surfaces.mitems: surface.redraw = true if pager.bufferIface != nil: pager.bufferIface.queueDraw() if pager.menu != nil: pager.menu.redraw = true if pager.lineEdit != nil: pager.lineEdit.redraw = true # private proc getTempFile(pager: Pager; ext = ""): string {.jsfunc.} = result = pager.config{"tmpdir"} / "chaptmp" & $pager.loader.clientPid & "-" & $pager.tmpfSeq if ext != "": result &= "." result &= ext inc pager.tmpfSeq type CachedImageEnv = ref object of RootObj pager: Pager cachedImage: CachedImage iface: BufferInterface cacheId: int proc loadCachedImage3(opaque: RootRef; response: Response) = let env = CachedImageEnv(opaque) let pager = env.pager let cachedImage = env.cachedImage let loader = pager.loader # remove previous step loader.removeCachedItem(env.cacheId) if response == nil: return loader.close(response) let cacheId = response.outputId if cachedImage.state == cisCanceled: loader.removeCachedItem(cacheId) return let ps = loader.openCachedItem(cacheId) if ps == nil: loader.removeCachedItem(cacheId) return let mem = ps.mmap() ps.sclose() if mem == nil: loader.removeCachedItem(env.cacheId) return let blob = newBlob(mem.p, mem.len, "image/x-sixel", (proc(opaque, p: pointer) = deallocMem(cast[MaybeMappedMemory](opaque)) ), mem ) env.iface.queueDraw() cachedImage.data = blob cachedImage.state = cisLoaded cachedImage.cacheId = cacheId cachedImage.transparent = response.headers.getFirst("Cha-Image-Sixel-Transparent") == "1" let plens = response.headers.getFirst("Cha-Image-Sixel-Prelude-Len") cachedImage.preludeLen = parseIntP(plens).get(0) proc loadCachedImage2(env: CachedImageEnv; response: Response) = let pager = env.pager let cachedImage = env.cachedImage if response == nil: return let cacheId = response.outputId env.cacheId = cacheId let loader = pager.loader if cachedImage.state == cisCanceled: loader.removeCachedItem(cacheId) return let headers = newHeaders(hgRequest, { "Cha-Image-Dimensions": $cachedImage.width & 'x' & $cachedImage.height }) var url: URL = nil case pager.term.imageMode of imSixel: url = parseURL0("img-codec+x-sixel:encode") headers.add("Cha-Image-Sixel-Halfdump", "1") headers.add("Cha-Image-Sixel-Palette", $pager.term.sixelRegisterNum) headers.add("Cha-Image-Offset", $cachedImage.offx & 'x' & $cachedImage.erry) headers.add("Cha-Image-Crop-Width", $cachedImage.dispw) of imKitty: url = parseURL0("img-codec+png:encode") of imNone: assert false let request = newRequest( url, httpMethod = hmPost, headers = headers, body = RequestBody(t: rbtCache, cacheId: cacheId), tocache = true ) loader.fetch(request, loadCachedImage3, env) loader.close(response) proc loadCachedImageResize(opaque: RootRef; response: Response) = let env = CachedImageEnv(opaque) # we must remove the previous cached item, but only after resize is done env.pager.loader.removeCachedItem(env.cacheId) env.loadCachedImage2(response) proc loadCachedImage0(opaque: RootRef; response: Response) = let env = CachedImageEnv(opaque) let pager = env.pager let cachedImage = env.cachedImage let bmp = cachedImage.bmp # remove previous step pager.loader.removeCachedItem(bmp.cacheId) if response == nil: return let cacheId = response.outputId # set by loader in tocache if cachedImage.state == cisCanceled: # container is no longer visible pager.loader.removeCachedItem(cacheId) return if cachedImage.width == bmp.width and cachedImage.height == bmp.height: # skip resize env.loadCachedImage2(response) return # resize # use a temp file, so that img-resize can mmap its output let headers = newHeaders(hgRequest, { "Cha-Image-Dimensions": $bmp.width & 'x' & $bmp.height, "Cha-Image-Target-Dimensions": $cachedImage.width & 'x' & $cachedImage.height }) let request = newRequest( "cgi-bin:resize", httpMethod = hmPost, headers = headers, body = RequestBody(t: rbtCache, cacheId: cacheId), tocache = true ) env.cacheId = cacheId pager.loader.fetch(request, loadCachedImageResize, env) pager.loader.close(response) proc loadCachedImage(pager: Pager; iface: BufferInterface; bmp: NetworkBitmap; width, height, offx, erry, dispw: int) = let cachedImage = CachedImage( bmp: bmp, width: width, height: height, offx: offx, erry: erry, dispw: dispw ) if not pager.loader.shareCachedItem(bmp.cacheId, pager.loader.clientPid, iface.process): pager.alert("Error: received incorrect cache ID from buffer") return let request = newRequest( "img-codec+" & bmp.contentType.after('/') & ":decode", httpMethod = hmPost, body = RequestBody(t: rbtCache, cacheId: bmp.cacheId), tocache = true ) let opaque = CachedImageEnv( pager: pager, cachedImage: cachedImage, iface: iface ) pager.loader.fetch(request, loadCachedImage0, opaque) iface.addCachedImage(cachedImage) proc initImages(pager: Pager; iface: BufferInterface) = let term = pager.term let bufWidth = pager.bufWidth let bufHeight = pager.bufHeight let maxwpx = bufWidth * pager.attrs.ppc let maxhpx = bufHeight * pager.attrs.ppl let imageMode = term.imageMode let pid = iface.process for image in iface.images: let dims = term.positionImage(image.x, image.y, image.x - iface.fromx, image.y - iface.fromy, image.offx, image.offy, image.width, image.height, maxwpx, maxhpx) if not dims.onScreen: continue let imageId = image.bmp.imageId let canvasImage = term.takeImage(pid, imageId, bufHeight, dims) if canvasImage != nil: term.addImage(canvasImage) continue let cachedOffx = if imageMode == imSixel: dims.offx else: 0 let cachedErry = if imageMode == imSixel: dims.erry else: 0 let cachedDispw = if imageMode == imSixel: dims.dispw else: 0 let width = image.width let height = image.height let cached = iface.findCachedImage(imageId, width, height, cachedOffx, cachedErry, cachedDispw) if cached == nil: pager.loadCachedImage(iface, image.bmp, width, height, cachedOffx, cachedErry, cachedDispw) continue if cached.state == cisLoaded: let canvasImage = newCanvasImage(cached.data, pid, cached.preludeLen, image.bmp, dims, cached.transparent) term.addImage(canvasImage) # updateImages yields all scrolled Sixel images damaged by checkImageDamage # with a new Y error. For these, we have to reload the cached image. for canvasImage in term.updateImages(bufWidth, bufHeight): let cachedOffx = if imageMode == imSixel: canvasImage.dims.offx else: 0 let cachedErry = if imageMode == imSixel: canvasImage.dims.erry else: 0 let cachedDispw = if imageMode == imSixel: canvasImage.dims.dispw else: 0 let width = canvasImage.dims.width let height = canvasImage.dims.height let cached = iface.findCachedImage(canvasImage.bmp.imageId, width, height, cachedOffx, cachedErry, cachedDispw) if cached == nil: pager.loadCachedImage(iface, canvasImage.bmp, width, height, cachedOffx, cachedErry, cachedDispw) canvasImage.damaged = false elif cached.state != cisLoaded: canvasImage.damaged = false else: canvasImage.updateImage(cached.data, cached.preludeLen) proc getAbsoluteCursorXY(pager: Pager; iface: BufferInterface): PagePos = var cursorx = 0 var cursory = 0 if not JS_IsUndefined(pager.jsmap.askPromise): return (pager.askCursor, pager.attrs.height - 1) elif pager.lineEdit != nil: return (pager.lineEdit.getCursorX(), pager.attrs.height - 1) elif (let menu = pager.menu; menu != nil): return (menu.getCursorX(), menu.getCursorY()) elif iface != nil: if pager.alertState == pasNormal: #TODO this really doesn't belong in draw... iface.clearHover() cursorx = iface.acursorx cursory = iface.acursory return (cursorx, cursory) proc highlightColor(pager: Pager): CellColor = if pager.attrs.colorMode != cmMonochrome: return pager.config{"highlightColor"}.cellColor() return defaultColor proc needsRedraw(pager: Pager; iface: BufferInterface): bool = return pager.display.redraw or pager.status.redraw or pager.menu != nil and pager.menu.redraw or pager.lineEdit != nil and pager.lineEdit.redraw or iface != nil and iface.redraw proc draw(pager: Pager): bool = let term = pager.term let iface = pager.bufferIface let redraw = pager.needsRedraw(iface) if redraw: # Note: lack of redraw does not necessarily mean that we send nothing to # the terminal, but that we at most only send a few cursor movement # controls. term.initFrame() var imageRedraw = false var hasMenu = false let bufHeight = pager.bufHeight let hlcolor = pager.highlightColor if iface != nil: if iface.redraw: iface.drawLines(pager.display.grid, hlcolor) if pager.config{"highlightMarks"}: iface.highlightMarks(pager.display.grid, hlcolor) iface.redraw = false pager.display.redraw = true imageRedraw = true let diff = pager.term.updateScroll(iface.process, iface.fromx, iface.fromy) if diff != 0 and abs(diff) <= (bufHeight + 1) div 2: if diff > 0: pager.term.scrollDown(diff, bufHeight) else: pager.term.scrollUp(-diff, bufHeight) else: pager.term.unsetScroll() if (let menu = pager.menu; menu != nil and (menu.redraw or pager.display.redraw)): menu.drawSelect(pager.display.grid) menu.redraw = false pager.display.redraw = true imageRedraw = false hasMenu = true if pager.display.redraw: pager.term.writeGrid(pager.display.grid) pager.display.redraw = false if pager.status.redraw: pager.term.writeGrid(pager.status.grid, 0, pager.attrs.height - 1) pager.status.redraw = false elif pager.lineEdit != nil and pager.lineEdit.redraw: let x = pager.lineEdit.generateOutput(hlcolor) pager.term.writeGrid(x, 0, pager.attrs.height - 1) pager.lineEdit.redraw = false if pager.term.imageMode != imNone: if imageRedraw: # init images only after term canvas has been finalized pager.initImages(iface) elif hasMenu and pager.term.imageMode == imKitty: # Kitty can't really deal with text layered both on top of *and* # under images. # # Well, it can, but only in a peculiar way: background color is # part of the text layer, so with our image model we'd have to # a) specify bgcolor for the menu and b) use sub-optimal in-cell # positioning. (You'll understand why if you try to implement it.) # # Ugh. :( pager.term.clearImages(bufHeight) let (cursorx, cursory) = pager.getAbsoluteCursorXY(iface) let mouse = not pager.mousePaste let bgcolor = if iface != nil: iface.bgcolor else: defaultColor pager.term.draw(redraw, mouse, cursorx, cursory, bufHeight, bgcolor).isOk proc writeAskPrompt(pager: Pager; s = "") = let maxwidth = pager.status.grid.width - s.width() let i = pager.status.writeStatusMessage(pager.askPrompt, maxwidth = maxwidth) pager.askCursor = pager.status.writeStatusMessage(s, start = i) # public proc askChar(ctx: JSContext; pager: Pager; prompt: string): JSValue {.jsfunc.} = var funs {.noinit.}: array[2, JSValue] let res = ctx.newPromiseCapability(funs) if JS_IsException(res): return JS_EXCEPTION JS_FreeValue(ctx, funs[1]) pager.askPrompt = prompt pager.writeAskPrompt() pager.jsmap.askPromise = funs[0] return res proc fitAskPrompt(pager: Pager; prompt0: string): string {.jsfunc.} = var prompt = prompt0 let choice = " (y/n)" let maxw = pager.status.grid.width - choice.width() var w = 0 var i = 0 while i < prompt.len: let pi = i w += prompt.nextUTF8(i).width() if w > maxw: i = pi break prompt.setLen(i) prompt &= choice move(prompt) # private proc fulfillAsk(ctx: JSContext; pager: Pager; paste: bool): JSValue {.jsfunc.} = if not JS_IsUndefined(pager.jsmap.askPromise): let inputBuffer = move(pager.inputBuffer) let text = ctx.toJS(inputBuffer) if JS_IsException(text): return text let fun = pager.jsmap.askPromise pager.jsmap.askPromise = JS_UNDEFINED pager.askPrompt = "" pager.paste = paste if pager.lineEdit != nil: pager.lineEdit.redraw = true let res = ctx.callSinkFree(fun, JS_UNDEFINED, text) if JS_IsException(res): return res JS_FreeValue(ctx, res) return JS_TRUE return JS_FALSE # private proc startMousePaste(pager: Pager) {.jsfunc.} = pager.mousePaste = true # private proc stopMousePaste(pager: Pager) {.jsfunc.} = pager.mousePaste = false # private proc copyLoadInfo(pager: Pager; init: BufferInit) {.jsfunc.} = if pager.bufferInit == init and init.loadInfo != "" and pager.alertState != pasAlertOn and pager.lineEdit == nil and JS_IsUndefined(pager.jsmap.askPromise): discard pager.status.writeStatusMessage(init.loadInfo) pager.alertState = pasLoadInfo pager.updateStatus = ussSkip proc initBuffer(pager: Pager; bufferConfig: BufferConfig; loaderConfig: LoaderClientConfig; request: Request; url: URL; contentType, filterCmd: string; title = ""; redirectDepth = 0; flags: set[BufferInitFlag] = {}; charsetStack: seq[Charset] = @[]): BufferInit = let stream = pager.loader.startRequest(request, loaderConfig) if stream == nil: pager.alert("failed to start request for " & $request.url) return nil pager.loader.pollData.register(stream.fd, POLLIN) let init = newBufferInit(bufferConfig, loaderConfig, url, request, pager.attrs, title, redirectDepth, flags, contentType, filterCmd, charsetStack) init.stream = stream pager.loader.put(init) return init # private proc initBufferFrom(pager: Pager; init: BufferInit; contentType, filterCmd: string): BufferInit {.jsfunc.} = return pager.initBuffer( init.config, init.loaderConfig, newRequest("cache:" & $init.cacheId), init.url, contentType, filterCmd, charsetStack = init.charsetStack ) proc addInterface(pager: Pager; init: BufferInit; stream: PosixStream; phandle: ProcessHandle): BufferInterface = stream.setBlocking(false) let iface = newBufferInterface(stream, pager.loader, phandle, addr pager.attrs, init) pager.loader.register(iface, POLLIN) return iface # private proc clone(pager: Pager; iface: BufferInterface; init: BufferInit; url: URL): BufferInterface {.jsfunc.} = var sv {.noinit.}: array[2, cint] if socketpair(AF_UNIX, SOCK_STREAM, IPPROTO_IP, sv) != 0: return nil let res = iface.clone(url, sv[1]) if res.isErr: return nil let fd = sv[0] let stream = newPosixStream(fd) # add a reference to parent's cached source; it will be removed when the # buffer is deleted let loader = pager.loader discard loader.shareCachedItem(init.cacheId, loader.clientPid) let iface2 = pager.addInterface(init, stream, iface.phandle) # I need numLines so that setCursorY works immediately iface2.numLines = iface.numLines iface2.requestLinesFast(force = true) return iface2 # public proc alert(pager: Pager; msg: string) {.jsfunc.} = if msg != "": pager.alerts.add(msg) pager.updateStatus = ussUpdate # public proc peekCursor(pager: Pager) {.jsfunc.} = if pager.bufferIface != nil: pager.alert(pager.bufferIface.getPeekCursorStr()) # private proc unregisterBufferIface(pager: Pager; iface: BufferInterface) {.jsfunc.} = if iface.dead: return # already unregistered pager.loader.removeCachedItem(iface.init.cacheId) if bifCrashed notin iface.init.flags: dec iface.phandle.refc if iface.phandle.refc == 0: pager.loader.removeClient(iface.process) let stream = iface.stream let fd = stream.fd pager.loader.unregister(fd) pager.loader.unset(fd) stream.sclose() iface.dead = true # private proc unregisterBufferInit(pager: Pager; init: BufferInit) {.jsfunc.} = if init.stream != nil: # connecting to URL pager.loader.unregister(init) let stream = move(init.stream) stream.sclose() template myExec(cmd: string) = discard execl("/bin/sh", "sh", "-c", cstring(cmd), nil) exitnow(127) type EnvVar = tuple[name, value: string] proc defaultEnv(pager: Pager): seq[EnvVar] = let init = pager.bufferInit if init != nil: return @[("CHA_URL", $init.url), ("CHA_CHARSET", $init.charset)] return @[] proc setEnvVars0(pager: Pager; env: openArray[EnvVar]): Opt[void] = for it in env: ?twtstr.setEnv(it.name, it.value) ok() proc setEnvVars(pager: Pager; env: openArray[EnvVar]) = if pager.setEnvVars0(env).isErr: pager.alert("Warning: failed to set some environment variables") # Run process (and suspend the terminal controller). # For the most part, this emulates system(3). proc runCommand(pager: Pager; cmd: string; suspend, wait: bool; env: openArray[EnvVar]): Opt[bool] = if suspend: ?pager.term.quit() var oldint, oldquit, act: Sigaction var oldmask, dummy: Sigset act.sa_handler = posix.SIG_IGN act.sa_flags = SA_RESTART if sigemptyset(act.sa_mask) < 0 or sigaction(SIGINT, act, oldint) < 0 or sigaction(SIGQUIT, act, oldquit) < 0 or sigaddset(act.sa_mask, SIGCHLD) < 0 or sigprocmask(SIG_BLOCK, act.sa_mask, oldmask) < 0: pager.alert("Failed to run process") if suspend: ?pager.term.restart() return ok(false) case (let pid = fork(); pid) of -1: pager.alert("Failed to run process") if suspend: ?pager.term.restart() return ok(false) of 0: if pager.setEnvVars0(env).isErr: quit(1) act.sa_handler = posix.SIG_DFL discard sigemptyset(act.sa_mask) discard sigaction(SIGINT, oldint, act) discard sigaction(SIGQUIT, oldquit, act) discard sigprocmask(SIG_SETMASK, oldmask, dummy); if not suspend: closeStdin() closeStdout() closeStderr() else: if pager.term.istream != nil: pager.term.istream.moveFd(STDIN_FILENO) myExec(cmd) else: var wstatus: cint if suspend: while waitpid(pid, wstatus, 0) == -1: if errno != EINTR: ?pager.term.restart() else: pager.pidMap[int(pid)] = cmd discard sigaction(SIGINT, oldint, act) discard sigaction(SIGQUIT, oldquit, act) discard sigprocmask(SIG_SETMASK, oldmask, dummy); if not suspend: return ok(true) if wait: ?pager.term.anyKey() ?pager.term.restart() pager.redraw() return ok(WIFEXITED(wstatus) and WEXITSTATUS(wstatus) == 0) # Run process, and capture its output. proc runProcessCapture(cmd: string; outs: var string): bool = let file = chafile.popen(cmd, "r") if file == nil: return false let res = file.readAll(outs).isOk let rv = file.pclose() if not res or rv == -1: return false return rv == 0 # Run process, and write an arbitrary string into its standard input. proc runProcessInto(cmd, ins: string): bool = let file = chafile.popen(cmd, "w") if file == nil: return false # It is OK if a process refuses to read all input. discard file.write(ins) let rv = file.pclose() if rv == -1: return false return rv == 0 # private proc getCacheFile(pager: Pager; cacheId: int; pid = -1): string {.jsfunc.} = let pid = if pid == -1: pager.loader.clientPid else: pid return pager.loader.getCacheFile(cacheId, pid) # private proc getEditorCommand(pager: Pager; file: string; line = 1): string {.jsfunc.} = var editor = pager.config{"editor"} if uqEditor := ChaPath(editor).unquote(""): if uqEditor in ["vi", "nvi", "vim", "nvim"]: editor = uqEditor & " +%d" var canpipe = true var s = unquoteCommand(editor, "", file, nil, canpipe, line) if s.len > 0 and canpipe: # %s not in command; add file name ourselves if s[^1] != ' ': s &= ' ' s &= quoteFile(file, qsNormal) move(s) proc windowChange(pager: Pager): Opt[void] = # maybe we didn't change dimensions, just color mode let dimChange = pager.attrs.width != pager.term.attrs.width or pager.attrs.height != pager.term.attrs.height or pager.attrs.ppc != pager.term.attrs.ppc or pager.attrs.ppl != pager.term.attrs.ppl pager.attrs = pager.term.attrs if dimChange: pager.term.unsetScroll() if pager.lineEdit != nil: pager.lineEdit.windowChange(pager.attrs) for st in SurfaceType: pager.clear(st) if pager.menu != nil: pager.menu.windowChange(pager.bufWidth, pager.bufHeight) if not JS_IsUndefined(pager.jsmap.askPromise): pager.writeAskPrompt() pager.queueStatusUpdate() let ctx = pager.jsctx let arg0 = ctx.toJS(ietWindowChange) if JS_IsException(arg0): return err() let res = ctx.callSink(pager.jsmap.handleInput, pager.jsmap.pager, arg0) if JS_IsException(res): return err() JS_FreeValue(ctx, res) ok() # Apply siteconf settings to a request. # Note that this may modify the URL passed. proc applySiteconf(pager: Pager; url: URL; charsetOverride: Charset; loaderConfig: var LoaderClientConfig; ourl: var URL; cookieJarId: var string; filterCmd: var string): BufferConfig = let ctx = pager.jsctx result = BufferConfig( userStyle: pager.config{"userStyle"} & '\n', refererFrom: pager.config{"refererFrom"}, scripting: pager.config{"scripting"}, charsets: pager.config{"documentCharset"}, images: pager.config{"images"}, styling: pager.config{"styling"}, autofocus: pager.config{"autofocus"}, history: pager.config{"history"}, headless: pager.config{"headless"}, charsetOverride: charsetOverride, metaRefresh: pager.config{"metaRefresh"}, markLinks: pager.config{"markLinks"} ) loaderConfig = LoaderClientConfig( originURL: url, defaultHeaders: pager.config{"defaultHeaders"}, cookiejar: nil, proxy: pager.config{"proxy"}, allowSchemes: @["data", "cache", "stream"], cookieMode: pager.config{"cookie"}, insecureSslNoVerify: false ) let allowHttpFromFile = when NimMajor < 2: pager.config.bits[coAllowHttpFromFile].bool else: pager.config{"allowHttpFromFile"} if allowHttpFromFile and url.schemeType in {stFile, stStream}: loaderConfig.allowSchemes.add("http") loaderConfig.allowSchemes.add("https") let host = url.host let surl = $url cookieJarId = host for sc in pager.config.siteconf: let matches = (case sc.matchType of smUrl: sc.regex.match(surl) of smHost: sc.regex.match(host)) if not matches: continue if not JS_IsUndefined(sc.fun): let fun = sc.fun var tmpUrl = newURL(url) let arg0 = ctx.toJS(tmpUrl) if JS_IsException(arg0): pager.alert("Error rewriting URL: " & ctx.getExceptionMsg()) else: let ret = ctx.callSink(fun, JS_UNDEFINED, arg0) if not JS_IsException(ret): # Warning: we must only print exceptions if the *call* returned one. # Conversion may simply error out because the function didn't return a # new URL, and that's fine. var nu: URL if ctx.fromJSFree(ret, nu).isOk: tmpUrl = nu else: #TODO should writeException the message to console pager.alert("Error rewriting URL: " & ctx.getExceptionMsg()) if $tmpUrl != surl: ourl = tmpUrl return for e in sc.entries: # we dispatch on class first to skip the object variant check case e.t of cocBit: let bit = e.bit case e.opt of coCookie: loaderConfig.cookieMode = bit.cookieMode of coScripting: result.scripting = bit.scriptingMode of coRefererFrom: result.refererFrom = bit.bool of coImages: result.images = bit.bool of coStyling: result.styling = bit.bool of coInsecureSslNoVerify: loaderConfig.insecureSslNoVerify = bit.bool of coAutofocus: result.autofocus = bit.bool of coMetaRefresh: result.metaRefresh = bit.metaRefresh of coHistory: result.history = bit.bool of coMarkLinks: result.markLinks = bit.bool else: assert false of cocStr: case e.opt of coShareCookieJar: cookieJarId = e.str of coUserStyle: result.userStyle &= e.str & '\n' of coFilterCmd: filterCmd = e.str else: assert false of cocCharsetSeq: assert e.opt == coDocumentCharset result.charsets = e.charsetSeq of cocURL: assert e.opt == coProxy loaderConfig.proxy = e.url of cocHeaders: assert e.opt == coDefaultHeaders let init = e.headers if init.clear: loaderConfig.defaultHeaders = newHeaders(hgRequest, init.s) else: let headers = loaderConfig.defaultHeaders.clone() for it in init.s: headers[it.name] = it.value loaderConfig.defaultHeaders = headers else: assert false if result.scripting != smFalse: loaderConfig.allowSchemes.add("x-cha-cookie") if result.images: result.imageTypes = pager.mimeTypes.image result.userAgent = loaderConfig.defaultHeaders.getFirst("User-Agent") proc applyCookieJar(pager: Pager; loaderConfig: var LoaderClientConfig; cookieJarId: string) = if loaderConfig.cookieMode != cmNone: var cookieJar = pager.cookieJars.getOrDefault(cookieJarId) if cookieJar == nil: cookieJar = pager.cookieJars.addNew(cookieJarId) loaderConfig.cookieJar = cookieJar proc initGotoURL(pager: Pager; request: Request; charset: Charset; referrer: BufferInit; cookie: Option[CookieMode]; loaderConfig: var LoaderClientConfig; bufferConfig: var BufferConfig; filterCmd: var string) = var cookieJarId: string for i in 0 ..< pager.config{"maxRedirect"}: var ourl: URL = nil bufferConfig = pager.applySiteconf(request.url, charset, loaderConfig, ourl, cookieJarId, filterCmd) if ourl == nil: break request.url = ourl if referrer != nil and referrer.config.refererFrom: let referer = $referrer.url request.headers["Referer"] = referer bufferConfig.referrer = referer loaderConfig.cookieMode = cookie.get(loaderConfig.cookieMode) pager.applyCookieJar(loaderConfig, cookieJarId) if request.url.username != "": pager.loader.addAuth(request.url) request.url.password = "" proc gotoURL0(pager: Pager; request: Request; save, history: bool; bufferConfig: BufferConfig; loaderConfig: LoaderClientConfig; title, contentType: string; redirectDepth: int; url: URL; filterCmd: string): BufferInit = var flags: set[BufferInitFlag] = {} if save: flags.incl(bifSave) if history and bufferConfig.history: flags.incl(bifHistory) let url = if url != nil: url else: request.url let init = pager.initBuffer(bufferConfig, loaderConfig, request, url, contentType, filterCmd, title, redirectDepth, flags) if init == nil: return nil inc pager.numload return init # private proc omniRewrite(ctx: JSContext; pager: Pager; arg0: JSValueConst): JSValue {.jsfunc.} = var s: string ?ctx.fromJS(arg0, s) for rule in pager.config.omnirule: if rule.regex.match(s): pager.lineHist[lmLocation].add(s) return ctx.call(rule.fun, JS_UNDEFINED, arg0) return JS_DupValue(ctx, arg0) proc createPipe(pager: Pager): (PosixStream, PosixStream) = var pipefds {.noinit.}: array[2, cint] if pipe(pipefds) == -1: pager.alert("Failed to create pipe") return (nil, nil) return (newPosixStream(pipefds[0]), newPosixStream(pipefds[1])) # private proc getHistoryURL(pager: Pager): URL {.jsfunc.} = let tmpf = pager.getTempFile() discard unlink(cstring(tmpf)) let ps = newPosixStream(tmpf, O_WRONLY or O_CREAT or O_EXCL, 0o600) if ps == nil: return nil ps.setCloseOnExec() let hist = pager.lineHist[lmLocation] if hist.write(ps, sync = false, reverse = true).isErr: pager.alert("failed to write history") return parseURL0("file:" & tmpf) proc addConsoleFile(pager: Pager): Opt[ChaFile] = let url = parseURL0("stream:console") let ps = pager.loader.addPipe(url.pathname) if ps == nil: return err() ps.setCloseOnExec() let file = ?ps.fdopen("w") let response = pager.loader.doRequest(newRequest(url)) if response.stream == nil: discard file.close() return err() let cacheId = pager.loader.addCacheFile(response.outputId) if cacheId == -1: discard file.close() return err() pager.loader.close(response) pager.consoleCacheId = cacheId pager.consoleFile = pager.getCacheFile(cacheId) ok(file) # private proc showConsole(pager: Pager) = let ctx = pager.jsctx let res = ctx.call(pager.jsmap.showConsole, pager.jsmap.pager) if JS_IsException(res): pager.console.writeException(ctx) JS_FreeValue(ctx, res) proc addConsole0(pager: Pager; close: bool): bool = let oldCacheId = pager.consoleCacheId if f := pager.addConsoleFile(): if oldCacheId != -1: pager.loader.removeCachedItem(oldCacheId) pager.console.setStream(f, close) return true return false # private proc addConsole(pager: Pager): bool {.jsfunc.} = pager.addConsole0(close = true) proc addConsole2(pager: Pager; interactive: bool) = if interactive and pager.config{"consoleBuffer"}: if pager.addConsole0(close = false): pager.console.log("Type (M-c) console.hide() to return to buffer mode.") pager.console.flush() return pager.alert("Failed to open temp file for console") # private proc saveTo(pager: Pager; init: BufferInit; path: string): bool {.jsfunc.} = if pager.loader.redirectToFile(init.istreamOutputId, path, init.url): pager.loader.resume(init.istreamOutputId) init.closeMailcap() return true return false # Go to specific URL (for JS) type GotoURLDict = object of JSDict contentType {.jsdefault.}: Option[string] save {.jsdefault.}: bool history {.jsdefault: true.}: bool scripting {.jsdefault.}: Option[ScriptingMode] cookie {.jsdefault.}: Option[CookieMode] charset {.jsdefault.}: Option[Charset] url {.jsdefault.}: Option[URL] referrer {.jsdefault.}: Option[BufferInit] redirectDepth {.jsdefault.}: int title {.jsdefault.}: string # public proc gotoURLImpl(ctx: JSContext; pager: Pager; v: JSValueConst; t = GotoURLDict()): Opt[BufferInit] {.jsfunc.} = var request: Request if ctx.fromJS(v, request).isErr: var url: URL if ctx.fromJS(v, url).isErr: var s: string ?ctx.fromJS(v, s) url = ?ctx.newURL(s) request = newRequest(url) var loaderConfig: LoaderClientConfig var bufferConfig: BufferConfig var filterCmd: string pager.initGotoURL(request, t.charset.get(csUnknown), t.referrer.get(nil), t.cookie, loaderConfig, bufferConfig, filterCmd) bufferConfig.scripting = t.scripting.get(bufferConfig.scripting) let init = pager.gotoURL0(request, t.save, t.history, bufferConfig, loaderConfig, t.title, t.contentType.get(""), t.redirectDepth, t.url.get(nil), filterCmd) ok(init) type ExternDict = object of JSDict env {.jsdefault: JS_UNDEFINED.}: JSValueConst suspend {.jsdefault: true.}: bool wait {.jsdefault: false.}: bool proc readEnvSeq(ctx: JSContext; pager: Pager; val: JSValueConst; s: var seq[EnvVar]): FromJSResult = if JS_IsUndefined(val): s = pager.defaultEnv() return fjOk var record: JSKeyValuePair[string, string] ?ctx.fromJS(val, record) s = move(record.s) fjOk #TODO we should have versions with retval as int? # or perhaps just an extern2 that can use JS readablestreams and returns # retval, then deprecate the rest. # public proc extern(ctx: JSContext; pager: Pager; cmd: string; t = ExternDict(env: JS_UNDEFINED, suspend: true)): JSValue {.jsfunc.} = var env = newSeq[EnvVar]() if ctx.readEnvSeq(pager, t.env, env) == fjErr: return JS_EXCEPTION let res = pager.runCommand(cmd, t.suspend, t.wait, env) if res.isErr: return ctx.jsQuit(pager, 1) return JS_NewBool(ctx, res.get) # public proc externCapture(ctx: JSContext; pager: Pager; cmd: string): JSValue {.jsfunc.} = pager.setEnvVars(pager.defaultEnv()) var s: string if runProcessCapture(cmd, s): return ctx.toJS(s) return JS_NULL # public proc externInto(pager: Pager; cmd, ins: string): bool {.jsfunc.} = pager.setEnvVars(pager.defaultEnv()) return runProcessInto(cmd, ins) # private proc suspend(ctx: JSContext; pager: Pager): JSValue {.jsfunc.} = if pager.term.quit().isErr: return ctx.jsQuit(pager, 1) discard kill(-pager.forkserver.pid, cint(SIGTSTP)) discard kill(0, cint(SIGTSTP)) discard kill(-pager.forkserver.pid, cint(SIGCONT)) if pager.term.restart().isErr: return ctx.jsQuit(pager, 1) return JS_UNDEFINED # public proc clipboardWrite(ctx: JSContext; pager: Pager; s: string; clipboard = true): JSValue {.jsfunc.} = if res := pager.term.sendOSC52(s, clipboard): if res: return JS_TRUE if not clipboard: return JS_FALSE return ctx.toJS(pager.externInto(pager.config{"copyCmd"}, s)) return ctx.jsQuit(pager, 1) # Execute cmd, with ps moved onto stdin, os onto stdout, and the browser # console onto stderr. # ps remains open, but os is consumed. proc execPipe(pager: Pager; cmd: string; ps, os: PosixStream): int = var oldint, oldquit: Sigaction var act = Sigaction(sa_handler: posix.SIG_IGN, sa_flags: SA_RESTART) var oldmask, dummy: Sigset let westream = pager.forkserver.westream if sigemptyset(act.sa_mask) < 0 or sigaction(SIGINT, act, oldint) < 0 or sigaction(SIGQUIT, act, oldquit) < 0 or sigaddset(act.sa_mask, SIGCHLD) < 0 or sigprocmask(SIG_BLOCK, act.sa_mask, oldmask) < 0: pager.alert("Failed to run process (errno " & $errno & ")") return -1 case (let pid = fork(); pid) of -1: pager.alert("Failed to fork process") return -1 of 0: act.sa_handler = posix.SIG_DFL discard sigemptyset(act.sa_mask) discard sigaction(SIGINT, oldint, act) discard sigaction(SIGQUIT, oldquit, act) discard sigprocmask(SIG_SETMASK, oldmask, dummy); ps.moveFd(STDIN_FILENO) os.moveFd(STDOUT_FILENO) westream.moveFd(STDERR_FILENO) myExec(cmd) else: discard sigaction(SIGINT, oldint, act) discard sigprocmask(SIG_SETMASK, oldmask, dummy); os.sclose() return pid proc execPipeWait(pager: Pager; cmd: string; ps, os: PosixStream): int = let pid = pager.execPipe(cmd, ps, os) if pid == -1: return 1 var wstatus = cint(0) while waitpid(Pid(pid), wstatus, 0) == -1: if errno != EINTR: break if WIFSIGNALED(wstatus): return 128 + WTERMSIG(wstatus) return WEXITSTATUS(wstatus) proc execPipeSink(pager: Pager; cmd: string; istream: PosixStream): PosixStream = let (pins, pouts) = pager.createPipe() if pins == nil: return nil pins.setCloseOnExec() let pid = pager.execPipe(cmd, istream, pouts) istream.sclose() if pid == -1: return nil return pins # Pipe output of an x-ansioutput mailcap command to the text/x-ansi handler. proc ansiDecode(pager: Pager; url: URL; ishtml: bool; istream: PosixStream): PosixStream = let entry = pager.autoMailcap.findMailcapEntry("text/x-ansi", "text/x-ansi", url) if entry == nil: pager.alert("No text/x-ansi entry found") return nil var canpipe = true let cmd = unquoteCommand(entry.cmd, "text/x-ansi", "", url, canpipe) if not canpipe: pager.alert("Error: could not pipe to text/x-ansi, decoding as text/plain") return nil return pager.execPipeSink(cmd, istream) # Pipe input into the mailcap command, and discard its output. # If needsterminal, leave stderr and stdout open and wait for the process. # Consumes stream. proc runMailcapWritePipe(pager: Pager; stream: PosixStream; needsterminal: bool; cmd: string): Opt[void] = if needsterminal: ?pager.term.quit() let pid = fork() if pid == -1: stream.sclose() pager.alert("Error: failed to fork mailcap write process") elif pid == 0: # child process stream.moveFd(STDIN_FILENO) if not needsterminal: closeStdout() closeStderr() myExec(cmd) else: # parent stream.sclose() if needsterminal: var x: cint while waitpid(pid, x, 0) == -1: if errno != EINTR: break ?pager.term.restart() ok() proc writeToFile(istream: PosixStream; outpath: string): bool = discard unlink(cstring(outpath)) let ps = newPosixStream(outpath, O_WRONLY or O_CREAT or O_EXCL, 0o600) if ps == nil: istream.sclose() return false var buffer {.noinit.}: array[4096, uint8] var n = 0 while (n = istream.read(buffer); n > 0): if ps.writeLoop(buffer.toOpenArray(0, n - 1)).isErr: n = -1 break ps.sclose() istream.sclose() n == 0 # Save input in a file, run the command, and redirect its output to a # new buffer. # needsterminal is ignored. proc runMailcapReadFile(pager: Pager; stream: PosixStream; cmd, outpath: string; pouts: PosixStream): int = case (let pid = fork(); pid) of -1: pager.alert("Error: failed to fork mailcap read process") pouts.sclose() return pid of 0: # child process closeStderr() pager.term.istream.sclose() pager.term.ostream.sclose() if not stream.writeToFile(outpath): quit(1) let ps = newPosixStream("/dev/null") let ret = pager.execPipeWait(cmd, ps, pouts) discard unlink(cstring(outpath)) quit(ret) else: # parent pouts.sclose() return pid # Save input in a file, run the command, and discard its output. # If needsterminal, leave stderr and stdout open and wait for the process. # Consumes stream. proc runMailcapWriteFile(pager: Pager; stream: PosixStream; needsterminal: bool; cmd, outpath: string): Opt[void] = discard mkdir(cstring(pager.config{"tmpdir"}), 0o700) if needsterminal: ?pager.term.quit() let os = newPosixStream(dup(pager.term.ostream.fd)) if not stream.writeToFile(outpath) or os.fd == -1: if os.fd != -1: os.sclose() ?pager.term.restart() pager.alert("Error: failed to write file for mailcap process") else: let ret = pager.execPipeWait(cmd, pager.term.istream, os) discard unlink(cstring(outpath)) ?pager.term.restart() if ret != 0: pager.alert("Error: " & cmd & " exited with status " & $ret) else: # don't block let pid = fork() if pid == 0: # child process closeStderr() pager.term.istream.sclose() pager.term.ostream.sclose() if not stream.writeToFile(outpath): quit(1) let ps = newPosixStream("/dev/null") let os = newPosixStream("/dev/null", O_WRONLY) let ret = pager.execPipeWait(cmd, ps, os) discard unlink(cstring(outpath)) quit(ret) # parent stream.sclose() ok() # Search for a mailcap entry, and if found, execute the specified command # and pipeline the input and output appropriately. # There are four possible outcomes: # * pipe stdin, discard stdout # * pipe stdin, read stdout # * write to file, run, discard stdout # * write to file, run, read stdout # If needsterminal is specified, and stdout is not being read, then the # pager is suspended until the command exits. #TODO add support for edit/compose proc runMailcap(pager: Pager; init: BufferInit; entry: MailcapEntry): Opt[void] = let url = init.url let stream = init.ostream let ext = url.pathname.afterLast('.') var outpath = pager.getTempFile(ext) let nametemplate = entry.find(nfNametemplate) if nametemplate != nil: outpath = unquoteCommand(nametemplate.value, init.contentType, outpath, url) var canpipe = true let cmd = unquoteCommand(entry.cmd, init.contentType, outpath, url, canpipe) let ishtml = mfHtmloutput in entry.flags let needsterminal = mfNeedsterminal in entry.flags block needsConnect: if entry.flags * {mfCopiousoutput, mfHtmloutput, mfAnsioutput, mfSaveoutput} == {}: # No output. Resume here, so that blocking needsterminal filters work. pager.loader.resume(init.istreamOutputId) let res = if canpipe: pager.runMailcapWritePipe(stream, needsterminal, cmd) else: pager.runMailcapWriteFile(stream, needsterminal, cmd, outpath) if res.isErr: init.flags.incl(bifMailcapCancel) return err() # stream is already closed break needsConnect # never connect here, since there's no output var (pins, pouts) = pager.createPipe() if pins == nil: stream.sclose() # connect: false implies that we consumed the stream break needsConnect pins.setCloseOnExec() let pid = if canpipe: # Pipe input into the mailcap command, then read its output into a buffer. # needsterminal is ignored. pager.execPipe(cmd, stream, pouts) else: pager.runMailcapReadFile(stream, cmd, outpath, pouts) stream.sclose() if pid == -1: break needsConnect let isansi = mfAnsioutput in entry.flags if not ishtml and isansi: let pins2 = pager.ansiDecode(url, ishtml, pins) if pins2 == nil: break needsConnect pins = pins2 # kind of a hack; we aren't modifying contentType here because # that would break reload. init.shortContentType = "text/x-ansi" let url = parseURL0("stream:" & $pid) pager.loader.passFd(url.pathname, pins.fd) let response = pager.loader.doRequest(newRequest(url)) if mfNeedsstyle in entry.flags or isansi: # ansi always needs styles init.config.styling = true if mfNeedsimage in entry.flags: init.config.images = true if mfSaveoutput in entry.flags: init.flags.incl(bifSave) if ishtml or isansi: init.flags.incl(bifHTML) else: init.flags.excl(bifHTML) init.flags.incl(bifRedirected) init.ostream = response.stream init.ostreamOutputId = response.outputId return ok() init.flags.incl(bifMailcapCancel) ok() # private proc addHist(pager: Pager; mode: LineMode; s: string) {.jsfunc.} = pager.getHist(mode).add(s) proc fail(pager: Pager; init: BufferInit; errorMessage: string): JSValue = dec pager.numload let ctx = pager.jsctx var msg = ctx.toJS(errorMessage) if JS_IsException(msg): # OOM msg = JS_UNDEFINED return ctx.toUndefined(ctx.connected(init, bcrFail, msg)) # private proc applyMailcap(ctx: JSContext; pager: Pager; init: BufferInit; val: JSValueConst): JSValue {.jsfunc.} = if JS_IsNumber(val): var i: int ?ctx.fromJS(val, i) let list = pager.mailcap.getList(init.shortContentType) if i < 0 or i >= list.s.len: return JS_ThrowRangeError(ctx, "invalid mailcap entry") if pager.runMailcap(init, list.s[i]).isErr: return ctx.jsQuit(pager, 1) else: var s: string ?ctx.fromJS(val, s) let entry = MailcapEntry() var state = MailcapParser() var dummy: string let res = state.parseEntry(s, entry, dummy) if res.isOk: if pager.runMailcap(init, entry).isErr: return ctx.jsQuit(pager, 1) else: return JS_ThrowTypeError(ctx, "%s", cstring(state.error)) return JS_UNDEFINED # private proc connected2(pager: Pager; init: BufferInit): JSValue {.jsfunc.} = let loader = pager.loader let ctx = pager.jsctx var arg0 = JS_UNDEFINED let cres = if bifSave in init.flags: dec pager.numload if init.ostreamOutputId != -1: # resume the ostream loader.resume(init.ostreamOutputId) bcrSave elif bifMailcapCancel in init.flags: dec pager.numload bcrCancel else: # buffer now actually exists; create a process for it var attrs = pager.attrs # subtract status line height attrs.height -= 1 attrs.heightPx -= attrs.ppl var url = init.url if url.username != "" or url.password != "": url = newURL(url) url.username = "" url.password = "" let (pid, stream) = pager.forkserver.forkBuffer( init.config, url, attrs, bifHTML in init.flags, init.charsetStack, init.shortContentType ) let ostream = init.ostream if pid == -1: ostream.sclose() return pager.fail(init, "error forking new process for buffer") let istreamOutputId = init.istreamOutputId let redirected = bifRedirected in init.flags let cstream = loader.addClient(pid, init.loaderConfig) if cstream == nil: stream.sclose() ostream.sclose() return pager.fail(init, "failed to create new loader client") if init.cacheId == -1: init.cacheId = loader.addCacheFile(istreamOutputId) if init.request.url.schemeType == stCache: # loading from cache; now both the buffer and us hold a new reference # to the cached item, but it's only shared with the buffer. add a # pager ref too. discard loader.shareCachedItem(init.cacheId, loader.clientPid) var outCacheId = init.cacheId if not redirected: discard loader.shareCachedItem(init.cacheId, pid) loader.resume(istreamOutputId) else: outCacheId = loader.addCacheFile(init.ostreamOutputId) discard loader.shareCachedItem(outCacheId, pid) loader.removeCachedItem(outCacheId) loader.resume([istreamOutputId, init.ostreamOutputId]) stream.withPacketWriterFire w: # if EOF, poll will notify us later w.swrite(outCacheId) w.sendFd(cstream.fd) # pass down ostream w.sendFd(ostream.fd) let iface = pager.addInterface(init, stream, newProcessHandle(pid)) arg0 = ctx.toJS(iface) bcrConnected return ctx.toUndefined(ctx.connected(init, cres, arg0)) proc saveEntry(pager: Pager; contentType: string; entry: MailcapEntry) = let path = pager.config{"autoMailcap"} if pager.autoMailcap.saveEntry(path, contentType, entry).isErr: pager.alert("Could not write to " & $path) # private proc saveMailcapEntry(ctx: JSContext; pager: Pager; init: BufferInit; i: int): Opt[void] {.jsfunc.} = let list = pager.mailcap.getList(init.shortContentType) if i < 0 or i >= list.s.len: JS_ThrowRangeError(ctx, "invalid mailcap entry") return err() pager.saveEntry(init.shortContentType, list.s[i]) ok() # private proc addMailcapEntry(pager: Pager; init: BufferInit; cmd: string; flag: MailcapFlag) {.jsfunc.} = pager.saveEntry(init.shortContentType, MailcapEntry(cmd: cmd, flags: {flag})) # private proc findMailcapPrevNext(pager: Pager; init: BufferInit; i: int): tuple[prev, next: int] {.jsfunc.} = if not pager.mailcapLoaded: for p in pager.config{"mailcap"}: pager.loadMailcap(pager.mailcap, p) pager.mailcap.parseBuiltin(DefaultMailcap) pager.mailcapLoaded = true let prev = pager.mailcap.findPrevMailcapEntry(init.shortContentType, init.contentType, init.url, i) var next = i discard pager.mailcap.findMailcapEntry(init.shortContentType, init.contentType, init.url, next) return (prev, next) # private proc askMailcap(ctx: JSContext; pager: Pager; init: BufferInit; i, sx, prev, next: int): JSValue {.jsfunc.} = var sx = sx let list = pager.mailcap.getList(init.shortContentType) var msg = "Open " & init.shortContentType & " as (shift=always): (t)ext, (s)ave" if i != -1: msg &= ", (r)un \"" & list.s[i].cmd.strip() & '"' msg &= ", (e)dit entry, (C-c)ancel" if prev != -1: msg &= ", (p)rev" if next != -1: msg &= ", (n)ext" msg = msg.toValidUTF8() var mw = msg.width() var j = 0 var x = 0 while j < msg.len: let pj = j let px = x x += msg.nextUTF8(j).width() if mw - px <= pager.attrs.width or x > sx: j = pj sx = px break return ctx.askChar(pager, msg.substr(j)) proc initMailcap(pager: Pager; init: BufferInit): JSValue = let ctx = pager.jsctx # contentType must have been set by applyResponse. if init.shortContentType.startsWith("text/"): # prepare content type for %{charset} init.contentType.setContentTypeAttr("charset", $init.charset) let entry = if bifForceType in init.flags: pager.autoMailcap.findMailcapEntry(init.shortContentType, init.contentType, init.url) else: pager.autoMailcap.findMailcapEntryMut(init.shortContentType, init.contentType, init.url) if init.shortContentType == "text/html": init.flags.incl(bifHTML) return pager.connected2(init) if init.shortContentType == "text/plain" or bifSave in init.flags: return pager.connected2(init) if entry != nil: if pager.runMailcap(init, entry).isErr: return ctx.jsQuit(pager, 1) return pager.connected2(init) elif pager.config{"headless"} != hmFalse: return pager.connected2(init) else: let (_, i) = pager.findMailcapPrevNext(init, -1) if i < 0 and init.shortContentType.isTextType(): return pager.connected2(init) let arg0 = ctx.toJS(i) if JS_IsException(arg0): return arg0 return ctx.toUndefined(ctx.connected(init, bcrMailcap, arg0)) proc handleRead(pager: Pager; init: BufferInit): JSValue = case init.connectionState of cdsBeforeResult: var res = int(ceLoaderGone) var msg: string init.stream.withPacketReaderFire r: r.sread(res) if res == 0: # continue r.sread(init.istreamOutputId) init.connectionState = cdsBeforeStatus let host = init.url.host if host == "": init.loadInfo = "Loading " & $init.url else: init.loadInfo = "Connected to " & host & ". Downloading..." pager.copyLoadInfo(init) else: r.sread(msg) if res != 0: # done if msg == "": msg = getLoaderErrorMessage(res) return pager.fail(init, msg) of cdsBeforeStatus: pager.loader.unregister(init) let stream = move(init.stream) let response = newResponse(init.request, stream, init.istreamOutputId) stream.withPacketReaderFire r: r.sread(response.status) r.sreadList(response.headers) init.applyResponse(response, pager.mimeTypes.t) let redirect = response.getRedirect(init.request) let ctx = pager.jsctx var arg0 = JS_UNDEFINED let cres = if redirect != nil: arg0 = ctx.toJS(redirect) bcrRedirect elif response.status == 401: bcrUnauthorized else: # This forces client to ask for confirmation before quitting. pager.hasload = true if bifHistory in init.flags: pager.lineHist[lmLocation].add($init.url) init.istreamOutputId = response.outputId init.ostream = stream if init.filterCmd != "": pager.setEnvVars(pager.defaultEnv()) let ostream = pager.execPipeSink(init.filterCmd, init.ostream) if ostream == nil: return pager.fail(init, "failed to filter buffer") init.ostream = ostream return pager.initMailcap(init) stream.sclose() return ctx.connected(init, cres, arg0) return JS_UNDEFINED # private proc setMenu(ctx: JSContext; pager: Pager; val: JSValueConst): Opt[void] {. jsfset: "menu".} = if JS_IsNull(val): pager.menu = nil else: ?ctx.fromJS(val, pager.menu) ok() # private proc handleStderr(pager: Pager) {.jsfunc.} = const BufferSize = 4096 const prefix = "STDERR: " var buffer {.noinit.}: array[BufferSize, char] let estream = pager.forkserver.estream var hadlf = true while true: let n = estream.read(buffer) if n <= 0: break var i = 0 while i < n: var j = n var found = false for k in i ..< n: if buffer[k] == '\n': j = k + 1 found = true break if hadlf: pager.console.write(prefix) if j - i > 0: pager.console.write(buffer.toOpenArray(i, j - 1)) i = j hadlf = found if not hadlf: pager.console.write('\n') pager.console.flush() proc handleRead(pager: Pager; fd: cint): JSValue = if pager.term.istream != nil and fd == pager.term.istream.fd: return pager.handleUserInput() elif fd == pager.forkserver.estream.fd: pager.handleStderr() elif fd in pager.loader.unregistered: discard # ignore (see handleError) elif (let data = pager.loader.get(fd); data != nil): if data of BufferInit: return pager.handleRead(BufferInit(data)) elif data of BufferInterface: let iface = BufferInterface(data) let ctx = pager.jsctx case ctx.handleCommand(iface) of irOk: if pager.bufferIface == iface and iface.refreshStatus: pager.showAlerts() iface.refreshStatus = false of irException: pager.console.writeException(ctx) of irEOF: discard else: pager.loader.onRead(fd) if data of ConnectData: if pager.runJSJobs().isErr: return JS_EXCEPTION else: assert false return JS_UNDEFINED proc handleWrite(pager: Pager; fd: cint): bool = if pager.term.ostream != nil and pager.term.ostream.fd == fd: let res = pager.term.flush() if res.isErr: return false if res.get: pager.loader.pollData.unregister(pager.term.ostream.fd) pager.term.registeredFlag = false elif fd in pager.loader.unregistered: discard # ignore (see handleError) else: let iface = BufferInterface(pager.loader.get(fd)) # if flushWrite errors out, then poll will notify us anyway discard iface.flushWrite() true proc handleError(pager: Pager; fd: cint): Opt[bool] = if pager.term.istream != nil and fd == pager.term.istream.fd: pager.alert("error in tty") return ok(false) elif fd == pager.forkserver.estream.fd: pager.alert("fork server crashed") return ok(false) elif fd in pager.loader.unregistered: # this fd is already unregistered in this cycle. # it is possible that another handle has taken the same fd number, in # that case we must suppress the error in this cycle and wait for the # next one. discard elif (let data = pager.loader.get(fd); data != nil): if data of BufferInit: let init = BufferInit(data) let res = pager.fail(init, "loader died while loading") if JS_IsException(res): return err() JS_FreeValue(pager.jsctx, res) elif data of BufferInterface: let iface = BufferInterface(data) let isConsole = iface.init == pager.consoleInit if isConsole: pager.dumpConsoleFile = true iface.init.flags.incl(bifCrashed) pager.unregisterBufferIface(iface) pager.console.error("Error in buffer", $iface.init.url) pager.console.flush() if not isConsole: pager.showConsole() dec pager.numload else: discard pager.loader.onError(fd) #TODO handle connection error? else: pager.showConsole() ok(true) let SIGWINCH {.importc, header: "<signal.h>", nodecl.}: cint proc setupSignals(pager: Pager): PosixStream = var pipefd {.noinit.}: array[2, cint] doAssert pipe(pipefd) != -1 let writer = newPosixStream(pipefd[1]) writer.setCloseOnExec() writer.setBlocking(false) var gwriter {.global.}: PosixStream = nil gwriter = writer onSignal SIGWINCH, SIGCHLD: let n = if sig == SIGCHLD: 1u8 else: 0u8 discard gwriter.write([n]) let reader = newPosixStream(pipefd[0]) reader.setCloseOnExec() reader.setBlocking(false) return reader proc handleSigchld(pager: Pager): Opt[void] = var wstatus: cint var pid: int while (pid = int(waitpid(Pid(-1), wstatus, WNOHANG)); pid == -1): if errno != EINTR: return err() # ECHILD, stop looking var cmd: string if pager.pidMap.pop(pid, cmd): if WIFEXITED(wstatus): let n = WEXITSTATUS(wstatus) if n != 0: pager.alert("Command " & cmd & " exited with code " & $n) elif WIFSIGNALED(wstatus): let sig = WTERMSIG(wstatus) # following were likely sent by the user, so don't bother alerting if sig != SIGINT and sig != SIGTERM and sig != SIGKILL: pager.alert("Command " & cmd & " crashed") ok() # private proc inputLoop(ctx: JSContext; pager: Pager): Opt[void] {.jsfunc.} = pager.loader.pollData.register(pager.term.istream.fd, POLLIN) let signals = pager.setupSignals() pager.loader.pollData.register(signals.fd, POLLIN) while true: let timeout = pager.timeouts.sortAndGetTimeout() pager.loader.pollData.poll(timeout) pager.loader.blockRegister() for event in pager.loader.pollData.events: let efd = event.fd if (event.revents and POLLIN) != 0: if event.fd == signals.fd: var sigwinch = false var sigchld = 0u var buffer {.noinit.}: array[256, uint8] while (let n = signals.read(buffer); n > 0): for c in buffer.toOpenArray(0, n - 1): if c == 1: # SIGCHLD inc sigchld else: # 0, SIGWINCH sigwinch = true for u in 0 ..< sigchld: if pager.handleSigchld().isErr: break if sigwinch: if pager.term.queryWindowSize().isErr: return ok() ?pager.windowChange() else: let res = pager.handleRead(efd) if JS_IsException(res): return err() JS_FreeValue(ctx, res) if (event.revents and POLLOUT) != 0: if not pager.handleWrite(efd): return ok() if (event.revents and POLLERR) != 0 or (event.revents and POLLHUP) != 0: if not ?pager.handleError(efd): return ok() if pager.timeouts.run(pager.console): if pager.consoleInit != nil: pager.consoleInit.flags.incl(bifTailOnLoad) pager.loader.unblockRegister() pager.loader.unregistered.setLen(0) ?pager.runJSJobs() if pager.bufferInit == nil and pager.lineEdit == nil: # No buffer to display. # Perhaps we failed to load every single URL the user passed us... if pager.hasload: # ...or at least one connection has succeeded, but we have nothing # to display. Normally, this means that the input stream has been # redirected to a file or to an external program, so we can't just # exit without potentially interrupting that stream. #TODO: a better UI would be querying the number of ongoing streams in # loader, and then asking for confirmation if there is at least one. discard pager.term.anyKey("Hit any key to quit Chawan:", bottom = true) return ok() case pager.updateStatus of ussNone, ussSkip: discard of ussUpdate: pager.refreshStatusMsg() pager.updateStatus = ussNone if not pager.draw(): return ok() ok() proc hasSelectFds(pager: Pager): bool = return not pager.timeouts.empty or pager.numload > 0 or pager.loader.hasFds() # private proc headlessLoop(ctx: JSContext; pager: Pager): Opt[void] {.jsfunc.} = while pager.hasSelectFds(): let timeout = pager.timeouts.sortAndGetTimeout() pager.loader.pollData.poll(timeout) pager.loader.blockRegister() for event in pager.loader.pollData.events: let efd = event.fd if (event.revents and POLLIN) != 0: let res = pager.handleRead(efd) if JS_IsException(res): return err() JS_FreeValue(ctx, res) if (event.revents and POLLOUT) != 0: if not pager.handleWrite(efd): return ok() if (event.revents and POLLERR) != 0 or (event.revents and POLLHUP) != 0: if not ?pager.handleError(efd): return ok() pager.loader.unblockRegister() pager.loader.unregistered.setLen(0) discard pager.timeouts.run(pager.console) ?pager.runJSJobs() ok() # List of properties that are defined on both Buffer and as reflectors # on Pager. # It's a horrible setup that should not be extended anymore, instead users # should just use `pager.buffer'. const LegacyReflectFuncList = [ cstring"cursorUp", "cursorDown", "cursorLeft", "cursorRight", "cursorLineBegin", "cursorLineEnd", "cursorLineTextStart", "cursorNextWord", "cursorNextViWord", "cursorNextBigWord", "cursorPrevWord", "cursorPrevViWord", "cursorPrevBigWord", "cursorWordEnd", "cursorViWordEnd", "cursorBigWordEnd", "cursorWordBegin", "cursorViWordBegin", "cursorBigWordBegin", "getCurrentWord", "cursorNextLink", "cursorPrevLink", "cursorLinkNavDown", "cursorLinkNavUp", "cursorNextParagraph", "cursorPrevParagraph", "cursorNthLink", "cursorRevNthLink", "pageUp", "pageDown", "pageLeft", "pageRight", "halfPageUp", "halfPageDown", "halfPageLeft", "halfPageRight", "scrollUp", "scrollDown", "scrollLeft", "scrollRight", "click", "cursorFirstLine", "cursorLastLine", "cursorTop", "cursorMiddle", "cursorBottom", "lowerPage", "lowerPageBegin", "centerLine", "centerLineBegin", "raisePage", "raisePageBegin", "nextPageBegin", "cursorLeftEdge", "cursorMiddleColumn", "cursorRightEdge", "centerColumn", "findNextMark", "setMark", "clearMark", "gotoMark", "gotoMarkY", "getMarkPos", "cursorToggleSelection", "getSelectionText", "markURL", "showLinkHints", "toggleImages", "saveLink", "saveSource", "setCursorX", "setCursorY", "setCursorXY", "setCursorXCenter", "setCursorYCenter", "setCursorXYCenter", "setFromX", "setFromY", "setFromXY", "find", "cancel", "reshape" ] const LegacyReflectGetList = [ cstring"url", "hoverTitle", "hoverLink", "hoverImage", "cursorx", "cursory", "fromx", "fromy", "numLines", "width", "height", "process", "title", "next", "prev", "select", "currentSelection" ] proc legacyReflectFunction(ctx: JSContext; this: JSValueConst; argc: cint; argv: JSValueConstArray; magic: cint): JSValue {.cdecl.} = var pager: Pager if ctx.fromJS(this, pager).isErr: return JS_EXCEPTION let cval = if pager.menu != nil: ctx.toJS(pager.menu) else: JS_GetProperty(ctx, this, pager.bufferAtom) if JS_IsException(cval): return cval let val = JS_GetPropertyStr(ctx, cval, LegacyReflectFuncList[magic]) if JS_IsException(val): JS_FreeValue(ctx, cval) return JS_EXCEPTION if JS_IsUndefined(val): JS_FreeValue(ctx, cval) return JS_UNDEFINED let res = JS_Call(ctx, val, cval, argc, argv) ctx.freeValues(val, cval) return res proc legacyReflectGetter(ctx: JSContext; this: JSValueConst; magic: cint): JSValue {.cdecl.} = var pager: Pager if ctx.fromJS(this, pager).isErr: return JS_EXCEPTION let cval = if pager.menu != nil: ctx.toJS(pager.menu) else: JS_GetProperty(ctx, this, pager.bufferAtom) if JS_IsException(cval): return cval let res = JS_GetPropertyStr(ctx, cval, LegacyReflectGetList[magic]) JS_FreeValue(ctx, cval) return res proc addPagerModule*(ctx: JSContext): Opt[void] = let pagerCID = ctx.registerType(Pager) if pagerCID == 0: return err() let proto = JS_GetClassProto(ctx, pagerCID) var f: JSCFunctionType f.generic_magic = legacyReflectFunction for i, name in LegacyReflectFuncList.mypairs: let fun = JS_NewCFunction2(ctx, f.generic, name, 0, JS_CFUNC_generic_magic, cint(i)) if ctx.defineProperty(proto, name, fun) == dprException: return err() f.getter_magic = legacyReflectGetter for i, name in LegacyReflectGetList.mypairs: let fun = JS_NewCFunction2(ctx, f.generic, name, 0, JS_CFUNC_getter_magic, cint(i)) let atom = JS_NewAtom(ctx, name) if JS_DefineProperty(ctx, proto, atom, JS_UNDEFINED, fun, JS_UNDEFINED, JS_PROP_HAS_GET) < 0: return err() JS_FreeValue(ctx, fun) JS_FreeAtom(ctx, atom) JS_FreeValue(ctx, proto) ok() {.pop.} # raises: [] ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/local/select.nim������������������������������������������������������������������0000664�0000000�0000000�00000030521�15202323131�0017000�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import monoucha/fromjs import monoucha/jsbind import monoucha/jsutils import monoucha/quickjs import monoucha/tojs import types/cell import types/jsopt import types/opt import utils/lrewrap import utils/luwrap import utils/strwidth import utils/twtstr type SelectOption* = object nop*: bool s*: string Select* = ref object options: seq[SelectOption] selected: int # new selection fromy {.jsget.}: int # first index to display cursory {.jsget.}: int # hover index maxw: int # widest option maxh: int # maximum number of options on screen # location on screen #TODO make this absolute x {.jsget.}: int y {.jsget.}: int redraw*: bool unselected: bool finish: JSValue jsDestructor(Select) proc finalize(rt: JSRuntime; select: Select) {.jsfin.} = JS_FreeValueRT(rt, select.finish) proc mark(rt: JSRuntime; select: Select; markFunc: JS_MarkFunc) {.jsmark.} = JS_MarkValue(rt, select.finish, markFunc) proc fromJS*(ctx: JSContext; val: JSValueConst; res: var SelectOption): FromJSResult = if JS_IsNull(val): res = SelectOption(nop: true) else: res = SelectOption() ?ctx.fromJS(val, res.s) fjOk proc toJS*(ctx: JSContext; x: SelectOption): JSValue = if x.nop: return JS_NULL return ctx.toJS(x.s) proc queueDraw(select: Select) = select.redraw = true proc numLines(select: Select): int {.jsfget.} = return select.options.len proc markPos0(select: Select) {.jsfunc.} = discard proc markPos(select: Select) {.jsfunc.} = discard proc setFromY(select: Select; y: int) = select.fromy = max(min(y, select.options.len - select.maxh), 0) proc width(select: Select): int {.jsfget.} = return select.maxw + 2 proc height(select: Select): int {.jsfget.} = return select.maxh + 2 proc setCursorY(select: Select; y: int) {.jsfunc.} = let y = clamp(y, 0, select.options.high) if select.options[max(y, 0)].nop: if not select.unselected: select.unselected = true select.queueDraw() return if select.fromy > y: select.setFromY(y) if select.fromy + select.maxh <= y: select.setFromY(y - select.maxh + 1) select.cursory = y if select.unselected: select.unselected = false select.queueDraw() proc getCursorX*(select: Select): int = if select.cursory == -1: return select.x return select.x + 1 proc getCursorY*(select: Select): int = return max(select.y + 1 + select.cursory - select.fromy, 0) proc cursorDown(select: Select; n = 1) {.jsfunc.} = var y = select.cursory + 1 var n = n while y < select.options.len: if not select.options[y].nop: dec n if n <= 0: break inc y select.setCursorY(y) proc cursorUp(select: Select; n = 1) {.jsfunc.} = var y = select.cursory - 1 var n = n while y >= 0: if not select.options[y].nop: dec n if n <= 0: break dec y select.setCursorY(y) proc scrollDown(select: Select; n = 1) {.jsfunc.} = let tfy = select.fromy + n select.setFromY(tfy) if select.fromy > select.cursory: select.cursorDown(select.fromy - select.cursory) elif tfy > select.fromy: select.cursorDown(tfy - select.fromy) select.queueDraw() proc scrollUp(select: Select; n = 1) {.jsfunc.} = let tfy = select.fromy - n select.setFromY(tfy) if select.fromy + select.maxh <= select.cursory: select.cursorUp(select.cursory - select.fromy - select.maxh + 1) elif tfy < select.fromy: select.cursorUp(select.fromy - tfy) select.queueDraw() proc cursorPrevLink(select: Select; n = 1) {.jsfunc.} = select.cursorUp(n) proc cursorNextLink(select: Select; n = 1) {.jsfunc.} = select.cursorDown(n) proc cursorLinkNavUp(select: Select; n = 1) {.jsfunc.} = select.cursorUp(n) proc cursorLinkNavDown(select: Select; n = 1) {.jsfunc.} = select.cursorDown(n) proc cursorNthLink(select: Select; n = 1) {.jsfunc.} = select.setCursorY(n - 1) proc cursorRevNthLink(select: Select; n = 1) {.jsfunc.} = select.setCursorY(select.options.len - n) proc halfPageDown(select: Select; n = 1) {.jsfunc.} = select.cursorDown(select.maxh div 2) proc halfPageUp(select: Select; n = 1) {.jsfunc.} = select.cursorUp(select.maxh div 2) proc pageDown(select: Select; n = 1) {.jsfunc.} = select.cursorDown(select.maxh) proc pageUp(select: Select; n = 1) {.jsfunc.} = select.cursorUp(select.maxh) proc finish(ctx: JSContext; select: Select): JSValue = let selected = ctx.toJS(select.selected) if JS_IsException(selected): return JS_EXCEPTION let finish = move(select.finish) select.finish = JS_UNDEFINED ctx.callSinkFree(finish, JS_UNDEFINED, selected) proc cancel(ctx: JSContext; select: Select): JSValue {.jsfunc.} = select.selected = -1 return ctx.finish(select) proc submit(ctx: JSContext; select: Select): JSValue {.jsfunc.} = select.selected = select.cursory return ctx.finish(select) proc click(ctx: JSContext; select: Select): JSValue {.jsfunc.} = if select.unselected or select.cursory >= 0 and select.cursory < select.options.len and select.options[select.cursory].nop: return JS_UNDEFINED else: return ctx.submit(select) proc cursorLeft(ctx: JSContext; select: Select): JSValue {.jsfunc.} = ctx.cancel(select) proc cursorRight(ctx: JSContext; select: Select): JSValue {.jsfunc.} = ctx.click(select) proc cursorFirstLine(select: Select) {.jsfunc.} = if select.cursory != 0: select.cursory = 0 select.fromy = 0 select.queueDraw() proc cursorLastLine(select: Select) {.jsfunc.} = if select.cursory < select.options.len: select.fromy = max(select.options.len - select.maxh, 0) select.cursory = select.fromy + select.maxh - 1 select.queueDraw() proc cursorTop(select: Select) {.jsfunc.} = select.setCursorY(select.fromy) proc cursorMiddle(select: Select) {.jsfunc.} = select.setCursorY(select.fromy + (select.height - 1) div 2) proc cursorBottom(select: Select) {.jsfunc.} = select.setCursorY(select.fromy + select.height - 1) proc cursorNextMatch(select: Select; regex: REBytecode; wrap: bool) = var j = -1 for i in select.cursory + 1 ..< select.options.len: if regex.match(select.options[i].s): j = i break if j != -1: select.setCursorY(j) select.queueDraw() elif wrap: for i in 0 ..< select.cursory: if regex.match(select.options[i].s): j = i break if j != -1: select.setCursorY(j) select.queueDraw() proc cursorPrevMatch(select: Select; regex: REBytecode; wrap: bool) = var j = -1 for i in countdown(select.cursory - 1, 0): if regex.match(select.options[i].s): j = i break if j != -1: select.setCursorY(j) select.queueDraw() elif wrap: for i in countdown(select.options.high, select.cursory): if regex.match(select.options[i].s): j = i break if j != -1: select.setCursorY(j) select.queueDraw() proc cursorPrevMatch(ctx: JSContext; select: Select; re: JSValueConst; wrap: bool; n: int): Opt[void] {.jsfunc.} = var plen: cint let p = JS_GetRegExpBytecode(ctx, re, plen) if p == nil: return err() for i in 0 ..< n: select.cursorPrevMatch(cast[REBytecode](p), wrap) ok() proc cursorNextMatch(ctx: JSContext; select: Select; re: JSValueConst; wrap: bool; n: int): Opt[void] {.jsfunc.} = var plen: cint let p = JS_GetRegExpBytecode(ctx, re, plen) if p == nil: return err() for i in 0 ..< n: select.cursorNextMatch(cast[REBytecode](p), wrap) ok() proc unselect(select: Select) {.jsfunc.} = if not select.unselected: select.unselected = true select.queueDraw() proc drawBorders(display: var FixedGrid; sx, ex, sy, ey: int; upmore, downmore: bool) = for y in sy .. ey: var x = 0 let yi = y * display.width while true: if display[yi + x].str == "": display[yi + x].str = " " let w = display[yi + x].str.width() if x + w > sx: while x < sx: display[yi + x].str = " " inc x break x += w # Draw corners. let tl = if upmore: bdcVerticalBarLeft else: bdcCornerTopLeft let tr = if upmore: bdcVerticalBarRight else: bdcCornerTopRight let bl = if downmore: bdcVerticalBarLeft else: bdcCornerBottomLeft let br = if downmore: bdcVerticalBarRight else: bdcCornerBottomRight const fmt = Format() display[sy * display.width + sx].str = $tl display[sy * display.width + ex].str = $tr display[ey * display.width + sx].str = $bl display[ey * display.width + ex].str = $br display[sy * display.width + sx].format = fmt display[sy * display.width + ex].format = fmt display[ey * display.width + sx].format = fmt display[ey * display.width + ex].format = fmt # Draw top, bottom borders. let ups = if upmore: " " else: $bdcHorizontalBarTop let downs = if downmore: " " else: $bdcHorizontalBarBottom for x in sx + 1 .. ex - 1: display[sy * display.width + x].str = ups display[ey * display.width + x].str = downs display[sy * display.width + x].format = fmt display[ey * display.width + x].format = fmt if upmore: display[sy * display.width + sx + (ex - sx) div 2].str = ":" if downmore: display[ey * display.width + sx + (ex - sx) div 2].str = ":" # Draw left, right borders. for y in sy + 1 .. ey - 1: display[y * display.width + sx].str = $bdcVerticalBarLeft display[y * display.width + ex].str = $bdcVerticalBarRight display[y * display.width + sx].format = fmt display[y * display.width + ex].format = fmt proc drawSelect*(select: Select; display: var FixedGrid) = if display.width < 2 or display.height < 2: return # border does not fit... # Max width, height with one row/column on the sides. let mw = display.width - 2 let mh = display.height - 2 var sy = select.y let si = select.fromy var ey = min(sy + select.options.len, mh) + 1 var sx = select.x if sx + select.maxw >= mw: sx = display.width - select.maxw if sx < 0: # This means the widest option is wider than the available screen. # w3m simply cuts off the part that doesn't fit, and we do that too, # but I feel like this may not be the best solution. sx = 0 var ex = min(sx + select.maxw, mw) + 1 let upmore = select.fromy > 0 let downmore = select.fromy + mh < select.options.len drawBorders(display, sx, ex, sy, ey, upmore, downmore) # move inside border inc sy inc sx var format = Format() for y in sy ..< ey: let i = y - sy + si var j = 0 var x = sx let dls = y * display.width if select.getCursorY() == y and not select.unselected: format.incl(ffReverse) else: format.excl(ffReverse) while j < select.options[i].s.len: let pj = j let u = select.options[i].s.nextUTF8(j) let uw = u.width() let nx = x + uw if nx > ex: break display[dls + x].str = "" if u.isControlChar(): display[dls + x].str &= u.controlToVisual() else: for l in pj ..< j: display[dls + x].str &= select.options[i].s[l] display[dls + x].format = format if x == sx: # do not reverse the position of the cursor display[dls + x].format.excl(ffReverse) inc x while x < nx: display[dls + x].str = "" display[dls + x].format = format inc x while x < ex: display[dls + x].str = " " display[dls + x].format = format inc x proc windowChange*(select: Select; width, height: int) {.jsfunc.} = if select.y + select.options.len >= height - 2: select.y = max(height - 2 - select.options.len, 0) select.maxh = min(height - 2, select.options.len) if select.x + select.maxw + 2 > width: #TODO I don't know why but - 2 does not work. select.x = max(width - select.maxw - 3, 0) select.setCursorY(select.cursory) select.queueDraw() proc newSelect(ctx: JSContext; options: seq[SelectOption]; selected: int; x, y, width, height: int; finish: JSValueConst): Opt[Select] {.jsctor.} = let select = Select( selected: selected, x: x, y: y, options: options, finish: JS_DupValue(ctx, finish) ) var maxw = 0 for opt in select.options.mitems: opt.s.mnormalize() opt.s = ' ' & opt.s & ' ' maxw = max(maxw, opt.s.width()) select.maxw = maxw for opt in select.options.mitems: if opt.nop: opt.s = ' ' & ($bdcHorizontalBarTop).repeat(maxw - 2) & ' ' select.windowChange(width, height) select.setCursorY(selected) ok(select) proc addSelectModule*(ctx: JSContext): JSClassID = return ctx.registerType(Select) {.pop.} # raises: [] �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/local/term.nim��������������������������������������������������������������������0000664�0000000�0000000�00000262441�15202323131�0016500�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/os import std/posix import std/termios import config/config import config/conftypes import encoding/charset import encoding/decoder import encoding/encoder import encoding/encodercore import io/dynstream import io/poll import server/loaderiface import types/bitmap import types/blob import types/cell import types/color import types/opt import types/winattrs import utils/myposix import utils/strwidth import utils/twtstr type TerminalType = enum ttAdm3a = "adm3a" ttAlacritty = "alacritty" ttContour = "contour" # pretends to be XTerm ttDvtm = "dvtm" ttEat = "eat" ttEterm = "eterm" ttFbterm = "fbterm" ttFoot = "foot" ttFreebsd = "freebsd" # pretends to be XTerm ttGhostty = "ghostty" ttIterm2 = "iterm2" ttKitty = "xterm-kitty" # hardly XTerm ttKonsole = "konsole" # pretends to be XTerm ttLinux = "linux" ttMintty = "mintty" ttMlterm = "mlterm" ttMsTerminal = "ms-terminal" ttPutty = "putty" ttRio = "rio" ttRlogin = "rlogin" ttRxvt = "rxvt" ttScreen = "screen" ttSt = "st" ttSyncterm = "syncterm" ttTerminology = "terminology" # pretends to be XTerm ttTmux = "tmux" ttUrxvt = "rxvt-unicode" ttVertigo = "vertigo" # pretends to be XTerm ttVt100 = "vt100" ttVt100Nav = "vt100-nav" # VT100 without advanced video ttVt420 = "vt420" ttVt52 = "vt52" ttVte = "vte" # pretends to be XTerm ttWezterm = "wezterm" ttWterm = "wterm" ttXst = "xst" ttXterm = "xterm" ttYaft = "yaft" ttZellij = "zellij" # pretends to be its underlying terminal CanvasImageDimensions* = object # relative position on screen (in cells, may be negative) x: int y*: int # relative position on screen (in pixels, may be negative) xpx: int ypx: int # original dimensions (after resizing) width*: int height*: int # offset (crop start) offx*: int offy: int # kitty only: X/Y offset *inside* cell. (TODO implement for sixel too) # has nothing to do with offx/offy. offx2: int offy2: int # size cap (crop end) # Note: this 0-based, so the final display size is # (dispw - offx, disph - offy) dispw*: int disph: int # absolute x, y in container rx: int ry: int # Sixel only: erry is the y deviation from 6 lines. # erry2 is the same, but it's not affected by scroll. erry*: int erry2*: int CanvasImage* = ref object pid: int bmp*: NetworkBitmap dims*: CanvasImageDimensions damaged*: bool transparent: bool scrolled: bool # sixel only: set if screen was scrolled since printing preludeLen: int kittyId: uint data: Blob next: CanvasImage TerminalPage {.acyclic.} = ref object a: seq[char] # bytes to flush n: int # bytes of s already flushed next: TerminalPage TermdescFlag = enum # 16 bits, 1 free tfTitle # can set window title tfPreEcma48 # does not support ECMA-48/VT100-like queries (DA1 etc.) tfXtermQuery # supports XTerm-like queries (background color etc.) tfAltScreen # has alt screen tfBleedsAPC # cannot handle APC tfColor1 # tfColor1: ANSI tfColor2 # tfColor2: eight-bit; together with tfColor1: true-color tfSixel # known to support Sixel (and doesn't advertise it) tfSpecialGraphics # supports DEC special graphics tfMargin # needs a 1-char margin at the right edge tfMouse # supports SGR mouse tfPrimary # interprets primary correctly in OSC 52 tfBracketedPaste # doesn't choke on bracketed paste (might not have it) tfFlowControl # uses XON/XOFF flow control (usually hardware terminals) tfScroll # supports VT100-style scroll (with scroll area) tfFastScroll # has SD/SU control sequences Termdesc = set[TermdescFlag] FrameType = enum ftCurrent # non-discardable ftNext # discardable Frame = object head: TerminalPage # output buffer queue tail: TerminalPage # last output buffer canvasImagesHead: CanvasImage canvas: seq[FixedCell] kittyImagesToClear: seq[uint] # Kitty only; vector of image ids lineDamage: seq[int] title: string # current title pos: tuple[pid, x, y: int] scrollTodo: int # lines to scroll (negative = up, positive = down) scrollBottom: int # last line of currently set scroll area (-1 if reset) format: Format # current formatting cursorx: uint32 cursory: uint32 cursorKnown: bool # set if we know the cursor's position fastScrollTodo: bool # flag to do fast scroll queueTitleFlag: bool # set title on next draw mouseEnabled: bool specialGraphics: bool # flag for special graphics processing cursorHidden: bool Terminal* = ref object termType: TerminalType cs*: Charset te: TextEncoder config: Config istream*: PosixStream ostream*: PosixStream tdctx: TextDecoderContext eparser: EventParser canvasImagesTmpHead: CanvasImage # temp list during rescan canvasImagesTmpTail: CanvasImage attrs*: WindowAttributes formatMode: FormatMode imageMode*: ImageMode cleared: bool asciiOnly: bool osc52Copy: bool osc52Primary*: bool ttyFlag: bool registeredFlag*: bool # kernel won't accept any more data right now desc: Termdesc origTermios: Termios newTermios: Termios defaultBackground: RGBColor defaultForeground: RGBColor ibuf: array[256, char] # buffer for chars when we can't process them ibufLen: int # len of ibuf ibufn: int # position in ibuf dynbuf: string # buffer for UTF-8 text input by the user, for areadChar dynbufn: int # position in dynbuf frames: array[FrameType, Frame] frameType: FrameType loader: FileLoader # callback to register ostream sixelRegisterNum*: uint16 kittyId: uint # counter for kitty image (*not* placement) ids. colorMap: array[16, RGBColor] QueryState = enum qsBackgroundColor, qsForegroundColor, qsXtermAllowedOps, qsXtermWindowOps, qsKitty, qsColorRegisters, qsTcapRGB, qsANSIColor, qsDA1, qsCellSize, qsWindowPixels, qsCPR, qsNone EventState = enum esNone, esEsc, esCSI, esCSIQMark, esCSIEquals, esCSINum, esBracketed, esBracketedEsc, esBracketedCSI, esBracketedCSI2, esBracketedCSI20, esBracketedCSI201, esCSILt, esOSC, esOSC6, esOSC60, esOSC60Semi, esOSC61, esOSC61Semi, esOSC4, esOSC4Semi, esOSC4SemiNum, esOSC1, esOSC10, esOSC10Semi, esOSC11, esOSC11Semi, esDCS, esDCS0, esDCS0Plus, esDCS1, esDCS1Plus, esDCS1PlusR, esAPC, esAPCG, esSTEsc, esSkipToST, esBacktrack EventParser = object state: EventState # queryState signifies where we are in the query. Escape sequences for # queries that we've a) already seen or b) come before queries we've # already seen are not detected. e.g. queryState = qsCellSize implies # the next response must be a cell size response or anything that comes # after that. DA1 is the last query as it seems to be universally # emulated. queryState: QueryState keyLen: int8 flag: bool colorState: uint8 num: uint32 backtrackStack: seq[char] nums: seq[uint32] # buffer for numeric parameters # It is possible that we need to send a query before the previous one # ends; in that case, we just put the next desired query state on this # stack and restart as soon as we receive all responses to the previous # query. queryStateStack: seq[QueryState] buf: string # string buffer InputEventType* = enum ietKey = "key" ietKeyEnd = "keyEnd" ietPaste = "paste" ietMouse = "mouse" ietWindowChange = "windowChange" ietRedraw = "redraw" InputEvent* = object case t*: InputEventType of ietKey: # key press - UTF-8 bytes c*: char of ietKeyEnd: # key press done (if not in bracketed paste mode) discard of ietPaste: # bracketed paste done discard of ietWindowChange: # window changed through query discard of ietRedraw: # must redraw because of query (e.g. Sixel detected) discard of ietMouse: m*: MouseInput MouseInputType* = enum mitPress = "press", mitRelease = "release", mitMove = "move" MouseInputMod* = enum mimShift = "shift", mimCtrl = "ctrl", mimMeta = "meta" MouseButton* = enum mibLeft = (1, "left") mibMiddle = (2, "middle") mibRight = (3, "right") mibWheelUp = (4, "wheelUp") mibWheelDown = (5, "wheelDown") mibWheelLeft = (6, "wheelLeft") mibWheelRight = (7, "wheelRight") mibThumbInner = (8, "thumbInner") mibThumbTip = (9, "thumbTip") mibButton10 = (10, "button10") mibButton11 = (11, "button11") MouseInputPosition* = tuple[x, y: int32] MouseInput* = object t*: MouseInputType button*: MouseButton mods*: set[MouseInputMod] pos*: MouseInputPosition # Forward declarations proc windowChange(term: Terminal) proc updateCanvasImage(term: Terminal; image: CanvasImage; dims: CanvasImageDimensions; maxh: int): bool proc clearImages*(term: Terminal; maxh: int) const StateMap = [ esNone: cstring"", esEsc: "\e", esCSI: "\e[", esCSIQMark: "\e[?", esCSIEquals: "\e[=", esCSINum: "\e[", esBracketed: "", esBracketedEsc: "\e", esBracketedCSI: "\e[", esBracketedCSI2: "\e[2", esBracketedCSI20: "\e[20", esBracketedCSI201: "\e[201", esCSILt: "\e[<", esOSC: "\e]", esOSC6: "\e]6", esOSC60: "\e]60", esOSC60Semi: "\e]60;", esOSC61: "\e]61", esOSC61Semi: "\e]61;", esOSC4: "\e]4", esOSC4Semi: "\e]4;", esOSC4SemiNum: "", esOSC1: "\e]1", esOSC10: "\e]10", esOSC10Semi: "\e]10;", esOSC11: "\e]11", esOSC11Semi: "\e]11;", esDCS: "\eP", esDCS0: "\eP0", esDCS0Plus: "\eP0+", esDCS1: "\eP1", esDCS1Plus: "\eP1+", esDCS1PlusR: "\eP1+r", esAPC: "\e_", esAPCG: "\e_G", esSTEsc: "\e", esSkipToST: "", esBacktrack: "", ] # Built-in terminal capability database. # # In an ideal world, none of this would be necessary as we could just get # capabilities from the terminal itself. Alas, some insist on terminfo # being the sole source of "reliable" information (it's not reliable...), so # we must emulate it to some extent. # # In general, terminal attributes that we can detect with queries are # omitted. Some terminals only set COLORTERM, but do not respond to # queries; this may not propagate through SSH, so we still check TERM for # these. # # For terminals I cannot directly test, our data is based on TERMINALS.md in # notcurses and terminfo.src in ncurses. # # XtermCompatible: probably not 1:1 compatible, but either a) compatible # enough for our purposes or b) advertises incompatibilities correctly # through queries. Descriptions with XtermCompatible and no extra flags # are redundant; I'm including them only to have a list of terminals already # tested. # # Note: we intentionally do not include tfPrimary here, because some poorly # written terminals choke on it despite advertising themselves as XTerm. const XtermCompatible = { tfTitle, tfXtermQuery, tfAltScreen, tfSpecialGraphics, tfMouse, tfBracketedPaste, tfScroll, tfFastScroll } # This for hardware terminals, *not* VT100-compatible emulators. # The primary difference is that no emulator uses flow control (XON/XOFF) # so we just disable it on those. const Vt100Compatible = { tfScroll, tfSpecialGraphics, tfFlowControl } const AnsiColorFlag = {tfColor1} const EightBitColorFlag = {tfColor2} const TrueColorFlag = {tfColor1, tfColor2} const TermdescMap = [ ttAdm3a: {tfMargin, tfPreEcma48}, ttAlacritty: XtermCompatible + TrueColorFlag, ttContour: XtermCompatible, ttDvtm: {tfAltScreen, tfBleedsAPC, tfBracketedPaste} + AnsiColorFlag, ttEat: XtermCompatible + TrueColorFlag, # eterm bleeds titles. ttEterm: {tfXtermQuery, tfBracketedPaste, tfScroll} + AnsiColorFlag, ttFbterm: {tfXtermQuery, tfBracketedPaste} + AnsiColorFlag, ttFoot: XtermCompatible, # FreeBSD has code to respond to queries, but it's #if 0'd out :( # It has no bracketed paste (duh). ttFreebsd: {tfPreEcma48, tfScroll} + AnsiColorFlag, ttGhostty: XtermCompatible, ttIterm2: XtermCompatible, ttKitty: XtermCompatible + TrueColorFlag + {tfPrimary}, ttKonsole: XtermCompatible, # Linux accepts true color or eight bit sequences, but as per the # man page they are "shoehorned into 16 colors". This breaks color # correction, so we stick to ANSI. # It also fails to advertise ANSI color in DA1, so we set it here. # Linux has no alt screen, and no paste (let alone bracketed). ttLinux: {tfXtermQuery, tfScroll} + AnsiColorFlag, ttMintty: XtermCompatible + TrueColorFlag, ttMlterm: XtermCompatible + TrueColorFlag, ttMsTerminal: XtermCompatible + TrueColorFlag, ttPutty: XtermCompatible + TrueColorFlag, ttRio: XtermCompatible, ttRlogin: XtermCompatible + TrueColorFlag, ttRxvt: XtermCompatible + {tfBleedsAPC} + EightBitColorFlag, # screen does true color, but only if you explicitly enable it. # The alt screen is also opt-in. ttScreen: XtermCompatible - {tfAltScreen} + EightBitColorFlag, ttSt: XtermCompatible + TrueColorFlag, # SyncTERM supports Sixel, but it doesn't have private color registers # so we omit it. ttSyncterm: XtermCompatible + TrueColorFlag + {tfMargin}, ttTerminology: XtermCompatible + {tfBleedsAPC}, # Scrolling on tmux destroys images. ttTmux: XtermCompatible + TrueColorFlag - {tfScroll}, # Direct color in urxvt is not really true color; apparently it # just takes the nearest color of the 256 registers and replaces it # with the direct color given. I don't think this is much worse than # our basic quantization for 256 colors, so we use it anyway. ttUrxvt: XtermCompatible + {tfBleedsAPC} + TrueColorFlag, ttVertigo: XtermCompatible + TrueColorFlag, ttVt100: Vt100Compatible, ttVt100Nav: Vt100Compatible, ttVt420: Vt100Compatible + {tfFastScroll}, ttVt52: {tfPreEcma48, tfFlowControl}, ttVte: XtermCompatible + TrueColorFlag, ttWezterm: XtermCompatible, ttWterm: XtermCompatible + TrueColorFlag, ttXst: XtermCompatible + TrueColorFlag, ttXterm: XtermCompatible, # yaft supports Sixel, but can't tell us so in DA1. ttYaft: XtermCompatible + {tfSixel, tfBleedsAPC} - {tfAltScreen, tfFastScroll}, # zellij advertises Sixel, but it's completely broken. ttZellij: XtermCompatible + TrueColorFlag, ] # reverse index (cursor up) const RI = "\eM" # control sequence introducer const CSI = "\e[" # primary device attributes const DA1 = CSI & 'c' # push/pop current title to/from the terminal's title stack const PushTitle = CSI & "22t" const PopTitle = CSI & "23t" # report xterm text area size in pixels const QueryWindowPixels = CSI & "14t" # report cell size const QueryCellSize = CSI & "16t" # number of color registers const QueryColorRegisters = CSI & "?1;1;0S" # report active position const QueryCursorPosition = CSI & "6n" # device control string const DCS = "\eP" # string terminator const ST = "\e\\" # xterm get terminal capability rgb const QueryTcapRGB = DCS & "+q524742" & ST # OS command const OSC = "\e]" const QueryForegroundColor = OSC & "10;?" & ST const QueryBackgroundColor = OSC & "11;?" & ST const QueryANSIColors = block: var s = "" for n in 0 ..< 16: s &= OSC & "4;" & $n & ";?" & ST s const QueryXtermAllowedOps = OSC & "60" & ST const QueryXtermWindowOps = OSC & "61;allowWindowOps" & ST # DEC set template DECSET(s: varargs[string, `$`]): string = CSI & '?' & s.join(';') & 'h' # DEC reset template DECRST(s: varargs[string, `$`]): string = CSI & '?' & s.join(';') & 'l' # alt screen const SetAltScreen = DECSET(1049) const ResetAltScreen = DECRST(1049) # mouse tracking const SetSGRMouse = DECSET(1002, 1006) const ResetSGRMouse = DECRST(1002, 1006) const SetBracketedPaste = DECSET(2004) const ResetBracketedPaste = DECRST(2004) const BracketedPasteStart* = CSI & "200~" const BracketedPasteEnd* = CSI & "201~" # show/hide cursor const ShowCursor = DECSET(25) const HideCursor = DECRST(25) # application program command const APC = "\e_" const KittyQuery = APC & "Gi=1,s=1,v=1,a=q;AAAAAA" & ST iterator canvasImages(frame: Frame): CanvasImage = var image = frame.canvasImagesHead while image != nil: yield image image = image.next template frame(term: Terminal): Frame = term.frames[term.frameType] proc clone(image: CanvasImage): CanvasImage = let image2 = CanvasImage() image2[] = image[] image2.next = nil image2 # Frame skipping. # # Conceptually, we have a FIFO queue of frames coming in, with all # frames that aren't partially flushed being discardable. (Theoretically # we could also discard partially flushed frames, but this sounds like a # nightmare to implement with minimal benefits.) # # In practice, we don't need an actual queue, this can be implemented as # a two-element array of frames: # * ftCurrent is the frame currently being written; we only ever write data # from here. # * ftNext is a buffered frame, which starts out with a copy of ftCurrent's # state when we start drawing despite ftCurrent not being fully flushed. # Then: # - If we start drawing again and ftCurrent is *still* not flushed, # we drop ftNext in favor of this new frame. # - Once ftCurrent is fully flushed, we "move" ftNext into ftCurrent's # place. proc swapFrame(term: Terminal; frameType: FrameType) = let ot = if frameType == ftCurrent: ftNext else: ftCurrent term.frameType = frameType case frameType of ftCurrent: # Unbuffer. It's fine to destructively read the old canvas here. term.frame.head = move(term.frames[ftNext].head) term.frame.tail = move(term.frames[ftNext].tail) swap(term.frame.canvas, term.frames[ot].canvas) swap(term.frame.lineDamage, term.frames[ot].lineDamage) swap(term.frame.kittyImagesToClear, term.frames[ot].kittyImagesToClear) # could swap this too, but that would keep data alive for longer than # desirable term.frame.canvasImagesHead = move(term.frames[ot].canvasImagesHead) of ftNext: # Buffer. We keep the old canvas intact in ftCurrent for the case where # we get a new frame before this frame becomes active (and this frame # is dropped). term.frame.head = nil term.frame.tail = nil for i in 0 ..< term.frames[ot].canvas.len: term.frame.canvas[i] = term.frames[ot].canvas[i] chaArrayCopy(term.frame.lineDamage, term.frames[ot].lineDamage) #TODO we could avoid some allocations here by reusing CanvasImage # objects from the frame to be dropped var imagesHead: CanvasImage = nil var imagesTail: CanvasImage = nil for image in term.frames[ot].canvasImages: let image2 = image.clone() if imagesTail == nil: imagesHead = image2 else: imagesTail.next = image2 imagesTail = image2 term.frame.kittyImagesToClear = term.frames[ot].kittyImagesToClear term.frame.canvasImagesHead = imagesHead term.frame.title = term.frames[ot].title term.frame.format = term.frames[ot].format term.frame.pos = term.frames[ot].pos term.frame.cursorx = term.frames[ot].cursorx term.frame.cursory = term.frames[ot].cursory term.frame.cursorKnown = term.frames[ot].cursorKnown term.frame.scrollTodo = term.frames[ot].scrollTodo term.frame.scrollBottom = term.frames[ot].scrollBottom term.frame.fastScrollTodo = term.frames[ot].fastScrollTodo term.frame.queueTitleFlag = term.frames[ot].queueTitleFlag term.frame.mouseEnabled = term.frames[ot].mouseEnabled term.frame.specialGraphics = term.frames[ot].specialGraphics term.frame.cursorHidden = term.frames[ot].cursorHidden # Must be called at the start of draw(). proc initFrame*(term: Terminal) = if term.frame.tail != nil: # Started drawing while another frame is not done. # We copy ftCurrent to ftNext; this clones (buffers) the current frame, # dropping the previous buffered frame (if any). term.swapFrame(ftNext) term.frame.scrollTodo = 0 term.frame.fastScrollTodo = false proc flush*(term: Terminal): Opt[bool] = while true: var page = term.frames[ftCurrent].head if page == nil: assert term.frameType != ftNext while page != nil: var n = page.n let H = page.a.len - 1 while n < page.a.len: let m = term.ostream.write(page.a.toOpenArray(n, H)) if m < 0: let e = errno if e != EAGAIN and e != EWOULDBLOCK and e != EINTR: return err() break n += m if n < page.a.len: page.n = n break page = page.next term.frames[ftCurrent].head = page if page != nil: # not done return ok(false) term.frames[ftCurrent].tail = nil if term.frameType == ftCurrent: break # flushed all term.swapFrame(ftCurrent) ok(true) proc startFlush(term: Terminal): Opt[void] = if term.registeredFlag: return ok() if not ?term.flush(): term.loader.pollData.register(term.ostream.fd, POLLOUT) term.registeredFlag = true ok() # Arbitrary buffer size; data is flushed once we exceed it. const BufferSize = 4096 proc write(term: Terminal; s: openArray[char]): Opt[void] = if s.len <= 0: return ok() if s.len <= BufferSize: # merge small writes let tail = term.frame.tail if tail != nil and tail.a.len + s.len > BufferSize: # The buffer is full, so we'll have to flush anyway; try to do it now, # maybe we can at least merge this write with a subsequent one. ?term.startFlush() let page = term.frame.tail if page == nil: let page = TerminalPage(a: @s) term.frame.head = page term.frame.tail = page return ok() let olen = page.a.len if olen + s.len <= BufferSize: page.a.setLen(olen + s.len) copyMem(addr page.a[olen], unsafeAddr s[0], s.len) return ok() # large write, or the buffer is full. ?term.startFlush() var n = 0 if term.frames[ftCurrent].head == nil: while n < s.len: let m = term.ostream.write(s.toOpenArray(n, s.high)) if m < 0: let e = errno if e != EAGAIN and e != EWOULDBLOCK and e != EINTR: return err() break n += m if n < s.len: let page = TerminalPage() if term.frame.tail == nil: term.frame.head = page term.frame.tail = page if term.frameType == ftCurrent: # no need to register next term.loader.pollData.register(term.ostream.fd, POLLOUT) term.registeredFlag = true else: term.frame.tail.next = page term.frame.tail = page page.a = @(s.toOpenArray(n, s.high)) ok() proc write(term: Terminal; c: char): Opt[void] = term.write([c]) proc readChar(term: Terminal): Opt[char] = if term.ibufn == term.ibufLen: term.ibufn = 0 term.ibufLen = term.istream.read(term.ibuf) if term.ibufLen == -1: return err() result = ok(term.ibuf[term.ibufn]) inc term.ibufn proc blockIO0(term: Terminal) = term.istream.setBlocking(true) term.ostream.setBlocking(true) proc blockIO(term: Terminal): Opt[void] = term.istream.setBlocking(true) term.ostream.setBlocking(true) doAssert ?term.flush() ok() proc unblockIO(term: Terminal) = term.istream.setBlocking(false) term.ostream.setBlocking(false) proc ahandleRead*(term: Terminal): Opt[bool] = term.ibufn = 0 term.ibufLen = term.istream.read(term.ibuf) if term.ibufLen < 0: let e = errno if e != EAGAIN and e != EWOULDBLOCK and e != EINTR: term.blockIO0() return err() term.ibufLen = 0 return ok(false) ok(true) # Note: in theory, we should run the escape parser state machine # *before* parsing the input. # In practice, it doesn't matter how you do it in UTF-8 as long as you # stick to 7-bit chars. proc areadChar(term: Terminal): Opt[char] = if term.dynbufn == term.dynbuf.len: term.dynbufn = 0 term.dynbuf.setLen(0) let H = term.ibufLen - 1 for it in term.tdctx.decode(term.ibuf.toOpenArrayByte(term.ibufn, H), finish = false): term.dynbuf &= it term.ibufn = term.ibufLen if term.dynbuf.len == term.dynbufn: return err() let c = term.dynbuf[term.dynbufn] inc term.dynbufn ok(c) proc backtrack(eparser: var EventParser; s: string; c: char) = var s = $StateMap[eparser.state] for i, num in eparser.nums: if i != 0: s &= ';' s &= $num eparser.nums.setLen(0) eparser.state = esBacktrack eparser.backtrackStack = @[c] for num in s.ritems: eparser.backtrackStack.add(num) proc backtrack(eparser: var EventParser; c: char) = eparser.backtrack($StateMap[eparser.state], c) proc nextState(eparser: var EventParser; c, cc: char) = if c == cc: inc eparser.state else: eparser.backtrack(cc) proc nextState(eparser: var EventParser; c, cc: char; state: EventState) = if c == cc: eparser.state = state else: eparser.backtrack(cc) proc nextState(eparser: var EventParser; qs: QueryState; cc: char; state: EventState) = if eparser.queryState <= qs: eparser.state = state let qs = qs.succ eparser.queryState = qs if qs == qsNone and eparser.queryStateStack.len > 0: eparser.queryState = eparser.queryStateStack.pop() else: eparser.backtrack(cc) proc nextStateScreenBug(term: Terminal; qs: QueryState; cc: char; state: EventState) = if term.eparser.queryState > qs and term.termType == ttScreen: # Work around a GNU screen 5.0.1 bug where we get foreground/background # color out of order. term.eparser.state = state else: term.eparser.nextState(qs, cc, state) proc nextStateSameQuery(eparser: var EventParser; qs: QueryState; cc: char; state: EventState) = # like above, but here we can have more responses of the same query type # so we don't immediately jump to the next query state if eparser.queryState <= qs: eparser.state = state eparser.queryState = qs else: eparser.backtrack(cc) proc parseNum(eparser: var EventParser; c: char): bool = let num = eparser.num if c in AsciiDigit: # this may overflow, but it's not really a problem eparser.num = (num * 10) + uint32(c) - uint32('0') return true eparser.nums.add(num) eparser.num = 0 return c == ';' proc parseST(eparser: var EventParser; c: char): bool = if c == '\a': # XTerm-specific response; although XTerm doesn't actually send it if # you didn't ask for it (and we don't), some other terminals do (st in # particular). eparser.state = esNone return true elif c == '\e': eparser.state = esSTEsc return true false proc parseMouseInput(eparser: var EventParser; t: MouseInputType; input: var MouseInput): Opt[void] = if eparser.nums.len != 3: eparser.nums.setLen(0) return err() let btn = eparser.nums[0] let x = eparser.nums[1] let y = eparser.nums[2] eparser.nums.setLen(0) if btn > uint16.high or x > uint16.high or y > uint16.high: return err() input.t = t input.pos = (int32(x) - 1, int32(y) - 1) if (btn and 4) != 0: input.mods.incl(mimShift) if (btn and 8) != 0: input.mods.incl(mimMeta) if (btn and 16) != 0: input.mods.incl(mimCtrl) if (btn and 32) != 0: input.t = mitMove # override var button = (btn and 3) + 1 if (btn and 64) != 0: button += 3 if (btn and 128) != 0: button += 7 if button notin uint32(MouseButton.low)..uint32(MouseButton.high): return err() input.button = MouseButton(button) ok() proc parseColor(eparser: var EventParser; c: char): bool = var num = eparser.num eparser.num = 0 let v0 = hexValue(c) if v0 == -1: eparser.colorState = 0 eparser.nums.add(num) return c == '/' let v = uint8(v0) let i = eparser.colorState if i == 0: # 1st place - expand it for when we don't get a 2nd place num = (v shl 4) or v inc eparser.colorState elif i == 1: # 2nd place - clear expanded placeholder from 1st place num = (num and not 0xFu8) or v inc eparser.colorState eparser.num = num # all other places are irrelevant true proc parseHexNum(eparser: var EventParser; c: char): bool = let num = eparser.num eparser.num = 0 let v0 = hexValue(c) if v0 == -1: eparser.nums.add(num) return false eparser.num = num * 0x10 + uint32(v0) if eparser.num < num: eparser.num = uint32.high true proc skipToST(eparser: var EventParser; c: char) = if eparser.parseST(c): discard else: eparser.state = esSkipToST proc parseNone(term: Terminal; c: char): bool = if term.eparser.state != esBacktrack and c == '\e': inc term.eparser.state return false if term.eparser.keyLen > 0: dec term.eparser.keyLen return true let u = uint8(c) term.eparser.keyLen = if u <= 0x7F: 1i8 elif u shr 5 == 0b110: 2i8 elif u shr 4 == 0b1110: 3i8 else: 4i8 return true proc parseEsc(eparser: var EventParser; c: char) = case c of '[': eparser.state = esCSI of ']': eparser.state = esOSC of 'P': eparser.nextState(qsTcapRGB, c, esDCS) of '_': eparser.nextState(qsKitty, c, esAPC) else: eparser.backtrack(c) proc parseCSI(eparser: var EventParser; c: char) = case c of '<': eparser.state = esCSILt of '?': let state = if eparser.queryState <= qsColorRegisters: qsColorRegisters else: qsDA1 eparser.nextState(state, c, esCSIQMark) of '=': eparser.nextState(qsDA1, c, esCSIEquals) of AsciiDigit: discard eparser.parseNum(c) eparser.state = esCSINum else: eparser.backtrack(c) type EscParseResult = enum eprNone, eprWindowChange, eprRedraw proc parseCSINum(term: Terminal; c: char): EscParseResult = if term.eparser.parseNum(c): return eprNone var changed = eprNone case c of '~': # bracketed paste if term.eparser.nums.len == 1 and term.eparser.nums[0] == 200: term.eparser.state = esBracketed term.eparser.nums.setLen(0) return eprNone # may be pageUp/pageDown; try to backtrack term.eparser.backtrack(c) return eprNone of 't': # XTWINOPS if term.eparser.nums.len == 3: let x = term.eparser.nums[2] let y = term.eparser.nums[1] if int64(x) <= int64(int.high) and int64(y) <= int64(int.high): let oattrs = term.attrs let x = int(x) let y = int(y) case term.eparser.nums[0] of 4: if not term.config{"forcePixelsPerColumn"} and term.attrs.ppc == 0 and term.attrs.width != 0: term.attrs.ppc = x div term.attrs.width term.attrs.widthPx = term.attrs.ppc * term.attrs.width if not term.config{"forcePixelsPerLine"} and term.attrs.ppl == 0 and term.attrs.height != 0: term.attrs.ppl = y div term.attrs.height term.attrs.heightPx = term.attrs.ppl * term.attrs.height term.eparser.queryState = qsWindowPixels.succ of 6: if not term.config{"forcePixelsPerColumn"}: term.attrs.ppc = x term.attrs.widthPx = x * term.attrs.width if not term.config{"forcePixelsPerLine"}: term.attrs.ppl = y term.attrs.heightPx = y * term.attrs.height term.eparser.queryState = qsCellSize.succ else: discard if term.attrs != oattrs: term.windowChange() changed = eprWindowChange of 'R': # CPR if term.eparser.nums.len == 2: let oattrs = term.attrs let x = term.eparser.nums[1] let y = term.eparser.nums[0] # if either value is 9999, we might just have a humongous terminal # (or CUP is implemented incorrectly) if x < 9999 and not term.config{"forceColumns"}: term.attrs.width = max(int(x) - int(tfMargin in term.desc), 0) term.attrs.widthPx = term.attrs.width * term.attrs.ppc if y < 9999 and not term.config{"forceLines"}: term.attrs.height = int(y) term.attrs.heightPx = term.attrs.height * term.attrs.ppl term.eparser.queryState = qsNone if term.attrs != oattrs: term.windowChange() changed = eprWindowChange else: term.eparser.backtrack(c) return eprNone term.eparser.nums.setLen(0) term.eparser.state = esNone changed proc parseCSIQMark(term: Terminal; c: char): EscParseResult = if term.eparser.parseNum(c): return eprNone let colorMode = term.attrs.colorMode let imageMode = term.imageMode case c of 'c': # DA1 for n in term.eparser.nums: case n of 4: if term.config{"imageMode"}.isNone and term.imageMode == imNone and term.termType != ttZellij: # Zellij says it supports Sixel; however: # * on Sixel-capable terminals it somehow misplaces images. # * on non-Sixel-capable terminals it still emits image data (???) # So we blacklist it. term.imageMode = imSixel of 22: if term.config{"colorMode"}.isNone: term.attrs.colorMode = max(term.attrs.colorMode, cmANSI) of 52: if term.config{"osc52Copy"}.isNone: term.osc52Copy = true if tfPrimary in term.desc and term.config{"osc52Primary"}.isNone: term.osc52Primary = true else: discard of 'S': # XTSMGRAPHICS if term.eparser.nums.len >= 3 and term.eparser.nums[0] == 1 and term.eparser.nums[1] == 0: let registers = term.eparser.nums[2] if term.config{"sixelColors"} <= 0: term.sixelRegisterNum = uint16(clamp(registers, 2, uint16.high)) else: discard term.eparser.nums.setLen(0) term.eparser.state = esNone if colorMode != term.attrs.colorMode: # windowChange implies redraw term.windowChange() return eprWindowChange if imageMode != term.imageMode: return eprRedraw eprNone proc parseCSILt(eparser: var EventParser; c: char; mouse: var MouseInput): bool = # Parse a mouse event: # CSI < btn ; Px ; Py M (press) # CSI < btn ; Px ; Py m (release) if eparser.parseNum(c): return false eparser.state = esNone if c in {'m', 'M'}: # otherwise, just ignore let t = if c == 'M': mitPress else: mitRelease return eparser.parseMouseInput(t, mouse).isOk eparser.nums.setLen(0) return false proc parseOSC(eparser: var EventParser; c: char) = case c of '6': eparser.state = esOSC6 of '4': eparser.nextStateSameQuery(qsANSIColor, c, esOSC4) of '1': eparser.state = esOSC1 else: eparser.backtrack(c) proc parseOSC6(eparser: var EventParser; c: char) = case c of '0': eparser.nextState(qsXtermAllowedOps, c, esOSC60) of '1': eparser.nextState(qsXtermWindowOps, c, esOSC61) else: eparser.backtrack(c) proc parseOSCNumSemi(term: Terminal; c: char): EscParseResult = if term.eparser.flag and term.eparser.parseColor(c): return eprNone term.eparser.flag = false case c of ':': let rgb = term.eparser.buf == "rgb" term.eparser.buf = "" if not rgb: term.eparser.state = esSkipToST else: term.eparser.flag = true of '\a', '\e': let state = term.eparser.state let i = if state == esOSC4SemiNum: 1 else: 0 term.eparser.buf = "" discard term.eparser.parseST(c) if term.eparser.nums.len == i + 3: let n = term.eparser.nums[0] let r = term.eparser.nums[i] let g = term.eparser.nums[i + 1] let b = term.eparser.nums[i + 2] let c = rgb(uint8(r), uint8(g), uint8(b)) term.eparser.nums.setLen(0) case state of esOSC4SemiNum: if n < 16: term.colorMap[uint8(n)] = c of esOSC10Semi: term.defaultForeground = c of esOSC11Semi: term.defaultBackground = c let prefersDark = term.defaultBackground.Y < 125 if prefersDark != term.attrs.prefersDark: term.attrs.prefersDark = prefersDark term.windowChange() return eprWindowChange else: discard return eprRedraw term.eparser.nums.setLen(0) elif not term.eparser.flag: term.eparser.buf &= c else: term.eparser.skipToST(c) return eprNone proc parseOSC60Semi(term: Terminal; c: char) = if c in {',', '\a', '\e'}: if term.eparser.buf.equalsIgnoreCase("allowWindowOps"): if term.config{"osc52Copy"}.isNone: term.osc52Copy = true if term.config{"osc52Primary"}.isNone: term.osc52Primary = true term.eparser.buf = "" case c of ',': term.eparser.buf = "" of '\a': term.eparser.state = esNone of '\e': term.eparser.state = esSTEsc else: term.eparser.buf &= c proc parseOSC61Semi(term: Terminal; c: char) = if c in {',', '\a', '\e'}: term.eparser.flag = term.eparser.flag or term.eparser.buf.equalsIgnoreCase("SetSelection") term.eparser.buf = "" if term.eparser.parseST(c): if not term.eparser.flag: if term.config{"osc52Copy"}.isNone: term.osc52Copy = true if term.config{"osc52Primary"}.isNone: term.osc52Primary = true term.eparser.flag = false else: term.eparser.buf &= c proc parseOSC1(term: Terminal; c: char) = case c of '0': term.nextStateScreenBug(qsForegroundColor, c, esOSC10) of '1': term.nextStateScreenBug(qsBackgroundColor, c, esOSC11) else: term.eparser.backtrack(c) proc parseOSC4Semi(eparser: var EventParser; c: char) = if eparser.parseST(c): discard elif c == ';': eparser.nums.add(eparser.num) eparser.num = 0 eparser.state = esOSC4SemiNum elif not eparser.parseNum(c): eparser.nums.setLen(0) eparser.state = esNone proc parseDCS(eparser: var EventParser; c: char) = case c of '0': eparser.state = esDCS0 of '1': eparser.state = esDCS1 else: eparser.backtrack(c) proc parseDCS1PlusR(term: Terminal; c: char): EscParseResult = if term.eparser.parseHexNum(c): return eprNone let nums = move(term.eparser.nums) term.eparser.nums = @[] term.eparser.skipToST(c) if c == '=' and nums.len == 1 and nums[0] == 0x524742 and # ASCII R G B term.config{"colorMode"}.isNone and term.attrs.colorMode != cmTrueColor: term.attrs.colorMode = cmTrueColor return eprWindowChange eprNone proc parseAPCG(term: Terminal; c: char): EscParseResult = let imageMode = term.imageMode if term.config{"imageMode"}.isNone: term.imageMode = imKitty term.eparser.skipToST(c) if imageMode != term.imageMode: return eprRedraw eprNone proc areadCharBacktrack(term: Terminal): Opt[char] = if term.eparser.state == esBacktrack: if term.eparser.backtrackStack.len > 0: return ok(term.eparser.backtrackStack.pop()) term.eparser.state = esNone return term.areadChar() proc areadEvent*(term: Terminal): Opt[InputEvent] = var epr = eprNone while epr == eprNone: if term.eparser.keyLen == 1: dec term.eparser.keyLen return ok(InputEvent(t: ietKeyEnd)) let c = ?term.areadCharBacktrack() case term.eparser.state of esBacktrack, esNone: if term.parseNone(c): return ok(InputEvent(t: ietKey, c: c)) of esBracketed: if c == '\e': term.eparser.state = esBracketedEsc else: return ok(InputEvent(t: ietKey, c: c)) of esBracketedEsc: term.eparser.nextState('[', c, esBracketedCSI) of esEsc: term.eparser.parseEsc(c) of esCSI: term.eparser.parseCSI(c) of esCSIQMark: epr = term.parseCSIQMark(c) of esCSIEquals: # SyncTERM DA1 response; skip if c == 'c': term.eparser.state = esNone of esCSINum: epr = term.parseCSINum(c) of esBracketedCSI: term.eparser.nextState('2', c) of esBracketedCSI2: term.eparser.nextState('0', c) of esBracketedCSI20: term.eparser.nextState('1', c) of esBracketedCSI201: if c == '~': term.eparser.state = esNone return ok(InputEvent(t: ietPaste)) term.eparser.backtrack(c) of esCSILt: var mouse: MouseInput if term.eparser.parseCSILt(c, mouse): return ok(InputEvent(t: ietMouse, m: mouse)) of esOSC: term.eparser.parseOSC(c) of esOSC6: term.eparser.parseOSC6(c) of esOSC60, esOSC61, esOSC10, esOSC11, esOSC4: term.eparser.nextState(';', c) of esOSC60Semi: term.parseOSC60Semi(c) of esOSC61Semi: term.parseOSC61Semi(c) of esOSC1: term.parseOSC1(c) of esOSC4Semi: term.eparser.parseOSC4Semi(c) of esOSC4SemiNum, esOSC10Semi, esOSC11Semi: epr = term.parseOSCNumSemi(c) of esDCS: term.eparser.parseDCS(c) of esDCS0, esDCS1: term.eparser.nextState('+', c) of esDCS0Plus: term.eparser.nextState('r', c, esSkipToST) of esDCS1Plus: term.eparser.nextState('r', c, esDCS1PlusR) of esDCS1PlusR: epr = term.parseDCS1PlusR(c) of esAPC: term.eparser.nextState('G', c, esAPCG) of esAPCG: epr = term.parseAPCG(c) of esSTEsc: term.eparser.nextState('\\', c, esNone) of esSkipToST: discard term.eparser.parseST(c) case epr of eprNone: return err() of eprWindowChange: return ok(InputEvent(t: ietWindowChange)) of eprRedraw: return ok(InputEvent(t: ietRedraw)) proc cursorNextLineBegin(term: Terminal): Opt[void] = let ocursory = term.frame.cursory if term.frame.scrollBottom < 0 and ocursory + 1 < uint32(term.attrs.width) or ocursory < uint32(term.frame.scrollBottom): inc term.frame.cursory term.frame.cursorx = 0 term.write("\r\n") proc cursorNextLine*(term: Terminal): Opt[void] = let ocursory = term.frame.cursory if term.frame.scrollBottom < 0 and ocursory + 1 < uint32(term.attrs.width) or ocursory < uint32(term.frame.scrollBottom): inc term.frame.cursory term.write('\n') proc cursorPrevLineBegin(term: Terminal): Opt[void] = if term.frame.cursory > 0: dec term.frame.cursory term.frame.cursorx = 0 term.write('\r' & RI) proc cursorLineBegin(term: Terminal): Opt[void] = term.frame.cursorx = 0 term.write('\r') proc cursorGoto(term: Terminal; x, y: uint32): Opt[void] = if term.frame.cursorKnown and term.frame.cursorx == x and term.frame.cursory == y: return ok() if term.frame.cursorKnown and (x == 0 or x == term.frame.cursorx) and y - term.frame.cursory <= 6: # This is probably more efficient than setting the cursor by address. if x == 0: ?term.cursorLineBegin() for u in term.frame.cursory ..< y: ?term.cursorNextLine() return ok() term.frame.cursorx = x term.frame.cursory = y term.frame.cursorKnown = true return case term.termType of ttAdm3a: term.write("\e=" & char(uint8(y) + 0x20) & char(uint8(x) + 0x20)) of ttVt52: term.write("\eY" & char(uint8(y) + 0x20) & char(uint8(x) + 0x20)) else: term.write(CSI & $(y + 1) & ';' & $(x + 1) & 'H') proc cursorGoto(term: Terminal; x, y: int): Opt[void] = term.cursorGoto(uint32(x), uint32(y)) proc cursorHome(term: Terminal): Opt[void] = if term.frame.cursorKnown and term.frame.cursorx == 0 and term.frame.cursory == 0: return ok() if tfPreEcma48 in term.desc: return term.cursorGoto(0, 0) term.frame.cursorx = 0 term.frame.cursory = 0 term.write(CSI & 'H') proc unsetCursorPos(term: Terminal) = term.frame.cursorKnown = false proc clearEnd(term: Terminal): Opt[void] = case term.termType of ttAdm3a: for x in term.frame.cursorx ..< uint32(term.attrs.width): ?term.write(' ') term.frame.cursorx = uint32(term.attrs.width) - 1 return ok() of ttVt52: return term.write("\eK") else: return term.write(CSI & 'K') proc clearDisplay(term: Terminal): Opt[void] = return case term.termType of ttAdm3a: term.write("\x1A") of ttVt52: term.write("\eJ") else: term.write(CSI & 'J') proc isatty(term: Terminal): bool = term.ttyFlag proc anyKey*(term: Terminal; msg = "[Hit any key]"; bottom = false): Opt[void] = if term.isatty(): if bottom: ?term.cursorGoto(0, term.attrs.height - 1) ?term.clearEnd() ?term.write(msg) ?term.blockIO() #TODO probably we should allow SIGINT here too while term.eparser.queryState != qsNone: if term.ahandleRead().isErr: break while true: if term.areadEvent().isErr: break discard term.readChar() term.unblockIO() ok() proc resetFormat(term: Terminal): Opt[void] = # This resets the formatting *and* synchronizes it with the terminal. # processFormat(Format()) is usually more efficient. term.frame.format = Format() case term.termType of ttAdm3a, ttVt52: return ok() else: return term.write(CSI & 'm') proc getRGB(term: Terminal; a: CellColor; termDefault: RGBColor): RGBColor = case a.t of ctNone: return termDefault of ctANSI: let n = a.ansi if uint8(n) >= 16: return n.toRGB() return term.colorMap[uint8(n)] of ctRGB: return a.rgb # Use euclidian distance to quantize RGB colors. proc approximateANSIColor(term: Terminal; rgb, termDefault: RGBColor): CellColor = var a = 0 var n = -1 if rgb == termDefault: return defaultColor for i in -1 .. term.colorMap.high: let color = if i >= 0: term.colorMap[i] else: termDefault if color == rgb: return ANSIColor(i).cellColor() {.push overflowChecks:off.} let x = int(color.r) - int(rgb.r) let y = int(color.g) - int(rgb.g) let z = int(color.b) - int(rgb.b) let xx = x * x let yy = y * y let zz = z * z let b = xx + yy + zz {.pop.} if i == -1 or b < a: n = i a = b return if n == -1: defaultColor else: ANSIColor(n).cellColor() # Return a fgcolor contrasted to the background by the minimum configured # contrast. proc correctContrast(term: Terminal; bgcolor, fgcolor: CellColor): CellColor = if bgcolor.t == ctRGB and fgcolor.t == ctRGB: # Both foreground and background are RGB, so presumably it was set by # the website itself. Correcting the foreground's contrast may be # counter-productive in this case, because many "spoiler text" # implementations just set the foreground and background to the same # color. # Of course, it's still a problem if we fail to parse only a certain # box's background color, but that should be rare enough (hopefully a # website would at least use a consistent color syntax...) return fgcolor let contrast = term.config{"minimumContrast"} let cfgcolor = fgcolor let bgcolor = term.getRGB(bgcolor, term.defaultBackground) let fgcolor = term.getRGB(fgcolor, term.defaultForeground) let bgY = int(bgcolor.Y) var fgY = int(fgcolor.Y) let diff = abs(bgY - fgY) if diff < contrast: if bgY > fgY: fgY = bgY - contrast if fgY < 0: fgY = bgY + contrast if fgY > 255: fgY = 0 else: fgY = bgY + contrast if fgY > 255: fgY = bgY - contrast if fgY < 0: fgY = 255 let newrgb = YUV(uint8(fgY), fgcolor.U, fgcolor.V) case term.attrs.colorMode of cmTrueColor: return cellColor(newrgb) of cmANSI: return term.approximateANSIColor(newrgb, term.defaultForeground) of cmEightBit: return cellColor(newrgb.toEightBit()) of cmMonochrome: assert false return cfgcolor proc writeColorSGR(term: Terminal; c: CellColor; bgmod: uint8): Opt[void] = var res = CSI case c.t of ctNone: res &= 39 + bgmod of ctANSI: let n = uint8(c.ansi) if n < 16: if n < 8: res &= 30 + bgmod + n else: res &= 82 + bgmod + n else: res &= 38 + bgmod res &= ";5;" res &= n of ctRGB: let rgb = c.rgb res &= 38 + bgmod res &= ";2;" res &= rgb.r res &= ';' res &= rgb.g res &= ';' res &= rgb.b res &= 'm' term.write(res) # If needed, quantize colors based on the color mode, and correct their # contrast. proc reduceFormat*(term: Terminal; format: Format): Format = var bgcolor = format.bgcolor var fgcolor = format.fgcolor case term.attrs.colorMode of cmANSI: if bgcolor.t == ctANSI and uint8(bgcolor.ansi) > 15: bgcolor = fgcolor.ansi.toRGB().cellColor() if bgcolor.t == ctRGB: bgcolor = term.approximateANSIColor(bgcolor.rgb, term.defaultBackground) if fgcolor.t == ctANSI and uint8(fgcolor.ansi) > 15: fgcolor = fgcolor.ansi.toRGB().cellColor() if fgcolor.t == ctRGB: fgcolor = term.approximateANSIColor(fgcolor.rgb, term.defaultForeground) fgcolor = term.correctContrast(bgcolor, fgcolor) of cmEightBit: if bgcolor.t == ctRGB: bgcolor = bgcolor.rgb.toEightBit().cellColor() if fgcolor.t == ctRGB: fgcolor = fgcolor.rgb.toEightBit().cellColor() fgcolor = term.correctContrast(bgcolor, fgcolor) of cmTrueColor: fgcolor = term.correctContrast(bgcolor, fgcolor) of cmMonochrome: fgcolor = defaultColor bgcolor = defaultColor let flags = format.flags * term.formatMode return initFormat(bgcolor, fgcolor, flags) const FormatCodes: array[FormatFlag, tuple[s, e: string]] = [ ffBold: ("1", "22"), ffItalic: ("3", "23"), ffUnderline: ("4", "24"), ffReverse: ("7", "27"), ffStrike: ("9", "29"), ffOverline: ("53", "55"), ffBlink: ("5", "25"), ] proc processFormat*(term: Terminal; cellf: Format): Opt[void] = let fgcolor = cellf.fgcolor let bgcolor = cellf.bgcolor let flags = cellf.flags let oformat = term.frame.format let oldFgcolor = oformat.fgcolor let oldBgcolor = oformat.bgcolor let oldFlags = oformat.flags if oldFlags != flags: # if either # * both fgcolor and bgcolor are the default, or # * both are being changed, # then we can use a general reset when new flags are empty. if flags == {} and (fgcolor != oldFgcolor and bgcolor != oldBgcolor or fgcolor == defaultColor and bgcolor == defaultColor): ?term.resetFormat() else: let flagsUnset = oldFlags - flags let flagsSet = flags - oldFlags var first = true const DivMap = [false: ";", true: CSI] for flag in FormatFlag: if flag in flagsUnset: ?term.write(DivMap[first]) ?term.write(FormatCodes[flag].e) first = false elif flag in flagsSet: ?term.write(DivMap[first]) ?term.write(FormatCodes[flag].s) first = false ?term.write('m') if fgcolor != oldFgcolor: ?term.writeColorSGR(fgcolor, bgmod = 0) if bgcolor != oldBgcolor: ?term.writeColorSGR(bgcolor, bgmod = 10) term.frame.format = cellf ok() proc hasTitle(term: Terminal): bool = term.config{"setTitle"}.get(tfTitle in term.desc) proc hasAltScreen(term: Terminal): bool = term.config{"altScreen"}.get(tfAltScreen in term.desc) proc hasBracketedPaste*(term: Terminal): bool = term.config{"bracketedPaste"}.get(tfBracketedPaste in term.desc) proc hasMouse(term: Terminal): bool = term.config{"useMouse"}.get(tfMouse in term.desc) proc encodeAllQMark(res: var string; te: var TextEncoder; iq: openArray[uint8]) = var n = 0 while true: case te.encode(iq, res.toOpenArrayByte(0, res.high), n, finish = true) of terDone: res.setLen(n) break of terReqOutput: res.setLen(res.len * 2) of terError: res.setLen(n) # match width of replaced char for i in 0 ..< te.c.width(): res &= '?' n = res.len proc encodeAscii(res: var string; s: openArray[char]; specialGraphics: var bool; hasSpecialGraphics: bool) = var sg = specialGraphics for u in s.points: if u < 0x80: if sg and u in 0x5Fu32..0x7Eu32: res &= "\e(B" sg = false res &= char(u) else: if hasSpecialGraphics: block graph: let c = case u of 0x2500, 0x2501, 0x2504, 0x2505, 0x2508, 0x2509, 0x254C, 0x254D, 0x2550: '\x71' of 0x2502, 0x2503, 0x2506, 0x2507, 0x250A, 0x250B, 0x254E, 0x254F, 0x2551: '\x78' of 0x250Cu32..0x250Fu32, 0x2552u32..0x2554u32: '\x6C' of 0x2510u32..0x2513u32, 0x2555u32..0x2557u32: '\x6B' of 0x2514u32..0x2517u32, 0x2558u32..0x255Au32: '\x6D' of 0x2518u32..0x251Bu32, 0x255Bu32..0x255Du32: '\x6A' of 0x251Cu32..0x2523u32, 0x255Eu32..0x2560u32: '\x74' of 0x2524u32..0x252Bu32, 0x2561u32..0x2563u32: '\x75' of 0x252Cu32..0x2533u32, 0x2564u32..0x2566u32: '\x77' of 0x2534u32..0x253Bu32, 0x2567u32..0x2569u32: '\x76' of 0x253Cu32..0x254Bu32, 0x256Au32..0x256Cu32: '\x6E' of 0x2264: '\x79' of 0x2265: '\x7A' of 0x3C0: '\x7B' of 0x2260: '\x7C' of 0xA3: '\x7D' of 0xB7: '\x7E' of 0x202F: '\x5F' else: break graph if not sg: res &= "\e(0" sg = true res &= c continue # quotes; to be fair these shouldn't have been included, but it looks # very awkward when they don't exist case u of 0x2018, 0x201B: res &= '`' of 0x2019: res &= '\'' of 0x201A: res &= ',' of 0x201C, 0x201D: res &= '"' of 0x2022: res &= '*' # also bullet lists are pretty common else: for i in 0 ..< u.width(): res &= '?' specialGraphics = sg proc processOutputString*(term: Terminal; s: openArray[char]; trackCursor = true): Opt[void] = if s.len <= 0: return ok() if not trackCursor: term.unsetCursorPos() if s.validateUTF8Surr() != -1: if trackCursor: inc term.frame.cursorx return term.write('?') if trackCursor: for u in s.points: assert u > 0x9F or u != 0x7F and u > 0x1F term.frame.cursorx += uint32(u.width()) if term.cs == csUtf8: # The output encoding matches the internal representation. return term.write(s) var res = "" if term.asciiOnly: res.encodeAscii(s, term.frame.specialGraphics, tfSpecialGraphics in term.desc) else: # Output is not utf-8, so we must encode it first. res = newString(s.len) # guess length res.encodeAllQMark(term.te, s.toOpenArrayByte(0, s.high)) term.write(res) proc hideCursor(term: Terminal): Opt[void] = if not term.frame.cursorHidden: term.frame.cursorHidden = true case term.termType of ttAdm3a, ttVt52: discard else: return term.write(HideCursor) ok() proc showCursor(term: Terminal): Opt[void] = if term.frame.cursorHidden: term.frame.cursorHidden = false case term.termType of ttAdm3a, ttVt52: discard else: return term.write(ShowCursor) ok() # 1-indexed proc setScrollArea(term: Terminal; top, bottom: int): Opt[void] = if term.frame.scrollBottom != bottom: term.frame.scrollBottom = bottom term.frame.cursorx = 0 term.frame.cursory = 0 return term.write(CSI & $top & ";" & $bottom & 'r') ok() proc resetScrollArea(term: Terminal): Opt[void] = if term.frame.scrollBottom != -1: term.frame.scrollBottom = -1 term.frame.cursorx = 0 term.frame.cursory = 0 return term.write(CSI & 'r') ok() proc moveLinesUp(term: Terminal; n: int): Opt[void] = term.write(CSI & $n & 'S') proc moveLinesDown(term: Terminal; n: int): Opt[void] = term.write(CSI & $n & 'T') proc processCell(term: Terminal; cell: FixedCell; x: int): Opt[void] = if cell.str.len == 0: return ok() # if previous cell was empty, catch up with x let x = uint32(x) while term.frame.cursorx < x: ?term.write(' ') inc term.frame.cursorx ?term.processFormat(cell.format) term.processOutputString(cell.str) proc drawLine(term: Terminal; sx, y: int): Opt[void] = for x in sx ..< term.attrs.width: ?term.processCell(term.frame.canvas[y * term.attrs.width + x], x) if term.frame.cursorx < uint32(term.attrs.width): ?term.processFormat(Format()) ?term.clearEnd() term.frame.lineDamage[y] = term.attrs.width ok() proc fullDraw(term: Terminal): Opt[void] = ?term.hideCursor() ?term.resetScrollArea() ?term.cursorHome() ?term.clearDisplay() ?term.resetFormat() for y in 0 ..< term.attrs.height: if y != 0: ?term.cursorNextLineBegin() ?term.drawLine(0, y) ok() proc partialDrawScroll(term: Terminal; scroll, scrollBottom: int; bgcolor: CellColor): Opt[void] = ?term.setScrollArea(1, scrollBottom) # may move cursor to 0, 0 # BCE to the buffer's background color to reduce visibility of tearing. ?term.processFormat(initFormat(bgcolor, defaultColor, {})) if term.imageMode == imSixel and term.frame.fastScrollTodo and tfFastScroll in term.desc: # Scrolling Sixel images line-by-line isn't very efficient (at least it # visibly slows down XTerm on my laptop), so use fast scroll for this. # (Also, XTerm has a bug that breaks slow scroll upwards, but TODO this # should be fixed in XTerm...) # # Note that "slow" scroll is more effective against tearing, because # it allows us to limit the number of unfilled lines to one. Hence we # only want to do fast scroll if we have Sixel images on the screen. if scroll < 0: return term.moveLinesDown(-scroll) else: return term.moveLinesUp(scroll) if scroll < 0: # scroll up ?term.cursorHome() for i in countdown(0, scroll + 1): ?term.cursorPrevLineBegin() ?term.drawLine(0, i - scroll - 1) return term.cursorLineBegin() # scroll down ?term.cursorGoto(0, scrollBottom - 1) for i in 0 ..< scroll: ?term.cursorNextLineBegin() ?term.drawLine(0, scrollBottom - scroll + i) term.cursorHome() proc partialDraw(term: Terminal; scrollBottom: int; bgcolor: CellColor): Opt[void] = let scroll = term.frame.scrollTodo if scroll != 0: ?term.hideCursor() ?term.partialDrawScroll(scroll, scrollBottom, bgcolor) for y in 0 ..< term.attrs.height: # set cx to x of the first change let cx = term.frame.lineDamage[y] # w will track the current position on screen if cx >= term.attrs.width: continue ?term.hideCursor() ?term.resetScrollArea() ?term.cursorGoto(cx, y) ?term.drawLine(cx, y) ok() proc writeGrid*(term: Terminal; grid: FixedGrid; x = 0, y = 0) = for ly in y ..< y + grid.height: var lastx = 0 for lx in x ..< x + grid.width: let i = ly * term.attrs.width + lx let cell = grid[(ly - y) * grid.width + (lx - x)] if term.frame.canvas[i].str != "": # if there is a change, we have to start from the last x with # a string (otherwise we might overwrite half of a double-width char) lastx = lx let format = term.reduceFormat(cell.format) if format != term.frame.canvas[i].format or cell.str != term.frame.canvas[i].str: term.frame.canvas[i].str = cell.str term.frame.canvas[i].format = format term.frame.lineDamage[ly] = min(term.frame.lineDamage[ly], lastx) proc getCurrentBgcolor*(term: Terminal): CellColor = term.frame.format.bgcolor # returns diff between current and old position (0 = cannot scroll) proc updateScroll*(term: Terminal; pid, x, y: int): int = var diff = 0 #TODO I think we always have to check against ftCurrent here... # with ftNext you get issues because we haven't dropped the frame at this # point yet? or something # but I guess that also breaks canvas updates # so probably you have to do the frame dropping thing *before* the # printing even starts # and then this is fine eh? let pos = term.frame.pos if pid != -1 and pos.pid == pid and pos.x == x: diff = y - pos.y term.frame.pos = (pid, x, y) diff proc unsetScroll*(term: Terminal) = # Called on winchange or when no container is on the screen. # This won't be replayed, so unset pid everywhere. for frame in term.frames.mitems: frame.pos.pid = -1 proc applyConfigDimensions(term: Terminal) = # screen dimensions if term.attrs.width == 0 or term.config{"forceColumns"}: term.attrs.width = int(term.config{"columns"}) if term.attrs.height == 0 or term.config{"forceLines"}: term.attrs.height = int(term.config{"lines"}) if term.attrs.ppc == 0 or term.config{"forcePixelsPerColumn"}: term.attrs.ppc = int(term.config{"pixelsPerColumn"}) if term.attrs.ppl == 0 or term.config{"forcePixelsPerLine"}: term.attrs.ppl = int(term.config{"pixelsPerLine"}) term.attrs.widthPx = term.attrs.ppc * term.attrs.width term.attrs.heightPx = term.attrs.ppl * term.attrs.height proc applyConfig(term: Terminal) = # colors, formatting if term.config{"colorMode"}.isSome: term.attrs.colorMode = term.config{"colorMode"}.get if term.config{"display.formatMode"}.isSome: term.formatMode = term.config{"display.formatMode"}.get for fm in FormatFlag: if fm in term.config{"noFormatMode"}: term.formatMode.excl(fm) if term.config{"imageMode"}.isSome: term.imageMode = term.config{"imageMode"}.get let sixelColors = term.config{"sixelColors"} if sixelColors >= 0: term.sixelRegisterNum = uint16(clamp(sixelColors, 2, 65535)) let defaultBackground = term.config{"defaultBackgroundColor"} if defaultBackground.isSome: term.defaultBackground = defaultBackground.get let defaultForeground = term.config{"defaultForegroundColor"} if defaultForeground.isSome: term.defaultForeground = defaultForeground.get term.attrs.prefersDark = term.defaultBackground.Y < 125 if term.config{"osc52Copy"}.isSome: term.osc52Copy = term.config{"osc52Copy"}.get if term.config{"osc52Primary"}.isSome: term.osc52Primary = term.config{"osc52Primary"}.get # charsets if term.config{"displayCharset"} != csUnknown: term.cs = term.config{"displayCharset"} else: term.cs = DefaultCharset for s in ["LC_ALL", "LC_CTYPE", "LANG"]: let env = getEnv(s) if env == "": continue let cs = getLocaleCharset(env) if cs != csUnknown: if env == "C": term.asciiOnly = true term.cs = csWindows1252 else: term.cs = cs break if term.cs in {csUtf8, csUtf16le, csUtf16be, csReplacement}: term.cs = csUtf8 else: term.te = initTextEncoder(term.cs) term.tdctx = initTextDecoderContext(term.cs) term.applyConfigDimensions() proc addImage*(term: Terminal; image: CanvasImage) = if term.canvasImagesTmpTail == nil: term.canvasImagesTmpHead = image else: term.canvasImagesTmpTail.next = image term.canvasImagesTmpTail = image proc takeImage*(term: Terminal; pid, imageId, bufHeight: int; dims: CanvasImageDimensions): CanvasImage = # pass2 is set after finding a damaged scrolled image (usually because we # scrolled out some part and scrolled in another part). # In this case, we can't just reuse the CanvasImage we found because that # would result in displaying an image with the modified (scrolled) erry. # So we just search again. #TODO this is way too convoluted, I'm sure there's a better way... var pass2 = false var it = term.frame.canvasImagesHead var prev: CanvasImage = nil while it != nil: if it.pid == pid and it.bmp.imageId == imageId and it.dims.width == dims.width and it.dims.height == dims.height and it.dims.rx == dims.rx and it.dims.ry == dims.ry and (term.imageMode != imSixel or (not pass2 and it.dims.erry == dims.erry or pass2 and it.dims.erry2 == dims.erry) and it.dims.dispw == dims.dispw and it.dims.offx == dims.offx): if not pass2 and not term.updateCanvasImage(it, dims, bufHeight): # retry with the right y error pass2 = true it = term.frame.canvasImagesHead continue if prev != nil: prev.next = it.next else: term.frame.canvasImagesHead = it.next it.next = nil return it prev = it it = it.next return nil proc positionImage*(term: Terminal; rx, ry, x, y, offx2, offy2, width, height, maxwpx, maxhpx: int): CanvasImageDimensions = let offx2 = if term.imageMode == imKitty: offx2 else: 0 let offy2 = if term.imageMode == imKitty: offy2 else: 0 let xpx = x * term.attrs.ppc + offx2 let ypx = y * term.attrs.ppl + offy2 # calculate offset inside image to start from let offx = -min(xpx, 0) let offy = -min(ypx, 0) let erry = -min(ypx, 0) mod 6 CanvasImageDimensions( x: x, y: y, width: width, height: height, rx: rx, ry: ry, xpx: xpx, ypx: ypx, offx: offx, offy: offy, offx2: offx2, offy2: offy2, # maximum image size that fits on the screen relative to the image # origin (*not* offx/offy) dispw: min(width + xpx, maxwpx) - xpx, disph: min(height + ypx, maxhpx) - ypx, erry: erry, erry2: erry ) proc onScreen*(dims: CanvasImageDimensions): bool = dims.dispw > dims.offx and dims.disph > dims.offy proc repositionImage(term: Terminal; image: CanvasImage; maxwpx, maxhpx: int): bool = let erry2 = image.dims.erry2 let dims = term.positionImage(image.dims.rx, image.dims.ry, image.dims.x, image.dims.y, image.dims.offx2, image.dims.offy2, image.dims.width, image.dims.height, maxwpx, maxhpx) if dims.onScreen: image.dims = dims image.dims.erry2 = erry2 return true false proc clearImage(term: Terminal; image: CanvasImage; maxh: int) = case term.imageMode of imNone: discard of imSixel: # we must clear sixels the same way as we clear text. let h = (image.dims.height + term.attrs.ppl - 1) div term.attrs.ppl # ceil let ey = min(image.dims.y + h, maxh) let x = max(image.dims.x, 0) for y in max(image.dims.y, 0) ..< ey: term.frame.lineDamage[y] = min(term.frame.lineDamage[y], x) of imKitty: if image.kittyId != 0: term.frame.kittyImagesToClear.add(image.kittyId) proc clearImages*(term: Terminal; maxh: int) = for image in term.frame.canvasImages: term.clearImage(image, maxh) term.frame.canvasImagesHead = nil proc checkImageDamage(term: Terminal; image: CanvasImage; maxw, maxh: int) = # we're interested in the last x/y *on screen*. if damage exceeds that, # then the image is unaffected and there's nothing to do. let lastx = maxw - 1 let ppl = term.attrs.ppl let ppc = term.attrs.ppc # compute the bottom and right borders, rounded in both directions. # if the last column/line doesn't cover a cell, consider it # transparent. let ey0 = min(image.dims.y + (image.dims.height + ppl - 1) div ppl, maxh) let eypx = image.dims.ypx + image.dims.disph let x = max(image.dims.x, 0) let mx0 = min(image.dims.x + image.dims.dispw div ppc, lastx) let mx = min(image.dims.x + (image.dims.dispw + ppc - 1) div ppc, lastx) for y in max(image.dims.y, 0) ..< ey0: let od = term.frame.lineDamage[y] if od > mx0: continue image.damaged = true if od < x: continue # If eypx is less than y * ppl, that means it only partially covers # the last line on the screen which it is painted to. Therefore we must # treat it as transparent here. # A similar situation arises when od is on the last covered column. if image.transparent or eypx < y * ppl or od in mx0 ..< mx: term.frame.lineDamage[y] = x else: var textFound = false # damage starts inside an opaque image; skip clear (but only if # the damage was not caused by a printing character) let si = y * term.attrs.width for i in si + od ..< si + term.attrs.width: if term.frame.canvas[i].str.len > 0 and term.frame.canvas[i].str[0] != ' ': textFound = true break if not textFound: term.frame.lineDamage[y] = mx proc updateCanvasImage(term: Terminal; image: CanvasImage; dims: CanvasImageDimensions; maxh: int): bool = # reuse image on screen if image.dims.x != dims.x or image.dims.y != dims.y or image.dims.disph != dims.disph or image.dims.offy != dims.offy or image.dims.erry != dims.erry: if term.imageMode == imSixel and image.dims.erry != image.dims.erry2: # we have scrolled in more of this image onto the screen, but the Y # error is incorrect. load the right one. return false image.damaged = true # only clear sixels; with kitty we just move the existing image if term.imageMode == imSixel: term.clearImage(image, maxh) image.dims = dims true proc checkImageOverlap(term: Terminal; image: CanvasImage) = var it = term.frame.canvasImagesHead var prev: CanvasImage = nil let x1 = image.dims.xpx + image.dims.offx let y1 = image.dims.ypx + image.dims.offy let x2 = image.dims.xpx + image.dims.dispw let y2 = image.dims.ypx + image.dims.disph let opaque = not image.transparent while it != image: let ix1 = it.dims.xpx + it.dims.offx let iy1 = it.dims.ypx + it.dims.offy let ix2 = it.dims.xpx + it.dims.dispw let iy2 = it.dims.ypx + it.dims.disph if ix1 < x2 and x1 < ix2 and iy1 < y2 and y1 < iy2: # overlap if opaque and ix1 >= x1 and iy1 >= y1: # `it' is fully covered by `image'; remove `it'. let next = move(it.next) if prev != nil: prev.next = next else: term.frame.canvasImagesHead = next it = next continue if term.imageMode == imSixel and it.damaged: # an image we overlap with was damaged; we have to redraw too to # preserve Z order. image.damaged = true prev = it it = it.next iterator updateImages*(term: Terminal; bufWidth, bufHeight: int): CanvasImage = term.clearImages(bufHeight) term.frame.canvasImagesHead = move(term.canvasImagesTmpHead) term.canvasImagesTmpTail = nil if term.imageMode == imSixel: var image = term.frame.canvasImagesHead var prev: CanvasImage = nil while image != nil: term.checkImageDamage(image, bufWidth, bufHeight) term.checkImageOverlap(image) if image.damaged and image.dims.erry != image.dims.erry2: yield image if not image.damaged: # ...yeah if prev == nil: term.frame.canvasImagesHead = image.next else: prev.next = image.next prev = image image = image.next proc updateImage*(image: CanvasImage; data: Blob; preludeLen: int) = image.data = data image.preludeLen = preludeLen image.dims.erry2 = image.dims.erry proc newCanvasImage*(data: Blob; pid, preludeLen: int; bmp: NetworkBitmap; dims: CanvasImageDimensions; transparent: bool): CanvasImage = CanvasImage( pid: pid, bmp: bmp, data: data, dims: dims, transparent: transparent, preludeLen: preludeLen, damaged: true ) proc getU32BE(data: openArray[char]; i: int): uint32 = return uint32(data[i + 3]) or (uint32(data[i + 2]) shl 8) or (uint32(data[i + 1]) shl 16) or (uint32(data[i]) shl 24) proc writeSixelAttrs(term: Terminal; data: openArray[char]; realw, realh: int): Opt[void] = var i = max(data.find('"'), 0) # set raster attrs ?term.write(data.toOpenArray(0, i)) ?term.write("1;1;" & $realw & ';' & $realh) while i < data.len and data[i] != '#': # skip aspect ratio attrs inc i term.write(data.toOpenArray(i, data.high)) proc outputSixelImage(term: Terminal; x, y: int; image: CanvasImage; data: openArray[char]): Opt[void] = let offx = image.dims.offx let offy = image.dims.offy let dispw = image.dims.dispw let disph = image.dims.disph let realw = dispw - offx let realh = disph - offy let preludeLen = image.preludeLen if preludeLen > data.len or data.len < 4: return ok() let L = data.len - int(data.getU32BE(data.len - 4)) - 4 if L < 0: return ok() ?term.hideCursor() ?term.cursorGoto(x, y) # From this point on we have no idea where the cursor is because pretty # much every terminal puts it somewhere else. term.unsetCursorPos() ?term.writeSixelAttrs(data.toOpenArray(0, preludeLen - 1), realw, realh) # Note: we only crop images when it is possible to do so in near constant # time. Otherwise, the image is re-coded in a cropped form. if realh == image.dims.height: # don't crop return term.write(data.toOpenArray(preludeLen, L - 1)) let si = preludeLen + int(data.getU32BE(L + (offy div 6) * 4)) if si >= data.len: # bounds check return term.write(ST) if disph == image.dims.height: # crop top only return term.write(data.toOpenArray(si, L - 1)) # crop both top & bottom let ed6 = (disph - image.dims.erry2) div 6 let ei = preludeLen + int(data.getU32BE(L + ed6 * 4)) - 1 if ei <= data.len: # bounds check ?term.write(data.toOpenArray(si, ei - 1)) # calculate difference between target Y & actual position in the map # note: it must be offset by image.erry2; that's where the map starts. let herry = disph - (ed6 * 6 + image.dims.erry2) if herry > 0: # can't write out the last row completely; mask off the bottom part. let mask = (1u8 shl herry) - 1 var s = "-" var i = ei + 1 while i < L and (let c = data[i]; c notin {'-', '\e'}): # newline or ST let u = uint8(c) - 0x3F # may underflow, but that's no problem if u < 0x40: s &= char((u and mask) + 0x3F) else: s &= c inc i ?term.write(s) term.write(ST) proc outputSixelImage(term: Terminal; x, y: int; image: CanvasImage): Opt[void] = var p = cast[ptr UncheckedArray[char]](image.data.buffer) if image.data.size > 0: let H = image.data.size - 1 ?term.outputSixelImage(x, y, image, p.toOpenArray(0, H)) ok() proc outputKittyImage(term: Terminal; x, y: int; image: CanvasImage): Opt[void] = ?term.cursorGoto(x, y) # ignore offx2/offy2 if the image starts outside the screen (and thus we # are painting a slice only) # note: this looks wrong, but it's correct let offx2 = if image.dims.offx > 0: 0 else: image.dims.offx2 let offy2 = if image.dims.offy > 0: 0 else: image.dims.offy2 var outs = APC & "GC=1,s=" & $image.dims.width & ",v=" & $image.dims.height & ",x=" & $image.dims.offx & ",y=" & $image.dims.offy & ",X=" & $offx2 & ",Y=" & $offy2 & ",w=" & $(image.dims.dispw - image.dims.offx) & ",h=" & $(image.dims.disph - image.dims.offy) & # for now, we always use placement id 1 ",p=1,q=2" if image.kittyId != 0: outs &= ",i=" & $image.kittyId & ",a=p;" & ST return term.write(outs) inc term.kittyId # skip i=0 if term.kittyId == 0: # unsigned wraparound inc term.kittyId image.kittyId = term.kittyId outs &= ",i=" & $image.kittyId const MaxBytes = 4096 * 3 div 4 var i = MaxBytes let p = cast[ptr UncheckedArray[uint8]](image.data.buffer) let L = image.data.size let m = if i < L: '1' else: '0' outs &= ",a=T,f=100,m=" & m & ';' outs.btoa(p.toOpenArray(0, min(L, i) - 1)) outs &= ST ?term.write(outs) while i < L: let j = i i += MaxBytes let m = if i < L: '1' else: '0' var outs = APC & "Gm=" & m & ';' outs.btoa(p.toOpenArray(j, min(L, i) - 1)) outs &= ST ?term.write(outs) ok() proc outputImages(term: Terminal): Opt[void] = if term.imageMode == imKitty: # clean up unused kitty images var s = "" for id in term.frame.kittyImagesToClear: s &= APC & "Ga=d,d=I,i=" & $id & ",p=1,q=2;" & ST ?term.write(s) term.frame.kittyImagesToClear.setLen(0) for image in term.frame.canvasImages: if image.damaged: assert image.dims.dispw > 0 and image.dims.disph > 0 ?term.resetScrollArea() let x = max(image.dims.x, 0) let y = max(image.dims.y, 0) case term.imageMode of imNone: assert false of imSixel: ?term.outputSixelImage(x, y, image) of imKitty: ?term.outputKittyImage(x, y, image) image.damaged = false ok() proc clearCanvas*(term: Terminal) = term.cleared = false let maxwpx = term.attrs.widthPx let maxh = term.attrs.height - 1 let maxhpx = maxh * term.attrs.ppl var imagesHead: CanvasImage = nil var imagesTail: CanvasImage = nil var image = term.frame.canvasImagesHead while image != nil: let next = image.next if not image.scrolled and term.repositionImage(image, maxwpx, maxhpx): image.damaged = true image.next = nil if imagesTail == nil: imagesHead = image else: imagesTail.next = image imagesTail = image image = next term.clearImages(maxh) term.frame.canvasImagesHead = imagesHead proc queueTitle*(term: Terminal; title: string) = if term.frame.title != title: term.frame.queueTitleFlag = true term.frame.title = title # Must be called directly before draw, otherwise the cursor will disappear. proc scrollUp*(term: Terminal; n, scrollBottom: int) = if tfScroll notin term.desc: return for y in countdown(scrollBottom - n - 1, 0): for x in 0 ..< term.attrs.width: let i = y * term.attrs.width + x let j = (y + n) * term.attrs.width + x term.frame.canvas[j] = move(term.frame.canvas[i]) for y in 0 ..< n: term.frame.lineDamage[y] = 0 let maxwpx = term.attrs.widthPx let maxhpx = scrollBottom * term.attrs.ppl let scrolled = term.imageMode == imSixel var found = false var image = term.frame.canvasImagesHead var prev: CanvasImage = nil while image != nil: image.dims.y += n image.scrolled = scrolled found = true let erry = image.dims.erry let offy = image.dims.offy if not term.repositionImage(image, maxwpx, maxhpx): # no longer visible let next = move(image.next) if prev != nil: prev.next = next else: term.frame.canvasImagesHead = next if term.imageMode == imKitty: # see below term.frame.kittyImagesToClear.add(image.kittyId) image = next continue if term.imageMode == imKitty: # Kitty exhibits strange behavior on scroll up: # * if the image touches the scroll boundary on the bottom, and is # cropped on the top, then the image fails to scroll. # * otherwise, the image is cropped, but the cropping code is # apparently glitched. # So we just mark all images as damaged in this case; repainting Kitty # is cheap anyway. image.damaged = true # scroll up does not change offy or erry (the slice's start). image.dims.offy = offy image.dims.erry = erry prev = image image = image.next if found and (n > 1 or term.termType == ttXterm): # XTerm can't do single-line scroll-up correctly, see below. term.frame.fastScrollTodo = true term.frame.scrollTodo -= n proc scrollDown*(term: Terminal; n, scrollBottom: int) = if tfScroll notin term.desc: return for y in n ..< scrollBottom: for x in 0 ..< term.attrs.width: let i = y * term.attrs.width + x let j = (y - n) * term.attrs.width + x term.frame.canvas[j] = move(term.frame.canvas[i]) for y in scrollBottom - n ..< scrollBottom: term.frame.lineDamage[y] = 0 let maxwpx = term.attrs.widthPx let maxhpx = scrollBottom * term.attrs.ppl let scrolled = term.imageMode == imSixel var found = false var image = term.frame.canvasImagesHead var prev: CanvasImage = nil while image != nil: found = true image.dims.y -= n image.scrolled = scrolled let disph = image.dims.disph if not term.repositionImage(image, maxwpx, maxhpx): # no longer visible let next = move(image.next) if prev != nil: prev.next = next else: term.frame.canvasImagesHead = next if term.imageMode == imKitty: # see below term.frame.kittyImagesToClear.add(image.kittyId) image = next continue if term.imageMode == imKitty: # scroll down seems to work in Kitty, but not in Ghostty :( # so we apply the same workaround. image.damaged = true # scroll down doesn't change disph (the slice's end). image.dims.disph = disph prev = image image = image.next if found and n > 1: term.frame.fastScrollTodo = true term.frame.scrollTodo += n proc draw*(term: Terminal; redraw, mouse: bool; cursorx, cursory, scrollBottom: int; bgcolor: CellColor): Opt[void] = if redraw: if not term.cleared: ?term.fullDraw() term.cleared = true else: ?term.partialDraw(scrollBottom, bgcolor) if term.imageMode != imNone: ?term.outputImages() if cursory > term.frame.scrollBottom: ?term.resetScrollArea() ?term.cursorGoto(cursorx, cursory) ?term.showCursor() if term.frame.queueTitleFlag and term.hasTitle(): ?term.write(OSC & "0;" & term.frame.title.replaceControls() & ST) term.frame.queueTitleFlag = false if term.hasMouse() and mouse != term.frame.mouseEnabled: if mouse: ?term.write(SetSGRMouse) else: ?term.write(ResetSGRMouse) term.frame.mouseEnabled = mouse term.startFlush() proc sendOSC52*(term: Terminal; s: string; clipboard = true): Opt[bool] = if not term.osc52Copy: return ok(false) var buf = OSC & "52;" if clipboard: buf &= 'c' if term.osc52Primary: buf &= 'p' buf &= ';' buf.btoa(s.toOpenArrayByte(0, s.high)) buf &= ST let ot = term.frameType term.frameType = ftCurrent ?term.write(buf) term.frameType = ot ok(true) # see https://viewsourcecode.org/snaptoken/kilo/02.enteringRawMode.html proc disableRawMode(term: Terminal): Opt[void] = if tcSetAttr(term.istream.fd, TCSAFLUSH, addr term.origTermios) < 0: return err() ok() proc enableRawMode(term: Terminal): Opt[void] = if tcGetAttr(term.istream.fd, addr term.origTermios) < 0: return err() var raw = term.origTermios raw.c_iflag = raw.c_iflag and not (BRKINT or ICRNL or INPCK or ISTRIP) if tfFlowControl notin term.desc: # If the terminal actually uses flow control, just let the OS handle it. # Otherwise, disable it so that the user can bind C-s and C-q freely. raw.c_iflag = raw.c_iflag and not IXON raw.c_oflag = raw.c_oflag and not (OPOST) raw.c_cflag = raw.c_cflag or CS8 raw.c_lflag = raw.c_lflag and not (ECHO or ICANON or ISIG or IEXTEN) raw.c_cc[VMIN] = char(1) raw.c_cc[VTIME] = char(0) term.newTermios = raw if tcSetAttr(term.istream.fd, TCSAFLUSH, addr raw) < 0: return err() ok() # This is checked in the SIGINT handler, set in main.nim. var sigintCaught* {.global.} = false var acceptSigint* {.global.} = false proc catchSigint*(term: Terminal) = term.newTermios.c_lflag = term.newTermios.c_lflag or ISIG acceptSigint = true discard tcSetAttr(term.istream.fd, TCSADRAIN, addr term.newTermios) proc respectSigint*(term: Terminal) = sigintCaught = false acceptSigint = false term.newTermios.c_lflag = term.newTermios.c_lflag and not ISIG discard tcSetAttr(term.istream.fd, TCSADRAIN, addr term.newTermios) proc quit*(term: Terminal): Opt[void] = if term.isatty(): term.frameType = ftCurrent # drop buffered frames if term.hasMouse() and term.frame.mouseEnabled: ?term.write(ResetSGRMouse) term.frame.mouseEnabled = false if term.hasBracketedPaste(): ?term.write(ResetBracketedPaste) ?term.resetScrollArea() if term.hasAltScreen(): if term.imageMode == imSixel: # xterm seems to keep sixels in the alt screen; clear these so it # doesn't flash in the user's face the next time they do smcup ?term.clearDisplay() ?term.write(ResetAltScreen) else: ?term.cursorGoto(0, term.attrs.height - 1) ?term.resetFormat() # if cleared, we have something on the screen; print a newline to # avoid overprinting it if term.cleared: ?term.cursorNextLineBegin() if term.hasTitle(): ?term.write(PopTitle) ?term.showCursor() ?term.blockIO() term.newTermios.c_lflag = term.newTermios.c_lflag or ISIG discard tcSetAttr(term.istream.fd, TCSANOW, addr term.newTermios) discard myposix.signal(SIGINT, myposix.SIG_DFL) while term.eparser.queryState != qsNone: if term.ahandleRead().isErr: break while true: if term.areadEvent().isErr: break ?term.disableRawMode() term.clearCanvas() ok() proc setQueryState(term: Terminal; qs: QueryState) = if term.eparser.queryState == qsNone: term.eparser.queryState = qs else: # I think this leaks on poorly written terminals, but one byte per # window change shouldn't be a problem term.eparser.queryStateStack.add(qs) proc queryAttrs(term: Terminal; windowOnly: bool): Opt[void] = if tfPreEcma48 in term.desc: term.eparser.queryState = qsNone return ok() let ot = term.frameType # query in the current frame term.frameType = ftCurrent if not windowOnly: term.setQueryState(qsBackgroundColor) if tfXtermQuery in term.desc: if term.config{"defaultBackgroundColor"}.isNone: ?term.write(QueryBackgroundColor) if term.config{"defaultForegroundColor"}.isNone: ?term.write(QueryForegroundColor) if term.config{"osc52Copy"}.isNone or term.config{"osc52Primary"}.isNone: ?term.write(QueryXtermAllowedOps) ?term.write(QueryXtermWindowOps) if term.config{"imageMode"}.isNone: if tfBleedsAPC notin term.desc: ?term.write(KittyQuery) ?term.write(QueryColorRegisters) elif term.config{"imageMode"}.get == imSixel: ?term.write(QueryColorRegisters) if term.attrs.colorMode < cmTrueColor and term.config{"colorMode"}.isNone: ?term.write(QueryTcapRGB) ?term.write(QueryANSIColors) ?term.write(DA1) else: term.setQueryState(qsCellSize) # We send these unconditionally because the OpenSSH fork of M$ returns # fake garbage in TIOCGWINSZ and this way we have a chance of the terminal # sending back real data to override that. if tfXtermQuery in term.desc: ?term.write(static(QueryCellSize & QueryWindowPixels)) # The resize hack. # # All vaguely VT100-compatible terminals must implement CPR, so sending # this last should ensure that the query state is set to qsNone and # thereby prevent any user input from being processed as a query response. # # We also prefer this to XTerm's (Sun's?) window size querying mechanism # because some old tmux versions output botched responses to that. ?term.cursorGoto(9998, 9998) ?term.write(QueryCursorPosition) term.unsetCursorPos() term.frameType = ot term.startFlush() # Parse TERM variable. This may adjust color-mode. proc parseTERM(term: Terminal): TerminalType = var s = getEnvEmpty("TERM", "xterm") # Sometimes, TERM variables contain: # -{n}color to denote the number of color registers # -direct[n] to denote direct colors (n is irrelevant here) # (in terminfo.src from ncurses at least...) if s.endsWith("color"): let i = s.rfind('-') if i != -1: let n = parseInt32(s.toOpenArray(i + 1, s.high - "color".len)).get(-1) if n == 256: term.attrs.colorMode = cmEightBit elif n >= 16: term.attrs.colorMode = cmANSI s.setLen(i) else: var i = s.high while i >= 0 and s[i] in AsciiDigit: dec i if s.substr(0, i).endsWith("-direct"): term.attrs.colorMode = cmTrueColor s.setLen(i + 1 - "-direct".len) # XTerm is the universal fallback. var res = strictParseEnum[TerminalType](s).get(ttXterm) # some screen versions use screen.{actual-terminal}, but we don't # really care about the actual terminal. if s.startsWith("screen."): res = ttScreen # tmux says it's screen, but it isn't. if res == ttScreen and getEnv("TMUX") != "": return ttTmux when defined(freebsd): # FreeBSD console says it's an XTerm, but it responds to *absolutely # nothing*. if res == ttXterm: let KDGETMODE {.global, importc, header: "<sys/consio.h>".}: culong var mode: cint if ioctl(term.istream.fd, KDGETMODE, addr mode) != -1: res = ttFreebsd # zellij says it's its underlying terminal, but it isn't. if getEnv("ZELLIJ") != "": return ttZellij return res proc applyTermDesc(term: Terminal; desc: Termdesc) = if tfColor1 in desc: if tfColor2 in desc: term.attrs.colorMode = cmTrueColor else: term.attrs.colorMode = cmANSI elif tfColor2 in desc: term.attrs.colorMode = cmEightBit if tfSixel in desc: term.imageMode = imSixel term.desc = desc case term.termType of ttVt52, ttAdm3a: discard of ttVt100Nav: term.formatMode = {ffReverse} of ttVt100: term.formatMode = {ffReverse, ffBold, ffBlink, ffUnderline} else: # Unless a terminal can't process one of these, it's OK to enable # all of them. term.formatMode = {FormatFlag.low..FormatFlag.high} # when windowOnly, only refresh window size. proc detectTermAttributes(term: Terminal; windowOnly: bool): Opt[void] = if not term.isatty(): return ok() if not windowOnly: term.termType = term.parseTERM() let colorterm = getEnv("COLORTERM") if colorterm in ["24bit", "truecolor"]: term.attrs.colorMode = cmTrueColor term.applyTermDesc(TermdescMap[term.termType]) let margin = int(tfMargin in term.desc) var win: IOctl_WinSize if ioctl(term.istream.fd, TIOCGWINSZ, addr win) != -1: if win.ws_col > 0: term.attrs.width = int(win.ws_col) - margin term.attrs.ppc = int(win.ws_xpixel) div term.attrs.width if win.ws_row > 0: term.attrs.height = int(win.ws_row) term.attrs.ppl = int(win.ws_ypixel) div term.attrs.height if term.attrs.width == 0: term.attrs.width = parseIntP(getEnv("COLUMNS")).get(0) - margin if term.attrs.height == 0: term.attrs.height = parseIntP(getEnv("LINES")).get(0) ok() proc initCanvas(term: Terminal) = for frame in term.frames.mitems: frame.lineDamage = newSeq[int](term.attrs.height) frame.canvas = newSeq[FixedCell](term.attrs.width * term.attrs.height) frame.scrollBottom = -1 proc windowChange(term: Terminal) = term.applyConfigDimensions() term.initCanvas() term.clearCanvas() proc queryWindowSize*(term: Terminal): Opt[void] = ?term.detectTermAttributes(windowOnly = true) ?term.queryAttrs(windowOnly = true) term.windowChange() ok() proc initScreen(term: Terminal): Opt[void] = # note: deinit happens in quit() term.unblockIO() term.unsetCursorPos() if term.hasTitle(): ?term.write(PushTitle) if term.hasAltScreen(): ?term.write(SetAltScreen) if term.hasBracketedPaste(): ?term.write(SetBracketedPaste) if term.hasMouse(): ?term.write(SetSGRMouse) term.frame.mouseEnabled = true term.startFlush() proc start*(term: Terminal; istream: PosixStream): Opt[void] = term.ttyFlag = istream != nil and istream.isatty() and term.ostream.isatty() term.istream = istream if term.isatty(): ?term.detectTermAttributes(windowOnly = false) ?term.enableRawMode() term.applyConfig() if term.isatty(): ?term.initScreen() # only query attrs after initializing screen to avoid moving the cursor # outside of the alt screen ?term.queryAttrs(windowOnly = false) term.initCanvas() ok() proc restart*(term: Terminal): Opt[void] = if term.isatty(): ?term.enableRawMode() ?term.initScreen() ok() const ANSIColorMap = [ rgb(0, 0, 0), rgb(205, 0, 0), rgb(0, 205, 0), rgb(205, 205, 0), rgb(0, 0, 238), rgb(205, 0, 205), rgb(0, 205, 205), rgb(229, 229, 229), rgb(127, 127, 127), rgb(255, 0, 0), rgb(0, 255, 0), rgb(255, 255, 0), rgb(92, 92, 255), rgb(255, 0, 255), rgb(0, 255, 255), rgb(255, 255, 255) ] proc newTerminal*(ostream: PosixStream; config: Config; loader: FileLoader): Terminal = const DefaultBackground = namedRGBColor("black").get const DefaultForeground = namedRGBColor("white").get return Terminal( ostream: ostream, config: config, defaultBackground: DefaultBackground, defaultForeground: DefaultForeground, colorMap: ANSIColorMap, termType: ttXterm, sixelRegisterNum: 256, loader: loader ) {.pop.} # raises: [] �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/main.nim��������������������������������������������������������������������������0000664�0000000�0000000�00000034361�15202323131�0015361�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/os import std/posix import encoding/charset import config/chapath import config/config import config/conftypes import html/catom import html/dom import html/env import html/script import io/chafile import io/console import io/dynstream import io/poll import local/clientutil import local/lineedit import local/pager import local/select import local/term import monoucha/fromjs import monoucha/jsbind import monoucha/jsutils import monoucha/quickjs import monoucha/tojs import server/bufferiface import server/forkserver import server/loaderiface import types/jsopt import types/opt import utils/myposix import utils/sandbox import utils/strwidth import utils/twtstr const ChaVersionStr0 = "Chawan browser v0.4.0" const ChaVersionStr = block: var s = ChaVersionStr0 & " (" when defined(debug): s &= "debug" else: s &= "release" s &= ", " s &= $SandboxMode s &= ", " s &= $PollMode s & ")\n" const ChaVersionStrLong = block: var s = ChaVersionStr0 & " (" when defined(debug): s &= "debug" else: s &= "release" s &= ", " when SandboxMode == stNone: s &= "not sandboxed" else: s &= "sandboxed by " & $SandboxMode s &= ", " s &= "poll uses " & $PollMode s & ")\n" proc die(s: string) {.noreturn.} = discard cast[ChaFile](stderr).writeLine("cha: " & s) quit(1) proc help(i: int) {.noreturn.} = let s = ChaVersionStr & """ Usage: cha [options] [URL(s) or file(s)...] Options: -- Interpret all following arguments as URLs -c, --css <stylesheet> Pass stylesheet (e.g. -c 'a {color: blue}') -d, --dump Print page to stdout -h, --help Print this usage message -o, --opt <config> Pass config options (e.g. -o buffer.images=true) -r, --run <script/file> Run passed script or file -v, --version Print version information -C, --config <file> Override config path -I, --input-charset <enc> Specify document charset -M, --monochrome Set color-mode to 'monochrome' -O, --output-charset <enc> Specify display charset -T, --type <type> Specify content mime type -V, --visual Visual startup mode """ if i == 0: discard cast[ChaFile](stdout).write(s) else: discard cast[ChaFile](stderr).write(s) quit(i) proc version() = discard cast[ChaFile](stdout).write(ChaVersionStrLong) quit(0) type ParamParseContext = object params: seq[string] i: int next: string configPath: string contentType: string charset: Charset visual: bool opts: seq[string] stylesheet: string jsctx: JSContext pages: seq[JSValue] proc addPage(ctx: var ParamParseContext; s: string): Opt[void] = let val = ctx.jsctx.toJS(s) if JS_IsException(val): return err() ctx.pages.add(val) ok() proc addDefaultPages(ctx: var ParamParseContext; config: Config; history: var bool): Opt[void] = if ctx.visual: history = false return ctx.addPage(config{"visualHome"}) if (let httpHome = getEnv("HTTP_HOME"); httpHome != ""): history = false return ctx.addPage(httpHome) if (let wwwHome = getEnv("WWW_HOME"); wwwHome != ""): history = false return ctx.addPage(wwwHome) ok() proc getNext(ctx: var ParamParseContext): string = if ctx.next != "": return ctx.next inc ctx.i if ctx.i < ctx.params.len: return ctx.params[ctx.i] help(1) proc parseConfig(ctx: var ParamParseContext) = ctx.configPath = ctx.getNext() if ctx.configPath == "": die("config override cannot be empty") proc parseMonochrome(ctx: var ParamParseContext) = ctx.opts.add("display.color-mode = monochrome") proc parseVisual(ctx: var ParamParseContext) = ctx.visual = true proc parseContentType(ctx: var ParamParseContext) = ctx.contentType = ctx.getNext() proc getCharset(ctx: var ParamParseContext): Charset = let s = ctx.getNext() let charset = getCharset(s) if charset == csUnknown: die("unknown charset " & s) return charset proc parseInputCharset(ctx: var ParamParseContext) = ctx.charset = ctx.getCharset() proc parseOutputCharset(ctx: var ParamParseContext) = ctx.opts.add("encoding.display-charset = '" & $ctx.getCharset() & "'") proc parseDump(ctx: var ParamParseContext) = ctx.opts.add("start.headless = 'dump'") proc parseCSS(ctx: var ParamParseContext) = ctx.stylesheet &= ctx.getNext() proc parseOpt(ctx: var ParamParseContext) = ctx.opts.add(ctx.getNext()) proc parseRun(ctx: var ParamParseContext) = let script = dqEscape(ctx.getNext()) ctx.opts.add("start.startup-script = \"\"\"" & script & "\"\"\"") ctx.opts.add("start.headless = true") proc parse(ctx: var ParamParseContext): Opt[void] = var escapeAll = false while ctx.i < ctx.params.len: let param = ctx.params[ctx.i] if escapeAll: # after -- ?ctx.addPage(param) inc ctx.i continue if param.len <= 0: inc ctx.i continue if param[0] == '-': if param.len == 1: # If param == "-", i.e. it is a single dash, then ignore it. # (Some programs use single-dash to read from stdin, but we do that # automatically when stdin is not a tty. So ignoring it entirely # is probably for the best.) inc ctx.i continue if param[1] != '-': for j in 1 ..< param.len: const NeedsNextParam = {'C', 'I', 'O', 'T', 'c', 'o', 'r'} if j < param.high and param[j] in NeedsNextParam: ctx.next = param.substr(j + 1) case param[j] of 'C': ctx.parseConfig() of 'I': ctx.parseInputCharset() of 'M': ctx.parseMonochrome() of 'O': ctx.parseOutputCharset() of 'T': ctx.parseContentType() of 'V': ctx.parseVisual() of 'c': ctx.parseCSS() of 'd': ctx.parseDump() of 'h': help(0) of 'o': ctx.parseOpt() of 'r': ctx.parseRun() of 'v': version() else: help(1) if ctx.next != "": ctx.next = "" break else: case param of "--config": ctx.parseConfig() of "--input-charset": ctx.parseInputCharset() of "--monochrome": ctx.parseMonochrome() of "--output-charset": ctx.parseOutputCharset() of "--type": ctx.parseContentType() of "--visual": ctx.parseVisual() of "--css": ctx.parseCSS() of "--dump": ctx.parseDump() of "--help": help(0) of "--opt": ctx.parseOpt() of "--run": ctx.parseRun() of "--version": version() of "--": escapeAll = true else: help(1) else: ?ctx.addPage(param) inc ctx.i ok() proc initConfig(ctx: ParamParseContext; warnings: var seq[string]; jsctx: JSContext): Result[Config, string] = var dir, dataDir: string let file = openConfig(dir, dataDir, ctx.configPath, warnings) if file.isErr and ctx.configPath.len > 0: # The user specified a non-existent config file. return err("failed to open config file " & ctx.configPath) if twtstr.setEnv("CHA_DIR", dir).isErr or twtstr.setEnv("CHA_DATA_DIR", dataDir).isErr: die("failed to set env vars") let config = newConfig(jsctx, dir, dataDir) if config == nil: return err(jsctx.getExceptionMsg()) let cwd = myposix.getcwd() if file.isOk: ?config.parseConfig(config.dir, file.get, warnings, jsctx, "config.toml") discard file.get.close() for opt in ctx.opts: ?config.parseConfig(cwd, opt, warnings, jsctx, "<input>", laxnames = true) config{"userStyle"} &= ctx.stylesheet isCJKAmbiguous = config{"doubleWidthAmbiguous"} ok(config) const libexecPath {.strdefine.} = "$CHA_BIN_DIR/../libexec/chawan" proc forkForkServer(loaderSockVec: array[2, cint]; pagerPid: int): ForkServer = var sockVec {.noinit.}: array[2, cint] # stdin in forkserver var pipeFdErr {.noinit.}: array[2, cint] # stderr in forkserver if socketpair(AF_UNIX, SOCK_STREAM, IPPROTO_IP, sockVec) != 0: die("failed to open fork server i/o socket") if pipe(pipeFdErr) == -1: die("failed to open fork server error pipe") let westream = newPosixStream(pipeFdErr[1]) let pid = fork() if pid == -1: die("failed to fork fork the server process") elif pid == 0: # child process discard setpgid(0, 0) closeStdin() closeStdout() westream.moveFd(STDERR_FILENO) discard close(pipeFdErr[0]) # close read discard close(sockVec[0]) discard close(loaderSockVec[0]) let controlStream = newPosixStream(sockVec[1]) let loaderStream = newPosixStream(loaderSockVec[1]) runForkServer(controlStream, loaderStream, pagerPid) exitnow(1) else: discard close(sockVec[1]) discard close(loaderSockVec[1]) let stream = newPosixStream(sockVec[0]) stream.setCloseOnExec() let estream = newPosixStream(pipeFdErr[0]) estream.setCloseOnExec() estream.setBlocking(false) return ForkServer( pid: pid, stream: stream, estream: estream, westream: westream ) proc setupStartupScript(ctx: JSContext; script: string) = let path = ChaPath("$CHA_LIBEXEC_DIR/" & script).unquoteGet() let ps = newPosixStream(path) if ps != nil: let src = ps.readAllOrMmap() let obj = JS_ReadObject(ctx, cast[ptr uint8](src.p), csize_t(src.len), JS_READ_OBJ_BYTECODE) if JS_IsException(obj): die(ctx.getExceptionMsg()) let ret = JS_EvalFunction(ctx, obj) JS_FreeValue(ctx, obj) if JS_IsException(ret): die(ctx.getExceptionMsg()) JS_FreeValue(ctx, ret) else: die("failed to read startup bytecode") proc readFile(ctx: JSContext; this: Window; path: string): JSValue {.jsfunc.} = var s: string if chafile.readFile(path, s).isOk: return ctx.toJS(s) return JS_NULL proc writeFile(ctx: JSContext; this: Window; path, content: string; mode = cint(0o644)): JSValue {.jsfunc.} = if chafile.writeFile(path, content, mode).isOk: return JS_UNDEFINED return JS_ThrowTypeError(ctx, "Could not write to file %s", cstring(path)) proc getenv(ctx: JSContext; this: Window; s: string; fallback: JSValueConst = JS_NULL): JSValue {.jsfunc.} = let env = twtstr.getEnvCString(s) if env == nil: return JS_DupValue(ctx, fallback) return JS_NewString(ctx, env) proc setenv(ctx: JSContext; this: Window; s: string; val: JSValueConst): JSValue {.jsfunc.} = if JS_IsNull(val): twtstr.unsetEnv(s) else: var vals: string ?ctx.fromJS(val, vals) if twtstr.setEnv(s, vals).isErr: return JS_ThrowTypeError(ctx, "Failed to set environment variable") return JS_UNDEFINED let ClientJSFunctions {.global.} = [ JS_CFUNC_DEF("getenv", 0, js_func_Window_getenv), JS_CFUNC_DEF("setenv", 0, js_func_Window_setenv), JS_CFUNC_DEF("readFile", 0, js_func_Window_readFile), JS_CFUNC_DEF("writeFile", 0, js_func_Window_writeFile) ] proc addJSModules(client: Window; ctx: JSContext): Opt[void] = ?ctx.addCommonModules(client) let global = JS_GetGlobalObject(ctx) if not ctx.setPropertyFunctionList(global, ClientJSFunctions): return err() JS_FreeValue(ctx, global) ?ctx.addUtilModule() ?ctx.addLineEditModule() ?ctx.addConfigModule() ?ctx.addPagerModule() ?ctx.addBufferInterfaceModule() ?ctx.addSelectModule() ok() proc newClient(forkserver: ForkServer; loader: FileLoader; jsctx: JSContext; urandom: PosixStream): Window = let console = newConsole(cast[ChaFile](stderr)) let client = Window( jsctx: jsctx, loader: loader, crypto: Crypto(urandom: urandom), console: console, settings: EnvironmentSettings( scripting: smApp, ), dangerAlwaysSameOrigin: true ) if client.addJSModules(jsctx).isOk: return client else: die("failed to initialize JS " & jsctx.getExceptionMsg()) proc main2(rt: JSRuntime; loaderSockVec: array[2, cint]; pagerPid: int; forkserver: ForkServer): int = let jsctx = rt.newJSContext() let urandom = newPosixStream("/dev/urandom", O_RDONLY, 0) urandom.setCloseOnExec() var ctx = ParamParseContext(jsctx: jsctx, params: commandLineParams(), i: 0) if ctx.parse().isErr: die(jsctx.getExceptionMsg()) let loaderControl = newPosixStream(loaderSockVec[0]) loaderControl.setCloseOnExec() let loader = newFileLoader(pagerPid, loaderControl) let client = newClient(forkserver, loader, jsctx, urandom) var warnings = newSeq[string]() let cres = ctx.initConfig(warnings, jsctx) if cres.isErr: die(cres.error) let config = cres.get let global = JS_GetGlobalObject(jsctx) if jsctx.definePropertyConvert(global, "config", config) == dprException: die(jsctx.getExceptionMsg()) JS_FreeValue(jsctx, global) var history = true let ps = newPosixStream(STDIN_FILENO) if ctx.pages.len == 0 and ps.isatty(): if ctx.addDefaultPages(config, history).isErr: die(jsctx.getExceptionMsg()) if ctx.pages.len == 0 and config{"headless"} != hmTrue: if ps.isatty(): help(1) # make sure tmpdir exists let tmpdir = cstring(config{"tmpdir"}) discard mkdir(tmpdir, 0o700) if chown(tmpdir, getuid(), getgid()) != 0: die("failed to set ownership of " & config{"tmpdir"}) if chmod(tmpdir, 0o700) != 0: die("failed to set permissions of " & config{"tmpdir"}) let loaderPid = forkserver.loadConfig(config) if loaderPid == -1: die("failed to fork loader process") onSignal SIGINT: discard sig if acceptSigint: sigintCaught = true else: quit(1) jsctx.setupStartupScript("init.jsb") let pager = newPager(config, forkserver, jsctx, warnings, loader, loaderPid, client.console) client.timeouts = pager.timeouts client.settings.attrsp = addr pager.term.attrs client.settings.scriptAttrsp = addr pager.term.attrs let code = pager.run(ctx.pages, ctx.contentType, ctx.charset, history) jsctx.free() return code proc main() = initCAtomFactory() let binDir = myposix.getAppFilename().untilLast('/') if twtstr.setEnv("CHA_BIN_DIR", binDir).isErr or twtstr.setEnv("CHA_LIBEXEC_DIR", ChaPath(libexecPath).unquoteGet()).isErr: die("failed to set env vars") var loaderSockVec {.noinit.}: array[2, cint] if socketpair(AF_UNIX, SOCK_STREAM, IPPROTO_IP, loaderSockVec) != 0: die("failed to set up initial socket pair") let pagerPid = getCurrentProcessId() let forkserver = forkForkServer(loaderSockVec, pagerPid) let jsrt = newGlobalJSRuntime() let code = main2(jsrt, loaderSockVec, pagerPid, forkserver) jsrt.free() quit(code) main() {.pop.} # raises: [] �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/server/���������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0015227�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/server/buffer.nim�����������������������������������������������������������������0000664�0000000�0000000�00000165155�15202323131�0017222�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/macros import std/options import std/posix import std/tables import encoding/charset import encoding/decoder import encoding/decodercore import chame/htmlparser import chame/tags import config/conftypes import css/box import css/csstree import css/cssvalues import css/layout import css/lunit import css/render import html/catom import html/chadombuilder import html/dom import html/env import html/event import html/formdata as formdata_impl import io/chafile import io/console import io/dynstream import io/packetreader import io/packetwriter import io/poll import io/timeout import local/select import monoucha/fromjs import monoucha/jsbind import monoucha/jsutils import monoucha/libregexp import monoucha/quickjs import server/bufferiface import server/headers import server/loaderiface import server/request import types/blob import types/cell import types/color import types/formdata import types/jsopt import types/opt import types/refstring import types/url import types/winattrs import utils/lrewrap import utils/luwrap import utils/strwidth import utils/twtstr type InputData = ref object of MapData PagerHandle = ref object of MapData tasks: array[BufferCommand, int] reportedLoad: LoadResult onReshapeImmediately: bool prevHover: Element next: PagerHandle hoverText: array[HoverType, string] BufferContext = ref object of RootObj firstBufferRead: bool headlessLoading: bool ishtml: bool needsBOMSniff: bool savetask: bool checkJobs: bool state: BufferState charset: Charset bgcolor: CellColor attrs: WindowAttributes bytesRead: uint64 cacheId: int charsetStack: seq[Charset] config: BufferConfig ctx: TextDecoderContext htmlParser: HTML5ParserWrapper images: seq[PosBitmap] linkHintChars: ref seq[uint32] schemes: seq[string] lines: FlexibleGrid loader: FileLoader navigateUrl: URL # stored when JS tries to navigate outputId: int clickResult: ClickResult rootBox: BlockBox window: Window luctx: LUContext nhints: int handlesHead: PagerHandle CommandResult = enum cmdrDone, cmdrEOF # Forward declarations proc click(bc: BufferContext; clickable: Element): ClickResult proc submitForm(bc: BufferContext; form: HTMLFormElement; submitter: HTMLElement; jsSubmitCall = false): Request iterator handles(bc: BufferContext): PagerHandle = var it = bc.handlesHead while it != nil: yield it it = it.next template document(bc: BufferContext): Document = bc.window.document template withPacketWriterReturnEOF(stream: PosixStream; w, body: untyped) = stream.withPacketWriter w: body do: return cmdrEOF # For each proxied command, we create a proxy proc to read packets in # buffer, call proxied proc, and send back the result (nameCmd). type ProxyFlag = enum pfNone, pfTask macro proxyt(flag: static ProxyFlag; fun: typed) = let name = fun.name # sym let params = fun.params # formalParams let cmd = strictParseEnum[BufferCommand](name.strVal).get let stmts = newStmtList() let r = ident("r") let packetid = ident("packetid") let call = newCall(name, ident("bc"), ident("handle")) for i in 3 ..< params.len: let param = params[i] for i in 0 ..< param.len - 2: let id = ident(param[i].strVal) let typ = param[^2] stmts.add(quote do: var `id`: `typ` `r`.sread(`id`) ) call.add(id) let hasRes = params[0].kind == nnkEmpty if hasRes: stmts.add(call) else: stmts.add(quote do: let retval {.inject.} = `call`) let resolve = if hasRes: quote do: handle.stream.withPacketWriterReturnEOF wt: wt.swrite(`packetid`) else: quote do: handle.stream.withPacketWriterReturnEOF wt: wt.swrite(`packetid`) wt.swrite(retval) case flag of pfTask: stmts.add(quote do: if bc.savetask: bc.savetask = false handle.tasks[BufferCommand(`cmd`)] = `packetid` else: `resolve` ) of pfNone: stmts.add(resolve) let nameId = ident(name.strVal & "Cmd") quote do: `fun` proc `nameId`(bc {.inject.}: BufferContext; handle {.inject.}: PagerHandle; `r`: var PacketReader; `packetid`: int): CommandResult = `stmts` cmdrDone template proxy(fun: untyped) = proxyt(pfNone, fun) template proxy(flag, fun: untyped) = proxyt(flag, fun) proc getTitleAttr(bc: BufferContext; element: Element): string = if element != nil: for element in element.branchElems: if element.attrb(satTitle): return element.attr(satTitle) return "" const ClickableElements = { TAG_A, TAG_INPUT, TAG_OPTION, TAG_BUTTON, TAG_TEXTAREA, TAG_LABEL, TAG_VIDEO, TAG_AUDIO, TAG_IFRAME, TAG_FRAME } proc isClickable(element: Element): bool = if element.hasEventListener(satClick.toAtom()): return true if element of HTMLAnchorElement: return HTMLAnchorElement(element).reinitURL().isOk if element.isButton() and FormAssociatedElement(element).form == nil: return false return element.tagType in ClickableElements proc getClickable(element: Element): Element = for element in element.branchElems: if element.isClickable(): return element return nil proc canSubmitOnClick(fae: FormAssociatedElement): bool = if fae.form == nil: return false if fae.form.canSubmitImplicitly(): return true if fae of HTMLButtonElement and HTMLButtonElement(fae).ctype == btSubmit: return true if fae of HTMLInputElement and HTMLInputElement(fae).inputType in {itSubmit, itButton}: return true return false proc getImageHover(bc: BufferContext; element: Element): string = if element of HTMLImageElement: let image = HTMLImageElement(element) let src = image.attr(satSrc) if src != "": if url := image.document.parseURL(src): return $url "" proc getClickHover(bc: BufferContext; element: Element): string = let clickable = element.getClickable() if clickable != nil: case clickable.tagType of TAG_A: if url := HTMLAnchorElement(clickable).reinitURL(): return $url of TAG_OPTION: return "<option>" of TAG_VIDEO, TAG_AUDIO: let (src, _) = HTMLElement(clickable).getSrc() if src != "": if url := clickable.document.parseURL(src): return $url of TAG_FRAME, TAG_IFRAME: let src = clickable.attr(satSrc) if src != "": if url := clickable.document.parseURL(src): return $url elif clickable of FormAssociatedElement: let fae = FormAssociatedElement(clickable) if fae.canSubmitOnClick(): let req = bc.submitForm(fae.form, fae) if req != nil: return $req.url return "<" & $clickable.tagType & ">" "" proc getCachedImageHover(bc: BufferContext; element: Element): string = if element of HTMLImageElement: let image = HTMLImageElement(element) if image.bitmap != nil and image.bitmap.cacheId != 0: return $image.bitmap.cacheId & ' ' & image.bitmap.contentType elif element of SVGSVGElement: let image = SVGSVGElement(element) if image.bitmap != nil and image.bitmap.cacheId != 0: return $image.bitmap.cacheId & ' ' & image.bitmap.contentType "" proc getCursorElement(bc: BufferContext; cursorx, cursory: int): Element = if cursory < 0 or cursory >= bc.lines.len: return nil let i = bc.lines[cursory].findFormatN(cursorx) - 1 if i >= 0: return bc.lines[cursory].formats[i].node return nil proc getCursorClickable(bc: BufferContext; cursorx, cursory: int): Element = let element = bc.getCursorElement(cursorx, cursory) if element != nil: return element.getClickable() return nil proc cursorBytes(bc: BufferContext; y, cc: int): int = let line = bc.lines[y].str var w = 0 var i = 0 while i < line.len and w < cc: let u = line.nextUTF8(i) w += u.width() return i proc navigate(bc: RootRef; url: URL) = let bc = BufferContext(bc) let stderr = cast[ChaFile](stderr) bc.navigateUrl = url discard stderr.writeLine("navigate to " & $url) #TODO rewrite findPrevLink, findNextLink to use the box tree instead proc findPrevLink(bc: BufferContext; handle: PagerHandle; cursorx, cursory, n: int): tuple[x, y: int] {.proxy.} = if cursory >= bc.lines.len: return (-1, -1) var found = 0 var i = bc.lines[cursory].findFormatN(cursorx) - 1 var link: Element = nil if cursorx == int.high: # Special case for when we want to jump to the last link on this # line (for cursorLinkNavUp). i = bc.lines[cursory].formats.len elif i >= 0: link = bc.lines[cursory].formats[i].node.getClickable() dec i var ly = 0 # last y var lx = 0 # last x for y in countdown(cursory, 0): let line = bc.lines[y] if y != cursory: i = line.formats.len - 1 while i >= 0: let format = line.formats[i] let fl = format.node.getClickable() if fl != nil and fl != link: # go to beginning of link ly = y lx = format.pos # on the current line while i >= 0: let format = line.formats[i] let nl = format.node.getClickable() if nl == fl: lx = format.pos dec i # on previous lines for iy in countdown(ly - 1, 0): let line = bc.lines[iy] i = line.formats.len - 1 let oly = iy let olx = lx while i >= 0: let format = line.formats[i] let nl = format.node.getClickable() if nl == fl: ly = iy lx = format.pos dec i if iy == oly and olx == lx: # Assume all multiline anchors are placed on consecutive # lines. # This is not true, but otherwise we would have to loop # through the entire document. # TODO: find an efficient and correct way to do this. break inc found if found == n: return (lx, ly) link = fl dec i return (-1, -1) proc findNextLink(bc: BufferContext; handle: PagerHandle; cursorx, cursory, n: int): tuple[x, y: int] {.proxy.} = if cursory >= bc.lines.len: return (-1, -1) var found = 0 var i = bc.lines[cursory].findFormatN(cursorx) - 1 var link: Element = nil if i >= 0: link = bc.lines[cursory].formats[i].node.getClickable() inc i for j, line in bc.lines.toOpenArray(cursory, bc.lines.high).mypairs: while i < line.formats.len: let format = line.formats[i] let fl = format.node.getClickable() if fl != nil and fl != link: inc found if found == n: return (format.pos, cursory + j) link = fl inc i i = 0 return (-1, -1) proc findNextParagraph(bc: BufferContext; handle: PagerHandle; cursory, n: int): int {.proxy.} = var y = cursory if n < 0: for i in 0 ..< -n: while y >= 0 and bc.lines[y].str.onlyWhitespace(): dec y while y >= 0 and not bc.lines[y].str.onlyWhitespace(): dec y else: for i in 0 ..< n: while y < bc.lines.len and bc.lines[y].str.onlyWhitespace(): inc y while y < bc.lines.len and not bc.lines[y].str.onlyWhitespace(): inc y return y proc findRevNthLink(bc: BufferContext; handle: PagerHandle; i: int): tuple[x, y: int] {.proxy.} = if i == 0: return (-1, -1) var k = 0 var link: Element for y in countdown(bc.lines.high, 0): let line = bc.lines[y] for format in line.formats.ritems: let fl = format.node.getClickable() if fl != nil and fl != link: inc k if k == i: return (format.pos, y) link = fl return (-1, -1) proc findPrevMatch(bc: BufferContext; handle: PagerHandle; regex: Regex; x, y, endy: int; wrap: bool; n: int): BufferMatch {.proxy.} = if n <= 0 or x < 0 or y < 0 or y >= bc.lines.len: return BufferMatch(x: -1, y: -1) var n = n var y = y var b = bc.cursorBytes(y, x) var first = true while true: if y < 0: if not wrap: break y = bc.lines.high let s = bc.lines[y].str if b < 0: b = s.len let cap = regex.matchLast(s.toOpenArray(0, b - 1), 0) if cap.s >= 0: let x = s.width(0, cap.s) let w = s.toOpenArray(cap.s, cap.e - 1).width() dec n if n == 0: return BufferMatch(x: x, y: y, w: w) if y == endy and not first: break first = false b = -1 dec y BufferMatch(x: -1, y: -1) proc findNextMatch(bc: BufferContext; handle: PagerHandle; regex: Regex; cursorx, cursory, endy: int; wrap: bool; n: int): BufferMatch {.proxy.} = if n <= 0 or cursorx < 0 or cursory < 0 or cursory >= bc.lines.len: return BufferMatch(x: -1, y: -1) var y = cursory var n = n var b = bc.cursorBytes(y, cursorx + 1) var first = true while true: if y >= bc.lines.len: if not wrap: break y = 0 let s = bc.lines[y].str let cap = regex.matchFirst(s, b) if cap.s >= 0: let x = s.width(0, cap.s) let w = s.toOpenArray(cap.s, cap.e - 1).width() dec n if n == 0: return BufferMatch(x: x, y: y, w: w) b = 0 if y == endy and not first: break first = false inc y BufferMatch(x: -1, y: -1) proc gotoAnchor(bc: BufferContext; handle: PagerHandle; anchor: string; autofocus, target: bool): GotoAnchorResult {.proxy.} = if bc.document == nil: return GotoAnchorResult(x: -1, y: -1) if anchor.len > 0 and anchor[0] == 'L' and not bc.ishtml: let y = parseIntP(anchor.toOpenArray(1, anchor.high)).get(-1) if y > 0: return GotoAnchorResult(x: 0, y: y - 1) var element = bc.document.findAnchor(anchor) if element == nil: let s = percentDecode(anchor) if s != anchor: element = bc.document.findAnchor(s) if target and element != nil: bc.document.setTarget(element) var focus = initClickResult() # Do not use bc.config.autofocus when we just want to check if the # anchor can be found. if autofocus: let autofocus = bc.document.findAutoFocus() if autofocus != nil: if element == nil: element = autofocus # jump to autofocus instead let res = bc.click(autofocus) if res.t in ClickResultReadLine: focus = res if element == nil or element.box == nil: return GotoAnchorResult(x: -1, y: -1) let offset = CSSBox(element.box).render.offset let x = max(offset.x div bc.attrs.ppc.toLUnit(), 0'lu).toInt let y = max(offset.y div bc.attrs.ppl.toLUnit(), 0'lu).toInt return GotoAnchorResult(x: x, y: y, focus: focus) proc checkRefresh(bc: BufferContext; handle: PagerHandle): CheckRefreshResult {.proxy.} = if bc.navigateUrl != nil: let url = bc.navigateUrl bc.navigateUrl = nil return (n: 0, url: url) if bc.document == nil: return (n: -1, url: nil) let element = bc.document.findMetaRefresh() if element == nil: return (n: -1, url: nil) return parseRefresh(element.attr(satContent), bc.document.url) proc hasTask(handle: PagerHandle; cmd: BufferCommand): bool = return handle.tasks[cmd] != 0 proc resolveTask(handle: PagerHandle; cmd: BufferCommand) = let packetid = handle.tasks[cmd] assert packetid != 0 handle.stream.withPacketWriterFire wt: wt.swrite(packetid) handle.tasks[cmd] = 0 proc resolveTask[T](handle: PagerHandle; cmd: BufferCommand; res: T) = let packetid = handle.tasks[cmd] assert packetid != 0 handle.stream.withPacketWriterFire wt: wt.swrite(packetid) wt.swrite(res) handle.tasks[cmd] = 0 proc resolveLoad(bc: BufferContext; handle: PagerHandle; n, len: uint64) = let res = (n: n, len: len, bs: bc.state) handle.reportedLoad = res handle.resolveTask(bcLoad, res) proc maybeReshape(bc: BufferContext; suppressFouc = false) = let document = bc.document if document == nil or document.documentElement == nil: return # not parsed yet, nothing to render if document.invalid: let (stack, fixedHead) = document.documentElement.buildTree(bc.rootBox, bc.config.markLinks, bc.nhints, bc.linkHintChars) bc.rootBox = BlockBox(stack.box) bc.rootBox.layout(bc.attrs, fixedHead, bc.luctx) bc.lines.render(bc.bgcolor, stack, bc.attrs, bc.images) document.invalid = false # We don't want a FOUC on automatic reshape, but we still want to allow # the user to override this and interact with the page (useful if e.g. a # sheet really doesn't want to load). if not suppressFouc or bc.window.loadedSheetNum == bc.window.remoteSheetNum: for handle in bc.handles: if handle.hasTask(bcOnReshape): handle.resolveTask(bcOnReshape) else: handle.onReshapeImmediately = true proc ensureLayout(bc: RootRef; element: Element) = let bc = BufferContext(bc) bc.maybeReshape(suppressFouc = true) proc processData0(bc: BufferContext; data: UnsafeSlice): bool = if bc.ishtml: if bc.htmlParser.parseBuffer(data.toOpenArray()) == PRES_STOP: bc.charsetStack = @[bc.htmlParser.builder.charset] return false else: var plaintext = bc.document.findFirst(TAG_PLAINTEXT) if plaintext == nil: const s = "<plaintext>" doAssert bc.htmlParser.parseBuffer(s) != PRES_STOP plaintext = bc.document.findFirst(TAG_PLAINTEXT) if data.len > 0: let lastChild = plaintext.lastChild if lastChild != nil and lastChild of Text: Text(lastChild).data.s &= data else: plaintext.insert(bc.document.newText($data), nil) plaintext.invalidate() true proc canSwitch(bc: BufferContext): bool {.inline.} = return bc.htmlParser.builder.confidence == ccTentative and bc.charsetStack.len > 0 const BufferSize = 16384 proc initDecoder(bc: BufferContext) = bc.ctx = initTextDecoderContext(bc.charset, demFatal, BufferSize) proc switchCharset(bc: BufferContext) = bc.charset = bc.charsetStack.pop() bc.initDecoder() bc.htmlParser.restart(bc.charset) bc.document.applyUASheet() bc.document.applyUserSheet(bc.config.userStyle) bc.document.invalid = true proc bomSniff(bc: BufferContext; iq: openArray[uint8]): int = if iq[0] == 0xFE and iq[1] == 0xFF: bc.charsetStack = @[csUtf16be] bc.switchCharset() return 2 if iq[0] == 0xFF and iq[1] == 0xFE: bc.charsetStack = @[csUtf16le] bc.switchCharset() return 2 if iq[0] == 0xEF and iq[1] == 0xBB and iq[2] == 0xBF: bc.charsetStack = @[csUtf8] bc.switchCharset() return 3 return 0 proc processData(bc: BufferContext; iq: openArray[uint8]): bool = var si = 0 if bc.needsBOMSniff: if iq.len >= 3: # ehm... TODO si += bc.bomSniff(iq) bc.needsBOMSniff = false if not bc.canSwitch(): bc.ctx.errorMode = demReplacement for chunk in bc.ctx.decode(iq.toOpenArray(si, iq.high), finish = false): if not bc.processData0(chunk): bc.switchCharset() return false if bc.ctx.failed: bc.switchCharset() return false true const HoverFun = [ htTitle: getTitleAttr, htLink: getClickHover, htImage: getImageHover, htCachedImage: getCachedImageHover ] proc updateHover(bc: BufferContext; handle: PagerHandle; cursorx, cursory: int): UpdateHoverResult {.proxy.} = let thisNode = bc.getCursorElement(cursorx, cursory) var hover = newSeq[tuple[t: HoverType, s: string]]() var repaint = false let prevHover = handle.prevHover if thisNode != prevHover: var oldHover = newSeq[Element]() for element in prevHover.branchElems: if element.hover: oldHover.add(element) for ht in HoverType: let s = HoverFun[ht](bc, thisNode) if handle.hoverText[ht] != s: hover.add((ht, s)) handle.hoverText[ht] = s for element in thisNode.branchElems: if not element.hover: element.setHover(true) repaint = true elif (let i = oldHover.find(element); i != -1): # branches converged oldHover.setLen(i) break for element in oldHover: element.setHover(false) repaint = true if repaint: bc.maybeReshape() handle.prevHover = thisNode move(hover) proc rewind(bc: BufferContext; data: InputData; offset: uint64): bool = let url = parseURL0("cache:" & $bc.cacheId & "?" & $offset) let response = bc.loader.doRequest(newRequest(url)) if response.stream == nil: return false bc.loader.resume(response.outputId) bc.loader.unregister(data) data.stream.sclose() response.stream.setBlocking(false) let data = InputData(stream: response.stream) bc.loader.register(data, POLLIN) bc.bytesRead = offset return true proc addPagerHandle(bc: BufferContext; stream: PosixStream) = let handle = PagerHandle(stream: stream) bc.loader.put(handle) bc.loader.pollData.register(stream.fd, POLLIN) var it = bc.handlesHead if it == nil: bc.handlesHead = handle else: while it.next != nil: it = it.next it.next = handle # returns true if there are still other handles, false otherwise proc removePagerHandle(bc: BufferContext; handle: PagerHandle): bool = bc.loader.unregister(handle) handle.stream.sclose() if bc.handlesHead == handle: bc.handlesHead = bc.handlesHead.next else: var it = bc.handlesHead while it.next != handle: it = it.next it.next = it.next.next bc.handlesHead != nil proc cloneCmd(bc: BufferContext; handle: PagerHandle; r: var PacketReader; packetid: int): CommandResult = var newurl: URL r.sread(newurl) let pstream = newPosixStream(r.recvFd()) bc.addPagerHandle(pstream) let target = bc.document.findAnchor(newurl.hash) bc.document.setTarget(target) handle.stream.withPacketWriterReturnEOF w: w.swrite(packetid) cmdrDone proc dispatchDOMContentLoadedEvent(bc: BufferContext) = let window = bc.window window.fireEvent(satDOMContentLoaded, bc.document, bubbles = false, cancelable = false, trusted = true) bc.maybeReshape(suppressFouc = true) proc dispatchLoadEvent(bc: BufferContext) = let window = bc.window let event = newEvent(satLoad.toAtom(), window.document, bubbles = false, cancelable = false) event.isTrusted = true discard window.jsctx.dispatch(window, event, targetOverride = true) bc.maybeReshape() proc finishLoad(bc: BufferContext; data: InputData) = if bc.ctx.td.charset != csUnknown: for chunk in bc.ctx.decode([], finish = true): doAssert bc.processData0(chunk) bc.htmlParser.finish() bc.document.readyState = rsInteractive if bc.config.scripting != smFalse: bc.dispatchDOMContentLoadedEvent() bc.loader.unregister(data) bc.loader.removeCachedItem(bc.cacheId) bc.cacheId = -1 bc.outputId = -1 data.stream.sclose() proc headlessMustWait(bc: BufferContext): bool = return bc.config.scripting != smFalse and (not bc.window.timeouts.empty or bc.checkJobs) or bc.loader.hasFds() proc imagesLoaded(bc: BufferContext) = bc.maybeReshape() bc.state = bsLoaded bc.document.readyState = rsComplete if bc.config.scripting != smFalse: bc.dispatchLoadEvent() for ctx in bc.window.pendingCanvasCtls: ctx.ps.sclose() ctx.ps = nil bc.window.pendingCanvasCtls.setLen(0) for handle in bc.handles: if handle.hasTask(bcGetTitle): handle.resolveTask(bcGetTitle, bc.document.title) if handle.hasTask(bcLoad): if bc.config.headless == hmTrue and bc.headlessMustWait(): #TODO might want to move this to handle too bc.headlessLoading = true else: bc.resolveLoad(handle, 0, 0) proc sheetsLoaded(bc: BufferContext) = if bc.window.loadedImageNum < bc.window.remoteImageNum: bc.maybeReshape() bc.state = bsLoadingImages for handle in bc.handles: if handle.hasTask(bcLoad): bc.resolveLoad(handle, bc.window.loadedImageNum, bc.window.remoteImageNum) else: bc.imagesLoaded() proc sheetLoaded(bc: RootRef) = let bc = BufferContext(bc) if bc.state == bsLoadingStyle: for handle in bc.handles: if handle.hasTask(bcLoad): bc.resolveLoad(handle, bc.window.loadedSheetNum, bc.window.remoteSheetNum) if bc.window.loadedSheetNum == bc.window.remoteSheetNum: bc.sheetsLoaded() proc imageLoaded(bc: RootRef) = let bc = BufferContext(bc) for handle in bc.handles: if bc.state == bsLoadingImages and handle.hasTask(bcLoad): bc.resolveLoad(handle, bc.window.loadedImageNum, bc.window.remoteImageNum) if handle.hasTask(bcToggleImages): handle.resolveTask(bcToggleImages, bc.config.images) if bc.window.loadedImageNum == bc.window.remoteImageNum: if bc.state == bsLoadingImages: bc.imagesLoaded() elif bc.state == bsLoaded: bc.maybeReshape() # Returns: # * -1 if loading is done # * a positive number for reporting the number of bytes loaded and that the page # has been partially rendered. proc load(bc: BufferContext; handle: PagerHandle): LoadResult {. proxy: pfTask.} = var n = 0'u64 var len = 0'u64 let bs = bc.state case bs of bsLoaded: if bc.config.headless == hmTrue and bc.headlessMustWait(): # suppress load event until all scripts have finished # (obviously, this might never happen) bc.savetask = true bc.headlessLoading = true of bsLoadingImages: n = bc.window.loadedImageNum len = bc.window.remoteImageNum of bsLoadingStyle: n = bc.window.loadedSheetNum len = bc.window.remoteSheetNum of bsLoadingPage: n = bc.bytesRead #TODO the problem here is that content-length is for compressed size, # but we already uncompress inside CGI so it's impossible to compare # the two # probably we'll need some reporting mechanism in BGI if n > handle.reportedLoad.n: bc.maybeReshape(suppressFouc = true) let old = handle.reportedLoad let res = (n: n, len: len, bs: bs) if bs != bsLoaded and old.bs == bs and n == old.n: # drop this result, resolve in onload instead bc.savetask = true else: handle.reportedLoad = res res proc onload(bc: BufferContext; data: InputData) = if bc.state != bsLoadingPage: # We've been called from onError, but we've already seen EOF here. # Nothing to do. return var reprocess = false var iq {.noinit.}: array[BufferSize, uint8] var n = 0 while true: if not reprocess: n = data.stream.read(iq) if n < 0: break bc.bytesRead += uint64(n) if n != 0: if not bc.processData(iq.toOpenArray(0, n - 1)): if not bc.firstBufferRead: reprocess = true continue if bc.rewind(data, 0): continue bc.checkJobs = true bc.firstBufferRead = true reprocess = false else: # EOF bc.finishLoad(data) if bc.window.loadedSheetNum < bc.window.remoteSheetNum: bc.state = bsLoadingStyle for handle in bc.handles: if handle.hasTask(bcLoad): bc.resolveLoad(handle, bc.window.loadedSheetNum, bc.window.remoteSheetNum) else: bc.sheetsLoaded() return # skip incr render # incremental rendering: only if we cannot read the entire stream in one # pass if bc.config.headless == hmFalse: for handle in bc.handles: if handle.hasTask(bcLoad): # only makes sense when not in dump mode (and the user has requested # a load) bc.maybeReshape(suppressFouc = true) if handle.hasTask(bcGetTitle): handle.resolveTask(bcGetTitle, bc.document.title) bc.resolveLoad(handle, bc.bytesRead, 0) #TODO content-length proc getTitle(bc: BufferContext; handle: PagerHandle): string {. proxy: pfTask.} = if bc.document != nil: let title = bc.document.findFirst(TAG_TITLE) if title != nil: return title.childTextContent.stripAndCollapse() if bc.state == bsLoaded: return "" # title no longer expected bc.savetask = true return "" proc forceReshape(bc: BufferContext; handle: PagerHandle) {.proxy.} = if bc.document != nil and bc.document.documentElement != nil: bc.document.documentElement.invalidate() bc.rootBox = nil if bc.document != nil: bc.document.invalid = true bc.maybeReshape() proc windowChange(bc: BufferContext; handle: PagerHandle; attrs: WindowAttributes; x, y: int): PagePos {.proxy.} = let element = bc.getCursorElement(x, y) let box = if element != nil: CSSBox(element.box) else: nil let offset = if box != nil: box.render.offset else: offset(0'lu, 0'lu) let ppc = attrs.ppc.toLUnit() let ppl = attrs.ppl.toLUnit() let dx = x - (offset.x div ppc).toInt() let dy = y - (offset.y div ppl).toInt() bc.attrs = attrs bc.window.windowChange() bc.maybeReshape() if element != nil and element.box != nil: let offset = CSSBox(element.box).render.offset let x = (offset.x div ppc).toInt() + dx let y = (offset.y div ppl).toInt() + dy return (x, y) return (x, y) proc cancel(bc: BufferContext; handle: PagerHandle) {.proxy.} = if bc.state == bsLoaded: return for it in bc.loader.data: if it of PagerHandle: continue bc.loader.unregister(it) it.stream.sclose() if it of InputData: bc.loader.removeCachedItem(bc.cacheId) bc.cacheId = -1 bc.outputId = -1 bc.htmlParser.finish() bc.document.readyState = rsInteractive bc.state = bsLoaded bc.maybeReshape() proc serializePlainTextFormData(kvs: seq[(string, string)]): string = result = "" for (name, value) in kvs: result &= name result &= '=' result &= value result &= "\r\n" proc getOutputEncoding(charset: Charset): Charset = if charset in {csReplacement, csUtf16be, csUtf16le}: return csUtf8 return charset proc pickCharset(form: HTMLFormElement): Charset = if form.attrb(satAcceptCharset): let input = form.attr(satAcceptCharset) for label in input.split(AsciiWhitespace): let charset = label.getCharset() if charset != csUnknown: return charset.getOutputEncoding() return csUtf8 return form.document.charset.getOutputEncoding() # entryList is consumed proc makeFormRequest(bc: BufferContext; parsedAction: URL; httpMethod: HttpMethod; entryList: var seq[FormDataEntry]; enctype: FormEncodingType): Request = assert httpMethod in {hmGet, hmPost} case parsedAction.schemeType of stFtp: return newRequest(parsedAction) # get action URL of stData: if httpMethod == hmGet: # mutate action URL let kvlist = entryList.toNameValuePairs() #TODO with charset parsedAction.setSearch('?' & serializeFormURLEncoded(kvlist)) return newRequest(parsedAction, httpMethod) return newRequest(parsedAction) # get action URL of stMailto: if httpMethod == hmGet: # mailWithHeaders let kvlist = entryList.toNameValuePairs() #TODO with charset parsedAction.setSearch('?' & serializeFormURLEncoded(kvlist, spaceAsPlus = false)) return newRequest(parsedAction, httpMethod) # mail as body let kvlist = entryList.toNameValuePairs() let body = if enctype == fetTextPlain: percentEncode(serializePlainTextFormData(kvlist), PathPercentEncodeSet) else: #TODO with charset serializeFormURLEncoded(kvlist) if parsedAction.search == "": parsedAction.search = "?" if parsedAction.search != "?": parsedAction.search &= '&' parsedAction.search &= "body=" & body return newRequest(parsedAction, httpMethod) else: if httpMethod == hmGet: # mutate action URL let kvlist = entryList.toNameValuePairs() #TODO with charset let search = '?' & serializeFormURLEncoded(kvlist) parsedAction.setSearch(search) return newRequest(parsedAction, httpMethod) # submit as entity body var contentType = $enctype let body = case enctype of fetUrlencoded: #TODO with charset let kvlist = entryList.toNameValuePairs() RequestBody(t: rbtString, s: serializeFormURLEncoded(kvlist)) of fetMultipart: #TODO with charset let formData = newFormData0(bc.window.crypto.urandom) if formData == nil: return nil formData.entries = move(entryList) for entry in formData.entries.mitems: entry.name = makeCRLF(entry.name) contentType = formData.getContentType() RequestBody(t: rbtMultipart, multipart: formData) of fetTextPlain: #TODO with charset let kvlist = entryList.toNameValuePairs() RequestBody(t: rbtString, s: serializePlainTextFormData(kvlist)) let headers = newHeaders(hgRequest, {"Content-Type": move(contentType)}) return newRequest(parsedAction, httpMethod, headers, body) # https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#form-submission-algorithm proc submitForm(bc: BufferContext; form: HTMLFormElement; submitter: HTMLElement; jsSubmitCall = false): Request = if form.constructingEntryList: return nil if not jsSubmitCall and bc.config.scripting != smFalse: if form.firing: return nil form.firing = true #TODO user validity/validity constraints let jsSubmitter = EventTarget(if submitter != form: submitter else: nil) let event = newSubmitEvent(satSubmit.toAtom(), SubmitEventInit( submitter: EventTargetHTMLElement(jsSubmitter), bubbles: true, cancelable: true )) event.isTrusted = true let canceled = bc.window.jsctx.dispatch(form, event) form.firing = false if canceled: return nil let charset = form.pickCharset() discard charset #TODO pass to constructEntryList var entryList = form.constructEntryList(submitter) let subAction = submitter.action() let action = if subAction != "": subAction else: $form.document.url #TODO encoding-parse let parsedAction = submitter.document.parseURL0(action) if parsedAction == nil: return nil let enctype = submitter.enctype() let formMethod = submitter.getFormMethod() let httpMethod = case formMethod of fmDialog: return nil #TODO of fmGet: hmGet of fmPost: hmPost #let target = if submitter.isSubmitButton() and submitter.attrb("formtarget"): # submitter.attr("formtarget") #else: # submitter.target() #let noopener = true #TODO return bc.makeFormRequest(parsedAction, httpMethod, entryList, enctype) proc setFocus(bc: BufferContext; e: Element) = bc.document.setFocus(e) bc.maybeReshape() proc restoreFocus(bc: BufferContext) = bc.document.setFocus(nil) bc.maybeReshape() proc implicitSubmit(bc: BufferContext; input: HTMLInputElement): Request = let form = input.form if form != nil and form.canSubmitImplicitly(): return bc.submitForm(form, form) return nil proc readSuccess0(bc: BufferContext; s: string; fd: cint): Request = if bc.document.focus != nil: let focus = bc.document.focus bc.restoreFocus() case focus.tagType of TAG_INPUT: let input = HTMLInputElement(focus) case input.inputType of itFile: input.files = @[newWebFile(s, fd)] input.invalidate() else: input.setValue(s) if bc.config.scripting != smFalse: let window = bc.window if input.inputType == itFile: window.fireEvent(satInput, input, bubbles = true, cancelable = true, trusted = true) else: let inputEvent = newInputEvent(satInput.toAtom(), InputEventInit( data: some(s), inputType: "insertText", bubbles: true, cancelable: true ) ) inputEvent.isTrusted = true window.fireEvent(inputEvent, input) bc.window.fireEvent(satChange, input, bubbles = true, cancelable = true, trusted = true) bc.maybeReshape() return bc.implicitSubmit(input) of TAG_TEXTAREA: let textarea = HTMLTextAreaElement(focus) textarea.value = s textarea.invalidate() if bc.config.scripting != smFalse: bc.window.fireEvent(satChange, textarea, bubbles = true, cancelable = true, trusted = true) bc.maybeReshape() else: discard return nil proc readSuccessCmd(bc: BufferContext; handle: PagerHandle; r: var PacketReader; packetid: int): CommandResult = var s: string var hasfd: bool r.sread(s) r.sread(hasfd) let fd = if hasfd: r.recvFd() else: -1 let request = bc.readSuccess0(s, fd) let clickResult = initClickResult(request) handle.stream.withPacketWriterReturnEOF w: w.swrite(packetid) w.swrite(clickResult) cmdrDone proc click(bc: BufferContext; label: HTMLLabelElement): ClickResult = let control = label.control if control != nil: return bc.click(control) return initClickResult() proc click(bc: BufferContext; select: HTMLSelectElement): ClickResult = if select.attrb(satMultiple): return initClickResult() bc.setFocus(select) var options: seq[SelectOption] = @[] var selected = -1 var i = 0 for option in select.options: #TODO: add nop options for each optgroup options.add(SelectOption(s: option.textContent.stripAndCollapse())) if selected == -1 and option.selected: selected = i inc i return initClickResult(move(options), selected) proc baseURL(bc: BufferContext): URL = return bc.document.baseURL proc evalJSURL(bc: BufferContext; url: URL): Opt[string] = let surl = $url let source = surl.toOpenArray("javascript:".len, surl.high).percentDecode() let ctx = bc.window.jsctx let ret = ctx.eval(source, $bc.baseURL, JS_EVAL_TYPE_GLOBAL) if JS_IsException(ret): bc.window.console.writeException(ctx) return err() # error if JS_IsUndefined(ret): return err() # no need to navigate var res: string ?ctx.fromJS(ret, res) JS_FreeValue(ctx, ret) # Navigate to result. return ok(res) proc click(bc: BufferContext; anchor: HTMLAnchorElement): ClickResult = bc.restoreFocus() if url := anchor.reinitURL(): if url.schemeType == stJavascript: if bc.config.scripting == smFalse: return initClickResult() let s = bc.evalJSURL(url) bc.maybeReshape() if s.isErr: return initClickResult() let urls = parseURL0("data:text/html," & s.get) if urls == nil: return initClickResult() url = urls return initClickResult(newRequest(url, hmGet)) return initClickResult() proc click(bc: BufferContext; option: HTMLOptionElement): ClickResult = let select = option.select if select != nil: if select.attrb(satMultiple): option.setSelected(not option.selected) if bc.config.scripting != smFalse: bc.window.fireEvent(satChange, select, bubbles = true, cancelable = true, trusted = true) bc.maybeReshape() return initClickResult() return bc.click(select) return initClickResult() proc click(bc: BufferContext; button: HTMLButtonElement): ClickResult = if button.form != nil: case button.ctype of btSubmit: let open = bc.submitForm(button.form, button) bc.setFocus(button) return initClickResult(open) of btReset: button.form.reset() of btButton: discard bc.setFocus(button) return initClickResult() proc click(bc: BufferContext; textarea: HTMLTextAreaElement): ClickResult = bc.setFocus(textarea) ClickResult(t: crtReadArea, value: textarea.value) proc click(bc: BufferContext; audio: HTMLAudioElement): ClickResult = bc.restoreFocus() let (src, contentType) = audio.getSrc() if src != "": if url := audio.document.parseURL(src): return initClickResult(newRequest(url), contentType) return initClickResult() proc click(bc: BufferContext; video: HTMLVideoElement): ClickResult = bc.restoreFocus() let (src, contentType) = video.getSrc() if src != "": if url := video.document.parseURL(src): return initClickResult(newRequest(url), contentType) return initClickResult() # Used for frame, ifframe proc clickFrame(bc: BufferContext; frame: Element): ClickResult = bc.restoreFocus() let src = frame.attr(satSrc) if src != "": if url := frame.document.parseURL(src): return initClickResult(newRequest(url)) return initClickResult() const InputTypePrompt = [ itText: "TEXT", itButton: "", itCheckbox: "", itColor: "Color", itDate: "Date", itDatetimeLocal: "Local date/time", itEmail: "E-Mail", itFile: "", itHidden: "", itImage: "Image", itMonth: "Month", itNumber: "Number", itPassword: "Password", itRadio: "Radio", itRange: "Range", itReset: "", itSearch: "Search", itSubmit: "", itTel: "Telephone number", itTime: "Time", itURL: "URL input", itWeek: "Week" ] proc click(bc: BufferContext; input: HTMLInputElement): ClickResult = bc.restoreFocus() case input.inputType of itFile: #TODO we should somehow extract the path name from the current file bc.setFocus(input) return ClickResult(t: crtReadFile) of itCheckbox: input.setChecked(not input.checked) if bc.config.scripting != smFalse: # Note: not an InputEvent. bc.window.fireEvent(satInput, input, bubbles = true, cancelable = true, trusted = true) bc.window.fireEvent(satChange, input, bubbles = true, cancelable = true, trusted = true) bc.maybeReshape() return initClickResult() of itRadio: let wasChecked = input.checked input.setChecked(true) if not wasChecked and bc.config.scripting != smFalse: # See above. bc.window.fireEvent(satInput, input, bubbles = true, cancelable = true, trusted = true) bc.window.fireEvent(satChange, input, bubbles = true, cancelable = true, trusted = true) bc.maybeReshape() return initClickResult() of itReset: if input.form != nil: input.form.reset() bc.maybeReshape() return initClickResult() of itSubmit, itButton: if input.form != nil: return initClickResult(bc.submitForm(input.form, input)) return initClickResult() else: # default is text. var prompt = InputTypePrompt[input.inputType] if input.inputType == itRange: prompt &= " (" & input.attr(satMin) & ".." & input.attr(satMax) & ")" bc.setFocus(input) if input.inputType == itPassword: return ClickResult( t: crtReadPassword, prompt: prompt & ": ", value: input.value ) return ClickResult( t: crtReadText, prompt: prompt & ": ", value: input.value ) proc click(bc: BufferContext; clickable: Element): ClickResult = case clickable.tagType of TAG_LABEL: return bc.click(HTMLLabelElement(clickable)) of TAG_SELECT: return bc.click(HTMLSelectElement(clickable)) of TAG_A: return bc.click(HTMLAnchorElement(clickable)) of TAG_OPTION: return bc.click(HTMLOptionElement(clickable)) of TAG_BUTTON: return bc.click(HTMLButtonElement(clickable)) of TAG_TEXTAREA: return bc.click(HTMLTextAreaElement(clickable)) of TAG_INPUT: return bc.click(HTMLInputElement(clickable)) of TAG_AUDIO: return bc.click(HTMLAudioElement(clickable)) of TAG_VIDEO: return bc.click(HTMLVideoElement(clickable)) of TAG_IFRAME, TAG_FRAME: return bc.clickFrame(clickable) else: bc.restoreFocus() return ClickResult() proc initMouseEventInit(bc: BufferContext; button: int16; buttons: uint16; x, y, detail: int): MouseEventInit = let x = if bc.config.scripting == smApp and x <= int32.high div bc.attrs.ppc: int32(x * bc.attrs.ppc) else: 0 let y = if bc.config.scripting == smApp and y <= int32.high div bc.attrs.ppl: int32(y * bc.attrs.ppl) else: 0 MouseEventInit( bubbles: true, cancelable: true, button: button, buttons: buttons, view: EventTargetWindow(bc.window), clientX: x, clientY: y, screenX: x, screenY: y, detail: int32(clamp(detail, 0, int32.high)) ) proc click(bc: BufferContext; handle: PagerHandle; cursorx, cursory, n: int): ClickResult {.proxy.} = if bc.lines.len <= cursory: return ClickResult() var canceled = false let clickable = bc.getCursorClickable(cursorx, cursory) if bc.config.scripting != smFalse: let element = bc.getCursorElement(cursorx, cursory) if element != nil: bc.clickResult = initClickResult() let window = bc.window let init = bc.initMouseEventInit(0, 0, cursorx, cursory, n) let event = newMouseEvent(satClick.toAtom(), init) event.isTrusted = true canceled = window.jsctx.dispatch(element, event) if n == 2: let init = bc.initMouseEventInit(0, 0, cursorx, cursory, n) let event = newMouseEvent(satDblclick.toAtom(), init) event.isTrusted = true discard window.jsctx.dispatch(element, event) bc.maybeReshape() if bc.clickResult.t != crtNone: return bc.clickResult let url = bc.navigateUrl bc.navigateUrl = nil if not canceled and clickable != nil: return bc.click(clickable) if url != nil: return initClickResult(newRequest(url, hmGet)) return initClickResult() proc click0(bc: RootRef; element: HTMLElement) = let bc = BufferContext(bc) #TODO not sure if this is the right behavior for app mode. # (for normal mode it's the right design, I think.) bc.clickResult = bc.click(element) proc contextMenu(bc: BufferContext; handle: PagerHandle; cursorx, cursory: int): bool {.proxy.} = var canceled = false if bc.config.scripting != smFalse: let element = bc.getCursorElement(cursorx, cursory) if element != nil: bc.clickResult = initClickResult() let window = bc.window let init = bc.initMouseEventInit(2, 2, cursorx, cursory, 1) let event = newMouseEvent(satContextmenu.toAtom(), init) event.isTrusted = true canceled = window.jsctx.dispatch(element, event) bc.maybeReshape() canceled proc select(bc: BufferContext; handle: PagerHandle; selected: int): ClickResult {.proxy.} = if bc.document.focus != nil and bc.document.focus of HTMLSelectElement: if selected != -1: let select = HTMLSelectElement(bc.document.focus) let index = select.selectedIndex if index != selected: select.setSelectedIndex(selected) if bc.config.scripting != smFalse: bc.window.fireEvent(satChange, select, bubbles = true, cancelable = true, trusted = true) bc.restoreFocus() bc.maybeReshape() return initClickResult() proc readCanceled(bc: BufferContext; handle: PagerHandle) {.proxy.} = bc.restoreFocus() # hack: avoid writing element in FormatCell by hand-rolling a serialization # function that matches SimpleFlexibleLine # (TODO: elements really don't belong in FormatCell...) proc swrite(w: var PacketWriter; x: FlexibleLine) = w.swrite(x.str) w.swrite(x.formats.len) for f in x.formats: w.swrite(f.format) w.swrite(f.pos) proc getLinesCmd(bc: BufferContext; handle: PagerHandle; r: var PacketReader; packetid: int): CommandResult = var slice: Slice[int] r.sread(slice) if slice.b < 0 or slice.b > bc.lines.high: slice.b = bc.lines.high handle.stream.withPacketWriterReturnEOF w: w.swrite(packetid) w.swrite(slice.a) # lineShift w.swrite(bc.lines.len) # numLines w.swrite(bc.bgcolor) # bgcolor w.swrite(slice.len) # lines.len for y in slice: # lines.data w.swrite(bc.lines[y]) var images: seq[PosBitmap] if bc.config.images: let ppl = bc.attrs.ppl for image in bc.images: let ey = image.y + (image.height + ppl - 1) div ppl # ceil if image.width > 0 and image.height > 0 and image.y <= slice.b and ey >= slice.a: images.add(image) w.swrite(images) # images cmdrDone proc getSelectionText(bc: BufferContext; handle: PagerHandle; sx, sy, ex, ey: int; t: SelectionType): string {.proxy.} = var s = "" let sy = max(sy, 0) let ey = min(bc.lines.high, ey) case t of stNormal: if sy == ey: let si = bc.lines[sy].str.findColBytes(sx) let ei = bc.lines[ey].str.findColBytes(ex + 1, sx, si) - 1 s = bc.lines[sy].str.toOpenArray(si, ei).expandPUATabsHard() else: let si = bc.lines[sy].str.findColBytes(sx) let ei = bc.lines[ey].str.findColBytes(ex + 1) - 1 s = bc.lines[sy].str.toOpenArray(si, bc.lines[sy].str.high) .expandPUATabsHard() & '\n' for y in sy + 1 .. ey - 1: s &= bc.lines[y].str.expandPUATabsHard() & '\n' s &= bc.lines[ey].str.toOpenArray(0, ei).expandPUATabsHard() of stBlock: for y in sy .. ey: let si = bc.lines[y].str.findColBytes(sx) let ei = bc.lines[y].str.findColBytes(ex + 1, sx, si) - 1 if y > sy: s &= '\n' s &= bc.lines[y].str.toOpenArray(si, ei).expandPUATabsHard() of stLine: for y in sy .. ey: if y > sy: s &= '\n' s &= bc.lines[y].str.expandPUATabsHard() move(s) proc getLinks(bc: BufferContext; handle: PagerHandle): seq[string] {.proxy.} = result = newSeq[string]() if bc.document != nil: for element in bc.window.displayedElements: if element.tagType == TAG_A and element.attrb(satHref): if url := HTMLAnchorElement(element).reinitURL(): result.add($url) else: result.add(element.attr(satHref)) proc onReshape(bc: BufferContext; handle: PagerHandle) {.proxy: pfTask.} = if handle.onReshapeImmediately: # We got a reshape before the container even asked us for the event. # This variable prevents the race that would otherwise occur if # the buffer were to be reshaped between two onReshape requests. handle.onReshapeImmediately = false return assert handle.tasks[bcOnReshape] == 0 bc.savetask = true proc markURL(bc: BufferContext; handle: PagerHandle) {.proxy.} = if bc.document == nil or bc.document.body == nil: return var buf = "(" for i, scheme in bc.schemes.mypairs: if i > 0: buf &= '|' buf &= scheme buf &= r"):(//[\w%:.-]+)?[\w/@%:.~-]*\??[\w%:~.=&-]*#?[\w:~.=-]*[\w/~=-]" var regex: Regex doAssert compileRegex(buf, {LRE_FLAG_GLOBAL}, regex) # Dummy element for the fragment parsing algorithm. We can't just use parent # there, because e.g. plaintext would not parse the text correctly. let html = bc.document.newHTMLElement(TAG_DIV) var stack = @[bc.document.body] while stack.len > 0: let element = stack.pop() var texts = newSeq[Text]() var lastText: Text = nil for node in element.safeChildList: if node of Text: let text = Text(node) if lastText != nil: lastText.data &= text.data.s text.remove() else: texts.add(text) lastText = text elif node of HTMLElement: let element = HTMLElement(node) if element.tagType in {TAG_NOBR, TAG_WBR}: element.remove() elif element.tagType notin {TAG_HEAD, TAG_SCRIPT, TAG_STYLE, TAG_A}: stack.add(element) lastText = nil else: lastText = nil else: lastText = nil for text in texts: var data = "" var j = 0 for cap in regex.matchCap(text.data.s, 0): let capLen = cap.e - cap.s while j < cap.s: case (let c = text.data[j]; c) of '<': data &= "&lt;" of '>': data &= "&gt;" of '\'': data &= "&apos;" of '"': data &= "&quot;" of '&': data &= "&amp;" else: data &= c inc j let s = text.data.s[j ..< j + capLen] let news = "<a href=\"" & s & "\">" & s.htmlEscape() & "</a>" data &= news j += capLen if data.len > 0: while j < text.data.len: case (let c = text.data[j]; c) of '<': data &= "&lt;" of '>': data &= "&gt;" of '\'': data &= "&apos;" of '"': data &= "&quot;" of '&': data &= "&amp;" else: data &= c inc j let replacement = html.fragmentParsingAlgorithm(data) discard element.replace(text, replacement) bc.maybeReshape() proc toggleImages(bc: BufferContext; handle: PagerHandle): bool {. proxy: pfTask.} = bc.config.images = not bc.config.images bc.window.settings.images = bc.config.images bc.window.svgCache.clear() for element in bc.document.descendants: if element of HTMLImageElement: bc.window.loadImage(HTMLImageElement(element)) elif element of SVGSVGElement: bc.window.loadSVG(SVGSVGElement(element)) bc.savetask = true if not bc.config.images: # if images were enabled, we reshape after imageLoaded bc.maybeReshape() return bc.config.images proc findLeaf(box: CSSBox; element: Element): CSSBox = for it in box.children: if it.element == element or it.element.parentNode == element and not it.element.isClickable(): let box = it.findLeaf(it.element) if box.computed{"visibility"} == VisibilityVisible and box of InlineTextBox: return box return box proc showHints(bc: BufferContext; handle: PagerHandle; sx, sy, ex, ey: int): HintResult {.proxy.} = result = @[] bc.maybeReshape() let ppc = bc.attrs.ppc.toLUnit() let ppl = bc.attrs.ppl.toLUnit() let so = offset(x = sx.toLUnit() * ppc, y = sy.toLUnit() * ppl) let eo = offset(x = ex.toLUnit() * ppc, y = ey.toLUnit() * ppl) for element in bc.window.displayedElements: if element.box != nil and element.isClickable(): let box = CSSBox(element.box).findLeaf(element) let offset = box.render.offset if offset >= so and offset < eo: result.add(CursorXY( x: (offset.x div ppc).toInt(), y: (offset.y div ppl).toInt() )) element.setHint(true) bc.nhints = result.len bc.maybeReshape() proc submitForm(bc: BufferContext; handle: PagerHandle; cursorx, cursory: int): ClickResult {.proxy.} = var element = bc.getCursorElement(cursorx, cursory) var form: HTMLFormElement = nil while element != nil: if element.tagType == TAG_FORM: form = HTMLFormElement(element) break if element of FormAssociatedElement: form = FormAssociatedElement(element).form break element = element.parentElement if form == nil: return ClickResult() let open = bc.submitForm(form, form) #TODO maybe use element as submitter? return initClickResult(open) proc hideHints(bc: BufferContext; handle: PagerHandle) {.proxy.} = for element in bc.window.document.elementDescendants: element.setHint(false) bc.maybeReshape() # Note: these functions are automatically generated by the .proxy macro. const ProxyMap = [ bcCancel: cancelCmd, bcCheckRefresh: checkRefreshCmd, bcClick: clickCmd, bcClone: cloneCmd, bcContextMenu: contextMenuCmd, bcFindNextLink: findNextLinkCmd, bcFindNextMatch: findNextMatchCmd, bcFindNextParagraph: findNextParagraphCmd, bcFindPrevLink: findPrevLinkCmd, bcFindPrevMatch: findPrevMatchCmd, bcFindRevNthLink: findRevNthLinkCmd, bcForceReshape: forceReshapeCmd, bcGetLines: getLinesCmd, bcGetLinks: getLinksCmd, bcGetSelectionText: getSelectionTextCmd, bcGetTitle: getTitleCmd, bcGotoAnchor: gotoAnchorCmd, bcHideHints: hideHintsCmd, bcLoad: loadCmd, bcMarkURL: markURLCmd, bcOnReshape: onReshapeCmd, bcReadCanceled: readCanceledCmd, bcReadSuccess: readSuccessCmd, bcSelect: selectCmd, bcShowHints: showHintsCmd, bcSubmitForm: submitFormCmd, bcToggleImages: toggleImagesCmd, bcUpdateHover: updateHoverCmd, bcWindowChange: windowChangeCmd, ] proc readCommand(bc: BufferContext; data: PagerHandle): CommandResult = var res = cmdrDone data.stream.withPacketReader r: var cmd: BufferCommand var packetid: int r.sread(cmd) r.sread(packetid) res = ProxyMap[cmd](bc, data, r, packetid) do: # EOF, pager died return cmdrEOF res proc handleRead(bc: BufferContext; fd: cint): bool = if fd in bc.loader.unregistered: discard # ignore (see pager handleError for explanation) elif (let data = bc.loader.get(fd); data != nil): if data of PagerHandle: let handle = PagerHandle(data) case bc.readCommand(handle) of cmdrDone: discard of cmdrEOF: if not bc.removePagerHandle(handle): return false elif data of InputData: bc.onload(InputData(data)) else: bc.loader.onRead(fd) bc.checkJobs = true else: assert false true proc handleError(bc: BufferContext; fd: cint): bool = if fd in bc.loader.unregistered: discard # ignore (see pager handleError for explanation) elif (let data = bc.loader.get(fd); data != nil): if data of InputData: bc.onload(InputData(data)) elif data of PagerHandle: if not bc.removePagerHandle(PagerHandle(data)): return false else: if not bc.loader.onError(fd): #TODO handle connection error assert false, $fd bc.checkJobs = true else: assert false, $fd true proc getPollTimeout(bc: BufferContext): cint = if bc.config.scripting != smFalse: return bc.window.timeouts.sortAndGetTimeout() return -1 proc runBuffer(bc: BufferContext) = var alive = true while alive: if bc.headlessLoading and not bc.headlessMustWait(): bc.headlessLoading = false for handle in bc.handles: bc.resolveLoad(handle, 0, 0) # already set to bsLoad let timeout = bc.getPollTimeout() bc.loader.pollData.poll(timeout) bc.loader.blockRegister() for fd, revents in bc.loader.pollData.events: let fd = fd if (revents and POLLIN) != 0: if not bc.handleRead(fd): alive = false break if (revents and POLLERR) != 0 or (revents and POLLHUP) != 0: if not bc.handleError(fd): alive = false break bc.loader.unregistered.setLen(0) bc.loader.unblockRegister() if bc.config.scripting != smFalse: if bc.window.timeouts.run(bc.window.console) or bc.checkJobs: bc.window.runJSJobs() bc.maybeReshape(suppressFouc = true) bc.checkJobs = false proc cleanup(bc: BufferContext) = #TODO loader map handles? bc.window.crypto.urandom.sclose() if bc.config.scripting != smFalse: let rt = JS_GetRuntime(bc.window.jsctx) bc.window.jsctx.free() rt.free() proc launchBuffer*(config: BufferConfig; url: URL; attrs: WindowAttributes; ishtml: bool; charsetStack: seq[Charset]; loader: FileLoader; pstream, istream, urandom: PosixStream; cacheId: int; contentType: string; linkHintChars: sink seq[uint32]; schemes: sink seq[string]) = let confidence = if config.charsetOverride == csUnknown: ccTentative else: ccCertain let bc = BufferContext( attrs: attrs, config: config, ishtml: ishtml, loader: loader, needsBOMSniff: config.charsetOverride == csUnknown, charsetStack: charsetStack, cacheId: cacheId, outputId: -1, luctx: LUContext(), schemes: schemes ) bc.linkHintChars = new(seq[uint32]) bc.linkHintChars[] = linkHintChars bc.window = newWindow( config.scripting, config.images, config.styling, config.autofocus, config.headless, addr bc.attrs, loader, url, urandom, config.imageTypes, config.userAgent, config.referrer, contentType ) bc.window.bc = bc bc.charset = bc.charsetStack.pop() istream.setBlocking(false) bc.loader.put(InputData(stream: istream)) bc.loader.pollData.register(istream.fd, POLLIN) bc.addPagerHandle(pstream) bc.initDecoder() bc.htmlParser = newHTML5ParserWrapper(bc.window, url, confidence, bc.charset) bc.document.applyUASheet() bc.document.applyUserSheet(bc.config.userStyle) bc.runBuffer() bc.cleanup() quit(0) # Forward declaration hack sheetLoadedImpl = sheetLoaded imageLoadedImpl = imageLoaded navigateImpl = navigate ensureLayoutImpl = ensureLayout clickImpl = click0 {.pop.} # raises: [] �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/server/bufferiface.nim������������������������������������������������������������0000664�0000000�0000000�00000154030�15202323131�0020200�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/posix import std/tables import encoding/charset import config/config import config/conftypes import config/cookie import config/mimetypes import css/render import io/dynstream import io/packetreader import io/packetwriter import io/poll import local/select import monoucha/fromjs import monoucha/jsbind import monoucha/jsutils import monoucha/libregexp import monoucha/quickjs import monoucha/tojs import server/headers import server/loaderiface import server/request import types/bitmap import types/blob import types/cell import types/color import types/jsopt import types/opt import types/referrer import types/refstring import types/url import types/winattrs import utils/lrewrap import utils/strwidth import utils/twtstr type BufferCommand* = enum bcCancel = "cancel" bcCheckRefresh = "checkRefresh" bcClick = "click" bcClone = "clone" bcContextMenu = "contextMenu" bcFindNextLink = "findNextLink" bcFindNextMatch = "findNextMatch" bcFindNextParagraph = "findNextParagraph" bcFindPrevLink = "findPrevLink" bcFindPrevMatch = "findPrevMatch" bcFindRevNthLink = "findRevNthLink" bcForceReshape = "forceReshape" bcGetLines = "getLines" bcGetLinks = "getLinks" bcGetSelectionText = "getSelectionText" bcGetTitle = "getTitle" bcGotoAnchor = "gotoAnchor" bcHideHints = "hideHints" bcLoad = "load" bcMarkURL = "markURL" bcOnReshape = "onReshape" bcReadCanceled = "readCanceled" bcReadSuccess = "readSuccess" bcSelect = "select" bcShowHints = "showHints" bcSubmitForm = "submitForm" bcToggleImages = "toggleImages" bcUpdateHover = "updateHover" bcWindowChange = "windowChange" HoverType* = enum htTitle, htLink, htImage, htCachedImage UpdateHoverResult* = seq[tuple[t: HoverType, s: string]] GetValueProc = proc(ctx: JSContext; iface: BufferInterface; r: var PacketReader): JSValue {.nimcall, raises: [].} BufferIfaceItem* = object id*: int fun: pointer get: GetValueProc HighlightType* = enum hltSearch, hltSelect Highlight* = ref object t* {.jsget.}: HighlightType selectionType* {.jsget.}: SelectionType mouse* {.jsget.}: bool x1*: int y1*: int x2* {.jsgetset.}: int y2* {.jsgetset.}: int CachedImageState* = enum cisLoading, cisCanceled, cisLoaded CachedImage* = ref object state*: CachedImageState width*: int height*: int data*: Blob # mmapped blob of image data cacheId*: int # cache id of the file backing "data" bmp*: NetworkBitmap # Following variables are always 0 in kitty mode; they exist to support # sixel cropping. # We can easily crop images where we just have to exclude some lines prior # to/after the image, but we must re-encode if # * offx > 0, dispw < width or # * offy % 6 != previous offy % 6 (currently only happens when cell height # is not a multiple of 6). offx*: int # same as CanvasImage.offx dispw*: int # same as CanvasImage.dispw erry*: int # same as CanvasImage.offy % 6 # whether the image has transparency, *disregarding the last row* transparent*: bool # length of introducer, raster, palette data before pixel data preludeLen*: int next: CachedImage ImageCache = object head: CachedImage tail: CachedImage BufferState* = enum bsLoadingPage = "loadingPage" bsLoadingStyle = "loadingStyle" bsLoadingImages = "loadingImages" bsLoaded = "loaded" LoadResult* = tuple n: uint64 len: uint64 bs: BufferState GotoAnchorResult* = object x*: int y*: int focus*: ClickResult PagePos* = tuple x: int y: int CursorXY* = object x*: int y*: int #TODO probably this should be PagePos instead HintResult* = seq[CursorXY] ClickResultType* = enum crtNone = "none" crtOpen = "open" crtReadText = "read-text" crtReadPassword = "read-password" crtReadArea = "read-area" crtReadFile = "read-file" crtSelect = "select" BufferMatch* = object x*: int y*: int w*: int ClickResult* = object case t*: ClickResultType of crtNone: discard of crtOpen: open*: Request contentType*: string of crtReadArea, crtReadText, crtReadPassword, crtReadFile: prompt*: string value*: string of crtSelect: options*: seq[SelectOption] selected*: int SelectionType* = enum stNormal = "normal" stBlock = "block" stLine = "line" ProcessHandle* = ref object process*: int refc*: int CursorState = object cursor: PagePos xend: int fromx: int fromy: int setx: int setxrefresh: bool setxsave: bool BufferConfig* = object refererFrom*: bool styling*: bool scripting*: ScriptingMode images*: bool headless*: HeadlessMode autofocus*: bool history*: bool markLinks*: bool charsetOverride*: Charset metaRefresh*: MetaRefresh charsets*: seq[Charset] imageTypes*: Table[string, string] userAgent*: string referrer*: string userStyle*: string BufferInitFlag* = enum bifSave bifHTML # buffer is parsed as HTML (applies for x-htmloutput too) bifHistory # buffer should be saved to history bifTailOnLoad # jump to the last line on the next load bifCrashed # buffer process no longer available bifHasStart # buffer has/had a starting position bifPendingStart # buffer will jump to the starting position when possible bifPartialStart # starting position was outside the screen on load, so we # jumped to the nearest possible line and are waiting # for the actual line to load bifRedirected bifMailcapCancel bifForceType # override type LoadState* = enum lsLoading = "loading" lsCanceled = "canceled" lsLoaded = "loaded" BufferConnectionResult* = enum bcrFail = "fail" bcrCancel = "cancel" bcrConnected = "connected" bcrSave = "save" bcrRedirect = "redirect" bcrUnauthorized = "unauthorized" bcrMailcap = "mailcap" Mark = object id: string pos: PagePos BufferInterface* = ref object of MapData map: seq[BufferIfaceItem] packetid: int loader: FileLoader packetBuffer: PacketBuffer partialReader: PartialPacketReader lines: SimpleFlexibleGrid lineShift: int numLines* {.jsget.}: int pos: CursorState highlights: seq[Highlight] images*: seq[PosBitmap] hoverText*: array[HoverType, string] phandle*: ProcessHandle imageCache: ImageCache attrsp: ptr WindowAttributes requestedLines: Slice[int] bgcolor*: CellColor lastPeek: HoverType registered: bool # registered for write (otherwise only for read) redraw*: bool refreshStatus*: bool dead* {.jsget.}: bool gotLines {.jsget.}: bool loadState* {.jsgetset.}: LoadState # private #TODO copy marks on clone tmpJumpMark: PagePos jumpMark: PagePos marks: seq[Mark] init*: BufferInit BufferInit* = ref object of MapData config*: BufferConfig loaderConfig*: LoaderClientConfig filterCmd*: string # filter command (called on load) startpos: CursorState title: string # if set, this *overrides* any content type received from the network. # (this is because it stores the content type from the -T flag.) # beware, this string may include content type attributes, if you want # to match it you'll have to use shortContentType. contentType* {.jsget.}: string shortContentType* {.jsget.}: string loadInfo* {.jsgetset.}: string request*: Request # source request # note: this is not the same as request.url (but should be synced # with buffer.url) url* {.jsget.}: URL # note: this is *not* the same as Buffer.cacheId. buffer has the cache ID of # the output, while iface holds that of the input. Thus pager can # re-interpret the original input, and buffer can rewind the (potentially # mailcap) output. cacheId* {.jsget.}: int redirectDepth {.jsget.}: int width* {.jsgetset.}: int height* {.jsgetset.}: int connectionState*: ConnectDataState flags*: set[BufferInitFlag] #TODO this is inaccurate, because charsetStack can desync charset*: Charset charsetStack*: seq[Charset] refreshUrl: URL refreshMillis: int connectedPtr: pointer # JSObject * # this really doesn't belong in here, but I don't want to expose # PosixStream to JS so instead I'll just smuggle it through init ostream*: PosixStream istreamOutputId*: int ostreamOutputId*: int jsDestructor(BufferInterface) jsDestructor(BufferInit) jsDestructor(Highlight) # Forward declarations proc queueDraw*(iface: BufferInterface) proc sendCursorPosition(iface: BufferInterface) proc requestLinesFast*(iface: BufferInterface; force = false) proc finalize(rt: JSRuntime; iface: BufferInterface) {.jsfin.} = iface.partialReader.r.closeFds() for it in iface.map: if it.fun != nil: JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, it.fun)) proc mark(rt: JSRuntime; iface: BufferInterface; markFunc: JS_MarkFunc) {.jsmark.} = for it in iface.map: if it.fun != nil: JS_MarkValue(rt, JS_MKPTR(JS_TAG_OBJECT, it.fun), markFunc) proc finalize(rt: JSRuntime; init: BufferInit) {.jsfin.} = if init.connectedPtr != nil: JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, init.connectedPtr)) proc mark(rt: JSRuntime; init: BufferInit; markFunc: JS_MarkFunc) {.jsmark.} = if init.connectedPtr != nil: JS_MarkValue(rt, JS_MKPTR(JS_TAG_OBJECT, init.connectedPtr), markFunc) # BufferInit proc newBufferInit*(config: BufferConfig; loaderConfig: LoaderClientConfig; url: URL; request: Request; attrs: WindowAttributes; title: string; redirectDepth: int; flags: set[BufferInitFlag]; contentType, filterCmd: string; charsetStack: seq[Charset]): BufferInit = let cacheId = if request.url.schemeType == stCache: parseInt32(request.url.pathname).get(-1) else: -1 let host = request.url.host let loadInfo = (if host != "": "Connecting to " & host else: "Loading " & $request.url) & "..." var flags = flags if contentType != "": flags.incl(bifForceType) BufferInit( config: config, loaderConfig: loaderConfig, title: title, url: url, cacheId: cacheId, redirectDepth: redirectDepth, flags: flags, contentType: contentType, shortContentType: contentType.untilLower(';'), width: attrs.width, height: attrs.height - 1, request: request, charsetStack: charsetStack, loadInfo: loadInfo, refreshMillis: -1, filterCmd: filterCmd, istreamOutputId: -1, ostreamOutputId: -1 ) proc newBufferInit*(url: URL; init: BufferInit): BufferInit {.jsctor.} = BufferInit( config: init.config, loaderConfig: init.loaderConfig, title: init.title, url: url, cacheId: init.cacheId, redirectDepth: init.redirectDepth, flags: init.flags, contentType: init.contentType, shortContentType: init.shortContentType, width: init.width, height: init.height, request: init.request, charsetStack: init.charsetStack, refreshMillis: -1, istreamOutputId: -1, ostreamOutputId: -1 ) proc copyCursorPos(ctx: JSContext; this: BufferInit; val: JSValueConst): Opt[void] {.jsfunc.} = var iface: BufferInterface if ctx.fromJS(val, iface).isOk: if bifPendingStart in iface.init.flags: this.startpos = iface.init.startpos else: this.startpos = iface.pos this.flags.incl(bifPendingStart) else: var init: BufferInit ?ctx.fromJS(val, init) this.startpos = init.startpos if bifPendingStart in init.flags: this.flags.incl(bifPendingStart) # set a separate flag, because startpos may be already used (and # therefore unset) by the time hasStart is checked this.flags.incl(bifHasStart) ok() proc hasStart(init: BufferInit): bool {.jsfget.} = bifHasStart in init.flags proc history(init: BufferInit): bool {.jsfget.} = bifHistory in init.flags proc scripting(init: BufferInit): ScriptingMode {.jsfget.} = init.config.scripting proc charsetOverride(ctx: JSContext; init: BufferInit): JSValue {.jsfget.} = let charset = init.config.charsetOverride if charset != csUnknown: return ctx.toJS(charset) return JS_NULL proc save(init: BufferInit): bool {.jsfget.} = bifSave in init.flags proc setSave(init: BufferInit; b: bool) {.jsfset: "save".} = if b: init.flags.incl(bifSave) else: init.flags.excl(bifSave) proc ishtml(init: BufferInit): bool {.jsfget.} = bifHTML in init.flags proc cookie(init: BufferInit): CookieMode {.jsfget.} = init.loaderConfig.cookieMode proc headless(init: BufferInit): HeadlessMode {.jsfget.} = init.config.headless proc metaRefresh(init: BufferInit): MetaRefresh {.jsfget.} = init.config.metaRefresh proc autofocus(init: BufferInit): bool {.jsfget.} = init.config.autofocus proc images(init: BufferInit): bool {.jsfget.} = init.config.images proc setImages(init: BufferInit; images: bool) {.jsfset: "images".} = init.config.images = images proc title*(init: BufferInit): string {.jsfget.} = if init.title != "": return init.title return init.url.serialize(excludepassword = true) proc setTitle(init: BufferInit; title: string) {.jsfset: "title".} = init.title = title proc connected*(ctx: JSContext; init: BufferInit; res: BufferConnectionResult; arg1: JSValue): JSValue = if init.connectedPtr == nil: JS_FreeValue(ctx, arg1) return JS_UNDEFINED let fun = JS_MKPTR(JS_TAG_OBJECT, init.connectedPtr) init.connectedPtr = nil let this = ctx.toJS(init) if JS_IsException(this): ctx.freeValues(fun, arg1) return JS_EXCEPTION let arg0 = ctx.toJS(res) if JS_IsException(arg0): ctx.freeValues(fun, this, arg1) return JS_EXCEPTION return ctx.callSinkThisFree(fun, this, arg0, arg1) proc setConnected(ctx: JSContext; init: BufferInit; connected: JSValueConst): JSValue {.jsfset: "connected".} = if not JS_IsFunction(ctx, connected): return JS_ThrowTypeError(ctx, "not a function") if init.connectedPtr != nil: return JS_ThrowTypeError(ctx, "connected is already set") let val = JS_DupValue(ctx, connected) init.connectedPtr = JS_VALUE_GET_PTR(val) return JS_DupValue(ctx, connected) proc closeMailcap*(init: BufferInit) {.jsfunc.} = if init.ostream != nil: init.ostream.sclose() init.ostream = nil init.istreamOutputId = -1 init.flags.incl(bifMailcapCancel) # Apply data received in response. # Note: pager must call this before checkMailcap. proc applyResponse*(init: BufferInit; response: Response; mimeTypes: MimeTypesTable) = # accept cookies let cookieJar = init.loaderConfig.cookieJar if cookieJar != nil: cookieJar.setCookie(response.headers.getAllNoComma("Set-Cookie"), response.url, init.loaderConfig.cookieMode == cmSave, http = true) # set referrer policy, if any if init.config.refererFrom: let referrerPolicy = response.getReferrerPolicy() init.loaderConfig.referrerPolicy = referrerPolicy.get(DefaultPolicy) else: init.loaderConfig.referrerPolicy = rpNoReferrer # setup content type; note that isSome means an override so we skip it if init.contentType == "": var contentType = response.getLongContentType("application/octet-stream") var shortContentType = contentType.untilLower(';') if shortContentType == "application/octet-stream": contentType = mimeTypes.guessContentType(init.url.pathname, "text/plain") shortContentType = contentType init.shortContentType = move(shortContentType) init.contentType = move(contentType) # setup charsets: # * override charset # * network charset # * default charset guesses # HTML may override the last two (but not the override charset). if init.config.charsetOverride != csUnknown: init.charsetStack = @[init.config.charsetOverride] elif (let charset = response.getCharset(csUnknown); charset != csUnknown): init.charsetStack = @[charset] else: init.charsetStack = @[] for charset in init.config.charsets.ritems: init.charsetStack.add(charset) if init.charsetStack.len == 0: init.charsetStack.add(DefaultCharset) init.charset = init.charsetStack[^1] let refresh = parseRefresh(response.headers.getFirst("Refresh"), init.url) init.refreshUrl = refresh.url init.refreshMillis = refresh.n # BufferInterface proc newBufferInterface*(stream: PosixStream; loader: FileLoader; phandle: ProcessHandle; attrsp: ptr WindowAttributes; init: BufferInit): BufferInterface = inc phandle.refc return BufferInterface( phandle: phandle, packetid: 1, # ids below 1 are invalid stream: stream, redraw: true, attrsp: attrsp, init: init, pos: CursorState(setx: -1), lastPeek: HoverType.high, packetBuffer: initPacketBuffer(), loader: loader ) proc newProcessHandle*(pid: int): ProcessHandle = ProcessHandle(process: pid) proc process*(iface: BufferInterface): int {.jsfget.} = return iface.phandle.process proc cursorx(iface: BufferInterface): int {.jsfget.} = return iface.pos.cursor.x proc cursory*(iface: BufferInterface): int {.jsfget.} = return iface.pos.cursor.y proc fromx*(iface: BufferInterface): int {.jsfget.} = return iface.pos.fromx proc fromy*(iface: BufferInterface): int {.jsfget.} = return iface.pos.fromy proc lineWindow(iface: BufferInterface): Slice[int] = let height = iface.init.height if iface.numLines == 0: # not loaded return 0 .. height * 5 let n = (height * 5) div 2 var x = iface.fromy - n + height div 2 var y = iface.fromy + n + height div 2 if y >= iface.numLines: x -= y - iface.numLines y = iface.numLines if x < 0: y += -x x = 0 return x .. y proc lastVisibleLine(iface: BufferInterface): int = min(iface.fromy + iface.init.height, iface.numLines) - 1 proc lineLoaded(iface: BufferInterface; y: int): bool = let dy = y - iface.lineShift return dy in 0 ..< iface.lines.len proc getLine(iface: BufferInterface; y: int): lent SimpleFlexibleLine = if iface.lineLoaded(y): return iface.lines[y - iface.lineShift] let line {.global.} = SimpleFlexibleLine() return line proc getLineStr(iface: BufferInterface; y: int): lent string = return iface.getLine(y).str #TODO following procs should probably be computed on setCursorX for # efficiency # Returns the X position of the first cell occupied by the character the cursor # currently points to. proc cursorFirstX(iface: BufferInterface): int {.jsfget.} = let y = iface.cursory if not iface.lineLoaded(y): return 0 let line = iface.getLineStr(y) var w = 0 var i = 0 let cc = iface.cursorx while i < line.len: let u = line.nextUTF8(i) let tw = u.width() if w + tw > cc: return w w += tw return w # Returns the X position of the last cell occupied by the character the cursor # currently points to. proc cursorLastX(iface: BufferInterface): int {.jsfget.} = let y = iface.cursory if not iface.lineLoaded(y): return 0 let line = iface.getLineStr(y) var w = 0 var i = 0 let cc = iface.cursorx while i < line.len and w <= cc: let u = line.nextUTF8(i) w += u.width() return max(w - 1, 0) # Last cell for tab, first cell for everything else (e.g. double width.) # This is needed because moving the cursor to the 2nd cell of a double # width character clears it on some terminals. proc cursorDispX(iface: BufferInterface): int = let y = iface.cursory if not iface.lineLoaded(y): return 0 let line = iface.getLineStr(y) if line.len == 0: return 0 var w = 0 var pw = 0 var i = 0 var u = 0u32 let cc = iface.cursorx while i < line.len and w <= cc: u = line.nextUTF8(i) pw = w w += u.width() if u == uint32('\t'): return max(w - 1, 0) return pw #TODO cache proc maxScreenWidth(iface: BufferInterface): int {.jsfunc.} = result = 0 for y in iface.fromy..iface.lastVisibleLine: result = max(iface.getLineStr(y).width(), result) proc currentLineWidth(iface: BufferInterface; s = 0; e = int.high): int {.jsfunc.} = let y = iface.cursory if not iface.lineLoaded(y): return 0 return iface.getLineStr(y).width(s, e) proc acursorx*(iface: BufferInterface): int {.jsfget.} = max(0, iface.cursorDispX() - iface.fromx) proc acursory*(iface: BufferInterface): int {.jsfget.} = iface.cursory - iface.fromy proc maxfromx(iface: BufferInterface): int = return max(iface.maxScreenWidth() - iface.init.width, 0) proc maxfromy(iface: BufferInterface): int = return max(iface.numLines - iface.init.height, 0) proc getHoverText*(iface: BufferInterface): string = for s in iface.hoverText: if s != "": return s "" proc hoverLink(iface: BufferInterface): lent string {.jsfget.} = iface.hoverText[htLink] proc hoverTitle(iface: BufferInterface): lent string {.jsfget.} = iface.hoverText[htTitle] proc hoverImage(iface: BufferInterface): lent string {.jsfget.} = iface.hoverText[htImage] proc hoverCachedImage(iface: BufferInterface): lent string {.jsfget.} = iface.hoverText[htCachedImage] proc clearHover*(iface: BufferInterface) = iface.lastPeek = HoverType.high proc getPeekCursorStr*(iface: BufferInterface): string = var p = iface.lastPeek while true: if p < HoverType.high: inc p else: p = HoverType.low if iface.hoverText[p] != "" or p == iface.lastPeek: break let s = iface.hoverText[p] iface.lastPeek = p s # Marks proc markPos0(iface: BufferInterface) {.jsfunc.} = iface.tmpJumpMark = (iface.cursorx, iface.cursory) proc markPos(iface: BufferInterface) {.jsfunc.} = let pos = iface.tmpJumpMark if iface.cursorx != pos.x or iface.cursory != pos.y: iface.jumpMark = pos proc findMark(iface: BufferInterface; id: string): int = for i, it in iface.marks.mypairs: if it.id == id: return i -1 proc setMark(iface: BufferInterface; id: string; x, y: int): bool {.jsfunc.} = let i = iface.findMark(id) if i != -1: iface.marks[i].pos = (x, y) else: iface.marks.add(Mark(id: id, pos: (x, y))) iface.queueDraw() i == -1 proc clearMark(iface: BufferInterface; id: string): bool {.jsfunc.} = let i = iface.findMark(id) if i != -1: iface.marks.del(i) iface.queueDraw() i != -1 proc getMarkPos(ctx: JSContext; iface: BufferInterface; id: string): JSValue {.jsfunc.} = if id == "`" or id == "'": return ctx.toJS(iface.jumpMark) let i = iface.findMark(id) if i != -1: return ctx.toJS(iface.marks[i].pos) return JS_NULL proc findNextMark(ctx: JSContext; iface: BufferInterface; x, y: int): JSValue {.jsfunc.} = var best: PagePos = (int.high, int.high) var j = -1 for i, mark in iface.marks.mypairs: if mark.pos.y < y or mark.pos.y == y and mark.pos.x <= x: continue if mark.pos.y < best.y or mark.pos.y == best.y and mark.pos.x < best.x: best = mark.pos j = i if j != -1: return ctx.toJS(iface.marks[j].id) return JS_NULL proc findPrevMark(ctx: JSContext; iface: BufferInterface; x, y: int): JSValue {.jsfunc.} = var best: PagePos = (-1, -1) var j = -1 for i, mark in iface.marks.mypairs: if mark.pos.y > y or mark.pos.y == y and mark.pos.x >= x: continue if mark.pos.y > best.y or mark.pos.y == best.y and mark.pos.x > best.x: best = mark.pos j = i if j != -1: return ctx.toJS(iface.marks[j].id) return JS_NULL proc setFromY(iface: BufferInterface; y: int) {.jsfunc.} = if iface.pos.fromy != y: iface.pos.fromy = max(min(y, iface.maxfromy), 0) iface.requestLinesFast() iface.queueDraw() proc setFromX(iface: BufferInterface; x: int; refresh = true) {.jsfunc.} = if iface.pos.fromx != x: iface.pos.fromx = max(min(x, iface.maxfromx), 0) if iface.pos.fromx > iface.cursorx: iface.pos.cursor.x = min(iface.pos.fromx, iface.currentLineWidth()) if refresh: iface.sendCursorPosition() iface.queueDraw() # Set the cursor to the xth column. 0-based. # * `refresh = false' inhibits reporting of the cursor position to the buffer. # * `save = false' inhibits cursor movement if it is currently outside the # screen, and makes it so cursorx is not saved for restoration on cursory # movement. proc setCursorX(iface: BufferInterface; x: int; refresh, save: bool) {.jsfunc.} = if not iface.lineLoaded(iface.cursory): iface.pos.setx = x iface.pos.setxrefresh = refresh iface.pos.setxsave = save return iface.pos.setx = -1 let cw = iface.currentLineWidth() let x2 = x let x = max(min(x, cw - 1), 0) # we check for save here, because it is only set by restoreCursorX where # we do not want to move the cursor just because it is outside the window. if not save or iface.fromx <= x and x < iface.fromx + iface.init.width: iface.pos.cursor.x = x elif save and iface.fromx > x: # target x is before the screen start if x2 < iface.cursorx: # desired X position is lower than cursor X; move screen back to the # desired position if valid, to 0 if the desired position is less than 0, # otherwise the last cell of the current line. if x2 <= x: iface.setFromX(x, false) else: iface.setFromX(cw - 1, false) # take whatever position the jump has resulted in. iface.pos.cursor.x = iface.fromx elif x > iface.cursorx: # target x is greater than current x; a simple case, just shift fromx too # accordingly iface.setFromX(max(x - iface.init.width + 1, iface.fromx), false) iface.pos.cursor.x = x if save: iface.pos.xend = iface.cursorx if refresh: iface.sendCursorPosition() proc setCursorY(iface: BufferInterface; y: int; refresh = true) {.jsfunc.} = let y = max(min(y, iface.numLines - 1), 0) if y >= iface.fromy and y - iface.init.height < iface.fromy: discard elif y > iface.cursory: iface.setFromY(y - iface.init.height + 1) else: iface.setFromY(y) if iface.cursory != y: iface.pos.cursor.y = y iface.setCursorX(iface.pos.xend, false, false) if refresh: iface.sendCursorPosition() # Send/receive packets const ClickResultReadLine* = {crtReadText, crtReadPassword, crtReadFile} proc initClickResult*(): ClickResult = ClickResult(t: crtNone) proc initClickResult*(open: Request; contentType = ""): ClickResult = if open == nil: return initClickResult() return ClickResult(t: crtOpen, open: open, contentType: contentType) proc initClickResult*(open: RawRequest; contentType = ""): ClickResult = return ClickResult( t: crtOpen, open: newRequest(open), contentType: contentType ) proc initClickResult*(options: seq[SelectOption]; selected: int): ClickResult = if options.len == 0: return initClickResult() return ClickResult(t: crtSelect, options: options, selected: selected) proc sread*(r: var PacketReader; x: var ClickResult) = var t0: ClickResultType r.sread(t0) let t = t0 case t of crtNone: x = initClickResult() of crtOpen: var open: RawRequest var contentType: string r.sread(open) r.sread(contentType) x = initClickResult(open, contentType) of crtReadArea, crtReadText, crtReadPassword, crtReadFile: var prompt: string var value: string r.sread(prompt) r.sread(value) x = ClickResult(t: t, prompt: prompt, value: value) of crtSelect: var options: seq[SelectOption] var selected: int r.sread(options) r.sread(selected) x = initClickResult(options, selected) proc swrite*(w: var PacketWriter; x: ClickResult) = w.swrite(x.t) case x.t of crtNone: discard of crtOpen: w.swrite(x.open) w.swrite(x.contentType) of crtReadArea, crtReadText, crtReadPassword, crtReadFile: w.swrite(x.prompt) w.swrite(x.value) of crtSelect: w.swrite(x.options) w.swrite(x.selected) proc toJS(ctx: JSContext; x: ClickResult): JSValue = if x.t == crtNone: return JS_NULL let obj = JS_NewObject(ctx) if JS_IsException(obj): return JS_EXCEPTION block good: if ctx.definePropertyConvert(obj, "t", x.t) == dprException: break good case x.t of crtNone: discard of crtOpen: let open = x.open if ctx.definePropertyConvert(obj, "open", open) == dprException: break good if ctx.definePropertyConvert(obj, "contentType", x.contentType) == dprException: break good of crtSelect: if ctx.definePropertyConvert(obj, "selected", x.selected) == dprException: break good if ctx.definePropertyConvert(obj, "options", x.options) == dprException: break good of crtReadText, crtReadPassword, crtReadArea, crtReadFile: if ctx.definePropertyConvert(obj, "prompt", x.prompt) == dprException: break good if ctx.definePropertyConvert(obj, "value", x.value) == dprException: break good return obj JS_FreeValue(ctx, obj) return JS_EXCEPTION proc toJS(ctx: JSContext; res: GotoAnchorResult): JSValue = var init = [JS_UNDEFINED, JS_UNDEFINED, JS_UNDEFINED] block good: init[0] = ctx.toJS(res.x) if JS_IsException(init[0]): break good init[1] = ctx.toJS(res.y) if JS_IsException(init[1]): break good init[2] = ctx.toJS(res.focus) if JS_IsException(init[2]): break good return ctx.newArrayFrom(init) ctx.freeValues(init) return JS_EXCEPTION proc toJS(ctx: JSContext; x: CursorXY): JSValue = let obj = JS_NewObject(ctx) if JS_IsException(obj): return JS_EXCEPTION block good: if ctx.definePropertyCWE(obj, "x", ctx.toJS(x.x)) == dprException: break good if ctx.definePropertyCWE(obj, "y", ctx.toJS(x.y)) == dprException: break good return obj JS_FreeValue(ctx, obj) return JS_EXCEPTION proc toJS(ctx: JSContext; match: BufferMatch): JSValue = var init = [JS_UNDEFINED, JS_UNDEFINED, JS_UNDEFINED] block good: init[0] = ctx.toJS(match.x) if JS_IsException(init[0]): break good init[1] = ctx.toJS(match.y) if JS_IsException(init[1]): break good init[2] = ctx.toJS(match.w) if JS_IsException(init[2]): break good return ctx.newArrayFrom(init) ctx.freeValues(init) return JS_EXCEPTION proc findPromise(iface: BufferInterface; id: int): int = for i, it in iface.map.mypairs: if it.id == id: return i return -1 type IfaceResult* = enum irOk, irException, irEOF # Returns false on I/O error, err on JS error. proc handleCommand*(ctx: JSContext; iface: BufferInterface): IfaceResult = assert not iface.dead case iface.stream.initPartialReader(iface.partialReader) of prcDone: var packetid: int iface.partialReader.r.sread(packetid) let i = iface.findPromise(packetid) var res = irOk if i != -1: let it = iface.map[i] let val = if it.get == nil: JS_UNDEFINED else: it.get(ctx, iface, iface.partialReader.r) if not JS_IsException(val) and it.fun != nil: let fun = JS_MKPTR(JS_TAG_OBJECT, it.fun) let ret = ctx.callSinkFree(fun, JS_UNDEFINED, val) if JS_IsException(ret): res = irException JS_FreeValue(ctx, ret) else: if it.fun != nil: JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, it.fun)) res = irException iface.map.del(i) of prcEOF: return irEOF of prcBuffer: discard irOk proc flushWrite*(iface: BufferInterface): bool = case iface.packetBuffer.flush(iface.stream) of frDone: iface.loader.pollData.unregister(iface.stream.fd) iface.loader.pollData.register(iface.stream.fd, POLLIN) iface.registered = false of frBuffer: discard of frEOF: return false true proc hasPromises(iface: BufferInterface): bool = return iface.map.len > 0 proc getFromStream[T](ctx: JSContext; iface: BufferInterface; r: var PacketReader): JSValue = var res: T r.sread(res) return ctx.toJS(res) proc addPromise(ctx: JSContext; iface: BufferInterface; get: GetValueProc): JSValue = var funs {.noinit.}: array[2, JSValue] let res = ctx.newPromiseCapability(funs) if JS_IsException(res): return res JS_FreeValue(ctx, funs[1]) iface.map.add(BufferIfaceItem( id: iface.packetid, fun: JS_VALUE_GET_PTR(funs[0]), get: get )) inc iface.packetid return res proc addPromise(iface: BufferInterface; get: GetValueProc) = iface.map.add(BufferIfaceItem( id: iface.packetid, fun: nil, get: get )) inc iface.packetid proc addPromise[T](ctx: JSContext; iface: BufferInterface): JSValue = return ctx.addPromise(iface, getFromStream[T]) proc addEmptyPromise(ctx: JSContext; iface: BufferInterface): JSValue = return ctx.addPromise(iface, nil) iterator ilines(iface: BufferInterface; slice: Slice[int]): lent SimpleFlexibleLine {.inline.} = for y in slice: yield iface.getLine(y) proc findColStartByte(s: string; endx: int): int = var w = 0 var i = 0 while i < s.len and w < endx: let pi = i let u = s.nextUTF8(i) w += u.width() if w > endx: return pi return i proc cursorStartByte(iface: BufferInterface; y, cc: int): int = return iface.getLineStr(y).findColStartByte(cc) proc findColBytes*(s: string; endx: int; startx = 0; starti = 0): int = var w = startx var i = starti while i < s.len and w < endx: let u = s.nextUTF8(i) w += u.width() return i proc cursorBytes(iface: BufferInterface; y, cc: int): int {.jsfunc.} = return iface.getLineStr(y).findColBytes(cc, 0, 0) proc atPercentOf*(iface: BufferInterface): int = if iface.numLines == 0: return 100 return (100 * (iface.cursory + 1)) div iface.numLines proc initPacketWriter(iface: BufferInterface; cmd: BufferCommand): PacketWriter = result = initPacketWriter() result.swrite(cmd) result.swrite(iface.packetid) proc flush(iface: BufferInterface; w: var PacketWriter): bool = if iface.dead: return false case iface.packetBuffer.flush(w, iface.stream) of frEOF: return false of frBuffer: iface.loader.pollData.unregister(iface.stream.fd) iface.loader.pollData.register(iface.stream.fd, POLLIN or POLLOUT) of frDone: discard true proc flush(ctx: JSContext; iface: BufferInterface; w: var PacketWriter): bool = if not iface.flush(w): JS_ThrowTypeError(ctx, "buffer %d disconnected", cint(iface.phandle.process)) return false return true template withPacketWriter(ctx: JSContext; iface: BufferInterface; cmd: BufferCommand; w, body: untyped) = var w = iface.initPacketWriter(cmd) body if not flush(ctx, iface, w): return JS_EXCEPTION template withPacketWriter(iface: BufferInterface; cmd: BufferCommand; w, body, fallback: untyped) = var w = iface.initPacketWriter(cmd) body if not iface.flush(w): fallback template withPacketWriterSync(iface: BufferInterface; cmd: BufferCommand; w, body, fallback: untyped) = var w = iface.initPacketWriter(cmd) body if iface.dead or not w.flush(iface.stream): fallback proc cancel*(iface: BufferInterface) {.jsfunc.} = iface.withPacketWriter bcCancel, w: discard do: return iface.addPromise(nil) proc checkRefresh(ctx: JSContext; iface: BufferInterface): JSValue {.jsfunc.} = let refreshMillis = iface.init.refreshMillis if refreshMillis >= 0: iface.init.refreshMillis = -1 return ctx.toJS((n: refreshMillis, url: move(iface.init.refreshUrl))) ctx.withPacketWriter iface, bcCheckRefresh, w: discard return addPromise[CheckRefreshResult](ctx, iface) proc click(ctx: JSContext; iface: BufferInterface; x, y, n: int): JSValue {. jsfunc.} = ctx.withPacketWriter iface, bcClick, w: w.swrite(x) w.swrite(y) w.swrite(n) return addPromise[ClickResult](ctx, iface) proc clone*(iface: BufferInterface; newurl: URL; pstreamFd: cint): Opt[void] = iface.withPacketWriter bcClone, w: w.swrite(newurl) w.sendFd(pstreamFd) do: return err() iface.addPromise(nil) ok() proc contextMenu(ctx: JSContext; iface: BufferInterface; cursorx, cursory: int): JSValue {.jsfunc.} = ctx.withPacketWriter iface, bcContextMenu, w: w.swrite(cursorx) w.swrite(cursory) return addPromise[bool](ctx, iface) proc findNextLink(ctx: JSContext; iface: BufferInterface; x, y, n: int): JSValue {.jsfunc.} = ctx.withPacketWriter iface, bcFindNextLink, w: w.swrite(x) w.swrite(y) w.swrite(n) return addPromise[PagePos](ctx, iface) proc findNextMatch(ctx: JSContext; iface: BufferInterface; re: JSValueConst; x, y: int; wrap: bool; n: int): JSValue {.jsfunc.} = var bytecodeLen: cint let p = JS_GetRegExpBytecode(ctx, re, bytecodeLen) if p == nil: return JS_EXCEPTION let bytecode = cast[REBytecode](p) var wrap = wrap let endy = y var y = y var n = n var b = iface.cursorBytes(y, x + 1) var first = true while true: if y >= iface.numLines: if not wrap: break wrap = false y = 0 if not iface.lineLoaded(y): let regex = bytecodeToRegex(bytecode, bytecodeLen) ctx.withPacketWriter iface, bcFindNextMatch, w: w.swrite(regex) w.swrite(x) w.swrite(y) w.swrite(endy) w.swrite(wrap) w.swrite(n) return addPromise[BufferMatch](ctx, iface) let s = iface.getLineStr(y) let cap = bytecode.matchFirst(s, b) if cap.s >= 0: let x = s.width(0, cap.s) let w = s.toOpenArray(cap.s, cap.e - 1).width() dec n if n == 0: return ctx.toJS(BufferMatch(x: x, y: y, w: w)) b = 0 if y == endy and not first: break first = false inc y return ctx.toJS(BufferMatch(x: -1, y: -1)) proc findNextParagraph(ctx: JSContext; iface: BufferInterface; y, n: int): JSValue {.jsfunc.} = ctx.withPacketWriter iface, bcFindNextParagraph, w: w.swrite(y) w.swrite(n) return addPromise[int](ctx, iface) #TODO findPrevLink & findRevNthLink should probably be merged into findNextLink proc findPrevLink(ctx: JSContext; iface: BufferInterface; x, y, n: int): JSValue {.jsfunc.} = ctx.withPacketWriter iface, bcFindPrevLink, w: w.swrite(x) w.swrite(y) w.swrite(n) return addPromise[PagePos](ctx, iface) proc findPrevMatch(ctx: JSContext; iface: BufferInterface; re: JSValueConst; x, y: int; wrap: bool; n: int): JSValue {.jsfunc.} = var bytecodeLen: cint let p = JS_GetRegExpBytecode(ctx, re, bytecodeLen) if p == nil: return JS_EXCEPTION let bytecode = cast[REBytecode](p) var wrap = wrap let endy = y var n = n var y = y var b = iface.cursorStartByte(y, x) var first = true while true: if y < 0: if not wrap: break y = iface.numLines - 1 wrap = false if not iface.lineLoaded(y): let regex = bytecodeToRegex(bytecode, bytecodeLen) ctx.withPacketWriter iface, bcFindPrevMatch, w: w.swrite(regex) w.swrite(x) w.swrite(y) w.swrite(endy) w.swrite(wrap) w.swrite(n) return addPromise[BufferMatch](ctx, iface) let s = iface.getLineStr(y) if b < 0: b = s.len let cap = bytecode.matchLast(s.toOpenArray(0, b - 1)) if cap.s >= 0: let x = s.width(0, cap.s) let w = s.toOpenArray(cap.s, cap.e - 1).width() dec n if n == 0: return ctx.toJS(BufferMatch(x: x, y: y, w: w)) dec y if y == endy and not first: break first = false b = -1 return ctx.toJS(BufferMatch(x: -1, y: -1)) proc findRevNthLink(ctx: JSContext; iface: BufferInterface; x, y, n: int): JSValue {.jsfunc.} = ctx.withPacketWriter iface, bcFindPrevLink, w: w.swrite(x) w.swrite(y) w.swrite(n) return addPromise[PagePos](ctx, iface) proc forceReshape(ctx: JSContext; iface: BufferInterface): JSValue {.jsfunc.} = ctx.withPacketWriter iface, bcForceReshape, w: discard return addEmptyPromise(ctx, iface) proc getLinesFromStream(ctx: JSContext; iface: BufferInterface; r: var PacketReader): JSValue = iface.gotLines = true let oldBgcolor = iface.bgcolor let oldNumLines = iface.numLines r.sread(iface.lineShift) r.sread(iface.numLines) r.sread(iface.bgcolor) r.sread(iface.lines) r.sread(iface.images) if iface.pos.setx >= 0: iface.setCursorX(iface.pos.setx, iface.pos.setxrefresh, iface.pos.setxsave) if oldNumLines != iface.numLines: if iface.fromy > iface.maxfromy: iface.setFromY(iface.maxfromy) if iface.cursory >= iface.numLines: let n = max(iface.lastVisibleLine, 0) if iface.cursory != n: iface.setCursorY(n) iface.refreshStatus = true if bifPendingStart in iface.init.flags and iface.numLines >= iface.init.startpos.cursor.y: iface.pos = iface.init.startpos iface.init.flags.excl(bifPendingStart) iface.requestLinesFast() iface.sendCursorPosition() if iface.loadState != lsLoading: if bifPendingStart in iface.init.flags and bifPartialStart notin iface.init.flags: # try to scroll to the nearest position to the original iface.setCursorY(iface.init.startpos.cursor.y) iface.setCursorX(iface.init.startpos.cursor.x, true, true) iface.init.flags.incl(bifPartialStart) iface.refreshStatus = true if bifTailOnLoad in iface.init.flags: iface.setCursorY(int.high) iface.refreshStatus = true iface.init.flags.excl(bifTailOnLoad) let slice = iface.lineShift ..< iface.lineShift + iface.lines.len if slice.b >= iface.fromy and slice.a <= iface.fromy + iface.init.height or oldBgcolor != iface.bgcolor: iface.queueDraw() return JS_UNDEFINED proc requestLinesFast*(iface: BufferInterface; force = false) = let slice = iface.lineWindow if not force and iface.requestedLines == slice: return iface.requestedLines = slice iface.withPacketWriter bcGetLines, w: w.swrite(slice) do: return iface.addPromise(getLinesFromStream) proc requestLines(ctx: JSContext; iface: BufferInterface; force = false): JSValue {.jsfunc.} = let slice = iface.lineWindow if not force and iface.requestedLines == slice: return JS_UNDEFINED iface.requestedLines = slice ctx.withPacketWriter iface, bcGetLines, w: w.swrite(slice) return ctx.addPromise(iface, getLinesFromStream) # dump mode type HandleReadLine = proc(line: SimpleFlexibleLine): Opt[void] # Synchronously read all lines in the buffer. proc requestLinesSync*(ctx: JSContext; iface: BufferInterface; handle: HandleReadLine): IfaceResult = if iface.dead: return irEOF iface.stream.setBlocking(true) while iface.hasPromises: # fulfill all promises let res = ctx.handleCommand(iface) if res != irOk: return res var slice = 0 .. 23 while true: let packetid = iface.packetid iface.withPacketWriterSync bcGetLines, w: w.swrite(slice) do: return irEOF inc iface.packetid iface.stream.withPacketReader r: var packetid2: int r.sread(packetid2) assert packetid == packetid2 r.sread(iface.lineShift) r.sread(iface.numLines) r.sread(iface.bgcolor) r.sread(iface.lines) r.sread(iface.images) do: return irEOF for line in iface.lines: if handle(line).isErr: return irEOF if iface.numLines <= slice.b: break slice.a += 24 slice.b += 24 if iface.init.config.markLinks: # avoid coloring link markers iface.bgcolor = defaultColor if handle(SimpleFlexibleLine()).isErr: return irEOF let packetid = iface.packetid iface.withPacketWriterSync bcGetLinks, w: discard do: return irEOF inc iface.packetid var links: seq[string] iface.stream.withPacketReaderFire r: var packetid2: int r.sread(packetid2) assert packetid == packetid2 r.sread(links) for i, link in links.mypairs: var s = "[" & $(i + 1) & "] " & link if handle(SimpleFlexibleLine(str: move(s))).isErr: return irEOF irOk proc getSelectionText(ctx: JSContext; iface: BufferInterface; sx, sy, ex, ey: int; t: SelectionType): JSValue {.jsfunc.} = ctx.withPacketWriter iface, bcGetSelectionText, w: w.swrite(sx) w.swrite(sy) w.swrite(ex) w.swrite(ey) w.swrite(t) return addPromise[string](ctx, iface) proc getTitle(ctx: JSContext; iface: BufferInterface): JSValue {.jsfunc.} = ctx.withPacketWriter iface, bcGetTitle, w: discard return addPromise[string](ctx, iface) proc gotoAnchor(ctx: JSContext; iface: BufferInterface; anchor: string; autofocus, target: bool): JSValue {.jsfunc.} = ctx.withPacketWriter iface, bcGotoAnchor, w: w.swrite(anchor) w.swrite(autofocus) w.swrite(target) return addPromise[GotoAnchorResult](ctx, iface) proc hideHints(ctx: JSContext; iface: BufferInterface): JSValue {.jsfunc.} = ctx.withPacketWriter iface, bcHideHints, w: discard return addEmptyPromise(ctx, iface) proc load(ctx: JSContext; iface: BufferInterface): JSValue {.jsfunc.} = ctx.withPacketWriter iface, bcLoad, w: discard return addPromise[LoadResult](ctx, iface) proc markURL(ctx: JSContext; iface: BufferInterface): JSValue {.jsfunc.} = ctx.withPacketWriter iface, bcMarkURL, w: discard return addEmptyPromise(ctx, iface) proc onReshape(ctx: JSContext; iface: BufferInterface): JSValue {.jsfunc.} = ctx.withPacketWriter iface, bcOnReshape, w: discard return addEmptyPromise(ctx, iface) proc readCanceled(ctx: JSContext; iface: BufferInterface): JSValue {.jsfunc.} = ctx.withPacketWriter iface, bcReadCanceled, w: discard return addEmptyPromise(ctx, iface) proc readSuccess(ctx: JSContext; iface: BufferInterface; s: string; fd: cint): JSValue {.jsfunc.} = ctx.withPacketWriter iface, bcReadSuccess, w: w.swrite(s) let hasfd = fd != -1 w.swrite(hasfd) if hasfd: w.sendFd(fd) return addPromise[ClickResult](ctx, iface) proc select(ctx: JSContext; iface: BufferInterface; selected: int): JSValue {.jsfunc.} = ctx.withPacketWriter iface, bcSelect, w: w.swrite(selected) return addPromise[ClickResult](ctx, iface) proc showHints(ctx: JSContext; iface: BufferInterface; sx, sy, ex, ey: int): JSValue {.jsfunc.} = ctx.withPacketWriter iface, bcShowHints, w: w.swrite(sx) w.swrite(sy) w.swrite(ex) w.swrite(ey) return addPromise[HintResult](ctx, iface) proc submitForm(ctx: JSContext; iface: BufferInterface; x, y: int): JSValue {. jsfunc.} = ctx.withPacketWriter iface, bcSubmitForm, w: w.swrite(x) w.swrite(y) return addPromise[ClickResult](ctx, iface) proc toggleImages(ctx: JSContext; iface: BufferInterface): JSValue {.jsfunc.} = ctx.withPacketWriter iface, bcToggleImages, w: discard return addPromise[bool](ctx, iface) proc updateHoverFromStream(ctx: JSContext; iface: BufferInterface; r: var PacketReader): JSValue = var res: UpdateHoverResult r.sread(res) if res.len > 0: assert res.high <= int(HoverType.high) for (ht, s) in res: iface.hoverText[ht] = s iface.refreshStatus = true return JS_UNDEFINED proc sendCursorPosition(iface: BufferInterface) {.jsfunc.} = iface.withPacketWriter bcUpdateHover, w: w.swrite(iface.cursorx) w.swrite(iface.cursory) do: return iface.addPromise(updateHoverFromStream) proc windowChange(ctx: JSContext; iface: BufferInterface; x, y: int): JSValue {.jsfunc.} = var attrs = iface.attrsp[] # subtract status line height attrs.height -= 1 attrs.heightPx -= attrs.ppl ctx.withPacketWriter iface, bcWindowChange, w: w.swrite(attrs) w.swrite(x) w.swrite(y) return addPromise[PagePos](ctx, iface) proc matchFirst(ctx: JSContext; iface: BufferInterface; re: JSValueConst; y: int): JSValue {.jsfunc.} = if not iface.lineLoaded(y): return ctx.toJS((-1, -1)) var plen: cint let p = JS_GetRegExpBytecode(ctx, re, plen) if p == nil: return JS_EXCEPTION return ctx.toJS(cast[REBytecode](p).matchFirst(iface.getLineStr(y))) # Highlight (search/selection) proc startx(hl: Highlight): int {.jsfget.} = if hl.y1 < hl.y2: hl.x1 elif hl.y2 < hl.y1: hl.x2 else: min(hl.x1, hl.x2) proc starty(hl: Highlight): int {.jsfget.} = return min(hl.y1, hl.y2) proc endx(hl: Highlight): int {.jsfget.} = if hl.y1 > hl.y2: hl.x1 elif hl.y2 > hl.y1: hl.x2 else: max(hl.x1, hl.x2) proc endy(hl: Highlight): int {.jsfget.} = return max(hl.y1, hl.y2) proc clearSearchHighlights(iface: BufferInterface) {.jsfunc.} = for i in countdown(iface.highlights.high, 0): if iface.highlights[i].t == hltSearch: iface.highlights.del(i) iface.queueDraw() proc addSearchHighlight(iface: BufferInterface; x1, y1, x2, y2: int) {. jsfunc.} = iface.highlights.add(Highlight( t: hltSearch, x1: x1, y1: y1, x2: x2, y2: y2 )) iface.queueDraw() proc startSelection(iface: BufferInterface; t: SelectionType; mouse: bool; x1, y1, x2, y2: int): Highlight {.jsfunc.} = let highlight = Highlight( t: hltSelect, selectionType: t, x1: x1, y1: y1, x2: x2, y2: y2, mouse: mouse ) iface.highlights.add(highlight) iface.queueDraw() return highlight proc removeHighlight(iface: BufferInterface; highlight: Highlight) {.jsfunc.} = let i = iface.highlights.find(highlight) if i != -1: iface.highlights.delete(i) iface.queueDraw() # Image iterator cachedImages(iface: BufferInterface): CachedImage = var it = iface.imageCache.head while it != nil: yield it it = it.next proc findCachedImage*(iface: BufferInterface; imageId, width, height, offx, erry, dispw: int): CachedImage = for it in iface.cachedImages: if it.bmp.imageId == imageId and it.width == width and it.height == height and it.offx == offx and it.erry == erry and it.dispw == dispw: return it return nil proc clearCachedImages*(iface: BufferInterface; loader: FileLoader) = for cachedImage in iface.cachedImages: if cachedImage.state == cisLoaded: loader.removeCachedItem(cachedImage.cacheId) cachedImage.state = cisCanceled iface.imageCache.head = nil iface.imageCache.tail = nil proc addCachedImage*(iface: BufferInterface; image: CachedImage) = if iface.imageCache.tail == nil: iface.imageCache.head = image else: iface.imageCache.tail.next = image iface.imageCache.tail = image # Display proc queueDraw*(iface: BufferInterface) {.jsfunc.} = iface.redraw = true proc colorNormal(iface: BufferInterface; hl: Highlight; y: int; limitx: Slice[int]): Slice[int] = let starty = hl.starty let endy = hl.endy if y in starty + 1 .. endy - 1: let w = iface.getLineStr(y).width() return min(limitx.a, w) .. min(limitx.b, w) if y == starty and y == endy: return max(hl.startx, limitx.a) .. min(hl.endx, limitx.b) if y == starty: let w = iface.getLineStr(y).width() return max(hl.startx, limitx.a) .. min(limitx.b, w) if y == endy: let w = iface.getLineStr(y).width() return min(limitx.a, w) .. min(hl.endx, limitx.b) 0 .. 0 proc colorArea(iface: BufferInterface; hl: Highlight; y: int; limitx: Slice[int]): Slice[int] = case hl.selectionType of stNormal: return iface.colorNormal(hl, y, limitx) of stBlock: if y in hl.starty .. hl.endy: return max(hl.startx, limitx.a) .. min(hl.endx, limitx.b) return 0 .. 0 of stLine: if y in hl.starty .. hl.endy: let w = iface.getLineStr(y).width() return min(limitx.a, w) .. min(limitx.b, w) return 0 .. 0 proc highlightMarks*(iface: BufferInterface; display: var FixedGrid; hlcolor: CellColor) = for mark in iface.marks: if mark.pos.x in iface.fromx ..< iface.fromx + display.width and mark.pos.y in iface.fromy ..< iface.fromy + display.height: let x = mark.pos.x - iface.fromx let y = mark.pos.y - iface.fromy let n = y * display.width + x if hlcolor != defaultColor: display[n].format.bgcolor = hlcolor else: display[n].format.incl(ffReverse) proc setFormat(cell: var FixedCell; cf: SimpleFormatCell; bgcolor: CellColor) = cell.format = cf.format if bgcolor != defaultColor and cell.format.bgcolor == defaultColor: cell.format.bgcolor = bgcolor proc setText(cell: var FixedCell; u: uint32; i, pi, uw: int; s: string) = if u.isControlChar(): cell.str = u.controlToVisual() elif u in TabPUARange: cell.str = ' '.repeat(uw) else: cell.str = s.substr(pi, i - 1) proc drawLines*(iface: BufferInterface; display: var FixedGrid; hlcolor: CellColor) = let bgcolor = iface.bgcolor var by = 0 let endy = min(iface.pos.fromy + display.height, iface.numLines) let maxw = iface.pos.fromx + display.width for line in iface.ilines(iface.pos.fromy ..< endy): var w = 0 # width of the row so far var i = 0 # byte in line.str # Skip cells till fromx. while w < iface.pos.fromx and i < line.str.len: let u = line.str.nextUTF8(i) w += u.width() let dls = by * display.width # starting position of row in display # Fill in the gap in case we skipped more cells than fromx mandates (i.e. # we encountered a double-width character.) var cf = line.findFormat(w) var nf = line.findNextFormat(w) var k = 0 while k < w - iface.pos.fromx: display[dls + k] = FixedCell(str: " ") display[dls + k].setFormat(cf, bgcolor) inc k let startw = w # save this for later # Now fill in the visible part of the row. while i < line.str.len: let pw = w let pi = i let u = line.str.nextUTF8(i) let uw = u.width() w += uw if w > maxw: break if nf.pos != -1 and nf.pos <= pw: cf = nf nf = line.findNextFormat(pw) display[dls + k].setText(u, i, pi, uw, line.str) display[dls + k].setFormat(cf, bgcolor) inc k for i in 1 ..< uw: display[dls + k] = FixedCell() inc k if bgcolor != defaultColor: # Fill the screen if bgcolor is not default. let format = initFormat(bgcolor, defaultColor, {}) for cell in display.mline(by, k): cell = FixedCell(str: " ", format: format) else: for cell in display.mline(by, k): cell = FixedCell() # Finally, override cell formatting for highlighted cells. let aw = display.width - (startw - iface.pos.fromx) # actual width let y = iface.pos.fromy + by for hl in iface.highlights: if y notin hl.starty .. hl.endy: continue let area = iface.colorArea(hl, iface.pos.fromy + by, startw .. startw + aw) for i in area: if i - startw >= display.width: break let n = dls + i - startw if hlcolor != defaultColor: display[n].format.bgcolor = hlcolor else: display[n].format.incl(ffReverse) inc by for y in by ..< display.height: # clear the rest for cell in display.mline(y): cell = FixedCell() proc addBufferInterfaceModule*(ctx: JSContext): Opt[void] = ?ctx.registerType(BufferInterface) ?ctx.registerType(BufferInit) ?ctx.registerType(Highlight) ok() {.pop.} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/server/connectionerror.nim��������������������������������������������������������0000664�0000000�0000000�00000005552�15202323131�0021154�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������type ConnectionError* = enum ceLoaderGone = -19 ceCookieStreamExists = -18 ceCGICachedBodyUnavailable = -17 ceCGIOutputHandleNotFound = -16 ceCGIFailedToOpenCacheOutput = -15 ceCGICachedBodyNotFound = -14 ceFailedToRedirect = -13 ceURLNotInCache = -12 ceFileNotInCache = -11 ceFailedToExecuteCGIScript = -10 ceCGIMalformedHeader = -9 ceCGIInvalidChaControl = -8 ceTooManyRewrites = -7 ceInvalidURIMethodEntry = -6 ceCGIFileNotFound = -5 ceInvalidCGIPath = -4 ceFailedToSetUpCGI = -3 ceDisallowedURL = -2 ceUnknownScheme = -1 ceNone = 0 ceInternalError = (1, "InternalError") ceInvalidMethod = (2, "InvalidMethod") ceInvalidURL = (3, "InvalidURL") ceFileNotFound = (4, "FileNotFound") ceConnectionRefused = (5, "ConnectionRefused") ceProxyRefusedToConnect = (6, "ProxyRefusedToConnect") ceFailedToResolveHost = (7, "FailedToResolveHost") ceFailedToResolveProxy = (8, "FailedToResolveProxy") ceProxyAuthFail = (9, "ProxyAuthFail") ceInvalidResponse = (10, "InvalidResponse") ceProxyInvalidResponse = (11, "ProxyInvalidResponse") const ErrorMessages* = [ ceLoaderGone: "loader process crashed", ceCookieStreamExists: "cookie stream already exists", ceCGICachedBodyUnavailable: "request body is not ready in the cache", ceCGIOutputHandleNotFound: "request body output handle not found", ceCGIFailedToOpenCacheOutput: "failed to open cache output", ceCGICachedBodyNotFound: "cached request body not found", ceFailedToRedirect: "failed to redirect request body", ceURLNotInCache: "URL was not found in the cache", ceFileNotInCache: "file was not found in the cache", ceFailedToExecuteCGIScript: "failed to execute CGI script", ceCGIMalformedHeader: "CGI script returned a malformed header", ceCGIInvalidChaControl: "CGI got invalid Cha-Control header", ceTooManyRewrites: "too many URI method map rewrites", ceInvalidURIMethodEntry: "invalid URI method entry", ceCGIFileNotFound: "CGI file not found", ceInvalidCGIPath: "invalid CGI path", ceFailedToSetUpCGI: "failed to set up CGI script", ceDisallowedURL: "url not allowed by filter", ceUnknownScheme: "unknown scheme", ceNone: "connection successful", ceInternalError: "internal error", ceInvalidMethod: "invalid method", ceInvalidURL: "invalid URL", ceFileNotFound: "file not found", ceConnectionRefused: "connection refused", ceProxyRefusedToConnect: "proxy refused to connect", ceFailedToResolveHost: "failed to resolve host", ceFailedToResolveProxy: "failed to resolve proxy", ceProxyAuthFail: "proxy authentication failed", ceInvalidResponse: "received an invalid response", ceProxyInvalidResponse: "proxy returned an invalid response", ] proc getLoaderErrorMessage*(code: int): string = if code in int(ConnectionError.low)..int(ConnectionError.high): return ErrorMessages[ConnectionError(code)] return "unexpected error code " & $code ������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/server/forkserver.nim�������������������������������������������������������������0000664�0000000�0000000�00000023327�15202323131�0020133�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/os import std/posix import std/tables import encoding/charset import config/config import config/urimethodmap import io/chafile import io/dynstream import io/packetreader import io/packetwriter import io/poll import server/buffer import server/bufferiface import server/connectionerror import server/loader import server/loaderiface import types/opt import types/url import types/winattrs import utils/myposix import utils/proctitle import utils/sandbox import utils/strwidth import utils/twtstr type ForkServer* = object pid*: Pid stream*: PosixStream estream*: PosixStream westream*: PosixStream ForkServerContext = object stream: PosixStream loaderStream: PosixStream pollData: PollData linkHintChars: seq[uint32] schemes: seq[string] proc loadConfig*(forkserver: ForkServer; config: Config): int = forkserver.stream.withPacketWriter w: w.swrite(config{"doubleWidthAmbiguous"}) w.swrite(config{"linkHintChars"}) w.swrite(LoaderConfig( w3mCGICompat: config{"w3mCgiCompat"}, cgiDir: config{"cgiDir"}, tmpdir: config{"tmpdir"}, configDir: config.dir, dataDir: config.dataDir, bookmark: config{"bookmark"}, maxNetConnections: config{"maxNetConnections"}, )) # client config for pager w.swrite(LoaderClientConfig( defaultHeaders: config{"defaultHeaders"}, proxy: config{"proxy"}, allowAllSchemes: true )) w.swrite(config{"urimethodmap"}) do: return -1 var process = -1 forkserver.stream.withPacketReaderFire r: r.sread(process) return process proc forkBuffer*(forkserver: ForkServer; config: BufferConfig; url: URL; attrs: WindowAttributes; ishtml: bool; charsetStack: seq[Charset]; contentType: string): tuple[pid: int; cstream: PosixStream] = var sv {.noinit.}: array[2, cint] if socketpair(AF_UNIX, SOCK_STREAM, IPPROTO_IP, sv) != 0: return (-1, nil) var fail = false forkserver.stream.withPacketWriter w: w.swrite(config) w.swrite(url) w.swrite(attrs) w.swrite(ishtml) w.swrite(charsetStack) w.swrite(contentType) w.sendFd(sv[1]) do: fail = true var bufferPid = -1 if not fail: forkserver.stream.withPacketReaderFire r: r.sread(bufferPid) if bufferPid == -1: discard close(sv[0]) return (-1, nil) return (bufferPid, newPosixStream(sv[0])) proc forkLoader(ctx: var ForkServerContext; config: LoaderConfig; loaderStream: PosixStream; pagerPid: int; pagerConfig: LoaderClientConfig; urimethodmap: URIMethodMap): (int, PosixStream) = # loaderStream is a connection between main process <-> loader, but we # also need a connection between fork server <-> loader. # The naming here is very confusing, sorry about that. var sv {.noinit.}: array[2, cint] if socketpair(AF_UNIX, SOCK_STREAM, IPPROTO_IP, sv) != 0: loaderStream.sclose() return (-1, nil) stderr.flushFile() let pid = fork() if pid == 0: # child process ctx.stream.sclose() discard close(sv[0]) let forkStream = newPosixStream(sv[1]) setProcessTitle("cha loader") runFileLoader(config, loaderStream, forkStream, pagerPid, pagerConfig, urimethodmap) exitnow(1) else: discard close(sv[1]) loaderStream.sclose() return (int(pid), newPosixStream(sv[0])) proc forkBuffer(ctx: var ForkServerContext; r: var PacketReader): int = var config: BufferConfig var url: URL var attrs: WindowAttributes var ishtml: bool var charsetStack: seq[Charset] var contentType: string r.sread(config) r.sread(url) r.sread(attrs) r.sread(ishtml) r.sread(charsetStack) r.sread(contentType) let fd = r.recvFd() stderr.flushFile() let pid = fork() if pid == 0: # child process ctx.stream.sclose() ctx.loaderStream.sclose() setBufferProcessTitle(url) let pid = getCurrentProcessId() let urandom = newPosixStream("/dev/urandom", O_RDONLY, 0) let pstream = newPosixStream(fd) var cacheId: int var loaderStream: PosixStream var istream: PosixStream pstream.withPacketReader r: r.sread(cacheId) loaderStream = newPosixStream(r.recvFd()) istream = newPosixStream(r.recvFd()) do: # EOF in pager; give up quit(1) let loader = newFileLoader(pid, loaderStream) # SIGPIPE remains ignored, because we don't want the buffer to signal # just because the pager unregistered it (this can also happen when a # buffer is cloned) enterBufferSandbox() launchBuffer(config, url, attrs, ishtml, charsetStack, loader, pstream, istream, urandom, cacheId, contentType, move(ctx.linkHintChars), move(ctx.schemes)) doAssert false discard close(fd) return pid proc forkCGI(ctx: var ForkServerContext; r: var PacketReader): int = var hasIstream: bool r.sread(hasIstream) let istream = if hasIstream: newPosixStream(r.recvFd()) else: nil let ostream = newPosixStream(r.recvFd()) # hack to detect when the child died var hasOstreamOut2: bool r.sread(hasOstreamOut2) let ostreamOut2 = if hasOstreamOut2: newPosixStream(r.recvFd()) else: nil var env: seq[tuple[name, value: string]] var dir: string var cmd: string var basename: string r.sread(env) r.sread(dir) r.sread(cmd) r.sread(basename) let pid = fork() if pid == 0: # child ctx.stream.sclose() ctx.loaderStream.sclose() # we leave stderr open, so it can be seen in the browser console if istream != nil: istream.moveFd(STDIN_FILENO) else: closeStdin() ostream.moveFd(STDOUT_FILENO) # reset SIGCHLD to the default handler. this is useful if the child # process expects SIGCHLD to be untouched. # (e.g. git dies a horrible death with SIGCHLD as SIG_IGN) discard myposix.signal(SIGCHLD, myposix.SIG_DFL) # let's also reset SIGPIPE, which we ignored on init discard myposix.signal(SIGPIPE, myposix.SIG_DFL) const ExecErrorMsg = "Cha-Control: ConnectionError " & $int(ceFailedToExecuteCGIScript) let stdout = cast[ChaFile](stdout) for it in env: if twtstr.setEnv(it.name, it.value).isErr: discard stdout.writeLine(ExecErrorMsg & " failed to set env vars") exitnow(1) if chdir(cstring(dir)) != 0: discard stdout.writeLine(ExecErrorMsg & " failed to set working directory") exitnow(1) discard execl(cstring(cmd), cstring(basename), nil) let es = $strerror(errno) discard stdout.writeLine(ExecErrorMsg & ' ' & es.deleteChars({'\n', '\r'})) exitnow(1) else: # parent or error if istream != nil: istream.sclose() ostream.sclose() if ostreamOut2 != nil: ostreamOut2.sclose() return pid proc setupForkServerEnv(config: LoaderConfig): Opt[void] = ?twtstr.setEnv("SERVER_SOFTWARE", "Chawan") ?twtstr.setEnv("SERVER_PROTOCOL", "HTTP/1.0") ?twtstr.setEnv("SERVER_NAME", "localhost") ?twtstr.setEnv("SERVER_PORT", "80") ?twtstr.setEnv("REMOTE_HOST", "localhost") ?twtstr.setEnv("REMOTE_ADDR", "127.0.0.1") ?twtstr.setEnv("GATEWAY_INTERFACE", "CGI/1.1") ?twtstr.setEnv("CHA_INSECURE_SSL_NO_VERIFY", "0") ?twtstr.setEnv("CHA_TMP_DIR", config.tmpdir) ?twtstr.setEnv("CHA_DIR", config.configDir) ?twtstr.setEnv("CHA_DATA_DIR", config.dataDir) ?twtstr.setEnv("CHA_BOOKMARK", config.bookmark) ok() proc runForkServer*(controlStream, loaderStream: PosixStream; pagerPid: int) = setProcessTitle("cha forkserver") var ctx = ForkServerContext(stream: controlStream) discard myposix.signal(SIGCHLD, myposix.SIG_IGN) discard myposix.signal(SIGPIPE, myposix.SIG_IGN) ctx.stream.withPacketReader r: var config: LoaderConfig var clientConfig: LoaderClientConfig var linkHintChars: string var urimethodmapPaths: seq[string] r.sread(isCJKAmbiguous) r.sread(linkHintChars) r.sread(config) r.sread(clientConfig) r.sread(urimethodmapPaths) ctx.linkHintChars = linkHintChars.toPoints() # for CGI if setupForkServerEnv(config).isErr: quit(1) var urimethodmap: URIMethodMap for path in urimethodmapPaths: let ps = newPosixStream(path) if ps != nil: urimethodmap.parseURIMethodMap(ps.readAll()) ps.sclose() urimethodmap.parseURIMethodMap(DefaultURIMethodMap) for key in urimethodmap.map.keys: ctx.schemes.add(key.until(':')) # returns a new stream that connects fork server <-> loader and # gives away main process <-> loader var (pid, loaderStream) = ctx.forkLoader(config, loaderStream, pagerPid, clientConfig, urimethodmap) ctx.stream.withPacketWriter w: w.swrite(pid) do: pid = -1 if pid == -1: # Notified main process of failure; our job is done. quit(1) ctx.loaderStream = loaderStream do: quit(1) ctx.pollData.register(ctx.stream.fd, POLLIN) ctx.pollData.register(ctx.loaderStream.fd, POLLIN) block mainLoop: while true: ctx.pollData.poll(-1) for event in ctx.pollData.events: if (event.revents and POLLIN) != 0: if event.fd == ctx.stream.fd: ctx.stream.withPacketReader r: let pid = ctx.forkBuffer(r) ctx.stream.withPacketWriter w: w.swrite(pid) do: break mainLoop # EOF do: break mainLoop # EOF elif event.fd == ctx.loaderStream.fd: ctx.loaderStream.withPacketReader r: let pid = ctx.forkCGI(r) ctx.loaderStream.withPacketWriter w: w.swrite(pid) do: break mainLoop # EOF do: break mainLoop # EOF if (event.revents and POLLERR) != 0 or (event.revents and POLLHUP) != 0: break mainLoop # EOF ctx.stream.sclose() # Clean up when the main process crashed. discard kill(0, cint(SIGTERM)) quit(0) {.pop.} # raises: [] ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/server/headers.nim����������������������������������������������������������������0000664�0000000�0000000�00000031011�15202323131�0017343�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/algorithm import io/packetreader import io/packetwriter import monoucha/fromjs import monoucha/jsbind import monoucha/jstypes import monoucha/quickjs import monoucha/tojs import types/jsopt import types/opt import types/referrer import types/url import utils/twtstr type HeaderGuard* = enum hgNone = "none" hgImmutable = "immutable" hgRequest = "request" hgRequestNoCors = "request-no-cors" hgResponse = "response" HTTPHeader* = tuple[name, value: string] HeaderList = seq[HTTPHeader] HeaderListConst = openArray[HTTPHeader] Headers* = ref object list: HeaderList guard*: HeaderGuard HeadersInit* = object s: seq[HTTPHeader] jsDestructor(Headers) proc isForbiddenResponseHeaderName*(name: string): bool iterator pairs*(this: Headers): tuple[name, value: lent string] = for (name, value) in this.list: if this.guard == hgResponse and name.isForbiddenResponseHeaderName(): continue yield (name, value) iterator allPairs*(headers: Headers): tuple[name, value: lent string] = for (name, value) in headers.list: yield (name, value) proc sort*(list: var HeaderList) = list.sort(proc(a, b: HTTPHeader): int = cmpIgnoreCase(a.name, b.name)) proc sort(headers: Headers) = headers.list.sort() # in the loader we just send a seq of openArray[HTTPHeader] proc sreadList*(r: var PacketReader; headers: Headers) = assert headers != nil r.sread(headers.list) headers.sort() proc swriteList*(w: var PacketWriter; headers: Headers) = w.swrite(headers.list) proc fromJS*(ctx: JSContext; val: JSValueConst; res: var HeadersInit): FromJSResult = var headers: Headers if ctx.fromJS(val, headers).isOk: res = HeadersInit(s: headers.list) return fjOk if ctx.isSequence(val): res = HeadersInit() if ctx.fromJS(val, res.s).isOk: return fjOk res = HeadersInit() var record: JSKeyValuePair[string, string] ?ctx.fromJS(val, record) res.s = move(record.s) fjOk const TokenChars = { '!', '#', '$', '%', '&', '\'', '*', '+', '-', '.', '^', '_', '`', '|', '~' } + AsciiAlphaNumeric proc isValidHeaderName*(s: string): bool = return s.len > 0 and AllChars - TokenChars notin s proc isValidHeaderValue*(s: string): bool = return s.len == 0 or s[0] notin {' ', '\t'} and s[^1] notin {' ', '\t'} and '\n' notin s proc isForbiddenRequestHeader*(name, value: string): bool = const ForbiddenNames = [ "Accept-Charset", "Accept-Encoding", "Access-Control-Request-Headers", "Access-Control-Request-Method", "Connection", "Content-Length", "Cookie", "Cookie2", "Date", "DNT", "Expect", "Host", "Keep-Alive", "Origin", "Referer", "Set-Cookie", "TE", "Trailer", "Transfer-Encoding", "Upgrade", "Via" ] for x in ForbiddenNames: if name.equalsIgnoreCase(x): return true if name.startsWithIgnoreCase("proxy-") or name.startsWithIgnoreCase("sec-"): return true if name.equalsIgnoreCase("X-HTTP-Method") or name.equalsIgnoreCase("X-HTTP-Method-Override") or name.equalsIgnoreCase("X-Method-Override"): return true # meh return false proc isForbiddenResponseHeaderName*(name: string): bool = return name.equalsIgnoreCase("Set-Cookie") or name.equalsIgnoreCase("Set-Cookie2") proc validate(ctx: JSContext; this: Headers; name, value: string): Opt[bool] = if not name.isValidHeaderName() or not value.isValidHeaderValue(): JS_ThrowTypeError(ctx, "invalid header name or value") return err() if this.guard == hgImmutable: JS_ThrowTypeError(ctx, "tried to modify immutable Headers object") return err() if this.guard == hgRequest and isForbiddenRequestHeader(name, value): return ok(false) if this.guard == hgResponse and name.isForbiddenResponseHeaderName(): return ok(false) ok(true) proc isNoCorsSafelistedName(name: string): bool = return name.equalsIgnoreCase("Accept") or name.equalsIgnoreCase("Accept-Language") or name.equalsIgnoreCase("Content-Language") or name.equalsIgnoreCase("Content-Type") const CorsUnsafeRequestByte = { char(0x00)..char(0x08), char(0x10)..char(0x1F), '"', '(', ')', ':', '<', '>', '?', '@', '[', '\\', ']', '{', '}', '\e' } proc isNoCorsSafelisted(name, value: string): bool = if value.len > 128: return false if name.equalsIgnoreCase("Accept"): return CorsUnsafeRequestByte notin value if name.equalsIgnoreCase("Accept-Language") or name.equalsIgnoreCase("Content-Language"): const Forbidden = AllChars - AsciiAlphaNumeric - {' ', '*', ',', '-', '.', ';', '='} return Forbidden notin value if name.equalsIgnoreCase("Content-Type"): return value.strip().toLowerAscii() in [ "multipart/form-data", "text/plain", "application-x-www-form-urlencoded" ] return false proc lowerBound(list: HeaderListConst; name: string): int = list.lowerBound(name, proc(it: HTTPHeader; name: string): int = cmpIgnoreCase(it.name, name) ) proc lowerBound(this: Headers; name: string): int = this.list.lowerBound(name) proc removeAll(list: var HeaderList; name: string; n: int) = var j = 0 for i, it in list.toOpenArray(n, list.high).mypairs: if not it.name.equalsIgnoreCase(name): break j = i + 1 var m = n + j if n != m: let L = list.len - j for n in n ..< L: list[n] = move(list[m]) inc m list.setLen(L) proc removeAll(this: Headers; name: string; n: int) = this.list.removeAll(name, n) proc contains(list: HeaderListConst; name: string; n: int): bool = return n < list.len and list[n].name.equalsIgnoreCase(name) proc contains(this: Headers; name: string; n: int): bool = this.list.contains(name, n) proc contains*(list: HeaderList; name: string): bool = list.contains(name, list.lowerBound(name)) proc contains*(this: Headers; name: string): bool = this.list.contains(name) proc removeAll*(this: Headers; name: string) = this.removeAll(name, this.lowerBound(name)) proc add(headers: Headers; name, value: string; n: int) = var n = n while n < headers.list.len and headers.contains(name, n): inc n headers.list.insert((name, value), n) proc addIfNotFound*(list: var HeaderList; name, value: string) = let n = list.lowerBound(name) if not list.contains(name, n): list.insert((name, value), n) proc addIfNotFound*(headers: Headers; name, value: string) = headers.list.addIfNotFound(name, value) # returns true if added, false otherwise proc addIfNotFoundCheck*(headers: Headers; name, value: string): bool = let n = headers.lowerBound(name) if not headers.contains(name, n): headers.list.insert((name, value), n) return true false proc get(this: Headers; name: string; n: int): string = var s = "" for it in this.list.toOpenArray(n, this.list.high): if not it.name.equalsIgnoreCase(name): break if s.len > 0: s &= ", " s &= it.value move(s) proc get*(ctx: JSContext; this: Headers; name: string): JSValue {.jsfunc.} = if not name.isValidHeaderName(): JS_ThrowTypeError(ctx, "Invalid header name") return JS_EXCEPTION let n = this.lowerBound(name) if this.contains(name, n): return ctx.toJS(this.get(name, n)) return JS_NULL proc removeRange(this: Headers) = if this.guard == hgRequestNoCors: this.removeAll("Range") # privileged no-CORS request headers proc append(ctx: JSContext; this: Headers; name, value: string): Opt[void] {.jsfunc.} = let value = value.strip(chars = HTTPWhitespace) if not ?ctx.validate(this, name, value): return ok() let n = this.lowerBound(name) if this.guard == hgRequestNoCors: var tmp = this.get(name, n) if tmp.len > 0: tmp &= ", " tmp &= value if not name.isNoCorsSafelisted(tmp): return ok() this.add(name, value, n) this.removeRange() ok() proc delete(ctx: JSContext; this: Headers; name: string): Opt[void] {.jsfunc.} = if not ?ctx.validate(this, name, "") or this.guard == hgRequestNoCors and not name.isNoCorsSafelistedName() and not name.equalsIgnoreCase("Range"): return ok() let n = this.lowerBound(name) if this.contains(name, n): this.removeAll(name, n) this.removeRange() ok() proc has(ctx: JSContext; this: Headers; name: string): JSValue {.jsfunc.} = if not name.isValidHeaderName(): return JS_ThrowTypeError(ctx, "invalid header name") if name in this: return JS_TRUE return JS_FALSE proc set(ctx: JSContext; this: Headers; name, value: string): Opt[void] {.jsfunc.} = let value = value.strip(chars = HTTPWhitespace) if not ?ctx.validate(this, name, value): return ok() if this.guard == hgRequestNoCors and not name.isNoCorsSafelisted(value): return ok() let n = this.lowerBound(name) this.removeAll(name, n) this.add(name, value, n) this.removeRange() ok() proc fill*(ctx: JSContext; headers: Headers; init: HeadersInit): Opt[void] = for (k, v) in init.s: ?ctx.append(headers, k, v) ok() proc newHeaders*(guard: HeaderGuard): Headers = return Headers(guard: guard) proc newHeaders*(guard: HeaderGuard; list: openArray[(string, string)]): Headers = let headers = newHeaders(guard) headers.list = @list headers.sort() return headers proc newHeaders(ctx: JSContext; jsInit: JSValueConst = JS_UNDEFINED): Opt[Headers] {.jsctor.} = let headers = newHeaders(hgNone) if not JS_IsUndefined(jsInit): var init: HeadersInit ?ctx.fromJS(jsInit, init) ?ctx.fill(headers, init) ok(headers) proc clone*(headers: Headers): Headers = return Headers(guard: headers.guard, list: headers.list) proc add*(headers: Headers; name, value: string) = headers.add(name, value, headers.lowerBound(name)) proc `[]=`*(this: Headers; name, value: string) = let n = this.lowerBound(name) this.removeAll(name, n) this.add(name, value, n) proc `[]`*(this: Headers; name: string): var string = let n = this.lowerBound(name) return this.list[n].value proc getFirst(list: HeaderListConst; name: string; n: int): lent string = if list.contains(name, n): return list[n].value let emptyStr {.global.} = "" return emptyStr proc getFirst*(list: HeaderListConst; name: string): lent string = list.getFirst(name, list.lowerBound(name)) proc getFirst*(headers: Headers; name: string): lent string = headers.list.getFirst(name) proc setupReferrer*(list: var HeaderList; target: URL; referrerPolicy: ReferrerPolicy) = # set referrer based on origin URL and referrer policy let n = list.lowerBound("Referer") if list.contains("Referer", n): let url = parseURL0(move(list[n].value)) list.removeAll("Referer", n) if url != nil: let referrer = url.getReferrer(target, referrerPolicy) if referrer != "": list.insert(("Referer", referrer), n) proc getAllNoComma*(list: HeaderListConst; k: string): seq[string] = result = @[] let n = list.lowerBound(k) for it in list.toOpenArray(n, list.high): if not it.name.equalsIgnoreCase(k): break result.add(it.value) proc getAllNoComma*(this: Headers; k: string): seq[string] = this.list.getAllNoComma(k) proc getAllCommaSplit*(this: Headers; k: string): seq[string] = result = @[] let n = this.lowerBound(k) for it in this.list.toOpenArray(n, this.list.high): if not it.name.equalsIgnoreCase(k): break for value in it.value.split(','): result.add(value.strip(chars = {' ', '\t'})) # n is timeout in millis. -1 => not found # url == nil => self type CheckRefreshResult* = tuple[n: int; url: URL] proc parseRefresh*(s: string; baseURL: URL): CheckRefreshResult = var i = s.skipBlanks(0) let s0 = s.until(NonDigit, i) let x = parseUInt32(s0, allowSign = false) if s0 != "": if x.isErr and (i >= s.len or s[i] != '.'): return (n: -1, url: nil) var n = int(x.get(0) * 1000) i = s.skipBlanks(i + s0.len) if i < s.len and s[i] == '.': inc i let s1 = s.until(NonDigit, i) if s1 != "": n += int(parseUInt32(s1, allowSign = false).get(0)) i = s.skipBlanks(i + s1.len) elif s0 == "": # empty string or blanks return (n: -1, url: nil) if i >= s.len: # just reload this page return (n: n, url: nil) if s[i] notin {',', ';'}: return (n: -1, url: nil) i = s.skipBlanks(i + 1) if s.toOpenArray(i, s.high).startsWithIgnoreCase("url="): i = s.skipBlanks(i + "url=".len) var q = false if i < s.len and s[i] in {'"', '\''}: q = true inc i var s2 = s.substr(i) if q and s2.len > 0 and s[^1] in {'"', '\''}: s2.setLen(s2.high) if url := parseURL(s2, baseURL): return (n: n, url: url) return (n: -1, url: nil) proc addHeadersModule*(ctx: JSContext): Opt[void] = ?ctx.registerType(Headers) ok() {.pop.} # raises: [] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/server/loader.nim�����������������������������������������������������������������0000664�0000000�0000000�00000177605�15202323131�0017222�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# A file loader server (?) # We receive various types of requests on a control socket, then respond # to each with a response. In case of the "load" request, we return one # half of a socket pair, and then send connection information before the # response body so that the protocol looks like: # C: RawRequest # S: (packet 1) res (0 => success, _ => error) # if success: # S: (packet 1) output ID # S: (packet 2) status code, headers # C: resume (on control socket) # S: response body # else: # S: (packet 1) error message # # The body is passed to the stream as-is, so effectively nothing can follow it. # # Note: if the consumer closes the request's body after headers have been # passed, it will *not* be cleaned up until a `resume' command is # received. (This allows for passing outputIds to the pager for later # addCacheFile commands there.) {.push raises: [].} import std/algorithm import std/os import std/posix import std/tables import std/times import config/conftypes import config/cookie import config/urimethodmap import html/script import io/dynstream import io/packetreader import io/packetwriter import io/poll import server/connectionerror import server/headers import server/loaderiface import server/request import types/blob import types/formdata import types/opt import types/url import utils/twtstr # Try to make it a SmallChunk. # We must subtract SmallChunk size, and then FreeCell size. # (See system/alloc.nim for details.) #TODO measure this on 32-bit too, we get a few more bytes there const LoaderBufferPageSize = 4016 # 4096 - 64 - 16 # Override posix.Time type Time = times.Time type CachedItem = ref object id: int refc: int offset: int64 path: string LoaderBuffer {.acyclic.} = ref object len: int page: seq[uint8] next: LoaderBuffer LoaderHandle = ref object of RootObj registered: bool # track registered state stream: PosixStream # input/output stream depending on type url: URL # URL nominally retrieved by handle before rewrites InputHandle = ref object of LoaderHandle outputs: seq[OutputHandle] # list of outputs to be streamed into cacheId: int # if cached, our ID in a client cacheMap cacheRef: CachedItem # if this is a tocache handle, a ref to our cache item parser: HeaderParser # only exists for CGI handles rstate: ResponseState # track response state credentials: bool # normalized to "include" (true) or "omit" (false) contentLen: uint64 # value of Content-Length; uint64.high if no such header bytesSeen: uint64 # number of bytes read until now startTime: Time # time when download of the body was started connectionOwner: ClientHandle # set if the handle counts in numConnections lastBuffer: LoaderBuffer # tail of buffer linked list OutputHandle = ref object of LoaderHandle parent: InputHandle currentBuffer: LoaderBuffer currentBufferIdx: int owner: ClientHandle outputId: int istreamAtEnd: bool suspended: bool dead: bool bytesSent: uint64 HandleParserState = enum hpsBeforeLines, hpsAfterFirstLine, hpsControlDone HeaderParser = ref object state: HandleParserState crSeen: bool status: uint16 lineBuffer: string headers: seq[HTTPHeader] ResponseState = enum rsBeforeResult, rsAfterFailure, rsBeforeStatus, rsAfterHeaders AuthItem = ref object origin: Origin username: string password: string ClientHandle = ref object of LoaderHandle pid: int # List of cached resources. cacheMap: seq[CachedItem] # List of file descriptors passed by the client. passedFdMap: seq[tuple[name: string; ps: PosixStream]] # host -> ps config: LoaderClientConfig # List of credentials the client has access to (same origin only). authMap: seq[AuthItem] # Number of ongoing requests in this client. numConnections: int # Requests that will only be sent once n no longer exceeds # maxNetConnections. pending: seq[(InputHandle, RawRequest, URL)] DownloadItem = ref object escapedPath: string displayUrl: string output: OutputHandle sent: uint64 contentLen: uint64 startTime: Time LoaderContext = object pid: int pagerClient: ClientHandle forkStream: PosixStream # handle to the fork server config: LoaderConfig handleMap: seq[LoaderHandle] pollData: PollData tmpfSeq: uint # List of existing clients (buffer or pager) that may make requests. clientMap: Table[int, ClientHandle] # pid -> data # ID of next output. TODO: find a better allocation scheme outputNum: int # List of *all* credentials the loader knows of. authMap: seq[AuthItem] # Handles to unregister and close at the end of this iteration. # This is needed so that we don't accidentally replace them with new # streams in the same iteration as they got closed. unregRead: seq[InputHandle] unregWrite: seq[OutputHandle] unregClient: seq[ClientHandle] downloadList: seq[DownloadItem] cookieStream: InputHandle pendingConnections: seq[ClientHandle] urimethodmap: URIMethodMap LoaderConfig* = object cgiDir*: seq[string] w3mCGICompat*: bool tmpdir*: string configDir*: string dataDir*: string bookmark*: string maxNetConnections*: int PushBufferResult = enum pbrDone, pbrUnregister CommandResult = enum cmdrDone, cmdrEOF # Forward declarations proc loadCGI(ctx: var LoaderContext; client: ClientHandle; handle: InputHandle; request: RawRequest; prevURL: URL; config: LoaderClientConfig) proc pushBuffer(ctx: var LoaderContext; handle: InputHandle; buffer: LoaderBuffer; ignoreSuspension: bool; unregWrite: var seq[OutputHandle]) proc `$`*(buffer: LoaderBuffer): string {.deprecated: "for debugging only".} = var s = newString(buffer.len) copyMem(addr s[0], addr buffer.page[0], buffer.len) return s template withPacketWriter(client: ClientHandle; w, body, fallback: untyped) = client.stream.withPacketWriter w: body do: fallback template withPacketWriterReturnEOF(client: ClientHandle; w, body: untyped) = client.withPacketWriter w: body do: return cmdrEOF proc put(ctx: var LoaderContext; handle: LoaderHandle) = let fd = int(handle.stream.fd) if ctx.handleMap.len <= fd: ctx.handleMap.setLen(fd + 1) assert ctx.handleMap[fd] == nil ctx.handleMap[fd] = handle proc unset(ctx: var LoaderContext; handle: LoaderHandle) = assert not handle.registered let fd = int(handle.stream.fd) if fd < ctx.handleMap.len: ctx.handleMap[fd] = nil proc getOutputId(ctx: var LoaderContext): int = result = ctx.outputNum inc ctx.outputNum # Create a new loader handle, with the output stream ostream. proc newInputHandle(ctx: var LoaderContext; ostream: PosixStream; owner: ClientHandle; url: URL; credentials: bool; suspended = true): InputHandle = let handle = InputHandle( cacheId: -1, contentLen: uint64.high, url: url, credentials: credentials ) let output = OutputHandle( stream: ostream, parent: handle, outputId: ctx.getOutputId(), owner: owner, url: url, suspended: suspended ) ctx.put(output) handle.outputs.add(output) return handle proc cap(buffer: LoaderBuffer): int {.inline.} = return LoaderBufferPageSize template isEmpty(output: OutputHandle): bool = output.currentBuffer == nil and not output.suspended proc newLoaderBuffer(size = LoaderBufferPageSize): LoaderBuffer = return LoaderBuffer(page: newSeqUninit[uint8](size)) proc newLoaderBuffer(s: openArray[char]): LoaderBuffer = let buffer = newLoaderBuffer(s.len) buffer.len = s.len copyMem(addr buffer.page[0], unsafeAddr s[0], s.len) buffer proc tee(ctx: var LoaderContext; outputIn: OutputHandle; ostream: PosixStream; owner: ClientHandle): OutputHandle = assert outputIn.suspended let output = OutputHandle( parent: outputIn.parent, stream: ostream, currentBuffer: outputIn.currentBuffer, currentBufferIdx: outputIn.currentBufferIdx, istreamAtEnd: outputIn.istreamAtEnd, outputId: ctx.getOutputId(), owner: owner, suspended: outputIn.suspended, url: outputIn.url ) ctx.put(output) if outputIn.parent != nil: assert outputIn.parent.parser == nil outputIn.parent.outputs.add(output) return output template output(handle: InputHandle): OutputHandle = assert handle.outputs.len == 1 handle.outputs[0] template bufferFromWriter(w, body: untyped): LoaderBuffer = var w = initPacketWriter() body w.writeSize() LoaderBuffer(page: move(w.buffer), len: w.bufLen) proc sendResult(ctx: var LoaderContext; handle: InputHandle; res: int; msg = ""): PushBufferResult = assert handle.rstate == rsBeforeResult let output = handle.output inc handle.rstate let buffer = bufferFromWriter w: w.swrite(res) if res == 0: # success assert msg == "" w.swrite(output.outputId) inc handle.rstate else: # error w.swrite(msg) var unregWrite: seq[OutputHandle] = @[] ctx.pushBuffer(handle, buffer, ignoreSuspension = true, unregWrite) if unregWrite.len > 0: return pbrUnregister pbrDone proc updateCookies(ctx: var LoaderContext; cookieJar: CookieJar; url: URL; owner: ClientHandle; values: openArray[string]) = # Syntax: {jarId} RS {url} RS {persist?} RS {header} [ CR {header} ... ] LF # Persist is ASCII digit 0 if persist, 1 if not. const RS = '\x1E' # ASCII record separator let persist = if owner.config.cookieMode == cmSave: '1' else: '0' var s = cookieJar.name & RS & $url & RS & persist & RS for i, it in values.mypairs: s &= it & [false: '\r', true: '\n'][i == values.high] let buffer = newLoaderBuffer(s) ctx.pushBuffer(ctx.cookieStream, buffer, ignoreSuspension = false, ctx.unregWrite) if ctx.cookieStream.output.dead: ctx.cookieStream = nil proc sendStatus(ctx: var LoaderContext; handle: InputHandle; status: uint16; headers: openArray[HTTPHeader]): PushBufferResult = assert handle.rstate == rsBeforeStatus inc handle.rstate let contentLens = headers.getFirst("Content-Length") handle.startTime = getTime() handle.contentLen = parseUInt64(contentLens).get(uint64.high) let output = handle.output let cookieJar = output.owner.config.cookieJar if cookieJar != nil and handle.credentials: # Never persist in loader; we save cookies in the pager. let values = headers.getAllNoComma("Set-Cookie") if values.len > 0: let url = handle.url cookieJar.setCookie(values, url, persist = false, http = true) if ctx.cookieStream != nil: ctx.updateCookies(cookieJar, url, output.owner, values) let buffer = bufferFromWriter w: w.swrite(status) w.swrite(headers) var unregWrite: seq[OutputHandle] = @[] ctx.pushBuffer(handle, buffer, ignoreSuspension = true, unregWrite) if unregWrite.len > 0: return pbrUnregister pbrDone proc sendConnectedStatus(ctx: var LoaderContext; handle: InputHandle; status: uint16; headers: openArray[HTTPHeader]): PushBufferResult = case ctx.sendResult(handle, 0) of pbrDone: discard of pbrUnregister: return pbrUnregister ctx.sendStatus(handle, status, headers) proc write(ps: PosixStream; buffer: LoaderBuffer; si = 0): int {.inline.} = let len = buffer.len - si if len == 0: # Warning: this can happen when using partially cached handles. return 0 assert len > 0 return ps.write(addr buffer.page[si], len) proc iclose(ctx: var LoaderContext; handle: InputHandle) = if handle.stream != nil: ctx.unset(handle) handle.stream.sclose() handle.stream = nil let client = handle.connectionOwner if client != nil: if client.numConnections == ctx.config.maxNetConnections and client.pending.len > 0: ctx.pendingConnections.add(client) dec client.numConnections handle.connectionOwner = nil proc oclose(ctx: var LoaderContext; output: OutputHandle) = ctx.unset(output) output.stream.sclose() output.stream = nil proc close(ctx: var LoaderContext; handle: InputHandle) = ctx.iclose(handle) for output in handle.outputs: if output.stream != nil: ctx.oclose(output) proc close(ctx: var LoaderContext; client: ClientHandle) = # Do *not* unset the client, that breaks temp-file cleanup. client.stream.sclose() client.stream = nil for it in client.cacheMap: dec it.refc if it.refc == 0: discard unlink(cstring(it.path)) proc isPrivileged(ctx: LoaderContext; client: ClientHandle): bool = return ctx.pagerClient == client #TODO this may be too low if we want to use urimethodmap for everything const MaxRewrites = 4 proc canRewriteForCGICompat(ctx: LoaderContext; path: string): bool = if path.startsWith("/cgi-bin/") or path.startsWith("/$LIB/"): return true for dir in ctx.config.cgiDir: if path.startsWith(dir): return true return false proc rejectHandle(ctx: var LoaderContext; handle: InputHandle; code: ConnectionError; msg = "") = case ctx.sendResult(handle, int(code), msg) of pbrDone: discard of pbrUnregister: ctx.unregWrite.add(handle.output) handle.output.dead = true iterator inputHandles(ctx: LoaderContext): InputHandle {.inline.} = for it in ctx.handleMap: if it != nil and it of InputHandle: yield InputHandle(it) iterator outputHandles(ctx: LoaderContext): OutputHandle {.inline.} = for it in ctx.handleMap: if it != nil and it of OutputHandle: yield OutputHandle(it) proc findOutput(ctx: var LoaderContext; id: int; client: ClientHandle): OutputHandle = assert id != -1 for it in ctx.outputHandles: if it.outputId == id: # verify that it's safe to access this handle. doAssert ctx.isPrivileged(client) or client == it.owner return it return nil proc findCachedHandle(ctx: LoaderContext; cacheId: int): InputHandle = assert cacheId != -1 for it in ctx.inputHandles: if it.cacheId == cacheId: return it return nil proc find(cacheMap: openArray[CachedItem]; id: int): int = for i, it in cacheMap.mypairs: if it.id == id: return i -1 proc register(ctx: var LoaderContext; handle: InputHandle) = assert not handle.registered ctx.pollData.register(handle.stream.fd, cshort(POLLIN)) handle.registered = true proc unregister(ctx: var LoaderContext; handle: InputHandle) = assert handle.registered ctx.pollData.unregister(int(handle.stream.fd)) handle.registered = false proc register(ctx: var LoaderContext; output: OutputHandle) = assert not output.registered ctx.pollData.register(int(output.stream.fd), cshort(POLLOUT)) output.registered = true proc unregister(ctx: var LoaderContext; output: OutputHandle) = assert output.registered ctx.pollData.unregister(int(output.stream.fd)) output.registered = false proc register(ctx: var LoaderContext; client: ClientHandle) = assert not client.registered ctx.clientMap[client.pid] = client ctx.pollData.register(client.stream.fd, cshort(POLLIN)) client.registered = true proc unregister(ctx: var LoaderContext; client: ClientHandle) = assert client.registered ctx.clientMap.del(client.pid) ctx.pollData.unregister(int(client.stream.fd)) client.registered = false # Either write data to the target output, or append it to the list of # buffers to write and register the output in our selector. # ignoreSuspension is meant to be used when sending the connection # result and headers, which are sent irrespective of whether the handle # is suspended or not. proc pushBuffer(ctx: var LoaderContext; handle: InputHandle; buffer: LoaderBuffer; ignoreSuspension: bool; unregWrite: var seq[OutputHandle]) = if handle.lastBuffer == nil: handle.lastBuffer = buffer else: handle.lastBuffer.next = buffer handle.lastBuffer = buffer for output in handle.outputs: if output.dead: # do not push to unregWrite candidates continue if output.currentBuffer == nil: if output.suspended and not ignoreSuspension: output.currentBuffer = buffer output.currentBufferIdx = 0 else: var n = output.stream.write(buffer) if n < 0: let e = errno if e == EAGAIN or e == EWOULDBLOCK or e == EINTR: n = 0 else: assert e == EPIPE, $strerror(e) output.dead = true unregWrite.add(output) continue else: output.bytesSent += uint64(n) if n < buffer.len: output.currentBuffer = buffer output.currentBufferIdx = n ctx.register(output) proc redirectToFile(ctx: var LoaderContext; output: OutputHandle; targetPath: string; fileOutput: var OutputHandle; osent: var uint64): bool = fileOutput = nil osent = 0 discard mkdir(cstring(ctx.config.tmpdir), 0o700) discard unlink(cstring(targetPath)) let ps = newPosixStream(targetPath, O_CREAT or O_WRONLY or O_EXCL, 0o600) if ps == nil: return false var buffer = output.currentBuffer var m = output.currentBufferIdx while buffer != nil: while m < buffer.len: let n = ps.write(buffer, m) if n <= 0: ps.sclose() return false m += n osent += uint64(n) m = 0 buffer = buffer.next if output.istreamAtEnd: ps.sclose() elif output.parent != nil: fileOutput = OutputHandle( parent: output.parent, stream: ps, istreamAtEnd: output.istreamAtEnd, outputId: ctx.getOutputId(), bytesSent: osent, url: output.url ) output.parent.outputs.add(fileOutput) return true proc getTempFile(ctx: var LoaderContext): string = result = ctx.config.tmpdir / "chaltmp" & $ctx.pid & "-" & $ctx.tmpfSeq inc ctx.tmpfSeq proc addCacheFile(ctx: var LoaderContext; client: ClientHandle; output: OutputHandle): int = if output.parent != nil and output.parent.cacheId != -1: # may happen e.g. if client tries to cache a `cache:' URL return output.parent.cacheId let tmpf = ctx.getTempFile() var dummy: OutputHandle var sent: uint64 if ctx.redirectToFile(output, tmpf, dummy, sent): let cacheId = output.outputId if output.parent != nil: output.parent.cacheId = cacheId client.cacheMap.add(CachedItem(id: cacheId, path: tmpf, refc: 1)) return cacheId return -1 proc openCachedItem(client: ClientHandle; id: int): (PosixStream, int) = let n = client.cacheMap.find(id) if n != -1: let item = client.cacheMap[n] let ps = newPosixStream(client.cacheMap[n].path, O_RDONLY, 0) if ps == nil: client.cacheMap.del(n) return (nil, -1) assert item.offset != -1 if ps.seek(item.offset) >= 0: return (ps, n) return (nil, -1) proc addFd(ctx: var LoaderContext; handle: InputHandle) = handle.stream.setBlocking(false) ctx.register(handle) ctx.put(handle) type ControlResult = enum crDone, crContinue, crError proc handleFirstLine(ctx: var LoaderContext; handle: InputHandle; line: string): ControlResult = if line.startsWithIgnoreCase("HTTP/1.0") or line.startsWithIgnoreCase("HTTP/1.1"): let codes = line.until(' ', "HTTP/1.0 ".len) let code = parseUInt16(codes) if codes.len > 3 or code.isErr: ctx.rejectHandle(handle, ceCGIMalformedHeader) return crError case ctx.sendResult(handle, 0) # Success of pbrDone: discard of pbrUnregister: return crError handle.parser.status = code.get return crDone let k = line.until(':') if k.len == line.len: # invalid ctx.rejectHandle(handle, ceCGIMalformedHeader) return crError let v = line.substr(k.len + 1).strip() if k.equalsIgnoreCase("Status"): case ctx.sendResult(handle, 0) # success of pbrDone: discard of pbrUnregister: return crError let code = parseUInt16(v) if v.len > 3 or code.isErr: ctx.rejectHandle(handle, ceCGIMalformedHeader) return crError handle.parser.status = code.get return crContinue if k.equalsIgnoreCase("Cha-Control"): if v.startsWithIgnoreCase("Connected"): case ctx.sendResult(handle, 0) # success of pbrDone: discard of pbrUnregister: return crError return crContinue if v.startsWithIgnoreCase("ConnectionError "): var code = ceCGIInvalidChaControl var message = "" var i = "ConnectionError ".len let ns = v.until(' ', i) if ns.len > 0: if n := parseInt32(ns): if n > 0 and n <= int32(ConnectionError.high): code = ConnectionError(n) else: let x = strictParseEnum[ConnectionError](ns).get(ceNone) if x != ceNone: code = x i += ns.len + 1 if i < v.len: message = v.substr(i) ctx.rejectHandle(handle, code, message) return crError if v.startsWithIgnoreCase("ControlDone"): case ctx.sendResult(handle, 0) # success of pbrDone: discard of pbrUnregister: return crError return crDone ctx.rejectHandle(handle, ceCGIInvalidChaControl) return crError case ctx.sendResult(handle, 0) # success of pbrDone: discard of pbrUnregister: return crError handle.parser.headers.add((k, v)) return crDone proc handleControlLine(handle: InputHandle; line: string): ControlResult = let k = line.until(':') if k.len == line.len: # invalid return crError let v = line.substr(k.len + 1).strip() if k.equalsIgnoreCase("Status"): let code = parseUInt16(v) if v.len > 3 or code.isErr: return crError handle.parser.status = parseUInt16(v).get(0) return crContinue if k.equalsIgnoreCase("Cha-Control"): if v.startsWithIgnoreCase("ControlDone"): return crDone return crError handle.parser.headers.add((k, v)) return crDone proc handleLine(handle: InputHandle; line: string) = let k = line.until(':') if k.len < line.len: let v = line.substr(k.len + 1).strip() handle.parser.headers.add((k, v)) proc parseHeaders0(ctx: var LoaderContext; handle: InputHandle; data: openArray[char]): int = let parser = handle.parser for i, c in data: if parser.crSeen and c != '\n': handle.parser = nil return -1 parser.crSeen = false if c == '\r': parser.crSeen = true elif c == '\n': if parser.lineBuffer == "": if parser.state == hpsBeforeLines: # body comes immediately, so we haven't had a chance to send result # yet. case ctx.sendResult(handle, 0) of pbrDone: discard of pbrUnregister: handle.parser = nil return -1 parser.headers.sort() let res = ctx.sendStatus(handle, parser.status, parser.headers) handle.parser = nil return case res of pbrDone: i + 1 # +1 to skip \n of pbrUnregister: -1 case parser.state of hpsBeforeLines: case ctx.handleFirstLine(handle, parser.lineBuffer) of crDone: parser.state = hpsControlDone of crContinue: parser.state = hpsAfterFirstLine of crError: handle.parser = nil return -1 of hpsAfterFirstLine: case handle.handleControlLine(parser.lineBuffer) of crDone: parser.state = hpsControlDone of crContinue: discard of crError: parser.headers.sort() discard ctx.sendStatus(handle, 500, parser.headers) handle.parser = nil return -1 of hpsControlDone: handle.handleLine(parser.lineBuffer) parser.lineBuffer = "" else: parser.lineBuffer &= c return data.len proc parseHeaders(ctx: var LoaderContext; handle: InputHandle; buffer: LoaderBuffer): int = if buffer == nil: return ctx.parseHeaders0(handle, ['\n']) let p = cast[ptr UncheckedArray[char]](addr buffer.page[0]) return ctx.parseHeaders0(handle, p.toOpenArray(0, buffer.len - 1)) proc finishParse(ctx: var LoaderContext; handle: InputHandle) = if handle.cacheRef != nil: assert handle.cacheRef.offset == -1 let ps = newPosixStream(handle.cacheRef.path, O_RDONLY, 0) if ps != nil: var buffer {.noinit.}: array[4096, char] var off = 0i64 while true: let n = ps.read(buffer) if n <= 0: assert n == 0 or errno != EBADF break let pn = ctx.parseHeaders0(handle, buffer.toOpenArray(0, n - 1)) if pn == -1: break off += int64(pn) if pn < n: handle.parser = nil break handle.cacheRef.offset = off ps.sclose() handle.cacheRef = nil if handle.parser != nil: discard ctx.parseHeaders(handle, nil) type HandleReadResult = enum hrrDone, hrrUnregister, hrrBrokenPipe # Called whenever there is more data available to read. proc handleRead(ctx: var LoaderContext; handle: InputHandle; unregWrite: var seq[OutputHandle]): HandleReadResult = let maxUnregs = unregWrite.len + handle.outputs.len while true: var buffer = newLoaderBuffer() let n = handle.stream.read(buffer.page) if n < 0: let e = errno if e == EAGAIN or e == EWOULDBLOCK or e == EINTR: # retry later break else: # sender died; stop streaming assert e == EPIPE, $strerror(e) return hrrBrokenPipe if n == 0: # EOF return hrrUnregister buffer.len = n var si = 0 if handle.parser != nil: si = ctx.parseHeaders(handle, buffer) if si == -1: # died while parsing headers; unregister return hrrUnregister if si == n: # parsed the entire buffer as headers; skip output handling continue if si != 0: # Some parts of the buffer have been consumed as headers; others # must be passed on to the client. # We *could* store si as an offset to the buffer, but it would # make things much more complex. Let's just do this: let nlen = buffer.len - si let nbuffer = newLoaderBuffer(nlen) nbuffer.len = nlen copyMem(addr nbuffer.page[0], addr buffer.page[si], nbuffer.len) buffer = nbuffer assert nbuffer.len != 0, $si & ' ' & $buffer.len & " n " & $n else: handle.bytesSeen += uint64(n) #TODO stop reading if Content-Length exceeded ctx.pushBuffer(handle, buffer, ignoreSuspension = false, unregWrite) if unregWrite.len == maxUnregs: # early return: no more outputs to write to break if n < buffer.cap: break hrrDone # stream is a regular file, so we can't select on it. # # cachedHandle is used for attaching the output handle to another # InputHandle when loadFromCache is called while a download is still # ongoing (and thus some parts of the document are not cached yet). proc loadStreamRegular(ctx: var LoaderContext; handle, cachedHandle: InputHandle) = assert handle.parser == nil # parser is only used with CGI var unregWrite: seq[OutputHandle] = @[] let r = ctx.handleRead(handle, unregWrite) for output in unregWrite: output.parent = nil let i = handle.outputs.find(output) if output.registered: ctx.unregister(output) handle.outputs.del(i) if r == hrrBrokenPipe: for output in handle.outputs: ctx.oclose(output) elif cachedHandle != nil: if handle.lastBuffer != nil: # cachedHandle has a different tail than handle, so output's # linked list will eventually break. # To fix this, we create a "ghost" buffer whose only purpose is to # connect the two chains, by setting it as the tail of both. # Note: we know that handle has read cachedHandle.lastBuffer, # because handle's input is taken synchronously from cachedHandle. let buffer = newLoaderBuffer(1) if cachedHandle.lastBuffer != nil: # I'm not 100% sure if this can be nil, but better safe than # sorry. cachedHandle.lastBuffer.next = buffer cachedHandle.lastBuffer = buffer handle.lastBuffer.next = buffer for output in handle.outputs: output.parent = cachedHandle cachedHandle.outputs.add(output) else: for output in handle.outputs: if output.registered or output.suspended: output.parent = nil output.istreamAtEnd = true else: ctx.oclose(output) handle.outputs.setLen(0) ctx.iclose(handle) proc findItem(authMap: seq[AuthItem]; origin: Origin): AuthItem = for it in authMap: if origin.isSameOrigin(it.origin): return it return nil proc includeCredentials(config: LoaderClientConfig; request: RawRequest; url: URL): bool = return request.credentials == cmInclude or request.credentials == cmSameOrigin and (config.originURL == nil or url.origin.isSameOrigin(config.originURL.origin)) proc findAuth(client: ClientHandle; request: RawRequest; url: URL): AuthItem = if not request.headers.contains("Authorization") and client.config.includeCredentials(request, url): if request.urlCredentials and url.includesCredentials(): #TODO this should be sent only after 401 I guess? # (otherwise we should return nil, *not* fallback to authMap) return AuthItem( origin: url.authOrigin, username: url.username, password: url.password ) if client.authMap.len > 0: return client.authMap.findItem(url.authOrigin) return nil proc putMappedURL(s: var seq[tuple[name, value: string]]; url: URL; auth: AuthItem) = s.add(("MAPPED_URI_SCHEME", url.scheme)) if auth != nil: s.add(("MAPPED_URI_USERNAME", auth.username)) s.add(("MAPPED_URI_PASSWORD", auth.password)) s.add(("MAPPED_URI_HOST", url.hostname)) s.add(("MAPPED_URI_PORT", url.port)) s.add(("MAPPED_URI_PATH", url.pathname)) s.add(("MAPPED_URI_QUERY", url.search.substr(1))) type CGIPath = object basename: string pathInfo: string cmd: string scriptName: string requestURI: string myDir: string proc setupEnv(cpath: CGIPath; request: RawRequest; contentLen: int; prevURL: URL; config: LoaderClientConfig; auth: AuthItem): seq[tuple[name, value: string]] = result = @[] let url = request.url result.add(("SCRIPT_NAME", cpath.scriptName)) result.add(("SCRIPT_FILENAME", cpath.cmd)) result.add(("REQUEST_URI", cpath.requestURI)) result.add(("REQUEST_METHOD", $request.httpMethod)) var contentTypeSeen = false var contentType = "" var cookieSeen = false var refererSeen = false var headers = "" for it in request.headers: headers &= it.name & ": " & it.value & "\r\n" if not contentTypeSeen and it.name.equalsIgnoreCase("Content-Type"): contentType = it.value contentTypeSeen = true elif not cookieSeen and it.name.equalsIgnoreCase("Cookie"): result.add(("HTTP_COOKIE", it.value)) cookieSeen = true elif not refererSeen and it.name.equalsIgnoreCase("Referer"): result.add(("HTTP_REFERER", it.value)) refererSeen = true result.add(("REQUEST_HEADERS", headers)) if prevURL != nil: result.putMappedURL(prevURL, auth) if cpath.pathInfo != "": result.add(("PATH_INFO", cpath.pathInfo)) if url.search != "": result.add(("QUERY_STRING", url.search.substr(1))) if request.httpMethod == hmPost: if request.body.t == rbtMultipart: result.add(("CONTENT_TYPE", request.body.multipart.getContentType())) else: result.add(("CONTENT_TYPE", contentType)) result.add(("CONTENT_LENGTH", $contentLen)) if config.proxy != nil: result.add(("ALL_PROXY", $config.proxy)) if config.insecureSslNoVerify: result.add(("CHA_INSECURE_SSL_NO_VERIFY", "1")) proc parseCGIPath(ctx: LoaderContext; request: RawRequest): CGIPath = var path = percentDecode(request.url.pathname) if path.startsWith("/cgi-bin/"): path.delete(0 .. "/cgi-bin/".high) elif path.startsWith("/$LIB/"): path.delete(0 .. "/$LIB/".high) var cpath = CGIPath() if path.len <= 0 or request.url.hostname != "": return cpath if path[0] == '/': for dir in ctx.config.cgiDir: if path.startsWith(dir): cpath.basename = path.substr(dir.len).until('/') cpath.pathInfo = path.substr(dir.len + cpath.basename.len) cpath.cmd = dir / cpath.basename if not fileExists(cpath.cmd): continue cpath.myDir = dir cpath.scriptName = path.substr(0, dir.len + cpath.basename.len) cpath.requestURI = cpath.cmd / cpath.pathInfo & request.url.search break else: cpath.basename = path.until('/') cpath.pathInfo = path.substr(cpath.basename.len) cpath.scriptName = "/cgi-bin/" & cpath.basename cpath.requestURI = "/cgi-bin/" & path & request.url.search for dir in ctx.config.cgiDir: cpath.cmd = dir / cpath.basename if fileExists(cpath.cmd): cpath.myDir = dir break return cpath proc loadCGI(ctx: var LoaderContext; client: ClientHandle; handle: InputHandle; request: RawRequest; prevURL: URL; config: LoaderClientConfig) = if prevURL != nil and not ctx.isPrivileged(client) and prevURL.isNetPath(): # Quick hack to throttle the number of simultaneous ongoing # connections. # We do not want to throttle non-net paths and requests originating # from the pager (i.e. client is privileged); in the former case, # we are probably dealing with local requests, and in the latter # case, the config may be different than client.config. handle.connectionOwner = client if client.numConnections >= ctx.config.maxNetConnections: client.pending.add((handle, request, prevURL)) return inc client.numConnections let cpath = ctx.parseCGIPath(request) if cpath.cmd == "" or cpath.basename.len <= 0 or cpath.basename == "." or cpath.basename == ".." or cpath.basename[0] == '~': ctx.rejectHandle(handle, ceInvalidCGIPath) ctx.close(handle) return if not fileExists(cpath.cmd): ctx.rejectHandle(handle, ceCGIFileNotFound) ctx.close(handle) return # Pipe the response body as stdout. var pipefd: array[2, cint] # child -> parent if pipe(pipefd) == -1: ctx.rejectHandle(handle, ceFailedToSetUpCGI) ctx.close(handle) return let istreamOut = newPosixStream(pipefd[0]) # read by loader var ostreamOut = newPosixStream(pipefd[1]) # written by child var ostreamOut2: PosixStream = nil if request.tocache: # Set stdout to a file, and repurpose the pipe as a dummy to detect when # the process ends. outputId is the cache id. let tmpf = ctx.getTempFile() ostreamOut2 = ostreamOut discard unlink(cstring(tmpf)) # RDWR, otherwise mmap won't work ostreamOut = newPosixStream(tmpf, O_CREAT or O_RDWR or O_EXCL, 0o600) if ostreamOut == nil: ctx.rejectHandle(handle, ceCGIFailedToOpenCacheOutput) ctx.close(handle) return let cacheId = handle.output.outputId # welp let item = CachedItem( id: cacheId, path: tmpf, refc: 1, offset: -1 ) handle.cacheRef = item client.cacheMap.add(item) # Pipe the request body as stdin for POST. var istream: PosixStream = nil # child end (read) var ostream: PosixStream = nil # parent end (write) var istream2: PosixStream = nil # child end (read) for rbtCache var cachedHandle: InputHandle = nil # for rbtCache var outputIn: OutputHandle = nil # for rbtOutput if request.body.t == rbtCache: var n: int (istream, n) = client.openCachedItem(request.body.cacheId) if istream == nil: ctx.rejectHandle(handle, ceCGICachedBodyNotFound) ctx.close(handle) return cachedHandle = ctx.findCachedHandle(request.body.cacheId) if cachedHandle != nil: # cached item still open, switch to streaming mode if client.cacheMap[n].offset == -1: ctx.rejectHandle(handle, ceCGICachedBodyUnavailable) ctx.close(handle) return istream2 = istream elif request.body.t == rbtOutput: outputIn = ctx.findOutput(request.body.outputId, client) if outputIn == nil: ctx.rejectHandle(handle, ceCGIOutputHandleNotFound) ctx.close(handle) return if request.body.t notin {rbtNone, rbtCache} or istream2 != nil: var pipefdRead: array[2, cint] # parent -> child if pipe(pipefdRead) == -1: ctx.rejectHandle(handle, ceFailedToSetUpCGI) ctx.close(handle) return istream = newPosixStream(pipefdRead[0]) ostream = newPosixStream(pipefdRead[1]) let contentLen = request.body.contentLength() let auth = if prevURL != nil: client.findAuth(request, prevURL) else: nil let env = setupEnv(cpath, request, contentLen, prevURL, config, auth) var pid: int ctx.forkStream.withPacketWriter w: w.swrite(istream != nil) if istream != nil: w.sendFd(istream.fd) w.sendFd(ostreamOut.fd) w.swrite(ostreamOut2 != nil) if ostreamOut2 != nil: w.sendFd(ostreamOut2.fd) w.swrite(env) w.swrite(cpath.myDir) w.swrite(cpath.cmd) w.swrite(cpath.basename) do: pid = -1 if pid != -1: ctx.forkStream.withPacketReader r: r.sread(pid) do: pid = -1 if pid == -1: ctx.rejectHandle(handle, ceFailedToSetUpCGI) if ostream != nil: ostream.sclose() ctx.close(handle) else: handle.parser = HeaderParser() handle.stream = istreamOut case request.body.t of rbtString: discard ostream.writeLoop(request.body.s) ostream.sclose() of rbtBlob: discard ostream.writeLoop(request.body.blob.toOpenArray()) ostream.sclose() of rbtMultipart: discard ostream.write(request.body.multipart) ostream.sclose() of rbtOutput: ostream.setBlocking(false) let output = ctx.tee(outputIn, ostream, client) output.suspended = false if not output.isEmpty: ctx.register(output) of rbtCache: if ostream != nil: let handle = ctx.newInputHandle(ostream, client, parseURL0("cache:/dev/null"), credentials = false, suspended = false) handle.stream = istream2 ostream.setBlocking(false) ctx.loadStreamRegular(handle, cachedHandle) assert handle.stream == nil ctx.close(handle) of rbtNone: discard proc findPassedFd(client: ClientHandle; name: string): int = for i in 0 ..< client.passedFdMap.len: if client.passedFdMap[i].name == name: return i return -1 proc loadStream(ctx: var LoaderContext; client: ClientHandle; handle: InputHandle; request: RawRequest) = let i = client.findPassedFd(request.url.pathname) if i == -1: ctx.rejectHandle(handle, ceFileNotFound, "stream not found") return case ctx.sendResult(handle, 0) of pbrDone: discard of pbrUnregister: return case ctx.sendStatus(handle, 200, []) of pbrDone: discard of pbrUnregister: return let ps = client.passedFdMap[i].ps var stats: Stat doAssert fstat(ps.fd, stats) != -1 handle.stream = ps client.passedFdMap.del(i) if S_ISCHR(stats.st_mode) or S_ISREG(stats.st_mode): # regular file: e.g. cha <file # or character device: e.g. cha </dev/null handle.output.stream.setBlocking(false) # not loading from cache, so cachedHandle is nil ctx.loadStreamRegular(handle, nil) proc loadFromCache(ctx: var LoaderContext; client: ClientHandle; handle: InputHandle; request: RawRequest) = let id = parseInt32(request.url.pathname).get(-1) let startFrom = parseInt64(request.url.search.substr(1)).get(0) let (ps, n) = client.openCachedItem(id) if ps != nil: if startFrom != 0: discard ps.seek(startFrom) handle.stream = ps if ps == nil: ctx.rejectHandle(handle, ceFileNotInCache) client.cacheMap.del(n) return case ctx.sendConnectedStatus(handle, 200, []) of pbrDone: handle.output.stream.setBlocking(false) let cachedHandle = ctx.findCachedHandle(id) ctx.loadStreamRegular(handle, cachedHandle) of pbrUnregister: client.cacheMap.del(n) ctx.close(handle) else: ctx.rejectHandle(handle, ceURLNotInCache) proc finishOutputSend(ctx: var LoaderContext; output: OutputHandle) = if not output.dead and (output.registered or output.suspended): output.istreamAtEnd = true else: if output.registered: ctx.unregister(output) ctx.oclose(output) # Data URL handler. # Moved back into loader from CGI, because data URLs can get extremely long # and thus no longer fit into the environment. proc loadDataSend(ctx: var LoaderContext; handle: InputHandle; s, ct: string) = case ctx.sendConnectedStatus(handle, 200, {"Content-Type": ct}) of pbrDone: discard of pbrUnregister: ctx.close(handle) return let output = handle.output if s.len == 0: ctx.finishOutputSend(output) return let buffer = newLoaderBuffer(s) var dummy: seq[OutputHandle] = @[] ctx.pushBuffer(handle, buffer, ignoreSuspension = false, dummy) ctx.finishOutputSend(output) proc loadData(ctx: var LoaderContext; handle: InputHandle; request: RawRequest) = let url = request.url var ct = url.pathname.until(',') if ct.len == url.pathname.len or NonAscii + Controls - {'\t'} in ct: ctx.rejectHandle(handle, ceInvalidURL, "invalid data URL") return let sd = ct.len + 1 # data start var body = percentDecode(url.pathname.toOpenArray(sd, url.pathname.high)) body &= percentDecode(url.search) if ct.endsWith(";base64"): var d: string if d.atob(body).isErr: ctx.rejectHandle(handle, ceInvalidURL, "invalid data URL") return ct.setLen(ct.len - ";base64".len) # remove base64 indicator ctx.loadDataSend(handle, d, ct) else: ctx.loadDataSend(handle, body, ct) # Download manager. Based on (you guessed it) w3m. proc formatSize(size: uint64): string = result = "" var size = size while size > 0: let n = size mod 1000 size = size div 1000 var ns = "" if size != 0: ns &= ',' if n < 100: ns &= '0' if n < 10: ns &= '0' ns &= $n result.insert(ns, 0) proc formatDuration(dur: Duration): string = result = "" let parts = dur.toParts() if parts[Weeks] != 0: result &= $parts[Weeks] & " Weeks, " if parts[Days] != 0: result &= $parts[Days] & " Days, " for i, it in [Hours, Minutes, Seconds]: if i > 0: result &= ':' if parts[it] in 0..9: result &= '0' result &= $parts[it] proc makeProgress(it: DownloadItem; now: Time): string = result = it.displayUrl.htmlEscape() & '\n' result &= " -> " if it.output == nil: # linkify path on completion result &= "<a href=\"file:" & it.escapedPath & "\">" & it.escapedPath & "</a>" else: result &= it.escapedPath result &= '\n' result &= " <progress value=" & $it.sent & " max=" result &= $it.contentLen & "></progress> \n " result &= formatSize(it.sent) if it.sent < it.contentLen and (it.contentLen < uint64.high or it.output != nil): if it.contentLen < uint64.high and it.contentLen > 0: result &= " / " & formatSize(it.contentLen) & " bytes (" & $(it.sent * 100 div it.contentLen) & "%) " else: result &= " bytes loaded " let dur = now - it.startTime result &= formatDuration(dur) result &= " rate " let udur = max(uint64(dur.inSeconds()), 1) let rate = it.sent div udur result &= convertSize(rate) & "/sec" if it.contentLen < uint64.high: let left = it.contentLen - it.sent let eta = initDuration(seconds = int64(left div max(rate, 1))) result &= " eta " & formatDuration(eta) else: result &= " bytes loaded" result &= '\n' type DownloadActionType = enum datRemove DownloadAction = object n: int t: DownloadActionType proc parseDownloadActions(ctx: LoaderContext; s: string): seq[DownloadAction] = result = @[] for it in s.split('&'): let name = it.until('=') if name.startsWith("stop"): let n = parseIntP(name.substr("stop".len)).get(-1) if n >= 0 and n < ctx.downloadList.len: result.add(DownloadAction(n: n, t: datRemove)) result.sort(proc(a, b: DownloadAction): int = return cmp(a.n, b.n), Descending) proc loadDownloads(ctx: var LoaderContext; handle: InputHandle; request: RawRequest) = if request.httpMethod == hmPost: # OK clicked if request.body.t != rbtString: ctx.rejectHandle(handle, ceInvalidURL, "wat") return for it in ctx.parseDownloadActions(request.body.s): let dl = ctx.downloadList[it.n] if dl.output != nil: ctx.unregWrite.add(dl.output) ctx.downloadList.del(it.n) var body = """ <!DOCTYPE html> <title>Download List Panel</title> <style>progress { width: calc(100% - 4ch) } </style> <body> <h1 align=center>Download List Panel</h1> <form method=POST action=about:downloads> <hr> <pre> """ let now = getTime() var refresh = false for i, it in ctx.downloadList.mpairs: if it.output != nil: it.sent = it.output.bytesSent if it.output.stream == nil: it.output = nil refresh = true body &= it.makeProgress(now) body &= "<input type=submit name=stop" & $i if it.output != nil: body &= " value=STOP" else: body &= " value=OK" body &= ">\n\n<hr>" if refresh: body &= "<meta http-equiv=refresh content=1>" # :P body &= """ </pre> </body> """ ctx.loadDataSend(handle, body, "text/html") # Stream for notifying the pager of new cookies set in the loader. proc loadCookieStream(ctx: var LoaderContext; handle: InputHandle; request: RawRequest) = if ctx.cookieStream != nil: ctx.rejectHandle(handle, ceCookieStreamExists) return case ctx.sendConnectedStatus(handle, 200, []) of pbrDone: ctx.cookieStream = handle of pbrUnregister: ctx.close(handle) proc loadAbout(ctx: var LoaderContext; handle: InputHandle; request: RawRequest) = let url = request.url case url.pathname of "blank": ctx.loadDataSend(handle, "", "text/html") of "chawan": const body = staticRead"res/chawan.html" ctx.loadDataSend(handle, body, "text/html") of "downloads": ctx.loadDownloads(handle, request) of "cookie-stream": ctx.loadCookieStream(handle, request) of "license": const body = staticRead"res/license.md" ctx.loadDataSend(handle, body, "text/markdown") else: ctx.rejectHandle(handle, ceInvalidURL, "invalid about URL") proc loadGetCookie(ctx: var LoaderContext; client: ClientHandle; handle: InputHandle) = case ctx.sendConnectedStatus(handle, 200, []) of pbrDone: discard of pbrUnregister: ctx.close(handle) return let output = handle.output let cookieJar = client.config.cookieJar if cookieJar != nil: let s = cookieJar.serialize(client.config.originURL, http = false) if s.len > 0: let buffer = newLoaderBuffer(s) var dummy: seq[OutputHandle] = @[] ctx.pushBuffer(handle, buffer, ignoreSuspension = false, dummy) ctx.finishOutputSend(output) proc loadSetCookie(ctx: var LoaderContext; client: ClientHandle; handle: InputHandle; request: RawRequest) = case ctx.sendConnectedStatus(handle, 200, []) of pbrDone: discard of pbrUnregister: ctx.close(handle) return let output = handle.output let cookieJar = client.config.cookieJar if cookieJar != nil: var cookies: seq[string] = @[] for it in request.headers: if it.name.equalsIgnoreCase("Set-Cookie"): cookies.add(it.value) let url = client.config.originURL cookieJar.setCookie(cookies, url, persist = false, http = false) if ctx.cookieStream != nil: ctx.updateCookies(cookieJar, url, output.owner, cookies) ctx.finishOutputSend(output) proc loadXChaCookie(ctx: var LoaderContext; client: ClientHandle; handle: InputHandle; request: RawRequest) = let url = request.url case url.pathname of "get-all": ctx.loadGetCookie(client, handle) of "set": ctx.loadSetCookie(client, handle, request) else: ctx.rejectHandle(handle, ceInvalidURL) proc loadResource(ctx: var LoaderContext; client: ClientHandle; config: LoaderClientConfig; request: var RawRequest; handle: InputHandle) = var redo = true var tries = 0 var prevurl: URL = nil while redo and tries < MaxRewrites: redo = false if ctx.config.w3mCGICompat and request.url.schemeType == stFile: let path = request.url.pathname.percentDecode() if ctx.canRewriteForCGICompat(path): let url = parseURL0("cgi-bin:" & path & request.url.search) if url != nil: request.url = url inc tries redo = true continue case request.url.schemeType of stCgiBin: ctx.loadCGI(client, handle, request, prevurl, config) if handle.stream != nil: ctx.addFd(handle) of stStream: ctx.loadStream(client, handle, request) if handle.stream != nil: ctx.addFd(handle) else: ctx.close(handle) of stCache: ctx.loadFromCache(client, handle, request) assert handle.stream == nil of stData: ctx.loadData(handle, request) of stAbout: ctx.loadAbout(handle, request) of stXChaCookie: ctx.loadXChaCookie(client, handle, request) else: prevurl = request.url case ctx.urimethodmap.findAndRewrite(request.url) of ummrSuccess: inc tries redo = true of ummrWrongURL: ctx.rejectHandle(handle, ceInvalidURIMethodEntry) of ummrNotFound: ctx.rejectHandle(handle, ceUnknownScheme) if tries >= MaxRewrites: ctx.rejectHandle(handle, ceTooManyRewrites) proc setupRequestDefaults(request: var RawRequest; config: LoaderClientConfig; credentials: bool) = for k, v in config.defaultHeaders.allPairs: request.headers.addIfNotFound(k, v) if config.cookieJar != nil and credentials: let cookie = config.cookieJar.serialize(request.url, http = true) if cookie != "": request.headers.addIfNotFound("Cookie", cookie) request.headers.setupReferrer(request.url, config.referrerPolicy) proc load(ctx: var LoaderContext; request: var RawRequest; client: ClientHandle; config: LoaderClientConfig): CommandResult = var pipev {.noinit.}: array[2, cint] var fail = false client.withPacketWriterReturnEOF w: if pipe(pipev) == 0: w.swrite(true) w.sendFd(pipev[0]) else: fail = true w.swrite(false) if not fail: let stream = newPosixStream(pipev[1]) stream.setBlocking(false) let credentials = config.includeCredentials(request, request.url) let handle = ctx.newInputHandle(stream, client, request.url, credentials) if not config.allowAllSchemes and request.url.scheme != config.originURL.scheme and request.url.scheme notin config.allowSchemes and request.url.scheme notin ctx.urimethodmap.imageProtos: ctx.rejectHandle(handle, ceDisallowedURL) else: request.setupRequestDefaults(config, credentials) ctx.loadResource(client, config, request, handle) cmdrDone proc loadCmd(ctx: var LoaderContext; client: ClientHandle; r: var PacketReader): CommandResult = var request: RawRequest r.sread(request) ctx.load(request, client, client.config) proc loadConfigCmd(ctx: var LoaderContext; client: ClientHandle; r: var PacketReader): CommandResult = var request: RawRequest var config: LoaderClientConfig r.sread(request) r.sread(config) ctx.load(request, client, config) proc getCacheFileCmd(ctx: var LoaderContext; rclient: ClientHandle; r: var PacketReader): CommandResult = var cacheId: int var sourcePid: int r.sread(cacheId) r.sread(sourcePid) let client = ctx.clientMap.getOrDefault(sourcePid, nil) let n = if client != nil: client.cacheMap.find(cacheId) else: -1 rclient.withPacketWriterReturnEOF w: if n != -1: w.swrite(client.cacheMap[n].path) else: w.swrite("") cmdrDone proc addClientCmd(ctx: var LoaderContext; rclient: ClientHandle; r: var PacketReader): CommandResult = var pid: int var config: LoaderClientConfig r.sread(pid) r.sread(config) assert pid notin ctx.clientMap var sv {.noinit.}: array[2, cint] var res = cmdrDone rclient.withPacketWriter w: if socketpair(AF_UNIX, SOCK_STREAM, IPPROTO_IP, sv) == 0: let stream = newPosixStream(sv[0]) let client = ClientHandle(stream: stream, pid: pid, config: config) ctx.register(client) ctx.put(client) if ctx.authMap.len > 0: let origin = config.originURL.authOrigin for it in ctx.authMap: if it.origin.isSameOrigin(origin): client.authMap.add(it) w.swrite(true) w.sendFd(sv[1]) else: w.swrite(false) do: res = cmdrEOF res proc removeClientCmd(ctx: var LoaderContext; rclient: ClientHandle; r: var PacketReader): CommandResult = var pid: int r.sread(pid) let client = ctx.clientMap.getOrDefault(pid) if client != nil: ctx.unregClient.add(client) cmdrDone proc addCacheFileCmd(ctx: var LoaderContext; rclient: ClientHandle; r: var PacketReader): CommandResult = var outputId: int r.sread(outputId) let output = ctx.findOutput(outputId, rclient) rclient.withPacketWriter w: if output == nil: w.swrite(-1) else: w.swrite(ctx.addCacheFile(rclient, output)) do: return cmdrEOF cmdrDone proc redirectToFileCmd(ctx: var LoaderContext; rclient: ClientHandle; r: var PacketReader): CommandResult = var outputId: int var targetPath: string var displayUrl: string r.sread(outputId) r.sread(targetPath) r.sread(displayUrl) let output = ctx.findOutput(outputId, rclient) var success = false if output != nil: var fileOutput: OutputHandle var sent: uint64 success = ctx.redirectToFile(output, targetPath, fileOutput, sent) let contentLen = if output.parent != nil: output.parent.contentLen else: uint64.high let startTime = if output.parent != nil: output.parent.startTime else: #TODO ??? fromUnix(0) ctx.downloadList.add(DownloadItem( escapedPath: targetPath.htmlEscape(), output: fileOutput, displayUrl: displayUrl, sent: sent, contentLen: contentLen, startTime: startTime )) rclient.withPacketWriter w: w.swrite(success) do: return cmdrEOF cmdrDone proc shareCachedItemCmd(ctx: var LoaderContext; rclient: ClientHandle; r: var PacketReader): CommandResult = # share a cached file with another buffer. this is for newBufferFrom # (i.e. view source) var sourcePid: int # pid of source client var targetPid: int # pid of target client var id: int r.sread(sourcePid) r.sread(targetPid) r.sread(id) let sourceClient = ctx.clientMap.getOrDefault(sourcePid) let targetClient = ctx.clientMap.getOrDefault(targetPid) let n = if sourceClient != nil and targetClient != nil: sourceClient.cacheMap.find(id) else: -1 if n != -1: let item = sourceClient.cacheMap[n] inc item.refc targetClient.cacheMap.add(item) rclient.withPacketWriter w: w.swrite(n != -1) do: return cmdrEOF cmdrDone proc openCachedItemCmd(ctx: var LoaderContext; rclient: ClientHandle; r: var PacketReader): CommandResult = # open a cached item var id: int r.sread(id) let (ps, _) = rclient.openCachedItem(id) rclient.withPacketWriter w: w.swrite(ps != nil) if ps != nil: w.sendFd(ps.fd) do: return cmdrEOF cmdrDone proc passFdCmd(ctx: var LoaderContext; rclient: ClientHandle; r: var PacketReader): CommandResult = var id: string r.sread(id) let fd = r.recvFd() #TODO cloexec? rclient.passedFdMap.add((id, newPosixStream(fd))) cmdrDone proc addPipeCmd(ctx: var LoaderContext; rclient: ClientHandle; r: var PacketReader): CommandResult = var id: string r.sread(id) var pipefd {.noinit.}: array[2, cint] if pipe(pipefd) == -1: rclient.withPacketWriter w: w.swrite(false) do: return cmdrEOF else: var success = true rclient.withPacketWriter w: w.swrite(true) w.sendFd(pipefd[1]) do: discard close(pipefd[0]) return cmdrEOF discard close(pipefd[1]) if success: let ps = newPosixStream(pipefd[0]) ps.setCloseOnExec() rclient.passedFdMap.add((id, ps)) else: discard close(pipefd[0]) cmdrDone proc removeCachedItemCmd(ctx: var LoaderContext; client: ClientHandle; r: var PacketReader): CommandResult = var id: int r.sread(id) let n = client.cacheMap.find(id) if n != -1: let item = client.cacheMap[n] client.cacheMap.del(n) dec item.refc if item.refc == 0: discard unlink(cstring(item.path)) cmdrDone proc teeCmd(ctx: var LoaderContext; rclient: ClientHandle; r: var PacketReader): CommandResult = var sourceId: int var targetPid: int r.sread(sourceId) r.sread(targetPid) let outputIn = ctx.findOutput(sourceId, rclient) let target = ctx.clientMap.getOrDefault(targetPid) var pipev {.noinit.}: array[2, cint] var res = cmdrDone if target != nil and outputIn != nil and pipe(pipev) == 0: let ostream = newPosixStream(pipev[1]) ostream.setBlocking(false) let output = ctx.tee(outputIn, ostream, target) rclient.withPacketWriter w: w.swrite(output.outputId) w.sendFd(pipev[0]) do: res = cmdrEOF else: rclient.withPacketWriter w: w.swrite(-1) do: res = cmdrEOF res proc addAuthCmd(ctx: var LoaderContext; rclient: ClientHandle; r: var PacketReader): CommandResult = var url: URL r.sread(url) let origin = url.authOrigin let item = ctx.authMap.findItem(origin) if item != nil: # Only replace the old item if the URL sets a password or the old # item's username is different. # This way, loading a URL with only the username set still lets us # load the password which is already associated with said username. if url.password != "" or item.username != url.username: item.username = url.username item.password = url.password else: let item = AuthItem( origin: url.authOrigin, username: url.username, password: url.password ) ctx.authMap.add(item) ctx.pagerClient.authMap.add(item) cmdrDone proc suspendCmd(ctx: var LoaderContext; rclient: ClientHandle; r: var PacketReader): CommandResult = var ids: seq[int] r.sread(ids) for id in ids: let output = ctx.findOutput(id, rclient) if output != nil: output.suspended = true if output.registered: # do not waste cycles trying to push into output ctx.unregister(output) cmdrDone proc resumeCmd(ctx: var LoaderContext; rclient: ClientHandle; r: var PacketReader): CommandResult = var ids: seq[int] r.sread(ids) for id in ids: let output = ctx.findOutput(id, rclient) if output != nil: output.suspended = false if not output.isEmpty or output.istreamAtEnd: ctx.register(output) cmdrDone const CommandMap = [ lcAddAuth: addAuthCmd, lcAddCacheFile: addCacheFileCmd, lcAddClient: addClientCmd, lcAddPipe: addPipeCmd, lcGetCacheFile: getCacheFileCmd, lcLoad: loadCmd, lcLoadConfig: loadConfigCmd, lcOpenCachedItem: openCachedItemCmd, lcPassFd: passFdCmd, lcRedirectToFile: redirectToFileCmd, lcRemoveCachedItem: removeCachedItemCmd, lcRemoveClient: removeClientCmd, lcResume: resumeCmd, lcShareCachedItem: shareCachedItemCmd, lcSuspend: suspendCmd, lcTee: teeCmd, ] const UnprivilegedCommands = { lcAddCacheFile, lcAddPipe, lcLoad, lcRemoveCachedItem, lcResume, lcSuspend, lcTee } const PrivilegedCommands = {LoaderCommand.low .. LoaderCommand.high} - UnprivilegedCommands proc readCommand(ctx: var LoaderContext; rclient: ClientHandle) = assert not rclient.stream.isend var res = cmdrEOF rclient.stream.withPacketReaderFire r: var cmd: LoaderCommand r.sread(cmd) if cmd in PrivilegedCommands: doAssert ctx.isPrivileged(rclient) res = CommandMap[cmd](ctx, rclient, r) case res of cmdrDone: discard of cmdrEOF: ctx.unregClient.add(rclient) proc exitLoader(ctx: LoaderContext) = for it in ctx.handleMap: if it of ClientHandle: let client = ClientHandle(it) for it in client.cacheMap: dec it.refc if it.refc <= 0: discard unlink(cstring(it.path)) exitnow(1) # This is only called when an OutputHandle could not read enough of one (or # more) buffers, and we asked select to notify us when it will be available. proc handleWrite(ctx: var LoaderContext; output: OutputHandle; unregWrite: var seq[OutputHandle]) = while output.currentBuffer != nil: let buffer = output.currentBuffer let n = output.stream.write(buffer, output.currentBufferIdx) if n < 0: let e = errno if e == EAGAIN or e == EWOULDBLOCK or e == EINTR: # never mind break else: # receiver died; stop streaming assert e == EPIPE, $strerror(e) unregWrite.add(output) break output.bytesSent += uint64(n) output.currentBufferIdx += n if output.currentBufferIdx < buffer.len: break # swap out buffer output.currentBufferIdx = 0 output.currentBuffer = buffer.next if output.isEmpty: if output.istreamAtEnd: # after EOF, no need to send anything more here unregWrite.add(output) else: # all buffers sent, no need to select on this output again for now ctx.unregister(output) proc finishCycle(ctx: var LoaderContext) = # Unregister handles queued for unregistration. # It is possible for both unregRead and unregWrite to contain duplicates. To # avoid double-close/double-unregister, we set the istream/ostream of # unregistered handles to nil. for handle in ctx.unregRead: if handle.stream != nil: ctx.unregister(handle) if handle.parser != nil: ctx.finishParse(handle) ctx.iclose(handle) for output in handle.outputs: output.istreamAtEnd = true if output.isEmpty: ctx.unregWrite.add(output) for output in ctx.unregWrite: if output.stream != nil: if output.registered: ctx.unregister(output) ctx.oclose(output) let handle = output.parent if handle != nil: # may be nil if from loadStream S_ISREG let i = handle.outputs.find(output) handle.outputs.del(i) if handle.outputs.len == 0 and handle.stream != nil: # premature end of all output streams; kill istream too ctx.unregister(handle) if handle.parser != nil: ctx.finishParse(handle) ctx.iclose(handle) for client in ctx.unregClient: if client.stream != nil: # Do it in this exact order, or the cleanup procedure will have # trouble finding all clients if we got interrupted in this loop. ctx.unregister(client) let fd = int(client.stream.fd) ctx.close(client) if fd < ctx.handleMap.len: ctx.handleMap[fd] = nil ctx.unregRead.setLen(0) ctx.unregWrite.setLen(0) ctx.unregClient.setLen(0) for client in ctx.pendingConnections: if client.stream == nil: continue var j = ctx.config.maxNetConnections - client.numConnections for (handle, request, prevURL) in client.pending: if client.numConnections >= ctx.config.maxNetConnections: break ctx.loadCGI(client, handle, request, prevURL, client.config) if handle.stream != nil: ctx.addFd(handle) let L = max(client.pending.len - j, 0) for i in 0 ..< L: client.pending[i] = client.pending[j] inc j client.pending.setLen(L) ctx.pendingConnections.setLen(0) proc loaderLoop(ctx: var LoaderContext) = while true: ctx.pollData.poll(-1) for event in ctx.pollData.events: let efd = int(event.fd) if (event.revents and POLLIN) != 0: let handle = ctx.handleMap[efd] if handle of ClientHandle: ctx.readCommand(ClientHandle(handle)) else: let handle = InputHandle(handle) case ctx.handleRead(handle, ctx.unregWrite) of hrrDone: discard of hrrUnregister, hrrBrokenPipe: ctx.unregRead.add(handle) if (event.revents and POLLOUT) != 0: let handle = ctx.handleMap[efd] ctx.handleWrite(OutputHandle(handle), ctx.unregWrite) if (event.revents and POLLERR) != 0 or (event.revents and POLLHUP) != 0: let handle = ctx.handleMap[efd] if handle of InputHandle: # istream died ctx.unregRead.add(InputHandle(handle)) elif handle of OutputHandle: # ostream died ctx.unregWrite.add(OutputHandle(handle)) else: # client died assert handle of ClientHandle ctx.unregClient.add(ClientHandle(handle)) ctx.finishCycle() ctx.exitLoader() proc runFileLoader*(config: LoaderConfig; stream, forkStream: PosixStream; pagerPid: int; pagerConfig: LoaderClientConfig; urimethodmap: URIMethodMap) = var ctx {.global.}: LoaderContext ctx = LoaderContext( config: config, pid: getCurrentProcessId(), forkStream: forkStream, urimethodmap: urimethodmap ) onSignal SIGTERM: discard sig ctx.exitLoader() for dir in ctx.config.cgiDir.mitems: if dir.len > 0 and dir[^1] != '/': dir &= '/' ctx.pagerClient = ClientHandle( stream: stream, pid: pagerPid, config: pagerConfig ) ctx.register(ctx.pagerClient) ctx.put(ctx.pagerClient) ctx.loaderLoop() {.pop.} # raises: [] ���������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/server/loaderiface.nim������������������������������������������������������������0000664�0000000�0000000�00000055622�15202323131�0020204�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Interface to server/loader. The idea is that modules don't have to # import the entire loader implementation to interact with it. # # See server/loader for a more detailed description of the protocol. {.push raises: [].} import std/posix import config/conftypes import config/cookie import config/mimetypes import encoding/charset import encoding/decoder import io/dynstream import io/packetreader import io/packetwriter import io/poll import monoucha/fromjs import monoucha/jsbind import monoucha/jsutils import monoucha/quickjs import monoucha/tojs import server/headers import server/request import types/blob import types/jsopt import types/opt import types/referrer import types/url import utils/twtstr type FileLoader* = ref object of RootObj clientPid*: int map: seq[MapData] mapFds*: int # number of fds in map pollData*: PollData unregistered*: seq[cint] # A mechanism to queue up new fds being added to the poll data # inside the events iterator. registerBlocked: bool registerQueue: seq[tuple[data: MapData; events: cshort]] # UNIX domain socket to the loader process. # We send all messages through this. controlStream*: PosixStream ConnectDataState* = enum cdsBeforeResult, cdsBeforeStatus MapData* = ref object of RootObj stream*: PosixStream LoaderData = ref object of MapData FetchFinish* = proc(opaque: RootRef; res: Response) {.nimcall, raises: [].} ConnectData* = ref object of LoaderData state: ConnectDataState outputId: int redirectNum: int finish: FetchFinish opaque*: RootRef request: Request LoaderCommand* = enum lcAddAuth lcAddCacheFile lcAddClient lcAddPipe lcGetCacheFile lcLoad lcLoadConfig lcOpenCachedItem lcPassFd lcRedirectToFile lcRemoveCachedItem lcRemoveClient lcResume lcShareCachedItem lcSuspend lcTee ClientKey* = array[32, uint8] LoaderClientConfig* = object originURL*: URL cookieJar*: CookieJar defaultHeaders*: Headers proxy*: URL allowSchemes*: seq[string] allowAllSchemes*: bool # only true for pager process insecureSslNoVerify*: bool referrerPolicy*: ReferrerPolicy cookieMode*: CookieMode ResponseType* = enum rtDefault = "default" rtBasic = "basic" rtCors = "cors" rtError = "error" rtOpaque = "opaque" rtOpaquedirect = "opaqueredirect" ResponseFlag* = enum rfAborted, rfBodyUsed, rfResumed ResponseFinish* = proc(response: Response; success: bool) {. nimcall, raises: [].} ResponseRead* = proc(response: Response) {.nimcall, raises: [].} Response* = ref object of LoaderData flags*: set[ResponseFlag] responseType* {.jsget: "type".}: ResponseType status* {.jsget.}: uint16 headers* {.jsget.}: Headers url*: URL #TODO should be urllist? onRead*: ResponseRead onFinish*: ResponseFinish outputId*: int opaque*: RootRef TextResult* = object isOk*: bool get*: string BlobFinish* = proc(opaque: BlobOpaque; blob: Blob) {.nimcall, raises: [].} BlobOpaque* = ref object of RootObj p: pointer len: int size: int contentType*: string JSBlobOpaque = ref object of BlobOpaque ctx: JSContext resolve: pointer # JSObject * reject: pointer # JSObject * jsDestructor(Response) # Forward declarations proc get*(loader: FileLoader; fd: cint): MapData proc resume*(loader: FileLoader; outputId: int) proc unregister*(loader: FileLoader; data: MapData) # Forward declaration hack var getLoaderImpl*: proc(ctx: JSContext): FileLoader {.nimcall, raises: [].} template resolveVal(this: BlobOpaque): JSValue = JS_MKPTR(JS_TAG_OBJECT, this.resolve) template rejectVal(this: BlobOpaque): JSValue = JS_MKPTR(JS_TAG_OBJECT, this.reject) proc finalize(rt: JSRuntime; this: Response) {.jsfin.} = if this.opaque of JSBlobOpaque: let opaque = JSBlobOpaque(this.opaque) if opaque.resolve != nil: JS_FreeValueRT(rt, opaque.resolveVal) if opaque.reject != nil: JS_FreeValueRT(rt, opaque.rejectVal) proc mark(rt: JSRuntime; this: Response; fun: JS_MarkFunc) {.jsmark.} = if this.opaque of JSBlobOpaque: let opaque = JSBlobOpaque(this.opaque) if opaque.resolve != nil: JS_MarkValue(rt, opaque.resolveVal, fun) if opaque.reject != nil: JS_MarkValue(rt, opaque.rejectVal, fun) template isErr*(x: TextResult): bool = not x.isOk template ok*(t: typedesc[TextResult]; s: string): TextResult = TextResult(isOk: true, get: s) template err*(t: typedesc[TextResult]): TextResult = TextResult() proc toJS*(ctx: JSContext; x: TextResult): JSValue = if x.isOk: return ctx.toJS(x.get) return JS_ThrowTypeError(ctx, "error reading response body") proc newResponse*(request: Request; stream: PosixStream; outputId: int): Response = return Response( url: if request != nil: request.url else: nil, stream: stream, outputId: outputId, headers: newHeaders(hgResponse), status: 200 ) proc newResponse*(ctx: JSContext; body: JSValueConst = JS_UNDEFINED; init: JSValueConst = JS_UNDEFINED): Opt[Response] {.jsctor.} = if not JS_IsUndefined(body) or not JS_IsUndefined(init): #TODO JS_ThrowInternalError(ctx, "Response constructor with body or init") return err() return ok(newResponse(nil, nil, -1)) proc makeNetworkError*(): Response {.jsstfunc: "Response#error".} = #TODO use "create" function return Response( responseType: rtError, status: 0, headers: newHeaders(hgImmutable), flags: {rfBodyUsed} ) proc jsOk(response: Response): bool {.jsfget: "ok".} = return response.status in 200u16 .. 299u16 proc surl*(response: Response): string {.jsfget: "url".} = if response.responseType == rtError or response.url == nil: return "" return $response.url proc bodyUsed*(response: Response): bool {.jsfget.} = rfBodyUsed in response.flags proc getCharset*(this: Response; fallback: Charset): Charset = let header = this.headers.getFirst("Content-Type").toLowerAscii() if header != "": let cs = header.getContentTypeAttr("charset").getCharset() if cs != csUnknown: return cs return fallback proc getLongContentType*(this: Response; fallback: string): string = let header = this.headers.getFirst("Content-Type") if header != "": return header.toValidUTF8().strip() # also use DefaultGuess for container, so that local mime.types cannot # override buffer mime.types return DefaultGuess.guessContentType(this.url.pathname, fallback) proc getContentType*(this: Response; fallback = "application/octet-stream"): string = return this.getLongContentType(fallback).untilLower(';') proc getContentLength*(this: Response): int64 = let x = this.headers.getFirst("Content-Length") let u = parseUInt64(x.strip(), allowSign = false).get(uint64.high) if u <= uint64(int64.high): return int64(u) return -1 proc getReferrerPolicy*(this: Response): Opt[ReferrerPolicy] = for value in this.headers.getAllCommaSplit("Referrer-Policy"): if policy := parseEnumNoCase[ReferrerPolicy](value): return ok(policy) err() proc resume*(loader: FileLoader; response: Response) = assert rfResumed notin response.flags loader.resume(response.outputId) response.flags.incl(rfResumed) proc close*(loader: FileLoader; response: Response) = response.flags.incl(rfBodyUsed) if response.stream != nil: if rfResumed notin response.flags: loader.resume(response) let fd = response.stream.fd let data = loader.get(fd) if data != nil: loader.unregister(data) response.stream.sclose() response.stream = nil const BufferSize = 4096 proc onReadBlob(response: Response) = let opaque = BlobOpaque(response.opaque) while true: if opaque.len + BufferSize > opaque.size: opaque.size *= 2 opaque.p = realloc(opaque.p, opaque.size) let p = cast[ptr UncheckedArray[uint8]](opaque.p) let diff = opaque.size - opaque.len let n = response.stream.read(addr p[opaque.len], diff) if n <= 0: assert n != -1 or errno != EBADF break opaque.len += n proc onFinishBlob*(response: Response; success: bool): Blob = let opaque = BlobOpaque(response.opaque) if success: let p = opaque.p opaque.p = nil let blob = if p == nil: newEmptyBlob(opaque.contentType) else: newBlob(p, opaque.len, opaque.contentType, deallocBlob) return blob if opaque.p != nil: dealloc(opaque.p) opaque.p = nil return nil proc blob*(loader: FileLoader; response: Response; opaque: BlobOpaque) = response.opaque = opaque if response.bodyUsed: response.onFinish(response, false) return if response.stream == nil: response.flags.incl(rfBodyUsed) response.onFinish(response, true) return opaque.contentType = response.getContentType() opaque.p = alloc(BufferSize) opaque.size = BufferSize response.onRead = onReadBlob response.flags.incl(rfBodyUsed) loader.resume(response) proc jsFinish0(opaque: JSBlobOpaque; val: JSValue) = let ctx = opaque.ctx let resolve = opaque.resolveVal let reject = opaque.rejectVal opaque.resolve = nil opaque.reject = nil opaque.ctx = nil if not JS_IsException(val): let res = ctx.callSink(resolve, JS_UNDEFINED, val) JS_FreeValue(ctx, res) else: discard ctx.enqueueRejection(reject) JS_FreeValue(ctx, resolve) JS_FreeValue(ctx, reject) JS_FreeContext(ctx) proc jsBlobFinish(response: Response; success: bool) = let blob = response.onFinishBlob(success) let opaque = JSBlobOpaque(response.opaque) let ctx = opaque.ctx let val = if blob != nil: ctx.toJS(blob) else: JS_ThrowTypeError(ctx, "error reading response body") jsFinish0(opaque, val) proc blob0(ctx: JSContext; response: Response; finish: ResponseFinish): JSValue = var funs {.noinit.}: array[2, JSValue] let res = ctx.newPromiseCapability(funs) if JS_IsException(res): return res let opaque = JSBlobOpaque( ctx: JS_DupContext(ctx), resolve: JS_VALUE_GET_PTR(funs[0]), reject: JS_VALUE_GET_PTR(funs[1]) ) response.onFinish = finish let loader = ctx.getLoaderImpl() loader.blob(response, opaque) return res proc blob(ctx: JSContext; response: Response): JSValue {.jsfunc.} = return ctx.blob0(response, jsBlobFinish) proc onFinishText(response: Response; success: bool) = let blob = response.onFinishBlob(success) let opaque = JSBlobOpaque(response.opaque) let ctx = opaque.ctx let val = if blob != nil: ctx.toJS(blob.toOpenArray().toValidUTF8()) else: JS_ThrowTypeError(ctx, "error reading response body") jsFinish0(opaque, val) proc text(ctx: JSContext; response: Response): JSValue {.jsfunc.} = return ctx.blob0(response, onFinishText) proc onFinishJSON(response: Response; success: bool) = let blob = response.onFinishBlob(success) let opaque = JSBlobOpaque(response.opaque) let ctx = opaque.ctx let val = if blob != nil: let s = blob.toOpenArray().toValidUTF8() JS_ParseJSON(ctx, cstring(s), csize_t(s.len), cstring"<input>") else: JS_ThrowTypeError(ctx, "error reading response body") jsFinish0(opaque, val) proc json(ctx: JSContext; this: Response): JSValue {.jsfunc.} = return ctx.blob0(this, onFinishJSON) proc addResponseModule*(ctx: JSContext): JSClassID = return ctx.registerType(Response) proc getRedirect*(response: Response; request: Request): Request = if response.status in 301u16..303u16 or response.status in 307u16..308u16: let location = response.headers.getFirst("Location") if url := parseURL(location, request.url): let status = response.status if status == 303 and request.httpMethod notin {hmGet, hmHead} or status == 301 or status == 302 and request.httpMethod == hmPost: return newRequest(url, hmGet) return newRequest(url, request.httpMethod, body = request.body) return nil # Sometimes, we can return a value even after the loader crashed. # This improves reliability of the pager. template withPacketWriter(loader: FileLoader; w, body, fallback: untyped) = loader.controlStream.withPacketWriter w: body do: fallback template withPacketWriterFire(loader: FileLoader; w, body: untyped) = loader.controlStream.withPacketWriterFire w: body template withPacketReaderFire(loader: FileLoader; r, body: untyped) = loader.controlStream.withPacketReaderFire r: body # Start a request. This should not block (not for a significant amount # of time anyway). proc startRequest(loader: FileLoader; request: Request): PosixStream = loader.withPacketWriter w: w.swrite(lcLoad) w.swrite(request) do: return nil var success = false var fd: cint loader.withPacketReaderFire r: r.sread(success) if success: fd = r.recvFd() if success: let res = newPosixStream(fd) res.setCloseOnExec() return res return nil proc startRequest*(loader: FileLoader; request: Request; config: LoaderClientConfig): PosixStream = loader.withPacketWriter w: w.swrite(lcLoadConfig) w.swrite(request) w.swrite(config) do: return nil var fd = cint(-1) loader.withPacketReaderFire r: var success: bool r.sread(success) if success: fd = r.recvFd() if fd != -1: return newPosixStream(fd) nil iterator data*(loader: FileLoader): MapData {.inline.} = for it in loader.map: if it != nil: yield it iterator ongoing*(loader: FileLoader): Response {.inline.} = for it in loader.data: if it of Response: yield Response(it) proc put*(loader: FileLoader; data: MapData) = let fd = int(data.stream.fd) if loader.map.len <= fd: loader.map.setLen(fd + 1) assert loader.map[fd] == nil loader.map[fd] = data if data of LoaderData: inc loader.mapFds proc get*(loader: FileLoader; fd: cint): MapData = if fd < loader.map.len: return loader.map[fd] return nil proc unset*(loader: FileLoader; fd: cint) = if loader.map[fd] != nil and loader.map[fd] of LoaderData: dec loader.mapFds loader.map[fd] = nil proc unset*(loader: FileLoader; data: MapData) = let fd = data.stream.fd if loader.get(fd) != nil: loader.unset(fd) proc hasFds*(loader: FileLoader): bool = return loader.mapFds > 0 or loader.registerQueue.len > 0 proc register*(loader: FileLoader; data: MapData; events: cshort) = if loader.registerBlocked: loader.registerQueue.add((data, events)) else: loader.pollData.register(data.stream.fd, events) loader.put(data) proc register(loader: FileLoader; data: ConnectData) = loader.register(data, POLLIN) proc unregister*(loader: FileLoader; fd: cint) = loader.pollData.unregister(fd) loader.unregistered.add(fd) #TODO ideally this should be the only exposed unregister function # (unset + unregister on fd belong together) proc unregister*(loader: FileLoader; data: MapData) = loader.unset(data) loader.unregister(data.stream.fd) proc blockRegister*(loader: FileLoader) = assert not loader.registerBlocked loader.registerBlocked = true proc unblockRegister*(loader: FileLoader) = assert loader.registerBlocked loader.registerBlocked = false for it in loader.registerQueue: loader.register(it.data, it.events) loader.registerQueue.setLen(0) proc fetch0(loader: FileLoader; input: Request; finish: FetchFinish; opaque: RootRef; redirectNum = 0) = let stream = loader.startRequest(input) if stream != nil: loader.register(ConnectData( opaque: opaque, finish: finish, request: input, stream: stream, redirectNum: redirectNum )) proc fetch*(loader: FileLoader; input: Request; finish: FetchFinish; opaque: RootRef) = loader.fetch0(input, finish, opaque, 0) proc suspend*(loader: FileLoader; fds: seq[int]) = loader.withPacketWriterFire w: w.swrite(lcSuspend) w.swrite(fds) proc resume*(loader: FileLoader; outputIds: openArray[int]) = loader.withPacketWriterFire w: w.swrite(lcResume) w.swrite(outputIds) proc resume*(loader: FileLoader; outputId: int) = loader.resume([outputId]) proc tee*(loader: FileLoader; sourceId, targetPid: int): (PosixStream, int) = loader.withPacketWriter w: w.swrite(lcTee) w.swrite(sourceId) w.swrite(targetPid) do: return (nil, -1) var outputId: int var fd = cint(-1) loader.withPacketReaderFire r: r.sread(outputId) if outputId != -1: fd = r.recvFd() if fd != -1: return (newPosixStream(fd), outputId) return (nil, -1) proc addCacheFile*(loader: FileLoader; outputId: int): int = loader.withPacketWriter w: w.swrite(lcAddCacheFile) w.swrite(outputId) do: return -1 var cacheId = -1 loader.withPacketReaderFire r: r.sread(cacheId) return cacheId proc getCacheFile*(loader: FileLoader; cacheId, sourcePid: int): string = loader.withPacketWriter w: w.swrite(lcGetCacheFile) w.swrite(cacheId) w.swrite(sourcePid) do: return "" var s = "" loader.withPacketReaderFire r: r.sread(s) move(s) proc redirectToFile*(loader: FileLoader; outputId: int; targetPath: string; displayUrl: URL): bool = loader.withPacketWriter w: w.swrite(lcRedirectToFile) w.swrite(outputId) w.swrite(targetPath) w.swrite($displayUrl) do: return false var res = false loader.withPacketReaderFire r: r.sread(res) return res proc onConnected(loader: FileLoader; connectData: ConnectData) = let stream = connectData.stream let finish = connectData.finish let opaque = connectData.opaque let request = connectData.request stream.withPacketReader r: case connectData.state of cdsBeforeResult: var res: int r.sread(res) # packet 1 if res == 0: r.sread(connectData.outputId) # packet 1 inc connectData.state else: var msg: string # msg is discarded. r.sread(msg) # packet 1 let fd = connectData.stream.fd loader.unregister(fd) stream.sclose() # delete before resolving the promise loader.unset(connectData) finish(opaque, nil) of cdsBeforeStatus: let response = newResponse(request, stream, connectData.outputId) # packet 2 r.sread(response.status) r.sreadList(response.headers) # Only a stream of the response body may arrive after this point. response.stream = stream # delete before resolving the promise loader.unset(connectData) loader.put(response) stream.setBlocking(false) let redirect = response.getRedirect(request) if redirect != nil: loader.unregister(response) stream.sclose() let redirectNum = connectData.redirectNum + 1 if redirectNum < 5: #TODO use config.network.max_redirect? loader.fetch0(redirect, finish, opaque, redirectNum) else: finish(opaque, nil) else: finish(opaque, response) do: # loader died loader.unregister(connectData.stream.fd) stream.sclose() # delete before resolving the promise loader.unset(connectData) finish(opaque, nil) proc onRead*(loader: FileLoader; response: Response) = response.onRead(response) if response.stream.isend: if response.onFinish != nil: response.onFinish(response, true) response.onFinish = nil loader.close(response) proc onRead*(loader: FileLoader; fd: int) = let data = loader.map[fd] if data of ConnectData: loader.onConnected(ConnectData(data)) else: loader.onRead(Response(data)) proc onError*(loader: FileLoader; response: Response) = if response.onFinish != nil: response.onFinish(response, true) response.onFinish = nil loader.close(response) proc onError*(loader: FileLoader; fd: int): bool = let data = loader.map[fd] if data of ConnectData: # probably shouldn't happen. TODO return false else: loader.onError(Response(data)) return true # Note: this blocks until headers are received. proc doRequest*(loader: FileLoader; request: Request): Response = let stream = loader.startRequest(request) let response = newResponse(request, nil, -1) var r: PacketReader if stream != nil and stream.initPacketReader(r): var res: int r.sread(res) # packet 1 if res == 0: r.sread(response.outputId) # packet 1 if stream.initPacketReader(r): # packet 2 r.sread(response.status) r.sreadList(response.headers) # Only a stream of the response body may arrive after this point. response.stream = stream else: # EOF stream.sclose() else: var msg: string r.sread(msg) # packet 1 stream.sclose() else: # EOF if stream != nil: stream.sclose() return response proc shareCachedItem*(loader: FileLoader; id, targetPid: int; sourcePid = -1): bool = let sourcePid = if sourcePid != -1: sourcePid else: loader.clientPid loader.withPacketWriterFire w: w.swrite(lcShareCachedItem) w.swrite(sourcePid) w.swrite(targetPid) w.swrite(id) var success = false loader.withPacketReaderFire r: r.sread(success) return success proc openCachedItem*(loader: FileLoader; cacheId: int): PosixStream = loader.withPacketWriter w: w.swrite(lcOpenCachedItem) w.swrite(cacheId) do: return nil var fd = cint(-1) loader.withPacketReaderFire r: var success: bool r.sread(success) if success: fd = r.recvFd() if fd != -1: return newPosixStream(fd) return nil proc passFd*(loader: FileLoader; id: string; fd: cint) = loader.withPacketWriterFire w: w.swrite(lcPassFd) w.swrite(id) w.sendFd(fd) proc removeCachedItem*(loader: FileLoader; cacheId: int) = loader.withPacketWriterFire w: w.swrite(lcRemoveCachedItem) w.swrite(cacheId) proc addAuth*(loader: FileLoader; url: URL) = loader.withPacketWriterFire w: w.swrite(lcAddAuth) w.swrite(url) proc addClient*(loader: FileLoader; pid: int; config: LoaderClientConfig): PosixStream = loader.withPacketWriter w: w.swrite(lcAddClient) w.swrite(pid) w.swrite(config) do: return nil var success = false var fd: cint loader.withPacketReaderFire r: r.sread(success) if success: fd = r.recvFd() if success: return newPosixStream(fd) return nil proc removeClient*(loader: FileLoader; pid: int) = loader.withPacketWriterFire w: w.swrite(lcRemoveClient) w.swrite(pid) # Equivalent to creating a pipe and passing its read half of it through # passFd. proc addPipe*(loader: FileLoader; id: string): PosixStream = loader.withPacketWriter w: w.swrite(lcAddPipe) w.swrite(id) do: return nil var fd: cint = -1 loader.withPacketReaderFire r: var success: bool r.sread(success) if success: fd = r.recvFd() if fd != -1: return newPosixStream(fd) return nil proc doPipeRequest*(loader: FileLoader; id: string): tuple[ps: PosixStream; response: Response] = let ps = loader.addPipe(id) if ps == nil: return (nil, nil) let request = newRequest("stream:" & id) let response = loader.doRequest(request) if response.stream == nil: ps.sclose() return (nil, nil) return (ps, response) proc newFileLoader*(clientPid: int; controlStream: PosixStream): FileLoader = return FileLoader( clientPid: clientPid, controlStream: controlStream ) {.pop.} ��������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/server/request.nim����������������������������������������������������������������0000664�0000000�0000000�00000023753�15202323131�0017436�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import html/script import io/packetreader import io/packetwriter import monoucha/fromjs import monoucha/jsbind import monoucha/jstypes import monoucha/quickjs import monoucha/tojs import server/headers import types/blob import types/formdata import types/jsopt import types/opt import types/url type HttpMethod* = enum hmGet = "GET" hmConnect = "CONNECT" hmDelete = "DELETE" hmHead = "HEAD" hmOptions = "OPTIONS" hmPatch = "PATCH" hmPost = "POST" hmPut = "PUT" hmTrace = "TRACE" hmTrack = "TRACK" RequestMode* = enum rmNoCors = "no-cors" rmSameOrigin = "same-origin" rmCors = "cors" rmNavigate = "navigate" rmWebsocket = "websocket" CORSAttribute* = enum caNoCors = "no-cors" caAnonymous = "anonymous" caUseCredentials = "use-credentials" type RequestOriginType* = enum rotClient, rotOrigin RequestOrigin* = object case t*: RequestOriginType of rotClient: discard of rotOrigin: origin*: Origin RequestWindowType* = enum rwtClient, rwtNoWindow, rwtWindow RequestWindow* = object case t*: RequestWindowType of rwtClient, rwtNoWindow: discard of rwtWindow: window*: EnvironmentSettings RequestBodyType* = enum rbtNone, rbtString, rbtBlob, rbtMultipart, rbtOutput, rbtCache RequestBody* = object case t*: RequestBodyType of rbtNone: discard of rbtString: s*: string of rbtMultipart: multipart*: FormData of rbtOutput: outputId*: int of rbtCache: cacheId*: int of rbtBlob: blob*: Blob RawRequest* = object url*: URL headers*: seq[HTTPHeader] body*: RequestBody httpMethod* {.jsget: "method".}: HttpMethod tocache*: bool urlCredentials*: bool credentials* {.jsget: "credentials".}: CredentialsMode Request* = ref object # RawRequest url*: URL headers* {.jsget.}: Headers body*: RequestBody httpMethod* {.jsget: "method".}: HttpMethod tocache*: bool urlCredentials*: bool # whether to use user/pass in URL credentials* {.jsget: "credentials".}: CredentialsMode # client-specific mode* {.jsget.}: RequestMode destination* {.jsget.}: RequestDestination origin*: RequestOrigin window*: RequestWindow client*: EnvironmentSettings jsDestructor(Request) # Forward declaration hack var getAPIBaseURLImpl*: proc(ctx: JSContext): URL {.nimcall, raises: [].} proc swrite*(w: var PacketWriter; o: RequestBody) = w.swrite(o.t) case o.t of rbtNone: discard of rbtString: w.swrite(o.s) of rbtBlob: w.swrite(o.blob) of rbtMultipart: w.swrite(o.multipart) of rbtOutput: w.swrite(o.outputId) of rbtCache: w.swrite(o.cacheId) proc sread*(r: var PacketReader; o: var RequestBody) = var t: RequestBodyType r.sread(t) o = RequestBody(t: t) case t of rbtNone: discard of rbtString: r.sread(o.s) of rbtBlob: r.sread(o.blob) of rbtMultipart: r.sread(o.multipart) of rbtOutput: r.sread(o.outputId) of rbtCache: r.sread(o.cacheId) proc swrite*(w: var PacketWriter; o: Request) = w.swrite(o.url) w.swriteList(o.headers) w.swrite(o.body) w.swrite(o.httpMethod) w.swrite(o.tocache) w.swrite(o.urlCredentials) w.swrite(o.credentials) proc sread*(w: var PacketReader; o: var Request) {. error: "use RawRequest instead".} = discard proc sread*(r: var PacketReader; o: var RawRequest) = r.sread(o.url) r.sread(o.headers) r.sread(o.body) r.sread(o.httpMethod) r.sread(o.tocache) r.sread(o.urlCredentials) r.sread(o.credentials) proc contentLength*(body: RequestBody): int = case body.t of rbtString: return body.s.len of rbtBlob: return body.blob.size of rbtMultipart: return body.multipart.calcLength() of rbtNone, rbtOutput, rbtCache: return 0 proc jsUrl(this: Request): string {.jsfget: "url".} = return $this.url #TODO pretty sure this is incorrect proc referrer(this: Request): string {.jsfget.} = return this.headers.getFirst("Referer") proc getReferrer*(this: Request): URL = return parseURL0(this.headers.getFirst("Referer")) proc newRequest*(url: URL; httpMethod = hmGet; headers = newHeaders(hgRequest); body = RequestBody(); referrer: URL = nil; tocache = false; credentials = cmSameOrigin; urlCredentials = false; destination = rdNone; mode = rmNoCors; window = RequestWindow(t: rwtNoWindow)): Request = assert url != nil if referrer != nil: headers["Referer"] = $referrer return Request( url: url, httpMethod: httpMethod, headers: headers, body: body, tocache: tocache, urlCredentials: urlCredentials, credentials: credentials, destination: destination, mode: mode ) proc newRequest*(raw: RawRequest): Request = return newRequest(raw.url, raw.httpMethod, newHeaders(hgRequest, raw.headers), raw.body, tocache = raw.tocache, credentials = raw.credentials, urlCredentials = raw.urlCredentials) proc newRequest*(s: string; httpMethod = hmGet; headers = newHeaders(hgRequest); body = RequestBody(); referrer: URL = nil; tocache = false; credentials = cmSameOrigin): Request = return newRequest(parseURL0(s), httpMethod, headers, body, referrer, tocache, credentials) proc createPotentialCORSRequest*(url: URL; destination: RequestDestination; cors: CORSAttribute; fallbackFlag = false): Request = var mode = if cors == caNoCors: rmNoCors else: rmCors if fallbackFlag and mode == rmNoCors: mode = rmSameOrigin let credentials = if cors == caAnonymous: cmSameOrigin else: cmInclude return newRequest(url, credentials = credentials, destination = destination, mode = mode) type BodyInitType = enum bitNull, bitBlob, bitFormData, bitUrlSearchParams, bitString BodyInit* = object #TODO ReadableStream, BufferSource case t: BodyInitType of bitNull: discard of bitBlob: blob: Blob of bitFormData: formData: FormData of bitUrlSearchParams: searchParams: URLSearchParams of bitString: s: string RequestInit = object of JSDict `method` {.jsdefault: JS_UNDEFINED.}: JSValueConst headers {.jsdefault.}: HeadersInit body {.jsdefault.}: BodyInit referrer {.jsdefault: JS_UNDEFINED.}: JSValueConst referrerPolicy {.jsdefault: JS_UNDEFINED.}: JSValueConst credentials {.jsdefault: JS_UNDEFINED.}: JSValueConst mode {.jsdefault: JS_UNDEFINED.}: JSValueConst window {.jsdefault: JS_UNDEFINED.}: JSValueConst proc fromJS*(ctx: JSContext; val: JSValueConst; res: var BodyInit): FromJSResult = if JS_IsNull(val): res = BodyInit(t: bitNull) return fjOk res = BodyInit(t: bitFormData) if ctx.fromJS(val, res.formData).isOk: return fjOk res = BodyInit(t: bitBlob) if ctx.fromJS(val, res.blob).isOk: return fjOk res = BodyInit(t: bitUrlSearchParams) if ctx.fromJS(val, res.searchParams).isOk: return fjOk res = BodyInit(t: bitString) ctx.fromJS(val, res.s) # Returns the content type proc extract*(init: BodyInit; body: var RequestBody): string = case init.t of bitNull: return "" of bitFormData: body = RequestBody(t: rbtMultipart, multipart: init.formData) return init.formData.getContentType() of bitString: body = RequestBody(t: rbtString, s: init.s) return "text/plain;charset=UTF-8" of bitUrlSearchParams: body = RequestBody(t: rbtString, s: $init.searchParams) return "application/x-www-form-urlencoded;charset=UTF-8" of bitBlob: body = RequestBody(t: rbtBlob, blob: init.blob) return init.blob.ctype proc safeExtract*(init: BodyInit; body: var RequestBody): string = #TODO check for ReadableStream once we have it init.extract(body) proc newRequest*(ctx: JSContext; resource: JSValueConst; jsInit: JSValueConst = JS_UNDEFINED): Opt[Request] {.jsctor.} = var init: RequestInit ?ctx.fromJS(jsInit, init) var headers = newHeaders(hgRequest) var window = RequestWindow(t: rwtClient) var body = RequestBody() var credentials = cmSameOrigin var httpMethod = hmGet if not JS_IsUndefined(init.credentials): ?ctx.fromJS(init.credentials, credentials) if not JS_IsUndefined(init.`method`): #TODO the spec allows this to be any string :( ?ctx.fromJS(init.method, httpMethod) var referrer: URL = nil var url: URL = nil var mode = rmNoCors if not JS_IsUndefined(init.mode): ?ctx.fromJS(init.mode, mode) if (var res: Request; ctx.fromJS(resource, res).isOk): url = res.url if JS_IsUndefined(init.`method`): httpMethod = res.httpMethod headers[] = res.headers[] referrer = res.getReferrer() if JS_IsUndefined(init.credentials): credentials = res.credentials body = res.body if JS_IsUndefined(init.mode): mode = rmCors window = res.window else: var s: string ?ctx.fromJS(resource, s) url = ?ctx.parseJSURL(s, ctx.getAPIBaseURLImpl()) if url.username != "" or url.password != "": JS_ThrowTypeError(ctx, "input URL contains a username or password") return err() let destination = rdNone #TODO origin, window if not JS_IsUndefined(init.window): if not JS_IsNull(init.window): JS_ThrowTypeError(ctx, "expected window to be null") return err() window = RequestWindow(t: rwtNoWindow) if mode == rmNavigate: mode = rmSameOrigin #TODO flags? #TODO referrer if init.body.t != bitNull and httpMethod in {hmGet, hmHead}: JS_ThrowTypeError(ctx, "HEAD or GET requests cannot have a body") return err() ?ctx.fill(headers, init.headers) let contentType = init.body.extract(body) if contentType != "": headers.addIfNotFound("Content-Type", contentType) if mode == rmNoCors: headers.guard = hgRequestNoCors ok(newRequest( url, httpMethod, headers, body, referrer = referrer, credentials = credentials, mode = mode, destination = destination, window = window )) proc credentials*(attribute: CORSAttribute): CredentialsMode = case attribute of caNoCors, caAnonymous: return cmSameOrigin of caUseCredentials: return cmInclude proc addRequestModule*(ctx: JSContext): Opt[void] = ?ctx.registerType(Request) ok() {.pop.} # raises: [] ���������������������chawan-v0.4.0/src/types/����������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0015065�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/types/bitmap.nim������������������������������������������������������������������0000664�0000000�0000000�00000000243�15202323131�0017045�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������type NetworkBitmap* = ref object width*: int height*: int cacheId*: int imageId*: int vector*: bool # not a bitmap? contentType*: string �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/types/blob.nim��������������������������������������������������������������������0000664�0000000�0000000�00000010053�15202323131�0016507�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/posix import config/mimetypes import io/packetreader import io/packetwriter import io/timeout import monoucha/fromjs import monoucha/jsbind import monoucha/jstypes import monoucha/quickjs import monoucha/tojs import types/jsopt import types/opt import utils/twtstr type DeallocFun = proc(opaque, p: pointer) {.nimcall, raises: [].} Blob* = ref object of RootObj size* {.jsget.}: int ctype* {.jsget: "type".}: string buffer*: pointer opaque*: pointer deallocFun*: DeallocFun WebFile* = ref object of Blob webkitRelativePath {.jsget.}: string name* {.jsget.}: string lastModified* {.jsget.}: int64 fd*: cint jsDestructor(Blob) jsDestructor(WebFile) # Forward declarations proc deallocBlob*(opaque, p: pointer) proc swrite*(w: var PacketWriter; blob: Blob) = w.swrite(blob of WebFile) if blob of WebFile: let file = WebFile(blob) let fd = dup(file.fd) w.swrite(fd != -1) if fd != -1: w.sendFd(fd) w.swrite(file.name) w.swrite(blob.ctype) w.swrite(blob.size) if blob.size > 0: w.writeData(blob.buffer, blob.size) proc sread*(r: var PacketReader; blob: var Blob) = var isWebFile: bool r.sread(isWebFile) blob = if isWebFile: WebFile() else: Blob() if isWebFile: let file = WebFile(blob) var hasFd: bool r.sread(hasFd) if hasFd: file.fd = r.recvFd() else: file.fd = -1 r.sread(file.name) r.sread(blob.ctype) r.sread(blob.size) if blob.size > 0: let buffer = alloc(blob.size) r.readData(buffer, blob.size) blob.buffer = buffer blob.deallocFun = deallocBlob proc newBlob*(buffer: pointer; size: int; ctype: string; deallocFun: DeallocFun; opaque: pointer = nil): Blob = return Blob( buffer: buffer, size: size, ctype: ctype, deallocFun: deallocFun, opaque: opaque ) proc newEmptyBlob*(contentType = ""): Blob = return newBlob(nil, 0, contentType, nil) proc deallocBlob*(opaque, p: pointer) = if p != nil: dealloc(p) template toOpenArray*(blob: Blob): openArray[char] = let p = cast[ptr UncheckedArray[char]](blob.buffer) if p != nil: p.toOpenArray(0, blob.size - 1) else: [] proc finalize(blob: Blob) {.jsfin.} = if blob.deallocFun != nil: blob.deallocFun(blob.opaque, blob.buffer) blob.buffer = nil proc finalize(file: WebFile) {.jsfin.} = if file.fd != -1: discard close(file.fd) proc newWebFile*(name: string; fd: cint): WebFile = return WebFile( name: name, fd: fd, ctype: DefaultGuess.guessContentType(name) ) type BlobPropertyBag = object of JSDict `type` {.jsdefault.}: string #TODO endings FilePropertyBag = object of BlobPropertyBag lastModified {.jsdefault: getUnixMillis().}: int64 proc newWebFile(ctx: JSContext; fileBits: seq[string]; fileName: string; options = FilePropertyBag(lastModified: getUnixMillis())): WebFile {.jsctor.} = let file = WebFile( name: fileName, fd: -1, lastModified: options.lastModified ) var len = 0 for blobPart in fileBits: len += blobPart.len let buffer = alloc(len) file.buffer = buffer file.deallocFun = deallocBlob var buf = cast[ptr UncheckedArray[uint8]](file.buffer) var i = 0 for blobPart in fileBits: if blobPart.len > 0: copyMem(addr buf[i], unsafeAddr blobPart[0], blobPart.len) i += blobPart.len file.size = len block ctype: for c in options.`type`: if c notin char(0x20)..char(0x7E): break ctype file.ctype &= c.toLowerAscii() return file #TODO Blob constructor proc getSize*(this: Blob): int = if this of WebFile: let file = WebFile(this) if file.fd != -1: var statbuf: Stat if fstat(file.fd, statbuf) < 0: return 0 return int(statbuf.st_size) return this.size proc size*(this: WebFile): int {.jsfget.} = return this.getSize() #TODO lastModified proc addBlobModule*(ctx: JSContext): Opt[void] = let blobCID = ctx.registerType(Blob) if blobCID == 0: return err() ?ctx.registerType(WebFile, parent = blobCID, name = "File") ok() {.pop.} # raises: [] �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/types/canvastypes.nim�������������������������������������������������������������0000664�0000000�0000000�00000000534�15202323131�0020134�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������type CanvasFillRule* = enum cfrNonZero = "nonzero" cfrEvenOdd = "evenodd" PaintCommand* = enum pcSetDimensions, pcFillRect, pcStrokeRect, pcFillPath, pcStrokePath, pcFillText, pcStrokeText CanvasTextAlign* = enum ctaStart = "start" ctaEnd = "end" ctaLeft = "left" ctaRight = "right" ctaCenter = "center" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/types/cell.nim��������������������������������������������������������������������0000664�0000000�0000000�00000007336�15202323131�0016522�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import types/color import utils/strwidth type FormatFlag* = enum ffBold = "bold" ffItalic = "italic" ffUnderline = "underline" ffReverse = "reverse" ffStrike = "strike" ffOverline = "overline" ffBlink = "blink" FormatMode* = set[FormatFlag] Format* = object u: uint64 SimpleFormatCell* = object format*: Format pos*: int SimpleFlexibleLine* = object str*: string formats*: seq[SimpleFormatCell] SimpleFlexibleGrid* = seq[SimpleFlexibleLine] FixedCell* = object str*: string format*: Format FixedGrid* = object width*, height*: int cells*: seq[FixedCell] proc `[]=`*(grid: var FixedGrid; i: int; cell: FixedCell) = grid.cells[i] = cell proc `[]=`*(grid: var FixedGrid; i: BackwardsIndex; cell: FixedCell) = grid.cells[i] = cell proc `[]`*(grid: var FixedGrid; i: int): var FixedCell = grid.cells[i] proc `[]`*(grid: var FixedGrid; i: BackwardsIndex): var FixedCell = grid.cells[i] proc `[]`*(grid: FixedGrid; i: int): lent FixedCell = grid.cells[i] proc `[]`*(grid: FixedGrid; i: BackwardsIndex): lent FixedCell = return grid.cells[grid.cells.len - int(i)] proc len*(grid: FixedGrid): int {.inline.} = grid.cells.len proc high*(grid: FixedGrid): int {.inline.} = grid.cells.high template bgcolor*(format: Format): CellColor = CellColor(format.u and 0x3FFFFFF) template fgcolor*(format: Format): CellColor = CellColor((format.u shr 26) and 0x3FFFFFF) template flags*(format: Format): FormatMode = cast[FormatMode](format.u shr 52) template `bgcolor=`*(format: var Format; bgcolor: CellColor) = format.u = format.u and static(not 0x3FFFFFFu64) or uint64(bgcolor) template `fgcolor=`*(format: var Format; fgcolor: CellColor) = format.u = format.u and static(not (0x3FFFFFFu64 shl 26)) or (uint64(fgcolor) shl 26) template `flags=`*(format: var Format; flags: FormatMode) = format.u = format.u and static(not (0xFFFu64 shl 52)) or (cast[uint64](flags) shl 52) template incl*(format: var Format; flag: FormatFlag) = format.u = format.u or (cast[uint64]({flag}) shl 52) template excl*(format: var Format; flag: FormatFlag) = format.u = format.u and not (cast[uint64]({flag}) shl 52) proc `$`*(format: Format): string = return "(bg: " & $format.bgcolor & ", fg: " & $format.fgcolor & ", flags: " & $format.flags & ")" static: doAssert {FormatFlag.low..FormatFlag.high}.card <= 12 proc initFormat*(bgcolor, fgcolor: CellColor; flags: FormatMode): Format = return Format( u: uint64(bgcolor.toUint26()) or (uint64(fgcolor.toUint26()) shl 26) or (cast[uint64](flags) shl 52) ) proc initFormat*(): Format = return initFormat(defaultColor, defaultColor, {}) iterator items*(grid: FixedGrid): lent FixedCell {.inline.} = for cell in grid.cells: yield cell iterator mline*(grid: var FixedGrid; y: int; startx = 0): var FixedCell {.inline.} = let dls = y * grid.width for cell in grid.cells.toOpenArray(dls + startx, dls + grid.width - 1).mitems: yield cell proc newFixedGrid*(w, h: int): FixedGrid = return FixedGrid(width: w, height: h, cells: newSeq[FixedCell](w * h)) proc width*(cell: FixedCell): int = return cell.str.width() # Get the first format cell after pos, if any. proc findFormatN*(line: SimpleFlexibleLine; pos: int): int = var i = 0 while i < line.formats.len: if line.formats[i].pos > pos: break inc i return i proc findFormat*(line: SimpleFlexibleLine; pos: int): SimpleFormatCell = let i = line.findFormatN(pos) - 1 if i != -1: return line.formats[i] return SimpleFormatCell(pos: -1) proc findNextFormat*(line: SimpleFlexibleLine; pos: int): SimpleFormatCell = let i = line.findFormatN(pos) if i < line.formats.len: return line.formats[i] return SimpleFormatCell(pos: -1) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/types/color.nim�������������������������������������������������������������������0000664�0000000�0000000�00000042771�15202323131�0016723�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/algorithm import types/opt import utils/dtoawrap import utils/twtstr type RGBColor* = distinct uint32 # ARGB color. machine-dependent format, so that bit shifts and arithmetic # works. (Alpha is MSB, then come R, G, B.) ARGBColor* = distinct uint32 # RGBA format; machine-independent, always big-endian. RGBAColorBE* {.packed.} = object r*: uint8 g*: uint8 b*: uint8 a*: uint8 # Either a 3-bit ANSI color (0..7), a 3-bit bright ANSI color (8..15), # a color on the RGB cube (16..231), or a grayscale color (232..255). ANSIColor* = distinct uint8 # ctNone: default color (intentionally 0), n is unused # ctANSI: ANSI color, as selected by SGR 38/48 # ctRGB: RGB color ColorTag* = enum ctNone, ctANSI, ctRGB # Color that can be represented by a terminal cell. # Crucially, this does not include colors with an alpha channel. CellColor* = distinct uint32 CSSColorType* = enum cctARGB, cctCell, cctCurrent # Color that can be represented in CSS. # As an extension, we also recognize ANSI colors, so ARGB does not suffice. # (Actually, it would, but then we'd have to copy over the ANSI color # table and then re-quantize on render. I'm fine with wasting a few # bytes instead.) CSSColor* = object t*: CSSColorType n: uint32 proc rgba*(r, g, b, a: uint8): ARGBColor # bitmasked so nimvm doesn't choke on it proc r*(c: ARGBColor): uint8 = return uint8((uint32(c) shr 16) and 0xFF) proc g*(c: ARGBColor): uint8 = return uint8((uint32(c) shr 8) and 0xFF) proc b*(c: ARGBColor): uint8 = return uint8((uint32(c) and 0xFF)) proc a*(c: ARGBColor): uint8 = return uint8(uint32(c) shr 24) proc rgb*(c: ARGBColor): RGBColor = return RGBColor(uint32(c) and 0xFFFFFFu32) proc argb*(c: RGBColor; a: uint8): ARGBColor = return ARGBColor((uint32(c) and 0x00FFFFFFu32) or (uint32(a) shl 24)) proc argb*(c: RGBColor): ARGBColor = return ARGBColor(uint32(c) or 0xFF000000u32) proc argb*(c: RGBAColorBE): ARGBColor = return rgba(c.r, c.g, c.b, c.a) proc `==`*(a, b: ARGBColor): bool {.borrow.} proc `==`*(a, b: RGBColor): bool {.borrow.} proc `==`*(a, b: ANSIColor): bool {.borrow.} proc `==`*(a, b: CellColor): bool {.borrow.} proc t*(color: CellColor): ColorTag = return cast[ColorTag]((uint32(color) shr 24) and 0x3) proc toUint26*(color: CellColor): uint32 = return uint32(color) and 0x3FFFFFF proc rgb*(color: CellColor): RGBColor = return RGBColor(uint32(color) and 0xFFFFFF) proc ansi*(color: CellColor): ANSIColor = return ANSIColor(color) proc cellColor(t: ColorTag; n: uint32): CellColor = return CellColor((uint32(t) shl 24) or (n and 0xFFFFFF)) proc cellColor*(rgb: RGBColor): CellColor = return cellColor(ctRGB, uint32(rgb)) proc cellColor*(c: ANSIColor): CellColor = return cellColor(ctANSI, uint32(c)) const defaultColor* = cellColor(ctNone, 0) proc cssColor*(c: ARGBColor): CSSColor = return CSSColor(t: cctARGB, n: uint32(c)) proc cssColor*(c: RGBColor): CSSColor = return c.argb.cssColor() proc cssColor*(c: CellColor): CSSColor = return CSSColor(t: cctCell, n: uint32(c)) proc cssColor*(c: ANSIColor): CSSColor = return c.cellColor().cssColor() proc cssCurrentColor*(): CSSColor = return CSSColor(t: cctCurrent) proc argb*(c: CSSColor): ARGBColor = return ARGBColor(c.n) proc a*(c: CSSColor): uint8 = if c.t == cctCell: if CellColor(c.n).t == ctNone: return 0 return 255 return c.argb().a proc rgbTransparent*(c: CSSColor): bool = return c.t == cctARGB and c.argb().a == 0 proc cellColor*(c: CSSColor): CellColor = if c.t == cctCell: return CellColor(c.n) if c.argb.a == 0: return defaultColor return cellColor(ctRGB, c.n) const ColorsRGBMap = { "aliceblue": 0xF0F8FFu32, "antiquewhite": 0xFAEBD7u32, "aqua": 0x00FFFFu32, "aquamarine": 0x7FFFD4u32, "azure": 0xF0FFFFu32, "beige": 0xF5F5DCu32, "bisque": 0xFFE4C4u32, "black": 0x000000u32, "blanchedalmond": 0xFFEBCDu32, "blue": 0x0000FFu32, "blueviolet": 0x8A2BE2u32, "brown": 0xA52A2Au32, "burlywood": 0xDEB887u32, "cadetblue": 0x5F9EA0u32, "chartreuse": 0x7FFF00u32, "chocolate": 0xD2691Eu32, "coral": 0xFF7F50u32, "cornflowerblue": 0x6495EDu32, "cornsilk": 0xFFF8DCu32, "crimson": 0xDC143Cu32, "cyan": 0x00FFFFu32, "darkblue": 0x00008Bu32, "darkcyan": 0x008B8Bu32, "darkgoldenrod": 0xB8860Bu32, "darkgray": 0xA9A9A9u32, "darkgreen": 0x006400u32, "darkgrey": 0xA9A9A9u32, "darkkhaki": 0xBDB76Bu32, "darkmagenta": 0x8B008Bu32, "darkolivegreen": 0x556B2Fu32, "darkorange": 0xFF8C00u32, "darkorchid": 0x9932CCu32, "darkred": 0x8B0000u32, "darksalmon": 0xE9967Au32, "darkseagreen": 0x8FBC8Fu32, "darkslateblue": 0x483D8Bu32, "darkslategray": 0x2F4F4Fu32, "darkslategrey": 0x2F4F4Fu32, "darkturquoise": 0x00CED1u32, "darkviolet": 0x9400D3u32, "deeppink": 0xFF1493u32, "deepskyblue": 0x00BFFFu32, "dimgray": 0x696969u32, "dimgrey": 0x696969u32, "dodgerblue": 0x1E90FFu32, "firebrick": 0xB22222u32, "floralwhite": 0xFFFAF0u32, "forestgreen": 0x228B22u32, "fuchsia": 0xFF00FFu32, "gainsboro": 0xDCDCDCu32, "ghostwhite": 0xF8F8FFu32, "gold": 0xFFD700u32, "goldenrod": 0xDAA520u32, "gray": 0x808080u32, "green": 0x008000u32, "greenyellow": 0xADFF2Fu32, "grey": 0x808080u32, "honeydew": 0xF0FFF0u32, "hotpink": 0xFF69B4u32, "indianred": 0xCD5C5Cu32, "indigo": 0x4B0082u32, "ivory": 0xFFFFF0u32, "khaki": 0xF0E68Cu32, "lavender": 0xE6E6FAu32, "lavenderblush": 0xFFF0F5u32, "lawngreen": 0x7CFC00u32, "lemonchiffon": 0xFFFACDu32, "lightblue": 0xADD8E6u32, "lightcoral": 0xF08080u32, "lightcyan": 0xE0FFFFu32, "lightgoldenrodyellow": 0xFAFAD2u32, "lightgray": 0xD3D3D3u32, "lightgreen": 0x90EE90u32, "lightgrey": 0xD3D3D3u32, "lightpink": 0xFFB6C1u32, "lightsalmon": 0xFFA07Au32, "lightseagreen": 0x20B2AAu32, "lightskyblue": 0x87CEFAu32, "lightslategray": 0x778899u32, "lightslategrey": 0x778899u32, "lightsteelblue": 0xB0C4DEu32, "lightyellow": 0xFFFFE0u32, "lime": 0x00FF00u32, "limegreen": 0x32CD32u32, "linen": 0xFAF0E6u32, "magenta": 0xFF00FFu32, "maroon": 0x800000u32, "mediumaquamarine": 0x66CDAAu32, "mediumblue": 0x0000CDu32, "mediumorchid": 0xBA55D3u32, "mediumpurple": 0x9370DBu32, "mediumseagreen": 0x3CB371u32, "mediumslateblue": 0x7B68EEu32, "mediumspringgreen": 0x00FA9Au32, "mediumturquoise": 0x48D1CCu32, "mediumvioletred": 0xC71585u32, "midnightblue": 0x191970u32, "mintcream": 0xF5FFFAu32, "mistyrose": 0xFFE4E1u32, "moccasin": 0xFFE4B5u32, "navajowhite": 0xFFDEADu32, "navy": 0x000080u32, "oldlace": 0xFDF5E6u32, "olive": 0x808000u32, "olivedrab": 0x6B8E23u32, "orange": 0xFFA500u32, "orangered": 0xFF4500u32, "orchid": 0xDA70D6u32, "palegoldenrod": 0xEEE8AAu32, "palegreen": 0x98FB98u32, "paleturquoise": 0xAFEEEEu32, "palevioletred": 0xDB7093u32, "papayawhip": 0xFFEFD5u32, "peachpuff": 0xFFDAB9u32, "peru": 0xCD853Fu32, "pink": 0xFFC0CBu32, "plum": 0xDDA0DDu32, "powderblue": 0xB0E0E6u32, "purple": 0x800080u32, "rebeccapurple": 0x663399u32, "red": 0xFF0000u32, "rosybrown": 0xBC8F8Fu32, "royalblue": 0x4169E1u32, "saddlebrown": 0x8B4513u32, "salmon": 0xFA8072u32, "sandybrown": 0xF4A460u32, "seagreen": 0x2E8B57u32, "seashell": 0xFFF5EEu32, "sienna": 0xA0522Du32, "silver": 0xC0C0C0u32, "skyblue": 0x87CEEBu32, "slateblue": 0x6A5ACDu32, "slategray": 0x708090u32, "slategrey": 0x708090u32, "snow": 0xFFFAFAu32, "springgreen": 0x00FF7Fu32, "steelblue": 0x4682B4u32, "tan": 0xD2B48Cu32, "teal": 0x008080u32, "thistle": 0xD8BFD8u32, "tomato": 0xFF6347u32, "turquoise": 0x40E0D0u32, "violet": 0xEE82EEu32, "wheat": 0xF5DEB3u32, "white": 0xFFFFFFu32, "whitesmoke": 0xF5F5F5u32, "yellow": 0xFFFF00u32, "yellowgreen": 0x9ACD32u32, } proc namedRGBColor*(s: string): Opt[RGBColor] = let i = ColorsRGBMap.binarySearch(s, proc(x: (string, uint32); y: string): int = return x[0].cmpIgnoreCase(y) ) if i != -1: return ok(RGBColor(ColorsRGBMap[i][1])) return err() # https://html.spec.whatwg.org/#serialisation-of-a-color proc serialize*(c: ARGBColor): string = if c.a == 255: var res = "#" res.pushHex(c.r) res.pushHex(c.g) res.pushHex(c.b) return move(res) let a = float64(c.a) / 255 result = "rgba(" & $c.r & ", " & $c.g & ", " & $c.b & ", " result.addDouble(a) result &= ')' proc `$`*(c: ARGBColor): string = return c.serialize() proc `$`*(c: RGBColor): string = return c.argb().serialize() proc `$`*(c: CSSColor): string = case c.t of cctCell: return "-cha-ansi(" & $c.n & ")" of cctCurrent: return "currentcolor" of cctARGB: let c = c.argb() if c.a != 255: return c.serialize() return "rgb(" & $c.r & ", " & $c.g & ", " & $c.b & ")" proc `$`*(color: CellColor): string = case color.t of ctNone: "none" of ctRGB: $color.rgb of ctANSI: "-cha-ansi(" & $uint8(color.ansi()) & ")" # Divide each component by 255, multiply them by n, and discard the fractions. # See https://arxiv.org/pdf/2202.02864.pdf for details. proc fastmul*(c: ARGBColor; n: uint32): ARGBColor = var c = (uint64(c) shl 24) or uint64(c) c = c and 0x00FF00FF00FF00FFu64 c *= n c += 0x80008000800080u64 c += (c shr 8) and 0x00FF00FF00FF00FFu64 c = c and 0xFF00FF00FF00FF00u64 c = (c shr 32) or (c shr 8) return ARGBColor(c) proc premul(c: ARGBColor): ARGBColor = let a = uint32(c.a) let c = ARGBColor(uint32(c) or 0xFF000000u32) return c.fastmul(a) # This is somewhat faster than floats or a lookup table, and is correct for # all inputs. proc straight(c: ARGBColor): ARGBColor = let a8 = c.a if a8 == 0: return ARGBColor(0) let a = uint32(a8) let r = ((uint32(c.r) * 0xFF00 div a + 0x80) shr 8) and 0xFF let g = ((uint32(c.g) * 0xFF00 div a + 0x80) shr 8) and 0xFF let b = ((uint32(c.b) * 0xFF00 div a + 0x80) shr 8) and 0xFF return ARGBColor((a shl 24) or (r shl 16) or (g shl 8) or b) # Note: this is a very poor approximation, as the premultiplication # already discards fractions... proc blend*(c0, c1: ARGBColor): ARGBColor = let pc0 = c0.premul() let pc1 = c1.premul() let k = 255 - pc1.a let mc = pc0.fastmul(uint32(k)) let rr = pc1.r + mc.r let rg = pc1.g + mc.g let rb = pc1.b + mc.b let ra = pc1.a + mc.a let pres = rgba(rr, rg, rb, ra) return straight(pres) # Blending operation for cell colors. # Normally, this should only happen with RGB color, so if either color is # not one, we can just return fg. # sbg is the bgcolor of the canvas; we fall back to it if the cell's bgcolor # is empty, so that we hopefully get something meaningful back. # If we still end up with cellColor, we just blend over white which is the # canvas color on all mainstream browsers these days. proc blend*(bg, sbg, fg: CellColor; a: uint8): CellColor = if fg.t != ctRGB: return fg let bg = if bg.t == ctRGB: bg.rgb.argb elif sbg.t == ctRGB: sbg.rgb.argb else: rgba(255, 255, 255, 255) let fg = fg.rgb.argb(a) return bg.blend(fg).rgb.cellColor() proc rgb*(r, g, b: uint8): RGBColor = return RGBColor((uint32(r) shl 16) or (uint32(g) shl 8) or uint32(b)) proc r*(c: RGBColor): uint8 = return uint8(uint32(c) shr 16) proc g*(c: RGBColor): uint8 = return uint8(uint32(c) shr 8) proc b*(c: RGBColor): uint8 = return uint8(uint32(c)) # see https://learn.microsoft.com/en-us/previous-versions/windows/embedded/ms893078(v=msdn.10) proc Y*(c: RGBColor): uint8 = let rmul = uint16(c.r) * 66u16 let gmul = uint16(c.g) * 129u16 let bmul = uint16(c.b) * 25u16 return uint8(((rmul + gmul + bmul + 128) shr 8) + 16) proc U*(c: RGBColor): uint8 = let rmul = uint16(c.r) * 38u16 let gmul = uint16(c.g) * 74u16 let bmul = uint16(c.b) * 112u16 return uint8(((128 + bmul - rmul - gmul) shr 8) + 128) proc V*(c: RGBColor): uint8 = let rmul = uint16(c.r) * 112u16 let gmul = uint16(c.g) * 94u16 let bmul = uint16(c.b) * 18u16 return uint8(((128 + rmul - gmul - bmul) shr 8) + 128) proc YUV*(Y, U, V: uint8): RGBColor = let C = int(Y) - 16 let D = int(U) - 128 let E = int(V) - 128 let r = max(min((298 * C + 409 * E + 128) shr 8, 255), 0) let g = max(min((298 * C - 100 * D - 208 * E + 128) shr 8, 255), 0) let b = max(min((298 * C + 516 * D + 128) shr 8, 255), 0) return rgb(uint8(r), uint8(g), uint8(b)) proc rgba*(r, g, b, a: uint8): ARGBColor = return ARGBColor((uint32(a) shl 24) or (uint32(r) shl 16) or (uint32(g) shl 8) or uint32(b)) proc rgba_be*(r, g, b, a: uint8): RGBAColorBE = return RGBAColorBE(r: r, g: g, b: b, a: a) proc rgba*(r, g, b, a: int): ARGBColor = return rgba(uint8(r), uint8(g), uint8(b), uint8(a)) proc gray*(n: uint8): RGBColor = return rgb(n, n, n) # I found this algorithm in yaft, but as far as I can tell, it # originates from Microsoft. proc hue2rgb(n1, n2, h: uint32): uint32 = let h = if h > 360: h - 360 else: h if h < 60: return n1 + ((n2 - n1) * h + 30) div 60 if h < 180: return n2 if h < 240: return n1 + ((n2 - n1) * (240 - h) + 30) div 60 return n1 proc hsla*(h: uint32; s, l, a: uint8): ARGBColor = let s = uint32(s) let l = uint32(l) let magic2 = if l <= 50: (l * (100 + s) + 50) div 100 else: l + s - ((l * s) + 50) div 100 let magic1 = l * 2 - magic2 let r = uint8((hue2rgb(magic1, magic2, h + 120) * 255 + 50) div 100) let g = uint8((hue2rgb(magic1, magic2, h) * 255 + 50) div 100) let b = uint8((hue2rgb(magic1, magic2, h + 240) * 255 + 50) div 100) return rgba(r, g, b, a) # Note: this assumes n notin 0..15 (which would be ANSI 4-bit) proc toRGB*(param0: ANSIColor): RGBColor = let u = uint8(param0) assert u notin 0u8..15u8 if u < 232: let n = u - 16 var r = (n div 36) * 40 var g = ((n mod 36) div 6) * 40 var b = (n mod 6) * 40 if r > 0: r += 55 if g > 0: g += 55 if b > 0: b += 55 return rgb(r, g, b) # 232..255 return gray((u - 232) * 10 + 8) proc toEightBit*(c: RGBColor): ANSIColor = # XTerm's cube is components rotated as 0, 95, 135, 175, 215, 255. # Given that there are 6 indices (0..5), it is tempting to just multiply c by # 5, divide by 255, and choose the location on the cube with that. However, # that's incorrect, since our indices aren't mapped uniformly over 0..255. # So instead, we approximate 0..95 by using two sevenths of the range. let cc = c.argb().fastmul(6) let r0 = max(cc.r, 1) - 1 let g0 = max(cc.g, 1) - 1 let b0 = max(cc.b, 1) - 1 if r0 == g0 and g0 == b0: let mid = min(min(max(c.r, c.g), max(c.g, c.b)), max(c.r, c.b)) # First check for mid < 5 and mid > 249, consider that black or white. # (Note: we cheat with wraparound.) # Then, check for an approximate match with the alternative grays on the # cube; if there is no match, go with the gradient. if mid - 5 < 245 and mid shr 2 notin [0x17u8, 0x21u8, 0x2Bu8, 0x35u8]: # Multiply by 25, then divide by 255. let x = uint8((uint32(mid) * 25 + 0x80) shr 8) # Gray values start at 232, but we index from 1 because we skip black. # (This is not a perfect approximation, but it's good enough in practice.) return ANSIColor(x + 231) return ANSIColor(uint8(16 + r0 * 36 + g0 * 6 + b0)) proc parseHexColor*(s: openArray[char]): Opt[ARGBColor] = for c in s: if c notin AsciiHexDigit: return err() case s.len of 6: let c = 0xFF000000 or (hexValue(s[0]) shl 20) or (hexValue(s[1]) shl 16) or (hexValue(s[2]) shl 12) or (hexValue(s[3]) shl 8) or (hexValue(s[4]) shl 4) or hexValue(s[5]) return ok(ARGBColor(c)) of 8: let c = (hexValue(s[6]) shl 28) or (hexValue(s[7]) shl 24) or (hexValue(s[0]) shl 20) or (hexValue(s[1]) shl 16) or (hexValue(s[2]) shl 12) or (hexValue(s[3]) shl 8) or (hexValue(s[4]) shl 4) or hexValue(s[5]) return ok(ARGBColor(c)) of 3: let c = 0xFF000000 or (hexValue(s[0]) shl 20) or (hexValue(s[0]) shl 16) or (hexValue(s[1]) shl 12) or (hexValue(s[1]) shl 8) or (hexValue(s[2]) shl 4) or hexValue(s[2]) return ok(ARGBColor(c)) of 4: let c = (hexValue(s[3]) shl 28) or (hexValue(s[3]) shl 24) or (hexValue(s[0]) shl 20) or (hexValue(s[0]) shl 16) or (hexValue(s[1]) shl 12) or (hexValue(s[1]) shl 8) or (hexValue(s[2]) shl 4) or hexValue(s[2]) return ok(ARGBColor(c)) else: return err() proc parseARGBColor*(s: string): Opt[ARGBColor] = if x := namedRGBColor(s): return ok(x.argb) if (s.len == 3 or s.len == 4 or s.len == 6 or s.len == 8) and s[0] == '#': return parseHexColor(s.toOpenArray(1, s.high)) if s.len > 2 and s[0] == '0' and s[1] == 'x': return parseHexColor(s.toOpenArray(2, s.high)) return parseHexColor(s) proc myHexValue(c: char): uint32 = let n = hexValue(c) if n != -1: return uint32(n) return 0 proc parseLegacyColor0*(s: string): RGBColor = if s.len <= 0: return rgb(0, 0, 0) if x := namedRGBColor(s): return x if s.len == 4 and s[0] == '#': let r = hexValue(s[1]) let g = hexValue(s[2]) let b = hexValue(s[3]) if r != -1 and g != -1 and b != -1: return rgb(uint8(r * 17), uint8(g * 17), uint8(b * 17)) # o_0 var s2 = if s[0] == '#': s.substr(1) else: s while s2.len == 0 or s2.len mod 3 != 0: s2 &= '0' let l = s2.len div 3 let c = if l == 1: (myHexValue(s2[0]) shl 20) or (myHexValue(s2[0]) shl 16) or (myHexValue(s2[1]) shl 12) or (myHexValue(s2[1]) shl 8) or (myHexValue(s2[2]) shl 4) or myHexValue(s2[2]) else: (myHexValue(s2[0]) shl 20) or (myHexValue(s2[1]) shl 16) or (myHexValue(s2[l]) shl 12) or (myHexValue(s2[l + 1]) shl 8) or (myHexValue(s2[l * 2]) shl 4) or myHexValue(s2[l * 2 + 1]) return RGBColor(c) {.pop.} # raises: [] �������chawan-v0.4.0/src/types/formdata.nim����������������������������������������������������������������0000664�0000000�0000000�00000007232�15202323131�0017373�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import io/dynstream import io/packetreader import io/packetwriter import monoucha/jsbind import types/blob import types/opt import utils/twtstr type FormDataEntry* = object name*: string filename*: string case isstr*: bool of true: svalue*: string of false: value*: Blob FormData* = ref object entries*: seq[FormDataEntry] boundary*: string jsDestructor(FormData) proc swrite*(w: var PacketWriter; part: FormDataEntry) = w.swrite(part.isstr) w.swrite(part.name) w.swrite(part.filename) if part.isstr: w.swrite(part.svalue) else: w.swrite(part.value) proc sread*(r: var PacketReader; part: var FormDataEntry) = var isstr: bool r.sread(isstr) if isstr: part = FormDataEntry(isstr: true) else: part = FormDataEntry(isstr: false) r.sread(part.name) r.sread(part.filename) if part.isstr: r.sread(part.svalue) else: r.sread(part.value) iterator items*(this: FormData): lent FormDataEntry {.inline.} = for entry in this.entries: yield entry proc calcLength*(this: FormData): int = result = 0 for entry in this.entries: result += "--\r\n".len + this.boundary.len # always have boundary #TODO maybe make CRLF for name first? result += entry.name.len # always have name # these must be percent-encoded, with 2 char overhead: result += entry.name.count({'\r', '\n', '"'}) * 2 if entry.isstr: result += "Content-Disposition: form-data; name=\"\"\r\n".len result += entry.svalue.len else: result += "Content-Disposition: form-data; name=\"\";".len # file name result += " filename=\"\"\r\n".len result += entry.filename.len # dquot must be quoted with 2 char overhead result += entry.filename.count('"') * 2 # content type result += "Content-Type: \r\n".len result += entry.value.ctype.len result += entry.value.getSize() result += "\r\n".len # header is always followed by \r\n result += "\r\n".len # value is always followed by \r\n result += "--".len + this.boundary.len + "--\r\n".len proc getContentType*(this: FormData): string = return "multipart/form-data; boundary=" & this.boundary proc writeEntry(stream: PosixStream; entry: FormDataEntry; boundary: string): Opt[void] = var buf = "--" & boundary & "\r\n" let name = percentEncode(entry.name, {'"', '\r', '\n'}) if entry.isstr: buf &= "Content-Disposition: form-data; name=\"" & name & "\"\r\n\r\n" # try to merge the write call for small entries if entry.svalue.len < 4096: buf &= entry.svalue ?stream.writeLoop(buf) else: ?stream.writeLoop(buf) ?stream.writeLoop(entry.svalue) else: buf &= "Content-Disposition: form-data; name=\"" & name & "\";" let filename = percentEncode(entry.filename, {'"', '\r', '\n'}) buf &= " filename=\"" & filename & "\"\r\n" let blob = entry.value let ctype = if blob.ctype == "": "application/octet-stream" else: blob.ctype buf &= "Content-Type: " & ctype & "\r\n\r\n" ?stream.writeLoop(buf) if blob of WebFile and WebFile(blob).fd != -1: let ps = newPosixStream(WebFile(blob).fd) if ps != nil: var buf {.noinit.}: array[4096, uint8] while true: let n = ps.read(buf) if n <= 0: break ?stream.writeLoop(buf.toOpenArray(0, n - 1)) else: ?stream.writeLoop(blob.buffer, blob.size) stream.writeLoop("\r\n") proc write*(stream: PosixStream; formData: FormData): Opt[void] = for entry in formData.entries: ?stream.writeEntry(entry, formData.boundary) stream.writeLoop("--" & formData.boundary & "--\r\n") {.pop.} # raises: [] ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/types/jscolor.nim�����������������������������������������������������������������0000664�0000000�0000000�00000003667�15202323131�0017261�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import css/cssparser import css/cssvalues import monoucha/fromjs import monoucha/quickjs import monoucha/tojs import types/color import types/jsopt import types/opt import utils/twtstr proc parseLegacyColor*(s: string): Result[RGBColor, cstring] = if s == "": return err(cstring"color value must not be the empty string") let s = s.strip(chars = AsciiWhitespace) if s.equalsIgnoreCase("transparent"): return err(cstring"color must not be transparent") return ok(parseLegacyColor0(s)) proc toJS*(ctx: JSContext; rgb: RGBColor): JSValue = var res = "#" res.pushHex(rgb.r) res.pushHex(rgb.g) res.pushHex(rgb.b) return toJS(ctx, res) proc fromJS*(ctx: JSContext; val: JSValueConst; res: var RGBColor): FromJSResult = var s: string ?ctx.fromJS(val, s) let x = parseLegacyColor(s) if x.isErr: JS_ThrowTypeError(ctx, x.error) return fjErr res = x.get fjOk proc toJS*(ctx: JSContext; rgba: ARGBColor): JSValue = var res = "#" res.pushHex(rgba.r) res.pushHex(rgba.g) res.pushHex(rgba.b) res.pushHex(rgba.a) return toJS(ctx, res) proc toJS*(ctx: JSContext; c: CSSColor): JSValue = if c.t == cctARGB: return ctx.toJS(c.argb()) return ctx.toJS($c) proc fromJS*(ctx: JSContext; val: JSValueConst; res: var ARGBColor): FromJSResult = if JS_IsNumber(val): # as hex return ctx.fromJS(val, uint32(res)) # parse var s: string ?ctx.fromJS(val, s) if x := parseARGBColor(s): res = x return fjOk JS_ThrowTypeError(ctx, "unrecognized color") fjErr proc fromJS*(ctx: JSContext; val: JSValueConst; res: var CSSColor): FromJSResult = var argb: ARGBColor if ctx.fromJS(val, argb).isOk: res = cssColor(argb) return fjOk var s: string ?ctx.fromJS(val, s) var p = initCSSParser(s) let c = p.parseColor() if c.isErr or p.has(): JS_ThrowTypeError(ctx, "invalid color %s", cstring(s)) return fjErr res = c.get fjOk {.pop.} # raises: [] �������������������������������������������������������������������������chawan-v0.4.0/src/types/jsopt.nim�������������������������������������������������������������������0000664�0000000�0000000�00000002533�15202323131�0016734�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import monoucha/fromjs import monoucha/quickjs import monoucha/tojs import types/opt proc toJS*[T](ctx: JSContext; opt: Opt[T]): JSValue proc toJSNew*[T](ctx: JSContext; opt: Opt[T]; ctor: JSValueConst): JSValue template `?`*(res: FromJSResult) = if res == fjErr: when result is FromJSResult: return fjErr elif result is JSValue or result is JSValueConst: return JS_EXCEPTION else: return err() template `?`*(res: JSClassID) = if res == JS_INVALID_CLASS_ID: when result is JSClassID: return JS_INVALID_CLASS_ID else: return err() proc toJS*[T](ctx: JSContext; opt: Opt[T]): JSValue = if opt.isOk: when not (T is void): return ctx.toJS(opt.get) else: return JS_UNDEFINED else: return JS_EXCEPTION proc toJSNew*[T](ctx: JSContext; opt: Opt[T]; ctor: JSValueConst): JSValue = if opt.isOk: when not (T is void): return ctx.toJSNew(opt.get, ctor) else: return JS_UNDEFINED else: return JS_EXCEPTION proc fromJSGetProp*[T](ctx: JSContext; this: JSValueConst; name: cstring; res: var T): Opt[bool] = if JS_IsUndefined(this): return ok(false) let prop = JS_GetPropertyStr(ctx, this, name) if JS_IsException(prop): return err() if JS_IsUndefined(prop): return ok(false) ?ctx.fromJSFree(prop, res) ok(true) {.pop.} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/types/opt.nim���������������������������������������������������������������������0000664�0000000�0000000�00000004057�15202323131�0016402�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Inspired by nim-results. type Result*[T, E] = object when E is void and T is void: # Opt[void] isOk*: bool elif E is void and T isnot void: # Opt[T] case isOk*: bool of true: value*: T else: discard elif E isnot void and T is void: # Err[T] case isOk*: bool of true: discard else: error*: E else: # Result[T, E] case isOk*: bool of true: value*: T else: error*: E Opt*[T] = Result[T, void] Err*[E] = Result[void, E] template ok*[E](t: type Err[E]): Err[E] = Err[E](isOk: true) template ok*[T, E](t: type Result[T, E]; x: T): Result[T, E] = Result[T, E](value: x, isOk: true) template ok*[T](x: T): auto = ok(typeof(result), x) template ok*(): auto = ok(typeof(result)) template err*[T, E](t: type Result[T, E]; e: E): Result[T, E] = Result[T, E](isOk: false, error: e) template err*[T](t: type Result[T, ref object]): auto = t(isOk: false, error: nil) template err*[T](t: type Result[T, void]): Result[T, void] = Result[T, void](isOk: false) template err*(): auto = err(typeof(result)) template err*[E](e: E): auto = err(typeof(result), e) template opt*[T](v: T): auto = ok(Opt[T], v) template opt*(t: typedesc): auto = err(Result[t, void]) template isErr*(res: Result): bool = not res.isOk template get*[T, E](res: Result[T, E]): T = res.value proc get*[T, E](res: Result[T, E]; v: T): T = if res.isOk: result = res.value else: result = v template `?`*[T, E](res: Result[T, E]): auto = var x = res # for when res is a funcall if not x.isOk: when typeof(result) is Result[T, E]: return move(x) elif E is cstring: return err(x.error) elif E isnot void: {.push checks: off.} return err(move(x.error)) {.pop.} else: return err() when T isnot void: move(x.get) template `:=`*(a, res: untyped): bool = var x = res # for when res is a funcall var a: typeof(x).T let r = x.isOk if r: {.push checks: off.} a = move(x.get) {.pop.} r ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/types/path.nim��������������������������������������������������������������������0000664�0000000�0000000�00000034765�15202323131�0016545�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import std/algorithm import std/math type Vector2D* = object x*: float64 y*: float64 proc `-`(v1, v2: Vector2D): Vector2D = return Vector2D(x: v1.x - v2.x, y: v1.y - v2.y) proc `+`(v1, v2: Vector2D): Vector2D = return Vector2D(x: v1.x + v2.x, y: v1.y + v2.y) # scalar multiplication proc `*`(s: float64; v: Vector2D): Vector2D {.inline.} = return Vector2D(x: v.x * s, y: v.y * s) proc `*`(v: Vector2D; s: float64): Vector2D {.inline.} = return Vector2D(x: v.x * s, y: v.y * s) proc `/`(v: Vector2D; s: float64): Vector2D = return Vector2D(x: v.x / s, y: v.y / s) # dot product proc `*`(v1, v2: Vector2D): float64 = return v1.x * v2.x + v1.y * v2.y proc norm(v: Vector2D): float64 = return sqrt(v.x * v.x + v.y * v.y) # kind of a cross product? proc cross(v1, v2: Vector2D): float64 = return v1.x * v2.y - v1.y * v2.x # https://en.wikipedia.org/wiki/Inner_product_space proc innerAngle(v1, v2: Vector2D): float64 = return arccos((v1 * v2) / (v1.norm() * v2.norm())) proc rotate(v: Vector2D, alpha: float64): Vector2D = let sa = sin(alpha) let ca = cos(alpha) return Vector2D( x: v.x * ca - v.y * sa, y: v.x * sa + v.y * ca ) proc collinear(v1, v2, v3: Vector2D): bool = return almostEqual((v1.y - v2.y) * (v1.x - v3.x), (v1.y - v3.y) * (v1.x - v2.x)) type Line* = object p0*: Vector2D p1*: Vector2D LineSegment* = object line: Line miny*: float64 maxy*: float64 minyx*: float64 islope*: float64 proc minyx(line: Line): float64 = if line.p0.y < line.p1.y: return line.p0.x return line.p1.x proc miny(line: Line): float64 = return min(line.p0.y, line.p1.y) proc maxy(line: Line): float64 = return max(line.p0.y, line.p1.y) # inverse slope proc islope(line: Line): float64 = let ydiff = (line.p0.y - line.p1.y) if ydiff == 0: return 0 return (line.p0.x - line.p1.x) / ydiff proc cmpLineSegmentY*(l1, l2: LineSegment): int = return cmp(l1.miny, l2.miny) proc cmpLineSegmentX*(l1, l2: LineSegment): int = return cmp(l1.minyx, l2.minyx) proc p0*(ls: LineSegment): Vector2D {.inline.} = ls.line.p0 proc p1*(ls: LineSegment): Vector2D {.inline.} = ls.line.p1 proc toLineSegment*(line: Line): LineSegment = LineSegment( line: line, miny: line.miny, maxy: line.maxy, minyx: line.minyx, islope: line.islope ) type Matrix* = object me*: seq[float64] w: int h: int proc newMatrix*(me: seq[float64]; w, h: int): Matrix = return Matrix( me: me, w: w, h: h ) proc newIdentityMatrix*(n: int): Matrix = var me = newSeq[float64](n * n) for i in 0 ..< n: me[n * i + i] = 1 return Matrix( me: me, w: n, h: n ) proc newMatrixUninitialized(w, h: int): Matrix = return Matrix( me: newSeqUninit[float64](w * h), w: w, h: h ) proc `*`*(a, b: Matrix): Matrix = assert a.w == b.h let h = a.h let w = b.w let n = a.w var c = newMatrixUninitialized(w, h) for x in 0 ..< w: for y in 0 ..< h: var val: float64 = 0 for i in 0 ..< n: val += a.me[y * a.w + i] * b.me[i * b.w + x] c.me[y * c.w + x] = val return c proc `*=`*(a: var Matrix; b: Matrix) = a = a * b type Path* = ref object subpaths: seq[Subpath] needsNewSubpath: bool tempClosed: bool PathLines* = object lines*: seq[LineSegment] miny*: float64 maxy*: float64 PathSegmentType = enum pstStraight, pstQuadratic, pstBezier, pstArc, pstEllipse PathSegment = object case t: PathSegmentType of pstQuadratic: cp: Vector2D of pstBezier: cp0: Vector2D cp1: Vector2D of pstArc: oa: Vector2D r: float64 ia: bool of pstEllipse: oe: Vector2D rx: float64 ry: float64 else: discard Subpath* = object points: seq[Vector2D] segments: seq[PathSegment] closed: bool proc newPath*(): Path = return Path( needsNewSubpath: true ) proc addSubpathAt(path: Path; p: Vector2D) = path.subpaths.add(Subpath(points: @[p])) proc addSegment(path: Path; segment: PathSegment; p: Vector2D) = path.subpaths[^1].segments.add(segment) path.subpaths[^1].points.add(p) proc addStraightSegment(path: Path; p: Vector2D) = let segment = PathSegment(t: pstStraight) path.addSegment(segment, p) proc addQuadraticSegment(path: Path; cp, p: Vector2D) = let segment = PathSegment( t: pstQuadratic, cp: cp ) path.addSegment(segment, p) proc addBezierSegment(path: Path; cp0, cp1, p: Vector2D) = let segment = PathSegment( t: pstBezier, cp0: cp0, cp1: cp1 ) path.addSegment(segment, p) # Goes from start tangent point to end tangent point proc addArcSegment(path: Path; o, etan: Vector2D; r: float64; ia: bool) = let segment = PathSegment( t: pstArc, oa: o, r: r, ia: ia ) path.addSegment(segment, etan) proc addEllipseSegment(path: Path; o, etan: Vector2D; rx, ry: float64) = #TODO simplify to bezier? let segment = PathSegment( t: pstEllipse, oe: o, rx: rx, ry: ry ) path.addSegment(segment, etan) # https://hcklbrrfnn.files.wordpress.com/2012/08/bez.pdf proc flatEnough(a, b, c0, c1: Vector2D): bool = let u = 3 * c0 - 2 * a - b let v = 3 * c1 - 2 * b - a let x = max(u.x, v.x) let y = max(u.y, v.y) return x * x + y * y <= 0.02 proc flatEnough(a, b, c: Vector2D): bool = return flatEnough(a, b, c, c) iterator items*(pl: PathLines): lent LineSegment {.inline.} = for line in pl.lines: yield line proc `[]`*(pl: PathLines; i: int): lent LineSegment = pl.lines[i] proc `[]`*(pl: PathLines; i: BackwardsIndex): lent LineSegment = return pl.lines[pl.lines.len - int(i)] proc len*(pl: PathLines): int = pl.lines.len iterator quadraticLines(a, b, c: Vector2D): Line {.inline.} = var points = newSeq[tuple[a, b, c: Vector2D]]() let tup = (a, b, c) points.add(tup) while points.len > 2: let (a, b, c) = points.pop() if flatEnough(a, b, c): yield Line(p0: a, p1: b) else: let mid1 = (c + a) / 2 let mid2 = (c + b) / 2 let s = (mid1 + mid2) / 2 points.add((a, s, mid1)) points.add((s, b, mid2)) iterator bezierLines(p0, p1, c0, c1: Vector2D): Line {.inline.} = var points = @[(p0, p1, c0, c1)] while points.len > 0: let (p0, p1, c0, c1) = points.pop() if flatEnough(p0, p1, c0, c1): yield Line(p0: p0, p1: p1) else: let mida1 = (p0 + c0) / 2 let mida2 = (c0 + c1) / 2 let mida3 = (c1 + p1) / 2 let midb1 = (mida1 + mida2) / 2 let midb2 = (mida2 + mida3) / 2 let midc = (midb1 + midb2) / 2 points.add((p0, midc, mida1, midb1)) points.add((midc, p1, midb2, mida3)) # https://stackoverflow.com/a/44829356 proc arcControlPoints(p1, p4, o: Vector2D): tuple[c0, c1: Vector2D] = let a = p1 - o let b = p4 - o let q1 = a * a let q2 = q1 + a * b let k2 = (4 / 3) * (sqrt(2 * q1 * q2) - q2) / a.cross(b) let c0 = o + a + Vector2D(x: -k2 * a.y, y: k2 * a.x) let c1 = o + b + Vector2D(x: k2 * b.y, y: -k2 * b.x) return (c0, c1) iterator arcLines(p0, p1, o: Vector2D; r: float64; i: bool): Line {.inline.} = var p0 = p0 let pp0 = p0 - o let pp1 = p1 - o var theta = pp0.innerAngle(pp1) if not i: theta = PI * 2 - theta while theta > 0: let step = if theta > PI / 2: PI / 2 else: theta let p1 = (p0 - o).rotate(step) + o let (c0, c1) = arcControlPoints(p0, p1, o) for line in bezierLines(p0, p1, c0, c1): yield line p0 = p1 theta -= step proc addLines(lines: var seq[Line]; subpath: Subpath; i: int) = let p0 = subpath.points[i] let p1 = subpath.points[i + 1] case subpath.segments[i].t of pstStraight: if p0 != p1: lines.add(Line(p0: p0, p1: p1)) of pstQuadratic: let c = subpath.segments[i].cp for line in quadraticLines(p0, p1, c): if line.p0 != line.p1: lines.add(line) of pstBezier: let c0 = subpath.segments[i].cp0 let c1 = subpath.segments[i].cp1 for line in bezierLines(p0, p1, c0, c1): if line.p0 != line.p1: lines.add(line) of pstArc: let o = subpath.segments[i].oa let r = subpath.segments[i].r let i = subpath.segments[i].ia for line in arcLines(p0, p1, o, r, i): if line.p0 != line.p1: lines.add(line) of pstEllipse: discard #TODO proc getLines*(path: Path): seq[Line] = var lines: seq[Line] = @[] for subpath in path.subpaths: assert subpath.points.len == subpath.segments.len + 1 for i in 0 ..< subpath.segments.len: lines.addLines(subpath, i) move(lines) proc getLineSegments*(path: Path): PathLines = if path.subpaths.len == 0: return PathLines() var miny = Inf var maxy = -Inf let lines = path.getLines() var segments: seq[LineSegment] = @[] for line in lines: let ls = line.toLineSegment() miny = min(miny, ls.miny) maxy = max(maxy, ls.maxy) segments.add(ls) segments.sort(cmpLineSegmentY) return PathLines( miny: miny, maxy: maxy, lines: segments ) proc moveTo(path: Path; v: Vector2D) = path.addSubpathAt(v) path.needsNewSubpath = false #TODO TODO TODO ???? why here proc beginPath*(path: Path) = path.subpaths.setLen(0) proc moveTo*(path: Path; x, y: float64) = for v in [x, y]: if classify(v) in {fcInf, fcNegInf, fcNan}: return path.moveTo(Vector2D(x: x, y: y)) proc ensureSubpath(path: Path; x, y: float64) = if path.needsNewSubpath: path.moveTo(x, y) path.needsNewSubpath = false proc closePath*(path: Path) = if path.subpaths.len > 0: let lsp = path.subpaths[^1] if lsp.points.len > 0 or lsp.closed: path.subpaths[^1].closed = true path.addSubpathAt(path.subpaths[^1].points[0]) #TODO this is a hack, and breaks as soon as any draw command is issued # between tempClosePath and tempOpenPath proc tempClosePath*(path: Path) = if path.subpaths.len > 0 and not path.subpaths[^1].closed: path.subpaths[^1].closed = true let lsp = path.subpaths[^1] path.addSubpathAt(lsp.points[^1]) path.addStraightSegment(lsp.points[0]) path.tempClosed = true proc tempOpenPath*(path: Path) = if path.tempClosed: path.subpaths.setLen(path.subpaths.len - 1) path.subpaths[^1].closed = false path.tempClosed = false proc lineTo*(path: Path; x, y: float64) = for v in [x, y]: if classify(v) in {fcInf, fcNegInf, fcNan}: return if path.subpaths.len == 0: path.ensureSubpath(x, y) else: path.addStraightSegment(Vector2D(x: x, y: y)) proc quadraticCurveTo*(path: Path; cpx, cpy, x, y: float64) = for v in [cpx, cpy, x, y]: if classify(v) in {fcInf, fcNegInf, fcNan}: return path.ensureSubpath(cpx, cpy) let cp = Vector2D(x: cpx, y: cpy) let p = Vector2D(x: x, y: y) path.addQuadraticSegment(cp, p) proc bezierCurveTo*(path: Path; cp0x, cp0y, cp1x, cp1y, x, y: float64) = for v in [cp0x, cp0y, cp1x, cp1y, x, y]: if classify(v) in {fcInf, fcNegInf, fcNan}: return path.ensureSubpath(cp0x, cp0y) let cp0 = Vector2D(x: cp0x, y: cp0y) let cp1 = Vector2D(x: cp1x, y: cp1y) let p = Vector2D(x: x, y: y) path.addBezierSegment(cp0, cp1, p) proc arcTo*(path: Path; x1, y1, x2, y2, radius: float64) = for v in [x1, y1, x2, y2, radius]: if classify(v) in {fcInf, fcNegInf, fcNan}: return path.ensureSubpath(x1, y1) #TODO this should be transformed by the inverse of the transformation matrix let v0 = path.subpaths[^1].points[^1] let v1 = Vector2D(x: x1, y: y1) let v2 = Vector2D(x: x2, y: y2) if v0.x == x1 and v0.y == y1 or x1 == x2 and y1 == y2 or radius == 0: path.addStraightSegment(v1) elif collinear(v0, v1, v2): path.addStraightSegment(v1) else: let pv0 = v0 - v1 let pv2 = v2 - v1 let tv0 = v1 + pv0 * radius * 2 / pv0.norm() let tv2 = v1 + pv2 * radius * 2 / pv2.norm() let q = -(pv0.x * tv0.x + pv0.y * tv0.y) let p = -(pv2.x * tv2.x + pv2.y * tv2.y) let cr = pv0.cross(pv2) let origin = Vector2D( x: (pv0.y * p - pv2.y * q) / cr, y: (pv2.x * q - pv0.x * p) / cr ) path.addStraightSegment(tv0) path.addArcSegment(origin, tv2, radius, true) #TODO always inner? # Ref. https://math.stackexchange.com/a/22067 # (Originally found it in SerenityOS.) proc resolveEllipsePoint(o: Vector2D; angle, radiusX, radiusY, rotation: float64): Vector2D = let tanrel = tan(angle) let tan2 = tanrel * tanrel let ab = radiusX * radiusY let a2 = radiusX * radiusX let b2 = radiusY * radiusY let sq = sqrt(b2 + a2 * tan2) let sn = if cos(angle) >= 0: 1f64 else: -1f64 let relx = ab / sq * sn let rely = relx * tanrel return Vector2D(x: relx, y: rely).rotate(rotation) + o proc arc*(path: Path; x, y, radius, startAngle, endAngle: float64; counterclockwise: bool) = for v in [x, y, radius, startAngle, endAngle]: if classify(v) in {fcInf, fcNegInf, fcNan}: return let o = Vector2D(x: x, y: y) var startAngle = startAngle var endAngle = endAngle if counterclockwise: swap(startAngle, endAngle) let s = resolveEllipsePoint(o, startAngle, radius, radius, 0) if path.subpaths.len > 0: path.addStraightSegment(s) else: path.moveTo(s) if endAngle - startAngle >= 2 * PI: path.addArcSegment(o, s, radius, false) else: let e = resolveEllipsePoint(o, endAngle, radius, radius, 0) let mul = if counterclockwise: -1f64 else: 1f64 let sa = (startAngle * mul).euclMod(2 * PI) let ea = (endAngle * mul).euclMod(2 * PI) let innerAngle = if sa == ea: startAngle == endAngle else: abs(sa - ea) < PI path.addArcSegment(o, e, radius, innerAngle) proc ellipse*(path: Path; x, y, radiusX, radiusY, rotation, startAngle, endAngle: float64; counterclockwise: bool) = for v in [x, y, radiusX, radiusY, rotation, startAngle, endAngle]: if classify(v) in {fcInf, fcNegInf, fcNan}: return let o = Vector2D(x: x, y: y) var s = resolveEllipsePoint(o, startAngle, radiusX, radiusY, rotation) var e = resolveEllipsePoint(o, endAngle, radiusX, radiusY, rotation) if counterclockwise: swap(s, e) if path.subpaths.len > 0: path.addStraightSegment(s) else: path.moveTo(s) path.addEllipseSegment(o, e, radiusX, radiusY) proc rect*(path: Path; x, y, w, h: float64) = for v in [x, y, w, h]: if classify(v) in {fcInf, fcNegInf, fcNan}: return path.addSubpathAt(Vector2D(x: x, y: y)) path.addStraightSegment(Vector2D(x: x + w, y: y)) path.addStraightSegment(Vector2D(x: x + w, y: y + h)) path.addStraightSegment(Vector2D(x: x, y: y + h)) path.addStraightSegment(Vector2D(x: x, y: y)) path.addSubpathAt(Vector2D(x: x, y: y)) proc roundRect*(path: Path; x, y, w, h, radii: float64) = for v in [x, y, w, h]: if classify(v) in {fcInf, fcNegInf, fcNan}: return #TODO implement path.rect(x, y, w, h) # :P �����������chawan-v0.4.0/src/types/referrer.nim����������������������������������������������������������������0000664�0000000�0000000�00000003154�15202323131�0017411�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import types/url type ReferrerPolicy* = enum rpStrictOriginWhenCrossOrigin = "strict-origin-when-cross-origin" rpNoReferrer = "no-referrer" rpNoReferrerWhenDowngrade = "no-referrer-when-downgrade" rpStrictOrigin = "strict-origin" rpOrigin = "origin" rpSameOrigin = "same-origin" rpOriginWhenCrossOrigin = "origin-when-cross-origin" rpUnsafeURL = "unsafe-url" const DefaultPolicy* = rpStrictOriginWhenCrossOrigin proc getReferrer*(prev, target: URL; policy: ReferrerPolicy): string = let origin = prev.origin if origin.t == otOpaque: return "" if prev.schemeType notin {stHttp, stHttps} or target.schemeType notin {stHttp, stHttps}: return "" case policy of rpNoReferrer: return "" of rpNoReferrerWhenDowngrade: if prev.schemeType == stHttps and target.schemeType == stHttp: return "" return $origin & prev.pathname & prev.search of rpSameOrigin: if origin.isSameOrigin(target.origin): return $origin return "" of rpOrigin: return $origin of rpStrictOrigin: if prev.schemeType == stHttps and target.schemeType == stHttp: return "" return $origin of rpOriginWhenCrossOrigin: if not origin.isSameOrigin(target.origin): return $origin return $origin & prev.pathname & prev.search of rpStrictOriginWhenCrossOrigin: if prev.schemeType == stHttps and target.schemeType == stHttp: return $origin if not origin.isSameOrigin(target.origin): return $origin return $origin & prev.pathname & prev.search of rpUnsafeURL: return $origin & prev.pathname & prev.search {.pop.} # raises: [] ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/types/refstring.nim���������������������������������������������������������������0000664�0000000�0000000�00000001134�15202323131�0017574�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import monoucha/fromjs import monoucha/quickjs import monoucha/tojs type RefString* = ref object s*: string proc newRefString*(s: sink string): RefString = return RefString(s: s) proc `$`*(rs: RefString): lent string = rs.s template `&=`*(rs: var RefString; ss: string) = rs.s &= ss template `[]`*(rs: RefString; i: int): char = rs.s[i] proc len*(rs: RefString): int = rs.s.len proc toJS*(ctx: JSContext; rs: RefString): JSValue = return ctx.toJS($rs) proc fromJS*(ctx: JSContext; val: JSValueConst; rs: var RefString): FromJSResult = rs = RefString() ctx.fromJS(val, rs.s) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/types/url.nim���������������������������������������������������������������������0000664�0000000�0000000�00000115421�15202323131�0016400�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# See https://url.spec.whatwg.org/#url-parsing. {.push raises: [].} import std/algorithm import io/packetreader import io/packetwriter import monoucha/fromjs import monoucha/jsbind import monoucha/jsopaque import monoucha/jstypes import monoucha/libunicode import monoucha/quickjs import monoucha/tojs import types/jsopt import types/opt import utils/luwrap import utils/twtstr type URLState = enum usFail, usDone, usSchemeStart, usNoScheme, usFile, usFragment, usAuthority, usPath, usQuery, usHost, usHostname, usPort, usPathStart HostType* = enum htNone, htDomain, htIpv4, htIpv6, htOpaque # List of known schemes. SchemeType* = enum stUnknown = "" stAbout = "about" stBlob = "blob" stCache = "cache" stCgiBin = "cgi-bin" stData = "data" stEd2k = "ed2k" stFile = "file" stFtp = "ftp" stHttp = "http" stHttps = "https" stJavascript = "javascript" stMailto = "mailto" stStream = "stream" stWs = "ws" stWss = "wss" stXChaCookie = "x-cha-cookie" URLSearchParams* = ref object list: seq[tuple[name, value: string]] url: URL URL* = ref object scheme: string username* {.jsget.}: string password* {.jsget.}: string opaquePath: bool hostType: HostType schemeType*: SchemeType port: int32 # -1 -> no port, other values: has port hostname* {.jsget.}: string pathname* {.jsget.}: string search* {.jsget.}: string hash* {.jsget.}: string searchParamsInternal: URLSearchParams OriginType* = enum otOpaque, otTuple Origin* = ref object t*: OriginType s: string jsDestructor(URL) jsDestructor(URLSearchParams) # Forward declarations proc parseURL0*(input: string; base: URL = nil): URL proc serialize*(url: URL; excludeHash = false; excludePassword = false): string proc serializeip(ipv4: uint32): string proc serializeip(ipv6: array[8, uint16]): string proc host*(url: URL): string proc swrite*(w: var PacketWriter; url: URL) = if url != nil: w.swrite(url.serialize()) else: w.swrite("") proc sread*(r: var PacketReader; url: var URL) = var s: string r.sread(s) if s == "": url = nil else: url = parseURL0(s) # -1 if not special # 0 if file # > 0 if special const SpecialPort = [ stUnknown: -1i32, stAbout: -1, stBlob: -1, stCache: -1, stCgiBin: -1, stData: -1, stEd2k: -1, stFile: 0, stFtp: 21, stHttp: 80, stHttps: 443, stJavascript: -1, stMailto: -1, stStream: -1, stWs: 80, stWss: 443, stXChaCookie: -1, ] template isSpecial(url: URL): bool = SpecialPort[url.schemeType] >= 0 proc parseSchemeType(buffer: string): SchemeType = return parseEnumNoCase[SchemeType](buffer).get(stUnknown) proc parseIpv6(input: openArray[char]): string = var pieceIndex = 0 var compress = -1 var i = 0 var address = array[8, uint16].default if input[i] == ':': if i + 1 >= input.len or input[i + 1] != ':': return "" i += 2 inc pieceIndex compress = pieceIndex while i < input.len: if pieceIndex == 8: return "" if input[i] == ':': if compress != -1: return "" inc i inc pieceIndex compress = pieceIndex continue var value: uint16 = 0 let L = min(i + 4, input.len) let oi = i while i < L and (let n = hexValue(input[i]); n != -1): value = value * 0x10 + uint16(n) inc i if i < input.len and input[i] == '.' and pieceIndex <= 6: # dual address i = oi for j in 0 ..< 4: var e = input.len if j < 3: # find ipv4 separator e = input.find('.', i) if e < 0: return "" let x = parseUInt8NoLeadingZero(input.toOpenArray(i, e - 1)) if x.isErr: return "" address[pieceIndex] = address[pieceIndex] * 0x100 + uint16(x.get) if j == 1 or j == 3: inc pieceIndex i = e + 1 break elif i < input.len: if input[i] != ':' or i + 1 >= input.len: return "" inc i address[pieceIndex] = value inc pieceIndex if compress != -1: var swaps = pieceIndex - compress pieceIndex = 7 while pieceIndex > 0 and swaps > 0: swap(address[pieceIndex], address[compress + swaps - 1]) dec pieceIndex dec swaps elif pieceIndex != 8: return "" return address.serializeip() proc parseIpv4Number(s: openArray[char]): Opt[uint32] = var i = 0 var R = 10u32 if s.len >= 2 and s[0] == '0': if s[1] in {'x', 'X'}: i = 2 R = 16 else: i = 1 R = 8 return parseUInt32Base(s.toOpenArray(i, s.high), radix = R) proc parseIpv4(input: string): Opt[uint32] = var last = input.high if last >= 0 and input[last] == '.': dec last var res = 0'u32 var i = 0 var pi = 0 var npart = 4'u32 while i <= last: let c = input[i] if c == '.': let tmp = ?parseIpv4Number(input.toOpenArray(pi, i - 1)) if tmp > 0xFF: return err() dec npart if npart == 0: return err() res = (res shl 8) or tmp pi = i + 1 inc i let tmp = ?parseIpv4Number(input.toOpenArray(pi, last)) if npart < 4: let shift = npart shl 3'u32 if tmp >= 1'u32 shl shift: return err() res = res shl shift res = res or tmp ok(res) const ForbiddenHostChars = { '\0', '\t', '\n', '\r', ' ', '#', '/', ':', '<', '>', '?', '@', '[', '\\', ']', '^', '|' } const ForbiddenDomainChars = ForbiddenHostChars + {'%'} proc opaqueParseHost(input: string; schemeType: SchemeType; hostType: var HostType): string = var o = "" for c in input: # non-standard ed2k quirk for web-compat if c in ForbiddenHostChars and not (c == '|' and schemeType == stEd2k): return "" o.percentEncode(c, ControlPercentEncodeSet) hostType = htOpaque move(o) proc endsInNumber(input: string): bool = if input.len <= 0: return false var i = input.high if input[i] == '.': dec i # if no period, start from 0 i = input.rfind('.', start = 0, last = i) + 1 if i + 1 < input.len and input[i] == '0' and input[i + 1] in {'x', 'X'}: # hex? i += 2 while i < input.len and input[i] != '.': if input[i] notin AsciiHexDigit: return false inc i else: while i < input.len and input[i] != '.': if input[i] notin AsciiDigit: return false inc i return true # RFC 3492 proc punyAdapt(delta, len: uint32; first: bool): uint32 = var delta = if first: delta div 700 else: delta div 2 delta += delta div len var k = 0u32 while delta > 455: delta = delta div 35 k += 36 return k + (36 * delta) div (delta + 38) proc punyCharDecode(c: char): Opt[uint32] = if c in AsciiDigit: return ok(uint32(c) - uint32('0') + 26) let c = c.toLowerAscii() if c in AsciiLowerAlpha: return ok(uint32(c) - uint32('a')) err() proc punyDecode(s: openArray[char]): Opt[seq[uint32]] = var j = 0 var res: seq[uint32] = @[] for k, c in s: if c == '-': j = k res &= uint32(c) res.setLen(j) if j > 0: inc j var n = 0x80u32 var bias = 72u32 var i = 0u32 while j < s.len: let oldi = i var w = 1u32 for k in countup(36u32, uint32.high, 36u32): if j >= s.len: return err() let d = ?punyCharDecode(s[j]) inc j let dw = d * w if uint32.high - dw < i: # overflow return err() i += dw let t = if k <= bias: 1u32 elif k >= bias + 26: 26u32 else: k - bias if d < t: break if static(uint32.high div 36) < w: # overflow return err() w *= 36 - t let L = uint32(res.len + 1) bias = punyAdapt(i - oldi, L, oldi == 0) let iL = i div L if uint32.high - iL < n: # overflow return err() n += iL i = i mod L res.insert(n, i) inc i ok(move(res)) proc punyCharEncode(q: uint32): char = if q < 26: return char(uint32('a') + q) return char(uint32('0') + q - 26) proc punyEncode(s: openArray[char]): Opt[string] = var res = "" var us: seq[uint32] = @[] for u in s.points: if u <= 0x7F: res &= char(u) else: us.add(u) us.sort() var h = uint32(res.len) if uint(res.len) != uint32(res.len): # overflow return err() let b = h if res.len > 0: res &= '-' var n = 0x7Fu32 var bias = 72u32 var delta = 0u32 for m in us: if m == n: continue let delta2 = uint64(delta) + uint64(m - n - 1) * uint64(h + 1) if uint64(delta) > uint64(uint32.high): # overflow return err() delta = uint32(delta2) n = m for u in s.points: if u < m: inc delta if delta == 0: # overflow return err() elif u == m: var q = delta for k in countup(36u32, uint32.high, 36u32): let t = if k <= bias: 1u32 elif k >= bias + 26: 26u32 else: k - bias if q < t: break let tt = 36 - t res &= punyCharEncode(t + (q - t) mod tt) q = (q - t) div tt res &= punyCharEncode(q) bias = punyAdapt(delta, h + 1, h == b) delta = 0 inc h inc delta ok(move(res)) proc mapIdna(ctx: LUContext; mapped: var seq[uint32]; u: uint32): Opt[void] = case u of 0xFF0E, 0x3002, 0xFF61: mapped &= 0x2E # dot-likes map to period of 0xDF, 0x1E9E: mapped &= 0xDF # scharfes S of 0x03C2: mapped &= u # sigma maps to itself elif ctx.isBidiControl(u): return err() # bidi_control is disallowed else: var res {.noinit.}: array[3, uint32] let p = cast[ptr UncheckedArray[uint32]](addr res[0]) let len = lre_case_conv(p, u, 2) # case fold let mapping = res.toOpenArray(0, len - 1).normalize(UNICODE_NFKC) for mu in mapping: if mu == 0xFFFC or mu == 0xFFFD or mu in 0xE0001u32..0xE007Fu32: return err() # base exclusion set if ctx.isIDSOperator(mu) or ctx.isWhiteSpace(mu) or ctx.isOther(mu): return err() # not in base valid set mapped &= mapping ok() proc processIdna(str: string; beStrict: bool): string = # CheckHyphens = false # CheckBidi = true # CheckJoiners = true # UseSTD3ASCIIRules = beStrict # Transitional_Processing = false # VerifyDnsLength = beStrict var mapped: seq[uint32] = @[] let ctx = LUContext() for u in str.points: if ctx.mapIdna(mapped, u).isErr: return "" mapped = mapped.normalize() if mapped.len == 0: return "" let luctx = LUContext() var labels = "" var first = true for label in mapped.toUTF8().split('.'): if label.startsWith("xn--"): let x0 = punyDecode(label.toOpenArray("xn--".len, label.high)) if x0.isErr: return "" let x1 = x0.get.normalize() # CheckHyphens is false if x0.get != x1 or x1.len > 0 and luctx.isMark(x1[0]): return "" #error for u in x1: if u == uint32('.'): return "" #error var mapping: seq[uint32] = @[] if ctx.mapIdna(mapping, u).isErr: return "" # error if mapping.len != 1 or mapping[0] != u: return "" # error, mapped value if beStrict and u < 0x80 and char(u) notin AsciiAlphaNumeric + {'-'}: return "" # error, STD3 rules #TODO check joiners #TODO check bidi if not first: labels &= '.' labels &= x1.toUTF8() else: if not first: labels &= '.' labels &= label first = false move(labels) proc unicodeToAscii(s: string; beStrict: bool): string = let processed = s.processIdna(beStrict) var labels = "" var all = 0 var first = true for label in processed.split('.'): var s = "" if NonAscii in label: let x = punyEncode(label) if x.isErr: return "" s = "xn--" & x.get else: s = label if beStrict: # VerifyDnsLength let rl = s.pointLen() if rl notin 1..63: return "" all += rl if not first: labels &= '.' labels &= s first = false if beStrict: # VerifyDnsLength if all notin 1..253: return "" #error move(labels) proc domainToAscii(domain: string; beStrict: bool): string = result = domain.toLowerAscii() if beStrict or result.startsWith("xn--") or result.find(".xn--") != -1 or NonAscii in result: result = domain.unicodeToAscii(beStrict) proc parseHost*(input: string; schemeType: SchemeType; hostType: var HostType): string = let special = SpecialPort[schemeType] >= 0 if input.len <= 0: if not special: hostType = htOpaque return "" if input[0] == '[': if input[^1] != ']' or input.len < 3: return "" var ipv6 = parseIpv6(input.toOpenArray(1, input.high - 1)) if ipv6 != "": hostType = htIpv6 return move(ipv6) if not special: return opaqueParseHost(input, schemeType, hostType) let domain = percentDecode(input) var asciiDomain = domain.domainToAscii(beStrict = false) if asciiDomain == "" or ForbiddenDomainChars in asciiDomain: return "" if asciiDomain.endsInNumber(): if ipv4 := parseIpv4(asciiDomain): hostType = htIpv4 return ipv4.serializeip() return "" hostType = htDomain move(asciiDomain) proc shortenPath(url: URL) = if url.schemeType == stFile and (url.pathname.len == 3 or url.pathname.len == 4 and url.pathname[2] == '/') and url.pathname[0] == '/' and url.pathname[1] in AsciiAlpha and url.pathname[2] == ':': return if url.pathname.len > 0: url.pathname.setLen(url.pathname.rfind('/')) proc includesCredentials*(url: URL): bool = return url.username != "" or url.password != "" proc isWinDriveLetter(s: string): bool = return s.len == 2 and s[0] in AsciiAlpha and s[1] in {':', '|'} proc parseOpaquePath(input: openArray[char]; pointer: var int; url: URL): URLState = var i = pointer while i < input.len: let c = input[i] let nexti = i + 1 case c of '?': url.search = "?" pointer = nexti return usQuery of '#': url.hash = "#" pointer = nexti return usFragment of ' ': if nexti < input.len and input[nexti] in {'?', '#'}: url.pathname &= "%20" else: url.pathname &= ' ' else: url.pathname.percentEncode(c, ControlPercentEncodeSet) i = nexti pointer = i return usDone proc parseSpecialAuthorityIgnoreSlashes(input: openArray[char]; pointer: var int): URLState = while pointer < input.len and input[pointer] in {'/', '\\'}: inc pointer return usAuthority proc parseRelativeSlash(input: openArray[char]; pointer: var int; base, url: URL): URLState = if url.isSpecial and pointer < input.len and input[pointer] in {'/', '\\'}: inc pointer return input.parseSpecialAuthorityIgnoreSlashes(pointer) if pointer < input.len and input[pointer] == '/': inc pointer return usAuthority url.username = base.username url.password = base.password url.hostname = base.hostname url.hostType = base.hostType url.port = base.port return usPath proc parseRelative(input: openArray[char]; pointer: var int; base, url: URL): URLState = url.scheme = base.scheme url.schemeType = base.schemeType assert url.schemeType != stFile if pointer < input.len and input[pointer] == '/' or url.isSpecial and pointer < input.len and input[pointer] == '\\': inc pointer return input.parseRelativeSlash(pointer, base, url) url.username = base.username url.password = base.password url.hostname = base.hostname url.hostType = base.hostType url.port = base.port url.pathname = base.pathname url.opaquePath = base.opaquePath url.search = base.search if pointer < input.len and input[pointer] == '?': url.search = "?" inc pointer return usQuery if pointer < input.len and input[pointer] == '#': url.hash = "#" inc pointer return usFragment url.search = "" url.shortenPath() return usPath proc parseSpecialRelativeOrAuthority(input: openArray[char]; pointer: var int; base, url: URL): URLState = if pointer + 1 < input.len and input[pointer] == '/' and input[pointer + 1] == '/': pointer += 2 return input.parseSpecialAuthorityIgnoreSlashes(pointer) return input.parseRelative(pointer, base, url) proc parseScheme(input: openArray[char]; pointer: var int; base, url: URL; override: bool): URLState = var buffer = "" var i = pointer while i < input.len: let c = input[i] if c in AsciiAlphaNumeric + {'+', '-', '.'}: buffer &= c.toLowerAscii() elif c == ':': let schemeType = parseSchemeType(buffer) let port = SpecialPort[schemeType] if override: if url.isSpecial != (port >= 0): return usNoScheme if (url.includesCredentials or url.port >= 0) and schemeType == stFile: return usNoScheme if url.hostType == htNone and url.schemeType == stFile: return usNoScheme url.scheme = move(buffer) url.schemeType = schemeType if override: if port == url.port: url.port = -1 return usDone pointer = i + 1 if url.schemeType == stFile: return usFile if url.isSpecial: if base != nil and base.scheme == url.scheme: return input.parseSpecialRelativeOrAuthority(pointer, base, url) # special authority slashes state if pointer + 1 < input.len and input[pointer] == '/' and input[pointer + 1] == '/': pointer += 2 return input.parseSpecialAuthorityIgnoreSlashes(pointer) if i + 1 < input.len and input[i + 1] == '/': inc pointer # path or authority state if pointer < input.len and input[pointer] == '/': inc pointer return usAuthority return usPath url.opaquePath = true url.pathname = "" return input.parseOpaquePath(pointer, url) else: break inc i return usNoScheme proc parseSchemeStart(input: openArray[char]; pointer: var int; base, url: URL; override: bool): URLState = var state = usNoScheme if pointer < input.len and input[pointer] in AsciiAlpha: # continue to scheme state state = input.parseScheme(pointer, base, url, override) if state == usNoScheme: pointer = 0 # start over if override: return usDone if state == usNoScheme: if base == nil: return usFail if base.opaquePath and (pointer >= input.len or input[pointer] != '#'): return usFail if base.opaquePath and pointer < input.len and input[pointer] == '#': url.scheme = base.scheme url.schemeType = base.schemeType url.pathname = base.pathname url.opaquePath = base.opaquePath url.search = base.search url.hash = "#" inc pointer return usFragment if base.schemeType == stFile: return usFile return input.parseRelative(pointer, base, url) return state proc parseAuthority(input: openArray[char]; pointer: var int; url: URL): URLState = var atSignSeen = false var passwordSeen = false var buffer = "" var beforeBuffer = pointer var i = pointer while i < input.len: let c = input[i] let nexti = i + 1 if c in {'/', '?', '#'} or url.isSpecial and c == '\\': break if c == '@': if atSignSeen: buffer = "%40" & buffer atSignSeen = true for c in buffer: if c == ':' and not passwordSeen: passwordSeen = true continue if passwordSeen: url.password.percentEncode(c, UserInfoPercentEncodeSet) else: url.username.percentEncode(c, UserInfoPercentEncodeSet) buffer = "" beforeBuffer = nexti else: buffer &= c i = nexti if atSignSeen and buffer == "": return usFail pointer = beforeBuffer return usHost proc parseFileHost(input: openArray[char]; pointer: var int; url: URL; override: bool): URLState = let buffer = input.until({'/', '\\', '?', '#'}, pointer) if not override and buffer.isWinDriveLetter(): return usPath pointer += buffer.len if buffer == "": url.hostType = htDomain url.hostname = "" else: var t = htNone var hostname = parseHost(buffer, url.schemeType, t) if t == htNone: return usFail url.hostType = t if t == htDomain and hostname == "localhost": url.hostname = "" else: url.hostname = move(hostname) if override: return usFail return usPathStart proc parseHostState(input: openArray[char]; pointer: var int; url: URL; override: bool; state: URLState): URLState = if override and url.schemeType == stFile: return input.parseFileHost(pointer, url, override) var insideBrackets = false var buffer = "" while pointer < input.len: let c = input[pointer] if c == ':' and not insideBrackets: if override and state == usHostname: return usFail var t = htNone let hostname = parseHost(buffer, url.schemeType, t) if t == htNone: return usFail url.hostname = hostname url.hostType = t inc pointer return usPort elif c in {'/', '?', '#'} or url.isSpecial and c == '\\': break else: if c == '[': insideBrackets = true elif c == ']': insideBrackets = false buffer &= c inc pointer if url.isSpecial and buffer == "": return usFail if override and buffer == "" and (url.includesCredentials or url.port >= 0): return usFail var t = htNone let hostname = parseHost(buffer, url.schemeType, t) if t == htNone: return usFail url.hostname = hostname url.hostType = t if override: return usFail return usPathStart proc parsePort(input: openArray[char]; pointer: var int; url: URL; override: bool): URLState = var buffer = "" var i = pointer while i < input.len: let c = input[i] if c in AsciiDigit: buffer &= c elif c in {'/', '?', '#'} or url.isSpecial and c == '\\' or override: break else: return usFail inc i pointer = i if buffer != "": let i = parseInt32(buffer).get(int32.high) # can't be negative, buffer only includes AsciiDigit if i > 65535: return usFail if SpecialPort[url.schemeType] == i: url.port = -1 else: url.port = i if override: return usFail return usPathStart proc startsWithWinDriveLetter(input: openArray[char]; i: int): bool = if i + 1 >= input.len: return false return input[i] in AsciiAlpha and input[i + 1] in {':', '|'} and (i + 2 >= input.len or input[i + 2] in {'/', '\\', '?', '#'}) proc parseFileSlash(input: openArray[char]; pointer: var int; base, url: URL; override: bool): URLState = if pointer < input.len and input[pointer] in {'/', '\\'}: inc pointer return input.parseFileHost(pointer, url, override) if base != nil and base.schemeType == stFile: url.hostname = base.hostname url.hostType = base.hostType if not input.startsWithWinDriveLetter(pointer) and base.pathname.len >= 3 and base.pathname[1] in AsciiAlpha and base.pathname[2] == ':': url.pathname &= '/' & base.pathname[1] & ':' return usPath proc parseFile(input: openArray[char]; pointer: var int; base, url: URL; override: bool): URLState = url.scheme = "file" url.schemeType = stFile url.hostname = "" url.hostType = htOpaque if pointer < input.len and input[pointer] in {'/', '\\'}: inc pointer return input.parseFileSlash(pointer, base, url, override) if base != nil and base.schemeType == stFile: url.hostname = base.hostname url.hostType = base.hostType url.pathname = base.pathname url.opaquePath = base.opaquePath url.search = base.search if pointer < input.len: let c = input[pointer] if c == '?': url.search = "?" inc pointer return usQuery elif c == '#': url.hash = "#" inc pointer return usFragment else: url.search = "" if not input.startsWithWinDriveLetter(pointer): url.shortenPath() else: url.pathname = "" return usPath proc parsePathStart(input: openArray[char]; pointer: var int; url: URL; override: bool): URLState = if url.isSpecial: if pointer < input.len and input[pointer] in {'/', '\\'}: inc pointer return usPath if pointer < input.len: let c = input[pointer] if not override: if c == '?': url.search = "?" inc pointer return usQuery if c == '#': url.hash = "#" inc pointer return usFragment if c == '/': inc pointer return usPath if override and url.hostType == htNone: url.pathname &= '/' inc pointer return usDone proc isSingleDotPathSegment(s: string): bool = s == "." or s.equalsIgnoreCase("%2e") proc isDoubleDotPathSegment(s: string): bool = s == ".." or s.equalsIgnoreCase(".%2e") or s.equalsIgnoreCase("%2e.") or s.equalsIgnoreCase("%2e%2e") proc parsePath(input: openArray[char]; pointer: var int; url: URL; override: bool): URLState = var state = usPath var buffer = "" while pointer < input.len: let c = input[pointer] if c == '/' or url.isSpecial and c == '\\' or not override and c in {'?', '#'}: if c == '?': url.search = "?" state = usQuery inc pointer break elif c == '#': url.hash = "#" state = usFragment inc pointer break let slashCond = c != '/' and (not url.isSpecial or c != '\\') if buffer.isDoubleDotPathSegment(): url.shortenPath() if slashCond: url.pathname &= '/' elif buffer.isSingleDotPathSegment() and slashCond: url.pathname &= '/' elif not buffer.isSingleDotPathSegment(): if url.schemeType == stFile and url.pathname == "" and buffer.isWinDriveLetter(): buffer[1] = ':' url.pathname &= '/' url.pathname &= buffer buffer = "" else: buffer.percentEncode(c, PathPercentEncodeSet) inc pointer let slashCond = pointer >= input.len or input[pointer] != '/' and (not url.isSpecial or input[pointer] != '\\') if buffer.isDoubleDotPathSegment(): url.shortenPath() if slashCond: url.pathname &= '/' elif buffer.isSingleDotPathSegment() and slashCond: url.pathname &= '/' elif not buffer.isSingleDotPathSegment(): if url.schemeType == stFile and url.pathname == "" and buffer.isWinDriveLetter(): buffer[1] = ':' url.pathname &= '/' url.pathname &= buffer return state proc parseQuery(input: openArray[char]; pointer: var int; url: URL; override: bool): URLState = #TODO encoding var buffer = "" var i = pointer while i < input.len: let c = input[i] if not override and c == '#': break buffer &= c inc i pointer = i let set = if url.isSpecial: SpecialQueryPercentEncodeSet else: QueryPercentEncodeSet url.search.percentEncode(buffer, set) if pointer < input.len: url.hash = "#" inc pointer return usFragment return usDone proc parseURLImpl(input: openArray[char]; base, url: URL; state: URLState; override: bool): URLState = var pointer = 0 let input = input.deleteChars({'\n', '\t'}) var state = state if state == usSchemeStart: state = input.parseSchemeStart(pointer, base, url, override) if state == usAuthority: state = input.parseAuthority(pointer, url) if state in {usHost, usHostname}: state = input.parseHostState(pointer, url, override, state) if state == usPort: state = input.parsePort(pointer, url, override) if state == usFile: state = input.parseFile(pointer, base, url, override) if state == usPathStart: state = input.parsePathStart(pointer, url, override) if state == usPath: state = input.parsePath(pointer, url, override) if state == usQuery: state = input.parseQuery(pointer, url, override) if state == usFragment: while pointer < input.len: url.hash.percentEncode(input[pointer], FragmentPercentEncodeSet) inc pointer return state #TODO encoding proc parseURL0*(input: string; base: URL = nil): URL = let url = URL(port: -1) const NoStrip = AllChars - C0Controls - {' '} let starti0 = input.find(NoStrip) let starti = if starti0 == -1: 0 else: starti0 let endi0 = input.rfind(NoStrip) let endi = if endi0 == -1: input.high else: endi0 if input.toOpenArray(starti, endi).parseURLImpl(base, url, usSchemeStart, override = false) == usFail: return nil return url proc parseURL1(input: string; url: URL; state: URLState) = discard input.parseURLImpl(base = nil, url, state, override = true) proc parseURL*(input: string; base: URL = nil): Opt[URL] = let url = parseURL0(input, base) if url == nil: return err() if url.schemeType == stBlob: #TODO blob urls discard ok(url) proc parseJSURL*(ctx: JSContext; s: string; base: URL = nil): Opt[URL] = let url = parseURL0(s, base) if url == nil: JS_ThrowTypeError(ctx, "%s is not a valid URL", cstring(s)) return err() ok(url) proc serializeip(ipv4: uint32): string = return $(ipv4 shr 24) & '.' & $((ipv4 shr 16) and 0xFF) & '.' & $((ipv4 shr 8) and 0xFF) & '.' & $(ipv4 and 0xFF) proc findZeroSeq(ipv6: array[8, uint16]): int = var maxi = -1 var maxn = 0 var newi = -1 var newn = 1 for i, n in ipv6: if n == 0: inc newn if newi == -1: newi = i else: if newn > maxn: maxn = newn maxi = newi newn = 0 newi = -1 if newn > maxn: return newi return maxi proc serializeip(ipv6: array[8, uint16]): string = let compress = findZeroSeq(ipv6) var ignore0 = false result = "[" for i, n in ipv6: if ignore0: if n == 0: continue else: ignore0 = false if i == compress: if i == 0: result &= "::" else: result &= ':' ignore0 = true continue result &= toHexLower(n) if i != ipv6.high: result &= ':' result &= ']' proc serialize*(url: URL; excludeHash = false; excludePassword = false): string = result = url.scheme & ':' if url.hostType != htNone: result &= "//" if url.includesCredentials: result &= url.username if not excludePassword and url.password != "": result &= ':' & url.password result &= '@' result &= url.hostname if url.port >= 0: result &= ':' & $url.port elif not url.opaquePath and url.pathname.len >= 2 and url.pathname[1] == '/': result &= "/." result &= url.pathname result &= url.search if not excludeHash: result &= url.hash proc equals*(a, b: URL; excludeHash = false): bool = return a.serialize(excludeHash) == b.serialize(excludeHash) proc `$`*(url: URL): string {.jsfunc: "toString".} = url.serialize() proc href(url: URL): string {.jsfget.} = return $url proc toJSON(url: URL): string {.jsfget.} = return $url # from a to b proc cloneInto(a, b: URL) = b[] = a[] b.searchParamsInternal = nil proc newURL*(url: URL): URL = result = URL() url.cloneInto(result) proc setHref(ctx: JSContext; url: URL; s: string) {.jsfset: "href".} = let purl = parseURL0(s) if purl != nil: purl.cloneInto(url) else: JS_ThrowTypeError(ctx, "%s is not a valid URL", s) proc isIP*(url: URL): bool = return url.hostType in {htIpv4, htIpv6} # https://url.spec.whatwg.org/#urlencoded-parsing proc parseFromURLEncoded(input: openArray[char]): seq[(string, string)] = result = @[] for s in input.split('&'): if s == "": continue var name = s.until('=') var value = s.after('=') for c in name.mitems: if c == '+': c = ' ' for c in value.mitems: if c == '+': c = ' ' result.add((name.percentDecode(), value.percentDecode())) # https://url.spec.whatwg.org/#urlencoded-serializing proc serializeFormURLEncoded*(kvs: seq[(string, string)]; spaceAsPlus = true): string = result = "" for (name, value) in kvs: if result.len > 0: result &= '&' result.percentEncode(name, ApplicationXWWWFormUrlEncodedSet, spaceAsPlus) result &= '=' result.percentEncode(value, ApplicationXWWWFormUrlEncodedSet, spaceAsPlus) proc newURLSearchParams(ctx: JSContext; init: JSValueConst = JS_UNDEFINED): Opt[URLSearchParams] {.jsctor.} = let params = URLSearchParams() if not JS_IsUndefined(init): if ctx.fromJS(init, params.list).isOk: discard elif (var t: JSKeyValuePair[string, string]; ctx.fromJS(init, t).isOk): params.list = move(t.s) else: var res: string ?ctx.fromJS(init, res) var i = 0 if res.len > 0 and res[0] == '?': inc i params.list = parseFromURLEncoded(res.toOpenArray(i, res.high)) return ok(params) proc searchParams(url: URL): URLSearchParams {.jsfget.} = if url.searchParamsInternal == nil: let i = int(url.search.len > 0) url.searchParamsInternal = URLSearchParams( list: parseFromURLEncoded(url.search.toOpenArray(i, url.search.high)), url: url ) return url.searchParamsInternal proc `$`*(params: URLSearchParams): string {.jsfunc: "toString".} = return serializeFormURLEncoded(params.list) proc update(params: URLSearchParams) = if params.url == nil: return let serializedQuery = $params if serializedQuery == "": params.url.search = "" else: params.url.search = "?" & serializedQuery proc append(params: URLSearchParams; name, value: sink string) {.jsfunc.} = params.list.add((name, value)) params.update() proc delete(params: URLSearchParams; name: string) {.jsfunc.} = for i in countdown(params.list.high, 0): if params.list[i][0] == name: params.list.delete(i) params.update() proc get(ctx: JSContext; params: URLSearchParams; name: string): JSValue {.jsfunc.} = for it in params.list: if it.name == name: return ctx.toJS(it.value) return JS_NULL proc getAll(params: URLSearchParams; name: string): seq[string] {.jsfunc.} = result = newSeq[string]() for it in params.list: if it.name == name: result.add(it.value) proc has(ctx: JSContext; params: URLSearchParams; name: string; jsValue: JSValueConst = JS_UNDEFINED): JSValue {.jsfunc.} = if JS_IsUndefined(jsValue): for it in params.list: if it.name == name: return JS_TRUE else: var value: string if ctx.fromJS(jsValue, value).isErr: return JS_EXCEPTION for it in params.list: if it.name == name and value == it.value: return JS_TRUE return JS_FALSE proc set(params: URLSearchParams; name: string; value: sink string) {.jsfunc.} = var found = false for param in params.list.mitems: if param.name == name: param.value = value found = true break if found: params.update() else: params.append(name, value) proc newURL*(ctx: JSContext; s: string; base: JSValueConst = JS_UNDEFINED): Opt[URL] {.jsctor.} = var baseURL: URL = nil if not JS_IsUndefined(base): var s: string if ctx.fromJS(base, s).isErr: return err() baseURL = ?ctx.parseJSURL(s) ctx.parseJSURL(s, baseURL) proc origin*(url: URL): Origin = case url.schemeType of stBlob: #TODO let pathURL = parseURL(url.pathname) if pathURL.isErr: return Origin(t: otOpaque, s: $url) return pathURL.get.origin of stFtp, stHttp, stHttps, stWs, stWss: return Origin(t: otTuple, s: url.scheme & "://" & url.host) else: return Origin(t: otOpaque, s: $url) # Whether the URL is a net path (ref. RFC 2396). # In general, this means that its serialization will look like # "scheme://host:port/blah" instead of "scheme:/blah", *except* for # file URLs which are special-cased for legacy reasons (they become # "file:///blah", but are treated as absoluteURI). proc isNetPath*(url: URL): bool = return url.hostType != htNone and url.schemeType != stFile # This follows somewhat different rules from the standard: # * for URLs with a net_path, the origin is opaque. # * with other host types, the origin is a tuple origin. proc authOrigin*(url: URL): Origin = if url.isNetPath(): return Origin(t: otTuple, s: url.scheme & "://" & url.host) return Origin(t: otOpaque, s: $url) proc `==`*(a, b: Origin): bool {.error.} = discard proc isSameOrigin*(a, b: Origin): bool = return a.t == b.t and a.s == b.s proc `$`*(origin: Origin): string = if origin.t == otOpaque: return "null" return origin.s proc jsOrigin*(url: URL): string {.jsfget: "origin".} = return $url.origin proc protocol*(ctx: JSContext; url: URL): JSValue {.jsfget.} = if url.schemeType == stUnknown: return ctx.toJS(url.scheme & ':') const enumId = getJSEnumId(SchemeType) let n = int(url.schemeType) let rt = JS_GetRuntime(ctx) let rtOpaque = rt.getOpaque() if rtOpaque.enumMap.len <= enumId: rtOpaque.enumMap.setLen(enumId + 1) if rtOpaque.enumMap[enumId].atoms.len <= n: rtOpaque.enumMap[enumId].atoms.setLen(n + 1) var atom = rtOpaque.enumMap[enumId].atoms[n] if atom == JS_ATOM_NULL: let s = url.scheme & ':' atom = JS_NewAtomLen(ctx, cstringConst(s), csize_t(s.len)) if atom == JS_ATOM_NULL: return JS_EXCEPTION rtOpaque.enumMap[enumId].atoms[n] = atom return JS_AtomToValue(ctx, atom) proc setProtocol*(url: URL; s: string) {.jsfset: "protocol".} = parseURL1(s & ':', url, usSchemeStart) proc scheme*(url: URL): lent string = return url.scheme proc setUsername*(url: URL; username: string) {.jsfset: "username".} = if url.isNetPath(): url.username = username.percentEncode(UserInfoPercentEncodeSet) proc setPassword*(url: URL; password: string) {.jsfset: "password".} = if url.isNetPath(): url.password = password.percentEncode(UserInfoPercentEncodeSet) proc host*(url: URL): string {.jsfget.} = if url.hostType == htNone: return "" if url.port >= 0: return url.hostname & ':' & $url.port return url.hostname proc setHost*(url: URL; s: string) {.jsfset: "host".} = if not url.opaquePath: parseURL1(s, url, usHost) proc setHostname*(url: URL; s: string) {.jsfset: "hostname".} = if not url.opaquePath: parseURL1(s, url, usHostname) proc port*(url: URL): string {.jsfget.} = if url.port >= 0: return $url.port return "" proc setPort*(url: URL; s: string) {.jsfset: "port".} = if url.isNetPath(): if s == "": url.port = -1 else: parseURL1(s, url, usPort) proc setPathname*(url: URL; s: string) {.jsfset: "pathname".} = if not url.opaquePath: url.pathname = "" parseURL1(s, url, usPathStart) proc setSearch*(url: URL; s: string) {.jsfset: "search".} = if s.len <= 0: url.search = "" if url.searchParamsInternal != nil: url.searchParamsInternal.list.setLen(0) return let s = if s[0] == '?': s.substr(1) else: s url.search = "?" parseURL1(s, url, usQuery) if url.searchParamsInternal != nil: url.searchParamsInternal.list = parseFromURLEncoded(s) proc setHash*(url: URL; s: string) {.jsfset: "hash".} = if s.len <= 0: url.hash = "" else: let s = if s[0] == '#': s.substr(1) else: s url.hash = "#" parseURL1(s, url, usFragment) proc jsParse(ctx: JSContext; url: string; base: JSValueConst = JS_UNDEFINED): URL {.jsstfunc: "URL#parse".} = return ctx.newURL(url, base).get(nil) proc canParse(ctx: JSContext; url: string; base: JSValueConst = JS_UNDEFINED): bool {.jsstfunc: "URL".} = return ctx.newURL(url, base).isOk proc addURLModule*(ctx: JSContext): Opt[void] = ?ctx.registerType(URL) ?ctx.registerType(URLSearchParams) ok() {.pop.} # raises: [] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/types/winattrs.nim����������������������������������������������������������������0000664�0000000�0000000�00000000747�15202323131�0017455�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import config/conftypes type WindowAttributes* = object width*: int height*: int ppc*: int # cell width (pixels per char) ppl*: int # cell height (pixels per line) widthPx*: int heightPx*: int prefersDark*: bool # prefers-color-scheme accepts "dark" (not "light") colorMode*: ColorMode let dummyAttrs* {.global.} = WindowAttributes( width: 80, height: 24, ppc: 9, ppl: 18, widthPx: 80 * 9, heightPx: 24 * 18, prefersDark: true, colorMode: cmTrueColor ) �������������������������chawan-v0.4.0/src/utils/����������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0015061�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/utils/dtoawrap.nim����������������������������������������������������������������0000664�0000000�0000000�00000002050�15202323131�0017404�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import monoucha/dtoa # n: start pointer -> end pointer # dtoa assumes NUL-termination, so s must be a cstring. # returns NaN if s doesn't start with a number. proc atod*(s: cstring; n: var int; radix = cint(10); flags = cint(0)): float64 = let cs = cast[cstringConst](unsafeAddr s[n]) var tmp: JSATODTempMem var pnext = cs let res = js_atod(cs, addr pnext, radix, flags, tmp) n += cast[int](cast[uint](pnext) - cast[uint](cs)) float64(res) proc parseFloat64*(s: string): float64 = var i = 0 let res = atod(cstring(s), i) if i < s.len: return NaN return res proc addDouble*(s: var string; d: float64) = let d = cdouble(d) let m = js_dtoa_max_len(d, 10, 0, JS_DTOA_FORMAT_FREE) let olen = s.len # Note: this relies on Nim strings having a NUL term by default (because # js_dtoa writes one). s.setLen(olen + int(m)) var tmp: JSDTOATempMem let n = js_dtoa(cast[cstring](addr s[olen]), d, 10, 0, JS_DTOA_FORMAT_FREE, tmp) s.setLen(olen + int(n)) proc dtoa*(d: float64): string = result = "" result.addDouble(d) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/utils/eprint.nim������������������������������������������������������������������0000664�0000000�0000000�00000001667�15202323131�0017101�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.used.} template eprint0(s: varargs[string]) = {.cast(noSideEffect), cast(tags: []), cast(raises: []).}: var o = "" for i in 0 ..< s.len: if i != 0: o &= ' ' o &= s[i] when nimvm: echo o else: when declared(stderr): o &= '\n' stderr.write(o) else: echo o when defined(release): func eprint*(s: varargs[string, `$`]) {.deprecated: "eprint is for debugging only".} = eprint0(s) else: func eprint*(s: varargs[string, `$`]) = eprint0(s) proc c_fprintf*(f: File, frmt: cstring): cint {. importc: "fprintf", header: "<stdio.h>", varargs, discardable.} func elog*(s: varargs[string, `$`]) = {.cast(noSideEffect), cast(tags: []), cast(raises: []).}: var f: File = nil if not f.open("a", fmAppend): return var o = "" for i in 0 ..< s.len: if i != 0: o &= ' ' o &= s[i] o &= '\n' f.write(o) close(f) �������������������������������������������������������������������������chawan-v0.4.0/src/utils/lrewrap.nim�����������������������������������������������������������������0000664�0000000�0000000�00000012137�15202323131�0017246�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import monoucha/libregexp import types/opt when NimMajor < 2: from utils/twtstr import substr type Regex* = object bytecode*: string REBytecode* = distinct ptr uint8 proc bytecodeToRegex*(p: REBytecode; plen: cint): Regex = let plen = int(plen) let p = cast[ptr UncheckedArray[char]](p) result = Regex(bytecode: p.toOpenArray(0, plen - 1).substr()) proc compileRegex*(buf: string; flags: LREFlags; regex: var Regex): bool = ## Compile a regular expression using QuickJS's libregexp library. ## If the result is false, regex.bytecode stores the error message emitted ## by libregexp instead. ## ## Use `exec` to actually use the resulting bytecode on a string. var errorMsg = newString(64) var plen: cint let bytecode = lre_compile(plen, cstring(errorMsg), cint(errorMsg.len), cstring(buf), csize_t(buf.len), flags.toCInt, nil) if bytecode == nil: # Failed to compile. let i = errorMsg.find('\0') if i != -1: errorMsg.setLen(i) regex = Regex(bytecode: move(errorMsg)) return false assert plen > 0 regex = bytecodeToRegex(cast[REBytecode](bytecode), plen) dealloc(bytecode) true type ExecContext* = object bytecode: ptr uint8 tmp: seq[ptr uint8] base: uint proc initContext*(bytecode: REBytecode): ExecContext = let bytecode = cast[ptr uint8](bytecode) let allocCount = lre_get_alloc_count(bytecode) ExecContext( bytecode: bytecode, tmp: newSeq[ptr uint8](int(allocCount)) ) proc initContext*(regex: Regex): ExecContext = initContext(cast[REBytecode](unsafeAddr regex.bytecode[0])) template ncaps(ctx: ExecContext): cint = lre_get_capture_count(ctx.bytecode) proc cap*(ctx: ExecContext; i: int): tuple[s, e: int] = assert i < int(ctx.ncaps) let sp = ctx.tmp[i * 2] let ep = ctx.tmp[i * 2 + 1] if sp == nil or ep == nil: return (-1, -1) let s = cast[int](cast[uint](sp) - ctx.base) let e = cast[int](cast[uint](ep) - ctx.base) return (s, e) iterator caps*(ctx: ExecContext): tuple[s, e: int] = for i in 0 ..< ctx.ncaps: yield ctx.cap(i) iterator exec*(ctx: var ExecContext; s: openArray[char]; start = 0): cint = let L = cint(min(int(cint.high), s.len)) let pcapture = if ctx.tmp.len > 0: addr ctx.tmp[0] else: nil let base = if s.len > 0: cast[ptr uint8](unsafeAddr s[0]) else: nil let flags = lre_get_flags(ctx.bytecode).toLREFlags() ctx.base = cast[uint](base) var start = cint(min(int(cint.high), start)) while start < L: let ret = lre_exec(pcapture, ctx.bytecode, base, start, L, 3, nil) yield ret if ret != 1 or LRE_FLAG_GLOBAL notin flags: break let pstart = start start = cast[cint](ctx.cap(0).e) if pstart == start: # avoid infinite loop: skip the first UTF-8 char. inc start while start < s.len and uint8(s[start]) in 0x80u8 .. 0xBFu8: inc start iterator matchCap*(regex: Regex; s: openArray[char]; cap: int; start = 0): tuple[s, e: int] = var ctx = initContext(regex) for ret in ctx.exec(s, start): if ret != 1: break yield ctx.cap(cap) proc matchFirst(ctx: var ExecContext; str: openArray[char]; start = 0): tuple[s, e: int] = for ret in ctx.exec(str, start): if ret != 1: break return ctx.cap(0) return (-1, -1) proc match*[T: Regex|REBytecode](regex: T; s: openArray[char]; start = 0): bool = var ctx = initContext(regex) ctx.matchFirst(s, start).s != -1 proc matchLast(ctx: var ExecContext; str: openArray[char]; start = 0): tuple[s, e: int] = var res = (-1, -1) for ret in ctx.exec(str, start): if ret != 1: break res = ctx.cap(0) res proc matchFirst*[T: Regex|REBytecode](regex: T; str: openArray[char]; start = 0): tuple[s, e: int] = var ctx = initContext(regex) ctx.matchFirst(str, start) proc matchLast*[T: Regex|REBytecode](regex: T; str: openArray[char]; start = 0): tuple[s, e: int] = var ctx = initContext(regex) ctx.matchLast(str, start) proc countBackslashes(buf: string; i: int): int = var j = 0 for i in countdown(i, 0): if buf[i] != '\\': break inc j return j proc compileRegex(buf: string; flags: LREFlags = {}): Result[Regex, string] = var regex: Regex if not compileRegex(buf, flags, regex): return err(regex.bytecode) ok(move(regex)) # ^abcd -> ^abcd # efgh$ -> efgh$ # ^ijkl$ -> ^ijkl$ # mnop -> ^mnop$ proc compileMatchRegex*(buf: string): Result[Regex, string] = if buf.len <= 0: return compileRegex(buf) if buf[0] == '^': return compileRegex(buf) if buf[^1] == '$': # Check whether the final dollar sign is escaped. if buf.len == 1 or buf[^2] != '\\': return compileRegex(buf) let j = buf.countBackslashes(buf.high - 2) if j mod 2 == 1: # odd, because we do not count the last backslash return compileRegex(buf) # escaped. proceed as if no dollar sign was at the end if buf[^1] == '\\': # Check if the regex contains an invalid trailing backslash. let j = buf.countBackslashes(buf.high - 1) if j mod 2 != 1: # odd, because we do not count the last backslash return err("unexpected end") var buf2 = "^" buf2 &= buf buf2 &= "$" return compileRegex(buf2) {.pop.} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/utils/luwrap.nim������������������������������������������������������������������0000664�0000000�0000000�00000010412�15202323131�0017076�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/algorithm import monoucha/libunicode import monoucha/libregexp import utils/twtstr proc passRealloc(opaque, p: pointer; size: csize_t): pointer {.cdecl.} = return realloc(p, cast[int](size)) proc normalize*(rs: openArray[uint32]; form = UNICODE_NFC): seq[uint32] = if rs.len <= 0: return @[] var outbuf: ptr uint32 let p = cast[ptr uint32](unsafeAddr rs[0]) let out_len = unicode_normalize(addr outbuf, p, cint(rs.len), form, nil, passRealloc) if out_len <= 0: return @[] var rs = newSeqUninit[uint32](int(out_len)) copyMem(addr rs[0], outbuf, out_len * sizeof(uint32)) dealloc(outbuf) return rs proc mnormalize*(s: var string) = if NonAscii notin s: return # no need to normalize ascii s = s.toPoints().normalize().toUTF8() # n == 0: upper, 1: lower, 2: case fold proc toUpperLU(s: string; n: cint): string = result = newStringOfCap(s.len) for u in s.points: var outa {.noinit.}: array[LRE_CC_RES_LEN_MAX, uint32] let n = lre_case_conv(cast[ptr UncheckedArray[uint32]](addr outa[0]), u, n) result.addUTF8(outa.toOpenArray(0, n - 1)) proc toUpperLU*(s: string): string = return s.toUpperLU(0) proc toLowerLU*(s: string): string = return s.toUpperLU(1) proc capitalizeLU*(s: string): string = result = newStringOfCap(s.len) var wordStart = true for u in s.points: if lre_is_space(u): wordStart = true result.addUTF8(u) elif wordStart: var outa {.noinit.}: array[LRE_CC_RES_LEN_MAX, uint32] let n = lre_case_conv(cast[ptr UncheckedArray[uint32]](addr outa[0]), u, 0) result.addUTF8(outa.toOpenArray(0, n - 1)) wordStart = false else: result.addUTF8(u) type u32pair* {.packed.} = object a: uint32 b: uint32 proc cmpRange*(x: u32pair; y: uint32): int = if x.a > y: return 1 elif x.b <= y: return -1 return 0 proc contains(cr: CharRange; u: uint32): bool = let cps = cast[ptr UncheckedArray[u32pair]](cr.points) let L = cr.len div 2 - 1 return cps.toOpenArray(0, L).binarySearch(u, cmpRange) != -1 type LURangeType = enum lurLetter = "Letter" lurSeparator = "Separator" lurOther = "Other" lurMark = "Mark" lurEnclosingMark = "Me" lurNonspacingMark = "Mn" lurFormat = "Cf" lurBidiControl = "Bidi_Control" lurIDSU = "IDSU" lurIDSB = "IDSB" lurIDST = "IDST" LUContextObj = object crs: array[LURangeType, CharRange] inited: set[LURangeType] LUContext* = ref LUContextObj proc `=destroy`*(ctx: var LUContextObj) = for lur, cr in ctx.crs.mpairs: if lur in ctx.inited: cr_free(addr cr) ctx.inited = {} proc initGeneralCategory(ctx: LUContext; lur: LURangeType) = if lur notin ctx.inited: let p = addr ctx.crs[lur] cr_init(p, nil, passRealloc) doAssert unicode_general_category(p, cstring($lur)) == 0 ctx.inited.incl(lur) proc initProp(ctx: LUContext; lur: LURangeType) = if lur notin ctx.inited: let p = addr ctx.crs[lur] cr_init(p, nil, passRealloc) doAssert unicode_prop(p, cstring($lur)) == 0 ctx.inited.incl(lur) proc isAlpha*(ctx: LUContext; u: uint32): bool = ctx.initGeneralCategory(lurLetter) return u in ctx.crs[lurLetter] proc isWhiteSpace*(ctx: LUContext; u: uint32): bool = ctx.initGeneralCategory(lurSeparator) return u in ctx.crs[lurSeparator] proc isOther*(ctx: LUContext; u: uint32): bool = ctx.initGeneralCategory(lurOther) return u in ctx.crs[lurOther] proc isMark*(ctx: LUContext; u: uint32): bool = ctx.initGeneralCategory(lurMark) return u in ctx.crs[lurMark] proc isEnclosingMark*(ctx: LUContext; u: uint32): bool = ctx.initGeneralCategory(lurEnclosingMark) return u in ctx.crs[lurEnclosingMark] proc isNonspacingMark*(ctx: LUContext; u: uint32): bool = ctx.initGeneralCategory(lurNonspacingMark) return u in ctx.crs[lurNonspacingMark] proc isFormat*(ctx: LUContext; u: uint32): bool = ctx.initGeneralCategory(lurFormat) return u in ctx.crs[lurFormat] proc isBidiControl*(ctx: LUContext; u: uint32): bool = ctx.initProp(lurBidiControl) return u in ctx.crs[lurBidiControl] proc isIDSOperator*(ctx: LUContext; u: uint32): bool = ctx.initProp(lurIDSU) ctx.initProp(lurIDSB) ctx.initProp(lurIDST) return u in ctx.crs[lurIDSU] or u in ctx.crs[lurIDSB] or u in ctx.crs[lurIDST] {.pop.} # raises: [] ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/utils/myaddr.nim������������������������������������������������������������������0000664�0000000�0000000�00000001427�15202323131�0017052�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Before 2.0, `addr' only worked on mutable types, and `unsafeAddr' # was needed to take the address of immutable ones. # # This was changed in 2.0 for some incomprehensible reason, even though # it's still a useful distinction (it catches bugs). # # This module fixes the above problem; it is automatically included # in every file by nim.cfg. # # Additionally, this adds a backport of newSeqUninit which is exactly # the same as newSeqUninitialized but with a different name. const msg = "expression has no address; maybe use `unsafeAddr'" template addr(x: auto): auto {.used, error: msg.} = discard template addr(x: var auto): auto {.used.} = system.addr x when not declared(newSeqUninit): template newSeqUninit[T](len: typed): seq[T] {.used.} = newSeqUninitialized[T](len) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/utils/myposix.nim�����������������������������������������������������������������0000664�0000000�0000000�00000002154�15202323131�0017300�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# misc OS-specific wrappers {.push raises: [].} import std/os import std/posix proc free(p: pointer) {.importc, header: "<stdlib.h>".} proc realPath(path: string): string = let p = realpath(cstring(path), nil) if p == nil: return "" var s = $p free(p) move(s) # std's getcwd binding uses int for size, but it's size_t... proc my_getcwd(buf: cstring; size: csize_t): cstring {. importc: "getcwd", header: "<unistd.h>".} proc getcwd*(): string = var s = newString(4096) let cs = my_getcwd(cstring(s), csize_t(s.len)) if cs == nil: return "" $cs proc system*(cmd: cstring): cint {.importc, header: "<stdlib.h>".} proc getAppFilename*(): string = result = "" try: result = os.getAppFilename() # The NetBSD sysctl does not resolve symlinks. result = realPath(result) except OSError: discard type SighandlerT = proc(sig: cint) {.cdecl, raises: [].} let SIG_DFL* {.importc, header: "<signal.h>".}: SighandlerT let SIG_IGN* {.importc, header: "<signal.h>".}: SighandlerT proc signal*(signum: cint; handler: SighandlerT): SighandlerT {. importc, header: "<signal.h>".} {.pop.} ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/utils/proctitle.nim���������������������������������������������������������������0000664�0000000�0000000�00000002323�15202323131�0017573�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import types/url when defined(freebsd): proc c_setproctitle(fmt: cstring) {.header: "<unistd.h>", importc: "setproctitle", varargs.} elif defined(netbsd) or defined(openbsd): proc c_setproctitle(fmt: cstring) {.header: "<stdlib.h>", importc: "setproctitle", varargs.} elif defined(linux): let PR_SET_NAME {.importc, header: "<sys/prctl.h>", nodecl.}: cint proc prctl(option: cint; arg2, arg3, arg4, arg5: culong): cint {.importc, header: "<sys/prctl.h>".} proc setProcessTitle*(s: string) = when defined(freebsd) or defined(netbsd) or defined(openbsd): c_setproctitle("%s", cstring(s)) elif defined(linux): discard prctl(PR_SET_NAME, cast[culong](cstring(s)), 0, 0, 0) when defined(linux): import utils/twtstr proc setBufferProcessTitle*(url: URL) = when defined(linux): # linux truncates to 15 chars; try to preserve important info const initTitle = "cha buf " var title = initTitle var hostname = url.hostname if hostname.startsWith("www."): hostname.delete(0.."www.".high) title &= hostname if title.len > initTitle.len: title &= ' ' title &= url.pathname.afterLast('/') setProcessTitle(title) else: setProcessTitle("cha buffer " & $url) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/utils/proptable.nim���������������������������������������������������������������0000664�0000000�0000000�00000001201�15202323131�0017550�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Lookup tables for characters on the BMP. This "only" takes up 8k of space # per table, as opposed to the 135k that storing all characters would require. # The downside is obviously that we need a binary search fallback for non-bmp. # We do not store a lookup table of ambiguous ranges, either. type ptint* = uint32 PropertyTable* = array[0x10000 div (sizeof(ptint) * 8), ptint] RangeMap* = openArray[(uint32, uint32)] {.push boundChecks:off.} proc contains*(props: PropertyTable; u: ptint): bool {.inline.} = const isz = sizeof(ptint) * 8 let i = u div isz let m = u mod isz return (props[i] and (1u32 shl m)) != 0 {.pop.} �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/utils/sandbox.nim�����������������������������������������������������������������0000664�0000000�0000000�00000006425�15202323131�0017233�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Security model with sandboxing: # # Buffer processes are the most security-sensitive, since they parse # various resources retrieved from the network (CSS, HTML) and sometimes # even execute untrusted code (JS, with an engine written in C). So the # main goal is to give buffers as few permissions as possible. # # Aside from sandboxing in buffer processes, we also have a more # restrictive "network" sandbox that is intended for CGI processes that # just read/write from/to the network and stdin/stdout. At the moment this # is used in the HTTP, FTP, SFTP, Gemini handlers, and all image # manipulation processes (codecs and resize). # # On FreeBSD, we enter capability mode with cap_enter. Since buffers # do not do anything that Capsicum does not allow (they receive their # UNIX sockets from the fork server), this is enough to lock down the # process. # # On OpenBSD, we pledge the minimum amount of promises we need, and # do not unveil anything. It seems to be roughly equivalent to the # security we get with FreeBSD Capsicum. # # On Linux, we use chaseccomp which is a very dumb BPF assembler for # seccomp-bpf. It only allows syscalls deemed to be safe, which has the # unique problem that a libc change can render the program unusable at # any time. # # We do not have syscall sandboxing on other systems (yet). {.push raises: [].} const disableSandbox {.booldefine.} = false type SandboxType* = enum stNone = "no sandbox" stCapsicum = "capsicum" stPledge = "pledge" stSeccomp = "seccomp-bpf" const SandboxMode* = when disableSandbox: stNone elif defined(freebsd): stCapsicum elif defined(openbsd): stPledge elif defined(linux): stSeccomp else: stNone when SandboxMode == stCapsicum: proc cap_enter(): cint {.importc, cdecl, header: "<sys/capsicum.h>".} proc enterBufferSandbox*() = # per man:cap_enter(2), it may return ENOSYS if the kernel was compiled # without CAPABILITY_MODE. So it seems better not to panic in this case. # (But TODO: when we get enough sandboxing coverage it should print a # warning or something.) discard cap_enter() proc enterNetworkSandbox*() = # no difference between buffer; Capsicum is quite straightforward # to use in this regard. discard cap_enter() elif SandboxMode == stPledge: proc pledge(promises, execpromises: cstring): cint {.importc, cdecl, header: "<unistd.h>".} proc enterBufferSandbox*() = # take whatever we need to send/receive fds doAssert pledge("stdio sendfd recvfd", nil) == 0 proc enterNetworkSandbox*() = # we don't need much to write out data from sockets to stdout. doAssert pledge("stdio", nil) == 0 elif SandboxMode == stSeccomp: proc sourceParent(): string = var s = currentSourcePath() while s.len > 0 and s[^1] != '/': s.setLen(s.len - 1) move(s) {.passl: sourceParent() & "../../lib/chaseccomp/chaseccomp.o".} proc cha_enter_buffer_sandbox(): cint {.importc, cdecl.} proc cha_enter_network_sandbox(): cint {.importc, cdecl.} proc enterBufferSandbox*() = doAssert cha_enter_buffer_sandbox() == 1 proc enterNetworkSandbox*() = doAssert cha_enter_network_sandbox() == 1 else: {.warning: "Building without syscall sandboxing!".} proc enterBufferSandbox*() = discard proc enterNetworkSandbox*() = discard {.pop.} # raises: [] �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/utils/strwidth.nim����������������������������������������������������������������0000664�0000000�0000000�00000005606�15202323131�0017445�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import utils/proptable import utils/twtstr include res/charwidth_gen # Tabs are a bit of a problem: depending on their position in text, they may # represent one to eight characters. Inferring their size after layout is wrong # because a rendered line is obviously not equivalent to a CSS line. # # In the past, we worked around this by always passing the string's current # width to width(), but this only ever worked properly for plain text documents, # which we no longer distinguish from HTML. # # So now, to preserve tabs, we do the following: # # * Define Unicode PUA U+E000 to U+E007 as a tab range. The final digit # represents the number of characters the tab occupies, minus one. (Tab size # ranges from 1 char to 8 chars.) # * In layout, replace characters in this range with U+FFFD. Then, translate # literal tabs into the range depending on their width in the document. # * In width(), substitute the size of these characters accordingly. # * Finally, in buffer drawing code, translate the range back into the necessary # number of spaces - except in dump mode, where properly aligned tabs become # hard tabs, and in selection mode, where *all* tabs become hard tabs. const TabPUARange* = 0xE000u32 .. 0xE007u32 proc tabPUAPoint*(n: int): uint32 = let u = 0xE000 + uint32(n) - 1 assert u in TabPUARange return u var isCJKAmbiguous* {.global.} = false # Warning: this shouldn't be called without normalization. proc width*(u: uint32): int = if u <= 0xFFFF: # fast path for BMP if u in DoubleWidthTable: return 2 if u in 0x80u32 .. 0x9Fu32: # Represent Unicode control chars as [XX] where X is a hex digit. return 4 if u in TabPUARange: return int(((u - TabPUARange.a) and 7) + 1) else: if DoubleWidthRanges.isInRange(u): return 2 if isCJKAmbiguous and DoubleWidthAmbiguousRanges.isInRange(u): return 2 return 1 proc width*(s: openArray[char]): int = var w = 0 for u in s.points: w += u.width() return w proc width*(s: string; start, len: int): int = var w = 0 var i = start var m = len if m > s.len: m = s.len while i < m: let u = s.nextUTF8(i) w += u.width() return w proc padToWidth*(s: string; size: uint32): string = result = newStringOfCap(s.len) var w = 0u32 var i = 0 var pi = 0 while i < s.len: pi = i w += uint32(s.nextUTF8(i).width()) if w > size: break for j in pi ..< i: result &= s[j] while w < size: result &= ' ' inc w # Expand all PUA tabs into hard tabs, disregarding their position. # (This is mainly intended for copy/paste, where the actual characters # are more interesting than cell alignment.) proc expandPUATabsHard*(s: openArray[char]): string = var res = newStringOfCap(s.len) var i = 0 while i < s.len: let pi = i if s.nextUTF8(i) in TabPUARange: res &= '\t' else: for j in pi ..< i: res &= s[j] move(res) ��������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/utils/twtstr.nim������������������������������������������������������������������0000664�0000000�0000000�00000076275�15202323131�0017156�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{.push raises: [].} import std/algorithm import std/math import std/posix import types/opt const AllChars* = {char.low..char.high} const C0Controls* = {'\0'..'\x1F'} const Controls* = C0Controls + {'\x7F'} const Ascii* = {'\0'..'\x7F'} const AsciiUpperAlpha* = {'A'..'Z'} const AsciiLowerAlpha* = {'a'..'z'} const AsciiAlpha* = AsciiUpperAlpha + AsciiLowerAlpha const NonAscii* = {'\x80'..'\xFF'} const AsciiDigit* = {'0'..'9'} const AsciiAlphaNumeric* = AsciiAlpha + AsciiDigit const AsciiHexDigit* = AsciiDigit + {'a'..'f', 'A'..'F'} const AsciiWhitespace* = {' ', '\n', '\r', '\t', '\f'} const HTTPWhitespace* = {' ', '\n', '\r', '\t'} const NonDigit* = AllChars - AsciiDigit type BoxDrawingChar* = enum bdcHorizontalBarTop = "\u2500" bdcHorizontalBarBottom = "\u2500" bdcVerticalBarLeft = "\u2502" bdcVerticalBarRight = "\u2502" bdcCornerTopLeft = "\u250C" bdcCornerTopRight = "\u2510" bdcCornerBottomLeft = "\u2514" bdcCornerBottomRight = "\u2518" bdcSideBarLeft = "\u251C" bdcSideBarRight = "\u2524" bdcSideBarTop = "\u252C" bdcSideBarBottom = "\u2534" bdcSideBarCross = "\u253C" const HorizontalBar* = {bdcHorizontalBarTop, bdcHorizontalBarBottom} const VerticalBar* = {bdcVerticalBarLeft, bdcVerticalBarRight} proc nextUTF8*(s: openArray[char]; i: var int): uint32 = var j = i var u = uint32(s[j]) {.push overflowChecks: off, boundChecks: off.} inc j # can't overflow if s[j] didn't panic if u <= 0x7F: i = j return u block good: var min = 0x80u32 var n = 1 if u shr 5 == 0b110: u = u and 0x1F elif u shr 4 == 0b1110: min = 0x800 n = 2 u = u and 0xF elif likely(u shr 3 == 0b11110): min = 0x10000 n = 3 u = u and 7 else: break good while true: if unlikely(j >= s.len): break good let u2 = uint32(s[j]) if unlikely((u2 shr 6) != 2): break good u = (u shl 6) or u2 and 0x3F inc j dec n if n == 0: break if u - min <= 0x10FFFF - min: i = j return u {.pop.} i = j 0xFFFD proc prevUTF8*(s: openArray[char]; i: var int): uint32 = var j = i - 1 while uint32(s[j]) shr 6 == 2: dec j i = j return s.nextUTF8(j) proc pointLenAt*(s: openArray[char]; i: int): int = var j = i discard s.nextUTF8(j) return j - i iterator points*(s: openArray[char]): uint32 {.inline.} = var i = 0 while i < s.len: let u = s.nextUTF8(i) yield u proc addPoints*(res: var seq[uint32]; s: openArray[char]) = for u in s.points: res.add(u) proc toPoints*(s: openArray[char]): seq[uint32] = result = @[] result.addPoints(s) proc addUTF8*(res: var string; u: uint32) = if u < 0x80: res &= char(u) elif u < 0x800: res &= char(u shr 6 or 0xC0) res &= char(u and 0x3F or 0x80) elif u < 0x10000: res &= char(u shr 12 or 0xE0) res &= char(u shr 6 and 0x3F or 0x80) res &= char(u and 0x3F or 0x80) else: res &= char(u shr 18 or 0xF0) res &= char(u shr 12 and 0x3F or 0x80) res &= char(u shr 6 and 0x3F or 0x80) res &= char(u and 0x3F or 0x80) proc addUTF8*(res: var string; us: openArray[uint32]) = for u in us: res.addUTF8(u) proc toUTF8*(u: uint32): string = result = "" result.addUTF8(u) proc toUTF8*(us: openArray[uint32]): string = result = newStringOfCap(us.len) result.addUTF8(us) proc pointLen*(s: openArray[char]): int = var n = 0 for u in s.points: inc n return n proc isInRange*[U](a: openArray[(U, U)]; u: U): bool = let res = binarySearch(a, u, proc(x: (U, U); y: U): int = if x[0] > y: 1 elif x[1] < y: -1 else: 0 ) return res != -1 proc isControlChar*(u: uint32): bool = return u <= 0x1F or u >= 0x7F and u <= 0x9F proc toLowerAscii*(c: char): char {.inline.} = if c in AsciiUpperAlpha: result = char(uint8(c) xor 0x20'u8) else: result = c proc toUpperAscii*(c: char): char {.inline.} = if c in AsciiLowerAlpha: result = char(uint8(c) xor 0x20'u8) else: result = c proc toLowerAscii*(s: openArray[char]): string = let L = s.len result = newString(L) for i in 0 ..< L: result[i] = s[i].toLowerAscii() proc toUpperAscii*(s: openArray[char]): string = let L = s.len result = newString(L) for i in 0 ..< L: result[i] = s[i].toUpperAscii() proc kebabToCamelCase*(s: string): string = result = "" var flip = false for c in s: if c == '-': flip = true else: if flip: result &= c.toUpperAscii() else: result &= c flip = false proc camelToKebabCase*(s: openArray[char]; dashPrefix = false): string = result = newStringOfCap(s.len) if dashPrefix: result &= '-' for c in s: if c in AsciiUpperAlpha: result &= '-' result &= c.toLowerAscii() else: result &= c proc hexValue*(c: char): int = if c in AsciiDigit: return int(uint8(c) - uint8('0')) if c in 'a'..'f': return int(uint8(c) - uint8('a') + 0xA) if c in 'A'..'F': return int(uint8(c) - uint8('A') + 0xA) return -1 proc decValue*(c: char): int = if c in AsciiDigit: return int(uint8(c) - uint8('0')) return -1 const HexCharsUpper = "0123456789ABCDEF" const HexCharsLower = "0123456789abcdef" proc pushHex*(buf: var string; u: uint8) = buf &= HexCharsUpper[u shr 4] buf &= HexCharsUpper[u and 0xF] proc pushHex*(buf: var string; c: char) = buf.pushHex(uint8(c)) proc toHexLower*(u: uint16): string = var x = u let len = if (u and 0xF000) != 0: 4 elif (u and 0x0F00) != 0: 3 elif (u and 0xF0) != 0: 2 else: 1 var s = newString(len) for i in countdown(len - 1, 0): s[i] = HexCharsLower[x and 0xF] x = x shr 4 move(s) proc controlToVisual*(u: uint32): string = if u <= 0x1F: return "^" & char(u or 0x40) if u == 0x7F: return "^?" var res = "[" res.pushHex(uint8(u)) res &= ']' move(res) proc add*(s: var string; u: uint8) = s.addInt(uint64(u)) proc cmpIgnoreCase2(a, b: openArray[char]): int = let alen = a.len let blen = b.len let L = min(alen, blen) for i in 0 ..< L: let n = cmp(a[i].toLowerAscii(), b[i].toLowerAscii()) if n != 0: return n cmp(alen, blen) proc cmpIgnoreCase*(a, b: string): int = a.cmpIgnoreCase2(b) proc equalsIgnoreCase*(s1, s2: openArray[char]): bool {.inline.} = return s1.cmpIgnoreCase2(s2) == 0 proc startsWithIgnoreCase*(s1, s2: openArray[char]): bool = if s1.len < s2.len: return false for i in 0 ..< s2.len: if s1[i].toLowerAscii() != s2[i].toLowerAscii(): return false return true proc startsWith*(s1, s2: openArray[char]): bool = let len2 = s2.len if s1.len < len2: return false when nimvm: for i in 0 ..< len2: if s1[i] != s2[i]: return false return true else: if len2 <= 0: return true return equalMem(unsafeAddr s1[0], unsafeAddr s2[0], len2) proc startsWith*(s1, s2: openArray[char]; start: int): bool = if start >= s1.len: return false return s1.toOpenArray(start, s1.high).startsWith(s2) proc endsWithIgnoreCase*(s1, s2: openArray[char]): bool = let len2 = s2.len if s1.len < len2: return false let h1 = s1.high let h2 = s2.high for i in 0 ..< len2: if s1[h1 - i].toLowerAscii() != s2[h2 - i].toLowerAscii(): return false return true proc endsWith*(s1, s2: openArray[char]): bool = let len1 = s1.len let len2 = s2.len if len1 < len2: return false when nimvm: let h1 = s1.high let h2 = s2.high for i in 0 ..< len2: if s1[h1 - i] != s2[h2 - i]: return false return true else: if len2 <= 0: return true return equalMem(unsafeAddr s1[len1 - len2], unsafeAddr s2[0], len2) proc memset(s: pointer; c: cint; size: csize_t): pointer {. importc, header: "<string.h>".} proc repeat*(c: char; n: int): string = result = newString(n) when nimvm: for ic in result.mitems: ic = c else: if n > 0: discard memset(addr result[0], cint(c), csize_t(n)) proc repeat*(s: string; n: int): string = result = newStringOfCap(s.len * n) for i in 0 ..< n: result &= s proc memchr(s: pointer; c: cint; n: csize_t): pointer {. importc, header: "<string.h>".} proc find*(s: openArray[char]; c: char): int = let slen = s.len when nimvm: for i in 0 ..< slen: if s[i] == c: return i else: if slen > 0: let sp = unsafeAddr s[0] let p = memchr(sp, cint(c), csize_t(slen)) if p != nil: return cast[int](cast[uint](p) - cast[uint](sp)) return -1 proc find*(s: openArray[char]; c: char; start: int; last = -1): int = let last = if last == -1: s.high else: last let n = s.toOpenArray(start, last).find(c) if n < 0: return n return start + n proc find*(s: openArray[char]; cs: set[char]): int = let slen = s.len for i in 0 ..< slen: if s[i] in cs: return i return -1 proc find*(s: openArray[char]; cs: set[char]; start: int; last = -1): int = let last = if last == -1: s.high else: last if start > last: return -1 let n = s.toOpenArray(start, last).find(cs) if n < 0: return n return start + n proc memmem(haystack: pointer; haystacklen: csize_t; needle: pointer; needlelen: csize_t): pointer {.importc, header: "<string.h>".} proc find*(haystack: openArray[char]; needle: string): int = let haystacklen = haystack.len let needlelen = needle.len if haystacklen < needlelen: return -1 if needlelen <= 0: return 0 when nimvm: let L = haystacklen - needlelen + 1 var i = 0 let haystackHigh = haystack.high while i < L: if haystack.toOpenArray(i, haystackHigh).startsWith(needle): return i inc i else: let sp = unsafeAddr haystack[0] let p = memmem(sp, csize_t(haystacklen), unsafeAddr needle[0], csize_t(needlelen)) if p != nil: return cast[int](cast[uint](p) - cast[uint](sp)) return -1 proc find*(haystack: openArray[char]; needle: string; start: int; last = -1): int = let last = if last == -1: haystack.high else: last if start > last: return -1 let n = haystack.toOpenArray(start, last).find(needle) if n < 0: return n return start + n const HasMemrchr = defined(linux) or defined(freebsd) or defined(openbsd) or defined(netbsd) or defined(haiku) when HasMemrchr: proc memrchr(s: pointer; c: cint; n: csize_t): pointer {. importc, header: "<string.h>".} proc rfind*(s: openArray[char]; c: char): int = template impl = for i in countdown(s.high, 0): if s[i] == c: return i when nimvm: impl() else: when HasMemrchr: let slen = s.len if slen > 0: let sp = unsafeAddr s[0] let p = memrchr(sp, cint(c), csize_t(slen)) if p != nil: return cast[int](cast[uint](p) - cast[uint](sp)) else: impl() return -1 proc rfind*(s: openArray[char]; c: char; start: int; last = -1): int = let last = if last == -1: s.high else: last let n = s.toOpenArray(start, last).rfind(c) if n < 0: return n return start + n proc rfind*(s: openArray[char]; cs: set[char]; start = 0; last = -1): int = let H = if last < 0: s.high else: last for i in countdown(H, start): if s[i] in cs: return i return -1 proc contains*(s1: openArray[char]; s2: string): bool = s1.find(s2) != -1 proc contains*(s: openArray[char]; cs: set[char]): bool = s.find(cs) != -1 proc onlyWhitespace*(s: string): bool = return AllChars - AsciiWhitespace notin s proc containsIgnoreCase*(ss: openArray[string]; s: string): bool = for it in ss: if it.equalsIgnoreCase(s): return true false proc count*(s: openArray[char]; c: char): int = var n = 0 for ic in s: if ic == c: inc n n proc count*(s: openArray[char]; cs: set[char]): int = var n = 0 for c in s: if c in cs: inc n n proc delete*(s: var string; slice: Slice[int]) = let a = max(0, slice.a) let b = min(s.high, slice.b) if b >= a: var i = a var j = b + 1 let moveLen = s.len - j let len = moveLen + i when nimvm: while i < len: s[i] = s[j] inc i inc j else: if moveLen > 0: moveMem(addr s[i], addr s[j], moveLen) s.setLen(len) proc skipBlanks*(buf: openArray[char]; at: int): int = result = at while result < buf.len and buf[result] in AsciiWhitespace: inc result when NimMajor < 2: proc substr*(s: openArray[char]): string = var res = newStringOfCap(s.len) for c in s: res &= c move(res) proc strip*(s: openArray[char]; leading = true; trailing = true; chars = AsciiWhitespace): string = var i = 0 if leading: while i < s.len and s[i] in chars: inc i var j = s.high if trailing: while j >= 0 and s[j] in chars: dec j if i > j: return "" return s.toOpenArray(i, j).substr() proc stripAndCollapse*(s: openArray[char]): string = var res = newStringOfCap(s.len) var space = false for c in s.toOpenArray(s.skipBlanks(0), s.high): let cspace = c in AsciiWhitespace if not cspace: if space: res &= ' ' res &= c space = cspace move(res) proc until*(s: openArray[char]; cc: char; starti = 0): string = result = "" for i in starti ..< s.len: let c = s[i] if c == cc: break result &= c proc until*(s: openArray[char]; cc: set[char]; starti = 0): string = result = "" for i in starti ..< s.len: let c = s[i] if c in cc: break result &= c proc untilLower*(s: openArray[char]; cc: char; starti = 0): string = result = "" for i in starti ..< s.len: let c = s[i] if c == cc: break result &= c.toLowerAscii() proc untilLower*(s: openArray[char]; cc: set[char]; starti = 0): string = result = "" for i in starti ..< s.len: let c = s[i] if c in cc: break result &= c.toLowerAscii() proc after*(s: string; c: char): string = let i = s.find(c) if i != -1: return s.substr(i + 1) return "" proc after*(s: string; c: set[char]): string = let i = s.find(c) if i != -1: return s.substr(i + 1) return "" proc afterLast*(s: string; c: char): string = let i = s.rfind(c) if i >= 0: return s.substr(i + 1) return s proc afterLast*(s: string; c: set[char]): string = let i = s.rfind(c) if i >= 0: return s.substr(i + 1) return s proc untilLast*(s: string; c: char): string = let i = s.rfind(c) if i >= 0: return s.substr(0, i - 1) return s proc untilLast*(s: string; c: set[char]): string = let i = s.rfind(c) if i >= 0: return s.substr(0, i - 1) return s proc snprintf(str: cstring; size: csize_t; format: cstring): cint {.header: "<stdio.h>", importc, varargs} # From w3m const SizeUnit = [ cstring"b", cstring"kb", cstring"Mb", cstring"Gb", cstring"Tb", cstring"Pb", cstring"Eb", cstring"Zb", cstring"Bb", cstring"Yb" ] proc convertSize*(size: uint64): string = var sizepos = 0 var csize = float32(size) while csize >= 999.495 and sizepos < SizeUnit.len: csize = csize / 1024.0 inc sizepos result = newString(10) let f = floor(csize * 100 + 0.5) / 100 discard snprintf(cstring(result), csize_t(result.len), "%.3g%s", f, SizeUnit[sizepos]) result.setLen(cstring(result).len) # https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#numbers proc parseUIntImpl[T: SomeUnsignedInt](s: openArray[char]; allowSign: bool; radix: T): Opt[T] = var integer: T = 0 let radix = uint(radix) var i = 0u let L = uint(s.len) if allowSign and i < L and s[i] == '+': inc i var fail = i == L # fail on empty input for i in i ..< L: let u = uint64(hexValue(s[i])) let n = uint64(integer) * radix + u integer = T(n) fail = fail or u >= radix or n != uint64(integer) # overflow check if fail: return err() # invalid or overflow ok(integer) proc parseUInt8*(s: openArray[char]; allowSign = false): Opt[uint8] = return parseUIntImpl[uint8](s, allowSign, 10) proc parseUInt8NoLeadingZero*(s: openArray[char]): Opt[uint8] = if s.len > 1 and s[0] == '0': return err() return parseUInt8(s) proc parseUInt16*(s: openArray[char]; allowSign = false): Opt[uint16] = return parseUIntImpl[uint16](s, allowSign, 10) proc parseUInt32Base*(s: openArray[char]; allowSign = false; radix: uint32): Opt[uint32] = return parseUIntImpl[uint32](s, allowSign, radix) proc parseUInt32*(s: openArray[char]; allowSign = false): Opt[uint32] = return parseUInt32Base(s, allowSign, 10) proc parseUInt64*(s: openArray[char]; allowSign = false): Opt[uint64] = return parseUIntImpl[uint64](s, allowSign, 10) proc parseIntImpl[T: SomeSignedInt; U: SomeUnsignedInt](s: openArray[char]; radix: U): Opt[T] = var sign: T = 1 var i = 0 if s.len > 0 and s[0] == '-': sign = -1 inc i let res = parseUIntImpl[U](s.toOpenArray(i, s.high), allowSign = true, radix) let u = res.get(U.high) if sign == -1 and u == U(T.high) + 1: return ok(T.low) # negative has one more valid int if u <= U(T.high): return ok(T(u) * sign) err() proc parseInt32*(s: openArray[char]): Opt[int32] = return parseIntImpl[int32, uint32](s, 10) proc parseInt64*(s: openArray[char]): Opt[int64] = return parseIntImpl[int64, uint64](s, 10) proc parseIntP*(s: openArray[char]): Opt[int] = return parseIntImpl[int, uint](s, 10) const ControlPercentEncodeSet* = Controls + NonAscii const FragmentPercentEncodeSet* = ControlPercentEncodeSet + {' ', '"', '<', '>', '`'} const QueryPercentEncodeSet* = FragmentPercentEncodeSet - {'`'} + {'#'} const SpecialQueryPercentEncodeSet* = QueryPercentEncodeSet + {'\''} const PathPercentEncodeSet* = QueryPercentEncodeSet + {'?', '`', '{', '}', '^'} const UserInfoPercentEncodeSet* = PathPercentEncodeSet + {'/', ':', ';', '=', '@', '['..']', '|'} const ComponentPercentEncodeSet* = UserInfoPercentEncodeSet + {'$'..'&', '+', ','} const ApplicationXWWWFormUrlEncodedSet* = ComponentPercentEncodeSet + {'!', '\''..')', '~'} # used by pager when defined(windows): const LocalPathPercentEncodeSet* = Ascii - AsciiAlpha - AsciiDigit - {'.', '\\', '/'} else: const LocalPathPercentEncodeSet* = Ascii - AsciiAlpha - AsciiDigit - {'.', '/'} proc percentEncode*(append: var string; c: char; set: set[char]; spaceAsPlus = false) {.inline.} = if spaceAsPlus and c == ' ': append &= '+' elif c notin set: append &= c else: append &= '%' append.pushHex(c) proc percentEncode*(append: var string; s: openArray[char]; set: set[char]; spaceAsPlus = false) = for c in s: append.percentEncode(c, set, spaceAsPlus) proc percentEncode*(s: openArray[char]; set: set[char]; spaceAsPlus = false): string = result = "" result.percentEncode(s, set, spaceAsPlus) proc percentDecode*(input: openArray[char]): string = result = "" var i = 0 while i < input.len: let c = input[i] if c != '%' or i + 2 >= input.len: result &= c else: let h1 = input[i + 1].hexValue let h2 = input[i + 2].hexValue if h1 == -1 or h2 == -1: result &= c else: result &= char((h1 shl 4) or h2) i += 2 inc i type EscapeMode* = enum emAll # attribute chars plus single quote (non-standard but safest) emAttribute # text chars plus double quote ("attribute mode" in spec) emText # &, nbsp, <, > (default mode in spec) proc htmlEscape*(s: openArray[char]; mode = emAll): string = result = newStringOfCap(s.len) var nbspMode = false for c in s: if nbspMode: if c == '\xA0': result &= "&nbsp;" else: result &= '\xC2' & c nbspMode = false continue case c of '<': result &= "&lt;" of '>': result &= "&gt;" of '&': result &= "&amp;" of '\xC2': nbspMode = true elif c == '"' and mode <= emAttribute: result &= "&quot;" elif c == '\'' and mode == emAll: result &= "&apos;" else: result &= c proc dqEscape*(s: openArray[char]): string = result = newStringOfCap(s.len) for c in s: if c == '"': result &= '\\' result &= c proc cssEscape*(s: openArray[char]): string = result = "" for c in s: if c == '\'': result &= '\\' result &= c proc join*(ss: openArray[string]; sep: char): string = if ss.len <= 0: return "" result = ss[0] for i in 1 ..< ss.len: result &= sep result &= ss[i] iterator split*(s: openArray[char]; sep: char): string = var buf = "" var i = 0 while i <= s.len: if i == s.len or s[i] == sep: yield buf buf.setLen(0) else: buf &= s[i] inc i iterator split*(s: openArray[char]; sep: set[char]): string = var buf = "" var i = 0 while i <= s.len: if i == s.len or s[i] in sep: yield buf buf.setLen(0) else: buf &= s[i] inc i proc containsToken*(s: openArray[char]; tok: string): bool = for it in s.split(AsciiWhitespace): if it == tok: return true return false proc containsTokenIgnoreCase*(s: openArray[char]; tok: string): bool = for it in s.split(AsciiWhitespace): if it.equalsIgnoreCase(tok): return true return false # https://www.w3.org/TR/xml/#NT-Name const NameStartCharRanges = [ (0xC0u16, 0xD6u16), (0xD8u16, 0xF6u16), (0xF8u16, 0x2FFu16), (0x370u16, 0x37Du16), (0x37Fu16, 0x1FFFu16), (0x200Cu16, 0x200Du16), (0x2070u16, 0x218Fu16), (0x2C00u16, 0x2FEFu16), (0x3001u16, 0xD7FFu16), (0xF900u16, 0xFDCFu16), (0xFDF0u16, 0xFFFDu16) ] const NameStartCharAscii = {':', '_'} + AsciiAlpha const NameCharAscii = NameStartCharAscii + {'-', '.'} + AsciiDigit proc isNameStartCharHigh(u: uint32): bool = return u <= uint16.high and NameStartCharRanges.isInRange(uint16(u)) or u in 0x10000u32..0xEFFFFu32 proc matchNameProduction*(s: openArray[char]): bool = if s.len <= 0: return false # NameStartChar var i = 0 let u = s.nextUTF8(i) if u <= 0x7F: if char(u) notin NameStartCharAscii: return false elif not u.isNameStartCharHigh(): return false # NameChar while i < s.len: let u = s.nextUTF8(i) if u <= 0x7F: if char(u) notin NameCharAscii: return false elif not u.isNameStartCharHigh() and u != 0xB7 and u notin 0x300u32..0x36Fu32 and u notin 0x203Fu32..0x2040u32: return false return true proc matchQNameProduction*(s: openArray[char]): bool = if s.len <= 0: return false if s[0] == ':': return false if s[^1] == ':': return false var colon = false for i in 1 ..< s.len - 1: if s[i] == ':': if colon: return false colon = true return s.matchNameProduction() proc utf16Len*(s: openArray[char]): int = result = 0 for u in s.points: if u < 0x10000: # ucs-2 result += 1 else: # surrogate result += 2 proc c_getenv(name: cstring): cstring {. header: "<stdlib.h>", importc: "getenv".} proc c_setenv(envname, envval: cstring; overwrite: cint): cint {. header: "<stdlib.h>", importc: "setenv".} proc c_unsetenv(name: cstring): cint {. header: "<stdlib.h>", importc: "unsetenv".} proc getEnvCString*(name: string): cstring = return c_getenv(cstring(name)) proc getEnvEmpty*(name: string; fallback = ""): string = var res = getEnvCString(name) if res == nil or res[0] == '\0': return fallback return $res proc setEnv*(name, value: string): Opt[void] = if c_setenv(cstring(name), cstring(value), 1) != 0: return err() ok() proc unsetEnv*(name: string) = discard c_unsetenv(cstring(name)) proc expandPath*(path: string): string = if path.len > 0 and path[0] == '~': if path.len == 1: return getEnvEmpty("HOME") if path[1] == '/': return getEnvEmpty("HOME") & path.substr(1) let usr = path.until({'/'}, 1) let p = getpwnam(cstring(usr)) if p != nil and p.pw_dir != nil: return $p.pw_dir & '/' & path.substr(usr.len) return path proc deleteChars*(s: openArray[char]; todel: set[char]): string = result = newStringOfCap(s.len) for c in s: if c notin todel: result &= c proc replaceControls*(s: openArray[char]): string = result = newStringOfCap(s.len) for u in s.points: if u.isControlChar(): result &= u.controlToVisual() else: result.addUTF8(u) # https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#multipart/form-data-encoding-algorithm proc makeCRLF*(s: openArray[char]): string = result = newStringOfCap(s.len) var i = 0 let L = s.len - 1 while i < L: let c1 = s[i] let c2 = s[i + 1] result &= c1 if c1 == '\r' and c2 != '\n': result &= '\n' elif c1 != '\r' and c2 == '\n': result &= '\r' result &= '\n' inc i inc i if i < s.len: if s[i] == '\r': result &= '\r' result &= '\n' else: result &= s[i] type IdentMapItem* = tuple[s: string; n: int] proc getIdentMap*[T: enum](e: typedesc[T]): seq[IdentMapItem] = result = @[] for e in T.low .. T.high: result.add(($e, int(e))) result.sort(proc(x, y: IdentMapItem): int = cmp(x.s, y.s)) proc cmpItem(x: IdentMapItem; y: openArray[char]): int = let slen = x.s.len let ylen = y.len let L = min(slen, ylen) when nimvm: for i in 0 ..< L: let n = cmp(x.s[i], y[i]) if n != 0: return n else: if L > 0: let n = cmpMem(unsafeAddr x.s[0], unsafeAddr y[0], L) if n != 0: return n return cmp(slen, ylen) proc cmpItemNoCase(x: IdentMapItem; y: openArray[char]): int = x.s.cmpIgnoreCase2(y) proc strictParseEnum0(map: openArray[IdentMapItem]; s: openArray[char]): int = let i = map.binarySearch(s, cmpItem) if i != -1: return map[i].n return -1 proc strictParseEnum*[T: enum](s: openArray[char]): Opt[T] = const IdentMap = getIdentMap(T) let n = IdentMap.strictParseEnum0(s) if n != -1: {.push rangeChecks: off.} return ok(T(n)) {.pop.} err() proc parseEnumNoCase0*(map: openArray[IdentMapItem]; s: openArray[char]): int = let i = map.binarySearch(s, cmpItemNoCase) if i != -1: return map[i].n return -1 proc parseEnumNoCase*[T: enum](s: openArray[char]): Opt[T] = const IdentMap = getIdentMap(T) let n = IdentMap.parseEnumNoCase0(s) if n != -1: {.push rangeChecks: off.} return ok(T(n)) {.pop.} return err() const tchar = AsciiAlphaNumeric + {'!', '#'..'\'', '*', '+', '-', '.', '^', '_', '`', '|', '~'} proc findContentTypeAttr(contentType, attrname: string): int = var i = contentType.find(';') while i != -1: i = contentType.skipBlanks(i + 1) if i >= contentType.len: break if contentType.startsWith(attrname, i): i = contentType.skipBlanks(i + attrname.len) if i >= contentType.len: break if contentType[i] == '=': return i + 1 i = contentType.find(';', i) return -1 proc getContentTypeAttr*(contentType, attrname: string): string = var i = contentType.findContentTypeAttr(attrname) if i < 0: return "" i = contentType.skipBlanks(i) if i >= contentType.len: return "" if contentType[i] != '"': return contentType.until(';', i) var q = false var s = "" for c in contentType.toOpenArray(i + 1, contentType.high): if q: s &= c q = false elif c == '"': break elif c == '\\': q = true else: s &= c move(s) # turn value into quoted-string proc mimeQuote*(value: string): string = var s = newStringOfCap(value.len) s &= '"' var found = false for c in value: if c in {'"', '\\'}: s &= '\\' found = found or c notin tchar s &= c if not found: return value s &= '"' move(s) proc setContentTypeAttr*(contentType: var string; attrname, value: string) = var i = contentType.findContentTypeAttr(attrname) if i != -1: var j = contentType.find(';', i) if j < 0: j = contentType.len contentType[i..<j] = value.mimeQuote() else: contentType &= ';' & attrname & '=' & value proc atob(c: char): uint8 {.inline.} = # see RFC 4648 table if c in AsciiUpperAlpha: return uint8(c) - uint8('A') if c in AsciiLowerAlpha: return uint8(c) - uint8('a') + 26 if c in AsciiDigit: return uint8(c) - uint8('0') + 52 if c == '+': return 62 if c == '/': return 63 return uint8.high # Warning: this overrides outs. proc atob*(outs: var string; data: string): Err[cstring] = outs = newStringOfCap(data.len div 4 * 3) var buf = array[4, uint8].default var i = 0 var j = 0 var pad = 0 while true: i = data.skipBlanks(i) if i >= data.len: break if data[i] == '=': i = data.skipBlanks(i + 1) inc pad break buf[j] = atob(data[i]) if buf[j] == uint8.high: return err("Invalid character in encoded string") if j == 3: let ob1 = (buf[0] shl 2) or (buf[1] shr 4) # 6 bits of b0 | 2 bits of b1 let ob2 = (buf[1] shl 4) or (buf[2] shr 2) # 4 bits of b1 | 4 bits of b2 let ob3 = (buf[2] shl 6) or buf[3] # 2 bits of b2 | 6 bits of b3 outs &= char(ob1) outs &= char(ob2) outs &= char(ob3) j = 0 else: inc j inc i if i < data.len: if i < data.len and data[i] == '=': inc pad inc i i = data.skipBlanks(i) if pad > 0 and j + pad != 4: return err("Too much padding") if i < data.len: return err("Invalid character after encoded string") if j == 3: let ob1 = (buf[0] shl 2) or (buf[1] shr 4) # 6 bits of b0 | 2 bits of b1 let ob2 = (buf[1] shl 4) or (buf[2] shr 2) # 4 bits of b1 | 4 bits of b2 outs &= char(ob1) outs &= char(ob2) elif j == 2: let ob1 = (buf[0] shl 2) or (buf[1] shr 4) # 6 bits of b0 | 2 bits of b1 outs &= char(ob1) elif j != 0: return err("Incorrect number of characters in encoded string") return ok() const AMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" proc btoa*(s: var string; data: openArray[uint8]) = var i = 0 let endw = data.len - 2 while i < endw: let n = uint32(data[i]) shl 16 or uint32(data[i + 1]) shl 8 or uint32(data[i + 2]) i += 3 s &= AMap[n shr 18 and 0x3F] s &= AMap[n shr 12 and 0x3F] s &= AMap[n shr 6 and 0x3F] s &= AMap[n and 0x3F] if i < data.len: let b1 = uint32(data[i]) inc i if i < data.len: let b2 = uint32(data[i]) s &= AMap[b1 shr 2] # 6 bits of b1 s &= AMap[b1 shl 4 and 0x3F or b2 shr 4] # 2 bits of b1 | 4 bits of b2 s &= AMap[b2 shl 2 and 0x3F] # 4 bits of b2 else: s &= AMap[b1 shr 2] # 6 bits of b1 s &= AMap[b1 shl 4 and 0x3F] # 2 bits of b1 s &= '=' s &= '=' proc btoa*(data: openArray[uint8]): string = if data.len == 0: return "" var L = data.len div 3 * 4 if (let rem = data.len mod 3; rem) > 0: L += 3 - rem var s = newStringOfCap(L) s.btoa(data) move(s) proc btoa*(data: openArray[char]): string = return btoa(data.toOpenArrayByte(0, data.len - 1)) iterator mypairs*[T](a: openArray[T]): tuple[key: int; val: lent T] {.inline.} = var i = 0 let L = a.len while i < L: yield (i, a[i]) {.push overflowChecks: off.} inc i {.pop.} iterator ritems*[T](a: openArray[T]): lent T {.inline.} = var i = a.len while i > 0: {.push overflowChecks: off.} dec i {.pop.} yield a[i] iterator mritems*[T](a: var openArray[T]): var T {.inline.} = for i in countdown(a.high, 0): yield a[i] proc getFileExt*(path: string): string = let n = path.rfind({'/', '.'}) if n < 0 or path[n] != '.': return "" return path.substr(n + 1) proc chaArrayCopy*[T](dest, src: var openArray[T]) = assert dest.len == src.len if dest.len > 0: copyMem(addr dest[0], addr src[0], dest.len * sizeof(T)) when not defined(nimHasXorSet): proc toggle*[T](x: var set[T]; y: set[T]) = x = x + y - (x * y) {.pop.} # raises: [] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/src/utils/widthconv.nim���������������������������������������������������������������0000664�0000000�0000000�00000005742�15202323131�0017603�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import std/algorithm import utils/twtstr const CanHaveDakuten = ("かきくけこさしすせそたちつてとはひふへほカキクケコ" & "サシスセソタチツテトハヒフヘホ").toPoints() const CanHaveHanDakuten = "はひふへほハヒフヘホ".toPoints() const HasDakuten = ("がぎぐげござじずぜぞだぢづでどばびぶべぼガギグゲゴ" & "ザジズゼゾダヂヅデドバビブベボ").toPoints() const HasHanDakuten = "ぱぴぷぺぽパピプペポ".toPoints() # Halfwidth to fullwidth & vice versa const halfFullMap = (proc(): seq[tuple[half, full1, full2: uint32]] = result = @[] const map = staticRead"res/widthconvmap.tab" var i = 0 while i < map.len: let half = map.nextUTF8(i) assert map[i] == '\t' inc i let full1 = map.nextUTF8(i) var full2 = 0u32 if i < map.len and map[i] != '\n': assert map[i] == '\t' inc i full2 = map.nextUTF8(i) result.add((half, full1, full2)) assert map[i] == '\n' inc i )() proc halfwidth(u: uint32): uint32 = if u != 0: # special case to avoid comparison with f2 for (h, f1, f2) in halfFullMap: if f1 == u or f2 == u: return h return u const HalfDakuten = 0xFF9Eu32 # half-width dakuten const HalfHanDakuten = 0xFF9Fu32 # half-width handakuten # Note: in unicode, char + 1 is dakuten and char + 2 handakuten proc halfwidth*(s: string): string = result = "" for u in s.points: case u of HasDakuten: result.addUTF8(halfwidth(u - 1)) result.addUTF8(HalfDakuten) of HasHanDakuten: result.addUTF8(halfwidth(u - 2)) result.addUTF8(HalfHanDakuten) else: result.addUTF8(halfwidth(u)) proc fullwidth(r: uint32): uint32 = if r != 0: # special case to avoid comparison with f2 for (h, f1, f2) in halfFullMap: if h == r: return f1 return r proc fullwidth*(s: string): string = result = "" var lastu = 0u32 for u in s.points: if lastu != 0: if u == HalfDakuten: # flush with dakuten result.addUTF8(lastu + 1) lastu = 0 continue elif u == HalfHanDakuten and lastu in CanHaveHanDakuten: # flush with handakuten result.addUTF8(lastu + 2) lastu = 0 continue result.addUTF8(lastu) lastu = 0 let u = fullwidth(u) if u in CanHaveDakuten: lastu = u else: result.addUTF8(u) if lastu != 0: # flush result.addUTF8(lastu) const kanamap = staticRead"res/kanamap.tab" proc genFullSizeMap(): seq[(uint32, uint32)] = result = @[] for line in kanamap.split('\n'): if line.len == 0: break let rs = line.toPoints() assert rs[1] == uint32('\t') result.add((rs[0], rs[2])) const fullSizeMap = genFullSizeMap() proc fullsize*(s: string): string = result = "" for u in s.points: let i = fullSizeMap.binarySearch(u, proc(x: (uint32, uint32); y: uint32): int = cmp(x[0], y)) if i == -1: result.addUTF8(u) else: result.addUTF8(fullSizeMap[i][1]) ������������������������������chawan-v0.4.0/test/���������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0014111�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/asserts.js�����������������������������������������������������������������������0000664�0000000�0000000�00000002333�15202323131�0016134�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������function assert(x, msg) { const mymsg = msg ? ": " + msg : ""; if (!x) throw new TypeError("Assertion failed" + mymsg); } function assertThrows(fun, error) { if (typeof fun == "string") { const x = fun; fun = () => eval(x); } if (!(fun instanceof Function)) throw new TypeError("error expected to be Function"); let me; try { fun(); } catch (e) { if (e instanceof error) return; me = e; } throw new TypeError("Assertion failed: expected " + error + ", got " + me + " for: " + fun); } async function assertThrowsAsync(fun, error) { if (typeof fun == "string") { const x = fun; fun = async () => eval(x); } if (!(fun instanceof Function)) throw new TypeError("error expected to be Function"); let me; try { await fun(); } catch (e) { if (e instanceof error) return; me = e; } throw new TypeError("Assertion failed: expected " + error + ", got " + me + " for: " + fun); } function assertEquals(a, b) { if (a !== b) throw new TypeError("Assertion failed: expected " + b + " but got " + a); } function assertNotEquals(a, b) { assert(a !== b, "Expected " + b + " to have some different value"); } function assertInstanceof(a, b) { assert(a instanceof b, a + " not an instance of " + b); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/charset/�������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0015542�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/charset/basic.nim����������������������������������������������������������������0000664�0000000�0000000�00000020567�15202323131�0017342�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import std/strutils import encoding/charset import encoding/decoder import encoding/decodercore import encoding/encoder const iroha = "いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす" proc testCJK() = const css = [ csShiftJIS, csIso2022JP, csEucJP, csEucKR, csGb18030, csGbk, csBig5, csUtf8 ] let iroha100 = iroha.repeat(100) for cs in css: let sencoded = if cs != csUtf8: iroha.encodeAll(cs) else: iroha let sdecoded = sencoded.decodeAll(cs) assert sdecoded == iroha var ctx = initTextDecoderContext(cs) var dec2 = "" for i in 0 ..< 100: for slice in ctx.decode(sencoded.toOpenArrayByte(0, sencoded.high), finish = false): dec2 &= slice for slice in ctx.decode([], finish = true): dec2 &= slice assert dec2 == iroha100 proc testUTF8Parts() = # Validate "Hellö, world!". let ss0 = "Hell\xC3" var td = initTextDecoder(csUtf8) var n = 0 var oq = newSeq[uint8](16) assert td.decode(ss0.toOpenArrayByte(0, ss0.high), oq, n) == tdrReadInput # read Hell (0xC3 is not consumed yet) assert td.decode(ss0.toOpenArrayByte(0, ss0.high), oq, n) == tdrDone # n is still 0, but 0xC3 is now buffered assert n == 0 # read 0xB6 + , world! => Hellö world! let ss1 = "\xB6, world!\xC3" assert td.decode(ss1.toOpenArrayByte(0, ss1.high), oq, n) == tdrReadInput # 0xC3 got moved from the internal buffer to oq assert n == 1 assert oq[0] == 0xC3 assert td.decode(ss1.toOpenArrayByte(0, ss1.high), oq, n, finish = true) == tdrError proc testUTF8Valid() = const utf8_valid = [ "aiueo", "äöüß", "あいうえお", "あöあüあöあüあöあü", "asdf asdf asdfasd fasdfas dfあöあüa lksdjf alskdfj asalkdf kldfj asdあ aklsdjf asd", "\u1F972" ] for s in utf8_valid: assert s.toValidUTF8() == s assert s.toValidUTF8() & 'x' == s & 'x' var ctx = initTextDecoderContext(csUtf8, bufLen = 3) block: var res = "" for s in ctx.decode(s.toOpenArrayByte(0, s.high), finish = true): res &= s assert res == s for j in 2 .. 10: var res = "" var i = 0 while i < s.len: for s in ctx.decode(s.toOpenArrayByte(i, min(i + j, s.len) - 1), finish = i + j >= s.len): res &= s i += j assert res == s proc testUTF8Invalid() = const utf8_error = { "\xF8\x80\x80\x80\x80\x80": "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD", "\uD800": "\uFFFD\uFFFD\uFFFD", # lowest surrogate "\uD8FF": "\uFFFD\uFFFD\uFFFD", # highest surrogate "\uD83E\uDD72": "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD", # paired surrogates "\uD83C": "\uFFFD\uFFFD\uFFFD", # some unpaired surrogate "r\xC8sum\xC8s": "r\uFFFDsum\uFFFDs", # latin-1 mis-declared as UTF-8 "\x41\xC0\xAF\x41\xF4\x80\x80\x41": "A\uFFFD\uFFFDA\uFFFDA", } for (s, t) in utf8_error: assert s.toValidUTF8() == t assert (s & 'x').toValidUTF8() == t & 'x' block: var ctx = initTextDecoderContext(csUtf8, bufLen = 2) var res = "" for i in 0 ..< s.len: for s in ctx.decode([uint8(s[i])], finish = i == s.high): res &= s assert res == t block: var ctx = initTextDecoderContext(csUtf8, bufLen = 2) var res = "" var i = 0 while i < s.len: for s in ctx.decode(s.toOpenArrayByte(i, min(i + 2, s.len) - 1), finish = i + 2 >= s.len): res &= s i += 2 assert res == t proc testUTF16be() = const list = { "\0H\0e\0l\0l\0o\0,\0 \0w\0o\0r\0l\0d\0!": "Hello, world!", "\xD8\x00": "\uFFFD", # lowest surrogate (unpaired) "\xDB\xFF": "\uFFFD", # highest low surrogate (unpaired) "\xDC\x00": "\uFFFD", # lowest high surrogate (unpaired) "\xD8\xFF": "\uFFFD", # highest surrogate (unpaired) "\xD8\x3E\xDD\x72": "\u{1F972}", # paired surrogates } for (s, t) in list: assert s.decodeAll(csUtf16be) == t proc testUTF16le() = const list = { "H\0e\0l\0l\0o\0,\0 \0w\0o\0r\0l\0d\0!\0": "Hello, world!", "\x00\xD8": "\uFFFD", # lowest surrogate (unpaired) "\xFF\xDB": "\uFFFD", # highest low surrogate (unpaired) "\x00\xDC": "\uFFFD", # lowest high surrogate (unpaired) "\xFF\xD8": "\uFFFD", # highest surrogate (unpaired) "\x3E\xD8\x72\xDD": "\u{1F972}", # paired surrogates } for (s, t) in list: assert s.decodeAll(csUtf16le) == t var s = "" var s8 = "" for i in 0 ..< 10: s &= "t\0e\0s\0t\0" s8 &= "test" var ctx = initTextDecoderContext(csUtf16le, bufLen = 32) var res = "" for s in ctx.decode(s.toOpenArrayByte(0, s.high), finish = true): res &= s assert res == s8 const tisztaszivvel = """ Nincsen apám, se anyám, se istenem, se hazám, se bölcsőm, se szemfedőm, se csókom, se szeretőm. Harmadnapja nem eszek, se sokat, se keveset. Húsz esztendőm hatalom; húsz esztendőm eladom. Hogyha nem kell senkinek, hát az ördög veszi meg. Tiszta szívvel betörök, ha kell, embert is ölök. Elfognak és felkötnek, áldott földdel elfödnek, s halált hozó fű terem gyönyörűszép szívemen. """ proc testWindows1250() = let sencoded = tisztaszivvel.encodeAll(csWindows1250) let sdecoded = sencoded.decodeAll(csWindows1250) assert sdecoded == tisztaszivvel const erlkoenig = """ Wer reitet so spät durch Nacht und Wind? Es ist der Vater mit seinem Kind; Er hat den Knaben wohl in dem Arm, Er faßt ihn sicher, er hält ihn warm. Mein Sohn, was birgst du so bang dein Gesicht? Siehst, Vater, du den Erlkönig nicht? Den Erlenkönig mit Kron' und Schweif? Mein Sohn, es ist ein Nebelstreif. "Du liebes Kind, komm, geh mit mir! Gar schöne Spiele spiel' ich mit dir; Manch' bunte Blumen sind an dem Strand, Meine Mutter hat manch gülden Gewand." Mein Vater, mein Vater, und hörest du nicht, Was Erlenkönig mir leise verspricht? Sei ruhig, bleibe ruhig, mein Kind; In dürren Blättern säuselt der Wind. "Willst, feiner Knabe, du mit mir gehn? Meine Töchter sollen dich warten schön; Meine Töchter führen den nächtlichen Reihn, Und wiegen und tanzen und singen dich ein." Mein Vater, mein Vater, und siehst du nicht dort Erlkönigs Töchter am düstern Ort? Mein Sohn, mein Sohn, ich seh' es genau: Es scheinen die alten Weiden so grau. "Ich liebe dich, mich reizt deine schöne Gestalt; Und bist du nicht willig, so brauch' ich Gewalt." Mein Vater, mein Vater, jetzt faßt er mich an! Erlkönig hat mir ein Leids getan! Dem Vater grauset's; er reitet geschwind, Er hält in den Armen das ächzende Kind, Erreicht den Hof mit Mühe und Not; In seinen Armen, das Kind war tot. """ proc testWindows1252() = let sencoded = erlkoenig.encodeAll(csWindows1252) let sdecoded = sencoded.decodeAll(csWindows1252) assert sdecoded == erlkoenig proc testIso8859_2() = let sencoded = tisztaszivvel.encodeAll(csIso8859_2) let sdecoded = sencoded.decodeAll(csIso8859_2) assert sdecoded == tisztaszivvel proc testGetLocaleCharset() = assert getLocaleCharset("ja_JP.EUC_JP") == csEucJP assert getLocaleCharset("ja_JP.UTF-8") == csUtf8 assert getLocaleCharset("") == csUtf8 proc testShiftJIS() = assert "\u2212".encodeAll(csShiftJIS) == "\uFF0D".encodeAll(csShiftJIS) proc testUTF8InvalidStream() = var ctx = initTextDecoderContext(csUtf8) var res = "" for slice in ctx.decode("\xc0a".toOpenArrayByte(0, 0), finish = false): res &= slice assert res == "\uFFFD" proc testIso2022JP() = assert "\x1B\x24".decodeAll(csIso2022JP) == "\uFFFD$" assert "\x1B\x28".decodeAll(csIso2022JP) == "\uFFFD(" assert "カタカナ".encodeAll(csIso2022JP) == "\e$B%+%?%+%J\e(B" proc testGb18030() = # surrogate let sencoded = "\uD800".encodeAll(csGb18030) let sdecoded = sencoded.decodeAll(csGb18030) assert sdecoded == "\uFFFD\uFFFD\uFFFD" # ranges let first = "\u0080".encodeAll(csGb18030) assert first == "\x81\x30\x81\x30" assert first.decodeAll(csGb18030) == "\u0080" let last = "\u{10000}".encodeAll(csGb18030) assert last == "\x90\x30\x81\x30" assert last.decodeAll(csGb18030) == "\u{10000}" assert "\xfe\x39\xfe\x40".decodeAll(csGb18030) == "\uFFFD9\uFA0C" # error with ASCII assert "\x81\x3a".decodeAll(csGb18030) == "\uFFFD:" proc main() = testCJK() testUTF8Parts() testUTF8Valid() testUTF8Invalid() testUTF16be() testUTF16le() testWindows1250() testWindows1252() testIso8859_2() testGetLocaleCharset() testShiftJIS() testUTF8InvalidStream() testIso2022JP() testGb18030() main() �����������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/charset/bench.nim����������������������������������������������������������������0000664�0000000�0000000�00000002567�15202323131�0017340�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import std/envvars import std/math import std/streams import std/strutils import std/times import encoding/charset import encoding/decoder import encoding/encoder proc main() = let file = getEnv("BENCH_FILE") let cs = getCharset(getEnv("BENCH_CHARSET")) let iter = parseInt(getEnv("BENCH_ITER")) let fail_outdir = getEnv("BENCH_ERROR_OUTDIR") let ss = newFileStream(file).readAll() let devnull = open("/dev/null", fmWrite) # check let check0 = ss.decodeAll(cs) let check = check0.encodeAll(cs) if check != ss: eprint "ERROR: equivalence check failed" if fail_outdir != "": let os0 = newFileStream("/tmp/bench_fail_output0", fmWrite) os0.write(check0) let os1 = newFileStream("/tmp/bench_fail_output1", fmWrite) os1.write(check) os0.close() os1.close() quit(1) echo "Starting benchmark for ", file, " charset ", cs let startAll = cpuTime() var times = 0f64 var low = float64.high var high = 0f64 for i in 0 ..< iter: let startIt = cpuTime() let res = ss.decodeAll(cs) devnull.write(res) let endIt = cpuTime() let time = endIt - startIt low = min(low, time) high = max(high, time) times += endIt - startIt let finishAll = cpuTime() echo "Done in ", finishAll - startAll, "ms, avg ", (times / float64(iter)).round(6), " lowest ", low.round(6), " highest ", high.round(6) main() �����������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/charset/data.nim�����������������������������������������������������������������0000664�0000000�0000000�00000003251�15202323131�0017161�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import std/os import std/streams import encoding/decoder import encoding/encoder import encoding/charset let dir = getEnv("CGS_TESTDIR") proc runTestIn(test_in, test_in_ref: FileStream, label: string) = let cs = getCharset(label) assert cs != csUnknown let s = test_in.readAll() let ours = s.decodeAll(cs) let theirs = test_in_ref.readAll() if ours != theirs: echo "ours vs theirs len ", ours.len, " ", theirs.len let helpfile = newFileStream(dir / "fail_in_" & label, fmWrite) helpfile.write(ours) assert false, "Failed in test" & label proc runTestOut(test_out, test_out_ref: FileStream, label: string) = let cs = getCharset(label) assert cs != csUnknown let s = test_out.readAll() let ours = s.encodeAll(cs) let theirs = test_out_ref.readAll() let match = ours == theirs if not match: echo "ours vs theirs len ", ours.len, " ", theirs.len let helpfile = newFileStream(dir / "fail_out_" & label, fmWrite) helpfile.write(ours) assert false, "Failed out test " & label proc runTest(name: string, label: string, no_out = false) = let test_in = newFileStream(dir / name & "_in.txt") let test_in_ref = newFileStream(dir / name & "_in_ref.txt") runTestIn(test_in, test_in_ref, label) if not no_out: let test_out = newFileStream(dir / name & "_out.txt") let test_out_ref = newFileStream(dir / name & "_out_ref.txt") runTestOut(test_out, test_out_ref, label) proc main() = runTest("big5", "big5") runTest("euc_kr", "euc-kr") runTest("jis0208", "euc-jp") runTest("jis0212", "euc-jp", no_out = true) runTest("gb18030", "gb18030") runTest("iso_2022_jp", "iso-2022-jp") runTest("shift_jis", "shift_jis") main() �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/charset/data.tar.xz��������������������������������������������������������������0000664�0000000�0000000�00000276224�15202323131�0017640�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������7zXZ��ִF�!���t/}]�1Ig0.uFc wLd˚8aK' iK g2]?Q%~ :Z#@)% ^A t莴h9 =>oBy?r6> � Q90b#%mZv)RIkl^3SؠT2fSx\2c2x$<Z b33ܮF]F+Ca?VpoސpYPlf~i^Q92~B.H"-ÂxαNO: $i 3]CRoۂϠʩ),6[&Oj}t;.EĬo1~Ƙoml0/Z@M6m 6bl"^%4x?sChf֎t6빵�E18 Jl/@MP_8 ;|+R[]GUVl|^�*1-KtRrܸu0%U.ѬSCG6~W; 9z '/GWb{<x8u Q2!єY!Jn5ioa zU:k Aqy8)鏇'PL7K#Z*'<IВ`(*I=ޛ&|s懛볣~nsH栳á fw`<\e@Ϳ$M@1҄PaH$}rˑZhʫ3["&/ŧOJdPz{=%۴ữ.y:tDË@wӐW3.J R#@6VxaDWtԟ\]w@t3д'-Ef;3eԃ-r-"zܮ =l hMB[(A(KIuMwL*#?YWNY=ŁICzfAA~{%isϯMHz0"ߔ ?`p+I“hN= 觎e0HH6o~2yEh>,;Р ܕ2 o ]-sw6=Oqck[\~Fܿ~~0~%߀gOmIKpS#Rbg cF˴9,$ c=Krs oyk(1PK*C0wrlU}XeNt!s(oI=!6NrbZvBndZZi-!rCLc +{qͽjޓ%*)zFڜw\w[0cVdt U1i{DWC[;Vk}h[0(%lUo'qD<w3-5ܤa/U2r1;^(+"ie^+�z|Gc[.g@ flskn6i6cf@K[ܥ<O}l=[[ i(uR p4n XjiVuQy*:Q)܎&�X1Sl{ p`Հ Þÿ_x#xWbb+hLl\>̐=[oΘisb�^Ic^$geqiц㍮ae;@-eļmr7aV^Hys~kr5CCר| X+ 7\AդPxЋ+ 7(5�syֹ`aĂD!</rb~K-;%D{)!S<dBK:cs<g#F71sY)ER 0C\x o .{6*JQqLUR _(a宂} s)AA"7؇739ƀ iЎV#AǪqM;!D\%ӻe)%r?{ݡ'md_>*VbU 1?JۆMaz,j t}юXllODvh0L蓺΀t:&x~/~ /s[뇴gb&kXdp="P;{0;lPaTQT(wԀ@ S\)G@ObG�Jg o7PkܬY_O8jvWQ1AsKYuxZly&M|-H[ɆqȦ;]ٝnGD:w鄪U)G&Ɯk4SDО'σ~VbvqI~'쥮ٷoO*yݹ _ ` ljM`O4N{{wӶ__H<]x )T@79ZTkExոkz$eӀ ;C!rl�@?"m 2Ij* Sk`Թ,V)ԲzTaE<Kzȉ]s$&D]d(()|U4#*2opFF,/ |_j~RFp(ᖀEJgWREBa\b8~`;Ӹ-O=cn!aams%v. h%dWIIl-/RD~eCpN2-#w bmg:uE. w6i2Dm%ڷ_l 5}| `띺U1>H[s^;^=1 -}S)ww#;AJO$g(E3CmI1ja'۷k�(H7 p.K1r7?|wX#-DyǮ111[v*L{ہLzi J(+Tͣ'EnBUo>\lCf4`'}&,6rڏ9N=B_Ġ06&qRm:?1q>iNw]Vg?gXM`=}02fCK(.g_QykIIyluH&VPe jb1ib9_(4Hyӻi*uR{dEBA}0n%CR7TK ՝++ flna/+fŻkVL#�!ܮЪnЌDG)J¿~w}N.oQ [C*ţİtšg0&Z* iC˭jꮸF[4Li+,&ԩ%錄[&lO�<FX>{o|wrKԩ.r;}A.ˡA&(vUGVזLj�߅IjFJ<='0Vj<z#ڄ ^obbr=<ryHn &q\a Pg�W*\=^-GL[Z#ψo|@孺Z~*8bVPtlS�=Ldہ%}$r+=QVſO!,g2yN6l;1A1W;a(Z)'Ev N^˥_QNlsOL!*:Y}TַBۮxj~>>ٞJ%pz nO[鴰@P`;F{:lYF+xj"|6A ܺ+)쭶,oJźa{b?")UFٗ(ϑ`憓I{otczr"!icT>4n�/C!"w!MUФ+֨@HǑwzI@/ru] `,ѩ1m[u_݃MİYo�2$r8:LM#kJo_a͇9g1m 0kl^z%aqf!fCW|~|Gj'[P7O!N=cxރxou|^aޣ+ bu-SW̺^ЎYv(LP*]'b9kQU|ǏE&~k4k>g>%k=ѪosW=,eaɟ~=[¯`_ޅVE?M鱉6RveB;Es%T,?#q}gô| =%MozqNٙy21)穽 gIutN�xCTK�@r(t%靰A ܕ+X|SM^7S cM 9�H~^Ec0T M:oBYS�6q|U}v]:~/-O`)Z8Z[9Oc/)=NO¬-#gA }x6r;5s EP9wv+ .̏K},m/+g FEzXf:~Kz~Ke<k[Bsώ8Z7̠̎r-#6L޲l/X>#kfDT~]Mڨ PtiRۧlofo'*oYįQ+ UURpwPʐPvx6 BXc^ÂdM E+؞R74oI8MvBƵe{o^t? |MbX`T "m#-c3M8� @dwe>Cl5&2Tˠef,4^zՋW+tڸ4X)hfدaJT�C@C쑀/g{kLsЧQX%kbv0ex�ž n[ԁꈶsUOS]! @6/[{nԠWBk d%R_C]Z-łi9Q~'B.)fQ!*U CH DOe}a2? m24HqL#J~>pR,b::_7!-m?)P}9 X΁:w \R9mP2$E [A 5IwwYl#m/afM@k H,%jJFC̰-4p.3"@} fW.9tm7T\Q}Ub@jQŽ66"5Vjzj;k<iOr {5dOk[}�j|[ܕ߄(Dxy8hk�߯EۃK l,)u0>*& XސlzM7}O=/+ms9`2g>Agkc~"f U]\MjŒ6|"M=""At܌ZA:݊\2}z43*P*3@5bf>oҿ"JF dJ-ݾs ˬ"2nqz )xڹhBמ\^ *C:PRMT.Ro㫡넌k G7ԝ#곬06$-T K6wލB@;"W` ͙ںcd%m{X<DCpJb\*i_H�tolo Oj'TB6c ЫQ(|q˱Tn,-5;E;*1c^yJf!q\#܉PiZ4}IPo&6� C~:DUa-6*iGf{lNOՙVO3/rY%lʰ[fj,mu=’{c2C)~ Z7-sOR]Psѡ ΃(:Q['|޷`"kSL'$dr0jc+[?﷜j3?Bfe1F߈Q@YƦDm,\J$kS_}iMaˠ? T:J+^e|ͅΙ4Fw"WxYj9ļR&6McO~:uF#hV*Ahk-O~r[�Y-t;l]GRKC`�Z whJ F4| �J=#/M%_~ڄ~:�-wt [c ݳ1sPMĻvl>+mpx0K!<H&@# T΍x(†rQ{CTl?(e*zAg3~9EAsRiՅ.q}^^x.0n3h LX:Uzs4xw ǒt,2{{R>N4 pG[i];!΃E0 LѿRj9}s"]G]$qqwx:Qq#Ьh{? *6 (Nb\>8e_H u_y+ _ R?WcϮ[ eI-27Rαé�-C&Wt0&ȜZ5~isy 6H=&@1-Sw6==J ɾ]DkzT-[RvZDa BejJ*S\.@eOLoP+bTTGRG,Aƿ—X<<D~ZLB y3?�Z"*H[<q)Fòw^nw:ac )͓P1Ӗ)G>Rb2z_`P T=۹Y!iٻ=P2c9N]H2X}ă&7yLv&K"USX5~\`7Jѣd6pei`'y]`\Hp&J}Ĝrj+#�٥<N[){,ȓ?&kn@ֲG)y*Wl[6Ž'HN@1K@Ƕ[;NY�hp-n 5{ N,\cs^yǡ}tnԨtUL \;DZ1d/oJy -RrsE\Ip7Ct Zx6n%|OC}.v4k] >zdQIx}p8Cpx,@*"ʅq`-&: q$!U9_Z't M)bu1s=}5]DUu0>'YZѴbEQ*MJ2m=fׯt|inXyBwvWy(=UA?^Cb焒431,ߣⶉ  f I3<V Oé ls&/RxdZmViZU 𣹶O2 ]e\K~Xz P(Q]1({O; >�PW5OdM6+>- 5WKT' xK^ס7,)V 9eQ|1 |ǰvGŀAB@F`z]\\*(r ldS )O: 2twy0wΠuͅ%+3.F^vJM&N*udLGa7n(7Dծk3= XXJ4<�=a6m+f$mr쫚Fu:RrnKa拈U/ )popa|s}i%/b2ADL'F'ݑi ϖ/FLBww~zC H)-YQhF9jA1V*m3{!2P.C=C[1*j_?g{Gu!0vhPe^faJH;L9|a.T|:0U2+[db]˜)1d8bs+i 8K#+X@d1ƍ=qrVP\ ;nyCېJ4CEg!m@Uj30A({H̺r$Kpįi;Hf٪L=Bn#ObY&nZxNiZ]K ej9 .S }ϟmOY!K-6i4ġD6I]4eW<noՅhIBlP w|/1a^EkeM\+v,Lc7o_W#~NY}=Ԑ`Uv虵QdcI<lòXAĶؕ2%'~8 C io]SeNqU.%!*r*qc˴ȭͮm[![XըD&u̯_IYJQeVq@-Ԓg3 <)MsDr\S^ MBg#iRmආ`nVi NYSKmY~i< pz j Qm�ɤf_lF.xdm`Ye #,2 LZ90W̢Q3ePx�6Qq9q١߯\pı f H}>@ɳTyḸ%2hkcXvM4&sb�KG߅sf�%m:Щ(R+v%FqIacQjel腧(N# Eӕ<VTQ\,KbPmh6|]7!!Dj:V ey4sU; Nᔗtq:?ʜj/ W7]RZOxSQF&b5œmZS{ ᵚR6yݱ #09%lB*Lx˰n-xp5*l@a=maa2I)C3큰  {P7m p=Qy̩e Ճw+oK$-t bkljST tm\n93uȋ:t~ -̋%sbQ�f2`WXcNKM㵝bKV26Rh?&Nt6bp<&ًc0ۆEMqݺrc!s1.b&' ~#%(hioB'Wϟ1-K+X5׮&2굶(u С:&r5 y/(e tU5(( aIT]vi+ mǀ 溤447a@HVgP߲鷨 XZ!|hkaRA%'r0jǫ &btmoג֎�F\Crد[cبJ(lY֜Kog Ǐc=P sh'v.}ѹ׸MwY'X'yfI&(kVn2C*+!sAjD`ߕOIFiԀS哮ďH[&,:Uѕ\}l Om:Ȉ'ڂa7dFQ#bI R&^/AExoJ}DƁXqrig͂F2=ITb�ȓV(ǣfnVY@.APc%tZ(sQMO:$&e>#AҶ7{ b[F*e55Dك9U|9!ӫ_J$ %€~�x=CBrܜY;PtjY zܨd姟6[-^MY&"B lc)`F[& aJ~c SSKtDge()wC vl&k"\G]DgG3f?!T[Y>/~S}>Ȧ~Cf'3͗Ep٪˛i#.@_6CFp#h]A*eɻDeIi8[f ȾdJ}>9TMF}+'YGIe6TiˆO- \,_Z,_m$ޥ -D#O_F1иk8McYW5NEv߈ߓKkq=͘b>wuz{Z6B@w٣FUw#,zpɪ0-61Ѽ{HG^'R{ l*>fwvz/' VYD(:0cB;MMAsBe`o?7DweIGsv61%\?bzu%#:%38,O#rB>g0=4#",12P/^GxeV*4T:\6x}!R#Q??O_[]6MP*7"ysqJT9 nl I`=3@XʢJdAjdGmnA6 ZrsA1D&Am8Páv&bCL(8-yEa` B{3=PAF"<V졽&eT}Rl@INgX}!:W;׮ƻ<ƽQ;=s Ƌ]̉GGq1fy>ѩ~۵Yvirl bj +E|Jq L�պYh`DV:7R/ rګ4"riZ#:orH!�A #K  8ԗ XGԊ4|˨]K=l d`Ef_?7V,O; ?Zt"<zn *eoƝåjJR;ܪmgJ@! {[Tٍ?Rw&aNH;"+0𾝓H V?0)t>euҵ7-ŝa3e?a|4 <ߊ [E]~JAP"˴Z.GbDoD6,2m/);y 5SP*þA3L]uM8 :{5Q 3$ۤL-U^m6u*j(p@92A~DOh6KP.*Hctǰ]}fq{5#Z_14_Tc18IzG(Z`}>)@5Be!( Dqb  DǒBz^W:l☑V^3PymȨSQuj[AB,$ib,2gjvMARϴo^LXLSE'C)<v�P.!-P;\4BG%jDZel6b 辷.[ndhi0wNZ}eTñ j&�)TjX}h_6ې$ͮ:S.Z6'W GZ 'HIR8Z F(/ O6)_oyT<8Wd~`r=jݶӶDt6{jEF1�\pWo*XeFZClQDZg3ۅ]ϰݗ#M5SroyWax+.ʎe2UJi}a-$cnfUV<UB"_j_)f"¸ &nNS�wtIAn /][v%Vn Shmc1mC^7Д[2v.qKjZLNU9� `b0< 1PG/_?x6~ItRP)%B\o/27<մ M!4==A=FKpX5edpyIjKm _wI{QIe%7.{ t?f.b_k/Si+7>.}zҝHi%/(딿e7~Y[APod}1Ղy,s<R+{ ne5e&tg 9W<O BІ-E:!ǣGhCt^s>ʸ340h y8{-h^o 8 "ց!A-#nJjaW(F(%֖? ;;Ysw/M w+l$_<"ܢGg ~p(Z]E!>J^'Ҿ0xx5Ts~˘Ds-+s6WwhY;9^0-b`k NqKy<nN Z&AS*$Qd7!?1GPf RTA`xs^jx|VshpkYc {$ jDOnB)wzm2l"@"Ã֣7[0(C<mos9ZHV8,n =iIF77~mXmq0AQd6`XĄ W}B-5:,uCBGv]r|ڭmrզ`I(˝B|%L3޳/(]8/=_ - p_fQ?;Zx G `T$wƧ7(b="#R_&\ ˍ(])cY.SEjSAd�滳wI=WDSZgw<3SNj5`�" Ε(Cng# d8Q"zpT"dCԌjV΅ QwMFCPʢƸs<)ȄgqԼqZ <Sy{  Z0gk1;0,Ɲݶ>1ux PB7? @fM"O8[q3m 6 zaz23E+X37_/p_`vr{ >H _>fNԴ"K~);l&sW+i%<He7/|(5z 4ceNnh6-Ƙ6@0:M][L{c I#kM#`vUq7xM@y"9AİWmzH$&d`N!ߞuhG$$\ j ]Co']kae}':>'{{OVs41T0:\Ms&&ײ P;-8ؾu[jM왱T7Q M1=9{R]b%<kԣ򏝑ؽ~~z_K0Z$&A"Nݪb,~qλ] 'pwҸ9rzU'ġf:駩04%*.J<Y$:uTPKCsrs_{N=㔕>K~_#7]DqYVtJɰ'6$R-@4Z*O*rIXvWg5Y}*=KB׉ ۷tr4] ࿘ pұs4Pb6;TxpbS<tY k_&9dQ86gQ"'$} �p㣩EGe4NܑTqZɉ&͞o#5{Kԩ=<݉%mGn;ϓ\\/&41ɬۀdO�AIp2':푴J2V!"Ld.\"eO2>†s]i-D:8'M * ӧsRQ mf i3=;1< T dރS!<JE_ob>'&fя(LtJp-?2zҟaà!G:[pOMgfܗ@R6_; Yj8v.O%Ւk,.2C__0DraR9 hUx{o@`aPj>{>:Ojm|oCT1(Oh0AlB(Ug޷4&IA/犦zv{ZZ9;).Gg,OE?ZSd>t_r+b"P+g.o.^S՜Zy, ݲ9kco/Hz( \v9E+_hE;畧H|}Apk@WhKOĐc[aR4~ >`?GP J-H G{AeW j3/Q`a%fY`�z R>18 |vs74^"3 fq~rh;"'N;Ć 8})~&: +pe6`gϊR(Ӭ͛^m˿Rkur沒&;J s:ԋkЯ.1JN=~ IԖ"^m&t-XW0EќK](�weXo/{Ƨ=c]Xp/>/w)i 87rxY!QPN?SDguڵ %zBdi7y1JUpvVO+kr^ k,ت {^Ïxo6Ks" 7%`j]PZ>ĸpz$x8i{dq!(B%!ea&(Jid.\FF Zg::2ڬKJ,ڶ9[f:TNuPE*7_ϝϒʘ8՜&9jA*BQđD@Jv*U)WZ0|M~~-,6YS8Y"cqRFd$|:~0A+\9Eha*[-oVHᚋ9o\ߑ`<rM[S>0a'[q˄E&I!a&*r٫i.j @q\+c @> ^ȮGZJxYYCQ=äP)WI^B liKSĒt+N埑+V; VZX<-R9{ B<&{q%;"2wS,(E1⸈_Awn 27(0&Y??0$C/5P]x}a ͇!m)CѶ4!-ei7S$OM3~&JNt,9Dȯy??:%z=بd/,ߧvrfs\f{?pM?Y mѾ3~j^o zl& Z嫳U(&b:eT5pc+.fQpG_b?y4mBԚzJt^!Bz^kw:)LA^^^Ʌ`9Cܤ*ț9"1:9 $E!9Ks_A%t@*@ٲ~/9%] 53wy=_R[Tj8ն.tC 7W$L(I�2z9epæ$Q S&E`)=" *>.:Y:!D^B_%⟦Ӝ,9d|;%^Mnt݁B@~ XSK[jwx/N\(YHc0EF* !ǗzexS6Lg%ȩbjP33;dy_o¸gHO[Ls`]snm.Q;TQ$J/+Pt,.Dk6۹*1 W דG+ oly('Q Pp"R8`k!\R8z(_0F^Dt?avІs*s&Kz{$|.?|Ntꛬ%I KG@]jmRzog)_zfjB0}}UviYBP_9a !8O/>b1 MWp"eDq \rZ`v&+1bmKZCkR+#c 0.dJ5I&;m<ro[/Ge 5~:k1,FB;9C7 k&^.x jr*G?yed*rPWa؉{hKF&ٰ6HZ$g= ]զR >)KQ2\tLqnX?mY7&IaLڏPAETʜ#>rjfU9�bJ ;Y5 ɚgY+FjR3FNxJ?/Kwcx Lp _;ہ 'WxuB\5tX疑X&Xås:#\s+ͳD;xc&qJtY-A6(Lsi]Ɔ?6en9JUhs{ 1Q=v ۢilZ]6&A21h[ gfOڌ7b891i 9xYgF5H.#z]"rƪaP]s5Jd)* /y Q \|t \7@ͰGSYx]c�qZ<U/ZT.Ws!Nɭ&%f08F[7aΰ ”txB>.BX'؜Ns@sL.KK%=`|5w9M"Ox.�y{!4״UeKq ګbEQe|O$6[⁥Y` -/YA;2�% WR`Zq#vsVazU$U倐ۥ& Ʊ&YLǧ]>CT)1;zˣ#^+x*xGc3BT| p4YgM&*d&>Njƥn.6ݭ /KZjp@W~o#\L_$0,nǀv2nܚ&^$+|_o7+P􄔬0+0}g&^$Gxߨ%MlE[^G7b ;A<&P6wOMeRt(s^.Dv ?X=ƉxG8#֖ Dj"7• x^];2۟<'t7l՚V%YxM.-ڙgdxoL 5Y۬+fءc܎S<T [QDqExOlݴQ4٣T;[ŧDO˯L/Y}}کSY! 1Sd,s//.8Ro˕5e2`CQj3TAeVh4lys*bFKNI^1 �uiM[g ӕID1J'8g fW\2WhhftWH'Y3NXyrRUJkg�8Mc57<ȯQ+ ix?Uκ1:SIRPd^][)k^F^mHC㼟1YWK^إKk]”y/wR{KBJC XVߣ mZ\+A71oXD8݇ 4v'\#ei[vu`;P"\a;&KuJ bMWv8 G~ħB ]{t$9QʲP[d?!sR38SE $h 1.:\,# ۾sZk}hؾ̮(?y#荮~oVr .:벌:'hMhkmJ׍io%^È\v@~F1B7S:BStC5#u:짯>]nL|Vys�cwm/>W5u(R^KT?(Y?!USd#䆋c1gv$7 )\10}%dPš٩RSycnэ#-$`DIw%OK :|O蹀F, ]fv\d!\[ ~[#WLAf"\63k6q�d��޽\_Sm60f`Yy3�Tn7�6|TpBC{RQ66 w;ՇW)^^vb{I\:%MR`B -f _@B+"|OVN; AI/Szܘ ӆ+EM ᝏ^P2-̄K$ n ^tuG{;2ˠl~']G2vmKAZig+o7!t"@WȂۯ} Nywktc),Ib( с䰹o+d 23&4{ٮ30bpUX"w$WʵFE/X꨿T#QEyd7q0ʒϑg~lԑUlvqTtT}=DH3N%0@17㢨MБAW(][3l"7}@S8I˒[WfMvE 7dq`fH0{Ma Êp2 mcS/Kא<2roqWeCOlz?2SGy8xo\B6ǜ MPQF#BIPL$vųLi?`<+^ĥe%`D;%^fx+UF&/P�2u9EP$x]gnkBGFo2 NШ,";. %0Ǐ�Ѱ|vRV;D&YzzXuz^)6Gְ#6YeLEP.ꟛ}\} ^iji:w<Vx�?eu]6Q.\ozfTΠZM[ !-/NlyD^0f Fނ)5D,:;BYfUcc.,>A?*%p%J(U$} mn{-Rt%&##6mDE *<O6;q^ xDUZ13!K%sPr.-ۭ%۵CFޕ y,%.P v`3tHXZNrIa-.%Hok<7a94F}GC؇r 4ĢdjFoBh0 EdŞAL'也yM)Zbꕘ!HܒYQA N'Kii�AOzTM.@6:$@3k&5)gGˢ,ak˼ C_.#);̓wHz @X7߷eEdvS/ڼ z qXzє=9ͨZ{y*%_ =mE%&^wjؘ##SclD[ty)Okb @_UCF:(E',<WX.iJIɘ~�~Q%c FFV<٦5Y(S $nkЮY_Z^W|ί76#4$3@\1^i 0I?z0· ^nCayN El i CTDe]ƝyzZě/af<PbgU(fQ6} eUӬJ3H89#읡J!wA4rLɫ1鏕l%BK0a/㰖7}Ê9ҙf2hXk1D`/͐\p_gTA>+FM6|{X/0f�LG/B%\0sKnKy<}&;E)PѡRxRj ,S(B$ۨkdjǒs@z{*7js}6.H piR^Ç2t`tm]lxI KAa6]1~3쯌.9zwcZ w%3`4x as q/|^񆐰ҩTP?J%�U1!JAHJa9it5bN$?o`&WrJ,)a@mrqn0] :`Q$6ZRy%'-cT+F,"JC9͠y~ǥJZ\%0<VoT=L:8z-�vzld�LO <#"dٿ G!H}Ŧ~"%Olsڐ0a3ȔT6ǜSr+ʚM ȓ'!0'?/k~bmO12N9MP.;|a>U6@Qچu>*h8"^+d7O2](h]55e_YE/5+ǰd{G訖{ckA=ih c-Ķmx3И[C_yGM.�HƺȁtD<Vuf;M ShAAX6v1RyCNsV"$js B%4^$B$H/<(x?I-wæ@ffpWПiH}h c8)&BmU4)QPS0ET|8hSd1Z=⣲JBkg  VND�?8OG+w6|!'ns8|iӍ4%G=L(E[`+c*v5dńDKτL$`\,ts?+֣~-HkIK+X*h1qM69:P\J]KB}DYk"ͤ}'FasO|Em.E]U!�"S5/}ֶtJ;9M&PH˦upL1ɔ^Y 5eœxj)t|>`mp?Mmd$F@Z"xp?>:dwum\f H?}fr켩؎y7l਷ϋ3Tt`V1dDW|p>AuOC,g@w5 &SR^P6C/iR1:T@{NWR , wrvuK% ?/Kc cIzx2x +М٦`"ÆUWpx.vl<-J9A_ h6K?ֳꣽ7Ӂ9v5~vAٖjcpX'J7{w-tbtYz Ay[TjFhWOiiHSATiA\bSU_Q΢*n_lxktN7襜#{H!c~2 /F|?IteExT,&&>g+tql!f ,%UD@E`\KW24kf CB_*o^Jadlh|uQRf41'k ^ҢkH SBL{yG#DZ. R]fP.viLM -To,H`fcab0NkUG1C.UP6u +[$}oJxMR'g2JBɕ* @(Jd#*H#mgPG'7T=mw0j IGO:4dmY7+@vU$ĜQu%V氛�QܕNF*VKrC6pj9<JB%vs$bh^啀^nQ8iEU3gK"(2~;kJH̵\rg/ AucCMh~kbX.64 Wɷ`sL啜>[�rp8%-QB<�OzbPhs#H"@Öv_Ħ�l!(؆~>̊ѽE0:Dx5H2 ɺHz1!b z�03LSܲ5rLF(<8h\ YMav;m(`LI(I͑u&)58YS򣜢-R\ы_6FZ<UW?=�eGz%#I}@I::&TQZ,CWCG}`T @ld4Ơ!JV\Gʍ7.],�ա !N mE#ŋ~V'Kt5_Pԩ&a}ي"BL #="_wy3(G|P%hltͽzf7r70ߏ5j&ɱ.aIBڮM(SK GBCw <ca4]mVG /V{ዃPY yF} q#*gƯ"2G>%w?<ۤaHã D^TӎJ[Wy+βU>h>O̝r\e+sֳ>X9ȼ@*뿙2 mfZۀ#$@j| |�OF^I hAaڂvGDzN`i.Zu43uϱɼB^YO@8rՌORyOpN 0= 5>u7>r p[>6myB kGk×| B?\WGteP*} l>1BB!HhIb<\0K45nVN݅Fڽ$̿){8CE KbI % :][%pb!:)P${V5‡ORo U U1;1WYk,m1E&ۻ+fA<uȩ:hMRk@\i*XfO=SӹIŲlUcCC1 óE0"W !>be#!f$WP]i9s ƚ%Azc~%԰e$%鯰&0PŻAI3Sj6b!m]wFD%Ņm &Ȭix%CLszd1\ h%�ȇY4g҄i?�~_%"K|5~P7Y"Zyi?b$4'&1E{{ 0k)gT{/s/uu Bnۚ5kV[ET3KW<T2YvFon> Q>% 5Y__gR/t18Xh@iT:IGVu.:h׽+?I0ܕZz)Wnp1D2KN.sM͛D`keĹYviy% ɷ-ca 7Ns#VʝR+f)MatZx}o/]_Ax–<F-a9:8& j0 ܥZ%"dH)ZA^w{o3䗡Y\PvIfJ&ޑ9)of{e=4C]Pb%'cG`a; l[[#:]ͼ˧CW`$s/U8䫗7}[|bWWW1_ x(:+$�&% X6p\Dsr, }#_&'#h~PrSw:qEU ԫQ';9R35& c%"*ѷ@+v݇uL W99=i([_5Ϛ /),UK))PQC!LLB*Cj!en7WhOH{LM/EKym_i"C^7dݴ>A*3,Tyy0e}֫ɪZ f2�U|2.+,̟:j@ʁl4)�:*M6.lіB^|�@)vGy16yQ/0}iwbr 7 5+])ʽ83&ްM�:EJhո&k {Rk9S�=4I.ՒVUf nBm2&V*LdI kp(=i NQLF[5vܺx=a !BѮ8ϪU(!@׈ a9Xjj㾀YgT Kd+!̈́U;�M02Tq -T`$sCRmI )\kZH:]#ܰk8vs_*4Sv+)(Jgw4m@:*>Zi#f8h̹ͥ&BኩXrψo=:H7{"7}wbKlC$㮝?`iIch CkZ/J_CtQ2dSr\J Lwɟ|xl5 1܁2 ϥ*6;,5<N+w=zWԃEuЅu{Q>pU?~t<XD\ șC@+.Wg/x)_iqAJ<^s;߲e=róg?kd[94Y^kcܝwl%oU.)DJc v,ÛG;n <COZf5#1| 2۩-a ǤOS!>$Aחeܮ:y!hlºqB8S_4fkėDAX8', ,r$)X'+qf=N`%FΠ>}nd ?g`#hI?9["h Ϭֳ�LBpT׺j1"=rXy8^7A*aɔKj4^u^XfJLʞ"wg8"{ aᓭryԊq$_ޣʡ9q6 *ޯ2HzcA)O1qO$}Ejyڬ|T5?&6L[/&sPgBl^%m LT \בZbh50ʭxdLg R`7(sԽO7aw ȨUϷp7d6q?3 GUSm?a^[}ܤ-+ATkL/u{$`I. ی8K4"xd.WQǫ2ޛ@- <\bں8_{e0n6`D]b1bL=;ݧk bY4|A^d�j'_fv]|C왱&�dLwxYz"Q\4Y8{xfs =^ &mhOHmMyc,90n;;E۟K_W YY4>zM;4XaWs+JKNf=i-8̝#H]vE+9bt/3MH+djj6cݢY:_@>qY*EߏsyBL[HcfO%'4(ïe0/zsԟ\Fh2K;ҽNKPHuG/tmdI@7`UsѿmM{�/1EPѣ0`ښ ˼]Uz!^lʠ{tUS|jFlI K @6 61⠠36ixQuK xRaE<#~ß,CE쉎[{·K#X]ld(Br.ap e UrZhT8qٖ:80ƌ  �JlK˴Ͷ錦ߕ1}*V~iR O(Ggî#Bx(R6EY3�c Jw1P3o=:`.ǵ�VȾF+n\4hX40?JF$Z?=y<QN֢ C}}voHÏI pztNKtx袎C03&74, J#u^b揱K畞W&[}lsFX`<;"vKǜ t}}#sdwwW(Q#r%=D<as yi^8ꯓO  J?k2Щ7UW7fb1v^݉}8g3h8˟bmkyT{nYQVs3$ 3u\7¬@]+ Zl);)lQ|:X(F2RF{F;!YtRaGJ޽\[u,"6edwX{]ѽIGC[g78)&W Rlȶ6Ghc\pr!R_fod8 !g7X7O^:CTE&晌)6\<洊*ȬMn\p_U654H IQ#da]"m z\HUPI\^蕤VPh1cE;s 椇GN &ÐQrTȭArŋv }HC|^{:J5a@W<#X|k,WxXƦ�ĹTEzTL^pP XFXa4xǻ$\wi.PAU^Il.5flM6JtFHnEv|ys派?bypn4B]ϛZt_b{0 +N-yF,\D$,pP"K??s9{K ;dj2n2?G4#IPM(sY1V(UՉ67>_99YAةA=KC 6G%3P)TL;)'0vgSHd"PY:=Ԥ 'i4.[3�g>5[u&A>ҵl'ҫ@SM@/"s&/,t%d 9PV*3v|&~>1tzL`km[Ce5mG4(9 0/%I/4KO4S@A)l'yL<gH$Dt`wΕ[ ]s }w+d:)n؃wQ~UX Yuà}/$x,<<i+l|4ҴRe))DM16%ӡ!ij_^+b 0<$T@R`HYyPvcVR%l.*Nv֭j:XVMTzd<äD_ �]*ku R&F(t)M͗iSPx |]YYy`!H8׈.%nb�֦`\â"ӫ@(:X3n4 �Ӆp*5)?]?.�#ܷ:c >Xa w<KZTbH`-֞JxXOޡ&WݽJ\aH8ssp_�'HW\)0IO"Ooȷ!ˈ&ƦH�¤ڌ[pt^~t_Lt9$={Pڌ?{[^@ZHփ\}PWꛪ91GMK!*/Q"t: S $e3%ESl %Q/qݘ-ZAC׽68Bz9]&}dh5 YF|fx ÄQ[! trl?w+`4үԏț^V´)BX[iP.S6|iU8CԉsWԋ ,r͵97 6/@ʳ7u2 PMW(k[PIF$Ě m۠I[ֽwE`_gףT$x_mVgSbvl R>`<zwqnUܠxjGHFlZ`yHe^:hQZ%/:q>]c[W3v^ ,sqT^E͢: L{YYV5P:h˰"DsW g -/֦3I@+WEy<QYN6c-4&^ބUnK03I1ўpTsNz2%n/XpE/*Ö?ڮtdJ#dLPhhEo&taO@0v[R!B RL ADiȃ,4SjyYY\ىs?PP8*XtΎqaKK"CLNTyɇ|oT]ɂa#_N'_Ć5GH64'Tdb_yfǕ[[ZfGAk/{WN@&C1hun w\w.ɦzLeJ9!O$^2tj$6!ֆc|#uj*u6UJ .IB舱p3VtON킻z('7D Q[ZC}$EiKBm%gi8^Rږ|g+jFWeB4Wl?Ž8Ρbl *3" ~9E: |Gs$pK@UKpud>(H}\>ۣ& \S%_ŽhGR6 XGpY!qc "+o^ c#df&=R,lLL<)+~چ50\h*!q,hs|h{Z[ HE8s/z\yKc`ʋƖp1,:9Bއ>b5"1jUJ@ �D}w@Syd�ItV܍L/u$i|v\h7ifi ϧ:lg-GrG)S:UtJنܨ9B,R:Q)IL@)'8}J4넊~9`'Nx5пg_P#;mݻ&8wD.^h3@>aȾ'egt'̺c^Eز_?j, *)}xu'Ƌ/`Nĉ]ʧ0zX9~l{4Og͔p7 CqP5vh/yZϻe"ш5ȍ]wK=a$J+M%e1A\@׹$F22ڨ6*؁m*Yܖu)<?؇7Tۙ L#<Ɣ`#ܰ~ot$  %I�"P#b= bevEFjmwCO\%Z:حA<@hzS, ^Bo,K;;C?5?-, tY"ɸpHEn,~;ej~$?6XH fask0 eӓDK`HY DeZXQ~߄Z,tICe% {Yf&6`aC1yς[(7N?Pg~ܳ~r5yȢ"&^fx:,pɣ2yzoPťf(%=uo4-Ȟ[1S&]XH24ńB + etuGٸ0:o{VpE{؈00Atv젏q!5!)b2.г&X|¸[x. 7 'd,ϥj*X~E?isuՎ-s{P3}Z̀r)a+"ƞ9PWGΧB(^529@J*OջMi|֢3R0Ս)mjڍ7I),aJ,D$}i~y#fC{P.f %IhY+OE+r{4d9uxN!BId4a\6Sg~*e>,kKO^՛~h79c9-^6;va?XXVlס_3.UGcWahbae_ʓ6BD8GFb9tm ۺxDά琇0Fl:h߽lQ# CJT<Ӝ)NG/\~gl BC[V :e >đGLED1I=Qt(Wcuѿtvirk^ȵyN<(E+@ه_I4ȦR cq].YR]~&hG95PcIkoa?Ҟџ#͋'b1r6X^F"UǍGW [N 2@ަm4E=Wq1j1igɁ0RHlڨ ^m<W 1PBM۴ �>O7 ֆPm{USW2]*׬H>}t Hp5_?Z<I?:/N T?ҡ~" kAcbQћx)S]Dڗ:W~h|s4hS5_~Ee�GmC]f"8^Y7LP /tL_'? Dx3:\Lw<HTٜ ީK2:0lf؝Q!_=+�ȸu[*@PB#X6 7)n./J1+8"SM<pkLS`6$š4J�o;Κ))\Fcl[Q?%dA^-n\aoXr\AjLP�1okG) *mB9&/y| 39:,FC&8fJ2f H#.׃{HZ"x}[dM/m,p5XZjueK`hρeHoBv q p~q%\Uܢ_[.ܒ@o- Yu4bտa ` 5鶇, Jn?wWU{l^'Cȼr[ nQ1ݟΦ~Ms)!¯yOlb\>!} P k i5 r#<7:Xff hHvvW <49C2|LlFve2 -z]|13 oV4ގ3&,İQzY:Td] SRc1dsyͩե%W;I=(1C%g@ޞǴc,78:, _J}8ehG4OeB"{(;}CSK[ [LKU|#^}da&[3BW%H+Pг]l} + S E#\I$5 yȈ';5d` ?w*Z^pyҒm B;cSn=tQ~&'`3쓱HFvε<}%=tXeGqX\X!\E?fŠkK"s3x~ʨbM0_OOys*f-rfR+=CG%p^~WҲY ^'G7C'CHC!N5n±TktDT~!DQ)j1Jc]'tDBee9IXn lZCdf"C@b$Rg W))M;v"NsHńCwp0Q4WS>6h�^(r^c hGBx"pXNttmЁmHyȑpi `Oݎ[c!֬ (i՗lOŜoleq k P4!NϘ�ҼYn9'ӜDu=7K[}w3F%]yȧdU׭ۅr6jELNkd1\@GlG)x*`E^Sv@U�jO+ 7C/dÂO+:)fؙ<#cybZV$QOtZdH*e*/XwnE홓A?*$�%08"Ew!f@ <aQVeЀx:41&b:^i CxS-j/^-P#sd?0)\5=[1ԜJH񚢌3ihBNJ4\ԾU1i4D?CyQkFoU2#G29xް@(&aV*�6׵/FJ.o+QUy 'CK6񏱾A;DPj J#s9.t;D`9 +cs#)N<IQ`EK߻l}h+<Ffb?/gU;JVhBNHz괣X�\z23ݙ<UXH&.6z;@^ιՆ3gV ]Ӑ0rDfDiPH9!xoN_<KME*KCBsDM̢a-t$)"1UswyX5vXܕ ,n )eAuiÅ,] 8DU:4!xCI0YX`N Xk s{CuIr6T9l;Id> ?wPё679u<0 0R[跲D d,kttpiߴ );mZT)<F6.T{0ŋ _WS>po!-s]1dB'n㉓ s M$0ETLY@�s*Vm9 @3*y1y.ЦkڲUmp0P)x+d8bzkWF6K+=*7Vނq@sbRUjIQý]t1=(~ ١|^?akF_HHl?~_zGlM Wd>dudwf45AVKZ(Nxu#w[qIV3G޽WJSqgp )`bmG//kR N[q;Hx^JOqC s&L#  gς~GzǗ<7bSE*V[ ^.kVD'| "1=^R" H7d 1XGB}ljU]{V㭢Atτ[M�<Zu&]e\S{RM~Q(p`xʝ/JWg?8 @c7Jaǻf) ~Կ8>݁^NcNo}P& Cק򚳓W6Ϩоrrv�^kY7M4;綘`"Mbʿ 3Iۘ)y ܂.vfDY65]X!] 3Yu9S8� kcsf0?-/V:1En D;YgbFN Q&_CpxVs~J㫒:4u 93A$NTDŶǫ/#,G ,$pU՗c~we{ E }#tM-mӮexx`E6,LyW$%$ T%3*޹\ஂ) {c3.e}OHVoz|›qc5^r6v.) 6U>snqi5L@Qu9NU7z9- .t(Jt˜+8w8`oB}Ra g z&6m8OGK>PgKj=_aʏFg2F\z}?!i^nϲτCAmߋZGHfé4>򍧶/ =6-[ pj>ҟ,5d%m:Kg$K\u@~0/&E޵ӂ5Kj&^V$m#7[VC0XDT~xSy$5SjsDhdRfT U8yp7fwnk8K5bvѕ4 D։|]EzP h  �vYw=givjTR3 jwd]9'{6'\bI<js$c KJ^BǤ?Ɏؚ$X{ȨUwY(?!oTCp`I;ZR~H=Qyu~&}^l:r2Ajiοɓ9udչ�_ $?G=fz!I13Oq"PP0bujƄ:B MhfZ4Qt!{׏4ˋCQAډ!|]ԟE!sw"л,67~]:,Le’ZC�NGu^oVox y ɤ>jQ >1Ȓ"`% K d 'FT**У|xiN]*A `4f>U$a0]v|a72,u$]^ʫy-SHh`ϵ] N[~,KݛKeo'yP߲څ \^Ev`W}Aȍȕ ) xA#<n8N/]]4" sr?.7[wͬ1bCu5Π;jvC i<L�^9}~&෷)(GC -lZGj>U"Z'Db9DS{9׎#d|;VCi"rwUeܖ׌xĥ;=$ ^ n.�`yz:mRJ,vLd{Ks^sixT 7S1-N�HoRMZCGf8?n}N~fRTy[I11W' WL[ 2;u Q[;nw@e̼AEsJ0.yϪYg.ˌE,=_QU]pkh)`h&)hi4-"1dG < aY6{sg\Vi}cRf`m#B 3h Ndz۷dٞw6t="wSm} n&?77 n`8L4`£LT>d4S\z΢skةT?:uƀštM)0 yqHB" wW@[^9T:e\GeաY,&z6?إ{֘\2W<-;-GU-Ӳc8cA%17B<@s wظ@uKuSޣ+y` l X3B^sb,}>Rfi {Ȋ u=|*(s"é{b@oYD^m^!1;ʞo9u\Kgq2>]IoX!{df|_ |(6#$K˵ ~ S|˜\y&ohЯUBWˍW>A淆2jN<yFޟ!Wqk坰PZ,8 3E؆ sx%o<,4o3C&n3;X0R'1Y)&/؈,vU;da[F_;0y1OȄU7)Kvož&32  h'ClnGߌjߛIzG;j!AB@?!AVgYD?; 3S]+p"iJ1(tDƕ*dP)b&_]w2U&<odS !Y9̫6gjck9Qt)+<*8@]vך:E˭^\֊S{otӸK1dzyZ9' ?+Fi0$!@d:dٜWܙ碀FdP(Knr{D;!5=5"$Ri&G9# fG{< S |?fT hTJwBx=1w'A!S jUyI֫~Wa4+ɪq}VpC4X /Loj>Z6nNUiV4ӷT^-7a�t,UgDen`N`O||,�ijbbSj6Vgף3O]'\; UiV׊XD\ ,22;pNEksM+B v:-3~dqWGd"aP`0x8Bz7=L9}Rꙮ%LJn|TV4�g(2ݽTp)lv8έza׾BB(#9 jS%82_ "rG$6Ü1#e#q8!CJюp__' >ījakFgp@,M2=^[kCO>ՙԓ7"P& Xj%+Ğ<,:aR;! `om }w4[ǃGtbr3ds5C5/Oؤ7]A鰓tL7(Mvz,o2C٦4L( Î  l^  (qD7 n59s?aAH=�>WSM`hkB8SȔ$?w׎a GTf]sm wu9`2YF�T#<R] 'i\RԪ i8}GIGLXĦ>ypWS;+xNVL'H(L7M,о�-/[B52Y0KiH 9 *;h^3D>Xթ %E3=W&-ha3;~UmyzkEk�Bw|<M\ : 1j|UZ 6F>84�|_d'{%NIT&a# oƚyp Ѹ�F4Wxw:~7Fԏb]@WՀݜݽSYT7qFÍVYj#/u]ShxzGj8g`>< CǠEFKoa:~ %=p*  ic ["�"q$p< oƮ}Tζxr~O [D넙E4+t쯴 ؏Kqxbwqt0&)M ku ѡ/ԹCxzʙ m;64e.&W_iҩ㜓ݬ3\5D>n]F' D1":゗*Ly'ҝn1O0K2/j,wr9;]m\z"P*V7"UYbb˱r:ϥ0HO'd0!T bi5r'`iSHG;N{o'˂i-mۉ*pF74'tymB.F!JUzNTߠJ5$:VTS-fS`g~6 ?1'NW0a?Ew'mݻ| 1.X*y=*Xkf 'eD-Vuj ^V 7룑�QC,~f/\ ΄yڈwM8F()YHHS!y oD {/AZ�ᗶ閲w8MD(z^$_W /͞*DK?OQ=52w_y.D ;I85,5勻Mn�ğd *$զ5% ģ Lw(w7^c-gOՕ;s�-P;5e=t\`AsBZEEzlU~SyAW^+U7xyZ ('ְ`]F P<QKSsqw}= of?uγNNؘJ W,[BGJ AEyyEKYԺ沛<q^cGYL5Ӿ·)9T?*#\~voVVo&HK2 Dk-\/Ǿ '|ty=(^J\{͙ndlP7OxuӐ/rk3A{v<s" y;&1?(6�eNIxiҒiRv-)J:H6\<C}RI:7F f<gQ%mwOGuy#'5F"v!*rhzGj\T(e!Dâ!_2xb;:к B cbWph:پ.6d$x=4)@#?/;*RV7I<_2Tf-�F%}g(dNy[vk `@bCZwRr뤈W,Z `b8|XP5 Ula'SX~SnN1͗]4΍d7)p[5dT[wBYj>kCݽM:RAo 뭏lpkw/50U[=e!/c`@Y =$wZlᖴOk/W&Zf)q`*H^Z 8M~9 n> Yp^$=ȏWQΣO1=vXW_MPF}]IeLv C+뿛W_>4lj " J%g3n<z`Yyիs92 A 'y_T]'Ϟ2t8^{Niܲ<kFb ehuEAA :0i]I; r=y[~%v3E.FfѦQ=!nL?_Nxy+ 1w0Kp(%}jV4Ӡ>VONV9sw7w=IzGvpupYL\#adCeޞkףy]ƝV<2Z4Ż9չI|ij6qy(lIASҔc=}ߋ,bzn>̦/$8c>Wb"VjZ71DDZl}xẫx7׀h:RV@)i4N3U]{;b&2-?tK8CO«#J6JV5b6 .7qapcK'+`n)A,LxQX �_R "`mIߵNOkL\7u4׶m7j6/AvY4a�ݒtGG#dlA]bOqW{t;`+ Ze eHqJڹ蟶Bm6  ]kлu:!#lNdC#+=5GWyoHQ)X{$pM""ŷ�'`ȗԲvq[0wژ 3^�dT g`ۤN1i~7w#V‘Ez?$9B<,{bXuƸ '|-7xHϓG NBw=|'d{%Q$Lw^Z@]ƻLĦIQܰ}um.ijcM0Kp;k -n5^p-24oqvlR'ߤK4/8s9%|9e>8\b䒚x(K&reI1#Ory>c` .=5;e$e,K9xX柑Қ%IQ0Ʈ^@䥬M f<c,tѬf�hD/Wf�+P#nI rlUjP;3*>=/o%kǟ?ȘJ<�ZvڵtL27.)2: Fh7A%7a*šJo|[Ynw(>~ {HM XNrlt7lA:~B&{Sk}SImOz'Pp- N}9<1rؗ|\-4 Twsy)rG\{leqcy_v&VyO+`6dg*?F$v Ή &N ,? ӌyQ΢*3!kD4|9D Bj6Q^{ǭM/S9*:"3 'Iسeϧ!ޘ�/IllFKEBX[EƱMvW*-'2c~^4*ja{cj#hc}r?7(fӺ_Oͤc4FxځR[#G; nO|BK {o1卫JcN*C g|?`3xJc|g=UyO1rǥbL+zD'}M1pUx]`M� 8;N d$@SkߦEx+xi % \MjH ,Br4D "*'X4.GLlY֓DFo /C~=wmJ=d{G~]ݶ?:o&t $)Q&6ʕ<[VÔB[`|}t8ƗA 07{4 Ww -XS1I}fxd%OK8N'c5G)Ν Aa[UVlQfx?ڱD1#<lQ` .:P{'1�!O ^p:Dl�3y#NϳM - xhF}7sdC*ݎ iNU> A'rAn.C&ca%Ċ?EU9݁ovp%"}#oE3?UTJO6Q؜,8rz\N"F9j9XΨ|9Tc!Zx|gNwM]>I%<1Hy۬k[ kz<?SZ$wte SK͠/�vtp󴩍[X R'3V7Of ׾Hܡ՞*05r Ls=Ij6 Zтx z"qJ^c.[!qϪ1d?u-z=M𛳻J32J=cxȢFޜB}'p =嵚1!(}释z~lG Rz�)ۯ-V6SW zܛ{܍Ӣ?Vփ$(FmNyY=;-4~:T`d'-I͕Pߧ>Ioo[yHWDZp`dpf}jm{D `Gus1;$7xFήGa9`Hp 'R1)蝜(&)DƺQ QNNEL?ΨGSYϻJJV:3;R Od<`+>,ڍLYlwܝj+I[ Bӛ#"wZ児BH*40Q@{iqd>F`Mm+'nm0#0***ְ LIB1$uaغz x~:~/ Yӥ_V1upi_Sr</^˙.,R!P|pm{=Զi.*)3q(s^{˂[ !hspu.>9t.nJQ-{ࡉZyh�T l;+"̩(a J΍iJ[KE_x_Y \X47XٳP'%yK7|t <ѡ/ 9$˱|翃JZp: 1~u"'f{?]a-э0@,{7p^ι" Y7~0c8ĊSeh5CfWJy𑝵e5.. OK3\jһ}W<�\Y!"Q 1& {D!GF0|ʓt1b�X5⤉OC\+~xd q2 {j>)THgl{{_L9n'eZӺ%GM{GYGQ&G9k>zir #ĝ4)*oT1Oӳ)-&s}8b:Ϙ< &xk9o�rl{g.e]if6!!?PNǰկ^ڜfw.&C{YE -AW<Hyzi4(v8z=6V^#1ՙ75z!X~(#M�waku*ΒPGTƼuZsZ/_SYk+RYGό]Ar>XޥB=aPh=C�Yȧnrɉ[Y5.}m o~o4M$Xv!JdS^g<b&) ߷?>u3]Ø:ˠߞ:u'.-0@wFaY%)}IYEYeU!@D+ycmF8͸h]t䮵n Y1۹�Q9[AJFh4O+tCGrMkDX:imtY}iw>LZ)̹<,? xJd_;މO¯Bu#-0q4&z(Mk3[NL:1r8-[ ŷNUu=D2G[Sp$ijП�ZfAiQU\ʸ�P V>Zh2ciffG^<=]1\ۤ}>3؅נ .5gR\1WJi.u^Ύq$^V:YUuC]X~w$E Uzyk41O!'%Eo H: QKVwܪ[ (˔L)}j4zq@\-3~[ltlUm_b*�:ᙊNmҜ܋N� ~cU6[Oq2#]ɝ W)P_<r=5cA#IsKW>4R*iЙ.S۪iF&|յ5Kx^ub,MA)INHcm"0etъEV&%?QSTUrڿ%Yڳcx*7X)N6 rф}洉kM^yX=S~$-P@;�Q}-6ryW.}FNH,p7D ԤCİZ'dsܞs\w\(8£�eѶrSm=u0͆q�DʪVٲHW4c1O0Y*}9g{K-(@AHq h]&j V;WNIk{Ձa̅.}83GngYvO5Ȧӧ%܍Rl#s*t3a-gJeだc Z=MHQ9`tpfH80՗p! 2*aL+ ȁ NmSl1I|0(j͵Ys2["q>@Hm<溜v<htĖj,|i 'Q C!U"BjkSr+ݫf {o[wͪ2 fU1GNbgc@s*N쇏GbRiF]v6\LZUM߀VdTjuc8̉ufI}sIJUca"ڽU[k%+yp^Y=,`16~$a *l9!ZGGrO ϙN4[GH",ğ^gV'l=k)/4[,fRO^Shh%pSҰWӣ(Uxzr)NM g5.icTfUU*IiE/HXKsnܒyKVA(w>_PFr:d^ǂ=!-.R]$1so ]|r%Uİ` WXCAV\Ei=Y/"ӿ1Ӎ</S6c6@k~oTa7w$>w:~ QF5GV jtpNs)?ZsR|ZK+NdC',2s]]3;eSyo^1WsGICVVɊdYHZL2Ǜp�٤guFN0k͇NU~}ݨh; cvVuf%`C60|Z}Ï?dء$R(8>cu'-{aDY(s~B0TfhQoH6S/1.r{{xݶSTutKjwFԊj'#I"'\mO7*"&0 �JC7Z>mYo%&iΰ3wlO=UmJcW E^>v>^y8wGJ Y0 R֞TC=Pʵ%]Uk"Z_G9myje ;PO�C;j!m" /FcۄmR{KVM,O$~!0 Tk~Xl].鷤[i[90ebJUϪM4͢բAL|~OoKdK 3E&Al' j?s)NXO׏�`]w:;M -xNiI.r4 u-#7#I%&8H˲d:4ή *~5顏Q5PIȞtTf 5KE^x::\DF4M�)uեceLk͙ɎŦ�hAx>W)+t^0)"Gˇ g;j"Ob E87S^oDpk{:pasW;Lp觉ܴ e3'wjV0[=4G56{0 &bRHmǹ4:j/*|nl"9PoQ^E !8 *ɛ%\?Cõ!C@ u7$>JsYS0u{@{=ԂDz#E%ǁ|☥\"6<ؘg&xy^67 [c3ncb&P�C?Lk{Bb@ᆱ]˳2ZCU tJzE#NvJۂ3uLfL~�s9C eթ0ft;E|4{`% KA"T ݶ15wv> |4u�&w+)+ $NSz .?+\1 zQU0+D ;19:AN`i/&WTY h/|ozt}I}c$qhE$4[/9mMx_k;oQlSNc ^2>{<ۨXwv ,~݇JDKrd΢tEUK~+\d'?)ϑO`r/;q&(m4mD5(brey4~<MSDb88N/2uiJE[qtݱPAzBLE- k'Vip(@vu*mϳZensv|{�ztw-0F,x87|-s$l8jYjWtU> ul>B#-LxD%_T Gaܟb^ZEUΈj-" 95EyƱlZXpTewYE>+7[(I�arKf. +h仭 x gL))Q8/_yi7P~Up ɜR9Z0^*o^VATR*' _侨Ue,?cVY"xfmCv"0 cbmGǑ_n[rFCAQʡzmsUy6 {]|rY{s<prRѬ`%Y`J"[b OROO|w{)9(`Av Ư�YbiѥξKH. WT^ڋ5H .*>D�Fa2 Z4=0yvFz+[=x2D9|ST_d.Y!Tj^;!v˪K])F rn2# ЃP7<x5>&Z`pc�d\I`C(7| i=v<7�<mhWx4= sUkBW1G&. 92^G3[y2*?]`3L&Қ4)Oׇ<֥ڇ:.KK U]3 ;j":d=Bގ t DoCcD`Ym)׊j0uۇjKpW\e9lFU:/c+tRsApH}S�c^�fޒV;>9hs5kws*S-؊ "P{їȂY.R[O%]0QC~ݺF ޥd@Rw8wV_rMw71cft968Vc@b}4pYSIY.Q"-9oS.!/wc``Hp!P0P]Ce#Ag-ԋF8sTǴ'B"e56 5B k@+NC d!WB3weq^X, n 0/{r[E4b`kyBf֯n,f=[Ԛt@tj$$Rʖc$'(<, DTEcrT afMsyT;iqyUxRɧv fs8 =w'Y  NTQ}<?O:3^@22cK1'f 01hcbdH1~IwRYg׎RiߧzZ[ XjPmn"#"Q)D+K)1IɲjF{  �=Ho%J16G?%�z:V 1<coHS=F\kղeߔT 2* R+}l+cU*똺8% DN{b  _yvQ(+Ɉ$X]Z]bK:BD)*kJM?: cFtPTZôBQzRV6 5/ۮv^!,ѿ&M" iYpe\V4i^w[(31lk`,KzxU3V8\JhwsXݓR:w0ÅT [`׸"EyI`"ᠽ<Mݎz6)u73[+s"<Nݘ|u|QJg˾xva#oв%POp.]7�3+㶴r囫&Z3jJiB8~\=$TvjoUp"M:� !*H^ [{P*TT3 7}O>jlzʣ*x/"Y(EV7PAn%θ(|NL'6-eFЉPӓ!h|>Ċ1;]M:t'=k O/g^bS syNRݻ$^Uڋbg}/k|ݣ:ndjlb;fq<}ݙtu ;0+j_zځJ~]{>! 7 ]<JT m.f ` Ϸ+7ΧZ]-{tq*>=I& k7SC7qԧ:]18v;%A'�\{ h3NB%4tgԥF\a[z?nR"Ńs7 Ή3�?P`vkiȌRֱC&_T�ZܶU nXr#9|tO>e8SlvHɭJHX7ËQH}Ԟ)'ɮ9j0<ApZrPe',gР'gҰȻـJ4ql uEr:qX3ś=:ylTխ)Zdī!׷(`-3w-_As}7K-p;p:\;Ota:s!\(X¯Ui~#N֋]A+Se E_{]}' 9d}EԱ~DYkoγ0I`od2i/Av۟r5,&öCIAJ5b`7>"8<{_ˬf}sD^ <>z\(k_Z}[4p(sɄ̶Yxd;(v$LODzN@Ope23/-.-XWfѳO}Zf"_}%eQ'z:,&`;B9ܮ7䬫F rmi ;,z6f�﹊rz ݪX/+42�|ZEJ#eID!׻?P=96TKD2)$K 0iku&EPC]yH)7b߮ǧtdC �xVLٶvbkN`ǚW?>+LWNQ!eoxh?࿼ji]d) '0&CUI't,Q4O7V,-<WF PVUOɅ'1Wh~=d)6@B*Z;cp;i"ϴip._NΘZxn~[t#ZY}wŻ3i}HIxm\mx}Y| $kzm6A<vF "ѝ/OA%P۴gigN穒�?gϚuE+v\1GQ#d)!;uLD?pGuzk>S{EaQu&z,f/^$67$$�* 1K|C3(U*{I̞ʪSB9U[<O_>ͳ�;fM$�1"II>L? l 0JT8.Dō+}4QZ]$ȡiXp+ǷdyKS#KuZ_3HOĄOWd[ 8K0l죞ˬX&+-3q.쑓r\eV�WP˴FЦUIތDnD8V?}9\G9IfP+$83fVXx`nFo]KFK%ZbI&м>qrC!(`A/:Re,˓ޘ Ŀh.a;&5 LLZX(W?iaXk #&>tгKe}~pkvJWoh\~\CVPj̕ˀ[Y` U^$y-yg1[F.ZE*\yhi} ` <kB :oVc/`Xv<Ot~CZ AsNZgKXFj%?)OKEԧU݌~g#&["zXP;idu' Wy-^&_M@PHuj1f7ߘ̉1}lKg8H-;˕f@)zkQ&ưCImb& 8rS;\n*l�qd)%]q7ǶN Lc':Q3a;Döz,!*n"X~V9+fA=Gz,812Z2Ŵ'!=d\v_%֋n#O S%Ds??ݭ9Y~$HVir+@9\5KY f^}Y#/C۾UؐL�Y\Ĺk4qB<L`ao`c(nÄ@=}a>ߙ 'K7_}=szфFtc0mT?z:BqJ"|g>olG5N� f'mx%oFӉ끙CQD%]<$Pz6we^kOh+բՏ.UiBG2(C ˝}4垙1* y(SU0U(o~؜XGV20m:ѿD7F¼GF KD#a k{y `| Z]uEH|F)L2?:ؤ@ئ.~]XliO4-7N=R4ca(,jOI)._qS:Vym-Cdf$87VO0jĎF:@p#V,! J \.d!W8v7]v~Xq;dJ㌄;wp 8?˹9~Cq: ?P/ A͔، I)jf'za|Ib+dD1uTgBlԓ'`ňiIKV؎'G?h߾^KpB2e9MZ5 nC#Jq� rp{حs-Q,|+QMR}&׻(ac |VYV5 jn=#E0 Z֠*Pҿv mSI4USʁ"gӧcי\>uŦC}N no$؎x|kvlw[)w_+zi|kwIXH`2BPPɗXK_4 R@8=Tcnsf8Q"LGw6{"SzǨtqS\ 4 N,='(n h}SI-Y|Q\}$hBc՟v(ם7Im % 7O::PR2> 1PX~}$7]|>i=f V"ouSvO T`Lnbe *W^5o? e! uV5/ZBfE 3IGjfGXL;]Ӯi< �uteSBƒGx^h-.?$< Q$&H<IWa(e, &qQ 8zEs ~cp/*Z| � fTjtU7/FqJ}G.|,^ôz^vټ[ec%T+8UGv'TiˡA;wv@&pAR](&;Ke κ÷yʌPJf#"6^F55OH9Y� F,5(U?T],ad}7)6qo#{H%\wn'>\AvZC/ɘNaN:tbŭԯ\,ʝ C5Os_CWQ^9]O@<zŧvIY԰3;XE\-&NO찃QH,^o&iFwET~?ŒK:X N9�FpFuYGv%Omb!^ސ%koo|P{o%l_^[ů[L ~7O|@EuB/XS�Ivc~R v&= U֕ {SߔD!"7D8 1/mݢ C xM|:U`*g4[9e%> El٘>"b`gؗ*61ͮd̑sT'c65a*4uքf}O_0LBipW8!K' x yں++>`W`gք6=a @=@af_cI`UlMɊ#X\tGC)3#~4?A�{m=Cxi ;NЌ!Te{;kl&$$ dY5xZ(ˆuz>tgHiU V<wvB-ys<9]36$kZRHcƜ2gȶ~I" (̈, \~&,$v.<!h ŜϕqXxM0z$cb)mٵ;4%s]H|,\Bm^MءONF MҘmXxS:h,D=Y)MJi[5a|`N]y/5bROO Nhf&suR9! uoY-3:Tgpkzb1P#00�әӲ35 Wמ Ѐ-돼6ݱjpQIEQl�` dP*T݀ ːT'pyZ20oi)V1vXx3j-m4+ WTİ4YHkXZO/#mxjUT [B|eP )[n% LǼΕzF1@vNl:zP!od4S2$s-q֛h"kzY7ܹX70x`[JF1ߖ^`\mm=!Hq K!jo"[ TR2ف @G5(K̉1!SJBȂ¿)3]NPJ+yEYYĞ,4tJNvq>Jڒan^_+B xb&J&\2 mU2|1 'vr}1tPw#F/A },Tl^m)S-~$t1 VچēҺŋX2�\,8UQQ.9�Z>:ˮ煈t՚#%Rfá-E=Jg[i5HFp~<*=G.z5+;U'( '\kJvP/ =+ 5i2؊lhBpZҏo;@ QI @\꩘l M~\?NJ\Z?l)3]`//[Y[uvbD_DQ0IT,T !"ȇIdw{q/ˀ3$,dJ-࣬[K,hMp<o),Ƿ^zrw0L[X#-:>K (jkN.0~4$/$ ksŊA^0T1#Y$08δՃiU!x R^ y!CLz$,4?6!#$psRFX6*s- p!C_)fvWi9WaFDRI,;6>ծk}XU4pS7ldBݺ,p*émˇ>;6y 1/WsѾj 6*ݦDpUOQlBIB_D$ @2hp ]L)S aƑI?e ҍˏ0hG+2---8[ZsZF=9܈YV< `$@YPl9k �)34RMy6W`"AN0Qot.rtf]-F̦Oc>+J{((AV"/O;CNjh #:<Li 7Gxf43Dt%f*!W9`Zd,ͤh/ep2e,R$3pT'T鹨$0]ېխ!r@^h!Ǔ>Hz3D34#gm.Qy,Bw@FNHȻ5ѽCcf+=D {|XT�2q7YɕbECҿ݇("oʚ[Kq6 uCh˂- qm9ˠ!/{;dc' mFQJ0vuZOe:\ٙfbhA@3t4rpO{BEɣgꬠb!Ƚ &^w{/!ixX~F w<CDr$e9?ē9PO T $&qG:'ԡ˝$,DB:AQsmſ;Pſ@7XH~$LuD,qڐĄ>$ÿ́ d(i(mʞ~eT LB_~^s?NzpU/ sa(qcM MnT@,Icܤeuz2I,ńh<<ު2 aa9|Ge05{兝jbYhpXV]@vO Jf[ hKdĠsL+rz?ѪkNMyÐC;x <ϵl9;RnS춅/|ejbu7+v'5XtTD KLzM?݁ꂨQU&k)$^8l/Vgtۆ^IWAQNOy4iH9ڞXI9IAC%܎bxޛ\}w~\ˮ#-VH 8l8=-o }C($ mm GT {eJriR~P0LP H$b K")<;g&%k͍qDz��;އ[ bsf?=A_f58~\_ eD<: 8Ʃ;uAӑJr^"'0 aoic`iEA2G{ HsUẗ́@0͚45e;֙ge #J^"W SaF*nZ %#V2K/wj߈!<NE!g?k9Uf{ :\+.v3f x2*Û1HV'+TcK�*U6U/ %K -t`s?Y8ȮFSt(8Rj"Qul�1?3Q -hH6\5{}8nm;+G'|"\#y<W1c(d-'m]z|E!~i[F<vԆvVn间Cӳ}@-g%}BS&-D-lbHC~sႋ l BK =댵e'@aRBW5 ^ᚊ=)h',~&U5tuSD qHM;5GޢZ"ߢShvR/?7�oDU = r"#vy5%658ƱEU 3Jz X -\LDZж2u /l]͆E/ 59v%ݵٔ*_ OݏgfG$yy fo;[BE::HsI%ȑ LSۃS;CVtF\s9I͗aE�|\хB)45pr___S0nuV!謠v@ tIHA)p;cEPB~#חQZ3w2 ~U|DZr+Gh(MKƽvI.-Ozݍ߿a<=<#\oqy`P�YwZJ=aks9!$^=e0;IM\޼Ix|:4LS  ]b:|O# :a"ʷi_k]cYgx(vj?0y*WAhm' &Qd 81 h>yDp ^ޛ>7N6ZaNu9K=,fC3x.h0[59NI#-Pn<ttC~틀,Ch y~[/1bfhm.#8V#3aKH6}QQ)3ǼAw((2#IV;͈�2aߩM:#@a@+zRBƹ8H`F_\tz@e7hǺ@@1u/j 86)˶-+�-1ᔆ}#lLrlVDzssQ8Ә7VN"cmYI 5L=uLًve\]U21AJR ["g �*e&TڍrRq fJgىtx7PvySUZRĂ`%{s6fܪfk> c`�\ŞR[w^Sk›fqFz/.s!?>z0؍8Nné! =Ŕ ;#�>[)@"&фW5W'XņY2yHb+A\.Jgt\XTvi(Md; �=hz(L HOhgz5fT7c^M2 Qrj=mRG-<?Gzآ=l 췍\h1sEZ8 ^X5P-BVA.wZŢjS'I( &3ou8Bfڬp1 g~LأaluIעyk>Մj f&7Prn`GaV[+drA2tޠwB\iս6T㭼ؐBʽJtAeL�C~p; M6dq[Vu@.f.dvؿ4ϸa G'@<딙AT|pxys+I$mBW1;k^N~~f["VIfijyKB%kynBTxRNգc~%{&`!_y,v5)pxz"}:+)fig=}v_gEQ9u�X,)r@`-{q ZlZAg}íi 9x*yR谁[m5=䣤cNUItYF .sׯ;ט?TB&,5&q j"5"Hi 88Y.NqV([ o Zg 0C(ɽ]f' [(SZdNlU!37Oc*t�{k:?qCEߵCC[ط~0T"b?�! Tu{๲{RdVY^& iYg|-!^$%Ψ><()s SF$p*w$K"]ik[u ׿:,a6�A~1x až&ADÊYc0]C@1'J?g<ݴ(oF)5JiގmYWT2&6r-?Xߔ xP̙O`mD=c ݳ|iPU0:g.*-fJ9�Y-r~L 瘗riq?6tyȂq[ -MBxLVUzhі΄٘1?؉ L-$EZ}سsq|T%h h٘7e YOSKd"w,S)5s>E pS!&u{{,% `!j"Yd3J91D!+K3�JoW+ G>!ZOr92@>{U|$JwU IJ*"\]b"淨rqN|9gQZ9wa@l33>AT]ѵ.ʋ ɿ1P`#cN-'2 iF\-s>i$n;p \X#D!b혽/e6#=bj '/{<{%m08o1#.ZfhWCIڙ8u%!zUI] E>sfvN�_j,sB_P yeNt=<L; ٵvs!~ɾ1Y O0M CTx:_FO=㓃`N(&Ms?20Q\bۭ"~67]Hn3}^P1M\H.m3q\>>ޙ.Hr?\,IJTRp6tԖ,\^¹pq30[\Zjk,tK)1A~'EضBąmҁ 4wDoE:QfZ#�(͵o)=TLRISմ9d-и>:Ҭ2xUHudG85G77 'fm5\h�L�?ծ;d^L>y׊2|ʻY,ս= Wp*6=I%Ad?zݹ8t"KH͎uI vOq^+z[pF6p9e|naܧU;Qw,iNJC(OXN|]dC\WAkG]#la,phׄ's8 bA~hVUh:{C:8~ @/L�H}]@ rfտ^ u c>|,GQV2L Bʇ"YߧcӠs>Vg)-\2N3vEJ)$~3^ ZW{ L_m~Üe7يnVfYKK6?XnPF0fowiՁ{3 Բ9M$dzC GC|SGhR@LZdq1߁\;ɝ"lW& ^ʨmg.=F <V5۞8^r*sV\GESU^0C=_"SxkX'qNIV{6 -'aQ(5eD$ |slJ Ri𯸫{Js-+M2U/8>e~p}֚^ۇyQzXh&+|Fʉhҽ%^ :)RB +Xwq,gja )RalJ3˫Gb }Nv~ET*O4µv hpayC.g:ޏq;Y)EDnjK [X3.$3iOR(5/5ue�Xv(u|ɰ ) qxg J((_ʳ~PqjfAB*f.skk`$QOW'WjL Kp.hpdj{x5]<NpoưG :/$:|s M-(]@(R׆gpn.;q']m[#\{ ~ '&kZAa_Yܠ,S.3{a_H-Eao0PQ5 <v?i _Mte">hlqji& أ{·"ϗhݦ5J̵J/&wtN7)a#uYWGIk[n@9# �|vv|U+nT,!ޚ*r*͈ =8s\cfT@[ZK8aջU [P]ZڸǍDKEBD&}m~KZy.zU".Ps݅E˄b H͊>P[]յKt7wD�|rnB]jdxc,^= 8;L zMYl;qn |H#Z>0V FFo:%ФQ}2ZԇbxvDXirWYّieua|_ŀ=+@޻jV4[O`HT3|SK|V7? 9̌N,FS萆ڮC8qP|hc"T8Cys}Re*f 2ƏNotrW0oWs2aF�|ڟ#| IrU+`_EDr0 -ib`qF.D s I  0z۩[a*(_<s4<|".c3_{+pףgVC-Fa^C7bF=&iW}lqۖ xUkR.ZJdNsae۵q# tR"<9[wM#bMԷ7N v~ KB&bR.Zsw!S0YmU'Vwc L+0ʸjGR^O!>2C7yxAUM [#qa|DT)g%<)SӱZ}|-<<bf œB ѿo/kV\0. ^?0kK׆(rS$βfQ>M \ܟt<21B0Т|ĨA; c^RJl/d-pF?�t=̜XvD�f3(xvOl�z سb-ws*!("m!RLG]Od$Ӵm{CN$b;ꨑV魚MßQ@r?9gi9'P˦Z\\t{9O^){e >yĜHkk ^+#*!i0ҴHUe}B][aCqΣ֐F HՂD,ټ~:^'֚fgDX*hY$4pfRӴ*'!vOz'C^FnF.II}+FMaE6x.-t6 @"T w49QB  -Fi8Gd9rf[@V#;c\֚ L[ FAj,i-8D"T=: wP?Dc'v Kb}`(oJq#4y߿FTl [k9djvz@HT >Ὓb�ZL3)y|/WC_WB::mdc 8W֩7˺;Υܱ 6ޞRL"-` SLq&Et/MבּUp67OIH*\#~Y7o>z#R$pu o^IN@ne`#ࠆN=X=A'kj|hH0z2UPT}ʆ% E0BBg!xp0xɓ%z3A߸փ6(^)@ dS#_l$DLhWU>w*\Ys܀bƗi~i9JE7\M9Tc+;gO\p\Ff lKYGide觲uʔ0ji!~1؟7]fυbС?_ezuX^sO3RM)r'|:ݜsFɽ!T̢Fe'O%熧ئ 9\M !ƾ::i 7c?f{]My._ύpP .D6)1zRgvٰvGZlA%R&Eb)<:Ӡo紨!yWߔ9iä] �<<>LOSRt~& °#,̐}q8|'v \[Ȳ,$P#還p|"˗7d}n]ES=.y7]?JvsM';D(}^IE8<LA�l!L}|\&Zg戽qXX<qJwyu.& |�+m9ʀZiWkP@*5['T,D>#&rJMFunqnp5ҩ6[5`! fzNνRx{=nM rҿE/_7J�+6 `-!=Ưt˰Ae:M�Z1TbN=cl81^VZNp!]V;P �YHoM;)"[JuŻdIU$1I Eb@=xTN7I{aɉ6`_w<lz- njI(1]D ÆQ8q_.f1ބ}/ ~%>0cޓ`i{q| =+%]¥i,"JǪzWǕ!p]QoѲQjXc, 3d_@$ t@۞ۊ !ּ -+iYʮm̗4|y%(>o.G6SU=x.SS( F|s5OӕDVk..?Q$y#w Fb ^cYG#ε+)rle]OO �sɛ¼w0Ò<L]zЖXn[.؃a/J!&1#iM^Z-tbV9 {@ЩP÷ع71n8a-Y+ V4UaIt?zp&;k8+aHfށ&t`r;hNY=ˏtxgJ,&]fHyoS!?9, S7ē5TuO}v;^;n.#f-^za C %})l1I{<ђP0?eT;݊mL_r=#aMz 0ua"Ƶ(Mfۦ E,/r,w%lNjڮ*膉ٲR]ZR*12piXݘy}xYzI{疏|)]nRX/� w)Q2o�ft�9vJ2iQzؙQ`Kˮaʅ$@inDSQO=PņuPcէx!Bx\moՋ^`;rE3u nBD-RΙC3-W#](3oCfAب"'\.!z;T)&"v]$|Ƨ{ (87"zŠezW}M.xZ26=]&0wxo$VJGɥKjx&XX U1jH=Nʝ�_,~bц�PQ<;]0\bh} h!E`-?de-4Y*uCo@DV@ h<_$3Ư)lC$}Kj1V28w_8**bL-赈3{ 1 :j^t h!.Px|N?@. (Zˆ$c$} ZE1B ?$+ ZT.-QW\ps[ڦ)MrM d BDL Y7-u?<wjŒ$~D%ljlK 54zW+ȕuBv{ �0Q &`{'6Rr. +&Y/ d +qL_S%qcܧF\aM3DD?'R!V"^7'P?t&zkEcVFfSWhݥ^ICBJ'u=Yй�,h|ߋt`STɎTxuFb3. Xʦk]I_p.^*/ES\>TO ۴GcBG<}u'am ZU=` K6'FG'>yF{e_ u_*Ɇ${=薉k g�kakˈ,?}JYx8ZeA�V|^^P(O&y HYw'=~ą^P 1RevۨseHO_iYOO\#,fu  FLyl$ŬԠxU= &r;겛/tVXQ6{F^ҙۓtK,f&ɠj$RU,II܈A+-nbL%O =u)pl_^`/K"A? ӊoj9hA-u"#V,usۓ0'u!E�*؊%{я ;(�A{w}CɎ}d3�VO-NuK&6A?GՅU(hHx®)!H&8Y{xxe);� $BaU't)aׂr�u*Bw)AQ'_MF7@gцUP^ Te6kE3I l77Qz"Y/8-|Nؘ!"qe_y ywbF%!]h6Y. DC/q=h(}iU2HfB35#5;$p- 皵_<H깥0S![Y#Uw�K!VWCTfNl~bI -E[=վx!IwIu{ [*@j61@{Updx*|]Z=T=gO퐸4Ԧsl.~ga2e?+3Jv5S =-}X„xk)pˢϕ-'m%{Kr @> $^BEbaQ(gNr2 As|6I[h= ]rcttƾ6$i[Cђw{=EYk  XKfE3}X<`@)4_&'$)-}v+zPq�S%"[e4)EX3q" :e.-3V+ݥ|ˎKIta,_a{34y5sDXɼ<Y8lXit[(0ƹ17RF7Jt{_{58,`ЫO53{e (G(8F]ɔO.{w =|Q)R6 KliGk;s%2ET?-ђP1aw ]1p('@sV%D&,V>ƗfV9;2~ Wa2<,gHZB@FWR{'u~Zg{5 H5MI>svQ΂`e#(N.x N{ymGk~>K5&Bh&IOJG̕’yh ܂3DU+OU.-ۻ1]ԫFƒh͋guɂ2~~b3yj\'Nە&֦\EzG]c5*@[N+X|!;,)uVd*3 rX\A#%< W귀Z*rsp+Pä<4`X#mID =u8CN[2k:23 A64M CF$93ˆ1rJ̩#}gj2Z1+J-l �~_֜yuB/XAu9u6ZNGK+)?C3[E>LɸX sq x,I6UWDxD\38TЌWL:gj͛Hi|QnH*@քv8|3v5hረ\`[|+F"ALB-y޳Ħʕt#�.boZ }E3#ād1i 8XH5~ݍcK}bk UkKGb V)בO6B*G omu5V4{>gTK#ˆU3�'JU7 ^\*s[*Pe;Tv =ZY\x7,҉ώH$:~HCq!(=1U;{:؀XZJƳ8&y~a{On!YTE# 8k2%q[tF<r8VT5mF[▘ Ŗ[SCні+U 9t{UcVjEj O+2w(40- 62tPit�8Rx<W;O#}=š ȷi@ډP{?)dc hG%,dr&dzt$~lp}A7R~ )ʑC(81 "qۻk .u*|O| # !/ɑ KaH~&%'?is QJ5#^(glD b5P_bH 49ɋ7m[J򚬹KSPM*FeRUS3jwς#Q$QdF5jF O>*�8Q. MEm[YX`C^"TG;)o2bMPP&u_=RnI9U^Hn/^R6&aj ;DCD=HW3`/ʴJ?ҥ'wwMl:C?SUQVo1݌F=f#z~=]'p9ZO_m!Ux+A.Ѯ5..pFo}; y祾W:)uիB-c6X =F!F($! a`¬ lH꞉d\/F Vf:FFD uY D+L@jɐ=se(/jYGΩ l<I=P,y$QѥU;؉ItݱOf&G8h,rP,(@IIp1X8&imb\o{T1kXEi<̌Ud 3{y\MÈ<y" @:o[rK)И^VՎ=^J2盈ᘞGLUU_9:S4FXdRsyPEb<' @j),91m3of:CXZQpW%k pSF9n�Uan1wX"7c n~8jaKk$N�_bU)S}l#ǣ,|bulgMl떳g%Wљg^=)`In5nmf岆7hS{{�_J| d2K8W].I<w_mDѴșY S.su٦UFuua8z:* /ipZx1AE[ $T4[IKC_W!?]]EgK_IK105 \f@Θ.^T~C*\ӈOށ&{ 7/fҿV�|6Ui(էB/LtJ!݌$0~Ȣ{>IO3fn7q]PhcŭM39omǯ;IZg؋2ZwP=}k)-S<9vea~[ >.f;b QOnAE>D- 3+Vh}ЋQ*@$J]|R fJ8ɺ@"%w*Pr<ic3CG߿t~:C-iŀ(/@)- ,zu֧Sһ :_"sPc50BڿXx[}'HIBDI v֯u._֍w++?P�~(O3:kcKj(Bx&I:;#g a9xmo^."e{o+_;}ry7(@ M.u0(][| M?htVAL`K͊8lK٘8\05Tע iw�W`c.m8%D Jabʯ "1œp3 ;lS+D�]J12~h=x̻O/pM>ۋ>s8W4/:4EϨҳ`2`眲V}Xҭ @9! q1JAg*.ع)Y RX}0�홆 &5? puB]BAz؏ {Oܕ;˘5OxF:rhndvk�K|\  X{ޘݟmO Ҍ*H{/6@H Q whgݠ9znkDmk³\pk�N4eRx^XỘREm,u|/\q S] .؇h赗v| -Xd|z#FCfI\"+(Xƿ /Hz,N'Qm\`rњޖťK nU7?\\lEP8'}:}r2ǴL]$-=(rc߾f74'D }@̪@Ϫ;x,2>8<tf`$2)9i-g[ Zr2ٸp!?<EURHeBZm&з5 ݣ\ehs]bUjs$ 4}mHV[1>+j3<9Ĺ+7md iM (S!h<bm6NKog3"Ոsm5(ۯdTs>N!R ՂH]U6_;)lp/&R" #gs(iY+1@ +<x'02t0c̳JMm@[L/kOU2j$-{A:4f\]FmhuOϻ8+r*!pytN֡}<l.G0]ՊI6<nYC) j;wZpr5'x.e9ioC`XCh%;Y@I`)*Mo$J07U6:'Ǫ'UqMxg~PuNg!^"~/yN(3k5VD[_kÕB]q- 4>kq��be؟@o|V#X)q7ǜCX;"zQ-5€X© Ofm=b6)4ߟs*r}T"N h{3,^N +f1X#?NBƲFH8uZU#^<(-3 e}65*HMt8lSANRIU�jg.ߢ:{sҍI'fsA9m3ӬG;dk#k8a8}㻧ӧ_3}:ꎌxh1� zi`BR}{�RωA&vVjOTrD7*l&r5|8=:2āA'M%۵f==)9d{^&qepc Gm>gљ\Lp89zЊpRі~r1LO{Z@)t<i hl}yYU 5�?`jliT9L?(t -61< 8XHxK90xƬ[Z#%d=aA<\wK�)&he¿&gSJ& x>6,B\hQcu߄¢1(` S^ G1Ӑ8 .N;f#X"gnS<u[6_l5jA}YʜeAw9L~/"K?HJKk** G!W|Kzcu<yВ8Rzdnُ,jJƶ~D1q@pNܼoK"4Á;!q:zr1m, %l;K'kba3F2Y-?N2p �1ɈuWٹ0*?~\}kAcnɾU#Ŕ^%5x͵$r͕DPEFDGρn6r]F]ʹK|yTH0,(= ݢ#Ow(V+ \́q}t 4 PE(q$ɡu.!}))3יgi6,cb-M&U w<̪ZO&E#nyd&lyFs 1ëu?zD`T]EV"9QfIg4 紟$U'4qpH4(i8iDz'3~|+!`kBp \ Sf*qK9=XC*ֵo;U|'z%ÕEw0宂DEǧH"K4B\h=A FeS&ۏj,#fds.kX' kxB@eܽd|M3f*=߲z!y=Sj5Cw*h :8j[F'ר"QRZXrjE',Ms5Hhl)uj HYNC.-4F,-YNmae/({8n-TBaS}%]n)Sy.<\ m~bn<M!yQu/M 78dž9�T1Ùo4CNiSw 8yAãjkm"0lc]Cf)4{yh?S"Q/sg+MM<]sOܝ,+Ճ,n\Yh е!cy)@*Bw#|Ti. 5ߘ^귺Pjc= ezf/XP^Oy۶ݵifwQ'RL%%D<mv�D/c 5v4V: asˌ!C0!WgPgǥG} rS=NΈG_~ԥ+SK6%O,=R 4w ܥSJB5_6Z7X[7VLũYč>buz?~Av%s5Aw6=wϤgR@zx^?[W)gae~D <0?.pyWŽdMK Vf�@ 6CO]eU. 0P9JU q[D+x^9,)̧J5}8g.ۅ;nK'*-EM!+8g];0:gFfQ{hЙ6SU c#␳CZ LHo�rkEeEp&2!f$/Ez V^_[6Swp뷔�2UkWQ[. C,_wcY񵉝 Ţq;F›bxOAƦቀy]jgT�U 'i4Fj3BO' q6a#$O@/Lgc.aBY(n`aܔ:ܡzCsْ^1I:VK͏JgUo m 'C8X< #{6ZϺ$R,v Ԉ:Ta*dR\xF-Oٗ:VMnB8Q_9HN9Tr'].s{e,qzf /ʃ°<*s kD6Ƅo+Cc$p3݋h&hKE˟ PVN;IhG彜ls|6*/j+.EWkoXX+(�"=7s!jܭ+(J2 S i էsɷ0Y i#6*N\ՁF`ýn@Ko.rGH)mћf,n&/cr͖ yjKB E}/Ҽz}0enB8skɘmܷf`W-n>,ԩA>kW1U Vi+*<cM>V`긥̩.!ySh3(!h߮EdeE ՅFS5W$lֲ"PuECڸ1j _LyIYTZD|^ R%J;/D B9u�=uF}h&{@H ueqW4[+�ݾ'KT'TOq-5a-zAdheJ"݃/~mc Vpc^ق\M''~E#Pwa -2!wMS^-)>PMWꥶc&`Z.k@/Zˁ\�$!=Z+Cxb73AbzݏϖBCEj3}u@ڃ@&^58n@/cդ\%.񻹡$؞=wdL*b@[L4nGo\ҰY7ʂ+`tva&Q=! l;э*"bSסԭJܼv߀N7CȒlׄ�vX2/1 gfh&ŬWVt] .q)>W0ET/#As69u͝<ˣ^T �0[n_XMญ]<dZuwhdNKQ�PY+x#Fe+a vQOl>ekh^$b4iE7C9+"y|֜=ټTu`>?ço;eDl hH9 az]/_sJfS%7eH(=/BKc{ݽI=>۱zn*=r4s {iѭ~g˗<s1^>櫩q_x(s|]hLP[5[5~޳)b]X?: |s<f$,{7eԏ0 |=R[4�<ݖ*:X݊=!,"1Y r;={E"B1ƹFBhFǞ۩h/RPvJ$BPr(PxqN~"=j' |r\}O:ѵwXΕܼ.]Oe:~w~#"32k MMԬjӮpi?V{mſ'm eDnK8J݂qI7ee_̻Um?}|, m pN m4*�9/Bř(ӎf\]Y,r\L*d<9g+5>q}jTF�eYnP:FHgDv5lTZۤ]06,簂̤N?bhS:Pc^褼JM(1't8~A^{Oe`O HW 열R0S爢\"&{JgvrseU54LF/� irk€^Ѱ }{ls.E<wҊj�Ӟ0k~D*z7@4"ʏ ;D 2|= )WWg3΋Qz7JUWa଎ 5\WjyۣY3NNFV˚ Y`uc+95@!,m}#.>N"L$myw#FmD]%^{#3KKIV[ :GjȄ9#ӏmoRf՚R³E{D"忾LѢW7aQ#R#7o:Cn^ :9OMXz?vxs%K*E 9'0[Dփ=g:_ gjt.2Ǫd`-3Ѥy2ZV߈3`税]IĒNǙ*Px۩~ǩ,L4`Gq4S,]?v ƒxen:< FR o=\)_p~qV}#rm\1_lO Pg_VAGHp?GGM2۹ئ=&�8o{-xx3"Ď.`ZqMէr8WmϦFVWt{k=P iMj*6{6`<4?#\\WS.'T7*g/"C/-?&-eZC~ЗyW!{Ev1‘,2_\lb<3mlȝE{Mnӧuf,@{ӂA<pQM*Yz41tR>\|eٮ#2e;aҎk0Mx5TPR%.z:dXXjQWMbh3hAd,Ж&qǘ< _g_`ӟ$τ]T,Fi.f'EQIJo\Z/]6]$͢vH($҇r ^u9[[Z.8 ;3 $iOW}P\Y4>*Nh6_%L-#+s>F 'x{upxL2`I "dLC v NvVZ=TZx.g\<@f2s-'Hk ܐL3x!f]Sfyg]{5Sm%aղ4 T_ !@;w%<25N}K+I;v#0H9ԵaaW@X9╜eE&d xź'e\H7+fa3h78H,.tv{>G<kk(< + Ɉ )5)5/@=A\MiG#lUr 4COh==#(Ζf Aw鞤u ZE2;}k:":{Z΅:މEhe-usHGTNj.b t'ѐuz8,A=ZN"*]IGr7bHD_U1-,ICU GѼ0֠xME`ПPJ-O:z̾?8ЫqnQ`i<D+C -2 1 TĈm`w=U}gv1f .#j`o4C:a9EUūlۼ@u' WC:>5|C<5IMY-qI&Z.v4:'s_2UPZ3 -̋s_ekI{uܓ 229~#1!(>#/# C`92j-?r=K't{)]B-B$49Ǣc6q[v׵ 4':{bKZ<N.ڱiZ,r>e G f P/B Ĭ> !R,goR \78 �RqMa'7ז;jr<o+9=چkL'o ?L.}TV?1H6 ~t9u2> f\` 9ŷB"{:F8Fro᱆m!0b�eVNJm7M]yXT t*X2< . WR3j/e} _cM+#[> =ޢ1RK9/%:fDyZ'Nw!0SLT-o`Ʉb- s,.z-! ZRt$9v^t31i7wnޓvd—+Vl }ikQt DlR!v5-RWB%W80�#уU dU <Jn. K-Y5ƴ&%$A\E�nS47ިM;/+Z7 pplx"YR$'ͭ"--R7>Ʉ5k/Gha#͎ xd>tT D=`jeG[t]0%]D)V`z8UyW|Υ|X".N7|WP7BS�\O6gQH[Ya[ ?bO )I8>t_NJ9. CһWбo !pvxPNӫ|i`|%#Q%E~0X.2."Ț,ܯD 7M⩧s ԟU;)`җfvR*/_MVq}*piȤ- Jk> r¶7fz14{@n\z@>>SV5D}To,j{PV4E y0H~7vr*8s�skHjG.LF/2Gxl{MkgN\qLy']D>sY4N,'M UWQnf.8O|0J:lNdMgڤ!B ([ltlq{t|&LQC^=BXiiƽ/i2`_prV`>]Hd$ #:Yۅcѵr]D&/'rt2?2Wo.Tq8P ?wY^zJːLv_Gݶ3*vT։o!X2T%wq  Ĥh@HC ͈/eB?F>ݧp{m5@Fak+؝f`4Р2TM`C>@~�Gxήq9p]ZXEХN69ȁJҙeM$>&G@s~Za7oxc{ \ 5]/N{j{v_f ~m�q 9AP}Ou/ta |eEG'E %`έUhV:8Q}j߆W.uIm+8}3Cp5VatJ}Ȏ<! /7=}7#pdh~3C4t Zf&qDM7:ZJ+ T@wVʆ%qq-?BN Y7* j!`}p6ӛdiu[ LTrc̓c }0/,JUBΣ{G  ~'ٝ3RA%sZ!Xo~bG3$zo=Fq1U T މ 啫L֪MeX)r^t,.$SexZ[*p]zTFԀ <}6 ׼KN!T$UF.ִ!A̢ܨAԼr*v�{kqGYp[cmҘ& \Shi0[v!z%*5 :dd.1m%"ug(i#!^pĴ)@]P5?]2%f;wif%K/.[#u"2} zWLqQ3CY 7iP1"2LG0|-\*%)B1ڄ"E"R%eUqcViyZ@ꖦX捸!@ȏo'gS=u:%;LR/4G)_n9kş/SeڍĴ!͒A>ġ5yUnԤ0>ZK*Qw@CNR$5_$$S$E,Z})AvhU j6R돶+)yCi{VzYbCN=^G*(ĺMQC! RPrCK,~Mv"viT^.>bMsB0<isE1�+ TʯFܒof8!U>"`-  ⷚQ b*ޣz3*r5"qu;(~L DHLy9Fz#9iviWMqF&7gTdYĚ5dM ԫ|*5p?9h B}ȫ75:EYu30Yp*}0"qDljnSE3N)N`y`R=}죠E,H͕`oq +]t,)@ \|h2Pi7["{;mG3#inXNCk  Odѩ0]3@Z31BʰٓnT jo&«p+he��{3xz"^W|zQPrx[!ޞ3{-WdNԾV6yp'<p?OMYUd](7`D 2"Espu3yX$mIus">,h(mM?~><&'^JVpmFnt{W.l0?Ix>ͭZ_]g$�QS@#ƍ9O c:uFAiAR}t4 }FT]B7Kl`@2N۰9@G[\1<P�1hp3"]=ʷƁ#|tOg-p?/NSXkYU{*\u8_!GtJ5ji.V&Wr] i10,- @*6oCnf+*>f]R$<o?kĊp[{g{VW w[�?^U_Ukt;ővR 6djhq.TdH{YCAdaV)ʰWr2UF(M'~/6 OА3olo>(Xx\9w9ruKoQQ/ |@B-W' lȇ@YYf>FI G$Bgs tD,&CFfsa } a<ajF bO`x_. !$OƌOm9_Y6 ;8 & I/BBҙ~:X7}R63α<4QGQ|E~\!<!L1ױb"[>^Z;<CbbFΙ/r %o02H>9J)-]S\?Kw|Ml2Z/⑛SmlA ^u5 U_Y͓INuNq7YXyJ. ʷ/_hM1)LJ,n#(兇;١KAvIkP5"ᗔ�Kօm=:>#n`lQW1_oVGr覆%mh& ĕ]pA5L!/eov,6W`͛EјGH} j6U؛mApyT]kui=fva7(`4s ڞ)B|:xϜP{-:Uki=m3@+?*Ӕ;H򱟀V<^ns b7w#2%{`䚈).ꥥ97\4pns>RO8M Iwezvq zQG`e.E4vP([ Vz̞H/rZ"/_niW^=TJ9VҍX=<I@_wgbH@`DXՎF'*;LU>WL}JLI҇4;ѩ<6fWAoxL8BA@ZkIFb.e$=%Oa^ද^Hx�<D |mX\&ӊb G�mPħeN>h:˟K G9jO5Nlw@ 訉rqqoi7<Xцy6A rPZ2_CzW`"iVhmTٰGH0Br?ST5{WfߴpqS_؉aL@^p"=3<7`ctA%HB( 0~U9$<CNEv]$c؞"Nd󉏚kkh<D_6Z{^R90\ I~6tӁXSk=@z>ᔶ&\5 NnCUۭb{*=LD ^Ө4ҭF(`L,!q *Hk2G5㦩C䉳;ga 15==?R#]rEaf !GZV7@8{yn�]dpF/#&9"R \M;юKW[sVkP5 I`&A݉In :Ѯn$[~n>Y)Ԍ&mqiA˛|kgvh&u+lō]�JV +[ܸhF%>"c1ȜVlzM34>-W9޵Ώ~лve~#}@7ؗx%ԓTԭaQ`pu+=wWL<1Z0ãB;5hA@=+L4G(Ȱ; Mw t&t>@| L : ߸ yίe>gH<":V%>Y@S`?7a ;wl6azm9sɈB?V�# >cozBr|yf{w1 ,=Vog](ڣٍԜ}I|;!f!+nZiѬs2v7 Nɾ. aJX?bؿ43%9Ó;k5Mů+mw</<9QᶤBzk-uܚZj, �~&Wڞbq6ty0ᄧ@dg0Z\G;n50JW|.Ҝ+vŽc8?Plf$;(0gW9D{_?F"<S!p̍(d|P/}K);Iq%hߢ/Y<K1N'7̾x 9qgob{v!<&4< Z*}|JQ|Cd�Gܮ`b4T˭`"kKJ+;PP&ip)7$J߮4p񯂳0FӞʘ>;̸9$7R+6.(금a:4gp_t<#zɿ3mƄCu]N+42o%S4%=Vᵵ$s8p0,fZ_P>?f$ +ԃ:y u0Z1L&CX>Js4S-GO)M˗#Z{'|r [[:5w^+/5P '7".Ǘ|X"ucA"nV kI zMLj"TN8.'$4jϜXa ?|wl9Xl1RU=)LڎG gɗHҤU{|SRO{Y > J>YuFMʃ,gm{ �,uqvm<i@: 2<%":1)yhaG+_`})D z>'(H -'YԗJP4F\dyD2(iupRy|R/ @2$/s*/тg0 {0u)w>NOq쓽QMMdH"7I8䆹?2y_srbz >w$?AαiuDyKD cOz H܌о?lT7#X7$)Adr?'l$0+zF||fP?;"g2B~X oԊJN�6.}k4+ٖS*ѴFMEm(J3JV(/VL/F܋+€Pdߎ/xYN 3sx#p&gy9!8lq^R;IB.Xs~hECݔёYVQK)\$m yfC|/ՊcG.�h$[w5F[:{"?Mm̃I:t"R02M[MrCt{2zQ\)t^]Uc'*qɄE?ldQ8|V#󐙥V8he'm}@Ɋ>qڂ*:#ܗ-6b{*̠o-dH򅁤AY!ִykRbq$- IJ=(fWD ! "ŘؑmD:Q$q+ \T"E@T\/M1+b'*LsrC4NcsXڂe5XA=vf쬊N qh ᚱߊfjXNm2e]y+2Ü,-wؙWˌ@ Z㱚"h�^,A+nͬ |wam|7w0_](2ЊanCiWnWmz>5p|G(hxPf)ld^W?h2\$j9ᄶ/�l(y(F0 $\o70'̚*R6t@hA]ra-|K B oGO3piW-IT$㥷 l4_LA.6cfh!w/"zCIu3PyށE$Qmh |�,h&pIw[KTp0,4r״G{wo74 S$U7Nq hMw"Ӌa_9(M. ]cBS`˟g")hK?lLpZ: >=MU`Un5m./ c950>|B屧9iR5g)olI .\_`^ ro߭OޞnwnN4Eޏ(a˪HL S=@d:ݘv#z̲lp"WNK)B&dٹ@'ْ$<r^d5�uh,Ý=UU?{t/+KXJAT%@-"7.cS2'|(yPfijJ!?W^n;x J֝@{pM EWox:~kEh]zlmJ} PlvjKvWmaDz6);cԳֿ䣃QDV"{d]i0CFlR8]?U(ZiFq i[x]%I-dLZ}|b)qr>aiSmRtdD+2[ɭ5_k 7PCAۮyO3^vۿ"nXs0a9_ FkWvC'lެ%ŖϵDg$jMHSE*`8w"\5~{VU�ŚLdn7Yp AČ'! N=~ͅf7j[c܌?;W8,aaqj}9 ?Nވ>m3kM`zא#6]!#˦\>9}Qޞ)𢂦pxn<+i%=qx$;�rȏVlM+1W/x%hZ<֨ҙ~n_ONt$R?oWlryZQwW?ymf$m2_a1߬$_&st5ڤ1]b 3�5y]>j%SnRMY-N߶(J叭v?6sPF^61 rlY|\iM+v]snK:OC\[aLyN Xl+ˑxBKG%qW h Ė-[BRAB~,>xYUrO!c68좸гFYk03ٲh8P#vSU#~ KVfOuM)i$O8luF!YI2_0~8KD_$bXtqV(U?;mY#h $QC-ǵ3<5~/ٓf-ڱ=,#3F{kN`UE>eٰE@8| D[\4V>Q-ϓXƾPVV@,84|Z r]޻`*E"@kCk� 쒇67yÔv.kL}*)oNߌtR#ԕHt1K+,+؂`'/;2�Ƨ)a=8QmzN}#׎&D7Ry7|[eZvh-^DXTRRXuLTyؑW/h̀{"5na)MPs[X)64 `o^|t)\ P˔ $P5&2FQl2& < l?!Н3Q^)?3&#Ewu8҇6AUhrL %#9t"A~4" 6ؽp"$�zȸ˶"0"`4`3;ˆZXw]Lf t<2ř>,Ġb+CN[,J7#1jꐼG:_aQPMޯ{2BMQFP:#eC FM+^TXxdu{I3?"M&[؜J8r( $9/gpzɔd/F6e9CK]}`UW 껴:Mi?yT^<djաn@7v?YW n{gظ 4aN�+#vBY} cѬl3 ,puJ۪D3an`₰YϩL{Bѱ7.Te)@(7�Q6훎�7[V,Rm�j6%SຮuʟuQ; n4P5b*߀~xz� 5d NfPؤzݰF~[+sG#IDomoAQ^J8g#G.4zk/h0>(2ð^!|D${_ CŜ 7 1ēESyY '^6΅i5)")W%&|# Ԃ= 0Wb*.A9YH0Ce CZv8SK#/Y+xʼ|$s6` 1=[jܳS+/N$"=fSoT/{]!W7mT?9YT%<267:opZB}LhF##7c߅3ҙ{$hZy /u|9WT|}*t۳T9�\܉{H)fAxtpoy$SADi|IF#f7|^C`;Zj8"Xrac8QkT<([!S9hz%_VS]Wi g\P.JژpQyQ:Jg7:>ڒxsl4?#N~rkzk,o|yZ7ZjRmhƟt3t2fLYQ?g|U(Oˆ,xkj:hB%,мpbsW'[LudjV/u|d2^#*{n9K%פڒ|jwO=zduyu�Tmwtک�⤧le8X6D L]pHJ貗Śrw zH$)Tׯ\ZWUohMc暍7K ~6ˑG*pqNAT<Kl{rO3K\ {f=[KcKcu|ǎU^;ena.ČASLdGgy_V֎2 i#R�#k�`i}ݞ)VAteDl)X̰-RoYe@un Q"T<to<9'- {jTSf,L퇤D"D(T̨BkJrL:q }HWz@pdXv�Eq(LDT#Uеb@AvwYpoi G2r%֮r9\C ݨzmEi6;PqœV,ł4,�e&N |yW-@ /&/S@&А)uŸ [R4CmʈQb)v݂:<SL"'"Ԑq>@b<󷂦bilRءIgH<$yϬt@hLhl v:�{ո`v.t.|5> ŻqZcq*UƾГ 褆Q΃5Q`̆mgVKG#œ$< TKP BJ.l=Υ2suB 'Q$˻(MZdal$G,c;p 2j}P,�,gb,G~`'EH* U)rإɽf YX-4^kr{ΖtI6ص@, $MjLHE~jrƀM?OA->I:CeM4-È៽ֳi-$a~IJsoσo "sGcmOJ5JzbyrJ\}CC-]{Oܼ.& ‹F@}]"aJ2ig0O9~YԊqe!M%]6 Vo5ci YqӜ ){%J#2�YzlG[$4m X$DMe 7 b xdss3DJVwu8sCxz'3$;~7EvEl!^Myt/o=2W?j[c3\Hx;5]Riރ?A>A\qp5Z`9VgILJx~;AfcO k0G(d"r/sTOin MCsY#O #ϰVJrM~@0:63~2e%9Taf̅e&r~gVGae%wڨv)kT?{Qr[k{&Ps[ݹ+u'Ł��@9R  GgYۀ|\UL~x gLmevcx'偀Bd1(el4#w {9öܻ}bf 8j#PRNW�Fx^k?ԬM!J<S�A觼 #6(`1an+Awt֒8= /.8hړA8b)N"`D^DCa[MZlk \a\֢—r0R&C+2D; X!q kz({{s-})_a#3iQ(^<9idkvwїMj~<y\NlGPp'�]%'^?B_لTWxH.q9zV,R<VEIq3 lsk 'wDej 0 ~SNw%?fIXJ*tQYSj/q}u=6wUF$Q3+Ph>�2VT]L}vzm_ D ,tg*Zӛh\5;*|g<Nw E:Ծk s&uv_ڍrV}/o-ib*kDSؘ6jn}Mi] O(Es6B3 HB`t['8D]Aݎ<ʆL.j/Cݽaջ<�i%ު vp鸰c2o6>ӈeD~]t#3C\@Ǥ%>L쭷1ԀLdWg~2 8"4 wxW]}5E壡Q3=HHR|-+ߣ7 Z'Q{5%N$9:߳fSWT(»zD#A(Sv  <MQ5S1xK'z _\pdw/(/bkr0I i:.KcNP3`Łsl^tlj[kT_)}6(%X&#8f;?/ 7TX):d|GLx%4X#]cT8Kݯ||%G٘SrF3P jԾA'rHfťU1x--YVo7>V�"V nN҄]O$jt@2+gFPvx.1:0\tD&`N f|i0, WQ6ww5hGJ*w)Q?Կ=(p~b_}uFMK>3#)"xG{9| @-~L=\D/=\2XEe.C(|Lgx&D+"AP@RK'vlO!"@jx"H2ƧiF#\r]Yv9^fcow#^ܒqchg׸B3klGܟf7,@S5UP%ymWо,IQ4ztTO% E |#X7Cji5vUv(>7'[1i 81qxuɰT(vN`p$F꧄iGnͯϢ5렦>/t<z>;` X&Rjk7ǣ@0{DL\pYP4tug-i[cٿcfH~.x=5ԇ�#@Khya7(kT\B0\3Ft0嬩TIި)>yYd$77^c]9{E$`=Yޢ%Ac#ėKHCşr@y(3-ڦN6Q>\K$N`Gx~x=kvv髉[Q+sP y|1п%20NvEB9H3qp,!/yk:P]uP¤ ŧ)I;"G>ҌᄞTSg  .|o9Wjz }HtwMDaE:$F IՇ4B/:1RE,3#uʗ3|uV w)IGZ,8 *.$BSg۰јഉqڞTiX'Y \^#K=N/͞E mɞQ˛X[RA^IAuY$m瓎]bkHj p(mCԺ\3E^䢔\L$؋ʣܑF2ʹ`[<>!F׾|b%3ri:Ҡ;3bG{G0 6$Ьxsf@2e(YX5Ua@+ $U#9?m<}t7gMϯɆĚ=o:9lFQOM7Q ӨV  6j tzJJ 0z1ZJ<gu3VH[ӭҦ4\0ϱק):^&N4n"(3Pd;Qh`TnYa!<w DCc*�fv~b @#+{Ut͵X1ԃ׎-wDK 310:srC&1nd>d\XeC^XnŌ/OB| 9o˪f&! .t|?CB$Ǒ*,xkR;Pr5CJ%iK _7#-5? L4qaΎ9ta(447x;'t˦ףW{>{Ua@Q!f9#@O }LcMjj:/B.cnL)5^ UiReTG)yI0aZuF*ila(Ȣ:8Z\:<lGn1>*(]"h@`�~ZW/h,׀/4dưu�bCڕG\v&L`d�ouk? ʙE%eRpQyN�Ox<spY8Ň bǰUXu4gu#&nh yNZRN(NUfeǡ*CuKj4m߬BkphIwJy >-Be,$[3x]5&8A<;:+rN&7<Z}l<;dZP$jy,Fkg$b 9T) O<_u`�`V d{RDڡIж"펏T9JHjV}T(Q/kZӭ ҙOVT?L{+%r,Aύ2B B}ҷ1ʉA0"ZL\ɽvTAyxO 〣%AU4*nNCeޥY"sd -g0?5\$+ U낖Oش7 ^IԾL:ެ^Z%wQek޸P iM>B%~7]n7KO<KA 4<k?36A?~[vf{XOQ ;h0trIyV%j2"LRK.퇫z`mQ4 Ӎ/v(fOAsPۂ+PImX\q^^y@j:7F?%՞-FI`:P\A]ُiXU(G ^]rYKsBjTދ:Th�_I*~c IJ1Φrq>uFVd gU7�;iwQZ6*Q f 9: 6(Pu rq w/Eܶ٘C,~'r~ gkc%p5y=hUFq/Oa_;釉}` 85ekD߬yL`_mnjnD[jP Nm3_W_1AI >ӽ]uH�0mC7sEohO,]uc390h,T: egqŞb7zY%2j&ݖ,_kXm0@w`ռ\b*]2GLh""!$HW? enmGhAk,0`krS{MZ\A#Px:kD}Ȅm}D'C[Ny4EE-Dwe�mHFOXݜBb#Uc٦|r燨M`ig+M{BGo-cR,'hiX=tt .> ˎ"dfW ba Y+-RslDj6]WխHJوV"-?kar\|mEz[+JuR>'eV`4Ǩ nЗ3r- <҅&K^SY`)v'EُVw B� = qn)aExҍ](,Ҳ#(C z,}rã8K1hA%Q0ba:|&08?k>۾:%fQC-ԅSZ[Q @ryPR/7[{ g`�".qɘJ>k@dzVWI,;N}dwJy0 lHy!s=N,L7!S068JlVҠzm5ƤZ5;s1!yot!9z9*xnnhOZ_΅Z p5X3qf95ue˧Cgmy]5_Y, |?֨XBP3�]uapD Fx cP sڤ]YSJ6xRtVʮKU9J0+o$M5D0EAw`G5iޤomoT]Ga>}G%m]X|T\<q%ݫx37 xx}@Sr G|}B\+OW'|%V"X&> F *xE,9B~|X@c"2*9g" cDW<!PӫwvKj栈;ͨQ&6)Kld_!0K)P}ѩ/f$F zObYgB12d[O csI& H Dq \?ύoiX 0<J+,RӄD U^�ӷ[?Ws0˅gP]sS B���� uո|x X�Vy g����YZ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/charset/run.sh�������������������������������������������������������������������0000775�0000000�0000000�00000000223�15202323131�0016702�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh if test -z "$CHA" then test -f ../../cha && CHA=../../cha || CHA=cha fi if ! $CHA -Iiso-2022-jp ./x | diff x.expected - then exit 1 fi �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/charset/x������������������������������������������������������������������������0000664�0000000�0000000�00000000002�15202323131�0015724�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������$������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/charset/x.expected���������������������������������������������������������������0000664�0000000�0000000�00000000005�15202323131�0017527�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000�������������������������������������������������������������������������������������������������������������������������������������������������������������������������$ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0014525�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/all.expected������������������������������������������������������������������0000664�0000000�0000000�00000000010�15202323131�0017007�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Success ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/array_proto_at.html�����������������������������������������������������������0000664�0000000�0000000�00000000356�15202323131�0020444�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <div id=x>Fail</div> <script src=asserts.js></script> <script> assert(!![].at); assertEquals([1, 2, 3].at(-2), 2); assertEquals([1, 2, 3].at(-4), undefined); document.getElementById("x").textContent = "Success"; </script> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/asserts.js��������������������������������������������������������������������0000777�0000000�0000000�00000000000�15202323131�0020777�2../asserts.js���������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/base64.html�������������������������������������������������������������������0000664�0000000�0000000�00000003617�15202323131�0016506�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>base64 test</title> <div id=x>Fail</div> <script src=asserts.js></script> <script> const div = document.getElementById("x"); assertEquals(atob(""), ""); assertEquals(atob(" "), ""); assertEquals(atob("YQ"), "a"); assertEquals(atob("YR"), "a"); assertThrows(() => atob("!"), DOMException); assertThrows(() => atob("a"), DOMException); assertThrows(() => atob("aaaaa"), DOMException); assertThrows(() => atob("Aaa=="), DOMException); assertThrows(() => atob("Aaaa=="), DOMException); assertThrows(() => atob("Aaaaa=="), DOMException); assertThrows(() => atob("Aa aaa= = "), DOMException); assertEquals(atob("AAAAAA=="), atob("AAAAAA")); assertEquals(atob("AAAAAA"), atob("A A A A A A")); assertEquals(atob("AAAAAA"), "\u0000\u0000\u0000\u0000"); assertEquals(atob("ABCDEF"), "\u0000\u0010\u0083\u0010"); assertEquals(atob("//////"), "ÿÿÿÿ"); const longa = "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz" + "IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg" + "dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu" + "dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo" + "ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4K"; const longb = "Man is distinguished, not only by his reason, but by this " + "singular passion from other animals, which is a lust of the mind, " + "that by a perseverance of delight in the continued and " + "indefatigable generation of knowledge, exceeds the short vehemence " + "of any carnal pleasure.\n"; assertEquals(atob(longa), longb); assertEquals(btoa(""), ""); assertEquals(btoa("a"), "YQ=="); assertEquals(btoa("aa"), "YWE="); assertEquals(btoa("aaa"), "YWFh"); assertEquals(btoa("aaazdxfksljdf"), "YWFhemR4ZmtzbGpkZg=="); assertEquals(btoa(longb), longa); assertThrows(() => btoa("őÉéeé"), DOMException); div.textContent = "Success"; </script> �����������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/class.html��������������������������������������������������������������������0000664�0000000�0000000�00000001050�15202323131�0016514�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>Element class test</title> <div class="a b c">Fail</div> <script src=asserts.js></script> <script> const div = document.getElementsByClassName("a")[0] const classes = ["a", "b", "c"]; let cl = div.classList; for (let i = 0; i < classes.length; ++i) assertEquals(cl[i], classes[i]); cl.remove("a"); assertEquals(div.getAttribute("class"), "b c"); const classes2 = ["x", "y", "z"]; div.setAttribute("class", classes2.join(' ')); let i = 0; for (let x of cl) assertEquals(x, classes2[i++]); div.textContent = "Success"; </script> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/click_setter.html�������������������������������������������������������������0000664�0000000�0000000�00000001076�15202323131�0020072�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>onclick setter/getter</title> <div id=x>Fail</div> <div id=y onclick="console.log('test')">test</div> <script src=asserts.js></script> <script> const x = document.getElementById("x"); assertEquals(x.onclick, null); function myFunction() { this.textContent = "hello" } x.onclick = () => ""; x.onclick = myFunction; assertEquals(x.onclick, myFunction); x.onclick = null; assertEquals(x.onclick, null); const y = document.getElementById("y"); y.onclick = myFunction; assertEquals(y.onclick, myFunction); y.remove(); x.textContent = "Success"; </script> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/computed-style-dependency-tracking.app.html�����������������������������������0000664�0000000�0000000�00000001304�15202323131�0025062�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <!-- Beware: this doesn't work in Gecko. --> <title>Selector dependency tracking</title> <style> :not(input:checked) + p { display: none; } </style> <div id=x>Fail</div> <input id=y type=checkbox> <p id=z>This paragraph is only shown when the checkbox above is checked. <script src=asserts.js></script> <script> const y = document.getElementById("y"); const z = document.getElementById("z"); assertEquals(window.getComputedStyle(z).display, "none"); y.checked = true; assertEquals(window.getComputedStyle(z).display, "block"); y.checked = false; assertEquals(window.getComputedStyle(z).display, "none"); y.remove(); z.remove(); document.getElementById("x").textContent = "Success"; </script> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/config.toml�������������������������������������������������������������������0000664�0000000�0000000�00000000474�15202323131�0016674�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[buffer] history = false [[siteconf]] url = 'file:///.*' scripting = true [[siteconf]] url = 'file:///.*\.app\.html' scripting = 'app' [display] columns = 80 lines = 24 pixels-per-column = 10 pixels-per-line = 20 force-columns = true force-lines = true force-pixels-per-column = true force-pixels-per-line = true ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/constructors.html�������������������������������������������������������������0000664�0000000�0000000�00000001476�15202323131�0020173�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <title>Test constructors</title> <div id=x>Fail</div> <script src=asserts.js></script> <script> assertInstanceof(new Image(), HTMLImageElement); let a = new Image(undefined, 1); /* * Note: this matches neither Blink nor Gecko. * In particular, Blink converts the undefined into 0 because of the * non-optional 1 after it, while Gecko just ignores the 1. * Blink behavior does make some sense, but it seems unimportant to match * it when there's no agreement anyway, and I can't find anything about * this in WebIDL either. */ assertEquals(a.getAttribute("width"), null); assertEquals(a.getAttribute("height"), "1"); let b = new Option(null); assertEquals(b.textContent, "null"); let c = new Option(undefined); assertEquals(c.textContent, ""); document.getElementById("x").textContent = "Success"; </script> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/crypto.html�������������������������������������������������������������������0000664�0000000�0000000�00000000741�15202323131�0016735�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <title>Test template</title> <div id=x>Fail</div> <script src=asserts.js></script> <script> const abuf = new ArrayBuffer(10); const view1 = new Int8Array(abuf); const view2 = new Int8Array(abuf, 9, 1); crypto.getRandomValues(view2); assertEquals(view1[0], 0); const view3 = new Uint8ClampedArray(abuf, 0, 1); assertThrows(() => crypto.getRandomValues(view3), DOMException); assertEquals(view1[0], 0); document.getElementById("x").textContent = "Success"; </script> �������������������������������chawan-v0.4.0/test/js/data_url.html�����������������������������������������������������������������0000664�0000000�0000000�00000000267�15202323131�0017213�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div id=abc>Fail</div> <script src="data:text/plain,"></script> <script src="data:text/javascript,1?document.getElementById('abc').textContent='Success':0"> </script> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/doctype.html������������������������������������������������������������������0000664�0000000�0000000�00000000530�15202323131�0017060�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>Document type</title> <div id=x>Fail</div> <script src=asserts.js></script> <script> document.implementation.createDocumentType('test\u00B7\u0301', '', ''); assertThrows(() => document.implementation.createDocumentType('test!!test', '', ''), DOMException); document.getElementById("x").textContent = "Success"; </script> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/document.html�����������������������������������������������������������������0000664�0000000�0000000�00000002550�15202323131�0017233�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>Document test</title> <body> <div id="abc">Fail</div> <img id=img2 name=img3> <img id=toString name=a> <img id=img4 name=> <form id=myform name=asdf></form> <script src=asserts.js></script> <script> assertEquals(document.toString, document.getElementById("toString")); assertThrows(() => document.remove(), TypeError); document.toString.remove(); document.testtest = "hi"; assertEquals(document.ELEMENT_NODE, 1); assertEquals(Document.ELEMENT_NODE, 1); assertEquals(document.getElementsByName("").length, 0); assertEquals(Object.getOwnPropertyNames(document).toString(), "testtest,location,img2,img3,asdf"); /* * Note: the spec says Document == HTMLDocument, but in other browsers * this is not true. */ if (HTMLDocument == Document) assertEquals(document.toString(), "[object Document]"); assertEquals(document, window.document); assertEquals(document.implementation, document.implementation); assertEquals(document.img2, document.getElementById("img2")); assertEquals(document.img3, document.getElementById("img2")); assertEquals(document.asdf, document.getElementById("myform")); assertEquals(document.img4, undefined); assertEquals(document.implementation.createHTMLDocument(null).title, "null"); document.getElementById("img4").remove(); document.asdf.remove(); document.img2.remove(); document.getElementById("abc").textContent = "Success"; </script> ��������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/documentall.html��������������������������������������������������������������0000664�0000000�0000000�00000001165�15202323131�0017725�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>HTMLCollection test</title> <div id="result">Fail</div> <script src=asserts.js></script> <style>style 1</style> <style>style 2</style> <style>style 3</style> <script> const abc = document.all; assert(!document.all, "document.all must be falsy"); assert(!abc, "document.all must be falsy"); assertEquals(document.all.length, 10); const styles = [abc[6], abc[7], abc[8]]; assertEquals(styles[0].textContent, "style 1"); assertEquals(styles[1].textContent, "style 2"); assertEquals(styles[2].textContent, "style 3"); const result = document.getElementById("result"); result.textContent = "Success"; </script> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/docwrite1.html����������������������������������������������������������������0000664�0000000�0000000�00000003236�15202323131�0017320�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <html lang="en"> <head> <title>document.write test</title> <script> window.onload = function() { const success = document.body.innerHTML == document.querySelector("style").textContent; while (document.body.childNodes[0]) document.body.childNodes[0].remove(); document.body.innerHTML = success ? "Success" : "Fail"; } let checkpointCounter = 0; function checkpoint(n) { if (++checkpointCounter != n) throw new TypeError(`Checkpoint failed: expected ${n} but got ${checkpointCounter}`); } </script> <style><h1>Main title</h1> <p>Text.</p> <script> document.write(`<h2>Subtitle</h2> <script> checkpoint(1); </scr` + `ipt> `); checkpoint(2); document.write(` <script> checkpoint(3); document.write( '<p>before subtext</p>\\n' + '<script>\\n' + 'checkpoint(4);\\n' + 'document.write("third nest");\\n' + '</scr' + 'ipt>\\n' ); </scr` + `ipt> <p>fin</p> `); </script><h2>Subtitle</h2> <script> checkpoint(1); </script> <script> checkpoint(3); document.write( '<p>before subtext</p>\n' + '<script>\n' + 'checkpoint(4);\n' + 'document.write("third nest");\n' + '</scr' + 'ipt>\n' ); </script><p>before subtext</p> <script> checkpoint(4); document.write("third nest"); </script>third nest <p>fin</p> <p>Subtext.</p> </style> <script> document.write("<h1>Main title</h1>"); </script> </head> <body> <p>Text.</p> <script> document.write(`<h2>Subtitle</h2> <script> checkpoint(1); </scr` + `ipt> `); checkpoint(2); document.write(` <script> checkpoint(3); document.write( '<p>before subtext</p>\\n' + '<script>\\n' + 'checkpoint(4);\\n' + 'document.write("third nest");\\n' + '</scr' + 'ipt>\\n' ); </scr` + `ipt> <p>fin</p> `); </script> <p>Subtext.</p> </body> </html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/docwrite2.html����������������������������������������������������������������0000664�0000000�0000000�00000001433�15202323131�0017316�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <html lang="en"> <head> <title>document.write test</title> <script> window.onload = function() { const success = document.body.innerHTML == document.querySelector("style").textContent; while (document.body.childNodes[0]) document.body.childNodes[0].remove(); document.body.innerHTML = success ? "Success" : "Fail"; } let checkpointCounter = 0; function checkpoint(n) { if (++checkpointCounter != n) throw new TypeError(`Checkpoint failed: expected ${n} but got ${checkpointCounter}`); } </script> <style><script> document.write("a"); document.write("<script></scr" + "ipt>x"); document.write("t"); </script>a<script></script>xt </style> </head> <body><script> document.write("a"); document.write("<script></scr" + "ipt>x"); document.write("t"); </script></body> </html> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/docwrite3.html����������������������������������������������������������������0000664�0000000�0000000�00000002401�15202323131�0017313�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <html lang="en"> <head> <script> window.onload = function() { const success = document.body.outerHTML == document.querySelector("style").textContent; /* console.log("BODY", document.body.outerHTML) console.log("STYLE", document.querySelector("style").textContent) */ while (document.body.childNodes[0]) document.body.childNodes[0].remove(); document.body.innerHTML = success ? "Success" : "Fail"; } </script> <style><body><h1>Main title</h1> <p>Text.</p> <script> document.write("<h2>Subtitle</h2>"); document.write("<scr" + "ipt>document.write('<p>before subtext</p><scri'+'pt>document.write(`third nest`)</scri'+'pt>')</scrip" + "t><p>fin</p>"); </script><h2>Subtitle</h2><script>document.write('<p>before subtext</p><scri'+'pt>document.write(`third nest`)</scri'+'pt>')</script><p>before subtext</p><script>document.write(`third nest`)</script>third nest<p>fin</p> <p>Subtext.</p> </body></style> <title>Write example</title> <script> document.write("<h1>Main title</h1>"); </script> </head> <body> <p>Text.</p> <script> document.write("<h2>Subtitle</h2>"); document.write("<scr" + "ipt>document.write('<p>before subtext</p><scri'+'pt>document.write(`third nest`)</scri'+'pt>')</scrip" + "t><p>fin</p>"); </script> <p>Subtext.</p> </body> </html> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/docwrite4.html����������������������������������������������������������������0000664�0000000�0000000�00000002056�15202323131�0017322�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <html lang="en"> <head> <title>document.write test</title> <script> window.onload = function() { const success = document.body.innerHTML == document.querySelector("style").textContent; while (document.body.childNodes[0]) document.body.childNodes[0].remove(); document.body.innerHTML = success ? "Success" : "Fail"; } let checkpointCounter = 0; function checkpoint(n) { if (++checkpointCounter != n) throw new TypeError(`Checkpoint failed: expected ${n} but got ${checkpointCounter}`); } </script> <style><script> document.write(`<script> document.write("a"); `); document.write(` document.write("<script></scr" + "ipt>x"); `); document.write(` document.write("t"); </scr` + "ipt>"); </script><script> document.write("a"); document.write("<script></scr" + "ipt>x"); document.write("t"); </script>a<script></script>xt </style> </head> <body><script> document.write(`<script> document.write("a"); `); document.write(` document.write("<script></scr" + "ipt>x"); `); document.write(` document.write("t"); </scr` + "ipt>"); </script></body> </html> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/domexception.html�������������������������������������������������������������0000664�0000000�0000000�00000002510�15202323131�0020107�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <title>DOMException</title> <div id=x>Fail</div> <script src=asserts.js></script> <script> "use strict"; function test_code() { let ex = new DOMException(); assertEquals(ex.code, 0); ex = new DOMException("", "HierarchyRequestError\0test"); assertEquals(ex.code, 0); ex = new DOMException("test", "HierarchyRequestError"); assertEquals(ex.code, 3); assertEquals(ex.code, ex.HIERARCHY_REQUEST_ERR); assertEquals(ex.code, DOMException.HIERARCHY_REQUEST_ERR); ex = new DOMException("", "DataCloneError"); assertEquals(ex.code, ex.DATA_CLONE_ERR); assertEquals(ex.code, 25); ex = new DOMException("", "IndexSizeError"); assertEquals(ex.code, ex.INDEX_SIZE_ERR); assertEquals(ex.code, 1); } function test_properties() { let ex = new DOMException("test"); assertEquals(ex.message, "test"); assertEquals(ex.name, "Error"); ex = new DOMException("test", "InvalidCharacterError"); assertEquals(ex.name, "InvalidCharacterError"); assertThrows(() => ex.message = "", TypeError); assertThrows(() => ex.name = "test", TypeError); assertEquals(ex.__proto__, DOMException.prototype); /* Note: browsers set "stack" on the prototype, not the object. * This follows node. */ assert(Object.getOwnPropertyNames(ex), ["stack"]); } test_code(); test_properties(); document.getElementById("x").textContent = "Success"; </script> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/element.html������������������������������������������������������������������0000664�0000000�0000000�00000003741�15202323131�0017051�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <!-- Note: yet another test that Gecko can't handle. --> <title>Element test</title> <div id=x class="a b c d" lang=asdf>Fail</div> <div id=y>test</div> <div id=z>test</div> <script src=asserts.js></script> <script> const x = document.getElementById("x"); assertEquals(x.localName, "div"); assertEquals(x.tagName, "DIV"); assertEquals(x.name, undefined); assertEquals(x.classList.item(-1), null); assertEquals(x.classList[-1], undefined); assertEquals(x.classList[1], "b"); assertEquals(x.classList[4294967296], undefined); assertEquals(document.createElementNS("test", "test:div").tagName, "test:div"); assertEquals(x.lang, "asdf"); x.setAttributeNS("ns", "pf:test", "a"); x.setAttributeNS("ns", "pf:test", "b"); /* * The spec, as far as I can tell, says that this shouldn't change * pf:test's prefix. Neither does Blink. But Gecko does. *sigh* I hate XML. */ x.setAttributeNS("ns", "as:test", "d"); x.setAttributeNS("ns2", "as:test", "c"); x.setAttributeNS("ns3", "pf:test", "c"); assertEquals(x.attributes["pf:test"].prefix, "pf"); assertEquals(x.attributes["pf:test"].namespaceURI, "ns"); assertEquals(x.attributes["pf:test"].prefix, "pf"); assertEquals(x.attributes["pf:test"].localName, "test"); assertEquals(x.attributes["pf:test"].value, "d"); assertEquals(x.attributes.unset, undefined); assertEquals(x.attributes.length, 6); assertEquals(x.getAttributeNS("ns", "test"), "d") let attr = x.attributes["pf:test"] x.removeAttributeNS("ns", "test") assertEquals(attr.value, "d") const y = document.getElementById("y"); assertEquals(y.getElementsByTagName("div").length, 0); assertEquals(x.nextElementSibling, y); for (let z = y; z; z = z.nextElementSibling) ; y.textContent = ""; assertEquals(y.childNodes.length, 0); y.remove(); const z = document.getElementById("z"); z.remove(); assertThrows(() => x.prepend({toString: () => new Error()}), TypeError); assertThrows(() => x.append({toString: () => new Error()}), TypeError); x.prepend(); x.append(); x.textContent = "Success"; </script> �������������������������������chawan-v0.4.0/test/js/encode_decode.html������������������������������������������������������������0000664�0000000�0000000�00000002555�15202323131�0020162�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>TextEncoder/TextDecoder test</title> <div id="success">Fail</div> <script src=asserts.js></script> <script> /* Adapted from: https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem */ function base64ToBytes(base64) { const binString = atob(base64); const result = []; for (const c of binString) result.push(Uint8Array.from(c, (m) => m.codePointAt(0))); return result; } function bytesToBase64(bytes) { const binString = String.fromCodePoint(...bytes); return btoa(binString); } assertEquals(new TextEncoder() + "", "[object TextEncoder]"); assertEquals(new TextEncoder().encode("").length, 0); const utf8 = new TextEncoder().encode("a Ā 𐀀 文 🦄") const b64utf8 = bytesToBase64(utf8); assertEquals(b64utf8, "YSDEgCDwkICAIOaWhyDwn6aE") const dec = new TextDecoder(); assertEquals(dec.encoding, "utf-8") const bytes = base64ToBytes(b64utf8); const a = []; let res = ""; for (const c of bytes) { assertThrows(() => dec.decode(null), TypeError); res += dec.decode(c, {stream: true}); } res += dec.decode(); assertEquals(res, "a Ā 𐀀 文 🦄"); /* EOS handling */ const d = new TextDecoder("utf-16le", {fatal: true}); assertEquals(d.decode(Uint8Array.of(0x00), {stream: true}), ''); assertThrows(() => d.decode(), TypeError); assertEquals(d.decode(), ''); document.getElementById("success").textContent = "Success"; </script> ���������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/event.html��������������������������������������������������������������������0000664�0000000�0000000�00000004233�15202323131�0016536�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <body onload="bodyOnload(event)"> <div id=y> <div id=x>Fail</div> </div> <script src=asserts.js></script> <script> let ok7 = false; function bodyOnload(event) { assertEquals(event.target, document); assertEquals(event.currentTarget, window); assertEquals(event, window.event); assert(event.isTrusted); assert(!event.bubbles); assert(!event.cancelable); document.body.dispatchEvent(new Event("load")); const x = document.getElementById("x") const y = document.getElementById("y") assertEquals(new SubmitEvent("submit", {submitter: x}).submitter, x); assertEquals(new SubmitEvent("submit", {}).submitter, null); assertThrows(() => new SubmitEvent("submit", {submitter: window}), TypeError); let n = 0; let ok1 = true, ok2 = true, ok3 = true, ok4 = true, ok5 = true; x.addEventListener("test", e => { n++; e.stopPropagation(); ok1 = e.eventPhase == 2; }, true); x.addEventListener("test", e => { n++; ok1 = ok1 && e.eventPhase == 2 }); x.dispatchEvent(new Event("test", {bubbles: true})); assert(ok1); assertEquals(n, 1); function el2() { ok2 = false; } x.addEventListener("test2", () => x.removeEventListener("test", el2)); x.addEventListener("test2", el2); assert(ok2); const el3 = e => e.stopPropagation(); document.documentElement.addEventListener("click", el3, true); y.addEventListener("click", e => ok3 = false, true); y.addEventListener("click", e => ok4 = false); function el5() { ok5 = false; }; x.addEventListener("click", el5); x.addEventListener("click", el5); x.click(); assert(ok3); assert(ok4); assert(ok5); document.documentElement.removeEventListener("click", el3, true); let ok6 = false; x.addEventListener("click", e => { e.preventDefault(); ok6 = !e.defaultPrevented; }, {passive: true}); x.click(); assert(ok6); ok7 = true; } let ok8 = true; document.addEventListener("load", e => { ok8 = false; }); let ok9 = false; window.addEventListener("click", e => { ok9 = true; }); window.addEventListener("load", e => { assert(ok7); assert(ok8); assert(ok9); assertEquals(e.target, document); assertEquals(e.currentTarget, window); let x = document.getElementById("x"); x.textContent = "Success"; }); </script> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/form.html���������������������������������������������������������������������0000664�0000000�0000000�00000004260�15202323131�0016360�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>Form/form control tests</title> <div id=x>Fail</div> <form id=test> <input id=1 name=input onchange="globalThis.onchangeCalled = true"> <input id=0 name=input> <textarea id=ta>test test</textarea> </form> <script src=asserts.js></script> <script> let x = document.createElement("button"); x.type = "test"; assertEquals(x.type, "submit"); assertEquals(x.getAttribute("type"), "test"); x.type = "button"; assertEquals(x.type, "button"); x.value = "test"; assertEquals(x.getAttribute("value"), "test"); assertEquals(document.getElementsByName("input").length, 2); (function() { // form const test = document.getElementById("test"); assertEquals(document.forms[0], test); assertEquals(document.forms["test"], test); const elements = test.elements; assertEquals(elements.length, test.length); assertEquals(elements["a"], undefined); assertInstanceof(elements[0], HTMLInputElement); assertEquals(elements[0].id, "1"); globalThis.onchangeCalled = false; elements[0].dispatchEvent(new Event("change")); assert(globalThis.onchangeCalled); assertEquals(elements["0"].id, "1"); assertEquals(elements[0].name, "input"); assertInstanceof(elements["input"], RadioNodeList); assertEquals(elements[2].id, "ta"); assertEquals(elements[2].value, "test test"); elements[2].defaultValue = ""; assertEquals(elements[2].value, ""); let el = elements[0]; el.remove(); el.remove(); elements[0].remove(); elements[0].remove(); })(); let test = document.forms[0]; let select = document.createElement("select"); test.append(select); let option = document.createElement("option"); assert(!option.selected); option.setAttribute("selected", ""); assert(option.selected) option.removeAttribute("selected"); assert(!option.selected) select.append(option); select.remove("test"); assertEquals(option.parentNode, null); assertEquals(select.parentNode, test); select.remove(); const formData = new FormData(); formData.append("test", "a"); assertThrows(() => formData.append("test", "b", { toString: function() { throw new Error("test"); } }), TypeError); assertThrows(() => new FormData(null), TypeError); assertEquals(formData.get("test"), "a"); document.getElementById("x").textContent = "Success"; </script> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/headers.html������������������������������������������������������������������0000664�0000000�0000000�00000001152�15202323131�0017025�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>Headers object test</title> <div id=x>Fail</div> <script src=asserts.js></script> <script> const x = new Headers(); x.append("hi", "world"); x.append("test", "test") x.append("test", "a") x.append("test", "b") x.append("z", "g") x.delete("z") assertEquals(x.get("hi"), "world"); assertEquals(x.get("Hi"), "world"); assertEquals(x.get("hI"), "world"); assertEquals(x.get("test"), "test, a, b"); x.append("q", "a"); x.append("r", "b"); x.delete("q"); assertEquals(x.get("q"), null); assertThrows(() => new Headers(null), TypeError); document.getElementById("x").textContent = "Success"; </script> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/htmlcollection.html�����������������������������������������������������������0000664�0000000�0000000�00000001416�15202323131�0020435�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>HTMLCollection test</title> <div class="abc">Fail</div> <style>style 0</style> <style>style 1</style> <style>style 2</style> <script src=asserts.js></script> <script> const abc = document.getElementsByClassName("abc"); assertEquals(abc.length, 1); abc[0].className = "defg"; assertEquals(abc.length, 0); const styles = document.getElementsByTagName("style"); assertEquals(styles.length, 3); for (let i = 0; i < styles.length; ++i) assertEquals(styles[i].textContent, "style " + i); for (const style of styles) style.remove(); const x = document.getElementsByClassName("defg")[0]; const children = x.__lookupGetter__("children").apply(x); children.z = "hi"; assertEquals(x.__lookupGetter__("children").apply(x).z, "hi"); x.textContent = "Success"; </script> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/hyperlink.html����������������������������������������������������������������0000664�0000000�0000000�00000002500�15202323131�0017415�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>Test template</title> <a id=invalid>invalid</a> <a id=valid href='https://username:password@example.org/path?search#hash'>valid</a> <div id=x>Fail</div> <script src=asserts.js></script> <script> const invalid = document.getElementById("invalid"); assertEquals(invalid.href, ""); assertEquals(invalid.protocol, ":"); assertEquals(invalid.search, ""); assertEquals(invalid.hostname, ""); assertEquals(invalid.hash, ""); const valid = document.getElementById("valid"); const url = new URL("https://username:password@example.org/path?search#hash"); assertEquals(valid.protocol, "https:"); for (const x in ["href", "origin", "protocol", "username", "password", "host", "hostname", "port", "pathname", "search", "hash"]) { assertEquals(valid[x], url[x]); } invalid.remove(); valid.remove(); const a = document.createElement("a"); a.href = "https://example.org"; assertEquals(a + "", "https://example.org/"); assertEquals(a.protocol, "https:"); a.protocol = "http" assertEquals(a + "", "http://example.org/") assertEquals(a.href, "http://example.org/"); a.protocol = "ftp" a.protocol = "http" assertEquals(a.href, "http://example.org/"); assertEquals(a.toString(), "http://example.org/"); assertEquals(JSON.stringify(Object.getOwnPropertyDescriptors(a)), "{}"); document.getElementById("x").textContent = "Success"; </script> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/intl.html���������������������������������������������������������������������0000664�0000000�0000000�00000000533�15202323131�0016362�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>Test template</title> <div id=x>Fail</div> <script src=asserts.js></script> <script> assertEquals(new Intl.PluralRules().resolvedOptions().locale, "en-US"); assertThrows(() => Intl.PluralRules(), TypeError); assertEquals(Intl.NumberFormat().format("1"), "1"); document.getElementById("x").textContent = "Success"; </script> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/jsget.html��������������������������������������������������������������������0000664�0000000�0000000�00000000402�15202323131�0016523�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <title>Test if .jsget handles ownership correctly.</title> <script> let a = {}; let x = new CustomEvent("hi", {detail: a}); x.detail; x.detail; x.detail; x.detail; x.detail; x.detail; x.detail; x.detail; x.detail; x.detail; </script> Success ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/li.html�����������������������������������������������������������������������0000664�0000000�0000000�00000001265�15202323131�0016023�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <title>List item test</title> <div id=x>Fail</div> <ol id=ol> <li id=y>first <li id=z value=10>second <li id=a value=-1>third <li id=b value=2147483648>fourth <li id=c value=-2147483650>fourth </ol> <script src=asserts.js></script> <script> const y = document.getElementById("y"); const z = document.getElementById("z"); const a = document.getElementById("a"); const b = document.getElementById("b"); const c = document.getElementById("c"); assertEquals(y.value, 0); assertEquals(z.value, 10); assertEquals(a.value, -1); assertEquals(b.value, 0); assertEquals(c.value, 0); document.getElementById("ol").remove(); document.getElementById("x").textContent = "Success"; </script> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/localstorage.html�������������������������������������������������������������0000664�0000000�0000000�00000000573�15202323131�0020077�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <title>localStorage</title> <div id=x>Fail</div> <script src=asserts.js></script> <script> localStorage.testKey = "test value"; assertEquals(localStorage.key(localStorage.length - 1), "testKey"); assertEquals(localStorage.key(-1), null); assertEquals(localStorage.getItem("testKey"), "test value"); document.getElementById("x").textContent = "Success"; </script> �������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/nocookie.html�����������������������������������������������������������������0000664�0000000�0000000�00000000401�15202323131�0017214�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <title>Cookie setter with cookies disabled</title> <div id=x>Fail</div> <script src=asserts.js></script> <script> document.cookie = "test=a"; assertEquals(document.cookie, ""); document.getElementById("x").textContent = "Success"; </script> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/node.html���������������������������������������������������������������������0000664�0000000�0000000�00000000522�15202323131�0016337�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>Node test</title> <div id=x>Fail</div> <script src=asserts.js></script> <script> let doc = new Document(); let text = doc.createTextNode("test"); let elem = document.createElement("div"); elem.append(text); assertEquals(text.ownerDocument, document); document.getElementById("x").textContent = "Success"; </script> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/outerhtml.html����������������������������������������������������������������0000664�0000000�0000000�00000000400�15202323131�0017430�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>innerHTML test</title> <div id="test">Fail</div> <script src=asserts.js></script> <script> const div = document.getElementById("test"); assertEquals(div.outerHTML, '<div id="test">Fail</div>'); div.textContent = "Success"; </script> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/prev_next_parent_child.html���������������������������������������������������0000664�0000000�0000000�00000001152�15202323131�0022140�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <main> <div id=x>Fail</div> test <a id=y>test test</a> </main> <script src=asserts.js></script> <script> const x = document.getElementById("x") const y = document.getElementById("y"); assertNotEquals(y.previousSibling, x); assertEquals(y.previousSibling.textContent.trim(), "test"); assertEquals(y.previousElementSibling, x); assertEquals(x.nextElementSibling, y); assertEquals(x.nextSibling.textContent.trim(), "test"); x.nextSibling.remove(); x.nextSibling.remove(); assertEquals(x.parentElement.children.length, 1); assertEquals(x.parentElement.children[0], x); x.textContent = "Success"; </script> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/query_selector_plus.html������������������������������������������������������0000664�0000000�0000000�00000000363�15202323131�0021525�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML> <div id=success>Fail</div> <script one> </script> <script two> </script> <script> if (document.querySelector("script[one] + script").attributes["two"]) { document.getElementById("success").textContent = "Success"; } </script> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/quickjs.html������������������������������������������������������������������0000664�0000000�0000000�00000002227�15202323131�0017067�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>QuickJS tests</title> <div id=x>Fail</div> <script src=asserts.js></script> <script> function testNumberLiterals() { assertEquals(0.1.a, undefined); assertEquals(0x1.a, undefined); assertEquals(0b1.a, undefined); assertEquals(01.a, undefined); assertEquals(0o1.a, undefined); assertThrows('0.a', SyntaxError); } function testArrayBuffer() { /* https://github.com/bellard/quickjs/issues/478 */ const rab = new ArrayBuffer(10, {maxByteLength: 10}); const src = new Uint8Array(rab, 0); const EvilConstructor = new Proxy(function() {}, { get: function(target, prop, receiver) { if (prop === 'prototype') { rab.resize(0); return Uint8Array.prototype; } return Reflect.get(target, prop, receiver); } }); Reflect.construct(Uint8Array, [src], EvilConstructor); } function testDate() { /* regression test for sandboxing */ new Date(); } function testRegExp() { /a/.test(""); const o = /x/g; Object.defineProperty(o, "flags", {get: undefined}); "".replace(o); } testNumberLiterals(); testArrayBuffer(); testDate(); testRegExp(); document.getElementById("x").textContent = "Success"; </script> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/reflect.html������������������������������������������������������������������0000664�0000000�0000000�00000005155�15202323131�0017045�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <div id=abc>Fail</div> <a class=claz target="abcd">test test</a> <script src=asserts.js></script> <img id=b src=test.png> <script id=c referrerpolicy=strict-Origin-when-Cross-origin></script> <form id=d></form> <form id=e method=post> <input id=f method=get formmethod=get> <input id=g> <button id=h formmethod=asdf> </form> <progress id=i value=.5 max=0>test</progress> <area id=j target="abcd">test test</area> <script> const x = document.getElementById("abc") const a = document.getElementsByTagName("a")[0]; assertEquals(a.target, "abcd"); a.target = "defg"; assertEquals(a.target, "defg"); assertEquals(a.relList + "", ""); a.relList = "..."; assertEquals(a.relList + "", "..."); assertEquals(a.className, "claz"); const b = document.getElementById("b"); assertEquals(b.crossOrigin, null); b.crossOrigin = "test"; assertEquals(b.crossOrigin, "anonymous"); b.crossOrigin = ""; assertEquals(b.crossOrigin, "anonymous"); b.crossOrigin = "Anonymous"; assertEquals(b.crossOrigin, "anonymous"); b.crossOrigin = "No-cors"; assertEquals(b.crossOrigin, "anonymous"); b.crossOrigin = null; assertEquals(b.crossOrigin, null); b.crossOrigin = "Use-Credentials"; assertEquals(b.crossOrigin, "use-credentials"); const c = document.getElementById("c"); assertEquals(c.referrerPolicy, "strict-origin-when-cross-origin"); c.referrerPolicy = null; assertEquals(c.referrerPolicy, ""); const d = document.getElementById("d"); const e = document.getElementById("e"); const f = document.getElementById("f"); const g = document.getElementById("g"); const h = document.getElementById("h"); const i = document.getElementById("i"); assertEquals(d.method, "get"); assertEquals(e.formMethod, undefined); assertEquals(e.method, "post"); assertEquals(f.formMethod, "get"); assertEquals(f.method, undefined); assertEquals(g.formMethod, "") assertEquals(h.formMethod, "get") assertEquals(i.value, 0.5); assertEquals(i.max, 1); i.setAttribute("max", "2\0asdf"); assertEquals(i.max, 1); i.removeAttribute("max"); assertEquals(i.max, 1); i.value = -1; assertEquals(i.value, 0); assertEquals(i.getAttribute("value"), "-1"); i.max = -1; assertEquals(i.max, 1); i.max = 0; assertEquals(i.max, 1); i.max = 2; assertEquals(i.getAttribute("max"), "2"); i.setAttribute("max", 9.5); assertEquals(i.max, 9.5); { const dummy = {}; dummy[Symbol.toPrimitive] = () => {throw RangeError()}; assertThrows(() => i.max = dummy, RangeError); } assertThrows(() => i.max = "test", TypeError); const j = document.getElementById("j"); assertThrows(() => a.__lookupGetter__("target").apply(j), TypeError); for (const it of [a, b, c, d, e, f, g, h, i]) it.remove(); x.textContent = "Success"; </script> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/request.html������������������������������������������������������������������0000664�0000000�0000000�00000001204�15202323131�0017100�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>Headers object test</title> <div id=x>Fail</div> <script src=asserts.js></script> <script> const url = "https://example.org"; assertThrows(() => new Request(url, {headers: null}), TypeError); assertThrows(() => new Request(url, {body: "test"}), TypeError); assertThrows(() => new Request(url, {mode: null}), TypeError); let n = 0; assertThrows(() => new Request({toString: () => {n = 1; return "!!!:/";}}, {mode: {toString: () => {n = 2; return null;}}}), TypeError); assertEquals(n, 2); new Request(url, {body: null}); /* this is OK, body init is null */ document.getElementById("x").textContent = "Success"; </script> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/run.sh������������������������������������������������������������������������0000775�0000000�0000000�00000000423�15202323131�0015667�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh if ! test "$CHA" then test -f ../../cha && CHA=../../cha || CHA=cha fi failed=0 for h in *.html do printf '%s\r' "$h" if ! "$CHA" -dC config.toml "$h" | diff all.expected - then failed=$(($failed+1)) printf 'FAIL: %s\n' "$h" fi done printf '\n' exit "$failed" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/settimeout.html���������������������������������������������������������������0000664�0000000�0000000�00000000346�15202323131�0017620�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>setTimeout test</title> <!-- For now, this only tests whether setTimeout crashes the buffer or not. (There has been a bug where it did.) --> <script> setTimeout(() => void(0), 1000); </script> Success ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/shadow.html�������������������������������������������������������������������0000664�0000000�0000000�00000000737�15202323131�0016707�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <title>Test shadow root</title> <div id=x>Fail</div> <div id=y>Fail if visible</div> <script src=asserts.js></script> <script> const el = document.getElementById("y"); const shadow = el.attachShadow({mode: "open"}) assertEquals(shadow.nextSibling, null); assertEquals(shadow.previousSibling, null); assertEquals(el.firstChild.previousSibling, null); assertInstanceof(el.firstChild, Text); shadow.append("Success") document.getElementById("x").remove(); </script> ���������������������������������chawan-v0.4.0/test/js/style.app.html����������������������������������������������������������������0000664�0000000�0000000�00000003451�15202323131�0017335�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <style> * { font-family: monospace,monospace } #y::before { color: blue } #y::marker { color: green } #y:first-child { text-align: right } @media (grid: 1) { #y { background: green } } </style> <title>Style test</title> <div id=x>Fail <div id=y style="color: red; display: inline; margin-left: 1ch">test</div> </div> <script src=asserts.js></script> <script> const y = document.getElementById("y"); assertEquals(y.style.cssText, "color: red; display: inline; margin-left: 1ch;"); assertEquals(window.getComputedStyle(y).cssText, ""); assertEquals(window.getComputedStyle(y, "::before").color, "rgb(0, 0, 255)"); /* note: Gecko fails the following case */ assertEquals(window.getComputedStyle(y, "::bEfOre").color, "rgb(0, 0, 255)"); assertEquals(window.getComputedStyle(y, "::marker").color, "rgb(0, 128, 0)"); assertEquals(window.getComputedStyle(y, ":marker").color, ""); assertEquals(window.getComputedStyle(y, "::").color, ""); assertEquals(window.getComputedStyle(y, "").color, "rgb(255, 0, 0)"); assertEquals(window.getComputedStyle(y, "").textAlign, "right"); if (window.matchMedia("(grid: 1)").matches) { const charSize = parseInt(window.getComputedStyle(y).marginLeft); assertEquals(y.getBoundingClientRect().width, charSize * 4); assertEquals(y.getClientRects().length, 1); } y.style.marginRight = "1px"; assertEquals(window.getComputedStyle(y).marginRight, "1px"); y.style.marginRight = "1%"; assertEquals(window.getComputedStyle(y).marginRight, "1%"); y.style.marginRight = "calc(calc(1% - 2px) + 1px)"; assertEquals(window.getComputedStyle(y).marginRight, "calc(1% - 1px)"); y.remove(); assertEquals(window.getComputedStyle(y, "").textAlign, ""); y.style.textAlign = "center"; assertEquals(window.getComputedStyle(y, "").textAlign, ""); document.getElementById("x").textContent = "Success"; </script> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/style.html��������������������������������������������������������������������0000664�0000000�0000000�00000001311�15202323131�0016547�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <style> #y::before { color: blue } </style> <title>Style test</title> <div id=x>Fail</div> <div id=y style="color: red; display: inline">test</div> <img id=z src='data:test'> <script src=asserts.js></script> <script> const y = document.getElementById("y"); const z = document.getElementById("z"); assertEquals(z.width, 0); assertEquals(y.style.cssText, "color: red; display: inline;"); assertEquals(window.getComputedStyle(y).cssText, ""); assertEquals(window.getComputedStyle(y, "::before").color, "red"); assert(window.matchMedia("(grid: 1)").matches); assert(window.matchMedia("(width = 720px)").matches); y.remove(); z.remove(); document.getElementById("x").textContent = "Success"; </script> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/template.html�����������������������������������������������������������������0000664�0000000�0000000�00000000272�15202323131�0017227�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <title>Test template</title> <div id=x>Fail</div> <script src=asserts.js></script> <script> assert(true); document.getElementById("x").textContent = "Success"; </script> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/text.html���������������������������������������������������������������������0000664�0000000�0000000�00000000364�15202323131�0016402�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <div id=x>Fail</div> <script src=asserts.js></script> <script> assertEquals(new Text("data").ownerDocument, document); assertEquals(Text.__proto__, CharacterData); document.getElementById("x").textContent = "Success"; </script> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/title.html��������������������������������������������������������������������0000664�0000000�0000000�00000000345�15202323131�0016536�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title id=t> Title test </title> <div id=x>Fail</div> <script src=asserts.js></script> <script> assertEquals(document.title, "Title test"); document.getElementById("x").textContent = "Success"; </script> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/js/url.html����������������������������������������������������������������������0000664�0000000�0000000�00000022665�15202323131�0016230�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>URL test</title> <div id=x>Fail</div> <script src=asserts.js></script> <script> assertEquals(new URL("https:example.org") + "", "https://example.org/"); assertEquals(new URL("https://////example.com///") + "", "https://example.com///"); assertEquals(new URL("https://example.com/././foo") + "", "https://example.com/foo"); assertEquals(new URL("hello:world", "https://example.com/") + "", "hello:world"); assertEquals(new URL("https:example.org", "https://example.com/") + "", "https://example.com/example.org"); assertEquals(new URL(String.raw`\example\..\demo/.\ `, "https://example.com/") + "", "https://example.com/demo/"); assertEquals(new URL("example", "https://example.com/demo") + "", "https://example.com/example"); assertEquals(new URL('file:///C|/demo') + "", "file:///C:/demo"); assertEquals(new URL('..', 'file:///C:/demo') + "", "file:///C:/"); assertEquals(new URL("x", "file:///A:y") + "", "file:///x"); assertEquals(new URL("x", "file:///A:/y") + "", "file:///A:/x"); assertEquals(new URL("/x", "file:///A:") + "", "file:///A:/x"); assertEquals(new URL('file://C:/') + "", "file:///C:/"); assertEquals(new URL('file://C|/') + "", "file:///C:/"); /* non-standard, but needed for compat with ed2k */ assertEquals(new URL('ed2k://|a|b|c|/') + "", "ed2k://|a|b|c|/"); /* following is standard behavior (but IMO the spec should be changed) */ assertThrows(() => new URL('ed3k://|a|b|c|/'), TypeError); assertEquals(new URL('file://loc%61lhost/') + "", "file:///"); assertEquals(new URL("https://user:password@example.org/") + "", "https://user:password@example.org/"); assertEquals(new URL("https://example.org/foo bar") + "", "https://example.org/foo%20bar"); assertEquals(new URL("https://EXAMPLE.com/../x") + "", "https://example.com/x"); assertThrows(() => new URL("https://ex ample.org/"), TypeError); assertThrows(() => new URL("example"), TypeError); assertThrows(() => new URL("https://example.com:demo"), TypeError); assertThrows(() => new URL("https://[www.example.com]"), TypeError); assertEquals(new URL("https://example.org//") + "", "https://example.org//"); assertEquals(new URL("https://example.com/[]?[]#[]") + "", "https://example.com/[]?[]#[]"); assertEquals(new URL("https://example/%?%#%") + "", "https://example/%?%#%"); assertEquals(new URL("https://example/%25?%25#%25") + "", "https://example/%25?%25#%25"); assertThrows(() => new URL("https:example\r.org"), TypeError); assertEquals(new URL(" https:exa\tmple\n.org\n/ ") + "", "https://example.org/"); assertEquals(new URL(" https:exa\tmple.org\n:\n2\n4\n5\n2\n\n/ ") + "", "https://example.org:2452/"); assertEquals(new URL(" h\nt\tt\np\ts\n:\t/\n/\te\nx\ta\nm\tp\nl\te\n/\tp\na\tt\n\nh\t?\nq\tu\ne\tr\ny\t#\nf\tr\na\tg\nm\te\nnt") + "", "https://example/path?query#fragment"); assertEquals(new URL(" h\nt\tt\np\ts\n:\t/\n/\tu\ns\ne\nr\nn\na\n\nm\ne\n:\np\na\ns\ns\nw\no\nr\nd\n@\ne\nx\ta\nm\tp\nl\te\n/\tp\na\tt\n\nh\t?\nq\tu\ne\tr\ny\t#\nf\tr\na\tg\nm\te\nnt") + "", "https://username:password@example/path?query#fragment"); assertEquals(new URL("abcd?efgh", "https://example.com/") + "", "https://example.com/abcd?efgh"); assertEquals(new URL("abcd#ijkl", "https://example.com/") + "", "https://example.com/abcd#ijkl"); assertEquals(new URL("abcd?efgh#ijkl", "https://example.com/") + "", "https://example.com/abcd?efgh#ijkl"); assertEquals(new URL("https://テスト") + "", "https://xn--zckzah/"); assertEquals(new URL("https://xn--zckzah") + "", "https://xn--zckzah/"); assertEquals(new URL("https://他们为什么不说中文") + "", "https://xn--ihqwcrb4cv8a8dqg056pqjye/"); assertEquals(new URL("https://xn--ihqwcrb4cv8a8dqg056pqjye") + "", "https://xn--ihqwcrb4cv8a8dqg056pqjye/"); assertEquals(new URL("https://3年b組金八先生") + "", "https://xn--3b-ww4c5e180e575a65lsy2b/"); assertEquals(new URL("https://straße.example") + "", "https://xn--strae-oqa.example/"); assertEquals(new URL("https://\uFF61.example") + "", "https://..example/"); // o_0 assertEquals(new URL("https://\u4E3D.example") + "", "https://xn--viq.example/"); assertEquals(new URL("https://\u{2F800}.example") + "", "https://xn--viq.example/"); assertEquals(new URL("https://\u53EF.example") + "", "https://xn--jpr.example/") assertEquals(new URL("https://\u{1F251}.example") + "", "https://xn--jpr.example/") assertEquals(new URL("https://\u{31350}.example") + "", "https://xn--8o8n.example/") assertEquals(new URL("https://xn--3B-ww4c5e180e575a65lsy2b") + "", "https://xn--3b-ww4c5e180e575a65lsy2b/"); assertEquals(new URL("https://あああ") + "", "https://xn--l8jaa/"); assertEquals(new URL("https://\u00DF.example") + "", "https://xn--zca.example/"); assertEquals(new URL("https://\u03C2.example") + "", "https://xn--3xa.example/"); assertEquals(new URL("test://") + "", "test://"); assertThrows(() => new URL("https://xn--ta.example"), TypeError); assertThrows(() => new URL("https://\u{2F800}\u0093.example"), TypeError); assertThrows(() => new URL("https://\u202D.example"), TypeError); assertThrows(() => new URL("https://\u200C.example"), TypeError); assertThrows(() => new URL("https://\u200D.example"), TypeError); assertThrows(() => new URL("https://\uFFFC.example"), TypeError); assertThrows(() => new URL("https://\uFFFD.example"), TypeError); assertThrows(() => new URL("https://xn--"), TypeError); assertEquals(new URL("https://いろは-にほへと") + "", "https://xn----07t3els0dua4l/"); assertEquals(new URL("https://xn----07t3els0dua4l/") + "", "https://xn----07t3els0dua4l/"); assertEquals(new URL("file:/test") + "", "file:///test"); assertEquals(new URL("https://[ffff::127.0.0.1]") + "", "https://[ffff::7f00:1]/"); assertThrows(() => new URL("https://[]"), TypeError); /* from the spec */ assertThrows(() => new URL("https://exa%23mple.org"), TypeError); assertThrows(() => new URL("foo://exa[mple.org"), TypeError); assertThrows(() => new URL("https://1.2.3.4.5/"), TypeError); assertThrows(() => new URL("https://test.42"), TypeError); assertThrows(() => new URL("https://255.255.4000.1"), TypeError); assertThrows(() => new URL("https://255.255.1.1.1"), TypeError); assertEquals(new URL("https://127.0.0.1") + "", "https://127.0.0.1/"); assertEquals(new URL("https://0xFF.0.0.1") + "", "https://255.0.0.1/"); assertEquals(new URL("https://127.0.0xFFFF") + "", "https://127.0.255.255/"); assertEquals(new URL("https://127.0.0xFFFF.") + "", "https://127.0.255.255/"); assertEquals(new URL("https://127.0.1") + "", "https://127.0.0.1/"); assertEquals(new URL("https://127.1") + "", "https://127.0.0.1/"); assertEquals(new URL("https://127") + "", "https://0.0.0.127/"); assertThrows(() => new URL("https://127.0.0x1FFFF"), TypeError); assertThrows(() => new URL("https://[::1"), TypeError); assertThrows(() => new URL("https://[:1]"), TypeError); assertThrows(() => new URL("https://[1:2:3:4:5:6:7:8:9]"), TypeError); assertThrows(() => new URL("https://[1::1::1]"), TypeError); assertThrows(() => new URL("https://[1:2:3!:4]"), TypeError); assertThrows(() => new URL("https://[1:2:3:]"), TypeError); assertThrows(() => new URL("https://[1:2:3]"), TypeError); assertThrows(() => new URL("https://[1:1:1:1:1:1:1:127.0.0.1]"), TypeError); assertThrows(() => new URL("https://[ffff::.0.0.1]"), TypeError); assertThrows(() => new URL("https://[ffff::127.0.xyz.1]"), TypeError); assertThrows(() => new URL("https://[ffff::127.0xyz]"), TypeError); assertThrows(() => new URL("https://[ffff::127.00.0.1]"), TypeError); assertThrows(() => new URL("https://[ffff::127.0.0.1.2]"), TypeError); assertThrows(() => new URL("https://[ffff::127.0.0.4000]"), TypeError); assertThrows(() => new URL("https://[ffff::127.0.0]"), TypeError); assertThrows(() => new URL("https://#fragment"), TypeError); assertThrows(() => new URL("https://:443"), TypeError); assertThrows(() => new URL("https://user:pass@"), TypeError); assertThrows(() => new URL("https://example.org:70000"), TypeError); assertThrows(() => new URL("https://example.org:7z"), TypeError); assertThrows(() => new URL("https://example.org", null), TypeError); { const x = new URL("file:/test"); x.protocol = "abcd"; assertEquals(x.protocol, "file:"); } { const x = new URL("efgh:/test"); x.protocol = "abcd"; assertEquals(x.protocol, "abcd:"); x.protocol = " efgh"; assertEquals(x.protocol, "abcd:"); } { const x = new URL("http:/test"); x.protocol = "abcd"; assertEquals(x.protocol, "http:"); x.port = 444; x.protocol = "https"; assertEquals(x.protocol, "https:"); assertEquals(x.port, "444"); x.port = 80; x.protocol = "http"; assertEquals(x + "", "http://test/"); } { const x = new URL("https://user:password@example.org:1234/path?search#hash"); assertEquals(x.protocol, "https:"); assertEquals(x.username, "user"); assertEquals(x.password, "password"); assertEquals(x.hostname, "example.org"); assertEquals(x.port, "1234"); assertEquals(x.host, "example.org:1234"); assertEquals(x.pathname, "/path"); assertEquals(x.search, "?search"); assertEquals(x.hash, "#hash"); x.searchParams.delete("search"); assertEquals(x.search, ""); x.searchParams.append("hi", "world"); assert(x.searchParams.has("hi")); assert(!x.searchParams.has("hi", null)); assert(!x.searchParams.has("hi", "")); assert(x.searchParams.has("hi", "world")); x.searchParams.set("hi", "ho"); assert(x.searchParams.has("hi", "ho")); x.searchParams.set("ho", "hi"); assert(x.searchParams.has("ho", "hi")); assertEquals(new URLSearchParams(undefined) + "", "") } { const url = new URL("data:blah #a"); assertEquals(url.pathname, "blah %20"); url.hash = ""; assertEquals(url.pathname, "blah %20"); } document.getElementById("x").textContent = "Success"; </script> ���������������������������������������������������������������������������chawan-v0.4.0/test/js/window.html�������������������������������������������������������������������0000664�0000000�0000000�00000002312�15202323131�0016720�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>Window test</title> <div id=x>Fail</div> <script src=asserts.js></script> <script> assertEquals(window.toString(), "[object Window]"); const desc = Object.getOwnPropertyDescriptor(window, "window"); assert(desc.enumerable, "window must be enumerable"); assert(!desc.configurable, "window must not be configurable"); assertEquals(window.history.state, null); assertEquals(window.event, undefined); assert(Object.getOwnPropertyNames(window).includes("atob")); assert(Object.getOwnPropertyNames(window).includes("onload")); window.localStorage.setItem("a", "x"); window.localStorage["b"] = "y"; assertEquals(window.localStorage["b"], "y") delete window.localStorage.b; assertEquals(window.localStorage["b"], undefined); window.localStorage["b"] = "y"; assert(window.sessionStorage instanceof Storage); Image = "test"; HTMLDocument = "test"; assertEquals(Image, "test"); assertEquals(HTMLDocument, "test"); window.onload = () => "first" let second = () => "second" window.onload = second; assertEquals(second, window.onload); let old = window.document; new DOMParser().parseFromString("asdf", "text/html"); assertEquals(old, window.document); document.getElementById("x").textContent = "Success"; </script> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/��������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0015426�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-before-resolved-margins.expected���������������������������������0000664�0000000�0000000�00000000034�15202323131�0025503�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ absolute 2em absolute 2 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-before-resolved-margins.html�������������������������������������0000664�0000000�0000000�00000000322�15202323131�0024646�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="margin-top: 1em"> <div style="position: absolute"> absolute </div> <div style="margin-top: 2em; margin-left: 10ch; margin-bottom: 1em"> 2em </div> <div style="position: absolute"> absolute 2 </div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-clipped-by-relative-ancestor.expected����������������������������0000664�0000000�0000000�00000000020�15202323131�0026432�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������visible visible ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-clipped-by-relative-ancestor.html��������������������������������0000664�0000000�0000000�00000000231�15202323131�0025601�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="position: relative; overflow: hidden; height: 2em"> visible <div style="position: absolute; z-index: -1"> visible<br> hidden �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-container-indefinite-height.expected�����������������������������0000664�0000000�0000000�00000000134�15202323131�0026327�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ outer 1 . . . . . . . . . . . . . . . . . . . . . . . . . . bottom 21 outer 2 bottom 43 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-container-indefinite-height.html���������������������������������0000664�0000000�0000000�00000000616�15202323131�0025477�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <pre style="position: relative"> <div style="position: absolute; bottom: 0">bottom .1</div> outer 1 . . . . . . . . . . . . . . . . . . . . . . . . . . <div style="position: absolute; bottom: 0">bottom 2</div> </pre> <pre style="position: relative"> <div style="position: absolute; bottom: 0">bottom .3</div> outer 2 <div style="position: absolute; bottom: 0">bottom 4</div> </pre> ������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-in-absolute.expected���������������������������������������������0000664�0000000�0000000�00000000262�15202323131�0023207�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test test2 test2 test2 test2 test2 test2 test2 test2 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-in-absolute.html�������������������������������������������������0000664�0000000�0000000�00000000474�15202323131�0022357�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="position: absolute"> <span style="display: inline-block; position: absolute; background: red"> test test <div style="position: absolute; background: blue"> test2 test2 test2 test2 </div> <br> <br> <br> <br> <br> <div style="position: absolute; background: blue; width: 0"> test2 test2 test2 test2 </div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-max-width.expected�����������������������������������������������0000664�0000000�0000000�00000000116�15202323131�0022665�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test  test  test  ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-max-width.html���������������������������������������������������0000664�0000000�0000000�00000000236�15202323131�0022033�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCYTPE html> <div style="position: relative; width: 5ch"> <div style="position: absolute; width: 10ch; max-width: 100%; background: green"> test test test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-negative-z-index-position-resolved-before-container.expected�����0000664�0000000�0000000�00000000053�15202323131�0033044�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������   �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-negative-z-index-position-resolved-before-container.html���������0000664�0000000�0000000�00000000336�15202323131�0032213�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="position: absolute; margin-left: 1ch"> <div style="position: absolute; margin-left: 1ch"> <div style="width: 10em; height: 1em; left: 0; position: absolute; z-index: -1; background: red"></div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-no-line-break-easy.expected��������������������������������������0000664�0000000�0000000�00000000203�15202323131�0024342�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ hi break world hi world ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-no-line-break-easy.html������������������������������������������0000664�0000000�0000000�00000000454�15202323131�0023515�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> * { font-family: monospace,monospace; line-height: 1em; font-size: 18px } </style> <div style="width: 100%; text-align: center"> <span style="text-align: right">hi <br><br><div style="position: absolute">break</div>world</span> <br> <span>hi </span> <span>world</span> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-overflow-hidden.expected�����������������������������������������0000664�0000000�0000000�00000000010�15202323131�0024050�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������visible ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-overflow-hidden.html���������������������������������������������0000664�0000000�0000000�00000000246�15202323131�0023226�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <html style="width: 0; height: 0; overflow: hidden"> visible <div style="position: absolute; width: 0; height: 0; overflow: hidden"> invisible </div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-percentage-width-of-container.expected���������������������������0000664�0000000�0000000�00000000052�15202323131�0026576�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test test  x ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-percentage-width-of-container.html�������������������������������0000664�0000000�0000000�00000000266�15202323131�0025750�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="position: relative; display: inline-block"> <div style="position: absolute; width: 100%; background: red; margin-top: 1em"> test </div> test test <br> </div> <br> <br> x ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-root-element.expected��������������������������������������������0000664�0000000�0000000�00000000005�15202323131�0023372�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-root-element.html������������������������������������������������0000664�0000000�0000000�00000000067�15202323131�0022545�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <html style="position: absolute"> test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-size-depends-on-float-sibling.expected���������������������������0000664�0000000�0000000�00000000066�15202323131�0026523�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������  test   ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-size-depends-on-float-sibling.html�������������������������������0000664�0000000�0000000�00000000316�15202323131�0025664�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="position: absolute; width: 10ch"> <div style="float: right; margin-bottom: 1em">test</div> <div style="position: absolute; background: red; width: 2ch; top: 0; bottom: 0"></div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-top-bottom-conflict-in-indefinite-parent.expected����������������0000664�0000000�0000000�00000000062�15202323131�0030675�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/absolute-top-bottom-conflict-in-indefinite-parent.html��������������������0000664�0000000�0000000�00000000204�15202323131�0030036�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="position: relative"> <div style="position: absolute; top: 0; bottom: 0; padding: 1em; background: red"> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/acid1.expected������������������������������������������������������������0000664�0000000�0000000�00000046302�15202323131�0020137�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������   ┌────────────────────────────────────────────────────────────────────────────────────────────────┐  │ ┌──────────────┐ ┌────────────────────────────────────────────────────────────────────────┐ │  │ │ │ │ │ │  │ │ toggle │ │ ┌──────────────┐   ┌──────────────┐ │ │  │ │ │ │ │ │  the world ends  │ │ │ │  │ │ │ │ │ the way │  bang ( )  │ i grow old │ │ │  │ │ │ │ │ │  whimper ( )  │ │ │ │  │ │ │ │ │ │   │ │ │ │  │ │ │ │ │ │   │ │ │ │  │ │ │ │ │ │   │ │ │ │  │ │ │ │ │ │   │ │ │ │  │ │ │ │ │ │   │ │ │ │  │ │ │ │ │ │   │ │ │ │  │ │ │ │ │ │   │ │ │ │  │ │ │ │ │ │ │ │ │ │  │ │ │ │ └──────────────┘ └──────────────┘ │ │  │ │ │ │ │ │  │ │ │ │   ┌──────────┐   │ │  │ │ │ │  pluot?  │ │  sing to me, erbarme  │ │  │ │ │ │   │bar maids,│  dich  │ │  │ │ │ │   │ │   │ │  │ │ │ │   │ │   │ │  │ │ │ │   │ │   │ │  │ │ │ │   │ │   │ │  │ │ │ │   │ │   │ │  │ │ │ │   │ │   │ │  │ │ │ │   │ │   │ │  │ │ │ │   │ │   │ │  │ │ │ │   │ │   │ │  │ │ │ │ └──────────┘ │ │  │ │ │ │ │ │  │ │ │ │ │ │  │ └──────────────┘ └────────────────────────────────────────────────────────────────────────┘ │  │This is a nonsensical document, but syntactically valid HTML 4.0. All 100%-conformant CSS1 │  │agents should be able to render the document elements above this paragraph indistinguishably (to│  │the pixel) from this reference rendering, (except font rasterization and form widgets). All │  │discrepancies should be traceable to CSS1 implementation shortcomings. Once you have finished │  │evaluating this test, you can return to the parent page. │  └────────────────────────────────────────────────────────────────────────────────────────────────┘ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/acid1.html����������������������������������������������������������������0000664�0000000�0000000�00000006010�15202323131�0017272�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head> <meta http-equiv="content-type" content="text/html; charset=windows-1252"> <title> display/box/float/clear test </title> <style type="text/css"> /* last modified: 1 Dec 98 */ html { font: 10px/1 Verdana, sans-serif; background-color: blue; color: white; } body { margin: 1.5em; border: .5em solid black; padding: 0; width: 48em; background-color: white; } dl { margin: 0; border: 0; padding: .5em; } dt { background-color: rgb(204,0,0); margin: 0; padding: 1em; width: 10.638%; /* refers to parent element's width of 47em. = 5em or 50px */ height: 28em; border: .5em solid black; float: left; } dd { float: right; margin: 0 0 0 1em; border: 1em solid black; padding: 1em; width: 34em; height: 27em; } ul { margin: 0; border: 0; padding: 0; } li { display: block; /* i.e., suppress marker */ color: black; height: 9em; width: 5em; margin: 0; border: .5em solid black; padding: 1em; float: left; background-color: #FC0; } #bar { background-color: black; color: white; width: 41.17%; /* = 14em */ border: 0; margin: 0 1em; } #baz { margin: 1em 0; border: 0; padding: 1em; width: 10em; height: 10em; background-color: black; color: white; } form { margin: 0; display: inline; } p { margin: 0; } form p { line-height: 1.9; } blockquote { margin: 1em 1em 1em 2em; border-width: 1em 1.5em 2em .5em; border-style: solid; border-color: black; padding: 1em 0; width: 5em; height: 9em; float: left; background-color: #FC0; color: black; } address { font-style: normal; } h1 { background-color: black; color: white; float: left; margin: 1em 0; border: 0; padding: 1em; width: 10em; height: 10em; font-weight: normal; font-size: 1em; } </style> </head> <body> <dl> <dt> toggle </dt> <dd> <ul> <li> the way </li> <li id="bar"> <p> the world ends </p> <form action="./" method="get"> <p> bang <input type="radio" name="foo" value="off"> </p> <p> whimper <input type="radio" name="foo2" value="on"> </p> </form> </li> <li> i grow old </li> <li id="baz"> pluot? </li> </ul> <blockquote> <address> bar maids, </address> </blockquote> <h1> sing to me, erbarme dich </h1> </dd> </dl> <p style="color: black; font-size: 1em; line-height: 1.3em; clear: both"> This is a nonsensical document, but syntactically valid HTML 4.0. All 100%-conformant CSS1 agents should be able to render the document elements above this paragraph indistinguishably (to the pixel) from this <a href="https://www.w3.org/Style/CSS/Test/CSS1/current/sec5526c.gif">reference rendering,</a> (except font rasterization and form widgets). All discrepancies should be traceable to CSS1 implementation shortcomings. Once you have finished evaluating this test, you can return to the <a href="https://www.w3.org/Style/CSS/Test/CSS1/current/sec5526c.htm">parent page</a>. </p> </body></html> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/add�����������������������������������������������������������������������0000775�0000000�0000000�00000000321�15202323131�0016100�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh if test -z "$1" then echo "Usage: test/layout/add test/layout/[test-name].html" exit 1 fi CHA=${CHA:-./cha} $CHA -Ctest/layout/config.toml "$1" >"$(dirname "$1")/$(basename "$1" .html).expected" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/adoption-agency.expected��������������������������������������������������0000664�0000000�0000000�00000000017�15202323131�0022230�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/adoption-agency.html������������������������������������������������������0000664�0000000�0000000�00000000037�15202323131�0021375�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<font><i><b><p><a>test</a></i> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/anb-whitespace.expected���������������������������������������������������0000664�0000000�0000000�00000000245�15202323131�0022044�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ • hello • world • how • are • you �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/anb-whitespace.html�������������������������������������������������������0000664�0000000�0000000�00000000171�15202323131�0021205�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> ul li:nth-child( 1n ) { color: blue } </style> <ul> <li>hello <li>world <li>how <li>are <li>you �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/anonymous-row-and-cell-in-display-table.expected��������������������������0000664�0000000�0000000�00000000022�15202323131�0026611�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������div 1 div 2 div 3 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/anonymous-row-and-cell-in-display-table.html������������������������������0000664�0000000�0000000�00000000140�15202323131�0025755�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: table"> <div>div 1</div> <div>div 2</div> <div>div 3</div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/at-rule-no-end-brace.expected���������������������������������������������0000664�0000000�0000000�00000000033�15202323131�0022746�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/at-rule-no-end-brace.html�������������������������������������������������0000664�0000000�0000000�00000000112�15202323131�0022107�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<style> @media (width > 0) { div { color: red } </style> <div>test</div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/attribute-selector.expected�����������������������������������������������0000664�0000000�0000000�00000000452�15202323131�0022773�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������should be green should be green should be green should be red should be red should be green should be green should be red ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/attribute-selector.html���������������������������������������������������0000664�0000000�0000000�00000000765�15202323131�0022145�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> div { color: red } div[test|=test] { color: green } div[test2|=test-] { color: green } div[type=a] { color: green } div[type=A] { color: green } div[type=b s] { color: green } </style> <div test=test>should be green</div> <div test=test->should be green</div> <div test=test-test>should be green</div> <div test=tes>should be red</div> <div test2=test>should be red</div> <div test2=test->should be green</div> <div type=a>should be green</div> <div type=B>should be red</div> �����������chawan-v0.4.0/test/layout/bfc-after-inline-float.expected�������������������������������������������0000664�0000000�0000000�00000000136�15202323131�0023361�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test  test   ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/bfc-after-inline-float.html�����������������������������������������������0000664�0000000�0000000�00000000213�15202323131�0022520�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> test <div style="width: 3em; height: 3em; background: red; float: left"> </div> test <div style="display: flow-root"> test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/bfc-child-after-float-overflows-parent.expected���������������������������0000664�0000000�0000000�00000000041�15202323131�0026474�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������float test  �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/bfc-child-after-float-overflows-parent.html�������������������������������0000664�0000000�0000000�00000000233�15202323131�0025642�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="display: flow-root; width: 3ch"> <div style="float: right">float</div> <pre style="width: 6ch; display: flow-root; background: red">test</pre> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/bfc-next-to-float.expected������������������������������������������������0000664�0000000�0000000�00000000352�15202323131�0022402�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������firstsecond  second second second second second second second second second second second second second second second third fourthfifth ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/bfc-next-to-float.html����������������������������������������������������0000664�0000000�0000000�00000000603�15202323131�0021544�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="float: left"> first </div> <div style="display: flow-root"> <div style="width: 100%; background: red">second</div> second second second second second second second second second second second second second second second </div> <div style="display: flow-root"> third </div> <div style="float: left"> fourth </div> <div style="display: flow-root"> fifth </div> �����������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/block-and-inline-block-overflows-fit-content-with-padding.expected��������0000664�0000000�0000000�00000000102�15202323131�0032171�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test   test  ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/block-and-inline-block-overflows-fit-content-with-padding.html������������0000664�0000000�0000000�00000000367�15202323131�0031351�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: inline-block; width: 5ch; background: red"> <div style="display: inline-block; background: green; padding: 0 5ch"> test </div> <div style="display: block; background: green; padding: 0 5ch"> test </div> </div> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/block-margin-auto.expected������������������������������������������������0000664�0000000�0000000�00000001045�15202323131�0022464�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������  test     test    test     test    test   test     test    test   test  �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/block-margin-auto.html����������������������������������������������������0000664�0000000�0000000�00000001555�15202323131�0021635�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 20ch; background: red"> <table style="background: green; margin-left: auto; margin-right: 2ch"> <tr> <td> test </table> <center> <table style="margin-left: auto; margin-right: auto" bgcolor=green> <tr> <td> test </table> </center> <center> <table style="margin-right: auto" bgcolor=green> <tr> <td> test </table> </center> <center> <table bgcolor=green> <tr> <td> test </table> </center> <center> <table bgcolor=green style="margin-right: auto"> <tr> <td> test </table> </center> <div style="margin-left: auto; margin-right: 3ch; background: green"> test </div> <center> <div style="margin-left: 3ch; background: green"> test </div> </center> <center> <div style="margin-left: 3ch; margin-right: auto; background: green"> test </div> </center> <div style="margin-left: 3ch; margin-right: auto; background: green"> test </div> </div> ���������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/body-background-color-blend.expected��������������������������������������0000664�0000000�0000000�00000000145�15202323131�0024421�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test  ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/body-background-color-blend.html������������������������������������������0000664�0000000�0000000�00000000156�15202323131�0023566�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="background: green"> <div style="background: rgba(0, 0, 0, .05)">test</div> </div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/border-float-inline-block-baseline.expected�������������������������������0000664�0000000�0000000�00000001102�15202323131�0025647�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������┌─────┐ ┌────────────┐ │float│test │inline-block│ test └─────┘ └────────────┘ height test height test ┌────────────┐ test │inline-block│ test └────────────┘ height test ┌─────┐┌─────┐test┌─────┐┌─────┐ │float││float│ │float││float│ └─────┘└─────┘ └─────┘└─────┘ height test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/border-float-inline-block-baseline.html�����������������������������������0000664�0000000�0000000�00000001055�15202323131�0025021�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> test <div style="display: inline-block; border: solid">inline-block</div> test <div style="float: left; border: solid">float</div> <br> height test height test <br> test <div style="display: inline-block; border: solid">inline-block</div> test <br> height test <div style="display: flow-root; width: 32ch"> test <div style="float: left; border: solid">float</div> <div style="float: left; border: solid">float</div> <div style="float: right; border: solid">float</div> <div style="float: right; border: solid">float</div> </div> height test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/bottom-property-non-absolute.expected�������������������������������������0000664�0000000�0000000�00000000012�15202323131�0024734�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/bottom-property-non-absolute.html�����������������������������������������0000664�0000000�0000000�00000000061�15202323131�0024103�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div>test<div> <div style="bottom: 0">test</div> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/br-clear-all.expected�����������������������������������������������������0000664�0000000�0000000�00000000026�15202323131�0021404�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ left left left test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/br-clear-all.html���������������������������������������������������������0000664�0000000�0000000�00000000125�15202323131�0020547�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <pre style=float:left>left left left</pre> <br clear=ALL> <div> test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/button-text.expected������������������������������������������������������0000664�0000000�0000000�00000000157�15202323131�0021451�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[SUBMIT] [] [RESET] [] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/button-text.html����������������������������������������������������������0000664�0000000�0000000�00000000241�15202323131�0020606�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<style> #x::before { content: "test" } </style> <input id=x type=submit><br> <input type=submit value=><br> <input type=reset><br> <input type=reset value=><br> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/calc-negative-padding.expected��������������������������������������������0000664�0000000�0000000�00000000005�15202323131�0023252�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/calc-negative-padding.html������������������������������������������������0000664�0000000�0000000�00000000133�15202323131�0022417�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 10ch"> <div style="padding-left: calc(10% - 4ch)"> test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/calc-with-var.expected����������������������������������������������������0000664�0000000�0000000�00000000011�15202323131�0021602�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/calc-with-var.html��������������������������������������������������������0000664�0000000�0000000�00000000143�15202323131�0020753�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<style> :root { --test: 1em; } div { padding-left: calc(var(--test) + 1em) } </style> <div> test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/calc.expected�������������������������������������������������������������0000664�0000000�0000000�00000001045�15202323131�0020053�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������0ch 4ch  2ch 2ch 3ch 8ch  1ch 2ch 1ch red red red red test test  test  test  test  test  test red �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/calc.html�����������������������������������������������������������������0000664�0000000�0000000�00000002553�15202323131�0017223�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 20ch"> <!-- valid --> <div style="width: calc(0em - 10em); background: red">0ch</div> <div style="width: calc(10ch - 3em); background: red">4ch</div> <div style="width: calc(1ch * 2); background: red">2ch</div> <div style="width: calc(1ch + calc(2ch - 1ch)); background: red">2ch</div> <div style="width: calc(1ch * 2 + calc(2ch - 1ch)); background: red">3ch</div> <div style="width: calc(50% - 2ch); background: red">8ch</div> <div style="background: red; width: calc(1ch">1ch</div> <div style="background: red; width: calc(1ch + 10ch * 4 / 20 - 1ch">2ch</div> <div style="background: red; width: calc(-1ch + (1ch + 1ch">1ch</div> <div style="color: rgba(calc(1 * 255), 0, 0, 1)">red</div> <div style="color: rgb(calc(1 * 255) 0 0)">red</div> <div style="color: rgba(calc(1 * 255) 0 0 / 1)">red</div> <div style="color: hsl(calc(1turn) 100 50 / 1)">red</div> <div style="color: hsl(calc(90) calc(50%) calc(60%))">test</div> <!-- invalid --> <div style="background: red; width: calc(- 1ch)">test</div> <div style="width: calc(1 * 2); background: red">test</div> <div style="width: calc(); background: red">test</div> <div style="width: calc(1); background: red">test</div> <div style="width: calc(1ch + + 1ch); background: red">test</div> <div style="color: rgba(calc(1ch) 0 0 / 1)">test</div> <div style="color: rgba(calc(1 * 255), 50%, 0)">red</div> �����������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/case2.expected������������������������������������������������������������0000664�0000000�0000000�00000000203�15202323131�0020141�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ hi break world hi world ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/case2.html����������������������������������������������������������������0000664�0000000�0000000�00000000454�15202323131�0017314�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> * { font-family: monospace,monospace; line-height: 1em; font-size: 18px } </style> <div style="width: 100%; text-align: center"> <span style="text-align: right">hi <br><br><div style="position: absolute">break</div>world</span> <br> <span>hi </span> <span>world</span> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/case4.expected������������������������������������������������������������0000664�0000000�0000000�00000000726�15202323131�0020155�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test test test test test test test test test test test testfloat right float lefttest test test test test test test test test test test testfloat right test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test ������������������������������������������chawan-v0.4.0/test/layout/case4.html����������������������������������������������������������������0000664�0000000�0000000�00000001257�15202323131�0017320�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <html> <body> <div style="margin-top: 1em"> <div style="float: right; background-color: blue">float right</div> <div style="float: left; clear: right; background-color: red">float left</div> <div style="float: right; background-color: yellow">float right</div> </div> <div style="margin-top: 2em"> test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div> </body> </html> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/center-in-inline.expected�������������������������������������������������0000664�0000000�0000000�00000000201�15202323131�0022302�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/center-in-inline.html�����������������������������������������������������0000664�0000000�0000000�00000000176�15202323131�0021460�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <center> <span> test <center style="width: 20ch"> <div style="width: 5ch"> test </div> </center> test </span> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/clear-before-margin-resolution.expected�����������������������������������0000664�0000000�0000000�00000001025�15202323131�0025151�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test      test right test       right test     right   test  �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/clear-before-margin-resolution.html���������������������������������������0000664�0000000�0000000�00000001212�15202323131�0024312�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 20ch; background: red"> <div>test</div> <div style="margin-top: 2em; clear: both"></div> <div style="float: right">right</div> <div style="margin-top: 1em">test</div> </div> <div style="width: 20ch; background: red"> <div>test</div> <div style="margin-top: 2em; clear: both"></div> <div style="float: right">right</div> <div style="margin-top: 3em">test</div> </div> <div style="display: flow-root; background: red; width: 20ch"> <div style="margin-top: 1em; background: blue"> <div style="float: right">right</div> <div style="clear: both; margin-top: 1em"></div> <div style="margin-top: 2em"> test </div> </div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/clear-before-margin-resolution2.expected����������������������������������0000664�0000000�0000000�00000003416�15202323131�0025241�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������   right test     right     test     right     test     right       test        test test   test test   test        test  ????    right   test  ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/clear-before-margin-resolution2.html��������������������������������������0000664�0000000�0000000�00000004005�15202323131�0024377�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flow-root; background: red; width: 20ch"> <div style="margin-top: 1em"> <div style="float: right">right</div> <div style="clear: both; margin-top: 3em"></div> <div style="margin-top: 2em"> test </div> </div> </div> <div style="display: flow-root; background: gainsboro; width: 20ch"> <div style="margin-top: 1em"> <div style="float: right">right</div> <div style="clear: both; margin-top: 3em; display: flow-root"></div> <div style="margin-top: 2em"> test </div> </div> </div> <div style="display: flow-root; background: blue; width: 20ch"> <div style="margin-top: 1em"> <div style="float: right; height: 2em">right</div> <div style="clear: both; margin-top: 2em"></div> <div style="margin-top: 3em"> test </div> </div> </div> <div style="display: flow-root; background: purple; width: 20ch"> <div style="margin-top: 1em"> <div style="float: right">right</div> <div style="clear: both; margin-top: -2em"></div> <div style="margin-top: 3em"> test </div> </div> </div> <div style="display: flow-root; background: yellow; width: 20ch"> <div style="margin-top: 1em"> <div style="float: right">test</div> <div style="clear: left; margin-top: 2em"></div> <div style="margin-top: 3em"> test </div> </div> </div> <div style="display: flow-root; background: brown; width: 20ch"> <div style="margin-top: 1em"> <div style="float: left">test</div> <div style="float: right">test</div> <div style="clear: left; margin-top: 2em"></div> <div style="margin-top: 3em"> test </div> </div> </div> <div style="display: flow-root; background: orange; width: 20ch"> <div style="margin-top: 1em"> <div style="margin-top: 2em"></div> <div style="margin-top: 3em"> test </div> </div> </div> <div style="margin-top: 10em; clear: both"> ???? </div> <div style="display: flow-root; background: red; width: 20ch"> <div style="margin-top: 1em; background: blue"> <div style="float: right">right</div> <div style="clear: both; margin-top: 1em"></div> <div style="margin-top: 2em"> test </div> </div> </div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/clear-on-new-bfc-only-clears-in-parent.expected���������������������������0000664�0000000�0000000�00000000154�15202323131�0026311�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test testtest test test right ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/clear-on-new-bfc-only-clears-in-parent.html�������������������������������0000664�0000000�0000000�00000000603�15202323131�0025453�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <!-- markers shouldn't clear. --> <style> li::marker { clear: both; display: block; content: "" } </style> <div> <div style="height: 5em">test</div> <div style="display: flow-root; clear: both"> test <div style="float: left">test</div> </div> </div> <div> <div style="height: 5em">test</div> <li style="float: right">right</li> <div style="float: left">test</div> </div> �����������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/cleared-float-with-text-on-same-line-box.expected�������������������������0000664�0000000�0000000�00000000115�15202323131�0026653�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������floattest test test test test floatfloat float float ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/cleared-float-with-text-on-same-line-box.html�����������������������������0000664�0000000�0000000�00000000453�15202323131�0026023�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 40ch"> <div style="float: left; clear: both">float</div> <div style="float: left; clear: left">float</div> <div style="float: left">float</div> test test test <div style="float: right">float</div> <div style="float: left; clear: left">float</div> test test </div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/color-functions.expected��������������������������������������������������0000664�0000000�0000000�00000000540�15202323131�0022274�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test hsl test test test test test test test test test test test test test test ����������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/color-functions.html������������������������������������������������������0000664�0000000�0000000�00000001431�15202323131�0021437�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="color: rgba(100, 200, 30, 1)">test</div> <div style="color: hsl(40, 20, 41)">hsl</div> <div style="color: rgb(0 , 200 , 100)">test</div> <div style="color: rgb(200, 0, 0, 1)">test</div> <div style="color: rgb(200, 0, 0, 1 test test)">test</div> <div style="color: rgb(200%, 0%, 0%)">test</div> <div style="color: rgb(200%, 0%, 0)">test</div> <div style="color: rgb(200% 0% 0)">test</div> <div style="color: rgb(200% none none)">test</div> <div style="color: rgb(255em 0 0)">test</div> <div style="color: hsl(999 40 40)">test</div> <div style="color: hsl(445 40 40)">test</div> <div style="color: hsl(-445 20 40)">test</div> <div style="color: hsl(-445 9999 40)">test</div> <div style="color: hsl(275 100 40)">test</div> <div style="color: hsl(360 0 50)">test</div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/colored-inline-block-squares.expected�������������������������������������0000664�0000000�0000000�00000003647�15202323131�0024637�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ one ?  ?  ??                                     ?                     w ?  w two                   �����������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/colored-inline-block-squares.html�����������������������������������������0000664�0000000�0000000�00000001020�15202323131�0023761�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div>one <div style="display: inline-block; margin: 2ch; width: 20ch; height: 20ch; background-color: blue"> ?<br> </div> <div style="display: inline-block; margin: 6ch; width: 20ch; height: 20ch; background-color: blue"> ?<br> </div> ?? <div style="display: inline-block; margin-left: 5ch; margin-top: 1em; width: 20ch; background-color: green">?<br><br><br><br><br><br><br><br><br><br><br></div>w <br> <div style="display: inline-block; margin-left: 6ch; width: 20ch; height: 20ch; background-color: red">?</div> w two </div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/colored-text-keeps-color-outside-box.expected�����������������������������0000664�0000000�0000000�00000000127�15202323131�0026243�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test test test test test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/colored-text-keeps-color-outside-box.html���������������������������������0000664�0000000�0000000�00000000201�15202323131�0025377�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="display: block; white-space: nowrap; background: red; width: 5ch; color: blue"> test test test test test </div> test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/config.toml���������������������������������������������������������������0000664�0000000�0000000�00000000510�15202323131�0017564�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[display] columns = 80 lines = 24 pixels-per-column = 9 pixels-per-line = 18 force-columns = true force-lines = true force-pixels-per-column = true force-pixels-per-line = true color-mode = 'true-color' format-mode = ["bold", "italic", "underline", "reverse", "strike"] [buffer] images = true history = false scripting = 'app' ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/counter-set-syntax.expected�����������������������������������������������0000664�0000000�0000000�00000000013�15202323131�0022737�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test 1test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/counter-set-syntax.html���������������������������������������������������0000664�0000000�0000000�00000000305�15202323131�0022106�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> #a { counter-set: a b c 2 } #b { counter-increment: b } #c::before { content: counter(b) } </style> <div id=a> <div> <div id=b>test</div> </div> <div id=c>test</div> </div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/counter-unspecified-nonsense.expected�������������������������������������0000664�0000000�0000000�00000000151�15202323131�0024747�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ 1. A 1. A1 2. A2 2. B 1. A 1. A1 2. A2 2. B 1. A 1. A1 2. A2 3. B �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/counter-unspecified-nonsense.html�����������������������������������������0000664�0000000�0000000�00000001465�15202323131�0024123�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <!-- Nonsensical and entirely unspecified behavior, but necessary for compatibility with others. For now, we imitate Gecko. --> <style> x-ol, y-ol { display: block; margin-left: 4ch } x-li, y-li { display: list-item } x-ol { counter-reset: list-item; counter-set: list-item } x-li { counter-increment: list-item } x-li::marker { content: counter(list-item) ". " } y-ol { counter-reset: test } y-li { counter-increment: test } y-li::marker { content: counter(test) ". " } </style> <p> <ol> <li>A</li> <ol> <li>A1</li> <li>A2</li> </ol> <li>B</li> </ol> <p> <x-ol> <x-li>A</x-li> <x-ol> <x-li>A1</x-li> <x-li>A2</x-li> </x-ol> <x-li>B</x-li> </x-ol> <p> <y-ol> <y-li>A</y-li> <y-ol> <y-li>A1</y-li> <y-li>A2</y-li> </y-ol> <y-li>B</y-li> </y-ol> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/counters.expected���������������������������������������������������������0000664�0000000�0000000�00000000250�15202323131�0021010�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[甲]test 1. 1 1 [乙]test 2. 2 2 3. 3 3 4. 4 4 5. 5 5 6. 6 6 7. 7 7 1. 1 1 2. 2 2 3. 3 3 4. 4 4 5. 5 5 [丙]test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/counters.html�������������������������������������������������������������0000664�0000000�0000000�00000001623�15202323131�0020160�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <!-- Once again, Blink disagrees with Gecko. This time though, it's Blink being weird: it resets list-item counters per div level. That feels wrong, so we follow Gecko. --> <style> myli { display: list-item; margin-left: 5ch; list-style-type: decimal } myli { counter-increment: asdf 1 } myli::before { content: counter(asdf) ' ' } :root { counter-set: my-link-counter } a[href]::before{ content: '['counter(my-link-counter, cjk-heavenly-stem)']'; counter-increment: my-link-counter } </style> <a href=https://example.org>test</a> <div> <myli>1</myli> <div> <a href=https://example.org>test</a> <myli>2</myli> <myli>3</myli> <myli>4</myli> <myli>5</myli> </div> <myli>6</myli> <myli>7</myli> </div> <div> <myli>1</myli> <myli>2</myli> <myli>3</myli> <div> <myli>4</myli> </div> <myli>5</myli> </div> <a href=https://example.org>test</a> �������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/currentcolor.expected�����������������������������������������������������0000664�0000000�0000000�00000000247�15202323131�0021675�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������┌────┐ │test│ └────┘ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/currentcolor.html���������������������������������������������������������0000664�0000000�0000000�00000000221�15202323131�0021030�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<style> table { color: blue } td { color: currentcolor; border: solid; background: currentcolor } </style> <table><tr><td>test</td></tr></table> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/document-element-style-invalidation.expected������������������������������0000664�0000000�0000000�00000000145�15202323131�0026233�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������background should be green  ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/document-element-style-invalidation.html����������������������������������0000664�0000000�0000000�00000000220�15202323131�0025370�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> background should be green <script> document.documentElement.getBoundingClientRect() </script> <html style="background: green"> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/double-comment-parsing.expected�������������������������������������������0000664�0000000�0000000�00000000006�15202323131�0023520�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/double-comment-parsing.html�����������������������������������������������0000664�0000000�0000000�00000000107�15202323131�0022665�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<style> /**//**/ #x { margin-left: 1ch } </style> <div id=x>test</div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/escape-sequence.expected��������������������������������������������������0000664�0000000�0000000�00000000006�15202323131�0022213�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������atest ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/escape-sequence.html������������������������������������������������������0000664�0000000�0000000�00000000106�15202323131�0021357�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<style> #x::before { content: "\0061" } </style> <div id=x>test</div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/fit-content-intrinsic-minimum-width-overrides-available-space.expected����0000664�0000000�0000000�00000000165�15202323131�0033202�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test  1. long...   �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/fit-content-intrinsic-minimum-width-overrides-available-space.html��������0000664�0000000�0000000�00000000411�15202323131�0032337�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 0"> <div style="display: inline-block; background: red"> test test </div> </div> <div style="width: 10ch; height: 2em; background: red"> <div style="padding-left: 8ch; list-style-type: decimal"><li style="background: red">long... �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/fit-content-max-width-child.expected��������������������������������������0000664�0000000�0000000�00000000120�15202323131�0024355�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������testing testing testing testing testing testing testing testing testing testing ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/fit-content-max-width-child.html������������������������������������������0000664�0000000�0000000�00000000240�15202323131�0023523�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="display: inline-block"> <div style="max-width: 70ch"> testing testing testing testing testing testing testing testing testing testing </div> </div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/fixed-in-fixed-in-fixed.expected������������������������������������������0000664�0000000�0000000�00000000015�15202323131�0023446�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������fixed fixed �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/fixed-in-fixed-in-fixed.html����������������������������������������������0000664�0000000�0000000�00000000350�15202323131�0022613�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html <div style="position: fixed"> <div style="position: fixed"> <div style="position: fixed"> fixed </div> </div> </div> <div style="position: fixed; top: 1em"> <div style="position: fixed; top: 2em"> fixed </div> </div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/fixed-in-position-relative.expected���������������������������������������0000664�0000000�0000000�00000000006�15202323131�0024323�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/fixed-in-position-relative.html�������������������������������������������0000664�0000000�0000000�00000000162�15202323131�0023471�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="position: relative; left: 2em; top: 1em"> <div style="position: fixed; left: 0"> test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-and-inline-block-max-width-in-fit-content.expected�������������������0000664�0000000�0000000�00000000062�15202323131�0027745�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-and-inline-block-max-width-in-fit-content.html�����������������������0000664�0000000�0000000�00000000357�15202323131�0027117�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="display: inline-block; width: 10ch"> <div style="background: red; min-width: 1ch; max-width: 2ch"> test </div> </div> <div style="display: flex"> <div style="background: red; min-width: 1ch; max-width: 2ch"> test </div> </div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-anonymous-item-from-text.expected������������������������������������0000664�0000000�0000000�00000000007�15202323131�0025011�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[test] �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-anonymous-item-from-text.html����������������������������������������0000664�0000000�0000000�00000000103�15202323131�0024151�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex">[<div>test</div>]</div> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-child-position-relative.expected�������������������������������������0000664�0000000�0000000�00000000021�15202323131�0024634�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test 2 test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-child-position-relative.html�����������������������������������������0000664�0000000�0000000�00000000202�15202323131�0024000�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="display: flex"> <div style="position: relative; top: 2em"> test </div> <div style="height: 5em"> test 2 </div> </div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-column-child-padding.expected����������������������������������������0000664�0000000�0000000�00000001200�15202323131�0024060�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-column-child-padding.html��������������������������������������������0000664�0000000�0000000�00000000612�15202323131�0023231�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="display: flex; flex-direction: column"> <div style="padding-left: 50ch"> test test test test test test test test test test test test test test test test test test test test test test test test </div> </div> <div style="display: inline-block; margin-left: 50ch"> test test test test test test test test test test test test test test test test test test test test test test test test ����������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-column-height-basis-0.expected���������������������������������������0000664�0000000�0000000�00000000034�15202323131�0024101�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test 1 test 1 test 1 test 2 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-column-height-basis-0.html�������������������������������������������0000664�0000000�0000000�00000000207�15202323131�0023246�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<body style="display: flex; flex-direction: column"> <div style="flex-basis: 0%"> test 1<br> test 1<br> test 1<br> </div> <div> test 2 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-column-width-stretch.expected����������������������������������������0000664�0000000�0000000�00000000145�15202323131�0024171�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test 1  ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-column-width-stretch.html��������������������������������������������0000664�0000000�0000000�00000000162�15202323131�0023333�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <body style="display: flex; flex-direction: column"> <div style="background-color: green"> test 1 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-cross-margin-auto.expected�������������������������������������������0000664�0000000�0000000�00000000170�15202323131�0023455�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-cross-margin-auto.html�����������������������������������������������0000664�0000000�0000000�00000001174�15202323131�0022625�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex; flex-direction: column; width: 10ch"> <!-- TODO: on other browsers, the background of this element is 5ch. not sure why, but it should be fixed --> <div style="margin-left: auto; background: blue; width: 4ch">test</div> </div> <div style="display: flex; height: 10ch"> <div style="margin-top: auto; background: blue; height: 1em">test</div> </div> <div style="display: flex; flex-direction: column; width: 10ch"> <div style="margin-left: auto; background: blue">test</div> </div> <div style="display: flex; height: 10ch"> <div style="margin-top: auto; background: blue">test</div> </div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-direction-reverse.expected�������������������������������������������0000664�0000000�0000000�00000000025�15202323131�0023533�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test 3 test 2 test 1 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-direction-reverse.html�����������������������������������������������0000664�0000000�0000000�00000000211�15202323131�0022673�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex; flex-direction: column-reverse"> <div>test 1</div> <div>test 2</div> <div>test 3</div> </div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-flow.expected��������������������������������������������������������0000664�0000000�0000000�00000000036�15202323131�0021053�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test test test test test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-flow.html������������������������������������������������������������0000664�0000000�0000000�00000000700�15202323131�0020214�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex; flex-flow: row wrap; width: 10ch"> <div style="width: 10ch">test</div> <div style="width: 10ch">test</div> </div> <div style="display: flex; flex-flow: wrap wrap; width: 10ch"> <div style="width: 10ch">test</div> <div style="width: 10ch">test</div> </div> <div style="display: flex; flex-flow: row wrap invalid; width: 10ch"> <div style="width: 10ch">test</div> <div style="width: 10ch">test</div> </div> ����������������������������������������������������������������chawan-v0.4.0/test/layout/flex-in-block-in-flex.expected��������������������������������������������0000664�0000000�0000000�00000000033�15202323131�0023137�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-in-block-in-flex.html������������������������������������������������0000664�0000000�0000000�00000000220�15202323131�0022300�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex"> <div> <div style="display: flex; background: red; padding-left: 1em"> <div>test</div> </div> </div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-in-flex-padding.expected���������������������������������������������0000664�0000000�0000000�00000000123�15202323131�0023047�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������┌──────┐ │ test │ └──────┘ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-in-flex-padding.html�������������������������������������������������0000664�0000000�0000000�00000000233�15202323131�0022214�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex"> <div style="border: solid; padding-left: 1ch; padding-right: 1ch; background: red; display: flex"> test </div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-in-table-intrinsic-min-width.expected��������������������������������0000664�0000000�0000000�00000000021�15202323131�0025467�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ testtest second ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-in-table-intrinsic-min-width.html������������������������������������0000664�0000000�0000000�00000000215�15202323131�0024637�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<table style="width: 4ch"> <tr> <td width=0%> <div style="display: flex"> <div> testtest </div> </div> </td> <td width=100%> second </table> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-item-border.expected�������������������������������������������������0000664�0000000�0000000�00000000277�15202323131�0022324�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test test┌┈┈┈┈┐test ┊test┊ └┈┈┈┈┘ test test ┌┈┈┈┈┐ ┊test┊┌┈┈┈┈┐ ┊ ┊┊test┊ └┈┈┈┈┘└┈┈┈┈┘ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-item-border.html�����������������������������������������������������0000664�0000000�0000000�00000000421�15202323131�0021456�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> test test <div style="display: flex"> test <div style="border: dotted"> test </div> test </div> test test <div style="display: flex"> <div style="border: dotted">test</div> <div style="margin-top: 1em"> <div style="border: dotted">test</div> </div> </div> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-item-indefinite-size-with-min-max-bounds.expected��������������������0000664�0000000�0000000�00000000106�15202323131�0027731�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test test test test test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-item-indefinite-size-with-min-max-bounds.html������������������������0000664�0000000�0000000�00000000231�15202323131�0027073�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex; background: green; width: 10ch"> <div style="max-width: 100%; min-width: 15ch"> test test test test test test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-item-intrinsic-min-height-respected.expected�������������������������0000664�0000000�0000000�00000000071�15202323131�0027044�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test test test test test test test test test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-item-intrinsic-min-height-respected.html�����������������������������0000664�0000000�0000000�00000000233�15202323131�0026207�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <body style="height: 2em; display: flex; flex-direction:column"> <pre> test test test test test test test </pre> <div> test test test test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-item-margin-collapsing.expected��������������������������������������0000664�0000000�0000000�00000000676�15202323131�0024460�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test         test2       test3       test3       ������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-item-margin-collapsing.html������������������������������������������0000664�0000000�0000000�00000001433�15202323131�0023613�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="display: flex; background: red; width: 5ch"> <div style="margin-bottom: 2em; background: blue"> <div style="margin-bottom: 1em; background: green"> test </div> </div> </div> <div style="display: flex; background: red; width: 5ch"> <div style="margin-bottom: 1em; background: blue"> <div style="margin-bottom: 2em; background: green"> test2 </div> </div> </div> <div style="display: flex; flex-direction: column; background: red; width: 5ch"> <div style="margin-bottom: 2em; background: blue"> <div style="margin-bottom: 1em; background: green"> test3 </div> </div> </div> <div style="display: flex; flex-direction: column; background: red; width: 5ch"> <div style="margin-bottom: 1em; background: blue"> <div style="margin-bottom: 2em; background: green"> test3 </div> </div> </div> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-item-padding-with-border.expected������������������������������������0000664�0000000�0000000�00000000131�15202323131�0024666�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������┌┈┈┈┈┈┈┐ ┊ ┊ ┊ test ┊ ┊ ┊ └┈┈┈┈┈┈┘ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-item-padding-with-border.html����������������������������������������0000664�0000000�0000000�00000000140�15202323131�0024031�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex"> <div style="border: dotted; padding: 1em 1ch"> test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-items-cross-margin.expected������������������������������������������0000664�0000000�0000000�00000001351�15202323131�0023630�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ testing        • testing       • testing     ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-items-cross-margin.html����������������������������������������������0000664�0000000�0000000�00000000462�15202323131�0022775�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="display: flex; background: blue; flex-wrap: wrap"> <ul style="margin-top: 3em; background: green"> <li style="margin-top: 1em; background: red"> testing </ul> <ul style="margin-top: 1em; width: 40ch; background: green"> <li style="margin-top: 1em; background: red"> testing </ul> <div> testing ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-main-padding-border-box.expected�������������������������������������0000664�0000000�0000000�00000000145�15202323131�0024476�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test  ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-main-padding-border-box.html�����������������������������������������0000664�0000000�0000000�00000000406�15202323131�0023641�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style>* { box-sizing: border-box }</style> <div style="display: flex; margin-right: -2ch; margin-left: -2ch"> <div style="flex-grow: 0; flex-shrink: 0; flex-basis: 100%; padding-right: 2ch; padding-left: 2ch"> <div style="background: red"> test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-main-padding-margin.expected�����������������������������������������0000664�0000000�0000000�00000000117�15202323131�0023707�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test 2 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-main-padding-margin.html���������������������������������������������0000664�0000000�0000000�00000000243�15202323131�0023052�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <body> <div style="display: flex; padding: 1ch 1em"> <span style="margin-right: 10ch"> test </span> <div style="flex-grow: 1"> </div> <div> test 2 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-max-content-over-min-height.expected���������������������������������0000664�0000000�0000000�00000000064�15202323131�0025342�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test   ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-max-content-over-min-height.html�������������������������������������0000664�0000000�0000000�00000000420�15202323131�0024501�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex; flex-direction: column; min-height: 2em; width: 4ch"> <div style="display: flex; flex-wrap: wrap; max-width: 1ch"> <div>test</div> <div style="width: 100%; display: inline-block; height: 2em; background: red"> test </div> </div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-min-max-sizes.expected�����������������������������������������������0000664�0000000�0000000�00000002613�15202323131�0022610�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test  test          test          ���������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-min-max-sizes.html���������������������������������������������������0000664�0000000�0000000�00000000717�15202323131�0021756�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div class="container" style="display: flex; max-height: 40em; background: aliceblue"> test </div> <div style="background: red; max-height: 500em; display: flex; min-height: 5em; flex-direction: column"> <div style="background: aliceblue; flex-grow: 1"> test </div> </div> <div style="background: red; display: flex; min-height: 5em; flex-direction: column"> <div style="background: aliceblue; max-height: 500em; flex-grow: 1"> test </div> </div> �������������������������������������������������chawan-v0.4.0/test/layout/flex-no-shrink-padding-cancels-out-parent-margin.expected�����������������0000664�0000000�0000000�00000000124�15202323131�0030373�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ aaaa aaaa test  test  ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-no-shrink-padding-cancels-out-parent-margin.html���������������������0000664�0000000�0000000�00000001123�15202323131�0027536�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style>* { font-family: monospace }</style> <div style="background: red; width: 11ch"> <div style="margin-left: -3ch"> <div style="flex-shrink: 0; width: 100%; padding-left: 3ch"> <div style="display: flex; flex-wrap: wrap"> <div style="padding: 0 1ch">aaaa</div> <div style="padding: 0 1ch">aaaa</div> </div> </div> </div> </div> <div style="width: 5ch; background: red"> <div style="display: flex; margin: 0 -1ch"> <div style="flex-basis: 100%; flex-shrink: 0; width: 100%; padding: 0 1ch; box-sizing: border-box"> <div> test </div> <div style="background: blue"> test </div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-perc-width-constrains-intrinsic-min-width.expected�������������������0000664�0000000�0000000�00000000075�15202323131�0030234�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������testtest testtest testtest test test test test test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-perc-width-constrains-intrinsic-min-width.html�����������������������0000664�0000000�0000000�00000000264�15202323131�0027377�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex; width: 10ch"> <div>test test test</div> <div style="width: 75%"> test test test test <div style="white-space: pre"> test test test test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-relayout-consistent-border-box-size.expected�������������������������0000664�0000000�0000000�00000000065�15202323131�0027152�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������╔═╗╔═╗ ║a║║b║ ╚═╝╚═╝ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-relayout-consistent-border-box-size.html�����������������������������0000664�0000000�0000000�00000000317�15202323131�0026315�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex"> <div style="display: flex; margin-bottom: 1em"> <div> <div style="display: flex; border: double">a</div> </div> <div style="display: flex; border: double">b</div> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-reverse-absolute-children.expected�����������������������������������0000664�0000000�0000000�00000000006�15202323131�0025156�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test3 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-reverse-absolute-children.html���������������������������������������0000664�0000000�0000000�00000000410�15202323131�0024320�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="position: relative"> <div style="position: absolute">test1</div> <div style="display: flex; flex-direction: column-reverse"> <div style="position: absolute">test2</div> <div>test</div> <div style="position: absolute">test3</div> </div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-shrink-overconstrained.expected��������������������������������������0000664�0000000�0000000�00000000771�15202323131�0024613�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������1111 1111 test test test test test  1111 1111 test test test test test  1111 1111 test test test test test  1111 1111 test test  1111   �������chawan-v0.4.0/test/layout/flex-shrink-overconstrained.html������������������������������������������0000664�0000000�0000000�00000000533�15202323131�0023752�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex; width: 40ch"> <div style="width: 40ch; background: red">1111 1111 1111 1111 1111 1111 1111 1111 1111</div> <div style="width: 80ch; background: pink">test test test test test test test test test test test test test test test test test</div> <!-- <div style="width: 4ch; background: aliceblue">last</div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-shrink-simple.expected�����������������������������������������������0000664�0000000�0000000�00000000216�15202323131�0022671�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test test test test test test test test test test test test test test last test test test test test test test test test test test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-shrink-simple.html���������������������������������������������������0000664�0000000�0000000�00000000324�15202323131�0022034�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex"> <div>test test test test test test test test test</div> <div>test test test test test test test test test test test test test test test test test</div> <div>last</div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-specified-width.expected���������������������������������������������0000664�0000000�0000000�00000000220�15202323131�0023147�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test testing testing testing testing testing testing testing testing ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-specified-width.html�������������������������������������������������0000664�0000000�0000000�00000000252�15202323131�0022317�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex"> <div style="width: 50%"> test </div> <div style="width: 50%"> testing testing testing testing testing testing testing testing ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-width-children-overconstrained.expected������������������������������0000664�0000000�0000000�00000000077�15202323131�0026221�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������something second second something second something �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-width-children-overconstrained.html����������������������������������0000664�0000000�0000000�00000000342�15202323131�0025357�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="display:flex"> <div style="width:25%">something something something</div> <div style="width:25%">second second second</div> <div style="width:25%"></div> <div style="width:25%"></div> <div style="width:25%"></div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-wrap-in-nowrap.expected����������������������������������������������0000664�0000000�0000000�00000001510�15202323131�0022763�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������                                             ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flex-wrap-in-nowrap.html��������������������������������������������������0000664�0000000�0000000�00000000763�15202323131�0022137�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex; flex-wrap: nowrap; width: 20ch"> <div style="display: flex; flex-flow: wrap"> <div style="width: 10ch; height: 5em; background: red"></div> <div style="width: 10ch; height: 5em; background: green"></div> <div style="width: 10ch; height: 5em; background: red"></div> <div style="width: 10ch; height: 5em; background: green"></div> <div style="width: 10ch; height: 5em; background: red"></div> <div style="width: 10ch; height: 5em; background: green"></div> �������������chawan-v0.4.0/test/layout/flexbox-simple-flex-grow-and-height.expected������������������������������0000664�0000000�0000000�00000002704�15202323131�0026030�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test 1000000000000  test 3                          ������������������������������������������������������������chawan-v0.4.0/test/layout/flexbox-simple-flex-grow-and-height.html����������������������������������0000664�0000000�0000000�00000000454�15202323131�0025173�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex"> <div style="flex-grow: 2; height:200px"><div style="background-color: red">test 1000000000000</div></div> <div style="flex-grow: 1; height: 100px;background-color: green; display: flex"></div> <div style="flex-grow: 1; background-color: pink">test 3</div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flexbox-with-ul.expected��������������������������������������������������0000664�0000000�0000000�00000000134�15202323131�0022205�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test • test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flexbox-with-ul.html������������������������������������������������������0000664�0000000�0000000�00000000137�15202323131�0021353�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<nav style="display: flex;"> <ul style="flex-grow: 1"> <li>test </ul> <div class="login"> test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-absolute.expected���������������������������������������������������0000664�0000000�0000000�00000000005�15202323131�0022065�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-absolute.html�������������������������������������������������������0000664�0000000�0000000�00000000112�15202323131�0021227�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<span> <div style="position: absolute; float: right"> test </div> </span> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-after-collapsing-margin-resolved-by-parent.expected�����������������0000664�0000000�0000000�00000000076�15202323131�0030504�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test float test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-after-collapsing-margin-resolved-by-parent.html���������������������0000664�0000000�0000000�00000000342�15202323131�0027643�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 50ch"> <div style="margin-bottom: 1em">test</div> <div id=empty style="margin-top: 1em"> <div style="float: right">float</div> </div> <div id=full style="margin-top: 2em"> test </div> </div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-between-collapsing-margins.expected���������������������������������0000664�0000000�0000000�00000000033�15202323131�0025470�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������one two float clears �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-between-collapsing-margins.html�������������������������������������0000664�0000000�0000000�00000000263�15202323131�0024640�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 20ch"> <div>one</div> <div style="margin-top: 1em"> <div style="float: right; clear: both">float clears</div> <div style="margin-top: 2em"> two ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-bfc-offset-does-not-start-at-zero.expected��������������������������0000664�0000000�0000000�00000000122�15202323131�0026525�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test test right test test test test test test test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-bfc-offset-does-not-start-at-zero.html������������������������������0000664�0000000�0000000�00000000343�15202323131�0025675�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flow-root; width: 20ch"> <div style="padding-top: 1em"> test <div style="float: right; margin-top: 1em; background: red">right</div> </div> test test test test test test test test test test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-child-percentage-width-ignored.expected�����������������������������0000664�0000000�0000000�00000000031�15202323131�0026206�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-child-percentage-width-ignored.html���������������������������������0000664�0000000�0000000�00000000156�15202323131�0025361�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="float: left; background: purple"> <div style="width: 100%; background: red"> test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-clear-in-inline-block.expected��������������������������������������0000664�0000000�0000000�00000000066�15202323131�0024314�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������measure me but not me right clear right now what? ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-clear-in-inline-block.html������������������������������������������0000664�0000000�0000000�00000000306�15202323131�0023454�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: inline-block"> measure me <div style="width: 20ch"> but not me<div style="float: right">right</div> <div style="clear: right">clear right</div> </div> now what? ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-clear-multiple.expected���������������������������������������������0000664�0000000�0000000�00000000276�15202323131�0023200�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������float lefttest test rightright clear lefttest clear all leftlefttest test float right test rightrightclear right clear all leftlefttest test float right lefttest clear right ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-clear-multiple.html�������������������������������������������������0000664�0000000�0000000�00000001511�15202323131�0022334�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 30ch"> <div style="float: right">right</div> <div style="float: right">right</div> <div style="float: left">float left</div> <div style="float: left; clear: left">clear left</div> <div> test test test </div> <div style="clear: both">clear all</div> <div style="float: left">left</div> <div style="float: left">left</div> <div style="float: right">float right</div> <div style="float: right; clear: right">clear right</div> <div style="float: right">right</div> <div style="float: right">right</div> <div> test test test </div> <div style="clear: both">clear all</div> <div style="float: left">left</div> <div style="float: left">left</div> <div style="float: right">float right</div> <div style="float: right; clear: right">clear right</div> <div style="float: left">left</div> <div> test test test </div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-clear-table.expected������������������������������������������������0000664�0000000�0000000�00000000242�15202323131�0022425�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-clear-table.html����������������������������������������������������0000664�0000000�0000000�00000000226�15202323131�0021572�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: table; clear: right; float: right">test</div> <div style="display: table; clear: right; float: right">test</div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-exclusion-after-outer-block-in-inline.expected����������������������0000664�0000000�0000000�00000000035�15202323131�0027466�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������block floatinline 1 inline 2 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-exclusion-after-outer-block-in-inline.html��������������������������0000664�0000000�0000000�00000000153�15202323131�0026632�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <span> <div> block </div> inline 1 <div style="float: left"> float </div> inline 2 </span> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-flushes-child-margin-bottom.expected��������������������������������0000664�0000000�0000000�00000000062�15202323131�0025561�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������testing testingtest test test test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-flushes-child-margin-bottom.html������������������������������������0000664�0000000�0000000�00000000203�15202323131�0024721�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="float: left"> <div style="margin-bottom: 1em"> testing testing </div> </div> <div> test<br> test<br> test<br> test<br> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-height-in-table.expected��������������������������������������������0000664�0000000�0000000�00000000336�15202323131�0023217�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ first first first first first second second second second second second second second second second second second second second second second second second second second ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-height-in-table.html������������������������������������������������0000664�0000000�0000000�00000000400�15202323131�0022352�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <table> <tr> <td><div style="float: right">first first first first first</div> </td> </tr> <tr> <td>second second second second second second second second second second second second second second second second second second second second ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-in-inline-context.expected������������������������������������������0000664�0000000�0000000�00000000022�15202323131�0023612�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������lefttesting after ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-in-inline-context.html����������������������������������������������0000664�0000000�0000000�00000000062�15202323131�0022761�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������testing <div style="float: left">left</div> after ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-in-table-cell.expected����������������������������������������������0000664�0000000�0000000�00000000005�15202323131�0022657�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ 123 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-in-table-cell.html��������������������������������������������������0000664�0000000�0000000�00000000147�15202323131�0022031�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <table> <tr> <td> <div style="float: left">1</div> <div style="float: right">3</div> 2 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-minimum-height.expected���������������������������������������������0000664�0000000�0000000�00000000702�15202323131�0023174�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ line 1 line 2 line 3 line 4 line 5 testing testing testing testing testing ��������������������������������������������������������������chawan-v0.4.0/test/layout/float-minimum-height.html�������������������������������������������������0000664�0000000�0000000�00000000302�15202323131�0022333�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<br> <br> <br> <br> <br> <div style="display: flow-root"> <div style="float: right"> line 1<br> line 2<br> line 3<br> line 4<br> line 5<br> </div> </div> testing testing testing testing testing ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-moved-by-parent-margin-before-line-flush.expected�������������������0000664�0000000�0000000�00000000252�15202323131�0030043�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test right test     test test test   test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-moved-by-parent-margin-before-line-flush.html�����������������������0000664�0000000�0000000�00000000373�15202323131�0027212�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="width: 20ch; display: flow-root"> <div style="margin-top: 1em"> <div style="float: right"> <div style="height: 4em; background: red; display: inline-block">right</div> </div> test<br> test <div style="margin-top: 1em"> test test test test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-next-to-caption.expected��������������������������������������������0000664�0000000�0000000�00000000124�15202323131�0023302�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test 1 2 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-next-to-caption.html������������������������������������������������0000664�0000000�0000000�00000000200�15202323131�0022440�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- the float will trigger a re-layout in test 2. --> <div style="float: right">test 1</div> <table> <caption>test 2</caption> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-position-with-inline-parent-that-establishes-bfc.expected�����������0000664�0000000�0000000�00000000013�15202323131�0031620�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ aa after ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-position-with-inline-parent-that-establishes-bfc.html���������������0000664�0000000�0000000�00000000126�15202323131�0030770�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<br> <br> <div style="overflow: auto">a <div style="float: left">a</div></div> after ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-reposition-with-left-padding-fills-space.expected�������������������0000664�0000000�0000000�00000000207�15202323131�0030153�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test   �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-reposition-with-left-padding-fills-space.html�����������������������0000664�0000000�0000000�00000000303�15202323131�0027313�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="padding: 0 1ch; background: purple"> <div style="float: right"> </div> <div style="background: red"> <div style="background: blue; display: flow-root"> test test test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-resolve-parent.expected���������������������������������������������0000664�0000000�0000000�00000002224�15202323131�0023222�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������                     this is line 1. this is line 2. this is line 3. this is line 4. this is line 5. this is line 6. this is line 7. this is line 8. this is line 9. this is line 10. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-resolve-parent.html�������������������������������������������������0000664�0000000�0000000�00000000661�15202323131�0022370�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML> <style> * { font-family: monospace,monospace; line-height: 1em; font-size: 15px } </style> <div style="display: flow-root"> <div> <div style="float: left; width: 100%; height: 10em; background-color: red"></div> <div style="margin-top: 1em"> this is line 1. this is line 2. this is line 3. this is line 4. this is line 5. this is line 6. this is line 7. this is line 8. this is line 9. this is line 10. </pre> �������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-stacking-context-imitation.expected���������������������������������0000664�0000000�0000000�00000000126�15202323131�0025533�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test right visible ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-stacking-context-imitation.html�������������������������������������0000664�0000000�0000000�00000000576�15202323131�0024707�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 20ch"> <div style="float: right; background: red"> right </div> <div style="background: green">test</div> <div style="position: absolute; background: purple; left: 0">visible</div> <div style="float: right; background: red"> <div style="position: absolute; left: 0; ; top: 1em; z-index: -1; background: yellow">covered</div> </div> </div> </div> ����������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-text-align-right.expected�������������������������������������������0000664�0000000�0000000�00000000171�15202323131�0023442�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������float float float testfloat �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-text-align-right.html�����������������������������������������������0000664�0000000�0000000�00000000252�15202323131�0022605�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="text-align: right"> <div style="float: right; background-color: red">float</div> <div style="float: left; background-color: red">float float float</div> test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-with-left-padding.expected������������������������������������������0000664�0000000�0000000�00000000121�15202323131�0023555�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ wat �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-with-left-padding.html����������������������������������������������0000664�0000000�0000000�00000000100�15202323131�0022715�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="padding-left: 10em"> <div style="float: right"> wat ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-with-margins.expected�����������������������������������������������0000664�0000000�0000000�00000000062�15202323131�0022663�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������testing aside 1 2 3 4 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/float-with-margins.html���������������������������������������������������0000664�0000000�0000000�00000000630�15202323131�0022027�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> * { font-family: monospace; font-size: 16px } </style> <div style="width: 20ch"> <div style="float: left; width: 20ch"> testing </div> <aside style="float: left; margin-right: -10ch"> aside </aside> </div> <br> <!-- test if margins & padding do not get consumed after a float --> <div style="float: left">1</div> <div style="margin-left: 3ch; padding-left: 3ch"> 2<br> 3<br> 4 </div> ��������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flow-border.expected������������������������������������������������������0000664�0000000�0000000�00000001160�15202323131�0021371�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test ──────────────────────────────────────────────────────────────────────────────── test test ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │test │ test ━━━━━━━━━━ test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flow-border.html����������������������������������������������������������0000664�0000000�0000000�00000000360�15202323131�0020535�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> test <div style="border-top-style: solid"> test </div> test <hr> <div style="border-left: solid; border-right: solid"> test </div> <div style="width: 10ch"> <div style="margin-bottom: 1em">test</div> <hr> test </div> </div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flow-root-margin-collapsing.expected��������������������������������������0000664�0000000�0000000�00000000322�15202323131�0024502�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test    test 2 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/flow-root-margin-collapsing.html������������������������������������������0000664�0000000�0000000�00000000221�15202323131�0023643�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flow-root; background: red; margin-bottom: 1em"> <div style="margin-bottom: 1em"> test </div> </div> test 2 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/fractional-margin-cancels-fractional-padding.expected���������������������0000664�0000000�0000000�00000000005�15202323131�0027673�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/fractional-margin-cancels-fractional-padding.html�������������������������0000664�0000000�0000000�00000000070�15202323131�0027040�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="padding-top: .5em; margin-top: -.5em"> test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/general-pseudo-element.expected�������������������������������������������0000664�0000000�0000000�00000000125�15202323131�0023510�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test testtest �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/general-pseudo-element.html�����������������������������������������������0000664�0000000�0000000�00000000132�15202323131�0022651�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> ::before { content: "test"; color: red } </style> <div>test</div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/hangul.expected�����������������������������������������������������������0000664�0000000�0000000�00000000163�15202323131�0020427�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������The following two paragraphs should contain the same hangul letters. Decomposed form: 수학 Normal form: 수학 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/hangul.html���������������������������������������������������������������0000664�0000000�0000000�00000000236�15202323131�0017573�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <p> The following two paragraphs should contain the same hangul letters. <p> Decomposed form:<br> 수학 <p> Normal form:<br> 수학 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/hr-attributes.expected����������������������������������������������������0000664�0000000�0000000�00000000072�15202323131�0021745�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test ───── ━ test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/hr-attributes.html��������������������������������������������������������0000664�0000000�0000000�00000000132�15202323131�0021105�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 10ch"> test <hr color=red width=50%> <hr width=0> test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/huge-transparent-border.expected������������������������������������������0000664�0000000�0000000�00000000012�15202323131�0023704�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/huge-transparent-border.html����������������������������������������������0000664�0000000�0000000�00000000113�15202323131�0023051�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="border-left: 5ch solid transparent">test</div> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/hyphen-wrap-intrinsic-min-width.expected����������������������������������0000664�0000000�0000000�00000000367�15202323131�0025317�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������  a   b  aaa- testtesttesttesttesttesttest b    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/hyphen-wrap-intrinsic-min-width.html��������������������������������������0000664�0000000�0000000�00000000313�15202323131�0024451�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 20ch"> <table> <tr> <th bgcolor=red>a</th> <th bgcolor=green>b</th> </tr> <tr> <td bgcolor=blue>aaa-b</td> <td bgcolor=purple>testtesttesttesttesttesttest </td> </tr> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/id-selector-hash-token-type-flag.expected���������������������������������0000664�0000000�0000000�00000000045�15202323131�0025307�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/id-selector-hash-token-type-flag.html�������������������������������������0000664�0000000�0000000�00000000301�15202323131�0024445�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> #99 { color: red } /* wrong */ #-- { color: blue } /* valid */ #- { color: green } /* wrong */ </style> <div id=99>test</div> <div id=-->test</div> <div id=->test</div> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/img-indefinite-parent-percentage-intrinsic-width.expected�����������������0000664�0000000�0000000�00000000323�15202323131�0030556�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������this box is small this box is big test intrinsic min sizes �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/img-indefinite-parent-percentage-intrinsic-width.html���������������������0000664�0000000�0000000�00000003321�15202323131�0027722�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex; flex-direction: column; width: 4ch"> <div style="margin: auto"> this box is small <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAkklEQVR42u3QoQ0AAAgDsFn+F7y7F3CYJr2gyQ5XCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyfpW2ApraeX08pUAAAAASUVORK5CYII=" style="max-width: 100%"> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAkklEQVR42u3QoQ0AAAgDsFn+F7y7F3CYJr2gyQ5XCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyfpW2ApraeX08pUAAAAASUVORK5CYII=" style="width: 100%"> </div> </div> this box is big <div style="display: flex; flex-direction: column; width: 4ch"> <div style="margin: auto"> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAkklEQVR42u3QoQ0AAAgDsFn+F7y7F3CYJr2gyQ5XCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyfpW2ApraeX08pUAAAAASUVORK5CYII=" style="min-width: 100%"> </div> </div> test intrinsic min sizes <table> <tr> <td> <img style="max-width: 100%" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAkklEQVR42u3QoQ0AAAgDsFn+F7y7F3CYJr2gyQ5XCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyfpW2ApraeX08pUAAAAASUVORK5CYII="> </table> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/img-sizing.expected�������������������������������������������������������0000664�0000000�0000000�00000000243�15202323131�0021225�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test test test test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/img-sizing.html�����������������������������������������������������������0000664�0000000�0000000�00000002476�15202323131�0020402�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <img style="display: inline-block; height: 2em; width: 2em" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAkklEQVR42u3QoQ0AAAgDsFn+F7y7F3CYJr2gyQ5XCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyfpW2ApraeX08pUAAAAASUVORK5CYII="> test <br> test <div style="width: 2ch; height: 1em; max-width: 2ch; margin-bottom: 5em"> <img style="display: inline" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAkklEQVR42u3QoQ0AAAgDsFn+F7y7F3CYJr2gyQ5XCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyfpW2ApraeX08pUAAAAASUVORK5CYII="> </div> <div style="display: flex; flex-direction: column; height: 5ch"> <div> <pre> test test test </pre> <img style="display: flex" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAkklEQVR42u3QoQ0AAAgDsFn+F7y7F3CYJr2gyQ5XCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyfpW2ApraeX08pUAAAAASUVORK5CYII="> </div> </div> test test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/img-with-padding-in-flex-column.expected����������������������������������0000664�0000000�0000000�00000000113�15202323131�0025130�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test  �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/img-with-padding-in-flex-column.html��������������������������������������0000664�0000000�0000000�00000000764�15202323131�0024307�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 20ch"> <div style="display: flex; flex-direction: column"> <img style="padding: 4em; display: flex" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAkklEQVR42u3QoQ0AAAgDsFn+F7y7F3CYJr2gyQ5XCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyfpW2ApraeX08pUAAAAASUVORK5CYII="> <div style="background: red"> test ������������chawan-v0.4.0/test/layout/inline-absolute-align-after-float.expected��������������������������������0000664�0000000�0000000�00000000136�15202323131�0025535�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test testtest ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-absolute-align-after-float.html������������������������������������0000664�0000000�0000000�00000000421�15202323131�0024675�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="text-align: right; display: flow-root"> <span style="float: left"> test </span> <span style="position: absolute"> test </div> <div style="display: flow-root"> <span style="float: left"> test </span> <span style="position: absolute"> test </div> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-absolute-flushed-before-positioning.expected�����������������������0000664�0000000�0000000�00000000220�15202323131�0027465�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test  test test test test test  wheretest test am I? ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-absolute-flushed-before-positioning.html���������������������������0000664�0000000�0000000�00000000506�15202323131�0026637�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="position: absolute"> test <div style="width: 25ch; text-align: right; background: red; position: relative"> <span style="position: relative"> test <span> test <span style="position: absolute; height: 100%; background: blue; top: 1em"> where am I? </span> </span> </span> test test test test test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-absolute-sticks-to-current-word.expected���������������������������0000664�0000000�0000000�00000000451�15202323131�0026612�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test flush  test test test test test  where am I?est   test test hist hist test test test test hist �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-absolute-sticks-to-current-word.html�������������������������������0000664�0000000�0000000�00000002713�15202323131�0025760�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <!-- This matches neither Blink, nor Gecko, but this is fine: * Gecko measures absolute height as one line, but we (like Blink) measure it as the container's height. This is an arbitrary decision (implementation convenience.) * Blink doesn't flush EOL absolutes, but we (like Gecko, sort of) do. This is intentional, as otherwise the link marker pseudo-elements would not stick to the links in many cases. - Do note however that Gecko keeps absolutes at EOL if they are preceeded by a space. I don't, because this is more convenient to implement and also seems more consistent. ---> <style>* { font-family: monospace; font-size: 16px }</style> <div style="position: absolute"> test <div style="width: 25ch; text-align: right; background: red; position: relative"> <span style="position: relative"> test <span> test <span style="position: absolute; height: 100%; background: blue; top: 1em"> where am I? </span> </span> test test test test test </div> </div> </div> <div align=right style="width: 20ch">flush</div> <div style="width: 10ch; margin-top: 3em"> <span>test test <span style="position: absolute; color: red">hi</span>test </div> <div style="width: 10ch; position: relative"> <span style="position: relative">test test <span style="position: absolute; color: red; top: 0">hi</span></span>test </div> <!-- diverges from Gecko: --> <div style="width: 10ch"> <span>test test <span style="position: absolute; color: red">hi</span> test </div> �����������������������������������������������������chawan-v0.4.0/test/layout/inline-absolute-sticks-to-next-word-start.expected������������������������0000664�0000000�0000000�00000000157�15202323131�0027244�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test ahist test test hist test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-absolute-sticks-to-next-word-start.html����������������������������0000664�0000000�0000000�00000000436�15202323131�0026407�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <span style="background: blue">test</span> a<span style="position: absolute">hi</span><span style="background: red">test</span> test <br> <span style="background: blue">test</span> <span style="position: absolute">hi</span><span style="background: red">test</span> test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-absolute-text-align-right.expected���������������������������������0000664�0000000�0000000�00000000135�15202323131�0025427�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test test test  where am I? �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-absolute-text-align-right.html�������������������������������������0000664�0000000�0000000�00000000251�15202323131�0024571�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 22ch; background: red"> test <span style="position: relative"> test test test <span style="position: absolute; top: 1em"> where am I? �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-backgrounds.expected�����������������������������������������������0000664�0000000�0000000�00000002051�15202323131�0022725�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ testing test test test test new line new line new line donenow another thing but this works: testing test test test test thing final stage testing test test test test new line new line new line donenow another thing test1  test2  test3   test4 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-backgrounds.html���������������������������������������������������0000664�0000000�0000000�00000002121�15202323131�0022066�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<pre style="width: 100%; text-align: center"> <span style="background-color: red"> <span style="text-align: center">testing</span> test test test <span style="display: inline-block; margin-top: -2em">test</span> new line new line new line done</span>now another thing </span> </pre> but <div style="width: 100%; text-align: center"> <br> <span style="background-color: red"> this works: <span style="text-align: center; padding-left: 2ch">testing</span> <br> <br> <br> <br> test test test <span style="display: inline-block">test</span> thing </div> final stage <pre style="width: 100%; text-align: center"> <span style="background-color: red"> <span style="text-align: center">testing</span> test test test <span style="display: inline-block; margin-top: -2em">test</span> new line new line new line done</span>now another thing </span> </pre> <span>test1</span> <span style="padding-left: 1ch; background-color: green">test2</span> <span style="background-color: blue; padding-left: 1ch; padding-right: 1ch; margin: 1em">test3</span> <span style="padding-left: 1ch; background-color: red">test4</span> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-block-baseline.expected��������������������������������������������0000664�0000000�0000000�00000000316�15202323131�0023277�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������   test test test   test test       test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-block-baseline.html������������������������������������������������0000664�0000000�0000000�00000000732�15202323131�0022444�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="height: 1em; display: inline-block; padding-bottom: 1em; background: red"><div>test</div></div> test test <div style="width: 2ch; height: 1em; display: inline-block; padding-bottom: 1em; background: red; margin-top: 1em"><div style="height: 1em"></div></div> test test <div style="width: 2ch; height: 1em; display: inline-block; padding-bottom: 1em; background: red"><div style="display: inline-block; height: 1em"></div></div> <div> test </div> ��������������������������������������chawan-v0.4.0/test/layout/inline-block-in-pre.expected����������������������������������������������0000664�0000000�0000000�00000000023�15202323131�0022702�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ a a test test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-block-in-pre.html��������������������������������������������������0000664�0000000�0000000�00000000447�15202323131�0022057�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="white-space: pre"> <div style="display: inline-block">a</div> </div> <div> <div style="display: inline-block; white-space: pre"> a</div> </div> <div style="width: 5ch"> <div style="display: inline-block">test</div> <div style="display: inline-block">test</div> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-block-in-table-row.expected����������������������������������������0000664�0000000�0000000�00000000005�15202323131�0024010�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-block-in-table-row.html��������������������������������������������0000664�0000000�0000000�00000000126�15202323131�0023157�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="display: table-row"> <div style="display: inline-block">test</div> </div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-block-no-margin-collapsing.expected��������������������������������0000664�0000000�0000000�00000000007�15202323131�0025532�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-block-no-margin-collapsing.html������������������������������������0000664�0000000�0000000�00000000130�15202323131�0024672�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="display: inline-block; margin-top: 1em"> <div style="margin-top: 1em"> test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-block-padding-round-down.expected����������������������������������0000664�0000000�0000000�00000000004�15202323131�0025207�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������a a ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-block-padding-round-down.html��������������������������������������0000664�0000000�0000000�00000000176�15202323131�0024364�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: inline-block"> <div style="display: inline-block; padding-left: .4em"> a a </div> </div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-flex-grow-item.expected��������������������������������������������0000664�0000000�0000000�00000000031�15202323131�0023265�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-flex-grow-item.html������������������������������������������������0000664�0000000�0000000�00000000176�15202323131�0022442�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="width: 20ch"> <div style="display: inline-flex"> <div style="background: green; flex-grow: 1"> test </div> </div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-float-before-and-after-clear.expected������������������������������0000664�0000000�0000000�00000000063�15202323131�0025714�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leftinline clear block float �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-float-before-and-after-clear.html����������������������������������0000664�0000000�0000000�00000000266�15202323131�0025064�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <span>inline</span> <div style="float: left">left</div> <div style="clear: both">clear</div> <div style="color: red">block</div> <div style="float: left">float</div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-float-breaks-line.expected�����������������������������������������0000664�0000000�0000000�00000000121�15202323131�0023716�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test1 test4 test2 test3 test2 test3test1 test4 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-float-breaks-line.html���������������������������������������������0000664�0000000�0000000�00000000455�15202323131�0023073�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flow-root"> test1 <div style="float: left; width: 100%"> test2 </div> <div style="float: left"> test3 </div> test4 </div> <div style="display: flow-root"> test1 <div style="float: left; width: 50%"> test2 </div> <div style="float: left"> test3 </div> test4 </div> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-float-collapsed-child-margin.expected������������������������������0000664�0000000�0000000�00000000025�15202323131�0026027�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test right next next �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-float-collapsed-child-margin.html����������������������������������0000664�0000000�0000000�00000000244�15202323131�0025175�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 10ch"> <span> test <div style="float: right"> <div style="margin-bottom: 1em"> right </div> </div> </span> <br> next next </div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-float-correct-bfc-position.expected��������������������������������0000664�0000000�0000000�00000000033�15202323131�0025557�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ float floattest test test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-float-correct-bfc-position.html������������������������������������0000664�0000000�0000000�00000000141�15202323131�0024722�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<br> <div> <span> <div style="float: left">float float</div> </span> </div> <div> test test test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-float-right-in-stretch.expected������������������������������������0000664�0000000�0000000�00000000145�15202323131�0024723�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������hello world test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-float-right-in-stretch.html����������������������������������������0000664�0000000�0000000�00000000150�15202323131�0024062�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <span style="background: red"> hello </span> <div style="float: right">test</div> world ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-float-weirdness.expected�������������������������������������������0000664�0000000�0000000�00000001122�15202323131�0023527�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test  test test  test  test  test  test  test  test  test  test test  test  test  ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-float-weirdness.html�����������������������������������������������0000664�0000000�0000000�00000001121�15202323131�0022671�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: inline-block; background: blue"> test <div style="float: left; width: 100%; background: red"> test </div> test<br> test </div> <div style="display: inline-block; background: blue"> <div> test <div style="float: left; width: 100%; background: red"> test </div> test<br> test </div> </div> <div style="display: inline-block; background: blue"> <div style="float: left; width: 100%; background: red"> test </div> test<br> test </div> <div style="background: blue"> test <div style="float: left; width: 100%; background: red"> test </div> test<br> test </div> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-margin-collapses-over-empty-boxes.expected�������������������������0000664�0000000�0000000�00000000304�15202323131�0027105�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test1 test2 test3 test4 test5 test6 test7 test8 test9 testa testb testd ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-margin-collapses-over-empty-boxes.html�����������������������������0000664�0000000�0000000�00000001057�15202323131�0026256�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <span style="background: red"> test1 <div> test2 </div> test3 </span> <br> <span style="background: red"> test4 <div style="margin-bottom: 1em"> test5 </div> <div style="margin-top: 1em"> test6 </div> </span> <span style="background: red"> test7 <div style="margin-bottom: 1em"> test8 </div> <div style="margin-top: 1em"> </div> test9 </span> <br> <span style="background: red"> testa <div style="margin-bottom: 1em"> testb </div> <div style="margin-top: 1em; margin-bottom: 2em"> </div> </span> <div style="margin-top: 2em"> testd </div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-position-absolute-z-index-before-parent-relative.expected����������0000664�0000000�0000000�00000000013�15202323131�0032013�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-position-absolute-z-index-before-parent-relative.html��������������0000664�0000000�0000000�00000000164�15202323131�0031165�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> test <span style="position: relative"><span style="position: absolute; z-index: -1; left: 1ch">test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-position-relative-painting-order.expected��������������������������0000664�0000000�0000000�00000000005�15202323131�0027015�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-position-relative-painting-order.html������������������������������0000664�0000000�0000000�00000000131�15202323131�0026160�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<span style="position: relative">test</span ><span style="margin-left: -4ch">fail</span> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-split-sizes.expected�����������������������������������������������0000664�0000000�0000000�00000000160�15202323131�0022710�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������before t carthago delenda  est hello after ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-split-sizes.html���������������������������������������������������0000664�0000000�0000000�00000000255�15202323131�0022060�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> before <span style="background-color: red"> t<br> <div>carthago delenda</div> <span style="padding-left: 5em"></span><span>est</span><br> hello</span> after ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-start-offset-flushed-after-block-child.expected��������������������0000664�0000000�0000000�00000000024�15202323131�0027742�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test blah test test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-start-offset-flushed-after-block-child.html������������������������0000664�0000000�0000000�00000000212�15202323131�0027104�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> test <span style="position: relative"> <div> test </div> test <div style="position: absolute; top: 0; left: 0">blah</div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-table-missing-parents.expected�������������������������������������0000664�0000000�0000000�00000000461�15202323131�0024636�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test 1 test 2 test 3 test 3.5 test 4 test 5 test 6 test 7 test 8 test 9 test 9.5 thing thing3 thing2  thing2.5 thing3  thing4  test  ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-table-missing-parents.html�����������������������������������������0000664�0000000�0000000�00000001416�15202323131�0024002�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: table-row"> <span>test 1 <div style="display: inline-table; line-height: 1em"><div style="display: table-row"><div style="display: table-cell">test 2</div></div></div> <!-- <div style="display: inline-block"><div><div>test</div></div></div> --> test 3<br>test 3.5</span> </div> <span>test 4 <div style="display: table-row; background: red">test 5</div> test 6</span> <br> <span>test 7 <div style="display: table-cell">test 8</div> test 9<br>test 9.5</span> <div style="display: table-row; background: red"> <div>thing</div> <div>thing2</div> thing2.5 <span>thing3</span> <div>thing4</div> <div style="display: table-cell"> thing3 </div> </div> <div style="display: table-row"><div style="display: table-cell; background: blue">test</div></div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-table.expected�����������������������������������������������������0000664�0000000�0000000�00000000005�15202323131�0021507�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/inline-table.html���������������������������������������������������������0000664�0000000�0000000�00000000056�15202323131�0020660�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="display: inline-table">test</div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/input-invalidate-on-parent-white-space-change.expected��������������������0000664�0000000�0000000�00000000123�15202323131�0027755�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[ ] [SUBMIT] ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/input-invalidate-on-parent-white-space-change.html������������������������0000664�0000000�0000000�00000000343�15202323131�0027124�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div id=x style="width: 5ch"> <input> <input type="submit"> </div> <script> const x = document.getElementById("x"); x.getBoundingClientRect(); window.onload = () => { x.style.whiteSpace = "nowrap"; } </script> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/input-value-invalidation.expected�����������������������������������������0000664�0000000�0000000�00000000064�15202323131�0024101�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[aest ] ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/input-value-invalidation.html���������������������������������������������0000664�0000000�0000000�00000000231�15202323131�0023240�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <input id=x type=text value=test> <script> const x = document.getElementById("x"); x.getBoundingClientRect(); x.value = "aest" </script> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/input-width-exceeds-size.expected�����������������������������������������0000664�0000000�0000000�00000000064�15202323131�0024013�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[test test test ] ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/input-width-exceeds-size.html���������������������������������������������0000664�0000000�0000000�00000000124�15202323131�0023153�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="width: 1ch"> <input size=10 style="width: 20ch" value='test test test'> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/insert-remove-invalidation.expected���������������������������������������0000664�0000000�0000000�00000000072�15202323131�0024426�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test 1 test 2 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/insert-remove-invalidation.html�������������������������������������������0000664�0000000�0000000�00000001071�15202323131�0023571�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> #x > #z:nth-child(2n+1) { color: red } #x > #y { color: green } #x > #z:nth-child(2n) { color: green } </style> <script src=../asserts.js></script> <div id=x> <div id=y>test 1</div> <div id=z>test 2</div> </div> <script> const x = document.getElementById("x"), y = document.getElementById("y"), z = document.getElementById("z"); y.remove(); assertEquals(window.getComputedStyle(y).color, "") assertEquals(window.getComputedStyle(z).color, "rgb(255, 0, 0)") y.getBoundingClientRect(); z.getBoundingClientRect(); x.insertBefore(y, z); </script> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/intrinsic-min-size-constrained-by-specified-size.expected�����������������0000664�0000000�0000000�00000002067�15202323131�0030531�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ first second third fourth         fifth             sixth �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/intrinsic-min-size-constrained-by-specified-size.html���������������������0000664�0000000�0000000�00000001772�15202323131�0027676�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex; width: 2ch"> <div> <div style="background-color: blue"> <div style="width: 10ch"></div> </div> </div> <div>first</div> </div> <div style="display: flex; width: 2ch"> <div> <div style="background-color: blue"> <div style="min-width: 10ch"></div> </div> </div> <div>second</div> </div> <div style="display: flex; width: 2ch"> <div> <div style="background-color: blue; min-width: 1ch"> <div style="width: 10ch"></div> </div> </div> <div>third</div> </div> <div style="display: flex; width: 2ch"> <div style="min-width: 1ch"> <div style="background-color: blue"> <div style="width: 10ch"></div> </div> </div> <div>fourth</div> </div> <div style="display: flex; flex-direction: column; height: 2em"> <div> <div style="min-height: 1em; height: 4em; background-color: blue"></div> </div> <div> fifth </div> <div style="display: flex; flex-direction: column; height: 2em"> <div> <div style="min-height: 6em; height: 4em; background-color: blue"></div> </div> <div> sixth </div> ������chawan-v0.4.0/test/layout/intrinsic-min-width-overflows-parent-perc-width-after-float.expected������0000664�0000000�0000000�00000000717�15202323131�0032637�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ right   test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test   �������������������������������������������������chawan-v0.4.0/test/layout/intrinsic-min-width-overflows-parent-perc-width-after-float.html����������0000664�0000000�0000000�00000000546�15202323131�0032002�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <body> <div style="float: right">right</div> <div style="display: flow-root; background: purple"> <div style="margin-left: auto; margin-right: auto; width: 100%; background: red"> <pre> test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test ����������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/intrinsic-min-width-with-breaking-opportunities.expected������������������0000664�0000000�0000000�00000000371�15202323131�0030525�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ ああ test ああ test ああ ああ test ああああああああ test test aaaaaaaaaaaaaaaa test aaaaa test aaaaa test aaaaa a a-a- a-a- a-a- test a-a- test a-a- a-a- a-a- a-a �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/intrinsic-min-width-with-breaking-opportunities.html����������������������0000664�0000000�0000000�00000000751�15202323131�0027672�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<table style="width: 12ch"> <tr> <td> test test <td> ああああああああ </table> <table style="width: 12ch"> <tr> <td> test test <td style="word-break: keep-all"> ああああああああ </table> <table style="width: 12ch"> <tr> <td> test test <td> aaaaaaaaaaaaaaaa </table> <table style="width: 12ch"> <tr> <td> test test <td style="word-break: break-all"> aaaaaaaaaaaaaaaa </table> <table style="width: 12ch"> <tr> <td> test test <td> a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a </table> �����������������������chawan-v0.4.0/test/layout/invalid-css-declaration.expected������������������������������������������0000664�0000000�0000000�00000000017�15202323131�0023646�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/invalid-css-declaration.html����������������������������������������������0000664�0000000�0000000�00000000063�15202323131�0023012�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test <div style="*display: inline">test</div> test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/invalid-pseudo-class-as-function.expected���������������������������������0000664�0000000�0000000�00000000005�15202323131�0025416�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/invalid-pseudo-class-as-function.html�������������������������������������0000664�0000000�0000000�00000000072�15202323131�0024565�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> :not { color: red } </style> test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/invalid-pseudo-element-selectors.expected���������������������������������0000664�0000000�0000000�00000000116�15202323131�0025522�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������should be green should be purple ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/invalid-pseudo-element-selectors.html�������������������������������������0000664�0000000�0000000�00000000602�15202323131�0024665�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> #x { color: green } #x::before { content: "should" } :is(#x::before) { color: pink } #x::before span { color: magenta } ::before#x { color: blue } :is(#x::before, #y) { color: purple } :is(#x::before) span { color: red } .-0 { color: red } span::-cha-none { color: yellow } </style> <span id=x> be <span> green </span> </span> <div id=y> should be purple </div> ������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/lang.expected�������������������������������������������������������������0000664�0000000�0000000�00000000155�15202323131�0020073�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test test test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/lang.html�����������������������������������������������������������������0000664�0000000�0000000�00000000422�15202323131�0017233�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <html lang=red> <style> :lang(red) { color: red } :lang(green) { color: green } :lang(blue) { color: blue } body { color: yellow !important } div { color: purple } </style> <div> test <div lang=green>test</div> <div lang=blue>test</div> <div lang>test</div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/lang2.expected������������������������������������������������������������0000664�0000000�0000000�00000000046�15202323131�0020154�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������should be green ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/lang2.html����������������������������������������������������������������0000664�0000000�0000000�00000000162�15202323131�0017316�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> div { color: green } div:lang(not-set) { color: red } </style> <div>should be green</div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/last-declaration-invalid.expected�����������������������������������������0000664�0000000�0000000�00000000034�15202323131�0024020�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/last-declaration-invalid.html���������������������������������������������0000664�0000000�0000000�00000000246�15202323131�0023170�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> div { *color: red } div { color: green; *color: red; } div { margin-left: 1ch } div { * ( } div { margin-left: 2ch } </style> <div>test</div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/layer.expected������������������������������������������������������������0000664�0000000�0000000�00000000331�15202323131�0020262�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test test test test test test test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/layer.html����������������������������������������������������������������0000664�0000000�0000000�00000002166�15202323131�0017435�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> @layer c, a; </style> <style> @layer a { #a { color: red } #b { color: red } #c { color: red !important } #d { color: red !important } } @layer b { #a { color: green } #b { color: green } #c { color: green !important } #d { color: green !important } } @layer c { #a { color: blue } #b { color: blue } #c { color: blue !important } #d { color: blue !important } } @layer { body > div#e { color: red } } @layer { div#e { color: green } } @layer { body > div#e { color: red } } @layer { div#e { color: green } } #b { color: purple } #d { color: purple !important } </style> <div id=a>test</div> <div id=b>test</div> <div id=c>test</div> <div id=d>test</div> <div id=e>test</div> <style> /* anonymous */ @layer { @layer test { body > div#f { color: pink } body > div#g { color: green } } @layer test { div#f { color: red } div#g { color: red } } } @layer { @layer test { div#f { color: green } } } @layer test.hi { div#h { color: green } } @layer test..hi { div#h { color: red } } @layer test. { div#h { color: red } } </style> <div id=f>test</div> <div id=g>test</div> <div id=h>test</div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/layout-cache-updates.expected���������������������������������������������0000664�0000000�0000000�00000000044�15202323131�0023170�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������left left test left left blah test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/layout-cache-updates.html�������������������������������������������������0000664�0000000�0000000�00000000777�15202323131�0022350�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flow-root"> <div style="float: left">left<br>left</div> <br id=x> test </div> <script> var x = document.getElementById("x"); x.getBoundingClientRect(); x.style.clear = "both"; </script> </div> <div style="display: flow-root"> <div style="float: left">left<br>left</div> <div id=y>blah</div> test </div> <script> var x = document.getElementById("y"); x.getBoundingClientRect(); x.style.clear = "both"; x.getBoundingClientRect(); x.style.marginLeft = "1ch"; </script> </div> �chawan-v0.4.0/test/layout/link-alternate.expected���������������������������������������������������0000664�0000000�0000000�00000000060�15202323131�0022057�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/link-alternate.html�������������������������������������������������������0000664�0000000�0000000�00000002532�15202323131�0021230�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <link rel=stylesheet href='data:invalid'> <link rel="alternate stylesheet" href='data:text/css,div{margin-left:1ch}' title="hi0" disabled> <link rel="alternate stylesheet" href='data:text/css,div{margin-left:10ch}' disabled> <link rel="alternate stylesheet" href='data:text/css,div{background:red!important}' title="hi1"> <link rel="stylesheet" href='data:text/css,div{background:yellow}' title="hi2"> <link rel="stylesheet" href='data:text/css,div{background:red}' title="hi3" disabled> <link rel="stylesheet" href='data:text/css,div{background:red}' title="hi4"> <link rel="stylesheet" href='data:text/css,div{background:yellow}'> <link rel="alternate stylesheet" href='data:text/css,div{color:green}' title="hi2"> <link rel="alternate stylesheet" href='data:text/css,div{color:red}' title="hi3"> <script> /* note: layout tests don't use headless mode so we can't do this on onload */ const links = document.getElementsByTagName("link"); links[1].disabled = false; // hi0 links[2].disabled = false; links[3].disabled = false; // hi1 links[4].disabled = true; // hi2 links[5].disabled = true; // hi3 links[7].disabled = true; // hi3 let link = document.createElement("link"); link.rel = "stylesheet"; link.title = "hi2"; link.href = "data:text/css,div{background:purple}"; document.head.appendChild(link); </script> <div style="width: 4ch"> test </div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/list-item-in-inline.expected����������������������������������������������0000664�0000000�0000000�00000000005�15202323131�0022733�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/list-item-in-inline.html��������������������������������������������������0000664�0000000�0000000�00000000041�15202323131�0022076�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <span> <li> test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/list-item-marker-pseudo-element.expected����������������������������������0000664�0000000�0000000�00000000163�15202323131�0025263�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ 甲、test hi worldtest hi worldtest �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/list-item-marker-pseudo-element.html��������������������������������������0000664�0000000�0000000�00000000573�15202323131�0024433�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> .x::marker { color: blue } .y::marker { color: red; content: 'hi world'; display: block } </style> <div style="margin-left: 8ch"> <div class=x style="display: list-item; list-style-type: cjk-heavenly-stem">test</div> <div class=y style="display: list-item">test</div> <div class=y style="display: list-item; list-style-position: inside">test</div> </div> �������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/list-item-position-relative-recognized-as-positioned-ancestor.expected����0000664�0000000�0000000�00000000062�15202323131�0033250�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������testtesttesttesttest asdfasdfasdf ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/list-item-position-relative-recognized-as-positioned-ancestor.html��������0000664�0000000�0000000�00000000467�15202323131�0032424�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="float: left">test</div> <div style="float: left">test</div> <div style="float: left">test</div> <div style="float: left">test</div> <div style="float: left; display: list-item; list-style: none; position: relative">test <div style="position: absolute; left: 0"> asdfasdfasdf </div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/list-style-position.expected����������������������������������������������0000664�0000000�0000000�00000000051�15202323131�0023120�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ • test inside • test outside ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/list-style-position.html��������������������������������������������������0000664�0000000�0000000�00000000220�15202323131�0022261�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <ul style="list-style-position: inside"> <li>test inside </ul> <ul style="list-style-position: outside"> <li>test outside </ul> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/list-style-type.expected��������������������������������������������������0000664�0000000�0000000�00000000173�15202323131�0022242�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ ○ -1 ○ 0 ○ 1 -1. -1 0. 0 1. 1 -1. -1 0. 0 1. 1 2. 2 3. 3 4. 4 1. 2 2. 3 3. 4 48. 2 47. 3 46. 4 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/list-style-type.html������������������������������������������������������0000664�0000000�0000000�00000000470�15202323131�0021405�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML> <ul type="circle"> <li value=-1>-1 <li value=0>0 <li>1 </ul> <ol> <li value=-1>-1 <li>0 <li>1 </ol> <ol start=2> <li value=-1>-1 <li>0 <li>1 </ol> <ol start=2> <li>2 <li>3 <li>4 </ol> <ol start=-2147483648> <li>2 <li>3 <li>4 </ol> <ol start=-2147483648> <li value=-2147483648>2 <li>3 <li>4 </ol> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/margin-does-not-collapse-through-padding.expected�������������������������0000664�0000000�0000000�00000000510�15202323131�0027032�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test  test      test test      test     test     what test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/margin-does-not-collapse-through-padding.html�����������������������������0000664�0000000�0000000�00000001344�15202323131�0026203�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> test <div style="width: 5ch; padding-bottom: 1em; margin-top: 1em; background: red"> <div style="display: flow-root; margin-top: 1em"> test <div style="margin-bottom: 1em; background: blue">test</div> </div> </div> test <div style="width: 5ch; padding-bottom: 1em; background: red"> <div style="margin-bottom: 1em; background: blue">test</div> </div> test </div> <div style="background: green; padding-top: 1em; width: 5ch"> <div style="margin-top: 1em"> test </div> </div> <div style="background: green; width: 5ch"><br></div> <div style="background: rgba(200 0 0); height: 1em; width: 4ch; margin-top: -1em"></div> <div> what </div> <div style="margin-top: 1em; height: 0px"></div> <div style="margin-top: 1em">test</div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/margin-resolved-before-float-before-line-flush.expected�������������������0000664�0000000�0000000�00000000437�15202323131�0030122�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������        test  test test test right test  ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/margin-resolved-before-float-before-line-flush.html�����������������������0000664�0000000�0000000�00000000404�15202323131�0027257�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div id=a style="width: 20ch; display: flow-root"> <div id=b style="background: blue; padding-top: 1em"> <div id=c style="margin-top: 3em"> <div id=d> test </div> <div id=e style="float: right">right</div> </div> <div id=f> test test test test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/margin.expected�����������������������������������������������������������0000664�0000000�0000000�00000000357�15202323131�0020433�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������spacer left, right: 2em top, bottom: 1em. spacer width: 10em left, right: auto top, bottom: 0 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/margin.html���������������������������������������������������������������0000664�0000000�0000000�00000000502�15202323131�0017566�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <style> .claz { margin: 1em 2em 1em; } .one { margin: 0 auto; width: 10em; } #a { margin: 1em; } </style> <div style="width: 1000px"> spacer <div class=claz>left, right: 2em<br>top, bottom: 1em.</div> spacer <div class="clazz one">width: 10em<br>left, right: auto<br>top, bottom: 0</div> </div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/margins-float.expected����������������������������������������������������0000664�0000000�0000000�00000000062�15202323131�0021712�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������wtf? hi inhi from right hi from left center ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/margins-float.html��������������������������������������������������������0000664�0000000�0000000�00000000720�15202323131�0021056�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> * { font-family: monospace,monospace; line-height: 1em; font-size: 18px } </style> <div style="display: inline-block; width: 15ch"> <div style="margin-bottom: 1em;">wtf?</div> <div style="float: right; margin-top: 2em">hi from right</div> <div style="margin-left: 2ch; margin-right: 2ch; margin-top: 2em"> <div style="float: left"> <div style="display: inline-block">hi from left</div> </div> </div> <div> hi in center </div> </div> ������������������������������������������������chawan-v0.4.0/test/layout/margins-float2-1.expected�������������������������������������������������0000664�0000000�0000000�00000000071�15202323131�0022132�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ float test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/margins-float2-1.html�����������������������������������������������������0000664�0000000�0000000�00000000316�15202323131�0021277�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: inline-block; width: 50ch"> <div id=empty style="margin-top: 1em"> <div style="float: right">float</div> </div> <div id=full style="margin-top: 2em"> test </div> </div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/margins-float2.expected���������������������������������������������������0000664�0000000�0000000�00000000065�15202323131�0021777�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test float ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/margins-float2.html�������������������������������������������������������0000664�0000000�0000000�00000000333�15202323131�0021140�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: inline-block; width: 50ch"> <div> <div id=empty style="margin-top: 1em"> <div style="float: right">float</div> </div> <div id=full style="margin-top: 2em"> test </div> </div> </div> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/margins.expected����������������������������������������������������������0000664�0000000�0000000�00000000065�15202323131�0020612�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������wtf? hi from right hi from left hi in center ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/margins.html��������������������������������������������������������������0000664�0000000�0000000�00000000613�15202323131�0017754�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> * { font-family: monospace,monospace } </style> <div style="display: inline-block; width: 15ch"> <div style="margin-bottom: 2ch;">wtf?</div> <div style="display: flow-root; margin-top: 4ch">hi from right</div> <div style="margin-left: 2ch; margin-right: 2ch; margin-top: 4ch"> <div style="display: flow-root">hi from left</div> </div> <div> hi in center </div> </div> ���������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/marker-inits-line-with-float-before-image.expected������������������������0000664�0000000�0000000�00000000340�15202323131�0027074�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ • test  • test a ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/marker-inits-line-with-float-before-image.html����������������������������0000664�0000000�0000000�00000002120�15202323131�0026235�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flow-root"> <ul style="margin: 1em 0 0"> <li style="float: left"><a href="https://example.org">test</a></li> </ul> <ul style="margin: 1em 0 0"> <li> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAkklEQVR42u3QoQ0AAAgDsFn+F7y7F3CYJr2gyQ5XCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyfpW2ApraeX08pUAAAAASUVORK5CYII="> </ul> </div> <div style="width: 20ch; display: flow-root"> <div style="margin: 1em 0 0"> <li style="float: left; margin-left: 2ch"><a href="https://example.org">test</a> </div> <div style="float: right"> <a href="https://example.org"> <img align=top src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAkklEQVR42u3QoQ0AAAgDsFn+F7y7F3CYJr2gyQ5XCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyZIlSxYKZMmSJUsWCmTJkiVLFgpkyfpW2ApraeX08pUAAAAASUVORK5CYII="> a ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/max-width-sets-main-width-indefinite-parent.expected����������������������0000664�0000000�0000000�00000000075�15202323131�0027473�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ testing testing testing testing testing �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/max-width-sets-main-width-indefinite-parent.html��������������������������0000664�0000000�0000000�00000000152�15202323131�0026632�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<table> <tr> <td> <div style="max-width: 100ch; background: blue">testing testing testing testing testing ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/media-query.expected������������������������������������������������������0000664�0000000�0000000�00000000157�15202323131�0021376�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������red green purple blue �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/media-query.html����������������������������������������������������������0000664�0000000�0000000�00000001327�15202323131�0020541�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<style> /* valid */ @mediA (WiDtH >= 1px) and (HeiGhT < 10000px) { #red { color: red } } @media screen and (WiDtH >= 1px) { #green { color: green } } @media (grid: 1) { #purple { color: purple } } @media screen and (min-width: 2px) { #blue { color: blue } } /* invalid */ @media (width >= 1px 2px) { #red { color: blue !important } } @media screen yahoo{ #purple { color: red !important } } @media screen or (min-width: 2px) { #blue { color: red !important } } @media screen and (min-width: 2px) or (min-width: 2px) { #blue { color: red !important } } @media (color) test { #blue { color: red !important } } </style> <div id=red>red</div> <div id=green>green</div> <div id=purple>purple</div> <div id=blue>blue</div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/min-max-width.expected����������������������������������������������������0000664�0000000�0000000�00000001625�15202323131�0021640�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This box should have a  2ch wide blue background and should wrap on every word. x This text should be displayed after a 2ch wide red box. This text should have a  2ch wide green background and should wrap on every word. II  min-width beats max-width  �����������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/min-max-width.html��������������������������������������������������������0000664�0000000�0000000�00000001414�15202323131�0020777�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> #one { width: 10ch; max-width: 2ch; background-color: blue; } #two { width: 10ch; max-width: 2ch; background-color: red; display: inline-block; } #three { width: 10ch; max-width: 2ch; background-color: green; display: block; } #four { width: fit-content(5ch); background-color: purple; max-width: 3ch; } </style> <div id=one> <span><span>This box should have a 2ch wide blue background and should wrap on every word.</span></span> </div> <div id=two>x</div>This text should be displayed after a 2ch wide red box. <div id=three><div>This text should have a 2ch wide green background and should wrap on every word.</div></div> <div id=four>II</div> <div style="background: red; min-width: 30ch; max-width: 1ch">min-width beats max-width</div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/min-width-flex-basis-idk.expected�����������������������������������������0000664�0000000�0000000�00000000040�15202323131�0023643�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test test test test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/min-width-flex-basis-idk.html���������������������������������������������0000664�0000000�0000000�00000000242�15202323131�0023012�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex; flex-wrap: wrap; width: 5ch"> <div style="flex-basis: 100%; width: 5ch"> <pre>test test test</pre> <div>test test test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/negative-z-index-with-bgcolor-body-and-html.expected����������������������0000664�0000000�0000000�00000000354�15202323131�0027364�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������      ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/negative-z-index-with-bgcolor-body-and-html.html��������������������������0000664�0000000�0000000�00000000266�15202323131�0026531�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <html style="background: purple"> <body style="background: red; height: 2em; width: 2em"> <div style="position: absolute; background: blue; z-index: -1"> test </div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/negative-z-index-with-bgcolor.expected������������������������������������0000664�0000000�0000000�00000000164�15202323131�0024726�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test  ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/negative-z-index-with-bgcolor.html����������������������������������������0000664�0000000�0000000�00000000233�15202323131�0024066�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <html> <body style="background: red; height: 2em; width: 2em"> <div style="position: absolute; background: blue; z-index: -1"> test </div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nested-flex-correct-intrinsic-size.expected�������������������������������0000664�0000000�0000000�00000002215�15202323131�0025776�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test                              test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nested-flex-correct-intrinsic-size.html�����������������������������������0000664�0000000�0000000�00000000474�15202323131�0025146�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex; flex-direction: column; height: 10em; background: purple"> <div style="display: flex; background: blue"> <div style="display: flex; background: green"> <div style="width: 10ch; height: 10em; background: red"> test </div> </div> </div> <div> <div style="height: 20em"> test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nested-flex-direction-swap-padding-overflow.expected����������������������0000664�0000000�0000000�00000000750�15202323131�0027564�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test   test   test   test   test   test   test   test  ������������������������chawan-v0.4.0/test/layout/nested-flex-direction-swap-padding-overflow.html��������������������������0000664�0000000�0000000�00000000377�15202323131�0026734�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex; width: 20ch; background: blue"> <div style="display: flex; flex-direction: column; max-width: 100%"> <div style="padding-left: 20ch; padding-right: 20ch; background: red"> test test test test test test test test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nested-floats-simple.expected���������������������������������������������0000664�0000000�0000000�00000000121�15202323131�0023202�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ onethreetwo �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nested-floats-simple.html�������������������������������������������������0000664�0000000�0000000�00000000230�15202323131�0022346�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="float: right"> <div style="float: left">one</div> <div style="float: right">two</div> <div style="float: right">three</div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nested-hover-selector.expected��������������������������������������������0000664�0000000�0000000�00000000012�15202323131�0023363�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ • li ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nested-hover-selector.html������������������������������������������������0000664�0000000�0000000�00000000146�15202323131�0022536�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<style> ul ul { display: none } ul li:hover ul { display: block } </style> <ul> <li>li <ul id=x> test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nested-inline-block.expected����������������������������������������������0000664�0000000�0000000�00000000011�15202323131�0022767�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������bekebeke �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nested-inline-block.html��������������������������������������������������0000664�0000000�0000000�00000000130�15202323131�0022134�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="display: inline-block"> <div style="display: inline-block"> bekebeke </div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nested-table-intrinsic-min-width-respected.expected�����������������������0000664�0000000�0000000�00000000042�15202323131�0027366�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ asdfasdfasdfasdf test test test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nested-table-intrinsic-min-width-respected.html���������������������������0000664�0000000�0000000�00000000177�15202323131�0026542�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<table> <tr> <td> <table width="100%"> <tr> <td width="100%"> asdfasdfasdfasdf </table> <td width="100%"> test test test </td> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nested-table-percentage-size.expected�������������������������������������0000664�0000000�0000000�00000000272�15202323131�0024604�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test   test   test   test   test   test  ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nested-table-percentage-size.html�����������������������������������������0000664�0000000�0000000�00000000260�15202323131�0023744�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 10ch; background: red"> <table> <tbody><tr><td> <table> <tbody><tr><td> <table width="100%"> <tbody> <tr> <td> test test test test test test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nesting.expected����������������������������������������������������������0000664�0000000�0000000�00000000213�15202323131�0020614�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test green green green green �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nesting.html��������������������������������������������������������������0000664�0000000�0000000�00000001052�15202323131�0017761�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> div{ color: red; blah { test: test } && & { color: green } && & & { color: red } } </style> <div><div>test</div></div> <!-- I don't think this matches the spec, but it does match Blink/Gecko --> <div style="color: green; test { hi } color: red">green</div> <div style="color: red; test { hi }; color: green">green</div> <div style="};color: green; test { hi } color: red">green</div> <!-- this isn't even consistent between Blink/Gecko. thanks W3C (not) --> <div style="}color: green; test { hi } color: red">green</div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/new-bfc-clears-floats.expected��������������������������������������������0000664�0000000�0000000�00000000262�15202323131�0023227�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������left right testing left right testing ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/new-bfc-clears-floats.html������������������������������������������������0000664�0000000�0000000�00000000434�15202323131�0022373�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="float: left">left</div> <div style="float: right">right</div> <div style="clear: both"><div style="display: flow-root">testing</div></div> <div style="float: left">left</div> <div style="float: right">right</div> <div style="clear: both; display: flow-root">testing</div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/non-growing-flex-item-indefinite-intrinsic-size.expected������������������0000664�0000000�0000000�00000000056�15202323131�0030372�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������flex item 1a absolute ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/non-growing-flex-item-indefinite-intrinsic-size.html����������������������0000664�0000000�0000000�00000000602�15202323131�0027532�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex"> <div>flex item 1</div> <div style="position: relative; background: pink"> <div style="display: inline-block; width: 100%; background: red">a</div> <!-- this part is a more or less unrelated test for whether setting relative on an inline root block box marks it as the containing block. --> <div style="right: 0; position: absolute"> absolute ������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/non-positioned-flex-item-respects-accepts-z-index.expected����������������0000664�0000000�0000000�00000000061�15202323131�0030625�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test test test test eh? �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/non-positioned-flex-item-respects-accepts-z-index.html��������������������0000664�0000000�0000000�00000000615�15202323131�0027775�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="position: relative; line-height: 1em"> <div style="display: flex"> <div style="background: red; position: absolute; height: 1em; width: 5ch"></div> <div style="z-index: 1"> test test </div> </div> <div style="display: flex; flex-direction: column"> <div>test</div> <div style="z-index: -1"> test test <div style="position: absolute; top: 3em"> eh? </div> </div> </div> �������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nowrap-intrinisc-table-cell-width.expected��������������������������������0000664�0000000�0000000�00000000056�15202323131�0025577�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test test test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nowrap-intrinisc-table-cell-width.html������������������������������������0000664�0000000�0000000�00000000171�15202323131�0024740�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <table width=100> <tr> <td>test <td bgcolor=red style="white-space: nowrap">test test test test </table> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nowrap-overflow.expected��������������������������������������������������0000664�0000000�0000000�00000000700�15202323131�0022315�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test one atest btest ctest dtest next atest btest ctest dtest atest btest ctest dtest test1 test2 test3test test4 test test4 test5 test4 test5test6 test7 test4 test5testtest6 test7 test8 test9test0 test test test test  float floattest test test  ����������������������������������������������������������������chawan-v0.4.0/test/layout/nowrap-overflow.html������������������������������������������������������0000664�0000000�0000000�00000002174�15202323131�0021467�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 5ch"> test <nobr>one</nobr> </div> <div style="width: 12ch"> atest <nobr style="background: green">btest ctest</nobr> dtest </div> next <div style="width: 20ch"> atest <nobr style="background: green">btest ctest</nobr> dtest </div> <div style="width: 25ch"> atest <nobr style="background: green">btest ctest</nobr> dtest </div> <div style="width: 10ch"> test1 <nobr style="background: green">test2 test3</nobr><nobr>test</nobr> test4 </div> <div style="width: 10ch"> test <nobr style="background: green">test4 test5</nobr> </div> <div style="width: 10ch"> <nobr style="background: green">test4 test5</nobr><nobr>test6</nobr> test7 </div> <div style="width: 10ch"> <nobr style="background: green">test4 test5test</nobr><nobr>test6</nobr> test7 </div> <div style="width: 10ch"> <nobr style="background: green">test8 test9</nobr><nobr>test0</nobr> </div> <div style="width: 20ch; background: green"> test test <nobr>test test</nobr><div style="float: left">float</div> </div> <div style="clear: both; width: 20ch; background: green"> <nobr>test test test</nobr><div style="float: left">float</div> </div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nth-child.expected��������������������������������������������������������0000664�0000000�0000000�00000007065�15202323131�0021033�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������green     • test   • test   • test   • test   • test     • test   • test   • test   • test   • test     1. test   2. test   3. test   4. test   5. test     1. test   2. test   3. test   4. test   5. test     1. test   2. test   3. test   4. test   5. test  ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/nth-child.html������������������������������������������������������������0000664�0000000�0000000�00000002336�15202323131�0020172�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<style> ul[first] :nth-child(1n+0) { color: green } ul[first] :nth-child(2n+0) { color: blue } ul[first] :nth-child(0n+1) { color: red } ul[second] :nth-child(1n+0 of li) { color: lime } ul[second] :nth-child(2n+0 of li) { color: aliceblue } ul[second] :nth-child(0n+1 of li) { color: pink } ol[first] :nth-last-child(1n+0) { color: green } ol[first] :nth-last-child(2n+0) { color: blue } ol[first] :nth-last-child(0n+1) { color: red } ol[second] :nth-last-child(1n+0 of li) { color: lime } ol[second] :nth-last-child(2n+0 of li) { color: aliceblue } ol[second] :nth-last-child(0n+1 of li) { color: pink } ol[third] :nth-child(n+2) { color: red } ol[third] :nth-child(eVeN) { color: green } /* invalid */ ol[first] :nth-last-child(0n++1) { color: purple } /* invalid, but :is ignores invalid selectors */ :is(:nth-child(), :nth-child(test()), div) { color: green } </style> <body bgcolor=black text=white> <div>green</div> <ul first> <li>test <li>test <li>test <li>test <li>test </ul> <ul second> <li>test <li>test <li>test <li>test <li>test </ul> <ol first> <li>test <li>test <li>test <li>test <li>test </ol> <ol second> <li>test <li>test <li>test <li>test <li>test </ol> <ol third> <li>test <li>test <li>test <li>test <li>test </ol> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/overflow-auto-in-nested-flex-with-shrink-to-fit.expected������������������0000664�0000000�0000000�00000000012�15202323131�0030240�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/overflow-auto-in-nested-flex-with-shrink-to-fit.html����������������������0000664�0000000�0000000�00000000270�15202323131�0027411�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex"> <div style="display: flex; flex-direction:column; max-width: 100%"> <div style="overflow: auto"> <div>test</div> </div> </div> </div> test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/overflow-auto-still-sets-intrinisc-min-height.expected��������������������0000664�0000000�0000000�00000000074�15202323131�0030113�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test test test test footer footer footer footer ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/overflow-auto-still-sets-intrinisc-min-height.html������������������������0000664�0000000�0000000�00000000335�15202323131�0027256�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="height: 2em; display: flex; flex-direction: column"> <div> <div style="overflow: auto; height: 2ch"> <pre> test test test test test test </pre> </div> </div> <div> footer footer footer footer ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/overflow-hidden-border.expected�������������������������������������������0000664�0000000�0000000�00000000061�15202323131�0023515�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������┌────┐ │test│ └────┘ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/overflow-hidden-border.html�����������������������������������������������0000664�0000000�0000000�00000000141�15202323131�0022657�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: inline-block; border: solid; overflow: hidden"> test </div> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/overflow-hidden-centered-inline-block.expected����������������������������0000664�0000000�0000000�00000000063�15202323131�0026377�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test  �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/overflow-hidden-centered-inline-block.html��������������������������������0000664�0000000�0000000�00000000256�15202323131�0025546�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="text-align: center; width: 30ch; background: red"> <div style="position: relative; display: inline-block; overflow: hidden"> <div> test test test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/overflow-scroll-starts-outside-canvas.expected����������������������������0000664�0000000�0000000�00000000000�15202323131�0026537�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/overflow-scroll-starts-outside-canvas.html��������������������������������0000664�0000000�0000000�00000000133�15202323131�0025711�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="background: red; width: 4ch; overflow: scroll; margin-left: -4ch"> test </div> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/overlapping-background-ends-before-new-text.expected����������������������0000664�0000000�0000000�00000000035�15202323131�0027552�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������testabcd ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/overlapping-background-ends-before-new-text.html��������������������������0000664�0000000�0000000�00000000214�15202323131�0026714�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="margin-left: 1ch; width: 4ch; height: 1em; background: red"></div> <div style="margin-top: -1em">testabcd</div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/overlapping-double-width-chars.expected�����������������������������������0000664�0000000�0000000�00000000601�15202323131�0025157�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������う い  a う  う a う a う a �������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/overlapping-double-width-chars.html���������������������������������������0000664�0000000�0000000�00000001406�15202323131�0024326�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="background-color: red"> <div> xあい </div> <div style="margin-top: -1em"> う </div> <div style="color: blue"> a<span style="color: yellow">あa</span> </div> <div style="margin-top: -1em; padding-left: 2ch; color: green"> う </div> </div> <div style="color: pink"> a<span style="text-decoration: none">あa</span> </div> <div style="margin-top: -1em; color: purple"> う </div> <div style="color: blue"> <!-- check if we re-insert old formatting --> a<span style="color: red">あa</span> </div> <div style="margin-top: -1em; color: purple"> う </div> <!-- check if we do not overwrite old formatting --> a<span style="color: red">あ<span style="color: yellow">a</span></span> </div> <div style="margin-top: -1em; color: purple"> う </div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/padding-counted-for-intrinisc-min-width.expected��������������������������0000664�0000000�0000000�00000000035�15202323131�0026676�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ a  test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/padding-counted-for-intrinisc-min-width.html������������������������������0000664�0000000�0000000�00000000163�15202323131�0026043�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<table style="padding: 0; width: 5ch"> <td><div style="padding: 0 1ch; background: red">a</div></td> <td>test</td> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/padding-negative.expected�������������������������������������������������0000664�0000000�0000000�00000000012�15202323131�0022350�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/padding-negative.html�����������������������������������������������������0000664�0000000�0000000�00000000106�15202323131�0021517�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test <div style="padding-top: -1em; padding-top: 1invalid">test</div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-absolute-block-in-inline.expected��������������������������������0000664�0000000�0000000�00000000410�15202323131�0025574�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������absolute 1 line absabsolute 2 absolute 3 line four absolute 4 absolute 5 line sixabsolute 6 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-absolute-block-in-inline.html������������������������������������0000664�0000000�0000000�00000002123�15202323131�0024742�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <!-- absolute, display: inline-block --> <div style="position: relative"> <br> <div> line <div style="display: inline-block; position: absolute; top: 0; left: 0; background-color: red"> absolute 1 </div> <!-- this should overprint "two", not the other way around. --> <div style="display: inline-block; position: absolute; background-color: red"> absolute 5 </div> two <div style="display: inline-block; position: absolute; background-color: red"> absolute 2 </div> </div> </div> <!-- absolute, display: block --> <div style="position: relative"> <br> <div> line <div style="position: absolute; top: 0; left: 0; background-color: blue"> absolute 3 </div> four <div style="display: block; position: absolute; background-color: yellow"> absolute 4 </div> </div> </div> <!-- absolute, display: inline --> <div style="position: relative; margin-top: 1em"> <br> <div> line <div style="display: inline; position: absolute; top: 0; left: 0; background-color: blue"> absolute 5 </div> six <div style="display: inline; position: absolute; background-color: yellow"> absolute 6 </div> </div> </div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-absolute-border.expected�����������������������������������������0000664�0000000�0000000�00000000100�15202323131�0024073�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ ┌────┐ │test│ │ │ └────┘ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-absolute-border.html���������������������������������������������0000664�0000000�0000000�00000000135�15202323131�0023246�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="position: absolute; border: solid; height: 2em; top: 0; left: .5em"> test </div> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-absolute-float-subtracted-from-available-space.expected����������0000664�0000000�0000000�00000000430�15202323131�0032037�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������asdf test test test   test test test   test test test   test test test   test test  ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-absolute-float-subtracted-from-available-space.html��������������0000664�0000000�0000000�00000000513�15202323131�0031204�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <body> <div style="position: relative; width: 30ch; height: 5em; background: purple"> <div style="display: inline-block; float: left; width: 50%; background: red"> asdf </div> <div style="display: inline-block; float: left; position: absolute"> test test test test test test test test test test test test test test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-absolute-in-table.expected���������������������������������������0000664�0000000�0000000�00000000015�15202323131�0024316�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ where am I? �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-absolute-in-table.html�������������������������������������������0000664�0000000�0000000�00000000202�15202323131�0023457�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <table> <tr> <td> test </td> </tr> <tr> <td> <div style="position: absolute; top: 0"> where am I? </div> </table> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-absolute-margin-padding-subtracted-from-available-space.expected�0000664�0000000�0000000�00000002643�15202323131�0033623�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test   test   test   test     test   test   test   test     test test  test test        test test  test test        test   test   test   test     test   test   test   test     test   test   test   test     test   test   test   test    test ���������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-absolute-margin-padding-subtracted-from-available-space.html�����0000664�0000000�0000000�00000003250�15202323131�0032761�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="position: relative; width: 10ch; height: 5em; background: purple"> <div style="margin-left: 5ch; position: absolute; background: red"> test test test test </div> </div> <div style="position: relative; width: 10ch; height: 5em; background: purple; box-sizing: border-box"> <div style="padding-left: 5ch; width: 10ch; position: absolute; box-sizing: border-box; background: red"> test test test test </div> </div> <div style="position: relative; width: 10ch; height: 5em; background: red"> <div style="padding-left: 5ch; width: 10ch; position: absolute"> test test test test </div> </div> <div style="position: relative; width: 10ch; height: 5em; background: red"> <div style="left: 5ch; width: 10ch; position: absolute"> test test test test </div> </div> <div style="position: relative; width: 10ch; height: 5em; background: purple"> <div style="margin-left: 5ch; position: absolute; background: red"> test test test test </div> </div> <div style="position: relative; width: 10ch; height: 5em; background: purple; box-sizing: border-box"> <div style="padding-left: 5ch; position: absolute; box-sizing: border-box; background: red"> test test test test </div> </div> <div style="position: relative; width: 10ch; height: 5em; background: red"> <div style="padding-left: 5ch; position: absolute"> test test test test </div> </div> <div style="position: relative; width: 10ch; height: 5em; background: red"> <div style="left: 5ch; position: absolute"> test test test test </div> </div> <div style="position: absolute; left: 50%; width: 60ch; margin-left: -30ch"> <div style="position: relative; left: 50%; margin-left: -30ch; width: 60ch; text-align: center"> test </div> </div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-absolute-margins.expected����������������������������������������0000664�0000000�0000000�00000000046�15202323131�0024267�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test with top/left without top/left ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-absolute-margins.html��������������������������������������������0000664�0000000�0000000�00000000407�15202323131�0023433�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> * { margin: 0; padding: 0; </style> test <div style="position: absolute; top: 0; left: 0; margin-left: 1ch; margin-top: 1em"> with top/left </div> <div style="position: absolute; margin-left: 1ch; margin-top: 1em"> without top/left </div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-absolute-prevents-blockification.expected������������������������0000664�0000000�0000000�00000000047�15202323131�0027454�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test 1test 2 test 1test 2 test 1test 2 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-absolute-prevents-blockification.html����������������������������0000664�0000000�0000000�00000001260�15202323131�0026615�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <!-- Fun fact: Blink and Gecko agree on inline-flex, but disagree on inline-table. The spec disagrees with both, but that breaks websites. LOL --> <div> <span> <div style="display: inline-block; float: left"> test 1 </div> <div id=abs1 style="display: inline-block; float: left; position: absolute"> test 2 </div> </span> </div> <br> <div> <div style="display: inline-block; float: left"> test 1 </div> <div id=abs2 style="display: inline-table; float: left; position: absolute"> test 2 </div> </div> <br> <div> <div style="display: inline-block; float: left"> test 1 </div> <div id=abs3 style="display: inline-flex; float: left; position: absolute"> test 2 </div> </div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-absolute-with-relative-inline-parent-offset.expected�������������0000664�0000000�0000000�00000000766�15202323131�0031453�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Note: per CSS, the absolute box's sizing is explicitly UB, apparently to accommodate for Gecko's broken rendering. We follow Blink. test test 2t 2t estadsfasdf test test 2 est asdfasd fa         test   ����������chawan-v0.4.0/test/layout/position-absolute-with-relative-inline-parent-offset.html�����������������0000664�0000000�0000000�00000001011�15202323131�0030576�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <!-- don't ask --> <p> Note: per CSS, the absolute box's sizing is explicitly UB, apparently to accommodate for Gecko's broken rendering. We follow Blink. </p> <br> <br>test test <span style="position:relative">test test<div style="display: inline-block">adsfasdf</div><BR> test test test test <div style="background: blue"> <div style="display: block; position: absolute; top: 0em; left: 0; height: 100%; background: red; width: 3em">2t 2t 2</div> asdfasd fasd </div> </div> <br> <br> <br> test </span> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-absolute-z-index-in-root.expected��������������������������������0000664�0000000�0000000�00000000031�15202323131�0025564�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-absolute-z-index-in-root.html������������������������������������0000664�0000000�0000000�00000000236�15202323131�0024736�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="position: absolute; z-index: 4">test</div> <div style="position: absolute; z-index: 3; background: red; width: 2em; height: 1em"> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-relative-bottom-right.expected�����������������������������������0000664�0000000�0000000�00000000017�15202323131�0025241�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������hi test asdf �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-relative-bottom-right.html���������������������������������������0000664�0000000�0000000�00000000253�15202323131�0024406�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="height: 2em"> hi </div> <div style="margin-left: 1ch; height: 2em; bottom: 1em; right: 1ch; position: relative"> test </div> </div> <div> asdf �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-relative-in-relative-relayouted-in-flex-item.expected������������0000664�0000000�0000000�00000000031�15202323131�0031504�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-relative-in-relative-relayouted-in-flex-item.html����������������0000664�0000000�0000000�00000000271�15202323131�0030655�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: flex"> <div style="position: relative; margin-bottom: 1em"> <div style="background: red; display: flow-root"> <div style="position: relative"> test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-relative-percentage-of-indefinite-parent-height.expected���������0000664�0000000�0000000�00000000152�15202323131�0032212�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test  ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-relative-percentage-of-indefinite-parent-height.html�������������0000664�0000000�0000000�00000000161�15202323131�0031355�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div> <div> test </div> <div style="position: relative; top: 300%; background: red"> test </div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-relative-percentage-on-table-with-excluded-space.expected��������0000664�0000000�0000000�00000000033�15202323131�0032271�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ float table �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-relative-percentage-on-table-with-excluded-space.html������������0000664�0000000�0000000�00000000222�15202323131�0031434�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="width: 20ch"> <div style="float: right; width: 5ch"> float </div> <table style="position: relative; left: 100%"><tr><td>table</table> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-relative-stacking-context.expected�������������������������������0000664�0000000�0000000�00000000012�15202323131�0026102�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ relative ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-relative-stacking-context.html�����������������������������������0000664�0000000�0000000�00000000113�15202323131�0025247�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="position: relative; top: 1em">relative</div> <div>static</div> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-sticky-establishes-absolute-container.expected�������������������0000664�0000000�0000000�00000000016�15202323131�0030416�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test absolute ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position-sticky-establishes-absolute-container.html�����������������������0000664�0000000�0000000�00000000161�15202323131�0027562�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div> test </div> <div style="position: sticky"> <div style="position: absolute; top: 0"> absolute </div> </div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/position.expected���������������������������������������������������������0000664�0000000�0000000�00000000671�15202323131�0021021�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test test test test test test test test  test test test test test test  abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd test test test  test  �����������������������������������������������������������������������chawan-v0.4.0/test/layout/position.html�������������������������������������������������������������0000664�0000000�0000000�00000001121�15202323131�0020153�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="background-color: red; position: absolute; left: 30ch">test test test test test test test test test test test test test test test test</div> <br> <br> <div style="background-color: green; position: absolute">abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd</div> <br> <br> <div style="background-color: red; position: absolute; left: 30ch; right: 30ch">test test test</div> <br> <br> <div style="position: absolute; width: 10ch"> <div style="width: 30ch"> <div style="background-color: blue; position: relative; left: 50%">test</div> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/positioned-clip-box.expected����������������������������������������������0000664�0000000�0000000�00000000012�15202323131�0023032�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ visible ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/positioned-clip-box.html��������������������������������������������������0000664�0000000�0000000�00000000462�15202323131�0022206�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="overflow: hidden"> <div style="position: absolute; top: 2em"> visible </div> </div> <div style="overflow: hidden"> <div style="position: relative; top: 3em"> hidden </div> </div> <div style="position: relative; overflow: hidden"> <div style="position: absolute; top: 3em"> hidden </div> </div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/pre-no-trailing-space.expected��������������������������������������������0000664�0000000�0000000�00000000017�15202323131�0023247�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/pre-no-trailing-space.html������������������������������������������������0000664�0000000�0000000�00000000024�15202323131�0022410�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<pre> test test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/pre-preserves-initial-whitespace.expected���������������������������������0000664�0000000�0000000�00000000020�15202323131�0025524�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/pre-preserves-initial-whitespace.html�������������������������������������0000664�0000000�0000000�00000000074�15202323131�0024700�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <pre> <span>test</span> <div>test</div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/progress-element.expected�������������������������������������������������0000664�0000000�0000000�00000000112�15202323131�0022436�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������##__________________ #################### ###############_______________ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/progress-element.html�����������������������������������������������������0000664�0000000�0000000�00000000617�15202323131�0021613�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 30ch"> <progress value=.1>test</progress> <progress value=2>test</progress> <!-- the following makes progress disappear, whcih kind of sucks but it also matches Blink so meh (Gecko does something entirely different in the next cases) --> <progress style="width: auto" value=.5>test</progress> <progress style="width: auto; display: block" value=.5>test</progress> �����������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/pseudo-element-after-only.expected����������������������������������������0000664�0000000�0000000�00000000006�15202323131�0024151�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������testa ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/pseudo-element-after-only.html��������������������������������������������0000664�0000000�0000000�00000000115�15202323131�0023315�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> div::after { content: "a" } </style> <div>test</div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/pseudo-element-display-table-empty-content.expected�����������������������0000664�0000000�0000000�00000000000�15202323131�0027421�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/pseudo-element-display-table-empty-content.html���������������������������0000664�0000000�0000000�00000000127�15202323131�0026576�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style>div::before { content: ""; display: table }</style> <div></div> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/quotes.expected�����������������������������������������������������������0000664�0000000�0000000�00000000070�15202323131�0020466�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test \test/ \atestb/ 1inc 2inc 3inc 4inc 5inc 6inc 7inc ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/quotes.html���������������������������������������������������������������0000664�0000000�0000000�00000000735�15202323131�0017641�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> div { quotes: "1" "" "2" "" "3" "" "4" "" "5" "" "6" "" "7" "" } #inc::before { content: open-quote } #dec::before { content: close-quote } </style> <q style="quotes: none">test</q> <q style="quotes: '\\' '/'">test</q> <q style="quotes: '\\' '/' 'a' 'b'"><q>test</q></q> <div> <span> <div id=inc>inc</div> <div id=inc>inc</div> <div id=inc>inc</div> <div id=inc>inc</div> </span> <div id=inc>inc</div> <div id=inc>inc</div> </div> <div id=inc>inc</div> �����������������������������������chawan-v0.4.0/test/layout/root-box-margin-respected.expected����������������������������������������0000664�0000000�0000000�00000000010�15202323131�0024140�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/root-box-margin-respected.html��������������������������������������������0000664�0000000�0000000�00000000066�15202323131�0023316�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <html style="margin: 1em">test</html> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/rule-after-unrecognized-at-rule.expected����������������������������������0000664�0000000�0000000�00000000045�15202323131�0025257�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������color me green �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/rule-after-unrecognized-at-rule.html��������������������������������������0000664�0000000�0000000�00000000145�15202323131�0024423�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<style> * { color: red } @media screen { @asdf aa { } * { color: green } } </style> color me green ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/run.sh��������������������������������������������������������������������0000775�0000000�0000000�00000000622�15202323131�0016571�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh if test -z "$CHA" then test -f ../../cha && CHA=../../cha || CHA=cha fi failed=0 for h in *.html do printf '%s\r' "$h" expected=${h%.html}.expected if test -f "$expected" then if ! "$CHA" -C config.toml "$h" | diff "$expected" - then failed=$(($failed+1)) printf 'FAIL: %s\n' "$h" fi else printf 'WARNING: expected file not found for %s\n' "$h" fi done printf '\n' exit "$failed" ��������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/select-multiple.expected��������������������������������������������������0000664�0000000�0000000�00000000246�15202323131�0022263�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ [ ]test test test test test test test test test [*]test [ ]test [ ]test test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/select-multiple.html������������������������������������������������������0000664�0000000�0000000�00000000533�15202323131�0021425�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <select multiple> <option>test test test test test test test test test</option> <option selected>test</option> <option>test</option> <option>test</option> </select> <!-- Note: mainstream browsers tend to put this next to the select. However, w3m puts it after the select (i.e. treats it as block), and so do we.--> test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/selector-case-insensitive.expected����������������������������������������0000664�0000000�0000000�00000000444�15202323131�0024242�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������id html upper, css lower class html upper, css lower id html lower, css upper class html lower, css upper attr html upper, css lower attr html lower, css upper ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/selector-case-insensitive.html��������������������������������������������0000664�0000000�0000000�00000000716�15202323131�0023407�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<style> div { color: red } #test1 { color: green } .test2 { color: green } #TEST3 { color: green } .TEST4 { color: green } [test5] { color: green } [TEST6] { color: green } </style> <div id=TEST1>id html upper, css lower</div> <div class=TEST2>class html upper, css lower</div> <div id=test3>id html lower, css upper</div> <div class=test4>class html lower, css upper</div> <div TEST5>attr html upper, css lower</div> <div test6>attr html lower, css upper</div> ��������������������������������������������������chawan-v0.4.0/test/layout/shrink-to-fit-indirect-floating-descendant.expected�����������������������0000664�0000000�0000000�00000000121�15202323131�0027347�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ abcd �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/shrink-to-fit-indirect-floating-descendant.html���������������������������0000664�0000000�0000000�00000000305�15202323131�0026516�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="float: right"> <div> <div style="float: right">d</div> <div style="float: right">c</div> <div style="float: left">a</div> <div style="float: left">b</div> </div> </div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/shrink-to-fit-inline-float-right.expected���������������������������������0000664�0000000�0000000�00000000062�15202323131�0025337�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test right flush test test testright 2 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/shrink-to-fit-inline-float-right.html�������������������������������������0000664�0000000�0000000�00000000265�15202323131�0024507�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: inline-block"> <span> test <div style="float: right">right</div> <div>flush</div> test test test <div style="float: right">right 2</div> </div> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/shrink-to-fit-margin-depends-on-content-width.expected��������������������0000664�0000000�0000000�00000000043�15202323131�0027736�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test test test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/shrink-to-fit-margin-depends-on-content-width.html������������������������0000664�0000000�0000000�00000000174�15202323131�0027106�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="display: inline-block"> <div> <div style="margin-left: 50%"> test </div> </div> <br> test test test test </div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/stacking-contexts.expected������������������������������������������������0000664�0000000�0000000�00000002000�15202323131�0022611�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������                                                             chawan-v0.4.0/test/layout/stacking-contexts.html����������������������������������������������������0000664�0000000�0000000�00000000765�15202323131�0021774�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> div { position: relative; width: 4em; height: 4em; top: 2em; left: 2em } </style> <div style="background: red"> <div style="z-index: -1; background: green"></div> </div> <div style="background: blue"></div> <br> <div style="z-index: 0; background: red"> <div style="z-index: 1; background: green"></div> </div> <div style="background: blue"></div> <br> <div style="background: red"> <div style="z-index: 1; background: green"></div> </div> <div style="background: blue"></div> �����������chawan-v0.4.0/test/layout/style-tag-order.expected��������������������������������������������������0000664�0000000�0000000�00000000066�15202323131�0022175�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/style-tag-order.html������������������������������������������������������0000664�0000000�0000000�00000000277�15202323131�0021344�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> * { color: blue } div { color: red } body > span { color: green } </style> <style> div { color: green } span { color: red } </style> <div>test</div> <span>test</span> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/subsequent-sibling-selector.expected��������������������������������������0000664�0000000�0000000�00000000074�15202323131�0024613�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������white abc green ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/subsequent-sibling-selector.html������������������������������������������0000664�0000000�0000000�00000000266�15202323131�0023761�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> div ~ div { color: green } #a ~ #b > #c { color: green } </style> <div>white</div> <span id=a>a</span><span id=b>b<span id=c>c</span></span> <div>green</div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/svg-sizing.expected�������������������������������������������������������0000664�0000000�0000000�00000000025�15202323131�0021246�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test 2 test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/svg-sizing.html�����������������������������������������������������������0000664�0000000�0000000�00000000675�15202323131�0020424�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: inline-block; height: 1em"> <svg style="display: inline" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="50" fill="rgb(0, 255, 0)" /></svg> </div> test <div style="display: inline-block; width: 1em"> <svg style="display: inline" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="50" fill="rgb(0, 255, 0)" /></svg> </div> test 2 <br> test �������������������������������������������������������������������chawan-v0.4.0/test/layout/svg-translate-wrong-number-of-params.expected�����������������������������0000664�0000000�0000000�00000000000�15202323131�0026234�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/svg-translate-wrong-number-of-params.html���������������������������������0000664�0000000�0000000�00000000062�15202323131�0025407�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<svg> <g transform="translate(1,100,850)"> </svg> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-auto-resolves-cells-with-percentage-width.expected������������������0000664�0000000�0000000�00000001114�15202323131�0030344�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ Lorem ipsum dolor sit amet, in pri debet    blandit, ius an idque voluptaria, vidit phaedrum   definitionem his ne.    123456789 123456789 123456789 123456789 1234   ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-auto-resolves-cells-with-percentage-width.html����������������������0000664�0000000�0000000�00000000641�15202323131�0027513�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> * { font-family: monospace, monospace; font-size: 16px } table { border-spacing: 0; padding: 0 }</style> <div style="width: 80ch"> <table> <tr> <td width="20%" bgcolor=red></td> <td>Lorem ipsum dolor sit amet, in pri debet blandit, ius an idque voluptaria, vidit phaedrum definitionem his ne.<br> 123456789 123456789 123456789 123456789 1234</td> <td width="20%" bgcolor=yellow></td> </table> �����������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-border-style.expected�����������������������������������������������0000664�0000000�0000000�00000002376�15202323131�0022661�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������solid ┌────┬────┐ │test│test│ ├────┼────┤ │test│test│ └────┴────┘ dotted ┌┈┈┈┈┬┈┈┈┈┐ ┊test┊test┊ ├┈┈┈┈┼┈┈┈┈┤ ┊test┊test┊ └┈┈┈┈┴┈┈┈┈┘ dashed ┌╌╌╌╌┬╌╌╌╌┐ ╎test╎test╎ ├╌╌╌╌┼╌╌╌╌┤ ╎test╎test╎ └╌╌╌╌┴╌╌╌╌┘ double ╔════╦════╗ ║test║test║ ╠════╬════╣ ║test║test║ ╚════╩════╝ inset ╔════╦════╗ ║test║test║ ╠════╬════╣ ║test║test║ ╚════╩════╝ ridge (if collapsed, same as inset) ╔════╦════╗ ║test║test║ ╠════╬════╣ ║test║test║ ╚════╩════╝ outset ┏━━━━┳━━━━┓ ┃test┃test┃ ┣━━━━╋━━━━┫ ┃test┃test┃ ┗━━━━┻━━━━┛ groove (if collapsed, same as outset) ┏━━━━┳━━━━┓ ┃test┃test┃ ┣━━━━╋━━━━┫ ┃test┃test┃ ┗━━━━┻━━━━┛ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-border-style.html���������������������������������������������������0000664�0000000�0000000�00000001744�15202323131�0022022�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> .dotted td { border: dotted } .dashed td { border: dashed } .double td { border: double } .inset td { border: inset } .ridge td { border: ridge } .outset td { border: outset } .groove td { border: groove } table { border-collapse: collapse } </style> solid <table border> <tr><td bgcolor=red>test<td bgcolor=green>test <tr><td>test<td bgcolor=blue>test </table> dotted <table class=dotted> <tr><td>test<td>test <tr><td>test<td>test </table> dashed <table class=dashed> <tr><td>test<td>test <tr><td>test<td>test </table> double <table class=double> <tr><td>test<td>test <tr><td>test<td>test </table> inset <table class=inset> <tr><td>test<td>test <tr><td>test<td>test </table> ridge (if collapsed, same as inset) <table class=ridge> <tr><td>test<td>test <tr><td>test<td>test </table> outset <table class=outset> <tr><td>test<td>test <tr><td>test<td>test </table> groove (if collapsed, same as outset) <table class=groove> <tr><td>test<td>test <tr><td>test<td>test </table> ����������������������������chawan-v0.4.0/test/layout/table-caption-correct-order.expected��������������������������������������0000664�0000000�0000000�00000000045�15202323131�0024442�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������testcaption test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-caption-correct-order.html������������������������������������������0000664�0000000�0000000�00000000171�15202323131�0023605�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <span>test<div style="display: table-caption; background: red">caption</div><br><span>test</span></span> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-caption-intrinsic-size-affects-inner-table-and-vice-versa.expected��0000664�0000000�0000000�00000001134�15202323131�0033253�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������   testtesttesttest test testtesttesttest test test test  test  test  test  testtesttesttest test test    atest test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-caption-intrinsic-size-affects-inner-table-and-vice-versa.html������0000664�0000000�0000000�00000002456�15202323131�0032426�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> xtable { display: table; background: green } xcaption { display: table-caption; background: pink } xtr { display: table-row; background: blue } xtd { display: table-cell; background: red } </style> <!-- caption grows to its intrinsic min width --> <div style="width: 1ch"> <xtable> <xcaption><div style="width: 20%; background: blue; height: 1em"></div>testtesttesttest</xcaption> <xtr><xtd>test</xtd></xtr> </xtable> </div> <!-- available space constrains table, caption is larger than space -> table grows to caption's intrinsic min width --> <div style="width: 5ch"> <xtable> <xcaption>testtesttesttest</xcaption> <xtr><xtd>test test</xtd></xtr> </xtable> </div> <!-- caption & table both fit in available space -> break lines --> <div style="width: 5ch"> <xtable> <xcaption>test test</xcaption> <xtr><xtd>test test</xtd></xtr> </xtable> </div> <!-- caption & table are not constrained in size, table is smaller -> table remains smaller --> <xtable> <xcaption>testtesttesttest</xcaption> <xtr><xtd>test test</xtd></xtr> </xtable> <!-- caption & table are not constrained in size, table is larger -> caption stretched to table size --> <xtable> <xcaption><div style="width: 50%; height: 1em; background: blue"></div></xcaption> <xtr> <xtd> atest test </xtd> </xtr> </xtable> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-caption-margins.expected��������������������������������������������0000664�0000000�0000000�00000000051�15202323131�0023325�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ something something row 2 testing ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-caption-margins.html������������������������������������������������0000664�0000000�0000000�00000000312�15202323131�0022470�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<table> <tr> <td> something something <tr> <td> row 2 <caption style="caption-side: bottom; margin-top: 2em; margin-left: 1ch"> <div style="margin-top: 2em; text-align: left"> testing </div> </caption> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-cell-anonymous-block-invalidation.expected��������������������������0000664�0000000�0000000�00000000024�15202323131�0026746�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ short looooong ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-cell-anonymous-block-invalidation.html������������������������������0000664�0000000�0000000�00000000442�15202323131�0026115�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <table> <tr><td style="width: 8ch">short <tr><td style="width: 8ch">looooong </table> <script> const style = document.createElement("style"); document.head.getBoundingClientRect(); style.textContent = "td { text-align: right }"; document.head.append(style); </script> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-cell-intrinsic-min-width-overrides-specified-width.expected���������0000664�0000000�0000000�00000000056�15202323131�0032122�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test test 2 test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-cell-intrinsic-min-width-overrides-specified-width.html�������������0000664�0000000�0000000�00000000171�15202323131�0031263�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <table style="width: 5ch"> <td width=1%> <pre> test test test </pre> <div> test </div> </td> <td> test 2 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-cell-padding.expected�����������������������������������������������0000664�0000000�0000000�00000000127�15202323131�0022561�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������    test    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-cell-padding.html���������������������������������������������������0000664�0000000�0000000�00000000131�15202323131�0021717�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <table> <tr> <td style="padding: 1em 2ch 1em 1ch; background: red"> test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-cell-percentage-width.expected��������������������������������������0000664�0000000�0000000�00000002770�15202323131�0024413�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ 1 test  test  t 2  test  3 test test  test   test    test  test  4 5  test test  6  test  test   7 test test  test  8 test test test  test  7  test test test test a  b  a  b  c  a  b  c  ��������chawan-v0.4.0/test/layout/table-cell-percentage-width.html������������������������������������������0000664�0000000�0000000�00000003604�15202323131�0023553�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="width: 20ch"> <table> <tr> <td width=1% bgcolor=red>1 <td bgcolor=blue width=100>test <td bgcolor=blue width=50>test <tr> <td width=100 bgcolor=red>t <!-- width ignored --> </table> <table> <tr> <td width=1% bgcolor=red>2 <td bgcolor=blue width=2%>test </table> <table> <tr> <td width=1% bgcolor=red>3 <td bgcolor=blue>test test test <td bgcolor=purple>test </table> </div> <!-- tests with larger space --> <div style="width: 80ch"> <!-- last column's weight overrides (expands) other columns' width --> <table> <tr> <td bgcolor=blue width=100>test <td bgcolor=blue width=50>test <td width=1% bgcolor=red>4 </table> <!-- first column's weight overrides (shrinks) other columns' width --> <table> <tr> <td width=100% bgcolor=red>5 <td bgcolor=blue width=200>test <td bgcolor=blue width=50>test </table> <!-- width and weight don't conflict, respect both --> <table bgcolor=yellow> <tr> <td width=60% bgcolor=red>6 <td bgcolor=blue width=100>test <td bgcolor=blue width=50>test </table> <table> <tr> <td width=1% bgcolor=red>7 <td bgcolor=blue>test test <td bgcolor=purple>test </table> <table> <tr> <td width=5% bgcolor=red>8 <td bgcolor=blue>test test test <td bgcolor=purple>test </table> <table> <tr> <td width=50% bgcolor=red>7 <td bgcolor=blue>test test test <td bgcolor=purple>test </table> <!-- first column expands to take unassigned width --> <table width=500> <tr> <td width=100 bgcolor=red>a <td width=50% bgcolor=blue>b </table> <!-- last column expands to take unassigned width --> <table width=500> <tr> <td width=100 bgcolor=red>a <td width=50% bgcolor=blue>b <td bgcolor=purple>c </table> <!-- note that width: 0 also counts as specified, it's just unrepresentable in HTML (for good reasons, but CSS of course does its own thing...) --> <table width=500> <tr> <td width=100 bgcolor=red>a <td width=50% bgcolor=blue>b <td bgcolor=purple style="width: 0">c </table> ����������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-col-width.expected��������������������������������������������������0000664�0000000�0000000�00000000326�15202323131�0022131�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test a  test  a  test  a  test  a  ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-col-width.html������������������������������������������������������0000664�0000000�0000000�00000000637�15202323131�0021301�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<table> <tr><td bgcolor=red>test</td></tr> <tr><td bgcolor=red>a</td></tr> </table> <table> <tr><td bgcolor=red style="width: 5ch">test</td></tr> <tr><td bgcolor=red>a</td></tr> </table> <table> <tr><td bgcolor=red>test</td></tr> <tr><td bgcolor=red style="width: 5ch">a</td></tr> </table> <table> <tr><td bgcolor=red style="width: 1ch">test</td></tr> <tr><td bgcolor=red style="width: 5ch">a</td></tr> </table> �������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-colwidth-overconstrained-too-small.expected�������������������������0000664�0000000�0000000�00000000170�15202323131�0027161�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ e  h?  ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-colwidth-overconstrained-too-small.html�����������������������������0000664�0000000�0000000�00000000142�15202323131�0026323�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<table width=100%> <tr> <td width=25% bgcolor=red>e <td width=25% bgcolor=green>h? </tr> </table> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-height.expected�����������������������������������������������������0000664�0000000�0000000�00000000100�15202323131�0021475�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test after table test test test after table 2 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-height.html���������������������������������������������������������0000664�0000000�0000000�00000000257�15202323131�0020655�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<table height=1> <tr><td> test<br> test<br> test </td></tr> </table> after table <table style="height: 5em"> <tr><td> test<br> test<br> test </td></tr> </table> after table 2 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-intrinsic-height-overrides-specified-height.expected����������������0000664�0000000�0000000�00000000014�15202323131�0030700�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-intrinsic-height-overrides-specified-height.html��������������������0000664�0000000�0000000�00000000065�15202323131�0030051�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<table> <tr> <td height=1> test </tr> <tr> <td> test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-multiple-thead-tfoot.expected���������������������������������������0000664�0000000�0000000�00000000025�15202323131�0024302�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ 1 2 3 4 5 6 7 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-multiple-thead-tfoot.html�������������������������������������������0000664�0000000�0000000�00000000172�15202323131�0023450�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <table> <tr><td>2 <tr><td>3 <thead><tr><td>1 <thead><tr><td>4 <tfoot><tr><td>7 <tfoot><tr><td>5 <tr><td>6 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-nested-simple.expected����������������������������������������������0000664�0000000�0000000�00000000007�15202323131�0023004�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ Test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-nested-simple.html��������������������������������������������������0000664�0000000�0000000�00000000061�15202323131�0022147�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<table width="100%"><tr><td> <table><tr><td>Test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-overlapping-rowspan-and-colspan.expected����������������������������0000664�0000000�0000000�00000000103�15202323131�0026442�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test col2 test col4 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-overlapping-rowspan-and-colspan.html��������������������������������0000664�0000000�0000000�00000000241�15202323131�0025610�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <table> <tr> <td> test </td> <td rowspan=2 bgcolor=blue> test<br> test </td> </tr> <tr> <td colspan=2> col2 </td> <td> col4 </td> </tr> </table> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-perc-width-respects-intrinsic-min-width.expected��������������������0000664�0000000�0000000�00000000077�15202323131�0030034�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ shouldbegreen thistoo �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-perc-width-respects-intrinsic-min-width.html������������������������0000664�0000000�0000000�00000000334�15202323131�0027173�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <table style="width: 5ch"> <td width=1% bgcolor=red> <div style="background: green"> shouldbegreen </div> </div> </td> <td bgcolor=red width=200> <div style="background: green"> thistoo </div> </td> <tr> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-rowspan.expected����������������������������������������������������0000664�0000000�0000000�00000000261�15202323131�0021726�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ row 1, cell 1 row 1, cell 3 row 2, cell 1 rowspan 3 (centered on row 2) row 2, cell 3 row 3, cell 1 row 3, cell 3 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-rowspan.html��������������������������������������������������������0000664�0000000�0000000�00000000413�15202323131�0021070�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML> <TABLE> <TR> <TD> row 1, cell 1 </TD> <TD ROWSPAN=3> rowspan 3 (centered on row 2) </TD> <TD> row 1, cell 3 </TD> </TR> <TR> <TD> row 2, cell 1 </TD> <TD> row 2, cell 3 </TD> </TR> <TR> <TD> row 3, cell 1 </TD> <TD> row 3, cell 3 </TD> </TR> </TABLE> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-vert-align-baseline.expected����������������������������������������0000664�0000000�0000000�00000000253�15202323131�0024066�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test  test   test       testtest test test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-vert-align-baseline.html��������������������������������������������0000664�0000000�0000000�00000001420�15202323131�0023226�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <table> <tr> <td style="vertical-align: baseline"> test </td> <td style="vertical-align: baseline"> test<br> test </table> <div style="display: table"> <div style="display: table-cell"> <div style="width: 1ch; height: 1em; background: red"></div> </div> <div style="display: table-cell">test</div> </div> <br> <br> <div style="display: table"> <div style="display: table-cell"> <div> <div style="width: 1ch; height: 1em; background: red; margin-top: -2em"></div> </div> </div> <div style="display: table-cell">test</div> </div> <div style="display: table"> <div style="display: table-cell"> <div> <div style="background: red; display: flow-root; height: 3em"></div> test <div>test</div> <div>test</div> </div> </div> <div style="display: table-cell">test</div> </div> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-vertical-padding.expected�������������������������������������������0000664�0000000�0000000�00000000016�15202323131�0023450�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������a test b ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-vertical-padding.html�����������������������������������������������0000664�0000000�0000000�00000000122�15202323131�0022611�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������a <table style="padding-top: 2em; padding-bottom: 2em"> <tr> <td> test </table> b ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-width-sets-intrinsic-min-width.expected�����������������������������0000664�0000000�0000000�00000000164�15202323131�0026230�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ 2222 1111 1111 1111 1111 2222 2222 2222 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table-width-sets-intrinsic-min-width.html���������������������������������0000664�0000000�0000000�00000000233�15202323131�0025370�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<table width=200> <tr> <td width=10%> <table width=200> <tr> <td> 1111 1111 1111 1111 </table> </td> <td> <table> <tr> <td width=100%> 2222 2222 2222 2222 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table.expected������������������������������������������������������������0000664�0000000�0000000�00000002326�15202323131�0020243�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ caption    lorem ipsum dolor sit amet, consectetur   one two  adipiscing elit, sed do eiusmod tempor   three  incididunt ut labore et dolore magna   four five c d aliqua いろはにほへとちりぬるをわかよたれ   six seven そつ one two three four five six seven   eight  eight nine ten elevenn twelve thirteen     fourteen sixteen seventeen eighteen     internationalization nineteen  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/table.html����������������������������������������������������������������0000664�0000000�0000000�00000001706�15202323131�0017407�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <style> * { font-family: monospace, monospace } table { border-spacing: 0.5ch 0 } </style> <table style="background-color: blue"> <caption> caption </caption> <tbody> <tr> <td style="background-color: red"> one two three four five six seven eight </td> <td colspan=2 style="vertical-align: bottom" valign=top> internationalization </td> <td> c </td> <td> d </td> <td valign=bottom> lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua いろはにほへとちりぬるをわかよたれそつ one two three four five six seven eight nine ten elevenn twelve thirteen fourteen sixteen seventeen eighteen nineteen </td> </tr> </tbody> </table> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ����������������������������������������������������������chawan-v0.4.0/test/layout/tabs.expected�������������������������������������������������������������0000664�0000000�0000000�00000001023�15202323131�0020076�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ x y  x y  x y  ^ The above rows should be aligned, and dump mode should output spaces.  Without bgcolor: x y x y x y ^ The above rows should be aligned, and dump mode should output real tab characters. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/tabs.html�����������������������������������������������������������������0000664�0000000�0000000�00000000442�15202323131�0017245�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <pre style="background-color: red"> x y x y x y ^ The above rows should be aligned, and dump mode should output spaces. </pre> Without bgcolor: <pre> x y x y x y ^ The above rows should be aligned, and dump mode should output real tab characters. </pre> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/text-align-cha-center-cha-right.expected����������������������������������0000664�0000000�0000000�00000000020�15202323131�0025070�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ aa test test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/text-align-cha-center-cha-right.html��������������������������������������0000664�0000000�0000000�00000000225�15202323131�0024242�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<center style="width: 10ch"> <div style="float: right">test</div> <div>aa</div> </center> <div align=right><div style="float: left">test</div></div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/text-transform.expected���������������������������������������������������0000664�0000000�0000000�00000000112�15202323131�0022140�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Testing Testing Testing testテスト¥ testテストテスト¥ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/text-transform.html�������������������������������������������������������0000664�0000000�0000000�00000000351�15202323131�0021310�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="text-transform: capitalize">testing testing testing</div> <div style="text-transform: full-width">testテスト¥</div> <div style="text-transform: -cha-half-width">testてすとテスト¥</div> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/translucent-background-over-default-bgcolor.expected����������������������0000664�0000000�0000000�00000000216�15202323131�0027647�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test  ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/translucent-background-over-default-bgcolor.html��������������������������0000664�0000000�0000000�00000000127�15202323131�0027013�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="background: rgb(20 20 20 / .1); color: black"> test </div> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/underline-does-not-escape-background-switch.expected����������������������0000664�0000000�0000000�00000000175�15202323131�0027541�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test  ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/underline-does-not-escape-background-switch.html��������������������������0000664�0000000�0000000�00000000205�15202323131�0026676�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="background: blue"> <div style="background: red; display: inline-block; text-decoration: underline"> test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/unhashed-selector-after-hashed-selector.expected��������������������������0000664�0000000�0000000�00000000033�15202323131�0026731�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/unhashed-selector-after-hashed-selector.html������������������������������0000664�0000000�0000000�00000000076�15202323131�0026103�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <style> div#a, * { color: red } </style> test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/value-case-insensitive.expected�������������������������������������������0000664�0000000�0000000�00000000061�15202323131�0023531�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������over �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/value-case-insensitive.html�����������������������������������������������0000664�0000000�0000000�00000000345�15202323131�0022701�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="position: absolute; background: red; width: 4ch; height: 1em"> </div> <div style="z-index: -1; z-index: Auto; position: absolute; background: pink; color: blue; color: rgb(nonE 99% None)"> over </div> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/variable-in-style.expected������������������������������������������������0000664�0000000�0000000�00000000007�15202323131�0022475�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/variable-in-style.html����������������������������������������������������0000664�0000000�0000000�00000000121�15202323131�0021635�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="padding-left: var(--test); --test: 1em"> test </div> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/variables.expected��������������������������������������������������������0000664�0000000�0000000�00000000630�15202323131�0021120�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������purple  test test2  test  ��������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/variables.html������������������������������������������������������������0000664�0000000�0000000�00000001334�15202323131�0020265�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<style> a { --purple: purple; color: var(--purple) } div { color: white; --pink: yellow !important; background-color: var(--purple) } #test { --test: var(--test2); --test2: var(--test); --test3: var(--test4); --test4: red; --test5: var(--test6,var(--test7)); --test7: var(--test6,var(--test5)); color: var(--test); color: var(--test3); background-color: var(--test5); } :root { --pink: pink } a { --pink0: var(--pink); --gray: gray } #test2 { color: var(--pink0); --pink: yellow !important; background-color: var(--gray) } </style> <a> <div>purple</div> </a> <span id=test>test</span> <a> <div id=test2>test2</div> </a> <div style="--asdf: "> <div style="--red: red; background: var(--asdf) var(--red)"> test </div> </div> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/vertical-align-margin-and-baseline.expected�������������������������������0000664�0000000�0000000�00000000132�15202323131�0025641�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������  test test test test test test test test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/vertical-align-margin-and-baseline.html�����������������������������������0000664�0000000�0000000�00000000520�15202323131�0025005�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<span style="background: red"> <div style="display: inline-block; vertical-align: middle; margin-top: 4em"> test<br> test<br> test </div> <div style="display: inline-block; vertical-align: top; margin-top: 9em"> test<br> test </div> <div style="display: inline-block; vertical-align: bottom; margin-top: 2em"> test<br> test </div> test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/vertical-align-middle-respects-size.expected������������������������������0000664�0000000�0000000�00000000014�15202323131�0026077�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/vertical-align-middle-respects-size.html����������������������������������0000664�0000000�0000000�00000000156�15202323131�0025251�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="display: inline-block; vertical-align: middle; height: 3em">test</div> <div> test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/vertical-align-top-does-not-affect-baseline.expected����������������������0000664�0000000�0000000�00000000061�15202323131�0027403�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/vertical-align-top-does-not-affect-baseline.html��������������������������0000664�0000000�0000000�00000000214�15202323131�0026546�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<span style="background: red"> <div style="display: inline-block; vertical-align: top; margin-top: 5em"> test<br> test<br> test </div> test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/visibility-inline-child.expected������������������������������������������0000664�0000000�0000000�00000000017�15202323131�0023673�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ visible �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/visibility-inline-child.html����������������������������������������������0000664�0000000�0000000�00000000174�15202323131�0023042�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<span><span style="visibility: hidden">hidden <div style="display: inline-block"> <div style="visibility: visible"> visible ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/visibility-switch-in-inline-box.expected����������������������������������0000664�0000000�0000000�00000000005�15202323131�0025300�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/visibility-switch-in-inline-box.html��������������������������������������0000664�0000000�0000000�00000000165�15202323131�0024452�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="visibility: hidden"> <span> <div style="visibility: visible"> test </div> </span> </div> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/weird-combination-of-overflow-float.expected������������������������������0000664�0000000�0000000�00000002131�15202323131�0026126�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������red box                    clear inline overflow right ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/weird-combination-of-overflow-float.html����������������������������������0000664�0000000�0000000�00000000331�15202323131�0025271�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <div style="height: 10em; background: red">red box</div> <div style="clear: left">clear</div> <span>inline</span> <div><div style="overflow: auto">overflow</div></div> <div style="float: right"> right �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/white-space-pre-line.expected���������������������������������������������0000664�0000000�0000000�00000000013�15202323131�0023065�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ a a a a a ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/white-space-pre-line.html�������������������������������������������������0000664�0000000�0000000�00000000061�15202323131�0022233�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div style="white-space: pre-line"> a a a a a �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/white-space-pre-on-new-line-box-skips-lf-space.expected�������������������0000664�0000000�0000000�00000000020�15202323131�0027671�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test test ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/white-space-pre-on-new-line-box-skips-lf-space.html�����������������������0000664�0000000�0000000�00000000120�15202323131�0027035�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test<br> <div style="display: inline-block; white-space: pre">test </div> test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/whitespace-pre-sets-intrinsic-min-width.expected��������������������������0000664�0000000�0000000�00000000020�15202323131�0026733�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ cell 1 cell 2 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/whitespace-pre-sets-intrinsic-min-width.html������������������������������0000664�0000000�0000000�00000000113�15202323131�0026101�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <table> <tr> <td> <pre> cell 1 <td width=100%> <br> cell 2 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/z-index-for-table.expected������������������������������������������������0000664�0000000�0000000�00000000164�15202323131�0022401�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test test test  ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/layout/z-index-for-table.html����������������������������������������������������0000664�0000000�0000000�00000000673�15202323131�0021551�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> test test <div style="position: relative"> test <div style="display: table; position: relative; z-index: -2; background: blue; z-index: 0.0"> <div style="display: table-row"> <div style="display: table-cell"> aa </div> </div> <div style="display: table-row"> <div style="display: table-cell"> <div style="position: absolute; top: 0; z-index: 1">b</div> </div> </div> </div> <div style="margin-top: -1em; background: red"> test ���������������������������������������������������������������������chawan-v0.4.0/test/md/������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0014511�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/add���������������������������������������������������������������������������0000775�0000000�0000000�00000000301�15202323131�0015161�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh if test -z "$1" then echo "Usage: test/md/add test/md/[test-name].md" exit 1 fi CHA=${CHA:-./cha} $CHA -Ctest/md/config.toml "$1" >"$(dirname "$1")/$(basename "$1" .md).expected" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/config.toml�������������������������������������������������������������������0000664�0000000�0000000�00000000416�15202323131�0016654�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[buffer] history = false [display] columns = 80 lines = 24 pixels-per-column = 9 pixels-per-line = 18 force-columns = true force-lines = true force-pixels-per-column = true force-pixels-per-line = true format-mode = ["bold", "italic", "underline", "reverse", "strike"] ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/dl.expected�������������������������������������������������������������������0000664�0000000�0000000�00000000506�15202323131�0016634�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ title 1 definition 1 title 2 definition 2 definition 3, par 1 definition 3, par 2 line 2 definition 3, tab • definition 3, li definition 4 definition 5, par 1 definition 5, par 2 p dt dd dd part 2 dd 2 not a dl because : title must be one line ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/dl.md�������������������������������������������������������������������������0000664�0000000�0000000�00000000426�15202323131�0015434�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������title 1 : definition 1 title 2 : definition 2 : definition 3, par 1 definition 3, par 2 line 2 definition 3, tab * definition 3, li : definition 4 : definition 5, par 1 definition 5, par 2 p dt : dd dd part 2 : dd 2 not a dl because : title must be one line ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/link-destination.expected�����������������������������������������������������0000664�0000000�0000000�00000000221�15202323131�0021503�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������valid [invalid](<https://example.org/) valid valid valid valid <invalidhttps://example.org/valid �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/link-destination.md�����������������������������������������������������������0000664�0000000�0000000�00000000336�15202323131�0020311�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[valid](https://example.org/<) [invalid](<https://example.org/) [valid](https://example.org/ ) [valid](h<ttps://example.org/) [valid](<https://example.org/>) [valid](valid "test") <invalid<https://example.org/valid> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/link-reference-definitions.expected�������������������������������������������0000664�0000000�0000000�00000000507�15202323131�0023440�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test hello test firsta[second] [oops not found] [second]: test [what]: https://wrong.example 'title' wrong, because the line has more text [what] 'title' not parsed this one's right, but has no title but incredibly, this is correct Test asdf [not found][] [not found][ [img] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/link-reference-definitions.md�������������������������������������������������0000664�0000000�0000000�00000000777�15202323131�0022250�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[first]: https://example.org test [hello][hi world] test [first]a[second] [oops not found] [hi world]: a [second]: test [what]: <https://wrong.example> 'title' wrong, because the line has more text [what] [another]: <https://wrong.example> 'title' not parsed [this one's right, but has no title][another] [but incredibly, this is correct]: <my url> 'but incredibly, this is correct' [but incredibly, this is correct] [Test][] asdf [not found][] [not found][ [tesT]: hi ![test][png] [png]: test.png �chawan-v0.4.0/test/md/list.expected�����������������������������������������������������������������0000664�0000000�0000000�00000000374�15202323131�0017213�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ • a • b • c • d par 1. test ○ test ○ test test 2. test test • test test • test test ○ test 1. test p • test 1. test p 10. test • test • test test 1 a ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/list.md�����������������������������������������������������������������������0000664�0000000�0000000�00000000304�15202323131�0016003�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ * a * b * c * d par 1. test * test * test test 4. test test * test test * test test - test 1. test p + test 1. test p 10. test * test * test **test** 1 a ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/mismatched-lt.expected��������������������������������������������������������0000664�0000000�0000000�00000000032�15202323131�0020762�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������< test << test < test > ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/mismatched-lt.md��������������������������������������������������������������0000664�0000000�0000000�00000000032�15202323131�0017561�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������< test << test < test > ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/nested-block.expected���������������������������������������������������������0000664�0000000�0000000�00000000133�15202323131�0020603�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test test test test code *code* cod • test code *code* cod �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/nested-block.md���������������������������������������������������������������0000664�0000000�0000000�00000000146�15202323131�0017406�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������> test test *test* > > test > > ``` > code *code* > cod > ``` * test ``` code *code* cod ``` ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/newline-after-list-before-eof.expected����������������������������������������0000664�0000000�0000000�00000000014�15202323131�0023747�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ • test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/newline-after-list-before-eof.md����������������������������������������������0000664�0000000�0000000�00000000010�15202323131�0022542�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������* test ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/newline.expected��������������������������������������������������������������0000664�0000000�0000000�00000000017�15202323131�0017673�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test test test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/newline.md��������������������������������������������������������������������0000664�0000000�0000000�00000000022�15202323131�0016466�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test\ test test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/par-hr-li-setext-switch.expected����������������������������������������������0000664�0000000�0000000�00000001527�15202323131�0022645�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test hi ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ hi # hi hi ## hi hi • test ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ • test test ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ === test test • test test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/par-hr-li-setext-switch.md����������������������������������������������������0000664�0000000�0000000�00000000143�15202323131�0021435�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test hi *** hi hi === hi hi --- hi * test --- * test test --- === test test * test test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/pipe-table.expected�����������������������������������������������������������0000664�0000000�0000000�00000002336�15202323131�0020262�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# good ┌──────┬─────────┬─────────────┐ │ a │ │hi world test│ ├──────┼─────────┼─────────────┤ │test -│test test│a │ └──────┴─────────┴─────────────┘ ┌────┬─────┐ │this│is ok│ └────┴─────┘ ┌─┬─┐ │a│b│ └─┴─┘ ┌─┐ │a│ └─┘ ┌─┐ │a│ └─┘ ┌─┐ │a│ └─┘ ┌─┬─┐ │a│b│ ├─┼─┤ │a│ │ ├─┼─┤ │a│ │ ├─┼─┤ │a│b│ ├─┼─┤ │a│b│ ├─┼─┤ │a│b│ └─┴─┘ # bad ## a test hi | world -- | -- hi | world wrong|delimiter row is a list • | - ┌─────────┬─────────────────┐ │multiline│isn't allowed T-T│ └─────────┴─────────────────┘ hi second line| world ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/pipe-table.md�����������������������������������������������������������������0000664�0000000�0000000�00000000527�15202323131�0017061�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# good a| | hi world test -- | - | :-: test -|test test| a this|is ok |- | - | a | b | |---|---| | a | |---| a | --| | a |-- |a|b| |-|-| |a| |a |a|b|ignored |a|b|ignored| a|b|ignored| # bad a -- test hi | world -- | -- hi | world wrong|delimiter row is a list - | - multiline|isn't allowed T-T |- | - hi \ second line| world �������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/run.sh������������������������������������������������������������������������0000775�0000000�0000000�00000000634�15202323131�0015657�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh if test -z "$CHA" then test -f ../../cha && CHA=../../cha || CHA=cha fi failed=0 for h in *.md do printf '%s\r' "$h" expected="$(basename "$h" .md).expected" if test -f "$expected" then if ! "$CHA" -C config.toml "$h" | diff "$expected" - then failed=$(($failed+1)) printf 'FAIL: %s\n' "$h" fi else printf 'WARNING: expected file not found for %s\n' "$h" fi done printf '\n' exit "$failed" ����������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/space-pre-file-end.expected���������������������������������������������������0000664�0000000�0000000�00000000006�15202323131�0021570�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ test ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/space-pre-file-end.md���������������������������������������������������������0000664�0000000�0000000�00000000026�15202323131�0020371�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ <test>test</test> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/thematic-break.expected�������������������������������������������������������0000664�0000000�0000000�00000000447�15202323131�0021121�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test - test -- ## test test ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ test �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/md/thematic-break.md�������������������������������������������������������������0000664�0000000�0000000�00000000055�15202323131�0017713�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test - test -- test --- test --- test �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/�����������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0014677�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/all.expected�����������������������������������������������������������������0000664�0000000�0000000�00000000010�15202323131�0017161�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Success ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/asserts.js�������������������������������������������������������������������0000777�0000000�0000000�00000000000�15202323131�0021151�2../asserts.js���������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/config.toml������������������������������������������������������������������0000664�0000000�0000000�00000000442�15202323131�0017041�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[start] headless = true [external] urimethodmap = [] [buffer] scripting = 'app' cookie = true history = false [display] columns = 80 lines = 24 pixels-per-column = 9 pixels-per-line = 18 force-columns = true force-lines = true force-pixels-per-column = true force-pixels-per-line = true ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/cookie.css.http��������������������������������������������������������������0000664�0000000�0000000�00000000115�15202323131�0017635�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-Type: text/css Set-Cookie: test9=css; HttpOnly #y { display: none } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/cookie.http������������������������������������������������������������������0000664�0000000�0000000�00000002612�15202323131�0017052�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-Type: text/html Set-Cookie: test=asdfasdf; HttpOnly; Max-Age=123123123; Path=/headers Set-Cookie: SID=31d4d96e407aad42 Set-Cookie: test2=asdfasdf; Max-Age=0; HttpOnly Set-Cookie: test3=x; HttpOnly Set-Cookie: test4=y; HttpOnly; Max-Age= Set-Cookie: test5=; HttpOnly; Domain=test.example Set-Cookie: test6=hi; HttpOnly; Max-Age=9223372036854775807 Set-Cookie: test7=hi; HttpOnly; Expires=Mon 0 Jan 1999 20:30:00 GMT Set-Cookie: test8=hi; HttpOnly; Expires=Mon, 31 Feb 1999 20:30:00 GMT Set-Cookie: test10=invalid; HttpOnly; Domain=localhost:12345 Set-Cookie: test11=valid; HttpOnly; Domain=localhost <link rel=stylesheet href=cookie.css.http> <div id=x>Fail</div> <div id=y>CSS fail</div> <script src=asserts.js></script> <script> window.onload = () => { const x = new XMLHttpRequest(); x.open("GET", "headers", false); x.overrideMimeType("text/plain"); x.send(); const cookie = x.responseText.split('\n').find(x => x.startsWith("cookie:")); assertEquals(cookie.split(': ').pop().split('; ').sort().join(), "SID=31d4d96e407aad42,test11=valid,test3=x,test4=y,test6=hi,test7=hi,test8=hi,test9=css,test=asdfasdf"); assertEquals(document.cookie, "SID=31d4d96e407aad42") document.cookie = "SID=test; HttpOnly"; assertEquals(document.cookie, "SID=31d4d96e407aad42") document.cookie = "SID=test"; assertEquals(document.cookie, "SID=test") document.getElementById("x").textContent = "Success"; } </script> ����������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/fetch.html�������������������������������������������������������������������0000664�0000000�0000000�00000001713�15202323131�0016660�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>onclick setter/getter</title> <link href=utf16-bom.css rel=stylesheet> <div id=x>Fail</div> <script src=asserts.js></script> <script type=module> const x = document.getElementById("x"); { const res = await fetch("/utf16-bom.css"); const s = await res.text(); assertEquals(window.getComputedStyle(x).textAlign, "right"); assertEquals(s.length, 53); x.style.textAlign = "left"; assertInstanceof(new Response().headers, Headers); } { const file = new File(["test"], "name"); const req = new Request("/headers", {method: "POST", body: file}); const res = await fetch(req); const s = await res.text(); const ss = s.split('\n'); const cl = ss.find(x => x.startsWith("content-length")); assertEquals(cl, "content-length: 4"); const ua = ss.find(x => x.startsWith("user-agent")); assertEquals(ua, "user-agent: chawan"); } { await assertThrowsAsync(() => fetch("file:///tmp/should-throw"), TypeError); } x.textContent = "Success"; </script> �����������������������������������������������������chawan-v0.4.0/test/net/headers.http�����������������������������������������������������������������0000664�0000000�0000000�00000000226�15202323131�0017213�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-Type: text/html Content-Length: 4 Header-1: a header-2: b _header-3: c _header-333: c HeaDeR_FoUr: d Set-Cookie: test Set-Cookie2: test2 eh? ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/json�������������������������������������������������������������������������0000664�0000000�0000000�00000000025�15202323131�0015570�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"test": "hi world"} �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/module.html������������������������������������������������������������������0000664�0000000�0000000�00000001211�15202323131�0017045�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>onclick setter/getter</title> <div id=x>Fail</div> <script src=asserts.js></script> <script> window.seen = 0; import("./module.http"); import(new URL("module4.http", window.location)).catch(x => 0); import('module3.http').catch(x => 0); </script> <script type=module> import './module2.http'; </script> <script src="nested/moduletest.js"></script> <script> window.onload = () => { if (window.seen == 3) document.getElementById("x").textContent = "Success" /* TODO use this once the eval test works window.x.then(() => { if (window.seen == 4) document.getElementById("x").textContent = "Success" }); */ } </script> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/module.http������������������������������������������������������������������0000664�0000000�0000000�00000000157�15202323131�0017070�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-Type: text/javascript assert(new URL(import.meta.url).pathname.startsWith("/module")); window.seen++; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/module2.http�����������������������������������������������������������������0000777�0000000�0000000�00000000000�15202323131�0021330�2module.http�����������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/module3.http�����������������������������������������������������������������0000664�0000000�0000000�00000000140�15202323131�0017143�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-Type: text/javascript window.seen--; throw new TypeError(JSON.stringify(import.meta)); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/module4.http�����������������������������������������������������������������0000777�0000000�0000000�00000000000�15202323131�0021332�2module.http�����������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/module5.http�����������������������������������������������������������������0000777�0000000�0000000�00000000000�15202323131�0021333�2module.http�����������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/nested/����������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0016161�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/nested/module3.http����������������������������������������������������������0000664�0000000�0000000�00000000060�15202323131�0020426�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Content-Type: text/javascript Content-Length: 0 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/nested/moduletest.js���������������������������������������������������������0000664�0000000�0000000�00000000504�15202323131�0020703�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import("./module3.http"); // loads module3 in nested, not in net /* TODO: would be nice if these worked window.x = new Promise(r => { window.r = r; // This works everywhere: eval(`import('../module5.http');`); // Blink fails this (but it works in FF): setTimeout(`import('./module3.http').then(() => r());`, 0); }); */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/ping�������������������������������������������������������������������������0000664�0000000�0000000�00000000005�15202323131�0015552�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������pong ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/run.nim����������������������������������������������������������������������0000664�0000000�0000000�00000003026�15202323131�0016211�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import std/asyncdispatch import std/asynchttpserver import std/httpcore import std/os import std/strutils import io/chafile import types/opt import utils/twtstr proc cb(req: Request) {.async.} = if req.url.path == "/stop": await req.respond(Http200, "") quit(0) var res = "" var headers: seq[(string, string)] = @[] if req.url.path == "/headers": for k, v in req.headers: res &= k & ": " & v & '\n' else: if chafile.readFile(req.url.path.after('/'), res).isErr: await req.respond(Http404, "Not found") return if req.url.path.endsWith(".http"): var i = 0 for line in res.split('\n'): i += line.len + 1 if line == "": break let n = line.find(':') if n >= 0: headers.add((line.substr(0, n - 1), line.substr(n + 1))) res = res.substr(i) else: res = readFile(req.url.path.after('/')) #echo (req.reqMethod, req.url.path, req.headers) await req.respond(Http200, res, headers.newHttpHeaders()) proc runServer(server: AsyncHttpServer) {.async.} = while true: if server.shouldAcceptRequest(): await server.acceptRequest(cb) else: # too many concurrent connections, `maxFDs` exceeded # wait 500ms for FDs to be closed await sleepAsync(500) proc main() = let server = newAsyncHttpServer() if paramCount() >= 1 and paramStr(1) == "-a": server.listen(Port(0), "localhost") else: server.listen(Port(8000), "localhost") echo $uint16(server.getPort()) waitFor server.runServer() main() ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/run.sh�����������������������������������������������������������������������0000775�0000000�0000000�00000001114�15202323131�0016037�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh if ! test "$CHA" then test -f ../../cha && CHA=../../cha || CHA=cha fi ./run -a | { IFS= read -r port addr="http://localhost:$port" # Now we have to close stdin, but if I exec here then ./run dies. </dev/null | { failed=0 for h in *.html *.http do case $h in cookie.css.http|headers.http|module*.http) continue;; esac printf '%s\r' "$h" if ! "$CHA" -C config.toml "$addr/$h" | diff all.expected - then failed=$(($failed+1)) printf 'FAIL: %s\n' "$h" fi done printf '\n' $CHA -C config.toml -d "$addr/stop" >/dev/null exit "$failed" } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/utf16-bom.css����������������������������������������������������������������0000664�0000000�0000000�00000000065�15202323131�0017132�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#�x� �{� �t�e�x�t�-�a�l�i�g�n�:� �r�i�g�h�t� �}� � ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/net/xhr.html���������������������������������������������������������������������0000664�0000000�0000000�00000003665�15202323131�0016400�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!doctype html> <title>onclick setter/getter</title> <div id=x>Fail</div> <script src=asserts.js></script> <script> const x = new XMLHttpRequest(); assert(x.onreadystatechange === null); let changed = false; function myFunction(event) { changed = true; assert(!event.bubbles); assert(!event.cancelable); assert(event.isTrusted); } x.onreadystatechange = myFunction; assertEquals(x.status, 0); assertEquals(myFunction, x.onreadystatechange); assertEquals(x.readyState, XMLHttpRequest.UNSENT); assertEquals(x.UNSENT, XMLHttpRequest.UNSENT); x.open("GET", "ping", false); assertThrows(() => x.responseType = 'document', DOMException); x.overrideMimeType("text/plain"); x.send(); assertThrows(() => x.overrideMimeType("text/plain"), DOMException); assertEquals(x.readyState, XMLHttpRequest.DONE); assert(changed); changed = false; x.onreadystatechange = function() { if (x.readyState === XMLHttpRequest.DONE) { x.response; x.response; assertEquals(JSON.stringify(x.response), '{"test":"hi world"}'); } } x.open("GET", "json", true, undefined, undefined); x.responseType = "json"; x.withCredentials = true; x.send(); assertThrows(() => x.withCredentials = true, DOMException); let y = new XMLHttpRequest(); y.onreadystatechange = function() { if (y.readyState === XMLHttpRequest.DONE) { assertEquals(y.getAllResponseHeaders(), `content-length: 4\r content-type: text/html\r header-1: a\r header-2: b\r header_four: d\r _header-3: c\r _header-333: c\r\n`); } } y.open("GET", "headers.http", false); y.send() let z = new XMLHttpRequest(); z.onreadystatechange = function() { if (z.readyState != XMLHttpRequest.DONE) return const auth = z.response.split('\n') .find(x => x.startsWith("authorization")); assertEquals(auth, "authorization: Basic Y2hhLXRlc3QtdXNlckA6Y2hhLXRlc3QtcGFzczo="); } z.open("GET", "headers", false, "cha-test-user@", "cha-test-pass:"); z.withCredentials = true; z.send() document.getElementById("x").textContent = "Success"; </script> ���������������������������������������������������������������������������chawan-v0.4.0/test/nim/�����������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0014674�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/nim/ttwtstr.nim������������������������������������������������������������������0000664�0000000�0000000�00000003562�15202323131�0017142�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import utils/twtstr proc testFind() = assert "test".find("te") == 0 assert "test".find("est") == 1 assert "test".find("st") == 2 assert "test".find("test") == 0 assert "test".find("t") == 0 assert "test".find("t", start = 5) == -1 assert "test".find("t", start = 1) == 3 assert "".find("t") == -1 assert "".find("t", start = 1) == -1 assert "".find("") == 0 assert "".find("", start = 1) == -1 assert "test".find("") == 0 assert "test".find("", start = 1) == 1 assert "test".rfind('t') == 3 assert "test".rfind('t', 0, last = 3) == 3 assert "test".rfind('t', 0, last = 2) == 0 assert "test".rfind('t', start = 1, last = 2) == -1 assert "test".startsWith("test") assert not "test".startsWith("testt") assert "test".startsWith("t") assert "test".startsWith("") assert "a\tb ".containsToken("a") assert "a\tb ".containsToken("") assert "\na\tb ".containsToken("") assert not "ab".containsToken("") proc testStrip() = assert " ".strip() == "" assert "\f\t test \r\n".strip() == "test" assert " test ".strip(trailing = false) == "test " assert " test ".strip(leading = false) == " test" assert " \tes\t ".strip(chars = {' '}) == "\tes\t" proc testDelete() = var x = "test" x.delete(1..4) assert x == "t" proc testContentType() = var s = "text/html; a = b" assert s.getContentTypeAttr("a") == "b" s.setContentTypeAttr("a", "test") assert s == "text/html; a =test" assert s.getContentTypeAttr("a") == "test" s.setContentTypeAttr("b", "test2") assert s.getContentTypeAttr("b") == "test2" assert "text/html; a=b; c=d".getContentTypeAttr("c") == "d" assert "text/html;a=b".getContentTypeAttr("a") == "b" assert "text/html;aa=b;a=c".getContentTypeAttr("a") == "c" assert "text/html;a=\"b\"".getContentTypeAttr("a") == "b" proc run() = testFind() testStrip() testDelete() testContentType() static: run() run() ����������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/pager/���������������������������������������������������������������������������0000775�0000000�0000000�00000000000�15202323131�0015207�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/pager/mailcap��������������������������������������������������������������������0000664�0000000�0000000�00000000226�15202323131�0016540�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test/test2; echo 'never used because of template'; test=echo %s\; true; copiousoutput test/test2; echo 'hello from mailcap'; test=true; copiousoutput ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/pager/mime.types�����������������������������������������������������������������0000664�0000000�0000000�00000000040�15202323131�0017216�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test/test test test/test2 test2 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/pager/run.sh���������������������������������������������������������������������0000775�0000000�0000000�00000000623�15202323131�0016353�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh if test -z "$CHA" then test -f ../../cha && CHA=../../cha || CHA=cha fi sed -E -e 's/^#([^ ])/\1/' ../../bonus/config.toml >tmp_config.toml if ! $CHA -Ctmp_config.toml /dev/null | diff /dev/null - then rm tmp_config.toml exit 1 fi rm tmp_config.toml $CHA -Ctest.toml test.test >/dev/null || exit 1 if ! $CHA -Ctest.toml test2.test2 | diff test2.expected - then exit 1 fi $CHA -r 'quit()' �������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/pager/test.test������������������������������������������������������������������0000664�0000000�0000000�00000000005�15202323131�0017062�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/pager/test.toml������������������������������������������������������������������0000664�0000000�0000000�00000000365�15202323131�0017067�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[buffer] history = false [external] mime-types = "mime.types" auto-mailcap = "mailcap" [[siteconf]] # test host = 'example\.org' # test default-headers = { # test a = "b", # comment c = "d", # trailing comma } # test cookie = true # test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/pager/test2.expected�������������������������������������������������������������0000664�0000000�0000000�00000000023�15202323131�0017766�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������hello from mailcap �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/test/pager/test2.test2����������������������������������������������������������������0000664�0000000�0000000�00000000005�15202323131�0017226�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������test ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������chawan-v0.4.0/todo����������������������������������������������������������������������������������0000664�0000000�0000000�00000004243�15202323131�0014025�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������charsets: - set up some fuzzer - use appropriate charsets in forms, urls, etc. display: - important: buffer list menu - dark mode (basically max Y) config: - important: config editor - $TERM-based display config - add RPC for CGI scripts e.g. toggle settings/issue downloads/etc * also some way to set permissions for RPC calls mailcap: - save custom command? (or a mailcap command editor like w3m) - w3mmee extensions * browsecap looks cleaner than urimethodmap, and would be useful for mailto buffer: - important: validate returned values - color visited links * needs some sort of conditional formatting in pager, e.g. give all Formats an id in buffer and send a list of "if URL visited, change Format" commands - xhtml pager: - handle long lines network: - BGI - uBO integration? (or at least implement filter lists) - dict - nntp - websockets javascript: - support defining function with magic - "this" value as JSValue - ReadableStream - separate console for each buffer - CORS layout: - flexbox: align-self, align-items, justify-content, margin: auto - details element - merge csstree into layout: first factor out tree traversal, then move build to before each layout * split each layout into pre, child pre, child post, post, * pre result: abort, continue * post result: redo, continue * probably box invalidation has to be reworked too, since we can't just skip layout without checking children first (maybe move it to the DOM?) - partial rendering * element pointers must go from buffer.lines, so rewrite getCursorStyledNode and findPrev/NextLink to use the box tree - this definitely needs an overflow box (maybe just add a pass after layout() that inherits it from children?) * if that's not enough, even a separate tree... (otherwise documents like `gitcha log' may take an eternity to hit test) * inline layout's output must be flattened again, so that we can deal with tall inline boxes (like the <plaintext> tag in text/plain buffers) - frame, iframe - fix image issues * z order * clipping - grid misc: - animation (GIF) - add a DOM -> man page converter so that we do not depend on pandoc for man page conversion - unifont -> milkjf? �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������